srm.h

Go to the documentation of this file.
00001 /* -*-  Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
00002 
00003 /*
00004  * srm.h
00005  * Copyright (C) 1997 by the University of Southern California
00006  * $Id: srm.h,v 1.22 2005/09/18 23:33:33 tomh Exp $
00007  *
00008  * This program is free software; you can redistribute it and/or
00009  * modify it under the terms of the GNU General Public License,
00010  * version 2, as published by the Free Software Foundation.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License along
00018  * with this program; if not, write to the Free Software Foundation, Inc.,
00019  * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
00020  *
00021  *
00022  * The copyright of this module includes the following
00023  * linking-with-specific-other-licenses addition:
00024  *
00025  * In addition, as a special exception, the copyright holders of
00026  * this module give you permission to combine (via static or
00027  * dynamic linking) this module with free software programs or
00028  * libraries that are released under the GNU LGPL and with code
00029  * included in the standard release of ns-2 under the Apache 2.0
00030  * license or under otherwise-compatible licenses with advertising
00031  * requirements (or modified versions of such code, with unchanged
00032  * license).  You may copy and distribute such a system following the
00033  * terms of the GNU GPL for this module and the licenses of the
00034  * other code concerned, provided that you include the source code of
00035  * that other code when and as the GNU GPL requires distribution of
00036  * source code.
00037  *
00038  * Note that people who make modified versions of this module
00039  * are not obligated to grant this special exception for their
00040  * modified versions; it is their choice whether to do so.  The GNU
00041  * General Public License gives permission to release a modified
00042  * version without this exception; this exception also makes it
00043  * possible to release a modified version which carries forward this
00044  * exception.
00045  *
00046  */
00047 
00048 //
00049 //  Author:     Kannan Varadhan <kannan@isi.edu>
00050 //  Version Date:   Mon Jun 30 15:51:33 PDT 1997
00051 //
00052 // @(#) $Header: /nfs/jade/vint/CVSROOT/ns-2/mcast/srm.h,v 1.22 2005/09/18 23:33:33 tomh Exp $ (USC/ISI)
00053 //
00054 
00055 #ifndef ns_srm_h
00056 #define ns_srm_h
00057 
00058 #include <math.h>
00059 #include <tcl.h>
00060 
00061 #include "config.h"
00062 //#include "heap.h"
00063 #include "srm-state.h"
00064 #include "srm-headers.h"
00065 
00066 class SRMAgent : public Agent {
00067 protected:
00068     int dataCtr_;       /* # of data packets sent */
00069     int sessCtr_;       /* # of session messages sent */
00070     int packetSize_;        /* size of data messages for repr */
00071     SRMinfo* sip_;          /* Table of sender info */
00072     Tcl_HashTable*  siphash_;
00073     int groupSize_;
00074     int seqno_;         /* Seqno for CBR packets */
00075     int app_fid_;
00076     packet_t app_type_;
00077 
00078     virtual void start() {
00079         int new_entry = 0;
00080         long key = addr();
00081 
00082         sip_->sender_   /* is itself */ = addr();
00083         sip_->distance_ /* to itself */ = 0.0;
00084         sip_->next_ = NULL;
00085 
00086         siphash_ = new Tcl_HashTable;
00087         Tcl_InitHashTable(siphash_, TCL_ONE_WORD_KEYS);
00088         Tcl_HashEntry* he = Tcl_CreateHashEntry(siphash_,
00089                             (char*) key,
00090                             &new_entry);
00091         Tcl_SetHashValue(he, (ClientData*)sip_);
00092         groupSize_++;
00093     }
00094     SRMinfo* get_state(int sender) {
00095         assert(siphash_);
00096 
00097         int new_entry = 0;
00098         long key = sender;
00099         Tcl_HashEntry* he = Tcl_CreateHashEntry(siphash_,
00100                             (char*) key,
00101                             &new_entry);
00102         if (new_entry) {
00103             groupSize_++;
00104             SRMinfo* tmp = new SRMinfo(sender);
00105             tmp->next_ = sip_->next_;
00106             sip_->next_ = tmp;
00107             Tcl_SetHashValue(he, (ClientData*)tmp);
00108         }
00109         return (SRMinfo*)Tcl_GetHashValue(he);
00110     }
00111     virtual void cleanup () {
00112         Tcl_DeleteHashTable(siphash_);
00113     }
00114     
00115     virtual void addExtendedHeaders(Packet*) {}
00116     virtual void parseExtendedHeaders(Packet*) {}
00117     virtual int request(SRMinfo* sp, int hi) {
00118         int miss = 0;
00119         if (sp->ldata_ >= hi)
00120             return miss;
00121         
00122         int maxsize = ((int)log10(hi + 1) + 2) * (hi - sp->ldata_);
00123                 // 1 + log10(msgid) bytes for the msgid
00124                 // msgid could be 0, if first pkt is lost.
00125                 // 1 byte per msg separator
00126                 // hi - sp->ldata_ msgs max missing
00127         char* msgids = new char[maxsize + 1];
00128         *msgids = '\0';
00129         for (int i = sp->ldata_ + 1; i <= hi; i++)
00130             if (! sp->ifReceived(i)) {
00131                 (void) sprintf(msgids, "%s %d", msgids, i);
00132                 miss++;
00133             }
00134         assert(miss);
00135         Tcl::instance().evalf("%s request %d %s", name_,
00136                       sp->sender_, msgids);
00137         delete[] msgids;
00138         return miss;
00139     }
00140 
00141     virtual void recv_data(int sender, int msgid, u_char* data);
00142     virtual void recv_repr(int round, int sender, int msgid, u_char* data);
00143     virtual void recv_rqst(int requestr, int round, int sender, int msgid);
00144     virtual void recv_sess(Packet*, int sessCtr, int* data);
00145 
00146     virtual void send_ctrl(int typ, int rnd, int sndr, int msgid, int sz);
00147     virtual void send_sess();
00148 public:
00149     SRMAgent();
00150     virtual ~SRMAgent();
00151     virtual int command(int argc, const char*const* argv);
00152     virtual void recv(Packet* p, Handler* h);
00153         virtual void sendmsg(int nbytes, const char *flags = 0);
00154         virtual void send(int nbytes) { sendmsg(nbytes); }
00155 };
00156 
00157 class ASRMAgent : public SRMAgent {
00158     double pdistance_;
00159     int    requestor_;
00160 public:
00161     ASRMAgent() {
00162         bind("pdistance_", &pdistance_);
00163         bind("requestor_", &requestor_);
00164     }
00165 protected:
00166     virtual void addExtendedHeaders(Packet* p) {
00167         SRMinfo* sp;
00168         hdr_srm* sh = hdr_srm::access(p);
00169         hdr_asrm* seh = hdr_asrm::access(p);
00170         switch (sh->type()) {
00171         case SRM_RQST:
00172             sp = get_state(sh->sender());
00173             seh->distance() = sp->distance_;
00174             break;
00175         case SRM_REPR:
00176             sp = get_state(requestor_);
00177             seh->distance() = sp->distance_;
00178             break;
00179         case SRM_DATA:
00180         case SRM_SESS:
00181             seh->distance() = 0.;
00182             break;
00183         default:
00184             assert(0);
00185             /*NOTREACHED*/
00186         }
00187         SRMAgent::addExtendedHeaders(p);
00188     }
00189     virtual void parseExtendedHeaders(Packet* p) {
00190         SRMAgent::parseExtendedHeaders(p);
00191         hdr_asrm* seh = hdr_asrm::access(p);
00192         pdistance_ = seh->distance();
00193     }
00194 };
00195 
00196 #endif

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