Skip to content

Commit

Permalink
refactor: pass ownNodeId where required
Browse files Browse the repository at this point in the history
  • Loading branch information
AlCalzone committed Oct 14, 2024
1 parent c774a14 commit b3981fa
Show file tree
Hide file tree
Showing 72 changed files with 357 additions and 271 deletions.
28 changes: 21 additions & 7 deletions packages/cc/src/cc/Security2CC.ts
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ export class Security2CCAPI extends CCAPI {

const cc = new Security2CCNonceReport(this.applHost, {
nodeId: this.endpoint.nodeId,
ownNodeId: this.applHost.ownNodeId,
endpoint: this.endpoint.index,
securityManagers: this.applHost,
SOS: true,
Expand Down Expand Up @@ -259,6 +260,7 @@ export class Security2CCAPI extends CCAPI {

const cc = new Security2CCNonceReport(this.applHost, {
nodeId: this.endpoint.nodeId,
ownNodeId: this.applHost.ownNodeId,
endpoint: this.endpoint.index,
securityManagers: this.applHost,
SOS: false,
Expand Down Expand Up @@ -303,6 +305,7 @@ export class Security2CCAPI extends CCAPI {

const cc = new Security2CCMessageEncapsulation(this.applHost, {
nodeId: this.endpoint.nodeId,
ownNodeId: this.applHost.ownNodeId,
endpoint: this.endpoint.index,
securityManagers: this.applHost,
extensions: [
Expand Down Expand Up @@ -368,6 +371,7 @@ export class Security2CCAPI extends CCAPI {
cc = Security2CC.encapsulate(
this.applHost,
cc,
this.applHost.ownNodeId,
this.applHost,
{ securityClass },
);
Expand Down Expand Up @@ -612,13 +616,16 @@ export class Security2CC extends CommandClass {

protected assertSecurity(
options:
| (CCCommandOptions & { securityManagers: SecurityManagers })
| (CCCommandOptions & {
ownNodeId: number;
securityManagers: SecurityManagers;
})
| CommandClassDeserializationOptions,
): SecurityManager2 {
const verb = gotDeserializationOptions(options) ? "decoded" : "sent";
const ownNodeId = gotDeserializationOptions(options)
? options.context.ownNodeId
: this.host.ownNodeId;
: options.ownNodeId;
if (!ownNodeId) {
throw new ZWaveError(
`Secure commands (S2) can only be ${verb} when the controller's node id is known!`,
Expand Down Expand Up @@ -945,6 +952,7 @@ export class Security2CC extends CommandClass {
public static encapsulate(
host: ZWaveHost,
cc: CommandClass,
ownNodeId: number,
securityManagers: SecurityManagers,
options?: {
securityClass?: SecurityClass;
Expand Down Expand Up @@ -979,6 +987,7 @@ export class Security2CC extends CommandClass {

const ret = new Security2CCMessageEncapsulation(host, {
nodeId,
ownNodeId,
encapsulated: cc,
securityManagers,
securityClass: options?.securityClass,
Expand All @@ -999,6 +1008,7 @@ export class Security2CC extends CommandClass {
export interface Security2CCMessageEncapsulationOptions
extends CCCommandOptions
{
ownNodeId: number;
securityManagers: Readonly<SecurityManagers>;
/** Can be used to override the default security class for the command */
securityClass?: SecurityClass;
Expand Down Expand Up @@ -1247,8 +1257,8 @@ export class Security2CCMessageEncapsulation extends Security2CC {

const authData = getAuthenticationData(
sendingNodeId,
this.getDestinationIDRX(),
this.host.homeId,
this.getDestinationIDRX(options.context.ownNodeId),
options.context.homeId,
messageLength,
unencryptedPayload,
);
Expand Down Expand Up @@ -1486,8 +1496,8 @@ export class Security2CCMessageEncapsulation extends Security2CC {
return ret;
}

private getDestinationIDRX(): number {
if (this.isSinglecast()) return this.host.ownNodeId;
private getDestinationIDRX(ownNodeId: number): number {
if (this.isSinglecast()) return ownNodeId;

const ret = this.getMulticastGroupId();
if (ret == undefined) {
Expand Down Expand Up @@ -1956,7 +1966,10 @@ export class Security2CCMessageEncapsulation extends Security2CC {

// @publicAPI
export type Security2CCNonceReportOptions =
& { securityManagers: SecurityManagers }
& {
ownNodeId: number;
securityManagers: SecurityManagers;
}
& (
| {
MOS: boolean;
Expand Down Expand Up @@ -2067,6 +2080,7 @@ export class Security2CCNonceReport extends Security2CC {

// @publicAPI
export interface Security2CCNonceGetOptions {
ownNodeId: number;
securityManagers: Readonly<SecurityManagers>;
}

Expand Down
16 changes: 14 additions & 2 deletions packages/cc/src/cc/SecurityCC.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ export class SecurityCCAPI extends PhysicalCCAPI {
: SecurityCCCommandEncapsulation
)(this.applHost, {
nodeId: this.endpoint.nodeId,
ownNodeId: this.applHost.ownNodeId,
securityManager: this.applHost.securityManager!,
encapsulated,
});
Expand Down Expand Up @@ -237,6 +238,7 @@ export class SecurityCCAPI extends PhysicalCCAPI {
cc = new SecurityCCCommandEncapsulation(this.applHost, {
nodeId: this.endpoint.nodeId,
endpoint: this.endpoint.index,
ownNodeId: this.applHost.ownNodeId,
securityManager: this.applHost.securityManager!,
encapsulated: cc,
});
Expand Down Expand Up @@ -272,6 +274,7 @@ export class SecurityCCAPI extends PhysicalCCAPI {
const cc = new SecurityCCCommandEncapsulation(this.applHost, {
nodeId: this.endpoint.nodeId,
endpoint: this.endpoint.index,
ownNodeId: this.applHost.ownNodeId,
securityManager: this.applHost.securityManager!,
encapsulated: keySet,
alternativeNetworkKey: Buffer.alloc(16, 0),
Expand Down Expand Up @@ -342,11 +345,17 @@ export class SecurityCC extends CommandClass {

protected assertSecurity(
options:
| (CCCommandOptions & { securityManager: SecurityManager })
| (CCCommandOptions & {
ownNodeId: number;
securityManager: SecurityManager;
})
| CommandClassDeserializationOptions,
): SecurityManager {
const verb = gotDeserializationOptions(options) ? "decoded" : "sent";
if (!this.host.ownNodeId) {
const ownNodeId = gotDeserializationOptions(options)
? options.context.ownNodeId
: options.ownNodeId;
if (!ownNodeId) {
throw new ZWaveError(
`Secure commands (S0) can only be ${verb} when the controller's node id is known!`,
ZWaveErrorCodes.Driver_NotReady,
Expand Down Expand Up @@ -529,12 +538,14 @@ export class SecurityCC extends CommandClass {
/** Encapsulates a command that should be sent encrypted */
public static encapsulate(
host: ZWaveHost,
ownNodeId: number,
securityManager: SecurityManager,
cc: CommandClass,
): SecurityCCCommandEncapsulation {
// TODO: When to return a SecurityCCCommandEncapsulationNonceGet?
const ret = new SecurityCCCommandEncapsulation(host, {
nodeId: cc.nodeId,
ownNodeId,
securityManager,
encapsulated: cc,
});
Expand Down Expand Up @@ -600,6 +611,7 @@ export class SecurityCCNonceGet extends SecurityCC {}
export interface SecurityCCCommandEncapsulationOptions
extends CCCommandOptions
{
ownNodeId: number;
securityManager: SecurityManager;
encapsulated: CommandClass;
alternativeNetworkKey?: Buffer;
Expand Down
2 changes: 1 addition & 1 deletion packages/host/src/ZWaveHost.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ export interface CCEncodingContext
}

/** Host application abstractions to be used in Serial API and CC implementations */
export interface ZWaveHost extends HostIDs {
export interface ZWaveHost {
/**
* Retrieves the maximum version of a command class that can be used to communicate with a node.
* Returns 1 if the node claims that it does not support a CC.
Expand Down
6 changes: 2 additions & 4 deletions packages/host/src/mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,9 @@ import {
ZWaveErrorCodes,
} from "@zwave-js/core";
import { createThrowingMap } from "@zwave-js/shared";
import type { ZWaveApplicationHost, ZWaveHost } from "./ZWaveHost";
import type { HostIDs, ZWaveApplicationHost, ZWaveHost } from "./ZWaveHost";

export interface CreateTestingHostOptions {
homeId: ZWaveHost["homeId"];
ownNodeId: ZWaveHost["ownNodeId"];
export interface CreateTestingHostOptions extends HostIDs {
getSafeCCVersion: ZWaveHost["getSafeCCVersion"];
getSupportedCCVersion?: ZWaveHost["getSupportedCCVersion"];
}
Expand Down
26 changes: 8 additions & 18 deletions packages/testing/src/MockController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,10 @@ export class MockController {
// const valueDBCache = new Map<number, ValueDB>();
// const supervisionSessionIDs = new Map<number, () => number>();

this.ownNodeId = options.ownNodeId ?? 1;
this.homeId = options.homeId ?? 0x7e571000;

this.host = {
ownNodeId: options.ownNodeId ?? 1,
homeId: options.homeId ?? 0x7e571000,
// nodes: this.nodes as any,
getSafeCCVersion: () => 100,
getSupportedCCVersion: (cc, nodeId, endpointIndex = 0) => {
if (!this.nodes.has(nodeId)) {
Expand All @@ -75,19 +75,6 @@ export class MockController {
return (endpoint ?? node).implementedCCs.get(cc)?.version ?? 0;
},
isCCSecure: () => false,
// getValueDB: (nodeId) => {
// if (!valueDBCache.has(nodeId)) {
// valueDBCache.set(
// nodeId,
// new ValueDB(
// nodeId,
// valuesStorage as any,
// metadataStorage as any,
// ),
// );
// }
// return valueDBCache.get(nodeId)!;
// },
};

this.capabilities = {
Expand All @@ -97,8 +84,8 @@ export class MockController {

const securityClasses = new Map<number, Map<SecurityClass, boolean>>();
this.encodingContext = {
homeId: this.host.homeId,
ownNodeId: this.host.ownNodeId,
homeId: this.homeId,
ownNodeId: this.ownNodeId,
// TODO: LR is not supported in mocks
nodeIdType: NodeIDType.Short,
hasSecurityClass(
Expand Down Expand Up @@ -142,6 +129,9 @@ export class MockController {
void this.execute();
}

public homeId: number;
public ownNodeId: number;

public securityManagers: SecurityManagers = {};

public encodingContext: MessageEncodingContext;
Expand Down
3 changes: 1 addition & 2 deletions packages/testing/src/MockNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,15 +115,14 @@ export class MockNode {
// A node's host is a bit more specialized than the controller's host.
this.host = {
...this.controller.host,
ownNodeId: this.id,
__internalIsMockNode: true,
// // Mimic the behavior of ZWaveNode, but for arbitrary node IDs
};

const securityClasses = new Map<number, Map<SecurityClass, boolean>>();

this.encodingContext = {
homeId: this.controller.host.homeId,
homeId: this.controller.homeId,
ownNodeId: this.id,
hasSecurityClass(
nodeId: number,
Expand Down
1 change: 1 addition & 0 deletions packages/zwave-js/src/lib/controller/Controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5112,6 +5112,7 @@ export class ZWaveController
Message & SuccessIndicator
>(
new SetSUCNodeIdRequest(this.driver, {
ownNodeId: this.ownNodeId!,
sucNodeId: nodeId,
enableSUC,
enableSIS,
Expand Down
18 changes: 9 additions & 9 deletions packages/zwave-js/src/lib/controller/MockControllerBehaviors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ function createLazySendDataPayload(
return () => {
try {
const cmd = CommandClass.from(node.host, {
nodeId: controller.host.ownNodeId,
nodeId: controller.ownNodeId,
data: msg.payload,
origin: MessageOrigin.Host,
context: {
Expand All @@ -113,7 +113,7 @@ function createLazySendDataPayload(
// The whole CC is not implemented yet. If this happens in tests, it is because we sent a raw CC.
try {
const cmd = new CommandClass(host, {
nodeId: controller.host.ownNodeId,
nodeId: controller.ownNodeId,
ccId: msg.payload[0],
ccCommand: msg.payload[1],
payload: msg.payload.subarray(2),
Expand Down Expand Up @@ -145,8 +145,8 @@ const respondToGetControllerId: MockControllerBehavior = {
async onHostMessage(host, controller, msg) {
if (msg instanceof GetControllerIdRequest) {
const ret = new GetControllerIdResponse(host, {
homeId: host.homeId,
ownNodeId: host.ownNodeId,
homeId: controller.homeId,
ownNodeId: controller.ownNodeId,
});
await controller.sendMessageToHost(ret);
return true;
Expand Down Expand Up @@ -194,7 +194,7 @@ const respondToGetSUCNodeId: MockControllerBehavior = {
async onHostMessage(host, controller, msg) {
if (msg instanceof GetSUCNodeIdRequest) {
const sucNodeId = controller.capabilities.isStaticUpdateController
? host.ownNodeId
? controller.ownNodeId
: controller.capabilities.sucNodeId;
const ret = new GetSUCNodeIdResponse(host, {
sucNodeId,
Expand All @@ -209,7 +209,7 @@ const respondToGetSerialApiInitData: MockControllerBehavior = {
async onHostMessage(host, controller, msg) {
if (msg instanceof GetSerialApiInitDataRequest) {
const nodeIds = new Set(controller.nodes.keys());
nodeIds.add(host.ownNodeId);
nodeIds.add(controller.ownNodeId);

const ret = new GetSerialApiInitDataResponse(host, {
zwaveApiVersion: controller.capabilities.zwaveApiVersion,
Expand Down Expand Up @@ -248,7 +248,7 @@ const respondToSoftReset: MockControllerBehavior = {
const respondToGetNodeProtocolInfo: MockControllerBehavior = {
async onHostMessage(host, controller, msg) {
if (msg instanceof GetNodeProtocolInfoRequest) {
if (msg.requestedNodeId === host.ownNodeId) {
if (msg.requestedNodeId === controller.ownNodeId) {
const ret = new GetNodeProtocolInfoResponse(host, {
...determineNIF(),
nodeType: NodeType.Controller,
Expand Down Expand Up @@ -494,7 +494,7 @@ const handleRequestNodeInfo: MockControllerBehavior = {
const node = controller.nodes.get(msg.getNodeId()!)!;
const command = new ZWaveProtocolCCRequestNodeInformationFrame(
node.host,
{ nodeId: controller.host.ownNodeId },
{ nodeId: controller.ownNodeId },
);
const frame = createMockZWaveRequestFrame(command, {
ackRequested: false,
Expand Down Expand Up @@ -570,7 +570,7 @@ const handleAssignSUCReturnRoute: MockControllerBehavior = {
const node = controller.nodes.get(msg.getNodeId()!)!;
const command = new ZWaveProtocolCCAssignSUCReturnRoute(host, {
nodeId: node.id,
destinationNodeId: controller.host.ownNodeId,
destinationNodeId: controller.ownNodeId,
repeaters: [], // don't care
routeIndex: 0, // don't care
destinationSpeed: ZWaveDataRate["100k"],
Expand Down
Loading

0 comments on commit b3981fa

Please sign in to comment.