C语言随笔小算法:char字节流与结构体变量相互转换
代码:
/*
**数据域
*/
typedef struct
{
kal_uint8 bt_dpacket_data_total_num; //(可省略)数据项个数
kal_uint8 bt_dpacket_data_serial_num; //数据项编号
kal_uint8 bt_dpacket_data_len; //对应的数据项长度
kal_uint8 bt_dpacket_data_content[2]; //数据项内容
} STRUCT_BT_DPACKET_DATA;
/*
**蓝牙数据包解码出来的数据
**对应的结构体缓存字段,
*/
typedef struct
{
kal_uint8 bt_dpacket_decoder_type; //控制类型 1BYTE
kal_uint8 bt_dpacket_decoder_imei[8]; //IMEI 8BYTE
kal_uint8 bt_dpacket_decoder_ctrl_code; //控制码 1BYTE
kal_uint8 bt_dpacket_decoder_cmd; //命令码 1BYTE
kal_uint8 bt_dpacket_decoder_datalen[2]; //数据域长度 2BYTE
STRUCT_BT_DPACKET_DATA bt_dpacket_decoder_content; //数据域 5BYTE
kal_uint8 bt_dpacket_decoder_crc16[2]; //校验码 2BYTE
} STRUCT_BT_DPACKET_DECODER_DATA;
/*控制器类型对应编号*/
typedef enum
{
ctrler_begin = 0, //保留
ctrler_simple = 1, //普通定位
ctrler_high_precision = 2, //高精度定位
ctrler_simple_lock = 3, //普通定位+锁车
ctrler_high_precision_lock = 4, //高精度定位+锁车
ctrler_simple_lock_bt = 5, //普通定位+ 锁车
ctrler_high_precision_lock_bt = 6, //高精度定位+锁车+bt
ctrler_NUM_MAX
} enum_bt_diag_ctrler_type;
/*
*把字节流按照结构体样式解析出来
*返回结构体成员
*/
STRUCT_BT_DPACKET_DECODER_DATA* Track_cust_bt_dpacket_decoder
(
void* recv_data
)
{
kal_uint32 pre_index = 0;
kal_uint32 next_index = 0;
kal_uint8 *tem_recv_data = (kal_uint8*) recv_data;
STRUCT_BT_DPACKET_DECODER_DATA decoder_data_ex = {0};
STRUCT_BT_DPACKET_DECODER_DATA* decoder_data = &decoder_data_ex;
//kal_uint8 val[5] = {0};
kal_uint8 *data_content = (kal_uint8 *)malloc(sizeof(STRUCT_BT_DPACKET_DATA));
//kal_uint8 index_total_num = 0;
//kal_uint8 index_serial_num = 0;
//kal_uint8 index_data_len = 0;
if(data_content == NULL)
{
#if defined(TRACK_CUST_TRACE_BT_DPACKET)
LOGD(L_OS, L_V5, "%s,内存分配失败!", __FUNCTION__);
kal_prompt_trace(MOD_TST, "%s,内存分配失败!", __FUNCTION__);
#endif
return;
}
//控制器类型1BYTE
next_index = sizeof(decoder_data->bt_dpacket_decoder_type);
memcpy((kal_uint8*)(&(decoder_data->bt_dpacket_decoder_type)), (kal_uint8*)(tem_recv_data + pre_index), next_index);
pre_index += next_index;
#if defined(TRACK_CUST_TRACE_BT_DPACKET)
LOGD(L_OS, L_V5, "%s,decoder_data->bt_dpacket_decoder_type=%d", __FUNCTION__, \
decoder_data->bt_dpacket_decoder_type);
kal_prompt_trace(MOD_TST, "%s,decoder_data->bt_dpacket_decoder_type=%d", __FUNCTION__, \
decoder_data->bt_dpacket_decoder_type);
#endif
//IMEI 8BYTE
next_index = sizeof(decoder_data->bt_dpacket_decoder_imei);
memcpy(decoder_data->bt_dpacket_decoder_imei, (kal_uint8*)(tem_recv_data + pre_index), next_index);
pre_index += next_index;
#if defined(TRACK_CUST_TRACE_BT_DPACKET)
LOGD(L_OS, L_V5, "%s,decoder_data->bt_dpacket_decoder_imei=%d", __FUNCTION__, \
decoder_data->bt_dpacket_decoder_imei);
#endif
//控制码 1BYTE
next_index = sizeof(decoder_data->bt_dpacket_decoder_ctrl_code);
memcpy(&decoder_data->bt_dpacket_decoder_ctrl_code, (kal_uint8*)(tem_recv_data + pre_index), next_index);
pre_index += next_index;
#if defined(TRACK_CUST_TRACE_BT_DPACKET)
LOGD(L_OS, L_V5, "%s,decoder_data->bt_dpacket_decoder_ctrl_code=%d", __FUNCTION__, \
decoder_data->bt_dpacket_decoder_ctrl_code);
#endif
//命令码 1BYTE
next_index = sizeof(decoder_data->bt_dpacket_decoder_cmd);
memcpy(&decoder_data->bt_dpacket_decoder_cmd, (kal_uint8*)(tem_recv_data + pre_index), next_index);
pre_index += next_index;
#if defined(TRACK_CUST_TRACE_BT_DPACKET)
LOGD(L_OS, L_V5, "%s,decoder_data->bt_dpacket_decoder_cmd=%d", __FUNCTION__, \
decoder_data->bt_dpacket_decoder_cmd);
#endif
//数据域长度 2BYTE
next_index = sizeof(decoder_data->bt_dpacket_decoder_datalen);
memcpy(decoder_data->bt_dpacket_decoder_datalen, (kal_uint8*)(tem_recv_data + pre_index), next_index);
pre_index += next_index;
#if defined(TRACK_CUST_TRACE_BT_DPACKET)
LOGD(L_OS, L_V5, "%s,decoder_data->bt_dpacket_decoder_datalen=%d", __FUNCTION__, \
decoder_data->bt_dpacket_decoder_datalen);
#endif
//数据域 5BYTE
next_index = sizeof(decoder_data->bt_dpacket_decoder_content);
memcpy(data_content, (kal_uint8*)(tem_recv_data + pre_index), next_index);
//数据域结构体单独处理
decoder_data->bt_dpacket_decoder_content.bt_dpacket_data_total_num = \
data_content[0];
decoder_data->bt_dpacket_decoder_content.bt_dpacket_data_serial_num = data_content[1];
decoder_data->bt_dpacket_decoder_content.bt_dpacket_data_len = data_content[2];
memcpy(decoder_data->bt_dpacket_decoder_content.bt_dpacket_data_content, (kal_uint8*)(data_content + 3), \
sizeof(decoder_data->bt_dpacket_decoder_content.bt_dpacket_data_content));
pre_index += next_index;
#if defined(TRACK_CUST_TRACE_BT_DPACKET)
LOGD(L_OS, L_V5, "%s,decoder_data->bt_dpacket_decoder_content=%d", __FUNCTION__, \
decoder_data->bt_dpacket_decoder_content);
#endif
//校验码 2BYTE
next_index = sizeof(decoder_data->bt_dpacket_decoder_crc16);
memcpy(decoder_data->bt_dpacket_decoder_crc16, (kal_uint8*)(tem_recv_data + pre_index), next_index);
pre_index += next_index;
#if defined(TRACK_CUST_TRACE_BT_DPACKET)
LOGD(L_OS, L_V5, "%s,decoder_data->bt_dpacket_decoder_crc16=%d", __FUNCTION__, \
decoder_data->bt_dpacket_decoder_crc16);
#endif
free(data_content);
return decoder_data;
}
/*
** 解析蓝牙数据包ysheng
*/
STRUCT_BT_DPACKET_DECODER_DATA Track_cust_decode_bt_dpacket
(
void* recv_data
)
{
kal_uint32 recv_data_len = 0;
//STRUCT_BT_DPACKET_DECODER_DATA decoder_data_ex = {0};
STRUCT_BT_DPACKET_DECODER_DATA *decoder_data = NULL;//&decoder_data_ex;
BOOL crc16_ret = FALSE;
#if defined(TRACK_CUST_TRACE_BT_DPACKET)
LOGD(L_OS, L_V5, "Entry-->>%s", __FUNCTION__);
kal_prompt_trace(MOD_TST, "Entry-->>%s", __FUNCTION__);
#endif
//1.判断接收到的数据是否为空
if((kal_uint8*) recv_data == NULL)
{
#if defined(TRACK_CUST_TRACE_BT_DPACKET)
LOGD(L_OS, L_V5, "%s,recv_data为空!", __FUNCTION__);
kal_prompt_trace(MOD_TST, "%s,recv_data为空!", __FUNCTION__);
#endif
return;
}
/*2.先把数据解析出来,赋值给结构体变量*/
decoder_data = Track_cust_bt_dpacket_decoder((kal_uint8*)recv_data);
if(decoder_data == NULL)
{
#if defined(TRACK_CUST_TRACE_BT_DPACKET)
LOGD(L_OS, L_V5, "%s,decoder_data为空,数据解析出错!", __FUNCTION__);
kal_prompt_trace(MOD_TST, "%s,decoder_data为空,数据解析出错!", __FUNCTION__);
#endif
return;
}
/**3.crc16校验码,校验码是16位的话,
**则后两个字节为校验码
*/
//crc16_ret = IsCrc16Good((const U8*)(decoder_data->bt_dpacket_decoder_crc16),sizeof(decoder_data->bt_dpacket_decoder_crc16));
//if(!crc16_ret)
//{
#if defined(TRACK_CUST_TRACE_BT_DPACKET)
//LOGD(L_OS, L_V5, "%s,蓝牙诊断解析包crc16校验失败!",__FUNCTION__);
//kal_prompt_trace(MOD_TST, "%s,蓝牙诊断解析包crc16校验失败!",__FUNCTION__);
#endif
//return;
//}
/*4.判断控制器类型是否为
ctrler_simple_lock_bt
ctrler_high_precision_lock_bt
*/
if((decoder_data->bt_dpacket_decoder_type != ctrler_simple_lock_bt)\
&& (decoder_data->bt_dpacket_decoder_type != ctrler_high_precision_lock_bt)
)
{
#if defined(TRACK_CUST_TRACE_BT_DPACKET)
LOGD(L_OS, L_V5, "%s,蓝牙诊断:终端不支持蓝牙功能!", __FUNCTION__);
kal_prompt_trace(MOD_TST, "%s,蓝牙诊断:终端不支持蓝牙功能!", __FUNCTION__);
#endif
return;
}
/*5.判断命令码是否为01H或者02H,
因为蓝牙只有这两种任务序号*/
if(decoder_data->bt_dpacket_decoder_cmd != 1\
&& decoder_data->bt_dpacket_decoder_cmd != 2
)
{
#if defined(TRACK_CUST_TRACE_BT_DPACKET)
LOGD(L_OS, L_V5, "%s,蓝牙诊断:无此任务序号!", __FUNCTION__);
kal_prompt_trace(MOD_TST, "%s,蓝牙诊断:无此任务序号!", __FUNCTION__);
#endif
return;
}
/*其余解析出来的参数,
**暂时不在这里面判断了!
**注意,APP发送过来的包数据域的数据内容为应该为空
*/
return *decoder_data;
}
/*将结构体转化为字节流
**输入:packet_data
**输出:sendData
*/
void Track_cust_bt_dpacket_encoder(
kal_uint8 *sendData,
STRUCT_BT_DPACKET_DECODER_DATA *packet_data
)
{
kal_uint8 pre_index = 0;
kal_uint8 next_index = 0;
//kal_uint8 tmp_content[5] = {0};
//kal_uint8 *data_content = tmp_content;
kal_uint8 *data_content = (kal_uint8 *)malloc(sizeof(STRUCT_BT_DPACKET_DATA));
if(data_content == NULL)
{
#if defined(TRACK_CUST_TRACE_BT_DPACKET)
LOGD(L_OS, L_V5, "%s,内存分配失败!", __FUNCTION__);
kal_prompt_trace(MOD_TST, "%s,内存分配失败!", __FUNCTION__);
#endif
return;
}
//1.控制器类型打包 1B
next_index = sizeof(packet_data->bt_dpacket_decoder_type);
memcpy(sendData + pre_index, (kal_uint8*)(&(packet_data->bt_dpacket_decoder_type)), next_index);
pre_index += next_index;
#if defined(TRACK_CUST_TRACE_BT_DPACKET)
LOGD(L_OS, L_V5, "%s,packet_data->bt_dpacket_decoder_crc16=%d", __FUNCTION__, \
packet_data->bt_dpacket_decoder_crc16);
#endif
//2.IMEI 8B
next_index = sizeof(packet_data->bt_dpacket_decoder_imei);
memcpy(sendData + pre_index, (kal_uint8*)(packet_data->bt_dpacket_decoder_imei), next_index);
pre_index += next_index;
#if defined(TRACK_CUST_TRACE_BT_DPACKET)
LOGD(L_OS, L_V5, "%s,packet_data->bt_dpacket_decoder_imei=%d", __FUNCTION__, \
packet_data->bt_dpacket_decoder_imei);
#endif
//3.控制码 1B
next_index = sizeof(packet_data->bt_dpacket_decoder_ctrl_code);
memcpy(sendData + pre_index, (kal_uint8*)(&(packet_data->bt_dpacket_decoder_ctrl_code)), next_index);
pre_index += next_index;
#if defined(TRACK_CUST_TRACE_BT_DPACKET)
LOGD(L_OS, L_V5, "%s,packet_data->bt_dpacket_decoder_ctrl_code=%d", __FUNCTION__, \
packet_data->bt_dpacket_decoder_ctrl_code);
#endif
//4.命令码 1B
next_index = sizeof(packet_data->bt_dpacket_decoder_cmd);
memcpy(sendData + pre_index, (kal_uint8*)(&(packet_data->bt_dpacket_decoder_cmd)), next_index);
pre_index += next_index;
#if defined(TRACK_CUST_TRACE_BT_DPACKET)
LOGD(L_OS, L_V5, "%s,packet_data->bt_dpacket_decoder_ctrl_code=%d", __FUNCTION__, \
packet_data->bt_dpacket_decoder_ctrl_code);
#endif
//5.数据长度 1B
next_index = sizeof(packet_data->bt_dpacket_decoder_datalen);
memcpy(sendData + pre_index, (kal_uint8*)packet_data->bt_dpacket_decoder_datalen, next_index);
pre_index += next_index;
#if defined(TRACK_CUST_TRACE_BT_DPACKET)
LOGD(L_OS, L_V5, "%s,packet_data->bt_dpacket_decoder_datalen=%d", __FUNCTION__, \
packet_data->bt_dpacket_decoder_datalen);
#endif
//6.数据域5B
next_index = sizeof(packet_data->bt_dpacket_decoder_content);
data_content[0] = packet_data->bt_dpacket_decoder_content.bt_dpacket_data_total_num;
data_content[1] = packet_data->bt_dpacket_decoder_content.bt_dpacket_data_serial_num;
data_content[2] = packet_data->bt_dpacket_decoder_content.bt_dpacket_data_len;
memcpy((kal_uint8*)(data_content + 3), (kal_uint8*)packet_data->bt_dpacket_decoder_content.bt_dpacket_data_content, \
sizeof(packet_data->bt_dpacket_decoder_content.bt_dpacket_data_content));
memcpy(sendData + pre_index, (kal_uint8*)data_content, next_index);
pre_index += next_index;
#if defined(TRACK_CUST_TRACE_BT_DPACKET)
LOGD(L_OS, L_V5, "%s,packet_data->bt_dpacket_decoder_content=%d", __FUNCTION__, \
packet_data->bt_dpacket_decoder_content);
#endif
//7.校验码5B
next_index = sizeof(packet_data->bt_dpacket_decoder_crc16);
memcpy(sendData + pre_index, (kal_uint8*)packet_data->bt_dpacket_decoder_crc16, next_index);
pre_index += next_index;
#if defined(TRACK_CUST_TRACE_BT_DPACKET)
LOGD(L_OS, L_V5, "%s,packet_data->bt_dpacket_decoder_crc16=%d", __FUNCTION__, \
packet_data->bt_dpacket_decoder_crc16);
#endif
free(data_content);
return;
}
/*
** 封装蓝牙数据包,
** 将结构体转为字节流
** ysheng
*/
kal_uint8 * Track_cust_encode_bt_dpacket(
STRUCT_BT_DPACKET_DECODER_DATA *packet_data)
{
kal_uint8 len = sizeof(STRUCT_BT_DPACKET_DECODER_DATA);
kal_uint8 tem_send_data[20] = {0};
//函数返回指针的话,不能用动态分配内存...
kal_uint8 *sendData = tem_send_data;//(kal_uint8*)malloc(len);
#if defined(TRACK_CUST_TRACE_BT_DPACKET)
LOGD(L_OS, L_V5, "Entry-->>%s", __FUNCTION__);
kal_prompt_trace(MOD_TST, "Entry-->>%s", __FUNCTION__);
#endif
//格式化打包
Track_cust_bt_dpacket_encoder(sendData, packet_data);
/*以下判断senddata是否有效数据包,
**且是否加包头保卫及crc16编码
*/
{
//crc16编码
}
//free(sendData);
return sendData;
}
void main(void)
{
int i, val = 0;
STRUCT_BT_DPACKET_DECODER_DATA tmp_data = {0};
kal_uint8 *tem_send_data = 0;
kal_uint8 recv_data[20] =
{
0x05, // 控制器类型
//05 23 43 26 78 34 98 26 开头0需要特殊处理
0x05, 0x17, 0x2b, 0x1a, 0x4e, 0x22, 0x62, 0x1a, //IMEI
0x86, //控制码
0x01, //命令码01/02
0x00, 0x67, //数据长度103
0x01, //数据项个数
0x01, //数据项编号
0x03, //数据项长度
0x00, 0x01, //数据项内容
0xac, 0xd2 //crc16
};
//接口验证
tmp_data = Track_cust_decode_bt_dpacket(recv_data);
tem_send_data = Track_cust_encode_bt_dpacket(&tmp_data);
for(i = 0; i < 20; i++)
{
val = tem_send_data[i];
}
}