patch-wimax-prerelease-092206
上传用户:hzie11
上传日期:2013-10-07
资源大小:1487k
文件大小:477k
- + map_->getDlSubframe()->getTimer()->reset();
- + if (ul_timer_->status()==TIMER_PENDING)
- + ul_timer_->cancel();
- + map_->getUlSubframe()->getTimer()->reset();
- +}
- +
- +/**
- + * Called when a timer expires
- + * @param The timer ID
- + */
- +void SSscheduler::expire (timer_id id)
- +{
- + switch (id) {
- + case WimaxT21TimerID:
- + mac_->debug ("At %f in Mac %d, synchronization failedn", NOW, mac_->addr());
- + //go to next channel
- + mac_->nextChannel();
- + t21timer_->start (mac_->macmib_.t21_timeout);
- + break;
- + case WimaxLostDLMAPTimerID:
- + mac_->debug ("At %f in Mac %d, lost synchronization (DL_MAP)n", NOW, mac_->addr());
- + lost_synch ();
- + break;
- + case WimaxT1TimerID:
- + mac_->debug ("At %f in Mac %d, lost synchronization (DCD)n", NOW, mac_->addr());
- + lost_synch ();
- + break;
- + case WimaxLostULMAPTimerID:
- + mac_->debug ("At %f in Mac %d, lost synchronization (UL_MAP)n", NOW, mac_->addr());
- + lost_synch ();
- + break;
- + case WimaxT12TimerID:
- + mac_->debug ("At %f in Mac %d, lost uplink param (UCD)n", NOW, mac_->addr());
- + lost_synch ();
- + break;
- + case WimaxT2TimerID:
- + mac_->debug ("At %f in Mac %d, lost synchronization (RNG)n", NOW, mac_->addr());
- + map_->getUlSubframe()->getRanging()->removeRequest ();
- + lost_synch ();
- + break;
- + case WimaxT3TimerID:
- + mac_->debug ("At %f in Mac %d, no response from BSn", NOW, mac_->addr());
- + //we reach the maximum number of retries
- + //mark DL channel usuable (i.e we go to next)
- + map_->getUlSubframe()->getRanging()->removeRequest ();
- + mac_->nextChannel();
- + lost_synch ();
- + break;
- + case WimaxT6TimerID:
- + mac_->debug ("At %f in Mac %d, registration timeout (nbretry=%d)n", NOW, mac_->addr(),
- + nb_reg_retry_);
- + if (nb_reg_retry_ == mac_->macmib_.reg_req_retry) {
- + mac_->debug ("tmax retry excedeedn");
- + lost_synch ();
- + } else {
- + send_registration();
- + }
- + break;
- + case WimaxT44TimerID:
- + mac_->debug ("At %f in Mac %d, did not receive MOB_SCN-RSP (nb_retry=%d)n", NOW, mac_->addr(), nb_scan_req_);
- + if (nb_scan_req_ <= mac_->macmib_.scan_req_retry) {
- + send_scan_request ();
- + } else { //reset for next time
- + nb_scan_req_ = 0;
- + }
- + break;
- + case WimaxScanIntervalTimerID:
- + pause_scanning ();
- + break;
- + case WimaxRdvTimerID:
- + //we need to meet at another station. We cancel the current scanning
- + //lost_synch ();
- + mac_->debug ("At %f in Mac %d Rdv timer expiredn", NOW, mac_->addr());
- + break;
- + default:
- + mac_->debug ("Trigger unkownn");
- + }
- +}
- +
- +/**** Packet processing methods ****/
- +
- +/**
- + * Process a DL_MAP message
- + * @param frame The dl_map information
- + */
- +void SSscheduler::process_dl_map (mac802_16_dl_map_frame *frame)
- +{
- + assert (frame);
- +
- + //create an entry for the BS
- + if (mac_->getPeerNode (frame->bsid)==NULL)
- + mac_->addPeerNode (new PeerNode (frame->bsid));
- +
- + map_->parseDLMAPframe (frame);
- +
- + if (mac_->getMacState()==MAC802_16_WAIT_DL_SYNCH) {
- + mac_->debug ("At %f in %d, received DL_MAP for synch from %d (substate=%d)n",
- + NOW, mac_->addr(), frame->bsid,scan_info_->substate);
- + assert (t21timer_->busy()!=0);
- + //synchronization is done
- + t21timer_->stop();
- + //start lost_dl_map
- + lostDLMAPtimer_->start (mac_->macmib_.lost_dlmap_interval);
- + //start T1: DCD
- + t1timer_->start (mac_->macmib_.t1_timeout);
- + //start T12: UCD
- + t12timer_->start (mac_->macmib_.t12_timeout);
- +
- +#ifdef USE_802_21
- + mac_->debug ("At %f in Mac %d, send link detectedn", NOW, mac_->addr());
- + mac_->send_link_detected (mac_->addr(), frame->bsid, 1);
- +#endif
- +
- + mac_->setMacState(MAC802_16_WAIT_DL_SYNCH_DCD);
- +
- + //if I am doing handoff and we have dcd/ucd information
- + //from scanning, use it
- + if (scan_info_->substate == HANDOVER || scan_info_->substate == SCANNING) {
- + if (scan_info_->substate == SCANNING) {
- + if (scan_info_->nbr == NULL || scan_info_->nbr->getID()!=frame->bsid) {
- + //check if an entry already exist in the database
- + scan_info_->nbr = nbr_db_->getNeighbor (frame->bsid);
- + if (scan_info_->nbr == NULL) {
- + //create entry
- + debug2 ("Creating nbr info for node %dn", frame->bsid);
- + scan_info_->nbr = new NeighborEntry (frame->bsid);
- + nbr_db_->addNeighbor (scan_info_->nbr);
- + } else {
- + debug2 ("loaded nbr infon");
- + if (scan_info_->nbr->isDetected ()) {
- + //we already synchronized with this AP...skip channel
- + mac_->nextChannel();
- + lost_synch ();
- + return;
- + }
- + }
- + }
- + }//if HANDOVER, scan_info_->nbr is already set
- +
- + bool error = false;
- + //we check if we can read the DL_MAP
- + mac802_16_dcd_frame *dcd = scan_info_->nbr->getDCD();
- + if (dcd!=NULL) {
- + debug2 ("Check if we can decode stored dcdn");
- + //check if we can decode dl_map with previously acquired dcd
- + bool found;
- + for (int i = 0 ; !error && i < map_->getDlSubframe()->getPdu()->getNbBurst() ; i++) {
- + int diuc = map_->getDlSubframe()->getPdu()->getBurst(i)->getIUC();
- + if (diuc == DIUC_END_OF_MAP)
- + continue;
- + found = false;
- + for (u_int32_t j = 0 ; !found && j < dcd->nb_prof; j++) {
- + found = dcd->profiles[j].diuc==diuc;
- + }
- + error = !found;
- + }
- + if (!error)
- + process_dcd (dcd);
- + } else {
- + debug2 ("No DCD information foundn");
- + }
- + }
- + } else {
- + //maintain synchronization
- + assert (lostDLMAPtimer_->busy());
- + lostDLMAPtimer_->stop();
- + //printf ("update dlmap timern");
- + lostDLMAPtimer_->start (mac_->macmib_.lost_dlmap_interval);
- +
- + if (mac_->getMacState()!= MAC802_16_WAIT_DL_SYNCH_DCD
- + && mac_->getMacState()!=MAC802_16_UL_PARAM) {
- +
- + //since the map may have changed, we need to adjust the timer
- + //for the DLSubframe
- + double stime = map_->getStarttime();
- + stime += map_->getDlSubframe()->getPdu()->getBurst(1)->getStarttime()*mac_->getPhy()->getSymbolTime();
- + //printf ("received dl..needs to update expiration to %f, %f,%fn", stime, NOW,map_->getStarttime());
- + map_->getDlSubframe()->getTimer()->resched (stime-NOW);
- + dl_timer_->resched (map_->getStarttime()+mac_->getFrameDuration()-NOW);
- + }
- + }
- +}
- +
- +/**
- + * Process a DCD message
- + * @param frame The dcd information
- + */
- +void SSscheduler::process_dcd (mac802_16_dcd_frame *frame)
- +{
- + if (mac_->getMacState()==MAC802_16_WAIT_DL_SYNCH) {
- + //we are waiting for DL_MAP, ignore this message
- + return;
- + }
- +
- + map_->parseDCDframe (frame);
- + if (mac_->getMacState()==MAC802_16_WAIT_DL_SYNCH_DCD) {
- + mac_->debug ("At %f in %d, received DCD for synchn", NOW, mac_->addr());
- + //now I have all information such as frame duration
- + //adjust timing in case the frame we received the DL_MAP
- + //and the DCD is different
- + while (NOW - map_->getStarttime () > mac_->getFrameDuration()) {
- + map_->setStarttime (map_->getStarttime()+mac_->getFrameDuration());
- + }
- +
- + //store information to be used during potential handoff
- + if (scan_info_->substate == SCANNING) {
- + mac802_16_dcd_frame *tmp = (mac802_16_dcd_frame *) malloc (sizeof (mac802_16_dcd_frame));
- + memcpy (tmp, frame, sizeof (mac802_16_dcd_frame));
- + mac802_16_dcd_frame *old = scan_info_->nbr->getDCD();
- + if (frame == old)
- + frame = tmp;
- + if (old)
- + free (old); //free previous entry
- + scan_info_->nbr->setDCD(tmp); //set new one
- + }
- +
- + mac_->setMacState(MAC802_16_UL_PARAM);
- + //we can schedule next frame
- + //printf ("SS schedule next frame at %fn", map_->getStarttime()+mac_->getFrameDuration());
- + //dl_timer_->sched (map_->getStarttime()+mac_->getFrameDuration()-NOW);
- + }
- +
- + if (t1timer_->busy()!=0) {
- + //we were waiting for this packet
- + t1timer_->stop();
- + t1timer_->start (mac_->macmib_.t1_timeout);
- + }
- +}
- +
- +/**
- + * Process a UCD message
- + * @param frame The ucd information
- + */
- +void SSscheduler::process_ucd (mac802_16_ucd_frame *frame)
- +{
- + if (mac_->getMacState()==MAC802_16_WAIT_DL_SYNCH
- + ||mac_->getMacState()==MAC802_16_WAIT_DL_SYNCH_DCD) {
- + //discard the packet
- + return;
- + }
- + assert (t12timer_->busy()!=0); //we are waiting for this packet
- +
- + if (mac_->getMacState()==MAC802_16_UL_PARAM) {
- + //check if uplink channel usable
- + mac_->debug ("At %f in %d, received UL(UCD) parametersn", NOW, mac_->addr());
- + //start T2: ranging
- + t2timer_->start (mac_->macmib_.t2_timeout);
- + //start Lost UL-MAP
- + lostULMAPtimer_->start (mac_->macmib_.lost_ulmap_interval);
- +
- + //store information to be used during potential handoff
- + if (scan_info_->substate == SCANNING) {
- + mac802_16_ucd_frame *tmp = (mac802_16_ucd_frame *) malloc (sizeof (mac802_16_ucd_frame));
- + memcpy (tmp, frame, sizeof (mac802_16_ucd_frame));
- + mac802_16_ucd_frame *old = scan_info_->nbr->getUCD();
- + if (frame == old)
- + frame = tmp;
- + if (old)
- + free (old); //free previous entry
- + scan_info_->nbr->setUCD(tmp); //set new one
- +
- + }
- +
- + //change state
- + mac_->setMacState (MAC802_16_RANGING);
- + }
- +
- + //reset T12
- + t12timer_->stop();
- + t12timer_->start (mac_->macmib_.t12_timeout);
- +
- + map_->parseUCDframe (frame);
- +}
- +
- +/**
- + * Process a UL_MAP message
- + * @param frame The ul_map information
- + */
- +void SSscheduler::process_ul_map (mac802_16_ul_map_frame *frame)
- +{
- + if (mac_->getMacState()==MAC802_16_WAIT_DL_SYNCH
- + || mac_->getMacState()==MAC802_16_WAIT_DL_SYNCH_DCD) {
- + //discard the packet
- + return;
- + }
- +
- + if (mac_->getMacState()==MAC802_16_UL_PARAM) {
- + if (scan_info_->substate == HANDOVER || scan_info_->substate==SCANNING) {
- + FrameMap *tmpMap = new FrameMap (mac_);
- + tmpMap->parseULMAPframe (frame);
- + //printf ("Checking if we can read UL_MAPn");
- + bool error = false;
- + //we check if we can read the UL_MAP
- + mac802_16_ucd_frame *ucd = scan_info_->nbr->getUCD();
- + if (ucd!=NULL) {
- + //check if we can decode ul_map with previously acquired ucd
- + bool found;
- + for (int i = 0 ; !error && i < tmpMap->getUlSubframe()->getNbPdu() ; i++) {
- + UlBurst *b = (UlBurst*)tmpMap->getUlSubframe()->getPhyPdu(i)->getBurst(0);
- + int uiuc = b->getIUC();
- + if (uiuc == UIUC_END_OF_MAP)
- + continue;
- + if (uiuc == UIUC_EXT_UIUC && b->getExtendedUIUC ()== UIUC_FAST_RANGING)
- + uiuc = b->getFastRangingUIUC();
- + found = false;
- + for (u_int32_t j = 0 ; !found && j < ucd->nb_prof; j++) {
- + //printf ("t prof=%d, search=%dn", ucd->profiles[j].uiuc, uiuc);
- + found = ucd->profiles[j].uiuc==uiuc;
- + }
- + error = !found;
- + }
- + if (!error)
- + process_ucd (ucd);
- + }
- + delete (tmpMap);
- + if (error) {
- + //we cannot read message
- + return;
- + }
- + } else
- + return;
- + }
- +
- + if (scan_info_->substate == SCANNING) {
- + //TBD: add checking scanning type for the given station
- + u_char scanning_type = 0;
- + for (int i = 0 ; i < scan_info_->rsp->n_recommended_bs_full ; i++) {
- + if (scan_info_->rsp->rec_bs_full[i].recommended_bs_id == scan_info_->nbr->getID()) {
- + scanning_type = scan_info_->rsp->rec_bs_full[i].scanning_type;
- + break;
- + }
- + }
- + if (scanning_type == 0) {
- + //store information about possible base station and keep scanning
- + scan_info_->nbr->getState()->state_info= mac_->backup_state();
- + mac_->debug ("At %f in Mac %d bs %d detected during scanningn", NOW, mac_->addr(), scan_info_->nbr->getID());
- + scan_info_->nbr->setDetected (true);
- + mac_->nextChannel();
- + lost_synch ();
- + return;
- + }
- + }
- +
- + map_->parseULMAPframe (frame);
- + if (mac_->getMacState()==MAC802_16_RANGING) {
- + //execute ranging
- + assert (t2timer_->busy()!=0); //we are waiting for this packet
- + init_ranging ();
- + }
- +
- + //schedule when to take care of outgoing packets
- + double start = map_->getStarttime();
- + start += map_->getUlSubframe()->getStarttime()*mac_->getPhy()->getPS(); //offset for ul subframe
- + start -= NOW; //works with relative time not absolute
- + debug2 ("Uplink starts in %f (framestate=%f) %f %fn",
- + start,
- + map_->getStarttime(),
- + mac_->getFrameDuration()/mac_->getPhy()->getPS(),
- + mac_->getFrameDuration()/mac_->getPhy()->getSymbolTime());
- +
- + ul_timer_->resched (start);
- +
- + //reset Lost UL-Map
- + lostULMAPtimer_->stop();
- + lostULMAPtimer_->start (mac_->macmib_.lost_ulmap_interval);
- +}
- +
- +/**
- + * Process a ranging response message
- + * @param frame The ranging response frame
- + */
- +void SSscheduler::process_ranging_rsp (mac802_16_rng_rsp_frame *frame)
- +{
- + //check the destination
- + if (frame->ss_mac_address != mac_->addr())
- + return;
- +
- + Connection *basic, *primary;
- + PeerNode *peer;
- +
- + //TBD: add processing for periodic ranging
- +
- + //check status
- + switch (frame->rng_status) {
- + case RNG_SUCCESS:
- + mac_->debug ("Ranging response: status = Success.Basic=%d, Primary=%dn",
- + 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 replyn");
- + 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 scanningn", 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 rangingn");
- + //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 opportunityn", 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 completen", 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 upn", 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 failuren", 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 requestn", 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 %fn",
- + 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 deniedn", 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 scanningn", NOW, mac_->addr());
- + else
- + mac_->debug ("At %f in Mac %d, resume scanningn", 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_;
- + if (t6timer_->busy())
- + t6timer_->pause();
- + scan_info_->normal_state.t6timer = t6timer_;
- + if (t12timer_->busy())
- + t12timer_->pause();
- + scan_info_->normal_state.t12timer = t12timer_;
- + if (t21timer_->busy())
- + t21timer_->pause();
- + scan_info_->normal_state.t21timer = t21timer_;
- + if (lostDLMAPtimer_->busy())
- + lostDLMAPtimer_->pause();
- + scan_info_->normal_state.lostDLMAPtimer = lostDLMAPtimer_;
- + if (lostULMAPtimer_->busy())
- + lostULMAPtimer_->pause();
- + scan_info_->normal_state.lostULMAPtimer = lostULMAPtimer_;
- + scan_info_->normal_state.map = map_;
- +
- + if (scan_info_->iteration == 0) {
- + //reset state
- + t1timer_ = new WimaxT1Timer (mac_);
- + t2timer_ = new WimaxT2Timer (mac_);
- + t6timer_ = new WimaxT6Timer (mac_);
- + t12timer_ = new WimaxT12Timer (mac_);
- + t21timer_ = new WimaxT21Timer (mac_);
- + lostDLMAPtimer_ = new WimaxLostDLMAPTimer (mac_);
- + lostULMAPtimer_ = new WimaxLostULMAPTimer (mac_);
- +
- + map_ = new FrameMap (mac_);
- +
- + mac_->nextChannel();
- +
- + scan_info_->scn_timer_ = new WimaxScanIntervalTimer (mac_);
- +
- + //start waiting for DL synch
- + mac_->setMacState (MAC802_16_WAIT_DL_SYNCH);
- + t21timer_->start (mac_->macmib_.t21_timeout);
- + if (dl_timer_->status()==TIMER_PENDING)
- + dl_timer_->cancel();
- + map_->getDlSubframe()->getTimer()->reset();
- + if (ul_timer_->status()==TIMER_PENDING)
- + ul_timer_->cancel();
- + map_->getUlSubframe()->getTimer()->reset();
- +
- +
- + }else{
- + //restore where we left
- + //restore previous timers
- + mac_->restore_state(scan_info_->scan_state.state_info);
- + t1timer_ = scan_info_->scan_state.t1timer;
- + if (t1timer_->paused())
- + t1timer_->resume();
- + t2timer_ = scan_info_->scan_state.t2timer;
- + if (t2timer_->paused())
- + t2timer_->resume();
- + t6timer_ = scan_info_->scan_state.t6timer;
- + if (t6timer_->paused())
- + t6timer_->resume();
- + t12timer_ = scan_info_->scan_state.t12timer;
- + if (t12timer_->paused())
- + t12timer_->resume();
- + t21timer_ = scan_info_->scan_state.t21timer;
- + if (t21timer_->paused())
- + t21timer_->resume();
- + lostDLMAPtimer_ = scan_info_->scan_state.lostDLMAPtimer;
- + if (lostDLMAPtimer_->paused())
- + lostDLMAPtimer_->resume();
- + lostULMAPtimer_ = scan_info_->scan_state.lostULMAPtimer;
- + if (lostULMAPtimer_->paused())
- + lostULMAPtimer_->resume();
- + map_ = scan_info_->scan_state.map;
- +
- + mac_->getPhy()->setMode (OFDM_RECV);
- +
- + if (ul_timer_->status()==TIMER_PENDING)
- + ul_timer_->cancel();
- + }
- + mac_->setNotify_upper (false);
- + //printf ("Scan duration=%d, frameduration=%fn", scan_info_->rsp->scan_duration, mac_->getFrameDuration());
- + scan_info_->scn_timer_->start (scan_info_->rsp->scan_duration*mac_->getFrameDuration());
- + scan_info_->iteration++;
- +
- +}
- +
- +/**
- + * Pause scanning
- + */
- +void SSscheduler::pause_scanning ()
- +{
- + if (scan_info_->iteration < scan_info_->rsp->scan_iteration)
- + mac_->debug ("At %f in Mac %d, pause scanningn", NOW, mac_->addr());
- + else
- + mac_->debug ("At %f in Mac %d, stop scanningn", NOW, mac_->addr());
- +
- + //return to normal mode
- + if (scan_info_->iteration < scan_info_->rsp->scan_iteration) {
- + //backup current state
- + scan_info_->scan_state.state_info = mac_->backup_state();
- + if (t1timer_->busy())
- + t1timer_->pause();
- + scan_info_->scan_state.t1timer = t1timer_;
- + if (t2timer_->busy())
- + t2timer_->pause();
- + scan_info_->scan_state.t2timer = t2timer_;
- + if (t6timer_->busy())
- + t6timer_->pause();
- + scan_info_->scan_state.t6timer = t6timer_;
- + if (t12timer_->busy())
- + t12timer_->pause();
- + scan_info_->scan_state.t12timer = t12timer_;
- + if (t21timer_->busy())
- + t21timer_->pause();
- + scan_info_->scan_state.t21timer = t21timer_;
- + if (lostDLMAPtimer_->busy())
- + lostDLMAPtimer_->pause();
- + scan_info_->scan_state.lostDLMAPtimer = lostDLMAPtimer_;
- + if (lostULMAPtimer_->busy())
- + lostULMAPtimer_->pause();
- + scan_info_->scan_state.lostULMAPtimer = lostULMAPtimer_;
- + scan_info_->scan_state.map = map_;
- +
- + scan_info_->count = scan_info_->rsp->interleaving_interval;
- +
- + } else {
- + //else scanning is over, no need to save data
- + //reset timers
- + if (t1timer_->busy()!=0)
- + t1timer_->stop();
- + delete (t1timer_);
- + if (t12timer_->busy()!=0)
- + t12timer_->stop();
- + delete (t12timer_);
- + if (t21timer_->busy()!=0)
- + t21timer_->stop();
- + delete (t21timer_);
- + if (lostDLMAPtimer_->busy()!=0)
- + lostDLMAPtimer_->stop();
- + delete (lostDLMAPtimer_);
- + if (lostULMAPtimer_->busy()!=0)
- + lostULMAPtimer_->stop();
- + delete (lostULMAPtimer_);
- + if (t2timer_->busy()!=0)
- + t2timer_->stop();
- + delete (t2timer_);
- + }
- + //restore previous timers
- + mac_->restore_state(scan_info_->normal_state.state_info);
- + t1timer_ = scan_info_->normal_state.t1timer;
- + if (t1timer_->paused())
- + t1timer_->resume();
- + t2timer_ = scan_info_->normal_state.t2timer;
- + if (t2timer_->paused())
- + t2timer_->resume();
- + t6timer_ = scan_info_->normal_state.t6timer;
- + if (t6timer_->paused())
- + t6timer_->resume();
- + t12timer_ = scan_info_->normal_state.t12timer;
- + if (t12timer_->paused())
- + t12timer_->resume();
- + t21timer_ = scan_info_->normal_state.t21timer;
- + if (t21timer_->paused())
- + t21timer_->resume();
- + lostDLMAPtimer_ = scan_info_->normal_state.lostDLMAPtimer;
- + if (lostDLMAPtimer_->paused())
- + lostDLMAPtimer_->resume();
- + lostULMAPtimer_ = scan_info_->normal_state.lostULMAPtimer;
- + if (lostULMAPtimer_->paused())
- + lostULMAPtimer_->resume();
- + map_ = scan_info_->normal_state.map;
- +
- + mac_->setNotify_upper (true);
- + dl_timer_->resched (0);
- +
- + if (scan_info_->iteration == scan_info_->rsp->scan_iteration) {
- + scan_info_->substate = NORMAL;
- +
- + /** here we check if there is a better BS **/
- + send_msho_req();
- +
- + scan_info_->count--; //to avoid restarting scanning
- + //delete (scan_info_);
- + //scan_info_ = NULL;
- + } else {
- + scan_info_->substate = SCAN_PENDING;
- + }
- +
- +}
- +
- +/**
- + * Send a MSHO-REQ message to the BS
- + */
- +void SSscheduler::send_msho_req ()
- +{
- + Packet *p;
- + struct hdr_cmn *ch;
- + hdr_mac802_16 *wimaxHdr;
- + mac802_16_mob_msho_req_frame *req_frame;
- + double rssi;
- +
- + PeerNode *peer = mac_->getPeerNode_head();
- +
- + int nbPref = 0;
- + for (int i = 0 ; i < nbr_db_->getNbNeighbor() ; i++) {
- + NeighborEntry *entry = nbr_db_->getNeighbors()[i];
- + if (entry->isDetected()) {
- + mac_->debug ("At %f in Mac %d Found new AP %d..need to send HO messagen",NOW, mac_->addr(), entry->getID());
- + nbPref++;
- + }
- + }
- +
- + if (nbPref==0)
- + return; //no other BS found
- +
- + //create packet for request
- + p = mac_->getPacket ();
- + ch = HDR_CMN(p);
- + wimaxHdr = HDR_MAC802_16(p);
- + p->allocdata (sizeof (struct mac802_16_mob_msho_req_frame)+nbPref*sizeof (mac802_16_mob_msho_req_bs_index));
- + req_frame = (mac802_16_mob_msho_req_frame*) p->accessdata();
- + memset (req_frame, 0, sizeof (mac802_16_mob_msho_req_bs_index));
- + req_frame->type = MAC_MOB_MSHO_REQ;
- +
- + req_frame->report_metric = 0x2; //include RSSI
- + req_frame->n_new_bs_index = 0;
- + req_frame->n_new_bs_full = nbPref;
- + req_frame->n_current_bs = 1;
- + rssi = mac_->getPeerNode_head()->getStatWatch()->average();
- + debug2 ("RSSI=%e, %d, bs=%dn", rssi, (u_char)((rssi+103.75)/0.25), mac_->getPeerNode_head()->getPeerNode());
- + req_frame->bs_current[0].temp_bsid = mac_->getPeerNode_head()->getPeerNode();
- + req_frame->bs_current[0].bs_rssi_mean = (u_char)((rssi+103.75)/0.25);
- + for (int i = 0, j=0; i < nbr_db_->getNbNeighbor() ; i++) {
- + NeighborEntry *entry = nbr_db_->getNeighbors()[i];
- + //TBD: there is an error measuring RSSI for current BS during scanning
- + //anyway, we don't put it in the least, so it's ok for now
- + if (entry->isDetected() && entry->getID()!= mac_->getPeerNode_head()->getPeerNode()) {
- + req_frame->bs_full[j].neighbor_bs_index = entry->getID();
- + rssi = entry->getState()->state_info->peer_list->lh_first->getStatWatch()->average();
- + debug2 ("RSSI=%e, %d, bs=%dn", rssi, (u_char)((rssi+103.75)/0.25), entry->getID());
- + req_frame->bs_full[j].bs_rssi_mean = (u_char)((rssi+103.75)/0.25);
- + //the rest of req_frame->bs_full is unused for now..
- + req_frame->bs_full[j].arrival_time_diff_ind = 0;
- + j++;
- + }
- + }
- +
- + ch->size() += Mac802_16pkt::getMOB_MSHO_REQ_size(req_frame);
- + wimaxHdr->header.cid = peer->getPrimary()->get_cid();
- + peer->getPrimary()->enqueue (p);
- +}
- +
- +/**
- + * Process a BSHO-RSP message
- + * @param frame The handover response frame
- + */
- +void SSscheduler::process_bsho_rsp (mac802_16_mob_bsho_rsp_frame *frame)
- +{
- + mac_->debug ("At %f in Mac %d, received handover responsen", NOW, mac_->addr());
- +
- + //go and switch to the channel recommended by the BS
- + int targetBS = frame->n_rec[0].neighbor_bsid;
- + PeerNode *peer = mac_->getPeerNode_head();
- +
- + if (peer->getPeerNode ()==targetBS) {
- + mac_->debug ("tDecision to stay in current BSn");
- + return;
- + }
- + scan_info_->nbr = nbr_db_->getNeighbor (targetBS);
- +
- + Packet *p;
- + struct hdr_cmn *ch;
- + hdr_mac802_16 *wimaxHdr;
- + mac802_16_mob_ho_ind_frame *ind_frame;
- +
- +
- + p = mac_->getPacket ();
- + ch = HDR_CMN(p);
- + wimaxHdr = HDR_MAC802_16(p);
- + p->allocdata (sizeof (struct mac802_16_mob_ho_ind_frame));
- + ind_frame = (mac802_16_mob_ho_ind_frame*) p->accessdata();
- + ind_frame->type = MAC_MOB_HO_IND;
- +
- + ind_frame->mode = 0; //HO
- + ind_frame->ho_ind_type = 0; //Serving BS release
- + ind_frame->rng_param_valid_ind = 0;
- + ind_frame->target_bsid = targetBS;
- +
- + ch->size() += Mac802_16pkt::getMOB_HO_IND_size(ind_frame);
- + wimaxHdr->header.cid = peer->getPrimary()->get_cid();
- + peer->getPrimary()->enqueue (p);
- +
- +#ifdef USE_802_21
- + mac_->send_link_handoff_imminent (mac_->addr(), peer->getPeerNode(), targetBS);
- + mac_->debug ("At %f in Mac %d link handoff imminentn", NOW, mac_->addr());
- +
- +#endif
- +
- + mac_->debug ("tHandover to BS %dn", targetBS);
- + scan_info_->handoff_timeout = 20;
- + scan_info_->substate = HANDOVER_PENDING;
- + //mac_->setChannel (scan_info_->bs_infos[i].channel);
- + //lost_synch ();
- +
- +}
- +
- +/**
- + * Process a NBR_ADV message
- + * @param frame The handover response frame
- + */
- +void SSscheduler::process_nbr_adv (mac802_16_mob_nbr_adv_frame *frame)
- +{
- + mac_->debug ("At %f in Mac %d, received neighbor advertisementn", NOW, mac_->addr());
- +
- + mac802_16_mob_nbr_adv_frame *copy;
- +
- + copy = (mac802_16_mob_nbr_adv_frame *) malloc (sizeof (mac802_16_mob_nbr_adv_frame));
- + memcpy (copy, frame, sizeof (mac802_16_mob_nbr_adv_frame));
- + //all we need is to store the information. We will process that only
- + //when we will look for another station
- + for (int i = 0 ; i < frame->n_neighbors ; i++) {
- + int nbrid = frame->nbr_info[i].nbr_bsid;
- + mac802_16_nbr_adv_info *info = (mac802_16_nbr_adv_info *) malloc (sizeof(mac802_16_nbr_adv_info));
- + NeighborEntry *entry = nbr_db_->getNeighbor (nbrid);
- + if (entry==NULL){
- + entry = new NeighborEntry (nbrid);
- + nbr_db_->addNeighbor (entry);
- + }
- + memcpy(info, &(frame->nbr_info[i]), sizeof(mac802_16_nbr_adv_info));
- + if (entry->getNbrAdvMessage ())
- + free (entry->getNbrAdvMessage());
- + entry->setNbrAdvMessage(info);
- + if (info->dcd_included) {
- + //set DCD
- + mac802_16_dcd_frame *tmp = (mac802_16_dcd_frame *)malloc (sizeof(mac802_16_dcd_frame));
- + memcpy(tmp, &(info->dcd_settings), sizeof(mac802_16_dcd_frame));
- + entry->setDCD(tmp);
- + }
- + else
- + entry->setDCD(NULL);
- + if (info->ucd_included) {
- + //set DCD
- + mac802_16_ucd_frame *tmp = (mac802_16_ucd_frame *)malloc (sizeof(mac802_16_ucd_frame));
- + memcpy(tmp, &(info->ucd_settings), sizeof(mac802_16_ucd_frame));
- + entry->setUCD(tmp);
- +#ifdef DEBUG_WIMAX
- + debug2 ("Dump information nbr in Mac %d for nbr %d %lxn", mac_->addr(), nbrid, (long)tmp);
- + int nb_prof = tmp->nb_prof;
- + mac802_16_ucd_profile *profiles = tmp->profiles;
- + for (int i = 0 ; i < nb_prof ; i++) {
- + debug2 ("t Reading ul profile %i: f=%d, rate=%d, iuc=%dn", i, 0, profiles[i].fec, profiles[i].uiuc);
- + }
- +#endif
- + }
- + else
- + entry->setUCD(NULL);
- + }
- +
- +}
- diff -Naur ns-2.29-org/wimax/scheduling/ssscheduler.h ns-2.29/wimax/scheduling/ssscheduler.h
- --- ns-2.29-org/wimax/scheduling/ssscheduler.h 1969-12-31 19:00:00.000000000 -0500
- +++ ns-2.29/wimax/scheduling/ssscheduler.h 2006-09-22 17:27:47.000000000 -0400
- @@ -0,0 +1,242 @@
- +/* 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
- + */
- +
- +#ifndef SSSCHEDULER_H
- +#define SSSCHEDULER_H
- +
- +#include "wimaxscheduler.h"
- +
- +/** The state of the scheduler */
- +enum ss_sched_state {
- + NORMAL, //Normal state
- + SCAN_PENDING, //Normal period but pending scanning to start/resume
- + SCANNING, //Currently scanning
- + HANDOVER_PENDING, //Normal state but handover to start
- + HANDOVER //Executing handover
- +};
- +
- +
- +/** Data structure to store scanning information */
- +struct scanning_structure {
- + struct mac802_16_mob_scn_rsp_frame *rsp; //response from BS
- + struct sched_state_info scan_state; //current scanning state
- + struct sched_state_info normal_state; //backup of normal state
- + int iteration; //current iteration
- + WimaxScanIntervalTimer *scn_timer_; //timer to notify end of scanning period
- + int count; //number of frame before switching to scanning
- + ss_sched_state substate;
- + NeighborEntry *nbr; //current neighbor during scanning or handover
- + //arrays of rdv timers
- + WimaxRdvTimer *rdv_timers[2*MAX_NBR];
- + int nb_rdv_timers;
- + //handoff information
- + int serving_bsid;
- + int handoff_timeout; //number frame to wait before executing handoff
- +};
- +
- +/**
- + * Class SSscheduler
- + * Scheduler for SSs
- + */
- +class SSscheduler : public WimaxScheduler {
- + friend class Mac802_16;
- + public:
- + /**
- + * Create a scheduler
- + */
- + SSscheduler ();
- +
- + /**
- + * Interface with the TCL script
- + * @param argc The number of parameter
- + * @param argv The list of parameters
- + */
- + int command(int argc, const char*const* argv);
- +
- + /**
- + * Process a packet received by the Mac. Only scheduling related packets should be sent here (BW request, UL_MAP...)
- + * @param p The packet to process
- + */
- + void process (Packet * p);
- +
- + /**
- + * Return the type of STA this scheduler is good for
- + */
- + virtual station_type_t getNodeType ();
- +
- + /**
- + * Initializes the scheduler
- + */
- + virtual void init ();
- +
- + /**
- + * Called when a timer expires
- + * @param The timer ID
- + */
- + virtual void expire (timer_id id);
- +
- + /**
- + * Start a new DL subframe
- + */
- + virtual void start_dlsubframe ();
- +
- + /**
- + * Start a new UL subframe
- + */
- + virtual void start_ulsubframe ();
- +
- + protected:
- +
- + /**
- + * Called when lost synchronization
- + */
- + void lost_synch ();
- +
- + /**
- + * Send a scanning message to the serving BS
- + */
- + void send_scan_request ();
- +
- + private:
- +
- + /**
- + * Process a DL_MAP message
- + * @param frame The dl_map information
- + */
- + void process_dl_map (mac802_16_dl_map_frame *frame);
- +
- + /**
- + * Process a DCD message
- + * @param frame The dcd information
- + */
- + void process_dcd (mac802_16_dcd_frame *frame);
- +
- + /**
- + * Process a uL_MAP message
- + * @param frame The ul_map information
- + */
- + void process_ul_map (mac802_16_ul_map_frame *frame);
- +
- + /**
- + * Process a UCD message
- + * @param frame The ucd information
- + */
- + void process_ucd (mac802_16_ucd_frame *frame);
- +
- + /**
- + * Process a ranging response message
- + * @param frame The ranging response frame
- + */
- + void process_ranging_rsp (mac802_16_rng_rsp_frame *frame);
- +
- + /**
- + * Process a registration response message
- + * @param frame The registration response frame
- + */
- + void process_reg_rsp (mac802_16_reg_rsp_frame *frame);
- +
- + /**
- + * Schedule a ranging
- + */
- + void init_ranging ();
- +
- + /**
- + * Create a request for the given connection
- + * @param con The connection to check
- + */
- + void create_request (Connection *con);
- +
- + /**
- + * Prepare to send a registration message
- + */
- + void send_registration ();
- +
- + /**
- + * Process a scanning response message
- + * @param frame The scanning response frame
- + */
- + void process_scan_rsp (mac802_16_mob_scn_rsp_frame *frame);
- +
- + /**
- + * Process a BSHO-RSP message
- + * @param frame The handover response frame
- + */
- + void process_bsho_rsp (mac802_16_mob_bsho_rsp_frame *frame);
- +
- + /**
- + * Process a BSHO-RSP message
- + * @param frame The handover response frame
- + */
- + void process_nbr_adv (mac802_16_mob_nbr_adv_frame *frame);
- +
- + /**
- + * Start/Continue scanning
- + */
- + void resume_scanning ();
- +
- + /**
- + * Pause scanning
- + */
- + void pause_scanning ();
- +
- + /**
- + * Send a MSHO-REQ message to the BS
- + */
- + void send_msho_req ();
- +
- + /**
- + * Check rdv point when scanning
- + */
- + void check_rdv ();
- +
- + /**
- + * Current number of registration retry
- + */
- + u_int32_t nb_reg_retry_;
- +
- + /**
- + * Current number of scan request retry
- + */
- + u_int32_t nb_scan_req_;
- +
- + /**
- + * Timers
- + */
- + WimaxT1Timer *t1timer_;
- + WimaxT2Timer *t2timer_;
- + WimaxT6Timer *t6timer_;
- + WimaxT12Timer *t12timer_;
- + WimaxT21Timer *t21timer_;
- + WimaxLostDLMAPTimer *lostDLMAPtimer_;
- + WimaxLostULMAPTimer *lostULMAPtimer_;
- + WimaxT44Timer *t44timer_;
- +
- + /**
- + * The scanning information
- + */
- + struct scanning_structure *scan_info_;
- +
- + /**
- + * Indicate if the ranging response is for a fast ranging
- + */
- + bool fast_ranging_;
- +
- +};
- +
- +#endif //SSSCHEDULER_H
- +
- diff -Naur ns-2.29-org/wimax/scheduling/subframe.cc ns-2.29/wimax/scheduling/subframe.cc
- --- ns-2.29-org/wimax/scheduling/subframe.cc 1969-12-31 19:00:00.000000000 -0500
- +++ ns-2.29/wimax/scheduling/subframe.cc 2006-09-22 17:27:47.000000000 -0400
- @@ -0,0 +1,220 @@
- +/* 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 "subframe.h"
- +
- +/*** Functions of super class ***/
- +
- +/**
- + * Constructor
- + * @param map The frame
- + */
- +SubFrame::SubFrame (FrameMap *map)
- +{
- + assert (map);
- + map_ = map;
- + ccc_ = 0;
- + nbProfile_ = 0;
- + LIST_INIT (&profile_list_);
- +}
- +
- +/**
- + * Destructor
- + */
- +SubFrame::~SubFrame ()
- +{
- + removeProfiles();
- +}
- +
- +/**
- + * Add a profile
- + * @param f The frequency of the profile
- + * @param enc The encoding used in the profile
- + * @return a new profile with the given caracteristics
- + */
- +Profile * SubFrame::addProfile (int f, Ofdm_mod_rate enc)
- +{
- + Profile *p = new Profile (this, f, enc);
- + p->insert_entry (&profile_list_);
- + nbProfile_++;
- + incrCCC();
- + return p;
- +}
- +
- +/**
- + * Remove a profile
- + * @param p The profile to remove
- + * @return a new profile with the given caracteristics
- + */
- +void SubFrame::removeProfile (Profile *p)
- +{
- + p->remove_entry ();
- + nbProfile_--;
- + incrCCC();
- +}
- +
- +/**
- + * Remove all profiles
- + */
- +void SubFrame::removeProfiles ()
- +{
- + for (Profile *p = profile_list_.lh_first; p ; p=profile_list_.lh_first) {
- + removeProfile (p);
- + delete (p);
- + }
- +}
- +
- +/**
- + * Return the profile with the given IUC
- + * @return the profile with the given IUC
- + */
- +Profile * SubFrame::getProfile (int iuc)
- +{
- + Profile *p;
- + for (p = profile_list_.lh_first; p ; p=p->next_entry()) {
- + if (p->getIUC()==iuc)
- + return p;
- + }
- + return NULL;
- +}
- +
- +/**
- + * Return the number of profiles for this subframe
- + */
- +int SubFrame::getNbProfile ()
- +{
- + return nbProfile_;
- +}
- +
- +/**
- + * Return the head of the profile list
- + */
- +Profile * SubFrame::getFirstProfile ()
- +{
- + return profile_list_.lh_first;
- +}
- +
- +/**
- + * Return the Configuration Change count
- + */
- +int SubFrame::getCCC ()
- +{
- + return ccc_;
- +}
- +
- +/**
- + * Increment the configuration change count
- + * The CCC is modulo 256.
- + */
- +void SubFrame::incrCCC ()
- +{
- + ccc_ = (ccc_+1)%256;
- +}
- +
- +/*** end of super class ***/
- +
- +/**
- + * Constructor
- + * @param map The frame
- + */
- +DlSubFrame::DlSubFrame (FrameMap *map): SubFrame(map), timer_(this)
- +{
- + phypdu_ = new DlPhyPdu (map , 0); //no preamble by default
- +}
- +
- +/**
- + * Destructor
- + */
- +DlSubFrame::~DlSubFrame ()
- +{
- + delete (phypdu_);
- +}
- +
- +/*** class UlSubFrame ***/
- +
- +/**
- + * Constructor
- + * @param map The frame
- + */
- +UlSubFrame::UlSubFrame (FrameMap *map): SubFrame(map), bw_req_(map ), ranging_(map ), timer_(this)
- +{
- + LIST_INIT (&phypdu_list_);
- + nbPhyPdu_ =0;
- +}
- +
- +/**
- + * Destructor
- + */
- +UlSubFrame::~UlSubFrame ()
- +{
- + for (PhyPdu *p = phypdu_list_.lh_first; p ; p=phypdu_list_.lh_first) {
- + removePhyPdu (p);
- + delete (p);
- + }
- +}
- +
- +/**
- + * Add an uplink phy pdu
- + * @param pos The position of the PhyPdu in the subframe
- + * @param preamble The size of the preamble in units of XX
- + * @return newly created PhyPdu
- + */
- +PhyPdu * UlSubFrame::addPhyPdu (int pos, int preamble)
- +{
- + assert (pos >= 0 && pos <= nbPhyPdu_ );
- + UlPhyPdu *p = new UlPhyPdu (map_, preamble);
- + if (pos==0)
- + p->insert_entry_head (&phypdu_list_);
- + else {
- + PhyPdu *prev = phypdu_list_.lh_first;
- + PhyPdu *p2 = prev->next_entry();
- + int index = 1;
- + while (index < pos) {
- + prev=p2;
- + p2=p2->next_entry();
- + index++;
- + }
- + p->insert_entry (prev);
- + }
- + nbPhyPdu_++;
- + return p;
- +}
- +
- +/**
- + * Remove a Phy PDU
- + * @param pdu The Phy PDU to remove
- + */
- +void UlSubFrame::removePhyPdu (PhyPdu *p)
- +{
- + p->remove_entry();
- + nbPhyPdu_--;
- +}
- +
- +/**
- + * Return the burst located at the given index
- + * @param pos The position of the burst
- + */
- +PhyPdu* UlSubFrame::getPhyPdu(int pos)
- +{
- + assert (pos >= 0 && pos < nbPhyPdu_ );
- + PhyPdu *p = phypdu_list_.lh_first ;
- + for (int i = 0 ; i < pos ; i++) {
- + p=p->next_entry();
- + }
- + return p;
- +}
- diff -Naur ns-2.29-org/wimax/scheduling/subframe.h ns-2.29/wimax/scheduling/subframe.h
- --- ns-2.29-org/wimax/scheduling/subframe.h 1969-12-31 19:00:00.000000000 -0500
- +++ ns-2.29/wimax/scheduling/subframe.h 2006-09-22 17:27:47.000000000 -0400
- @@ -0,0 +1,307 @@
- +/* 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
- + */
- +
- +#ifndef SUBFRAME_H
- +#define SUBFRAME_H
- +
- +#include "profile.h"
- +#include "contentionslot.h"
- +#include "phypdu.h"
- +#include "ulsubframetimer.h"
- +#include "dlsubframetimer.h"
- +
- +class FrameMap;
- +
- +/**
- + * Abstract class for subframe
- + */
- +class SubFrame
- +{
- + public:
- + /**
- + * Constructor
- + * @param map The frame
- + */
- + SubFrame (FrameMap *map);
- +
- + /**
- + * Destructor
- + */
- + ~SubFrame ();
- +
- + /**
- + * Add a downlink profile
- + * @param f The frequency of the profile
- + * @param enc The encoding used in the profile
- + * @return a new profile with the given caracteristics
- + */
- + Profile * addProfile (int f, Ofdm_mod_rate enc);
- +
- + /**
- + * Return the DL profile with the given UID
- + * @return the DL profile with the given UID
- + */
- + Profile * getProfile (int iuc);
- +
- + /**
- + * Remove a downlink profile
- + * @param p The profile to remove
- + */
- + void removeProfile (Profile *p);
- +
- + /**
- + * Remove all downlink profiles
- + */
- + void removeProfiles ();
- +
- + /**
- + * Return the number of profiles for this subframe
- + */
- + int getNbProfile ();
- +
- + /**
- + * Return the head of the profile list
- + */
- + Profile * getFirstProfile ();
- +
- + /**
- + * Return the Configuration Change count
- + */
- + int getCCC ();
- +
- + /**
- + * Increment the configuration change count
- + */
- + void incrCCC ();
- +
- + protected:
- + /**
- + * The frame where it is located
- + */
- + FrameMap *map_;
- +
- + /**
- + * List of burst profiles for downlink
- + */
- + struct profile profile_list_;
- +
- + /**
- + * Number of element in the PhyPDU list
- + */
- + int nbProfile_;
- +
- + /**
- + * Configuration change count
- + */
- + int ccc_;
- +};
- +
- +
- +
- +/**
- + * This class defines a downlink subframe
- + */
- +class DlSubFrame : public SubFrame
- +{
- + friend class DlSubFrameTimer;
- + public:
- + /**
- + * Constructor
- + * @param map The frame
- + */
- + DlSubFrame (FrameMap *map);
- +
- + /**
- + * Destructor
- + */
- + ~DlSubFrame ();
- +
- + /**
- + * Return the DL phypdu
- + * @return the phypdu
- + */
- + inline PhyPdu * getPdu () { return phypdu_; }
- +
- + /**
- + * Set the channel ID
- + * @param id The channel id
- + */
- + inline void setChannelID (int id) { channel_ = id; }
- +
- + /**
- + * Return the channel ID
- + * @return The channel ID
- + */
- + inline int getChannelID () { return channel_; }
- +
- + /**
- + * Return the timer handling the subframe
- + */
- + inline DlSubFrameTimer *getTimer () { return &timer_; }
- +
- + private:
- +
- + /**
- + * List of uplink PhyPDU composing the uplink subframe
- + */
- + PhyPdu * phypdu_;
- +
- + /**
- + * The downlink channel id
- + */
- + int channel_;
- +
- + /**
- + * The timer for handling bursts
- + */
- + DlSubFrameTimer timer_;
- +};
- +
- +/**
- + * This class defines a downlink subframe
- + */
- +
- +class UlSubFrame : public SubFrame
- +{
- + friend class UlSubFrameTimer;
- + public:
- + /**
- + * Constructor
- + * @param map The frame
- + */
- + UlSubFrame (FrameMap *map);
- +
- + /**
- + * Destructor
- + */
- + ~UlSubFrame ();
- +
- + /**
- + * Return the DL phypdu
- + * @return the phypdu
- + */
- + inline PhyPdu * getFirstPdu () { return phypdu_list_.lh_first; }
- +
- + /**
- + * Add an uplink phy pdu
- + * @param pos The position of the PhyPdu in the subframe
- + * @param preamble The size of the preamble in units of XX
- + * @return newly created PhyPdu
- + */
- + PhyPdu * addPhyPdu (int pos, int preamble);
- +
- + /**
- + * Remove a Phy PDU
- + * @param pdu The Phy PDU to remove
- + */
- + void removePhyPdu (PhyPdu *p);
- +
- + /**
- + * Return the number of PhyPdu
- + */
- + inline int getNbPdu () { return nbPhyPdu_; }
- +
- + /**
- + * Return the burst located at the given index
- + * @param pos The position of the burst
- + */
- + PhyPdu* getPhyPdu(int pos);
- +
- + /*
- + * Return the contention slot for BW requests
- + * @return the pointer to the contention slot for BW requests
- + */
- + inline BwContentionSlot* getBw_req( ) { return &bw_req_; }
- +
- + /*
- + * Return the contention slot for BW requests
- + * @return the pointer to the contention slot for BW requests
- + */
- + inline RngContentionSlot* getRanging( ) { return &ranging_; }
- +
- + /**
- + * Set the start time in units of PS
- + * @param time The subframe start time
- + */
- + inline void setStarttime (int time) { starttime_ = time;}
- +
- + /**
- + * Get the start time in units of PS
- + * @return The subframe start time
- + */
- + inline int getStarttime () { return starttime_;}
- +
- + /**
- + * Set the channel ID
- + * @param id The channel id
- + */
- + inline void setChannelID (int id) { channel_ = id; }
- +
- + /**
- + * Return the channel ID
- + * @return The channel ID
- + */
- + inline int getChannelID () { return channel_; }
- +
- + /**
- + * Return the timer handling the subframe
- + */
- + inline UlSubFrameTimer *getTimer () { return &timer_; }
- +
- + protected:
- +
- + /**
- + * Information about the bandwidth request contention
- + */
- + BwContentionSlot bw_req_;
- +
- + /**
- + * Information about the ranging contention
- + */
- + RngContentionSlot ranging_;
- +
- + private:
- +
- + /**
- + * List of uplink PhyPDU composing the uplink subframe
- + */
- + struct phyPdu phypdu_list_;
- +
- + /**
- + * Number of phypdu
- + */
- + int nbPhyPdu_;
- +
- + /**
- + * Start time of the subframe in unit of PS
- + */
- + int starttime_;
- +
- + /**
- + * The downlink channel id
- + */
- + int channel_;
- +
- + /**
- + * The timer for handling bursts
- + */
- + UlSubFrameTimer timer_;
- +
- +};
- +
- +#endif
- diff -Naur ns-2.29-org/wimax/scheduling/ulburst.cc ns-2.29/wimax/scheduling/ulburst.cc
- --- ns-2.29-org/wimax/scheduling/ulburst.cc 1969-12-31 19:00:00.000000000 -0500
- +++ ns-2.29/wimax/scheduling/ulburst.cc 2006-09-22 17:27:47.000000000 -0400
- @@ -0,0 +1,65 @@
- +/* 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 "ulburst.h"
- +
- +/**
- + * Creates a downlink burst
- + * @param phypdu The PhyPdu where it is located
- + */
- +UlBurst::UlBurst (PhyPdu *phypdu) : Burst (phypdu)
- +{
- + midamble_ = PREAMBLE_ONLY;
- +}
- +
- +/**
- + * Set the burst to Fast Ranging
- + * @param macAddr address of MN
- + * @param uiuc Encoding to use
- + */
- +void UlBurst::setFastRangingParam (int macAddr, int uiuc)
- +{
- + assert (getIUC() == UIUC_EXT_UIUC);
- +
- + extuiuc_ = UIUC_FAST_RANGING;
- + uiuc2_ = uiuc;
- + macAddr_ = macAddr;
- +}
- +
- +
- +/**
- + * Return the mac address for fast ranging
- + * @return The mac address for fast ranging
- + */
- +int UlBurst::getFastRangingMacAddr ()
- +{
- + assert (extuiuc_ == UIUC_FAST_RANGING);
- + return macAddr_;
- +}
- +
- +/**
- + * Return the UIUC encoding to use
- + * @return The UIUC encoding to use
- + */
- +int UlBurst::getFastRangingUIUC (){
- + assert (extuiuc_ == UIUC_FAST_RANGING);
- + return uiuc2_;
- +}
- +
- +
- +
- diff -Naur ns-2.29-org/wimax/scheduling/ulburst.h ns-2.29/wimax/scheduling/ulburst.h
- --- ns-2.29-org/wimax/scheduling/ulburst.h 1969-12-31 19:00:00.000000000 -0500
- +++ ns-2.29/wimax/scheduling/ulburst.h 2006-09-22 17:27:47.000000000 -0400
- @@ -0,0 +1,127 @@
- +/* 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
- + */
- +
- +#ifndef ULBURST_H
- +#define ULBURST_H
- +
- +#include "burst.h"
- +
- +/* Defines the OFDM UIUC values */
- +enum uiuc_t {
- + //0 is reserved
- + UIUC_INITIAL_RANGING=1,
- + UIUC_REQ_REGION_FULL,
- + UIUC_REQ_REGION_FOCUSED,
- + UIUC_FOCUSED_CONTENTION_IE,
- + //5-12 reserved for burst profiles
- + UIUC_PROFILE_1,
- + UIUC_PROFILE_2,
- + UIUC_PROFILE_3,
- + UIUC_PROFILE_4,
- + UIUC_PROFILE_5,
- + UIUC_PROFILE_6,
- + UIUC_PROFILE_7,
- + UIUC_PROFILE_8,
- + UIUC_SUBCH_NET_ENTRY=13,
- + UIUC_END_OF_MAP,
- + UIUC_EXT_UIUC
- +};
- +
- +/* Defines Midamble repetition interval */
- +enum midamble_t {
- + PREAMBLE_ONLY,
- + MIDAMBLE_8_SYMBOLS, //every 8 data symbols
- + MIDAMBLE_16_SYMBOLS, //every 16 data symbols
- + MIDAMBLE_32_SYMBOLS //every 32 data symbols
- +};
- +
- +/* List of Extended UIUC */
- +enum extuiuc_t {
- + UIUC_FAST_POWER_CTRL=0,
- + UIUC_PHY_MODIFIER,
- + UIUC_AAS,
- + UIUC_FAST_RANGING,
- + UIUC_FAST_TRACKING
- +};
- +
- +
- +/**
- + * Uplink Burst description
- + */
- +class UlBurst : public Burst
- +{
- +public:
- + /**
- + * Default contructor
- + * @param phypdu The PhyPdu where it is located
- + */
- + UlBurst (PhyPdu *phypdu);
- +
- + /**
- + * Return the midamble used in the burst
- + */
- + inline int getMidamble( ) { return midamble_; }
- + /**
- + * Set the midamble used in the burst
- + */
- + inline void setMidamble( int midamble ) { midamble_ = midamble; }
- +
- + /**
- + * Return extended uiuc
- + */
- + inline int getExtendedUIUC () { return extuiuc_; }
- +
- + /**
- + * Set the burst to Fast Ranging
- + * @param macAddr address of MN
- + * @param uiuc Encoding to use
- + */
- + void setFastRangingParam (int macAddr, int uiuc);
- +
- + /**
- + * Return the mac address for fast ranging
- + * @return The mac address for fast ranging
- + */
- + int getFastRangingMacAddr ();
- +
- + /**
- + * Return the UIUC encoding to use
- + * @return The UIUC encoding to use
- + */
- + int getFastRangingUIUC ();
- +
- +
- + private:
- + /**
- + * The type of midamble included in the burst
- + */
- + int midamble_;
- +
- + /**
- + * The extended UIUC
- + */
- + int extuiuc_;
- +
- + /**
- + * For Fast Ranging
- + */
- + int uiuc2_;
- + int macAddr_;
- +};
- +
- +#endif
- diff -Naur ns-2.29-org/wimax/scheduling/ulsubframetimer.cc ns-2.29/wimax/scheduling/ulsubframetimer.cc
- --- ns-2.29-org/wimax/scheduling/ulsubframetimer.cc 1969-12-31 19:00:00.000000000 -0500
- +++ ns-2.29/wimax/scheduling/ulsubframetimer.cc 2006-09-22 17:27:47.000000000 -0400
- @@ -0,0 +1,161 @@
- +/* 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 "ulsubframetimer.h"
- +#include "framemap.h"
- +#include "subframe.h"
- +#include "wimaxscheduler.h"
- +#include "contentionslot.h"
- +
- +/**
- + * Creates a timer to handle the subframe transmission
- + * @param subframe The UlSubframe
- + */
- +UlSubFrameTimer::UlSubFrameTimer (UlSubFrame *subframe): pdu_(0), newphy_(true), mac_(0)
- +{
- + assert (subframe);
- + subframe_ = subframe;
- +}
- +
- +/**
- + * Reset the timer
- + */
- +void UlSubFrameTimer::reset ()
- +{
- + pdu_= NULL;
- + newphy_ = true;
- + if (status()==TIMER_PENDING)
- + cancel();
- +}
- +
- +/**
- + * When it expires, the timer will handle the next packet to send
- + * @param e not used
- + */
- +void UlSubFrameTimer::expire( Event* e )
- +{
- + if (!mac_) {
- + mac_= subframe_->map_->getMac();
- + }
- +
- + //mac_->debug ("At %f in Mac %d UlsubFrameTimer expiresn", NOW, mac_->addr());
- + int iuc;
- + if (newphy_) {
- + if (pdu_==NULL){
- + //printf ("ttake first pdun");
- + //get the first pdu
- + pdu_ = subframe_->getFirstPdu();
- + } else {
- + //printf ("tcontinue pdun");
- + iuc = pdu_->getBurst(0)->getIUC();
- + //check if this is a contention slot
- + if (iuc == UIUC_INITIAL_RANGING) {
- + //stop ranging timer
- + //printf ("tpause rangingn");
- + subframe_->ranging_.pauseTimers ();
- + } else if (iuc == UIUC_REQ_REGION_FULL) {
- + //stop bw request timers
- + //printf ("tpause bw requestsn");
- + subframe_->bw_req_.pauseTimers();
- + }
- + pdu_ = pdu_->next_entry();
- + }
- +
- + if (pdu_->getBurst(0)->getIUC()==UIUC_END_OF_MAP){
- + pdu_=NULL; //reset for next frame
- + //mac_->debug ("tend of mapn");
- + if (mac_->getScheduler()->getNodeType()==STA_BS) {
- + mac_->getPhy()->setMode (OFDM_SEND);
- + } else {
- + mac_->getPhy()->setMode (OFDM_RECV);
- + }
- + return; //end of subframe
- + }
- +
- + //change the modulation
- + UlBurst *burst = (UlBurst*)pdu_->getBurst(0);
- + iuc = burst->getIUC();
- + //printf ("Searching for IUC=%dn", iuc);
- + if (iuc == UIUC_EXT_UIUC && burst->getExtendedUIUC()== UIUC_FAST_RANGING) {
- + iuc = burst->getFastRangingUIUC ();
- + //printf ("Searching for IUC=%dn", iuc);
- + }
- + Ofdm_mod_rate rate = subframe_->getProfile (iuc)->getEncoding();
- + mac_->getPhy()->setModulation (rate);
- + //check if this is a contention slot
- + if (iuc == UIUC_INITIAL_RANGING) {
- + //resume ranging timer
- + //printf ("tresume rangingn");
- + subframe_->ranging_.resumeTimers();
- + } else if (iuc == UIUC_REQ_REGION_FULL) {
- + //resume bw request timers
- + //printf ("tresume bw requestsn");
- + subframe_->bw_req_.resumeTimers();
- + }
- + }
- + //check if packet to send
- + Packet *p = pdu_->getBurst(0)->dequeue();
- +
- + if (p) {
- + newphy_= false;
- + double txtime = HDR_CMN(p)->txtime();
- + //printf ("tPacket to sendn");
- + //schedule for next packet
- + mac_->transmit (p);
- + if (pdu_->getBurst(0)->getQueueLength()!=0) {
- + //mac_->debug ("treschedule in %f (%f)n", txtime, NOW+txtime);
- + resched (txtime); //wait transmition time
- + return;
- + }
- + }
- +
- + newphy_= true;
- + double stime=0.0;
- + assert (pdu_->next_entry());
- +
- + stime = subframe_->map_->getStarttime();
- + //mac_->debug("tstart frame=%fn", stime);
- + stime += subframe_->getStarttime()*mac_->getPhy()->getPS();
- + //mac_->debug ("tulstart = %fn", stime);
- + stime += pdu_->next_entry()->getBurst(0)->getStarttime()*mac_->getPhy()->getSymbolTime();
- + //mac_->debug ("tnext pdu start=%dn", pdu_->next_entry()->getBurst(0)->getStarttime());
- + //mac_->debug ("t%f Next burst %d at %fn", NOW, pdu_->next_entry()->getBurst(0)->getIUC(), stime);
- + resched (stime-NOW);
- +
- + /*
- + if (!p) {
- + //no packet to send...schedule for next phypdu
- + newphy_= true;
- + double stime=0.0;
- + assert (pdu_->next_entry());
- +
- + stime = subframe_->map_->getStarttime();
- + stime += subframe_->getStarttime()*mac_->getPhy()->getPS();
- + stime += pdu_->next_entry()->getBurst(0)->getStarttime()*mac_->getPhy()->getSymbolTime();
- + printf ("t%f Next burst %d at %fn", NOW, pdu_->next_entry()->getBurst(0)->getIUC(), stime);
- + resched (stime-NOW);
- +
- + } else {
- + newphy_= false;
- + double txtime = HDR_CMN(p)->txtime();
- + //printf ("tPacket to sendn");
- + //schedule for next packet
- + mac_->transmit (p);
- + resched (txtime); //wait transmition time
- + }*/
- +}
- diff -Naur ns-2.29-org/wimax/scheduling/ulsubframetimer.h ns-2.29/wimax/scheduling/ulsubframetimer.h
- --- ns-2.29-org/wimax/scheduling/ulsubframetimer.h 1969-12-31 19:00:00.000000000 -0500
- +++ ns-2.29/wimax/scheduling/ulsubframetimer.h 2006-09-22 17:27:47.000000000 -0400
- @@ -0,0 +1,73 @@
- +/* 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
- + */
- +
- +#ifndef ULSUBFRAME_H
- +#define ULSUBFRAME_H
- +
- +#include "mac802_16.h"
- +#include "phypdu.h"
- +
- +class UlSubFrame;
- +/**
- + * This timer is used to handle the transmission of
- + * a UlSubframe.
- + */
- +class UlSubFrameTimer: public TimerHandler
- +{
- + public:
- + /**
- + * Creates a timer to handle the subframe transmission
- + * @param subframe The UlSubframe
- + */
- + UlSubFrameTimer (UlSubFrame *subframe);
- +
- + /**
- + * When it expires, the timer will handle the next packet to send
- + * @param e not used
- + */
- + void expire( Event* e );
- +
- + /**
- + * Reset the timer
- + */
- + void reset ();
- +
- + private:
- + /**
- + * The subframe
- + */
- + UlSubFrame *subframe_;
- +
- + /**
- + * The current PhyPdu being handled
- + */
- + PhyPdu *pdu_;
- +
- + /**
- + * Tag to know if we are changing PhyPdu
- + */
- + bool newphy_;
- +
- + /**
- + * Store local variables for faster access
- + */
- + Mac802_16 *mac_;
- +
- +};
- +
- +#endif
- diff -Naur ns-2.29-org/wimax/scheduling/wimaxctrlagent.cc ns-2.29/wimax/scheduling/wimaxctrlagent.cc
- --- ns-2.29-org/wimax/scheduling/wimaxctrlagent.cc 1969-12-31 19:00:00.000000000 -0500
- +++ ns-2.29/wimax/scheduling/wimaxctrlagent.cc 2006-09-22 17:27:47.000000000 -0400
- @@ -0,0 +1,447 @@
- +/* This class contains the control agent located in IEEE 802.16 BS responsible
- + * for synchronization between BSs.
- + * 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 "wimaxctrlagent.h"
- +#include "mac802_16.h"
- +#include "bsscheduler.h"
- +
- +#define MYNUM Address::instance().print_nodeaddr(addr())
- +
- +
- +int hdr_wimaxbs::offset_;
- +/**
- + * Tcl hook for Packet definitions
- + */
- +static class WimaxBSHeaderClass : public PacketHeaderClass {
- +public:
- + WimaxBSHeaderClass() : PacketHeaderClass("PacketHeader/WIMAXBS",
- + sizeof(hdr_wimaxbs)) {
- + bind_offset(&hdr_wimaxbs::offset_);
- + }
- +} class_wimaxbshdr;
- +
- +/**
- + * Tcl hook for agent
- + */
- +static class WimaxCtrlAgentClass : public TclClass {
- +public:
- + WimaxCtrlAgentClass() : TclClass("Agent/WimaxCtrl") {}
- + TclObject* create(int, const char*const*) {
- + return (new WimaxCtrlAgent());
- + }
- +} class_wimaxctrlagent;
- +
- +/*
- + * Handler for timer expiration
- + */
- +void UpdateTimer::expire (Event*)
- +{
- + a_->sendUpdate();
- +}
- +
- +/*
- + * Handler for response timer expiration
- + */
- +void ScanRspTimer::expire (Event*)
- +{
- + a_->agent()->send_scan_response(a_->cid());
- +}
- +
- +
- +/*
- + * Creates a Wimax controler agent
- + * Initializes the agent and bind variable to be accessible in TCL
- + */
- +WimaxCtrlAgent::WimaxCtrlAgent() : Agent(PT_WIMAXBS), mac_(0), updatetimer_ (this)
- +{
- + nbmapentry_=0;
- + LIST_INIT (&scan_req_head_);
- +
- + //bind attributes
- + bind ("adv_interval_", &adv_interval_);
- + bind ("default_association_level_", &defaultlevel_);
- + bind ("synch_frame_delay_", &synch_frame_delay_);
- +
- + //schedule first update
- + updatetimer_.sched (Random::uniform(0, UPDATE_JITTER));
- +}
- +
- +/*
- + * Interface with TCL interpreter
- + * @param argc The number of elements in argv
- + * @param argv The list of arguments
- + * @return TCL_OK if everything went well else TCL_ERROR
- + */
- +int WimaxCtrlAgent::command(int argc, const char*const* argv)
- +{
- + Tcl& tcl= Tcl::instance();
- +
- + if (argc == 3) {
- + // set the Minimum interval between two RAs
- + if (strcmp(argv[1], "set-mac") == 0) {
- + mac_ = (Mac802_16*) TclObject::lookup(argv[2]);
- + ((BSScheduler*)mac_->getScheduler())->setCtrlAgent (this);
- + return TCL_OK;
- + }
- + else if (strcmp(argv[1], "add-neighbor") == 0) {
- + //the parameter is the mac, and we also extract the node
- + Mac802_16 *tmp = (Mac802_16 *) TclObject::lookup(argv[2]);
- + if (nbmapentry_ == MAX_MAP_ENTRY) {
- + fprintf (stderr, "Table size exceeding. Increase MAX_MAP_ENTRYn");
- + }
- + tcl.evalf ("%s get-node", argv[2]);
- + Node *tmpNode = (Node *) TclObject::lookup(tcl.result());
- + //add entry
- + maptable_[nbmapentry_][0] = tmp->addr();
- + maptable_[nbmapentry_][1] = tmpNode->address();
- + debug ("Adding neighbor %s (mac %d) in %sn", Address::instance().print_nodeaddr(tmpNode->address()),
- + tmp->addr(), MYNUM);
- + nbmapentry_++;
- + return TCL_OK;
- + }
- + }
- +
- + return (Agent::command(argc, argv));
- +}
- +
- +/*
- + * Send an update (DCD/UCD) to all neighboring BSs
- + */
- +void WimaxCtrlAgent::sendUpdate ()
- +{
- + //get the DCD/UCD message to include in the update
- + Packet *dcd = mac_->getScheduler()->map_->getDCD();
- + Packet *ucd = mac_->getScheduler()->map_->getUCD();
- +
- + //allocate data to store information
- + mac802_16_dcd_frame *dcdframe = (mac802_16_dcd_frame*) dcd->accessdata();
- + mac802_16_ucd_frame *ucdframe = (mac802_16_ucd_frame*) ucd->accessdata();
- +
- + Packet *p = allocpkt();
- + hdr_ip *iph = HDR_IP(p);
- + hdr_wimaxbs *rh = HDR_WIMAXBS(p);
- + hdr_cmn *hdrc = HDR_CMN(p);
- +
- + rh->getType() = WIMAX_BS_ADV;
- + hdrc->size() = HDR_CMN(dcd)->size()+HDR_CMN(ucd)->size(); //TBD: remove double header
- + //set content
- + rh->macAddr() = mac_->addr();
- + p->allocdata (sizeof (mac802_16_dcd_frame)+sizeof (mac802_16_ucd_frame));
- + unsigned char *data = p->accessdata();
- + memcpy (data, dcdframe, sizeof (mac802_16_dcd_frame));
- + memcpy (data+sizeof (mac802_16_dcd_frame), ucdframe, sizeof (mac802_16_ucd_frame));
- +
- + Packet *tmpPkt;
- + for (int i = 0; i < nbmapentry_ ; i++) {
- + tmpPkt = p->copy();
- + iph = HDR_IP(tmpPkt);
- + //set packet destination
- + iph->daddr() = maptable_[i][1];
- + iph->dport() = port();
- + debug ("At %f in node %s, send update to node %sn", NOW, MYNUM,Address::instance().print_nodeaddr(iph->daddr()));
- + debug ("frame number=%dn", dcdframe->frame_number);
- + send(tmpPkt, 0);
- + }
- +
- + //reschedule timer
- + updatetimer_.resched (adv_interval_);
- +}
- +
- +/*
- + * Process received packet
- + * @param p The packet received
- + * @param h The handler that sent the packet
- + */
- +void WimaxCtrlAgent::recv(Packet* p, Handler *h)
- +{
- + assert (p);
- +
- + hdr_wimaxbs *rh = HDR_WIMAXBS(p);
- + switch (rh->getType()) {
- + case WIMAX_BS_ADV:
- + processUpdate (p);
- + break;
- + case WIMAX_BS_SYNCH_REQ:
- + process_synch_request (p);
- + break;
- + case WIMAX_BS_SYNCH_RSP:
- + process_synch_response (p);
- + break;
- + default:
- + fprintf (stderr, "Unknown message type in WimaxCtrlAgentn");
- + }
- + Packet::free (p);
- +}
- +
- +/*
- + * Process received packet
- + * @param p The update received
- + * @param h The handler that sent the packet
- + */
- +void WimaxCtrlAgent::processUpdate(Packet* p)
- +{
- + debug ("At %f in node %s, WimaxCtrlAgent received update message from %sn", NOW, MYNUM,
- + Address::instance().print_nodeaddr(HDR_IP(p)->saddr()));
- +
- + hdr_wimaxbs *rh = HDR_WIMAXBS(p);
- + NeighborEntry *entry = mac_->getScheduler()->nbr_db_->getNeighbor(rh->macAddr());
- +
- + //check if we know about this neighbor
- + bool found = false;
- + for (int i = 0; i < nbmapentry_ ; i++) {
- + if (maptable_[i][1]==HDR_IP(p)->saddr())
- + found = true;
- + }
- + assert (found);
- +
- + if (entry==NULL) {
- + debug ("tNew neighbor detected...add entry for mac %dn", rh->macAddr());
- + entry = new NeighborEntry (rh->macAddr());
- + mac_->getScheduler()->nbr_db_->addNeighbor(entry);
- + }
- + //update entry
- + unsigned char *data = p->accessdata();
- + mac802_16_dcd_frame *dcdframe = (mac802_16_dcd_frame *)malloc (sizeof (mac802_16_dcd_frame));
- + mac802_16_ucd_frame *ucdframe = (mac802_16_ucd_frame *)malloc (sizeof (mac802_16_ucd_frame));
- +
- + memcpy (dcdframe, data, sizeof (mac802_16_dcd_frame));
- + memcpy (ucdframe, data+sizeof (mac802_16_dcd_frame), sizeof (mac802_16_ucd_frame));
- + debug ("tframe number=%d ccc=%dn", dcdframe->frame_number,ucdframe->config_change_count);
- + mac802_16_dcd_frame *dcdtmp = entry->getDCD();
- + if (dcdtmp)
- + free(dcdtmp);
- + mac802_16_ucd_frame *ucdtmp = entry->getUCD();
- + if (ucdtmp)
- + free(ucdtmp);
- + entry->setDCD (dcdframe);
- + entry->setUCD (ucdframe);
- + //free (p);
- +}
- +
- +/**
- + * Process scanning request
- + * @param p The request
- + */
- +void WimaxCtrlAgent::process_scan_request (Packet *req)
- +{
- + hdr_mac802_16 *wimaxHdr_req = HDR_MAC802_16(req);
- + gen_mac_header_t header_req = wimaxHdr_req->header;
- + mac802_16_mob_scn_req_frame *req_frame;
- + req_frame = (mac802_16_mob_scn_req_frame*) req->accessdata();
- +
- + mac_->debug ("At %f in Mac %d received scanning request from %dn", NOW, mac_->addr(), header_req.cid);
- +
- + //for first implementation we disregard the information
- + //sent by MN. Just use default association mechanisms
- +
- + //should check if there is already pending request: TBD
- + Scan_req *entry = new Scan_req (this, synch_frame_delay_*mac_->getFrameDuration(), header_req.cid, req_frame);
- + entry->insert_entry (&scan_req_head_);
- + entry->start_frame()=mac_->getFrameNumber();
- +
- + switch (defaultlevel_){
- + case 0: //Scan without association
- + entry->response()->scan_duration = req_frame->scan_duration;
- + entry->response()->start_frame = 2;
- + entry->response()->report_mode = 0; //no report for now
- + entry->response()->interleaving_interval = req_frame->interleaving_interval;
- + entry->response()->scan_iteration = req_frame->scan_iteration;
- + entry->response()->n_recommended_bs_index = 0;
- + entry->response()->n_recommended_bs_full = nbmapentry_;
- + for (int i = 0; i < nbmapentry_ ; i++) {
- + entry->response()->rec_bs_full[i].recommended_bs_id = maptable_[i][0];
- + entry->response()->rec_bs_full[i].scanning_type = SCAN_WITHOUT_ASSOC;
- + }
- + //send response
- + ((BSScheduler*)mac_->getScheduler())->send_scan_response (entry->response(), header_req.cid);
- + //clean data
- + entry->remove_entry();
- + delete entry;
- + break;
- +
- + case 1: //Association without coordination
- + entry->response()->scan_duration = req_frame->scan_duration;
- + entry->response()->start_frame = 2;
- + entry->response()->report_mode = 0; //no report for now
- + entry->response()->interleaving_interval = req_frame->interleaving_interval;
- + entry->response()->scan_iteration = req_frame->scan_iteration;
- + entry->response()->n_recommended_bs_index = 0;
- + entry->response()->n_recommended_bs_full = nbmapentry_;
- + for (int i = 0; i < nbmapentry_ ; i++) {
- + entry->response()->rec_bs_full[i].recommended_bs_id = maptable_[i][0];
- + entry->response()->rec_bs_full[i].scanning_type = SCAN_ASSOC_LVL0;
- + }
- + //send response
- + ((BSScheduler*)mac_->getScheduler())->send_scan_response (entry->response(), header_req.cid);
- + //clean data
- + entry->remove_entry();
- + delete entry;
- + break;
- +
- + case 2: //Association with coordination
- + //init data
- + entry->response()->n_recommended_bs_index = 0;
- + entry->response()->n_recommended_bs_full = 0;
- + entry->pending_rsp () = 0;
- +
- + //send request to neighbors
- + for (int i = 0; i < nbmapentry_ ; i++) {
- + Packet *p = allocpkt();
- + hdr_ip *iph = HDR_IP(p);
- + hdr_wimaxbs *rh = HDR_WIMAXBS(p);
- + hdr_cmn *hdrc = HDR_CMN(p);
- +
- + rh->getType() = WIMAX_BS_SYNCH_REQ;
- + hdrc->size() = 30; //We need to define proper size
- + //set content
- + iph = HDR_IP(p);
- + iph->daddr() = maptable_[i][1];
- + iph->dport() = port();
- +
- + rh->macAddr() = mac_->getCManager()->get_connection(header_req.cid, true)->getPeerNode()->getPeerNode();
- + rh->cid = header_req.cid;
- + rh->scanning_type = (wimax_scanning_type) defaultlevel_;
- + //we suggest a rendez-vous time at the beginning of each
- + //scan iteration
- + rh->current_frame = mac_->getFrameNumber();
- + //if we want to start scanning 2 frames after, then add one (i.e 3) because
- + //the message will be sent on the next frame
- + printf ("scan_duration=%d, scan_interval=%dn", req_frame->scan_duration,
- + req_frame->interleaving_interval);
- + rh->rdvt = (i+1)*(req_frame->scan_duration+req_frame->interleaving_interval)+synch_frame_delay_+START_FRAME_OFFSET+1;
- + rh->rendezvous_time = NOW+rh->rdvt*mac_->getFrameDuration();
- + printf ("Request: current frame=%d, rdv frame=%d, rdv time=%fn",
- + rh->current_frame, rh->rdvt, rh->rendezvous_time);
- +
- + entry->pending_rsp ()++;
- + send (p,0);
- +
- + entry->response()->n_recommended_bs_full = i + 1;
- + entry->response()->rec_bs_full[i].recommended_bs_id = maptable_[i][0];
- + entry->response()->rec_bs_full[i].scanning_type = rh->scanning_type;
- + entry->response()->rec_bs_full[i].rdv_time = rh->rdvt-synch_frame_delay_;
- + }
- +
- + //continue initializing response
- + entry->response()->scan_duration = req_frame->scan_duration;
- + entry->response()->start_frame = START_FRAME_OFFSET;
- + entry->response()->report_mode = 0; //no report for now
- + entry->response()->interleaving_interval = entry->request()->interleaving_interval;
- + entry->response()->scan_iteration = entry->request()->scan_iteration;
- + entry->response()->n_recommended_bs_index = 0;
- +
- + //printf ("Response: current frame=%d (now=%f), start in %d frame (t=%f)n",
- + // mac_->getFrameNumber (), NOW, entry->response()->start_frame, NOW+(entry->response()->start_frame*mac_->getFrameDuration()));
- + //send response
- + //((BSScheduler*)mac_->getScheduler())->send_scan_response (entry->response(), entry->cid());
- +
- + break;
- + case 3: //Network Assisted Association reporting
- +
- + break;
- + default:
- + break;
- + }
- +}
- +
- +/**
- + * Process synchronization request
- + * @param req The request
- + */
- +void WimaxCtrlAgent::process_synch_request (Packet *req)
- +{
- + debug ("At %f in node %s, WimaxCtrlAgent received synch request from %sn", NOW, MYNUM,
- + Address::instance().print_nodeaddr(HDR_IP(req)->saddr()));
- +
- + //schedule rendez-vous time
- + //schedule sending of Fast-ranging-IE
- + ((BSScheduler*)mac_->getScheduler())->addNewFastRanging (HDR_WIMAXBS(req)->rendezvous_time, HDR_WIMAXBS(req)->macAddr());
- +
- +
- + //send response
- + Packet *p = allocpkt();
- + hdr_ip *iph = HDR_IP(p);
- + hdr_wimaxbs *rh = HDR_WIMAXBS(p);
- + hdr_cmn *hdrc = HDR_CMN(p);
- +
- + rh->getType() = WIMAX_BS_SYNCH_RSP;
- + hdrc->size() = 30; //We need to define proper size
- + //set content
- + iph = HDR_IP(p);
- + iph->daddr() = HDR_IP(req)->saddr();
- + iph->dport() = port();
- +
- + //we accept what the serving BS sent
- + rh->cid = HDR_WIMAXBS(req)->cid;
- + rh->scanning_type = HDR_WIMAXBS(req)->scanning_type;
- + rh->current_frame = HDR_WIMAXBS(req)->current_frame;
- + rh->rdvt = HDR_WIMAXBS(req)->rdvt;
- + rh->rendezvous_time = HDR_WIMAXBS(req)->rendezvous_time;
- +
- + //send (p,0);
- +}
- +
- +/**
- + * Process synchronization response
- + * @param p The response
- + */
- +void WimaxCtrlAgent::process_synch_response (Packet *p)
- +{
- + debug ("At %f in node %s, WimaxCtrlAgent received synch response from %sn", NOW, MYNUM,
- + Address::instance().print_nodeaddr(HDR_IP(p)->saddr()));
- +
- + hdr_wimaxbs *rh = HDR_WIMAXBS(p);
- + int i;
- +
- + //update information
- + Scan_req *entry;
- + for (entry = scan_req_head_.lh_first ; entry && (entry->cid() != rh->cid); entry=entry->next_entry());
- +
- + assert (entry);
- +
- + i = entry->response()->n_recommended_bs_full;
- + entry->response()->n_recommended_bs_full = i + 1;
- + entry->response()->rec_bs_full[i].recommended_bs_id = maptable_[i][0];
- + entry->response()->rec_bs_full[i].scanning_type = rh->scanning_type;
- + entry->response()->rec_bs_full[i].rdv_time = rh->rdvt;
- +}
- +
- +/**
- + * Send a scan response to the MN that has the given CID
- + * @param cid The CID of the MN
- + */
- +void WimaxCtrlAgent::send_scan_response (int cid)
- +{
- + Scan_req *entry;
- + for (entry = scan_req_head_.lh_first ; entry && (entry->cid() != cid); entry=entry->next_entry());
- +
- + assert (entry);
- +
- + entry->response()->scan_duration = entry->request()->scan_duration;
- + printf ("Response: current frame=%d, start frame=%d diff=%dn",
- + mac_->getFrameNumber(), entry->start_frame(), 100-(mac_->getFrameNumber()-entry->start_frame()));
- + printf ("Response: current frame=%d (now=%f), start in %d frame (t=%f)n",
- + mac_->getFrameNumber (), NOW, entry->response()->start_frame, NOW+(entry->response()->start_frame*mac_->getFrameDuration()));
- + //send response
- + ((BSScheduler*)mac_->getScheduler())->send_scan_response (entry->response(), entry->cid());
- + //clean data
- + entry->remove_entry();
- + delete entry;
- +}
- diff -Naur ns-2.29-org/wimax/scheduling/wimaxctrlagent.h ns-2.29/wimax/scheduling/wimaxctrlagent.h
- --- ns-2.29-org/wimax/scheduling/wimaxctrlagent.h 1969-12-31 19:00:00.000000000 -0500
- +++ ns-2.29/wimax/scheduling/wimaxctrlagent.h 2006-09-22 17:27:47.000000000 -0400
- @@ -0,0 +1,261 @@
- +/* This class contains the control agent located in IEEE 802.16 BS responsible
- + * for synchronization between BSs.
- + * 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
- + */
- +
- +#ifndef WIMAXCTRLAGENT_H
- +#define WIMAXCTRLAGENT_H
- +
- +#include "agent.h"
- +#include "tclcl.h"
- +#include "packet.h"
- +#include "address.h"
- +#include "ip.h"
- +#include "node.h"
- +#include "random.h"
- +#include "mac802_16pkt.h"
- +
- +#define MAX_MAP_ENTRY 10
- +#define MAX_MN_REQ 10 //maximum number of concurrent MN requests
- +#define UPDATE_JITTER 0.5 //jitter at start up to avoid synchronization
- +#define START_FRAME_OFFSET 2 //in the response we set teh start_frame to this value
- +
- +/*
- + * Packet structure for
- + */
- +#define HDR_WIMAXBS(p) ((struct hdr_wimaxbs*)(p)->access(hdr_wimaxbs::offset_))
- +
- +/** Types of message */
- +enum wimaxbs_type {
- + WIMAX_BS_ADV,
- + WIMAX_BS_SYNCH_REQ,
- + WIMAX_BS_SYNCH_RSP,
- +};
- +
- +/** Structure of packet exchanged between BSs */
- +struct hdr_wimaxbs {
- + wimaxbs_type subtype_; //type of message
- +
- + uint32_t macaddr_; //address of the MAC of interest in this message
- +
- + //data for BS association request
- + int cid; //to know for which connection the message is
- + wimax_scanning_type scanning_type;
- + int current_frame;
- + int rdvt; //rendez-vous time in units of frame
- + double rendezvous_time; //rendez-vous time in seconds
- +
- + static int offset_;
- + inline static int& offset() { return offset_; }
- + inline static hdr_wimaxbs* access(Packet* p) {
- + return (hdr_wimaxbs*) p->access(offset_);
- + }
- + inline wimaxbs_type& getType() {return subtype_;}
- + inline uint32_t& macAddr() { return macaddr_; }
- +};
- +
- +class WimaxCtrlAgent;
- +
- +class Scan_req;
- +LIST_HEAD (scan_req, Scan_req);
- +//structure to handle scan requests
- +
- +/**
- + * Timer to send an update to neighboring BSs
- + */
- +class ScanRspTimer : public TimerHandler {
- + public:
- + ScanRspTimer(Scan_req *a) : TimerHandler()
- + { a_ = a;}
- + protected:
- + void expire(Event *);
- + Scan_req *a_;
- +};
- +
- +/**
- + * Store information about a pending scan request
- + */
- +class Scan_req {
- + public:
- + Scan_req (WimaxCtrlAgent *agent, double delay, int cid, mac802_16_mob_scn_req_frame *req) {
- + agent_ = agent;
- + timer_ = new ScanRspTimer (this);
- + timer_->sched (delay);
- + cid_ = cid;
- + memcpy (&req_, req, sizeof (mac802_16_mob_scn_req_frame));
- + }
- +
- + int cid() { return cid_; }
- + int& start_frame() { return start_frame_; }
- + int& pending_rsp () { return pending_rsp_; }
- + WimaxCtrlAgent *agent() {return agent_; }
- + mac802_16_mob_scn_req_frame *request() { return &req_; }
- + mac802_16_mob_scn_rsp_frame *response() { return &rsp_; }
- +
- + inline void cancel_timer () {
- + if (timer_->status()==TIMER_PENDING)
- + timer_->cancel();
- + }
- +
- + inline void sched_timer (double time) {
- + timer_->sched (time);
- + }
- + // Chain element to the list
- + inline void insert_entry(struct scan_req *head) {
- + LIST_INSERT_HEAD(head, this, link);
- + }
- +
- + // Return next element in the chained list
- + Scan_req* next_entry(void) const { return link.le_next; }
- +
- + // Remove the entry from the list
- + inline void remove_entry() {
- + cancel_timer ();
- + LIST_REMOVE(this, link);
- + }
- + protected:
- + /*
- + * Pointer to next in the list
- + */
- + LIST_ENTRY(Scan_req) link;
- + //LIST_ENTRY(Scan_req); //for magic draw
- +
- + private:
- + int cid_; //CID of the connection the request came from
- + mac802_16_mob_scn_req_frame req_; //store request data
- + mac802_16_mob_scn_rsp_frame rsp_; //store response data
- + int pending_rsp_; //number of pending responses
- + int start_frame_; //frame number when the serving BS decided the rendez-vous time
- + ScanRspTimer *timer_;
- + WimaxCtrlAgent *agent_;
- +};
- +
- +/**
- + * Timer to send an update to neighboring BSs
- + */
- +class UpdateTimer : public TimerHandler {
- + public:
- + UpdateTimer(WimaxCtrlAgent *a) : TimerHandler()
- + { a_ = a;}
- + protected:
- + void expire(Event *);
- + WimaxCtrlAgent *a_;
- +};
- +
- +class Mac802_16;
- +/**
- + * Agnet to handle communication between BSs
- + */
- +class WimaxCtrlAgent : public Agent {
- +
- + public:
- + /**
- + * Constructor
- + */
- + WimaxCtrlAgent();
- +
- + /*
- + * Interface with TCL interpreter
- + * @param argc The number of elements in argv
- + * @param argv The list of arguments
- + * @return TCL_OK if everything went well else TCL_ERROR
- + */
- + int command(int argc, const char*const* argv);
- +
- + /*
- + * Process received packet
- + * @param p The packet received
- + * @param h The handler that sent the packet
- + */
- + void recv(Packet*, Handler*);
- +
- + /*
- + * Send an update (DCD/UCD) to all neighboring BSs
- + */
- + void sendUpdate ();
- +
- + /**
- + * Process a request from a MN
- + * @param req The request
- + */
- + virtual void process_scan_request (Packet *req);
- +
- + /**
- + * Process synchronization request
- + * @param p The request
- + */
- + virtual void process_synch_request (Packet *p);
- +
- + /**
- + * Process synchronization response
- + * @param p The response
- + */
- + virtual void process_synch_response (Packet *p);
- +
- + /**
- + * Send a scan response to the MN that has the given CID
- + * @param cid The CID of the MN
- + */
- + virtual void send_scan_response (int cid);
- +
- + protected:
- + /**
- + * Process an update message
- + */
- + void processUpdate(Packet* p);
- +
- + Mac802_16 *mac_;
- +
- + /**
- + * Timer to send update messages to neighbor BSs
- + */
- + UpdateTimer updatetimer_;
- +
- + /**
- + * time interval between updates
- + */
- + double adv_interval_;
- +
- + /**
- + * Table mapping neighbor IP address and Mac address
- + */
- + int maptable_[MAX_MAP_ENTRY][2];
- +
- + /**
- + * number of element in the mapping table
- + */
- + int nbmapentry_;
- +
- + /**
- + * Default association level
- + */
- + int defaultlevel_;
- +
- + /**
- + * Contains list of requests
- + */
- + struct scan_req scan_req_head_;
- +
- + /**
- + * Synchronization delay in unit of frame (i.e time we wait for synchronization with BSs)
- + */
- + int synch_frame_delay_;
- +};
- +
- +
- +#endif
- diff -Naur ns-2.29-org/wimax/scheduling/wimaxscheduler.cc ns-2.29/wimax/scheduling/wimaxscheduler.cc
- --- ns-2.29-org/wimax/scheduling/wimaxscheduler.cc 1969-12-31 19:00:00.000000000 -0500
- +++ ns-2.29/wimax/scheduling/wimaxscheduler.cc 2006-09-22 17:27:47.000000000 -0400
- @@ -0,0 +1,226 @@
- +/* 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 "wimaxscheduler.h"
- +
- +/** Subframe timers **/
- +
- +void DlTimer::expire (Event *e)
- +{
- + s_->start_dlsubframe();
- +}
- +
- +void UlTimer::expire (Event *e)
- +{
- + s_->start_ulsubframe();
- +}
- +
- +
- +
- +/*
- + * Create a scheduler
- + * @param mac The Mac where it is located
- + */
- +WimaxScheduler::WimaxScheduler ()
- +{
- + map_ = NULL;
- + dl_timer_ = new DlTimer (this);
- + ul_timer_ = new UlTimer (this);
- + nbr_db_ = new NeighborDB ();
- +}
- +
- +/*
- + * Set the mac
- + * @param mac The Mac where it is located
- + */
- +void WimaxScheduler::setMac (Mac802_16 *mac)
- +{
- + assert (mac!=NULL);
- +
- + mac_ = mac;
- +
- + init ();
- +}
- +
- +/**
- + * Initialize the scheduler.
- + */
- +void WimaxScheduler::init()
- +{
- + //create map structure
- + map_ = new FrameMap (mac_);
- +}
- +
- +/**
- + * Called when a timer expires
- + * @param The timer ID
- + */
- +void WimaxScheduler::expire (timer_id id)
- +{
- +
- +}
- +
- +/**
- + * Return the type of STA this scheduler is good for.
- + * Must be overwritten by subclass.
- + */
- +station_type_t WimaxScheduler::getNodeType ()
- +{
- + return STA_UNKNOWN;
- +}
- +
- +/**
- + * Start a new DL dlframe
- + */
- +void WimaxScheduler::start_dlsubframe ()
- +{
- + //must be overwritten by subclasses.
- +}
- +
- +/**
- + * Start a new UL subframe
- + */
- +void WimaxScheduler::start_ulsubframe ()
- +{
- + //must be overwritten by subclasses.
- +}
- +
- +/**
- + * Process a packet received by the Mac.
- + * Only scheduling related packets should be sent here (BW request, UL_MAP...)
- + */
- +void WimaxScheduler::process (Packet * p) {
- +
- +}
- +
- +/**
- + * Transfert the packets from the given connection to the given burst
- + * @param con The connection
- + * @param b The burst
- + * @param duration The current occupation of the burst
- + * @return the new burst occupation
- + */
- +int WimaxScheduler::transfer_packets (Connection *c, Burst *b, int duration)
- +{
- + Packet *p;
- + hdr_cmn* ch;
- + hdr_mac802_16 *wimaxHdr;
- + double txtime;
- + int txtime_s;
- + bool pkt_transfered = false;
- + OFDMPhy *phy = mac_->getPhy();
- +
- + p = c->get_queue()->head();
- +
- + int max_data;
- + if (getNodeType ()==STA_BS)
- + max_data = phy->getMaxPktSize (b->getDuration()-duration, map_->getDlSubframe()->getProfile (b->getIUC())->getEncoding());
- + else
- + max_data = phy->getMaxPktSize (b->getDuration()-duration, map_->getUlSubframe()->getProfile (b->getIUC())->getEncoding());
- +
- + debug2 ("max data=%d (burst duration=%d, used duration=%dn", max_data, b->getDuration(), duration);
- + if (max_data < HDR_MAC802_16_SIZE ||
- + (c->getFragmentationStatus()!=FRAG_NOFRAG && max_data < HDR_MAC802_16_SIZE+HDR_MAC802_16_FRAGSUB_SIZE))
- + return duration; //not even space for header
- +
- + while (p) {
- + ch = HDR_CMN(p);
- + wimaxHdr = HDR_MAC802_16(p);
- +
- + if (getNodeType ()==STA_BS)
- + max_data = phy->getMaxPktSize (b->getDuration()-duration, map_->getDlSubframe()->getProfile (b->getIUC())->getEncoding());
- + else
- + max_data = phy->getMaxPktSize (b->getDuration()-duration, map_->getUlSubframe()->getProfile (b->getIUC())->getEncoding());
- +
- + if (max_data < HDR_MAC802_16_SIZE ||
- + (c->getFragmentationStatus()!=FRAG_NOFRAG && max_data < HDR_MAC802_16_SIZE+HDR_MAC802_16_FRAGSUB_SIZE))
- + return duration; //not even space for header
- +
- + if (c->getFragmentationStatus()!=FRAG_NOFRAG) {
- + if (max_data >= ch->size()-c->getFragmentBytes()+HDR_MAC802_16_FRAGSUB_SIZE) {
- + //add fragmentation header
- + wimaxHdr->frag_subheader = true;
- + //no need to fragment again
- + wimaxHdr->fc = FRAG_LAST;
- + wimaxHdr->fsn = c->getFragmentNumber ();
- + ch->size() = ch->size()-c->getFragmentBytes()+HDR_MAC802_16_FRAGSUB_SIZE; //new packet size
- + //remove packet from queue
- + c->dequeue();
- + //update fragmentation
- + debug2 ("End of fragmentation %d (max_data=%d, bytes to send=%dn", wimaxHdr->fsn&0x7, max_data, ch->size());
- + c->updateFragmentation (FRAG_NOFRAG, 0, 0);
- + } else {
- + //need to fragment the packet again
- + p = p->copy(); //copy packet to send
- + ch = HDR_CMN(p);
- + wimaxHdr = HDR_MAC802_16(p);
- + //add fragmentation header
- + wimaxHdr->frag_subheader = true;
- + wimaxHdr->fc = FRAG_CONT;
- + wimaxHdr->fsn = c->getFragmentNumber ();
- + ch->size() = max_data; //new packet size
- + //update fragmentation
- + c->updateFragmentation (FRAG_CONT, (c->getFragmentNumber ()+1)%8, c->getFragmentBytes()+max_data-(HDR_MAC802_16_SIZE+HDR_MAC802_16_FRAGSUB_SIZE));
- + debug2 ("Continue fragmentation %dn", wimaxHdr->fsn&0x7);
- + }
- + } else {
- + if (max_data < ch->size() && c->isFragEnable()) {
- + //need to fragment the packet for the first time
- + p = p->copy(); //copy packet to send
- + ch = HDR_CMN(p);
- + wimaxHdr = HDR_MAC802_16(p);
- + //add fragmentation header
- + wimaxHdr->frag_subheader = true;
- + wimaxHdr->fc = FRAG_FIRST;
- + wimaxHdr->fsn = c->getFragmentNumber ();
- + ch->size() = max_data; //new packet size
- + //update fragmentation
- + c->updateFragmentation (FRAG_FIRST, 1, c->getFragmentBytes()+max_data-(HDR_MAC802_16_SIZE+HDR_MAC802_16_FRAGSUB_SIZE));
- + debug2 ("First fragmentationn");
- + } else if (max_data < ch->size() && !c->isFragEnable()) {
- + //the connection does not support fragmentation
- + //can't move packets anymore
- + return duration;
- + } else {
- + //no fragmentation necessary
- + c->dequeue();
- + }
- + }
- +
- + if (getNodeType ()==STA_BS)
- + txtime = phy->getTrxTime (ch->size(), map_->getDlSubframe()->getProfile (b->getIUC())->getEncoding());
- + else
- + txtime = phy->getTrxTime (ch->size(), map_->getUlSubframe()->getProfile (b->getIUC())->getEncoding());
- + ch->txtime() = txtime;
- + txtime_s = (int)round (txtime/phy->getSymbolTime ()); //in units of symbol
- + //printf ("symbtime=%fn", phy->getSymbolTime ());
- + //printf ("Check packet to send: size=%d txtime=%f(%d) duration=%d(%f)n", ch->size(),txtime, txtime_s, b->getDuration(), b->getDuration()*phy->getSymbolTime ());
- + assert ( (duration+txtime_s) <= b->getDuration() );
- + //printf ("transfert to burstn");
- + //p = c->dequeue(); //dequeue connection queue
- + b->enqueue(p); //enqueue into burst
- + duration += txtime_s; //increment time
- + if (!pkt_transfered && getNodeType ()!=STA_BS){ //if we transfert at least one packet, remove bw request
- + pkt_transfered = true;
- + map_->getUlSubframe()->getBw_req()->removeRequest (c->get_cid());
- + }
- + p = c->get_queue()->head(); //get new head
- + }
- + return duration;
- +}
- +
- diff -Naur ns-2.29-org/wimax/scheduling/wimaxscheduler.h ns-2.29/wimax/scheduling/wimaxscheduler.h
- --- ns-2.29-org/wimax/scheduling/wimaxscheduler.h 1969-12-31 19:00:00.000000000 -0500
- +++ ns-2.29/wimax/scheduling/wimaxscheduler.h 2006-09-22 17:27:47.000000000 -0400
- @@ -0,0 +1,151 @@
- +/* 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
- + */
- +
- +#ifndef WIMAX_SCHEDULER_H
- +#define WIMAX_SCHEDULER_H
- +
- +#include "packet.h"
- +#include "mac802_16.h"
- +#include "framemap.h"
- +#include "neighbordb.h"
- +
- +class WimaxScheduler;
- +/** Timer to indicate a new Downlink frame */
- +class DlTimer : public TimerHandler {
- + public:
- + DlTimer(WimaxScheduler *s) : TimerHandler() {s_=s;}
- +
- + void expire(Event *e);
- + private:
- + WimaxScheduler *s_;
- +};
- +
- +/** Timer to indicate a new uplink frame */
- +class UlTimer : public TimerHandler {
- + public:
- + UlTimer(WimaxScheduler *s) : TimerHandler() {s_=s;}
- +
- + void expire(Event *e);
- + private:
- + WimaxScheduler *s_;
- +};
- +
- +
- +/**
- + * Super class for schedulers (BS and MS schedulers)
- + */
- +class WimaxScheduler : public TclObject
- +{
- + friend class FrameMap;
- + friend class WimaxCtrlAgent;
- +public:
- + /*
- + * Create a scheduler
- + */
- + WimaxScheduler ();
- +
- + /*
- + * Set the mac
- + * @param mac The Mac where it is located
- + */
- + void setMac (Mac802_16 *mac);
- +
- + /**
- + * Process a packet received by the Mac. Only scheduling related packets should be sent here (BW request, UL_MAP...)
- + * @param p The packet to process
- + */
- + virtual void process (Packet * p);
- +
- + /**
- + * Return the type of STA this scheduler is good for
- + */
- + virtual station_type_t getNodeType ();
- +
- + /**
- + * Initializes the scheduler
- + */
- + virtual void init ();
- +
- + /**
- + * Called when a timer expires
- + * @param The timer ID
- + */
- + virtual void expire (timer_id id);
- +
- + /**
- + * Return the Mac layer
- + */
- + inline Mac802_16 * getMac () { return mac_;}
- +
- + /**
- + * Start a new DL subframe
- + */
- + virtual void start_dlsubframe ();
- +
- + /**
- + * Start a new UL subframe
- + */
- + virtual void start_ulsubframe ();
- +
- +protected:
- +
- + /**
- + * Transfert the packets from the given connection to the given burst
- + * @param con The connection
- + * @param b The burst
- + * @param duration The current occupation of the burst
- + * @return the new burst occupation
- + */
- + int transfer_packets (Connection *c, Burst *b, int duration);
- +
- + /**
- + * The Mac layer
- + */
- + Mac802_16 * mac_;
- +
- + /**
- + * Packets scheduled to be send this frame
- + */
- + PacketQueue queue_;
- +
- + /**
- + * The map of the frame
- + */
- + FrameMap *map_;
- +
- + /**
- + * Timer used to mark the begining of downlink subframe (i.e new frame)
- + */
- + DlTimer *dl_timer_;
- +
- + /**
- + * Timer used to mark the begining of uplink subframe
- + */
- + UlTimer *ul_timer_;
- +
- + /**
- + * Database of neighboring BS
- + */
- + NeighborDB *nbr_db_;
- +private:
- +
- +
- +
- +};
- +#endif //SCHEDULER_H
- +
- diff -Naur ns-2.29-org/wimax/sduclassifier.cc ns-2.29/wimax/sduclassifier.cc
- --- ns-2.29-org/wimax/sduclassifier.cc 1969-12-31 19:00:00.000000000 -0500
- +++ ns-2.29/wimax/sduclassifier.cc 2006-09-22 17:27:47.000000000 -0400
- @@ -0,0 +1,53 @@
- +/* 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 "sduclassifier.h"
- +
- +/*
- + * Create a classifier in the given mac
- + */
- +SDUClassifier::SDUClassifier ()
- +{
- + //set default priority
- + priority_ = 0;
- +}
- +
- +/*
- + * Interface with the TCL script
- + * @param argc The number of parameter
- + * @param argv The list of parameters
- + */
- +int SDUClassifier::command(int argc, const char*const* argv)
- +{
- + if (argc == 3) {
- + if (strcmp(argv[1], "set-priority") == 0) {
- + priority_ = atoi(argv[2]);
- + return TCL_OK;
- + }
- + }
- + return TCL_ERROR;
- +}
- +
- +/**
- + * Classify a packet and return the CID to use (or -1 if unknown)
- + * @param p The packet to classify
- + * @return The CID or -1
- + */
- +int SDUClassifier::classify (Packet * p) {
- + return -1;
- +}
- diff -Naur ns-2.29-org/wimax/sduclassifier.h ns-2.29/wimax/sduclassifier.h
- --- ns-2.29-org/wimax/sduclassifier.h 1969-12-31 19:00:00.000000000 -0500
- +++ ns-2.29/wimax/sduclassifier.h 2006-09-22 17:27:47.000000000 -0400
- @@ -0,0 +1,107 @@
- +/* 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
- + */
- +
- +#ifndef SDUCLASSIFIER_H
- +#define SDUCLASSIFIER_H
- +
- +#include "packet.h"
- +
- +class Mac802_16;
- +
- +class SDUClassifier;
- +LIST_HEAD (sduClassifier, SDUClassifier);
- +/**
- + * Abstract class for classifiers that will map a packet to a CID
- + */
- +class SDUClassifier : public TclObject
- +{
- + friend class Mac802_16;
- +
- + public:
- + /**
- + * Create a classifier in the given mac
- + */
- + SDUClassifier ();
- +
- + /**
- + * Interface with the TCL script
- + * @param argc The number of parameter
- + * @param argv The list of parameters
- + */
- + int command(int argc, const char*const* argv);
- +
- + /**
- + * Return the classifier's priority
- + */
- + inline int getPriority () { return priority_; }
- +
- + /**
- + * Set the classifier's priority
- + * @param prio The new priority
- + */
- + inline void setPriority (int prio) { priority_ = prio; }
- +
- + /**
- + * Classify a packet and return the CID to use (or -1 if unknown)
- + * @param p The packet to classify
- + * @return The CID or -1
- + */
- + virtual int classify (Packet * p);
- +
- + // Chain element to the list
- + inline void insert_entry_head(struct sduClassifier *head) {
- + LIST_INSERT_HEAD(head, this, link);
- + }
- +
- + // Chain element to the list
- + inline void insert_entry(struct SDUClassifier *elem) {
- + LIST_INSERT_AFTER(elem, this, link);
- + }
- +
- + // Return next element in the chained list
- + SDUClassifier* next_entry(void) const { return link.le_next; }
- +
- + // Remove the entry from the list
- + inline void remove_entry() {
- + LIST_REMOVE(this, link);
- + }
- +
- + protected:
- + /**
- + * The max where the classifier is located
- + */
- + Mac802_16 *mac_;
- +
- + /**
- + * The priority
- + */
- + int priority_;
- +
- + /**
- + * Pointer to next in the list
- + */
- + LIST_ENTRY(SDUClassifier) link;
- + //LIST_ENTRY(SDUClassifier); //for magic draw
- +
- + /**
- + * Register the Mac
- + */
- + inline void setMac (Mac802_16 *mac) { assert (mac); mac_ = mac; }
- +};
- +
- +#endif
- diff -Naur ns-2.29-org/wimax/serviceflow.cc ns-2.29/wimax/serviceflow.cc
- --- ns-2.29-org/wimax/serviceflow.cc 1969-12-31 19:00:00.000000000 -0500
- +++ ns-2.29/wimax/serviceflow.cc 2006-09-22 17:27:47.000000000 -0400
- @@ -0,0 +1,48 @@
- +/* 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 "serviceflow.h"
- +
- +/**
- + * Create a flow with the given parameter
- + */
- +static int FlowIndex = 0;
- +ServiceFlow::ServiceFlow (SchedulingType_t scheduling, ServiceFlowQoS *qos) {
- + id_ = UNASSIGNED_FLOW_ID; //assign and increment flow id
- + scheduling_ = scheduling;
- + qos_ = qos;
- +}
- +
- +/**
- + * Pick the next available ID. Should be called by a BS to assign a unique ID
- + */
- +void ServiceFlow::pickID ()
- +{
- + id_ = FlowIndex++;
- +}
- +
- +/**
- + * Assign an ID to the service flow
- + * @param id The ID to set
- + */
- +void ServiceFlow::setID (int id)
- +{
- + id_ = id;
- +}
- +
- +
- diff -Naur ns-2.29-org/wimax/serviceflow.h ns-2.29/wimax/serviceflow.h
- --- ns-2.29-org/wimax/serviceflow.h 1969-12-31 19:00:00.000000000 -0500
- +++ ns-2.29/wimax/serviceflow.h 2006-09-22 17:27:47.000000000 -0400
- @@ -0,0 +1,139 @@
- +/* 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
- + */
- +
- +#ifndef SERVICEFLOW_H
- +#define SERVICEFLOW_H
- +
- +#include "serviceflowqos.h"
- +//#include "connection.h"
- +#include "packet.h"
- +
- +#define UNASSIGNED_FLOW_ID -1
- +
- +/** Defines the supported scheduling mechanism for the flow */
- +enum SchedulingType_t {
- + SERVICE_UGS,
- + SERVICE_rtPS,
- + SERVICE_nrtPS,
- + SERVICE_BE
- +};
- +
- +class ServiceFlow;
- +LIST_HEAD (serviceflow, ServiceFlow);
- +
- +/**
- + * Class ServiceFlow
- + * The service flow identifies the service requirement
- + * for the associated connection
- + */
- +class ServiceFlow {
- + public:
- + /**
- + * Constructor
- + */
- + ServiceFlow (SchedulingType_t, ServiceFlowQoS*);
- +
- + /**
- + * Return the service flow id
- + * @return The service flow id. -1 if not yet assigned
- + */
- + inline int getID () { return id_; }
- +
- + /**
- + * Assign an ID to the service flow
- + * @param id The ID to set
- + */
- + void setID (int id);
- +
- + /**
- + * Pick the next available ID. Should be called by a BS to assign a unique ID
- + */
- + void pickID ();
- +
- + /**
- + * Set the scheduling mechanism for this flow
- + * @param scheduling The scheduling type
- + */
- + inline void setScheduling (SchedulingType_t scheduling) {scheduling_ = scheduling;}
- +
- + /**
- + * Return the scheduling type for this service flow
- + */
- + inline SchedulingType_t getScheduling () { return scheduling_; }
- +
- + /**
- + * Set the QoS for this flow
- + * @param qos The new QoS for this flow
- + */
- + inline void setQoS (ServiceFlowQoS* qos) { qos_ = qos; }
- +
- + /**
- + * Return the QoS for this connection
- + */
- + inline ServiceFlowQoS * getQoS () { return qos_; }
- +
- + // Chain element to the list
- + inline void insert_entry_head(struct serviceflow *head) {
- + LIST_INSERT_HEAD(head, this, link);
- + }
- +
- + // Chain element to the list
- + inline void insert_entry(ServiceFlow *elem) {
- + LIST_INSERT_AFTER(elem, this, link);
- + }
- +
- + // Return next element in the chained list
- + ServiceFlow* next_entry(void) const { return link.le_next; }
- +
- + // Remove the entry from the list
- + inline void remove_entry() {
- + LIST_REMOVE(this, link);
- + }
- +
- + protected:
- +
- + /**
- + * Pointer to next in the list
- + */
- + LIST_ENTRY(ServiceFlow) link;
- + //LIST_ENTRY(ServiceFlow); //for magic draw
- +
- + private:
- + /**
- + * The service flow id
- + */
- + int id_;
- +
- + /**
- + * The scheduling type (UGS, rtPS...)
- + */
- + SchedulingType_t scheduling_;
- +
- + /**
- + * Flow direction
- + */
- + int direction_;
- +
- + /**
- + * The quality of service for this flow
- + */
- + ServiceFlowQoS * qos_;
- +
- +};
- +#endif //SERVICEFLOW_H
- +
- diff -Naur ns-2.29-org/wimax/serviceflowhandler.cc ns-2.29/wimax/serviceflowhandler.cc
- --- ns-2.29-org/wimax/serviceflowhandler.cc 1969-12-31 19:00:00.000000000 -0500
- +++ ns-2.29/wimax/serviceflowhandler.cc 2006-09-22 17:27:47.000000000 -0400
- @@ -0,0 +1,251 @@
- +/* 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 "serviceflowhandler.h"
- +#include "mac802_16.h"
- +#include "scheduling/wimaxscheduler.h"
- +
- +static int TransactionID = 0;
- +/*
- + * Create a service flow
- + * @param mac The Mac where it is located
- + */
- +ServiceFlowHandler::ServiceFlowHandler ()
- +{
- + LIST_INIT (&flow_head_);
- + LIST_INIT (&pendingflow_head_);
- +}
- +
- +/*
- + * Set the mac it is located in
- + * @param mac The mac it is located in
- + */
- +void ServiceFlowHandler::setMac (Mac802_16 *mac)
- +{
- + assert (mac);
- +
- + mac_ = mac;
- +}
- +
- +/**
- + * Process the given packet. Only service related packets must be sent here.
- + * @param p The packet received
- + */
- +void ServiceFlowHandler::process (Packet * p)
- +{
- + hdr_mac802_16 *wimaxHdr = HDR_MAC802_16(p);
- + gen_mac_header_t header = wimaxHdr->header;
- +
- + //we cast to this frame because all management frame start with
- + //a type
- + mac802_16_dl_map_frame *frame = (mac802_16_dl_map_frame*) p->accessdata();
- +
- + switch (frame->type) {
- + case MAC_DSA_REQ:
- + processDSA_req (p);
- + break;
- + case MAC_DSA_RSP:
- + processDSA_rsp (p);
- + break;
- + case MAC_DSA_ACK:
- + processDSA_ack (p);
- + break;
- + default:
- + printf ("Unknow frame type (%d) in flow handlern", frame->type);
- + }
- + Packet::free (p);
- +}
- +
- +/**
- + * Add a flow with the given qos
- + * @param qos The QoS for the flow
- + * @return the created ServiceFlow
- + */
- +ServiceFlow* ServiceFlowHandler::addFlow (ServiceFlowQoS * qos) {
- + return NULL;
- +}
- +
- +/**
- + * Remove the flow given its id
- + * @param id The flow id
- + */
- +void ServiceFlowHandler::removeFlow (int id) {
- +
- +}
- +
- +/**
- + * Send a flow request to the given node
- + * @param index The node address
- + * @param uplink The flow direction
- + */
- +void ServiceFlowHandler::sendFlowRequest (int index, bool uplink)
- +{
- + Packet *p;
- + struct hdr_cmn *ch;
- + hdr_mac802_16 *wimaxHdr;
- + mac802_16_dsa_req_frame *dsa_frame;
- + PeerNode *peer;
- +
- + //create packet for request
- + peer = mac_->getPeerNode(index);
- + p = mac_->getPacket ();
- + ch = HDR_CMN(p);
- + wimaxHdr = HDR_MAC802_16(p);
- + p->allocdata (sizeof (struct mac802_16_dsa_req_frame));
- + dsa_frame = (mac802_16_dsa_req_frame*) p->accessdata();
- + dsa_frame->type = MAC_DSA_REQ;
- + dsa_frame->uplink = uplink;
- + dsa_frame->transaction_id = TransactionID++;
- + if (mac_->getScheduler()->getNodeType()==STA_MN)
- + ch->size() += GET_DSA_REQ_SIZE (0);
- + else {
- + //assign a CID and include it in the message
- + Connection *data = new Connection (CONN_DATA);
- + mac_->getCManager()->add_connection (data, uplink);
- + if (uplink)
- + peer->setInData (data);
- + else
- + peer->setOutData (data);
- + dsa_frame->cid = data->get_cid();
- + ch->size() += GET_DSA_REQ_SIZE (1);
- + }
- +
- + wimaxHdr->header.cid = peer->getPrimary()->get_cid();
- + peer->getPrimary()->enqueue (p);
- +}
- +
- +/**
- + * process a flow request
- + * @param p The received request
- + */
- +void ServiceFlowHandler::processDSA_req (Packet *p)
- +{
- + mac_->debug ("At %f in Mac %d received DSA requestn", NOW, mac_->addr());
- +
- + Packet *rsp;
- + struct hdr_cmn *ch;
- + hdr_mac802_16 *wimaxHdr_req;
- + hdr_mac802_16 *wimaxHdr_rsp;
- + mac802_16_dsa_req_frame *dsa_req_frame;
- + mac802_16_dsa_rsp_frame *dsa_rsp_frame;
- + PeerNode *peer;
- + Connection *data;
- +
- + //read the request
- + wimaxHdr_req = HDR_MAC802_16(p);
- + dsa_req_frame = (mac802_16_dsa_req_frame*) p->accessdata();
- + peer = mac_->getCManager ()->get_connection (wimaxHdr_req->header.cid, true)->getPeerNode();
- +
- + //allocate response
- + //create packet for request
- + rsp = mac_->getPacket ();
- + ch = HDR_CMN(rsp);
- + wimaxHdr_rsp = HDR_MAC802_16(rsp);
- + rsp->allocdata (sizeof (struct mac802_16_dsa_rsp_frame));
- + dsa_rsp_frame = (mac802_16_dsa_rsp_frame*) rsp->accessdata();
- + dsa_rsp_frame->type = MAC_DSA_RSP;
- + dsa_rsp_frame->transaction_id = dsa_req_frame->transaction_id;
- + dsa_rsp_frame->uplink = dsa_req_frame->uplink;
- + dsa_rsp_frame->confirmation_code = 0; //OK
- +
- + if (mac_->getScheduler()->getNodeType()==STA_MN) {
- + //the message contains the CID for the connection
- + data = new Connection (CONN_DATA, dsa_req_frame->cid);
- + mac_->getCManager()->add_connection (data, dsa_req_frame->uplink);
- + if (dsa_req_frame->uplink)
- + peer->setOutData (data);
- + else
- + peer->setInData (data);
- + ch->size() += GET_DSA_RSP_SIZE (0);
- + } else {
- + //allocate new connection
- + data = new Connection (CONN_DATA);
- + mac_->getCManager()->add_connection (data, dsa_req_frame->uplink);
- + if (dsa_req_frame->uplink)
- + peer->setInData (data);
- + else
- + peer->setOutData (data);
- + dsa_rsp_frame->cid = data->get_cid();
- + ch->size() += GET_DSA_RSP_SIZE (1);
- + }
- +
- + wimaxHdr_rsp->header.cid = peer->getPrimary()->get_cid();
- + peer->getPrimary()->enqueue (rsp);
- +
- +}
- +
- +/**
- + * process a flow response
- + * @param p The received response
- + */
- +void ServiceFlowHandler::processDSA_rsp (Packet *p)
- +{
- + mac_->debug ("At %f in Mac %d received DSA responsen", NOW, mac_->addr());
- +
- + Packet *ack;
- + struct hdr_cmn *ch;
- + hdr_mac802_16 *wimaxHdr_ack;
- + hdr_mac802_16 *wimaxHdr_rsp;
- + mac802_16_dsa_ack_frame *dsa_ack_frame;
- + mac802_16_dsa_rsp_frame *dsa_rsp_frame;
- + Connection *data;
- + PeerNode *peer;
- +
- + //read the request
- + wimaxHdr_rsp = HDR_MAC802_16(p);
- + dsa_rsp_frame = (mac802_16_dsa_rsp_frame*) p->accessdata();
- + peer = mac_->getCManager ()->get_connection (wimaxHdr_rsp->header.cid, true)->getPeerNode();
- +
- + //TBD: check if status not OK
- +
- + if (mac_->getScheduler()->getNodeType()==STA_MN) {
- + //the message contains the CID for the connection
- + data = new Connection (CONN_DATA, dsa_rsp_frame->cid);
- + mac_->getCManager()->add_connection (data, dsa_rsp_frame->uplink);
- + if (dsa_rsp_frame->uplink)
- + peer->setOutData (data);
- + else
- + peer->setInData (data);
- + }
- +
- + //allocate ack
- + //create packet for request
- + ack = mac_->getPacket ();
- + ch = HDR_CMN(ack);
- + wimaxHdr_ack = HDR_MAC802_16(ack);
- + ack->allocdata (sizeof (struct mac802_16_dsa_ack_frame));
- + dsa_ack_frame = (mac802_16_dsa_ack_frame*) ack->accessdata();
- + dsa_ack_frame->type = MAC_DSA_ACK;
- + dsa_ack_frame->transaction_id = dsa_rsp_frame->transaction_id;
- + dsa_ack_frame->uplink = dsa_rsp_frame->uplink;
- + dsa_ack_frame->confirmation_code = 0; //OK
- + ch->size() += DSA_ACK_SIZE;
- +
- + wimaxHdr_ack->header.cid = peer->getPrimary()->get_cid();
- + peer->getPrimary()->enqueue (ack);
- +
- +}
- +
- +/**
- + * process a flow request
- + * @param p The received response
- + */
- +void ServiceFlowHandler::processDSA_ack (Packet *p)
- +{
- + mac_->debug ("At %f in Mac %d received DSA ackn", NOW, mac_->addr());
- +}
- diff -Naur ns-2.29-org/wimax/serviceflowhandler.h ns-2.29/wimax/serviceflowhandler.h
- --- ns-2.29-org/wimax/serviceflowhandler.h 1969-12-31 19:00:00.000000000 -0500
- +++ ns-2.29/wimax/serviceflowhandler.h 2006-09-22 17:27:47.000000000 -0400
- @@ -0,0 +1,111 @@
- +/* 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
- + */
- +
- +#ifndef SERVICEFLOWHANDLER_H
- +#define SERVICEFLOWHANDLER_H
- +
- +#include "serviceflowqos.h"
- +#include "serviceflow.h"
- +#include "packet.h"
- +
- +class Mac802_16;
- +
- +/**
- + * Handler for service flows
- + */
- +class ServiceFlowHandler {
- +
- + public:
- +
- + /*
- + * Create a service flow
- + * @param mac The Mac where it is located
- + */
- + ServiceFlowHandler ();
- +
- + /*
- + * Set the mac it is located in
- + * @param mac The mac it is located in
- + */
- + void setMac (Mac802_16 *mac);
- +
- + /**
- + * Process the given packet. Only service related packets must be sent here.
- + * @param p The packet to process
- + */
- + void process (Packet * p);
- +
- + /**
- + * Add a flow
- + * @param qos The qos for the new connection
- + */
- + ServiceFlow* addFlow (ServiceFlowQoS * qos);
- +
- + /**
- + * Remove a flow
- + * @param id The flow ID
- + */
- + void removeFlow (int id);
- +
- + /**
- + * Send a flow request to the given node
- + * @param index The node address
- + * @param incoming The flow direction
- + */
- + void sendFlowRequest (int index, bool incoming);
- +
- + protected:
- +
- + /**
- + * process a flow request
- + * @param p The received request
- + */
- + void processDSA_req (Packet *p);
- +
- + /**
- + * process a flow response
- + * @param p The received response
- + */
- + void processDSA_rsp (Packet *p);
- +
- + /**
- + * process a flow request
- + * @param p The received response
- + */
- + void processDSA_ack (Packet *p);
- +
- + private:
- +
- + /**
- + * The Mac where this handler is located
- + */
- + Mac802_16 * mac_;
- +
- + /**
- + * The list of current flows
- + */
- + struct serviceflow flow_head_;
- +
- + /**
- + * List of pending flows
- + */
- + struct serviceflow pendingflow_head_;
- +};
- +
- +#endif //SERVICEFLOWHANDLER_H
- +
- diff -Naur ns-2.29-org/wimax/serviceflowqos.cc ns-2.29/wimax/serviceflowqos.cc
- --- ns-2.29-org/wimax/serviceflowqos.cc 1969-12-31 19:00:00.000000000 -0500
- +++ ns-2.29/wimax/serviceflowqos.cc 2006-09-22 17:27:47.000000000 -0400
- @@ -0,0 +1,33 @@
- +/* 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 "serviceflowqos.h"
- +
- +/**
- + * Constructor
- + * @param delay The maximum delay for this connection
- + * @param datarate The average datarate for the connection
- + * @param burstsize The number of byte sent per burst
- + */
- +ServiceFlowQoS::ServiceFlowQoS (int delay, int datarate, int burstsize) {
- + delay_ = delay;
- + datarate_ = datarate;
- + burstsize_ = burstsize;
- +}
- +
- +
- diff -Naur ns-2.29-org/wimax/serviceflowqos.h ns-2.29/wimax/serviceflowqos.h
- --- ns-2.29-org/wimax/serviceflowqos.h 1969-12-31 19:00:00.000000000 -0500
- +++ ns-2.29/wimax/serviceflowqos.h 2006-09-22 17:27:47.000000000 -0400
- @@ -0,0 +1,87 @@
- +/* 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
- + */
- +
- +#ifndef SERVICEFLOWQOS_H
- +#define SERVICEFLOWQOS_H
- +
- +/**
- + * Class ServiceFlowQoS
- + * Defines Qos requirements for the flows
- + */
- +class ServiceFlowQoS {
- +
- + public:
- + /**
- + * Constructor
- + * @param delay The maximum supported delay for the connection
- + * @param datarate Average datarate
- + * @param burstsize Size of each burst
- + */
- + ServiceFlowQoS (int delay, int datarate, int burstsize);
- +
- + /**
- + * Return the maximum delay supported by the connection
- + */
- + inline double getDelay () { return delay_; }
- +
- + /**
- + * Return the average datarate
- + */
- + inline double getDatarate () { return datarate_; }
- +
- + /**
- + * Return the burst size
- + */
- + inline int getBurstSize () { return burstsize_; }
- +
- + /**
- + * Set the maximum delay supported by the connection
- + * @param delay The new delay
- + */
- + inline void setDelay (double delay) { delay_ = delay; }
- +
- + /**
- + * Set the average datarate for the connection
- + * @param datarate The average datarate
- + */
- + inline void setDatarate (double datarate) { datarate_ = datarate; }
- +
- + /**
- + * Set the burst size for the connection
- + * @param size The number of byte sent for each burst
- + */
- + inline void setBurstSize (int size) { burstsize_ = size; }
- +
- + protected:
- +
- + private:
- + /**
- + * The maximum delay for this connection (in sec)
- + */
- + double delay_;
- + /**
- + * The average datarate
- + */
- + double datarate_;
- + /**
- + * The number of bytes per burst
- + */
- + int burstsize_;
- +};
- +#endif //SERVICEFLOWQOS_H
- +