Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 92 additions & 1 deletion web/main-app.js
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,32 @@ button:disabled {
max-width: 500px;
}


#csispairbox {
display: flex;
position: fixed;
left: 0;
top: 0;
width: 100vw;
height: 100vh;

background: rgba(255, 255, 255, 0.8);
backdrop-filter: blur(10px);

z-index: 900;
}

#csispairbox.hidden {
display: none;
}

.csispaircontent {
margin: auto;
position: relative;
width: 90%;
max-width: 500px;
}

#splashbox {
display: flex;
position: fixed;
Expand Down Expand Up @@ -240,6 +266,16 @@ button:disabled {
</div>
</div>

<div id="csispairbox" class="hidden">
<div class="csispaircontent">
<div class="col">
<h2>Do you want to pair coordinated set?</h2>
<button id='paircsisbutton'>Yes</button>
<button id='cancelcsisbutton'>No</button>
</div>
</div>
</div>

<div id="splashbox">
<div class="splashcontent">
<div class="col">
Expand Down Expand Up @@ -293,6 +329,9 @@ export class MainApp extends HTMLElement {
this.bauFound = this.bauFound.bind(this);
this.requestBC = this.requestBC.bind(this);
this.bcReceived = this.bcReceived.bind(this);
this.sirkFound = this.sirkFound.bind(this);
this.pairCSIS = this.pairCSIS.bind(this);
this.closeCSISPair = this.closeCSISPair.bind(this);
}

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

const pairCSISButton = this.shadowRoot?.querySelector('#paircsisbutton');
pairCSISButton?.addEventListener('click', this.pairCSIS);

const cancelCSISButton = this.shadowRoot?.querySelector('#cancelcsisbutton');
cancelCSISButton?.addEventListener('click', this.closeCSISPair);

const splashbox = this.shadowRoot?.querySelector('#splashbox');
WebUSBDeviceService.addEventListener('connected', () => { splashbox?.classList.add('hidden') });
WebUSBDeviceService.addEventListener('disconnected', () => { splashbox?.classList.remove('hidden') });
Expand All @@ -374,7 +419,6 @@ export class MainApp extends HTMLElement {

this.#stopScanButton = this.shadowRoot?.querySelector('#stop_scan');
this.#stopScanButton.addEventListener('click', this.sendStopScan);
this.#stopScanButton.addEventListener('click', this.sendStopScan);
// this.#stopScanButton.disabled = true;

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

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

sirkFound(evt) {
console.log("SIRK found");

const sirk = evt.detail.sirk;
const set_size = evt.detail.set_size;

if (window["pairedSetMembers"] > 0) {
return;
}

window["sirk"] = sirk;
window["set_size"] = set_size;

const csispairbox = this.shadowRoot?.querySelector('#csispairbox');

csispairbox?.classList.remove('hidden');
}

closeCSISPair() {
console.log("Close CSIS pairing query");

const csispairbox = this.shadowRoot?.querySelector('#csispairbox');

window["setPairingInProgress"] = 0;
csispairbox?.classList.add('hidden');
}

pairCSIS() {
console.log("Pairing coordinated set");

const csispairbox = this.shadowRoot?.querySelector('#csispairbox');

const sirk = window["sirk"];
const set_size = window["set_size"];
window["setPairingInProgress"] = 1;
window["pairedSetMembers"] = 1;

// Pair all already-found members first
this.#model.handlePrefoundSetMembers(set_size, sirk);

setTimeout(() => {
this.#model.findSetMembers(set_size, sirk);
}, 500);
}

bauFound(evt) {
const {decoded, raw} = evt.detail;

Expand Down
70 changes: 64 additions & 6 deletions web/models/assistant-model.js
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,18 @@ class AssistantModel extends EventTarget {
} else {
if (message.subType === MessageSubType.SINK_CONNECTED) {
sink.state = "connected";

const pairingInProgress = window["setPairingInProgress"];
const pairedSetMembers = window["pairedSetMembers"];

if (pairingInProgress) {
window["pairedSetMembers"] = pairedSetMembers + 1;

if (window["pairedSetMembers"] == window["set_size"]) {
this.dispatchEvent(new CustomEvent('csis-pairing-complete'));
}
}

this.dispatchEvent(new CustomEvent('sink-updated', {detail: { sink }}));
} else {
this.#sinks.splice(this.#sinks.indexOf(sink, 1));
Expand Down Expand Up @@ -472,11 +484,17 @@ class AssistantModel extends EventTarget {
])?.value;

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

setTimeout(() => {
// Delayed setVolume to prevent comm issue
this.findSetMembers(set_size, sirk);
}, 500);
if (sink) {
sink.csis = {
sirk,
rank,
set_size
};
}

this.dispatchEvent(new CustomEvent('sirk-found', {detail: {sirk, set_size}}));
}

handleSetMemberFound(message) {
Expand All @@ -495,11 +513,14 @@ class AssistantModel extends EventTarget {
return;
}

// Send Connect : Note, if the connect fails, we should rely on FW to send new "found" event
this.connectSink({addr});

console.log(`Set member = ${addr}`);
}

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

const payloadArray = ltvToTvArray(message.payload);
Expand Down Expand Up @@ -554,6 +575,20 @@ class AssistantModel extends EventTarget {
}
}

handleStartSetMemberScanRes(message) {
console.log("Handle Start Set Member Scan Res");

const payloadArray = ltvToTvArray(message.payload);

const err = tvArrayFindItem(payloadArray, [
BT_DataType.BT_DATA_ERROR_CODE
])?.value;

if (err !== 0) {
console.log("Error code", err);
}
}

handleRES(message) {
console.log(`Response message with subType 0x${message.subType.toString(16)}`);

Expand Down Expand Up @@ -586,6 +621,10 @@ class AssistantModel extends EventTarget {
console.log('RESET response received');
this.dispatchEvent(new CustomEvent('scan-stopped'));
break;
case MessageSubType.START_SET_MEMBER_SCAN:
console.log('START_SET_MEMBER_SCAN response received');
this.handleStartSetMemberScanRes(message);
break;
default:
console.log(`Missing handler for RES subType 0x${message.subType.toString(16)}`);
}
Expand Down Expand Up @@ -667,7 +706,7 @@ class AssistantModel extends EventTarget {
console.log('Set indentifier found');
this.handleSetIndentifierFound(message);
break;
case MessageSubType.SINK_SET_MEMBER_FOUND:
case MessageSubType.SET_MEMBER_FOUND:
console.log('Set member found');
this.handleSetMemberFound(message);
default:
Expand Down Expand Up @@ -1029,6 +1068,25 @@ class AssistantModel extends EventTarget {
this.#service.sendCMD(message);
}

handlePrefoundSetMembers(set_size, sirk) {
console.log("Connect to already found CSIS set members");

const connected_set_members = this.#sinks.filter(i => (i.csis && compareTypedArray(i.csis.sirk, sirk) && i.state === "connected"));
const unconnected_set_members = this.#sinks.filter(i => (i.csis && compareTypedArray(i.csis.sirk, sirk) && i.state ==! "connected"));

window["pairedSetMembers"] = connected_set_members.length;

// If we already discovered members that are not connected yet, connect to them now
unconnected_set_members.forEach( s => { this.connectSink(s); });

// In case all other members were already connected before, then we just need to send off event that we are done
const pairedSetMembers = window["pairedSetMembers"];

if (pairedSetMembers == set_size) {
this.dispatchEvent(new CustomEvent('csis-pairing-complete'));
}
}

findSetMembers(set_size, sirk) {
console.log("Connect CSIS set members CMD");

Expand Down