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

udp.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) Xerox Corporation 1997. All rights reserved.
00004  *  
00005  * License is granted to copy, to use, and to make and to use derivative
00006  * works for research and evaluation purposes, provided that Xerox is
00007  * acknowledged in all documentation pertaining to any such copy or derivative
00008  * work. Xerox grants no other licenses expressed or implied. The Xerox trade
00009  * name should not be used in any advertising without its written permission.
00010  *  
00011  * XEROX CORPORATION MAKES NO REPRESENTATIONS CONCERNING EITHER THE
00012  * MERCHANTABILITY OF THIS SOFTWARE OR THE SUITABILITY OF THIS SOFTWARE
00013  * FOR ANY PARTICULAR PURPOSE.  The software is provided "as is" without
00014  * express or implied warranty of any kind.
00015  *  
00016  * These notices must be retained in any copies of any part of this software.
00017  */
00018 
00019 #ifndef lint
00020 static const char rcsid[] =
00021     "@(#) $Header: /nfs/jade/vint/CVSROOT/ns-2/apps/udp.cc,v 1.19 2001/11/16 22:29:59 buchheim Exp $ (Xerox)";
00022 #endif
00023 
00024 #include "udp.h"
00025 #include "rtp.h"
00026 #include "random.h"
00027 #include "address.h"
00028 #include "ip.h"
00029 
00030 
00031 static class UdpAgentClass : public TclClass {
00032 public:
00033         UdpAgentClass() : TclClass("Agent/UDP") {}
00034         TclObject* create(int, const char*const*) {
00035                 return (new UdpAgent());
00036         }
00037 } class_udp_agent;
00038 
00039 UdpAgent::UdpAgent() : Agent(PT_UDP), seqno_(-1)
00040 {
00041         bind("packetSize_", &size_);
00042 }
00043 
00044 UdpAgent::UdpAgent(packet_t type) : Agent(type)
00045 {
00046         bind("packetSize_", &size_);
00047 }
00048 
00049 // put in timestamp and sequence number, even though UDP doesn't usually 
00050 // have one.
00051 void UdpAgent::sendmsg(int nbytes, AppData* data, const char* flags)
00052 {
00053         Packet *p;
00054         int n;
00055 
00056         if (size_)
00057                 n = nbytes / size_;
00058         else
00059                 printf("Error: UDP size = 0\n");
00060 
00061         if (nbytes == -1) {
00062                 printf("Error:  sendmsg() for UDP should not be -1\n");
00063                 return;
00064         }       
00065 
00066         // If they are sending data, then it must fit within a single packet.
00067         if (data && nbytes > size_) {
00068                 printf("Error: data greater than maximum UDP packet size\n");
00069                 return;
00070         }
00071 
00072         double local_time = Scheduler::instance().clock();
00073         while (n-- > 0) {
00074                 p = allocpkt();
00075                 hdr_cmn::access(p)->size() = size_;
00076                 hdr_rtp* rh = hdr_rtp::access(p);
00077                 rh->flags() = 0;
00078                 rh->seqno() = ++seqno_;
00079                 hdr_cmn::access(p)->timestamp() = 
00080                     (u_int32_t)(SAMPLERATE*local_time);
00081                 // add "beginning of talkspurt" labels (tcl/ex/test-rcvr.tcl)
00082                 if (flags && (0 ==strcmp(flags, "NEW_BURST")))
00083                         rh->flags() |= RTP_M;
00084                 p->setdata(data);
00085                 target_->recv(p);
00086         }
00087         n = nbytes % size_;
00088         if (n > 0) {
00089                 p = allocpkt();
00090                 hdr_cmn::access(p)->size() = n;
00091                 hdr_rtp* rh = hdr_rtp::access(p);
00092                 rh->flags() = 0;
00093                 rh->seqno() = ++seqno_;
00094                 hdr_cmn::access(p)->timestamp() = 
00095                     (u_int32_t)(SAMPLERATE*local_time);
00096                 // add "beginning of talkspurt" labels (tcl/ex/test-rcvr.tcl)
00097                 if (flags && (0 == strcmp(flags, "NEW_BURST")))
00098                         rh->flags() |= RTP_M;
00099                 p->setdata(data);
00100                 target_->recv(p);
00101         }
00102         idle();
00103 }
00104 void UdpAgent::recv(Packet* pkt, Handler*)
00105 {
00106         if (app_ ) {
00107                 // If an application is attached, pass the data to the app
00108                 hdr_cmn* h = hdr_cmn::access(pkt);
00109                 app_->process_data(h->size(), pkt->userdata());
00110         } else if (pkt->userdata() && pkt->userdata()->type() == PACKET_DATA) {
00111                 // otherwise if it's just PacketData, pass it to Tcl
00112                 //
00113                 // Note that a Tcl procedure Agent/Udp recv {from data}
00114                 // needs to be defined.  For example,
00115                 //
00116                 // Agent/Udp instproc recv {from data} {puts data}
00117 
00118                 PacketData* data = (PacketData*)pkt->userdata();
00119 
00120                 hdr_ip* iph = hdr_ip::access(pkt);
00121                 Tcl& tcl = Tcl::instance();
00122                 tcl.evalf("%s process_data %d {%s}", name(),
00123                           iph->src_.addr_ >> Address::instance().NodeShift_[1],
00124                           data->data());
00125         }
00126         Packet::free(pkt);
00127 }
00128 
00129 
00130 int UdpAgent::command(int argc, const char*const* argv)
00131 {
00132         if (argc == 4) {
00133                 if (strcmp(argv[1], "send") == 0) {
00134                         PacketData* data = new PacketData(1 + strlen(argv[3]));
00135                         strcpy((char*)data->data(), argv[3]);
00136                         sendmsg(atoi(argv[2]), data);
00137                         return (TCL_OK);
00138                 }
00139         } else if (argc == 5) {
00140                 if (strcmp(argv[1], "sendmsg") == 0) {
00141                         PacketData* data = new PacketData(1 + strlen(argv[3]));
00142                         strcpy((char*)data->data(), argv[3]);
00143                         sendmsg(atoi(argv[2]), data, argv[4]);
00144                         return (TCL_OK);
00145                 }
00146         }
00147         return (Agent::command(argc, argv));
00148 }

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