diff --git a/main/ciot.c b/main/ciot.c index 5152388..36c178e 100644 --- a/main/ciot.c +++ b/main/ciot.c @@ -65,46 +65,48 @@ static ciot_err_t ciot_iface_event_handler(void *sender, ciot_iface_event_t *eve return ciot_iface_send_data(iface_snd, &event->msg, event->size); } - if (event->msg.iface.id >= this->iface_list.count || event->msg.iface.id < 0) + if (event->msg.iface.id >= this->iface_list.count) { event->msg.error = CIOT_ERR_INVALID_ID; event->size = CIOT_MSG_SIZE; return ciot_iface_send_data(this->iface_rsp, &event->msg, event->size); } - switch (event->id) - { - case CIOT_IFACE_EVENT_REQUEST: - if (sync_msg) - { - ciot_iface_process_msg(iface_sel, &event->msg, &event->size); - event->msg.iface = iface_sel->info; - return ciot_iface_send_data(iface_snd, &event->msg, event->size); - } - else - { - this->iface_rsp = iface_snd; - this->iface_busy = iface_sel; - this->state = CIOT_STATE_BUSY; - return ciot_iface_process_msg(iface_sel, &event->msg, &event->size); - } - break; - case CIOT_IFACE_EVENT_RESPONSE: - if (this->state == CIOT_STATE_BUSY) - { - this->state = CIOT_STATE_IDLE; - event->msg.iface = iface_sel->info; - return ciot_iface_send_data(this->iface_rsp, &event->msg, event->size); - } - else - { - return CIOT_ERR_INVALID_ID; - } - case CIOT_IFACE_EVENT_CUSTOM: - // return custom event to main application - return CIOT_OK; - default: - event->msg.error = CIOT_ERR_INVALID_TYPE; - return ciot_iface_send_data(iface_snd, &event->msg, CIOT_MSG_SIZE); - } + // switch (event->id) + // { + // case CIOT_IFACE_EVENT_REQUEST: + // if (sync_msg) + // { + // ciot_iface_process_msg(iface_sel, &event->msg, &event->size); + // event->msg.iface = iface_sel->info; + // return ciot_iface_send_data(iface_snd, &event->msg, event->size); + // } + // else + // { + // this->iface_rsp = iface_snd; + // this->iface_busy = iface_sel; + // this->state = CIOT_STATE_BUSY; + // return ciot_iface_process_msg(iface_sel, &event->msg, &event->size); + // } + // break; + // case CIOT_IFACE_EVENT_RESPONSE: + // if (this->state == CIOT_STATE_BUSY) + // { + // this->state = CIOT_STATE_IDLE; + // event->msg.iface = iface_sel->info; + // return ciot_iface_send_data(this->iface_rsp, &event->msg, event->size); + // } + // else + // { + // return CIOT_ERR_INVALID_ID; + // } + // case CIOT_IFACE_EVENT_CUSTOM: + // // return custom event to main application + // return CIOT_OK; + // default: + // event->msg.error = CIOT_ERR_INVALID_TYPE; + // return ciot_iface_send_data(iface_snd, &event->msg, CIOT_MSG_SIZE); + // } + + return CIOT_ERR_NOT_IMPLEMENTED; } diff --git a/main/data/ciot_https_data.h b/main/data/ciot_https_data.h index 2dc0ce9..3e68de2 100644 --- a/main/data/ciot_https_data.h +++ b/main/data/ciot_https_data.h @@ -35,6 +35,7 @@ typedef struct __attribute__((packed)) { char address[CIOT_HTTPS_ADDRESS_LEN]; char route[CIOT_HTTPS_ROUTE_LEN]; + int port; } ciot_https_cfg_t; typedef struct __attribute__((packed)) diff --git a/main/data/ciot_mqttc_data.h b/main/data/ciot_mqttc_data.h index 2b2921d..ab02f42 100644 --- a/main/data/ciot_mqttc_data.h +++ b/main/data/ciot_mqttc_data.h @@ -29,6 +29,7 @@ typedef enum __attribute__((packed)) CIOT_MQTT_STATE_ERROR = -1, CIOT_MQTT_STATE_DISCONNECTED, CIOT_MQTT_STATE_CONNECTING, + CIOT_MQTT_STATE_DISCONNECTING, CIOT_MQTT_STATE_CONNECTED, } ciot_mqttc_state_t; diff --git a/main/data/ciot_msg_data.h b/main/data/ciot_msg_data.h index 9faae39..2f55fab 100644 --- a/main/data/ciot_msg_data.h +++ b/main/data/ciot_msg_data.h @@ -28,7 +28,8 @@ typedef enum __attribute__((packed)) CIOT_MSG_TYPE_STOP, CIOT_MSG_TYPE_GET_CONFIG, CIOT_MSG_TYPE_GET_STATUS, - CIOT_MSG_TYPE_REQUEST + CIOT_MSG_TYPE_REQUEST, + CIOT_MSG_TYPE_EVENT, } ciot_msg_type_t; typedef enum __attribute__((packed)) diff --git a/main/infra/ciot_mqttc.h b/main/infra/ciot_mqttc.h index 9647a37..285dbae 100644 --- a/main/infra/ciot_mqttc.h +++ b/main/infra/ciot_mqttc.h @@ -20,7 +20,9 @@ typedef struct ciot_mqtt *ciot_mqttc_t; typedef enum ciot_mqttc_event_id { - CIOT_MQTT_EVENT_DATA = CIOT_IFACE_EVENT_CUSTOM + CIOT_MQTT_EVENT_DATA = CIOT_IFACE_EVENT_CUSTOM, + CIOT_MQTT_EVENT_SUBSCRIBED, + CIOT_MQTT_EVENT_UNSUBCRIBED, } ciot_mqttc_event_id_t; ciot_mqttc_t ciot_mqttc_new(void *handle); diff --git a/main/infra/idf/ciot_https.c b/main/infra/idf/ciot_https.c index 72581bc..9718217 100644 --- a/main/infra/idf/ciot_https.c +++ b/main/infra/idf/ciot_https.c @@ -10,20 +10,59 @@ */ #include "ciot_https.h" +#include "esp_log.h" +#include "esp_http_server.h" + +struct ciot_https +{ + ciot_iface_t iface; + ciot_https_cfg_t cfg; + ciot_https_status_t status; + httpd_handle_t handle; + httpd_req_t *req; +}; + +static ciot_err_t ciot_https_register_routes(ciot_https_t this); +static esp_err_t ciot_post_handler(httpd_req_t *req); + +static const char *TAG = "ciot_https"; ciot_https_t ciot_https_new(void *handle) { - return NULL; + ciot_https_t this = calloc(1, sizeof(struct ciot_https)); + this->iface.base.ptr = this; + this->iface.base.start = (ciot_iface_start_fn *)ciot_https_start; + this->iface.base.stop = (ciot_iface_stop_fn *)ciot_https_stop; + this->iface.base.process_req = (ciot_iface_process_req_fn *)ciot_https_process_req; + this->iface.base.send_data = (ciot_iface_send_data_fn *)ciot_https_send_data; + this->iface.base.cfg.ptr = &this->cfg; + this->iface.base.cfg.size = sizeof(this->cfg); + this->iface.base.status.ptr = &this->status; + this->iface.base.status.size = sizeof(this->status); + this->iface.info.type = CIOT_IFACE_TYPE_HTTP_SERVER; + return this; } ciot_err_t ciot_https_start(ciot_https_t this, ciot_https_cfg_t *cfg) { - return CIOT_ERR_NOT_IMPLEMENTED; + httpd_config_t http_config = HTTPD_DEFAULT_CONFIG(); + http_config.server_port = cfg->port; + http_config.uri_match_fn = httpd_uri_match_wildcard; + http_config.max_uri_handlers = 7; + + int err_code = httpd_start(&this->handle, &http_config); + if (err_code == ESP_OK) + { + ESP_LOGI(TAG, "Server Started on port %d", cfg->port); + ciot_https_register_routes(this); + } + + return err_code; } ciot_err_t ciot_https_stop(ciot_https_t this) { - return CIOT_ERR_NOT_IMPLEMENTED; + return httpd_stop(this->handle); } ciot_err_t ciot_https_process_req(ciot_https_t this, ciot_https_req_t *req) @@ -33,5 +72,41 @@ ciot_err_t ciot_https_process_req(ciot_https_t this, ciot_https_req_t *req) ciot_err_t ciot_https_send_data(ciot_https_t this, uint8_t *data, int size) { - return CIOT_ERR_NOT_IMPLEMENTED; + CIOT_ERR_NULL_CHECK(this); + CIOT_ERR_NULL_CHECK(data); + CIOT_ERR_NULL_CHECK(this->req); + httpd_resp_set_status(this->req, HTTPD_200); + httpd_resp_set_type(this->req, HTTPD_TYPE_OCTET); + httpd_resp_send(this->req, (const char*)data, size); + this->req = NULL; + return CIOT_OK; +} + +static ciot_err_t ciot_https_register_routes(ciot_https_t this) +{ + httpd_uri_t ciot_post = { + .uri = this->cfg.route, + .handler = ciot_post_handler, + .method = HTTP_POST, + .user_ctx = this, + }; + return httpd_register_uri_handler(this->handle, &ciot_post); +} + +static esp_err_t ciot_post_handler(httpd_req_t *req) +{ + ciot_https_t this = req->user_ctx; + ciot_iface_event_t event = { 0 }; + + this->req = req; + event.id = CIOT_IFACE_EVENT_DATA; + event.size = req->content_len; + httpd_req_recv(req, (char*)&event.msg, sizeof(event.msg)); + + if(this->iface.event_handler != NULL) + { + this->iface.event_handler(this, &event, this->iface.event_args); + } + + return CIOT_OK; } diff --git a/main/infra/idf/ciot_mqttc.c b/main/infra/idf/ciot_mqttc.c index 835cfbe..589305b 100644 --- a/main/infra/idf/ciot_mqttc.c +++ b/main/infra/idf/ciot_mqttc.c @@ -67,6 +67,7 @@ ciot_err_t ciot_mqttc_start(ciot_mqttc_t this, ciot_mqttc_cfg_t *cfg) #endif }; + this->status.state = CIOT_MQTT_STATE_CONNECTING; this->handle = esp_mqtt_client_init(&mqtt_client_cfg); esp_mqtt_client_register_event(this->handle, ESP_EVENT_ANY_ID, ciot_mqtt_event_handler, this); return esp_mqtt_client_start(this->handle); @@ -75,6 +76,7 @@ ciot_err_t ciot_mqttc_start(ciot_mqttc_t this, ciot_mqttc_cfg_t *cfg) ciot_err_t ciot_mqttc_stop(ciot_mqttc_t this) { CIOT_ERR_NULL_CHECK(this); + this->status.state = CIOT_MQTT_STATE_DISCONNECTING; return esp_mqtt_client_stop(this->handle); } @@ -137,52 +139,81 @@ ciot_err_t ciot_mqttc_subscribe(ciot_mqttc_t this, ciot_mqttc_req_subscribe_t *r } } +static void ciot_mqttc_event_data(ciot_mqttc_t this, ciot_iface_event_t *event, char *topic, uint8_t *data, int size) +{ + event->id = (strncmp(topic, this->cfg.topics.b2d, CIOT_MQTT_TOPIC_LEN) == 0) + ? CIOT_IFACE_EVENT_DATA + : CIOT_MQTT_EVENT_DATA; + if(event->id == CIOT_IFACE_EVENT_DATA) { + event->size = size; + memcpy(&event->msg.data, data, size); + } + else + { + event->msg.data.mqtt.msg.topic = topic; + event->msg.data.mqtt.msg.data = data; + event->msg.data.mqtt.msg.size = size; + } +} + static void ciot_mqtt_event_handler(void *handler_args, esp_event_base_t event_base, int32_t event_id, void *event_data) { ciot_mqttc_t this = (ciot_mqttc_t)handler_args; + esp_mqtt_event_t *ev_data = (esp_mqtt_event_t*)event_data; ciot_iface_event_t event = { 0 }; + event.msg.type = CIOT_MSG_TYPE_EVENT; event.msg.iface = this->iface.info; switch ((esp_mqtt_event_id_t)event_id) { case MQTT_EVENT_ERROR: ESP_LOGI(TAG, "MQTT_EVENT_ERROR"); - event.id = this->status.state == CIOT_MQTT_STATE_CONNECTING ? CIOT_IFACE_EVENT_RESPONSE : CIOT_IFACE_EVENT_ERROR; + this->status.error.code = ev_data->error_handle->connect_return_code; + this->status.error.tls_cert_verify_flags = ev_data->error_handle->esp_tls_cert_verify_flags; + this->status.error.tls_last_err = ev_data->error_handle->esp_tls_last_esp_err; + this->status.error.tls_stack_err = ev_data->error_handle->esp_tls_stack_err; + this->status.error.transport_sock = ev_data->error_handle->esp_transport_sock_errno; + this->status.error.type = ev_data->error_handle->error_type; this->status.state = CIOT_MQTT_STATE_ERROR; - memcpy(&this->status.error, ((esp_mqtt_event_t*)event_data)->error_handle, sizeof(esp_mqtt_error_codes_t)); + event.id = CIOT_IFACE_EVENT_ERROR; + event.msg.error = this->status.error.code; + event.msg.data.mqtt.status = this->status; break; case MQTT_EVENT_CONNECTED: ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED"); - // this->status.conn_count++; - // this->status.state = CIOT_MQTT_STATE_CONNECTED; - // xEventGroupSetBits(this->event_group, CIOT_MQTT_EVENT_BIT_CONNECT_DONE); + this->status.conn_count++; + this->status.state = CIOT_MQTT_STATE_CONNECTED; + event.id = CIOT_IFACE_EVENT_STARTED; + event.msg.data.mqtt.status = this->status; break; case MQTT_EVENT_DISCONNECTED: ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED"); - // this->status.state = CIOT_MQTT_STATE_DISCONNECTED; - // xEventGroupSetBits(this->event_group, CIOT_MQTT_EVENT_BIT_CONNECT_DONE); + this->status.state = CIOT_MQTT_STATE_DISCONNECTED; + event.id = CIOT_IFACE_EVENT_STOPPED; + event.msg.data.mqtt.status = this->status; break; case MQTT_EVENT_SUBSCRIBED: ESP_LOGI(TAG, "MQTT_EVENT_SUBSCRIBED"); + event.id = CIOT_MQTT_EVENT_SUBSCRIBED; + event.msg.data.mqtt.msg.topic = ev_data->topic; break; case MQTT_EVENT_UNSUBSCRIBED: ESP_LOGI(TAG, "MQTT_EVENT_UNSUBSCRIBED"); + event.id = CIOT_MQTT_EVENT_UNSUBCRIBED; + event.msg.data.mqtt.msg.topic = ev_data->topic; break; case MQTT_EVENT_DATA: ESP_LOGI(TAG, "MQTT_EVENT_DATA"); - // event.data.message.topic.data = ((esp_mqtt_event_t*)event_data)->topic; - // event.data.message.topic.size = ((esp_mqtt_event_t*)event_data)->topic_len; - // event.data.message.payload.data = ((esp_mqtt_event_t*)event_data)->data; - // event.data.message.payload.size = ((esp_mqtt_event_t*)event_data)->data_len; + ciot_mqttc_event_data(this, &event, ev_data->topic, (uint8_t*)ev_data->data, ev_data->data_len); break; default: ESP_LOGI(TAG, "Other event id:%d", event.id); break; } - // if(this->event_handler != NULL) - // { - // this->event_handler(this, &event, this->event_arg); - // } + if(this->iface.event_handler != NULL) + { + this->iface.event_handler(this, &event, this->iface.event_args); + } } diff --git a/main/infra/mg/ciot_mqttc.c b/main/infra/mg/ciot_mqttc.c index 511105c..1233d60 100644 --- a/main/infra/mg/ciot_mqttc.c +++ b/main/infra/mg/ciot_mqttc.c @@ -125,78 +125,54 @@ ciot_err_t ciot_mqttc_subscribe(ciot_mqttc_t this, ciot_mqttc_req_subscribe_t *r return CIOT_OK; } -static void ciot_mqttc_on_msg(ciot_mqttc_t this, struct mg_connection *c, struct mg_mqtt_message *mm) +static void ciot_mqtt_event_data(ciot_mqttc_t this, ciot_iface_event_t *event, char *topic, uint8_t *data, int size) { - ciot_iface_event_t event = {0}; - if (strncmp(mm->topic.ptr, this->cfg.topics.b2d, CIOT_MQTT_TOPIC_LEN) == 0) - { - event.id = CIOT_IFACE_EVENT_REQUEST; - event.size = mm->data.len; - memcpy(&event.msg, mm->data.ptr, mm->data.len); + event->id = (strncmp(topic, this->cfg.topics.b2d, CIOT_MQTT_TOPIC_LEN) == 0) + ? CIOT_IFACE_EVENT_DATA + : CIOT_MQTT_EVENT_DATA; + if(event->id == CIOT_IFACE_EVENT_DATA) { + event->size = size; + memcpy(&event->msg.data, data, size); } else { - event.id = CIOT_MQTT_EVENT_DATA; - event.msg.iface = this->iface.info; - event.msg.type = CIOT_MSG_TYPE_UNKNOWN; - event.msg.data.mqtt.msg.topic = (char *)mm->topic.ptr; - event.msg.data.mqtt.msg.data = (void *)mm->data.ptr; - event.msg.data.mqtt.msg.size = mm->data.len; + event->msg.data.mqtt.msg.topic = topic; + event->msg.data.mqtt.msg.data = data; + event->msg.data.mqtt.msg.size = size; } - this->iface.event_handler(this, &event, this->iface.event_args); } static void ciot_mqttc_event_handler(struct mg_connection *c, int ev, void *ev_data, void *fn_data) { ciot_mqttc_t this = fn_data; + ciot_iface_event_t event = { 0 }; switch (ev) { case MG_EV_ERROR: printf("MG_EV_ERROR:%d:%s\n", c->id, (char *)ev_data); + this->status.error.code = c->id; this->status.state = CIOT_MQTT_STATE_ERROR; + event.id = CIOT_IFACE_EVENT_ERROR; + event.msg.error = this->status.error.code; + event.msg.data.mqtt.status = this->status; break; case MG_EV_MQTT_OPEN: printf("MG_EV_MQTT_OPEN\n"); this->status.conn_count++; this->status.state = CIOT_MQTT_STATE_CONNECTED; - if (this->iface.event_handler != NULL) - { - ciot_iface_event_t event = {0}; - event.id = CIOT_IFACE_EVENT_RESPONSE; - event.size = CIOT_MSG_GET_SIZE(this->status); - event.msg.iface = this->iface.info; - event.msg.type = CIOT_MSG_TYPE_START; - event.msg.data.mqtt.status = this->status; - this->iface.event_handler(this, &event, this->iface.event_args); - } + event.id = CIOT_IFACE_EVENT_STARTED; + event.msg.data.mqtt.status = this->status; break; case MG_EV_MQTT_MSG: printf("MG_EV_MQTT_MSG\n"); - if(this->iface.event_handler != NULL) - { - struct mg_mqtt_message *hm = (struct mg_mqtt_message *)ev_data; - ciot_mqttc_on_msg(this, c, hm); - } - else - { - mg_error(c, "Event Handler is NULL"); - } + ciot_mqtt_event_data(this, &event, mm->topic.ptr, mm->data.ptr, mm->data.len) break; case MG_EV_CLOSE: printf("MG_EV_CLOSE\n"); this->status.state = CIOT_MQTT_STATE_DISCONNECTED; - this->connection = NULL; - if (this->iface.event_handler != NULL) - { - ciot_iface_event_t event = {0}; - event.id = CIOT_IFACE_EVENT_RESPONSE; - event.size = CIOT_MSG_GET_SIZE(this->status); - event.msg.iface = this->iface.info; - event.msg.type = CIOT_MSG_TYPE_STOP; - event.msg.data.mqtt.status = this->status; - this->iface.event_handler(this, &event, this->iface.event_args); - } + event.id = CIOT_IFACE_EVENT_STOPPED; + event.msg.data.mqtt.status = this->status; break; default: break; diff --git a/main/interfaces/ciot_iface.c b/main/interfaces/ciot_iface.c index 5214276..770d19e 100644 --- a/main/interfaces/ciot_iface.c +++ b/main/interfaces/ciot_iface.c @@ -95,6 +95,8 @@ ciot_err_t ciot_iface_process_msg(ciot_iface_t *this, ciot_msg_t *msg, int *size return ciot_iface_get_status(this, &msg->data); case CIOT_MSG_TYPE_REQUEST: return ciot_iface_process_req(this, &msg->data); + case CIOT_MSG_TYPE_EVENT: + return CIOT_ERR_NOT_IMPLEMENTED; } return CIOT_ERR_INVALID_TYPE; diff --git a/main/interfaces/ciot_iface.h b/main/interfaces/ciot_iface.h index bf5a276..8827677 100644 --- a/main/interfaces/ciot_iface.h +++ b/main/interfaces/ciot_iface.h @@ -18,9 +18,10 @@ typedef enum ciot_iface_event_id { CIOT_IFACE_EVENT_UNKNOWN, - CIOT_IFACE_EVENT_REQUEST, - CIOT_IFACE_EVENT_RESPONSE, + CIOT_IFACE_EVENT_STARTED, + CIOT_IFACE_EVENT_STOPPED, CIOT_IFACE_EVENT_ERROR, + CIOT_IFACE_EVENT_DATA, CIOT_IFACE_EVENT_CUSTOM, } ciot_iface_event_id_t;