ble nano hid over gatt
Dependencies: BLE_API mbed-dev nRF51822
KeyboardService.h
- Committer:
- cho45
- Date:
- 2016-07-21
- Revision:
- 5:65d4e94735b6
- Child:
- 6:f1c3ea8bc850
File content as of revision 5:65d4e94735b6:
/* mbed Microcontroller Library * Copyright (c) 2015 ARM Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "HIDServiceBase.h" #include "keyboard.h" /** * Report descriptor for a standard 101 keys keyboard, following the HID specification example: * - 8 bytes input report (1 byte for modifiers and 6 for keys) * - 1 byte output report (LEDs) */ report_map_t KEYBOARD_REPORT_MAP = { USAGE_PAGE(1), 0x01, // Generic Desktop Ctrls USAGE(1), 0x06, // Keyboard COLLECTION(1), 0x01, // Application USAGE_PAGE(1), 0x07, // Kbrd/Keypad USAGE_MINIMUM(1), 0xE0, USAGE_MAXIMUM(1), 0xE7, LOGICAL_MINIMUM(1), 0x00, LOGICAL_MAXIMUM(1), 0x01, REPORT_SIZE(1), 0x01, // 1 byte (Modifier) REPORT_COUNT(1), 0x08, INPUT(1), 0x02, // Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position REPORT_COUNT(1), 0x01, // 1 byte (Reserved) REPORT_SIZE(1), 0x08, INPUT(1), 0x01, // Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position REPORT_COUNT(1), 0x05, // 5 bits (Num lock, Caps lock, Scroll lock, Compose, Kana) REPORT_SIZE(1), 0x01, USAGE_PAGE(1), 0x08, // LEDs USAGE_MINIMUM(1), 0x01, // Num Lock USAGE_MAXIMUM(1), 0x05, // Kana OUTPUT(1), 0x02, // Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile REPORT_COUNT(1), 0x01, // 3 bits (Padding) REPORT_SIZE(1), 0x03, OUTPUT(1), 0x01, // Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile REPORT_COUNT(1), 0x06, // 6 bytes (Keys) REPORT_SIZE(1), 0x08, LOGICAL_MINIMUM(1), 0x00, LOGICAL_MAXIMUM(1), 0x65, // 101 keys USAGE_PAGE(1), 0x07, // Kbrd/Keypad USAGE_MINIMUM(1), 0x00, USAGE_MAXIMUM(1), 0x65, INPUT(1), 0x00, // Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position END_COLLECTION(0), }; class KeyboardService : public HIDServiceBase { union { uint8_t raw[8]; struct { uint8_t modifier; uint8_t padding; uint8_t keycode[6]; } data; } inputReportData; union { uint8_t raw[1]; } outputReportData; static const uint8_t MODIFIER_LEFT_CONTROL = 1<<0; static const uint8_t MODIFIER_LEFT_SHIFT = 1<<1; static const uint8_t MODIFIER_LEFT_ALT = 1<<2; static const uint8_t MODIFIER_LEFT_GUI = 1<<3; static const uint8_t MODIFIER_RIGHT_CONTROL = 1<<4; static const uint8_t MODIFIER_RIGHT_SHIFT = 1<<5; static const uint8_t MODIFIER_RIGHT_ALT = 1<<6; static const uint8_t MODIFIER_RIGHT_GUI = 1<<7; public: KeyboardService(BLE& _ble) : HIDServiceBase( _ble, KEYBOARD_REPORT_MAP, sizeof(KEYBOARD_REPORT_MAP), inputReport = inputReportData.raw, outputReport = outputReportData.raw, featureReport = NULL, inputReportLength = sizeof(inputReportData), outputReportLength = sizeof(outputReportData), featureReportLength = 0, reportTickerDelay = 24 ) { } void appendReportData(uint8_t keycode) { uint8_t modifier = toModifierBit(keycode); if (modifier) { inputReportData.data.modifier |= modifier; startReportTicker(); return; } for (int i = 0; i < 6; i++) { if (inputReportData.data.keycode[i] == 0) { inputReportData.data.keycode[i] = keycode; startReportTicker(); return; } } // TODO: report data is full } void deleteReportData(uint8_t keycode) { uint8_t modifier = toModifierBit(keycode); if (modifier) { inputReportData.data.modifier &= ~modifier; startReportTicker(); return; } for (int i = 0; i < 6; i++) { if (inputReportData.data.keycode[i] == keycode) { inputReportData.data.keycode[i] = 0; startReportTicker(); return; } } } uint8_t toModifierBit(uint8_t keycode) const { switch (keycode) { case KEY_LeftControl: return MODIFIER_LEFT_CONTROL; case KEY_LeftShift: return MODIFIER_LEFT_SHIFT; case KEY_LeftAlt: return MODIFIER_LEFT_ALT; case KEY_LeftGUI: return MODIFIER_LEFT_GUI; case KEY_RightControl: return MODIFIER_RIGHT_CONTROL; case KEY_RightShift: return MODIFIER_RIGHT_SHIFT; case KEY_RightAlt: return MODIFIER_RIGHT_ALT; case KEY_RightGUI: return MODIFIER_RIGHT_GUI; } return 0; } bool isKeyPressed() { for (int i = 0; i < 8; i++) { if (inputReportData.raw[i]) { return 1; } } return 0; } virtual void sendCallback(void) { ble_error_t error = HIDServiceBase::send(inputReportData.raw); if (error == BLE_STACK_BUSY) { // retry after return; } if (!isKeyPressed()) { stopReportTicker(); } } };