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: Seeed_Tiny_BLE_FTHR_Peripheral
Fork of BLE_HID by
HIDServiceBase.h@1:7a6c2e2c9371, 2015-10-07 (annotated)
- Committer:
- Jean-Philippe Brucker
- Date:
- Wed Oct 07 11:29:52 2015 +0100
- Revision:
- 1:7a6c2e2c9371
- Parent:
- 0:cfd70fa91663
- Child:
- 3:4f8429a1905b
Publish version 0.1 of the BLE HID lib
This version number is completely arbitrary, and probably won't stick: once the
service is stable, we'll merge it with BLE API.
It is simply used to keep examples in sync with the lib and the github
repository during development.
Who changed what in which revision?
User | Revision | Line number | New 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 |
0:cfd70fa91663 | 23 | #include "HID_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_ */ |