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

📄 p802_15_4mac.cc

📁 802.15.4 mac 协议源程序
💻 CC
📖 第 1 页 / 共 5 页
字号:
	||  ((frmCtrl.dstAddrMode == defFrmCtrl_AddrMode64)&&(wph->MHR_DstAddrInfo.addr_64 == mpib.macCoordExtendedAddress)))		return true;	else		return false;}double Mac802_15_4::locateBoundary(bool parent,double wtime){	//In the case that a node acts as both a coordinator and a device, 	//transmission of beacons is preferablly to be aligned with reception 	//of beacons to achieve the best results -- but we cannot control this.	//For example, the parent may originally work in non-beacon enabled mode	//and later on begin to work in beacon enabled mode; the parent will	//not align with the child since it is not supposed to handle the beacons	//from the child.	//So the alignment is specifically w.r.t. either transmission of beacons	//(as a coordinator) or reception of beacons (as a device), but there is	//no guarantee to satisfy both.		int align;				double bcnTxRxTime,bPeriod;	double newtime;		if ((mpib.macBeaconOrder == 15)&&(macBeaconOrder2 == 15))		return wtime;			if (parent)					align = (macBeaconOrder2 == 15)?1:2;	else						align = (mpib.macBeaconOrder == 15)?2:1;		bcnTxRxTime = (align == 1)?(macBcnTxTime / phy->getRate('s')):(macBcnRxTime / phy->getRate('s'));	bPeriod = aUnitBackoffPeriod / phy->getRate('s');	/* Linux floating number compatibility	newtime = fmod(CURRENT_TIME + wtime - bcnTxRxTime, bPeriod);	*/	{	double tmpf;	tmpf = CURRENT_TIME + wtime;	tmpf -= bcnTxRxTime;	newtime = fmod(tmpf, bPeriod);	}#ifdef DEBUG802_15_4	//fprintf(stdout,"[%s::%s][%f](node %d) delay = bPeriod - fmod = %f - %f = %f\n",__FILE__,__FUNCTION__,CURRENT_TIME,index_,bPeriod,newtime,bPeriod - newtime);#endif	if(newtime > 0.0)	{		/* Linux floating number compatibility		newtime = wtime + (bPeriod - newtime);		*/		{		double tmpf;		tmpf = bPeriod - newtime;		newtime = wtime + tmpf;		}	}	else		newtime = wtime;	return newtime;}void Mac802_15_4::txOverHandler(void){	assert(txPkt);	PD_DATA_confirm(p_UNDEFINED);}void Mac802_15_4::txHandler(void){	assert(txBcnCmd||txBcnCmd2||txData);	Packet *p;	hdr_lrwpan* wph;	hdr_cmn* ch;	UINT_8 t_numRetry;	if (txBcnCmd) p = txBcnCmd;	else if (txBcnCmd2) p = txBcnCmd2;	else p = txData;	wph = HDR_LRWPAN(p);	ch = HDR_CMN(p);	if (txBcnCmd) t_numRetry = numBcnCmdRetry;	else if (txBcnCmd2) t_numRetry = numBcnCmdRetry2;	else t_numRetry = numDataRetry;	t_numRetry++;#ifdef DEBUG802_15_4	if (t_numRetry <= aMaxFrameRetries)		fprintf(stdout,"[%s::%s][%f](node %d) No ACK - retransmitting: type = %s, src = %d, dst = %d, uid = %d, mac_uid = %ld, size = %d\n",__FILE__,__FUNCTION__,CURRENT_TIME,index_,wpan_pName(p),p802_15_4macSA(p),p802_15_4macDA(p),ch->uid(),wph->uid,ch->size());	else		fprintf(stdout,"[%s::%s][%f](node %d) No ACK - giving up: type = %s, src = %d, dst = %d, uid = %d, mac_uid = %ld, size = %d\n",__FILE__,__FUNCTION__,CURRENT_TIME,index_,wpan_pName(p),p802_15_4macSA(p),p802_15_4macDA(p),ch->uid(),wph->uid,ch->size());#endif	if (t_numRetry > aMaxFrameRetries)		nam->flashLinkFail(CURRENT_TIME,p802_15_4macDA(p));	dispatch(p_BUSY,__FUNCTION__);	//the status p_BUSY will be ignore}void Mac802_15_4::extractHandler(void){	if (taskP.taskStatus(TP_mlme_associate_request))		strcpy(taskP.taskFrFunc(TP_mlme_associate_request),__FUNCTION__);	dispatch(p_BUSY,__FUNCTION__);}void Mac802_15_4::assoRspWaitHandler(void){	dispatch(p_BUSY,__FUNCTION__);}void Mac802_15_4::dataWaitHandler(void){	dispatch(p_BUSY,__FUNCTION__);}void Mac802_15_4::rxEnableHandler(void){	dispatch(p_SUCCESS,__FUNCTION__);}void Mac802_15_4::scanHandler(void){	if (taskP.mlme_scan_request_ScanType == 0x01)		taskP.taskStep(TP_mlme_scan_request)++;			dispatch(p_SUCCESS,__FUNCTION__);}void Mac802_15_4::beaconTxHandler(bool forTX){	hdr_lrwpan* wph;	FrameCtrl frmCtrl;	TRANSACLINK *tmp;	int i;	if ((mpib.macBeaconOrder != 15)		//beacon enabled	|| (oneMoreBeacon))	if (forTX)	{		if (capability.FFD/*&&(numberDeviceLink(&deviceLink1) > 0)*/)		{			//enable the transmitter			beaconWaiting = true;			plme_set_trx_state_request(p_FORCE_TRX_OFF);	//finish your job before this!			//assert(txAck == 0);	//It's not true, for the reason that packets can arrive 						//at any time if the source is in non-beacon mode.						//This could also happen if a device loses synchronization						//with its coordinator, or if a coordinator changes beacon						//order in the middle.			if (txAck)			{#ifdef DEBUG802_15_4				if (!updateDeviceLink(tr_oper_est, &deviceLink1, &deviceLink2, p802_15_4macDA(txAck)))	//this ACK is for my child					fprintf(stdout,"[%f](node %d) outgoing ACK truncated by beacon: src = %d, dst = %d, uid = %d, mac_uid = %ld, size = %d\n", CURRENT_TIME,index_,p802_15_4macSA(txAck),p802_15_4macDA(txAck),HDR_CMN(txAck)->uid(),HDR_LRWPAN(txAck)->uid,HDR_CMN(txAck)->size());#endif				Packet::free(txAck);				txAck = 0;			}			plme_set_trx_state_request(p_TX_ON);		}		else			assert(0);	}	else	{		if (capability.FFD/*&&(numberDeviceLink(&deviceLink1) > 0)*/)	//send a beacon here		{			//beaconWaiting = false;							if ((taskP.taskStatus(TP_mlme_start_request))					&&  (mpib.macBeaconOrder != 15))			{				if (txAck||backoffStatus == 1)				{					beaconWaiting = false;					bcnTxT->start();					return;				}			}#ifdef DEBUG802_15_4			fprintf(stdout,"[%s::%s][%f](node %d) before alloc txBeacon:\n\t\ttxBeacon\t= %ld\n\t\ttxAck   \t= %ld\n\t\ttxBcnCmd\t= %ld\n\t\ttxBcnCmd2\t= %ld\n\t\ttxData  \t= %ld\n",__FILE__,__FUNCTION__,CURRENT_TIME,index_,txBeacon,txAck,txBcnCmd,txBcnCmd2,txData);#endif			if (updateNFailLink(fl_oper_est,index_) == 0)			{				if (txBeacon)				{					Packet::free(txBeacon);					txBeacon = 0;				}				beaconWaiting = false;				bcnTxT->start();				return;			}			assert(!txBeacon);			txBeacon = Packet::alloc();			if (!txBeacon)			{				bcnTxT->start();		//try to restore the transmission of beacons next time				return;			}			wph = HDR_LRWPAN(txBeacon);			frmCtrl.FrmCtrl = 0;			frmCtrl.setFrmType(defFrmCtrl_Type_Beacon);			frmCtrl.setSecu(secuBeacon);			frmCtrl.setAckReq(false);			frmCtrl.setDstAddrMode(defFrmCtrl_AddrModeNone);			if (mpib.macShortAddress == 0xfffe)			{				frmCtrl.setSrcAddrMode(defFrmCtrl_AddrMode64);				wph->MHR_SrcAddrInfo.panID = mpib.macPANId;				wph->MHR_SrcAddrInfo.addr_64 = aExtendedAddress;			}			else			{				frmCtrl.setSrcAddrMode(defFrmCtrl_AddrMode16);				wph->MHR_SrcAddrInfo.panID = mpib.macPANId;				wph->MHR_SrcAddrInfo.addr_16 = mpib.macShortAddress;			}			sfSpec.SuperSpec = 0;			sfSpec.setBO(mpib.macBeaconOrder);			sfSpec.setSO(mpib.macSuperframeOrder);			sfSpec.setFinCAP(aNumSuperframeSlots - 1);		//TBD: may be less than <aNumSuperframeSlots> when considering GTS			sfSpec.setBLE(mpib.macBattLifeExt);			sfSpec.setPANCoor(isPANCoor);			sfSpec.setAssoPmt(mpib.macAssociationPermit);			//populate the GTS fields -- more TBD when considering GTS			gtsSpec.fields.spec = 0;			gtsSpec.setPermit(mpib.macGTSPermit);			wph->MSDU_GTSFields = gtsSpec.fields;			//--- populate the pending address list ---			pendAddrSpec.numShortAddr = 0;			pendAddrSpec.numExtendedAddr = 0;			purgeTransacLink(&transacLink1,&transacLink2);			tmp = transacLink1;			i = 0;			while (tmp != NULL)			{				if (tmp->pendAddrMode == defFrmCtrl_AddrMode16)				{					if (updateDeviceLink(tr_oper_est,&deviceLink1,&deviceLink2,tmp->pendAddr64) == 0)						i = pendAddrSpec.addShortAddr(tmp->pendAddr16);		//duplicated address filtered out				}				else				{					if (updateDeviceLink(tr_oper_est,&deviceLink1,&deviceLink2,tmp->pendAddr64) == 0)						i = pendAddrSpec.addExtendedAddr(tmp->pendAddr64);	//duplicated address filtered out				}				if (i >= 7) break;				tmp = tmp->next;			}			pendAddrSpec.format();			wph->MSDU_PendAddrFields = pendAddrSpec.fields;			frmCtrl.setFrmPending(i>0);			//To populate the beacon payload field, <macBeaconPayloadLength> and <macBeaconPayload>			//should be set first, in that order (use primitive MLME_SET_request).			wph->MSDU_PayloadLen = mpib.macBeaconPayloadLength;			memcpy(wph->MSDU_Payload,mpib.macBeaconPayload,mpib.macBeaconPayloadLength);			//-----------------------------------------#ifdef ZigBeeIF			sscs->setGetClusTreePara('s',txBeacon);#endif			constructMPDU(2 + gtsSpec.size() + pendAddrSpec.size() + mpib.macBeaconPayloadLength,txBeacon,frmCtrl.FrmCtrl,mpib.macBSN++,wph->MHR_DstAddrInfo,wph->MHR_SrcAddrInfo,sfSpec.SuperSpec,0,0);			hdr_src((char *)HDR_MAC(txBeacon),index_);			hdr_dst((char *)HDR_MAC(txBeacon),MAC_BROADCAST);			HDR_CMN(txBeacon)->ptype() = PT_MAC;			HDR_CMN(txBeacon)->next_hop_ = p802_15_4macDA(txBeacon);		//nam needs the nex_hop information			p802_15_4hdrBeacon(txBeacon);#ifdef DEBUG802_15_4			fprintf(stdout,"[%s::%s][%f](node %d) transmit BEACON to %d: SN = %d, uid = %d, mac_uid = %ld\n",__FILE__,__FUNCTION__,CURRENT_TIME,index_,p802_15_4macDA(txBeacon),HDR_LRWPAN(txBeacon)->MHR_BDSN,HDR_CMN(txBeacon)->uid(),HDR_LRWPAN(txBeacon)->uid);#endif			txPkt = txBeacon;			HDR_CMN(txBeacon)->direction() = hdr_cmn::DOWN;			//nam->flashNodeMark(CURRENT_TIME);			sendDown(txBeacon->refcopy(), this);			mpib.macBeaconTxTime = (UINT_32)(CURRENT_TIME * phy->getRate('s'));			macBcnTxTime = CURRENT_TIME * phy->getRate('s');	//double used for accuracy			oneMoreBeacon = false;		}		else			assert(0);	}	bcnTxT->start();	//don't disable this even beacon not enabled (beacon may be temporarily disabled like in channel scan, but it will be enabled again)}void Mac802_15_4::beaconRxHandler(void){	if (macBeaconOrder2 != 15)		//beacon enabled (do nothing if beacon not enabled)	{		if (txAck)		{			Packet::free(txAck);			txAck = 0;		}		//enable the receiver		plme_set_trx_state_request(p_RX_ON);		if (taskP.mlme_sync_request_tracking)			{			//a better way is using another timer to detect <numLostBeacons> right after the header of superframe			if (numLostBeacons > aMaxLostBeacons)			{				char label[11];				//label[0] = 0;						strcpy(label,"\" \"");#ifdef ZigBeeIF				if (sscs->t_isCT)					sprintf(label,"\"%s\"",(sscs->RNType())?"+":"-");#endif				nam->changeLabel(CURRENT_TIME,label);				changeNodeColor(CURRENT_TIME,Nam802_15_4::def_Node_clr);				sscs->MLME_SYNC_LOSS_indication(m_BEACON_LOSS);				numLostBeacons = 0;			}			else			{				numLostBeacons++;				bcnRxT->start();			}		}	}}void Mac802_15_4::beaconSearchHandler(void){	dispatch(p_BUSY,__FUNCTION__);}void Mac802_15_4::isPanCoor(bool isPC){	if (isPANCoor == isPC)		return;	if (isPC)		changeNodeColor(CURRENT_TIME,Nam802_15_4::def_PANCoor_clr);	else if (isPANCoor)		changeNodeColor(CURRENT_TIME,		   (mpib.macPANId == 0xffff) ? Nam802_15_4::def_Node_clr :		   (mpib.macAssociationPermit) ? Nam802_15_4::def_Coor_clr : Nam802_15_4::def_Dev_clr);	isPANCoor = isPC;}//-------------------------------------------------------------------------------------void Mac802_15_4::set_trx_state_request(PHYenum state,const char *frFile,const char *frFunc,int line){#ifdef DEBUG802_15_4	fprintf(stdout,"[%s::%s][%f](node %d): %s request from [%s:%s:%d]\n",__FILE__,__FUNCTION__,CURRENT_TIME,index_,	(state == p_RX_ON)?"RX_ON":	(state == p_TX_ON)?"TX_ON":	(state == p_TRX_OFF)?"TRX_OFF":	(state == p_FORCE_TRX_OFF)?"FORCE_TRX_OFF":"???",	frFile,frFunc,line);#endif	trx_state_req = state;	phy->PLME_SET_TRX_STATE_request(state);}char *taskName[] = {"NONE",		    "MCPS-DATA.request",		    "MLME-ASSOCIATE.request",		    "MLME-ASSOCIATE.response",		    "MLME-DISASSOCIATE.request",		    "MLME-ORPHAN.response",		    "MLME-RESET.request",		    "MLME-RX-ENABLE.request",		    "MLME-SCAN.request",		    "MLME-START.request",		    "MLME-SYNC.request",		    "MLME-POLL.request",		    "CCA_csmaca",		    "RX_ON_csmaca"};void Mac802_15_4::checkTaskOverflow(UINT_8 task){	//Though we assume the upper layer should know what it is doing -- should send down requests one by one.	//But we'd better check again (we have no control over upper layer and we don't know who is operating on the upper layer)	if (taskP.taskStatus(task))	{		fprintf(stdout,"[%s::%s][%f](node %d) task overflow: %s\n",__FILE__,__FUNCTION__,CURRENT_TIME,index_,taskName[task]);		exit(1);	}	else	{		taskP.taskStep(task) = 0;		(taskP.taskFrFunc(task))[0] = 0;	}}void Mac802_15_4::dispatch(PHYenum status,const char *frFunc,PHYenum req_state,MACenum mStatus){	hdr_lrwpan *wph;	hdr_cmn *ch;	FrameCtrl frmCtrl;	UINT_8 ifs;	int i;	if (strcmp(frFunc,"csmacaCallBack") == 0)	{		if (txCsmaca == txBcnCmd2)		{			if (taskP.taskStatus(TP_mlme_scan_request)			&& (strcmp(taskP.taskFrFunc(TP_mlme_scan_request),frFunc) == 0))			{				if ((taskP.mlme_scan_request_ScanType == 0x01)	//active scan				||  (taskP.mlme_scan_request_ScanType == 0x03))	//orphan scan				

⌨️ 快捷键说明

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