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.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
HeartRateService.h
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2006-2013 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 #ifndef MBED_BLE_HEART_RATE_SERVICE_H__ 00018 #define MBED_BLE_HEART_RATE_SERVICE_H__ 00019 00020 #include "ble/BLE.h" 00021 00022 #if BLE_FEATURE_GATT_SERVER 00023 00024 /** 00025 * BLE Heart Rate Service. 00026 * 00027 * @par purpose 00028 * 00029 * Fitness applications use the heart rate service to expose the heart 00030 * beat per minute measured by a heart rate sensor. 00031 * 00032 * Clients can read the intended location of the sensor and the last heart rate 00033 * value measured. Additionally, clients can subscribe to server initiated 00034 * updates of the heart rate value measured by the sensor. The service delivers 00035 * these updates to the subscribed client in a notification packet. 00036 * 00037 * The subscription mechanism is useful to save power; it avoids unecessary data 00038 * traffic between the client and the server, which may be induced by polling the 00039 * value of the heart rate measurement characteristic. 00040 * 00041 * @par usage 00042 * 00043 * When this class is instantiated, it adds a heart rate service in the GattServer. 00044 * The service contains the location of the sensor and the initial value measured 00045 * by the sensor. 00046 * 00047 * Application code can invoke updateHeartRate() when a new heart rate measurement 00048 * is acquired; this function updates the value of the heart rate measurement 00049 * characteristic and notifies the new value to subscribed clients. 00050 * 00051 * @note You can find specification of the heart rate service here: 00052 * https://www.bluetooth.com/specifications/gatt 00053 * 00054 * @attention The service does not expose information related to the sensor 00055 * contact, the accumulated energy expanded or the interbeat intervals. 00056 * 00057 * @attention The heart rate profile limits the number of instantiations of the 00058 * heart rate services to one. 00059 */ 00060 class HeartRateService { 00061 public: 00062 /** 00063 * Intended location of the heart rate sensor. 00064 */ 00065 enum BodySensorLocation { 00066 /** 00067 * Other location. 00068 */ 00069 LOCATION_OTHER = 0, 00070 00071 /** 00072 * Chest. 00073 */ 00074 LOCATION_CHEST = 1, 00075 00076 /** 00077 * Wrist. 00078 */ 00079 LOCATION_WRIST = 2, 00080 00081 /** 00082 * Finger. 00083 */ 00084 LOCATION_FINGER, 00085 00086 /** 00087 * Hand. 00088 */ 00089 LOCATION_HAND, 00090 00091 /** 00092 * Earlobe. 00093 */ 00094 LOCATION_EAR_LOBE, 00095 00096 /** 00097 * Foot. 00098 */ 00099 LOCATION_FOOT, 00100 }; 00101 00102 public: 00103 /** 00104 * Construct and initialize a heart rate service. 00105 * 00106 * The construction process adds a GATT heart rate service in @p _ble 00107 * GattServer, sets the value of the heart rate measurement characteristic 00108 * to @p hrmCounter and the value of the body sensor location characteristic 00109 * to @p location. 00110 * 00111 * @param[in] _ble BLE device that hosts the heart rate service. 00112 * @param[in] hrmCounter Heart beats per minute measured by the heart rate 00113 * sensor. 00114 * @param[in] location Intended location of the heart rate sensor. 00115 */ 00116 HeartRateService(BLE &_ble, uint16_t hrmCounter, BodySensorLocation location) : 00117 ble(_ble), 00118 valueBytes(hrmCounter), 00119 hrmRate( 00120 GattCharacteristic::UUID_HEART_RATE_MEASUREMENT_CHAR, 00121 valueBytes.getPointer(), 00122 valueBytes.getNumValueBytes(), 00123 HeartRateValueBytes::MAX_VALUE_BYTES, 00124 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY 00125 ), 00126 hrmLocation( 00127 GattCharacteristic::UUID_BODY_SENSOR_LOCATION_CHAR, 00128 reinterpret_cast<uint8_t*>(&location) 00129 ) 00130 { 00131 setupService(); 00132 } 00133 00134 /** 00135 * Update the heart rate that the service exposes. 00136 * 00137 * The server sends a notification of the new value to clients that have 00138 * subscribed to updates of the heart rate measurement characteristic; clients 00139 * reading the heart rate measurement characteristic after the update obtain 00140 * the updated value. 00141 * 00142 * @param[in] hrmCounter Heart rate measured in BPM. 00143 * 00144 * @attention This function must be called in the execution context of the 00145 * BLE stack. 00146 */ 00147 void updateHeartRate(uint16_t hrmCounter) { 00148 valueBytes.updateHeartRate(hrmCounter); 00149 ble.gattServer().write( 00150 hrmRate.getValueHandle(), 00151 valueBytes.getPointer(), 00152 valueBytes.getNumValueBytes() 00153 ); 00154 } 00155 00156 protected: 00157 /** 00158 * Construct and add to the GattServer the heart rate service. 00159 */ 00160 void setupService(void) { 00161 GattCharacteristic *charTable[] = { 00162 &hrmRate, 00163 &hrmLocation 00164 }; 00165 GattService hrmService( 00166 GattService::UUID_HEART_RATE_SERVICE, 00167 charTable, 00168 sizeof(charTable) / sizeof(GattCharacteristic*) 00169 ); 00170 00171 ble.gattServer().addService(hrmService); 00172 } 00173 00174 protected: 00175 /* 00176 * Heart rate measurement value. 00177 */ 00178 struct HeartRateValueBytes { 00179 /* 1 byte for the Flags, and up to two bytes for heart rate value. */ 00180 static const unsigned MAX_VALUE_BYTES = 3; 00181 static const unsigned FLAGS_BYTE_INDEX = 0; 00182 00183 static const unsigned VALUE_FORMAT_BITNUM = 0; 00184 static const uint8_t VALUE_FORMAT_FLAG = (1 << VALUE_FORMAT_BITNUM); 00185 00186 HeartRateValueBytes(uint16_t hrmCounter) : valueBytes() 00187 { 00188 updateHeartRate(hrmCounter); 00189 } 00190 00191 void updateHeartRate(uint16_t hrmCounter) 00192 { 00193 if (hrmCounter <= 255) { 00194 valueBytes[FLAGS_BYTE_INDEX] &= ~VALUE_FORMAT_FLAG; 00195 valueBytes[FLAGS_BYTE_INDEX + 1] = hrmCounter; 00196 } else { 00197 valueBytes[FLAGS_BYTE_INDEX] |= VALUE_FORMAT_FLAG; 00198 valueBytes[FLAGS_BYTE_INDEX + 1] = (uint8_t)(hrmCounter & 0xFF); 00199 valueBytes[FLAGS_BYTE_INDEX + 2] = (uint8_t)(hrmCounter >> 8); 00200 } 00201 } 00202 00203 uint8_t *getPointer(void) 00204 { 00205 return valueBytes; 00206 } 00207 00208 const uint8_t *getPointer(void) const 00209 { 00210 return valueBytes; 00211 } 00212 00213 unsigned getNumValueBytes(void) const 00214 { 00215 if (valueBytes[FLAGS_BYTE_INDEX] & VALUE_FORMAT_FLAG) { 00216 return 1 + sizeof(uint16_t); 00217 } else { 00218 return 1 + sizeof(uint8_t); 00219 } 00220 } 00221 00222 private: 00223 uint8_t valueBytes[MAX_VALUE_BYTES]; 00224 }; 00225 00226 protected: 00227 BLE &ble; 00228 HeartRateValueBytes valueBytes; 00229 GattCharacteristic hrmRate; 00230 ReadOnlyGattCharacteristic<uint8_t> hrmLocation; 00231 }; 00232 00233 #endif // BLE_FEATURE_GATT_SERVER 00234 00235 #endif /* #ifndef MBED_BLE_HEART_RATE_SERVICE_H__*/
Generated on Tue Jul 12 2022 13:54:24 by
1.7.2