From baa9fe02e616cbd1b129e86f7870724ceb2d7a3e Mon Sep 17 00:00:00 2001 From: Greg Lauckhart Date: Fri, 8 Mar 2024 11:09:41 -0800 Subject: [PATCH 1/3] Change NetworkServer address configuration Now takes addresses as a list of listening address instead of one each of IPv4, IPv6 and BLE. Adds support for dual-mode (IPv4 + IPv6) sockets. Adds one dual-mode UDP listener on all addresses if none is configured. Adds one BLE listener if BLE is supported and "ble" option is not set to false. Throws an error if there are multiple BLE addresses or the HCI address is specified in the listener list (these require lower-level changes I did not make yet). I want to make similar changes for Mdns at some point but figured I'd see how these go over first. Includes some additional convenience methods for variable access. --- .../src/examples/DeviceNodeFull.ts | 4 +- .../DummyThreadNetworkCommissioningServer.ts | 2 +- .../matter-node.js/src/net/UdpChannelNode.ts | 6 +- .../behavior/system/network/NetworkRuntime.ts | 2 - .../behavior/system/network/NetworkServer.ts | 155 ++++++++++++++++-- .../system/network/ServerNetworkRuntime.ts | 146 ++++++++--------- .../src/environment/VariableService.ts | 87 +++++++++- packages/matter.js/src/net/UdpChannel.ts | 24 ++- packages/matter.js/src/net/UdpInterface.ts | 8 +- .../matter.js/src/net/fake/UdpChannelFake.ts | 2 +- 10 files changed, 334 insertions(+), 102 deletions(-) diff --git a/packages/matter-node.js-examples/src/examples/DeviceNodeFull.ts b/packages/matter-node.js-examples/src/examples/DeviceNodeFull.ts index ca1392626..5488daa18 100644 --- a/packages/matter-node.js-examples/src/examples/DeviceNodeFull.ts +++ b/packages/matter-node.js-examples/src/examples/DeviceNodeFull.ts @@ -41,7 +41,7 @@ import { Endpoint, EndpointServer } from "@project-chip/matter.js/endpoint"; import { RootRequirements } from "@project-chip/matter.js/endpoint/definitions"; import { Environment, StorageService } from "@project-chip/matter.js/environment"; import { FabricAction } from "@project-chip/matter.js/fabric"; -import { Level, Logger, levelFromString } from "@project-chip/matter.js/log"; +import { Logger, levelFromString } from "@project-chip/matter.js/log"; import { ServerNode } from "@project-chip/matter.js/node"; import { QrCode } from "@project-chip/matter.js/schema"; import { Time } from "@project-chip/matter.js/time"; @@ -103,7 +103,7 @@ function executeCommand(scriptParamName: string) { const logFile = environment.vars.string("logfile.filename"); if (logFile !== undefined) { Logger.addLogger("filelogger", await createFileLogger(logFile), { - defaultLogLevel: levelFromString(environment.vars.string("logfile.loglevel")) ?? Level.DEBUG, + defaultLogLevel: levelFromString(environment.vars.string("logfile.loglevel", "debug")), }); } diff --git a/packages/matter-node.js-examples/src/examples/cluster/DummyThreadNetworkCommissioningServer.ts b/packages/matter-node.js-examples/src/examples/cluster/DummyThreadNetworkCommissioningServer.ts index 7ec0ed0e8..281f5ddf9 100644 --- a/packages/matter-node.js-examples/src/examples/cluster/DummyThreadNetworkCommissioningServer.ts +++ b/packages/matter-node.js-examples/src/examples/cluster/DummyThreadNetworkCommissioningServer.ts @@ -43,7 +43,7 @@ export class DummyThreadNetworkCommissioningServer extends NetworkCommissioningB const threadScanResults = [ { panId: this.endpoint.env.vars.number("ble.thread.panId"), - extendedPanId: BigInt(this.endpoint.env.vars.string("ble.thread.extendedPanId")), + extendedPanId: this.endpoint.env.vars.bigint("ble.thread.extendedPanId"), networkName: this.endpoint.env.vars.string("ble.thread.networkName"), channel: this.endpoint.env.vars.number("ble.thread.channel"), version: 130, diff --git a/packages/matter-node.js/src/net/UdpChannelNode.ts b/packages/matter-node.js/src/net/UdpChannelNode.ts index ca9aee349..78afbbaa7 100644 --- a/packages/matter-node.js/src/net/UdpChannelNode.ts +++ b/packages/matter-node.js/src/net/UdpChannelNode.ts @@ -47,11 +47,15 @@ export class UdpChannelNode implements UdpChannel { listeningAddress, netInterface, membershipAddresses, + reuseAddress, }: UdpChannelOptions) { - const socketOptions: dgram.SocketOptions = { type, reuseAddr: true }; + const socketOptions: dgram.SocketOptions = { type: type === "udp" ? "udp6" : type }; if (type === "udp6") { socketOptions.ipv6Only = true; } + if (reuseAddress) { + socketOptions.reuseAddr = true; + } const socket = await createDgramSocket(listeningAddress, listeningPort, socketOptions); socket.setBroadcast(true); let netInterfaceZone: string | undefined; diff --git a/packages/matter.js/src/behavior/system/network/NetworkRuntime.ts b/packages/matter.js/src/behavior/system/network/NetworkRuntime.ts index ed0c4f1ee..909511038 100644 --- a/packages/matter.js/src/behavior/system/network/NetworkRuntime.ts +++ b/packages/matter.js/src/behavior/system/network/NetworkRuntime.ts @@ -62,8 +62,6 @@ export abstract class NetworkRuntime { } } - abstract operationalPort: number; - protected abstract start(): Promise; protected abstract stop(): Promise; diff --git a/packages/matter.js/src/behavior/system/network/NetworkServer.ts b/packages/matter.js/src/behavior/system/network/NetworkServer.ts index 75a858bc6..bb84a7569 100644 --- a/packages/matter.js/src/behavior/system/network/NetworkServer.ts +++ b/packages/matter.js/src/behavior/system/network/NetworkServer.ts @@ -5,7 +5,7 @@ */ import { Ble } from "../../../ble/Ble.js"; -import { ImplementationError } from "../../../common/MatterError.js"; +import { ImplementationError, NotImplementedError } from "../../../common/MatterError.js"; import { Logger } from "../../../log/Logger.js"; import { SubscriptionOptions } from "../../../protocol/interaction/SubscriptionOptions.js"; import { TypeFromPartialBitSchema } from "../../../schema/BitmapSchema.js"; @@ -27,13 +27,11 @@ export class NetworkServer extends NetworkBehavior { declare internal: NetworkServer.Internal; override initialize() { - if (this.state.ble === undefined) { - // TODO make working again when State init gets fixed! - this.state.ble = Ble.enabled; - } else if (this.state.ble && !Ble.enabled) { - logger.warn("Disabling Bluetooth commissioning because BLE support is not installed"); - this.state.ble = false; - } + const vars = this.endpoint.env.vars; + + this.state.port = vars.number("network.port", this.state.port); + + this.state.listen = this.#configureListeners(vars.list("network.listen", this.state.listen)); const discoveryCaps = this.state.discoveryCapabilities; switch (discoveryCaps.ble) { @@ -101,21 +99,156 @@ export class NetworkServer extends NetworkBehavior { this.internal.runtime.endUncommissionedMode(); } } + + #configureListeners(config: unknown[]) { + const listen = Array(); + let hasUdp = false; + let hasBle = false; + let disabledBle = false; + for (const addr of config) { + if (typeof addr !== "object") { + throw new ImplementationError("Listen address is not an object"); + } + + let { protocol, port } = addr as Record; + const { address } = addr as Record; + + if (protocol === undefined) { + protocol = "udp"; + } + + switch (protocol) { + case "ble": + if (Ble.enabled) { + if (hasBle) { + throw new NotImplementedError("Currently only a single BLE transport is allowed"); + } else { + hasBle = true; + } + if (address !== undefined) { + throw new NotImplementedError("Currently you may not specify HCI ID for BLE transport"); + } + listen.push({ protocol, address }); + this.state.ble = true; + } else { + disabledBle = true; + } + break; + + case "udp": + case "udp4": + case "udp6": + hasUdp = true; + if (port === undefined) { + port = this.state.port; + } + listen.push({ protocol, address, port }); + break; + + default: + throw new ImplementationError(`Unknown listen protocol "${protocol}"`); + } + } + + if (disabledBle) { + logger.warn("Disabling Bluetooth commissioning because BLE support is not installed"); + this.state.ble = false; + } else if (this.state.ble !== false && Ble.enabled) { + if (!hasBle) { + listen.push({ protocol: "ble" }); + } + this.state.ble = true; + } + + if (!hasUdp) { + listen.push({ protocol: "udp", port: this.state.port }); + } + + return listen; + } } export namespace NetworkServer { + /** + * A UDP listening address. + */ + export interface UdpAddress { + protocol: "udp" | "udp4" | "udp6"; + + /** + * The hostname or IP address. Leave undefined for all addresses, "0.0.0.0" for all IPv4 addresses, and "::" + * for all IPv6 addresses. + */ + address?: string; + + /** + * The port to listen on. Defaults to {@link State.port}. + */ + port?: number; + } + + /** + * A Bluetooth LE listening address, + * + * TODO - currently only a single BLE transport is supported + */ + export interface BleAddress { + protocol: "ble"; + + /** + * The HCI ID of the bluetooth adapter. + * + * By default selects the first adapter on the system. + * + * TODO - currently you cannot specify HCI ID here + */ + address?: string; + } + + export type Address = BleAddress | UdpAddress; + export class Internal extends NetworkBehavior.Internal { declare runtime: ServerNetworkRuntime; } export class State extends NetworkBehavior.State { - listeningAddressIpv4?: string = undefined; - listeningAddressIpv6?: string = undefined; - ipv4 = true; + /** + * An array of {@link Address} objects configuring the interfaces the server listens on. + * + * Configurable also with variable "network.listen". You may configure a single listener using: + * + * * `network.listen.protocol` either "ble", "udp4", "udp6" or "udp" (default is "udp" for dual IPv4/6) + * * `network.listen.address` the hostname, IP address (default all) or HCI ID (default first) to listen on + * * `network.listen.port` the port for UDP listeners (default is 5540) + * + * You may configure multiple listeners using `network.listen.0`, `network.listen.1`, etc. with the same subkeys + * as above. + * + * At least one UDP listener is required. The server will add one if none are present. + * + * If {@link ble} is true, the server will add a BLE listener as well if none are present and Matter.js supports + * BLE on the current platform. + */ + listen = Array
(); + + /** + * Controls whether BLE is added to the default configuration. If undefined, BLE is enabled if present on the + * system. + * + * Once the server starts this value reflects the current state of BLE for the node. + */ ble?: boolean = undefined; + + /** + * The Matter capabilities the server broadcasts. + */ discoveryCapabilities: TypeFromPartialBitSchema = { onIpNetwork: true, }; + + /** + * Time intervales for subscription configuration. + */ subscriptionOptions?: SubscriptionOptions = undefined; } } diff --git a/packages/matter.js/src/behavior/system/network/ServerNetworkRuntime.ts b/packages/matter.js/src/behavior/system/network/ServerNetworkRuntime.ts index a02f23ce9..c25fe8274 100644 --- a/packages/matter.js/src/behavior/system/network/ServerNetworkRuntime.ts +++ b/packages/matter.js/src/behavior/system/network/ServerNetworkRuntime.ts @@ -32,9 +32,9 @@ export class ServerNetworkRuntime extends NetworkRuntime { #interactionServer?: TransactionalInteractionServer; #matterDevice?: MatterDevice; #mdnsBroadcaster?: MdnsInstanceBroadcaster; - #primaryNetInterface?: UdpInterface; + #transports?: Set; + #bleTransports?: Set; #bleBroadcaster?: InstanceBroadcaster; - #bleTransport?: TransportInterface; #commissionedListener?: () => void; override get owner() { @@ -81,22 +81,56 @@ export class ServerNetworkRuntime extends NetworkRuntime { } /** - * The IPv6 {@link UdpInterface}. We create this interface independently of the server so the OS can select a port - * before we are fully online. + * The {@link UdpInterface} instances we listen on. We create these independently of the server so the OS can + * select a port before we are fully online. */ - protected async getPrimaryNetInterface() { - if (this.#primaryNetInterface === undefined) { - const port = this.owner.state.network.port; - this.#primaryNetInterface = await UdpInterface.create( - this.owner.env.get(Network), - "udp6", - port ? port : undefined, - this.owner.state.network.listeningAddressIpv6, - ); - - await this.owner.set({ network: { operationalPort: this.#primaryNetInterface.port } }); + protected async getTransports() { + if (this.#transports !== undefined) { + return this.#transports; } - return this.#primaryNetInterface; + + const transports = new Set(); + const bleTransports = new Set(); + + for (const address of this.owner.state.network.listen) { + switch (address.protocol) { + case "udp": + case "udp4": + case "udp6": + const udp = await UdpInterface.create( + this.owner.env.get(Network), + address.protocol, + address.port, + address.address, + ); + + transports.add(udp); + + // We advertise the first (most likely only) UDP port we open as our official address + await this.owner.act(agent => { + const state = agent.network.state; + if (state.operationalPort === -1) { + state.operationalPort = udp.port; + } + }); + + break; + + case "ble": + // TODO - HCI ID and/or multiple BLE transports? (Former seems valuable, latter not really but + // would include for completeness) + const ble = Ble.get().getBlePeripheralInterface(); + transports.add(ble); + bleTransports.add(ble); + break; + } + } + + // AFAICT no way to query transport interface for protocol type so just store BLE transports separately so we + // can identify them for removal after commissioning completes + this.#bleTransports = bleTransports; + + return (this.#transports = transports); } /** @@ -110,40 +144,6 @@ export class ServerNetworkRuntime extends NetworkRuntime { return this.#bleBroadcaster; } - /** - * A BLE transport. - */ - protected get bleTransport() { - if (this.#bleTransport === undefined) { - this.#bleTransport = Ble.get().getBlePeripheralInterface(); - } - return this.#bleTransport; - } - - /** - * Add transports to the {@link MatterDevice}. - */ - protected async addTransports(device: MatterDevice) { - device.addTransportInterface(await this.getPrimaryNetInterface()); - - const netconf = this.owner.state.network; - - if (netconf.ipv4) { - device.addTransportInterface( - await UdpInterface.create( - this.owner.env.get(Network), - "udp4", - netconf.port, - netconf.listeningAddressIpv4, - ), - ); - } - - if (netconf.ble) { - device.addTransportInterface(this.bleTransport); - } - } - /** * Add broadcasters to the {@link MatterDevice}. */ @@ -187,20 +187,23 @@ export class ServerNetworkRuntime extends NetworkRuntime { this.#bleBroadcaster = undefined; } - if (this.#bleTransport) { - this.owner.env.runtime.add(this.#removeBleTransport(this.#bleTransport)); - this.#bleTransport = undefined; + if (this.#bleTransports) { + for (const ble of this.#bleTransports) { + this.owner.env.runtime.add(this.#removeBleTransport(ble)); + } } } - async #removeBleBroadcaster(bleBroadcaster: InstanceBroadcaster) { - await this.#matterDevice?.deleteBroadcaster(bleBroadcaster); - await bleBroadcaster.close(); + async #removeBleBroadcaster(broadcaster: InstanceBroadcaster) { + await this.#matterDevice?.deleteBroadcaster(broadcaster); + await broadcaster.close(); } - async #removeBleTransport(bleTransport: TransportInterface) { - await this.#matterDevice?.deleteTransportInterface(bleTransport); - await bleTransport.close(); + async #removeBleTransport(transport: TransportInterface) { + this.#transports?.delete(transport); + this.#bleTransports?.delete(transport); + await this.#matterDevice?.deleteTransportInterface(transport); + await transport.close(); } /** @@ -217,10 +220,6 @@ export class ServerNetworkRuntime extends NetworkRuntime { return this.owner.state.operationalCredentials.commissionedFabrics; } - override get operationalPort() { - return this.#primaryNetInterface?.port ?? 0; - } - async endCommissioning() { if (this.#matterDevice !== undefined) { return this.#matterDevice.endCommissioning(); @@ -266,10 +265,11 @@ export class ServerNetworkRuntime extends NetworkRuntime { await this.owner.act(agent => agent.load(SessionsBehavior)); this.owner.eventsOf(CommissioningBehavior).commissioned.on(() => this.endUncommissionedMode()); - await this.addTransports(this.#matterDevice); - await this.addBroadcasters(this.#matterDevice); + for (const transport of await this.getTransports()) { + this.#matterDevice.addTransportInterface(transport); + } - await this.owner.set({ network: { operationalPort: this.operationalPort } }); + await this.addBroadcasters(this.#matterDevice); await this.openAdvertisementWindow(); } @@ -282,13 +282,13 @@ export class ServerNetworkRuntime extends NetworkRuntime { await this.#matterDevice.close(); this.#matterDevice = undefined; - this.#primaryNetInterface = undefined; - } - - if (this.#primaryNetInterface) { - // If we created the net interface but not the device we need to dispose ourselves - await this.#primaryNetInterface.close(); - this.#primaryNetInterface = undefined; + this.#transports = undefined; + } else if (this.#transports) { + // We created the transports but not the device; so we need to dispose ourselves + for (const transport of this.#transports) { + await transport.close(); + } + this.#transports = undefined; } await this.#interactionServer?.[Symbol.asyncDispose](); diff --git a/packages/matter.js/src/environment/VariableService.ts b/packages/matter.js/src/environment/VariableService.ts index 4d4d18891..db7abf6b5 100644 --- a/packages/matter.js/src/environment/VariableService.ts +++ b/packages/matter.js/src/environment/VariableService.ts @@ -38,13 +38,13 @@ export class VariableService { get(name: string, fallback?: VariableService.Value) { switch (typeof fallback) { case "string": - return this.string(name) ?? fallback; + return this.string(name, fallback); case "number": - return this.number(name) ?? fallback; + return this.number(name, fallback); case "boolean": - return this.boolean(name) ?? fallback; + return this.boolean(name, fallback); } let value: VariableService.Value = this.#vars; @@ -77,10 +77,14 @@ export class VariableService { parent[key] = value; } - string(name: string) { + string(name: string): string | undefined; + + string(name: string, fallback: string): string; + + string(name: string, fallback?: string) { const value = this.get(name); if (value === undefined) { - return value; + return fallback; } if (typeof value === "string") { return value; @@ -91,11 +95,15 @@ export class VariableService { return value.toString(); } - boolean(name: string) { + boolean(name: string): boolean | undefined; + + boolean(name: string, fallback: boolean): boolean; + + boolean(name: string, fallback?: boolean) { const value = this.get(name); switch (value) { case undefined: - return value; + return fallback; case null: case 0: @@ -109,7 +117,11 @@ export class VariableService { } } - number(name: string) { + number(name: string): number | undefined; + + number(name: string, fallback: number): number; + + number(name: string, fallback?: number) { let value = this.get(name); if (typeof value === "number") { return value; @@ -117,12 +129,35 @@ export class VariableService { if (typeof value === "string") { value = Number.parseFloat(value); if (Number.isNaN(value)) { - return; + return fallback; } return value; } + return fallback; + } + + bigint(name: string): bigint | undefined; + + bigint(name: string, fallback: bigint): bigint; + + bigint(name: string, fallback?: bigint) { + const value = this.get(name); + + if (typeof value === "bigint") { + return value; + } + + if (typeof value === "number" || typeof value === "string") { + return BigInt(value); + } + + return fallback; } + integer(name: string): number | undefined; + + integer(name: string, fallback: number): number; + integer(name: string, fallback?: number) { const number = this.number(name) ?? fallback; if (typeof number === "number") { @@ -130,6 +165,40 @@ export class VariableService { } } + list(name: string): unknown[] | undefined; + + list(name: string, fallback: unknown[]): unknown[]; + + list(name: string, fallback?: unknown[]): unknown[] | undefined { + const value = this.get(name); + if (value === undefined || value === null) { + return fallback; + } + + if (Array.isArray(value)) { + return value; + } + + if (typeof value === "object") { + const keys = Object.keys(value); + if (!keys.length) { + return fallback; + } + + let isArrayLike = true; + for (const key of keys) { + if (!key.match(/^[0-9]+$/)) { + isArrayLike = false; + } + } + if (isArrayLike) { + return Object.values(value); + } + } + + return [value]; + } + increment(name: string) { const value = this.integer(name) ?? 0; this.set(name, value + 1); diff --git a/packages/matter.js/src/net/UdpChannel.ts b/packages/matter.js/src/net/UdpChannel.ts index 4f98fa49b..c18bc4dcd 100644 --- a/packages/matter.js/src/net/UdpChannel.ts +++ b/packages/matter.js/src/net/UdpChannel.ts @@ -8,10 +8,32 @@ import { Listener } from "../common/TransportInterface.js"; import { ByteArray } from "../util/ByteArray.js"; export interface UdpChannelOptions { + /** + * UDP channel type. "udp4" and "udp6" mean IPv4 and IPv6 respectively. "udp" is dual-mode IPv4/IPv6. + * {@link listeningAddress} in this case must be undefined or "::". + */ + type: "udp" | "udp4" | "udp6"; + + /** + * The port to listen on. undefined or 0 directs the operating system to select an open port. + */ listeningPort?: number; - type: "udp4" | "udp6"; + + /** + * The address to listen on, either a hostname or IP address in correct format based on {@link type}. + */ listeningAddress?: string; + + /** + * If true the socket is opened non-exclusively. + */ + reuseAddress?: boolean; + + /** + * The network interface, required for multicast. + */ netInterface?: string; + membershipAddresses?: string[]; } diff --git a/packages/matter.js/src/net/UdpInterface.ts b/packages/matter.js/src/net/UdpInterface.ts index ce26b19c9..f150b6008 100644 --- a/packages/matter.js/src/net/UdpInterface.ts +++ b/packages/matter.js/src/net/UdpInterface.ts @@ -13,7 +13,13 @@ import { Network, NetworkError } from "./Network.js"; import { UdpChannel } from "./UdpChannel.js"; export class UdpInterface implements NetInterface { - static async create(network: Network, type: "udp4" | "udp6", port?: number, host?: string, netInterface?: string) { + static async create( + network: Network, + type: "udp" | "udp4" | "udp6", + port?: number, + host?: string, + netInterface?: string, + ) { return new UdpInterface( await network.createUdpChannel({ listeningPort: port, type, netInterface, listeningAddress: host }), ); diff --git a/packages/matter.js/src/net/fake/UdpChannelFake.ts b/packages/matter.js/src/net/fake/UdpChannelFake.ts index bf83609a3..eea1ca1ef 100644 --- a/packages/matter.js/src/net/fake/UdpChannelFake.ts +++ b/packages/matter.js/src/net/fake/UdpChannelFake.ts @@ -35,7 +35,7 @@ export class UdpChannelFake implements UdpChannel { private readonly listeningAddress: string | undefined, listeningPort?: number, ) { - this.listeningPort = listeningPort ?? 1024 + Math.floor(Math.random() * 64511); // Random port 1024-65535 + this.listeningPort = listeningPort ? listeningPort : 1024 + Math.floor(Math.random() * 64511); // Random port 1024-65535 } onData(listener: (netInterface: string, peerAddress: string, peerPort: number, data: ByteArray) => void) { From 38c2dce97f3a59ae73a1d7d01f34c86aed593979 Mon Sep 17 00:00:00 2001 From: Greg Lauckhart Date: Fri, 8 Mar 2024 12:08:30 -0800 Subject: [PATCH 2/3] Forgot to turn reuseAddress on for multicast --- packages/matter.js/src/net/UdpMulticastServer.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/matter.js/src/net/UdpMulticastServer.ts b/packages/matter.js/src/net/UdpMulticastServer.ts index 60eccb711..e113d4f51 100644 --- a/packages/matter.js/src/net/UdpMulticastServer.ts +++ b/packages/matter.js/src/net/UdpMulticastServer.ts @@ -41,12 +41,14 @@ export class UdpMulticastServer { netInterface, listeningPort, membershipAddresses: [broadcastAddressIpv4], + reuseAddress: true, }), await network.createUdpChannel({ type: "udp6", netInterface, listeningPort, membershipAddresses: [broadcastAddressIpv6], + reuseAddress: true, }), netInterface, ); @@ -122,6 +124,7 @@ export class UdpMulticastServer { type: iPv4 ? "udp4" : "udp6", listeningPort: this.broadcastPort, netInterface, + reuseAddress: true, }); } From 77f6516eef369d804f3e0625ed6c1e37dbb939a2 Mon Sep 17 00:00:00 2001 From: Greg Lauckhart Date: Sat, 9 Mar 2024 11:31:13 -0800 Subject: [PATCH 3/3] "protocol" -> "transport" per CR --- .../behavior/system/network/NetworkServer.ts | 26 +++++++++---------- .../system/network/ServerNetworkRuntime.ts | 4 +-- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/packages/matter.js/src/behavior/system/network/NetworkServer.ts b/packages/matter.js/src/behavior/system/network/NetworkServer.ts index bb84a7569..00cae6105 100644 --- a/packages/matter.js/src/behavior/system/network/NetworkServer.ts +++ b/packages/matter.js/src/behavior/system/network/NetworkServer.ts @@ -110,14 +110,14 @@ export class NetworkServer extends NetworkBehavior { throw new ImplementationError("Listen address is not an object"); } - let { protocol, port } = addr as Record; + let { transport, port } = addr as Record; const { address } = addr as Record; - if (protocol === undefined) { - protocol = "udp"; + if (transport === undefined) { + transport = "udp"; } - switch (protocol) { + switch (transport) { case "ble": if (Ble.enabled) { if (hasBle) { @@ -126,9 +126,9 @@ export class NetworkServer extends NetworkBehavior { hasBle = true; } if (address !== undefined) { - throw new NotImplementedError("Currently you may not specify HCI ID for BLE transport"); + throw new NotImplementedError("Currently you may not specify the BLE transport address"); } - listen.push({ protocol, address }); + listen.push({ transport: transport, address }); this.state.ble = true; } else { disabledBle = true; @@ -142,11 +142,11 @@ export class NetworkServer extends NetworkBehavior { if (port === undefined) { port = this.state.port; } - listen.push({ protocol, address, port }); + listen.push({ transport: transport, address, port }); break; default: - throw new ImplementationError(`Unknown listen protocol "${protocol}"`); + throw new ImplementationError(`Unknown listen protocol "${transport}"`); } } @@ -155,13 +155,13 @@ export class NetworkServer extends NetworkBehavior { this.state.ble = false; } else if (this.state.ble !== false && Ble.enabled) { if (!hasBle) { - listen.push({ protocol: "ble" }); + listen.push({ transport: "ble" }); } this.state.ble = true; } if (!hasUdp) { - listen.push({ protocol: "udp", port: this.state.port }); + listen.push({ transport: "udp", port: this.state.port }); } return listen; @@ -173,7 +173,7 @@ export namespace NetworkServer { * A UDP listening address. */ export interface UdpAddress { - protocol: "udp" | "udp4" | "udp6"; + transport: "udp" | "udp4" | "udp6"; /** * The hostname or IP address. Leave undefined for all addresses, "0.0.0.0" for all IPv4 addresses, and "::" @@ -193,7 +193,7 @@ export namespace NetworkServer { * TODO - currently only a single BLE transport is supported */ export interface BleAddress { - protocol: "ble"; + transport: "ble"; /** * The HCI ID of the bluetooth adapter. @@ -217,7 +217,7 @@ export namespace NetworkServer { * * Configurable also with variable "network.listen". You may configure a single listener using: * - * * `network.listen.protocol` either "ble", "udp4", "udp6" or "udp" (default is "udp" for dual IPv4/6) + * * `network.listen.transport` either "ble", "udp4", "udp6" or "udp" (default is "udp" for dual IPv4/6) * * `network.listen.address` the hostname, IP address (default all) or HCI ID (default first) to listen on * * `network.listen.port` the port for UDP listeners (default is 5540) * diff --git a/packages/matter.js/src/behavior/system/network/ServerNetworkRuntime.ts b/packages/matter.js/src/behavior/system/network/ServerNetworkRuntime.ts index c25fe8274..80cdf2102 100644 --- a/packages/matter.js/src/behavior/system/network/ServerNetworkRuntime.ts +++ b/packages/matter.js/src/behavior/system/network/ServerNetworkRuntime.ts @@ -93,13 +93,13 @@ export class ServerNetworkRuntime extends NetworkRuntime { const bleTransports = new Set(); for (const address of this.owner.state.network.listen) { - switch (address.protocol) { + switch (address.transport) { case "udp": case "udp4": case "udp6": const udp = await UdpInterface.create( this.owner.env.get(Network), - address.protocol, + address.transport, address.port, address.address, );