sat-hdlc.cc

Go to the documentation of this file.
00001 /* -*-  Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
00002 /*
00003  * Copyright (c) 1997 Regents of the University of California.
00004  * All rights reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions
00008  * are met:
00009  * 1. Redistributions of source code must retain the above copyright
00010  *    notice, this list of conditions and the following disclaimer.
00011  * 2. Redistributions in binary form must reproduce the above copyright
00012  *    notice, this list of conditions and the following disclaimer in the
00013  *    documentation and/or other materials provided with the distribution.
00014  * 3. All advertising materials mentioning features or use of this software
00015  *    must display the following acknowledgement:
00016  *  This product includes software developed by the Daedalus Research
00017  *  Group at the University of California Berkeley.
00018  * 4. Neither the name of the University nor of the Laboratory may be used
00019  *    to endorse or promote products derived from this software without
00020  *    specific prior written permission.
00021  *
00022  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00023  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00024  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00025  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00026  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00027  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00028  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00029  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00031  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00032  * SUCH DAMAGE.
00033  *
00034  * Contributed by the Daedalus Research Group, http://daedalus.cs.berkeley.edu
00035  */
00036 
00037 #include <sat-hdlc.h>
00038 #include <mac.h>
00039 
00040 #define RESET_HDLC 1
00041 
00042 int HDLC::uidcnt_;
00043 // int hdr_hdlc::offset_;
00044 
00045 // static class HDLCHeaderClass : public PacketHeaderClass {
00046 // public:
00047 //  HDLCHeaderClass()   : PacketHeaderClass("PacketHeader/HDLC",
00048 //                      sizeof(hdr_hdlc)) {
00049 //      bind_offset(&hdr_hdlc::offset_);
00050 //  }
00051 // } class_hdr_hdlc;
00052 
00053 static class HDLCClass : public TclClass {
00054 public:
00055     HDLCClass() : TclClass("LL/Sat/HDLC") {}
00056     TclObject* create(int, const char*const*) {
00057         return (new HDLC);
00058     }
00059 } class_hdlc;
00060 
00061 void HdlcTimer::expire(Event *)
00062 {
00063     (*agent_.*callback_)(a_);
00064     
00065 }
00066 
00067 
00068 HDLC::HDLC() : SatLL(), list_head_(0)
00069 {
00070     bind("window_size_", &wnd_);
00071     bind("queue_size_", &queueSize_);
00072     bind_time("timeout_", &timeout_);
00073     bind("max_timeouts_", &maxTimeouts_);
00074     bind("selRepeat_", &selRepeat_);
00075     bind("delAck_", &delAck_);
00076     bind("delAckVal_", &delAckVal_);
00077     
00078     wndmask_ = HDLC_MWM;
00079     //seen_ = new Packet*[(HDLC_MWM+1)];
00080     //memset(seen_, 0, (sizeof(Packet *) * (HDLC_MWM+1)));
00081 }
00082 
00083 void HDLC::recv(Packet* p, Handler* h)
00084 {
00085     hdr_cmn *ch = HDR_CMN(p);
00086 
00087     /*
00088      * Sanity Check
00089      */
00090     assert(initialized());
00091 
00092     // If direction = UP, then HDLC is recv'ing pkt from the network
00093     // Otherwise, set direction to DOWN and pass it down the stack
00094     if (ch->direction() == hdr_cmn::UP) {
00095         if (ch->ptype_ == PT_ARP)
00096             arptable_->arpinput(p, this);
00097         else 
00098             recvIncoming(p);
00099         // uptarget_ ? sendUp(p) : drop(p);
00100         return;
00101     }
00102 
00103     ch->direction() = hdr_cmn::DOWN;
00104     recvOutgoing(p);
00105 }
00106 
00107 // Functions for sending packets out to network
00108 
00109 void HDLC::recvOutgoing(Packet* p)
00110 {
00111     ARQstate *a;
00112     int next_hop = getRoute(p);
00113     
00114     //if (disconnect_) {
00115         
00116         // if (!sentDISC_) {
00117 //          sendUA(p, DISC);
00118 //          sentDISC_ = 1;
00119 //          set_rtx_timer();
00120 //          drop(p);
00121             
00122 //          return;
00123 //      }
00124 //      drop(p);
00125 //      return;
00126 //  }
00127     
00128     a = checkState(next_hop);
00129     if (a == 0)
00130         a = createState(next_hop);
00131     
00132     if (!(a->SABME_req_) && a->t_seqno_ == 0) {
00133         // this is the first pkt being sent
00134         // send out SABME request to start connection
00135         
00136         sendUA(p, SABME);
00137 
00138         // set SABME request flag to 1
00139         // have sent request, not yet confirmed
00140         a->SABME_req_ = 1;
00141         
00142         // set some timer for SABME?
00143         set_rtx_timer(a);
00144         
00145     }
00146         
00147         // place pkt in outgoing queue
00148     inSendBuffer(p, a);
00149     
00150     // send data pkts only after recving UA
00151     // in reply to SABME request
00152     if (a->SABME_req_ == 2) 
00153         sendMuch(a);
00154     
00155 }
00156 
00157 
00158 void HDLC::inSendBuffer(Packet *p, ARQstate *a) 
00159 {
00160     hdr_cmn *ch = HDR_CMN(p);
00161     hdr_ip *ih = HDR_IP(p);
00162     hdr_hdlc *hh = HDR_HDLC(p);
00163     struct I_frame* ifr = (struct I_frame *)&(hh->hdlc_fc_);
00164     
00165     nsaddr_t src = (nsaddr_t)Address::instance().get_nodeaddr(ih->saddr());
00166     nsaddr_t dst = (nsaddr_t)Address::instance().get_nodeaddr(ih->daddr());
00167     
00168     hh->fc_type_ = HDLC_I_frame;
00169     hh->saddr_ = src;
00170     hh->daddr_ = dst;
00171     
00172     ifr->send_seqno = a->seqno_++;
00173     
00174     ch->size() += HDLC_HDR_LEN;
00175     
00176     a->sendBuf_.enque(p);
00177     
00178 }
00179 
00180 //Packet *HDLC::dataToSend(Packet *p)
00181 Packet *HDLC::dataToSend(ARQstate *a)
00182 {
00183     Packet *dp;
00184     //hdr_ip *ih = HDR_IP(p);
00185     //nsaddr_t dst = (nsaddr_t)Address::instance().get_nodeaddr(ih->saddr());
00186     
00187     // if have any data to send
00188     if (a->t_seqno_ <= a->highest_ack_ + wnd_ && \
00189         (dp = getPkt(a->sendBuf_, a->t_seqno_)) != 0) {
00190         
00191         // XXcheck if the destinations match for data and RR??
00192         
00193         Packet *np = dp->copy();
00194         return np;
00195     }
00196     return NULL;
00197 }
00198 
00199 
00200 
00201 // try to send as much as possible if have any pkts to send
00202 void HDLC::sendMuch(ARQstate *a)
00203 {
00204     Packet *p;
00205     
00206     while (a->t_seqno_ <= a->highest_ack_ + wnd_ && (p = getPkt(a->sendBuf_, a->t_seqno_)) != 0) {
00207         Packet *dp = p->copy();
00208         output(dp, a, a->t_seqno_);
00209         a->t_seqno_++;
00210         
00211     } 
00212     
00213 }
00214 
00215 
00216 void HDLC::output(Packet *p, ARQstate *a, int seqno)
00217 {
00218     int force_set_rtx_timer = 0;
00219 
00220     hdr_hdlc* hh = HDR_HDLC(p);
00221     struct I_frame* ifr = (struct I_frame *)&(hh->hdlc_fc_);
00222 
00223     // piggyback the last seqno recvd
00224     if (selRepeat_)
00225         ifr->recv_seqno = a->nextpkt_;
00226     else
00227         ifr->recv_seqno = a->recv_seqno_;
00228 
00229     // cancel the delay timer if pending
00230     if (a->delay_timer_->status() == TIMER_PENDING) 
00231         cancel_delay_timer(a);
00232     if (a->save_ != NULL) {
00233                 Packet::free(a->save_);
00234                 a->save_ = NULL;
00235         }
00236     
00237     sendDown(p);
00238     
00239     // if no outstanding data set rtx timer again
00240     if (a->highest_ack_ == a->maxseq_)
00241         force_set_rtx_timer = 1;
00242     if (seqno > a->maxseq_) 
00243         a->maxseq_ = seqno;
00244     else if (seqno < a->maxseq_)
00245         ++(a->nrexmit_);
00246     
00247     if (!(a->rtx_timer_->status() == TIMER_PENDING) || force_set_rtx_timer)
00248 
00249         // No timer pending.  Schedule one.
00250         set_rtx_timer(a);
00251 }
00252 
00253 
00254 void HDLC::sendUA(Packet *p, COMMAND_t cmd)
00255 {
00256     Packet *np = Packet::alloc();
00257     
00258     hdr_cmn *ch = HDR_CMN(p);
00259     hdr_cmn *nch = HDR_CMN(np);
00260     hdr_ip *ih = HDR_IP(p);
00261     hdr_ip *nih = HDR_IP(np);
00262     struct hdr_hdlc* nhh = HDR_HDLC(np);
00263     struct U_frame* uf = (struct U_frame *)&(nhh->hdlc_fc_);
00264     
00265     nsaddr_t src = (nsaddr_t)Address::instance().get_nodeaddr(ih->saddr());
00266     nsaddr_t dst = (nsaddr_t)Address::instance().get_nodeaddr(ih->daddr());
00267 
00268         // setup common hdr
00269     nch->addr_type() = ch->addr_type();
00270     nch->uid() = uidcnt_++;
00271     nch->ptype() = PT_HDLC;
00272     nch->size() = HDLC_HDR_LEN;
00273     nch->error() = 0;
00274     nch->iface() = -2;
00275     
00276     //nih->daddr() = ih->daddr();
00277     
00278     nhh->fc_type_ = HDLC_U_frame;
00279 
00280     switch(cmd) {
00281         
00282     case SABME:
00283     case DISC:
00284         // use same dst and src address
00285         nih->daddr() = ih->daddr();
00286         nih->saddr() = ih->saddr();
00287         nhh->daddr_ = dst;
00288         nhh->saddr_ = src;
00289         break;
00290         
00291     case UA:
00292         // use reply mode; src and dst get reversed
00293         nih->daddr() = ih->saddr();
00294         nih->saddr() = ih->daddr();
00295         nhh->daddr_ = src;
00296         nhh->saddr_ = dst;
00297         break;
00298         
00299     default:
00300         fprintf(stderr, "Unknown type of U frame\n");
00301         exit(1);
00302     }
00303     
00304     uf->utype = cmd;
00305     sendDown(np);
00306     
00307     //return (np);
00308 }
00309 
00310 
00311 void HDLC::sendDISC(Packet *p)
00312 {
00313     sendUA(p, DISC);
00314     
00315 }
00316 
00317 void HDLC::delayTimeout(ARQstate *state)
00318 {
00319     // The delay timer expired so we ACK the last pkt seen
00320     if (state->save_ != NULL) {
00321         Packet* pkt = state->save_;
00322         ack(pkt);
00323         state->save_ = NULL;
00324         Packet::free(pkt);
00325     }
00326 }
00327 
00328 void HDLC::ack(Packet *p)
00329 {
00330 
00331     hdr_cmn *ch = HDR_CMN(p);
00332     int last_hop = ch->last_hop_;
00333     ARQstate *a = checkState(last_hop);
00334 
00335     // sanity check; but should not come here.
00336     if (a == 0) {
00337         printf("ack(): No state found for %d\n",last_hop);
00338         return;
00339     }
00340     
00341     Packet *dp;
00342     
00343     //if ((dp = dataToSend(p)) != NULL) {
00344     if (a->t_seqno_ > 0 && (dp = dataToSend(a)) != NULL) {
00345         output(dp, a, a->t_seqno_); 
00346         a->t_seqno_++;
00347         
00348     } else {
00349         
00350         sendRR(p,a);
00351     }
00352     
00353 }
00354 
00355 
00356 void HDLC::sendRR(Packet *p, ARQstate *a)
00357 {
00358     Packet *np = Packet::alloc();
00359     
00360     hdr_cmn *ch = HDR_CMN(p);
00361     hdr_ip *ih = HDR_IP(p);
00362     struct hdr_hdlc *hh = HDR_HDLC(p);
00363 
00364     hdr_cmn *nch = HDR_CMN(np);
00365     hdr_ip *nih = HDR_IP(np);
00366     struct hdr_hdlc *nhh = HDR_HDLC(np);
00367     struct S_frame *sf = (struct S_frame*)&(nhh->hdlc_fc_);
00368     
00369 
00370     // common hdr
00371     nch->addr_type() = ch->addr_type();
00372     nch->uid() = uidcnt_++;
00373     nch->ptype() = PT_HDLC;
00374     nch->size() = HDLC_HDR_LEN;
00375     nch->error() = 0;
00376     nch->iface() = -2;
00377     
00378     nih->daddr() = ih->saddr();
00379     nih->saddr() = ih->daddr();
00380     
00381     nhh->fc_type_ = HDLC_S_frame;
00382 
00383     if (selRepeat_)
00384         sf->recv_seqno = a->nextpkt_;
00385     else
00386         sf->recv_seqno = a->recv_seqno_;
00387     
00388     sf->stype = RR;
00389     
00390     nhh->saddr_ = hh->daddr();
00391     nhh->daddr_ = hh->saddr();
00392 
00393     sendDown(np);
00394     
00395 }
00396 
00397 void HDLC::sendRNR(Packet *p)
00398 {}
00399 
00400 void HDLC::sendREJ(Packet *p, ARQstate *a)
00401 {
00402     Packet *np = Packet::alloc();
00403 
00404     hdr_cmn *ch = HDR_CMN(p);
00405     hdr_ip *ih = HDR_IP(p);
00406     struct hdr_hdlc *hh = HDR_HDLC(p);
00407 
00408     hdr_cmn *nch = HDR_CMN(np);
00409     hdr_ip *nih = HDR_IP(np);
00410     struct hdr_hdlc *nhh = HDR_HDLC(np);
00411     struct S_frame *sf = (struct S_frame *)&(nhh->hdlc_fc_);
00412     
00413 
00414     // common hdr
00415     nch->addr_type() = ch->addr_type();
00416     nch->uid() = uidcnt_++;
00417     nch->ptype() = PT_HDLC;
00418     nch->size() = HDLC_HDR_LEN;
00419     nch->error() = 0;
00420     nch->iface() = -2;
00421     
00422     nih->daddr() = ih->saddr();
00423     nih->saddr() = ih->daddr();
00424     
00425     nhh->fc_type_ = HDLC_S_frame;
00426     sf->recv_seqno = a->recv_seqno_;
00427     sf->stype = REJ;
00428     
00429     nhh->saddr_ = hh->daddr();
00430     nhh->daddr_ = hh->saddr();
00431 
00432     sendDown(np);
00433     
00434 }
00435 
00436 void HDLC::sendSREJ(Packet *p, int seq)
00437 {
00438     Packet *np = Packet::alloc();
00439 
00440     hdr_cmn *ch = HDR_CMN(p);
00441     hdr_ip *ih = HDR_IP(p);
00442     struct hdr_hdlc *hh = HDR_HDLC(p);
00443 
00444     hdr_cmn *nch = HDR_CMN(np);
00445     hdr_ip *nih = HDR_IP(np);
00446     struct hdr_hdlc *nhh = HDR_HDLC(np);
00447     struct S_frame *sf = (struct S_frame *)&(nhh->hdlc_fc_);
00448 
00449     // common hdr
00450     nch->addr_type() = ch->addr_type();
00451     nch->uid() = uidcnt_++;
00452     nch->ptype() = PT_HDLC;
00453     nch->size() = HDLC_HDR_LEN;
00454     nch->error() = 0;
00455     nch->iface() = -2;
00456     
00457     nih->daddr() = ih->saddr();
00458     nih->saddr() = ih->daddr();
00459     
00460     nhh->fc_type_ = HDLC_S_frame;
00461 
00462     sf->recv_seqno = seq;
00463     sf->stype = SREJ;
00464 
00465     nhh->saddr_ = hh->daddr();
00466     nhh->daddr_ = hh->saddr();
00467 
00468     sendDown(np);
00469 
00470 }
00471 
00472 
00473 
00474 void HDLC::sendDown(Packet* p)
00475 {   
00476     hdr_cmn *ch = HDR_CMN(p);
00477     
00478     char *mh = (char*)p->access(hdr_mac::offset_);
00479     int peer_mac_;
00480     SatChannel* satchannel_;
00481 
00482     getRoute(p);
00483     
00484     // Set mac src, type, and dst
00485     mac_->hdr_src(mh, mac_->addr());
00486     mac_->hdr_type(mh, ETHERTYPE_IP); // We'll just use ETHERTYPE_IP
00487     
00488     nsaddr_t dst = ch->next_hop();
00489     // a value of -1 is IP_BROADCAST
00490     if (dst < -1) {
00491         printf("Error:  next_hop_ field not set by routing agent\n");
00492         exit(1);
00493     }
00494 
00495     switch(ch->addr_type()) {
00496 
00497     case NS_AF_INET:
00498     case NS_AF_NONE:
00499         if (IP_BROADCAST == (u_int32_t) dst)
00500             {
00501             mac_->hdr_dst((char*) HDR_MAC(p), MAC_BROADCAST);
00502             break;
00503         }
00504         /* 
00505          * Here is where arp would normally occur.  In the satellite
00506          * case, we don't arp (for now).  Instead, use destination
00507          * address to find the mac address corresponding to the
00508          * peer connected to this channel.  If someone wants to
00509          * add arp, look at how the wireless code does it.
00510          */ 
00511         // Cache latest value used
00512         if (dst == arpcachedst_) {
00513             mac_->hdr_dst((char*) HDR_MAC(p), arpcache_);
00514             break;
00515         }
00516         // Search for peer's mac address (this is the pseudo-ARP)
00517         satchannel_ = (SatChannel*) channel();
00518         peer_mac_ = satchannel_->find_peer_mac_addr(dst);
00519         if (peer_mac_ < 0 ) {
00520             printf("Error:  couldn't find dest mac on channel ");
00521             printf("for src/dst %d %d at NOW %f\n", 
00522                 ch->last_hop_, dst, NOW); 
00523             exit(1);
00524         } else {
00525             mac_->hdr_dst((char*) HDR_MAC(p), peer_mac_);
00526             arpcachedst_ = dst;
00527             arpcache_ = peer_mac_;
00528             break;
00529         } 
00530 
00531     default:
00532         printf("Error:  addr_type not set to NS_AF_INET or NS_AF_NONE\n");
00533         exit(1);
00534     }
00535     
00536     // let mac decide when to take a new packet from the queue.
00537     Scheduler& s = Scheduler::instance();
00538     s.schedule(downtarget_, p, delay_);
00539 }
00540 
00541 
00542 
00543 
00544 
00545 // functions for receiving pkts from the network
00546 
00547 void HDLC::recvIncoming(Packet* p)
00548 {
00549     // This pkt is coming from the network
00550     // check if pkt has error
00551     
00552     if (hdr_cmn::access(p)->error() > 0)
00553         drop(p);
00554     else {
00555         hdr_hdlc* hh = HDR_HDLC(p);
00556         switch (hh->fc_type_) {
00557         case HDLC_I_frame:
00558             recvIframe(p);
00559             break;
00560         case HDLC_S_frame:
00561             recvSframe(p);
00562             break;
00563         case HDLC_U_frame:
00564             recvUframe(p);
00565             break;
00566         default:
00567             fprintf(stderr, "Invalid HDLC control type\n");
00568             exit(1);
00569         }
00570     }
00571 }
00572 
00573 // recv data pkt
00574 void HDLC::recvIframe(Packet *p) 
00575 {
00576     struct I_frame* ifr = (struct I_frame *)&(HDR_HDLC(p)->hdlc_fc_);
00577     int rseq = ((struct I_frame*)&(HDR_HDLC(p)->hdlc_fc_))->recv_seqno;
00578     
00579     // check if any ack is piggybacking
00580     // and update highest_ack_
00581     int last_hop = HDR_CMN(p)->last_hop_;
00582     ARQstate *a = checkState(last_hop);
00583     
00584     // if state doesn't exist, or connection not setup yet
00585     // drop data pkt
00586     if (a == 0 || a->SABME_req_ == 1) {
00587         printf("recvIframe(): No state/connection found for %d\n",last_hop);
00588         return;
00589     }
00590     
00591     // if this is the first data pkt we recv, set the
00592     // SABME flag, as this is the third leg of the 3 way handshake
00593     // for connection setup for HDLC
00594     if (a->recv_seqno_ == -1 && a->SABME_req_ == 0)
00595         a->SABME_req_ = 2;
00596     
00597     if (rseq > -1)  // valid ack
00598         handlePiggyAck(p,a);
00599     
00600     // recvd first data pkt
00601     if (ifr->send_seqno == 0 && a->recv_seqno_ == -1) 
00602         a->recv_seqno_ = 0;
00603 
00604     if (selRepeat_) // do selective repeat
00605     
00606         selectiveRepeatMode(p);
00607     else
00608         // default to go back N
00609         goBackNMode(p);
00610     
00611     
00612     // if we had got a valid piggy ack
00613     // see if we can send more
00614     if (rseq > -1)  
00615         sendMuch(a);
00616     
00617 }
00618 
00619 void HDLC::recvSframe(Packet* p)
00620 {
00621     hdr_hdlc* hh = HDR_HDLC(p);
00622     struct S_frame *sf = (struct S_frame*)&(hh->hdlc_fc_);
00623     
00624     
00625     switch(sf->stype)
00626     {
00627     case RR:
00628         handleRR(p);
00629         break;
00630         
00631     case REJ:
00632         handleREJ(p);
00633         break;
00634         
00635     case RNR:
00636         handleRNR(p);
00637         break;
00638         
00639     case SREJ:
00640         handleSREJ(p);
00641         break;
00642         
00643     default:
00644         fprintf(stderr, "Unknown type of S frame\n");
00645         exit(0);
00646         
00647     }
00648     
00649 }
00650 
00651 void HDLC::recvUframe(Packet* p)
00652 {
00653     // U frames supported for now are ABME/UA/DISC
00654     hdr_hdlc* hh = HDR_HDLC(p);
00655     struct U_frame *uf = (struct U_frame*)&(hh->hdlc_fc_);
00656     
00657     switch(uf->utype) 
00658     {
00659     case SABME:
00660         handleSABMErequest(p);
00661         break;
00662         
00663     case UA:
00664         handleUA(p);
00665         break;
00666         
00667     case DISC:
00668         handleDISC(p);
00669         break;
00670         
00671     default:
00672         fprintf(stderr, "Unknown type of U frame\n");
00673         exit(1);
00674     }
00675     
00676 }
00677 
00678 void HDLC::handleSABMErequest(Packet *p)
00679 {
00680     hdr_cmn *ch = HDR_CMN(p);
00681     int last_hop = ch->last_hop_;
00682 
00683     ARQstate *a = checkState(last_hop);
00684 
00685 #ifdef RESET_HDLC
00686     if (a != 0) {
00687         
00688         // For HDLC resetting option, we might recv a SABME req since the sender got reset but the recvr didn't. In that case the recvr should reset in order to synchronise with sender.
00689         printf("Got SABME req for existing connection; resetting\n");
00690         reset(a);
00691     }
00692     
00693     // create new state
00694     a = createState(last_hop);
00695 #else
00696     // create state only if one is not present already
00697     if (a == 0)
00698         a = createState(last_hop);
00699 #endif  
00700     
00701         // got a request to either open a connection
00702     // or reset an old connection as sender may have reset due to timeout
00703         // ack back an UA
00704     //if (a->recv_seqno_ == -1) {
00705     sendUA(p, UA);
00706     //closed_ = 0;
00707     //}
00708 
00709     Packet::free(p);
00710 }
00711 
00712 
00713 void HDLC::handleDISC(Packet *p)
00714 {
00715     hdr_cmn *ch = HDR_CMN(p);
00716     int last_hop = ch->last_hop_;
00717     ARQstate *a = checkState(last_hop);
00718     
00719         // got request for disconnect
00720     // send UA 
00721     reset(a);
00722     sendUA(p, UA);
00723     Packet::free(p);
00724 
00725 }
00726 
00727 void HDLC::handleUA(Packet *p)
00728 {
00729     hdr_cmn *ch = HDR_CMN(p);
00730     int last_hop = ch->last_hop_;
00731     ARQstate *a = checkState(last_hop);
00732     
00733     if (a == 0) {
00734         printf("handleUA: No state found for %d\n", last_hop);
00735         return;
00736     }
00737     
00738     // recv ok for connection
00739     // if waiting to send, start sending
00740     // ?? shouldn't I match the addresses here??
00741     if (a->t_seqno_ == 0 && a->SABME_req_ == 1) {
00742         // set SABME request flag to 2
00743         // indicating a confirmed connection
00744         a->SABME_req_ = 2;
00745         
00746         // cancel the SABME timers
00747         cancel_rtx_timer(a);
00748         
00749         sendMuch(a);
00750         //closed_ = 0;
00751         
00752     } else { // have I sent a DISCONNECT?
00753         if (a->disconnect_) {
00754             // recvd confirmation on disconnect
00755             reset(a);
00756         }
00757     }
00758     Packet::free(p);
00759     
00760 }
00761 
00762 
00763 void HDLC::handlePiggyAck(Packet *p, ARQstate *a)
00764 {
00765     hdr_hdlc* hh = HDR_HDLC(p);
00766     struct I_frame *ifr =  (struct I_frame*)&(hh->hdlc_fc_);
00767 
00768     int seqno = ifr->recv_seqno - 1;
00769     if (seqno > a->highest_ack_) {  // recvd a new ack
00770         
00771         Packet *datapkt = getPkt(a->sendBuf_, seqno);
00772         a->sendBuf_.remove(datapkt);
00773         Packet::free(datapkt);
00774 
00775         // update highest_ack_
00776         a->highest_ack_ = seqno;
00777         
00778         // set retx_timer
00779         if (a->t_seqno_ > seqno || seqno < a->maxseq_)
00780             set_rtx_timer(a);
00781         
00782         else
00783             cancel_rtx_timer(a);
00784         
00785     } else { // got duplicate acks
00786         // do nothing as piggyback ack
00787     }
00788     
00789     // if had timeouts, should reset it now
00790     a->ntimeouts_ = 0;
00791     
00792 }
00793 
00794 
00795 // receiver ready - ack for a pkt successfully recvd by receiver, send next pkt pl
00796 void HDLC::handleRR(Packet *p)
00797 {
00798     // recvd an ack for a pkt
00799     // remove data pkt from outgoing buffer, if applicable
00800     struct S_frame *sf = (struct S_frame *)&(HDR_HDLC(p)->hdlc_fc_);
00801     int seqno = sf->recv_seqno - 1;
00802     int last_hop = HDR_CMN(p)->last_hop_;
00803     ARQstate *a = checkState(last_hop);
00804     
00805     if (a == 0){
00806         printf("handleRR: No state found for %d\n", last_hop);
00807         return;
00808     }
00809 
00810     if (seqno > a->highest_ack_) {  // recvd a new ack
00811         
00812         Packet *datapkt = getPkt(a->sendBuf_, seqno);
00813         if (datapkt != NULL) {
00814             a->sendBuf_.remove(datapkt);
00815             Packet::free(datapkt);
00816             
00817             // update highest_ack_
00818             a->highest_ack_ = seqno;
00819         }
00820         
00821         // set retx_timer
00822         if ((a->t_seqno_-1) > seqno || seqno < a->maxseq_ )
00823             set_rtx_timer(a);
00824         
00825         else
00826             cancel_rtx_timer(a);
00827         
00828     } else { // got duplicate acks
00829         
00830         drop(p);
00831     }
00832     
00833     // if had timeouts, should reset it now
00834     a->ntimeouts_ = 0;
00835     
00836     // try to send more
00837     Packet::free(p);
00838     sendMuch(a);
00839     
00840 }
00841 
00842 
00843 Packet *HDLC::getPkt(PacketQueue buffer, int seqno)
00844 {
00845     Packet *p;
00846     
00847     buffer.resetIterator();
00848     for (p = buffer.getNext(); p != 0; p = buffer.getNext()) {
00849         
00850         if (((struct I_frame *)&(HDR_HDLC(p)->hdlc_fc_))->send_seqno == seqno)
00851             return p;
00852     }
00853 
00854     return(NULL);
00855 }
00856 
00857 // receiver not ready
00858 void HDLC::handleRNR(Packet *p)
00859 {
00860     // stop sending pkts and wait until RR is recved.
00861     // wait for how long?
00862 }
00863 
00864 // handle reject or a go-back-N request from receiver
00865 void HDLC::handleREJ(Packet *rejp)
00866 {
00867     // set seqno_ = seqno in REJ
00868     // and start sending
00869     struct S_frame *sf = (struct S_frame *)&(HDR_HDLC(rejp)->hdlc_fc_);
00870     int seqno = sf->recv_seqno;
00871     int last_hop = HDR_CMN(rejp)->last_hop_;
00872     ARQstate *a = checkState(last_hop);
00873     
00874     if (a == 0) {
00875         printf("handleREJ: No state found for %d\n", last_hop);
00876         return;
00877     }
00878 
00879     a->t_seqno_ = seqno;
00880     sendMuch(a);
00881     
00882     Packet::free(rejp);
00883 }
00884 
00885 
00886 // selective reject or a NACK for a data pkt not recvd from the receiver
00887 void HDLC::handleSREJ(Packet *rejp)
00888 {
00889     
00890     struct S_frame *sf = (struct S_frame *)&(HDR_HDLC(rejp)->hdlc_fc_);
00891     int seqno = sf->recv_seqno;
00892     int last_hop = HDR_CMN(rejp)->last_hop_;
00893     ARQstate *a = checkState(last_hop);
00894     
00895     if (a == 0) {
00896         printf("handleSREJ: No state found for %d\n", last_hop);
00897         return;
00898     }
00899 
00900     // resend only the pkt that was requested
00901     Packet *p = getPkt(a->sendBuf_, seqno);
00902     Packet *dp = p->copy();
00903     
00904     output(dp, a, seqno);
00905     
00906     Packet::free(rejp);
00907     
00908 }
00909 
00910 void HDLC::reset(ARQstate *a)
00911 {
00912     Packet *p;
00913     int n;
00914     
00915     // cancel all pending timeouts
00916     if (a->rtx_timer_->status() == TIMER_PENDING) 
00917         cancel_rtx_timer(a);
00918     if (a->reset_timer_->status() == TIMER_PENDING)
00919         cancel_reset_timer(a);
00920     if (a->delay_timer_->status() == TIMER_PENDING)
00921         cancel_delay_timer(a);
00922     
00923     // now delete timers
00924     delete a->rtx_timer_;
00925     delete a->reset_timer_;
00926     delete a->delay_timer_;
00927 
00928     // purge send buffer, if any
00929     n = a->highest_ack_ + 1;
00930     while ((p = getPkt(a->sendBuf_, n)) != NULL) 
00931     {
00932         a->sendBuf_.remove(p);
00933         Packet::free(p);
00934         n++;
00935     }
00936 
00937     // purge recv buffer, if any
00938     if (selRepeat_)
00939     {
00940         // purge recv side buffer
00941         // to send up out-of-order pkts
00942         // should we drop these pkts instead ??
00943         for (n=0; n <= HDLC_MWM; n++) {
00944             
00945             Packet *p = a->seen_[n];
00946             if (p != 0) {
00947                 uptarget_ ? sendUp(p) : drop(p);
00948                 a->seen_[n] = 0;
00949             }
00950         }
00951         delete a->seen_;
00952     }
00953     if (a->save_)
00954         delete a->save_;
00955 
00956     removeState(a->nh_);
00957     
00958 }
00959 
00960 // void HDLC::reset_recvr(ARQstate *a)
00961 // {
00962 //  int n = 0;
00963     
00964 //  if (selRepeat_)
00965 //  {
00966 //      // purge recv side buffer
00967 //      // to send up out-of-order pkts
00968 //      // should we drop these pkts instead ??
00969 //      while (a->seen_[n] != NULL){
00970 //          Packet *p = a->seen_[n];
00971 //          a->seen_[n] = 0;
00972 //          uptarget_ ? sendUp(p) : drop(p);
00973 //          ++n;
00974 //      }
00975 //      delete a->seen_;
00976 //      delete a->save_;
00977         
00978 //  }
00979     
00980 //  delete rtx_timer_;
00981 //  delete reset_timer_;
00982 //  delete delay_timer_;
00983     
00984 //  removeState(a);
00985 // }
00986 
00987         
00988         
00989 
00990 // void HDLC::reset_sender(ARQstate *a)
00991 // {
00992 //  Packet *p;
00993 //  int n = a->highest_ack_ + 1;
00994     
00995 //  // purge pkts in sendBuf
00996 //  while ((p = getPkt(a->sendBuf_, n)) != NULL) 
00997 //  {
00998 //      a->sendBuf_.remove(p);
00999 //      Packet::free(p);
01000 //      n++;
01001 //  }
01002     
01003 //         // delete timers
01004     
01005     
01006      
01007 // }
01008 
01009 // void HDLC::set_ack_timer()
01010 // {
01011 //  ack_timer_.sched(DELAY_ACK_VAL);
01012 // }
01013 
01014 
01015 void HDLC::reset_rtx_timer(ARQstate *a, int backoff)
01016 {
01017     if (backoff)
01018         rtt_backoff();
01019     set_rtx_timer(a);
01020     a->t_seqno_ = a->highest_ack_ + 1;
01021 }
01022 
01023 void HDLC::set_rtx_timer(ARQstate *a)
01024 {
01025     a->rtx_timer_->resched(rtt_timeout());
01026 }
01027 
01028 void HDLC::set_reset_timer(ARQstate *a)
01029 {
01030     a->reset_timer_->resched(reset_timeout());
01031 }
01032 
01033 
01034 void HDLC::timeout(ARQstate *a)
01035 {
01036     //char buf[SMALL_LEN];
01037     
01038     //if (disconnect_) {
01039     //sentDISC_ = 0;
01040     //return;
01041     //}
01042     double now = Scheduler::instance().clock();
01043     
01044     a->ntimeouts_++;
01045     
01046     printf("hdlc TIMEOUT:%f, nh=%d, nto=%d\n", now, a->nh_,a->ntimeouts_);
01047     //trace_event(buf);
01048     
01049     if (a->ntimeouts_ > maxTimeouts_) {
01050         //disconnect_ = 1;
01051         //sendDISC();
01052 
01053 #ifdef RESET_HDLC
01054         reset(a);
01055 #endif
01056         return;
01057     }
01058 
01059     // SABME timeout
01060     if (a->SABME_req_ && a->t_seqno_ == 0 ) {
01061         
01062         if (a->ntimeouts_ < maxTimeouts_) {
01063             Packet *p = getPkt(a->sendBuf_, 0);
01064             sendUA(p, SABME);
01065             set_rtx_timer(a);
01066         
01067         } else {
01068             fprintf(stderr,"SABME timeout: No connection\n");
01069 #ifdef RESET_HDLC
01070             // flush all pkts 
01071             reset(a);
01072 #endif          
01073         }
01074         return;
01075     }
01076     
01077     
01078     
01079     if (a->highest_ack_ == a->maxseq_) {
01080         // no outstanding data
01081         // then don't do  anything
01082         reset_rtx_timer(a,0);
01083 
01084     } else {
01085         a->t_seqno_ = a->highest_ack_ + 1;
01086         sendMuch(a);
01087         
01088     }
01089 }
01090 
01091 double HDLC::rtt_timeout()
01092 {
01093     return timeout_;
01094 }
01095 
01096 double HDLC::reset_timeout()
01097 {
01098     if (maxTimeouts_ < 1)
01099         maxTimeouts_ = 1;
01100     
01101     return (timeout_ * maxTimeouts_);
01102 }
01103 
01104 void HDLC::rtt_backoff()
01105 {
01106     // no backoff for now
01107 }
01108 
01109 
01110 // doing GoBAckN error recovery
01111 void HDLC::goBackNMode(Packet *p)
01112 {
01113     hdr_cmn *ch = HDR_CMN(p);
01114     hdr_hdlc* hh = HDR_HDLC(p);
01115     struct I_frame* ifr = (struct I_frame *)&(hh->hdlc_fc_);
01116     int last_hop = ch->last_hop_;
01117     ARQstate *a = checkState(last_hop);
01118     
01119     // recv data in order
01120     if (ifr->send_seqno == a->recv_seqno_) {
01121         
01122         if (a->sentREJ_)
01123             a->sentREJ_ = 0;
01124         
01125         a->recv_seqno_++;
01126         
01127                 // strip off hdlc hdr
01128         ch->size() -= HDLC_HDR_LEN;
01129 
01130         // send ack back
01131         // start a timer to delay the ack so that
01132         // we can try and piggyback the ack in some data pkt
01133         if (delAck_) {
01134             
01135             if (a->delay_timer_->status() != TIMER_PENDING) {
01136                 assert(a->save_ == NULL);
01137                 a->save_ = p->copy();
01138                 a->delay_timer_->sched(delAckVal_);
01139             } 
01140             
01141         } else {
01142             ack(p);
01143             
01144         }
01145         
01146         uptarget_ ? sendUp(p) : drop(p);
01147 
01148         
01149     } else if (ifr->send_seqno > a->recv_seqno_) {
01150 
01151         if (!a->sentREJ_) {
01152             a->sentREJ_ = 1;
01153             // since GoBackN send REJ for the first
01154             // out of order pkt
01155             sendREJ(p,a);
01156             // set a timer for resetting recvr on timeout
01157             // waiting for in order pkt
01158 #ifdef RESET_HDLC
01159             set_reset_timer(a);
01160 #endif
01161             
01162         }
01163         
01164         drop(p, "Pkt out of order");
01165         
01166     } else {
01167         // send_seqno < recv_seqno; duplicate data pkts
01168         // send ack back as previous RR maybe lost
01169         ack(p);
01170         //ack();
01171         drop(p, "Duplicate pkt");
01172     }
01173     
01174 }
01175 
01176 
01177 // Selective Repeat mode of error recovery
01178 // in case of a missing pkt, send SREJ for that pkt only
01179 
01180 void HDLC::selectiveRepeatMode(Packet* p)
01181 {
01182     hdr_cmn *ch = HDR_CMN(p);
01183     int seq =  ((struct I_frame *)&(HDR_HDLC(p)->hdlc_fc_))->send_seqno;
01184     bool just_marked_as_seen = FALSE;
01185     int last_hop = ch->last_hop_;
01186     ARQstate *a = checkState(last_hop);
01187 
01188     // resize buffers
01189     // while (seq + 1 - next >= wndmask_) {
01190     
01191 //      resize_buffers((wndmask_+1)*2);
01192 //  }
01193     
01194     // strip off hdlc hdr
01195     ch->size() -= HDLC_HDR_LEN;
01196     
01197     if (seq > a->maxseen_) {
01198         // the packet is the highest we've seen so far
01199         int i;
01200         for (i = a->maxseen_ + 1; i < seq; i++) {
01201             sendSREJ(p, i);
01202         }
01203 
01204         // we record the packets between the old maximum and
01205         // the new max as being "unseen" i.e. 0 
01206         a->maxseen_ = seq;
01207         
01208         // place pkt in buffer
01209         a->seen_[a->maxseen_ & wndmask_] = p;
01210         
01211         // necessary so this packet isn't confused as being a duplicate
01212         just_marked_as_seen = TRUE;
01213         
01214     }
01215     
01216     if (seq < a->nextpkt_) {
01217         // Duplicate packet case 1: the packet is to the left edge of
01218         // the receive window; therefore we must have seen it
01219         // before
01220         printf("%f\t Received duplicate packet %d\n",Scheduler::instance().clock(),seq);
01221         ack(p);
01222         drop(p);
01223         return;
01224         
01225     }
01226     
01227     int next = a->nextpkt_;
01228     
01229     if (seq >= a->nextpkt_ && seq <= a->maxseen_) {
01230         // next is the left edge of the recv window; maxseen_
01231         // is the right edge; execute this block if there are
01232         // missing packets in the recv window AND if current
01233         // packet falls within those gaps
01234 
01235         if (a->seen_[seq & wndmask_] && !just_marked_as_seen) {
01236         // Duplicate case 2: the segment has already been
01237         // recorded as being received (AND not because we just
01238         // marked it as such)
01239             
01240             printf("%f\t Received duplicate packet %d\n",Scheduler::instance().clock(),seq);
01241             ack(p);
01242             drop(p);
01243             return;
01244             
01245         }
01246 
01247         // record the packet as being seen
01248         a->seen_[seq & wndmask_] = p;
01249 
01250         while ( a->seen_[next & wndmask_] != NULL ) {
01251             // this loop first gets executed if seq==next;
01252             // i.e., this is the next packet in order that
01253             // we've been waiting for.  the loop sets how
01254             // many pkt we can now deliver to the
01255             // application, due to this packet arriving
01256             // (and the prior arrival of any pkts
01257             // immediately to the right)
01258 
01259             Packet* rpkt = a->seen_[next & wndmask_];
01260             a->seen_[next & wndmask_] = 0;
01261             
01262             uptarget_ ? sendUp(rpkt) : drop(rpkt);
01263             
01264             ++next;
01265         }
01266 
01267         // store the new left edge of the window
01268         a->nextpkt_ = next;
01269 
01270         // send ack 
01271         ack(p);
01272     }
01273     
01274 }
01275 
01276 ARQstate *HDLC::newEntry(int next_hop)
01277 {
01278     ARQstate *a = new ARQstate;
01279     
01280     a->nh_ = next_hop;
01281     a->t_seqno_ = 0;
01282     a->seqno_ = 0;
01283     a->maxseq_ = 0;
01284     a->highest_ack_ = -1;
01285     a->recv_seqno_ = -1;
01286     a->nrexmit_ = 0;
01287     a->ntimeouts_ = 0;
01288     a->closed_ = 0;
01289     a->disconnect_ = 0;
01290     a->sentDISC_ = 0;
01291     a->SABME_req_ = 0;
01292     a->sentREJ_ = 0;
01293     a->save_ = NULL;
01294     a->rtx_timer_ = new HdlcTimer(this, a, &HDLC::timeout);
01295     a->reset_timer_ = new HdlcTimer(this, a, &HDLC::reset);
01296         a->delay_timer_ = new HdlcTimer(this, a, &HDLC::delayTimeout);
01297     
01298     a->nextpkt_ = 0;
01299     a->next_ = 0;
01300 
01301     if (selRepeat_) {
01302         
01303         a->seen_ = new Packet*[(HDLC_MWM+1)];
01304         memset(a->seen_, 0, (sizeof(Packet *) * (HDLC_MWM+1)));
01305     }
01306     
01307     return a;
01308     
01309 }
01310 
01311 ARQstate *HDLC::createState(int next_hop)
01312 {
01313     ARQstate *a = list_head_;
01314     
01315     if (list_head_ == 0 ) {
01316     
01317         list_head_ = newEntry(next_hop);
01318         return list_head_;
01319         
01320     } else {
01321         while (a->next_)
01322             a = a->next_;
01323         a->next_ = newEntry(next_hop);
01324         return (a->next_);
01325     }
01326 }
01327 
01328     
01329 
01330 ARQstate *HDLC::checkState(int next_hop)
01331 {
01332     ARQstate *a;
01333 
01334     if (list_head_ == 0)
01335         return 0;
01336     
01337     for(a=list_head_; a != 0; a=a->next_) {
01338         if (a->nh_ == next_hop)
01339             return a;
01340     }
01341         
01342     // no existing state
01343     return 0;
01344 }
01345 
01346 
01347 
01348 void HDLC::removeState(int next_hop)
01349 {
01350     ARQstate *a, *p;
01351     
01352     for(p=0, a=list_head_; a != 0; p=a, a=a->next_) {
01353         if (a->nh_ == next_hop) {
01354             
01355             if (a == list_head_) {
01356                 if (a->next_ == 0)
01357                     list_head_ = 0;
01358                 else
01359                     list_head_ = a->next_;
01360                 
01361                 delete a;
01362                 return;
01363                 
01364 
01365             } else {
01366                 p->next_ = a->next_;
01367                 delete a;
01368                 return;
01369                 
01370             }
01371         }
01372     }
01373     
01374     fprintf(stderr, "HDLC:removeState() couldn't find state\n");
01375 }
01376     

Generated on Tue Mar 6 16:47:50 2007 for ns2 Network Simulator 2.29 by  doxygen 1.4.6