BLE PLX profile with customized services (raw data).
Dependencies: MtSense06
PulseOximeterService.h
00001 /* Copyright (c) 2016 MtM Technology Corporation, MIT License 00002 * 00003 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software 00004 * and associated documentation files (the "Software"), to deal in the Software without restriction, 00005 * including without limitation the rights to use, copy, modify, merge, publish, distribute, 00006 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 00007 * furnished to do so, subject to the following conditions: 00008 * 00009 * The above copyright notice and this permission notice shall be included in all copies or 00010 * substantial portions of the Software. 00011 * 00012 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 00013 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00014 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 00015 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00016 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00017 */ 00018 #ifndef __BLE_PULSE_OXIMETER_SERVICE_H__ 00019 #define __BLE_PULSE_OXIMETER_SERVICE_H__ 00020 00021 #include "ble/BLE.h" 00022 00023 class PulseOximeterService { 00024 public: 00025 PulseOximeterService(BLE &_ble, float spo2, float pr) : 00026 ble(_ble), 00027 plxMeasValueBytes(spo2, pr), 00028 plxFeatValueBytes(), 00029 rawValueBytes(), 00030 flagSigValueBytes(), 00031 plxSpotCheckMeasurementCharacteristic(0x2A5E/* UUID:PLX Spot-Check Measurement */, 00032 plxMeasValueBytes.getPointer(), 00033 PlxSpotCheckMeasurementValueBytes::SIZEOF_VALUE_BYTES, 00034 PlxSpotCheckMeasurementValueBytes::SIZEOF_VALUE_BYTES, 00035 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE, 00036 NULL, 0, false 00037 ), 00038 plxFeaturesCharacteristic(0x2A60/* UUID:PLX Features */, 00039 plxFeatValueBytes.getPointer(), 00040 PlxFeaturesValueBytes::SIZEOF_VALUE_BYTES, 00041 PlxFeaturesValueBytes::SIZEOF_VALUE_BYTES, 00042 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ, 00043 NULL, 0, false 00044 ), 00045 rawDataCharacteristic(0x2B00/* UUID:Self defined for raw data */, 00046 rawValueBytes.getPointer(), 00047 RawDataValueBytes::SIZEOF_VALUE_BYTES, 00048 RawDataValueBytes::SIZEOF_VALUE_BYTES, 00049 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY, 00050 NULL, 0, false 00051 ), 00052 signalCharacteristic(0x2B01/* UUID:Self defined for flag & signal */, 00053 flagSigValueBytes.getPointer(), 00054 FlagSignalValueBytes::SIZEOF_VALUE_BYTES, 00055 FlagSignalValueBytes::SIZEOF_VALUE_BYTES, 00056 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ, 00057 NULL, 0, false 00058 ) 00059 { 00060 GattCharacteristic *charTable[] = { 00061 &plxSpotCheckMeasurementCharacteristic, 00062 &plxFeaturesCharacteristic, 00063 &rawDataCharacteristic, 00064 &signalCharacteristic 00065 }; 00066 GattService PulseOximeterService(0x1822/* UUID:Pulse Oximeter Service */, charTable, sizeof(charTable) / sizeof(GattCharacteristic *)); 00067 ble.gattServer().addService(PulseOximeterService); 00068 } 00069 00070 void updatePlxMeas(float spo2, float pr) { 00071 plxMeasValueBytes.updatePlxSpotCheckMeasurement(spo2, pr); 00072 ble.gattServer().write(plxSpotCheckMeasurementCharacteristic.getValueHandle(), 00073 plxMeasValueBytes.getPointer(), 00074 PlxSpotCheckMeasurementValueBytes::SIZEOF_VALUE_BYTES 00075 ); 00076 } 00077 00078 void updateRaw(uint8_t *raw) { 00079 rawValueBytes.updateRawData(raw); 00080 ble.gattServer().write(rawDataCharacteristic.getValueHandle(), 00081 rawValueBytes.getPointer(), 00082 RawDataValueBytes::SIZEOF_VALUE_BYTES 00083 ); 00084 } 00085 00086 void updateStatusFlagAndSignalQuality(uint8_t statusFlag, uint8_t signalQuality) { 00087 flagSigValueBytes.updateFlagSignal(statusFlag, signalQuality); 00088 ble.gattServer().write(signalCharacteristic.getValueHandle(), 00089 flagSigValueBytes.getPointer(), 00090 FlagSignalValueBytes::SIZEOF_VALUE_BYTES 00091 ); 00092 } 00093 //================================================================================== 00094 private: 00095 struct PlxSpotCheckMeasurementValueBytes { 00096 static const unsigned OFFSET_OF_FLAGS = 0; 00097 static const unsigned OFFSET_OF_SPO2 = 1; 00098 static const unsigned OFFSET_OF_PR = 3; 00099 static const unsigned SIZEOF_VALUE_BYTES = 5; 00100 00101 PlxSpotCheckMeasurementValueBytes(float spo2, float pr) : bytes() { 00102 bytes[OFFSET_OF_FLAGS] = 0x00; /* All fields aren't present */ 00103 updatePlxSpotCheckMeasurement(spo2, pr); 00104 } 00105 00106 void updatePlxSpotCheckMeasurement(float spo2, float pr) { 00107 uint16_t sfloat_spo2 = ieee11073_SFLOAT(spo2); 00108 uint16_t sfloat_pr = ieee11073_SFLOAT(pr); 00109 #if 0 00110 memcpy(&bytes[OFFSET_OF_SPO2], &sfloat_spo2, sizeof(uint16_t)); 00111 memcpy(&bytes[OFFSET_OF_PR], &sfloat_pr, sizeof(uint16_t)); 00112 #else 00113 bytes[OFFSET_OF_SPO2+0] = (uint8_t)(sfloat_spo2 >> 8); 00114 bytes[OFFSET_OF_SPO2+1] = (uint8_t)(sfloat_spo2 >> 0); 00115 bytes[OFFSET_OF_PR+0] = (uint8_t)(sfloat_pr >> 8); 00116 bytes[OFFSET_OF_PR+1] = (uint8_t)(sfloat_pr >> 0); 00117 #endif 00118 } 00119 00120 uint8_t *getPointer(void) { return bytes; } 00121 const uint8_t *getPointer(void) const { return bytes; } 00122 00123 uint16_t ieee11073_SFLOAT(float v) { 00124 /* Bitmap: eeee_mmmm_mmmm_mmmm */ 00125 /* Exponent: 4bits, Base10, 2'sComplement */ 00126 /* Mantissa: 12bits, 2's Complement */ 00127 uint8_t exponent = 0; 00128 uint16_t mantissa = (uint16_t)v; 00129 return (((uint16_t)exponent) << 12) | mantissa; 00130 } 00131 00132 uint8_t bytes[SIZEOF_VALUE_BYTES]; 00133 }; 00134 //------------------------------------------------------------------------------- 00135 struct PlxFeaturesValueBytes { 00136 static const unsigned OFFSET_OF_SUPPORTED_FEATURES = 0; 00137 static const unsigned SIZEOF_VALUE_BYTES = 2; 00138 00139 PlxFeaturesValueBytes() : bytes() { 00140 memset(bytes, 0x00, SIZEOF_VALUE_BYTES); /* All features aren't support */ 00141 } 00142 00143 void updatePlxFeatures(uint16_t feat) { 00144 memcpy(&bytes[OFFSET_OF_SUPPORTED_FEATURES], &feat, SIZEOF_VALUE_BYTES); 00145 } 00146 00147 uint8_t *getPointer(void) { return bytes; } 00148 const uint8_t *getPointer(void) const { return bytes; } 00149 00150 uint8_t bytes[SIZEOF_VALUE_BYTES]; 00151 }; 00152 //------------------------------------------------------------------------------- 00153 struct RawDataValueBytes { 00154 static const unsigned OFFSET_OF_RAW = 0; 00155 static const unsigned SIZEOF_VALUE_BYTES = 18; 00156 00157 RawDataValueBytes() : bytes() { 00158 memset(bytes, 0x00, SIZEOF_VALUE_BYTES); 00159 } 00160 00161 void updateRawData(uint8_t *raw) { 00162 memcpy(&bytes[OFFSET_OF_RAW], raw, SIZEOF_VALUE_BYTES); 00163 } 00164 00165 uint8_t *getPointer(void) { return bytes; } 00166 const uint8_t *getPointer(void) const { return bytes; } 00167 00168 uint8_t bytes[SIZEOF_VALUE_BYTES]; 00169 }; 00170 //------------------------------------------------------------------------------- 00171 struct FlagSignalValueBytes { 00172 static const unsigned OFFSET_OF_FLAG = 0; 00173 static const unsigned OFFSET_OF_SIGNAL_QUALITY = 1; 00174 static const unsigned SIZEOF_VALUE_BYTES = 2; 00175 00176 FlagSignalValueBytes() : bytes() { 00177 memset(bytes, 0x00, SIZEOF_VALUE_BYTES); 00178 } 00179 00180 void updateFlagSignal(uint8_t statusFlag, uint8_t signalQuality) { 00181 bytes[OFFSET_OF_FLAG] = statusFlag; 00182 bytes[OFFSET_OF_SIGNAL_QUALITY] = signalQuality; 00183 } 00184 00185 uint8_t *getPointer(void) { return bytes; } 00186 const uint8_t *getPointer(void) const { return bytes; } 00187 00188 uint8_t bytes[SIZEOF_VALUE_BYTES]; 00189 }; 00190 //================================================================================== 00191 protected: 00192 BLE &ble; 00193 00194 PlxSpotCheckMeasurementValueBytes plxMeasValueBytes; 00195 PlxFeaturesValueBytes plxFeatValueBytes; 00196 RawDataValueBytes rawValueBytes; 00197 FlagSignalValueBytes flagSigValueBytes; 00198 00199 GattCharacteristic plxSpotCheckMeasurementCharacteristic; 00200 GattCharacteristic plxFeaturesCharacteristic; 00201 GattCharacteristic rawDataCharacteristic; 00202 GattCharacteristic signalCharacteristic; 00203 }; 00204 00205 #endif /* #ifndef __BLE_PULSE_OXIMETER_SERVICE_H__*/
Generated on Sat Jul 16 2022 13:40:23 by 1.7.2