AP05/uart_can/uart_can.c
2025-07-04 09:13:31 +08:00

746 lines
26 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "uart_can.h"
#include "uart_utils.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#define PRINT_TIME_TAG
#define DBG_TAG "uart_can"
#define DBG_LVL DBG_INFO
#include "debug_print.h"
uint16_t CRC16_APOTA( unsigned char * pdat, unsigned int len)
{
const uint16_t CRC_16_IBM_TableOTA[16] =
{
0x0000, 0x8005, 0x800F, 0x000A, 0x801B, 0x001E, 0x0014, 0x8011,
0x8033, 0x0036, 0x003C, 0x8039, 0x0028, 0x802D, 0x8027, 0x0022
};
uint16_t i, j;
uint16_t crc = 0xffff;
uint8_t val;
for (i = 0; i < len; i++)
{
val = pdat[i];
for(j = 0; j < 2; j++)
{
crc = (crc << 4) ^ CRC_16_IBM_TableOTA[(((crc >> 8) ^ val) >> 4) & 0x0F];
val <<= 4;
}
}
return (crc);
}
uint16_t CRC16_XMODEM(uint8_t *puchMsg, uint32_t usDataLen)
{
uint16_t wCRCin = 0x0000;
uint16_t wCPoly = 0x1021;
uint8_t wChar = 0;
while (usDataLen--) {
wChar = *(puchMsg++);
wCRCin ^= (wChar << 8);
for (int i = 0; i < 8; i++) {
if (wCRCin & 0x8000) {
wCRCin = (wCRCin << 1) ^ wCPoly;
} else {
wCRCin = wCRCin << 1;
}
}
}
return (wCRCin);
}
int uart_data_send_head_apota(uart_utils_t *uart,uint32_t datalen,uint16_t packagenum){
int ret = 0;
jt_apota_package_t jt_apota_package ={
.head=ntohl(0x404F5441),//@OTA
.len1=(datalen>>16)&0xFF,
.len2=(datalen>>8)&0xFF,
.len3=datalen&0xFF,
.packagenum=ntohs(packagenum),
.reserve=ntohs(0x0000),
};
LOG_I("%s:HEAD:%08x,%02x,%02x,%02x,%04x,%04x\r\n",__func__,jt_apota_package.head,
jt_apota_package.len1,jt_apota_package.len2,jt_apota_package.len3,jt_apota_package.packagenum,jt_apota_package.reserve);
if (uart == NULL){
LOG_I("uart NULL pointer\n");
ret = -1;
goto error;
}
if(sizeof(jt_apota_package) == write(uart->uart_fd, &jt_apota_package, sizeof(jt_apota_package))){
ret = 0;
//LOG_I("%s success\n",__func__);
}else{
//LOG_I("%s fail\n", __func__);
ret = -2;
goto error;
}
error:
return ret;
return 0;
}
int uart_data_send_head_ledota(uart_utils_t *uart,uint32_t datalen,uint16_t datacrc,uint16_t version){
int ret = 0;
jt_ledota_package_t jt_ledota_package ={
.head=ntohl(0x404F5457),//@OTW
.len1=(datalen>>16)&0xFF,
.len2=(datalen>>8)&0xFF,
.len3=datalen&0xFF,
.data_crc=ntohs(datacrc),
.hdinfo=0x21,
.sfinfo=ntohs(version),
.custom_code=ntohs(0x0003),
.mode=0xF8,
#if 1
.startmac1=0x00,
.startmac2=0x00,
.startmac3=0x00,
.endmac1=0xff,
.endmac2=0xff,
.endmac3=0xff,
#else
.startmac1=0xfe,
.startmac2=0x64,
.startmac3=0xa8,
.endmac1=0xfe,
.endmac2=0x64,
.endmac3=0xa8,
#endif
};
LOG_I("%s:HEAD:%08x,%02x,%02x,%02x,%04x,%02x,%04x,%04x,%02x,%02x,%02x,%02x,%02x,%02x,%02x\r\n",__func__,jt_ledota_package.head,
jt_ledota_package.len1,jt_ledota_package.len2,jt_ledota_package.len3,jt_ledota_package.data_crc,jt_ledota_package.hdinfo,
jt_ledota_package.sfinfo,jt_ledota_package.custom_code,jt_ledota_package.mode,jt_ledota_package.startmac1,
jt_ledota_package.startmac2,jt_ledota_package.startmac3,jt_ledota_package.endmac1,jt_ledota_package.endmac2,
jt_ledota_package.endmac3);
if (uart == NULL){
LOG_I("uart NULL pointer\n");
ret = -1;
goto error;
}
if(sizeof(jt_ledota_package) == write(uart->uart_fd, &jt_ledota_package, sizeof(jt_ledota_package))){
ret = 0;
//LOG_I("%s success\n",__func__);
}else{
//LOG_I("%s fail\n", __func__);
ret = -2;
goto error;
}
usleep(100*1000);
error:
return ret;
return 0;
}
int uart_data_send_ledota(uart_utils_t *uart,char *data,int size){
int ret=0;
if(size==write(uart->uart_fd,data,size)){
LOG_I("write size:%d success\n",size);
}else{
LOG_I("write size:%d fail\n",size);
}
usleep(500*1000);
return ret;
}
int uart_data_send_apota(uart_utils_t *uart,uint8_t dataori[],int datalen,uint16_t pindex,uint16_t datacrc){
int ret = 0;
int sendlen = 0;
jt_apota_data_package_t jt_apota_data_package ={
.start=0x24,//$
.len1=(datalen>>16)&0xFF,
.len2=(datalen>>8)&0xFF,
.len3=datalen&0xFF,
.packageindex=ntohs(pindex),
//.data=dataori,
.data_crc=ntohs(datacrc),
};
if(datalen>2048){
sendlen=2048;
}else{
sendlen=datalen;
}
memcpy(jt_apota_data_package.data,dataori,sendlen);
if (uart == NULL){
LOG_I("uart NULL pointer\n");
ret = -1;
goto error;
}
if(sizeof(jt_apota_data_package) == write(uart->uart_fd, &jt_apota_data_package, sizeof(jt_apota_data_package))){
ret = 0;
LOG_I("%s success\n",__func__);
}else{
LOG_I("%s fail\n", __func__);
ret = -2;
goto error;
}
error:
return ret;
return 0;
}
int uart_data_send_head_lighton(uart_utils_t *uart,uint8_t wakeup_time,uint16_t tag_num){
int ret = 0;
uint8_t data_len = 8 + tag_num * 4 + 2;
jt_head_package_t jt_head_package ={
.pre=0x2323,//# 0x23 $ 0x24
.wakeupTime=wakeup_time,//5s,<120s
.func='A',
.len1=0x0000,
.len2=data_len,
.reserve=ntohs(0x0003),
.lableNum=ntohs(tag_num),
};
LOG_I("%s:HEAD:%04x,%02x,%02x,%04x,%02x,%04x,%04x\r\n",__func__,jt_head_package.pre,jt_head_package.wakeupTime,jt_head_package.func,
jt_head_package.len1,jt_head_package.len2,jt_head_package.reserve,jt_head_package.lableNum);
if (uart == NULL){
LOG_I("uart NULL pointer\n");
ret = -1;
goto error;
}
if(sizeof(jt_head_package) == write(uart->uart_fd, &jt_head_package, sizeof(jt_head_package))){
ret = 0;
//LOG_I("%s success\n",__func__);
}else{
//LOG_I("%s fail\n", __func__);
ret = -2;
goto error;
}
error:
return ret;
return 0;
}
int uart_data_send_head_lableup(uart_utils_t *uart, uint8_t wakeup_time, uint16_t tag_num) {
int ret = 0;
uint8_t data_len = 16 + (tag_num > 0 ? (tag_num - 1) * 11 : 0); // 兼容原协议
jt_head_package_t jt_head_package = {
.pre = 0x2323,
.wakeupTime = wakeup_time,
.func = 'B',
.len1 = 0x0000,
.len2 = data_len,
.reserve = ntohs(0x0003),
.lableNum = ntohs(tag_num),
};
LOG_I("%s:HEAD:%04x,%02x,%02x,%04x,%02x,%04x,%04x\r\n", __func__, jt_head_package.pre, jt_head_package.wakeupTime, jt_head_package.func,
jt_head_package.len1, jt_head_package.len2, jt_head_package.reserve, jt_head_package.lableNum);
if (uart == NULL) {
LOG_I("uart NULL pointer\n");
ret = -1;
goto error;
}
if (sizeof(jt_head_package) == write(uart->uart_fd, &jt_head_package, sizeof(jt_head_package))) {
ret = 0;
} else {
ret = -2;
goto error;
}
error:
return ret;
}
int uart_data_send_head_lightonrule(uart_utils_t *uart,uint8_t wakeup_time){
int ret = 0;
if (uart == NULL){
LOG_I("uart NULL pointer\n");
ret = -1;
goto error;
}
jt_head_package_t jt_head_package ={
.pre=0x2323,//# 0x23 $ 0x24
.wakeupTime=wakeup_time,//5s,<120s
.func='C',
.len1=0x0000,
.len2=20,
.reserve=ntohs(0x0003),
.lableNum=ntohs(0x0001),
};
LOG_I("%s:HEAD:%04x,%02x,%02x,%04x,%02x,%04x,%04x\r\n",__func__,jt_head_package.pre,jt_head_package.wakeupTime,jt_head_package.func,
jt_head_package.len1,jt_head_package.len2,jt_head_package.reserve,jt_head_package.lableNum);
if(sizeof(jt_head_package) == write(uart->uart_fd, &jt_head_package, sizeof(jt_head_package))){
ret = 0;
//LOG_I("%s success\n",__func__);
}else{
//LOG_I("%s fail\n", __func__);
ret = -2;
goto error;
}
error:
return ret;
return 0;
}
int uart_data_send_head_search(uart_utils_t *uart,uint8_t wakeup_time){
int ret = 0;
if (uart == NULL){
LOG_I("uart NULL pointer\n");
ret = -1;
goto error;
}
jt_head_package_t jt_head_package ={
.pre=0x2323,//# 0x23 $ 0x24
.wakeupTime=wakeup_time,//5s,<120s
.func='D',
.len1=0x0000,
.len2=13,
.reserve=ntohs(0x0003),
.lableNum=ntohs(0x0001),
};
LOG_I("%s:HEAD:%04x,%02x,%02x,%04x,%02x,%04x,%04x\r\n",__func__,jt_head_package.pre,jt_head_package.wakeupTime,jt_head_package.func,
jt_head_package.len1,jt_head_package.len2,jt_head_package.reserve,jt_head_package.lableNum);
if(sizeof(jt_head_package) == write(uart->uart_fd, &jt_head_package, sizeof(jt_head_package))){
ret = 0;
//LOG_I("%s success\n",__func__);
}else{
//LOG_I("%s fail\n", __func__);
ret = -2;
goto error;
}
error:
return ret;
return 0;
}
int uart_data_send_search(uart_utils_t *uart,uint8_t lable_1,uint8_t lable_2,uint8_t lable_3,uint8_t lable_4,uint8_t lable_5,
uint8_t lable_6,uint8_t lable_7,uint8_t lable_8){
int ret = 0;
if (uart == NULL){
LOG_I("uart NULL pointer\n");
ret = -1;
goto error;
}
uint8_t test1[11] = {0x00,0x00,10,lable_1,lable_2,lable_3,lable_4,lable_5,lable_6,lable_7,lable_8};
uint16_t crc_c=CRC16_XMODEM(test1,sizeof(test1));
for(int i=0;i<11;i++){
printf("%02x ",test1[i]);
}
LOG_I("\r\n");
LOG_I("%s XModem_CRC16 = %04x\r\n",__func__,crc_c);
jt_search_package_t jt_search_package ={
.len1=0x0000,
.len2=10,
.lable3_1=lable_1,
.lable3_2=lable_2,
.lable3_3=lable_3,
.lable3_4=lable_4,
.lable3_5=lable_5,
.lable3_6=lable_6,
.lable3_7=lable_7,
.lable3_8=lable_8,
.crc=ntohs(crc_c),
};
#if 1
if(sizeof(jt_search_package) == write(uart->uart_fd, &jt_search_package, sizeof(jt_search_package))){
ret = 0;
//LOG_I("%s success\n",__func__);
}else{
//LOG_I("%s fail\n", __func__);
ret = -2;
goto error;
}
#endif
error:
return ret;
return 0;
}
int uart_data_send_light_rule(uart_utils_t *uart,uint8_t lable_1,uint16_t lable_2,uint32_t lable_3,
uint8_t lable_1_rule, uint8_t lable_2_rule, uint8_t lable_3_rule,
uint8_t led_ctrl, uint16_t flash_i, uint16_t light_d){
int ret = 0;
if (uart == NULL){
LOG_I("uart NULL pointer\n");
ret = -1;
goto error;
}
uint8_t lable_2_1=(lable_2>>8)&0xFF;
uint8_t lable_2_2=(lable_2)&0xFF;
uint8_t lable_3_1=(lable_3>>24)&0xFF;
uint8_t lable_3_2=(lable_3>>16)&0xFF;
uint8_t lable_3_3=(lable_3>>8)&0xFF;
uint8_t lable_3_4=(lable_3)&0xFF;
uint8_t flash_i_1=(flash_i>>8)&0xFF;
uint8_t flash_i_2=(flash_i)&0xFF;
uint8_t light_d_1=(light_d>>8)&0xFF;
uint8_t light_d_2=(light_d)&0xFF;
uint8_t test1[18] = {0x00,0x00,17,lable_1,lable_2_1,lable_2_2,lable_3_1,lable_3_2,lable_3_3,lable_3_4,
lable_1_rule,lable_2_rule,lable_3_rule,led_ctrl,flash_i_1,flash_i_2,light_d_1,light_d_2};
uint16_t crc_c=CRC16_XMODEM(test1,sizeof(test1));
for(int i=0;i<18;i++){
printf("%02x ",test1[i]);
}
LOG_I("\r\n");
LOG_I("%s XModem_CRC16 = %04x\r\n",__func__,crc_c);
jt_light_rule_package_t jt_light_rule_package ={
.len1=0x0000,
.len2=17,
.lable1=lable_1,
.lable2=ntohs(lable_2),
.lable3=ntohl(lable_3),
.lable1_rule=lable_1_rule,
.lable2_rule=lable_2_rule,
.lable3_rule=lable_3_rule,
.ledctrl=led_ctrl,
.flash_i=ntohs(flash_i),
.light_d=ntohs(light_d),
.crc=ntohs(crc_c),
};
if(sizeof(jt_light_rule_package) == write(uart->uart_fd, &jt_light_rule_package, sizeof(jt_light_rule_package))){
ret = 0;
//LOG_I("%s success\n",__func__);
}else{
//LOG_I("%s fail\n", __func__);
ret = -2;
goto error;
}
error:
return ret;
return 0;
}
int uart_data_send_lable(uart_utils_t *uart, uint32_t tags[], uint8_t lable1[], uint16_t lable2[], uint32_t lable3[], uint32_t tag_num) {
int ret = 0;
if (uart == NULL) {
LOG_I("uart NULL pointer\n");
return -1;
}
if (tag_num > MAX_LABEL_NUM) tag_num = MAX_LABEL_NUM;
uint8_t data_len = 16 + (tag_num > 0 ? (tag_num - 1) * 11 : 0); // 和头部一致
uint8_t *buf = (uint8_t *)malloc(data_len);
if (!buf) return -2;
memset(buf, 0, data_len);
buf[0] = 0x00; // len1
buf[1] = 0x00; // len2
buf[2] = data_len - 3; // 数据区长度不含len1/len2/len3
for (uint32_t i = 0; i < tag_num; ++i) {
int base = 3 + i * 11;
buf[base + 0] = (tags[i] >> 24) & 0xFF;
buf[base + 1] = (tags[i] >> 16) & 0xFF;
buf[base + 2] = (tags[i] >> 8) & 0xFF;
buf[base + 3] = tags[i] & 0xFF;
buf[base + 4] = lable1[i];
buf[base + 5] = (lable2[i] >> 8) & 0xFF;
buf[base + 6] = lable2[i] & 0xFF;
buf[base + 7] = (lable3[i] >> 24) & 0xFF;
buf[base + 8] = (lable3[i] >> 16) & 0xFF;
buf[base + 9] = (lable3[i] >> 8) & 0xFF;
buf[base + 10] = lable3[i] & 0xFF;
}
uint16_t crc_c = CRC16_XMODEM(buf, data_len - 2);
buf[data_len - 2] = (crc_c >> 8) & 0xFF;
buf[data_len - 1] = crc_c & 0xFF;
// 打印即将发送的数据内容
printf("[uart_data_send_lable] send: ");
for (int i = 0; i < data_len; ++i) {
printf("%02X ", buf[i]);
}
printf("\n");
int write_ret = write(uart->uart_fd, buf, data_len);
LOG_I("[uart_data_send_lable] write_ret=%d, data_len=%d", write_ret, data_len);
if (write_ret == data_len) ret = 0; else ret = -3;
free(buf);
return ret;
}
int uart_data_send_lighton(uart_utils_t *uart,uint8_t ledctl,uint16_t flash_i,uint16_t light_d,
uint32_t tag_1,uint32_t tag_2,uint32_t tag_3,uint32_t tag_4,uint32_t tag_5,
uint32_t tag_6,uint32_t tag_7,uint32_t tag_8,uint32_t tag_9,uint32_t tag_10,
uint32_t tag_11,uint32_t tag_12,uint32_t tag_13,uint32_t tag_14,uint32_t tag_15,
uint32_t tag_16,uint32_t tag_17,uint32_t tag_18,uint32_t tag_19,uint32_t tag_20,
uint32_t tag_21,uint32_t tag_22,uint32_t tag_23,uint32_t tag_24,uint32_t tag_25,
uint32_t tag_26,uint32_t tag_27,uint32_t tag_28,uint32_t tag_29,uint32_t tag_30,
uint32_t tag_num){
int ret = 0;
if (uart == NULL){
LOG_I("uart NULL pointer\n");
ret = -1;
goto error;
}
uint8_t flash_i_h=(flash_i>>8)&0xFF;
uint8_t flash_i_l=(flash_i)&0xFF;
uint8_t light_d_h=(light_d>>8)&0xFF;
uint8_t light_d_l=(light_d)&0xFF;
// 计算数据包长度:基础长度(7) + tag数量 * 4 + CRC(2)
uint8_t data_len = 8 + tag_num * 4 + 2;
uint8_t *buf = (uint8_t *)malloc(data_len);
if (buf == NULL) {
LOG_I("malloc failed\n");
ret = -3;
goto error;
}
memset(buf, 0, data_len);
// 填充基础数据
buf[0] = 0x00; buf[1] = 0x00; // len1
buf[2] = data_len - 3; // len2 (修改减去3因为len2不包含CRC和len1、len2本身)
buf[3] = ledctl; // ledCtr
buf[4] = flash_i_h; // flashInterval
buf[5] = flash_i_l;
buf[6] = light_d_h; // lightDuration
buf[7] = light_d_l;
// 填充tag数据
uint32_t tags_array[30] = {tag_1, tag_2, tag_3, tag_4, tag_5, tag_6, tag_7, tag_8, tag_9, tag_10,
tag_11, tag_12, tag_13, tag_14, tag_15, tag_16, tag_17, tag_18, tag_19, tag_20,
tag_21, tag_22, tag_23, tag_24, tag_25, tag_26, tag_27, tag_28, tag_29, tag_30};
for (int i = 0; i < tag_num; ++i) {
buf[8 + i * 4] = (tags_array[i] >> 24) & 0xFF;
buf[9 + i * 4] = (tags_array[i] >> 16) & 0xFF;
buf[10 + i * 4] = (tags_array[i] >> 8) & 0xFF;
buf[11 + i * 4] = tags_array[i] & 0xFF;
}
// 计算CRC - 计算除了CRC本身之外的所有数据
uint16_t crc_c = CRC16_XMODEM(buf, data_len - 2);
buf[data_len - 2] = (crc_c >> 8) & 0xFF;
buf[data_len - 1] = crc_c & 0xFF;
// 打印CRC计算详情
printf("[uart_data_send_lighton] CRC calculation: ");
for (int i = 0; i < data_len - 2; ++i) {
printf("%02X ", buf[i]);
}
printf(" -> CRC: %04X\n", crc_c);
// 打印发送数据内容
printf("[uart_data_send_lighton] send: ");
for (int i = 0; i < data_len; ++i) {
printf("%02X ", buf[i]);
}
printf("\n");
// 发送数据
int write_ret = write(uart->uart_fd, buf, data_len);
LOG_I("[uart_data_send_lighton] write_ret=%d, data_len=%d", write_ret, data_len);
if (write_ret == data_len) ret = 0; else ret = -4;
free(buf);
DEBUG_TX("lightsnNum = %d\n", tag_num);
for(int i=0;i<tag_num;i++) {
DEBUG_TX("tag%d = %08X\n", i+1, tags_array[i]);
}
error:
return ret;
}
int uart_data_receive_version(uart_utils_t *uart){
int ret = 0;
jt_receive_version_package_t jt_receive_version_package;
ret = uart_read_until_time(uart->uart_fd,(char *)&jt_receive_version_package,sizeof(jt_receive_version_package_t), 1000, 50);
if(ret == sizeof(jt_receive_version_package_t)){
LOG_I("%s success:%04x,%04x\n", __func__,jt_receive_version_package.v1,jt_receive_version_package.v2);
}else{
LOG_I("%s, failed, time out\n", __func__);
ret = -1;
}
return ret;
}
int uart_data_receive_ack(uart_utils_t *uart,uint16_t *parm_ack){
int ret = 0;
jt_receive_package_t jt_receive_package;
ret = uart_read_until_time(uart->uart_fd,(char *)&jt_receive_package,sizeof(jt_receive_package_t), 1000, 50);
if(ret == sizeof(jt_receive_package_t)){
LOG_I("%s success:%04x,%04x,%04x,%04x\n", __func__,jt_receive_package.pre1,jt_receive_package.pre2,
jt_receive_package.pre3,jt_receive_package.ack);
if((jt_receive_package.pre1 == 0x2424)
&&(jt_receive_package.pre2 == 0x2424)
&&(jt_receive_package.pre3 == 0x2424)){
*parm_ack=jt_receive_package.ack;
}else{
LOG_I("%s failed\n", __func__);
ret = -2;
}
}else{
LOG_I("%s, failed, time out\n", __func__);
ret = -1;
}
return ret;
}
int uart_data_receive_data_back(uart_utils_t *uart,uint16_t *parmAck,uint32_t *tagCode,uint8_t *tagSignal,
uint8_t *totalLen,uint8_t *tagFeature,uint8_t *count,uint16_t *batteryV,uint16_t *version,uint8_t *ledCtrl,
uint8_t *lable1,uint16_t *lable2,uint32_t *lable3){
int ret = 0;
jt_data_back_package_t jt_data_back_package;
ret = uart_read_until_time(uart->uart_fd,(char *)&jt_data_back_package,sizeof(jt_data_back_package_t), 1000, 50);
if(ret == sizeof(jt_data_back_package_t)){
//LOG_I("%s success\n", __func__);
if((jt_data_back_package.pre1 == 0x2424)
&&(jt_data_back_package.pre2 == 0x2424)
&&(jt_data_back_package.pre3 == 0x2424)){
uint8_t pre4_1=(jt_data_back_package.pre4>>8)&0xFF;
uint8_t pre4_2=(jt_data_back_package.pre4)&0xFF;
uint8_t tagCode_1=(ntohl(jt_data_back_package.tag)>>24)&0xFF;
uint8_t tagCode_2=(ntohl(jt_data_back_package.tag)>>16)&0xFF;
uint8_t tagCode_3=(ntohl(jt_data_back_package.tag)>>8)&0xFF;
uint8_t tagCode_4=(ntohl(jt_data_back_package.tag))&0xFF;
uint8_t battery_1=(ntohs(jt_data_back_package.battery)>>8)&0xFF;
uint8_t battery_2=(ntohs(jt_data_back_package.battery))&0xFF;
uint8_t version_1=(ntohs(jt_data_back_package.version)>>8)&0xFF;
uint8_t version_2=(ntohs(jt_data_back_package.version))&0xFF;
uint8_t lable2_1=(ntohs(jt_data_back_package.lable2)>>8)&0xFF;
uint8_t lable2_2=(ntohs(jt_data_back_package.lable2))&0xFF;
uint8_t lable3_1=(ntohl(jt_data_back_package.lable3)>>24)&0xFF;
uint8_t lable3_2=(ntohl(jt_data_back_package.lable3)>>16)&0xFF;
uint8_t lable3_3=(ntohl(jt_data_back_package.lable3)>>8)&0xFF;
uint8_t lable3_4=(ntohl(jt_data_back_package.lable3))&0xFF;
uint8_t test1[15] = {jt_data_back_package.len,jt_data_back_package.featureCode,
jt_data_back_package.count,battery_1,battery_2,version_1,version_2,jt_data_back_package.ledCtrl,
jt_data_back_package.lable1,lable2_1,lable2_2,lable3_1,lable3_2,lable3_3,lable3_4};
uint16_t crc_c=CRC16_XMODEM(test1,15);
//for(int i=0;i<15;i++){
// printf("%02x ",test1[i]);
//}
//LOG_I("%s:XModem_CRC16 = %04x\r\n",__func__,crc_c);
//LOG_I("CRC = %04x\r\n",ntohs(jt_data_back_package.crc));
*parmAck=ntohs(jt_data_back_package.pre4);
*tagCode=ntohl(jt_data_back_package.tag);
*tagSignal=jt_data_back_package.signal;
*totalLen=jt_data_back_package.len;
*tagFeature=jt_data_back_package.featureCode;
*count=jt_data_back_package.count;
*batteryV=ntohs(jt_data_back_package.battery);
*version=ntohs(jt_data_back_package.version);
*ledCtrl=jt_data_back_package.ledCtrl;
*lable1=jt_data_back_package.lable1;
*lable2=ntohs(jt_data_back_package.lable2);
*lable3=ntohl(jt_data_back_package.lable3);
}else{
// LOG_I("%s failed\n", __func__);
ret = -2;
}
}else{
//LOG_I("%s, failed, time out\n", __func__);
ret = -1;
}
return ret;
}
// 修正版:点亮灯带下行帧头,严格按协议示例
int uart_data_send_head_lightband(uart_utils_t *uart, uint8_t wakeup_time, uint16_t tag_num) {
int ret = 0;
// 帧头中的len2 = tag_num * 9 + 5
uint8_t data_len = tag_num * 9 + 5;
jt_head_package_t jt_head_package = {
.pre = 0x2323, // ##
.wakeupTime = wakeup_time, // 5s,<120s
.func = 'E', // 功能码E
.len1 = 0x0000, // 固定为0
.len2 = data_len, // tag_num*9+5
.reserve = htons(0x0003),
.lableNum = htons(tag_num),
};
LOG_I("%s:HEAD:%04x,%02x,%02x,%04x,%02x,%04x,%04x\r\n", __func__,
jt_head_package.pre, jt_head_package.wakeupTime, jt_head_package.func,
jt_head_package.len1, jt_head_package.len2, jt_head_package.reserve, jt_head_package.lableNum);
if (uart == NULL) {
LOG_I("uart NULL pointer\n");
ret = -1;
goto error;
}
if (sizeof(jt_head_package) == write(uart->uart_fd, &jt_head_package, sizeof(jt_head_package))) {
ret = 0;
LOG_I("!!%s:HEAD:%04x,%02x,%02x,%04x,%02x,%04x,%04x\r\n", __func__,
jt_head_package.pre, jt_head_package.wakeupTime, jt_head_package.func,
jt_head_package.len1, jt_head_package.len2, jt_head_package.reserve, jt_head_package.lableNum);
//LOG_I("%s success\n",__func__);
} else {
//LOG_I("%s fail\n", __func__);
ret = -2;
goto error;
}
error:
return ret;
}
// 修正版:点亮灯带下行数据,严格按协议示例
int uart_data_send_lightband(uart_utils_t *uart, uint8_t ledctl, uint16_t flash_i, uint16_t light_d, uint32_t tags[], uint8_t tag_leds[], uint16_t tag_num) {
int ret = 0;
// 检查tag数量限制
if (tag_num > 30) {
LOG_I("[uart_data_send_lightband] tag_num too large: %d, max 30\n", tag_num);
return -4;
}
// 数据包总长度: 3字节头 + tag_num * 9字节 + 2字节CRC
int data_len = 3 + tag_num * 9 + 2;
uint8_t *buf = malloc(data_len);
if (!buf) return -2;
memset(buf, 0, data_len);
buf[0] = 0x00; // len1
buf[1] = 0x00; // len2
buf[2] = tag_num * 9 + 2; // 数据区长度含CRC
// 填充tag数据 - 每个tag 9字节
for (int i = 0; i < tag_num; ++i) {
int base = 3 + i * 9;
buf[base + 0] = (tags[i] >> 24) & 0xFF; // MAC高字节
buf[base + 1] = (tags[i] >> 16) & 0xFF; // MAC次高字节
buf[base + 2] = (tags[i] >> 8) & 0xFF; // MAC次低字节
buf[base + 3] = tags[i] & 0xFF; // MAC低字节
buf[base + 4] = tag_leds[i]; // LED控制
buf[base + 5] = (flash_i >> 8) & 0xFF; // 闪烁间隔高字节
buf[base + 6] = flash_i & 0xFF; // 闪烁间隔低字节
buf[base + 7] = (light_d >> 8) & 0xFF; // 点灯时长高字节
buf[base + 8] = light_d & 0xFF; // 点灯时长低字节
}
// CRC16XMODEM不含最后2字节
uint16_t crc = CRC16_XMODEM(buf, data_len - 2);
buf[data_len - 2] = (crc >> 8) & 0xFF;
buf[data_len - 1] = crc & 0xFF;
// 打印CRC计算详情
printf("[uart_data_send_lightband] tag_num=%d, data_len=%d\n", tag_num, data_len);
printf("[uart_data_send_lightband] CRC calculation: ");
for (int i = 0; i < data_len - 2; ++i) {
printf("%02X ", buf[i]);
}
printf(" -> CRC: %04X\n", crc);
// 打印发送数据内容
printf("[uart_data_send_lightband] send: ");
for (int i = 0; i < data_len; ++i) {
printf("%02X ", buf[i]);
}
printf("\n");
if (uart == NULL) { free(buf); return -1; }
int write_ret = write(uart->uart_fd, buf, data_len);
LOG_I("[uart_data_send_lightband] write_ret=%d, data_len=%d", write_ret, data_len);
if (write_ret == data_len) ret = 0; else ret = -3;
free(buf);
return ret;
}