#include "LoraTask.h"
#include "main.h"
#include "CatOneTask.h"
#include "DebugCmd.h"

#define	UC_OFFLINE_TIME_INTERVAL_MAX				(2 * 60 * 60)//离线判断最大时间间隔，单位秒

static rt_sem_t LoraDioIRQ_Sem = RT_NULL;
static rt_thread_t LoraIRQ_Thread = RT_NULL;
static GateWayPara GateWay;

void LoraSend(uint8_t* pucBuff, uint8_t ucLen)
{
	Sx1276LoRaSendBuffer(pucBuff, ucLen);
}

//Lora接收消息统一放到消息队列，由接收任务处理
int LoraRevCallBack(GateWayPara GateWay, uint8_t *rData, uint16_t rLen)
{
	uint8_t *sData;
	if(rLen > 255)
		return -1;
	
	sData = rt_malloc(rLen + 5);
	sData[0] = rLen;
	
//	Debug_Printf("Lora Rev: ");
//	for(int i = 0; i < rLen; i++) {
//		Debug_Printf("%02x ", rData[i]);
//	}
//	Debug_Printf("\r\n");
	
	memcpy(&sData[1], rData, rLen);
	rt_mq_send(GateWay->LoraRev_MQ, sData, rLen + 1);
	rt_free(sData);
	return 0;
}

void LoraIRQ_Thread_Entry(void *parameter)
{
	rt_err_t result;
	static uint16_t LoraErrCnt = 0;
	
	Debug_Printf("LoraRev Thread is running！\r\n");
	while(1) {
		if(GateWay->ConfigPara.Lora.OnOff == false) {
			rt_thread_delay(100);
			continue;
		}
			
		result = rt_sem_take(LoraDioIRQ_Sem, 1000);
		if(result == RT_EOK) {
			IsrSx1276LoRaTxRx(GateWay);
			LoraErrCnt = 0;
		}
		else {
			LoraErrCnt++;
			if(LoraErrCnt > LORA_ERR_RESET_DLY_MAX) {		//15分钟内没有收到lora数据重启lora模块
				LoraErrCnt = 0;
				Debug_Printf("Lora Reset！\r\n");
				Sx1276LoRaInit(LoraRevCallBack);
			}
		}
	}
}

static void LoRaSendBuffer(uint8_t* pucBuff, uint16_t ucLen)
{
	if(GateWay->ConfigPara.Lora.OnOff == true)
		Sx1276LoRaSendBuffer(pucBuff, ucLen);
}

void Lora_Thread_Entry(void *parameter)
{
	rt_err_t result;
#ifndef LORA_LOWPOWER
	bool UnitCommSendFlag = false;
	uint8_t SendUnitCommIdx = 0;
	uint16_t UnitCommReadDelayCnt = 0;
#endif	
	uint8_t Payload[256];
	uint8_t MegData[9];
	
	GateWay = (GateWayPara)parameter;
	
	while(GateWay->ConfigPara.Lora.OnOff == false) {
		rt_thread_delay(100);
	}
	
	LoraDioIRQ_Sem  = rt_sem_create("loradioirq_sem",	0, RT_IPC_FLAG_FIFO);
	if(LoraDioIRQ_Sem == RT_NULL) {
		Debug_Printf("CatOneIRQ Sem Create Failed!\r\n");
	}
	
	LoraIRQ_Thread = rt_thread_create("LoraIRQ", LoraIRQ_Thread_Entry, NULL, 512, 3, 20);
	if (LoraIRQ_Thread != RT_NULL)
		rt_thread_startup(LoraIRQ_Thread);
	
	Sx1276LoRaInit(LoraRevCallBack);
	Debug_Printf("Lora Thread is running！\r\n");
#ifdef LORA_LOWPOWER
	while(1) {
		if(GateWay->ConfigPara.Lora.OnOff == false) {
			rt_thread_delay(100);
			continue;
		}
		
		result = rt_mq_recv(GateWay->LoraRev_MQ, Payload, 256, 1000);
		if(result == RT_EOK) {
			int ret = GateWay->CommUnitRevCallBack(GateWay, &Payload[1], Payload[0], LoRaSendBuffer);
			if(ret == 0xff)	//注册信息
				continue;
		}
		else {	//离线判断    
			for(int i = 0; i < COMMUNIT_NUM_MAX; i++) {
				if(GateWay->ConfigPara.CommUnitArray[i].RegFlag == true) {
					if(GateWay->ConfigPara.CommUnitArray[i].CommErrCnt < UC_OFFLINE_TIME_INTERVAL_MAX) {
						GateWay->ConfigPara.CommUnitArray[i].CommErrCnt++;
					}
					else if(GateWay->ConfigPara.CommUnitArray[i].CommStatus) {
						GateWay->ConfigPara.CommUnitArray[i].CommStatus = 0;
						MegData[0] = 7;
						MegData[1] = 0;
						MegData[2] = COMM_UNIT_CMD_READ;
						memcpy(&MegData[3], GateWay->ConfigPara.CommUnitArray[i].Mac[0], 6);
						MegData[9] = GateWay->ConfigPara.CommUnitArray[i].CommStatus;
						Debug_Printf("The CommUnit is offline.Mac:%02X-%02X-%02X-%02X-%02X-%02X\r\n",
													GateWay->ConfigPara.CommUnitArray[i].Mac[0][0],
													GateWay->ConfigPara.CommUnitArray[i].Mac[0][1],
													GateWay->ConfigPara.CommUnitArray[i].Mac[0][2],
													GateWay->ConfigPara.CommUnitArray[i].Mac[0][3],
													GateWay->ConfigPara.CommUnitArray[i].Mac[0][4],
													GateWay->ConfigPara.CommUnitArray[i].Mac[0][5]);
						CatOneEthSendQueue(MegData, 10);		//发送离线消息
					}
				}
			}
		}
	}
#else		
	while(1) {	
		if(UnitCommSendFlag == false && UnitCommReadDelayCnt >= GateWay->ConfigPara.CommUnitReadInterval) {
			if(SendUnitCommIdx < COMMUNIT_NUM_MAX) {
				if(GateWay->ConfigPara.CommUnitArray[SendUnitCommIdx].RegFlag && 
					GateWay->ConfigPara.CommUnitArray[SendUnitCommIdx].Mac[0][2] == 0x01) {
					GateWay->ConfigPara.CommUnitArray[SendUnitCommIdx].RevNewDataFlag = false;	
					Debug_Printf("Lora Read CommUnit: %02X:%02X:%02X:%02X:%02X:%02X\r\n",
												GateWay->ConfigPara.CommUnitArray[SendUnitCommIdx].Mac[0][0],
												GateWay->ConfigPara.CommUnitArray[SendUnitCommIdx].Mac[0][1],
												GateWay->ConfigPara.CommUnitArray[SendUnitCommIdx].Mac[0][2],
												GateWay->ConfigPara.CommUnitArray[SendUnitCommIdx].Mac[0][3],
												GateWay->ConfigPara.CommUnitArray[SendUnitCommIdx].Mac[0][4],
												GateWay->ConfigPara.CommUnitArray[SendUnitCommIdx].Mac[0][5]);	
					CommUnitCmdSend(GateWay, GateWay->ConfigPara.CommUnitArray[SendUnitCommIdx].Mac[0], COMM_UNIT_CMD_READ, NULL, 0, Sx1276LoRaSendBuffer);
					UnitCommSendFlag = true;
				}
				else {
					SendUnitCommIdx++;
					continue;
				}
			}
			else {
				SendUnitCommIdx = 0;
				UnitCommReadDelayCnt = 0;
			}
		}
		
		if(UnitCommReadDelayCnt < GateWay->ConfigPara.CommUnitReadInterval)
			UnitCommReadDelayCnt++;
		
		result = rt_mq_recv(GateWay->LoraRev_MQ, Payload, 256, 1000);
		if(result == RT_EOK) {
			int ret = GateWay->CommUnitRevCallBack(GateWay, &Payload[1], Payload[0], Sx1276LoRaSendBuffer);
			if(ret == 0xff)	//注册信息
				continue;
			
			if(UnitCommSendFlag && GateWay->ConfigPara.CommUnitArray[SendUnitCommIdx].RevNewDataFlag) {
				UnitCommSendFlag = false;
				SendUnitCommIdx++;
			}
		}
		else if(UnitCommSendFlag) {	//离线判断
			GateWay->ConfigPara.CommUnitArray[SendUnitCommIdx].CommErrCnt++;
			if(GateWay->ConfigPara.CommUnitArray[SendUnitCommIdx].CommErrCnt == 10) {
				GateWay->ConfigPara.CommUnitArray[SendUnitCommIdx].CommErrCnt = 0;
				if(GateWay->ConfigPara.CommUnitArray[SendUnitCommIdx].CommStatus) {
					GateWay->ConfigPara.CommUnitArray[SendUnitCommIdx].CommStatus = 0;
					MegData[0] = 7;
					MegData[1] = 0;
					MegData[2] = COMM_UNIT_CMD_READ;
					memcpy(&MegData[3], GateWay->ConfigPara.CommUnitArray[SendUnitCommIdx].Mac[0], 6);
					MegData[9] = GateWay->ConfigPara.CommUnitArray[SendUnitCommIdx].CommStatus;
					CatOneEthSendQueue(MegData, 10);		//发送离线消息
				}
			}
			UnitCommSendFlag = false;
			SendUnitCommIdx++;
		}
	}
#endif
}


void LoraTxRxIrqCallback(void)
{
	rt_sem_release(LoraDioIRQ_Sem);
}

void LoraInit(void)
{
	Sx1276LoRaInit(LoraRevCallBack);
}
