From c2e60809f6155aa260eb1be58141cac8c382e195 Mon Sep 17 00:00:00 2001 From: Benjamin Runnels Date: Sat, 29 Aug 2015 11:29:40 -0500 Subject: [PATCH] more mqtt work --- cmd/handlers.c | 15 +- cmd/mqtt_cmd.c | 336 ++++++++++++++++++++++++++++++++++ cmd/mqtt_cmd.h | 22 +++ esp-link.vcxproj | 35 +++- include/esp8266.h | 4 +- mqtt/include/proto.h | 31 ---- mqtt/include/ringbuf.h | 18 -- mqtt/include/typedef.h | 17 -- mqtt/include/utils.h | 9 - mqtt/mqtt.c | 190 ++++++++++--------- mqtt/{include => }/mqtt.h | 112 ++++++------ mqtt/mqtt_msg.c | 217 ++++++++++------------ mqtt/{include => }/mqtt_msg.h | 66 +++---- mqtt/proto.c | 182 +++++++----------- mqtt/proto.h | 28 +++ mqtt/queue.c | 15 +- mqtt/{include => }/queue.h | 13 +- mqtt/ringbuf.c | 82 ++++----- mqtt/ringbuf.h | 17 ++ mqtt/utils.c | 18 +- mqtt/utils.h | 9 + user/user_main.c | 186 +++++++++---------- 22 files changed, 947 insertions(+), 675 deletions(-) create mode 100644 cmd/mqtt_cmd.c create mode 100644 cmd/mqtt_cmd.h delete mode 100644 mqtt/include/proto.h delete mode 100644 mqtt/include/ringbuf.h delete mode 100644 mqtt/include/typedef.h delete mode 100644 mqtt/include/utils.h rename mqtt/{include => }/mqtt.h (60%) rename mqtt/{include => }/mqtt_msg.h (86%) create mode 100644 mqtt/proto.h rename mqtt/{include => }/queue.h (86%) create mode 100644 mqtt/ringbuf.h create mode 100644 mqtt/utils.h diff --git a/cmd/handlers.c b/cmd/handlers.c index 28382dd..ae21bec 100644 --- a/cmd/handlers.c +++ b/cmd/handlers.c @@ -9,6 +9,7 @@ #include "serbridge.h" #include "uart.h" #include "cgiwifi.h" +#include "mqtt_cmd.h" static uint32_t ICACHE_FLASH_ATTR CMD_Null(CmdPacket *cmd); static uint32_t ICACHE_FLASH_ATTR CMD_IsReady(CmdPacket *cmd); @@ -24,14 +25,12 @@ const CmdList commands[] = { {CMD_IS_READY, CMD_IsReady}, {CMD_WIFI_CONNECT, CMD_WifiConnect}, -/* - {CMD_MQTT_SETUP, MQTTAPP_Setup}, - {CMD_MQTT_CONNECT, MQTTAPP_Connect}, - {CMD_MQTT_DISCONNECT, MQTTAPP_Disconnect}, - {CMD_MQTT_PUBLISH, MQTTAPP_Publish}, - {CMD_MQTT_SUBSCRIBE , MQTTAPP_Subscribe}, - {CMD_MQTT_LWT, MQTTAPP_Lwt}, - */ + {CMD_MQTT_SETUP, MQTTCMD_Setup}, + {CMD_MQTT_CONNECT, MQTTCMD_Connect}, + {CMD_MQTT_DISCONNECT, MQTTCMD_Disconnect}, + {CMD_MQTT_PUBLISH, MQTTCMD_Publish}, + {CMD_MQTT_SUBSCRIBE , MQTTCMD_Subscribe}, + {CMD_MQTT_LWT, MQTTCMD_Lwt}, {CMD_REST_SETUP, REST_Setup}, {CMD_REST_REQUEST, REST_Request}, diff --git a/cmd/mqtt_cmd.c b/cmd/mqtt_cmd.c new file mode 100644 index 0000000..d12ba21 --- /dev/null +++ b/cmd/mqtt_cmd.c @@ -0,0 +1,336 @@ +#include "mqtt_cmd.h" + +uint32_t connectedCb = 0, disconnectCb = 0, publishedCb = 0, dataCb = 0; + +void ICACHE_FLASH_ATTR +mqttConnectedCb(uint32_t* args) { + MQTT_Client* client = (MQTT_Client*)args; + MqttCmdCb* cb = (MqttCmdCb*)client->user_data; + os_printf("MQTT: Connected connectedCb=%p, disconnectedCb=%p, publishedCb=%p, dataCb=%p\n", + (void*)cb->connectedCb, + (void*)cb->disconnectedCb, + (void*)cb->publishedCb, + (void*)cb->dataCb); + uint16_t crc = CMD_ResponseStart(CMD_MQTT_EVENTS, cb->connectedCb, 0, 0); + CMD_ResponseEnd(crc); +} + +void ICACHE_FLASH_ATTR +mqttTcpDisconnectedCb(uint32_t *args) { + MQTT_Client* client = (MQTT_Client*)args; + MqttCmdCb *cb = (MqttCmdCb*)client->user_data; + os_printf("MQTT: TCP Disconnected\n"); + uint16_t crc = CMD_ResponseStart(CMD_MQTT_EVENTS, cb->tcpDisconnectedCb, 0, 0); + CMD_ResponseEnd(crc); +} + +void ICACHE_FLASH_ATTR +mqttDisconnectedCb(uint32_t* args) { + MQTT_Client* client = (MQTT_Client*)args; + MqttCmdCb* cb = (MqttCmdCb*)client->user_data; + os_printf("MQTT: Disconnected\n"); + uint16_t crc = CMD_ResponseStart(CMD_MQTT_EVENTS, cb->disconnectedCb, 0, 0); + CMD_ResponseEnd(crc); +} + +void ICACHE_FLASH_ATTR +mqttPublishedCb(uint32_t* args) { + MQTT_Client* client = (MQTT_Client*)args; + MqttCmdCb* cb = (MqttCmdCb*)client->user_data; + os_printf("MQTT: Published\n"); + uint16_t crc = CMD_ResponseStart(CMD_MQTT_EVENTS, cb->publishedCb, 0, 0); + CMD_ResponseEnd(crc); +} + +void ICACHE_FLASH_ATTR +mqttDataCb(uint32_t* args, const char* topic, uint32_t topic_len, const char* data, uint32_t data_len) { + uint16_t crc = 0; + MQTT_Client* client = (MQTT_Client*)args; + MqttCmdCb* cb = (MqttCmdCb*)client->user_data; + + crc = CMD_ResponseStart(CMD_MQTT_EVENTS, cb->dataCb, 0, 2); + crc = CMD_ResponseBody(crc, (uint8_t*)topic, topic_len); + crc = CMD_ResponseBody(crc, (uint8_t*)data, data_len); + CMD_ResponseEnd(crc); +} + +uint32_t ICACHE_FLASH_ATTR +MQTTCMD_Setup(CmdPacket *cmd) { + CmdRequest req; + CMD_Request(&req, cmd); + + if (CMD_GetArgc(&req) != 9) + return 0; + + // create mqtt client + uint8_t clientLen = sizeof(MQTT_Client); + MQTT_Client* client = (MQTT_Client*)os_zalloc(clientLen); + if (client == NULL) + return 0; + os_memset(client, 0, clientLen); + + uint16_t len; + uint8_t *client_id, *user_data, *pass_data; + uint32_t keepalive, clean_session, cb_data; + + // get client id + len = CMD_ArgLen(&req); + if (len > 32) return 0; // safety check + client_id = (uint8_t*)os_zalloc(len + 1); + CMD_PopArg(&req, client_id, len); + client_id[len] = 0; + + // get username + len = CMD_ArgLen(&req); + if (len > 32) return 0; // safety check + user_data = (uint8_t*)os_zalloc(len + 1); + CMD_PopArg(&req, user_data, len); + user_data[len] = 0; + + // get password + len = CMD_ArgLen(&req); + if (len > 32) return 0; // safety check + pass_data = (uint8_t*)os_zalloc(len + 1); + CMD_PopArg(&req, pass_data, len); + pass_data[len] = 0; + + // get keepalive + CMD_PopArg(&req, (uint8_t*)&keepalive, 4); + + // get clean session + CMD_PopArg(&req, (uint8_t*)&clean_session, 4); + + os_printf("MQTT: MQTTCMD_Setup clientid=%s, user=%s, pw=%s, keepalive=%ld, clean_session=%ld\n", client_id, user_data, pass_data, keepalive, clean_session); + + // init client + // TODO: why malloc these all here, pass to MQTT_InitClient to be malloc'd again? + MQTT_InitClient(client, client_id, user_data, pass_data, keepalive, clean_session); + + // create callback + MqttCmdCb* callback = (MqttCmdCb*)os_zalloc(sizeof(MqttCmdCb)); + + CMD_PopArg(&req, (uint8_t*)&cb_data, 4); + callback->connectedCb = cb_data; + CMD_PopArg(&req, (uint8_t*)&cb_data, 4); + callback->disconnectedCb = cb_data; + CMD_PopArg(&req, (uint8_t*)&cb_data, 4); + callback->publishedCb = cb_data; + CMD_PopArg(&req, (uint8_t*)&cb_data, 4); + callback->dataCb = cb_data; + + client->user_data = callback; + + client->cmdConnectedCb = mqttConnectedCb; + client->cmdDisconnectedCb = mqttDisconnectedCb; + client->cmdPublishedCb = mqttPublishedCb; + client->cmdDataCb = mqttDataCb; + + if (CMD_GetArgc(&req) == 10) { + CMD_PopArg(&req, (uint8_t*)&cb_data, 4); + callback->tcpDisconnectedCb = cb_data; + client->cmdTcpDisconnectedCb = mqttTcpDisconnectedCb; + } + + os_free(client_id); + os_free(user_data); + os_free(pass_data); + + return (uint32_t)client; +} + +uint32_t ICACHE_FLASH_ATTR +MQTTCMD_Lwt(CmdPacket *cmd) { + CmdRequest req; + CMD_Request(&req, cmd); + + if (CMD_GetArgc(&req) != 5) + return 0; + + // get mqtt client + uint32_t client_ptr; + CMD_PopArg(&req, (uint8_t*)&client_ptr, 4); + MQTT_Client* client = (MQTT_Client*)client_ptr; + os_printf("MQTT: MQTTCMD_Lwt client ptr=%p\n", (void*)client_ptr); + + uint16_t len; + + // get topic + if (client->connect_info.will_topic) + os_free(client->connect_info.will_topic); + len = CMD_ArgLen(&req); + if (len > 128) return 0; // safety check + client->connect_info.will_topic = (char*)os_zalloc(len + 1); + CMD_PopArg(&req, client->connect_info.will_topic, len); + client->connect_info.will_topic[len] = 0; + + // get message + if (client->connect_info.will_message) + os_free(client->connect_info.will_message); + len = CMD_ArgLen(&req); + // TODO: safety check + client->connect_info.will_message = (char*)os_zalloc(len + 1); + CMD_PopArg(&req, client->connect_info.will_message, len); + client->connect_info.will_message[len] = 0; + + // get qos + CMD_PopArg(&req, (uint8_t*)&client->connect_info.will_qos, 4); + + // get retain + CMD_PopArg(&req, (uint8_t*)&client->connect_info.will_retain, 4); + + os_printf("MQTT: MQTTCMD_Lwt topic=%s, message=%s, qos=%ld, retain=%ld\n", + client->connect_info.will_topic, + client->connect_info.will_message, + client->connect_info.will_qos, + client->connect_info.will_retain); + return 1; +} + +uint32_t ICACHE_FLASH_ATTR +MQTTCMD_Connect(CmdPacket *cmd) { + CmdRequest req; + CMD_Request(&req, cmd); + + if (CMD_GetArgc(&req) != 4) + return 0; + + // get mqtt client + uint32_t client_ptr; + CMD_PopArg(&req, (uint8_t*)&client_ptr, 4); + MQTT_Client* client = (MQTT_Client*)client_ptr; + os_printf("MQTT: MQTTCMD_Connect client ptr=%p\n", (void*)client_ptr); + + uint16_t len; + + // get host + if (client->host) + os_free(client->host); + len = CMD_ArgLen(&req); + if (len > 128) return 0; // safety check + client->host = (uint8_t*)os_zalloc(len + 1); + CMD_PopArg(&req, client->host, len); + client->host[len] = 0; + + // get port + CMD_PopArg(&req, (uint8_t*)&client->port, 4); + + // get security + CMD_PopArg(&req, (uint8_t*)&client->security, 4); + + os_printf("MQTT: MQTTCMD_Connect host=%s, port=%ld, security=%ld\n", + client->host, + client->port, + client->security); + + MQTT_Connect(client); + return 1; +} + +uint32_t ICACHE_FLASH_ATTR +MQTTCMD_Disconnect(CmdPacket *cmd) { + CmdRequest req; + CMD_Request(&req, cmd); + + if (CMD_GetArgc(&req) != 1) + return 0; + + // get mqtt client + uint32_t client_ptr; + CMD_PopArg(&req, (uint8_t*)&client_ptr, 4); + MQTT_Client* client = (MQTT_Client*)client_ptr; + os_printf("MQTT: MQTTCMD_Disconnect client ptr=%p\n", (void*)client_ptr); + + // disconnect + MQTT_Disconnect(client); + return 1; +} + +uint32_t ICACHE_FLASH_ATTR +MQTTCMD_Publish(CmdPacket *cmd) { + CmdRequest req; + CMD_Request(&req, cmd); + + if (CMD_GetArgc(&req) != 6) + return 0; + + // get mqtt client + uint32_t client_ptr; + CMD_PopArg(&req, (uint8_t*)&client_ptr, 4); + MQTT_Client* client = (MQTT_Client*)client_ptr; + os_printf("MQTT: MQTTCMD_Publish client ptr=%p\n", (void*)client_ptr); + + uint16_t len; + uint8_t *topic, *data; + uint32_t qos = 0, retain = 0, data_len; + + // get topic + len = CMD_ArgLen(&req); + if (len > 128) return 0; // safety check + topic = (uint8_t*)os_zalloc(len + 1); + CMD_PopArg(&req, topic, len); + topic[len] = 0; + + // get data + len = CMD_ArgLen(&req); + // TODO: Safety check + // TODO: this was orignially zalloc len not len+1 + data = (uint8_t*)os_zalloc(len+1); + CMD_PopArg(&req, data, len); + // TODO: next line not originally present + data[len] = 0; + + // get data length + // TODO: this isn't used but we have to pull it off the stack + CMD_PopArg(&req, (uint8_t*)&data_len, 4); + + // get qos + CMD_PopArg(&req, (uint8_t*)&qos, 4); + + // get retain + CMD_PopArg(&req, (uint8_t*)&retain, 4); + + os_printf("MQTT: MQTTCMD_Publish topic=%s, data_len=%d, qos=%ld, retain=%ld\n", + topic, + os_strlen((char*)data), + qos, + retain); + + MQTT_Publish(client, (char*)topic, (char*)data, (uint8_t)qos, (uint8_t)retain); + os_free(topic); + os_free(data); + return 1; +} + +uint32_t ICACHE_FLASH_ATTR +MQTTCMD_Subscribe(CmdPacket *cmd) { + CmdRequest req; + CMD_Request(&req, cmd); + + if (CMD_GetArgc(&req) != 3) + return 0; + + // get mqtt client + uint32_t client_ptr; + CMD_PopArg(&req, (uint8_t*)&client_ptr, 4); + MQTT_Client* client = (MQTT_Client*)client_ptr; + os_printf("MQTT: MQTTCMD_Subscribe client ptr=%p\n", (void*)client_ptr); + + uint16_t len; + uint8_t* topic; + uint32_t qos = 0; + + // get topic + len = CMD_ArgLen(&req); + if (len > 128) return 0; // safety check + topic = (uint8_t*)os_zalloc(len + 1); + CMD_PopArg(&req, topic, len); + topic[len] = 0; + + // get qos + CMD_PopArg(&req, (uint8_t*)&qos, 4); + + os_printf("MQTT: MQTTCMD_Subscribe topic=%s, qos=%ld\n", topic, qos); + MQTT_Subscribe(client, (char*)topic, (uint8_t)qos); + os_free(topic); + return 1; +} diff --git a/cmd/mqtt_cmd.h b/cmd/mqtt_cmd.h new file mode 100644 index 0000000..66fd8f6 --- /dev/null +++ b/cmd/mqtt_cmd.h @@ -0,0 +1,22 @@ +#ifndef MODULES_MQTT_CMD_H_ +#define MODULES_MQTT_CMD_H_ + +#include "cmd.h" +#include "mqtt.h" + +typedef struct { + uint32_t connectedCb; + uint32_t disconnectedCb; + uint32_t publishedCb; + uint32_t dataCb; + uint32_t tcpDisconnectedCb; +} MqttCmdCb; + +uint32_t ICACHE_FLASH_ATTR MQTTCMD_Connect(CmdPacket *cmd); +uint32_t ICACHE_FLASH_ATTR MQTTCMD_Disconnect(CmdPacket *cmd); +uint32_t ICACHE_FLASH_ATTR MQTTCMD_Setup(CmdPacket *cmd); +uint32_t ICACHE_FLASH_ATTR MQTTCMD_Publish(CmdPacket *cmd); +uint32_t ICACHE_FLASH_ATTR MQTTCMD_Subscribe(CmdPacket *cmd); +uint32_t ICACHE_FLASH_ATTR MQTTCMD_Lwt(CmdPacket *cmd); + +#endif /* MODULES_MQTT_CMD_H_ */ diff --git a/esp-link.vcxproj b/esp-link.vcxproj index eac1d5b..ce508d0 100644 --- a/esp-link.vcxproj +++ b/esp-link.vcxproj @@ -28,7 +28,7 @@ __ets__;_STDINT_H;ICACHE_FLASH;__MINGW32__;__WIN32__ - .\mqtt\include;.\cmd;.\serial;.\user;.\espfs;.\httpd;.\include;..\esp_iot_sdk_v1.3.0\include;..\xtensa-lx106-elf\xtensa-lx106-elf\include;c:\tools\mingw64\x86_64-w64-mingw32\include;c:\tools\mingw64\lib\gcc\x86_64-w64-mingw32\4.8.3\include + .\mqtt;.\cmd;.\serial;.\user;.\espfs;.\httpd;.\include;..\esp_iot_sdk_v1.3.0\include;..\xtensa-lx106-elf\xtensa-lx106-elf\include;c:\tools\mingw64\x86_64-w64-mingw32\include;c:\tools\mingw64\lib\gcc\x86_64-w64-mingw32\4.8.3\include @@ -65,6 +65,7 @@ + @@ -87,6 +88,15 @@ + + + + + + + + + @@ -95,10 +105,10 @@ - + @@ -112,18 +122,25 @@ - - - - - - - + + + + + + + + + + + + + + diff --git a/include/esp8266.h b/include/esp8266.h index 96a7364..535dfeb 100644 --- a/include/esp8266.h +++ b/include/esp8266.h @@ -1,5 +1,5 @@ // Combined include file for esp8266 - +#include #include #include #include @@ -17,6 +17,8 @@ #include "espmissingincludes.h" #include "uart_hw.h" +//void init(void); + #ifdef __WIN32__ #include <_mingw.h> #endif diff --git a/mqtt/include/proto.h b/mqtt/include/proto.h deleted file mode 100644 index 73a4e8b..0000000 --- a/mqtt/include/proto.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * File: proto.h - * Author: ThuHien - * - * Created on November 23, 2012, 8:57 AM - */ - -#ifndef _PROTO_H_ -#define _PROTO_H_ -#include -#include "ringbuf.h" - -typedef void(PROTO_PARSE_CALLBACK)(); - -typedef struct{ - uint8_t *buf; - uint16_t bufSize; - uint16_t dataLen; - uint8_t isEsc; - uint8_t isBegin; - PROTO_PARSE_CALLBACK* callback; -}PROTO_PARSER; - -int8_t ICACHE_FLASH_ATTR PROTO_Init(PROTO_PARSER *parser, PROTO_PARSE_CALLBACK *completeCallback, uint8_t *buf, uint16_t bufSize); -int8_t ICACHE_FLASH_ATTR PROTO_Parse(PROTO_PARSER *parser, uint8_t *buf, uint16_t len); -int16_t ICACHE_FLASH_ATTR PROTO_Add(uint8_t *buf, const uint8_t *packet, int16_t bufSize); -int16_t ICACHE_FLASH_ATTR PROTO_AddRb(RINGBUF *rb, const uint8_t *packet, int16_t len); -int8_t ICACHE_FLASH_ATTR PROTO_ParseByte(PROTO_PARSER *parser, uint8_t value); -int16_t ICACHE_FLASH_ATTR PROTO_ParseRb(RINGBUF *rb, uint8_t *bufOut, uint16_t* len, uint16_t maxBufLen); -#endif - diff --git a/mqtt/include/ringbuf.h b/mqtt/include/ringbuf.h deleted file mode 100644 index 03d780d..0000000 --- a/mqtt/include/ringbuf.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef _RING_BUF_H_ -#define _RING_BUF_H_ - -#include -#include "typedef.h" - -typedef struct{ - U8* p_o; /**< Original pointer */ - U8* volatile p_r; /**< Read pointer */ - U8* volatile p_w; /**< Write pointer */ - volatile I32 fill_cnt; /**< Number of filled slots */ - I32 size; /**< Buffer size */ -}RINGBUF; - -I16 ICACHE_FLASH_ATTR RINGBUF_Init(RINGBUF *r, U8* buf, I32 size); -I16 ICACHE_FLASH_ATTR RINGBUF_Put(RINGBUF *r, U8 c); -I16 ICACHE_FLASH_ATTR RINGBUF_Get(RINGBUF *r, U8* c); -#endif diff --git a/mqtt/include/typedef.h b/mqtt/include/typedef.h deleted file mode 100644 index a4c69d6..0000000 --- a/mqtt/include/typedef.h +++ /dev/null @@ -1,17 +0,0 @@ -/** -* \file -* Standard Types definition -*/ - -#ifndef _TYPE_DEF_H_ -#define _TYPE_DEF_H_ - -typedef char I8; -typedef unsigned char U8; -typedef short I16; -typedef unsigned short U16; -typedef long I32; -typedef unsigned long U32; -typedef unsigned long long U64; - -#endif diff --git a/mqtt/include/utils.h b/mqtt/include/utils.h deleted file mode 100644 index 676501e..0000000 --- a/mqtt/include/utils.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef _UTILS_H_ -#define _UTILS_H_ - -#include - -uint32_t ICACHE_FLASH_ATTR UTILS_Atoh(const int8_t *s); -uint8_t ICACHE_FLASH_ATTR UTILS_StrToIP(const int8_t* str, void *ip); -uint8_t ICACHE_FLASH_ATTR UTILS_IsIPV4 (int8_t *str); -#endif diff --git a/mqtt/mqtt.c b/mqtt/mqtt.c index 49ed507..9d435c8 100644 --- a/mqtt/mqtt.c +++ b/mqtt/mqtt.c @@ -33,41 +33,38 @@ #define MQTT_TASK_PRIO 0 #define MQTT_TASK_QUEUE_SIZE 1 -#define MQTT_SEND_TIMOUT 5 +#define MQTT_SEND_TIMOUT 5 #ifndef QUEUE_BUFFER_SIZE #define QUEUE_BUFFER_SIZE 2048 #endif -unsigned char *default_certificate; +unsigned char* default_certificate; unsigned int default_certificate_len = 0; -unsigned char *default_private_key; +unsigned char* default_private_key; unsigned int default_private_key_len = 0; os_event_t mqtt_procTaskQueue[MQTT_TASK_QUEUE_SIZE]; LOCAL void ICACHE_FLASH_ATTR -mqtt_dns_found(const char *name, ip_addr_t *ipaddr, void *arg) -{ - struct espconn *pConn = (struct espconn *)arg; +mqtt_dns_found(const char* name, ip_addr_t* ipaddr, void* arg) { + struct espconn* pConn = (struct espconn *)arg; MQTT_Client* client = (MQTT_Client *)pConn->reverse; - if (ipaddr == NULL) - { + if (ipaddr == NULL) { os_printf("DNS: Found, but got no ip, try to reconnect\n"); client->connState = TCP_RECONNECT_REQ; return; } os_printf("DNS: found ip %d.%d.%d.%d\n", - *((uint8 *)&ipaddr->addr), - *((uint8 *)&ipaddr->addr + 1), - *((uint8 *)&ipaddr->addr + 2), - *((uint8 *)&ipaddr->addr + 3)); + *((uint8 *)&ipaddr->addr), + *((uint8 *)&ipaddr->addr + 1), + *((uint8 *)&ipaddr->addr + 2), + *((uint8 *)&ipaddr->addr + 3)); - if (client->ip.addr == 0 && ipaddr->addr != 0) - { + if (client->ip.addr == 0 && ipaddr->addr != 0) { os_memcpy(client->pCon->proto.tcp->remote_ip, &ipaddr->addr, 4); #ifdef CLIENT_SSL_ENABLE if (client->security){ @@ -75,7 +72,7 @@ mqtt_dns_found(const char *name, ip_addr_t *ipaddr, void *arg) } else #endif - espconn_connect(client->pCon); + espconn_connect(client->pCon); client->connState = TCP_CONNECTING; os_printf("MQTT-TCP: connecting...\n"); @@ -85,10 +82,8 @@ mqtt_dns_found(const char *name, ip_addr_t *ipaddr, void *arg) } - LOCAL void ICACHE_FLASH_ATTR -deliver_publish(MQTT_Client* client, uint8_t* message, int length) -{ +deliver_publish(MQTT_Client* client, uint8_t* message, uint16_t length) { mqtt_event_data_t event_data; event_data.topic_length = length; @@ -99,8 +94,10 @@ deliver_publish(MQTT_Client* client, uint8_t* message, int length) if (client->dataCb) client->dataCb((uint32_t*)client, event_data.topic, event_data.topic_length, event_data.data, event_data.data_length); -} + if (client->cmdDataCb) + client->cmdDataCb((uint32_t*)client, event_data.topic, event_data.topic_length, event_data.data, event_data.data_length); +} /** * @brief Client received callback function. @@ -110,26 +107,25 @@ deliver_publish(MQTT_Client* client, uint8_t* message, int length) * @retval None */ void ICACHE_FLASH_ATTR -mqtt_tcpclient_recv(void *arg, char *pdata, unsigned short len) -{ +mqtt_tcpclient_recv(void* arg, char* pdata, unsigned short len) { uint8_t msg_type; uint8_t msg_qos; uint16_t msg_id; - struct espconn *pCon = (struct espconn*)arg; - MQTT_Client *client = (MQTT_Client *)pCon->reverse; + struct espconn* pCon = (struct espconn*)arg; + MQTT_Client* client = (MQTT_Client *)pCon->reverse; READPACKET: os_printf("MQTT-TCP: Data received %d bytes\n", len); - if (len < MQTT_BUF_SIZE && len > 0){ + if (len < MQTT_BUF_SIZE && len > 0) { os_memcpy(client->mqtt_state.in_buffer, pdata, len); msg_type = mqtt_get_type(client->mqtt_state.in_buffer); msg_qos = mqtt_get_qos(client->mqtt_state.in_buffer); msg_id = mqtt_get_id(client->mqtt_state.in_buffer, client->mqtt_state.in_buffer_length); if (client->connState == MQTT_CONNECT_SENDING) { - if (msg_type == MQTT_MSG_TYPE_CONNACK){ - if (client->mqtt_state.pending_msg_type != MQTT_MSG_TYPE_CONNECT){ + if (msg_type == MQTT_MSG_TYPE_CONNACK) { + if (client->mqtt_state.pending_msg_type != MQTT_MSG_TYPE_CONNECT) { os_printf("MQTT: Invalid packet\n"); #ifdef CLIENT_SSL_ENABLE if (client->security){ @@ -137,13 +133,15 @@ READPACKET: } else #endif - espconn_disconnect(client->pCon); + espconn_disconnect(client->pCon); } else { os_printf("MQTT: Connected to %s:%ld\n", client->host, client->port); client->connState = MQTT_DATA; if (client->connectedCb) client->connectedCb((uint32_t*)client); + if (client->cmdConnectedCb) + client->cmdConnectedCb((uint32_t*)client); } } } @@ -154,50 +152,50 @@ READPACKET: if (msg_type == MQTT_MSG_TYPE_SUBACK) { if (client->mqtt_state.pending_msg_type == MQTT_MSG_TYPE_SUBSCRIBE && client->mqtt_state.pending_msg_id == msg_id) - os_printf("MQTT: Subscribe successful\n"); + os_printf("MQTT: Subscribe successful\n"); } - else if (msg_type == MQTT_MSG_TYPE_UNSUBACK){ + else if (msg_type == MQTT_MSG_TYPE_UNSUBACK) { if (client->mqtt_state.pending_msg_type == MQTT_MSG_TYPE_UNSUBSCRIBE && client->mqtt_state.pending_msg_id == msg_id) - os_printf("MQTT: UnSubscribe successful\n"); + os_printf("MQTT: UnSubscribe successful\n"); } else if (msg_type == MQTT_MSG_TYPE_PUBLISH) { if (msg_qos == 1) client->mqtt_state.outbound_message = mqtt_msg_puback(&client->mqtt_state.mqtt_connection, msg_id); else if (msg_qos == 2) client->mqtt_state.outbound_message = mqtt_msg_pubrec(&client->mqtt_state.mqtt_connection, msg_id); - if (msg_qos == 1 || msg_qos == 2){ + if (msg_qos == 1 || msg_qos == 2) { os_printf("MQTT: Queue response QoS: %d\n", msg_qos); - if (QUEUE_Puts(&client->msgQueue, client->mqtt_state.outbound_message->data, client->mqtt_state.outbound_message->length) == -1){ + if (QUEUE_Puts(&client->msgQueue, client->mqtt_state.outbound_message->data, client->mqtt_state.outbound_message->length) == -1) { os_printf("MQTT: Queue full\n"); } } deliver_publish(client, client->mqtt_state.in_buffer, client->mqtt_state.message_length_read); } else if (msg_type == MQTT_MSG_TYPE_PUBACK) { - if (client->mqtt_state.pending_msg_type == MQTT_MSG_TYPE_PUBLISH && client->mqtt_state.pending_msg_id == msg_id){ + if (client->mqtt_state.pending_msg_type == MQTT_MSG_TYPE_PUBLISH && client->mqtt_state.pending_msg_id == msg_id) { os_printf("MQTT: received MQTT_MSG_TYPE_PUBACK, finish QoS1 publish\n"); } } else if (msg_type == MQTT_MSG_TYPE_PUBREC) { client->mqtt_state.outbound_message = mqtt_msg_pubrel(&client->mqtt_state.mqtt_connection, msg_id); - if (QUEUE_Puts(&client->msgQueue, client->mqtt_state.outbound_message->data, client->mqtt_state.outbound_message->length) == -1){ + if (QUEUE_Puts(&client->msgQueue, client->mqtt_state.outbound_message->data, client->mqtt_state.outbound_message->length) == -1) { os_printf("MQTT: Queue full\n"); } } else if (msg_type == MQTT_MSG_TYPE_PUBREL) { client->mqtt_state.outbound_message = mqtt_msg_pubcomp(&client->mqtt_state.mqtt_connection, msg_id); - if (QUEUE_Puts(&client->msgQueue, client->mqtt_state.outbound_message->data, client->mqtt_state.outbound_message->length) == -1){ + if (QUEUE_Puts(&client->msgQueue, client->mqtt_state.outbound_message->data, client->mqtt_state.outbound_message->length) == -1) { os_printf("MQTT: Queue full\n"); } } else if (msg_type == MQTT_MSG_TYPE_PUBCOMP) { - if (client->mqtt_state.pending_msg_type == MQTT_MSG_TYPE_PUBLISH && client->mqtt_state.pending_msg_id == msg_id){ + if (client->mqtt_state.pending_msg_type == MQTT_MSG_TYPE_PUBLISH && client->mqtt_state.pending_msg_id == msg_id) { os_printf("MQTT: receive MQTT_MSG_TYPE_PUBCOMP, finish QoS2 publish\n"); } } else if (msg_type == MQTT_MSG_TYPE_PINGREQ) { client->mqtt_state.outbound_message = mqtt_msg_pingresp(&client->mqtt_state.mqtt_connection); - if (QUEUE_Puts(&client->msgQueue, client->mqtt_state.outbound_message->data, client->mqtt_state.outbound_message->length) == -1){ + if (QUEUE_Puts(&client->msgQueue, client->mqtt_state.outbound_message->data, client->mqtt_state.outbound_message->length) == -1) { os_printf("MQTT: Queue full\n"); } } @@ -205,12 +203,10 @@ READPACKET: // NOTE: this is done down here and not in the switch case above // because the PSOCK_READBUF_LEN() won't work inside a switch // statement due to the way protothreads resume. - if (msg_type == MQTT_MSG_TYPE_PUBLISH) - { + if (msg_type == MQTT_MSG_TYPE_PUBLISH) { len = client->mqtt_state.message_length_read; - if (client->mqtt_state.message_length < client->mqtt_state.message_length_read) - { + if (client->mqtt_state.message_length < client->mqtt_state.message_length_read) { //client->connState = MQTT_PUBLISH_RECV; //Not Implement yet len -= client->mqtt_state.message_length; @@ -234,26 +230,27 @@ READPACKET: * @retval None */ void ICACHE_FLASH_ATTR -mqtt_tcpclient_sent_cb(void *arg) -{ - struct espconn *pCon = (struct espconn *)arg; +mqtt_tcpclient_sent_cb(void* arg) { + struct espconn* pCon = (struct espconn *)arg; MQTT_Client* client = (MQTT_Client *)pCon->reverse; os_printf("MQTT-TCP: Sent\n"); client->sendTimeout = 0; - if (client->connState == MQTT_DATA && client->mqtt_state.pending_msg_type == MQTT_MSG_TYPE_PUBLISH){ + if (client->connState == MQTT_DATA && client->mqtt_state.pending_msg_type == MQTT_MSG_TYPE_PUBLISH) { if (client->publishedCb) client->publishedCb((uint32_t*)client); + if (client->cmdPublishedCb) + client->cmdPublishedCb((uint32_t*)client); } system_os_post(MQTT_TASK_PRIO, 0, (os_param_t)client); } -void ICACHE_FLASH_ATTR mqtt_timer(void *arg) -{ +void ICACHE_FLASH_ATTR +mqtt_timer(void* arg) { MQTT_Client* client = (MQTT_Client*)arg; - if (client->connState == MQTT_DATA){ + if (client->connState == MQTT_DATA) { client->keepAliveTick++; - if (client->keepAliveTick > client->mqtt_state.connect_info->keepalive){ + if (client->keepAliveTick > client->mqtt_state.connect_info->keepalive) { os_printf("\nMQTT: Send keepalive packet to %s:%ld!\n", client->host, client->port); client->mqtt_state.outbound_message = mqtt_msg_pingreq(&client->mqtt_state.mqtt_connection); @@ -270,7 +267,7 @@ void ICACHE_FLASH_ATTR mqtt_timer(void *arg) } else #endif - espconn_sent(client->pCon, client->mqtt_state.outbound_message->data, client->mqtt_state.outbound_message->length); + espconn_sent(client->pCon, client->mqtt_state.outbound_message->data, client->mqtt_state.outbound_message->length); client->mqtt_state.outbound_message = NULL; @@ -279,11 +276,15 @@ void ICACHE_FLASH_ATTR mqtt_timer(void *arg) } } - else if (client->connState == TCP_RECONNECT_REQ){ + else if (client->connState == TCP_RECONNECT_REQ) { client->reconnectTick++; if (client->reconnectTick > MQTT_RECONNECT_TIMEOUT) { client->reconnectTick = 0; client->connState = TCP_RECONNECT; + if (client->tcpDisconnectedCb) + client->tcpDisconnectedCb((uint32_t*)client); + if (client->cmdTcpDisconnectedCb) + client->cmdTcpDisconnectedCb((uint32_t*)client); system_os_post(MQTT_TASK_PRIO, 0, (os_param_t)client); } } @@ -292,15 +293,16 @@ void ICACHE_FLASH_ATTR mqtt_timer(void *arg) } void ICACHE_FLASH_ATTR -mqtt_tcpclient_discon_cb(void *arg) -{ +mqtt_tcpclient_discon_cb(void* arg) { - struct espconn *pespconn = (struct espconn *)arg; + struct espconn* pespconn = (struct espconn *)arg; MQTT_Client* client = (MQTT_Client *)pespconn->reverse; os_printf("MQTT-TCP: Disconnected callback\n"); client->connState = TCP_RECONNECT_REQ; if (client->disconnectedCb) client->disconnectedCb((uint32_t*)client); + if (client->cmdDisconnectedCb) + client->cmdDisconnectedCb((uint32_t*)client); system_os_post(MQTT_TASK_PRIO, 0, (os_param_t)client); } @@ -311,9 +313,8 @@ mqtt_tcpclient_discon_cb(void *arg) * @retval None */ void ICACHE_FLASH_ATTR -mqtt_tcpclient_connect_cb(void *arg) -{ - struct espconn *pCon = (struct espconn *)arg; +mqtt_tcpclient_connect_cb(void* arg) { + struct espconn* pCon = (struct espconn *)arg; MQTT_Client* client = (MQTT_Client *)pCon->reverse; espconn_regist_disconcb(client->pCon, mqtt_tcpclient_discon_cb); @@ -335,7 +336,7 @@ mqtt_tcpclient_connect_cb(void *arg) } else #endif - espconn_sent(client->pCon, client->mqtt_state.outbound_message->data, client->mqtt_state.outbound_message->length); + espconn_sent(client->pCon, client->mqtt_state.outbound_message->data, client->mqtt_state.outbound_message->length); client->mqtt_state.outbound_message = NULL; client->connState = MQTT_CONNECT_SENDING; @@ -348,9 +349,8 @@ mqtt_tcpclient_connect_cb(void *arg) * @retval None */ void ICACHE_FLASH_ATTR -mqtt_tcpclient_recon_cb(void *arg, sint8 errType) -{ - struct espconn *pCon = (struct espconn *)arg; +mqtt_tcpclient_recon_cb(void* arg, int8_t errType) { + struct espconn* pCon = (struct espconn *)arg; MQTT_Client* client = (MQTT_Client *)pCon->reverse; os_printf("MQTT-TCP: Reconnect to %s:%ld\n", client->host, client->port); @@ -371,21 +371,20 @@ mqtt_tcpclient_recon_cb(void *arg, sint8 errType) * @retval TRUE if success queue */ bool ICACHE_FLASH_ATTR -MQTT_Publish(MQTT_Client *client, const char* topic, const char* data, int qos, int retain) -{ +MQTT_Publish(MQTT_Client* client, const char* topic, const char* data, uint8_t qos, uint8_t retain) { int data_length = os_strlen(data); uint8_t dataBuffer[MQTT_BUF_SIZE]; uint16_t dataLen; client->mqtt_state.outbound_message = mqtt_msg_publish(&client->mqtt_state.mqtt_connection, - topic, data, data_length, - qos, retain, - &client->mqtt_state.pending_msg_id); - if (client->mqtt_state.outbound_message->length == 0){ + topic, data, data_length, + qos, retain, + &client->mqtt_state.pending_msg_id); + if (client->mqtt_state.outbound_message->length == 0) { os_printf("MQTT: Queuing Publish failed\n"); return FALSE; } os_printf("MQTT: Queuing Publish, length: %d, queue size(%ld/%ld)\n", client->mqtt_state.outbound_message->length, client->msgQueue.rb.fill_cnt, client->msgQueue.rb.size); - while (QUEUE_Puts(&client->msgQueue, client->mqtt_state.outbound_message->data, client->mqtt_state.outbound_message->length) == -1){ + while (QUEUE_Puts(&client->msgQueue, client->mqtt_state.outbound_message->data, client->mqtt_state.outbound_message->length) == -1) { os_printf("MQTT: Queue full\n"); if (QUEUE_Gets(&client->msgQueue, dataBuffer, &dataLen, MQTT_BUF_SIZE) == -1) { os_printf("MQTT: Serious buffer error\n"); @@ -404,16 +403,15 @@ MQTT_Publish(MQTT_Client *client, const char* topic, const char* data, int qos, * @retval TRUE if success queue */ bool ICACHE_FLASH_ATTR -MQTT_Subscribe(MQTT_Client *client, char* topic, uint8_t qos) -{ +MQTT_Subscribe(MQTT_Client* client, char* topic, uint8_t qos) { uint8_t dataBuffer[MQTT_BUF_SIZE]; uint16_t dataLen; client->mqtt_state.outbound_message = mqtt_msg_subscribe(&client->mqtt_state.mqtt_connection, - topic, 0, - &client->mqtt_state.pending_msg_id); + topic, 0, + &client->mqtt_state.pending_msg_id); os_printf("MQTT: Queue Subscribe, topic: \"%s\", id: %d\n", topic, client->mqtt_state.pending_msg_id); - while (QUEUE_Puts(&client->msgQueue, client->mqtt_state.outbound_message->data, client->mqtt_state.outbound_message->length) == -1){ + while (QUEUE_Puts(&client->msgQueue, client->mqtt_state.outbound_message->data, client->mqtt_state.outbound_message->length) == -1) { os_printf("MQTT: Queue full\n"); if (QUEUE_Gets(&client->msgQueue, dataBuffer, &dataLen, MQTT_BUF_SIZE) == -1) { os_printf("MQTT: Serious buffer error\n"); @@ -424,7 +422,8 @@ MQTT_Subscribe(MQTT_Client *client, char* topic, uint8_t qos) return TRUE; } -void ICACHE_FLASH_ATTR MQTT_Task(os_event_t *e) { +void ICACHE_FLASH_ATTR +MQTT_Task(os_event_t* e) { MQTT_Client* client = (MQTT_Client*)e->par; uint8_t dataBuffer[MQTT_BUF_SIZE]; uint16_t dataLen; @@ -434,7 +433,7 @@ void ICACHE_FLASH_ATTR MQTT_Task(os_event_t *e) { if (client->connState == TCP_RECONNECT_REQ) { return; } - else if (client->connState == TCP_RECONNECT){ + else if (client->connState == TCP_RECONNECT) { MQTT_Connect(client); os_printf("MQTT-TCP: Reconnect to: %s:%ld\n", client->host, client->port); client->connState = TCP_CONNECTING; @@ -443,7 +442,7 @@ void ICACHE_FLASH_ATTR MQTT_Task(os_event_t *e) { if (QUEUE_IsEmpty(&client->msgQueue) || client->sendTimeout != 0) return; - if (QUEUE_Gets(&client->msgQueue, dataBuffer, &dataLen, MQTT_BUF_SIZE) == 0){ + if (QUEUE_Gets(&client->msgQueue, dataBuffer, &dataLen, MQTT_BUF_SIZE) == 0) { client->mqtt_state.pending_msg_type = mqtt_get_type(dataBuffer); client->mqtt_state.pending_msg_id = mqtt_get_id(dataBuffer, dataLen); client->sendTimeout = MQTT_SEND_TIMOUT; @@ -454,7 +453,7 @@ void ICACHE_FLASH_ATTR MQTT_Task(os_event_t *e) { } else #endif - espconn_sent(client->pCon, dataBuffer, dataLen); + espconn_sent(client->pCon, dataBuffer, dataLen); client->mqtt_state.outbound_message = NULL; return; @@ -472,8 +471,7 @@ void ICACHE_FLASH_ATTR MQTT_Task(os_event_t *e) { * @retval None */ void ICACHE_FLASH_ATTR -MQTT_InitConnection(MQTT_Client *mqttClient, uint8_t* host, uint32 port, uint8_t security) -{ +MQTT_InitConnection(MQTT_Client* mqttClient, uint8_t* host, uint32 port, uint8_t security) { uint32_t temp; os_printf("MQTT_InitConnection\n"); os_memset(mqttClient, 0, sizeof(MQTT_Client)); @@ -495,8 +493,7 @@ MQTT_InitConnection(MQTT_Client *mqttClient, uint8_t* host, uint32 port, uint8_t * @retval None */ void ICACHE_FLASH_ATTR -MQTT_InitClient(MQTT_Client *mqttClient, uint8_t* client_id, uint8_t* client_user, uint8_t* client_pass, uint32_t keepAliveTime, uint8_t cleanSession) -{ +MQTT_InitClient(MQTT_Client* mqttClient, uint8_t* client_id, uint8_t* client_user, uint8_t* client_pass, uint8_t keepAliveTime, uint8_t cleanSession) { uint32_t temp; os_printf("MQTT_InitClient\n"); @@ -536,8 +533,7 @@ MQTT_InitClient(MQTT_Client *mqttClient, uint8_t* client_id, uint8_t* client_use } void ICACHE_FLASH_ATTR -MQTT_InitLWT(MQTT_Client *mqttClient, uint8_t* will_topic, uint8_t* will_msg, uint8_t will_qos, uint8_t will_retain) -{ +MQTT_InitLWT(MQTT_Client* mqttClient, uint8_t* will_topic, uint8_t* will_msg, uint8_t will_qos, uint8_t will_retain) { uint32_t temp; temp = os_strlen((char*)will_topic); mqttClient->connect_info.will_topic = (char*)os_zalloc(temp + 1); @@ -560,8 +556,7 @@ MQTT_InitLWT(MQTT_Client *mqttClient, uint8_t* will_topic, uint8_t* will_msg, ui * @retval None */ void ICACHE_FLASH_ATTR -MQTT_Connect(MQTT_Client *mqttClient) -{ +MQTT_Connect(MQTT_Client* mqttClient) { MQTT_Disconnect(mqttClient); mqttClient->pCon = (struct espconn *)os_zalloc(sizeof(struct espconn)); mqttClient->pCon->type = ESPCONN_TCP; @@ -589,7 +584,7 @@ MQTT_Connect(MQTT_Client *mqttClient) } else #endif - espconn_connect(mqttClient->pCon); + espconn_connect(mqttClient->pCon); } else { os_printf("MQTT-TCP: Connect to domain %s:%ld\n", mqttClient->host, mqttClient->port); @@ -599,12 +594,11 @@ MQTT_Connect(MQTT_Client *mqttClient) } void ICACHE_FLASH_ATTR -MQTT_Disconnect(MQTT_Client *mqttClient) -{ - if (mqttClient->pCon){ +MQTT_Disconnect(MQTT_Client* mqttClient) { + if (mqttClient->pCon) { os_printf("Free memory\n"); if (mqttClient->pCon->proto.tcp) - os_free(mqttClient->pCon->proto.tcp); + os_free(mqttClient->pCon->proto.tcp); os_free(mqttClient->pCon); mqttClient->pCon = NULL; } @@ -613,25 +607,27 @@ MQTT_Disconnect(MQTT_Client *mqttClient) } void ICACHE_FLASH_ATTR -MQTT_OnConnected(MQTT_Client *mqttClient, MqttCallback connectedCb) -{ +MQTT_OnConnected(MQTT_Client* mqttClient, MqttCallback connectedCb) { mqttClient->connectedCb = connectedCb; } void ICACHE_FLASH_ATTR -MQTT_OnDisconnected(MQTT_Client *mqttClient, MqttCallback disconnectedCb) -{ +MQTT_OnDisconnected(MQTT_Client* mqttClient, MqttCallback disconnectedCb) { mqttClient->disconnectedCb = disconnectedCb; } void ICACHE_FLASH_ATTR -MQTT_OnData(MQTT_Client *mqttClient, MqttDataCallback dataCb) +MQTT_OnTcpDisconnected(MQTT_Client *mqttClient, MqttCallback tcpDisconnectedCb) { + mqttClient->tcpDisconnectedCb = tcpDisconnectedCb; +} + +void ICACHE_FLASH_ATTR +MQTT_OnData(MQTT_Client* mqttClient, MqttDataCallback dataCb) { mqttClient->dataCb = dataCb; } void ICACHE_FLASH_ATTR -MQTT_OnPublished(MQTT_Client *mqttClient, MqttCallback publishedCb) -{ +MQTT_OnPublished(MQTT_Client* mqttClient, MqttCallback publishedCb) { mqttClient->publishedCb = publishedCb; } diff --git a/mqtt/include/mqtt.h b/mqtt/mqtt.h similarity index 60% rename from mqtt/include/mqtt.h rename to mqtt/mqtt.h index 52d21fe..d0fdfb5 100644 --- a/mqtt/include/mqtt.h +++ b/mqtt/mqtt.h @@ -35,8 +35,7 @@ #include "queue.h" #include "utils.h" -typedef struct mqtt_event_data_t -{ +typedef struct mqtt_event_data_t { uint8_t type; const char* topic; const char* data; @@ -45,8 +44,7 @@ typedef struct mqtt_event_data_t uint16_t data_offset; } mqtt_event_data_t; -typedef struct mqtt_state_t -{ +typedef struct mqtt_state_t { uint16_t port; int auto_reconnect; mqtt_connect_info_t* connect_info; @@ -64,48 +62,54 @@ typedef struct mqtt_state_t } mqtt_state_t; typedef enum { - WIFI_INIT, - WIFI_CONNECTING, - WIFI_CONNECTING_ERROR, - WIFI_CONNECTED, - DNS_RESOLVE, - TCP_DISCONNECTED, - TCP_RECONNECT_REQ, - TCP_RECONNECT, - TCP_CONNECTING, - TCP_CONNECTING_ERROR, - TCP_CONNECTED, - MQTT_CONNECT_SEND, - MQTT_CONNECT_SENDING, - MQTT_SUBSCIBE_SEND, - MQTT_SUBSCIBE_SENDING, - MQTT_DATA, - MQTT_PUBLISH_RECV, - MQTT_PUBLISHING + WIFI_INIT, + WIFI_CONNECTING, + WIFI_CONNECTING_ERROR, + WIFI_CONNECTED, + DNS_RESOLVE, + TCP_DISCONNECTED, + TCP_RECONNECT_REQ, + TCP_RECONNECT, + TCP_CONNECTING, + TCP_CONNECTING_ERROR, + TCP_CONNECTED, + MQTT_CONNECT_SEND, + MQTT_CONNECT_SENDING, + MQTT_SUBSCIBE_SEND, + MQTT_SUBSCIBE_SENDING, + MQTT_DATA, + MQTT_PUBLISH_RECV, + MQTT_PUBLISHING } tConnState; -typedef void (*MqttCallback)(uint32_t *args); -typedef void (*MqttDataCallback)(uint32_t *args, const char* topic, uint32_t topic_len, const char *data, uint32_t lengh); +typedef void (*MqttCallback)(uint32_t* args); +typedef void (*MqttDataCallback)(uint32_t* args, const char* topic, uint32_t topic_len, const char* data, uint32_t lengh); -typedef struct { - struct espconn *pCon; - uint8_t security; - uint8_t* host; - uint32_t port; - ip_addr_t ip; - mqtt_state_t mqtt_state; - mqtt_connect_info_t connect_info; - MqttCallback connectedCb; - MqttCallback disconnectedCb; - MqttCallback publishedCb; - MqttDataCallback dataCb; - ETSTimer mqttTimer; - uint32_t keepAliveTick; - uint32_t reconnectTick; - uint32_t sendTimeout; - tConnState connState; - QUEUE msgQueue; - void* user_data; +typedef struct { + struct espconn* pCon; + uint32_t security; + uint8_t* host; + uint32_t port; + ip_addr_t ip; + mqtt_state_t mqtt_state; + mqtt_connect_info_t connect_info; + MqttCallback connectedCb; + MqttCallback cmdConnectedCb; + MqttCallback disconnectedCb; + MqttCallback cmdDisconnectedCb; + MqttCallback tcpDisconnectedCb; + MqttCallback cmdTcpDisconnectedCb; + MqttCallback publishedCb; + MqttCallback cmdPublishedCb; + MqttDataCallback dataCb; + MqttDataCallback cmdDataCb; + ETSTimer mqttTimer; + uint32_t keepAliveTick; + uint32_t reconnectTick; + uint32_t sendTimeout; + tConnState connState; + QUEUE msgQueue; + void* user_data; } MQTT_Client; #define SEC_NONSSL 0 @@ -125,16 +129,16 @@ typedef struct { #define MQTT_EVENT_TYPE_EXITED 7 #define MQTT_EVENT_TYPE_PUBLISH_CONTINUATION 8 -void ICACHE_FLASH_ATTR MQTT_InitConnection(MQTT_Client *mqttClient, uint8_t* host, uint32 port, uint8_t security); -void ICACHE_FLASH_ATTR MQTT_InitClient(MQTT_Client *mqttClient, uint8_t* client_id, uint8_t* client_user, uint8_t* client_pass, uint32_t keepAliveTime, uint8_t cleanSession); -void ICACHE_FLASH_ATTR MQTT_InitLWT(MQTT_Client *mqttClient, uint8_t* will_topic, uint8_t* will_msg, uint8_t will_qos, uint8_t will_retain); -void ICACHE_FLASH_ATTR MQTT_OnConnected(MQTT_Client *mqttClient, MqttCallback connectedCb); -void ICACHE_FLASH_ATTR MQTT_OnDisconnected(MQTT_Client *mqttClient, MqttCallback disconnectedCb); -void ICACHE_FLASH_ATTR MQTT_OnPublished(MQTT_Client *mqttClient, MqttCallback publishedCb); -void ICACHE_FLASH_ATTR MQTT_OnData(MQTT_Client *mqttClient, MqttDataCallback dataCb); -bool ICACHE_FLASH_ATTR MQTT_Subscribe(MQTT_Client *client, char* topic, uint8_t qos); -void ICACHE_FLASH_ATTR MQTT_Connect(MQTT_Client *mqttClient); -void ICACHE_FLASH_ATTR MQTT_Disconnect(MQTT_Client *mqttClient); -bool ICACHE_FLASH_ATTR MQTT_Publish(MQTT_Client *client, const char* topic, const char* data, int qos, int retain); +void ICACHE_FLASH_ATTR MQTT_InitConnection(MQTT_Client* mqttClient, uint8_t* host, uint32 port, uint8_t security); +void ICACHE_FLASH_ATTR MQTT_InitClient(MQTT_Client* mqttClient, uint8_t* client_id, uint8_t* client_user, uint8_t* client_pass, uint8_t keepAliveTime, uint8_t cleanSession); +void ICACHE_FLASH_ATTR MQTT_InitLWT(MQTT_Client* mqttClient, uint8_t* will_topic, uint8_t* will_msg, uint8_t will_qos, uint8_t will_retain); +void ICACHE_FLASH_ATTR MQTT_OnConnected(MQTT_Client* mqttClient, MqttCallback connectedCb); +void ICACHE_FLASH_ATTR MQTT_OnDisconnected(MQTT_Client* mqttClient, MqttCallback disconnectedCb); +void ICACHE_FLASH_ATTR MQTT_OnPublished(MQTT_Client* mqttClient, MqttCallback publishedCb); +void ICACHE_FLASH_ATTR MQTT_OnData(MQTT_Client* mqttClient, MqttDataCallback dataCb); +bool ICACHE_FLASH_ATTR MQTT_Subscribe(MQTT_Client* client, char* topic, uint8_t qos); +void ICACHE_FLASH_ATTR MQTT_Connect(MQTT_Client* mqttClient); +void ICACHE_FLASH_ATTR MQTT_Disconnect(MQTT_Client* mqttClient); +bool ICACHE_FLASH_ATTR MQTT_Publish(MQTT_Client* client, const char* topic, const char* data, uint8_t qos, uint8_t retain); #endif /* USER_AT_MQTT_H_ */ diff --git a/mqtt/mqtt_msg.c b/mqtt/mqtt_msg.c index 77c777e..03da28e 100644 --- a/mqtt/mqtt_msg.c +++ b/mqtt/mqtt_msg.c @@ -32,8 +32,7 @@ #include "mqtt_msg.h" #define MQTT_MAX_FIXED_HEADER_SIZE 3 -enum mqtt_connect_flag -{ +enum mqtt_connect_flag { MQTT_CONNECT_FLAG_USERNAME = 1 << 7, MQTT_CONNECT_FLAG_PASSWORD = 1 << 6, MQTT_CONNECT_FLAG_WILL_RETAIN = 1 << 5, @@ -41,8 +40,8 @@ enum mqtt_connect_flag MQTT_CONNECT_FLAG_CLEAN_SESSION = 1 << 1 }; -struct __attribute__((__packed__)) mqtt_connect_variable_header -{ +struct + __attribute__((__packed__)) mqtt_connect_variable_header { uint8_t lengthMsb; uint8_t lengthLsb; #if defined(PROTOCOL_NAMEv31) @@ -58,8 +57,8 @@ struct __attribute__((__packed__)) mqtt_connect_variable_header uint8_t keepaliveLsb; }; -static int ICACHE_FLASH_ATTR append_string(mqtt_connection_t* connection, const char* string, int len) -{ +static int ICACHE_FLASH_ATTR +append_string(mqtt_connection_t* connection, const char* string, int len) { if (connection->message.length + len + 2 > connection->buffer_length) return -1; @@ -71,8 +70,8 @@ static int ICACHE_FLASH_ATTR append_string(mqtt_connection_t* connection, const return len + 2; } -static uint16_t ICACHE_FLASH_ATTR append_message_id(mqtt_connection_t* connection, uint16_t message_id) -{ +static uint16_t ICACHE_FLASH_ATTR +append_message_id(mqtt_connection_t* connection, uint16_t message_id) { // If message_id is zero then we should assign one, otherwise // we'll use the one supplied by the caller while (message_id == 0) @@ -87,33 +86,31 @@ static uint16_t ICACHE_FLASH_ATTR append_message_id(mqtt_connection_t* connectio return message_id; } -static int ICACHE_FLASH_ATTR init_message(mqtt_connection_t* connection) -{ +static int ICACHE_FLASH_ATTR +init_message(mqtt_connection_t* connection) { connection->message.length = MQTT_MAX_FIXED_HEADER_SIZE; return MQTT_MAX_FIXED_HEADER_SIZE; } -static mqtt_message_t* ICACHE_FLASH_ATTR fail_message(mqtt_connection_t* connection) -{ +static mqtt_message_t* ICACHE_FLASH_ATTR +fail_message(mqtt_connection_t* connection) { connection->message.data = connection->buffer; connection->message.length = 0; return &connection->message; } -static mqtt_message_t* ICACHE_FLASH_ATTR fini_message(mqtt_connection_t* connection, int type, int dup, int qos, int retain) -{ +static mqtt_message_t* ICACHE_FLASH_ATTR +fini_message(mqtt_connection_t* connection, int type, int dup, int qos, int retain) { int remaining_length = connection->message.length - MQTT_MAX_FIXED_HEADER_SIZE; - if (remaining_length > 127) - { + if (remaining_length > 127) { connection->buffer[0] = ((type & 0x0f) << 4) | ((dup & 1) << 3) | ((qos & 3) << 1) | (retain & 1); connection->buffer[1] = 0x80 | (remaining_length % 128); connection->buffer[2] = remaining_length / 128; connection->message.length = remaining_length + 3; connection->message.data = connection->buffer; } - else - { + else { connection->buffer[1] = ((type & 0x0f) << 4) | ((dup & 1) << 3) | ((qos & 3) << 1) | (retain & 1); connection->buffer[2] = remaining_length; connection->message.length = remaining_length + 2; @@ -131,16 +128,14 @@ mqtt_msg_init(mqtt_connection_t* connection, uint8_t* buffer, uint16_t buffer_le connection->buffer_length = buffer_length; } -int ICACHE_FLASH_ATTR mqtt_get_total_length(uint8_t* buffer, uint16_t length) -{ +int ICACHE_FLASH_ATTR +mqtt_get_total_length(uint8_t* buffer, uint16_t length) { int i; int totlen = 0; - for (i = 1; i < length; ++i) - { + for (i = 1; i < length; ++i) { totlen += (buffer[i] & 0x7f) << (7 * (i - 1)); - if ((buffer[i] & 0x80) == 0) - { + if ((buffer[i] & 0x80) == 0) { ++i; break; } @@ -150,17 +145,15 @@ int ICACHE_FLASH_ATTR mqtt_get_total_length(uint8_t* buffer, uint16_t length) return totlen; } -const char* ICACHE_FLASH_ATTR mqtt_get_publish_topic(uint8_t* buffer, uint16_t* length) -{ +const char* ICACHE_FLASH_ATTR +mqtt_get_publish_topic(uint8_t* buffer, uint16_t* length) { int i; int totlen = 0; int topiclen; - for (i = 1; i < *length; ++i) - { + for (i = 1; i < *length; ++i) { totlen += (buffer[i] & 0x7f) << (7 * (i - 1)); - if ((buffer[i] & 0x80) == 0) - { + if ((buffer[i] & 0x80) == 0) { ++i; break; } @@ -179,17 +172,15 @@ const char* ICACHE_FLASH_ATTR mqtt_get_publish_topic(uint8_t* buffer, uint16_t* return (const char*)(buffer + i); } -const char* ICACHE_FLASH_ATTR mqtt_get_publish_data(uint8_t* buffer, uint16_t* length) -{ +const char* ICACHE_FLASH_ATTR +mqtt_get_publish_data(uint8_t* buffer, uint16_t* length) { int i; int totlen = 0; int topiclen; - for (i = 1; i < *length; ++i) - { + for (i = 1; i < *length; ++i) { totlen += (buffer[i] & 0x7f) << (7 * (i - 1)); - if ((buffer[i] & 0x80) == 0) - { + if ((buffer[i] & 0x80) == 0) { ++i; break; } @@ -201,14 +192,13 @@ const char* ICACHE_FLASH_ATTR mqtt_get_publish_data(uint8_t* buffer, uint16_t* l topiclen = buffer[i++] << 8; topiclen |= buffer[i++]; - if (i + topiclen >= *length){ + if (i + topiclen >= *length) { *length = 0; return NULL; } i += topiclen; - if (mqtt_get_qos(buffer) > 0) - { + if (mqtt_get_qos(buffer) > 0) { if (i + 2 >= *length) return NULL; i += 2; @@ -224,71 +214,65 @@ const char* ICACHE_FLASH_ATTR mqtt_get_publish_data(uint8_t* buffer, uint16_t* l return (const char*)(buffer + i); } -uint16_t ICACHE_FLASH_ATTR mqtt_get_id(uint8_t* buffer, uint16_t length) -{ +uint16_t ICACHE_FLASH_ATTR +mqtt_get_id(uint8_t* buffer, uint16_t length) { if (length < 1) return 0; - switch (mqtt_get_type(buffer)) - { - case MQTT_MSG_TYPE_PUBLISH: - { - int i; - int topiclen; - - for (i = 1; i < length; ++i) - { - if ((buffer[i] & 0x80) == 0) - { - ++i; - break; + switch (mqtt_get_type(buffer)) { + case MQTT_MSG_TYPE_PUBLISH: { + int i; + int topiclen; + + for (i = 1; i < length; ++i) { + if ((buffer[i] & 0x80) == 0) { + ++i; + break; + } } - } - if (i + 2 >= length) - return 0; - topiclen = buffer[i++] << 8; - topiclen |= buffer[i++]; + if (i + 2 >= length) + return 0; + topiclen = buffer[i++] << 8; + topiclen |= buffer[i++]; - if (i + topiclen >= length) - return 0; - i += topiclen; + if (i + topiclen >= length) + return 0; + i += topiclen; - if (mqtt_get_qos(buffer) > 0) - { - if (i + 2 >= length) + if (mqtt_get_qos(buffer) > 0) { + if (i + 2 >= length) + return 0; + //i += 2; + } + else { return 0; - //i += 2; + } + + return (buffer[i] << 8) | buffer[i + 1]; } - else { - return 0; + case MQTT_MSG_TYPE_PUBACK: + case MQTT_MSG_TYPE_PUBREC: + case MQTT_MSG_TYPE_PUBREL: + case MQTT_MSG_TYPE_PUBCOMP: + case MQTT_MSG_TYPE_SUBACK: + case MQTT_MSG_TYPE_UNSUBACK: + case MQTT_MSG_TYPE_SUBSCRIBE: { + // This requires the remaining length to be encoded in 1 byte, + // which it should be. + if (length >= 4 && (buffer[1] & 0x80) == 0) + return (buffer[2] << 8) | buffer[3]; + else + return 0; } - return (buffer[i] << 8) | buffer[i + 1]; - } - case MQTT_MSG_TYPE_PUBACK: - case MQTT_MSG_TYPE_PUBREC: - case MQTT_MSG_TYPE_PUBREL: - case MQTT_MSG_TYPE_PUBCOMP: - case MQTT_MSG_TYPE_SUBACK: - case MQTT_MSG_TYPE_UNSUBACK: - case MQTT_MSG_TYPE_SUBSCRIBE: - { - // This requires the remaining length to be encoded in 1 byte, - // which it should be. - if (length >= 4 && (buffer[1] & 0x80) == 0) - return (buffer[2] << 8) | buffer[3]; - else + default: return 0; } - - default: - return 0; - } } -mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_connect(mqtt_connection_t* connection, mqtt_connect_info_t* info) -{ +mqtt_message_t* ICACHE_FLASH_ATTR +mqtt_msg_connect(mqtt_connection_t* connection, mqtt_connect_info_t* info) { struct mqtt_connect_variable_header* variable_header; init_message(connection); @@ -318,16 +302,14 @@ mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_connect(mqtt_connection_t* connection if (info->clean_session) variable_header->flags |= MQTT_CONNECT_FLAG_CLEAN_SESSION; - if (info->client_id != NULL && info->client_id[0] != '\0') - { + if (info->client_id != NULL && info->client_id[0] != '\0') { if (append_string(connection, info->client_id, strlen(info->client_id)) < 0) return fail_message(connection); } else return fail_message(connection); - if (info->will_topic != NULL && info->will_topic[0] != '\0') - { + if (info->will_topic != NULL && info->will_topic[0] != '\0') { if (append_string(connection, info->will_topic, strlen(info->will_topic)) < 0) return fail_message(connection); @@ -340,16 +322,14 @@ mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_connect(mqtt_connection_t* connection variable_header->flags |= (info->will_qos & 3) << 3; } - if (info->username != NULL && info->username[0] != '\0') - { + if (info->username != NULL && info->username[0] != '\0') { if (append_string(connection, info->username, strlen(info->username)) < 0) return fail_message(connection); variable_header->flags |= MQTT_CONNECT_FLAG_USERNAME; } - if (info->password != NULL && info->password[0] != '\0') - { + if (info->password != NULL && info->password[0] != '\0') { if (append_string(connection, info->password, strlen(info->password)) < 0) return fail_message(connection); @@ -359,8 +339,8 @@ mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_connect(mqtt_connection_t* connection return fini_message(connection, MQTT_MSG_TYPE_CONNECT, 0, 0, 0); } -mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_publish(mqtt_connection_t* connection, const char* topic, const char* data, int data_length, int qos, int retain, uint16_t* message_id) -{ +mqtt_message_t* ICACHE_FLASH_ATTR +mqtt_msg_publish(mqtt_connection_t* connection, const char* topic, const char* data, int data_length, int qos, int retain, uint16_t* message_id) { init_message(connection); if (topic == NULL || topic[0] == '\0') @@ -369,8 +349,7 @@ mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_publish(mqtt_connection_t* connection if (append_string(connection, topic, strlen(topic)) < 0) return fail_message(connection); - if (qos > 0) - { + if (qos > 0) { if ((*message_id = append_message_id(connection, 0)) == 0) return fail_message(connection); } @@ -385,40 +364,40 @@ mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_publish(mqtt_connection_t* connection return fini_message(connection, MQTT_MSG_TYPE_PUBLISH, 0, qos, retain); } -mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_puback(mqtt_connection_t* connection, uint16_t message_id) -{ +mqtt_message_t* ICACHE_FLASH_ATTR +mqtt_msg_puback(mqtt_connection_t* connection, uint16_t message_id) { init_message(connection); if (append_message_id(connection, message_id) == 0) return fail_message(connection); return fini_message(connection, MQTT_MSG_TYPE_PUBACK, 0, 0, 0); } -mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_pubrec(mqtt_connection_t* connection, uint16_t message_id) -{ +mqtt_message_t* ICACHE_FLASH_ATTR +mqtt_msg_pubrec(mqtt_connection_t* connection, uint16_t message_id) { init_message(connection); if (append_message_id(connection, message_id) == 0) return fail_message(connection); return fini_message(connection, MQTT_MSG_TYPE_PUBREC, 0, 0, 0); } -mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_pubrel(mqtt_connection_t* connection, uint16_t message_id) -{ +mqtt_message_t* ICACHE_FLASH_ATTR +mqtt_msg_pubrel(mqtt_connection_t* connection, uint16_t message_id) { init_message(connection); if (append_message_id(connection, message_id) == 0) return fail_message(connection); return fini_message(connection, MQTT_MSG_TYPE_PUBREL, 0, 1, 0); } -mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_pubcomp(mqtt_connection_t* connection, uint16_t message_id) -{ +mqtt_message_t* ICACHE_FLASH_ATTR +mqtt_msg_pubcomp(mqtt_connection_t* connection, uint16_t message_id) { init_message(connection); if (append_message_id(connection, message_id) == 0) return fail_message(connection); return fini_message(connection, MQTT_MSG_TYPE_PUBCOMP, 0, 0, 0); } -mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_subscribe(mqtt_connection_t* connection, const char* topic, int qos, uint16_t* message_id) -{ +mqtt_message_t* ICACHE_FLASH_ATTR +mqtt_msg_subscribe(mqtt_connection_t* connection, const char* topic, int qos, uint16_t* message_id) { init_message(connection); if (topic == NULL || topic[0] == '\0') @@ -437,8 +416,8 @@ mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_subscribe(mqtt_connection_t* connecti return fini_message(connection, MQTT_MSG_TYPE_SUBSCRIBE, 0, 1, 0); } -mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_unsubscribe(mqtt_connection_t* connection, const char* topic, uint16_t* message_id) -{ +mqtt_message_t* ICACHE_FLASH_ATTR +mqtt_msg_unsubscribe(mqtt_connection_t* connection, const char* topic, uint16_t* message_id) { init_message(connection); if (topic == NULL || topic[0] == '\0') @@ -453,20 +432,20 @@ mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_unsubscribe(mqtt_connection_t* connec return fini_message(connection, MQTT_MSG_TYPE_UNSUBSCRIBE, 0, 1, 0); } -mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_pingreq(mqtt_connection_t* connection) -{ +mqtt_message_t* ICACHE_FLASH_ATTR +mqtt_msg_pingreq(mqtt_connection_t* connection) { init_message(connection); return fini_message(connection, MQTT_MSG_TYPE_PINGREQ, 0, 0, 0); } -mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_pingresp(mqtt_connection_t* connection) -{ +mqtt_message_t* ICACHE_FLASH_ATTR +mqtt_msg_pingresp(mqtt_connection_t* connection) { init_message(connection); return fini_message(connection, MQTT_MSG_TYPE_PINGRESP, 0, 0, 0); } -mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_disconnect(mqtt_connection_t* connection) -{ +mqtt_message_t* ICACHE_FLASH_ATTR +mqtt_msg_disconnect(mqtt_connection_t* connection) { init_message(connection); return fini_message(connection, MQTT_MSG_TYPE_DISCONNECT, 0, 0, 0); } diff --git a/mqtt/include/mqtt_msg.h b/mqtt/mqtt_msg.h similarity index 86% rename from mqtt/include/mqtt_msg.h rename to mqtt/mqtt_msg.h index f16bb80..ce840b7 100644 --- a/mqtt/include/mqtt_msg.h +++ b/mqtt/mqtt_msg.h @@ -1,18 +1,3 @@ -/* - * File: mqtt_msg.h - * Author: Minh Tuan - * - * Created on July 12, 2014, 1:05 PM - */ - -#ifndef MQTT_MSG_H -#define MQTT_MSG_H -#include - -#ifdef __cplusplus -extern "C" { -#endif - /* * Copyright (c) 2014, Stephen Robinson * All rights reserved. @@ -43,12 +28,12 @@ extern "C" { * POSSIBILITY OF SUCH DAMAGE. * */ -/* 7 6 5 4 3 2 1 0*/ -/* | --- Message Type ---- | DUP Flag | QoS Level | Retain | Remaining Length | */ +#ifndef MQTT_MSG_H +#define MQTT_MSG_H +#include -enum mqtt_message_type -{ +enum mqtt_message_type { MQTT_MSG_TYPE_CONNECT = 1, MQTT_MSG_TYPE_CONNACK = 2, MQTT_MSG_TYPE_PUBLISH = 3, @@ -65,15 +50,13 @@ enum mqtt_message_type MQTT_MSG_TYPE_DISCONNECT = 14 }; -typedef struct mqtt_message -{ +typedef struct mqtt_message { uint8_t* data; uint16_t length; } mqtt_message_t; -typedef struct mqtt_connection -{ +typedef struct mqtt_connection { mqtt_message_t message; uint16_t message_id; @@ -82,25 +65,35 @@ typedef struct mqtt_connection } mqtt_connection_t; -typedef struct mqtt_connect_info -{ +typedef struct mqtt_connect_info { char* client_id; char* username; char* password; char* will_topic; char* will_message; - int keepalive; - int will_qos; - int will_retain; - int clean_session; + uint32_t keepalive; + uint32_t will_qos; + uint32_t will_retain; + uint32_t clean_session; } mqtt_connect_info_t; -static inline int ICACHE_FLASH_ATTR mqtt_get_type(uint8_t* buffer) { return (buffer[0] & 0xf0) >> 4; } -static inline int ICACHE_FLASH_ATTR mqtt_get_dup(uint8_t* buffer) { return (buffer[0] & 0x08) >> 3; } -static inline int ICACHE_FLASH_ATTR mqtt_get_qos(uint8_t* buffer) { return (buffer[0] & 0x06) >> 1; } -static inline int ICACHE_FLASH_ATTR mqtt_get_retain(uint8_t* buffer) { return (buffer[0] & 0x01); } +static inline int ICACHE_FLASH_ATTR mqtt_get_type(uint8_t* buffer) { + return (buffer[0] & 0xf0) >> 4; +} + +static inline int ICACHE_FLASH_ATTR mqtt_get_dup(uint8_t* buffer) { + return (buffer[0] & 0x08) >> 3; +} + +static inline int ICACHE_FLASH_ATTR mqtt_get_qos(uint8_t* buffer) { + return (buffer[0] & 0x06) >> 1; +} + +static inline int ICACHE_FLASH_ATTR mqtt_get_retain(uint8_t* buffer) { + return (buffer[0] & 0x01); +} void ICACHE_FLASH_ATTR mqtt_msg_init(mqtt_connection_t* connection, uint8_t* buffer, uint16_t buffer_length); int ICACHE_FLASH_ATTR mqtt_get_total_length(uint8_t* buffer, uint16_t length); @@ -120,10 +113,5 @@ mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_pingreq(mqtt_connection_t* connection mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_pingresp(mqtt_connection_t* connection); mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_disconnect(mqtt_connection_t* connection); - -#ifdef __cplusplus -} -#endif - -#endif /* MQTT_MSG_H */ +#endif // MQTT_MSG_H diff --git a/mqtt/proto.c b/mqtt/proto.c index 3909b15..69b5367 100644 --- a/mqtt/proto.c +++ b/mqtt/proto.c @@ -1,128 +1,86 @@ #include "proto.h" -int8_t ICACHE_FLASH_ATTR PROTO_Init(PROTO_PARSER *parser, PROTO_PARSE_CALLBACK *completeCallback, uint8_t *buf, uint16_t bufSize) -{ - parser->buf = buf; - parser->bufSize = bufSize; - parser->dataLen = 0; - parser->callback = completeCallback; - parser->isEsc = 0; - return 0; +int8_t ICACHE_FLASH_ATTR +PROTO_Init(PROTO_PARSER* parser, PROTO_PARSE_CALLBACK* completeCallback, uint8_t* buf, uint16_t bufSize) { + parser->buf = buf; + parser->bufSize = bufSize; + parser->dataLen = 0; + parser->callback = completeCallback; + parser->isEsc = 0; + return 0; } -int8_t ICACHE_FLASH_ATTR PROTO_ParseByte(PROTO_PARSER *parser, uint8_t value) -{ - switch(value){ - case 0x7D: - parser->isEsc = 1; - break; - - case 0x7E: - parser->dataLen = 0; - parser->isEsc = 0; - parser->isBegin = 1; - break; - - case 0x7F: - if (parser->callback != NULL) - parser->callback(); - parser->isBegin = 0; - return 0; - break; - - default: - if(parser->isBegin == 0) break; - - if(parser->isEsc){ - value ^= 0x20; - parser->isEsc = 0; - } - - if(parser->dataLen < parser->bufSize) - parser->buf[parser->dataLen++] = value; - - break; - } - return -1; -} +int8_t ICACHE_FLASH_ATTR +PROTO_ParseByte(PROTO_PARSER* parser, uint8_t value) { + switch (value) { + case 0x7D: + parser->isEsc = 1; + break; -int8_t ICACHE_FLASH_ATTR PROTO_Parse(PROTO_PARSER *parser, uint8_t *buf, uint16_t len) -{ - while(len--) - PROTO_ParseByte(parser, *buf++); - return 0; -} -int16_t ICACHE_FLASH_ATTR PROTO_ParseRb(RINGBUF* rb, uint8_t *bufOut, uint16_t* len, uint16_t maxBufLen) -{ - uint8_t c; + case 0x7E: + parser->dataLen = 0; + parser->isEsc = 0; + parser->isBegin = 1; + break; - PROTO_PARSER proto; - PROTO_Init(&proto, NULL, bufOut, maxBufLen); - while(RINGBUF_Get(rb, &c) == 0){ - if(PROTO_ParseByte(&proto, c) == 0){ - *len = proto.dataLen; - return 0; - } - } - return -1; -} -int16_t ICACHE_FLASH_ATTR PROTO_Add(uint8_t *buf, const uint8_t *packet, int16_t bufSize) -{ - uint16_t i = 2; - uint16_t len = *(uint16_t*) packet; + case 0x7F: + if (parser->callback != NULL) + parser->callback(); + parser->isBegin = 0; + return 0; + break; - if (bufSize < 1) return -1; + default: + if (parser->isBegin == 0) break; - *buf++ = 0x7E; - bufSize--; + if (parser->isEsc) { + value ^= 0x20; + parser->isEsc = 0; + } - while (len--) { - switch (*packet) { - case 0x7D: - case 0x7E: - case 0x7F: - if (bufSize < 2) return -1; - *buf++ = 0x7D; - *buf++ = *packet++ ^ 0x20; - i += 2; - bufSize -= 2; - break; - default: - if (bufSize < 1) return -1; - *buf++ = *packet++; - i++; - bufSize--; - break; - } - } + if (parser->dataLen < parser->bufSize) + parser->buf[parser->dataLen++] = value; - if (bufSize < 1) return -1; - *buf++ = 0x7F; + break; + } + return -1; +} + +int16_t ICACHE_FLASH_ATTR +PROTO_ParseRb(RINGBUF* rb, uint8_t* bufOut, uint16_t* len, uint16_t maxBufLen) { + uint8_t c; - return i; + PROTO_PARSER proto; + PROTO_Init(&proto, NULL, bufOut, maxBufLen); + while (RINGBUF_Get(rb, &c) == 0) { + if (PROTO_ParseByte(&proto, c) == 0) { + *len = proto.dataLen; + return 0; + } + } + return -1; } -int16_t ICACHE_FLASH_ATTR PROTO_AddRb(RINGBUF *rb, const uint8_t *packet, int16_t len) -{ - uint16_t i = 2; - if(RINGBUF_Put(rb, 0x7E) == -1) return -1; - while (len--) { - switch (*packet) { - case 0x7D: - case 0x7E: - case 0x7F: - if(RINGBUF_Put(rb, 0x7D) == -1) return -1; - if(RINGBUF_Put(rb, *packet++ ^ 0x20) == -1) return -1; - i += 2; - break; - default: - if(RINGBUF_Put(rb, *packet++) == -1) return -1; - i++; - break; - } +int16_t ICACHE_FLASH_ATTR +PROTO_AddRb(RINGBUF* rb, const uint8_t* packet, int16_t len) { + uint16_t i = 2; + if (RINGBUF_Put(rb, 0x7E) == -1) return -1; + while (len--) { + switch (*packet) { + case 0x7D: + case 0x7E: + case 0x7F: + if (RINGBUF_Put(rb, 0x7D) == -1) return -1; + if (RINGBUF_Put(rb, *packet++ ^ 0x20) == -1) return -1; + i += 2; + break; + default: + if (RINGBUF_Put(rb, *packet++) == -1) return -1; + i++; + break; } - if(RINGBUF_Put(rb, 0x7F) == -1) return -1; + } + if (RINGBUF_Put(rb, 0x7F) == -1) return -1; - return i; + return i; } - diff --git a/mqtt/proto.h b/mqtt/proto.h new file mode 100644 index 0000000..8d20832 --- /dev/null +++ b/mqtt/proto.h @@ -0,0 +1,28 @@ +/* + * File: proto.h + * Author: ThuHien + * + * Created on November 23, 2012, 8:57 AM + */ + +#ifndef _PROTO_H_ +#define _PROTO_H_ +#include +#include "ringbuf.h" + +typedef void (PROTO_PARSE_CALLBACK)(); + +typedef struct { + uint8_t* buf; + uint16_t bufSize; + uint16_t dataLen; + uint8_t isEsc; + uint8_t isBegin; + PROTO_PARSE_CALLBACK* callback; +} PROTO_PARSER; + +int8_t ICACHE_FLASH_ATTR PROTO_Init(PROTO_PARSER* parser, PROTO_PARSE_CALLBACK* completeCallback, uint8_t* buf, uint16_t bufSize); +int16_t ICACHE_FLASH_ATTR PROTO_AddRb(RINGBUF* rb, const uint8_t* packet, int16_t len); +int8_t ICACHE_FLASH_ATTR PROTO_ParseByte(PROTO_PARSER* parser, uint8_t value); +int16_t ICACHE_FLASH_ATTR PROTO_ParseRb(RINGBUF* rb, uint8_t* bufOut, uint16_t* len, uint16_t maxBufLen); +#endif diff --git a/mqtt/queue.c b/mqtt/queue.c index 147015e..39c4790 100644 --- a/mqtt/queue.c +++ b/mqtt/queue.c @@ -29,22 +29,25 @@ */ #include "queue.h" -void ICACHE_FLASH_ATTR QUEUE_Init(QUEUE *queue, int bufferSize) { +void ICACHE_FLASH_ATTR +QUEUE_Init(QUEUE* queue, int bufferSize) { queue->buf = (uint8_t*)os_zalloc(bufferSize); RINGBUF_Init(&queue->rb, queue->buf, bufferSize); } -int32_t ICACHE_FLASH_ATTR QUEUE_Puts(QUEUE *queue, uint8_t* buffer, uint16_t len) { +int32_t ICACHE_FLASH_ATTR +QUEUE_Puts(QUEUE* queue, uint8_t* buffer, uint16_t len) { return PROTO_AddRb(&queue->rb, buffer, len); } -int32_t ICACHE_FLASH_ATTR QUEUE_Gets(QUEUE *queue, uint8_t* buffer, uint16_t* len, uint16_t maxLen) { - +int32_t ICACHE_FLASH_ATTR +QUEUE_Gets(QUEUE* queue, uint8_t* buffer, uint16_t* len, uint16_t maxLen) { return PROTO_ParseRb(&queue->rb, buffer, len, maxLen); } -bool ICACHE_FLASH_ATTR QUEUE_IsEmpty(QUEUE *queue) { +bool ICACHE_FLASH_ATTR +QUEUE_IsEmpty(QUEUE* queue) { if (queue->rb.fill_cnt <= 0) return TRUE; return FALSE; -} \ No newline at end of file +} diff --git a/mqtt/include/queue.h b/mqtt/queue.h similarity index 86% rename from mqtt/include/queue.h rename to mqtt/queue.h index 7a84480..78b7882 100644 --- a/mqtt/include/queue.h +++ b/mqtt/queue.h @@ -33,13 +33,14 @@ #include #include "proto.h" #include "ringbuf.h" + typedef struct { - uint8_t *buf; - RINGBUF rb; + uint8_t* buf; + RINGBUF rb; } QUEUE; -void ICACHE_FLASH_ATTR QUEUE_Init(QUEUE *queue, int bufferSize); -int32_t ICACHE_FLASH_ATTR QUEUE_Puts(QUEUE *queue, uint8_t* buffer, uint16_t len); -int32_t ICACHE_FLASH_ATTR QUEUE_Gets(QUEUE *queue, uint8_t* buffer, uint16_t* len, uint16_t maxLen); -bool ICACHE_FLASH_ATTR QUEUE_IsEmpty(QUEUE *queue); +void ICACHE_FLASH_ATTR QUEUE_Init(QUEUE* queue, int bufferSize); +int32_t ICACHE_FLASH_ATTR QUEUE_Puts(QUEUE* queue, uint8_t* buffer, uint16_t len); +int32_t ICACHE_FLASH_ATTR QUEUE_Gets(QUEUE* queue, uint8_t* buffer, uint16_t* len, uint16_t maxLen); +bool ICACHE_FLASH_ATTR QUEUE_IsEmpty(QUEUE* queue); #endif /* USER_QUEUE_H_ */ diff --git a/mqtt/ringbuf.c b/mqtt/ringbuf.c index 5ac3d07..a0cc782 100644 --- a/mqtt/ringbuf.c +++ b/mqtt/ringbuf.c @@ -1,11 +1,5 @@ -/** -* \file -* Ring Buffer library -*/ - #include "ringbuf.h" - /** * \brief init a RINGBUF object * \param r pointer to a RINGBUF object @@ -13,55 +7,57 @@ * \param size size of buf * \return 0 if successfull, otherwise failed */ -I16 ICACHE_FLASH_ATTR RINGBUF_Init(RINGBUF *r, U8* buf, I32 size) -{ - if(r == NULL || buf == NULL || size < 2) return -1; - - r->p_o = r->p_r = r->p_w = buf; - r->fill_cnt = 0; - r->size = size; - - return 0; +int16_t ICACHE_FLASH_ATTR +RINGBUF_Init(RINGBUF* r, uint8_t* buf, int32_t size) { + if (r == NULL || buf == NULL || size < 2) return -1; + + r->p_o = r->p_r = r->p_w = buf; + r->fill_cnt = 0; + r->size = size; + + return 0; } + /** * \brief put a character into ring buffer * \param r pointer to a ringbuf object * \param c character to be put * \return 0 if successfull, otherwise failed */ -I16 ICACHE_FLASH_ATTR RINGBUF_Put(RINGBUF *r, U8 c) -{ - if(r->fill_cnt>=r->size)return -1; // ring buffer is full, this should be atomic operation - - - r->fill_cnt++; // increase filled slots count, this should be atomic operation - - - *r->p_w++ = c; // put character into buffer - - if(r->p_w >= r->p_o + r->size) // rollback if write pointer go pass - r->p_w = r->p_o; // the physical boundary - - return 0; +int16_t ICACHE_FLASH_ATTR +RINGBUF_Put(RINGBUF* r, uint8_t c) { + if (r->fill_cnt >= r->size)return -1; // ring buffer is full, this should be atomic operation + + + r->fill_cnt++; // increase filled slots count, this should be atomic operation + + + *r->p_w++ = c; // put character into buffer + + if (r->p_w >= r->p_o + r->size) // rollback if write pointer go pass + r->p_w = r->p_o; // the physical boundary + + return 0; } + /** * \brief get a character from ring buffer * \param r pointer to a ringbuf object * \param c read character * \return 0 if successfull, otherwise failed */ -I16 ICACHE_FLASH_ATTR RINGBUF_Get(RINGBUF *r, U8* c) -{ - if(r->fill_cnt<=0)return -1; // ring buffer is empty, this should be atomic operation - - - r->fill_cnt--; // decrease filled slots count - - - *c = *r->p_r++; // get the character out - - if(r->p_r >= r->p_o + r->size) // rollback if write pointer go pass - r->p_r = r->p_o; // the physical boundary - - return 0; +int16_t ICACHE_FLASH_ATTR +RINGBUF_Get(RINGBUF* r, uint8_t* c) { + if (r->fill_cnt <= 0)return -1; // ring buffer is empty, this should be atomic operation + + + r->fill_cnt--; // decrease filled slots count + + + *c = *r->p_r++; // get the character out + + if (r->p_r >= r->p_o + r->size) // rollback if write pointer go pass + r->p_r = r->p_o; // the physical boundary + + return 0; } diff --git a/mqtt/ringbuf.h b/mqtt/ringbuf.h new file mode 100644 index 0000000..7d9f8e9 --- /dev/null +++ b/mqtt/ringbuf.h @@ -0,0 +1,17 @@ +#ifndef _RING_BUF_H_ +#define _RING_BUF_H_ + +#include + +typedef struct { + uint8_t* p_o; /**< Original pointer */ + uint8_t* volatile p_r; /**< Read pointer */ + uint8_t* volatile p_w; /**< Write pointer */ + volatile int32_t fill_cnt; /**< Number of filled slots */ + int32_t size; /**< Buffer size */ +} RINGBUF; + +int16_t ICACHE_FLASH_ATTR RINGBUF_Init(RINGBUF* r, uint8_t* buf, int32_t size); +int16_t ICACHE_FLASH_ATTR RINGBUF_Put(RINGBUF* r, uint8_t c); +int16_t ICACHE_FLASH_ATTR RINGBUF_Get(RINGBUF* r, uint8_t* c); +#endif diff --git a/mqtt/utils.c b/mqtt/utils.c index 173b573..86aff20 100644 --- a/mqtt/utils.c +++ b/mqtt/utils.c @@ -33,11 +33,10 @@ #include "utils.h" uint8_t ICACHE_FLASH_ATTR -UTILS_IsIPV4(int8_t *str) -{ - uint8_t segs = 0; /* Segment count. */ - uint8_t chcnt = 0; /* Character count within segment. */ - uint8_t accum = 0; /* Accumulator for segment. */ +UTILS_IsIPV4(int8_t* str) { + uint8_t segs = 0; /* Segment count. */ + uint8_t chcnt = 0; /* Character count within segment. */ + uint8_t accum = 0; /* Accumulator for segment. */ /* Catch NULL pointer. */ if (str == 0) return 0; @@ -85,8 +84,7 @@ UTILS_IsIPV4(int8_t *str) } uint8_t ICACHE_FLASH_ATTR -UTILS_StrToIP(const int8_t* str, void *ip) -{ +UTILS_StrToIP(const int8_t* str, void* ip) { /* The count of the number of bytes processed. */ int i; @@ -122,12 +120,11 @@ UTILS_StrToIP(const int8_t* str, void *ip) } uint32_t ICACHE_FLASH_ATTR -UTILS_Atoh(const int8_t *s) -{ +UTILS_Atoh(const int8_t* s) { uint32_t value = 0, digit; int8_t c; - while ((c = *s++)){ + while ((c = *s++)) { if ('0' <= c && c <= '9') digit = c - '0'; else if ('A' <= c && c <= 'F') @@ -141,4 +138,3 @@ UTILS_Atoh(const int8_t *s) return value; } - diff --git a/mqtt/utils.h b/mqtt/utils.h new file mode 100644 index 0000000..bc4d2af --- /dev/null +++ b/mqtt/utils.h @@ -0,0 +1,9 @@ +#ifndef _UTILS_H_ +#define _UTILS_H_ + +#include + +uint32_t ICACHE_FLASH_ATTR UTILS_Atoh(const int8_t* s); +uint8_t ICACHE_FLASH_ATTR UTILS_StrToIP(const int8_t* str, void* ip); +uint8_t ICACHE_FLASH_ATTR UTILS_IsIPV4(int8_t* str); +#endif diff --git a/user/user_main.c b/user/user_main.c index cf6d266..db5db0f 100644 --- a/user/user_main.c +++ b/user/user_main.c @@ -1,13 +1,13 @@ /* - * ---------------------------------------------------------------------------- - * "THE BEER-WARE LICENSE" (Revision 42): - * Jeroen Domburg wrote this file. As long as you retain - * this notice you can do whatever you want with this stuff. If we meet some day, - * and you think this stuff is worth it, you can buy me a beer in return. - * ---------------------------------------------------------------------------- - * Heavily modified and enhanced by Thorsten von Eicken in 2015 - * ---------------------------------------------------------------------------- - */ +* ---------------------------------------------------------------------------- +* "THE BEER-WARE LICENSE" (Revision 42): +* Jeroen Domburg wrote this file. As long as you retain +* this notice you can do whatever you want with this stuff. If we meet some day, +* and you think this stuff is worth it, you can buy me a beer in return. +* ---------------------------------------------------------------------------- +* Heavily modified and enhanced by Thorsten von Eicken in 2015 +* ---------------------------------------------------------------------------- +*/ #include @@ -35,19 +35,20 @@ //This is disabled in the default build; if you want to try it, enable the authBasic line in //the builtInUrls below. int myPassFn(HttpdConnData *connData, int no, char *user, int userLen, char *pass, int passLen) { - if (no==0) { - os_strcpy(user, "admin"); - os_strcpy(pass, "s3cr3t"); - return 1; -//Add more users this way. Check against incrementing no for each user added. -// } else if (no==1) { -// os_strcpy(user, "user1"); -// os_strcpy(pass, "something"); -// return 1; - } - return 0; + if (no == 0) { + os_strcpy(user, "admin"); + os_strcpy(pass, "s3cr3t"); + return 1; + //Add more users this way. Check against incrementing no for each user added. + // } else if (no==1) { + // os_strcpy(user, "user1"); + // os_strcpy(pass, "something"); + // return 1; + } + return 0; } + /* This is the main url->function dispatching data struct. In short, it's a struct with various URLs plus their handlers. The handlers can @@ -58,115 +59,110 @@ handled top-down, so make sure to put more specific rules above the more general ones. Authorization things (like authBasic) act as a 'barrier' and should be placed above the URLs they protect. */ -HttpdBuiltInUrl builtInUrls[]={ - {"/", cgiRedirect, "/home.html"}, - {"/menu", cgiMenu, NULL}, - {"/flash/next", cgiGetFirmwareNext, NULL}, - {"/flash/upload", cgiUploadFirmware, NULL}, - {"/flash/reboot", cgiRebootFirmware, NULL}, - //{"/home.html", cgiEspFsHtml, NULL}, - //{"/log.html", cgiEspFsHtml, NULL}, - {"/log/text", ajaxLog, NULL}, - {"/log/dbg", ajaxLogDbg, NULL}, - //{"/console.html", cgiEspFsHtml, NULL}, - {"/console/reset", ajaxConsoleReset, NULL}, - {"/console/baud", ajaxConsoleBaud, NULL}, - {"/console/text", ajaxConsole, NULL}, - - //Routines to make the /wifi URL and everything beneath it work. - -//Enable the line below to protect the WiFi configuration with an username/password combo. -// {"/wifi/*", authBasic, myPassFn}, - - {"/wifi", cgiRedirect, "/wifi/wifi.html"}, - {"/wifi/", cgiRedirect, "/wifi/wifi.html"}, - //{"/wifi/wifi.html", cgiEspFsHtml, NULL}, - {"/wifi/info", cgiWifiInfo, NULL}, - {"/wifi/scan", cgiWiFiScan, NULL}, - {"/wifi/connect", cgiWiFiConnect, NULL}, - {"/wifi/connstatus", cgiWiFiConnStatus, NULL}, - {"/wifi/setmode", cgiWiFiSetMode, NULL}, - {"/wifi/special", cgiWiFiSpecial, NULL}, - {"/pins", cgiPins, NULL}, - {"/tcpclient", cgiTcp, NULL}, - - {"*", cgiEspFsHook, NULL}, //Catch-all cgi function for the filesystem - {NULL, NULL, NULL} +HttpdBuiltInUrl builtInUrls[] = { + { "/", cgiRedirect, "/home.html" }, + { "/menu", cgiMenu, NULL }, + { "/flash/next", cgiGetFirmwareNext, NULL }, + { "/flash/upload", cgiUploadFirmware, NULL }, + { "/flash/reboot", cgiRebootFirmware, NULL }, + //{"/home.html", cgiEspFsHtml, NULL}, + //{"/log.html", cgiEspFsHtml, NULL}, + { "/log/text", ajaxLog, NULL }, + { "/log/dbg", ajaxLogDbg, NULL }, + //{"/console.html", cgiEspFsHtml, NULL}, + { "/console/reset", ajaxConsoleReset, NULL }, + { "/console/baud", ajaxConsoleBaud, NULL }, + { "/console/text", ajaxConsole, NULL }, + + //Routines to make the /wifi URL and everything beneath it work. + + //Enable the line below to protect the WiFi configuration with an username/password combo. + // {"/wifi/*", authBasic, myPassFn}, + + { "/wifi", cgiRedirect, "/wifi/wifi.html" }, + { "/wifi/", cgiRedirect, "/wifi/wifi.html" }, + //{"/wifi/wifi.html", cgiEspFsHtml, NULL}, + { "/wifi/info", cgiWifiInfo, NULL }, + { "/wifi/scan", cgiWiFiScan, NULL }, + { "/wifi/connect", cgiWiFiConnect, NULL }, + { "/wifi/connstatus", cgiWiFiConnStatus, NULL }, + { "/wifi/setmode", cgiWiFiSetMode, NULL }, + { "/wifi/special", cgiWiFiSpecial, NULL }, + { "/pins", cgiPins, NULL }, + { "/tcpclient", cgiTcp, NULL }, + + { "*", cgiEspFsHook, NULL }, //Catch-all cgi function for the filesystem + { NULL, NULL, NULL } }; + //#define SHOW_HEAP_USE #ifdef SHOW_HEAP_USE static ETSTimer prHeapTimer; static void ICACHE_FLASH_ATTR prHeapTimerCb(void *arg) { - os_printf("Heap: %ld\n", (unsigned long)system_get_free_heap_size()); + os_printf("Heap: %ld\n", (unsigned long)system_get_free_heap_size()); } #endif +void user_rf_pre_init(void) { +} + +// address of espfs binary blob +extern uint32_t _binary_espfs_img_start; + +static char *rst_codes[] = { + "normal", "wdt reset", "exception", "soft wdt", "restart", "deep sleep", "external", +}; + # define VERS_STR_STR(V) #V # define VERS_STR(V) VERS_STR_STR(V) char *esp_link_version = VERS_STR(VERSION); -void user_rf_pre_init(void) { +//Main routine. Initialize stdout, the I/O, filesystem and the webserver and we're done. +void user_init(void) { // get the flash config so we know how to init things - //configWipe(); // uncomment to reset the config for testing purposes + //configWipe(); // uncomment to reset the config for testing purposes bool restoreOk = configRestore(); - // init gpio pin registers gpio_init(); - // init UART uart_init(flashConfig.baud_rate, 115200); logInit(); // must come after init of uart - // say hello (leave some time to cause break in TX after boot loader's msg os_delay_us(10000L); os_printf("\n\n** %s\n", esp_link_version); os_printf("Flash config restore %s\n", restoreOk ? "ok" : "*FAILED*"); - // Status LEDs statusInit(); serledInit(); - + // Wifi + wifiInit(); + // init the flash filesystem with the html stuff + espFsInit(&_binary_espfs_img_start); + //EspFsInitResult res = espFsInit(&_binary_espfs_img_start); + //os_printf("espFsInit %s\n", res?"ERR":"ok"); + // mount the http handlers + httpdInit(builtInUrls, 80); + // init the wifi-serial transparent bridge (port 23) + serbridgeInit(23); + uart_add_recv_cb(&serbridgeUartCb); #ifdef SHOW_HEAP_USE os_timer_disarm(&prHeapTimer); os_timer_setfn(&prHeapTimer, prHeapTimerCb, NULL); os_timer_arm(&prHeapTimer, 10000, 1); #endif -} -// address of espfs binary blob -extern uint32_t _binary_espfs_img_start; + struct rst_info *rst_info = system_get_rst_info(); + os_printf("Reset cause: %d=%s\n", rst_info->reason, rst_codes[rst_info->reason]); + os_printf("exccause=%d epc1=0x%x epc2=0x%x epc3=0x%x excvaddr=0x%x depc=0x%x\n", + rst_info->exccause, rst_info->epc1, rst_info->epc2, rst_info->epc3, + rst_info->excvaddr, rst_info->depc); + os_printf("Flash map %d, chip %08X\n", system_get_flash_size_map(), spi_flash_get_id()); -static char *rst_codes[] = { - "normal", "wdt reset", "exception", "soft wdt", "restart", "deep sleep", "external", -}; + os_printf("** esp-link ready\n"); -//Main routine. Initialize stdout, the I/O, filesystem and the webserver and we're done. -void user_init(void) { - // Wifi - wifiInit(); - - // init the flash filesystem with the html stuff - espFsInit(&_binary_espfs_img_start); - - //EspFsInitResult res = espFsInit(&_binary_espfs_img_start); - //os_printf("espFsInit %s\n", res?"ERR":"ok"); - - // mount the http handlers - httpdInit(builtInUrls, 80); - - // init the wifi-serial transparent bridge (port 23) - serbridgeInit(23); - uart_add_recv_cb(&serbridgeUartCb); - - struct rst_info *rst_info = system_get_rst_info(); - os_printf("Reset cause: %d=%s\n", rst_info->reason, rst_codes[rst_info->reason]); - os_printf("exccause=%d epc1=0x%x epc2=0x%x epc3=0x%x excvaddr=0x%x depc=0x%x\n", - rst_info->exccause, rst_info->epc1, rst_info->epc2, rst_info->epc3, - rst_info->excvaddr, rst_info->depc); - os_printf("Flash map %d, chip %08X\n", system_get_flash_size_map(), spi_flash_get_id()); - - os_printf("** esp-link ready\n"); -} + // call user_main init +// init(); +} \ No newline at end of file