Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of BLE_HeartRate_DELTA by
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 "HeartRateSecService.h" 00020 #include "ble/services/BatteryService.h" 00021 #include "ble/services/DeviceInformationService.h" 00022 00023 BLE ble; 00024 DigitalOut led1(LED1); 00025 Serial uart(USBTX, USBRX, 115200); 00026 00027 const static char DEVICE_NAME[] = "DELTA_HRM_SEC"; 00028 static const uint16_t uuid16_list[] = {GattService::UUID_HEART_RATE_SERVICE, 00029 GattService::UUID_DEVICE_INFORMATION_SERVICE}; 00030 static volatile bool triggerSensorPolling = false; 00031 bool isSecuritySuccess = false; 00032 00033 uint8_t hrmCounter = 100; // init HRM to 100bps 00034 00035 HeartRateSecService *hrSecService; 00036 DeviceInformationService *deviceInfo; 00037 00038 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params) 00039 { 00040 ble.gap().startAdvertising(); // restart advertising 00041 } 00042 00043 void periodicCallback(void) 00044 { 00045 led1 = !led1; /* Do blinky on LED1 while we're waiting for BLE events */ 00046 00047 /* Note that the periodicCallback() executes in interrupt context, so it is safer to do 00048 * heavy-weight sensor polling from the main thread. */ 00049 triggerSensorPolling = true; 00050 } 00051 00052 void passkeyDisplayCallback(Gap::Handle_t handle, const SecurityManager::Passkey_t passkey) 00053 { 00054 uart.printf("Input passKey: "); 00055 for (unsigned i = 0; i < Gap::ADDR_LEN; i++) { 00056 uart.printf("%c ", passkey[i]); 00057 } 00058 uart.printf("\r\n"); 00059 } 00060 00061 void securitySetupCompletedCallback(Gap::Handle_t handle, SecurityManager::SecurityCompletionStatus_t status) 00062 { 00063 if (status == SecurityManager::SEC_STATUS_SUCCESS) { 00064 uart.printf("Security success\r\n"); 00065 isSecuritySuccess = true; 00066 } else { 00067 uart.printf("Security failed\r\n"); 00068 isSecuritySuccess = false; 00069 ble.gap().disconnect(Gap::LOCAL_HOST_TERMINATED_CONNECTION); 00070 } 00071 } 00072 00073 void bleInitComplete(BLE::InitializationCompleteCallbackContext *params) 00074 { 00075 BLE &ble = params->ble; 00076 ble_error_t error = params->error; 00077 00078 if (error != BLE_ERROR_NONE) { 00079 return; 00080 } 00081 00082 /* Initialize BLE security */ 00083 bool enableBonding = true; 00084 bool requireMITM = true; //Need passkey 00085 uint8_t pKey[6] = {'0', '0', '0', '0', '0', '0'}; //set the passkey 00086 ble.securityManager().init(enableBonding, requireMITM, SecurityManager::IO_CAPS_DISPLAY_ONLY, pKey); 00087 00088 ble.gap().onDisconnection(disconnectionCallback); 00089 ble.securityManager().onPasskeyDisplay(passkeyDisplayCallback); 00090 ble.securityManager().onSecuritySetupCompleted(securitySetupCompletedCallback); 00091 00092 /* Setup primary service. */ 00093 hrSecService = new HeartRateSecService(ble, hrmCounter, HeartRateSecService::LOCATION_FINGER ); 00094 00095 /* Setup auxiliary service. */ 00096 deviceInfo = new DeviceInformationService(ble, "DELTA", "NQ620", "SN1", "hw-rev1", "fw-rev1", "soft-rev1"); 00097 00098 /* Setup advertising. */ 00099 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); 00100 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list)); 00101 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_HEART_RATE_SENSOR); 00102 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); 00103 ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); 00104 ble.gap().setAdvertisingInterval(1000); /* 1000ms */ 00105 ble.gap().startAdvertising(); 00106 } 00107 00108 int main(void) 00109 { 00110 led1 = 1; 00111 Ticker ticker; 00112 ticker.attach(periodicCallback, 1); // blink LED every second 00113 00114 ble.init(bleInitComplete); 00115 00116 /* SpinWait for initialization to complete. This is necessary because the 00117 * BLE object is used in the main loop below. */ 00118 while (ble.hasInitialized() == false) { /* spin loop */ } 00119 00120 ble.setTxPower(0); 00121 00122 // infinite loop 00123 while (1) { 00124 // check for trigger from periodicCallback() 00125 if (triggerSensorPolling && ble.getGapState().connected && isSecuritySuccess) { 00126 triggerSensorPolling = false; 00127 00128 // Do blocking calls or whatever is necessary for sensor polling. 00129 // In our case, we simply update the HRM measurement. 00130 hrmCounter++; 00131 if (hrmCounter == 175) { // 100 <= HRM bps <=175 00132 hrmCounter = 100; 00133 } 00134 00135 hrSecService->updateHeartRate(hrmCounter); 00136 } else { 00137 ble.waitForEvent(); // low power wait for event 00138 } 00139 } 00140 }
Generated on Wed Jul 13 2022 06:43:56 by
1.7.2
