Skip to content

Instantly share code, notes, and snippets.

@cattaka
Created March 10, 2018 16:48
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cattaka/e54bb8dd53e76d2bf48aa261463cc683 to your computer and use it in GitHub Desktop.
Save cattaka/e54bb8dd53e76d2bf48aa261463cc683 to your computer and use it in GitHub Desktop.
#include<BLEDevice.h>
#include<BLEHIDDevice.h>
BLEServer* gBLEServer;
BLEHIDDevice* gBLEHIDDevice;
BLECharacteristic* gBLECharacteristic;
class MyServerCallbacks: public BLEServerCallbacks {
public:
bool deviceConnected;
void onConnect(BLEServer* pServer) {
Serial.println("onConnect");
deviceConnected = true;
};
void onDisconnect(BLEServer* pServer) {
Serial.println("onDisconnect");
deviceConnected = false;
}
};
MyServerCallbacks gMyServerCallbacks;
void setup() {
pinMode(5,INPUT_PULLUP);
// put your setup code here, to run once:
pinMode(16, INPUT);
pinMode(17, INPUT);
Serial.begin(9600);
Serial.print("addr: ");
BLEDevice::init("hoge");
gBLEServer = BLEDevice::createServer();
gBLEServer->setCallbacks(&gMyServerCallbacks);
gBLEHIDDevice = new BLEHIDDevice(gBLEServer);
/*
Set manufacturer name
https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.characteristic.manufacturer_name_string.xml
*/
std::string name = "ctk-lab";
gBLEHIDDevice->manufacturer()->setValue(name);
/*
Set pnp parameters
https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.characteristic.pnp_id.xml
*/
// const uint8_t pnp[] = {0x01, 0x02, 0xe5, 0xab, 0xcd, 0x01, 0x10};
gBLEHIDDevice->pnp(0x01, 0x02e5, 0xabcd, 0x0110);
/*
Set hid informations
https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.characteristic.hid_information.xml
*/
//const uint8_t val1[] = {0x01, 0x11, 0x00, 0x03};
gBLEHIDDevice->hidInfo(0, 4);
/*
Mouse
*/
const uint8_t reportMap2[] = {
USAGE_PAGE(1), 0x01,
USAGE(1), 0x02,
COLLECTION(1), 0x01,
USAGE(1), 0x01,
COLLECTION(1), 0x00,
USAGE_PAGE(1), 0x09,
USAGE_MINIMUM(1), 0x1,
USAGE_MAXIMUM(1), 0x3,
LOGICAL_MINIMUM(1), 0x0,
LOGICAL_MAXIMUM(1), 0x1,
REPORT_COUNT(1), 0x3,
REPORT_SIZE(1), 0x1,
HIDINPUT(1), 0x2, // (Data, Variable, Absolute), ;3 button bits
REPORT_COUNT(1), 0x1,
REPORT_SIZE(1), 0x5,
HIDINPUT(1), 0x1, //(Constant), ;5 bit padding
USAGE_PAGE(1), 0x1, //(Generic Desktop),
USAGE(1), 0x30,
USAGE(1), 0x31,
LOGICAL_MINIMUM(1), 0x81,
LOGICAL_MAXIMUM(1), 0x7f,
REPORT_SIZE(1), 0x8,
REPORT_COUNT(1), 0x2,
HIDINPUT(1), 0x6, //(Data, Variable, Relative), ;2 position bytes (X & Y)
END_COLLECTION(0),
END_COLLECTION(0)
};
/*
Keyboard
*/
const uint8_t reportMap[] = {
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,
HIDINPUT(1), 0x02, // Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position
REPORT_COUNT(1), 0x01, // 1 byte (Reserved)
REPORT_SIZE(1), 0x08,
HIDINPUT(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
HIDOUTPUT(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,
HIDOUTPUT(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,
HIDINPUT(1), 0x00, // Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position
END_COLLECTION(0)
};
/*
Set report map (here is initialized device driver on client side)
https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.characteristic.report_map.xml
*/
gBLEHIDDevice->reportMap((uint8_t*)reportMap, sizeof(reportMap));
gBLECharacteristic = gBLEHIDDevice->inputReport(NULL);
gBLEHIDDevice->startServices();
// gBLECharacteristic = gBLEHIDDevice->hidService()->getCharacteristic((uint16_t)0x2a4b);
Serial.println(gBLECharacteristic->getUUID().toString().c_str());
BLEAdvertising *pAdvertising = gBLEServer->getAdvertising();
pAdvertising->setAppearance(HID_KEYBOARD);
pAdvertising->addServiceUUID(gBLEHIDDevice->hidService()->getUUID());
pAdvertising->start();
BLESecurity *pSecurity = new BLESecurity();
pSecurity->setAuthenticationMode(ESP_LE_AUTH_REQ_SC_BOND);
pSecurity->setCapability(ESP_IO_CAP_NONE);
pSecurity->setInitEncryptionKey(ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK);
Serial.println(BLEDevice::getAddress().toString().c_str());
}
bool gPressed16 = false;
bool gPressed17 = false;
void sendChar(uint8_t modifier, uint8_t usage) {
uint8_t a[] = {modifier, 0x0, usage, 0x0, 0x0, 0x0, 0x0, 0x0};
gBLECharacteristic->setValue(a, sizeof(a));
gBLECharacteristic->notify();
}
void loop() {
// put your main code here, to run repeatedly:
bool pressed16 = !digitalRead(16);
bool pressed17 = !digitalRead(17);
if (gMyServerCallbacks.deviceConnected) {
if (gPressed16 != pressed16) {
gPressed16 = pressed16;
if (gPressed16) {
sendChar(0, 0x04/*a*/);
sendChar(0, 0);
}
}
if (gPressed17 != pressed17) {
gPressed17 = pressed17;
if (gPressed17) {
sendChar(0, 0x16/*s*/);
sendChar(0, 0);
}
Serial.print(gPressed16);
Serial.print(", ");
Serial.print(gPressed17);
Serial.println();
}
}
delay(100);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment