diff --git a/CMakeLists.txt b/CMakeLists.txt index 617df21..9e6a2d7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required (VERSION 3.7) project(core - VERSION 0.2.17 + VERSION 0.3.0 LANGUAGES C) add_executable(core src/main.c) @@ -11,7 +11,6 @@ target_link_libraries(core -luuid) set(CMAKE_C_FLAGS "$ENV{CFLAGS}") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3 -std=gnu99 -Wpedantic -Werror -Wall -Wextra -ffile-prefix-map=${CMAKE_SOURCE_DIR}/src/=") -set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -g -fprofile-arcs -ftest-coverage") set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -g -fprofile-arcs -ftest-coverage") add_definitions("-DMG_ENABLE_EXTRA_ERRORS_DESC -DMG_ENABLE_MQTT_BROKER") diff --git a/include/command.h b/include/command.h index e69b7ff..55eed0e 100644 --- a/include/command.h +++ b/include/command.h @@ -5,15 +5,18 @@ #include int -command_set_relay_schedule(relay_t *relay); +command_relay_schedules_set(relay_t *relay); int -command_set_controller_name(controller_t *controller); +command_controller_name_set(controller_t *controller); int -command_send(controller_t *controller, int command_code, char *payload, uint32_t payload_size); +command_send(controller_t *controller, char *payload, uint32_t payload_size); int -command_pulse(relay_t *relay, uint8_t duration); +command_relay_pulse(relay_t *relay, uint8_t duration); + +int +command_schedule_update(schedule_t *schedule); #endif /* CORE_COMMAND_H */ diff --git a/include/enums.h b/include/enums.h index a51ff31..1e740fc 100644 --- a/include/enums.h +++ b/include/enums.h @@ -7,31 +7,6 @@ typedef enum POLL_FDS_COMMAND } poll_fds_t; -typedef enum -{ - COMMAND_MAPPING_CODE = 0, - COMMAND_MAPPING_NAME = 1, - COMMAND_MAPPING_RELAY_NUM = 2, - COMMAND_MAPPING_SCHEDULES_ARRAY = 3, - COMMAND_MAPPING_SCHEDULE_ID = 4, - COMMAND_MAPPING_PERIODS_COUNT = 5, - COMMAND_MAPPING_PERIODS_BLOB = 6, - COMMAND_MAPPING_PULSE_DURATION = 7, -} control_mapping_t; - -typedef enum -{ - COMMAND_CODE_GET_TIME = 1, - COMMAND_CODE_GET_ID = 2, - COMMAND_CODE_SET_NAME = 100, - COMMAND_CODE_GET_NAME = 101, - COMMAND_CODE_SET_SCHEDULE = 102, - COMMAND_CODE_GET_SCHEDULE = 103, - COMMAND_CODE_SET_RELAY_NAME = 104, - COMMAND_CODE_GET_RELAY_NAME = 105, - COMMAND_CODE_PULSE = 200, -} command_code_t; - typedef enum { RELAY_DRIVER_NONE, diff --git a/include/macros.h b/include/macros.h index 5aca3d6..4242abe 100644 --- a/include/macros.h +++ b/include/macros.h @@ -1 +1,6 @@ +#ifndef CORE_MACROS_H +#define CORE_MACROS_H + #define STRLEN(s) ((sizeof(s)/sizeof(s[0])) - sizeof(s[0])) + +#endif /* CORE_MACROS_H */ diff --git a/src/command.c b/src/command.c index 141e5a6..098ca93 100644 --- a/src/command.c +++ b/src/command.c @@ -10,8 +10,96 @@ #include #include +typedef enum +{ + COMMAND_CODE_CONTROLLER_ID_GET = 0, + COMMAND_CODE_CONTROLLER_TIME_GET = 1, + COMMAND_CODE_CONTROLLER_NAME_SET = 2, + COMMAND_CODE_CONTROLLER_NAME_GET = 3, + + COMMAND_CODE_RELAY_SCHEDULES_SET = 100, + COMMAND_CODE_RELAY_SCHEDULES_GET = 101, + COMMAND_CODE_RELAY_NAME_SET = 102, + COMMAND_CODE_RELAY_NAME_GET = 103, + COMMAND_CODE_RELAY_PULSE = 200, + + COMMAND_CODE_SCHEDULE_UPDATE = 300 +} command_code_t; + +typedef enum +{ + COMMAND_MAPPING_CODE = 0, + COMMAND_MAPPING_NAME = 1, + COMMAND_MAPPING_RELAY_NUM = 2, + COMMAND_MAPPING_SCHEDULES_ARRAY = 3, + COMMAND_MAPPING_SCHEDULE_ID = 4, + COMMAND_MAPPING_PERIODS_COUNT = 5, + COMMAND_MAPPING_PERIODS_BLOB = 6, + COMMAND_MAPPING_PULSE_DURATION = 7, +} control_mapping_t; + int -command_set_relay_schedule(relay_t *relay) +command_schedule_update(schedule_t *schedule) +{ + char* payload; + size_t payload_size; + mpack_writer_t writer; + mpack_writer_init_growable(&writer, &payload, &payload_size); + + // 4 = code, periods_count, schedule_id, periods_blob + mpack_start_map(&writer, 4); + + mpack_write_uint(&writer, COMMAND_MAPPING_CODE); + mpack_write_u16(&writer, COMMAND_CODE_SCHEDULE_UPDATE); + + uint16_t *periods_blob = schedule_periods_to_blob(schedule); + uint16_t periods_count = periods_blob[0]; + + mpack_write_uint(&writer, COMMAND_MAPPING_PERIODS_COUNT); + mpack_write_u16(&writer, periods_count); + + mpack_write_uint(&writer, COMMAND_MAPPING_SCHEDULE_ID); + mpack_write_bin(&writer, (char*)schedule->uid, sizeof(uuid_t)); + + mpack_write_uint(&writer, COMMAND_MAPPING_PERIODS_BLOB); + // periods + 1 to skip length in periods[0] + // periods_count * 2 because each uint16_t is a timestamp. 2 are start and end + mpack_write_bin(&writer, (char*)(periods_blob + 1), sizeof(uint16_t) * periods_count * 2); + + free(periods_blob); + + mpack_finish_array(&writer); + + mpack_finish_map(&writer); + + // finish writing + if (mpack_writer_destroy(&writer) != mpack_ok) + { + LOGGER_ERR("an error occurred encoding the data"); + return 1; + } + + int result = 0; + + relay_t **relays = relay_get_with_schedule(schedule->id); + for(int i = 0; relays[i] != NULL; ++i) + { + controller_t *controller = controller_get_by_id(relays[i]->controller_id); + if(!controller) + { + LOGGER_ERR("couldn't find controller for relay %d\n", relays[i]->id); + continue; + } + controller_free(controller); + result |= command_send(controller, payload, payload_size); + } + relay_free_list(relays); + + return result; +} + +int +command_relay_schedules_set(relay_t *relay) { controller_t *controller = controller_get_by_id(relay->controller_id); if(!controller) @@ -29,7 +117,7 @@ command_set_relay_schedule(relay_t *relay) mpack_start_map(&writer, 3); mpack_write_uint(&writer, COMMAND_MAPPING_CODE); - mpack_write_u8(&writer, COMMAND_CODE_SET_SCHEDULE); + mpack_write_u16(&writer, COMMAND_CODE_RELAY_SCHEDULES_GET); mpack_write_uint(&writer, COMMAND_MAPPING_RELAY_NUM); mpack_write_u8(&writer, relay->number); @@ -39,27 +127,28 @@ command_set_relay_schedule(relay_t *relay) mpack_start_array(&writer, 7); for(int i = 0; i < 7; ++i) { + // 3 = uid, periods count, periods blob + mpack_start_map(&writer, 3); + uint16_t *periods_blob = schedule_periods_to_blob(relay->schedules[i]); uint16_t periods_count = periods_blob[0]; - // 3 = code, relaynum, schedules(array) - mpack_start_map(&writer, 3); + mpack_write_uint(&writer, COMMAND_MAPPING_SCHEDULE_ID); + mpack_write_bin(&writer, (char*)relay->schedules[i]->uid, sizeof(uuid_t)); mpack_write_uint(&writer, COMMAND_MAPPING_PERIODS_COUNT); mpack_write_u16(&writer, periods_count); - mpack_write_uint(&writer, COMMAND_MAPPING_SCHEDULE_ID); - mpack_write_bin(&writer, (char*)relay->schedules[0]->uid, sizeof(uuid_t)); - mpack_write_uint(&writer, COMMAND_MAPPING_PERIODS_BLOB); // periods + 1 to skip length in periods[0] // periods_count * 2 because each uint16_t is a timestamp. 2 are start and end mpack_write_bin(&writer, (char*)(periods_blob + 1), sizeof(uint16_t) * periods_count * 2); - mpack_finish_map(&writer); - free(periods_blob); + + mpack_finish_map(&writer); } + mpack_finish_array(&writer); mpack_finish_map(&writer); @@ -72,7 +161,7 @@ command_set_relay_schedule(relay_t *relay) return 1; } - int result = command_send(controller, COMMAND_CODE_SET_SCHEDULE, payload, payload_size); + int result = command_send(controller, payload, payload_size); controller_free(controller); free(payload); @@ -80,7 +169,7 @@ command_set_relay_schedule(relay_t *relay) } int -command_set_controller_name(controller_t *controller) +command_controller_name_set(controller_t *controller) { char* payload; size_t payload_size; @@ -91,7 +180,7 @@ command_set_controller_name(controller_t *controller) mpack_start_map(&writer, 2); mpack_write_uint(&writer, COMMAND_MAPPING_CODE); - mpack_write_u8(&writer, COMMAND_CODE_SET_NAME); + mpack_write_u16(&writer, COMMAND_CODE_CONTROLLER_NAME_SET); mpack_write_uint(&writer, COMMAND_MAPPING_NAME); mpack_write_cstr(&writer, controller->name); @@ -105,17 +194,15 @@ command_set_controller_name(controller_t *controller) return 1; } - int result = command_send(controller, COMMAND_CODE_SET_NAME, payload, payload_size); + int result = command_send(controller, payload, payload_size); free(payload); return result; } int -command_send(controller_t *controller, int command_code, char *payload, uint32_t payload_size) +command_send(controller_t *controller, char *payload, uint32_t payload_size) { - LOGGER_DEBUG("commanding %d\n", command_code); - int bytes_transferred; int fd_controller = helper_connect_tcp_server(controller->ip, controller->port); @@ -142,7 +229,7 @@ command_send(controller_t *controller, int command_code, char *payload, uint32_t } int -command_pulse(relay_t *relay, uint8_t duration) +command_relay_pulse(relay_t *relay, uint8_t duration) { controller_t *controller = controller_get_by_id(relay->controller_id); if(!controller) @@ -160,7 +247,7 @@ command_pulse(relay_t *relay, uint8_t duration) mpack_start_map(&writer, 3); mpack_write_uint(&writer, COMMAND_MAPPING_CODE); - mpack_write_u8(&writer, COMMAND_CODE_PULSE); + mpack_write_u16(&writer, COMMAND_CODE_RELAY_PULSE); mpack_write_uint(&writer, COMMAND_MAPPING_RELAY_NUM); mpack_write_u8(&writer, relay->number); @@ -178,7 +265,7 @@ command_pulse(relay_t *relay, uint8_t duration) return 1; } - int result = command_send(controller, COMMAND_CODE_PULSE, payload, payload_size); + int result = command_send(controller, payload, payload_size); controller_free(controller); free(payload); diff --git a/src/endpoints/api_v1_controllers_STR.c b/src/endpoints/api_v1_controllers_STR.c index 8056358..eb4c24d 100644 --- a/src/endpoints/api_v1_controllers_STR.c +++ b/src/endpoints/api_v1_controllers_STR.c @@ -147,7 +147,7 @@ api_v1_controllers_STR_PUT(struct mg_connection *nc, struct http_message *hm, en cJSON_Delete(json); json = controller_to_json(controller); - command_set_controller_name(controller); + command_controller_name_set(controller); endpoint_response_json(response, 200, json); cJSON_Delete(json); diff --git a/src/endpoints/api_v1_controllers_STR_relays_INT.c b/src/endpoints/api_v1_controllers_STR_relays_INT.c index ed2eea4..7705d3a 100644 --- a/src/endpoints/api_v1_controllers_STR_relays_INT.c +++ b/src/endpoints/api_v1_controllers_STR_relays_INT.c @@ -271,7 +271,7 @@ api_v1_controllers_STR_relays_INT_PUT(struct mg_connection *nc, struct http_mess json = relay_to_json(relay); LOGGER_DEBUG("commanding schedules"); - command_set_relay_schedule(relay); + command_relay_schedules_set(relay); endpoint_response_json(response, 200, json); cJSON_Delete(json); diff --git a/src/endpoints/api_v1_controllers_STR_relays_INT_pulse.c b/src/endpoints/api_v1_controllers_STR_relays_INT_pulse.c index 9f5e0b2..22b158a 100644 --- a/src/endpoints/api_v1_controllers_STR_relays_INT_pulse.c +++ b/src/endpoints/api_v1_controllers_STR_relays_INT_pulse.c @@ -62,7 +62,7 @@ api_v1_controllers_STR_relays_INT_pulse_POST(struct mg_connection *nc, struct ht } LOGGER_DEBUG("commanding pulse to relay %d for controller %s\n", args[1].value.v_int, args[0].value.v_str); - command_pulse(relay, duration); + command_relay_pulse(relay, duration); endpoint_response_text(response, 200, "", 0); relay_free(relay); diff --git a/src/endpoints/api_v1_schedules_STR.c b/src/endpoints/api_v1_schedules_STR.c index ca315b4..03613d1 100644 --- a/src/endpoints/api_v1_schedules_STR.c +++ b/src/endpoints/api_v1_schedules_STR.c @@ -146,11 +146,7 @@ api_v1_schedules_STR_PUT(struct mg_connection *nc, struct http_message *hm, endp return; } - relay_t **relays = relay_get_with_schedule(schedule->id); - for(int i = 0; relays[i] != NULL; ++i) - { - command_set_relay_schedule(relays[i]); - } + command_schedule_update(schedule); cJSON *json_tag; cJSON *json_tags = cJSON_GetObjectItemCaseSensitive(json, "tags"); @@ -180,7 +176,6 @@ api_v1_schedules_STR_PUT(struct mg_connection *nc, struct http_message *hm, endp endpoint_response_json(response, 200, json); cJSON_Delete(json); - relay_free_list(relays); schedule_free(schedule); } diff --git a/src/models/controller.c b/src/models/controller.c index b70184a..c237ad9 100644 --- a/src/models/controller.c +++ b/src/models/controller.c @@ -30,6 +30,7 @@ db_update_insert(controller_t *controller, sqlite3_stmt *stmt) return rc != SQLITE_DONE; } + static controller_t* controller_db_select_mapper(sqlite3_stmt *stmt) { @@ -82,7 +83,7 @@ controller_db_select(sqlite3_stmt *stmt) int row = 0; - while(true) + for(;;) { int s; diff --git a/src/models/schedule.c b/src/models/schedule.c index cd1d783..abb6850 100644 --- a/src/models/schedule.c +++ b/src/models/schedule.c @@ -78,7 +78,7 @@ schedule_db_select(sqlite3_stmt *stmt) int row = 0; - while(true) + for(;;) { int s; diff --git a/tests/controller.testing.ini b/tests/controller.testing.ini index b21277d..d3577f6 100644 --- a/tests/controller.testing.ini +++ b/tests/controller.testing.ini @@ -8,7 +8,7 @@ mqtt-port = 1886 mqtt-host = localhost relay-count = 10 -database = controller_db.lmdb +database = controller.sqlite log-level = debug log-file = stdout