dresden-elektronik / deconz-rest-plugin

deCONZ REST-API plugin to control ZigBee devices
BSD 3-Clause "New" or "Revised" License
1.89k stars 498 forks source link

Problem with DATA_CONFIRM packet received using ConBee II #1520

Closed dhylands closed 5 years ago

dhylands commented 5 years ago

I just tried my new ConBee II and ran into an issue.

The firmware is reporting version 26400700

Things get started off by my host software sending a ZDO Mgmt LQI Neighbor Table request

  c0
  12    APS_DATA_REQUEST - Enqueue Send Data
  14    Sequence Number
  00    Reserved
  1e 00 frameLen
  17 00 payloadLen
  02    request ID
  00    flags
  03    addrMode (64-bit)
  98 d4 03 ff ff 2e 21 00 - 64 bit address of the ConBee II dongle
  00    destination endpoint
  00 00 profileId - ZDO
  31 00 clusterId - Mgmt LQI (Neighbor Table) Req (0x0031)
  00    sourceEndpoint
  02 00 ADSU len
  02    zdoSeq
  00    startIndex
  04    txOptions
  00    radius
  ab fb CRC
  c0

I then receive a response:

  c0
  12    APS_DATA_REQUEST - Enqueue Send Data
  14    Sequence Number
  00    status
  09 00 frameLen
  02 00 payloadLeb
  22    deviceState
  02    requestId
  ab ff CRC
  c0

followed by a device state changed:

  c0
  0e    Device State Changed (0x0e)
  15    Seqnum
  00    status
  07 00 frameLen
  a6    deviceState
  00    reserved
  30 ff CRC
  c0

So I send a DATA CONFIRM:

  c0
  04    Data Confirm - Query Send Data State (0x04)
  15    Seqnum
  00    Reserved
  07 00 frameLen
  00 00 payloadLen
  e0 ff CRC
  c0

And get back an invalid data confirm response

  c0
  04    Data Confirm
  15    Seqnum
  00    Reserved
  11 00 frameLen
  0a 00 payloadLen
  22    deviceState
  02    requestId
  03    destAddrMode
  98 2e a6  00 00 00 00  <<<< There isn't enough data here for dstAddrMode == 3
  39 fe CRC
  c0

The frameLen/payloadLen is consitent with the amount of data received. However, it says that dstAddrMode is 3, but it only includes 7 more bytes of data. The frameLen and payload len also don't match anything from the documentation.

Admittedly, I should probably be sending the Mgmt LQI request to addr 0000 but this code worked fine with the original ConBee.

dhylands commented 5 years ago

I can confirm that this still happens using the latest ConBee II firmware (26490700)

dhylands commented 5 years ago

I've updated my code to send using 16-bit addresses and that seems to mostly eliminate the problem. I still get the issue when sending out Network Address Requests (Cluster 0x0000), which are sent to a 64-bit address to discover its 16-bit address.

For example, using the IKEA outlet, when using the ConBee I get back a valid network addr response, but with the ConBee II i get back the short CONFIRM packet and never receive the Network Address Response.

dhylands commented 5 years ago

This program: https://github.com/mozilla-iot/deconz-api/blob/master/test.js demonstrates the problem 100% of the time (It prints Rcvd DATA_CONFIRM with invalid payLoad len of 10). With a ConBee dongle I get a NetworkAddress response.

manup commented 5 years ago

Thanks a lot for the detailed test. I can confirm the bug, it slipped in during porting the AVR to ARM firmware. The 64-bit address is written but the pointer in the buffer wasn't incremented by eight, so basically the whole destination address field is missing.

This is fixed now and will be available in firmware version 0x264a0700 in the next two days.

Double checked, the AVR based ConBee and RaspBee firmware doesn't contain the bug. In deCONZ we haven't stumbled over this yet since we're only using the request id to match the APS confirm to the request.

I've updated my code to send using 16-bit addresses and that seems to mostly eliminate the problem. I still get the issue when sending out Network Address Requests (Cluster 0x0000), which are sent to a 64-bit address to discover its 16-bit address.

I would recommend to send the Network Address Request as broadcast to all routers (0xFFFC) with destination address mode set to NWK address. The matching device, or in case of a sleeping end-device the parent, will respond to it.

dhylands commented 5 years ago

I would recommend to send the Network Address Request as broadcast to all routers (0xFFFC) with destination address mode set to NWK address. The matching device, or in case of a sleeping end-device the parent, will respond to it.

Cool - thanks for the tip, I'll update my code.

dhylands commented 5 years ago

I tried using dstAddrMode = 2 with a 16-bit address of 0xfffc and destination endpoints of 0, 1 and 255 and I always get back a confirmStatus of 166 (INVALID_PARAMETER). I also tried dstAddrMode = 1 (group) and a 16-bit address of 0xfffc, but this also resulted in INVALID_PARAMETER.

What's the correct way to do a broadcast?

manup commented 5 years ago

Hmm basically for ZDP it should look like:

02 destination address mode
FC FF destination nwk address
00 destination endpoint
00 00 ZDP profile id
00 00 NWK Address Request cluster id
00 source endpoint
... asdu fields ...
dhylands commented 5 years ago

I figured it out. I had the txOptions field defaulting to 4 (Use APS ACKs) and I had to set that to 0 in order for the broadcast to work.

manup commented 5 years ago

Ah right, yes aps acks are rejected for broadcast addresses :relaxed:

manup commented 5 years ago

And here it is, the new firmware version 0x264a0700 fixes parsing and serialization of IEEE address mode (0x03) in APS_DATA_REQUEST (0x12), APS_DATA_CONFIRM (0x04) and APS_DATA_INDICATION (0x17) commands.

https://www.dresden-elektronik.de/rpi/deconz-firmware/deCONZ_ConBeeII_0x264a0700.bin.GCF

dhylands commented 5 years ago

So even with the new firmware, and code to reset the watchdog to 3600 every 1800 seconds, my ConBee II stops responding to commands after a while. This morning, I sent a command to turn a Hue light on. A few hours later sending a command to turn the light off no longer works. My ConBee doesn't suffer from this problem.

manup commented 5 years ago

I've read over the code a bit (by the way, very good architecture; easy to understand and follow). To me it seems the watchdog parameter frame builder isn't implemented yet?

https://github.com/dhylands/deconz-api/blob/38fe0ba3b6dd5727936ff088fda6673c83453dd4/lib/frame-builder.js#L190-L196

According to the code an error should have been raised here?

dhylands commented 5 years ago

Sorry about that - the watchdog changes are still on my local branch. I found a bug this morning. I was creating the commands to write the watchdog parameter and not actually sending them - Doh. I'm retesting and will report back.

dhylands commented 5 years ago

So far so good. It's survived past the first hour.

manup commented 5 years ago

:) cool, hope it stays connected.

dhylands commented 5 years ago

I left it overnight and it was still working in the morning.