/*
 * AppTaskBle.c
 *
 *  Created on: 2022
 *      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},
	{AT_QuitCSend, "+++", at_callbackFunc}};
static void AtcmdTransmit(sint8 CmdIdx, uint8 *SetValuePtr, uint16 SetValueLen, uint8 *CmdRead, sint8 *retFunc);
static void bleInit(void);
static sint8 bleRoleSetFunc(uint8 SET_ROLE);
static uint8 bleDisconnect(void);
static void BLEStaMan(void);
static void BLEConnectMan(uint8* AtCmdRead, uint16* ReadLen, BleState BleStateFlg);

static uint8 bleSendFunc(uint8 *SendDataPtr, uint16 SendDataLen);
static void bleDataDecode(uint8 *dataIn,uint16 dataLen);
void BleTask(void *pvParameters)
{
	(void)pvParameters;
	uint8 AtCmdRead[150] = {0};
	BleStateFlg = NoConnect;
    Dio_WriteChannel(DioConf_DioChannel_PTE9_GPIO_OUT_MCU_BT_POW_EN,STD_ON);
	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);
	uint16 ReadLen = 0;
	for (;;)
	{
		BLEStaMan();
		BLEConnectMan(AtCmdRead, &ReadLen, BleStateFlg);
	}
}
static void AtcmdTransmit(sint8 CmdIdx, uint8 *SetValuePtr, uint16 SetValueLen, uint8 *CmdRead, sint8 *retFunc)
{
	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;
	UART_Query_Data(UART_LPUART2, UART_LPUART2, ATCmd_Send, ATCmd_SendLen, CmdRead,&ReadLen, 1000);

	*retFunc = BleAtCmdFunc[CmdIdx].cb(ATCmd_Send, CmdRead, CmdIdx);
	return;
}
static void bleInit(void)
{
	uint8 AtCmdRead[50];
	sint8 ret = -1;
	uint8 bleInitStep = 0;
	uint8 BleCurrentName[6];
	uint16 Readlen = 0;
	/* 设置为从机 */
	bleRoleSetFunc(0);
	while (1)
	{
		vTaskDelay(pdMS_TO_TICKS(100));
		switch (bleInitStep)
		{
			case 0: // AT同步
			{
				AtcmdTransmit(AT_Cmd_Test, NULL, 0, AtCmdRead, &ret);
				if (ret == 0)
				{
					bleInitStep++;
				}
				else
				{
					vTaskDelay(pdMS_TO_TICKS(100));
					UART_Reset(UART_LPUART2);
				}
				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
				{
					UART_Reset(UART_LPUART2);
				}
				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
				{
					UART_Reset(UART_LPUART2);
				}
				break;
			}
			case 3:
			{
				return;
			}
			default:
				bleInitStep = 0;
				break;
			}
	}
	return;
}
/* 0-从机设置 1-主机设置 */
static sint8 bleRoleSetFunc(uint8 SET_ROLE)
{
	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
				{
					vTaskDelay(pdMS_TO_TICKS(100));
					UART_Reset(UART_LPUART2);
				}
				break;
			}
			case 1: //角色设置
			{
				memset(AtCmdRead, 0x00, sizeof(AtCmdRead));
				uint8 roleMode[1] = {0};
				if(1 == SET_ROLE)
				{
					roleMode[0] = '1';
				}
				else
				{
					roleMode[0] = '0';
				}
				memset(AtCmdRead, 0x00, sizeof(AtCmdRead));
				AtcmdTransmit(AT_RoleSet, roleMode, 1, AtCmdRead, &ret);
				if (ret == 0)
				{
					BleRoleSetStep++;
				}
				else
				{
					UART_Reset(UART_LPUART2);
					BleRoleSetStep = 0;
				}
				break;
			}
			case 3: //蓝牙模块重启
			{
				memset(AtCmdRead, 0x00, sizeof(AtCmdRead));
				AtcmdTransmit(AT_Reset, NULL, 0, AtCmdRead, &ret);
				break;
			}
			default:
				return 0;;
				break;
		}
	}
	return 0;
}
sint8 at_callbackFunc(uint8 *PSendStr, uint8 *ptr, BleAtCmd CmdIdx)
{
	uint16 pReadLen = 0;
	sint8 returnvalue = -1;
	uint8 *retptr = NULL;
	if(NULL != strstr((char *)ptr, (char *)("STA:connect")))
	{
		/* 防止蓝牙初始化时,被主机连接，设置标志位 */
		BleStateFlg = Connected;
	}
	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 *)("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;
}

static uint8 bleSendFunc(uint8 *SendDataPtr, uint16 SendDataLen)
{
	return UART_Send_Data(UART_LPUART2, (uint8 *)SendDataPtr, SendDataLen, 100);
}
/**************************解码部分***********************************/
static void bleDataDecode(uint8 *dataIn,uint16 dataLen)
{
	(void)dataLen;
	uint8 cmd = 0;
	uint8 sendBuffer[255];
	uint16 dataOutLen = 0;
	static uint16 lockOrUnlockIng = 0; /* 目前等待解锁或者加锁反馈 0 无 LOCK_M 加锁 UNLOCK_M 解锁 */
	static uint32 awaitTick = 0;
	uint16 frameLen = 0;
	for(uint16 i = 0; i < dataLen - 23; i++)
	{
		if(0X68 == dataIn[i] && 0X23 == dataIn[i + 1] && 0X24 == dataIn[i + 2])
		{
			frameLen = dataIn[i + 3] + (dataIn[i + 4] << 8);
			if((i + frameLen <= dataLen) && 0X68 == dataIn[frameLen - 1])
			{
				cmd  = dataIn[i + 5];
				EffectiveDataFed = 1;
				break;
			}

			else
			{
				cmd = 0XFF;
			}

		}
	}
	switch(cmd)
	{
		case LOCK_M:
		{
			LockSta = 1;
			break;
		}
		case UNLOCK_M:
		{
			UnlockSta = 1;
			break;
		}
		case GETINFO_M:
		{
			dataOutLen = DecodeSlaveBuffer(sendBuffer, sizeof(sendBuffer), GETINFO_S);
			bleSendFunc(sendBuffer,dataOutLen);
			break;
		}
		case HEARTBEAT_M:
		{
			heartTickLost_B = 0;
			break;
		}
		default:break;
	}
	if((0 != lockOrUnlockIng) &&
			((xTaskGetTickCount() - awaitTick >= pdMS_TO_TICKS(20000)) ||
			((LOCK_S == lockOrUnlockIng && 0 == SolValActuSt) ||
			(UNLOCK_S == lockOrUnlockIng && 1 == SolValActuSt))))
	{
		dataOutLen = DecodeSlaveBuffer(sendBuffer, sizeof(sendBuffer), lockOrUnlockIng);
		bleSendFunc(sendBuffer,dataOutLen);
		if(LOCK_S == lockOrUnlockIng)
			UnlockSta = 0;
		else if(UNLOCK_S == lockOrUnlockIng)
			LockSta = 0;
		else {}
		lockOrUnlockIng = 0;
	}
}

static uint8 bleDisconnect(void)
{
	uint8 AtCmdRead[50];
	sint8 ret = -1;
	uint8 BleRoleSetStep = 0;
	//蓝牙断开指令，Mod拉低，才能发送命令
	/*S32K*/
	Dio_WriteChannel(DioConf_DioChannel_PTE7_GPIO_OUT_MCU_BT_MOD, STD_OFF);
	uint32 clickCount = xTaskGetTickCount();
	EffectiveDataFed = 0;
	while (1)
	{
		vTaskDelay(pdMS_TO_TICKS(100));
		if(xTaskGetTickCount() - clickCount >= pdMS_TO_TICKS(5000))
		{
			return -1;
		}
		switch (BleRoleSetStep)
		{
			case 0: // AT同步
			{
				UART_Reset(UART_LPUART2);
				memset(AtCmdRead, 0x00, sizeof(AtCmdRead));
				AtcmdTransmit(AT_Cmd_Test, NULL, 0, AtCmdRead, &ret);
				if (ret == 0)
				{
					BleRoleSetStep++;
				}
				else
				{
					vTaskDelay(pdMS_TO_TICKS(100));
				}
				break;
			}
			case 1: //断开连接
			{
				memset(AtCmdRead, 0x00, sizeof(AtCmdRead));
				AtcmdTransmit(AT_DisCon, NULL, 0, AtCmdRead, &ret);
				if (ret == 0)
				{
					BleRoleSetStep++;
				}
				else
				{
					UART_Reset(UART_LPUART2);
					BleRoleSetStep = 0;
				}
				break;
			}
			case 2: //蓝牙模块重启
			{
				memset(AtCmdRead, 0x00, sizeof(AtCmdRead));
				AtcmdTransmit(AT_Reset, NULL, 0, AtCmdRead, &ret);
				/*S32K*/
				Dio_WriteChannel(DioConf_DioChannel_PTE7_GPIO_OUT_MCU_BT_MOD, STD_ON);
				return 0;
				break;
			}
			default:
				return 0;
				break;
		}
	}
	return 0;
}

static void BLEStaMan(void)
{
	if(1 == BlePwrControl && Shutdown != BleStateFlg) /* 关机 */
	{
		bleDisconnect();
		Dio_WriteChannel(DioConf_DioChannel_PTE9_GPIO_OUT_MCU_BT_POW_EN,STD_OFF);
		BleStateFlg = Shutdown;
		//
	}
	else if(2 == BlePwrControl && Shutdown == BleStateFlg) /* 开机 */
	{
		Dio_WriteChannel(DioConf_DioChannel_PTE7_GPIO_OUT_MCU_BT_MOD, STD_ON);
		bleInit();
		BleStateFlg = NoConnect;
	}
	if(1 == BleConnectControl && 1 == BleStateFlg) //断开连接
	{
		if(0 == bleDisconnect())
		{
			BleStateFlg = NoConnect;
		}
	}
}

static void BLEConnectMan(uint8* AtCmdRead, uint16* pReadLen, BleState BleStateFlg)
{
	switch (BleStateFlg)
	{
		case NoConnect: //等待连接或者主动连接
		{
			UART_Receive_Data(UART_LPUART2, (uint8 *)AtCmdRead, pReadLen, 100);
			if (*pReadLen > 0)//未连接状态下，蓝牙串口处会发送连接状态以及扫描的内容
			{
				if (0 != strstr((char *)AtCmdRead, (char *)("STA:connect")))
				{
					BleStateFlg = Connected;  /* 已连接 */
				}
			}
			break;
		}
		case Connected: /* 已连接 */
		{
			if (2 == BleConnectControl)//主从机均可断开连接
			{
				bleDisconnect();
				BleStateFlg = NoConnect; /* 已经断开连接 */
			}
			/*
			 * 已连接状态下的数据交换在此进行
			*/
			UART_Receive_Data(UART_LPUART2, AtCmdRead,pReadLen, 100);
			if (*pReadLen > 0)//连接的状态下，蓝牙串口会发送断开状态以及发送的内容
			{
				if((uint8 *)strstr((char *)AtCmdRead, (char *)("STA:disconnec")))
				{
					BleStateFlg = NoConnect;
				}
				else
				{
					bleDataDecode(AtCmdRead,*pReadLen);
				}

			}
			/* 心跳报文发送 */
			static uint64 tickcount = 0;
			if(xTaskGetTickCount() - tickcount > pdMS_TO_TICKS(2000))
			{
				tickcount = xTaskGetTickCount();
				uint16 dataOutLen = 0;
				uint8 dataOutBuffer[128] = {0};
				/* 组包 */
				dataOutLen = DecodeSlaveBuffer(dataOutBuffer, sizeof(dataOutBuffer),  HEARTBEAT_S);
				/* 数据发送 */
				bleSendFunc(dataOutBuffer,dataOutLen);
				heartTickLost_B++;
			}
			if(heartTickLost_B > MAX_LOSTHEART)
			{
				if(0 == bleDisconnect())
				{
					BleStateFlg = NoConnect;
					heartTickLost_B = 0;
				}
			}

			break;
		}
		case Shutdown:
		{
			break;
		}
		default:
		{
			BleStateFlg = 0;
			break;
		}
	}
}
