📄 mac802_16.cc
字号:
/* This software was developed at the National Institute of Standards and * Technology by employees of the Federal Government in the course of * their official duties. Pursuant to title 17 Section 105 of the United * States Code this software is not subject to copyright protection and * is in the public domain. * NIST assumes no responsibility whatsoever for its use by other parties, * and makes no guarantees, expressed or implied, about its quality, * reliability, or any other characteristic. * <BR> * We would appreciate acknowledgement if the software is used. * <BR> * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING * FROM THE USE OF THIS SOFTWARE. * </PRE></P> * @author rouil */#include "mac802_16.h"#include "scheduling/wimaxscheduler.h"#include "scheduling/ssscheduler.h" //TBR//we use mac 802_11 for trace#include "mac-802_11.h"/* Defines frequencies for 3.5 GHz band and 7 Mhz freqency bandwidth *//* Will be removed when a dynamic way is added */static const int nbFreq = 5;static const double frequencies[] = { 3.486e+9, 3.493e+9, 3.5e+9, 3.507e+9, 3.514e+9};int hdr_mac802_16::offset_;/** * TCL Hooks for the simulator for wimax packets */static class Mac802_16HeaderClass : public PacketHeaderClass{public: Mac802_16HeaderClass() : PacketHeaderClass("PacketHeader/802_16", sizeof(hdr_mac802_16)) { bind_offset(&hdr_mac802_16::offset_); }} class_hdr_mac802_16;/** * TCL Hooks for the simulator for wimax mac */static class Mac802_16Class : public TclClass {public: Mac802_16Class() : TclClass("Mac/802_16") {} TclObject* create(int, const char*const*) { return (new Mac802_16()); }} class_mac802_16;Phy802_16MIB::Phy802_16MIB(Mac802_16 *parent){ parent->bind ("channel_", &channel ); parent->bind ("fbandwidth_", &fbandwidth ); parent->bind ("ttg_", &ttg ); parent->bind ("rtg_", &rtg );}Mac802_16MIB::Mac802_16MIB(Mac802_16 *parent){ parent->bind ("queue_length_", &queue_length ); parent->bind ("frame_duration_", &frame_duration ); parent->bind ("dcd_interval_", &dcd_interval ); parent->bind ("ucd_interval_", &ucd_interval ); parent->bind ("init_rng_interval_", &init_rng_interval ); parent->bind ("lost_dlmap_interval_", &lost_dlmap_interval ); parent->bind ("lost_ulmap_interval_", &lost_ulmap_interval ); parent->bind ("t1_timeout_", &t1_timeout ); parent->bind ("t2_timeout_", &t2_timeout ); parent->bind ("t3_timeout_", &t3_timeout ); parent->bind ("t6_timeout_", &t6_timeout ); parent->bind ("t12_timeout_", &t12_timeout ); parent->bind ("t16_timeout_", &t16_timeout ); parent->bind ("t17_timeout_", &t17_timeout ); parent->bind ("t21_timeout_", &t21_timeout ); parent->bind ("contention_rng_retry_", &contention_rng_retry ); parent->bind ("invited_rng_retry_", &invited_rng_retry ); parent->bind ("request_retry_", &request_retry ); parent->bind ("reg_req_retry_", ®_req_retry ); parent->bind ("tproc_", &tproc ); parent->bind ("dsx_req_retry_", &dsx_req_retry ); parent->bind ("dsx_rsp_retry_", &dsx_rsp_retry ); parent->bind ("rng_backoff_start_", &rng_backoff_start); parent->bind ("rng_backoff_stop_", &rng_backoff_stop); parent->bind ("bw_backoff_start_", &bw_backoff_start); parent->bind ("bw_backoff_stop_", &bw_backoff_stop); //mobility extension parent->bind ("scan_duration_", &scan_duration ); parent->bind ("interleaving_interval_", &interleaving ); parent->bind ("scan_iteration_", &scan_iteration ); parent->bind ("t44_timeout_", &t44_timeout ); parent->bind ("max_dir_scan_time_", &max_dir_scan_time ); parent->bind ("nbr_adv_interval_", &nbr_adv_interval ); parent->bind ("scan_req_retry_", &scan_req_retry ); parent->bind ("client_timeout_", &client_timeout ); parent->bind ("rxp_avg_alpha_", &rxp_avg_alpha); parent->bind ("lgd_factor_", &lgd_factor_);}/** * Creates a Mac 802.16 */Mac802_16::Mac802_16() : Mac (), macmib_(this), phymib_(this), rxTimer_(this){ //init variable LIST_INIT(&classifier_list_); peer_list_ = (struct peerNode *) malloc (sizeof(struct peerNode)); LIST_INIT(peer_list_); collision_ = false; pktRx_ = NULL; pktBuf_ = NULL; connectionManager_ = new ConnectionManager (this); scheduler_ = NULL; /* the following will be replaced by dynamic adding of service flow */ serviceFlowHandler_ = new ServiceFlowHandler (); serviceFlowHandler_->setMac (this); bs_id_ = BS_NOT_CONNECTED; type_ = STA_UNKNOWN; frame_number_ = 0; state_ = MAC802_16_DISCONNECTED; notify_upper_ = true; last_tx_time_ = 0; last_tx_duration_ = 0; Tcl& tcl = Tcl::instance(); tcl.evalf ("Phy/WirelessPhy set RXThresh_"); macmib_.RXThreshold_ = atof (tcl.result()); /* Initialize Stats variables */ bind_bool ("print_stats_", &print_stats_); last_tx_delay_ = 0; double tmp; bind ("delay_avg_alpha_", &tmp); delay_watch_.set_alpha(tmp); bind ("jitter_avg_alpha_", &tmp); jitter_watch_.set_alpha(tmp); bind ("loss_avg_alpha_", &tmp); loss_watch_.set_alpha(tmp); bind ("throughput_avg_alpha_", &tmp); rx_data_watch_.set_alpha(tmp); rx_data_watch_.set_pos_gradient (false); rx_traffic_watch_.set_alpha(tmp); rx_traffic_watch_.set_pos_gradient (false); tx_data_watch_.set_alpha(tmp); tx_data_watch_.set_pos_gradient (false); tx_traffic_watch_.set_alpha(tmp); tx_traffic_watch_.set_pos_gradient (false); bind ("throughput_delay_", &tmp); rx_data_watch_.set_delay (tmp); rx_traffic_watch_.set_delay (tmp); tx_data_watch_.set_delay (tmp); tx_traffic_watch_.set_delay (tmp); //timers for stats rx_data_timer_ = new StatTimer (this, &rx_data_watch_); rx_traffic_timer_ = new StatTimer (this, &rx_traffic_watch_); tx_data_timer_ = new StatTimer (this, &tx_data_watch_); tx_traffic_timer_ = new StatTimer (this, &tx_traffic_watch_);}/* * Interface with the TCL script * @param argc The number of parameter * @param argv The list of parameters */int Mac802_16::command(int argc, const char*const* argv){ if (argc == 2) { if (strcmp(argv[1], "dump-classifiers") == 0) { for (SDUClassifier *n=classifier_list_.lh_first;n;n=n->next_entry()) { //printf ("Classifier %x priority=%d\n", (int)n, n->getPriority()); } return TCL_OK; } } else if (argc == 3) { /* if (strcmp(argv[1], "set-bs") == 0) { bs_id_ = atoi (argv[2]); } else*/ if (strcmp(argv[1], "add-classifier") == 0) { SDUClassifier *clas = (SDUClassifier*) TclObject::lookup(argv[2]); if (clas == 0) return TCL_ERROR; //add classifier to the list addClassifier (clas); return TCL_OK; } else if (strcmp(argv[1], "set-scheduler") == 0) { scheduler_ = (WimaxScheduler*) TclObject::lookup(argv[2]); if (scheduler_ == 0) return TCL_ERROR; scheduler_->setMac (this); //register the mac setStationType (scheduler_->getNodeType()); //get the node type (BS or MN) return TCL_OK; } else if (strcmp(argv[1], "set-servicehandler") == 0) { serviceFlowHandler_ = (ServiceFlowHandler*) TclObject::lookup(argv[2]); if (serviceFlowHandler_ == 0) return TCL_ERROR; serviceFlowHandler_->setMac (this); return TCL_OK; } else if (strcmp(argv[1], "set-channel") == 0) { assert (netif_); //to make sure we can update the phy phymib_.channel = atoi (argv[2]); double tmp = frequencies[phymib_.channel]; getPhy ()->setFrequency (tmp); return TCL_OK; } } return Mac::command(argc, argv);}/** * Set the type of STA. This will be called when adding the scheduler * It is used to create the default connections * @param type The station type */void Mac802_16::setStationType (station_type_t type){ assert (type_ == STA_UNKNOWN && type != STA_UNKNOWN); type_ = type; init_default_connections ();}/** * Initialize default connections */void Mac802_16::init_default_connections (){ Connection * con; //create initial ranging and padding connection con = new Connection (CONN_INIT_RANGING); connectionManager_->add_connection (con, true); //uplink con = new Connection (CONN_INIT_RANGING); connectionManager_->add_connection (con, false); //downlink con = new Connection (CONN_PADDING); connectionManager_->add_connection (con, true); con = new Connection (CONN_PADDING); connectionManager_->add_connection (con, false); if (type_ == STA_BS) { //the BS is always connected setMacState (MAC802_16_CONNECTED); //we need to create a Broadcast connection and AAS init ranging CIDs con = new Connection (CONN_BROADCAST); connectionManager_->add_connection (con, false); con = new Connection (CONN_AAS_INIT_RANGING); connectionManager_->add_connection (con, true); } else if (type_ == STA_MN) { //create connection to receive broadcast packets from BS con = new Connection (CONN_BROADCAST); connectionManager_->add_connection (con, false); }}/** * Return the peer node that has the given address * @param index The address of the peer * @return The peer node that has the given address */PeerNode* Mac802_16::getPeerNode (int index){ for (PeerNode *p=peer_list_->lh_first;p;p=p->next_entry()) { if (p->getPeerNode ()==index) return p; } return NULL;}/** * Add the peer node * @param The peer node to add */void Mac802_16::addPeerNode (PeerNode *node){ node->insert_entry (peer_list_); //update Rx time so for default value node->setRxTime(NOW); node->getStatWatch()->set_alpha(macmib_.rxp_avg_alpha);}/** * Remove the peer node * @param The peer node to remove */void Mac802_16::removePeerNode (PeerNode *peer){ if (peer->getBasic()) { getCManager()->remove_connection (peer->getBasic()->get_cid()); delete (peer->getBasic()); } if (peer->getPrimary()) { getCManager()->remove_connection (peer->getPrimary()->get_cid()); delete (peer->getPrimary()); } if (peer->getSecondary()) { getCManager()->remove_connection (peer->getSecondary()->get_cid()); delete (peer->getSecondary()); } if (peer->getInData()) { getCManager()->remove_connection (peer->getInData()->get_cid()); delete (peer->getInData()); } if (peer->getOutData()) { getCManager()->remove_connection (peer->getOutData()->get_cid()); delete (peer->getOutData()); } peer->remove_entry (); delete (peer);}/** * Set the mac state * @param state The new mac state */ void Mac802_16::setMacState (Mac802_16State state){ state_ = state;}/** * Return the mac state * @return The new mac state */ Mac802_16State Mac802_16::getMacState (){ return state_;}/** * Return the PHY layer * @return The PHY layer */OFDMPhy* Mac802_16::getPhy () { return (OFDMPhy*) netif_;}/** * Change the channel * @param channel The new channel */void Mac802_16::setChannel (int channel){ assert (channel < nbFreq); phymib_.channel = channel; double tmp = frequencies[phymib_.channel]; getPhy ()->setFrequency (tmp);}/** * Return the channel number for the given frequency * @param freq The frequency * @return The channel number of -1 if the frequency does not match */int Mac802_16::getChannel (double freq){ for (int i = 0 ; i < nbFreq ; i++) { if (frequencies[i]==freq) return i; } return -1;}/** * Return the channel index * @return The channel */int Mac802_16::getChannel (){ return phymib_.channel;}/** * Set the channel to the next from the list * Used at initialisation and when loosing signal
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -