#include "usart.h"
#include "mmodbus.h"
#include "dlt645.h"
#include "gateway_message.h"
#include "tcp_server.h"
#include "timer.h"
#include "updata.h"


uint8_t rxByte;
uint8_t rx_232_Buffer[RX_BUFFER_SIZE];
uint8_t recv_232_done;
unsigned int rxIndex = 0;

uint8_t UART6_RX_BUF[BUFF_SIZE];
uint8_t UART6_RX_STAT=0;
uint32_t UART6_RX_NUM = 0;	

UART_HandleTypeDef 	USART_InitStruct_485;
UART_HandleTypeDef  USART_InitStruct_232;
UART_HandleTypeDef  USART_InitStruct_DEBUG;
DMA_HandleTypeDef 	DMA_DEBUG_RX;

//重定向c库函数printf到串口，重定向后可使用printf函数
int fputc(int ch, FILE *f)
{
		/* 发送一个字节数据到串口 */
		USART_232->DR = (ch & (uint16_t)0x01FF);
		
		/* 等待发送完毕 */
		while (__HAL_UART_GET_FLAG(&USART_InitStruct_232, USART_FLAG_TXE) == RESET);	
		return (ch);
}


/*           232串口配置             */

void USART_232_config(void)
{
    __HAL_RCC_GPIOA_CLK_ENABLE();
		__HAL_RCC_USART1_CLK_ENABLE();
  
		GPIO_InitTypeDef GPIO_InitStruct = {0};
    GPIO_InitStruct.Pin = USART_232_TX_PIN | USART_232_RX_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
	
		USART_InitStruct_232.Instance = USART_232;
		USART_InitStruct_232.Init.BaudRate = USART_232_BAUDRATE;
		USART_InitStruct_232.Init.WordLength = UART_WORDLENGTH_8B;
		USART_InitStruct_232.Init.StopBits = UART_STOPBITS_1;
		USART_InitStruct_232.Init.Parity = UART_PARITY_NONE;
		USART_InitStruct_232.Init.Mode = UART_MODE_TX_RX;
		USART_InitStruct_232.Init.HwFlowCtl = UART_HWCONTROL_NONE;
		USART_InitStruct_232.Init.OverSampling = UART_OVERSAMPLING_8;
		HAL_UART_Init(&USART_InitStruct_232);
		
		HAL_NVIC_SetPriority(USART_232_IRQ, 1, 0);
    HAL_NVIC_EnableIRQ(USART_232_IRQ);
	
//		HAL_UART_Receive_IT(&USART_InitStruct_232, &rxByte, 1);
		__HAL_UART_ENABLE_IT(&USART_InitStruct_232, UART_IT_RXNE); // 使能接收中断	
		__HAL_UART_ENABLE_IT(&USART_InitStruct_232, UART_IT_IDLE); // 使能空闲中断	
}

void USART_232_IRQHandler(void){
//    HAL_UART_IRQHandler(&USART_InitStruct_232);
	if(__HAL_UART_GET_FLAG(&USART_InitStruct_232, UART_FLAG_RXNE) && __HAL_UART_GET_IT_SOURCE(&USART_InitStruct_232, UART_IT_RXNE))
	{
				rx_232_Buffer[rxIndex] = USART_InitStruct_232.Instance->DR;
				rxIndex++;
	}
	if (RESET != __HAL_UART_GET_FLAG(&USART_InitStruct_232, USART_FLAG_IDLE) && __HAL_UART_GET_IT_SOURCE(&USART_InitStruct_232, UART_IT_IDLE))
	{	
		uint8_t i;
		i = USART_InitStruct_232.Instance->SR;
		i = USART_InitStruct_232.Instance->DR;
		rxIndex = 0;
		recv_232_done = 1;
		return;
	}
	USART1->DR;
}

void USART_232_Send(uint8_t *message,uint16_t size)
{
	recv_232_done = 0;
	HAL_UART_Transmit(&USART_InitStruct_232, message,size,HAL_MAX_DELAY);
}




/*           485串口配置             */
void USART_485_DE_init()
{
		__HAL_RCC_GPIOC_CLK_ENABLE();
		GPIO_InitTypeDef GPIO_InitStruct = {0};
		GPIO_InitStruct.Pin = USART_485_DE_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    HAL_GPIO_Init(USART_485_DE_GPIO_PORT, &GPIO_InitStruct);
}
void USART_485_DE_TX()
{
	HAL_GPIO_WritePin(USART_485_DE_GPIO_PORT,USART_485_DE_PIN,1);
}
void USART_485_DE_RX()
{
	HAL_GPIO_WritePin(USART_485_DE_GPIO_PORT,USART_485_DE_PIN,0);
}

// 485发送数据
void USART_485_Send(uint8_t *message,uint16_t size)
{
	uint16_t i=0;
	USART_485_DE_TX();
	HAL_UART_Transmit(&USART_InitStruct_485, message, size, HAL_MAX_DELAY);
	USART_485_DE_RX();
}
// USART_485 初始化
void USART_485_config()
{
		USART_485_DE_init();
	
		__HAL_RCC_USART3_CLK_ENABLE();
		__HAL_RCC_GPIOC_CLK_ENABLE();
	
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    // 配置 GPIOC Pin 11 和 10 分别作为 USART3 的 RX 和 TX 引脚
    GPIO_InitStruct.Pin = USART_485_RX_PIN | USART_485_TX_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF7_USART3;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

    USART_InitStruct_485.Instance = USART_485;
    USART_InitStruct_485.Init.BaudRate = USART_485_BAUDRATE;
    USART_InitStruct_485.Init.WordLength = UART_WORDLENGTH_8B;
    USART_InitStruct_485.Init.StopBits = UART_STOPBITS_1;
    USART_InitStruct_485.Init.Parity = UART_PARITY_NONE;
    USART_InitStruct_485.Init.Mode = UART_MODE_TX_RX; // 既支持发送也支持接收
    USART_InitStruct_485.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    USART_InitStruct_485.Init.OverSampling = UART_OVERSAMPLING_16;
    HAL_UART_Init(&USART_InitStruct_485);

		HAL_NVIC_SetPriority(USART_485_IRQ, 0, 0);
    HAL_NVIC_EnableIRQ(USART_485_IRQ);
		// 初始化 DE 引脚 接收数据
    HAL_GPIO_WritePin(USART_485_DE_GPIO_PORT,USART_485_DE_PIN,GPIO_PIN_RESET); 
		
//		HAL_UART_Receive_IT(&USART_InitStruct_485, &rxByte, 1);
		__HAL_UART_ENABLE_IT(&USART_InitStruct_485, UART_IT_RXNE); // 使能接收中断	
		__HAL_UART_ENABLE_IT(&USART_InitStruct_485, UART_IT_IDLE); // 使能空闲中断	
}

/*
 *  函数名：void Config_485_Port(uint32_t baudrate, uint8_t databits, uint8_t stopbits, uint8_t parity, uint8_t flowcontrol)
 *  输入参数：baudrate,databits,stopbits,parity,flowcontol 串口的配置参数
 *  输出参数：无
 *  返回值：无
 *  函数作用：根据输入参数进行配置485串口参数
 */
void Config_485_Port(uint32_t baudrate, uint8_t databits, uint8_t stopbits, uint8_t parity, uint8_t flowcontrol)
{
		uint8_t wordLength;
		if(parity!=0)
		{
			wordLength=databits+1;
		}else wordLength=databits;

		__HAL_RCC_USART3_CLK_ENABLE();
		__HAL_RCC_GPIOC_CLK_ENABLE();
	
		GPIO_InitTypeDef GPIO_InitStruct = {0};

		// 配置 GPIOC Pin 11 和 10 分别作为 USART3 的 RX 和 TX 引脚
    GPIO_InitStruct.Pin = USART_485_RX_PIN | USART_485_TX_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF7_USART3;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

		USART_InitStruct_485.Instance = USART_485;
    USART_InitStruct_485.Init.BaudRate = USART_485_BAUDRATE;
    USART_InitStruct_485.Init.WordLength = UART_WORDLENGTH_8B;
    USART_InitStruct_485.Init.StopBits = UART_STOPBITS_1;
    USART_InitStruct_485.Init.Parity = UART_PARITY_NONE;
    USART_InitStruct_485.Init.Mode = UART_MODE_TX_RX; // 既支持发送也支持接收
    USART_InitStruct_485.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    USART_InitStruct_485.Init.OverSampling = UART_OVERSAMPLING_16;
    HAL_UART_Init(&USART_InitStruct_485);

		HAL_NVIC_SetPriority(USART_485_IRQ, 0, 0);
    HAL_NVIC_EnableIRQ(USART_485_IRQ);
		// 初始化 DE 引脚 接收数据
    HAL_GPIO_WritePin(USART_485_DE_GPIO_PORT,USART_485_DE_PIN,GPIO_PIN_RESET); 
		
//		HAL_UART_Receive_IT(&USART_InitStruct_485, &rxByte, 1);
		__HAL_UART_ENABLE_IT(&USART_InitStruct_485, UART_IT_RXNE); // 使能接收中断	
		__HAL_UART_ENABLE_IT(&USART_InitStruct_485, UART_IT_IDLE); // 使能空闲中断	
	
}

void USART_485_IRQHandler(void){
			GATEWAY_PARAMS *get;
			get= get_gateway_config_params();
			if(get->device_params->protocol == 3)
			mmodbus_callback(&USART_InitStruct_485);
			else if(get->device_params->protocol == 1 || get->device_params->protocol == 2)
			dlt_callback(&USART_InitStruct_485);
}


void DEBUG_USART_Config(void)
{
	GPIO_InitTypeDef GPIO_InitStruct = {0};

  // Enable USART6 clock
  __HAL_RCC_USART6_CLK_ENABLE();
  // Enable GPIOC clock
  __HAL_RCC_GPIOC_CLK_ENABLE();

  // Configure USART6 pins
	GPIO_InitStruct.Pin = DEBUG_USART_RX_PIN | DEBUG_USART_TX_PIN;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.Alternate = GPIO_AF8_USART6;// Connect USART6 pins to AF8
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
	
	// Configure USART6
	USART_InitStruct_DEBUG.Instance = DEBUG_USART;
	USART_InitStruct_DEBUG.Init.BaudRate = DEBUG_USART_BAUDRATE;
	USART_InitStruct_DEBUG.Init.WordLength = UART_WORDLENGTH_8B;
	USART_InitStruct_DEBUG.Init.StopBits = UART_STOPBITS_1;
	USART_InitStruct_DEBUG.Init.Parity = UART_PARITY_NONE;
	USART_InitStruct_DEBUG.Init.Mode = UART_MODE_TX_RX; // 既支持发送也支持接收
	USART_InitStruct_DEBUG.Init.HwFlowCtl = UART_HWCONTROL_NONE;
	USART_InitStruct_DEBUG.Init.OverSampling = UART_OVERSAMPLING_16;
	HAL_UART_Init(&USART_InitStruct_DEBUG);

	HAL_NVIC_SetPriority(DEBUG_USART_IRQ, 2, 1);
  HAL_NVIC_EnableIRQ(DEBUG_USART_IRQ);
	
	// Enable USART6
	__HAL_UART_ENABLE_IT(&USART_InitStruct_DEBUG, UART_IT_IDLE); // 使能空闲中断
//	__HAL_UART_ENABLE_IT(&USART_InitStruct_DEBUG, UART_IT_RXNE); // 使能接收中断		
	__HAL_DMA_ENABLE(&DMA_DEBUG_RX);						//使能DMA
  __HAL_UART_ENABLE(&USART_InitStruct_DEBUG);
//	__HAL_UART_CLEAR_FLAG(&USART_InitStruct_DEBUG, USART_FLAG_TC);
	
}


void DEBUG_USART_IRQHandler(void)
{	
	uint16_t clear;
	if(RESET != __HAL_UART_GET_FLAG(&USART_InitStruct_DEBUG, UART_FLAG_IDLE)) // 判断是否是空闲中断
	{
		__HAL_UART_CLEAR_IDLEFLAG(&USART_InitStruct_DEBUG); //清空空闲中断标志位
		//关闭DMA
		__HAL_DMA_DISABLE(&DMA_DEBUG_RX);
//		HAL_UART_DMAStop(&USART_InitStruct_DEBUG); 
		UART6_RX_NUM = BUFF_SIZE - __HAL_DMA_GET_COUNTER(&DMA_DEBUG_RX);
		//清除DMA中断
		__HAL_DMA_CLEAR_FLAG(&DMA_DEBUG_RX,DMA_FLAG_TCIF1_5);
		__HAL_DMA_ENABLE(&DMA_DEBUG_RX);
		//接收状态置位
		UART6_RX_STAT=1;
	}
}

void USART_DMA_Config(void)
{
	// 使能串口和DMA时钟
	__HAL_RCC_USART6_CLK_ENABLE();
	__HAL_RCC_DMA2_CLK_ENABLE();
  
	DMA_DEBUG_RX.Instance = DEBUG_USART_DMA_STREAM;
	DMA_DEBUG_RX.Init.Channel = DEBUG_USART_DMA_CHANNEL;
	/*方向：从外设到内存*/		
	DMA_DEBUG_RX.Init.Direction =  DMA_PERIPH_TO_MEMORY;
	/*外设地址不增*/	 
	DMA_DEBUG_RX.Init.PeriphInc = DMA_PINC_DISABLE;
	/*内存地址自增*/
	DMA_DEBUG_RX.Init.MemInc = DMA_MINC_ENABLE;
	 /*外设数据单位*/	
	DMA_DEBUG_RX.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
	/*内存数据单位 8bit*/
	DMA_DEBUG_RX.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;	
	/*DMA模式：不断循环*/
	DMA_DEBUG_RX.Init.Mode = DMA_NORMAL;
	/*优先级：中*/	
	DMA_DEBUG_RX.Init.Priority = DMA_PRIORITY_MEDIUM;
	/*禁用FIFO*/
	DMA_DEBUG_RX.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
	DMA_DEBUG_RX.Init.FIFOThreshold= DMA_FIFO_THRESHOLD_FULL;  
	
	 HAL_DMA_Init(&DMA_DEBUG_RX);
	__HAL_LINKDMA(&USART_InitStruct_DEBUG, hdmarx, DMA_DEBUG_RX);	
	
	 SET_BIT(USART_InitStruct_DEBUG.Instance->CR3, USART_CR3_DMAR);
	 HAL_DMA_Start(&DMA_DEBUG_RX,DEBUG_USART_DR_BASE, (uint32_t)UART6_RX_BUF, BUFF_SIZE);
	__HAL_DMA_ENABLE_IT(&DMA_DEBUG_RX,DMA_IT_TC);
	
	HAL_NVIC_SetPriority(DMA2_Stream1_IRQn, 2, 2);
  HAL_NVIC_EnableIRQ(DMA2_Stream1_IRQn);
}


void DMA2_Stream1_IRQHandler() {
    if (__HAL_DMA_GET_IT_SOURCE(&DMA_DEBUG_RX,DMA_IT_TC)) 
		{
        __HAL_DMA_CLEAR_FLAG(&DMA_DEBUG_RX,DMA_IT_TC);
    }
}
 

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *husart)
{	
		// USART 232
    if(husart->Instance == USART_232)
		{
				if (rxIndex < RX_BUFFER_SIZE)
        {
            // 将接收到的数据存储在缓冲区中
						rx_232_Buffer[rxIndex] = rxByte;
						rxIndex++;
        }							
				HAL_UART_Transmit(husart, rx_232_Buffer,rxIndex,HAL_MAX_DELAY);			
				memset(rx_232_Buffer, 0, rxIndex);
				rxIndex = 0;
				HAL_UART_Receive_IT(husart, &rxByte, 1);
		}
		
		// USART 485
		if(husart->Instance == USART_485)
		{
				if (rxIndex < RX_BUFFER_SIZE)
        {
            // 将接收到的数据存储在缓冲区中
						rx_232_Buffer[rxIndex] = rxByte;
						rxIndex++;
        }							
				memset(rx_232_Buffer, 0, rxIndex);
				rxIndex = 0;
				HAL_UART_Receive_IT(husart, &rxByte, 1);
		}
		if(husart->Instance == USART6)
		{
	
		}

}


/*    上位机功能    */

// 储存上位机发送的config数据，并返回上位机操作结果
void save_config_232(uint8_t* buf)
{
		char* saveData = mymalloc(SRAMEX,20 * 1024);//(RECV_BUF_SIZE);// 存储config数据			最大20K，暂定3K
		if(saveData == NULL) 
			LogPrint(LOG_ERROR,__FILE__,__FUNCTION__,__LINE__,"recv buf malloc fail");
		memset(saveData,0,strlen(saveData));	
		// 插入tcp_config标志位，后续不通过http获取默认配置数据
		sprintf(saveData, "tcp_config");
		sprintf(saveData + strlen(saveData),"%s",buf);
		
		DeleteDirFile("device.txt");
		write_file("device.txt",saveData,strlen(saveData));// 储存到flash 不用判断失败
		myfree(SRAMEX, saveData);
		
		char* retMsg = mymalloc(SRAMEX,32);
		memset(retMsg, 0, strlen(retMsg));
		retMsg = "{\"write_config\":\"success\"}";
		USART_232_Send((uint8_t*)retMsg, strlen(retMsg));
		myfree(SRAMEX ,retMsg);
}


void read_device_params(char* device_params)
{
	GATEWAY_PARAMS *get;
	get= get_gateway_config_params();
	DEVICE_PARAMS *current_device=get->device_params;
	sprintf(device_params, "{\"read_config\":\"success\",\"baudrate\":%d,\"checkBit\":%d,\"commandTopic\":\"%s\",\"dataBit\":%d,\
\"deviceId\":\"%s\",\"host\":\"%s\",\"inboundTime\":%d,\"messageTopic\":\"%s\",\"port\":%d,\"stopBit\":%d,\"deviceList\":[",get->baudrate,
			get->checkBit,get->commandTopic,get->dataBits,get->deviceId,get->host,get->inboundTime,get->messageTopic,get->port,get->stopBit);
	while(current_device != NULL)
	{	
		sprintf(device_params + strlen(device_params),"{\"protocol\":%d,\"bigLittleFormat\":%d,\"deviceId\":\"%s\",\"sensorData\":[",
												current_device->protocol,current_device->MDBbigLittleFormat,current_device->deviceID);
			GATEWAY_READ_DLT645_COMMAND *read_dlt645_command = current_device->params->gateway_read_dlt645_command;
			GATEWAY_READ_MODBUS_COMMAND *read_modbus_command = current_device->params->gateway_read_modbus_command;
			GATEWAY_WRITE_MODBUS_COMMAND *write_modbus_command = current_device->params->gateway_write_modbus_command;
			
			// dlt645 read
			while(read_dlt645_command != NULL)
			{	
				sprintf(device_params + strlen(device_params),"{\"identifier645\":%d,\"identifier\":\"%s\",\"deviceID645\":\"%s\"},",
											read_dlt645_command->Identification,read_dlt645_command->keyword,read_dlt645_command->deviceID645);
				read_dlt645_command = read_dlt645_command->nextParams;
			}
		
			// modbus read
			while(read_modbus_command != NULL)
			{
				sprintf(device_params + strlen(device_params),"{\"rFunctionCode\":%d,\"registerAddress\":%d,\"slaveAddress\":%d,\"registerByteNum\":%d,\"identifier\":\"%s\",\"precise\":%d},",
																											read_modbus_command->functionCode, read_modbus_command->registerAddress,read_modbus_command->slaveAddress,
																											read_modbus_command->registerByteNum,read_modbus_command->keyword,read_modbus_command->decimalPoint);
				read_modbus_command = read_modbus_command->nextParams;
			}
			
			// modbus write
			sprintf(device_params + strlen(device_params)-1,"], \"commandData\":[");//sensorData:[ 
			while(write_modbus_command != NULL)
			{
				sprintf(device_params + strlen(device_params),"{\"registerAddress\":%d,\"slaveAddress\":%d,\"wFunctionCode\":%d,\"registerByteNum\":%d},",
								write_modbus_command->registerAddress,write_modbus_command->slaveAddress,write_modbus_command->functionCode,write_modbus_command->registerByteNum);
				write_modbus_command = write_modbus_command->nextParams;
			}		
			sprintf(device_params + strlen(device_params)-1,"]},");// commandData:[
			current_device = current_device->nextDevice;	
	}
	sprintf(device_params + strlen(device_params) -1 ,"]}");
}
void read_config_232(void)
{
	GATEWAY_PARAMS *get;
	get= get_gateway_config_params();
	char* device_params = mymalloc(SRAMEX, 3 * 1024);
	memset(device_params,0,3 * 1024);
	if(get->device_params == NULL)
	{
		sprintf(device_params, "{\"read_config\":\"error\"}");
		USART_232_Send((uint8_t*)device_params, strlen(device_params));
	}
	else
	{
		read_device_params(device_params);
		USART_232_Send((uint8_t*)device_params, strlen(device_params));
	}
	myfree(SRAMEX, device_params);
}

// 设备嗅探
void find_device_232(void)
{
	char deviceId[50];// 发送设备名
	GATEWAY_PARAMS *get;
	get= get_gateway_config_params();
	if(get->device_params == NULL)
	{	
//		sprintf(deviceId, "{\"find_device\":\"%s\"}", gatewayId);		
		sprintf(deviceId, "{\"find_device\":\"error\"}");		
		USART_232_Send((uint8_t*)deviceId, strlen(deviceId));
	}
	else
	{
		sprintf(deviceId, "{\"find_device\":\"%s\"}", get->deviceId);		
		USART_232_Send((uint8_t*)deviceId, strlen(deviceId));
	}
	memset(deviceId, 0, 50);
}


// 储存上位机发送的config_add数据，并返回上位机操作结果
void add_config_232(uint8_t* dataBuf)
{	
	GATEWAY_PARAMS *get;
	get= get_gateway_config_params();
	DEVICE_PARAMS *device=get->device_params;
	char* retMsg = mymalloc(SRAMEX,32);
	memset(retMsg, 0, strlen(retMsg));
	while(device != NULL)// 一直轮询到当前为NULL
	{
		device = device->nextDevice;
	}
	addDevice((char*)dataBuf);
	// 再检查更新后的deviceId是否为NULL
	if(device == NULL)// error
	{	
		retMsg = "{\"write_config\":\"error\"}";
		USART_232_Send((uint8_t*)retMsg, strlen(retMsg));
	}
	else// success
	{
		retMsg = "{\"write_config\":\"success\"}";
		USART_232_Send((uint8_t*)retMsg, strlen(retMsg));
	}
		myfree(SRAMEX, retMsg);
}


// 切换工作模式
void work_mode_232(uint8_t* buf)
{
	/* 用标志位开关data_task任务中，发送数据的方式 */
		// 内置协议模式
		if(strstr((char*)buf,"protocolsMode") != NULL)
		{
			ProtocolsModeFlag = 1;// 开启内置协议模式
			TransparentModeFlag = 0; // 关闭透明传输模式
			LogPrint(LOG_INFO,__FILE__,__FUNCTION__,__LINE__,"ProtocolsMode");	
		}
		// 透明传输模式
		if(strstr((char*)buf,"TransparentMode") != NULL)
		{
			ProtocolsModeFlag = 0;// 关闭内置协议模式
			TransparentModeFlag = 1; // 开启透明传输模式
			LogPrint(LOG_INFO,__FILE__,__FUNCTION__,__LINE__,"TransparentModeFlag");	
		}
}

// 更新OTA数据
void updata_232(void)
{
	int recv_size, i;

	uint16_t crc;	
	uint8_t databuf[1024];// 保存包数据
	
	uint16_t packId = 0x01;
	uint8_t stx = 0x02,eot = 0x04,ack = 0x06,nak = 0x15,C = 0x43;

	// 向上位机发送就绪信号
	char* retMsg = mymalloc(SRAMEX,32);
	memset(retMsg, 0, strlen(retMsg));
	retMsg = "{\"software_update\":\"ready\"}";
	USART_232_Send((uint8_t*)retMsg,  strlen(retMsg));
	myfree(SRAMEX, retMsg);
	memset(rx_232_Buffer, 0, strlen(rx_232_Buffer));
	delay_ms(300);
	
	// 发送第一个C
	USART_232_Send(&C, 1);
	delay_ms(300);
__start:
	i = 0;
	//等待接收到消息，最长等待3S
	while(recv_232_done == 0 && i < 3000) 
	{
		delay_ms(1);
		i++;
	}
	if(recv_232_done == 0)	USART_232_Send(&C, 1);//如果还没接收到消息，再发送一个C
	do{
			// 接收到结束信号，反馈ack
			if(rx_232_Buffer[0] == eot)
			{
				USART_232_Send(&ack, 1);
				delay_ms(300);
				break;
			}
			// 检测头标志
			if(rx_232_Buffer[0] != stx)
			{
				USART_232_Send(&nak, 1);
				delay_ms(300);
				goto __start;
			}
			// 检测包序列
			if(rx_232_Buffer[1] != packId)
			{
				USART_232_Send(&nak, 1);
				delay_ms(300);
				goto __start;
			}
			// 检测包号反码
			if(rx_232_Buffer[2] !=(~packId & 0xff))
			{
				USART_232_Send(&nak, 1);
				delay_ms(300);
				goto __start;
			}
			// 提取数据包
			for(int i = 0; i < 1024; i++)
			{
				databuf[i] = rx_232_Buffer[3 + i];
			}
			crc = Checkcrc16(databuf, 1024);
			// 检测数据包的校验码
			if (((crc & 0x00FF) != rx_232_Buffer[1028]) || (((crc & 0xFF00) >> 8) != rx_232_Buffer[1027]))
			{	
				USART_232_Send(&nak, 1);
				delay_ms(300);
				goto __start;
			}
			// 对数据包进行操作
			/*                */
			memset(databuf, 0, sizeof(databuf));
			
			// 准备接收下一包数据
			USART_232_Send(&ack, 1);
			delay_ms(300);
			packId += 1;

	}while(recv_232_done);

		// 所有数据包接受完成，准备重启
		__set_PRIMASK(1);
		NVIC_SystemReset();
}

void USART_232_task(void const * argument)
{
	int j;
	char* recv_cmd[] = {"\"cmd\":\"write_config\"","\"cmd\":\"write_config_add\"",
											"\"cmd\":\"read_config\"","\"cmd\":\"find_device\"",
											"\"cmd\":\"ip_config\"","\"cmd\":\"toggle_work_mode\"",
											"\"cmd\":\"software_update\"","\"cmd\":\"reboot\"",
											"\"cmd\":\"cmd error\""	};
	while(1)
	{
		j = 0;
		for(int i = 0; i < sizeof(recv_cmd)/sizeof(recv_cmd[0]); i++)
		{
			if(strstr((char*)rx_232_Buffer,recv_cmd[i]) != NULL)
			{
				i = sizeof(recv_cmd)/sizeof(recv_cmd[0]);
			}
			j++;
		}
		
		if (ProtocolsModeFlag) {
					switch (j) {
						case WRITE_CONFIG:
								save_config_232(rx_232_Buffer);
								LogPrint(LOG_INFO, __FILE__, __FUNCTION__, __LINE__, "write config");
								__set_PRIMASK(1);
								NVIC_SystemReset();
								break;
						case WRITE_CONFIG_ADD:
								add_config_232(rx_232_Buffer);
								LogPrint(LOG_INFO, __FILE__, __FUNCTION__, __LINE__, "write config add");
								break;
						case READ_CONFIG:
								read_config_232();
								LogPrint(LOG_INFO, __FILE__, __FUNCTION__, __LINE__, "read config");
								break;
						case FIND_DEVICE:
								find_device_232();
								LogPrint(LOG_INFO, __FILE__, __FUNCTION__, __LINE__, "find device");
								break;				
						case TOGGLE_MODE:
								work_mode_232(rx_232_Buffer);
								LogPrint(LOG_INFO, __FILE__, __FUNCTION__, __LINE__, "toggle work mode");
								break;
						case UPDATE:
								LogPrint(LOG_INFO, __FILE__, __FUNCTION__, __LINE__, "update");
								updata_232();
								break;
						case REBOOT:
								LogPrint(LOG_INFO, __FILE__, __FUNCTION__, __LINE__, "reboot");
								__set_PRIMASK(1);
								NVIC_SystemReset();
								break;
						case CMD_ERROR:
								goto __exit;
					}
				} else {
					switch (j) {
						case FIND_DEVICE:
								find_device_232();
								LogPrint(LOG_INFO, __FILE__, __FUNCTION__, __LINE__, "find device");
								break;
						case TOGGLE_MODE:
								work_mode_232(rx_232_Buffer);
								LogPrint(LOG_INFO, __FILE__, __FUNCTION__, __LINE__, "toggle work mode");
								break;
						case UPDATE:
								updata_232();
								LogPrint(LOG_INFO, __FILE__, __FUNCTION__, __LINE__, "update");
								break;
						case REBOOT:
								LogPrint(LOG_INFO, __FILE__, __FUNCTION__, __LINE__, "reboot");
								__set_PRIMASK(1);
								NVIC_SystemReset();	
								break;
						case CMD_ERROR:
								goto __exit;
				}
			}
				memset(rx_232_Buffer, 0, strlen(rx_232_Buffer));
			__exit:
				vTaskDelay(500);
		}
}

void USART_232_task_creat()
{
	osThreadDef(USART_task, USART_232_task, osPriorityNormal, 0, configMINIMAL_STACK_SIZE*4);
  osThreadCreate(osThread(USART_task), NULL);
}

/*********************************************END OF FILE**********************/
