#include "bsp.h"

NODESTATUS NodeStatus;//节点状态
static Handl IsHandl[DATA_BUF_COUNT];
static DATA_BUF Data_Buf[DATA_BUF_COUNT];//数据缓冲,最大长度PAYLOAD_DATA_LEN

u8 tx_mac[MAC_LEN+1]={0};//初始发送mac地址
static const u8 pipe1_4_mac[MAC_LEN+1]={0xFF,0xB9,0x7F,0x55,0xB0,0x00};//通道1-4地址,用于接收广播消息
static u8 pipe5_mac[MAC_LEN+1]={0x00,0xB9,0x7F,0x55,0xB0,0x00};//通道5地址,用于接收广播消息
static HANDLECALLBACK RecvHandler=NULL;

void NRF_Init(void)//初始化协议
{
	MemSet((BYTE *)&Data_Buf,0,sizeof(DATA_BUF)*DATA_BUF_COUNT);//初始化缓冲区为空闲状态
	MemSet((BYTE *)&IsHandl,0,sizeof(Handl)*DATA_BUF_COUNT);
	MemSet((BYTE *)&NodeStatus,0,sizeof(NODESTATUS));//初始化节点状态
	if(NRF_IsHaveStoreData(NRF_STORE_FLAG,NRF_STORE_ADDRESS))
	{
		NRF_ReadNrfParam();
	}
	NodeStatus.route_addr=1;
	NodeStatus.channel=124;//初始信道124,可用信道0~124
	NodeStatus.link_status=DISCONNECT;
	NRF_Config(NodeStatus.node_mac,NodeStatus.channel);//硬件初始化
	NRF_SetPipe1To4Mac(pipe1_4_mac);
	NRF_SetPipe5Mac(pipe5_mac);
}

void NRF_SetPipe5Mac(u8 *addr)
{
	NRF_CE = 0;
	GetMacAddr(addr,'M',0);//生成MAC地址
	if(addr[0]>0xFB)
	{
		addr[0]-=4;
	}
	NRF_WriteReg(RX_ADDR_P5, addr[0]);//写通道5,RX地址
	NRF_WriteReg(CONFIG, 0x0B);//接收模式
	NRF_CE = 1;
}

void GetMacAddr(u8 *mac,const char ch,const u8 addr)
{
	u8 str[6]={0};
	sprintf((char *)str,"%05d",NodeStatus.pwd);
	if(ch=='S')
	{
		str[0]=~(str[0]^(((str[1]<<4)^(str[2]<<2))^((str[3]<<1)^(str[4]<<3))));
		str[1]=(~((str[1]<<2)^(str[4]<<2)))^str[0];
		str[2]=(~((str[2]<<3)^(str[3]<<1)))^str[1];
		str[3]=(~((str[3]<<3)^(str[2]<<4)))^str[2];
		str[4]=(~((str[4]<<1)^(str[1]<<3)))^str[3];
	}
	else if(ch=='C')
	{
		str[0]=~((str[0]^addr)^(((str[1]<<2)^addr)^((str[3]<<1)^addr))^(((str[4]<<2)^addr)^((str[2]<<3)^addr)));
		str[1]=(~((str[1]<<3)^addr))^(str[0]^(~((str[4]<<1)^addr)));
		str[2]=(~((str[2]<<3)^addr))^str[1]^(~((str[3]<<1)^addr));
		str[3]=(~((str[3]<<2)^addr))^str[2]^(~((str[2]<<4)^addr));
		str[4]=(~((str[4]<<1)^addr))^str[3]^(~((str[1]<<3)^addr));
	}
	else if(ch=='M')
	{
		str[0]=~(((str[1]<<1)^(str[2]<<4))^((str[3]<<1)^(str[4]<<3)));
		str[1]=0xB9;
		str[2]=0x7F;
		str[3]=0x55;
		str[4]=0xB0;
	}
	MemCopy((BYTE *)mac,(BYTE *)str,MAC_LEN);
}

void NRF_WaitDistributionAddr(void)
{
	NRF_ClearStroreData(NRF_STORE_ADDRESS);
	sprintf((char *)NodeStatus.node_mac,"00000");//获取mac地址
	NodeStatus.node_addr=0;
}

void NRF_SetNodeAddrMac(const u8 node,const u8 *mac)
{
	NodeStatus.node_addr=node;
	MemCopy((BYTE *)NodeStatus.node_mac,(BYTE *)mac,MAC_LEN);
	NRF_StoreNrfParam();
}

void NRF_SetDefaultRecvHandler(HANDLECALLBACK pFun)
{
	RecvHandler=pFun;
}

void NRF_StoreNrfParam(void)
{
	NRFSTOREDATA store_data;
	MemSet((BYTE *)&store_data,0,sizeof(NRFSTOREDATA));
	store_data.node_addr=NodeStatus.node_addr;
	store_data.pwd=NodeStatus.pwd;
	MemCopy((BYTE *)store_data.local_mac,(BYTE *)NodeStatus.node_mac,MAC_LEN);
	EE_FlashWrite(NRF_STORE_FLAG,NRF_STORE_ADDRESS,(u8 *)&store_data,sizeof(NRFSTOREDATA));//擦除并写1页flash
	GetMacAddr(tx_mac,'S',0);//生成TX-MAC地址
}

static void NRF_ReadNrfParam(void)
{
	NRFSTOREDATA store_data;
	if(NRF_IsHaveStoreData(NRF_STORE_FLAG,NRF_STORE_ADDRESS))
	{
		MemSet((BYTE *)&store_data,0,sizeof(NRFSTOREDATA));
		EE_FlashReadFlag(NRF_STORE_FLAG,NRF_STORE_ADDRESS,(u8 *)&store_data,sizeof(NRFSTOREDATA));
		NodeStatus.node_addr=store_data.node_addr;
		NodeStatus.pwd=store_data.pwd;
		MemCopy((BYTE *)NodeStatus.node_mac,(BYTE *)store_data.local_mac,MAC_LEN);
		GetMacAddr(tx_mac,'S',0);//生成TX-MAC地址
	}
}

static void NRF_AutoLink(void)//自动连接
{
	char linkbuf[PAYLOAD_DATA_LEN]={0};
	static u16 time=0;
	if(DISCONNECT==NodeStatus.link_status&&(NodeStatus.node_addr>=30&&NodeStatus.node_addr<0xFF))
	{
		time++;
		if(time>500)//5秒
		{
			time=0;
			sprintf(linkbuf,"Request Addr %d",NodeStatus.node_addr);
			NRF_SendData(NodeStatus.route_addr,START_LINK,(u8 *)linkbuf,tx_mac,NULL);//发送数据接口
		}
	}
}

void NRF_SendData(const u8 dst_addr,const u8 type,const u8 *buf,const u8 *mac,HANDLECALLBACK fun)//发送数据接口
{
	u8 idx;
	static u16 id=0;
	u16 length=strlen((char *)buf);
	if(length>PAYLOAD_DATA_LEN)
	{
		return;
	}
	if(dst_addr!=NodeStatus.node_addr)
	{
		idx=NRF_MallocIdleDataBufId();
		if(0xFF==idx)
		{
			return;
		}
		id++;
		if(0xFFFF==id)
		{
			id=0;
		}
		Data_Buf[idx].status=WAIT_SEND;
		Data_Buf[idx].dst_channel=NodeStatus.channel;
		MemCopy((BYTE *)Data_Buf[idx].dst_mac,(BYTE *)mac,MAC_LEN);
		Data_Buf[idx].HandleCallBack=fun;
		Data_Buf[idx].payload.header.src_addr=NodeStatus.node_addr;
		Data_Buf[idx].payload.header.dst_addr=dst_addr;
		Data_Buf[idx].payload.header.pack_type=type;
		Data_Buf[idx].payload.header.pwd=NodeStatus.pwd;
		Data_Buf[idx].payload.header.ID=id;//获取唯一的ID
		MemCopy((BYTE *)Data_Buf[idx].payload.buf,(BYTE *)buf,PAYLOAD_DATA_LEN);
	}
}

//void NRF_SendCallBack(u8 src_addr,u8 dst_addr,u8 pack_type,u16 ID,u8 *buf,u8 status)
//{
//	printf("***SendCallBackPayload***\r\n");
//	printf("src_addr=%d\r\ndst_addr=%d\r\n",src_addr,dst_addr);
//	printf("type=%d\r\nID=%d\r\nbuf=%s\r\n",pack_type,ID,buf);
//	if(status)
//	{
//		printf("SendData=%s ok\r\n\r\n",buf);
//	}
//	else
//	{
//		printf("SendData=%s fail\r\n\r\n",buf);
//	}
//}

static void NRF_NrfSendData(void)//根据缓冲区状态发送数据,发送前先检测干扰
{
	u8 index;
	index=NRF_SearchDataBuf(WAIT_SEND);
	if(0xFF==index)
	{
		index=NRF_SearchDataBuf(WAIT_SEND_RETRY);
	}
	if(0xFF!=index)
	{
		if(!NRF_DisturbanceDetect())//检测是否有其它节点在发送数据
		{
			NodeStatus.shift_failed_count=0;
			NodeStatus.shift_count++;
			if(!Data_Buf[index].isBroadcast)
			{
				if(NRF_SendPayload(ACK,Data_Buf[index].dst_mac,Data_Buf[index].dst_channel,(u8* )&Data_Buf[index].payload))//通道0
				{	
					Data_Buf[index].status=SEND_SUCCESS;
				}
				else
				{
					Data_Buf[index].status=WAIT_SEND_RETRY;
					Data_Buf[index].send_failed_count++;
				}
			}
			else
			{
				switch(Data_Buf[index].payload.header.pack_type)
				{
					case BUILD_CONNECT:
						NRF_SendPayload(NO_ACK,(u8 *)pipe1_4_mac,NodeStatus.channel,(u8* )&Data_Buf[index].payload);//通道1
						break;
					default:
						NRF_SendPayload(NO_ACK,pipe5_mac,NodeStatus.channel,(u8* )&Data_Buf[index].payload);//通道5
						break;
				}
				Data_Buf[index].status=SEND_FAILED;
			}
			NRF_RxMode(NodeStatus.node_mac,NodeStatus.channel);//自动ACK方式会改变mac地址,必须重新设置
		}
		else
		{
			NodeStatus.shift_failed_count++;
			if(NodeStatus.shift_failed_count>300)
			{
				NodeStatus.shift_failed_count=0;
				NRF_Init();
			}
		}
		//NRF_RxMode(NodeStatus.node_mac,NodeStatus.channel);//自动ACK方式会改变mac地址,必须重新设置
	}
}

static void NRF_HandleDataPack(LPayload pPayLoad,u8 pipe)//处理数据包
{
	if((WAIT_CONNECT==NodeStatus.link_status&&BUILD_CONNECT==pPayLoad->header.pack_type)||
		NodeStatus.node_addr==pPayLoad->header.dst_addr)
	{
		if(RecvHandler)
		{
			RecvHandler(pPayLoad->header.src_addr,pPayLoad->header.dst_addr,pPayLoad->header.pack_type,
						pPayLoad->header.pwd,pPayLoad->buf,pipe);
		}
	}
	else
	{
		NRF_RelayPackage(pPayLoad);//转发
	}
}

static void NRF_RelayPackage(LPayload pPayLoad)//转发
{
	u8 idx;
	u8 link_mac[MAC_LEN+1]={0};
	if(pPayLoad->header.pwd==NodeStatus.pwd)
	{
		idx=NRF_MallocIdleDataBufId();
		if(0xFF!=idx)
		{
			MemCopy((BYTE*)&Data_Buf[idx].payload,(BYTE *)pPayLoad,sizeof(Payload));
			Data_Buf[idx].dst_channel=NodeStatus.channel;
			if(pPayLoad->header.dst_addr<30)
			{
				GetMacAddr(link_mac,'S',0);
			}
			if(pPayLoad->header.dst_addr>=30)
			{
				GetMacAddr(link_mac,'C',pPayLoad->header.dst_addr);//生成MAC地址
			}
			MemCopy((BYTE *)Data_Buf[idx].dst_mac,(BYTE *)link_mac,MAC_LEN);
			Data_Buf[idx].status=WAIT_SEND;
		}
		printf("\r\n***Relay-Package***\r\n");
	}
}

void NRF_RecvData(void)
{
	Payload tmp;
	u8 id,status,pipe_num;
	MemSet((BYTE *)&tmp,0,sizeof(Payload));
	status=NRF_ReadReg(STATUS);//读取status寄存器的值
	pipe_num=(status&RX_P_NO_MASK)>>1;
	NRF_ReadBuf(R_RX_PAYLOAD, (u8 *)&tmp, PAYLOAD_LEN);//保存接收到的数据
	NodeStatus.recv_count++;
	if(tmp.header.src_addr==NodeStatus.node_addr)//是自己的包
	{
		NRF_RxMode(NodeStatus.node_mac, NodeStatus.channel);
		return;
	}
	if(!NRF_CmpHandlId(tmp.header.src_addr,tmp.header.dst_addr,tmp.header.ID))
	{
		id=NRF_SearchHandlTimeoutId();
		if(0xFF!=id)
		{
			IsHandl[id].src_addr=tmp.header.src_addr;
			IsHandl[id].dst_addr=tmp.header.dst_addr;
			IsHandl[id].RID=tmp.header.ID;
			IsHandl[id].time=Get_RunTime();
			NRF_HandleDataPack(&tmp,pipe_num);
		}
	}
	NRF_RxMode(NodeStatus.node_mac, NodeStatus.channel);
}

void NRF_HandleBuf(void)//根据缓冲区状态处理缓冲区
{
	u8 i;
	for(i=0;i<DATA_BUF_COUNT;i++)
	{
		switch(Data_Buf[i].status)
		{
			case WAIT_SEND_RETRY:
				if(Data_Buf[i].send_failed_count>=MAX_FAILED_COUNT)
				{
					Data_Buf[i].isBroadcast=1;
				}
				break;
			case SEND_SUCCESS:
				if(Data_Buf[i].HandleCallBack)
				{
					Data_Buf[i].HandleCallBack(Data_Buf[i].payload.header.src_addr,
												Data_Buf[i].payload.header.dst_addr,
												Data_Buf[i].payload.header.pack_type,
												Data_Buf[i].payload.header.ID,
												Data_Buf[i].payload.buf,PACKAGE_SUCCESS);
				}
				NRF_FreeDataBuf(i);
				break;
			case SEND_FAILED:
				if(Data_Buf[i].HandleCallBack)
				{
					Data_Buf[i].HandleCallBack(Data_Buf[i].payload.header.src_addr,
												Data_Buf[i].payload.header.dst_addr,
												Data_Buf[i].payload.header.pack_type,
												Data_Buf[i].payload.header.ID,
												Data_Buf[i].payload.buf,PACKAGE_FAILED);
				}
				NRF_FreeDataBuf(i);
				break;
			default:
				break;
		}
	}
}

u8 NRF_AppropriateChannelDetect(void)//检测拥挤程度最低的信道
{
	u8 channel,min_disturb_count=11,i,j;
	u8 disturb_count[125];
	ThreadLock=1;
	MemSet((BYTE *)disturb_count,0,125);
	channel=NRF_ReadChannel();
	for(i=0;i<10;i++)
	{
		for(j=0;j<125;j++)
		{
			NRF_SetChannel(i);
			if(NRF_DisturbanceDetect())
			{
				disturb_count[j]++;
			}
		}
	}
	NRF_SetChannel(channel);
	for(i=0;i<125;i++)
	{
		if(disturb_count[i]<min_disturb_count)
		{
			min_disturb_count=disturb_count[i];
			channel=i;
		}
	}
	NRF_ReadReg(FLUSH_RX);//清接收FIFO
	ThreadLock=0;
	return channel;
}

u8 NRF_CmpHandlId(const u8 src_addr,const u8 dst_addr,const u16 ID)
{
	u8 i=0;
	u32 time;
	time=Get_RunTime();
	for(i=0;i<DATA_BUF_COUNT;i++)
	{
		if(time-IsHandl[i].time<LINK_INTERVAL)
		{
			if(src_addr==IsHandl[i].src_addr&&dst_addr==IsHandl[i].dst_addr&&ID==IsHandl[i].RID)
			{
				return TRUE;
			}
		}
	}
	return FALSE;
}

void NRF_Thread(void)//定时线程,执行协议
{
	NRF_AutoLink();
	NRF_NrfSendData();
	NRF_HandleBuf();
}

u8 NRF_MallocIdleDataBufId(void)//得到一个空闲DATABUF,并将其标记为待用
{
	u8 i;
	ThreadLock=1;//锁定
	for(i=0;i<DATA_BUF_COUNT;i++)
	{
		if(IDLE==Data_Buf[i].status)
		{
			Data_Buf[i].status=WAIT_USE;
			ThreadLock=0;//解锁
			return i;
		}
	}
	ThreadLock=0;//解锁
	return 0xFF;
}	

void NRF_FreeDataBuf(const u8 id)//释放被使用的DATABUF,仅改变为空闲状态
{
	if(id>(DATA_BUF_COUNT-1)||id==0xFF)
	{
		return;
	}
	ThreadLock=1;//锁定
	MemSet((BYTE *)&Data_Buf[id],0,sizeof(DATA_BUF));
	ThreadLock=0;//解锁
}

u8 NRF_SearchDataBuf(const u8 status)//查找状态为status的DataBuf,返回索引
{
	u8 i;
	for(i=0;i<DATA_BUF_COUNT;i++)
	{
		if(status==Data_Buf[i].status)
		{
			return i;
		}
	}
	return 0xFF;
}

u8 NRF_SearchHandlTimeoutId(void)
{
	u8 i;
	u32 time;
	time=Get_RunTime();
	for(i=0;i<DATA_BUF_COUNT;i++)
	{
		if(time-IsHandl[i].time>LINK_INTERVAL)
		{
			return i;
		}
	}
	return 0xFF;
}
