// Lua: mqtt:close() // client disconnect and unref itself static int mqtt_socket_close( lua_State* L ) { NODE_DBG("enter mqtt_socket_close.\n"); int i = 0; lmqtt_userdata *mud = NULL; mud = (lmqtt_userdata *)luaL_checkudata(L, 1, "mqtt.socket"); luaL_argcheck(L, mud, 1, "mqtt.socket expected"); if(mud == NULL) return 0; if(mud->pesp_conn == NULL) return 0; // call mqtt_disconnect() mud->mqtt_state.auto_reconnect = 0; // stop auto reconnect. if(mud->secure){ if(mud->pesp_conn->proto.tcp->remote_port || mud->pesp_conn->proto.tcp->local_port) espconn_secure_disconnect(mud->pesp_conn); } else { if(mud->pesp_conn->proto.tcp->remote_port || mud->pesp_conn->proto.tcp->local_port) espconn_disconnect(mud->pesp_conn); } NODE_DBG("leave mqtt_socket_close.\n"); return 0; }
static void ICACHE_FLASH_ATTR receive_callback(void * arg, char * buf, unsigned short len) { struct espconn * conn = (struct espconn *)arg; request_args * req = (request_args *)conn->reverse; if (req->buffer == NULL) { return; } // Let's do the equivalent of a realloc(). const int new_size = req->buffer_size + len; char * new_buffer; if (new_size > BUFFER_SIZE_MAX || NULL == (new_buffer = (char *)os_malloc(new_size))) { os_printf("Response too long (%d)\n", new_size); req->buffer[0] = '\0'; // Discard the buffer to avoid using an incomplete response. if (req->secure) espconn_secure_disconnect(conn); else espconn_disconnect(conn); return; // The disconnect callback will be called. } os_memcpy(new_buffer, req->buffer, req->buffer_size); os_memcpy(new_buffer + req->buffer_size - 1 /*overwrite the null character*/, buf, len); // Append new data. new_buffer[new_size - 1] = '\0'; // Make sure there is an end of string. os_free(req->buffer); req->buffer = new_buffer; req->buffer_size = new_size; }
/****************************************************************************** * FunctionName : user_upgrade_check * Description : Processing the received data from the server * Parameters : arg -- Additional argument to pass to the callback function * pusrdata -- The received data (or NULL when the connection has been closed!) * length -- The length of received data * Returns : none *******************************************************************************/ LOCAL void ICACHE_FLASH_ATTR upgrade_check(struct upgrade_server_info *server) { UPGRADE_DBG("upgrade_check\n"); if (system_upgrade_flag_check() != UPGRADE_FLAG_FINISH) { totallength = 0; sumlength = 0; os_timer_disarm(&upgrade_timer); system_upgrade_flag_set(UPGRADE_FLAG_IDLE); upgrade_deinit(); server->upgrade_flag = false; if (server->check_cb != NULL) { server->check_cb(server); } } else { os_timer_disarm(&upgrade_timer); upgrade_deinit(); server->upgrade_flag = true; if (server->check_cb != NULL) { server->check_cb(server); } } #ifdef UPGRADE_SSL_ENABLE espconn_secure_disconnect(upgrade_conn); #else espconn_disconnect(upgrade_conn); #endif }
void ICACHE_FLASH_ATTR net_asyncDisconnect(NetConnection* conn) { uart0_tx_buffer("disconnect\r\n", 12); HTTPESP8266ConnectionData* driver = esp8266_getConnection(conn); //esp8266_destroyConnection(conn); //conn->disconnectCallback(conn->userData, net_ok); if(driver->secure) espconn_secure_disconnect(&driver->connection); else espconn_disconnect(&driver->connection); }
/** * @brief after sending (version) request, wait for reply timeout * we do not received right answer, close connection * @param arg: contain the ip link information * @retval None */ LOCAL void ICACHE_FLASH_ATTR get_version_timeout(void *arg) { struct espconn *pespconn = arg; fota_client_t *fota_client = (fota_client_t *)pespconn->reverse; os_timer_disarm(&fota_client->request_timeout); INFO("FOTA Client: Request timeout, close connection\n"); if (FOTA_SECURE) espconn_secure_disconnect(pespconn); else espconn_disconnect(pespconn); }
static int tls_socket_close( lua_State *L ) { tls_socket_ud *ud = (tls_socket_ud *)luaL_checkudata(L, 1, "tls.socket"); luaL_argcheck(L, ud, 1, "TLS socket expected"); if(ud==NULL){ NODE_DBG("userdata is nil.\n"); return 0; } if (ud->pesp_conn) { espconn_secure_disconnect(ud->pesp_conn); } return 0; }
static void tls_socket_cleanup(tls_socket_ud *ud) { if (ud->pesp_conn) { espconn_secure_disconnect(ud->pesp_conn); if (ud->pesp_conn->proto.tcp) { c_free(ud->pesp_conn->proto.tcp); ud->pesp_conn->proto.tcp = NULL; } c_free(ud->pesp_conn); ud->pesp_conn = NULL; } lua_State *L = lua_getstate(); lua_gc(L, LUA_GCSTOP, 0); luaL_unref(L, LUA_REGISTRYINDEX, ud->self_ref); ud->self_ref = LUA_NOREF; lua_gc(L, LUA_GCRESTART, 0); }
static void ICACHE_FLASH_ATTR mqtt_doAbort(MQTT_Client* client) { os_printf("MQTT: Disconnecting from %s:%d (%p)\n", client->host, client->port, client->pCon); client->pCon->reverse = NULL; // ensure we jettison this pCon... if (client->security) espconn_secure_disconnect(client->pCon); else espconn_disconnect(client->pCon); if (client->disconnectedCb) client->disconnectedCb((uint32_t*)client); if (client->cmdDisconnectedCb) client->cmdDisconnectedCb((uint32_t*)client); if (client->sending_buffer != NULL) { os_free(client->sending_buffer); client->sending_buffer = NULL; } client->pCon = NULL; // it will be freed in disconnect callback client->connState = TCP_RECONNECT_REQ; client->timeoutTick = client->reconTimeout; // reconnect in a few seconds if (client->reconTimeout < 128) client->reconTimeout <<= 1; }
void ICACHE_FLASH_ATTR get_version_recon_cb(void *arg, sint8 err) { //error occured , tcp connection broke. user can try to reconnect here. INFO("FOTA Client: reconnect callback, code %d\n", err); struct espconn *pespconn = arg; fota_client_t *fota_client = (fota_client_t *)pespconn->reverse; if (fota_client->status != FOTA_GETTING_FIRMWARE) fota_client->status = FOTA_IDLE; INFO("State of esp conn: %d\n", pespconn->state); if (FOTA_SECURE) espconn_secure_disconnect((struct espconn *)arg); else espconn_disconnect((struct espconn *)arg); // when host failed to connect, disconnect will not work, // need to clean connection to avoid mem leak clear_espconn(pespconn); }
static int tls_socket_delete( lua_State *L ) { tls_socket_ud *ud = (tls_socket_ud *)luaL_checkudata(L, 1, "tls.socket"); luaL_argcheck(L, ud, 1, "TLS socket expected"); if(ud==NULL){ NODE_DBG("userdata is nil.\n"); return 0; } if (ud->pesp_conn) { espconn_secure_disconnect(ud->pesp_conn); if (ud->pesp_conn->proto.tcp) { c_free(ud->pesp_conn->proto.tcp); ud->pesp_conn->proto.tcp = NULL; } c_free(ud->pesp_conn); ud->pesp_conn = NULL; } luaL_unref(L, LUA_REGISTRYINDEX, ud->cb_connect_ref); ud->cb_connect_ref = LUA_NOREF; luaL_unref(L, LUA_REGISTRYINDEX, ud->cb_disconnect_ref); ud->cb_disconnect_ref = LUA_NOREF; luaL_unref(L, LUA_REGISTRYINDEX, ud->cb_reconnect_ref); ud->cb_reconnect_ref = LUA_NOREF; luaL_unref(L, LUA_REGISTRYINDEX, ud->cb_dns_ref); ud->cb_dns_ref = LUA_NOREF; luaL_unref(L, LUA_REGISTRYINDEX, ud->cb_receive_ref); ud->cb_receive_ref = LUA_NOREF; luaL_unref(L, LUA_REGISTRYINDEX, ud->cb_sent_ref); ud->cb_sent_ref = LUA_NOREF; lua_gc(L, LUA_GCSTOP, 0); luaL_unref(L, LUA_REGISTRYINDEX, ud->self_ref); ud->self_ref = LUA_NOREF; lua_gc(L, LUA_GCRESTART, 0); return 0; }
/** * @brief Client received callback function. * @param arg: contain the ip link information * @param pdata: received data * @param len: the lenght of received data * @retval None */ void ICACHE_FLASH_ATTR mqtt_tcpclient_recv(void *arg, char *pdata, unsigned short len) { uint8_t msg_type; uint8_t msg_qos; uint16_t msg_id; struct espconn *pCon = (struct espconn*)arg; MQTT_Client *client = (MQTT_Client *)pCon->reverse; READPACKET: INFO("TCP: data received %d bytes\r\n", len); if(len < MQTT_BUF_SIZE && len > 0){ os_memcpy(client->mqtt_state.in_buffer, pdata, len); msg_type = mqtt_get_type(client->mqtt_state.in_buffer); msg_qos = mqtt_get_qos(client->mqtt_state.in_buffer); msg_id = mqtt_get_id(client->mqtt_state.in_buffer, client->mqtt_state.in_buffer_length); switch(client->connState){ case MQTT_CONNECT_SENDING: if(msg_type == MQTT_MSG_TYPE_CONNACK){ if(client->mqtt_state.pending_msg_type != MQTT_MSG_TYPE_CONNECT){ INFO("MQTT: Invalid packet\r\n"); if(client->security){ espconn_secure_disconnect(client->pCon); } else { espconn_disconnect(client->pCon); } } else { INFO("MQTT: Connected to %s:%d\r\n", client->host, client->port); client->connState = MQTT_DATA; if(client->connectedCb) client->connectedCb((uint32_t*)client); } } break; case MQTT_DATA: client->mqtt_state.message_length_read = len; client->mqtt_state.message_length = mqtt_get_total_length(client->mqtt_state.in_buffer, client->mqtt_state.message_length_read); 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) INFO("MQTT: Subscribe successful\r\n"); break; case MQTT_MSG_TYPE_UNSUBACK: if(client->mqtt_state.pending_msg_type == MQTT_MSG_TYPE_UNSUBSCRIBE && client->mqtt_state.pending_msg_id == msg_id) INFO("MQTT: UnSubscribe successful\r\n"); break; case MQTT_MSG_TYPE_PUBLISH: if(msg_qos == 1) client->mqtt_state.outbound_message = mqtt_msg_puback(&client->mqtt_state.mqtt_connection, msg_id); else if(msg_qos == 2) client->mqtt_state.outbound_message = mqtt_msg_pubrec(&client->mqtt_state.mqtt_connection, msg_id); if(msg_qos == 1 || msg_qos == 2){ INFO("MQTT: Queue response QoS: %d\r\n", msg_qos); if(QUEUE_Puts(&client->msgQueue, client->mqtt_state.outbound_message->data, client->mqtt_state.outbound_message->length) == -1){ INFO("MQTT: Queue full\r\n"); } } deliver_publish(client, client->mqtt_state.in_buffer, client->mqtt_state.message_length_read); break; case MQTT_MSG_TYPE_PUBACK: if(client->mqtt_state.pending_msg_type == MQTT_MSG_TYPE_PUBLISH && client->mqtt_state.pending_msg_id == msg_id){ 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); if(QUEUE_Puts(&client->msgQueue, client->mqtt_state.outbound_message->data, client->mqtt_state.outbound_message->length) == -1){ INFO("MQTT: Queue full\r\n"); } break; case MQTT_MSG_TYPE_PUBREL: client->mqtt_state.outbound_message = mqtt_msg_pubcomp(&client->mqtt_state.mqtt_connection, msg_id); if(QUEUE_Puts(&client->msgQueue, client->mqtt_state.outbound_message->data, client->mqtt_state.outbound_message->length) == -1){ INFO("MQTT: Queue full\r\n"); } break; case MQTT_MSG_TYPE_PUBCOMP: if(client->mqtt_state.pending_msg_type == MQTT_MSG_TYPE_PUBLISH && client->mqtt_state.pending_msg_id == msg_id){ INFO("MQTT: receive MQTT_MSG_TYPE_PUBCOMP, finish QoS2 publish\r\n"); } break; case MQTT_MSG_TYPE_PINGREQ: client->mqtt_state.outbound_message = mqtt_msg_pingresp(&client->mqtt_state.mqtt_connection); if(QUEUE_Puts(&client->msgQueue, client->mqtt_state.outbound_message->data, client->mqtt_state.outbound_message->length) == -1){ INFO("MQTT: Queue full\r\n"); } break; case MQTT_MSG_TYPE_PINGRESP: // Ignore break; } // 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) { len = 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; pdata += client->mqtt_state.message_length; INFO("Get another published message\r\n"); goto READPACKET; } } break; } } else { INFO("ERROR: Message too long\r\n"); } system_os_post(MQTT_TASK_PRIO, 0, (os_param_t)client); }
/** * @brief Client received callback function. * @param arg: contain the ip link information * @param pdata: received data * @param len: the lenght of received data * @retval None */ void ICACHE_FLASH_ATTR mqtt_tcpclient_recv(void *arg, char *pdata, unsigned short len) { uint8_t msg_type; uint8_t msg_qos; uint16_t msg_id; struct espconn *pCon = (struct espconn*)arg; MQTT_Client *client = (MQTT_Client *)pCon->reverse; //spam INFO("TCP: data received\r\n"); if(len < MQTT_BUF_SIZE && len > 0){ memcpy(client->mqtt_state.in_buffer, pdata, len); switch(client->connState){ case MQTT_CONNECT_SENDING: if(mqtt_get_type(client->mqtt_state.in_buffer) != MQTT_MSG_TYPE_CONNACK){ //spam INFO("MQTT: Invalid packet\r\n"); if(client->security){ espconn_secure_disconnect(client->pCon); } else { espconn_disconnect(client->pCon); } } else { //spam INFO("MQTT: Connected to %s:%d\r\n", client->host, client->port); client->connState = MQTT_DATA; if(client->connectedCb) client->connectedCb((uint32_t*)client); } break; case MQTT_DATA: client->mqtt_state.message_length_read = len; client->mqtt_state.message_length = mqtt_get_total_length(client->mqtt_state.in_buffer, client->mqtt_state.message_length_read); msg_type = mqtt_get_type(client->mqtt_state.in_buffer); msg_qos = mqtt_get_qos(client->mqtt_state.in_buffer); msg_id = mqtt_get_id(client->mqtt_state.in_buffer, client->mqtt_state.in_buffer_length); switch(msg_type) { case MQTT_MSG_TYPE_SUBACK: //spam if(client->mqtt_state.pending_msg_type == MQTT_MSG_TYPE_SUBSCRIBE && client->mqtt_state.pending_msg_id == msg_id) //spam INFO("MQTT: Subscribe successful to %s:%d\r\n", client->host, client->port); break; case MQTT_MSG_TYPE_UNSUBACK: //spam if(client->mqtt_state.pending_msg_type == MQTT_MSG_TYPE_UNSUBSCRIBE && client->mqtt_state.pending_msg_id == msg_id) //spam INFO("MQTT: UnSubscribe successful\r\n"); break; case MQTT_MSG_TYPE_PUBLISH: if(msg_qos == 1) client->mqtt_state.outbound_message = mqtt_msg_puback(&client->mqtt_state.mqtt_connection, msg_id); else if(msg_qos == 2) client->mqtt_state.outbound_message = mqtt_msg_pubrec(&client->mqtt_state.mqtt_connection, msg_id); deliver_publish(client, client->mqtt_state.in_buffer, client->mqtt_state.message_length_read); break; case MQTT_MSG_TYPE_PUBACK: if(client->mqtt_state.pending_msg_type == MQTT_MSG_TYPE_PUBLISH && client->mqtt_state.pending_msg_id == msg_id){ //spam INFO("MQTT: Publish successful\r\n"); if(client->publishedCb) client->publishedCb((uint32_t*)client); } break; case MQTT_MSG_TYPE_PUBREC: client->mqtt_state.outbound_message = mqtt_msg_pubrel(&client->mqtt_state.mqtt_connection, msg_id); break; case MQTT_MSG_TYPE_PUBREL: client->mqtt_state.outbound_message = mqtt_msg_pubcomp(&client->mqtt_state.mqtt_connection, msg_id); break; case MQTT_MSG_TYPE_PUBCOMP: if(client->mqtt_state.pending_msg_type == MQTT_MSG_TYPE_PUBLISH && client->mqtt_state.pending_msg_id == msg_id){ //spam INFO("MQTT: Public successful\r\n"); if(client->publishedCb) client->publishedCb((uint32_t*)client); } break; case MQTT_MSG_TYPE_PINGREQ: client->mqtt_state.outbound_message = mqtt_msg_pingresp(&client->mqtt_state.mqtt_connection); break; case MQTT_MSG_TYPE_PINGRESP: // Ignore break; } // 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) { uint16_t len; // adjust message_length and message_length_read so that // they only account for the publish data and not the rest of the // message, this is done so that the offset passed with the // continuation event is the offset within the publish data and // not the offset within the message as a whole. len = client->mqtt_state.message_length_read; mqtt_get_publish_data(client->mqtt_state.in_buffer, &len); len = client->mqtt_state.message_length_read - len; client->mqtt_state.message_length -= len; client->mqtt_state.message_length_read -= len; if(client->mqtt_state.message_length_read < client->mqtt_state.message_length) { //client->connState = MQTT_PUBLISH_RECV; } } break; case MQTT_PUBLISH_RECV: /* * Long publish message, not implement yet * TODO: Implement method used deliver_publish_continuation */ break; } } system_os_post(MQTT_TASK_PRIO, 0, (os_param_t)client); }
void ICACHE_FLASH_ATTR MQTT_Task(os_event_t *e) { MQTT_Client* client = (MQTT_Client*)e->par; uint8_t dataBuffer[MQTT_BUF_SIZE]; uint16_t dataLen; if (e->par == 0) return; switch (client->connState) { case TCP_RECONNECT_REQ: break; case TCP_RECONNECT: mqtt_tcpclient_delete(client); MQTT_Connect(client); INFO("TCP: Reconnect to: %s:%d\r\n", client->host, client->port); client->connState = TCP_CONNECTING; break; case MQTT_DELETING: case TCP_DISCONNECTING: case TCP_RECONNECT_DISCONNECTING: if (client->security) { #ifdef MQTT_SSL_ENABLE espconn_secure_disconnect(client->pCon); #else INFO("TCP: Do not support SSL\r\n"); #endif } else { espconn_disconnect(client->pCon); } break; case TCP_DISCONNECTED: INFO("MQTT: Disconnected\r\n"); mqtt_tcpclient_delete(client); break; case MQTT_DELETED: INFO("MQTT: Deleted client\r\n"); mqtt_client_delete(client); break; case MQTT_KEEPALIVE_SEND: mqtt_send_keepalive(client); break; case MQTT_DATA: if (QUEUE_IsEmpty(&client->msgQueue) || client->sendTimeout != 0) { break; } if (QUEUE_Gets(&client->msgQueue, dataBuffer, &dataLen, MQTT_BUF_SIZE) == 0) { client->mqtt_state.pending_msg_type = mqtt_get_type(dataBuffer); client->mqtt_state.pending_msg_id = mqtt_get_id(dataBuffer, dataLen); client->sendTimeout = MQTT_SEND_TIMOUT; INFO("MQTT: Sending, type: %d, id: %04X\r\n", client->mqtt_state.pending_msg_type, client->mqtt_state.pending_msg_id); if (client->security) { #ifdef MQTT_SSL_ENABLE espconn_secure_send(client->pCon, dataBuffer, dataLen); #else INFO("TCP: Do not support SSL\r\n"); #endif } else { espconn_send(client->pCon, dataBuffer, dataLen); } client->mqtt_state.outbound_message = NULL; break; } break; } }
// Lua: server/socket:close() // server disconnect everything, unref everything // client disconnect and unref itself static int net_close( lua_State* L, const char* mt ) { NODE_DBG("net_close is called.\n"); bool isserver = false; int i = 0; lnet_userdata *nud = NULL, *skt = NULL; nud = (lnet_userdata *)luaL_checkudata(L, 1, mt); luaL_argcheck(L, nud, 1, "Server/Socket expected"); if(nud == NULL) return 0; if(nud->pesp_conn == NULL) return 0; if (mt!=NULL && c_strcmp(mt, "net.server")==0) isserver = true; else if (mt!=NULL && c_strcmp(mt, "net.socket")==0) isserver = false; else { NODE_DBG("wrong metatable for net_close.\n"); return 0; } if(isserver && nud->pesp_conn->type == ESPCONN_TCP && tcpserver_cb_connect_ref != LUA_NOREF){ luaL_unref(L, LUA_REGISTRYINDEX, tcpserver_cb_connect_ref); tcpserver_cb_connect_ref = LUA_NOREF; } int n = lua_gettop(L); skt = nud; do{ if(isserver && skt == NULL){ if(socket[i] != LUA_NOREF){ // there is client socket exists lua_rawgeti(L, LUA_REGISTRYINDEX, socket[i]); // get the referenced user_data to stack top #if 0 socket[i] = LUA_NOREF; socket_num--; #endif // do this in net_server_disconnected i++; if(lua_isuserdata(L,-1)){ skt = lua_touserdata(L,-1); } else { lua_pop(L, 1); continue; } }else{ // skip LUA_NOREF i++; continue; } } if(skt==NULL){ NODE_DBG("userdata is nil.\n"); continue; } if(skt->pesp_conn) // disconnect the connection { if(skt->pesp_conn->type == ESPCONN_TCP) { #ifdef CLIENT_SSL_ENABLE if(skt->secure){ if(skt->pesp_conn->proto.tcp->remote_port || skt->pesp_conn->proto.tcp->local_port) espconn_secure_disconnect(skt->pesp_conn); } else #endif { if(skt->pesp_conn->proto.tcp->remote_port || skt->pesp_conn->proto.tcp->local_port) espconn_disconnect(skt->pesp_conn); } }else if(skt->pesp_conn->type == ESPCONN_UDP) { if(skt->pesp_conn->proto.tcp->remote_port || skt->pesp_conn->proto.tcp->local_port) espconn_delete(skt->pesp_conn); // a udp server/socket unref it self here. not in disconnect. if(LUA_NOREF!=skt->self_ref){ // for a udp self_ref is NOREF luaL_unref(L, LUA_REGISTRYINDEX, skt->self_ref); skt->self_ref = LUA_NOREF; // for a socket, now only var in lua is ref to the userdata } } } #if 0 // unref the self_ref if(LUA_NOREF!=skt->self_ref){ // for a server self_ref is NOREF luaL_unref(L, LUA_REGISTRYINDEX, skt->self_ref); skt->self_ref = LUA_NOREF; // for a socket, now only var in lua is ref to the userdata } #endif lua_settop(L, n); // reset the stack top skt = NULL; } while( isserver && i<MAX_SOCKET); #if 0 // unref the self_ref, for both socket and server if(LUA_NOREF!=nud->self_ref){ // for a server self_ref is NOREF luaL_unref(L, LUA_REGISTRYINDEX, nud->self_ref); nud->self_ref = LUA_NOREF; // now only var in lua is ref to the userdata } #endif return 0; }
// Lua: server:listen( port, ip, function(con) ) // Lua: socket:connect( port, ip, function(con) ) static int net_start( lua_State* L, const char* mt ) { NODE_DBG("net_start is called.\n"); struct espconn *pesp_conn = NULL; lnet_userdata *nud; unsigned port; size_t il; bool isserver = false; ip_addr_t ipaddr; const char *domain; uint8_t stack = 1; if (mt!=NULL && c_strcmp(mt, "net.server")==0) isserver = true; else if (mt!=NULL && c_strcmp(mt, "net.socket")==0) isserver = false; else { NODE_DBG("wrong metatable for net_start.\n"); return 0; } nud = (lnet_userdata *)luaL_checkudata(L, stack, mt); luaL_argcheck(L, nud, stack, "Server/Socket expected"); stack++; if(nud==NULL){ NODE_DBG("userdata is nil.\n"); return 0; } pesp_conn = nud->pesp_conn; port = luaL_checkinteger( L, stack ); stack++; if( pesp_conn->type == ESPCONN_TCP ) { if(isserver) pesp_conn->proto.tcp->local_port = port; else{ pesp_conn->proto.tcp->remote_port = port; pesp_conn->proto.tcp->local_port = espconn_port(); } NODE_DBG("TCP port is set: %d.\n", port); } else if (pesp_conn->type == ESPCONN_UDP) { if(isserver) pesp_conn->proto.udp->local_port = port; else{ pesp_conn->proto.udp->remote_port = port; pesp_conn->proto.udp->local_port = espconn_port(); } NODE_DBG("UDP port is set: %d.\n", port); } if( lua_isstring(L,stack) ) // deal with the domain string { domain = luaL_checklstring( L, stack, &il ); stack++; if (domain == NULL) { if(isserver) domain = "0.0.0.0"; else domain = "127.0.0.1"; } ipaddr.addr = ipaddr_addr(domain); if( pesp_conn->type == ESPCONN_TCP ) { if(isserver) c_memcpy(pesp_conn->proto.tcp->local_ip, &ipaddr.addr, 4); else c_memcpy(pesp_conn->proto.tcp->remote_ip, &ipaddr.addr, 4); NODE_DBG("TCP ip is set: "); NODE_DBG(IPSTR, IP2STR(&ipaddr.addr)); NODE_DBG("\n"); } else if (pesp_conn->type == ESPCONN_UDP) { if(isserver) c_memcpy(pesp_conn->proto.udp->local_ip, &ipaddr.addr, 4); else c_memcpy(pesp_conn->proto.udp->remote_ip, &ipaddr.addr, 4); NODE_DBG("UDP ip is set: "); NODE_DBG(IPSTR, IP2STR(&ipaddr.addr)); NODE_DBG("\n"); } } // call back function when a connection is obtained, tcp only if ( pesp_conn->type == ESPCONN_TCP ) { if (lua_type(L, stack) == LUA_TFUNCTION || lua_type(L, stack) == LUA_TLIGHTFUNCTION){ lua_pushvalue(L, stack); // copy argument (func) to the top of stack if(isserver) // for tcp server connected callback { if(tcpserver_cb_connect_ref != LUA_NOREF) luaL_unref(L, LUA_REGISTRYINDEX, tcpserver_cb_connect_ref); tcpserver_cb_connect_ref = luaL_ref(L, LUA_REGISTRYINDEX); } else { if(nud->cb_connect_ref != LUA_NOREF) luaL_unref(L, LUA_REGISTRYINDEX, nud->cb_connect_ref); nud->cb_connect_ref = luaL_ref(L, LUA_REGISTRYINDEX); } } } if(!isserver || pesp_conn->type == ESPCONN_UDP){ // self_ref is only needed by socket userdata, or udp server lua_pushvalue(L, 1); // copy to the top of stack if(nud->self_ref != LUA_NOREF) luaL_unref(L, LUA_REGISTRYINDEX, nud->self_ref); nud->self_ref = luaL_ref(L, LUA_REGISTRYINDEX); } if( pesp_conn->type == ESPCONN_TCP ) { if(isserver){ // no secure server support for now espconn_regist_connectcb(pesp_conn, net_server_connected); // tcp server, SSL is not supported #ifdef CLIENT_SSL_ENABLE // if(nud->secure) // espconn_secure_accept(pesp_conn); // else #endif espconn_accept(pesp_conn); // if it's a server, no need to dns. espconn_regist_time(pesp_conn, tcp_server_timeover, 0); } else{ espconn_regist_connectcb(pesp_conn, net_socket_connected); espconn_regist_reconcb(pesp_conn, net_socket_reconnected); #ifdef CLIENT_SSL_ENABLE if(nud->secure){ if(pesp_conn->proto.tcp->remote_port || pesp_conn->proto.tcp->local_port) espconn_secure_disconnect(pesp_conn); // espconn_secure_connect(pesp_conn); } else #endif { if(pesp_conn->proto.tcp->remote_port || pesp_conn->proto.tcp->local_port) espconn_disconnect(pesp_conn); // espconn_connect(pesp_conn); } } } else if (pesp_conn->type == ESPCONN_UDP) { espconn_regist_recvcb(pesp_conn, net_socket_received); espconn_regist_sentcb(pesp_conn, net_socket_sent); if(pesp_conn->proto.tcp->remote_port || pesp_conn->proto.tcp->local_port) espconn_delete(pesp_conn); if(isserver) espconn_create(pesp_conn); // if it's a server, no need to dns. } if(!isserver){ if((ipaddr.addr == IPADDR_NONE) && (c_memcmp(domain,"255.255.255.255",16) != 0)) { host_ip.addr = 0; dns_reconn_count = 0; if(ESPCONN_OK == espconn_gethostbyname(pesp_conn, domain, &host_ip, socket_dns_found)){ socket_dns_found(domain, &host_ip, pesp_conn); // ip is returned in host_ip. } } else { socket_connect(pesp_conn); } } return 0; }
void ICACHE_FLASH_ATTR tcpclient_recv(void *arg, char *pdata, unsigned short len) { uint8_t currentLineIsBlank = 0; uint8_t httpBody = 0; uint8_t inStatus = 0; char statusCode[4]; int i = 0, j; uint32_t code = 0; uint16_t crc; struct espconn *pCon = (struct espconn*)arg; REST_CLIENT *client = (REST_CLIENT *)pCon->reverse; for(j=0 ;j<len; j++){ char c = pdata[j]; if(c == ' ' && !inStatus){ inStatus = 1; } if(inStatus && i < 3 && c != ' '){ statusCode[i] = c; i++; //start edit for emma if(i == 3) { statusCode[i] = '\0'; code = atoi(statusCode); INFO("REST: status = %d\r\n",code); } //end edit for emma } if(i == 3){ statusCode[i] = '\0'; code = atoi(statusCode); } if(httpBody){ //only write response if its not null uint32_t body_len = len - j; INFO("REST: status = %d, body_len = %d\r\n",code, body_len); if(body_len == 0){ crc = CMD_ResponseStart(CMD_REST_EVENTS, client->resp_cb, code, 0); } else { crc = CMD_ResponseStart(CMD_REST_EVENTS, client->resp_cb, code, 1); crc = CMD_ResponseBody(crc, &pdata[j], body_len); } CMD_ResponseEnd(crc); break; } else { if (c == '\n' && currentLineIsBlank) { httpBody = true; } if (c == '\n') { // you're starting a new line currentLineIsBlank = true; } else if (c != '\r') { // you've gotten a character on the current line currentLineIsBlank = false; } } } if(client->security) espconn_secure_disconnect(client->pCon); else espconn_disconnect(client->pCon); }
static void mqtt_socket_received(void *arg, char *pdata, unsigned short len) { NODE_DBG("enter mqtt_socket_received.\n"); uint8_t msg_type; uint8_t msg_qos; uint16_t msg_id; msg_queue_t *node = NULL; int length = (int)len; // uint8_t in_buffer[MQTT_BUF_SIZE]; uint8_t *in_buffer = (uint8_t *)pdata; struct espconn *pesp_conn = arg; if(pesp_conn == NULL) return; lmqtt_userdata *mud = (lmqtt_userdata *)pesp_conn->reverse; if(mud == NULL) return; READPACKET: if(length > MQTT_BUF_SIZE || length <= 0) return; // c_memcpy(in_buffer, pdata, length); uint8_t temp_buffer[MQTT_BUF_SIZE]; mqtt_msg_init(&mud->mqtt_state.mqtt_connection, temp_buffer, MQTT_BUF_SIZE); mqtt_message_t *temp_msg = NULL; switch(mud->connState){ case MQTT_CONNECT_SENDING: case MQTT_CONNECT_SENT: if(mqtt_get_type(in_buffer) != MQTT_MSG_TYPE_CONNACK){ NODE_DBG("MQTT: Invalid packet\r\n"); mud->connState = MQTT_INIT; if(mud->secure) espconn_secure_disconnect(pesp_conn); else espconn_disconnect(pesp_conn); } else { mud->connState = MQTT_DATA; NODE_DBG("MQTT: Connected\r\n"); if(mud->cb_connect_ref == LUA_NOREF) break; if(mud->self_ref == LUA_NOREF) break; if(mud->L == NULL) break; lua_rawgeti(mud->L, LUA_REGISTRYINDEX, mud->cb_connect_ref); lua_rawgeti(mud->L, LUA_REGISTRYINDEX, mud->self_ref); // pass the userdata(client) to callback func in lua lua_call(mud->L, 1, 0); break; } break; case MQTT_DATA: mud->mqtt_state.message_length_read = length; mud->mqtt_state.message_length = mqtt_get_total_length(in_buffer, mud->mqtt_state.message_length_read); msg_type = mqtt_get_type(in_buffer); msg_qos = mqtt_get_qos(in_buffer); msg_id = mqtt_get_id(in_buffer, mud->mqtt_state.message_length); 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", msg_type, msg_qos, msg_id, (pending_msg)?pending_msg->msg_id:0); switch(msg_type) { case MQTT_MSG_TYPE_SUBACK: if(pending_msg && pending_msg->msg_type == MQTT_MSG_TYPE_SUBSCRIBE && pending_msg->msg_id == msg_id){ NODE_DBG("MQTT: Subscribe successful\r\n"); msg_destroy(msg_dequeue(&(mud->mqtt_state.pending_msg_q))); if (mud->cb_suback_ref == LUA_NOREF) break; if (mud->self_ref == LUA_NOREF) break; if(mud->L == NULL) break; lua_rawgeti(mud->L, LUA_REGISTRYINDEX, mud->cb_suback_ref); lua_rawgeti(mud->L, LUA_REGISTRYINDEX, mud->self_ref); lua_call(mud->L, 1, 0); } break; case MQTT_MSG_TYPE_UNSUBACK: if(pending_msg && pending_msg->msg_type == MQTT_MSG_TYPE_UNSUBSCRIBE && pending_msg->msg_id == msg_id){ NODE_DBG("MQTT: UnSubscribe successful\r\n"); msg_destroy(msg_dequeue(&(mud->mqtt_state.pending_msg_q))); } break; case MQTT_MSG_TYPE_PUBLISH: if(msg_qos == 1){ temp_msg = mqtt_msg_puback(&mud->mqtt_state.mqtt_connection, msg_id); node = msg_enqueue(&(mud->mqtt_state.pending_msg_q), temp_msg, msg_id, MQTT_MSG_TYPE_PUBACK, (int)mqtt_get_qos(temp_msg->data) ); } else if(msg_qos == 2){ temp_msg = mqtt_msg_pubrec(&mud->mqtt_state.mqtt_connection, msg_id); node = msg_enqueue(&(mud->mqtt_state.pending_msg_q), temp_msg, msg_id, MQTT_MSG_TYPE_PUBREC, (int)mqtt_get_qos(temp_msg->data) ); } if(msg_qos == 1 || msg_qos == 2){ NODE_DBG("MQTT: Queue response QoS: %d\r\n", msg_qos); } deliver_publish(mud, in_buffer, mud->mqtt_state.message_length); break; case MQTT_MSG_TYPE_PUBACK: if(pending_msg && pending_msg->msg_type == MQTT_MSG_TYPE_PUBLISH && pending_msg->msg_id == msg_id){ NODE_DBG("MQTT: Publish with QoS = 1 successful\r\n"); msg_destroy(msg_dequeue(&(mud->mqtt_state.pending_msg_q))); if(mud->cb_puback_ref == LUA_NOREF) break; if(mud->self_ref == LUA_NOREF) break; if(mud->L == NULL) break; lua_rawgeti(mud->L, LUA_REGISTRYINDEX, mud->cb_puback_ref); lua_rawgeti(mud->L, LUA_REGISTRYINDEX, mud->self_ref); // pass the userdata to callback func in lua lua_call(mud->L, 1, 0); } break; 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))); temp_msg = mqtt_msg_pubrel(&mud->mqtt_state.mqtt_connection, msg_id); node = msg_enqueue(&(mud->mqtt_state.pending_msg_q), temp_msg, msg_id, MQTT_MSG_TYPE_PUBREL, (int)mqtt_get_qos(temp_msg->data) ); NODE_DBG("MQTT: Response PUBREL\r\n"); } break; 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))); temp_msg = mqtt_msg_pubcomp(&mud->mqtt_state.mqtt_connection, msg_id); node = msg_enqueue(&(mud->mqtt_state.pending_msg_q), temp_msg, msg_id, MQTT_MSG_TYPE_PUBCOMP, (int)mqtt_get_qos(temp_msg->data) ); NODE_DBG("MQTT: Response PUBCOMP\r\n"); } break; case MQTT_MSG_TYPE_PUBCOMP: 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"); msg_destroy(msg_dequeue(&(mud->mqtt_state.pending_msg_q))); if(mud->cb_puback_ref == LUA_NOREF) break; if(mud->self_ref == LUA_NOREF) break; if(mud->L == NULL) break; lua_rawgeti(mud->L, LUA_REGISTRYINDEX, mud->cb_puback_ref); lua_rawgeti(mud->L, LUA_REGISTRYINDEX, mud->self_ref); // pass the userdata to callback func in lua lua_call(mud->L, 1, 0); } break; case MQTT_MSG_TYPE_PINGREQ: temp_msg = mqtt_msg_pingresp(&mud->mqtt_state.mqtt_connection); node = msg_enqueue(&(mud->mqtt_state.pending_msg_q), temp_msg, msg_id, MQTT_MSG_TYPE_PINGRESP, (int)mqtt_get_qos(temp_msg->data) ); NODE_DBG("MQTT: Response PINGRESP\r\n"); break; case MQTT_MSG_TYPE_PINGRESP: // Ignore NODE_DBG("MQTT: PINGRESP received\r\n"); break; } // 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) { length = mud->mqtt_state.message_length_read; if(mud->mqtt_state.message_length < mud->mqtt_state.message_length_read) { length -= mud->mqtt_state.message_length; in_buffer += mud->mqtt_state.message_length; NODE_DBG("Get another published message\r\n"); goto READPACKET; } } break; } if(node && (1==msg_size(&(mud->mqtt_state.pending_msg_q))) && mud->event_timeout == 0){ mud->event_timeout = MQTT_SEND_TIMEOUT; NODE_DBG("Sent: %d\n", node->msg.length); if( mud->secure ) espconn_secure_sent( pesp_conn, node->msg.data, node->msg.length ); else espconn_sent( pesp_conn, node->msg.data, node->msg.length ); } mud->keep_alive_tick = 0; NODE_DBG("receive, queue size: %d\n", msg_size(&(mud->mqtt_state.pending_msg_q))); NODE_DBG("leave mqtt_socket_received.\n"); return; }
void mqtt_socket_timer(void *arg) { NODE_DBG("enter mqtt_socket_timer.\n"); lmqtt_userdata *mud = (lmqtt_userdata*) arg; if(mud == NULL) return; if(mud->pesp_conn == NULL){ NODE_DBG("mud->pesp_conn is NULL.\n"); os_timer_disarm(&mud->mqttTimer); return; } NODE_DBG("timer, queue size: %d\n", msg_size(&(mud->mqtt_state.pending_msg_q))); if(mud->event_timeout > 0){ NODE_DBG("event_timeout: %d.\n", mud->event_timeout); mud->event_timeout --; if(mud->event_timeout > 0){ return; } else { NODE_DBG("event timeout. \n"); if(mud->connState == MQTT_DATA) msg_destroy(msg_dequeue(&(mud->mqtt_state.pending_msg_q))); // should remove the head of the queue and re-send with DUP = 1 // Not implemented yet. } } if(mud->connState == MQTT_INIT){ // socket connect time out. NODE_DBG("Can not connect to broker.\n"); // Never goes here. } else if(mud->connState == MQTT_CONNECT_SENDING){ // MQTT_CONNECT send time out. NODE_DBG("sSend MQTT_CONNECT failed.\n"); mud->connState = MQTT_INIT; if(mud->secure) espconn_secure_disconnect(mud->pesp_conn); else espconn_disconnect(mud->pesp_conn); mud->keep_alive_tick = 0; // not need count anymore } else if(mud->connState == MQTT_CONNECT_SENT){ // wait for CONACK time out. NODE_DBG("MQTT_CONNECT failed.\n"); } else if(mud->connState == MQTT_DATA){ msg_queue_t *pending_msg = msg_peek(&(mud->mqtt_state.pending_msg_q)); if(pending_msg){ mud->event_timeout = MQTT_SEND_TIMEOUT; if(mud->secure) espconn_secure_sent(mud->pesp_conn, pending_msg->msg.data, pending_msg->msg.length); else espconn_sent(mud->pesp_conn, pending_msg->msg.data, pending_msg->msg.length); mud->keep_alive_tick = 0; NODE_DBG("id: %d - qos: %d, length: %d\n", pending_msg->msg_id, pending_msg->publish_qos, pending_msg->msg.length); } else { // no queued event. mud->keep_alive_tick ++; if(mud->keep_alive_tick > mud->mqtt_state.connect_info->keepalive){ mud->event_timeout = MQTT_SEND_TIMEOUT; uint8_t temp_buffer[MQTT_BUF_SIZE]; mqtt_msg_init(&mud->mqtt_state.mqtt_connection, temp_buffer, MQTT_BUF_SIZE); NODE_DBG("\r\nMQTT: Send keepalive packet\r\n"); mqtt_message_t* temp_msg = mqtt_msg_pingreq(&mud->mqtt_state.mqtt_connection); msg_queue_t *node = msg_enqueue( &(mud->mqtt_state.pending_msg_q), temp_msg, 0, MQTT_MSG_TYPE_PINGREQ, (int)mqtt_get_qos(temp_msg->data) ); // only one message in queue, send immediately. if(mud->secure) espconn_secure_sent(mud->pesp_conn, temp_msg->data, temp_msg->length); else espconn_sent(mud->pesp_conn, temp_msg->data, temp_msg->length); mud->keep_alive_tick = 0; } } } NODE_DBG("leave mqtt_socket_timer.\n"); }
/** * @brief Client received callback function. * @param arg: contain the ip link information * @param pdata: received data * @param len: the lenght of received data * @retval None */ void ICACHE_FLASH_ATTR mqtt_tcpclient_recv(void *arg, char *pdata, unsigned short len) { INFO("TCP: data received %d bytes\r\n", len); uint8_t msg_type; uint8_t msg_qos; uint16_t msg_id; struct espconn *pCon = (struct espconn*)arg; MQTT_Client *client = (MQTT_Client *)pCon->reverse; if(len > MQTT_BUF_SIZE || len == 0) { INFO("receive length is invalid.\n"); return; } os_memcpy(client->mqtt_state.in_buffer + client->mqtt_state.message_length_read, pdata, len); client->mqtt_state.message_length_read += len; READPACKET: if(client->mqtt_state.message_length_read == 1) { INFO("not enough data for read package length.\n!"); return; } client->mqtt_state.message_length = mqtt_get_total_length(client->mqtt_state.in_buffer, client->mqtt_state.message_length_read); INFO("message length:%d\n", client->mqtt_state.message_length); show_package(client->mqtt_state.in_buffer, client->mqtt_state.message_length_read); if(client->mqtt_state.message_length > client->mqtt_state.message_length_read) { INFO("not enough data.\n"); return; } msg_type = mqtt_get_type(client->mqtt_state.in_buffer); msg_qos = mqtt_get_qos(client->mqtt_state.in_buffer); msg_id = mqtt_get_id(client->mqtt_state.in_buffer, client->mqtt_state.message_length); INFO("client->connstate:%d, type:%d, Qos:%d, id:%d, message length:%d\n", client->connState, msg_type, msg_qos, \ msg_id, client->mqtt_state.message_length); switch(client->connState) { case MQTT_CONNECT_SENDING: if(msg_type == MQTT_MSG_TYPE_CONNACK) { if(client->mqtt_state.pending_msg_type != MQTT_MSG_TYPE_CONNECT) { INFO("MQTT: Invalid packet\r\n"); if(client->security) { espconn_secure_disconnect(client->pCon); } else { espconn_disconnect(client->pCon); } } else { INFO("MQTT: Connected to %s:%d\r\n", client->host, client->port); client->connState = MQTT_DATA; if(client->connectedCb) client->connectedCb((uint32_t*)client); } } break; case MQTT_DATA: 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) INFO("MQTT: Subscribe successful\r\n"); break; case MQTT_MSG_TYPE_UNSUBACK: if(client->mqtt_state.pending_msg_type == MQTT_MSG_TYPE_UNSUBSCRIBE && client->mqtt_state.pending_msg_id == msg_id) INFO("MQTT: UnSubscribe successful\r\n"); break; case MQTT_MSG_TYPE_PUBLISH: if(msg_qos == 1) client->mqtt_state.outbound_message = mqtt_msg_puback(&client->mqtt_state.mqtt_connection, msg_id); else if(msg_qos == 2) client->mqtt_state.outbound_message = mqtt_msg_pubrec(&client->mqtt_state.mqtt_connection, msg_id); if(msg_qos == 1 || msg_qos == 2) { INFO("MQTT: Queue response QoS: %d\r\n", msg_qos); if(QUEUE_Puts(&client->msgQueue, client->mqtt_state.outbound_message->data,\ client->mqtt_state.outbound_message->length) == -1) { INFO("MQTT: Queue full\r\n"); } } show_package(client->mqtt_state.in_buffer, client->mqtt_state.message_length); deliver_publish(client, client->mqtt_state.in_buffer, client->mqtt_state.message_length); break; case MQTT_MSG_TYPE_PUBACK: if(client->mqtt_state.pending_msg_type == MQTT_MSG_TYPE_PUBLISH && client->mqtt_state.pending_msg_id == msg_id) { 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); if(QUEUE_Puts(&client->msgQueue, client->mqtt_state.outbound_message->data, client->mqtt_state.outbound_message->length) == -1) { INFO("MQTT: Queue full\r\n"); } break; case MQTT_MSG_TYPE_PUBREL: client->mqtt_state.outbound_message = mqtt_msg_pubcomp(&client->mqtt_state.mqtt_connection, msg_id); if(QUEUE_Puts(&client->msgQueue, client->mqtt_state.outbound_message->data, client->mqtt_state.outbound_message->length) == -1) { INFO("MQTT: Queue full\r\n"); } break; case MQTT_MSG_TYPE_PUBCOMP: if(client->mqtt_state.pending_msg_type == MQTT_MSG_TYPE_PUBLISH && client->mqtt_state.pending_msg_id == msg_id) { INFO("MQTT: receive MQTT_MSG_TYPE_PUBCOMP, finish QoS2 publish\r\n"); } break; case MQTT_MSG_TYPE_PINGREQ: client->mqtt_state.outbound_message = mqtt_msg_pingresp(&client->mqtt_state.mqtt_connection); if(QUEUE_Puts(&client->msgQueue, client->mqtt_state.outbound_message->data, client->mqtt_state.outbound_message->length) == -1) { INFO("MQTT: Queue full\r\n"); } break; case MQTT_MSG_TYPE_PINGRESP: INFO("receive a heart beat response!\n"); client->heart_beat_flag = 1; break; } break; } // process package adhesive. uint16_t remain_length = client->mqtt_state.message_length_read - client->mqtt_state.message_length; client->mqtt_state.message_length_read = remain_length; INFO("client->mqtt_state.message_length_read = %d\n", client->mqtt_state.message_length_read); INFO("client->mqtt_state.message_length = %d\n", client->mqtt_state.message_length); INFO("the package is\n"); show_package(client->mqtt_state.in_buffer, client->mqtt_state.message_length); if(remain_length > 0) { int i = 0; for(i = 0; i< remain_length; i++) { client->mqtt_state.in_buffer[i] = \ client->mqtt_state.in_buffer[client->mqtt_state.message_length_read - remain_length + i]; } INFO("Get another published message\r\n"); goto READPACKET; } system_os_post(MQTT_TASK_PRIO, 0, (os_param_t)client); }
/** * @brief response for get version request. * parse answer, save online version to flash. * @param arg: contain the ip link information * pusrdata: data * len: len of data (strlen) * @retval None */ LOCAL void ICACHE_FLASH_ATTR get_version_recv(void *arg, char *pusrdata, unsigned short len) { struct espconn *pespconn = arg; fota_client_t *fota_client = (fota_client_t *)pespconn->reverse; /* get body */ char *body = (char*)os_strstr(pusrdata, "\r\n\r\n"); if (body == NULL) { INFO("Invalide response\n"); return; } INFO("Body: %s\n", body+4); uint32_t bodylen = os_strlen(body); /* parse json, get version */ char *n_host, *n_url, *n_version, *n_protocol; if (parse_fota(body, bodylen, &n_version, &n_host, &n_url, &n_protocol) < 0) { INFO("FOTA Client: Invalid response\n"); goto CLEAN_MEM; } INFO("\tVersion %s\n", n_version); INFO("\tHost %s\n", n_host); INFO("\tURL %s\n", n_url); INFO("\tProtocol %s\n", n_protocol); /* then, we have valide JSON response */ // disable data receiving timeout handing // and close connection os_timer_disarm(&fota_client->request_timeout); #if (FOTA_SECURE) espconn_secure_disconnect(pespconn); #else espconn_disconnect(pespconn); #endif uint32_t version; if (convert_version(n_version, os_strlen(n_version), &version) < 0) { REPORT("FOTA Client: Invalide version return %s\n", n_version); goto CLEAN_MEM; } /* if we still have lastest version */ if (version <= version_fwr) { INFO("FOTA Client: We have lastest firmware (current %u.%u.%u vs online %u.%u.%u)\n", (version_fwr/256/256)%256, (version_fwr/256)%256, version_fwr%256, (version/256/256)%256, (version/256)%256, version%256); goto CLEAN_MEM; } INFO("FOTA Client: Preparing to get firmware\n"); start_cdn(&fota_client->fw_server, n_version, n_host, n_url, n_protocol); CLEAN_MEM: FREE(n_host); FREE(n_url); FREE(n_version); FREE(n_protocol); }