Skip to content

Commit bff05d7

Browse files
More robust radio bridge connection (#16)
Only reconnect serial session on tab change if consumer is already listening.
1 parent b2b2c0a commit bff05d7

File tree

2 files changed

+25
-5
lines changed

2 files changed

+25
-5
lines changed

lib/usb-radio-bridge.ts

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ export class MicrobitRadioBridgeConnection
4545
private logging: Logging;
4646
private serialSession: RadioBridgeSerialSession | undefined;
4747
private remoteDeviceId: number | undefined;
48+
private disconnectPromise: Promise<void> | undefined;
49+
private serialSessionOpen = false;
4850

4951
private delegateStatusListner = (e: ConnectionStatusEvent) => {
5052
const currentStatus = this.status;
@@ -53,7 +55,10 @@ export class MicrobitRadioBridgeConnection
5355
this.serialSession?.dispose();
5456
} else {
5557
this.status = ConnectionStatus.NOT_CONNECTED;
56-
if (currentStatus === ConnectionStatus.NOT_CONNECTED) {
58+
if (
59+
currentStatus === ConnectionStatus.NOT_CONNECTED &&
60+
this.serialSessionOpen
61+
) {
5762
this.serialSession?.connect();
5863
}
5964
}
@@ -96,6 +101,9 @@ export class MicrobitRadioBridgeConnection
96101
}
97102

98103
async connect(): Promise<ConnectionStatus> {
104+
if (this.disconnectPromise) {
105+
await this.disconnectPromise;
106+
}
99107
// TODO: previously this skipped overlapping connect attempts but that seems awkward
100108
// can we... just not do that? or wait?
101109

@@ -108,7 +116,10 @@ export class MicrobitRadioBridgeConnection
108116
message: "Serial connect start",
109117
});
110118

111-
await this.delegate.connect();
119+
if (this.delegate.status !== ConnectionStatus.CONNECTED) {
120+
await this.delegate.connect();
121+
}
122+
112123
try {
113124
this.serialSession = new RadioBridgeSerialSession(
114125
this.logging,
@@ -137,6 +148,7 @@ export class MicrobitRadioBridgeConnection
137148
);
138149

139150
await this.serialSession.connect();
151+
this.serialSessionOpen = true;
140152

141153
this.logging.event({
142154
type: "Connect",
@@ -154,7 +166,14 @@ export class MicrobitRadioBridgeConnection
154166
}
155167

156168
async disconnect(): Promise<void> {
157-
await this.serialSession?.dispose();
169+
if (this.disconnectPromise) {
170+
return this.disconnectPromise;
171+
}
172+
this.disconnectPromise = (async () => {
173+
this.serialSessionOpen = false;
174+
await this.serialSession?.dispose();
175+
this.disconnectPromise = undefined;
176+
})();
158177
}
159178

160179
private setStatus(status: ConnectionStatus) {
@@ -260,7 +279,6 @@ class RadioBridgeSerialSession {
260279
this.delegate.addEventListener("serialerror", this.serialErrorListener);
261280

262281
try {
263-
await this.delegate.softwareReset();
264282
await this.handshake();
265283
this.onStatusChanged(ConnectionStatus.CONNECTED);
266284

@@ -318,6 +336,7 @@ class RadioBridgeSerialSession {
318336
this.responseMap.clear();
319337
this.delegate.removeEventListener("serialdata", this.serialDataListener);
320338
this.delegate.removeEventListener("serialerror", this.serialErrorListener);
339+
await this.delegate.softwareReset();
321340

322341
this.onStatusChanged(ConnectionStatus.NOT_CONNECTED);
323342
}

lib/usb.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,8 @@ export class MicrobitWebUSBConnection
149149
};
150150
this.removeEventListener = (type, ...args) => {
151151
this._removeEventListener(type, ...args);
152-
if (--this.addedListeners[type] === 0) {
152+
if (--this.addedListeners[type] <= 0) {
153+
this.addedListeners[type] = 0;
153154
this.stopNotifications(type);
154155
}
155156
};

0 commit comments

Comments
 (0)