react-native-ble-mesh 2.1.0 → 2.1.2
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/package.json +1 -1
- package/src/MeshNetwork.js +48 -46
- package/src/constants/audio.js +4 -4
- package/src/constants/ble.js +1 -1
- package/src/constants/crypto.js +1 -1
- package/src/constants/errors.js +2 -2
- package/src/constants/events.js +1 -1
- package/src/constants/protocol.js +2 -2
- package/src/crypto/AutoCrypto.js +2 -0
- package/src/crypto/CryptoProvider.js +17 -17
- package/src/crypto/providers/ExpoCryptoProvider.js +12 -7
- package/src/crypto/providers/QuickCryptoProvider.js +12 -7
- package/src/crypto/providers/TweetNaClProvider.js +9 -7
- package/src/errors/AudioError.js +2 -1
- package/src/errors/ConnectionError.js +2 -2
- package/src/errors/CryptoError.js +1 -1
- package/src/errors/HandshakeError.js +2 -2
- package/src/errors/MeshError.js +4 -4
- package/src/errors/MessageError.js +2 -2
- package/src/errors/ValidationError.js +3 -3
- package/src/expo/withBLEMesh.js +10 -10
- package/src/hooks/AppStateManager.js +2 -1
- package/src/hooks/useMesh.js +7 -7
- package/src/hooks/useMessages.js +13 -12
- package/src/hooks/usePeers.js +10 -9
- package/src/index.js +2 -2
- package/src/mesh/dedup/BloomFilter.js +1 -0
- package/src/mesh/dedup/DedupManager.js +4 -7
- package/src/mesh/dedup/MessageCache.js +3 -0
- package/src/mesh/fragment/Assembler.js +5 -4
- package/src/mesh/fragment/Fragmenter.js +2 -2
- package/src/mesh/monitor/ConnectionQuality.js +17 -8
- package/src/mesh/monitor/NetworkMonitor.js +22 -15
- package/src/mesh/peer/Peer.js +4 -9
- package/src/mesh/peer/PeerDiscovery.js +18 -19
- package/src/mesh/peer/PeerManager.js +14 -14
- package/src/mesh/router/MessageRouter.js +15 -15
- package/src/mesh/router/PathFinder.js +10 -13
- package/src/mesh/router/RouteTable.js +8 -7
- package/src/mesh/store/StoreAndForwardManager.js +20 -23
- package/src/protocol/message.js +5 -13
- package/src/protocol/serializer.js +4 -4
- package/src/protocol/validator.js +7 -6
- package/src/service/BatteryOptimizer.js +18 -17
- package/src/service/EmergencyManager.js +18 -25
- package/src/service/HandshakeManager.js +100 -2
- package/src/service/MeshService.js +106 -22
- package/src/service/SessionManager.js +38 -3
- package/src/service/audio/AudioManager.js +80 -38
- package/src/service/audio/buffer/FrameBuffer.js +7 -8
- package/src/service/audio/buffer/JitterBuffer.js +1 -1
- package/src/service/audio/codec/LC3Codec.js +18 -19
- package/src/service/audio/codec/LC3Decoder.js +10 -10
- package/src/service/audio/codec/LC3Encoder.js +11 -9
- package/src/service/audio/session/AudioSession.js +14 -17
- package/src/service/audio/session/VoiceMessage.js +15 -22
- package/src/service/audio/transport/AudioFragmenter.js +17 -9
- package/src/service/audio/transport/AudioFramer.js +8 -12
- package/src/service/file/FileAssembler.js +4 -2
- package/src/service/file/FileChunker.js +1 -1
- package/src/service/file/FileManager.js +26 -20
- package/src/service/file/FileMessage.js +7 -12
- package/src/service/text/TextManager.js +55 -28
- package/src/service/text/broadcast/BroadcastManager.js +14 -17
- package/src/service/text/channel/Channel.js +10 -14
- package/src/service/text/channel/ChannelManager.js +10 -10
- package/src/service/text/message/TextMessage.js +12 -19
- package/src/service/text/message/TextSerializer.js +2 -2
- package/src/storage/AsyncStorageAdapter.js +17 -14
- package/src/storage/MemoryStorage.js +11 -8
- package/src/storage/MessageStore.js +22 -30
- package/src/storage/Storage.js +9 -9
- package/src/transport/BLETransport.js +16 -14
- package/src/transport/MockTransport.js +7 -2
- package/src/transport/MultiTransport.js +13 -6
- package/src/transport/Transport.js +9 -9
- package/src/transport/WiFiDirectTransport.js +22 -17
- package/src/transport/adapters/BLEAdapter.js +19 -19
- package/src/transport/adapters/NodeBLEAdapter.js +24 -23
- package/src/transport/adapters/RNBLEAdapter.js +14 -11
- package/src/utils/EventEmitter.js +9 -7
- package/src/utils/LRUCache.js +10 -4
- package/src/utils/RateLimiter.js +1 -1
- package/src/utils/compression.js +5 -5
- package/src/utils/encoding.js +8 -2
- package/src/utils/retry.js +11 -13
- package/src/utils/time.js +9 -4
- package/src/utils/validation.js +1 -1
|
@@ -13,7 +13,7 @@ const EventEmitter = require('../utils/EventEmitter');
|
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
15
|
* Panic trigger types
|
|
16
|
-
* @constant {
|
|
16
|
+
* @constant {any}
|
|
17
17
|
*/
|
|
18
18
|
const PANIC_TRIGGER = Object.freeze({
|
|
19
19
|
TRIPLE_TAP: 'triple_tap',
|
|
@@ -24,7 +24,7 @@ const PANIC_TRIGGER = Object.freeze({
|
|
|
24
24
|
|
|
25
25
|
/**
|
|
26
26
|
* Default configuration
|
|
27
|
-
* @constant {
|
|
27
|
+
* @constant {any}
|
|
28
28
|
*/
|
|
29
29
|
const DEFAULT_CONFIG = Object.freeze({
|
|
30
30
|
/** Trigger type for panic mode */
|
|
@@ -63,18 +63,14 @@ const DEFAULT_CONFIG = Object.freeze({
|
|
|
63
63
|
class EmergencyManager extends EventEmitter {
|
|
64
64
|
/**
|
|
65
65
|
* Creates a new EmergencyManager instance.
|
|
66
|
-
* @param {
|
|
67
|
-
* @param {string} [options.trigger='triple_tap'] - Panic trigger type
|
|
68
|
-
* @param {number} [options.tapWindowMs=500] - Time window for taps
|
|
69
|
-
* @param {number} [options.tapCount=3] - Required tap count
|
|
70
|
-
* @param {boolean} [options.requireConfirmation=false] - Require confirmation
|
|
66
|
+
* @param {any} [options] - Configuration options
|
|
71
67
|
*/
|
|
72
68
|
constructor(options = {}) {
|
|
73
69
|
super();
|
|
74
70
|
|
|
75
71
|
/**
|
|
76
72
|
* Configuration
|
|
77
|
-
* @type {
|
|
73
|
+
* @type {any}
|
|
78
74
|
* @private
|
|
79
75
|
*/
|
|
80
76
|
this._config = { ...DEFAULT_CONFIG, ...options };
|
|
@@ -88,7 +84,7 @@ class EmergencyManager extends EventEmitter {
|
|
|
88
84
|
|
|
89
85
|
/**
|
|
90
86
|
* Tap tracking
|
|
91
|
-
* @type {
|
|
87
|
+
* @type {any}
|
|
92
88
|
* @private
|
|
93
89
|
*/
|
|
94
90
|
this._tapState = {
|
|
@@ -98,7 +94,7 @@ class EmergencyManager extends EventEmitter {
|
|
|
98
94
|
|
|
99
95
|
/**
|
|
100
96
|
* Shake tracking
|
|
101
|
-
* @type {
|
|
97
|
+
* @type {any}
|
|
102
98
|
* @private
|
|
103
99
|
*/
|
|
104
100
|
this._shakeState = {
|
|
@@ -122,7 +118,7 @@ class EmergencyManager extends EventEmitter {
|
|
|
122
118
|
|
|
123
119
|
/**
|
|
124
120
|
* Statistics
|
|
125
|
-
* @type {
|
|
121
|
+
* @type {any}
|
|
126
122
|
* @private
|
|
127
123
|
*/
|
|
128
124
|
this._stats = {
|
|
@@ -134,9 +130,7 @@ class EmergencyManager extends EventEmitter {
|
|
|
134
130
|
|
|
135
131
|
/**
|
|
136
132
|
* Enables panic mode.
|
|
137
|
-
* @param {
|
|
138
|
-
* @param {Function} [options.onWipe] - Callback after wipe
|
|
139
|
-
* @param {string} [options.trigger] - Override trigger type
|
|
133
|
+
* @param {any} [options] - Enable options
|
|
140
134
|
*/
|
|
141
135
|
enablePanicMode(options = {}) {
|
|
142
136
|
this._enabled = true;
|
|
@@ -208,10 +202,7 @@ class EmergencyManager extends EventEmitter {
|
|
|
208
202
|
|
|
209
203
|
/**
|
|
210
204
|
* Registers accelerometer data for shake detection.
|
|
211
|
-
* @param {
|
|
212
|
-
* @param {number} data.x - X acceleration
|
|
213
|
-
* @param {number} data.y - Y acceleration
|
|
214
|
-
* @param {number} data.z - Z acceleration
|
|
205
|
+
* @param {any} data - Accelerometer data
|
|
215
206
|
*/
|
|
216
207
|
registerAccelerometer(data) {
|
|
217
208
|
if (!this._enabled || this._config.trigger !== PANIC_TRIGGER.SHAKE) {
|
|
@@ -236,7 +227,7 @@ class EmergencyManager extends EventEmitter {
|
|
|
236
227
|
|
|
237
228
|
/**
|
|
238
229
|
* Manually triggers panic wipe.
|
|
239
|
-
* @returns {Promise<
|
|
230
|
+
* @returns {Promise<any>} Wipe result
|
|
240
231
|
*/
|
|
241
232
|
async triggerManualWipe() {
|
|
242
233
|
return this._executeWipe(PANIC_TRIGGER.MANUAL);
|
|
@@ -244,7 +235,7 @@ class EmergencyManager extends EventEmitter {
|
|
|
244
235
|
|
|
245
236
|
/**
|
|
246
237
|
* Wipes all registered data.
|
|
247
|
-
* @returns {Promise<
|
|
238
|
+
* @returns {Promise<any>} Wipe result with timing
|
|
248
239
|
*/
|
|
249
240
|
async wipeAllData() {
|
|
250
241
|
return this._executeWipe(PANIC_TRIGGER.MANUAL);
|
|
@@ -252,7 +243,7 @@ class EmergencyManager extends EventEmitter {
|
|
|
252
243
|
|
|
253
244
|
/**
|
|
254
245
|
* Gets emergency statistics.
|
|
255
|
-
* @returns {
|
|
246
|
+
* @returns {any} Statistics
|
|
256
247
|
*/
|
|
257
248
|
getStats() {
|
|
258
249
|
return { ...this._stats };
|
|
@@ -280,7 +271,7 @@ class EmergencyManager extends EventEmitter {
|
|
|
280
271
|
|
|
281
272
|
try {
|
|
282
273
|
await this._executeWipe(trigger);
|
|
283
|
-
} catch (error) {
|
|
274
|
+
} catch (/** @type {any} */ error) {
|
|
284
275
|
this.emit('error', {
|
|
285
276
|
message: 'Panic wipe failed',
|
|
286
277
|
error: error.message,
|
|
@@ -292,7 +283,7 @@ class EmergencyManager extends EventEmitter {
|
|
|
292
283
|
/**
|
|
293
284
|
* Executes the data wipe.
|
|
294
285
|
* @param {string} trigger - Trigger type
|
|
295
|
-
* @returns {Promise<
|
|
286
|
+
* @returns {Promise<any>} Wipe result
|
|
296
287
|
* @private
|
|
297
288
|
*/
|
|
298
289
|
async _executeWipe(trigger) {
|
|
@@ -300,6 +291,7 @@ class EmergencyManager extends EventEmitter {
|
|
|
300
291
|
|
|
301
292
|
this.emit('panic-wipe-started', { trigger, timestamp: startTime });
|
|
302
293
|
|
|
294
|
+
/** @type {any} */
|
|
303
295
|
const results = {
|
|
304
296
|
trigger,
|
|
305
297
|
startTime,
|
|
@@ -308,12 +300,13 @@ class EmergencyManager extends EventEmitter {
|
|
|
308
300
|
};
|
|
309
301
|
|
|
310
302
|
// Execute all clearers in parallel for speed
|
|
303
|
+
/** @type {any[]} */
|
|
311
304
|
const clearerResults = new Array(this._clearers.length);
|
|
312
305
|
const promises = this._clearers.map(async (clearer, index) => {
|
|
313
306
|
try {
|
|
314
307
|
await clearer();
|
|
315
308
|
clearerResults[index] = { index, success: true };
|
|
316
|
-
} catch (error) {
|
|
309
|
+
} catch (/** @type {any} */ error) {
|
|
317
310
|
results.errors.push({ index, error: error.message });
|
|
318
311
|
clearerResults[index] = { index, success: false, error: error.message };
|
|
319
312
|
}
|
|
@@ -344,7 +337,7 @@ class EmergencyManager extends EventEmitter {
|
|
|
344
337
|
if (this._onWipe) {
|
|
345
338
|
try {
|
|
346
339
|
this._onWipe(results);
|
|
347
|
-
} catch (error) {
|
|
340
|
+
} catch (/** @type {any} */ error) {
|
|
348
341
|
// Ignore callback errors
|
|
349
342
|
}
|
|
350
343
|
}
|
|
@@ -21,15 +21,27 @@ const STATE = Object.freeze({
|
|
|
21
21
|
* @extends EventEmitter
|
|
22
22
|
*/
|
|
23
23
|
class HandshakeManager extends EventEmitter {
|
|
24
|
+
/**
|
|
25
|
+
* @param {any} keyManager
|
|
26
|
+
* @param {any} sessionManager
|
|
27
|
+
*/
|
|
24
28
|
constructor(keyManager, sessionManager) {
|
|
25
29
|
super();
|
|
26
30
|
if (!keyManager || !sessionManager) { throw new Error('keyManager and sessionManager required'); }
|
|
31
|
+
/** @type {any} */
|
|
27
32
|
this._keyManager = keyManager;
|
|
33
|
+
/** @type {any} */
|
|
28
34
|
this._sessionManager = sessionManager;
|
|
35
|
+
/** @type {Map<string, any>} */
|
|
29
36
|
this._pending = new Map();
|
|
37
|
+
/** @type {number} */
|
|
30
38
|
this._timeout = MESH_CONFIG.HANDSHAKE_TIMEOUT_MS;
|
|
31
39
|
}
|
|
32
40
|
|
|
41
|
+
/**
|
|
42
|
+
* @param {string} peerId
|
|
43
|
+
* @param {any} transport
|
|
44
|
+
*/
|
|
33
45
|
async initiateHandshake(peerId, transport) {
|
|
34
46
|
if (this._pending.has(peerId)) { throw HandshakeError.alreadyInProgress(peerId); }
|
|
35
47
|
|
|
@@ -44,12 +56,18 @@ class HandshakeManager extends EventEmitter {
|
|
|
44
56
|
hs.step = 1;
|
|
45
57
|
this.emit(EVENTS.HANDSHAKE_PROGRESS, { peerId, step: 1, role: 'initiator' });
|
|
46
58
|
return await this._waitForCompletion(peerId);
|
|
47
|
-
} catch (err) {
|
|
59
|
+
} catch (/** @type {any} */ err) {
|
|
48
60
|
this._fail(peerId, err);
|
|
49
61
|
throw err;
|
|
50
62
|
}
|
|
51
63
|
}
|
|
52
64
|
|
|
65
|
+
/**
|
|
66
|
+
* @param {string} peerId
|
|
67
|
+
* @param {number} type
|
|
68
|
+
* @param {Uint8Array} payload
|
|
69
|
+
* @param {any} transport
|
|
70
|
+
*/
|
|
53
71
|
async handleIncomingHandshake(peerId, type, payload, transport) {
|
|
54
72
|
try {
|
|
55
73
|
if (type === MESSAGE_TYPE.HANDSHAKE_INIT) {
|
|
@@ -62,12 +80,15 @@ class HandshakeManager extends EventEmitter {
|
|
|
62
80
|
return await this._onFinal(peerId, payload);
|
|
63
81
|
}
|
|
64
82
|
throw HandshakeError.handshakeFailed(peerId, null, { reason: 'Unknown type' });
|
|
65
|
-
} catch (err) {
|
|
83
|
+
} catch (/** @type {any} */ err) {
|
|
66
84
|
this._fail(peerId, err);
|
|
67
85
|
throw err;
|
|
68
86
|
}
|
|
69
87
|
}
|
|
70
88
|
|
|
89
|
+
/**
|
|
90
|
+
* @param {string} peerId
|
|
91
|
+
*/
|
|
71
92
|
cancelHandshake(peerId) {
|
|
72
93
|
const hs = this._pending.get(peerId);
|
|
73
94
|
if (!hs) { return; }
|
|
@@ -77,9 +98,20 @@ class HandshakeManager extends EventEmitter {
|
|
|
77
98
|
this.emit(EVENTS.HANDSHAKE_FAILED, { peerId, reason: 'cancelled' });
|
|
78
99
|
}
|
|
79
100
|
|
|
101
|
+
/**
|
|
102
|
+
* @param {string} peerId
|
|
103
|
+
* @returns {boolean}
|
|
104
|
+
*/
|
|
80
105
|
isHandshakePending(peerId) { return this._pending.has(peerId); }
|
|
106
|
+
/** @returns {number} */
|
|
81
107
|
getPendingCount() { return this._pending.size; }
|
|
82
108
|
|
|
109
|
+
/**
|
|
110
|
+
* @param {string} peerId
|
|
111
|
+
* @param {boolean} isInitiator
|
|
112
|
+
* @returns {any}
|
|
113
|
+
* @private
|
|
114
|
+
*/
|
|
83
115
|
_createState(peerId, isInitiator) {
|
|
84
116
|
const kp = this._keyManager.getStaticKeyPair();
|
|
85
117
|
return {
|
|
@@ -88,11 +120,18 @@ class HandshakeManager extends EventEmitter {
|
|
|
88
120
|
};
|
|
89
121
|
}
|
|
90
122
|
|
|
123
|
+
/**
|
|
124
|
+
* @param {any} keyPair
|
|
125
|
+
* @param {boolean} isInitiator
|
|
126
|
+
* @returns {any}
|
|
127
|
+
* @private
|
|
128
|
+
*/
|
|
91
129
|
_createNoise(keyPair, isInitiator) {
|
|
92
130
|
// Get crypto provider from keyManager if available
|
|
93
131
|
const provider = this._keyManager.provider;
|
|
94
132
|
|
|
95
133
|
// Generate ephemeral key pair for this handshake
|
|
134
|
+
/** @type {any} */
|
|
96
135
|
let ephemeralKeyPair;
|
|
97
136
|
if (provider && typeof provider.generateKeyPair === 'function') {
|
|
98
137
|
ephemeralKeyPair = provider.generateKeyPair();
|
|
@@ -101,11 +140,18 @@ class HandshakeManager extends EventEmitter {
|
|
|
101
140
|
ephemeralKeyPair = { publicKey: randomBytes(32), secretKey: randomBytes(32) };
|
|
102
141
|
}
|
|
103
142
|
|
|
143
|
+
/** @type {Uint8Array | null} */
|
|
104
144
|
let remoteEphemeralPublic = null;
|
|
145
|
+
/** @type {Uint8Array | null} */
|
|
105
146
|
let sharedSecret = null;
|
|
147
|
+
/** @type {any} */
|
|
106
148
|
let sessionKeys = null;
|
|
107
149
|
let complete = false;
|
|
108
150
|
|
|
151
|
+
/**
|
|
152
|
+
* @param {Uint8Array} secret
|
|
153
|
+
* @returns {any}
|
|
154
|
+
*/
|
|
109
155
|
const deriveSessionKeys = (secret) => {
|
|
110
156
|
// Derive send/receive keys from shared secret
|
|
111
157
|
// Use hash to derive two different keys from the secret
|
|
@@ -125,6 +171,7 @@ class HandshakeManager extends EventEmitter {
|
|
|
125
171
|
return ephemeralKeyPair.publicKey;
|
|
126
172
|
},
|
|
127
173
|
|
|
174
|
+
/** @param {Uint8Array} msg */
|
|
128
175
|
readMessage1: (msg) => {
|
|
129
176
|
// Responder receives initiator's ephemeral public key
|
|
130
177
|
remoteEphemeralPublic = new Uint8Array(msg);
|
|
@@ -137,10 +184,12 @@ class HandshakeManager extends EventEmitter {
|
|
|
137
184
|
} else {
|
|
138
185
|
throw new Error('Crypto provider required for secure handshake. Install tweetnacl: npm install tweetnacl');
|
|
139
186
|
}
|
|
187
|
+
// @ts-ignore
|
|
140
188
|
sessionKeys = deriveSessionKeys(sharedSecret);
|
|
141
189
|
return ephemeralKeyPair.publicKey;
|
|
142
190
|
},
|
|
143
191
|
|
|
192
|
+
/** @param {Uint8Array} msg */
|
|
144
193
|
readMessage2: (msg) => {
|
|
145
194
|
// Initiator receives responder's ephemeral public key and derives shared secret
|
|
146
195
|
remoteEphemeralPublic = new Uint8Array(msg);
|
|
@@ -149,6 +198,7 @@ class HandshakeManager extends EventEmitter {
|
|
|
149
198
|
} else {
|
|
150
199
|
throw new Error('Crypto provider required for secure handshake. Install tweetnacl: npm install tweetnacl');
|
|
151
200
|
}
|
|
201
|
+
// @ts-ignore
|
|
152
202
|
sessionKeys = deriveSessionKeys(sharedSecret);
|
|
153
203
|
},
|
|
154
204
|
|
|
@@ -158,6 +208,7 @@ class HandshakeManager extends EventEmitter {
|
|
|
158
208
|
return ephemeralKeyPair.publicKey;
|
|
159
209
|
},
|
|
160
210
|
|
|
211
|
+
/** @param {any} _msg */
|
|
161
212
|
readMessage3: (_msg) => {
|
|
162
213
|
// Responder confirms handshake completion
|
|
163
214
|
complete = true;
|
|
@@ -184,6 +235,7 @@ class HandshakeManager extends EventEmitter {
|
|
|
184
235
|
const recvNonceView = new DataView(recvNonceBuf.buffer);
|
|
185
236
|
|
|
186
237
|
return {
|
|
238
|
+
/** @param {Uint8Array} plaintext */
|
|
187
239
|
encrypt: (plaintext) => {
|
|
188
240
|
if (provider && typeof provider.encrypt === 'function') {
|
|
189
241
|
// Store counter in last 8 bytes of nonce
|
|
@@ -194,6 +246,7 @@ class HandshakeManager extends EventEmitter {
|
|
|
194
246
|
throw new Error('Crypto provider required for encryption');
|
|
195
247
|
},
|
|
196
248
|
|
|
249
|
+
/** @param {Uint8Array} ciphertext */
|
|
197
250
|
decrypt: (ciphertext) => {
|
|
198
251
|
if (provider && typeof provider.decrypt === 'function') {
|
|
199
252
|
recvNonceView.setUint32(16, 0, true);
|
|
@@ -215,6 +268,12 @@ class HandshakeManager extends EventEmitter {
|
|
|
215
268
|
};
|
|
216
269
|
}
|
|
217
270
|
|
|
271
|
+
/**
|
|
272
|
+
* @param {string} peerId
|
|
273
|
+
* @param {Uint8Array} payload
|
|
274
|
+
* @param {any} transport
|
|
275
|
+
* @private
|
|
276
|
+
*/
|
|
218
277
|
async _onInit(peerId, payload, transport) {
|
|
219
278
|
const existing = this._pending.get(peerId);
|
|
220
279
|
|
|
@@ -245,6 +304,12 @@ class HandshakeManager extends EventEmitter {
|
|
|
245
304
|
return null;
|
|
246
305
|
}
|
|
247
306
|
|
|
307
|
+
/**
|
|
308
|
+
* @param {string} peerId
|
|
309
|
+
* @param {Uint8Array} payload
|
|
310
|
+
* @param {any} transport
|
|
311
|
+
* @private
|
|
312
|
+
*/
|
|
248
313
|
async _onResponse(peerId, payload, transport) {
|
|
249
314
|
const hs = this._pending.get(peerId);
|
|
250
315
|
if (!hs || !hs.isInitiator) {
|
|
@@ -258,6 +323,11 @@ class HandshakeManager extends EventEmitter {
|
|
|
258
323
|
return this._complete(peerId, hs);
|
|
259
324
|
}
|
|
260
325
|
|
|
326
|
+
/**
|
|
327
|
+
* @param {string} peerId
|
|
328
|
+
* @param {Uint8Array} payload
|
|
329
|
+
* @private
|
|
330
|
+
*/
|
|
261
331
|
async _onFinal(peerId, payload) {
|
|
262
332
|
const hs = this._pending.get(peerId);
|
|
263
333
|
if (!hs || hs.isInitiator) { throw HandshakeError.invalidState(peerId, 3); }
|
|
@@ -266,6 +336,11 @@ class HandshakeManager extends EventEmitter {
|
|
|
266
336
|
return this._complete(peerId, hs);
|
|
267
337
|
}
|
|
268
338
|
|
|
339
|
+
/**
|
|
340
|
+
* @param {string} peerId
|
|
341
|
+
* @param {any} hs
|
|
342
|
+
* @private
|
|
343
|
+
*/
|
|
269
344
|
_complete(peerId, hs) {
|
|
270
345
|
if (hs.timer) { clearTimeout(hs.timer); }
|
|
271
346
|
const session = hs.noise.getSession();
|
|
@@ -279,6 +354,11 @@ class HandshakeManager extends EventEmitter {
|
|
|
279
354
|
return session;
|
|
280
355
|
}
|
|
281
356
|
|
|
357
|
+
/**
|
|
358
|
+
* @param {string} peerId
|
|
359
|
+
* @param {any} error
|
|
360
|
+
* @private
|
|
361
|
+
*/
|
|
282
362
|
_fail(peerId, error) {
|
|
283
363
|
const hs = this._pending.get(peerId);
|
|
284
364
|
if (hs) {
|
|
@@ -289,6 +369,10 @@ class HandshakeManager extends EventEmitter {
|
|
|
289
369
|
this.emit(EVENTS.HANDSHAKE_FAILED, { peerId, error: error.message, step: hs?.step });
|
|
290
370
|
}
|
|
291
371
|
|
|
372
|
+
/**
|
|
373
|
+
* @param {string} peerId
|
|
374
|
+
* @private
|
|
375
|
+
*/
|
|
292
376
|
_setTimeout(peerId) {
|
|
293
377
|
const hs = this._pending.get(peerId);
|
|
294
378
|
if (!hs) { return; }
|
|
@@ -299,6 +383,10 @@ class HandshakeManager extends EventEmitter {
|
|
|
299
383
|
}, this._timeout);
|
|
300
384
|
}
|
|
301
385
|
|
|
386
|
+
/**
|
|
387
|
+
* @param {string} peerId
|
|
388
|
+
* @private
|
|
389
|
+
*/
|
|
302
390
|
_waitForCompletion(peerId) {
|
|
303
391
|
return new Promise((resolve, reject) => {
|
|
304
392
|
const hs = this._pending.get(peerId);
|
|
@@ -309,6 +397,11 @@ class HandshakeManager extends EventEmitter {
|
|
|
309
397
|
});
|
|
310
398
|
}
|
|
311
399
|
|
|
400
|
+
/**
|
|
401
|
+
* @param {any} localKey
|
|
402
|
+
* @param {any} remoteId
|
|
403
|
+
* @private
|
|
404
|
+
*/
|
|
312
405
|
_compareKeys(localKey, remoteId) {
|
|
313
406
|
// Simple string/byte comparison for deterministic tie-breaking
|
|
314
407
|
const localStr = typeof localKey === 'string' ? localKey : Array.from(localKey).join(',');
|
|
@@ -316,6 +409,11 @@ class HandshakeManager extends EventEmitter {
|
|
|
316
409
|
return localStr < remoteStr ? -1 : localStr > remoteStr ? 1 : 0;
|
|
317
410
|
}
|
|
318
411
|
|
|
412
|
+
/**
|
|
413
|
+
* @param {number} type
|
|
414
|
+
* @param {Uint8Array} payload
|
|
415
|
+
* @private
|
|
416
|
+
*/
|
|
319
417
|
_wrap(type, payload) {
|
|
320
418
|
const w = new Uint8Array(1 + payload.length);
|
|
321
419
|
w[0] = type;
|