Example for BLE HID scanner

Fork of BLE_HIDScanner_DELTA by Silvia Chen

Committer:
silviaChen
Date:
Wed Jul 26 09:55:34 2017 +0000
Revision:
5:8f0f8b8a85eb
Parent:
2:9f46fa6237dd
Change button action for RX characteristic demo

Who changed what in which revision?

UserRevisionLine numberNew contents of line
silviaChen 1:8bca989a70be 1 #ifndef __BLE_HID_SERVICE_H__
silviaChen 1:8bca989a70be 2 #define __BLE_HID_SERVICE_H__
silviaChen 1:8bca989a70be 3
silviaChen 1:8bca989a70be 4 #include "BLE.h"
silviaChen 2:9f46fa6237dd 5
silviaChen 2:9f46fa6237dd 6 #define BLE_UUID_DESCRIPTOR_REPORT_REFERENCE 0x2908
silviaChen 2:9f46fa6237dd 7
silviaChen 1:8bca989a70be 8 /**
silviaChen 1:8bca989a70be 9 * @class Human Interface Device Service
silviaChen 1:8bca989a70be 10 * @brief BLE Human Interface Device Service. This service displays the Glucose measurement value represented as a 16bit Float format.<br>
silviaChen 1:8bca989a70be 11 * @Author: Marco.Hsu
silviaChen 1:8bca989a70be 12 * @Email: marco.missyou@gmail.com
silviaChen 1:8bca989a70be 13 */
silviaChen 1:8bca989a70be 14
silviaChen 2:9f46fa6237dd 15 typedef struct {
silviaChen 2:9f46fa6237dd 16 uint8_t ID;
silviaChen 2:9f46fa6237dd 17 uint8_t type;
silviaChen 2:9f46fa6237dd 18 } report_reference_t;
silviaChen 2:9f46fa6237dd 19
silviaChen 2:9f46fa6237dd 20 enum ReportType {
silviaChen 2:9f46fa6237dd 21 INPUT_REPORT = 0x1,
silviaChen 2:9f46fa6237dd 22 OUTPUT_REPORT = 0x2,
silviaChen 2:9f46fa6237dd 23 FEATURE_REPORT = 0x3,
silviaChen 2:9f46fa6237dd 24 };
silviaChen 2:9f46fa6237dd 25
silviaChen 1:8bca989a70be 26 extern const uint8_t KeyboardReportMap[76];
silviaChen 1:8bca989a70be 27
silviaChen 1:8bca989a70be 28 class HIDService {
silviaChen 1:8bca989a70be 29 public:
silviaChen 2:9f46fa6237dd 30 HIDService(BLE &_ble, const uint8_t* key = &KeyboardReportMap[0]):
silviaChen 1:8bca989a70be 31 ble(_ble),
silviaChen 1:8bca989a70be 32 protocol_modeValue(1), // Report Protocol Mode(1), Boot Protocol Mode(0)
silviaChen 1:8bca989a70be 33 KeyboardMap(key),
silviaChen 1:8bca989a70be 34 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),
silviaChen 2:9f46fa6237dd 35 ReportMap(GattCharacteristic::UUID_REPORT_MAP_CHAR, KeyboardMap.getPointer(), 76, sizeof(KeyboardMap), GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ),
silviaChen 2:9f46fa6237dd 36 Report(GattCharacteristic::UUID_REPORT_CHAR, reportValue.getPointer(), 8, 8, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY|GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ|GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE, inputReportDescriptors(), 1),
silviaChen 1:8bca989a70be 37 HID_Information(GattCharacteristic::UUID_HID_INFORMATION_CHAR, hidInformation.getPointer(), 4, 4, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ),
silviaChen 2:9f46fa6237dd 38 HID_Control_Point(GattCharacteristic::UUID_HID_CONTROL_POINT_CHAR, &hidcontrolPointer, 1, 1, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE),
silviaChen 2:9f46fa6237dd 39 inputReportReferenceDescriptor(BLE_UUID_DESCRIPTOR_REPORT_REFERENCE,(uint8_t *)&inputReportReferenceData, 2, 2)
silviaChen 1:8bca989a70be 40 {
silviaChen 1:8bca989a70be 41 static bool serviceAdded = false; /* We should only ever need to add the heart rate service once. */
silviaChen 1:8bca989a70be 42 if (serviceAdded) {
silviaChen 1:8bca989a70be 43 return;
silviaChen 1:8bca989a70be 44 }
silviaChen 1:8bca989a70be 45
silviaChen 1:8bca989a70be 46 //SecurityManager::SecurityMode_t securityMode = SecurityManager::SECURITY_MODE_ENCRYPTION_NO_MITM;
silviaChen 1:8bca989a70be 47 Protocol_Mode.requireSecurity(SecurityManager::SECURITY_MODE_ENCRYPTION_NO_MITM);
silviaChen 1:8bca989a70be 48 ReportMap.requireSecurity(SecurityManager::SECURITY_MODE_ENCRYPTION_NO_MITM);
silviaChen 1:8bca989a70be 49 Report.requireSecurity(SecurityManager::SECURITY_MODE_ENCRYPTION_NO_MITM);
silviaChen 1:8bca989a70be 50 HID_Information.requireSecurity(SecurityManager::SECURITY_MODE_ENCRYPTION_NO_MITM);
silviaChen 1:8bca989a70be 51 HID_Control_Point.requireSecurity(SecurityManager::SECURITY_MODE_ENCRYPTION_NO_MITM);
silviaChen 1:8bca989a70be 52 GattCharacteristic *charTable[] = {&Protocol_Mode, &ReportMap, &Report, &HID_Information, &HID_Control_Point};
silviaChen 1:8bca989a70be 53 GattService HIDGattService(GattService::UUID_HUMAN_INTERFACE_DEVICE_SERVICE, charTable, sizeof(charTable) / sizeof(GattCharacteristic *));
silviaChen 1:8bca989a70be 54 ble.addService(HIDGattService);
silviaChen 1:8bca989a70be 55 serviceAdded = true;
silviaChen 1:8bca989a70be 56 ble.onDataWritten(this, &HIDService::onDataWritten);
silviaChen 1:8bca989a70be 57 }
silviaChen 1:8bca989a70be 58 public:
silviaChen 1:8bca989a70be 59 void updateReport(uint8_t modifydata, uint8_t data) {
silviaChen 1:8bca989a70be 60 reportValue.updateReportValue(modifydata, data);
silviaChen 1:8bca989a70be 61
silviaChen 1:8bca989a70be 62 //ble.updateCharacteristicValue(Report.getValueAttribute().getHandle(), reportValue.getPointer(), 8);
silviaChen 1:8bca989a70be 63 ble.gattServer().write(Report.getValueAttribute().getHandle(), reportValue.getPointer(), 8);
silviaChen 1:8bca989a70be 64 }
silviaChen 1:8bca989a70be 65
silviaChen 1:8bca989a70be 66 virtual void onDataWritten(const GattWriteCallbackParams *params) {
silviaChen 1:8bca989a70be 67 if (params->handle == HID_Control_Point.getValueAttribute().getHandle()) {
silviaChen 1:8bca989a70be 68 uint16_t bytesRead = params->len;
silviaChen 1:8bca989a70be 69 if (bytesRead == 1) {
silviaChen 1:8bca989a70be 70 memcpy(&hidcontrolPointer, params->data, bytesRead);
silviaChen 1:8bca989a70be 71 }
silviaChen 1:8bca989a70be 72 }
silviaChen 1:8bca989a70be 73 if (params->handle == Report.getValueAttribute().getHandle()) {
silviaChen 1:8bca989a70be 74 uint16_t bytesRead = params->len;
silviaChen 1:8bca989a70be 75 if (bytesRead <= 4) {
silviaChen 1:8bca989a70be 76 memcpy(&reportValue, params->data, bytesRead);
silviaChen 1:8bca989a70be 77 }
silviaChen 1:8bca989a70be 78 }
silviaChen 1:8bca989a70be 79 }
silviaChen 1:8bca989a70be 80
silviaChen 1:8bca989a70be 81 private:
silviaChen 1:8bca989a70be 82 struct ReportMapStructure{
silviaChen 1:8bca989a70be 83 uint8_t KeyboardMap[76];
silviaChen 1:8bca989a70be 84 ReportMapStructure(const uint8_t* data): KeyboardMap() {
silviaChen 1:8bca989a70be 85 memcpy(&KeyboardMap[0], data, 76);
silviaChen 1:8bca989a70be 86 }
silviaChen 1:8bca989a70be 87 uint8_t *getPointer(void) {
silviaChen 1:8bca989a70be 88 return KeyboardMap;
silviaChen 1:8bca989a70be 89 }
silviaChen 1:8bca989a70be 90 };
silviaChen 2:9f46fa6237dd 91
silviaChen 2:9f46fa6237dd 92 GattAttribute** HIDService::inputReportDescriptors() {
silviaChen 2:9f46fa6237dd 93 inputReportReferenceData.ID = 0;
silviaChen 2:9f46fa6237dd 94 inputReportReferenceData.type = INPUT_REPORT;
silviaChen 2:9f46fa6237dd 95
silviaChen 2:9f46fa6237dd 96 static GattAttribute *descs[] = {
silviaChen 2:9f46fa6237dd 97 &inputReportReferenceDescriptor,
silviaChen 2:9f46fa6237dd 98 };
silviaChen 2:9f46fa6237dd 99 return descs;
silviaChen 2:9f46fa6237dd 100 }
silviaChen 1:8bca989a70be 101
silviaChen 1:8bca989a70be 102 private:
silviaChen 1:8bca989a70be 103 struct ReportStructure {
silviaChen 1:8bca989a70be 104 // Initial setting report value
silviaChen 1:8bca989a70be 105 ReportStructure(): reportValue() {
silviaChen 1:8bca989a70be 106 uint8_t data= 0x00;
silviaChen 1:8bca989a70be 107 updateReportValue(data, data);
silviaChen 1:8bca989a70be 108 }
silviaChen 1:8bca989a70be 109
silviaChen 1:8bca989a70be 110 void updateReportValue(uint8_t modifyKey, uint8_t data){
silviaChen 1:8bca989a70be 111 memset(&reportValue[0], 0 ,8);
silviaChen 1:8bca989a70be 112 memcpy(&reportValue[0], &modifyKey, 1);
silviaChen 1:8bca989a70be 113 memcpy(&reportValue[2], &data, 1);
silviaChen 1:8bca989a70be 114 }
silviaChen 1:8bca989a70be 115
silviaChen 1:8bca989a70be 116 uint8_t *getPointer(void) {
silviaChen 1:8bca989a70be 117 return reportValue;
silviaChen 1:8bca989a70be 118 }
silviaChen 1:8bca989a70be 119
silviaChen 1:8bca989a70be 120 uint8_t reportValue[8];
silviaChen 1:8bca989a70be 121 };
silviaChen 1:8bca989a70be 122
silviaChen 1:8bca989a70be 123 private:
silviaChen 1:8bca989a70be 124 struct HIDInforStructure{
silviaChen 1:8bca989a70be 125 uint16_t bcdHID;
silviaChen 1:8bca989a70be 126 uint8_t bCountryCode;
silviaChen 1:8bca989a70be 127 uint8_t Flags;
silviaChen 1:8bca989a70be 128
silviaChen 1:8bca989a70be 129 HIDInforStructure():bcdHID(0),bCountryCode(0),Flags(0){
silviaChen 1:8bca989a70be 130 memcpy(&hidInformation[0], &bcdHID, 2);
silviaChen 1:8bca989a70be 131 memcpy(&hidInformation[2], &bCountryCode, 1);
silviaChen 1:8bca989a70be 132 memcpy(&hidInformation[3], &Flags, 1);
silviaChen 1:8bca989a70be 133 }
silviaChen 1:8bca989a70be 134 uint8_t *getPointer(void) {
silviaChen 1:8bca989a70be 135 return hidInformation;
silviaChen 1:8bca989a70be 136 }
silviaChen 1:8bca989a70be 137
silviaChen 1:8bca989a70be 138 uint8_t hidInformation[4];
silviaChen 1:8bca989a70be 139 };
silviaChen 1:8bca989a70be 140
silviaChen 1:8bca989a70be 141 private:
silviaChen 2:9f46fa6237dd 142 BLE &ble;
silviaChen 1:8bca989a70be 143 uint8_t protocol_modeValue;
silviaChen 1:8bca989a70be 144 ReportStructure reportValue;
silviaChen 1:8bca989a70be 145 uint8_t hidcontrolPointer;
silviaChen 1:8bca989a70be 146 ReportMapStructure KeyboardMap;
silviaChen 1:8bca989a70be 147 HIDInforStructure hidInformation;
silviaChen 1:8bca989a70be 148 GattCharacteristic Protocol_Mode;
silviaChen 1:8bca989a70be 149 GattCharacteristic ReportMap;
silviaChen 1:8bca989a70be 150 GattCharacteristic Report;
silviaChen 1:8bca989a70be 151 // ReadOnlyGattCharacteristic Boot_Keyboard_Input_Report;
silviaChen 1:8bca989a70be 152 // ReadWriteGattCharacteristic Boot_Keyboard_Output_Report;
silviaChen 1:8bca989a70be 153 // ReadOnlyGattCharacteristic Boot_Mouse_Input_Report;
silviaChen 1:8bca989a70be 154 GattCharacteristic HID_Information;
silviaChen 1:8bca989a70be 155 GattCharacteristic HID_Control_Point;
silviaChen 2:9f46fa6237dd 156 GattAttribute inputReportReferenceDescriptor;
silviaChen 2:9f46fa6237dd 157 report_reference_t inputReportReferenceData;
silviaChen 1:8bca989a70be 158 };
silviaChen 1:8bca989a70be 159 #endif /* #ifndef __BLE_GLUCOSE_SERVICE_H__*/