Rtos API example

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