/*
 * AppTaskBle.c
 *
 *  Created on: 2022年1月19日
 *      Author: 陈杰
 */
#include "AppTaskBle.h"
const BleAtCmdFunc_t BleAtCmdFunc[] = {
	{AT_Cmd_Test, "AT", at_callbackFunc},
	{AT_GetMac, "AT+MAC?", at_callbackFunc},
	{AT_NameChk, "AT+NAME?", at_callbackFunc},
	{AT_NameSet, "AT+NAME=", at_callbackFunc},
	{AT_AutoConnSet, "AT+AUTOCONN=", at_callbackFunc},
	{AT_LogMsgSet, "AT+LOGMSG=", at_callbackFunc},
	{AT_RoleChk, "AT+ROLE?", at_callbackFunc},
	{AT_RoleSet, "AT+ROLE=", at_callbackFunc},
	{AT_Conn, "AT+CONN=", at_callbackFunc},
	{AT_DisCon, "AT+DISCON", at_callbackFunc},
	{AT_Reset, "AT+RESET", at_callbackFunc}};
static void AtcmdTransmit(sint8 CmdIdx, uint8 *SetValuePtr, uint16 SetValueLen, uint8 *CmdRead, sint8 *retFunc);
static void bleInit(void);
static sint8 bleRoleSetFunc(void);
void BleTask(void *pvParameters)
{
	(void)pvParameters;
	uint8 McuDataSend[10] = {0};
	sint8 QueueRet = -1;
	uint8 AtCmdRead[150] = {0};
	Dio_WriteChannel(DioConf_DioChannel_PTE7_GPIO_OUT_MCU_BT_MOD, STD_OFF);
	bleInit();
	Dio_WriteChannel(DioConf_DioChannel_PTE7_GPIO_OUT_MCU_BT_MOD, STD_ON);
	uint8 bleWorkState = 0;
	sint8 ret = -1;
	QueueDataTrans_Type BleAnsData={0,NULL};
	QueueDataTrans_Type BleAskData={0,NULL};
	uint16 ReadLen = 0;
	uint8 *retptr = NULL;
	uint8 *pSend = NULL;
	uint8 *UartRecvPtr=NULL;
	for (;;)
	{
		switch (bleWorkState)
		{
		case 0: //等待连接或者主动连接
		{
			if (BleSetRoleEnable) //是否更改角色
			{
				if (bleRoleSetFunc() == 0)
				{
					BleSetRoleEnable = 0;
				}
			}
			if (BleCurrentRole == 1)
			{
				if (BleConnectEnable == 1 && BleConnectFlg == 0) //主机蓝牙主动请求连接
				{
					Dio_WriteChannel(DioConf_DioChannel_PTE7_GPIO_OUT_MCU_BT_MOD, STD_OFF);
					AtcmdTransmit(AT_Conn, BleTargetMacAddr, sizeof(BleTargetMacAddr), AtCmdRead, &ret);
					if (ret == 0) //连接成功
					{
						bleWorkState = 1;
						BleConnectEnable = 0;
						BleConnectFlg = 1;
						BleDisconnectFlg = 0;
						xSemaphoreGive(ConnSemaphore);
					}
					else
					{
						BleConnectFlg = 0;
					}
					Dio_WriteChannel(DioConf_DioChannel_PTE7_GPIO_OUT_MCU_BT_MOD, STD_ON);
				}
			}
			UART_Receive_Data(UART_LPUART2, &UartRecvPtr,&ReadLen, 100);
			if (ReadLen>0)//未连接状态下，蓝牙串口处会发送连接状态以及扫描的内容
			{
				memset(AtCmdRead,0x00,sizeof(AtCmdRead));
				memcpy(AtCmdRead, &UartRecvPtr,ReadLen);
				retptr = (uint8 *)strstr((char *)AtCmdRead, (char *)("STA:connect"));
				if (retptr)
				{
					bleWorkState = 1;
					BleConnectEnable = 0;
					BleConnectFlg = 1;
					BleDisconnectFlg = 0;
					xSemaphoreGive(ConnSemaphore);
				}
				if(BleCurrentRole == 0)//如果从机在串口0上收到数据，则证明已连接
				{
					uint8 DataTemp[8] = {0x00};
					DataTemp[0] = 0x01;
					DataTemp[1] = 0x01;
					bleWorkState = 1;
					BleConnectFlg = 1;
					BleDisconnectFlg = 0;
					BleAskData.RealLen = 1;
					BleAskData.DataPtr = DataTemp;
					xQueueSend(Uart2ToCanDataHandle,&BleAskData,0);
				}
			}
			if(UartRecvPtr != NULL)
			{
				free(UartRecvPtr);
			}
			UartRecvPtr = NULL;
			break;
		}
		case 1: //已连接
		{
			if (BleDisconnectEnable == 1 && BleDisconnectFlg == 0)//主从机均可断开连接
			{
				//蓝牙断开指令，Mod拉低，才能发送命令
				/*S32K*/
				Dio_WriteChannel(DioConf_DioChannel_PTE7_GPIO_OUT_MCU_BT_MOD, STD_OFF);

				memset(AtCmdRead, 0x00, sizeof(AtCmdRead));
				AtcmdTransmit(AT_DisCon, NULL, 0, AtCmdRead, &ret);
				if (ret == 0)
				{
					memset(AtCmdRead, 0x00, sizeof(AtCmdRead));
					AtcmdTransmit(AT_Reset, NULL, 0, AtCmdRead, &ret);
					if (ret == 0)
					{
						BleDisconnectFlg = 1;
						BleDisconnectEnable = 0;
						BleConnectFlg = 0;
						/*S32K*/
						bleWorkState = 0;
						Dio_WriteChannel(DioConf_DioChannel_PTE7_GPIO_OUT_MCU_BT_MOD, STD_ON);
					}
				}
				else
				{
					BleDisconnectFlg = 0;
				}
			}
			/*已连接状态下的数据交换在此进行
			UartTramsit;
			*/
			/*S32K144*/
			if (BleCurrentRole == 1)//主机蓝牙在连接状态下的蓝牙串口发送功能，从MCU串口0队列得到，发给串口2
			{
				if(AT_MsgFlag)
				{
					QueueRet = xQueueReceive(McuDataSendHandle,McuDataSend,0);
					UART_Send_Data(UART_LPUART2,McuDataSend,sizeof(McuDataSend),1000);
					AT_MsgFlag = false;
				}
			}
			else if(BleCurrentRole == 0)//从机蓝牙在连接状态下的蓝牙串口发送功能，从CAN队列得到，发给串口2
			{
				if((xQueueReceive(CanToUart2DataHandle,&BleAnsData,0)==pdPASS))
				{
					UART_Send_Data(UART_LPUART2,BleAnsData.DataPtr,BleAnsData.RealLen,1000);
					if(BleAnsData.DataPtr)
					{
						free(BleAnsData.DataPtr);
					}
					BleAnsData.DataPtr = NULL;
				}
			}
			UART_Receive_Data(UART_LPUART2, &UartRecvPtr,&ReadLen, 100);
			if (ReadLen>0)//连接的状态下，蓝牙串口会发送断开状态以及发送的内容
			{
				memset(AtCmdRead,0x00,sizeof(AtCmdRead));
				memcpy(AtCmdRead, UartRecvPtr, ReadLen);
				uint8 *retptr = NULL;
				retptr = (uint8 *)strstr((char *)AtCmdRead, (char *)("STA:disconnec"));
				if(retptr)
				{
					bleWorkState = 0;
					BleDisconnectFlg = 1;
					BleConnectFlg = 0;
					if(BleCurrentRole == 0)//从机断开连接，主动给ebc发送一帧信息
					{
						uint8 DataTemp[8] = {0x00};
						DataTemp[0] = 0x01;
						DataTemp[1] = 0x02;
						BleAskData.RealLen = 1;
						BleAskData.DataPtr = DataTemp;
						xQueueSend(Uart2ToCanDataHandle,&BleAskData,0);
					}
				}
				else
				{
					if(BleCurrentRole == 1)
					{
						BleRecvDataFromUart2 DataSend={0,NULL};
						DataSend.RealLen = ReadLen;
						DataSend.DataPtr = malloc(ReadLen+1);
						memset(DataSend.DataPtr,0x00,ReadLen+1);
						memcpy(DataSend.DataPtr,AtCmdRead,DataSend.RealLen);
						sint8 McuDataRet = -1;
						McuDataRet= xQueueSend(McuDataRecvHandle,&DataSend,1000*2);//增加数据的有效性判定，主机蓝牙从Uart2->Uart0数据的有效性，len>7?
						if(McuDataRet!=pdPASS)
						{
							if(DataSend.DataPtr != NULL)
							{
								free(DataSend.DataPtr);
							}
							DataSend.DataPtr = NULL;
						}
					}
					else if(BleCurrentRole == 0 && ReadLen==10)
					{
						BleAskData.RealLen = ReadLen;
						BleAskData.DataPtr = malloc(ReadLen);
						memset(BleAskData.DataPtr,0x00,BleAskData.RealLen);
						memcpy(BleAskData.DataPtr,AtCmdRead,BleAskData.RealLen);
						if(xQueueSend(Uart2ToCanDataHandle,&BleAskData,1000*5)!=pdPASS)
						{
							if(BleAskData.DataPtr != NULL)
							{
								free(BleAskData.DataPtr);
							}
							BleAskData.DataPtr = NULL;
						}
					}
				}
			}
			if(UartRecvPtr != NULL)
			{
				free(UartRecvPtr);
			}
			UartRecvPtr = NULL;
			break;
		}
		default:
			bleWorkState = 0;
			break;
		}
	}
}
static void AtcmdTransmit(sint8 CmdIdx, uint8 *SetValuePtr, uint16 SetValueLen, uint8 *CmdRead, sint8 *retFunc)
{
	uint8 *UartRecvPtr = NULL;
	uint16 ReadLen = 0;
	uint8 ATCmd_Send[50];
	uint16 ATCmd_SendLen;
	memset(ATCmd_Send, 0x00, sizeof(ATCmd_Send));
	ATCmd_SendLen = mstrlen(BleAtCmdFunc[CmdIdx].str);
	memcpy(ATCmd_Send, BleAtCmdFunc[CmdIdx].str, ATCmd_SendLen);
	if (SetValuePtr != NULL)
	{
		memcpy(&ATCmd_Send[ATCmd_SendLen], SetValuePtr, SetValueLen);
	}
	ATCmd_SendLen = ATCmd_SendLen + SetValueLen;
	/**/
//	memset(RX_Buffer[UART_LPUART2], 0x00, sizeof(RX_Buffer[UART_LPUART2]));
	UART_Query_Data(UART_LPUART2, UART_LPUART2, ATCmd_Send, ATCmd_SendLen, &UartRecvPtr,&ReadLen, 1000);
	memcpy(CmdRead, UartRecvPtr, 50);
	/*
	UartTramsit(ATCmd_Send, ATCmd_SendLen, CmdRead, 1, osWaitForever);
	*/
	*retFunc = BleAtCmdFunc[CmdIdx].cb(ATCmd_Send, CmdRead, CmdIdx);
	if(UartRecvPtr != NULL)
	{
		free(UartRecvPtr);
	}
	UartRecvPtr = NULL;
	return;
}
static void bleInit(void)
{
	uint8 AtCmdRead[50];
	sint8 ret = -1;
	uint8 bleInitStep = 0;
	uint8 BleCurrentName[6];
	uint8 *UartRecvPtr=NULL;
	while (1)
	{
		vTaskDelay(pdMS_TO_TICKS(100));
		switch (bleInitStep)
		{
		case 0: // AT同步
		{
			//UartTramsit(NULL, 0, AtCmdRead, 1, 100);
			uint16 Readlen = 0;
			memset(AtCmdRead, 0x00, sizeof(AtCmdRead));
			AtcmdTransmit(AT_Cmd_Test, NULL, 0, AtCmdRead, &ret);
			if (ret == 0)
			{
				bleInitStep++;
			}
			else
			{
				vTaskDelay(pdMS_TO_TICKS(1000));
				bleInitStep = 0;
			}
			break;
		}
		case 1: //获取Mac地址
		{
			memset(AtCmdRead, 0x00, sizeof(AtCmdRead));
			AtcmdTransmit(AT_GetMac, NULL, 0, AtCmdRead, &ret);
			memcpy(BleMacAddr, &AtCmdRead[4], sizeof(BleMacAddr));
			if (ret == 0)
			{
				bleInitStep++;
			}
			else
			{
				bleInitStep = 0;
			}
			break;
		}
		case 2: //广播名称设置
		{
			uint8 NameChk = 0; //默认不需要设置
			memset(AtCmdRead, 0x00, sizeof(AtCmdRead));
			AtcmdTransmit(AT_NameChk, NULL, 0, AtCmdRead, &ret);
			for (uint8 i = 0; i < 6; i++)
			{
				if (mstrlen((char *)AtCmdRead) != 16)
				{
					NameChk = 1;
					break;
				}
				else
				{
					BleCurrentName[i] = (CharToHex(AtCmdRead[(i * 2) + 4]) << 4) + CharToHex(AtCmdRead[(i * 2 + 1) + 4]);
					if (BleMacAddr[i] != BleCurrentName[i])
					{
						NameChk = 1;
						break;
					}
				}
			}
			if (NameChk)
			{
				uint8 NameTemp[12] = {0};
				for (uint8 i = 0; i < 6; i++)
				{
					NameTemp[(i * 2)] = HexToChar(BleMacAddr[i] >> 4);
					NameTemp[(i * 2) + 1] = HexToChar(BleMacAddr[i] & 0x0F);
				}
				memset(AtCmdRead, 0x00, sizeof(AtCmdRead));
				AtcmdTransmit(AT_NameSet, NameTemp, 12, AtCmdRead, &ret);
			}
			if (ret == 0)
			{
				bleInitStep++;
			}
			else
			{
				bleInitStep = 0;
			}
			break;
		}
		case 3: //关闭自动连接
		{
			uint8 CmdTemp = '0';
			memset(AtCmdRead, 0x00, sizeof(AtCmdRead));
			AtcmdTransmit(AT_AutoConnSet, &CmdTemp, 1, AtCmdRead, &ret);
			if (ret == 0)
			{
				bleInitStep++;
			}
			else
			{
				bleInitStep = 0;
			}
			break;
		}
		case 4: //打开log输出
		{
			uint8 CmdTemp = '1';
			memset(AtCmdRead, 0x00, sizeof(AtCmdRead));
			AtcmdTransmit(AT_LogMsgSet, &CmdTemp, 1, AtCmdRead, &ret);
			if (ret == 0)
			{
				bleInitStep++;
			}
			else
			{
				bleInitStep = 0;
			}
			break;
		}
		case 5: //角色获取
		{
			memset(AtCmdRead, 0x00, sizeof(AtCmdRead));
			AtcmdTransmit(AT_RoleChk, NULL, 0, AtCmdRead, &ret);
			BleCurrentRole = CharToHex(AtCmdRead[4]);
			if (ret == 0 && (BleCurrentRole == 0 || BleCurrentRole == 1))
			{
				bleInitStep++;
			}
			else
			{
				bleInitStep = 0;
			}
			break;
		}
		case 6:
		{
			return;
		}
		default:
			bleInitStep = 0;
			break;
		}
	}
	return;
}
static sint8 bleRoleSetFunc(void)
{
	uint8 AtCmdRead[50];
	sint8 ret = -1;
	uint8 BleRoleSetStep = 0;
	uint16 ReadLen = 0;
	while (1)
	{
		vTaskDelay(pdMS_TO_TICKS(100));
		switch (BleRoleSetStep)
		{
		case 0: // AT同步
		{
			memset(AtCmdRead, 0x00, sizeof(AtCmdRead));
			AtcmdTransmit(AT_Cmd_Test, NULL, 0, AtCmdRead, &ret);
			if (ret == 0)
			{
				BleRoleSetStep++;
			}
			else
			{
				return -1;
			}
			break;
		}
		case 1: //角色检查
		{
			memset(AtCmdRead, 0x00, sizeof(AtCmdRead));
			AtcmdTransmit(AT_RoleChk, NULL, 0, AtCmdRead, &ret);
			BleCurrentRole = CharToHex(AtCmdRead[4]);
			if (ret == 0)
			{
				if (BleCurrentRole == BleSetRole)
				{
					return 0;
				}
				else
				{
					BleRoleSetStep++;
				}
			}
			else
			{
				BleRoleSetStep = 0;
			}
			break;
		}
		case 2: //角色设置
		{
			memset(AtCmdRead, 0x00, sizeof(AtCmdRead));
			uint8 RoleTemp;
			RoleTemp = HexToChar(BleSetRole);
			AtcmdTransmit(AT_RoleSet, &RoleTemp, 1, AtCmdRead, &ret);
			if (ret == 0)
			{
				BleRoleSetStep++;
			}
			else
			{
				BleRoleSetStep = 0;
			}
			break;
		}
		case 3: //蓝牙模块重启
		{
			memset(AtCmdRead, 0x00, sizeof(AtCmdRead));
			AtcmdTransmit(AT_Reset, NULL, 0, AtCmdRead, &ret);
			BleRoleSetStep = 0;
			break;
		}
		default:
			BleRoleSetStep = 0;
			break;
		}
	}
	return 0;
}
sint8 at_callbackFunc(uint8 *PSendStr, uint8 *ptr, BleAtCmd CmdIdx)
{
	uint16 pReadLen = 0;
	sint8 returnvalue = -1;
	uint8 *retptr = NULL;
	switch (CmdIdx)
	{
	case AT_Cmd_Test:
	{
		pReadLen = ATstrdel((char *)ptr);
		retptr = (uint8 *)strstr((char *)ptr, (char *)("OK"));
		if (retptr && strlen((char *)ptr) < 5)
		{
			returnvalue = 0;
		}
		else
		{
			returnvalue = -1;
		}
		break;
	}
	case AT_GetMac:
	{
		retptr = (uint8 *)strstr((char *)ptr, (char *)("OK"));
		if (retptr && strlen((char *)ptr) > 5)
		{
			returnvalue = 0;
		}
		else
		{
			returnvalue = -1;
		}
		break;
	}
	case AT_NameChk:
	{
		pReadLen = ATstrdel((char *)ptr);
		retptr = (uint8 *)strstr((char *)ptr, (char *)("OK"));
		if (retptr && strlen((char *)ptr) > 5)
		{
			returnvalue = 0;
		}
		else
		{
			returnvalue = -1;
		}
		break;
	}
	case AT_Conn:
	{
		pReadLen = ATstrdel((char *)ptr);
//		retptr = (uint8 *)strstr((char *)ptr, (char *)("OK"));
//		if (retptr)
//		{
//			returnvalue = 0;
//		}
		retptr = (uint8 *)strstr((char *)ptr, (char *)("ERR=-14"));//利用最大连接数错误判断连接成功
		if(retptr)
		{
			returnvalue = 0;
		}
		break;
	}
	default:
	{
		pReadLen = ATstrdel((char *)ptr);
		retptr = (uint8 *)strstr((char *)ptr, (char *)("OK"));
		if (retptr)
		{
			returnvalue = 0;
		}
		else
		{
			returnvalue = -1;
		}
		break;
	}
	}
	return returnvalue;
}
