• Main Page
  • Classes
  • Files
  • File List

/Users/yzchen/ns/ns-allinone-2.33/ns-2.33/mcast/srm.h

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: /cvsroot/nsnam/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 Aug 10 2010 16:16:07 for ns-2.33 by  doxygen 1.7.1