⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 unet.c

📁 Zigbee模块的详细电路原理图和C代码.rar
💻 C
📖 第 1 页 / 共 3 页
字号:
			{
				ChiPtr->Available = 1;
				UnetSys.Flag.GP0 = 1;
			}			
			goto TX_ASSO_RSP_LABEL;		//在子节点链表里找到发送连接申请的节点的地址,则直接应答,不用再申请空间存储该节点信息
		}
		ChiPtr = ChiPtr->Next;		//如果该子节点地址与收到的连接请求帧子地址不一样,则切换到下一个子节点进行比较
	}	
	//Check CAPACITY
	if(MsgPtr->Cap & 0x02)		//判断该设备是否完整功能设备
	{ // Router
		if(UnetSys.JoinRouterCnt + UnetSys.JoinEndevCnt >= UNET_MAX_CHILD || UnetSys.JoinRouterCnt >= UNET_MAX_ROUTER)
		{		//如果连接的设备个数已经超限
			RsPtr->ShortAddr = 0xffff;		//应答帧里分配的短地址设定为该值表示拒绝连接请求
			RsPtr->AssoStatus = PAN_AT_CAPACITY;
			//UnetSys.Flag.ChildFull = 1; 
			goto TX_ASSO_RSP_LABEL;
		}
		UnetSys.JoinRouterCnt++;		
	}
	else		//非完整功能设备
	{ // End device	
		if(UnetSys.JoinRouterCnt + UnetSys.JoinEndevCnt >= UNET_MAX_CHILD)
		{
			RsPtr->ShortAddr = 0xffff;
			RsPtr->AssoStatus = PAN_AT_CAPACITY;
			//UnetSys.Flag.ChildFull = 1; 
			goto TX_ASSO_RSP_LABEL;
		}
		UnetSys.JoinEndevCnt++;
	}
	//Allocate address
	RsPtr->ShortAddr = UnetSys.NextAddr;		//分配短地址
	stAddrList.MACAddress[stAddrList.ucAddrCont] = UnetSys.NextAddr;	//将地址添加到地址列表中
	stAddrList.LifeTime[stAddrList.ucAddrCont] = 20000;		//
	stAddrList.ucAddrCont ++;
	RsPtr->AssoStatus = ASSOCIATION_SUCCESS;	//连接成功状态
	UnetSys.NextAddr += UnetSys.AddrInc;
	for(i=0;i<stAddrList.ucAddrCont;i++)		//判断地址是否已经被使用
	{
		if( UnetSys.NextAddr == stAddrList.MACAddress[i] )
		{
			UnetSys.NextAddr += UnetSys.AddrInc;
			i = 0;
			continue;
		}
	}
	//Add new entry and update information
	if(insert_node((void *) &UnetSys.ChildHead, (void *) &UnetSys.ChildTail, CHILD ) == NULL)
		return FAILURE;		//申请新的节点信息存储空间
	//初始化新的末尾节点的数据	
	UnetSys.ChildTail->Cap = MsgPtr->Cap;		
	UnetSys.ChildTail->NetworkAddress = RsPtr->ShortAddr;
	UnetSys.ChildTail->Available = 1;
	UnetSys.ChildTail->Next = NULL;
	MSG_Copy(UnetSys.ChildTail->MacAddr, MsgPtr->SrcAddr, 8);
	
TX_ASSO_RSP_LABEL:		//发送连接响应命令帧
	RsPtr->Header.val = 0x8c23;
	RsPtr->Seqnum = UnetSys.MacDSN;	
	UnetSys.MacDSN++;
	RsPtr->SrcAddr = UnetSys.NwkAddr;
	RsPtr->SrcPID = UnetSys.JoinPID;
	RsPtr->DstPID = UnetSys.JoinPID;
	RsPtr->COMM_ID = MT_ASSO_RSP;
	MSG_Copy(RsPtr->DstAddr, MsgPtr->SrcAddr, 8);
	if(UzTx(RF_TX_BUFF, sizeof(MCP_ASSO_RSP)))
	{
		if(UnetSys.Flag.GP0)
			goto TX_PBACK_LABEL;		
		return SUCCESS;
	}
	return RETRY_EXCEED;
TX_PBACK_LABEL:	
	UnetSys.Flag.GP0 = 0; //Clear flag
	return unet_tx_pback(ChiPtr->NetworkAddress);
}


void unet_rx_asso_rsp(MCP_ASSO_RSP *RsPtr)
{
	UnetSys.Flag.RecvAssoRsp = 1;

	#ifdef CONSOLE
	printf("Join PANid: %2x, Join Status: %x\r\n", RsPtr->SrcPID, RsPtr->AssoStatus);
	#endif

	if(RsPtr->AssoStatus == ASSOCIATION_SUCCESS){
		//UnetSys.Status = JOIN_SUCCESS;
		UnetSys.Flag.AssoSuccess = 1;
		UnetSys.NwkAddr = RsPtr->ShortAddr;
		#ifdef CONSOLE
		printf("Parent: %2x, NwkAddr: %2x\r\n", RsPtr->SrcAddr, RsPtr->ShortAddr);
		#endif
	}

	return;
}


UINT8 unet_check_child(UINT16 NwkAddr, struct _child_list_ **CurrPtr){
	struct _child_list_ *ChildPtr;

	DBG_tag();

	ChildPtr = UnetSys.ChildHead;

	while(ChildPtr != NULL){
		if(ChildPtr->NetworkAddress == NwkAddr){
			if(CurrPtr)
			*CurrPtr = ChildPtr;
			if(ChildPtr->Available){
				return SUCCESS;
			}
			break;
		}
		ChildPtr = ChildPtr->Next;
	}

	return FAILURE;
}


UINT8 unet_tree_routing(MAC_DATA_PKT *MsgPtr){
	UINT16 NextAddr, Cskip, A, D;

	A = UnetSys.NwkAddr;
	D = MsgPtr->NwkDstAddr;
	
	Cskip = compute_Cskip(UnetSys.DevDep -1);  //Cskip(d-1)

	if((D > A) && (D < (A + Cskip))){ //if destination is my descendant? ( A<D<A+compute_Cskip(d-1)), 2.7.3.3
		Cskip = compute_Cskip(UnetSys.DevDep);
		NextAddr = (A + 1) + ((D - (A + 1)) / Cskip) * Cskip;

		if(NextAddr < UnetSys.NextAddr){ // if next hop addr alread allocate?
			if(unet_check_child(NextAddr, NULL)) {
				MsgPtr->MHR.DstAddr = NextAddr;
				return FOUND_NEXT_HOP;
			}
		}

		return NEXT_HOP_NOT_AVAILABLE;
	}

	if(UnetSys.Flag.PanCoordinator)
		return TREE_ROUTING_FAILED; 
	
	MsgPtr->MHR.DstAddr = UnetSys.JoinParent; // Send to parent
	return SEND_TO_PARENT; 
	
}


UINT8 unet_rx_data_ind(MAC_DATA_PKT *MsgPtr, UINT8 Length)
{
	struct _broadcast_list_ *BroPtr;
	UINT8 i,*TmPtr;

	DBG_tag();

	//Check destination
	if(MsgPtr->NwkDstAddr == 0xffff)
	{ // if broadcast	
		if(MsgPtr->NwkSrcAddr == UnetSys.NwkAddr)  // This broadcast issued by devself.
			return DISCARD_FRAME;  

		BroPtr = UnetSys.BroHead;
		while(BroPtr != NULL)
		{
			if(BroPtr->Address == MsgPtr->NwkSrcAddr)
			{
				//if(MsgPtr->MHR.Seqnum > BroPtr->Sequence || (MsgPtr->MHR.Seqnum < 5 && BroPtr->Sequence >250)){ // Compare sequence number
				if(MsgPtr->MHR.Seqnum != BroPtr->Sequence)
				{ // Compare sequence number
					BroPtr->Sequence = MsgPtr->MHR.Seqnum;
					goto SEND_TO_QUEUE_LABEL;
				}
				return DISCARD_FRAME;  
			}
			BroPtr = BroPtr->Next;
		}
		if(insert_node((void *) &UnetSys.BroHead, (void *) &UnetSys.BroTail, BROADCAST ) == NULL) // Add new entry
			return FAILURE;			
		UnetSys.BroTail->Address = MsgPtr->NwkSrcAddr;
		UnetSys.BroTail->Sequence = MsgPtr->MHR.Seqnum;
		UnetSys.BroTail->Next = NULL;
		goto SEND_TO_QUEUE_LABEL;
	}
	else if(MsgPtr->NwkDstAddr == UnetSys.NwkAddr)
	{ // if devself
		UnetSys.Flag.GP0 = 1; // Set flag, indicate it will do only SEND_TO_QUEUE
		goto SEND_TO_QUEUE_LABEL;
	}
	else
	{ // Both not , routing
		i = unet_tree_routing(MsgPtr);

		if(i == NEXT_HOP_NOT_AVAILABLE)
		{  //Check the destination if allready link to devself by self-healing
			MsgPtr->MHR.DstAddr = MsgPtr->NwkDstAddr; // Send to the child directly
		}
		else if(i == TREE_ROUTING_FAILED)
		{
			return DISCARD_FRAME;  
		}
		goto TX_DATA_PKT_LABEL;
	}
SEND_TO_QUEUE_LABEL:

	DBG_tag();

	if(UnetSys.DataCnt < 5)
	{ // Max Data Packets were buffered.
		if(insert_node((void *) &UnetSys.DataHead, (void *) &UnetSys.DataTail, DATA ) == NULL) // Add new entry
			return FAILURE;	
			
		UnetSys.DataTail->Length = Length - sizeof(MAC_DATA_PKT) -2; // 2:FCS	
		if((UnetSys.DataTail->Msg = (UINT8 *) MSG_Alloc(UnetSys.DataTail->Length)) == NULL)
			return FAILURE;
	
		UnetSys.DataTail->SrcAddr = MsgPtr->NwkSrcAddr;
		UnetSys.DataTail->Next = NULL;
	
		TmPtr = (UINT8 *) MsgPtr;

		MSG_Copy(UnetSys.DataTail->Msg, (TmPtr + sizeof(MAC_DATA_PKT)), UnetSys.DataTail->Length);

		UnetSys.DataCnt++;
	}

	if(UnetSys.Flag.GP0)
	{
		UnetSys.Flag.GP0 = 0;
		return SUCCESS;
	}

TX_DATA_PKT_LABEL:

	DBG_tag();

	if(MsgPtr->Radius >0)
	{
		MsgPtr->Radius -= 1;
		MsgPtr->MHR.SrcAddr = UnetSys.NwkAddr;

		if(UzTx((UINT8 *) MsgPtr,Length -2)) 
			return SUCCESS;

	    if(!UnetSys.Flag.PanCoordinator) 
	    {
			if(MsgPtr->MHR.DstAddr == UnetSys.JoinParent)
			{
				if(unet_self_healing() == SELF_HEAL_SUCCESS) 
					goto TX_DATA_PKT_LABEL;
			
				return SELF_HEAL_FAILED; //Coordinator die
			}
	    }
	}
	
	return DISCARD_FRAME;
}

void unet_active_scan(BOOL AUTO)
{
	UINT8 TempChannel, i;
	
	TempChannel = UnetSys.Channel;
	
	UzRxOnlyBeacon();

	if(AUTO)
	{
		for(i=11; i<=26; i++)
		{ // Scan all channel
			UnetSys.Channel = i;
			UzSetChannel(i); // set channel
			while(!unet_tx_bcn_req())
			{ // Issue beacon request	
				WaitMS(10);
			}
			//WaitUS(aBaseSuperframeDuration*UnetSys.SO*16); // aBaseSuperframeDuration X 2eSO X 16us
			WaitMS(UNET_SCAN_WAIT_TIME); 
		}
	}
	else
	{
		UzSetChannel(UnetSys.Channel); // set channel
		while(!unet_tx_bcn_req()); // Issue beacon request	
		//WaitMS(1967); // aBaseSuperframeDuration X 2eSO (2e7 = 128) X 16us
		WaitMS(UNET_SCAN_WAIT_TIME); 	
	}

	unet_proc(); //Process all beacon frame in queue
	
	UzRxAllFrame();
	UnetSys.Channel = TempChannel;

}


/*********************************** Self - Healing *******************************************/
/*
UINT8 unet_tx_rebpan(){
	MAC_CMD_PKT *CmdPtr;
	UINT8 i;

	CmdPtr = (MAC_CMD_PKT *) RF_TX_BUFF;

	CmdPtr->MHR.Header.val = 0x8803;
	CmdPtr->MHR.DstAddr = 0xffff;
	CmdPtr->MHR.DstPID = UnetSys.JoinPID;
	CmdPtr->MHR.SrcAddr = UnetSys.NwkAddr;
	CmdPtr->MHR.SrcPID = UnetSys.JoinPID;
	CmdPtr->MHR.Seqnum = UnetSys.MacDSN;
	//UnetSys.MacDSN++;
	CmdPtr->COMM_ID = MT_REBPAN;

	for(i=0; i< UNET_MAX_RETRY; i++) {
		if(UzTx(RF_TX_BUFF, sizeof(MAC_CMD_PKT), 0)) return SUCCESS;
	}
	return RETRY_EXCEED;

}

UINT8 unet_rx_rebpan(){


}
*/

UINT8 unet_tx_disasso(UINT8 *DST_MAC){
	MCP_DISASSO_NTF *DisPtr;

	DBG_tag();

	DisPtr = (MCP_DISASSO_NTF *) RF_TX_BUFF;

	DisPtr->Header.val = 0x8c23;
	DisPtr->Seqnum = UnetSys.MacDSN;
	UnetSys.MacDSN++;
	DisPtr->SrcAddr = UnetSys.NwkAddr;
	DisPtr->SrcPID = UnetSys.JoinPID;
	DisPtr->DstPID = UnetSys.JoinPID;

	MSG_Copy(DisPtr->DstAddr, DST_MAC, 8);
	
	DisPtr->COMM_ID = MT_DISASSO_NTF;
	DisPtr->DisassoReason = 0x01; // The coordinator or router wishes the device to leave the PAN.
	
	return UzTx(RF_TX_BUFF, sizeof(MCP_DISASSO_NTF));
}


UINT8 unet_rx_disasso(MAC_CMD_PKT *CmdPtr){

	if(CmdPtr->MHR.SrcAddr == UnetSys.JoinParent){
		INIT_UNET();
		return JOIN_UNET(UNET_PAN_ID, UNET_CHANNEL);
	}

	return DISCARD_FRAME;
}

UINT8 unet_tx_ipop(UINT16 NNParent, UINT16 NParent){
	MCP_IPOP *FpoPtr;

	FpoPtr = (MCP_IPOP *) RF_TX_BUFF;

	FpoPtr->MHR.Header.val = 0x8823;
	FpoPtr->MHR.DstAddr = NNParent;
	FpoPtr->MHR.DstPID = UnetSys.JoinPID;
	FpoPtr->MHR.SrcAddr = UnetSys.NwkAddr;
	FpoPtr->MHR.SrcPID = UnetSys.JoinPID;
	FpoPtr->MHR.Seqnum = UnetSys.MacDSN;
	UnetSys.MacDSN++;
	FpoPtr->COMM_ID = MT_IPOP;
	FpoPtr->Parent = NParent;

	return UzTx(RF_TX_BUFF, sizeof(MCP_IPOP));
}


UINT8 unet_rx_ipop(MCP_IPOP *MsgPtr){
	struct _child_list_ *Ptr = NULL;
  
	unet_check_child(MsgPtr->Parent, &Ptr);

	if(Ptr != NULL)
		Ptr->Available = 0;
	
  	return SUCCESS;
}

UINT8 unet_tx_cback()
{
	MCP_CBACK *CBptr;

	CBptr= (MCP_CBACK *) RF_TX_BUFF;

	CBptr->MHR.Header.val = 0x8823;
	CBptr->MHR.DstAddr = UnetSys.JoinParent;
	CBptr->MHR.DstPID = UnetSys.JoinPID;
	CBptr->MHR.SrcAddr = UnetSys.NwkAddr;
	CBptr->MHR.SrcPID = UnetSys.JoinPID;
	CBptr->MHR.Seqnum = UnetSys.MacDSN;
	CBptr->COMM_ID = MT_CBACK;
	CBptr->Cap = 0xca;

	MSG_Copy(CBptr->MacAddr, MAC_ADDRESS, 8);

	return UzTx(RF_TX_BUFF, sizeof(MCP_CBACK));
}

UINT8 unet_rx_cback(MCP_CBACK *Msg){
	UINT8 i;
	struct _child_list_ *Cptr = NULL;

	//Check if any other device use the same address
	unet_check_child(Msg->MHR.SrcAddr, &Cptr);

	if(Cptr !=NULL){ // find exist entry
		unet_tx_disasso(Cptr->MacAddr);

		Cptr->NetworkAddress = Msg->MHR.SrcAddr;
		Cptr->Cap = Msg->Cap;
		Cptr->Available = 1;

		for(i=0; i<8; i++){
			Cptr->MacAddr[i] = Msg->MacAddr[i];
		}
		
	}else{
		if(Msg->Cap & 0x02){
			UnetSys.JoinRouterCnt++;
		}else{ // End device
			UnetSys.JoinEndevCnt++;
		}

		if(insert_node((void *) &UnetSys.ChildHead, (void *) &UnetSys.ChildTail, CHILD ) == NULL) // Add new entry
			return FAILURE;	

		UnetSys.ChildTail->Cap = Msg->Cap;
		UnetSys.ChildTail->NetworkAddress = Msg->MHR.SrcAddr;
		UnetSys.ChildTail->Available = 1;
		UnetSys.ChildTail->Next = NULL;

		MSG_Copy(UnetSys.ChildTail->MacAddr, Msg->MacAddr, 8);
	
		UnetSys.NextAddr = Msg->MHR.SrcAddr + UnetSys.AddrInc; // Update Address allocate
	}

	return SUCCESS;
}


UINT8 unet_tx_pback(UINT16 NwkAddr){
	MCP_PBACK *PBptr;

	PBptr = (MCP_PBACK *) RF_TX_BUFF;

	PBptr->MHR.Header.val = 0x8803;
	PBptr->MHR.DstAddr = 0xffff;
	PBptr->MHR.DstPID = UnetSys.JoinPID;
	PBptr->MHR.SrcAddr = UnetSys.NwkAddr;
	PBptr->MHR.SrcPID = UnetSys.JoinPID;
	PBptr->MHR.Seqnum = UnetSys.MacDSN;
	UnetSys.MacDSN++;
	PBptr->COMM_ID = MT_PBACK;
	PBptr->Parent = NwkAddr;

	return UzTx(RF_TX_BUFF, sizeof(MCP_PBACK));
}

UINT8 unet_rx_pback(MCP_PBACK *Msg)
{
	struct _broadcast_list_ *BroPtr;

	if(UnetSys.OrigParent == Msg->Parent)
	{
		UnetSys.JoinParent = UnetSys.OrigParent;
		BroPtr = UnetSys.BroHead;
		while(BroPtr != NULL)
		{
			if(BroPtr->Address == UnetSys.JoinParent)
			{
				BroPtr->Sequence = 0;	
				break;
			}
			BroPtr = BroPtr->Next;
		}
		return unet_tx_cback();	
	}
	return DISCARD_FRAME;
}

UINT8 unet_self_healing(){
	UINT8 Depth, Retry = 3;
	UINT16 NParent, NNParent;

	Depth = UnetSys.DevDep;
	NParent = UnetSys.JoinParent;

	while(Depth > 1 && Retry >0){
		NNParent = compute_Parent(Depth, NParent);

		if(unet_tx_ipop(NNParent, NParent)){ // Send indicate parent of parent
			UnetSys.OrigParent = UnetSys.JoinParent;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -