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:   BLENano_HID BLE_HID_MouseScrollDemo BLE_HID_KeyboardStreamDemo Shervs_TestKeyboard_TinyBLE ... more

The development repository is currently hosted on github. It contains examples and documentation. This is a snapshot of the library. The documentation can be read on github, or on docs.mbed.com.

Committer:
Jean-Philippe Brucker
Date:
Thu Nov 19 15:00:39 2015 +0000
Revision:
3:4f8429a1905b
Parent:
1:7a6c2e2c9371
Version 0.3

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Jean-Philippe Brucker 1:7a6c2e2c9371 1 /* mbed Microcontroller Library
Jean-Philippe Brucker 1:7a6c2e2c9371 2 * Copyright (c) 2015 ARM Limited
Jean-Philippe Brucker 1:7a6c2e2c9371 3 *
Jean-Philippe Brucker 1:7a6c2e2c9371 4 * Licensed under the Apache License, Version 2.0 (the "License");
Jean-Philippe Brucker 1:7a6c2e2c9371 5 * you may not use this file except in compliance with the License.
Jean-Philippe Brucker 1:7a6c2e2c9371 6 * You may obtain a copy of the License at
Jean-Philippe Brucker 1:7a6c2e2c9371 7 *
Jean-Philippe Brucker 1:7a6c2e2c9371 8 * http://www.apache.org/licenses/LICENSE-2.0
Jean-Philippe Brucker 1:7a6c2e2c9371 9 *
Jean-Philippe Brucker 1:7a6c2e2c9371 10 * Unless required by applicable law or agreed to in writing, software
Jean-Philippe Brucker 1:7a6c2e2c9371 11 * distributed under the License is distributed on an "AS IS" BASIS,
Jean-Philippe Brucker 1:7a6c2e2c9371 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Jean-Philippe Brucker 1:7a6c2e2c9371 13 * See the License for the specific language governing permissions and
Jean-Philippe Brucker 1:7a6c2e2c9371 14 * limitations under the License.
Jean-Philippe Brucker 1:7a6c2e2c9371 15 */
Jean-Philippe Brucker 1:7a6c2e2c9371 16
Jean-Philippe Brucker 0:cfd70fa91663 17 #ifndef HID_SERVICE_BASE_H_
Jean-Philippe Brucker 0:cfd70fa91663 18 #define HID_SERVICE_BASE_H_
Jean-Philippe Brucker 0:cfd70fa91663 19
Jean-Philippe Brucker 0:cfd70fa91663 20 #include "mbed.h"
Jean-Philippe Brucker 0:cfd70fa91663 21
Jean-Philippe Brucker 0:cfd70fa91663 22 #include "ble/BLE.h"
Jean-Philippe Brucker 3:4f8429a1905b 23 #include "USBHID_Types.h"
Jean-Philippe Brucker 0:cfd70fa91663 24
Jean-Philippe Brucker 0:cfd70fa91663 25 #define BLE_UUID_DESCRIPTOR_REPORT_REFERENCE 0x2908
Jean-Philippe Brucker 0:cfd70fa91663 26
Jean-Philippe Brucker 0:cfd70fa91663 27 typedef const uint8_t report_map_t[];
Jean-Philippe Brucker 0:cfd70fa91663 28 typedef const uint8_t * report_t;
Jean-Philippe Brucker 0:cfd70fa91663 29
Jean-Philippe Brucker 0:cfd70fa91663 30 typedef struct {
Jean-Philippe Brucker 0:cfd70fa91663 31 uint16_t bcdHID;
Jean-Philippe Brucker 0:cfd70fa91663 32 uint8_t bCountryCode;
Jean-Philippe Brucker 0:cfd70fa91663 33 uint8_t flags;
Jean-Philippe Brucker 0:cfd70fa91663 34 } HID_information_t;
Jean-Philippe Brucker 0:cfd70fa91663 35
Jean-Philippe Brucker 0:cfd70fa91663 36 enum ReportType {
Jean-Philippe Brucker 0:cfd70fa91663 37 INPUT_REPORT = 0x1,
Jean-Philippe Brucker 0:cfd70fa91663 38 OUTPUT_REPORT = 0x2,
Jean-Philippe Brucker 0:cfd70fa91663 39 FEATURE_REPORT = 0x3,
Jean-Philippe Brucker 0:cfd70fa91663 40 };
Jean-Philippe Brucker 0:cfd70fa91663 41
Jean-Philippe Brucker 0:cfd70fa91663 42 enum ProtocolMode {
Jean-Philippe Brucker 0:cfd70fa91663 43 BOOT_PROTOCOL = 0x0,
Jean-Philippe Brucker 0:cfd70fa91663 44 REPORT_PROTOCOL = 0x1,
Jean-Philippe Brucker 0:cfd70fa91663 45 };
Jean-Philippe Brucker 0:cfd70fa91663 46
Jean-Philippe Brucker 0:cfd70fa91663 47 typedef struct {
Jean-Philippe Brucker 0:cfd70fa91663 48 uint8_t ID;
Jean-Philippe Brucker 0:cfd70fa91663 49 uint8_t type;
Jean-Philippe Brucker 0:cfd70fa91663 50 } report_reference_t;
Jean-Philippe Brucker 0:cfd70fa91663 51
Jean-Philippe Brucker 0:cfd70fa91663 52
Jean-Philippe Brucker 0:cfd70fa91663 53 class HIDServiceBase {
Jean-Philippe Brucker 0:cfd70fa91663 54 public:
Jean-Philippe Brucker 0:cfd70fa91663 55 /**
Jean-Philippe Brucker 0:cfd70fa91663 56 * Constructor
Jean-Philippe Brucker 0:cfd70fa91663 57 *
Jean-Philippe Brucker 0:cfd70fa91663 58 * @param _ble
Jean-Philippe Brucker 0:cfd70fa91663 59 * BLE object to add this service to
Jean-Philippe Brucker 0:cfd70fa91663 60 * @param reportMap
Jean-Philippe Brucker 0:cfd70fa91663 61 * Byte array representing the input/output report formats. In USB HID jargon, it
Jean-Philippe Brucker 0:cfd70fa91663 62 * is called "HID report descriptor".
Jean-Philippe Brucker 0:cfd70fa91663 63 * @param reportMapLength
Jean-Philippe Brucker 0:cfd70fa91663 64 * Size of the reportMap array
Jean-Philippe Brucker 0:cfd70fa91663 65 * @param outputReportLength
Jean-Philippe Brucker 0:cfd70fa91663 66 * Maximum length of a sent report (up to 64 bytes) (default: 64 bytes)
Jean-Philippe Brucker 0:cfd70fa91663 67 * @param inputReportLength
Jean-Philippe Brucker 0:cfd70fa91663 68 * Maximum length of a received report (up to 64 bytes) (default: 64 bytes)
Jean-Philippe Brucker 0:cfd70fa91663 69 * @param inputReportTickerDelay
Jean-Philippe Brucker 0:cfd70fa91663 70 * Delay between input report notifications, in ms. Acceptable values depend directly on
Jean-Philippe Brucker 0:cfd70fa91663 71 * GAP's connInterval parameter, so it shouldn't be less than 12ms
Jean-Philippe Brucker 0:cfd70fa91663 72 * Preferred GAP connection interval is set after this value, in order to send
Jean-Philippe Brucker 0:cfd70fa91663 73 * notifications as quick as possible: minimum connection interval will be set to
Jean-Philippe Brucker 0:cfd70fa91663 74 * (inputReportTickerDelay / 2)
Jean-Philippe Brucker 0:cfd70fa91663 75 */
Jean-Philippe Brucker 0:cfd70fa91663 76 HIDServiceBase(BLE &_ble,
Jean-Philippe Brucker 0:cfd70fa91663 77 report_map_t reportMap,
Jean-Philippe Brucker 0:cfd70fa91663 78 uint8_t reportMapLength,
Jean-Philippe Brucker 0:cfd70fa91663 79 report_t inputReport,
Jean-Philippe Brucker 0:cfd70fa91663 80 report_t outputReport,
Jean-Philippe Brucker 0:cfd70fa91663 81 report_t featureReport,
Jean-Philippe Brucker 0:cfd70fa91663 82 uint8_t inputReportLength = 0,
Jean-Philippe Brucker 0:cfd70fa91663 83 uint8_t outputReportLength = 0,
Jean-Philippe Brucker 0:cfd70fa91663 84 uint8_t featureReportLength = 0,
Jean-Philippe Brucker 0:cfd70fa91663 85 uint8_t inputReportTickerDelay = 50);
Jean-Philippe Brucker 0:cfd70fa91663 86
Jean-Philippe Brucker 0:cfd70fa91663 87 /**
Jean-Philippe Brucker 0:cfd70fa91663 88 * Send Report
Jean-Philippe Brucker 0:cfd70fa91663 89 *
Jean-Philippe Brucker 0:cfd70fa91663 90 * @param report Report to send. Must be of size @ref inputReportLength
Jean-Philippe Brucker 0:cfd70fa91663 91 * @return The write status
Jean-Philippe Brucker 0:cfd70fa91663 92 *
Jean-Philippe Brucker 0:cfd70fa91663 93 * @note Don't call send() directly for multiple reports! Use reportTicker for that, in order
Jean-Philippe Brucker 0:cfd70fa91663 94 * to avoid overloading the BLE stack, and let it handle events between each report.
Jean-Philippe Brucker 0:cfd70fa91663 95 */
Jean-Philippe Brucker 0:cfd70fa91663 96 virtual ble_error_t send(const report_t report);
Jean-Philippe Brucker 0:cfd70fa91663 97
Jean-Philippe Brucker 0:cfd70fa91663 98 /**
Jean-Philippe Brucker 0:cfd70fa91663 99 * Read Report
Jean-Philippe Brucker 0:cfd70fa91663 100 *
Jean-Philippe Brucker 0:cfd70fa91663 101 * @param report Report to fill. Must be of size @ref outputReportLength
Jean-Philippe Brucker 0:cfd70fa91663 102 * @return The read status
Jean-Philippe Brucker 0:cfd70fa91663 103 */
Jean-Philippe Brucker 0:cfd70fa91663 104 virtual ble_error_t read(report_t report);
Jean-Philippe Brucker 0:cfd70fa91663 105
Jean-Philippe Brucker 1:7a6c2e2c9371 106 virtual void onConnection(const Gap::ConnectionCallbackParams_t *params);
Jean-Philippe Brucker 1:7a6c2e2c9371 107 virtual void onDisconnection(const Gap::DisconnectionCallbackParams_t *params);
Jean-Philippe Brucker 0:cfd70fa91663 108
Jean-Philippe Brucker 0:cfd70fa91663 109 virtual bool isConnected(void)
Jean-Philippe Brucker 0:cfd70fa91663 110 {
Jean-Philippe Brucker 0:cfd70fa91663 111 return connected;
Jean-Philippe Brucker 0:cfd70fa91663 112 }
Jean-Philippe Brucker 0:cfd70fa91663 113
Jean-Philippe Brucker 0:cfd70fa91663 114 protected:
Jean-Philippe Brucker 0:cfd70fa91663 115 /**
Jean-Philippe Brucker 0:cfd70fa91663 116 * Called by BLE API when data has been successfully sent.
Jean-Philippe Brucker 0:cfd70fa91663 117 *
Jean-Philippe Brucker 0:cfd70fa91663 118 * @param count Number of reports sent
Jean-Philippe Brucker 0:cfd70fa91663 119 *
Jean-Philippe Brucker 0:cfd70fa91663 120 * @note Subclasses can override this to avoid starting the report ticker when there is nothing
Jean-Philippe Brucker 0:cfd70fa91663 121 * to send
Jean-Philippe Brucker 0:cfd70fa91663 122 */
Jean-Philippe Brucker 0:cfd70fa91663 123 virtual void onDataSent(unsigned count);
Jean-Philippe Brucker 0:cfd70fa91663 124
Jean-Philippe Brucker 0:cfd70fa91663 125 /**
Jean-Philippe Brucker 0:cfd70fa91663 126 * Start the ticker that sends input reports at regular interval
Jean-Philippe Brucker 0:cfd70fa91663 127 *
Jean-Philippe Brucker 0:cfd70fa91663 128 * @note reportTickerIsActive describes the state of the ticker and can be used by HIDS
Jean-Philippe Brucker 0:cfd70fa91663 129 * implementations.
Jean-Philippe Brucker 0:cfd70fa91663 130 */
Jean-Philippe Brucker 0:cfd70fa91663 131 virtual void startReportTicker(void);
Jean-Philippe Brucker 0:cfd70fa91663 132
Jean-Philippe Brucker 0:cfd70fa91663 133 /**
Jean-Philippe Brucker 0:cfd70fa91663 134 * Stop the input report ticker
Jean-Philippe Brucker 0:cfd70fa91663 135 */
Jean-Philippe Brucker 0:cfd70fa91663 136 virtual void stopReportTicker(void);
Jean-Philippe Brucker 0:cfd70fa91663 137
Jean-Philippe Brucker 0:cfd70fa91663 138 /**
Jean-Philippe Brucker 0:cfd70fa91663 139 * Called by input report ticker at regular interval (reportTickerDelay). This must be
Jean-Philippe Brucker 0:cfd70fa91663 140 * overriden by HIDS implementations to call the @ref send() with a report, if necessary.
Jean-Philippe Brucker 0:cfd70fa91663 141 */
Jean-Philippe Brucker 0:cfd70fa91663 142 virtual void sendCallback(void) = 0;
Jean-Philippe Brucker 0:cfd70fa91663 143
Jean-Philippe Brucker 0:cfd70fa91663 144 /**
Jean-Philippe Brucker 0:cfd70fa91663 145 * Create the Gatt descriptor for a report characteristic
Jean-Philippe Brucker 0:cfd70fa91663 146 */
Jean-Philippe Brucker 0:cfd70fa91663 147 GattAttribute** inputReportDescriptors();
Jean-Philippe Brucker 0:cfd70fa91663 148 GattAttribute** outputReportDescriptors();
Jean-Philippe Brucker 0:cfd70fa91663 149 GattAttribute** featureReportDescriptors();
Jean-Philippe Brucker 0:cfd70fa91663 150
Jean-Philippe Brucker 0:cfd70fa91663 151 /**
Jean-Philippe Brucker 0:cfd70fa91663 152 * Create the HID information structure
Jean-Philippe Brucker 0:cfd70fa91663 153 */
Jean-Philippe Brucker 0:cfd70fa91663 154 HID_information_t* HIDInformation();
Jean-Philippe Brucker 0:cfd70fa91663 155
Jean-Philippe Brucker 0:cfd70fa91663 156 protected:
Jean-Philippe Brucker 0:cfd70fa91663 157 BLE &ble;
Jean-Philippe Brucker 0:cfd70fa91663 158 bool connected;
Jean-Philippe Brucker 0:cfd70fa91663 159
Jean-Philippe Brucker 0:cfd70fa91663 160 int reportMapLength;
Jean-Philippe Brucker 0:cfd70fa91663 161
Jean-Philippe Brucker 0:cfd70fa91663 162 report_t inputReport;
Jean-Philippe Brucker 0:cfd70fa91663 163 report_t outputReport;
Jean-Philippe Brucker 0:cfd70fa91663 164 report_t featureReport;
Jean-Philippe Brucker 0:cfd70fa91663 165
Jean-Philippe Brucker 0:cfd70fa91663 166 uint8_t inputReportLength;
Jean-Philippe Brucker 0:cfd70fa91663 167 uint8_t outputReportLength;
Jean-Philippe Brucker 0:cfd70fa91663 168 uint8_t featureReportLength;
Jean-Philippe Brucker 0:cfd70fa91663 169
Jean-Philippe Brucker 0:cfd70fa91663 170 uint8_t controlPointCommand;
Jean-Philippe Brucker 0:cfd70fa91663 171 uint8_t protocolMode;
Jean-Philippe Brucker 0:cfd70fa91663 172
Jean-Philippe Brucker 0:cfd70fa91663 173 report_reference_t inputReportReferenceData;
Jean-Philippe Brucker 0:cfd70fa91663 174 report_reference_t outputReportReferenceData;
Jean-Philippe Brucker 0:cfd70fa91663 175 report_reference_t featureReportReferenceData;
Jean-Philippe Brucker 0:cfd70fa91663 176
Jean-Philippe Brucker 0:cfd70fa91663 177 GattAttribute inputReportReferenceDescriptor;
Jean-Philippe Brucker 0:cfd70fa91663 178 GattAttribute outputReportReferenceDescriptor;
Jean-Philippe Brucker 0:cfd70fa91663 179 GattAttribute featureReportReferenceDescriptor;
Jean-Philippe Brucker 0:cfd70fa91663 180
Jean-Philippe Brucker 0:cfd70fa91663 181 // Optional gatt characteristics:
Jean-Philippe Brucker 0:cfd70fa91663 182 GattCharacteristic protocolModeCharacteristic;
Jean-Philippe Brucker 0:cfd70fa91663 183
Jean-Philippe Brucker 0:cfd70fa91663 184 // Report characteristics (each sort of optional)
Jean-Philippe Brucker 0:cfd70fa91663 185 GattCharacteristic inputReportCharacteristic;
Jean-Philippe Brucker 0:cfd70fa91663 186 GattCharacteristic outputReportCharacteristic;
Jean-Philippe Brucker 0:cfd70fa91663 187 GattCharacteristic featureReportCharacteristic;
Jean-Philippe Brucker 0:cfd70fa91663 188
Jean-Philippe Brucker 0:cfd70fa91663 189 // Required gatt characteristics: Report Map, Information, Control Point
Jean-Philippe Brucker 0:cfd70fa91663 190 GattCharacteristic reportMapCharacteristic;
Jean-Philippe Brucker 0:cfd70fa91663 191 ReadOnlyGattCharacteristic<HID_information_t> HIDInformationCharacteristic;
Jean-Philippe Brucker 0:cfd70fa91663 192 GattCharacteristic HIDControlPointCharacteristic;
Jean-Philippe Brucker 0:cfd70fa91663 193
Jean-Philippe Brucker 0:cfd70fa91663 194 Ticker reportTicker;
Jean-Philippe Brucker 0:cfd70fa91663 195 uint32_t reportTickerDelay;
Jean-Philippe Brucker 0:cfd70fa91663 196 bool reportTickerIsActive;
Jean-Philippe Brucker 0:cfd70fa91663 197 };
Jean-Philippe Brucker 0:cfd70fa91663 198
Jean-Philippe Brucker 0:cfd70fa91663 199 #endif /* !HID_SERVICE_BASE_H_ */