more mqtt work

pull/47/head
Benjamin Runnels 9 years ago
parent 634cfa6887
commit c2e60809f6
  1. 15
      cmd/handlers.c
  2. 336
      cmd/mqtt_cmd.c
  3. 22
      cmd/mqtt_cmd.h
  4. 35
      esp-link.vcxproj
  5. 4
      include/esp8266.h
  6. 31
      mqtt/include/proto.h
  7. 18
      mqtt/include/ringbuf.h
  8. 17
      mqtt/include/typedef.h
  9. 9
      mqtt/include/utils.h
  10. 152
      mqtt/mqtt.c
  11. 42
      mqtt/mqtt.h
  12. 149
      mqtt/mqtt_msg.c
  13. 66
      mqtt/mqtt_msg.h
  14. 80
      mqtt/proto.c
  15. 28
      mqtt/proto.h
  16. 13
      mqtt/queue.c
  17. 11
      mqtt/queue.h
  18. 30
      mqtt/ringbuf.c
  19. 17
      mqtt/ringbuf.h
  20. 12
      mqtt/utils.c
  21. 9
      mqtt/utils.h
  22. 130
      user/user_main.c

@ -9,6 +9,7 @@
#include "serbridge.h" #include "serbridge.h"
#include "uart.h" #include "uart.h"
#include "cgiwifi.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_Null(CmdPacket *cmd);
static uint32_t ICACHE_FLASH_ATTR CMD_IsReady(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_IS_READY, CMD_IsReady},
{CMD_WIFI_CONNECT, CMD_WifiConnect}, {CMD_WIFI_CONNECT, CMD_WifiConnect},
/* {CMD_MQTT_SETUP, MQTTCMD_Setup},
{CMD_MQTT_SETUP, MQTTAPP_Setup}, {CMD_MQTT_CONNECT, MQTTCMD_Connect},
{CMD_MQTT_CONNECT, MQTTAPP_Connect}, {CMD_MQTT_DISCONNECT, MQTTCMD_Disconnect},
{CMD_MQTT_DISCONNECT, MQTTAPP_Disconnect}, {CMD_MQTT_PUBLISH, MQTTCMD_Publish},
{CMD_MQTT_PUBLISH, MQTTAPP_Publish}, {CMD_MQTT_SUBSCRIBE , MQTTCMD_Subscribe},
{CMD_MQTT_SUBSCRIBE , MQTTAPP_Subscribe}, {CMD_MQTT_LWT, MQTTCMD_Lwt},
{CMD_MQTT_LWT, MQTTAPP_Lwt},
*/
{CMD_REST_SETUP, REST_Setup}, {CMD_REST_SETUP, REST_Setup},
{CMD_REST_REQUEST, REST_Request}, {CMD_REST_REQUEST, REST_Request},

@ -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;
}

@ -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_ */

@ -28,7 +28,7 @@
<PropertyGroup> <PropertyGroup>
<NMakeOutput /> <NMakeOutput />
<NMakePreprocessorDefinitions>__ets__;_STDINT_H;ICACHE_FLASH;__MINGW32__;__WIN32__</NMakePreprocessorDefinitions> <NMakePreprocessorDefinitions>__ets__;_STDINT_H;ICACHE_FLASH;__MINGW32__;__WIN32__</NMakePreprocessorDefinitions>
<NMakeIncludeSearchPath>.\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</NMakeIncludeSearchPath> <NMakeIncludeSearchPath>.\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</NMakeIncludeSearchPath>
<ExecutablePath /> <ExecutablePath />
<ReferencePath /> <ReferencePath />
<LibraryPath /> <LibraryPath />
@ -65,6 +65,7 @@
<ItemGroup> <ItemGroup>
<ClCompile Include="cmd\cmd.c" /> <ClCompile Include="cmd\cmd.c" />
<ClCompile Include="cmd\handlers.c" /> <ClCompile Include="cmd\handlers.c" />
<ClCompile Include="cmd\mqtt_cmd.c" />
<ClCompile Include="cmd\rest.c" /> <ClCompile Include="cmd\rest.c" />
<ClCompile Include="cmd\tcpclient.c" /> <ClCompile Include="cmd\tcpclient.c" />
<ClCompile Include="espfs\espfs.c" /> <ClCompile Include="espfs\espfs.c" />
@ -87,6 +88,15 @@
<ClCompile Include="serial\serled.c" /> <ClCompile Include="serial\serled.c" />
<ClCompile Include="serial\slip.c" /> <ClCompile Include="serial\slip.c" />
<ClCompile Include="serial\uart.c" /> <ClCompile Include="serial\uart.c" />
<ClCompile Include="esp-link\cgi.c" />
<ClCompile Include="esp-link\cgiflash.c" />
<ClCompile Include="esp-link\cgipins.c" />
<ClCompile Include="esp-link\cgitcp.c" />
<ClCompile Include="esp-link\cgiwifi.c" />
<ClCompile Include="esp-link\config.c" />
<ClCompile Include="esp-link\log.c" />
<ClCompile Include="esp-link\status.c" />
<ClCompile Include="esp-link\main.c" />
<ClCompile Include="user\cgi.c" /> <ClCompile Include="user\cgi.c" />
<ClCompile Include="user\cgiflash.c" /> <ClCompile Include="user\cgiflash.c" />
<ClCompile Include="user\cgipins.c" /> <ClCompile Include="user\cgipins.c" />
@ -95,10 +105,10 @@
<ClCompile Include="user\config.c" /> <ClCompile Include="user\config.c" />
<ClCompile Include="user\log.c" /> <ClCompile Include="user\log.c" />
<ClCompile Include="user\status.c" /> <ClCompile Include="user\status.c" />
<ClCompile Include="user\user_main.c" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="cmd\cmd.h" /> <ClInclude Include="cmd\cmd.h" />
<ClInclude Include="cmd\mqtt_cmd.h" />
<ClInclude Include="cmd\rest.h" /> <ClInclude Include="cmd\rest.h" />
<ClInclude Include="cmd\tcpclient.h" /> <ClInclude Include="cmd\tcpclient.h" />
<ClInclude Include="espfs\espfs.h" /> <ClInclude Include="espfs\espfs.h" />
@ -112,18 +122,25 @@
<ClInclude Include="include\espmissingincludes.h" /> <ClInclude Include="include\espmissingincludes.h" />
<ClInclude Include="include\uart_hw.h" /> <ClInclude Include="include\uart_hw.h" />
<ClInclude Include="include\user_config.h" /> <ClInclude Include="include\user_config.h" />
<ClInclude Include="mqtt\include\mqtt.h" /> <ClInclude Include="mqtt\mqtt.h" />
<ClInclude Include="mqtt\include\mqtt_msg.h" /> <ClInclude Include="mqtt\mqtt_msg.h" />
<ClInclude Include="mqtt\include\proto.h" /> <ClInclude Include="mqtt\proto.h" />
<ClInclude Include="mqtt\include\queue.h" /> <ClInclude Include="mqtt\queue.h" />
<ClInclude Include="mqtt\include\ringbuf.h" /> <ClInclude Include="mqtt\ringbuf.h" />
<ClInclude Include="mqtt\include\typedef.h" /> <ClInclude Include="mqtt\utils.h" />
<ClInclude Include="mqtt\include\utils.h" />
<ClInclude Include="serial\console.h" /> <ClInclude Include="serial\console.h" />
<ClInclude Include="serial\crc16.h" /> <ClInclude Include="serial\crc16.h" />
<ClInclude Include="serial\serbridge.h" /> <ClInclude Include="serial\serbridge.h" />
<ClInclude Include="serial\serled.h" /> <ClInclude Include="serial\serled.h" />
<ClInclude Include="serial\uart.h" /> <ClInclude Include="serial\uart.h" />
<ClInclude Include="esp-link\cgi.h" />
<ClInclude Include="esp-link\cgiflash.h" />
<ClInclude Include="esp-link\cgipins.h" />
<ClInclude Include="esp-link\cgitcp.h" />
<ClInclude Include="esp-link\cgiwifi.h" />
<ClInclude Include="esp-link\config.h" />
<ClInclude Include="esp-link\log.h" />
<ClInclude Include="esp-link\status.h" />
<ClInclude Include="user\cgi.h" /> <ClInclude Include="user\cgi.h" />
<ClInclude Include="user\cgiflash.h" /> <ClInclude Include="user\cgiflash.h" />
<ClInclude Include="user\cgipins.h" /> <ClInclude Include="user\cgipins.h" />

@ -1,5 +1,5 @@
// Combined include file for esp8266 // Combined include file for esp8266
#include <user_config.h>
#include <ctype.h> #include <ctype.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -17,6 +17,8 @@
#include "espmissingincludes.h" #include "espmissingincludes.h"
#include "uart_hw.h" #include "uart_hw.h"
//void init(void);
#ifdef __WIN32__ #ifdef __WIN32__
#include <_mingw.h> #include <_mingw.h>
#endif #endif

@ -1,31 +0,0 @@
/*
* File: proto.h
* Author: ThuHien
*
* Created on November 23, 2012, 8:57 AM
*/
#ifndef _PROTO_H_
#define _PROTO_H_
#include <esp8266.h>
#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

@ -1,18 +0,0 @@
#ifndef _RING_BUF_H_
#define _RING_BUF_H_
#include <esp8266.h>
#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

@ -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

@ -1,9 +0,0 @@
#ifndef _UTILS_H_
#define _UTILS_H_
#include <esp8266.h>
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

@ -39,22 +39,20 @@
#define QUEUE_BUFFER_SIZE 2048 #define QUEUE_BUFFER_SIZE 2048
#endif #endif
unsigned char *default_certificate; unsigned char* default_certificate;
unsigned int default_certificate_len = 0; unsigned int default_certificate_len = 0;
unsigned char *default_private_key; unsigned char* default_private_key;
unsigned int default_private_key_len = 0; unsigned int default_private_key_len = 0;
os_event_t mqtt_procTaskQueue[MQTT_TASK_QUEUE_SIZE]; os_event_t mqtt_procTaskQueue[MQTT_TASK_QUEUE_SIZE];
LOCAL void ICACHE_FLASH_ATTR LOCAL void ICACHE_FLASH_ATTR
mqtt_dns_found(const char *name, ip_addr_t *ipaddr, void *arg) mqtt_dns_found(const char* name, ip_addr_t* ipaddr, void* arg) {
{ struct espconn* pConn = (struct espconn *)arg;
struct espconn *pConn = (struct espconn *)arg;
MQTT_Client* client = (MQTT_Client *)pConn->reverse; 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"); os_printf("DNS: Found, but got no ip, try to reconnect\n");
client->connState = TCP_RECONNECT_REQ; client->connState = TCP_RECONNECT_REQ;
return; return;
@ -66,8 +64,7 @@ mqtt_dns_found(const char *name, ip_addr_t *ipaddr, void *arg)
*((uint8 *)&ipaddr->addr + 2), *((uint8 *)&ipaddr->addr + 2),
*((uint8 *)&ipaddr->addr + 3)); *((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); os_memcpy(client->pCon->proto.tcp->remote_ip, &ipaddr->addr, 4);
#ifdef CLIENT_SSL_ENABLE #ifdef CLIENT_SSL_ENABLE
if (client->security){ if (client->security){
@ -85,10 +82,8 @@ mqtt_dns_found(const char *name, ip_addr_t *ipaddr, void *arg)
} }
LOCAL void ICACHE_FLASH_ATTR 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; mqtt_event_data_t event_data;
event_data.topic_length = length; event_data.topic_length = length;
@ -99,8 +94,10 @@ deliver_publish(MQTT_Client* client, uint8_t* message, int length)
if (client->dataCb) if (client->dataCb)
client->dataCb((uint32_t*)client, event_data.topic, event_data.topic_length, event_data.data, event_data.data_length); 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. * @brief Client received callback function.
@ -110,26 +107,25 @@ deliver_publish(MQTT_Client* client, uint8_t* message, int length)
* @retval None * @retval None
*/ */
void ICACHE_FLASH_ATTR 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_type;
uint8_t msg_qos; uint8_t msg_qos;
uint16_t msg_id; uint16_t msg_id;
struct espconn *pCon = (struct espconn*)arg; struct espconn* pCon = (struct espconn*)arg;
MQTT_Client *client = (MQTT_Client *)pCon->reverse; MQTT_Client* client = (MQTT_Client *)pCon->reverse;
READPACKET: READPACKET:
os_printf("MQTT-TCP: Data received %d bytes\n", len); 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); os_memcpy(client->mqtt_state.in_buffer, pdata, len);
msg_type = mqtt_get_type(client->mqtt_state.in_buffer); msg_type = mqtt_get_type(client->mqtt_state.in_buffer);
msg_qos = mqtt_get_qos(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); msg_id = mqtt_get_id(client->mqtt_state.in_buffer, client->mqtt_state.in_buffer_length);
if (client->connState == MQTT_CONNECT_SENDING) { if (client->connState == MQTT_CONNECT_SENDING) {
if (msg_type == MQTT_MSG_TYPE_CONNACK){ if (msg_type == MQTT_MSG_TYPE_CONNACK) {
if (client->mqtt_state.pending_msg_type != MQTT_MSG_TYPE_CONNECT){ if (client->mqtt_state.pending_msg_type != MQTT_MSG_TYPE_CONNECT) {
os_printf("MQTT: Invalid packet\n"); os_printf("MQTT: Invalid packet\n");
#ifdef CLIENT_SSL_ENABLE #ifdef CLIENT_SSL_ENABLE
if (client->security){ if (client->security){
@ -144,6 +140,8 @@ READPACKET:
client->connState = MQTT_DATA; client->connState = MQTT_DATA;
if (client->connectedCb) if (client->connectedCb)
client->connectedCb((uint32_t*)client); client->connectedCb((uint32_t*)client);
if (client->cmdConnectedCb)
client->cmdConnectedCb((uint32_t*)client);
} }
} }
} }
@ -156,7 +154,7 @@ READPACKET:
if (client->mqtt_state.pending_msg_type == MQTT_MSG_TYPE_SUBSCRIBE && client->mqtt_state.pending_msg_id == msg_id) 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) 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");
} }
@ -165,39 +163,39 @@ READPACKET:
client->mqtt_state.outbound_message = mqtt_msg_puback(&client->mqtt_state.mqtt_connection, msg_id); client->mqtt_state.outbound_message = mqtt_msg_puback(&client->mqtt_state.mqtt_connection, msg_id);
else if (msg_qos == 2) else if (msg_qos == 2)
client->mqtt_state.outbound_message = mqtt_msg_pubrec(&client->mqtt_state.mqtt_connection, msg_id); 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); 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"); os_printf("MQTT: Queue full\n");
} }
} }
deliver_publish(client, client->mqtt_state.in_buffer, client->mqtt_state.message_length_read); deliver_publish(client, client->mqtt_state.in_buffer, client->mqtt_state.message_length_read);
} }
else if (msg_type == MQTT_MSG_TYPE_PUBACK) { 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"); os_printf("MQTT: received MQTT_MSG_TYPE_PUBACK, finish QoS1 publish\n");
} }
} }
else if (msg_type == MQTT_MSG_TYPE_PUBREC) { else if (msg_type == MQTT_MSG_TYPE_PUBREC) {
client->mqtt_state.outbound_message = mqtt_msg_pubrel(&client->mqtt_state.mqtt_connection, msg_id); 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"); os_printf("MQTT: Queue full\n");
} }
} }
else if (msg_type == MQTT_MSG_TYPE_PUBREL) { else if (msg_type == MQTT_MSG_TYPE_PUBREL) {
client->mqtt_state.outbound_message = mqtt_msg_pubcomp(&client->mqtt_state.mqtt_connection, msg_id); 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"); os_printf("MQTT: Queue full\n");
} }
} }
else if (msg_type == MQTT_MSG_TYPE_PUBCOMP) { 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"); os_printf("MQTT: receive MQTT_MSG_TYPE_PUBCOMP, finish QoS2 publish\n");
} }
} }
else if (msg_type == MQTT_MSG_TYPE_PINGREQ) { else if (msg_type == MQTT_MSG_TYPE_PINGREQ) {
client->mqtt_state.outbound_message = mqtt_msg_pingresp(&client->mqtt_state.mqtt_connection); 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"); os_printf("MQTT: Queue full\n");
} }
} }
@ -205,12 +203,10 @@ READPACKET:
// NOTE: this is done down here and not in the switch case above // NOTE: this is done down here and not in the switch case above
// because the PSOCK_READBUF_LEN() won't work inside a switch // because the PSOCK_READBUF_LEN() won't work inside a switch
// statement due to the way protothreads resume. // 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; 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; //client->connState = MQTT_PUBLISH_RECV;
//Not Implement yet //Not Implement yet
len -= client->mqtt_state.message_length; len -= client->mqtt_state.message_length;
@ -234,26 +230,27 @@ READPACKET:
* @retval None * @retval None
*/ */
void ICACHE_FLASH_ATTR void ICACHE_FLASH_ATTR
mqtt_tcpclient_sent_cb(void *arg) mqtt_tcpclient_sent_cb(void* arg) {
{ struct espconn* pCon = (struct espconn *)arg;
struct espconn *pCon = (struct espconn *)arg;
MQTT_Client* client = (MQTT_Client *)pCon->reverse; MQTT_Client* client = (MQTT_Client *)pCon->reverse;
os_printf("MQTT-TCP: Sent\n"); os_printf("MQTT-TCP: Sent\n");
client->sendTimeout = 0; 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) if (client->publishedCb)
client->publishedCb((uint32_t*)client); client->publishedCb((uint32_t*)client);
if (client->cmdPublishedCb)
client->cmdPublishedCb((uint32_t*)client);
} }
system_os_post(MQTT_TASK_PRIO, 0, (os_param_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; MQTT_Client* client = (MQTT_Client*)arg;
if (client->connState == MQTT_DATA){ if (client->connState == MQTT_DATA) {
client->keepAliveTick++; 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); 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); client->mqtt_state.outbound_message = mqtt_msg_pingreq(&client->mqtt_state.mqtt_connection);
@ -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++; client->reconnectTick++;
if (client->reconnectTick > MQTT_RECONNECT_TIMEOUT) { if (client->reconnectTick > MQTT_RECONNECT_TIMEOUT) {
client->reconnectTick = 0; client->reconnectTick = 0;
client->connState = TCP_RECONNECT; 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); 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 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; MQTT_Client* client = (MQTT_Client *)pespconn->reverse;
os_printf("MQTT-TCP: Disconnected callback\n"); os_printf("MQTT-TCP: Disconnected callback\n");
client->connState = TCP_RECONNECT_REQ; client->connState = TCP_RECONNECT_REQ;
if (client->disconnectedCb) if (client->disconnectedCb)
client->disconnectedCb((uint32_t*)client); client->disconnectedCb((uint32_t*)client);
if (client->cmdDisconnectedCb)
client->cmdDisconnectedCb((uint32_t*)client);
system_os_post(MQTT_TASK_PRIO, 0, (os_param_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 * @retval None
*/ */
void ICACHE_FLASH_ATTR void ICACHE_FLASH_ATTR
mqtt_tcpclient_connect_cb(void *arg) mqtt_tcpclient_connect_cb(void* arg) {
{ struct espconn* pCon = (struct espconn *)arg;
struct espconn *pCon = (struct espconn *)arg;
MQTT_Client* client = (MQTT_Client *)pCon->reverse; MQTT_Client* client = (MQTT_Client *)pCon->reverse;
espconn_regist_disconcb(client->pCon, mqtt_tcpclient_discon_cb); espconn_regist_disconcb(client->pCon, mqtt_tcpclient_discon_cb);
@ -348,9 +349,8 @@ mqtt_tcpclient_connect_cb(void *arg)
* @retval None * @retval None
*/ */
void ICACHE_FLASH_ATTR void ICACHE_FLASH_ATTR
mqtt_tcpclient_recon_cb(void *arg, sint8 errType) mqtt_tcpclient_recon_cb(void* arg, int8_t errType) {
{ struct espconn* pCon = (struct espconn *)arg;
struct espconn *pCon = (struct espconn *)arg;
MQTT_Client* client = (MQTT_Client *)pCon->reverse; MQTT_Client* client = (MQTT_Client *)pCon->reverse;
os_printf("MQTT-TCP: Reconnect to %s:%ld\n", client->host, client->port); os_printf("MQTT-TCP: Reconnect to %s:%ld\n", client->host, client->port);
@ -371,8 +371,7 @@ mqtt_tcpclient_recon_cb(void *arg, sint8 errType)
* @retval TRUE if success queue * @retval TRUE if success queue
*/ */
bool ICACHE_FLASH_ATTR 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); int data_length = os_strlen(data);
uint8_t dataBuffer[MQTT_BUF_SIZE]; uint8_t dataBuffer[MQTT_BUF_SIZE];
uint16_t dataLen; uint16_t dataLen;
@ -380,12 +379,12 @@ MQTT_Publish(MQTT_Client *client, const char* topic, const char* data, int qos,
topic, data, data_length, topic, data, data_length,
qos, retain, qos, retain,
&client->mqtt_state.pending_msg_id); &client->mqtt_state.pending_msg_id);
if (client->mqtt_state.outbound_message->length == 0){ if (client->mqtt_state.outbound_message->length == 0) {
os_printf("MQTT: Queuing Publish failed\n"); os_printf("MQTT: Queuing Publish failed\n");
return FALSE; 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); 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"); os_printf("MQTT: Queue full\n");
if (QUEUE_Gets(&client->msgQueue, dataBuffer, &dataLen, MQTT_BUF_SIZE) == -1) { if (QUEUE_Gets(&client->msgQueue, dataBuffer, &dataLen, MQTT_BUF_SIZE) == -1) {
os_printf("MQTT: Serious buffer error\n"); os_printf("MQTT: Serious buffer error\n");
@ -404,8 +403,7 @@ MQTT_Publish(MQTT_Client *client, const char* topic, const char* data, int qos,
* @retval TRUE if success queue * @retval TRUE if success queue
*/ */
bool ICACHE_FLASH_ATTR 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]; uint8_t dataBuffer[MQTT_BUF_SIZE];
uint16_t dataLen; uint16_t dataLen;
@ -413,7 +411,7 @@ MQTT_Subscribe(MQTT_Client *client, char* topic, uint8_t qos)
topic, 0, topic, 0,
&client->mqtt_state.pending_msg_id); &client->mqtt_state.pending_msg_id);
os_printf("MQTT: Queue Subscribe, topic: \"%s\", id: %d\n", topic, 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"); os_printf("MQTT: Queue full\n");
if (QUEUE_Gets(&client->msgQueue, dataBuffer, &dataLen, MQTT_BUF_SIZE) == -1) { if (QUEUE_Gets(&client->msgQueue, dataBuffer, &dataLen, MQTT_BUF_SIZE) == -1) {
os_printf("MQTT: Serious buffer error\n"); os_printf("MQTT: Serious buffer error\n");
@ -424,7 +422,8 @@ MQTT_Subscribe(MQTT_Client *client, char* topic, uint8_t qos)
return TRUE; 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; MQTT_Client* client = (MQTT_Client*)e->par;
uint8_t dataBuffer[MQTT_BUF_SIZE]; uint8_t dataBuffer[MQTT_BUF_SIZE];
uint16_t dataLen; uint16_t dataLen;
@ -434,7 +433,7 @@ void ICACHE_FLASH_ATTR MQTT_Task(os_event_t *e) {
if (client->connState == TCP_RECONNECT_REQ) { if (client->connState == TCP_RECONNECT_REQ) {
return; return;
} }
else if (client->connState == TCP_RECONNECT){ else if (client->connState == TCP_RECONNECT) {
MQTT_Connect(client); MQTT_Connect(client);
os_printf("MQTT-TCP: Reconnect to: %s:%ld\n", client->host, client->port); os_printf("MQTT-TCP: Reconnect to: %s:%ld\n", client->host, client->port);
client->connState = TCP_CONNECTING; 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) if (QUEUE_IsEmpty(&client->msgQueue) || client->sendTimeout != 0)
return; 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_type = mqtt_get_type(dataBuffer);
client->mqtt_state.pending_msg_id = mqtt_get_id(dataBuffer, dataLen); client->mqtt_state.pending_msg_id = mqtt_get_id(dataBuffer, dataLen);
client->sendTimeout = MQTT_SEND_TIMOUT; client->sendTimeout = MQTT_SEND_TIMOUT;
@ -472,8 +471,7 @@ void ICACHE_FLASH_ATTR MQTT_Task(os_event_t *e) {
* @retval None * @retval None
*/ */
void ICACHE_FLASH_ATTR 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; uint32_t temp;
os_printf("MQTT_InitConnection\n"); os_printf("MQTT_InitConnection\n");
os_memset(mqttClient, 0, sizeof(MQTT_Client)); 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 * @retval None
*/ */
void ICACHE_FLASH_ATTR 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; uint32_t temp;
os_printf("MQTT_InitClient\n"); 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 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; uint32_t temp;
temp = os_strlen((char*)will_topic); temp = os_strlen((char*)will_topic);
mqttClient->connect_info.will_topic = (char*)os_zalloc(temp + 1); 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 * @retval None
*/ */
void ICACHE_FLASH_ATTR void ICACHE_FLASH_ATTR
MQTT_Connect(MQTT_Client *mqttClient) MQTT_Connect(MQTT_Client* mqttClient) {
{
MQTT_Disconnect(mqttClient); MQTT_Disconnect(mqttClient);
mqttClient->pCon = (struct espconn *)os_zalloc(sizeof(struct espconn)); mqttClient->pCon = (struct espconn *)os_zalloc(sizeof(struct espconn));
mqttClient->pCon->type = ESPCONN_TCP; mqttClient->pCon->type = ESPCONN_TCP;
@ -599,9 +594,8 @@ MQTT_Connect(MQTT_Client *mqttClient)
} }
void ICACHE_FLASH_ATTR void ICACHE_FLASH_ATTR
MQTT_Disconnect(MQTT_Client *mqttClient) MQTT_Disconnect(MQTT_Client* mqttClient) {
{ if (mqttClient->pCon) {
if (mqttClient->pCon){
os_printf("Free memory\n"); os_printf("Free memory\n");
if (mqttClient->pCon->proto.tcp) if (mqttClient->pCon->proto.tcp)
os_free(mqttClient->pCon->proto.tcp); os_free(mqttClient->pCon->proto.tcp);
@ -613,25 +607,27 @@ MQTT_Disconnect(MQTT_Client *mqttClient)
} }
void ICACHE_FLASH_ATTR void ICACHE_FLASH_ATTR
MQTT_OnConnected(MQTT_Client *mqttClient, MqttCallback connectedCb) MQTT_OnConnected(MQTT_Client* mqttClient, MqttCallback connectedCb) {
{
mqttClient->connectedCb = connectedCb; mqttClient->connectedCb = connectedCb;
} }
void ICACHE_FLASH_ATTR void ICACHE_FLASH_ATTR
MQTT_OnDisconnected(MQTT_Client *mqttClient, MqttCallback disconnectedCb) MQTT_OnDisconnected(MQTT_Client* mqttClient, MqttCallback disconnectedCb) {
{
mqttClient->disconnectedCb = disconnectedCb; mqttClient->disconnectedCb = disconnectedCb;
} }
void ICACHE_FLASH_ATTR 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; mqttClient->dataCb = dataCb;
} }
void ICACHE_FLASH_ATTR void ICACHE_FLASH_ATTR
MQTT_OnPublished(MQTT_Client *mqttClient, MqttCallback publishedCb) MQTT_OnPublished(MQTT_Client* mqttClient, MqttCallback publishedCb) {
{
mqttClient->publishedCb = publishedCb; mqttClient->publishedCb = publishedCb;
} }

@ -35,8 +35,7 @@
#include "queue.h" #include "queue.h"
#include "utils.h" #include "utils.h"
typedef struct mqtt_event_data_t typedef struct mqtt_event_data_t {
{
uint8_t type; uint8_t type;
const char* topic; const char* topic;
const char* data; const char* data;
@ -45,8 +44,7 @@ typedef struct mqtt_event_data_t
uint16_t data_offset; uint16_t data_offset;
} mqtt_event_data_t; } mqtt_event_data_t;
typedef struct mqtt_state_t typedef struct mqtt_state_t {
{
uint16_t port; uint16_t port;
int auto_reconnect; int auto_reconnect;
mqtt_connect_info_t* connect_info; mqtt_connect_info_t* connect_info;
@ -84,21 +82,27 @@ typedef enum {
MQTT_PUBLISHING MQTT_PUBLISHING
} tConnState; } tConnState;
typedef void (*MqttCallback)(uint32_t *args); 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 (*MqttDataCallback)(uint32_t* args, const char* topic, uint32_t topic_len, const char* data, uint32_t lengh);
typedef struct { typedef struct {
struct espconn *pCon; struct espconn* pCon;
uint8_t security; uint32_t security;
uint8_t* host; uint8_t* host;
uint32_t port; uint32_t port;
ip_addr_t ip; ip_addr_t ip;
mqtt_state_t mqtt_state; mqtt_state_t mqtt_state;
mqtt_connect_info_t connect_info; mqtt_connect_info_t connect_info;
MqttCallback connectedCb; MqttCallback connectedCb;
MqttCallback cmdConnectedCb;
MqttCallback disconnectedCb; MqttCallback disconnectedCb;
MqttCallback cmdDisconnectedCb;
MqttCallback tcpDisconnectedCb;
MqttCallback cmdTcpDisconnectedCb;
MqttCallback publishedCb; MqttCallback publishedCb;
MqttCallback cmdPublishedCb;
MqttDataCallback dataCb; MqttDataCallback dataCb;
MqttDataCallback cmdDataCb;
ETSTimer mqttTimer; ETSTimer mqttTimer;
uint32_t keepAliveTick; uint32_t keepAliveTick;
uint32_t reconnectTick; uint32_t reconnectTick;
@ -125,16 +129,16 @@ typedef struct {
#define MQTT_EVENT_TYPE_EXITED 7 #define MQTT_EVENT_TYPE_EXITED 7
#define MQTT_EVENT_TYPE_PUBLISH_CONTINUATION 8 #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_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_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_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_OnConnected(MQTT_Client* mqttClient, MqttCallback connectedCb);
void ICACHE_FLASH_ATTR MQTT_OnDisconnected(MQTT_Client *mqttClient, MqttCallback disconnectedCb); 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_OnPublished(MQTT_Client* mqttClient, MqttCallback publishedCb);
void ICACHE_FLASH_ATTR MQTT_OnData(MQTT_Client *mqttClient, MqttDataCallback dataCb); 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); 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_Connect(MQTT_Client* mqttClient);
void ICACHE_FLASH_ATTR MQTT_Disconnect(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); 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_ */ #endif /* USER_AT_MQTT_H_ */

@ -32,8 +32,7 @@
#include "mqtt_msg.h" #include "mqtt_msg.h"
#define MQTT_MAX_FIXED_HEADER_SIZE 3 #define MQTT_MAX_FIXED_HEADER_SIZE 3
enum mqtt_connect_flag enum mqtt_connect_flag {
{
MQTT_CONNECT_FLAG_USERNAME = 1 << 7, MQTT_CONNECT_FLAG_USERNAME = 1 << 7,
MQTT_CONNECT_FLAG_PASSWORD = 1 << 6, MQTT_CONNECT_FLAG_PASSWORD = 1 << 6,
MQTT_CONNECT_FLAG_WILL_RETAIN = 1 << 5, MQTT_CONNECT_FLAG_WILL_RETAIN = 1 << 5,
@ -41,8 +40,8 @@ enum mqtt_connect_flag
MQTT_CONNECT_FLAG_CLEAN_SESSION = 1 << 1 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 lengthMsb;
uint8_t lengthLsb; uint8_t lengthLsb;
#if defined(PROTOCOL_NAMEv31) #if defined(PROTOCOL_NAMEv31)
@ -58,8 +57,8 @@ struct __attribute__((__packed__)) mqtt_connect_variable_header
uint8_t keepaliveLsb; 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) if (connection->message.length + len + 2 > connection->buffer_length)
return -1; return -1;
@ -71,8 +70,8 @@ static int ICACHE_FLASH_ATTR append_string(mqtt_connection_t* connection, const
return len + 2; 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 // If message_id is zero then we should assign one, otherwise
// we'll use the one supplied by the caller // we'll use the one supplied by the caller
while (message_id == 0) while (message_id == 0)
@ -87,33 +86,31 @@ static uint16_t ICACHE_FLASH_ATTR append_message_id(mqtt_connection_t* connectio
return message_id; 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; connection->message.length = MQTT_MAX_FIXED_HEADER_SIZE;
return 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.data = connection->buffer;
connection->message.length = 0; connection->message.length = 0;
return &connection->message; 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; 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[0] = ((type & 0x0f) << 4) | ((dup & 1) << 3) | ((qos & 3) << 1) | (retain & 1);
connection->buffer[1] = 0x80 | (remaining_length % 128); connection->buffer[1] = 0x80 | (remaining_length % 128);
connection->buffer[2] = remaining_length / 128; connection->buffer[2] = remaining_length / 128;
connection->message.length = remaining_length + 3; connection->message.length = remaining_length + 3;
connection->message.data = connection->buffer; connection->message.data = connection->buffer;
} }
else else {
{
connection->buffer[1] = ((type & 0x0f) << 4) | ((dup & 1) << 3) | ((qos & 3) << 1) | (retain & 1); connection->buffer[1] = ((type & 0x0f) << 4) | ((dup & 1) << 3) | ((qos & 3) << 1) | (retain & 1);
connection->buffer[2] = remaining_length; connection->buffer[2] = remaining_length;
connection->message.length = remaining_length + 2; 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; 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 i;
int totlen = 0; int totlen = 0;
for (i = 1; i < length; ++i) for (i = 1; i < length; ++i) {
{
totlen += (buffer[i] & 0x7f) << (7 * (i - 1)); totlen += (buffer[i] & 0x7f) << (7 * (i - 1));
if ((buffer[i] & 0x80) == 0) if ((buffer[i] & 0x80) == 0) {
{
++i; ++i;
break; break;
} }
@ -150,17 +145,15 @@ int ICACHE_FLASH_ATTR mqtt_get_total_length(uint8_t* buffer, uint16_t length)
return totlen; 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 i;
int totlen = 0; int totlen = 0;
int topiclen; int topiclen;
for (i = 1; i < *length; ++i) for (i = 1; i < *length; ++i) {
{
totlen += (buffer[i] & 0x7f) << (7 * (i - 1)); totlen += (buffer[i] & 0x7f) << (7 * (i - 1));
if ((buffer[i] & 0x80) == 0) if ((buffer[i] & 0x80) == 0) {
{
++i; ++i;
break; break;
} }
@ -179,17 +172,15 @@ const char* ICACHE_FLASH_ATTR mqtt_get_publish_topic(uint8_t* buffer, uint16_t*
return (const char*)(buffer + i); 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 i;
int totlen = 0; int totlen = 0;
int topiclen; int topiclen;
for (i = 1; i < *length; ++i) for (i = 1; i < *length; ++i) {
{
totlen += (buffer[i] & 0x7f) << (7 * (i - 1)); totlen += (buffer[i] & 0x7f) << (7 * (i - 1));
if ((buffer[i] & 0x80) == 0) if ((buffer[i] & 0x80) == 0) {
{
++i; ++i;
break; 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++] << 8;
topiclen |= buffer[i++]; topiclen |= buffer[i++];
if (i + topiclen >= *length){ if (i + topiclen >= *length) {
*length = 0; *length = 0;
return NULL; return NULL;
} }
i += topiclen; i += topiclen;
if (mqtt_get_qos(buffer) > 0) if (mqtt_get_qos(buffer) > 0) {
{
if (i + 2 >= *length) if (i + 2 >= *length)
return NULL; return NULL;
i += 2; i += 2;
@ -224,22 +214,18 @@ const char* ICACHE_FLASH_ATTR mqtt_get_publish_data(uint8_t* buffer, uint16_t* l
return (const char*)(buffer + i); 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) if (length < 1)
return 0; return 0;
switch (mqtt_get_type(buffer)) switch (mqtt_get_type(buffer)) {
{ case MQTT_MSG_TYPE_PUBLISH: {
case MQTT_MSG_TYPE_PUBLISH:
{
int i; int i;
int topiclen; int topiclen;
for (i = 1; i < length; ++i) for (i = 1; i < length; ++i) {
{ if ((buffer[i] & 0x80) == 0) {
if ((buffer[i] & 0x80) == 0)
{
++i; ++i;
break; break;
} }
@ -254,8 +240,7 @@ uint16_t ICACHE_FLASH_ATTR mqtt_get_id(uint8_t* buffer, uint16_t length)
return 0; return 0;
i += topiclen; i += topiclen;
if (mqtt_get_qos(buffer) > 0) if (mqtt_get_qos(buffer) > 0) {
{
if (i + 2 >= length) if (i + 2 >= length)
return 0; return 0;
//i += 2; //i += 2;
@ -272,8 +257,7 @@ uint16_t ICACHE_FLASH_ATTR mqtt_get_id(uint8_t* buffer, uint16_t length)
case MQTT_MSG_TYPE_PUBCOMP: case MQTT_MSG_TYPE_PUBCOMP:
case MQTT_MSG_TYPE_SUBACK: case MQTT_MSG_TYPE_SUBACK:
case MQTT_MSG_TYPE_UNSUBACK: case MQTT_MSG_TYPE_UNSUBACK:
case MQTT_MSG_TYPE_SUBSCRIBE: case MQTT_MSG_TYPE_SUBSCRIBE: {
{
// This requires the remaining length to be encoded in 1 byte, // This requires the remaining length to be encoded in 1 byte,
// which it should be. // which it should be.
if (length >= 4 && (buffer[1] & 0x80) == 0) if (length >= 4 && (buffer[1] & 0x80) == 0)
@ -287,8 +271,8 @@ uint16_t ICACHE_FLASH_ATTR mqtt_get_id(uint8_t* buffer, uint16_t length)
} }
} }
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; struct mqtt_connect_variable_header* variable_header;
init_message(connection); init_message(connection);
@ -318,16 +302,14 @@ mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_connect(mqtt_connection_t* connection
if (info->clean_session) if (info->clean_session)
variable_header->flags |= MQTT_CONNECT_FLAG_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) if (append_string(connection, info->client_id, strlen(info->client_id)) < 0)
return fail_message(connection); return fail_message(connection);
} }
else else
return fail_message(connection); 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) if (append_string(connection, info->will_topic, strlen(info->will_topic)) < 0)
return fail_message(connection); 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; 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) if (append_string(connection, info->username, strlen(info->username)) < 0)
return fail_message(connection); return fail_message(connection);
variable_header->flags |= MQTT_CONNECT_FLAG_USERNAME; 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) if (append_string(connection, info->password, strlen(info->password)) < 0)
return fail_message(connection); 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); 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); init_message(connection);
if (topic == NULL || topic[0] == '\0') 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) if (append_string(connection, topic, strlen(topic)) < 0)
return fail_message(connection); return fail_message(connection);
if (qos > 0) if (qos > 0) {
{
if ((*message_id = append_message_id(connection, 0)) == 0) if ((*message_id = append_message_id(connection, 0)) == 0)
return fail_message(connection); 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); 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); init_message(connection);
if (append_message_id(connection, message_id) == 0) if (append_message_id(connection, message_id) == 0)
return fail_message(connection); return fail_message(connection);
return fini_message(connection, MQTT_MSG_TYPE_PUBACK, 0, 0, 0); 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); init_message(connection);
if (append_message_id(connection, message_id) == 0) if (append_message_id(connection, message_id) == 0)
return fail_message(connection); return fail_message(connection);
return fini_message(connection, MQTT_MSG_TYPE_PUBREC, 0, 0, 0); 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); init_message(connection);
if (append_message_id(connection, message_id) == 0) if (append_message_id(connection, message_id) == 0)
return fail_message(connection); return fail_message(connection);
return fini_message(connection, MQTT_MSG_TYPE_PUBREL, 0, 1, 0); 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); init_message(connection);
if (append_message_id(connection, message_id) == 0) if (append_message_id(connection, message_id) == 0)
return fail_message(connection); return fail_message(connection);
return fini_message(connection, MQTT_MSG_TYPE_PUBCOMP, 0, 0, 0); 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); init_message(connection);
if (topic == NULL || topic[0] == '\0') 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); 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); init_message(connection);
if (topic == NULL || topic[0] == '\0') 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); 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); init_message(connection);
return fini_message(connection, MQTT_MSG_TYPE_PINGREQ, 0, 0, 0); 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); init_message(connection);
return fini_message(connection, MQTT_MSG_TYPE_PINGRESP, 0, 0, 0); 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); init_message(connection);
return fini_message(connection, MQTT_MSG_TYPE_DISCONNECT, 0, 0, 0); return fini_message(connection, MQTT_MSG_TYPE_DISCONNECT, 0, 0, 0);
} }

@ -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 <esp8266.h>
#ifdef __cplusplus
extern "C" {
#endif
/* /*
* Copyright (c) 2014, Stephen Robinson * Copyright (c) 2014, Stephen Robinson
* All rights reserved. * All rights reserved.
@ -43,12 +28,12 @@ extern "C" {
* POSSIBILITY OF SUCH DAMAGE. * 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 <esp8266.h>
enum mqtt_message_type enum mqtt_message_type {
{
MQTT_MSG_TYPE_CONNECT = 1, MQTT_MSG_TYPE_CONNECT = 1,
MQTT_MSG_TYPE_CONNACK = 2, MQTT_MSG_TYPE_CONNACK = 2,
MQTT_MSG_TYPE_PUBLISH = 3, MQTT_MSG_TYPE_PUBLISH = 3,
@ -65,15 +50,13 @@ enum mqtt_message_type
MQTT_MSG_TYPE_DISCONNECT = 14 MQTT_MSG_TYPE_DISCONNECT = 14
}; };
typedef struct mqtt_message typedef struct mqtt_message {
{
uint8_t* data; uint8_t* data;
uint16_t length; uint16_t length;
} mqtt_message_t; } mqtt_message_t;
typedef struct mqtt_connection typedef struct mqtt_connection {
{
mqtt_message_t message; mqtt_message_t message;
uint16_t message_id; uint16_t message_id;
@ -82,25 +65,35 @@ typedef struct mqtt_connection
} mqtt_connection_t; } mqtt_connection_t;
typedef struct mqtt_connect_info typedef struct mqtt_connect_info {
{
char* client_id; char* client_id;
char* username; char* username;
char* password; char* password;
char* will_topic; char* will_topic;
char* will_message; char* will_message;
int keepalive; uint32_t keepalive;
int will_qos; uint32_t will_qos;
int will_retain; uint32_t will_retain;
int clean_session; uint32_t clean_session;
} mqtt_connect_info_t; } 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_type(uint8_t* buffer) {
static inline int ICACHE_FLASH_ATTR mqtt_get_dup(uint8_t* buffer) { return (buffer[0] & 0x08) >> 3; } return (buffer[0] & 0xf0) >> 4;
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_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); 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); 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_pingresp(mqtt_connection_t* connection);
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);
#endif // MQTT_MSG_H
#ifdef __cplusplus
}
#endif
#endif /* MQTT_MSG_H */

@ -1,7 +1,7 @@
#include "proto.h" #include "proto.h"
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_Init(PROTO_PARSER* parser, PROTO_PARSE_CALLBACK* completeCallback, uint8_t* buf, uint16_t bufSize) {
parser->buf = buf; parser->buf = buf;
parser->bufSize = bufSize; parser->bufSize = bufSize;
parser->dataLen = 0; parser->dataLen = 0;
@ -10,9 +10,9 @@ int8_t ICACHE_FLASH_ATTR PROTO_Init(PROTO_PARSER *parser, PROTO_PARSE_CALLBACK *
return 0; return 0;
} }
int8_t ICACHE_FLASH_ATTR PROTO_ParseByte(PROTO_PARSER *parser, uint8_t value) int8_t ICACHE_FLASH_ATTR
{ PROTO_ParseByte(PROTO_PARSER* parser, uint8_t value) {
switch(value){ switch (value) {
case 0x7D: case 0x7D:
parser->isEsc = 1; parser->isEsc = 1;
break; break;
@ -31,14 +31,14 @@ int8_t ICACHE_FLASH_ATTR PROTO_ParseByte(PROTO_PARSER *parser, uint8_t value)
break; break;
default: default:
if(parser->isBegin == 0) break; if (parser->isBegin == 0) break;
if(parser->isEsc){ if (parser->isEsc) {
value ^= 0x20; value ^= 0x20;
parser->isEsc = 0; parser->isEsc = 0;
} }
if(parser->dataLen < parser->bufSize) if (parser->dataLen < parser->bufSize)
parser->buf[parser->dataLen++] = value; parser->buf[parser->dataLen++] = value;
break; break;
@ -46,83 +46,41 @@ int8_t ICACHE_FLASH_ATTR PROTO_ParseByte(PROTO_PARSER *parser, uint8_t value)
return -1; return -1;
} }
int8_t ICACHE_FLASH_ATTR PROTO_Parse(PROTO_PARSER *parser, uint8_t *buf, uint16_t len) int16_t ICACHE_FLASH_ATTR
{ PROTO_ParseRb(RINGBUF* rb, uint8_t* bufOut, uint16_t* len, uint16_t maxBufLen) {
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; uint8_t c;
PROTO_PARSER proto; PROTO_PARSER proto;
PROTO_Init(&proto, NULL, bufOut, maxBufLen); PROTO_Init(&proto, NULL, bufOut, maxBufLen);
while(RINGBUF_Get(rb, &c) == 0){ while (RINGBUF_Get(rb, &c) == 0) {
if(PROTO_ParseByte(&proto, c) == 0){ if (PROTO_ParseByte(&proto, c) == 0) {
*len = proto.dataLen; *len = proto.dataLen;
return 0; return 0;
} }
} }
return -1; 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;
if (bufSize < 1) return -1; int16_t ICACHE_FLASH_ATTR
PROTO_AddRb(RINGBUF* rb, const uint8_t* packet, int16_t len) {
*buf++ = 0x7E;
bufSize--;
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 (bufSize < 1) return -1;
*buf++ = 0x7F;
return i;
}
int16_t ICACHE_FLASH_ATTR PROTO_AddRb(RINGBUF *rb, const uint8_t *packet, int16_t len)
{
uint16_t i = 2; uint16_t i = 2;
if(RINGBUF_Put(rb, 0x7E) == -1) return -1; if (RINGBUF_Put(rb, 0x7E) == -1) return -1;
while (len--) { while (len--) {
switch (*packet) { switch (*packet) {
case 0x7D: case 0x7D:
case 0x7E: case 0x7E:
case 0x7F: case 0x7F:
if(RINGBUF_Put(rb, 0x7D) == -1) return -1; if (RINGBUF_Put(rb, 0x7D) == -1) return -1;
if(RINGBUF_Put(rb, *packet++ ^ 0x20) == -1) return -1; if (RINGBUF_Put(rb, *packet++ ^ 0x20) == -1) return -1;
i += 2; i += 2;
break; break;
default: default:
if(RINGBUF_Put(rb, *packet++) == -1) return -1; if (RINGBUF_Put(rb, *packet++) == -1) return -1;
i++; i++;
break; break;
} }
} }
if(RINGBUF_Put(rb, 0x7F) == -1) return -1; if (RINGBUF_Put(rb, 0x7F) == -1) return -1;
return i; return i;
} }

@ -0,0 +1,28 @@
/*
* File: proto.h
* Author: ThuHien
*
* Created on November 23, 2012, 8:57 AM
*/
#ifndef _PROTO_H_
#define _PROTO_H_
#include <esp8266.h>
#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

@ -29,21 +29,24 @@
*/ */
#include "queue.h" #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); queue->buf = (uint8_t*)os_zalloc(bufferSize);
RINGBUF_Init(&queue->rb, queue->buf, 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); 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); 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) if (queue->rb.fill_cnt <= 0)
return TRUE; return TRUE;
return FALSE; return FALSE;

@ -33,13 +33,14 @@
#include <esp8266.h> #include <esp8266.h>
#include "proto.h" #include "proto.h"
#include "ringbuf.h" #include "ringbuf.h"
typedef struct { typedef struct {
uint8_t *buf; uint8_t* buf;
RINGBUF rb; RINGBUF rb;
} QUEUE; } QUEUE;
void ICACHE_FLASH_ATTR QUEUE_Init(QUEUE *queue, int bufferSize); 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_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); 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); bool ICACHE_FLASH_ATTR QUEUE_IsEmpty(QUEUE* queue);
#endif /* USER_QUEUE_H_ */ #endif /* USER_QUEUE_H_ */

@ -1,11 +1,5 @@
/**
* \file
* Ring Buffer library
*/
#include "ringbuf.h" #include "ringbuf.h"
/** /**
* \brief init a RINGBUF object * \brief init a RINGBUF object
* \param r pointer to a RINGBUF object * \param r pointer to a RINGBUF object
@ -13,9 +7,9 @@
* \param size size of buf * \param size size of buf
* \return 0 if successfull, otherwise failed * \return 0 if successfull, otherwise failed
*/ */
I16 ICACHE_FLASH_ATTR RINGBUF_Init(RINGBUF *r, U8* buf, I32 size) int16_t ICACHE_FLASH_ATTR
{ RINGBUF_Init(RINGBUF* r, uint8_t* buf, int32_t size) {
if(r == NULL || buf == NULL || size < 2) return -1; if (r == NULL || buf == NULL || size < 2) return -1;
r->p_o = r->p_r = r->p_w = buf; r->p_o = r->p_r = r->p_w = buf;
r->fill_cnt = 0; r->fill_cnt = 0;
@ -23,15 +17,16 @@ I16 ICACHE_FLASH_ATTR RINGBUF_Init(RINGBUF *r, U8* buf, I32 size)
return 0; return 0;
} }
/** /**
* \brief put a character into ring buffer * \brief put a character into ring buffer
* \param r pointer to a ringbuf object * \param r pointer to a ringbuf object
* \param c character to be put * \param c character to be put
* \return 0 if successfull, otherwise failed * \return 0 if successfull, otherwise failed
*/ */
I16 ICACHE_FLASH_ATTR RINGBUF_Put(RINGBUF *r, U8 c) 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 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->fill_cnt++; // increase filled slots count, this should be atomic operation
@ -39,20 +34,21 @@ I16 ICACHE_FLASH_ATTR RINGBUF_Put(RINGBUF *r, U8 c)
*r->p_w++ = c; // put character into buffer *r->p_w++ = c; // put character into buffer
if(r->p_w >= r->p_o + r->size) // rollback if write pointer go pass if (r->p_w >= r->p_o + r->size) // rollback if write pointer go pass
r->p_w = r->p_o; // the physical boundary r->p_w = r->p_o; // the physical boundary
return 0; return 0;
} }
/** /**
* \brief get a character from ring buffer * \brief get a character from ring buffer
* \param r pointer to a ringbuf object * \param r pointer to a ringbuf object
* \param c read character * \param c read character
* \return 0 if successfull, otherwise failed * \return 0 if successfull, otherwise failed
*/ */
I16 ICACHE_FLASH_ATTR RINGBUF_Get(RINGBUF *r, U8* c) 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 if (r->fill_cnt <= 0)return -1; // ring buffer is empty, this should be atomic operation
r->fill_cnt--; // decrease filled slots count r->fill_cnt--; // decrease filled slots count
@ -60,7 +56,7 @@ I16 ICACHE_FLASH_ATTR RINGBUF_Get(RINGBUF *r, U8* c)
*c = *r->p_r++; // get the character out *c = *r->p_r++; // get the character out
if(r->p_r >= r->p_o + r->size) // rollback if write pointer go pass if (r->p_r >= r->p_o + r->size) // rollback if write pointer go pass
r->p_r = r->p_o; // the physical boundary r->p_r = r->p_o; // the physical boundary
return 0; return 0;

@ -0,0 +1,17 @@
#ifndef _RING_BUF_H_
#define _RING_BUF_H_
#include <esp8266.h>
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

@ -33,8 +33,7 @@
#include "utils.h" #include "utils.h"
uint8_t ICACHE_FLASH_ATTR uint8_t ICACHE_FLASH_ATTR
UTILS_IsIPV4(int8_t *str) UTILS_IsIPV4(int8_t* str) {
{
uint8_t segs = 0; /* Segment count. */ uint8_t segs = 0; /* Segment count. */
uint8_t chcnt = 0; /* Character count within segment. */ uint8_t chcnt = 0; /* Character count within segment. */
uint8_t accum = 0; /* Accumulator for segment. */ uint8_t accum = 0; /* Accumulator for segment. */
@ -85,8 +84,7 @@ UTILS_IsIPV4(int8_t *str)
} }
uint8_t ICACHE_FLASH_ATTR 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. */ /* The count of the number of bytes processed. */
int i; int i;
@ -122,12 +120,11 @@ UTILS_StrToIP(const int8_t* str, void *ip)
} }
uint32_t ICACHE_FLASH_ATTR uint32_t ICACHE_FLASH_ATTR
UTILS_Atoh(const int8_t *s) UTILS_Atoh(const int8_t* s) {
{
uint32_t value = 0, digit; uint32_t value = 0, digit;
int8_t c; int8_t c;
while ((c = *s++)){ while ((c = *s++)) {
if ('0' <= c && c <= '9') if ('0' <= c && c <= '9')
digit = c - '0'; digit = c - '0';
else if ('A' <= c && c <= 'F') else if ('A' <= c && c <= 'F')
@ -141,4 +138,3 @@ UTILS_Atoh(const int8_t *s)
return value; return value;
} }

@ -0,0 +1,9 @@
#ifndef _UTILS_H_
#define _UTILS_H_
#include <esp8266.h>
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

@ -1,13 +1,13 @@
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42): * "THE BEER-WARE LICENSE" (Revision 42):
* Jeroen Domburg <jeroen@spritesmods.com> wrote this file. As long as you retain * Jeroen Domburg <jeroen@spritesmods.com> wrote this file. As long as you retain
* this notice you can do whatever you want with this stuff. If we meet some day, * 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. * 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 * Heavily modified and enhanced by Thorsten von Eicken in 2015
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
*/ */
#include <esp8266.h> #include <esp8266.h>
@ -35,19 +35,20 @@
//This is disabled in the default build; if you want to try it, enable the authBasic line in //This is disabled in the default build; if you want to try it, enable the authBasic line in
//the builtInUrls below. //the builtInUrls below.
int myPassFn(HttpdConnData *connData, int no, char *user, int userLen, char *pass, int passLen) { int myPassFn(HttpdConnData *connData, int no, char *user, int userLen, char *pass, int passLen) {
if (no==0) { if (no == 0) {
os_strcpy(user, "admin"); os_strcpy(user, "admin");
os_strcpy(pass, "s3cr3t"); os_strcpy(pass, "s3cr3t");
return 1; return 1;
//Add more users this way. Check against incrementing no for each user added. //Add more users this way. Check against incrementing no for each user added.
// } else if (no==1) { // } else if (no==1) {
// os_strcpy(user, "user1"); // os_strcpy(user, "user1");
// os_strcpy(pass, "something"); // os_strcpy(pass, "something");
// return 1; // return 1;
} }
return 0; return 0;
} }
/* /*
This is the main url->function dispatching data struct. This is the main url->function dispatching data struct.
In short, it's a struct with various URLs plus their handlers. The handlers can In short, it's a struct with various URLs plus their handlers. The handlers can
@ -58,42 +59,43 @@ 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 general ones. Authorization things (like authBasic) act as a 'barrier' and
should be placed above the URLs they protect. should be placed above the URLs they protect.
*/ */
HttpdBuiltInUrl builtInUrls[]={ HttpdBuiltInUrl builtInUrls[] = {
{"/", cgiRedirect, "/home.html"}, { "/", cgiRedirect, "/home.html" },
{"/menu", cgiMenu, NULL}, { "/menu", cgiMenu, NULL },
{"/flash/next", cgiGetFirmwareNext, NULL}, { "/flash/next", cgiGetFirmwareNext, NULL },
{"/flash/upload", cgiUploadFirmware, NULL}, { "/flash/upload", cgiUploadFirmware, NULL },
{"/flash/reboot", cgiRebootFirmware, NULL}, { "/flash/reboot", cgiRebootFirmware, NULL },
//{"/home.html", cgiEspFsHtml, NULL}, //{"/home.html", cgiEspFsHtml, NULL},
//{"/log.html", cgiEspFsHtml, NULL}, //{"/log.html", cgiEspFsHtml, NULL},
{"/log/text", ajaxLog, NULL}, { "/log/text", ajaxLog, NULL },
{"/log/dbg", ajaxLogDbg, NULL}, { "/log/dbg", ajaxLogDbg, NULL },
//{"/console.html", cgiEspFsHtml, NULL}, //{"/console.html", cgiEspFsHtml, NULL},
{"/console/reset", ajaxConsoleReset, NULL}, { "/console/reset", ajaxConsoleReset, NULL },
{"/console/baud", ajaxConsoleBaud, NULL}, { "/console/baud", ajaxConsoleBaud, NULL },
{"/console/text", ajaxConsole, NULL}, { "/console/text", ajaxConsole, NULL },
//Routines to make the /wifi URL and everything beneath it work. //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. //Enable the line below to protect the WiFi configuration with an username/password combo.
// {"/wifi/*", authBasic, myPassFn}, // {"/wifi/*", authBasic, myPassFn},
{"/wifi", cgiRedirect, "/wifi/wifi.html"}, { "/wifi", cgiRedirect, "/wifi/wifi.html" },
{"/wifi/", cgiRedirect, "/wifi/wifi.html"}, { "/wifi/", cgiRedirect, "/wifi/wifi.html" },
//{"/wifi/wifi.html", cgiEspFsHtml, NULL}, //{"/wifi/wifi.html", cgiEspFsHtml, NULL},
{"/wifi/info", cgiWifiInfo, NULL}, { "/wifi/info", cgiWifiInfo, NULL },
{"/wifi/scan", cgiWiFiScan, NULL}, { "/wifi/scan", cgiWiFiScan, NULL },
{"/wifi/connect", cgiWiFiConnect, NULL}, { "/wifi/connect", cgiWiFiConnect, NULL },
{"/wifi/connstatus", cgiWiFiConnStatus, NULL}, { "/wifi/connstatus", cgiWiFiConnStatus, NULL },
{"/wifi/setmode", cgiWiFiSetMode, NULL}, { "/wifi/setmode", cgiWiFiSetMode, NULL },
{"/wifi/special", cgiWiFiSpecial, NULL}, { "/wifi/special", cgiWiFiSpecial, NULL },
{"/pins", cgiPins, NULL}, { "/pins", cgiPins, NULL },
{"/tcpclient", cgiTcp, NULL}, { "/tcpclient", cgiTcp, NULL },
{"*", cgiEspFsHook, NULL}, //Catch-all cgi function for the filesystem { "*", cgiEspFsHook, NULL }, //Catch-all cgi function for the filesystem
{NULL, NULL, NULL} { NULL, NULL, NULL }
}; };
//#define SHOW_HEAP_USE //#define SHOW_HEAP_USE
#ifdef SHOW_HEAP_USE #ifdef SHOW_HEAP_USE
@ -104,62 +106,53 @@ static void ICACHE_FLASH_ATTR prHeapTimerCb(void *arg) {
} }
#endif #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_STR(V) #V
# define VERS_STR(V) VERS_STR_STR(V) # define VERS_STR(V) VERS_STR_STR(V)
char *esp_link_version = VERS_STR(VERSION); 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 // 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(); bool restoreOk = configRestore();
// init gpio pin registers // init gpio pin registers
gpio_init(); gpio_init();
// init UART // init UART
uart_init(flashConfig.baud_rate, 115200); uart_init(flashConfig.baud_rate, 115200);
logInit(); // must come after init of uart logInit(); // must come after init of uart
// say hello (leave some time to cause break in TX after boot loader's msg // say hello (leave some time to cause break in TX after boot loader's msg
os_delay_us(10000L); os_delay_us(10000L);
os_printf("\n\n** %s\n", esp_link_version); os_printf("\n\n** %s\n", esp_link_version);
os_printf("Flash config restore %s\n", restoreOk ? "ok" : "*FAILED*"); os_printf("Flash config restore %s\n", restoreOk ? "ok" : "*FAILED*");
// Status LEDs // Status LEDs
statusInit(); statusInit();
serledInit(); serledInit();
#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;
static char *rst_codes[] = {
"normal", "wdt reset", "exception", "soft wdt", "restart", "deep sleep", "external",
};
//Main routine. Initialize stdout, the I/O, filesystem and the webserver and we're done.
void user_init(void) {
// Wifi // Wifi
wifiInit(); wifiInit();
// init the flash filesystem with the html stuff // init the flash filesystem with the html stuff
espFsInit(&_binary_espfs_img_start); espFsInit(&_binary_espfs_img_start);
//EspFsInitResult res = espFsInit(&_binary_espfs_img_start); //EspFsInitResult res = espFsInit(&_binary_espfs_img_start);
//os_printf("espFsInit %s\n", res?"ERR":"ok"); //os_printf("espFsInit %s\n", res?"ERR":"ok");
// mount the http handlers // mount the http handlers
httpdInit(builtInUrls, 80); httpdInit(builtInUrls, 80);
// init the wifi-serial transparent bridge (port 23) // init the wifi-serial transparent bridge (port 23)
serbridgeInit(23); serbridgeInit(23);
uart_add_recv_cb(&serbridgeUartCb); 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
struct rst_info *rst_info = system_get_rst_info(); 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("Reset cause: %d=%s\n", rst_info->reason, rst_codes[rst_info->reason]);
@ -169,4 +162,7 @@ void user_init(void) {
os_printf("Flash map %d, chip %08X\n", system_get_flash_size_map(), spi_flash_get_id()); os_printf("Flash map %d, chip %08X\n", system_get_flash_size_map(), spi_flash_get_id());
os_printf("** esp-link ready\n"); os_printf("** esp-link ready\n");
// call user_main init
// init();
} }
Loading…
Cancel
Save