Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers HeartRateService.h Source File

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__*/