mcu_hi3321_watch/tjd/ble/data_link_layer/ble_protocol.c
2025-05-26 20:15:20 +08:00

196 lines
8.8 KiB
C

/*----------------------------------------------*
* 包含头文件 *
*----------------------------------------------*/
#include "wsf_types.h"
#include "wsf_trace.h"
#include "crc16.h"
#include "am_util_debug.h"
#include "sys_config.h"
#include "ble_management_server.h"
#include "ble_device_setup_server.h"
#include "ble_personal_info_server.h"
#include "ble_daily_health_data_server.h"
#include "ble_heart_rate_server.h"
#include "ble_sleep_server.h"
#include "ble_stress_server.h"
#include "ble_blood_oxygen_server.h"
#include "ble_exercise_server.h"
#include "ble_blood_pressure_server.h"
#include "ble_body_temp_server.h"
#include "ble_ota_server.h"
//#include "ble_file_trans.h"
#include "ble_message_server.h"
#include "ble_incoming_server.h"
#include "ble_music_server.h"
#include "ble_weather_server.h"
#include "ble_collect_data_server.h"
#include "ble_test_special_server.h"
#include "ble_multi_language_server.h"
#include "ble_gps_server.h"
#if (PRJ_FOR_FS_SPECIAL_TEST == ON)
#include "fs_test_server.h"
#endif
#include "ble_factory_command_server.h"
#include "ble_file_trans_server.h"
#include "ble_protocol.h"
#define ENABLE_STATIC_PRINT false
extern uint32_t am_util_stdio_printf(const char *pcFmt, ...);
#define static_print_remind(...) 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
typedef void (*user_protocol_handle_t)(uint8_t *data, uint16_t in_len, uint8_t *out_data, uint16_t *out_len);
typedef struct _service_handle
{
uint8_t service;
uint8_t cmd_max_id;
uint8_t func_num;
const p_func_t* func;
} user_protocol_service_t;
const static user_protocol_service_t m_user_protocol_services[] =
{
{ DEVICE_MANAGEMENT_SERVER, mamagement_server_max_ID, sizeof(user_manamagement_server_func)/sizeof(user_manamagement_server_func[0]), user_manamagement_server_func },
{ DEVICE_SETUP_SERVER, DEVICE_SETUP_SERVERE_MAX_ID, sizeof(DeviceSetupServerFunc) / sizeof(DeviceSetupServerFunc[0]), DeviceSetupServerFunc },
{ PERSON_INFO_SERVER, PERSONAL_INFO_SERVER_MAX_ID, sizeof(personal_info_server_func) / sizeof(personal_info_server_func[0]), personal_info_server_func },
{ DAILY_HEALTH_SERVER, DAILY_HEALTH_SERVERE_MAX_ID, sizeof(daily_health_server_func) / sizeof(daily_health_server_func[0]), daily_health_server_func },
{ HEART_RATE_SERVER, HEART_RATE_SERVER_MAX_ID, sizeof(heart_rate_server_func) / sizeof(heart_rate_server_func[0]), heart_rate_server_func },
{ SLEEP_SERVER, SLEEP_SERVERE_MAX_ID, sizeof(sleep_server_func) / sizeof(sleep_server_func[0]), sleep_server_func },
{ STRESS_SERVER, STRESS_SERVERE_MAX_ID, sizeof(stress_server_func) / sizeof(stress_server_func[0]), stress_server_func },
{ BLOOD_OXYGEN_SERVER, BLOOD_OXYGEN_SERVER_MAX_ID, sizeof(blood_oxygen_server_func) / sizeof(blood_oxygen_server_func[0]), blood_oxygen_server_func },
{ EXERCISE_SERVER, EXERCISE_SERVER_MAX_ID, sizeof(exercise_server_func) / sizeof(exercise_server_func[0]), exercise_server_func },
{ BLOOD_PRESSURE_SERVER, BLOOD_PRESSURE_SERVER_MAX_ID, sizeof(blood_pressure_server_func) / sizeof(blood_pressure_server_func[0]), blood_pressure_server_func },
{ BODY_TEMP_SERVER, BODY_TEMP_SERVER_MAX_ID, sizeof(body_temp_server_func) / sizeof(body_temp_server_func[0]), body_temp_server_func },
{ BLE_FILE_TRANS_SERVER, FILE_TRANS_ACTION_MAX, sizeof(FileTransServerFunc) / sizeof(FileTransServerFunc[0]), FileTransServerFunc },
{ TEST_SPECIAL_SERVER, TEST_SPECIAL_SERVERE_MAX_ID, sizeof(test_special_server_func) / sizeof(test_special_server_func[0]), test_special_server_func },
{ OTA_SERVER, Ota_server_max_ID, sizeof(user_Ota_server_func)/sizeof(user_Ota_server_func[0]), user_Ota_server_func },
{ MUSIC_SERVER, MUSIC_SERVERE_MAX_ID, sizeof(MusicServerFunc) / sizeof(MusicServerFunc[0]), MusicServerFunc },
{ INCOMING_SERVER, INCOMING_SERVERE_MAX_ID, sizeof(IncomingServerFunc) / sizeof(IncomingServerFunc[0]), IncomingServerFunc },
{ WEATHER_SERVER, WEATHER_SERVERE_MAX_ID, sizeof(WeatherServerFunc) / sizeof(WeatherServerFunc[0]), WeatherServerFunc },
{ MESSAGE_SERVER, MESSAGE_SERVERE_MAX_ID, sizeof(MessageServerFunc) / sizeof(MessageServerFunc[0]), MessageServerFunc },
{ GPS_SERVER, GPS_SERVERE_MAX_ID, sizeof(GpsServerFunc) / sizeof(GpsServerFunc[0]), GpsServerFunc },
{ MULTI_LANGUAGE_SERVER, MULTI_LANGUAGE_SERVERE_MAX_ID, sizeof(multiLanguageServerFunc) / sizeof(multiLanguageServerFunc[0]), multiLanguageServerFunc },
{ COLLECT_DATA_SERVER, COLLECT_DATA_SERVERE_MAX_ID, sizeof(collect_data_server_func) / sizeof(collect_data_server_func[0]), collect_data_server_func },
#if (PRJ_FOR_FS_SPECIAL_TEST == ON)
{ TEST_SPECIAL_SERVER, FS_TEST_SERVER_MAX_ID, sizeof(FsTestServerFunc) / sizeof(FsTestServerFunc[0]), FsTestServerFunc },
#endif
{FACTORY_COMMAND_SERVER, FACTORY_COMMAND_SERVERE_MAX_ID, sizeof(factory_command_server_func) / sizeof(factory_command_server_func[0]), factory_command_server_func },
};
void user_null_func(uint8_t *in_data,uint16_t in_len,uint8_t *out_data,uint16_t *out_len)
{
*out_len = 0;
}
/**
* add a new architecture to parse the ble protocol, for reducing code size
*
* @param server_id the server id of command
* @param common_id the command id of command
* @param data the source data of command
* @param in_len the length of source data
* @param out_data the data to send to the host
* @param out_len the length of data to send to the host
* @return
*/
bool user_protocol_parse(uint8_t server_id, uint8_t common_id, uint8_t *data, uint16_t in_len, uint8_t *out_data, uint16_t *out_len)
{
uint8_t idx = 0;
for (idx = 0; idx < sizeof(m_user_protocol_services)/sizeof(m_user_protocol_services[0]); ++idx)
{
const user_protocol_service_t* p_service = &m_user_protocol_services[idx];
if (server_id == p_service->service)
{
if (common_id < p_service->cmd_max_id)
{
if (user_null_func != p_service->func[common_id].func)
{
p_service->func[common_id].func(data, in_len, out_data, out_len);
return 0;
}
}
}
}
return 1;
}
/*!
* brief: 接收数据CRC校验
*/
uint8_t user_check_data_crc(uint8_t *data, uint16_t len)
{
uint16_t calculate_crc = 0;
uint16_t rev_crc = 0;
if(len < CRC_LEN)
{
return false;
}
rev_crc = data[len-2] << 8;
rev_crc += data[len-1];
calculate_crc = crc16(data, (len-2));
if(calculate_crc == rev_crc)
{
return true;
}
else
{
return false;
}
}
void user_data_crc(uint8_t *data, uint16_t len)
{
uint16_t crc = 0;
crc = crc16(data, (len-2));
data[len-2] = (crc >> 8) & 0xff;
data[len-1] = crc & 0xff;
}
void user_get_data_info(protocol_data_info_t *data_info, uint8_t **in_data, uint16_t *in_len)
{
data_info->len = *(*in_data)++;
if(data_info->len & 0x80)
{
data_info->len <<= 9;
data_info->len >>= 2;
data_info->len += *(*in_data)++;
data_info->len--;
(*in_len)--;
}
data_info->len -= 2;
data_info->type = *(*in_data)++;
data_info->p_data = *in_data;
}
uint16_t user_set_protocol_error(uint8_t *data, uint8_t errorServiceID, uint8_t errorCode)
{
uint16_t data_idx = 0;
data[data_idx++] = ERROR_LEN;
data[data_idx++] = ERROR_TYPE;
data[data_idx++] = errorServiceID;
data[data_idx++] = errorCode;
return data_idx;
}