Example for BLE HID scanner

Fork of BLE_HIDScanner_DELTA by Silvia Chen

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /* mbed Microcontroller Library
00002  * Copyright (c) 2006-2015 ARM Limited
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 #include "mbed.h"
00018 #include "ble/BLE.h"
00019 #include "ble/services/BatteryService.h"
00020 #include "ble/services/DeviceInformationService.h"
00021 #include "HIDService.h"
00022 #include "ble/services/UARTService.h"
00023 
00024 #define KEY_BUF_SIZE 50  //Buffer used to store keys to send (store up to 25 characters)
00025 
00026 //DigitalOut led1(LED1);
00027 Serial uart(USBTX, USBRX);
00028 InterruptIn testHID_btn(BUTTON1);
00029 
00030 HIDService *hidService;
00031 unsigned char keyData;
00032 const static char     DEVICE_NAME[]        = "HID_Keyboard";
00033 static const uint16_t uuid16_list[]        = {GattService::UUID_HUMAN_INTERFACE_DEVICE_SERVICE,
00034                                               GattService::UUID_BATTERY_SERVICE,
00035                                               GattService::UUID_DEVICE_INFORMATION_SERVICE};
00036 static volatile bool  triggerSensorPolling = false;
00037 bool isConnectionSecured = false;
00038 bool isSecuritySetup = false;
00039 unsigned char serial_buf[20];
00040 uint16_t serialLen = 0;
00041 static uint8_t key_press_scan_buff[KEY_BUF_SIZE];
00042 static uint8_t modifyKey[KEY_BUF_SIZE];
00043 int index_b = 0;
00044 
00045 DeviceInformationService *deviceInfo;
00046 BatteryService *batteryService;
00047 static UARTService *uartServicePtr;
00048 
00049 void passkeyDisplayCallback(Gap::Handle_t handle, const SecurityManager::Passkey_t passkey)
00050 {
00051     uart.printf("Input passKey: ");
00052     for (unsigned i = 0; i < Gap::ADDR_LEN; i++) {
00053         uart.printf("%c ", passkey[i]);
00054     }
00055     uart.printf("\r\n");
00056 }
00057 
00058 void securitySetupInitiatedCallback(Gap::Handle_t, bool allowBonding, bool requireMITM, SecurityManager::SecurityIOCapabilities_t iocaps)
00059 {
00060     uart.printf("securitySetupInitiatedCallback\r\n");
00061     isSecuritySetup = true;
00062 }
00063  
00064 void securitySetupCompletedCallback(Gap::Handle_t handle, SecurityManager::SecurityCompletionStatus_t status)
00065 {
00066     if (status == SecurityManager::SEC_STATUS_SUCCESS) {
00067         uart.printf("Security success\r\n", status);
00068         isConnectionSecured = true;
00069     } else {
00070         uart.printf("Security failed\r\n", status);
00071     }
00072 }
00073 
00074 void linkSecuredCallback(Gap::Handle_t handle, SecurityManager::SecurityMode_t securityMode)
00075 {
00076     uart.printf("linkSecuredCallback\r\n");
00077     if (!isSecuritySetup) {
00078         isConnectionSecured = true;
00079     }
00080 }
00081 
00082 void securityContextStoredCallback(Gap::Handle_t handle) {
00083     uart.printf("securityContextStoredCallback\r\n");
00084     isConnectionSecured = true;
00085     isSecuritySetup = false;
00086 }
00087 
00088 void onConnectionCallback(const Gap::ConnectionCallbackParams_t *params)
00089 {
00090     uart.printf("Connected\r\n");
00091 }
00092 
00093 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
00094 {
00095     uart.printf("Disconnected\r\n");
00096     isConnectionSecured = false;
00097     BLE::Instance(BLE::DEFAULT_INSTANCE).gap().startAdvertising(); // restart advertising
00098 }
00099 
00100 void onTimeoutCallback(Gap::TimeoutSource_t source)
00101 {
00102     switch (source) {
00103         case Gap::TIMEOUT_SRC_ADVERTISING:
00104             uart.printf("Advertising timeout\r\n");
00105             break;  
00106         case Gap::TIMEOUT_SRC_SECURITY_REQUEST:
00107             uart.printf("Security request timeout\r\n");
00108             break;
00109         case Gap::TIMEOUT_SRC_SCAN:
00110             uart.printf("Scanning timeout\r\n");
00111             break;
00112         case Gap::TIMEOUT_SRC_CONN:
00113             uart.printf("Connection timeout\r\n");
00114             break;
00115     }
00116 }
00117 
00118 void serverDataWrittenCallback(const GattWriteCallbackParams *response) {
00119     uart.printf("serverDataWrittenCallback\r\n");
00120     if (response->handle == uartServicePtr->getTXCharacteristicHandle()) {
00121         serialLen = response->len;
00122         for(int j=0;j<response->len;j++) {
00123             //uart.printf("data: %02X\r\n", response->data[j]);
00124             serial_buf[j] = response->data[j];
00125         }
00126     }
00127 }
00128 
00129 void periodicCallback(void)
00130 {
00131     //led1 = !led1; /* Do blinky on LED1 while we're waiting for BLE events */
00132 
00133     /* Note that the periodicCallback() executes in interrupt context, so it is safer to do
00134      * heavy-weight sensor polling from the main thread. */
00135     //triggerSensorPolling = true;
00136 }
00137 
00138 void testHIDRiseInterrupt() {
00139     triggerSensorPolling = true; 
00140 }
00141 
00142 void transferReportData(unsigned char keyData) {
00143     if(keyData <= 0x39 && keyData >= 0x30){             //number
00144         if(keyData == 0x30){
00145             modifyKey[index_b] = 0x00;
00146             key_press_scan_buff[index_b] = 0x27;
00147             index_b++;
00148             key_press_scan_buff[index_b] = 0x73;
00149         } else {
00150             modifyKey[index_b] = 0x00;
00151             key_press_scan_buff[index_b] = keyData-0x13;
00152             index_b++;
00153             key_press_scan_buff[index_b] = 0x73;
00154             }
00155     } else if(keyData <= 0x7a && keyData >= 0x61 ){ //lowercase letters
00156         modifyKey[index_b] = 0x00;
00157         key_press_scan_buff[index_b] = keyData-0x5d;
00158         index_b++;
00159         key_press_scan_buff[index_b] = 0x73;
00160     } else if(keyData <= 0x5a && keyData >= 0x41){  //uppercase letters
00161         modifyKey[index_b] = 0x02;
00162         key_press_scan_buff[index_b] = keyData-0x3d;
00163         index_b++;
00164         key_press_scan_buff[index_b] = 0x73;
00165     } else if (keyData == 0x20) {                   //space
00166         modifyKey[index_b] = 0x00;
00167         key_press_scan_buff[index_b] = 0x2c;
00168         index_b++;
00169         key_press_scan_buff[index_b] = 0x73;
00170     } else {
00171         modifyKey[index_b] = 0x00;
00172         //key_press_scan_buff[index_b] = 0x73;          //this is dummy data.
00173         //msg[index_w+1] = '\0';
00174     }
00175     index_b++;
00176 }
00177 
00178 void dataSentCallback(const unsigned callback) {
00179     //uart.printf("dataSentCallback\r\n");
00180 }
00181 
00182 void bleInitComplete(BLE::InitializationCompleteCallbackContext *params)
00183 {
00184     BLE &ble          = params->ble;
00185     ble_error_t error = params->error;
00186 
00187     if (error != BLE_ERROR_NONE) {
00188         return;
00189     }
00190     
00191     bool enableBonding = true;
00192     bool requireMITM   = false;
00193 
00194     //uint8_t pKey[6] = {'1', '1', '1', '1', '1', '1'}; //set the passkey
00195     ble.securityManager().init(enableBonding, requireMITM, SecurityManager::IO_CAPS_NONE);
00196     ble.securityManager().onPasskeyDisplay(passkeyDisplayCallback);
00197     ble.securityManager().onSecuritySetupInitiated(securitySetupInitiatedCallback);
00198     ble.securityManager().onSecuritySetupCompleted(securitySetupCompletedCallback);
00199     ble.securityManager().onLinkSecured(linkSecuredCallback);
00200     ble.securityManager().onSecurityContextStored(securityContextStoredCallback);
00201     ble.gap().onDisconnection(disconnectionCallback);
00202     ble.gap().onConnection(onConnectionCallback);
00203     ble.gap().onTimeout(onTimeoutCallback);
00204     ble.gattServer().onDataWritten(serverDataWrittenCallback);
00205     ble.gattServer().onDataSent(dataSentCallback);
00206 
00207     /* Setup primary service. */
00208     hidService = new HIDService(ble);
00209 
00210     /* Setup auxiliary service. */
00211     uartServicePtr = new UARTService(ble);
00212     batteryService = new BatteryService(ble, 100);
00213     deviceInfo = new DeviceInformationService(ble, "DELTA", "NQ620", "SN1", "hw-rev1", "fw-rev1", "soft-rev1");
00214 
00215     /* Setup advertising. */
00216     ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
00217     ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list));
00218     ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::KEYBOARD);
00219     ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));
00220     ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
00221     ble.gap().setAdvertisingInterval(50); /* 50ms */
00222     ble.gap().startAdvertising();
00223     uart.printf("Start advertising\r\n");
00224 }
00225 
00226 int main(void)
00227 {
00228     //led1 = 1;
00229    // Ticker ticker;
00230 //    ticker.attach(periodicCallback, 0.1); // blink LED every second
00231 
00232     testHID_btn.rise(&testHIDRiseInterrupt);
00233     
00234     uart.baud(115200);
00235     uart.printf("Srarting HID Service\r\n");
00236 
00237     BLE& ble = BLE::Instance(BLE::DEFAULT_INSTANCE);
00238     ble.init(bleInitComplete);
00239 
00240     /* SpinWait for initialization to complete. This is necessary because the
00241      * BLE object is used in the main loop below. */
00242     while (ble.hasInitialized()  == false) { /* spin loop */ }
00243 
00244     // infinite loop
00245     while (1) {
00246         if (isConnectionSecured) {
00247             if (uart.readable() == 1) {
00248                 keyData = uart.getc();
00249                 //uart.printf("keyData: %c\r\n", keyData);
00250                 transferReportData(keyData);
00251                 if(keyData == 0x0a && ble.getGapState().connected){ //detecting LF and check the ble state
00252                     for(int i = 0; i < index_b ; i++){
00253                         hidService->updateReport(modifyKey[i], key_press_scan_buff[i]);
00254                         ble.waitForEvent();
00255                         wait(0.01); //This is necessary
00256                     }
00257             
00258                     index_b = 0;
00259                     memset(modifyKey, 0, KEY_BUF_SIZE);
00260                     memset(key_press_scan_buff, 0, KEY_BUF_SIZE);
00261                 }
00262             } else if(triggerSensorPolling) {
00263                 //Demo HID/Serial at the same time
00264                 triggerSensorPolling = false;
00265                 
00266                 //Write data via RX characteristic
00267                 ble.gattServer().write(uartServicePtr->getRXCharacteristicHandle(), static_cast<const uint8_t *>(serial_buf), serialLen);
00268                 
00269                 /*
00270                 //Write data via HID
00271                 for(int j=0;j<serialLen;j++) {
00272                     keyData = serial_buf[j];
00273                     //uart.printf("keyData: %c\r\n", keyData);
00274                     transferReportData(keyData);
00275                 }
00276                 
00277                 for(int i = 0; i < index_b ; i++){
00278                     //uart.printf("m[%x] k[%x] ", modifyKey[i], key_press_scan_buff[i]);
00279                     hidService->updateReport(modifyKey[i], key_press_scan_buff[i]);
00280                     ble.waitForEvent();
00281                     wait(0.01);
00282                 }
00283             
00284                 index_b = 0;
00285                 memset(modifyKey, 0, KEY_BUF_SIZE);
00286                 memset(key_press_scan_buff, 0, KEY_BUF_SIZE);
00287                 */
00288             } else {
00289                 ble.waitForEvent();
00290             }
00291         } else {
00292             ble.waitForEvent(); // low power wait for event
00293             wait(1);
00294         }
00295         
00296     }
00297 }