ble nano hid over gatt
Dependencies: BLE_API mbed-dev nRF51822
Revision 86:e0fab77e669d, committed 2016-09-15
- Comitter:
- cho45
- Date:
- Thu Sep 15 09:31:05 2016 +0900
- Parent:
- 85:e526a89a0674
- Commit message:
- support consumer keys
Changed in this revision
--- a/HIDController_BLE.cpp Thu Sep 15 08:48:57 2016 +0900 +++ b/HIDController_BLE.cpp Thu Sep 15 09:31:05 2016 +0900 @@ -350,6 +350,18 @@ } } +void HIDController::pressConsumerKey(const uint16_t key) { + if (keyboardService) { + keyboardService->pressConsumerKey(key); + } +} + +void HIDController::releaseConsumerKey() { + if (keyboardService) { + keyboardService->releaseConsumerKey(); + } +} + void HIDController::queueCurrentReportData() { if (!connected()) return; if (keyboardService) {
--- a/HIDController_BLE.h Thu Sep 15 08:48:57 2016 +0900 +++ b/HIDController_BLE.h Thu Sep 15 09:31:05 2016 +0900 @@ -20,6 +20,8 @@ static void appendReportData(const uint8_t key); static void deleteReportData(const uint8_t key); + static void pressConsumerKey(const uint16_t key); + static void releaseConsumerKey(); static void queueCurrentReportData(); static void updateBatteryLevel(const uint8_t percentage, const uint16_t voltage); static void initializeConnection(const bool ignoreWhiteList);
--- a/HIDServiceBase.cpp Thu Sep 15 08:48:57 2016 +0900 +++ b/HIDServiceBase.cpp Thu Sep 15 09:31:05 2016 +0900 @@ -18,20 +18,20 @@ #include "config.h" #include "HIDServiceBase.h" -static const report_reference_t inputReportReferenceData = { 0, INPUT_REPORT }; +static const report_reference_t inputReportReferenceData = { 1, INPUT_REPORT }; static const GattAttribute inputReportReferenceDescriptor(BLE_UUID_DESCRIPTOR_REPORT_REFERENCE, (uint8_t *)&inputReportReferenceData, 2, 2, false); static const GattAttribute * inputReportDescriptors[] = { &inputReportReferenceDescriptor, }; -static const report_reference_t outputReportReferenceData = { 0, OUTPUT_REPORT }; +static const report_reference_t outputReportReferenceData = { 1, OUTPUT_REPORT }; static const GattAttribute outputReportReferenceDescriptor(BLE_UUID_DESCRIPTOR_REPORT_REFERENCE, (uint8_t *)&outputReportReferenceData, 2, 2, false); static const GattAttribute * outputReportDescriptors[] = { &outputReportReferenceDescriptor, }; -static const report_reference_t featureReportReferenceData = { 0, FEATURE_REPORT }; +static const report_reference_t featureReportReferenceData = { 1, FEATURE_REPORT }; static const GattAttribute featureReportReferenceDescriptor(BLE_UUID_DESCRIPTOR_REPORT_REFERENCE, (uint8_t *)&featureReportReferenceData, 2, 2, false); static const GattAttribute * featureReportDescriptors[] = { &featureReportReferenceDescriptor,
--- a/KeyboardService.h Thu Sep 15 08:48:57 2016 +0900 +++ b/KeyboardService.h Thu Sep 15 09:31:05 2016 +0900 @@ -28,6 +28,7 @@ USAGE_PAGE(1), 0x01, // Generic Desktop Ctrls USAGE(1), 0x06, // Keyboard COLLECTION(1), 0x01, // Application + REPORT_ID(1), 0x01, USAGE_PAGE(1), 0x07, // Kbrd/Keypad USAGE_MINIMUM(1), 0xE0, USAGE_MAXIMUM(1), 0xE7, @@ -61,13 +62,36 @@ USAGE_MAXIMUM(1), 0x65, INPUT(1), 0x00, // Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position - USAGE_PAGE(1), 0x00, // Undefined - USAGE_MINIMUM(1), 0x00, - USAGE_MAXIMUM(1), 0xFF, - REPORT_COUNT(1), 0x01, // 1 byte - REPORT_SIZE(1), 0x08, - FEATURE(1), 0x02, // Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile + USAGE_PAGE(1), 0x0C, // Consumer + USAGE(1), 0x00, + COLLECTION(1), 0x02, // Logical + REPORT_ID(1), 0x01, + USAGE_MINIMUM(1), 0x00, + USAGE_MAXIMUM(1), 0xFF, + REPORT_COUNT(1), 0x01, // 1 byte + REPORT_SIZE(1), 0x08, + FEATURE(1), 0x02, // Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile + END_COLLECTION(0), END_COLLECTION(0), + + USAGE_PAGE(1), 0x0C, + USAGE(1), 0x01, + COLLECTION(1), 0x01, + REPORT_ID(1), 0x03, + REPORT_SIZE(1), 0x10, + REPORT_COUNT(1), 0x01, + LOGICAL_MINIMUM(1), 1, + LOGICAL_MAXIMUM(2), 0xFF, 0x03, + USAGE_MINIMUM(1), 1, + USAGE_MAXIMUM(2), 0xFF, 0x03, + INPUT(1), 0x60, + END_COLLECTION(0), +}; + +static const report_reference_t consumerInputReportReferenceData = { 3, INPUT_REPORT }; +static const GattAttribute consumerInputReportReferenceDescriptor(BLE_UUID_DESCRIPTOR_REPORT_REFERENCE, (uint8_t *)&consumerInputReportReferenceData, 2, 2, false); +static const GattAttribute * consumerInputReportDescriptors[] = { + &consumerInputReportReferenceDescriptor, }; class KeyboardService : public HIDServiceBase { @@ -89,12 +113,18 @@ uint8_t raw[1]; }; + union ConsumerInputReportData { + uint8_t raw[2]; + uint16_t key; + }; + /** * Boot Protocol * Share input/output report with Report Protocol for memmory saving */ GattCharacteristic bootKeyboardInputReportCharacteristic; GattCharacteristic bootKeyboardOutputReportCharacteristic; + GattCharacteristic consumerInputReportCharacteristic; InputReportData inputReportDataPublished; InputReportData inputReportData; @@ -110,6 +140,9 @@ FeatureReportData featureReportData; bool isSending; + ConsumerInputReportData consumerInputReportData; + bool hasPendingConsumerInputReport; + 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; @@ -149,7 +182,16 @@ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE ), + consumerInputReportCharacteristic( + GattCharacteristic::UUID_REPORT_CHAR, + (uint8_t *)&consumerInputReportData, sizeof(consumerInputReportData), sizeof(consumerInputReportData), + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ + | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY + | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE, + const_cast<GattAttribute**>(consumerInputReportDescriptors), 1 + ), isSending(false), + hasPendingConsumerInputReport(false), sendAvailable(false), bufferCount(0) { @@ -165,6 +207,7 @@ DEBUG_PRINTF_BLE("addExtraCharacteristics %d\r\n", charIndex); characteristics[charIndex++] = &bootKeyboardInputReportCharacteristic; characteristics[charIndex++] = &bootKeyboardOutputReportCharacteristic; + characteristics[charIndex++] = &consumerInputReportCharacteristic; } virtual ble_error_t send(const report_t report) { @@ -216,6 +259,18 @@ } } + void pressConsumerKey(const uint16_t key) { + consumerInputReportData.key = key; + hasPendingConsumerInputReport = true; + sendAvailable = true; + } + + void releaseConsumerKey() { + consumerInputReportData.key = 0; + hasPendingConsumerInputReport = true; + sendAvailable = true; + } + void queueCurrentReportData() { DEBUG_PRINTF_BLE("Q %d\r\n", bufferCount); bufferCount++; @@ -251,6 +306,15 @@ return; } sendAvailable = false; + + if (hasPendingConsumerInputReport) { + ble.gattServer().write( + consumerInputReportCharacteristic.getValueHandle(), + (uint8_t*)&consumerInputReportData, + sizeof(consumerInputReportData) + ); + hasPendingConsumerInputReport = false; + } // isSending の場合現在送信中の report があり、再送中である可能性がある // そうではない場合のみ queue から pop して新しく send する
--- a/keymap.h Thu Sep 15 08:48:57 2016 +0900 +++ b/keymap.h Thu Sep 15 09:31:05 2016 +0900 @@ -38,6 +38,14 @@ DEBUG_PRINTF_KEYEVENT("LAYER->%d\r\n", keymap.layer); } + static void consumer_play_pause(Keymap& keymap, const bool pressed) { + if (pressed) { + HIDController::pressConsumerKey(0x00cd); + } else { + HIDController::releaseConsumerKey(); + } + } + void execute(const int row, const int col, const bool pressed) { for (int i = 0; ; i++) { const keyfunc_t& keyfunc = KEYMAP_FUNCTIONS[i]; @@ -100,6 +108,7 @@ const keyfunc_t Keymap::KEYMAP_FUNCTIONS[] = { { 5, 14, &Keymap::switch_layer }, + { 5, 5, &Keymap::consumer_play_pause }, { -1, -1, 0 } /* for iteration */ };