HID-over-GATT implementation with the BLE API. This library allows to create devices such as mouse, keyboard or joystick, over Bluetooth Low Energy.
Dependents: MtConnect04S_Gesture_HID
Fork of BLE_HID by
Revision 5:dc4e6dbcb79b, committed 2017-01-17
- Comitter:
- bcc6
- Date:
- Tue Jan 17 03:48:12 2017 +0000
- Parent:
- 4:c02f0fe0db5f
- Commit message:
- Add PNP_ID in DeviceInformationService; Add bootKeyboardInputReportCharacteristic, bootKeyboardOutputReportCharacteristic in HIDServiceBase
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BatteryService.h Tue Jan 17 03:48:12 2017 +0000 @@ -0,0 +1,77 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __BLE_BATTERY_SERVICE_H__ +#define __BLE_BATTERY_SERVICE_H__ + +#include "ble/BLE.h" + +/** +* @class BatteryService +* @brief BLE Battery Service. This service displays the battery level from 0% to 100%, represented as an 8bit number. +* Service: https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.battery_service.xml +* Battery Level Char: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.battery_level.xml +*/ +class BatteryService { +public: + /** + * @param[in] _ble + * BLE object for the underlying controller. + * @param[in] level + * 8bit batterly level. Usually used to represent percentage of batterly charge remaining. + */ + BatteryService(BLE &_ble, uint8_t level = 100) : + ble(_ble), + batteryLevel(level), + batteryLevelCharacteristic(GattCharacteristic::UUID_BATTERY_LEVEL_CHAR, &batteryLevel, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY) { + + GattCharacteristic *charTable[] = {&batteryLevelCharacteristic}; + GattService batteryService(GattService::UUID_BATTERY_SERVICE, charTable, sizeof(charTable) / sizeof(GattCharacteristic *)); + + ble.addService(batteryService); + } + + /** + * @brief Update the battery level with a new value. Valid values lie between 0 and 100, + * anything outside this range will be ignored. + * + * @param newLevel + * Update to battery level. + */ + void updateBatteryLevel(uint8_t newLevel) { + batteryLevel = newLevel; + ble.gattServer().write(batteryLevelCharacteristic.getValueHandle(), &batteryLevel, 1); + } + +protected: + /** + * A reference to the underlying BLE instance that this object is attached to. + * The services and characteristics will be registered in this BLE instance. + */ + BLE &ble; + + /** + * The current battery level represented as an integer from 0% to 100%. + */ + uint8_t batteryLevel; + /** + * A ReadOnlyGattCharacteristic that allows access to the peer device to the + * batteryLevel value through BLE. + */ + ReadOnlyGattCharacteristic<uint8_t> batteryLevelCharacteristic; +}; + +#endif /* #ifndef __BLE_BATTERY_SERVICE_H__*/ \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DeviceInformationService.h Tue Jan 17 03:48:12 2017 +0000 @@ -0,0 +1,164 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __BLE_DEVICE_INFORMATION_SERVICE_H__ +#define __BLE_DEVICE_INFORMATION_SERVICE_H__ + +#include "ble/BLE.h" + + +/* https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.characteristic.pnp_id.xml */ +#pragma pack(push, 1) +typedef struct { + uint8_t vendorID_source; + uint16_t vendorID; + uint16_t productID; + uint16_t productVersion; +} PnPID_t; +#pragma pack(pop) + + +/** +* @class DeviceInformationService +* @brief BLE Device Information Service +* Service: https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.device_information.xml +* Manufacturer Name String Char: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.manufacturer_name_string.xml +*/ +class DeviceInformationService { +public: + /** + * @brief Device Information Service Constructor: copies device-specific information + * into the BLE stack. + * + * @param[in] _ble + * A reference to a BLE object for the underlying controller. + * @param[in] manufacturersName + * The name of the manufacturer of the device. + * @param[in] modelNumber + * The model number that is assigned by the device vendor. + * @param[in] serialNumber + * The serial number for a particular instance of the device. + * @param[in] hardwareRevision + * The hardware revision for the hardware within the device. + * @param[in] firmwareRevision + * The device's firmware version. + * @param[in] softwareRevision + * The device's software version. + * @param[in] pnpID + * vendor id, product id and version. + */ + DeviceInformationService(BLE &_ble, + const char *manufacturersName = NULL, + const char *modelNumber = NULL, + const char *serialNumber = NULL, + const char *hardwareRevision = NULL, + const char *firmwareRevision = NULL, + const char *softwareRevision = NULL, + PnPID_t *pnpID = NULL) : + ble(_ble), + manufacturersNameStringCharacteristic(GattCharacteristic::UUID_MANUFACTURER_NAME_STRING_CHAR, + (uint8_t *)manufacturersName, + (manufacturersName != NULL) ? strlen(manufacturersName) : 0, /* Min length */ + (manufacturersName != NULL) ? strlen(manufacturersName) : 0, /* Max length */ + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ), + modelNumberStringCharacteristic(GattCharacteristic::UUID_MODEL_NUMBER_STRING_CHAR, + (uint8_t *)modelNumber, + (modelNumber != NULL) ? strlen(modelNumber) : 0, /* Min length */ + (modelNumber != NULL) ? strlen(modelNumber) : 0, /* Max length */ + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ), + serialNumberStringCharacteristic(GattCharacteristic::UUID_SERIAL_NUMBER_STRING_CHAR, + (uint8_t *)serialNumber, + (serialNumber != NULL) ? strlen(serialNumber) : 0, /* Min length */ + (serialNumber != NULL) ? strlen(serialNumber) : 0, /* Max length */ + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ), + hardwareRevisionStringCharacteristic(GattCharacteristic::UUID_HARDWARE_REVISION_STRING_CHAR, + (uint8_t *)hardwareRevision, + (hardwareRevision != NULL) ? strlen(hardwareRevision) : 0, /* Min length */ + (hardwareRevision != NULL) ? strlen(hardwareRevision) : 0, /* Max length */ + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ), + firmwareRevisionStringCharacteristic(GattCharacteristic::UUID_FIRMWARE_REVISION_STRING_CHAR, + (uint8_t *)firmwareRevision, + (firmwareRevision != NULL) ? strlen(firmwareRevision) : 0, /* Min length */ + (firmwareRevision != NULL) ? strlen(firmwareRevision) : 0, /* Max length */ + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ), + softwareRevisionStringCharacteristic(GattCharacteristic::UUID_SOFTWARE_REVISION_STRING_CHAR, + (uint8_t *)softwareRevision, + (softwareRevision != NULL) ? strlen(softwareRevision) : 0, /* Min length */ + (softwareRevision != NULL) ? strlen(softwareRevision) : 0, /* Max length */ + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ), + pnpIDCharacteristic(GattCharacteristic::UUID_PNP_ID_CHAR, + pnpID) + { + static bool serviceAdded = false; /* We only add the information service once. */ + if (serviceAdded) { + return; + } + + /* required for OS X bonding */ + pnpIDCharacteristic.requireSecurity(SecurityManager::SECURITY_MODE_ENCRYPTION_NO_MITM); + + GattCharacteristic *charTable[] = {&manufacturersNameStringCharacteristic, + &modelNumberStringCharacteristic, + &serialNumberStringCharacteristic, + &hardwareRevisionStringCharacteristic, + &firmwareRevisionStringCharacteristic, + &softwareRevisionStringCharacteristic, + &pnpIDCharacteristic}; + GattService deviceInformationService(GattService::UUID_DEVICE_INFORMATION_SERVICE, charTable, + sizeof(charTable) / sizeof(GattCharacteristic *)); + + ble.addService(deviceInformationService); + serviceAdded = true; + } + +protected: + /** + * A reference to the BLE instance object to which the services and + * characteristics will be added. + */ + BLE &ble; + /** + * BLE characterising to allow BLE peers access to the manufacturer's name. + */ + GattCharacteristic manufacturersNameStringCharacteristic; + /** + * BLE characterising to allow BLE peers access to the model number. + */ + GattCharacteristic modelNumberStringCharacteristic; + /** + * BLE characterising to allow BLE peers access to the serial number. + */ + GattCharacteristic serialNumberStringCharacteristic; + /** + * BLE characterising to allow BLE peers access to the hardware revision string. + */ + GattCharacteristic hardwareRevisionStringCharacteristic; + /** + * BLE characterising to allow BLE peers access to the firmware revision string. + */ + GattCharacteristic firmwareRevisionStringCharacteristic; + /** + * BLE characterising to allow BLE peers access to the software revision string. + */ + GattCharacteristic softwareRevisionStringCharacteristic; + /** + * BLE characterising to allow BLE peers access to the PnP ID. + */ + ReadOnlyGattCharacteristic<PnPID_t> pnpIDCharacteristic; +}; + +#endif /* #ifndef __BLE_DEVICE_INFORMATION_SERVICE_H__*/ +
--- a/HIDServiceBase.cpp Fri Dec 16 10:26:25 2016 +0000 +++ b/HIDServiceBase.cpp Tue Jan 17 03:48:12 2017 +0000 @@ -72,6 +72,18 @@ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE, featureReportDescriptors(), 1), + bootKeyboardInputReportCharacteristic(GattCharacteristic::UUID_BOOT_KEYBOARD_INPUT_REPORT_CHAR, + (uint8_t *)inputReport, inputReportLength, inputReportLength, + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ + | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY + | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE), + + bootKeyboardOutputReportCharacteristic(GattCharacteristic::UUID_BOOT_KEYBOARD_OUTPUT_REPORT_CHAR, + (uint8_t *)outputReport, outputReportLength, outputReportLength, + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ + | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE + | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE), + /* * We need to set reportMap content as const, in order to let the compiler put it into flash * instead of RAM. The characteristic is read-only so it won't be written, but @@ -112,6 +124,10 @@ characteristics[charIndex++] = &outputReportCharacteristic; if (featureReportLength) characteristics[charIndex++] = &featureReportCharacteristic; + if (inputReportLength) + characteristics[charIndex++] = &bootKeyboardInputReportCharacteristic; + if (outputReportLength) + characteristics[charIndex++] = &bootKeyboardOutputReportCharacteristic; /* TODO: let children add some more characteristics, namely boot keyboard and mouse (They are * mandatory as per HIDS spec.) Ex: @@ -150,6 +166,8 @@ inputReportCharacteristic.requireSecurity(securityMode); outputReportCharacteristic.requireSecurity(securityMode); featureReportCharacteristic.requireSecurity(securityMode); + bootKeyboardInputReportCharacteristic.requireSecurity(securityMode); + bootKeyboardOutputReportCharacteristic.requireSecurity(securityMode); } void HIDServiceBase::startReportTicker(void) { @@ -206,9 +224,19 @@ } ble_error_t HIDServiceBase::send(const report_t report) { - return ble.gattServer().write(inputReportCharacteristic.getValueHandle(), - report, - inputReportLength); + if (protocolMode == REPORT_PROTOCOL) { + return ble.gattServer().write( + inputReportCharacteristic.getValueHandle(), + report, + inputReportLength + ); + } else { + return ble.gattServer().write( + bootKeyboardInputReportCharacteristic.getValueHandle(), + report, + inputReportLength + ); + } } ble_error_t HIDServiceBase::read(report_t report) {
--- a/HIDServiceBase.h Fri Dec 16 10:26:25 2016 +0000 +++ b/HIDServiceBase.h Tue Jan 17 03:48:12 2017 +0000 @@ -185,6 +185,9 @@ GattCharacteristic inputReportCharacteristic; GattCharacteristic outputReportCharacteristic; GattCharacteristic featureReportCharacteristic; + // Share input/output report with Report Protocol for memmory saving + GattCharacteristic bootKeyboardInputReportCharacteristic; + GattCharacteristic bootKeyboardOutputReportCharacteristic; // Required gatt characteristics: Report Map, Information, Control Point GattCharacteristic reportMapCharacteristic;