@matter/react-native 0.16.0-alpha.0-20251001-7eb06da95 → 0.16.0-alpha.0-20251004-92135c7df
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/cjs/ble/ReactNativeBle.d.ts +2 -2
- package/dist/cjs/ble/ReactNativeBle.d.ts.map +1 -1
- package/dist/cjs/ble/ReactNativeBle.js.map +1 -1
- package/dist/cjs/ble/ReactNativeBleChannel.d.ts +3 -3
- package/dist/cjs/ble/ReactNativeBleChannel.d.ts.map +1 -1
- package/dist/cjs/ble/ReactNativeBleChannel.js +25 -36
- package/dist/cjs/ble/ReactNativeBleChannel.js.map +1 -1
- package/dist/esm/ble/ReactNativeBle.d.ts +2 -2
- package/dist/esm/ble/ReactNativeBle.d.ts.map +1 -1
- package/dist/esm/ble/ReactNativeBle.js.map +1 -1
- package/dist/esm/ble/ReactNativeBleChannel.d.ts +3 -3
- package/dist/esm/ble/ReactNativeBleChannel.d.ts.map +1 -1
- package/dist/esm/ble/ReactNativeBleChannel.js +25 -36
- package/dist/esm/ble/ReactNativeBleChannel.js.map +1 -1
- package/package.json +5 -5
- package/src/ble/ReactNativeBle.ts +2 -2
- package/src/ble/ReactNativeBleChannel.ts +39 -49
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
* Copyright 2022-2025 Matter.js Authors
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
|
-
import { ChannelType,
|
|
6
|
+
import { ChannelType, ConnectionlessTransport } from "#general";
|
|
7
7
|
import { Ble, BlePeripheralInterface, Scanner } from "#protocol";
|
|
8
8
|
export declare class ReactNativeBle extends Ble {
|
|
9
9
|
private bleCentral;
|
|
10
10
|
constructor();
|
|
11
|
-
get centralInterface():
|
|
11
|
+
get centralInterface(): ConnectionlessTransport;
|
|
12
12
|
get scanner(): Scanner;
|
|
13
13
|
get peripheralInterface(): BlePeripheralInterface;
|
|
14
14
|
supports(type: ChannelType): type is ChannelType.BLE;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ReactNativeBle.d.ts","sourceRoot":"","sources":["../../../src/ble/ReactNativeBle.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,WAAW,
|
|
1
|
+
{"version":3,"file":"ReactNativeBle.d.ts","sourceRoot":"","sources":["../../../src/ble/ReactNativeBle.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,WAAW,EAAE,uBAAuB,EAAuB,MAAM,UAAU,CAAC;AACrF,OAAO,EAAE,GAAG,EAAE,sBAAsB,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKjE,qBAAa,cAAe,SAAQ,GAAG;IACnC,OAAO,CAAC,UAAU,CAAmC;;IAMrD,IAAI,gBAAgB,IAAI,uBAAuB,CAK9C;IAED,IAAI,OAAO,IAAI,OAAO,CAKrB;IAED,IAAI,mBAAmB,IAAI,sBAAsB,CAEhD;IAED,QAAQ,CAAC,IAAI,EAAE,WAAW;CAG7B"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/ble/ReactNativeBle.ts"],
|
|
4
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,
|
|
4
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,qBAA0E;AAC1E,sBAAqD;AACrD,wBAA2B;AAC3B,mCAA+C;AAC/C,kCAAqC;AAVrC;AAAA;AAAA;AAAA;AAAA;AAYO,MAAM,uBAAuB,oBAAI;AAAA,EAC5B;AAAA,EAER,cAAc;AACV,UAAM;AAAA,EACV;AAAA,EAEA,IAAI,mBAA4C;AAC5C,QAAI,KAAK,eAAe,QAAW;AAC/B,WAAK,aAAa,IAAI,iDAAqB;AAAA,IAC/C;AACA,WAAO,IAAI,4DAA+B,IAAI;AAAA,EAClD;AAAA,EAEA,IAAI,UAAmB;AACnB,QAAI,KAAK,eAAe,QAAW;AAC/B,WAAK,aAAa,IAAI,iDAAqB;AAAA,IAC/C;AACA,WAAO,IAAI,6BAAW,KAAK,UAAU;AAAA,EACzC;AAAA,EAEA,IAAI,sBAA8C;AAC9C,UAAM,IAAI,mCAAoB,kEAAkE;AAAA,EACpG;AAAA,EAEA,SAAS,MAAmB;AACxB,WAAO,SAAS,2BAAY;AAAA,EAChC;AACJ;",
|
|
5
5
|
"names": []
|
|
6
6
|
}
|
|
@@ -3,14 +3,14 @@
|
|
|
3
3
|
* Copyright 2022-2025 Matter.js Authors
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
|
-
import { Bytes, Channel, ChannelType,
|
|
6
|
+
import { Bytes, Channel, ChannelType, ConnectionlessTransport, ServerAddress } from "#general";
|
|
7
7
|
import { Ble, BleChannel, BtpSessionHandler } from "#protocol";
|
|
8
8
|
import { Characteristic, Device } from "react-native-ble-plx";
|
|
9
|
-
export declare class ReactNativeBleCentralInterface implements
|
|
9
|
+
export declare class ReactNativeBleCentralInterface implements ConnectionlessTransport {
|
|
10
10
|
#private;
|
|
11
11
|
constructor(ble: Ble);
|
|
12
12
|
openChannel(address: ServerAddress): Promise<Channel<Bytes>>;
|
|
13
|
-
onData(listener: (socket: Channel<Bytes>, data: Bytes) => void):
|
|
13
|
+
onData(listener: (socket: Channel<Bytes>, data: Bytes) => void): ConnectionlessTransport.Listener;
|
|
14
14
|
close(): Promise<void>;
|
|
15
15
|
supports(type: ChannelType): type is ChannelType.BLE;
|
|
16
16
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ReactNativeBleChannel.d.ts","sourceRoot":"","sources":["../../../src/ble/ReactNativeBleChannel.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACH,KAAK,EACL,OAAO,EACP,WAAW,
|
|
1
|
+
{"version":3,"file":"ReactNativeBleChannel.d.ts","sourceRoot":"","sources":["../../../src/ble/ReactNativeBleChannel.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACH,KAAK,EACL,OAAO,EACP,WAAW,EACX,uBAAuB,EAIvB,aAAa,EAGhB,MAAM,UAAU,CAAC;AAClB,OAAO,EASH,GAAG,EACH,UAAU,EAIV,iBAAiB,EACpB,MAAM,WAAW,CAAC;AACnB,OAAO,EAEH,cAAc,EACd,MAAM,EAGT,MAAM,sBAAsB,CAAC;AAK9B,qBAAa,8BAA+B,YAAW,uBAAuB;;gBAK9D,GAAG,EAAE,GAAG;IAId,WAAW,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IA8FlE,MAAM,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,KAAK,KAAK,IAAI,GAAG,uBAAuB,CAAC,QAAQ;IAO3F,KAAK;IAMX,QAAQ,CAAC,IAAI,EAAE,WAAW;CAG7B;AAED,qBAAa,qBAAsB,SAAQ,UAAU,CAAC,KAAK,CAAC;IA4GpD,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,UAAU;WA5GlB,MAAM,CACf,UAAU,EAAE,MAAM,EAClB,wBAAwB,EAAE,cAAc,EACxC,4BAA4B,EAAE,cAAc,EAC5C,uBAAuB,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,KAAK,KAAK,IAAI,EACtE,mCAAmC,CAAC,EAAE,KAAK,GAC5C,OAAO,CAAC,qBAAqB,CAAC;IAiGjC,OAAO,CAAC,SAAS,CAAQ;IACzB,OAAO,CAAC,sBAAsB,CAAe;gBAGxB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,iBAAiB;IAWlD;;;;OAIG;IACG,IAAI,CAAC,IAAI,EAAE,KAAK;IAYtB,IAAI,IAAI,WAEP;IAEK,KAAK;CAMd"}
|
|
@@ -163,15 +163,13 @@ class ReactNativeBleChannel extends import_protocol.BleChannel {
|
|
|
163
163
|
logger.debug("subscribing to C2 characteristic");
|
|
164
164
|
const { promise: handshakeResponseReceivedPromise, resolver } = (0, import_general.createPromise)();
|
|
165
165
|
let handshakeReceived = false;
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
return;
|
|
169
|
-
}
|
|
166
|
+
let btpSession = void 0;
|
|
167
|
+
const characteristicSubscribe = characteristicC2ForSubscribe.monitor((error, characteristic) => {
|
|
170
168
|
if (error !== null || characteristic === null) {
|
|
171
|
-
if (error instanceof import_react_native_ble_plx.BleError && error.errorCode === 2
|
|
169
|
+
if (error instanceof import_react_native_ble_plx.BleError && error.errorCode === 2) {
|
|
172
170
|
return;
|
|
173
171
|
}
|
|
174
|
-
logger.debug("Error while monitoring C2 characteristic", error);
|
|
172
|
+
logger.debug("Error while monitoring C2 characteristic.", error?.message);
|
|
175
173
|
return;
|
|
176
174
|
}
|
|
177
175
|
const characteristicData = characteristic.value;
|
|
@@ -179,18 +177,25 @@ class ReactNativeBleChannel extends import_protocol.BleChannel {
|
|
|
179
177
|
logger.debug("C2 characteristic value is null");
|
|
180
178
|
return;
|
|
181
179
|
}
|
|
182
|
-
const data = import_general.Bytes.
|
|
183
|
-
logger.debug(`received
|
|
184
|
-
if (
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
180
|
+
const data = import_general.Bytes.fromBase64(characteristicData);
|
|
181
|
+
logger.debug(`received data on C2: ${import_general.Bytes.toHex(data)}`);
|
|
182
|
+
if (!handshakeReceived) {
|
|
183
|
+
const _data = import_general.Bytes.of(data);
|
|
184
|
+
if (_data[0] === 101 && _data[1] === 108 && _data.length === 6) {
|
|
185
|
+
logger.info(`Received Matter handshake response: ${import_general.Bytes.toHex(_data)}.`);
|
|
186
|
+
btpHandshakeTimeout.stop();
|
|
187
|
+
handshakeReceived = true;
|
|
188
|
+
resolver(_data);
|
|
189
|
+
}
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
if (btpSession) {
|
|
193
|
+
btpSession.handleIncomingBleData(data).catch(() => {
|
|
194
|
+
});
|
|
188
195
|
}
|
|
189
196
|
});
|
|
190
197
|
const handshakeResponse = await handshakeResponseReceivedPromise;
|
|
191
|
-
|
|
192
|
-
let connectionCloseExpected = false;
|
|
193
|
-
const btpSession = await import_protocol.BtpSessionHandler.createAsCentral(
|
|
198
|
+
btpSession = await import_protocol.BtpSessionHandler.createAsCentral(
|
|
194
199
|
handshakeResponse,
|
|
195
200
|
// callback to write data to characteristic C1
|
|
196
201
|
async (data) => {
|
|
@@ -198,8 +203,10 @@ class ReactNativeBleChannel extends import_protocol.BleChannel {
|
|
|
198
203
|
},
|
|
199
204
|
// callback to disconnect the BLE connection
|
|
200
205
|
async () => {
|
|
201
|
-
|
|
202
|
-
await peripheral.
|
|
206
|
+
characteristicSubscribe.remove();
|
|
207
|
+
if (await peripheral.isConnected()) {
|
|
208
|
+
await peripheral.cancelConnection();
|
|
209
|
+
}
|
|
203
210
|
logger.debug("disconnected from peripheral");
|
|
204
211
|
},
|
|
205
212
|
// callback to forward decoded and de-assembled Matter messages to ExchangeManager
|
|
@@ -210,23 +217,6 @@ class ReactNativeBleChannel extends import_protocol.BleChannel {
|
|
|
210
217
|
onMatterMessageListener(bleChannel, data);
|
|
211
218
|
}
|
|
212
219
|
);
|
|
213
|
-
characteristicC2ForSubscribe.monitor((error, characteristic) => {
|
|
214
|
-
if (error !== null || characteristic === null) {
|
|
215
|
-
if (error instanceof import_react_native_ble_plx.BleError && error.errorCode === 2 && connectionCloseExpected) {
|
|
216
|
-
return;
|
|
217
|
-
}
|
|
218
|
-
logger.debug("Error while monitoring C2 characteristic", error);
|
|
219
|
-
return;
|
|
220
|
-
}
|
|
221
|
-
const characteristicData = characteristic.value;
|
|
222
|
-
if (characteristicData === null) {
|
|
223
|
-
logger.debug("C2 characteristic value is null");
|
|
224
|
-
return;
|
|
225
|
-
}
|
|
226
|
-
const data = import_general.Bytes.fromBase64(characteristicData);
|
|
227
|
-
logger.debug(`received data on C2: ${import_general.Bytes.toHex(data)}`);
|
|
228
|
-
void btpSession.handleIncomingBleData(data);
|
|
229
|
-
});
|
|
230
220
|
const bleChannel = new ReactNativeBleChannel(peripheral, btpSession);
|
|
231
221
|
return bleChannel;
|
|
232
222
|
}
|
|
@@ -252,9 +242,8 @@ class ReactNativeBleChannel extends import_protocol.BleChannel {
|
|
|
252
242
|
return `ble://${this.peripheral.id}`;
|
|
253
243
|
}
|
|
254
244
|
async close() {
|
|
255
|
-
await this.btpSession.close();
|
|
256
245
|
this.disconnectSubscription.remove();
|
|
257
|
-
await this.
|
|
246
|
+
await this.btpSession.close();
|
|
258
247
|
}
|
|
259
248
|
}
|
|
260
249
|
//# sourceMappingURL=ReactNativeBleChannel.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/ble/ReactNativeBleChannel.ts"],
|
|
4
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,
|
|
4
|
+
"mappings": "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",
|
|
5
5
|
"names": ["ReactNativeBleError"]
|
|
6
6
|
}
|
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
* Copyright 2022-2025 Matter.js Authors
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
|
-
import { ChannelType,
|
|
6
|
+
import { ChannelType, ConnectionlessTransport } from "#general";
|
|
7
7
|
import { Ble, BlePeripheralInterface, Scanner } from "#protocol";
|
|
8
8
|
export declare class ReactNativeBle extends Ble {
|
|
9
9
|
private bleCentral;
|
|
10
10
|
constructor();
|
|
11
|
-
get centralInterface():
|
|
11
|
+
get centralInterface(): ConnectionlessTransport;
|
|
12
12
|
get scanner(): Scanner;
|
|
13
13
|
get peripheralInterface(): BlePeripheralInterface;
|
|
14
14
|
supports(type: ChannelType): type is ChannelType.BLE;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ReactNativeBle.d.ts","sourceRoot":"","sources":["../../../src/ble/ReactNativeBle.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,WAAW,
|
|
1
|
+
{"version":3,"file":"ReactNativeBle.d.ts","sourceRoot":"","sources":["../../../src/ble/ReactNativeBle.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,WAAW,EAAE,uBAAuB,EAAuB,MAAM,UAAU,CAAC;AACrF,OAAO,EAAE,GAAG,EAAE,sBAAsB,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKjE,qBAAa,cAAe,SAAQ,GAAG;IACnC,OAAO,CAAC,UAAU,CAAmC;;IAMrD,IAAI,gBAAgB,IAAI,uBAAuB,CAK9C;IAED,IAAI,OAAO,IAAI,OAAO,CAKrB;IAED,IAAI,mBAAmB,IAAI,sBAAsB,CAEhD;IAED,QAAQ,CAAC,IAAI,EAAE,WAAW;CAG7B"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/ble/ReactNativeBle.ts"],
|
|
4
|
-
"mappings": "AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,SAAS,
|
|
4
|
+
"mappings": "AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,SAAS,aAAsC,2BAA2B;AAC1E,SAAS,WAA4C;AACrD,SAAS,kBAAkB;AAC3B,SAAS,sCAAsC;AAC/C,SAAS,4BAA4B;AAE9B,MAAM,uBAAuB,IAAI;AAAA,EAC5B;AAAA,EAER,cAAc;AACV,UAAM;AAAA,EACV;AAAA,EAEA,IAAI,mBAA4C;AAC5C,QAAI,KAAK,eAAe,QAAW;AAC/B,WAAK,aAAa,IAAI,qBAAqB;AAAA,IAC/C;AACA,WAAO,IAAI,+BAA+B,IAAI;AAAA,EAClD;AAAA,EAEA,IAAI,UAAmB;AACnB,QAAI,KAAK,eAAe,QAAW;AAC/B,WAAK,aAAa,IAAI,qBAAqB;AAAA,IAC/C;AACA,WAAO,IAAI,WAAW,KAAK,UAAU;AAAA,EACzC;AAAA,EAEA,IAAI,sBAA8C;AAC9C,UAAM,IAAI,oBAAoB,kEAAkE;AAAA,EACpG;AAAA,EAEA,SAAS,MAAmB;AACxB,WAAO,SAAS,YAAY;AAAA,EAChC;AACJ;",
|
|
5
5
|
"names": []
|
|
6
6
|
}
|
|
@@ -3,14 +3,14 @@
|
|
|
3
3
|
* Copyright 2022-2025 Matter.js Authors
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
|
-
import { Bytes, Channel, ChannelType,
|
|
6
|
+
import { Bytes, Channel, ChannelType, ConnectionlessTransport, ServerAddress } from "#general";
|
|
7
7
|
import { Ble, BleChannel, BtpSessionHandler } from "#protocol";
|
|
8
8
|
import { Characteristic, Device } from "react-native-ble-plx";
|
|
9
|
-
export declare class ReactNativeBleCentralInterface implements
|
|
9
|
+
export declare class ReactNativeBleCentralInterface implements ConnectionlessTransport {
|
|
10
10
|
#private;
|
|
11
11
|
constructor(ble: Ble);
|
|
12
12
|
openChannel(address: ServerAddress): Promise<Channel<Bytes>>;
|
|
13
|
-
onData(listener: (socket: Channel<Bytes>, data: Bytes) => void):
|
|
13
|
+
onData(listener: (socket: Channel<Bytes>, data: Bytes) => void): ConnectionlessTransport.Listener;
|
|
14
14
|
close(): Promise<void>;
|
|
15
15
|
supports(type: ChannelType): type is ChannelType.BLE;
|
|
16
16
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ReactNativeBleChannel.d.ts","sourceRoot":"","sources":["../../../src/ble/ReactNativeBleChannel.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACH,KAAK,EACL,OAAO,EACP,WAAW,
|
|
1
|
+
{"version":3,"file":"ReactNativeBleChannel.d.ts","sourceRoot":"","sources":["../../../src/ble/ReactNativeBleChannel.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACH,KAAK,EACL,OAAO,EACP,WAAW,EACX,uBAAuB,EAIvB,aAAa,EAGhB,MAAM,UAAU,CAAC;AAClB,OAAO,EASH,GAAG,EACH,UAAU,EAIV,iBAAiB,EACpB,MAAM,WAAW,CAAC;AACnB,OAAO,EAEH,cAAc,EACd,MAAM,EAGT,MAAM,sBAAsB,CAAC;AAK9B,qBAAa,8BAA+B,YAAW,uBAAuB;;gBAK9D,GAAG,EAAE,GAAG;IAId,WAAW,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IA8FlE,MAAM,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,KAAK,KAAK,IAAI,GAAG,uBAAuB,CAAC,QAAQ;IAO3F,KAAK;IAMX,QAAQ,CAAC,IAAI,EAAE,WAAW;CAG7B;AAED,qBAAa,qBAAsB,SAAQ,UAAU,CAAC,KAAK,CAAC;IA4GpD,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,UAAU;WA5GlB,MAAM,CACf,UAAU,EAAE,MAAM,EAClB,wBAAwB,EAAE,cAAc,EACxC,4BAA4B,EAAE,cAAc,EAC5C,uBAAuB,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,KAAK,KAAK,IAAI,EACtE,mCAAmC,CAAC,EAAE,KAAK,GAC5C,OAAO,CAAC,qBAAqB,CAAC;IAiGjC,OAAO,CAAC,SAAS,CAAQ;IACzB,OAAO,CAAC,sBAAsB,CAAe;gBAGxB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,iBAAiB;IAWlD;;;;OAIG;IACG,IAAI,CAAC,IAAI,EAAE,KAAK;IAYtB,IAAI,IAAI,WAEP;IAEK,KAAK;CAMd"}
|
|
@@ -164,15 +164,13 @@ class ReactNativeBleChannel extends BleChannel {
|
|
|
164
164
|
logger.debug("subscribing to C2 characteristic");
|
|
165
165
|
const { promise: handshakeResponseReceivedPromise, resolver } = createPromise();
|
|
166
166
|
let handshakeReceived = false;
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
return;
|
|
170
|
-
}
|
|
167
|
+
let btpSession = void 0;
|
|
168
|
+
const characteristicSubscribe = characteristicC2ForSubscribe.monitor((error, characteristic) => {
|
|
171
169
|
if (error !== null || characteristic === null) {
|
|
172
|
-
if (error instanceof ReactNativeBleError && error.errorCode === 2
|
|
170
|
+
if (error instanceof ReactNativeBleError && error.errorCode === 2) {
|
|
173
171
|
return;
|
|
174
172
|
}
|
|
175
|
-
logger.debug("Error while monitoring C2 characteristic", error);
|
|
173
|
+
logger.debug("Error while monitoring C2 characteristic.", error?.message);
|
|
176
174
|
return;
|
|
177
175
|
}
|
|
178
176
|
const characteristicData = characteristic.value;
|
|
@@ -180,18 +178,25 @@ class ReactNativeBleChannel extends BleChannel {
|
|
|
180
178
|
logger.debug("C2 characteristic value is null");
|
|
181
179
|
return;
|
|
182
180
|
}
|
|
183
|
-
const data = Bytes.
|
|
184
|
-
logger.debug(`received
|
|
185
|
-
if (
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
181
|
+
const data = Bytes.fromBase64(characteristicData);
|
|
182
|
+
logger.debug(`received data on C2: ${Bytes.toHex(data)}`);
|
|
183
|
+
if (!handshakeReceived) {
|
|
184
|
+
const _data = Bytes.of(data);
|
|
185
|
+
if (_data[0] === 101 && _data[1] === 108 && _data.length === 6) {
|
|
186
|
+
logger.info(`Received Matter handshake response: ${Bytes.toHex(_data)}.`);
|
|
187
|
+
btpHandshakeTimeout.stop();
|
|
188
|
+
handshakeReceived = true;
|
|
189
|
+
resolver(_data);
|
|
190
|
+
}
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
if (btpSession) {
|
|
194
|
+
btpSession.handleIncomingBleData(data).catch(() => {
|
|
195
|
+
});
|
|
189
196
|
}
|
|
190
197
|
});
|
|
191
198
|
const handshakeResponse = await handshakeResponseReceivedPromise;
|
|
192
|
-
|
|
193
|
-
let connectionCloseExpected = false;
|
|
194
|
-
const btpSession = await BtpSessionHandler.createAsCentral(
|
|
199
|
+
btpSession = await BtpSessionHandler.createAsCentral(
|
|
195
200
|
handshakeResponse,
|
|
196
201
|
// callback to write data to characteristic C1
|
|
197
202
|
async (data) => {
|
|
@@ -199,8 +204,10 @@ class ReactNativeBleChannel extends BleChannel {
|
|
|
199
204
|
},
|
|
200
205
|
// callback to disconnect the BLE connection
|
|
201
206
|
async () => {
|
|
202
|
-
|
|
203
|
-
await peripheral.
|
|
207
|
+
characteristicSubscribe.remove();
|
|
208
|
+
if (await peripheral.isConnected()) {
|
|
209
|
+
await peripheral.cancelConnection();
|
|
210
|
+
}
|
|
204
211
|
logger.debug("disconnected from peripheral");
|
|
205
212
|
},
|
|
206
213
|
// callback to forward decoded and de-assembled Matter messages to ExchangeManager
|
|
@@ -211,23 +218,6 @@ class ReactNativeBleChannel extends BleChannel {
|
|
|
211
218
|
onMatterMessageListener(bleChannel, data);
|
|
212
219
|
}
|
|
213
220
|
);
|
|
214
|
-
characteristicC2ForSubscribe.monitor((error, characteristic) => {
|
|
215
|
-
if (error !== null || characteristic === null) {
|
|
216
|
-
if (error instanceof ReactNativeBleError && error.errorCode === 2 && connectionCloseExpected) {
|
|
217
|
-
return;
|
|
218
|
-
}
|
|
219
|
-
logger.debug("Error while monitoring C2 characteristic", error);
|
|
220
|
-
return;
|
|
221
|
-
}
|
|
222
|
-
const characteristicData = characteristic.value;
|
|
223
|
-
if (characteristicData === null) {
|
|
224
|
-
logger.debug("C2 characteristic value is null");
|
|
225
|
-
return;
|
|
226
|
-
}
|
|
227
|
-
const data = Bytes.fromBase64(characteristicData);
|
|
228
|
-
logger.debug(`received data on C2: ${Bytes.toHex(data)}`);
|
|
229
|
-
void btpSession.handleIncomingBleData(data);
|
|
230
|
-
});
|
|
231
221
|
const bleChannel = new ReactNativeBleChannel(peripheral, btpSession);
|
|
232
222
|
return bleChannel;
|
|
233
223
|
}
|
|
@@ -253,9 +243,8 @@ class ReactNativeBleChannel extends BleChannel {
|
|
|
253
243
|
return `ble://${this.peripheral.id}`;
|
|
254
244
|
}
|
|
255
245
|
async close() {
|
|
256
|
-
await this.btpSession.close();
|
|
257
246
|
this.disconnectSubscription.remove();
|
|
258
|
-
await this.
|
|
247
|
+
await this.btpSession.close();
|
|
259
248
|
}
|
|
260
249
|
}
|
|
261
250
|
export {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/ble/ReactNativeBleChannel.ts"],
|
|
4
|
-
"mappings": "AAAA;AAAA;AAAA;AAAA;AAAA;AAMA;AAAA,EACI;AAAA,EAEA;AAAA,
|
|
4
|
+
"mappings": "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",
|
|
5
5
|
"names": []
|
|
6
6
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@matter/react-native",
|
|
3
|
-
"version": "0.16.0-alpha.0-
|
|
3
|
+
"version": "0.16.0-alpha.0-20251004-92135c7df",
|
|
4
4
|
"description": "Experimental React Native support for matter.js",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"iot",
|
|
@@ -36,9 +36,9 @@
|
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"@craftzdog/react-native-buffer": "6.1.0",
|
|
39
|
-
"@matter/general": "0.16.0-alpha.0-
|
|
40
|
-
"@matter/nodejs": "0.16.0-alpha.0-
|
|
41
|
-
"@matter/protocol": "0.16.0-alpha.0-
|
|
39
|
+
"@matter/general": "0.16.0-alpha.0-20251004-92135c7df",
|
|
40
|
+
"@matter/nodejs": "0.16.0-alpha.0-20251004-92135c7df",
|
|
41
|
+
"@matter/protocol": "0.16.0-alpha.0-20251004-92135c7df",
|
|
42
42
|
"@react-native-async-storage/async-storage": "^2.2.0",
|
|
43
43
|
"@react-native-community/netinfo": "^11.4.1",
|
|
44
44
|
"@types/node": "^24.4.0",
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"react-native-udp": "^4.1.7"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
|
-
"@matter/tools": "0.16.0-alpha.0-
|
|
51
|
+
"@matter/tools": "0.16.0-alpha.0-20251004-92135c7df"
|
|
52
52
|
},
|
|
53
53
|
"overrides": {
|
|
54
54
|
"brorand": "npm:@matter.js/brorand@1.1.0"
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import { ChannelType,
|
|
7
|
+
import { ChannelType, ConnectionlessTransport, ImplementationError } from "#general";
|
|
8
8
|
import { Ble, BlePeripheralInterface, Scanner } from "#protocol";
|
|
9
9
|
import { BleScanner } from "./BleScanner.js";
|
|
10
10
|
import { ReactNativeBleCentralInterface } from "./ReactNativeBleChannel.js";
|
|
@@ -17,7 +17,7 @@ export class ReactNativeBle extends Ble {
|
|
|
17
17
|
super();
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
get centralInterface():
|
|
20
|
+
get centralInterface(): ConnectionlessTransport {
|
|
21
21
|
if (this.bleCentral === undefined) {
|
|
22
22
|
this.bleCentral = new ReactNativeBleClient();
|
|
23
23
|
}
|
|
@@ -8,13 +8,12 @@ import {
|
|
|
8
8
|
Bytes,
|
|
9
9
|
Channel,
|
|
10
10
|
ChannelType,
|
|
11
|
+
ConnectionlessTransport,
|
|
11
12
|
Diagnostic,
|
|
12
13
|
InternalError,
|
|
13
14
|
Logger,
|
|
14
|
-
NetInterface,
|
|
15
15
|
ServerAddress,
|
|
16
16
|
Time,
|
|
17
|
-
TransportInterface,
|
|
18
17
|
createPromise,
|
|
19
18
|
} from "#general";
|
|
20
19
|
import {
|
|
@@ -44,7 +43,7 @@ import { BleScanner } from "./BleScanner.js";
|
|
|
44
43
|
|
|
45
44
|
const logger = Logger.get("BleChannel");
|
|
46
45
|
|
|
47
|
-
export class ReactNativeBleCentralInterface implements
|
|
46
|
+
export class ReactNativeBleCentralInterface implements ConnectionlessTransport {
|
|
48
47
|
#ble: Ble;
|
|
49
48
|
#openChannels: Map<ServerAddress, Device> = new Map();
|
|
50
49
|
#onMatterMessageListener: ((socket: Channel<Bytes>, data: Bytes) => void) | undefined;
|
|
@@ -147,7 +146,7 @@ export class ReactNativeBleCentralInterface implements NetInterface {
|
|
|
147
146
|
throw new BleError(`No Matter service found on peripheral ${device.id}`);
|
|
148
147
|
}
|
|
149
148
|
|
|
150
|
-
onData(listener: (socket: Channel<Bytes>, data: Bytes) => void):
|
|
149
|
+
onData(listener: (socket: Channel<Bytes>, data: Bytes) => void): ConnectionlessTransport.Listener {
|
|
151
150
|
this.#onMatterMessageListener = listener;
|
|
152
151
|
return {
|
|
153
152
|
close: async () => await this.close(),
|
|
@@ -198,18 +197,15 @@ export class ReactNativeBleChannel extends BleChannel<Bytes> {
|
|
|
198
197
|
const { promise: handshakeResponseReceivedPromise, resolver } = createPromise<Bytes>();
|
|
199
198
|
|
|
200
199
|
let handshakeReceived = false;
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
// Make sure data potentially submitted here after handshake was received are ignored
|
|
205
|
-
return;
|
|
206
|
-
}
|
|
200
|
+
let btpSession: BtpSessionHandler | undefined = undefined;
|
|
201
|
+
|
|
202
|
+
const characteristicSubscribe = characteristicC2ForSubscribe.monitor((error, characteristic) => {
|
|
207
203
|
if (error !== null || characteristic === null) {
|
|
208
|
-
if (error instanceof ReactNativeBleError && error.errorCode === 2
|
|
209
|
-
// Subscription got removed
|
|
204
|
+
if (error instanceof ReactNativeBleError && error.errorCode === 2) {
|
|
205
|
+
// Subscription got removed and received, all good
|
|
210
206
|
return;
|
|
211
207
|
}
|
|
212
|
-
logger.debug("Error while monitoring C2 characteristic", error);
|
|
208
|
+
logger.debug("Error while monitoring C2 characteristic.", error?.message);
|
|
213
209
|
return;
|
|
214
210
|
}
|
|
215
211
|
const characteristicData = characteristic.value;
|
|
@@ -217,22 +213,32 @@ export class ReactNativeBleChannel extends BleChannel<Bytes> {
|
|
|
217
213
|
logger.debug("C2 characteristic value is null");
|
|
218
214
|
return;
|
|
219
215
|
}
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
216
|
+
|
|
217
|
+
const data = Bytes.fromBase64(characteristicData);
|
|
218
|
+
logger.debug(`received data on C2: ${Bytes.toHex(data)}`);
|
|
219
|
+
|
|
220
|
+
if (!handshakeReceived) {
|
|
221
|
+
// 1. waiting for a successful handshake
|
|
222
|
+
const _data = Bytes.of(data);
|
|
223
|
+
if (_data[0] === 0x65 && _data[1] === 0x6c && _data.length === 6) {
|
|
224
|
+
// Check if the first two bytes and length match the Matter handshake
|
|
225
|
+
logger.info(`Received Matter handshake response: ${Bytes.toHex(_data)}.`);
|
|
226
|
+
btpHandshakeTimeout.stop();
|
|
227
|
+
handshakeReceived = true;
|
|
228
|
+
resolver(_data);
|
|
229
|
+
}
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// 2. then handle Incoming Data - btpSession is guaranteed to be set after handshake
|
|
234
|
+
if (btpSession) {
|
|
235
|
+
btpSession.handleIncomingBleData(data).catch(() => {});
|
|
228
236
|
}
|
|
229
237
|
});
|
|
230
238
|
|
|
231
239
|
const handshakeResponse = await handshakeResponseReceivedPromise;
|
|
232
|
-
handshakeReceived = true;
|
|
233
240
|
|
|
234
|
-
|
|
235
|
-
const btpSession = await BtpSessionHandler.createAsCentral(
|
|
241
|
+
btpSession = await BtpSessionHandler.createAsCentral(
|
|
236
242
|
handshakeResponse,
|
|
237
243
|
// callback to write data to characteristic C1
|
|
238
244
|
async data => {
|
|
@@ -240,8 +246,12 @@ export class ReactNativeBleChannel extends BleChannel<Bytes> {
|
|
|
240
246
|
},
|
|
241
247
|
// callback to disconnect the BLE connection
|
|
242
248
|
async () => {
|
|
243
|
-
|
|
244
|
-
|
|
249
|
+
// First, unsubscribe from characteristic
|
|
250
|
+
characteristicSubscribe.remove();
|
|
251
|
+
// Then, cancel the connection
|
|
252
|
+
if (await peripheral.isConnected()) {
|
|
253
|
+
await peripheral.cancelConnection();
|
|
254
|
+
}
|
|
245
255
|
logger.debug("disconnected from peripheral");
|
|
246
256
|
},
|
|
247
257
|
|
|
@@ -254,27 +264,6 @@ export class ReactNativeBleChannel extends BleChannel<Bytes> {
|
|
|
254
264
|
},
|
|
255
265
|
);
|
|
256
266
|
|
|
257
|
-
// ignore the response because it seems when we remove a subscription the whole connection is closed
|
|
258
|
-
characteristicC2ForSubscribe.monitor((error, characteristic) => {
|
|
259
|
-
if (error !== null || characteristic === null) {
|
|
260
|
-
if (error instanceof ReactNativeBleError && error.errorCode === 2 && connectionCloseExpected) {
|
|
261
|
-
// Subscription got removed and received, all good
|
|
262
|
-
return;
|
|
263
|
-
}
|
|
264
|
-
logger.debug("Error while monitoring C2 characteristic", error);
|
|
265
|
-
return;
|
|
266
|
-
}
|
|
267
|
-
const characteristicData = characteristic.value;
|
|
268
|
-
if (characteristicData === null) {
|
|
269
|
-
logger.debug("C2 characteristic value is null");
|
|
270
|
-
return;
|
|
271
|
-
}
|
|
272
|
-
const data = Bytes.fromBase64(characteristicData);
|
|
273
|
-
logger.debug(`received data on C2: ${Bytes.toHex(data)}`);
|
|
274
|
-
|
|
275
|
-
void btpSession.handleIncomingBleData(data);
|
|
276
|
-
});
|
|
277
|
-
|
|
278
267
|
const bleChannel = new ReactNativeBleChannel(peripheral, btpSession);
|
|
279
268
|
return bleChannel;
|
|
280
269
|
}
|
|
@@ -317,8 +306,9 @@ export class ReactNativeBleChannel extends BleChannel<Bytes> {
|
|
|
317
306
|
}
|
|
318
307
|
|
|
319
308
|
async close() {
|
|
320
|
-
|
|
309
|
+
// should unsubscribe first
|
|
321
310
|
this.disconnectSubscription.remove();
|
|
322
|
-
|
|
311
|
+
// then close others
|
|
312
|
+
await this.btpSession.close();
|
|
323
313
|
}
|
|
324
314
|
}
|