Skip to content
Merged
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
41 changes: 9 additions & 32 deletions lib/bluetooth-device-wrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,8 @@ import {
import { UARTService } from "./uart-service.js";

export const bondingTimeoutInMs = 40_000;
export const connectTimeoutInMs = 4_000;
export const connectTimeoutInMs = 10_000;
export const scanningTimeoutInMs = 10_000;
const connectionMaxAttempts = 4;

export const isAndroid = () => Capacitor.getPlatform() === "android";

Expand Down Expand Up @@ -83,7 +82,7 @@ export class BluetoothDeviceWrapper implements Logging {
// or reconnection itself.
private duringExplicitConnectDisconnect: number = 0;

private connected = false;
connected = false;
private isReconnect = false;

// Only updated after the full connection flow completes not during bond handling.
Expand Down Expand Up @@ -153,11 +152,13 @@ export class BluetoothDeviceWrapper implements Logging {
try {
if (Capacitor.isNativePlatform()) {
await this.connectHandlingBond();
// We need this on Android for reconnecting after DFU.
await BleClient.discoverServices(this.device.deviceId);
} else {
await this.connectInternal();
}
await this.getBoardVersion();

const events = this.currentEvents();
const services = await BleClient.getServices(this.device.deviceId);
this.serviceIds = new Set(services.map((s) => s.uuid));
Expand Down Expand Up @@ -200,33 +201,10 @@ export class BluetoothDeviceWrapper implements Logging {

private async connectInternal() {
this.waitingForDisconnectEventCallbacks.length = 0;

// Attempt multiple connection tries.
for (let i = 0; i < connectionMaxAttempts; i++) {
try {
// Fail immediately if disconnect occurs whilst connecting.
await this.raceDisconnectAndTimeout(
BleClient.connect(this.device.deviceId, this.handleDisconnectEvent),
{
actionName: "connect internal",
timeout: connectTimeoutInMs,
initiallyDisconnected: true,
},
);
this.connected = true;
return;
} catch (error) {
const attempts = i + 1;
if (attempts === connectionMaxAttempts) {
throw error;
}
const delayDuration = Math.pow(2, i) * 1000; // 1s, 2s, 4s
this.logging.log(
`Attempt ${attempts} failed, retrying in ${delayDuration}ms...`,
);
await delay(delayDuration);
}
}
await BleClient.connect(this.device.deviceId, this.handleDisconnectEvent, {
timeout: connectTimeoutInMs,
});
this.connected = true;
}

async disconnect(): Promise<void> {
Expand Down Expand Up @@ -433,10 +411,9 @@ export class BluetoothDeviceWrapper implements Logging {
options: {
actionName?: string;
timeout?: number;
initiallyDisconnected?: boolean;
} = {},
): Promise<T> {
if (!this.connected && !options.initiallyDisconnected) {
if (!this.connected) {
throw new DisconnectError();
}
const actionName = options.actionName ?? "action";
Expand Down
4 changes: 4 additions & 0 deletions lib/bluetooth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,10 @@ class MicrobitWebBluetoothConnectionImpl

if (partialFlashResult === PartialFlashResult.AttemptFullFlash) {
await fullFlash(connection, boardVersion, memoryMap, progress);
} else if (partialFlashResult === PartialFlashResult.Success) {
if (connection.connected) {
await connection.waitForDisconnect(10_000);
}
}
} catch (e) {
this.error("Failed to flash", e);
Expand Down