Gleb Klochkov / Mbed OS Climatcontroll_Main

Dependencies:   esp8266-driver

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers HealthThermometerService.h Source File

HealthThermometerService.h

00001 /* mbed Microcontroller Library
00002  * Copyright (c) 2006-2013 ARM Limited
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 #ifndef __BLE_HEALTH_THERMOMETER_SERVICE_H__
00018 #define __BLE_HEALTH_THERMOMETER_SERVICE_H__
00019 
00020 #include "ble/BLE.h"
00021 
00022 /**
00023 * @class HealthThermometerService
00024 * @brief BLE Health Thermometer Service. This service provides the location of the thermometer and the temperature.
00025 * Service:  https://developer.bluetooth.org/gatt/profiles/Pages/ProfileViewer.aspx?u=org.bluetooth.profile.health_thermometer.xml
00026 * Temperature Measurement: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.temperature_measurement.xml
00027 * Temperature Type: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.temperature_type.xml
00028 */
00029 class HealthThermometerService {
00030 public:
00031     /**
00032     * @brief Location of sensor on the body.
00033     */
00034     enum SensorLocation_t {
00035         LOCATION_ARMPIT  = 1,    /*!< Armpit. */
00036         LOCATION_BODY ,          /*!< Body. */
00037         LOCATION_EAR ,           /*!< Ear. */
00038         LOCATION_FINGER ,        /*!< Finger. */
00039         LOCATION_GI_TRACT ,      /*!< GI tract */
00040         LOCATION_MOUTH ,         /*!< Mouth. */
00041         LOCATION_RECTUM ,        /*!< Rectum. */
00042         LOCATION_TOE ,           /*!< Toe. */
00043         LOCATION_EAR_DRUM ,      /*!< Eardrum. */
00044     };
00045 
00046 public:
00047     /**
00048      * @brief Add the Health Thermometer Service to an existing BLE object, initialize with temperature and location.
00049      * @param[in] _ble         Reference to the BLE device.
00050      * @param[in] initialTemp  Initial value in celsius.
00051      * @param[in] _location
00052      */
00053     HealthThermometerService(BLE &_ble, float initialTemp, uint8_t _location) :
00054         ble(_ble),
00055         valueBytes(initialTemp),
00056         tempMeasurement(GattCharacteristic::UUID_TEMPERATURE_MEASUREMENT_CHAR, (TemperatureValueBytes *)valueBytes.getPointer(), GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY),
00057         tempLocation(GattCharacteristic::UUID_TEMPERATURE_TYPE_CHAR, &_location) {
00058 
00059         GattCharacteristic *hrmChars[] = {&tempMeasurement, &tempLocation, };
00060         GattService         hrmService(GattService::UUID_HEALTH_THERMOMETER_SERVICE, hrmChars, sizeof(hrmChars) / sizeof(GattCharacteristic *));
00061 
00062         ble.addService(hrmService);
00063     }
00064 
00065     /**
00066     * @brief Update the temperature being broadcast.
00067     *
00068     * @param[in] temperature
00069     *                   Floating point value of the temperature.
00070     *
00071     */
00072     void updateTemperature(float temperature) {
00073         if (ble.getGapState().connected) {
00074             valueBytes.updateTemperature(temperature);
00075             ble.gattServer().write(tempMeasurement.getValueHandle(), valueBytes.getPointer(), sizeof(TemperatureValueBytes));
00076         }
00077     }
00078 
00079     /**
00080      * @brief Update the location.
00081      * @param loc
00082      *        New location value.
00083      */
00084     void updateLocation(SensorLocation_t loc) {
00085         ble.gattServer().write(tempLocation.getValueHandle(), reinterpret_cast<uint8_t *>(&loc), sizeof(uint8_t));
00086     }
00087 
00088 private:
00089     /* Private internal representation for the bytes used to work with the vaulue of the temperature characteristic. */
00090     struct TemperatureValueBytes {
00091         static const unsigned OFFSET_OF_FLAGS    = 0;
00092         static const unsigned OFFSET_OF_VALUE    = OFFSET_OF_FLAGS + sizeof(uint8_t);
00093         static const unsigned SIZEOF_VALUE_BYTES = sizeof(uint8_t) + sizeof(float);
00094 
00095         static const unsigned TEMPERATURE_UNITS_FLAG_POS = 0;
00096         static const unsigned TIMESTAMP_FLAG_POS         = 1;
00097         static const unsigned TEMPERATURE_TYPE_FLAG_POS  = 2;
00098 
00099         static const uint8_t  TEMPERATURE_UNITS_CELSIUS    = 0;
00100         static const uint8_t  TEMPERATURE_UNITS_FAHRENHEIT = 1;
00101 
00102         TemperatureValueBytes(float initialTemperature) : bytes() {
00103             /* Assumption: temperature values are expressed in celsius */
00104             bytes[OFFSET_OF_FLAGS] =  (TEMPERATURE_UNITS_CELSIUS << TEMPERATURE_UNITS_FLAG_POS) |
00105                                       (false << TIMESTAMP_FLAG_POS) |
00106                                       (false << TEMPERATURE_TYPE_FLAG_POS);
00107             updateTemperature(initialTemperature);
00108         }
00109 
00110         void updateTemperature(float temp) {
00111             uint32_t temp_ieee11073 = quick_ieee11073_from_float(temp);
00112             memcpy(&bytes[OFFSET_OF_VALUE], &temp_ieee11073, sizeof(float));
00113         }
00114 
00115         uint8_t       *getPointer(void) {
00116             return bytes;
00117         }
00118 
00119         const uint8_t *getPointer(void) const {
00120             return bytes;
00121         }
00122 
00123 private:
00124         /**
00125          * @brief A very quick conversion between a float temperature and 11073-20601 FLOAT-Type.
00126          * @param temperature The temperature as a float.
00127          * @return The temperature in 11073-20601 FLOAT-Type format.
00128          */
00129         uint32_t quick_ieee11073_from_float(float temperature) {
00130             uint8_t  exponent = 0xFE; //Exponent is -2
00131             uint32_t mantissa = (uint32_t)(temperature * 100);
00132 
00133             return (((uint32_t)exponent) << 24) | mantissa;
00134         }
00135 
00136 private:
00137         /* First byte: 8-bit flags. Second field is a float holding the temperature value. */
00138         /* See https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.temperature_measurement.xml */
00139         uint8_t bytes[SIZEOF_VALUE_BYTES];
00140     };
00141 
00142 protected:
00143     BLE                                               &ble;
00144     TemperatureValueBytes                              valueBytes;
00145     ReadOnlyGattCharacteristic<TemperatureValueBytes>   tempMeasurement;
00146     ReadOnlyGattCharacteristic<uint8_t>                 tempLocation;
00147 };
00148 
00149 #endif /* #ifndef __BLE_HEALTH_THERMOMETER_SERVICE_H__*/