T-vK / ESP32-BLE-Keyboard

Bluetooth LE Keyboard library for the ESP32 (Arduino IDE compatible)
2.41k stars 404 forks source link

Read Numlock/Capslock/Scrolllock state progress? #68

Open LeeNX opened 3 years ago

LeeNX commented 3 years ago

Any progress or feedback on Read Numlock/Capslock/Scrolllock state?

I was looking at some examples of how to possible do this and see that KeyboardOutputCallbacks might be logging feedback special keys is that correct?

lalalandrus commented 3 years ago

I too am trying to probe those states. It seems right now it just gets dumped into the debug messages and lost forever. I dont know how to send the data up the callback to the parent function. If anyone can help, greatly appreciated.

T-vK commented 3 years ago

I haven't looked into it yet. I wasn't even aware that it was already implemented to the point that it would handle and log changes to the lock states.

@lalalandrus Is this where it gets logged? https://github.com/T-vK/ESP32-BLE-Keyboard/blob/928c09320e3e6e344a63640c7de21d52a20c1d47/KeyboardOutputCallbacks.cpp#L16

The name onWrite seems confusing... maybe onWrite was referring to the computer writing the lock state back to the keyboard? I can't remember.

If that's the case, maybe we can add 3 variables for each of the lock states and save the states to them within the onWrite method. Kind of like it's done with the connected state in BleConnectionStatus:

https://github.com/T-vK/ESP32-BLE-Keyboard/blob/928c09320e3e6e344a63640c7de21d52a20c1d47/BleConnectionStatus.cpp#L8

which can then be read from the BleKeyboard class:

https://github.com/T-vK/ESP32-BLE-Keyboard/blob/928c09320e3e6e344a63640c7de21d52a20c1d47/BleKeyboard.cpp#L110

In addition to that I think it would make sense to add another variable which simply holds a callback function that you have to pass to the constructor of KeyboardOutputCallbacks once in the beginning which is then called whenever a lock state changes.

The following is completely untested. Maybe it could be done somewhat like this:

KeyboardOutputCallbacks.h

#ifndef ESP32_BLE_KEYBOARD_OUTPUT_CALLBACKS_H
#define ESP32_BLE_KEYBOARD_OUTPUT_CALLBACKS_H
#include "sdkconfig.h"
#if defined(CONFIG_BT_ENABLED)

#include <BLEServer.h>
#include "BLE2902.h"
#include "BLECharacteristic.h"

class KeyboardOutputCallbacks : public BLECharacteristicCallbacks
{
public:
  KeyboardOutputCallbacks(void (*lockCallback)(bool,bool,bool)); // MODIFIED
  void onWrite(BLECharacteristic* me);
  void (*onLockChange)(bool,bool,bool); // ADDED
  bool numLockState; // ADDED
  bool capsLockState; // ADDED
  bool scrollLockState; // ADDED
};

#endif // CONFIG_BT_ENABLED
#endif // ESP32_BLE_KEYBOARD_OUTPUT_CALLBACKS_H

KeyboardOutputCallbacks.cpp

#include "KeyboardOutputCallbacks.h"

#if defined(CONFIG_ARDUHAL_ESP_LOG)
  #include "esp32-hal-log.h"
  #define LOG_TAG ""
#else
  #include "esp_log.h"
  static const char* LOG_TAG = "BLEDevice";
#endif

KeyboardOutputCallbacks::KeyboardOutputCallbacks(void (*lockCallback)(bool,bool,bool)) { // MODIFIED
  onLockChange = lockCallback; // ADDED
}

void KeyboardOutputCallbacks::onWrite(BLECharacteristic* me) {
  uint8_t* value = (uint8_t*)(me->getValue().c_str());
  ESP_LOGI(LOG_TAG, "special keys: %d", *value);

  // TODO: Add logic to find out which lock key changed to which state and set variables accordingly
  this->numLockState = ?????; // ADDED
  this->capsLockState = ?????; // ADDED
  this->scrollLockState = ?????; // ADDED
  this->onLockChange(this->numLockState, this->capsLockState, this->scrollLockState) // ADDED
}

Then you could add something like this to the BleKeyboard class (BleKeyboard.cpp):

// add:
bool BleKeyboard::isNumLockOn(void) {
  return this->keyboardOutputCallbacks->numLockState;
}
bool BleKeyboard::isCapsLockOn(void) {
  return this->keyboardOutputCallbacks->capsLockState;
}
bool BleKeyboard::isScollLockOn(void) {
  return this->keyboardOutputCallbacks->scrollLockState;
}

// remove:
bleKeyboardInstance->outputKeyboard->setCallbacks(new KeyboardOutputCallbacks());
//add:
this->keyboardOutputCallbacks = new KeyboardOutputCallbacks(this->onLockChange);
bleKeyboardInstance->outputKeyboard->setCallbacks(keyboardOutputCallbacks);

//remove:
BleKeyboard::BleKeyboard(std::string deviceName, std::string deviceManufacturer, uint8_t batteryLevel) : hid(0)
{
// add:
BleKeyboard::BleKeyboard(std::string deviceName, std::string deviceManufacturer, uint8_t batteryLevel, void (*lockCallback)(bool,bool,bool)) : hid(0)
{
onLockChange = lockCallback;

and of course in the BleKeyboard.h:

// remove
BleKeyboard(std::string deviceName = "ESP32 BLE Keyboard", std::string deviceManufacturer = "Espressif", uint8_t batteryLevel = 100);
// add
BleKeyboard(std::string deviceName = "ESP32 BLE Keyboard", std::string deviceManufacturer = "Espressif", uint8_t batteryLevel = 100, void (*lockCallback)(bool,bool,bool));

// add
void (*onLockChange)(bool,bool,bool);

Then it should be possible to do:

void onLockChange(bool numLockState, bool capsLockState, bool ScrollLockState) {
  // this gets called every time a lock state changes
  // do whatever you want with numLockState, capsLockState and ScrollLockState ....
}

BleKeyboard bleKeyboard("Bluetooth Device Name", "Bluetooth Device Manufacturer", 100, onLockChange);

// to manually check for the current state do this:
bool numLockState = bleKeybaord.isNumLockOn();

As I said, completely untested. If you want to make this happen feel free to give it a try and make a PR. I don't really want to spend too much time working on this library.

T-vK commented 3 years ago

@LeeNX @lalalandrus See #70

60999 commented 2 years ago

Excuse me, what's the progress now? Has the problem been solved?