@@ -420,10 +420,22 @@ async def startup(self, auto_form=False):
420
420
endpoint = 100 , profile_id = zigpy .profiles .zll .PROFILE_ID , device_id = 0x0005
421
421
)
422
422
423
- # Structure is in `zstack/stack/nwk/nwk.h`
423
+ # Structure is in `zstack/stack/nwk/nwk.h`.
424
+ #
425
+ # This is hacky but since there are exactly two distinct firmwares, it doesn't
426
+ # make sense to try and write some fancys struct padding guesser.
424
427
nib = await self ._znp .nvram_read (NwkNvIds .NIB )
425
- self ._channel = nib [24 ]
426
- self ._channels = t .Channels .deserialize (nib [40 :44 ])[0 ]
428
+
429
+ if len (nib ) == 116 :
430
+ # Structs aligned to 16 bits: CC26x2, CC13X2
431
+ self ._channel = nib [24 ]
432
+ self ._channels , _ = t .Channels .deserialize (nib [40 :44 ])
433
+ elif len (nib ) == 110 :
434
+ # No struct alignment: CC2531
435
+ self ._channel = nib [22 ]
436
+ self ._channels , _ = t .Channels .deserialize (nib [36 :40 ])
437
+ else :
438
+ LOGGER .warning ("Could not extract channel information from NIB: %r" , nib )
427
439
428
440
async def update_network (
429
441
self ,
@@ -469,9 +481,16 @@ async def update_network(
469
481
self ._channels = channels
470
482
471
483
if channel is not None :
472
- # We modify the logical channel value directly in the NIB
484
+ # XXX: We modify the logical channel value directly in the NIB
473
485
nib = bytearray (await self ._znp .nvram_read (NwkNvIds .NIB ))
474
- nib [24 ] = channel
486
+
487
+ if len (nib ) == 116 :
488
+ nib [24 ] = channel
489
+ elif len (nib ) == 110 :
490
+ nib [22 ] = channel
491
+ else :
492
+ raise RuntimeError (f"Cannot set channel in unknown NIB struct: { nib !r} " )
493
+
475
494
await self ._znp .nvram_write (NwkNvIds .NIB , nib )
476
495
477
496
self ._channel = channel
0 commit comments