#include "uart_can.h" #include "uart_utils.h" #include #include #include #include #include #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;iuart_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; // 点灯时长低字节 } // CRC16(XMODEM),不含最后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; }