Holla back
Fork of BLE_API by
Embed:
(wiki syntax)
Show/hide line numbers
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 UART service to receive updates to the 00096 * txCharacteristic. The application should forward the call to this 00097 * function from the global onDataWritten() callback handler; or if that's 00098 * not used, this method can be used as a callback directly. 00099 */ 00100 virtual void onDataWritten(const GattCharacteristicWriteCBParams *params) { 00101 if (params->charHandle == controlPoint.getValueAttribute().getHandle()) { 00102 /* Do something here if the new value is 1; else you can override this method by 00103 * extending this class. 00104 * @NOTE: if you are extending this class, be sure to also call 00105 * ble.onDataWritten(this, &ExtendedHRService::onDataWritten); in 00106 * your constructor. 00107 */ 00108 } 00109 } 00110 00111 private: 00112 void setupService(void) { 00113 static bool serviceAdded = false; /* We should only ever need to add the heart rate service once. */ 00114 if (serviceAdded) { 00115 return; 00116 } 00117 00118 GattCharacteristic *charTable[] = {&hrmRate, &hrmLocation, &controlPoint}; 00119 GattService hrmService(GattService::UUID_HEART_RATE_SERVICE, charTable, sizeof(charTable) / sizeof(GattCharacteristic *)); 00120 00121 ble.addService(hrmService); 00122 serviceAdded = true; 00123 00124 ble.onDataWritten(this, &HeartRateService::onDataWritten); 00125 } 00126 00127 private: 00128 /* Private internal representation for the bytes used to work with the vaulue of the heart-rate characteristic. */ 00129 struct HeartRateValueBytes { 00130 static const unsigned MAX_VALUE_BYTES = 3; /* FLAGS + up to two bytes for heart-rate */ 00131 static const unsigned FLAGS_BYTE_INDEX = 0; 00132 00133 static const unsigned VALUE_FORMAT_BITNUM = 0; 00134 static const uint8_t VALUE_FORMAT_FLAG = (1 << VALUE_FORMAT_BITNUM); 00135 00136 HeartRateValueBytes(uint8_t hrmCounter) : valueBytes() { 00137 updateHeartRate(hrmCounter); 00138 } 00139 00140 HeartRateValueBytes(uint16_t hrmCounter) : valueBytes() { 00141 updateHeartRate(hrmCounter); 00142 } 00143 00144 void updateHeartRate(uint8_t hrmCounter) { 00145 valueBytes[FLAGS_BYTE_INDEX] &= ~VALUE_FORMAT_FLAG; 00146 valueBytes[FLAGS_BYTE_INDEX + 1] = hrmCounter; 00147 } 00148 00149 void updateHeartRate(uint16_t hrmCounter) { 00150 valueBytes[FLAGS_BYTE_INDEX] |= VALUE_FORMAT_FLAG; 00151 valueBytes[FLAGS_BYTE_INDEX + 1] = (uint8_t)(hrmCounter & 0xFF); 00152 valueBytes[FLAGS_BYTE_INDEX + 2] = (uint8_t)(hrmCounter >> 8); 00153 } 00154 00155 uint8_t *getPointer(void) { 00156 return valueBytes; 00157 } 00158 00159 const uint8_t *getPointer(void) const { 00160 return valueBytes; 00161 } 00162 00163 unsigned getNumValueBytes(void) const { 00164 return 1 + ((valueBytes[FLAGS_BYTE_INDEX] & VALUE_FORMAT_FLAG) ? sizeof(uint16_t) : sizeof(uint8_t)); 00165 } 00166 00167 private: 00168 /* First byte = 8-bit values, no extra info, Second byte = uint8_t HRM value */ 00169 /* See --> https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.heart_rate_measurement.xml */ 00170 uint8_t valueBytes[MAX_VALUE_BYTES]; 00171 }; 00172 00173 private: 00174 BLEDevice &ble; 00175 HeartRateValueBytes valueBytes; 00176 uint8_t controlPointValue; 00177 GattCharacteristic hrmRate; 00178 GattCharacteristic hrmLocation; 00179 GattCharacteristic controlPoint; 00180 }; 00181 00182 #endif /* #ifndef __BLE_HEART_RATE_SERVICE_H__*/
Generated on Tue Jul 12 2022 14:23:51 by 1.7.2