📄 mac802_16.cc
字号:
switch (con->getType()) { case CONN_INIT_RANGING: scheduler_->process (pktRx_); break; case CONN_AAS_INIT_RANGING: break; case CONN_MULTICAST_POLLING: break; case CONN_PADDING: //padding is sent by a SS that does not have data //to send is required to send a signal. //TBD: Find the SS that sent the padding scheduler_->process (pktRx_); break; case CONN_BROADCAST: if (HDR_CMN(pktRx_)->ptype()==PT_MAC) scheduler_->process (pktRx_); else { //Richard: only send to upper layer if connected if (state_ == MAC802_16_CONNECTED) goto send_upper; else { //update drop stat, could be used to detect deconnection update_watch (&loss_watch_, 1); Packet::free(pktRx_); pktRx_=NULL; return; } } break; case CONN_BASIC: scheduler_->process (pktRx_); break; case CONN_PRIMARY: assert (HDR_CMN(pktRx_)->ptype()==PT_MAC); //we cast to this frame because all management frame start with a type if (wimaxHdr->header.ht==1) { //bw request scheduler_->process (pktRx_); } else { frame = (mac802_16_dl_map_frame*) pktRx_->accessdata(); switch (frame->type) { case MAC_DSA_REQ: case MAC_DSA_RSP: case MAC_DSA_ACK: serviceFlowHandler_->process (pktRx_); break; default: scheduler_->process (pktRx_); } } break; case CONN_SECONDARY: //fall through case CONN_DATA: //send to upper layer goto send_upper; break; default: fprintf (stderr,"Error: unknown connection type\n"); exit (0); } goto sent_mac; //default jump send_upper: update_throughput (&rx_data_watch_, 8*ch->size()); update_throughput (&rx_traffic_watch_, 8*ch->size()); ch->size() -= HDR_MAC802_16_SIZE; uptarget_->recv(pktRx_, (Handler*) 0); goto done; sent_mac: update_throughput (&rx_traffic_watch_, 8*ch->size()); //fall through //should not free it here because we don't know if other modules //kept a copy of it. //Packet::free(pktRx_); //update Rx stat done: update_watch (&loss_watch_, 0); pktRx_=NULL;}/**** Helper methods ****//** * Return the frame number * @return the frame number */int Mac802_16::getFrameNumber () { return frame_number_;}/* * Return the code for the frame duration * @return the code for the frame duration */int Mac802_16::getFrameDurationCode () { if (macmib_.frame_duration == 0.0025) return 0; else if (macmib_.frame_duration == 0.004) return 1; else if (macmib_.frame_duration == 0.005) return 2; else if (macmib_.frame_duration == 0.008) return 3; else if (macmib_.frame_duration == 0.01) return 4; else if (macmib_.frame_duration == 0.0125) return 5; else if (macmib_.frame_duration == 0.02) return 6; else { fprintf (stderr, "Invalid frame duration %f\n", macmib_.frame_duration); exit (1); }}/* * Set the frame duration using code * @param code The frame duration code */void Mac802_16::setFrameDurationCode (int code) { switch (code) { case 0: macmib_.frame_duration = 0.0025; break; case 1: macmib_.frame_duration = 0.004; break; case 2: macmib_.frame_duration = 0.005; break; case 3: macmib_.frame_duration = 0.008; break; case 4: macmib_.frame_duration = 0.01; break; case 5: macmib_.frame_duration = 0.0125; break; case 6: macmib_.frame_duration = 0.02; break; default: fprintf (stderr, "Invalid frame duration code %d\n", code); exit (1); }}/** * Return a packet * @return a new packet */Packet *Mac802_16::getPacket (){ Packet *p = Packet::alloc (); hdr_mac802_16 *wimaxHdr= HDR_MAC802_16(p); //set header information wimaxHdr->header.ht = 0; wimaxHdr->header.ec = 1; wimaxHdr->header.type = 0; //no subheader wimaxHdr->header.ci = 0; wimaxHdr->header.eks = 0; wimaxHdr->header.cid = BROADCAST_CID; //default wimaxHdr->header.hcs = 0; HDR_CMN(p)->ptype() = PT_MAC; HDR_CMN(p)->size() = HDR_MAC802_16_SIZE; return p;}/**** Internal methods ****//* * Add a classifier * @param clas The classifier to add */void Mac802_16::addClassifier (SDUClassifier *clas) { SDUClassifier *n=classifier_list_.lh_first; SDUClassifier *prev=NULL; int i = 0; if (!n || (n->getPriority () >= clas->getPriority ())) { //the first element //debug ("Add first classifier\n"); clas->insert_entry_head (&classifier_list_); } else { while ( n && (n->getPriority () < clas->getPriority ()) ) { prev=n; n=n->next_entry(); i++; } //debug ("insert entry at position %d\n", i); clas->insert_entry (prev); } //Register this mac with the classifier clas->setMac (this);}#ifdef USE_802_21/* * Configure/Request configuration * The upper layer sends a config object with the required * new values for the parameters (or PARAMETER_UNKNOWN_VALUE). * The MAC tries to set the values and return the new setting. * For examples if a MAC does not support a parameter it will * return PARAMETER_UNKNOWN_VALUE * @param config The configuration object */ void Mac802_16::link_configure (link_parameter_config_t* config){ assert (config); config->bandwidth = 15000000; //TBD use phy (but depend on modulation) config->type = LINK_802_16; //we set the rest to PARAMETER_UNKNOWN_VALUE config->ber = PARAMETER_UNKNOWN_VALUE; config->delay = PARAMETER_UNKNOWN_VALUE; config->macPoA = PARAMETER_UNKNOWN_VALUE;}/* * Disconnect from the PoA */void Mac802_16::link_disconnect (){ if (type_ == STA_MN) { //force losing synchronization ((SSscheduler*) scheduler_)->lost_synch (); getPhy()->node_off(); }}/* * Connect to the PoA */void Mac802_16::link_connect (int poa){ if (type_ == STA_MN) { getPhy()->node_on(); }}/* * Configure the threshold values for the given parameters * @param numLinkParameter number of parameter configured * @param linkThresholds list of parameters and thresholds */struct link_param_th_status * Mac802_16::link_configure_thresholds (int numLinkParameter, struct link_param_th *linkThresholds){ struct link_param_th_status *result = (struct link_param_th_status *) malloc(numLinkParameter * sizeof (struct link_param_th_status)); StatWatch *watch=NULL; for (int i=0 ; i < numLinkParameter ; i++) { result[i].parameter = linkThresholds[i].parameter; result[i].status = 1; //accepted..default switch (linkThresholds[i].parameter){ case LINK_PACKET_LOSS: watch = &loss_watch_; break; case LINK_PACKET_DELAY: watch = &delay_watch_; break; case LINK_PACKET_JITTER: watch = &jitter_watch_; break; case LINK_RX_DATA_THROUGHPUT: watch = &rx_data_watch_; break; case LINK_RX_TRAFFIC_THROUGHPUT: watch = &rx_traffic_watch_; break; case LINK_TX_DATA_THROUGHPUT: watch = &tx_data_watch_; break; case LINK_TX_TRAFFIC_THROUGHPUT: watch = &tx_traffic_watch_; break; default: fprintf (stderr, "Parameter type not supported %d\n", linkThresholds[i].parameter); result[i].status = 0; //rejected } watch->set_thresholds (linkThresholds[i].initActionTh.data_d, linkThresholds[i].rollbackActionTh.data_d , linkThresholds[i].exectActionTh.data_d); } return result;} #endif/** * Update the given timer and check if thresholds are crossed * @param watch the stat watch to update * @param value the stat value */void Mac802_16::update_watch (StatWatch *watch, double value){ char *name;#ifdef USE_802_21 //Switch to activate when using 802.21 modules (external package) threshold_action_t action = watch->update (value); if (action != NO_ACTION_TH) { link_parameter_t param; union param_value old_value, new_value; if (watch == &loss_watch_) { param = LINK_PACKET_LOSS; } else if (watch == &delay_watch_) { param = LINK_PACKET_DELAY; } else if (watch == &jitter_watch_) { param = LINK_PACKET_JITTER; } old_value.data_d = watch->old_average(); new_value.data_d = watch->average(); send_link_parameter_change (addr(), param, old_value, new_value); }#endif if (watch == &loss_watch_) { name = "loss"; } else if (watch == &delay_watch_) { name = "delay"; } else if (watch == &jitter_watch_) { name = "jitter"; } else { name = "other"; } if (print_stats_) printf ("At %f in Mac %d, updating stats %s: %f\n", NOW, addr(), name, watch->average());}/** * Update the given timer and check if thresholds are crossed * @param watch the stat watch to update * @param value the stat value */void Mac802_16::update_throughput (ThroughputWatch *watch, double size){ char *name;#ifdef USE_802_21 //Switch to activate when using 802.21 modules (external package) threshold_action_t action = watch->update (size, NOW); if (action != NO_ACTION_TH) { link_parameter_t param; union param_value old_value, new_value; if (watch == &rx_data_watch_) { param = LINK_RX_DATA_THROUGHPUT; } else if (watch == &rx_traffic_watch_) { param = LINK_RX_TRAFFIC_THROUGHPUT; } else if (watch == &tx_data_watch_) { param = LINK_TX_DATA_THROUGHPUT; } else if (watch == &tx_traffic_watch_) { param = LINK_TX_TRAFFIC_THROUGHPUT; } old_value.data_d = watch->old_average(); new_value.data_d = watch->average(); send_link_parameter_change (addr(), param, old_value, new_value); }#endif if (watch == &rx_data_watch_) { name = "rx_data"; rx_data_timer_->resched (watch->get_timer_interval()); } else if (watch == &rx_traffic_watch_) { rx_traffic_timer_->resched (watch->get_timer_interval()); name = "rx_traffic"; } else if (watch == &tx_data_watch_) { tx_data_timer_->resched (watch->get_timer_interval()); name = "tx_data"; } else if (watch == &tx_traffic_watch_) { tx_traffic_timer_->resched (watch->get_timer_interval()); name = "tx_traffic"; } if (print_stats_) printf ("At %f in Mac %d, updating stats %s: %f\n", NOW, addr(), name, watch->average());}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -