51 52 with same code
Dependencies: MtSense06
Fork of MtConnect04S_MtSense06 by
source/PulseOximeterService.h
- Committer:
- johnathanlyu
- Date:
- 2018-04-27
- Revision:
- 3:cab2817f6c40
- Parent:
- PulseOximeterService.h@ 1:0ec0e5694c4a
File content as of revision 3:cab2817f6c40:
/* 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__*/