📄 ssscheduler.cc
字号:
//TBD: add processing for periodic ranging //check status switch (frame->rng_status) { case RNG_SUCCESS: mac_->debug ("Ranging response: status = Success.Basic=%d, Primary=%d\n", frame->basic_cid, frame->primary_cid); peer = mac_->getPeerNode_head(); assert (peer); map_->getUlSubframe()->getRanging()->removeRequest (); if (scan_info_->substate == SCANNING) { //store information about possible base station and keep scanning scan_info_->nbr->getState()->state_info= mac_->backup_state(); scan_info_->nbr->setDetected (true); //keep the information for later mac802_16_rng_rsp_frame *tmp = (mac802_16_rng_rsp_frame *) malloc (sizeof (mac802_16_rng_rsp_frame)); memcpy (tmp, frame, sizeof (mac802_16_rng_rsp_frame)); scan_info_->nbr->setRangingRsp (tmp); mac_->nextChannel(); lost_synch (); return; } //ranging worked, now we must register basic = peer->getBasic(); primary = peer->getPrimary(); if (basic!=NULL && basic->get_cid ()==frame->basic_cid) { //duplicate response assert (primary->get_cid () == frame->primary_cid); } else { if (basic !=NULL) { //we have been allocated new cids..clear old ones mac_->getCManager ()->remove_connection (basic); mac_->getCManager ()->remove_connection (primary); if (peer->getSecondary()!=NULL) mac_->getCManager ()->remove_connection (peer->getSecondary()); if (peer->getOutData()!=NULL) mac_->getCManager ()->remove_connection (peer->getOutData()); if (peer->getInData()!=NULL) mac_->getCManager ()->remove_connection (peer->getInData()); } basic = new Connection (CONN_BASIC, frame->basic_cid); Connection *upbasic = new Connection (CONN_BASIC, frame->basic_cid); primary = new Connection (CONN_PRIMARY, frame->primary_cid); Connection *upprimary = new Connection (CONN_PRIMARY, frame->primary_cid); //a SS should only have one peer, the BS peer->setBasic (upbasic); //set outgoing peer->setPrimary (upprimary); //set outgoing basic->setPeerNode (peer); primary->setPeerNode (peer); mac_->getCManager()->add_connection (upbasic, true); mac_->getCManager()->add_connection (basic, false); mac_->getCManager()->add_connection (upprimary, true); mac_->getCManager()->add_connection (primary, false); } //registration must be sent using Primary Management CID mac_->setMacState (MAC802_16_REGISTER); //stop timeout timer t2timer_->stop (); nb_reg_retry_ = 0; //first time sending send_registration(); break; case RNG_ABORT: case RNG_CONTINUE: case RNG_RERANGE: break; default: fprintf (stderr, "Unknown status reply\n"); exit (-1); }}/** * Schedule a ranging */void SSscheduler::init_ranging (){ //check if there is a ranging opportunity UlSubFrame *ulsubframe = map_->getUlSubframe(); DlSubFrame *dlsubframe = map_->getDlSubframe(); /* If I am doing a Handoff, check if I already associated with the target AP*/ if (scan_info_->substate == HANDOVER && scan_info_->nbr->getRangingRsp()!=NULL) { mac_->debug ("At %f in Mac %d MN already executed ranging during scanning\n", NOW, mac_->addr()); process_ranging_rsp (scan_info_->nbr->getRangingRsp()); return; } //check if there is Fast Ranging IE for (PhyPdu *p = map_->getUlSubframe ()->getFirstPdu(); p ; p= p ->next_entry()) { UlBurst *b = (UlBurst*) p->getBurst(0); if (b->getIUC() == UIUC_EXT_UIUC && b->getExtendedUIUC ()== UIUC_FAST_RANGING && b->getFastRangingMacAddr ()==mac_->addr()) { debug2 ("Found fast ranging\n"); //we should put the ranging request in that burst Packet *p= mac_->getPacket(); hdr_cmn* ch = HDR_CMN(p); HDR_MAC802_16(p)->header.cid = INITIAL_RANGING_CID; p->allocdata (sizeof (struct mac802_16_rng_req_frame)); mac802_16_rng_req_frame *frame = (mac802_16_rng_req_frame*) p->accessdata(); frame->type = MAC_RNG_REQ; frame->dc_id = dlsubframe->getChannelID(); frame->ss_mac_address = mac_->addr(); //other elements?? ch->size() += RNG_REQ_SIZE; //compute when to send message double txtime = mac_->getPhy()->getTrxTime (ch->size(), ulsubframe->getProfile (b->getFastRangingUIUC ())->getEncoding()); ch->txtime() = txtime; //starttime+backoff b->enqueue(p); mac_->setMacState(MAC802_16_WAIT_RNG_RSP); return; } } for (PhyPdu *pdu = ulsubframe->getFirstPdu(); pdu ; pdu = pdu->next_entry()) { if (pdu->getBurst(0)->getIUC()==UIUC_INITIAL_RANGING) { mac_->debug ("At %f SS Mac %d found ranging opportunity\n", NOW, mac_->addr()); Packet *p= mac_->getPacket(); hdr_cmn* ch = HDR_CMN(p); HDR_MAC802_16(p)->header.cid = INITIAL_RANGING_CID; p->allocdata (sizeof (struct mac802_16_rng_req_frame)); mac802_16_rng_req_frame *frame = (mac802_16_rng_req_frame*) p->accessdata(); frame->type = MAC_RNG_REQ; frame->dc_id = dlsubframe->getChannelID(); frame->ss_mac_address = mac_->addr(); //other elements?? ch->size() += RNG_REQ_SIZE; //compute when to send message double txtime = mac_->getPhy()->getTrxTime (ch->size(), ulsubframe->getProfile (pdu->getBurst(0)->getIUC())->getEncoding()); ch->txtime() = txtime; //starttime+backoff map_->getUlSubframe()->getRanging()->addRequest (p); mac_->setMacState(MAC802_16_WAIT_RNG_RSP); return; } }}/** * Prepare to send a registration message */void SSscheduler::send_registration (){ Packet *p; struct hdr_cmn *ch; hdr_mac802_16 *wimaxHdr; mac802_16_reg_req_frame *reg_frame; PeerNode *peer; //create packet for request p = mac_->getPacket (); ch = HDR_CMN(p); wimaxHdr = HDR_MAC802_16(p); p->allocdata (sizeof (struct mac802_16_reg_req_frame)); reg_frame = (mac802_16_reg_req_frame*) p->accessdata(); reg_frame->type = MAC_REG_REQ; ch->size() += REG_REQ_SIZE; peer = mac_->getPeerNode_head(); wimaxHdr->header.cid = peer->getPrimary()->get_cid(); peer->getPrimary()->enqueue (p); //start reg timeout if (t6timer_==NULL) { t6timer_ = new WimaxT6Timer (mac_); } t6timer_->start (mac_->macmib_.t6_timeout); nb_reg_retry_++;}/** * Process a registration response message * @param frame The registration response frame */void SSscheduler::process_reg_rsp (mac802_16_reg_rsp_frame *frame){ //check the destination PeerNode *peer = mac_->getPeerNode_head(); if (frame->response == 0) { //status OK mac_->debug ("At %f in Mac %d, registration sucessful (nbretry=%d)\n", NOW, mac_->addr(), nb_reg_retry_); Connection *secondary = peer->getSecondary(); if (!secondary) { Connection *secondary = new Connection (CONN_SECONDARY, frame->sec_mngmt_cid); Connection *upsecondary = new Connection (CONN_SECONDARY, frame->sec_mngmt_cid); mac_->getCManager()->add_connection (upsecondary, true); mac_->getCManager()->add_connection (secondary, false); peer->setSecondary (upsecondary); secondary->setPeerNode (peer); } //cancel timeout t6timer_->stop (); //update status mac_->setMacState(MAC802_16_CONNECTED); //we need to setup a data connection (will be moved to service flow handler) mac_->getServiceHandler ()->sendFlowRequest (peer->getPeerNode(), true); mac_->getServiceHandler ()->sendFlowRequest (peer->getPeerNode(), false);#ifdef USE_802_21 if (scan_info_->substate==HANDOVER) { mac_->debug ("At %f in Mac %d link handoff complete\n", NOW, mac_->addr()); mac_->send_link_handoff_complete (mac_->addr(), scan_info_->serving_bsid, peer->getPeerNode()); scan_info_->handoff_timeout = -1; } mac_->debug ("At %f in Mac %d, send link up\n", NOW, mac_->addr()); mac_->send_link_up (mac_->addr(), peer->getPeerNode());#endif } else { //status failure mac_->debug ("At %f in Mac %d, registration failed (nbretry=%d)\n", NOW, mac_->addr(), nb_reg_retry_); if (nb_reg_retry_ == mac_->macmib_.reg_req_retry) {#ifdef USE_802_21 if (scan_info_ && scan_info_->handoff_timeout == -2) { mac_->debug ("At %f in Mac %d link handoff failure\n", NOW, mac_->addr()); mac_->send_link_handoff_failure (mac_->addr(), scan_info_->serving_bsid, peer->getPeerNode()); scan_info_->handoff_timeout = -1; }#endif lost_synch (); } else { send_registration(); } }}/** * Send a scanning message to the serving BS */void SSscheduler::send_scan_request (){ Packet *p; struct hdr_cmn *ch; hdr_mac802_16 *wimaxHdr; mac802_16_mob_scn_req_frame *req_frame; PeerNode *peer; mac_->debug ("At %f in Mac %d enqueue scan request\n", NOW, mac_->addr()); //create packet for request p = mac_->getPacket (); ch = HDR_CMN(p); wimaxHdr = HDR_MAC802_16(p); p->allocdata (sizeof (struct mac802_16_mob_scn_req_frame)); req_frame = (mac802_16_mob_scn_req_frame*) p->accessdata(); req_frame->type = MAC_MOB_SCN_REQ; req_frame->scan_duration = mac_->macmib_.scan_duration; req_frame->interleaving_interval = mac_->macmib_.interleaving; req_frame->scan_iteration = mac_->macmib_.scan_iteration; req_frame->n_recommended_bs_index = 0; req_frame->n_recommended_bs_full = 0; ch->size() += Mac802_16pkt::getMOB_SCN_REQ_size(req_frame); peer = mac_->getPeerNode_head(); wimaxHdr->header.cid = peer->getPrimary()->get_cid(); peer->getPrimary()->enqueue (p); //start reg timeout if (t44timer_==NULL) { t44timer_ = new WimaxT44Timer (mac_); } t44timer_->start (mac_->macmib_.t44_timeout); nb_scan_req_++;}/** * Process a scanning response message * @param frame The scanning response frame */void SSscheduler::process_scan_rsp (mac802_16_mob_scn_rsp_frame *frame){ //PeerNode *peer = mac_->getPeerNode_head(); if (frame->scan_duration != 0) { //scanning accepted mac_->debug ("At %f in Mac %d, scanning accepted (dur=%d it=%d)\n", NOW, mac_->addr(), frame->scan_duration,frame->scan_iteration ); //allocate data for scanning //scan_info_ = (struct scanning_structure *) malloc (sizeof (struct scanning_structure)); //store copy of frame scan_info_->rsp = (struct mac802_16_mob_scn_rsp_frame *) malloc (sizeof (struct mac802_16_mob_scn_rsp_frame)); memcpy (scan_info_->rsp, frame, sizeof (struct mac802_16_mob_scn_rsp_frame)); scan_info_->iteration = 0; scan_info_->count = frame->start_frame; scan_info_->substate = SCAN_PENDING; scan_info_->handoff_timeout = 0; scan_info_->serving_bsid = mac_->getPeerNode_head()->getPeerNode(); scan_info_->nb_rdv_timers = 0; //mark all neighbors as not detected for (int i = 0 ; i < nbr_db_->getNbNeighbor() ; i++) { nbr_db_->getNeighbors()[i]->setDetected(false); } //schedule timer for rdv time (for now just use full) //TBD: add rec_bs_index mac_->debug ("\tstart scan in %d frames (%f)\n",frame->start_frame,NOW+frame->start_frame*mac_->getFrameDuration()); for (int i = 0 ; i < scan_info_->rsp->n_recommended_bs_full ; i++) { if (scan_info_->rsp->rec_bs_full[i].scanning_type ==SCAN_ASSOC_LVL1 || scan_info_->rsp->rec_bs_full[i].scanning_type==SCAN_ASSOC_LVL2) { debug2 ("Creating timer for bs=%d at time %f\n", scan_info_->rsp->rec_bs_full[i].recommended_bs_id, NOW+mac_->getFrameDuration()*scan_info_->rsp->rec_bs_full[i].rdv_time); assert (nbr_db_->getNeighbor (scan_info_->rsp->rec_bs_full[i].recommended_bs_id)); //get the channel int ch = mac_->getChannel (nbr_db_->getNeighbor (scan_info_->rsp->rec_bs_full[i].recommended_bs_id)->getDCD ()->frequency*1000); assert (ch!=-1); WimaxRdvTimer *timer = new WimaxRdvTimer (mac_, ch); scan_info_->rdv_timers[scan_info_->nb_rdv_timers++] = timer; timer->start(mac_->getFrameDuration()*scan_info_->rsp->rec_bs_full[i].rdv_time); } } } else { mac_->debug ("At %f in Mac %d, scanning denied\n", NOW, mac_->addr()); //what do I do??? } t44timer_->stop();}/** * Start/Continue scanning */void SSscheduler::resume_scanning (){ if (scan_info_->iteration == 0) mac_->debug ("At %f in Mac %d, starts scanning\n", NOW, mac_->addr()); else mac_->debug ("At %f in Mac %d, resume scanning\n", NOW, mac_->addr()); scan_info_->substate = SCANNING; //backup current state scan_info_->normal_state.state_info = mac_->backup_state(); if (t1timer_->busy()) t1timer_->pause(); scan_info_->normal_state.t1timer = t1timer_; if (t2timer_->busy()) t2timer_->pause(); scan_info_->normal_state.t2timer = t2timer_;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -