Skip to content

Commit

Permalink
implement hid keyboard led set #166
Browse files Browse the repository at this point in the history
  • Loading branch information
hathach committed Aug 1, 2018
1 parent c44725b commit 1d301d5
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 56 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ void setup()
*/
blehid.begin();

// Set callback for set LED from central
blehid.setKeyboardLedCallback(set_keyboard_led);

/* Set connection interval (min, max) to your perferred value.
* Note: It is already set by BLEHidAdafruit::begin() to 11.25ms - 15ms
* min = 9*1.25=11.25 ms, max = 12*1.25= 15 ms
Expand Down Expand Up @@ -122,22 +125,21 @@ void loop()
}

/**
* RTOS Idle callback is automatically invoked by FreeRTOS
* when there are no active threads. E.g when loop() calls delay() and
* there is no bluetooth or hw event. This is the ideal place to handle
* background data.
*
* NOTE: FreeRTOS is configured as tickless idle mode. After this callback
* is executed, if there is time, freeRTOS kernel will go into low power mode.
* Therefore waitForEvent() should not be called in this callback.
* http://www.freertos.org/low-power-tickless-rtos.html
*
* WARNING: This function MUST NOT call any blocking FreeRTOS API
* such as delay(), xSemaphoreTake() etc ... for more information
* http://www.freertos.org/a00016.html
* Callback invoked when received Set LED from central.
* Must be set previously with setKeyboardLedCallback()
*
* The LED bit map is as follows: (also defined by KEYBOARD_LED_* )
* Kana (4) | Compose (3) | ScrollLock (2) | CapsLock (1) | Numlock (0)
*/
void rtos_idle_callback(void)
void set_keyboard_led(uint8_t led_bitmap)
{
// Don't call any other FreeRTOS blocking API()
// Perform background task(s) here
// light up Red Led if any bits is set
if ( led_bitmap )
{
ledOn( LED_RED );
}
else
{
ledOff( LED_RED );
}
}
24 changes: 23 additions & 1 deletion libraries/Bluefruit52Lib/src/services/BLEHidAdafruit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ BLEHidAdafruit::BLEHidAdafruit(void)
: BLEHidGeneric(3, 1, 0)
{
_mse_buttons = 0;
_kbd_led_cb = NULL;
}

err_t BLEHidAdafruit::begin(void)
Expand All @@ -211,7 +212,7 @@ err_t BLEHidAdafruit::begin(void)

VERIFY_STATUS( BLEHidGeneric::begin() );

// Attemp to change the connection interval to 11.25-15 ms when starting HID
// Attempt to change the connection interval to 11.25-15 ms when starting HID
Bluefruit.setConnInterval(9, 12);

return ERROR_NONE;
Expand All @@ -220,6 +221,27 @@ err_t BLEHidAdafruit::begin(void)
/*------------------------------------------------------------------*/
/* Keyboard
*------------------------------------------------------------------*/

void blehid_ada_keyboard_output_cb(BLECharacteristic& chr, uint8_t* data, uint16_t len, uint16_t offset)
{
LOG_LV2("HID", "Keyboard LED : 0x%02X", data[0]);
VERIFY(len == 1, );

BLEHidAdafruit& svc = (BLEHidAdafruit&) chr.parentService();
if ( svc._kbd_led_cb ) svc._kbd_led_cb(data[0]);
}

void BLEHidAdafruit::setKeyboardLedCallback(kbd_led_cb_t fp)
{
_kbd_led_cb = fp;

// Report mode
this->setOutputReportCallback(REPORT_ID_KEYBOARD, fp ? blehid_ada_keyboard_output_cb : NULL);

// Boot mode
_chr_boot_keyboard_output->setWriteCallback(fp ? blehid_ada_keyboard_output_cb : NULL);
}

bool BLEHidAdafruit::keyboardReport(hid_keyboard_report_t* report)
{
if ( isBootMode() )
Expand Down
14 changes: 11 additions & 3 deletions libraries/Bluefruit52Lib/src/services/BLEHidAdafruit.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@

class BLEHidAdafruit : public BLEHidGeneric
{
protected:
uint8_t _mse_buttons;

public:
/*--------- Callback Signatures ----------*/
typedef void (*kbd_led_cb_t) (uint8_t leds_bitmap);

BLEHidAdafruit(void);

virtual err_t begin(void);
Expand All @@ -58,6 +58,8 @@ class BLEHidAdafruit : public BLEHidGeneric
bool keyboardReport(uint8_t modifier, uint8_t keycode[6]);
bool keyboardReport(uint8_t modifier, uint8_t keycode0, uint8_t keycode1=0, uint8_t keycode2=0, uint8_t keycode3=0, uint8_t keycode4=0, uint8_t keycode5=0);

void setKeyboardLedCallback(kbd_led_cb_t fp);

bool keyPress(char ch);
bool keyRelease(void);
bool keySequence(const char* str, int interal=5);
Expand All @@ -77,6 +79,12 @@ class BLEHidAdafruit : public BLEHidGeneric
bool mouseMove(int8_t x, int8_t y);
bool mouseScroll(int8_t scroll);
bool mousePan(int8_t pan);

protected:
uint8_t _mse_buttons;
kbd_led_cb_t _kbd_led_cb;

friend void blehid_ada_keyboard_output_cb(BLECharacteristic& chr, uint8_t* data, uint16_t len, uint16_t offset);
};

#endif /* BLEHIDADAFRUIT_H_ */
38 changes: 11 additions & 27 deletions libraries/Bluefruit52Lib/src/services/BLEHidGeneric.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,6 @@ BLEHidGeneric::BLEHidGeneric(uint8_t num_input, uint8_t num_output, uint8_t num_
_chr_inputs = _chr_outputs = _chr_features = NULL;
_chr_boot_keyboard_input = _chr_boot_keyboard_output = _chr_boot_mouse_input = NULL;

_output_cbs = NULL;

if ( _num_input )
{
_chr_inputs = new BLECharacteristic[_num_input];
Expand All @@ -79,9 +77,6 @@ BLEHidGeneric::BLEHidGeneric(uint8_t num_input, uint8_t num_output, uint8_t num_
if ( _num_output )
{
_chr_outputs = new BLECharacteristic[_num_output];
_output_cbs = new output_report_cb_t[_num_output];

for (uint8_t i=0; i<_num_output; i++) _output_cbs[i] = NULL;
}

if ( _num_feature )
Expand Down Expand Up @@ -123,25 +118,18 @@ void BLEHidGeneric::setReportLen(uint16_t input_len[], uint16_t output_len[], ui
_feature_len = feature_len;
}

void BLEHidGeneric::setOutputReportCallback(uint8_t reportID, output_report_cb_t fp)
void BLEHidGeneric::setOutputReportCallback(uint8_t reportID, BLECharacteristic::write_cb_t fp)
{
_output_cbs[reportID] = fp;
// index is ID-1
uint8_t const idx = ( reportID ? (reportID-1) : 0 );

// report mode
if ( idx < _num_output ) _chr_outputs[idx].setWriteCallback(fp);
}

/*------------------------------------------------------------------*/
/* Callbacks
*------------------------------------------------------------------*/
// TODO output report
COMMENT_OUT (
void blehidgeneric_output_cb(BLECharacteristic& chr, ble_gatts_evt_write_t* request)
{
(void) chr;
(void) request;
// BLEHidGeneric& hid = (BLEHidGeneric&) chr.parentService();
// PRINT_BUFFER(request->data, request->len);
}
)

void blehid_generic_protocol_mode_cb(BLECharacteristic& chr, uint8_t* data, uint16_t len, uint16_t offset)
{
BLEHidGeneric& svc = (BLEHidGeneric&) chr.parentService();
Expand Down Expand Up @@ -192,13 +180,9 @@ err_t BLEHidGeneric::begin(void)
{
_chr_outputs[i].setUuid(UUID16_CHR_REPORT);
_chr_outputs[i].setProperties(CHR_PROPS_READ | CHR_PROPS_WRITE | CHR_PROPS_WRITE_WO_RESP);
_chr_outputs[i].setPermission(SECMODE_ENC_NO_MITM, SECMODE_NO_ACCESS);
_chr_outputs[i].setPermission(SECMODE_ENC_NO_MITM, SECMODE_ENC_NO_MITM);
_chr_outputs[i].setReportRefDescriptor(i+1, REPORT_TYPE_OUTPUT);

COMMENT_OUT(
_chr_outputs[i].setWriteCallback(blehidgeneric_output_cb);
)

// Input report len is configured, else variable len up to 255
if ( _output_len ) _chr_outputs[i].setFixedLen( _output_len[i] );

Expand Down Expand Up @@ -228,7 +212,7 @@ err_t BLEHidGeneric::begin(void)
_chr_boot_keyboard_output = new BLECharacteristic(UUID16_CHR_BOOT_KEYBOARD_OUTPUT_REPORT);
_chr_boot_keyboard_output->setProperties(CHR_PROPS_READ | CHR_PROPS_WRITE | CHR_PROPS_WRITE_WO_RESP);
_chr_boot_keyboard_output->setFixedLen(1); // boot keyboard is 1 byte
_chr_boot_keyboard_output->setPermission(SECMODE_ENC_NO_MITM, SECMODE_NO_ACCESS);
_chr_boot_keyboard_output->setPermission(SECMODE_ENC_NO_MITM, SECMODE_ENC_NO_MITM);
VERIFY_STATUS(_chr_boot_keyboard_output->begin());
_chr_boot_keyboard_output->write8(0);
}
Expand Down Expand Up @@ -267,10 +251,10 @@ err_t BLEHidGeneric::begin(void)
*------------------------------------------------------------------*/
bool BLEHidGeneric::inputReport(uint8_t reportID, void const* data, int len)
{
// 0 will treated as report ID = 1
if ( reportID == 0 ) reportID++;
// index is ID-1
uint8_t const idx = ( reportID ? (reportID-1) : 0 );

return _chr_inputs[reportID-1].notify( (uint8_t const*) data, len);
return _chr_inputs[idx].notify( (uint8_t const*) data, len);
}

bool BLEHidGeneric::bootKeyboardReport(void const* data, int len)
Expand Down
10 changes: 1 addition & 9 deletions libraries/Bluefruit52Lib/src/services/BLEHidGeneric.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,6 @@ typedef ATTR_PACKED_STRUCT(struct)
class BLEHidGeneric : public BLEService
{
public:
typedef void (*output_report_cb_t) (uint8_t reportID, uint8_t* data, uint16_t len);

BLEHidGeneric(uint8_t num_input, uint8_t num_output = 0, uint8_t num_feature = 0);

void enableKeyboard(bool enable);
Expand All @@ -111,7 +109,7 @@ class BLEHidGeneric : public BLEService
void setReportLen(uint16_t input_len[], uint16_t output_len[] = NULL, uint16_t feature_len[] = NULL);
void setReportMap(const uint8_t* report_map, size_t len);

void setOutputReportCallback(uint8_t reportID, output_report_cb_t fp);
void setOutputReportCallback(uint8_t reportID, BLECharacteristic::write_cb_t fp);

virtual err_t begin(void);

Expand Down Expand Up @@ -139,8 +137,6 @@ class BLEHidGeneric : public BLEService
uint16_t* _output_len;
uint16_t* _feature_len;

output_report_cb_t* _output_cbs;

BLECharacteristic* _chr_protocol;

BLECharacteristic* _chr_inputs;
Expand All @@ -154,10 +150,6 @@ class BLEHidGeneric : public BLEService
BLECharacteristic _chr_control;

friend void blehid_generic_protocol_mode_cb(BLECharacteristic& chr, uint8_t* data, uint16_t len, uint16_t offset);

COMMENT_OUT (
friend void blehidgeneric_output_cb(BLECharacteristic& chr, ble_gatts_evt_write_t* request);
)
};

//--------------------------------------------------------------------+
Expand Down

0 comments on commit 1d301d5

Please sign in to comment.