(
- UPDATE FINAL FIRMARE (TEMPLATE + ACTION WIP) {deviceInfo.final}
+ UPDATE FINAL FIRMARE (TEMPLATE + ACTION WIP) {deviceInfo.isOSU}
)}
renderMcuUpdate={(device: Device, deviceInfo: DeviceInfo) => (
diff --git a/src/components/Workflow/EnsureDashboard.js b/src/components/Workflow/EnsureDashboard.js
index e7b86416..bc762558 100644
--- a/src/components/Workflow/EnsureDashboard.js
+++ b/src/components/Workflow/EnsureDashboard.js
@@ -7,12 +7,7 @@ import type { Device } from 'types/common'
import getDeviceInfo from 'commands/getDeviceInfo'
-type DeviceInfo = {
- targetId: number | string,
- version: string,
- final: boolean,
- mcu: boolean,
-}
+import type { DeviceInfo } from 'helpers/devices/getDeviceInfo'
type Error = {
message: string,
diff --git a/src/components/Workflow/EnsureGenuine.js b/src/components/Workflow/EnsureGenuine.js
index a1890480..2ebc5729 100644
--- a/src/components/Workflow/EnsureGenuine.js
+++ b/src/components/Workflow/EnsureGenuine.js
@@ -15,7 +15,8 @@ type Error = {
type DeviceInfos = {
targetId: number | string,
- version: string,
+ seVersion: string,
+ providerName: string,
}
type Props = {
@@ -60,8 +61,15 @@ class EnsureGenuine extends PureComponent {
if (device && infos && !this._checking) {
this._checking = true
try {
+ const versionName = `${infos.seVersion}${
+ infos.providerName ? `-${infos.providerName}` : ''
+ }`
const res = await getIsGenuine
- .send({ devicePath: device.path, targetId: infos.targetId, version: infos.version })
+ .send({
+ devicePath: device.path,
+ targetId: infos.targetId,
+ version: versionName,
+ })
.pipe(timeout(GENUINE_TIMEOUT))
.toPromise()
if (this._unmounting) return
diff --git a/src/components/Workflow/index.js b/src/components/Workflow/index.js
index e3db974f..7c778f63 100644
--- a/src/components/Workflow/index.js
+++ b/src/components/Workflow/index.js
@@ -1,6 +1,7 @@
// @flow
import React, { PureComponent } from 'react'
+import type { DeviceInfo } from 'helpers/devices/getDeviceInfo'
import type { Node } from 'react'
import type { Device } from 'types/common'
@@ -9,13 +10,6 @@ import EnsureDevice from './EnsureDevice'
import EnsureDashboard from './EnsureDashboard'
import EnsureGenuine from './EnsureGenuine'
-type DeviceInfo = {
- targetId: number | string,
- version: string,
- final: boolean,
- mcu: boolean,
-}
-
type Error = {
message: string,
stack: string,
@@ -55,11 +49,11 @@ class Workflow extends PureComponent {
{(device: Device) => (
{(deviceInfo: ?DeviceInfo, dashboardError: ?Error) => {
- if (deviceInfo && deviceInfo.mcu && renderMcuUpdate) {
+ if (deviceInfo && deviceInfo.isBootloader && renderMcuUpdate) {
return renderMcuUpdate(device, deviceInfo)
}
- if (deviceInfo && deviceInfo.final && renderFinalUpdate) {
+ if (deviceInfo && deviceInfo.isOSU && renderFinalUpdate) {
return renderFinalUpdate(device, deviceInfo)
}
diff --git a/src/helpers/common.js b/src/helpers/common.js
index 3d5a9c30..a8e4bb13 100644
--- a/src/helpers/common.js
+++ b/src/helpers/common.js
@@ -32,9 +32,20 @@ export async function getFirmwareInfo(transport: Transport<*>) {
const data = byteArray.slice(0, byteArray.length - 2)
const targetIdStr = Buffer.from(data.slice(0, 4))
const targetId = targetIdStr.readUIntBE(0, 4)
- const versionLength = data[4]
- const version = Buffer.from(data.slice(5, 5 + versionLength)).toString()
- return { targetId, version }
+ const seVersionLength = data[4]
+ const seVersion = Buffer.from(data.slice(5, 5 + seVersionLength)).toString()
+ const flagsLength = data[5 + seVersionLength]
+ const flags = Buffer.from(
+ data.slice(5 + seVersionLength + 1, 5 + seVersionLength + 1 + flagsLength),
+ ).toString()
+ const mcuVersionLength = data[5 + seVersionLength + 1 + flagsLength]
+ const mcuVersion = Buffer.from(
+ data.slice(
+ 7 + seVersionLength + flagsLength,
+ 7 + seVersionLength + flagsLength + mcuVersionLength,
+ ),
+ ).toString()
+ return { targetId, seVersion, flags, mcuVersion }
} catch (err) {
const error = new Error(err.message)
error.stack = err.stack
diff --git a/src/helpers/devices/getDeviceInfo.js b/src/helpers/devices/getDeviceInfo.js
index 06a1e2be..34bf6fe6 100644
--- a/src/helpers/devices/getDeviceInfo.js
+++ b/src/helpers/devices/getDeviceInfo.js
@@ -4,23 +4,193 @@ import type Transport from '@ledgerhq/hw-transport'
import { getFirmwareInfo } from 'helpers/common'
-type Result = {
+export type DeviceInfo = {
targetId: string | number,
- version: string,
- mcu: boolean,
- final: boolean,
+ seVersion: string,
+ isBootloader: boolean,
+ flags: string,
+ mcuVersion: string,
+ isOSU: boolean,
+ providerName: string,
}
-export default async (transport: Transport<*>): Promise => {
- try {
- const { targetId, version } = await getFirmwareInfo(transport)
- const finalReady = version.endsWith('-osu')
- const mcuReady = targetId === 0x01000001
+const DETECT_CLUBCOIN = [
+ [0xe0, 0x04, 0x00, 0x00, 0x04, 0x31, 0x10, 0x00, 0x02],
+ [0xe0, 0x50, 0x00, 0x00, 0x08, 0xe4, 0x6c, 0x4c, 0x71, 0x8b, 0xc8, 0x7f, 0xb7],
+ [
+ 0xe0,
+ 0x51,
+ 0x80,
+ 0x00,
+ 0x8a,
+ 0x41,
+ 0x04,
+ 0xc9,
+ 0x8c,
+ 0xa0,
+ 0x99,
+ 0x53,
+ 0x47,
+ 0x2b,
+ 0x36,
+ 0x06,
+ 0x1e,
+ 0x0e,
+ 0x40,
+ 0xc9,
+ 0x3d,
+ 0x50,
+ 0x52,
+ 0x34,
+ 0x09,
+ 0x0e,
+ 0xfd,
+ 0x74,
+ 0xf1,
+ 0xd7,
+ 0xa2,
+ 0x93,
+ 0xe8,
+ 0x28,
+ 0x15,
+ 0x9a,
+ 0x97,
+ 0x71,
+ 0x1b,
+ 0x33,
+ 0xd1,
+ 0x8a,
+ 0xfc,
+ 0x17,
+ 0xad,
+ 0x15,
+ 0x6e,
+ 0xae,
+ 0xd9,
+ 0x9c,
+ 0xf4,
+ 0x3b,
+ 0x20,
+ 0xe1,
+ 0x5d,
+ 0x64,
+ 0xaf,
+ 0x39,
+ 0xa5,
+ 0x51,
+ 0x3b,
+ 0x4e,
+ 0x3c,
+ 0x5f,
+ 0x43,
+ 0x17,
+ 0xe6,
+ 0x42,
+ 0x70,
+ 0x2f,
+ 0x05,
+ 0x47,
+ 0x30,
+ 0x45,
+ 0x02,
+ 0x21,
+ 0x00,
+ 0xf1,
+ 0xd2,
+ 0xb8,
+ 0x34,
+ 0x99,
+ 0x4a,
+ 0x0c,
+ 0x1f,
+ 0x25,
+ 0xea,
+ 0x20,
+ 0xcf,
+ 0x33,
+ 0xe3,
+ 0x2b,
+ 0xd0,
+ 0x6b,
+ 0xcf,
+ 0x7c,
+ 0x42,
+ 0x4a,
+ 0x02,
+ 0xee,
+ 0xe8,
+ 0xf6,
+ 0x96,
+ 0x99,
+ 0x20,
+ 0xe1,
+ 0xe8,
+ 0xc2,
+ 0xb3,
+ 0x02,
+ 0x20,
+ 0x63,
+ 0x2d,
+ 0x19,
+ 0xbd,
+ 0x30,
+ 0xab,
+ 0x20,
+ 0x76,
+ 0x18,
+ 0x78,
+ 0x78,
+ 0xae,
+ 0xaa,
+ 0x0f,
+ 0x4d,
+ 0x48,
+ 0x04,
+ 0x01,
+ 0x32,
+ 0x79,
+ 0xd0,
+ 0x16,
+ 0xde,
+ 0xca,
+ 0x66,
+ 0x93,
+ 0xf3,
+ 0x7b,
+ 0x4e,
+ 0x50,
+ 0x7f,
+ 0x43,
+ ],
+]
- return { targetId, version, final: finalReady, mcu: mcuReady }
- } catch (err) {
- const error = Error(err.message)
- error.stack = err.stack
- throw error
+export default async (transport: Transport<*>): Promise => {
+ const res = await getFirmwareInfo(transport)
+ let { seVersion } = res
+ const { targetId, mcuVersion, flags } = res
+ if (seVersion === '1.2') {
+ try {
+ DETECT_CLUBCOIN.forEach(async apdus => {
+ await transport.send(...apdus)
+ })
+ seVersion = '1.2.0-club'
+ } catch (e) {
+ seVersion = '1.2.0'
+ }
+ }
+ const parsedVersion = seVersion.match(/[0-9]+.[0-9]+(.[0-9]+)?(-[a-z]+)?(-osu)?/) || []
+ const isOSU = typeof parsedVersion[5] !== 'undefined'
+ const providerName = parsedVersion[4] || ''
+ const isBootloader = targetId === 0x01000001
+ const majMin = parsedVersion[1]
+ const patch = parsedVersion[2] || '.0'
+ return {
+ targetId,
+ seVersion: majMin + patch,
+ isOSU,
+ mcuVersion,
+ isBootloader,
+ providerName,
+ flags,
}
}