Skip to content

Commit

Permalink
fix: several more tests
Browse files Browse the repository at this point in the history
  • Loading branch information
AlCalzone committed Oct 21, 2024
1 parent 1d92664 commit 3cdd24b
Show file tree
Hide file tree
Showing 12 changed files with 90 additions and 89 deletions.
19 changes: 19 additions & 0 deletions packages/cc/src/cc/MultiChannelCC.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ import {
expectedCCResponse,
implementedVersion,
} from "../lib/CommandClassDecorators";
import {
isEncapsulatingCommandClass,
isMultiEncapsulatingCommandClass,
} from "../lib/EncapsulatingCommandClass";
import { V } from "../lib/Values";
import { MultiChannelCommand } from "../lib/_Types";

Expand Down Expand Up @@ -1373,6 +1377,21 @@ export class MultiChannelCCCommandEncapsulation extends MultiChannelCC {
super(options);
this.encapsulated = options.encapsulated;
this.encapsulated.encapsulatingCC = this as any;
// Propagate the endpoint index all the way down
let cur: CommandClass = this;
while (cur) {
if (isMultiEncapsulatingCommandClass(cur)) {
for (const cc of cur.encapsulated) {
cc.endpointIndex = this.endpointIndex;
}
break;
} else if (isEncapsulatingCommandClass(cur)) {
cur.encapsulated.endpointIndex = this.endpointIndex;
cur = cur.encapsulated;
} else {
break;
}
}
this.destination = options.destination;
}

Expand Down
2 changes: 2 additions & 0 deletions packages/cc/src/cc/MultiCommandCC.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ export class MultiCommandCCCommandEncapsulation extends MultiCommandCC {
this.encapsulated = options.encapsulated;
for (const cc of options.encapsulated) {
cc.encapsulatingCC = this as any;
// Multi Command CC is inside Multi Channel CC, so the endpoint must be copied
cc.endpointIndex = this.endpointIndex;
}
}

Expand Down
94 changes: 30 additions & 64 deletions packages/cc/src/cc/Security2CC.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1702,33 +1702,26 @@ export class Security2CCMessageEncapsulation extends Security2CC {
public readonly verifyDelivery: boolean = true;

public sequenceNumber: number | undefined;

protected assertSequenceNumber(): asserts this is this & {
private ensureSequenceNumber(
securityManager: SecurityManager2,
): asserts this is this & {
sequenceNumber: number;
} {
if (this.sequenceNumber == undefined) {
throw new ZWaveError(
`Sending a Security S2 CC requires the sequence number to be sent!`,
ZWaveErrorCodes.Security2CC_NoSPAN,
);
if (this.isSinglecast()) {
this.sequenceNumber = securityManager.nextSequenceNumber(
this.nodeId,
);
} else {
const groupId = getDestinationIDTX.call(this);
this.sequenceNumber = securityManager
.nextMulticastSequenceNumber(
groupId,
);
}
}
}

// public get sequenceNumber(): number {
// if (this._sequenceNumber == undefined) {
// if (this.isSinglecast()) {
// this._sequenceNumber = this.securityManager
// .nextSequenceNumber(this.nodeId);
// } else {
// const groupId = getDestinationIDTX.call(this);
// return this.securityManager.nextMulticastSequenceNumber(
// groupId,
// );
// }
// }
// return this._sequenceNumber;
// }

public encapsulated?: CommandClass;
public extensions: Security2Extension[];

Expand Down Expand Up @@ -1822,7 +1815,7 @@ export class Security2CCMessageEncapsulation extends Security2CC {

public serialize(ctx: CCEncodingContext): Buffer {
const securityManager = assertSecurityTX(ctx, this.nodeId);
this.assertSequenceNumber();
this.ensureSequenceNumber(securityManager);

// Include Sender EI in the command if we only have the receiver's EI
this.maybeAddSPANExtension(ctx, securityManager);
Expand Down Expand Up @@ -2062,39 +2055,25 @@ export class Security2CCNonceReport extends Security2CC {
}

public sequenceNumber: number | undefined;

protected assertSequenceNumber(): asserts this is this & {
private ensureSequenceNumber(
securityManager: SecurityManager2,
): asserts this is this & {
sequenceNumber: number;
} {
if (this.sequenceNumber == undefined) {
throw new ZWaveError(
`Sending a Security S2 CC requires the sequence number to be sent!`,
ZWaveErrorCodes.Security2CC_NoSPAN,
this.sequenceNumber = securityManager.nextSequenceNumber(
this.nodeId as number,
);
}
}
// /**
// * Return the sequence number of this command.
// *
// * **WARNING:** If the sequence number hasn't been set before, this will create a new one.
// * When sending messages, this should only happen immediately before serializing.
// */
// public get sequenceNumber(): number {
// if (this._sequenceNumber == undefined) {
// this._sequenceNumber = this.securityManager
// .nextSequenceNumber(
// this.nodeId as number,
// );
// }
// return this._sequenceNumber;
// }

public readonly SOS: boolean;
public readonly MOS: boolean;
public readonly receiverEI?: Buffer;

public serialize(ctx: CCEncodingContext): Buffer {
this.assertSequenceNumber();
const securityManager = assertSecurityTX(ctx, this.nodeId);
this.ensureSequenceNumber(securityManager);

this.payload = Buffer.from([
this.sequenceNumber,
Expand Down Expand Up @@ -2160,35 +2139,22 @@ export class Security2CCNonceGet extends Security2CC {
}

public sequenceNumber: number | undefined;

protected assertSequenceNumber(): asserts this is this & {
private ensureSequenceNumber(
securityManager: SecurityManager2,
): asserts this is this & {
sequenceNumber: number;
} {
if (this.sequenceNumber == undefined) {
throw new ZWaveError(
`Sending a Security S2 CC requires the sequence number to be sent!`,
ZWaveErrorCodes.Security2CC_NoSPAN,
this.sequenceNumber = securityManager.nextSequenceNumber(
this.nodeId as number,
);
}
}
// /**
// * Return the sequence number of this command.
// *
// * **WARNING:** If the sequence number hasn't been set before, this will create a new one.
// * When sending messages, this should only happen immediately before serializing.
// */
// public get sequenceNumber(): number {
// if (this._sequenceNumber == undefined) {
// this._sequenceNumber = this.securityManager
// .nextSequenceNumber(
// this.nodeId as number,
// );
// }
// return this._sequenceNumber;
// }

public serialize(ctx: CCEncodingContext): Buffer {
this.assertSequenceNumber();
const securityManager = assertSecurityTX(ctx, this.nodeId);
this.ensureSequenceNumber(securityManager);

this.payload = Buffer.from([this.sequenceNumber]);
return super.serialize(ctx);
}
Expand Down
1 change: 1 addition & 0 deletions packages/cc/src/cc/SecurityCC.ts
Original file line number Diff line number Diff line change
Expand Up @@ -637,6 +637,7 @@ export class SecurityCCCommandEncapsulation extends SecurityCC {
this.encapsulated = options.encapsulated;
this.encapsulated.encapsulatingCC = this as any;
} else {
this.decryptedCCBytes = options.decryptedCCBytes;
this.sequenced = options.sequenced;
this.secondFrame = options.secondFrame;
this.sequenceCounter = options.sequenceCounter;
Expand Down
2 changes: 2 additions & 0 deletions packages/cc/src/cc/SupervisionCC.ts
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,8 @@ export class SupervisionCCGet extends SupervisionCC {
this.sessionId = options.sessionId;
this.requestStatusUpdates = options.requestStatusUpdates;
this.encapsulated = options.encapsulated;
// Supervision is inside MultiChannel CCs, so the endpoint must be copied
this.encapsulated.endpointIndex = this.endpointIndex;
this.encapsulated.encapsulatingCC = this as any;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ function createLazySendDataPayload(
return () => {
try {
const cmd = CommandClass.parse(msg.payload, {
sourceNodeId: node.id,
sourceNodeId: controller.ownNodeId,
__internalIsMockNode: true,
...node.encodingContext,
...node.securityManagers,
Expand Down
2 changes: 1 addition & 1 deletion packages/zwave-js/src/lib/test/cc/BinarySwitchCC.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ test("the Report command (v2) should be deserialized correctly", (t) => {
t.is(cc.duration!.value, 1);
});

test.only("deserializing an unsupported command should return an unspecified version of BinarySwitchCC", (t) => {
test("deserializing an unsupported command should return an unspecified version of BinarySwitchCC", (t) => {
const serializedCC = buildCCBuffer(
Buffer.from([255]), // not a valid command
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -344,15 +344,15 @@ integrationTest(
const parseS0CC: MockNodeBehavior = {
handleCC(controller, self, receivedCC) {
// We don't support sequenced commands here
if (
receivedCC instanceof SecurityCCCommandEncapsulation
) {
receivedCC.mergePartialCCs(
[],
{} as any,
);
if (receivedCC instanceof SecurityCCCommandEncapsulation) {
receivedCC.mergePartialCCs([], {
sourceNodeId: controller.ownNodeId,
__internalIsMockNode: true,
...self.encodingContext,
...self.securityManagers,
});
}

// This just decodes - we need to call further handlers
return undefined;
},
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,14 +63,13 @@ integrationTest(
const parseS0CC: MockNodeBehavior = {
handleCC(controller, self, receivedCC) {
// We don't support sequenced commands here
if (
receivedCC
instanceof SecurityCCCommandEncapsulation
) {
receivedCC.mergePartialCCs(
[],
{} as any,
);
if (receivedCC instanceof SecurityCCCommandEncapsulation) {
receivedCC.mergePartialCCs([], {
sourceNodeId: controller.ownNodeId,
__internalIsMockNode: true,
...self.encodingContext,
...self.securityManagers,
});
}
// This just decodes - we need to call further handlers
return undefined;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import path from "node:path";
import { integrationTest } from "../integrationTestSuite";

integrationTest("S0 commands are S0-encapsulated, even when S2 is supported", {
debug: true,
// debug: true,

// We need the cache to skip the CC interviews and mark S2 as supported
provisioningDirectory: path.join(
Expand Down Expand Up @@ -110,7 +110,12 @@ integrationTest("S0 commands are S0-encapsulated, even when S2 is supported", {
handleCC(controller, self, receivedCC) {
// We don't support sequenced commands here
if (receivedCC instanceof SecurityCCCommandEncapsulation) {
receivedCC.mergePartialCCs([], {} as any);
receivedCC.mergePartialCCs([], {
sourceNodeId: controller.ownNodeId,
__internalIsMockNode: true,
...self.encodingContext,
...self.securityManagers,
});
}
return undefined;
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,12 @@ integrationTest("Communication via Security S0 works", {
handleCC(controller, self, receivedCC) {
// We don't support sequenced commands here
if (receivedCC instanceof SecurityCCCommandEncapsulation) {
receivedCC.mergePartialCCs([], {} as any);
receivedCC.mergePartialCCs([], {
sourceNodeId: controller.ownNodeId,
__internalIsMockNode: true,
...self.encodingContext,
...self.securityManagers,
});
}
// This just decodes - we need to call further handlers
return undefined;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,10 +207,12 @@ integrationTest(
if (
receivedCC instanceof SecurityCCCommandEncapsulation
) {
receivedCC.mergePartialCCs(
[],
{} as any,
);
receivedCC.mergePartialCCs([], {
sourceNodeId: controller.ownNodeId,
__internalIsMockNode: true,
...self.encodingContext,
...self.securityManagers,
});
}
// This just decodes - we need to call further handlers
return undefined;
Expand Down

0 comments on commit 3cdd24b

Please sign in to comment.