2020-05-06 23:38:13 +00:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <sys/socket.h>
|
|
|
|
|
|
|
|
#include <mpack.h>
|
2020-08-13 09:26:06 +00:00
|
|
|
|
|
|
|
#include <command.h>
|
2020-05-06 23:38:13 +00:00
|
|
|
#include <logger.h>
|
|
|
|
#include <helpers.h>
|
|
|
|
#include <enums.h>
|
|
|
|
#include <models/controller.h>
|
|
|
|
|
2020-08-24 13:59:46 +00:00
|
|
|
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_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;
|
|
|
|
}
|
|
|
|
|
2020-05-06 23:38:13 +00:00
|
|
|
int
|
2020-08-24 13:59:46 +00:00
|
|
|
command_relay_schedules_set(relay_t *relay)
|
2020-05-06 23:38:13 +00:00
|
|
|
{
|
|
|
|
controller_t *controller = controller_get_by_id(relay->controller_id);
|
|
|
|
if(!controller)
|
|
|
|
{
|
2020-07-26 19:00:05 +00:00
|
|
|
LOGGER_ERR("couldn't find controller\n");
|
2020-05-06 23:38:13 +00:00
|
|
|
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);
|
2020-08-24 13:59:46 +00:00
|
|
|
mpack_write_u16(&writer, COMMAND_CODE_RELAY_SCHEDULES_GET);
|
2020-05-06 23:38:13 +00:00
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
2020-08-24 13:59:46 +00:00
|
|
|
// 3 = uid, periods count, periods blob
|
|
|
|
mpack_start_map(&writer, 3);
|
|
|
|
|
2020-05-06 23:38:13 +00:00
|
|
|
uint16_t *periods_blob = schedule_periods_to_blob(relay->schedules[i]);
|
|
|
|
uint16_t periods_count = periods_blob[0];
|
|
|
|
|
2020-08-24 13:59:46 +00:00
|
|
|
mpack_write_uint(&writer, COMMAND_MAPPING_SCHEDULE_ID);
|
|
|
|
mpack_write_bin(&writer, (char*)relay->schedules[i]->uid, sizeof(uuid_t));
|
2020-05-06 23:38:13 +00:00
|
|
|
|
|
|
|
mpack_write_uint(&writer, COMMAND_MAPPING_PERIODS_COUNT);
|
|
|
|
mpack_write_u16(&writer, periods_count);
|
|
|
|
|
|
|
|
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);
|
2020-08-24 13:59:46 +00:00
|
|
|
|
|
|
|
mpack_finish_map(&writer);
|
2020-05-06 23:38:13 +00:00
|
|
|
}
|
2020-08-24 13:59:46 +00:00
|
|
|
|
2020-05-06 23:38:13 +00:00
|
|
|
mpack_finish_array(&writer);
|
|
|
|
|
|
|
|
mpack_finish_map(&writer);
|
|
|
|
|
|
|
|
// finish writing
|
|
|
|
if (mpack_writer_destroy(&writer) != mpack_ok)
|
|
|
|
{
|
2020-07-26 19:00:05 +00:00
|
|
|
LOGGER_ERR("an error occurred encoding the data");
|
2020-05-06 23:38:13 +00:00
|
|
|
controller_free(controller);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2020-08-24 13:59:46 +00:00
|
|
|
int result = command_send(controller, payload, payload_size);
|
2020-05-06 23:38:13 +00:00
|
|
|
|
|
|
|
controller_free(controller);
|
2020-05-07 00:38:58 +00:00
|
|
|
free(payload);
|
2020-05-06 23:38:13 +00:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2020-08-24 13:59:46 +00:00
|
|
|
command_controller_name_set(controller_t *controller)
|
2020-05-06 23:38:13 +00:00
|
|
|
{
|
|
|
|
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);
|
2020-08-24 13:59:46 +00:00
|
|
|
mpack_write_u16(&writer, COMMAND_CODE_CONTROLLER_NAME_SET);
|
2020-05-06 23:38:13 +00:00
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
2020-07-26 19:00:05 +00:00
|
|
|
LOGGER_ERR("an error occurred encoding the data");
|
2020-05-06 23:38:13 +00:00
|
|
|
return 1;
|
|
|
|
}
|
2020-05-07 00:38:58 +00:00
|
|
|
|
2020-08-24 13:59:46 +00:00
|
|
|
int result = command_send(controller, payload, payload_size);
|
2020-05-07 00:38:58 +00:00
|
|
|
|
|
|
|
free(payload);
|
|
|
|
return result;
|
2020-05-06 23:38:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2020-08-24 13:59:46 +00:00
|
|
|
command_send(controller_t *controller, char *payload, uint32_t payload_size)
|
2020-05-06 23:38:13 +00:00
|
|
|
{
|
|
|
|
int bytes_transferred;
|
|
|
|
|
|
|
|
int fd_controller = helper_connect_tcp_server(controller->ip, controller->port);
|
|
|
|
|
|
|
|
if(fd_controller == -1)
|
|
|
|
{
|
2020-07-26 19:00:05 +00:00
|
|
|
LOGGER_ERR("can't open command socket %s:%d\n", controller->ip, controller->port);
|
2020-05-06 23:38:13 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if((bytes_transferred = send(fd_controller, &payload_size, sizeof(payload_size), 0)) <= 0)
|
|
|
|
{
|
2020-07-26 19:00:05 +00:00
|
|
|
LOGGER_ERR("error during sending size\n");
|
2020-05-06 23:38:13 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
if((bytes_transferred = send(fd_controller, payload, payload_size, 0)) <= 0)
|
|
|
|
{
|
2020-07-26 19:00:05 +00:00
|
|
|
LOGGER_ERR("error during sending\n");
|
2020-05-06 23:38:13 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
close(fd_controller);
|
|
|
|
return 0;
|
|
|
|
}
|
2020-06-27 16:31:36 +00:00
|
|
|
|
|
|
|
int
|
2020-08-24 13:59:46 +00:00
|
|
|
command_relay_pulse(relay_t *relay, uint8_t duration)
|
2020-06-27 16:31:36 +00:00
|
|
|
{
|
|
|
|
controller_t *controller = controller_get_by_id(relay->controller_id);
|
|
|
|
if(!controller)
|
|
|
|
{
|
2020-07-26 19:00:05 +00:00
|
|
|
LOGGER_ERR("couldn't find controller\n");
|
2020-06-27 16:31:36 +00:00
|
|
|
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);
|
2020-08-24 13:59:46 +00:00
|
|
|
mpack_write_u16(&writer, COMMAND_CODE_RELAY_PULSE);
|
2020-06-27 16:31:36 +00:00
|
|
|
|
|
|
|
mpack_write_uint(&writer, COMMAND_MAPPING_RELAY_NUM);
|
|
|
|
mpack_write_u8(&writer, relay->number);
|
|
|
|
|
|
|
|
mpack_write_uint(&writer, COMMAND_MAPPING_PULSE_DURATION);
|
|
|
|
mpack_write_u8(&writer, duration);
|
|
|
|
|
|
|
|
mpack_finish_map(&writer);
|
|
|
|
|
|
|
|
// finish writing
|
|
|
|
if (mpack_writer_destroy(&writer) != mpack_ok)
|
|
|
|
{
|
2020-07-26 19:00:05 +00:00
|
|
|
LOGGER_ERR("an error occurred encoding the data");
|
2020-06-27 16:31:36 +00:00
|
|
|
controller_free(controller);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2020-08-24 13:59:46 +00:00
|
|
|
int result = command_send(controller, payload, payload_size);
|
2020-06-27 16:31:36 +00:00
|
|
|
|
|
|
|
controller_free(controller);
|
|
|
|
free(payload);
|
|
|
|
return result;
|
|
|
|
}
|