00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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
00050
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
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
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
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
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
00112
00113
00114
00115
00116
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 }