1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
|
/**
*****************************************************************************************
* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
*****************************************************************************************
* @file plxs.h
* @brief Head file for using Pulse Oximeter Service .
* @details Pulse Oximeter Service data types and external functions declaration.
* @author danni
* @date 2018-12-27
* @version v1.0
* *************************************************************************************
*/
/* Define to prevent recursive inclusion */
#ifndef _PLXS_H
#define _PLXS_H
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* Add Includes here */
#include "profile_server.h"
#include "plxs_config.h"
/** @defgroup PLXS Pulse Oximeter Service
* @brief Pulse Oximeter Service
* @{
*/
/*============================================================================*
* Macros
*============================================================================*/
/** @defgroup PLXS_Exported_Macros PLXS Exported Macros
* @brief
* @{
*/
#define PLXS_SPOT_CHECK_MEASUREMENT_INDICATION_ENABLE 1 /**< spot check measurement indication cccd enable */
#define PLXS_SPOT_CHECK_MEASUREMENT_INDICATION_DISABLE 2 /**< spot check measurement indication cccd disable */
#define PLXS_CONTINUOUS_MEASUREMENT_NOTIFY_ENABLE 3 /**< continuous measurement notify cccd enable */
#define PLXS_CONTINUOUS_MEASUREMENT_NOTIFY_DISABLE 4 /**< continuous measurement notify cccd disable */
#define PLXS_RACP_INDICATION_ENABLE 5 /**< racp indication cccd enable*/
#define PLXS_RACP_INDICATION_DISABLE 6 /**< racp indication cccd disable*/
#define PLXS_SFLOAT_VALUE_NaN 0x07ff /**< not a number */
#define PLXS_SFLOAT_VALUE_NRes 0x0800 /**< not at this resolution */
#define PLXS_SFLOAT_VALUE_PlusINFINITY 0x07fe /**< + INFINITY */
#define PLXS_SFLOAT_VALUE_MinusINFINITY 0x0802 /**< - INFINITY */
#define PLXS_SFLOAT_VALUE_RFU 0x0801 /**< reserved for future use */
/** @} End of PLXS_Exported_Macros */
/*============================================================================*
* Types
*============================================================================*/
/** @defgroup PLXS_Exported_Types PLXS Exported Types
* @brief
* @{
*/
/** @brief define PLXS_TIMESTAMP type to store date time data,PLXS_TIMESTAMP[0] = LSO,PLXS_TIMESTAMP[6]=MSO*/
typedef uint8_t PLXS_TIMESTAMP[7];
/** @brief define PLXS_SFLOAT type to store spo2,pr,Pulse Amplitude Index value,PLXS_SFLOAT[0] = LSO,PLXS_SFLOAT[1] = MSO*/
typedef uint8_t PLXS_SFLOAT[2];
/** @brief plxs service parameter type*/
typedef enum
{
PLXS_PARAM_SPOT_CHECK_MEASUREMENT_FLAGS = 0x01,
PLXS_PARAM_CONTINUOUS_MEASUREMENT_FLAGS,
PLXS_PARAM_FEATURE_FLAGS
} T_PLXS_PARAM_TYPE;
/** @brief spot check measurement vaule indicate, continuous measurement vaule notify or racp procedure status */
typedef enum
{
PLXS_STATUS_SPOT_CHECK_MEASUREMENT_INDICATION_IDLE = 0x00,/**< function plxs_spot_check_measurement_value_indicate() never be called and in initialization state*/
PLXS_STATUS_SPOT_CHECK_MEASUREMENT_INDICATION_DOING,/**< function plxs_spot_check_measurement_value_indicate() be called success, but PROFILE_EVT_SEND_DATA_COMPLETE was not received*/
PLXS_STATUS_SPOT_CHECK_MEASUREMENT_INDICATION_DONE,/**< function plxs_spot_check_measurement_value_indicate() be called success, and PROFILE_EVT_SEND_DATA_COMPLETE was received*/
PLXS_STATUS_CONTINUOUS_MEASUREMENT_NOTIFY_IDLE,/**< function plxs_continuous_measurement_value_notify() never be called and in initialization state*/
PLXS_STATUS_CONTINUOUS_MEASUREMENT_NOTIFY_DOING,/**< function plxs_continuous_measurement_value_notify() be called success, but PROFILE_EVT_SEND_DATA_COMPLETE was not received*/
PLXS_STATUS_CONTINUOUS_MEASUREMENT_NOTIFY_DONE,/**< function plxs_continuous_measurement_value_notify() be called success, and PROFILE_EVT_SEND_DATA_COMPLETE was received*/
PLXS_STATUS_REPORT_RECORDS_INDICATION_IDLE,/**< function plxs_spot_check_measurement_value_store_indicate() never be called and in initialization state*/
PLXS_STATUS_REPORT_RECORDS_INDICATION_DOING,/**< function plxs_spot_check_measurement_value_store_indicate() be called success, but PROFILE_EVT_SEND_DATA_COMPLETE was not received*/
PLXS_STATUS_REPORT_RECORDS_INDICATION_DONE,/**< function plxs_spot_check_measurement_value_store_indicate() be called success and PROFILE_EVT_SEND_DATA_COMPLETE was received*/
PLXS_STATUS_NOT_SUPPORT,/**< status not supported*/
} T_PLXS_DATA_SEND_STATUS;
/** @brief APP Return Result List */
typedef enum
{
PLXS_APP_RESULT_SUCCESS = 0x00,/**< plx service return result success*/
PLXS_APP_RESULT_PENDING,/**< if plx service return pending, means that report stored records procedure is in progress,please send data later*/
PLXS_APP_RESULT_QUEUE_NULL,/**< plx service return result empty*/
PLXS_APP_RESULT_NOT_SUPPORT,/**< plx service return result procedure not support*/
PLXS_APP_RESULT_INVALID_VALUE_SIZE,/**< plx service return result invalid value size*/
PLXS_APP_RESULT_INVALID_TYPE,/**< plx service return result invalid type*/
PLXS_APP_RESULT_INVALID_OFFSET,/**< plx service return result invalid offset*/
PLXS_APP_RESULT_POINTER_NULL,/**< plx service return result pointer is null*/
PLXS_APP_RESULT_FAIL,/**< plx service return result fail for other reasons*/
PLXS_APP_RESULT_CCCD_NOT_ENABLED/**< plx service return result cccd not enable*/
} T_PLXS_APP_RESULT;
/** @brief measurement status bits*/
typedef struct
{
uint16_t rfu: 5;
uint16_t measurement_ongoing: 1;
uint16_t early_estimated_data: 1;
uint16_t validated_data: 1;
uint16_t fully_qualified_data: 1;
uint16_t data_from_measurement_storage: 1;
uint16_t data_for_demonstration: 1;
uint16_t data_for_testing: 1;
uint16_t calibration_ongoing: 1;
uint16_t measurement_unavailable: 1;
uint16_t questionable_measurement_detected: 1;
uint16_t invalid_measurement_detected: 1;
} T_PLXS_MEASUREMENT_STATE;
/** @brief device and sensor status bits*/
typedef struct
{
uint8_t extended_display_update_ongoing: 1;
uint8_t equipment_malfunction_detected: 1;
uint8_t signal_processing_irregularity_detected: 1;
uint8_t inadequate_signal_detected: 1;
uint8_t poor_signal_detected: 1;
uint8_t low_perfusion_detected: 1;
uint8_t erratic_signal_detected: 1;
uint8_t nonPulsatile_signal_detected: 1;
uint8_t questionable_pulse_detected: 1;
uint8_t signal_analysis_ongoing: 1;
uint8_t sensor_interference_detected: 1;
uint8_t sensor_unconnected_to_user: 1;
uint8_t unknown_sensor_connected: 1;
uint8_t sensor_displaced: 1;
uint8_t sensor_malfunctioning: 1;
uint8_t sensor_disconnected: 1;
uint8_t rfu: 8;
} T_PLXS_DEVICE_AND_SENSOR_STATE;
/** @brief typedef spot check measurement value*/
typedef struct
{
PLXS_SFLOAT spo2;
PLXS_SFLOAT pr;
#if PLXS_SPOT_CHECK_MEASUREMENT_TIMESTAMP_SUPPORT
PLXS_TIMESTAMP time;
#endif
#if PLXS_MEASUREMENT_STATE_SUPPORT
T_PLXS_MEASUREMENT_STATE measurement_status;
#endif
#if PLXS_DEVICE_AND_SENSOR_STATUS_SUPPORT
T_PLXS_DEVICE_AND_SENSOR_STATE device_and_sensor_status;
#endif
#if PLXS_PULSE_AMPLITUDE_INDEX_SUPPORT
PLXS_SFLOAT pulse_amplitude_index;
#endif
} T_PLXS_SPOT_CHECK_MEASUREMENT_VALUE;
/** @brief typedef spo2PR*/
typedef struct
{
PLXS_SFLOAT spo2;
PLXS_SFLOAT pr;
} T_SPO2PR;
/**@brief typedef continuous measurement value*/
typedef struct
{
T_SPO2PR spo2pr_normal;
#if PLXS_CONTINUOUS_MEASUREMENT_SPO2PR_FAST_SUPPORT
T_SPO2PR spo2pr_fast;
#endif
#if PLXS_CONTINUOUS_MEASUREMENT_SPO2PR_SLOW_SUPPORT
T_SPO2PR spo2pr_slow;
#endif
#if PLXS_MEASUREMENT_STATE_SUPPORT
T_PLXS_MEASUREMENT_STATE measurement_status;
#endif
#if PLXS_DEVICE_AND_SENSOR_STATUS_SUPPORT
T_PLXS_DEVICE_AND_SENSOR_STATE device_and_sensor_status;
#endif
#if PLXS_PULSE_AMPLITUDE_INDEX_SUPPORT
PLXS_SFLOAT pulse_amplitude_index;
#endif
} T_PLXS_CONTINUOUS_MEASUREMENT_VALUE;
/** @brief typedef features value */
typedef struct
{
uint16_t supported_features;
#if PLXS_MEASUREMENT_STATE_SUPPORT
uint16_t measurement_status_support_bits;
#endif
#if PLXS_DEVICE_AND_SENSOR_STATUS_SUPPORT
uint32_t device_and_sensor_status_support_bits;
#endif
} T_PLXS_FEATURES_VALUE;
/** @} End of PLXS_Exported_Types */
/** @defgroup PLXS_Callback_Data PLXS Callback Data
* @brief PLXS data struct for notification data to application.
* @{
*/
typedef union
{
uint8_t notify_indicate_index;
} T_PLXS_UPSTREAM_MSG_DATA;
typedef struct
{
uint8_t conn_id;
T_SERVICE_CALLBACK_TYPE msg_type;
T_PLXS_UPSTREAM_MSG_DATA msg_data;
} T_PLXS_CALLBACK_DATA;
/** @} End of PLXS_Callback_Data */
/*============================================================================*
* Functions
*============================================================================*/
/** @defgroup PLXS_Exported_Functions PLXS Exported Functions
* @brief
* @{
*/
/**
* @brief Add PLX service to the BLE stack database.
*
* @param[in] p_func Callback when service attribute was read, write or cccd update.
* @return Service id generated by the BLE stack: @ref T_SERVER_ID.
* @retval 0xFF Operation failure.
* @retval Others Service id assigned by stack.
*
* <b>Example usage</b>
* \code{.c}
void app_le_profile_init()
{
server_init(1);
plxs_srv_id = plxs_add_service(app_handle_profile_message);
}
* \endcode
*/
T_SERVER_ID plxs_add_service(void *p_func);
/**
* @brief get plxs parameters such as spot check measurement flags,continuous measurement flags or features supports @ref T_PLXS_PARAM_TYPE
*
* @param[in] param_type @ref T_PLXS_PARAM_TYPE
* @param[in,out] p_value get spot check measurement flags,continuous measurement flags or features supports
* @return plxs_get_parameter result
* @retval PLXS_APP_RESULT_SUCCESS Operation success.
* @retval others Operation fail.
*
* <b>Example usage</b>
* \code{.c}
static T_USER_CMD_PARSE_RESULT cmd_plxs_feature_flags_set(T_USER_CMD_PARSED_VALUE *p_parse_value)
{
T_PLXS_FEATURES_VALUE plxs_features;
plxs_get_parameter(PLXS_PARAM_FEATURE_FLAGS, &plxs_features);
if (p_parse_value->dw_param[0] == 1)
{
//both measurement status and device sensor status not support
plxs_features.supported_features = plxs_features.supported_features & 0xFFFC;
}
......
}
* \endcode
*/
T_PLXS_APP_RESULT plxs_get_parameter(T_PLXS_PARAM_TYPE param_type, void *p_value);
/**
* @brief send plxs spot check measurement characteristic indication
*
* @param[in] conn_id connection index
* @param[in] Service_id generated by the BLE stack: @ref T_SERVER_ID.
* @param[in] p_spot_check_measurement_value @ref T_PLXS_SPOT_CHECK_MEASUREMENT_VALUE
* @return plxs_spot_check_measurement_value_indicate result
* @retval PLXS_APP_RESULT_SUCCESS Operation success.
* @retval others Operation fail.
*
* <b>Example usage</b>
* \code{.c}
void test_plxs(void)
{
T_PLXS_SPOT_CHECK_MEASUREMENT_VALUE plxs_spot_check_measure_value;
......//plxs_spot_check_measure_value initialization
bool result = plxs_spot_check_measurement_value_indicate(conn_id,plxs_srv_id,&plxs_spot_check_measure_value);
if(result == PLXS_APP_RESULT_SUCCESS)
{
}
}
* \endcode
*/
#if PLXS_SPOT_CHECK_MEASUREMENT_SUPPORT
T_PLXS_APP_RESULT plxs_spot_check_measurement_value_indicate(uint8_t conn_id, uint8_t service_id,
T_PLXS_SPOT_CHECK_MEASUREMENT_VALUE *p_spot_check_measurement_value);
#endif
/**
* @brief send plxs continuous measurement characteristic notification
*
* @param[in] conn_id connection index
* @param[in] Service_id generated by the BLE stack: @ref T_SERVER_ID.
* @param[in] plxs_continuous_measurement_value @ref T_PLXS_CONTINUOUS_MEASUREMENT_VALUE
* @return plxs_continuous_measurement_value_notify result
* @retval PLXS_APP_RESULT_SUCCESS Operation success.
* @retval others Operation fail.
*
* <b>Example usage</b>
* \code{.c}
void test_plxs(void)
{
......//plxs_continuous_measurement_value initialization
bool result = plxs_continuous_measurement_value_notify( conn_id, plxs_srv_id,&plxs_continuous_measurement_value);
if(result == PLXS_APP_RESULT_SUCCESS)
{
PROFILE_PRINT_INFO0("plxs_continuous_measurement_value_notify notify data send success!");
}
}
* \endcode
*/
#if PLXS_CONTINUOUS_MEASUREMENT_SUPPORT
T_PLXS_APP_RESULT plxs_continuous_measurement_value_notify(uint8_t conn_id, T_SERVER_ID service_id,
T_PLXS_CONTINUOUS_MEASUREMENT_VALUE *p_plxs_continuous_measurement_value);
#endif
/**
* @brief clear flags if procedure fail or disconnect
*
* <b>Example usage</b>
* \code{.c}
void app_handle_conn_state_evt(uint8_t conn_id, T_GAP_CONN_STATE new_state, uint16_t disc_cause)
{
APP_PRINT_INFO4("app_handle_conn_state_evt: conn_id %d old_state %d new_state %d, disc_cause 0x%x",
conn_id, gap_conn_state, new_state, disc_cause);
switch (new_state)
{
case GAP_CONN_STATE_DISCONNECTED:
{
if ((disc_cause != (HCI_ERR | HCI_ERR_REMOTE_USER_TERMINATE))&& (disc_cause != (HCI_ERR | HCI_ERR_LOCAL_HOST_TERMINATE)))
{
APP_PRINT_ERROR1("app_handle_conn_state_evt: connection lost cause 0x%x", disc_cause);
}
plxs_flags_clear();//when disconnect clear plxs flags
le_adv_start();
}
break;
}
}
* \endcode
*/
void plxs_flags_clear(void);
/**
* @brief plxs check report data send procedure to enable flow control of notification or indication
* @param[in] conn_id connection index
* @param[in] Service_id generated by the BLE stack: @ref T_SERVER_ID.
* @param[in] attribute_index attribute_index
*
* <b>Example usage</b>
* \code{.c}
T_APP_RESULT app_handle_profile_message(T_SERVER_ID service_id, void *p_data)
{
T_APP_RESULT result = APP_RESULT_SUCCESS;
if (service_id == SERVICE_PROFILE_GENERAL_ID)
{
T_SERVER_APP_CB_DATA *p_para = (T_SERVER_APP_CB_DATA *)p_data;
switch (p_para->eventId)
{
......
case PROFILE_EVT_SEND_DATA_COMPLETE:
......
else if (p_para->event_data.send_data_result.service_id == plxs_srv_id)
{
uint8_t conn_id = p_para->event_data.send_data_result.conn_id;
if (p_para->event_data.send_data_result.cause == GAP_SUCCESS)
{
plxs_check_report_data_send_procedure(conn_id, plxs_srv_id,p_para->event_data.send_data_result.attrib_idx);
}
else
{
APP_PRINT_ERROR1("PROFILE_EVT_SEND_DATA_COMPLETE failed,cause %x", p_para->event_data.send_data_result.cause);
}
}
break;
}
}
}
* \endcode
*/
void plxs_check_report_data_send_procedure(uint8_t conn_id, T_SERVER_ID service_id,
uint16_t attribute_index);
/** @} End of PLXS_Exported_Functions */
/** @} End of PLXS */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* PULSE_OXIMETER_SERVICE_H */
|