/**
***************************************************************************************
* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
***************************************************************************************
* @file plxs.c
* @brief Pulse Oximeter Service source file.
* @details Interface to access the Pulse Oximeter Service.
* @author danni
* @date 2018-12-27
* @version v1.0
* *************************************************************************************
*/
#include "trace.h"
#include <string.h>
#include <gatt.h>
#include "plxs.h"
/*============================================================================*
* Macros
*============================================================================*/
/** @defgroup PLXS_SERVICE_UUID service related UUIDs.
* @{
*/
#define GATT_UUID_PULSE_OXIMETER 0x1822
#define GATT_UUID_CHAR_PLX_SPOT_CHECK_MEASUREMENT 0x2A5E
#define GATT_UUID_CHAR_PLX_CONTINUOUS_MEASUREMENT 0x2A5F
#define GATT_UUID_CHAR_PLX_FEATURE 0x2A60
#define GATT_UUID_CHAR_RECORD_ACCESS_CONTROL_POINT 0x2A52
/** @} End of PLXS_SERVICE_UUID */
/** @brief Check PLXS Record Access Control Point operation is available or not. */
#define PLXS_RACP_OPERATION_ACTIVE(x) (((x) >= PLXS_RACP_OPCODE_REPORT_RECS) && ((x) < PLXS_RACP_OPCODE_NBR_OF_RECS_RESP))
/** @defgroup PLXS_APP_ERROR_CODE profile specific attribute protocol application error codes
* @{
*/
#define PLXS_ERR_PROC_ALREADY_IN_PROGRESS 0xFE
#define PLXS_ERR_CCCD_IMPROPERLY_CONFIGURED 0xFD
/** @} End of PLXS_APP_ERROR_CODE */
/** @defgroup PLXS_SPOT_CHECK_FLAGS PLX Spot-check Measurement Characteristic Flags,The Flags field is an 8-bit bit field which indicates what fields are present in the PLX Spot-check
* Measurement Characteristic value
* @{
*/
#define PLXS_SPOT_CHECK_MEASUREMENT_FLAG_TIMESTAMP 0x01
#define PLXS_SPOT_CHECK_MEASUREMENT_FLAG_MEASUREMENT_STATUS 0x02
#define PLXS_SPOT_CHECK_MEASUREMENT_FLAG_DEVICE_SENSOR_STATUS 0x04
#define PLXS_SPOT_CHECK_MEASUREMENT_FLAG_PULSE_AMPLITUDE_INDEX 0x08
#define PLXS_SPOT_CHECK_MEASUREMENT_FLAG_DEVICE_CLOCK_NOT_SET 0x10
/** @} End of PLXS_SPOT_CHECK_FLAGS */
/** @defgroup PLXS_CONTINUOUS_MEAS_FLAGS PLX Continuous Measurement Characteristic Flags,The Flags field is an 8-bit bit field which indicates what fields are present in the PLX Continuous
* Measurement Characteristic value.
* @{
*/
#define PLXS_CONTINUOUS_MEASUREMENT_FLAG_SPO2PR_FAST 0x01
#define PLXS_CONTINUOUS_MEASUREMENT_FLAG_SPO2PR_SLOW 0x02
#define PLXS_CONTINUOUS_MEASUREMENT_FLAG_MEASUREMENT_STATUS 0x04
#define PLXS_CONTINUOUS_MEASUREMENT_FLAG_DEVICE_SENSOR_STATUS 0x08
#define PLXS_CONTINUOUS_MEASUREMENT_FLAG_PULSE_AMPLITUDE_INDEX 0x10
/** @} End of PLXS_CONTINUOUS_MEAS_FLAGS */
/** @defgroup PLXS_FEASURES_FLAGS PLX Supported Features field. The Supported Features field is a 16-bit bit field which indicates feature support as well as what
* fields are present in the PLX Features characteristic.
* @{
*/
#define PLXS_FEATURES_MEASUREMENT_STATUS 0x0001
#define PLXS_FEATURES_DEVICE_SENSOR_STATUS 0x0002
#define PLXS_FEATURES_MEASUREMENT_STORAGE 0x0004
#define PLXS_FEATURES_TIMESTAMP 0x0008
#define PLXS_FEATURES_SPO2PR_FAST_METRIC 0x0010
#define PLXS_FEATURES_SPO2PR_SLOW_METRIC 0x0020
#define PLXS_FEATURES_PULSE_AMPLITUDE_INDEX 0x0040
#define PLXS_FEATURES_MULTIPLE_BONDS 0x0080
/** @} End of PLXS_FEASURES_FLAGS */
/** @brief The Server should be able to store 30 or more measurements*/
#define PLXS_RACP_DATABASE_SIZE (PLXS_RACP_MAX_NBR_OF_STORED_RECS + 1)
/*============================================================================*
* Types
*============================================================================*/
#if PLXS_STORE_SPOT_CHECK_MEASUREMENT_SUPPORT
typedef struct
{
T_PLXS_SPOT_CHECK_MEASUREMENT_VALUE plxs_spot_check_measurement_value;
} T_PLXS_PATIENT_RECORD;
/** @brief data base for store spot check measurement value*/
typedef struct
{
T_PLXS_PATIENT_RECORD records[PLXS_RACP_DATABASE_SIZE];
uint8_t record_num;
uint8_t head;
uint8_t tail;
} T_PLXS_RECORD_DATA_BASE;
/** @brief PLXS Record Access Control Point OpCodes. */
typedef enum
{
PLXS_RACP_OPCODE_RESERVED = 0x00,/**< reserved for future use operator:N/A */
PLXS_RACP_OPCODE_REPORT_RECS = 0x01,/**< report stored records(operator:All records)*/
PLXS_RACP_OPCODE_DELETE_RECS = 0x02,/**< delete stored records(operator:All records)*/
PLXS_RACP_OPCODE_ABORT_OPERATION = 0x03,/**< Abort operation(operator:Null 0x00)*/
PLXS_RACP_OPCODE_REPORT_NBR_OF_RECS = 0x04,/**< report number of stored records(operator:All records)*/
PLXS_RACP_OPCODE_NBR_OF_RECS_RESP = 0x05,/**< number of stored records response(operator:Null 0x00)*/
PLXS_RACP_OPCODE_RESP_CODE = 0x06/**< response code (operator:Null 0x00)*/
} T_PLXS_CTRL_POINT_OPCODE;
/**@brief PLXS Record Access Control Point Operator. */
typedef enum
{
PLXS_RACP_OPERATOR_NULL = 0x00,
PLXS_RACP_OPERATOR_ALL_RECS = 0x01,/**< All records*/
PLXS_RACP_OPERATOR_LT_EQ = 0x02,/**< less than or equal to*/
PLXS_RACP_OPERATOR_GT_EQ = 0x03,/**< greater than or equal to*/
PLXS_RACP_OPERATOR_RANGE = 0x04,/**< within range of */
PLXS_RACP_OPERATOR_FIRST = 0x05,/**< first records*/
PLXS_RACP_OPERATOR_LAST = 0x06/**< last records*/
} T_PLXS_CTRL_POINT_OPERATOR;
/** @brief Glucose Record Access Control Point Response Codes. */
typedef enum
{
PLXS_RACP_RESP_RESERVED = 0x00,
PLXS_RACP_RESP_SUCCESS = 0x01,
PLXS_RACP_RESP_OPCODE_NOT_SUPPORTED = 0x02,
PLXS_RACP_RESP_INVALID_OPERATOR = 0x03,
PLXS_RACP_RESP_OPERATOR_NOT_SUPPORTED = 0x04,
PLXS_RACP_RESP_INVALID_OPERAND = 0x05,
PLXS_RACP_RESP_NO_RECS_FOUND = 0x06,
PLXS_RACP_RESP_ABORT_UNSUCCESSFUL = 0x07,
PLXS_RACP_RESP_PROC_NOT_COMPLETED = 0x08,
PLXS_RACP_RESP_OPERAND_NOT_SUPPORTED = 0x09
} T_PLXS_CTRL_POINT_RESP_CODES;
typedef struct
{
T_PLXS_CTRL_POINT_OPCODE op_code;
T_PLXS_CTRL_POINT_OPERATOR op;/**< operator*/
uint8_t operand[18];
} T_PLXS_CONTROL_POINT;
typedef struct
{
T_PLXS_CONTROL_POINT ctrl_point;
uint8_t cp_length;/**< length of current operand of control point*/
T_PLXS_RECORD_DATA_BASE record_db;
} T_PLXS_RACP;
/** @brief plxs report records procedure flags*/
typedef struct
{
uint16_t plxs_num_records_to_report;
uint16_t plxs_current_record_to_report;
uint16_t plxs_record_to_report_start_index;
uint16_t plxs_records_to_report_offset;
bool plxs_send_data_end_flag;
} T_PLXS_REPORT_RECORDS_FLAGS;
#endif
/** @brief notification or indiaction enabled or not.1:enabled,0: disabled*/
typedef struct
{
uint8_t spot_check_measurement_indication_enable: 1;
uint8_t continuous_measurement_notify_enable: 1;
uint8_t racp_indication_enable: 1;
uint8_t rfu: 5;
} T_PLXS_NOTIFY_INDICATE_FLAG;
/** @brief add flow control for notify and indicate*/
typedef struct
{
uint8_t spot_check_indica