/*---------------------------------------------------------------------------- * Copyright (c) Fenda Technologies Co., Ltd. 2021. All rights reserved. * * Description: ble_blood_pressure_server.c * * Author: shey.tanxiaoyu * * Create: 2021-09-13 *--------------------------------------------------------------------------*/ #include "ble_blood_pressure_server.h" #include "ble_data_transmission.h" #include "exercise_api.h" #include "health_api.h" #include "FreeRTOS.h" #include "task_ui.h" #define ENABLE_STATIC_PRINT 1 extern uint32_t am_util_stdio_printf(const char *pcFmt, ...); #define static_print_error(...) am_util_stdio_printf(__VA_ARGS__)//错误打印一般常开 #if ENABLE_STATIC_PRINT #define static_print_info(...) am_util_stdio_printf(__VA_ARGS__)//一般信息打印宏控制 #else #define static_print_info(...) #endif #define BP_DATA_FRAME_NUMBER_MAX 60 /* 4.0A.1 血压测量 */ void ble_set_bp_measure_sw(uint8_t *in_data, uint16_t in_len, uint8_t *out_data, uint16_t *out_len) { protocol_data_info_t data_info = {0}; uint16_t write_idx = 0; data_info.error = FENDA_SUCCESS; do { user_get_data_info(&data_info, &in_data, &in_len); switch (data_info.type & 0x7F) { case 0x01: break; case 0x02: break; default: break; } in_data = data_info.p_data; in_data += (data_info.len); in_len -= (2 + data_info.len); if (in_len > FRAM_MAX_SIZ) { in_len = 0; } } while (in_len); write_idx = user_set_protocol_error(out_data, BLOOD_PRESSURE_SERVER, data_info.error); *out_len = write_idx; } /* 4.0A.2 设备上传PPG信号 */ void ble_report_bp_measure_ppg_raw_data(void *p_buf) { } /* 4.0A.3 APP下发血压结果 */ void ble_set_bp_measure_result(uint8_t *in_data, uint16_t in_len, uint8_t *out_data, uint16_t *out_len) { protocol_data_info_t data_info = {0}; uint16_t write_idx = 0; data_info.error = FENDA_SUCCESS; do { user_get_data_info(&data_info, &in_data, &in_len); switch (data_info.type & 0x7F) { case 0x01: break; case 0x02: break; default: break; } in_data = data_info.p_data; in_data += (data_info.len); in_len -= (2 + data_info.len); if (in_len > FRAM_MAX_SIZ) { in_len = 0; } } while (in_len); write_idx = user_set_protocol_error(out_data, BLOOD_PRESSURE_SERVER, data_info.error); *out_len = write_idx; } /* 4.0A.4 APP获取血压数据帧数 */ void ble_get_bp_measure_frame_number(uint8_t *in_data, uint16_t in_len, uint8_t *out_data, uint16_t *out_len) { protocol_data_info_t data_info = {0}; uint32_t start_timestamp = 0; uint32_t end_timestamp = 0; uint32_t frame_num = 0; uint16_t write_idx = 0; uint8_t send_buf[10] = {0}; data_info.error = FENDA_SUCCESS; do { user_get_data_info(&data_info, &in_data, &in_len); switch (data_info.type & 0x7F) { case 0x01: start_timestamp += data_info.p_data[0] << 24; start_timestamp += data_info.p_data[1] << 16; start_timestamp += data_info.p_data[2] << 8; start_timestamp += data_info.p_data[3]; break; case 0x02: end_timestamp += data_info.p_data[0] << 24; end_timestamp += data_info.p_data[1] << 16; end_timestamp += data_info.p_data[2] << 8; end_timestamp += data_info.p_data[3]; health_api_bp_frame_number_get(BP_DATA_FRAME_NUMBER_MAX, start_timestamp, end_timestamp, &frame_num); send_buf[write_idx++] = 4; send_buf[write_idx++] = 0x03; send_buf[write_idx++] = frame_num >> 8; send_buf[write_idx++] = frame_num; BLE_SendFrameById(BLOOD_PRESSURE_SERVER, GET_BP_MEASURE_FRAME_NUMBER_ID, send_buf, write_idx); break; default: break; } in_data = data_info.p_data; in_data += (data_info.len); in_len -= (2 + data_info.len); if (in_len > FRAM_MAX_SIZ) { in_len = 0; } } while (in_len); *out_len = 0; } /* 4.0A.5 APP获取血压详细帧数据 */ void ble_get_bp_measure_frame_detail(uint8_t *in_data, uint16_t in_len, uint8_t *out_data, uint16_t *out_len) { protocol_data_info_t data_info = {0}; uint32_t frame_index = 0; uint32_t item_num = 0; health_bp_data_t item_buf[BP_DATA_FRAME_NUMBER_MAX] = {0}; uint16_t bp_data_len = 0; uint32_t i; uint16_t write_idx = 0; uint8_t *send_buf = NULL; send_buf = (uint8_t*)pvPortMalloc(sizeof(uint8_t) * 2048); if (send_buf == NULL) { static_print_info("ble_get_bp_measure_frame_detail send_buf malloc failed!!!\n"); data_info.error = REQ_MEMORY_ERROR; write_idx = user_set_protocol_error(out_data, BLOOD_PRESSURE_SERVER, data_info.error); *out_len = write_idx; return; } data_info.error = FENDA_SUCCESS; do { user_get_data_info(&data_info, &in_data, &in_len); switch (data_info.type & 0x7F) { case 0x01: frame_index += data_info.p_data[0] << 8; frame_index += data_info.p_data[1]; health_api_bp_frame_detail_get(BP_DATA_FRAME_NUMBER_MAX, frame_index, &item_num, item_buf); send_buf[write_idx++] = 9; send_buf[write_idx++] = 0x02; send_buf[write_idx++] = frame_index >> 8; send_buf[write_idx++] = frame_index; send_buf[write_idx++] = item_num >> 8; send_buf[write_idx++] = item_num; send_buf[write_idx++] = 18; send_buf[write_idx++] = 0xFF; send_buf[write_idx++] = 0x01; bp_data_len = 2 + 18 * item_num; if (bp_data_len <= 127) { send_buf[write_idx++] = bp_data_len; } else { bp_data_len += 1; send_buf[write_idx++] = 0x80 | (bp_data_len >> 7); send_buf[write_idx++] = bp_data_len & 0x7F; } send_buf[write_idx++] = 0x03; for (i = 0; i < item_num; i++) { send_buf[write_idx++] = item_buf[i].start_timestamp >> 24; send_buf[write_idx++] = item_buf[i].start_timestamp >> 16; send_buf[write_idx++] = item_buf[i].start_timestamp >> 8; send_buf[write_idx++] = item_buf[i].start_timestamp; send_buf[write_idx++] = item_buf[i].end_timestamp >> 24; send_buf[write_idx++] = item_buf[i].end_timestamp >> 16; send_buf[write_idx++] = item_buf[i].end_timestamp >> 8; send_buf[write_idx++] = item_buf[i].end_timestamp; send_buf[write_idx++] = item_buf[i].bp_sbp >> 8; send_buf[write_idx++] = item_buf[i].bp_sbp; send_buf[write_idx++] = item_buf[i].bp_dbp; send_buf[write_idx++] = item_buf[i].bp_map; send_buf[write_idx++] = item_buf[i].bp_pr; send_buf[write_idx++] = item_buf[i].bp_lvl; send_buf[write_idx++] = item_buf[i].bp_measure_scene >> 24; send_buf[write_idx++] = item_buf[i].bp_measure_scene >> 16; send_buf[write_idx++] = item_buf[i].bp_measure_scene >> 8; send_buf[write_idx++] = item_buf[i].bp_measure_scene; } static_print_info("ble_get_bp_measure_frame_detail ***write_idx %d\n", write_idx); BLE_SendFrameById(BLOOD_PRESSURE_SERVER, GET_BP_MEASURE_FRAME_DETAIL_ID, send_buf, write_idx); break; default: break; } in_data = data_info.p_data; in_data += (data_info.len); in_len -= (2 + data_info.len); if (in_len > FRAM_MAX_SIZ) { in_len = 0; } } while (in_len); vPortFree(send_buf); *out_len = 0; } /* 4.0A.6 APP开启气泵血压测试 */ void ble_set_bp_measure_switch(uint8_t *in_data, uint16_t in_len, uint8_t *out_data, uint16_t *out_len) { protocol_data_info_t data_info = {0}; uint8_t measure_sw = 0; uint8_t measure_type = 0; uint32_t measure_sence = 0; uint16_t write_idx = 0; data_info.error = FENDA_SUCCESS; do { user_get_data_info(&data_info, &in_data, &in_len); switch (data_info.type & 0x7F) { case 0x01: measure_sw = data_info.p_data[0]; break; case 0x02: measure_type = data_info.p_data[0]; break; case 0x03: measure_sence += data_info.p_data[0] << 24; measure_sence += data_info.p_data[1] << 16; measure_sence += data_info.p_data[2] << 8; measure_sence += data_info.p_data[3]; if ((health_api_get_bp_measure_sw() == 0) && (exercise_api_exercise_state_get() == 0 || exercise_api_exercise_state_get() == 4)) { task_ui_notify(EVENT_BLOOD_PRESSURE_MEASURE_SWITCH, 0, NULL, 0); } else { data_info.error = UNKNOW_ERROR; } break; default: break; } in_data = data_info.p_data; in_data += (data_info.len); in_len -= (2 + data_info.len); if (in_len > FRAM_MAX_SIZ) { in_len = 0; } } while (in_len); write_idx = user_set_protocol_error(out_data, BLOOD_PRESSURE_SERVER, data_info.error); *out_len = write_idx; } /* 4.0A.7 设备上报气泵血压测试结果 */ void ble_report_bp_measure_result(uint8_t bp_measure_sta) { uint16_t write_idx = 0; uint8_t send_buf[140] = {0}; health_cache_t *p_health_cache = health_api_get_health_cache_ptr(); send_buf[write_idx++] = 3; send_buf[write_idx++] = 0x01; send_buf[write_idx++] = bp_measure_sta; send_buf[write_idx++] = 6; send_buf[write_idx++] = 0x02; send_buf[write_idx++] = p_health_cache->bp_data.start_timestamp >> 24; send_buf[write_idx++] = p_health_cache->bp_data.start_timestamp >> 16; send_buf[write_idx++] = p_health_cache->bp_data.start_timestamp >> 8; send_buf[write_idx++] = p_health_cache->bp_data.start_timestamp; send_buf[write_idx++] = 6; send_buf[write_idx++] = 0x03; send_buf[write_idx++] = p_health_cache->bp_data.end_timestamp >> 24; send_buf[write_idx++] = p_health_cache->bp_data.end_timestamp >> 16; send_buf[write_idx++] = p_health_cache->bp_data.end_timestamp >> 8; send_buf[write_idx++] = p_health_cache->bp_data.end_timestamp; send_buf[write_idx++] = 4; send_buf[write_idx++] = 0x04; send_buf[write_idx++] = p_health_cache->bp_data.bp_sbp >> 8; send_buf[write_idx++] = p_health_cache->bp_data.bp_sbp; send_buf[write_idx++] = 3; send_buf[write_idx++] = 0x05; send_buf[write_idx++] = p_health_cache->bp_data.bp_dbp; send_buf[write_idx++] = 3; send_buf[write_idx++] = 0x06; send_buf[write_idx++] = p_health_cache->bp_data.bp_map; send_buf[write_idx++] = 3; send_buf[write_idx++] = 0x07; send_buf[write_idx++] = p_health_cache->bp_data.bp_pr; send_buf[write_idx++] = 3; send_buf[write_idx++] = 0x08; send_buf[write_idx++] = p_health_cache->bp_data.bp_lvl; send_buf[write_idx++] = 6; send_buf[write_idx++] = 0x09; send_buf[write_idx++] = p_health_cache->bp_data.bp_measure_scene >> 24; send_buf[write_idx++] = p_health_cache->bp_data.bp_measure_scene >> 16; send_buf[write_idx++] = p_health_cache->bp_data.bp_measure_scene >> 8; send_buf[write_idx++] = p_health_cache->bp_data.bp_measure_scene; BLE_SendFrameById(BLOOD_PRESSURE_SERVER, REPORT_BP_MEASURE_RESULT_ID, send_buf, write_idx); } const p_func_t blood_pressure_server_func[BLOOD_PRESSURE_SERVER_MAX_ID] = { user_null_func, ble_set_bp_measure_sw, //4.0A.1 血压测量 user_null_func, //4.0A.2 设备上传PPG信号 ble_set_bp_measure_result, //4.0A.3 APP下发血压结果 ble_get_bp_measure_frame_number, //4.0A.4 APP获取血压数据帧数 ble_get_bp_measure_frame_detail, //4.0A.5 APP获取血压详细帧数据 ble_set_bp_measure_switch, //4.0A.6 APP开启气泵血压测试 user_null_func, //4.0A.7 设备上报气泵血压测试结果 };