?? mac-gprs.cc
字號:
} } 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
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -