Fix Zigbee auto-increment transaction number (#7757)

This commit is contained in:
Hadinger 2020-02-22 20:53:55 +01:00
parent f706b7c490
commit 13763f55a6
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) - 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 initial support for Sensors AHT10 and AHT15 by Martin Wagner (#7596)
- Add support for Wemos Motor Shield V1 by Denis Sborets (#7764) - Add support for Wemos Motor Shield V1 by Denis Sborets (#7764)
- Fix Zigbee auto-increment transaction number (#7757)
### 8.1.0.8 20200212 ### 8.1.0.8 20200212

View File

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

View File

@ -21,7 +21,7 @@
// contains some definitions for functions used before their declarations // 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 // 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 // json buffer used for attribute reporting
DynamicJsonBuffer *json_buffer; DynamicJsonBuffer *json_buffer;
JsonObject *json; JsonObject *json;
// sequence number for Zigbee frames
uint8_t seqNumber;
} Z_Device; } Z_Device;
// All devices are stored in a Vector // All devices are stored in a Vector
@ -96,6 +98,9 @@ public:
// device just seen on the network, update the lastSeen field // device just seen on the network, update the lastSeen field
void updateLastSeen(uint16_t shortaddr); void updateLastSeen(uint16_t shortaddr);
// get next sequence number for (increment at each all)
uint8_t getNextSeqNumber(uint16_t shortaddr);
// Dump json // Dump json
String dump(uint32_t dump_mode, uint16_t status_shortaddr = 0) const; String dump(uint32_t dump_mode, uint16_t status_shortaddr = 0) const;
@ -133,6 +138,7 @@ public:
private: private:
std::vector<Z_Device> _devices = {}; std::vector<Z_Device> _devices = {};
uint32_t _saveTimer = 0; uint32_t _saveTimer = 0;
uint8_t _seqNumber = 0; // global seqNumber if device is unknown
template < typename T> template < typename T>
static bool findInVector(const std::vector<T> & vecOfElements, const T & element); 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>(), std::vector<uint32_t>(),
0,0,0,0, 0,0,0,0,
nullptr, nullptr,
nullptr, nullptr }; nullptr, nullptr,
0, // seqNumber
};
device.json_buffer = new DynamicJsonBuffer(); device.json_buffer = new DynamicJsonBuffer();
_devices.push_back(device); _devices.push_back(device);
dirty(); dirty();
@ -532,6 +540,19 @@ void Z_Devices::updateLastSeen(uint16_t shortaddr) {
_updateLastSeen(device); _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 // Per device timers
// //
// Reset the timer for a specific device // 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; break;
} }
if (attrs) { 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()); 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); zcl_received.postProcessAttributes(srcaddr, json);
// Add Endpoint
json[F(D_CMND_ZIGBEE_ENDPOINT)] = srcendpoint;
// Add linkquality // Add linkquality
json[F(D_CMND_ZIGBEE_LINKQUALITY)] = 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))); 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); SBuffer buf(25+len);
buf.add8(Z_SREQ | Z_AF); // 24 buf.add8(Z_SREQ | Z_AF); // 24
buf.add8(AF_DATA_REQUEST); // 01 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(0x1E); // 1E radius
buf.add8(3 + len); 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(transacId); // Transaction Sequance Number
buf.add8(cmdId); buf.add8(cmdId);
if (len > 0) { 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 // 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 // now set the timer, if any, to read back the state later
if (clusterSpecific) { if (clusterSpecific) {
zigbeeSetCommandTimer(dstAddr, cluster, endpoint); zigbeeSetCommandTimer(dstAddr, cluster, endpoint);
@ -469,6 +469,7 @@ void CmndZbSend(void) {
uint8_t endpoint = 0x00; // 0x00 is invalid for the dst endpoint uint8_t endpoint = 0x00; // 0x00 is invalid for the dst endpoint
String cmd_str = ""; // the actual low-level command, either specified or computed String cmd_str = ""; // the actual low-level command, either specified or computed
// parse JSON
const JsonVariant &val_device = getCaseInsensitive(json, PSTR("Device")); const JsonVariant &val_device = getCaseInsensitive(json, PSTR("Device"));
if (nullptr != &val_device) { if (nullptr != &val_device) {
device = zigbee_devices.parseDeviceParam(val_device.as<char*>()); device = zigbee_devices.parseDeviceParam(val_device.as<char*>());
@ -729,7 +730,7 @@ void CmndZbRead(void) {
} }
if ((0 != endpoint) && (attrs_len > 0)) { 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(); ResponseCmndDone();
} else { } else {
ResponseCmndChar("Missing parameters"); ResponseCmndChar("Missing parameters");