diff --git a/config.cc b/config.cc index 9704029..9b8fd7b 100644 --- a/config.cc +++ b/config.cc @@ -7,4 +7,14 @@ namespace config uint16_t discover_port = 4419; int discover_timeout_ms = 2000; uint8_t discover_code_accept = 0; + uint8_t discover_code_reject = 100; + + uint8_t command_code_get_time = 1; + uint8_t command_code_get_id = 2; + uint8_t command_code_set_name = 100; + uint8_t command_code_get_name = 101; + uint8_t command_code_set_schedule = 102; + uint8_t command_code_get_schedule = 103; + uint8_t command_code_set_relay_name = 104; + uint8_t command_code_get_relay_name = 105; } diff --git a/config.h b/config.h index 3a630b4..d7ea5c8 100644 --- a/config.h +++ b/config.h @@ -10,6 +10,16 @@ namespace config extern uint16_t discover_port; extern int discover_timeout_ms; extern uint8_t discover_code_accept; + extern uint8_t discover_code_reject; + + extern uint8_t command_code_get_time; + extern uint8_t command_code_get_id; + extern uint8_t command_code_set_name; + extern uint8_t command_code_get_name; + extern uint8_t command_code_set_schedule; + extern uint8_t command_code_get_schedule; + extern uint8_t command_code_set_relay_name; + extern uint8_t command_code_get_relay_name; } #endif //EMGAUWA_CORE_CONFIG_H diff --git a/controllers/api_v1_controllers_discover.cc b/controllers/api_v1_controllers_discover.cc index 6927192..9bbf8f4 100644 --- a/controllers/api_v1_controllers_discover.cc +++ b/controllers/api_v1_controllers_discover.cc @@ -4,8 +4,8 @@ #include #include #include -#include #include "api_v1_controllers.h" + using namespace api::v1; void controllers::post_discover(const HttpRequestPtr &req, std::function &&callback) @@ -94,15 +94,20 @@ void controllers::post_discover(const HttpRequestPtr &req, std::functionactive = true; known_controllers[i]->update(); - free(known_controllers[i]); + delete known_controllers[i]; found_discovered_in_list = true; known_controllers[i] = known_controllers[i + 1]; } diff --git a/controllers/api_v1_devices_relays.cc b/controllers/api_v1_devices_relays.cc index 0d1c26a..72d34d9 100644 --- a/controllers/api_v1_devices_relays.cc +++ b/controllers/api_v1_devices_relays.cc @@ -2,6 +2,8 @@ #include #include #include +#include +#include #include "api_v1_controllers.h" using namespace api::v1; @@ -93,8 +95,22 @@ controllers::put_relays_one_by_id_and_num(const HttpRequestPtr &req, } else { + auto schedules = schedule_dbo::get_by_simple("id", body["active_schedule"].asCString(), (intptr_t)&sqlite3_bind_text); + auto controllers = controller_dbo::get_by_simple("id", controller_id.c_str(), (intptr_t)&sqlite3_bind_text); + + Json::Value payload; + payload["target"] = relay_num; + payload["schedule"] = schedules[0]->to_json(); + + Json::StreamWriterBuilder json_writer; + + controllers[0]->command(config::command_code_set_schedule, Json::writeString(json_writer, payload).c_str()); + auto resp = HttpResponse::newHttpJsonResponse(relay->to_json()); callback(resp); + + schedule_dbo::free_list(schedules); + controller_dbo::free_list(controllers); } delete relay; diff --git a/controllers/api_v1_schedules.cc b/controllers/api_v1_schedules.cc index 613f4bf..68ad221 100644 --- a/controllers/api_v1_schedules.cc +++ b/controllers/api_v1_schedules.cc @@ -48,6 +48,15 @@ schedules::get_one_by_id(const HttpRequestPtr &req, std::function &&callback, const std::string& schedule_id) { + if(strcmp(schedule_id.c_str(), "off") == 0) + { + auto resp = HttpResponse::newHttpResponse(); + resp->setStatusCode(k403Forbidden); + callback(resp); + + return; + } + schedule_dbo **schedules = schedule_dbo::get_by_simple("id", schedule_id.c_str(), (intptr_t) &sqlite3_bind_text); if(schedules[0]) @@ -100,6 +109,15 @@ void schedules::put_one_by_id(const HttpRequestPtr &req, std::function &&callback, const std::string &schedule_id) { + if(strcmp(schedule_id.c_str(), "off") == 0) + { + auto resp = HttpResponse::newHttpResponse(); + resp->setStatusCode(k403Forbidden); + callback(resp); + + return; + } + Json::Value body = *req->jsonObject(); schedule_dbo **schedules = schedule_dbo::get_by_simple("id", schedule_id.c_str(), (intptr_t) &sqlite3_bind_text); diff --git a/helpers.h b/helpers.h index 4fc3144..fe3080f 100644 --- a/helpers.h +++ b/helpers.h @@ -32,6 +32,9 @@ namespace helpers sqlite3_stmt* create_sql_filtered_query(const char *sql, sql_filter_builder **filters); + + int + open_tcp_connection(char* host, char* port); } #endif //EMGAUWA_CORE_HELPERS_H diff --git a/helpers/open_tcp_connection.cc b/helpers/open_tcp_connection.cc new file mode 100644 index 0000000..099b8fa --- /dev/null +++ b/helpers/open_tcp_connection.cc @@ -0,0 +1,33 @@ +#include +#include +#include + +int +helpers::open_tcp_connection(char *host, char *port) +{ + int s, status; + struct addrinfo hints{}, *res; + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + + if ((status = getaddrinfo(host, port, &hints, &res)) != 0) + { + LOG_ERROR << "Error getting addressinfo: " << gai_strerror(status); + freeaddrinfo(res); + return 0; + } + + s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); //creating Socket + + if ((status = connect(s, res->ai_addr, res->ai_addrlen)) != 0) + { + LOG_ERROR << "Error opening connection"; + freeaddrinfo(res); + return 0; + } + + freeaddrinfo(res); + + return s; +} \ No newline at end of file diff --git a/models/controller_dbo.cc b/models/controller_dbo.cc index 982944b..c4f5c7d 100644 --- a/models/controller_dbo.cc +++ b/models/controller_dbo.cc @@ -2,10 +2,17 @@ #include #include #include +#include +#include #include #include "controller_dbo.h" #include "globals.h" +controller_dbo::~controller_dbo() +{ + relay_dbo::free_list(this->relays); +} + static bool controller_db_update_insert(controller_dbo *controller, sqlite3_stmt *stmt) { int rc; @@ -85,6 +92,7 @@ controller_db_select(sqlite3_stmt *stmt) if (s == SQLITE_ROW) { controller_dbo *new_controller = controller_db_select_mapper(stmt); + new_controller->relays = relay_dbo::get_by_simple("controller_id", new_controller->id, (intptr_t)&sqlite3_bind_text); row++; all_controllers = (controller_dbo**)realloc(all_controllers, sizeof(controller_dbo*) * (row + 1)); @@ -153,10 +161,18 @@ controller_dbo::to_json() controller_json["name"] = this->name; controller_json["id"] = this->id; controller_json["ip"] = this->ip; - controller_json["port"] = this->port; + //controller_json["port"] = this->port; controller_json["relay_count"] = this->relay_count; controller_json["active"] = this->active; + + controller_json["relays"] = Json::arrayValue; + + for(int i = 0; this->relays[i] != nullptr; i++) + { + controller_json["relays"].append(this->relays[i]->to_json()); + } + return controller_json; } @@ -195,13 +211,32 @@ controller_dbo::get_by(helpers::sql_filter_builder **filters) return controller_db_select(stmt); } +bool +controller_dbo::command(int command_code, const char *payload) +{ + char port[6]; + sprintf(port, "%d", this->port); + + int controller_socket = helpers::open_tcp_connection(this->ip, port); + + if(!controller_socket) + { + return false; + } + + send(controller_socket, &command_code, 1, 0); + send(controller_socket, payload, strlen(payload), 0); + close(controller_socket); + + return true; +} + void controller_dbo::free_list(controller_dbo **controllers_list) { for(int i = 0; controllers_list[i] != nullptr; i++) { - free(controllers_list[i]); + delete controllers_list[i]; } free(controllers_list); } - diff --git a/models/controller_dbo.h b/models/controller_dbo.h index ed6060f..c87b8c2 100644 --- a/models/controller_dbo.h +++ b/models/controller_dbo.h @@ -5,6 +5,7 @@ #include #include #include +#include "relay_dbo.h" class controller_dbo { @@ -16,6 +17,9 @@ public: bool active; int port; int relay_count; + relay_dbo **relays; + + ~controller_dbo(); bool update(); @@ -29,9 +33,6 @@ public: Json::Value to_json(); - static void - free_list(controller_dbo **controllers_list); - static controller_dbo** get_by_simple(const char *key, const void *value, intptr_t bind_func); @@ -40,6 +41,12 @@ public: static controller_dbo** get_all(); + + bool + command(int command_code, const char *payload); + + static void + free_list(controller_dbo **controllers_list); }; diff --git a/models/relay_dbo.cc b/models/relay_dbo.cc index 5343788..bd8a1f3 100644 --- a/models/relay_dbo.cc +++ b/models/relay_dbo.cc @@ -6,6 +6,7 @@ #include "relay_dbo.h" #include "globals.h" #include "controller_dbo.h" +#include "schedule_dbo.h" static bool relay_db_update_insert(relay_dbo *relay, sqlite3_stmt *stmt) { @@ -41,7 +42,7 @@ relay_db_select_mapper(sqlite3_stmt *stmt) case 'a': // active_schedule_id strncpy(new_relay->active_schedule_id, (const char*)sqlite3_column_text(stmt, i), 33); break; - case 'd': // controller_id + case 'c': // controller_id strncpy(new_relay->controller_id, (const char*)sqlite3_column_text(stmt, i), 33); break; case 'i': @@ -81,6 +82,18 @@ relay_db_select(sqlite3_stmt *stmt) if (s == SQLITE_ROW) { relay_dbo *new_relay = relay_db_select_mapper(stmt); + schedule_dbo **schedules = schedule_dbo::get_by_simple("id", new_relay->active_schedule_id, (intptr_t)&sqlite3_bind_text); + + if(!schedules[0]) + { + free(schedules); + schedules = schedule_dbo::get_by_simple("id", "off", (intptr_t)&sqlite3_bind_text); + strcpy(new_relay->active_schedule_id, "off"); + } + + new_relay->active_schedule = schedules[0]; + + free(schedules); row++; all_relays = (relay_dbo**)realloc(all_relays, sizeof(relay_dbo*) * (row + 1)); @@ -150,6 +163,7 @@ relay_dbo::to_json() relay_json["number"] = this->number; relay_json["active_schedule_id"] = this->active_schedule_id; relay_json["controller_id"] = this->controller_id; + relay_json["active_schedule"] = this->active_schedule->to_json(); return relay_json; } diff --git a/models/relay_dbo.h b/models/relay_dbo.h index 25f1678..5ead660 100644 --- a/models/relay_dbo.h +++ b/models/relay_dbo.h @@ -5,6 +5,7 @@ #include #include #include +#include "schedule_dbo.h" class relay_dbo { @@ -15,6 +16,7 @@ public: int number; char controller_id[33]; char active_schedule_id[33]; + schedule_dbo *active_schedule; bool update();