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

📄 macp.nc

📁 IEEE802.15.4标准下的基于ZIGBEE协议栈的物理及链路层的代码
💻 NC
📖 第 1 页 / 共 3 页
字号:
/** * */#include "ZBMAC.h"module MacP {	provides interface Init;	provides interface SplitControl;	provides interface MldeSap;	provides interface MlmeSap;	uses interface SplitControl as PhyControl;  	uses interface PdSap;	uses interface PlmeSap;  	uses interface Alarm<T32khz,uint32_t> as MacTimer;		uses interface Mem;	uses interface ZbCache<mac_send_cache_t> as SendCache;		uses interface ZbCache<mac_receive_cache_t> as ReceiveCache;		uses interface Leds;}implementation {/** * request beacon frame * FCF(2)+DSN(1)+DST_PANID(2)+DST_SADDR(2)+CMD_TYPE(1)+FCS(2) * * beacon frame format * FCF(2)+DSN(1)+SOURCE_PANID(2)+SOURCE_SADDR(2)+BEACON_INFO(2)+|-->PROTOCOL_ID(1)+NWK_INFO(2)+IEEEADDR(8)<--| * * assoc request packet * FCF(2)+DSN(1)+DST_PANID(2)+DST_SADDR(2)+SOURCE_PANID(2,0xffff)+SOURCE_LADDR(8)+CMD_TYPE(1)+CAP_INFO(1)+|ZIGBEE_NUM(4)| * length = 2+1+2+2+2+8+1+1+4 = 23  * * association response frame format:  * FCF(2)+DSN(1)+DST_PANID(2)+DST_LADDR(8)+SOURCE_PANID(2)+SOURCE_LADDR(8)+CMD_TYPE(1)+SADDR(2)+ASSOC_STATUS(1) * length = 2+1+2+8+2+8+1+2+1 = 27 **/  #define BEACON_REQ_FRAME_LEN		2+1+2+2+1#define BEACON_DEF_PAYLOAD_LEN	1+2+8#define BEACON_MAX_PAYLOAD_LEN	BEACON_DEF_PAYLOAD_LEN#define BEACON_FRAME_LEN			BEACON_MAX_PAYLOAD_LEN + 2 + 1 + 2 + 2 + 2 #define ASSOC_REQ_FRAME_LEN		2+1+2+2+2+8+1+1+4#define ASSOC_WAIT_TIME			1024*32	//32us unit #define ASSOC_RESPON_FRAME_LEN	2+1+2+8+2+8+1+2+1#define PHY_HEAD_LEN	1		//1 byte length field/*** mac state enum ****/typedef enum {	S_STOPPED,	S_STARTING,	S_IDLE,	S_SCANNING,	S_SCAN_DONE,	#ifdef IS_COORD	S_ESTABLISHING,	S_ESTABLISHED,#endif#ifndef IS_COORD				S_JOINING,	S_JOINED,#endif		S_STOPPING,} mac_state_t;  /**** send state enum *****/ typedef enum {	SEND_IDLE,	SEND_BUSY,} send_state_t;/******** send task use mac_send_cache_t.type to distinguish packet. ********/enum {	TYPE_DATA,	TYPE_BEACON,	CMD_ASSOC_REQ,	CMD_ASSOC_RESPON,	CMD_BEACON_REQ,	CMD_ORPHAN_NOTIFY,	CMD_COORD_REALIGN,	CMD_DISASSOC_NOTIFY,};		  /*** next hight layer's parameter store into this type when sending data ***/ typedef struct {	uint8_t length;	mem_head_t* pmsdu;	error_t error;} send_parameter_t;/** below variable use to control next high layer send data. **/norace bool dataSendPending = FALSE;send_parameter_t sendParameter;task void sendDone_task();norace send_state_t send_state = SEND_IDLE;norace mac_state_t mac_state = S_STOPPED;norace mac_pib_t macPib;/** use by positive scanning **/ pan_descriptor_t panDescriptorTable[MAX_PAN_DESCRIPTOR_NUM];/*** if this value is 0, indicate scan failed beacause no pan_descriptor_t have store in panDescriptorTable. **/uint8_t panDescriptorNum;/** scan done task **/task void positiveScanDone_task();/** next high layer should get and set beaconPayload contents ***/uint8_t beaconPayload[BEACON_MAX_PAYLOAD_LEN];/** received mac frame header parameter **/typedef struct {	uint16_t fcf;	uint8_t type;	uint8_t dstAddrMode;	uint8_t srcAddrMode;		nxle_uint8_t dsn;	nxle_uint16_t dstPanId;	addr_union_t dstAddr;	nxle_uint16_t srcPanId;	addr_union_t srcAddr;} receive_head_t;/** used by parseHead() function **/receive_head_t receiveHead;/** receiveTask call this function to parse mac head into receiveHead **/void parseHead(mem_head_t* pMacPkt);/** join done task **/task void joinDone_task();/** used for joinDone_task() **/mac_error_t joinDoneError;saddr_t joinAssignedAddr;/** sendTask's task is getting a packet from mac_send_cache and send it. **/task void sendTask();/** receiveTask's task is to getting a packet from mac_receive_cache and handle it. **/task void receiveTask();/** use to fill in pBeaconPkt with propriety beacon parameter. **/void generateBeacon(mem_head_t* pBeaconPkt);/** store beacon parameter into panDescritorTable. **/void handleBeacon(uint8_t length, uint8_t* pBuf, uint8_t lqi); /***************** function start *********************/command error_t Init.init(){	mac_state = S_STOPPED;		send_state = SEND_IDLE;	return SUCCESS;}command error_t SplitControl.start(){	if(mac_state != S_STOPPED){		return FAIL;	}	mac_state = S_STARTING;	call PhyControl.start();		return SUCCESS;}command error_t SplitControl.stop(){	if(mac_state != S_IDLE){		return FAIL;	}	mac_state = S_STOPPING;	call PhyControl.stop();		return SUCCESS;}/** * shuld set all mac layer module variable into default value if error == SUCCESS.  **/event void PhyControl.startDone(error_t error){	if(error == SUCCESS){		/** set mac_state ***/		mac_state = S_IDLE;				/** set pan descriptor table **/		panDescriptorNum = 0;				/*** there shuld only one next high layer frame pending in SendCache ***/			dataSendPending = FALSE;	  				/*** set mac pib ***/		macPib.bits.macAssociationPermit = TRUE;		macPib.bits.ifReceiveAllFrame = TRUE;		macPib.bits.macRxOnWhenIdle = FALSE;				/*** set mac dsn to 0 ***/		macPib.macDsn = 0;				/*** set macPib.pPanId point at phyPib.panId ***/		macPib.pPanId = call PlmeSap.getPanId();				/*** set macPib.pShortAddr point at phyPib.shortAddress **/		macPib.pShortAddr = call PlmeSap.getShortAddr();  				/*** set macPib.pLongAddr point at phyPib.longAddress ***/		macPib.pLongAddr = call PlmeSap.getLongAddr();				signal SplitControl.startDone(SUCCESS);	}	else{		mac_state = S_STOPPED;		signal SplitControl.startDone(FAIL);	}		}event void PhyControl.stopDone(error_t error){	if(error == SUCCESS){		mac_state = S_STOPPED;		signal SplitControl.stopDone(SUCCESS);			}	else{		mac_state = S_IDLE;		signal SplitControl.stopDone(FAIL);	}				}event void PlmeSap.directSetShortAddrDone(error_t error){	#ifndef IS_COORD	if(error == SUCCESS){		mac_state = S_JOINED;		post joinDone_task();	}	else{		mac_state = S_SCAN_DONE;		joinDoneError = FAIL;		post joinDone_task();		}		#endif	}/** * currently only use default channel, parameter scanChannel is not use  * * scanDuration range from 0-14, * scan time is ( aBaseSuperframeDuration (60*16symbol period) ) * ( 2**scanDuration + 1 ) * symbol period is 64k. * * request beacon frame * FCF(2)+DSN(1)+DST_PANID(2)+DST_SADDR(2)+CMD_TYPE(1) **/  command error_t MlmeSap.positiveScan(uint32_t scanChannel, uint8_t scanDuration){	uint8_t i;		/*** use for calculate scan time duration ***/	uint32_t scanTime = 1;		/*** point to beacon request frame memory block ***/	mem_head_t* pScanPkt;		/*** use to fill data **/	uint8_t* p;		/*** a SendCache element pointer ***/	mac_send_cache_t* pSendCache;		if(mac_state != S_IDLE){		return FAIL;	}	if(scanDuration > 14){		return FAIL;	}		/** malloc beacon request frame memory block and get a pointer to SendCache element **/ 	if( ( call Mem.malloc( &pScanPkt, (BEACON_REQ_FRAME_LEN + PHY_HEAD_LEN) ) ) != SUCCESS ){		return FAIL;	}	if( ( pSendCache = call SendCache.fetchFree() ) == NULL ){		call Mem.free(pScanPkt);		return FAIL;	}			/** set p point at end of memory block **/		p = (uint8_t*)pScanPkt + call Mem.getSize(pScanPkt);		/** set mac cmd type **/	p--;	*p = MAC_CMD_TYPE_BEACON_REQ;		/** add destination broadcast address **/	p -= 2;	*(nxle_uint16_t*)p = 0xFFFF;		/** add destination broadcast pan id **/	p -= 2;	*(nxle_uint16_t*)p = 0xFFFF;		/** set mac dsn **/	p--;	*p = macPib.macDsn++;		/** set fcf **/	p -= 2;	*(nxle_uint16_t*)p = ( MAC_FRAME_TYPE_CMD << POS_MAC_FRAME_TYPE ) |					 ( 0 << POS_MAC_SECURITY ) |					 ( 0 << POS_MAC_FRAME_PENDING ) |					 ( 0 << POS_MAC_ACK_REQUEST ) |					 ( 1 << POS_MAC_INTRA_PAN ) |					 ( MAC_ADDR_MODE_SHORT << POS_MAC_DEST_ADDR_MODE ) |				 					 ( MAC_ADDR_MODE_NONE << POS_MAC_SOURCE_ADDR_MODE );					 	/*** set memory current position **/				 	call Mem.setCurrentPos( pScanPkt, (p - (uint8_t*)pScanPkt) );		/** calculate scan time, in symbol unit **/	for(i=0; i<scanDuration; i++){		scanTime *= 2;	}	scanTime++;		/*** 60*16)/2 is aBaseSuperframeDuration in 32k time unit ***/	scanTime *= (60*16)/2;			/** fill SendCache element **/	pSendCache->type = CMD_BEACON_REQ;	pSendCache->psdu = pScanPkt;	pSendCache->isAckSend = FALSE;		/*** dsn isn't use when isAckSend == FALSE ***/	pSendCache->dsn = macPib.macDsn - 1;			/** put it into SendCache **/	call SendCache.putFull(pSendCache);	post sendTask();		mac_state = S_SCANNING;		/*** set scan duration timer ***/	call MacTimer.start(scanTime);	return SUCCESS;		 	  	}#ifdef IS_COORD/*** * **/command error_t MlmeSap.establish(uint8_t channel, panid_t panId){	uint8_t* p = beaconPayload;	uint8_t i;		if(mac_state != S_IDLE){		return FAIL;	}		/** 	 * set beacon payload.	 * if this node is a router, beacon payload shuld be set by next high layer after signal joinDone.	 **/	macPib.beaconPayloadLen = BEACON_DEF_PAYLOAD_LEN;			/*** set PROTOCOL_ID ***/	*p = PROTOCOL_ID;	p++;			/*** set NWK_INFO filed ***/	*(nxle_uint16_t*)p = ( NWK_INFO_STACK_PROFILE_ID << POS_NWK_INFO_STACK_PROFILE ) |					 ( NWK_INFO_VERSION_ID << POS_NWK_INFO_VERSION ) |					 ( 1 << POS_NWK_INFO_ROUTER_CAP ) |					 ( 0 << POS_NWK_INFO_DEPTH ) |					 ( 1 << POS_NWK_INFO_END_DEVICE_CAP );		/*** set IEEE address field ***/   	p += 2;//	*(laddr_t*)p = *(macPib.pLongAddr);		for(i=0; i<8; i++){		*p++ = macPib.pLongAddr->bytes[i];	}		/*** set short address to 0 **/	call PlmeSap.setShortAddr(0);		/*** set pan id ***/	call PlmeSap.setPanId(panId);		/*** sync with cc2420 ram ***/	call PlmeSap.sync();	mac_state = S_ESTABLISHING;		return SUCCESS;}#endifevent void PlmeSap.syncDone(error_t error){	/*** coordinator establishing ***/	#ifdef IS_COORD	if(error == SUCCESS){		mac_state = S_ESTABLISHED;		signal MlmeSap.establishDone(SUCCESS);	}	else{		mac_state = S_IDLE;		signal MlmeSap.establishDone(FAIL);	}	#endif		/**** router or rfd joinning ***/	#ifndef IS_COORD	if(error == SUCCESS){		mac_state = S_JOINED;		signal MlmeSap.joinDone(joinAssignedAddr, joinDoneError);	}	else{		mac_state = S_SCAN_DONE;		joinDoneError = FAIL;		signal MlmeSap.joinDone(joinAssignedAddr, joinDoneError);	}	 	#endif}#ifndef IS_COORD/** * assoc request packet * FCF(2)+DSN(1)+DST_PANID(2)+DST_SADDR(2)+SOURCE_PANID(2,0xffff)+SOURCE_LADDR(8)+CMD_TYPE(1)+CAP_INFO(1)+|ZIGBEE_NUM(4)|+FCS(2) * length = 2+1+2+2+2+8+1+1+4 = 23 **/command error_t MlmeSap.joinRequest(uint8_t descriptorSequence, uint8_t myCapInfo){	mac_send_cache_t* pSendCache;	mem_head_t* pJoinPkt;	pan_descriptor_t* pdt;	uint8_t* p;	uint8_t i;		if( descriptorSequence >= MAX_PAN_DESCRIPTOR_NUM ){		return FAIL;	}	if(mac_state != S_SCAN_DONE){		return FAIL;	}		/** malloc associate request frame memory block and get a pointer to SendCache element **/ 		if( ( call Mem.malloc(&pJoinPkt, ASSOC_REQ_FRAME_LEN+PHY_HEAD_LEN) ) != SUCCESS){		return FAIL;	}	if( ( pSendCache = call SendCache.fetchFree() ) == NULL ){		call Mem.free(pJoinPkt);		return FAIL;	}		/** set pdt point at intent father node's descriptor **/	pdt = &panDescriptorTable[descriptorSequence]; 		/*** pre set intent father's pan id, short address and long address **/ 	call PlmeSap.setPanId(pdt->panId);

⌨️ 快捷键说明

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