@matter/nodejs-ble 0.11.0-alpha.0-20241005-e3e4e4a7a

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +55 -0
  3. package/dist/cjs/BleBroadcaster.d.ts +20 -0
  4. package/dist/cjs/BleBroadcaster.d.ts.map +1 -0
  5. package/dist/cjs/BleBroadcaster.js +121 -0
  6. package/dist/cjs/BleBroadcaster.js.map +6 -0
  7. package/dist/cjs/BlePeripheralInterface.d.ts +15 -0
  8. package/dist/cjs/BlePeripheralInterface.d.ts.map +1 -0
  9. package/dist/cjs/BlePeripheralInterface.js +54 -0
  10. package/dist/cjs/BlePeripheralInterface.js.map +6 -0
  11. package/dist/cjs/BleScanner.d.ts +52 -0
  12. package/dist/cjs/BleScanner.d.ts.map +1 -0
  13. package/dist/cjs/BleScanner.js +240 -0
  14. package/dist/cjs/BleScanner.js.map +6 -0
  15. package/dist/cjs/BlenoBleServer.d.ts +70 -0
  16. package/dist/cjs/BlenoBleServer.d.ts.map +1 -0
  17. package/dist/cjs/BlenoBleServer.js +337 -0
  18. package/dist/cjs/BlenoBleServer.js.map +6 -0
  19. package/dist/cjs/NobleBleChannel.d.ts +32 -0
  20. package/dist/cjs/NobleBleChannel.d.ts.map +1 -0
  21. package/dist/cjs/NobleBleChannel.js +266 -0
  22. package/dist/cjs/NobleBleChannel.js.map +6 -0
  23. package/dist/cjs/NobleBleClient.d.ts +20 -0
  24. package/dist/cjs/NobleBleClient.d.ts.map +1 -0
  25. package/dist/cjs/NobleBleClient.js +108 -0
  26. package/dist/cjs/NobleBleClient.js.map +6 -0
  27. package/dist/cjs/NodeJsBle.d.ts +22 -0
  28. package/dist/cjs/NodeJsBle.d.ts.map +1 -0
  29. package/dist/cjs/NodeJsBle.js +68 -0
  30. package/dist/cjs/NodeJsBle.js.map +6 -0
  31. package/dist/cjs/index.d.ts +9 -0
  32. package/dist/cjs/index.d.ts.map +1 -0
  33. package/dist/cjs/index.js +26 -0
  34. package/dist/cjs/index.js.map +6 -0
  35. package/dist/cjs/package.json +3 -0
  36. package/dist/cjs/tsconfig.tsbuildinfo +1 -0
  37. package/dist/esm/BleBroadcaster.d.ts +20 -0
  38. package/dist/esm/BleBroadcaster.d.ts.map +1 -0
  39. package/dist/esm/BleBroadcaster.js +101 -0
  40. package/dist/esm/BleBroadcaster.js.map +6 -0
  41. package/dist/esm/BlePeripheralInterface.d.ts +15 -0
  42. package/dist/esm/BlePeripheralInterface.d.ts.map +1 -0
  43. package/dist/esm/BlePeripheralInterface.js +34 -0
  44. package/dist/esm/BlePeripheralInterface.js.map +6 -0
  45. package/dist/esm/BleScanner.d.ts +52 -0
  46. package/dist/esm/BleScanner.d.ts.map +1 -0
  47. package/dist/esm/BleScanner.js +220 -0
  48. package/dist/esm/BleScanner.js.map +6 -0
  49. package/dist/esm/BlenoBleServer.d.ts +70 -0
  50. package/dist/esm/BlenoBleServer.d.ts.map +1 -0
  51. package/dist/esm/BlenoBleServer.js +327 -0
  52. package/dist/esm/BlenoBleServer.js.map +6 -0
  53. package/dist/esm/NobleBleChannel.d.ts +32 -0
  54. package/dist/esm/NobleBleChannel.d.ts.map +1 -0
  55. package/dist/esm/NobleBleChannel.js +266 -0
  56. package/dist/esm/NobleBleChannel.js.map +6 -0
  57. package/dist/esm/NobleBleClient.d.ts +20 -0
  58. package/dist/esm/NobleBleClient.d.ts.map +1 -0
  59. package/dist/esm/NobleBleClient.js +88 -0
  60. package/dist/esm/NobleBleClient.js.map +6 -0
  61. package/dist/esm/NodeJsBle.d.ts +22 -0
  62. package/dist/esm/NodeJsBle.d.ts.map +1 -0
  63. package/dist/esm/NodeJsBle.js +48 -0
  64. package/dist/esm/NodeJsBle.js.map +6 -0
  65. package/dist/esm/index.d.ts +9 -0
  66. package/dist/esm/index.d.ts.map +1 -0
  67. package/dist/esm/index.js +9 -0
  68. package/dist/esm/index.js.map +6 -0
  69. package/dist/esm/package.json +3 -0
  70. package/dist/esm/tsconfig.tsbuildinfo +1 -0
  71. package/package.json +83 -0
  72. package/require/package.json +4 -0
  73. package/require/require.cjs +1 -0
  74. package/require/require.d.ts +1 -0
  75. package/require/require.mjs +3 -0
  76. package/src/BleBroadcaster.ts +126 -0
  77. package/src/BlePeripheralInterface.ts +36 -0
  78. package/src/BleScanner.ts +279 -0
  79. package/src/BlenoBleServer.ts +403 -0
  80. package/src/NobleBleChannel.ts +337 -0
  81. package/src/NobleBleClient.ts +117 -0
  82. package/src/NodeJsBle.ts +56 -0
  83. package/src/index.ts +9 -0
  84. package/src/tsconfig.json +16 -0
@@ -0,0 +1,240 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var BleScanner_exports = {};
20
+ __export(BleScanner_exports, {
21
+ BleScanner: () => BleScanner
22
+ });
23
+ module.exports = __toCommonJS(BleScanner_exports);
24
+ var import_general = require("@matter/general");
25
+ var import_ble = require("@project-chip/matter.js/ble");
26
+ var import_codec = require("@project-chip/matter.js/codec");
27
+ var import_datatype = require("@project-chip/matter.js/datatype");
28
+ /**
29
+ * @license
30
+ * Copyright 2022-2024 Matter.js Authors
31
+ * SPDX-License-Identifier: Apache-2.0
32
+ */
33
+ const logger = import_general.Logger.get("BleScanner");
34
+ class BleScanner {
35
+ constructor(nobleClient) {
36
+ this.nobleClient = nobleClient;
37
+ this.nobleClient.setDiscoveryCallback(
38
+ (address, manufacturerData) => this.handleDiscoveredDevice(address, manufacturerData)
39
+ );
40
+ }
41
+ get type() {
42
+ return import_general.ChannelType.BLE;
43
+ }
44
+ recordWaiters = /* @__PURE__ */ new Map();
45
+ discoveredMatterDevices = /* @__PURE__ */ new Map();
46
+ getDiscoveredDevice(address) {
47
+ const device = this.discoveredMatterDevices.get(address);
48
+ if (device === void 0) {
49
+ throw new import_ble.BleError(`No device found for address ${address}`);
50
+ }
51
+ return device;
52
+ }
53
+ /**
54
+ * Registers a deferred promise for a specific queryId together with a timeout and return the promise.
55
+ * The promise will be resolved when the timer runs out latest.
56
+ */
57
+ async registerWaiterPromise(queryId, timeoutSeconds, resolveOnUpdatedRecords = true) {
58
+ const { promise, resolver } = (0, import_general.createPromise)();
59
+ const timer = import_general.Time.getTimer(
60
+ "BLE query timeout",
61
+ timeoutSeconds * 1e3,
62
+ () => this.finishWaiter(queryId, true)
63
+ ).start();
64
+ this.recordWaiters.set(queryId, { resolver, timer, resolveOnUpdatedRecords });
65
+ logger.debug(
66
+ `Registered waiter for query ${queryId} with timeout ${timeoutSeconds} seconds${resolveOnUpdatedRecords ? "" : " (not resolving on updated records)"}`
67
+ );
68
+ await promise;
69
+ }
70
+ /**
71
+ * Remove a waiter promise for a specific queryId and stop the connected timer. If required also resolve the
72
+ * promise.
73
+ */
74
+ finishWaiter(queryId, resolvePromise, isUpdatedRecord = false) {
75
+ const waiter = this.recordWaiters.get(queryId);
76
+ if (waiter === void 0) return;
77
+ const { timer, resolver, resolveOnUpdatedRecords } = waiter;
78
+ if (isUpdatedRecord && !resolveOnUpdatedRecords) return;
79
+ logger.debug(`Finishing waiter for query ${queryId}, resolving: ${resolvePromise}`);
80
+ timer.stop();
81
+ if (resolvePromise) {
82
+ resolver();
83
+ }
84
+ this.recordWaiters.delete(queryId);
85
+ }
86
+ cancelCommissionableDeviceDiscovery(identifier) {
87
+ const queryKey = this.buildCommissionableQueryIdentifier(identifier);
88
+ this.finishWaiter(queryKey, true);
89
+ }
90
+ handleDiscoveredDevice(peripheral, manufacturerServiceData) {
91
+ logger.debug(
92
+ `Discovered device ${peripheral.address} ${manufacturerServiceData === void 0 ? void 0 : import_general.Bytes.toHex(manufacturerServiceData)}`
93
+ );
94
+ try {
95
+ const { discriminator, vendorId, productId, hasAdditionalAdvertisementData } = import_codec.BtpCodec.decodeBleAdvertisementServiceData(manufacturerServiceData);
96
+ const commissionableDevice = {
97
+ deviceIdentifier: peripheral.address,
98
+ D: discriminator,
99
+ SD: discriminator >> 8 & 15,
100
+ VP: `${vendorId}+${productId}`,
101
+ CM: 1,
102
+ // Can be no other mode,
103
+ addresses: [{ type: "ble", peripheralAddress: peripheral.address }]
104
+ };
105
+ logger.debug(`Discovered device ${peripheral.address} data: ${import_general.Logger.toJSON(commissionableDevice)}`);
106
+ const deviceExisting = this.discoveredMatterDevices.has(peripheral.address);
107
+ this.discoveredMatterDevices.set(peripheral.address, {
108
+ deviceData: commissionableDevice,
109
+ peripheral,
110
+ hasAdditionalAdvertisementData
111
+ });
112
+ const queryKey = this.findCommissionableQueryIdentifier(commissionableDevice);
113
+ if (queryKey !== void 0) {
114
+ this.finishWaiter(queryKey, true, deviceExisting);
115
+ }
116
+ } catch (error) {
117
+ logger.debug(`Seems not to be a valid Matter device: Failed to decode device data: ${error}`);
118
+ }
119
+ }
120
+ findCommissionableQueryIdentifier(record) {
121
+ const longDiscriminatorQueryId = this.buildCommissionableQueryIdentifier({ longDiscriminator: record.D });
122
+ if (this.recordWaiters.has(longDiscriminatorQueryId)) {
123
+ return longDiscriminatorQueryId;
124
+ }
125
+ const shortDiscriminatorQueryId = this.buildCommissionableQueryIdentifier({ shortDiscriminator: record.SD });
126
+ if (this.recordWaiters.has(shortDiscriminatorQueryId)) {
127
+ return shortDiscriminatorQueryId;
128
+ }
129
+ if (record.VP !== void 0) {
130
+ const vendorIdQueryId = this.buildCommissionableQueryIdentifier({
131
+ vendorId: (0, import_datatype.VendorId)(parseInt(record.VP.split("+")[0]))
132
+ });
133
+ if (this.recordWaiters.has(vendorIdQueryId)) {
134
+ return vendorIdQueryId;
135
+ }
136
+ if (record.VP.includes("+")) {
137
+ const productIdQueryId = this.buildCommissionableQueryIdentifier({
138
+ vendorId: (0, import_datatype.VendorId)(parseInt(record.VP.split("+")[1]))
139
+ });
140
+ if (this.recordWaiters.has(productIdQueryId)) {
141
+ return productIdQueryId;
142
+ }
143
+ }
144
+ }
145
+ if (this.recordWaiters.has("*")) {
146
+ return "*";
147
+ }
148
+ return void 0;
149
+ }
150
+ /**
151
+ * Builds an identifier string for commissionable queries based on the given identifier object.
152
+ * Some identifiers are identical to the official DNS-SD identifiers, others are custom.
153
+ */
154
+ buildCommissionableQueryIdentifier(identifier) {
155
+ if ("longDiscriminator" in identifier) {
156
+ return `D:${identifier.longDiscriminator}`;
157
+ } else if ("shortDiscriminator" in identifier) {
158
+ return `SD:${identifier.shortDiscriminator}`;
159
+ } else if ("vendorId" in identifier) {
160
+ return `V:${identifier.vendorId}`;
161
+ } else if ("productId" in identifier) {
162
+ return `P:${identifier.productId}`;
163
+ } else return "*";
164
+ }
165
+ getCommissionableDevices(identifier) {
166
+ const storedRecords = Array.from(this.discoveredMatterDevices.values());
167
+ const foundRecords = new Array();
168
+ if ("longDiscriminator" in identifier) {
169
+ foundRecords.push(...storedRecords.filter(({ deviceData: { D } }) => D === identifier.longDiscriminator));
170
+ } else if ("shortDiscriminator" in identifier) {
171
+ foundRecords.push(
172
+ ...storedRecords.filter(({ deviceData: { SD } }) => SD === identifier.shortDiscriminator)
173
+ );
174
+ } else if ("vendorId" in identifier) {
175
+ foundRecords.push(
176
+ ...storedRecords.filter(
177
+ ({ deviceData: { VP } }) => VP === `${identifier.vendorId}` || VP?.startsWith(`${identifier.vendorId}+`)
178
+ )
179
+ );
180
+ } else if ("productId" in identifier) {
181
+ foundRecords.push(
182
+ ...storedRecords.filter(({ deviceData: { VP } }) => VP?.endsWith(`+${identifier.productId}`))
183
+ );
184
+ } else {
185
+ foundRecords.push(...storedRecords.filter(({ deviceData: { CM } }) => CM === 1 || CM === 2));
186
+ }
187
+ return foundRecords;
188
+ }
189
+ async findOperationalDevice() {
190
+ logger.info(`skip BLE scan because scanning for operational devices is not supported`);
191
+ return void 0;
192
+ }
193
+ getDiscoveredOperationalDevice() {
194
+ logger.info(`skip BLE scan because scanning for operational devices is not supported`);
195
+ return void 0;
196
+ }
197
+ async findCommissionableDevices(identifier, timeoutSeconds = 10) {
198
+ let storedRecords = this.getCommissionableDevices(identifier);
199
+ if (storedRecords.length === 0) {
200
+ const queryKey = this.buildCommissionableQueryIdentifier(identifier);
201
+ await this.nobleClient.startScanning();
202
+ await this.registerWaiterPromise(queryKey, timeoutSeconds);
203
+ storedRecords = this.getCommissionableDevices(identifier);
204
+ await this.nobleClient.stopScanning();
205
+ }
206
+ return storedRecords.map(({ deviceData }) => deviceData);
207
+ }
208
+ async findCommissionableDevicesContinuously(identifier, callback, timeoutSeconds = 60) {
209
+ const discoveredDevices = /* @__PURE__ */ new Set();
210
+ const discoveryEndTime = import_general.Time.nowMs() + timeoutSeconds * 1e3;
211
+ const queryKey = this.buildCommissionableQueryIdentifier(identifier);
212
+ await this.nobleClient.startScanning();
213
+ while (true) {
214
+ this.getCommissionableDevices(identifier).forEach(({ deviceData }) => {
215
+ const { deviceIdentifier } = deviceData;
216
+ if (!discoveredDevices.has(deviceIdentifier)) {
217
+ discoveredDevices.add(deviceIdentifier);
218
+ callback(deviceData);
219
+ }
220
+ });
221
+ const remainingTime = Math.ceil((discoveryEndTime - import_general.Time.nowMs()) / 1e3);
222
+ if (remainingTime <= 0) {
223
+ break;
224
+ }
225
+ await this.registerWaiterPromise(queryKey, remainingTime, false);
226
+ }
227
+ await this.nobleClient.stopScanning();
228
+ return this.getCommissionableDevices(identifier).map(({ deviceData }) => deviceData);
229
+ }
230
+ getDiscoveredCommissionableDevices(identifier) {
231
+ return this.getCommissionableDevices(identifier).map(({ deviceData }) => deviceData);
232
+ }
233
+ close() {
234
+ void this.nobleClient.stopScanning();
235
+ [...this.recordWaiters.keys()].forEach(
236
+ (queryId) => this.finishWaiter(queryId, !!this.recordWaiters.get(queryId)?.timer)
237
+ );
238
+ }
239
+ }
240
+ //# sourceMappingURL=BleScanner.js.map
@@ -0,0 +1,6 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/BleScanner.ts"],
4
+ "mappings": "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",
5
+ "names": []
6
+ }
@@ -0,0 +1,70 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2022-2024 Matter.js Authors
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { Channel } from "@matter/general";
7
+ import { BleChannel } from "@project-chip/matter.js/ble";
8
+ import { BleOptions } from "./NodeJsBle.js";
9
+ /**
10
+ * Implements the Matter over BLE server using Bleno as Peripheral.
11
+ *
12
+ * Note: Bleno is only supporting a single connection at a time right now - mainly because it also only can announce
13
+ * one BLE device at a time!
14
+ */
15
+ export declare class BlenoBleServer extends BleChannel<Uint8Array> {
16
+ private state;
17
+ isAdvertising: boolean;
18
+ private additionalAdvertisingData;
19
+ private advertisingData;
20
+ private latestHandshakePayload;
21
+ private btpSession;
22
+ private onMatterMessageListener;
23
+ private writeConformationResolver;
24
+ clientAddress: string | undefined;
25
+ private btpHandshakeTimeout;
26
+ private readonly matterBleService;
27
+ constructor(options?: BleOptions);
28
+ /**
29
+ * Process a Write request on characteristic C1 from the Matter service.
30
+ * The data are checked if it might be a handshake request and stored until the subscribe request comes in.
31
+ * Otherwise, the data are forwarded to the BTP session handler to be decoded and processed.
32
+ *
33
+ * @param data
34
+ * @param offset
35
+ * @param withoutResponse
36
+ */
37
+ handleC1WriteRequest(data: Buffer, offset: number, withoutResponse: boolean): void;
38
+ /**
39
+ * Process a Subscribe request on characteristic C2 from the Matter service.
40
+ * This is expected directly after a handshake request and initializes the BTP session handler with the stored
41
+ * handshake payload.
42
+ * The BtpSessionHandler instance is wired with the bleno instance for sending data and disconnecting.
43
+ *
44
+ * @param maxValueSize
45
+ * @param updateValueCallback
46
+ */
47
+ handleC2SubscribeRequest(maxValueSize: number, updateValueCallback: (data: Buffer) => void): Promise<void>;
48
+ handleC2Indicate(): void;
49
+ /**
50
+ * Process a Read request on characteristic C3 from the Matter service.
51
+ * The relevant data needs optionally to be set before advertising, else empty data are used.
52
+ *
53
+ * @param offset
54
+ */
55
+ handleC3ReadRequest(offset: number): Buffer;
56
+ advertise(advertiseData: Uint8Array, additionalAdvertisementData?: Uint8Array): Promise<void>;
57
+ stopAdvertising(): Promise<void>;
58
+ setMatterMessageListener(listener: (socket: Channel<Uint8Array>, data: Uint8Array) => void): void;
59
+ btpHandshakeTimeoutTriggered(): Promise<void>;
60
+ close(): Promise<void>;
61
+ disconnect(): Promise<void>;
62
+ /**
63
+ * Send a Matter message to the connected device - need to do BTP assembly first.
64
+ *
65
+ * @param data
66
+ */
67
+ send(data: Uint8Array): Promise<void>;
68
+ get name(): string;
69
+ }
70
+ //# sourceMappingURL=BlenoBleServer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BlenoBleServer.d.ts","sourceRoot":"","sources":["../../src/BlenoBleServer.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAA8C,MAAM,iBAAiB,CAAC;AAEtF,OAAO,EAMH,UAAU,EAIb,MAAM,6BAA6B,CAAC;AAErC,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAmG5C;;;;;GAKG;AACH,qBAAa,cAAe,SAAQ,UAAU,CAAC,UAAU,CAAC;IACtD,OAAO,CAAC,KAAK,CAAa;IAC1B,aAAa,UAAS;IACtB,OAAO,CAAC,yBAAyB,CAA2B;IAC5D,OAAO,CAAC,eAAe,CAAqB;IAE5C,OAAO,CAAC,sBAAsB,CAAqB;IACnD,OAAO,CAAC,UAAU,CAAgC;IAElD,OAAO,CAAC,uBAAuB,CAAwE;IACvG,OAAO,CAAC,yBAAyB,CAAsC;IAEhE,aAAa,EAAE,MAAM,GAAG,SAAS,CAAC;IACzC,OAAO,CAAC,mBAAmB,CAEzB;IAEF,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAC;gBAEtB,OAAO,CAAC,EAAE,UAAU;IAiEhC;;;;;;;;OAQG;IACH,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE,OAAO;IA0B3E;;;;;;;;OAQG;IACG,wBAAwB,CAAC,YAAY,EAAE,MAAM,EAAE,mBAAmB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI;IAsChG,gBAAgB;IAShB;;;;;OAKG;IACH,mBAAmB,CAAC,MAAM,EAAE,MAAM;IAQ5B,SAAS,CAAC,aAAa,EAAE,UAAU,EAAE,2BAA2B,CAAC,EAAE,UAAU;IAyB7E,eAAe;IAYrB,wBAAwB,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,UAAU,KAAK,IAAI;IAOpF,4BAA4B;IAK5B,KAAK;IAUL,UAAU;IAahB;;;;OAIG;IACG,IAAI,CAAC,IAAI,EAAE,UAAU;IAQ3B,IAAI,IAAI,WAEP;CACJ"}
@@ -0,0 +1,337 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var BlenoBleServer_exports = {};
20
+ __export(BlenoBleServer_exports, {
21
+ BlenoBleServer: () => BlenoBleServer
22
+ });
23
+ module.exports = __toCommonJS(BlenoBleServer_exports);
24
+ var import_general = require("@matter/general");
25
+ var import_require = require("@matter/nodejs-ble/require");
26
+ var import_ble = require("@project-chip/matter.js/ble");
27
+ var import_protocol = require("@project-chip/matter.js/protocol");
28
+ /**
29
+ * @license
30
+ * Copyright 2022-2024 Matter.js Authors
31
+ * SPDX-License-Identifier: Apache-2.0
32
+ */
33
+ const logger = import_general.Logger.get("BlenoBleServer");
34
+ let Bleno;
35
+ function initializeBleno(server, hciId) {
36
+ if (hciId !== void 0) {
37
+ process.env.BLENO_HCI_DEVICE_ID = hciId.toString();
38
+ }
39
+ Bleno = (0, import_require.require)("@stoprocent/bleno");
40
+ class BtpWriteCharacteristicC1 extends Bleno.Characteristic {
41
+ constructor() {
42
+ super({
43
+ uuid: import_ble.BLE_MATTER_C1_CHARACTERISTIC_UUID,
44
+ properties: ["write"]
45
+ });
46
+ }
47
+ onWriteRequest(data, offset, withoutResponse, callback) {
48
+ logger.debug(`C1 write request: ${data.toString("hex")} ${offset} ${withoutResponse}`);
49
+ try {
50
+ server.handleC1WriteRequest(data, offset, withoutResponse);
51
+ callback(this.RESULT_SUCCESS);
52
+ } catch (e) {
53
+ logger.error(`C1 write request failed: ${e}`);
54
+ callback(this.RESULT_UNLIKELY_ERROR);
55
+ }
56
+ }
57
+ }
58
+ class BtpIndicateCharacteristicC2 extends Bleno.Characteristic {
59
+ constructor() {
60
+ super({
61
+ uuid: import_ble.BLE_MATTER_C2_CHARACTERISTIC_UUID,
62
+ properties: ["indicate"]
63
+ });
64
+ }
65
+ async onSubscribe(maxValueSize, updateValueCallback) {
66
+ logger.debug(`C2 subscribe ${maxValueSize}`);
67
+ await server.handleC2SubscribeRequest(maxValueSize, updateValueCallback);
68
+ }
69
+ async onUnsubscribe() {
70
+ logger.debug("C2 unsubscribe");
71
+ await server.close();
72
+ }
73
+ onIndicate() {
74
+ logger.debug("C2 indicate");
75
+ server.handleC2Indicate();
76
+ }
77
+ }
78
+ class BtpReadCharacteristicC3 extends Bleno.Characteristic {
79
+ constructor() {
80
+ super({
81
+ uuid: import_ble.BLE_MATTER_C3_CHARACTERISTIC_UUID,
82
+ properties: ["read"]
83
+ });
84
+ }
85
+ onReadRequest(offset, callback) {
86
+ try {
87
+ const data = server.handleC3ReadRequest(offset);
88
+ logger.debug(`C3 read request: ${data.toString("hex")} ${offset}`);
89
+ callback(this.RESULT_SUCCESS, data);
90
+ } catch (e) {
91
+ logger.debug(`C3 read request failed : ${e} ${offset}`);
92
+ callback(this.RESULT_INVALID_OFFSET);
93
+ }
94
+ }
95
+ }
96
+ class BtpService extends Bleno.PrimaryService {
97
+ constructor() {
98
+ super({
99
+ uuid: import_ble.BLE_MATTER_SERVICE_UUID,
100
+ characteristics: [
101
+ new BtpWriteCharacteristicC1(),
102
+ new BtpIndicateCharacteristicC2(),
103
+ new BtpReadCharacteristicC3()
104
+ ]
105
+ });
106
+ }
107
+ }
108
+ return new BtpService();
109
+ }
110
+ class BlenoBleServer extends import_ble.BleChannel {
111
+ state = "unknown";
112
+ isAdvertising = false;
113
+ additionalAdvertisingData = Buffer.alloc(0);
114
+ advertisingData;
115
+ latestHandshakePayload;
116
+ btpSession;
117
+ onMatterMessageListener;
118
+ writeConformationResolver;
119
+ clientAddress;
120
+ btpHandshakeTimeout = import_general.Time.getTimer(
121
+ "BTP handshake timeout",
122
+ import_ble.BTP_CONN_RSP_TIMEOUT_MS,
123
+ () => this.btpHandshakeTimeoutTriggered()
124
+ );
125
+ matterBleService;
126
+ constructor(options) {
127
+ super();
128
+ this.matterBleService = initializeBleno(this, options?.hciId);
129
+ Bleno.on("stateChange", (state) => {
130
+ if (state === this.state) return;
131
+ this.state = state;
132
+ logger.debug(`stateChange: ${state}, address = ${Bleno.address}`);
133
+ if (state !== "poweredOn") {
134
+ Bleno.stopAdvertising();
135
+ } else if (this.advertisingData) {
136
+ Bleno.startAdvertisingWithEIRData(this.advertisingData);
137
+ this.isAdvertising = true;
138
+ }
139
+ });
140
+ Bleno.on("accept", (clientAddress) => {
141
+ logger.debug(`accept new connection, client: ${clientAddress}`);
142
+ this.clientAddress = clientAddress;
143
+ Bleno.updateRssi();
144
+ });
145
+ Bleno.on("disconnect", (clientAddress) => {
146
+ logger.debug(`disconnect, client: ${clientAddress}`);
147
+ if (this.btpSession !== void 0) {
148
+ this.btpSession.close().then(() => {
149
+ this.btpSession = void 0;
150
+ }).catch(() => {
151
+ this.btpSession = void 0;
152
+ });
153
+ }
154
+ });
155
+ Bleno.on("rssiUpdate", (rssi) => {
156
+ logger.debug(`rssiUpdate: ${rssi}`);
157
+ });
158
+ Bleno.on("mtuChange", (mtu) => {
159
+ logger.debug(`mtuChange: ${mtu}`);
160
+ });
161
+ Bleno.on("advertisingStart", (error) => {
162
+ logger.debug(`advertisingStart: ${error ? `error ${error}` : "success"}`);
163
+ if (!error) {
164
+ Bleno.setServices([this.matterBleService]);
165
+ }
166
+ });
167
+ Bleno.on("advertisingStop", () => {
168
+ logger.debug("advertisingStop");
169
+ });
170
+ Bleno.on("servicesSet", (error) => {
171
+ logger.debug(`servicesSet: ${error ? `error ${error}` : "success"}`);
172
+ });
173
+ }
174
+ /**
175
+ * Process a Write request on characteristic C1 from the Matter service.
176
+ * The data are checked if it might be a handshake request and stored until the subscribe request comes in.
177
+ * Otherwise, the data are forwarded to the BTP session handler to be decoded and processed.
178
+ *
179
+ * @param data
180
+ * @param offset
181
+ * @param withoutResponse
182
+ */
183
+ handleC1WriteRequest(data, offset, withoutResponse) {
184
+ if (offset !== 0 || withoutResponse) {
185
+ throw new import_ble.BleError(`Offset ${offset} or withoutResponse ${withoutResponse} not supported`);
186
+ }
187
+ if (data[0] === 101 && data[1] === 108 && data.length === 9) {
188
+ this.btpHandshakeTimeout.start();
189
+ logger.info(
190
+ `Received Matter handshake request: ${data.toString("hex")}, store until subscribe request comes in.`
191
+ );
192
+ this.latestHandshakePayload = data;
193
+ } else {
194
+ if (this.btpSession !== void 0) {
195
+ logger.debug(`Received Matter data for BTP Session: ${data.toString("hex")}`);
196
+ void this.btpSession.handleIncomingBleData(new Uint8Array(data));
197
+ } else {
198
+ throw new import_ble.BtpFlowError(
199
+ `Received Matter data but no BTP session was initialized: ${data.toString("hex")}`
200
+ );
201
+ }
202
+ }
203
+ }
204
+ /**
205
+ * Process a Subscribe request on characteristic C2 from the Matter service.
206
+ * This is expected directly after a handshake request and initializes the BTP session handler with the stored
207
+ * handshake payload.
208
+ * The BtpSessionHandler instance is wired with the bleno instance for sending data and disconnecting.
209
+ *
210
+ * @param maxValueSize
211
+ * @param updateValueCallback
212
+ */
213
+ async handleC2SubscribeRequest(maxValueSize, updateValueCallback) {
214
+ if (this.latestHandshakePayload === void 0) {
215
+ throw new import_ble.BtpFlowError(`Subscription request received before handshake Request`);
216
+ }
217
+ if (this.btpSession !== void 0) {
218
+ throw new import_ble.BtpFlowError(
219
+ `Subscription request received but BTP session already initialized. Cannot handle two sessions!`
220
+ );
221
+ }
222
+ this.btpHandshakeTimeout.stop();
223
+ this.btpSession = await import_ble.BtpSessionHandler.createFromHandshakeRequest(
224
+ Math.min(Bleno.mtu - 3, maxValueSize),
225
+ new Uint8Array(this.latestHandshakePayload),
226
+ // callback to write data to characteristic C2
227
+ async (data) => {
228
+ updateValueCallback(Buffer.from(data.buffer));
229
+ const { promise, resolver } = (0, import_general.createPromise)();
230
+ this.writeConformationResolver = resolver;
231
+ return promise;
232
+ },
233
+ // callback to disconnect the BLE connection
234
+ async () => this.close(),
235
+ // callback to forward decoded and de-assembled Matter messages to ExchangeManager
236
+ async (data) => {
237
+ if (this.onMatterMessageListener === void 0) {
238
+ throw new import_general.InternalError(`No listener registered for Matter messages`);
239
+ }
240
+ this.onMatterMessageListener(this, data);
241
+ }
242
+ );
243
+ this.latestHandshakePayload = void 0;
244
+ }
245
+ handleC2Indicate() {
246
+ if (this.writeConformationResolver !== void 0) {
247
+ this.writeConformationResolver();
248
+ this.writeConformationResolver = void 0;
249
+ } else {
250
+ logger.warn(`Received C2 indication but no former write expected a confirmation`);
251
+ }
252
+ }
253
+ /**
254
+ * Process a Read request on characteristic C3 from the Matter service.
255
+ * The relevant data needs optionally to be set before advertising, else empty data are used.
256
+ *
257
+ * @param offset
258
+ */
259
+ handleC3ReadRequest(offset) {
260
+ if (offset > this.additionalAdvertisingData.length) {
261
+ throw new import_ble.BleError(`Offset ${offset} is larger than data ${this.additionalAdvertisingData.length}`);
262
+ } else {
263
+ return this.additionalAdvertisingData.subarray(offset);
264
+ }
265
+ }
266
+ async advertise(advertiseData, additionalAdvertisementData) {
267
+ this.advertisingData = Buffer.from(advertiseData.buffer);
268
+ if (additionalAdvertisementData) {
269
+ this.additionalAdvertisingData = Buffer.from(additionalAdvertisementData.buffer);
270
+ } else {
271
+ this.additionalAdvertisingData = Buffer.alloc(0);
272
+ }
273
+ if (this.isAdvertising) {
274
+ await this.stopAdvertising();
275
+ this.isAdvertising = false;
276
+ }
277
+ if (this.state === "poweredOn") {
278
+ Bleno.startAdvertisingWithEIRData(this.advertisingData);
279
+ this.isAdvertising = true;
280
+ } else {
281
+ logger.debug(`State is ${this.state}, advertise when powered on`);
282
+ }
283
+ return new Promise((resolve) => {
284
+ Bleno.once("advertisingStart", () => resolve());
285
+ });
286
+ }
287
+ async stopAdvertising() {
288
+ if (this.isAdvertising) {
289
+ return new Promise((resolve) => {
290
+ Bleno.stopAdvertising();
291
+ Bleno.once("advertisingStop", () => {
292
+ this.isAdvertising = false;
293
+ resolve();
294
+ });
295
+ });
296
+ }
297
+ }
298
+ setMatterMessageListener(listener) {
299
+ if (this.onMatterMessageListener !== void 0) {
300
+ throw new import_general.InternalError(`onData listener already set`);
301
+ }
302
+ this.onMatterMessageListener = listener;
303
+ }
304
+ async btpHandshakeTimeoutTriggered() {
305
+ await this.disconnect();
306
+ logger.error("Timeout for handshake subscribe request on C2 reached, disconnecting.");
307
+ }
308
+ async close() {
309
+ this.btpHandshakeTimeout.stop();
310
+ await this.disconnect();
311
+ if (this.btpSession !== void 0) {
312
+ await this.btpSession.close();
313
+ this.btpSession = void 0;
314
+ }
315
+ this.onMatterMessageListener = void 0;
316
+ }
317
+ async disconnect() {
318
+ Bleno.disconnect();
319
+ }
320
+ // Channel<Uint8Array>
321
+ /**
322
+ * Send a Matter message to the connected device - need to do BTP assembly first.
323
+ *
324
+ * @param data
325
+ */
326
+ async send(data) {
327
+ if (this.btpSession === void 0) {
328
+ throw new import_protocol.ChannelNotConnectedError(`Cannot send data, no BTP session initialized`);
329
+ }
330
+ await this.btpSession.sendMatterMessage(data);
331
+ }
332
+ // Channel<Uint8Array>
333
+ get name() {
334
+ return `${this.type}://${this.clientAddress}`;
335
+ }
336
+ }
337
+ //# sourceMappingURL=BlenoBleServer.js.map
@@ -0,0 +1,6 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/BlenoBleServer.ts"],
4
+ "mappings": "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",
5
+ "names": []
6
+ }