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

📄 unet.c

📁 Zigbee模块的详细电路原理图和C代码.rar
💻 C
📖 第 1 页 / 共 3 页
字号:
/*******************************************************************************

       UBEC (Uniband Electronic Corp.)

       Project: U-NET01, Ubiquitous network platform

       File: unet.c

       Version: 0.1.2

       Usage: Unet api & unet sub function

       Platform: U-NET01 DK with IAR 8051 C compiler

       Reference:

               Silicon Laboratories: C8051F124

               UBEC: UZ2400

       Note :

               Copyright (C) 2007 Uniband Electronic Corporation, All rights reserved

********************************************************************************/

#include ".\zigbee\unet.h"


UNET_SYS UnetSys;
UINT8 MAC_ADDRESS[8] = {0x11, 0x11, 0x18, 0x11, 0xaa, 0xbb, 0xcc, 0xdd};

MSG_QUEUE CommQueue; // Mac command queue
MSG_QUEUE DataQueue; // Mac data queue
UINT8 RF_RX_BUFF[128+16]; // RF receive buffer
UINT8 RF_TX_BUFF[128]; // RF transmit buffer

/*******************************************************************************/

void unet_active_scan(BOOL AUTO);
UINT8 unet_tx_bcn_req(void);
UINT8 unet_tx_asso_req(void);
UINT16 compute_Cskip(INT8 depth);
UINT16  compute_Parent(INT8 depth, UINT16 Parent);
void unet_init();
UINT8 unet_check_child(UINT16 NwkAddr, struct _child_list_ **CurrPtr);
UINT8 unet_tree_routing(MAC_DATA_PKT *MsgPtr);
INT8 unet_queue_proc(UINT8 frequency, MSG_QUEUE *QueuePtr);
void unet_proc(void);
UINT8 unet_self_healing();
UINT8 unet_tx_pback(UINT16 NwkAddr);

void clear_table(void **HeadAddr);
void *insert_node(void **HeadAddr, void **TailAddr, UINT8 Type);


/*******************************************************************************

	Unet Function
					
********************************************************************************/

void INIT_UNET(){

#ifdef CONSOLE
//	InitUART(); // Uart Initial
#endif

	InitSPI(); //SPI Initial
	UzInit(); //RF Initial
	
#ifdef PAOPEN	
	UzEnablePA();
#endif

	UzSetMacAddress(MAC_ADDRESS); //MAC Address

	unet_init(); //UNET Initial

//	EnabMcuInt(); //Interrupt
}


UINT8 ESTABLISH_UNET(UINT16 PanId, UINT8 Channel)
{
	struct _beacon_list_ *TmPtr;

	if(PanId > 0x3fff) 
          return PANID_INVALID;

	if(Channel > 26 || Channel < 11) 
		return CHANNEL_INVALID;

	UnetSys.JoinPID = PanId;	
	UnetSys.Channel = Channel;
	
	unet_active_scan(0); // Active Scan

	TmPtr = UnetSys.BcnHead;
 
	while(TmPtr != NULL){ // Check received beacon
		if(TmPtr->Channel == Channel && TmPtr->PID == PanId) 
			return PAN_ID_CONFLICT;

		TmPtr = TmPtr->Next;
	}

	UnetSys.NwkAddr = UNET_COORD_ADDRESS; // Coordinator default address
	UnetSys.DevDep = 0;
	UnetSys.NextAddr = UnetSys.NwkAddr + 1;
	UnetSys.AddrInc = compute_Cskip(UnetSys.DevDep);
	UnetSys.BcnPayload.DevDep = UnetSys.DevDep; 
	UnetSys.BcnPayload.EndevCap = 1;
	UnetSys.BcnPayload.ProtID = 0;
	UnetSys.BcnPayload.ProtVer = 0x01;
	UnetSys.BcnPayload.StackPro = 0;
	UnetSys.BcnPayload.RouterCap = 1;
	UnetSys.BcnPayload.Rvd0 = 0;
	UnetSys.Flag.JoinNetwork = 1;
	UnetSys.Flag.PanCoordinator = 1;
	
	UnetSys.Coordinator = 1;
	
	clear_table((void *) &UnetSys.BcnHead);
	
	UzSetPanId(PanId);
	UzSetChannel(Channel);
	UzSetNwkAddr(UnetSys.NwkAddr);
	UzSetCoordinator();
	
	return SUCCESS;

}


UINT8 JOIN_UNET(UINT16 PanId, UINT8 Channel)
{
	struct _beacon_list_ *BcnPtr;
	UINT8 rssi = 0, count = 0, State;

	if(PanId > 0x3fff) 
		return PANID_INVALID;

	if(Channel > 26 || Channel < 11) 
		return CHANNEL_INVALID;

	UnetSys.JoinPID = PanId;	
	UnetSys.Channel = Channel;

	UzSetPanId(PanId);
	//UzSetChannel(Channel);
	
	while(1)
	{
		unet_active_scan(0); // Active Scan
	
		BcnPtr = UnetSys.BcnHead;
	
		while(BcnPtr != NULL)
		{
			if(BcnPtr->Channel == Channel && BcnPtr->PID == PanId && (BcnPtr->SfSpec & 0x8000) && BcnPtr->LinkQuality > rssi && BcnPtr->DevDep < UNET_MAX_DEPTH)
			{
				rssi = BcnPtr->LinkQuality;
				UnetSys.JoinParent = BcnPtr->Addr;
				UnetSys.DevDep = BcnPtr->DevDep + 1;
				UnetSys.Flag.FindNetwork = 1;		
			}
			BcnPtr = BcnPtr->Next;
		}
			
		if(UnetSys.Flag.FindNetwork)
		{
			UnetSys.Flag.FindNetwork = 0; //Clear flag
	
			clear_table((void *) &UnetSys.BcnHead);
	
			//UzSetPanId(PanId);
			UzSetChannel(Channel);
		
			while(!unet_tx_asso_req()) // Send association request
				WaitMS(20);
			 
			while(!UnetSys.Flag.RecvAssoRsp) // Wait association response
				unet_proc();
			
			UnetSys.Flag.RecvAssoRsp = 0; // Clear flag
	
			if(UnetSys.Flag.AssoSuccess)
			{ //Check associate result
				UnetSys.Flag.AssoSuccess = 0; // Clear flag
				
				UnetSys.NextAddr = UnetSys.NwkAddr + 1;
				UnetSys.AddrInc = compute_Cskip(UnetSys.DevDep);
				UnetSys.BcnPayload.DevDep = UnetSys.DevDep; 
				UnetSys.BcnPayload.EndevCap = 1;
				UnetSys.BcnPayload.ProtID = 0;
				UnetSys.BcnPayload.ProtVer = 0x01;
				UnetSys.BcnPayload.StackPro = 0;
				UnetSys.BcnPayload.RouterCap = 1;	
				UnetSys.BcnPayload.Rvd0 = 0;
				UnetSys.Flag.JoinNetwork = 1;
				UnetSys.Flag.Router = 1;
				
				UnetSys.Coordinator = 0;
				
				UzSetNwkAddr(UnetSys.NwkAddr);
				return SUCCESS;
			}
			return FAILURE;
		}
		else
		{
			count ++;
			if(count > 5)
			{
				State = ESTABLISH_UNET( PanId, Channel );
				if(State != SUCCESS)
				{
					return State;
				}
				break;
			}
		}
	}
	return SUCCESS;
}


UINT8 SEND_TO_UNET(UINT16 DstAddr, UINT8 *DataPtr, UINT8 Length)
{
	MAC_DATA_PKT *TxPtr;
    UINT8 i;
        
TX_DATA_LABEL:

	if(Length > MAC_MAX_DATA_PAYLOAD_LENGTH -3)
		return DATA_TOO_LONG; // 3: Radius, Network Source address and Destination address

	TxPtr = (MAC_DATA_PKT *) RF_TX_BUFF;

	TxPtr->MHR.Header.val = 0x8801;
	TxPtr->MHR.Seqnum = UnetSys.MacDSN;
	UnetSys.MacDSN++;
	TxPtr->MHR.DstPID = UnetSys.JoinPID;
	TxPtr->MHR.SrcPID = UnetSys.JoinPID;
	TxPtr->MHR.SrcAddr = UnetSys.NwkAddr;
	TxPtr->Radius = UNET_MAX_DEPTH*2;
	TxPtr->NwkDstAddr = DstAddr;
	TxPtr->NwkSrcAddr = UnetSys.NwkAddr;

	if(DstAddr == 0xffff)
	{
		TxPtr->MHR.DstAddr = 0xffff;	//广播地址
	}
	else if(DstAddr == UnetSys.NwkAddr)
	{
		return DEST_IS_DEVSELF;
	}
	else
	{
		i = unet_tree_routing(TxPtr);

		if(i == NEXT_HOP_NOT_AVAILABLE)
		{  //Check the destination if allready link to devself by self-healing
			//if(!unet_check_child(TxPtr->NwkDstAddr, NULL))
			//	return NEXT_HOP_NOT_AVAILABLE;   // The destination does not link to devself
			TxPtr->MHR.DstAddr = TxPtr->NwkDstAddr; // Send to the child directly
		}
		else if(i == TREE_ROUTING_FAILED)
		{
			return TREE_ROUTING_FAILED;  
		}	
		TxPtr->MHR.Header.val |= 0x0020;
	}
	MSG_Copy(&RF_TX_BUFF[sizeof(MAC_DATA_PKT)], DataPtr, Length);
	
	if(UzTx(RF_TX_BUFF, sizeof(MAC_DATA_PKT) + Length)) return SUCCESS;

#ifndef I_Am_Coordinator
	
	if(TxPtr->MHR.DstAddr == UnetSys.JoinParent)
	{
		if(unet_self_healing() == SELF_HEAL_SUCCESS)
			goto TX_DATA_LABEL;
		
		return SELF_HEAL_FAILED; //Coordinator die
	}
#endif

	return NEXT_HOP_NOT_AVAILABLE;

}


UINT8 RECV_FROM_UNET(UINT8 *Buff){
	struct _data_list_ *TmPtr;
	UINT8 Length;

	if(UnetSys.DataCnt >0)
	{			
		TmPtr = UnetSys.DataHead;
		Length = TmPtr->Length;

		MSG_Copy(Buff, TmPtr->Msg, Length);

		UnetSys.DataHead = TmPtr->Next;
		UnetSys.DataCnt -= 1;
		
		MSG_Free(TmPtr->Msg);
		MSG_Free(TmPtr);
		
		return Length;
	}

	return 0;
}


UINT8 CHECK_UNET_DATA(){

	unet_proc();

	return UnetSys.DataCnt;
}


/*******************************************************************************

	Unet Sub Function
					
********************************************************************************/

void unet_init(){
	void *Temp;
	UINT8 *p;
	
	UnetSys.JoinPID = 0xffff; //Join pan id
	UnetSys.Channel = 0xff; // Join channel
	UnetSys.JoinParent = 0xffff; // Join parent address
	UnetSys.OrigParent = 0xffff; 
	UnetSys.JoinRouterCnt = 0; // Join router count
	UnetSys.JoinEndevCnt = 0; // Join end device count
	UnetSys.NwkAddr = 0xffff; // Network address (short address)
	UnetSys.DevDep = 0xff; // Device depth
	UnetSys.NextAddr = 0xff; // Next available short address
	UnetSys.AddrInc = 0xff; // Address increment
	UnetSys.MacBSN = 0; // Mac broadcast sequence number 
	UnetSys.MacDSN = 0; // Mac packet (Data or Command) sequence number
	
	*((UINT8 *) &UnetSys.IntFlag) = 0; // Interrupt Flag
//	*((UINT16 *) &UnetSys.Flag) = 0; // System Flag
	p = ((UINT8 *) &UnetSys.Flag); // System Flag
	*p = 0; // System Flag
	*(p+1) = 0;
	MSG_Init(&CommQueue);
	MSG_Init(&DataQueue);

	UnetSys.BcnHead = NULL;
	clear_table((void *) &UnetSys.BcnHead);
	clear_table((void *) &UnetSys.ChildHead);
	UnetSys.ChildHead = NULL;
	clear_table((void *) &UnetSys.BroHead);
	UnetSys.BroHead = NULL;

	while(UnetSys.DataHead != NULL){
		Temp = (void *) UnetSys.DataHead; // Temp = Head->Next
		UnetSys.DataHead = ((struct _data_list_ *) Temp)->Next; // Head = Temp-Next
		MSG_Free(((struct _data_list_ *) Temp)->Msg);
		MSG_Free(Temp);
	}
	UnetSys.DataHead = NULL;
	UnetSys.DataCnt = 0;
	
	stAddrList.ucAddrCont = 0;
	stCommandCFM.val = 0;
}


UINT8 unet_tx_bcn(){
	MAC_BCN_PKT *BcnPtr;

	//if(UnetSys.Flag.ChildFull)
	//	return DISCARD_FRAME;

	BcnPtr = (MAC_BCN_PKT *) RF_TX_BUFF;

	BcnPtr->Header.val = 0x8000;
	BcnPtr->SrcAddr = UnetSys.NwkAddr;
	BcnPtr->SrcPID = UnetSys.JoinPID;
	BcnPtr->Seqnum = UnetSys.MacBSN;
	UnetSys.MacBSN++;
	BcnPtr->GTSF = 0;
	BcnPtr->PASF = 0;

	MSG_Copy(&BcnPtr->PAYLOAD,  &UnetSys.BcnPayload, sizeof(MAC_BP));

	if(UnetSys.Flag.PanCoordinator){
		BcnPtr->SFS = 0xc00f;
	}else if(UnetSys.Flag.Router){
		BcnPtr->SFS = 0x800f;
	}
			
	if(UzTx(RF_TX_BUFF, sizeof(MAC_BCN_PKT)))
		return SUCCESS;

	return RETRY_EXCEED;
}


UINT8 unet_tx_bcn_req(void){
	MCP_BCN_REQ *CmdPtr;
	
	CmdPtr = (MCP_BCN_REQ *) RF_TX_BUFF;

	CmdPtr->Header.val = 0x0803;
	CmdPtr->DstAddr = 0xffff;
	CmdPtr->DstPID = 0xffff;
	CmdPtr->Seqnum = UnetSys.MacDSN;	
	UnetSys.MacDSN++;
	CmdPtr->COMM_ID = MT_BEACON_REQ;

	if(UzTx(RF_TX_BUFF, sizeof(MCP_BCN_REQ)))
		return SUCCESS;
	
	return RETRY_EXCEED;
}


UINT8 unet_rx_bcn_ind(MAC_BCN_PKT *BcnPkt, UINT8 Length){
	UINT8 *TmPtr;

	//if(UnetSys.Flag.JoinNetwork){
		// if realiment??
	//}

	TmPtr = (UINT8 *) BcnPkt;

	DBG_tag();

	if(insert_node((void *) &UnetSys.BcnHead ,(void *) &UnetSys.BcnTail, BEACON ) == NULL)
		return FAILURE;

       UnetSys.BcnTail->PID = BcnPkt->SrcPID;
	UnetSys.BcnTail->Addr = BcnPkt->SrcAddr;
	UnetSys.BcnTail->Channel = UnetSys.Channel;
	UnetSys.BcnTail->SfSpec = BcnPkt->SFS;
	UnetSys.BcnTail->DevDep = BcnPkt->PAYLOAD.DevDep;
////	UnetSys.BcnTail->LinkQuality = *(TmPtr+ sizeof(MAC_BCN_PKT) + 3); // 2 + 1 = FCS + LQI, (LinkQuality = RSSI)
	UnetSys.BcnTail->LinkQuality = UzReadRSSI();
	UnetSys.BcnTail->Next = NULL;
	
	return SUCCESS;
}


UINT8 unet_tx_asso_req(void){
	MCP_ASSO_REQ *AssoPtr;

	DBG_tag();

	AssoPtr = (MCP_ASSO_REQ *) RF_TX_BUFF;

	AssoPtr->Header.val = 0xc823;
	AssoPtr->SrcPID = UnetSys.JoinPID;

	MSG_Copy(AssoPtr->SrcAddr, MAC_ADDRESS, 8);
		
	AssoPtr->DstAddr = UnetSys.JoinParent;
	AssoPtr->DstPID = UnetSys.JoinPID;
	AssoPtr->Seqnum = UnetSys.MacDSN;	
	UnetSys.MacDSN++;
	AssoPtr->COMM_ID = MT_ASSO_REQ;
	//AssoPtr->Cap.val = 0xca;
	AssoPtr->Cap = 0xca;

	if(UzTx(RF_TX_BUFF, sizeof(MCP_ASSO_REQ)))
		return SUCCESS;

	return RETRY_EXCEED;
}

/****************************************************************************************
*  	Function: 
*  	Description: 处理连接请求命令帧
*  	Syntax: 
*	Modify: 
*	parameter:  无
*  	Returns:    无
*  	Notes: 
*	Date: 2007-04-03
*	Author: ZijianWang
****************************************************************************************/
UINT8 unet_rx_asso_req(MCP_ASSO_REQ *MsgPtr)
{
	struct _child_list_ *ChiPtr;
	MCP_ASSO_RSP *RsPtr;
	UINT8 i;
	
	DBG_tag();

	RsPtr = (MCP_ASSO_RSP *) RF_TX_BUFF;
	ChiPtr = UnetSys.ChildHead;
	while(ChiPtr != NULL)		//如果当前子节点指针里有东西,(即存在子节点)
	{
		if(memcmp(ChiPtr->MacAddr, MsgPtr->SrcAddr, 8) == 0) //且该子节点地址与收到的连接请求帧子地址一样
		{
			RsPtr->ShortAddr = ChiPtr->NetworkAddress;
			RsPtr->AssoStatus = ASSOCIATION_SUCCESS;
			if(ChiPtr->Available == 0)

⌨️ 快捷键说明

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