BLE HID keyboard with gesture
Dependencies: BLE_API BLE_HID PAJ7620U2 mbed nRF51822
We have full tutorial, please visit our blog
main.cpp
- Committer:
- mtmkimi
- Date:
- 2016-12-30
- Revision:
- 2:6109e375f9a7
- Parent:
- 0:55c7f79a524c
- Child:
- 3:656f8fb89f05
File content as of revision 2:6109e375f9a7:
/* Copyright (c) 2016 MtM Technology Corporation, MIT License * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software * and associated documentation files (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, publish, distribute, * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or * substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "mbed.h" #include "ble/BLE.h" #include "ble/services/BatteryService.h" #include "ble/services/DeviceInformationService.h" #include "PAJ7620U2.h" #include "HIDServiceBase.h" //#include "MouseService.h" //#include "JoystickService.h" #include "KeyboardService.h" /** * IO capabilities of the device. During development, you most likely want "JustWorks", which means * no IO capabilities. * It is also possible to use IO_CAPS_DISPLAY_ONLY to generate and show a pincode on the serial * output. */ #ifndef HID_SECURITY_IOCAPS #define HID_SECURITY_IOCAPS (SecurityManager::IO_CAPS_NONE) #endif /** * Security level. MITM disabled forces "Just Works". If you require MITM, HID_SECURITY_IOCAPS must * be at least IO_CAPS_DISPLAY_ONLY. */ #ifndef HID_SECURITY_REQUIRE_MITM #define HID_SECURITY_REQUIRE_MITM false #endif /* UART printf */ Serial pc(p5, p4); /* Sensor */ PAJ7620U2 gesture(p3, p2, p0); volatile bool gestureHasIntEvent = false; /* HID service */ //MouseService *msService = NULL; //JoystickService *jsService = NULL; KeyboardService *kbService = NULL; /* Device name */ static const char DEVICE_NAME[] = "MtM Gesture"; static const char SHORT_DEVICE_NAME[] = "gHID"; void connectionCallback(const Gap::ConnectionCallbackParams_t *params) { pc.printf("connection\n"); } void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params) { BLE::Instance().gap().startAdvertising(); // restart advertising pc.printf("disconnection\n"); } static void passkeyDisplayCallback(Gap::Handle_t handle, const SecurityManager::Passkey_t passkey) { pc.printf("Input passKey: "); for (unsigned i = 0; i < Gap::ADDR_LEN; i++) { pc.printf("%c", passkey[i]); } pc.printf("\r\n"); } static void securitySetupCompletedCallback(Gap::Handle_t handle, SecurityManager::SecurityCompletionStatus_t status) { if (status == SecurityManager::SEC_STATUS_SUCCESS) { pc.printf("Security success %d\r\n", status); } else { pc.printf("Security failed %d\r\n", status); } } static void securitySetupInitiatedCallback(Gap::Handle_t, bool allowBonding, bool requireMITM, SecurityManager::SecurityIOCapabilities_t iocaps) { pc.printf("Security setup initiated\r\n"); } void initializeSecurity(BLE &ble) { bool enableBonding = true; bool requireMITM = HID_SECURITY_REQUIRE_MITM; ble.securityManager().onSecuritySetupInitiated(securitySetupInitiatedCallback); ble.securityManager().onPasskeyDisplay(passkeyDisplayCallback); ble.securityManager().onSecuritySetupCompleted(securitySetupCompletedCallback); ble.securityManager().init(enableBonding, requireMITM, HID_SECURITY_IOCAPS); } void initializeHOGP(BLE &ble) { static const uint16_t uuid16_list[] = {GattService::UUID_HUMAN_INTERFACE_DEVICE_SERVICE, GattService::UUID_DEVICE_INFORMATION_SERVICE, GattService::UUID_BATTERY_SERVICE}; DeviceInformationService deviceInfo(ble, "ARM", "m1", "abc", "def", "ghi", "jkl"); BatteryService batteryInfo(ble, 80); ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list)); // see 5.1.2: HID over GATT Specification (pg. 25) ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); // 30ms to 50ms is recommended (5.1.2) ble.gap().setAdvertisingInterval(50); } void bleInitComplete(BLE::InitializationCompleteCallbackContext *params) { BLE &ble = params->ble; ble_error_t error = params->error; if (error != BLE_ERROR_NONE) { return; } ble.gap().onConnection(connectionCallback); ble.gap().onDisconnection(disconnectionCallback); /* Setup primary service. */ initializeSecurity(ble); // msService = new MouseService(ble); // jsService = new JoystickService(ble); kbService = new KeyboardService(ble); initializeHOGP(ble); /* Setup advertising. */ ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::KEYBOARD/*MOUSE*/); ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (const uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME, (const uint8_t *)SHORT_DEVICE_NAME, sizeof(SHORT_DEVICE_NAME)); ble.gap().setDeviceName((const uint8_t *)DEVICE_NAME); ble.gap().startAdvertising(); } void gestureIntEventCallback() { pc.printf("gestureIntEventCallback\n"); gestureHasIntEvent = true; } int main(void) { /* Force to disable the hardware flow control of Serial */ *((uint32_t *)(0x40002000+0x56C)) = 0; pc.printf("~ Hell World ~\n"); /* Init BLE */ BLE& ble = BLE::Instance(); ble.init(bleInitComplete); while(ble.hasInitialized() == false) { /* spin loop */ } /* Config sensor */ pc.printf("PID(0x%04X), VID(0x%02X)\n", gesture.PID, gesture.VID); gesture.IntEvent(&gestureIntEventCallback); /* Main loop */ while(1){ /* Process interrupt event */ if(gestureHasIntEvent && ble.getGapState().connected){ gestureHasIntEvent = false; /* Get sensor data */ uint16_t int_flag = gesture.ReadIntFlag(); pc.printf("(0x%04X)\n", int_flag); /* Send HID code */ if(kbService!=NULL && kbService->isConnected()){ switch(int_flag){ case 0x0001: // Up pc.printf("UpArrow\n"); kbService->printf("%c", UP_ARROW); break; case 0x0002: // Down pc.printf("DownArrow\n"); kbService->printf("%c", DOWN_ARROW); break; case 0x0004: // Left pc.printf("LeftArrow\n"); kbService->printf("%c", LEFT_ARROW); break; case 0x0008: // Right pc.printf("RightArrow\n"); kbService->printf("%c", RIGHT_ARROW); break; case 0x0010: // Forward pc.printf("PageDown\n"); kbService->printf("%c", KEY_PAGE_DOWN); break; case 0x0020: // Backword pc.printf("PageUp\n"); kbService->printf("%c", KEY_PAGE_UP); break; case 0x0040: // Clockwise pc.printf("F5\n"); kbService->printf("%c", KEY_F5); break; case 0x0080: // Counter-Clockwise pc.printf("ESC\n"); kbService->printf("%c", 27); break; case 0x0100: // Wave pc.printf("Bye Bye\n"); kbService->printf("Bye Bye\n"); break; }// End of switch } } /* low power wait for event */ // pc.printf("sleep\n"); ble.waitForEvent(); // pc.printf("wakeup\n"); }// End of while }