Merge pull request #7773 from s-hadinger/zigbee_seq

Fix Zigbee auto-increment transaction number (#7757)
This commit is contained in:
Theo Arends 2020-02-23 08:59:31 +01:00 committed by GitHub
commit 8689cc8d5e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 33 additions and 7 deletions

View File

@ -5,6 +5,7 @@
- Revert most wifi connectivity changes introduced in 8.1.0.5 (#7746, #7602, #7621)
- Add initial support for Sensors AHT10 and AHT15 by Martin Wagner (#7596)
- Add support for Wemos Motor Shield V1 by Denis Sborets (#7764)
- Fix Zigbee auto-increment transaction number (#7757)
### 8.1.0.8 20200212

View File

@ -489,6 +489,7 @@
#define D_CMND_ZIGBEE_FORGET "Forget"
#define D_CMND_ZIGBEE_SAVE "Save"
#define D_CMND_ZIGBEE_LINKQUALITY "LinkQuality"
#define D_CMND_ZIGBEE_ENDPOINT "Endpoint"
#define D_CMND_ZIGBEE_READ "Read"
#define D_CMND_ZIGBEE_SEND "Send"
#define D_JSON_ZIGBEE_ZCL_SENT "ZbZCLSent"

View File

@ -21,7 +21,7 @@
// contains some definitions for functions used before their declarations
void ZigbeeZCLSend(uint16_t dtsAddr, uint16_t clusterId, uint8_t endpoint, uint8_t cmdId, bool clusterSpecific, const uint8_t *msg, size_t len, bool disableDefResp = true, uint8_t transacId = 1);
void ZigbeeZCLSend(uint16_t dtsAddr, uint16_t clusterId, uint8_t endpoint, uint8_t cmdId, bool clusterSpecific, const uint8_t *msg, size_t len, bool needResponse, uint8_t transacId);
// Get an JSON attribute, with case insensitive key search

View File

@ -49,6 +49,8 @@ typedef struct Z_Device {
// json buffer used for attribute reporting
DynamicJsonBuffer *json_buffer;
JsonObject *json;
// sequence number for Zigbee frames
uint8_t seqNumber;
} Z_Device;
// All devices are stored in a Vector
@ -96,6 +98,9 @@ public:
// device just seen on the network, update the lastSeen field
void updateLastSeen(uint16_t shortaddr);
// get next sequence number for (increment at each all)
uint8_t getNextSeqNumber(uint16_t shortaddr);
// Dump json
String dump(uint32_t dump_mode, uint16_t status_shortaddr = 0) const;
@ -133,6 +138,7 @@ public:
private:
std::vector<Z_Device> _devices = {};
uint32_t _saveTimer = 0;
uint8_t _seqNumber = 0; // global seqNumber if device is unknown
template < typename T>
static bool findInVector(const std::vector<T> & vecOfElements, const T & element);
@ -226,7 +232,9 @@ Z_Device & Z_Devices::createDeviceEntry(uint16_t shortaddr, uint64_t longaddr) {
std::vector<uint32_t>(),
0,0,0,0,
nullptr,
nullptr, nullptr };
nullptr, nullptr,
0, // seqNumber
};
device.json_buffer = new DynamicJsonBuffer();
_devices.push_back(device);
dirty();
@ -532,6 +540,19 @@ void Z_Devices::updateLastSeen(uint16_t shortaddr) {
_updateLastSeen(device);
}
// get the next sequance number for the device, or use the global seq number if device is unknown
uint8_t Z_Devices::getNextSeqNumber(uint16_t shortaddr) {
int32_t short_found = findShortAddr(shortaddr);
if (short_found >= 0) {
Z_Device &device = getShortAddr(shortaddr);
device.seqNumber += 1;
return device.seqNumber;
} else {
_seqNumber += 1;
return _seqNumber;
}
}
// Per device timers
//
// Reset the timer for a specific device

View File

@ -78,7 +78,7 @@ int32_t Z_ReadAttrCallback(uint16_t shortaddr, uint16_t cluster, uint16_t endpoi
break;
}
if (attrs) {
ZigbeeZCLSend(shortaddr, cluster, endpoint, ZCL_READ_ATTRIBUTES, false, attrs, attrs_len, false /* we do want a response */);
ZigbeeZCLSend(shortaddr, cluster, endpoint, ZCL_READ_ATTRIBUTES, false, attrs, attrs_len, true /* we do want a response */, zigbee_devices.getNextSeqNumber(shortaddr));
}
}

View File

@ -451,6 +451,8 @@ int32_t Z_ReceiveAfIncomingMessage(int32_t res, const class SBuffer &buf) {
AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE D_JSON_ZIGBEEZCL_RAW_RECEIVED ": {\"0x%04X\":%s}"), srcaddr, msg.c_str());
zcl_received.postProcessAttributes(srcaddr, json);
// Add Endpoint
json[F(D_CMND_ZIGBEE_ENDPOINT)] = srcendpoint;
// Add linkquality
json[F(D_CMND_ZIGBEE_LINKQUALITY)] = linkquality;

View File

@ -344,7 +344,7 @@ void ZigbeeZNPSend(const uint8_t *msg, size_t len) {
ToHex_P(msg, len, hex_char, sizeof(hex_char)));
}
void ZigbeeZCLSend(uint16_t dtsAddr, uint16_t clusterId, uint8_t endpoint, uint8_t cmdId, bool clusterSpecific, const uint8_t *msg, size_t len, bool disableDefResp, uint8_t transacId) {
void ZigbeeZCLSend(uint16_t dtsAddr, uint16_t clusterId, uint8_t endpoint, uint8_t cmdId, bool clusterSpecific, const uint8_t *msg, size_t len, bool needResponse, uint8_t transacId) {
SBuffer buf(25+len);
buf.add8(Z_SREQ | Z_AF); // 24
buf.add8(AF_DATA_REQUEST); // 01
@ -357,7 +357,7 @@ void ZigbeeZCLSend(uint16_t dtsAddr, uint16_t clusterId, uint8_t endpoint, uint8
buf.add8(0x1E); // 1E radius
buf.add8(3 + len);
buf.add8((disableDefResp ? 0x10 : 0x00) | (clusterSpecific ? 0x01 : 0x00)); // Frame Control Field
buf.add8((needResponse ? 0x00 : 0x10) | (clusterSpecific ? 0x01 : 0x00)); // Frame Control Field
buf.add8(transacId); // Transaction Sequance Number
buf.add8(cmdId);
if (len > 0) {
@ -438,7 +438,7 @@ void zigbeeZCLSendStr(uint16_t dstAddr, uint8_t endpoint, const char *data) {
}
// everything is good, we can send the command
ZigbeeZCLSend(dstAddr, cluster, endpoint, cmd, clusterSpecific, buf.getBuffer(), buf.len());
ZigbeeZCLSend(dstAddr, cluster, endpoint, cmd, clusterSpecific, buf.getBuffer(), buf.len(), false, zigbee_devices.getNextSeqNumber(dstAddr));
// now set the timer, if any, to read back the state later
if (clusterSpecific) {
zigbeeSetCommandTimer(dstAddr, cluster, endpoint);
@ -469,6 +469,7 @@ void CmndZbSend(void) {
uint8_t endpoint = 0x00; // 0x00 is invalid for the dst endpoint
String cmd_str = ""; // the actual low-level command, either specified or computed
// parse JSON
const JsonVariant &val_device = getCaseInsensitive(json, PSTR("Device"));
if (nullptr != &val_device) {
device = zigbee_devices.parseDeviceParam(val_device.as<char*>());
@ -729,7 +730,7 @@ void CmndZbRead(void) {
}
if ((0 != endpoint) && (attrs_len > 0)) {
ZigbeeZCLSend(device, cluster, endpoint, ZCL_READ_ATTRIBUTES, false, attrs, attrs_len, false /* we do want a response */);
ZigbeeZCLSend(device, cluster, endpoint, ZCL_READ_ATTRIBUTES, false, attrs, attrs_len, true /* we do want a response */, zigbee_devices.getNextSeqNumber(device));
ResponseCmndDone();
} else {
ResponseCmndChar("Missing parameters");