Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(app): tighten filter logic that identifies Realtek U2E adapters #5707

Merged
merged 1 commit into from
May 20, 2020
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
2 changes: 1 addition & 1 deletion app/src/analytics/make-event.js
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ export function makeEvent(

const superProperties = head(
devices
.filter(SystemInfo.isRealtekDevice)
.filter(SystemInfo.isRealtekU2EAdapter)
.map(SystemInfo.deviceToU2EAnalyticsProps)
)

Expand Down
2 changes: 1 addition & 1 deletion app/src/support/profile.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ export function makeProfileUpdate(

const update = head(
devices
.filter(SystemInfo.isRealtekDevice)
.filter(SystemInfo.isRealtekU2EAdapter)
.map(SystemInfo.deviceToU2EAnalyticsProps)
)

Expand Down
16 changes: 8 additions & 8 deletions app/src/system-info/__fixtures__/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ export const mockUsbDevice: UsbDevice = {

export const mockRealtekDevice: UsbDevice = {
locationId: 1,
// 0x0010
vendorId: 16,
// 0x00A0
productId: 160,
// 0x0BDA
vendorId: 3034,
// 0x8150
productId: 33104,
deviceName: 'USB 10/100 LAN',
manufacturer: 'Realtek',
serialNumber: 'Serial Number',
Expand All @@ -27,10 +27,10 @@ export const mockRealtekDevice: UsbDevice = {

export const mockWindowsRealtekDevice: UsbDevice = {
locationId: 1,
// 0x0100
vendorId: 256,
// 0x0A00
productId: 2560,
// 0x0BDA
vendorId: 3034,
// 0x8150
productId: 33104,
deviceName: 'Realtek USB FE Family Controller',
manufacturer: 'Realtek',
serialNumber: 'Serial Number',
Expand Down
34 changes: 33 additions & 1 deletion app/src/system-info/__tests__/utils.test.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,41 @@
// @flow

import { mockUsbDevice, mockRealtekDevice } from '../__fixtures__'
import { getDriverStatus } from '../utils'
import { isRealtekU2EAdapter, getDriverStatus } from '../utils'

describe('system info utilities', () => {
describe('isRealtekU2EAdapter', () => {
it('should return false if device VID is not Realtek (0x0BDA)', () => {
const device = { ...mockRealtekDevice, vendorId: parseInt('1234', 16) }
const isAdapter = isRealtekU2EAdapter(device)
expect(isAdapter).toBe(false)
})

// NOTE(mc, 2020-05-20): this is not the expected value for a RTL8150 chip
// our device reports 8050 for some reason instead of 8150
// https://devicehunt.com/view/type/usb/vendor/0BDA/device/8150
it('should return true if device PID is 0x8050', () => {
const device = { ...mockRealtekDevice, productId: parseInt('8050', 16) }
const isAdapter = isRealtekU2EAdapter(device)
expect(isAdapter).toBe(true)
})

// just for safety, catch the canonical PIDs, too
// these are the model numbers listed on Realtek's driver page
// https://www.realtek.com/en/component/zoo/category/network-interface-controllers-10-100-1000m-gigabit-ethernet-usb-3-0-software
it('should return true if device PID is 0x815x', () => {
const devices = [
{ ...mockRealtekDevice, productId: parseInt('8150', 16) },
{ ...mockRealtekDevice, productId: parseInt('8151', 16) },
{ ...mockRealtekDevice, productId: parseInt('8152', 16) },
{ ...mockRealtekDevice, productId: parseInt('8153', 16) },
{ ...mockRealtekDevice, productId: parseInt('8154', 16) },
{ ...mockRealtekDevice, productId: parseInt('8156', 16) },
]
expect(devices.every(isRealtekU2EAdapter)).toBe(true)
})
})

describe('getDriverStatus', () => {
it('should return NOT_APPLICABLE if device is not Realtek', () => {
const device = mockUsbDevice
Expand Down
4 changes: 2 additions & 2 deletions app/src/system-info/selectors.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// @flow
import { createSelector } from 'reselect'
import { isRealtekDevice, getDriverStatus } from './utils'
import { isRealtekU2EAdapter, getDriverStatus } from './utils'
import { NOT_APPLICABLE } from './constants'

import type { State } from '../types'
Expand All @@ -10,7 +10,7 @@ export const getU2EAdapterDevice: (
state: State
) => UsbDevice | null = createSelector(
state => state.systemInfo.usbDevices,
usbDevices => usbDevices.find(isRealtekDevice) ?? null
usbDevices => usbDevices.find(isRealtekU2EAdapter) ?? null
)

export const getU2EWindowsDriverStatus: (
Expand Down
20 changes: 15 additions & 5 deletions app/src/system-info/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,19 @@ import { NOT_APPLICABLE, UNKNOWN, UP_TO_DATE, OUTDATED } from './constants'

import type { UsbDevice, U2EAnalyticsProps, DriverStatus } from './types'

const RE_REALTEK = /realtek/i

// Driver version 10.38.117.2020, latest for Windows 10 as of 2020-04-12
// NOTE(mc, 2020-05-05): this will cause false alerts on Windows 7; Realtek's
// versioning scheme seems to be WindowsVersion.Something.Something.Year
// TODO(mc, 2020-05-06): move to config once migrations are addressed
// https://github.com/Opentrons/opentrons/issues/5587
const REALTEK_UP_TO_DATE_VERSION = [10, 38, 117, 2020]

// Our U2E adapter should have the following properties:
// Vendor ID: 0x0BDA, Product ID: 0x8150
// NOTE(mc, 2020-05-20): our device erroneously reports a PID of 0x8050
const REALTEK_VID = parseInt('0BDA', 16)
const RE_REALTEK_PID = /^8[0|1]5[0-9]$/

export const deviceToU2EAnalyticsProps = (
device: UsbDevice
): U2EAnalyticsProps => {
Expand All @@ -32,13 +36,19 @@ export const deviceToU2EAnalyticsProps = (
return result
}

export const isRealtekDevice = (device: UsbDevice): boolean => {
return RE_REALTEK.test(device.manufacturer)
export const isRealtekU2EAdapter = (device: UsbDevice): boolean => {
return (
device.vendorId === REALTEK_VID &&
RE_REALTEK_PID.test(device.productId.toString(16))
)
}

export const getDriverStatus = (device: UsbDevice): DriverStatus => {
const { windowsDriverVersion } = device
if (!isRealtekDevice(device) || typeof windowsDriverVersion === 'undefined') {
if (
!isRealtekU2EAdapter(device) ||
typeof windowsDriverVersion === 'undefined'
) {
return NOT_APPLICABLE
}

Expand Down