@matter-server/ble-proxy 0.7.2-alpha.0-20260601-e778038 → 0.8.0
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.
- package/dist/esm/BleProxyConnection.d.ts +34 -0
- package/dist/esm/BleProxyConnection.d.ts.map +1 -0
- package/dist/esm/BleProxyConnection.js +210 -0
- package/dist/esm/BleProxyConnection.js.map +6 -0
- package/dist/esm/BleProxyHandler.d.ts +15 -20
- package/dist/esm/BleProxyHandler.d.ts.map +1 -1
- package/dist/esm/BleProxyHandler.js +114 -183
- package/dist/esm/BleProxyHandler.js.map +1 -1
- package/dist/esm/ProxyBleChannel.d.ts.map +1 -1
- package/dist/esm/ProxyBleChannel.js +70 -40
- package/dist/esm/ProxyBleChannel.js.map +1 -1
- package/dist/esm/ProxyBleClient.d.ts.map +1 -1
- package/dist/esm/ProxyBleClient.js +16 -24
- package/dist/esm/ProxyBleClient.js.map +1 -1
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +1 -0
- package/dist/esm/index.js.map +1 -1
- package/package.json +21 -20
- package/src/BleProxyConnection.ts +282 -0
- package/src/BleProxyHandler.ts +121 -246
- package/src/ProxyBleChannel.ts +92 -56
- package/src/ProxyBleClient.ts +22 -26
- package/src/index.ts +1 -0
|
@@ -3,34 +3,35 @@
|
|
|
3
3
|
* Copyright 2025-2026 Open Home Foundation
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
|
-
import {
|
|
6
|
+
import { Logger, Observable } from "@matter/main";
|
|
7
7
|
import { WebSocket, WebSocketServer } from "ws";
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
decodeBinaryFrame,
|
|
11
|
-
encodeBinaryFrame
|
|
12
|
-
} from "./BleProxyProtocol.js";
|
|
8
|
+
import { BleProxyConnection } from "./BleProxyConnection.js";
|
|
9
|
+
import { BleProxyCommand, BleProxyEvent } from "./BleProxyProtocol.js";
|
|
13
10
|
const logger = Logger.get("BleProxyHandler");
|
|
14
|
-
const HANDSHAKE_TIMEOUT = Seconds(10);
|
|
15
|
-
const COMMAND_TIMEOUT = Seconds(60);
|
|
16
11
|
class BleProxyHandler {
|
|
17
12
|
#wss;
|
|
18
13
|
/** Upgrade listener removers, one per HTTP server `register()` call (multi-bind). */
|
|
19
14
|
#removeUpgradeListeners = [];
|
|
20
|
-
#
|
|
21
|
-
#handshakeComplete = false;
|
|
22
|
-
#pendingCommands = /* @__PURE__ */ new Map();
|
|
23
|
-
/** Command ID counter. Rolls over at 0xFFFF to stay in safe integer range. */
|
|
24
|
-
#nextCommandId = 0;
|
|
15
|
+
#connections = /* @__PURE__ */ new Set();
|
|
25
16
|
#closed = false;
|
|
26
|
-
/**
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
17
|
+
/** Active scan intent + args, so clients joining mid-scan can be synced. */
|
|
18
|
+
#scanActive = false;
|
|
19
|
+
#scanArgs;
|
|
20
|
+
/** Connections currently told to scan, for aggregate `scanStopped`. */
|
|
21
|
+
#scanning = /* @__PURE__ */ new Set();
|
|
22
|
+
/** address -> owning connection + every connection that has seen it. */
|
|
23
|
+
#owners = /* @__PURE__ */ new Map();
|
|
24
|
+
/** Emitted whenever a connection completes its handshake. */
|
|
31
25
|
connectionEstablished = new Observable();
|
|
26
|
+
/** Emitted for each `device_discovered`, after ownership is updated. */
|
|
27
|
+
deviceDiscovered = new Observable();
|
|
28
|
+
/** Emitted once no connection is scanning anymore. */
|
|
29
|
+
scanStopped = new Observable();
|
|
32
30
|
get connected() {
|
|
33
|
-
|
|
31
|
+
for (const c of this.#connections) {
|
|
32
|
+
if (c.connected) return true;
|
|
33
|
+
}
|
|
34
|
+
return false;
|
|
34
35
|
}
|
|
35
36
|
async register(server) {
|
|
36
37
|
const isFirstBind = this.#wss === void 0;
|
|
@@ -59,38 +60,11 @@ class BleProxyHandler {
|
|
|
59
60
|
ws.close();
|
|
60
61
|
return;
|
|
61
62
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
logger.info("BLE proxy client connected, waiting for handshake");
|
|
68
|
-
this.#client = ws;
|
|
69
|
-
this.#handshakeComplete = false;
|
|
70
|
-
const handshakeTimer = Time.getTimer("BLE proxy handshake timeout", HANDSHAKE_TIMEOUT, () => {
|
|
71
|
-
if (!this.#handshakeComplete) {
|
|
72
|
-
logger.warn("BLE proxy handshake timeout - closing connection");
|
|
73
|
-
ws.close(4001, "Handshake timeout");
|
|
74
|
-
this.#cleanupClient();
|
|
75
|
-
}
|
|
76
|
-
}).start();
|
|
77
|
-
ws.on("message", (data, isBinary) => {
|
|
78
|
-
if (isBinary) {
|
|
79
|
-
this.#handleBinaryMessage(data);
|
|
80
|
-
} else {
|
|
81
|
-
this.#handleTextMessage(data.toString(), handshakeTimer);
|
|
82
|
-
}
|
|
83
|
-
});
|
|
84
|
-
ws.on("close", () => {
|
|
85
|
-
handshakeTimer.stop();
|
|
86
|
-
logger.info("BLE proxy client disconnected");
|
|
87
|
-
this.#cleanupClient();
|
|
88
|
-
});
|
|
89
|
-
ws.on("error", (err) => {
|
|
90
|
-
logger.error("BLE proxy WebSocket error:", err);
|
|
91
|
-
handshakeTimer.stop();
|
|
92
|
-
this.#cleanupClient();
|
|
93
|
-
});
|
|
63
|
+
const connection = new BleProxyConnection(ws);
|
|
64
|
+
this.#connections.add(connection);
|
|
65
|
+
connection.handshakeCompleted.on(() => this.#onHandshakeCompleted(connection));
|
|
66
|
+
connection.eventReceived.on((event, data) => this.#onConnectionEvent(connection, event, data));
|
|
67
|
+
connection.closed.on(() => this.#onConnectionClosed(connection));
|
|
94
68
|
});
|
|
95
69
|
}
|
|
96
70
|
unregister() {
|
|
@@ -100,10 +74,12 @@ class BleProxyHandler {
|
|
|
100
74
|
this.#closed = true;
|
|
101
75
|
for (const remove of this.#removeUpgradeListeners) remove();
|
|
102
76
|
this.#removeUpgradeListeners = [];
|
|
103
|
-
|
|
104
|
-
|
|
77
|
+
for (const connection of this.#connections) {
|
|
78
|
+
connection.close();
|
|
105
79
|
}
|
|
106
|
-
this.#
|
|
80
|
+
this.#connections.clear();
|
|
81
|
+
this.#scanning.clear();
|
|
82
|
+
this.#owners.clear();
|
|
107
83
|
const wss = this.#wss;
|
|
108
84
|
this.#wss = void 0;
|
|
109
85
|
wss.clients.forEach((client) => {
|
|
@@ -112,152 +88,107 @@ class BleProxyHandler {
|
|
|
112
88
|
}
|
|
113
89
|
});
|
|
114
90
|
return new Promise((resolve, reject) => {
|
|
115
|
-
wss.close((err) =>
|
|
116
|
-
if (err) {
|
|
117
|
-
reject(err);
|
|
118
|
-
} else {
|
|
119
|
-
resolve();
|
|
120
|
-
}
|
|
121
|
-
});
|
|
91
|
+
wss.close((err) => err ? reject(err) : resolve());
|
|
122
92
|
});
|
|
123
93
|
}
|
|
124
|
-
/**
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
async sendCommand(command, ...rest) {
|
|
130
|
-
if (!this.connected || !this.#client) {
|
|
131
|
-
throw new Error("BLE proxy client not connected");
|
|
132
|
-
}
|
|
133
|
-
const args = rest[0];
|
|
134
|
-
const id = this.#nextCommandId;
|
|
135
|
-
this.#nextCommandId = this.#nextCommandId + 1 & 65535;
|
|
136
|
-
const message = { id, command };
|
|
137
|
-
if (args !== void 0) {
|
|
138
|
-
message.args = args;
|
|
139
|
-
}
|
|
140
|
-
const { promise, resolver, rejecter } = createPromise();
|
|
141
|
-
this.#pendingCommands.set(id, { resolver, rejecter });
|
|
142
|
-
this.#client.send(JSON.stringify(message), (err) => {
|
|
143
|
-
if (err) {
|
|
144
|
-
this.#pendingCommands.delete(id);
|
|
145
|
-
rejecter(new Error(`Failed to send command ${command}: ${err.message}`));
|
|
146
|
-
}
|
|
147
|
-
});
|
|
148
|
-
return withTimeout(COMMAND_TIMEOUT, promise, () => this.#pendingCommands.delete(id));
|
|
94
|
+
/** Returns the connection that owns `address`, if it is still connected. */
|
|
95
|
+
getOwner(address) {
|
|
96
|
+
const entry = this.#owners.get(address);
|
|
97
|
+
if (entry && entry.owner.connected) return entry.owner;
|
|
98
|
+
return void 0;
|
|
149
99
|
}
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
100
|
+
async startScan(args) {
|
|
101
|
+
this.#scanActive = true;
|
|
102
|
+
this.#scanArgs = args;
|
|
103
|
+
const sends = new Array();
|
|
104
|
+
for (const connection of this.#connections) {
|
|
105
|
+
if (connection.connected) {
|
|
106
|
+
this.#scanning.add(connection);
|
|
107
|
+
sends.push(
|
|
108
|
+
connection.sendCommand(BleProxyCommand.StartScan, args).catch((err) => {
|
|
109
|
+
logger.warn(`[${connection.id}] Failed to start scan:`, err);
|
|
110
|
+
this.#markNotScanning(connection, "start scan failed");
|
|
111
|
+
})
|
|
112
|
+
);
|
|
113
|
+
}
|
|
156
114
|
}
|
|
157
|
-
|
|
158
|
-
this.#client.send(frame);
|
|
115
|
+
await Promise.all(sends);
|
|
159
116
|
}
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
if (!this.#handshakeComplete) {
|
|
170
|
-
this.#handleHandshake(msg, handshakeTimer);
|
|
171
|
-
return;
|
|
172
|
-
}
|
|
173
|
-
if ("id" in msg && "success" in msg) {
|
|
174
|
-
this.#handleResponse(msg);
|
|
175
|
-
return;
|
|
176
|
-
}
|
|
177
|
-
if ("event" in msg && "data" in msg) {
|
|
178
|
-
this.#handleEvent(msg);
|
|
179
|
-
return;
|
|
117
|
+
async stopScan() {
|
|
118
|
+
this.#scanActive = false;
|
|
119
|
+
const sends = new Array();
|
|
120
|
+
for (const connection of this.#connections) {
|
|
121
|
+
if (connection.connected) {
|
|
122
|
+
sends.push(
|
|
123
|
+
connection.sendCommand(BleProxyCommand.StopScan).catch((err) => logger.warn(`[${connection.id}] Failed to stop scan:`, err))
|
|
124
|
+
);
|
|
125
|
+
}
|
|
180
126
|
}
|
|
181
|
-
|
|
127
|
+
this.#scanning.clear();
|
|
128
|
+
await Promise.all(sends);
|
|
182
129
|
}
|
|
183
|
-
#
|
|
184
|
-
if (msg.type !== "hello") {
|
|
185
|
-
logger.warn(`Expected hello message, got: ${JSON.stringify(msg)}`);
|
|
186
|
-
this.#client?.close(4002, "Expected hello message");
|
|
187
|
-
this.#cleanupClient();
|
|
188
|
-
return;
|
|
189
|
-
}
|
|
190
|
-
const hello = msg;
|
|
191
|
-
handshakeTimer.stop();
|
|
192
|
-
if (hello.version !== BLE_PROXY_PROTOCOL_VERSION) {
|
|
193
|
-
logger.warn(
|
|
194
|
-
`BLE proxy client version ${hello.version} not supported (server supports ${BLE_PROXY_PROTOCOL_VERSION})`
|
|
195
|
-
);
|
|
196
|
-
this.#client?.send(
|
|
197
|
-
JSON.stringify({
|
|
198
|
-
type: "hello_response",
|
|
199
|
-
version: BLE_PROXY_PROTOCOL_VERSION,
|
|
200
|
-
error: "unsupported_version",
|
|
201
|
-
message: `Server supports protocol version ${BLE_PROXY_PROTOCOL_VERSION}, client sent version ${hello.version}`
|
|
202
|
-
})
|
|
203
|
-
);
|
|
204
|
-
this.#client?.close(4003, "Unsupported protocol version");
|
|
205
|
-
this.#cleanupClient();
|
|
206
|
-
return;
|
|
207
|
-
}
|
|
208
|
-
this.#handshakeComplete = true;
|
|
209
|
-
this.#client?.send(
|
|
210
|
-
JSON.stringify({
|
|
211
|
-
type: "hello_response",
|
|
212
|
-
version: BLE_PROXY_PROTOCOL_VERSION
|
|
213
|
-
})
|
|
214
|
-
);
|
|
215
|
-
logger.info(`BLE proxy handshake complete (version ${BLE_PROXY_PROTOCOL_VERSION})`);
|
|
130
|
+
#onHandshakeCompleted(connection) {
|
|
216
131
|
this.connectionEstablished.emit();
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
}
|
|
224
|
-
this.#pendingCommands.delete(msg.id);
|
|
225
|
-
if (msg.success) {
|
|
226
|
-
pending.resolver(msg.result);
|
|
227
|
-
} else {
|
|
228
|
-
pending.rejecter(new Error(`${msg.error}: ${msg.message}`));
|
|
132
|
+
if (this.#scanActive && this.#scanArgs) {
|
|
133
|
+
this.#scanning.add(connection);
|
|
134
|
+
connection.sendCommand(BleProxyCommand.StartScan, this.#scanArgs).catch((err) => {
|
|
135
|
+
logger.warn(`[${connection.id}] Failed to sync scan to joining client:`, err);
|
|
136
|
+
this.#markNotScanning(connection, "start scan failed");
|
|
137
|
+
});
|
|
229
138
|
}
|
|
230
139
|
}
|
|
231
|
-
#
|
|
232
|
-
|
|
140
|
+
#onConnectionEvent(connection, event, data) {
|
|
141
|
+
if (event === BleProxyEvent.DeviceDiscovered) {
|
|
142
|
+
this.#onDeviceDiscovered(connection, data);
|
|
143
|
+
} else if (event === BleProxyEvent.ScanStopped) {
|
|
144
|
+
this.#markNotScanning(connection, data.reason ?? "unknown");
|
|
145
|
+
}
|
|
233
146
|
}
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
147
|
+
/** Drop a connection from the scanning set; emit aggregate scanStopped once none remain. */
|
|
148
|
+
#markNotScanning(connection, reason) {
|
|
149
|
+
if (!this.#scanning.delete(connection)) {
|
|
237
150
|
return;
|
|
238
151
|
}
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
const head = Array.from(frame.payload.subarray(0, 8)).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
242
|
-
logger.debug(
|
|
243
|
-
`[FRAME] opcode=${frame.opcode} handle=${frame.connectionHandle} len=${frame.payload.length} head=${head}`
|
|
244
|
-
);
|
|
245
|
-
this.binaryFrameReceived.emit(frame);
|
|
246
|
-
} catch (err) {
|
|
247
|
-
logger.error("Failed to decode binary frame:", err);
|
|
152
|
+
if (this.#scanning.size === 0) {
|
|
153
|
+
this.scanStopped.emit(reason);
|
|
248
154
|
}
|
|
249
155
|
}
|
|
250
|
-
#
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
156
|
+
#onDeviceDiscovered(connection, data) {
|
|
157
|
+
let entry = this.#owners.get(data.address);
|
|
158
|
+
if (!entry) {
|
|
159
|
+
entry = { owner: connection, seers: /* @__PURE__ */ new Set([connection]) };
|
|
160
|
+
this.#owners.set(data.address, entry);
|
|
161
|
+
} else {
|
|
162
|
+
entry.seers.add(connection);
|
|
163
|
+
if (!entry.owner.connected) {
|
|
164
|
+
entry.owner = connection;
|
|
254
165
|
}
|
|
255
|
-
this.#client = void 0;
|
|
256
166
|
}
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
167
|
+
logger.debug(
|
|
168
|
+
`[${connection.id}] device_discovered ${data.address} rssi=${data.rssi ?? "n/a"} seers=${entry.seers.size} isOwner=${entry.owner === connection}`
|
|
169
|
+
);
|
|
170
|
+
this.deviceDiscovered.emit(data, connection);
|
|
171
|
+
}
|
|
172
|
+
#onConnectionClosed(connection) {
|
|
173
|
+
this.#connections.delete(connection);
|
|
174
|
+
this.#markNotScanning(connection, "client disconnected");
|
|
175
|
+
for (const [address, entry] of this.#owners) {
|
|
176
|
+
entry.seers.delete(connection);
|
|
177
|
+
if (entry.owner === connection) {
|
|
178
|
+
let next;
|
|
179
|
+
for (const seer of entry.seers) {
|
|
180
|
+
if (seer.connected) {
|
|
181
|
+
next = seer;
|
|
182
|
+
break;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
if (next) {
|
|
186
|
+
entry.owner = next;
|
|
187
|
+
logger.info(`Reassigned ownership of ${address} to [${next.id}]`);
|
|
188
|
+
} else {
|
|
189
|
+
this.#owners.delete(address);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
261
192
|
}
|
|
262
193
|
}
|
|
263
194
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/BleProxyHandler.ts"],
|
|
4
|
-
"mappings": "AAAA;AAAA;AAAA;AAAA;AAAA;AAOA,SAAS,
|
|
4
|
+
"mappings": "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",
|
|
5
5
|
"names": []
|
|
6
6
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProxyBleChannel.d.ts","sourceRoot":"","sources":["../../src/ProxyBleChannel.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACH,KAAK,KAAK,EACV,KAAK,OAAO,EACZ,WAAW,EAKX,aAAa,EAEb,KAAK,SAAS,EACjB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,UAAU,EAAoC,iBAAiB,EAAa,MAAM,uBAAuB,CAAC;AACnH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAE5D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAgC5D;;;GAGG;AACH,qBAAa,wBAAyB,YAAW,SAAS;;IAMtD,YAAY,UAAU,EAAE,eAAe,EAAE,OAAO,EAAE,eAAe,EAGhE;IAEK,WAAW,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"ProxyBleChannel.d.ts","sourceRoot":"","sources":["../../src/ProxyBleChannel.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACH,KAAK,KAAK,EACV,KAAK,OAAO,EACZ,WAAW,EAKX,aAAa,EAEb,KAAK,SAAS,EACjB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,UAAU,EAAoC,iBAAiB,EAAa,MAAM,uBAAuB,CAAC;AACnH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAE5D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAgC5D;;;GAGG;AACH,qBAAa,wBAAyB,YAAW,SAAS;;IAMtD,YAAY,UAAU,EAAE,eAAe,EAAE,OAAO,EAAE,eAAe,EAGhE;IAEK,WAAW,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CA2PjE;IAED,MAAM,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,KAAK,KAAK,IAAI,GAAG,SAAS,CAAC,QAAQ,CAKlF;IAEK,KAAK,kBAEV;IAED,QAAQ,CAAC,IAAI,EAAE,WAAW,EAAE,QAAQ,CAAC,EAAE,MAAM,2BAE5C;CACJ;AAED;;;GAGG;AACH,qBAAa,eAAgB,SAAQ,UAAU,CAAC,KAAK,CAAC;;IAWlD,YAAY,iBAAiB,EAAE,MAAM,EAAE,UAAU,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,IAAI,EAOjG;IAED,IAAI,SAAS,YAEZ;IAED,gBAAgB,SAEf;IAED,WAAW,CAAC,IAAI,EAAE,KAAK,GAAG,IAAI,CAQ7B;IAED,OAAO,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,SAAS,CAAC,QAAQ,CAOhD;IAED,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,aAAa,CAAC,KAAK,CAAC,CAc7C;IAUK,IAAI,CAAC,IAAI,EAAE,KAAK,iBASrB;IAED,IAAI,IAAI,WAEP;IAEK,KAAK,kBAUV;CACJ"}
|
|
@@ -51,28 +51,34 @@ class ProxyBleCentralInterface {
|
|
|
51
51
|
throw new InternalError("Network Interface was not added to the system yet.");
|
|
52
52
|
}
|
|
53
53
|
const { peripheralAddress } = address;
|
|
54
|
-
const
|
|
55
|
-
if (!
|
|
56
|
-
throw new BleError(
|
|
54
|
+
const connection = this.#handler.getOwner(peripheralAddress);
|
|
55
|
+
if (!connection) {
|
|
56
|
+
throw new BleError(`No connected BLE proxy client owns peripheral ${peripheralAddress}`);
|
|
57
57
|
}
|
|
58
|
-
|
|
59
|
-
const {
|
|
58
|
+
const discovered = this.#bleScanner.getDiscoveredDevice(peripheralAddress);
|
|
59
|
+
const { hasAdditionalAdvertisementData } = discovered;
|
|
60
|
+
const rssi = discovered.peripheral.rssi;
|
|
61
|
+
logger.debug(`Connecting to peripheral ${peripheralAddress} (rssi=${rssi ?? "n/a"}) via proxy`);
|
|
62
|
+
const { connection_handle, mtu: peripheralMtu } = await connection.sendCommand(BleProxyCommand.Connect, {
|
|
60
63
|
address: peripheralAddress
|
|
61
64
|
});
|
|
62
65
|
let mtu = peripheralMtu ?? 0;
|
|
63
66
|
if (mtu > MatterBle.MAXIMUM_BTP_MTU) {
|
|
64
67
|
mtu = MatterBle.MAXIMUM_BTP_MTU;
|
|
65
68
|
}
|
|
66
|
-
logger.
|
|
69
|
+
logger.info(
|
|
70
|
+
`Connected to ${peripheralAddress}, handle=${connection_handle}, mtu=${mtu}, rssi=${rssi ?? "n/a"}`
|
|
71
|
+
);
|
|
72
|
+
let detachObservers;
|
|
67
73
|
try {
|
|
68
|
-
const { services } = await
|
|
74
|
+
const { services } = await connection.sendCommand(BleProxyCommand.DiscoverServices, {
|
|
69
75
|
connection_handle
|
|
70
76
|
});
|
|
71
77
|
const matterService = services.find((s) => MatterBle.isServiceUuid(s.uuid));
|
|
72
78
|
if (!matterService) {
|
|
73
79
|
throw new BleError(`Peripheral ${peripheralAddress} does not have Matter BLE service`);
|
|
74
80
|
}
|
|
75
|
-
const { characteristics } = await
|
|
81
|
+
const { characteristics } = await connection.sendCommand(BleProxyCommand.DiscoverCharacteristics, {
|
|
76
82
|
connection_handle,
|
|
77
83
|
service_uuid: matterService.uuid
|
|
78
84
|
});
|
|
@@ -94,24 +100,11 @@ class ProxyBleCentralInterface {
|
|
|
94
100
|
}
|
|
95
101
|
if (c3Uuid && hasAdditionalAdvertisementData) {
|
|
96
102
|
logger.debug(`Reading additional commissioning data from C3`);
|
|
97
|
-
await
|
|
103
|
+
await connection.sendCommand(BleProxyCommand.ReadCharacteristic, {
|
|
98
104
|
connection_handle,
|
|
99
105
|
characteristic_uuid: c3Uuid
|
|
100
106
|
});
|
|
101
107
|
}
|
|
102
|
-
const btpHandshakeRequest = BtpCodec.encodeBtpHandshakeRequest({
|
|
103
|
-
versions: MatterBle.BTP_SUPPORTED_VERSIONS,
|
|
104
|
-
attMtu: mtu,
|
|
105
|
-
clientWindowSize: MatterBle.BTP_MAXIMUM_WINDOW_SIZE
|
|
106
|
-
});
|
|
107
|
-
logger.debug(`Sending BTP handshake request on C1 and subscribing C2 atomically`);
|
|
108
|
-
await this.#handler.sendCommand(BleProxyCommand.WriteAndSubscribe, {
|
|
109
|
-
connection_handle,
|
|
110
|
-
write_uuid: c1Uuid,
|
|
111
|
-
write_value: Buffer.from(btpHandshakeRequest).toString("base64"),
|
|
112
|
-
write_response: true,
|
|
113
|
-
subscribe_uuid: c2Uuid
|
|
114
|
-
});
|
|
115
108
|
const {
|
|
116
109
|
promise: handshakePromise,
|
|
117
110
|
resolver: handshakeResolver,
|
|
@@ -133,29 +126,61 @@ class ProxyBleCentralInterface {
|
|
|
133
126
|
}
|
|
134
127
|
}
|
|
135
128
|
};
|
|
136
|
-
|
|
129
|
+
connection.binaryFrameReceived.on(handshakeObserver);
|
|
130
|
+
const btpHandshakeRequest = BtpCodec.encodeBtpHandshakeRequest({
|
|
131
|
+
versions: MatterBle.BTP_SUPPORTED_VERSIONS,
|
|
132
|
+
attMtu: mtu,
|
|
133
|
+
clientWindowSize: MatterBle.BTP_MAXIMUM_WINDOW_SIZE
|
|
134
|
+
});
|
|
135
|
+
logger.debug(`Sending BTP handshake request on C1 and subscribing C2 atomically`);
|
|
137
136
|
let handshakeResponse;
|
|
138
137
|
try {
|
|
138
|
+
await connection.sendCommand(BleProxyCommand.WriteAndSubscribe, {
|
|
139
|
+
connection_handle,
|
|
140
|
+
write_uuid: c1Uuid,
|
|
141
|
+
write_value: Buffer.from(btpHandshakeRequest).toString("base64"),
|
|
142
|
+
write_response: true,
|
|
143
|
+
subscribe_uuid: c2Uuid
|
|
144
|
+
});
|
|
139
145
|
handshakeResponse = await handshakePromise;
|
|
140
146
|
} finally {
|
|
141
|
-
|
|
147
|
+
connection.binaryFrameReceived.off(handshakeObserver);
|
|
142
148
|
btpHandshakeTimeout.stop();
|
|
143
149
|
}
|
|
144
150
|
const onMatterMessageListener = this.#onMatterMessageListener;
|
|
145
151
|
const channelRef = {};
|
|
152
|
+
const sessionRef = {};
|
|
153
|
+
const earlyFrames = new Array();
|
|
154
|
+
const forwardToBtp = (payload) => {
|
|
155
|
+
sessionRef.session?.handleIncomingBleData(payload).catch(
|
|
156
|
+
(error) => logger.warn(`Peripheral ${peripheralAddress}: Error handling incoming BLE data`, error)
|
|
157
|
+
);
|
|
158
|
+
};
|
|
159
|
+
const binaryObserver = (frame) => {
|
|
160
|
+
if (frame.connectionHandle === connection_handle && frame.opcode === BinaryFrameOpcode.Notification) {
|
|
161
|
+
const payload = new Uint8Array(frame.payload);
|
|
162
|
+
if (sessionRef.session) {
|
|
163
|
+
forwardToBtp(payload);
|
|
164
|
+
} else {
|
|
165
|
+
earlyFrames.push(payload);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
connection.binaryFrameReceived.on(binaryObserver);
|
|
170
|
+
detachObservers = () => connection.binaryFrameReceived.off(binaryObserver);
|
|
146
171
|
const btpSession = await BtpSessionHandler.createAsCentral(
|
|
147
172
|
handshakeResponse,
|
|
148
173
|
// Write callback: send binary frame to proxy client
|
|
149
174
|
async (data) => {
|
|
150
175
|
const bytes = data instanceof Uint8Array ? data : new Uint8Array(data);
|
|
151
|
-
|
|
176
|
+
connection.sendBinaryFrame(BinaryFrameOpcode.WriteData, connection_handle, bytes);
|
|
152
177
|
},
|
|
153
178
|
// Disconnect callback
|
|
154
179
|
async () => {
|
|
155
180
|
if (!channelRef.channel?.connected) return;
|
|
156
181
|
logger.debug(`Disconnecting from ${peripheralAddress} via proxy`);
|
|
157
182
|
try {
|
|
158
|
-
await
|
|
183
|
+
await connection.sendCommand(BleProxyCommand.Disconnect, { connection_handle });
|
|
159
184
|
} catch (error) {
|
|
160
185
|
logger.debug(
|
|
161
186
|
`Peripheral ${peripheralAddress}: Error sending Disconnect to proxy client`,
|
|
@@ -171,14 +196,11 @@ class ProxyBleCentralInterface {
|
|
|
171
196
|
}
|
|
172
197
|
}
|
|
173
198
|
);
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
}
|
|
180
|
-
};
|
|
181
|
-
this.#handler.binaryFrameReceived.on(binaryObserver);
|
|
199
|
+
sessionRef.session = btpSession;
|
|
200
|
+
for (const payload of earlyFrames) {
|
|
201
|
+
forwardToBtp(payload);
|
|
202
|
+
}
|
|
203
|
+
earlyFrames.length = 0;
|
|
182
204
|
const eventObserver = (event, data) => {
|
|
183
205
|
if (event === BleProxyEvent.Disconnected && typeof data.connection_handle === "number" && data.connection_handle === connection_handle) {
|
|
184
206
|
logger.info(`Peripheral ${peripheralAddress} disconnected unexpectedly`);
|
|
@@ -186,17 +208,25 @@ class ProxyBleCentralInterface {
|
|
|
186
208
|
channelRef.channel?.close().catch((error) => logger.debug(`Peripheral ${peripheralAddress}: Error closing channel`, error));
|
|
187
209
|
}
|
|
188
210
|
};
|
|
189
|
-
|
|
190
|
-
const
|
|
191
|
-
|
|
192
|
-
|
|
211
|
+
connection.eventReceived.on(eventObserver);
|
|
212
|
+
const ownerClosedObserver = () => {
|
|
213
|
+
logger.info(`Owning proxy client for ${peripheralAddress} disconnected`);
|
|
214
|
+
channelRef.channel?.markDisconnected();
|
|
215
|
+
channelRef.channel?.close().catch((error) => logger.debug(`Peripheral ${peripheralAddress}: Error closing channel`, error));
|
|
216
|
+
};
|
|
217
|
+
connection.closed.on(ownerClosedObserver);
|
|
218
|
+
detachObservers = () => {
|
|
219
|
+
connection.binaryFrameReceived.off(binaryObserver);
|
|
220
|
+
connection.eventReceived.off(eventObserver);
|
|
221
|
+
connection.closed.off(ownerClosedObserver);
|
|
193
222
|
};
|
|
194
|
-
const proxyChannel = new ProxyBleChannel(peripheralAddress, btpSession,
|
|
223
|
+
const proxyChannel = new ProxyBleChannel(peripheralAddress, btpSession, detachObservers);
|
|
195
224
|
channelRef.channel = proxyChannel;
|
|
196
225
|
return proxyChannel;
|
|
197
226
|
} catch (error) {
|
|
227
|
+
detachObservers?.();
|
|
198
228
|
try {
|
|
199
|
-
await
|
|
229
|
+
await connection.sendCommand(BleProxyCommand.Disconnect, { connection_handle });
|
|
200
230
|
} catch (cleanupError) {
|
|
201
231
|
logger.debug(`Peripheral ${peripheralAddress}: Error during connect-failure cleanup`, cleanupError);
|
|
202
232
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/ProxyBleChannel.ts"],
|
|
4
|
-
"mappings": "AAAA;AAAA;AAAA;AAAA;AAAA;AAMA;AAAA,EAGI;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAEG;AACP,SAAS,YAAY,UAAU,UAAU,cAAc,mBAAmB,iBAAiB;AAE3F,SAAS,mBAAmB,iBAAiB,qBAAqB;AAGlE,MAAM,SAAS,OAAO,IAAI,iBAAiB;AAG3C,MAAM,kCAAkC;AACxC,MAAM,kCAAkC;AACxC,MAAM,gCAAgC;AAWtC,SAAS,gBAAgB,MAAsB;AAC3C,QAAM,QAAQ,KAAK,YAAY;AAC/B,MAAI,MAAM,WAAW,IAAI;AACrB,WAAO;AAAA,MACH,MAAM,UAAU,GAAG,CAAC;AAAA,MACpB,MAAM,UAAU,GAAG,EAAE;AAAA,MACrB,MAAM,UAAU,IAAI,EAAE;AAAA,MACtB,MAAM,UAAU,IAAI,EAAE;AAAA,MACtB,MAAM,UAAU,IAAI,EAAE;AAAA,IAC1B,EAAE,KAAK,GAAG;AAAA,EACd;AACA,SAAO;AACX;AAMO,MAAM,yBAA8C;AAAA,EAC9C;AAAA,EACA;AAAA,EACT;AAAA,EACA,UAAU;AAAA,EAEV,YAAY,YAA6B,SAA0B;AAC/D,SAAK,cAAc;AACnB,SAAK,WAAW;AAAA,EACpB;AAAA,EAEA,MAAM,YAAY,SAAiD;AAC/D,QAAI,KAAK,SAAS;AACd,YAAM,IAAI,aAAa,6BAA6B;AAAA,IACxD;AACA,QAAI,CAAC,cAAc,MAAM,OAAO,GAAG;AAC/B,YAAM,IAAI,cAAc,2CAA2C;AAAA,IACvE;AACA,QAAI,KAAK,6BAA6B,QAAW;AAC7C,YAAM,IAAI,cAAc,oDAAoD;AAAA,IAChF;AAEA,UAAM,EAAE,kBAAkB,IAAI;
|
|
4
|
+
"mappings": "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",
|
|
5
5
|
"names": []
|
|
6
6
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProxyBleClient.d.ts","sourceRoot":"","sources":["../../src/ProxyBleClient.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"ProxyBleClient.d.ts","sourceRoot":"","sources":["../../src/ProxyBleClient.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAa5D;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACrC,GAAG,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,qBAAa,cAAc;;IAevB,YAAY,OAAO,EAAE,eAAe,EAInC;IAED,oBAAoB,CAAC,QAAQ,EAAE,CAAC,UAAU,EAAE,eAAe,EAAE,iBAAiB,EAAE,UAAU,KAAK,IAAI,GAAG,IAAI,CAKzG;IAEK,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CA0BnC;IAEK,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAOlC;IAED,KAAK,IAAI,IAAI,CAIZ;CA2CJ"}
|