Delta / Mbed 2 deprecated BLE_Glucose_Demo

Dependencies:   BLE_API mbed nRF51822

Fork of BLE_HeartRate by Bluetooth Low Energy

GlucoseService.h

Committer:
Marcomissyou
Date:
2015-05-29
Revision:
63:fc6117c32419
Child:
64:8cd9416028a7

File content as of revision 63:fc6117c32419:

/* mbed Microcontroller Library
 * Copyright (c) 2006-2013 ARM Limited
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef __BLE_GLUCOSE_SERVICE_H__
#define __BLE_GLUCOSE_SERVICE_H__

#include "BLEDevice.h"
/**
* @class GlucoseService
* @brief BLE Glucose Service. This service displays the Glucose measurement value represented as a 16bit Float format.<br>
* @This example can be demonstrated with Blood Pressure Android App downloaded from
* @https://github.com/Marcomissyou/BluetoothLeGlucose.git
*/
static uint16_t SEQUENCE_NUMBER = 11111;
static uint16_t BASE_TIME_YEAR = 2015;
static uint8_t BASE_TIME_MONTH = 5;
static uint8_t BASE_TIME_DAY = 29;
static uint8_t BASE_TIME_HOURS = 17;
static uint8_t BASE_TIME_MINUTES = 30;
static uint8_t BASE_TIME_SECONDS = 45;

class GlucoseService {
public:
    GlucoseService(BLEDevice &_ble, float GluMeasure, uint16_t GluFeature =2111):
        ble(_ble),
        GluReceiveBuffer(),
        GluReceive_flag(),
        GlucoseMeasurementValue(GluMeasure),
        GlucoseFeatureValue(GluFeature),
        GlucoseValue(GattCharacteristic::UUID_GLUCOSE_MEASUREMENT_CHAR, GlucoseMeasurementValue.getPointer(),
        12, 12,GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY),
        GlucoseFeature(GattCharacteristic::UUID_GLUCOSE_FEATURE_CHAR, &GluFeature),
        GluControlPoint(GattCharacteristic::UUID_RECORD_ACCESS_CONTROL_POINT_CHAR, GluReceiveBuffer, 4, 4,
        GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE)
        {
            setupService();
        }

    void updateGlucoseMeasurement(float GluMeasure) {
        GlucoseMeasurementValue.updateGlucoseMeasurement(GluMeasure);
        ble.updateCharacteristicValue(GlucoseValue.getValueAttribute().getHandle(), GlucoseMeasurementValue.getPointer(), 12);
    }
    
    virtual void onDataWritten(const GattCharacteristicWriteCBParams *params) {
        if (params->charHandle == GluControlPoint.getValueAttribute().getHandle()) {
            uint16_t bytesRead = params->len;
            if (bytesRead <= 4) {
                memcpy(GluReceiveBuffer, params->data, bytesRead);
                GluReceive_flag = 1;
            }
        }
    }
    
    bool is_GluReceived(){
        if(GluReceive_flag ==1){
            return true;
        }
        return false;
    }
    
    uint8_t *getControlPoint(){
        return GluReceiveBuffer;
        }
        
    void CleanFlag(){
        GluReceive_flag = 0;
        }
    
private:
    void setupService(void) {
        static bool serviceAdded = false; /* We should only ever need to add the heart rate service once. */
        if (serviceAdded) {
            return;
        }
        GattCharacteristic *charTable[] = {&GlucoseValue, &GlucoseFeature, &GluControlPoint}; //, &GlucoseContext
        GattService         GluService(GattService::UUID_GLUCOSE_SERVICE, charTable, sizeof(charTable) / sizeof(GattCharacteristic *));
        ble.addService(GluService);
        serviceAdded = true;
        ble.onDataWritten(this, &GlucoseService::onDataWritten);
    }

//==========================================================================================================
private:
struct GlucoseMeasurementBytes {
        static const unsigned FLAGS_BYTE_INDEX = 0;
        static const unsigned TIME_OFFSET_PRESENT = 0;
        static const unsigned GLUCOSE_CONCENTRATION_Type_Sample_Location = 1;
        static const unsigned GLUCOSE_CONCENTRATION_UNIT = 1; // 0 = kg/L, 1 = mol/L
        static const unsigned SENSOR_STATUS_ANNUNCIATION = 0;
        static const unsigned CONTEXT_INFORMATION_FOLLOWS_FALSE = 0;
        static const unsigned CONTEXT_INFORMATION_FOLLOWS_TRUE = 1;
        static const unsigned VALUE_FORMAT_BITNUM = 0;
        static const uint8_t  VALUE_FORMAT_FLAG   = 0;
        
        // Initial setting Glucose measurement value
        GlucoseMeasurementBytes(uint16_t GluMeasure) : GlucoseMeasurementValue() { 
            updateGlucoseMeasurement(GluMeasure);
        }
        
        void updateDataAndSequneceNumber(){
            SEQUENCE_NUMBER++;
            memcpy(&GlucoseMeasurementValue[FLAGS_BYTE_INDEX+3], &BASE_TIME_YEAR, 2);
            memcpy(&GlucoseMeasurementValue[FLAGS_BYTE_INDEX+5], &BASE_TIME_MONTH, 1);
            memcpy(&GlucoseMeasurementValue[FLAGS_BYTE_INDEX+6], &BASE_TIME_DAY, 1);
            memcpy(&GlucoseMeasurementValue[FLAGS_BYTE_INDEX+7], &BASE_TIME_HOURS, 1);
            memcpy(&GlucoseMeasurementValue[FLAGS_BYTE_INDEX+8], &BASE_TIME_MINUTES, 1);
            memcpy(&GlucoseMeasurementValue[FLAGS_BYTE_INDEX+9], &BASE_TIME_SECONDS, 1);
            
            }
        
        void updateGlucoseMeasurement(float GluMeasure) {
            GlucoseMeasurementValue[FLAGS_BYTE_INDEX] = (TIME_OFFSET_PRESENT << 0)|(GLUCOSE_CONCENTRATION_Type_Sample_Location << 1)
                                                    |(GLUCOSE_CONCENTRATION_UNIT << 2)|(SENSOR_STATUS_ANNUNCIATION << 3)
                                                    |(CONTEXT_INFORMATION_FOLLOWS_FALSE << 4);
                                                    
            memcpy(&GlucoseMeasurementValue[FLAGS_BYTE_INDEX+1], &SEQUENCE_NUMBER, 2);
            memcpy(&GlucoseMeasurementValue[FLAGS_BYTE_INDEX+3], &BASE_TIME_YEAR, 2);
            memcpy(&GlucoseMeasurementValue[FLAGS_BYTE_INDEX+5], &BASE_TIME_MONTH, 1);
            memcpy(&GlucoseMeasurementValue[FLAGS_BYTE_INDEX+6], &BASE_TIME_DAY, 1);
            memcpy(&GlucoseMeasurementValue[FLAGS_BYTE_INDEX+7], &BASE_TIME_HOURS, 1);
            memcpy(&GlucoseMeasurementValue[FLAGS_BYTE_INDEX+8], &BASE_TIME_MINUTES, 1);
            memcpy(&GlucoseMeasurementValue[FLAGS_BYTE_INDEX+9], &BASE_TIME_SECONDS, 1);
            uint16_t GluMeasureData = ieee11073_float16(GluMeasure);
            GlucoseMeasurementValue[FLAGS_BYTE_INDEX + 10] = (uint8_t)(GluMeasureData & 0xFF);
            GlucoseMeasurementValue[FLAGS_BYTE_INDEX + 11] = (uint8_t)(GluMeasureData >> 8);
        }

        uint8_t       *getPointer(void) {
            return GlucoseMeasurementValue;
        }
        
        uint16_t ieee11073_float16(float GluMeasure) {
            uint8_t  exponent = 0; 
            uint16_t mantissa = (uint16_t)GluMeasure;
            return ((exponent << 12)&0xF0) | (mantissa << 0) & 0x0FFF ;
        }

        uint8_t GlucoseMeasurementValue[14];
    };
        
private:
    BLEDevice           &ble;
    GlucoseMeasurementBytes  GlucoseMeasurementValue;
    GattCharacteristic       GlucoseValue;  
    uint16_t GlucoseFeatureValue;
    ReadWriteGattCharacteristic<uint16_t>  GlucoseFeature;
    uint8_t             GluReceiveBuffer[4];
    uint8_t             GluReceive_flag;
    GattCharacteristic GluControlPoint;
};
#endif /* #ifndef __BLE_GLUCOSE_SERVICE_H__*/