diff --git a/tasmota/support.ino b/tasmota/support.ino index 24fa920b9..fd65135a5 100644 --- a/tasmota/support.ino +++ b/tasmota/support.ino @@ -1178,10 +1178,12 @@ uint32_t ResponseLength(void) { } void ResponseClear(void) { + // Reset string length to zero TasmotaGlobal.mqtt_data[0] = '\0'; } void ResponseJsonStart(void) { + // Insert a JSON start bracket { TasmotaGlobal.mqtt_data[0] = '{'; } diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino index b4c088bad..6b85364d3 100644 --- a/tasmota/support_command.ino +++ b/tasmota/support_command.ino @@ -305,18 +305,6 @@ void CommandHandler(char* topicBuf, char* dataBuf, uint32_t data_len) } if (ResponseLength()) { -/* - // Add "Command":"POWERONSTATE", like: - // 12:15:37 MQT: stat/wemos4/RESULT = {"Command":"POWERONSTATE","PowerOnState":3} - char json_command[TOPSZ]; - snprintf_P(json_command, sizeof(json_command), PSTR("{\"" D_JSON_COMMAND "\":\"%s\","), type); - uint32_t jc_len = strlen(json_command); - uint32_t mq_len = ResponseLength() +1; - if (mq_len < ResponseSize() - jc_len) { - memmove(TasmotaGlobal.mqtt_data +jc_len -1, TasmotaGlobal.mqtt_data, mq_len); - memmove(TasmotaGlobal.mqtt_data, json_command, jc_len); - } -*/ MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_STAT, type); } TasmotaGlobal.fallback_topic_flag = false; diff --git a/tasmota/tasmota_globals.h b/tasmota/tasmota_globals.h index bc0f9cd74..e451563c8 100644 --- a/tasmota/tasmota_globals.h +++ b/tasmota/tasmota_globals.h @@ -268,6 +268,7 @@ const uint16_t LOG_BUFFER_SIZE = 4000; // Max number of characters in lo #ifndef MQTT_MAX_PACKET_SIZE #define MQTT_MAX_PACKET_SIZE 1200 // Bytes +//#define MQTT_MAX_PACKET_SIZE 2048 // Bytes #endif #ifndef MQTT_KEEPALIVE #define MQTT_KEEPALIVE 30 // Seconds @@ -288,6 +289,8 @@ const uint16_t LOG_BUFFER_SIZE = 4000; // Max number of characters in lo #ifndef MESSZ //#define MESSZ 1040 // Max number of characters in JSON message string (Hass discovery and nice MQTT_MAX_PACKET_SIZE = 1200) #define MESSZ (MQTT_MAX_PACKET_SIZE -TOPSZ -7) // Max number of characters in JSON message string +//#define MESSZ MQTT_MAX_PACKET_SIZE // Max number of characters in JSON message string +//#define MESSZ 2048 // Max number of characters in JSON message string #endif #ifndef USE_DEVICE_GROUPS diff --git a/tasmota/xdrv_02_mqtt_1_file.ino b/tasmota/xdrv_02_mqtt_1_file.ino index 942576d63..952f5525c 100644 --- a/tasmota/xdrv_02_mqtt_1_file.ino +++ b/tasmota/xdrv_02_mqtt_1_file.ino @@ -259,8 +259,7 @@ void CmndFileUpload(void) { /* The upload chunk size is the data size of the payload. - It can be larger than the download chunksize which is bound by MESSZ - The PubSubClient upload buffer with length MQTT_MAX_PACKET_SIZE (1200) contains + The PubSubClient upload buffer with length MQTT_MAX_PACKET_SIZE contains - Header of 5 bytes (MQTT_MAX_HEADER_SIZE) - Topic string terminated with a zero (stat/demo/FILEUPLOAD) - Payload ({"Id":116,"Data":""}) or () @@ -378,36 +377,40 @@ void CmndFileDownload(void) { */ if (FMqtt.file_buffer) { if (FMqtt.file_pos < FMqtt.file_size) { + uint32_t chunk_size = 4096; + if (!FMqtt.file_binary) { + /* + The download chunk size is the data size before it is encoded to base64. + The download buffer contains + - Payload ({"Id":117,"Data":""}) + */ + chunk_size = (((ResponseSize() - FileTransferHeaderSize) / 4) * 3) -2; + } uint32_t bytes_left = FMqtt.file_size - FMqtt.file_pos; - - /* - The download chunk size is the data size before it is encoded to base64. - It is smaller than the upload chunksize as it is bound by MESSZ - The download buffer with length MESSZ (1042) contains - - Payload ({"Id":117,"Data":""}) - */ - const uint32_t mqtt_file_chunk_size = (((MESSZ - FileTransferHeaderSize) / 4) * 3) -2; - uint32_t chunk_size = (FMqtt.file_binary) ? 4096 : mqtt_file_chunk_size; uint32_t write_bytes = (bytes_left < chunk_size) ? bytes_left : chunk_size; - uint8_t* buffer = FMqtt.file_buffer + FMqtt.file_pos; FMqtt.md5.add(buffer, write_bytes); - FMqtt.file_pos += write_bytes; if (FMqtt.file_binary) { + // Binary data up to 4k MqttPublishPayloadPrefixTopic_P(STAT, XdrvMailbox.command, (const char*)buffer, write_bytes); } else { // {"Id":117,"Data":"CRJcTQ9fYGF ... OT1BRUlNUVVZXWFk="} - Response_P(PSTR("{\"Id\":%d,\"Data\":\""), FMqtt.file_id); // FileTransferHeaderSize - char base64_data[encode_base64_length(write_bytes)]; - encode_base64((unsigned char*)buffer, write_bytes, (unsigned char*)base64_data); - ResponseAppend_P(base64_data); - ResponseAppend_P("\"}"); - MqttPublishPrefixTopic_P(STAT, XdrvMailbox.command); + char* base64_data = (char*)malloc(encode_base64_length(write_bytes) +2); + if (base64_data) { + Response_P(PSTR("{\"Id\":%d,\"Data\":\""), FMqtt.file_id); // FileTransferHeaderSize + encode_base64((unsigned char*)buffer, write_bytes, (unsigned char*)base64_data); + ResponseAppend_P(base64_data); + ResponseAppend_P("\"}"); + MqttPublishPrefixTopic_P(STAT, XdrvMailbox.command); + free(base64_data); + } else { + XdrvMailbox.payload = 0; // Abort + } } ResponseClear(); - return; + if (XdrvMailbox.payload != 0) { return; } // No error } else { FMqtt.md5.calculate(); diff --git a/tasmota/xdrv_02_mqtt_9_impl.ino b/tasmota/xdrv_02_mqtt_9_impl.ino index aa9214f5a..506b8ebaa 100644 --- a/tasmota/xdrv_02_mqtt_9_impl.ino +++ b/tasmota/xdrv_02_mqtt_9_impl.ino @@ -534,7 +534,6 @@ void MqttDataHandler(char* mqtt_topic, uint8_t* mqtt_data, unsigned int data_len // AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_MQTT "BufferSize %d, Topic |%s|, Length %d, data_len %d"), MqttClient.getBufferSize(), mqtt_topic, strlen(mqtt_topic), data_len); - // Save MQTT data ASAP as it's data is discarded by PubSubClient with next publish as used in MQTTlog char topic[TOPSZ]; #ifdef USE_MQTT_AZURE_IOT // for Azure, we read the topic from the property of the message @@ -557,8 +556,6 @@ void MqttDataHandler(char* mqtt_topic, uint8_t* mqtt_data, unsigned int data_len strlcpy(topic, mqtt_topic, sizeof(topic)); #endif // USE_MQTT_AZURE_IOT mqtt_data[data_len] = 0; - char data[data_len +1]; - memcpy(data, mqtt_data, sizeof(data)); if (Mqtt.disable_logging) { TasmotaGlobal.masterlog_level = LOG_LEVEL_DEBUG_MORE; // Hide logging @@ -568,12 +565,12 @@ void MqttDataHandler(char* mqtt_topic, uint8_t* mqtt_data, unsigned int data_len XdrvMailbox.index = strlen(topic); XdrvMailbox.data_len = data_len; XdrvMailbox.topic = topic; - XdrvMailbox.data = (char*)data; + XdrvMailbox.data = (char*)mqtt_data; if (XdrvCall(FUNC_MQTT_DATA)) { return; } ShowSource(SRC_MQTT); - CommandHandler(topic, data, data_len); + CommandHandler(topic, (char*)mqtt_data, data_len); if (Mqtt.disable_logging) { TasmotaGlobal.masterlog_level = LOG_LEVEL_NONE; // Enable logging @@ -608,7 +605,7 @@ void MqttPublishLoggingAsync(bool refresh) { char stopic[TOPSZ]; GetTopic_P(stopic, STAT, TasmotaGlobal.mqtt_topic, PSTR("LOGGING")); // strlcpy(TasmotaGlobal.mqtt_data, line, len); // No JSON and ugly!! -// MqttPublishLib(stopic, (const uint8_t*)TasmotaGlobal.mqtt_data, strlen(TasmotaGlobal.mqtt_data), false); +// MqttPublishLib(stopic, (const uint8_t*)TasmotaGlobal.mqtt_data, ResponseLength(), false); MqttPublishLib(stopic, (const uint8_t*)line, len -1, false); } } diff --git a/tasmota/xdrv_10_rules.ino b/tasmota/xdrv_10_rules.ino index fc0b772f4..1f6536b4a 100644 --- a/tasmota/xdrv_10_rules.ino +++ b/tasmota/xdrv_10_rules.ino @@ -984,7 +984,7 @@ void RulesEvery100ms(void) { TasmotaGlobal.tele_period = 2; // Do not allow HA updates during next function call XsnsNextCall(FUNC_JSON_APPEND, xsns_index); // ,"INA219":{"Voltage":4.494,"Current":0.020,"Power":0.089} TasmotaGlobal.tele_period = tele_period_save; - if (strlen(TasmotaGlobal.mqtt_data)) { + if (ResponseLength()) { ResponseJsonStart(); // {"INA219":{"Voltage":4.494,"Current":0.020,"Power":0.089} ResponseJsonEnd(); RulesProcessEvent(TasmotaGlobal.mqtt_data); diff --git a/tasmota/xdrv_10_scripter.ino b/tasmota/xdrv_10_scripter.ino index 396a52888..7d5f1c074 100755 --- a/tasmota/xdrv_10_scripter.ino +++ b/tasmota/xdrv_10_scripter.ino @@ -2424,9 +2424,9 @@ chknext: } } else { // preserve mqtt_data - char *mqd = (char*)malloc(MESSZ+2); + char *mqd = (char*)malloc(ResponseSize()+2); if (mqd) { - strlcpy(mqd, TasmotaGlobal.mqtt_data, MESSZ); + strlcpy(mqd, TasmotaGlobal.mqtt_data, ResponseSize()); wd = mqd; char *lwd = wd; while (index) { @@ -7703,7 +7703,7 @@ int32_t http_req(char *host, char *request) { } #ifdef USE_WEBSEND_RESPONSE - strlcpy(TasmotaGlobal.mqtt_data, http.getString().c_str(), MESSZ); + strlcpy(TasmotaGlobal.mqtt_data, http.getString().c_str(), ResponseSize()); //AddLog(LOG_LEVEL_INFO, PSTR("HTTP RESULT %s"), TasmotaGlobal.mqtt_data); Run_Scripter(">E", 2, TasmotaGlobal.mqtt_data); glob_script_mem.glob_error = 0; diff --git a/tasmota/xdrv_12_home_assistant.ino b/tasmota/xdrv_12_home_assistant.ino index 564e6f4ba..46bfcf9c1 100644 --- a/tasmota/xdrv_12_home_assistant.ino +++ b/tasmota/xdrv_12_home_assistant.ino @@ -876,7 +876,7 @@ void HAssAnnounceSensors(void) TasmotaGlobal.tele_period = 2; // Do not allow HA updates during next function call XsnsNextCall(FUNC_JSON_APPEND, hass_xsns_index); // ,"INA219":{"Voltage":4.494,"Current":0.020,"Power":0.089} TasmotaGlobal.tele_period = tele_period_save; - size_t sensordata_len = strlen(TasmotaGlobal.mqtt_data); + size_t sensordata_len = ResponseLength(); char sensordata[sensordata_len+2]; // dynamically adjust the size strcpy(sensordata, TasmotaGlobal.mqtt_data); // we can use strcpy since the buffer has the right size diff --git a/tasmota/xdrv_13_display.ino b/tasmota/xdrv_13_display.ino index ee85c2f0d..0f464410a 100755 --- a/tasmota/xdrv_13_display.ino +++ b/tasmota/xdrv_13_display.ino @@ -1292,7 +1292,7 @@ void draw_dt_vars(void) { void DisplayDTVarsTeleperiod(void) { ResponseClear(); MqttShowState(); - uint32_t jlen = strlen(TasmotaGlobal.mqtt_data); + uint32_t jlen = ResponseLength(); if (jlen < DTV_JSON_SIZE) { char *json = (char*)malloc(jlen + 2); diff --git a/tasmota/xdrv_49_pid.ino b/tasmota/xdrv_49_pid.ino index 8dfc7c29c..f54003bac 100644 --- a/tasmota/xdrv_49_pid.ino +++ b/tasmota/xdrv_49_pid.ino @@ -393,7 +393,7 @@ void PIDRun(void) { // `%topic%/PID {"power":"0.000"}` char str_buf[FLOATSZ]; dtostrfd(power, 3, str_buf); - snprintf_P(TasmotaGlobal.mqtt_data, sizeof(TasmotaGlobal.mqtt_data), PSTR("{\"%s\":\"%s\"}"), "power", str_buf); + Response_P(PSTR("{\"%s\":\"%s\"}"), "power", str_buf); MqttPublishPrefixTopicRulesProcess_P(TELE, "PID"); #endif // PID_DONT_USE_PID_TOPIC diff --git a/tasmota/xdrv_79_esp32_ble.ino b/tasmota/xdrv_79_esp32_ble.ino index 5fabfe5cc..9b816c63f 100644 --- a/tasmota/xdrv_79_esp32_ble.ino +++ b/tasmota/xdrv_79_esp32_ble.ino @@ -54,7 +54,7 @@ AABBCCDDEEFF/n (n = 0..3) where n indicates the TYPE of address most notably, if you wish to connect to a random address (n = 1), then you must specify, else it will not connect. - e.g. to alias a random address to fred: + e.g. to alias a random address to fred: BLEAlias fred=1234567890/1 to connect and read fred's name: BLEName fred @@ -68,14 +68,14 @@ BLEAdv - unused BLEOp advanced - perform a BLE active operation - mainly for debug or unsupported devices. + mainly for debug or unsupported devices. BLEMode - control scanning mode + control scanning mode 0 - stop BLE 1 - run BLE but manual scan *2 - run BLE with auto scan BLEDetails - display details of adverts + display details of adverts BLEdetails0 - no display BLEdetails2 - display for one device BLEdetails3 - display for ALL devices @@ -98,7 +98,7 @@ BLEDevices display or clear the devices list BLEDevices0 - clear list - BLEDevices1 - publish on tele + BLEDevices1 - publish on tele BLEMaxAge display or set the max age of a BLE address before being forgotten BLEMaxAge - display the setting @@ -1164,8 +1164,8 @@ void setDetails(ble_advertisment_t *ad){ p += len; maxlen -= len; if (ad->addrtype){ - *(p++) = '/'; - *(p++) = 0x30+ad->addrtype; + *(p++) = '/'; + *(p++) = 0x30+ad->addrtype; } *(p++) = '\"'; maxlen--; @@ -3145,10 +3145,9 @@ static void BLEPostMQTTSeenDevices(int type) { nextSeenDev = 0; memset(TasmotaGlobal.mqtt_data, 0, sizeof(TasmotaGlobal.mqtt_data)); - ResponseTime_P(PSTR("")); - int timelen = strlen(TasmotaGlobal.mqtt_data); + int timelen = ResponseTime_P(PSTR("")); char *dest = TasmotaGlobal.mqtt_data + timelen; - int maxlen = (sizeof(TasmotaGlobal.mqtt_data)-20) - timelen; + int maxlen = ResponseSize() -20 -timelen; // if (!TasmotaGlobal.ota_state_flag){ do { @@ -3340,7 +3339,7 @@ static void mainThreadOpCallbacks() { // always remove from here completedOperations.erase(completedOperations.begin() + i); - // unless some callback told us not to send on MQTT, then remove from completed and + // unless some callback told us not to send on MQTT, then remove from completed and // add to mqtt list if (!callbackres){ addOperation(&mqttOperations, &op); @@ -3595,14 +3594,14 @@ void HandleBleConfiguration(void) int ExtStopBLE(){ AddLog(LOG_LEVEL_INFO, PSTR("BLE: Stopping if active")); - BLE_ESP32::BLEEnableMask = 0; + BLE_ESP32::BLEEnableMask = 0; BLE_ESP32::stopStartBLE(); return 0; } int ExtRestartBLEIfEnabled(){ AddLog(LOG_LEVEL_INFO, PSTR("BLE: Starting if active")); - BLE_ESP32::BLEEnableMask = 1; + BLE_ESP32::BLEEnableMask = 1; BLE_ESP32::stopStartBLE(); return 0; } @@ -3738,7 +3737,7 @@ void sendExample(){ #endif } // end #ifdef BLE_ESP32_EXAMPLES -#endif +#endif #endif diff --git a/tasmota/xdrv_99_debug.ino b/tasmota/xdrv_99_debug.ino index d7e82b053..6c4c57ce3 100644 --- a/tasmota/xdrv_99_debug.ino +++ b/tasmota/xdrv_99_debug.ino @@ -512,10 +512,10 @@ void CmndCfgPoke(void) void CmndCfgXor(void) { if (XdrvMailbox.data_len > 0) { - Web.config_xor_on_set = XdrvMailbox.payload; + config_xor_on_set = XdrvMailbox.payload; } char temp[10]; - snprintf_P(temp, sizeof(temp), PSTR("0x%02X"), Web.config_xor_on_set); + snprintf_P(temp, sizeof(temp), PSTR("0x%02X"), config_xor_on_set); ResponseCmndChar(temp); } #endif // USE_WEBSERVER diff --git a/tasmota/xsns_61_MI_NRF24.ino b/tasmota/xsns_61_MI_NRF24.ino index 9ec551acd..7282435fe 100644 --- a/tasmota/xsns_61_MI_NRF24.ino +++ b/tasmota/xsns_61_MI_NRF24.ino @@ -1708,7 +1708,7 @@ void MINRFShow(bool json) ResponseAppend_P(PSTR(",\"%s-%02x%02x%02x\":"),kMINRFDeviceType[MIBLEsensors[i].type-1],MIBLEsensors[i].MAC[3],MIBLEsensors[i].MAC[4],MIBLEsensors[i].MAC[5]); - uint32_t _positionCurlyBracket = strlen(TasmotaGlobal.mqtt_data); // ... this will be a ',' first, but later be replaced + uint32_t _positionCurlyBracket = ResponseLength(); // ... this will be a ',' first, but later be replaced if((!MINRF.mode.triggeredTele && !MINRF.option.minimalSummary)||MINRF.mode.triggeredTele){ bool tempHumSended = false; @@ -1811,7 +1811,7 @@ void MINRFShow(bool json) } } } - if(_positionCurlyBracket==strlen(TasmotaGlobal.mqtt_data)) ResponseAppend_P(PSTR(",")); // write some random char, to be overwritten in the next step + if(_positionCurlyBracket==ResponseLength()) ResponseAppend_P(PSTR(",")); // write some random char, to be overwritten in the next step ResponseAppend_P(PSTR("}")); TasmotaGlobal.mqtt_data[_positionCurlyBracket] = '{'; MIBLEsensors[i].eventType.raw = 0; diff --git a/tasmota/xsns_62_MI_HM10.ino b/tasmota/xsns_62_MI_HM10.ino index 680beaa7e..ffb2bd81e 100644 --- a/tasmota/xsns_62_MI_HM10.ino +++ b/tasmota/xsns_62_MI_HM10.ino @@ -459,7 +459,7 @@ void HM10_ReverseMAC(uint8_t _mac[]){ */ void HM10nullifyEndOfMQTT_DATA(){ - char *p = TasmotaGlobal.mqtt_data + strlen(TasmotaGlobal.mqtt_data); + char *p = TasmotaGlobal.mqtt_data + ResponseLength(); while(true){ *p--; if(p[0]==':'){ @@ -1052,12 +1052,14 @@ void HM10addBeacon(uint8_t index, char* data){ void HM10showScanResults(){ size_t _size = MIBLEscanResult.size(); ResponseAppend_P(PSTR(",\"BLEScan\":{\"Found\":%u,\"Devices\":["), _size); + bool add_comma = false; for(auto _scanResult : MIBLEscanResult){ char _MAC[18]; ToHex_P(_scanResult.MAC,6,_MAC,18,':'); - ResponseAppend_P(PSTR("{\"MAC\":\"%s\",\"CID\":\"0x%04x\",\"SVC\":\"0x%04x\",\"UUID\":\"0x%04x\",\"RSSI\":%d},"), _MAC, _scanResult.CID, _scanResult.SVC, _scanResult.UUID, _scanResult.RSSI); + ResponseAppend_P(PSTR("%s{\"MAC\":\"%s\",\"CID\":\"0x%04x\",\"SVC\":\"0x%04x\",\"UUID\":\"0x%04x\",\"RSSI\":%d}"), + (add_comma)?",":"", _MAC, _scanResult.CID, _scanResult.SVC, _scanResult.UUID, _scanResult.RSSI); + add_comma = true; } - if(_size != 0)TasmotaGlobal.mqtt_data[strlen(TasmotaGlobal.mqtt_data)-1] = 0; // delete last comma ResponseAppend_P(PSTR("]}")); MIBLEscanResult.clear(); HM10.mode.shallShowScanResult = 0; @@ -1065,12 +1067,13 @@ void HM10showScanResults(){ void HM10showBlockList(){ ResponseAppend_P(PSTR(",\"Block\":[")); + bool add_comma = false; for(auto _scanResult : MIBLEBlockList){ char _MAC[18]; ToHex_P(_scanResult.buf,6,_MAC,18,':'); - ResponseAppend_P(PSTR("\"%s\","), _MAC); + ResponseAppend_P(PSTR("%s\"%s\""), (add_comma)?",":"", _MAC); + add_comma = true; } - if(MIBLEBlockList.size()!=0) TasmotaGlobal.mqtt_data[strlen(TasmotaGlobal.mqtt_data)-1] = 0; // delete last comma ResponseAppend_P(PSTR("]")); HM10.mode.shallShowBlockList = 0; } @@ -1782,7 +1785,7 @@ void HM10Show(bool json) kHM10DeviceType[MIBLEsensors[i].type-1], MIBLEsensors[i].MAC[3], MIBLEsensors[i].MAC[4], MIBLEsensors[i].MAC[5]); - uint32_t _positionCurlyBracket = strlen(TasmotaGlobal.mqtt_data); // ... this will be a ',' first, but later be replaced + uint32_t _positionCurlyBracket = ResponseLength(); // ... this will be a ',' first, but later be replaced if((!HM10.mode.triggeredTele && !HM10.option.minimalSummary)||HM10.mode.triggeredTele){ bool tempHumSended = false; @@ -1910,7 +1913,7 @@ void HM10Show(bool json) if (HM10.option.showRSSI) ResponseAppend_P(PSTR(",\"RSSI\":%d"), MIBLEsensors[i].rssi); - if(_positionCurlyBracket==strlen(TasmotaGlobal.mqtt_data)) ResponseAppend_P(PSTR(",")); // write some random char, to be overwritten in the next step + if(_positionCurlyBracket==ResponseLength()) ResponseAppend_P(PSTR(",")); // write some random char, to be overwritten in the next step ResponseAppend_P(PSTR("}")); TasmotaGlobal.mqtt_data[_positionCurlyBracket] = '{'; MIBLEsensors[i].eventType.raw = 0; diff --git a/tasmota/xsns_62_esp32_mi.ino b/tasmota/xsns_62_esp32_mi.ino index 2d0f9ef79..3a9a3a68a 100644 --- a/tasmota/xsns_62_esp32_mi.ino +++ b/tasmota/xsns_62_esp32_mi.ino @@ -634,7 +634,7 @@ int MI32_decryptPacket(char *_buf, uint16_t _bufSize, uint32_t _type){ */ void MI32nullifyEndOfMQTT_DATA(){ - char *p = TasmotaGlobal.mqtt_data + strlen(TasmotaGlobal.mqtt_data); + char *p = TasmotaGlobal.mqtt_data + ResponseLength(); while(true){ *p--; if(p[0]==':'){ @@ -1598,12 +1598,14 @@ void MI32addBeacon(uint8_t index, char* data){ void MI32showScanResults(){ size_t _size = MIBLEscanResult.size(); ResponseAppend_P(PSTR(",\"BLEScan\":{\"Found\":%u,\"Devices\":["), _size); + bool add_comma = false; for(auto _scanResult : MIBLEscanResult){ char _MAC[18]; ToHex_P(_scanResult.MAC,6,_MAC,18,':'); - ResponseAppend_P(PSTR("{\"MAC\":\"%s\",\"CID\":\"0x%04x\",\"SVC\":\"0x%04x\",\"UUID\":\"0x%04x\",\"RSSI\":%d},"), _MAC, _scanResult.CID, _scanResult.SVC, _scanResult.UUID, _scanResult.RSSI); + ResponseAppend_P(PSTR("%s{\"MAC\":\"%s\",\"CID\":\"0x%04x\",\"SVC\":\"0x%04x\",\"UUID\":\"0x%04x\",\"RSSI\":%d}"), + (add_comma)?",":"", _MAC, _scanResult.CID, _scanResult.SVC, _scanResult.UUID, _scanResult.RSSI); + add_comma = true; } - if(_size != 0)TasmotaGlobal.mqtt_data[strlen(TasmotaGlobal.mqtt_data)-1] = 0; // delete last comma ResponseAppend_P(PSTR("]}")); MIBLEscanResult.clear(); MI32.mode.shallShowScanResult = 0; @@ -1611,12 +1613,13 @@ void MI32showScanResults(){ void MI32showBlockList(){ ResponseAppend_P(PSTR(",\"Block\":[")); + bool add_comma = false; for(auto _scanResult : MIBLEBlockList){ char _MAC[18]; ToHex_P(_scanResult.buf,6,_MAC,18,':'); - ResponseAppend_P(PSTR("\"%s\","), _MAC); + ResponseAppend_P(PSTR("%s\"%s\""), (add_comma)?",":"", _MAC); + add_comma = true; } - if(MIBLEBlockList.size()!=0) TasmotaGlobal.mqtt_data[strlen(TasmotaGlobal.mqtt_data)-1] = 0; // delete last comma ResponseAppend_P(PSTR("]")); MI32.mode.shallShowBlockList = 0; } @@ -2027,7 +2030,7 @@ void MI32Show(bool json) kMI32DeviceType[MIBLEsensors[i].type-1], MIBLEsensors[i].MAC[3], MIBLEsensors[i].MAC[4], MIBLEsensors[i].MAC[5]); - uint32_t _positionCurlyBracket = strlen(TasmotaGlobal.mqtt_data); // ... this will be a ',' first, but later be replaced + uint32_t _positionCurlyBracket = ResponseLength(); // ... this will be a ',' first, but later be replaced if((!MI32.mode.triggeredTele && !MI32.option.minimalSummary)||MI32.mode.triggeredTele){ bool tempHumSended = false; @@ -2158,7 +2161,7 @@ void MI32Show(bool json) } if (MI32.option.showRSSI) ResponseAppend_P(PSTR(",\"RSSI\":%d"), MIBLEsensors[i].RSSI); - if(_positionCurlyBracket==strlen(TasmotaGlobal.mqtt_data)) ResponseAppend_P(PSTR(",")); // write some random char, to be overwritten in the next step + if(_positionCurlyBracket==ResponseLength()) ResponseAppend_P(PSTR(",")); // write some random char, to be overwritten in the next step ResponseAppend_P(PSTR("}")); TasmotaGlobal.mqtt_data[_positionCurlyBracket] = '{'; MIBLEsensors[i].eventType.raw = 0; diff --git a/tasmota/xsns_62_esp32_mi_ble.ino b/tasmota/xsns_62_esp32_mi_ble.ino index c0afcc649..1c12aa245 100644 --- a/tasmota/xsns_62_esp32_mi_ble.ino +++ b/tasmota/xsns_62_esp32_mi_ble.ino @@ -1341,7 +1341,7 @@ int MIParsePacket(const uint8_t* slotmac, struct mi_beacon_data_t *parsed, const */ void MI32nullifyEndOfMQTT_DATA(){ - char *p = TasmotaGlobal.mqtt_data + strlen(TasmotaGlobal.mqtt_data); + char *p = TasmotaGlobal.mqtt_data + ResponseLength(); while(true){ *p--; if(p[0]==':'){ diff --git a/tasmota/xsns_75_prometheus.ino b/tasmota/xsns_75_prometheus.ino index 223312987..a358f9697 100644 --- a/tasmota/xsns_75_prometheus.ino +++ b/tasmota/xsns_75_prometheus.ino @@ -132,7 +132,7 @@ void HandleMetrics(void) { ResponseClear(); MqttShowSensor(); //Pull sensor data - char json[strlen(TasmotaGlobal.mqtt_data)+1]; + char json[ResponseLength()+1]; snprintf_P(json, sizeof(json), TasmotaGlobal.mqtt_data); String jsonStr = json; JsonParser parser((char *)jsonStr.c_str());