diff --git a/packages/connect/src/device/Device.ts b/packages/connect/src/device/Device.ts index 15687750b3..b2dbfed252 100644 --- a/packages/connect/src/device/Device.ts +++ b/packages/connect/src/device/Device.ts @@ -131,7 +131,7 @@ type DeviceParams = { export class Device extends TypedEmitter { public readonly transport: Transport; private thp: protocolThp.ThpState | undefined; - public readonly descriptor: Pick; + public readonly descriptor: Pick; private sessionAcquired: Session | null; // protocol related @@ -239,6 +239,7 @@ export class Device extends TypedEmitter { apiType: descriptor.apiType, type: descriptor.type, path: descriptor.path, + model: descriptor.model, // session, sessionOwner are handled separately // debug, debugSession are not relevant here }; diff --git a/packages/transport-bluetooth/src/client/bluetooth-api.ts b/packages/transport-bluetooth/src/client/bluetooth-api.ts index bb3c061a4f..dbf96b276e 100644 --- a/packages/transport-bluetooth/src/client/bluetooth-api.ts +++ b/packages/transport-bluetooth/src/client/bluetooth-api.ts @@ -6,6 +6,7 @@ import { import { DEVICE_TYPE } from '@trezor/transport/src/constants'; import * as ERRORS from '@trezor/transport/src/errors'; import { PathInternal } from '@trezor/transport/src/types'; +import { getBLEDescriptorModel } from '@trezor/transport/src/utils/descriptor'; import { readMessageBuffer } from '@trezor/transport/src/utils/readMessageBuffer'; import { TrezorBluetooth } from './trezor-bluetooth'; @@ -36,6 +37,7 @@ export class BluetoothApi extends AbstractApi { type: DEVICE_TYPE.TypeBluetooth, id: device.id, apiType: this.type, + model: getBLEDescriptorModel(device.data[2]), })); } diff --git a/packages/transport/src/api/usb.ts b/packages/transport/src/api/usb.ts index 6d08170c6b..1c6b128604 100644 --- a/packages/transport/src/api/usb.ts +++ b/packages/transport/src/api/usb.ts @@ -15,6 +15,7 @@ import { } from '../constants'; import * as ERRORS from '../errors'; import { DescriptorApiLevel, PathInternal } from '../types'; +import { getUSBDescriptorModel } from '../utils/descriptor'; interface ConstructorParams extends Omit { usbInterface: USB; @@ -136,6 +137,7 @@ export class UsbApi extends AbstractApi { vendor: d.device.vendorId, id: d.device.serialNumber, apiType: this.type, + model: getUSBDescriptorModel(d.device), })); } diff --git a/packages/transport/src/types/index.ts b/packages/transport/src/types/index.ts index 707b1cb2e2..328472a7d4 100644 --- a/packages/transport/src/types/index.ts +++ b/packages/transport/src/types/index.ts @@ -1,6 +1,7 @@ import { Branded } from '@trezor/type-utils'; import { DEVICE_TYPE } from '../constants'; +import type { DescriptorModel } from '../utils/descriptor'; export * from './apiCall'; @@ -24,6 +25,8 @@ export type DescriptorApiLevel = { apiType: ApiType; /** api level device id. */ id?: string; + /** api level device model */ + model?: DescriptorModel; }; export type Descriptor = Omit & { diff --git a/packages/transport/src/utils/bridgeApiResult.ts b/packages/transport/src/utils/bridgeApiResult.ts index 2e7dd39e5c..c17ff85210 100644 --- a/packages/transport/src/utils/bridgeApiResult.ts +++ b/packages/transport/src/utils/bridgeApiResult.ts @@ -65,6 +65,7 @@ export function devices(res: UnknownPayload) { debugSession: o.debugSession, id: o.id, apiType: o.apiType || 'usb', // no other option is implemented at this moment + model: o.model, }), ), ); diff --git a/packages/transport/src/utils/descriptor.ts b/packages/transport/src/utils/descriptor.ts new file mode 100644 index 0000000000..a0c96f1d80 --- /dev/null +++ b/packages/transport/src/utils/descriptor.ts @@ -0,0 +1,47 @@ +/** + * references: DeviceModelInternal, MODEL_BLE_CODE + * DeviceModelInternal represented as number + */ +export enum DescriptorModel { + UNKNOWN = 0, + T1B1 = 1, + T2T1 = 2, + T2B1 = 3, + T3B1 = 4, + T3T1 = 5, + T3W1 = 6, +} + +/** + * Returns DescriptorModel from USBDevice + */ +export const getUSBDescriptorModel = (device: USBDevice): DescriptorModel => { + if (device.deviceVersionMajor === 1) { + return DescriptorModel.T1B1; + } + + if (device.deviceVersionMajor === 2) { + switch (device.productName) { + case 'TREZOR': + return DescriptorModel.T2T1; + case 'Trezor Safe 3': + return DescriptorModel.T3B1; // NOTE: this could be also T2B1 + case 'Trezor Safe 5': + return DescriptorModel.T3T1; + case 'Trezor Safe 7': + return DescriptorModel.T3W1; + default: + return DescriptorModel.UNKNOWN; + } + } + + return DescriptorModel.UNKNOWN; +}; + +/** + * Returns DescriptorModel from bluetooth Manufacturer Data [2] byte. see MODEL_BLE_CODE + */ +export const getBLEDescriptorModel = (data: number | undefined): DescriptorModel => + typeof data === 'number' && Object.values(DescriptorModel).includes(data) + ? data + : DescriptorModel.UNKNOWN; diff --git a/packages/transport/tests/abstractUsb.test.ts b/packages/transport/tests/abstractUsb.test.ts index b693288474..cec69d35c7 100644 --- a/packages/transport/tests/abstractUsb.test.ts +++ b/packages/transport/tests/abstractUsb.test.ts @@ -140,6 +140,7 @@ describe('Usb', () => { path: '1', session: null, type: 1, + model: 0, product: 21441, vendor: 4617, apiType: 'usb', @@ -149,6 +150,7 @@ describe('Usb', () => { path: '2', session: null, type: 1, + model: 0, product: 21441, vendor: 4617, apiType: 'usb',