#include "ML307A.h"
#include "usart.h"
#include "circle_buffer.h"
#include "rtc.h"
#include <stdio.h>	//printf
#include <string.h>
#include <stdbool.h> // bool
#include "cmsis_os.h"
#include "main.h"
#include "queue.h"
#include "uType.h"
#include "remote.h"

extern circle_buf_t uart3CircleBuf;  // 环形缓冲区管理结构体
//extern circle_buf_t_2 uart3CircleBuf_2;  // 环形缓冲区管理结构体
#define BUFFER_SIZE4G 512
extern uint8_t receiveBuff4G[BUFFER_SIZE4G];

char responseBuf[256]; // AT指令应答的局部缓冲区
char responseBuf_2[256]; // AT指令应答的局部缓冲区

//static uint8_t uart3ParseBuf[BUFFER_SIZE4G]; // 解析+MIPURC: "rtcp"的缓冲区
//static uint16_t parseIndex = 0;  // 解析+MIPURC: "rtcp"的缓冲区指针
extern uint8_t receiveBuff4G_MIPURC[BUFFER_SIZE4G];
extern osMessageQueueId_t uart3rxqueueHandle;
bool MgnssFlag = false;// GNSS定位信息上报成功标志位
uint8_t Reset4G_flag = 0;

#define MAX_HEX_DATA_LEN 256  // 假设最多解析 256 字节的 HEX 数据
uint8_t parsed_4GMIPURC_Data[MAX_HEX_DATA_LEN];

extern bool flash_save_parameter_flag;
uint16_t msg_serial = 0;
extern volatile bool heartbeat_reply_received;
extern volatile bool unixtime_reply_received;
/**
  * @breaf 封装串口发送4G AT命令函数
  */
void USART_SendString(UART_HandleTypeDef *huart,char *str)
{
//	HAL_UART_Transmit(huart, (uint8_t*)str, strlen(str), 0xFFFF);	
	HAL_UART_Transmit_DMA(huart, (uint8_t*)str, strlen(str));
}
/**
  * @breaf 发送4G串口命令
  */
/*
uint8_t sendCmd_4G(char *pCmd, char *pRes, uint32_t timeOut, uint8_t sendNum)
{
	uint8_t i = 0;
	uint32_t time;
//	uint8_t found = 0;
	
	for (i = 0; i < sendNum; i++) 
	{
		time = timeOut * 10;															// 将超时时间转换为循环次数
		memset(receiveBuff4G, 0, sizeof(receiveBuff4G));	// 清空接收缓冲区
		USART_SendString(&huart3, pCmd);									// 发送命令字符串
//		HAL_Delay(100);
		osDelay(100);

		while (time--) 
		{
			if (strstr((const char *)receiveBuff4G, pRes) != NULL) 
				{
					printf("-- %s\n", receiveBuff4G); // 打印接收到的内容
					//如果接收缓冲区包含预期的响应
					return 1;
				}
//			HAL_Delay(100);
				osDelay(100);
		}
		printf("! %s\n", receiveBuff4G);
	}
	return 0;
}
*/

uint8_t sendCmd_4G(char *pCmd, char *pRes1, uint32_t timeOut, uint8_t sendNum)
{
    uint8_t i;
    uint32_t time;
    uint8_t receivedByte;

    memset(responseBuf, 0, sizeof(responseBuf)); // 清空临时缓冲区

    for (i = 0; i < sendNum; i++)
    {
        time = timeOut * 10; // 计算超时时间

        // ★ 发送前丢弃旧数据 ★
        __HAL_UART_DISABLE_IT(&huart3, UART_IT_IDLE); // 可选：保护指针修改
        uart3CircleBuf.r = uart3CircleBuf.w;          // 丢弃旧数据
        __HAL_UART_ENABLE_IT(&huart3, UART_IT_IDLE);
//printf("send command: %s\r\n", pCmd);
			
        USART_SendString(&huart3, pCmd); // 发送 AT 指令
        osDelay(100);                    // 等待模块返回（短暂延时）

        while (time--)
        {
            uint8_t gotNewData = 0;

            // 读取环形缓冲区内的新数据
            while (circle_buf_read(&uart3CircleBuf, &receivedByte) == 0)
            {
                gotNewData = 1;

                uint16_t len = strlen(responseBuf);
                if (len < sizeof(responseBuf) - 1)
                {
                    responseBuf[len] = receivedByte;
                    responseBuf[len + 1] = '\0'; // 字符串结束符
                }
            }

            if (gotNewData)
						{
								// ★ 判断是否匹配 ★
                if (pRes1 && strstr(responseBuf, pRes1) != NULL)
                {
//                    printf("-: %s\n", responseBuf);
                    return 1; // 任意一个匹配成功
                }
						}

            osDelay(10);
        }

        printf("Timeout_!: %s\n", responseBuf); // 超时打印
    }

    return 0;
}

uint8_t sendCmd_4G_2(char *pCmd, char *pRes1, char *pRes2, uint32_t timeOut, uint8_t sendNum)
{
    uint8_t i;
    uint32_t time;
    uint8_t receivedByte;

    memset(responseBuf_2, 0, sizeof(responseBuf_2)); // 清空临时缓冲区

    for (i = 0; i < sendNum; i++)
    {
        time = timeOut * 10; // 计算超时时间

        // ★ 发送前丢弃旧数据 ★
        __HAL_UART_DISABLE_IT(&huart3, UART_IT_IDLE); // 可选：保护指针修改
        uart3CircleBuf.r = uart3CircleBuf.w;          // 丢弃旧数据
        __HAL_UART_ENABLE_IT(&huart3, UART_IT_IDLE);
//printf("send command: %s\r\n", pCmd);
			
        USART_SendString(&huart3, pCmd); // 发送 AT 指令
        osDelay(100);                    // 等待模块返回（短暂延时）

        while (time--)
        {
            uint8_t gotNewData = 0;

            // 读取环形缓冲区内的新数据
            while (circle_buf_read(&uart3CircleBuf, &receivedByte) == 0)
            {
                gotNewData = 1;

                uint16_t len = strlen(responseBuf_2);
                if (len < sizeof(responseBuf_2) - 1)
                {
                    responseBuf_2[len] = receivedByte;
                    responseBuf_2[len + 1] = '\0'; // 字符串结束符
                }
            }

            if (gotNewData)
						{
								// ★ 判断是否匹配 ★
                if ((pRes1 && strstr(responseBuf_2, pRes1) != NULL) ||
                    (pRes2 && strstr(responseBuf_2, pRes2) != NULL))
								
                {
//                    printf("-: %s\n", responseBuf_2);
                    return 1; // 任意一个匹配成功
                }
						}

            osDelay(10);
        }

        printf("Timeout_!: %s\n", responseBuf_2); // 超时打印
    }

    return 0;
}

uint8_t sendCmd_4G_3(char *pCmd, char *pRes1, char *pRes2, uint32_t timeOut, uint8_t sendNum)
{
    uint8_t i;
    uint32_t time;
    uint8_t receivedByte;

    memset(responseBuf_2, 0, sizeof(responseBuf_2)); // 清空临时缓冲区

    for (i = 0; i < sendNum; i++)
    {
        time = timeOut * 10; // 计算超时时间

        // ★ 发送前丢弃旧数据 ★
        __HAL_UART_DISABLE_IT(&huart3, UART_IT_IDLE); // 可选：保护指针修改
        uart3CircleBuf.r = uart3CircleBuf.w;          // 丢弃旧数据
        __HAL_UART_ENABLE_IT(&huart3, UART_IT_IDLE);

        USART_SendString(&huart3, pCmd); // 发送 AT 指令
        osDelay(100);                    // 等待模块返回（短暂延时）

        uint8_t matchFlag = 0;

        while (time--)
        {
            uint8_t gotNewData = 0;

            // 读取环形缓冲区内的新数据
            while (circle_buf_read(&uart3CircleBuf, &receivedByte) == 0)
            {
                gotNewData = 1;

                uint16_t len = strlen(responseBuf_2);
                if (len < sizeof(responseBuf_2) - 1)
                {
                    responseBuf_2[len] = receivedByte;
                    responseBuf_2[len + 1] = '\0'; // 字符串结束符
                }
            }

            if (gotNewData)
            {
                // 每次有新数据都检测是否有完整的行
                char *lineStart = responseBuf_2;
                while (1)
                {
                    // 查找是否有一行结束符
                    char *lineEnd = strstr(lineStart, "\r\n");
                    if (lineEnd == NULL)
                        break; // 没有完整行，等待更多数据

                    // 截断这一行，形成完整字符串
                    *lineEnd = '\0';

                    // 打印完整行
//                    printf("%s\n", lineStart);

//                    // 重点：如果是+MIPURC开头的数据
//                    if (strstr(lineStart, "+MIPURC: \"rtcp\"") != NULL)
//                    {
//                        printf("MIPURC Data: %s\n", lineStart);
//                    }

                    // 判断是否有匹配到成功应答
                    if ((pRes1 && strstr(lineStart, pRes1) != NULL) ||
                        (pRes2 && strstr(lineStart, pRes2) != NULL))
                    {
                        matchFlag = 1;
                    }

                    // 移动到下一行
                    lineStart = lineEnd + 2;
                }

                // 剩下的内容移动到buffer头部（继续拼接未完整行）
                uint16_t remainLen = strlen(lineStart);
                memmove(responseBuf_2, lineStart, remainLen + 1); // +1 包含结束符
            }

            osDelay(10);
        }

        if (matchFlag)
        {
//            printf("%s\n", responseBuf_2); // 打印剩余数据
            return 1; // 任意一个匹配成功
        }

        printf("Timeout_!: %s\n", responseBuf_2); // 超时打印
    }

    return 0;
}
void process_uart3_buffer(void)
{
	Uart3Rx_msg uart3_msg;
	
	if (xQueueReceive(uart3rxqueueHandle, &uart3_msg,  (TickType_t)500) == pdPASS) // portMAX_DELAY   (TickType_t)0
	{
				uint16_t len = (uart3_msg.length < sizeof(receiveBuff4G_MIPURC)) ? uart3_msg.length : (sizeof(receiveBuff4G_MIPURC) - 1);
				memcpy(receiveBuff4G_MIPURC, uart3_msg.data, len);
				receiveBuff4G_MIPURC[len] = '\0';  // 确保字符串结尾
        printf("Queue Data: %s\n", receiveBuff4G_MIPURC);
				if(system_cloud_mode == Cloud_4G_MODE)
				{
						process_MIPURC_data(receiveBuff4G_MIPURC, len);
				}
	}
}
void process_MIPURC_data(uint8_t *buf, uint16_t len) 
{
    const char *mipurcStr = "+MIPURC: \"rtcp\",0,";
    uint16_t mipurcLen = strlen(mipurcStr);
    int mipurcPos = -1;

    // **查找 "+MIPURC: \"rtcp\",0," 位置**
    for (uint16_t i = 0; i <= len - mipurcLen; i++) {
        if (memcmp(buf + i, mipurcStr, mipurcLen) == 0) {
            mipurcPos = i;
            break;
        }
    }

    // **如果找到 "+MIPURC: \"rtcp\",0,"**
    if (mipurcPos != -1) 
		{
        uint8_t *dataStart = buf + mipurcPos + mipurcLen; // `+MIPURC: "rtcp",0,` 后的数据

        // **提取数据长度**
        char *commaPos = strchr((char *)dataStart, ',');
        if (commaPos == NULL) {
            printf("Invalid MIPURC format (missing length)\n");
            return;
        }

        int expectedDataLen = 0;
        if (sscanf(commaPos - 2, "%d,", &expectedDataLen) != 1) {  // **修正解析**
            printf("Invalid MIPURC format (length parse error)\n");
            return;
        }

        // 找到实际数据部分（跳过逗号后面的空格）
        char *hexDataStr = commaPos + 3;  // 这里 +3 是跳过 ", "，确保指向 HEX 数据

        // **转换 HEX 字符串到二进制**
        int actualDataLen = hexStringToBytes(hexDataStr-2, parsed_4GMIPURC_Data, MAX_HEX_DATA_LEN);
        if (actualDataLen < 0) {
            printf("HEX Data parse error! Code: %d\n", actualDataLen);
            return;
        }
        // **检查长度是否匹配**
        if (expectedDataLen == actualDataLen-1) 
				{
//            printf("Extracted JT808 Data (%d bytes): ", expectedDataLen);
//            for (int i = 0; i < expectedDataLen; i++) {
//                printf("%02X ", parsed_4GMIPURC_Data[i]);
//            }
//            printf("\n");

            // 直接解析 JT808 数据
            parse_JT808_frame(parsed_4GMIPURC_Data, expectedDataLen);
        } else {
            printf("Length mismatch: expected %d, got %d. Ignoring.\n", expectedDataLen, actualDataLen);
        }
    }
}

/**
 * @brief 等待UART3接收预期字符串中的任意一个 WIFI用
 * @param keywords      关键词数组（多个字符串）
 * @param keyword_count 关键词数量
 * @param buffer        存储接收数据的缓冲区
 * @param buffer_len    缓冲区长度
 * @param timeout_ms    等待超时时间（毫秒）
 * @return              匹配到的关键词索引（0 ~ keyword_count-1），否则返回 -1
 */
int wait_uart3_multi_response(const char* keywords[], int keyword_count, char* buffer, uint16_t buffer_len, uint32_t timeout_ms)
{
    TickType_t start_tick = xTaskGetTickCount();
    uint16_t total_len = 0;
    Uart3Rx_msg uart3_msg;

    while ((xTaskGetTickCount() - start_tick) < pdMS_TO_TICKS(timeout_ms))
    {
        if (xQueueReceive(uart3rxqueueHandle, &uart3_msg, pdMS_TO_TICKS(300)) == pdPASS)
        {
            uint16_t copy_len = (uart3_msg.length < (buffer_len - total_len - 1)) ? uart3_msg.length : (buffer_len - total_len - 1);
            memcpy(buffer + total_len, uart3_msg.data, copy_len);
            total_len += copy_len;
            buffer[total_len] = '\0';

						printf("Recv: %s\r\n", buffer);
						// 检查并提取 +TRDTC: 数据
						extract_and_parse_trdtc(buffer);
            for (int i = 0; i < keyword_count; ++i)
            {
                if (strstr(buffer, keywords[i]) != NULL)
                {
//                    printf("Matched keyword[%d]: %s\r\n", i, keywords[i]);
                    return i;
                }
            }
						
        }
    }

    printf("Timeout\r\n");
    return -1;
}

/**
  * @brief 从 UART 数据中提取并解析 +TRDTC: 开头的 JT808 帧数据
  * @param buffer 接收到的完整字符串（含 +TRDTC:）
  */
void extract_and_parse_trdtc(const char* buffer)
{
	
    const char* trdtc_start = strstr(buffer, "+TRDTC:");
    if (!trdtc_start)
        return;
    // 查找第一个 "7E" 作为帧起始
    const char* frame_start = strstr(trdtc_start, "7E");
    if (!frame_start)
        return;
//		printf("first 7E \r\n");
    const char* frame_end = strstr(frame_start + 2, "7E"); // 查找第二个 7E
    if (frame_end)
    {
        frame_end += 2; // 包含结束 7E
    }
    else
    {
        // 如果没找到第二个7E，尝试查找\r\n作为帧尾
        frame_end = strstr(frame_start, "\r\n");
        if (!frame_end)
            return;  // 没有找到帧尾，退出

        // 不包括 \r\n，只处理到前面为止
    }
//		printf("frame_end 7E \r\n");
    int hex_len = frame_end - frame_start;

    if (hex_len <= 0 || hex_len > 512)
        return;

    uint8_t jt808_frame[256];
    int byte_len = 0;
    char byte_str[3] = {0};

    for (int i = 0; i < hex_len; i += 2)
    {
        if (frame_start[i] == '\0' || frame_start[i + 1] == '\0')
            break;

        byte_str[0] = frame_start[i];
        byte_str[1] = frame_start[i + 1];
        jt808_frame[byte_len++] = (uint8_t)strtol(byte_str, NULL, 16);
    }

    if (byte_len > 0)
        parse_JT808_frame(jt808_frame, byte_len);
}

void parse_JT808_frame(uint8_t *frame, uint16_t length)
{
//    printf("JT808 Frame Received (Len: %d): ", length);
//    for (uint16_t i = 0; i < length; i++)
//    {
//        printf("%02X ", frame[i]);
//    }
//    printf("\n");
		
		uint16_t msg_id = (frame[1] << 8) | frame[2]; // 消息 ID
//    uint16_t msg_length = (frame[3] << 8) | frame[4]; // 消息体长度
//    uint8_t *phone_number = &frame[5]; // 手机号 (BCD 编码)
    msg_serial = (frame[11] << 8) | frame[12]; // 消息流水号
    uint8_t *payload = &frame[13]; // 消息体数据
    uint8_t received_checksum  = frame[length - 2]; // 校验码
		
		uint8_t calculated_checksum = Calculate_Checksum(&frame[1], length - 3);
		if (calculated_checksum != received_checksum )
    {
        printf("Checksum Mismatch! Expected: %02X, Received: %02X\n", calculated_checksum, received_checksum);
        return;
    }
		
//		printf("JT808 Frame Received (Len: %d)\n", length);
//    printf("Message ID: 0x%04X, Length: %d, Serial: %d\n", msg_id, msg_length, msg_serial);

		switch (msg_id)
    {
				case 0x80FF: // 服务器下发unix时间
						if ((length - 13) >= 4) // 数据体长度至少 4 字节
						{
								// 从 payload 中提取 4 字节，转成 uint32_t
								uint32_t timestamp = 
										((uint32_t)payload[0] << 24) |
										((uint32_t)payload[1] << 16) |
										((uint32_t)payload[2] << 8)  |
										((uint32_t)payload[3]);

//								printf("Received UNIX Timestamp: %lu\r\n", timestamp);

								// 设置 RTC 时间
								Set_RTC_Time((time_t)timestamp);
								unixtime_reply_received = true;
						}
						else
						{
								printf("Invalid 0x80FF payload length: %d\r\n", length - 13);
						}
						break;
			
        case 0x8001: // 终端通用应答
            if (length > 18 && frame[17] == 0)
                printf("Heart_callback_OK\n");
								heartbeat_reply_received = true;
            break;

        case 0x8100: // 终端注册应答
            if (length > 14 && frame[13] == 0)
                printf("Cloud_Register_callback_OK\n");
            break;

        case 0x8103: // 终端参数设置
            parse_JT808_8103(payload, length);
						Send_General_response();
            break;

        default:
            printf("Unknown Message ID: 0x%04X\n", msg_id);
            break;
			}
		
		
}

// 解析 JT808 0x8103 终端参数设置
void parse_JT808_8103(uint8_t *payload, uint16_t length)
{
    printf("Terminal Parameter Settings Received:\n");
    for (uint16_t i = 1; i < length;)
    {
				
        uint16_t param_id = (payload[i] << 8) | payload[i + 1]; // 参数 ID
        uint8_t param_length = payload[i + 2]; // 参数长度
        uint8_t param_value = payload[i + 3]; // 只支持 1 字节参数

        printf("Param ID: 0x%04X, Length: %d, Value: %d\n", param_id, param_length, param_value);

        switch (param_id)
        {
            case 0xF101: flash_data.controltransmit_flag = param_value; break;
            case 0xF102: flash_data.temp_first_threshold = param_value; break;
            case 0xF103: flash_data.temp_second_threshold = param_value; break;
            case 0xF104: flash_data.pressure_threshold = param_value; break;
            case 0xF105: flash_data.co_threshold = param_value; break;
            case 0xF106: flash_data.h2_threshold = param_value; break;
            case 0xF107: flash_data.smallboard_upload_frequency = param_value; break;
            case 0xF108: flash_data.heart_upload_frequency = param_value; break;
            case 0xF109: flash_data.mainboard_upload_frequency = param_value; break;
            default:
                printf("Unknown Parameter ID: 0x%04X\n", param_id);
                break;
        }

        i += (3 + param_length); // 跳过已解析的参数
    }
		CAN_Send_Parameter(0x00110000, &flash_data, 8);
    flash_save_parameter_flag = true;
    printf("Updated flash_data:\n");
    printf("Control Transmit Flag: %d\n", flash_data.controltransmit_flag);
    printf("Temp First Threshold: %d°C\n", flash_data.temp_first_threshold);
    printf("Temp Second Threshold: %d°C\n", flash_data.temp_second_threshold);
    printf("Pressure Threshold: %d Pa\n", flash_data.pressure_threshold);
    printf("CO Threshold: %d ppm\n", flash_data.co_threshold);
    printf("H2 Threshold: %d ppm\n", flash_data.h2_threshold);
    printf("Smallboard Upload Frequency: %d s\n", flash_data.smallboard_upload_frequency);
    printf("Heart Upload Frequency: %d s\n", flash_data.heart_upload_frequency);
    printf("Mainboard Upload Frequency: %d s\n", flash_data.mainboard_upload_frequency);
}

// HEX 字符串转换为二进制数据
int hexStringToBytes(const char *hexStr, uint8_t *outBytes, int maxLen) 
{
    int hexStrLen = strlen(hexStr);
    if (hexStrLen % 2 != 0) {
        return -1;  // HEX 字符串长度必须是偶数
    }
    
    int byteLen = hexStrLen / 2;
    if (byteLen > maxLen) {
        return -2;  // 数据超出缓冲区
    }

    for (int i = 0; i < byteLen; i++) {
        sscanf(hexStr + 2 * i, "%2hhx", &outBytes[i]);  // 每两个字符转换成 1 个字节
    }
    
    return byteLen;
}

/**
* @breaf MQTT连接至MQTT服务器,订阅,发布消息
  */
// 封装MQTT连接至MQTT服务器
uint8_t mqttconn(char *IpAddr, uint16_t port, char *ID, char *User, char *Passwd, char* pRes)
{
	
	char MQTT_Sendbuf[128]; 
	sprintf((char *)MQTT_Sendbuf,"AT+MQTTCONN=0,\"%s\",\"%d\",\"%s\",\"%s\",\"%s\"\r\n",IpAddr, port, ID,User, Passwd);
	sendCmd_4G(MQTT_Sendbuf,pRes,1,1);
	if(sendCmd_4G(MQTT_Sendbuf,pRes,1,1))
	{
		return 1;
	}
	return 0;
}
// 连接至MQTT服务器,订阅
void MQTTCONN(void)
{
	char MQTT_SUBbuf[50]; // 订阅字符缓冲区
	char topicb[50];//*服务器发布主题B
	
	// 连接至MQTT服务器
	mqttconn((char*)MQTTADDR,MQTTPORT,"DCCJC",(char*)MQTTUSER,(char*)MQTTPSWD,"+MQTTURC: \"conn\",0,0");//	printf("#连接MQTT成功\r\n");
		
	// 订阅主题
	snprintf(MQTT_SUBbuf, 50, "AT+MQTTSUB=0,\"%s\",1\r\n", topicb);
	// 发送订阅指令并检查结果
	sendCmd_4G(MQTT_SUBbuf, "+MQTTURC: \"suback\"", 1, 1);// printf("#订阅成功\r\n");		
		
}
// 发布消息QoS=0;
uint8_t MQTT_PUB(uint8_t connect_id, char *topic, char *mesg, char* pRes)
{
	char MQTT_Sendbuf[200]; 
	uint8_t length = strlen(mesg);
	sprintf((char *)MQTT_Sendbuf,"AT+MQTTPUB=%d,\"%s\",0,0,0,%d,\"%s\"\r\n",connect_id, topic, length, mesg);
	sendCmd_4G(MQTT_Sendbuf,pRes,1,1);
//	if(sendCmd_4G(MQTT_Sendbuf,pRes,1,1)){// printf("#发布心跳成功\r\n");
//		return 1;
//	}
	return 1;
}

// 断开MQTT连接
void MQTTDISCONN(void)
{
	sendCmd_4G("AT+MQTTDISC=0\r\n", "OK", 1, 1);// printf("#断开MQTT连接成功\r\n");		

}
/**
  * @breaf 建立TCP连接
  */
// 封装建立TCP连接函数
void tcpconn(char *value, uint8_t cid, char *IPaddr, uint16_t port, uint8_t tcpConnmode)
{
	char *ptr = value;
	ptr += sprintf(ptr, "AT+MIPOPEN=%d,\"TCP\",\"%s\",%d,60,%d\r\n",cid,IPaddr,port,tcpConnmode);
}
// 建立TCP连接平台端IP及端口号
void TCPCONN(void)
{
	char TCPconnvalue[100];
	tcpconn(TCPconnvalue, 1, JIALONGip, JIALONGport,0);		//cid=1		tcpConnmode=0 普通模式
}

/**
* @breaf 连续定位信息上报
  */
void GNSSLOC(void)
{
//	sendCmd_4G("AT+MIPCFG=\"encoding\",1,1,1\r\n", "OK", 1, 1);//默认输入输出为ASCII，0    发16，1    接16，1
			
	sendCmd_4G("AT+MGNSSCFG=\"nmea/mask\",0\r\n", "OK", 1, 1);
	sendCmd_4G("AT+MGNSSLOC=0\r\n", "OK", 1, 1);
	sendCmd_4G("AT+MGNSS=1\r\n", "OK", 1, 1);
	if(sendCmd_4G("AT+MGNSSCFG=\"nmea/mask\",0\r\n", "OK", 1, 1))
	{ // printf("#使能NMEA信息\r\n");
		if(sendCmd_4G("AT+MGNSSLOC=0\r\n", "OK", 1, 1))
		{// printf("#关闭自动定位上报\r\n");
			if(sendCmd_4G("AT+MGNSS=1\r\n", "OK", 1, 1))
			{// printf("开启MGNSS\r\n");
				MgnssFlag=true;
			}
		}
	}
}

	/**
  * @breaf 4G模块初始化
  */
void ML307A_INIT(void)
{
	
	if (sendCmd_4G("AT\r\n", "OK", 1, 5)) 
	{	
		printf("AT_OK\r\n");
	}else
	{
		printf("AT_fail\r\n");
		ML307AReset();
	}
	if (sendCmd_4G("AT+CPIN?\r\n", "+CPIN: READY", 1, 5)) 
	{
		printf("CPIN_OK\r\n");
	}
	if (sendCmd_4G("AT+CEREG?\r\n", "+CEREG: 0,1", 1, 5)) 
	{
		printf("CEREG_OK\r\n");
	}			
	if(sendCmd_4G("AT+MIPCLOSE=1\r\n", "+MIPSEND:", 1, 1))//关闭TCP连接
	{
		printf("MIPCLOSE_OK\r\n");
	}
	ML307A_MQTT_Init();
}
void ML307A_Init(void)
{	
	
	for (int attempt_count = 0; attempt_count < 3; attempt_count++)
	{
		sendCmd_4G("AT\r\n", "OK", 1, 5);
		HAL_Delay(10);
		sendCmd_4G("AT+CPIN?\r\n", "+CPIN: READY", 1, 5);
		printf("CPIN_OK\r\n");	
		HAL_Delay(10);
		sendCmd_4G("AT+CEREG?\r\n", "+CEREG: 0,1", 1, 5);
		printf("Network ing...\r\n");	
		if (sendCmd_4G("AT+CPIN?\r\n", "+CPIN: READY", 1, 5)) 
		{
				printf("PIN认证成功\r\n");	
				if (sendCmd_4G("AT+CEREG?\r\n", "+CEREG: 0,1", 1, 5)) 
				{
					printf("驻网成功\r\n");	
					break;					
				}
		} else {
				ML307AReset();
		}
		
		break;
	}					
}

/*
char TCPconnvalue[100];// TCP的IP地址端口号缓冲区
case 2:           
//            tcpconn(TCPconnvalue, 1, JIALONGip, JIALONGport,0);		//cid=1		tcpConnmode=0 普通模式
//            if (sendCmd_4G(TCPconnvalue, "+MIPOPEN: 1,0", 1, 1)) {
//                step4g++;
//            }
						step4g=3;
            break;
        case 3:
            sendCmd_4G("AT+MIPCFG=\"encoding\",0,2,0\r\n", "OK", 1, 1);////输入配置为转义字符模式
            if (!reset4Gmodule) {
                if (sendCmd_4G("AT+MGNSSCFG=\"nmea/mask\",0\r\n", "OK", 1, 1)) {
                    printf("#使能NMEA信息\r\n");
                    if (sendCmd_4G("AT+MGNSSLOC=0\r\n", "OK", 1, 1)) {
                        printf("#关闭自动定位上报\r\n");
                        if (sendCmd_4G("AT+MGNSS=1\r\n", "OK", 1, 1)) {
                            printf("#开启MGNSS\r\n");
                            MgnssFlag = true;
                        }
                    }
                }
						step4g++;
            } else {
              reset4Gmodule = false;
            }
            break;
        case 4:
            MQTTCONN();         					
						char data_buff[256]; //组合JSON报文数据
						uint8_t run_state = 0; 
						sprintf((char *)data_buff,"{\"temperature\":{\"ID\":180}}"); 						
						run_state=MQTT_PUB(0,Publish_Topic,data_buff,"+MQTTURC: \"puback\"");//上报
						if(run_state==1)
						{
							printf("4G模块发布数据至MQTT成功\r\n");
							run_state = 0;
						} 

*/


void Send_AT_Command(char *command) 
{
    // 发送AT指令时添加换行符
    char command_with_newline[256];
    snprintf(command_with_newline, sizeof(command_with_newline), "%s\r\n", command);

    // 发送指令
    HAL_UART_Transmit(&huart3, (uint8_t *)command_with_newline, strlen(command_with_newline),1000);
}
void Receive_Response(char *buffer, uint16_t size) 
{
    
	
    // 接收数据
    HAL_UART_Receive_DMA(&huart3, (uint8_t *)buffer, size - 1);
    
    // 添加字符串结束符
    buffer[size - 1] = '\0';
		memset(buffer, 0, size);  // 清空接收缓冲区
}


int Check_Response(char *buffer, uint16_t size) 
{
    Receive_Response(buffer, size);
    
    // 判断是否为错误响应
    if (strstr(buffer, "+CME ERROR") != NULL) {
        return 0; // 失败
    }

    // 判断是否为特定成功响应
    if (strstr(buffer, "+MQTTREAD") != NULL || 
        strstr(buffer, "+MQTTPUB") != NULL || 
        strstr(buffer, "+MQTTSUB") != NULL || 
        strstr(buffer, "+MQTTURC") != NULL ||
				strstr(buffer, "+CEREG:0,1") != NULL
		) {
        return 1; // 成功
    }

    // 判断是否为OK响应
    if (strstr(buffer, "OK") != NULL) {
        return 1; // 成功
    }

    return 0; // 其他情况视为失败
}

int Send_Command_Check_Response(char *command, char *response_buffer, uint16_t buffer_size) 
{
    Send_AT_Command(command);
    return Check_Response(response_buffer, buffer_size);
}

void MQTT_Process(void) 
{
    char response[256];  // 存放接收的响应数据
    int total_attempt = 0;  // 总共跳回清除会话模式的次数
    int attempt = 0;        // 每个步骤的重试次数
    int success = 0;        // 是否成功标志位

    while (total_attempt < 5) {  // 最多尝试5次清除会话模式
        total_attempt++;  // 每次从头开始都计为一次清除会话模式的执行

        // 1. 清除会话模式
        attempt = 0;  // 重置步骤重试计数
        while (attempt < 3) {  // 每个步骤最多重试3次
            success = Send_Command_Check_Response("AT+MQTTCFG=\"clean\",0,1", response, sizeof(response));
            if (success)
//						printf("清除会话模式成功\n");							
						break;  // 成功则继续下一个步骤

						attempt++;
						
        }
        if (!success) continue;  // 如果重试3次仍然失败，则重新开始整个流程
				HAL_Delay(1);
        // 2. 配置为接收缓存模式
        attempt = 0;  // 重置步骤重试计数
        while (attempt < 3) {
            success = Send_Command_Check_Response("AT+MQTTCFG=\"cached\",0,1", response, sizeof(response));
            if (success) {
						printf("配置为接收缓存模式成功\n");
						break;
						}
            attempt++;
        }
        if (!success) continue;  // 如果失败则重新开始整个流程
				HAL_Delay(1);
        // 3. 连接至MQTT服务器
        attempt = 0;
        while (attempt < 3) {
            success = Send_Command_Check_Response("AT+MQTTCONN=0,\"183.230.40.96\",1883,\"test0923_1\",\"0w8A8Kloxm\",\"version=2018-10-31&res=products%2F0w8A8Kloxm%2Fdevices%2Ftest0923_1&et=1853416411&method=md5&sign=VBoBVpruRrjQA6LjW2KEXw%3D%3D\"", response, sizeof(response));
            if (success) {
							printf("连接至MQTT服务器成功\n");
						break;
						}
            attempt++;
        }
        if (!success) continue;
				HAL_Delay(1);
        // 4. 订阅主题
        attempt = 0;
        while (attempt < 3) {
            success = Send_Command_Check_Response("AT+MQTTSUB=0,\"$sys/0w8A8Kloxm/test0923_1/#\",1", response, sizeof(response));
            if (success) {
							printf("订阅主题成功\n");
							break;
						}
            attempt++;
        }
        if (!success) continue;
				HAL_Delay(1);
        // 5. 发布消息
        attempt = 0;
        while (attempt < 3) {
            success = Send_Command_Check_Response("AT+MQTTPUB=0,\"$sys/0w8A8Kloxm/test0923_1/dp/post/json\",0,0,0,65,\"{\"id\":123,\"dp\":{\"gps\":[{\"v\":{\"lon\":20.898888,\"lat\":15.268888}}]}}\"", response, sizeof(response));
            if (success){ 
						printf("发布消息成功\n");	
						break;
						}
            attempt++;
        }
        if (!success) continue;

//        // 6. 读取缓存数据
//        attempt = 0;
//        while (attempt < 3) {
//            success = Send_Command_Check_Response("AT+MQTTREAD=0,1", response, sizeof(response));
//            if (success) {
//							printf("读取缓存数据成功");
//							break;
//						}
//            attempt++;
//        }
//        if (!success) continue;

//        // 7. 断开连接
//        attempt = 0;
//        while (attempt < 3) {
//            success = Send_Command_Check_Response("AT+MQTTDISC=0", response, sizeof(response));
//            if (success) {
//						printf("断开连接成功");
//						break;
//						}
//            attempt++;
//        }
//        if (!success) continue;

        // 如果所有步骤都成功，则退出函数
        break;
    }

    // 如果达到5次还不成功，可以输出日志或执行其他错误处理
    if (total_attempt >= 5) {
        // 错误处理
        printf("MQTT连接失败，达到最大重试次数。\n");
    }
}


void ML307A_MQTT_Init(void)
{
//	check_network_connection();
	char response[256];  // 存放接收的响应数据
	Send_Command_Check_Response("AT+MQTTDISC=0", response, sizeof(response));
	HAL_Delay(100);
	Send_Command_Check_Response("AT+MQTTCFG=\"clean\",0,1", response, sizeof(response));
	HAL_Delay(100);
	Send_Command_Check_Response("AT+MQTTCFG=\"cached\",0,1", response, sizeof(response));
	HAL_Delay(100);
	Send_Command_Check_Response("AT+MQTTCONN=0,\"106.14.207.159\",1883,\"BATT|securemode=2,signmethod=hmacsha1,timestamp=1729351701003|\",\"BATT&k1vccLJvsUy\",\"E664F110C5752BDB294C14ADC5594A673C6552B8\"", response, sizeof(response));
	HAL_Delay(100);
	Send_Command_Check_Response("AT+MQTTSUB=0,\"/sys/k1vccLJvsUy/BATT/thing/service/property/set\",1", response, sizeof(response));	
}

int cpin_attempts = 0;  // AT+CPIN计数3次的计数器
void ML307A_NET_Init(void)
{	
	HAL_Delay(100);
	uint8_t step4g = 0;// 模组4G初始化步骤标志位
	char response[256];  // 存放接收的响应数据
//	if(Reset4G_flag)
//	{
//		Reset4G_flag = 0;
//		step4g = 0;
//	}
	switch(step4g)
	{			
		case 0:  
		{
//			if (sendCmd_4G("AT\r\n", "OK", 1, 4))
			HAL_Delay(10);
			if (Send_Command_Check_Response("AT", response, sizeof(response)))  
			{
				printf("AT_OK\r\n");
				step4g++;  // 进入下一步
			}else
			{				
				printf("AT_fail\r\n");
				step4g++;
			}

		}
		case 1:
		{	
			HAL_Delay(10);
//			if (sendCmd_4G("AT+CEREG?\r\n", "+CEREG:0,1", 1, 5)) 
			if (Send_Command_Check_Response("AT+CEREG?", response, sizeof(response))) 
			{
				printf("CEREG_OK\r\n");
				HAL_Delay(500);
				step4g++;  // 进入下一步
				cpin_attempts = 0;  // 重置计数器
			}
			else
			{
//				cpin_attempts++;  // 增加计数
//				if (cpin_attempts >= 3)  // 如果已经发送了3次
//				{
////					sendCmd_4G("AT+CGATT=1\r\n", "OK", 1, 5);  // 手动驻网
//					Send_Command_Check_Response("AT+CGATT=1", response, sizeof(response));
//					HAL_Delay(100);
//					printf("CEREG_fail\r\n");
//					cpin_attempts = 0;  // 重置计数器
//				}
//				Send_Command_Check_Response("AT+CGATT=1", response, sizeof(response));
				HAL_Delay(100);
				printf("CEREG_fail\r\n");
				step4g ++;  
			}

		}
		case 2:
		{
			HAL_Delay(10);
//			sendCmd_4G("AT+CFUN=1\r\n", "OK", 1, 5);  // 确保CFUN为1
//			if(Send_Command_Check_Response("AT+CFUN=1", response, sizeof(response)))
//			{
//			HAL_Delay(100);
//			step4g++;  // 进入下一步
//			printf("AT+CFUN_ok\r\n");
//			}
			step4g++;  // 进入下一步
//			else
//			{
//				step4g++;  // 进入下一步
//				printf("AT+CFUN_fail\r\n");
//			}
		}
		case 3:
		{
			HAL_Delay(10);
			// 配置为自动连网（模组应用层网络）
			if(Send_Command_Check_Response("AT+MUECONFIG=\"autoconn\",1", response, sizeof(response)))
			{
			HAL_Delay(100);
			printf("AT+MUECONFIG_ok\r\n");
			step4g++;  // 进入下一步
			}
			else
			{
				step4g++;  // 进入下一步
				printf("AT+MUECONFIG_fail\r\n");
			}
		}
		case 4:
		{ 
			HAL_Delay(10);
			// 配置为自动拨号（上位机网卡拨号）
			if(Send_Command_Check_Response("AT+MDIALUPCFG=\"auto\",1", response, sizeof(response)))
			{
			HAL_Delay(100);
			step4g++;  // 进入下一步
			printf("AT+MDIALUPCFG_ok\r\n");
			}
			else
			{
				step4g++;  // 进入下一步
				printf("AT+MDIALUPCFG_fail\r\n");
			}	
		}
		case 5:
		{
			HAL_Delay(10);
			ML307A_MQTT_Init();  // 初始化MQTT
			break;
		}
		case 7:
		{
			break;
		}

	}		
}
/**
  * @breaf 重启模块
  */
void ML307AReset(void)
{
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_RESET);
	HAL_Delay(500);
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_SET);
	HAL_Delay(2000);
	Reset4G_flag = 1;
  printf("Reset_4G\n");

}


void check_network_connection(void) 
{
    char response[100];

    // 发送 AT+CREG? 查询网络注册状态
    Send_Command_Check_Response("AT+CREG?", response, sizeof(response));
		HAL_Delay(10);
    // 检查是否已注册到网络，通常返回 0,1 或 0,5 代表已连接
    if (strstr(response, "0,1") == NULL && strstr(response, "0,5") == NULL) {
        // 如果未联网，执行联网操作
        Send_Command_Check_Response("AT+CGATT=1", response, sizeof(response));
				HAL_Delay(10);
        // 检查联网是否成功
        Send_Command_Check_Response("AT+CGATT?", response, sizeof(response));
				HAL_Delay(10);
    }else
		{
				ML307A_MQTT_Init();
		}
		
}
void ML307A_GNSS(void)
{
	sendCmd_4G("AT+CPIN?\r\n", "+CPIN: READY", 1, 5);
}

