Bluetooth Low Energy / BLE_API

Dependents:   BLE_ANCS_SDAPI BLE_temperature BLE_HeartRate BLE_ANCS_SDAPI_IRC ... more

Committer:
rgrover1
Date:
Fri Jun 19 15:53:28 2015 +0100
Revision:
711:ea0c4bf9ec99
Parent:
710:b2e1a2660ec2
Synchronized with git rev 69726547
Author: Rohit Grover
Release 0.3.9
=============

A minor patch to fix a build error introduced by the previous
release. This has to do with certain declarations being made members
of class UUID.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Rohit Grover 118:620d28e7a1ba 1 /* mbed Microcontroller Library
Rohit Grover 118:620d28e7a1ba 2 * Copyright (c) 2006-2013 ARM Limited
Rohit Grover 118:620d28e7a1ba 3 *
Rohit Grover 118:620d28e7a1ba 4 * Licensed under the Apache License, Version 2.0 (the "License");
Rohit Grover 118:620d28e7a1ba 5 * you may not use this file except in compliance with the License.
Rohit Grover 118:620d28e7a1ba 6 * You may obtain a copy of the License at
Rohit Grover 118:620d28e7a1ba 7 *
Rohit Grover 118:620d28e7a1ba 8 * http://www.apache.org/licenses/LICENSE-2.0
Rohit Grover 118:620d28e7a1ba 9 *
Rohit Grover 118:620d28e7a1ba 10 * Unless required by applicable law or agreed to in writing, software
Rohit Grover 118:620d28e7a1ba 11 * distributed under the License is distributed on an "AS IS" BASIS,
Rohit Grover 118:620d28e7a1ba 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Rohit Grover 118:620d28e7a1ba 13 * See the License for the specific language governing permissions and
Rohit Grover 118:620d28e7a1ba 14 * limitations under the License.
Rohit Grover 118:620d28e7a1ba 15 */
Rohit Grover 118:620d28e7a1ba 16
Rohit Grover 118:620d28e7a1ba 17 #ifndef __BLE_HEART_RATE_SERVICE_H__
Rohit Grover 118:620d28e7a1ba 18 #define __BLE_HEART_RATE_SERVICE_H__
Rohit Grover 118:620d28e7a1ba 19
rgrover1 710:b2e1a2660ec2 20 #include "BLEDevice.h"
Rohit Grover 118:620d28e7a1ba 21
rgrover1 242:0e9201b67e2f 22 /**
mbedAustin 234:aac647674384 23 * @class HeartRateService
rgrover1 242:0e9201b67e2f 24 * @brief BLE Service for HeartRate. This BLE Service contains the location of the sensor, the heartrate in beats per minute. <br>
mbedAustin 234:aac647674384 25 * Service: https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.heart_rate.xml <br>
mbedAustin 234:aac647674384 26 * HRM Char: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.heart_rate_measurement.xml <br>
rgrover1 242:0e9201b67e2f 27 * Location: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.body_sensor_location.xml
mbedAustin 234:aac647674384 28 */
Rohit Grover 118:620d28e7a1ba 29 class HeartRateService {
Rohit Grover 118:620d28e7a1ba 30 public:
mbedAustin 234:aac647674384 31 /**
mbedAustin 234:aac647674384 32 * @enum SensorLocation
rgrover1 242:0e9201b67e2f 33 * @brief Location of HeartRate sensor on body.
mbedAustin 234:aac647674384 34 */
Rohit Grover 118:620d28e7a1ba 35 enum {
mbedAustin 234:aac647674384 36 LOCATION_OTHER = 0, /*!< Other Location */
mbedAustin 234:aac647674384 37 LOCATION_CHEST, /*!< Chest */
mbedAustin 234:aac647674384 38 LOCATION_WRIST, /*!< Wrist */
mbedAustin 234:aac647674384 39 LOCATION_FINGER, /*!< Finger */
mbedAustin 234:aac647674384 40 LOCATION_HAND, /*!< Hand */
mbedAustin 234:aac647674384 41 LOCATION_EAR_LOBE, /*!< Earlobe */
mbedAustin 234:aac647674384 42 LOCATION_FOOT, /*!< Foot */
Rohit Grover 118:620d28e7a1ba 43 };
Rohit Grover 118:620d28e7a1ba 44
Rohit Grover 118:620d28e7a1ba 45 public:
Rohit Grover 118:620d28e7a1ba 46 /**
rgrover1 242:0e9201b67e2f 47 * @brief Constructor with 8bit HRM Counter value.
Rohit Grover 118:620d28e7a1ba 48 *
mbedAustin 234:aac647674384 49 * @param[ref] _ble
rgrover1 710:b2e1a2660ec2 50 * Reference to the underlying BLEDevice.
mbedAustin 234:aac647674384 51 * @param[in] hrmCounter (8-bit)
Rohit Grover 118:620d28e7a1ba 52 * initial value for the hrm counter.
mbedAustin 234:aac647674384 53 * @param[in] location
Rohit Grover 118:620d28e7a1ba 54 * Sensor's location.
Rohit Grover 118:620d28e7a1ba 55 */
rgrover1 710:b2e1a2660ec2 56 HeartRateService(BLEDevice &_ble, uint8_t hrmCounter, uint8_t location) :
Rohit Grover 118:620d28e7a1ba 57 ble(_ble),
Rohit Grover 118:620d28e7a1ba 58 valueBytes(hrmCounter),
Rohit Grover 118:620d28e7a1ba 59 hrmRate(GattCharacteristic::UUID_HEART_RATE_MEASUREMENT_CHAR, valueBytes.getPointer(),
Rohit Grover 118:620d28e7a1ba 60 valueBytes.getNumValueBytes(), HeartRateValueBytes::MAX_VALUE_BYTES,
rgrover1 338:fd32ec0ebd98 61 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY),
rgrover1 277:1407d2f1ce3c 62 hrmLocation(GattCharacteristic::UUID_BODY_SENSOR_LOCATION_CHAR, &location),
rgrover1 277:1407d2f1ce3c 63 controlPoint(GattCharacteristic::UUID_HEART_RATE_CONTROL_POINT_CHAR, &controlPointValue) {
Rohit Grover 118:620d28e7a1ba 64 setupService();
Rohit Grover 118:620d28e7a1ba 65 }
Rohit Grover 118:620d28e7a1ba 66
Rohit Grover 118:620d28e7a1ba 67 /**
rgrover1 242:0e9201b67e2f 68 * @brief Constructor with a 16-bit HRM Counter value.
mbedAustin 234:aac647674384 69 *
mbedAustin 234:aac647674384 70 * @param[in] _ble
rgrover1 710:b2e1a2660ec2 71 * Reference to the underlying BLEDevice.
mbedAustin 234:aac647674384 72 * @param[in] hrmCounter (8-bit)
mbedAustin 234:aac647674384 73 * initial value for the hrm counter.
mbedAustin 234:aac647674384 74 * @param[in] location
mbedAustin 234:aac647674384 75 * Sensor's location.
Rohit Grover 118:620d28e7a1ba 76 */
rgrover1 710:b2e1a2660ec2 77 HeartRateService(BLEDevice &_ble, uint16_t hrmCounter, uint8_t location) :
Rohit Grover 118:620d28e7a1ba 78 ble(_ble),
Rohit Grover 118:620d28e7a1ba 79 valueBytes(hrmCounter),
Rohit Grover 118:620d28e7a1ba 80 hrmRate(GattCharacteristic::UUID_HEART_RATE_MEASUREMENT_CHAR, valueBytes.getPointer(),
Rohit Grover 118:620d28e7a1ba 81 valueBytes.getNumValueBytes(), HeartRateValueBytes::MAX_VALUE_BYTES,
Rohit Grover 118:620d28e7a1ba 82 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY),
rgrover1 277:1407d2f1ce3c 83 hrmLocation(GattCharacteristic::UUID_BODY_SENSOR_LOCATION_CHAR, &location),
rgrover1 277:1407d2f1ce3c 84 controlPoint(GattCharacteristic::UUID_HEART_RATE_CONTROL_POINT_CHAR, &controlPointValue) {
Rohit Grover 118:620d28e7a1ba 85 setupService();
Rohit Grover 118:620d28e7a1ba 86 }
Rohit Grover 118:620d28e7a1ba 87
Rohit Grover 118:620d28e7a1ba 88 /**
rgrover1 242:0e9201b67e2f 89 * @brief Set a new 8-bit value for heart rate.
mbedAustin 234:aac647674384 90 *
mbedAustin 234:aac647674384 91 * @param[in] hrmCounter
rgrover1 242:0e9201b67e2f 92 * HeartRate in bpm.
Rohit Grover 118:620d28e7a1ba 93 */
Rohit Grover 118:620d28e7a1ba 94 void updateHeartRate(uint8_t hrmCounter) {
Rohit Grover 118:620d28e7a1ba 95 valueBytes.updateHeartRate(hrmCounter);
Rohit Grover 118:620d28e7a1ba 96 ble.updateCharacteristicValue(hrmRate.getValueAttribute().getHandle(), valueBytes.getPointer(), valueBytes.getNumValueBytes());
Rohit Grover 118:620d28e7a1ba 97 }
Rohit Grover 118:620d28e7a1ba 98
Rohit Grover 118:620d28e7a1ba 99 /**
Rohit Grover 118:620d28e7a1ba 100 * Set a new 16-bit value for heart rate.
mbedAustin 234:aac647674384 101 *
mbedAustin 234:aac647674384 102 * @param[in] hrmCounter
rgrover1 242:0e9201b67e2f 103 * HeartRate in bpm.
Rohit Grover 118:620d28e7a1ba 104 */
Rohit Grover 118:620d28e7a1ba 105 void updateHeartRate(uint16_t hrmCounter) {
Rohit Grover 118:620d28e7a1ba 106 valueBytes.updateHeartRate(hrmCounter);
Rohit Grover 118:620d28e7a1ba 107 ble.updateCharacteristicValue(hrmRate.getValueAttribute().getHandle(), valueBytes.getPointer(), valueBytes.getNumValueBytes());
Rohit Grover 118:620d28e7a1ba 108 }
Rohit Grover 118:620d28e7a1ba 109
Rohit Grover 118:620d28e7a1ba 110 /**
Rohit Grover 123:fede41ce9407 111 * This callback allows the HeartRateService to receive updates to the
Rohit Grover 123:fede41ce9407 112 * controlPoint Characteristic.
rgrover1 242:0e9201b67e2f 113 *
rgrover1 243:98f930d14515 114 * @param[in] params
rgrover1 243:98f930d14515 115 * Information about the characterisitc being updated.
Rohit Grover 118:620d28e7a1ba 116 */
rgrover1 710:b2e1a2660ec2 117 virtual void onDataWritten(const GattCharacteristicWriteCBParams *params) {
rgrover1 710:b2e1a2660ec2 118 if (params->charHandle == controlPoint.getValueAttribute().getHandle()) {
Rohit Grover 118:620d28e7a1ba 119 /* Do something here if the new value is 1; else you can override this method by
Rohit Grover 118:620d28e7a1ba 120 * extending this class.
Rohit Grover 118:620d28e7a1ba 121 * @NOTE: if you are extending this class, be sure to also call
Rohit Grover 118:620d28e7a1ba 122 * ble.onDataWritten(this, &ExtendedHRService::onDataWritten); in
Rohit Grover 118:620d28e7a1ba 123 * your constructor.
Rohit Grover 118:620d28e7a1ba 124 */
Rohit Grover 118:620d28e7a1ba 125 }
Rohit Grover 118:620d28e7a1ba 126 }
Rohit Grover 118:620d28e7a1ba 127
rgrover1 710:b2e1a2660ec2 128 private:
Rohit Grover 118:620d28e7a1ba 129 void setupService(void) {
rgrover1 710:b2e1a2660ec2 130 static bool serviceAdded = false; /* We should only ever need to add the heart rate service once. */
rgrover1 710:b2e1a2660ec2 131 if (serviceAdded) {
rgrover1 710:b2e1a2660ec2 132 return;
rgrover1 710:b2e1a2660ec2 133 }
rgrover1 710:b2e1a2660ec2 134
Rohit Grover 118:620d28e7a1ba 135 GattCharacteristic *charTable[] = {&hrmRate, &hrmLocation, &controlPoint};
Rohit Grover 118:620d28e7a1ba 136 GattService hrmService(GattService::UUID_HEART_RATE_SERVICE, charTable, sizeof(charTable) / sizeof(GattCharacteristic *));
Rohit Grover 118:620d28e7a1ba 137
Rohit Grover 118:620d28e7a1ba 138 ble.addService(hrmService);
rgrover1 710:b2e1a2660ec2 139 serviceAdded = true;
rgrover1 710:b2e1a2660ec2 140
Rohit Grover 118:620d28e7a1ba 141 ble.onDataWritten(this, &HeartRateService::onDataWritten);
Rohit Grover 118:620d28e7a1ba 142 }
Rohit Grover 118:620d28e7a1ba 143
rgrover1 710:b2e1a2660ec2 144 private:
Rohit Grover 118:620d28e7a1ba 145 /* Private internal representation for the bytes used to work with the vaulue of the heart-rate characteristic. */
Rohit Grover 118:620d28e7a1ba 146 struct HeartRateValueBytes {
Rohit Grover 118:620d28e7a1ba 147 static const unsigned MAX_VALUE_BYTES = 3; /* FLAGS + up to two bytes for heart-rate */
Rohit Grover 118:620d28e7a1ba 148 static const unsigned FLAGS_BYTE_INDEX = 0;
Rohit Grover 118:620d28e7a1ba 149
Rohit Grover 118:620d28e7a1ba 150 static const unsigned VALUE_FORMAT_BITNUM = 0;
Rohit Grover 118:620d28e7a1ba 151 static const uint8_t VALUE_FORMAT_FLAG = (1 << VALUE_FORMAT_BITNUM);
Rohit Grover 118:620d28e7a1ba 152
Rohit Grover 118:620d28e7a1ba 153 HeartRateValueBytes(uint8_t hrmCounter) : valueBytes() {
Rohit Grover 118:620d28e7a1ba 154 updateHeartRate(hrmCounter);
Rohit Grover 118:620d28e7a1ba 155 }
Rohit Grover 118:620d28e7a1ba 156
Rohit Grover 118:620d28e7a1ba 157 HeartRateValueBytes(uint16_t hrmCounter) : valueBytes() {
Rohit Grover 118:620d28e7a1ba 158 updateHeartRate(hrmCounter);
Rohit Grover 118:620d28e7a1ba 159 }
Rohit Grover 118:620d28e7a1ba 160
Rohit Grover 118:620d28e7a1ba 161 void updateHeartRate(uint8_t hrmCounter) {
rgrover1 242:0e9201b67e2f 162 valueBytes[FLAGS_BYTE_INDEX] &= ~VALUE_FORMAT_FLAG;
Rohit Grover 118:620d28e7a1ba 163 valueBytes[FLAGS_BYTE_INDEX + 1] = hrmCounter;
Rohit Grover 118:620d28e7a1ba 164 }
Rohit Grover 118:620d28e7a1ba 165
Rohit Grover 118:620d28e7a1ba 166 void updateHeartRate(uint16_t hrmCounter) {
rgrover1 242:0e9201b67e2f 167 valueBytes[FLAGS_BYTE_INDEX] |= VALUE_FORMAT_FLAG;
Rohit Grover 118:620d28e7a1ba 168 valueBytes[FLAGS_BYTE_INDEX + 1] = (uint8_t)(hrmCounter & 0xFF);
Rohit Grover 118:620d28e7a1ba 169 valueBytes[FLAGS_BYTE_INDEX + 2] = (uint8_t)(hrmCounter >> 8);
Rohit Grover 118:620d28e7a1ba 170 }
Rohit Grover 118:620d28e7a1ba 171
rgrover1 242:0e9201b67e2f 172 uint8_t *getPointer(void) {
Rohit Grover 118:620d28e7a1ba 173 return valueBytes;
Rohit Grover 118:620d28e7a1ba 174 }
Rohit Grover 118:620d28e7a1ba 175
Rohit Grover 118:620d28e7a1ba 176 const uint8_t *getPointer(void) const {
Rohit Grover 118:620d28e7a1ba 177 return valueBytes;
Rohit Grover 118:620d28e7a1ba 178 }
Rohit Grover 118:620d28e7a1ba 179
rgrover1 242:0e9201b67e2f 180 unsigned getNumValueBytes(void) const {
Rohit Grover 118:620d28e7a1ba 181 return 1 + ((valueBytes[FLAGS_BYTE_INDEX] & VALUE_FORMAT_FLAG) ? sizeof(uint16_t) : sizeof(uint8_t));
Rohit Grover 118:620d28e7a1ba 182 }
Rohit Grover 118:620d28e7a1ba 183
rgrover1 710:b2e1a2660ec2 184 private:
Rohit Grover 118:620d28e7a1ba 185 /* First byte = 8-bit values, no extra info, Second byte = uint8_t HRM value */
Rohit Grover 118:620d28e7a1ba 186 /* See --> https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.heart_rate_measurement.xml */
Rohit Grover 118:620d28e7a1ba 187 uint8_t valueBytes[MAX_VALUE_BYTES];
Rohit Grover 118:620d28e7a1ba 188 };
Rohit Grover 118:620d28e7a1ba 189
rgrover1 710:b2e1a2660ec2 190 private:
rgrover1 710:b2e1a2660ec2 191 BLEDevice &ble;
rgrover1 277:1407d2f1ce3c 192
Rohit Grover 118:620d28e7a1ba 193 HeartRateValueBytes valueBytes;
Rohit Grover 118:620d28e7a1ba 194 uint8_t controlPointValue;
rgrover1 277:1407d2f1ce3c 195
rgrover1 277:1407d2f1ce3c 196 GattCharacteristic hrmRate;
rgrover1 277:1407d2f1ce3c 197 ReadOnlyGattCharacteristic<uint8_t> hrmLocation;
rgrover1 277:1407d2f1ce3c 198 WriteOnlyGattCharacteristic<uint8_t> controlPoint;
Rohit Grover 118:620d28e7a1ba 199 };
Rohit Grover 118:620d28e7a1ba 200
rgrover1 242:0e9201b67e2f 201 #endif /* #ifndef __BLE_HEART_RATE_SERVICE_H__*/