HID-over-GATT implementation with the BLE API. This library allows to create devices such as mouse, keyboard or joystick, over Bluetooth Low Energy.
Dependents: Seeed_Tiny_BLE_FTHR_Peripheral
Fork of BLE_HID by
Diff: KeyboardService.h
- Revision:
- 2:3d9adb26bdc5
- Parent:
- 1:7a6c2e2c9371
--- a/KeyboardService.h Wed Oct 07 11:29:52 2015 +0100 +++ b/KeyboardService.h Thu Oct 29 16:48:26 2015 +0000 @@ -24,7 +24,7 @@ /* TODO: make this easier to configure by application (e.g. as a template parameter for * KeyboardService) */ #ifndef KEYBUFFER_SIZE -#define KEYBUFFER_SIZE 512 +#define KEYBUFFER_SIZE 256 #endif /** @@ -237,8 +237,7 @@ /* * We're not transmitting anything anymore. Might as well avoid overloading the * system in case it can magically fix itself. Ticker will start again on next _putc - * call. It could also be started on next connection, but we can't register a callback - * for that, currently. + * call, or on next connection. */ stopReportTicker(); consecutiveFailures = 0; @@ -298,18 +297,20 @@ /** * Pop a key from the internal FIFO, and attempt to send it over BLE + * + * keyUp reports should theoretically be sent after every keyDown, but we optimize the + * throughput by only sending one when strictly necessary: + * - when we need to repeat the same key + * - when there is no more key to report + * + * In case of error, put the key event back in the buffer, and retry on next tick. */ virtual void sendCallback(void) { ble_error_t ret; uint8_t c; + static uint8_t previousKey = 0; - if (!keyBuffer.isSomethingPending()) { - /* Stop until the next call to putc */ - stopReportTicker(); - return; - } - - if (!keyBuffer.isKeyUpPending()) { + if (keyBuffer.isSomethingPending() && !keyBuffer.isKeyUpPending()) { bool hasData = keyBuffer.getPending(c); /* @@ -318,13 +319,26 @@ */ MBED_ASSERT(hasData); - if (hasData) { + if (!hasData) + return; + + if (previousKey == c) { + /* + * When the same key needs to be sent twice, we need to interleave a keyUp report, + * or else the OS won't be able to differentiate them. + * Push the key back into the buffer, and continue to keyUpCode. + */ + keyBuffer.setPending(c); + } else { ret = keyDownCode(c, keymap[c].modifier); if (ret) { keyBuffer.setPending(c); failedReports++; - return; + } else { + previousKey = c; } + + return; } } @@ -334,6 +348,11 @@ failedReports++; } else { keyBuffer.clearKeyUpPending(); + previousKey = 0; + + /* Idle when there is nothing more to send */ + if (!keyBuffer.isSomethingPending()) + stopReportTicker(); } }