summaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorvishal <vishal@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2000-07-21 05:28:31 +0000
committervishal <vishal@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2000-07-21 05:28:31 +0000
commit2831144de324584b17c275fae7e4c94abfb4425e (patch)
tree49a245034afa4364c241dcec73e9a387cc7bf1a0 /examples
parent5910091e4a9197ac9cb7716b249bbbb99ce40a6c (diff)
downloadATCD-2831144de324584b17c275fae7e4c94abfb4425e.tar.gz
*** empty log message ***
Diffstat (limited to 'examples')
-rw-r--r--examples/QOS/Fill_ACE_QoS.cpp116
-rw-r--r--examples/QOS/Fill_ACE_QoS.h77
-rw-r--r--examples/QOS/FlowSpec_Dbase.h52
-rw-r--r--examples/QOS/Makefile48
-rw-r--r--examples/QOS/QoS_Signal_Handler.cpp33
-rw-r--r--examples/QOS/QoS_Signal_Handler.h45
-rw-r--r--examples/QOS/QoS_Util.cpp121
-rw-r--r--examples/QOS/QoS_Util.h74
-rw-r--r--examples/QOS/QosEvent.h195
-rw-r--r--examples/QOS/RAPI_Event_Handler.cpp (renamed from examples/QOS/Sender_QOS_Event_Handler.cpp)101
-rw-r--r--examples/QOS/RAPI_Event_Handler.h59
-rw-r--r--examples/QOS/README97
-rw-r--r--examples/QOS/Receiver_QoS_Event_Handler.cpp (renamed from examples/QOS/Receiver_QOS_Event_Handler.cpp)91
-rw-r--r--examples/QOS/Receiver_QoS_Event_Handler.h (renamed from examples/QOS/Receiver_QOS_Event_Handler.h)38
-rw-r--r--examples/QOS/Sender_QoS_Event_Handler.cpp141
-rw-r--r--examples/QOS/Sender_QoS_Event_Handler.h (renamed from examples/QOS/Sender_QOS_Event_Handler.h)28
-rw-r--r--examples/QOS/client.cpp897
-rw-r--r--examples/QOS/client.dsp13
-rw-r--r--examples/QOS/server.cpp935
-rw-r--r--examples/QOS/server.dsp13
20 files changed, 1477 insertions, 1697 deletions
diff --git a/examples/QOS/Fill_ACE_QoS.cpp b/examples/QOS/Fill_ACE_QoS.cpp
new file mode 100644
index 00000000000..87d893b92bd
--- /dev/null
+++ b/examples/QOS/Fill_ACE_QoS.cpp
@@ -0,0 +1,116 @@
+// Fill_ACE_QoS.cpp
+// $Id$
+
+#include "Fill_ACE_QoS.h"
+
+ACE_RCSID(QOS, Fill_ACE_QoS,"$Id$")
+
+const iovec Fill_ACE_QoS::iov_ = {0,0};
+
+Fill_ACE_QoS::Fill_ACE_QoS (void)
+{
+ ACE_NEW (this->default_traffic_,
+ ACE_Flow_Spec (ACE_QOS_NOT_SPECIFIED,
+ ACE_QOS_NOT_SPECIFIED,
+ ACE_QOS_NOT_SPECIFIED,
+ ACE_QOS_NOT_SPECIFIED,
+ ACE_QOS_NOT_SPECIFIED,
+ ACE_SERVICETYPE_NOTRAFFIC,
+ ACE_QOS_NOT_SPECIFIED,
+ ACE_QOS_NOT_SPECIFIED,
+ 25,
+ 1));
+}
+
+// destructor.
+Fill_ACE_QoS::~Fill_ACE_QoS (void)
+{}
+
+int
+Fill_ACE_QoS::fill_simplex_receiver_qos (ACE_QoS &ace_qos,
+ const ACE_CString &recv_flow_name)
+{
+ ACE_Flow_Spec *recv_flow_spec = new ACE_Flow_Spec ();
+
+ if (this->map ().find (recv_flow_name, recv_flow_spec) != 0)
+ ACE_ERROR_RETURN ((LM_DEBUG,
+ "Unable to find a FlowSpec with name %s",
+ recv_flow_name.c_str ()),
+ -1);
+ ace_qos.receiving_flowspec (*recv_flow_spec);
+ ace_qos.sending_flowspec (*(this->default_traffic_));
+ ace_qos.provider_specific (Fill_ACE_QoS::iov_);
+
+ return 0;
+}
+
+
+int
+Fill_ACE_QoS::fill_simplex_sender_qos (ACE_QoS &ace_qos,
+ const ACE_CString &send_flow_name)
+{
+ ACE_Flow_Spec *send_flow_spec = 0;
+
+ if (this->map ().find (send_flow_name, send_flow_spec) != 0)
+ ACE_ERROR_RETURN ((LM_DEBUG,
+ "Unable to find a FlowSpec with name %s",
+ send_flow_name.c_str ()),
+ -1);
+
+ ace_qos.receiving_flowspec (*(this->default_traffic_));
+ ace_qos.sending_flowspec (*send_flow_spec);
+ ace_qos.provider_specific (Fill_ACE_QoS::iov_);
+
+ return 0;
+}
+
+int
+Fill_ACE_QoS::fill_duplex_qos (ACE_QoS &ace_qos,
+ const ACE_CString &recv_flow_name,
+ const ACE_CString &send_flow_name)
+{
+ ACE_Flow_Spec *send_flow_spec = 0;
+ ACE_Flow_Spec *recv_flow_spec = 0;
+
+ if (this->map ().find (recv_flow_name, recv_flow_spec) != 0)
+ ACE_ERROR_RETURN ((LM_DEBUG,
+ "Unable to find a FlowSpec with name %s",
+ recv_flow_name.c_str ()),
+ -1);
+
+ if (this->map ().find (send_flow_name, send_flow_spec) != 0)
+ ACE_ERROR_RETURN ((LM_DEBUG,
+ "Unable to find a FlowSpec with name %s",
+ send_flow_name.c_str ()),
+ -1);
+
+ ace_qos.receiving_flowspec (*recv_flow_spec);
+ ace_qos.sending_flowspec (*send_flow_spec);
+ ace_qos.provider_specific (Fill_ACE_QoS::iov_);
+
+ return 0;
+}
+
+Fill_ACE_QoS::FLOW_SPEC_HASH_MAP
+Fill_ACE_QoS::map (void)
+{
+ return this->flow_spec_map_;
+}
+
+#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
+template class ACE_Hash_Map_Manager<ACE_CString,ACE_Flow_Spec *,ACE_Null_Mutex>;
+template class ACE_Hash_Map_Manager_Ex<ACE_CString, ACE_Flow_Spec *, ACE_Hash<ACE_CString>, ACE_Equal_To<ACE_CString>, ACE_Null_Mutex>;
+template class ACE_Hash_Map_Iterator_Base_Ex<ACE_CString, ACE_Flow_Spec *, ACE_Hash<ACE_CString>, ACE_Equal_To<ACE_CString>, ACE_Null_Mutex>;
+template class ACE_Hash_Map_Entry<ACE_CString, ACE_Flow_Spec *>;
+template class ACE_Hash_Map_Manager_Ex<ACE_CString, ACE_Flow_Spec *, ACE_Hash<ACE_CString>, ACE_Equal_To<ACE_CString>, ACE_Thread_Mutex>;
+template class ACE_Hash_Map_Iterator_Base_Ex<ACE_CString, ACE_Flow_Spec *, ACE_Hash<ACE_CString>, ACE_Equal_To<ACE_CString>, ACE_Thread_Mutex>;
+#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
+#pragma instantiate ACE_Hash_Map_Manager<ACE_CString,ACE_Flow_Spec *,ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Manager_Ex<ACE_CString, ACE_Flow_Spec *, ACE_Hash<ACE_CString>, ACE_Equal_To<ACE_CString>, ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Iterator_Base_Ex<ACE_CString, ACE_Flow_Spec *, ACE_Hash<ACE_CString>, ACE_Equal_To<ACE_CString>, ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Entry<ACE_CString, ACE_Flow_Spec *>
+#pragma instantiate ACE_Hash_Map_Manager_Ex<ACE_CString, ACE_Flow_Spec *, ACE_Hash<ACE_CString>, ACE_Equal_To<ACE_CString>, ACE_Thread_Mutex>
+#pragma instantiate ACE_Hash_Map_Iterator_Base_Ex<ACE_CString, ACE_Flow_Spec *, ACE_Hash<ACE_CString>, ACE_Equal_To<ACE_CString>, ACE_Thread_Mutex>
+#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */
+
+
diff --git a/examples/QOS/Fill_ACE_QoS.h b/examples/QOS/Fill_ACE_QoS.h
new file mode 100644
index 00000000000..3dd92f548e4
--- /dev/null
+++ b/examples/QOS/Fill_ACE_QoS.h
@@ -0,0 +1,77 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// ACE_wrappers/examples/QOS
+//
+// = FILENAME
+// Fill_ACE_QoS.h
+//
+// = AUTHOR
+// Vishal Kachroo <vishal@cs.wustl.edu>
+//
+// ============================================================================
+
+#ifndef FILL_ACE_QOS_H
+#define FILL_ACE_QOS_H
+
+#include "ace/SString.h"
+#include "ace/Hash_Map_Manager.h"
+#include "ace/Synch.h"
+#include "ace/ACE.h"
+#include "ace/OS.h"
+
+class Fill_ACE_QoS
+{
+ // TITLE
+ // This class helps users to add new flow specs and provides
+ // utility functions for filling up the flow specs for simplex/duplex
+ // sessions.
+
+public:
+ typedef ACE_Hash_Map_Manager <ACE_CString, ACE_Flow_Spec *, ACE_Null_Mutex> FLOW_SPEC_HASH_MAP;
+
+ //Initialization and termination methods.
+ Fill_ACE_QoS (void);
+ // constructor.
+
+ ~Fill_ACE_QoS (void);
+ // destructor.
+
+ int fill_simplex_receiver_qos (ACE_QoS &ace_qos,
+ const ACE_CString &recv_flow_name);
+ // To be used by receivers. Fills the receiver qos and sets the
+ // sender qos to NO_TRAFFIC.
+
+ int fill_simplex_sender_qos (ACE_QoS &ace_qos,
+ const ACE_CString &send_flow_name);
+ // To be used by senders. Fills the sender qos and sets the receiver
+ // qos to NO_TRAFFIC.
+
+ int fill_duplex_qos (ACE_QoS &ace_qos,
+ const ACE_CString &recv_flow_name,
+ const ACE_CString &send_flow_name);
+ // To be used by applications that wish to be both receivers and
+ // senders.
+
+ FLOW_SPEC_HASH_MAP map (void);
+ // Returns the hash map of flowspecs indexed by flowspec name.
+
+private:
+
+ // The Service Provider is currently set to NULL for all ACE_QoS.
+ static const iovec iov_;
+
+ // A NO_TRAFFIC flow spec. Senders set the receiving qos to this
+ // while the receivers set the sending qos to this.
+ ACE_Flow_Spec *default_traffic_;
+
+ // A list of flowspecs indexed by the flowspec name.
+ FLOW_SPEC_HASH_MAP flow_spec_map_;
+
+
+};
+
+#endif /* FILL_ACE_QOS_H */
diff --git a/examples/QOS/FlowSpec_Dbase.h b/examples/QOS/FlowSpec_Dbase.h
new file mode 100644
index 00000000000..fc382048c13
--- /dev/null
+++ b/examples/QOS/FlowSpec_Dbase.h
@@ -0,0 +1,52 @@
+/* -*- C++ -*- */
+//$Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// ACE_wrappers/examples/QOS
+//
+// = FILENAME
+// FlowSpec_Dbase.h
+//
+// = AUTHOR
+// Vishal Kachroo <vishal@cs.wustl.edu>
+//
+// ============================================================================
+
+#ifndef FLOWSPEC_DBASE_H
+#define FLOWSPEC_DBASE_H
+
+// This file contains the different FlowSpecs that the QoS enabled
+// application uses. Its a good idea to list them all here so the
+// application code is clean.
+
+ACE_Flow_Spec notraffic (ACE_QOS_NOT_SPECIFIED,
+ ACE_QOS_NOT_SPECIFIED,
+ ACE_QOS_NOT_SPECIFIED,
+ ACE_QOS_NOT_SPECIFIED,
+ ACE_QOS_NOT_SPECIFIED,
+ ACE_SERVICETYPE_NOTRAFFIC,
+ ACE_QOS_NOT_SPECIFIED,
+ ACE_QOS_NOT_SPECIFIED,
+ 25,
+ 1);
+
+ACE_Flow_Spec g711 (9200,
+ 708,
+ 18400,
+ 0,
+ 0,
+ ACE_SERVICETYPE_CONTROLLEDLOAD,
+ 368,
+ 368,
+ 25,
+ 1);
+
+// The default session address is macarena.cs.wustl.edu. I am using macarena
+// as my receiver for testing.
+#define DEFAULT_QOS_SESSION_MACHINE "128.252.165.127"
+#define DEFAULT_QOS_SESSION_PORT 8001
+
+#endif /* FLOWSPEC_DBASE_H */
+
diff --git a/examples/QOS/Makefile b/examples/QOS/Makefile
index e7e8d34f25a..c358b212620 100644
--- a/examples/QOS/Makefile
+++ b/examples/QOS/Makefile
@@ -10,12 +10,18 @@
#----------------------------------------------------------------------------
SIMPLE_CLT_OBJS = \
+ QoS_Signal_Handler.o \
+ QoS_Util.o \
+ Fill_ACE_QoS.o \
client.o \
- Sender_QOS_Event_Handler.o
+ Sender_QoS_Event_Handler.o
SIMPLE_SVR_OBJS = \
+ QoS_Signal_Handler.o \
+ QoS_Util.o \
+ Fill_ACE_QoS.o \
server.o \
- Receiver_QOS_Event_Handler.o
+ Receiver_QoS_Event_Handler.o
BUILD = $(VBIN)
@@ -51,6 +57,42 @@ client: $(addprefix $(VDIR),$(SIMPLE_CLT_OBJS))
# DO NOT DELETE THIS LINE -- g++dep uses it.
# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
-
+.obj/Log_Wrapper.o .obj/Log_Wrapper.so .shobj/Log_Wrapper.o .shobj/Log_Wrapper.so: Log_Wrapper.cpp Log_Wrapper.h \
+ $(ACE_ROOT)/ace/Profile_Timer.h \
+ $(ACE_ROOT)/ace/ACE.h \
+ $(ACE_ROOT)/ace/OS.h \
+ $(ACE_ROOT)/ace/inc_user_config.h \
+ $(ACE_ROOT)/ace/config.h \
+ $(ACE_ROOT)/ace/config-sunos5.5.h \
+ $(ACE_ROOT)/ace/config-g++-common.h \
+ $(ACE_ROOT)/ace/streams.h \
+ $(ACE_ROOT)/ace/Basic_Types.h \
+ $(ACE_ROOT)/ace/Basic_Types.i \
+ $(ACE_ROOT)/ace/OS.i \
+ $(ACE_ROOT)/ace/Trace.h \
+ $(ACE_ROOT)/ace/Log_Msg.h \
+ $(ACE_ROOT)/ace/Log_Record.h \
+ $(ACE_ROOT)/ace/ACE.i \
+ $(ACE_ROOT)/ace/Log_Priority.h \
+ $(ACE_ROOT)/ace/SString.h \
+ $(ACE_ROOT)/ace/SString.i \
+ $(ACE_ROOT)/ace/Malloc_Base.h \
+ $(ACE_ROOT)/ace/Log_Record.i \
+ $(ACE_ROOT)/ace/Time_Value.h \
+ $(ACE_ROOT)/ace/High_Res_Timer.h \
+ $(ACE_ROOT)/ace/High_Res_Timer.i \
+ $(ACE_ROOT)/ace/Profile_Timer.i \
+ $(ACE_ROOT)/ace/INET_Addr.h \
+ $(ACE_ROOT)/ace/Addr.h \
+ $(ACE_ROOT)/ace/Addr.i \
+ $(ACE_ROOT)/ace/INET_Addr.i \
+ $(ACE_ROOT)/ace/SOCK_Dgram_Mcast.h \
+ $(ACE_ROOT)/ace/SOCK_Dgram.h \
+ $(ACE_ROOT)/ace/SOCK.h \
+ $(ACE_ROOT)/ace/IPC_SAP.h \
+ $(ACE_ROOT)/ace/IPC_SAP.i \
+ $(ACE_ROOT)/ace/SOCK.i \
+ $(ACE_ROOT)/ace/SOCK_Dgram.i \
+ $(ACE_ROOT)/ace/SOCK_Dgram_Mcast.i
# IF YOU PUT ANYTHING HERE IT WILL GO AWAY
diff --git a/examples/QOS/QoS_Signal_Handler.cpp b/examples/QOS/QoS_Signal_Handler.cpp
new file mode 100644
index 00000000000..706b122978b
--- /dev/null
+++ b/examples/QOS/QoS_Signal_Handler.cpp
@@ -0,0 +1,33 @@
+// QoS_Signal_Handler.cpp
+// $Id$
+
+#include "QoS_Signal_Handler.h"
+
+ACE_RCSID(QOS, QoS_Signal_Handler,"$Id$")
+
+// constructor.
+QoS_Signal_Handler::QoS_Signal_Handler (ACE_QoS_Session *qos_session)
+ : qos_session_ (qos_session)
+{
+}
+
+// Releases the QoS sessions gracefully.
+int
+QoS_Signal_Handler::handle_signal (int signum, siginfo_t *, ucontext_t*)
+{
+ if (signum == SIGINT)
+ {
+ if (this->qos_session_->close () == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Unable to close the QoS session.\n"),
+ -1);
+ else
+ ACE_DEBUG ((LM_DEBUG,
+ "QoS Session with id %d closed successfully.\n",
+ this->qos_session_->session_id ()));
+ }
+ else
+ ACE_DEBUG ((LM_DEBUG,
+ "A signal other than SIGINT received.\nIgnoring.\n"));
+ return 0;
+}
diff --git a/examples/QOS/QoS_Signal_Handler.h b/examples/QOS/QoS_Signal_Handler.h
new file mode 100644
index 00000000000..9e776e36b42
--- /dev/null
+++ b/examples/QOS/QoS_Signal_Handler.h
@@ -0,0 +1,45 @@
+/* -*- C++ -*- */
+// $Id$
+
+// =====================================================================
+//
+// = LIBRARY
+// ACE_wrappers/examples/QOS
+//
+// = FILENAME
+// QoS_Signal_Handler.h
+//
+// = AUTHOR
+// Vishal Kachroo <vishal@cs.wustl.edu>
+//
+// =====================================================================
+
+#ifndef QOS_SIGNAL_HANDLER_H
+#define QOS_SIGNAL_HANDLER_H
+
+#include "ace/Event_Handler.h"
+#include "ace/QoS_Session.h"
+
+class QoS_Signal_Handler : public ACE_Event_Handler
+{
+ // TITLE
+ // This class Handles the SIGINT signal through the Reactor.
+ // Useful to gracefully release QoS sessions.
+
+public:
+
+ QoS_Signal_Handler (ACE_QoS_Session *qos_session);
+ // constructor.
+
+ int handle_signal(int signum, siginfo_t*,ucontext_t*);
+ // Override this method to implement graceful shutdown.
+
+private:
+
+ ACE_QoS_Session *qos_session_;
+ // Session to be gracefully shutdown.
+
+};
+
+#endif /* QOS_SIGNAL_HANDLER_H */
+
diff --git a/examples/QOS/QoS_Util.cpp b/examples/QOS/QoS_Util.cpp
new file mode 100644
index 00000000000..303ebad078a
--- /dev/null
+++ b/examples/QOS/QoS_Util.cpp
@@ -0,0 +1,121 @@
+// QoS_Session_Impl.cpp
+// $Id$
+
+#define SENDER_PORT 10001
+
+#include "ace/Get_Opt.h"
+#include "QoS_Util.h"
+
+ACE_RCSID(QOS, QoS_Util,"$Id$")
+
+// constructor.
+QoS_Util::QoS_Util (int argc,
+ char *argv[])
+ : argc_ (argc),
+ argv_ (argv),
+ protocol_ (IPPROTO_UDP),
+ multicast_flag_ (0),
+ source_port_ (SENDER_PORT)
+{
+ ACE_NEW (this->mult_session_addr_,
+ ACE_INET_Addr (ACE_DEFAULT_MULTICAST_PORT));
+
+ ACE_NEW (this->dest_addr_,
+ ACE_INET_Addr (ACE_DEFAULT_SERVER_PORT));
+}
+
+// destructor.
+QoS_Util::~QoS_Util (void)
+{
+ delete this->mult_session_addr_;
+ delete this->dest_addr_;
+}
+
+int
+QoS_Util::parse_args (void)
+{
+ ACE_Get_Opt get_opts (this->argc_, this->argv_, "m:n:p:P:");
+ int c = 0;
+
+ while ((c = get_opts ()) != -1)
+ switch (c)
+ {
+ case 'm': // multicast session address.
+ this->multicast_flag_ = 1;
+ this->mult_session_addr_->set (get_opts.optarg);
+ break;
+ case 'n': // to be used by Senders only to specify the destination.
+ this->dest_addr_->set (get_opts.optarg);
+ break;
+ case 'p': // protocol.
+ if (ACE_OS::strcasecmp (get_opts.optarg, "tcp") == 0)
+ this->protocol_ = IPPROTO_TCP;
+ else
+ if (ACE_OS::strcasecmp (get_opts.optarg, "udp") == 0)
+ this->protocol_ = IPPROTO_UDP;
+ else
+ ACE_DEBUG ((LM_DEBUG,
+ "Unknown protocol specified\n"
+ "UDP assumed\n"));
+ break;
+ case 'P': // sender source port.
+ this->source_port_ = ACE_OS::atoi (get_opts.optarg);
+ break;
+ case 'h': // display help for different options.
+ default:
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "usage: %s"
+ " [-m host:port] QoS multicast session address"
+ " Overides the receiver address specified in the -n option"
+ " [-n host:port] Use for a unicast sender. "
+ " Follow by receiver addr"
+ " [-p tcp|udp] specify protocol to be used"
+ " [-P port] source sender port"
+ " [-h] <help>"
+ "\n",
+ argv_ [0]),
+ -1);
+ }
+
+ // If multicast address is specified then ignore the unicast sender
+ // destination address and force the protocol to be UDP.
+ if (this->multicast_flag_ == 1)
+ {
+ this->dest_addr_ = this->mult_session_addr_;
+ this->protocol_ = IPPROTO_UDP;
+ }
+
+ // Indicates successful parsing of command line.
+ return 0;
+}
+
+ACE_INET_Addr *
+QoS_Util::mult_session_addr (void) const
+{
+ return this->mult_session_addr_;
+}
+
+ACE_INET_Addr *
+QoS_Util::dest_addr (void) const
+{
+ return this->dest_addr_;
+}
+
+u_short
+QoS_Util::source_port (void) const
+{
+ return this->source_port_;
+}
+
+ACE_Protocol_ID
+QoS_Util::protocol (void) const
+{
+ return this->protocol_;
+}
+
+int
+QoS_Util::multicast_flag (void) const
+{
+ return this->multicast_flag_;
+}
+
diff --git a/examples/QOS/QoS_Util.h b/examples/QOS/QoS_Util.h
new file mode 100644
index 00000000000..66ac8b1392e
--- /dev/null
+++ b/examples/QOS/QoS_Util.h
@@ -0,0 +1,74 @@
+/* -*- C++ -*- */
+// $Id$
+
+// =====================================================================
+//
+// = LIBRARY
+// ACE_wrappers/examples/QOS
+//
+// = FILENAME
+// QoS_Util.h
+//
+// = AUTHOR
+// Vishal Kachroo <vishal@cs.wustl.edu>
+//
+// =====================================================================
+
+#ifndef QOS_UTIL_H
+#define QOS_UTIL_H
+
+#include "ace/INET_Addr.h"
+#include "ace/QoS_Session.h"
+
+class QoS_Util
+{
+ // = TITLE
+ // This class provides the utility functions like parse_args ()
+ // required by a QoS enabled application.
+
+public:
+
+ // constructor.
+ QoS_Util (int argc, char *argv[]);
+
+ // destructor.
+ ~QoS_Util (void);
+
+ // Parse command-line arguments.
+ int parse_args (void);
+
+ // GET methods.
+ ACE_INET_Addr *mult_session_addr (void) const;
+
+ ACE_INET_Addr *dest_addr (void) const;
+
+ u_short source_port (void) const;
+
+ ACE_Protocol_ID protocol (void) const;
+
+ int multicast_flag (void) const;
+
+private:
+
+ // Command line arguments.
+ int argc_;
+ char **argv_;
+
+ // Multicast session address.
+ ACE_INET_Addr *mult_session_addr_;
+
+ // Unicast destination address of the receiver.
+ ACE_INET_Addr *dest_addr_;
+
+ // Source port for the sender.
+ u_short source_port_;
+
+ // Protocol.
+ ACE_Protocol_ID protocol_;
+
+ // Multicast Flag.
+ int multicast_flag_;
+};
+
+#endif /* QOS_UTIL_H */
+
diff --git a/examples/QOS/QosEvent.h b/examples/QOS/QosEvent.h
deleted file mode 100644
index a80a422fe6e..00000000000
--- a/examples/QOS/QosEvent.h
+++ /dev/null
@@ -1,195 +0,0 @@
-/* -*- C++ -*- */
-//$Id$
-
-// ============================================================================
-//
-// = LIBRARY
-// ACE_wrappers/examples/QOS
-//
-// = FILENAME
-// QosEvent.h
-//
-// = AUTHOR
-// Vishal Kachroo <vishal@cs.wustl.edu>
-//
-// ============================================================================
-
-#ifndef QOSEVENT_H
-#define QOSEVENT_H
-
-
-#define TRUE 1
-#define FALSE 0
-
-#define MY_DEFPORT 5001
-
-#if defined (ACE_HAS_WINSOCK2_GQOS)
-#else
-#define QOS_NOT_SPECIFIED 0
-#endif
-
-#define SERVICETYPE_NOTRAFFIC 0x00000000 // No data in this direction.
-#define SERVICETYPE_CONTROLLEDLOAD 0x00000002 // Controlled Load.
-#define SERVICETYPE_GUARANTEED 0x00000003 // Guaranteed.
-
-// Application-specific define - there is NO specific invalid send
-// priority. This value is simply used to indicate whether or not to
-// even set priority.
-#define INVALID_SEND_PRIORITY 255
-
-// Application-specific define - there is no "default" QOS template in
-// GQoS, only for this particular application does "default" have
-// meaning.
-#define QOS_DEFAULTNAME "default"
-
-// Use an arbitrary multicast group if none is specified on the
-// command line
-#define DEFAULT_MULTICASTGROUP "234.5.6.7"
-
-typedef struct _SP_OPTIONS
-{
- int iProtocol;
- // protocol to use
-
- int bQos;
- // enable QOS
-
- int bMulticast;
- // enable multicasting
-} SP_OPTIONS;
-
-typedef enum
-{
- QOS_IOCTL_SET_DURING,
- // do not use ioctl to set Qos
-
- QOS_IOCTL_SET_BEFORE,
- // set qos with ioctl before connection/accept
-
- QOS_IOCTL_SET_AFTER,
- // set qos with ioctl after connection/accept
-
- QOS_IOCTL_SET_QOS
- // set qos in receiver during FD_QOS, note that qos must be set
- // prior to wsaeventselect in order to ever receive fd_qos
-} QOS_IOCTL_SET;
-
-
-typedef struct _QOS_OPTIONS
-{
- int bReceiver;
- // act as receiver if TRUE
-
- int bWaitToSend;
- // sender must wait for RESV before sending
-
- int bConfirmResv;
- // have receiver request RESV confirmation
-
- int bQueryBufferSize;
- // have WSAioctl return size of buffer needed when using SIO_GET_QOS
- // (behaviour not avail on Win98).
-
- int bMustSetQosInAccept;
- // Will be set for Win98 only. Win98 currently needs valid qos
- // structure to be set in wsaaccept condition func in lpSQos is
- // valid
-
- int bDisableSignalling;
- // If TRUE do not emit RSVP signalling, just use traffic control
-
- int bAlternateQos;
- // Alternate between enabling and disabling QOS on a socket every N
- // sends
-
- u_int SendPriority;
- // create QOS_OBJECT_PRIORITY structure, and set valid priority 0-7
-
- int bSetDestaddr;
- // TRUE if unconnected UDP and QOS is used (not multicast)
-
- int bProviderSpecific;
- // TRUE if a provider-specific object must be set
-
- int bFineGrainErrorAvail;
- // TRUE if Win2000beta3 availability of fine grain errors on SIO_SET_QOS
-
- int bQosabilityIoctls;
- // TRUE if Win2000beta3 qosablity ioctls
-
- int bFixTemplate;
- // TRUE if Win98 to divide ToeknRate and PeakBandwidth by 8 when
- // using WSAGetQOSByName
-
- QOS_IOCTL_SET qosIoctlSet;
- // when to set QOS
-
- char szTemplate[64];
- // qos template
-} QOS_OPTIONS;
-
-extern ACE_Flow_Spec default_notraffic;
-extern ACE_Flow_Spec default_g711;
-
-typedef struct _OPTIONS
-{
- char szHostname[64];
- u_short port;
- int nRepeat;
- char fillchar;
- int nBufSize;
- char *buf;
- u_long dwSleep;
- u_long dwTotalClients;
- QOS_OPTIONS qosOptions;
- SP_OPTIONS spOptions;
-} OPTIONS;
-
-#ifdef QOSEVENT_MAIN
-
-OPTIONS default_options =
-{
- "localhost",
- MY_DEFPORT,
- 1,
- 'c',
- 4096,
- NULL,
- 0,
- 0,
- {TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, INVALID_SEND_PRIORITY,
- TRUE, TRUE, TRUE, TRUE, FALSE, QOS_IOCTL_SET_BEFORE, QOS_DEFAULTNAME},
- {IPPROTO_TCP, FALSE, FALSE}
-};
-
-ACE_Flow_Spec default_notraffic (ACE_QOS_NOT_SPECIFIED,
- ACE_QOS_NOT_SPECIFIED,
- ACE_QOS_NOT_SPECIFIED,
- ACE_QOS_NOT_SPECIFIED,
- ACE_QOS_NOT_SPECIFIED,
- ACE_SERVICETYPE_NOTRAFFIC,
- ACE_QOS_NOT_SPECIFIED,
- ACE_QOS_NOT_SPECIFIED,
- 25,
- 1);
-
-ACE_Flow_Spec default_g711 (9200,
- 708,
- 18400,
- 0,
- 0,
- ACE_SERVICETYPE_CONTROLLEDLOAD,
- 368,
- 368,
- 25,
- 1);
-#else
-extern FLOWSPEC default_notraffic;
-extern FLOWSPEC default_g711;
-extern SOCKADDR_IN g_destaddr;
-#endif /* QOSEVENT_MAIN */
-extern int FindServiceProvider (int iProtocol,
- int bQos,
- int bMulticast,
- ACE_Protocol_Info *pProtocolInfo);
-#endif /* QOSEVENT_H */
diff --git a/examples/QOS/Sender_QOS_Event_Handler.cpp b/examples/QOS/RAPI_Event_Handler.cpp
index 96b10590769..072bda10cc6 100644
--- a/examples/QOS/Sender_QOS_Event_Handler.cpp
+++ b/examples/QOS/RAPI_Event_Handler.cpp
@@ -7,28 +7,29 @@
// ACE_wrappers/examples/QOS
//
// = FILENAME
-// Sender_QOS_Event_Handler.cpp
+// RAPI_Event_Handler.cpp
//
// = AUTHOR
// Vishal Kachroo <vishal@cs.wustl.edu>
//
// ============================================================================
-#include "Sender_QOS_Event_Handler.h"
+#include "RAPI_Event_Handler.h"
// Constructor.
-ACE_QOS_Event_Handler::ACE_QOS_Event_Handler (void)
+ACE_RAPI_Event_Handler::ACE_RAPI_Event_Handler (void)
{
}
// Constructor.
-ACE_QOS_Event_Handler::ACE_QOS_Event_Handler (const ACE_SOCK_Dgram_Mcast_QoS &dgram_mcast)
- : dgram_mcast_ (dgram_mcast)
+ACE_RAPI_Event_Handler::ACE_RAPI_Event_Handler (ACE_QoS_Session *qos_session)
+ : qos_session_ (qos_session)
{
+
}
// Destructor.
-ACE_QOS_Event_Handler::~ACE_QOS_Event_Handler (void)
+ACE_RAPI_Event_Handler::~ACE_RAPI_Event_Handler (void)
{
}
@@ -36,38 +37,53 @@ ACE_QOS_Event_Handler::~ACE_QOS_Event_Handler (void)
// internally by the reactor.
ACE_HANDLE
-ACE_QOS_Event_Handler::get_handle (void) const
+ACE_RAPI_Event_Handler::get_handle (void) const
{
- return this->dgram_mcast_.get_handle ();
+ ACE_DEBUG ((LM_DEBUG,
+ "\nInside get_handle : returning %d\n",
+ this->qos_session_->rsvp_events_handle ()));
+
+ return this->qos_session_->rsvp_events_handle ();
}
-// Handle the QoS Event. In this case send data to the receiver
-// using WSASendTo() that uses overlapped I/O.
+int
+ACE_RAPI_Event_Handler::handle_qos (ACE_HANDLE)
+{
+
+ ACE_DEBUG ((LM_DEBUG,
+ "Inside handle_qos ()\n"));
+
+ return 0;
+
+}
int
-ACE_QOS_Event_Handler::handle_qos (ACE_HANDLE)
+ACE_RAPI_Event_Handler::handle_input (ACE_HANDLE)
{
ACE_DEBUG ((LM_DEBUG,
- "\nReceived a QOS event. Inside handle_qos ()\n"));
-
- ACE_QoS ace_get_qos;
- u_long dwBytes;
-
- if (ACE_OS::ioctl (this->dgram_mcast_.get_handle (),
- ACE_SIO_GET_QOS,
- ace_get_qos,
- &dwBytes) == -1)
- ACE_ERROR ((LM_ERROR,
- "Error in Qos get ACE_OS::ioctl ()\n"
- "Bytes Returned = %d\n",
- dwBytes));
+ "\nReceived a RAPI event. Inside handle_input ()\n"));
+
+ // We have received an RSVP event. The following update_qos () call
+ // calls rapi_dispatch () in case of RAPI and WSAIoctl (GET_QOS) in
+ // case of W2K. It then does the QoS parameter translation and updates
+ // the QoS session object with the latest QoS. This call replaces the
+ // direct call that was being made to WSAIoctl (GET_QOS) here for the
+ // Win2K example.
+
+ if (this->qos_session_->update_qos () == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Error in updating QoS\n"),
+ -1);
else
ACE_DEBUG ((LM_DEBUG,
- "Getting QOS using ACE_OS::ioctl () succeeds.\n"));
+ " Updating QOS succeeds.\n"));
+
+ // Now proactively query the QoS object for QoS.
+ ACE_QoS ace_get_qos = this->qos_session_->qos ();
ACE_DEBUG ((LM_DEBUG,
"\nReceiving Flowspec :\t\t\tSending Flowspec :\n\n"
- "\tToken Rate = %d\t\t\t\tToken Rate = %d\n"
+ "\tToken Rate = %d\t\t\tToken Rate = %d\n"
"\tToken Bucket Size = %d\t\t\tToken Bucket Size = %d\n"
"\tPeak Bandwidth = %d\t\t\tPeak Bandwidth = %d\n"
"\tLatency = %d\t\t\t\tLatency = %d\n"
@@ -92,37 +108,8 @@ ACE_QOS_Event_Handler::handle_qos (ACE_HANDLE)
ace_get_qos.receiving_flowspec ().minimum_policed_size (),
ace_get_qos.sending_flowspec ().minimum_policed_size ()));
-
- ACE_OVERLAPPED ace_overlapped;
-
- iovec iov;
- iov.iov_base = (char *) "Hello";
- iov.iov_len = 5;
-
- // For some really weird reason if I do not define the following
- // sockaddr_in, the <send> call fails.
-
- sockaddr_in s;
- ACE_UNUSED_ARG (s);
-
- ACE_INET_Addr send_to_addr (MY_DEFPORT,
- DEFAULT_MULTICASTGROUP);
- size_t bytes_sent;
-
- if (this->dgram_mcast_.send (&iov,
- 1,
- bytes_sent,
- 0,
- send_to_addr,
- &ace_overlapped,
- NULL) != 0)
- ACE_ERROR_RETURN ((LM_ERROR,
- "Error in dgram_mcast.send ()\n"),
- -1);
- else
- ACE_DEBUG ((LM_DEBUG,
- "Using ACE_OS::sendto () : Bytes sent : %d",
- bytes_sent));
return 0;
+
}
+
diff --git a/examples/QOS/RAPI_Event_Handler.h b/examples/QOS/RAPI_Event_Handler.h
new file mode 100644
index 00000000000..bfea6726753
--- /dev/null
+++ b/examples/QOS/RAPI_Event_Handler.h
@@ -0,0 +1,59 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// ACE_wrappers/examples/QOS
+//
+// = FILENAME
+// RAPI_Event_Handler.h
+//
+// = AUTHOR
+// Vishal Kachroo <vishal@cs.wustl.edu>
+//
+// ============================================================================
+
+#ifndef RAPI_EVENT_HANDLER_H
+#define RAPI_EVENT_HANDLER_H
+
+#include "ace/Event_Handler.h"
+// #include "ace/Reactor.h"
+// #include "ace/INET_Addr.h"
+// #include "ace/SOCK_Dgram_Mcast.h"
+#include "ace/QoS_Session.h"
+
+ACE_RCSID(RAPI_Event_Handler, RAPI_Event_Handler, "$Id$")
+
+ class ACE_RAPI_Event_Handler : public ACE_Event_Handler
+ {
+ public:
+ // = Initialization and Termination methods.
+ ACE_RAPI_Event_Handler (void);
+ // Constructor.
+
+ ACE_RAPI_Event_Handler (ACE_QoS_Session *qos_session);
+ // Constructor.
+
+ ~ACE_RAPI_Event_Handler (void);
+ // Destructor.
+
+ virtual ACE_HANDLE get_handle (void) const;
+ // Override this to return the handle of the UNIX domain socket
+ // that RAPI uses to communicate with the RAPI daemon.
+
+ virtual int handle_qos (ACE_HANDLE fd);
+ // Handles a QOS event. Right now, just
+ // prints a message.
+
+ virtual int handle_input (ACE_HANDLE fd);
+ // Handles a READ event.
+
+ private:
+
+ ACE_QoS_Session *qos_session_;
+
+ };
+
+#endif /* RAPI_EVENT_HANDLER_H */
+
diff --git a/examples/QOS/README b/examples/QOS/README
index ccfe2ed7fe0..dfcfa33c987 100644
--- a/examples/QOS/README
+++ b/examples/QOS/README
@@ -6,11 +6,11 @@ A Regression test for ACE QoS features.
This test implements a simple Receiver-Sender program that ensures
Quality of Service (QoS) guarantees on the underlying network before
transmitting data. The program tests the ACE QoS APIs/features. The
-test works only on Win2K because currently most QoS ACE APIs are
-implemented as wrappers around WinSock2 APIs. In the future, RAPI, an
-implementation of QoS APIs on Solaris will be incorporated into ACE
-and this test should work "out of the box" for the underlying RAPI
-APIs as should all the applications that use the ACE QoS APIs.
+test works for Winsock2 APIs on Win2K as well as RAPI on Solaris.
+
+
+------------------------------------------------------------------------
+WIN2K :
Build Requirements :
--------------------
@@ -23,41 +23,90 @@ The test consists of a server (which is the receiver) and a client
The receiver is started first (though it is not mandatory) as :
- server -q:default -m
+ server -m merengue.cs.wustl.edu:9091
+
+ -m: specifies the multicast session address that both client and
+ server subscribe to for QoS events.
+
+ -p: Protocol to be used. Could be udp or tcp. Default is udp.
+
+ -P: Sender source port. If not specified, DEFAULT_SOURCE_SENDER_PORT
+ (10001) will be used.
+
+ -h: Displays the help on various options.
- The -q:default option makes the receiver use the default QoS parameters
- in the test.
+The sample Sender is started next as :
- The -m option specifies that the receiver is listening to multicast
- from any potential senders that can negotiate and satisfy the QoS
- requirements of the receiver.
+ client -m merengue.cs.wustl.edu:9091 -P 10004
-The Sender is started next as :
+ -m: specifies the multicast session address that both client and
+ server subscribe to for QoS events.
- client -q:default -n -m
+ -n: Option to be used by senders only to specify the destination
+ address. This option is overriden if a multicast address is also
+ specified through the -m option.
- The -q:default option makes the sender use the default QoS parameters
- in the test. These are the same as those used by the receiver.
+ -p: Protocol to be used. Could be udp or tcp. Default is udp.
- The -n option specifies that this is a sender.
+ -P: Sender source port. If not specified, DEFAULT_SOURCE_SENDER_PORT
+ (10001) will be used.
- The -m option specifies that the sender would be sending multicast to
- any potential receivers that can negotiate and satisfy the QoS
- requirements of the sender.
+ -h: Displays the help on various options.
-The user must have administrative access to the machine to run this program.
-It seems to be a pre-requisite to opening QoS sockets.
+On Win2K the user must have administrative access to the machine to
+run this program. It seems to be a pre-requisite to opening QoS
+sockets.
The sender and receiver should be run on different Win2K machines.
The test demonstrates how to GQOS enable an application using the ACE QoS APIs.
It concentrates on the use of various ACE QoS APIs and their correctness.
------------------
+-------------------------------------------------------------------------------
+
+RAPI :
+
+0. The $ACE_ROOT/include/makeinclude/platform_macros.GNU should be the
+following :
+
+include /project/doc/vishal/ACE_wrappers/include/makeinclude/platform_sunos5_sunc++.GNU
+PLATFORM_RAPI_CPPFLAGS += -I/project/doc/vishal/rapi/rel4.2a4/rsvpd/
+PLATFORM_RAPI_LIBS += -lrsvp
+PLATFORM_RAPI_LDFLAGS += -L/project/doc/vishal/rapi/rel4.2a4/rsvpd/
+
+assuming that RAPI library is installed in /project/doc/vishal/rapi/rel4.2a4/
+
+1. Compile ACE with
+
+ make rapi=1 static_libs_only=1
+ Static library option is used because the RAPI library that we have
+ does not compile as a shared object.
+
+2. Run the RSVP Daemon on two machines: (merengue.cs and macarena.cs)
+
+ /project/doc/vishal/rapi/rel4.2a4/rsvpd/rsvpd -D
+
+ The current version of the daemon comes with an inbuilt rtap
+ application to test the various reservation commands and RAPI APIs.
+
+ Typical values for rtap would be :
+
+ dest udp ace/5000
+ sender merengue/5000 [ t 2000000 100000 2000000 512 1024 ]
+
+ dest udp ace/5000
+ reserve wf [ cl 2000000 100000 2000000 512 1024 ]
+
+3. If RTAP runs fine and the daemons show the debug messages about
+ RESV, PATH and other RSVP messages, run the QoS example, making sure
+ that rtap session is released on both machines.
+
+-------------------------------------------------------------------------------
+
If you run into any problems with this test please contact Vishal
Kachroo <vishal@cs.wustl.edu>.
+This README last updated on 20th July, 2000.
-
-
+-------------------------------------------------------------------------------
diff --git a/examples/QOS/Receiver_QOS_Event_Handler.cpp b/examples/QOS/Receiver_QoS_Event_Handler.cpp
index ea0844b0500..bc05ea81b14 100644
--- a/examples/QOS/Receiver_QOS_Event_Handler.cpp
+++ b/examples/QOS/Receiver_QoS_Event_Handler.cpp
@@ -7,43 +7,78 @@
// ACE_wrappers/examples/QOS
//
// = FILENAME
-// Receiver_QOS_Event_Handler.cpp
+// Receiver_QoS_Event_Handler.cpp
//
// = AUTHOR
// Vishal Kachroo <vishal@cs.wustl.edu>
//
// ============================================================================
-#include "Receiver_QOS_Event_Handler.h"
+#include "Receiver_QoS_Event_Handler.h"
// Constructor.
-ACE_QOS_Event_Handler::ACE_QOS_Event_Handler (void)
+Receiver_QoS_Event_Handler::Receiver_QoS_Event_Handler (void)
{
}
-ACE_QOS_Event_Handler::ACE_QOS_Event_Handler (const ACE_SOCK_Dgram_Mcast &dgram_mcast,
- ACE_QoS_Session *qos_session)
- : dgram_mcast_ (dgram_mcast),
+Receiver_QoS_Event_Handler::Receiver_QoS_Event_Handler (const ACE_SOCK_Dgram_Mcast_QoS
+ &dgram_mcast_qos,
+ ACE_QoS_Session *qos_session)
+ : dgram_mcast_qos_ (dgram_mcast_qos),
qos_session_ (qos_session)
{
}
// Destructor.
-ACE_QOS_Event_Handler::~ACE_QOS_Event_Handler (void)
+Receiver_QoS_Event_Handler::~Receiver_QoS_Event_Handler (void)
{
}
// Return the handle of the Dgram_Mcast. This method is called
// internally by the reactor.
-
ACE_HANDLE
-ACE_QOS_Event_Handler::get_handle (void) const
+Receiver_QoS_Event_Handler::get_handle (void) const
{
- return this->dgram_mcast_.get_handle ();
+ return this->dgram_mcast_qos_.get_handle ();
+}
+
+// Called when there is a READ activity on the dgram_mcast_qos handle.
+int
+Receiver_QoS_Event_Handler::handle_input (ACE_HANDLE)
+{
+ char buf[BUFSIZ];
+
+ iovec iov;
+ iov.iov_base = buf;
+ iov.iov_len = BUFSIZ;
+
+ ACE_OS::memset (iov.iov_base,
+ 0,
+ BUFSIZ);
+
+ ACE_DEBUG ((LM_DEBUG,
+ "Inside handle_input () of Receiver_QoS_Event_Handler ()\n"));
+
+ // Receive message from multicast group.
+ ssize_t result =
+ this->dgram_mcast_qos_.recv (&iov,
+ 1,
+ this->remote_addr_);
+
+ if (result != -1)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "Message Received : %s",
+ iov.iov_base));
+ return 0;
+ }
+ else
+ return -1;
}
+// Called when there is a QoS Event.
int
-ACE_QOS_Event_Handler::handle_qos (ACE_HANDLE)
+Receiver_QoS_Event_Handler::handle_qos (ACE_HANDLE fd)
{
ACE_DEBUG ((LM_DEBUG,
@@ -95,40 +130,6 @@ ACE_QOS_Event_Handler::handle_qos (ACE_HANDLE)
ace_get_qos.sending_flowspec ().minimum_policed_size ()));
return 0;
-}
-
-// Called when there is a READ activity on the dgram_mcast handle.
-
-int
-ACE_QOS_Event_Handler::handle_input (ACE_HANDLE)
-{
- char buf[BUFSIZ];
-
- iovec iov;
- iov.iov_base = buf;
- iov.iov_len = BUFSIZ;
-
- ACE_OS::memset (iov.iov_base,
- 0,
- BUFSIZ);
- ACE_DEBUG ((LM_DEBUG,
- "Inside handle_input () of ACE_Read_Handler ()\n"));
-
- // Receive message from multicast group.
- ssize_t result =
- this->dgram_mcast_.recv (&iov,
- 1,
- this->remote_addr_);
-
- if (result != -1)
- {
- ACE_DEBUG ((LM_DEBUG,
- "Message Received %s",
- iov.iov_base));
- return 0;
- }
- else
- return -1;
}
diff --git a/examples/QOS/Receiver_QOS_Event_Handler.h b/examples/QOS/Receiver_QoS_Event_Handler.h
index d17e2c711fe..1c23255395d 100644
--- a/examples/QOS/Receiver_QOS_Event_Handler.h
+++ b/examples/QOS/Receiver_QoS_Event_Handler.h
@@ -7,7 +7,7 @@
// ACE_wrappers/examples/QOS
//
// = FILENAME
-// Receiver_QOS_Event_Handler.h
+// Receiver_QoS_Event_Handler.h
//
// = AUTHOR
// Vishal Kachroo <vishal@cs.wustl.edu>
@@ -17,43 +17,45 @@
#ifndef RECEIVER_QOS_EVENT_HANDLER_H
#define RECEIVER_QOS_EVENT_HANDLER_H
-#include "ace/Event_Handler.h"
#include "ace/Reactor.h"
#include "ace/INET_Addr.h"
-#include "ace/SOCK_Dgram_Mcast.h"
+#include "ace/Event_Handler.h"
#include "ace/QoS_Session.h"
+#include "ace/SOCK_Dgram_Mcast_QoS.h"
-ACE_RCSID(Receiver_QOS_Event_Handler, Receiver_QOS_Event_Handler, "$Id$")
+ACE_RCSID(Receiver_QoS_Event_Handler, Receiver_QoS_Event_Handler, "$Id$")
- class ACE_QOS_Event_Handler : public ACE_Event_Handler
+ class Receiver_QoS_Event_Handler : public ACE_Event_Handler
{
public:
// = Initialization and Termination methods.
- ACE_QOS_Event_Handler (void);
+ Receiver_QoS_Event_Handler (void);
// Constructor.
-
- ACE_QOS_Event_Handler::ACE_QOS_Event_Handler (const ACE_SOCK_Dgram_Mcast &dgram_mcast,
- ACE_QoS_Session *qos_session);
+
+ Receiver_QoS_Event_Handler::Receiver_QoS_Event_Handler (const ACE_SOCK_Dgram_Mcast_QoS &dgram_mcast_qos,
+ ACE_QoS_Session *qos_session);
// Constructor.
-
- ~ACE_QOS_Event_Handler (void);
+
+ ~Receiver_QoS_Event_Handler (void);
// Destructor.
virtual ACE_HANDLE get_handle (void) const;
// Override this to return the handle of the Dgram_Mcast
// that we are using.
-
- virtual int handle_qos (ACE_HANDLE fd);
- // Handles a QOS event. Right now, just
- // prints a message.
-
+
virtual int handle_input (ACE_HANDLE fd);
// Handles a READ event.
+
+ virtual int handle_qos (ACE_HANDLE fd);
+ // Handles a QoS event.
private:
- ACE_SOCK_Dgram_Mcast dgram_mcast_;
- ACE_INET_Addr remote_addr_;
+ ACE_SOCK_Dgram_Mcast_QoS dgram_mcast_qos_;
ACE_QoS_Session *qos_session_;
+ ACE_INET_Addr remote_addr_;
};
#endif /* RECEIVER_QOS_EVENT_HANDLER_H */
+
+
+
diff --git a/examples/QOS/Sender_QoS_Event_Handler.cpp b/examples/QOS/Sender_QoS_Event_Handler.cpp
new file mode 100644
index 00000000000..2d11b428bed
--- /dev/null
+++ b/examples/QOS/Sender_QoS_Event_Handler.cpp
@@ -0,0 +1,141 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// ACE_wrappers/examples/QOS
+//
+// = FILENAME
+// Sender_QoS_Event_Handler.cpp
+//
+// = AUTHOR
+// Vishal Kachroo <vishal@cs.wustl.edu>
+//
+// ============================================================================
+
+#include "Sender_QoS_Event_Handler.h"
+
+// Constructor.
+Sender_QoS_Event_Handler::Sender_QoS_Event_Handler (void)
+{
+}
+
+// Constructor.
+Sender_QoS_Event_Handler::Sender_QoS_Event_Handler (const ACE_SOCK_Dgram_Mcast_QoS
+ &dgram_mcast_qos,
+ ACE_QoS_Session *qos_session)
+ : dgram_mcast_qos_ (dgram_mcast_qos),
+ qos_session_ (qos_session)
+{
+}
+
+// Destructor.
+Sender_QoS_Event_Handler::~Sender_QoS_Event_Handler (void)
+{
+}
+
+// Return the handle of the Dgram_Mcast. This method is called
+// internally by the reactor.
+
+ACE_HANDLE
+Sender_QoS_Event_Handler::get_handle (void) const
+{
+ return this->dgram_mcast_qos_.get_handle ();
+}
+
+// Handle the QoS Event. In this case send data to the receiver
+// using WSASendTo() that uses overlapped I/O.
+
+int
+Sender_QoS_Event_Handler::handle_qos (ACE_HANDLE)
+{
+ ACE_DEBUG ((LM_DEBUG,
+ "\nReceived a QOS event. Inside handle_qos ()\n"));
+
+ // We have received an RSVP event. The following update_qos () call
+ // calls rapi_dispatch () in case of RAPI and WSAIoctl (GET_QOS) in
+ // case of W2K. It then does the QoS parameter translation and updates
+ // the QoS session object with the latest QoS. This call replaces the
+ // direct call that was being made to WSAIoctl (GET_QOS) here for the
+ // Win2K example.
+
+ if (this->qos_session_->update_qos () == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Error in updating QoS\n"),
+ -1);
+ else
+ ACE_DEBUG ((LM_DEBUG,
+ " Updating QOS succeeds.\n"));
+
+ // Now proactively query the QoS object for QoS.
+ ACE_QoS ace_get_qos = this->qos_session_->qos ();
+
+ ACE_DEBUG ((LM_DEBUG,
+ "\nReceiving Flowspec :\t\t\tSending Flowspec :\n\n"
+ "\tToken Rate = %d\t\t\tToken Rate = %d\n"
+ "\tToken Bucket Size = %d\t\t\tToken Bucket Size = %d\n"
+ "\tPeak Bandwidth = %d\t\t\tPeak Bandwidth = %d\n"
+ "\tLatency = %d\t\t\t\tLatency = %d\n"
+ "\tDelay Variation = %d\t\t\tDelay Variation = %d\n"
+ "\tService Type = %d\t\t\tService Type = %d\n"
+ "\tMax SDU Size = %d\t\t\tMax SDU Size = %d\n"
+ "\tMinimum Policed Size = %d\t\tMinimum Policed Size = %d\n\n",
+ ace_get_qos.receiving_flowspec ().token_rate (),
+ ace_get_qos.sending_flowspec ().token_rate (),
+ ace_get_qos.receiving_flowspec ().token_bucket_size (),
+ ace_get_qos.sending_flowspec ().token_bucket_size (),
+ ace_get_qos.receiving_flowspec ().peak_bandwidth (),
+ ace_get_qos.sending_flowspec ().peak_bandwidth (),
+ ace_get_qos.receiving_flowspec ().latency (),
+ ace_get_qos.sending_flowspec ().latency (),
+ ace_get_qos.receiving_flowspec ().delay_variation (),
+ ace_get_qos.sending_flowspec ().delay_variation (),
+ ace_get_qos.receiving_flowspec ().service_type (),
+ ace_get_qos.sending_flowspec ().service_type (),
+ ace_get_qos.receiving_flowspec ().max_sdu_size (),
+ ace_get_qos.sending_flowspec ().max_sdu_size (),
+ ace_get_qos.receiving_flowspec ().minimum_policed_size (),
+ ace_get_qos.sending_flowspec ().minimum_policed_size ()));
+
+ // This is SPECIFIC TO WIN2K and should be done in the qos_update function.
+
+// ACE_QoS ace_get_qos;
+// u_long dwBytes;
+
+// if (ACE_OS::ioctl (this->dgram_mcast_qos_.get_handle (),
+// ACE_SIO_GET_QOS,
+// ace_get_qos,
+// &dwBytes) == -1)
+// ACE_ERROR ((LM_ERROR,
+// "Error in Qos get ACE_OS::ioctl ()\n"
+// "Bytes Returned = %d\n",
+// dwBytes));
+// else
+// ACE_DEBUG ((LM_DEBUG,
+// "Getting QOS using ACE_OS::ioctl () succeeds.\n"));
+
+ iovec iov[1];
+ iov[0].iov_base = (char *) "Hello sent on a QoS enabled session !!\n";
+ iov[0].iov_len = ACE_OS::strlen (iov[0].iov_base);
+
+ size_t bytes_sent = 0;
+
+ // Send "Hello" to the QoS session address to which the receiver has
+ // subscribed.
+ if (this->dgram_mcast_qos_.send (iov,
+ 1,
+ bytes_sent,
+ 0,
+ this->qos_session_->dest_addr (),
+ 0,
+ 0) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Error in dgram_mcast.send ()\n"),
+ -1);
+ else
+ ACE_DEBUG ((LM_DEBUG,
+ "Using ACE_OS::sendto () : Bytes sent : %d",
+ bytes_sent));
+ return 0;
+}
diff --git a/examples/QOS/Sender_QOS_Event_Handler.h b/examples/QOS/Sender_QoS_Event_Handler.h
index ee9e5a5d4c8..d14403527a2 100644
--- a/examples/QOS/Sender_QOS_Event_Handler.h
+++ b/examples/QOS/Sender_QoS_Event_Handler.h
@@ -7,7 +7,7 @@
// ACE_wrappers/examples/QOS
//
// = FILENAME
-// QOS_Event_Handler.h
+// Sender_QoS_Event_Handler.h
//
// = AUTHOR
// Vishal Kachroo <vishal@cs.wustl.edu>
@@ -21,23 +21,27 @@
#include "ace/Reactor.h"
#include "ace/INET_Addr.h"
#include "ace/SOCK_Dgram_Mcast_QoS.h"
+#include "ace/QoS_Session.h"
-#define MY_DEFPORT 5001
-#define DEFAULT_MULTICASTGROUP "234.5.6.7"
+//#define MY_DEFPORT 5001
+//#define DEFAULT_MULTICASTGROUP "234.5.6.7"
-ACE_RCSID(QOS_Event_Handler, QOS_Event_Handler, "$Id$")
+ACE_RCSID(Sender_QoS_Event_Handler, Sender_QoS_Event_Handler, "$Id$")
-class ACE_QOS_Event_Handler : public ACE_Event_Handler
+class Sender_QoS_Event_Handler : public ACE_Event_Handler
{
public:
// = Initialization and Termination methods.
- ACE_QOS_Event_Handler (void);
+ Sender_QoS_Event_Handler (void);
// Constructor.
- ACE_QOS_Event_Handler::ACE_QOS_Event_Handler (const ACE_SOCK_Dgram_Mcast_QoS &dgram_mcast);
+ Sender_QoS_Event_Handler::Sender_QoS_Event_Handler (const ACE_SOCK_Dgram_Mcast_QoS
+ &dgram_mcast_qos,
+ ACE_QoS_Session *qos_session
+ );
// Constructor.
-
- ~ACE_QOS_Event_Handler (void);
+
+ ~Sender_QoS_Event_Handler (void);
// Destructor.
virtual ACE_HANDLE get_handle (void) const;
@@ -45,13 +49,13 @@ public:
// that we are using.
virtual int handle_qos (ACE_HANDLE fd);
- // Handles a QOS event. Right now, just
+ // Handles a QoS event. Right now, just
// prints a message.
private:
- ACE_SOCK_Dgram_Mcast_QoS dgram_mcast_;
-
+ ACE_SOCK_Dgram_Mcast_QoS dgram_mcast_qos_;
+ ACE_QoS_Session *qos_session_;
};
#endif /* SENDER_QOS_EVENT_HANDLER_H */
diff --git a/examples/QOS/client.cpp b/examples/QOS/client.cpp
index f902a3ba814..5315f115f5e 100644
--- a/examples/QOS/client.cpp
+++ b/examples/QOS/client.cpp
@@ -14,23 +14,18 @@
//
// ============================================================================
-#include "ace/SOCK_Dgram_Mcast_QoS.h"
-#include "ace/OS.h"
-#define QOSEVENT_MAIN
-#include "QosEvent.h"
-#include "Sender_QOS_Event_Handler.h"
-
-static const char *const SERVER_HOST = DEFAULT_MULTICASTGROUP;
-static const int MAX_ITERATIONS = 4;
-
-static int ValidOptions (char *argv[],
- int argc,
- OPTIONS *pOptions);
-static void Usage (char *szProgramname,
- OPTIONS *pOptions);
+#include "ace/OS.h"
+#include "ace/QoS_Session.h"
+#include "ace/QoS_Session_Factory.h"
+#include "ace/QoS_Session_Impl.h"
+#include "ace/QoS_Decorator.h"
+#include "ace/SOCK_Dgram_Mcast_QoS.h"
-static const u_short PORT = ACE_DEFAULT_SERVER_PORT;
+#include "QoS_Util.h"
+#include "Fill_ACE_QoS.h"
+#include "QoS_Signal_Handler.h"
+#include "Sender_QoS_Event_Handler.h"
// To open QOS sockets administrative access is required on the
// machine. Fill in default values for QoS structure. The default
@@ -42,90 +37,7 @@ static const u_short PORT = ACE_DEFAULT_SERVER_PORT;
// depending upon whether this application is acting as a sender or
// receiver.
-static int
-fill_ace_qos_flowspec_default (ACE_QoS *pQos,
- QOS_OPTIONS *pQosOptions)
-{
- ACE_Flow_Spec ace_default_g711 (9200,
- 708,
- 18400,
- 0,
- 0,
- ACE_SERVICETYPE_GUARANTEED,
- // SERVICETYPE_CONTROLLEDLOAD
- // doesnt work here for a yet unknown
- // reason.
- 368,
- 368,
- 25, // TTL. ACE specific. Not used on NT.
- 1 // Priority. ACE specific. Not used on NT.
- );
-
- ACE_Flow_Spec ace_default_notraffic (ACE_QOS_NOT_SPECIFIED,
- ACE_QOS_NOT_SPECIFIED,
- ACE_QOS_NOT_SPECIFIED,
- ACE_QOS_NOT_SPECIFIED,
- ACE_QOS_NOT_SPECIFIED,
- ACE_SERVICETYPE_NOTRAFFIC,
- ACE_QOS_NOT_SPECIFIED,
- ACE_QOS_NOT_SPECIFIED,
- 25, // TTL. ACE specific. Not used on NT.
- 1); // Priority. ACE specific. Not used on NT.
- if (pQosOptions->bReceiver)
- {
- pQos->receiving_flowspec (ace_default_g711);
- pQos->sending_flowspec (ace_default_notraffic);
- }
- else
- {
- pQos->sending_flowspec (ace_default_g711);
- pQos->receiving_flowspec (ace_default_notraffic);
- }
-
- const iovec iov = {0, 0};
- pQos->provider_specific (iov);
-
- return 0;
-}
-
-int SetQos (QOS_OPTIONS *pQosOptions,
- ACE_QoS *pQos)
-{
- int bError = FALSE;
-
- // fill in default values
- if (ACE_OS::strcasecmp (pQosOptions->szTemplate,
- QOS_DEFAULTNAME) == 0)
- fill_ace_qos_flowspec_default (pQos,
- pQosOptions);
- else
- ACE_DEBUG ((LM_DEBUG,
- "Run the program with -q:default option\n"));
- return !bError;
-}
-
-// Fill up the ACE_Flow_Spec with the default_g711 values as defined
-// in the QoSEvent.h
-
-int
-FillQoSTraffic (ACE_Flow_Spec &afc)
-{
- afc = default_g711;
- return 0;
-}
-
-// Fill up the ACE_Flow_Spec with the default_notraffic values
-// as defined in the QoSEvent.h
-
-int
-FillQoSNoTraffic (ACE_Flow_Spec &afc)
-{
- afc = default_notraffic;
- return 0;
-}
-
-// This function fills up the ACE_QoS_Params with the supplied
-// iovec and ACE_QoS.
+// This function fills up the ACE_QoS_Params with the supplied iovec and ACE_QoS.
int
FillQoSParams (ACE_QoS_Params &qos_params,
@@ -136,7 +48,7 @@ FillQoSParams (ACE_QoS_Params &qos_params,
qos_params.caller_data (0);
qos_params.socket_qos (qos);
qos_params.group_socket_qos (0);
- qos_params.flags (ACE_JL_SENDER_ONLY);
+ qos_params.flags (ACE_JL_BOTH);
return 0;
}
@@ -144,577 +56,278 @@ FillQoSParams (ACE_QoS_Params &qos_params,
int
main (int argc, char * argv[])
{
- ACE_Protocol_Info protocol_info;
-
- OPTIONS options;
-
- if (!ValidOptions (argv,
- argc,
- &options))
- ACE_ERROR_RETURN ((LM_ERROR,
- "Error in ValidOptions\n"),
- -1);
-
- if (FindServiceProvider (options.spOptions.iProtocol,
- options.spOptions.bQos,
- options.spOptions.bMulticast,
- &protocol_info) == FALSE)
- ACE_ERROR_RETURN ((LM_ERROR,
- "Error in FindServiceProvider\n"),
- -1);
ACE_DEBUG ((LM_DEBUG,
"Sender\n"));
- ACE_QoS qos;
-
- // By default the QOS is set as QOS_IOCTL_SET_BEFORE.
- if (options.spOptions.bQos)
- {
- if (QOS_IOCTL_SET_BEFORE == options.qosOptions.qosIoctlSet)
- {
- if (SetQos (&options.qosOptions,
- &qos))
- ACE_DEBUG ((LM_DEBUG,
- " QOS set before accept\n"));
- }
- else if (QOS_IOCTL_SET_QOS == options.qosOptions.qosIoctlSet)
- {
- options.qosOptions.bDisableSignalling = TRUE;
- if (SetQos (&options.qosOptions,
- &qos))
- ACE_DEBUG ((LM_DEBUG,
- " QOS set qos before accept - will be "
- "set again in FD_QOS\n"));
- }
- }
- else
- ACE_ERROR_RETURN ((LM_ERROR,
- "Use the -q:default option to enable the QOS\n"),
- -1);
+ QoS_Util qos_util(argc, argv);
- // Opening a new Multicast Datagram. It is absolutely necessary that
- // the sender and the receiver subscribe to the same multicast
- // addresses to make sure the "multicast sessions" for the two are
- // the same. This is used to match the RESV<->PATH states.
- ACE_SOCK_Dgram_Mcast_QoS dgram_mcast;
-
- // The windows example code uses PF_INET for the address family.
- // Winsock.h defines PF_INET to be AF_INET. Is there really a
- // difference between the protocol families and the address families
- // ? The following code internally uses AF_INET as a default for the
- // underlying socket.
- ACE_INET_Addr mult_addr (options.port,
- options.szHostname);
-
- // Fill the ACE_QoS_Params to be passed to the <ACE_OS::join_leaf>
- // through subscribe.
- ACE_QoS_Params qos_params;
- FillQoSParams (qos_params,
- 0,
- &qos);
-
- // The following call opens the Dgram_Mcast and calls the
- // <ACE_OS::join_leaf> with the qos_params supplied here.
- if (dgram_mcast.subscribe (mult_addr,
- qos_params,
- 1,
- 0,
- AF_INET,
- ACE_FROM_PROTOCOL_INFO,
- &protocol_info,
- 0,
- ACE_OVERLAPPED_SOCKET_FLAG
- | ACE_FLAG_MULTIPOINT_C_LEAF
- | ACE_FLAG_MULTIPOINT_D_LEAF) == -1)
+ if (qos_util.parse_args () == -1)
ACE_ERROR_RETURN ((LM_ERROR,
- "Error in subscribe\n"),
+ "Error in parsing args\n"),
-1);
- else
- ACE_DEBUG ((LM_DEBUG,
- "Dgram_Mcast subscribe succeeds \n"));
-
- int nIP_TTL = 25;
- char achInBuf [BUFSIZ];
- u_long dwBytes;
-
- if (ACE_OS::ioctl (dgram_mcast.get_handle (), // Socket.
- ACE_SIO_MULTICAST_SCOPE, // IO control code.
- &nIP_TTL, // In buffer.
- sizeof (nIP_TTL), // Length of in buffer.
- achInBuf, // Out buffer.
- BUFSIZ, // Length of Out buffer.
- &dwBytes, // bytes returned.
- 0, // Overlapped.
- 0) == -1) // Func.
- ACE_ERROR ((LM_ERROR,
- "Error in Multicast scope ACE_OS::ioctl() \n"));
- else
- ACE_DEBUG ((LM_DEBUG,
- "Setting TTL with Multicast scope ACE_OS::ioctl call succeeds \n"));
-
- int bFlag = FALSE;
-
- if (ACE_OS::ioctl (dgram_mcast.get_handle (), // Socket.
- ACE_SIO_MULTIPOINT_LOOPBACK, // IO control code.
- &bFlag, // In buffer.
- sizeof (bFlag), // Length of in buffer.
- achInBuf, // Out buffer.
- BUFSIZ, // Length of Out buffer.
- &dwBytes, // bytes returned.
- 0, // Overlapped.
- 0) == -1) // Func.
- ACE_ERROR ((LM_ERROR,
- "Error in Loopback ACE_OS::ioctl() \n"));
- else
- ACE_DEBUG ((LM_DEBUG,
- "Disable Loopback with ACE_OS::ioctl call succeeds \n"));
-
- // Fill up an ACE_QoS and pass it to the overloaded ACE_OS::ioctl ()
- // that uses the I/O control code as SIO_SET_QOS.
- ACE_QoS ace_qos;
-
- // Make sure the flowspec is set in the correct direction. Since
- // this is the sender, sending flowspec is set to g711 and receiving
- // flowspec is set to no traffic.
- ACE_Flow_Spec sending_flowspec;
- ACE_Flow_Spec receiving_flowspec;
- const iovec iov = {0, 0};
-
- FillQoSTraffic (sending_flowspec);
- FillQoSNoTraffic (receiving_flowspec);
-
- ace_qos.sending_flowspec (sending_flowspec);
- ace_qos.receiving_flowspec (receiving_flowspec);
- ace_qos.provider_specific (iov);
-
- // Set the QOS according to the supplied ACE_QoS. The I/O control
- // code used under the hood is SIO_SET_QOS.
- if (ACE_OS::ioctl (dgram_mcast.get_handle (), // Socket.
- ACE_SIO_SET_QOS,
- ace_qos, // ACE_QoS.
- &dwBytes) == -1) // bytes returned.
- ACE_ERROR ((LM_ERROR,
- "Error in Qos set ACE_OS::ioctl() %d\n",
- dwBytes));
- else
- ACE_DEBUG ((LM_DEBUG,
- "Setting Default QOS with ACE_OS::ioctl succeeds \n"));
-
- // Instantiate a QOS Event Handler and pass the Dgram_Mcast into it.
- ACE_QOS_Event_Handler qos_event_handler (dgram_mcast);
-
- // Register the QOS Handler with the Reactor for the QOS_MASK. Note
- // the receiver registers for both QOS_MASK as well as READ_MASK.
-
- if (ACE_Reactor::instance ()->register_handler
- (&qos_event_handler,
- ACE_Event_Handler::QOS_MASK) == -1)
- ACE_ERROR_RETURN ((LM_ERROR,
- "Error in registering QOS Handler\n"),
- -1);
-
- // Start the event loop.
- ACE_DEBUG ((LM_DEBUG,
- "Running the Event Loop ... \n"));
-
- ACE_Reactor::instance ()->run_event_loop ();
-
- ACE_DEBUG ((LM_DEBUG,
- "(%P|%t) shutting down Sender\n"));
- return 0;
-}
-
-int
-FindServiceProvider(int iProtocol,
- int bQos,
- int bMulticast,
- ACE_Protocol_Info *pProtocolInfo)
-{
-
- ACE_Protocol_Info *protocol_buffer = 0;
-
- u_long buffer_length = 0;
- u_long dwErr;
- int bProtocolFound = FALSE;
- // first have enum_protocols () tell us how big a buffer is needed.
- int ret_val = ACE_OS::enum_protocols (0,
- protocol_buffer,
- &buffer_length);
- if (ret_val != -1)
- ACE_DEBUG ((LM_DEBUG,
- "enum_protocols () : should not have suceeded\n"));
-
- else if (ACE_ENOBUFS != (dwErr = ACE_OS::set_errno_to_wsa_last_error ()))
- // enum_protocols () failed for some reason not relating to buffer size
- ACE_DEBUG ((LM_DEBUG,
- "enum_protocols () : failed for a reason other than "
- "inadequate buffer size : %d\n",
- ACE_OS::set_errno_to_wsa_last_error ()));
- else
+ // This is a multicast application.
+ if (qos_util.multicast_flag ())
{
- if (buffer_length > 0)
- {
- void *ptr = 0;
- ACE_NEW_RETURN (ptr,
- char [buffer_length],
- 0);
- protocol_buffer = (ACE_Protocol_Info *) ptr;
- }
+ Fill_ACE_QoS fill_ace_qos;
+
+ // The application adds the flow specs that it wants into the
+ // Fill_ACE_QoS. The Fill_ACE_QoS indexes the flow specs by the flow
+ // spec names. Here the new flowspec being added is g_711.
+ ACE_CString g_711 ("g_711");
+
+ switch (fill_ace_qos.map ().bind (g_711,
+ new ACE_Flow_Spec (9200,
+ 708,
+ 18400,
+ 0,
+ 0,
+ ACE_SERVICETYPE_CONTROLLEDLOAD,
+ 368,
+ 368,
+ 25,
+ 1)))
+ {
+ case 1 :
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Unable to bind the new flow spec\n"
+ "The Flow Spec name already exists\n"),
+ -1);
+ break;
+ case -1 :
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Unable to bind the new flow spec\n"),
+ -1);
+ break;
+ }
+
+ ACE_DEBUG ((LM_DEBUG,
+ "g_711 Flow Spec bound successfully\n"));
+
+ // This is a sender. So we fill in the sending QoS parameters.
+ ACE_QoS ace_qos_sender;
+
+ if (fill_ace_qos.fill_simplex_sender_qos (ace_qos_sender,
+ g_711) !=0)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Unable to fill simplex sender qos\n"),
+ -1);
+ else
+ ACE_DEBUG ((LM_DEBUG,
+ "Filled up the Sender QoS parameters\n"));
+
+ // Opening a new Multicast Datagram. It is absolutely necessary that
+ // the sender and the receiver subscribe to the same multicast
+ // addresses to make sure the "multicast sessions" for the two are
+ // the same. This is used to match the RESV<->PATH states.
+ ACE_SOCK_Dgram_Mcast_QoS dgram_mcast_qos;
+
+ // Multicast Session Address specified by user at command line.
+ // If this address is not specified,
+ // <localhost:ACE_DEFAULT_MULTICAST_PORT> is assumed.
+ ACE_INET_Addr mult_addr (*(qos_util.mult_session_addr ()));
+
+ // Fill the ACE_QoS_Params to be passed to the <ACE_OS::join_leaf>
+ // through subscribe.
+
+ ACE_QoS_Params qos_params;
+ FillQoSParams (qos_params, 0, &ace_qos_sender);
+
+ // Create a QoS Session Factory.
+ ACE_QoS_Session_Factory session_factory;
+
+ // Ask the factory to create a QoS session. This could be RAPI or
+ // GQoS based on the parameter passed.
+ ACE_QoS_Session *qos_session =
+ session_factory.create_session (ACE_QoS_Session_Factory::ACE_RAPI_SESSION);
+
+ // Create a destination address for the QoS session. The same
+ // address should be used for the subscribe call later. A copy is
+ // made below only to distinguish the two usages of the dest
+ // address.
+ ACE_INET_Addr dest_addr (mult_addr);
+
+ // A QoS session is defined by the 3-tuple [DestAddr, DestPort,
+ // Protocol]. Initialize the QoS session.
+ if (qos_session->open (mult_addr,
+ IPPROTO_UDP) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Error in opening the QoS session\n"),
+ -1);
else
+ ACE_DEBUG ((LM_DEBUG,
+ "QoS session opened successfully\n"));
+
+ // The following call opens the Dgram_Mcast and calls the
+ // <ACE_OS::join_leaf> with the qos_params supplied here. Note the
+ // QoS session object is passed into this call. This subscribes the
+ // underlying socket to the passed in QoS session. For joining
+ // multiple multicast sessions, the following subscribe call should
+ // be made with different multicast addresses and a new QoS session
+ // object should be passed in for each such call. The QoS session
+ // objects can be created only through the session factory. Care
+ // should be taken that the mult_addr for the subscribe() call
+ // matches the dest_addr of the QoS session object. If this is not
+ // done, the subscribe call will fail. A more abstract version of
+ // subscribe will be added that constrains the various features of
+ // GQoS like different flags etc.
+
+ if (dgram_mcast_qos.subscribe (mult_addr,
+ qos_params,
+ 1,
+ 0,
+ AF_INET,
+ // ACE_FROM_PROTOCOL_INFO,
+ 0,
+ 0, // ACE_Protocol_Info,
+ 0,
+ ACE_OVERLAPPED_SOCKET_FLAG
+ | ACE_FLAG_MULTIPOINT_C_LEAF
+ | ACE_FLAG_MULTIPOINT_D_LEAF,
+ qos_session) == -1)
ACE_ERROR_RETURN ((LM_ERROR,
- "Buffer length returned by enum_protocols () is"
- "less than or equal to zero\n"),
+ "Error in subscribe\n"),
-1);
+ else
+ ACE_DEBUG ((LM_DEBUG,
+ "Dgram_Mcast subscribe succeeds \n"));
- if (protocol_buffer)
- {
- // now we can call enum_protocols () again with the
- // expectation it will succeed because we have allocated a
- // big enough buffer.
- ret_val = ACE_OS::enum_protocols (0,
- protocol_buffer,
- &buffer_length);
- if (ret_val == -1)
- ACE_DEBUG ((LM_DEBUG,
- "enum_protocols () : failed even after allocating"
- " a big enough buffer : %d\n",
- ACE_OS::set_errno_to_wsa_last_error ()));
- else
- {
- ACE_DEBUG ((LM_DEBUG,
- "Size allocated for the Protocol Buffer = %d\n"
- "\nList of transport protocols "
- "returned by enum_protocols () : \n",
- buffer_length));
-
- // Loop thru protocols, looking for a matching service
- // provider.
- for (int i = 0; i < ret_val; i++)
- {
- ACE_DEBUG ((LM_DEBUG,
- " sp <%s>\n",
- protocol_buffer[i].szProtocol));
-
- if (AF_INET == protocol_buffer[i].iAddressFamily
- && iProtocol == protocol_buffer[i].iProtocol)
- {
- // look for
- if (bQos && bMulticast)
- {
- if ((ACE_XP1_QOS_SUPPORTED == ((ACE_XP1_QOS_SUPPORTED
- & protocol_buffer[i].dwServiceFlags1)))
- && (ACE_XP1_SUPPORT_MULTIPOINT == (ACE_XP1_SUPPORT_MULTIPOINT &
- protocol_buffer[i].dwServiceFlags1)))
- {
- *pProtocolInfo = protocol_buffer[i];
- bProtocolFound = TRUE;
- break;
- }
- }
- else if (bQos)
- {
- if (ACE_XP1_QOS_SUPPORTED == (ACE_XP1_QOS_SUPPORTED
- & protocol_buffer[i].dwServiceFlags1))
- {
- *pProtocolInfo = protocol_buffer[i];
- bProtocolFound = TRUE;
- break;
- }
- }
- else if (bMulticast)
- {
- if ((ACE_XP1_SUPPORT_MULTIPOINT == (ACE_XP1_SUPPORT_MULTIPOINT &
- protocol_buffer[i].dwServiceFlags1))
- && (ACE_XP1_QOS_SUPPORTED != (ACE_XP1_QOS_SUPPORTED &
- protocol_buffer[i].dwServiceFlags1)))
- {
- *pProtocolInfo = protocol_buffer[i];
- bProtocolFound = TRUE;
- break;
- }
- }
- else if ((ACE_XP1_QOS_SUPPORTED != (ACE_XP1_QOS_SUPPORTED
- & protocol_buffer[i].dwServiceFlags1)))
- {
- *pProtocolInfo = protocol_buffer[i];
- bProtocolFound = TRUE;
- break;
- }
- }
-
- } // for loop.
-
- } // ACE_OS::enum_protocols ().
+ int nIP_TTL = 25;
+ char achInBuf [BUFSIZ];
+ u_long dwBytes;
+
+ // Should this be abstracted into QoS objects ?? Doesnt seem to have
+ // to do anything directly with QoS.
+ if (ACE_OS::ioctl (dgram_mcast_qos.get_handle (), // Socket.
+ ACE_SIO_MULTICAST_SCOPE, // IO control code.
+ &nIP_TTL, // In buffer.
+ sizeof (nIP_TTL), // Length of in buffer.
+ achInBuf, // Out buffer.
+ BUFSIZ, // Length of Out buffer.
+ &dwBytes, // bytes returned.
+ 0, // Overlapped.
+ 0) == -1) // Func.
+ ACE_ERROR ((LM_ERROR,
+ "Error in Multicast scope ACE_OS::ioctl() \n"));
+ else
+ ACE_DEBUG ((LM_DEBUG,
+ "Setting TTL with Multicast scope ACE_OS::ioctl call succeeds \n"));
+
+ int bFlag = 0;
+
+ // Should this be abstracted into QoS objects ?? Doesnt seem to have
+ // to do anything directly with QoS.
+ if (ACE_OS::ioctl (dgram_mcast_qos.get_handle (), // Socket.
+ ACE_SIO_MULTIPOINT_LOOPBACK, // IO control code.
+ &bFlag, // In buffer.
+ sizeof (bFlag), // Length of in buffer.
+ achInBuf, // Out buffer.
+ BUFSIZ, // Length of Out buffer.
+ &dwBytes, // bytes returned.
+ 0, // Overlapped.
+ 0) == -1) // Func.
+ ACE_ERROR ((LM_ERROR,
+ "Error in Loopback ACE_OS::ioctl() \n"));
+ else
+ ACE_DEBUG ((LM_DEBUG,
+ "Disable Loopback with ACE_OS::ioctl call succeeds \n"));
+
+ // This is a sender.
+ qos_session->flags (ACE_QoS_Session::ACE_QOS_SENDER);
- ACE_OS::free (protocol_buffer);
+ ACE_QoS_Manager qos_manager = dgram_mcast_qos.qos_manager ();
- } // protocol_buffer
+ // Since we are using RSVP, it is imperative that the client
+ // application have the option of supplying the source sender
+ // port for the RSVP messages. A default will be chosen by the
+ // ACE API if this is not done.
+ qos_session->source_port (qos_util.source_port ());
+
+ // Set the QoS for the session. Replaces the ioctl () call that
+ // was being made previously.
+ if (qos_session->qos (&dgram_mcast_qos,
+ &qos_manager,
+ ace_qos_sender) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Unable to set QoS\n"),
+ -1);
+ else
+ ACE_DEBUG ((LM_DEBUG,
+ "Setting QOS succeeds.\n"));
+
+ // Register a signal handler that helps to gracefully close the open
+ // QoS sessions.
+ QoS_Signal_Handler qos_signal_handler (qos_session);
+
+ // Register the usual SIGINT signal handler with the Reactor for
+ // the application to gracefully release the QoS session and
+ // shutdown.
+ if (ACE_Reactor::instance ()->register_handler
+ (SIGINT, &qos_signal_handler) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Error in registering the Signal Handler.\n"),
+ -1);
- } // ACE_OS::enum_protocols ().
+ // Handler to process QoS and Data events for the reciever.
+ Sender_QoS_Event_Handler qos_event_handler (dgram_mcast_qos,
+ qos_session);
- if (bProtocolFound)
- ACE_DEBUG ((LM_DEBUG,
- "\n Using service provider <%s>\n\n",
- pProtocolInfo->szProtocol));
+ // Decorate the above handler with QoS functionality.
+ ACE_QoS_Decorator qos_decorator (&qos_event_handler,
+ qos_session);
- return bProtocolFound;
+ // Initialize the Decorator.
+ if (qos_decorator.init () != 0)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "QoS Decorator init () failed.\n"),
+ -1);
-}
+ // Register the decorated Event Handler with the Reactor.
+ if (ACE_Reactor::instance ()->register_handler (&qos_decorator,
+ ACE_Event_Handler::QOS_MASK |
+ ACE_Event_Handler::READ_MASK) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Error in registering the Decorator with the Reactor\n"),
+ -1);
-int
-ValidOptions (char *argv[],
- int argc,
- OPTIONS *pOptions)
-{
- *pOptions = default_options;
- for (int i = 1; i < argc; i++)
- {
- if (argv[i][0] == '-' || argv[i][0] == '/')
- {
- switch (ACE_OS::to_lower (argv[i][1]))
- {
- case 'b' :
- if (ACE_OS::strlen (argv[i]) > 3)
- pOptions->nBufSize = 1024 * ACE_OS::atoi (&argv[i][3]);
- break;
-
- case 'c' :
- pOptions->qosOptions.bAlternateQos = TRUE;
- break;
-
- case 'd' :
- if (ACE_OS::strlen (argv[i]) > 3)
- pOptions->fillchar = argv[i][3];
- break;
-
- case 'e' :
- if (ACE_OS::strlen (argv[i]) > 3)
- pOptions->port = ACE_OS::atoi (&argv[i][3]);
- break;
-
- case 'i' :
- if (ACE_OS::strlen (argv[i]) > 3)
- {
- if ('a' == argv[i][3] || 'A' == argv[i][3])
- pOptions->qosOptions.qosIoctlSet = QOS_IOCTL_SET_AFTER;
- else if ('b' == argv[i][3] || 'B' == argv[i][3])
- pOptions->qosOptions.qosIoctlSet = QOS_IOCTL_SET_BEFORE;
- else if ('d' == argv[i][3] || 'D' == argv[i][3])
- pOptions->qosOptions.qosIoctlSet = QOS_IOCTL_SET_DURING;
- else if ('q' == argv[i][3] || 'Q' == argv[i][3])
- pOptions->qosOptions.qosIoctlSet = QOS_IOCTL_SET_QOS;
- else
- pOptions->qosOptions.qosIoctlSet = QOS_IOCTL_SET_BEFORE;
- }
- break;
-
- case 'l' :
- if (ACE_OS::strlen (argv[i]) > 3)
- pOptions->nRepeat = ACE_OS::atoi (&argv[i][3]);
- break;
-
- case 'm' :
- pOptions->spOptions.bMulticast = TRUE;
- if (ACE_OS::strlen (argv[i]) > 3)
- ACE_OS::strcpy (pOptions->szHostname,
- &argv[i][3]);
- else
- ACE_OS::strcpy (pOptions->szHostname,
- DEFAULT_MULTICASTGROUP);
- break;
-
- case 'n' :
- pOptions->qosOptions.bReceiver = FALSE;
- // multicast group overrides hostname on -n
- if (!pOptions->spOptions.bMulticast
- && ACE_OS::strlen (argv[i]) > 3)
- ACE_OS::strcpy (pOptions->szHostname,
- &argv[i][3]);
- break;
-
- case 'p' :
- if (ACE_OS::strlen (argv[i]) > 3)
- {
- if ('u' == argv[i][3] || 'U' == argv[i][3])
- pOptions->spOptions.iProtocol = IPPROTO_UDP;
- else if ('t' == argv[i][3] || 'T' == argv[i][3])
- pOptions->spOptions.iProtocol = IPPROTO_TCP;
- else
- pOptions->spOptions.iProtocol = IPPROTO_TCP;
- }
- break;
-
- case 'q' :
- pOptions->spOptions.bQos = TRUE;
- if (ACE_OS::strlen (argv[i]) > 3)
- ACE_OS::strcpy (pOptions->qosOptions.szTemplate,
- &argv[i][3]);
- break;
-
- case 'r' :
- if (ACE_OS::strlen (argv[i]) > 3)
- {
- if (ACE_OS::strcasecmp (argv[i],
- "-rsvp-confirm") == 0
- || ACE_OS::strcasecmp (argv[i],
- "-rsvp_confirm") == 0)
- {
- pOptions->qosOptions.bConfirmResv = TRUE;
- pOptions->qosOptions.bProviderSpecific = TRUE;
- }
- else if (ACE_OS::strcasecmp (argv[i],
- "-rsvp-wait") == 0
- || ACE_OS::strcasecmp (argv[i],
- "-rsvp_wait") == 0)
- {
- pOptions->qosOptions.bWaitToSend = TRUE;
- pOptions->qosOptions.bProviderSpecific = TRUE;
- }
- else
- ACE_DEBUG ((LM_DEBUG,
- "Ignoring option <%s>\n",
- argv[i]));
- }
- break;
-
- case 's' :
- if (ACE_OS::strlen (argv[i]) > 3)
- pOptions->dwSleep =
- ACE_OS::atoi (&argv[i][3]);
- break;
-
- case '?' :
- Usage (argv[0],
- &default_options);
- return FALSE;
- break;
-
- default:
- ACE_DEBUG ((LM_DEBUG,
- " unknown options flag %s\n",
- argv[i]));
- Usage (argv[0],
- &default_options);
- return FALSE;
- break;
- }
- }
- else
- {
- ACE_DEBUG ((LM_DEBUG,
- " unknown option %s\n",
- argv[i]));
- Usage (argv[0],
- &default_options);
- return FALSE;
- }
- }
+// // Instantiate a QOS Event Handler and pass the Dgram_Mcast and QoS
+// // session object into it.
+// ACE_QOS_Event_Handler qos_event_handler (dgram_mcast_qos,
+// qos_session);
- if (pOptions->qosOptions.bReceiver)
- pOptions->fillchar = 0;
+// ACE_RAPI_Event_Handler rapi_event_handler (qos_session);
- if (pOptions->spOptions.bMulticast)
- {
- pOptions->spOptions.iProtocol = IPPROTO_UDP;
- pOptions->qosOptions.bSetDestaddr = FALSE;
+// // Register the RAPI Event Handler with the Reactor. This
+// // handles the QoS events.
+// if (ACE_Reactor::instance ()->register_handler
+// (&rapi_event_handler,
+// ACE_Event_Handler::QOS_MASK | ACE_Event_Handler::READ_MASK) == -1)
+// ACE_ERROR_RETURN ((LM_ERROR,
+// "Error in registering the RAPI Event Handler\n"),
+// -1);
+
+ // Start the event loop.
+ ACE_DEBUG ((LM_DEBUG,
+ "Running the Event Loop ... \n"));
+
+ ACE_Reactor::instance ()->run_event_loop ();
+
+ ACE_DEBUG ((LM_DEBUG,
+ "(%P|%t) shutting down server logging daemon\n"));
}
+ else
+ ACE_DEBUG ((LM_DEBUG,
+ "Specify a -m option for multicast application\n"));
+ return 0;
+}
+
- if (IPPROTO_TCP == pOptions->spOptions.iProtocol)
- {
- pOptions->spOptions.bMulticast = FALSE;
- pOptions->qosOptions.bSetDestaddr = FALSE;
- }
- else if (!pOptions->spOptions.bMulticast)
- pOptions->qosOptions.bSetDestaddr = TRUE;
- if (pOptions->spOptions.bQos)
- {
- if (pOptions->qosOptions.bReceiver
- && pOptions->qosOptions.bWaitToSend)
- pOptions->qosOptions.bWaitToSend = FALSE;
- // not a valid receiver option
-
- if (!pOptions->qosOptions.bReceiver
- && pOptions->qosOptions.bConfirmResv)
- pOptions->qosOptions.bWaitToSend = FALSE;
- // not a valid sender option
-
- if (pOptions->qosOptions.bAlternateQos)
- // override repeat count to continuous mode
- pOptions->nRepeat = 0;
-
- if (IPPROTO_UDP == pOptions->spOptions.iProtocol
- && !pOptions->spOptions.bMulticast)
- // Using UDP, there WSAAccept will not be called, therefore
- // do not wait to set qos.
- pOptions->qosOptions.qosIoctlSet =
- QOS_IOCTL_SET_BEFORE;
-
- pOptions->qosOptions.bFineGrainErrorAvail = TRUE;
- pOptions->qosOptions.bQosabilityIoctls = TRUE;
- ACE_DEBUG ((LM_DEBUG,
- "running on NT\n"));
- }
- if (pOptions->nBufSize > 0)
- ACE_NEW_RETURN (pOptions->buf,
- char[pOptions->nBufSize],
- 0);
- else
- ACE_ERROR_RETURN ((LM_ERROR,
- "Buffer size to be allocated is less than or"
- "equal to zero\n"),
- -1);
- if (pOptions->buf == 0)
- return FALSE;
- else
- {
- ACE_OS::memset (pOptions->buf,
- pOptions->fillchar,
- pOptions->nBufSize);
- return TRUE;
- }
-}
-// Print out usage table for the program.
-void
-Usage (char *szProgramname,
- OPTIONS *pOptions)
-{
- ACE_DEBUG ((LM_DEBUG,
- "usage:\n %s -?\n\n"
- " %s [-b:#] [-d:c] [-e:#] [-l:#] [-m:group] "
- "[-n:host] [-s:#] [-u]\n\t[-q:template [-i:[a|b|d|q]]"
- "[-c] [-rsvp-confirm] [-rsvp-wait]]\n\n",
- " -?\t\tDisplay this help\n\n"
- " -b:bufsize\tSize of send/recv buffer; in 1K increments (Def:%d)\n"
- " -d:c\t\tCharacter used to fill buffer (Def:%c)\n"
- " -e:port\tEndpoint number (port) to use (Def:%d)\n"
- " -l:loop\tLoop count for sending buffer (0==>continuous)\n"
- " -m:group\tMulticast group (IP) to join (Def:%s)\n"
- " -n:host\tAct as the client and connect to 'host' (Def:%s)\n"
- " -p:protocol\tTCP or UDP (def:TCP)\n"
- " -s:#\t\tSleep # milliseconds between sends (def: 0)\n"
- " -q:template\tEnable QoS and use 'template' to specify the name (Def:%s)\n"
- " -c\t\tCycle enabling/disabling QOS on sending socket (Def: no cycling)\n"
- " -i:[a|b|d|q]\tSet Qos After, Before, During accept/connect, or during FD_QOS\n\t\t\t(def: Before)\n"
- " -rsvp-confirm\t\tRequest RESV confirmation be sent (Def: no confirmation)\n"
- " -rsvp-wait\t\tWait for RESV from receiver before sending data\n",
- szProgramname,
- szProgramname,
- pOptions->nBufSize,
- pOptions->fillchar,
- pOptions->port,
- pOptions->nRepeat,
- DEFAULT_MULTICASTGROUP,
- pOptions->szHostname,
- pOptions->qosOptions.szTemplate));
- return;
-}
diff --git a/examples/QOS/client.dsp b/examples/QOS/client.dsp
index 9b53d073de0..a32951cbc01 100644
--- a/examples/QOS/client.dsp
+++ b/examples/QOS/client.dsp
@@ -39,11 +39,9 @@ RSC=rc.exe
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
-# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FD /c
-# SUBTRACT CPP /YX
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\.." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
@@ -51,7 +49,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 ace.lib /nologo /subsystem:console /machine:I386 /libpath:"../../ace"
+# ADD LINK32 ace.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\ace"
!ELSEIF "$(CFG)" == "003 - Win32 Debug"
@@ -62,13 +60,12 @@ LINK32=link.exe
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
-# PROP Output_Dir ""
+# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MDd /W3 /GX /Od /I "../../" /D "WIN32" /D "_DEBUG" /FD /c
-# SUBTRACT CPP /YX
+# ADD CPP /nologo /MDd /W3 /GX /Od /I "d:\vishal\ACE_wrappers" /D "WIN32" /D "_DEBUG" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
@@ -76,7 +73,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 aced.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"../../ace"
+# ADD LINK32 d:\vishal\ACE_wrappers\ace\aced.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"d:\vishal\ACE_wrappers\ace"
!ENDIF
diff --git a/examples/QOS/server.cpp b/examples/QOS/server.cpp
index 6cef1314cfd..73974621059 100644
--- a/examples/QOS/server.cpp
+++ b/examples/QOS/server.cpp
@@ -16,22 +16,17 @@
#define QOSEVENT_MAIN
-#include "ace/SOCK_Dgram_Mcast_QoS.h"
#include "ace/OS.h"
-#include "ace/QoS_Session_Factory.h"
#include "ace/QoS_Session.h"
+#include "ace/QoS_Session_Factory.h"
+#include "ace/QoS_Decorator.h"
+#include "ace/SOCK_Dgram_Mcast_QoS.h"
-#include "QosEvent.h"
-#include "Receiver_QOS_Event_Handler.h"
+#include "QoS_Util.h"
+#include "Fill_ACE_QoS.h"
+#include "QoS_Signal_Handler.h"
+#include "Receiver_QoS_Event_Handler.h"
-static int ValidOptions (char *argv[],
- int argc,
- OPTIONS *pOptions);
-static void Usage (char *szProgramname,
- OPTIONS *pOptions);
-
-static const u_short PORT = ACE_DEFAULT_SERVER_PORT;
-
// To open QOS sockets administrative access is required on the
// machine. Fill in default values for QoS structure. The default
// values were simply choosen from existing QOS templates available
@@ -42,90 +37,9 @@ static const u_short PORT = ACE_DEFAULT_SERVER_PORT;
// depending upon whether this application is acting as a sender or
// receiver.
-static int
-fill_ace_qos_flowspec_default (ACE_QoS *pQos,
- QOS_OPTIONS *pQosOptions)
-{
- ACE_Flow_Spec ace_default_g711 (9200,
- 708,
- 18400,
- 0,
- 0,
- ACE_SERVICETYPE_GUARANTEED,
- // SERVICETYPE_CONTROLLEDLOAD
- // doesnt work here for a yet unknown
- // reason.
- 368,
- 368,
- 25, // TTL. ACE specific. Not used on NT.
- 1 // Priority. ACE specific. Not used on NT.
- );
-
- ACE_Flow_Spec ace_default_notraffic (ACE_QOS_NOT_SPECIFIED,
- ACE_QOS_NOT_SPECIFIED,
- ACE_QOS_NOT_SPECIFIED,
- ACE_QOS_NOT_SPECIFIED,
- ACE_QOS_NOT_SPECIFIED,
- ACE_SERVICETYPE_NOTRAFFIC,
- ACE_QOS_NOT_SPECIFIED,
- ACE_QOS_NOT_SPECIFIED,
- 25, // TTL. ACE specific. Not used on NT.
- 1); // Priority. ACE specific. Not used on NT.
- if (pQosOptions->bReceiver)
- {
- pQos->receiving_flowspec (ace_default_g711);
- pQos->sending_flowspec (ace_default_notraffic);
- }
- else
- {
- pQos->sending_flowspec (ace_default_g711);
- pQos->receiving_flowspec (ace_default_notraffic);
- }
-
- const iovec iov = {0, 0};
- pQos->provider_specific (iov);
-
- return 0;
-}
-
-int SetQos (QOS_OPTIONS *pQosOptions,
- ACE_QoS *pQos)
-{
- int bError = FALSE;
-
- // fill in default values
- if (ACE_OS::strcasecmp (pQosOptions->szTemplate,
- QOS_DEFAULTNAME) == 0)
- fill_ace_qos_flowspec_default (pQos,
- pQosOptions);
- else
- ACE_DEBUG ((LM_DEBUG,
- "Run the program with -q:default option\n"));
-
- return !bError;
-}
-
-// Fill up the ACE_Flow_Spec with the default_g711 values
-// as defined in the QoSEvent.h
-
-int
-FillQoSTraffic (ACE_Flow_Spec &afc)
-{
- afc = default_g711;
- return 0;
-}
-// Fill up the ACE_Flow_Spec with the default_notraffic values
-// as defined in the QoSEvent.h
-
-int
-FillQoSNoTraffic (ACE_Flow_Spec &afc)
-{
- afc = default_notraffic;
- return 0;
-}
-
-// This function fills up the ACE_QoS_Params with the supplied iovec and ACE_QoS.
+// This function fills up the ACE_QoS_Params with the supplied iovec
+// and ACE_QoS.
int
FillQoSParams (ACE_QoS_Params &qos_params,
@@ -144,617 +58,268 @@ FillQoSParams (ACE_QoS_Params &qos_params,
int
main (int argc, char * argv[])
{
- ACE_Protocol_Info *pinfo=0;
-
- OPTIONS options;
-
- if (!ValidOptions (argv,
- argc,
- &options))
- ACE_ERROR_RETURN ((LM_ERROR,
- "Error in ValidOptions\n"),
- -1);
-
- // XX pinfo = &protocol_info;
- // XX FindServiceProvider is not needed by RSVP
- // XX if (FindServiceProvider (options.spOptions.iProtocol,
- // XX options.spOptions.bQos,
- // XX options.spOptions.bMulticast,
- // XX pinfo) == FALSE)
- // XX ACE_ERROR_RETURN ((LM_ERROR,
- // XX "Error in FindServiceProvider\n"),
- // XX -1);
-
- ACE_QoS qos;
-
- // By default the QOS is set as QOS_IOCTL_SET_BEFORE.
- if (options.spOptions.bQos)
- {
- if (QOS_IOCTL_SET_BEFORE == options.qosOptions.qosIoctlSet)
- {
- if (SetQos (&options.qosOptions,
- &qos))
- ACE_DEBUG ((LM_DEBUG,
- " QOS set before accept\n"));
- }
- else if (QOS_IOCTL_SET_QOS == options.qosOptions.qosIoctlSet)
- {
- options.qosOptions.bDisableSignalling = TRUE;
- if (SetQos (&options.qosOptions,
- &qos))
- ACE_DEBUG ((LM_DEBUG,
- " QOS set qos before accept - will be "
- "set again in FD_QOS\n"));
- }
- }
-
- else
- ACE_ERROR_RETURN ((LM_ERROR,
- "Use the -q:default option to enable the QOS\n"),
- -1);
-
- // Opening a new Multicast Datagram.
- ACE_SOCK_Dgram_Mcast_QoS dgram_mcast;
-
- // The windows example code uses PF_INET for the address family.
- // Winsock.h defines PF_INET to be AF_INET. The following
- // code internally uses AF_INET as a default for the underlying socket.
-
- ACE_INET_Addr mult_addr (options.port,
- options.szHostname);
-
- // Fill the ACE_QoS_Params to be passed to the <ACE_OS::join_leaf>
- // through subscribe.
-
- ACE_QoS_Params qos_params;
- FillQoSParams (qos_params, 0, &qos);
-
- // Create a QoS Session Factory.
- ACE_QoS_Session_Factory session_factory;
-
- // Ask the factory to create a QoS session. This could be RAPI or
- // GQoS based on the parameter passed.
- ACE_QoS_Session *qos_session =
- session_factory.create_session (ACE_QoS_Session_Factory::ACE_RAPI_SESSION);
-// XX Shouldn't have to specify GQOS or RAPI?!?
-// XX it is not clear that we need to pass in a key indicating the type
-// XX of object to create. Since we use RAPI flag at compile time can
-// XX we assume rapi here also? Or could we have RAPI and GQoS?
-
- // Create a destination address for the QoS session. The same
- // address should be used for the subscribe call later. A copy is
- // made below only to distinguish the two usages of the dest
- // address.
-
- ACE_INET_Addr dest_addr (mult_addr);
- // A QoS session is defined by the 3-tuple [DestAddr, DestPort,
- // Protocol]. Initialize the QoS session.
- if (qos_session->open (mult_addr,
- IPPROTO_UDP) == -1)
- ACE_ERROR_RETURN ((LM_ERROR,
- "Error in opening the QoS session\n"),
- -1);
+ QoS_Util qos_util(argc, argv);
- // The following call opens the Dgram_Mcast and calls the
- // <ACE_OS::join_leaf> with the qos_params supplied here. Note the
- // QoS session object is passed into this call. This subscribes the
- // underlying socket to the passed in QoS session. For joining
- // multiple multicast sessions, the following subscribe call should
- // be made with different multicast addresses and a new QoS session
- // object should be passed in for each such call. The QoS session
- // objects can be created only through the session factory. Care
- // should be taken that the mult_addr for the subscribe() call
- // matches the dest_addr of the QoS session object. If this is not
- // done, the subscribe call will fail. A more abstract version of
- // subscribe will be added that constrains the various features of
- // GQoS like different flags etc.
-
- ACE_QoS_Manager *ace_qos_manager = 0;
-
- if (dgram_mcast.subscribe (mult_addr,
- qos_params,
- 1,
- 0,
- AF_INET,
- // ACE_FROM_PROTOCOL_INFO,
- 0,
- pinfo,
- 0,
- ACE_OVERLAPPED_SOCKET_FLAG
- | ACE_FLAG_MULTIPOINT_C_LEAF
- | ACE_FLAG_MULTIPOINT_D_LEAF) == -1)
- ACE_ERROR_RETURN ((LM_ERROR,
- "Error in subscribe\n"),
- -1);
- else
- ACE_DEBUG ((LM_DEBUG,
- "Dgram_Mcast subscribe succeeds \n"));
-
- int nIP_TTL = 25;
- char achInBuf [BUFSIZ];
- u_long dwBytes;
-
- // Should this be abstracted into QoS objects ?? Doesnt seem to have
- // to do anything directly with QoS.
- if (ACE_OS::ioctl (dgram_mcast.get_handle (), // Socket.
- ACE_SIO_MULTICAST_SCOPE, // IO control code.
- &nIP_TTL, // In buffer.
- sizeof (nIP_TTL), // Length of in buffer.
- achInBuf, // Out buffer.
- BUFSIZ, // Length of Out buffer.
- &dwBytes, // bytes returned.
- 0, // Overlapped.
- 0) == -1) // Func.
- ACE_ERROR ((LM_ERROR,
- "Error in Multicast scope ACE_OS::ioctl() \n"));
- else
- ACE_DEBUG ((LM_DEBUG,
- "Setting TTL with Multicast scope ACE_OS::ioctl call succeeds \n"));
-
- int bFlag = FALSE;
-
- // Should this be abstracted into QoS objects ?? Doesnt seem to have
- // to do anything directly with QoS.
- if (ACE_OS::ioctl (dgram_mcast.get_handle (), // Socket.
- ACE_SIO_MULTIPOINT_LOOPBACK, // IO control code.
- &bFlag, // In buffer.
- sizeof (bFlag), // Length of in buffer.
- achInBuf, // Out buffer.
- BUFSIZ, // Length of Out buffer.
- &dwBytes, // bytes returned.
- 0, // Overlapped.
- 0) == -1) // Func.
- ACE_ERROR ((LM_ERROR,
- "Error in Loopback ACE_OS::ioctl() \n"));
- else
- ACE_DEBUG ((LM_DEBUG,
- "Disable Loopback with ACE_OS::ioctl call succeeds \n"));
-
- // Fill up an ACE_QoS and pass it to the overloaded ACE_OS::ioctl ()
- // that uses the I/O control code as SIO_SET_QOS.
- ACE_QoS ace_qos;
-
- // Make sure the flowspec is set in the correct direction for the
- // sender/client.
- ACE_Flow_Spec sending_flowspec;
- ACE_Flow_Spec receiving_flowspec;
- const iovec iov = {0, 0};
-
- FillQoSTraffic (receiving_flowspec);
- FillQoSNoTraffic (sending_flowspec);
-
- ace_qos.sending_flowspec (sending_flowspec);
- ace_qos.receiving_flowspec (receiving_flowspec);
- ace_qos.provider_specific (iov);
-
- // Set the QoS for the session. Replaces the ioctl () call that was
- // being made previously.
- if (qos_session->qos (&dgram_mcast,
- ace_qos_manager,
- ace_qos) == -1)
- ACE_ERROR_RETURN ((LM_ERROR,
- "Unable to set QoS\n"),
- -1);
- else
- ACE_DEBUG ((LM_DEBUG,
- "Setting QOS succeeds.\n"));
-
- // Instantiate a QOS Event Handler and pass the Dgram_Mcast and QoS
- // session object into it.
- ACE_QOS_Event_Handler qos_event_handler (dgram_mcast,
- qos_session);
-
- // Register the QOS Handler with the Reactor.
- if (ACE_Reactor::instance ()->register_handler
- (&qos_event_handler,
- ACE_Event_Handler::QOS_MASK | ACE_Event_Handler::READ_MASK) == -1)
+ if (qos_util.parse_args () == -1)
ACE_ERROR_RETURN ((LM_ERROR,
- "Error in registering QOS Handler\n"),
+ "Error in parsing args\n"),
-1);
- // Start the event loop.
- ACE_DEBUG ((LM_DEBUG,
- "Running the Event Loop ... \n"));
-
- ACE_Reactor::instance ()->run_event_loop ();
-
- ACE_DEBUG ((LM_DEBUG,
- "(%P|%t) shutting down server logging daemon\n"));
- return 0;
-}
-
-int
-FindServiceProvider(int iProtocol,
- int bQos,
- int bMulticast,
- ACE_Protocol_Info *pProtocolInfo)
-{
- ACE_Protocol_Info *protocol_buffer = 0;
- u_long buffer_length = 0;
- u_long dwErr;
- int bProtocolFound = FALSE;
-
- // first have enum_protocols () tell us how big a buffer is needed.
- int ret_val = ACE_OS::enum_protocols (0,
- protocol_buffer,
- &buffer_length);
- if (ret_val != -1)
- ACE_DEBUG ((LM_DEBUG,
- "enum_protocols () : should not have suceeded\n"));
-
- else if (ACE_ENOBUFS != (dwErr = ACE_OS::set_errno_to_wsa_last_error ()))
- // enum_protocols () failed for some reason not relating to buffer size
- ACE_DEBUG ((LM_DEBUG,
- "enum_protocols () : failed for a reason other than "
- "inadequate buffer size : %d\n",
- ACE_OS::set_errno_to_wsa_last_error ()));
- else
+ // This is a multicast application.
+ if (qos_util.multicast_flag ())
{
- if (buffer_length > 0)
- {
- void *ptr = 0;
- ACE_NEW_RETURN (ptr,
- char [buffer_length],
- 0);
- protocol_buffer = (ACE_Protocol_Info *) ptr;
- }
-
+ Fill_ACE_QoS fill_ace_qos;
+
+ // The application adds the flow specs that it wants into the
+ // Fill_ACE_QoS. The Fill_ACE_QoS indexes the flow specs by the
+ // flow spec names. Here the new flowspec being added is g_711.
+ ACE_CString g_711 ("g_711");
+
+ switch (fill_ace_qos.map ().bind (g_711,
+ new ACE_Flow_Spec (9200,
+ 708,
+ 18400,
+ 0,
+ 0,
+ ACE_SERVICETYPE_CONTROLLEDLOAD,
+ 368,
+ 368,
+ 25,
+ 1)))
+ {
+ case 1 :
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Unable to bind the new flow spec\n"
+ "The Flow Spec name already exists\n"),
+ -1);
+ break;
+ case -1 :
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Unable to bind the new flow spec\n"),
+ -1);
+ break;
+ }
+
+ ACE_DEBUG ((LM_DEBUG,
+ "g_711 Flow Spec bound successfully\n"));
+
+ // This is a receiver. So we fill in the receiving QoS parameters.
+ ACE_QoS ace_qos_receiver;
+ if (fill_ace_qos.fill_simplex_receiver_qos (ace_qos_receiver,
+ g_711) !=0)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Unable to fill simplex receiver qos\n"),
+ -1);
+ else
+ ACE_DEBUG ((LM_DEBUG,
+ "Filled up the Receiver QoS parameters\n"));
+
+ // Opening a new Multicast Datagram.
+ ACE_SOCK_Dgram_Mcast_QoS dgram_mcast_qos;
+
+ // Multicast Session Address specified by user at command line.
+ // If this address is not specified,
+ // <localhost:ACE_DEFAULT_MULTICAST_PORT> is assumed.
+ ACE_INET_Addr mult_addr (*(qos_util.mult_session_addr ()));
+
+ // Fill the ACE_QoS_Params to be passed to the <ACE_OS::join_leaf>
+ // through subscribe.
+
+ ACE_QoS_Params qos_params;
+ FillQoSParams (qos_params, 0, &ace_qos_receiver);
+
+ // Create a QoS Session Factory.
+ ACE_QoS_Session_Factory session_factory;
+
+ // Ask the factory to create a QoS session. This could be RAPI or
+ // GQoS based on the parameter passed.
+ ACE_QoS_Session *qos_session =
+ session_factory.create_session (ACE_QoS_Session_Factory::ACE_RAPI_SESSION);
+ // XX Shouldn't have to specify GQOS or RAPI?!? XX it is not
+ // clear that we need to pass in a key indicating the type XX of
+ // object to create. Since we use RAPI flag at compile time can
+ // XX we assume rapi here also? Or could we have RAPI and GQoS?
+
+ // Create a destination address for the QoS session. The same
+ // address should be used for the subscribe call later. A copy
+ // is made below only to distinguish the two usages of the dest
+ // address.
+
+ ACE_INET_Addr dest_addr (mult_addr);
+
+ // A QoS session is defined by the 3-tuple [DestAddr, DestPort,
+ // Protocol]. Initialize the QoS session.
+ if (qos_session->open (mult_addr,
+ IPPROTO_UDP) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Error in opening the QoS session\n"),
+ -1);
else
+ ACE_DEBUG ((LM_DEBUG,
+ "QoS session opened successfully\n"));
+
+ // The following call opens the Dgram_Mcast and calls the
+ // <ACE_OS::join_leaf> with the qos_params supplied here. Note
+ // the QoS session object is passed into this call. This
+ // subscribes the underlying socket to the passed in QoS
+ // session. For joining multiple multicast sessions, the
+ // following subscribe call should be made with different
+ // multicast addresses and a new QoS session object should be
+ // passed in for each such call. The QoS session objects can be
+ // created only through the session factory. Care should be
+ // taken that the mult_addr for the subscribe() call matches the
+ // dest_addr of the QoS session object. If this is not done, the
+ // subscribe call will fail. A more abstract version of
+ // subscribe will be added that constrains the various features
+ // of GQoS like different flags etc.
+
+ if (dgram_mcast_qos.subscribe (mult_addr,
+ qos_params,
+ 1,
+ 0,
+ AF_INET,
+ // ACE_FROM_PROTOCOL_INFO,
+ 0,
+ 0, // ACE_Protocol_Info,
+ 0,
+ ACE_OVERLAPPED_SOCKET_FLAG
+ | ACE_FLAG_MULTIPOINT_C_LEAF
+ | ACE_FLAG_MULTIPOINT_D_LEAF,
+ qos_session) == -1)
ACE_ERROR_RETURN ((LM_ERROR,
- "Buffer length returned by enum_protocols () is"
- "less than or equal to zero\n"),
+ "Error in subscribe\n"),
-1);
+ else
+ ACE_DEBUG ((LM_DEBUG,
+ "Dgram_Mcast subscribe succeeds \n"));
- if (protocol_buffer)
- {
- // now we can call enum_protocols () again with the
- // expectation it will succeed because we have allocated a
- // big enough buffer.
- ret_val = ACE_OS::enum_protocols (0,
- protocol_buffer,
- &buffer_length);
- if (ret_val == -1)
- ACE_DEBUG ((LM_DEBUG,
- "enum_protocols () : failed even after allocating"
- " a big enough buffer : %d\n",
- ACE_OS::set_errno_to_wsa_last_error ()));
- else
- {
- ACE_DEBUG ((LM_DEBUG,
- "Size allocated for the Protocol Buffer = %d\n"
- "\nList of transport protocols "
- "returned by enum_protocols () : \n",
- buffer_length));
-
- // Loop thru protocols, looking for a matching service
- // provider.
- for (int i = 0; i < ret_val; i++)
- {
- ACE_DEBUG ((LM_DEBUG,
- " sp <%s>\n",
- protocol_buffer[i].szProtocol));
-
- if (AF_INET == protocol_buffer[i].iAddressFamily
- && iProtocol == protocol_buffer[i].iProtocol)
- {
- // look for
- if (bQos && bMulticast)
- {
- if ((ACE_XP1_QOS_SUPPORTED == ((ACE_XP1_QOS_SUPPORTED
- & protocol_buffer[i].dwServiceFlags1)))
- && (ACE_XP1_SUPPORT_MULTIPOINT == (ACE_XP1_SUPPORT_MULTIPOINT &
- protocol_buffer[i].dwServiceFlags1)))
- {
- *pProtocolInfo = protocol_buffer[i];
- bProtocolFound = TRUE;
- break;
- }
- }
- else if (bQos)
- {
- if (ACE_XP1_QOS_SUPPORTED == (ACE_XP1_QOS_SUPPORTED
- & protocol_buffer[i].dwServiceFlags1))
- {
- *pProtocolInfo = protocol_buffer[i];
- bProtocolFound = TRUE;
- break;
- }
- }
- else if (bMulticast)
- {
- if ((ACE_XP1_SUPPORT_MULTIPOINT == (ACE_XP1_SUPPORT_MULTIPOINT &
- protocol_buffer[i].dwServiceFlags1))
- && (ACE_XP1_QOS_SUPPORTED != (ACE_XP1_QOS_SUPPORTED &
- protocol_buffer[i].dwServiceFlags1)))
- {
- *pProtocolInfo = protocol_buffer[i];
- bProtocolFound = TRUE;
- break;
- }
- }
- else if ((ACE_XP1_QOS_SUPPORTED != (ACE_XP1_QOS_SUPPORTED
- & protocol_buffer[i].dwServiceFlags1)))
- {
- *pProtocolInfo = protocol_buffer[i];
- bProtocolFound = TRUE;
- break;
- }
- }
-
- } // for loop.
-
- } // ACE_OS::enum_protocols ().
+ int nIP_TTL = 25;
+ char achInBuf [BUFSIZ];
+ u_long dwBytes;
+
+ // Should this be abstracted into QoS objects ?? Doesnt seem to have
+ // to do anything directly with QoS.
+ if (ACE_OS::ioctl (dgram_mcast_qos.get_handle (), // Socket.
+ ACE_SIO_MULTICAST_SCOPE, // IO control code.
+ &nIP_TTL, // In buffer.
+ sizeof (nIP_TTL), // Length of in buffer.
+ achInBuf, // Out buffer.
+ BUFSIZ, // Length of Out buffer.
+ &dwBytes, // bytes returned.
+ 0, // Overlapped.
+ 0) == -1) // Func.
+ ACE_ERROR ((LM_ERROR,
+ "Error in Multicast scope ACE_OS::ioctl() \n"));
+ else
+ ACE_DEBUG ((LM_DEBUG,
+ "Setting TTL with Multicast scope ACE_OS::ioctl call succeeds \n"));
- ACE_OS::free (protocol_buffer);
+ int bFlag = 0;
- } // protocol_buffer
-
- } // ACE_OS::enum_protocols ().
-
- if (bProtocolFound)
- ACE_DEBUG ((LM_DEBUG,
- "\n Using service provider <%s>\n\n",
- pProtocolInfo->szProtocol));
-
- return bProtocolFound;
-
-}
-
-int
-ValidOptions (char *argv[],
- int argc,
- OPTIONS *pOptions)
-{
- *pOptions = default_options;
-
- for (int i = 1; i < argc; i++)
- {
- if ((argv[i][0] == '-') || (argv[i][0] == '/') )
- {
- switch (ACE_OS::to_lower (argv[i][1]))
- {
- case 'b' :
- if (ACE_OS::strlen (argv[i]) > 3)
- pOptions->nBufSize = 1024 * ACE_OS::atoi (&argv[i][3]);
- break;
-
- case 'c' :
- pOptions->qosOptions.bAlternateQos = TRUE;
- break;
-
- case 'd' :
- if (ACE_OS::strlen (argv[i]) > 3)
- pOptions->fillchar = argv[i][3];
- break;
-
- case 'e' :
- if (ACE_OS::strlen (argv[i]) > 3)
- pOptions->port = ACE_OS::atoi (&argv[i][3]);
- break;
-
- case 'i' :
- if (ACE_OS::strlen (argv[i]) > 3)
- {
- if ('a' == argv[i][3] || 'A' == argv[i][3])
- pOptions->qosOptions.qosIoctlSet = QOS_IOCTL_SET_AFTER;
- else if ('b' == argv[i][3] || 'B' == argv[i][3])
- pOptions->qosOptions.qosIoctlSet = QOS_IOCTL_SET_BEFORE;
- else if ('d' == argv[i][3] || 'D' == argv[i][3])
- pOptions->qosOptions.qosIoctlSet = QOS_IOCTL_SET_DURING;
- else if ('q' == argv[i][3] || 'Q' == argv[i][3])
- pOptions->qosOptions.qosIoctlSet = QOS_IOCTL_SET_QOS;
- else
- pOptions->qosOptions.qosIoctlSet = QOS_IOCTL_SET_BEFORE;
- }
- break;
-
- case 'l' :
- if (ACE_OS::strlen (argv[i]) > 3)
- pOptions->nRepeat = ACE_OS::atoi (&argv[i][3]);
- break;
-
- case 'm' :
- pOptions->spOptions.bMulticast = TRUE;
- if (ACE_OS::strlen (argv[i]) > 3)
- ACE_OS::strcpy (pOptions->szHostname,
- &argv[i][3]);
- else
- ACE_OS::strcpy (pOptions->szHostname,
- DEFAULT_MULTICASTGROUP);
- break;
-
- case 'n' :
- pOptions->qosOptions.bReceiver = FALSE;
- // multicast group overrides hostname on -n
- if (!pOptions->spOptions.bMulticast)
- {
- if (ACE_OS::strlen (argv[i]) > 3)
- ACE_OS::strcpy (pOptions->szHostname,
- &argv[i][3]);
- }
- break;
-
- case 'p' :
- if (ACE_OS::strlen (argv[i]) > 3)
- {
- if ('u' == argv[i][3] || 'U' == argv[i][3])
- pOptions->spOptions.iProtocol = IPPROTO_UDP;
- else if ('t' == argv[i][3] || 'T' == argv[i][3])
- pOptions->spOptions.iProtocol = IPPROTO_TCP;
- else
- pOptions->spOptions.iProtocol = IPPROTO_TCP;
- }
- break;
-
- case 'q' :
- pOptions->spOptions.bQos = TRUE;
- if (ACE_OS::strlen (argv[i]) > 3)
- ACE_OS::strcpy (pOptions->qosOptions.szTemplate,
- &argv[i][3]);
- break;
-
- case 'r' :
- if (ACE_OS::strlen (argv[i]) > 3)
- {
- if (ACE_OS::strcasecmp (argv[i],
- "-rsvp-confirm") == 0
- || ACE_OS::strcasecmp (argv[i],
- "-rsvp_confirm") == 0)
- {
- pOptions->qosOptions.bConfirmResv = TRUE;
- pOptions->qosOptions.bProviderSpecific = TRUE;
- }
- else if (ACE_OS::strcasecmp (argv[i],
- "-rsvp-wait") == 0
- || ACE_OS::strcasecmp (argv[i],
- "-rsvp_wait") == 0)
- {
- pOptions->qosOptions.bWaitToSend = TRUE;
- pOptions->qosOptions.bProviderSpecific = TRUE;
- }
- else
- ACE_DEBUG ((LM_DEBUG,
- "Ignoring option <%s>\n",
- argv[i]));
- }
- break;
-
- case 's' :
- if (ACE_OS::strlen (argv[i]) > 3)
- pOptions->dwSleep =
- ACE_OS::atoi (&argv[i][3]);
- break;
-
- case '?' :
- Usage (argv[0],
- &default_options);
- return FALSE;
- break;
-
- default:
- ACE_DEBUG ((LM_DEBUG,
- " unknown options flag %s\n",
- argv[i]));
- Usage (argv[0],
- &default_options);
- return FALSE;
- break;
- }
- }
+ // Should this be abstracted into QoS objects ?? Doesnt seem to have
+ // to do anything directly with QoS.
+ if (ACE_OS::ioctl (dgram_mcast_qos.get_handle (), // Socket.
+ ACE_SIO_MULTIPOINT_LOOPBACK, // IO control code.
+ &bFlag, // In buffer.
+ sizeof (bFlag), // Length of in buffer.
+ achInBuf, // Out buffer.
+ BUFSIZ, // Length of Out buffer.
+ &dwBytes, // bytes returned.
+ 0, // Overlapped.
+ 0) == -1) // Func.
+ ACE_ERROR ((LM_ERROR,
+ "Error in Loopback ACE_OS::ioctl() \n"));
else
- {
- ACE_DEBUG ((LM_DEBUG,
- " unknown option %s\n",
- argv[i]));
- Usage (argv[0],
- &default_options);
- return FALSE;
- }
- }
+ ACE_DEBUG ((LM_DEBUG,
+ "Disable Loopback with ACE_OS::ioctl call succeeds \n"));
+
+ // This is a receiver.
+ qos_session->flags (ACE_QoS_Session::ACE_QOS_RECEIVER);
+
+ ACE_QoS_Manager qos_manager = dgram_mcast_qos.qos_manager ();
+
+ // Set the QoS for the session. Replaces the ioctl () call that
+ // was being made previously.
+ if (qos_session->qos (&dgram_mcast_qos,
+ &qos_manager,
+ ace_qos_receiver) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Unable to set QoS\n"),
+ -1);
+ else
+ ACE_DEBUG ((LM_DEBUG,
+ "Setting QOS succeeds.\n"));
+ // Register a signal handler that helps to gracefully close the
+ // open QoS sessions.
+ QoS_Signal_Handler qos_signal_handler (qos_session);
+
+ // Register the usual SIGINT signal handler with the Reactor for
+ // the application to gracefully release the QoS session and
+ // shutdown.
+ if (ACE_Reactor::instance ()->register_handler
+ (SIGINT, &qos_signal_handler) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Error in registering the Signal Handler.\n"),
+ -1);
- if (pOptions->qosOptions.bReceiver)
- pOptions->fillchar = 0;
+ // Handler to process QoS and Data events for the reciever.
+ Receiver_QoS_Event_Handler qos_event_handler (dgram_mcast_qos,
+ qos_session);
- if (pOptions->spOptions.bMulticast)
- {
- pOptions->spOptions.iProtocol = IPPROTO_UDP;
- pOptions->qosOptions.bSetDestaddr = FALSE;
- }
+ // Decorate the above handler with QoS functionality.
+ ACE_QoS_Decorator qos_decorator (&qos_event_handler,
+ qos_session);
- if (IPPROTO_TCP == pOptions->spOptions.iProtocol)
- {
- pOptions->spOptions.bMulticast = FALSE;
- pOptions->qosOptions.bSetDestaddr = FALSE;
- }
- else if (!pOptions->spOptions.bMulticast)
- pOptions->qosOptions.bSetDestaddr = TRUE;
+ // Initialize the Decorator.
+ if (qos_decorator.init () != 0)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "QoS Decorator init () failed.\n"),
+ -1);
- if (pOptions->spOptions.bQos)
- {
- if (pOptions->qosOptions.bReceiver
- && pOptions->qosOptions.bWaitToSend)
- pOptions->qosOptions.bWaitToSend = FALSE;
- // not a valid receiver option
-
- if (!pOptions->qosOptions.bReceiver
- && pOptions->qosOptions.bConfirmResv)
- pOptions->qosOptions.bWaitToSend = FALSE;
- // not a valid sender option
-
- if (pOptions->qosOptions.bAlternateQos)
- // override repeat count to continuous mode
- pOptions->nRepeat = 0;
-
- if (IPPROTO_UDP == pOptions->spOptions.iProtocol
- && !pOptions->spOptions.bMulticast)
- // Using UDP, there WSAAccept will not be called, therefore
- // do not wait to set qos.
- pOptions->qosOptions.qosIoctlSet =
- QOS_IOCTL_SET_BEFORE;
-
- pOptions->qosOptions.bFineGrainErrorAvail = TRUE;
- pOptions->qosOptions.bQosabilityIoctls = TRUE;
+ // Register the decorated Event Handler with the Reactor.
+ if (ACE_Reactor::instance ()->register_handler (&qos_decorator,
+ ACE_Event_Handler::QOS_MASK |
+ ACE_Event_Handler::READ_MASK) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Error in registering the Decorator with the Reactor\n"),
+ -1);
+
+// // Register the RAPI Event Handler with the Reactor. This
+// // handles the QoS events.
+// if (ACE_Reactor::instance ()->register_handler
+// (&rapi_event_handler,
+// ACE_Event_Handler::QOS_MASK | ACE_Event_Handler::READ_MASK) == -1)
+// ACE_ERROR_RETURN ((LM_ERROR,
+// "Error in registering the RAPI Event Handler\n"),
+// -1);
+
+// // The following event handler handles the data.
+// ACE_QoS_Event_Handler data_event_handler (dgram_mcast_qos,
+// qos_session);
+
+// // Register the Data Event Handler with the Reactor.
+// if (ACE_Reactor::instance ()->register_handler
+// (&data_event_handler,ACE_Event_Handler::READ_MASK) == -1)
+// ACE_ERROR_RETURN ((LM_ERROR,
+// "Error in registering Data Event Handler\n"),
+// -1);
+
+ // Start the event loop.
ACE_DEBUG ((LM_DEBUG,
- "running on XX\n"));
+ "Running the Event Loop ... \n"));
+
+ ACE_Reactor::instance ()->run_event_loop ();
+
+ ACE_DEBUG ((LM_DEBUG,
+ "(%P|%t) shutting down server logging daemon\n"));
}
-
- if (pOptions->nBufSize > 0)
- ACE_NEW_RETURN (pOptions->buf,
- char[pOptions->nBufSize],
- 0);
-
- else
- ACE_ERROR_RETURN ((LM_ERROR,
- "Buffer size to be allocated is less than or"
- "equal to zero\n"),
- -1);
-
- if (pOptions->buf == 0)
- return FALSE;
else
- {
- ACE_OS::memset (pOptions->buf,
- pOptions->fillchar,
- pOptions->nBufSize);
- return TRUE;
- }
+ ACE_DEBUG ((LM_DEBUG,
+ "Specify a -m option for multicast application\n"));
+ return 0;
}
-// Print out usage table for the program
-void
-Usage (char *szProgramname,
- OPTIONS *pOptions)
-{
- ACE_DEBUG ((LM_DEBUG,
- "usage:\n %s -?\n\n"
- " %s [-b:#] [-d:c] [-e:#] [-l:#] [-m:group] "
- "[-n:host] [-s:#] [-u]\n\t[-q:template [-i:[a|b|d|q]]"
- "[-c] [-rsvp-confirm] [-rsvp-wait]]\n\n",
- " -?\t\tDisplay this help\n\n"
- " -b:bufsize\tSize of send/recv buffer; in 1K increments (Def:%d)\n"
- " -d:c\t\tCharacter used to fill buffer (Def:%c)\n"
- " -e:port\tEndpoint number (port) to use (Def:%d)\n"
- " -l:loop\tLoop count for sending buffer (0==>continuous)\n"
- " -m:group\tMulticast group (IP) to join (Def:%s)\n"
- " -n:host\tAct as the client and connect to 'host' (Def:%s)\n"
- " -p:protocol\tTCP or UDP (def:TCP)\n"
- " -s:#\t\tSleep # milliseconds between sends (def: 0)\n"
- " -q:template\tEnable QoS and use 'template' to specify the name (Def:%s)\n"
- " -c\t\tCycle enabling/disabling QOS on sending socket (Def: no cycling)\n"
- " -i:[a|b|d|q]\tSet Qos After, Before, During accept/connect, or during FD_QOS\n\t\t\t(def: Before)\n"
- " -rsvp-confirm\t\tRequest RESV confirmation be sent (Def: no confirmation)\n"
- " -rsvp-wait\t\tWait for RESV from receiver before sending data\n",
- szProgramname,
- szProgramname,
- pOptions->nBufSize,
- pOptions->fillchar,
- pOptions->port,
- pOptions->nRepeat,
- DEFAULT_MULTICASTGROUP,
- pOptions->szHostname,
- pOptions->qosOptions.szTemplate));
- return;
-}
+
diff --git a/examples/QOS/server.dsp b/examples/QOS/server.dsp
index f6c47b582b9..753486b8741 100644
--- a/examples/QOS/server.dsp
+++ b/examples/QOS/server.dsp
@@ -39,11 +39,9 @@ RSC=rc.exe
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
-# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FD /c
-# SUBTRACT CPP /YX
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\.." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
@@ -51,7 +49,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 ace.lib /nologo /subsystem:console /machine:I386 /libpath:"../../ace"
+# ADD LINK32 ace.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\ace"
!ELSEIF "$(CFG)" == "002 - Win32 Debug"
@@ -62,13 +60,12 @@ LINK32=link.exe
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
-# PROP Output_Dir ""
+# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MDd /W3 /GX /Od /I "../../" /D "WIN32" /D "_DEBUG" /FD /c
-# SUBTRACT CPP /YX
+# ADD CPP /nologo /MDd /W3 /GX /Od /I "d:\vishal\ACE_wrappers" /D "WIN32" /D "_DEBUG" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
@@ -76,7 +73,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 aced.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"../../ace"
+# ADD LINK32 d:\vishal\ACE_wrappers\ace\aced.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"d:\vishal\ACE_wrappers\ace"
!ENDIF