@@ -11,7 +11,7 @@ import {logger} from '../../../utils/logger';
11
11
import Waitress from '../../../utils/waitress' ;
12
12
import * as ZSpec from '../../../zspec' ;
13
13
import * as Zdo from '../../../zspec/zdo' ;
14
- import { EndDeviceAnnounce , GenericZdoResponse } from '../../../zspec/zdo/definition/tstypes' ;
14
+ import { EndDeviceAnnounce , GenericZdoResponse , ResponseMap as ZdoResponseMap } from '../../../zspec/zdo/definition/tstypes' ;
15
15
import { SerialPort } from '../../serialPort' ;
16
16
import SerialPortUtils from '../../serialPortUtils' ;
17
17
import SocketPortUtils from '../../socketPortUtils' ;
@@ -345,33 +345,47 @@ export default class ZiGate extends EventEmitter<ZiGateEventMap> {
345
345
346
346
this . zdoWaitress . resolve ( { ziGatePayload, zdo} ) ;
347
347
this . emit ( 'zdoResponse' , ziGatePayload . clusterID , zdo ) ;
348
+ } else if ( code === ZiGateMessageCode . LeaveIndication && ziGateObject . payload . rejoin === 0 ) {
349
+ // mock a ZDO response (if waiter present) as zigate does not follow spec on this (missing ZDO LEAVE_RESPONSE)
350
+ const ziGatePayload : ZdoWaitressPayload [ 'ziGatePayload' ] = {
351
+ status : 0 ,
352
+ profileID : Zdo . ZDO_PROFILE_ID ,
353
+ clusterID : Zdo . ClusterId . LEAVE_RESPONSE , // only piece actually required for waitress validation
354
+ sourceEndpoint : Zdo . ZDO_ENDPOINT ,
355
+ destinationEndpoint : Zdo . ZDO_ENDPOINT ,
356
+ sourceAddressMode : 0x03 ,
357
+ sourceAddress : ziGateObject . payload . extendedAddress ,
358
+ destinationAddressMode : 0x03 ,
359
+ destinationAddress : ZSpec . BLANK_EUI64 ,
360
+ // @ts -expect-error not used
361
+ payload : undefined ,
362
+ } ;
363
+
364
+ // Workaround: `zdo` is not valid for LEAVE_RESPONSE, but required to pass altered waitress validation (in sendZdo)
365
+ if ( this . zdoWaitress . resolve ( { ziGatePayload, zdo : [ Zdo . Status . SUCCESS , { eui64 : ziGateObject . payload . extendedAddress } ] } ) ) {
366
+ this . emit ( 'zdoResponse' , Zdo . ClusterId . LEAVE_RESPONSE , [
367
+ Zdo . Status . SUCCESS ,
368
+ undefined ,
369
+ ] as ZdoResponseMap [ Zdo . ClusterId . LEAVE_RESPONSE ] ) ;
370
+ }
371
+
372
+ this . emit ( 'LeaveIndication' , ziGateObject ) ;
348
373
} else {
349
374
this . waitress . resolve ( ziGateObject ) ;
350
- }
351
375
352
- switch ( code ) {
353
- case ZiGateMessageCode . DataIndication :
354
- switch ( ziGateObject . payload . profileID ) {
355
- case Zdo . ZDO_PROFILE_ID :
356
- // handled above
357
- break ;
358
- case ZSpec . HA_PROFILE_ID :
359
- this . emit ( 'received' , ziGateObject ) ;
360
- break ;
361
- default :
362
- logger . debug ( 'not implemented profile: ' + ziGateObject . payload . profileID , NS ) ;
376
+ if ( code === ZiGateMessageCode . DataIndication ) {
377
+ if ( ziGateObject . payload . profileID === ZSpec . HA_PROFILE_ID ) {
378
+ this . emit ( 'received' , ziGateObject ) ;
379
+ } else {
380
+ logger . debug ( 'not implemented profile: ' + ziGateObject . payload . profileID , NS ) ;
363
381
}
364
- break ;
365
- case ZiGateMessageCode . LeaveIndication :
366
- this . emit ( 'LeaveIndication' , ziGateObject ) ;
367
- break ;
368
- case ZiGateMessageCode . DeviceAnnounce :
382
+ } else if ( code === ZiGateMessageCode . DeviceAnnounce ) {
369
383
this . emit ( 'DeviceAnnounce' , {
370
384
nwkAddress : ziGateObject . payload . shortAddress ,
371
385
eui64 : ziGateObject . payload . ieee ,
372
386
capabilities : ziGateObject . payload . MACcapability ,
373
387
} ) ;
374
- break ;
388
+ }
375
389
}
376
390
} catch ( error ) {
377
391
logger . error ( `Parsing error: ${ error } ` , NS ) ;
0 commit comments