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

📄 mac-gprs.cc

📁 一个很好的LINUX底下的GPRS协议栈
💻 CC
📖 第 1 页 / 共 3 页
字号:
					}					}					if (j != gprs_slots_per_frame_+1 ) {					break;				}			}			if (i==max_num_freq_ && j==gprs_slots_per_frame_+1) {       							fprintf(stderr," No GPRS freq/slot free..... cant allot.  \n");				return;			}			} 		else { // it's a gsm node			for ( i=0; i<max_num_freq_ ; i++) { 			    for ( j=gprs_slots_per_frame_+1 ; j< SLOTS_PER_FRAME; j++) {					if (vlr_.up_table[i][j] == -10) {						break;					}					}					if (j != SLOTS_PER_FRAME ) {					break;				}			}			if ( i==max_num_freq_ && j==SLOTS_PER_FRAME) {       							fprintf(stderr," No GSM freq/slot free..... cant allot.  \n");				return;			}			} 				 	// => i, j are the first free freq-slot pair.		// reserve them for the requesting Mobile 		vlr_.up_table[i][j] = ms_ ;		vlr_.down_table[i][j] = ms_;		freq=i;		slot=j;	//showing the current reservations		for (i=0; i < max_num_freq_; i++) {	        for (j=0; j < SLOTS_PER_FRAME; j++) {          				if (verbose_==1)				printf ("vlr_.up_table [%d][%d] = %d \n", i,j, vlr_.up_table [i][j]  );			}	}				return;}/* To handle incoming packet. */void MacGprs::recv(Packet* p, Handler* h) {	MobileNode * node_ = (MobileNode*)(netif_->node());	if (node_->base_stn() != node_->address()) {//node !=BS ie its an MS 		ms_recv(p,h);    }			else if (node_->base_stn() == node_->address()) {//node is its own BS ie its aBS 		bs_recv(p,h);	}}			void MacGprs::ms_recv(Packet* p, Handler* h){		struct hdr_cmn *ch = HDR_CMN(p);	struct hdr_mac_gprs *dh = HDR_MAC_GPRS(p);	int dst = ETHER_ADDR(dh->dh_da);   	int src = ETHER_ADDR(dh->dh_sa);   		int i,j,len; 			if (ch->direction() == hdr_cmn::UP) {	// ie MS rx pkt from phy on a Downlink slot					if ( src == 0  && (dst == index_ || ((u_int32_t)dst == MAC_BROADCAST) ) ){			if ( rx_chan[down_slot_-1] == ch->chan() )   {				if (verbose_==1)				printf("<%d> %f ms_recv pkt 4 me at phy. mac_src=%d mac-dst=%d, next_hop=%s,\n			  uid= %d. ptype=%s. \n",				index_, NOW, src, dst, Address::instance().print_nodeaddr (ch->next_hop_) ,       				ch->uid(), packet_info.name(ch->ptype()) );					if (mhRel_.busy() !=0 /*&& (ch->ptype()!=PT_ACK) */					/*&&  (dh->dh_fc.fc_type != MAC_Type_Control)*/ ) {									mhRel_.stop();					if (verbose_==1)					   printf("<%d> %f  pkt goin UP. release timer stopped \n", index_, NOW); 										if (q_ !=NULL && gprs_ ==1){						len= q_->length();	//restart timer if length =0						if ( len==0 && (down_slot_ != 1) && (rx_chan[down_slot_-1] !=-10) ) {							slot_release_time_ = (4*SLOTS_PER_FRAME) *slot_time_;							mhRel_.start(slot_release_time_);							if (verbose_==1)							    printf("<%d> %f  release timer started: 1 \n",index_, NOW);   						}					}				}									pktRx[down_slot_-1] = p;				radioSwitch(ON); 				rx_from_phy ( pktRx[down_slot_-1] );  			}			}			return;	}   if (verbose_==1)	 printf("<%d> %f ms_recv pkt at IFQ. mac_src=%d mac-dst=%d, next_hop=%s,			 uid= %d. ptype=%s. rlc_seqno=%d, size=%d\n",			index_, NOW, src, dst, Address::instance().print_nodeaddr (ch->next_hop_) ,       			ch->uid(), packet_info.name(ch->ptype()), HDR_RLC(p)->seqno(), ch->size() );	callback_ = h;	if	( (u_int32_t)dst == MAC_BROADCAST && ch->ptype() != PT_ARP ){ 		j = 0;   		if (verbose_==1)		   printf("<%d> %f Ms: pkt to broadcast dst=%d \n", NOW,dst);	} 	else {		// find upslot/freq to tx on		for ( j=1; j< SLOTS_PER_FRAME ; j++) {			if ( tx_chan[j] != -10 ) { //ie MS has been allotted SOME upchan				break;			 }		 }		if (j==SLOTS_PER_FRAME) { // => I dont have a channel so far - ask for one.			if (mhwait_.busy() !=0 ) {// wait timer busy - waiting for res reply..   				if (verbose_==1)				   printf("<%d> %f I am waiting for res_reply \n", index_, NOW);				return; 			}    			if (verbose_==1)			   printf("<%d> %f I dont have a chan yet - will send a resource request.\n", index_, NOW);			send_res_request();			p_temp=p;// store the pkt to tx later.....			return;		}		}	  	//if we have multiple ARP requests: drop 	if ( ch->ptype()==PT_ARP )  {		 Packet::free(p) ;         if (verbose_==1)		    printf("<%d> %f I got multiple ARP requests. Dropped duplicates.\n",  index_, NOW); 		 return;	}	 			ch->chan() = tx_chan[j]; //stamp pkt hdr with chan num	pktTx[j] = p; // schedule pkt to be txd in upslot j		   if (verbose_==1) 	  printf("<%d> %f MS: pkt 2b txd in [Uslot %d],[chan %d]. ptype=%s uid=%d\n, 			  rlc_seqno=%d size=%d\n",			index_, NOW, j, tx_chan[j], packet_info.name(ch->ptype()), 			ch->uid(), HDR_RLC(p)->seqno(),ch->size() );		rx_from_ll (pktTx[j] ); // add MAC hdr onto pkt			if (mhRel_.busy() !=0 /*&&  (dh->dh_fc.fc_type != MAC_Type_Control)*/ ) {		mhRel_.stop();   		if (verbose_==1)		    printf("<%d> %f  pkt goin DOWN. release timer stopped \n", index_, NOW);   	}	return;}			void MacGprs::bs_recv(Packet* p, Handler* h) {	int i,j; 		struct hdr_cmn *ch = HDR_CMN(p);	struct hdr_mac_gprs *dh = HDR_MAC_GPRS(p);	int dst = ETHER_ADDR(dh->dh_da);   	int src = ETHER_ADDR(dh->dh_sa);        	if (ch->direction() == hdr_cmn::UP) {	// BS rxs pkt from phy at start of upslot.    //error model: only on uplink. if u want both uplink and downlink	//to have errors, just put these 11 lines above the if(..direction..)		if (rlc_error_==1 && index_==0) {// pkts are marked  only at BS. generally		drop_counter_ ++;		if (drop_counter_ == next_drop_) { 		    ch->error() = 1; //mark the pkt as erroneous			drop_gap_ = Random::integer(error_rate_);//find next pkt to drop			next_drop_ = next_drop_ + drop_gap_;		    if (verbose_==1)				printf("<%d> %f rlc pkt error. pkt %d being marked. next_drop=%d\n", 				 index_, NOW, drop_counter_,next_drop_);         }    }		if (((u_int32_t)dst == MAC_BROADCAST) || (dst == index_) ) {			   			if (verbose_==1)			    printf("<%d> %f bs_recv pkt 4 me at phy, mac_src=%d mac-dst=%d, next_hop=%s,\n		  		   uid= %d. ptype=%s. upslot=%d rlc_seqno=%d \n",			index_, NOW, src, dst, Address::instance().print_nodeaddr (ch->next_hop_) ,       			ch->uid(), packet_info.name(ch->ptype()), (up_slot_ -1), HDR_RLC(p)->seqno()  );						i = ch->chan();			rxQ[i][up_slot_-1] = p;			radioSwitch(ON);			rx_from_phy ( rxQ[i][up_slot_-1] );  		}		return;	}			// ie for down slot: pkt rxd from IFQ. prepare to tx	callback_ = h;   if (verbose_==1)	printf("<%d> %f bs_recv pkt at IFQ, mac_src=%d mac-dst=%d, next_hop=%s,\n		  uid= %d. ptype=%s. \n",		index_, NOW, src, dst, Address::instance().print_nodeaddr (ch->next_hop_) ,       		ch->uid(), packet_info.name(ch->ptype()) );		if	( (u_int32_t) dst == MAC_BROADCAST /*|| ch->ptype()==PT_ARP*/ ){   		if (verbose_==1)		   printf("<%d> %f BS. have to broadcast pkt \n", index_, NOW);	 	// downchan[0], downslot[0] reserved for broadcast/signalling 		ch->chan()=0 ; //stamp pkt hdr		txQ[0][0] = p ;		rx_from_ll(txQ[0][0]);		return;	}	else {		//find the first freq/slot combo allotted for this mac-dst 		for (i=0; i< max_num_freq_ ;i++){			// leave out i=0 coz reserved for Broadcast/signalling			for (j=1 ; j< SLOTS_PER_FRAME; j++ ) {				if ( dst == vlr_.down_table[i][j]) {					break;				}			}			if (j!= SLOTS_PER_FRAME) {   				if (verbose_==1)			//	  printf("<%d> %f I can tx in Downslot=%d, on freq=%d\n",index_, NOW, j, i);				break;				}		}			if ( i==max_num_freq_ && j==SLOTS_PER_FRAME) { //eiteher dst is a fixed node			//or it hasnt got a slot yet. 			if (mhwait_.busy() !=0 ) {// res reply ready.. but hasnt been txed yet.....   				if (verbose_==1)				  printf("<%d> %f  res_reply not yet recv by MS\n", index_, NOW);				 //return; 			} 			else {   				if (verbose_==1)				   printf("<%d> %f have to allot slots to dst=%d \n", index_, NOW, dst);					slot_allot( dst, i, j); 				send_res_reply(dst,i,j);			}				dh->dh_wait = 1;   			if (verbose_==1)		        printf("<%d> %f bs_recv dh_wait set for txQ[%d][%d]=%d \n", index_, NOW, i, j,dh->dh_wait );				//return;		}				ch->chan()=i ; //stamp pkt hdr		txQ[i][j] = p ;			   		if (verbose_==1)	     	printf("<%d> %f BS: pkt 2b txd in [Dslot %d],[chan %d]. ptype=%s uid=%d \n",			index_, NOW, j, i, packet_info.name(ch->ptype()), ch->uid() );		rx_from_ll(txQ[i][j]);		return;	}	}void MacGprs::rx_from_phy(Packet* p) {	struct hdr_cmn *ch = HDR_CMN(p);	struct hdr_mac_gprs* dh = HDR_MAC_GPRS(p);      		//check for collision at BS (check only at BS!) if this is a Random Access Channel	if ( ch->chan()==0 && up_slot_ ==1 && index_==0) {	// this is why u have t omake sure BS is index_==0!!!		switch (chan0_0) {			case IDLE:   				 if (verbose_==1)				  printf("<%d> %f uh oh!! chan0_0 idle - though a request/ARP was txd!!\n", 						index_, NOW );				return;				break;			case BUSY:				 // recive normally				 break;			case COLL :				 // if chan0_0 != 0 or 1 => many MS txing = collision				 Packet::free(p) ; //drop the pkt				 coll_count --;   				 if (verbose_==1)				    printf("<%d> %f chan0_0  collision. pkt dropped. coll_count=%d  \n" ,						 index_, NOW, coll_count);				 break;		}		if  (chan0_0 == BUSY) {			double rtime = TX_Time(p);						if (rtime > slot_time_) rtime= slot_time_ ;// hack-just in case.			   		    if (verbose_==1)			   printf("<%d> %f rtime = %f \n", index_, NOW, rtime);			assert(rtime >= 0);  			mhRxPkt_.start(p, rtime); 		//	mhRxPkt_.start(p, slot_time_); 					chan0_0 = IDLE;   		    if (verbose_==1)			   printf("<%d> %f recv timr started for chan0_0, chan made IDLE \n" , index_, NOW);   		}	   			if  (chan0_0 == COLL && coll_count==0) {			chan0_0 = IDLE;   		    if (verbose_==1)			   printf("<%d> %f chan0_0 made IDLE. all coll sensed.\n" , index_, NOW);   		}					return;	}			//jsut in case ..... ;) 	if (ch->error() == 1) {	//	Packet::free(p) ;   	    drop(p);		if (verbose_==1)		   printf("<%d> %f pkt dropped. ch->error()=1 \n", index_, NOW);		return;	}			double rtime = TX_Time(p);		//if pkt's too large - tx/rx only for one slot interval		if (rtime > slot_time_) rtime= slot_time_ ;		    		if (verbose_==1)		   printf("<%d> %f rtime=%f \n", index_, NOW, rtime);		assert(rtime >= 0);  		mhRxPkt_.start(p, rtime); 		//mhRxPkt_.start(p, slot_time_); }// Forward data to RLC/LL after pkt rxd from PHY ie when RxPktTimer times out.// Adjust the MAC packet size: strip off the mac header for data// and fwd to ll.// else check which control type and deal accordingly// NB: MAC control messgs are terminated here only and not passed// to the RLC/LLvoid MacGprs::fwd_DATA_to_LL(Packet *p){	int i,j, freq, slot;	float temp;	double backoff_time;		struct hdr_cmn *ch2;	struct hdr_mac_gprs *dh2;		struct hdr_cmn *ch = HDR_CMN(p);	struct hdr_mac_gprs* dh = HDR_MAC_GPRS(p); 	int src_ = ETHER_ADDR(dh->dh_sa); //the ode tha sent the res_request  		switch ( dh->dh_fc.fc_type) {				case MAC_Type_Data:							ch->size() -= ETHER_HDR_LEN;			ch->num_forwards() += 1;   		    if (verbose_==1)			   printf("<%d> %f  fwding_data_to_LL \n", index_, NOW);			uptarget_->recv(p, (Handler*) 0);			break;				case MAC_Type_Control:			switch (dh->dh_fc.fc_subtype) {								case MAC_Subtype_res_request: //happens at BS					//look for next free slot in vlr and assign it 					 slot_allot (src_, freq, slot);   					 if (verbose_==1)					    printf ("<%d> %f res request recvd. freq%d, slot%d reserved for <%d>.\n",							 index_, NOW, freq, slot, src_);									 send_res_reply (src_,freq, slot);					 //	break;					 return;									case MAC_Subtype_res_reply: //happens at MS									mhwait_.stop(); //stop the RA wait timer.					// set tx/rx_chan;					slot = dh->dh_slot;					freq = dh->dh_freq;					tx_chan[slot]=freq;					rx_chan[slot]=freq; // tx and rx r symmetric   					if (verbose_==1)					   printf ("<%d> %f res reply recvd. freq=%d slot=%d\n", index_, NOW, freq, slot);					// send the old pkt waiting at BS					if ( txQ[freq][slot] ==NULL) {					//	printf (" BS: no pkt waiting ...txq[%d][%d]  NULL \n", freq, slot);					}					else {						dh2 = HDR_MAC_GPRS(txQ[freq][slot]);						dh2->dh_wait=0;   						if (verbose_==1)						    printf("<%d> %f BS: OLD  pkt waiting. dh wait corrected \n", index_, NOW );					}					// if there's a packet buffered at the MS, send it					if ( p_temp!= NULL) {						ch2 = HDR_CMN(p_temp);						ch2->chan() = freq;   //stamp pkt hdr with chan num						pktTx[slot] = p_temp; // schedule pkt to be txd in upslot j						p_temp= NULL;         //clear p_temp.   						if (verbose_==1)						    printf("<%d> %f MS: got chan. OLD pkt 2b txd in [Uslot %d],[chan %d]. p type=%s uid=%d\n",								index_, NOW, slot, freq,packet_info.name(ch2->ptype()), ch2->uid() );							rx_from_ll ( pktTx[slot] ); // add MAC hdr onto pkt					}										//unblock IFQ				    q_->unblock();						if (verbose_==1) printf("<%d> %f IFQ unblocked \n", index_, NOW);										return;				    //	break;									case MAC_Subtype_tx_end: //happens at BS					//find MS entry in vlr and clear					for (i=0; i< max_num_freq_ ;i++){						for (j=1 ; j< gprs_slots_per_frame_; j++ ) {							if ( src_ == vlr_.down_table[i][j]) {   								if (verbose_==1)								    printf("vlr entry for %d, slot%d freq%d, deleted.\n", src_,j, i );								vlr_.down_table[i][j] = -10;								vlr_.up_table[i][j] = -10;								break;							}						}						if ( j!= gprs_slots_per_frame_) {							break;							}					}						return;				//	break;			}			default:			break;			//nothing.. the only MAC types are data and control.	}}// creates a resource_request message and schedules it to be sent// in the next upslot 0void MacGprs::send_res_request(){ // sent by an MS to its  BS		int dst;	Packet *p1 = Packet::alloc();		struct hdr_cmn* ch1= HDR_CMN(p1);	struct hdr_mac_gprs* dh1 = HDR_MAC_GPRS(p1);		MobileNode * node_ = (MobileNode*)(netif_->node());		dst=0; //hack since index_==0 => BS

⌨️ 快捷键说明

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