Skip to content

Commit

Permalink
fix: EZSP: fix frombuffer refactor GP (#1023)
Browse files Browse the repository at this point in the history
  • Loading branch information
Nerivec authored Apr 21, 2024
1 parent d855b3b commit bd4f476
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 65 deletions.
9 changes: 3 additions & 6 deletions src/adapter/ezsp/driver/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import {/* Basic Types */
LVBytes,
fixed_list,
WordList,
Bytes,

/* Named Types */
EmberNodeId,
Expand Down Expand Up @@ -2252,11 +2251,9 @@ export const FRAMES: {[key: string]: EZSPFrameDesc} = {
bidirectionalInfo: uint8_t,
gpdSecurityFrameCounter: uint32_t,
gpdCommandId: uint8_t,
payload: Bytes,
// mic: uint32_t,
//attr: EmberGpSinkListEntry,
// proxyTableIndex: uint8_t,
// gpdCommandPayload: LVBytes
mic: uint32_t,
proxyTableIndex: uint8_t,
gpdCommandPayload: LVBytes,
},
},
changeSourceRouteHandler: {
Expand Down
98 changes: 39 additions & 59 deletions src/adapter/ezsp/driver/driver.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* istanbul ignore file */
import * as TsType from './../../tstype';
import {Ezsp, EZSPFrameData, EZSPZDOResponseFrameData} from './ezsp';
import {EmberStatus, EmberNodeType, uint16_t, uint8_t, uint32_t, EmberZDOCmd, EmberApsOption, EmberKeyData,
import {EmberStatus, EmberNodeType, uint16_t, uint8_t, EmberZDOCmd, EmberApsOption, EmberKeyData,
EmberJoinDecision} from './types';
import {EventEmitter} from "events";
import {EmberApsFrame, EmberNetworkParameters, EmberInitialSecurityState, EmberKeyStruct,
Expand All @@ -28,6 +28,7 @@ import equals from 'fast-deep-equal/es6';
import {ParamsDesc} from './commands';
import {EZSPAdapterBackup} from '../adapter/backup';
import {logger} from '../../../utils/logger';
import Cluster from '../../../zcl/definition/cluster';

const NS = 'zh:ezsp:driv';

Expand Down Expand Up @@ -428,7 +429,43 @@ export class Driver extends EventEmitter {
// break;
// }
case (frameName == 'gpepIncomingMessageHandler'): {
this.handleGPMessage(frame);
let commandIdentifier = Cluster.greenPower.commands.notification.ID;

if (frame.gpdCommandId === 0xE0) {
if (!frame.gpdCommandPayload.length) {
// XXX: seem to be receiving duplicate commissioningNotification from some devices, second one with empty payload?
// this will mess with the process no doubt, so dropping them
return;
}

commandIdentifier = Cluster.greenPower.commands.commissioningNotification.ID;
}

const gpdHeader = Buffer.alloc(15);
gpdHeader.writeUInt8(0b00000001, 0);// frameControl: FrameType.SPECIFIC + Direction.CLIENT_TO_SERVER + disableDefaultResponse=false
gpdHeader.writeUInt8(frame.sequenceNumber, 1);// transactionSequenceNumber
gpdHeader.writeUInt8(commandIdentifier, 2);// commandIdentifier
gpdHeader.writeUInt16LE(0, 3);// options XXX: bypassed, same as deconz https://github.com/Koenkk/zigbee-herdsman/pull/536
gpdHeader.writeUInt32LE(frame.srcId, 5);// srcID
// omitted: gpdIEEEAddr ieeeAddr
// omitted: gpdEndpoint uint8
gpdHeader.writeUInt32LE(frame.gpdSecurityFrameCounter, 9);// frameCounter
gpdHeader.writeUInt8(frame.gpdCommandId, 13);// commandID
gpdHeader.writeUInt8(frame.gpdCommandPayload.length, 14);// payloadSize

const gpdMessage = {
messageType: frame.gpdCommandId,
apsFrame: {
profileId: 0xA1E0,
sourceEndpoint: 242,
clusterId: 0x0021,
sequence: frame.sequenceNumber,
},
lqi: frame.gpdLink,
message: Buffer.concat([gpdHeader, frame.gpdCommandPayload]),
sender: frame.addr,
};
this.emit('incomingMessage', gpdMessage);
break;
}
default:
Expand Down Expand Up @@ -821,63 +858,6 @@ export class Driver extends EventEmitter {
}
}

private handleGPMessage(frame: EZSPFrameData): void {
// Commissioning
if (frame.gpdCommandId == 0xE0) {
let data = frame.payload.subarray(5);
/* eslint-disable */
let st, deviceId, options, extOptions, key, mic, counter;
[st, data] = uint8_t.deserialize(uint8_t, data);
[deviceId, data] = uint8_t.deserialize(uint8_t, data);
[options, data] = uint8_t.deserialize(uint8_t, data);
[extOptions, data] = uint8_t.deserialize(uint8_t, data);
[key, data] = EmberKeyData.deserialize(EmberKeyData, data);
[mic, data] = uint32_t.deserialize(uint32_t, data);
[counter, data] = uint32_t.deserialize(uint32_t, data);
/* eslint-enable */
const gpdMessage = {
messageType: frame.gpdCommandId,
apsFrame: {
profileId: 0xA1E0,
sourceEndpoint: 242,
clusterId: 0x0021,
sequence: frame.sequenceNumber,
},
lqi: frame.gpdLink,
message: {
commandID: frame.gpdCommandId,
commandFrame: {
options: options,
securityKey: Buffer.from(key.contents),
deviceID: deviceId,
outgoingCounter: counter,
},
srcID: frame.srcId,
},
sender: frame.addr,
};
this.emit('incomingMessage', gpdMessage);
} else {
const gpdMessage = {
messageType: frame.gpdCommandId,
apsFrame: {
profileId: 0xA1E0,
sourceEndpoint: 242,
clusterId: 0x0021,
sequence: frame.sequenceNumber,
},
lqi: frame.gpdLink,
message: {
commandID: frame.gpdCommandId,
frameCounter: frame.sequenceNumber,
srcID: frame.srcId,
},
sender: frame.addr,
};
this.emit('incomingMessage', gpdMessage);
}
}

public async getKey(keyType: EmberKeyType): Promise<EZSPFrameData> {
if (this.ezsp.ezspV < 13) {
return this.ezsp.execCommand('getKey', {keyType});
Expand Down

0 comments on commit bd4f476

Please sign in to comment.