project for nrf51822 qfab

Dependencies:   eddystone_URL mbed

Fork of eddystone_URL by vo dung

Committer:
tridung141196
Date:
Thu Nov 23 15:38:48 2017 +0000
Revision:
5:267bdacf5508
Parent:
0:76dfa9657d9d
ibeacon

Who changed what in which revision?

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