/** * @brief MQTT publish function. * @param client: MQTT_Client reference * @param topic: string topic will publish to * @param data: buffer data send point to * @param data_length: length of data * @param qos: qos * @param retain: retain * @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) { uint8_t dataBuffer[MQTT_BUF_SIZE]; uint16_t dataLen; client->mqtt_state.outbound_message = mqtt_msg_publish(&client->mqtt_state.mqtt_connection, topic, data, data_length, qos, retain, &client->mqtt_state.pending_msg_id); if (client->mqtt_state.outbound_message->length == 0) { MQTT_INFO("MQTT: Queuing publish failed\r\n"); return FALSE; } MQTT_INFO("MQTT: queuing publish, length: %d, queue size(%d/%d)\r\n", client->mqtt_state.outbound_message->length, client->msgQueue.rb.fill_cnt, client->msgQueue.rb.size); while (QUEUE_Puts (&client->msgQueue, client->mqtt_state.outbound_message->data, client->mqtt_state.outbound_message->length) == -1) { MQTT_INFO("MQTT: Queue full\r\n"); if (QUEUE_Gets(&client->msgQueue, dataBuffer, &dataLen, MQTT_BUF_SIZE) == -1) { MQTT_INFO("MQTT: Serious buffer error\r\n"); return FALSE; } } system_os_post(MQTT_TASK_PRIO, 0, (os_param_t) client); return TRUE; }
// Publish the specified message int mqtt_publish_with_length(const char* topic, const char* data, int data_length, int qos, int retain) { if(!mqtt_ready()) return -1; printf("mqtt: sending publish...\n"); mqtt_state.outbound_message = mqtt_msg_publish(&mqtt_state.mqtt_connection, topic, data, data_length, qos, retain, &mqtt_state.pending_msg_id); mqtt_flags &= ~MQTT_FLAG_READY; mqtt_state.pending_msg_type = MQTT_MSG_TYPE_PUBLISH; tcpip_poll_tcp(mqtt_state.tcp_connection); return 0; }
BOOL ICACHE_FLASH_ATTR MQTT_Publish(MQTT_Client *client, const char* topic, const char* data, int data_length, int qos, int retain) { mqtt_message_t* outbound_message; outbound_message = mqtt_msg_publish(&client->mqtt_state.mqtt_connection, topic, data, data_length, qos, retain, &client->mqtt_state.pending_msg_id); //spam INFO("MQTT: queuing publish, length: %d...\r\n", outbound_message->length); if(QUEUE_Puts(&client->msgQueue, outbound_message->data, outbound_message->length) == -1){ //spam INFO("MQTT: Exceed the amount of queues\r\n"); return FALSE; } system_os_post(MQTT_TASK_PRIO, 0, (os_param_t)client); return TRUE; }
static void periodic_timer_cb(void) { mqtt_event_data_t event_data; uint8_t val, frac; uint16_t temp; printf("Ping timer %d\n", mqtt.keepalive_error); if (mqtt.state != MQTT_STATE_CONNECTED) { /* Not connected : try to reconnect */ printf("Try to reconnect\n"); mqtt_msg_connect_send(&mqtt); uip_udp_packet_send(mqtt.udp_connection, mqtt.data, mqtt.len); return; } if (mqtt.keepalive_error >= MAX_KEEPALIVE_ERROR) { PRINTF("DISCONNECTED\n"); mqtt.state = MQTT_STATE_CONNECTION_IN_PROGRESS; event_data.type = MQTT_EVENT_TYPE_DISCONNECTED; process_post_synch(mqtt.calling_process, mqtt_event, &event_data); return; } else { mqtt.keepalive_error++; } temp = onewire_temp_read(); val = temp / 100; frac = temp % 100; sprintf(temperature, "%d.%d", val, frac); printf("temperature : %s\n", temperature); mqtt_msg_publish(topic_name, temperature); mqtt_msg_ping_send(&mqtt, MQTT_MSG_PINGREQ); uip_udp_packet_send(mqtt.udp_connection, mqtt.data, mqtt.len); }
/** * @brief MQTT publish function. * @param client: MQTT_Client reference * @param topic: string topic will publish to * @param data: buffer data send point to * @param data_length: length of data * @param qos: qos * @param retain: retain * @retval TRUE if success queue */ bool ICACHE_FLASH_ATTR MQTT_Publish(MQTT_Client* client, const char* topic, const char* data, uint8_t qos, uint8_t retain) { // estimate the packet size to allocate a buffer uint16_t topic_length = os_strlen(topic); uint16_t data_length = os_strlen(data); // estimate: fixed hdr, pkt-id, topic length, topic, data, fudge uint16_t buf_len = 3 + 2 + 2 + topic_length + data_length + 16; PktBuf *buf = PktBuf_New(buf_len); if (buf == NULL) { os_printf("MQTT ERROR: Cannot allocate buffer for %d byte publish\n", buf_len); return FALSE; } // use a temporary mqtt_message_t pointing to our buffer, this is a bit of a mess because we // need to keep track of the message_id that is embedded in it mqtt_connection_t msg; msg_conn_init(&msg, &client->mqtt_connection, buf->data, buf_len); uint16_t msg_id; if (!mqtt_msg_publish(&msg, topic, data, data_length, qos, retain, &msg_id)){ os_printf("MQTT ERROR: Queuing Publish failed\n"); os_free(buf); return FALSE; } client->mqtt_connection.message_id = msg.message_id; if (msg.message.data != buf->data) os_memcpy(buf->data, msg.message.data, msg.message.length); buf->filled = msg.message.length; DBG_MQTT("MQTT: Publish, topic: \"%s\", length: %d\n", topic, msg.message.length); //dumpMem(buf, buf_len); client->msgQueue = PktBuf_Push(client->msgQueue, buf); if (!client->sending && client->pending_buffer == NULL) { mqtt_send_message(client); } return TRUE; }
// Lua: bool = mqtt:publish( topic, payload, qos, retain, function() ) static int mqtt_socket_publish( lua_State* L ) { NODE_DBG("enter mqtt_socket_publish.\n"); struct espconn *pesp_conn = NULL; lmqtt_userdata *mud; size_t l; uint8_t stack = 1; uint16_t msg_id = 0; 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; } const char *topic = luaL_checklstring( L, stack, &l ); stack ++; if (topic == NULL){ luaL_error( L, "need topic" ); lua_pushboolean(L, 0); return 1; } const char *payload = luaL_checklstring( L, stack, &l ); stack ++; uint8_t qos = luaL_checkinteger( L, stack); stack ++; uint8_t retain = luaL_checkinteger( L, stack); stack ++; 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 = mqtt_msg_publish(&mud->mqtt_state.mqtt_connection, topic, payload, l, qos, retain, &msg_id); 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(mud->cb_puback_ref != LUA_NOREF) luaL_unref(L, LUA_REGISTRYINDEX, mud->cb_puback_ref); mud->cb_puback_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_PUBLISH, (int)qos ); 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("publish, queue size: %d\n", msg_size(&(mud->mqtt_state.pending_msg_q))); NODE_DBG("leave mqtt_socket_publish.\n"); return 1; }