Lancaster University's fork of the mbed BLE API. Lives on github, https://github.com/lancaster-university/BLE_API

Dependents:   microbit-dal microbit-dal microbit-ble-open microbit-dal ... more

Fork of BLE_API by Bluetooth Low Energy

Committer:
LancasterUniversity
Date:
Wed Apr 06 18:40:26 2016 +0100
Revision:
1131:73c11a85c6d6
Parent:
1056:ce2fb3d09929
Child:
1134:faa0160c87ff
Synchronized with git rev 13bf70b6
Author: Rohit Grover
Release 2.1.5
=============

A minor release to separate the concept of minlen and len in
GattCharacteristic. Also contains some improvements to documentation.

Who changed what in which revision?

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