From 10e41ca166f8dcb08c910004312cfab6f43bf1ad Mon Sep 17 00:00:00 2001 From: Tobias Reisinger Date: Thu, 7 May 2020 01:38:13 +0200 Subject: [PATCH] add: commands fix: timezone problem --- command.c | 136 ++++++++++++++++++ endpoints/api_v1_controllers_STR.c | 13 +- endpoints/api_v1_controllers_STR_relays_INT.c | 22 ++- endpoints/api_v1_controllers_discover.c | 1 + endpoints/api_v1_schedules_STR.c | 3 + helpers/get_day_of_week.c | 12 -- helpers/get_weekday.c | 11 ++ include/command.h | 16 +++ include/helpers.h | 3 +- models/controller.c | 9 +- models/relay.c | 4 +- 11 files changed, 209 insertions(+), 21 deletions(-) create mode 100644 command.c delete mode 100644 helpers/get_day_of_week.c create mode 100644 helpers/get_weekday.c create mode 100644 include/command.h diff --git a/command.c b/command.c new file mode 100644 index 0000000..73cbaa5 --- /dev/null +++ b/command.c @@ -0,0 +1,136 @@ +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +int +command_set_relay_schedule(relay_t *relay) +{ + controller_t *controller = controller_get_by_id(relay->controller_id); + if(!controller) + { + LOG_ERROR("couldn't find controller\n"); + return 1; + } + + char* payload; + size_t payload_size; + mpack_writer_t writer; + mpack_writer_init_growable(&writer, &payload, &payload_size); + + // 3 = code, relay num, relay name, schedules(array) + mpack_start_map(&writer, 3); + + mpack_write_uint(&writer, COMMAND_MAPPING_CODE); + mpack_write_u8(&writer, COMMAND_CODE_SET_SCHEDULE); + + mpack_write_uint(&writer, COMMAND_MAPPING_RELAY_NUM); + mpack_write_u8(&writer, relay->number); + + mpack_write_uint(&writer, COMMAND_MAPPING_SCHEDULES_ARRAY); + // 7 = days of week + mpack_start_array(&writer, 7); + for(int i = 0; i < 7; ++i) + { + 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_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_array(&writer); + + mpack_finish_map(&writer); + + // finish writing + if (mpack_writer_destroy(&writer) != mpack_ok) + { + LOG_ERROR("an error occurred encoding the data"); + controller_free(controller); + return 1; + } + + int result = command_send(controller, COMMAND_CODE_SET_SCHEDULE, payload, payload_size); + + controller_free(controller); + return result; +} + +int +command_set_controller_name(controller_t *controller) +{ + char* payload; + size_t payload_size; + mpack_writer_t writer; + mpack_writer_init_growable(&writer, &payload, &payload_size); + + // write the example on the msgpack homepage + mpack_start_map(&writer, 2); + + mpack_write_uint(&writer, COMMAND_MAPPING_CODE); + mpack_write_u8(&writer, COMMAND_CODE_SET_NAME); + + mpack_write_uint(&writer, COMMAND_MAPPING_NAME); + mpack_write_cstr(&writer, controller->name); + + mpack_finish_map(&writer); + + // finish writing + if (mpack_writer_destroy(&writer) != mpack_ok) + { + LOG_ERROR("an error occurred encoding the data"); + return 1; + } + return command_send(controller, COMMAND_CODE_SET_NAME, payload, payload_size); +} + +int +command_send(controller_t *controller, int command_code, char *payload, uint32_t payload_size) +{ + LOG_DEBUG("commanding %d\n", command_code); + + int bytes_transferred; + + int fd_controller = helper_connect_tcp_server(controller->ip, controller->port); + + if(fd_controller == -1) + { + LOG_ERROR("can't open command socket %s:%d\n", controller->ip, controller->port); + return 1; + } + + if((bytes_transferred = send(fd_controller, &payload_size, sizeof(payload_size), 0)) <= 0) + { + LOG_ERROR("error during sending size\n"); + return 1; + } + if((bytes_transferred = send(fd_controller, payload, payload_size, 0)) <= 0) + { + LOG_ERROR("error during sending\n"); + return 1; + } + + close(fd_controller); + return 0; +} diff --git a/endpoints/api_v1_controllers_STR.c b/endpoints/api_v1_controllers_STR.c index c6646c7..1e3d7a9 100644 --- a/endpoints/api_v1_controllers_STR.c +++ b/endpoints/api_v1_controllers_STR.c @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -114,16 +115,24 @@ api_v1_controllers_STR_PUT(struct mg_connection *c, endpoint_args_t *args, struc cJSON_Delete(json); json = controller_to_json(controller); + int result = command_set_controller_name(controller); + int status_code = 200; + + if(result) + { + status_code = 504; + } + char *json_str = cJSON_Print(json); if (json_str == NULL) { LOG_ERROR("failed to print controller json\n"); - mg_send_head(c, 200, 2, "Content-Type: application/json\r\n" STANDARD_HEADERS); + mg_send_head(c, status_code, 2, "Content-Type: application/json\r\n" STANDARD_HEADERS); mg_printf(c, "{}"); } else { - mg_send_head(c, 200, strlen(json_str), "Content-Type: application/json\r\n" STANDARD_HEADERS); + mg_send_head(c, status_code, strlen(json_str), "Content-Type: application/json\r\n" STANDARD_HEADERS); mg_printf(c, "%s", json_str); free(json_str); } diff --git a/endpoints/api_v1_controllers_STR_relays_INT.c b/endpoints/api_v1_controllers_STR_relays_INT.c index 7bdc2d1..601686f 100644 --- a/endpoints/api_v1_controllers_STR_relays_INT.c +++ b/endpoints/api_v1_controllers_STR_relays_INT.c @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -104,7 +105,9 @@ api_v1_controllers_STR_relays_INT_PUT(struct mg_connection *c, endpoint_args_t * { relay->schedules[i] = schedule_get_by_uid(tmp_uuid); } - relay->active_schedule = schedule_get_by_uid(tmp_uuid); + time_t timestamp = time(NULL); + struct tm *time_struct = localtime(×tamp); + relay->active_schedule = relay->schedules[helper_get_weekday(time_struct)]; } cJSON *json = cJSON_ParseWithLength(hm->body.p, hm->body.len); @@ -169,7 +172,10 @@ api_v1_controllers_STR_relays_INT_PUT(struct mg_connection *c, endpoint_args_t * cJSON *json_active_schedule_uid = cJSON_GetObjectItemCaseSensitive(json_active_schedule, "id"); if(cJSON_IsString(json_active_schedule_uid) && json_active_schedule_uid->valuestring) { - int day_of_week = helper_get_weekday(time(NULL)); + time_t timestamp = time(NULL); + struct tm *time_struct = localtime(×tamp); + int day_of_week = helper_get_weekday(time_struct); + schedule_free(relay->schedules[day_of_week]); uuid_t target_uid; @@ -220,16 +226,24 @@ api_v1_controllers_STR_relays_INT_PUT(struct mg_connection *c, endpoint_args_t * cJSON_Delete(json); json = relay_to_json(relay); + int result = command_set_relay_schedule(relay); + int status_code = 200; + + if(result) + { + status_code = 504; + } + char *json_str = cJSON_Print(json); if (json_str == NULL) { LOG_ERROR("failed to print relay json\n"); - mg_send_head(c, 200, 2, "Content-Type: application/json\r\n" STANDARD_HEADERS); + mg_send_head(c, status_code, 2, "Content-Type: application/json\r\n" STANDARD_HEADERS); mg_printf(c, "{}"); } else { - mg_send_head(c, 200, strlen(json_str), "Content-Type: application/json\r\n" STANDARD_HEADERS); + mg_send_head(c, status_code, strlen(json_str), "Content-Type: application/json\r\n" STANDARD_HEADERS); mg_printf(c, "%s", json_str); free(json_str); } diff --git a/endpoints/api_v1_controllers_discover.c b/endpoints/api_v1_controllers_discover.c index 971dd8b..94a954c 100644 --- a/endpoints/api_v1_controllers_discover.c +++ b/endpoints/api_v1_controllers_discover.c @@ -244,6 +244,7 @@ api_v1_controllers_discover_POST(struct mg_connection *c, endpoint_args_t *args, discovered_controller->active = 1; controller_save(discovered_controller); + controller_free(discovered_controller); } mpack_tree_destroy(&tree); free(answer_payload); diff --git a/endpoints/api_v1_schedules_STR.c b/endpoints/api_v1_schedules_STR.c index 6643ccd..a87d51a 100644 --- a/endpoints/api_v1_schedules_STR.c +++ b/endpoints/api_v1_schedules_STR.c @@ -83,6 +83,9 @@ api_v1_schedules_STR_PUT(struct mg_connection *c, endpoint_args_t *args, struct LOG_ERROR("error before: %s\n", error_ptr); } cJSON_Delete(json); + mg_send_head(c, 400, 2, "Content-Type: application/json\r\n" STANDARD_HEADERS); + mg_printf(c, "{}"); + return; } cJSON *json_name = cJSON_GetObjectItemCaseSensitive(json, "name"); diff --git a/helpers/get_day_of_week.c b/helpers/get_day_of_week.c deleted file mode 100644 index 0214f63..0000000 --- a/helpers/get_day_of_week.c +++ /dev/null @@ -1,12 +0,0 @@ -#include - -#include - -int -helper_get_weekday(const time_t timestamp_now) -{ - struct tm *now = localtime(×tamp_now); - int wday_sun_sat = now->tm_wday; - int wday_mon_sun = (wday_sun_sat + 6) % 7; - return wday_mon_sun; -} diff --git a/helpers/get_weekday.c b/helpers/get_weekday.c new file mode 100644 index 0000000..68f029e --- /dev/null +++ b/helpers/get_weekday.c @@ -0,0 +1,11 @@ +#include + +#include + +int +helper_get_weekday(const struct tm *time_struct) +{ + int wday_sun_sat = time_struct->tm_wday; + int wday_mon_sun = (wday_sun_sat + 6) % 7; + return wday_mon_sun; +} diff --git a/include/command.h b/include/command.h new file mode 100644 index 0000000..01b045f --- /dev/null +++ b/include/command.h @@ -0,0 +1,16 @@ +#ifndef CORE_COMMAND_H +#define CORE_COMMAND_H + +#include +#include + +int +command_set_relay_schedule(relay_t *relay); + +int +command_set_controller_name(controller_t *controller); + +int +command_send(controller_t *controller, int command_code, char *payload, uint32_t payload_size); + +#endif /* CORE_COMMAND_H */ diff --git a/include/helpers.h b/include/helpers.h index a958bd5..f382679 100644 --- a/include/helpers.h +++ b/include/helpers.h @@ -1,6 +1,7 @@ #ifndef CORE_HELPERS_H #define CORE_HELPERS_H +#include #include #include @@ -29,6 +30,6 @@ void helper_parse_cli(int argc, const char **argv, config_t *config); int -helper_get_weekday(const time_t timestamp_now); +helper_get_weekday(const struct tm *time_struct); #endif /* CORE_HELPERS_H */ diff --git a/models/controller.c b/models/controller.c index 7ad9be7..3007159 100644 --- a/models/controller.c +++ b/models/controller.c @@ -235,7 +235,14 @@ controller_to_json(controller_t *controller) } cJSON_AddItemToObject(json, "active", json_active); - //TODO add relays + relay_t **relays = relay_get_by_controller_id(controller->id); + cJSON *json_relays = cJSON_CreateArray(); + for(int i = 0; relays[i] != NULL; ++i) + { + cJSON_AddItemToArray(json_relays, relay_to_json(relays[i])); + } + cJSON_AddItemToObject(json, "relays", json_relays); + relay_free_list(relays); return json; } diff --git a/models/relay.c b/models/relay.c index d86e0f9..e876624 100644 --- a/models/relay.c +++ b/models/relay.c @@ -169,7 +169,9 @@ relay_remove(relay_t *relay) void relay_reload_active_schedule(relay_t *relay) { - relay->active_schedule = relay->schedules[helper_get_weekday(time(NULL))]; + time_t timestamp = time(NULL); + struct tm *time_struct = localtime(×tamp); + relay->active_schedule = relay->schedules[helper_get_weekday(time_struct)]; } void