polish mqtt module

This commit is contained in:
funshine 2015-03-31 23:38:28 +08:00
parent dcb6e53af7
commit 32e062f523
5 changed files with 79 additions and 16 deletions

View File

@ -36,6 +36,12 @@ Tencent QQ group: 309957875<br />
- cross compiler (done) - cross compiler (done)
# Change log # Change log
2015-03-31<br />
polish mqtt module, add queue for mqtt module.<br />
add reconnect option to mqtt.connect api, :connect( host, port, secure, auto_reconnect, function(client) )<br />
move node.readvdd33 to adc.readvdd33.<br />
tools/esptool.py supported NodeMCU devkit automatic flash.
2015-03-18<br /> 2015-03-18<br />
update u8glib.<br /> update u8glib.<br />
merge everything to master. merge everything to master.

View File

@ -231,7 +231,7 @@ READPACKET:
msg_qos = mqtt_get_qos(mud->mqtt_state.in_buffer); msg_qos = mqtt_get_qos(mud->mqtt_state.in_buffer);
msg_id = mqtt_get_id(mud->mqtt_state.in_buffer, mud->mqtt_state.in_buffer_length); msg_id = mqtt_get_id(mud->mqtt_state.in_buffer, mud->mqtt_state.in_buffer_length);
msg_queue_t *pending_msg = mud->mqtt_state.pending_msg_q; msg_queue_t *pending_msg = msg_peek(&(mud->mqtt_state.pending_msg_q));
NODE_DBG("MQTT_DATA: type: %d, qos: %d, msg_id: %d, pending_id: %d\r\n", NODE_DBG("MQTT_DATA: type: %d, qos: %d, msg_id: %d, pending_id: %d\r\n",
msg_type, msg_type,
@ -263,12 +263,12 @@ READPACKET:
if(msg_qos == 1){ if(msg_qos == 1){
mud->mqtt_state.outbound_message = mqtt_msg_puback(&mud->mqtt_state.mqtt_connection, msg_id); mud->mqtt_state.outbound_message = mqtt_msg_puback(&mud->mqtt_state.mqtt_connection, msg_id);
node = msg_enqueue(&(mud->mqtt_state.pending_msg_q), mud->mqtt_state.outbound_message, node = msg_enqueue(&(mud->mqtt_state.pending_msg_q), mud->mqtt_state.outbound_message,
msg_id, MQTT_MSG_TYPE_PUBACK, (int)msg_qos ); msg_id, MQTT_MSG_TYPE_PUBACK, 0 );
} }
else if(msg_qos == 2){ else if(msg_qos == 2){
mud->mqtt_state.outbound_message = mqtt_msg_pubrec(&mud->mqtt_state.mqtt_connection, msg_id); mud->mqtt_state.outbound_message = mqtt_msg_pubrec(&mud->mqtt_state.mqtt_connection, msg_id);
node = msg_enqueue(&(mud->mqtt_state.pending_msg_q), mud->mqtt_state.outbound_message, node = msg_enqueue(&(mud->mqtt_state.pending_msg_q), mud->mqtt_state.outbound_message,
msg_id, MQTT_MSG_TYPE_PUBREC, (int)msg_qos ); msg_id, MQTT_MSG_TYPE_PUBREC, 0 );
} }
if(msg_qos == 1 || msg_qos == 2){ if(msg_qos == 1 || msg_qos == 2){
NODE_DBG("MQTT: Queue response QoS: %d\r\n", msg_qos); NODE_DBG("MQTT: Queue response QoS: %d\r\n", msg_qos);
@ -290,19 +290,27 @@ READPACKET:
break; break;
case MQTT_MSG_TYPE_PUBREC: case MQTT_MSG_TYPE_PUBREC:
if(pending_msg && pending_msg->msg_type == MQTT_MSG_TYPE_PUBLISH && pending_msg->msg_id == msg_id){
NODE_DBG("MQTT: Publish with QoS = 2 Received PUBREC\r\n");
// Note: actrually, should not destroy the msg until PUBCOMP is received.
msg_destroy(msg_dequeue(&(mud->mqtt_state.pending_msg_q)));
mud->mqtt_state.outbound_message = mqtt_msg_pubrel(&mud->mqtt_state.mqtt_connection, msg_id); mud->mqtt_state.outbound_message = mqtt_msg_pubrel(&mud->mqtt_state.mqtt_connection, msg_id);
node = msg_enqueue(&(mud->mqtt_state.pending_msg_q), mud->mqtt_state.outbound_message, node = msg_enqueue(&(mud->mqtt_state.pending_msg_q), mud->mqtt_state.outbound_message,
msg_id, MQTT_MSG_TYPE_PUBREL, (int)msg_qos ); msg_id, MQTT_MSG_TYPE_PUBREL, 1 );
NODE_DBG("MQTT: Response PUBREL\r\n"); NODE_DBG("MQTT: Response PUBREL\r\n");
}
break; break;
case MQTT_MSG_TYPE_PUBREL: case MQTT_MSG_TYPE_PUBREL:
if(pending_msg && pending_msg->msg_type == MQTT_MSG_TYPE_PUBREC && pending_msg->msg_id == msg_id){
msg_destroy(msg_dequeue(&(mud->mqtt_state.pending_msg_q)));
mud->mqtt_state.outbound_message = mqtt_msg_pubcomp(&mud->mqtt_state.mqtt_connection, msg_id); mud->mqtt_state.outbound_message = mqtt_msg_pubcomp(&mud->mqtt_state.mqtt_connection, msg_id);
node = msg_enqueue(&(mud->mqtt_state.pending_msg_q), mud->mqtt_state.outbound_message, node = msg_enqueue(&(mud->mqtt_state.pending_msg_q), mud->mqtt_state.outbound_message,
msg_id, MQTT_MSG_TYPE_PUBCOMP, (int)msg_qos ); msg_id, MQTT_MSG_TYPE_PUBCOMP, 0 );
NODE_DBG("MQTT: Response PUBCOMP\r\n"); NODE_DBG("MQTT: Response PUBCOMP\r\n");
}
break; break;
case MQTT_MSG_TYPE_PUBCOMP: case MQTT_MSG_TYPE_PUBCOMP:
if(pending_msg && pending_msg->msg_type == MQTT_MSG_TYPE_PUBLISH && pending_msg->msg_id == msg_id){ if(pending_msg && pending_msg->msg_type == MQTT_MSG_TYPE_PUBREL && pending_msg->msg_id == msg_id){
NODE_DBG("MQTT: Publish with QoS = 2 successful\r\n"); NODE_DBG("MQTT: Publish with QoS = 2 successful\r\n");
msg_destroy(msg_dequeue(&(mud->mqtt_state.pending_msg_q))); msg_destroy(msg_dequeue(&(mud->mqtt_state.pending_msg_q)));
if(mud->cb_puback_ref == LUA_NOREF) if(mud->cb_puback_ref == LUA_NOREF)
@ -317,7 +325,7 @@ READPACKET:
case MQTT_MSG_TYPE_PINGREQ: case MQTT_MSG_TYPE_PINGREQ:
mud->mqtt_state.outbound_message = mqtt_msg_pingresp(&mud->mqtt_state.mqtt_connection); mud->mqtt_state.outbound_message = mqtt_msg_pingresp(&mud->mqtt_state.mqtt_connection);
node = msg_enqueue(&(mud->mqtt_state.pending_msg_q), mud->mqtt_state.outbound_message, node = msg_enqueue(&(mud->mqtt_state.pending_msg_q), mud->mqtt_state.outbound_message,
msg_id, MQTT_MSG_TYPE_PINGRESP, (int)msg_qos ); msg_id, MQTT_MSG_TYPE_PINGRESP, 1 );
NODE_DBG("MQTT: Response PINGRESP\r\n"); NODE_DBG("MQTT: Response PINGRESP\r\n");
break; break;
case MQTT_MSG_TYPE_PINGRESP: case MQTT_MSG_TYPE_PINGRESP:
@ -345,7 +353,7 @@ READPACKET:
break; break;
} }
if(node && (mud->mqtt_state.pending_msg_q->next == NULL) && mud->event_timeout == 0){ if(node && (1==msg_size(&(mud->mqtt_state.pending_msg_q))) && mud->event_timeout == 0){
mud->event_timeout = MQTT_SEND_TIMEOUT; mud->event_timeout = MQTT_SEND_TIMEOUT;
NODE_DBG("Sent: %d\n", node->msg.length); NODE_DBG("Sent: %d\n", node->msg.length);
if( mud->secure ) if( mud->secure )
@ -355,6 +363,7 @@ READPACKET:
mud->keep_alive_tick = 0; mud->keep_alive_tick = 0;
mud->mqtt_state.outbound_message = NULL; mud->mqtt_state.outbound_message = NULL;
} }
NODE_DBG("receive, queue size: %d\n", msg_size(&(mud->mqtt_state.pending_msg_q)));
NODE_DBG("leave mqtt_socket_received.\n"); NODE_DBG("leave mqtt_socket_received.\n");
return; return;
} }
@ -376,9 +385,9 @@ static void mqtt_socket_sent(void *arg)
// call mqtt_sent() // call mqtt_sent()
mud->event_timeout = 0; mud->event_timeout = 0;
NODE_DBG("sent1, queue size: %d\n", msg_size(&(mud->mqtt_state.pending_msg_q)));
// qos = 0, publish and forgot. // qos = 0, publish and forgot.
msg_queue_t *node = mud->mqtt_state.pending_msg_q; msg_queue_t *node = msg_peek(&(mud->mqtt_state.pending_msg_q));
if(node && node->msg_type == MQTT_MSG_TYPE_PUBLISH && node->publish_qos == 0) { if(node && node->msg_type == MQTT_MSG_TYPE_PUBLISH && node->publish_qos == 0) {
msg_destroy(msg_dequeue(&(mud->mqtt_state.pending_msg_q))); msg_destroy(msg_dequeue(&(mud->mqtt_state.pending_msg_q)));
if(mud->cb_puback_ref == LUA_NOREF) if(mud->cb_puback_ref == LUA_NOREF)
@ -388,7 +397,14 @@ static void mqtt_socket_sent(void *arg)
lua_rawgeti(gL, LUA_REGISTRYINDEX, mud->cb_puback_ref); lua_rawgeti(gL, LUA_REGISTRYINDEX, mud->cb_puback_ref);
lua_rawgeti(gL, LUA_REGISTRYINDEX, mud->self_ref); // pass the userdata to callback func in lua lua_rawgeti(gL, LUA_REGISTRYINDEX, mud->self_ref); // pass the userdata to callback func in lua
lua_call(gL, 1, 0); lua_call(gL, 1, 0);
} else if(node && node->msg_type == MQTT_MSG_TYPE_PUBACK && node->publish_qos == 1) {
msg_destroy(msg_dequeue(&(mud->mqtt_state.pending_msg_q)));
} else if(node && node->msg_type == MQTT_MSG_TYPE_PUBCOMP) {
msg_destroy(msg_dequeue(&(mud->mqtt_state.pending_msg_q)));
} else if(node && node->msg_type == MQTT_MSG_TYPE_PINGRESP) {
msg_destroy(msg_dequeue(&(mud->mqtt_state.pending_msg_q)));
} }
NODE_DBG("sent2, queue size: %d\n", msg_size(&(mud->mqtt_state.pending_msg_q)));
NODE_DBG("leave mqtt_socket_sent.\n"); NODE_DBG("leave mqtt_socket_sent.\n");
} }
@ -423,16 +439,21 @@ static void mqtt_socket_connected(void *arg)
void mqtt_socket_timer(void *arg) void mqtt_socket_timer(void *arg)
{ {
// NODE_DBG("enter mqtt_socket_timer.\n"); NODE_DBG("enter mqtt_socket_timer.\n");
lmqtt_userdata *mud = (lmqtt_userdata*) arg; lmqtt_userdata *mud = (lmqtt_userdata*) arg;
if(mud == NULL) if(mud == NULL)
return; return;
NODE_DBG("timer, queue size: %d\n", msg_size(&(mud->mqtt_state.pending_msg_q)));
if(mud->event_timeout > 0){ if(mud->event_timeout > 0){
NODE_DBG("event_timeout: %d.\n", mud->event_timeout); NODE_DBG("event_timeout: %d.\n", mud->event_timeout);
mud->event_timeout --; mud->event_timeout --;
if(mud->event_timeout > 0){ if(mud->event_timeout > 0){
return; return;
} else {
NODE_DBG("event timeout. \n");
// should remove the head of the queue and re-send with DUP = 1
// Not implemented yet.
} }
} }
@ -453,7 +474,7 @@ void mqtt_socket_timer(void *arg)
} else if(mud->connState == MQTT_CONNECT_SENT){ // wait for CONACK time out. } else if(mud->connState == MQTT_CONNECT_SENT){ // wait for CONACK time out.
NODE_DBG("MQTT_CONNECT failed.\n"); NODE_DBG("MQTT_CONNECT failed.\n");
} else if(mud->connState == MQTT_DATA){ } else if(mud->connState == MQTT_DATA){
msg_queue_t *pending_msg = mud->mqtt_state.pending_msg_q; msg_queue_t *pending_msg = msg_peek(&(mud->mqtt_state.pending_msg_q));
if(pending_msg){ if(pending_msg){
mud->event_timeout = MQTT_SEND_TIMEOUT; mud->event_timeout = MQTT_SEND_TIMEOUT;
if(mud->secure) if(mud->secure)
@ -477,7 +498,7 @@ void mqtt_socket_timer(void *arg)
} }
} }
} }
// NODE_DBG("leave mqtt_socket_timer.\n"); NODE_DBG("leave mqtt_socket_timer.\n");
} }
// Lua: mqtt.Client(clientid, keepalive, user, pass) // Lua: mqtt.Client(clientid, keepalive, user, pass)
@ -1057,7 +1078,7 @@ static int mqtt_socket_subscribe( lua_State* L ) {
NODE_DBG("topic: %s - id: %d - qos: %d, length: %d\n", topic, node->msg_id, node->publish_qos, node->msg.length); NODE_DBG("topic: %s - id: %d - qos: %d, length: %d\n", topic, node->msg_id, node->publish_qos, node->msg.length);
if(node && (mud->mqtt_state.pending_msg_q->next == NULL) && mud->event_timeout == 0){ if(node && (1==msg_size(&(mud->mqtt_state.pending_msg_q))) && mud->event_timeout == 0){
mud->event_timeout = MQTT_SEND_TIMEOUT; mud->event_timeout = MQTT_SEND_TIMEOUT;
NODE_DBG("Sent: %d\n", node->msg.length); NODE_DBG("Sent: %d\n", node->msg.length);
if( mud->secure ) if( mud->secure )
@ -1073,6 +1094,7 @@ static int mqtt_socket_subscribe( lua_State* L ) {
lua_pushboolean(L, 1); // enqueued succeed. lua_pushboolean(L, 1); // enqueued succeed.
} }
mud->mqtt_state.outbound_message = NULL; mud->mqtt_state.outbound_message = NULL;
NODE_DBG("subscribe, queue size: %d\n", msg_size(&(mud->mqtt_state.pending_msg_q)));
NODE_DBG("leave mqtt_socket_subscribe.\n"); NODE_DBG("leave mqtt_socket_subscribe.\n");
return 1; return 1;
} }
@ -1133,7 +1155,7 @@ static int mqtt_socket_publish( lua_State* L )
msg_queue_t *node = msg_enqueue(&(mud->mqtt_state.pending_msg_q), mud->mqtt_state.outbound_message, msg_queue_t *node = msg_enqueue(&(mud->mqtt_state.pending_msg_q), mud->mqtt_state.outbound_message,
msg_id, MQTT_MSG_TYPE_PUBLISH, (int)qos ); msg_id, MQTT_MSG_TYPE_PUBLISH, (int)qos );
if(node && (mud->mqtt_state.pending_msg_q->next == NULL) && mud->event_timeout == 0){ if(node && (1==msg_size(&(mud->mqtt_state.pending_msg_q))) && mud->event_timeout == 0){
mud->event_timeout = MQTT_SEND_TIMEOUT; mud->event_timeout = MQTT_SEND_TIMEOUT;
NODE_DBG("Sent: %d\n", node->msg.length); NODE_DBG("Sent: %d\n", node->msg.length);
if( mud->secure ) if( mud->secure )
@ -1149,6 +1171,7 @@ static int mqtt_socket_publish( lua_State* L )
lua_pushboolean(L, 1); // enqueued succeed. lua_pushboolean(L, 1); // enqueued succeed.
} }
mud->mqtt_state.outbound_message = NULL; mud->mqtt_state.outbound_message = NULL;
NODE_DBG("publish, queue size: %d\n", msg_size(&(mud->mqtt_state.pending_msg_q)));
NODE_DBG("leave mqtt_socket_publish.\n"); NODE_DBG("leave mqtt_socket_publish.\n");
return 1; return 1;
} }

View File

@ -58,3 +58,25 @@ msg_queue_t * msg_dequeue(msg_queue_t **head){
node->next = NULL; node->next = NULL;
return node; return node;
} }
msg_queue_t * msg_peek(msg_queue_t **head){
if(!head || !*head){
return NULL;
}
return *head; // fetch head.
}
int msg_size(msg_queue_t **head){
if(!head || !*head){
return 0;
}
int i = 1;
msg_queue_t *tail = *head;
if(tail){
while(tail->next!=NULL){
tail = tail->next;
i++;
}
}
return i;
}

View File

@ -18,6 +18,8 @@ typedef struct msg_queue_t {
msg_queue_t * msg_enqueue(msg_queue_t **head, mqtt_message_t *msg, uint16_t msg_id, int msg_type, int publish_qos); msg_queue_t * msg_enqueue(msg_queue_t **head, mqtt_message_t *msg, uint16_t msg_id, int msg_type, int publish_qos);
void msg_destroy(msg_queue_t *node); void msg_destroy(msg_queue_t *node);
msg_queue_t * msg_dequeue(msg_queue_t **head); msg_queue_t * msg_dequeue(msg_queue_t **head);
msg_queue_t * msg_peek(msg_queue_t **head);
int msg_size(msg_queue_t **head);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -418,7 +418,7 @@ m:publish("/topic1","hello",0,0)
m:publish("/topic3","hello",0,0) m:publish("/topic4","hello",0,0) m:publish("/topic3","hello",0,0) m:publish("/topic4","hello",0,0)
m:publish("/topic1","hello1",0,0) m:publish("/topic2","hello2",0,0) m:publish("/topic1","hello1",0,0) m:publish("/topic2","hello2",0,0)
m:publish("/topic1","hello",1,0) m:publish("/topic1","hello",1,0)
m:subscribe("/topic3",2,function(m) print("sub done") end) m:subscribe("/topic3",0,function(m) print("sub done") end)
m:publish("/topic3","hello3",2,0) m:publish("/topic3","hello3",2,0)
m=mqtt.Client() m=mqtt.Client()
@ -450,3 +450,13 @@ end)
m:connect("192.168.18.88",1883) m:connect("192.168.18.88",1883)
m:close() m:close()
m=mqtt.Client()
m:connect("192.168.18.88",1883)
m:on("message",function(m,t,pl) print(t..":") if pl~=nil then print(pl) end end )
m:subscribe("/topic1",0,function(m) print("sub done") end)
m:publish("/topic1","hello3",2,0) m:publish("/topic1","hello2",2,0)
m:publish("/topic1","hello3",0,0) m:publish("/topic1","hello2",2,0)
m:subscribe("/topic2",2,function(m) print("sub done") end)
m:publish("/topic2","hello3",0,0) m:publish("/topic2","hello2",2,0)