Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Compound Members | File Members

imep_api.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 Computer Systems
00017  *      Engineering Group at Lawrence Berkeley Laboratory.
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 /* Ported from CMU/Monarch's code*/
00035 
00036 /* 
00037    imep_api.cc
00038    $Id: imep_api.cc,v 1.4 2002/03/21 22:44:38 haldar Exp $
00039    */
00040 
00041 #include <imep/imep.h>
00042 
00043 #define CURRENT_TIME    Scheduler::instance().clock()
00044 
00045 static const int verbose = 0;
00046 
00047 // ======================================================================
00048 // ======================================================================
00049 // The IMEP API
00050 
00051 void
00052 imepAgent::imepRegister(rtAgent *rt)
00053 {
00054         rtagent_ = rt;
00055         assert(rtagent_);
00056 }
00057 
00058 void
00059 imepAgent::imepGetLinkStatus(nsaddr_t index, u_int32_t &status)
00060 {
00061         imepLink *l = findLink(index);
00062 
00063         if(l == 0)
00064           {
00065             status = LINK_DOWN;
00066           }
00067         else
00068           {
00069             status = l->status();
00070           }
00071 }
00072 
00073 void
00074 imepAgent::imepSetLinkInStatus(nsaddr_t index)
00075 {
00076   imepLink *l = findLink(index);
00077 
00078   if(l == 0) 
00079     {
00080       l = new imepLink(index);
00081       LIST_INSERT_HEAD(&imepLinkHead, l, link);
00082       l->status() = LINK_DOWN;
00083     }
00084         
00085   if (LINK_DOWN == l->status()) 
00086     { // the link is an in adjacency
00087       if (verbose) trace("T %.9f _%d_ new link to %d",
00088                          CURRENT_TIME, ipaddr, index);
00089       l->lastSeq() = 0; // expect 1 next  (not needed XXX)
00090       l->lastSeqValid() = 0;
00091       l->out_expire() = -1.0;
00092 
00093       stats.new_in_adjacency++;
00094       // using the imep-spec-01 logic (sec 3.4.2)
00095       // send a hello immeadiately after learning of a new
00096       // adjacency.
00097       sendHello(index);
00098       // the draft sez ``immeadiate'' --- I'll allow the
00099       // time for aggregation.  we could cancel the controlTimer
00100       // here and launch the packet immeadiately if we wanted. -dam
00101     }
00102 
00103   u_int ostatus = l->status();
00104   l->status() |= LINK_IN;
00105   if (ostatus != l->status() && l->status() == LINK_BI)
00106     {
00107       rtagent_->rtNotifyLinkUP(index);
00108       stats.new_neighbor++;
00109     }    
00110 
00111   l->in_expire() = CURRENT_TIME + MAX_BEACON_TIME;
00112 }
00113 
00114 void
00115 imepAgent::imepSetLinkOutStatus(nsaddr_t index)
00116 {
00117         imepLink *l = findLink(index);
00118 
00119         // how could we know that someone hears us w/o us
00120         // first receiving a packet from them (which would create
00121         // in status and create a link record for them)? -dam
00122         assert(l);
00123 
00124         u_int ostatus = l->status();
00125         l->status() |= LINK_OUT;
00126         if (ostatus != l->status() && l->status() == LINK_BI)
00127           {
00128             rtagent_->rtNotifyLinkUP(index);
00129             stats.new_neighbor++;
00130           }
00131 
00132         l->out_expire() = CURRENT_TIME + MAX_BEACON_TIME;
00133 }
00134 
00135 void
00136 imepAgent::imepSetLinkBiStatus(nsaddr_t index)
00137 {
00138   imepSetLinkInStatus(index);
00139   imepSetLinkOutStatus(index);
00140 }
00141 
00142 void
00143 imepAgent::imepSetLinkDownStatus(nsaddr_t index)
00144 {
00145         imepLink *l = findLink(index);
00146 
00147         if(l == 0) {
00148                 return;
00149         }
00150         l->status() = LINK_DOWN;
00151         l->in_expire() = -1.0;
00152         l->out_expire() = -1.0;
00153 
00154         // clear the resequencing queue for the neighbor
00155         incomingQ.deleteDst(index);
00156 
00157         // clean this node off the response list of any packets 
00158         // we're expecting them to ack
00159         purgeReXmitQ(index);
00160 
00161         // tell the routing layer the link is gone
00162         rtagent_->rtNotifyLinkDN(index);
00163 
00164         stats.delete_neighbor1++;
00165 
00166         if (verbose) trace("T %.9f _%d_ down link to %d",
00167                            CURRENT_TIME, ipaddr, index);
00168 }
00169 
00170 void
00171 imepAgent::imepPacketUndeliverable(Packet *p)
00172 {
00173         struct hdr_cmn *cmh = HDR_CMN(p);
00174         struct hdr_ip *ip = HDR_IP(p);
00175 
00176         if (NS_AF_INET == cmh->addr_type())
00177           imepSetLinkDownStatus(cmh->next_hop());
00178 
00179         if (verbose) trace("T %.9f _%d_ undeliverable pkt to %d",
00180                            CURRENT_TIME, ipaddr, ip->daddr());
00181 
00182         rtagent_->rtRoutePacket(p);
00183 }
00184 
00185 void
00186 imepAgent::purgeLink()
00187 {
00188   imepLink *l, *nl;
00189 
00190   for(l = imepLinkHead.lh_first ; l; l = nl) 
00191     { 
00192       nl = l->link.le_next;
00193       
00194       // Is this a bug?  should save old status now, and then
00195       // notify rtagent if ostatus == LINK_BI and new status doesn't
00196       // -dam 8/26/98
00197       // I don't think it's a problem, since any packet that
00198       // sets link_out expire time also sets link_in expire time,
00199       // so a LINK_OUT && !LINK_IN state should never be possible -dam
00200       
00201       int ostatus = l->status();
00202       if (l->in_expire() < CURRENT_TIME) l->status() &= ~LINK_IN;
00203       if (l->out_expire() < CURRENT_TIME) l->status() &= ~LINK_OUT;
00204       if (LINK_BI == ostatus && LINK_BI != l->status())
00205         {
00206           imepSetLinkDownStatus(l->index());
00207         }
00208 
00209       if (LINK_DOWN == l->status())
00210         {
00211           stats.delete_neighbor2++;
00212 
00213           LIST_REMOVE(l, link);
00214           delete l;
00215         }
00216     }
00217 }
00218 
00219 void
00220 imepAgent::imepGetBiLinks(int*& nblist, int& nbcnt)
00221 {
00222         imepLink *l;
00223         int cnt = 0;
00224 
00225         for(l = imepLinkHead.lh_first; l; l = l->link.le_next) {
00226                 if(l->status() == LINK_BI) cnt++;
00227         }
00228         nbcnt = cnt;
00229 
00230         if(cnt == 0) return;
00231         // no neighbors
00232 
00233         nblist = new int[cnt];
00234         cnt = 0;
00235         for(l = imepLinkHead.lh_first; l; l = l->link.le_next) {
00236                 if(l->status() == LINK_BI) {
00237                         nblist[cnt] = l->index();
00238                         cnt++;
00239                 }
00240         }
00241 }

Generated on Tue Apr 20 12:14:20 2004 for NS2.26SourcesOriginal by doxygen 1.3.3