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 Jean-Philippe Brucker

Files at this revision

API Documentation at this revision

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

BatteryService.h Show annotated file Show diff for this revision Revisions of this file
DeviceInformationService.h Show annotated file Show diff for this revision Revisions of this file
HIDServiceBase.cpp Show annotated file Show diff for this revision Revisions of this file
HIDServiceBase.h Show annotated file Show diff for this revision Revisions of this file
--- /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;