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