From 885bde3af9c628b9977a26f71eae8e33d942397a Mon Sep 17 00:00:00 2001 From: Jeff H Date: Sun, 20 Nov 2016 01:12:37 -0800 Subject: [PATCH] Extend init method to allow 0-length client IDs if MQTTv311 is set --- mqtt/include/mqtt.h | 2 +- mqtt/mqtt.c | 44 +++++++++++++++++++++++++++++++++++++++----- mqtt/mqtt_msg.c | 22 ++++++++++++++++++---- user/user_main.c | 6 +++++- 4 files changed, 63 insertions(+), 11 deletions(-) diff --git a/mqtt/include/mqtt.h b/mqtt/include/mqtt.h index f026319..c33d471 100644 --- a/mqtt/include/mqtt.h +++ b/mqtt/include/mqtt.h @@ -131,7 +131,7 @@ typedef struct { #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); -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); +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_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_OnConnected(MQTT_Client *mqttClient, MqttCallback connectedCb); diff --git a/mqtt/mqtt.c b/mqtt/mqtt.c index 60d0cf3..c010c65 100644 --- a/mqtt/mqtt.c +++ b/mqtt/mqtt.c @@ -59,6 +59,10 @@ 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 }; +#endif + LOCAL void ICACHE_FLASH_ATTR mqtt_dns_found(const char *name, ip_addr_t *ipaddr, void *arg) { @@ -227,7 +231,13 @@ 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 ) + os_free(mqttClient->connect_info.client_id); +#else os_free(mqttClient->connect_info.client_id); +#endif mqttClient->connect_info.client_id = NULL; } @@ -786,7 +796,7 @@ MQTT_InitConnection(MQTT_Client *mqttClient, uint8_t* host, uint32_t port, uint8 * @param client_pass:MQTT keep alive timer, in second * @retval None */ -void ICACHE_FLASH_ATTR +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) { uint32_t temp; @@ -794,10 +804,33 @@ MQTT_InitClient(MQTT_Client *mqttClient, uint8_t* client_id, uint8_t* client_use os_memset(&mqttClient->connect_info, 0, sizeof(mqtt_connect_info_t)); - temp = os_strlen(client_id); - mqttClient->connect_info.client_id = (uint8_t*)os_zalloc(temp + 1); - os_strcpy(mqttClient->connect_info.client_id, client_id); - mqttClient->connect_info.client_id[temp] = 0; + if ( !client_id ) + { + /* Should be allowed by broker, but clean session flag must be set. */ + #ifdef PROTOCOL_NAMEv311 + if (cleanSession) + { + mqttClient->connect_info.client_id = zero_len_id; + } else { + MQTT_INFO("cleanSession must be set to use 0 length client_id\r\n"); + return false; + } + /* Not supported. Return. */ + #else + MQTT_INFO("Client ID required for MQTT < 3.1.1!\r\n"); + return false; + #endif + } + + /* 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) ) + { + temp = os_strlen(client_id); + mqttClient->connect_info.client_id = (uint8_t*)os_zalloc(temp + 1); + os_strcpy(mqttClient->connect_info.client_id, client_id); + mqttClient->connect_info.client_id[temp] = 0; + } if (client_user) { @@ -831,6 +864,7 @@ MQTT_InitClient(MQTT_Client *mqttClient, uint8_t* client_id, uint8_t* client_use system_os_task(MQTT_Task, MQTT_TASK_PRIO, mqtt_procTaskQueue, MQTT_TASK_QUEUE_SIZE); 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) diff --git a/mqtt/mqtt_msg.c b/mqtt/mqtt_msg.c index 565322a..57dcbac 100644 --- a/mqtt/mqtt_msg.c +++ b/mqtt/mqtt_msg.c @@ -319,13 +319,27 @@ mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_connect(mqtt_connection_t* connection if (info->clean_session) variable_header->flags |= MQTT_CONNECT_FLAG_CLEAN_SESSION; - if (info->client_id != NULL && info->client_id[0] != '\0') + if (info->client_id == NULL) { - if (append_string(connection, info->client_id, strlen(info->client_id)) < 0) - return fail_message(connection); + /* Never allowed */ + return fail_message(connection); + } + else if (info->client_id[0] == '\0') + { +#ifdef PROTOCOL_NAMEv311 + /* Allowed. Format 0 Length ID */ + append_string(connection, info->client_id, 2) ; +#else + /* 0 Length not allowed */ + return fail_message(connection); +#endif } else - return fail_message(connection); + { + /* No 0 data and at least 1 long. Good to go. */ + if(append_string(connection, info->client_id, strlen(info->client_id)) < 0) + return fail_message(connection); + } if (info->will_topic != NULL && info->will_topic[0] != '\0') { diff --git a/user/user_main.c b/user/user_main.c index 8436b6a..e10959a 100644 --- a/user/user_main.c +++ b/user/user_main.c @@ -109,7 +109,11 @@ static void ICACHE_FLASH_ATTR app_init(void) MQTT_InitConnection(&mqttClient, MQTT_HOST, MQTT_PORT, DEFAULT_SECURITY); //MQTT_InitConnection(&mqttClient, "192.168.11.122", 1880, 0); - MQTT_InitClient(&mqttClient, MQTT_CLIENT_ID, MQTT_USER, MQTT_PASS, MQTT_KEEPALIVE, MQTT_CLEAN_SESSION); + if ( !MQTT_InitClient(&mqttClient, MQTT_CLIENT_ID, MQTT_USER, MQTT_PASS, MQTT_KEEPALIVE, MQTT_CLEAN_SESSION) ) + { + INFO("Failed to initialize properly. Check MQTT version.\r\n"); + return; + } //MQTT_InitClient(&mqttClient, "client_id", "user", "pass", 120, 1); MQTT_InitLWT(&mqttClient, "/lwt", "offline", 0, 0); MQTT_OnConnected(&mqttClient, mqttConnectedCb);