51 52 with same code
Dependencies: MtSense06
Fork of MtConnect04S_MtSense06 by
Diff: source/PulseOximeterService.h
- Revision:
- 3:cab2817f6c40
- Parent:
- 1:0ec0e5694c4a
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/PulseOximeterService.h Fri Apr 27 09:59:38 2018 +0000 @@ -0,0 +1,205 @@ +/* Copyright (c) 2016 MtM Technology Corporation, MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software + * and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#ifndef __BLE_PULSE_OXIMETER_SERVICE_H__ +#define __BLE_PULSE_OXIMETER_SERVICE_H__ + +#include "ble/BLE.h" + +class PulseOximeterService { +public: + PulseOximeterService(BLE &_ble, float spo2, float pr) : + ble(_ble), + plxMeasValueBytes(spo2, pr), + plxFeatValueBytes(), + rawValueBytes(), + flagSigValueBytes(), + plxSpotCheckMeasurementCharacteristic(0x2A5E/* UUID:PLX Spot-Check Measurement */, + plxMeasValueBytes.getPointer(), + PlxSpotCheckMeasurementValueBytes::SIZEOF_VALUE_BYTES, + PlxSpotCheckMeasurementValueBytes::SIZEOF_VALUE_BYTES, + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE, + NULL, 0, false + ), + plxFeaturesCharacteristic(0x2A60/* UUID:PLX Features */, + plxFeatValueBytes.getPointer(), + PlxFeaturesValueBytes::SIZEOF_VALUE_BYTES, + PlxFeaturesValueBytes::SIZEOF_VALUE_BYTES, + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ, + NULL, 0, false + ), + rawDataCharacteristic(0x2B00/* UUID:Self defined for raw data */, + rawValueBytes.getPointer(), + RawDataValueBytes::SIZEOF_VALUE_BYTES, + RawDataValueBytes::SIZEOF_VALUE_BYTES, + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY, + NULL, 0, false + ), + signalCharacteristic(0x2B01/* UUID:Self defined for flag & signal */, + flagSigValueBytes.getPointer(), + FlagSignalValueBytes::SIZEOF_VALUE_BYTES, + FlagSignalValueBytes::SIZEOF_VALUE_BYTES, + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ, + NULL, 0, false + ) + { + GattCharacteristic *charTable[] = { + &plxSpotCheckMeasurementCharacteristic, + &plxFeaturesCharacteristic, + &rawDataCharacteristic, + &signalCharacteristic + }; + GattService PulseOximeterService(0x1822/* UUID:Pulse Oximeter Service */, charTable, sizeof(charTable) / sizeof(GattCharacteristic *)); + ble.gattServer().addService(PulseOximeterService); + } + + void updatePlxMeas(float spo2, float pr) { + plxMeasValueBytes.updatePlxSpotCheckMeasurement(spo2, pr); + ble.gattServer().write(plxSpotCheckMeasurementCharacteristic.getValueHandle(), + plxMeasValueBytes.getPointer(), + PlxSpotCheckMeasurementValueBytes::SIZEOF_VALUE_BYTES + ); + } + + void updateRaw(uint8_t *raw) { + rawValueBytes.updateRawData(raw); + ble.gattServer().write(rawDataCharacteristic.getValueHandle(), + rawValueBytes.getPointer(), + RawDataValueBytes::SIZEOF_VALUE_BYTES + ); + } + + void updateStatusFlagAndSignalQuality(uint8_t statusFlag, uint8_t signalQuality) { + flagSigValueBytes.updateFlagSignal(statusFlag, signalQuality); + ble.gattServer().write(signalCharacteristic.getValueHandle(), + flagSigValueBytes.getPointer(), + FlagSignalValueBytes::SIZEOF_VALUE_BYTES + ); + } +//================================================================================== +private: + struct PlxSpotCheckMeasurementValueBytes { + static const unsigned OFFSET_OF_FLAGS = 0; + static const unsigned OFFSET_OF_SPO2 = 1; + static const unsigned OFFSET_OF_PR = 3; + static const unsigned SIZEOF_VALUE_BYTES = 5; + + PlxSpotCheckMeasurementValueBytes(float spo2, float pr) : bytes() { + bytes[OFFSET_OF_FLAGS] = 0x00; /* All fields aren't present */ + updatePlxSpotCheckMeasurement(spo2, pr); + } + + void updatePlxSpotCheckMeasurement(float spo2, float pr) { + uint16_t sfloat_spo2 = ieee11073_SFLOAT(spo2); + uint16_t sfloat_pr = ieee11073_SFLOAT(pr); +#if 0 + memcpy(&bytes[OFFSET_OF_SPO2], &sfloat_spo2, sizeof(uint16_t)); + memcpy(&bytes[OFFSET_OF_PR], &sfloat_pr, sizeof(uint16_t)); +#else + bytes[OFFSET_OF_SPO2+0] = (uint8_t)(sfloat_spo2 >> 8); + bytes[OFFSET_OF_SPO2+1] = (uint8_t)(sfloat_spo2 >> 0); + bytes[OFFSET_OF_PR+0] = (uint8_t)(sfloat_pr >> 8); + bytes[OFFSET_OF_PR+1] = (uint8_t)(sfloat_pr >> 0); +#endif + } + + uint8_t *getPointer(void) { return bytes; } + const uint8_t *getPointer(void) const { return bytes; } + + uint16_t ieee11073_SFLOAT(float v) { + /* Bitmap: eeee_mmmm_mmmm_mmmm */ + /* Exponent: 4bits, Base10, 2'sComplement */ + /* Mantissa: 12bits, 2's Complement */ + uint8_t exponent = 0; + uint16_t mantissa = (uint16_t)v; + return (((uint16_t)exponent) << 12) | mantissa; + } + + uint8_t bytes[SIZEOF_VALUE_BYTES]; + }; + //------------------------------------------------------------------------------- + struct PlxFeaturesValueBytes { + static const unsigned OFFSET_OF_SUPPORTED_FEATURES = 0; + static const unsigned SIZEOF_VALUE_BYTES = 2; + + PlxFeaturesValueBytes() : bytes() { + memset(bytes, 0x00, SIZEOF_VALUE_BYTES); /* All features aren't support */ + } + + void updatePlxFeatures(uint16_t feat) { + memcpy(&bytes[OFFSET_OF_SUPPORTED_FEATURES], &feat, SIZEOF_VALUE_BYTES); + } + + uint8_t *getPointer(void) { return bytes; } + const uint8_t *getPointer(void) const { return bytes; } + + uint8_t bytes[SIZEOF_VALUE_BYTES]; + }; + //------------------------------------------------------------------------------- + struct RawDataValueBytes { + static const unsigned OFFSET_OF_RAW = 0; + static const unsigned SIZEOF_VALUE_BYTES = 18; + + RawDataValueBytes() : bytes() { + memset(bytes, 0x00, SIZEOF_VALUE_BYTES); + } + + void updateRawData(uint8_t *raw) { + memcpy(&bytes[OFFSET_OF_RAW], raw, SIZEOF_VALUE_BYTES); + } + + uint8_t *getPointer(void) { return bytes; } + const uint8_t *getPointer(void) const { return bytes; } + + uint8_t bytes[SIZEOF_VALUE_BYTES]; + }; + //------------------------------------------------------------------------------- + struct FlagSignalValueBytes { + static const unsigned OFFSET_OF_FLAG = 0; + static const unsigned OFFSET_OF_SIGNAL_QUALITY = 1; + static const unsigned SIZEOF_VALUE_BYTES = 2; + + FlagSignalValueBytes() : bytes() { + memset(bytes, 0x00, SIZEOF_VALUE_BYTES); + } + + void updateFlagSignal(uint8_t statusFlag, uint8_t signalQuality) { + bytes[OFFSET_OF_FLAG] = statusFlag; + bytes[OFFSET_OF_SIGNAL_QUALITY] = signalQuality; + } + + uint8_t *getPointer(void) { return bytes; } + const uint8_t *getPointer(void) const { return bytes; } + + uint8_t bytes[SIZEOF_VALUE_BYTES]; + }; +//================================================================================== +protected: + BLE &ble; + + PlxSpotCheckMeasurementValueBytes plxMeasValueBytes; + PlxFeaturesValueBytes plxFeatValueBytes; + RawDataValueBytes rawValueBytes; + FlagSignalValueBytes flagSigValueBytes; + + GattCharacteristic plxSpotCheckMeasurementCharacteristic; + GattCharacteristic plxFeaturesCharacteristic; + GattCharacteristic rawDataCharacteristic; + GattCharacteristic signalCharacteristic; +}; + +#endif /* #ifndef __BLE_PULSE_OXIMETER_SERVICE_H__*/ \ No newline at end of file