#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_test(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_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;

    uint8_t tag_1_1=(tag_1>>24)&0xFF;
    uint8_t tag_1_2=(tag_1>>16)&0xFF;
    uint8_t tag_1_3=(tag_1>>8)&0xFF;
    uint8_t tag_1_4=(tag_1)&0xFF;

    uint8_t tag_2_1=(tag_2>>24)&0xFF;
    uint8_t tag_2_2=(tag_2>>16)&0xFF;
    uint8_t tag_2_3=(tag_2>>8)&0xFF;
    uint8_t tag_2_4=(tag_2)&0xFF;

    uint8_t tag_3_1=(tag_3>>24)&0xFF;
    uint8_t tag_3_2=(tag_3>>16)&0xFF;
    uint8_t tag_3_3=(tag_3>>8)&0xFF;
    uint8_t tag_3_4=(tag_3)&0xFF;

    uint8_t tag_4_1=(tag_4>>24)&0xFF;
    uint8_t tag_4_2=(tag_4>>16)&0xFF;
    uint8_t tag_4_3=(tag_4>>8)&0xFF;
    uint8_t tag_4_4=(tag_4)&0xFF;

    uint8_t tag_5_1=(tag_5>>24)&0xFF;
    uint8_t tag_5_2=(tag_5>>16)&0xFF;
    uint8_t tag_5_3=(tag_5>>8)&0xFF;
    uint8_t tag_5_4=(tag_5)&0xFF;
#if 0
    LOG_I("ledctl = %02x\r\n",ledctl);
    LOG_I("flash_i_h = %02x\r\n",flash_i_h);
    LOG_I("flash_i_l = %02x\r\n",flash_i_l);
    LOG_I("light_d_h = %02x\r\n",light_d_h);
    LOG_I("light_d_l = %02x\r\n",light_d_l);
    LOG_I("tag_1_1 = %02x\r\n",tag_1_1);
    LOG_I("tag_1_2 = %02x\r\n",tag_1_2);
    LOG_I("tag_1_3 = %02x\r\n",tag_1_3);
    LOG_I("tag_1_4 = %02x\r\n",tag_1_4);
    LOG_I("tag_2_1 = %02x\r\n",tag_2_1);
    LOG_I("tag_2_2 = %02x\r\n",tag_2_2);
    LOG_I("tag_2_3 = %02x\r\n",tag_2_3);
    LOG_I("tag_2_4 = %02x\r\n",tag_2_4);
    LOG_I("tag_3_1 = %02x\r\n",tag_3_1);
    LOG_I("tag_3_2 = %02x\r\n",tag_3_2);
    LOG_I("tag_3_3 = %02x\r\n",tag_3_3);
    LOG_I("tag_3_4 = %02x\r\n",tag_3_4);
    LOG_I("tag_4_1 = %02x\r\n",tag_4_1);
    LOG_I("tag_4_2 = %02x\r\n",tag_4_2);
    LOG_I("tag_4_3 = %02x\r\n",tag_4_3);
    LOG_I("tag_4_4 = %02x\r\n",tag_4_4);
    LOG_I("tag_5_1 = %02x\r\n",tag_5_1);
    LOG_I("tag_5_2 = %02x\r\n",tag_5_2);
    LOG_I("tag_5_3 = %02x\r\n",tag_5_3);
    LOG_I("tag_5_4 = %02x\r\n",tag_5_4);
#endif
    if(tag_num==1){
        uint8_t test1[12] = {0x00,0x00,11,ledctl,flash_i_h,flash_i_l,light_d_h,light_d_l,
                             tag_1_1,tag_1_2,tag_1_3,tag_1_4};
        uint16_t crc_c=CRC16_XMODEM(test1,sizeof(test1));
        for(int i=0;i<12;i++){
            printf("%02x ",test1[i]);
        }
        LOG_I("\r\n");
        LOG_I("%s XModem_CRC16 = %04x\r\n",__func__,crc_c);
        jt_light_led1_package_t jt_light_led1_package ={
            .len1=0x0000,
            .len2=11,
            .ledCtr=ledctl,
            .flashInterval=ntohs(flash_i),
            .lightDuration=ntohs(light_d),
            .tag1=ntohl(tag_1),
            .crc=ntohs(crc_c),
        };
        if(sizeof(jt_light_led1_package) == write(uart->uart_fd, &jt_light_led1_package, sizeof(jt_light_led1_package))){
            ret = 0;
            //LOG_I("%s success\n",__func__);
        }else{
            //LOG_I("%s fail\n", __func__);
            ret = -2;
            goto error;
        }
    }else if(tag_num==2){
        uint8_t test1[16] = {0x00,0x00,15,ledctl,flash_i_h,flash_i_l,light_d_h,light_d_l,
                             tag_1_1,tag_1_2,tag_1_3,tag_1_4,tag_2_1,tag_2_2,tag_2_3,tag_2_4};
        uint16_t crc_c=CRC16_XMODEM(test1,sizeof(test1));
        for(int i=0;i<16;i++){
            printf("%02x ",test1[i]);
        }
        LOG_I("\r\n");
        LOG_I("%s XModem_CRC16 = %04x\r\n",__func__,crc_c);
        jt_light_led2_package_t jt_light_led2_package ={
            .len1=0x0000,
            .len2=15,
            .ledCtr=ledctl,
            .flashInterval=ntohs(flash_i),
            .lightDuration=ntohs(light_d),
            .tag1=ntohl(tag_1),
            .tag2=ntohl(tag_2),
            .crc=ntohs(crc_c),
        };

       LOG_I("%04x,%02x,%02x,%04x,%04x,%08x,%08x,%04x\r\n",jt_light_led2_package.len1,jt_light_led2_package.len2,
             jt_light_led2_package.ledCtr,jt_light_led2_package.flashInterval,jt_light_led2_package.lightDuration,
             jt_light_led2_package.tag1,jt_light_led2_package.tag2,jt_light_led2_package.crc);
        if(sizeof(jt_light_led2_package) == write(uart->uart_fd, &jt_light_led2_package, sizeof(jt_light_led2_package))){
            ret = 0;
            //LOG_I("%s success\n",__func__);
        }else{
            //LOG_I("%s fail\n", __func__);
            ret = -2;
            goto error;
        }
    }else if(tag_num==3){
        uint8_t test1[20] = {0x00,0x00,19,ledctl,flash_i_h,flash_i_l,light_d_h,light_d_l,
                             tag_1_1,tag_1_2,tag_1_3,tag_1_4,tag_2_1,tag_2_2,tag_2_3,tag_2_4,tag_3_1,tag_3_2,tag_3_3,tag_3_4};
        uint16_t crc_c=CRC16_XMODEM(test1,sizeof(test1));
        for(int i=0;i<20;i++){
            printf("%02x ",test1[i]);
        }
        LOG_I("\r\n");
        LOG_I("%s XModem_CRC16 = %04x\r\n",__func__,crc_c);
        jt_light_led3_package_t jt_light_led3_package ={
            .len1=0x0000,
            .len2=19,
            .ledCtr=ledctl,
            .flashInterval=ntohs(flash_i),
            .lightDuration=ntohs(light_d),
            .tag1=ntohl(tag_1),
            .tag2=ntohl(tag_2),
            .tag3=ntohl(tag_3),
            .crc=ntohs(crc_c),
        };
        if(sizeof(jt_light_led3_package) == write(uart->uart_fd, &jt_light_led3_package, sizeof(jt_light_led3_package))){
            ret = 0;
            //LOG_I("%s success\n",__func__);
        }else{
            //LOG_I("%s fail\n", __func__);
            ret = -2;
            goto error;
        }
    }else if(tag_num==4){
        uint8_t test1[24] = {0x00,0x00,23,ledctl,flash_i_h,flash_i_l,light_d_h,light_d_l,
                             tag_1_1,tag_1_2,tag_1_3,tag_1_4,tag_2_1,tag_2_2,tag_2_3,tag_2_4,tag_3_1,tag_3_2,tag_3_3,tag_3_4,
                             tag_4_1,tag_4_2,tag_4_3,tag_4_4};
        uint16_t crc_c=CRC16_XMODEM(test1,sizeof(test1));
        for(int i=0;i<24;i++){
            printf("%02x ",test1[i]);
        }
        LOG_I("\r\n");
        LOG_I("%s XModem_CRC16 = %04x\r\n",__func__,crc_c);
        jt_light_led4_package_t jt_light_led4_package ={
            .len1=0x0000,
            .len2=23,
            .ledCtr=ledctl,
            .flashInterval=ntohs(flash_i),
            .lightDuration=ntohs(light_d),
            .tag1=ntohl(tag_1),
            .tag2=ntohl(tag_2),
            .tag3=ntohl(tag_3),
            .tag4=ntohl(tag_4),
            .crc=ntohs(crc_c),
        };
        if(sizeof(jt_light_led4_package) == write(uart->uart_fd, &jt_light_led4_package, sizeof(jt_light_led4_package))){
            ret = 0;
            //LOG_I("%s success\n",__func__);
        }else{
            //LOG_I("%s fail\n", __func__);
            ret = -2;
            goto error;
        }
    }else if(tag_num==5){
        uint8_t test1[28] = {0x00,0x00,27,ledctl,flash_i_h,flash_i_l,light_d_h,light_d_l,
                             tag_1_1,tag_1_2,tag_1_3,tag_1_4,tag_2_1,tag_2_2,tag_2_3,tag_2_4,tag_3_1,tag_3_2,tag_3_3,tag_3_4,
                             tag_4_1,tag_4_2,tag_4_3,tag_4_4,tag_5_1,tag_5_2,tag_5_3,tag_5_4};
        uint16_t crc_c=CRC16_XMODEM(test1,sizeof(test1));
        for(int i=0;i<28;i++){
            printf("%02x ",test1[i]);
        }
        LOG_I("\r\n");
        LOG_I("%s XModem_CRC16 = %04x\r\n",__func__,crc_c);
        jt_light_led5_package_t jt_light_led5_package ={
            .len1=0x0000,
            .len2=27,
            .ledCtr=ledctl,
            .flashInterval=ntohs(flash_i),
            .lightDuration=ntohs(light_d),
            .tag1=ntohl(tag_1),
            .tag2=ntohl(tag_2),
            .tag3=ntohl(tag_3),
            .tag4=ntohl(tag_4),
            .tag5=ntohl(tag_5),
            .crc=ntohs(crc_c),
        };
        if(sizeof(jt_light_led5_package) == write(uart->uart_fd, &jt_light_led5_package, sizeof(jt_light_led5_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_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;         // 点灯时长低字节
    }

    // 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计算详情
    LOG_I("[uart_data_send_lightband] tag_num=%d, data_len=%d\n", tag_num, data_len);
    LOG_I("[uart_data_send_lightband] CRC cal: ");
    for (int i = 0; i < data_len - 2; ++i) {
        LOG_RAW("%02X ", buf[i]);
    }
    LOG_RAW(" -> CRC: %04X\n", crc);

    // 打印发送数据内容
    LOG_I("[uart_data_send_lightband] send: ");
    for (int i = 0; i < data_len; ++i) {
        LOG_RAW("%02X ", buf[i]);
    }
    LOG_RAW("\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;
}
