ble-uart: decode PnP ID if it exists

This commit is contained in:
David Lechner
2021-06-23 12:31:19 -05:00
parent ec4160dbab
commit 10148fa9cf
2 changed files with 69 additions and 0 deletions
+37
View File
@@ -13,3 +13,40 @@ export const firmwareRevisionStringUUID = 0x2a26;
/** Software Revision String characteristic UUID. */
export const softwareRevisionStringUUID = 0x2a28;
/** PnP ID characteristic UUID. */
export const pnpIdUUID = 0x2a50;
/**
* Parameters for the PnP ID characteristic vendor ID source field.
*/
export enum PnpIdVendorIdSource {
/** The vendor ID was assigned by the Bluetooth SIG. */
BluetoothSig = 1,
/** The vendor and product IDs were assigned by the USB implementors forum. */
UsbImpForum = 2,
}
/**
* Decoded data from the PnP ID characteristic.
*/
export type PnpId = {
vendorIdSource: PnpIdVendorIdSource;
vendorId: number;
productId: number;
productVersion: number;
};
/**
* Decodes data read from the PnP ID characteristics.
* @param data The data read from the characteristic.
* @returns The decoded data.
*/
export function decodePnpId(data: DataView): PnpId {
return {
vendorIdSource: data.getUint8(0),
vendorId: data.getUint16(1, true),
productId: data.getUint16(3, true),
productVersion: data.getUint16(5, true),
};
}
+32
View File
@@ -16,8 +16,11 @@ import {
takeMaybe,
} from 'typed-redux-saga/macro';
import {
PnpId,
decodePnpId,
serviceUUID as deviceInfoServiceUUID,
firmwareRevisionStringUUID,
pnpIdUUID,
softwareRevisionStringUUID,
} from '../ble-device-info-service/protocol';
import {
@@ -45,6 +48,7 @@ import {
} from '../ble/actions';
import { BleConnectionState } from '../ble/reducers';
import { RootState } from '../reducers';
import { hex } from '../utils';
import {
BleUartActionType,
BleUartWriteAction,
@@ -229,6 +233,34 @@ function* connect(_action: BleDeviceConnectAction): Generator {
// TODO: verify that minimum protocol version is met
console.log(`Pybricks protocol version: ${protocolVersion}`);
let pnpIdChar: BluetoothRemoteGATTCharacteristic | undefined = undefined;
try {
pnpIdChar = yield* call([deviceInfoService, 'getCharacteristic'], pnpIdUUID);
} catch (err) {
console.warn(
'PnP ID characteristic requires Pybricks firmware v3.1.0a1 or later',
);
}
if (pnpIdChar) {
let pnpId: PnpId;
try {
pnpId = decodePnpId(yield* call([pnpIdChar, 'readValue']));
} catch (err) {
server.disconnect();
yield* takeMaybe(disconnectChannel);
yield* put(didFailToConnect({ reason: Reason.Unknown, err }));
return;
}
console.log(
`Vendor: ${hex(pnpId.vendorId, 4)}, Product: ${hex(
pnpId.productId,
4,
)}, Version: ${hex(pnpId.productVersion, 4)}`,
);
}
let pybricksService: BluetoothRemoteGATTService;
try {
pybricksService = yield* call(