Holla back

Fork of BLE_API by Bluetooth Low Energy

Committer:
jakerosenthal@gmail.com
Date:
Fri Oct 10 17:32:22 2014 -0700
Branch:
2chains
Revision:
123:d2cdf4ebe524
Parent:
118:620d28e7a1ba
first attempt at chaining onconnect and ondisconnect

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
Rohit Grover 118:620d28e7a1ba 20 #include "BLEDevice.h"
Rohit Grover 118:620d28e7a1ba 21
Rohit Grover 118:620d28e7a1ba 22 /* Heart Rate Service */
Rohit Grover 118:620d28e7a1ba 23 /* Service: https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.heart_rate.xml */
Rohit Grover 118:620d28e7a1ba 24 /* HRM Char: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.heart_rate_measurement.xml */
Rohit Grover 118:620d28e7a1ba 25 /* Location: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.body_sensor_location.xml */
Rohit Grover 118:620d28e7a1ba 26 class HeartRateService {
Rohit Grover 118:620d28e7a1ba 27 public:
Rohit Grover 118:620d28e7a1ba 28 enum {
Rohit Grover 118:620d28e7a1ba 29 LOCATION_OTHER = 0,
Rohit Grover 118:620d28e7a1ba 30 LOCATION_CHEST,
Rohit Grover 118:620d28e7a1ba 31 LOCATION_WRIST,
Rohit Grover 118:620d28e7a1ba 32 LOCATION_FINGER,
Rohit Grover 118:620d28e7a1ba 33 LOCATION_HAND,
Rohit Grover 118:620d28e7a1ba 34 LOCATION_EAR_LOBE,
Rohit Grover 118:620d28e7a1ba 35 LOCATION_FOOT,
Rohit Grover 118:620d28e7a1ba 36 };
Rohit Grover 118:620d28e7a1ba 37
Rohit Grover 118:620d28e7a1ba 38 public:
Rohit Grover 118:620d28e7a1ba 39 /**
Rohit Grover 118:620d28e7a1ba 40 * Constructor.
Rohit Grover 118:620d28e7a1ba 41 *
Rohit Grover 118:620d28e7a1ba 42 * param[in] _ble
Rohit Grover 118:620d28e7a1ba 43 * Reference to the underlying BLEDevice.
Rohit Grover 118:620d28e7a1ba 44 * param[in] hrmCounter (8-bit)
Rohit Grover 118:620d28e7a1ba 45 * initial value for the hrm counter.
Rohit Grover 118:620d28e7a1ba 46 * param[in] location
Rohit Grover 118:620d28e7a1ba 47 * Sensor's location.
Rohit Grover 118:620d28e7a1ba 48 */
Rohit Grover 118:620d28e7a1ba 49 HeartRateService(BLEDevice &_ble, uint8_t hrmCounter, uint8_t location) :
Rohit Grover 118:620d28e7a1ba 50 ble(_ble),
Rohit Grover 118:620d28e7a1ba 51 valueBytes(hrmCounter),
Rohit Grover 118:620d28e7a1ba 52 hrmRate(GattCharacteristic::UUID_HEART_RATE_MEASUREMENT_CHAR, valueBytes.getPointer(),
Rohit Grover 118:620d28e7a1ba 53 valueBytes.getNumValueBytes(), HeartRateValueBytes::MAX_VALUE_BYTES,
Rohit Grover 118:620d28e7a1ba 54 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY),
Rohit Grover 118:620d28e7a1ba 55 hrmLocation(GattCharacteristic::UUID_BODY_SENSOR_LOCATION_CHAR, (uint8_t *)&location, sizeof(location), sizeof(location),
Rohit Grover 118:620d28e7a1ba 56 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ),
Rohit Grover 118:620d28e7a1ba 57 controlPoint(GattCharacteristic::UUID_HEART_RATE_CONTROL_POINT_CHAR, (uint8_t *)&controlPointValue,
Rohit Grover 118:620d28e7a1ba 58 sizeof(controlPointValue), sizeof(controlPointValue), GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE) {
Rohit Grover 118:620d28e7a1ba 59 setupService();
Rohit Grover 118:620d28e7a1ba 60 }
Rohit Grover 118:620d28e7a1ba 61
Rohit Grover 118:620d28e7a1ba 62 /**
Rohit Grover 118:620d28e7a1ba 63 * Same constructor as above, but with a 16-bit HRM Counter value.
Rohit Grover 118:620d28e7a1ba 64 */
Rohit Grover 118:620d28e7a1ba 65 HeartRateService(BLEDevice &_ble, uint16_t hrmCounter, uint8_t location) :
Rohit Grover 118:620d28e7a1ba 66 ble(_ble),
Rohit Grover 118:620d28e7a1ba 67 valueBytes(hrmCounter),
Rohit Grover 118:620d28e7a1ba 68 hrmRate(GattCharacteristic::UUID_HEART_RATE_MEASUREMENT_CHAR, valueBytes.getPointer(),
Rohit Grover 118:620d28e7a1ba 69 valueBytes.getNumValueBytes(), HeartRateValueBytes::MAX_VALUE_BYTES,
Rohit Grover 118:620d28e7a1ba 70 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY),
Rohit Grover 118:620d28e7a1ba 71 hrmLocation(GattCharacteristic::UUID_BODY_SENSOR_LOCATION_CHAR, (uint8_t *)&location, sizeof(location), sizeof(location),
Rohit Grover 118:620d28e7a1ba 72 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ),
Rohit Grover 118:620d28e7a1ba 73 controlPoint(GattCharacteristic::UUID_HEART_RATE_CONTROL_POINT_CHAR, (uint8_t *)&controlPointValue,
Rohit Grover 118:620d28e7a1ba 74 sizeof(controlPointValue), sizeof(controlPointValue), GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE) {
Rohit Grover 118:620d28e7a1ba 75 setupService();
Rohit Grover 118:620d28e7a1ba 76 }
Rohit Grover 118:620d28e7a1ba 77
Rohit Grover 118:620d28e7a1ba 78 /**
Rohit Grover 118:620d28e7a1ba 79 * Set a new 8-bit value for heart rate.
Rohit Grover 118:620d28e7a1ba 80 */
Rohit Grover 118:620d28e7a1ba 81 void updateHeartRate(uint8_t hrmCounter) {
Rohit Grover 118:620d28e7a1ba 82 valueBytes.updateHeartRate(hrmCounter);
Rohit Grover 118:620d28e7a1ba 83 ble.updateCharacteristicValue(hrmRate.getValueAttribute().getHandle(), valueBytes.getPointer(), valueBytes.getNumValueBytes());
Rohit Grover 118:620d28e7a1ba 84 }
Rohit Grover 118:620d28e7a1ba 85
Rohit Grover 118:620d28e7a1ba 86 /**
Rohit Grover 118:620d28e7a1ba 87 * Set a new 16-bit value for heart rate.
Rohit Grover 118:620d28e7a1ba 88 */
Rohit Grover 118:620d28e7a1ba 89 void updateHeartRate(uint16_t hrmCounter) {
Rohit Grover 118:620d28e7a1ba 90 valueBytes.updateHeartRate(hrmCounter);
Rohit Grover 118:620d28e7a1ba 91 ble.updateCharacteristicValue(hrmRate.getValueAttribute().getHandle(), valueBytes.getPointer(), valueBytes.getNumValueBytes());
Rohit Grover 118:620d28e7a1ba 92 }
Rohit Grover 118:620d28e7a1ba 93
Rohit Grover 118:620d28e7a1ba 94 /**
Rohit Grover 118:620d28e7a1ba 95 * This callback allows the UART service to receive updates to the
Rohit Grover 118:620d28e7a1ba 96 * txCharacteristic. The application should forward the call to this
Rohit Grover 118:620d28e7a1ba 97 * function from the global onDataWritten() callback handler; or if that's
Rohit Grover 118:620d28e7a1ba 98 * not used, this method can be used as a callback directly.
Rohit Grover 118:620d28e7a1ba 99 */
Rohit Grover 118:620d28e7a1ba 100 virtual void onDataWritten(const GattCharacteristicWriteCBParams *params) {
Rohit Grover 118:620d28e7a1ba 101 if (params->charHandle == controlPoint.getValueAttribute().getHandle()) {
Rohit Grover 118:620d28e7a1ba 102 /* Do something here if the new value is 1; else you can override this method by
Rohit Grover 118:620d28e7a1ba 103 * extending this class.
Rohit Grover 118:620d28e7a1ba 104 * @NOTE: if you are extending this class, be sure to also call
Rohit Grover 118:620d28e7a1ba 105 * ble.onDataWritten(this, &ExtendedHRService::onDataWritten); in
Rohit Grover 118:620d28e7a1ba 106 * your constructor.
Rohit Grover 118:620d28e7a1ba 107 */
Rohit Grover 118:620d28e7a1ba 108 }
Rohit Grover 118:620d28e7a1ba 109 }
Rohit Grover 118:620d28e7a1ba 110
Rohit Grover 118:620d28e7a1ba 111 private:
Rohit Grover 118:620d28e7a1ba 112 void setupService(void) {
Rohit Grover 118:620d28e7a1ba 113 static bool serviceAdded = false; /* We should only ever need to add the heart rate service once. */
Rohit Grover 118:620d28e7a1ba 114 if (serviceAdded) {
Rohit Grover 118:620d28e7a1ba 115 return;
Rohit Grover 118:620d28e7a1ba 116 }
Rohit Grover 118:620d28e7a1ba 117
Rohit Grover 118:620d28e7a1ba 118 GattCharacteristic *charTable[] = {&hrmRate, &hrmLocation, &controlPoint};
Rohit Grover 118:620d28e7a1ba 119 GattService hrmService(GattService::UUID_HEART_RATE_SERVICE, charTable, sizeof(charTable) / sizeof(GattCharacteristic *));
Rohit Grover 118:620d28e7a1ba 120
Rohit Grover 118:620d28e7a1ba 121 ble.addService(hrmService);
Rohit Grover 118:620d28e7a1ba 122 serviceAdded = true;
Rohit Grover 118:620d28e7a1ba 123
Rohit Grover 118:620d28e7a1ba 124 ble.onDataWritten(this, &HeartRateService::onDataWritten);
Rohit Grover 118:620d28e7a1ba 125 }
Rohit Grover 118:620d28e7a1ba 126
Rohit Grover 118:620d28e7a1ba 127 private:
Rohit Grover 118:620d28e7a1ba 128 /* Private internal representation for the bytes used to work with the vaulue of the heart-rate characteristic. */
Rohit Grover 118:620d28e7a1ba 129 struct HeartRateValueBytes {
Rohit Grover 118:620d28e7a1ba 130 static const unsigned MAX_VALUE_BYTES = 3; /* FLAGS + up to two bytes for heart-rate */
Rohit Grover 118:620d28e7a1ba 131 static const unsigned FLAGS_BYTE_INDEX = 0;
Rohit Grover 118:620d28e7a1ba 132
Rohit Grover 118:620d28e7a1ba 133 static const unsigned VALUE_FORMAT_BITNUM = 0;
Rohit Grover 118:620d28e7a1ba 134 static const uint8_t VALUE_FORMAT_FLAG = (1 << VALUE_FORMAT_BITNUM);
Rohit Grover 118:620d28e7a1ba 135
Rohit Grover 118:620d28e7a1ba 136 HeartRateValueBytes(uint8_t hrmCounter) : valueBytes() {
Rohit Grover 118:620d28e7a1ba 137 updateHeartRate(hrmCounter);
Rohit Grover 118:620d28e7a1ba 138 }
Rohit Grover 118:620d28e7a1ba 139
Rohit Grover 118:620d28e7a1ba 140 HeartRateValueBytes(uint16_t hrmCounter) : valueBytes() {
Rohit Grover 118:620d28e7a1ba 141 updateHeartRate(hrmCounter);
Rohit Grover 118:620d28e7a1ba 142 }
Rohit Grover 118:620d28e7a1ba 143
Rohit Grover 118:620d28e7a1ba 144 void updateHeartRate(uint8_t hrmCounter) {
Rohit Grover 118:620d28e7a1ba 145 valueBytes[FLAGS_BYTE_INDEX] &= ~VALUE_FORMAT_FLAG;
Rohit Grover 118:620d28e7a1ba 146 valueBytes[FLAGS_BYTE_INDEX + 1] = hrmCounter;
Rohit Grover 118:620d28e7a1ba 147 }
Rohit Grover 118:620d28e7a1ba 148
Rohit Grover 118:620d28e7a1ba 149 void updateHeartRate(uint16_t hrmCounter) {
Rohit Grover 118:620d28e7a1ba 150 valueBytes[FLAGS_BYTE_INDEX] |= VALUE_FORMAT_FLAG;
Rohit Grover 118:620d28e7a1ba 151 valueBytes[FLAGS_BYTE_INDEX + 1] = (uint8_t)(hrmCounter & 0xFF);
Rohit Grover 118:620d28e7a1ba 152 valueBytes[FLAGS_BYTE_INDEX + 2] = (uint8_t)(hrmCounter >> 8);
Rohit Grover 118:620d28e7a1ba 153 }
Rohit Grover 118:620d28e7a1ba 154
Rohit Grover 118:620d28e7a1ba 155 uint8_t *getPointer(void) {
Rohit Grover 118:620d28e7a1ba 156 return valueBytes;
Rohit Grover 118:620d28e7a1ba 157 }
Rohit Grover 118:620d28e7a1ba 158
Rohit Grover 118:620d28e7a1ba 159 const uint8_t *getPointer(void) const {
Rohit Grover 118:620d28e7a1ba 160 return valueBytes;
Rohit Grover 118:620d28e7a1ba 161 }
Rohit Grover 118:620d28e7a1ba 162
Rohit Grover 118:620d28e7a1ba 163 unsigned getNumValueBytes(void) const {
Rohit Grover 118:620d28e7a1ba 164 return 1 + ((valueBytes[FLAGS_BYTE_INDEX] & VALUE_FORMAT_FLAG) ? sizeof(uint16_t) : sizeof(uint8_t));
Rohit Grover 118:620d28e7a1ba 165 }
Rohit Grover 118:620d28e7a1ba 166
Rohit Grover 118:620d28e7a1ba 167 private:
Rohit Grover 118:620d28e7a1ba 168 /* First byte = 8-bit values, no extra info, Second byte = uint8_t HRM value */
Rohit Grover 118:620d28e7a1ba 169 /* See --> https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.heart_rate_measurement.xml */
Rohit Grover 118:620d28e7a1ba 170 uint8_t valueBytes[MAX_VALUE_BYTES];
Rohit Grover 118:620d28e7a1ba 171 };
Rohit Grover 118:620d28e7a1ba 172
Rohit Grover 118:620d28e7a1ba 173 private:
Rohit Grover 118:620d28e7a1ba 174 BLEDevice &ble;
Rohit Grover 118:620d28e7a1ba 175 HeartRateValueBytes valueBytes;
Rohit Grover 118:620d28e7a1ba 176 uint8_t controlPointValue;
Rohit Grover 118:620d28e7a1ba 177 GattCharacteristic hrmRate;
Rohit Grover 118:620d28e7a1ba 178 GattCharacteristic hrmLocation;
Rohit Grover 118:620d28e7a1ba 179 GattCharacteristic controlPoint;
Rohit Grover 118:620d28e7a1ba 180 };
Rohit Grover 118:620d28e7a1ba 181
Rohit Grover 118:620d28e7a1ba 182 #endif /* #ifndef __BLE_HEART_RATE_SERVICE_H__*/