123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220 |
- //
- // MQTT Commands coming in from the attache microcontrollver over the serial port
- //
- #include <esp8266.h>
- #include "mqtt.h"
- #include "mqtt_client.h"
- #include "mqtt_cmd.h"
- #ifdef MQTTCMD_DBG
- #define DBG(format, ...) do { os_printf(format, ## __VA_ARGS__); } while(0)
- #else
- #define DBG(format, ...) do { } while(0)
- #endif
- static bool blocked; // flag to prevent MQTT from sending on serial while trying to PGM uC
- void ICACHE_FLASH_ATTR
- mqtt_block() { blocked = true; }
- void ICACHE_FLASH_ATTR
- mqtt_unblock() { blocked = false; }
- void ICACHE_FLASH_ATTR
- cmdMqttConnectedCb(MQTT_Client* client) {
- if (blocked) return;
- MqttCmdCb* cb = (MqttCmdCb*)client->user_data;
- DBG("MQTT: Connected Cb=%p\n", (void*)cb->connectedCb);
- cmdResponseStart(CMD_RESP_CB, cb->connectedCb, 0);
- cmdResponseEnd();
- }
- void ICACHE_FLASH_ATTR
- cmdMqttDisconnectedCb(MQTT_Client* client) {
- if (blocked) return;
- MqttCmdCb* cb = (MqttCmdCb*)client->user_data;
- DBG("MQTT: Disconnected cb=%p\n", (void*)cb->disconnectedCb);
- cmdResponseStart(CMD_RESP_CB, cb->disconnectedCb, 0);
- cmdResponseEnd();
- }
- void ICACHE_FLASH_ATTR
- cmdMqttPublishedCb(MQTT_Client* client) {
- if (blocked) return;
- MqttCmdCb* cb = (MqttCmdCb*)client->user_data;
- DBG("MQTT: Published cb=%p\n", (void*)cb->publishedCb);
- cmdResponseStart(CMD_RESP_CB, cb->publishedCb, 0);
- cmdResponseEnd();
- }
- void ICACHE_FLASH_ATTR
- cmdMqttDataCb(MQTT_Client* client, const char* topic, uint32_t topic_len,
- const char* data, uint32_t data_len)
- {
- if (blocked) return;
- MqttCmdCb* cb = (MqttCmdCb*)client->user_data;
- DBG("MQTT: Data cb=%p topic=%s len=%u\n", (void*)cb->dataCb, topic, data_len);
- cmdResponseStart(CMD_RESP_CB, cb->dataCb, 2);
- cmdResponseBody(topic, topic_len);
- cmdResponseBody(data, data_len);
- cmdResponseEnd();
- }
- void ICACHE_FLASH_ATTR
- MQTTCMD_Lwt(CmdPacket *cmd) {
- CmdRequest req;
- cmdRequest(&req, cmd);
- if (cmdGetArgc(&req) != 4) return;
- MQTT_Client* client = &mqttClient;
- // free old topic & message
- if (client->connect_info.will_topic)
- os_free(client->connect_info.will_topic);
- if (client->connect_info.will_message)
- os_free(client->connect_info.will_message);
- uint16_t len;
- // get topic
- len = cmdArgLen(&req);
- if (len > 128) return; // safety check
- client->connect_info.will_topic = (char*)os_zalloc(len + 1);
- cmdPopArg(&req, client->connect_info.will_topic, len);
- client->connect_info.will_topic[len] = 0;
- // get message
- len = cmdArgLen(&req);
- if (len > 128) return; // safety check
- client->connect_info.will_message = (char*)os_zalloc(len + 1);
- cmdPopArg(&req, client->connect_info.will_message, len);
- client->connect_info.will_message[len] = 0;
- // get qos
- cmdPopArg(&req, (uint8_t*)&client->connect_info.will_qos, 4);
- // get retain
- cmdPopArg(&req, (uint8_t*)&client->connect_info.will_retain, 4);
- DBG("MQTT: MQTTCMD_Lwt topic=%s, message=%s, qos=%d, retain=%d\n",
- client->connect_info.will_topic,
- client->connect_info.will_message,
- client->connect_info.will_qos,
- client->connect_info.will_retain);
- // trigger a reconnect to set the LWT
- MQTT_Reconnect(client);
- }
- void ICACHE_FLASH_ATTR
- MQTTCMD_Publish(CmdPacket *cmd) {
- CmdRequest req;
- cmdRequest(&req, cmd);
- if (cmdGetArgc(&req) != 5) return;
- MQTT_Client* client = &mqttClient;
- uint16_t len;
- // get topic
- len = cmdArgLen(&req);
- if (len > 128) return; // safety check
- uint8_t *topic = (uint8_t*)os_zalloc(len + 1);
- cmdPopArg(&req, topic, len);
- topic[len] = 0;
- // get data
- len = cmdArgLen(&req);
- uint8_t *data = (uint8_t*)os_zalloc(len+1);
- if (!data) { // safety check
- os_free(topic);
- return;
- }
- cmdPopArg(&req, data, len);
- data[len] = 0;
- uint16_t data_len;
- uint8_t qos, retain;
- // get data length
- cmdPopArg(&req, &data_len, sizeof(data_len));
- // get qos
- cmdPopArg(&req, &qos, sizeof(qos));
- // get retain
- cmdPopArg(&req, &retain, sizeof(retain));
- DBG("MQTT: MQTTCMD_Publish topic=%s, data_len=%d, qos=%d, retain=%d\n",
- topic, data_len, qos, retain);
- MQTT_Publish(client, (char*)topic, (char*)data, data_len, qos%3, retain&1);
- os_free(topic);
- os_free(data);
- return;
- }
- void ICACHE_FLASH_ATTR
- MQTTCMD_Subscribe(CmdPacket *cmd) {
- CmdRequest req;
- cmdRequest(&req, cmd);
- if (cmdGetArgc(&req) != 2) return;
- MQTT_Client* client = &mqttClient;
- uint16_t len;
- // get topic
- len = cmdArgLen(&req);
- if (len > 128) return; // safety check
- uint8_t* topic = (uint8_t*)os_zalloc(len + 1);
- cmdPopArg(&req, topic, len);
- topic[len] = 0;
- // get qos
- uint32_t qos = 0;
- cmdPopArg(&req, (uint8_t*)&qos, 4);
- DBG("MQTT: MQTTCMD_Subscribe topic=%s, qos=%u\n", topic, qos);
- MQTT_Subscribe(client, (char*)topic, (uint8_t)qos);
- os_free(topic);
- return;
- }
- void ICACHE_FLASH_ATTR
- MQTTCMD_Setup(CmdPacket *cmd) {
- CmdRequest req;
- cmdRequest(&req, cmd);
- MQTT_Client* client = &mqttClient;
- if (cmdGetArgc(&req) != 4) return;
- // create callback
- MqttCmdCb* callback = (MqttCmdCb*)os_zalloc(sizeof(MqttCmdCb));
- cmdPopArg(&req, &callback->connectedCb, 4);
- cmdPopArg(&req, &callback->disconnectedCb, 4);
- cmdPopArg(&req, &callback->publishedCb, 4);
- cmdPopArg(&req, &callback->dataCb, 4);
- client->user_data = callback;
- DBG("MQTT connectedCb=%x\n", callback->connectedCb);
- client->cmdConnectedCb = cmdMqttConnectedCb;
- client->cmdDisconnectedCb = cmdMqttDisconnectedCb;
- client->cmdPublishedCb = cmdMqttPublishedCb;
- client->cmdDataCb = cmdMqttDataCb;
- if (client->connState == MQTT_CONNECTED) {
- if (callback->connectedCb)
- cmdMqttConnectedCb(client);
- } else if (callback->disconnectedCb) {
- cmdMqttDisconnectedCb(client);
- }
- }
|