AndroidにキーボードとしてBLEモジュールを認識させて、ショートカットを叩けます。 ショートカットキー btn1:Alt + Tab btn2: Enter

Dependencies:   BLE_API mbed nRF51822

Files at this revision

API Documentation at this revision

Comitter:
leibun
Date:
Tue Sep 15 02:53:19 2015 +0000
Commit message:
First commit.

Changed in this revision

BLE_API.lib Show annotated file Show diff for this revision Revisions of this file
HIDService.cpp Show annotated file Show diff for this revision Revisions of this file
HIDService.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
nRF51822.lib Show annotated file Show diff for this revision Revisions of this file
--- /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