Skip to content

Commit 49acc56

Browse files
Add rudimentary CSIS pairing in the web-assistant
1 parent c5f3f42 commit 49acc56

File tree

2 files changed

+155
-7
lines changed

2 files changed

+155
-7
lines changed

web/main-app.js

Lines changed: 92 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,32 @@ button:disabled {
158158
max-width: 500px;
159159
}
160160
161+
162+
#csispairbox {
163+
display: flex;
164+
position: fixed;
165+
left: 0;
166+
top: 0;
167+
width: 100vw;
168+
height: 100vh;
169+
170+
background: rgba(255, 255, 255, 0.8);
171+
backdrop-filter: blur(10px);
172+
173+
z-index: 900;
174+
}
175+
176+
#csispairbox.hidden {
177+
display: none;
178+
}
179+
180+
.csispaircontent {
181+
margin: auto;
182+
position: relative;
183+
width: 90%;
184+
max-width: 500px;
185+
}
186+
161187
#splashbox {
162188
display: flex;
163189
position: fixed;
@@ -240,6 +266,16 @@ button:disabled {
240266
</div>
241267
</div>
242268
269+
<div id="csispairbox" class="hidden">
270+
<div class="csispaircontent">
271+
<div class="col">
272+
<h2>Do you want to pair coordinated set?</h2>
273+
<button id='paircsisbutton'>Yes</button>
274+
<button id='cancelcsisbutton'>No</button>
275+
</div>
276+
</div>
277+
</div>
278+
243279
<div id="splashbox">
244280
<div class="splashcontent">
245281
<div class="col">
@@ -293,6 +329,9 @@ export class MainApp extends HTMLElement {
293329
this.bauFound = this.bauFound.bind(this);
294330
this.requestBC = this.requestBC.bind(this);
295331
this.bcReceived = this.bcReceived.bind(this);
332+
this.sirkFound = this.sirkFound.bind(this);
333+
this.pairCSIS = this.pairCSIS.bind(this);
334+
this.closeCSISPair = this.closeCSISPair.bind(this);
296335
}
297336

298337
initializeModels() {
@@ -366,6 +405,12 @@ export class MainApp extends HTMLElement {
366405
const button = this.shadowRoot?.querySelector('#connect');
367406
button?.addEventListener('click', WebUSBDeviceService.scan);
368407

408+
const pairCSISButton = this.shadowRoot?.querySelector('#paircsisbutton');
409+
pairCSISButton?.addEventListener('click', this.pairCSIS);
410+
411+
const cancelCSISButton = this.shadowRoot?.querySelector('#cancelcsisbutton');
412+
cancelCSISButton?.addEventListener('click', this.closeCSISPair);
413+
369414
const splashbox = this.shadowRoot?.querySelector('#splashbox');
370415
WebUSBDeviceService.addEventListener('connected', () => { splashbox?.classList.add('hidden') });
371416
WebUSBDeviceService.addEventListener('disconnected', () => { splashbox?.classList.remove('hidden') });
@@ -374,7 +419,6 @@ export class MainApp extends HTMLElement {
374419

375420
this.#stopScanButton = this.shadowRoot?.querySelector('#stop_scan');
376421
this.#stopScanButton.addEventListener('click', this.sendStopScan);
377-
this.#stopScanButton.addEventListener('click', this.sendStopScan);
378422
// this.#stopScanButton.disabled = true;
379423

380424
this.#scanSinkButton = this.shadowRoot?.querySelector('#sink_scan');
@@ -398,6 +442,8 @@ export class MainApp extends HTMLElement {
398442
this.#model.addEventListener('scan-stopped', this.scanStopped);
399443
this.#model.addEventListener('sink-scan-started', this.sinkScanStarted);
400444
this.#model.addEventListener('source-scan-started', this.sourceScanStarted);
445+
this.#model.addEventListener('sirk-found', this.sirkFound);
446+
this.#model.addEventListener('csis-pairing-complete', this.closeCSISPair);
401447

402448
const activityLog = this.shadowRoot?.querySelector('#activity');
403449
if (this.#pageState.get('log') === 'y') {
@@ -502,6 +548,51 @@ export class MainApp extends HTMLElement {
502548
qrscannerbox?.classList.add('hidden');
503549
}
504550

551+
sirkFound(evt) {
552+
console.log("SIRK found");
553+
554+
const sirk = evt.detail.sirk;
555+
const set_size = evt.detail.set_size;
556+
557+
if (window["pairedSetMembers"] > 0) {
558+
return;
559+
}
560+
561+
window["sirk"] = sirk;
562+
window["set_size"] = set_size;
563+
564+
const csispairbox = this.shadowRoot?.querySelector('#csispairbox');
565+
566+
csispairbox?.classList.remove('hidden');
567+
}
568+
569+
closeCSISPair() {
570+
console.log("Close CSIS pairing query");
571+
572+
const csispairbox = this.shadowRoot?.querySelector('#csispairbox');
573+
574+
window["setPairingInProgress"] = 0;
575+
csispairbox?.classList.add('hidden');
576+
}
577+
578+
pairCSIS() {
579+
console.log("Pairing coordinated set");
580+
581+
const csispairbox = this.shadowRoot?.querySelector('#csispairbox');
582+
583+
const sirk = window["sirk"];
584+
const set_size = window["set_size"];
585+
window["setPairingInProgress"] = 1;
586+
window["pairedSetMembers"] = 1;
587+
588+
// Pair all already-found members first
589+
this.#model.handlePrefoundSetMembers(set_size, sirk);
590+
591+
setTimeout(() => {
592+
this.#model.findSetMembers(set_size, sirk);
593+
}, 500);
594+
}
595+
505596
bauFound(evt) {
506597
const {decoded, raw} = evt.detail;
507598

web/models/assistant-model.js

Lines changed: 63 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,18 @@ class AssistantModel extends EventTarget {
376376
} else {
377377
if (message.subType === MessageSubType.SINK_CONNECTED) {
378378
sink.state = "connected";
379+
380+
const pairingInProgress = window["setPairingInProgress"];
381+
const pairedSetMembers = window["pairedSetMembers"];
382+
383+
if (pairingInProgress) {
384+
window["pairedSetMembers"] = pairedSetMembers + 1;
385+
386+
if (window["pairedSetMembers"] == window["set_size"]) {
387+
this.dispatchEvent(new CustomEvent('csis-pairing-complete'));
388+
}
389+
}
390+
379391
this.dispatchEvent(new CustomEvent('sink-updated', {detail: { sink }}));
380392
} else {
381393
this.#sinks.splice(this.#sinks.indexOf(sink, 1));
@@ -472,11 +484,17 @@ class AssistantModel extends EventTarget {
472484
])?.value;
473485

474486
console.log(`Set size = ${set_size}, rank = ${rank}, sirk = ${sirk}`);
487+
const sink = this.#sinks.find(i => compareTypedArray(i.addr.value.addr, addr.value.addr));
475488

476-
setTimeout(() => {
477-
// Delayed setVolume to prevent comm issue
478-
this.findSetMembers(set_size, sirk);
479-
}, 500);
489+
if (sink) {
490+
sink.csis = {
491+
sirk,
492+
rank,
493+
set_size
494+
};
495+
}
496+
497+
this.dispatchEvent(new CustomEvent('sirk-found', {detail: {sirk, set_size}}));
480498
}
481499

482500
handleSetMemberFound(message) {
@@ -495,11 +513,14 @@ class AssistantModel extends EventTarget {
495513
return;
496514
}
497515

516+
// Send Connect : Note, if the connect fails, we should rely on FW to send new "found" event
517+
this.connectSink({addr});
518+
498519
console.log(`Set member = ${addr}`);
499520
}
500521

501522
handleSinkConnectivityRes(message) {
502-
console.log(`Handle potential Error`);
523+
console.log(`Handle Sink Connectivity Response`);
503524
// TODO: Tie RES to actual call (could be another sink)
504525

505526
const payloadArray = ltvToTvArray(message.payload);
@@ -554,6 +575,20 @@ class AssistantModel extends EventTarget {
554575
}
555576
}
556577

578+
handleStartSetMemberScanRes(message) {
579+
console.log("Handle Start Set Member Scan Res");
580+
581+
const payloadArray = ltvToTvArray(message.payload);
582+
583+
const err = tvArrayFindItem(payloadArray, [
584+
BT_DataType.BT_DATA_ERROR_CODE
585+
])?.value;
586+
587+
if (err !== 0) {
588+
console.log("Error code", err);
589+
}
590+
}
591+
557592
handleRES(message) {
558593
console.log(`Response message with subType 0x${message.subType.toString(16)}`);
559594

@@ -586,6 +621,10 @@ class AssistantModel extends EventTarget {
586621
console.log('RESET response received');
587622
this.dispatchEvent(new CustomEvent('scan-stopped'));
588623
break;
624+
case MessageSubType.START_SET_MEMBER_SCAN:
625+
console.log('START_SET_MEMBER_SCAN response received');
626+
this.handleStartSetMemberScanRes(message);
627+
break;
589628
default:
590629
console.log(`Missing handler for RES subType 0x${message.subType.toString(16)}`);
591630
}
@@ -667,7 +706,7 @@ class AssistantModel extends EventTarget {
667706
console.log('Set indentifier found');
668707
this.handleSetIndentifierFound(message);
669708
break;
670-
case MessageSubType.SINK_SET_MEMBER_FOUND:
709+
case MessageSubType.SET_MEMBER_FOUND:
671710
console.log('Set member found');
672711
this.handleSetMemberFound(message);
673712
default:
@@ -1029,6 +1068,24 @@ class AssistantModel extends EventTarget {
10291068
this.#service.sendCMD(message);
10301069
}
10311070

1071+
handlePrefoundSetMembers(set_size, sirk) {
1072+
console.log("Connect to already found CSIS set members");
1073+
1074+
const connected_set_members = this.#sinks.filter(i => (i.csis && compareTypedArray(i.csis.sirk, sirk) && i.state === "connected"));
1075+
1076+
window["pairedSetMembers"] = connected_set_members.length;
1077+
1078+
// If we already discovered members that are not connected yet, connect to them now
1079+
unconnected_set_members.forEach( s => { this.connectSink(s); });
1080+
1081+
// In case all other members were already connected before, then we just need to send off event that we are done
1082+
const pairedSetMembers = window["pairedSetMembers"];
1083+
1084+
if (pairedSetMembers == set_size) {
1085+
this.dispatchEvent(new CustomEvent('csis-pairing-complete'));
1086+
}
1087+
}
1088+
10321089
findSetMembers(set_size, sirk) {
10331090
console.log("Connect CSIS set members CMD");
10341091

0 commit comments

Comments
 (0)