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.
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 __BLE_HEART_RATE_SERVICE_H__ 00018 #define __BLE_HEART_RATE_SERVICE_H__ 00019 00020 #include "BLEDevice.h" 00021 00022 /* Heart Rate Service */ 00023 /* Service: https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.heart_rate.xml */ 00024 /* HRM Char: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.heart_rate_measurement.xml */ 00025 /* Location: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.body_sensor_location.xml */ 00026 class HeartRateService { 00027 public: 00028 enum { 00029 LOCATION_OTHER = 0, 00030 LOCATION_CHEST, 00031 LOCATION_WRIST, 00032 LOCATION_FINGER, 00033 LOCATION_HAND, 00034 LOCATION_EAR_LOBE, 00035 LOCATION_FOOT, 00036 }; 00037 00038 public: 00039 /** 00040 * Constructor. 00041 * 00042 * param[in] _ble 00043 * Reference to the underlying BLEDevice. 00044 * param[in] hrmCounter (8-bit) 00045 * initial value for the hrm counter. 00046 * param[in] location 00047 * Sensor's location. 00048 */ 00049 HeartRateService(BLEDevice &_ble, uint8_t hrmCounter, uint8_t location) : 00050 ble(_ble), 00051 valueBytes(hrmCounter), 00052 hrmRate(GattCharacteristic::UUID_HEART_RATE_MEASUREMENT_CHAR, valueBytes.getPointer(), 00053 valueBytes.getNumValueBytes(), HeartRateValueBytes::MAX_VALUE_BYTES, 00054 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY), 00055 hrmLocation(GattCharacteristic::UUID_BODY_SENSOR_LOCATION_CHAR, (uint8_t *)&location, sizeof(location), sizeof(location), 00056 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ), 00057 controlPoint(GattCharacteristic::UUID_HEART_RATE_CONTROL_POINT_CHAR, (uint8_t *)&controlPointValue, 00058 sizeof(controlPointValue), sizeof(controlPointValue), GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE) { 00059 setupService(); 00060 } 00061 00062 /** 00063 * Same constructor as above, but with a 16-bit HRM Counter value. 00064 */ 00065 HeartRateService(BLEDevice &_ble, uint16_t hrmCounter, uint8_t location) : 00066 ble(_ble), 00067 valueBytes(hrmCounter), 00068 hrmRate(GattCharacteristic::UUID_HEART_RATE_MEASUREMENT_CHAR, valueBytes.getPointer(), 00069 valueBytes.getNumValueBytes(), HeartRateValueBytes::MAX_VALUE_BYTES, 00070 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY), 00071 hrmLocation(GattCharacteristic::UUID_BODY_SENSOR_LOCATION_CHAR, (uint8_t *)&location, sizeof(location), sizeof(location), 00072 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ), 00073 controlPoint(GattCharacteristic::UUID_HEART_RATE_CONTROL_POINT_CHAR, (uint8_t *)&controlPointValue, 00074 sizeof(controlPointValue), sizeof(controlPointValue), GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE) { 00075 setupService(); 00076 } 00077 00078 /** 00079 * Set a new 8-bit value for heart rate. 00080 */ 00081 void updateHeartRate(uint8_t hrmCounter) { 00082 valueBytes.updateHeartRate(hrmCounter); 00083 ble.updateCharacteristicValue (hrmRate.getValueAttribute().getHandle(), valueBytes.getPointer(), valueBytes.getNumValueBytes()); 00084 } 00085 00086 /** 00087 * Set a new 16-bit value for heart rate. 00088 */ 00089 void updateHeartRate(uint16_t hrmCounter) { 00090 valueBytes.updateHeartRate(hrmCounter); 00091 ble.updateCharacteristicValue (hrmRate.getValueAttribute().getHandle(), valueBytes.getPointer(), valueBytes.getNumValueBytes()); 00092 } 00093 00094 /** 00095 * This callback allows the HeartRateService to receive updates to the 00096 * controlPoint Characteristic. 00097 */ 00098 virtual void onDataWritten(const GattCharacteristicWriteCBParams *params) { 00099 if (params->charHandle == controlPoint.getValueAttribute().getHandle()) { 00100 /* Do something here if the new value is 1; else you can override this method by 00101 * extending this class. 00102 * @NOTE: if you are extending this class, be sure to also call 00103 * ble.onDataWritten(this, &ExtendedHRService::onDataWritten); in 00104 * your constructor. 00105 */ 00106 } 00107 } 00108 00109 private: 00110 void setupService(void) { 00111 static bool serviceAdded = false; /* We should only ever need to add the heart rate service once. */ 00112 if (serviceAdded) { 00113 return; 00114 } 00115 00116 GattCharacteristic *charTable[] = {&hrmRate, &hrmLocation, &controlPoint}; 00117 GattService hrmService(GattService::UUID_HEART_RATE_SERVICE, charTable, sizeof(charTable) / sizeof(GattCharacteristic *)); 00118 00119 ble.addService(hrmService); 00120 serviceAdded = true; 00121 00122 ble.onDataWritten(this, &HeartRateService::onDataWritten); 00123 } 00124 00125 private: 00126 /* Private internal representation for the bytes used to work with the vaulue of the heart-rate characteristic. */ 00127 struct HeartRateValueBytes { 00128 static const unsigned MAX_VALUE_BYTES = 3; /* FLAGS + up to two bytes for heart-rate */ 00129 static const unsigned FLAGS_BYTE_INDEX = 0; 00130 00131 static const unsigned VALUE_FORMAT_BITNUM = 0; 00132 static const uint8_t VALUE_FORMAT_FLAG = (1 << VALUE_FORMAT_BITNUM); 00133 00134 HeartRateValueBytes(uint8_t hrmCounter) : valueBytes() { 00135 updateHeartRate(hrmCounter); 00136 } 00137 00138 HeartRateValueBytes(uint16_t hrmCounter) : valueBytes() { 00139 updateHeartRate(hrmCounter); 00140 } 00141 00142 void updateHeartRate(uint8_t hrmCounter) { 00143 valueBytes[FLAGS_BYTE_INDEX] &= ~VALUE_FORMAT_FLAG; 00144 valueBytes[FLAGS_BYTE_INDEX + 1] = hrmCounter; 00145 } 00146 00147 void updateHeartRate(uint16_t hrmCounter) { 00148 valueBytes[FLAGS_BYTE_INDEX] |= VALUE_FORMAT_FLAG; 00149 valueBytes[FLAGS_BYTE_INDEX + 1] = (uint8_t)(hrmCounter & 0xFF); 00150 valueBytes[FLAGS_BYTE_INDEX + 2] = (uint8_t)(hrmCounter >> 8); 00151 } 00152 00153 uint8_t *getPointer(void) { 00154 return valueBytes; 00155 } 00156 00157 const uint8_t *getPointer(void) const { 00158 return valueBytes; 00159 } 00160 00161 unsigned getNumValueBytes(void) const { 00162 return 1 + ((valueBytes[FLAGS_BYTE_INDEX] & VALUE_FORMAT_FLAG) ? sizeof(uint16_t) : sizeof(uint8_t)); 00163 } 00164 00165 private: 00166 /* First byte = 8-bit values, no extra info, Second byte = uint8_t HRM value */ 00167 /* See --> https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.heart_rate_measurement.xml */ 00168 uint8_t valueBytes[MAX_VALUE_BYTES]; 00169 }; 00170 00171 private: 00172 BLEDevice &ble; 00173 HeartRateValueBytes valueBytes; 00174 uint8_t controlPointValue; 00175 GattCharacteristic hrmRate; 00176 GattCharacteristic hrmLocation; 00177 GattCharacteristic controlPoint; 00178 }; 00179 00180 #endif /* #ifndef __BLE_HEART_RATE_SERVICE_H__*/
Generated on Tue Jul 12 2022 20:04:42 by
