Skip to content

Commit

Permalink
feat: implement mqttc and httpc on idf
Browse files Browse the repository at this point in the history
  • Loading branch information
wjsan committed Oct 13, 2023
1 parent bc57f4f commit 3050fc3
Show file tree
Hide file tree
Showing 10 changed files with 195 additions and 103 deletions.
74 changes: 38 additions & 36 deletions main/ciot.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
1 change: 1 addition & 0 deletions main/data/ciot_https_data.h
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
1 change: 1 addition & 0 deletions main/data/ciot_mqttc_data.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
3 changes: 2 additions & 1 deletion main/data/ciot_msg_data.h
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
4 changes: 3 additions & 1 deletion main/infra/ciot_mqttc.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
83 changes: 79 additions & 4 deletions main/infra/idf/ciot_https.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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;
}
61 changes: 46 additions & 15 deletions main/infra/idf/ciot_mqttc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
}

Expand Down Expand Up @@ -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);
}
}
Loading

0 comments on commit 3050fc3

Please sign in to comment.