fix(zigbee): fix convertTuyaSpecificCluster datapoint parser -> support multiple data points in the same payload. (#23247)

Co-authored-by: valentin <email@example.com>
This commit is contained in:
valentin richard 2025-04-12 19:12:32 +02:00 committed by GitHub
parent c12974366b
commit 0604fac3bc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 30 additions and 8 deletions

3
.gitignore vendored
View File

@ -49,6 +49,9 @@ lib/libesp32/berry/berry
*.bak
*.code-workspace
## IntelliJ ######
.idea
## Python virtual environments for Platformio ##
venv
.venv

View File

@ -602,19 +602,38 @@ static void replyTuyaTime( uint16_t cluster, uint16_t shortaddr, uint8_t dstendp
bool convertTuyaSpecificCluster(class Z_attribute_list &attr_list, uint16_t cluster, uint8_t cmd, bool direction, uint16_t shortaddr, uint8_t srcendpoint, const SBuffer &buf) {
if ((1 == cmd) || (2 == cmd)) { // attribute report or attribute response
// uint16_t seq_number = buf.get16BigEndian(0)
uint8_t dpid = buf.get8(2); // dpid from Tuya documentation
uint8_t attr_type = buf.get8(3); // data type from Tuya documentation
uint16_t len = buf.get16BigEndian(4);
// create a synthetic attribute with id 'dpid'
Z_attribute & attr = attr_list.addAttribute(cluster, (attr_type << 8) | dpid);
parseSingleTuyaAttribute(attr, buf, 6, len, attr_type);
return true; // true = remove the original Tuya attribute
uint16_t read_index = 0; // position in the buffer
// uint16_t seq_number = buf.get16BigEndian(read_index); // seq
read_index += 2;
// continue while we can read at least 4 bytes: the dpid (u8), the type (u8), and the length (u16)
while ((read_index + 4) <= buf.len()) {
uint8_t dpid = buf.get8(read_index); // dpid
read_index++;
uint8_t attr_type = buf.get8(read_index); // data type
read_index++;
uint16_t len = buf.get16BigEndian(read_index);
read_index += 2;
// ensures we may read at least `len` bytes, if not, the payload is malformed.
if ((read_index + len) > buf.len()) {
break;
}
// create a synthetic attribute with id 'dpid'
Z_attribute & attr = attr_list.addAttribute(cluster, (attr_type << 8) | dpid);
parseSingleTuyaAttribute(attr, buf, read_index, len, attr_type);
read_index += len;
}
return true; // true = remove the original Tuya attribute
}
if (0x24 == cmd) {
replyTuyaTime(cluster, shortaddr, srcendpoint);
return true;
}
return false;
}