Skip to content

Commit

Permalink
fix(connect): edgecase where device is not detected during fw update …
Browse files Browse the repository at this point in the history
…using the old bridge
  • Loading branch information
mroz22 committed Feb 3, 2025
1 parent e411dee commit 5fa3d45
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 4 deletions.
37 changes: 35 additions & 2 deletions packages/connect/src/core/onCallFirmwareUpdate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,37 @@ const waitForReconnectedDevice = async (
} catch {
/* empty */
}

// general logic (DeviceList/Device) refuses to call getFeatures if the reported descriptor has a session.
// the reason for session to be still there is this scenario:
// 1. reboot to bootloader is called
// 2. old bridge uses cca 200ms enumeration loop. If device appears on usb in the right time, bridge does not consider it
// a disconnect and it does not flush sessions
// 3. listen now reported a new device in bootloader mode but it still has the session from the previous device in normal mode
// 4. now we automatically take the device, as if user clicked on the "use device here button"

if (
reconnectedDevice &&
!reconnectedDevice.features &&
reconnectedDevice.handshakeFinished
) {
log.debug(
'onCallFirmwareUpdate',
'we were unable to read device.features on the first interaction after seeing it, retrying...',
);
try {
// todo: it keeps printing warning "Previous call is still running" on reconnect from bl to normal
await reconnectedDevice.run(undefined, {
skipFirmwareChecks: true,
skipLanguageChecks: true,
});
} catch {
// empty
}
}

i++;
log.debug('onCallFirmwareUpdate', 'waiting for device to reconnect', i);
log.debug('onCallFirmwareUpdate', '...still waiting for device to reconnect', i);
} while (
!abortSignal.aborted &&
(!reconnectedDevice?.features ||
Expand All @@ -123,7 +152,10 @@ const waitForReconnectedDevice = async (

registerEvents(reconnectedDevice, postMessage);
await reconnectedDevice.waitForFirstRun();
await reconnectedDevice.acquire();

if (!reconnectedDevice.isUsedHere()) {
await reconnectedDevice.acquire();
}

return reconnectedDevice;
};
Expand Down Expand Up @@ -267,6 +299,7 @@ const firmwareCheck = async (
progress: 0,
}),
);

const { hash, challenge } = calculateFirmwareHash(
device.features.major_version,
stripped,
Expand Down
14 changes: 12 additions & 2 deletions packages/connect/src/device/Device.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ type RunOptions = {
skipFinalReload?: boolean;
keepSession?: boolean;
useCardanoDerivation?: boolean;
skipFirmwareChecks?: boolean;
skipLanguageChecks?: boolean;
};

export const GET_FEATURES_TIMEOUT = 3_000;
Expand Down Expand Up @@ -203,6 +205,9 @@ export class Device extends TypedEmitter<DeviceEvents> {

private sessionDfd?: Deferred<Session | null>;

// todo: marek will solve this
public handshakeFinished = false;

constructor({ id, transport, descriptor, listener }: DeviceParams) {
super();

Expand Down Expand Up @@ -385,6 +390,8 @@ export class Device extends TypedEmitter<DeviceEvents> {
}
}

this.handshakeFinished = true;

return;
}
}
Expand Down Expand Up @@ -590,10 +597,13 @@ export class Device extends TypedEmitter<DeviceEvents> {
}
}

await this.checkFirmwareHashWithRetries();
await this.checkFirmwareRevisionWithRetries();
if (!options.skipFirmwareChecks) {
await this.checkFirmwareHashWithRetries();
await this.checkFirmwareRevisionWithRetries();
}

if (
!options.skipLanguageChecks &&
this.features?.language &&
!this.features.language_version_matches &&
this.atLeast('2.7.0')
Expand Down

0 comments on commit 5fa3d45

Please sign in to comment.