/** * @brief MQTT subscribe function. * @param client: MQTT_Client reference * @param topic: string topic will subscribe * @param qos: qos * @retval TRUE if success queue */ bool ICACHE_FLASH_ATTR MQTT_Subscribe(MQTT_Client* client, char* topic, uint8_t qos) { uint16_t msg_id; if (!mqtt_msg_subscribe(&client->mqtt_connection, topic, 0, &msg_id)) { os_printf("MQTT ERROR: Queuing Subscribe failed (too long)\n"); return FALSE; } DBG_MQTT("MQTT: Subscribe, topic: \"%s\"\n", topic); mqtt_enq_message(client, client->mqtt_connection.message.data, client->mqtt_connection.message.length); return TRUE; }
// Subscribe to the specified topic int mqtt_subscribe(const char* topic) { if(!mqtt_ready()) return -1; printf("mqtt: sending subscribe...\n"); mqtt_state.outbound_message = mqtt_msg_subscribe(&mqtt_state.mqtt_connection, topic, 0, &mqtt_state.pending_msg_id); mqtt_flags &= ~MQTT_FLAG_READY; mqtt_state.pending_msg_type = MQTT_MSG_TYPE_SUBSCRIBE; tcpip_poll_tcp(mqtt_state.tcp_connection); return 0; }
/** * @brief MQTT subscibe function. * @param client: MQTT_Client reference * @param topic: string topic will subscribe * @param qos: qos * @retval TRUE if success queue */ BOOL ICACHE_FLASH_ATTR MQTT_Subscribe(MQTT_Client *client, char* topic, uint8_t qos) { client->mqtt_state.outbound_message = mqtt_msg_subscribe(&client->mqtt_state.mqtt_connection, topic, 0, &client->mqtt_state.pending_msg_id); INFO("MQTT: queue subscribe, topic\"%s\", id: %d\r\n",topic, client->mqtt_state.pending_msg_id); if(QUEUE_Puts(&client->msgQueue, client->mqtt_state.outbound_message->data, client->mqtt_state.outbound_message->length) == -1){ INFO("MQTT: Exceed the amount of queues\r\n"); return FALSE; } system_os_post(MQTT_TASK_PRIO, 0, (os_param_t)client); return TRUE; }
/** * @brief MQTT subscibe function. * @param client: MQTT_Client reference * @param topic: string topic will subscribe * @param qos: qos * @retval TRUE if success queue */ BOOL ICACHE_FLASH_ATTR MQTT_Subscribe(MQTT_Client *client, char* topic, uint8_t qos) { uint8_t dataBuffer[MQTT_BUF_SIZE]; uint16_t dataLen; client->mqtt_state.outbound_message = mqtt_msg_subscribe(&client->mqtt_state.mqtt_connection, topic, 0, &client->mqtt_state.pending_msg_id); INFO("MQTT: queue subscribe, topic\"%s\", id: %d\r\n",topic, client->mqtt_state.pending_msg_id); while(QUEUE_Puts(&client->msgQueue, client->mqtt_state.outbound_message->data, client->mqtt_state.outbound_message->length) == -1){ INFO("MQTT: Queue full\r\n"); if(QUEUE_Gets(&client->msgQueue, dataBuffer, &dataLen, MQTT_BUF_SIZE) == -1) { INFO("MQTT: Serious buffer error\r\n"); return FALSE; } } system_os_post(MQTT_TASK_PRIO, 0, (os_param_t)client); return TRUE; }
// Lua: bool = mqtt:subscribe(topic, qos, function()) static int mqtt_socket_subscribe( lua_State* L ) { NODE_DBG("enter mqtt_socket_subscribe.\n"); uint8_t stack = 1, qos = 0; uint16_t msg_id = 0; const char *topic; size_t il; lmqtt_userdata *mud; mud = (lmqtt_userdata *) luaL_checkudata( L, stack, "mqtt.socket" ); luaL_argcheck( L, mud, stack, "mqtt.socket expected" ); stack++; if(mud==NULL){ NODE_DBG("userdata is nil.\n"); lua_pushboolean(L, 0); return 1; } if(mud->pesp_conn == NULL){ NODE_DBG("mud->pesp_conn is NULL.\n"); lua_pushboolean(L, 0); return 1; } if(!mud->connected){ luaL_error( L, "not connected" ); lua_pushboolean(L, 0); return 1; } 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; if( lua_istable( L, stack ) ) { NODE_DBG("subscribe table\n"); lua_pushnil( L ); /* first key */ uint8_t temp_buf[MQTT_BUF_SIZE]; uint32_t temp_pos = 0; while( lua_next( L, stack ) != 0 ) { topic = luaL_checkstring( L, -2 ); qos = luaL_checkinteger( L, -1 ); temp_msg = mqtt_msg_subscribe( &mud->mqtt_state.mqtt_connection, topic, qos, &msg_id ); NODE_DBG("topic: %s - qos: %d, length: %d\n", topic, qos, temp_msg->length); if (temp_pos + temp_msg->length > MQTT_BUF_SIZE){ lua_pop(L, 1); break; // too long message for the outbuffer. } c_memcpy( temp_buf + temp_pos, temp_msg->data, temp_msg->length ); temp_pos += temp_msg->length; lua_pop( L, 1 ); } if (temp_pos == 0){ luaL_error( L, "invalid data" ); lua_pushboolean(L, 0); return 1; } c_memcpy( temp_buffer, temp_buf, temp_pos ); temp_msg->data = temp_buffer; temp_msg->length = temp_pos; stack++; } else { NODE_DBG("subscribe string\n"); topic = luaL_checklstring( L, stack, &il ); stack++; if( topic == NULL ){ luaL_error( L, "need topic name" ); lua_pushboolean(L, 0); return 1; } qos = luaL_checkinteger( L, stack ); temp_msg = mqtt_msg_subscribe( &mud->mqtt_state.mqtt_connection, topic, qos, &msg_id ); stack++; } if( lua_type( L, stack ) == LUA_TFUNCTION || lua_type( L, stack ) == LUA_TLIGHTFUNCTION ) { // TODO: this will overwrite the previous one. lua_pushvalue( L, stack ); // copy argument (func) to the top of stack if( mud->cb_suback_ref != LUA_NOREF ) luaL_unref( L, LUA_REGISTRYINDEX, mud->cb_suback_ref ); mud->cb_suback_ref = luaL_ref( L, LUA_REGISTRYINDEX ); } msg_queue_t *node = msg_enqueue( &(mud->mqtt_state.pending_msg_q), temp_msg, msg_id, MQTT_MSG_TYPE_SUBSCRIBE, (int)mqtt_get_qos(temp_msg->data) ); NODE_DBG("topic: %s - id: %d - qos: %d, length: %d\n", topic, node->msg_id, node->publish_qos, node->msg.length); 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( mud->pesp_conn, node->msg.data, node->msg.length ); else espconn_sent( mud->pesp_conn, node->msg.data, node->msg.length ); mud->keep_alive_tick = 0; } if(!node){ lua_pushboolean(L, 0); } else { lua_pushboolean(L, 1); // enqueued succeed. } NODE_DBG("subscribe, queue size: %d\n", msg_size(&(mud->mqtt_state.pending_msg_q))); NODE_DBG("leave mqtt_socket_subscribe.\n"); return 1; }