![](/media/cache/group/logo.jpg.50x50_q85.jpg)
HID scanner demo
Dependencies: BLE_API WIFI_API_32kRAM nRF51822 mbed
BLE HID function in this demo is temporary working with Android phone ONLY. Will be fixed to support iOS device in next update.
HIDService.h@0:b0fc0661c081, 2015-07-02 (annotated)
- Committer:
- Marcomissyou
- Date:
- Thu Jul 02 01:35:08 2015 +0000
- Revision:
- 0:b0fc0661c081
HID Keyboard with Bluetooth 4.0
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Marcomissyou | 0:b0fc0661c081 | 1 | #ifndef __BLE_HID_SERVICE_H__ |
Marcomissyou | 0:b0fc0661c081 | 2 | #define __BLE_HID_SERVICE_H__ |
Marcomissyou | 0:b0fc0661c081 | 3 | |
Marcomissyou | 0:b0fc0661c081 | 4 | #include "BLE.h" |
Marcomissyou | 0:b0fc0661c081 | 5 | /** |
Marcomissyou | 0:b0fc0661c081 | 6 | * @class Human Interface Device Service |
Marcomissyou | 0:b0fc0661c081 | 7 | * @brief BLE Human Interface Device Service. This service displays the Glucose measurement value represented as a 16bit Float format.<br> |
Marcomissyou | 0:b0fc0661c081 | 8 | * @Author: Marco.Hsu |
Marcomissyou | 0:b0fc0661c081 | 9 | * @Email: marco.missyou@gmail.com |
Marcomissyou | 0:b0fc0661c081 | 10 | */ |
Marcomissyou | 0:b0fc0661c081 | 11 | |
Marcomissyou | 0:b0fc0661c081 | 12 | extern const uint8_t KeyboardReportMap[76]; |
Marcomissyou | 0:b0fc0661c081 | 13 | |
Marcomissyou | 0:b0fc0661c081 | 14 | class HIDService { |
Marcomissyou | 0:b0fc0661c081 | 15 | public: |
Marcomissyou | 0:b0fc0661c081 | 16 | HIDService(BLEDevice &_ble, const uint8_t* key = &KeyboardReportMap[0]): |
Marcomissyou | 0:b0fc0661c081 | 17 | ble(_ble), |
Marcomissyou | 0:b0fc0661c081 | 18 | protocol_modeValue(1), // Report Protocol Mode(1), Boot Protocol Mode(0) |
Marcomissyou | 0:b0fc0661c081 | 19 | KeyboardMap(key), |
Marcomissyou | 0:b0fc0661c081 | 20 | Protocol_Mode(GattCharacteristic::UUID_PROTOCOL_MODE_CHAR, &protocol_modeValue, 1, 1, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE|GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ), |
Marcomissyou | 0:b0fc0661c081 | 21 | ReportMap(GattCharacteristic::UUID_REPORT_MAP_CHAR, KeyboardMap.getPointer(), 76, sizeof(KeyboardMap), GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ |GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY), |
Marcomissyou | 0:b0fc0661c081 | 22 | Report(GattCharacteristic::UUID_REPORT_CHAR, reportValue.getPointer(), 8, 8, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY|GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ), |
Marcomissyou | 0:b0fc0661c081 | 23 | HID_Information(GattCharacteristic::UUID_HID_INFORMATION_CHAR, hidInformation.getPointer(), 4, 4, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ), |
Marcomissyou | 0:b0fc0661c081 | 24 | HID_Control_Point(GattCharacteristic::UUID_HID_CONTROL_POINT_CHAR, &hidcontrolPointer, 1, 1, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE) |
Marcomissyou | 0:b0fc0661c081 | 25 | { |
Marcomissyou | 0:b0fc0661c081 | 26 | static bool serviceAdded = false; /* We should only ever need to add the heart rate service once. */ |
Marcomissyou | 0:b0fc0661c081 | 27 | if (serviceAdded) { |
Marcomissyou | 0:b0fc0661c081 | 28 | return; |
Marcomissyou | 0:b0fc0661c081 | 29 | } |
Marcomissyou | 0:b0fc0661c081 | 30 | //Report.requireSecurity(SecurityManager::SECURITY_MODE_ENCRYPTION_OPEN_LINK); |
Marcomissyou | 0:b0fc0661c081 | 31 | GattCharacteristic *charTable[] = {&Protocol_Mode, &ReportMap, &Report, &HID_Information, &HID_Control_Point}; |
Marcomissyou | 0:b0fc0661c081 | 32 | GattService HIDGattService(GattService::UUID_HUMAN_INTERFACE_DEVICE_SERVICE, charTable, sizeof(charTable) / sizeof(GattCharacteristic *)); |
Marcomissyou | 0:b0fc0661c081 | 33 | ble.addService(HIDGattService); |
Marcomissyou | 0:b0fc0661c081 | 34 | serviceAdded = true; |
Marcomissyou | 0:b0fc0661c081 | 35 | ble.onDataWritten(this, &HIDService::onDataWritten); |
Marcomissyou | 0:b0fc0661c081 | 36 | } |
Marcomissyou | 0:b0fc0661c081 | 37 | public: |
Marcomissyou | 0:b0fc0661c081 | 38 | void updateReport(uint8_t modifydata, uint8_t data) { |
Marcomissyou | 0:b0fc0661c081 | 39 | reportValue.updateReportValue(modifydata, data); |
Marcomissyou | 0:b0fc0661c081 | 40 | ble.updateCharacteristicValue(Report.getValueAttribute().getHandle(), reportValue.getPointer(), 8); |
Marcomissyou | 0:b0fc0661c081 | 41 | } |
Marcomissyou | 0:b0fc0661c081 | 42 | |
Marcomissyou | 0:b0fc0661c081 | 43 | virtual void onDataWritten(const GattWriteCallbackParams *params) { |
Marcomissyou | 0:b0fc0661c081 | 44 | if (params->handle == HID_Control_Point.getValueAttribute().getHandle()) { |
Marcomissyou | 0:b0fc0661c081 | 45 | uint16_t bytesRead = params->len; |
Marcomissyou | 0:b0fc0661c081 | 46 | if (bytesRead == 1) { |
Marcomissyou | 0:b0fc0661c081 | 47 | memcpy(&hidcontrolPointer, params->data, bytesRead); |
Marcomissyou | 0:b0fc0661c081 | 48 | } |
Marcomissyou | 0:b0fc0661c081 | 49 | } |
Marcomissyou | 0:b0fc0661c081 | 50 | if (params->handle == Report.getValueAttribute().getHandle()) { |
Marcomissyou | 0:b0fc0661c081 | 51 | uint16_t bytesRead = params->len; |
Marcomissyou | 0:b0fc0661c081 | 52 | if (bytesRead <= 4) { |
Marcomissyou | 0:b0fc0661c081 | 53 | memcpy(&reportValue, params->data, bytesRead); |
Marcomissyou | 0:b0fc0661c081 | 54 | } |
Marcomissyou | 0:b0fc0661c081 | 55 | } |
Marcomissyou | 0:b0fc0661c081 | 56 | } |
Marcomissyou | 0:b0fc0661c081 | 57 | |
Marcomissyou | 0:b0fc0661c081 | 58 | private: |
Marcomissyou | 0:b0fc0661c081 | 59 | struct ReportMapStructure{ |
Marcomissyou | 0:b0fc0661c081 | 60 | uint8_t KeyboardMap[76]; |
Marcomissyou | 0:b0fc0661c081 | 61 | ReportMapStructure(const uint8_t* data): KeyboardMap() { |
Marcomissyou | 0:b0fc0661c081 | 62 | memcpy(&KeyboardMap[0], data, 76); |
Marcomissyou | 0:b0fc0661c081 | 63 | } |
Marcomissyou | 0:b0fc0661c081 | 64 | uint8_t *getPointer(void) { |
Marcomissyou | 0:b0fc0661c081 | 65 | return KeyboardMap; |
Marcomissyou | 0:b0fc0661c081 | 66 | } |
Marcomissyou | 0:b0fc0661c081 | 67 | }; |
Marcomissyou | 0:b0fc0661c081 | 68 | |
Marcomissyou | 0:b0fc0661c081 | 69 | private: |
Marcomissyou | 0:b0fc0661c081 | 70 | struct ReportStructure { |
Marcomissyou | 0:b0fc0661c081 | 71 | // Initial setting report value |
Marcomissyou | 0:b0fc0661c081 | 72 | ReportStructure(): reportValue() { |
Marcomissyou | 0:b0fc0661c081 | 73 | uint8_t data= 0x00; |
Marcomissyou | 0:b0fc0661c081 | 74 | updateReportValue(data, data); |
Marcomissyou | 0:b0fc0661c081 | 75 | } |
Marcomissyou | 0:b0fc0661c081 | 76 | |
Marcomissyou | 0:b0fc0661c081 | 77 | void updateReportValue(uint8_t modifyKey, uint8_t data){ |
Marcomissyou | 0:b0fc0661c081 | 78 | memset(&reportValue[0], 0 ,8); |
Marcomissyou | 0:b0fc0661c081 | 79 | memcpy(&reportValue[0], &modifyKey, 1); |
Marcomissyou | 0:b0fc0661c081 | 80 | memcpy(&reportValue[2], &data, 1); |
Marcomissyou | 0:b0fc0661c081 | 81 | } |
Marcomissyou | 0:b0fc0661c081 | 82 | |
Marcomissyou | 0:b0fc0661c081 | 83 | uint8_t *getPointer(void) { |
Marcomissyou | 0:b0fc0661c081 | 84 | return reportValue; |
Marcomissyou | 0:b0fc0661c081 | 85 | } |
Marcomissyou | 0:b0fc0661c081 | 86 | |
Marcomissyou | 0:b0fc0661c081 | 87 | uint8_t reportValue[8]; |
Marcomissyou | 0:b0fc0661c081 | 88 | }; |
Marcomissyou | 0:b0fc0661c081 | 89 | |
Marcomissyou | 0:b0fc0661c081 | 90 | private: |
Marcomissyou | 0:b0fc0661c081 | 91 | struct HIDInforStructure{ |
Marcomissyou | 0:b0fc0661c081 | 92 | uint16_t bcdHID; |
Marcomissyou | 0:b0fc0661c081 | 93 | uint8_t bCountryCode; |
Marcomissyou | 0:b0fc0661c081 | 94 | uint8_t Flags; |
Marcomissyou | 0:b0fc0661c081 | 95 | |
Marcomissyou | 0:b0fc0661c081 | 96 | HIDInforStructure():bcdHID(0),bCountryCode(0),Flags(0){ |
Marcomissyou | 0:b0fc0661c081 | 97 | memcpy(&hidInformation[0], &bcdHID, 2); |
Marcomissyou | 0:b0fc0661c081 | 98 | memcpy(&hidInformation[2], &bCountryCode, 1); |
Marcomissyou | 0:b0fc0661c081 | 99 | memcpy(&hidInformation[3], &Flags, 1); |
Marcomissyou | 0:b0fc0661c081 | 100 | } |
Marcomissyou | 0:b0fc0661c081 | 101 | uint8_t *getPointer(void) { |
Marcomissyou | 0:b0fc0661c081 | 102 | return hidInformation; |
Marcomissyou | 0:b0fc0661c081 | 103 | } |
Marcomissyou | 0:b0fc0661c081 | 104 | |
Marcomissyou | 0:b0fc0661c081 | 105 | uint8_t hidInformation[4]; |
Marcomissyou | 0:b0fc0661c081 | 106 | }; |
Marcomissyou | 0:b0fc0661c081 | 107 | |
Marcomissyou | 0:b0fc0661c081 | 108 | private: |
Marcomissyou | 0:b0fc0661c081 | 109 | BLEDevice &ble; |
Marcomissyou | 0:b0fc0661c081 | 110 | uint8_t protocol_modeValue; |
Marcomissyou | 0:b0fc0661c081 | 111 | ReportStructure reportValue; |
Marcomissyou | 0:b0fc0661c081 | 112 | uint8_t hidcontrolPointer; |
Marcomissyou | 0:b0fc0661c081 | 113 | ReportMapStructure KeyboardMap; |
Marcomissyou | 0:b0fc0661c081 | 114 | HIDInforStructure hidInformation; |
Marcomissyou | 0:b0fc0661c081 | 115 | GattCharacteristic Protocol_Mode; |
Marcomissyou | 0:b0fc0661c081 | 116 | GattCharacteristic ReportMap; |
Marcomissyou | 0:b0fc0661c081 | 117 | GattCharacteristic Report; |
Marcomissyou | 0:b0fc0661c081 | 118 | // ReadOnlyGattCharacteristic Boot_Keyboard_Input_Report; |
Marcomissyou | 0:b0fc0661c081 | 119 | // ReadWriteGattCharacteristic Boot_Keyboard_Output_Report; |
Marcomissyou | 0:b0fc0661c081 | 120 | // ReadOnlyGattCharacteristic Boot_Mouse_Input_Report; |
Marcomissyou | 0:b0fc0661c081 | 121 | GattCharacteristic HID_Information; |
Marcomissyou | 0:b0fc0661c081 | 122 | GattCharacteristic HID_Control_Point; |
Marcomissyou | 0:b0fc0661c081 | 123 | }; |
Marcomissyou | 0:b0fc0661c081 | 124 | #endif /* #ifndef __BLE_GLUCOSE_SERVICE_H__*/ |