mirror of https://github.com/arendst/Tasmota.git
Fix and improvement to ext_snprintf
This commit is contained in:
parent
72e4d8f0d2
commit
48c4b64879
|
@ -237,6 +237,21 @@ public:
|
|||
return buf2;
|
||||
}
|
||||
|
||||
// nullptr accepted
|
||||
static bool equalsSBuffer(const class SBuffer * buf1, const class SBuffer * buf2) {
|
||||
if (buf1 == buf2) { return true; }
|
||||
if (!buf1 && (buf2->len() == 0)) { return true; }
|
||||
if (!buf2 && (buf1->len() == 0)) { return true; }
|
||||
if (!buf1 || !buf2) { return false; } // at least one buf is not empty
|
||||
// we know that both buf1 and buf2 are non-null
|
||||
if (buf1->len() != buf2->len()) { return false; }
|
||||
size_t len = buf1->len();
|
||||
for (uint32_t i=0; i<len; i++) {
|
||||
if (buf1->get8(i) != buf2->get8(i)) { return false; }
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
static uint8_t asc2byte(char chr) {
|
||||
|
@ -269,18 +284,3 @@ public:
|
|||
_buf = nullptr;
|
||||
}
|
||||
} PreAllocatedSBuffer;
|
||||
|
||||
// nullptr accepted
|
||||
bool equalsSBuffer(const class SBuffer * buf1, const class SBuffer * buf2) {
|
||||
if (buf1 == buf2) { return true; }
|
||||
if (!buf1 && (buf2->len() == 0)) { return true; }
|
||||
if (!buf2 && (buf1->len() == 0)) { return true; }
|
||||
if (!buf1 || !buf2) { return false; } // at least one buf is not empty
|
||||
// we know that both buf1 and buf2 are non-null
|
||||
if (buf1->len() != buf2->len()) { return false; }
|
||||
size_t len = buf1->len();
|
||||
for (uint32_t i=0; i<len; i++) {
|
||||
if (buf1->get8(i) != buf2->get8(i)) { return false; }
|
||||
}
|
||||
return true;
|
||||
}
|
|
@ -20,6 +20,7 @@
|
|||
#include "ext_printf.h"
|
||||
#include <Arduino.h>
|
||||
#include <IPAddress.h>
|
||||
#include <SBuffer.hpp>
|
||||
|
||||
/*********************************************************************************************\
|
||||
* va_list extended support
|
||||
|
@ -139,6 +140,26 @@ char * U64toHex(uint64_t value, char *str) {
|
|||
return str;
|
||||
}
|
||||
|
||||
// see https://stackoverflow.com/questions/6357031/how-do-you-convert-a-byte-array-to-a-hexadecimal-string-in-c
|
||||
// char* ToHex_P(unsigned char * in, size_t insz, char * out, size_t outsz, char inbetween = '\0'); in tasmota_globals.h
|
||||
char* ToHex_P(const unsigned char * in, size_t insz, char * out, size_t outsz, char inbetween = '\0') {
|
||||
// ToHex_P(in, insz, out, outz) -> "12345667"
|
||||
// ToHex_P(in, insz, out, outz, ' ') -> "12 34 56 67"
|
||||
// ToHex_P(in, insz, out, outz, ':') -> "12:34:56:67"
|
||||
static const char * hex PROGMEM = "0123456789ABCDEF";
|
||||
int between = (inbetween) ? 3 : 2;
|
||||
const unsigned char * pin = in;
|
||||
char * pout = out;
|
||||
for (; pin < in+insz; pout += between, pin++) {
|
||||
pout[0] = pgm_read_byte(&hex[(pgm_read_byte(pin)>>4) & 0xF]);
|
||||
pout[1] = pgm_read_byte(&hex[ pgm_read_byte(pin) & 0xF]);
|
||||
if (inbetween) { pout[2] = inbetween; }
|
||||
if (pout + 3 - out > outsz) { break; } // Better to truncate output string than overflow buffer
|
||||
}
|
||||
pout[(inbetween && insz) ? -1 : 0] = 0; // Discard last inbetween if any input
|
||||
return out;
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* snprintf extended
|
||||
*
|
||||
|
@ -166,10 +187,11 @@ int32_t ext_vsnprintf_P(char * buf, size_t buf_len, const char * fmt_P, va_list
|
|||
const uint32_t ALLOC_SIZE = 12;
|
||||
static char * allocs[ALLOC_SIZE] = {}; // initialized to zeroes
|
||||
uint32_t alloc_idx = 0;
|
||||
int32_t decimals = -2; // default to 2 decimals and remove trailing zeros
|
||||
static char hex[20]; // buffer used for 64 bits, favor RAM instead of stack to remove pressure
|
||||
|
||||
for (; *fmt != 0; ++fmt) {
|
||||
int32_t decimals = -2; // default to 2 decimals and remove trailing zeros
|
||||
int32_t * decimals_ptr = nullptr;
|
||||
if (alloc_idx >= ALLOC_SIZE) { break; } // buffer is full, don't continue parsing
|
||||
if (*fmt == '%') {
|
||||
fmt++;
|
||||
|
@ -177,8 +199,11 @@ int32_t ext_vsnprintf_P(char * buf, size_t buf_len, const char * fmt_P, va_list
|
|||
if (*fmt == '\0') { break; } // end of string
|
||||
if (*fmt == '%') { continue; } // actual '%' char
|
||||
if (*fmt == '*') {
|
||||
va_arg(va, int32_t); // skip width argument as int
|
||||
decimals = va_arg(va, int32_t); // skip width argument as int
|
||||
decimals_ptr = va_cur_ptr4(va, int32_t); // pointer to value on stack
|
||||
const char ** cur_val_ptr = va_cur_ptr4(va, const char*); // pointer to value on stack
|
||||
fmt++;
|
||||
// Serial.printf("> decimals=%d, decimals_ptr=0x%08X\n", decimals, decimals_ptr);
|
||||
}
|
||||
if (*fmt < 'A') {
|
||||
decimals = strtol(fmt, nullptr, 10);
|
||||
|
@ -189,6 +214,12 @@ int32_t ext_vsnprintf_P(char * buf, size_t buf_len, const char * fmt_P, va_list
|
|||
}
|
||||
|
||||
if (*fmt == '_') { // extension
|
||||
if (decimals_ptr) {
|
||||
// Serial.printf(">2 decimals=%d, decimals_ptr=0x%08X\n", decimals, decimals_ptr);
|
||||
*decimals_ptr = 0; // if '*' was used, make sure we replace the value with zero for snprintf()
|
||||
*(fmt_start++) = '-'; // in this case replace with `%-*s`
|
||||
*(fmt_start++) = '*';
|
||||
}
|
||||
for (; fmt_start <= fmt; fmt_start++) {
|
||||
*fmt_start = '0';
|
||||
}
|
||||
|
@ -198,14 +229,43 @@ int32_t ext_vsnprintf_P(char * buf, size_t buf_len, const char * fmt_P, va_list
|
|||
const char ** cur_val_ptr = va_cur_ptr4(va, const char*); // pointer to value on stack
|
||||
char * new_val_str = (char*) "";
|
||||
switch (*fmt) {
|
||||
case 'H': // Hex, decimals indicates the length, default 2
|
||||
{
|
||||
if (decimals < 0) { decimals = 0; }
|
||||
if (decimals > 0) {
|
||||
char * hex_char = (char*) malloc(decimals*2 + 2);
|
||||
ToHex_P((const uint8_t *)cur_val, decimals, hex_char, decimals*2 + 2);
|
||||
new_val_str = hex_char;
|
||||
allocs[alloc_idx++] = new_val_str;
|
||||
// Serial.printf("> hex=%s\n", hex_char);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'B': // Pointer to SBuffer
|
||||
{
|
||||
const SBuffer & buf = *(const SBuffer*)cur_val;
|
||||
size_t buf_len = (&buf != nullptr) ? buf.len() : 0;
|
||||
if (buf_len) {
|
||||
char * hex_char = (char*) malloc(buf_len*2 + 2);
|
||||
ToHex_P(buf.getBuffer(), buf_len, hex_char, buf_len*2 + 2);
|
||||
new_val_str = hex_char;
|
||||
allocs[alloc_idx++] = new_val_str;
|
||||
}
|
||||
}
|
||||
break;
|
||||
// case 'D':
|
||||
// decimals = *(int32_t*)cur_val_ptr;
|
||||
// break;
|
||||
|
||||
// `%_I` ouputs an IPv4 32 bits address passed as u32 into a decimal dotted format
|
||||
case 'I': // Input is `uint32_t` 32 bits IP address, output is decimal dotted address
|
||||
new_val_str = copyStr(IPAddress(cur_val).toString().c_str());
|
||||
allocs[alloc_idx++] = new_val_str;
|
||||
{
|
||||
char * ip_str = (char*) malloc(16);
|
||||
IPAddress ip(cur_val);
|
||||
sprintf_P(ip_str, PSTR("%u.%u.%u.%u"), ip[0], ip[1], ip[2], ip[3]);
|
||||
new_val_str = ip_str;
|
||||
allocs[alloc_idx++] = new_val_str;
|
||||
}
|
||||
break;
|
||||
|
||||
// `%_f` or `%*_f` outputs a float with optionan number of decimals passed as first argument if `*` is present
|
||||
|
@ -224,21 +284,26 @@ int32_t ext_vsnprintf_P(char * buf, size_t buf_len, const char * fmt_P, va_list
|
|||
decimals = -decimals;
|
||||
truncate = true;
|
||||
}
|
||||
dtostrf(*(float*)cur_val, (decimals + 2), decimals, hex);
|
||||
float number = *(float*)cur_val;
|
||||
if (isnan(number) || isinf(number)) {
|
||||
new_val_str = (char*) "null";
|
||||
} else {
|
||||
dtostrf(*(float*)cur_val, (decimals + 2), decimals, hex);
|
||||
|
||||
if (truncate) {
|
||||
uint32_t last = strlen(hex) - 1;
|
||||
// remove trailing zeros
|
||||
while (hex[last] == '0') {
|
||||
hex[last--] = 0; // remove last char
|
||||
}
|
||||
// remove trailing dot
|
||||
if (hex[last] == '.') {
|
||||
hex[last] = 0;
|
||||
if (truncate) {
|
||||
uint32_t last = strlen(hex) - 1;
|
||||
// remove trailing zeros
|
||||
while (hex[last] == '0') {
|
||||
hex[last--] = 0; // remove last char
|
||||
}
|
||||
// remove trailing dot
|
||||
if (hex[last] == '.') {
|
||||
hex[last] = 0;
|
||||
}
|
||||
}
|
||||
new_val_str = copyStr(hex);
|
||||
allocs[alloc_idx++] = new_val_str;
|
||||
}
|
||||
new_val_str = copyStr(hex);
|
||||
allocs[alloc_idx++] = new_val_str;
|
||||
}
|
||||
break;
|
||||
// '%_X' outputs a 64 bits unsigned int to uppercase HEX with 16 digits
|
||||
|
@ -277,14 +342,17 @@ int32_t ext_vsnprintf_P(char * buf, size_t buf_len, const char * fmt_P, va_list
|
|||
#else // defined(ESP8266) || defined(ESP32)
|
||||
#error "ext_printf is not suppoerted on this platform"
|
||||
#endif // defined(ESP8266) || defined(ESP32)
|
||||
// Serial.printf("> format_final=%s\n", fmt_cpy); Serial.flush();
|
||||
int32_t ret = vsnprintf_P(buf, buf_len, fmt_cpy, va_cpy);
|
||||
|
||||
va_end(va_cpy);
|
||||
|
||||
// disallocated all temporary strings
|
||||
for (uint32_t i = 0; i < alloc_idx; i++) {
|
||||
free(allocs[i]);
|
||||
free(allocs[i]); // it is ok to call free() on nullptr so we don't test for nullptr first
|
||||
allocs[i] = nullptr;
|
||||
}
|
||||
free(fmt_cpy);
|
||||
free(fmt_cpy); // free the local copy of the format string
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
int32_t ext_vsnprintf_P(char * buf, size_t buf_len, const char * fmt_P, va_list va);
|
||||
int32_t ext_snprintf_P(char * buf, size_t buf_len, const char * fmt, ...);
|
||||
|
||||
char* ToHex_P(const unsigned char * in, size_t insz, char * out, size_t outsz, char inbetween);
|
||||
|
||||
// void test_ext_snprintf_P(void);
|
||||
|
||||
#endif // EXT_PRINTF_H
|
|
@ -64,12 +64,16 @@ void test_ext_snprintf_P(void) {
|
|||
|
||||
ext_snprintf_P(c, sizeof(c), "Float default=%1_f, int(3)=%4_f, int(3)=%-4_f, int(3)=%-4_f, 6dec=%-8_f", &fpi, &f3, &f3, &f31, &fpi);
|
||||
Serial.printf("--> out=%s\n", c);
|
||||
ext_snprintf_P(c, sizeof(c), "Float default=%*_f, int(3)=%*_f, int(3)=%*_f, int(3)=%*_f, 6dec=%*_f", 1, &fpi, 4, &f3, -4, &f3, -4, &f31, -8, &fpi);
|
||||
Serial.printf("--> out=%s\n", c);
|
||||
uint64_t u641 = 0x1122334455667788LL;
|
||||
uint64_t u642 = 0x0123456789ABCDEFLL;
|
||||
uint64_t u643 = 0xFEDCBA9876543210LL;
|
||||
ext_snprintf_P(c, sizeof(c), "Int64 0x%_X 0x%_X 0x%_X", &u641, &u642, &u643);
|
||||
Serial.printf("--> out=%s\n", c);
|
||||
|
||||
// ext_snprintf_P(c, sizeof(c), "Float default=%*_f, int(3)=%*_f, int(3)=%*_f, int(3)=%*_f, 6dec=%*_f", &fpi, &f3, &f3, &f31, &fpi);
|
||||
|
||||
// String string("Foobar");
|
||||
// ext_snprintf_P(c, sizeof(c), "String 0x%08X %_s", &string, &string);
|
||||
// Serial.printf("--> out=%s\n", c);
|
||||
|
|
|
@ -322,27 +322,6 @@ int TextToInt(char *str)
|
|||
return strtol(str, &p, radix);
|
||||
}
|
||||
|
||||
// see https://stackoverflow.com/questions/6357031/how-do-you-convert-a-byte-array-to-a-hexadecimal-string-in-c
|
||||
// char* ToHex_P(unsigned char * in, size_t insz, char * out, size_t outsz, char inbetween = '\0'); in tasmota_globals.h
|
||||
char* ToHex_P(const unsigned char * in, size_t insz, char * out, size_t outsz, char inbetween)
|
||||
{
|
||||
// ToHex_P(in, insz, out, outz) -> "12345667"
|
||||
// ToHex_P(in, insz, out, outz, ' ') -> "12 34 56 67"
|
||||
// ToHex_P(in, insz, out, outz, ':') -> "12:34:56:67"
|
||||
static const char * hex = "0123456789ABCDEF";
|
||||
int between = (inbetween) ? 3 : 2;
|
||||
const unsigned char * pin = in;
|
||||
char * pout = out;
|
||||
for (; pin < in+insz; pout += between, pin++) {
|
||||
pout[0] = hex[(pgm_read_byte(pin)>>4) & 0xF];
|
||||
pout[1] = hex[ pgm_read_byte(pin) & 0xF];
|
||||
if (inbetween) { pout[2] = inbetween; }
|
||||
if (pout + 3 - out > outsz) { break; } // Better to truncate output string than overflow buffer
|
||||
}
|
||||
pout[(inbetween && insz) ? -1 : 0] = 0; // Discard last inbetween if any input
|
||||
return out;
|
||||
}
|
||||
|
||||
char* dtostrfd(double number, unsigned char prec, char *s)
|
||||
{
|
||||
if ((isnan(number)) || (isinf(number))) { // Fix for JSON output (https://stackoverflow.com/questions/1423081/json-left-out-infinity-and-nan-json-status-in-ecmascript)
|
||||
|
|
|
@ -53,6 +53,7 @@
|
|||
#include <ESP8266httpUpdate.h> // Ota
|
||||
#include <StreamString.h> // Webserver, Updater
|
||||
#include <ext_printf.h>
|
||||
#include <SBuffer.hpp>
|
||||
#include <JsonParser.h>
|
||||
#include <JsonGenerator.h>
|
||||
#ifdef USE_ARDUINO_OTA
|
||||
|
|
|
@ -45,7 +45,7 @@ public:
|
|||
};
|
||||
|
||||
typedef int32_t (*ZB_Func)(uint8_t value);
|
||||
typedef int32_t (*ZB_RecvMsgFunc)(int32_t res, const class SBuffer &buf);
|
||||
typedef int32_t (*ZB_RecvMsgFunc)(int32_t res, const SBuffer &buf);
|
||||
|
||||
// Labels used in the State Machine -- internal only
|
||||
const uint8_t ZIGBEE_LABEL_RESTART = 1; // Restart the state_machine in a different mode
|
||||
|
@ -118,6 +118,7 @@ public:
|
|||
struct ZigbeeStatus zigbee;
|
||||
SBuffer *zigbee_buffer = nullptr;
|
||||
|
||||
void zigbeeZCLSendCmd(const ZigbeeZCLSendMessage &msg);
|
||||
void ZigbeeZCLSend_Raw(const ZigbeeZCLSendMessage &zcl);
|
||||
bool ZbAppendWriteBuf(SBuffer & buf, const Z_attribute & attr, bool prepend_status_ok = false);
|
||||
|
||||
|
|
|
@ -537,7 +537,7 @@ bool Z_attribute::equalsVal(const Z_attribute & attr2) const {
|
|||
if (val.uval32 != attr2.val.uval32) { return false; }
|
||||
} else if (type == Za_type::Za_raw) {
|
||||
// compare 2 Static buffers
|
||||
return equalsSBuffer(val.bval, attr2.val.bval);
|
||||
return SBuffer::equalsSBuffer(val.bval, attr2.val.bval);
|
||||
} else if (type == Za_type::Za_str) {
|
||||
// if (val_str_raw != attr2.val_str_raw) { return false; }
|
||||
if (strcmp_PP(val.sval, attr2.val.sval)) { return false; }
|
||||
|
|
|
@ -136,7 +136,7 @@ bool hibernateDeviceConfiguration(SBuffer & buf, const class Z_Data_Set & data,
|
|||
return found;
|
||||
}
|
||||
|
||||
class SBuffer hibernateDevicev2(const struct Z_Device &device) {
|
||||
SBuffer hibernateDevicev2(const struct Z_Device &device) {
|
||||
SBuffer buf(128);
|
||||
|
||||
buf.add8(0x00); // overall length, will be updated later
|
||||
|
@ -178,7 +178,7 @@ class SBuffer hibernateDevicev2(const struct Z_Device &device) {
|
|||
return buf;
|
||||
}
|
||||
|
||||
class SBuffer hibernateDevices(void) {
|
||||
SBuffer hibernateDevices(void) {
|
||||
SBuffer buf(2048);
|
||||
|
||||
size_t devices_size = zigbee_devices.devicesSize();
|
||||
|
|
|
@ -74,7 +74,7 @@ bool hydrateDeviceData(class Z_Device & device, const SBuffer & buf, size_t star
|
|||
|
||||
// negative means error
|
||||
// positive is the segment length
|
||||
int32_t hydrateSingleDevice(const class SBuffer & buf, size_t start, size_t len) {
|
||||
int32_t hydrateSingleDevice(const SBuffer & buf, size_t start, size_t len) {
|
||||
uint8_t segment_len = buf.get8(start);
|
||||
if ((segment_len < 4) || (start + segment_len > len)) {
|
||||
AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "invalid segment_len=%d"), segment_len);
|
||||
|
@ -154,7 +154,7 @@ bool hydrateDevicesDataFromEEPROM(void) {
|
|||
#endif // USE_ZIGBEE_EZSP
|
||||
}
|
||||
|
||||
class SBuffer hibernateDeviceData(const struct Z_Device & device, bool mqtt = false) {
|
||||
SBuffer hibernateDeviceData(const struct Z_Device & device, bool mqtt = false) {
|
||||
SBuffer buf(192);
|
||||
|
||||
// If we have zero information about the device, just skip ir
|
||||
|
|
|
@ -869,7 +869,7 @@ uint8_t toPercentageCR2032(uint32_t voltage) {
|
|||
// Adds to buf:
|
||||
// - n bytes: value (typically between 1 and 4 bytes, or bigger for strings)
|
||||
// returns number of bytes of attribute, or <0 if error
|
||||
int32_t encodeSingleAttribute(class SBuffer &buf, double val_d, const char *val_str, uint8_t attrtype) {
|
||||
int32_t encodeSingleAttribute(SBuffer &buf, double val_d, const char *val_str, uint8_t attrtype) {
|
||||
uint32_t len = Z_getDatatypeLen(attrtype); // pre-compute length, overloaded for variable length attributes
|
||||
uint32_t u32 = val_d;
|
||||
int32_t i32 = val_d;
|
||||
|
|
|
@ -82,6 +82,7 @@ const Z_CommandConverter Z_Commands[] PROGMEM = {
|
|||
{ Z_(HueSat), 0x0300, 0x06, 0x01, Z_(xxyy0A00) }, // Hue, Sat
|
||||
{ Z_(Color), 0x0300, 0x07, 0x01, Z_(xxxxyyyy0A00) }, // x, y (uint16)
|
||||
{ Z_(CT), 0x0300, 0x0A, 0x01, Z_(xxxx0A00) }, // Color Temperature Mireds (uint16)
|
||||
{ Z_(RGB), 0x0300, 0xF0, 0x81, Z_() }, // synthetic commands converting RGB to XY
|
||||
{ Z_(ShutterOpen), 0x0102, 0x00, 0x01, Z_() },
|
||||
{ Z_(ShutterClose), 0x0102, 0x01, 0x01, Z_() },
|
||||
{ Z_(ShutterStop), 0x0102, 0x02, 0x01, Z_() },
|
||||
|
@ -282,7 +283,7 @@ void convertClusterSpecific(class Z_attribute_list &attr_list, uint16_t cluster,
|
|||
uint8_t conv_direction;
|
||||
Z_XYZ_Var xyz;
|
||||
|
||||
//AddLog_P(LOG_LEVEL_INFO, PSTR(">>> len = %d - %02X%02X%02X"), payload.len(), payload.get8(0), payload.get8(1), payload.get8(2));
|
||||
//AddLog_P(LOG_LEVEL_INFO, PSTR(">>> len = %d - %02X%02X%02X"), payload.len(), payload.get8(0), payload.get8(1), payload.get8(2));
|
||||
for (uint32_t i = 0; i < sizeof(Z_Commands) / sizeof(Z_Commands[0]); i++) {
|
||||
const Z_CommandConverter *conv = &Z_Commands[i];
|
||||
uint16_t conv_cluster = pgm_read_word(&conv->cluster);
|
||||
|
@ -298,18 +299,18 @@ void convertClusterSpecific(class Z_attribute_list &attr_list, uint16_t cluster,
|
|||
// - payload exactly matches conv->param (conv->param may be longer)
|
||||
// - payload matches conv->param until 'x', 'y' or 'z'
|
||||
const char * p = Z_strings + pgm_read_word(&conv->param_offset);
|
||||
//AddLog_P(LOG_LEVEL_INFO, PSTR(">>>++1 param = %s"), p);
|
||||
//AddLog_P(LOG_LEVEL_INFO, PSTR(">>>++1 param = %s"), p);
|
||||
bool match = true;
|
||||
for (uint8_t i = 0; i < payload.len(); i++) {
|
||||
const char c1 = pgm_read_byte(p);
|
||||
// const char c2 = pgm_read_byte(p+1);
|
||||
//AddLog_P(LOG_LEVEL_INFO, PSTR(">>>++2 c1 = %c, c2 = %c"), c1, c2);
|
||||
//AddLog_P(LOG_LEVEL_INFO, PSTR(">>>++2 c1 = %c, c2 = %c"), c1, c2);
|
||||
if ((0x00 == c1) || isXYZ(c1)) {
|
||||
break;
|
||||
}
|
||||
const char * p2 = p;
|
||||
uint32_t nextbyte = parseHex_P(&p2, 2);
|
||||
//AddLog_P(LOG_LEVEL_INFO, PSTR(">>>++3 parseHex_P = %02X"), nextbyte);
|
||||
//AddLog_P(LOG_LEVEL_INFO, PSTR(">>>++3 parseHex_P = %02X"), nextbyte);
|
||||
if (nextbyte != payload.get8(i)) {
|
||||
match = false;
|
||||
break;
|
||||
|
@ -461,6 +462,12 @@ void convertClusterSpecific(class Z_attribute_list &attr_list, uint16_t cluster,
|
|||
}
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
*
|
||||
* Tuya Zigbee specific protocol
|
||||
*
|
||||
\*********************************************************************************************/
|
||||
// Parse a sinlge attribute value and convert to human readable JSON attribute value
|
||||
void parseSingleTuyaAttribute(Z_attribute & attr, const SBuffer &buf,
|
||||
uint32_t i, uint32_t len, int32_t attrtype) {
|
||||
|
||||
|
@ -519,6 +526,11 @@ bool convertTuyaSpecificCluster(class Z_attribute_list &attr_list, uint16_t clus
|
|||
return false;
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
*
|
||||
* Find commands
|
||||
*
|
||||
\*********************************************************************************************/
|
||||
// Find the command details by command name
|
||||
// Only take commands outgoing, i.e. direction == 0
|
||||
// If not found:
|
||||
|
@ -604,4 +616,11 @@ uint32_t ZigbeeAliasOrNumber(const char *state_text) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************************************\
|
||||
*
|
||||
* Send Zigbee commands
|
||||
*
|
||||
\*********************************************************************************************/
|
||||
|
||||
#endif // USE_ZIGBEE
|
||||
|
|
|
@ -1094,7 +1094,7 @@ void ZigbeeStateMachine_Run(void) {
|
|||
//
|
||||
// Process a bytes buffer and call any callback that matches the received message
|
||||
//
|
||||
int32_t ZigbeeProcessInput(class SBuffer &buf) {
|
||||
int32_t ZigbeeProcessInput(SBuffer &buf) {
|
||||
if (!zigbee.state_machine) { return -1; } // if state machine is stopped, send 'ignore' message
|
||||
|
||||
// apply the receive filter, acts as 'startsWith()'
|
||||
|
|
|
@ -74,7 +74,7 @@ void EZ_ERROR(uint8_t error_code) {
|
|||
MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEE_STATE));
|
||||
}
|
||||
|
||||
int32_t EZ_ReadAPSUnicastMessage(int32_t res, class SBuffer &buf) {
|
||||
int32_t EZ_ReadAPSUnicastMessage(int32_t res, SBuffer &buf) {
|
||||
// Called when receiving a response from getConfigurationValue
|
||||
// Value is in bytes 2+3
|
||||
// uint16_t value = buf.get16(2);
|
||||
|
@ -88,7 +88,7 @@ int32_t EZ_ReadAPSUnicastMessage(int32_t res, class SBuffer &buf) {
|
|||
//
|
||||
// Handle a "getEui64" incoming message
|
||||
//
|
||||
int32_t EZ_GetEUI64(int32_t res, class SBuffer &buf) {
|
||||
int32_t EZ_GetEUI64(int32_t res, SBuffer &buf) {
|
||||
localIEEEAddr = buf.get64(2);
|
||||
return res;
|
||||
}
|
||||
|
@ -96,7 +96,7 @@ int32_t EZ_GetEUI64(int32_t res, class SBuffer &buf) {
|
|||
//
|
||||
// Handle a "getEui64" incoming message
|
||||
//
|
||||
int32_t EZ_GetNodeId(int32_t res, class SBuffer &buf) {
|
||||
int32_t EZ_GetNodeId(int32_t res, SBuffer &buf) {
|
||||
localShortAddr = buf.get8(2);
|
||||
return res;
|
||||
}
|
||||
|
@ -104,7 +104,7 @@ int32_t EZ_GetNodeId(int32_t res, class SBuffer &buf) {
|
|||
//
|
||||
// Handle a "getNetworkParameters" incoming message
|
||||
//
|
||||
int32_t EZ_NetworkParameters(int32_t res, class SBuffer &buf) {
|
||||
int32_t EZ_NetworkParameters(int32_t res, SBuffer &buf) {
|
||||
uint8_t node_type = buf.get8(3);
|
||||
// ext panid: 4->11
|
||||
// panid: 12->13
|
||||
|
@ -128,7 +128,7 @@ int32_t EZ_NetworkParameters(int32_t res, class SBuffer &buf) {
|
|||
//
|
||||
// Analyze response to "getKey" and check NWK key
|
||||
//
|
||||
int32_t EZ_CheckKeyNWK(int32_t res, class SBuffer &buf) {
|
||||
int32_t EZ_CheckKeyNWK(int32_t res, SBuffer &buf) {
|
||||
// uint8_t status = buf.get8(2);
|
||||
// uint16_t bitmask = buf.get16(3);
|
||||
uint8_t key_type = buf.get8(5);
|
||||
|
@ -147,7 +147,7 @@ int32_t EZ_CheckKeyNWK(int32_t res, class SBuffer &buf) {
|
|||
//
|
||||
// Handle a "incomingRouteErrorHandler" incoming message
|
||||
//
|
||||
int32_t EZ_RouteError(int32_t res, const class SBuffer &buf) {
|
||||
int32_t EZ_RouteError(int32_t res, const SBuffer &buf) {
|
||||
uint8_t status = buf.get8(2);
|
||||
uint16_t shortaddr = buf.get16(3);
|
||||
|
||||
|
@ -163,7 +163,7 @@ int32_t EZ_RouteError(int32_t res, const class SBuffer &buf) {
|
|||
//
|
||||
// Handle a "permitJoining" incoming message
|
||||
//
|
||||
int32_t EZ_PermitJoinRsp(int32_t res, const class SBuffer &buf) {
|
||||
int32_t EZ_PermitJoinRsp(int32_t res, const SBuffer &buf) {
|
||||
uint8_t status = buf.get8(2);
|
||||
|
||||
if (status) { // only report if there is an error
|
||||
|
@ -187,7 +187,7 @@ void Z_PermitJoinDisable(void) {
|
|||
//
|
||||
// We normally ignore the message, but it's a way to sniff group ids for IKEA remote
|
||||
// In case of a multicast message sent to 0xFFFD with non-null group id, we log the group id
|
||||
int32_t EZ_MessageSent(int32_t res, const class SBuffer &buf) {
|
||||
int32_t EZ_MessageSent(int32_t res, const SBuffer &buf) {
|
||||
uint8_t message_type = buf.get8(2);
|
||||
uint16_t dst_addr = buf.get16(3);
|
||||
uint16_t group_addr = buf.get16(13);
|
||||
|
@ -247,7 +247,7 @@ void Z_Map(uint16_t shortaddr, uint16_t groupaddr, uint16_t cluster, uint8_t end
|
|||
//
|
||||
// Handle a "getEui64" incoming message
|
||||
//
|
||||
int32_t Z_EZSPGetEUI64(int32_t res, class SBuffer &buf) {
|
||||
int32_t Z_EZSPGetEUI64(int32_t res, SBuffer &buf) {
|
||||
localIEEEAddr = buf.get64(2);
|
||||
return res;
|
||||
}
|
||||
|
@ -255,7 +255,7 @@ int32_t Z_EZSPGetEUI64(int32_t res, class SBuffer &buf) {
|
|||
//
|
||||
// Handle a "getEui64" incoming message
|
||||
//
|
||||
int32_t Z_EZSPGetNodeId(int32_t res, class SBuffer &buf) {
|
||||
int32_t Z_EZSPGetNodeId(int32_t res, SBuffer &buf) {
|
||||
localShortAddr = buf.get8(2);
|
||||
return res;
|
||||
}
|
||||
|
@ -263,7 +263,7 @@ int32_t Z_EZSPGetNodeId(int32_t res, class SBuffer &buf) {
|
|||
//
|
||||
// Handle a "getNetworkParameters" incoming message
|
||||
//
|
||||
int32_t Z_EZSPNetworkParameters(int32_t res, class SBuffer &buf) {
|
||||
int32_t Z_EZSPNetworkParameters(int32_t res, SBuffer &buf) {
|
||||
uint8_t node_type = buf.get8(3);
|
||||
// ext panid: 4->11
|
||||
// panid: 12->13
|
||||
|
@ -291,7 +291,7 @@ int32_t Z_EZSPNetworkParameters(int32_t res, class SBuffer &buf) {
|
|||
//
|
||||
// Handle a "Receive Device Info" incoming message
|
||||
//
|
||||
int32_t ZNP_ReceiveDeviceInfo(int32_t res, class SBuffer &buf) {
|
||||
int32_t ZNP_ReceiveDeviceInfo(int32_t res, SBuffer &buf) {
|
||||
// Ex= 6700.00.6263151D004B1200.0000.07.09.02.83869991
|
||||
// IEEE Adr (8 bytes) = 0x00124B001D156362
|
||||
// Short Addr (2 bytes) = 0x0000
|
||||
|
@ -333,7 +333,7 @@ int32_t ZNP_ReceiveDeviceInfo(int32_t res, class SBuffer &buf) {
|
|||
return res;
|
||||
}
|
||||
|
||||
int32_t ZNP_CheckNVWrite(int32_t res, class SBuffer &buf) {
|
||||
int32_t ZNP_CheckNVWrite(int32_t res, SBuffer &buf) {
|
||||
// Check the status after NV Init "ZNP Has Configured"
|
||||
// Good response should be 610700 or 610709 (Success or Created)
|
||||
// We only filter the response on 6107 and check the code in this function
|
||||
|
@ -345,7 +345,7 @@ int32_t ZNP_CheckNVWrite(int32_t res, class SBuffer &buf) {
|
|||
}
|
||||
}
|
||||
|
||||
int32_t ZNP_Reboot(int32_t res, class SBuffer &buf) {
|
||||
int32_t ZNP_Reboot(int32_t res, SBuffer &buf) {
|
||||
// print information about the reboot of device
|
||||
// 4180.02.02.00.02.06.03
|
||||
//
|
||||
|
@ -380,7 +380,7 @@ int32_t ZNP_Reboot(int32_t res, class SBuffer &buf) {
|
|||
}
|
||||
|
||||
#ifdef USE_ZIGBEE_ZNP
|
||||
int32_t ZNP_ReceiveCheckVersion(int32_t res, class SBuffer &buf) {
|
||||
int32_t ZNP_ReceiveCheckVersion(int32_t res, SBuffer &buf) {
|
||||
// check that the version is supported
|
||||
// typical version for ZNP 1.2
|
||||
// 61020200-02.06.03.D9143401.0200000000
|
||||
|
@ -412,7 +412,7 @@ int32_t ZNP_ReceiveCheckVersion(int32_t res, class SBuffer &buf) {
|
|||
#endif // USE_ZIGBEE_ZNP
|
||||
|
||||
#ifdef USE_ZIGBEE_EZSP
|
||||
int32_t EZ_ReceiveCheckVersion(int32_t res, class SBuffer &buf) {
|
||||
int32_t EZ_ReceiveCheckVersion(int32_t res, SBuffer &buf) {
|
||||
uint8_t protocol_version = buf.get8(2);
|
||||
uint8_t stack_type = buf.get8(3);
|
||||
uint16_t stack_version = buf.get16(4);
|
||||
|
@ -463,7 +463,7 @@ int32_t EZ_GotoIfResetConfig(uint8_t value) {
|
|||
// If coordinator continue
|
||||
// If router goto ZIGBEE_LABEL_START_ROUTER
|
||||
// If device goto ZIGBEE_LABEL_START_DEVICE
|
||||
int32_t Z_SwitchDeviceType(int32_t res, class SBuffer &buf) {
|
||||
int32_t Z_SwitchDeviceType(int32_t res, SBuffer &buf) {
|
||||
switch (Settings.zb_pan_id) {
|
||||
case 0xFFFF: return ZIGBEE_LABEL_INIT_ROUTER;
|
||||
case 0xFFFE: return ZIGBEE_LABEL_INIT_DEVICE;
|
||||
|
@ -474,7 +474,7 @@ int32_t Z_SwitchDeviceType(int32_t res, class SBuffer &buf) {
|
|||
//
|
||||
// Helper function, checks if the incoming buffer matches the 2-bytes prefix, i.e. message type in PMEM
|
||||
//
|
||||
bool Z_ReceiveMatchPrefix(const class SBuffer &buf, const uint8_t *match) {
|
||||
bool Z_ReceiveMatchPrefix(const SBuffer &buf, const uint8_t *match) {
|
||||
if ( (pgm_read_byte(&match[0]) == buf.get8(0)) &&
|
||||
(pgm_read_byte(&match[1]) == buf.get8(1)) ) {
|
||||
return true;
|
||||
|
@ -486,7 +486,7 @@ bool Z_ReceiveMatchPrefix(const class SBuffer &buf, const uint8_t *match) {
|
|||
//
|
||||
// Handle Permit Join response
|
||||
//
|
||||
int32_t ZNP_ReceivePermitJoinStatus(int32_t res, const class SBuffer &buf) {
|
||||
int32_t ZNP_ReceivePermitJoinStatus(int32_t res, const SBuffer &buf) {
|
||||
// we received a PermitJoin status change
|
||||
uint8_t duration = buf.get8(2);
|
||||
uint8_t status_code;
|
||||
|
@ -518,7 +518,7 @@ int32_t ZNP_ReceivePermitJoinStatus(int32_t res, const class SBuffer &buf) {
|
|||
//
|
||||
// ZNP only
|
||||
//
|
||||
int32_t ZNP_ReceiveNodeDesc(int32_t res, const class SBuffer &buf) {
|
||||
int32_t ZNP_ReceiveNodeDesc(int32_t res, const SBuffer &buf) {
|
||||
// Received ZDO_NODE_DESC_RSP
|
||||
// Z_ShortAddress srcAddr = buf.get16(2);
|
||||
uint8_t status = buf.get8(4);
|
||||
|
@ -560,7 +560,7 @@ int32_t ZNP_ReceiveNodeDesc(int32_t res, const class SBuffer &buf) {
|
|||
//
|
||||
// Porcess Receive Active Endpoint
|
||||
//
|
||||
int32_t Z_ReceiveActiveEp(int32_t res, const class SBuffer &buf) {
|
||||
int32_t Z_ReceiveActiveEp(int32_t res, const SBuffer &buf) {
|
||||
// Received ZDO_ACTIVE_EP_RSP
|
||||
#ifdef USE_ZIGBEE_ZNP
|
||||
// Z_ShortAddress srcAddr = buf.get16(2);
|
||||
|
@ -672,7 +672,7 @@ void Z_AutoBindDefer(uint16_t shortaddr, uint8_t endpoint, const SBuffer &buf,
|
|||
}
|
||||
}
|
||||
|
||||
int32_t Z_ReceiveSimpleDesc(int32_t res, const class SBuffer &buf) {
|
||||
int32_t Z_ReceiveSimpleDesc(int32_t res, const SBuffer &buf) {
|
||||
#ifdef USE_ZIGBEE_ZNP
|
||||
// Received ZDO_SIMPLE_DESC_RSP
|
||||
// Z_ShortAddress srcAddr = buf.get16(2);
|
||||
|
@ -747,7 +747,7 @@ int32_t Z_ReceiveSimpleDesc(int32_t res, const class SBuffer &buf) {
|
|||
// Handle IEEEAddr incoming message
|
||||
//
|
||||
// Same works for both ZNP and EZSP
|
||||
int32_t Z_ReceiveIEEEAddr(int32_t res, const class SBuffer &buf) {
|
||||
int32_t Z_ReceiveIEEEAddr(int32_t res, const SBuffer &buf) {
|
||||
#ifdef USE_ZIGBEE_ZNP
|
||||
uint8_t status = buf.get8(2);
|
||||
Z_IEEEAddress ieeeAddr = buf.get64(3);
|
||||
|
@ -784,7 +784,7 @@ int32_t Z_ReceiveIEEEAddr(int32_t res, const class SBuffer &buf) {
|
|||
// Report any AF_DATA_CONFIRM message
|
||||
// Ex: {"ZbConfirm":{"Endpoint":1,"Status":0,"StatusMessage":"SUCCESS"}}
|
||||
//
|
||||
int32_t ZNP_DataConfirm(int32_t res, const class SBuffer &buf) {
|
||||
int32_t ZNP_DataConfirm(int32_t res, const SBuffer &buf) {
|
||||
uint8_t status = buf.get8(2);
|
||||
uint8_t endpoint = buf.get8(3);
|
||||
//uint8_t transId = buf.get8(4); // unused
|
||||
|
@ -815,7 +815,7 @@ int32_t ZNP_DataConfirm(int32_t res, const class SBuffer &buf) {
|
|||
// 0x08: Starting as ZigBee Coordinator
|
||||
// 0x09: Started as ZigBee Coordinator
|
||||
// 0x0A: Device has lost information about its parent
|
||||
int32_t ZNP_ReceiveStateChange(int32_t res, const class SBuffer &buf) {
|
||||
int32_t ZNP_ReceiveStateChange(int32_t res, const SBuffer &buf) {
|
||||
uint8_t state = buf.get8(2);
|
||||
const char * msg = nullptr;
|
||||
|
||||
|
@ -865,7 +865,7 @@ int32_t ZNP_ReceiveStateChange(int32_t res, const class SBuffer &buf) {
|
|||
// This message is also received when a previously paired device is powered up
|
||||
// Send back Active Ep Req message
|
||||
//
|
||||
int32_t Z_ReceiveEndDeviceAnnonce(int32_t res, const class SBuffer &buf) {
|
||||
int32_t Z_ReceiveEndDeviceAnnonce(int32_t res, const SBuffer &buf) {
|
||||
#ifdef USE_ZIGBEE_ZNP
|
||||
// Z_ShortAddress srcAddr = buf.get16(2);
|
||||
Z_ShortAddress nwkAddr = buf.get16(4);
|
||||
|
@ -915,7 +915,7 @@ int32_t Z_ReceiveEndDeviceAnnonce(int32_t res, const class SBuffer &buf) {
|
|||
// Handle Receive TC Dev Ind incoming message
|
||||
// 45CA
|
||||
//
|
||||
int32_t ZNP_ReceiveTCDevInd(int32_t res, const class SBuffer &buf) {
|
||||
int32_t ZNP_ReceiveTCDevInd(int32_t res, const SBuffer &buf) {
|
||||
Z_ShortAddress srcAddr = buf.get16(2);
|
||||
Z_IEEEAddress ieeeAddr = buf.get64(4);
|
||||
Z_ShortAddress parentNw = buf.get16(12);
|
||||
|
@ -937,7 +937,7 @@ int32_t ZNP_ReceiveTCDevInd(int32_t res, const class SBuffer &buf) {
|
|||
//
|
||||
// Handle Bind Rsp incoming message
|
||||
//
|
||||
int32_t Z_BindRsp(int32_t res, const class SBuffer &buf) {
|
||||
int32_t Z_BindRsp(int32_t res, const SBuffer &buf) {
|
||||
#ifdef USE_ZIGBEE_ZNP
|
||||
Z_ShortAddress nwkAddr = buf.get16(2);
|
||||
uint8_t status = buf.get8(4);
|
||||
|
@ -970,7 +970,7 @@ int32_t Z_BindRsp(int32_t res, const class SBuffer &buf) {
|
|||
//
|
||||
// Handle Unbind Rsp incoming message
|
||||
//
|
||||
int32_t Z_UnbindRsp(int32_t res, const class SBuffer &buf) {
|
||||
int32_t Z_UnbindRsp(int32_t res, const SBuffer &buf) {
|
||||
#ifdef USE_ZIGBEE_ZNP
|
||||
Z_ShortAddress nwkAddr = buf.get16(2);
|
||||
uint8_t status = buf.get8(4);
|
||||
|
@ -1003,7 +1003,7 @@ int32_t Z_UnbindRsp(int32_t res, const class SBuffer &buf) {
|
|||
//
|
||||
// Handle MgMt Bind Rsp incoming message
|
||||
//
|
||||
int32_t Z_MgmtBindRsp(int32_t res, const class SBuffer &buf) {
|
||||
int32_t Z_MgmtBindRsp(int32_t res, const SBuffer &buf) {
|
||||
return Z_Mgmt_Lqi_Bind_Rsp(res, buf, false);
|
||||
}
|
||||
|
||||
|
@ -1043,7 +1043,7 @@ const char * Z_DeviceType(uint32_t value) {
|
|||
//
|
||||
// If the response has a follow-up, send more requests automatically
|
||||
//
|
||||
int32_t Z_Mgmt_Lqi_Bind_Rsp(int32_t res, const class SBuffer &buf, boolean lqi) {
|
||||
int32_t Z_Mgmt_Lqi_Bind_Rsp(int32_t res, const SBuffer &buf, boolean lqi) {
|
||||
#ifdef USE_ZIGBEE_ZNP
|
||||
uint16_t shortaddr = buf.get16(2);
|
||||
uint8_t status = buf.get8(4);
|
||||
|
@ -1202,7 +1202,7 @@ int32_t Z_Mgmt_Lqi_Bind_Rsp(int32_t res, const class SBuffer &buf, boolean lqi)
|
|||
//
|
||||
// Handle MgMt Bind Rsp incoming message
|
||||
//
|
||||
int32_t Z_MgmtLqiRsp(int32_t res, const class SBuffer &buf) {
|
||||
int32_t Z_MgmtLqiRsp(int32_t res, const SBuffer &buf) {
|
||||
return Z_Mgmt_Lqi_Bind_Rsp(res, buf, true);
|
||||
}
|
||||
|
||||
|
@ -1211,7 +1211,7 @@ int32_t Z_MgmtLqiRsp(int32_t res, const class SBuffer &buf) {
|
|||
// Handle Parent Annonce Rsp incoming message
|
||||
//
|
||||
// rsp: true = ZDO_Parent_annce_rsp, false = ZDO_Parent_annce
|
||||
int32_t EZ_ParentAnnceRsp(int32_t res, const class SBuffer &buf, bool rsp) {
|
||||
int32_t EZ_ParentAnnceRsp(int32_t res, const SBuffer &buf, bool rsp) {
|
||||
size_t prefix_len;
|
||||
uint8_t status;
|
||||
uint8_t num_children;
|
||||
|
@ -1570,7 +1570,7 @@ void Z_AutoConfigReportingForCluster(uint16_t shortaddr, uint16_t groupaddr, uin
|
|||
// 2400
|
||||
//
|
||||
#ifdef USE_ZIGBEE_EZSP
|
||||
int32_t EZ_ReceiveTCJoinHandler(int32_t res, const class SBuffer &buf) {
|
||||
int32_t EZ_ReceiveTCJoinHandler(int32_t res, const SBuffer &buf) {
|
||||
uint16_t srcAddr = buf.get16(2);
|
||||
uint64_t ieeeAddr = buf.get64(4);
|
||||
uint8_t status = buf.get8(12);
|
||||
|
@ -1743,7 +1743,7 @@ void EZ_SendZDO(uint16_t shortaddr, uint16_t cmd, const unsigned char *payload,
|
|||
* Send specific EZSP messages
|
||||
\*********************************************************************************************/
|
||||
|
||||
int32_t EZ_IncomingMessage(int32_t res, const class SBuffer &buf) {
|
||||
int32_t EZ_IncomingMessage(int32_t res, const SBuffer &buf) {
|
||||
uint8_t msgtype = buf.get8(2); // see EZSP_EmberIncomingMessageType
|
||||
bool wasbroadcast = (msgtype >= EMBER_INCOMING_MULTICAST) && (msgtype <= EMBER_INCOMING_BROADCAST_LOOPBACK);
|
||||
uint16_t profileid = buf.get16(3); // HA = 0x0104, ZDO = 0x0000
|
||||
|
@ -1837,7 +1837,7 @@ int32_t EZ_Reset_Device(uint8_t value) {
|
|||
* Default resolver
|
||||
\*********************************************************************************************/
|
||||
|
||||
int32_t EZ_Recv_Default(int32_t res, const class SBuffer &buf) {
|
||||
int32_t EZ_Recv_Default(int32_t res, const SBuffer &buf) {
|
||||
// Default message handler for new messages
|
||||
if (zigbee.init_phase) {
|
||||
// if still during initialization phase, ignore any unexpected message
|
||||
|
@ -1907,7 +1907,7 @@ int32_t ZNP_Reset_Device(uint8_t value) {
|
|||
return 0; // continue
|
||||
}
|
||||
|
||||
int32_t ZNP_ReceiveAfIncomingMessage(int32_t res, const class SBuffer &buf) {
|
||||
int32_t ZNP_ReceiveAfIncomingMessage(int32_t res, const SBuffer &buf) {
|
||||
uint16_t groupid = buf.get16(2);
|
||||
uint16_t clusterid = buf.get16(4);
|
||||
uint16_t srcaddr = buf.get16(6);
|
||||
|
@ -1968,7 +1968,7 @@ const Z_Dispatcher Z_DispatchTable[] PROGMEM = {
|
|||
* Default resolver
|
||||
\*********************************************************************************************/
|
||||
|
||||
int32_t ZNP_Recv_Default(int32_t res, const class SBuffer &buf) {
|
||||
int32_t ZNP_Recv_Default(int32_t res, const SBuffer &buf) {
|
||||
// Default message handler for new messages
|
||||
if (zigbee.init_phase) {
|
||||
// if still during initialization phase, ignore any unexpected message
|
||||
|
|
|
@ -134,25 +134,21 @@ void ZigbeeInputLoop(void) {
|
|||
}
|
||||
|
||||
if (zigbee_buffer->len() && (millis() > (zigbee_polling_window + ZIGBEE_POLLING))) {
|
||||
char hex_char[(zigbee_buffer->len() * 2) + 2];
|
||||
ToHex_P((unsigned char*)zigbee_buffer->getBuffer(), zigbee_buffer->len(), hex_char, sizeof(hex_char));
|
||||
|
||||
// AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_ZIGBEE "Bytes follow_read_metric = %0d"), ZigbeeSerial->getLoopReadMetric());
|
||||
// buffer received, now check integrity
|
||||
if (zigbee_buffer->len() != zigbee_frame_len) {
|
||||
// Len is not correct, log and reject frame
|
||||
AddLog_P(LOG_LEVEL_INFO, PSTR(D_JSON_ZIGBEEZNPRECEIVED ": received frame of wrong size %s, len %d, expected %d"), hex_char, zigbee_buffer->len(), zigbee_frame_len);
|
||||
AddLog_P(LOG_LEVEL_INFO, PSTR(D_JSON_ZIGBEEZNPRECEIVED ": received frame of wrong size %_B, len %d, expected %d"), &zigbee_buffer, zigbee_buffer->len(), zigbee_frame_len);
|
||||
} else if (0x00 != fcs) {
|
||||
// FCS is wrong, packet is corrupt, log and reject frame
|
||||
AddLog_P(LOG_LEVEL_INFO, PSTR(D_JSON_ZIGBEEZNPRECEIVED ": received bad FCS frame %s, %d"), hex_char, fcs);
|
||||
AddLog_P(LOG_LEVEL_INFO, PSTR(D_JSON_ZIGBEEZNPRECEIVED ": received bad FCS frame %_B, %d"), &zigbee_buffer, fcs);
|
||||
} else {
|
||||
// frame is correct
|
||||
//AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR(D_JSON_ZIGBEEZNPRECEIVED ": received correct frame %s"), hex_char);
|
||||
|
||||
SBuffer znp_buffer = zigbee_buffer->subBuffer(2, zigbee_frame_len - 3); // remove SOF, LEN and FCS
|
||||
|
||||
ToHex_P((unsigned char*)znp_buffer.getBuffer(), znp_buffer.len(), hex_char, sizeof(hex_char));
|
||||
Response_P(PSTR("{\"" D_JSON_ZIGBEEZNPRECEIVED "\":\"%s\"}"), hex_char);
|
||||
Response_P(PSTR("{\"" D_JSON_ZIGBEEZNPRECEIVED "\":\"%_B\"}"), &znp_buffer);
|
||||
if (Settings.flag3.tuya_serial_mqtt_publish) {
|
||||
MqttPublishPrefixTopicRulesProcess_P(TELE, PSTR(D_RSLT_SENSOR));
|
||||
} else {
|
||||
|
@ -552,7 +548,7 @@ void ZigbeeEZSPSendDATA(const uint8_t *msg, size_t len) {
|
|||
}
|
||||
|
||||
// Receive a high-level EZSP command/response, starting with 16-bits frame ID
|
||||
void ZigbeeProcessInputEZSP(class SBuffer &buf) {
|
||||
void ZigbeeProcessInputEZSP(SBuffer &buf) {
|
||||
// verify errors in first 2 bytes.
|
||||
// TODO
|
||||
// uint8_t sequence_num = buf.get8(0);
|
||||
|
@ -632,7 +628,7 @@ void EZSP_HandleAck(uint8_t new_ack) {
|
|||
}
|
||||
|
||||
// Receive raw ASH frame (CRC was removed, data unstuffed) but still contains frame numbers
|
||||
void ZigbeeProcessInputRaw(class SBuffer &buf) {
|
||||
void ZigbeeProcessInputRaw(SBuffer &buf) {
|
||||
uint8_t control_byte = buf.get8(0);
|
||||
uint8_t ack_num = control_byte & 0x07; // keep 3 LSB
|
||||
if (control_byte & 0x80) { // non DATA frame
|
||||
|
|
Loading…
Reference in New Issue