diff --git a/README.md b/README.md index b0310a9..db37f2e 100644 --- a/README.md +++ b/README.md @@ -5,76 +5,82 @@ This is MQTT client library for ESP8266, port from: [MQTT client library for Contiki](https://github.com/esar/contiki-mqtt) (thanks) - **Features:** * Support subscribing, publishing, authentication, will messages, keep alive pings and all 3 QoS levels (it should be a fully functional client). * Support multiple connection (to multiple hosts). - * Support SSL connection + * Support SSL connection (including cert verification). * Easy to setup and use + ***Prerequire:*** - ESPTOOL.PY: https://github.com/themadinventor/esptool - SDK 2.0 or higher: http://bbs.espressif.com/viewtopic.php?f=46&t=2451 -- ESP8266 compiler: +- ESP8266 compiler: + OSX or Linux: http://tuanpm.net/esp8266-development-kit-on-mac-os-yosemite-and-eclipse-ide/ - + Windows: http://programs74.ru/udkew-en.html + + Windows: http://programs74.ru/udkew-en.html + **Compile:** - Copy file `include/user_config.sample.h` to `include/user_config.local.h` and change settings, included: SSID, PASS, MQTT configurations ... - Make sure to add PYTHON PATH and compile PATH to Eclipse environment variable if using Eclipse - ```bash git clone --recursive https://github.com/tuanpmt/esp_mqtt cd esp_mqtt #clean make clean #make -make SDK_BASE=/tools/esp8266/sdk/ESP8266_NONOS_SDK ESPTOOL=tools/esp8266/esptool/esptool.py all +make SDK_BASE=/tools/esp8266/sdk/ESP8266_NONOS_SDK ESPTOOL=/tools/esp8266/esptool/esptool.py all #flash make ESPPORT=/dev/ttyUSB0 flash ``` +To create the library (and removing the uart debug output) use + +```bash +make SDK_BASE=/tools/esp8266/sdk/ESP8266_NONOS_SDK FLAVOR=release lib +``` + **Usage** See file: `user/user_main.c` + **Notes** -- The client id needs to be unique. If not, When there are more than 2 clients use the same ClientID, the following logged-in client will kick the ahead logged-in client, and so on forever +- The client id needs to be unique. If not, when there are more than 2 clients use the same ClientID, the following logged-in client will kick the ahead logged-in client, and so on forever. + **Publish message and Subscribe** ```c /* TRUE if success */ -BOOL MQTT_Subscribe(MQTT_Client *client, char* topic, uint8_t qos); - -BOOL MQTT_Publish(MQTT_Client *client, const char* topic, const char* data, int data_length, int qos, int retain); +BOOL MQTT_Subscribe(MQTT_Client *client, const char* topic, uint8_t qos); +BOOL MQTT_Publish(MQTT_Client *client, const char* topic, const char* data, int data_length, uint8_t qos, uint8_t retain); ``` + **Already support LWT: (Last Will and Testament)** ```c - /* Broker will publish a message with qos = 0, retain = 0, data = "offline" to topic "/lwt" if client don't send keepalive packet */ MQTT_InitLWT(&mqttClient, "/lwt", "offline", 0, 0); - ``` + # Default configuration See: **include/user_config.sample.h** -**Define protocol name in include/user_config.local.h** +Define protocol name in `include/user_config.local.h` ```c #define PROTOCOL_NAMEv31 /*MQTT version 3.1 compatible with Mosquitto v0.15*/ -//PROTOCOL_NAMEv311 /*MQTT version 3.11 compatible with https://eclipse.org/paho/clients/testing/*/ +//#define PROTOCOL_NAMEv311 /*MQTT version 3.11 compatible with https://eclipse.org/paho/clients/testing/*/ ``` @@ -84,6 +90,26 @@ See: **include/user_config.sample.h** openssl req -x509 -newkey rsa:1024 -keyout key.pem -out cert.pem -days XXX ``` +On client side (ESP8266) you need to provide a `ca.crt` and a `client.crt`, `client.key` pair depending what kind of security you choose (SEC_SSL_ONE_WAY_AUTH or SEC_SSL_TWO_WAY_AUTH). + +```c +//#define DEFAULT_SECURITY SEC_NONSSL // disable SSL/TLS +#define DEFAULT_SECURITY SEC_SSL_WITHOUT_AUTH // enable SSL/TLS, but there is no a certificate verify +//#define DEFAULT_SECURITY SEC_SSL_ONE_WAY_AUTH // enable SSL/TLS, ESP8266 would verify the SSL server certificate at the same time +//#define DEFAULT_SECURITY SEC_SSL_TWO_WAY_AUTH // enable SSL/TLS, ESP8266 would verify the SSL server certificate and SSL server would verify ESP8266 certificate +``` + +For more details how to create and flash the `ca.crt` and `client.crt` see the `tools` folder in [SDK_BASE](https://github.com/espressif/ESP8266_NONOS_SDK/tree/master/tools). +See also [ESP8266 Non-OS SDK SSL User Manual](https://www.espressif.com/sites/default/files/documentation/5a-esp8266_sdk_ssl_user_manual_en.pdf) in the Espressif documentation. + +If needed you may configure the flash locations of the certificates in `include/user_config.local.h` + +```c +#define CA_CERT_FLASH_ADDRESS 0x77 // CA certificate address in flash to read, 0x77 means address 0x77000 +#define CLIENT_CERT_FLASH_ADDRESS 0x78 // client certificate and private key address in flash to read, 0x78 means address 0x78000 +``` + + **SSL Mqtt broker for test** ```javascript diff --git a/include/user_config.sample.h b/include/user_config.sample.h index 4de6ccc..34acfbc 100644 --- a/include/user_config.sample.h +++ b/include/user_config.sample.h @@ -1,31 +1,44 @@ #ifndef __MQTT_CONFIG_H__ #define __MQTT_CONFIG_H__ -#define MQTT_SSL_ENABLE +#include "mqtt.h" /*DEFAULT CONFIGURATIONS*/ -#define MQTT_HOST "192.168.0.101" //or "mqtt.yourdomain.com" -#define MQTT_PORT 1883 -#define MQTT_BUF_SIZE 1024 -#define MQTT_KEEPALIVE 120 /*second*/ +#define MQTT_HOST "192.168.0.101" //or "mqtt.yourdomain.com" +#define MQTT_CLIENT_ID "CLIENT_1234" +#define MQTT_USER "USER" +#define MQTT_PASS "PASS" -#define MQTT_CLIENT_ID "CLIENT_1234" -#define MQTT_USER "USER" -#define MQTT_PASS "PASS" +#define MQTT_BUF_SIZE 1024 +#define MQTT_SSL_SIZE 3072 +#define MQTT_KEEPALIVE 120 /*second*/ #define MQTT_CLEAN_SESSION 1 -#define MQTT_KEEPALIVE 120 +#define MQTT_RECONNECT_TIMEOUT 5 /*second*/ +#define QUEUE_BUFFER_SIZE 2048 + #define STA_SSID "SSID" #define STA_PASS "PASS" -#define MQTT_RECONNECT_TIMEOUT 5 /*second*/ -#define DEFAULT_SECURITY 0 -#define QUEUE_BUFFER_SIZE 2048 +//#define DEFAULT_SECURITY SEC_NONSSL // disable SSL/TLS +#define DEFAULT_SECURITY SEC_SSL_WITHOUT_AUTH // enable SSL/TLS, but there is no a certificate verify +//#define DEFAULT_SECURITY SEC_SSL_ONE_WAY_AUTH // enable SSL/TLS, ESP8266 would verify the SSL server certificate at the same time +//#define DEFAULT_SECURITY SEC_SSL_TWO_WAY_AUTH // enable SSL/TLS, ESP8266 would verify the SSL server certificate and SSL server would verify ESP8266 certificate + +#if DEFAULT_SECURITY == SEC_NONSSL +#define MQTT_PORT 1883 +#else +#define MQTT_PORT 8883 +#define MQTT_SSL_ENABLE +#define CA_CERT_FLASH_ADDRESS 0x77 // CA certificate address in flash to read, 0x77 means address 0x77000 +#define CLIENT_CERT_FLASH_ADDRESS 0x78 // client certificate and private key address in flash to read, 0x78 means address 0x78000 +// also add mbedtls to the Makefile LIBS +#endif -#define PROTOCOL_NAMEv31 /*MQTT version 3.1 compatible with Mosquitto v0.15*/ -//PROTOCOL_NAMEv311 /*MQTT version 3.11 compatible with https://eclipse.org/paho/clients/testing/*/ +//#define PROTOCOL_NAMEv31 /*MQTT version 3.1 compatible with Mosquitto v0.15*/ +#define PROTOCOL_NAMEv311 /*MQTT version 3.11 compatible with https://eclipse.org/paho/clients/testing/*/ #if defined(DEBUG_ON) #define INFO( format, ... ) os_printf( format, ## __VA_ARGS__ ) diff --git a/modules/include/wifi.h b/modules/include/wifi.h index 60f93e1..c383a76 100644 --- a/modules/include/wifi.h +++ b/modules/include/wifi.h @@ -9,5 +9,5 @@ #define USER_WIFI_H_ #include "os_type.h" typedef void (*WifiCallback)(uint8_t); -void ICACHE_FLASH_ATTR WIFI_Connect(uint8_t* ssid, uint8_t* pass, WifiCallback cb); +void ICACHE_FLASH_ATTR WIFI_Connect(const char* ssid, const char* pass, WifiCallback cb); #endif /* USER_WIFI_H_ */ diff --git a/modules/wifi.c b/modules/wifi.c index 8f46908..010c2ef 100644 --- a/modules/wifi.c +++ b/modules/wifi.c @@ -60,7 +60,7 @@ static void ICACHE_FLASH_ATTR wifi_check_ip(void *arg) } } -void ICACHE_FLASH_ATTR WIFI_Connect(uint8_t* ssid, uint8_t* pass, WifiCallback cb) +void ICACHE_FLASH_ATTR WIFI_Connect(const char* ssid, const char* pass, WifiCallback cb) { struct station_config stationConf; @@ -76,4 +76,3 @@ void ICACHE_FLASH_ATTR WIFI_Connect(uint8_t* ssid, uint8_t* pass, WifiCallback c os_timer_arm(&WiFiLinker, 1000, 0); wifi_station_connect(); } - diff --git a/mqtt/include/mqtt.h b/mqtt/include/mqtt.h index c33d471..fa08716 100644 --- a/mqtt/include/mqtt.h +++ b/mqtt/include/mqtt.h @@ -29,11 +29,10 @@ */ #ifndef USER_AT_MQTT_H_ #define USER_AT_MQTT_H_ -#include "user_config.h" #include "mqtt_msg.h" #include "user_interface.h" - #include "queue.h" + typedef struct mqtt_event_data_t { uint8_t type; @@ -94,7 +93,7 @@ typedef void (*MqttDataCallback)(uint32_t *args, const char* topic, uint32_t top typedef struct { struct espconn *pCon; uint8_t security; - uint8_t* host; + char* host; uint32_t port; ip_addr_t ip; mqtt_state_t mqtt_state; @@ -113,36 +112,39 @@ typedef struct { void* user_data; } MQTT_Client; -#define SEC_NONSSL 0 -#define SEC_SSL 1 +// define the possible MQTT SSL/TLS certificate options +#define SEC_NONSSL 0 // disable SSL/TLS +#define SEC_SSL_WITHOUT_AUTH 1 // enable SSL/TLS, but there is no a certificate verify +#define SEC_SSL_ONE_WAY_AUTH 2 // enable SSL/TLS, ESP8266 would verify the SSL server certificate at the same time +#define SEC_SSL_TWO_WAY_AUTH 3 // enable SSL/TLS, ESP8266 would verify the SSL server certificate and SSL server would verify ESP8266 certificate -#define MQTT_FLAG_CONNECTED 1 +#define MQTT_FLAG_CONNECTED 1 #define MQTT_FLAG_READY 2 #define MQTT_FLAG_EXIT 4 -#define MQTT_EVENT_TYPE_NONE 0 +#define MQTT_EVENT_TYPE_NONE 0 #define MQTT_EVENT_TYPE_CONNECTED 1 #define MQTT_EVENT_TYPE_DISCONNECTED 2 #define MQTT_EVENT_TYPE_SUBSCRIBED 3 #define MQTT_EVENT_TYPE_UNSUBSCRIBED 4 -#define MQTT_EVENT_TYPE_PUBLISH 5 +#define MQTT_EVENT_TYPE_PUBLISH 5 #define MQTT_EVENT_TYPE_PUBLISHED 6 -#define MQTT_EVENT_TYPE_EXITED 7 +#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_t port, uint8_t security); -BOOL 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_InitConnection(MQTT_Client *mqttClient, const char* host, uint32_t port, uint8_t security); +BOOL ICACHE_FLASH_ATTR MQTT_InitClient(MQTT_Client *mqttClient, const char* client_id, const char* client_user, const char* client_pass, uint32_t keepAliveTime, uint8_t cleanSession); void ICACHE_FLASH_ATTR MQTT_DeleteClient(MQTT_Client *mqttClient); -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, const char* will_topic, const char* 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_OnTimeout(MQTT_Client *mqttClient, MqttCallback timeoutCb); 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_UnSubscribe(MQTT_Client *client, char* topic); +BOOL ICACHE_FLASH_ATTR MQTT_Subscribe(MQTT_Client *client, const char* topic, uint8_t qos); +BOOL ICACHE_FLASH_ATTR MQTT_UnSubscribe(MQTT_Client *client, const char* topic); 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 data_length, int qos, int retain); +BOOL ICACHE_FLASH_ATTR MQTT_Publish(MQTT_Client *client, const char* topic, const char* data, int data_length, uint8_t qos, uint8_t retain); #endif /* USER_AT_MQTT_H_ */ diff --git a/mqtt/include/mqtt_msg.h b/mqtt/include/mqtt_msg.h index be3cc55..d9bec89 100644 --- a/mqtt/include/mqtt_msg.h +++ b/mqtt/include/mqtt_msg.h @@ -7,7 +7,6 @@ #ifndef MQTT_MSG_H #define MQTT_MSG_H -#include "user_config.h" #include "c_types.h" #ifdef __cplusplus extern "C" { @@ -138,4 +137,3 @@ mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_disconnect(mqtt_connection_t* connect #endif #endif /* MQTT_MSG_H */ - diff --git a/mqtt/include/typedef.h b/mqtt/include/typedef.h index 887001a..b86bb27 100644 --- a/mqtt/include/typedef.h +++ b/mqtt/include/typedef.h @@ -14,4 +14,17 @@ typedef long I32; typedef unsigned long U32; typedef unsigned long long U64; +#ifdef __cplusplus +// fix bug in c_types.h include, not defining BOOL, TRUE, FALSE for c++ +#ifndef BOOL +# define BOOL bool +#endif // BOOL +#ifndef TRUE +# define TRUE true +#endif // TRUE +#ifndef FALSE +# define FALSE false +#endif // FALSE +#endif // __cplusplus + #endif diff --git a/mqtt/include/utils.h b/mqtt/include/utils.h index fe28748..493a486 100644 --- a/mqtt/include/utils.h +++ b/mqtt/include/utils.h @@ -3,7 +3,7 @@ #include "c_types.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); +uint32_t ICACHE_FLASH_ATTR UTILS_Atoh(const char *s); +uint8_t ICACHE_FLASH_ATTR UTILS_StrToIP(const char *str, void *ip); +uint8_t ICACHE_FLASH_ATTR UTILS_IsIPV4 (const char *str); #endif diff --git a/mqtt/mqtt.c b/mqtt/mqtt.c index 375a441..1b7d742 100644 --- a/mqtt/mqtt.c +++ b/mqtt/mqtt.c @@ -39,9 +39,10 @@ #include "user_config.h" #include "mqtt.h" #include "queue.h" +#include "utils.h" -#define MQTT_TASK_PRIO 2 -#define MQTT_TASK_QUEUE_SIZE 1 +#define MQTT_TASK_PRIO 2 +#define MQTT_TASK_QUEUE_SIZE 1 #define MQTT_SEND_TIMOUT 5 #ifndef MQTT_SSL_SIZE @@ -60,7 +61,7 @@ unsigned int default_private_key_len = 0; os_event_t mqtt_procTaskQueue[MQTT_TASK_QUEUE_SIZE]; #ifdef PROTOCOL_NAMEv311 -LOCAL uint8_t zero_len_id[2] = { 0, 0 }; +LOCAL char zero_len_id[2] = { 0, 0 }; #endif LOCAL void ICACHE_FLASH_ATTR @@ -69,9 +70,7 @@ 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) { MQTT_INFO("DNS: Found, but got no ip, try to reconnect\r\n"); client->connState = TCP_RECONNECT_REQ; return; @@ -83,11 +82,16 @@ mqtt_dns_found(const char *name, ip_addr_t *ipaddr, void *arg) *((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); if (client->security) { #ifdef MQTT_SSL_ENABLE + if (client->security >= SEC_SSL_ONE_WAY_AUTH) { + espconn_secure_ca_enable(ESPCONN_CLIENT, CA_CERT_FLASH_ADDRESS); + } + if (client->security >= SEC_SSL_TWO_WAY_AUTH) { + espconn_secure_cert_req_enable(ESPCONN_CLIENT, CLIENT_CERT_FLASH_ADDRESS); + } espconn_secure_set_size(ESPCONN_CLIENT, MQTT_SSL_SIZE); espconn_secure_connect(client->pCon); #else @@ -105,8 +109,6 @@ mqtt_dns_found(const char *name, ip_addr_t *ipaddr, void *arg) system_os_post(MQTT_TASK_PRIO, 0, (os_param_t)client); } - - LOCAL void ICACHE_FLASH_ATTR deliver_publish(MQTT_Client* client, uint8_t* message, int length) { @@ -122,7 +124,7 @@ deliver_publish(MQTT_Client* client, uint8_t* message, int length) } -void ICACHE_FLASH_ATTR +LOCAL void ICACHE_FLASH_ATTR mqtt_send_keepalive(MQTT_Client *client) { MQTT_INFO("\r\nMQTT: Send keepalive packet to %s:%d!\r\n", client->host, client->port); @@ -131,7 +133,6 @@ mqtt_send_keepalive(MQTT_Client *client) client->mqtt_state.pending_msg_type = mqtt_get_type(client->mqtt_state.outbound_message->data); client->mqtt_state.pending_msg_id = mqtt_get_id(client->mqtt_state.outbound_message->data, client->mqtt_state.outbound_message->length); - client->sendTimeout = MQTT_SEND_TIMOUT; MQTT_INFO("MQTT: Sending, type: %d, id: %04X\r\n", client->mqtt_state.pending_msg_type, client->mqtt_state.pending_msg_id); err_t result = ESPCONN_OK; @@ -163,7 +164,7 @@ mqtt_send_keepalive(MQTT_Client *client) * @param mqttClient: The mqtt client which contain TCP client * @retval None */ -void ICACHE_FLASH_ATTR +LOCAL void ICACHE_FLASH_ATTR mqtt_tcpclient_delete(MQTT_Client *mqttClient) { if (mqttClient->pCon != NULL) { @@ -187,7 +188,7 @@ mqtt_tcpclient_delete(MQTT_Client *mqttClient) * @param mqttClient: The mqtt client * @retval None */ -void ICACHE_FLASH_ATTR +LOCAL void ICACHE_FLASH_ATTR mqtt_client_delete(MQTT_Client *mqttClient) { if (mqttClient == NULL) @@ -218,8 +219,7 @@ mqtt_client_delete(MQTT_Client *mqttClient) } if (mqttClient->mqtt_state.outbound_message != NULL) { - if (mqttClient->mqtt_state.outbound_message->data != NULL) - { + if (mqttClient->mqtt_state.outbound_message->data != NULL) { os_free(mqttClient->mqtt_state.outbound_message->data); mqttClient->mqtt_state.outbound_message->data = NULL; } @@ -233,7 +233,7 @@ mqtt_client_delete(MQTT_Client *mqttClient) if (mqttClient->connect_info.client_id != NULL) { #ifdef PROTOCOL_NAMEv311 /* Don't attempt to free if it's the zero_len array */ - if ( ((uint8_t*)mqttClient->connect_info.client_id) != zero_len_id ) + if (mqttClient->connect_info.client_id != zero_len_id) os_free(mqttClient->connect_info.client_id); #else os_free(mqttClient->connect_info.client_id); @@ -278,7 +278,6 @@ mqtt_client_delete(MQTT_Client *mqttClient) MQTT_INFO("MQTT: client already deleted\r\n"); } - /** * @brief Client received callback function. * @param arg: contain the ip link information @@ -286,7 +285,7 @@ mqtt_client_delete(MQTT_Client *mqttClient) * @param len: the lenght of received data * @retval None */ -void ICACHE_FLASH_ATTR +LOCAL void ICACHE_FLASH_ATTR mqtt_tcpclient_recv(void *arg, char *pdata, unsigned short len) { uint8_t msg_type; @@ -359,9 +358,7 @@ mqtt_tcpclient_recv(void *arg, char *pdata, unsigned short len) client->mqtt_state.message_length = mqtt_get_total_length(client->mqtt_state.in_buffer, client->mqtt_state.message_length_read); - switch (msg_type) - { - + switch (msg_type) { case MQTT_MSG_TYPE_SUBACK: if (client->mqtt_state.pending_msg_type == MQTT_MSG_TYPE_SUBSCRIBE && client->mqtt_state.pending_msg_id == msg_id) MQTT_INFO("MQTT: Subscribe successful\r\n"); @@ -388,7 +385,6 @@ mqtt_tcpclient_recv(void *arg, char *pdata, unsigned short len) if (client->mqtt_state.pending_msg_type == MQTT_MSG_TYPE_PUBLISH && client->mqtt_state.pending_msg_id == msg_id) { MQTT_INFO("MQTT: received MQTT_MSG_TYPE_PUBACK, finish QoS1 publish\r\n"); } - break; case MQTT_MSG_TYPE_PUBREC: client->mqtt_state.outbound_message = mqtt_msg_pubrel(&client->mqtt_state.mqtt_connection, msg_id); @@ -420,12 +416,9 @@ mqtt_tcpclient_recv(void *arg, char *pdata, unsigned short len) // 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; @@ -434,7 +427,6 @@ mqtt_tcpclient_recv(void *arg, char *pdata, unsigned short len) MQTT_INFO("Get another published message\r\n"); goto READPACKET; } - } break; } @@ -449,11 +441,12 @@ mqtt_tcpclient_recv(void *arg, char *pdata, unsigned short len) * @param arg: contain the ip link information * @retval None */ -void ICACHE_FLASH_ATTR +LOCAL void ICACHE_FLASH_ATTR mqtt_tcpclient_sent_cb(void *arg) { struct espconn *pCon = (struct espconn *)arg; MQTT_Client* client = (MQTT_Client *)pCon->reverse; + MQTT_INFO("TCP: Sent\r\n"); client->sendTimeout = 0; client->keepAliveTick = 0; @@ -466,7 +459,8 @@ mqtt_tcpclient_sent_cb(void *arg) system_os_post(MQTT_TASK_PRIO, 0, (os_param_t)client); } -void ICACHE_FLASH_ATTR mqtt_timer(void *arg) +LOCAL void ICACHE_FLASH_ATTR +mqtt_timer(void *arg) { MQTT_Client* client = (MQTT_Client*)arg; @@ -491,12 +485,12 @@ void ICACHE_FLASH_ATTR mqtt_timer(void *arg) client->sendTimeout --; } -void ICACHE_FLASH_ATTR +LOCAL void ICACHE_FLASH_ATTR mqtt_tcpclient_discon_cb(void *arg) { - struct espconn *pespconn = (struct espconn *)arg; MQTT_Client* client = (MQTT_Client *)pespconn->reverse; + MQTT_INFO("TCP: Disconnected callback\r\n"); if (TCP_DISCONNECTING == client->connState) { client->connState = TCP_DISCONNECTED; @@ -513,14 +507,12 @@ mqtt_tcpclient_discon_cb(void *arg) system_os_post(MQTT_TASK_PRIO, 0, (os_param_t)client); } - - /** * @brief Tcp client connect success callback function. * @param arg: contain the ip link information * @retval None */ -void ICACHE_FLASH_ATTR +LOCAL void ICACHE_FLASH_ATTR mqtt_tcpclient_connect_cb(void *arg) { struct espconn *pCon = (struct espconn *)arg; @@ -536,7 +528,6 @@ mqtt_tcpclient_connect_cb(void *arg) client->mqtt_state.pending_msg_type = mqtt_get_type(client->mqtt_state.outbound_message->data); client->mqtt_state.pending_msg_id = mqtt_get_id(client->mqtt_state.outbound_message->data, client->mqtt_state.outbound_message->length); - client->sendTimeout = MQTT_SEND_TIMOUT; MQTT_INFO("MQTT: Sending, type: %d, id: %04X\r\n", client->mqtt_state.pending_msg_type, client->mqtt_state.pending_msg_id); if (client->security) { @@ -560,7 +551,7 @@ mqtt_tcpclient_connect_cb(void *arg) * @param arg: contain the ip link information * @retval None */ -void ICACHE_FLASH_ATTR +LOCAL void ICACHE_FLASH_ATTR mqtt_tcpclient_recon_cb(void *arg, sint8 errType) { struct espconn *pCon = (struct espconn *)arg; @@ -571,7 +562,6 @@ mqtt_tcpclient_recon_cb(void *arg, sint8 errType) client->connState = TCP_RECONNECT_REQ; system_os_post(MQTT_TASK_PRIO, 0, (os_param_t)client); - } /** @@ -585,7 +575,7 @@ 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 data_length, int qos, int retain) +MQTT_Publish(MQTT_Client *client, const char* topic, const char* data, int data_length, uint8_t qos, uint8_t retain) { uint8_t dataBuffer[MQTT_BUF_SIZE]; uint16_t dataLen; @@ -617,7 +607,7 @@ MQTT_Publish(MQTT_Client *client, const char* topic, const char* data, int data_ * @retval TRUE if success queue */ BOOL ICACHE_FLASH_ATTR -MQTT_Subscribe(MQTT_Client *client, char* topic, uint8_t qos) +MQTT_Subscribe(MQTT_Client *client, const char* topic, uint8_t qos) { uint8_t dataBuffer[MQTT_BUF_SIZE]; uint16_t dataLen; @@ -645,7 +635,7 @@ MQTT_Subscribe(MQTT_Client *client, char* topic, uint8_t qos) * @retval TRUE if success queue */ BOOL ICACHE_FLASH_ATTR -MQTT_UnSubscribe(MQTT_Client *client, char* topic) +MQTT_UnSubscribe(MQTT_Client *client, const char* topic) { uint8_t dataBuffer[MQTT_BUF_SIZE]; uint16_t dataLen; @@ -773,18 +763,18 @@ MQTT_Task(os_event_t *e) * @retval None */ void ICACHE_FLASH_ATTR -MQTT_InitConnection(MQTT_Client *mqttClient, uint8_t* host, uint32_t port, uint8_t security) +MQTT_InitConnection(MQTT_Client *mqttClient, const char* host, uint32_t port, uint8_t security) { uint32_t temp; + MQTT_INFO("MQTT:InitConnection\r\n"); os_memset(mqttClient, 0, sizeof(MQTT_Client)); temp = os_strlen(host); - mqttClient->host = (uint8_t*)os_zalloc(temp + 1); + mqttClient->host = (char *)os_zalloc(temp + 1); os_strcpy(mqttClient->host, host); mqttClient->host[temp] = 0; mqttClient->port = port; mqttClient->security = security; - } /** @@ -793,25 +783,25 @@ MQTT_InitConnection(MQTT_Client *mqttClient, uint8_t* host, uint32_t port, uint8 * @param clientid: MQTT client id * @param client_user:MQTT client user * @param client_pass:MQTT client password - * @param client_pass:MQTT keep alive timer, in second - * @retval None + * @param keepAliveTime: MQTT keep alive timer, in second + * @param cleanSession: MQTT clean session (TRUE = Clean session, FALSE = Persistent Session) + * @retval TRUE if success init */ BOOL 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, const char* client_id, const char* client_user, const char* client_pass, uint32_t keepAliveTime, uint8_t cleanSession) { uint32_t temp; - MQTT_INFO("MQTT:InitClient\r\n"); + MQTT_INFO("MQTT:InitClient\r\n"); os_memset(&mqttClient->connect_info, 0, sizeof(mqtt_connect_info_t)); - if ( !client_id ) - { + if ( !client_id ) { /* Should be allowed by broker, but clean session flag must be set. */ #ifdef PROTOCOL_NAMEv311 - if (cleanSession) - { + if (cleanSession) { mqttClient->connect_info.client_id = zero_len_id; - } else { + } + else { MQTT_INFO("cleanSession must be set to use 0 length client_id\r\n"); return false; } @@ -824,31 +814,27 @@ MQTT_InitClient(MQTT_Client *mqttClient, uint8_t* client_id, uint8_t* client_use /* If connect_info's client_id is still NULL and we get here, we can * * assume the passed client_id is non-NULL. */ - if ( !(mqttClient->connect_info.client_id) ) - { + if ( !(mqttClient->connect_info.client_id) ) { temp = os_strlen(client_id); - mqttClient->connect_info.client_id = (uint8_t*)os_zalloc(temp + 1); + mqttClient->connect_info.client_id = (char *)os_zalloc(temp + 1); os_strcpy(mqttClient->connect_info.client_id, client_id); mqttClient->connect_info.client_id[temp] = 0; } - if (client_user) - { + if (client_user) { temp = os_strlen(client_user); - mqttClient->connect_info.username = (uint8_t*)os_zalloc(temp + 1); + mqttClient->connect_info.username = (char *)os_zalloc(temp + 1); os_strcpy(mqttClient->connect_info.username, client_user); mqttClient->connect_info.username[temp] = 0; } - if (client_pass) - { + if (client_pass) { temp = os_strlen(client_pass); - mqttClient->connect_info.password = (uint8_t*)os_zalloc(temp + 1); + mqttClient->connect_info.password = (char *)os_zalloc(temp + 1); os_strcpy(mqttClient->connect_info.password, client_pass); mqttClient->connect_info.password[temp] = 0; } - mqttClient->connect_info.keepalive = keepAliveTime; mqttClient->connect_info.clean_session = cleanSession; @@ -866,24 +852,26 @@ MQTT_InitClient(MQTT_Client *mqttClient, uint8_t* client_id, uint8_t* client_use system_os_post(MQTT_TASK_PRIO, 0, (os_param_t)mqttClient); return true; } + 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, const char* will_topic, const char* will_msg, uint8_t will_qos, uint8_t will_retain) { uint32_t temp; + temp = os_strlen(will_topic); - mqttClient->connect_info.will_topic = (uint8_t*)os_zalloc(temp + 1); + mqttClient->connect_info.will_topic = (char *)os_zalloc(temp + 1); os_strcpy(mqttClient->connect_info.will_topic, will_topic); mqttClient->connect_info.will_topic[temp] = 0; temp = os_strlen(will_msg); - mqttClient->connect_info.will_message = (uint8_t*)os_zalloc(temp + 1); + mqttClient->connect_info.will_message = (char *)os_zalloc(temp + 1); os_strcpy(mqttClient->connect_info.will_message, will_msg); mqttClient->connect_info.will_message[temp] = 0; - mqttClient->connect_info.will_qos = will_qos; mqttClient->connect_info.will_retain = will_retain; } + /** * @brief Begin connect to MQTT broker * @param client: MQTT_Client reference @@ -911,24 +899,28 @@ MQTT_Connect(MQTT_Client *mqttClient) mqttClient->keepAliveTick = 0; mqttClient->reconnectTick = 0; - os_timer_disarm(&mqttClient->mqttTimer); os_timer_setfn(&mqttClient->mqttTimer, (os_timer_func_t *)mqtt_timer, mqttClient); os_timer_arm(&mqttClient->mqttTimer, 1000, 1); + MQTT_INFO("your ESP SSL/TLS configuration is %d. [0:NONSSL\t1:SSL_WITHOUT_AUTH\t2:SSL_ONE_WAY_AUTH\t3:SSL_TWO_WAY_AUTH]\r\n", mqttClient->security); if (UTILS_StrToIP(mqttClient->host, &mqttClient->pCon->proto.tcp->remote_ip)) { MQTT_INFO("TCP: Connect to ip %s:%d\r\n", mqttClient->host, mqttClient->port); - if (mqttClient->security) - { + if (mqttClient->security) { #ifdef MQTT_SSL_ENABLE + if (mqttClient->security >= SEC_SSL_ONE_WAY_AUTH) { + espconn_secure_ca_enable(ESPCONN_CLIENT, CA_CERT_FLASH_ADDRESS); + } + if (mqttClient->security >= SEC_SSL_TWO_WAY_AUTH) { + espconn_secure_cert_req_enable(ESPCONN_CLIENT, CLIENT_CERT_FLASH_ADDRESS); + } espconn_secure_set_size(ESPCONN_CLIENT, MQTT_SSL_SIZE); espconn_secure_connect(mqttClient->pCon); #else MQTT_INFO("TCP: Do not support SSL\r\n"); #endif } - else - { + else { espconn_connect(mqttClient->pCon); } } diff --git a/mqtt/mqtt_msg.c b/mqtt/mqtt_msg.c index 57dcbac..93c7953 100644 --- a/mqtt/mqtt_msg.c +++ b/mqtt/mqtt_msg.c @@ -296,7 +296,7 @@ mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_connect(mqtt_connection_t* connection if (connection->message.length + sizeof(*variable_header) > connection->buffer_length) return fail_message(connection); - variable_header = (void*)(connection->buffer + connection->message.length); + variable_header = (struct mqtt_connect_variable_header*)(connection->buffer + connection->message.length); connection->message.length += sizeof(*variable_header); variable_header->lengthMsb = 0; diff --git a/mqtt/utils.c b/mqtt/utils.c index ac4c927..361ab60 100644 --- a/mqtt/utils.c +++ b/mqtt/utils.c @@ -38,7 +38,7 @@ #include "utils.h" -uint8_t ICACHE_FLASH_ATTR UTILS_IsIPV4 (int8_t *str) +uint8_t ICACHE_FLASH_ATTR UTILS_IsIPV4(const char *str) { uint8_t segs = 0; /* Segment count. */ uint8_t chcnt = 0; /* Character count within segment. */ @@ -88,9 +88,9 @@ uint8_t ICACHE_FLASH_ATTR UTILS_IsIPV4 (int8_t *str) return 1; } -uint8_t ICACHE_FLASH_ATTR UTILS_StrToIP(const int8_t* str, void *ip) -{ +uint8_t ICACHE_FLASH_ATTR UTILS_StrToIP(const char *str, void *ip) +{ /* The count of the number of bytes processed. */ int i; /* A pointer to the next digit to process. */ @@ -127,7 +127,8 @@ uint8_t ICACHE_FLASH_ATTR UTILS_StrToIP(const int8_t* str, void *ip) return 1; } -uint32_t ICACHE_FLASH_ATTR UTILS_Atoh(const int8_t *s) + +uint32_t ICACHE_FLASH_ATTR UTILS_Atoh(const char *s) { uint32_t value = 0, digit; int8_t c; @@ -146,4 +147,3 @@ uint32_t ICACHE_FLASH_ATTR UTILS_Atoh(const int8_t *s) return value; } -