@mega-yfue/eufy-sdk 0.3.0-beta.1 → 0.3.0-beta.3
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/index.js +106 -16
- package/dist/index.js.map +2 -2
- package/dist/transport/p2p/p2p-session.d.ts +25 -7
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -5813,6 +5813,7 @@ var LIGHT_SWITCH_JSON_TYPES = /* @__PURE__ */ new Set([
|
|
|
5813
5813
|
DeviceType.CAMERA_4G_S330
|
|
5814
5814
|
]);
|
|
5815
5815
|
var LIGHT_SWITCH_INT_STRING_TYPES = /* @__PURE__ */ new Set([
|
|
5816
|
+
DeviceType.FLOODLIGHT_CAMERA_8423,
|
|
5816
5817
|
DeviceType.INDOOR_OUTDOOR_CAMERA_1080P_NO_LIGHT,
|
|
5817
5818
|
DeviceType.INDOOR_OUTDOOR_CAMERA_2K,
|
|
5818
5819
|
DeviceType.INDOOR_OUTDOOR_CAMERA_1080P,
|
|
@@ -15140,6 +15141,8 @@ var LIVE_START_ACK_DEADLINE_MS = 3e3;
|
|
|
15140
15141
|
var SEQUENCE_LOOKBACK = 32768;
|
|
15141
15142
|
var STALE_RETRANSMIT_DEPTH = 1024;
|
|
15142
15143
|
var PUNCH_PROBE_SOCKETS = 7;
|
|
15144
|
+
var REORDER_WAIT_MS = 250;
|
|
15145
|
+
var REORDER_MAX_DATAGRAMS = 128;
|
|
15143
15146
|
var MAX_TRACED_DATAGRAM_GAPS = 8;
|
|
15144
15147
|
var CMD_SET_PAYLOAD = 1350;
|
|
15145
15148
|
var CMD_NOTIFY_PAYLOAD = 1351;
|
|
@@ -15209,9 +15212,10 @@ var P2PSession = class _P2PSession extends EventEmitter2 {
|
|
|
15209
15212
|
selfHost;
|
|
15210
15213
|
/** In-flight multi-datagram frame per data channel (see onData). */
|
|
15211
15214
|
pendingByDataType = /* @__PURE__ */ new Map();
|
|
15212
|
-
/** Last datagram sequence number
|
|
15213
|
-
* mid-frame and drop the (now unrecoverable) partial frame instead of splicing wrong bytes. */
|
|
15215
|
+
/** Last delivered datagram sequence number per data type. */
|
|
15214
15216
|
lastSeqByType = /* @__PURE__ */ new Map();
|
|
15217
|
+
/** Held datagrams and their active gap timer, grouped by data type. */
|
|
15218
|
+
reorderByType = /* @__PURE__ */ new Map();
|
|
15215
15219
|
tracedDatagramGaps = 0;
|
|
15216
15220
|
level1Key;
|
|
15217
15221
|
/** Negotiated 32-byte level-2/gateway key (AES-256-GCM). Set via setLevel2Key once known. */
|
|
@@ -16466,8 +16470,7 @@ var P2PSession = class _P2PSession extends EventEmitter2 {
|
|
|
16466
16470
|
* Acknowledge and reassemble one DATA datagram, sequenced independently per data type.
|
|
16467
16471
|
*
|
|
16468
16472
|
* The device numbers each data type's datagrams in its own 16-bit space and repeats what it thinks was
|
|
16469
|
-
* lost
|
|
16470
|
-
* retransmission of something already reassembled: it is acknowledged, then ignored. Distance is measured
|
|
16473
|
+
* lost. A repeat of something already delivered is acknowledged, then ignored. Distance is measured
|
|
16471
16474
|
* modulo the sequence space and read as backwards beyond {@link SEQUENCE_LOOKBACK}, which is what lets the
|
|
16472
16475
|
* numbering wrap without the next datagram looking like a jump of nearly a full space.
|
|
16473
16476
|
*
|
|
@@ -16477,9 +16480,13 @@ var P2PSession = class _P2PSession extends EventEmitter2 {
|
|
|
16477
16480
|
* numbering and the half-assembled frame goes — because ignoring it would freeze the mark, and every
|
|
16478
16481
|
* datagram of the new numbering would then be read as behind it too, for as long as it took to climb back.
|
|
16479
16482
|
*
|
|
16480
|
-
*
|
|
16481
|
-
*
|
|
16482
|
-
*
|
|
16483
|
+
* A forward gap means a datagram has not arrived YET, which is not the same as lost. The device repeats
|
|
16484
|
+
* unacknowledged datagrams, so successors are held for a bounded wait and delivered strictly in sequence
|
|
16485
|
+
* if the missing one arrives. A logical frame's payload spans datagrams that carry no header of their
|
|
16486
|
+
* own, so reassembling around a hole is impossible; waiting for it is what keeps the frame whole.
|
|
16487
|
+
*
|
|
16488
|
+
* Only once {@link REORDER_WAIT_MS} passes, or {@link REORDER_MAX_DATAGRAMS} pile up, is the datagram
|
|
16489
|
+
* treated as lost: a pending frame is discarded and delivery resumes from the earliest held datagram.
|
|
16483
16490
|
*/
|
|
16484
16491
|
onData(msg, addr) {
|
|
16485
16492
|
const dataTypeBuffer = msg.subarray(4, 6);
|
|
@@ -16490,18 +16497,98 @@ var P2PSession = class _P2PSession extends EventEmitter2 {
|
|
|
16490
16497
|
const advance = prevSeq === void 0 ? 1 : seqNo - prevSeq & 65535;
|
|
16491
16498
|
if (advance === 0)
|
|
16492
16499
|
return;
|
|
16493
|
-
|
|
16494
|
-
|
|
16495
|
-
|
|
16496
|
-
|
|
16497
|
-
|
|
16498
|
-
|
|
16499
|
-
|
|
16500
|
-
}
|
|
16500
|
+
if (advance > SEQUENCE_LOOKBACK) {
|
|
16501
|
+
if (65536 - advance <= STALE_RETRANSMIT_DEPTH)
|
|
16502
|
+
return;
|
|
16503
|
+
if (this.pendingByDataType.has(dataType) && this.tracedDatagramGaps++ < MAX_TRACED_DATAGRAM_GAPS)
|
|
16504
|
+
this.trace({ phase: "sequence-restart", dataType });
|
|
16505
|
+
this.clearReorderTimer(dataType);
|
|
16506
|
+
this.reorderByType.delete(dataType);
|
|
16501
16507
|
this.pendingByDataType.delete(dataType);
|
|
16508
|
+
this.lastSeqByType.set(dataType, seqNo);
|
|
16509
|
+
this.reassemble(dataType, msg.subarray(8));
|
|
16510
|
+
return;
|
|
16511
|
+
}
|
|
16512
|
+
if (advance === 1) {
|
|
16513
|
+
this.lastSeqByType.set(dataType, seqNo);
|
|
16514
|
+
this.reassemble(dataType, msg.subarray(8));
|
|
16515
|
+
this.drainReorder(dataType);
|
|
16516
|
+
return;
|
|
16517
|
+
}
|
|
16518
|
+
this.holdForRetransmit(dataType, seqNo, msg.subarray(8));
|
|
16519
|
+
}
|
|
16520
|
+
/** Hold a datagram that arrived past a hole, and arm the wait for the missing one to be repeated. */
|
|
16521
|
+
holdForRetransmit(dataType, seqNo, body) {
|
|
16522
|
+
let reorder = this.reorderByType.get(dataType);
|
|
16523
|
+
if (!reorder) {
|
|
16524
|
+
reorder = { held: /* @__PURE__ */ new Map() };
|
|
16525
|
+
this.reorderByType.set(dataType, reorder);
|
|
16526
|
+
}
|
|
16527
|
+
if (!reorder.held.has(seqNo))
|
|
16528
|
+
reorder.held.set(seqNo, body);
|
|
16529
|
+
if (reorder.held.size > REORDER_MAX_DATAGRAMS) {
|
|
16530
|
+
this.abandonHole(dataType);
|
|
16531
|
+
return;
|
|
16532
|
+
}
|
|
16533
|
+
this.armReorderTimer(dataType);
|
|
16534
|
+
}
|
|
16535
|
+
/** Start a full wait for the current hole, leaving an existing wait undisturbed. */
|
|
16536
|
+
armReorderTimer(dataType) {
|
|
16537
|
+
const reorder = this.reorderByType.get(dataType);
|
|
16538
|
+
if (!reorder?.held.size || reorder.timer)
|
|
16539
|
+
return;
|
|
16540
|
+
const timer = setTimeout(() => {
|
|
16541
|
+
reorder.timer = void 0;
|
|
16542
|
+
this.abandonHole(dataType);
|
|
16543
|
+
}, REORDER_WAIT_MS);
|
|
16544
|
+
timer.unref?.();
|
|
16545
|
+
reorder.timer = timer;
|
|
16546
|
+
}
|
|
16547
|
+
/** Deliver held datagrams that now follow directly on from the last one delivered. */
|
|
16548
|
+
drainReorder(dataType) {
|
|
16549
|
+
const reorder = this.reorderByType.get(dataType);
|
|
16550
|
+
if (!reorder?.held.size)
|
|
16551
|
+
return;
|
|
16552
|
+
this.clearReorderTimer(dataType);
|
|
16553
|
+
for (; ; ) {
|
|
16554
|
+
const next = this.lastSeqByType.get(dataType) + 1 & 65535;
|
|
16555
|
+
const body = reorder.held.get(next);
|
|
16556
|
+
if (body === void 0)
|
|
16557
|
+
break;
|
|
16558
|
+
reorder.held.delete(next);
|
|
16559
|
+
this.lastSeqByType.set(dataType, next);
|
|
16560
|
+
this.reassemble(dataType, body);
|
|
16502
16561
|
}
|
|
16562
|
+
if (reorder.held.size)
|
|
16563
|
+
this.armReorderTimer(dataType);
|
|
16564
|
+
else
|
|
16565
|
+
this.reorderByType.delete(dataType);
|
|
16566
|
+
}
|
|
16567
|
+
/**
|
|
16568
|
+
* The missing datagram was not repeated in time: report the gap, drop the frame it belonged to, and
|
|
16569
|
+
* resume from the earliest datagram still held so the stream keeps moving.
|
|
16570
|
+
*/
|
|
16571
|
+
abandonHole(dataType) {
|
|
16572
|
+
const held = this.reorderByType.get(dataType).held;
|
|
16573
|
+
if (this.pendingByDataType.has(dataType) && this.tracedDatagramGaps++ < MAX_TRACED_DATAGRAM_GAPS)
|
|
16574
|
+
this.trace({ phase: "datagram-gap", dataType });
|
|
16575
|
+
this.pendingByDataType.delete(dataType);
|
|
16576
|
+
const last = this.lastSeqByType.get(dataType);
|
|
16577
|
+
const earliest = [...held.keys()].sort((a, b) => (a - last & 65535) - (b - last & 65535))[0];
|
|
16578
|
+
this.lastSeqByType.set(dataType, earliest - 1 & 65535);
|
|
16579
|
+
this.drainReorder(dataType);
|
|
16580
|
+
}
|
|
16581
|
+
clearReorderTimer(dataType) {
|
|
16582
|
+
const reorder = this.reorderByType.get(dataType);
|
|
16583
|
+
if (!reorder?.timer)
|
|
16584
|
+
return;
|
|
16585
|
+
clearTimeout(reorder.timer);
|
|
16586
|
+
reorder.timer = void 0;
|
|
16587
|
+
}
|
|
16588
|
+
/** Reassemble one in-sequence datagram body into logical frames. */
|
|
16589
|
+
reassemble(dataType, datagramBody) {
|
|
16503
16590
|
const pending = this.pendingByDataType.get(dataType);
|
|
16504
|
-
let body = pending ? Buffer.concat([pending.buf,
|
|
16591
|
+
let body = pending ? Buffer.concat([pending.buf, datagramBody]) : datagramBody;
|
|
16505
16592
|
const carryHeader = pending?.header;
|
|
16506
16593
|
this.pendingByDataType.delete(dataType);
|
|
16507
16594
|
if (carryHeader) {
|
|
@@ -16532,6 +16619,9 @@ var P2PSession = class _P2PSession extends EventEmitter2 {
|
|
|
16532
16619
|
* completed either.
|
|
16533
16620
|
*/
|
|
16534
16621
|
resetInboundSequencing() {
|
|
16622
|
+
for (const dataType of this.reorderByType.keys())
|
|
16623
|
+
this.clearReorderTimer(dataType);
|
|
16624
|
+
this.reorderByType.clear();
|
|
16535
16625
|
this.lastSeqByType.clear();
|
|
16536
16626
|
this.pendingByDataType.clear();
|
|
16537
16627
|
this.tracedDatagramGaps = 0;
|