ble nano hid over gatt

Dependencies:   BLE_API mbed-dev nRF51822

Committer:
cho45
Date:
Tue Aug 23 15:25:30 2016 +0000
Revision:
28:1f843a3daab0
Parent:
27:7370b8994603
Child:
29:ec548c473d50
MyTimerEvent ????? stuck ??????????????RTC0 ?????????RTC1 ?????????????????????????????mbed ???????

Who changed what in which revision?

UserRevisionLine numberNew contents of line
cho45 6:f1c3ea8bc850 1 #include "mbed.h"
cho45 6:f1c3ea8bc850 2 #include "BLE.h"
cho45 6:f1c3ea8bc850 3 #include "KeyboardService.h"
cho45 6:f1c3ea8bc850 4 #include "BatteryService.h"
cho45 6:f1c3ea8bc850 5 #include "DeviceInformationService.h"
cho45 15:70bf079d3ee1 6 #include "DFUService.h"
cho45 6:f1c3ea8bc850 7 #include "HIDController_BLE.h"
cho45 6:f1c3ea8bc850 8
cho45 6:f1c3ea8bc850 9 static const char MODEL_NAME[] = "keyboard";
cho45 6:f1c3ea8bc850 10 static const char SERIAL_NUMBER[] = "X00000";
cho45 6:f1c3ea8bc850 11 static const char HARDWARE_REVISION[] = "0.1";
cho45 6:f1c3ea8bc850 12 static const char FIRMWARE_REVISION[] = "0.1";
cho45 6:f1c3ea8bc850 13 static const char SOFTWARE_REVISION[] = "0.0";
cho45 6:f1c3ea8bc850 14
cho45 6:f1c3ea8bc850 15 static const uint8_t DEVICE_NAME[] = "my keyboard";
cho45 6:f1c3ea8bc850 16 static const uint8_t SHORT_DEVICE_NAME[] = "kbd1";
cho45 6:f1c3ea8bc850 17
cho45 6:f1c3ea8bc850 18 static const bool ENABLE_BONDING = true;
cho45 6:f1c3ea8bc850 19 static const bool REQUIRE_MITM = true;
cho45 6:f1c3ea8bc850 20 static const uint8_t PASSKEY[6] = {'1','2','3','4','5','6'}; // must be 6-digits number
cho45 6:f1c3ea8bc850 21
cho45 6:f1c3ea8bc850 22 static const uint16_t uuid16_list[] = {
cho45 6:f1c3ea8bc850 23 GattService::UUID_HUMAN_INTERFACE_DEVICE_SERVICE,
cho45 6:f1c3ea8bc850 24 GattService::UUID_DEVICE_INFORMATION_SERVICE,
cho45 6:f1c3ea8bc850 25 GattService::UUID_BATTERY_SERVICE
cho45 6:f1c3ea8bc850 26 };
cho45 6:f1c3ea8bc850 27
cho45 6:f1c3ea8bc850 28 static KeyboardService* keyboardService;
cho45 6:f1c3ea8bc850 29 static BatteryService* batteryService;
cho45 6:f1c3ea8bc850 30 static DeviceInformationService* deviceInformationService;
cho45 15:70bf079d3ee1 31 static DFUService* dfuService;
cho45 6:f1c3ea8bc850 32
cho45 13:b0ffdf2012b9 33 static BLEProtocol::Address_t peerAddress;
cho45 27:7370b8994603 34
cho45 27:7370b8994603 35
cho45 27:7370b8994603 36 static volatile Status_t controllerStatus;
cho45 13:b0ffdf2012b9 37
cho45 6:f1c3ea8bc850 38 static void updateBatteryLevel() {
cho45 6:f1c3ea8bc850 39 if (!batteryService) return;
cho45 6:f1c3ea8bc850 40 static const float BATTERY_MAX = 2.4;
cho45 6:f1c3ea8bc850 41 static const float REFERNECE = 1.2;
cho45 6:f1c3ea8bc850 42 static const float PRESCALE = 3;
cho45 6:f1c3ea8bc850 43
cho45 6:f1c3ea8bc850 44 NRF_ADC->ENABLE = ADC_ENABLE_ENABLE_Enabled;
cho45 6:f1c3ea8bc850 45
cho45 6:f1c3ea8bc850 46 // Use internal 1.2V reference for batteryInput
cho45 6:f1c3ea8bc850 47 // 1/3 pre-scaled input and 1.2V internal band gap reference
cho45 6:f1c3ea8bc850 48 // ref. mbed-src/targets/hal/TARGET_NORDIC/TARGET_MCU_NRF51822/analogin_api.c
cho45 6:f1c3ea8bc850 49 NRF_ADC->CONFIG =
cho45 6:f1c3ea8bc850 50 (ADC_CONFIG_RES_10bit << ADC_CONFIG_RES_Pos) |
cho45 6:f1c3ea8bc850 51 // Use VDD 1/3 for input
cho45 6:f1c3ea8bc850 52 (ADC_CONFIG_INPSEL_SupplyOneThirdPrescaling << ADC_CONFIG_INPSEL_Pos) |
cho45 6:f1c3ea8bc850 53 // Use internal band gap for reference
cho45 6:f1c3ea8bc850 54 (ADC_CONFIG_REFSEL_VBG << ADC_CONFIG_REFSEL_Pos) |
cho45 6:f1c3ea8bc850 55 (ADC_CONFIG_EXTREFSEL_None << ADC_CONFIG_EXTREFSEL_Pos);
cho45 6:f1c3ea8bc850 56
cho45 6:f1c3ea8bc850 57 // Start ADC
cho45 6:f1c3ea8bc850 58 NRF_ADC->TASKS_START = 1;
cho45 6:f1c3ea8bc850 59 while (((NRF_ADC->BUSY & ADC_BUSY_BUSY_Msk) >> ADC_BUSY_BUSY_Pos) == ADC_BUSY_BUSY_Busy) {
cho45 6:f1c3ea8bc850 60 // busy loop
cho45 6:f1c3ea8bc850 61 }
cho45 6:f1c3ea8bc850 62
cho45 6:f1c3ea8bc850 63 // Read ADC result
cho45 6:f1c3ea8bc850 64 uint16_t raw10bit = static_cast<uint16_t>(NRF_ADC->RESULT);
cho45 21:d801c32231b0 65
cho45 21:d801c32231b0 66 NRF_ADC->ENABLE = ADC_ENABLE_ENABLE_Disabled;
cho45 21:d801c32231b0 67
cho45 6:f1c3ea8bc850 68 float ratio = raw10bit / static_cast<float>(1<<10);
cho45 6:f1c3ea8bc850 69
cho45 6:f1c3ea8bc850 70 float batteryVoltage = ratio * (REFERNECE * PRESCALE);
cho45 6:f1c3ea8bc850 71 float percentage = (batteryVoltage / BATTERY_MAX) * 100;
cho45 6:f1c3ea8bc850 72 if (percentage > 100) {
cho45 6:f1c3ea8bc850 73 percentage = 100;
cho45 6:f1c3ea8bc850 74 }
cho45 6:f1c3ea8bc850 75 printf("updateBatteryLevel %f V : %d/100\r\n", batteryVoltage, static_cast<uint8_t>(percentage));
cho45 6:f1c3ea8bc850 76 batteryService->updateBatteryLevel(static_cast<uint8_t>(percentage));
cho45 6:f1c3ea8bc850 77 }
cho45 6:f1c3ea8bc850 78
cho45 6:f1c3ea8bc850 79
cho45 6:f1c3ea8bc850 80 static void onConnect(const Gap::ConnectionCallbackParams_t *params) {
cho45 25:094df0d9e95b 81
cho45 17:3233ee19f716 82 printf("onConnect: ");
cho45 22:a78f0a91280a 83 for (unsigned i = 0; i < Gap::ADDR_LEN; i++) {
cho45 17:3233ee19f716 84 printf("%02x", params->peerAddr[i]);
cho45 17:3233ee19f716 85 }
cho45 17:3233ee19f716 86 printf("\r\n");
cho45 25:094df0d9e95b 87
cho45 13:b0ffdf2012b9 88 peerAddress.type = params->peerAddrType;
cho45 13:b0ffdf2012b9 89 memcpy(peerAddress.address, params->peerAddr, Gap::ADDR_LEN);
cho45 27:7370b8994603 90 controllerStatus = CONNECTING;
cho45 6:f1c3ea8bc850 91 }
cho45 6:f1c3ea8bc850 92
cho45 6:f1c3ea8bc850 93 static void onDisconnect(const Gap::DisconnectionCallbackParams_t *params) {
cho45 6:f1c3ea8bc850 94 printf("onDisconnect\r\n");
cho45 27:7370b8994603 95 controllerStatus = DISCONNECTED;
cho45 6:f1c3ea8bc850 96 BLE::Instance(BLE::DEFAULT_INSTANCE).gap().startAdvertising();
cho45 6:f1c3ea8bc850 97 }
cho45 6:f1c3ea8bc850 98
cho45 6:f1c3ea8bc850 99 static void onTimeout(const Gap::TimeoutSource_t source) {
cho45 6:f1c3ea8bc850 100 printf("onTimeout\r\n");
cho45 27:7370b8994603 101 controllerStatus = DISCONNECTED;
cho45 6:f1c3ea8bc850 102 BLE::Instance(BLE::DEFAULT_INSTANCE).gap().startAdvertising();
cho45 6:f1c3ea8bc850 103 }
cho45 6:f1c3ea8bc850 104
cho45 6:f1c3ea8bc850 105 static void passkeyDisplayCallback(Gap::Handle_t handle, const SecurityManager::Passkey_t passkey) {
cho45 6:f1c3ea8bc850 106 printf("Input passKey: ");
cho45 6:f1c3ea8bc850 107 for (unsigned i = 0; i < Gap::ADDR_LEN; i++) {
cho45 6:f1c3ea8bc850 108 printf("%c", passkey[i]);
cho45 6:f1c3ea8bc850 109 }
cho45 6:f1c3ea8bc850 110 printf("\r\n");
cho45 6:f1c3ea8bc850 111 }
cho45 6:f1c3ea8bc850 112
cho45 6:f1c3ea8bc850 113 static void securitySetupCompletedCallback(Gap::Handle_t handle, SecurityManager::SecurityCompletionStatus_t status) {
cho45 6:f1c3ea8bc850 114 if (status == SecurityManager::SEC_STATUS_SUCCESS) {
cho45 6:f1c3ea8bc850 115 printf("Security success %d\r\n", status);
cho45 13:b0ffdf2012b9 116
cho45 13:b0ffdf2012b9 117 printf("Set whitelist\r\n");
cho45 13:b0ffdf2012b9 118 Gap::Whitelist_t whitelist;
cho45 13:b0ffdf2012b9 119 whitelist.size = 1;
cho45 13:b0ffdf2012b9 120 whitelist.capacity = 1;
cho45 13:b0ffdf2012b9 121 whitelist.addresses = &peerAddress;
cho45 13:b0ffdf2012b9 122
cho45 13:b0ffdf2012b9 123 BLE::Instance(BLE::DEFAULT_INSTANCE).gap().setWhitelist(whitelist);
cho45 13:b0ffdf2012b9 124 printf("Set Advertising Policy Mode\r\n");
cho45 13:b0ffdf2012b9 125 // BLE::Instance(BLE::DEFAULT_INSTANCE).gap().setAdvertisingPolicyMode(Gap::ADV_POLICY_FILTER_SCAN_REQS);
cho45 13:b0ffdf2012b9 126 // BLE::Instance(BLE::DEFAULT_INSTANCE).gap().setAdvertisingPolicyMode(Gap::ADV_POLICY_FILTER_CONN_REQS);
cho45 13:b0ffdf2012b9 127 BLE::Instance(BLE::DEFAULT_INSTANCE).gap().setAdvertisingPolicyMode(Gap::ADV_POLICY_FILTER_ALL_REQS);
cho45 27:7370b8994603 128 controllerStatus = CONNECTED;
cho45 6:f1c3ea8bc850 129 } else {
cho45 6:f1c3ea8bc850 130 printf("Security failed %d\r\n", status);
cho45 6:f1c3ea8bc850 131 }
cho45 6:f1c3ea8bc850 132 }
cho45 6:f1c3ea8bc850 133
cho45 6:f1c3ea8bc850 134 static void securitySetupInitiatedCallback(Gap::Handle_t, bool allowBonding, bool requireMITM, SecurityManager::SecurityIOCapabilities_t iocaps) {
cho45 6:f1c3ea8bc850 135 printf("Security setup initiated\r\n");
cho45 6:f1c3ea8bc850 136 }
cho45 6:f1c3ea8bc850 137
cho45 6:f1c3ea8bc850 138 static void bleInitComplete(BLE::InitializationCompleteCallbackContext *params) {
cho45 6:f1c3ea8bc850 139 // https://developer.mbed.org/compiler/#nav:/keyboard/BLE_API/ble/blecommon.h;
cho45 6:f1c3ea8bc850 140 ble_error_t error;
cho45 6:f1c3ea8bc850 141 BLE &ble = params->ble;
cho45 23:b31957ce64e9 142
cho45 27:7370b8994603 143 controllerStatus = DISCONNECTED;
cho45 16:345eebc4f259 144
cho45 16:345eebc4f259 145 /**< Minimum Connection Interval in 1.25 ms units, see BLE_GAP_CP_LIMITS.*/
cho45 18:5d0232c9e70e 146 uint16_t minConnectionInterval = Gap::MSEC_TO_GAP_DURATION_UNITS(24);
cho45 16:345eebc4f259 147 /**< Maximum Connection Interval in 1.25 ms units, see BLE_GAP_CP_LIMITS.*/
cho45 18:5d0232c9e70e 148 uint16_t maxConnectionInterval = Gap::MSEC_TO_GAP_DURATION_UNITS(44);
cho45 16:345eebc4f259 149 /**< Slave Latency in number of connection events, see BLE_GAP_CP_LIMITS.*/
cho45 24:a4dbde033def 150 uint16_t slaveLatency = 4;
cho45 16:345eebc4f259 151 /**< Connection Supervision Timeout in 10 ms units, see BLE_GAP_CP_LIMITS.*/
cho45 16:345eebc4f259 152 uint16_t connectionSupervisionTimeout = 32 * 100;
cho45 16:345eebc4f259 153 Gap::ConnectionParams_t connectionParams = {
cho45 16:345eebc4f259 154 minConnectionInterval,
cho45 16:345eebc4f259 155 maxConnectionInterval,
cho45 16:345eebc4f259 156 slaveLatency,
cho45 16:345eebc4f259 157 connectionSupervisionTimeout
cho45 16:345eebc4f259 158 };
cho45 16:345eebc4f259 159
cho45 6:f1c3ea8bc850 160 error = params->error;
cho45 6:f1c3ea8bc850 161 if (error != BLE_ERROR_NONE) {
cho45 6:f1c3ea8bc850 162 printf("error on ble.init() \r\n");
cho45 6:f1c3ea8bc850 163 goto return_error;
cho45 6:f1c3ea8bc850 164 }
cho45 6:f1c3ea8bc850 165
cho45 6:f1c3ea8bc850 166 ble.gap().onDisconnection(onDisconnect);
cho45 6:f1c3ea8bc850 167 ble.gap().onConnection(onConnect);
cho45 6:f1c3ea8bc850 168 ble.gap().onTimeout(onTimeout);
cho45 6:f1c3ea8bc850 169
cho45 17:3233ee19f716 170 // printf("setup ble security manager\r\n");
cho45 6:f1c3ea8bc850 171 ble.securityManager().onSecuritySetupInitiated(securitySetupInitiatedCallback);
cho45 6:f1c3ea8bc850 172 ble.securityManager().onPasskeyDisplay(passkeyDisplayCallback);
cho45 6:f1c3ea8bc850 173 ble.securityManager().onSecuritySetupCompleted(securitySetupCompletedCallback);
cho45 6:f1c3ea8bc850 174 // bonding with hard-coded passkey.
cho45 6:f1c3ea8bc850 175 error = ble.securityManager().init(ENABLE_BONDING, REQUIRE_MITM, SecurityManager::IO_CAPS_DISPLAY_ONLY, PASSKEY);
cho45 6:f1c3ea8bc850 176 if (error != BLE_ERROR_NONE) {
cho45 6:f1c3ea8bc850 177 printf("error on ble.securityManager().init()");
cho45 6:f1c3ea8bc850 178 goto return_error;
cho45 6:f1c3ea8bc850 179 }
cho45 16:345eebc4f259 180
cho45 6:f1c3ea8bc850 181
cho45 17:3233ee19f716 182 // printf("new KeyboardService\r\n");
cho45 6:f1c3ea8bc850 183 keyboardService = new KeyboardService(ble);
cho45 17:3233ee19f716 184 // printf("new DeviceInformationService\r\n");
cho45 6:f1c3ea8bc850 185 deviceInformationService = new DeviceInformationService(ble, "lowreal.net", MODEL_NAME, SERIAL_NUMBER, HARDWARE_REVISION, FIRMWARE_REVISION, SOFTWARE_REVISION);
cho45 17:3233ee19f716 186 // printf("new BatteryService\r\n");
cho45 6:f1c3ea8bc850 187 batteryService = new BatteryService(ble, 100);
cho45 16:345eebc4f259 188 /** TODO STUCK with BLE NANO
cho45 16:345eebc4f259 189 printf("new DFUService\r\n");
cho45 16:345eebc4f259 190 dfuService = new DFUService(ble);
cho45 16:345eebc4f259 191 */
cho45 16:345eebc4f259 192
cho45 6:f1c3ea8bc850 193 updateBatteryLevel();
cho45 16:345eebc4f259 194
cho45 17:3233ee19f716 195 //printf("setup connection params\r\n");
cho45 16:345eebc4f259 196
cho45 16:345eebc4f259 197 ble.gap().setPreferredConnectionParams(&connectionParams);
cho45 6:f1c3ea8bc850 198
cho45 17:3233ee19f716 199 // printf("general setup\r\n");
cho45 6:f1c3ea8bc850 200 error = ble.gap().accumulateAdvertisingPayload(
cho45 6:f1c3ea8bc850 201 GapAdvertisingData::BREDR_NOT_SUPPORTED |
cho45 6:f1c3ea8bc850 202 GapAdvertisingData::LE_GENERAL_DISCOVERABLE
cho45 6:f1c3ea8bc850 203 );
cho45 9:d1daefbf1fbd 204 // shoud be LE_LIMITED_DISCOVERABLE
cho45 9:d1daefbf1fbd 205 // error = ble.gap().accumulateAdvertisingPayload(
cho45 9:d1daefbf1fbd 206 // GapAdvertisingData::BREDR_NOT_SUPPORTED |
cho45 9:d1daefbf1fbd 207 // GapAdvertisingData::LE_LIMITED_DISCOVERABLE
cho45 9:d1daefbf1fbd 208 // );
cho45 6:f1c3ea8bc850 209 if (error != BLE_ERROR_NONE) goto return_error;
cho45 6:f1c3ea8bc850 210
cho45 17:3233ee19f716 211 // printf("set COMPLETE_LIST_16BIT_SERVICE_IDS\r\n");
cho45 6:f1c3ea8bc850 212 error = ble.gap().accumulateAdvertisingPayload(
cho45 6:f1c3ea8bc850 213 GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS,
cho45 6:f1c3ea8bc850 214 (uint8_t*)uuid16_list, sizeof(uuid16_list)
cho45 6:f1c3ea8bc850 215 );
cho45 6:f1c3ea8bc850 216 if (error != BLE_ERROR_NONE) goto return_error;
cho45 6:f1c3ea8bc850 217
cho45 17:3233ee19f716 218 // printf("set advertising\r\n");
cho45 6:f1c3ea8bc850 219 // see 5.1.2: HID over GATT Specification (pg. 25)
cho45 6:f1c3ea8bc850 220 ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
cho45 6:f1c3ea8bc850 221
cho45 17:3233ee19f716 222 // printf("set advertising interval\r\n");
cho45 28:1f843a3daab0 223 ble.gap().setAdvertisingInterval(20);
cho45 17:3233ee19f716 224 // printf("set advertising timeout\r\n");
cho45 9:d1daefbf1fbd 225 ble.gap().setAdvertisingTimeout(180);
cho45 28:1f843a3daab0 226
cho45 28:1f843a3daab0 227 /*
cho45 28:1f843a3daab0 228 ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED);
cho45 28:1f843a3daab0 229 ble.gap().setAdvertisingTimeout(1.28);
cho45 28:1f843a3daab0 230 */
cho45 6:f1c3ea8bc850 231
cho45 17:3233ee19f716 232 // printf("set keyboard\r\n");
cho45 6:f1c3ea8bc850 233 error = ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::KEYBOARD);
cho45 6:f1c3ea8bc850 234 if (error != BLE_ERROR_NONE) goto return_error;
cho45 6:f1c3ea8bc850 235
cho45 17:3233ee19f716 236 // printf("set complete local name\r\n");
cho45 6:f1c3ea8bc850 237 error = ble.gap().accumulateAdvertisingPayload(
cho45 6:f1c3ea8bc850 238 GapAdvertisingData::COMPLETE_LOCAL_NAME,
cho45 6:f1c3ea8bc850 239 DEVICE_NAME, sizeof(DEVICE_NAME)
cho45 6:f1c3ea8bc850 240 );
cho45 6:f1c3ea8bc850 241 if (error != BLE_ERROR_NONE) goto return_error;
cho45 6:f1c3ea8bc850 242
cho45 17:3233ee19f716 243 // printf("set device name\r\n");
cho45 6:f1c3ea8bc850 244 error = ble.gap().setDeviceName(DEVICE_NAME);
cho45 6:f1c3ea8bc850 245 if (error != BLE_ERROR_NONE) goto return_error;
cho45 22:a78f0a91280a 246 /* (Valid values are -40, -20, -16, -12, -8, -4, 0, 4) */
cho45 19:cd7f2fe05ae4 247 ble.gap().setTxPower(0);
cho45 6:f1c3ea8bc850 248
cho45 23:b31957ce64e9 249 // ble.gap().setAdvertisingPolicyMode(Gap::ADV_POLICY_IGNORE_WHITELIST);
cho45 23:b31957ce64e9 250
cho45 6:f1c3ea8bc850 251
cho45 6:f1c3ea8bc850 252 printf("advertising\r\n");
cho45 6:f1c3ea8bc850 253 error = ble.gap().startAdvertising();
cho45 6:f1c3ea8bc850 254 if (error != BLE_ERROR_NONE) goto return_error;
cho45 6:f1c3ea8bc850 255 return;
cho45 6:f1c3ea8bc850 256
cho45 6:f1c3ea8bc850 257 return_error:
cho45 6:f1c3ea8bc850 258 printf("error with %d\r\n", error);
cho45 6:f1c3ea8bc850 259 return;
cho45 6:f1c3ea8bc850 260 }
cho45 6:f1c3ea8bc850 261
cho45 20:d8840ac38434 262 bool HIDController::connected() {
cho45 27:7370b8994603 263 return controllerStatus == CONNECTED;
cho45 27:7370b8994603 264 }
cho45 27:7370b8994603 265
cho45 27:7370b8994603 266 Status_t HIDController::status() {
cho45 27:7370b8994603 267 return controllerStatus;
cho45 20:d8840ac38434 268 }
cho45 20:d8840ac38434 269
cho45 6:f1c3ea8bc850 270 void HIDController::init() {
cho45 6:f1c3ea8bc850 271 // https://github.com/jpbrucker/BLE_HID/blob/master/examples/examples_common.cpp
cho45 6:f1c3ea8bc850 272 printf("ble.init\r\n");
cho45 6:f1c3ea8bc850 273
cho45 6:f1c3ea8bc850 274 BLE& ble = BLE::Instance(BLE::DEFAULT_INSTANCE);
cho45 6:f1c3ea8bc850 275 ble.init(bleInitComplete);
cho45 6:f1c3ea8bc850 276
cho45 6:f1c3ea8bc850 277 while (!ble.hasInitialized()) { }
cho45 6:f1c3ea8bc850 278 printf("ble.hasIntialized\r\n");
cho45 6:f1c3ea8bc850 279 }
cho45 6:f1c3ea8bc850 280
cho45 22:a78f0a91280a 281
cho45 10:1aed2481a743 282 void HIDController::waitForEvent() {
cho45 6:f1c3ea8bc850 283 BLE& ble = BLE::Instance(BLE::DEFAULT_INSTANCE);
cho45 21:d801c32231b0 284 keyboardService->stopReportTicker();
cho45 6:f1c3ea8bc850 285 ble.waitForEvent();
cho45 6:f1c3ea8bc850 286 }
cho45 6:f1c3ea8bc850 287
cho45 6:f1c3ea8bc850 288 void HIDController::appendReportData(uint8_t key) {
cho45 6:f1c3ea8bc850 289 if (keyboardService) {
cho45 6:f1c3ea8bc850 290 keyboardService->appendReportData(key);
cho45 6:f1c3ea8bc850 291 }
cho45 6:f1c3ea8bc850 292 }
cho45 6:f1c3ea8bc850 293
cho45 6:f1c3ea8bc850 294 void HIDController::deleteReportData(uint8_t key) {
cho45 6:f1c3ea8bc850 295 if (keyboardService) {
cho45 6:f1c3ea8bc850 296 keyboardService->deleteReportData(key);
cho45 6:f1c3ea8bc850 297 }
cho45 6:f1c3ea8bc850 298 }
cho45 9:d1daefbf1fbd 299
cho45 9:d1daefbf1fbd 300 void HIDController::queueCurrentReportData() {
cho45 20:d8840ac38434 301 if (!connected) return;
cho45 9:d1daefbf1fbd 302 if (keyboardService) {
cho45 23:b31957ce64e9 303 printf("queueCurrentReportData\r\n");
cho45 9:d1daefbf1fbd 304 keyboardService->queueCurrentReportData();
cho45 9:d1daefbf1fbd 305 }
cho45 9:d1daefbf1fbd 306 }