High level Bluetooth Low Energy API and radio abstraction layer

Dependencies:   nRF51822

Dependents:   LinkNode_LIS3DH

Fork of BLE_API by Bluetooth Low Energy

Committer:
rgrover1
Date:
Fri Jun 19 15:53:01 2015 +0100
Revision:
669:7179b4a5aa7d
Parent:
667:875aecb84719
Child:
670:5e4aecd9af5b
Synchronized with git rev 9bcd7433
Author: Rohit Grover
Rename BLEDevice as BLE. Retain an alias to BLEDevice for the sake of compatibility with old code.

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 567:e4b38e43de7c 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 567:e4b38e43de7c 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 567:e4b38e43de7c 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 567:e4b38e43de7c 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 567:e4b38e43de7c 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 669:7179b4a5aa7d 117 virtual void onDataWritten(const GattCharacteristicWriteCBParams *params) {
rgrover1 567:e4b38e43de7c 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 669:7179b4a5aa7d 128 protected:
Rohit Grover 118:620d28e7a1ba 129 void setupService(void) {
Rohit Grover 118:620d28e7a1ba 130 GattCharacteristic *charTable[] = {&hrmRate, &hrmLocation, &controlPoint};
Rohit Grover 118:620d28e7a1ba 131 GattService hrmService(GattService::UUID_HEART_RATE_SERVICE, charTable, sizeof(charTable) / sizeof(GattCharacteristic *));
Rohit Grover 118:620d28e7a1ba 132
Rohit Grover 118:620d28e7a1ba 133 ble.addService(hrmService);
Rohit Grover 118:620d28e7a1ba 134 ble.onDataWritten(this, &HeartRateService::onDataWritten);
Rohit Grover 118:620d28e7a1ba 135 }
Rohit Grover 118:620d28e7a1ba 136
rgrover1 669:7179b4a5aa7d 137 protected:
Rohit Grover 118:620d28e7a1ba 138 /* Private internal representation for the bytes used to work with the vaulue of the heart-rate characteristic. */
Rohit Grover 118:620d28e7a1ba 139 struct HeartRateValueBytes {
Rohit Grover 118:620d28e7a1ba 140 static const unsigned MAX_VALUE_BYTES = 3; /* FLAGS + up to two bytes for heart-rate */
Rohit Grover 118:620d28e7a1ba 141 static const unsigned FLAGS_BYTE_INDEX = 0;
Rohit Grover 118:620d28e7a1ba 142
Rohit Grover 118:620d28e7a1ba 143 static const unsigned VALUE_FORMAT_BITNUM = 0;
Rohit Grover 118:620d28e7a1ba 144 static const uint8_t VALUE_FORMAT_FLAG = (1 << VALUE_FORMAT_BITNUM);
Rohit Grover 118:620d28e7a1ba 145
Rohit Grover 118:620d28e7a1ba 146 HeartRateValueBytes(uint8_t hrmCounter) : valueBytes() {
Rohit Grover 118:620d28e7a1ba 147 updateHeartRate(hrmCounter);
Rohit Grover 118:620d28e7a1ba 148 }
Rohit Grover 118:620d28e7a1ba 149
Rohit Grover 118:620d28e7a1ba 150 HeartRateValueBytes(uint16_t hrmCounter) : valueBytes() {
Rohit Grover 118:620d28e7a1ba 151 updateHeartRate(hrmCounter);
Rohit Grover 118:620d28e7a1ba 152 }
Rohit Grover 118:620d28e7a1ba 153
Rohit Grover 118:620d28e7a1ba 154 void updateHeartRate(uint8_t hrmCounter) {
rgrover1 242:0e9201b67e2f 155 valueBytes[FLAGS_BYTE_INDEX] &= ~VALUE_FORMAT_FLAG;
Rohit Grover 118:620d28e7a1ba 156 valueBytes[FLAGS_BYTE_INDEX + 1] = hrmCounter;
Rohit Grover 118:620d28e7a1ba 157 }
Rohit Grover 118:620d28e7a1ba 158
Rohit Grover 118:620d28e7a1ba 159 void updateHeartRate(uint16_t hrmCounter) {
rgrover1 242:0e9201b67e2f 160 valueBytes[FLAGS_BYTE_INDEX] |= VALUE_FORMAT_FLAG;
Rohit Grover 118:620d28e7a1ba 161 valueBytes[FLAGS_BYTE_INDEX + 1] = (uint8_t)(hrmCounter & 0xFF);
Rohit Grover 118:620d28e7a1ba 162 valueBytes[FLAGS_BYTE_INDEX + 2] = (uint8_t)(hrmCounter >> 8);
Rohit Grover 118:620d28e7a1ba 163 }
Rohit Grover 118:620d28e7a1ba 164
rgrover1 242:0e9201b67e2f 165 uint8_t *getPointer(void) {
Rohit Grover 118:620d28e7a1ba 166 return valueBytes;
Rohit Grover 118:620d28e7a1ba 167 }
Rohit Grover 118:620d28e7a1ba 168
Rohit Grover 118:620d28e7a1ba 169 const uint8_t *getPointer(void) const {
Rohit Grover 118:620d28e7a1ba 170 return valueBytes;
Rohit Grover 118:620d28e7a1ba 171 }
Rohit Grover 118:620d28e7a1ba 172
rgrover1 242:0e9201b67e2f 173 unsigned getNumValueBytes(void) const {
Rohit Grover 118:620d28e7a1ba 174 return 1 + ((valueBytes[FLAGS_BYTE_INDEX] & VALUE_FORMAT_FLAG) ? sizeof(uint16_t) : sizeof(uint8_t));
Rohit Grover 118:620d28e7a1ba 175 }
Rohit Grover 118:620d28e7a1ba 176
rgrover1 669:7179b4a5aa7d 177 private:
Rohit Grover 118:620d28e7a1ba 178 /* First byte = 8-bit values, no extra info, Second byte = uint8_t HRM value */
Rohit Grover 118:620d28e7a1ba 179 /* See --> https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.heart_rate_measurement.xml */
Rohit Grover 118:620d28e7a1ba 180 uint8_t valueBytes[MAX_VALUE_BYTES];
Rohit Grover 118:620d28e7a1ba 181 };
Rohit Grover 118:620d28e7a1ba 182
rgrover1 669:7179b4a5aa7d 183 protected:
rgrover1 567:e4b38e43de7c 184 BLEDevice &ble;
rgrover1 277:1407d2f1ce3c 185
Rohit Grover 118:620d28e7a1ba 186 HeartRateValueBytes valueBytes;
Rohit Grover 118:620d28e7a1ba 187 uint8_t controlPointValue;
rgrover1 277:1407d2f1ce3c 188
rgrover1 277:1407d2f1ce3c 189 GattCharacteristic hrmRate;
rgrover1 277:1407d2f1ce3c 190 ReadOnlyGattCharacteristic<uint8_t> hrmLocation;
rgrover1 277:1407d2f1ce3c 191 WriteOnlyGattCharacteristic<uint8_t> controlPoint;
Rohit Grover 118:620d28e7a1ba 192 };
Rohit Grover 118:620d28e7a1ba 193
rgrover1 242:0e9201b67e2f 194 #endif /* #ifndef __BLE_HEART_RATE_SERVICE_H__*/