Mistake on this page?
Report an issue in GitHub or email us
HeartRateService.h
1 /* mbed Microcontroller Library
2  * Copyright (c) 2006-2013 ARM Limited
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef MBED_BLE_HEART_RATE_SERVICE_H__
18 #define MBED_BLE_HEART_RATE_SERVICE_H__
19 
20 #include "ble/BLE.h"
21 
22 #if BLE_FEATURE_GATT_SERVER
23 
24 /**
25  * BLE Heart Rate Service.
26  *
27  * @par purpose
28  *
29  * Fitness applications use the heart rate service to expose the heart
30  * beat per minute measured by a heart rate sensor.
31  *
32  * Clients can read the intended location of the sensor and the last heart rate
33  * value measured. Additionally, clients can subscribe to server initiated
34  * updates of the heart rate value measured by the sensor. The service delivers
35  * these updates to the subscribed client in a notification packet.
36  *
37  * The subscription mechanism is useful to save power; it avoids unecessary data
38  * traffic between the client and the server, which may be induced by polling the
39  * value of the heart rate measurement characteristic.
40  *
41  * @par usage
42  *
43  * When this class is instantiated, it adds a heart rate service in the GattServer.
44  * The service contains the location of the sensor and the initial value measured
45  * by the sensor.
46  *
47  * Application code can invoke updateHeartRate() when a new heart rate measurement
48  * is acquired; this function updates the value of the heart rate measurement
49  * characteristic and notifies the new value to subscribed clients.
50  *
51  * @note You can find specification of the heart rate service here:
52  * https://www.bluetooth.com/specifications/gatt
53  *
54  * @attention The service does not expose information related to the sensor
55  * contact, the accumulated energy expanded or the interbeat intervals.
56  *
57  * @attention The heart rate profile limits the number of instantiations of the
58  * heart rate services to one.
59  */
61 public:
62  /**
63  * Intended location of the heart rate sensor.
64  */
66  /**
67  * Other location.
68  */
70 
71  /**
72  * Chest.
73  */
75 
76  /**
77  * Wrist.
78  */
80 
81  /**
82  * Finger.
83  */
85 
86  /**
87  * Hand.
88  */
90 
91  /**
92  * Earlobe.
93  */
95 
96  /**
97  * Foot.
98  */
100  };
101 
102 public:
103  /**
104  * Construct and initialize a heart rate service.
105  *
106  * The construction process adds a GATT heart rate service in @p _ble
107  * GattServer, sets the value of the heart rate measurement characteristic
108  * to @p hrmCounter and the value of the body sensor location characteristic
109  * to @p location.
110  *
111  * @param[in] _ble BLE device that hosts the heart rate service.
112  * @param[in] hrmCounter Heart beats per minute measured by the heart rate
113  * sensor.
114  * @param[in] location Intended location of the heart rate sensor.
115  */
116  HeartRateService(BLE &_ble, uint16_t hrmCounter, BodySensorLocation location) :
117  ble(_ble),
118  valueBytes(hrmCounter),
119  hrmRate(
120  GattCharacteristic::UUID_HEART_RATE_MEASUREMENT_CHAR,
121  valueBytes.getPointer(),
122  valueBytes.getNumValueBytes(),
123  HeartRateValueBytes::MAX_VALUE_BYTES,
124  GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY
125  ),
126  hrmLocation(
127  GattCharacteristic::UUID_BODY_SENSOR_LOCATION_CHAR,
128  reinterpret_cast<uint8_t*>(&location)
129  )
130  {
131  setupService();
132  }
133 
134  /**
135  * Update the heart rate that the service exposes.
136  *
137  * The server sends a notification of the new value to clients that have
138  * subscribed to updates of the heart rate measurement characteristic; clients
139  * reading the heart rate measurement characteristic after the update obtain
140  * the updated value.
141  *
142  * @param[in] hrmCounter Heart rate measured in BPM.
143  *
144  * @attention This function must be called in the execution context of the
145  * BLE stack.
146  */
147  void updateHeartRate(uint16_t hrmCounter) {
148  valueBytes.updateHeartRate(hrmCounter);
149  ble.gattServer().write(
150  hrmRate.getValueHandle(),
151  valueBytes.getPointer(),
152  valueBytes.getNumValueBytes()
153  );
154  }
155 
156 protected:
157  /**
158  * Construct and add to the GattServer the heart rate service.
159  */
160  void setupService(void) {
161  GattCharacteristic *charTable[] = {
162  &hrmRate,
163  &hrmLocation
164  };
165  GattService hrmService(
167  charTable,
168  sizeof(charTable) / sizeof(GattCharacteristic*)
169  );
170 
171  ble.gattServer().addService(hrmService);
172  }
173 
174 protected:
175  /*
176  * Heart rate measurement value.
177  */
179  /* 1 byte for the Flags, and up to two bytes for heart rate value. */
180  static const unsigned MAX_VALUE_BYTES = 3;
181  static const unsigned FLAGS_BYTE_INDEX = 0;
182 
183  static const unsigned VALUE_FORMAT_BITNUM = 0;
184  static const uint8_t VALUE_FORMAT_FLAG = (1 << VALUE_FORMAT_BITNUM);
185 
186  HeartRateValueBytes(uint16_t hrmCounter) : valueBytes()
187  {
188  updateHeartRate(hrmCounter);
189  }
190 
191  void updateHeartRate(uint16_t hrmCounter)
192  {
193  if (hrmCounter <= 255) {
194  valueBytes[FLAGS_BYTE_INDEX] &= ~VALUE_FORMAT_FLAG;
195  valueBytes[FLAGS_BYTE_INDEX + 1] = hrmCounter;
196  } else {
197  valueBytes[FLAGS_BYTE_INDEX] |= VALUE_FORMAT_FLAG;
198  valueBytes[FLAGS_BYTE_INDEX + 1] = (uint8_t)(hrmCounter & 0xFF);
199  valueBytes[FLAGS_BYTE_INDEX + 2] = (uint8_t)(hrmCounter >> 8);
200  }
201  }
202 
203  uint8_t *getPointer(void)
204  {
205  return valueBytes;
206  }
207 
208  const uint8_t *getPointer(void) const
209  {
210  return valueBytes;
211  }
212 
213  unsigned getNumValueBytes(void) const
214  {
215  if (valueBytes[FLAGS_BYTE_INDEX] & VALUE_FORMAT_FLAG) {
216  return 1 + sizeof(uint16_t);
217  } else {
218  return 1 + sizeof(uint8_t);
219  }
220  }
221 
222  private:
223  uint8_t valueBytes[MAX_VALUE_BYTES];
224  };
225 
226 protected:
227  BLE &ble;
228  HeartRateValueBytes valueBytes;
229  GattCharacteristic hrmRate;
231 };
232 
233 #endif // BLE_FEATURE_GATT_SERVER
234 
235 #endif /* #ifndef MBED_BLE_HEART_RATE_SERVICE_H__*/
BodySensorLocation
Intended location of the heart rate sensor.
BLE Heart Rate Service.
Abstract away BLE-capable radio transceivers or SOCs.
Definition: BLE.h:139
HeartRateService(BLE &_ble, uint16_t hrmCounter, BodySensorLocation location)
Construct and initialize a heart rate service.
Representation of a GattServer characteristic.
UUID of the Heart Rate service.
Definition: GattService.h:89
GattAttribute::Handle_t getValueHandle(void) const
Get the characteristic&#39;s value attribute handle in the ATT table.
void setupService(void)
Construct and add to the GattServer the heart rate service.
Representation of a GattServer service.
Definition: GattService.h:38
Entry namespace for all BLE API definitions.
void updateHeartRate(uint16_t hrmCounter)
Update the heart rate that the service exposes.
Important Information for this Arm website

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies. If you are not happy with the use of these cookies, please review our Cookie Policy to learn how they can be disabled. By disabling cookies, some features of the site will not work.