/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : UARTCallback.c
  * @brief          : 
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2025 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
	
/* USER CODE END Header */

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "FreeRTOS.h"
#include "cmsis_os.h"
#include "task.h"
#include "queue.h"
#include "main.h"
#include "Callback.h"
#include "Modbussimple.h"
#include "FLASH.h"
#include "DRV8837D.h"
#include "kv_flash.h"

/* USER CODE END Includes */

/* Exported types ------------------------------------------------------------*/
/* USER CODE BEGIN ET */

extern DMA_HandleTypeDef hdma_usart1_rx;
extern DMA_HandleTypeDef hdma_usart2_rx;
extern osThreadId_t ReadTaskHandle;
extern osMessageQueueId_t uart485rxqueueHandle;
extern osMessageQueueId_t consolemsgqueueHandle;

extern uint8_t dataReceive485[BUFFER_SIZE485];	// 485
extern uint8_t dataReceivep[BUFFER_SIZEP];	// 调试

extern uint32_t uartIRQ_rx_len;	// 485串口接收数据长度
extern uint32_t uartprint_rx_len ;

/*
	* @ 多功能API阀参数信息
*/


uint16_t Valve_status = 0;			//	阀状态0000关0001开
uint32_t uint_liquidHeight = 0; // 液位高度
uint32_t uint_oil_percent = 0; 	// 油水百分比
uint32_t uint_filtered_cap = 0; 	// 滤波之后的电容值
 
/* USER CODE END ET */

/* Exported functions prototypes ---------------------------------------------*/
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) // UART 接收完成回调
{
	if (huart->Instance == USART1) 
		HAL_GPIO_WritePin(GPIOA, RS485_RD_Pin, GPIO_PIN_RESET);  
}

void UART1_IdleCallback(void)
{
		HAL_UART_DMAStop(&huart1);  // 停止 DMA，获取剩余数据长度
    uint32_t remain = __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);
    uartIRQ_rx_len = BUFFER_SIZE485 - remain;

    if (uartIRQ_rx_len == 0 || uartIRQ_rx_len > BUFFER_SIZE485) {
        // 异常长度，忽略
        Restart_UART1_DMA();
        return;
    }
		
		Uart485Rx_msg uart485_msg;
		memset(&uart485_msg, 0, sizeof(uart485_msg));
		uart485_msg.len = uartIRQ_rx_len;
		memcpy(uart485_msg.data, dataReceive485, uartIRQ_rx_len);  // 只拷贝有效长度
		
		BaseType_t xHigherPriorityTaskWoken = pdFALSE;	
		if (xQueueSendToBackFromISR(uart485rxqueueHandle, &uart485_msg, &xHigherPriorityTaskWoken) != pdPASS) 
		{
				// 队列满，移出一个旧数据再塞入
				Uart485Rx_msg discard_msg;
				xQueueReceiveFromISR(uart485rxqueueHandle, &discard_msg, &xHigherPriorityTaskWoken);
				xQueueSendToBackFromISR(uart485rxqueueHandle, &uart485_msg, &xHigherPriorityTaskWoken);
		}
		Restart_UART1_DMA();  // 重启 DMA 接收
}

void UART2_IdleCallback(void) 
{
		HAL_UART_DMAStop(&huart2);

    // 计算接收长度
		uint32_t remain = __HAL_DMA_GET_COUNTER(&hdma_usart2_rx);
    uartprint_rx_len = BUFFER_SIZEP - remain;

    if (uartprint_rx_len < 4 || uartprint_rx_len > BUFFER_SIZEP)
    {
        Restart_UART2_DMA(); // 长度异常直接重启 DMA
        return;
    }

		Console_msg console_msg;
		memset(&console_msg, 0, sizeof(console_msg));  // 
		BaseType_t xHigherPriorityTaskWoken = pdFALSE;
		
		console_msg.len = uartprint_rx_len;
		memcpy(console_msg.data, dataReceivep, uartprint_rx_len); // 拷贝接收数据
		memset(dataReceivep, 0, sizeof(dataReceivep));
		
		if (xQueueSendToBackFromISR(consolemsgqueueHandle, &console_msg, &xHigherPriorityTaskWoken) != pdPASS) // FreeRTOS 原生 API
		{
				Console_msg discard_msg;
				xQueueReceiveFromISR(consolemsgqueueHandle, &discard_msg, &xHigherPriorityTaskWoken); // 丢弃队首
				xQueueSendToBackFromISR(consolemsgqueueHandle, &console_msg, &xHigherPriorityTaskWoken);
		}
		
}

void Process_Consolecallback(void) // 处理控制台命令
{   
		Console_msg conmsg;

    if (osMessageQueueGet(consolemsgqueueHandle, &conmsg, NULL, 0) == osOK) { // CMSIS API
			 if (conmsg.len > 0 && conmsg.data[0] != '\0'){  // 过滤空命令
            parse_AT_command(conmsg.data);

        }
			 Restart_UART2_DMA();
		}
}

void Process_Uart485callback(void)
{   
		Uart485Rx_msg rxMsg;

    if (osMessageQueueGet(uart485rxqueueHandle, &rxMsg, NULL, 0) == osOK) {
			
			DEBUG_PRINTF("485rxBuffer: ");
			for (int i = 0; i < rxMsg.len; i++) {
					DEBUG_PRINTF("%02X ", rxMsg.data[i]);
			}
			DEBUG_PRINTF("\n");

//			if(Systemmode != releasemode)
//			{
//				taskprint(rxMsg.data, rxMsg.len);
//			}
			if (is_modbus_03_response(rxMsg.data)) { // 处理03读指令
					process_modbus_03(rxMsg.data);
					return;
			}
			if (is_modbus_06_response(rxMsg.data)) { // 处理06写单指令
					process_modbus_06(rxMsg.data);
					return;
			}
			if (is_modbus_10_response(rxMsg.data)) { // 处理10写多指令
					process_modbus_10(rxMsg.data);
					return;
			}
			if (is_modbus_42_response(rxMsg.data)) { // 处理42升级指令
					process_modbus_42(rxMsg.data);
					return;
			}
    }
}

bool is_modbus_03_response(uint8_t *data)  
{
    if (!((data[0] == (JsRoot.addr & 0xFF) || data[0] == 0xFF) && data[1] == 0x03))    
    return false; // 不匹配，直接返回 false   
    uint16_t crc_received = (data[7] << 8) | data[6];		
    uint16_t crc_calculated = modbus_crc16(data, 6);
    return memcmp(&crc_received, &crc_calculated, sizeof(crc_calculated)) == 0;
}

void process_modbus_03(uint8_t *data) 
{		
	memset(g_modbusbuffer, 0, sizeof(g_modbusbuffer));  // 清零缓存，防止旧数据影响
	uint8_t *tx_buf = (uint8_t *)g_modbusbuffer;  // 强制转成字节指针	

	uint8_t func_code = data[1];	// 功能码
	uint16_t reg_addr  = (data[2] <<8) | data[3]; // 寄存器地址
	uint8_t reg_count  = data[5]; // 寄存器数量
	
	// 最多读取125个寄存器（Modbus限制）
    if (reg_count == 0 || reg_count > 125) return;
	
	// 填充应答头部
    tx_buf[0] = JsRoot.addr & 0xFF;
    tx_buf[1] = func_code;
    tx_buf[2] = reg_count * 2;

    uint16_t data_len = 0;
    bool found = read_modbus_registers(reg_addr, reg_count, &tx_buf[3], &data_len);
    if (!found) return; // 地址非法

    // 计算CRC
    uint16_t crc = modbus_crc16(tx_buf, 3 + data_len);
    tx_buf[3 + data_len] = crc & 0xFF;
    tx_buf[4 + data_len] = (crc >> 8) & 0xFF;

    // 发送帧长度
    uint16_t total_len = 5 + data_len;

		uart485send(tx_buf, total_len);
}
 
bool is_modbus_06_response(uint8_t *data)  
{
    if (!((data[0] == (JsRoot.addr & 0xFF) || data[0] == 0xFF)&&  data[1] == 0x06))    
    return false; // 不匹配，直接返回 false   
    uint16_t crc_received = (data[7] << 8) | data[6];		
    uint16_t crc_calculated = modbus_crc16(data, 6);
    return memcmp(&crc_received, &crc_calculated, sizeof(crc_calculated)) == 0;
}

void process_modbus_06(uint8_t *data) {
    memset(g_modbusbuffer, 0, sizeof(g_modbusbuffer));
    uint8_t* tx_buf = (uint8_t *)g_modbusbuffer;

    uint8_t func_code = data[1];
    uint16_t reg_addr = (data[2] << 8) | data[3];
    uint16_t reg_data = (data[4] << 8) | data[5];

    bool found = false;
    for (size_t i = 0; i < REGISTER_MAP_SIZE; ++i) {
        if (WriteReg_map[i].address == reg_addr) {
            found = true;
            if (WriteReg_map[i].handler(reg_data)) {
                break;  
            } else {
                return; 
            }
        }
    }

    if (!found) {
        return;  // 地址无效，不做任何处理
    }

    // 构造应答
    uint16_t len = 0;
    tx_buf[len++] = JsRoot.addr;
    tx_buf[len++] = func_code;
    tx_buf[len++] = (reg_addr >> 8) & 0xFF;
    tx_buf[len++] = reg_addr & 0xFF;
    tx_buf[len++] = (reg_data >> 8) & 0xFF;
    tx_buf[len++] = reg_data & 0xFF;

    uint16_t crc = modbus_crc16(tx_buf, len);
    tx_buf[len++] = crc & 0xFF;
    tx_buf[len++] = (crc >> 8) & 0xFF;

    uart485send(tx_buf, len);
}

bool is_modbus_10_response(uint8_t *data)  
{
    if (!((data[0] == (JsRoot.addr & 0xFF) || data[0] == 0xFF)&& data[1] == 0x10)) 		
			return false; // 不匹配，直接返回 false   

    uint16_t crc_received = (data[uartIRQ_rx_len-1] << 8) | data[uartIRQ_rx_len - 2];	
    uint16_t crc_calculated = modbus_crc16(data, uartIRQ_rx_len - 2);

    if (crc_received != crc_calculated)
    {
        return false; // 返回false，不执行后续处理
    }
    return true;  // CRC正确
}
void process_modbus_10(uint8_t *data) 
{
    memset(g_modbusbuffer, 0, sizeof(g_modbusbuffer));
    uint8_t *tx_buf = (uint8_t *)g_modbusbuffer;

    uint8_t func_code  = data[1];
    uint16_t reg_addr  = (data[2] << 8) | data[3];
    uint16_t reg_count = (data[4] << 8) | data[5];
//    uint16_t byte_count = data[6];

    // 数据段转成 uint16_t 数组
    uint16_t values[reg_count];
    for (uint16_t i = 0; i < reg_count; i++) {
        values[i] = (data[7 + i * 2] << 8) | data[8 + i * 2];
    }

    bool found = false;
    for (size_t i = 0; i < MULTI_REGISTER_MAP_SIZE; i++) {
        if (WriteMultiReg_map[i].start_address == reg_addr &&
            WriteMultiReg_map[i].reg_count == reg_count) 
        {
            found = true;
            if (!WriteMultiReg_map[i].handler(values, WriteMultiReg_map[i].arg)) {
                return; // 处理失败，不应答
            }
            break;
        }
    }

    if (!found) {
        return;
    }

    // 构造应答帧
    uint16_t len = 0;
    tx_buf[len++] = JsRoot.addr;
    tx_buf[len++] = func_code;
    tx_buf[len++] = (reg_addr >> 8) & 0xFF;
    tx_buf[len++] = reg_addr & 0xFF;
    tx_buf[len++] = (reg_count >> 8) & 0xFF;
    tx_buf[len++] = reg_count & 0xFF;

    uint16_t crc = modbus_crc16(tx_buf, len);
    tx_buf[len++] = crc & 0xFF;
    tx_buf[len++] = (crc >> 8) & 0xFF;

    uart485send(tx_buf, len);
}



bool is_modbus_42_response(uint8_t *data)  
{
    // 检查前个字节是否符合要求
    if (!((data[0] == (JsRoot.addr & 0xFF) && data[0] == 0xFF)&& 
					data[1] == 0x42 && data[2] == 0xAA && data[3] == 0xBB))    
    return false; // 不匹配，直接返回 false 
	
    uint16_t crc_received = (data[uartIRQ_rx_len-1] << 8) | data[uartIRQ_rx_len - 2];		
    uint16_t crc_calculated = modbus_crc16(data, uartIRQ_rx_len - 2);

		if (crc_received != crc_calculated)
    {
        return false; // 返回false，不执行后续处理
    }
    return true;  // CRC正确
}

void process_modbus_42(uint8_t *data) 
{		
		memset(g_modbusbuffer, 0, sizeof(g_modbusbuffer));  // 清零缓存，防止旧数据影响
		uint16_t iapDataCommandCode  = (data[4] <<8) |data[5]; // IAP数据的命令码 

		switch(iapDataCommandCode)
		{
			case 0x4000:  // 升级程序起始帧	
		
						handle_upgrade_start_frame(data); 					
            break;
					
				case 0x4001:  // 升级程序数据帧		
						
						handle_upgrade_data_frame(data);
            break;
				
				case 0x4002:  // 升级程序结束帧	
					
						handle_upgrade_end_frame();
            break;
				
        default:
            send_upgrade_end_response(0x42, 0xAABB, 0x07, 0x0000); // 命令码错误
            break;		
		}

}

bool is_modbus_errorfunc_response(uint8_t *data)  
{
    // 检查从机地址是否符合要求（等于 JsRoot.addr 或 0xFF）
    bool is_valid_addr = (data[0] == (JsRoot.addr & 0xFF)) || (data[0] == 0xFF);
    
    // 检查功能码是否不在允许的范围内（0x03, 0x06, 0x10, 0x42）
    bool is_invalid_func = (data[1] != 0x03) && 
                           (data[1] != 0x06) && 
                           (data[1] != 0x10) && 
                           (data[1] != 0x42);
    
    if (is_valid_addr && is_invalid_func)
    {
        uint16_t crc_received = (data[7] << 8) | data[6];        
        uint16_t crc_calculated = modbus_crc16(data, 6);
        return (memcmp(&crc_received, &crc_calculated, sizeof(crc_received)) == 0);
    }
    
    return false; // 不匹配，直接返回 false   
}

void process_modbus_errorfunc(uint8_t *data) 
{		
		memset(g_modbusbuffer, 0, sizeof(g_modbusbuffer));  // 清零缓存，防止旧数据影响
    uint8_t *tx_buf = (uint8_t *)g_modbusbuffer;  // 强制转成字节指针
	
		uint8_t func_code = data[1];	// 功能码	
		uint8_t total_len = 0;
	
		total_len = modbus_error_response(JsRoot.addr & 0xFF, func_code, 0x01, tx_buf); // 功能码错误
	
		uart485send(tx_buf, total_len);

}

bool is_modbus_error_regaddr_response(uint8_t *data)  
{
    // 检查从机地址是否符合要求（等于 JsRoot.addr 或 0xFF）
    bool is_valid_addr = (data[0] == (JsRoot.addr & 0xFF)) || (data[0] == 0xFF);
    
    // 检查功能码是否不在允许的范围内（0x03, 0x06, 0x10, 0x42）
    bool is_valid_func = (data[1] == 0x03) || 
                          (data[1] == 0x06) || 
                          (data[1] == 0x10) || 
                          (data[1] == 0x42);
		
		uint16_t reg_addr  = (data[2] <<8) | data[3]; // 寄存器地址
		
		// 检查寄存器地址是否不在允许的范围内（0x0000 到 0x001D 之间，0xAABB）
    bool is_invalid_regaddr = (reg_addr > 0x0021) && (reg_addr != 0xAABB);

    if (is_valid_addr && is_valid_func && is_invalid_regaddr)
    {
        uint16_t crc_received = (data[7] << 8) | data[6];        
        uint16_t crc_calculated = modbus_crc16(data, 6);
        return (memcmp(&crc_received, &crc_calculated, sizeof(crc_received)) == 0);
    }
    
    return false; // 不匹配，直接返回 false   
}

void process_modbus_error_regaddr(uint8_t *data) 
{		
		memset(g_modbusbuffer, 0, sizeof(g_modbusbuffer));  // 清零缓存，防止旧数据影响
    uint8_t *tx_buf = (uint8_t *)g_modbusbuffer;  // 强制转成字节指针
	
		uint8_t func_code = data[1];	// 功能码	
		uint8_t total_len = 0;
	
		total_len = modbus_error_response(JsRoot.addr & 0xFF, func_code, 0x02, tx_buf); // 功能码错误
		
		uart485send(tx_buf, total_len);
}

void process_modbus_error_data(uint8_t *data) 
{		
		memset(g_modbusbuffer, 0, sizeof(g_modbusbuffer));  // 清零缓存，防止旧数据影响
    uint8_t *tx_buf = (uint8_t *)g_modbusbuffer;  // 强制转成字节指针
	
		uint8_t func_code = data[1];	// 功能码	

		uint8_t total_len = modbus_error_response(JsRoot.addr & 0xFF, func_code, 0x03, tx_buf); // 功能码错误
	
    uart485send(tx_buf, total_len);

}


void taskprint(uint8_t *tx_buf, uint16_t len)
{
    char buf[1024];
    int offset = 0;

    offset += snprintf(buf + offset, sizeof(buf) - offset, "RX_BUF: ");
    for (uint16_t i = 0; i < len && offset < sizeof(buf) - 2; i++) { // 防止越界
        offset += snprintf(buf + offset, sizeof(buf) - offset, "%02X ", tx_buf[i]);
    }

    CommonPrintf("%s\r\n", buf);
}
void taskprinttx(uint8_t *tx_buf, uint16_t len)
{
    char buf[128];
    int offset = 0;

    offset += snprintf(buf + offset, sizeof(buf) - offset, "TX_BUF: ");
    for (uint16_t i = 0; i < len && offset < sizeof(buf) - 3; i++) { // 防止越界
        offset += snprintf(buf + offset, sizeof(buf) - offset, "%02X ", tx_buf[i]);
    }

    CommonPrintf("%s\r\n", buf);
}
void uart485send(uint8_t *tx_buf, uint16_t total_len)
{
	HAL_GPIO_WritePin(GPIOA, RS485_RD_Pin, GPIO_PIN_SET); // 拉高发送
  HAL_UART_Transmit_DMA(&huart1, tx_buf, total_len);
}
void parse_AT_command(uint8_t *buf)
{
		if (buf == NULL || buf[0] == '\0') // 去空
				return;
		
		size_t len = strlen((char*)buf);
		
//		// 调试打印原始数据
//    printf("Raw recv (len=%d): ", (int)len);
//    for (size_t i = 0; i < len; i++) {
//        if (buf[i] >= 32 && buf[i] <= 126) {
//            // 可打印字符
//            printf("%c", buf[i]);
//        } else {
//            // 控制字符打印为 [xx]
//            printf("[0x%02X]", buf[i]);
//        }
//    }
//    printf("\r\n");
		
		 // 必须以 "###::" 开头
		if (len < 5 || strncmp((char*)buf, "###::", 5) != 0) {// 排除不符帧头的命令串
				printf("error=invalid prefix, rlt=401\r\n");
        return;
		}
		
		// 必须以 "\r\n" 结尾
    if (len < 5 || !(buf[len - 2] == '\r' && buf[len - 1] == '\n')) {
        printf("error=invalid ending, rlt=402\r\n");
        return;
    }
		
		buf[len - 2] = '\0'; // 去掉 \r\n
    char *cmd = (char*)buf + 5; // 去掉开头 "###::"
//		printf("AT Raw: %s\r\n", buf);

		
		// ================== 文档命令判断 ==================

		if (strncmp(cmd, "--debug=", 8) == 0) { // 控制台调试时限
        int minutes = atoi(cmd + 8);
        // 限制范围：UART1 特殊限制
        if (minutes >= 0 && minutes <= 1440) {
//            uint32_t debug_console_timeout = minutes;
            printf("Debug console %s, timeout=%d min\r\n, OK",
                   (minutes > 0) ? "enabled" : "disabled",
										minutes);
						
        } else {
            printf("Invalid debug time\r\n");
        }
        return;
    }
		if (strcmp(cmd, "ls") == 0) {
//			printf("ls OK \r\n");
				print_JsRoot(); // 数据缓存 dump 输出        
        return;
    }
		if (strncmp(cmd, "{\"mac\":\"", 8) == 0) {			
				handle_mac_set_cmd(cmd); // 设置设备sn
        return;
    }
		 if (strncmp(cmd, "--set_time=", 11) == 0) {
        printf("no rtc time, ok\r\n"); // 设置系统时间
        return;
    }
		if (strncmp(cmd, "--cfg_set=", 10) == 0) {         
				handle_cfg_set_cmd(cmd); // 系统配置-KV设置
        return;
    }

    if (strncmp(cmd, "--cfg_setx=", 11) == 0) {         
				handle_cfg_setx_cmd(cmd); // 通用配置-KV设置
        return;
    }

    if (strncmp(cmd, "--cfg_get=", 10) == 0) {         
				handle_cfg_get_cmd(cmd); // 读取键值内容
        return;
    }

    if (strcmp(cmd, "reboot") == 0) {
				printf("ok\r\n");
        NVIC_SystemReset(); // 重启设备
        return;
    }

    if (strncmp(cmd, "--fileid=", 9) == 0) {       
				handle_fileid_cmd(cmd); // 读取库存信息
        return;
    }

    if (strncmp(cmd, "--clear_fileid=", 15) == 0) {
      
				handle_clear_fileid_cmd(cmd);  // 清除内部配置库
        return;
    }
		if (strncmp(cmd, "--iwdg_get", 10) == 0) {
			
				if (__HAL_RCC_GET_FLAG(RCC_FLAG_IWDGRST))	// 清除复位标志
				{
					printf ("\r\n IWDG_RST flag");				
					__HAL_RCC_CLEAR_RESET_FLAGS();	// 清除所有复位标志（包括IWDG复位标志）
				}else{
					printf ("\r\n No IWDG_RST flag");
				}
        return;
    }
		if (strncmp(cmd, "--Stack_size", 12) == 0) {      
				Read_Remaining_stack_space(); // 读取每个任务栈剩余空间
        return;
    }
		if (strncmp(cmd, "--debug_printf=", 15) == 0) {
			char val = cmd[15];
			if (val == '0' || val == '1')
			{
				debug_print_enabled = (val == '1') ? 1 : 0;
				printf("Debug print %s\r\n", debug_print_enabled ? "enabled" : "disabled");
			}
			else
			{
				printf("Invalid debugprintf value: %c\r\n", val);
			}
        return;
    }
		if (strncmp(cmd, "--fdc_printf=", 13) == 0) {
			char val = cmd[13];
			if (val == '0' || val == '1')
			{
				fdc_print_enabled = (val == '1') ? 1 : 0;
				printf("FDC print %s\r\n", fdc_print_enabled ? "enabled" : "disabled");
			}
			else
			{
				printf("Invalid fdcprintf value: %c\r\n", val);
			}
			return;
    }
		if (strncmp(cmd, "--ads_printf=", 13) == 0) {
			char val = cmd[13];
			if (val == '0' || val == '1')
			{
				ads_print_enabled = (val == '1') ? 1 : 0;
				printf("ADS print %s\r\n", ads_print_enabled ? "enabled" : "disabled");
			}
			else
			{
				printf("Invalid adsprintf value: %c\r\n", val);
			}
			return;
    }
		if (strncmp((char*)cmd, "help", 4) == 0)
		{
			CommonPrintf("--debug=X\r\n");
			CommonPrintf("ls\r\n");
			CommonPrintf("{\"mac\":\"X\"}\r\n");
			CommonPrintf("--cfg_set=${key1}=${val1}\r\n");
			CommonPrintf("--cfg_setx=X,${key}=${val}\r\n");
			CommonPrintf("--cfg_get=${key}\r\n");
			CommonPrintf("reboot\r\n");
			CommonPrintf("--fileid=X,0\r\n");
			CommonPrintf("--clear_fileid=X\r\n");
			CommonPrintf("--iwdg_get\r\n");
			CommonPrintf("--Stack_size\r\n");
			CommonPrintf("--debug_printf=X\r\n");
			CommonPrintf("--fdc_printf=X\r\n");
			CommonPrintf("--ads_printf=X\r\n");
			return;
		}
		
		printf("error=unknown command, rlt=409\r\n"); // 未识别的命令
		

		//		//  AT+sys=release\r\n 更改系统模式为发布模式
//    if (strncmp((char*)buf, "AT+sys=release", 14) == 0)
//    {
//			Systemmode = releasemode;
//			printf(" Systemmode = releasemode \r\n");
//			return;
//    }
//		//  AT+sys=iapboot\r\n 更改系统模式为升级模式
//    if (strncmp((char*)buf, "AT+sys=iapboot", 14) == 0)
//    {
//			Systemmode = IAPbootloader;
//			printf(" Systemmode = iapbootloader \r\n");
//			return;
//    }
//		//  AT+sys=debug\r\n 更改系统模式为调试模式
//    if (strncmp((char*)buf, "AT+sys=debug", 12) == 0)
//    {
//			Systemmode = Debugmode;
//			printf(" Systemmode = debugmode \r\n");
//			return;
//    }
}

void print_JsRoot(void) {

    // 打印 JsonDat_Root 基础字段
    CommonPrintf(
        "mac=%s, addr=%u, role=%d, vers_id=%u, age=%d, age_ms=%ld, "
        "iapSize=%d, iapMd5=%s, iapLoadStatus=%u, subcode=%u, ubootback=%d, "
        "debug=%d, console=%d, baudrate=%d, update_ok=%d, update_err=%d\n",
        JsRoot.mac, JsRoot.addr, JsRoot.role, JsRoot.vers_id, JsRoot.age, JsRoot.age_ms,
        JsRoot.iapSize, JsRoot.iapMd5, JsRoot.iapLoadStatus, JsRoot.subcode, JsRoot.ubootback,
        JsRoot.debug, JsRoot.console, JsRoot.baudrate, JsRoot.update_ok, JsRoot.update_err
    );
    // 打印 calib_rod
    CommonPrintf("[calib_rod.vol_values]=");
    for (int i = 0; i < CALIB_ROD_POINT_NUM; i++) {
        CommonPrintf("%.3f%s", JsWork.calib_rod.vol_values[i],
                       (i < CALIB_ROD_POINT_NUM - 1) ? "," : "\n");
    }
    // 打印 calib_oil_water
    CommonPrintf("[calib_oil_water.cap_values]=");
    for (int i = 0; i < CALIB_POINT_NUM; i++) {
        CommonPrintf("%.3f%s", JsWork.calib_oil_water.cap_values[i],
                       (i < CALIB_POINT_NUM - 1) ? "," : "\n");
    }
    // 打印 calib_residual_oil
    CommonPrintf("[calib_residual_oil.cap_values]=");
    for (int i = 0; i < CALIB_HEIGHT_POINT_NUM; i++) {
        CommonPrintf("%.3f%s", JsWork.calib_residual_oil.cap_values[i],
                       (i < CALIB_HEIGHT_POINT_NUM - 1) ? "," : "\n");
    }
    CommonPrintf("[calib_residual_oil.vol_values]=");
    for (int i = 0; i < CALIB_HEIGHT_POINT_NUM; i++) {
        CommonPrintf("%.3f%s", JsWork.calib_residual_oil.vol_values[i],
                       (i < CALIB_HEIGHT_POINT_NUM - 1) ? "," : "\n");
    }
    // 打印 JsWork 其他 float 字段
    CommonPrintf(
        "rod_vol_offset=%.3f, rod_dialog=%.3f, "
        "oil_para_indu=%.3f, oil_para_cap=%.3f, oil_cap_offset=%.3f, oil_dialog=%.3f, rod_coltime=%d\n",
        JsWork.rod_vol_offset,
        JsWork.rod_dialog,
        JsWork.oil_para_indu,
        JsWork.oil_para_cap,
        JsWork.oil_cap_offset,
        JsWork.oil_dialog,
				JsWork.rod_coltime		
    );
		CommonPrintf(        
        "res_para_indu=%.3f, res_para_cap=%.3f, res_cap_offset=%.3f, res_vol_offset=%.3f, "
        "res_cap_dialog=%.3f, res_vol_dialog=%.3f, res_oil_cap_coltime=%d, res_oil_vol_coltime=%d\n",       
        JsWork.res_para_indu,
        JsWork.res_para_cap,
        JsWork.res_cap_offset,
        JsWork.res_vol_offset,
        JsWork.res_cap_dialog,
        JsWork.res_vol_dialog,
				JsWork.res_oil_cap_coltime,
				JsWork.res_oil_vol_coltime
    );
		CommonPrintf(        
        "temp_vol_offset=%.3f, temp_dialog=%.3f, temp_coltime=%d\n",       
        JsWork.temp_vol_offset,
        JsWork.temp_dialog,
				JsWork.temp_coltime
    );
}

/* USER CODE BEGIN EFP */
