diff --git a/controllers/api_v1_controllers.cc b/controllers/api_v1_controllers.cc index 484d921..32b38d3 100644 --- a/controllers/api_v1_controllers.cc +++ b/controllers/api_v1_controllers.cc @@ -1,5 +1,6 @@ #include #include +#include #include "api_v1_controllers.h" using namespace api::v1; @@ -133,7 +134,14 @@ controllers::put_one_by_id(const HttpRequestPtr &req, std::functionupdate()) { - controllers[0]->command(config::command_code_set_name, controllers[0]->name); + binn *map = binn_map(); + + binn_map_set_uint8(map, COMMAND_MAPPING_CODE, config::command_code_set_name); + binn_map_set_str(map, COMMAND_MAPPING_NAME, controllers[0]->name); + + controllers[0]->command(map); + + binn_free(map); resp = HttpResponse::newHttpJsonResponse(controllers[0]->to_json()); } else diff --git a/controllers/api_v1_controllers_discover.cc b/controllers/api_v1_controllers_discover.cc index 75b1bd1..9b676c6 100644 --- a/controllers/api_v1_controllers_discover.cc +++ b/controllers/api_v1_controllers_discover.cc @@ -120,6 +120,10 @@ void controllers::post_discover(const HttpRequestPtr &req, std::functionid, discovered_id) == 0) { known_controllers[i]->active = true; + strncpy(known_controllers[i]->name, discovered_name, 128); + known_controllers[i]->name[127] = '\0'; + known_controllers[i]->port = discovered_command_port; + known_controllers[i]->relay_count = discovered_relay_count; known_controllers[i]->update(); delete known_controllers[i]; found_discovered_in_list = true; diff --git a/controllers/api_v1_controllers_relays.cc b/controllers/api_v1_controllers_relays.cc index 3c79a04..fdf8cb4 100644 --- a/controllers/api_v1_controllers_relays.cc +++ b/controllers/api_v1_controllers_relays.cc @@ -4,6 +4,7 @@ #include #include #include +#include #include "api_v1_controllers.h" using namespace api::v1; @@ -75,6 +76,7 @@ controllers::put_relays_one_by_id_and_num(const HttpRequestPtr &req, uuid_t controller_id; if(uuid_parse(controller_id_str.c_str(), controller_id)) { + LOG_DEBUG << "bad uuid"; auto resp = HttpResponse::newHttpResponse(); resp->setStatusCode(k400BadRequest); callback(resp); @@ -82,6 +84,7 @@ controllers::put_relays_one_by_id_and_num(const HttpRequestPtr &req, } if(!relay_dbo::valid_num_for_controller(controller_id, relay_num)) { + LOG_DEBUG << "invalid num for controller"; auto resp = HttpResponse::newHttpResponse(); resp->setStatusCode(k400BadRequest); callback(resp); @@ -90,8 +93,9 @@ controllers::put_relays_one_by_id_and_num(const HttpRequestPtr &req, Json::Value body = *req->getJsonObject(); uuid_t active_schedule_id; - if(!schedule_dbo::parse_id(body["active_schedule"].asCString(), active_schedule_id)) + if(schedule_dbo::parse_id(body["active_schedule"].asCString(), active_schedule_id)) { + LOG_DEBUG << "bad active_schedule uuid"; auto resp = HttpResponse::newHttpResponse(); resp->setStatusCode(k400BadRequest); callback(resp); @@ -134,13 +138,23 @@ controllers::put_relays_one_by_id_and_num(const HttpRequestPtr &req, auto schedules = schedule_dbo::get_by_simple("id", active_schedule_id, (intptr_t)&sqlite3_bind_blob, sizeof(uuid_t)); auto controllers = controller_dbo::get_by_simple("id", controller_id, (intptr_t)&sqlite3_bind_blob, sizeof(uuid_t)); - Json::Value payload; - payload["target"] = relay_num; - payload["schedule"] = schedules[0]->to_json(); + uint16_t *periods = schedules[0]->periods->to_blob(); + uint16_t periods_count = periods[0]; + binn *map = binn_map(); - Json::StreamWriterBuilder json_writer; + binn_map_set_uint8(map, COMMAND_MAPPING_CODE, config::command_code_set_schedule); + binn_map_set_uint8(map, COMMAND_MAPPING_RELAY_NUM, relay_num); + binn_map_set_blob(map, COMMAND_MAPPING_SCHEDULE_ID, schedules[0]->id, sizeof(uuid_t)); + binn_map_set_uint16(map, COMMAND_MAPPING_PERIODS_COUNT, periods_count); - controllers[0]->command(config::command_code_set_schedule, Json::writeString(json_writer, payload).c_str()); + // periods + 1 to skip length in periods[0] + // periods_count * 2 because each uint16_t is a timestamp. 2 are start and end + binn_map_set_blob(map, COMMAND_MAPPING_PERIODS_BLOB, periods + 1, sizeof(uint16_t) * periods_count * 2); + + controllers[0]->command(map); + + binn_free(map); + free(periods); auto resp = HttpResponse::newHttpJsonResponse(relay->to_json()); callback(resp); diff --git a/enums.h b/enums.h new file mode 100644 index 0000000..b367307 --- /dev/null +++ b/enums.h @@ -0,0 +1,14 @@ +#ifndef CORE_ENUM_H +#define CORE_ENUM_H + +enum control_mapping +{ + COMMAND_MAPPING_CODE = 0, + COMMAND_MAPPING_NAME = 1, + COMMAND_MAPPING_RELAY_NUM = 2, + COMMAND_MAPPING_SCHEDULE_ID = 3, + COMMAND_MAPPING_PERIODS_COUNT = 4, + COMMAND_MAPPING_PERIODS_BLOB = 5, +}; + +#endif /* CORE_ENUM_H */ diff --git a/helpers/open_tcp_connection.cc b/helpers/open_tcp_connection.cc index 07055fe..1cfb765 100644 --- a/helpers/open_tcp_connection.cc +++ b/helpers/open_tcp_connection.cc @@ -1,5 +1,7 @@ #include #include +#include +#include #include int @@ -22,7 +24,7 @@ helpers::open_tcp_connection(char *host, char *port) if ((status = connect(s, res->ai_addr, res->ai_addrlen)) != 0) { - LOG_ERROR << "Error opening connection " << status; + LOG_ERROR << "Error opening connection " << strerror(errno); freeaddrinfo(res); return 0; } @@ -30,4 +32,4 @@ helpers::open_tcp_connection(char *host, char *port) freeaddrinfo(res); return s; -} \ No newline at end of file +} diff --git a/models/controller_dbo.cc b/models/controller_dbo.cc index 565f7c2..692d727 100644 --- a/models/controller_dbo.cc +++ b/models/controller_dbo.cc @@ -5,6 +5,9 @@ #include #include #include +#include +#include + #include "controller_dbo.h" #include "globals.h" @@ -228,23 +231,37 @@ controller_dbo::get_by(helpers::sql_filter_builder **filters) } bool -controller_dbo::command(int command_code, const char *payload) +controller_dbo::command(binn *payload) { + LOG_DEBUG << "Commanding " << binn_map_uint8(payload, COMMAND_MAPPING_CODE); + + int bytes_transferred; char port_str[6]; sprintf(port_str, "%d", this->port); - int controller_socket = helpers::open_tcp_connection(this->ip, port_str); + void *payload_ptr = binn_ptr(payload); + uint32_t payload_size = binn_size(payload); - if(!controller_socket) + int fd_controller = helpers::open_tcp_connection(this->ip, port_str); + + if(fd_controller == -1) { LOG_ERROR << "Can't open command socket " << this->ip << ":" << port_str; return false; } - LOG_DEBUG << "Commanding (" << command_code << ") " << payload; - send(controller_socket, &command_code, 1, 0); - send(controller_socket, payload, strlen(payload), 0); - close(controller_socket); + if((bytes_transferred = send(fd_controller, &payload_size, sizeof(payload_size), 0)) <= 0) + { + LOG_ERROR << "error during sending size"; + return false; + } + if((bytes_transferred = send(fd_controller, payload_ptr, payload_size, 0)) <= 0) + { + LOG_ERROR << "error during sending"; + return false; + } + + close(fd_controller); return true; } diff --git a/models/controller_dbo.h b/models/controller_dbo.h index db4138f..7410ad7 100644 --- a/models/controller_dbo.h +++ b/models/controller_dbo.h @@ -6,6 +6,7 @@ #include #include #include +#include #include "relay_dbo.h" class controller_dbo @@ -45,7 +46,7 @@ public: get_all(); bool - command(int command_code, const char *payload); + command(binn *payload); static void free_list(controller_dbo **controllers_list); diff --git a/models/period_list.cc b/models/period_list.cc index 820c23c..f5b07c5 100644 --- a/models/period_list.cc +++ b/models/period_list.cc @@ -55,7 +55,7 @@ period_list::to_json() } uint16_t* -period_list::to_db_blob() +period_list::to_blob() { auto result = (uint16_t*)malloc(sizeof(uint16_t) * ((this->length * 2) + 1)); diff --git a/models/period_list.h b/models/period_list.h index 2da4302..84302d7 100644 --- a/models/period_list.h +++ b/models/period_list.h @@ -22,7 +22,7 @@ public: to_json(); uint16_t* - to_db_blob(); + to_blob(); }; #endif //EMGAUWA_CORE_PERIOD_LIST_H diff --git a/models/schedule_dbo.cc b/models/schedule_dbo.cc index 5cf089b..c84b8ab 100644 --- a/models/schedule_dbo.cc +++ b/models/schedule_dbo.cc @@ -8,7 +8,7 @@ static bool schedule_db_update_insert(schedule_dbo *schedule, sqlite3_stmt *stmt) { int rc; - uint16_t *periods_blob = schedule->periods->to_db_blob(); + uint16_t *periods_blob = schedule->periods->to_blob(); int blob_size = (int)sizeof(uint16_t) * ((periods_blob[0] * 2) + 1); sqlite3_bind_blob(stmt, 1, schedule->id, sizeof(uuid_t), SQLITE_STATIC);