/*
 * @Author       : ChenJie
 * @Date         : 2022-02-10 11:43:56
 * @Version      : V3.0
 * @LastEditors  : ChenJie
 * @LastEditTime : 2022-05-17 17:49:46
 * @Description  : file content
 * @FilePath     : \S32K146_4G\src\AppTaskUart1.c
 */
/*
 * AppTaskUart2.c
 *  4G的串口函数
 *  Created on: 2022年2月10日
 *      Author: QiXiang_CHENJIE
 */
#include "AppTaskUart1.h"
#include "hal_fls.h"

const ATCmdFunc Atcmdfunc[] = {
	{AT_CMD_TEST, "AT\r\n", at_callbackFunc},
	{AT_ATE0, "ATE0\r\n", at_callbackFunc},
	{AT_SIMREADY, "AT+CPIN?\r\n", at_callbackFunc},
	{AT_GETICCID, "AT+CICCID\r\n", at_callbackFunc},
	{AT_CGREG, "AT+CGREG?\r\n", at_callbackFunc},
	{AT_CSQ, "AT+CSQ\r\n", at_callbackFunc},
	{AT_NETOPEN, "AT+NETOPEN\r\n", at_callbackFunc},
	{AT_CGIP, "AT+CDNSGIP=", at_callbackFunc},
	//{AT_CONNECT, "AT+CIPOPEN=0,\"TCP\",\"120.26.68.165\",14319\r\n", at_callbackFunc},
	{AT_CONNECT, "AT+CIPOPEN=", at_callbackFunc},
	{AT_CONNECTCHK, "AT+CIPOPEN?\r\n", at_callbackFunc},
	{AT_SEND, "AT+CIPSEND=", at_callbackFunc},
	{AT_DISCON, "AT+CIPCLOSE=0\r\n", at_callbackFunc},
	{AT_NETCLOSE, "AT+NETCLOSE\r\n", at_callbackFunc}};

static process_Tcp gProcess_Tcp_Task = PROCESS_TCP_IDLE;
#define PROC_TCP_STATE_SWITCH(a) (gProcess_Tcp_Task = a)
void InitFunc(void);
sint8 TcpConnectFunc(sint8 *ConnectId);
sint8 TcpDataSendFunc(sint8 ConnectId);
sint8 TcpRegisterChkFunc(void);
void TcpDataEncode(uint32 *PtrSendAddr, uint16 *SendLen);
void GetUtc8Time(UTC8TimeType *UTC8TimeTcp);
static void AtcmdTransmit(sint8 CmdIdx, uint8 *SetValuePtr, uint16 SetValueLen, sint8 *retFunc);
static void TcpDataInfoRecvHandle(uint8 *DataRecv, uint16 DataRecvLen);
static void GetCSQValue(uint8 *out);
void Uart_4G_Task(void *pvParameters)
{
	(void)pvParameters;
	// 4G开机
	Dio_WriteChannel(DioConf_DioChannel_PTA6_GPIO_OUT_MCU_4G_POW_EN, STD_ON);
	Dio_WriteChannel(DioConf_DioChannel_PTA7_GPIO_OUT_MCU_4G_PWRKEY, STD_ON);
	Dio_LevelType _4G_Status = 0; // 0-关机，1-开机
	_4G_Status = Dio_ReadChannel(DioConf_DioChannel_PTB1_GPIO_IN_MCU_4G_STATUS);
	// LED测试
	Dio_WriteChannel(DioConf_DioChannel_PTE0_GPIO_OUT_MCU_LED1, STD_OFF);
	vTaskDelay(pdMS_TO_TICKS(1000));
	uint16 pReadLen = 0;
	InitFunc(); // 4G模块初始化,注：AT同步不通过，没有进行次数判定及跳转
	uint32 SendTimerCounter = 0;
	uint32 RecvTimerDelay = 0;
	uint8 *UartRecvPtr=NULL;
	for (;;)
	{
		switch (gProcess_Tcp_Task)
		{
		case PROCESS_TCP_IDLE: //空闲状态
		{
			UART_Receive_Data(UART_LPUART1, &UartRecvPtr, &pReadLen, 10);//100ms检测
			if (SocketId < 0)
			{
				PROC_TCP_STATE_SWITCH(PROCESS_TCP_REGCHK);
			}
			else if (pReadLen>0)
			{
				PROC_TCP_STATE_SWITCH(PROCESS_TCP_RECV);
				RecvTimerDelay = TimerCounter;
			}
			else if (AppConfigInfo.eolFlg == 1 && (TimerCounter - SendTimerCounter) >= 1000 && TcpWorkState==0)
			{
				SendTimerCounter = TimerCounter;
				PROC_TCP_STATE_SWITCH(PROCESS_TCP_SEND);
			}
			if((TimerCounter-RecvTimerDelay)>=10000 && TcpWorkState==1)//10s内没有命令下发，进行正常发送任务
			{
				TcpWorkState = 0;
			}
			break;
		}
		case PROCESS_TCP_ATSYS:
		{
			sint8 ATRet = -1;
			AtcmdTransmit(AT_CMD_TEST, NULL, 0, &ATRet);
			if (ATRet == 0)
			{
				PROC_TCP_STATE_SWITCH(PROCESS_TCP_IDLE);
			}
			else
			{
				PROC_TCP_STATE_SWITCH(PROCESS_TCP_ERROR);
			}
			break;
		}
		case PROCESS_TCP_REGCHK: //驻网检查，包括SIM，CPIN检查,ICCID获取
		{
			RegChkRet = TcpRegisterChkFunc();
			if (RegChkRet > 0) //检查通过，SIM卡已就绪，已进行驻网
			{
				PROC_TCP_STATE_SWITCH(PROCESS_TCP_CONNECT);
			}
			else
			{
				PROC_TCP_STATE_SWITCH(PROCESS_TCP_ERROR);
			}
			break;
		}
		case PROCESS_TCP_CONNECT: //网络连接，包括域名转换
		{
			if (SocketId < 0)
			{
				sint8 ConnectRet = 0;
				ConnectRet = TcpConnectFunc(&SocketId);
				if (ConnectRet > 0)
				{
					PROC_TCP_STATE_SWITCH(PROCESS_TCP_IDLE);
				}
				else
				{
					PROC_TCP_STATE_SWITCH(PROCESS_TCP_ERROR);
				}
			}
			break;
		}
		case PROCESS_TCP_SEND: //网络数据发送
		{
//			Dio_WriteChannel(DioConf_DioChannel_PTE0_GPIO_OUT_MCU_LED1,STD_ON);
			sint8 SendRet = -1;
			SendRet = TcpDataSendFunc(SocketId);
			if (SendRet == 0)
			{
				PROC_TCP_STATE_SWITCH(PROCESS_TCP_IDLE);
			}
			else
			{
				SocketId = -1;
				PROC_TCP_STATE_SWITCH(PROCESS_TCP_ERROR);
			}
			break;
		}
		case PROCESS_TCP_RECV: //网络数据接收,100ms空闲状态下即可接收
		{
			Dio_FlipChannel(DioConf_DioChannel_PTE0_GPIO_OUT_MCU_LED1);

			if (pReadLen > 0 && SocketId >= 0)
			{
				TcpDataInfoRecvHandle(UartRecvPtr, pReadLen);

				if(UartRecvPtr != NULL)
				{
					free(UartRecvPtr);
				}
				UartRecvPtr = NULL;
			}
			PROC_TCP_STATE_SWITCH(PROCESS_TCP_IDLE);
			break;
		}
		case PROCESS_TCP_HEART: //心跳包发送
		{
			break;
		}
		case PROCESS_TCP_SLEEP: //网络休眠状态
		{
			break;
		}
		case PROCESS_TCP_ERROR: //错误状态
		{
			//			Dio_WriteChannel(DioConf_DioChannel_PTA7_GPIO_OUT_MCU_4G_PWRKEY, STD_OFF);
			//			vTaskDelay(pdMS_TO_TICKS(100));
			PROC_TCP_STATE_SWITCH(PROCESS_TCP_IDLE);
			//			Dio_WriteChannel(DioConf_DioChannel_PTA7_GPIO_OUT_MCU_4G_PWRKEY, STD_ON);
			break;
		}
		}
	}
}
sint8 TcpDataSendFunc(sint8 ConnectId)
{
	sint8 outValue = -1;
	uint32 pSendDataAddr = 0;
	uint16 DataSendLen = 0;
	memcpy(TcpbattSN, AppConfigInfo.deviceSn, 17);
	TcpDataEncode(&pSendDataAddr, &DataSendLen); //数据组包，malloc申请在里面,pSendData指向申请的地址
	if (DataSendLen == 0)
	{
		return 0; //暂时无数据可以发
	}
	outValue = tcpipConnectionSend(ConnectId, (uint8 *)pSendDataAddr, DataSendLen); //发送函数
	if (pSendDataAddr != 0)
	{
		free((uint8 *)(pSendDataAddr));
	}
	pSendDataAddr = 0;
	return outValue;
}
sint8 TcpConnectFunc(sint8 *ConnectId)
{
	uint8 ConnectStep = 0;
	sint8 ChkState = 0;
	sint8 ATRet = -1;
	while (1)
	{
		switch (ConnectStep)
		{
		case 0: // AT指令同步
		{
			char *ATCmdSend = (char *)("ATE0\r\n");
			uint8 ATCmdSendLen = mstrlen(ATCmdSend);
			uint8 ReadLen = 0;
			uint8 *UartRecvPtr = NULL;
			UART_Query_Data(UART_LPUART1, UART_LPUART1, ATCmdSend, ATCmdSendLen,&UartRecvPtr, &ReadLen, pdMS_TO_TICKS(1000));
			uint8 *retptr = NULL;
			if (ReadLen > 0)
			{
				retptr = (uint8 *)strstr((char *)UartRecvPtr, (char *)("OK"));

				if(UartRecvPtr != NULL)
				{
					free(UartRecvPtr);
				}
				UartRecvPtr = NULL;

				if (retptr)
				{
					ConnectStep++;
				}
				else
				{
					ChkState = -ConnectStep;
					return ChkState;
				}
			}
			else
			{
				ChkState = -ConnectStep;
				return ChkState;
			}
			break;
		}
		case 1: // Netopen
		{
			AtcmdTransmit(AT_NETOPEN, NULL, 0, &ATRet);
			if (ATRet == 0)
			{
				ConnectStep++;
			}
			else
			{
				ChkState = -ConnectStep;
				return ChkState;
			}
			break;
		}
		case 2: //连接检查
		{
			AtcmdTransmit(AT_CONNECTCHK, NULL, 0, &ATRet); // ATret返回的值是连接id，如果未连接返回-1
			if (ATRet >= 0)
			{
				*ConnectId = ATRet;
				return 1;
			}
			else
			{
				ConnectStep++;
			}
			break;
		}
		case 3: //域名转换
		{
			char AtCmdSend[30] = {0};
			uint8 AtCmdSendLen = 0;
			AtCmdSendLen = mstrlen(WebSiteName);
			memcpy(AtCmdSend, WebSiteName, AtCmdSendLen);
			memcpy(AtCmdSend + AtCmdSendLen, (char *)CRLF, sizeof(CRLF));
			AtCmdSendLen = AtCmdSendLen + 2;
			AtcmdTransmit(AT_CGIP, AtCmdSend, AtCmdSendLen, &ATRet);
			if (ATRet == 0)
			{
				ConnectStep++;
			}
			else
			{
				ChkState = -ConnectStep;
				return ChkState;
			}
			break;
		}
		case 4: //创建连接
		{
			char AtCmdSend[40] = {0};
			uint8 AtCmdSendTotalLen = 0;
			*ConnectId = 0;
			sprintf(AtCmdSend, "%d,\"TCP\",%s,%d\r\n", *ConnectId, WebSiteIp, WebSitePort); //此处需要优化
			AtCmdSendTotalLen = mstrlen(AtCmdSend);
			AtcmdTransmit(AT_CONNECT, AtCmdSend, AtCmdSendTotalLen, &ATRet);
			if (ATRet == 0)
			{
				ConnectStep++;
			}
			else
			{
				ChkState = -ConnectStep;
				*ConnectId = -1;
				return ChkState;
			}
			break;
		}
		default:
			ChkState = ConnectStep;
			return ChkState;
		}
	}
}
sint8 TcpRegisterChkFunc(void)
{
	uint8 RegChkStep = 0;
	sint8 ChkState = 0; //默认为0
	sint8 ATRet = -1;
	while (1)
	{
		switch (RegChkStep)
		{
		case 0: // AT指令同步
		{
			AtcmdTransmit(AT_CMD_TEST, NULL, 0, &ATRet);
			if (ATRet == 0)
			{
				RegChkStep++;
			}
			else
			{
				ChkState = -RegChkStep;
				return ChkState;
			}
			break;
		}
		case 1: // CPIN检查
		{
			AtcmdTransmit(AT_SIMREADY, NULL, 0, &ATRet);
			if (ATRet == 0)
			{
				RegChkStep++;
			}
			else
			{
				ChkState = -RegChkStep;
				return ChkState;
			}
			break;
		}
		case 2:
		{
			AtcmdTransmit(AT_CGREG, NULL, 0, &ATRet); //驻网检查，返回值1和5是驻网成功
			if (ATRet == 1 || ATRet == 5)
			{
				RegChkStep++;
			}
			else
			{
				ChkState = -RegChkStep;
				return ChkState;
			}
			break;
		}
		default:
			ChkState = RegChkStep;
			return ChkState;
			break;
		}
	}
}
void InitFunc(void)
{
	// 4G模块初始化
	uint8 _4G_InitStep = 0;
	sint8 ATRet = -1;
	uint8 ReadLen = 0;
	char *ATCmdSend = NULL;
	uint8 ATCmdSendLen = 0;
	uint8 *UartRecvPtr = NULL;
	while (1)
	{
		switch (_4G_InitStep)
		{
		case 0: // AT指令同步
		{
			AtcmdTransmit(AT_CMD_TEST, NULL, 0, &ATRet);
			if (ATRet == 0)
			{
				_4G_InitStep++;
			}
			else
			{
				vTaskDelay(pdMS_TO_TICKS(100));
			}
			break;
		}
		case 1: //关闭回显
		{
			ATCmdSend = (char *)("ATE0\r\n");
			ATCmdSendLen = mstrlen(ATCmdSend);
			UART_Query_Data(UART_LPUART1, UART_LPUART1, ATCmdSend, ATCmdSendLen, &UartRecvPtr, &ReadLen, pdMS_TO_TICKS(1000));
			uint8 *retptr = NULL;
			if (ReadLen > 0)
			{
				retptr = (uint8 *)strstr((char *)UartRecvPtr, (char *)("OK"));
				if (retptr)
				{
					_4G_InitStep++;
				}
				else
				{
					_4G_InitStep=0;
				}
			}
			else
			{
				_4G_InitStep=0;
			}
			if(UartRecvPtr != NULL)
			{
				free(UartRecvPtr);
			}
			UartRecvPtr = NULL;
			break;
		}
		case 2: // IMEI获取
		{
			ATCmdSend = (char *)("AT+SIMEI?\r\n");
			ATCmdSendLen = mstrlen(ATCmdSend);
			UART_Query_Data(UART_LPUART1, UART_LPUART1, ATCmdSend, ATCmdSendLen, &UartRecvPtr, &ReadLen, pdMS_TO_TICKS(100));

			uint8 *retptr = NULL;
			if (ReadLen > 0)
			{
				retptr = (uint8 *)strstr((char *)UartRecvPtr, (char *)("+SIMEI"));
				if (retptr)
				{
					memcpy(ImeiNum, retptr + 8, 15);
					_4G_InitStep++;
				}
				else
				{
					_4G_InitStep=0;
				}
			}
			else
			{
				_4G_InitStep = 0;
			}
			if(UartRecvPtr != NULL)
			{
				free(UartRecvPtr);
			}
			UartRecvPtr = NULL;
			break;
		}
		case 3: // 打开时间自动更新
		{
			ATCmdSend = (char *)("AT+CTZU=1\r\n");
			ATCmdSendLen = mstrlen(ATCmdSend);
			UART_Query_Data(UART_LPUART1, UART_LPUART1, ATCmdSend, ATCmdSendLen, &UartRecvPtr, &ReadLen, pdMS_TO_TICKS(100));
			uint8 *retptr = NULL;
			if (ReadLen > 0)
			{
				retptr = (uint8 *)strstr((char *)UartRecvPtr, (char *)("OK"));
				if (retptr)
				{
					_4G_InitStep++;
				}
			}
			else
			{
				_4G_InitStep = 0;
			}
			if(UartRecvPtr != NULL)
			{
				free(UartRecvPtr);
			}
			UartRecvPtr = NULL;
			break;
		}
		case 4: // ICCID获取
		{
			AtcmdTransmit(AT_GETICCID, NULL, 0, &ATRet);
			if (ATRet == 0)
			{
				_4G_InitStep++;
			}
			else
			{
				_4G_InitStep=0;
			}
			break;
		}
		case 5:
		{
			ATCmdSend = (char *)("AT+CIPSENDMODE=0\r\n");
			ATCmdSendLen = mstrlen(ATCmdSend);
			UART_Query_Data(UART_LPUART1, UART_LPUART1, ATCmdSend, ATCmdSendLen, &UartRecvPtr, &ReadLen, pdMS_TO_TICKS(100));
			uint8 *retptr = NULL;
			if (ReadLen > 0)
			{
				retptr = (uint8 *)strstr((char *)UartRecvPtr, (char *)("OK"));
				if (retptr)
				{
					_4G_InitStep++;
				}
			}
			else
			{
				_4G_InitStep = 0;
			}
			if(UartRecvPtr != NULL)
			{
				free(UartRecvPtr);
			}
			UartRecvPtr = NULL;
		}
		default:
		{
			return;
			break;
		}
		}
	}
}
static void AtcmdTransmit(sint8 CmdIdx, uint8 *SetValuePtr, uint16 SetValueLen, sint8 *retFunc)
{
	uint16 ReadLen = 0;
	uint8 *PtrATCmdSend = NULL;
	uint8 ATCmdFixedLen = 0;
	uint16 ATCmdTotalLen = 0;
	uint8 *UartRecvPtr=NULL;
	ATCmdFixedLen = mstrlen(Atcmdfunc[CmdIdx].str);
	ATCmdTotalLen = ATCmdFixedLen + SetValueLen;
	PtrATCmdSend = malloc(ATCmdTotalLen + 1);
	memset(PtrATCmdSend, 0x00, ATCmdTotalLen + 1);
	memcpy(PtrATCmdSend, Atcmdfunc[CmdIdx].str, ATCmdFixedLen);
	if (SetValuePtr != NULL)
	{
		memcpy(PtrATCmdSend + ATCmdFixedLen, SetValuePtr, SetValueLen);
	}

	UART_Query_Data(UART_LPUART1, UART_LPUART1, PtrATCmdSend, ATCmdTotalLen, &UartRecvPtr, &ReadLen, pdMS_TO_TICKS(1000));
	if(ReadLen>0)
	{
		*retFunc = Atcmdfunc[CmdIdx].cb(PtrATCmdSend, UartRecvPtr, CmdIdx, ReadLen);
	}
	else
	{
		*retFunc = -1;
	}
	if (PtrATCmdSend != NULL)
	{
		memset(PtrATCmdSend, 0x00, ATCmdTotalLen + 1);
		free(PtrATCmdSend);
	}
	PtrATCmdSend = NULL;

	if(UartRecvPtr != NULL)
	{
		free(UartRecvPtr);
	}
	UartRecvPtr = NULL;

	return;
}
sint8 at_callbackFunc(char *PSendStr, char *pReadStr, uint8 CmdIdx, uint16 pReadLen)
{
	sint8 OutValue = -1;
	uint8 *retptr = NULL;
	char *OkAns = "OK";
	retptr = (uint8 *)strstr((char *)pReadStr, OkAns);
	switch (CmdIdx)
	{
	case AT_CMD_TEST:
	{
		if (retptr)
		{
			OutValue = 0;
		}
		break;
	}
	case AT_SIMREADY:
	{
		if (retptr)
		{
			retptr = (uint8 *)strstr((char *)pReadStr, (char *)("READY"));
			if (retptr)
			{
				OutValue = 0;
			}
		}
		break;
	}
	case AT_GETICCID:
	{
		if (retptr)
		{
			retptr = (uint8 *)strstr((char *)pReadStr, (char *)("ICCID:"));
			if (retptr)
			{
				memcpy(IccidNum, retptr + 7, 20);
				OutValue = 0;
			}
		}
		break;
	}
	case AT_CGREG:
	{
		if (retptr)
		{
			retptr = (uint8 *)strstr((char *)pReadStr, (char *)("CGREG:"));
			if (retptr)
			{
				uint8 RegN = 0;
				uint8 RegState = 0;
				RegN = CharToHex(*(retptr + 7));
				RegState = CharToHex(*(retptr + 9));
				OutValue = (RegState + RegN);
				return OutValue;
			}
		}

		break;
	}
	case AT_NETOPEN:
	{
		if (retptr)
		{
			OutValue = 0;
		}
		retptr = (uint8 *)strstr((char *)pReadStr, (char *)("opened")); //重复打开
		if (retptr)
		{
			OutValue = 0;
		}
		break;
	}
	case AT_CONNECTCHK:
	{
		if (retptr)
		{
			retptr = (uint8 *)strstr((char *)pReadStr, (char *)("TCP"));
			if (retptr)
			{
				OutValue = CharToHex(*(retptr - 3));
				return OutValue;
			}
		}
		break;
	}
	case AT_CGIP:
	{
		if (retptr)
		{
			for (uint8 i = 0; i < 30; i++)
			{
				if (*(retptr - i) == ',')
				{
					memcpy(WebSiteIp, retptr - i + 1, i-5);
					OutValue = 0;
					break;
				}
			}
		}
		break;
	}
	case AT_CONNECT:
	{
		if (retptr)
		{
			retptr = (uint8 *)strstr((char *)pReadStr, (char *)("CIPOPEN:"));
			if (retptr)
			{
				SocketId = CharToHex(*(retptr + 9));
			}
			OutValue = 0;
		}
		break;
	}
	case AT_SEND:
	{
		retptr = (uint8 *)strstr((char *)pReadStr, (char *)(">"));
		if (retptr)
		{
			OutValue = 0;
		}
		else
		{
			OutValue = -1;
		}
		break;
	}
	default:
		break;
	}
	return OutValue;
}
void TcpDataEncode(uint32 *PtrSendAddr, uint16 *SendLen)
{
	uint8 DataIdx = 0;
	static uint32 TcpSendTimeCounter = 0;
	TcpSendTimeCounter++;

	if (TcpSendTimeCounter%60 == 1)
	{
		DataIdx = VerMsg; //版本信息发送
	}
	else if (TcpSendTimeCounter % 30 == 0)
	{
		DataIdx = TruckBattMsg; //电池信息发送
	}
	else if ((TcpSendTimeCounter - 1) % 60 == 0)
	{
		DataIdx = TruckVehiMsg; //车辆信息发送
	}
	else if ((TcpSendTimeCounter - 2) % 60 == 0)
	{
		DataIdx = TruckAcclMsg; //累计信息发送
	}
	else if (TcpSendTimeCounter % 60 == 0)
	{
		DataIdx = GpsMsg; //定位信息发送
	}
	else
	{
		*SendLen = 0;
		DataIdx = 0; //不发送,返回
		return;
	}
	UTC8TimeType UTC8TimeTcp;
	GetUtc8Time(&UTC8TimeTcp); //时间获取
	uint8 *SendBuffer = NULL;
	switch (DataIdx)
	{
	case 0x82:
	{
		GPSInfo GpsRecvData;
		GPSMsgtoTcpType GpsToTcpInfo;
		*SendLen = sizeof(GpsToTcpInfo);
		SendBuffer = malloc(*SendLen);
		uint16 tac = 0;
		uint32 cellId = 0;
		uint8 DataLen = (uint16)sizeof(GpsToTcpInfo.gpsInfo);
		GpsToTcpInfo.startSymbol[0] = TCP_START_SYM1;
		GpsToTcpInfo.startSymbol[1] = TCP_START_SYM2;
		GpsToTcpInfo.cmdSymbol = TCP_CMD_SYM;
		GpsToTcpInfo.ansSymbol = TCP_ANS_SYM;
		memcpy(GpsToTcpInfo.SN, TcpbattSN, BATT_SN_LEN);
		GpsToTcpInfo.encryptMethod = TCP_ENCPT_DISABLE; // not encrypt
		GpsToTcpInfo.dataLength[0] = (DataLen >> 8) & 0xFF;
		GpsToTcpInfo.dataLength[1] = DataLen & 0xFF;
		GpsToTcpInfo.gpsInfo.sendTimeUTC[0] = (UTC8TimeTcp.year) & 0xFF; // year
		GpsToTcpInfo.gpsInfo.sendTimeUTC[1] = UTC8TimeTcp.month & 0xFF;	 // month
		GpsToTcpInfo.gpsInfo.sendTimeUTC[2] = UTC8TimeTcp.day & 0xFF;	 // day
		GpsToTcpInfo.gpsInfo.sendTimeUTC[3] = UTC8TimeTcp.hour & 0xFF;	 // hour
		GpsToTcpInfo.gpsInfo.sendTimeUTC[4] = UTC8TimeTcp.minute & 0xFF; // mins
		GpsToTcpInfo.gpsInfo.sendTimeUTC[5] = UTC8TimeTcp.second & 0xFF; // sec
		GpsToTcpInfo.gpsInfo.msgMark = DataIdx;
		GpsToTcpInfo.gpsInfo.msgCollectionTimeUTC[0] = (UTC8TimeTcp.year) & 0xFF; // year
		GpsToTcpInfo.gpsInfo.msgCollectionTimeUTC[1] = UTC8TimeTcp.month & 0xFF;  // month
		GpsToTcpInfo.gpsInfo.msgCollectionTimeUTC[2] = UTC8TimeTcp.day & 0xFF;	  // day
		GpsToTcpInfo.gpsInfo.msgCollectionTimeUTC[3] = UTC8TimeTcp.hour & 0xFF;	  // hour
		GpsToTcpInfo.gpsInfo.msgCollectionTimeUTC[4] = UTC8TimeTcp.minute & 0xFF; // mins
		GpsToTcpInfo.gpsInfo.msgCollectionTimeUTC[5] = UTC8TimeTcp.second & 0xFF;
		if (xQueueReceive(GpsDataQueueHandle, &GpsRecvData, 0) == pdPASS)
		{
			memcpy((uint8 *)&GpsToTcpInfo.gpsInfo.GpsInfoData, (uint8 *)&GpsRecvData, sizeof(GPSInfo));
		}
		else
		{
			memset((uint8 *)&GpsToTcpInfo.gpsInfo.GpsInfoData, 0x00, sizeof(GPSInfo));
		}
		GpsToTcpInfo.gpsInfo.Tac[0] = tac >> 8;
		GpsToTcpInfo.gpsInfo.Tac[1] = tac & 0xFF;
		GpsToTcpInfo.gpsInfo.CellID[0] = cellId >> 24;
		GpsToTcpInfo.gpsInfo.CellID[0] = cellId >> 16;
		GpsToTcpInfo.gpsInfo.CellID[0] = cellId >> 8;
		GpsToTcpInfo.gpsInfo.CellID[0] = cellId;
		uint16 xyzDatacahce[3] = {0};
		memcpy(xyzDatacahce, xyzData, 3);
		for (uint8 i = 0; i < 3; i++)
		{
			if (xyzDatacahce[i] > 0x8000) // 数据为负
			{
				xyzDatacahce[i] = (uint16)((uint16)(~(xyzDatacahce[i])) + 1);
				xyzDatacahce[i] = 20000U - xyzDatacahce[i];
			}
			else
			{
				xyzDatacahce[i] = xyzDatacahce[i] + 20000U;
			}
		}
		GpsToTcpInfo.gpsInfo.xData[0] = xyzDatacahce[0] >> 8;
		GpsToTcpInfo.gpsInfo.xData[1] = xyzDatacahce[0];
		GpsToTcpInfo.gpsInfo.yData[0] = xyzDatacahce[1] >> 8;
		GpsToTcpInfo.gpsInfo.yData[1] = xyzDatacahce[1];
		GpsToTcpInfo.gpsInfo.zData[0] = xyzDatacahce[2] >> 8;
		GpsToTcpInfo.gpsInfo.zData[1] = xyzDatacahce[2];
		GpsToTcpInfo.CRC = bcc_chk((uint8 *)&GpsToTcpInfo, sizeof(GPSMsgtoTcpType) - 1);
		memcpy(SendBuffer, &GpsToTcpInfo, sizeof(GpsToTcpInfo));
		*PtrSendAddr = (uint32)SendBuffer;
		break;
	}
	case 0x86:
	{
		VersionMsgtoTcpType VerMsgToTcpInfo;
		*SendLen = sizeof(VersionMsgtoTcpType);
		SendBuffer = malloc(*SendLen);
		uint16 DataLen = 0;
		DataLen = (uint16)sizeof(VerMsgToTcpInfo.VerInfo);
		VerMsgToTcpInfo.startSymbol[0] = TCP_START_SYM1;
		VerMsgToTcpInfo.startSymbol[1] = TCP_START_SYM2;
		VerMsgToTcpInfo.cmdSymbol = TCP_CMD_SYM;
		VerMsgToTcpInfo.ansSymbol = TCP_ANS_SYM;
		memcpy(VerMsgToTcpInfo.SN, TcpbattSN, BATT_SN_LEN);
		VerMsgToTcpInfo.encryptMethod = TCP_ENCPT_DISABLE; // not encrypt
		VerMsgToTcpInfo.dataLength[0] = (DataLen >> 8) & 0xFF;
		VerMsgToTcpInfo.dataLength[1] = DataLen & 0xFF;
		VerMsgToTcpInfo.VerInfo.sendTimeUTC[0] = (UTC8TimeTcp.year) & 0xFF; // year
		VerMsgToTcpInfo.VerInfo.sendTimeUTC[1] = UTC8TimeTcp.month & 0xFF;	// month
		VerMsgToTcpInfo.VerInfo.sendTimeUTC[2] = UTC8TimeTcp.day & 0xFF;	// day
		VerMsgToTcpInfo.VerInfo.sendTimeUTC[3] = UTC8TimeTcp.hour & 0xFF;	// hour
		VerMsgToTcpInfo.VerInfo.sendTimeUTC[4] = UTC8TimeTcp.minute & 0xFF; // mins
		VerMsgToTcpInfo.VerInfo.sendTimeUTC[5] = UTC8TimeTcp.second & 0xFF; // sec
		VerMsgToTcpInfo.VerInfo.msgMark = DataIdx;
		VerMsgToTcpInfo.VerInfo.msgCollectionTimeUTC[0] = (UTC8TimeTcp.year) & 0xFF; // year
		VerMsgToTcpInfo.VerInfo.msgCollectionTimeUTC[1] = UTC8TimeTcp.month & 0xFF;	 // month
		VerMsgToTcpInfo.VerInfo.msgCollectionTimeUTC[2] = UTC8TimeTcp.day & 0xFF;	 // day
		VerMsgToTcpInfo.VerInfo.msgCollectionTimeUTC[3] = UTC8TimeTcp.hour & 0xFF;	 // hour
		VerMsgToTcpInfo.VerInfo.msgCollectionTimeUTC[4] = UTC8TimeTcp.minute & 0xFF; // mins
		VerMsgToTcpInfo.VerInfo.msgCollectionTimeUTC[5] = UTC8TimeTcp.second & 0xFF;
		memcpy(VerMsgToTcpInfo.VerInfo.ICCID, IccidNum, 20);
		memcpy(VerMsgToTcpInfo.VerInfo.IMEI, ImeiNum, 15);
		VerMsgToTcpInfo.VerInfo.BMSHwVersion[0] = BMS_HardwareVersion >> 8;
		VerMsgToTcpInfo.VerInfo.BMSHwVersion[1] = BMS_HardwareVersion;
		VerMsgToTcpInfo.VerInfo.BMSSwVersion[0] = BMS_SoftwareVersion >> 24;
		VerMsgToTcpInfo.VerInfo.BMSSwVersion[1] = BMS_SoftwareVersion >> 16;
		VerMsgToTcpInfo.VerInfo.BMSSwVersion[2] = BMS_SoftwareVersion >> 8;
		VerMsgToTcpInfo.VerInfo.BMSSwVersion[3] = BMS_SoftwareVersion;
		VerMsgToTcpInfo.VerInfo.HwVersion[0] = (HWVERSION >> 8) & 0xFF;
		VerMsgToTcpInfo.VerInfo.HwVersion[1] = (HWVERSION)&0xFF;
		VerMsgToTcpInfo.VerInfo.BLVersion[0] = (BLSWVERSION >> 24) & 0xFF;
		VerMsgToTcpInfo.VerInfo.BLVersion[1] = (BLSWVERSION >> 16) & 0xFF;
		VerMsgToTcpInfo.VerInfo.BLVersion[2] = (BLSWVERSION >> 8) & 0xFF;
		VerMsgToTcpInfo.VerInfo.BLVersion[3] = (BLSWVERSION)&0xFF;
		VerMsgToTcpInfo.VerInfo.DRVVersion[0] = (DRVSWVERSION >> 24) & 0xFF;
		VerMsgToTcpInfo.VerInfo.DRVVersion[1] = (DRVSWVERSION >> 16) & 0xFF;
		VerMsgToTcpInfo.VerInfo.DRVVersion[2] = (DRVSWVERSION >> 8) & 0xFF;
		VerMsgToTcpInfo.VerInfo.DRVVersion[3] = (DRVSWVERSION)&0xFF;
		VerMsgToTcpInfo.VerInfo.APPVersion[0] = (APPSWVERSION >> 24) & 0xFF;
		VerMsgToTcpInfo.VerInfo.APPVersion[1] = (APPSWVERSION >> 16) & 0xFF;
		VerMsgToTcpInfo.VerInfo.APPVersion[2] = (APPSWVERSION >> 8) & 0xFF;
		VerMsgToTcpInfo.VerInfo.APPVersion[3] = (APPSWVERSION)&0xFF;
		VerMsgToTcpInfo.VerInfo.BmsType = BMS_MANUFACTURE;
		VerMsgToTcpInfo.VerInfo.BmsInfo = BMS_INFO;
		VerMsgToTcpInfo.VerInfo.DataModuleType = DATA_MODULE_TYPE;
		VerMsgToTcpInfo.CRC = bcc_chk((uint8 *)&VerMsgToTcpInfo, sizeof(VerMsgToTcpInfo) - 1);
		memcpy(SendBuffer, &VerMsgToTcpInfo, sizeof(VersionMsgtoTcpType));
		*PtrSendAddr = (uint32)SendBuffer;
		break;
	}
	case 0x90:
	{
		*SendLen = 0x52;
		SendBuffer = malloc(*SendLen);
		*(SendBuffer + 0) = TCP_START_SYM1;
		*(SendBuffer + 1) = TCP_START_SYM2;
		*(SendBuffer + 2) = TCP_CMD_SYM;
		*(SendBuffer + 3) = TCP_ANS_SYM;
		memcpy(SendBuffer + 4, TcpbattSN, BATT_SN_LEN);
		*(SendBuffer + 0x15) = (TCP_ENCPT_DISABLE & 0xFF); // uint8	TCP_ENCPT_DISABLE
		uint16 DataLen = 0x39;							   // 57
		*(SendBuffer + 0x16) = ((DataLen >> 8) & 0xFF);	   // uint16	DataLen
		*(SendBuffer + 0x17) = (DataLen & 0xFF);
		*(SendBuffer + 0x18) = ((UTC8TimeTcp.year) & 0xFF); // uint8	year
		*(SendBuffer + 0x19) = (UTC8TimeTcp.month & 0xFF);	// uint8	month
		*(SendBuffer + 0x1A) = (UTC8TimeTcp.day & 0xFF);	// uint8	day
		*(SendBuffer + 0x1B) = (UTC8TimeTcp.hour & 0xFF);	// uint8	hour
		*(SendBuffer + 0x1C) = (UTC8TimeTcp.minute & 0xFF); // uint8	minute
		*(SendBuffer + 0x1D) = (UTC8TimeTcp.second & 0xFF); // uint8	second
		*(SendBuffer + 0x1E) = (DataIdx & 0xFF);			// uint8	BATTMSG
		*(SendBuffer + 0x1F) = ((UTC8TimeTcp.year) & 0xFF); // uint8	year
		*(SendBuffer + 0x20) = (UTC8TimeTcp.month & 0xFF);	// uint8	month
		*(SendBuffer + 0x21) = (UTC8TimeTcp.day & 0xFF);	// uint8	day
		*(SendBuffer + 0x22) = (UTC8TimeTcp.hour & 0xFF);	// uint8	hour
		*(SendBuffer + 0x23) = (UTC8TimeTcp.minute & 0xFF); // uint8	minute
		*(SendBuffer + 0x24) = (UTC8TimeTcp.second & 0xFF); // uint8	second
		memcpy(SendBuffer + 0x25, VIN, 17);
		*(SendBuffer + 0x36) = (vehicleStatus & 0xFF);		 // uint8	整车状态
		*(SendBuffer + 0x37) = (bmsHVOn & 0xFF);			 // uint8	bms上高压指令
		*(SendBuffer + 0x38) = (currentGearPosition & 0xFF); // uint8	当前档位
		*(SendBuffer + 0x39) = (parkingBreakStatus & 0xFF);	 // uint8	手刹信号
		*(SendBuffer + 0x3A) = (breakingStatus & 0xFF);		 // uint8	制动开关
		*(SendBuffer + 0x3B) = ((ODO >> 24) & 0xFF);		 // uint32	总里程
		*(SendBuffer + 0x3C) = ((ODO >> 16) & 0xFF);
		*(SendBuffer + 0x3D) = ((ODO >> 8) & 0xFF);
		*(SendBuffer + 0x3E) = (ODO & 0xFF);
		*(SendBuffer + 0x3F) = (dcdcWorkStatus & 0xFF);			   // uint8 DCDC状态
		*(SendBuffer + 0x40) = (numOfChrgableSubsys & 0xFF);	   // uint8	可充电子系统数
		*(SendBuffer + 0x41) = (chrgableSubsysCode & 0xFF);		   // uint8	可充电储能子系统号
		*(SendBuffer + 0x42) = (BMS_MaxCellTempCSC & 0xFF);		   // uint8	最高温度子系统号 精度_1，偏移量_0，单位_
		*(SendBuffer + 0x43) = (BMS_MaxCellTempNum & 0xFF);		   // uint8	最高温度探针单体代号 精度_1，偏移量_0，单位_
		*(SendBuffer + 0x44) = (BMS_MinCellTempCSC & 0xFF);		   // uint8	最低温度子系统号 精度_1，偏移量_0，单位_
		*(SendBuffer + 0x45) = (BMS_MinCellTempNum & 0xFF);		   // uint8	最低温度探针子系统代号 精度_1，偏移量_0，单位_
		*(SendBuffer + 0x46) = (BMS_MaxCellVoltCSC & 0xFF);		   // uint8	最高电压电池子系统号 精度_1，偏移量_0，单位_
		*(SendBuffer + 0x47) = ((BMS_MaxCellVoltNum >> 8) & 0xFF); // uint16	最高电压电池单体代号 精度_1，偏移量_0，单位_
		*(SendBuffer + 0x48) = (BMS_MaxCellVoltNum & 0xFF);
		*(SendBuffer + 0x49) = (BMS_MinCellVoltCSC & 0xFF);		   // uint8	最低电压电池子系统号 精度_1，偏移量_0，单位_
		*(SendBuffer + 0x4A) = ((BMS_MinCellVoltNum >> 8) & 0xFF); // uint16	最低电压电池单体代号 精度_1，偏移量_0，单位_
		*(SendBuffer + 0x4B) = (BMS_MinCellVoltNum & 0xFF);
		*(SendBuffer + 0x4C) = (ebcStatus & 0xFF); // uint8 换电控制器状态
		*(SendBuffer + 0x4D) = (uint8)((ebcAskHVOn & 0x01) | ((ebcAskHVOff & 0x01) << 1) | ((retainLockSignal & 0x01) << 3) | ((dischargeLockSignal & 0x01) << 5) | ((chargeLockSignal & 0x01) << 6));
		*(SendBuffer + 0x4E) = (chargeFlag & 0xFF);		 // uint8 充电标志位
		*(SendBuffer + 0x4F) = ((vcuDCVol >> 8) & 0xFF); // uint16 电机直流母线电压
		*(SendBuffer + 0x50) = (vcuDCVol & 0xFF);
		*(SendBuffer + 0x51) = bcc_chk(SendBuffer, 0x51);
		*PtrSendAddr = (uint32)SendBuffer;
		break;
	}
	case 0x91:
	{
		GetCSQValue(&CSQValue);
		if (BMS_Mode == 1)
		{
			BMS_Mode = 2;
		}
		else
		{
			BMS_Mode = 1;
		}
		*SendLen = 0x54 + min(BMS_CellTotal,BMS_CELL_MAX_NUM)*2 + min(BMS_TempTotal,BMS_TEMP_MAX_NUM);
		SendBuffer = malloc(*SendLen);
		*(SendBuffer + 0) = TCP_START_SYM1;
		*(SendBuffer + 1) = TCP_START_SYM2;
		*(SendBuffer + 2) = TCP_CMD_SYM;
		*(SendBuffer + 3) = TCP_ANS_SYM;
		memcpy(SendBuffer + 4, TcpbattSN, BATT_SN_LEN);
		*(SendBuffer + 0x15) = (TCP_ENCPT_DISABLE & 0xFF); // uint8	TCP_ENCPT_DISABLE
		uint16 DataLen = 0x3B + min(BMS_CellTotal,BMS_CELL_MAX_NUM)*2 + min(BMS_TempTotal,BMS_TEMP_MAX_NUM);
		*(SendBuffer + 0x16) = ((DataLen >> 8) & 0xFF); // uint16	DataLen
		*(SendBuffer + 0x17) = (DataLen & 0xFF);
		*(SendBuffer + 0x18) = ((UTC8TimeTcp.year) & 0xFF);	   // uint8	year
		*(SendBuffer + 0x19) = (UTC8TimeTcp.month & 0xFF);	   // uint8	month
		*(SendBuffer + 0x1A) = (UTC8TimeTcp.day & 0xFF);	   // uint8	day
		*(SendBuffer + 0x1B) = (UTC8TimeTcp.hour & 0xFF);	   // uint8	hour
		*(SendBuffer + 0x1C) = (UTC8TimeTcp.minute & 0xFF);	   // uint8	minute
		*(SendBuffer + 0x1D) = (UTC8TimeTcp.second & 0xFF);	   // uint8	second
		*(SendBuffer + 0x1E) = (DataIdx & 0xFF);			   // uint8	BATTMSG
		*(SendBuffer + 0x1F) = ((UTC8TimeTcp.year) & 0xFF);	   // uint8	year
		*(SendBuffer + 0x20) = (UTC8TimeTcp.month & 0xFF);	   // uint8	month
		*(SendBuffer + 0x21) = (UTC8TimeTcp.day & 0xFF);	   // uint8	day
		*(SendBuffer + 0x22) = (UTC8TimeTcp.hour & 0xFF);	   // uint8	hour
		*(SendBuffer + 0x23) = (UTC8TimeTcp.minute & 0xFF);	   // uint8	minute
		*(SendBuffer + 0x24) = (UTC8TimeTcp.second & 0xFF);	   // uint8	second
		*(SendBuffer + 0x25) = (CSQValue & 0xFF);			   // uint8	csq
		*(SendBuffer + 0x26) = (BMS_Mode & 0xFF);			   // uint8	电池管理系统工作状态，0-初始化 1-自检完成允许上电 2-运行状态 3-高压切断 4-故障状态，精度_1，偏移量_0，单位_
		*(SendBuffer + 0x27) = (BMS_CharGunSt & 0xFF);		   // uint8	直流充电枪连接状态，0-未连接 1-单枪连接 2-双枪连接 3-无效，精度_1，偏移量_0，单位_
		*(SendBuffer + 0x28) = (BMS_FtLvl & 0xFF);			   // uint8	当前最高故障等级，0-正常 1-1级 轻微故障 2-2级 较严重故障 3-3级 最严重故障，精度_1，偏移量_0，单位_
		*(SendBuffer + 0x29) = (BMS_FtCode & 0xFF);			   // uint8	故障码，见BMS_ErrCode，精度_1，偏移量_0，单位_
		*(SendBuffer + 0x2A) = (BMS_ReqHVOff & 0xFF);		   // uint8	BMS下高压请求，0-无效 1-请求下高压 2-不请求下高压 3-无效，精度_1，偏移量_0，单位_
		*(SendBuffer + 0x2B) = (BMS_CharSt & 0xFF);			   // uint8	充电状态，0-未充电 1-充电中 2-充电已完成 3-充电错误故障，精度_1，偏移量_0，单位_
		*(SendBuffer + 0x2C) = (BMS_PackSOC & 0xFF);		   // uint8	电池包SOC 精度_0.4，偏移量_0，单位_
		*(SendBuffer + 0x2D) = (BMS_PackSOH / 25 * 10) & 0xFF; // SOH 精度1%
		*(SendBuffer + 0x2E) = (BMS_BattVolt >> 8) & 0xFF;	   //电池包总电压
		*(SendBuffer + 0x2F) = (BMS_BattVolt & 0xFF);
		*(SendBuffer + 0x30) = ((BMS_PackCurr >> 8) & 0xFF); // uint16	电池包总电流，充电为负值，放电为正值 精度_0.1，偏移量_-1000，单位_A
		*(SendBuffer + 0x31) = (BMS_PackCurr & 0xFF);
		*(SendBuffer + 0x32) = ((BMS_SysInsRes >> 8) & 0xFF); // uint16	系统绝缘电阻 精度_1，偏移量_0，单位_KΩ
		*(SendBuffer + 0x33) = (BMS_SysInsRes & 0xFF);
		/*28 Byte 继电器状态*/
		*(SendBuffer + 0x34) = (BMS_StPosRly & 0xFF);	   // uint8	主正继电器状态，0-预留 1-断开 2-吸合  ，精度_1，偏移量_0，单位_
		*(SendBuffer + 0x35) = (BMS_StPreCharRly & 0xFF);  // uint8	预充继电器状态，0-预留 1-断开 2-吸合  ，精度_1，偏移量_0，单位_
		*(SendBuffer + 0x36) = (BMS_StNegRly & 0xFF);	   // uint8	主负继电器状态，0-预留 1-断开 2-吸合  ，精度_1，偏移量_0，单位_
		*(SendBuffer + 0x37) = 0;						   // 三合一
		*(SendBuffer + 0x38) = 0;						   // PTC
		*(SendBuffer + 0x39) = 0;						   // 空调
		*(SendBuffer + 0x3A) = (BMS_StPosCharRly1 & 0xFF); // uint8	直流充正继电器1状态，0-预留 1-断开 2-吸合  ，精度_1，偏移量_0，单位_
		*(SendBuffer + 0x3B) = (BMS_StNegCharRly1 & 0xFF); // uint8	直流充负继电器1状态，0-预留 1-断开 2-吸合  ，精度_1，偏移量_0，单位_
		*(SendBuffer + 0x3C) = (BMS_StPosCharRly2 & 0xFF); // uint8	直流充正继电器2状态，0-预留 1-断开 2-吸合  ，精度_1，偏移量_0，单位_
		*(SendBuffer + 0x3D) = (BMS_StNegCharRly2 & 0xFF); // uint8	直流充负继电器2状态，0-预留 1-断开 2-吸合  ，精度_1，偏移量_0，单位_
		*(SendBuffer + 0x3E) = (BMS_StPosHeatRly & 0xFF);  // uint8	加热正继电器状态，0-预留 1-断开 2-吸合  ，精度_1，偏移量_0，单位_
		*(SendBuffer + 0x3F) = (BMS_StNegHeatRly & 0xFF);  // uint8	加热负继电器状态，0-预留 1-断开 2-吸合  ，精度_1，偏移量_0，单位_
		*(SendBuffer + 0x40) = 0;
		/*28-Byte继电器状态结束*/
		*(SendBuffer + 0x50) = ((BMS_CellTotal >> 8) & 0xFF); // uint16	PACK中单体电芯的总数目
		*(SendBuffer + 0x51) = (BMS_CellTotal & 0xFF);
		for (uint16 index = 0; index < min(BMS_CellTotal,BMS_CELL_MAX_NUM); index++)
		{
			*(SendBuffer + 0x52 + index * 2) = ((BMS_CellVolt[index] >> 8) & 0xFF);
			*(SendBuffer + 0x52 + index * 2 + 1) = ((BMS_CellVolt[index]) & 0xFF);
		}
		*(SendBuffer + 0x52 + min(BMS_CellTotal,BMS_CELL_MAX_NUM)*2) = (BMS_TempTotal & 0xFF); //  uint8	PACK中电芯温度点(探针)的总数目
		memcpy(SendBuffer + 0x53 + min(BMS_CellTotal,BMS_CELL_MAX_NUM)*2, BMS_CellTemp, min(BMS_TempTotal,BMS_TEMP_MAX_NUM));
		*(SendBuffer + 0x53 + min(BMS_CellTotal,BMS_CELL_MAX_NUM)*2 + min(BMS_TempTotal,BMS_TEMP_MAX_NUM)) = bcc_chk(SendBuffer, 0x53 + min(BMS_CellTotal,BMS_CELL_MAX_NUM)*2 + min(BMS_TempTotal,BMS_TEMP_MAX_NUM));
		*PtrSendAddr = (uint32)SendBuffer;
		break;
	}
	case 0x92:
	{
		*SendLen = 0x4E;
		SendBuffer = malloc(*SendLen);
		*(SendBuffer + 0) = TCP_START_SYM1;
		*(SendBuffer + 1) = TCP_START_SYM2;
		*(SendBuffer + 2) = TCP_CMD_SYM;
		*(SendBuffer + 3) = TCP_ANS_SYM;
		memcpy(SendBuffer + 4, TcpbattSN, BATT_SN_LEN);
		*(SendBuffer + 0x15) = (TCP_ENCPT_DISABLE & 0xFF); // uint8	TCP_ENCPT_DISABLE
		uint16 DataLen = 0x35;
		*(SendBuffer + 0x16) = ((DataLen >> 8) & 0xFF); // uint16	DataLen
		*(SendBuffer + 0x17) = (DataLen & 0xFF);
		*(SendBuffer + 0x18) = ((UTC8TimeTcp.year) & 0xFF);		   // uint8	year
		*(SendBuffer + 0x19) = (UTC8TimeTcp.month & 0xFF);		   // uint8	month
		*(SendBuffer + 0x1A) = (UTC8TimeTcp.day & 0xFF);		   // uint8	day
		*(SendBuffer + 0x1B) = (UTC8TimeTcp.hour & 0xFF);		   // uint8	hour
		*(SendBuffer + 0x1C) = (UTC8TimeTcp.minute & 0xFF);		   // uint8	minute
		*(SendBuffer + 0x1D) = (UTC8TimeTcp.second & 0xFF);		   // uint8	second
		*(SendBuffer + 0x1E) = (DataIdx & 0xFF);				   // uint8
		*(SendBuffer + 0x1F) = ((UTC8TimeTcp.year) & 0xFF);		   // uint8	year
		*(SendBuffer + 0x20) = (UTC8TimeTcp.month & 0xFF);		   // uint8	month
		*(SendBuffer + 0x21) = (UTC8TimeTcp.day & 0xFF);		   // uint8	day
		*(SendBuffer + 0x22) = (UTC8TimeTcp.hour & 0xFF);		   // uint8	hour
		*(SendBuffer + 0x23) = (UTC8TimeTcp.minute & 0xFF);		   // uint8	minute
		*(SendBuffer + 0x24) = (UTC8TimeTcp.second & 0xFF);		   // uint8	second
		*(SendBuffer + 0x25) = ((BMS_TotalCharCapy >> 24) & 0xFF); // uint32	累积充入Ah 数 精度_0.1，偏移量_0，单位_Ah
		*(SendBuffer + 0x26) = ((BMS_TotalCharCapy >> 16) & 0xFF);
		*(SendBuffer + 0x27) = ((BMS_TotalCharCapy >> 8) & 0xFF);
		*(SendBuffer + 0x28) = (BMS_TotalCharCapy & 0xFF);
		*(SendBuffer + 0x29) = ((BMS_TotalDisCharCapy >> 24) & 0xFF); // uint32	累积放出Ah 数 精度_0.1，偏移量_0，单位_Ah
		*(SendBuffer + 0x2A) = ((BMS_TotalDisCharCapy >> 16) & 0xFF);
		*(SendBuffer + 0x2B) = ((BMS_TotalDisCharCapy >> 8) & 0xFF);
		*(SendBuffer + 0x2C) = (BMS_TotalDisCharCapy & 0xFF);
		*(SendBuffer + 0x2D) = ((BMS_TotalCharEngy >> 24) & 0xFF); // uint32	累计充入kWh 数 精度_0.1，偏移量_0，单位_KWh
		*(SendBuffer + 0x2E) = ((BMS_TotalCharEngy >> 16) & 0xFF);
		*(SendBuffer + 0x2F) = ((BMS_TotalCharEngy >> 8) & 0xFF);
		*(SendBuffer + 0x30) = (BMS_TotalCharEngy & 0xFF);
		*(SendBuffer + 0x31) = ((BMS_TotalDisCharEngy >> 24) & 0xFF); // uint32	累计放出kWh 数 精度_0.1，偏移量_0，单位_KWh
		*(SendBuffer + 0x32) = ((BMS_TotalDisCharEngy >> 16) & 0xFF);
		*(SendBuffer + 0x33) = ((BMS_TotalDisCharEngy >> 8) & 0xFF);
		*(SendBuffer + 0x34) = (BMS_TotalDisCharEngy & 0xFF);
		*(SendBuffer + 0x35) = ((BMS_TotalBackCharCapy >> 24) & 0xFF); // uint32	累计动能回馈充入Ah 数 精度_0.1，偏移量_0，单位_Ah
		*(SendBuffer + 0x36) = ((BMS_TotalBackCharCapy >> 16) & 0xFF);
		*(SendBuffer + 0x37) = ((BMS_TotalBackCharCapy >> 8) & 0xFF);
		*(SendBuffer + 0x38) = (BMS_TotalBackCharCapy & 0xFF);
		*(SendBuffer + 0x39) = ((BMS_TotalBackCharEngy >> 24) & 0xFF); // uint32	累计动能回馈充入kWh 数 精度_0.1，偏移量_0，单位_KWh
		*(SendBuffer + 0x3A) = ((BMS_TotalBackCharEngy >> 16) & 0xFF);
		*(SendBuffer + 0x3B) = ((BMS_TotalBackCharEngy >> 8) & 0xFF);
		*(SendBuffer + 0x3C) = (BMS_TotalBackCharEngy & 0xFF);
		*(SendBuffer + 0x3D) = ((BMS_TotalStaCharCapy >> 24) & 0xFF); // uint32	累计换电站充入Ah 数 精度_0.1，偏移量_0，单位_Ah
		*(SendBuffer + 0x3E) = ((BMS_TotalStaCharCapy >> 16) & 0xFF);
		*(SendBuffer + 0x3F) = ((BMS_TotalStaCharCapy >> 8) & 0xFF);
		*(SendBuffer + 0x40) = (BMS_TotalStaCharCapy & 0xFF);
		*(SendBuffer + 0x41) = ((BMS_TotalStaCharEngy >> 24) & 0xFF); // uint32	累计换电站充入kWh 数 精度_0.1，偏移量_0，单位_KWh
		*(SendBuffer + 0x42) = ((BMS_TotalStaCharEngy >> 16) & 0xFF);
		*(SendBuffer + 0x43) = ((BMS_TotalStaCharEngy >> 8) & 0xFF);
		*(SendBuffer + 0x44) = (BMS_TotalStaCharEngy & 0xFF);
		*(SendBuffer + 0x45) = ((BMS_TotalGunCharCapy >> 24) & 0xFF); // uint32	累计插枪充电充入Ah 数 精度_0.1，偏移量_0，单位_Ah
		*(SendBuffer + 0x46) = ((BMS_TotalGunCharCapy >> 16) & 0xFF);
		*(SendBuffer + 0x47) = ((BMS_TotalGunCharCapy >> 8) & 0xFF);
		*(SendBuffer + 0x48) = (BMS_TotalGunCharCapy & 0xFF);
		*(SendBuffer + 0x49) = ((BMS_TotalGunCharEngy >> 24) & 0xFF); // uint32	累计插枪充电充入kWh 数 精度_0.1，偏移量_0，单位_KWh
		*(SendBuffer + 0x4A) = ((BMS_TotalGunCharEngy >> 16) & 0xFF);
		*(SendBuffer + 0x4B) = ((BMS_TotalGunCharEngy >> 8) & 0xFF);
		*(SendBuffer + 0x4C) = (BMS_TotalGunCharEngy & 0xFF);
		*(SendBuffer + 0x4D) = bcc_chk(SendBuffer, 0x4D);
		*PtrSendAddr = (uint32)SendBuffer;
		break;
	}
	default:
		break;
	}
}
void GetUtc8Time(UTC8TimeType *UTC8TimeTcp)
{
	char *AtCmdAsk = (char *)("AT+CCLK?\r\n");
	uint8 AtCmdLen = mstrlen(AtCmdAsk);
	uint8 ReadLen = 0;
	uint8 *retptr = NULL;
	uint8 *UartRecvPtr=NULL;
	UART_Query_Data(UART_LPUART1, UART_LPUART1, AtCmdAsk, AtCmdLen, &UartRecvPtr, &ReadLen, pdMS_TO_TICKS(100));
	if (ReadLen > 0)
	{
		if ((uint8 *)strstr((char *)UartRecvPtr, (char *)("OK")))
		{
			retptr = (uint8 *)strstr((char *)UartRecvPtr, (char *)("+CCLK:"));
			UTC8TimeTcp->year = CharToHex(*(retptr + 8)) * 10 + CharToHex(*(retptr + 9));
			UTC8TimeTcp->month = CharToHex(*(retptr + 11)) * 10 + CharToHex(*(retptr + 12));
			UTC8TimeTcp->day = CharToHex(*(retptr + 14)) * 10 + CharToHex(*(retptr + 15));
			UTC8TimeTcp->hour = CharToHex(*(retptr + 17)) * 10 + CharToHex(*(retptr + 18));
			UTC8TimeTcp->minute = CharToHex(*(retptr + 20)) * 10 + CharToHex(*(retptr + 21));
			UTC8TimeTcp->second = CharToHex(*(retptr + 23)) * 10 + CharToHex(*(retptr + 24));
		}

		if(UartRecvPtr != NULL)
		{
			free(UartRecvPtr);
		}
		UartRecvPtr = NULL;
	}
}
static void GetCSQValue(uint8 *out)
{
	char *AtCmdAsk = (char *)("AT+CSQ\r\n");
	uint8 AtCmdLen = mstrlen(AtCmdAsk);
	uint8 ReadLen = 0;
	uint8 *retptr = NULL;
	uint8 *UartRecvPtr=NULL;
	UART_Query_Data(UART_LPUART1, UART_LPUART1, AtCmdAsk, AtCmdLen, &UartRecvPtr, &ReadLen, pdMS_TO_TICKS(100));
	*out = 99;
	if (ReadLen > 0)
	{
		if ((uint8 *)strstr((char *)UartRecvPtr, (char *)("OK")))
		{
			*out = 0;
			retptr = (uint8 *)strstr((char *)UartRecvPtr, (char *)("+CSQ:"));
			char CsqStr[5];
			for (uint8 i = 0; i < 5; i++)
			{
				if (*(retptr+i+6) == ',')
				{
					break;
				}
				memcpy((CsqStr+i),(retptr+i+6),1);
			}
			*out = atoi(CsqStr);
		}

		if(UartRecvPtr != NULL)
		{
			free(UartRecvPtr);
		}
		UartRecvPtr = NULL;
	}
	return;
}
static void TcpDataInfoRecvHandle(uint8 *DataRecv, uint16 DataRecvLen)
{
	uint8 Tcp_Cmd;
	uint8 *Ptr = NULL, *retptr = NULL;
	uint8 TcpCmdAnswer[31];
	uint16 TcpDataLen = 0;
	uint16 NumCalTemp = 1;
	retptr = (uint8 *)strstr((char *)DataRecv, (char *)("\r\n##"));
	if (retptr == NULL)
		return;
	for (uint8 i = 0; i < 5; i++)
	{
		if (*(retptr - i - 1) == 'D')
		{
			break;
		}
		TcpDataLen = TcpDataLen + CharToHex(*(retptr - i - 1)) * NumCalTemp;
		NumCalTemp = NumCalTemp * 10;
	}
	if (TcpDataLen > 0)
	{
		Ptr = retptr + 2;
		if ((*(Ptr + 0) == TCP_START_SYM1) && (*(Ptr + 1) == TCP_START_SYM2)) //服务器起始信息
		{
			Tcp_Cmd = *(Ptr + 2); //命令标志
			if (*(Ptr + 3) == 0xFE)
			{
				TcpWorkState = 0x01;//需要暂停发送，进行命令应答的标志
			}
			switch (Tcp_Cmd)
			{
			case TCP_QUERY_SYM:
				break;
			case TCP_SETCMD_SYM:
				break;
			case TCP_CONCMD_SYM:
			{
				TcpCmdAnswer[0] = TCP_START_SYM1;
				TcpCmdAnswer[1] = TCP_START_SYM1;
				TcpCmdAnswer[2] = TCP_CONCMD_SYM;
				if (*(Ptr + 30) == 0x01) //远程升级指令
				{
					Fota_Func(Ptr, SocketId);
				}
				else
				{
					TcpCmdAnswer[3] = 0x0f;
					memcpy(&TcpCmdAnswer[4], (Ptr + 4), BATT_SN_LEN);
					TcpCmdAnswer[21] = TCP_ENCPT_DISABLE;
					TcpCmdAnswer[22] = 0x00;
					TcpCmdAnswer[23] = 0x06;
					memcpy(&TcpCmdAnswer[24], (Ptr + 24), 6);
					TcpCmdAnswer[30] = bcc_chk(TcpCmdAnswer, 30);
					tcpipConnectionSend(SocketId, TcpCmdAnswer, 31);
				}
			}
			default:
			{
				break;
			}
			}
		}
	}
}
sint8 tcpipConnectionSend(uint8 TcpConnectId, uint8 *SendDataPtr, uint16 SendDataLen)
{
	sint8 outValue = -1;
	uint8  sendErrConuter= 0;
	uint8 ReadLen = 0;
	char AtCmdSend[20] = {0};
	uint8 AtCmdSendTotalLen = 0;
	uint8 *UartRecvPtr1 =NULL;
	uint8 *UartRecvPtr =NULL;
	uint8 ret = 0;
	sprintf(AtCmdSend, "AT+CIPSEND=%d,%d\r\n", TcpConnectId, SendDataLen);
	AtCmdSendTotalLen = mstrlen(AtCmdSend);
	myPrintf("send,test\n");
	while(outValue!=0&&sendErrConuter<10)
	{
		ret = UART_Query_Data(UART_LPUART1, UART_LPUART1, (uint8 *)AtCmdSend, AtCmdSendTotalLen, &UartRecvPtr1, &ReadLen, 1000);
		if (ret==0&&ReadLen>0&&(uint8 *)strstr((char *)UartRecvPtr1, (char *)(">")))
		{
			UART_Query_Data(UART_LPUART1, UART_LPUART1, (uint8 *)SendDataPtr, SendDataLen, &UartRecvPtr, &ReadLen, 1000);
			if (ReadLen>0&&(uint8 *)strstr((char *)UartRecvPtr, (char *)("\r\nOK\r\n\r\n+CIPSEND")))
			{
				outValue = 0;
			}
			else
			{
				outValue = -2;
			}
		}
		else
		{
			outValue = -1;
		}
		sendErrConuter++;
		vTaskDelay(pdMS_TO_TICKS(100*sendErrConuter));
	}

	if(UartRecvPtr != NULL)
	{
		free(UartRecvPtr);
	}
	UartRecvPtr = NULL;
	if(UartRecvPtr1 != NULL)
	{
		free(UartRecvPtr1);
	}
	UartRecvPtr1 = NULL;
	return outValue;
}
