#include "CatOneTask.h"
#include "Public.h"
#include "DebugCmd.h"

static rt_sem_t CatOneRev_Sem = RT_NULL;
static rt_sem_t CatOneIRQ_Sem = RT_NULL;
static rt_sem_t EthIRQ_Sem = RT_NULL;
static rt_thread_t Cat1Rev_Thread = RT_NULL;

static uint8_t CAT1DispEn = false;
static CatOne_t CatOne;

static char CatOneEthRxBuff[CAT_ONE_REV_LEN_MAX];
static uint16_t CatOneEthRxLen;

static uint8_t CatOneEthTxBuff[CAT_ONE_REV_LEN_MAX];
static uint16_t CatOneEthTxLen;

static uint8_t Payload[CAT_ONE_REV_LEN_MAX];
static char CommUnitSendASCII[CAT_ONE_REV_LEN_MAX * 2];
	
static uint8_t EthRevTimeOutCnt;

static uint16_t CatSendErrCnt = 0;

#define	CAT1_DBG_LOG(...)									{ if(CAT1DispEn) Debug_Printf(__VA_ARGS__);}
//#define	CAT1_DBG_ARRAY(ARRAY, SIZE)			{ if(CAT1DispEn) {DBG_ARRAY(ARRAY,SIZE)}}

#define	CATONE_RESET_DELAY_TIME_MAX				(5 * 60 * 1000)

const char *CatOneATCmdStr[16] = {
	"NULL",
	"AT\r\n",						//开机检测
	"ATE0\r\n",					//关回显
	"AT+CPIN?\r\n",			//识卡
//	"AT+CIMI\r\n",			//IMEI
	"AT+CGSN=1\r\n",
	"AT+LCCID\r\n",			//读卡号			
	"AT+CEREG?\r\n",		//查询注册状态
	"AT+CGPADDR=1\r\n",	//查询IP地址
	"AT+CSQ\r\n",				//查询信号强度
	"AT+LDNSGIP=gxjt.cui635.cn\r\n",
	"AT+LBS=0\r\n",			//获取基站定位信息
	"AT+LIPOPEN=",			//设置TCP服务器地址和端口，AT+LIPOPEN="TCP","114.55.52.96",6803
	"AT+LIPSEND=",			//发送数据,	AT+LIPSEND=0,1,20,"31313131313131323232323232"
	"AT+LIPCLOSE=0\r\n",//断开连接
	"AT+LBSPARA=http://locator-aep.xiot.senthink.com:80/locator/v0.1/locate,B84E427D95B1DF4A3F49B18DDF714C72\r\n",
	"AT+CCLK?\r\n",	//获取时间
};

void Cat1DBGOnOff(bool OnOff)
{
	CAT1DispEn = OnOff;
	if(OnOff)
		Debug_Printf("\r\nCat1 Display Enable!\r\n\r\n");
	else
		Debug_Printf("\r\nCat1 Display Disable!\r\n\r\n");
}

const CatOneATCMD_m CatOneModeSetCmdArray[] = {
	CAT_ONE_AT_NULL, 
	CAT_ONE_AT, 
	CAT_ONE_ATE0, 
	//CAT_ONE_LBSPARA,
	CAT_ONE_LCCID,
	CAT_ONE_IMEI,
	CAT_ONE_CPIN, 
	CAT_ONE_CEREG, 
	CAT_ONE_CSQ,
	//CAT_ONE_LDNSGIP,
	//CAT_ONE_LBS,
	CAT_ONE_CCLK,
	CAT_ONE_AT_CMD_END
};

//CatOneRetStatus_m CatOneSend(uint8_t *sData, uint16_t sLen)
//{
//	rt_err_t result;
//	
//	if(CatOne.Status != CAT_ONE_IDEL && CatOne.Status != CAT_ONE_WAIT_SEND)
//		return CAT_ONE_RET_ERR;
//	
//	//CatOne.Status = CAT_ONE_RESET;
//	result = rt_mq_send(CatOneRev_MQ, sData, sLen);
//  if(result != RT_EOK) {
//		CAT1_DBG_LOG("CatOne MQ Send ERR...\r\n");
//		return CAT_ONE_RET_ERR;
//	}
//	CAT1_DBG_LOG("CatOne Send Message: \r\n", sData);
//	return CAT_ONE_RET_OK;
//}

void CatOneStop(void)
{
	CatOne.Status = CAT_ONE_OFF;
}

void CatOneGetLocationInfo(int *Longitude, int *Latitude)
{
	if(CatOne.LBSFlag) {
		*Longitude = CatOne.Longitude;
		*Latitude = CatOne.Latitude;
	}
	else {
		*Longitude = 0;
		*Latitude = 0;
	}
}

void CatOneGetIMEIAndSIM(char *Imei, char *Sim)
{
	memcpy(Imei, CatOne.IMEI, 15);
	memcpy(Sim, CatOne.SIM, 20);
}

//返回true-busy, false-Idle
bool CatOneGetStatus(void)
{
	if(CatOne.Status == CAT_ONE_IDEL)
		return false;
	return true;
}

void CatOneReset(void)
{
	CatOne.Status = CAT_ONE_RESET;
}

void CatTimeSync(char *Data) 
{
	struct tm sTimet;
	time_t sTime;
  char *p;
	
	p = strchr(Data, '\"');
	if(p == NULL)
		return;
	
	int ret = sscanf(p, "\"%d/%d/%d,%d:%d:%d+", 
										&sTimet.tm_year, &sTimet.tm_mon, &sTimet.tm_mday,
										&sTimet.tm_hour, &sTimet.tm_min, & sTimet.tm_sec);
	if(ret != 6) {
		int ret = sscanf(p, "\"%d/%d/%d,%d:%d:%d-", 
										&sTimet.tm_year, &sTimet.tm_mon, &sTimet.tm_mday,
										&sTimet.tm_hour, &sTimet.tm_min, & sTimet.tm_sec);
		if(ret != 6)
			return;
	}
	
	sTimet.tm_isdst = 0;
	if(sTimet.tm_year < 24 || sTimet.tm_year > 50)
		return;
	sTimet.tm_year += 100;
	
	if(sTimet.tm_mon > 12 || sTimet.tm_mon == 0)
		return;
	sTimet.tm_mon--;
	
	sTime = mktime(&sTimet);
	TimeSync(sTime);
	CAT1_DBG_LOG("Set Time:");
	TimeShow(TimeTs());
}

void CatOneAtCmdAnalyze(char *RxBuff)
{
	char *p;
	int ret;
	
	CatOne.ATCmdRet = CAT_ONE_RET_OK;
	CAT1_DBG_LOG(RxBuff);
	
	switch(CatOne.AtCmd) {
		case CAT_ONE_AT:
		case CAT_ONE_ATE0:
		case CAT_ONE_LIPSEND:
		case CAT_ONE_LDNSGIP:
		case CAT_ONE_LBSPARA:
			if(strstr(RxBuff, "OK") == NULL) {
				CatOne.ATCmdRet = CAT_ONE_RET_ERR;
			}
			break;
			
		case CAT_ONE_IMEI:
			if(strstr(RxBuff, "OK") == NULL) {
				CatOne.ATCmdRet = CAT_ONE_RET_ERR;
			}
			p = strstr(RxBuff, "+CGSN");
			if(p == NULL) {
				CatOne.ATCmdRet = CAT_ONE_RET_ERR;
			}
			p = strchr(p, '"');
			if(p != NULL) {
				memcpy(CatOne.IMEI, p+1, 15);
			}
			else {
				memset(CatOne.IMEI, 0, 15);
			}
//			ret = sscanf(p, "+CGSN: \"%s\"\r\n", CatOne.IMEI);
//			if(ret != 1) {
//				memset(CatOne.IMEI, 0, 15);
//			}
			CatOne.IMEI[15] = 0;
			break;
		
			case CAT_ONE_CCLK:
			if(strstr(RxBuff, "+CCLK") != NULL) {
				CatTimeSync(RxBuff);
			}
			break;
			
		case CAT_ONE_LCCID:
			if(strstr(RxBuff, "OK") == NULL) {
				CatOne.ATCmdRet = CAT_ONE_RET_ERR;
			}
			p = strstr(RxBuff, "+LCCID");
			if(p == NULL) {
				CatOne.ATCmdRet = CAT_ONE_RET_ERR;
			}
			memset(CatOne.SIM, 0, 32);
			ret = sscanf(p, "+LCCID: %s\r\n", CatOne.SIM);
			if(ret != 1) {
				memset(CatOne.SIM, 0, 32);
			}
			break;
			
		case CAT_ONE_LBS:
			p = strstr(RxBuff, "+LBS");
			if(p != NULL) {
				double Longitude, Latitude;
				int ret = sscanf(p, "+LBS: %lf,%lf\r\n", &Longitude, &Latitude);
				if(ret == 2) {
					CatOne.LBSFlag = true;
					CatOne.Longitude = Longitude * 100000;
					CatOne.Latitude = Latitude * 100000;
				}
			}
			break;

		case CAT_ONE_LIPOPEN:
			if(strstr(RxBuff, "OK") != NULL) {
				CatOne.Status = CatOne.NextStatus;
				CatOne.CatOne1mSDelayCnt = 10 * 1000;
				return;
			}
			else {
				if(strstr(RxBuff, "LIPOPEN: 0,1") != NULL) {
					CAT1_DBG_LOG("Cat1 successfully to connect to the server.\r\n\r\n");
					CatOne.TcpConnFlag = true;
					CatOne.Status = CatOne.NextStatus;
					rt_sem_release(CatOneRev_Sem);
				}
				else if(strstr(RxBuff, "LIPOPEN: 0,0") != NULL) {
					CAT1_DBG_LOG("Cat1 failed to connect to the server.\r\n\r\n");
					CatOne.TcpConnFlag = false;
					CatOne.Status = CAT_ONE_OFF;
				}
				return;
			}
			
		case CAT_ONE_CPIN:
			if(strstr(RxBuff, "READY") == NULL) {
				CatOne.ATCmdRet = CAT_ONE_RET_ERR;
			}
			break;
		
		case CAT_ONE_CEREG:
			if(strstr(RxBuff, "CEREG: 0,1") == NULL) {
				CatOne.CatOne1mSDelayCnt = 3000;
				CatOne.ATCmdRet = CAT_ONE_RET_ERR;
			}
			break;
		
		case CAT_ONE_CGPADDR:
			if(strstr(RxBuff, "+CGPADDR") == NULL) {
				CatOne.ATCmdRet = CAT_ONE_RET_ERR;
			}
			break;
		
		case CAT_ONE_CSQ:
			if(strstr(RxBuff, "+CSQ") == NULL) {
				CatOne.ATCmdRet = CAT_ONE_RET_ERR;
			}
			break;
		
		case CAT_ONE_LTPCLOSE:
			if(strstr(RxBuff, "CLOSE OK") != NULL) {
				break;
			}
			else if(strstr(RxBuff, "ERROR") != NULL) {
				break;
			}
			else if(strstr(RxBuff, "OK") != NULL){
				break;
			}
			CatOne.ATCmdRet = CAT_ONE_RET_ERR;
			break;
		case CAT_ONE_AT_NULL: 
			p = strstr(RxBuff, "+LIPURC");
			if(p != NULL) {
				char rData[120];
				uint8_t  hData[60];
				int rLen, hLen, ret;
				
				if(strstr(p, "+LIPURC: 0,0") != NULL) {
					CAT1_DBG_LOG("TCP connection disconnected.\r\n\r\n");
					CatOne.TcpConnFlag = false;
					CatOne.Status = CAT_ONE_OFF;
					return;
				}
				
				ret = sscanf(p, "+LIPURC: 0,1,%d,%s\r\n", &rLen, rData);
				if(ret == 2) {
					if(rLen < 24)
						return;
					memset(hData, 0x00, 60);
					hLen = AsciiToHex(rData, hData, rLen);
					CatSendErrCnt = 0;
					CatOne.GateWay->SvrRevCallBack(CatOne.GateWay, hData, hLen);
				}
				else {
					return;
				}
				//CatOne.Status = CAT_ONE_CLOSE_TCP;
				rt_sem_release(CatOneRev_Sem);//接收任务
				return;
			}
		default:
			CatOne.ATCmdRet = CAT_ONE_RET_ERR;
			
	}
	if(CatOne.ATCmdRet == CAT_ONE_RET_OK) {
		CatOne.Status = CatOne.NextStatus;
		if(CatOne.AtCmd == CAT_ONE_LIPSEND)
			CatOne.CatOne1mSDelayCnt = 5 * 1000;
		else
			CatOne.CatOne1mSDelayCnt = 10;
		CatOne.AtCmd = CAT_ONE_AT_NULL;
		rt_sem_release(CatOneRev_Sem);
	}
}

void CatOneAtCmdSend(CatOneATCMD_m Cmd, uint32_t Dly, CatOneStatus_m NextStatus)
{
	CatOne.AtCmd = Cmd;
	if(CatOne.AtCmd == CAT_ONE_LIPSEND) {
		HexToAscii(CatOneEthTxBuff, CommUnitSendASCII, CatOneEthTxLen);
		sprintf(CatOne.CatOneSendBuff,"AT+LIPSEND=0,1,%d,\"%s\"\r\n",CatOneEthTxLen * 2, CommUnitSendASCII);
		CatOne.GateWay->BatteryReadDlyCnt = 30;
	}
	else if(CatOne.AtCmd == CAT_ONE_LIPOPEN) {
		sprintf(CatOne.CatOneSendBuff,"AT+LIPOPEN=\"TCP\",\"%d.%d.%d.%d\",%d\r\n", 
						CatOne.GateWay->ConfigPara.SvrAddr[0], 
						CatOne.GateWay->ConfigPara.SvrAddr[1], 
						CatOne.GateWay->ConfigPara.SvrAddr[2],
						CatOne.GateWay->ConfigPara.SvrAddr[3], 
						CatOne.GateWay->ConfigPara.SvrPort);
	}
	else {
		strcpy(CatOne.CatOneSendBuff, CatOneATCmdStr[CatOne.AtCmd]);
	}
	CAT1_DBG_LOG(CatOne.CatOneSendBuff);
	EthRevTimeOutCnt = 0;
	EthOrCat1UartSend((uint8_t *)CatOne.CatOneSendBuff, strlen(CatOne.CatOneSendBuff));
	CatOne.CatOne1mSDelayCnt = Dly;
	CatOne.Status = CAT_ONE_WAIT_REV;
	CatOne.NextStatus = NextStatus;
}

int GateWayRegister(uint8_t *TxBuff)
{
	uint16_t UnitCommCnt = 0;
	uint8_t *p = &TxBuff[0];
	uint16_t len = 5;
	
	if(CatOne.GateWay->ConfigPara.Rs485Ch1.CommUnitEnable == true && CatOne.GateWay->ConfigPara.Rs485Ch1.Enable == true) {
		UnitCommCnt++;
		memcpy(&p[len], CatOne.GateWay->ConfigPara.Rs485Ch1.CUData.Para.Mac[0], 6);
		len += 6;
	}
	if(CatOne.GateWay->ConfigPara.Rs485Ch2.CommUnitEnable == true && CatOne.GateWay->ConfigPara.Rs485Ch2.Enable == true) {
		UnitCommCnt++;
		memcpy(&p[len], CatOne.GateWay->ConfigPara.Rs485Ch2.CUData.Para.Mac[0], 6);
		len += 6;
	}
	for(int i = 0; i < COMMUNIT_NUM_MAX; i++) {
		if(CatOne.GateWay->ConfigPara.CommUnitArray[i].RegFlag == true) {
			for(int j = 0; j < CatOne.GateWay->ConfigPara.CommUnitArray[i].SensorN; j++)
			{
				memcpy(&p[len], CatOne.GateWay->ConfigPara.CommUnitArray[i].Mac[j], 6);
				len += 6;
				UnitCommCnt++;
			}
		}
	}
	TxBuff[0] = (len - 3) & 0x00ff;
	TxBuff[1] = ((len - 3) >> 8) & 0x00ff;
	TxBuff[2] = NET_COMM_CMD_REG;
	TxBuff[3] = UnitCommCnt & 0x00ff;
	TxBuff[4] = (UnitCommCnt >> 8) & 0x00ff;
	return len;
}

void CatOneLoopHandler(void)
{
	static rt_err_t result;
	uint16_t ret;
	static uint8_t Cat1RevErrCnt = 0;
	
	switch(CatOne.Status){
		case CAT_ONE_IDEL:
			rt_thread_delay(1);
			if(CatOne.ResetDelayCnt > 0) {
				CatOne.ResetDelayCnt--;
			}
			else {
				CatOne.Status = CAT_ONE_RESET;
			}
			break;
		
		case CAT_ONE_WAIT_REV:
			result = rt_sem_take(CatOneRev_Sem, CatOne.CatOne1mSDelayCnt);
			if(result != RT_EOK) {
				if(CatOne.AtCmdResendCnt > 0) {
					CatOne.AtCmdResendCnt--;
					CatOneAtCmdSend(CatOne.AtCmd, 2000, CatOne.NextStatus);
					CAT1_DBG_LOG("Cat1 Ret TimeOut, ReSend(%d)...\r\n", CatOne.AtCmdResendCnt);
				}
				else {		//3次错误，关机
					CAT1_DBG_LOG("Cat1 error, Close!\r\n");
					if(CatOne.AtCmd == CAT_ONE_LIPSEND)
						CatOne.Status = CAT_ONE_CLOSE_TCP;
					else
						CatOne.Status = CAT_ONE_OFF;
				}
			}
			break;
				
		case CAT_ONE_INIT:
			CatOne.AtCmdIdx++;
			if(CatOneModeSetCmdArray[CatOne.AtCmdIdx] != CAT_ONE_AT_CMD_END) {
				if(CatOneModeSetCmdArray[CatOne.AtCmdIdx] == CAT_ONE_CEREG)
					CatOne.AtCmdResendCnt = 30;
				else
					CatOne.AtCmdResendCnt = 3;
				CatOneAtCmdSend(CatOneModeSetCmdArray[CatOne.AtCmdIdx], 1000, CAT_ONE_INIT);
			}
			else {
				CatOne.Status = CAT_ONE_TCP_CONN;
				CatOne.CatOne1mSDelayCnt = 0;
				CatOne.AtCmdIdx = 0;
				CatOne.AtCmd = CAT_ONE_AT_NULL;
			}
			break;

		case CAT_ONE_TCP_CONN:
			CatOneAtCmdSend(CAT_ONE_LIPOPEN, 2000, CAT_ONE_WAIT_CONN);
			break;
		
		case CAT_ONE_WAIT_CONN:
			if(CatOne.TcpConnFlag) {
				if(CatOne.GateWay->SvrRegFlag == false)
					CatOne.Status = CAT_ONE_REG_SVR;
				else 
					CatOne.Status = CAT_ONE_WAIT_SEND;
			}
			break;
		
		case CAT_ONE_REG_SVR:		//注册服务器	
			ret = GateWayRegister(CatOneEthTxBuff);
			rt_mq_send(CatOne.GateWay->NetSendData_MQ, CatOneEthTxBuff, ret);
			CatOne.Status = CAT_ONE_WAIT_SEND;
			break;
		
		case CAT_ONE_WAIT_SEND:
			result = rt_mq_recv(CatOne.GateWay->NetSendData_MQ, Payload, CAT_ONE_REV_LEN_MAX, 1000);
			if(result == RT_EOK) {
				CatOneEthTxLen = NetCommOrgData(CatOne.GateWay, Payload, CatOneEthTxBuff);
				CatOne.Status = CAT_ONE_SEND_DATA;
			}
			else {
				if(CatOne.Status == CAT_ONE_RESET || CatOne.Status == CAT_ONE_OFF)		//外部命令执行，状态改变
					return;
				if(!CatOne.TcpConnFlag) {
					CatOne.Status = CAT_ONE_OFF;
				}
				else {
					CatSendErrCnt++;
					if(CatSendErrCnt > CAT1_ERR_RESET_DLY_MAX) {
						CatOne.Status = CAT_ONE_RESET;
						CAT1_DBG_LOG("Cat1 has no data for a long time, Reset!\r\n");
						CatSendErrCnt = 0;
						break;
					}
					CatOne.Status = CAT_ONE_WAIT_SEND;
				}
			}
			break;
		
		case CAT_ONE_SEND_DATA: 
			CatOne.AtCmdResendCnt = 3;
			Cat1RevErrCnt++;
			if(Cat1RevErrCnt > 10) {
				CatOne.Status = CAT_ONE_RESET;
				CAT1_DBG_LOG("Cat1 has no receive data for a long time, Reset!\r\n");
				Cat1RevErrCnt = 0;
				break;
			}
			CatOneAtCmdSend(CAT_ONE_LIPSEND, 5000, CAT_ONE_REV_DATA);
			break;
			
		case CAT_ONE_REV_DATA:
			result = rt_sem_take(CatOneRev_Sem, CatOne.CatOne1mSDelayCnt);
			if(result != RT_EOK) {
				if(CatOne.TcpConnFlag == false) {
					CAT1_DBG_LOG("Cat1 Rec Server Data Timeout!\r\n");
					break;
				}
			}
			else {
				Cat1RevErrCnt = 0;
			}
			if(CatOne.GateWay->SvrRegFlag == false)		//设备没注册，关闭4G，等待下一次重新注册
				CatOne.Status = CAT_ONE_OFF;
			else
				CatOne.Status = CAT_ONE_WAIT_SEND;
			break;

		case CAT_ONE_CLOSE_TCP:
			CatOne.AtCmdResendCnt = 3;
			CatOneAtCmdSend(CAT_ONE_LTPCLOSE, 1000, CAT_ONE_OFF);
			break;
		
		case CAT_ONE_OFF:
			//CAT1_POW_OFF();
			CAT1_RESET_SET();
			CAT1_PWR_KEY_CLR();
			rt_thread_delay(3000);
			CAT1_PWR_KEY_SET();
			CatSendErrCnt = 0;
			CAT1_DBG_LOG("Cat1 Power Off!\r\n");
			CatOne.Status = CAT_ONE_IDEL;
			CatOne.ResetDelayCnt = CATONE_RESET_DELAY_TIME_MAX;
			break;
			
		case CAT_ONE_RESET:
			CatSendErrCnt = 0;
			CAT1_DBG_LOG("Cat1 Reset!\r\n");
			CAT1_RESET_CLR();
			CAT1_PWR_KEY_SET();
			//CAT1_POW_ON();
			rt_thread_delay(50);
			CAT1_RESET_SET();
			CAT1_PWR_KEY_CLR();
			rt_thread_delay(1000);
			CAT1_PWR_KEY_SET();
			CatOne.Status = CAT_ONE_INIT;
			CatOne.AtCmdIdx = 0;
			rt_thread_delay(1000);
			CatOne.GateWay->BatteryReadDlyCnt = 60;
			break;	
	}
}

void EthLoopHandler(void)
{
	rt_err_t result;
	
	if(CatOne.GateWay->SvrRegFlag == false) {
		if(CatOne.RegisterDelayCnt == 0) {
			if(ETH_LINK_GET() == Reset) {
				CatOne.RegisterDelayCnt = REGISTER_INTERVAL_MAX * 10;
				uint8_t ret = GateWayRegister(CatOneEthTxBuff);
				rt_mq_send(CatOne.GateWay->NetSendData_MQ, CatOneEthTxBuff, ret);
			}
		}
		else {
			CatOne.RegisterDelayCnt--;
		}
	}
	result = rt_mq_recv(CatOne.GateWay->NetSendData_MQ, Payload, CAT_ONE_REV_LEN_MAX, 100);
	if(result == RT_EOK) {
		CatOneEthTxLen = NetCommOrgData(CatOne.GateWay, Payload, CatOneEthTxBuff);
		HexToAscii(CatOneEthTxBuff, CommUnitSendASCII, CatOneEthTxLen);
		EthRevTimeOutCnt = 0;
		EthOrCat1UartSend((uint8_t *)CommUnitSendASCII, CatOneEthTxLen * 2);
		CommUnitSendASCII[CatOneEthTxLen * 2] = 0;
		CAT1_DBG_LOG("Eth Send: %s\r\n",CommUnitSendASCII);
	} 
}

bool CatOneEthSendQueue(uint8_t *sData, uint16_t sLen)
{
	if(CatOne.GateWay->SvrRegFlag == false)
		return false;
	rt_mq_send(CatOne.GateWay->NetSendData_MQ, sData, sLen);
	return true;
}

static void CatOneInit(GateWayPara GateWay)
{
	memset(&CatOne, 0x00, sizeof(CatOne_t));
	CatOne.Status = CAT_ONE_RESET;
	CatOne.GateWay = GateWay;
	CatOne.CatOneRevCallBack = GateWay->SvrRevCallBack;
}

void CatOneEthRev_Thread_Entry(void *parameter)
{
	rt_err_t result;
	char RxBuffTemp[CAT_ONE_REV_LEN_MAX];
	uint8_t HexData[CAT_ONE_REV_LEN_MAX / 2];
	
	GateWayPara GateWay = (GateWayPara)parameter;
	
	rt_kprintf("CatOneTthRev Thread is running!\r\n");
	
	while(1) {
		if(GateWay->ConfigPara.Comm == CATONE_COMM) {
			result = rt_sem_take(CatOneIRQ_Sem, 500);
			if(result == RT_EOK) {
				memcpy(RxBuffTemp, CatOneEthRxBuff, CatOneEthRxLen);
				RxBuffTemp[CatOneEthRxLen] = 0;
				CatOneAtCmdAnalyze(RxBuffTemp);
				memset(CatOneEthRxBuff, 0x00, CAT_ONE_REV_LEN_MAX);
				CatOneEthRxLen  = 0;
			}
			//CatOneEthRxLen  = 0;
		}
		else if(GateWay->ConfigPara.Comm == ETH_COMM) {
			result = rt_sem_take(EthIRQ_Sem, 500);
			if(result == RT_EOK) {
				memcpy(RxBuffTemp, CatOneEthRxBuff, CatOneEthRxLen);
				RxBuffTemp[CatOneEthRxLen] = 0;
				CAT1_DBG_LOG("Eth Rev: %s\r\n",RxBuffTemp);
				memset(HexData, 0x00, CatOneEthRxLen / 2);
				uint8_t ret = AsciiToHex(RxBuffTemp, HexData, CatOneEthRxLen);
				if(ret > 0)
					GateWay->SvrRevCallBack(GateWay, HexData,  ret);
				memset(CatOneEthRxBuff, 0x00, CAT_ONE_REV_LEN_MAX);
				CatOneEthRxLen = 0;
			}
			//CatOneEthRxLen = 0;
		}
	}
}

void CatOne_Eth_Thread_Entry(void *parameter)
{
	GateWayPara GateWay = (GateWayPara)parameter;
	
	CatOneRev_Sem  = rt_sem_create("cat1r_sem",	0, RT_IPC_FLAG_FIFO);
	if(CatOneRev_Sem == RT_NULL) {
		rt_kprintf("CatOne Sem Create Failed!\r\n");
	}
	
	EthIRQ_Sem  = rt_sem_create("eth_sem",	0, RT_IPC_FLAG_FIFO);
	if(EthIRQ_Sem == RT_NULL) {
		rt_kprintf("Eth Sem Create Failed!\r\n");
	}
	
	CatOneIRQ_Sem  = rt_sem_create("cat1_sem",	0, RT_IPC_FLAG_FIFO);
	if(CatOneIRQ_Sem == RT_NULL) {
		rt_kprintf("CatOneIRQ Sem Create Failed!\r\n");
	}
	
	CatOneInit(GateWay);
	ETH_RESET_CLR();
	rt_thread_delay(10);
	ETH_RESET_SET();	
	Cat1Rev_Thread = rt_thread_create("Cat1Rev", CatOneEthRev_Thread_Entry, parameter, 3000, 3, 20);
	if (Cat1Rev_Thread != RT_NULL) {
		rt_thread_startup(Cat1Rev_Thread);
	}
	else {
		rt_kprintf("CatOneRev Thread Create Failed! Exit...\r\n");
		return;
	}
	rt_kprintf("CatOne Thread is running！\r\n");

	while(1) {
		//rt_mutex_take(GateWay->UartRevMutex, RT_WAITING_FOREVER);
		if(GateWay->ConfigPara.Comm == CATONE_COMM)
			CatOneLoopHandler();
		else if(GateWay->ConfigPara.Comm == ETH_COMM)
			EthLoopHandler();
		else
			rt_thread_delay(1);
		//rt_mutex_release(GateWay->UartRevMutex);
	}
}


void EthOrCat1RxIrqCallback(uint8_t rData)
{	
	if(EthRevTimeOutCnt == 0) 
		CatOneEthRxLen = 0;
	
	if(CatOneEthRxLen < CAT_ONE_REV_LEN_MAX) {
		CatOneEthRxBuff[CatOneEthRxLen++] = rData;
	}
	
	EthRevTimeOutCnt = 3;
}

void EthRxOverhandler(void)
{
	if(EthRevTimeOutCnt > 0)
		EthRevTimeOutCnt--;
	
	if(CatOneEthRxLen > 5 && EthRevTimeOutCnt == 0) {
		EthRevTimeOutCnt = 20;
		if(CatOne.GateWay->ConfigPara.Comm == CATONE_COMM)
			rt_sem_release(CatOneIRQ_Sem);
		else
			rt_sem_release(EthIRQ_Sem);
	}
}

void CatReadImeiOrSim(char *Imei, char *Sim)
{
	if(Imei != NULL) {
		memcpy(Imei, CatOne.IMEI, 15);
		Imei[15] = 0x00;
	}
	if(Sim != NULL) {
		memcpy(Sim, CatOne.SIM, 20);
		Sim[20] = 0x00;
	}
}
