AndroidにキーボードとしてBLEモジュールを認識させて、ショートカットを叩けます。 ショートカットキー btn1:Alt + Tab btn2: Enter
Dependencies: BLE_API mbed nRF51822
Revision 0:f9f11f6ee09d, committed 2015-09-15
- Comitter:
- leibun
- Date:
- Tue Sep 15 02:53:19 2015 +0000
- Commit message:
- First commit.
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BLE_API.lib Tue Sep 15 02:53:19 2015 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/teams/Bluetooth-Low-Energy/code/BLE_API/#8cea5d9c12c0
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HIDService.cpp Tue Sep 15 02:53:19 2015 +0000 @@ -0,0 +1,79 @@ +#include "HIDService.h" + +const uint8_t KeyboardReportMap[] = + { 0x05, 0x01, // Usage Page (Generic Desktop) + 0x09, 0x06, // Usage (Keyboard) + 0xA1, 0x01, // Collection (Application) + 0x05, 0x07, // Usage Page (Key Codes) + 0x19, 0xe0, // Usage Minimum (224) + 0x29, 0xe7, // Usage Maximum (231) + 0x15, 0x00, // Logicagl Minimum (0) + 0x25, 0x01, // Logical Maximum (1) + 0x75, 0x01, // Report Size (1) + 0x95, 0x08, // Report Count (8) + 0x81, 0x02, // Input (Data, Variable, Absolute) + + 0x95, 0x01, // Report Count (1) + 0x75, 0x08, // Report Size (8) + 0x81, 0x01, // Input (Constant) reserved byte(1) + + 0x95, 0x05, // Report Count (5) + 0x75, 0x01, // Report Size (1) + 0x05, 0x08, // Usage Page (Page# for LEDs) + 0x19, 0x01, // Usage Minimum (1) + 0x29, 0x05, // Usage Maximum (5) + 0x91, 0x02, // Output (Data, Variable, Absolute), Led report + 0x95, 0x01, // Report Count (1) + 0x75, 0x03, // Report Size (3) + 0x91, 0x01, // Output (Data, Variable, Absolute), Led report padding + + 0x95, 0x06, // Report Count (6) + 0x75, 0x08, // Report Size (8) + 0x15, 0x00, // Logical Minimum (0) + 0x25, 0x65, // Logical Maximum (101) + 0x05, 0x07, // Usage Page (Key codes) + 0x19, 0x00, // Usage Minimum (0) +// 0x29, 0x65, // Usage Maximum (101) + 0x29, 0xA4, // Usage Maximum (0xA4) + 0x81, 0x00, // Input (Data, Array) Key array(6 bytes) + + 0x09, 0x05, // Usage (Vendor Defined) + 0x15, 0x00, // Logical Minimum (0) + 0x26, 0xFF, 0x00, // Logical Maximum (255) + 0x75, 0x08, // Report Count (2) + 0x95, 0x02, // Report Size (8 bit) + 0xB1, 0x02, // Feature (Data, Variable, Absolute) + 0xC0 // End Collection (Application) + }; + +const uint8_t KeyboardReportMap2[] = + { + 0x05, 0x01, // USAGE_PAGE (Generic Desktop) // 47 + 0x09, 0x06, // USAGE (Keyboard) + 0xa1, 0x01, // COLLECTION (Application) + 0x85, 0x02, // REPORT_ID (2) + 0x05, 0x07, // USAGE_PAGE (Keyboard) + + 0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl) + 0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x25, 0x01, // LOGICAL_MAXIMUM (1) + 0x75, 0x01, // REPORT_SIZE (1) + + 0x95, 0x08, // REPORT_COUNT (8) + 0x81, 0x02, // INPUT (Data,Var,Abs) + 0x95, 0x01, // REPORT_COUNT (1) + 0x75, 0x08, // REPORT_SIZE (8) + 0x81, 0x03, // INPUT (Cnst,Var,Abs) + + 0x95, 0x06, // REPORT_COUNT (6) + 0x75, 0x08, // REPORT_SIZE (8) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x25, 0x65, // LOGICAL_MAXIMUM (101) + 0x05, 0x07, // USAGE_PAGE (Keyboard) + + 0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated)) + 0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application) + 0x81, 0x00, // INPUT (Data,Ary,Abs) + 0xc0, // END_COLLECTION + }; \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HIDService.h Tue Sep 15 02:53:19 2015 +0000 @@ -0,0 +1,131 @@ +#ifndef __BLE_HID_SERVICE_H__ +#define __BLE_HID_SERVICE_H__ + +#include <stdio.h> +#include "BLE.h" +/** +* @class Human Interface Device Service +* @brief BLE Human Interface Device Service. This service displays the Glucose measurement value represented as a 16bit Float format.<br> +* @Author: Marco.Hsu +* @Email: marco.missyou@gmail.com +*/ + +extern const uint8_t KeyboardReportMap[76]; + +class HIDService { +public: + HIDService(BLEDevice &_ble, const uint8_t* key = &KeyboardReportMap[0]): + ble(_ble), + protocol_modeValue(1), // Report Protocol Mode(1), Boot Protocol Mode(0) + KeyboardMap(key), + Protocol_Mode(GattCharacteristic::UUID_PROTOCOL_MODE_CHAR, &protocol_modeValue, 1, 1, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE|GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ), + ReportMap(GattCharacteristic::UUID_REPORT_MAP_CHAR, KeyboardMap.getPointer(), 76, sizeof(KeyboardMap), GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ |GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY), + Report(GattCharacteristic::UUID_REPORT_CHAR, reportValue.getPointer(), 8, 8, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY|GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ), + HID_Information(GattCharacteristic::UUID_HID_INFORMATION_CHAR, hidInformation.getPointer(), 4, 4, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ), + HID_Control_Point(GattCharacteristic::UUID_HID_CONTROL_POINT_CHAR, &hidcontrolPointer, 1, 1, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE) + { + static bool serviceAdded = false; /* We should only ever need to add the heart rate service once. */ + if (serviceAdded) { + return; + } + //Report.requireSecurity(SecurityManager::SECURITY_MODE_ENCRYPTION_OPEN_LINK); + GattCharacteristic *charTable[] = {&Protocol_Mode, &ReportMap, &Report, &HID_Information, &HID_Control_Point}; + GattService HIDGattService(GattService::UUID_HUMAN_INTERFACE_DEVICE_SERVICE, charTable, sizeof(charTable) / sizeof(GattCharacteristic *)); + ble.addService(HIDGattService); + serviceAdded = true; + ble.onDataWritten(this, &HIDService::onDataWritten); + } +public: + void updateReport(uint8_t modifydata, uint8_t data) { + reportValue.updateReportValue(modifydata, data); + + uint8_t *pRv = reportValue.getPointer(); + printf("reportValue[8]:"); + for(int i=0;i<8;i++){ printf("%x:",pRv[i]);} + printf("\r\n"); + + ble.updateCharacteristicValue(Report.getValueAttribute().getHandle(), reportValue.getPointer(), 8); + } + + virtual void onDataWritten(const GattWriteCallbackParams *params) { + if (params->handle == HID_Control_Point.getValueAttribute().getHandle()) { + uint16_t bytesRead = params->len; + if (bytesRead == 1) { + memcpy(&hidcontrolPointer, params->data, bytesRead); + } + } + if (params->handle == Report.getValueAttribute().getHandle()) { + uint16_t bytesRead = params->len; + if (bytesRead <= 4) { + memcpy(&reportValue, params->data, bytesRead); + } + } + } + +private: + struct ReportMapStructure{ + uint8_t KeyboardMap[76]; + ReportMapStructure(const uint8_t* data): KeyboardMap() { + memcpy(&KeyboardMap[0], data, 76); + } + uint8_t *getPointer(void) { + return KeyboardMap; + } + }; + +private: + struct ReportStructure { + // Initial setting report value + ReportStructure(): reportValue() { + uint8_t data= 0x00; + updateReportValue(data, data); + } + + void updateReportValue(uint8_t modifyKey, uint8_t data){ + memset(&reportValue[0], 0 ,8); + memcpy(&reportValue[0], &modifyKey, 1); + memcpy(&reportValue[2], &data, 1); + } + + uint8_t *getPointer(void) { + return reportValue; + } + + uint8_t reportValue[8]; + }; + +private: + struct HIDInforStructure{ + uint16_t bcdHID; + uint8_t bCountryCode; + uint8_t Flags; + + HIDInforStructure():bcdHID(0x001)/*Release version 0.01*/,bCountryCode(33)/*US*/,Flags(0){ + memcpy(&hidInformation[0], &bcdHID, 2); + memcpy(&hidInformation[2], &bCountryCode, 1); + memcpy(&hidInformation[3], &Flags, 1); + } + uint8_t *getPointer(void) { + return hidInformation; + } + + uint8_t hidInformation[4]; + }; + +private: + BLEDevice &ble; + uint8_t protocol_modeValue; + ReportStructure reportValue; + uint8_t hidcontrolPointer; + ReportMapStructure KeyboardMap; + HIDInforStructure hidInformation; + GattCharacteristic Protocol_Mode; + GattCharacteristic ReportMap; + GattCharacteristic Report; +// ReadOnlyGattCharacteristic Boot_Keyboard_Input_Report; +// ReadWriteGattCharacteristic Boot_Keyboard_Output_Report; +// ReadOnlyGattCharacteristic Boot_Mouse_Input_Report; + GattCharacteristic HID_Information; + GattCharacteristic HID_Control_Point; +}; +#endif /* #ifndef __BLE_GLUCOSE_SERVICE_H__*/ \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Tue Sep 15 02:53:19 2015 +0000 @@ -0,0 +1,92 @@ +#include "mbed.h" +#include "BLE.h" +#include "BatteryService.h" +#include "DeviceInformationService.h" +#include "HIDService.h" + +BLEDevice ble; + +Serial uart(USBTX, USBRX); +DigitalOut led01(LED1); +DigitalOut RFSWIO(LED2); +Ticker flipper; +DigitalIn btn01(P0_17); +DigitalIn btn02(P0_16); +DigitalIn btn03(P0_21); + +bool flip_lock = false; + +void flip() { + if (!flip_lock) RFSWIO = !RFSWIO; +} + +unsigned char keyData; +static const char DEVICE_NAME[] = "HID_Android_ShortCutKey"; +static const uint16_t uuid16_list[] = {GattService::UUID_HUMAN_INTERFACE_DEVICE_SERVICE}; +static volatile bool triggerSensorPolling = false; + +void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason) +{ + ble.startAdvertising(); // restart advertising +} + +char msg[25] = "NNN40 CONNECTED\n"; +int main(void) +{ + btn01.mode(PullUp); + btn02.mode(PullUp); + btn03.mode(PullUp); + + uart.baud(115200); + uart.printf("Starting HID Service\r\n"); + RFSWIO = 1; + led01 = 1; + memset(msg, 0, 25); + /*======BLE setup========*/ + ble.init(); + bool enableBonding = true; + bool requireMITM = true; + ble.initializeSecurity(enableBonding, requireMITM, SecurityManager::IO_CAPS_NONE); //IO_CAPS_DISPLAY_ONLY, IO_CAPS_NONE + ble.onDisconnection(disconnectionCallback); + + /* Setup primary service. */ + HIDService hidService(ble); + /* Setup auxiliary service. */ + DeviceInformationService deviceInfo(ble, "ARM", "CYNTEC", "SN1", "hw-rev1", "fw-rev1", "soft-rev1"); + /* Setup advertising. */ + ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); + ble.accumulateAdvertisingPayload(GapAdvertisingData::KEYBOARD); + ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); + ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list)); + ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); + ble.setAdvertisingInterval(1000); + + RFSWIO = 1; + ble.startAdvertising(); + uart.printf("Starting advertising\r\n"); + wait(5); + flipper.attach(&flip, 0.15); + + while (1) { + if(ble.getGapState().connected){ + if(!btn01){ + hidService.updateReport(0x04, 0x2B);//0x04 ALT(LEFT) 0x2B Keyboard TAB + wait(0.03); + hidService.updateReport(0x04, 0x00);//0x04 ALT(LEFT) 0x2B + wait(0.5); + } + if(!btn02){ + hidService.updateReport(0x00, 0x28);//0x28 Keyboard RETURN(Enter) + wait(0.03); + hidService.updateReport(0x00, 0x00); + wait(0.5); + } + if(!btn03){ + hidService.updateReport(0x08, 0x07);//0x08 Left GUI 0x07 Keyboard d + wait(0.03); + hidService.updateReport(0x00, 0x00); + wait(0.5); + } + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Tue Sep 15 02:53:19 2015 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/ba1f97679dad \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nRF51822.lib Tue Sep 15 02:53:19 2015 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/teams/Nordic-Semiconductor/code/nRF51822/#ca9c9c2cfc6a