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

📄 macp.nc

📁 IEEE802.15.4标准下的基于ZIGBEE协议栈的物理及链路层的代码
💻 NC
📖 第 1 页 / 共 3 页
字号:
	macPib.macCoordShortAddress = pdt->shortAddr;	for(i=0; i<8; i++){		macPib.macCoordExtendedAddress.bytes[i] = pdt->extendedAddr.bytes[i];	}	/** set p point at end of memory block **/	p = (uint8_t*)pJoinPkt + call Mem.getSize(pJoinPkt);		/** set ZIGBEE_NUM **/	p--;	*p = ZIGBEE_NUM_3;	p--;	*p = ZIGBEE_NUM_2;	p--;	*p = ZIGBEE_NUM_1;	p--;	*p = ZIGBEE_NUM_0;			/** set capability information **/	p--;	*p = myCapInfo;		/** set mac cmd type field **/	p--;	*p = MAC_CMD_TYPE_ASSOC_REQ;		/** set source address field with long address **/	p -= 8;	for(i=0; i<8; i++){		*(p+i) = macPib.pLongAddr->bytes[i];	}		/** set source pan id filed with broadcast pan id **/	p -= 2;	*(uint16_t*)p = 0xffff;		/** set destination address field with intent father's short address **/	p -= 2;	*(saddr_t*)p = pdt->shortAddr;		/** set destination pan id field with intent father' pan id **/	p -= 2;	*(nxle_uint16_t*)p = pdt->panId;		/** 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 ) |					 ( 1 << POS_MAC_ACK_REQUEST ) |					 ( 0 << POS_MAC_INTRA_PAN ) |					 ( MAC_ADDR_MODE_SHORT << POS_MAC_DEST_ADDR_MODE ) |				 					 ( MAC_ADDR_MODE_LONG << POS_MAC_SOURCE_ADDR_MODE );		/** set memory block position **/	call Mem.setCurrentPos( pJoinPkt, (p-(uint8_t*)pJoinPkt) );		/** fill SendCache element **/	pSendCache->isAckSend = TRUE;	pSendCache->type = CMD_ASSOC_REQ;	pSendCache->psdu = pJoinPkt;	pSendCache->dsn = macPib.macDsn - 1;			/** put into SendCache full queue **/	call SendCache.putFull(pSendCache);	mac_state = S_JOINING;		/** start associate wait timer **/	call MacTimer.start(ASSOC_WAIT_TIME);	return SUCCESS;}#endifasync event void MacTimer.fired(){	switch(mac_state){	case S_SCANNING:		post positiveScanDone_task();		break;	#ifndef IS_COORD		case S_JOINING:		/** have not detected right associate response frame in ASSOC_WAIT_TIME **/		joinDoneError = FAIL;		joinAssignedAddr = 0;		post joinDone_task();		break;		#endif		default:break;		}}/** * currently just support data sending in the same pan. * do not support GTS transmission, indirect transmission, security enabled transmission. * source short address and pan id will automatically add by mac layer module. * * mac data frame format: * fcf(2) + dsn(1) + destPan(2) + destAddr(2/8) + srcAddr(2/8) + payload **/command error_t MldeSap.send(uint8_t srcAddrMode, uint8_t dstAddrMode, addr_union_t destAddr, 					uint8_t length, mem_head_t* pmsdu, bool ackSend){	mac_send_cache_t* pSendCache;	uint8_t* p;	int8_t pos;	uint8_t i;		/** check pmsdu free space **/	pos = (int8_t)( call Mem.getCurrentPos(pmsdu) );	if( srcAddrMode == MAC_ADDR_MODE_LONG )		pos -= 8;	else		pos -= 2;	if( dstAddrMode == MAC_ADDR_MODE_LONG )		pos -= 8;	else		pos -= 2;	if(pos < 6 ){	// 5 = fcf + dsn + destPanId + PHY_HEAD_LEN			return FAIL;	}					/** dataSendPending is TRUE indicate MldeSap.send have been called without signal MldeSap.sendDone **/ 	if(dataSendPending){		return FAIL;	}	#ifdef IS_COORD	if(mac_state != S_ESTABLISHED){		return FAIL;	}	#endif	#ifndef IS_COORD 	if(mac_state != S_JOINED){ 		return FAIL; 	}	#endif	/** get a full element in SendCache **/	if( ( pSendCache = call SendCache.fetchFree() ) == NULL ){		return FAIL;	}	/** store MldeSap.send parameter **/	sendParameter.length = length;	sendParameter.pmsdu = pmsdu;		/** set p point at the beginning of mac payload **/		p = (uint8_t*)pmsdu + call Mem.getCurrentPos(pmsdu);		/** add sourse address **/	if(srcAddrMode == MAC_ADDR_MODE_LONG){		p -= 8;		for(i=0; i<8; i++){			*(p+i) = macPib.pLongAddr->bytes[i];		}	}		/** MAC_ADDR_MODE_SHORT and other **/	else{			p -= 2;		*(saddr_t*)p = *(macPib.pShortAddr);	}		/** add dest address **/		if(dstAddrMode == MAC_ADDR_MODE_LONG){		p -= 8;		for(i=0; i<8; i++){			*(p+i) = destAddr.laddr.bytes[i];		}			}		/*** MAC_ADDR_MODE_SHORT and other ***/	else{			p -= 2;		*(saddr_t*)p = destAddr.saddr;	} 				/** add pan id **/	p -= 2;	*(nxle_uint16_t*)p = *(macPib.pPanId);		/** add dsn **/	p--;	*p = macPib.macDsn++;		/** add fcf **/	p -= 2;	*(nxle_uint16_t*)p = (MAC_FRAME_TYPE_DATA << POS_MAC_FRAME_TYPE) |					 (0 << POS_MAC_SECURITY) |					 (0 << POS_MAC_FRAME_PENDING) |					 (ackSend << POS_MAC_ACK_REQUEST) |					 (1 << POS_MAC_INTRA_PAN) |					 ( (dstAddrMode&0x3) << POS_MAC_DEST_ADDR_MODE ) |					 ( (srcAddrMode&0x3) << POS_MAC_SOURCE_ADDR_MODE );		/** set memory position at the start of mac fcf field **/				 	call Mem.setCurrentPos(pmsdu, (p - (uint8_t*)pmsdu) );		/** fill SendCache element **/	pSendCache->type = TYPE_DATA;	pSendCache->isAckSend = ackSend;			pSendCache->psdu = pmsdu;	pSendCache->dsn = macPib.macDsn - 1;		/** put into SendCache. **/	call SendCache.putFull(pSendCache);	return SUCCESS;				}task void sendTask(){	mac_send_cache_t* pSendCache;		if(send_state != SEND_IDLE){		post sendTask();		return;	}	if( ( pSendCache = call SendCache.getFull() ) == NULL){		post sendTask();		return;	}	/*** send different frame ***/	if( call PdSap.send(pSendCache->psdu, pSendCache->isAckSend, pSendCache->dsn) != SUCCESS ){		call SendCache.fetchFull();		call SendCache.putFree(pSendCache);		post sendTask();			switch (pSendCache->type){		case TYPE_DATA:			sendParameter.error = FAIL;			post sendDone_task();				break;		#ifndef IS_COORD			case CMD_BEACON_REQ:			mac_state = S_IDLE;			call MacTimer.stop();			post positiveScanDone_task();			break;		case CMD_ASSOC_REQ:			mac_state = S_SCAN_DONE;			call MacTimer.stop();			joinDoneError = FAIL;			joinAssignedAddr = 0;			post joinDone_task();			break;		#endif			case TYPE_BEACON:		case CMD_ASSOC_RESPON:					default:break;			}	}	else{		send_state = SEND_BUSY;	}}									event void PdSap.sendDone(error_t error, mem_head_t* psdu){	mac_send_cache_t* pSendCache;		/*** fetch the frame just send ***/	pSendCache = call SendCache.fetchFull();	switch(pSendCache->type){	case TYPE_DATA:		sendParameter.error = error;		post sendDone_task();		break;		#ifndef IS_COORD		case CMD_BEACON_REQ:			if(error == FAIL){			mac_state = S_IDLE;						post positiveScanDone_task();						/** stop wait beacon timer **/			call MacTimer.stop();		}				/** this packet is generate in mac layer module, so should be freed by mac layer module. **/		call Mem.free(pSendCache->psdu);		break;		case CMD_ASSOC_REQ:		if(error == FAIL){			mac_state = S_SCAN_DONE;			call MacTimer.stop();				joinDoneError = FAIL;			joinAssignedAddr = 0;			post joinDone_task();		}		call Mem.free(pSendCache->psdu);										break;		#endif		case TYPE_BEACON:	case CMD_ASSOC_RESPON:		default:		call Mem.free(pSendCache->psdu);		break;			}			send_state = SEND_IDLE;			/*** put this SendCache elment into free queue ***/ 	call SendCache.putFree(pSendCache);			/*** sendTask can send frame when send_state == SEND_IDLE ***/	post sendTask();			}task void sendDone_task(){	uint8_t pos;	pos = call Mem.getCurrentPos(sendParameter.pmsdu);		/** set memory block position at the beginning of mac layer payload **/	call Mem.setCurrentPos( sendParameter.pmsdu, (pos+sendParameter.length) );	signal MldeSap.sendDone(sendParameter.error, sendParameter.pmsdu);	dataSendPending = FALSE;}event void PdSap.receive(uint8_t length, mem_head_t* psdu, uint8_t lqi){	mac_receive_cache_t* pReceiveCache;	if( ( pReceiveCache = call ReceiveCache.fetchFree() ) != SUCCESS ){		call Mem.free(psdu);		return;	}	pReceiveCache->lqi = lqi;	pReceiveCache->length = length;	pReceiveCache->psdu = psdu;	call ReceiveCache.putFull(pReceiveCache);}task void receiveTask(){	uint8_t* p;	uint8_t length;	mac_receive_cache_t* pReceiveCache;		/** mac cmd frame type **/	uint8_t cmdType;		/** generate mac layer frame when needed after receiving mac cmd packet **/	mem_head_t* pSendPkt;	mac_send_cache_t* pSendCache;		/** used when receive associate request frame or associate response frame **/	saddr_t assignedAddr;	mac_error_t assocError;	uint8_t capInfo;		uint8_t i;	/*** no frame in receive cache ***/		if( ( pReceiveCache = call ReceiveCache.fetchFull() ) == NULL ){		post receiveTask();		return;	}		/** parse mac head into receiveHead and set psdu to payload position **/	parseHead(pReceiveCache->psdu);			/** calculate mac frame payload beginning position **/  	p = (uint8_t*)pReceiveCache->psdu + call Mem.getCurrentPos(pReceiveCache->psdu);		/** 	 * get mac frame payload length, length1 is length + 2(FCS) 	 * length1 = call Mem.getSize(pReceiveCache->psdu) - call Mem.getCurrentPos(pReceiveCache->psdu);	 **/	length = call Mem.getSize(pReceiveCache->psdu) - call Mem.getCurrentPos(pReceiveCache->psdu) - 2;	/*** 	 * check fcf first 	 * security and frame pending bit shuld not be set, ACK bit field do not care	 **/	if( ( ( (receiveHead.fcf&MASK_MAC_SECURITY) >> POS_MAC_SECURITY ) == 1 ) ||	    ( ( (receiveHead.fcf&MASK_MAC_FRAME_PENDING) >> POS_MAC_FRAME_PENDING ) == 1 ) ){		    	call Mem.free(pReceiveCache->psdu);		    	call ReceiveCache.putFree(pReceiveCache);				post receiveTask();				return;	}		/** handle different frame type **/	switch(receiveHead.type){	case MAC_FRAME_TYPE_BEACON:		if(mac_state == S_SCANNING){			handleBeacon(length, p, pReceiveCache->lqi);		}			call Mem.free(pReceiveCache->psdu);				break;	case MAC_FRAME_TYPE_DATA:		#ifdef IS_COORD		if(mac_state != S_ESTABLISHED){		    	call Mem.free(pReceiveCache->psdu);		    	call ReceiveCache.putFree(pReceiveCache);				post receiveTask();				return;		}		#endif		#ifndef IS_COORD	 	if(mac_state != S_JOINED){		    	call Mem.free(pReceiveCache->psdu);		    	call ReceiveCache.putFree(pReceiveCache);				post receiveTask();				return;	 	}		#endif				/** 		 * mac data frame format:		 * fcf(2) + dsn(1) + destPan(2) + destAddr(2/8) + srcAddr(2/8) + payload		 *		 * currently do not support receiving frame from different pan 		 * address field must be short address or long address		 **/  		if( ( (receiveHead.fcf&MASK_MAC_INTRA_PAN) == 0 ) || (receiveHead.dstAddrMode == MAC_ADDR_MODE_NONE) ||								(receiveHead.srcAddrMode == MAC_ADDR_MODE_NONE) ){		    	call Mem.free(pReceiveCache->psdu);		    	call ReceiveCache.putFree(pReceiveCache);				post receiveTask();				return;		}		    							/** notify next high layer **/			signal MldeSap.receive(receiveHead.srcAddrMode, receiveHead.srcAddr, receiveHead.dstAddrMode, 				receiveHead.dstAddr, length, pReceiveCache->psdu, pReceiveCache->lqi);																	break;	case MAC_FRAME_TYPE_CMD:		/** get cmd frame type **/		cmdType = *(uint8_t*)p;				/** skip cmd type field byte **/		p++;				/** handle different cmd frame **/		switch(cmdType){		/**		 * FCF(2)+DSN(1)+DST_PANID(2)+DST_SADDR(2)+CMD_TYPE(1)		 * length = 1;		 **/			case MAC_CMD_TYPE_BEACON_REQ:				/** free this memory block **/			call Mem.free(pReceiveCache->psdu);						/** check length filed **/			if(length != 1){		    		call ReceiveCache.putFree(pReceiveCache);								post receiveTask();					return;			}										/** coordinator must be in established mode to handle this frame **/			#ifdef IS_COORD			if(mac_state != S_ESTABLISHED){		    		call ReceiveCache.putFree(pReceiveCache);								post receiveTask();					return;			}			#endif						/** router must be in joined mode to handle this frame, be sure all node are FFD **/			#ifndef IS_COORD	 		if(mac_state != S_JOINED){		    		call ReceiveCache.putFree(pReceiveCache);	 								post receiveTask();					return;	 		}			#endif						/** malloc beacon frame memory block and get a pointer to SendCache element  **/			if( ( call Mem.malloc(&pSendPkt, BEACON_FRAME_LEN+PHY_HEAD_LEN) ) != SUCCESS ){		    		call ReceiveCache.putFree(pReceiveCache);								post receiveTask();					return;			}							if( ( ( pSendCache = call SendCache.fetchFree() ) == NULL ) ){				call Mem.free(pSendPkt);		    		call ReceiveCache.putFree(pReceiveCache);								post receiveTask();					return;			}			/** generate beacon and send it **/						generateBeacon(pSendPkt);						/** fill this SendCache element **/ 			pSendCache->type = TYPE_BEACON;			pSendCache->isAckSend = FALSE;			pSendCache->psdu = pSendPkt;			pSendCache->dsn = macPib.macDsn - 1;

⌨️ 快捷键说明

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