summaryrefslogtreecommitdiff
path: root/TAO/orbsvcs/orbsvcs/AV
diff options
context:
space:
mode:
authornaga <naga@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1999-08-31 23:17:58 +0000
committernaga <naga@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1999-08-31 23:17:58 +0000
commitbf7c6eed6bfff6ffbf4f28809a0b9031e492e123 (patch)
treed65e282fbf3232635b7f6e8e4f1628dab8b39a94 /TAO/orbsvcs/orbsvcs/AV
parentb6f7377616988bc10dd543cd970120843ae2c65b (diff)
downloadATCD-bf7c6eed6bfff6ffbf4f28809a0b9031e492e123.tar.gz
Tue Aug 31 18:07:35 1999 Nagarajan Surendran <naga@cs.wustl.edu>
Diffstat (limited to 'TAO/orbsvcs/orbsvcs/AV')
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/AVStreams_i.cpp4497
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/AVStreams_i.h1064
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/AVStreams_i.i31
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/AV_Core.h185
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/Endpoint_Strategy.cpp38
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/Endpoint_Strategy.h39
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/Endpoint_Strategy_T.cpp36
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/Endpoint_Strategy_T.h57
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/FlowSpec_Entry.cpp532
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/FlowSpec_Entry.h282
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/FlowSpec_Entry.i208
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/Flows_T.cpp248
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/Flows_T.h126
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/MCast.cpp207
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/MCast.h110
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/MCast.i13
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/Nil.cpp45
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/Nil.h45
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/Policy.cpp148
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/Policy.h163
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/Policy.i75
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/Protocol_Factory.cpp157
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/Protocol_Factory.h100
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/RTCP.cpp931
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/RTCP.h296
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/RTP.cpp344
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/RTP.h299
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/TCP.cpp677
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/TCP.h236
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/Transport.cpp1249
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/Transport.h226
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/Transport.i180
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/UDP.cpp729
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/UDP.h219
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/UDP.i20
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/media-timer.cpp86
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/media-timer.h59
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/ntp-time.h96
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/sfp.cpp2195
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/sfp.h355
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/source.cpp531
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/source.h225
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/source.i491
43 files changed, 15148 insertions, 2702 deletions
diff --git a/TAO/orbsvcs/orbsvcs/AV/AVStreams_i.cpp b/TAO/orbsvcs/orbsvcs/AV/AVStreams_i.cpp
index 4c0bcdb02ce..6c447753e7c 100644
--- a/TAO/orbsvcs/orbsvcs/AV/AVStreams_i.cpp
+++ b/TAO/orbsvcs/orbsvcs/AV/AVStreams_i.cpp
@@ -1,5 +1,4 @@
// $Id$
-
// ============================================================================
//
// = LIBRARY
@@ -16,10 +15,128 @@
// ============================================================================
#include "AVStreams_i.h"
-#include "orbsvcs/Trader/Trader.h"
+#include "sfp.h"
+#include "MCast.h"
+#include "RTCP.h"
ACE_RCSID(AV, AVStreams_i, "$Id$")
+int
+deactivate_servant (PortableServer::Servant servant)
+{
+ // Because of reference counting, the POA
+ // will automatically delete the servant when all pending requests
+ // on this servant are complete.
+
+ ACE_DECLARE_NEW_CORBA_ENV;
+ ACE_TRY
+ {
+ PortableServer::POA_var poa = servant->_default_POA (ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+
+ PortableServer::ObjectId_var id = poa->servant_to_id (servant,
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+
+ poa->deactivate_object (id.in (),
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"deactivate_servant");
+ return -1;
+ }
+ ACE_ENDTRY;
+ ACE_CHECK_RETURN (-1);
+ return 0;
+}
+
+char *
+get_flowname (const char *flow_spec_entry_str)
+{
+ ACE_CString flow_spec_entry (flow_spec_entry_str);
+ int slash_pos = flow_spec_entry.find ('\\');
+ ACE_CString flow_name;
+ if (slash_pos != flow_spec_entry.npos)
+ flow_name = flow_spec_entry.substring (0,slash_pos);
+ else
+ flow_name = flow_spec_entry_str;
+ return CORBA::string_dup (flow_name.c_str ());
+}
+
+#if !defined (__ACE_INLINE__)
+#include "AVStreams_i.i"
+#endif /* __ACE_INLINE__ */
+
+//------------------------------------------------------------
+// TAO_AV_Qos
+//------------------------------------------------------------
+
+TAO_AV_QoS::TAO_AV_QoS (void)
+{
+}
+
+TAO_AV_QoS::TAO_AV_QoS (AVStreams::streamQoS &stream_qos)
+{
+ this->set (stream_qos);
+}
+
+int
+TAO_AV_QoS::convert (AVStreams::streamQoS &/*network_qos*/)
+{
+ return -1;
+}
+
+#if !defined (TAO_ORBSVCS_HAS_Trader)
+// = Methods to deal with ACE_Hash_Map_Manager.
+
+TAO_String_Hash_Key::TAO_String_Hash_Key (void)
+{
+}
+
+TAO_String_Hash_Key::TAO_String_Hash_Key (char * name)
+ : CORBA_String_var (name)
+{
+}
+
+TAO_String_Hash_Key::TAO_String_Hash_Key (const char * name)
+ : CORBA_String_var (name)
+{
+}
+
+TAO_String_Hash_Key::TAO_String_Hash_Key (const CORBA::String_var &src)
+ : CORBA_String_var (src)
+{
+}
+
+int
+TAO_String_Hash_Key::operator == (const TAO_String_Hash_Key &hash_key) const
+{
+ return ACE_OS::strcmp (this->in (), hash_key.in ()) == 0;
+}
+
+int
+operator < (const TAO_String_Hash_Key &left,
+ const TAO_String_Hash_Key &right)
+{
+ return ACE_OS::strcmp (left.in (), right.in ()) < 0;
+}
+
+
+u_long
+TAO_String_Hash_Key::hash (void) const
+{
+ u_long ret = ACE::hash_pjw (this->in ());
+ return ret;
+}
+
+TAO_String_Hash_Key::~TAO_String_Hash_Key (void)
+{
+}
+
+#endif /* !TAO_ORBSVCS_HAS_Trader */
+
// ----------------------------------------------------------------------
// AV_Null_MediaCtrl
// ----------------------------------------------------------------------
@@ -38,24 +155,52 @@ TAO_Basic_StreamCtrl::TAO_Basic_StreamCtrl (void)
{
}
-TAO_Basic_StreamCtrl::~TAO_Basic_StreamCtrl (void)
-{
-}
-
// Stop the transfer of data of the stream
// Empty the_spec means apply operation to all flows
void
-TAO_Basic_StreamCtrl::stop (const AVStreams::flowSpec &the_spec,
+TAO_Basic_StreamCtrl::stop (const AVStreams::flowSpec &flow_spec,
CORBA::Environment &ACE_TRY_ENV)
ACE_THROW_SPEC ((CORBA::SystemException,
AVStreams::noSuchFlow))
-
{
- if (CORBA::is_nil (this->sep_a_.in ()))
- return;
-
- // Make the upcall into the application
- this->sep_a_->stop (the_spec, ACE_TRY_ENV);
+ ACE_TRY
+ {
+ // @@Call stop on the Related MediaCtrl.
+ // call stop on the flow connections.
+ if (this->flow_connection_map_.current_size () > 0)
+ {
+ if (flow_spec.length () > 0)
+ for (u_int i=0;i<flow_spec.length ();i++)
+ {
+ char *flowname = get_flowname (flow_spec[i]);
+ TAO_String_Hash_Key flow_name_key (flowname);
+ FlowConnection_Map::ENTRY *flow_connection_entry = 0;
+ if (this->flow_connection_map_.find (flow_name_key,flow_connection_entry) == 0)
+ {
+ flow_connection_entry->int_id_->stop (ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ }
+ }
+ else
+ {
+ // call start on all the flows.
+ FlowConnection_Map_Iterator iterator (this->flow_connection_map_);
+ FlowConnection_Map_Entry *entry = 0;
+ for (;iterator.next (entry) != 0;iterator.advance ())
+ {
+ entry->int_id_->stop (ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ }
+ }
+ }
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"TAO_Basic_StreamCtrl::stop");
+ return;
+ }
+ ACE_ENDTRY;
+ ACE_CHECK;
}
// Start the transfer of data in the stream.
@@ -66,28 +211,90 @@ TAO_Basic_StreamCtrl::start (const AVStreams::flowSpec &flow_spec,
ACE_THROW_SPEC ((CORBA::SystemException,
AVStreams::noSuchFlow))
{
- // call start on the flow connections.
- if (CORBA::is_nil (this->sep_a_.in ()))
- return;
+ ACE_TRY
+ {
+ // @@Call start on the Related MediaCtrl.
- // Make the upcall into the application
- this->sep_a_->start (flow_spec, ACE_TRY_ENV);
+ // call start on the flow connections.
+ if (this->flow_connection_map_.current_size () > 0)
+ {
+ if (flow_spec.length () > 0)
+ for (u_int i=0;i<flow_spec.length ();i++)
+ {
+ char *flowname = get_flowname (flow_spec[i]);
+ TAO_String_Hash_Key flow_name_key (flowname);
+ FlowConnection_Map::ENTRY *flow_connection_entry = 0;
+ if (this->flow_connection_map_.find (flow_name_key,flow_connection_entry) == 0)
+ {
+ flow_connection_entry->int_id_->start (ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ }
+ }
+ else
+ {
+ // call start on all the flows.
+ FlowConnection_Map_Iterator iterator (this->flow_connection_map_);
+ FlowConnection_Map_Entry *entry = 0;
+ for (;iterator.next (entry) != 0;iterator.advance ())
+ {
+ entry->int_id_->start (ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ }
+ }
+ }
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"TAO_Basic_StreamCtrl::start");
+ return;
+ }
+ ACE_ENDTRY;
+ ACE_CHECK;
}
// Tears down the stream. This will close the connection, and delete
// the streamendpoint and vdev associated with this stream
// Empty the_spec means apply operation to all flows
void
-TAO_Basic_StreamCtrl::destroy (const AVStreams::flowSpec &the_spec,
+TAO_Basic_StreamCtrl::destroy (const AVStreams::flowSpec &flow_spec,
CORBA::Environment &ACE_TRY_ENV)
ACE_THROW_SPEC ((CORBA::SystemException,
AVStreams::noSuchFlow))
{
- if (CORBA::is_nil (this->sep_a_.in ()))
- return;
-
- // Make the upcall into the application
- this->sep_a_->destroy (the_spec, ACE_TRY_ENV);
+ ACE_TRY
+ {
+ // call stop on the flow connections.
+ if (this->flow_connection_map_.current_size () > 0)
+ {
+ if (flow_spec.length () > 0)
+ for (u_int i=0;i<flow_spec.length ();i++)
+ {
+ char *flowname = get_flowname (flow_spec[i]);
+ TAO_String_Hash_Key flow_name_key (flowname);
+ FlowConnection_Map::ENTRY *flow_connection_entry = 0;
+ if (this->flow_connection_map_.find (flow_name_key,flow_connection_entry) == 0)
+ flow_connection_entry->int_id_->destroy (ACE_TRY_ENV);
+ }
+ else
+ {
+ // call start on all the flows.
+ FlowConnection_Map_Iterator iterator (this->flow_connection_map_);
+ FlowConnection_Map_Entry *entry = 0;
+ for (;iterator.next (entry) != 0;iterator.advance ())
+ {
+ entry->int_id_->destroy (ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ }
+ }
+ }
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"TAO_Basic_StreamCtrl::destroy");
+ return;
+ }
+ ACE_ENDTRY;
+ ACE_CHECK;
}
// Changes the QoS associated with the stream
@@ -120,27 +327,32 @@ TAO_Basic_StreamCtrl::modify_QoS (AVStreams::streamQoS & new_qos,
// Used by StreamEndPoint and VDev to inform StreamCtrl of events.
// E.g., loss of flow, reestablishment of flow, etc..
void
-TAO_Basic_StreamCtrl::push_event (const struct CosPropertyService::Property & /* the_event */,
+TAO_Basic_StreamCtrl::push_event (const struct CosPropertyService::Property &/*the_event*/,
CORBA::Environment & /* ACE_TRY_ENV */)
ACE_THROW_SPEC ((CORBA::SystemException))
{
ACE_DEBUG ((LM_DEBUG,"\n(%P|%t) Recieved event \""));
}
-// @@ Need to throw not-supported exception here
+// Sets the flow protocol status.
void
-TAO_Basic_StreamCtrl::set_FPStatus (const AVStreams::flowSpec &/* the_spec */,
- const char * /* fp_name */,
- const CORBA::Any &/* fp_settings */,
- CORBA::Environment &/* ACE_TRY_ENV */)
+TAO_Basic_StreamCtrl::set_FPStatus (const AVStreams::flowSpec &flow_spec,
+ const char *fp_name,
+ const CORBA::Any &fp_settings,
+ CORBA::Environment &ACE_TRY_ENV)
ACE_THROW_SPEC ((CORBA::SystemException,
AVStreams::noSuchFlow,
AVStreams::FPError))
{
+ if (!CORBA::is_nil (this->sep_a_.in ()))
+ {
+ this->sep_a_->set_FPStatus (flow_spec,fp_name,fp_settings,ACE_TRY_ENV);
+ ACE_CHECK;
+ }
}
-// @@ Need to throw not-supported exception here
+// Gets the flow connection.
CORBA::Object_ptr
TAO_Basic_StreamCtrl::get_flow_connection (const char *flow_name,
CORBA::Environment &ACE_TRY_ENV)
@@ -150,28 +362,49 @@ TAO_Basic_StreamCtrl::get_flow_connection (const char *flow_name,
{
TAO_String_Hash_Key flow_name_key (flow_name);
FlowConnection_Map::ENTRY *flow_connection_entry = 0;
- if (this->flow_map_.find (flow_name_key,flow_connection_entry) == 0)
- return flow_connection_entry->int_id_;
+ if (this->flow_connection_map_.find (flow_name_key,flow_connection_entry) == 0)
+ return AVStreams::FlowConnection::_duplicate (flow_connection_entry->int_id_);
else
ACE_THROW_RETURN (AVStreams::noSuchFlow (),CORBA::Object::_nil ());
}
-// @@ Need to throw not-supported exception here
+// Sets the flow connection.
void
TAO_Basic_StreamCtrl::set_flow_connection (const char *flow_name,
- CORBA::Object_ptr flow_connection,
+ CORBA::Object_ptr flow_connection_obj,
CORBA::Environment &ACE_TRY_ENV)
ACE_THROW_SPEC ((CORBA::SystemException,
AVStreams::noSuchFlow,
AVStreams::notSupported))
{
+ AVStreams::FlowConnection_ptr flow_connection = AVStreams::FlowConnection::_nil ();
+ ACE_TRY
+ {
+ flow_connection = AVStreams::FlowConnection::_narrow (flow_connection_obj,ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"TAO_Basic_StreamCtrl::set_flow_connection");
+ return;
+ }
+ ACE_ENDTRY;
+ ACE_CHECK;
// add the flowname and the flowconnection to the hashtable.
+ this->flows_.length (this->flow_count_ + 1);
this->flows_ [this->flow_count_++] = CORBA::string_dup (flow_name);
TAO_String_Hash_Key flow_name_key (flow_name);
- if (this->flow_map_.bind (flow_name_key,flow_connection) != 0)
+ if (this->flow_connection_map_.bind (flow_name_key,flow_connection) != 0)
ACE_THROW (AVStreams::noSuchFlow ());// is this right?
}
+TAO_Basic_StreamCtrl::~TAO_Basic_StreamCtrl (void)
+{
+ FlowConnection_Map_Iterator iterator (this->flow_connection_map_);
+ FlowConnection_Map_Entry *entry = 0;
+ for (;iterator.next (entry) != 0;iterator.advance ())
+ CORBA::release (entry->int_id_);
+}
// ----------------------------------------------------------------------
// TAO_Negotiator
@@ -187,17 +420,258 @@ TAO_Negotiator::negotiate (AVStreams::Negotiator_ptr /* remote_negotiator */,
}
// ----------------------------------------------------------------------
+// MMDevice_Map_Hash_Key
+// ----------------------------------------------------------------------
+
+const int MMDevice_Map_Hash_Key::hash_maximum_ = 10000;
+
+//default constructor.
+MMDevice_Map_Hash_Key::MMDevice_Map_Hash_Key (void)
+{
+ this->mmdevice_ = AVStreams::MMDevice::_nil ();
+}
+
+// constructor.
+MMDevice_Map_Hash_Key::MMDevice_Map_Hash_Key (AVStreams::MMDevice_ptr mmdevice)
+{
+ this->mmdevice_ = AVStreams::MMDevice::_duplicate (mmdevice);
+}
+
+// copy constructor.
+MMDevice_Map_Hash_Key::MMDevice_Map_Hash_Key (const MMDevice_Map_Hash_Key& hash_key)
+{
+ this->mmdevice_ = AVStreams::MMDevice::_duplicate (hash_key.mmdevice_);
+}
+
+// destructor.
+MMDevice_Map_Hash_Key::~MMDevice_Map_Hash_Key (void)
+{
+ CORBA::release (this->mmdevice_);
+}
+
+int
+MMDevice_Map_Hash_Key::operator == (const MMDevice_Map_Hash_Key &hash_key) const
+{
+ CORBA::Boolean result = 0;
+ ACE_DECLARE_NEW_CORBA_ENV;
+ ACE_TRY
+ {
+ result =
+ this->mmdevice_->_is_equivalent (hash_key.mmdevice_,ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"MMDevice_Map_Hash_Key::operator == ");
+ return 0;
+ }
+ ACE_ENDTRY;
+ ACE_CHECK_RETURN (0);
+ return result;
+}
+
+int
+operator < (const MMDevice_Map_Hash_Key &left,
+ const MMDevice_Map_Hash_Key &right)
+{
+ int result = 0;
+ ACE_DECLARE_NEW_CORBA_ENV;
+ ACE_TRY
+ {
+ CORBA::ULong left_hash = left.mmdevice_->_hash (left.hash_maximum_,
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ CORBA::ULong right_hash = right.mmdevice_->_hash (right.hash_maximum_,
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ result = left_hash < right_hash;
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"operator < for MMDevice_Map_Hash_Key");
+ return 0;
+ }
+ ACE_ENDTRY;
+ ACE_CHECK_RETURN (0);
+ return result;
+}
+
+u_long
+MMDevice_Map_Hash_Key::hash (void) const
+{
+ u_long result = 0;
+ ACE_DECLARE_NEW_CORBA_ENV;
+ ACE_TRY
+ {
+ result = this->mmdevice_->_hash (this->hash_maximum_,
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"MMDevice_Map_Hash_Key::hash");
+ return 0;
+ }
+ ACE_ENDTRY;
+ ACE_CHECK_RETURN (0);
+ return result;
+}
+
+// ----------------------------------------------------------------------
// TAO_StreamCtrl
// ----------------------------------------------------------------------
TAO_StreamCtrl::TAO_StreamCtrl (void)
- :mcastconfigif_ (0),
- mcastconfigif_ptr_ (0)
+ :mcastconfigif_ (0)
{
+ ACE_DECLARE_NEW_CORBA_ENV;
+ ACE_TRY
+ {
+ this->streamctrl_ = this->_this (ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ char buf [BUFSIZ];
+ int result = gethostname (buf,BUFSIZ);
+ unsigned long ipaddr = 0;
+ if (result == 0)
+ ipaddr = ACE_OS::inet_addr (buf);
+ this->source_id_ = TAO_AV_RTCP::alloc_srcid (ipaddr);
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"TAO_StreamCtrl::TAO_StreamCtrl");
+ }
+ ACE_ENDTRY;
+ ACE_CHECK;
+}
+
+TAO_StreamCtrl::TAO_StreamCtrl (TAO_StreamCtrl const &)
+{
+ //no-op
+}
+
+void
+TAO_StreamCtrl::operator= (TAO_StreamCtrl const &)
+{
+ //no-op
}
TAO_StreamCtrl::~TAO_StreamCtrl (void)
{
+ delete this->mcastconfigif_;
+}
+
+
+// Stop the transfer of data of the stream
+// Empty the_spec means apply operation to all flows
+void
+TAO_StreamCtrl::stop (const AVStreams::flowSpec &flow_spec,
+ CORBA::Environment &ACE_TRY_ENV)
+ ACE_THROW_SPEC ((CORBA::SystemException,
+ AVStreams::noSuchFlow))
+{
+ ACE_TRY
+ {
+ TAO_Basic_StreamCtrl::stop (flow_spec,ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ if (this->flow_connection_map_.current_size () > 0)
+ return;
+ MMDevice_Map_Iterator a_iterator (this->mmdevice_a_map_);
+ MMDevice_Map::ENTRY *entry = 0;
+ for (;a_iterator.next (entry)!= 0;a_iterator.advance ())
+ {
+ entry->int_id_.sep_->stop (flow_spec, ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ }
+ MMDevice_Map_Iterator b_iterator (this->mmdevice_b_map_);
+ for (;b_iterator.next (entry)!= 0;b_iterator.advance ())
+ {
+ entry->int_id_.sep_->stop (flow_spec, ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ }
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"TAO_Basic_StreamCtrl::stop");
+ return;
+ }
+ ACE_ENDTRY;
+ ACE_CHECK;
+}
+
+// Start the transfer of data in the stream.
+// Empty the_spec means apply operation to all flows
+void
+TAO_StreamCtrl::start (const AVStreams::flowSpec &flow_spec,
+ CORBA::Environment &ACE_TRY_ENV)
+ ACE_THROW_SPEC ((CORBA::SystemException,
+ AVStreams::noSuchFlow))
+{
+ ACE_TRY
+ {
+ TAO_Basic_StreamCtrl::start (flow_spec,ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ if (this->flow_connection_map_.current_size () > 0)
+ return;
+
+ MMDevice_Map_Iterator a_iterator (this->mmdevice_a_map_);
+ MMDevice_Map::ENTRY *entry = 0;
+ for (;a_iterator.next (entry)!= 0;a_iterator.advance ())
+ {
+ entry->int_id_.sep_->start (flow_spec, ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ }
+ MMDevice_Map_Iterator b_iterator (this->mmdevice_b_map_);
+ for (;b_iterator.next (entry)!= 0;b_iterator.advance ())
+ {
+ entry->int_id_.sep_->start (flow_spec, ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ }
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"TAO_Basic_StreamCtrl::start");
+ return;
+ }
+ ACE_ENDTRY;
+ ACE_CHECK;
+}
+
+// Tears down the stream. This will close the connection, and delete
+// the streamendpoint and vdev associated with this stream
+// Empty the_spec means apply operation to all flows
+void
+TAO_StreamCtrl::destroy (const AVStreams::flowSpec &flow_spec,
+ CORBA::Environment &ACE_TRY_ENV)
+ ACE_THROW_SPEC ((CORBA::SystemException,
+ AVStreams::noSuchFlow))
+{
+ ACE_TRY
+ {
+ TAO_Basic_StreamCtrl::destroy (flow_spec,ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ if (this->flow_connection_map_.current_size () > 0)
+ return;
+ MMDevice_Map_Iterator a_iterator (this->mmdevice_a_map_);
+ MMDevice_Map::ENTRY *entry = 0;
+ for (;a_iterator.next (entry)!= 0;a_iterator.advance ())
+ {
+ entry->int_id_.sep_->destroy (flow_spec, ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ }
+ MMDevice_Map_Iterator b_iterator (this->mmdevice_b_map_);
+ for (;b_iterator.next (entry)!= 0;b_iterator.advance ())
+ {
+ entry->int_id_.sep_->destroy (flow_spec, ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ }
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"TAO_Basic_StreamCtrl::destroy");
+ return;
+ }
+ ACE_ENDTRY;
+ ACE_CHECK;
}
// request the two MMDevices to create vdev and stream endpoints. save
@@ -215,77 +689,188 @@ TAO_StreamCtrl::bind_devs (AVStreams::MMDevice_ptr a_party,
AVStreams::noSuchFlow,
AVStreams::QoSRequestFailed))
{
- // do a Qos Translation from application level Qos to Network level Qos??
ACE_TRY
{
if (CORBA::is_nil (a_party) && CORBA::is_nil (b_party))
ACE_ERROR_RETURN ((LM_ERROR,"Both parties are nil\n"),0);
// Check to see if we have non-nil parties to bind!
- if (CORBA::is_nil (a_party) ||
- CORBA::is_nil (b_party))
- ACE_DEBUG ((LM_DEBUG,
- "(%P|%t) TAO_StreamCtrl::bind_devs: "
- "a_party or b_party is null"
- "Multicast mode\n"));
+ if (TAO_debug_level > 0)
+ if (CORBA::is_nil (a_party) ||
+ CORBA::is_nil (b_party))
+ ACE_DEBUG ((LM_DEBUG,
+ "(%P|%t) TAO_StreamCtrl::bind_devs: "
+ "a_party or b_party is null"
+ "Multicast mode\n"));
// Request a_party to create the endpoint and vdev
CORBA::Boolean met_qos;
CORBA::String_var named_vdev;
- AVStreams::StreamCtrl_var streamctrl =
- this->_this (ACE_TRY_ENV);
- ACE_TRY_CHECK;
+
if (!CORBA::is_nil (a_party))
{
- this->sep_a_ =
- a_party-> create_A (streamctrl.in (),
- this->vdev_a_.out (),
- the_qos,
- met_qos,
- named_vdev.inout (),
- the_flows,
- ACE_TRY_ENV);
- ACE_TRY_CHECK;
+ MMDevice_Map_Hash_Key find_key (a_party);
+ MMDevice_Map_Entry find_entry;
+ int result =
+ this->mmdevice_a_map_.find (find_key,find_entry);
+ if (result == 0)
+ {
+ if (TAO_debug_level > 0)
+ {
+ // Already in the map.
+ ACE_DEBUG ((LM_DEBUG,"mmdevice a_party is already bound\n"));
+ }
+ return 1;
+ }
+ else
+ {
+ this->sep_a_ =
+ a_party-> create_A (this->streamctrl_.in (),
+ this->vdev_a_.out (),
+ the_qos,
+ met_qos,
+ named_vdev.inout (),
+ the_flows,
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK;
- ACE_DEBUG ((LM_DEBUG,
- "(%P|%t) TAO_StreamCtrl::create_A: succeeded\n"));
+ if (TAO_debug_level > 0)
+ ACE_DEBUG ((LM_DEBUG,"(%P|%t) TAO_StreamCtrl::create_A: succeeded\n"));
+ // Define ourselves as the related_streamctrl property of the sep.
+ CORBA::Any streamctrl_any;
+ streamctrl_any <<= this->streamctrl_.in ();
+ this->sep_a_->define_property ("Related_StreamCtrl",
+ streamctrl_any,
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ // add the mmdevice,sep and vdev to the map.
+ MMDevice_Map_Entry map_entry;
+ MMDevice_Map_Hash_Key key (a_party);
+ map_entry.sep_ = AVStreams::StreamEndPoint_A::_duplicate (this->sep_a_.in ());
+ map_entry.vdev_ = AVStreams::VDev::_duplicate (this->vdev_a_.in ());
+ map_entry.flowspec_ = the_flows;
+ map_entry.qos_ = the_qos;
+ result =
+ this->mmdevice_a_map_.bind (key,map_entry);
+ if (result < 0)
+ if (TAO_debug_level > 0)
+ ACE_DEBUG ((LM_DEBUG,"Error binding mmdevice entry in the a_map"));
+ }
}
-
// Request b_party to create the endpoint and vdev
-
if (!CORBA::is_nil (b_party))
{
- this->sep_b_ =
- b_party-> create_B (streamctrl.in (),
- this->vdev_b_.out (),
- the_qos,
- met_qos,
- named_vdev.inout (),
- the_flows,
- ACE_TRY_ENV);
- ACE_TRY_CHECK;
+ MMDevice_Map_Hash_Key find_key (b_party);
+ MMDevice_Map_Entry find_entry;
+ int result =
+ this->mmdevice_b_map_.find (find_key,find_entry);
+ if (result == 0)
+ {
+ // Already in the map.
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"mmdevice b_party is already bound\n"));
+ return 1;
+ }
+ else
+ {
+ this->sep_b_ =
+ b_party-> create_B (this->streamctrl_.in (),
+ this->vdev_b_.out (),
+ the_qos,
+ met_qos,
+ named_vdev.inout (),
+ the_flows,
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK;
- ACE_DEBUG ((LM_DEBUG,
- "(%P|%t) TAO_StreamCtrl::create_B: succeeded\n"));
- ACE_DEBUG ((LM_DEBUG,
- "\n(%P|%t)stream_endpoint_b_ = %s",
- TAO_ORB_Core_instance ()->orb ()->object_to_string (this->sep_b_.in (),
- ACE_TRY_ENV)));
- ACE_TRY_CHECK;
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"(%P|%t) TAO_StreamCtrl::create_B: succeeded\n"));
+
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,
+ "\n(%P|%t)stream_endpoint_b_ = %s",
+ TAO_ORB_Core_instance ()->orb ()->object_to_string (this->sep_b_.in (),
+ ACE_TRY_ENV)));
+ ACE_TRY_CHECK;
+ // Define ourselves as the related_streamctrl property of the sep.
+ CORBA::Any streamctrl_any;
+ streamctrl_any <<= this->streamctrl_.in ();
+ this->sep_b_->define_property ("Related_StreamCtrl",
+ streamctrl_any,
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+
+ // add the mmdevice,sep and vdev to the map.
+ MMDevice_Map_Entry map_entry;
+ MMDevice_Map_Hash_Key key (b_party);
+ map_entry.sep_ = AVStreams::StreamEndPoint::_duplicate (this->sep_b_.in ());
+ map_entry.vdev_ = AVStreams::VDev::_duplicate(this->vdev_b_.in ());
+ map_entry.flowspec_ = the_flows;
+ map_entry.qos_ = the_qos;
+ int result =
+ this->mmdevice_b_map_.bind (key,map_entry);
+ if (result < 0)
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"Error binding mmdevice entry in the b_map"));
+ }
}
- if (CORBA::is_nil (b_party))
+ // In the full profile case there's no VDev.
+ if (CORBA::is_nil (b_party) && (!CORBA::is_nil (this->vdev_a_.in ())))
{
- if (this->mcastconfigif_ != 0)
+ // Now set the source id for this A endpoint.
+ // If the sep contains flow producers then set the source ids for those
+ // instead.
+ ACE_TRY_EX (set_source_id)
+ {
+ CORBA::Any_ptr flows_any = this->sep_a_->get_property_value ("Flows",
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK_EX (set_source_id);
+ AVStreams::flowSpec_var flows;
+ *flows_any >>= flows.out ();
+ for (u_int i=0; i< flows->length ();i++)
+ {
+ CORBA::Object_var fep_obj =
+ this->sep_a_->get_fep (flows [i],ACE_TRY_ENV);
+ ACE_TRY_CHECK_EX (set_source_id);
+ ACE_TRY_EX (producer_check)
+ {
+ AVStreams::FlowProducer_var producer =
+ AVStreams::FlowProducer::_narrow (fep_obj.in (),
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK_EX (producer_check);
+ producer->set_source_id (this->source_id_++);
+ }
+ ACE_CATCHANY
+ {
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG," %s ",flows[i].in ()));
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"producer_check: not a producer");
+ }
+ ACE_ENDTRY;
+ ACE_CHECK_RETURN (0);
+ }
+ }
+ ACE_CATCHANY
+ {
+ // Since the full profile failed try setting the source id
+ // for the sep instead.
+ // @@Naga: What do we do if in the light profile the sep has
+ // many producers who do not have flow interfaces. Then
+ // the streamctrl has to give an array of source ids to
+ // the sep.
+ this->sep_a_->set_source_id (this->source_id_++,
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ }
+ ACE_ENDTRY;
+ ACE_CHECK_RETURN (0);
+ if (!this->mcastconfigif_)
{
ACE_NEW_RETURN (this->mcastconfigif_,
TAO_MCastConfigIf,
0);
+ // @@: Deactivating the object thru poa means calling remove_ref after _this.
this->mcastconfigif_ptr_ = this->mcastconfigif_->_this (ACE_TRY_ENV);
ACE_TRY_CHECK;
}
// Multicast source being added.
- CORBA::Boolean result = this->vdev_a_->set_Mcast_peer (streamctrl.in (),
- this->mcastconfigif_ptr_,
+ CORBA::Boolean result = this->vdev_a_->set_Mcast_peer (this->streamctrl_.in (),
+ this->mcastconfigif_ptr_.in (),
the_qos,
the_flows,
ACE_TRY_ENV);
@@ -295,49 +880,93 @@ TAO_StreamCtrl::bind_devs (AVStreams::MMDevice_ptr a_party,
if (CORBA::is_nil (a_party))
{
- // Multicast sink being added.
- if (this->mcastconfigif_ != 0)
- ACE_ERROR_RETURN ((LM_ERROR,"first add a source and then a sink\n"),0);
- this->mcastconfigif_->set_peer (this->vdev_b_.in (),
- the_qos,
- the_flows,
- ACE_TRY_ENV);
- ACE_TRY_CHECK;
+ if (!CORBA::is_nil (this->vdev_b_.in ()))
+ {
+ // Multicast sink being added.
+ if (!this->mcastconfigif_)
+ ACE_ERROR_RETURN ((LM_ERROR,"first add a source and then a sink\n"),0);
+ this->mcastconfigif_->set_peer (this->vdev_b_.in (),
+ the_qos,
+ the_flows,
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ }
- this->sep_a_->connect_leaf (this->sep_b_.in (),
- the_qos,
- the_flows,
- ACE_TRY_ENV);
- ACE_TRY_CHECK;
+ int connect_leaf_success = 0;
+ ACE_TRY_EX (connect_leaf)
+ {
+ // @@: define null interfaces for Atm so that they can be implemented once
+ // ACE adds support for ATM multicast.
+ connect_leaf_success = this->sep_a_->connect_leaf (this->sep_b_.in (),
+ the_qos,
+ the_flows,
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK_EX (connect_leaf);
+ connect_leaf_success = 1;
+ }
+ ACE_CATCH (AVStreams::notSupported,ex)
+ {
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"connect_leaf failed\n"));
+ connect_leaf_success = 0;
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"TAO_StreamCtrl::bind_devs");
+ }
+ ACE_ENDTRY;
+ ACE_CHECK_RETURN (0);
+ if (!connect_leaf_success)
+ {
+ AVStreams::flowSpec connect_flows = the_flows;
+ this->sep_a_->multiconnect (the_qos,connect_flows,ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ this->sep_b_->multiconnect (the_qos,connect_flows,ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ }
}
if (!CORBA::is_nil (a_party) && !CORBA::is_nil (b_party))
{
- // Tell the 2 VDev's about one another
- this->vdev_a_->set_peer (streamctrl.in (),
- this->vdev_b_.in (),
- the_qos,
- the_flows,
- ACE_TRY_ENV);
-
- ACE_TRY_CHECK;
-
- this->vdev_b_->set_peer (streamctrl.in (),
- this->vdev_a_.in (),
- the_qos,
- the_flows,
- ACE_TRY_ENV);
+ if (!CORBA::is_nil (this->vdev_a_.in ()) && !CORBA::is_nil (this->vdev_b_.in ()))
+ {
+ // Tell the 2 VDev's about one another
+ this->vdev_a_->set_peer (this->streamctrl_.in (),
+ this->vdev_b_.in (),
+ the_qos,
+ the_flows,
+ ACE_TRY_ENV);
- ACE_TRY_CHECK;
+ ACE_TRY_CHECK;
+ this->vdev_b_->set_peer (this->streamctrl_.in (),
+ this->vdev_a_.in (),
+ the_qos,
+ the_flows,
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK;
- // Now connect the streams together. This will
- // establish the connection
- this->sep_a_->connect (this->sep_b_.in (),
- the_qos,
- the_flows,
- ACE_TRY_ENV);
- ACE_TRY_CHECK;
+ // Now connect the streams together. This will
+ // establish the connection
+ CORBA::Boolean result =
+ this->sep_a_->connect (this->sep_b_.in (),
+ the_qos,
+ the_flows,
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ if (result == 0)
+ ACE_ERROR_RETURN ((LM_ERROR,"sep_a->connect (sep_b) failed\n"),0);
+ }
+ else
+ {
+ // Its full profile
+ // we have feps in the sep then dont call connect instead call bind on the streamctrl.
+ this->bind (this->sep_a_.in (),
+ this->sep_b_.in (),
+ the_qos,
+ the_flows,
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ }
}
}
ACE_CATCHANY
@@ -355,8 +984,8 @@ TAO_StreamCtrl::bind_devs (AVStreams::MMDevice_ptr a_party,
CORBA::Boolean
TAO_StreamCtrl::bind (AVStreams::StreamEndPoint_A_ptr sep_a,
AVStreams::StreamEndPoint_B_ptr sep_b,
- AVStreams::streamQoS &the_qos,
- const AVStreams::flowSpec &the_flows,
+ AVStreams::streamQoS &stream_qos,
+ const AVStreams::flowSpec &flow_spec,
CORBA::Environment &ACE_TRY_ENV)
ACE_THROW_SPEC ((CORBA::SystemException,
AVStreams::streamOpFailed,
@@ -366,6 +995,7 @@ TAO_StreamCtrl::bind (AVStreams::StreamEndPoint_A_ptr sep_a,
this->sep_a_ = sep_a;
this->sep_b_ = sep_b;
+ int result = 0;
ACE_TRY
{
if (CORBA::is_nil (sep_a) ||
@@ -375,114 +1005,294 @@ TAO_StreamCtrl::bind (AVStreams::StreamEndPoint_A_ptr sep_a,
"a_party or b_party null!"),
0);
+ // Define each other as their peers.
+ CORBA::Any sep_any;
+ sep_any <<= sep_b;
+ sep_a->define_property ("PeerAdapter",
+ sep_any,
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ sep_any <<= sep_a;
+ sep_b->define_property ("PeerAdapter",
+ sep_any,
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK;
// since its full profile we do the viable stream setup algorithm.
// get the flows for the A streamendpoint.
- if (the_flows.length () == 0)
+ // the flows spec is empty and hence we do a exhaustive match.
+ AVStreams::flowSpec a_flows,b_flows;
+ CORBA::Any_var flows_any;
+ flows_any = sep_a->get_property_value ("Flows",ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ AVStreams::flowSpec_ptr temp_flows;
+ flows_any.in () >>= temp_flows;
+ a_flows = *temp_flows;
+ flows_any = sep_b->get_property_value ("Flows",ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ flows_any.in () >>= temp_flows;
+ b_flows = *temp_flows;
+ u_int i;
+ FlowEndPoint_Map *a_fep_map;
+ FlowEndPoint_Map *b_fep_map;
+ ACE_NEW_RETURN (a_fep_map,
+ FlowEndPoint_Map,
+ 0);
+ ACE_NEW_RETURN (b_fep_map,
+ FlowEndPoint_Map,
+ 0);
+ for (i=0;i<a_flows.length ();i++)
{
- // the flows spec is empty and hence we do a exhaustive match.
- AVStreams::flowSpec *a_flows = 0,*b_flows = 0;
- AVStreams::FlowEndPoint_seq a_feps,b_feps;
- CORBA::Any_ptr flows_any;
- flows_any = sep_a->get_property_value ("Flows",ACE_TRY_ENV);
+ const char *flowname = a_flows[i];
+ // get the flowendpoint references.
+ CORBA::Object_var fep_obj =
+ sep_a->get_fep (flowname,
+ ACE_TRY_ENV);
ACE_TRY_CHECK;
- *flows_any >>= a_flows;
- flows_any = sep_b->get_property_value ("Flows",ACE_TRY_ENV);
+ AVStreams::FlowEndPoint_ptr fep =
+ AVStreams::FlowEndPoint::_narrow (fep_obj.in (),
+ ACE_TRY_ENV);
ACE_TRY_CHECK;
- *flows_any >>= b_flows;
- u_int i;
- for (i=0;i<a_flows->length ();i++)
- {
- // get the flowendpoint references.
- CORBA::Object_ptr fep_obj;
- fep_obj = sep_a->get_fep ((*a_flows)[i],
- ACE_TRY_ENV);
- ACE_TRY_CHECK;
- AVStreams::FlowEndPoint_ptr fep;
- fep = AVStreams::FlowEndPoint::_narrow (fep_obj,
- ACE_TRY_ENV);
- ACE_TRY_CHECK;
- a_feps [i] = fep;
- }
- // get the flowendpoints for streamendpoint_b
- for (i=0;i<b_flows->length ();i++)
+ TAO_String_Hash_Key fep_key (flowname);
+ result = a_fep_map->bind (fep_key,fep);
+ if (result == -1)
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"TAO_StreamCtrl::bind failed for %s",flowname));
+ }
+ // get the flowendpoints for streamendpoint_b
+ for (i=0;i<b_flows.length ();i++)
+ {
+ const char *flowname = b_flows[i];
+ // get the flowendpoint references.
+ CORBA::Object_var fep_obj =
+ sep_b->get_fep (flowname,
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ AVStreams::FlowEndPoint_ptr fep =
+ AVStreams::FlowEndPoint::_narrow (fep_obj.in (),
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ TAO_String_Hash_Key fep_key (flowname);
+ result = b_fep_map->bind (fep_key,fep);
+ if (result == -1)
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"TAO_StreamCtrl::bind failed for %s",flowname));
+ }
+ FlowEndPoint_Map *map_a = 0,*map_b = 0;
+ if (flow_spec.length () == 0)
+ {
+ map_a = a_fep_map;
+ map_b = b_fep_map;
+ }
+ else
+ {
+ FlowEndPoint_Map *spec_fep_map_a,*spec_fep_map_b;
+ ACE_NEW_RETURN (spec_fep_map_a,
+ FlowEndPoint_Map,
+ 0);
+ ACE_NEW_RETURN (spec_fep_map_b,
+ FlowEndPoint_Map,
+ 0);
+ for (i=0; i< flow_spec.length ();i++)
{
- // get the flowendpoint references.
- CORBA::Object_ptr fep_obj;
- fep_obj = sep_b->get_fep ((*b_flows)[i],
- ACE_TRY_ENV);
- ACE_TRY_CHECK;
+ TAO_Forward_FlowSpec_Entry *entry;
+ ACE_NEW_RETURN (entry,
+ TAO_Forward_FlowSpec_Entry,
+ 0);
+ entry->parse (flow_spec[i].in ());
+ TAO_String_Hash_Key fep_key (entry->flowname ());
AVStreams::FlowEndPoint_ptr fep;
- fep = AVStreams::FlowEndPoint::_narrow (fep_obj,
- ACE_TRY_ENV);
- ACE_TRY_CHECK;
- b_feps [i] = fep;
+ result = a_fep_map->find (fep_key,fep);
+ if (result == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,"Fep not found on A side for flowname: %s",flow_spec[i].in ()),0);
+
+ result = spec_fep_map_a->bind (fep_key,fep);
+ if (result == -1)
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"Bind faile for %s",flow_spec[i].in ()));
+
+ result = b_fep_map->find (fep_key,fep);
+ if (result == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,"Fep not found on B side for flowname: %s",flow_spec[i].in ()),0);
+
+ result = spec_fep_map_b->bind (fep_key,fep);
+ if (result == -1)
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"Bind faile for %s",flow_spec[i].in ()));
}
- // Now go thru the list of flow endpoint and match them.
- // uses the first match policy.
- for (i=0;i<a_feps.length ();i++)
+ map_a = spec_fep_map_a;
+ map_b = spec_fep_map_b;
+ }
+
+ TAO_AV_QoS qos (stream_qos);
+ // Now go thru the list of flow endpoint and match them.
+ // uses the first match policy.
+ FlowEndPoint_Map_Iterator a_feps_iterator (*map_a);
+ FlowEndPoint_Map_Entry *a_feps_entry, *b_feps_entry;
+ ACE_TRY_EX (flow_connect)
+ {
+
+ for (;a_feps_iterator.next (a_feps_entry) != 0;
+ a_feps_iterator.advance ())
{
- for (u_int j=0;j<b_feps.length ();j++)
+ AVStreams::FlowEndPoint_ptr fep_a = a_feps_entry->int_id_;
+ AVStreams::FlowEndPoint_var connected_to =
+ fep_a->get_connected_fep (ACE_TRY_ENV);
+ ACE_TRY_CHECK_EX (flow_connect);
+
+ if (!CORBA::is_nil (connected_to.in ()))
{
- AVStreams::FlowEndPoint_ptr fep_a =
- AVStreams::FlowEndPoint::_narrow (a_feps [i],ACE_TRY_ENV);
- ACE_TRY_CHECK;
- AVStreams::FlowEndPoint_ptr fep_b =
- AVStreams::FlowEndPoint::_narrow (b_feps [j],ACE_TRY_ENV);
+ // Skip this one, it is already connected...
+ continue;
+ }
- if (fep_b->get_connected_fep () != 0)
+ FlowEndPoint_Map_Iterator b_feps_iterator (*map_b);
+ for (;b_feps_iterator.next (b_feps_entry) != 0;
+ b_feps_iterator.advance ())
+ {
+ AVStreams::FlowEndPoint_ptr fep_b = b_feps_entry->int_id_;
+ AVStreams::FlowConnection_var flow_connection;
+
+ AVStreams::FlowEndPoint_var connected_to =
+ fep_b->get_connected_fep (ACE_TRY_ENV);
+ ACE_TRY_CHECK_EX (flow_connect);
+
+ if (!CORBA::is_nil (connected_to.in ()))
+ {
+ // Skip this one, it is already connected...
+ continue;
+ }
+
+ if (fep_a->is_fep_compatible (fep_b,
+ ACE_TRY_ENV) == 1)
{
- if (fep_a->is_fep_compatible (fep_b,
- ACE_TRY_ENV) == 1)
+ ACE_TRY_CHECK_EX (flow_connect);
+ // assume that flow names are same so that we
+ // can use either of them.
+ CORBA::Object_var flow_connection_obj;
+ CORBA::Any_var flowname_any =
+ fep_a->get_property_value ("Flow",
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK_EX (flow_connect);
+ char *flowname = 0;
+ flowname_any.in () >>= flowname;
+ ACE_TRY_EX (flow_connection)
{
- // assume that flow names are same so that we
- // can use either of them.
- CORBA::Object_ptr flow_connection_obj;
- AVStreams::FlowConnection_ptr flow_connection;
- if ((flow_connection_obj
- = this->get_flow_connection ((*a_flows)[i],ACE_TRY_ENV))!= 0)
- {
- flow_connection = AVStreams::FlowConnection::_narrow (flow_connection_obj,ACE_TRY_ENV);
- ACE_TRY_CHECK;
- }
- else
+ flow_connection_obj =
+ this->get_flow_connection (flowname,
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK_EX (flow_connection);
+ flow_connection =
+ AVStreams::FlowConnection::_narrow (flow_connection_obj.in (),
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK_EX (flow_connection);
+ }
+ ACE_CATCHANY
+ {
+ TAO_FlowConnection *flowConnection;
+ ACE_NEW_RETURN (flowConnection,
+ TAO_FlowConnection,
+ 0);
+ flow_connection = flowConnection->_this (ACE_TRY_ENV);
+ ACE_TRY_CHECK_EX (flow_connect);
+ this->set_flow_connection (flowname,
+ flow_connection.in (),
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK_EX (flow_connect);
+ }
+ ACE_ENDTRY;
+ ACE_CHECK_RETURN (0);
+
+ // make sure that a_feps is flow_producer
+ // and b_feps is flow_consumer
+ // There should be a way to find which flow
+ // endpoint is producer and which is
+ // consumer.
+
+ AVStreams::FlowProducer_var producer;
+ AVStreams::FlowConsumer_var consumer;
+
+ ACE_TRY_EX (producer_check)
+ {
+ producer =
+ AVStreams::FlowProducer::_narrow (fep_a,
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK_EX (producer_check);
+ consumer =
+ AVStreams::FlowConsumer::_narrow (fep_b,
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK_EX (producer_check);
+
+ // If the types don't match then try in
+ // the opposite order
+ if (CORBA::is_nil (producer.in ()))
{
- TAO_FlowConnection *flowConnection;
- ACE_NEW_RETURN (flowConnection,TAO_FlowConnection,0);
- flow_connection = flowConnection->_this (ACE_TRY_ENV);
- ACE_TRY_CHECK;
+ producer =
+ AVStreams::FlowProducer::_narrow (fep_b,
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK_EX (producer_check);
+ consumer =
+ AVStreams::FlowConsumer::_narrow (fep_a,
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK_EX (producer_check);
}
- // make sure that a_feps is flow_producer and b_feps is flow_consumer
- // There should be a way to find which flow endpoint is producer and which is consumer.
- AVStreams::FlowProducer_ptr producer =
- AVStreams::FlowProducer::_narrow (fep_a,ACE_TRY_ENV);
- ACE_TRY_CHECK;
- AVStreams::FlowConsumer_ptr consumer =
- AVStreams::FlowConsumer::_narrow (fep_b,ACE_TRY_ENV);
- ACE_TRY_CHECK;
- // what should be passed to QoS?
- flow_connection->connect (producer,consumer,the_qos [0],ACE_TRY_ENV);
- fep_a->set_peer (flow_connection,fep_b,the_qos[0],ACE_TRY_ENV);
- fep_b->set_peer (flow_connection,fep_a,the_qos[0],ACE_TRY_ENV);
+ // At this point they should both be
+ // non-nil
+ // @@ raise an exception (which one?) if
+ // this is not true...
+ ACE_ASSERT (!CORBA::is_nil (producer.in ()));
+ ACE_ASSERT (!CORBA::is_nil (consumer.in ()));
}
+ ACE_CATCHANY
+ {
+ ACE_RETHROW;
+ }
+ ACE_ENDTRY;
+ ACE_CHECK_RETURN (0);
+ CORBA::String_var fep_a_name,fep_b_name;
+ CORBA::String temp_name;
+ flowname_any = fep_a->get_property_value ("FlowName",
+ ACE_TRY_ENV);
+ flowname_any.in () >>= temp_name;
+ fep_a_name = CORBA::string_dup (temp_name);
+ flowname_any = fep_b->get_property_value ("FlowName",
+ ACE_TRY_ENV);
+ flowname_any.in () >>= temp_name;
+ fep_b_name = CORBA::string_dup (temp_name);
+ AVStreams::QoS flow_qos;
+ flow_qos.QoSType = fep_a_name;
+ flow_qos.QoSParams.length (0);
+ result = qos.get_flow_qos (fep_a_name.in (),flow_qos);
+ if (result == -1)
+ {
+ flow_qos.QoSType = fep_b_name;
+ result = qos.get_flow_qos (fep_b_name.in (),
+ flow_qos);
+ if (result == -1 && TAO_debug_level > 0)
+ ACE_DEBUG ((LM_DEBUG,
+ "No QoS Specified for this flow <%s>\n", flowname));
+ }
+ flow_connection->connect (producer.in (),
+ consumer.in (),
+ flow_qos,
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK_EX (flow_connect);
}
}
}
}
- else
+ ACE_CATCHANY
{
- // since the flow spec is not empty we need to query for the
- // flows mentioned on both the A and B sides.
- // not implemented yet.
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,
+ "TAO_StreamCtrl::bind:flow_connect block");
+ return 0;
}
+ ACE_ENDTRY;
+ ACE_CHECK_RETURN (0);
}
ACE_CATCHANY
{
// error was thrown because one of the streamendpoints is light profile.
// Now connect the streams together
this->sep_a_->connect (this->sep_b_.in (),
- the_qos,
- the_flows,
- ACE_TRY_ENV);
+ stream_qos,
+ flow_spec,
+ ACE_TRY_ENV);
ACE_TRY_CHECK;
}
ACE_ENDTRY;
@@ -491,24 +1301,20 @@ TAO_StreamCtrl::bind (AVStreams::StreamEndPoint_A_ptr sep_a,
}
void
-TAO_StreamCtrl::unbind (CORBA::Environment &ACE_TRY_ENV)
+TAO_StreamCtrl::unbind (CORBA::Environment &/* ACE_TRY_ENV */)
ACE_THROW_SPEC ((CORBA::SystemException,
AVStreams::streamOpFailed))
{
- ACE_UNUSED_ARG (ACE_TRY_ENV);
}
void
-TAO_StreamCtrl::unbind_party (AVStreams::StreamEndPoint_ptr the_ep,
- const AVStreams::flowSpec &the_spec,
- CORBA::Environment &ACE_TRY_ENV)
+TAO_StreamCtrl::unbind_party (AVStreams::StreamEndPoint_ptr /* the_ep */,
+ const AVStreams::flowSpec &/* the_spec */,
+ CORBA::Environment &/* ACE_TRY_ENV */)
ACE_THROW_SPEC ((CORBA::SystemException,
AVStreams::streamOpFailed,
AVStreams::noSuchFlow))
{
- ACE_UNUSED_ARG (the_ep);
- ACE_UNUSED_ARG (the_spec);
- ACE_UNUSED_ARG (ACE_TRY_ENV);
}
void
@@ -519,17 +1325,27 @@ TAO_StreamCtrl::unbind_dev (AVStreams::MMDevice_ptr /* dev */,
AVStreams::streamOpFailed,
AVStreams::noSuchFlow))
{
-
}
AVStreams::VDev_ptr
-TAO_StreamCtrl::get_related_vdev (AVStreams::MMDevice_ptr /* adev */,
- AVStreams::StreamEndPoint_out /* sep */,
+TAO_StreamCtrl::get_related_vdev (AVStreams::MMDevice_ptr adev,
+ AVStreams::StreamEndPoint_out sep,
CORBA::Environment &/* ACE_TRY_ENV */)
ACE_THROW_SPEC ((CORBA::SystemException,
AVStreams::streamOpFailed))
{
- return AVStreams::VDev::_nil ();
+ MMDevice_Map_Hash_Key key (adev);
+ MMDevice_Map_Entry entry;
+ int result = -1;
+ result = this->mmdevice_a_map_.find (key,entry);
+ if (result < 0)
+ {
+ result = this->mmdevice_a_map_.find (key,entry);
+ if (result < 0)
+ return AVStreams::VDev::_nil ();
+ }
+ sep = AVStreams::StreamEndPoint::_duplicate (entry.sep_.in ());
+ return AVStreams::VDev::_duplicate (entry.vdev_.in ());
}
CORBA::Boolean
@@ -543,7 +1359,7 @@ TAO_StreamCtrl::modify_QoS (AVStreams::streamQoS &the_qos,
if (this->mcastconfigif_ != 0)
{
// call modify_Qos on the root VDev which is the mcast configif.
- ACE_DEBUG ((LM_DEBUG,"Cannot Modify the Qos for multipoint streams\n"));
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"Cannot Modify the Qos for multipoint streams\n"));
}
else
{
@@ -556,55 +1372,170 @@ TAO_StreamCtrl::modify_QoS (AVStreams::streamQoS &the_qos,
// TAO_MCastConfigIf
// ----------------------------------------------------------------------
+TAO_MCastConfigIf::TAO_MCastConfigIf (void)
+ :peer_list_iterator_ (peer_list_)
+{
+}
+
+TAO_MCastConfigIf::~TAO_MCastConfigIf (void)
+{
+ //no-op
+}
+
+// In future this should be a multicast message instead of point-to-point unicasts.
CORBA::Boolean
-TAO_MCastConfigIf::set_peer (CORBA::Object_ptr /* peer */,
- AVStreams::streamQoS & /* the_qos */,
- const AVStreams::flowSpec & /* the_spec */,
- CORBA::Environment &/* ACE_TRY_ENV */)
+TAO_MCastConfigIf::set_peer (CORBA::Object_ptr peer,
+ AVStreams::streamQoS & qos,
+ const AVStreams::flowSpec & flow_spec,
+ CORBA::Environment &ACE_TRY_ENV)
ACE_THROW_SPEC ((CORBA::SystemException,
AVStreams::QoSRequestFailed,
AVStreams::streamOpFailed))
{
- return 0;
+ ACE_TRY
+ {
+ Peer_Info *info;
+ ACE_NEW_RETURN (info,
+ Peer_Info,
+ 0);
+ info->peer_ = AVStreams::VDev::_narrow (peer,ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ info->qos_ = qos;
+ info->flow_spec_ = flow_spec;
+ this->peer_list_.insert_tail (info);
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"TAO_MCastConfigIf::set_peer");
+ return 0;
+ }
+ ACE_ENDTRY;
+ ACE_CHECK_RETURN (0);
+ return 1;
}
+// In future this should be a multicast message instead of point-to-point unicasts.
void
-TAO_MCastConfigIf::configure (const CosPropertyService::Property & /* a_configuration */,
- CORBA::Environment &/* ACE_TRY_ENV */)
+TAO_MCastConfigIf::configure (const CosPropertyService::Property & a_configuration,
+ CORBA::Environment &ACE_TRY_ENV)
ACE_THROW_SPEC ((CORBA::SystemException))
{
+ Peer_Info *info;
+ ACE_TRY
+ {
+ this->peer_list_iterator_.first ();
+ info = this->peer_list_iterator_.next ();
+ while (info != 0)
+ {
+ info->peer_->configure (a_configuration,ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ info = this->peer_list_iterator_.next ();
+ }
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"TAO_MCastConfigIf::set_configure");
+ return;
+ }
+ ACE_ENDTRY;
+ ACE_CHECK;
}
+
void
-TAO_MCastConfigIf::set_initial_configuration (const CosPropertyService::Properties & /* initial */,
- CORBA::Environment &/* ACE_TRY_ENV */)
+TAO_MCastConfigIf::set_initial_configuration (const CosPropertyService::Properties &initial,
+ CORBA::Environment &/*ACE_TRY_ENV*/)
ACE_THROW_SPEC ((CORBA::SystemException))
{
+ this->initial_configuration_ = initial;
}
+// In future this should be a multicast message instead of point-to-point unicasts.
void
-TAO_MCastConfigIf::set_format (const char * /* flowName */,
- const char * /* format_name */,
- CORBA::Environment &/* ACE_TRY_ENV */)
+TAO_MCastConfigIf::set_format (const char * flowName,
+ const char * format_name,
+ CORBA::Environment &ACE_TRY_ENV)
ACE_THROW_SPEC ((CORBA::SystemException,
AVStreams::notSupported))
{
+ Peer_Info *info;
+ ACE_TRY
+ {
+ this->peer_list_iterator_.first ();
+ info = this->peer_list_iterator_.next ();
+ while (info != 0)
+ {
+ if (this->in_flowSpec (info->flow_spec_,flowName))
+ {
+ info->peer_->set_format (flowName,format_name,ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ }
+ info = this->peer_list_iterator_.next ();
+ }
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"TAO_MCastConfigIf::set_format");
+ return;
+ }
+ ACE_ENDTRY;
+ ACE_CHECK;
}
+// In future this should be a multicast message instead of point-to-point unicasts.
void
-TAO_MCastConfigIf::set_dev_params (const char * /* flowName */,
- const CosPropertyService::Properties & /* new_params */,
- CORBA::Environment &/* ACE_TRY_ENV */)
+TAO_MCastConfigIf::set_dev_params (const char * flowName,
+ const CosPropertyService::Properties & new_params,
+ CORBA::Environment &ACE_TRY_ENV)
ACE_THROW_SPEC ((CORBA::SystemException,
AVStreams::PropertyException,
AVStreams::streamOpFailed))
{
+ Peer_Info *info;
+ ACE_TRY
+ {
+
+ this->peer_list_iterator_.first ();
+ info = this->peer_list_iterator_.next ();
+ while (info != 0)
+ {
+ if (this->in_flowSpec (info->flow_spec_,flowName))
+ {
+ info->peer_->set_dev_params (flowName,new_params,ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ }
+ info = this->peer_list_iterator_.next ();
+ }
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"TAO_MCastConfigIf::set_dev_params");
+ return;
+ }
+ ACE_ENDTRY;
+ ACE_CHECK;
+}
+
+int
+TAO_MCastConfigIf::in_flowSpec (const AVStreams::flowSpec& flow_spec, const char *flow_name)
+{
+ int len = strlen (flow_name);
+ for (u_int i=0;i<flow_spec.length ();i++)
+ if (ACE_OS::strncmp (flow_spec[i],flow_name,len) == 0)
+ {
+ return 1;
+ }
+ return 0;
}
// ----------------------------------------------------------------------
// TAO_Base_StreamEndPoint
// ----------------------------------------------------------------------
+TAO_Base_StreamEndPoint::TAO_Base_StreamEndPoint (void)
+{
+}
+
TAO_Base_StreamEndPoint::~TAO_Base_StreamEndPoint (void)
{
}
@@ -617,231 +1548,304 @@ TAO_Base_StreamEndPoint::handle_close (void)
return -1;
}
-
-// ----------------------------------------------------------------------
-// TAO_Client_StreamEndPoint
-// ----------------------------------------------------------------------
-
-TAO_Client_StreamEndPoint::TAO_Client_StreamEndPoint (void)
+int
+TAO_Base_StreamEndPoint::handle_open (void)
{
- ACE_DEBUG ((LM_DEBUG,
- "(%P|%t) TAO_Client_StreamEndPoint::TAO_Client_StreamEndPoint: created\n"));
+ return 0;
}
-CORBA::Boolean
-TAO_Client_StreamEndPoint::connect (AVStreams::StreamEndPoint_ptr responder,
- AVStreams::streamQoS &qos_spec,
- const AVStreams::flowSpec &the_spec,
- CORBA::Environment &ACE_TRY_ENV)
- ACE_THROW_SPEC ((CORBA::SystemException,
- AVStreams::noSuchFlow,
- AVStreams::QoSRequestFailed,
- AVStreams::streamOpFailed))
+int
+TAO_Base_StreamEndPoint::handle_stop (const AVStreams::flowSpec &,
+ CORBA::Environment &)
{
- CORBA::Boolean retv = 0;
-
- ACE_TRY
- {
- AVStreams::flowSpec flow_spec (the_spec);
- this->handle_preconnect (flow_spec);
-
- AVStreams::StreamEndPoint_var streamendpoint = this->_this (ACE_TRY_ENV);
- ACE_TRY_CHECK;
- // Use the base class implementation of connect
- responder->request_connection (streamendpoint.in (),
- 0,
- qos_spec,
- flow_spec,
- ACE_TRY_ENV);
+ return 0;
+}
- ACE_TRY_CHECK;
+int
+TAO_Base_StreamEndPoint::handle_start (const AVStreams::flowSpec &,
+ CORBA::Environment &)
+{
+ return 0;
+}
- // Make the upcall to the app
- retv = this->handle_postconnect (flow_spec);
- }
- ACE_CATCHANY
- {
- return 0;
- }
- ACE_ENDTRY;
- ACE_CHECK_RETURN (0);
- return retv;
+int
+TAO_Base_StreamEndPoint::handle_destroy (const AVStreams::flowSpec &,
+ CORBA::Environment &)
+{
+ return 0;
}
+// The following function is for backward compatibility.
+CORBA::Boolean
+TAO_Base_StreamEndPoint::handle_preconnect (AVStreams::flowSpec &)
+{
+ return 1;
+}
-// @@ Need to throw not-supported exception here
+// The following function is for backward compatibility.
CORBA::Boolean
-TAO_Client_StreamEndPoint::multiconnect (AVStreams::streamQoS &the_qos,
- AVStreams::flowSpec &the_spec,
- CORBA::Environment &ACE_TRY_ENV)
- ACE_THROW_SPEC ((CORBA::SystemException,
- AVStreams::noSuchFlow,
- AVStreams::QoSRequestFailed,
- AVStreams::streamOpFailed))
+TAO_Base_StreamEndPoint::handle_postconnect (AVStreams::flowSpec &)
{
- ACE_UNUSED_ARG (the_qos);
- ACE_UNUSED_ARG (the_spec);
- ACE_UNUSED_ARG (ACE_TRY_ENV);
- return 0;
+ return 1;
}
-// Multicast is not supported yet.
+// The following function is for backward compatibility.
CORBA::Boolean
-TAO_Client_StreamEndPoint::connect_leaf (AVStreams::StreamEndPoint_B_ptr the_ep,
- AVStreams::streamQoS &the_qos,
- const AVStreams::flowSpec &the_flows,
- CORBA::Environment &ACE_TRY_ENV)
- ACE_THROW_SPEC ((CORBA::SystemException,
- AVStreams::streamOpFailed,
- AVStreams::noSuchFlow,
- AVStreams::QoSRequestFailed,
- AVStreams::notSupported))
+TAO_Base_StreamEndPoint::handle_connection_requested (AVStreams::flowSpec &,
+ CORBA::Environment &)
{
- ACE_UNUSED_ARG (the_ep);
- ACE_UNUSED_ARG (the_qos);
- ACE_UNUSED_ARG (the_flows);
- ACE_UNUSED_ARG (ACE_TRY_ENV);
- return 0;
+ return 1;
}
-// Multicast not supported yet.
-void
-TAO_Client_StreamEndPoint::disconnect_leaf (AVStreams::StreamEndPoint_B_ptr the_ep,
- const AVStreams::flowSpec &theSpec,
- CORBA::Environment &ACE_TRY_ENV)
- ACE_THROW_SPEC ((CORBA::SystemException,
- AVStreams::streamOpFailed,
- AVStreams::noSuchFlow))
+int
+TAO_Base_StreamEndPoint::set_protocol_object (const char */*flowname*/,
+ TAO_AV_Protocol_Object * /*sfp_object*/)
{
- ACE_UNUSED_ARG (the_ep);
- ACE_UNUSED_ARG (theSpec);
- ACE_UNUSED_ARG (ACE_TRY_ENV);
+ return -1;
}
-TAO_Client_StreamEndPoint::~TAO_Client_StreamEndPoint (void)
+int
+TAO_Base_StreamEndPoint::get_callback (const char */*flowname*/,
+ TAO_AV_Callback *&/*sfp_callback*/)
{
+ return -1;
}
-// ----------------------------------------------------------------------
-// TAO_Server_StreamEndPoint
-// ----------------------------------------------------------------------
+int
+TAO_Base_StreamEndPoint::get_control_callback (const char */*flowname*/,
+ TAO_AV_Callback *&/*sfp_callback*/)
+{
+ return -1;
+}
-TAO_Server_StreamEndPoint::TAO_Server_StreamEndPoint (void)
+void
+TAO_Base_StreamEndPoint::set_handler (const char *flowname,
+ TAO_AV_Flow_Handler *handler)
{
- ACE_DEBUG ((LM_DEBUG,
- "\n(%P|%t) TAO_Server_StreamEndPoint::TAO_Server_StreamEndPoint: created"));
}
+// ----------------------------------------------------------------------
+// TAO_StreamEndPoint
+// ----------------------------------------------------------------------
-// Called by streamctrl, requesting us to call request_connection
-// on the responder (to initiate a connection)
-CORBA::Boolean
-TAO_Server_StreamEndPoint::connect (AVStreams::StreamEndPoint_ptr responder,
- AVStreams::streamQoS &qos_spec,
- const AVStreams::flowSpec &the_spec,
- CORBA::Environment &ACE_TRY_ENV)
- ACE_THROW_SPEC ((CORBA::SystemException,
- AVStreams::noSuchFlow,
- AVStreams::QoSRequestFailed,
- AVStreams::streamOpFailed))
+// constructor.
+
+TAO_StreamEndPoint::TAO_StreamEndPoint (void)
+ :flow_count_ (0),
+ flow_num_ (0),
+ mcast_port_ (ACE_DEFAULT_MULTICAST_PORT+1)
{
- ACE_UNUSED_ARG (responder);
- ACE_UNUSED_ARG (qos_spec);
- ACE_UNUSED_ARG (the_spec);
- ACE_UNUSED_ARG (ACE_TRY_ENV);
- ACE_ERROR_RETURN ((LM_ERROR,
- "(%P|%t) Calling TAO_Server_StreamEndPoint::connect"
- " is not compatible with the spec!"
- "\n"),
- 0);
+ this->mcast_addr_ = ACE_OS::inet_addr (ACE_DEFAULT_MULTICAST_ADDR);
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"TAO_StreamEndPoint::TAO_StreamEndPoint::mcast_addr = %ud",this->mcast_addr_));
+ // this->handle_open ();
}
+
CORBA::Boolean
-TAO_Server_StreamEndPoint::request_connection (AVStreams::StreamEndPoint_ptr initiator,
- CORBA::Boolean is_mcast,
- AVStreams::streamQoS &qos,
- AVStreams::flowSpec &the_spec,
- CORBA::Environment &ACE_TRY_ENV)
- ACE_THROW_SPEC ((CORBA::SystemException,
- AVStreams::streamOpDenied,
- AVStreams::noSuchFlow,
- AVStreams::QoSRequestFailed,
- AVStreams::FPError))
+TAO_StreamEndPoint::connect (AVStreams::StreamEndPoint_ptr responder,
+ AVStreams::streamQoS &qos,
+ const AVStreams::flowSpec &the_spec,
+ CORBA::Environment &ACE_TRY_ENV)
{
- int result = 0;
- ACE_TRY
+ CORBA::Boolean retv = 0;
+ this->peer_sep_ = AVStreams::StreamEndPoint::_duplicate (responder);
+ ACE_TRY_EX (negotiate)
{
- // Use the base class implementation of request_connection
- TAO_StreamEndPoint::request_connection (initiator,
- is_mcast,
+ if (!CORBA::is_nil (this->negotiator_.in ()))
+ {
+ CORBA::Any_var negotiator_any = responder->get_property_value ("Negotiator");
+
+ AVStreams::Negotiator_ptr peer_negotiator;
+ negotiator_any.in () >>= peer_negotiator;
+ if (!CORBA::is_nil (peer_negotiator))
+ {
+ CORBA::Boolean result =
+ this->negotiator_->negotiate (peer_negotiator,
qos,
- the_spec,
ACE_TRY_ENV);
+ ACE_TRY_CHECK_EX (negotiate);
+ if (!result)
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"TAO_StreamEndPoint::Connect (): negotiate failed\n"));
+ }
+ }
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"TAO_StreamEndPoint::negotiate");
+ }
+ ACE_ENDTRY;
+ ACE_CHECK_RETURN (0);
+
+ ACE_TRY_EX (available_protocols)
+ {
+ if (this->protocols_.length () > 0)
+ {
+ // choose protocols based on what the remote endpoint can support.
+ CORBA::Any_var protocols_any =
+ responder->get_property_value ("AvailableProtocols",ACE_TRY_ENV);
+ ACE_TRY_CHECK_EX (available_protocols);
+ AVStreams::protocolSpec peer_protocols;
+ AVStreams::protocolSpec_ptr temp_protocols;
+ protocols_any.in () >>= temp_protocols;
+ peer_protocols = *temp_protocols;
+ for (u_int i=0;i<peer_protocols.length ();i++)
+ {
+ for (u_int j=0;j<this->protocols_.length ();j++)
+ if (ACE_OS::strcmp (peer_protocols [i],
+ this->protocols_[j]) == 0)
+ {
+ // we'll agree upon the first protocol that matches.
+ this->protocol_ = CORBA::string_copy (peer_protocols [i]);
+ break;
+ }
+ }
+ }
+ }
+ ACE_CATCHANY
+ {
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"Availableprotocols property not defined\n"));
+ }
+ ACE_ENDTRY;
+ ACE_CHECK_RETURN (0);
+ ACE_TRY
+ {
+ AVStreams::streamQoS network_qos;
+ if (qos.length () > 0)
+ {
+ int result = this->translate_qos (qos,network_qos);
+ if (result != 0)
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"QoS translation failed\n"));
+ }
+ AVStreams::flowSpec flow_spec (the_spec);
+ this->handle_preconnect (flow_spec);
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"TAO_StreamEndPoint::connect: flow_spec_length = %d",
+ flow_spec.length ()));
+ u_int i;
+ for (i=0;i<flow_spec.length ();i++)
+ {
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,
+ "TAO_StreamEndPoint::connect:%s\n",
+ flow_spec[i].in ()));
+ TAO_Forward_FlowSpec_Entry *entry = 0;
+ // if (i >= FLOWSPEC_MAX)
+ ACE_NEW_RETURN (entry,
+ TAO_Forward_FlowSpec_Entry,
+ 0);
+// else
+// entry = &this->forward_entries_[i];
+ if (entry->parse (flow_spec[i]) == -1)
+ return 0;
+ this->forward_flow_spec_set.insert (entry);
+ }
+ int result =TAO_AV_CORE::instance ()->init_forward_flows (this,
+ this->forward_flow_spec_set,
+ TAO_AV_Core::TAO_AV_ENDPOINT_A,
+ flow_spec);
+ if (result < 0)
+ ACE_ERROR_RETURN ((LM_ERROR,"TAO_AV_Core::init_forward_flows failed\n"),0);
+
+ AVStreams::StreamEndPoint_var streamendpoint = this->_this (ACE_TRY_ENV);
ACE_TRY_CHECK;
- // Make the upcall to the app
- result = this->handle_connection_requested (the_spec,ACE_TRY_ENV);
+ retv = responder->request_connection (streamendpoint.in (),
+ 0,
+ network_qos,
+ flow_spec,
+ ACE_TRY_ENV);
+
ACE_TRY_CHECK;
+ if (retv == 0)
+ return retv;
+ for (i=0;i<flow_spec.length ();i++)
+ {
+ TAO_Reverse_FlowSpec_Entry *entry = 0;
+ // if (i >= FLOWSPEC_MAX)
+ ACE_NEW_RETURN (entry,
+ TAO_Reverse_FlowSpec_Entry,
+ 0);
+// else
+// entry = &this->reverse_entries_[i];
+ if (entry->parse (flow_spec[i].in ()) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,"Reverse_Flow_Spec_Set::parse failed\n"),0);
+ this->reverse_flow_spec_set.insert (entry);
+ }
+ result = TAO_AV_CORE::instance ()->init_reverse_flows (this,
+ this->forward_flow_spec_set,
+ this->reverse_flow_spec_set,
+ TAO_AV_Core::TAO_AV_ENDPOINT_A);
+ if (result < 0)
+ ACE_ERROR_RETURN ((LM_ERROR,"TAO_AV_Core::init_reverse_flows failed\n"),0);
+ // Make the upcall to the app
+ retv = this->handle_postconnect (flow_spec);
}
ACE_CATCHANY
{
- ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"TAO_Server_StreamEndpoint::request_connection");
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"TAO_StreamEndPoint::connect");
return 0;
}
ACE_ENDTRY;
- ACE_CHECK_RETURN (1);
- return result;
+ ACE_CHECK_RETURN (0);
+ return retv;
}
-CORBA::Boolean
-TAO_Server_StreamEndPoint::multiconnect (AVStreams::streamQoS &the_qos,
- AVStreams::flowSpec &the_spec,
- CORBA::Environment &ACE_TRY_ENV)
- ACE_THROW_SPEC ((CORBA::SystemException,
- AVStreams::streamOpFailed,
- AVStreams::noSuchFlow,
- AVStreams::QoSRequestFailed,
- AVStreams::FPError))
+int
+TAO_StreamEndPoint::translate_qos (const AVStreams::streamQoS& application_qos,
+ AVStreams::streamQoS& network_qos)
{
- ACE_UNUSED_ARG (the_qos);
- ACE_UNUSED_ARG (the_spec);
- ACE_UNUSED_ARG (ACE_TRY_ENV);
+ u_int len = application_qos.length ();
+ network_qos.length (len);
+ for (u_int i=0;i<len;i++)
+ {
+ network_qos [i].QoSType = application_qos [i].QoSType;
+ }
return 0;
}
-TAO_Server_StreamEndPoint::~TAO_Server_StreamEndPoint (void)
-{
-}
-
-
-// ----------------------------------------------------------------------
-// TAO_StreamEndPoint
-// ----------------------------------------------------------------------
-
-// constructor.
-
-TAO_StreamEndPoint::TAO_StreamEndPoint (void)
- :flow_count_ (1)
-{
- // this->handle_open ();
-}
-
// Stop the physical flow of data on the stream
// Empty the_spec --> apply to all flows
void
-TAO_StreamEndPoint::stop (const AVStreams::flowSpec &the_spec,
+TAO_StreamEndPoint::stop (const AVStreams::flowSpec &flow_spec,
CORBA::Environment &ACE_TRY_ENV)
ACE_THROW_SPEC ((CORBA::SystemException,
AVStreams::noSuchFlow))
{
// Make the upcall into the app
- this->handle_stop (the_spec, ACE_TRY_ENV);
+ this->handle_stop (flow_spec, ACE_TRY_ENV);
+ if (flow_spec.length () > 0)
+ {
+
+ for (u_int i=0;i<flow_spec.length ();i++)
+ {
+ TAO_AV_FlowSpecSetItor end = this->forward_flow_spec_set.end ();
+ for (TAO_AV_FlowSpecSetItor begin = this->forward_flow_spec_set.begin ();
+ begin != end; ++begin)
+ {
+ if (ACE_OS::strcmp ((*begin)->flowname (),flow_spec [i].in ()) == 0)
+ {
+ TAO_FlowSpec_Entry *entry = *begin;
+ // (*begin)->protocol_object ()->stop ();
+ entry->handler ()->stop (entry->role ());
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ TAO_AV_FlowSpecSetItor end = this->forward_flow_spec_set.end ();
+ for (TAO_AV_FlowSpecSetItor begin = this->forward_flow_spec_set.begin ();
+ begin != end; ++begin)
+ {
+ TAO_FlowSpec_Entry *entry = *begin;
+ // entry->protocol_object ()->stop ();
+ entry->handler ()->stop (entry->role ());
+ }
+ }
}
// Start the physical flow of data on the stream
// Empty the_spec --> apply to all flows
-
void
TAO_StreamEndPoint::start (const AVStreams::flowSpec &flow_spec,
CORBA::Environment &ACE_TRY_ENV)
@@ -850,87 +1854,156 @@ TAO_StreamEndPoint::start (const AVStreams::flowSpec &flow_spec,
{
// Make the upcall into the app
this->handle_start (flow_spec, ACE_TRY_ENV);
+ if (flow_spec.length () > 0)
+ {
+ // Now call start on all the flow handlers.
+ for (u_int i=0;i<flow_spec.length ();i++)
+ {
+ TAO_AV_FlowSpecSetItor end = this->forward_flow_spec_set.end ();
+ for (TAO_AV_FlowSpecSetItor begin = this->forward_flow_spec_set.begin ();
+ begin != end; ++begin)
+ {
+ TAO_FlowSpec_Entry *entry = *begin;
+ if (ACE_OS::strcmp (entry->flowname (),flow_spec [i]) == 0)
+ {
+ // entry->protocol_object ()->start ();
+ entry->handler ()->start (entry->role ());
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ TAO_AV_FlowSpecSetItor end = this->forward_flow_spec_set.end ();
+ for (TAO_AV_FlowSpecSetItor begin = this->forward_flow_spec_set.begin ();
+ begin != end; ++begin)
+ {
+ TAO_FlowSpec_Entry *entry = *begin;
+ // entry->protocol_object ()->start ();
+ entry->handler ()->start (entry->role ());
+ }
+ }
}
// Close the connection
-
void
-TAO_StreamEndPoint::destroy (const AVStreams::flowSpec &/* the_spec */,
- CORBA::Environment &ACE_TRY_ENV)
+TAO_StreamEndPoint::destroy (const AVStreams::flowSpec &flow_spec,
+ CORBA::Environment &/* ACE_TRY_ENV */)
ACE_THROW_SPEC ((CORBA::SystemException,
AVStreams::noSuchFlow))
{
-// // Make the upcall into the app
-// this->handle_destroy (the_spec, ACE_TRY_ENV);
- //
- // Remove self from POA. Because of reference counting, the POA
- // will automatically delete the servant when all pending requests
- // on this servant are complete.
- //
- PortableServer::POA_var poa = this->_default_POA (ACE_TRY_ENV);
- ACE_CHECK;
+ int result = deactivate_servant (this);
+ if (result < 0)
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"TAO_StreamEndPoint::destroy failed\n"));
- PortableServer::ObjectId_var id = poa->servant_to_id (this,
- ACE_TRY_ENV);
- ACE_CHECK;
+ if (flow_spec.length () > 0)
+ {
+ for (u_int i=0;i<flow_spec.length ();i++)
+ {
+ TAO_AV_FlowSpecSetItor end = this->forward_flow_spec_set.end ();
+ for (TAO_AV_FlowSpecSetItor begin = this->forward_flow_spec_set.begin ();
+ begin != end; ++begin)
+ {
+ TAO_FlowSpec_Entry *entry = *begin;
+ if (ACE_OS::strcmp (entry->flowname (),flow_spec [i]) == 0)
+ {
+ entry->protocol_object ()->destroy ();
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ TAO_AV_FlowSpecSetItor end = this->forward_flow_spec_set.end ();
+ for (TAO_AV_FlowSpecSetItor begin = this->forward_flow_spec_set.begin ();
+ begin != end; ++begin)
+ {
+ TAO_FlowSpec_Entry *entry = *begin;
+ entry->protocol_object ()->destroy ();
+ }
+ }
- poa->deactivate_object (id.in (),
- ACE_TRY_ENV);
- ACE_CHECK;
+ // Make the upcall into the app
+ // this->handle_destroy (the_spec, ACE_TRY_ENV);
+ //
}
// Called by our peer endpoint, requesting us to establish
// a connection
-
CORBA::Boolean
-TAO_StreamEndPoint::request_connection (AVStreams::StreamEndPoint_ptr initiator,
+TAO_StreamEndPoint::request_connection (AVStreams::StreamEndPoint_ptr /*initiator*/,
CORBA::Boolean is_mcast,
- AVStreams::streamQoS &qos,
- AVStreams::flowSpec &the_spec,
- CORBA::Environment &)
+ AVStreams::streamQoS &/*qos*/,
+ AVStreams::flowSpec &flow_spec,
+ CORBA::Environment &ACE_TRY_ENV)
ACE_THROW_SPEC ((CORBA::SystemException,
AVStreams::streamOpDenied,
AVStreams::noSuchFlow,
AVStreams::QoSRequestFailed,
AVStreams::FPError))
-{
- ACE_UNUSED_ARG (initiator);
- ACE_UNUSED_ARG (is_mcast);
- ACE_UNUSED_ARG (qos);
-
- ACE_DEBUG ((LM_DEBUG, "\n(%P|%t) TAO_StreamEndPoint::request_connection called"));
- ACE_DEBUG ((LM_DEBUG,
- "\n(%P|%t) TAO_StreamEndPoint::request_connection: "
- "flowspec has length = %d"
- "and the strings are:",
- the_spec.length ()));
- for (u_int i = 0; i < the_spec.length (); i++)
- ACE_DEBUG ((LM_DEBUG,
- the_spec [i]));
- return 0;
+{
+ int result = 0;
+ ACE_TRY
+ {
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG, "\n(%P|%t) TAO_StreamEndPoint::request_connection called"));
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,
+ "\n(%P|%t) TAO_StreamEndPoint::request_connection: "
+ "flowspec has length = %d"
+ "and the strings are:",
+ flow_spec.length ()));
+ u_int i;
+ for (i = 0; i < flow_spec.length (); i++)
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,flow_spec [i]));
+
+ for (i=0;i<flow_spec.length ();i++)
+ {
+ TAO_Forward_FlowSpec_Entry *entry = 0;
+ ACE_NEW_RETURN (entry,
+ TAO_Forward_FlowSpec_Entry,
+ 0);
+ if (entry->parse (flow_spec[i]) == -1)
+ return 0;
+ this->forward_flow_spec_set.insert (entry);
+ }
+ result = TAO_AV_CORE::instance ()->init_forward_flows (this,
+ this->forward_flow_spec_set,
+ TAO_AV_Core::TAO_AV_ENDPOINT_B,
+ flow_spec);
+ if (result < 0)
+ return 0;
+ // Make the upcall to the app
+ result = this->handle_connection_requested (flow_spec,ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"TAO_StreamEndpoint::request_connection");
+ return 0;
+ }
+ ACE_ENDTRY;
+ ACE_CHECK_RETURN (0);
+ return result;
}
-// @@ Need to throw not-supported exception here
-
+// Refers to modification of transport QoS.
CORBA::Boolean
-TAO_StreamEndPoint::modify_QoS (AVStreams::streamQoS &new_qos,
- const AVStreams::flowSpec &the_flows,
- CORBA::Environment &ACE_TRY_ENV)
+TAO_StreamEndPoint::modify_QoS (AVStreams::streamQoS &/* new_qos */,
+ const AVStreams::flowSpec &/* the_flows */,
+ CORBA::Environment &/* ACE_TRY_ENV */)
ACE_THROW_SPEC ((CORBA::SystemException,
AVStreams::noSuchFlow,
AVStreams::QoSRequestFailed))
{
- ACE_UNUSED_ARG (new_qos);
- ACE_UNUSED_ARG (the_flows);
- ACE_UNUSED_ARG (ACE_TRY_ENV);
return 0;
}
-// @@ Need to throw not-supported exception here
+// Sets the list of protocols this streamendpoint can understand.
CORBA::Boolean
-TAO_StreamEndPoint::set_protocol_restriction (const AVStreams::protocolSpec &the_pspec,
+TAO_StreamEndPoint::set_protocol_restriction (const AVStreams::protocolSpec &protocols,
CORBA::Environment &ACE_TRY_ENV)
ACE_THROW_SPEC ((CORBA::SystemException))
{
@@ -938,11 +2011,12 @@ TAO_StreamEndPoint::set_protocol_restriction (const AVStreams::protocolSpec &the
{
CORBA::Any protocol_restriction_any;
- protocol_restriction_any <<= the_pspec;
+ protocol_restriction_any <<= protocols;
this->define_property ("ProtocolRestriction",
protocol_restriction_any,
ACE_TRY_ENV);
ACE_TRY_CHECK;
+ this->protocols_ = protocols;
}
ACE_CATCHANY
{
@@ -966,21 +2040,21 @@ TAO_StreamEndPoint::disconnect (const AVStreams::flowSpec &the_spec,
ACE_UNUSED_ARG (ACE_TRY_ENV);
}
-// @@ Need to throw not-supported exception here
+// Sets the status of the flow protocol.
void
-TAO_StreamEndPoint::set_FPStatus (const AVStreams::flowSpec &the_spec,
+TAO_StreamEndPoint::set_FPStatus (const AVStreams::flowSpec &/*the_spec*/,
const char *fp_name,
const CORBA::Any &fp_settings,
- CORBA::Environment &ACE_TRY_ENV)
+ CORBA::Environment &/*ACE_TRY_ENV*/)
ACE_THROW_SPEC ((CORBA::SystemException,
AVStreams::noSuchFlow,
AVStreams::FPError))
{
- ACE_UNUSED_ARG (the_spec);
- ACE_UNUSED_ARG (fp_name);
- ACE_UNUSED_ARG (fp_settings);
- ACE_UNUSED_ARG (ACE_TRY_ENV);
+ if (ACE_OS::strcmp (fp_name,"SFP1.0") != 0)
+ return;
+ fp_settings >>= this->sfp_status_;
+ // @@Naga: We should call set_FPStatus on all the protocol objects.
}
@@ -1000,19 +2074,19 @@ TAO_StreamEndPoint::get_fep (const char *flow_name,
char *
-TAO_StreamEndPoint::add_fep (CORBA::Object_ptr the_fep,
+TAO_StreamEndPoint::add_fep (CORBA::Object_ptr fep_obj,
CORBA::Environment &ACE_TRY_ENV)
ACE_THROW_SPEC ((CORBA::SystemException,
AVStreams::notSupported,
AVStreams::streamOpFailed))
{
char *flow_name = 0;
+ AVStreams::FlowEndPoint_ptr fep = AVStreams::FlowEndPoint::_nil ();
ACE_TRY_EX (flow_name);
{
ACE_NEW_RETURN (flow_name,char [BUFSIZ],0);
CORBA::Any_ptr flow_name_any;
- AVStreams::FlowEndPoint_ptr fep =
- AVStreams::FlowEndPoint::_narrow (the_fep,ACE_TRY_ENV);
+ fep = AVStreams::FlowEndPoint::_narrow (fep_obj,ACE_TRY_ENV);
ACE_TRY_CHECK_EX (flow_name);
flow_name_any = fep->get_property_value ("FlowName",ACE_TRY_ENV);
ACE_TRY_CHECK_EX (flow_name);
@@ -1022,17 +2096,36 @@ TAO_StreamEndPoint::add_fep (CORBA::Object_ptr the_fep,
{
// exception implies the flow name is not defined and is system generated.
ACE_OS::sprintf (flow_name,"flow%d",flow_num_++);
+ ACE_TRY_EX (flow)
+ {
+ // exception implies the flow name is not defined and is system generated.
+ ACE_OS::sprintf (flow_name,"flow%d",flow_num_++);
+ CORBA::Any flowname_any;
+ flowname_any <<= flow_name;
+ fep->define_property ("Flow",flowname_any,ACE_TRY_ENV);
+ ACE_TRY_CHECK_EX (flow);
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"TAO_StreamEndPoint::add_fep");
+ return 0;
+ }
+ ACE_ENDTRY;
+ ACE_CHECK_RETURN (0);
}
ACE_ENDTRY;
- // Add it to the sequence of flowNames supported.
- // put the flowname and the flowendpoint in a hashtable.
- TAO_String_Hash_Key fep_name_key (flow_name);
- if (this->fep_map_.bind (fep_name_key,the_fep) != 0)
- {
- ACE_THROW_RETURN (AVStreams::streamOpFailed (),0);
- }
- ACE_TRY_EX (flows)
+ ACE_CHECK_RETURN (0);
+ ACE_TRY
{
+ fep->lock (ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ // Add it to the sequence of flowNames supported.
+ // put the flowname and the flowendpoint in a hashtable.
+ TAO_String_Hash_Key fep_name_key (CORBA::string_dup (flow_name));
+ if (this->fep_map_.bind (fep_name_key,fep) != 0)
+ {
+ ACE_THROW_RETURN (AVStreams::streamOpFailed (),0);
+ }
// increment the flow count.
this->flow_count_++;
this->flows_.length (this->flow_count_);
@@ -1043,7 +2136,7 @@ TAO_StreamEndPoint::add_fep (CORBA::Object_ptr the_fep,
this->define_property ("Flows",
flows_any,
ACE_TRY_ENV);
- ACE_TRY_CHECK_EX (flows);
+ ACE_TRY_CHECK;
}
ACE_CATCHANY
{
@@ -1066,7 +2159,7 @@ TAO_StreamEndPoint::remove_fep (const char *flow_name,
ACE_TRY
{
TAO_String_Hash_Key fep_name_key (flow_name);
- CORBA::Object_ptr fep_entry = 0;
+ AVStreams::FlowEndPoint_ptr fep_entry = 0;
// Remove the fep from the hash table.
if (this->fep_map_.unbind (fep_name_key,fep_entry)!= 0)
ACE_THROW (AVStreams::streamOpFailed ());
@@ -1092,8 +2185,7 @@ TAO_StreamEndPoint::remove_fep (const char *flow_name,
ACE_CHECK;
}
-// @@ Need to throw not-supported exception here
-
+// Sets the negotiator object.
void
TAO_StreamEndPoint::set_negotiator (AVStreams::Negotiator_ptr new_negotiator,
CORBA::Environment &ACE_TRY_ENV)
@@ -1107,6 +2199,7 @@ TAO_StreamEndPoint::set_negotiator (AVStreams::Negotiator_ptr new_negotiator,
negotiator,
ACE_TRY_ENV);
ACE_TRY_CHECK;
+ this->negotiator_ = AVStreams::Negotiator::_duplicate (new_negotiator);
}
ACE_CATCHANY
{
@@ -1117,7 +2210,6 @@ TAO_StreamEndPoint::set_negotiator (AVStreams::Negotiator_ptr new_negotiator,
}
// Sets the public key used for this streamendpoint.
-
void
TAO_StreamEndPoint::set_key (const char *flow_name,
const AVStreams::key & the_key,
@@ -1126,7 +2218,7 @@ TAO_StreamEndPoint::set_key (const char *flow_name,
{
ACE_TRY
{
-
+ this->key_ = the_key;
CORBA::Any PublicKey;
PublicKey <<= the_key;
char PublicKey_property [BUFSIZ];
@@ -1145,7 +2237,6 @@ TAO_StreamEndPoint::set_key (const char *flow_name,
}
// Set the source id.
-
void
TAO_StreamEndPoint::set_source_id (CORBA::Long source_id,
CORBA::Environment &)
@@ -1154,10 +2245,405 @@ TAO_StreamEndPoint::set_source_id (CORBA::Long source_id,
this->source_id_ = source_id;
}
+CORBA::Boolean
+TAO_StreamEndPoint::multiconnect (AVStreams::streamQoS &/*the_qos*/,
+ AVStreams::flowSpec &/*flow_spec*/,
+ CORBA::Environment &/*ACE_TRY_ENV*/)
+{
+ return 0;
+}
TAO_StreamEndPoint::~TAO_StreamEndPoint (void)
{
//this->handle_close ();
+ TAO_AV_FlowSpecSetItor begin = this->forward_flow_spec_set.begin ();
+ TAO_AV_FlowSpecSetItor end = this->forward_flow_spec_set.end ();
+ int i=0;
+ // @@ Naga: Will the iterator always give the entries in the order of insertion.
+ // or is it an implementation fact of ACE containers.
+ for ( ; begin != end; ++begin,++i)
+ {
+// if (i >= FLOWSPEC_MAX)
+// {
+ TAO_FlowSpec_Entry *entry = *begin;
+ delete entry;
+ // }
+ }
+ begin = this->reverse_flow_spec_set.begin ();
+ end = this->reverse_flow_spec_set.end ();
+ i = 0;
+ for (; begin != end; ++begin)
+ {
+// if (i >= FLOWSPEC_MAX)
+// {
+ TAO_FlowSpec_Entry *entry = *begin;
+ delete entry;
+ // }
+ }
+}
+
+
+// ----------------------------------------------------------------------
+// TAO_StreamEndPoint_A
+// ----------------------------------------------------------------------
+
+TAO_StreamEndPoint_A::TAO_StreamEndPoint_A (void)
+{
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"(%P|%t) TAO_StreamEndPoint_A::TAO_StreamEndPoint_A: created\n"));
+}
+
+// IP Multicast style connect.
+CORBA::Boolean
+TAO_StreamEndPoint_A::multiconnect (AVStreams::streamQoS &stream_qos,
+ AVStreams::flowSpec &flow_spec,
+ CORBA::Environment &ACE_TRY_ENV)
+{
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"TAO_StreamEndPoint::multiconnect\n"));
+ ACE_TRY
+ {
+ int result = 0;
+ TAO_AV_QoS qos (stream_qos);
+ for (u_int i=0;i< flow_spec.length ();i++)
+ {
+ TAO_Forward_FlowSpec_Entry *forward_entry;
+ ACE_NEW_RETURN (forward_entry,
+ TAO_Forward_FlowSpec_Entry,
+ 0);
+ forward_entry->parse (flow_spec[i]);
+ TAO_String_Hash_Key mcast_key (forward_entry->flowname ());
+ AVStreams::FlowEndPoint_ptr flow_endpoint = AVStreams::FlowEndPoint::_nil ();
+ // @@Naga: There is a problem in the full profile case for multiconnect. Since
+ // multiconnect on sep_a is called everytime a sink is added and if called for
+ // the same flow twice, the following code will just call add producer on the flow connection.
+ // It is however very hard to find out if the flow producer is already in the flow connection
+ // since comparing object references will not work and the flowproducer reference is
+ // generated by _narrow. Our only hope is that _narrow on the same fep will return the same
+ // pointer for the flowproducer in which case we can find out if the flowproducer exists in
+ // fep set for that flowconnection.
+ if (this->fep_map_.find (mcast_key,flow_endpoint) == 0)
+ {
+ ACE_TRY_EX (narrow)
+ {
+ AVStreams::QoS flow_qos;
+ result = qos.get_flow_qos (forward_entry->flowname (),flow_qos);
+ if (result < 0)
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"QoS not found for %s",forward_entry->flowname ()));
+ // Narrow it to FlowProducer.
+ AVStreams::FlowProducer_var producer = AVStreams::FlowProducer::_narrow (flow_endpoint,ACE_TRY_ENV);
+ ACE_TRY_CHECK_EX (narrow);
+ // Else narrow succeeeded.
+ if (!CORBA::is_nil (producer.in ()))
+ {
+ AVStreams::FlowConnection_var flow_connection;
+ ACE_TRY_EX (flow_connection)
+ {
+ if (CORBA::is_nil (this->streamctrl_.in ()))
+ {
+ CORBA::Any_var streamctrl_any;
+ streamctrl_any = this->get_property_value ("Related_StreamCtrl",
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ AVStreams::StreamCtrl_ptr streamctrl;
+ streamctrl_any.in () >>= streamctrl;
+ this->streamctrl_ = AVStreams::StreamCtrl::_duplicate (streamctrl);
+ }
+
+ CORBA::Object_var flow_connection_obj =
+ this->streamctrl_->get_flow_connection (forward_entry->flowname (),
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK_EX (flow_connection);
+ flow_connection = AVStreams::FlowConnection::_narrow (flow_connection_obj.in (),
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK_EX (flow_connection);
+ }
+ ACE_CATCHANY
+ {
+ TAO_FlowConnection *flowConnection;
+ ACE_NEW_RETURN (flowConnection,
+ TAO_FlowConnection,
+ 0);
+ //@@ Strategize the multicast address allocation.
+ flowConnection->set_mcast_addr (this->mcast_addr_,this->mcast_port_);
+ this->mcast_port_++;
+ flowConnection->set_protocol (forward_entry->carrier_protocol_str ());
+ flow_connection = flowConnection->_this (ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ this->streamctrl_->set_flow_connection (forward_entry->flowname (),
+ flow_connection.in (),
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ }
+ ACE_ENDTRY;
+ ACE_CHECK_RETURN (0);
+ if (ACE_OS::strcmp (forward_entry->flow_protocol_str (),"") != 0)
+ {
+ CORBA::Any fp_settings;
+ flow_connection->use_flow_protocol (forward_entry->flow_protocol_str (),
+ fp_settings,
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ }
+ result = flow_connection->add_producer (producer.in (),
+ flow_qos,
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ if (result == 0)
+ ACE_ERROR_RETURN ((LM_ERROR,"TAO_StreamEndPoint_A::multiconnect: add_producer failed\n"),0);
+ }
+ }
+ ACE_CATCHANY
+ {
+ // Narrow failed and since its not a flowproducer its an error.
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"FlowProducer::_narrow");
+ ACE_ERROR_RETURN ((LM_ERROR,"sep_a doesn't contain a flowproducer"),0);
+ }
+ ACE_ENDTRY;
+ ACE_CHECK_RETURN (0);
+ }
+ else
+ {
+ ACE_INET_Addr *mcast_addr;
+ TAO_FlowSpec_Entry *entry = 0;
+ result = this->mcast_entry_map_.find (mcast_key,entry);
+ if (result == 0)
+ {
+ mcast_addr = ACE_dynamic_cast (ACE_INET_Addr *,entry->address ());
+ char str_addr [BUFSIZ];
+ result = mcast_addr->addr_to_string (str_addr,BUFSIZ);
+ if (result < 0)
+ ACE_ERROR_RETURN ((LM_ERROR,"TAO_StreamEndPoint::multiconnect ::addr_to_string failed\n"),0);
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"TAO_StreamEndPoint_A::multiconnect:%s\n",str_addr));
+ TAO_Forward_FlowSpec_Entry new_entry (entry->flowname (),
+ entry->direction_str (),
+ entry->format (),
+ entry->flow_protocol_str (),
+ entry->carrier_protocol_str (),
+ entry->address ());
+ flow_spec[i] = CORBA::string_dup (new_entry.entry_to_string ());
+ }
+ else
+ {
+
+ switch (forward_entry->direction ())
+ {
+ case TAO_FlowSpec_Entry::TAO_AV_DIR_IN:
+ {
+ ACE_NEW_RETURN (mcast_addr,
+ ACE_INET_Addr,
+ 0);
+ mcast_addr->set (this->mcast_port_,this->mcast_addr_);
+ this->mcast_port_++;
+ char buf[BUFSIZ];
+ mcast_addr->addr_to_string (buf,BUFSIZ);
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"%s\n",buf));
+ TAO_Forward_FlowSpec_Entry *new_entry;
+ ACE_NEW_RETURN (new_entry,
+ TAO_Forward_FlowSpec_Entry (forward_entry->flowname (),
+ forward_entry->direction_str (),
+ forward_entry->format (),
+ forward_entry->flow_protocol_str (),
+ forward_entry->carrier_protocol_str (),
+ mcast_addr),
+ 0);
+ flow_spec[i] = CORBA::string_dup (new_entry->entry_to_string ());
+
+ this->forward_flow_spec_set.insert (new_entry);
+ TAO_AV_Acceptor_Registry *acceptor_registry = TAO_AV_CORE::instance ()->acceptor_registry ();
+ result = acceptor_registry->open (this,
+ TAO_AV_CORE::instance (),
+ this->forward_flow_spec_set);
+ if (result < 0)
+ ACE_ERROR_RETURN ((LM_ERROR,"Acceptor_Registry::open failed\n"),0);
+ result = this->mcast_entry_map_.bind (mcast_key,new_entry);
+ if (result < 0)
+ ACE_ERROR_RETURN ((LM_ERROR,"mcast_entry::bind failed"),0);
+ }
+ break;
+ case TAO_FlowSpec_Entry::TAO_AV_DIR_OUT:
+ // OUT implies we're the sink.
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"TAO_StreamEndPoint_A::multiconnect");
+ return 0;
+ }
+ ACE_ENDTRY;
+ ACE_CHECK_RETURN (0);
+ return 1;
+}
+
+// ATM style Multicast is not supported yet.
+CORBA::Boolean
+TAO_StreamEndPoint_A::connect_leaf (AVStreams::StreamEndPoint_B_ptr /* the_ep */,
+ AVStreams::streamQoS & /* the_qos */,
+ const AVStreams::flowSpec & /* the_flows */,
+ CORBA::Environment &ACE_TRY_ENV)
+{
+ ACE_THROW_RETURN (AVStreams::notSupported (),0);
+ return 0;
+}
+
+// Multicast not supported yet.
+void
+TAO_StreamEndPoint_A::disconnect_leaf (AVStreams::StreamEndPoint_B_ptr /* the_ep */,
+ const AVStreams::flowSpec & /* theSpec */,
+ CORBA::Environment &ACE_TRY_ENV)
+{
+ ACE_THROW (AVStreams::notSupported ());
+}
+
+TAO_StreamEndPoint_A::~TAO_StreamEndPoint_A (void)
+{
+}
+
+// ----------------------------------------------------------------------
+// TAO_StreamEndPoint_B
+// ----------------------------------------------------------------------
+
+TAO_StreamEndPoint_B::TAO_StreamEndPoint_B (void)
+{
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,
+ "\n(%P|%t) TAO_StreamEndPoint_B::TAO_StreamEndPoint_B: created"));
+}
+
+CORBA::Boolean
+TAO_StreamEndPoint_B::multiconnect (AVStreams::streamQoS &stream_qos,
+ AVStreams::flowSpec &flow_spec,
+ CORBA::Environment &ACE_TRY_ENV)
+{
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"TAO_StreamEndPoint_B::multiconnect\n"));
+ ACE_TRY
+ {
+ int result = 0;
+ TAO_AV_QoS qos (stream_qos);
+ for (u_int i=0;i< flow_spec.length ();i++)
+ {
+ TAO_Forward_FlowSpec_Entry *forward_entry;
+ ACE_NEW_RETURN (forward_entry,
+ TAO_Forward_FlowSpec_Entry,
+ 0);
+ forward_entry->parse (flow_spec[i]);
+ TAO_String_Hash_Key mcast_key (forward_entry->flowname ());
+ AVStreams::FlowEndPoint_var flow_endpoint;
+ if (this->fep_map_.find (mcast_key,flow_endpoint.out ()) == 0)
+ {
+ AVStreams::FlowConsumer_var consumer;
+ ACE_TRY_EX (narrow)
+ {
+ consumer = AVStreams::FlowConsumer::_narrow (flow_endpoint.in (),ACE_TRY_ENV);
+ ACE_TRY_CHECK_EX (narrow);
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"FlowConsumer::_narrow");
+ ACE_ERROR_RETURN ((LM_ERROR,"sep_b doesn't contain a flowconsumer"),0);
+ }
+ ACE_ENDTRY;
+ ACE_CHECK_RETURN (0);
+ AVStreams::QoS flow_qos;
+ result = qos.get_flow_qos (forward_entry->flowname (),flow_qos);
+ if (result < 0)
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"QoS not found for %s",forward_entry->flowname ()));
+ AVStreams::FlowConnection_var flow_connection;
+ ACE_TRY_EX (flow_connection)
+ {
+ if (CORBA::is_nil (this->streamctrl_.in ()))
+ {
+ CORBA::Any_var streamctrl_any;
+ streamctrl_any = this->get_property_value ("Related_StreamCtrl",
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ AVStreams::StreamCtrl_ptr streamctrl;
+ streamctrl_any.in () >>= streamctrl;
+ this->streamctrl_ = AVStreams::StreamCtrl::_duplicate (streamctrl);
+ }
+ CORBA::Object_var flow_connection_obj =
+ this->streamctrl_->get_flow_connection (forward_entry->flowname (),
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK_EX (flow_connection);
+ flow_connection = AVStreams::FlowConnection::_narrow (flow_connection_obj.in (),
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK_EX (flow_connection);
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"TAO_StreamEndPoint_B::multiconnect::get_flow_connection");
+ return 0;
+ }
+ ACE_ENDTRY;
+ ACE_CHECK_RETURN (0);
+ result = flow_connection->add_consumer (consumer.in (),
+ flow_qos,
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ if (result == 0)
+ ACE_ERROR_RETURN ((LM_ERROR,"TAO_StreamEndPoint_B::multiconnect:add_consumer failed\n"),0);
+ }
+ else
+ {
+ TAO_FlowSpec_Entry *mcast_entry = 0;
+ ACE_INET_Addr *mcast_addr;
+ mcast_addr = ACE_dynamic_cast (ACE_INET_Addr *,forward_entry->address ());
+ if (mcast_addr == 0)
+ ACE_ERROR_RETURN ((LM_ERROR,"TAO_StreamEndPoint_B::multiconnect::Address missing in flowspec_entry\n"),0);
+ result = this->mcast_entry_map_.find (mcast_key,mcast_entry);
+ if (result == 0)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,"TAO_StreamEndPoint_B::multiconnect::handler already found\n"),0);
+ }
+ else
+ {
+ switch (forward_entry->direction ())
+ {
+ case TAO_FlowSpec_Entry::TAO_AV_DIR_IN:
+ {
+ // IN means we're the sink.
+ // @@ We have to take care of this.
+ // result = this->make_dgram_mcast_flow_handler (mcast_dgram);
+ // if (result < 0)
+ // return 0;
+
+ this->forward_flow_spec_set.insert (forward_entry);
+ TAO_AV_Connector_Registry *connector_registry = TAO_AV_CORE::instance ()->connector_registry ();
+ result = connector_registry->open (this,
+ TAO_AV_CORE::instance (),
+ this->forward_flow_spec_set);
+ if (result < 0)
+ ACE_ERROR_RETURN ((LM_ERROR,"connector_registry::open failed\n"),0);
+ result = this->mcast_entry_map_.bind (mcast_key,forward_entry);
+ if (result < 0)
+ ACE_ERROR_RETURN ((LM_ERROR,"dgram_mcast_handler::bind failed"),0);
+ }
+ break;
+ case TAO_FlowSpec_Entry::TAO_AV_DIR_OUT:
+ // OUT implies we're the source.,which is an error.
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"TAO_StreamEndPoint_B::multiconnect");
+ return 0;
+ }
+ ACE_ENDTRY;
+ ACE_CHECK_RETURN (0);
+ return 1;
+}
+
+TAO_StreamEndPoint_B::~TAO_StreamEndPoint_B (void)
+{
}
// ----------------------------------------------------------------------
@@ -1166,7 +2652,7 @@ TAO_StreamEndPoint::~TAO_StreamEndPoint (void)
TAO_VDev::TAO_VDev (void)
{
- ACE_DEBUG ((LM_DEBUG,
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,
"(%P|%t) TAO_VDev::TAO_VDev: created\n"));
}
@@ -1179,8 +2665,8 @@ TAO_VDev::set_peer (AVStreams::StreamCtrl_ptr the_ctrl,
const AVStreams::flowSpec &the_spec,
CORBA::Environment &ACE_TRY_ENV)
ACE_THROW_SPEC ((CORBA::SystemException,
- AVStreams::noSuchFlow,
- AVStreams::QoSRequestFailed,
+ AVStreams::noSuchFlow,
+ AVStreams::QoSRequestFailed,
AVStreams::streamOpFailed))
{
ACE_UNUSED_ARG (the_qos);
@@ -1189,7 +2675,7 @@ TAO_VDev::set_peer (AVStreams::StreamCtrl_ptr the_ctrl,
CORBA::Boolean result = 0;
ACE_TRY
{
- ACE_DEBUG ((LM_DEBUG,
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,
"(%P|%t) TAO_VDev::set_peer: called"));
CORBA::String_var ior = TAO_ORB_Core_instance ()->orb ()->object_to_string (the_peer_dev,
@@ -1197,7 +2683,7 @@ TAO_VDev::set_peer (AVStreams::StreamCtrl_ptr the_ctrl,
ACE_TRY_CHECK;
- ACE_DEBUG ((LM_DEBUG,
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,
"(%P|%t) TAO_VDev::set_peer: my peer is %s\n",
ior.in ()));
@@ -1209,21 +2695,18 @@ TAO_VDev::set_peer (AVStreams::StreamCtrl_ptr the_ctrl,
ACE_TRY_CHECK;
- this->streamctrl_ = the_ctrl;
- this->peer_ = the_peer_dev;
+ this->streamctrl_ = AVStreams::StreamCtrl::_duplicate (the_ctrl);
+ this->peer_ = AVStreams::VDev::_duplicate (the_peer_dev);
- CORBA::Any_ptr anyptr;
+ CORBA::Any_var anyptr;
CORBA::String media_ctrl_ior;
anyptr = this->peer_->get_property_value ("Related_MediaCtrl",
ACE_TRY_ENV);
ACE_TRY_CHECK;
- if (anyptr != 0)
- {
- *anyptr >>= media_ctrl_ior;
- ACE_DEBUG ((LM_DEBUG,"(%P|%t)The Media Control IOR is %s\n",
- media_ctrl_ior));
- }
+ anyptr.in () >>= media_ctrl_ior;
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"(%P|%t)The Media Control IOR is %s\n",
+ media_ctrl_ior));
CORBA::Object_ptr media_ctrl_obj =
TAO_ORB_Core_instance ()->orb ()->string_to_object
(media_ctrl_ior,ACE_TRY_ENV);
@@ -1234,7 +2717,7 @@ TAO_VDev::set_peer (AVStreams::StreamCtrl_ptr the_ctrl,
}
ACE_CATCHANY
{
- ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"TAO_Server_StreamEndpoint::request_connection");
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"TAO_VDev::set_peer");
return 0;
}
ACE_ENDTRY;
@@ -1252,36 +2735,30 @@ TAO_VDev::set_media_ctrl (CORBA::Object_ptr media_ctrl,
return 1;
}
-// Multicast is not supported yet.
+// Sets the multicast VDev peer.
CORBA::Boolean
-TAO_VDev::set_Mcast_peer (AVStreams::StreamCtrl_ptr the_ctrl,
- AVStreams::MCastConfigIf_ptr a_mcastconfigif,
- AVStreams::streamQoS &the_qos,
- const AVStreams::flowSpec &the_spec,
- CORBA::Environment &ACE_TRY_ENV)
+TAO_VDev::set_Mcast_peer (AVStreams::StreamCtrl_ptr /* the_ctrl */,
+ AVStreams::MCastConfigIf_ptr mcast_peer,
+ AVStreams::streamQoS &/* the_qos */,
+ const AVStreams::flowSpec &/* the_spec */,
+ CORBA::Environment &/* ACE_TRY_ENV */)
ACE_THROW_SPEC ((CORBA::SystemException,
- AVStreams::noSuchFlow,
- AVStreams::QoSRequestFailed,
+ AVStreams::noSuchFlow,
+ AVStreams::QoSRequestFailed,
AVStreams::streamOpFailed))
{
- ACE_UNUSED_ARG (the_ctrl);
- ACE_UNUSED_ARG (a_mcastconfigif);
- ACE_UNUSED_ARG (the_qos);
- ACE_UNUSED_ARG (the_spec);
- ACE_UNUSED_ARG (ACE_TRY_ENV);
- return 0;
+ this->mcast_peer_ = AVStreams::MCastConfigIf::_duplicate (mcast_peer);
+ return 1;
}
// applications should override this to handle configuration changes.
void
-TAO_VDev::configure (const CosPropertyService::Property &the_config_mesg,
- CORBA::Environment &ACE_TRY_ENV)
+TAO_VDev::configure (const CosPropertyService::Property &/*the_config_mesg*/,
+ CORBA::Environment &/*ACE_TRY_ENV*/)
ACE_THROW_SPEC ((CORBA::SystemException,
- AVStreams::PropertyException,
+ AVStreams::PropertyException,
AVStreams::streamOpFailed))
{
- ACE_UNUSED_ARG (the_config_mesg);
- ACE_UNUSED_ARG (ACE_TRY_ENV);
}
// sets the media format used for the flowname as a property.
@@ -1321,12 +2798,11 @@ TAO_VDev::set_dev_params (const char *flowName,
const CosPropertyService::Properties &new_params,
CORBA::Environment &ACE_TRY_ENV)
ACE_THROW_SPEC ((CORBA::SystemException,
- AVStreams::PropertyException,
+ AVStreams::PropertyException,
AVStreams::streamOpFailed))
{
ACE_TRY
{
-
if (flowName == 0)
ACE_ERROR ((LM_ERROR,"TAO_VDev::set_dev_params:flowName is null\n"));
char devParams_property[BUFSIZ];
@@ -1354,7 +2830,7 @@ TAO_VDev::modify_QoS (AVStreams::streamQoS &the_qos,
const AVStreams::flowSpec &the_spec,
CORBA::Environment &ACE_TRY_ENV)
ACE_THROW_SPEC ((CORBA::SystemException,
- AVStreams::noSuchFlow,
+ AVStreams::noSuchFlow,
AVStreams::QoSRequestFailed))
{
ACE_UNUSED_ARG (the_qos);
@@ -1373,10 +2849,19 @@ TAO_VDev::~TAO_VDev (void)
TAO_MMDevice::TAO_MMDevice (TAO_AV_Endpoint_Strategy *endpoint_strategy)
- : endpoint_strategy_ (endpoint_strategy)
+ : endpoint_strategy_ (endpoint_strategy),
+ flow_count_ (0),
+ flow_num_ (0),
+ stream_ctrl_ (0)
{
}
+TAO_MMDevice::TAO_MMDevice (TAO_MMDevice const &mm_device)
+ :TAO_PropertySet (mm_device)
+{
+ //no-op
+}
+
// create a streamctrl which is colocated with me, use that streamctrl
// to bind the peer_device with me.
AVStreams::StreamCtrl_ptr
@@ -1386,28 +2871,26 @@ TAO_MMDevice::bind (AVStreams::MMDevice_ptr peer_device,
const AVStreams::flowSpec &the_spec,
CORBA::Environment &ACE_TRY_ENV)
ACE_THROW_SPEC ((CORBA::SystemException,
- AVStreams::streamOpFailed,
- AVStreams::noSuchFlow,
+ AVStreams::streamOpFailed,
+ AVStreams::noSuchFlow,
AVStreams::QoSRequestFailed))
{
AVStreams::StreamCtrl_ptr streamctrl (AVStreams::StreamCtrl::_nil ());
ACE_TRY
{
ACE_UNUSED_ARG (is_met);
- TAO_StreamCtrl *stream_ctrl;
- ACE_NEW_RETURN (stream_ctrl,
+ ACE_NEW_RETURN (this->stream_ctrl_,
TAO_StreamCtrl,
0);
- AVStreams::MMDevice_var mmdevice =
- this->_this (ACE_TRY_ENV);
+ AVStreams::MMDevice_var mmdevice = this->_this (ACE_TRY_ENV);
ACE_TRY_CHECK;
- stream_ctrl->bind_devs (peer_device,
- mmdevice.in (),
- the_qos,
- the_spec,
- ACE_TRY_ENV);
+ this->stream_ctrl_->bind_devs (peer_device,
+ mmdevice.in (),
+ the_qos,
+ the_spec,
+ ACE_TRY_ENV);
ACE_TRY_CHECK;
- streamctrl = stream_ctrl->_this (ACE_TRY_ENV);
+ streamctrl = this->stream_ctrl_->_this (ACE_TRY_ENV);
ACE_TRY_CHECK;
}
ACE_CATCHANY
@@ -1428,8 +2911,8 @@ TAO_MMDevice::bind_mcast (AVStreams::MMDevice_ptr first_peer,
const AVStreams::flowSpec &the_spec,
CORBA::Environment &ACE_TRY_ENV)
ACE_THROW_SPEC ((CORBA::SystemException,
- AVStreams::streamOpFailed,
- AVStreams::noSuchFlow,
+ AVStreams::streamOpFailed,
+ AVStreams::noSuchFlow,
AVStreams::QoSRequestFailed))
{
ACE_UNUSED_ARG (first_peer);
@@ -1440,136 +2923,284 @@ TAO_MMDevice::bind_mcast (AVStreams::MMDevice_ptr first_peer,
return 0;
}
-AVStreams::StreamEndPoint_A_ptr
-TAO_MMDevice::create_A (AVStreams::StreamCtrl_ptr the_requester,
- AVStreams::VDev_out the_vdev,
- AVStreams::streamQoS &the_qos,
- CORBA::Boolean_out met_qos,
- char *&named_vdev,
- const AVStreams::flowSpec &the_spec,
- CORBA::Environment &ACE_TRY_ENV)
+AVStreams::StreamEndPoint_ptr
+TAO_MMDevice::create_A_B (MMDevice_Type type,
+ AVStreams::StreamCtrl_ptr streamctrl,
+ AVStreams::VDev_out the_vdev,
+ AVStreams::streamQoS &the_qos,
+ CORBA::Boolean_out met_qos,
+ char *&/*named_vdev*/,
+ const AVStreams::flowSpec &flow_spec,
+ CORBA::Environment &ACE_TRY_ENV)
ACE_THROW_SPEC ((CORBA::SystemException,
- AVStreams::streamOpFailed,
- AVStreams::streamOpDenied,
+ AVStreams::streamOpFailed,
+ AVStreams::streamOpDenied,
AVStreams::notSupported,
- AVStreams::QoSRequestFailed,
+ AVStreams::QoSRequestFailed,
AVStreams::noSuchFlow))
{
- ACE_UNUSED_ARG (the_requester);
- ACE_UNUSED_ARG (the_qos);
- ACE_UNUSED_ARG (met_qos);
- ACE_UNUSED_ARG (named_vdev);
- ACE_UNUSED_ARG (the_spec);
-
- AVStreams::StreamEndPoint_A_ptr ptr (AVStreams::StreamEndPoint_A::_nil ());
+ AVStreams::StreamEndPoint_A_ptr sep_a (AVStreams::StreamEndPoint_A::_nil ());
+ AVStreams::StreamEndPoint_B_ptr sep_b (AVStreams::StreamEndPoint_B::_nil ());
+ AVStreams::StreamEndPoint_ptr sep (AVStreams::StreamEndPoint::_nil ());
ACE_TRY
{
- // In full profile application can override this to use FDevs.
-
- if (this->endpoint_strategy_->create_A (ptr,
- the_vdev,
- ACE_TRY_ENV) == -1)
- ACE_ERROR_RETURN ((LM_ERROR,
- "(%P|%t) Error in create_A\n"),
- 0);
+ switch (type)
+ {
+ case MMDEVICE_A:
+ {
+ if (this->endpoint_strategy_->create_A (sep_a,
+ the_vdev,
+ ACE_TRY_ENV) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "TAO_MMDevice::create_A_B (%P|%t) - "
+ "error in create_A\n"),
+ 0);
+ sep = sep_a;
+ }
+ break;
+ case MMDEVICE_B:
+ {
+ if (this->endpoint_strategy_->create_B (sep_b,
+ the_vdev,
+ ACE_TRY_ENV) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "TAO_MMDevice::create_A_B (%P|%t) - "
+ "error in create_B\n"),
+ 0);
+ sep = sep_b;
+ }
+ break;
+ default:
+ break;
+ }
+ ACE_TRY_CHECK;
+ if (this->fdev_map_.current_size () > 0)
+ {
+ // first set the vdev to be a nil pointer.
+ the_vdev = AVStreams::VDev::_nil ();
+ TAO_AV_QoS qos (the_qos);
+ // create flowendpoints from the FDevs.
+ for (u_int i=0;i<flow_spec.length ();i++)
+ {
+ TAO_Forward_FlowSpec_Entry forward_entry;
+ forward_entry.parse (flow_spec[i]);
+ TAO_String_Hash_Key flow_key (forward_entry.flowname ());
+ AVStreams::FDev_ptr flow_dev;
+ AVStreams::FlowConnection_var flowconnection = AVStreams::FlowConnection::_nil ();
+ ACE_TRY_EX (flowconnection)
+ {
+ // Get the flowconnection for this flow.
+ CORBA::Object_var flowconnection_obj =
+ streamctrl->get_flow_connection (forward_entry.flowname (),ACE_TRY_ENV);
+ ACE_TRY_CHECK_EX (flowconnection);
+ if (!CORBA::is_nil (flowconnection_obj.in ()))
+ {
+ flowconnection = AVStreams::FlowConnection::_narrow (flowconnection_obj.in (),
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK_EX (flowconnection);
+ }
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"TAO_MMDevice::create_a::get_flow_connection");
+ }
+ ACE_ENDTRY;
+ ACE_CHECK_RETURN (0);
+
+ int result = this->fdev_map_.find (flow_key,flow_dev);
+ if (result < 0)
+ ACE_ERROR_RETURN ((LM_ERROR,"fdev_map::find failed\n"),0);
+ CORBA::String_var named_fdev;
+ AVStreams::FlowEndPoint_var flow_endpoint;
+ AVStreams::QoS flow_qos;
+ result = qos.get_flow_qos (forward_entry.flowname (),flow_qos);
+ if (result < 0)
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"get_flow_qos failed for %s\n",forward_entry.flowname ()));
+ switch (forward_entry.direction ())
+ {
+ case TAO_FlowSpec_Entry::TAO_AV_DIR_IN:
+ {
+ switch (type)
+ {
+ case MMDEVICE_A:
+ {
+ // In implies flow is from A to B and
+ // hence A is the producer for this flow and B is the consumer for this flow.
+ // We have to create a producer from the FDev for this flow.
+ flow_endpoint =
+ flow_dev->create_producer (flowconnection.in (),
+ flow_qos,
+ met_qos,
+ named_fdev.inout (),
+ ACE_TRY_ENV);
+ }
+ break;
+ case MMDEVICE_B:
+ {
+ flow_endpoint =
+ flow_dev->create_consumer (flowconnection.in (),
+ flow_qos,
+ met_qos,
+ named_fdev.inout (),
+ ACE_TRY_ENV);
+ }
+ break;
+ }
+ ACE_TRY_CHECK;
+ }
+ break;
+ case TAO_FlowSpec_Entry::TAO_AV_DIR_OUT:
+ {
+ switch (type)
+ {
+ case MMDEVICE_A:
+ {
+ // OUT implies flow is from B to A and
+ // hence B is the producer for this flow and A is the consumer for this flow.
+ // We have to create a consumer from the FDev for this flow.
+ flow_endpoint =
+ flow_dev->create_consumer (flowconnection.in (),
+ flow_qos,
+ met_qos,
+ named_fdev.inout (),
+ ACE_TRY_ENV);
+ }
+ break;
+ case MMDEVICE_B:
+ {
+ // In implies flow is from A to B and
+ // hence A is the producer for this flow and B is the consumer for this flow.
+ // We have to create a producer from the FDev for this flow.
+ flow_endpoint =
+ flow_dev->create_producer (flowconnection.in (),
+ flow_qos,
+ met_qos,
+ named_fdev.inout (),
+ ACE_TRY_ENV);
+ }
+ break;
+ }
+ ACE_TRY_CHECK;
+ }
+ break;
+ default:
+ break;
+ }
+ CORBA::Any flowname_any;
+ flowname_any <<= forward_entry.flowname ();
+ flow_endpoint->define_property ("FlowName",flowname_any,ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ sep->add_fep (flow_endpoint.in (),
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ }
+ }
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"TAO_MMDevice::create_A");
+ return sep;
+ }
+ ACE_ENDTRY;
+ ACE_CHECK_RETURN (sep);
+ return sep;
+}
+AVStreams::StreamEndPoint_A_ptr
+TAO_MMDevice::create_A (AVStreams::StreamCtrl_ptr streamctrl,
+ AVStreams::VDev_out the_vdev,
+ AVStreams::streamQoS &stream_qos,
+ CORBA::Boolean_out met_qos,
+ char *&named_vdev,
+ const AVStreams::flowSpec &flow_spec,
+ CORBA::Environment &ACE_TRY_ENV)
+{
+ AVStreams::StreamEndPoint_A_ptr sep_a = 0;
+ AVStreams::StreamEndPoint_ptr sep = 0;
+ ACE_TRY
+ {
+ sep = this->create_A_B (MMDEVICE_A,streamctrl,the_vdev,stream_qos,met_qos,named_vdev,flow_spec,ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ sep_a = AVStreams::StreamEndPoint_A::_narrow (sep,ACE_TRY_ENV);
ACE_TRY_CHECK;
}
ACE_CATCHANY
{
ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"TAO_MMDevice::create_A");
- return ptr;
+ return sep_a;
}
ACE_ENDTRY;
- ACE_CHECK_RETURN (ptr);
- return ptr;
+ ACE_CHECK_RETURN (sep_a);
+ return sep_a;
}
AVStreams::StreamEndPoint_B_ptr
-TAO_MMDevice::create_B (AVStreams::StreamCtrl_ptr the_requester,
+TAO_MMDevice::create_B (AVStreams::StreamCtrl_ptr streamctrl,
AVStreams::VDev_out the_vdev,
- AVStreams::streamQoS &the_qos,
+ AVStreams::streamQoS &stream_qos,
CORBA::Boolean_out met_qos,
char *&named_vdev,
- const AVStreams::flowSpec &the_spec,
+ const AVStreams::flowSpec &flow_spec,
CORBA::Environment &ACE_TRY_ENV)
ACE_THROW_SPEC ((CORBA::SystemException,
- AVStreams::streamOpFailed,
- AVStreams::streamOpDenied,
+ AVStreams::streamOpFailed,
+ AVStreams::streamOpDenied,
AVStreams::notSupported,
- AVStreams::QoSRequestFailed,
+ AVStreams::QoSRequestFailed,
AVStreams::noSuchFlow))
{
- ACE_UNUSED_ARG (the_requester);
- ACE_UNUSED_ARG (the_qos);
- ACE_UNUSED_ARG (met_qos);
- ACE_UNUSED_ARG (named_vdev);
- ACE_UNUSED_ARG (the_spec);
-
- // In full profile application can override this to use FDevs.
- AVStreams::StreamEndPoint_B_ptr ptr (AVStreams::StreamEndPoint_B::_nil ());
-
+ AVStreams::StreamEndPoint_B_ptr sep_b = AVStreams::StreamEndPoint_B::_nil ();
+ AVStreams::StreamEndPoint_ptr sep;
ACE_TRY
{
- if (this->endpoint_strategy_->create_B (ptr,
- the_vdev,
- ACE_TRY_ENV) == -1)
- ACE_ERROR_RETURN ((LM_ERROR,
- "(%P|%t) Error in create_B\n"),
- 0);
-
- ACE_TRY_CHECK;
+ sep = this->create_A_B (MMDEVICE_B,streamctrl,the_vdev,stream_qos,met_qos,named_vdev,flow_spec,ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ sep_b = AVStreams::StreamEndPoint_B::_narrow (sep,ACE_TRY_ENV);
+ ACE_TRY_CHECK;
}
ACE_CATCHANY
{
- ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"TAO_MMDevice::create_B");
- return ptr;
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"TAO_MMDevice::create_A");
+ return sep_b;
}
ACE_ENDTRY;
- ACE_CHECK_RETURN (ptr);
- return ptr;
+ ACE_CHECK_RETURN (sep_b);
+ return sep_b;
}
+
// destroys the streamendpoint and the Vdev.
void
TAO_MMDevice::destroy (AVStreams::StreamEndPoint_ptr /* the_ep */,
const char * /* vdev_name */,
- CORBA::Environment &ACE_TRY_ENV)
+ CORBA::Environment &/*ACE_TRY_ENV*/)
ACE_THROW_SPEC ((CORBA::SystemException,
AVStreams::notSupported))
{
// Remove self from POA. Because of reference counting, the POA
// will automatically delete the servant when all pending requests
// on this servant are complete.
- //
- PortableServer::POA_var poa = this->_default_POA (ACE_TRY_ENV);
- ACE_CHECK;
-
- PortableServer::ObjectId_var id = poa->servant_to_id (this,
- ACE_TRY_ENV);
- ACE_CHECK;
-
- poa->deactivate_object (id.in (),
- ACE_TRY_ENV);
- ACE_CHECK;
+ int result = deactivate_servant (this);
+ if (result < 0)
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"TAO_MMDevice::destroy failed\n"));
}
// Adds the fdev object to the MMDevice.
char *
-TAO_MMDevice::add_fdev (CORBA::Object_ptr the_fdev,
+TAO_MMDevice::add_fdev (CORBA::Object_ptr fdev_obj,
CORBA::Environment &ACE_TRY_ENV)
ACE_THROW_SPEC ((CORBA::SystemException,
- AVStreams::notSupported,
+ AVStreams::notSupported,
AVStreams::streamOpFailed))
{
char *flow_name = 0;
+ AVStreams::FDev_ptr fdev = AVStreams::FDev::_nil ();
ACE_TRY_EX (flow_name)
{
ACE_NEW_RETURN (flow_name,char [BUFSIZ],0);
CORBA::Any_ptr flow_name_any;
- AVStreams::FDev_ptr fdev =
- AVStreams::FDev::_narrow (the_fdev,ACE_TRY_ENV);
+ fdev = AVStreams::FDev::_narrow (fdev_obj,ACE_TRY_ENV);
ACE_TRY_CHECK_EX (flow_name);
flow_name_any = fdev->get_property_value ("Flow",ACE_TRY_ENV);
ACE_TRY_CHECK_EX (flow_name);
@@ -1577,14 +3208,33 @@ TAO_MMDevice::add_fdev (CORBA::Object_ptr the_fdev,
}
ACE_CATCHANY
{
- // exception implies the flow name is not defined and is system generated.
- ACE_OS::sprintf (flow_name,"flow%d",flow_num_++);
+ ACE_TRY_EX (flow)
+ {
+ // exception implies the flow name is not defined and is system generated.
+ ACE_OS::sprintf (flow_name,"flow%d",flow_num_++);
+ CORBA::Any flowname_any;
+ flowname_any <<= flow_name;
+ fdev->define_property ("Flow",flowname_any,ACE_TRY_ENV);
+ ACE_TRY_CHECK_EX (flow);
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"TAO_MMDevice::add_fdev");
+ return 0;
+ }
+ ACE_ENDTRY;
+ ACE_CHECK_RETURN (0);
}
ACE_ENDTRY;
+ ACE_CHECK_RETURN (0);
+
+ if (CORBA::is_nil (fdev))
+ return 0;
+
// Add it to the sequence of flowNames supported.
// put the flowname and the fdev in a hashtable.
- TAO_String_Hash_Key fdev_name_key (flow_name);
- if (this->fdev_map_.bind (fdev_name_key,the_fdev) != 0)
+ TAO_String_Hash_Key fdev_name_key (CORBA::string_dup (flow_name));
+ if (this->fdev_map_.bind (fdev_name_key,fdev) != 0)
ACE_THROW_RETURN (AVStreams::streamOpFailed (),0);
// increment the flow count.
@@ -1616,7 +3266,7 @@ CORBA::Object_ptr
TAO_MMDevice::get_fdev (const char *flow_name,
CORBA::Environment &ACE_TRY_ENV)
ACE_THROW_SPEC ((CORBA::SystemException,
- AVStreams::notSupported,
+ AVStreams::notSupported,
AVStreams::noSuchFlow))
{
ACE_UNUSED_ARG (ACE_TRY_ENV);
@@ -1624,7 +3274,7 @@ TAO_MMDevice::get_fdev (const char *flow_name,
TAO_String_Hash_Key fdev_name_key (flow_name);
FDev_Map::ENTRY *fdev_entry = 0;
if (this->fdev_map_.find (fdev_name_key,fdev_entry) == 0)
- return fdev_entry->int_id_;
+ return AVStreams::FDev::_duplicate (fdev_entry->int_id_);
return 0;
}
@@ -1633,16 +3283,19 @@ void
TAO_MMDevice::remove_fdev (const char *flow_name,
CORBA::Environment &ACE_TRY_ENV)
ACE_THROW_SPEC ((CORBA::SystemException,
- AVStreams::notSupported,
+ AVStreams::notSupported,
AVStreams::noSuchFlow))
{
ACE_TRY
{
TAO_String_Hash_Key fdev_name_key (flow_name);
- CORBA::Object_ptr fdev_entry = 0;
+ AVStreams::FDev_ptr fdev_entry = AVStreams::FDev::_nil ();
// Remove the fep from the hash table.
- if (this->fdev_map_.unbind (flow_name,fdev_entry)!= 0)
- ACE_THROW (AVStreams::noSuchFlow ());
+ if (this->fdev_map_.unbind (fdev_name_key,fdev_entry)!= 0)
+ ACE_THROW (AVStreams::streamOpFailed ());
+
+ if (!CORBA::is_nil (fdev_entry))
+ CORBA::release (fdev_entry);
AVStreams::flowSpec new_flows (this->flows_.length ());
for (u_int i=0,j=0 ; i <this->flows_.length (); i++)
@@ -1668,6 +3321,11 @@ TAO_MMDevice::remove_fdev (const char *flow_name,
// destructor.
TAO_MMDevice::~TAO_MMDevice (void)
{
+ delete this->stream_ctrl_;
+ FDev_Map_Iterator iterator (fdev_map_);
+ FDev_Map_Entry *entry = 0;
+ for (;iterator.next (entry) != 0; iterator.advance ())
+ CORBA::release (entry->int_id_);
}
//------------------------------------------------------------------
@@ -1676,10 +3334,23 @@ TAO_MMDevice::~TAO_MMDevice (void)
// default constructor.
TAO_FlowConnection::TAO_FlowConnection (void)
- :producer_ (0),
- consumer_ (0),
- fp_name_ (0)
+ :fp_name_ (CORBA::string_dup ("")),
+ ip_multicast_ (1)
+{
+}
+
+int
+TAO_FlowConnection::set_mcast_addr (ACE_UINT32 mcast_addr, u_short mcast_port)
+{
+ this->mcast_addr_ = mcast_addr;
+ this->mcast_port_ = mcast_port;
+ return 0;
+}
+
+void
+TAO_FlowConnection::set_protocol (const char *protocol)
{
+ this->protocol_ = protocol;
}
// stop this flow.
@@ -1687,7 +3358,34 @@ void
TAO_FlowConnection::stop (CORBA::Environment &ACE_TRY_ENV)
ACE_THROW_SPEC ((CORBA::SystemException))
{
- ACE_UNUSED_ARG (ACE_TRY_ENV);
+ ACE_TRY
+ {
+ FlowProducer_SetItor producer_begin = this->flow_producer_set_.begin
+ ();
+ for (FlowProducer_SetItor producer_end =
+ this->flow_producer_set_.end ();
+ producer_begin != producer_end; ++producer_begin)
+ {
+ (*producer_begin)->stop (ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ }
+ FlowConsumer_SetItor consumer_begin = this->flow_consumer_set_.begin
+ ();
+ for (FlowConsumer_SetItor consumer_end =
+ this->flow_consumer_set_.end ();
+ consumer_begin != consumer_end; ++consumer_begin)
+ {
+ (*consumer_begin)->stop (ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ }
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"TAO_FlowConnection::stop");
+ return;
+ }
+ ACE_ENDTRY;
+ ACE_CHECK;
}
// start this flow.
@@ -1695,28 +3393,71 @@ void
TAO_FlowConnection::start (CORBA::Environment &ACE_TRY_ENV)
ACE_THROW_SPEC ((CORBA::SystemException))
{
- ACE_UNUSED_ARG (ACE_TRY_ENV);
+ ACE_TRY
+ {
+ FlowConsumer_SetItor consumer_begin = this->flow_consumer_set_.begin
+ ();
+ for (FlowConsumer_SetItor consumer_end =
+ this->flow_consumer_set_.end ();
+ consumer_begin != consumer_end; ++consumer_begin)
+ {
+ (*consumer_begin)->start (ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ }
+ FlowProducer_SetItor producer_begin = this->flow_producer_set_.begin
+ ();
+ for (FlowProducer_SetItor producer_end =
+ this->flow_producer_set_.end ();
+ producer_begin != producer_end; ++producer_begin)
+ {
+ (*producer_begin)->start (ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ }
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"TAO_FlowConnection::start");
+ return;
+ }
+ ACE_ENDTRY;
+ ACE_CHECK;
}
// destroy this flow.
void
TAO_FlowConnection::destroy (CORBA::Environment &ACE_TRY_ENV)
- ACE_THROW_SPEC ((CORBA::SystemException))
{
- // Remove self from POA. Because of reference counting, the POA
- // will automatically delete the servant when all pending requests
- // on this servant are complete.
- //
- PortableServer::POA_var poa = this->_default_POA (ACE_TRY_ENV);
- ACE_CHECK;
-
- PortableServer::ObjectId_var id = poa->servant_to_id (this,
- ACE_TRY_ENV);
- ACE_CHECK;
-
- poa->deactivate_object (id.in (),
- ACE_TRY_ENV);
+ ACE_TRY
+ {
+ FlowProducer_SetItor producer_begin = this->flow_producer_set_.begin
+ ();
+ for (FlowProducer_SetItor producer_end =
+ this->flow_producer_set_.end ();
+ producer_begin != producer_end; ++producer_begin)
+ {
+ (*producer_begin)->destroy (ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ }
+ FlowConsumer_SetItor consumer_begin = this->flow_consumer_set_.begin
+ ();
+ for (FlowConsumer_SetItor consumer_end =
+ this->flow_consumer_set_.end ();
+ consumer_begin != consumer_end; ++consumer_begin)
+ {
+ (*consumer_begin)->destroy (ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ }
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"TAO_FlowConnection::destroy");
+ return;
+ }
+ ACE_ENDTRY;
ACE_CHECK;
+ int result = deactivate_servant (this);
+ if (result < 0)
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"TAO_FlowConnection::destroy failed\n"));
}
// modify the QoS for this flow.
@@ -1737,12 +3478,31 @@ TAO_FlowConnection::use_flow_protocol (const char * fp_name,
const CORBA::Any & fp_settings,
CORBA::Environment &ACE_TRY_ENV)
ACE_THROW_SPEC ((CORBA::SystemException,
- AVStreams::FPError,
+ AVStreams::FPError,
AVStreams::notSupported))
{
- ACE_UNUSED_ARG (fp_settings);
- ACE_UNUSED_ARG (ACE_TRY_ENV);
- this->fp_name_ = (char *)fp_name;
+ this->fp_name_ = fp_name;
+ this->fp_settings_ = fp_settings;
+ FlowProducer_SetItor producer_begin = this->flow_producer_set_.begin
+ ();
+ for (FlowProducer_SetItor producer_end =
+ this->flow_producer_set_.end ();
+ producer_begin != producer_end; ++producer_begin)
+ {
+ (*producer_begin)->use_flow_protocol
+ (fp_name,fp_settings,ACE_TRY_ENV);
+ ACE_CHECK_RETURN (0);
+ }
+ FlowConsumer_SetItor consumer_begin = this->flow_consumer_set_.begin
+ ();
+ for (FlowConsumer_SetItor consumer_end =
+ this->flow_consumer_set_.end ();
+ consumer_begin != consumer_end; ++consumer_begin)
+ {
+ (*consumer_begin)->use_flow_protocol
+ (fp_name,fp_settings,ACE_TRY_ENV);
+ ACE_CHECK_RETURN (0);
+ }
return 1;
}
@@ -1758,64 +3518,119 @@ TAO_FlowConnection::push_event (const AVStreams::streamEvent & the_event,
CORBA::Boolean
TAO_FlowConnection::connect_devs (AVStreams::FDev_ptr a_party,
AVStreams::FDev_ptr b_party,
- AVStreams::QoS & the_qos,
+ AVStreams::QoS & flow_qos,
CORBA::Environment &ACE_TRY_ENV)
ACE_THROW_SPEC ((CORBA::SystemException,
- AVStreams::streamOpFailed,
- AVStreams::streamOpDenied,
+ AVStreams::streamOpFailed,
+ AVStreams::streamOpDenied,
AVStreams::QoSRequestFailed))
{
- ACE_UNUSED_ARG (a_party);
- ACE_UNUSED_ARG (b_party);
- ACE_UNUSED_ARG (the_qos);
- ACE_UNUSED_ARG (ACE_TRY_ENV);
- return 0;
+ CORBA::Boolean result = 0;
+ ACE_TRY
+ {
+ AVStreams::FlowConnection_var flowconnection = this->_this (ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ CORBA::Boolean met_qos;
+ CORBA::String_var named_fdev ((const char *)"");
+ AVStreams::FlowProducer_var producer =
+ a_party->create_producer (flowconnection.in (),
+ flow_qos,
+ met_qos,
+ named_fdev.inout (),
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ AVStreams::FlowConsumer_var consumer =
+ b_party->create_consumer (flowconnection.in (),
+ flow_qos,
+ met_qos,
+ named_fdev.inout (),
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ result = this->connect (producer.in (),
+ consumer.in (),
+ flow_qos,
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"TAO_FlowConnection::connect_devs");
+ return 0;
+ }
+ ACE_ENDTRY;
+ ACE_CHECK_RETURN (0);
+ return result;
}
// connect the producer and the consumer
CORBA::Boolean
-TAO_FlowConnection::connect (AVStreams::FlowProducer_ptr flow_producer,
- AVStreams::FlowConsumer_ptr flow_consumer,
+TAO_FlowConnection::connect (AVStreams::FlowProducer_ptr producer,
+ AVStreams::FlowConsumer_ptr consumer,
AVStreams::QoS & the_qos,
CORBA::Environment &ACE_TRY_ENV)
ACE_THROW_SPEC ((CORBA::SystemException,
- AVStreams::formatMismatch,
- AVStreams::FEPMismatch,
+ AVStreams::formatMismatch,
+ AVStreams::FEPMismatch,
AVStreams::alreadyConnected))
{
ACE_TRY
{
- this->producer_ = flow_producer;
- this->consumer_ = flow_consumer;
+ AVStreams::FlowProducer_ptr flow_producer =
+ AVStreams::FlowProducer::_duplicate (producer);
+ AVStreams::FlowConsumer_ptr flow_consumer =
+ AVStreams::FlowConsumer::_duplicate (consumer);
+
+ this->flow_producer_set_.insert (flow_producer);
+ this->flow_consumer_set_.insert (flow_consumer);
AVStreams::FlowConnection_var flowconnection =
this->_this (ACE_TRY_ENV);
- ACE_TRY_CHECK;
- this->producer_->set_peer (flowconnection.in (),
- this->consumer_,
- the_qos,
- ACE_TRY_ENV);
+ flow_producer->set_peer (flowconnection.in (),
+ flow_consumer,
+ the_qos,
+ ACE_TRY_ENV);
ACE_TRY_CHECK;
- this->consumer_->set_peer (flowconnection.in (),
- this->producer_,
- the_qos,
- ACE_TRY_ENV);
+ flow_consumer->set_peer (flowconnection.in (),
+ flow_producer,
+ the_qos,
+ ACE_TRY_ENV);
ACE_TRY_CHECK;
char *consumer_address =
- this->consumer_->go_to_listen (the_qos,
- 0,// false for is_mcast
- this->producer_,
- this->fp_name_,
- ACE_TRY_ENV);
+ flow_consumer->go_to_listen (the_qos,
+ 0,// false for is_mcast
+ flow_producer,
+ this->fp_name_.inout (),
+ ACE_TRY_ENV);
ACE_TRY_CHECK;
- this->producer_->connect_to_peer (the_qos,
- consumer_address,
- this->fp_name_,
- ACE_TRY_ENV);
- ACE_TRY_CHECK;
+ if (ACE_OS::strcmp (consumer_address,"") == 0)
+ {
+ // Consumer is not willing to listen,so try the producer.
+ consumer_address = flow_producer->go_to_listen (the_qos,
+ 0,// false for is_mcast
+ flow_consumer,
+ this->fp_name_.inout (),
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ flow_consumer->connect_to_peer (the_qos,
+ consumer_address,
+ this->fp_name_.inout (),
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ // @@ Naga: We have to find means to set the reverse channel for the producer.
+ // Its broken in the point-to_point case for UDP.
+ }
+ else
+ {
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"TAO_FlowConnection::connect_to_peer addres: %s",consumer_address));
+ flow_producer->connect_to_peer (the_qos,
+ consumer_address,
+ this->fp_name_.inout (),
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ }
}
ACE_CATCHANY
{
@@ -1836,29 +3651,190 @@ TAO_FlowConnection::disconnect (CORBA::Environment &ACE_TRY_ENV)
}
CORBA::Boolean
-TAO_FlowConnection::add_producer (AVStreams::FlowProducer_ptr flow_producer,
+TAO_FlowConnection::add_producer (AVStreams::FlowProducer_ptr producer,
AVStreams::QoS & the_qos,
CORBA::Environment &ACE_TRY_ENV)
ACE_THROW_SPEC ((CORBA::SystemException,
AVStreams::alreadyConnected,
AVStreams::notSupported))
{
- ACE_UNUSED_ARG (the_qos);
- ACE_UNUSED_ARG (ACE_TRY_ENV);
- this->producer_ = flow_producer;
+ ACE_TRY
+ {
+ AVStreams::FlowProducer_ptr flow_producer =
+ AVStreams::FlowProducer::_duplicate (producer);
+ // @@Naga:Sometimes the same producer could be added with a different object reference.
+ // There's no portable way of comparing obj refs. but we have to do this till we find
+ // a permanent solution.For eg. 2 different flowproducers for the same flow in a
+ // Multipoint to Multipoint binding will have the same flowname and hence cannot be
+ // used for resolving ties.
+ FlowProducer_SetItor begin = this->flow_producer_set_.begin ();
+ FlowProducer_SetItor end = this->flow_producer_set_.end ();
+ for (; begin != end; ++begin)
+ {
+ if ((*begin)->_is_equivalent (producer,
+ ACE_TRY_ENV))
+ // producer exists in the set, a duplicate.
+ ACE_ERROR_RETURN ((LM_WARNING,"TAO_FlowConnection::add_producer: producer already exists\n"),1);
+ }
+ // We need to check the return value of the insert into the flow producer
+ // set, since multiconnect could be called many times which will lead to
+ // a call to add_producer every time a sink is added. If the producer is already
+ // present in our list we just return immediately.
+ int result = this->flow_producer_set_.insert (flow_producer);
+ if (result == 1)
+ {
+ // producer exists in the set, a duplicate.
+ ACE_ERROR_RETURN ((LM_WARNING,"TAO_FlowConnection::add_producer: producer already exists\n"),1);
+ }
+ CORBA::Boolean met_qos;
+ char mcast_address[BUFSIZ];
+ if (this->producer_address_.in () == 0)
+ {
+ ACE_INET_Addr mcast_addr (this->mcast_port_,
+ this->mcast_addr_);
+ char buf [BUFSIZ];
+ mcast_addr.addr_to_string (buf,BUFSIZ);
+ ACE_OS::sprintf (mcast_address,"%s=%s",this->protocol_.in (),buf);
+ }
+ else
+ ACE_OS::strcpy (mcast_address,this->producer_address_.in ());
+ char *address = flow_producer->connect_mcast (the_qos,
+ met_qos,
+ mcast_address,
+ this->fp_name_.in (),
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ if (this->producer_address_.in () == 0)
+ {
+ TAO_Forward_FlowSpec_Entry entry ("","","","",address);
+ if (entry.address () != 0)
+ {
+ // Internet multicasting is in use.
+ this->producer_address_ = address;
+ }
+ else
+ {
+ // ATM Multicasting is in use.
+ this->ip_multicast_ = 0;
+ }
+ }
+ // set the multicast peer.
+ if (CORBA::is_nil (this->mcastconfigif_.in ()))
+ {
+ ACE_NEW_RETURN (this->mcastconfigif_i_,
+ TAO_MCastConfigIf,
+ 0);
+ this->mcastconfigif_ = this->mcastconfigif_i_->_this (ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ }
+ AVStreams::FlowConnection_var flowconnection = this->_this (ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ flow_producer->set_Mcast_peer (flowconnection.in (),
+ this->mcastconfigif_.in (),
+ the_qos,
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"TAO_FlowConnection::add_producer");
+ return 0;
+ }
+ ACE_ENDTRY;
+ ACE_CHECK_RETURN (0);
return 1;
}
CORBA::Boolean
-TAO_FlowConnection::add_consumer (AVStreams::FlowConsumer_ptr flow_consumer,
+TAO_FlowConnection::add_consumer (AVStreams::FlowConsumer_ptr consumer,
AVStreams::QoS & the_qos,
CORBA::Environment &ACE_TRY_ENV)
ACE_THROW_SPEC ((CORBA::SystemException,
AVStreams::alreadyConnected))
{
- ACE_UNUSED_ARG (the_qos);
- ACE_UNUSED_ARG (ACE_TRY_ENV);
- this->consumer_ = flow_consumer;
+ ACE_TRY
+ {
+ AVStreams::FlowConsumer_ptr flow_consumer =
+ AVStreams::FlowConsumer::_duplicate (consumer);
+ FlowConsumer_SetItor begin = this->flow_consumer_set_.begin ();
+ FlowConsumer_SetItor end = this->flow_consumer_set_.end ();
+ for (; begin != end; ++begin)
+ {
+ if ((*begin)->_is_equivalent (consumer,
+ ACE_TRY_ENV))
+ // Consumer exists in the set, a duplicate.
+ ACE_ERROR_RETURN ((LM_WARNING,"TAO_FlowConnection::add_Consumer: Consumer already exists\n"),1);
+ }
+ int result = this->flow_consumer_set_.insert (flow_consumer);
+ if (result == 1)
+ {
+ // consumer exists in the set, a duplicate.
+ ACE_ERROR_RETURN ((LM_WARNING,"TAO_FlowConnection::add_consumer: consumer already exists\n"),1);
+ }
+
+ FlowProducer_SetItor producer_begin = this->flow_producer_set_.begin ();
+ // @@Lets take that the first entry as the only producer. We're
+ // not sure if we can have multiple flow producers in a
+ // flowconnection. We can have multiple producer in the MtM binding,
+ // in which case the first producer that gets added is the leader.
+ AVStreams::FlowProducer_ptr flow_producer = (*producer_begin);
+
+ AVStreams::protocolSpec protocols (1);
+ protocols.length (1);
+ protocols [0] = CORBA::string_dup (this->producer_address_);
+ if (!this->ip_multicast_)
+ {
+ flow_consumer->set_protocol_restriction (protocols,
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ char * address =
+ flow_consumer->go_to_listen (the_qos,
+ 1,
+ flow_producer,
+ this->fp_name_.inout (),
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ CORBA::Boolean is_met;
+ flow_producer->connect_mcast (the_qos,
+ is_met,
+ address,
+ this->fp_name_.inout (),
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ }
+ else
+ {
+ // The spec says go_to_listen is called with the multicast
+ // address returned from the connect_mcast call called
+ // during add_producer. But go_to_listen doesn't have a
+ // address parameter. I guess it should be connect_to_peer.
+ // IP Multicasting.
+ flow_consumer->connect_to_peer (the_qos,
+ this->producer_address_.in (),
+ this->fp_name_.inout (),
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ }
+ if (CORBA::is_nil (this->mcastconfigif_.in ()))
+ ACE_ERROR_RETURN ((LM_ERROR,"TAO_FlowConnection::add_consumer: first add a producer and then a consumer\n"),0);
+ // @@ Is this the right place to do set_peer?
+ AVStreams::flowSpec flow_spec;
+ AVStreams::streamQoS stream_qos (1);
+ stream_qos.length (1);
+ stream_qos [0] = the_qos;
+ this->mcastconfigif_->set_peer (flow_consumer,
+ stream_qos,
+ flow_spec,
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"TAO_FlowConnection::add_consumer");
+ return 0;
+ }
+ ACE_ENDTRY;
+ ACE_CHECK_RETURN (0);
return 1;
}
@@ -1879,11 +3855,77 @@ TAO_FlowConnection::drop (AVStreams::FlowEndPoint_ptr target,
//default constructor.
TAO_FlowEndPoint::TAO_FlowEndPoint (void)
- :related_sep_ (0),
- related_flow_connection_ (0)
+ :lock_ (0)
{
}
+TAO_FlowEndPoint::TAO_FlowEndPoint (const char *flowname,
+ AVStreams::protocolSpec &protocols,
+ const char *format)
+{
+ this->open (flowname,protocols,format);
+}
+
+void
+TAO_FlowEndPoint::set_handler (const char *flowname,
+ TAO_AV_Flow_Handler *handler)
+{
+}
+
+int
+TAO_FlowEndPoint::open (const char *flowname,
+ AVStreams::protocolSpec &protocols,
+ const char *format)
+{
+ this->flowname_ = flowname;
+ this->format_ = format;
+
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"TAO_FlowEndPoint::open\n"));
+ ACE_DECLARE_NEW_CORBA_ENV;
+ ACE_TRY
+ {
+ CORBA::Any flowname_any;
+ flowname_any <<= flowname;
+ this->define_property ("Flow",
+ flowname_any,
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ this->set_format (format,
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ this->protocol_addresses_ = protocols;
+ AVStreams::protocolSpec protocol_spec (protocols.length ());
+ protocol_spec.length (protocols.length ());
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"%N:%l\n"));
+ for (u_int i=0;i<protocols.length ();i++)
+ {
+ CORBA::String_var address = CORBA::string_dup (protocols [i].in ());
+ TAO_Forward_FlowSpec_Entry entry ("","","","",address.in ());
+ protocol_spec [i] = CORBA::string_dup (entry.carrier_protocol_str ());
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"%s\n",protocol_spec[i].in ()));
+ }
+ this->set_protocol_restriction (protocol_spec,
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"TAO_FlowEndPoint::open");
+ return -1;
+ }
+ ACE_ENDTRY;
+ ACE_CHECK_RETURN (-1);
+ return 0;
+}
+
+
+int
+TAO_FlowEndPoint::set_flowname (const char *flowname)
+{
+ this->flowname_ = flowname;
+ return 0;
+}
+
// used by one flowconnection so that multiple connections cant use
// the same flowendpoint.
CORBA::Boolean
@@ -1892,7 +3934,10 @@ TAO_FlowEndPoint::lock (CORBA::Environment &ACE_TRY_ENV)
{
// lock the current flowendpoint
ACE_UNUSED_ARG (ACE_TRY_ENV);
- return 0;
+ if (this->lock_)
+ return 0;
+ this->lock_ = 1;
+ return 1;
}
// unlocks the flowendpoint ,becomes free to be used in another flow.
@@ -1901,66 +3946,44 @@ TAO_FlowEndPoint::unlock (CORBA::Environment &ACE_TRY_ENV)
ACE_THROW_SPEC ((CORBA::SystemException))
{
ACE_UNUSED_ARG (ACE_TRY_ENV);
+ this->lock_ = 0;
}
-// The start,stop and destroy are to be handled by the application.
-void
-TAO_FlowEndPoint::stop (CORBA::Environment &ACE_TRY_ENV)
- ACE_THROW_SPEC ((CORBA::SystemException))
-{
- ACE_UNUSED_ARG (ACE_TRY_ENV);
-}
-
-void
-TAO_FlowEndPoint::start (CORBA::Environment &ACE_TRY_ENV)
- ACE_THROW_SPEC ((CORBA::SystemException))
-{
- ACE_UNUSED_ARG (ACE_TRY_ENV);
-}
void
-TAO_FlowEndPoint::destroy (CORBA::Environment &ACE_TRY_ENV)
+TAO_FlowEndPoint::destroy (CORBA::Environment &/*ACE_TRY_ENV*/)
ACE_THROW_SPEC ((CORBA::SystemException))
{
- // Remove self from POA. Because of reference counting, the POA
- // will automatically delete the servant when all pending requests
- // on this servant are complete.
- //
- PortableServer::POA_var poa = this->_default_POA (ACE_TRY_ENV);
- ACE_CHECK;
-
- PortableServer::ObjectId_var id = poa->servant_to_id (this,
- ACE_TRY_ENV);
- ACE_CHECK;
-
- poa->deactivate_object (id.in (),
- ACE_TRY_ENV);
- ACE_CHECK;
+ int result = deactivate_servant (this);
+ if (result < 0)
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"TAO_StreamEndPoint::destroy failed\n"));
+ TAO_AV_FlowSpecSetItor end = this->flow_spec_set_.end ();
+ for (TAO_AV_FlowSpecSetItor begin = this->flow_spec_set_.begin ();
+ begin != end; ++begin)
+ (*begin)->protocol_object ()->destroy ();
}
AVStreams::StreamEndPoint_ptr
-TAO_FlowEndPoint::related_sep (CORBA::Environment &ACE_TRY_ENV)
+TAO_FlowEndPoint::related_sep (CORBA::Environment &/*ACE_TRY_ENV*/)
ACE_THROW_SPEC ((CORBA::SystemException))
{
- ACE_UNUSED_ARG (ACE_TRY_ENV);
- return this->related_sep_;
+
+ return AVStreams::StreamEndPoint::_duplicate (this->related_sep_.in ());
}
void
TAO_FlowEndPoint::related_sep (AVStreams::StreamEndPoint_ptr related_sep,
- CORBA::Environment &ACE_TRY_ENV)
+ CORBA::Environment &)
ACE_THROW_SPEC ((CORBA::SystemException))
{
- ACE_UNUSED_ARG (ACE_TRY_ENV);
- this->related_sep_ = related_sep;
+ this->related_sep_ = AVStreams::StreamEndPoint::_duplicate (related_sep);
}
AVStreams::FlowConnection_ptr
-TAO_FlowEndPoint::related_flow_connection (CORBA::Environment &ACE_TRY_ENV)
+TAO_FlowEndPoint::related_flow_connection (CORBA::Environment &)
ACE_THROW_SPEC ((CORBA::SystemException))
{
- ACE_UNUSED_ARG (ACE_TRY_ENV);
- return this->related_flow_connection_;
+ return AVStreams::FlowConnection::_duplicate (this->related_flow_connection_.in ());
}
void
@@ -1969,29 +3992,27 @@ TAO_FlowEndPoint::related_flow_connection (AVStreams::FlowConnection_ptr related
ACE_THROW_SPEC ((CORBA::SystemException))
{
ACE_UNUSED_ARG (ACE_TRY_ENV);
- this->related_flow_connection_ = related_flow_connection;
+ this->related_flow_connection_ = AVStreams::FlowConnection::_duplicate (related_flow_connection);
}
// returns the connected peer for this flow
AVStreams::FlowEndPoint_ptr
-TAO_FlowEndPoint::get_connected_fep (CORBA::Environment &ACE_TRY_ENV)
+TAO_FlowEndPoint::get_connected_fep (CORBA::Environment &)
ACE_THROW_SPEC ((CORBA::SystemException,
AVStreams::notConnected,
AVStreams::notSupported))
{
- ACE_UNUSED_ARG (ACE_TRY_ENV);
- return this->peer_fep_;
+ return AVStreams::FlowEndPoint::_duplicate (this->peer_fep_.in ());
}
CORBA::Boolean
TAO_FlowEndPoint::use_flow_protocol (const char * fp_name,
- const CORBA::Any & fp_settings,
+ const CORBA::Any & ,
CORBA::Environment &ACE_TRY_ENV)
ACE_THROW_SPEC ((CORBA::SystemException,
- AVStreams::FPError,
+ AVStreams::FPError,
AVStreams::notSupported))
{
- ACE_UNUSED_ARG (fp_settings);
ACE_TRY
{
// Define the property called FlowProtocol
@@ -2018,6 +4039,7 @@ TAO_FlowEndPoint::set_format (const char * format,
ACE_THROW_SPEC ((CORBA::SystemException,
AVStreams::notSupported))
{
+ this->format_ = format;
ACE_TRY
{
// make this a property so that is_fep_compatible can query this and
@@ -2041,9 +4063,10 @@ void
TAO_FlowEndPoint::set_dev_params (const CosPropertyService::Properties & new_settings,
CORBA::Environment &ACE_TRY_ENV)
ACE_THROW_SPEC ((CORBA::SystemException,
- AVStreams::PropertyException,
+ AVStreams::PropertyException,
AVStreams::streamOpFailed))
{
+ this->dev_params_ = new_settings;
ACE_TRY
{
CORBA::Any DevParams_property;
@@ -2062,19 +4085,38 @@ TAO_FlowEndPoint::set_dev_params (const CosPropertyService::Properties & new_set
}
void
-TAO_FlowEndPoint::set_protocol_restriction (const AVStreams::protocolSpec & the_spec,
+TAO_FlowEndPoint::set_protocol_restriction (const AVStreams::protocolSpec & protocols,
CORBA::Environment &ACE_TRY_ENV)
ACE_THROW_SPEC ((CORBA::SystemException,
AVStreams::notSupported))
{
ACE_TRY
{
+ u_int i = 0;
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"%N:%l\n"));
+ for (i=0;i<protocols.length ();i++)
+ {
+ const char *protocol = (protocols)[i].in ();
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"%s\n",protocol));
+ }
CORBA::Any AvailableProtocols_property;
- AvailableProtocols_property <<= the_spec;
+ AvailableProtocols_property <<= protocols;
this->define_property ("AvailableProtocols",
AvailableProtocols_property,
ACE_TRY_ENV);
ACE_TRY_CHECK;
+ AVStreams::protocolSpec *temp_spec;
+ CORBA::Any_var temp_any = this->get_property_value ("AvailableProtocols",
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ temp_any.in () >>= temp_spec;
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"%N:%l\n"));
+ for (i=0;i<temp_spec->length ();i++)
+ {
+ const char *protocol = (*temp_spec)[i].in ();
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"%s\n",protocol));
+ }
+ this->protocols_ = protocols;
}
ACE_CATCHANY
{
@@ -2088,60 +4130,87 @@ CORBA::Boolean
TAO_FlowEndPoint::is_fep_compatible (AVStreams::FlowEndPoint_ptr peer_fep,
CORBA::Environment &ACE_TRY_ENV)
ACE_THROW_SPEC ((CORBA::SystemException,
- AVStreams::formatMismatch,
+ AVStreams::formatMismatch,
AVStreams::deviceQosMismatch))
{
+ const char *exception_message = "";
ACE_TRY
{
// check whether the passed flowendpoint is compatible with this flowendpoint.
// should we check for the availableFormats and choose one format.
// get my format value
- CORBA::Any_ptr format_ptr;
- CORBA::String my_format,peer_format;
+ CORBA::Any_var format_ptr;
+ CORBA::String_var my_format,peer_format;
+ CORBA::String temp_format;
+
+ exception_message = "TAO_FlowEndPoint::is_fep_compatible - Format";
format_ptr = this->get_property_value ("Format",
ACE_TRY_ENV);
ACE_TRY_CHECK;
- if (format_ptr != 0)
- *format_ptr >>= my_format;
- else
- // property is not defined
- ACE_ERROR_RETURN ((LM_ERROR,"(%P|%t) TAO_FlowEndPoint::is_fep_compatible"),0);
-
+ format_ptr.in () >>= temp_format;
+ my_format = CORBA::string_dup (temp_format);
// get my peer's format value
-
+ exception_message = "TAO_FlowEndPoint::is_fep_compatible - Format[2]";
format_ptr = peer_fep->get_property_value ("Format",
ACE_TRY_ENV);
ACE_TRY_CHECK;
- if (format_ptr != 0)
- *format_ptr >>= peer_format;
- else
- // property is not defined
- ACE_ERROR_RETURN ((LM_ERROR,"(%P|%t) TAO_FlowEndPoint::is_fep_compatible"),0);
-
- // can we use strcmp??
- if (ACE_OS::strcmp (my_format,peer_format) != 0)
+ format_ptr.in () >>= temp_format;
+ peer_format = CORBA::string_dup (temp_format);
+ if (ACE_OS::strcmp (my_format.in (),
+ peer_format.in ()) != 0)
return 0;
+
// since formats are same, check for a common protocol
- CORBA::Any* AvailableProtocols_ptr;
- AVStreams::protocolSpec *my_protocolSpec,*peer_protocolSpec;
+ CORBA::Any_var AvailableProtocols_ptr;
+ AVStreams::protocolSpec my_protocol_spec,peer_protocol_spec;
+ AVStreams::protocolSpec_ptr temp_protocols;;
+ exception_message =
+ "TAO_FlowEndPoint::is_fep_compatible - AvailableProtocols";
AvailableProtocols_ptr = this->get_property_value ("AvailableProtocols",
ACE_TRY_ENV);
ACE_TRY_CHECK;
- if (AvailableProtocols_ptr != 0)
- *AvailableProtocols_ptr >>= my_protocolSpec;
- else
- ACE_ERROR_RETURN ((LM_ERROR,"(%P|%t) TAO_FlowEndPoint::is_fep_compatible"),0);
+ AvailableProtocols_ptr.in () >>= temp_protocols;
+ my_protocol_spec = *temp_protocols;
+ exception_message =
+ "TAO_FlowEndPoint::is_fep_compatible - AvailableProtocols[2]";
AvailableProtocols_ptr = peer_fep->get_property_value ("AvailableProtocols",
ACE_TRY_ENV);
ACE_TRY_CHECK;
- if (AvailableProtocols_ptr != 0)
- *AvailableProtocols_ptr >>= peer_protocolSpec;
+ AvailableProtocols_ptr.in () >>= temp_protocols;
+ peer_protocol_spec = *temp_protocols;
+
+ int protocol_match = 0;
+ for (u_int i=0;i<my_protocol_spec.length ();i++)
+ {
+ CORBA::String_var my_protocol_string;
+ for (u_int j=0;j<peer_protocol_spec.length ();j++)
+ {
+ CORBA::String_var peer_protocol_string;
+ my_protocol_string = CORBA::string_dup (my_protocol_spec[i]);
+ peer_protocol_string = CORBA::string_dup (peer_protocol_spec[j]);
+ if (ACE_OS::strcmp (my_protocol_string,peer_protocol_string) == 0)
+ {
+ protocol_match = 1;
+ break;
+ }
+ }
+ if (protocol_match)
+ break;
+ }
+ if (!protocol_match)
+ return 0;
+ }
+ ACE_CATCH (CosPropertyService::PropertyNotFound, nf)
+ {
+ ACE_PRINT_EXCEPTION (nf,
+ exception_message);
}
ACE_CATCHANY
{
- ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"TAO_FlowEndPoint::is_fep_compatible");
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,
+ "TAO_FlowEndPoint::is_fep_compatible");
return 0;
}
ACE_ENDTRY;
@@ -2150,97 +4219,171 @@ TAO_FlowEndPoint::is_fep_compatible (AVStreams::FlowEndPoint_ptr peer_fep,
}
CORBA::Boolean
-TAO_FlowEndPoint::set_peer (AVStreams::FlowConnection_ptr the_fc,
+TAO_FlowEndPoint::set_peer (AVStreams::FlowConnection_ptr /* the_fc */,
AVStreams::FlowEndPoint_ptr the_peer_fep,
- AVStreams::QoS & the_qos,
- CORBA::Environment &ACE_TRY_ENV)
+ AVStreams::QoS & /* the_qos */,
+ CORBA::Environment &/* ACE_TRY_ENV */)
ACE_THROW_SPEC ((CORBA::SystemException,
AVStreams::QoSRequestFailed,
AVStreams::streamOpFailed))
{
- ACE_UNUSED_ARG (the_fc);
- ACE_UNUSED_ARG (the_peer_fep);
- ACE_UNUSED_ARG (the_qos);
- ACE_UNUSED_ARG (ACE_TRY_ENV);
-
- this->peer_fep_ = the_peer_fep;
+ this->peer_fep_ =
+ AVStreams::FlowEndPoint::_duplicate (the_peer_fep);
return 1;
}
CORBA::Boolean
-TAO_FlowEndPoint::set_Mcast_peer (AVStreams::FlowConnection_ptr the_fc,
- AVStreams::MCastConfigIf_ptr a_mcastconfigif,
- AVStreams::QoS & the_qos,
- CORBA::Environment &ACE_TRY_ENV)
+TAO_FlowEndPoint::set_Mcast_peer (AVStreams::FlowConnection_ptr /* the_fc */,
+ AVStreams::MCastConfigIf_ptr mcast_peer,
+ AVStreams::QoS & /* the_qos */,
+ CORBA::Environment &/* ACE_TRY_ENV */)
ACE_THROW_SPEC ((CORBA::SystemException,
AVStreams::QoSRequestFailed))
{
- ACE_UNUSED_ARG (the_fc);
- ACE_UNUSED_ARG (a_mcastconfigif);
- ACE_UNUSED_ARG (the_qos);
- ACE_UNUSED_ARG (ACE_TRY_ENV);
+ this->mcast_peer_ = AVStreams::MCastConfigIf::_duplicate (mcast_peer);
return 0;
}
char *
-TAO_FlowEndPoint::go_to_listen (AVStreams::QoS & the_qos,
- CORBA::Boolean is_mcast,
- AVStreams::FlowProducer_ptr peer,
- char *& flowProtocol,
- CORBA::Environment &ACE_TRY_ENV)
+TAO_FlowEndPoint::go_to_listen_i (TAO_FlowSpec_Entry::Role role,
+ AVStreams::QoS & /*the_qos*/,
+ CORBA::Boolean is_mcast,
+ AVStreams::FlowEndPoint_ptr peer_fep,
+ char *& flowProtocol,
+ CORBA::Environment &ACE_TRY_ENV)
ACE_THROW_SPEC ((CORBA::SystemException,
- AVStreams::failedToListen,
- AVStreams::FPError,
+ AVStreams::failedToListen,
+ AVStreams::FPError,
AVStreams::QoSRequestFailed))
{
- return this->handle_go_to_listen (the_qos,is_mcast,peer,flowProtocol,ACE_TRY_ENV);
-}
-
-char *
-TAO_FlowEndPoint::handle_go_to_listen (AVStreams::QoS & the_qos,
- CORBA::Boolean is_mcast,
- AVStreams::FlowProducer_ptr peer,
- char *& flowProtocol,
- CORBA::Environment &ACE_TRY_ENV)
-{
- ACE_UNUSED_ARG (the_qos);
- ACE_UNUSED_ARG (is_mcast);
- ACE_UNUSED_ARG (peer);
- ACE_UNUSED_ARG (flowProtocol);
- ACE_UNUSED_ARG (ACE_TRY_ENV);
-
+ char direction [BUFSIZ];
+ switch (role)
+ {
+ case TAO_FlowSpec_Entry::TAO_AV_PRODUCER:
+ ACE_OS::strcpy (direction,"IN");
+ break;
+ case TAO_FlowSpec_Entry::TAO_AV_CONSUMER:
+ ACE_OS::strcpy (direction,"OUT");
+ break;
+ default:
+ break;
+ }
+ AVStreams::protocolSpec my_protocol_spec,peer_protocol_spec;
+ AVStreams::protocolSpec_ptr temp_protocols;
+ CORBA::Any_var AvailableProtocols_ptr =
+ peer_fep->get_property_value ("AvailableProtocols",
+ ACE_TRY_ENV);
+ ACE_CHECK_RETURN (0);
+ AvailableProtocols_ptr.in () >>= temp_protocols;
+ peer_protocol_spec = *temp_protocols;
+ AvailableProtocols_ptr =
+ this->get_property_value ("AvailableProtocols",
+ ACE_TRY_ENV);
+ ACE_CHECK_RETURN (0);
+ AvailableProtocols_ptr.in () >>= temp_protocols;
+ my_protocol_spec = *temp_protocols;
+ int protocol_match = 0;
+ CORBA::String_var listen_protocol;
+ u_int i =0;
+ for (i=0;i<my_protocol_spec.length ();i++)
+ {
+ CORBA::String_var my_protocol_string;
+ for (u_int j=0;j<peer_protocol_spec.length ();j++)
+ {
+ CORBA::String_var peer_protocol_string;
+ my_protocol_string = CORBA::string_dup (my_protocol_spec[i]);
+ peer_protocol_string = CORBA::string_dup (peer_protocol_spec[j]);
+ if (ACE_OS::strcmp (my_protocol_string,peer_protocol_string) == 0)
+ {
+ listen_protocol = my_protocol_string;
+ protocol_match = 1;
+ break;
+ }
+ }
+ if (protocol_match)
+ break;
+ }
+ if (!protocol_match)
+ ACE_ERROR_RETURN ((LM_ERROR,"TAO_FlowEndPoint::go_to_listen failed: no protoocol match\n"),0);
+
+ for (u_int j=0;j<this->protocol_addresses_.length ();j++)
+ if (ACE_OS::strncmp (this->protocol_addresses_ [j],listen_protocol,ACE_OS::strlen (listen_protocol)) == 0)
+ {
+ // Now listen on that protocol.
+ TAO_Forward_FlowSpec_Entry *entry;
+ ACE_NEW_RETURN (entry,
+ TAO_Forward_FlowSpec_Entry (this->flowname_.in (),
+ direction,
+ this->format_.in (),
+ flowProtocol,
+ this->protocol_addresses_ [j]),
+ 0);
+
+ TAO_AV_Acceptor_Registry *acceptor_registry = TAO_AV_CORE::instance ()->acceptor_registry ();
+ this->flow_spec_set_.insert (entry);
+ int result = acceptor_registry->open (this,
+ TAO_AV_CORE::instance (),
+ this->flow_spec_set_);
+ if (result < 0)
+ return 0;
+ char *listen_address = entry->get_local_addr_str ();
+ char *address;
+ ACE_NEW_RETURN (address,
+ char [BUFSIZ],
+ 0);
+ ACE_OS::sprintf (address,"%s=%s",listen_protocol.in (),listen_address);
+ return address;
+ }
return 0;
}
+
CORBA::Boolean
-TAO_FlowEndPoint::connect_to_peer (AVStreams::QoS & the_qos,
- const char * address,
- const char * use_flow_protocol,
- CORBA::Environment &ACE_TRY_ENV)
+TAO_FlowEndPoint::connect_to_peer_i (TAO_FlowSpec_Entry::Role role,
+ AVStreams::QoS & /*the_qos*/,
+ const char * address,
+ const char * use_flow_protocol,
+ CORBA::Environment &/*ACE_TRY_ENV*/)
ACE_THROW_SPEC ((CORBA::SystemException,
AVStreams::failedToConnect,
- AVStreams::FPError,
+ AVStreams::FPError,
AVStreams::QoSRequestFailed))
{
- // Right now since the A/V framework doesnt bother about the
- // protocols we leave it to the application to handle the connection
- // to its peer. When A/V Streams implements common protocol
- // interaction like UDP and TCP this will be handled by the
- // framework.
-
- return this->handle_connect_to_peer (the_qos,address,use_flow_protocol,ACE_TRY_ENV);
+ char direction [BUFSIZ];
+ switch (role)
+ {
+ case TAO_FlowSpec_Entry::TAO_AV_PRODUCER:
+ ACE_OS::strcpy (direction,"IN");
+ break;
+ case TAO_FlowSpec_Entry::TAO_AV_CONSUMER:
+ ACE_OS::strcpy (direction,"OUT");
+ break;
+ default:
+ break;
+ }
+ TAO_Forward_FlowSpec_Entry *entry;
+ ACE_NEW_RETURN (entry,
+ TAO_Forward_FlowSpec_Entry (this->flowname_.in (),
+ direction,
+ this->format_.in (),
+ use_flow_protocol,
+ address),
+ 0);
+ this->flow_spec_set_.insert (entry);
+ TAO_AV_Connector_Registry *connector_registry = TAO_AV_CORE::instance ()->connector_registry ();
+ int result = connector_registry->open (this,
+ TAO_AV_CORE::instance (),
+ this->flow_spec_set_);
+ if (result < 0)
+ ACE_ERROR_RETURN ((LM_ERROR,"TAO_FlowEndPoint::connector_registry::open failed\n"),0);
+ this->reverse_channel_ = entry->get_local_addr_str ();
+ return 1;
}
-CORBA::Boolean
-TAO_FlowEndPoint::handle_connect_to_peer (AVStreams::QoS & the_qos,
- const char * address,
- const char * use_flow_protocol,
- CORBA::Environment &ACE_TRY_ENV)
+int
+TAO_FlowEndPoint::set_protocol_object (const char *flowname,
+ TAO_AV_Protocol_Object *object)
{
- ACE_UNUSED_ARG (the_qos);
- ACE_UNUSED_ARG (address);
- ACE_UNUSED_ARG (use_flow_protocol);
- ACE_UNUSED_ARG (ACE_TRY_ENV);
return 0;
}
@@ -2254,36 +4397,125 @@ TAO_FlowProducer::TAO_FlowProducer (void)
{
}
-// multicast is currently not supported
+TAO_FlowProducer::TAO_FlowProducer (const char *flowname,
+ AVStreams::protocolSpec protocols,
+ const char *format)
+{
+ this->open (flowname,protocols,format);
+}
+
+// gets the reverse channel for feedback.
char *
-TAO_FlowProducer::connect_mcast (AVStreams::QoS & the_qos,
- CORBA::Boolean_out is_met,
- const char * address,
- const char * use_flow_protocol,
- CORBA::Environment &ACE_TRY_ENV)
+TAO_FlowProducer::get_rev_channel (const char *pcol_name,
+ CORBA::Environment &/* ACE_TRY_ENV */)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ return 0;
+}
+
+// The start,stop and destroy are to be handled by the application.
+void
+TAO_FlowProducer::stop (CORBA::Environment &/*ACE_TRY_ENV*/)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ TAO_AV_FlowSpecSetItor end = this->flow_spec_set_.end ();
+ for (TAO_AV_FlowSpecSetItor begin = this->flow_spec_set_.begin ();
+ begin != end; ++begin)
+ {
+ TAO_FlowSpec_Entry *entry = (*begin);
+ entry->handler ()->stop (TAO_FlowSpec_Entry::TAO_AV_PRODUCER);
+ }
+}
+
+void
+TAO_FlowProducer::start (CORBA::Environment &/*ACE_TRY_ENV*/)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ TAO_AV_FlowSpecSetItor end = this->flow_spec_set_.end ();
+ for (TAO_AV_FlowSpecSetItor begin = this->flow_spec_set_.begin ();
+ begin != end; ++begin)
+ {
+ TAO_FlowSpec_Entry *entry = (*begin);
+ entry->handler ()->start (TAO_FlowSpec_Entry::TAO_AV_PRODUCER);
+ }
+}
+
+char *
+TAO_FlowProducer::go_to_listen (AVStreams::QoS & the_qos,
+ CORBA::Boolean is_mcast,
+ AVStreams::FlowEndPoint_ptr peer_fep,
+ char *& flowProtocol,
+ CORBA::Environment &ACE_TRY_ENV)
ACE_THROW_SPEC ((CORBA::SystemException,
- AVStreams::failedToConnect,
- AVStreams::notSupported,
+ AVStreams::failedToListen,
AVStreams::FPError,
AVStreams::QoSRequestFailed))
{
- ACE_UNUSED_ARG (the_qos);
- ACE_UNUSED_ARG (is_met);
- ACE_UNUSED_ARG (address);
- ACE_UNUSED_ARG (use_flow_protocol);
- ACE_UNUSED_ARG (ACE_TRY_ENV);
- return 0;
+ return this->go_to_listen_i (TAO_FlowSpec_Entry::TAO_AV_PRODUCER,
+ the_qos,
+ is_mcast,
+ peer_fep,
+ flowProtocol,
+ ACE_TRY_ENV);
}
-// gets the reverse channel for feedback.
-char *
-TAO_FlowProducer::get_rev_channel (const char * pcol_name,
+CORBA::Boolean
+TAO_FlowProducer::connect_to_peer (AVStreams::QoS & the_qos,
+ const char * address,
+ const char * use_flow_protocol,
CORBA::Environment &ACE_TRY_ENV)
- ACE_THROW_SPEC ((CORBA::SystemException))
+ ACE_THROW_SPEC ((CORBA::SystemException,
+ AVStreams::failedToConnect,
+ AVStreams::FPError,
+ AVStreams::QoSRequestFailed))
{
- ACE_UNUSED_ARG (pcol_name);
- ACE_UNUSED_ARG (ACE_TRY_ENV);
- return 0;
+ return this->connect_to_peer_i (TAO_FlowSpec_Entry::TAO_AV_PRODUCER,
+ the_qos,
+ address,
+ use_flow_protocol,
+ ACE_TRY_ENV);
+}
+// Connect to a IP multicast address.
+char *
+TAO_FlowProducer::connect_mcast (AVStreams::QoS & /* the_qos */,
+ CORBA::Boolean_out /* is_met */,
+ const char *address,
+ const char * use_flow_protocol,
+ CORBA::Environment &/*ACE_TRY_ENV*/)
+ ACE_THROW_SPEC ((CORBA::SystemException,
+ AVStreams::failedToConnect,
+ AVStreams::notSupported,
+ AVStreams::FPError,
+ AVStreams::QoSRequestFailed))
+{
+ // The address variable gives the multicast address to subscribe to.
+ for (u_int i=0;i<this->protocols_.length ();i++)
+ {
+ // choose the protocol which supports multicast.
+ }
+ TAO_Forward_FlowSpec_Entry *entry;
+ ACE_NEW_RETURN (entry,
+ TAO_Forward_FlowSpec_Entry(this->flowname_.in (),
+ "IN",
+ this->format_.in (),
+ use_flow_protocol,
+ address),
+ 0);
+
+ this->flow_spec_set_.insert (entry);
+ TAO_AV_Acceptor_Registry *acceptor_registry =
+ TAO_AV_CORE::instance ()->acceptor_registry ();
+ int result = acceptor_registry->open (this,
+ TAO_AV_CORE::instance (),
+ this->flow_spec_set_);
+ if (result < 0)
+ ACE_ERROR_RETURN ((LM_ERROR,"TAO_FlowProducer::connect_mcast:acceptor_registry open failed\n"),0);
+ // Now remove our handler from the reactor since we're a producer and dont want to get called for
+ // multicast packets.
+ ACE_Event_Handler *event_handler = entry->handler ()->event_handler ();
+ event_handler->reactor ()->remove_handler (event_handler,
+ ACE_Event_Handler::READ_MASK);
+ return CORBA::string_dup (address);
}
// sets the key for this flow.
@@ -2312,10 +4544,9 @@ TAO_FlowProducer::set_key (const AVStreams::key & the_key,
// source id to be used to distinguish this source from others.
void
TAO_FlowProducer::set_source_id (CORBA::Long source_id,
- CORBA::Environment &ACE_TRY_ENV)
+ CORBA::Environment &/* ACE_TRY_ENV */)
ACE_THROW_SPEC ((CORBA::SystemException))
{
- ACE_UNUSED_ARG (ACE_TRY_ENV);
this->source_id_ = source_id;
}
@@ -2329,192 +4560,132 @@ TAO_FlowConsumer::TAO_FlowConsumer (void)
{
}
-// ------------------------------------------------------------
-// TAO_FDev
-// ------------------------------------------------------------
-
-// default constructor
-TAO_FDev::TAO_FDev (void)
- :producer_ (0),
- consumer_ (0)
-{
-}
-
-AVStreams::FlowProducer_ptr
-TAO_FDev::create_producer (AVStreams::FlowConnection_ptr the_requester,
- AVStreams::QoS & the_qos,
- CORBA::Boolean_out met_qos,
- char *& named_fdev,
- CORBA::Environment &ACE_TRY_ENV)
- ACE_THROW_SPEC ((CORBA::SystemException,
- AVStreams::streamOpFailed,
- AVStreams::streamOpDenied,
- AVStreams::notSupported,
- AVStreams::QoSRequestFailed))
-{
- // call the bridge method.
- this->producer_ = this->make_producer (the_requester,
- the_qos,
- met_qos,
- named_fdev,
- ACE_TRY_ENV);
- return this->producer_;
-}
-
-// hook for the applications to override the creation process.
-AVStreams::FlowProducer_ptr
-TAO_FDev::make_producer (AVStreams::FlowConnection_ptr /* the_requester */,
- AVStreams::QoS & /* the_qos */,
- CORBA::Boolean_out /* met_qos */,
- char *& /* named_fdev */,
- CORBA::Environment &ACE_TRY_ENV)
+TAO_FlowConsumer::TAO_FlowConsumer (const char *flowname,
+ AVStreams::protocolSpec protocols,
+ const char *format)
{
- AVStreams::FlowProducer_ptr flow_producer = AVStreams::FlowProducer::_nil ();
- ACE_TRY
- {
- // memory leak??
- TAO_FlowProducer *producer;
- ACE_NEW_RETURN (producer,
- TAO_FlowProducer,
- 0);
-
- flow_producer = producer->_this (ACE_TRY_ENV);
- ACE_TRY_CHECK;
- }
- ACE_CATCHANY
- {
- ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"TAO_FDev::make_producer");
- return flow_producer;
- }
- ACE_ENDTRY;
- ACE_CHECK_RETURN (flow_producer);
- return flow_producer;
+ this->open (flowname,protocols,format);
}
-// hook for the applications to override the consumer creation.
-AVStreams::FlowConsumer_ptr
-TAO_FDev::make_consumer (AVStreams::FlowConnection_ptr /* the_requester */,
- AVStreams::QoS & /* the_qos */,
- CORBA::Boolean_out /* met_qos */,
- char *& /* named_fdev */,
- CORBA::Environment &ACE_TRY_ENV)
+// The start,stop and destroy are to be handled by the application.
+void
+TAO_FlowConsumer::stop (CORBA::Environment &/*ACE_TRY_ENV*/)
+ ACE_THROW_SPEC ((CORBA::SystemException))
{
- AVStreams::FlowConsumer_ptr flow_consumer = AVStreams::FlowConsumer::_nil ();
- ACE_TRY
- {
-
- // memory leak??
- TAO_FlowConsumer *consumer;
- ACE_NEW_RETURN (consumer,
- TAO_FlowConsumer,
- 0);
- flow_consumer = consumer->_this (ACE_TRY_ENV);
- ACE_TRY_CHECK;
- }
- ACE_CATCHANY
- {
- ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"TAO_FDev::make_consumer");
- return flow_consumer;
- }
- ACE_ENDTRY;
- ACE_CHECK_RETURN (flow_consumer);
- return flow_consumer;
+ TAO_AV_FlowSpecSetItor end = this->flow_spec_set_.end ();
+ for (TAO_AV_FlowSpecSetItor begin = this->flow_spec_set_.begin ();
+ begin != end; ++begin)
+ (*begin)->handler ()->stop (TAO_FlowSpec_Entry::TAO_AV_CONSUMER);
}
-AVStreams::FlowConsumer_ptr
-TAO_FDev::create_consumer (AVStreams::FlowConnection_ptr the_requester,
- AVStreams::QoS & the_qos,
- CORBA::Boolean_out met_qos,
- char *& named_fdev,
- CORBA::Environment &ACE_TRY_ENV)
- ACE_THROW_SPEC ((CORBA::SystemException,
- AVStreams::streamOpFailed,
- AVStreams::streamOpDenied,
- AVStreams::notSupported,
- AVStreams::QoSRequestFailed))
+void
+TAO_FlowConsumer::start (CORBA::Environment &/*ACE_TRY_ENV*/)
+ ACE_THROW_SPEC ((CORBA::SystemException))
{
- this->consumer_ = this->make_consumer (the_requester,
- the_qos,
- met_qos,
- named_fdev,
- ACE_TRY_ENV);
- return this->consumer_;
+ TAO_AV_FlowSpecSetItor end = this->flow_spec_set_.end ();
+ for (TAO_AV_FlowSpecSetItor begin = this->flow_spec_set_.begin ();
+ begin != end; ++begin)
+ (*begin)->handler ()->start (TAO_FlowSpec_Entry::TAO_AV_CONSUMER);
}
-// not implemented yet.
-AVStreams::FlowConnection_ptr
-TAO_FDev::bind (AVStreams::FDev_ptr peer_device,
- AVStreams::QoS & the_qos,
- CORBA::Boolean_out is_met,
- CORBA::Environment &ACE_TRY_ENV)
+char *
+TAO_FlowConsumer::go_to_listen (AVStreams::QoS & the_qos,
+ CORBA::Boolean is_mcast,
+ AVStreams::FlowEndPoint_ptr peer_fep,
+ char *& flowProtocol,
+ CORBA::Environment &ACE_TRY_ENV)
ACE_THROW_SPEC ((CORBA::SystemException,
- AVStreams::streamOpFailed,
+ AVStreams::failedToListen,
+ AVStreams::FPError,
AVStreams::QoSRequestFailed))
{
- ACE_UNUSED_ARG (peer_device);
- ACE_UNUSED_ARG (the_qos);
- ACE_UNUSED_ARG (is_met);
- ACE_UNUSED_ARG (ACE_TRY_ENV);
- return 0;
+ return this->go_to_listen_i (TAO_FlowSpec_Entry::TAO_AV_CONSUMER,
+ the_qos,
+ is_mcast,
+ peer_fep,
+ flowProtocol,
+ ACE_TRY_ENV);
}
-// multicast is not supported yet.
-AVStreams::FlowConnection_ptr
-TAO_FDev::bind_mcast (AVStreams::FDev_ptr first_peer,
- AVStreams::QoS & the_qos,
- CORBA::Boolean_out is_met,
- CORBA::Environment &ACE_TRY_ENV)
+CORBA::Boolean
+TAO_FlowConsumer::connect_to_peer (AVStreams::QoS & the_qos,
+ const char * address,
+ const char * use_flow_protocol,
+ CORBA::Environment &ACE_TRY_ENV)
ACE_THROW_SPEC ((CORBA::SystemException,
- AVStreams::streamOpFailed,
+ AVStreams::failedToConnect,
+ AVStreams::FPError,
AVStreams::QoSRequestFailed))
{
- ACE_UNUSED_ARG (first_peer);
- ACE_UNUSED_ARG (the_qos);
- ACE_UNUSED_ARG (is_met);
- ACE_UNUSED_ARG (ACE_TRY_ENV);
- return 0;
-}
-
-void
-TAO_FDev::destroy (AVStreams::FlowEndPoint_ptr /* the_ep */,
- const char * /* fdev_name */,
- CORBA::Environment &ACE_TRY_ENV)
- ACE_THROW_SPEC ((CORBA::SystemException,
- AVStreams::notSupported))
-{
- // Remove self from POA. Because of reference counting, the POA
- // will automatically delete the servant when all pending requests
- // on this servant are complete.
- //
- PortableServer::POA_var poa = this->_default_POA (ACE_TRY_ENV);
- ACE_CHECK;
-
- PortableServer::ObjectId_var id = poa->servant_to_id (this,
- ACE_TRY_ENV);
- ACE_CHECK;
-
- poa->deactivate_object (id.in (),
- ACE_TRY_ENV);
- ACE_CHECK;
+ return this->connect_to_peer_i (TAO_FlowSpec_Entry::TAO_AV_CONSUMER,
+ the_qos,
+ address,
+ use_flow_protocol,
+ ACE_TRY_ENV);
}
//------------------------------------------------------------
// TAO_Tokenizer
//------------------------------------------------------------
-TAO_Tokenizer::TAO_Tokenizer (char *string, char delimiter)
+TAO_Tokenizer::TAO_Tokenizer (const char *string, char delimiter)
:token_array_ (10),
count_ (0)
{
this->parse (string,delimiter);
}
-int
-TAO_Tokenizer::parse (char *string,char delimiter)
+TAO_Tokenizer::~TAO_Tokenizer ()
{
+// ACE_Array_Iterator<char*> iterator (this->token_array_);
+// char **entry = 0;
+// for (; iterator.next (entry) != 0; iterator.advance ())
+// {
+// if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"%s\n",*entry));
+// CORBA::string_free (*entry);
+// }
+}
+
+
+int
+TAO_Tokenizer::parse (const char *string,char delimiter)
+{
+ ACE_CString new_string (string);
+ u_int pos =0;
+ int slash_pos = 0;
+ u_int count = 0;
+ int result;
+ while (pos < new_string.length ())
+ {
+ slash_pos = new_string.find (delimiter,pos);
+ ACE_CString substring;
+ if (slash_pos != new_string.npos)
+ {
+ substring = new_string.substring (pos,slash_pos);
+ pos += slash_pos+1;
+ }
+ else
+ {
+ substring = new_string.substring (pos);
+ pos = new_string.length ();
+ }
+ char *token = CORBA::string_dup (substring.c_str ());
+ result = this->token_array_.set (token,count);
+ if (result == -1)
+ {
+ this->token_array_.size (this->token_array_.size ()*2);
+ result = this->token_array_.set (token,count);
+ if (result == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,"TAO_Tokenizer::parse error"),-1);
+ }
+ count++;
+ }
+
+ /*
+ ACE_OS::strcpy (this->string_ , string);
char delimiter_str [2] = {0,0};
delimiter_str [0] = delimiter;
- char *token = ACE_OS::strtok (string,delimiter_str);
- int count=0,result;
+ char *token = ACE_OS::strtok (this->string_,delimiter_str);
+
while (token != 0)
{
result = this->token_array_.set (token,count);
@@ -2525,9 +4696,10 @@ TAO_Tokenizer::parse (char *string,char delimiter)
if (result == -1)
ACE_ERROR_RETURN ((LM_ERROR,"TAO_Tokenizer::parse error"),-1);
}
- token = ACE_OS::strtok (string,0);
+ token = ACE_OS::strtok (0,delimiter_str);
count++;
}
+ */
this->num_tokens_ = count;
return 0;
}
@@ -2536,7 +4708,7 @@ char*
TAO_Tokenizer::token (void)
{
if (count_ < num_tokens_)
- return this->token_array_[this->count_++];
+ return CORBA::string_dup (this->token_array_[this->count_++]);
else
return 0;
}
@@ -2552,143 +4724,262 @@ TAO_Tokenizer::operator [] (size_t index) const
{
if (index >= this->num_tokens_)
return 0;
- return this->token_array_[index];
-}
-
-//------------------------------------------------------------
-// TAO_FlowSpec_Entry
-//------------------------------------------------------------
-
-// constructor.
-TAO_FlowSpec_Entry::TAO_FlowSpec_Entry (void)
- :sfp_ (0),
- address_ (0),
- format_ (0),
- direction_ (TAO_AV_INVALID)
-{
+ return CORBA::string_dup (this->token_array_[index]);
}
-// Destructor.
-TAO_FlowSpec_Entry::~TAO_FlowSpec_Entry (void)
-{
-}
-int
-TAO_FlowSpec_Entry::direction (void)
-{
- return this->direction_;
-}
+#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
-TAO_SFP*
-TAO_FlowSpec_Entry::flow_protocol (void)
-{
- return this->sfp_;
-}
+template class ACE_Hash_Map_Entry<TAO_String_Hash_Key,AVStreams::FDev_ptr>;
+template class ACE_Hash_Map_Entry<TAO_String_Hash_Key,AVStreams::FlowConnection_ptr>;
+template class ACE_Hash_Map_Entry<TAO_String_Hash_Key,AVStreams::FlowEndPoint_ptr>;
+template class ACE_Hash_Map_Entry<TAO_String_Hash_Key, TAO_FlowSpec_Entry *>;
+
+template class ACE_Hash_Map_Manager<TAO_String_Hash_Key,AVStreams::FDev_ptr,ACE_Null_Mutex>;
+template class ACE_Hash_Map_Manager<TAO_String_Hash_Key,TAO_FlowSpec_Entry *, ACE_Null_Mutex>;
+template class ACE_Hash_Map_Manager<TAO_String_Hash_Key,AVStreams::FlowConnection_ptr,ACE_Null_Mutex>;
+
+template class ACE_Hash_Map_Iterator<TAO_String_Hash_Key,AVStreams::FDev_ptr,ACE_Null_Mutex>;
+template class ACE_Hash_Map_Iterator_Ex<TAO_String_Hash_Key, AVStreams::FDev_ptr, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>;
+template class ACE_Hash_Map_Iterator_Base_Ex<TAO_String_Hash_Key, AVStreams::FDev_ptr, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>;
+template class ACE_Hash_Map_Reverse_Iterator<TAO_String_Hash_Key,AVStreams::FDev_ptr,ACE_Null_Mutex>;
+template class ACE_Hash_Map_Reverse_Iterator_Ex<TAO_String_Hash_Key, AVStreams::FDev_ptr, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>;
+
+template class ACE_Hash_Map_Manager_Ex<TAO_String_Hash_Key, AVStreams::FDev_ptr, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>;
+template class ACE_Hash_Map_Manager_Ex<TAO_String_Hash_Key, AVStreams::FlowConnection_ptr, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>;
+template class ACE_Hash_Map_Manager_Ex<TAO_String_Hash_Key, TAO_FlowSpec_Entry *, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>;
+template class ACE_Hash_Map_Iterator<TAO_String_Hash_Key,AVStreams::FlowConnection_ptr,ACE_Null_Mutex>;
+template class ACE_Hash_Map_Iterator_Ex<TAO_String_Hash_Key, AVStreams::FlowConnection_ptr, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>;
+template class ACE_Hash_Map_Iterator_Base_Ex<TAO_String_Hash_Key, AVStreams::FlowConnection_ptr, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>;
+template class ACE_Hash_Map_Reverse_Iterator<TAO_String_Hash_Key,AVStreams::FlowConnection_ptr,ACE_Null_Mutex>;
+template class ACE_Hash_Map_Reverse_Iterator_Ex<TAO_String_Hash_Key, AVStreams::FlowConnection_ptr, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>;
+
+template class ACE_Hash_Map_Manager<TAO_String_Hash_Key,AVStreams::FlowEndPoint_ptr,ACE_Null_Mutex>;
+template class ACE_Hash_Map_Manager_Ex<TAO_String_Hash_Key, AVStreams::FlowEndPoint_ptr, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>;
+template class ACE_Hash_Map_Iterator<TAO_String_Hash_Key,AVStreams::FlowEndPoint_ptr,ACE_Null_Mutex>;
+template class ACE_Hash_Map_Iterator_Ex<TAO_String_Hash_Key, AVStreams::FlowEndPoint_ptr, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>;
+template class ACE_Hash_Map_Iterator_Base_Ex<TAO_String_Hash_Key, AVStreams::FlowEndPoint_ptr, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>;
+template class ACE_Hash_Map_Reverse_Iterator<TAO_String_Hash_Key,AVStreams::FlowEndPoint_ptr,ACE_Null_Mutex>;
+template class ACE_Hash_Map_Reverse_Iterator_Ex<TAO_String_Hash_Key, AVStreams::FlowEndPoint_ptr, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>;
+
+template class ACE_Hash_Map_Entry<MMDevice_Map_Hash_Key,TAO_StreamCtrl::MMDevice_Map_Entry>;
+template class ACE_Hash_Map_Manager<MMDevice_Map_Hash_Key,TAO_StreamCtrl::MMDevice_Map_Entry,ACE_Null_Mutex>;
+template class ACE_Hash_Map_Manager_Ex<MMDevice_Map_Hash_Key, TAO_StreamCtrl::MMDevice_Map_Entry, ACE_Hash<MMDevice_Map_Hash_Key>, ACE_Equal_To<MMDevice_Map_Hash_Key>, ACE_Null_Mutex>;
+template class ACE_Hash_Map_Iterator<MMDevice_Map_Hash_Key,TAO_StreamCtrl::MMDevice_Map_Entry,ACE_Null_Mutex>;
+template class ACE_Hash_Map_Iterator_Ex<MMDevice_Map_Hash_Key, TAO_StreamCtrl::MMDevice_Map_Entry, ACE_Hash<MMDevice_Map_Hash_Key>, ACE_Equal_To<MMDevice_Map_Hash_Key>, ACE_Null_Mutex>;
+template class ACE_Hash_Map_Iterator_Base_Ex<MMDevice_Map_Hash_Key, TAO_StreamCtrl::MMDevice_Map_Entry, ACE_Hash<MMDevice_Map_Hash_Key>, ACE_Equal_To<MMDevice_Map_Hash_Key>, ACE_Null_Mutex>;
+template class ACE_Hash_Map_Reverse_Iterator<MMDevice_Map_Hash_Key,TAO_StreamCtrl::MMDevice_Map_Entry,ACE_Null_Mutex>;
+template class ACE_Hash_Map_Reverse_Iterator_Ex<MMDevice_Map_Hash_Key, TAO_StreamCtrl::MMDevice_Map_Entry, ACE_Hash<MMDevice_Map_Hash_Key>, ACE_Equal_To<MMDevice_Map_Hash_Key>, ACE_Null_Mutex>;
+
+template class ACE_Hash_Map_Entry<TAO_String_Hash_Key,TAO_AV_Acceptor*>;
+template class ACE_Hash_Map_Manager<TAO_String_Hash_Key,TAO_AV_Acceptor*,ACE_Null_Mutex>;
+template class ACE_Hash_Map_Manager_Ex<TAO_String_Hash_Key, TAO_AV_Acceptor*, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>;
+template class ACE_Hash_Map_Iterator<TAO_String_Hash_Key,TAO_AV_Acceptor*,ACE_Null_Mutex>;
+template class ACE_Hash_Map_Iterator_Ex<TAO_String_Hash_Key, TAO_AV_Acceptor*, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>;
+template class ACE_Hash_Map_Iterator_Base_Ex<TAO_String_Hash_Key, TAO_AV_Acceptor*, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>;
+template class ACE_Hash_Map_Reverse_Iterator<TAO_String_Hash_Key,TAO_AV_Acceptor*,ACE_Null_Mutex>;
+template class ACE_Hash_Map_Reverse_Iterator_Ex<TAO_String_Hash_Key, TAO_AV_Acceptor*, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>;
+
+template class ACE_Hash_Map_Entry<TAO_String_Hash_Key,TAO_Forward_FlowSpec_Entry*>;
+template class ACE_Hash_Map_Manager<TAO_String_Hash_Key,TAO_Forward_FlowSpec_Entry*,ACE_Null_Mutex>;
+template class ACE_Hash_Map_Manager_Ex<TAO_String_Hash_Key, TAO_Forward_FlowSpec_Entry*, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>;
+template class ACE_Hash_Map_Iterator<TAO_String_Hash_Key,TAO_Forward_FlowSpec_Entry*,ACE_Null_Mutex>;
+template class ACE_Hash_Map_Iterator_Ex<TAO_String_Hash_Key, TAO_Forward_FlowSpec_Entry*, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>;
+template class ACE_Hash_Map_Iterator_Base_Ex<TAO_String_Hash_Key, TAO_Forward_FlowSpec_Entry*, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>;
+template class ACE_Hash_Map_Reverse_Iterator<TAO_String_Hash_Key,TAO_Forward_FlowSpec_Entry*,ACE_Null_Mutex>;
+template class ACE_Hash_Map_Reverse_Iterator_Ex<TAO_String_Hash_Key, TAO_Forward_FlowSpec_Entry*, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>;
+
+template class ACE_Hash_Map_Entry<TAO_String_Hash_Key,TAO_Reverse_FlowSpec_Entry*>;
+template class ACE_Hash_Map_Manager<TAO_String_Hash_Key,TAO_Reverse_FlowSpec_Entry*,ACE_Null_Mutex>;
+template class ACE_Hash_Map_Manager_Ex<TAO_String_Hash_Key, TAO_Reverse_FlowSpec_Entry*, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>;
+template class ACE_Hash_Map_Iterator<TAO_String_Hash_Key,TAO_Reverse_FlowSpec_Entry*,ACE_Null_Mutex>;
+template class ACE_Hash_Map_Iterator_Ex<TAO_String_Hash_Key, TAO_Reverse_FlowSpec_Entry*, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>;
+template class ACE_Hash_Map_Iterator_Base_Ex<TAO_String_Hash_Key, TAO_Reverse_FlowSpec_Entry*, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>;
+template class ACE_Hash_Map_Reverse_Iterator<TAO_String_Hash_Key,TAO_Reverse_FlowSpec_Entry*,ACE_Null_Mutex>;
+template class ACE_Hash_Map_Reverse_Iterator_Ex<TAO_String_Hash_Key, TAO_Reverse_FlowSpec_Entry*, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>;
+
+template class ACE_Hash_Map_Entry<TAO_String_Hash_Key,TAO_AV_UDP_MCast_Flow_Handler*>;
+template class ACE_Hash_Map_Manager<TAO_String_Hash_Key,TAO_AV_UDP_MCast_Flow_Handler*,ACE_Null_Mutex>;
+template class ACE_Hash_Map_Manager_Ex<TAO_String_Hash_Key, TAO_AV_UDP_MCast_Flow_Handler*, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>;
+template class ACE_Hash_Map_Iterator<TAO_String_Hash_Key,TAO_AV_UDP_MCast_Flow_Handler*,ACE_Null_Mutex>;
+template class ACE_Hash_Map_Iterator_Ex<TAO_String_Hash_Key, TAO_AV_UDP_MCast_Flow_Handler*, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>;
+template class ACE_Hash_Map_Iterator_Base_Ex<TAO_String_Hash_Key, TAO_AV_UDP_MCast_Flow_Handler*, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>;
+template class ACE_Hash_Map_Reverse_Iterator<TAO_String_Hash_Key,TAO_AV_UDP_MCast_Flow_Handler*,ACE_Null_Mutex>;
+template class ACE_Hash_Map_Reverse_Iterator_Ex<TAO_String_Hash_Key, TAO_AV_UDP_MCast_Flow_Handler*, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>;
+
+template class ACE_Hash_Map_Entry<TAO_String_Hash_Key,AVStreams::QoS>;
+template class ACE_Hash_Map_Manager<TAO_String_Hash_Key,AVStreams::QoS,ACE_Null_Mutex>;
+template class ACE_Hash_Map_Manager_Ex<TAO_String_Hash_Key, AVStreams::QoS, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>;
+template class ACE_Hash_Map_Iterator<TAO_String_Hash_Key,AVStreams::QoS,ACE_Null_Mutex>;
+template class ACE_Hash_Map_Iterator_Ex<TAO_String_Hash_Key, AVStreams::QoS, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>;
+template class ACE_Hash_Map_Iterator_Base_Ex<TAO_String_Hash_Key, AVStreams::QoS, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>;
+template class ACE_Hash_Map_Reverse_Iterator<TAO_String_Hash_Key,AVStreams::QoS,ACE_Null_Mutex>;
+template class ACE_Hash_Map_Reverse_Iterator_Ex<TAO_String_Hash_Key, AVStreams::QoS, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>;
+
+template class ACE_Hash_Map_Manager<TAO_String_Hash_Key,TAO_FlowSpec_Entry *,ACE_Null_Mutex>;
+template class ACE_Hash_Map_Manager_Ex<TAO_String_Hash_Key, TAO_FlowSpec_Entry *, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>;
+template class ACE_Hash_Map_Iterator<TAO_String_Hash_Key,TAO_FlowSpec_Entry *,ACE_Null_Mutex>;
+template class ACE_Hash_Map_Iterator_Ex<TAO_String_Hash_Key, TAO_FlowSpec_Entry *, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>;
+template class ACE_Hash_Map_Iterator_Base_Ex<TAO_String_Hash_Key, TAO_FlowSpec_Entry *, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>;
+template class ACE_Hash_Map_Reverse_Iterator<TAO_String_Hash_Key,TAO_FlowSpec_Entry *,ACE_Null_Mutex>;
+template class ACE_Hash_Map_Reverse_Iterator_Ex<TAO_String_Hash_Key, TAO_FlowSpec_Entry *, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>;
+
+template class ACE_Svc_Handler <ACE_SOCK_STREAM,ACE_NULL_SYNCH>;
-ACE_Addr*
-TAO_FlowSpec_Entry::carrier_protocol (void)
-{
- return address_;
-}
-
-char*
-TAO_FlowSpec_Entry::format (void)
-{
- return this->format_;
-}
+template class ACE_Array<char*>;
+template class ACE_Array_Base<char*>;
+template class ACE_DLList<TAO_MCastConfigIf::Peer_Info>;
+template class ACE_DLList_Iterator<TAO_MCastConfigIf::Peer_Info>;
+template class ACE_DLList <TAO_FlowProducer>;
+template class ACE_DLList_Iterator <TAO_FlowProducer>;
+template class ACE_DLList <TAO_FlowConsumer>;
+template class ACE_DLList_Iterator <TAO_FlowConsumer>;
-int
-TAO_Forward_FlowSpec_Entry::parse (char *flowSpec_entry)
-{
- TAO_Tokenizer tokenizer (flowSpec_entry,'\\');
- if (this->parse_flow_protocol_string (tokenizer [TAO_AV_FLOW_PROTOCOL]) < 0)
- return -1;
- this->set_direction (tokenizer [TAO_AV_DIRECTION]);
- if (this->parse_address (tokenizer [TAO_AV_ADDRESS]) < 0)
- return -1;
- this->format_ = tokenizer [TAO_AV_FORMAT];
- this->flowname_ = tokenizer [TAO_AV_FLOWNAME];
- return 0;
-}
+template class ACE_Node <TAO_FlowSpec_Entry*>;
+template class ACE_Unbounded_Set <TAO_FlowSpec_Entry*>;
+template class ACE_Unbounded_Set_Iterator <TAO_FlowSpec_Entry*>;
-int
-TAO_FlowSpec_Entry::set_direction (char *direction)
-{
- if (ACE_OS::strcasecmp (direction,"in") == 0)
- this->direction_ = TAO_AV_DIR_IN;
- else if (ACE_OS::strcasecmp (direction,"out") == 0)
- this->direction_ = TAO_AV_DIR_OUT;
- else if (ACE_OS::strcasecmp (direction,"inout") == 0)
- this->direction_ = TAO_AV_DIR_INOUT;
- return 0;
-}
+template class ACE_Node <TAO_AV_Transport_Item*>;
+template class ACE_Unbounded_Set<TAO_AV_Transport_Item*>;
+template class ACE_Unbounded_Set_Iterator<TAO_AV_Transport_Item*>;
-int
-TAO_FlowSpec_Entry::parse_flow_protocol_string (char *flow_string)
-{
- if (ACE_OS::strncasecmp (flow_string,"sfp",3) == 0)
- {
- // do some flow protocol processing.
- }
- return 0;
-}
+template class ACE_Node <TAO_AV_Flow_Protocol_Item*>;
+template class ACE_Unbounded_Set<TAO_AV_Flow_Protocol_Item*>;
+template class ACE_Unbounded_Set_Iterator<TAO_AV_Flow_Protocol_Item*>;
-int
-TAO_FlowSpec_Entry::parse_address (char *address)
-{
- TAO_Tokenizer protocol_tokenizer (address,'=');
- this->protocol_ = protocol_tokenizer[0];
- TAO_Tokenizer address_tokenizer (protocol_tokenizer[1],';');
- char addr[BUFSIZ];
- ACE_OS::sprintf (addr,"%s:%s",address_tokenizer[0],address_tokenizer[1]);
- if (ACE_OS::strncasecmp (this->protocol_,"AAL",3) == 0)
- ACE_DEBUG ((LM_DEBUG,"ATM support not added yet\n"));
-// ACE_NEW_RETURN (this->address_,
-// ACE_ATM_Addr (addr),
-// -1);
- else // we assume everything else is INET addr.
- {
- ACE_NEW_RETURN (this->address_,
- ACE_INET_Addr (addr),
- -1);
- }
- return 0;
-}
+template class ACE_Node<AVStreams::FlowProducer *>;
+template class ACE_Unbounded_Set<AVStreams::FlowProducer *>;
+template class ACE_Unbounded_Set_Iterator<AVStreams::FlowProducer *>;
-int
-TAO_Reverse_FlowSpec_Entry::parse (char *flowSpec_entry)
-{
- TAO_Tokenizer tokenizer (flowSpec_entry,'\\');
- if (this->parse_flow_protocol_string (tokenizer [TAO_AV_FLOW_PROTOCOL]) < 0)
- return -1;
- this->set_direction (tokenizer [TAO_AV_DIRECTION]);
- if (this->parse_address (tokenizer [TAO_AV_ADDRESS]) < 0)
- return -1;
- this->format_ = tokenizer [TAO_AV_FORMAT];
- this->flowname_ = tokenizer [TAO_AV_FLOWNAME];
- return 0;
-}
+template class ACE_Node<AVStreams::FlowConsumer *>;
+template class ACE_Unbounded_Set<AVStreams::FlowConsumer *>;
+template class ACE_Unbounded_Set_Iterator<AVStreams::FlowConsumer *>;
-#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
-template class ACE_Hash_Map_Entry<TAO_String_Hash_Key,CORBA::Object_ptr>;
-template class ACE_Hash_Map_Manager<TAO_String_Hash_Key,CORBA::Object_ptr,ACE_Null_Mutex>;
-template class ACE_Hash_Map_Manager_Ex<TAO_String_Hash_Key, CORBA::Object_ptr, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>;
-template class ACE_Hash_Map_Iterator<TAO_String_Hash_Key,CORBA::Object_ptr,ACE_Null_Mutex>;
-template class ACE_Hash_Map_Iterator_Ex<TAO_String_Hash_Key, CORBA::Object_ptr, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>;
-template class ACE_Hash_Map_Iterator_Base_Ex<TAO_String_Hash_Key, CORBA::Object_ptr, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>;
-template class ACE_Hash_Map_Reverse_Iterator<TAO_String_Hash_Key,CORBA::Object_ptr,ACE_Null_Mutex>;
-template class ACE_Hash_Map_Reverse_Iterator_Ex<TAO_String_Hash_Key, CORBA::Object_ptr, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>;
-template class ACE_Array<char*>;
-template class ACE_Array_Base<char*>;
#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
-#pragma instantiate ACE_Hash_Map_Entry<TAO_String_Hash_Key,CORBA::Object_ptr>
-#pragma instantiate ACE_Hash_Map_Manager<TAO_String_Hash_Key,CORBA::Object_ptr,ACE_Null_Mutex>
-#pragma instantiate ACE_Hash_Map_Manager_Ex<TAO_String_Hash_Key, CORBA::Object_ptr, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>
-#pragma instantiate ACE_Hash_Map_Iterator<TAO_String_Hash_Key,CORBA::Object_ptr,ACE_Null_Mutex>
-#pragma instantiate ACE_Hash_Map_Iterator_Ex<TAO_String_Hash_Key, CORBA::Object_ptr, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>
-#pragma instantiate ACE_Hash_Map_Iterator_Base_Ex<TAO_String_Hash_Key, CORBA::Object_ptr, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>
-#pragma instantiate ACE_Hash_Map_Reverse_Iterator<TAO_String_Hash_Key,CORBA::Object_ptr,ACE_Null_Mutex>
-#pragma instantiate ACE_Hash_Map_Reverse_Iterator_Ex<TAO_String_Hash_Key, CORBA::Object_ptr, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>
+
+#pragma instantiate ACE_Hash_Map_Entry<TAO_String_Hash_Key,AVStreams::FDev_ptr>
+#pragma instantaite ACE_Hash_Map_Entry<TAO_String_Hash_Key, TAO_FlowSpec_Entry *>
+#pragma instantiate ACE_Hash_Map_Manager<TAO_String_Hash_Key,AVStreams::FDev_ptr,ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Manager<TAO_String_Hash_Key,TAO_FlowSpec_Entry *, ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Manager_Ex<TAO_String_Hash_Key, AVStreams::FDev_ptr, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Iterator<TAO_String_Hash_Key,AVStreams::FDev_ptr,ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Iterator_Ex<TAO_String_Hash_Key, AVStreams::FDev_ptr, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Iterator_Base_Ex<TAO_String_Hash_Key, AVStreams::FDev_ptr, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Reverse_Iterator<TAO_String_Hash_Key,AVStreams::FDev_ptr,ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Reverse_Iterator_Ex<TAO_String_Hash_Key, AVStreams::FDev_ptr, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Manager_Ex<TAO_String_Hash_Key, TAO_FlowSpec_Entry *, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>
+
+#pragma instantiate ACE_Hash_Map_Entry<TAO_String_Hash_Key,AVStreams::FlowConnection_ptr>
+#pragma instantiate ACE_Hash_Map_Manager<TAO_String_Hash_Key,AVStreams::FlowConnection_ptr,ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Manager_Ex<TAO_String_Hash_Key, AVStreams::FlowConnection_ptr, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Iterator<TAO_String_Hash_Key,AVStreams::FlowConnection_ptr,ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Iterator_Ex<TAO_String_Hash_Key, AVStreams::FlowConnection_ptr, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Iterator_Base_Ex<TAO_String_Hash_Key, AVStreams::FlowConnection_ptr, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Reverse_Iterator<TAO_String_Hash_Key,AVStreams::FlowConnection_ptr,ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Reverse_Iterator_Ex<TAO_String_Hash_Key, AVStreams::FlowConnection_ptr, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>
+
+#pragma instantiate ACE_Hash_Map_Entry<TAO_String_Hash_Key,AVStreams::FlowEndPoint_ptr>
+#pragma instantiate ACE_Hash_Map_Manager<TAO_String_Hash_Key,AVStreams::FlowEndPoint_ptr,ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Manager_Ex<TAO_String_Hash_Key, AVStreams::FlowEndPoint_ptr, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Iterator<TAO_String_Hash_Key,AVStreams::FlowEndPoint_ptr,ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Iterator_Ex<TAO_String_Hash_Key, AVStreams::FlowEndPoint_ptr, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Iterator_Base_Ex<TAO_String_Hash_Key, AVStreams::FlowEndPoint_ptr, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Reverse_Iterator<TAO_String_Hash_Key,AVStreams::FlowEndPoint_ptr,ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Reverse_Iterator_Ex<TAO_String_Hash_Key, AVStreams::FlowEndPoint_ptr, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>
+
+#pragma instantiate ACE_Hash_Map_Entry<MMDevice_Map_Hash_Key,TAO_StreamCtrl::MMDevice_Map_Entry>
+#pragma instantiate ACE_Hash_Map_Manager<MMDevice_Map_Hash_Key,TAO_StreamCtrl::MMDevice_Map_Entry,ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Manager_Ex<MMDevice_Map_Hash_Key, TAO_StreamCtrl::MMDevice_Map_Entry, ACE_Hash<MMDevice_Map_Hash_Key>, ACE_Equal_To<MMDevice_Map_Hash_Key>, ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Iterator<MMDevice_Map_Hash_Key,TAO_StreamCtrl::MMDevice_Map_Entry,ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Iterator_Ex<MMDevice_Map_Hash_Key, TAO_StreamCtrl::MMDevice_Map_Entry, ACE_Hash<MMDevice_Map_Hash_Key>, ACE_Equal_To<MMDevice_Map_Hash_Key>, ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Iterator_Base_Ex<MMDevice_Map_Hash_Key, TAO_StreamCtrl::MMDevice_Map_Entry, ACE_Hash<MMDevice_Map_Hash_Key>, ACE_Equal_To<MMDevice_Map_Hash_Key>, ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Reverse_Iterator<MMDevice_Map_Hash_Key,TAO_StreamCtrl::MMDevice_Map_Entry,ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Reverse_Iterator_Ex<MMDevice_Map_Hash_Key, TAO_StreamCtrl::MMDevice_Map_Entry, ACE_Hash<MMDevice_Map_Hash_Key>, ACE_Equal_To<MMDevice_Map_Hash_Key>, ACE_Null_Mutex>
+
+#pragma instantiate ACE_Hash_Map_Entry<TAO_String_Hash_Key,TAO_AV_Acceptor*>
+#pragma instantiate ACE_Hash_Map_Manager<TAO_String_Hash_Key,TAO_AV_Acceptor*,ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Manager_Ex<TAO_String_Hash_Key, TAO_AV_Acceptor*, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Iterator<TAO_String_Hash_Key,TAO_AV_Acceptor*,ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Iterator_Ex<TAO_String_Hash_Key, TAO_AV_Acceptor*, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Iterator_Base_Ex<TAO_String_Hash_Key, TAO_AV_Acceptor*, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Reverse_Iterator<TAO_String_Hash_Key,TAO_AV_Acceptor*,ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Reverse_Iterator_Ex<TAO_String_Hash_Key, TAO_AV_Acceptor*, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>
+
+#pragma instantiate ACE_Hash_Map_Entry<TAO_String_Hash_Key,TAO_Forward_FlowSpec_Entry*>
+#pragma instantiate ACE_Hash_Map_Manager<TAO_String_Hash_Key,TAO_Forward_FlowSpec_Entry*,ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Manager_Ex<TAO_String_Hash_Key, TAO_Forward_FlowSpec_Entry*, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Iterator<TAO_String_Hash_Key,TAO_Forward_FlowSpec_Entry*,ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Iterator_Ex<TAO_String_Hash_Key, TAO_Forward_FlowSpec_Entry*, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Iterator_Base_Ex<TAO_String_Hash_Key, TAO_Forward_FlowSpec_Entry*, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Reverse_Iterator<TAO_String_Hash_Key,TAO_Forward_FlowSpec_Entry*,ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Reverse_Iterator_Ex<TAO_String_Hash_Key, TAO_Forward_FlowSpec_Entry*, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>
+
+#pragma instantiate ACE_Hash_Map_Entry<TAO_String_Hash_Key,TAO_Reverse_FlowSpec_Entry*>
+#pragma instantiate ACE_Hash_Map_Manager<TAO_String_Hash_Key,TAO_Reverse_FlowSpec_Entry*,ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Manager_Ex<TAO_String_Hash_Key, TAO_Reverse_FlowSpec_Entry*, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Iterator<TAO_String_Hash_Key,TAO_Reverse_FlowSpec_Entry*,ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Iterator_Ex<TAO_String_Hash_Key, TAO_Reverse_FlowSpec_Entry*, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Iterator_Base_Ex<TAO_String_Hash_Key, TAO_Reverse_FlowSpec_Entry*, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Reverse_Iterator<TAO_String_Hash_Key,TAO_Reverse_FlowSpec_Entry*,ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Reverse_Iterator_Ex<TAO_String_Hash_Key, TAO_Reverse_FlowSpec_Entry*, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>
+
+#pragma instantiate ACE_Hash_Map_Entry<TAO_String_Hash_Key,TAO_AV_UDP_MCast_Flow_Handler*>
+#pragma instantiate ACE_Hash_Map_Manager<TAO_String_Hash_Key,TAO_AV_UDP_MCast_Flow_Handler*,ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Manager_Ex<TAO_String_Hash_Key, TAO_AV_UDP_MCast_Flow_Handler*, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Iterator<TAO_String_Hash_Key,TAO_AV_UDP_MCast_Flow_Handler*,ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Iterator_Ex<TAO_String_Hash_Key, TAO_AV_UDP_MCast_Flow_Handler*, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Iterator_Base_Ex<TAO_String_Hash_Key, TAO_AV_UDP_MCast_Flow_Handler*, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Reverse_Iterator<TAO_String_Hash_Key,TAO_AV_UDP_MCast_Flow_Handler*,ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Reverse_Iterator_Ex<TAO_String_Hash_Key, TAO_AV_UDP_MCast_Flow_Handler*, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>
+
+#pragma instantiate ACE_Hash_Map_Entry<TAO_String_Hash_Key,AVStreams::QoS>
+#pragma instantiate ACE_Hash_Map_Manager<TAO_String_Hash_Key,AVStreams::QoS,ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Manager_Ex<TAO_String_Hash_Key, AVStreams::QoS, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Iterator<TAO_String_Hash_Key,AVStreams::QoS,ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Iterator_Ex<TAO_String_Hash_Key, AVStreams::QoS, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Iterator_Base_Ex<TAO_String_Hash_Key, AVStreams::QoS, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Reverse_Iterator<TAO_String_Hash_Key,AVStreams::QoS,ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Reverse_Iterator_Ex<TAO_String_Hash_Key, AVStreams::QoS, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>
+
+#pragma instantiate ACE_Hash_Map_Entry<TAO_String_Hash_Key,TAO_FlowSpec_Entry *>
+#pragma instantiate ACE_Hash_Map_Manager<TAO_String_Hash_Key,TAO_FlowSpec_Entry *,ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Manager_Ex<TAO_String_Hash_Key, TAO_FlowSpec_Entry *, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Iterator<TAO_String_Hash_Key,TAO_FlowSpec_Entry *,ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Iterator_Ex<TAO_String_Hash_Key, TAO_FlowSpec_Entry *, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Iterator_Base_Ex<TAO_String_Hash_Key, TAO_FlowSpec_Entry *, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Reverse_Iterator<TAO_String_Hash_Key,TAO_FlowSpec_Entry *,ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Reverse_Iterator_Ex<TAO_String_Hash_Key, TAO_FlowSpec_Entry *, ACE_Hash<TAO_String_Hash_Key>, ACE_Equal_To<TAO_String_Hash_Key>, ACE_Null_Mutex>
+
+
+#pragma instantiate ACE_Svc_Handler <ACE_SOCK_STREAM,ACE_NULL_SYNCH>
#pragma instantiate ACE_Array<char*>
#pragma instantiate ACE_Array_Base<char*>
+#pragma instantiate ACE_DLList<TAO_MCastConfigIf::Peer_Info>
+#pragma instantiate ACE_DLList_Iterator<TAO_MCastConfigIf::Peer_Info>
+#pragma instantiate ACE_DLList <TAO_FlowProducer>
+#pragma instantiate ACE_DLList_Iterator <TAO_FlowProducer>
+#pragma instantiate ACE_DLList <TAO_FlowConsumer>
+#pragma instantiate ACE_DLList_Iterator <TAO_FlowConsumer>
+
+#pragma instantiate ACE_Node <TAO_FlowSpec_Entry*>
+#pragma instantiate ACE_Unbounded_Set <TAO_FlowSpec_Entry*>
+#pragma instantiate ACE_Unbounded_Set_Iterator <TAO_FlowSpec_Entry*>
+
+#pragma instantiate ACE_Node <TAO_AV_Transport_Item*>
+#pragma instantiate ACE_Unbounded_Set<TAO_AV_Transport_Item*>
+#pragma instantiate ACE_Unbounded_Set_Iterator<TAO_AV_Transport_Item*>
+
+#pragma instantiate ACE_Node <TAO_AV_Flow_Protocol_Item*>
+#pragma instantiate ACE_Unbounded_Set<TAO_AV_Flow_Protocol_Item*>
+#pragma instantiate ACE_Unbounded_Set_Iterator<TAO_AV_Transport_Item*>
+
+#pragma instantiate ACE_Node<AVStreams::FlowProducer *>
+#pragma instantiate ACE_Unbounded_Set<AVStreams::FlowProducer *>
+#pragma instantiate ACE_Unbounded_Set_Iterator<AVStreams::FlowProducer *>
+
+#pragma instantiate ACE_Node<AVStreams::FlowConsumer *>
+#pragma instantiate ACE_Unbounded_Set<AVStreams::FlowConsumer *>
+#pragma instantiate ACE_Unbounded_Set_Iterator<AVStreams::FlowConsumer *>
+
+
#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */
diff --git a/TAO/orbsvcs/orbsvcs/AV/AVStreams_i.h b/TAO/orbsvcs/orbsvcs/AV/AVStreams_i.h
index 1a871277da6..405b7b00e92 100644
--- a/TAO/orbsvcs/orbsvcs/AV/AVStreams_i.h
+++ b/TAO/orbsvcs/orbsvcs/AV/AVStreams_i.h
@@ -5,7 +5,7 @@
// ============================================================================
//
// = LIBRARY
-// cos
+// ORBSVCS (AVStreams)
//
// = FILENAME
// AVStreams_i.h
@@ -20,11 +20,20 @@
#ifndef AVSTREAMS_I_H
#define AVSTREAMS_I_H
+#include "ace/OS.h"
#include "ace/SOCK_Dgram_Mcast.h"
#include "ace/ATM_Addr.h"
#include "ace/Containers_T.h"
#include "ace/Process.h"
-
+#include "ace/SOCK_CODgram.h"
+#include "ace/Connector.h"
+#include "ace/SOCK_Connector.h"
+#include "ace/Acceptor.h"
+#include "ace/SOCK_Stream.h"
+#include "ace/Svc_Handler.h"
+#include "ace/SOCK_Acceptor.h"
+
+#include "tao/TAO.h"
#include "orbsvcs/orbsvcs_export.h"
#include "orbsvcs/CosPropertyServiceS.h"
#include "orbsvcs/AVStreamsS.h"
@@ -32,10 +41,19 @@
#include "orbsvcs/CosNamingC.h"
#include "orbsvcs/AV/Endpoint_Strategy.h"
#include "orbsvcs/Null_MediaCtrlS.h"
+
+#if defined (TAO_ORBSVCS_HAS_Trader)
#include "orbsvcs/Trader/Trader.h"
-// for the Hash_Map helper classes.
+#endif /* TAO_ORBSVCS_HAS_Trader */
-#include "sfp.h"
+#include "FlowSpec_Entry.h"
+
+#if defined(sun) || defined(__osf__)
+extern "C" int gethostname(char* name, int len);
+#endif
+
+#define FLOWSPEC_MAX 5
+// for the Hash_Map helper classes.
// This is to remove "inherits via dominance" warnings from MSVC.
// MSVC is being a little too paranoid.
@@ -43,6 +61,54 @@
# pragma warning (disable : 4250)
#endif /* _MSC_VER */
+#if !defined (TAO_ORBSVCS_HAS_Trader)
+
+// = Classes to deal with the ACE_Hash_Map_Manager.
+class TAO_ORBSVCS_Export TAO_String_Hash_Key : public CORBA::String_var
+{
+ // = TITLE
+ // Key for the Hash Table. The EXT_ID of the
+ // ACE_Hash_Map_Manager.
+public:
+ // = Initialization and termination methods.
+ TAO_String_Hash_Key (void);
+ // Default constructor.
+
+ TAO_String_Hash_Key (char * name);
+ // Constructor from a const string.
+
+ TAO_String_Hash_Key (const char * name);
+ // Constructor from a const string.
+
+ TAO_String_Hash_Key (const CORBA::String_var &hash_key);
+ // Copy constructor.
+
+ ~TAO_String_Hash_Key (void);
+ // Destructor.
+
+ int operator == (const TAO_String_Hash_Key &hash_key) const;
+ // The operator for hash binding and "find"ing.
+
+ friend int operator < (const TAO_String_Hash_Key &left,
+ const TAO_String_Hash_Key &right);
+ // The operator for hash binding and "find"ing.
+
+ u_long hash (void) const;
+ // The function that computes a hash value.
+};
+#endif /* !TAO_ORBSVCS_HAS_Trader */
+
+typedef ACE_Hash_Map_Manager <TAO_String_Hash_Key,AVStreams::FlowEndPoint_ptr,ACE_Null_Mutex> FlowEndPoint_Map;
+typedef ACE_Hash_Map_Entry <TAO_String_Hash_Key,AVStreams::FlowEndPoint_ptr> FlowEndPoint_Map_Entry;
+typedef ACE_Hash_Map_Iterator <TAO_String_Hash_Key,AVStreams::FlowEndPoint_ptr,ACE_Null_Mutex> FlowEndPoint_Map_Iterator;
+
+#include "AV_Core.h"
+
+typedef ACE_Singleton <TAO_AV_Core,ACE_Null_Mutex> TAO_AV_CORE;
+
+int deactivate_servant (PortableServer::Servant servant);
+char *get_flowname (const char *flow_spec_entry_str);
+
class TAO_ORBSVCS_Export AV_Null_MediaCtrl
: public virtual POA_Null_MediaCtrl,
public virtual PortableServer::RefCountServantBase
@@ -52,7 +118,7 @@ public:
};
-class TAO_ORBSVCS_Export TAO_Basic_StreamCtrl
+class TAO_ORBSVCS_Export TAO_Basic_StreamCtrl
: public virtual POA_AVStreams::Basic_StreamCtrl,
public virtual TAO_PropertySet,
public virtual PortableServer::RefCountServantBase
@@ -65,22 +131,25 @@ public:
TAO_Basic_StreamCtrl (void);
// Default Constructor
+ virtual ~TAO_Basic_StreamCtrl (void);
+ // Destructor.
+
virtual void stop (const AVStreams::flowSpec &the_spec,
- CORBA::Environment &env = CORBA::Environment::default_environment ())
+ CORBA::Environment &env = CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException,
AVStreams::noSuchFlow));
// Stop the transfer of data of the stream
// Empty the_spec means apply operation to all flows
virtual void start (const AVStreams::flowSpec &the_spec,
- CORBA::Environment &env = CORBA::Environment::default_environment ())
+ CORBA::Environment &env = CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException,
AVStreams::noSuchFlow));
// Start the transfer of data in the stream.
// Empty the_spec means apply operation to all flows
virtual void destroy (const AVStreams::flowSpec &the_spec,
- CORBA::Environment &env = CORBA::Environment::default_environment ())
+ CORBA::Environment &env = CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException,
AVStreams::noSuchFlow));
// Tears down the stream. This will close the connection, and delete
@@ -89,15 +158,15 @@ public:
virtual CORBA::Boolean modify_QoS (AVStreams::streamQoS &new_qos,
const AVStreams::flowSpec &the_spec,
- CORBA::Environment &env = CORBA::Environment::default_environment ())
+ CORBA::Environment &env = CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException,
AVStreams::noSuchFlow,
AVStreams::QoSRequestFailed));
// Changes the QoS associated with the stream
// Empty the_spec means apply operation to all flows
- virtual void push_event (const struct CosPropertyService::Property & the_event,
- CORBA::Environment &env = CORBA::Environment::default_environment ())
+ virtual void push_event (const struct CosPropertyService::Property & the_event,
+ CORBA::Environment &env = CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException));
// Used by StreamEndPoint and VDev to inform StreamCtrl of events.
// E.g., loss of flow, reestablishment of flow, etc..
@@ -105,7 +174,7 @@ public:
virtual void set_FPStatus (const AVStreams::flowSpec &the_spec,
const char *fp_name,
const CORBA::Any &fp_settings,
- CORBA::Environment &env = CORBA::Environment::default_environment ())
+ CORBA::Environment &env = CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException,
AVStreams::noSuchFlow,
AVStreams::FPError));
@@ -128,9 +197,6 @@ public:
// Not implemented in the light profile, will raise the notsupported
// exception
- virtual ~TAO_Basic_StreamCtrl (void);
- // Destructor
-
protected:
AVStreams::VDev_var vdev_a_;
@@ -141,8 +207,10 @@ protected:
AVStreams::StreamEndPoint_B_var sep_b_;
// The Endpoints for this stream
- typedef ACE_Hash_Map_Manager <TAO_String_Hash_Key,CORBA::Object_ptr,ACE_Null_Mutex> FlowConnection_Map;
- FlowConnection_Map flow_map_;
+ typedef ACE_Hash_Map_Manager <TAO_String_Hash_Key,AVStreams::FlowConnection_ptr,ACE_Null_Mutex> FlowConnection_Map;
+ typedef ACE_Hash_Map_Iterator <TAO_String_Hash_Key,AVStreams::FlowConnection_ptr,ACE_Null_Mutex> FlowConnection_Map_Iterator;
+ typedef ACE_Hash_Map_Entry <TAO_String_Hash_Key,AVStreams::FlowConnection_ptr> FlowConnection_Map_Entry;
+ FlowConnection_Map flow_connection_map_;
// Hash table for the flow names and its corresponding flowconnection object reference.
AVStreams::FlowConnection_seq flowConnections_;
@@ -158,30 +226,93 @@ class TAO_ORBSVCS_Export TAO_Negotiator
public:
virtual CORBA::Boolean negotiate (AVStreams::Negotiator_ptr remote_negotiator,
const AVStreams::streamQoS &qos_spec,
- CORBA::Environment &ACE_TRY_ENV = CORBA::Environment::default_environment ())
+ CORBA::Environment &ACE_TRY_ENV = CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException));
};
class TAO_MCastConfigIf;
+class MMDevice_Map_Hash_Key
+{
+public:
+ MMDevice_Map_Hash_Key (void);
+ // default constructor.
+
+ MMDevice_Map_Hash_Key (AVStreams::MMDevice_ptr mmdevice);
+ // constructor.
+
+ MMDevice_Map_Hash_Key (const MMDevice_Map_Hash_Key&);
+ // copy constructor.
+
+ ~MMDevice_Map_Hash_Key (void);
+ // destructor.
+
+ int operator == (const MMDevice_Map_Hash_Key &hash_key) const;
+ // operator== needed by ACE_Hash_Map_Manager.
+
+ friend int operator < (const MMDevice_Map_Hash_Key &left,
+ const MMDevice_Map_Hash_Key &right);
+ // operator== needed by ACE_Hash_Map_Manager.
+
+ u_long hash (void) const;
+ // hash function for this mmdevice.
+
+ static const int hash_maximum_;
+protected:
+ AVStreams::MMDevice_ptr mmdevice_;
+};
+
class TAO_ORBSVCS_Export TAO_StreamCtrl
: public virtual POA_AVStreams::StreamCtrl,
public virtual TAO_Basic_StreamCtrl,
public virtual PortableServer::RefCountServantBase
-// = DESCRIPTION
-// Implementation the A/V StreamCtrl class. this class
-// is used to control the stream. It should be subclassed
-// by applications that want to provide more control features.
{
+ // = DESCRIPTION
+ // Implementation the A/V StreamCtrl class. this class
+ // is used to control the stream. It should be subclassed
+ // by applications that want to provide more control features.
+
public:
+
TAO_StreamCtrl (void);
// Default Constructor
+ TAO_StreamCtrl (TAO_StreamCtrl const &);
+ // Copy Constructor to fool g++
+
+ virtual ~TAO_StreamCtrl (void);
+ // virtual destructor.
+
+ void operator= (TAO_StreamCtrl const &);
+ // Fooling g++
+
+ virtual void stop (const AVStreams::flowSpec &the_spec,
+ CORBA::Environment &env = CORBA::Environment::default_environment ())
+ ACE_THROW_SPEC ((CORBA::SystemException,
+ AVStreams::noSuchFlow));
+ // Stop the transfer of data of the stream
+ // Empty the_spec means apply operation to all flows
+
+ virtual void start (const AVStreams::flowSpec &the_spec,
+ CORBA::Environment &env = CORBA::Environment::default_environment ())
+ ACE_THROW_SPEC ((CORBA::SystemException,
+ AVStreams::noSuchFlow));
+ // Start the transfer of data in the stream.
+ // Empty the_spec means apply operation to all flows
+
+ virtual void destroy (const AVStreams::flowSpec &the_spec,
+ CORBA::Environment &env = CORBA::Environment::default_environment ())
+ ACE_THROW_SPEC ((CORBA::SystemException,
+ AVStreams::noSuchFlow));
+ // Tears down the stream. This will close the connection, and delete
+ // the streamendpoint and vdev associated with this stream
+ // Empty the_spec means apply operation to all flows
+
virtual CORBA::Boolean bind_devs (AVStreams::MMDevice_ptr a_party,
AVStreams::MMDevice_ptr b_party,
AVStreams::streamQoS &the_qos,
const AVStreams::flowSpec &the_flows,
- CORBA::Environment &env = CORBA::Environment::default_environment ())
+ CORBA::Environment &env = CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException,
AVStreams::streamOpFailed,
AVStreams::noSuchFlow,
@@ -207,7 +338,7 @@ public:
virtual void unbind_dev (AVStreams::MMDevice_ptr dev,
const AVStreams::flowSpec & the_spec,
- CORBA::Environment &ACE_TRY_ENV = CORBA::Environment::default_environment ())
+ CORBA::Environment &ACE_TRY_ENV = CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException,
AVStreams::streamOpFailed,
AVStreams::noSuchFlow));
@@ -220,7 +351,7 @@ public:
AVStreams::noSuchFlow));
// Unbind the_ep from the stream. Empty the_spec means apply to all flows.
- virtual void unbind (CORBA::Environment &env = CORBA::Environment::default_environment ())
+ virtual void unbind (CORBA::Environment &env = CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException,
AVStreams::streamOpFailed));
// unbind the stream. Same effect as Basic_StreamCtrl::destroy ()
@@ -233,19 +364,32 @@ public:
virtual CORBA::Boolean modify_QoS (AVStreams::streamQoS &new_qos,
const AVStreams::flowSpec &the_spec,
- CORBA::Environment &env = CORBA::Environment::default_environment ())
+ CORBA::Environment &env = CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException,
AVStreams::noSuchFlow,
AVStreams::QoSRequestFailed));
// Changes the QoS associated with the stream
// Empty the_spec means apply operation to all flows
- virtual ~TAO_StreamCtrl (void);
- // Destructor.
+protected:
+
+ struct MMDevice_Map_Entry
+ {
+ AVStreams::StreamEndPoint_var sep_;
+ AVStreams::VDev_var vdev_;
+ AVStreams::flowSpec flowspec_;
+ AVStreams::streamQoS qos_;
+ };
+
+ typedef ACE_Hash_Map_Manager <MMDevice_Map_Hash_Key,MMDevice_Map_Entry,ACE_Null_Mutex> MMDevice_Map;
+ typedef ACE_Hash_Map_Iterator <MMDevice_Map_Hash_Key,MMDevice_Map_Entry,ACE_Null_Mutex> MMDevice_Map_Iterator;
- protected:
+ MMDevice_Map mmdevice_a_map_;
+ MMDevice_Map mmdevice_b_map_;
TAO_MCastConfigIf *mcastconfigif_;
- AVStreams::MCastConfigIf_ptr mcastconfigif_ptr_;
+ AVStreams::MCastConfigIf_var mcastconfigif_ptr_;
+ AVStreams::StreamCtrl_var streamctrl_;
+ CORBA::ULong source_id_;
};
class TAO_ORBSVCS_Export TAO_MCastConfigIf
@@ -254,6 +398,23 @@ class TAO_ORBSVCS_Export TAO_MCastConfigIf
public virtual PortableServer::RefCountServantBase
{
public:
+
+ enum Peer_Interface {VDEV = 0, FLOWENDPOINT=1};
+ struct Peer_Info
+ {
+ AVStreams::VDev_var peer_;
+ AVStreams::FlowEndPoint_var fep_;
+ AVStreams::streamQoS qos_;
+ AVStreams::flowSpec flow_spec_;
+ Peer_Interface interface_;
+ };
+
+ TAO_MCastConfigIf (void);
+ // Default constructor.
+
+ ~TAO_MCastConfigIf (void);
+ // Dtor
+
virtual CORBA::Boolean set_peer (CORBA::Object_ptr peer,
AVStreams::streamQoS & the_qos,
const AVStreams::flowSpec & the_spec,
@@ -272,7 +433,7 @@ public:
virtual void set_format (const char * flowName,
const char * format_name,
- CORBA::Environment &ACE_TRY_ENV =
+ CORBA::Environment &ACE_TRY_ENV =
CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException,
AVStreams::notSupported));
@@ -280,64 +441,95 @@ public:
virtual void set_dev_params (const char * flowName,
const CosPropertyService::Properties & new_params,
CORBA::Environment &ACE_TRY_ENV = CORBA::Environment::default_environment ())
+
ACE_THROW_SPEC ((CORBA::SystemException,
AVStreams::PropertyException,
AVStreams::streamOpFailed));
-
+
protected:
+ int in_flowSpec (const AVStreams::flowSpec& flow_spec, const char *flow_name);
+ // checks whether the flowname is in the flow_spec.
+
ACE_SOCK_Dgram_Mcast sock_mcast_;
// Multicast socket.
+
+ CosPropertyService::Properties initial_configuration_;
+ // Initial configuration to be distributed to all B parties when they join.
+
+ ACE_DLList<Peer_Info> peer_list_;
+ ACE_DLList_Iterator<Peer_Info> peer_list_iterator_;
};
+// Forward declarations.
+class TAO_AV_TCP_Flow_Handler;
+class TAO_AV_UDP_Flow_Handler;
+class TAO_AV_UDP_MCast_Flow_Handler;
+class TAO_AV_Protocol_Object;
+class TAO_AV_Callback;
+class TAO_AV_SourceManager;
+class TAO_AV_Source;
+class TAO_AV_RTP_State;
+class TAO_AV_Flow_Handler;
+
class TAO_ORBSVCS_Export TAO_Base_StreamEndPoint
{
// = DESCRIPTION
// Base class for the A/V StreamEndPoint class. this class
// is used to control the stream. It should be subclassed
// by applications that want to provide more control features.
+
+ // @@Naga: Rename this class to TAO_Base_EndPoint since both stream and flowendpoints derive from it.
public:
+ TAO_Base_StreamEndPoint (void);
virtual ~TAO_Base_StreamEndPoint (void);
- virtual int handle_open (void) = 0;
+ virtual int handle_open (void);
// called when streamendpoint is instantiated
- virtual int handle_close (void) = 0;
+ virtual int handle_close (void);
// called when streamendpoint is being destructed
virtual int handle_stop (const AVStreams::flowSpec &the_spec,
- CORBA::Environment &env = CORBA::Environment::default_environment ()) = 0;
+ CORBA::Environment &env = CORBA::Environment::default_environment ());
// Application needs to define this
virtual int handle_start (const AVStreams::flowSpec &the_spec,
- CORBA::Environment &env = CORBA::Environment::default_environment ()) = 0;
+ CORBA::Environment &env = CORBA::Environment::default_environment ());
// Application needs to define this
-
virtual int handle_destroy (const AVStreams::flowSpec &the_spec,
- CORBA::Environment &env = CORBA::Environment::default_environment ()) = 0;
+ CORBA::Environment &env = CORBA::Environment::default_environment ());
// Application needs to define this
-};
-class TAO_ORBSVCS_Export TAO_Client_Base_StreamEndPoint
- : public virtual TAO_Base_StreamEndPoint
-{
-public:
- virtual CORBA::Boolean handle_preconnect (AVStreams::flowSpec &the_spec) = 0;
+ virtual CORBA::Boolean handle_preconnect (AVStreams::flowSpec &the_spec);
// Application needs to define this
- virtual CORBA::Boolean handle_postconnect (AVStreams::flowSpec &the_spec) = 0;
+ virtual CORBA::Boolean handle_postconnect (AVStreams::flowSpec &the_spec);
// Application needs to define this
-};
-class TAO_ORBSVCS_Export TAO_Server_Base_StreamEndPoint
- : public virtual TAO_Base_StreamEndPoint
-{
-public:
virtual CORBA::Boolean handle_connection_requested (AVStreams::flowSpec &the_spec,
- CORBA::Environment &env = CORBA::Environment::default_environment ()) = 0;
+ CORBA::Environment &env = CORBA::Environment::default_environment ());
// Application needs to define this
+
+ virtual int get_callback (const char *flowname,
+ TAO_AV_Callback *&callback);
+
+ virtual int get_control_callback (const char *flowname,
+ TAO_AV_Callback *&callback);
+
+ virtual int set_protocol_object (const char *flowname,
+ TAO_AV_Protocol_Object *object);
+
+ virtual void set_handler (const char *flowname,
+ TAO_AV_Flow_Handler *handler);
};
+// Forward declarations.
+class TAO_AV_Acceptor;
+class TAO_AV_Connector;
+class TAO_Forward_FlowSpec_Entry;
+class TAO_Reverse_FlowSpec_Entry;
+
class TAO_ORBSVCS_Export TAO_StreamEndPoint
: public virtual POA_AVStreams::StreamEndPoint,
public virtual TAO_Base_StreamEndPoint,
@@ -352,7 +544,7 @@ public:
// Constructor
virtual void stop (const AVStreams::flowSpec &the_spec,
- CORBA::Environment &env = CORBA::Environment::default_environment ())
+ CORBA::Environment &env = CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException,
AVStreams::noSuchFlow));
// Stop the stream. Empty the_spec means, for all the flows
@@ -372,18 +564,18 @@ public:
virtual CORBA::Boolean connect (AVStreams::StreamEndPoint_ptr responder,
AVStreams::streamQoS &qos_spec,
const AVStreams::flowSpec &the_spec,
- CORBA::Environment &env = CORBA::Environment::default_environment ())
+ CORBA::Environment &env = CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException,
AVStreams::noSuchFlow,
AVStreams::QoSRequestFailed,
- AVStreams::streamOpFailed)) = 0;
+ AVStreams::streamOpFailed));
// Called by StreamCtrl. responder is the peer to connect to
virtual CORBA::Boolean request_connection (AVStreams::StreamEndPoint_ptr initiator,
CORBA::Boolean is_mcast,
AVStreams::streamQoS &qos,
AVStreams::flowSpec &the_spec,
- CORBA::Environment &env = CORBA::Environment::default_environment ())
+ CORBA::Environment &env = CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException,
AVStreams::streamOpDenied,
AVStreams::noSuchFlow,
@@ -394,19 +586,19 @@ public:
virtual CORBA::Boolean modify_QoS (AVStreams::streamQoS &new_qos,
const AVStreams::flowSpec &the_flows,
- CORBA::Environment &env = CORBA::Environment::default_environment ())
+ CORBA::Environment &env = CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException,
AVStreams::noSuchFlow,
AVStreams::QoSRequestFailed));
// Change the transport qos on a stream
virtual CORBA::Boolean set_protocol_restriction (const AVStreams::protocolSpec &the_pspec,
- CORBA::Environment &env = CORBA::Environment::default_environment ())
+ CORBA::Environment &env = CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException));
// Used to restrict the set of protocols
virtual void disconnect (const AVStreams::flowSpec &the_spec,
- CORBA::Environment &env = CORBA::Environment::default_environment ())
+ CORBA::Environment &env = CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException,
AVStreams::noSuchFlow,
AVStreams::streamOpFailed));
@@ -415,21 +607,21 @@ public:
virtual void set_FPStatus (const AVStreams::flowSpec &the_spec,
const char *fp_name,
const CORBA::Any &fp_settings,
- CORBA::Environment &env = CORBA::Environment::default_environment ())
+ CORBA::Environment &env = CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException,
AVStreams::noSuchFlow,
AVStreams::FPError));
// Used to control the flow
virtual CORBA::Object_ptr get_fep (const char *flow_name,
- CORBA::Environment &env = CORBA::Environment::default_environment ())
+ CORBA::Environment &env = CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException,
AVStreams::notSupported,
AVStreams::noSuchFlow));
// Not implemented in the light profile, throws notsupported
virtual char * add_fep (CORBA::Object_ptr the_fep,
- CORBA::Environment &env = CORBA::Environment::default_environment ())
+ CORBA::Environment &env = CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException,
AVStreams::notSupported,
AVStreams::streamOpFailed));
@@ -443,141 +635,143 @@ public:
// Not implemented in the light profile, throws notsupported
virtual void set_negotiator (AVStreams::Negotiator_ptr new_negotiator,
- CORBA::Environment &env = CORBA::Environment::default_environment ())
+ CORBA::Environment &env = CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException));
// Used to "attach" a negotiator to the endpoint
virtual void set_key (const char *flow_name,
const AVStreams::key & the_key,
- CORBA::Environment &env = CORBA::Environment::default_environment ())
+ CORBA::Environment &env = CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException));
// Used for public key encryption.
virtual void set_source_id (CORBA::Long source_id,
- CORBA::Environment &env = CORBA::Environment::default_environment ())
+ CORBA::Environment &env = CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException));
// Used to set a unique id for packets sent by this streamendpoint
virtual ~TAO_StreamEndPoint (void);
// Destructor
-private:
+ CORBA::Boolean multiconnect (AVStreams::streamQoS &the_qos,
+ AVStreams::flowSpec &the_spec,
+ CORBA::Environment &ACE_TRY_ENV);
+protected:
+ int translate_qos (const AVStreams::streamQoS& application_qos,
+ AVStreams::streamQoS& network_qos);
+ // translate from application level to network level qos.
+
u_int flow_count_;
// Count of the number of flows in this streamendpoint, used to
// generate unique names for the flows.
+
u_int flow_num_;
// current flow number used for system generation of flow names.
- typedef ACE_Hash_Map_Manager <TAO_String_Hash_Key,CORBA::Object_ptr,ACE_Null_Mutex>
- FlowEndPoint_Map;
+
FlowEndPoint_Map fep_map_;
- // hash table for the flownames and its corresponding flowEndpoint
- // reference.
+ // hash table for the flownames and its corresponding flowEndpoint reference.
+
AVStreams::flowSpec flows_;
// sequence of supported flow names.
+
CORBA::Long source_id_;
// source id used for multicast.
+
+ AVStreams::Negotiator_var negotiator_;
+ // our local negotiator for QoS.
+
+ AVStreams::protocolSpec protocols_;
+ // Our available list of protocols.
+
+ CORBA::String_var protocol_;
+ // Chosen protocol for this streamendpoint based on availableprotocols property.
+
+ AVStreams::key key_;
+ // Key used for encryption.
+
+ u_short mcast_port_;
+ ACE_UINT32 mcast_addr_;
+ ACE_Hash_Map_Manager <TAO_String_Hash_Key, TAO_FlowSpec_Entry*,ACE_Null_Mutex> mcast_entry_map_;
+ TAO_AV_FlowSpecSet forward_flow_spec_set;
+ TAO_AV_FlowSpecSet reverse_flow_spec_set;
+ AVStreams::StreamEndPoint_var peer_sep_;
+ AVStreams::SFPStatus *sfp_status_;
+ AVStreams::StreamCtrl_var streamctrl_;
+// TAO_Forward_FlowSpec_Entry forward_entries_ [FLOWSPEC_MAX];
+// TAO_Reverse_FlowSpec_Entry reverse_entries_ [FLOWSPEC_MAX];
};
-class TAO_ORBSVCS_Export TAO_Client_StreamEndPoint :
+
+class TAO_ORBSVCS_Export TAO_StreamEndPoint_A :
public virtual POA_AVStreams::StreamEndPoint_A,
public virtual TAO_StreamEndPoint,
- public virtual TAO_Client_Base_StreamEndPoint,
public virtual PortableServer::RefCountServantBase
{
// = DESCRIPTION
// The "A" side of a streamendpoint
public:
- TAO_Client_StreamEndPoint (void);
+ TAO_StreamEndPoint_A (void);
// Constructor
- virtual CORBA::Boolean connect (AVStreams::StreamEndPoint_ptr responder,
- AVStreams::streamQoS &qos_spec,
- const AVStreams::flowSpec &the_spec,
- CORBA::Environment &env = CORBA::Environment::default_environment ())
- ACE_THROW_SPEC ((CORBA::SystemException,
- AVStreams::noSuchFlow,
- AVStreams::QoSRequestFailed,
- AVStreams::streamOpFailed));
- // Called by StreamCtrl. responder is the peer to connect to
-
virtual CORBA::Boolean multiconnect (AVStreams::streamQoS &the_qos,
AVStreams::flowSpec &the_spec,
- CORBA::Environment &env = CORBA::Environment::default_environment ())
+ CORBA::Environment &env = CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException,
- AVStreams::noSuchFlow,
- AVStreams::QoSRequestFailed,
+ AVStreams::noSuchFlow,
+ AVStreams::QoSRequestFailed,
AVStreams::streamOpFailed));
// Used for ATM-style multicast
virtual CORBA::Boolean connect_leaf (AVStreams::StreamEndPoint_B_ptr the_ep,
AVStreams::streamQoS &the_qos,
const AVStreams::flowSpec &the_flows,
- CORBA::Environment &env = CORBA::Environment::default_environment ())
+ CORBA::Environment &env = CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException,
- AVStreams::streamOpFailed,
+ AVStreams::streamOpFailed,
AVStreams::noSuchFlow,
- AVStreams::QoSRequestFailed,
+ AVStreams::QoSRequestFailed,
AVStreams::notSupported));
// Used for ATM-style multicast
virtual void disconnect_leaf (AVStreams::StreamEndPoint_B_ptr the_ep,
const AVStreams::flowSpec &theSpec,
- CORBA::Environment &env = CORBA::Environment::default_environment ())
+ CORBA::Environment &env = CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException,
- AVStreams::streamOpFailed,
+ AVStreams::streamOpFailed,
AVStreams::noSuchFlow));
// Used to remove a multicast leaf
- virtual ~TAO_Client_StreamEndPoint (void);
+ virtual ~TAO_StreamEndPoint_A (void);
// Destructor
};
-class TAO_ORBSVCS_Export TAO_Server_StreamEndPoint :
+// For backward compatibility.
+#define TAO_Client_StreamEndPoint TAO_StreamEndPoint_A
+#define TAO_Server_StreamEndPoint TAO_StreamEndPoint_B
+
+class TAO_ORBSVCS_Export TAO_StreamEndPoint_B :
public virtual POA_AVStreams::StreamEndPoint_B,
public virtual TAO_StreamEndPoint,
- public virtual TAO_Server_Base_StreamEndPoint,// Abstract interface
public virtual PortableServer::RefCountServantBase
{
// = DESCRIPTION
// The "B" side of a streamendpoint
public:
- TAO_Server_StreamEndPoint (void);
+ TAO_StreamEndPoint_B (void);
// Constructor
- virtual CORBA::Boolean connect (AVStreams::StreamEndPoint_ptr responder,
- AVStreams::streamQoS &qos_spec,
- const AVStreams::flowSpec &the_spec,
- CORBA::Environment &env = CORBA::Environment::default_environment ())
- ACE_THROW_SPEC ((CORBA::SystemException,
- AVStreams::noSuchFlow,
- AVStreams::QoSRequestFailed,
- AVStreams::streamOpFailed));
-
- virtual CORBA::Boolean request_connection (AVStreams::StreamEndPoint_ptr initiator,
- CORBA::Boolean is_mcast,
- AVStreams::streamQoS &qos,
- AVStreams::flowSpec &the_spec,
- CORBA::Environment &env = CORBA::Environment::default_environment ())
- ACE_THROW_SPEC ((CORBA::SystemException,
- AVStreams::streamOpDenied,
- AVStreams::noSuchFlow,
- AVStreams::QoSRequestFailed,
- AVStreams::FPError));
- // Called by the peer StreamEndPoint. The flow_spec indicates the
- // flows (which contain transport addresses etc.)
-
virtual CORBA::Boolean multiconnect (AVStreams::streamQoS &the_qos,
AVStreams::flowSpec &the_spec,
- CORBA::Environment &env = CORBA::Environment::default_environment ())
+ CORBA::Environment &env = CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException,
- AVStreams::streamOpFailed,
+ AVStreams::streamOpFailed,
AVStreams::noSuchFlow,
- AVStreams::QoSRequestFailed,
+ AVStreams::QoSRequestFailed,
AVStreams::FPError));
// Used for internet-style multicast
- virtual ~TAO_Server_StreamEndPoint (void);
+ virtual ~TAO_StreamEndPoint_B (void);
// Destructor
};
@@ -585,11 +779,11 @@ class TAO_ORBSVCS_Export TAO_VDev
:public virtual TAO_PropertySet,
public virtual POA_AVStreams::VDev,
public virtual PortableServer::RefCountServantBase
-// = DESCRIPTION
-// Implements the VDev interface. One of these is created per connection,
-// and represents device-specific parameters
{
- public:
+ // = DESCRIPTION
+ // Implements the VDev interface. One of these is created per connection,
+ // and represents device-specific parameters
+public:
TAO_VDev (void);
// Default Constructor
@@ -597,10 +791,10 @@ class TAO_ORBSVCS_Export TAO_VDev
AVStreams::VDev_ptr the_peer_dev,
AVStreams::streamQoS &the_qos,
const AVStreams::flowSpec &the_spec,
- CORBA::Environment &env = CORBA::Environment::default_environment ())
+ CORBA::Environment &env = CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException,
- AVStreams::noSuchFlow,
- AVStreams::QoSRequestFailed,
+ AVStreams::noSuchFlow,
+ AVStreams::QoSRequestFailed,
AVStreams::streamOpFailed));
// Called to tell the vdev who the streamctrl, peer vdev is
@@ -608,47 +802,47 @@ class TAO_ORBSVCS_Export TAO_VDev
AVStreams::MCastConfigIf_ptr a_mcastconfigif,
AVStreams::streamQoS &the_qos,
const AVStreams::flowSpec &the_spec,
- CORBA::Environment &env = CORBA::Environment::default_environment ())
+ CORBA::Environment &env = CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException,
- AVStreams::noSuchFlow,
- AVStreams::QoSRequestFailed,
+ AVStreams::noSuchFlow,
+ AVStreams::QoSRequestFailed,
AVStreams::streamOpFailed));
// Used to set the streamctrl and multicast device
virtual void configure (const CosPropertyService::Property &the_config_mesg,
- CORBA::Environment &env = CORBA::Environment::default_environment ())
+ CORBA::Environment &env = CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException,
- AVStreams::PropertyException,
+ AVStreams::PropertyException,
AVStreams::streamOpFailed));
// Called by the peer VDev to configure the device (catch all)
virtual void set_format (const char *flowName,
const char *format_name,
- CORBA::Environment &env = CORBA::Environment::default_environment ())
+ CORBA::Environment &env = CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException,
AVStreams::notSupported));
// Used to set a format on a flowname
virtual void set_dev_params (const char *flowName,
const CosPropertyService::Properties &new_params,
- CORBA::Environment &env = CORBA::Environment::default_environment ())
+ CORBA::Environment &env = CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException,
- AVStreams::PropertyException,
+ AVStreams::PropertyException,
AVStreams::streamOpFailed));
// Used to set device parameters
virtual CORBA::Boolean modify_QoS (AVStreams::streamQoS &the_qos,
const AVStreams::flowSpec &the_spec,
- CORBA::Environment &env = CORBA::Environment::default_environment ())
+ CORBA::Environment &env = CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException,
- AVStreams::noSuchFlow,
+ AVStreams::noSuchFlow,
AVStreams::QoSRequestFailed));
// Called to change QoS of the device
virtual ~TAO_VDev (void);
// Destructor
- protected:
+protected:
virtual CORBA::Boolean set_media_ctrl (CORBA::Object_ptr media_ctrl,
CORBA::Environment &env = CORBA::Environment::default_environment ());
// hook called after set_peer is done to set the media ctrl of the peer vdev.
@@ -658,6 +852,9 @@ class TAO_ORBSVCS_Export TAO_VDev
AVStreams::VDev_var peer_;
// My peer
+
+ AVStreams::MCastConfigIf_var mcast_peer_;
+ // The multicast VDev peer.
};
class TAO_AV_Endpoint_Strategy;
@@ -666,26 +863,36 @@ class TAO_ORBSVCS_Export TAO_MMDevice
:public virtual POA_AVStreams::MMDevice,
public TAO_PropertySet,
public virtual PortableServer::RefCountServantBase
-// = DESCRIPTION
-// Implements a factory to create Endpoints and VDevs
{
- protected:
-
- TAO_AV_Endpoint_Strategy *endpoint_strategy_;
+ // = DESCRIPTION
+ // Implements a factory to create Endpoints and VDevs
- public:
+public:
+ enum MMDevice_Type {MMDEVICE_A = 0,MMDEVICE_B = 1};
TAO_MMDevice (TAO_AV_Endpoint_Strategy *endpoint_strategy_);
// Constructor
+ TAO_MMDevice (TAO_MMDevice const &);
+ // Copy constructor to fool g++
+
+ virtual AVStreams::StreamEndPoint_ptr create_A_B (MMDevice_Type type,
+ AVStreams::StreamCtrl_ptr the_requester,
+ AVStreams::VDev_out the_vdev,
+ AVStreams::streamQoS &the_qos,
+ CORBA::Boolean_out met_qos,
+ char *&named_vdev,
+ const AVStreams::flowSpec &the_spec,
+ CORBA::Environment &env = CORBA::Environment::default_environment ());
+
virtual AVStreams::StreamCtrl_ptr bind (AVStreams::MMDevice_ptr peer_device,
AVStreams::streamQoS &the_qos,
CORBA::Boolean_out is_met,
const AVStreams::flowSpec &the_spec,
- CORBA::Environment &env = CORBA::Environment::default_environment ())
+ CORBA::Environment &env = CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException,
- AVStreams::streamOpFailed,
- AVStreams::noSuchFlow,
+ AVStreams::streamOpFailed,
+ AVStreams::noSuchFlow,
AVStreams::QoSRequestFailed));
// Can be used to request the MMDevice to create a new StreamCtrl,
// and call bind_devs on it
@@ -694,10 +901,10 @@ class TAO_ORBSVCS_Export TAO_MMDevice
AVStreams::streamQoS &the_qos,
CORBA::Boolean_out is_met,
const AVStreams::flowSpec &the_spec,
- CORBA::Environment &env = CORBA::Environment::default_environment ())
+ CORBA::Environment &env = CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException,
- AVStreams::streamOpFailed,
- AVStreams::noSuchFlow,
+ AVStreams::streamOpFailed,
+ AVStreams::noSuchFlow,
AVStreams::QoSRequestFailed));
// Multicast bind
@@ -707,12 +914,12 @@ class TAO_ORBSVCS_Export TAO_MMDevice
CORBA::Boolean_out met_qos,
char *&named_vdev,
const AVStreams::flowSpec &the_spec,
- CORBA::Environment &env = CORBA::Environment::default_environment ())
+ CORBA::Environment &env = CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException,
- AVStreams::streamOpFailed,
- AVStreams::streamOpDenied,
+ AVStreams::streamOpFailed,
+ AVStreams::streamOpDenied,
AVStreams::notSupported,
- AVStreams::QoSRequestFailed,
+ AVStreams::QoSRequestFailed,
AVStreams::noSuchFlow));
// Called by StreamCtrl to create a "A" type streamandpoint and vdev
@@ -722,59 +929,69 @@ class TAO_ORBSVCS_Export TAO_MMDevice
CORBA::Boolean_out met_qos,
char *&named_vdev,
const AVStreams::flowSpec &the_spec,
- CORBA::Environment &env = CORBA::Environment::default_environment ())
+ CORBA::Environment &env = CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException,
- AVStreams::streamOpFailed,
- AVStreams::streamOpDenied,
+ AVStreams::streamOpFailed,
+ AVStreams::streamOpDenied,
AVStreams::notSupported,
- AVStreams::QoSRequestFailed,
+ AVStreams::QoSRequestFailed,
AVStreams::noSuchFlow));
// Called by StreamCtrl to create a "B" type streamandpoint and vdev
virtual void destroy (AVStreams::StreamEndPoint_ptr the_ep,
const char *vdev_name,
- CORBA::Environment &env = CORBA::Environment::default_environment ())
+ CORBA::Environment &env = CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException,
AVStreams::notSupported));
// Remove the StreamEndPoint and the related vdev
virtual char * add_fdev (CORBA::Object_ptr the_fdev,
- CORBA::Environment &env = CORBA::Environment::default_environment ())
+ CORBA::Environment &env = CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException,
- AVStreams::notSupported,
+ AVStreams::notSupported,
AVStreams::streamOpFailed));
// Not supported in the light profile, raises notsupported
virtual CORBA::Object_ptr get_fdev (const char *flow_name,
- CORBA::Environment &env = CORBA::Environment::default_environment ())
+ CORBA::Environment &env = CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException,
- AVStreams::notSupported,
+ AVStreams::notSupported,
AVStreams::noSuchFlow));
// Not supported in the light profile, raises notsupported
virtual void remove_fdev (const char *flow_name,
CORBA::Environment &env = CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException,
- AVStreams::notSupported,
+ AVStreams::notSupported,
AVStreams::noSuchFlow));
// Not supported in the light profile, raises notsupported
virtual ~TAO_MMDevice (void);
// Destructor
- protected:
+protected:
+
+ TAO_AV_Endpoint_Strategy *endpoint_strategy_;
+
u_int flow_count_;
// Count of the number of flows in this MMDevice , used to
// generate unique names for the flows.
+
u_int flow_num_;
// current flow number used for system generation of flow names.
- typedef ACE_Hash_Map_Manager <TAO_String_Hash_Key,CORBA::Object_ptr,ACE_Null_Mutex>
- FDev_Map;
+
+ typedef ACE_Hash_Map_Manager <TAO_String_Hash_Key,AVStreams::FDev_ptr,ACE_Null_Mutex> FDev_Map;
+ typedef ACE_Hash_Map_Iterator <TAO_String_Hash_Key,AVStreams::FDev_ptr,ACE_Null_Mutex> FDev_Map_Iterator;
+ typedef ACE_Hash_Map_Entry <TAO_String_Hash_Key,AVStreams::FDev_ptr> FDev_Map_Entry;
+
FDev_Map fdev_map_;
// hash table for the flownames and its corresponding flowEndpoint
// reference.
+
AVStreams::flowSpec flows_;
// sequence of supported flow names.
+
+ TAO_StreamCtrl *stream_ctrl_;
};
class TAO_FlowConsumer;
@@ -795,34 +1012,34 @@ public:
TAO_FlowConnection (void);
// default constructor.
- virtual void stop (CORBA::Environment &env = CORBA::Environment::default_environment ())
+ virtual void stop (CORBA::Environment &env = CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException));
// stop this flow.
- virtual void start (CORBA::Environment &env = CORBA::Environment::default_environment ())
+ virtual void start (CORBA::Environment &env = CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException));
// start this flow.
- virtual void destroy (CORBA::Environment &env = CORBA::Environment::default_environment ())
+ virtual void destroy (CORBA::Environment &env = CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException));
// destroy this flow.
virtual CORBA::Boolean modify_QoS (AVStreams::QoS & new_qos,
- CORBA::Environment &env = CORBA::Environment::default_environment ())
+ CORBA::Environment &env = CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException,
AVStreams::QoSRequestFailed));
// modify the QoS for this flow.
virtual CORBA::Boolean use_flow_protocol (const char * fp_name,
const CORBA::Any & fp_settings,
- CORBA::Environment &env = CORBA::Environment::default_environment ())
+ CORBA::Environment &env = CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException,
- AVStreams::FPError,
+ AVStreams::FPError,
AVStreams::notSupported));
// use the specified flow protocol for this flow.
virtual void push_event (const AVStreams::streamEvent & the_event,
- CORBA::Environment &env = CORBA::Environment::default_environment ())
+ CORBA::Environment &env = CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException));
// pushes an event , to be handled by the application.
@@ -830,35 +1047,35 @@ public:
virtual CORBA::Boolean connect_devs (AVStreams::FDev_ptr a_party,
AVStreams::FDev_ptr b_party,
AVStreams::QoS & the_qos,
- CORBA::Environment &env = CORBA::Environment::default_environment ())
+ CORBA::Environment &env = CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException,
- AVStreams::streamOpFailed,
- AVStreams::streamOpDenied,
+ AVStreams::streamOpFailed,
+ AVStreams::streamOpDenied,
AVStreams::QoSRequestFailed));
// connect 2 Flow Devices.
-
+
virtual CORBA::Boolean connect (AVStreams::FlowProducer_ptr flow_producer,
AVStreams::FlowConsumer_ptr flow_consumer,
AVStreams::QoS & the_qos,
- CORBA::Environment &env = CORBA::Environment::default_environment ())
+ CORBA::Environment &env = CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException,
- AVStreams::formatMismatch,
- AVStreams::FEPMismatch,
+ AVStreams::formatMismatch,
+ AVStreams::FEPMismatch,
AVStreams::alreadyConnected));
// Connect a flow producer and consumer under this flow connection.
- virtual CORBA::Boolean disconnect (CORBA::Environment &env = CORBA::Environment::default_environment ())
+ virtual CORBA::Boolean disconnect (CORBA::Environment &env = CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException));
// disconnect this flow connection.
virtual CORBA::Boolean add_producer (AVStreams::FlowProducer_ptr flow_producer,
AVStreams::QoS & the_qos,
- CORBA::Environment &env = CORBA::Environment::default_environment ())
+ CORBA::Environment &env = CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException,
AVStreams::alreadyConnected,
AVStreams::notSupported));
// adds the producer to this flow connection.
-
+
virtual CORBA::Boolean add_consumer (AVStreams::FlowConsumer_ptr flow_consumer,
AVStreams::QoS & the_qos,
CORBA::Environment &env = CORBA::Environment::default_environment ())
@@ -867,85 +1084,108 @@ public:
// adds a consumer to this flow connection.
virtual CORBA::Boolean drop (AVStreams::FlowEndPoint_ptr target,
- CORBA::Environment &env = CORBA::Environment::default_environment ())
+ CORBA::Environment &env = CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException,
AVStreams::notConnected));
// drops a flow endpoint from the flow.
+ int set_mcast_addr (ACE_UINT32 addr,u_short port);
+ void set_protocol (const char *protocol);
protected:
- AVStreams::FlowProducer *producer_;
- // The producer of this flow.
- AVStreams::FlowConsumer *consumer_;
- // The consumer of this flow
- char * fp_name_;
- // name of the flow protocol to be used.
+ typedef ACE_Unbounded_Set<AVStreams::FlowProducer_ptr> FlowProducer_Set;
+ typedef ACE_Unbounded_Set_Iterator<AVStreams::FlowProducer_ptr> FlowProducer_SetItor;
+ typedef ACE_Unbounded_Set<AVStreams::FlowConsumer_ptr> FlowConsumer_Set;
+ typedef ACE_Unbounded_Set_Iterator<AVStreams::FlowConsumer_ptr> FlowConsumer_SetItor;
+
+ FlowProducer_Set flow_producer_set_;
+ FlowConsumer_Set flow_consumer_set_;
+ CORBA::String_var fp_name_;
+ CORBA::Any fp_settings_;
+ CORBA::String_var producer_address_;
+ // The multicast address returned by the producer.
+
+ int ip_multicast_;
+ // IP Multicasting is used.
+ TAO_MCastConfigIf *mcastconfigif_i_;
+ AVStreams::MCastConfigIf_var mcastconfigif_;
+ u_short mcast_port_;
+ ACE_UINT32 mcast_addr_;
+ CORBA::String_var protocol_;
};
class TAO_ORBSVCS_Export TAO_FlowEndPoint :
public virtual POA_AVStreams::FlowEndPoint,
public virtual TAO_PropertySet,
- public virtual PortableServer::RefCountServantBase
+ public virtual PortableServer::RefCountServantBase,
+ public virtual TAO_Base_StreamEndPoint
{
// = DESCRIPTION
// This class is used per flow e.g video flow and an audio flow
- // to encapuslate the transport details.
+ // to encapuslate the transport details.
- public:
+public:
TAO_FlowEndPoint (void);
//default constructor.
+ TAO_FlowEndPoint (const char *flowname,
+ AVStreams::protocolSpec &protocols,
+ const char *format);
+
+ int open (const char *flowname,
+ AVStreams::protocolSpec &protocols,
+ const char *format);
+
+ int set_flowname (const char *flowname);
+
+ virtual void set_handler (const char *flowname,
+ TAO_AV_Flow_Handler *handler);
+
+ virtual int set_protocol_object (const char *flowname,
+ TAO_AV_Protocol_Object *object);
+
virtual CORBA::Boolean lock (CORBA::Environment &env =
- CORBA::Environment::default_environment ())
+ CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException));
// lock the flow endpoint for a particular flow.
virtual void unlock (CORBA::Environment &env =
- CORBA::Environment::default_environment ())
+ CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException));
// unlock the flow endpoint for subsequent use.
- virtual void stop (CORBA::Environment &env =
- CORBA::Environment::default_environment ())
- ACE_THROW_SPEC ((CORBA::SystemException));
- // stop this flow, to be overridden by the application.
-
- virtual void start (CORBA::Environment &env =
- CORBA::Environment::default_environment ())
- ACE_THROW_SPEC ((CORBA::SystemException));
- // start this flow, to be overridden by the application.
virtual void destroy (CORBA::Environment &env =
- CORBA::Environment::default_environment ())
+ CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException));
// destroy this flow.
- virtual AVStreams::StreamEndPoint_ptr related_sep(CORBA::Environment &env =
- CORBA::Environment::default_environment ())
+ virtual AVStreams::StreamEndPoint_ptr related_sep(CORBA::Environment &env =
+ CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException));
// get method for the related streamendpoint under which this
// flowendpoint is.
virtual void related_sep (AVStreams::StreamEndPoint_ptr related_sep,
- CORBA::Environment &env =
- CORBA::Environment::default_environment ())
+ CORBA::Environment &env =
+ CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException));
// set method for the related streamendpoint under which this
// flowendpoint is.
- virtual AVStreams::FlowConnection_ptr related_flow_connection(CORBA::Environment &env =
- CORBA::Environment::default_environment ())
+ virtual AVStreams::FlowConnection_ptr related_flow_connection(CORBA::Environment &env =
+ CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException));
// accessor for the related flow connection attribute.
virtual void related_flow_connection (AVStreams::FlowConnection_ptr related_flow_connection,
- CORBA::Environment &env = CORBA::Environment::default_environment ())
+ CORBA::Environment &env = CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException));
// set method for the related flow connection attribute.
- virtual AVStreams::FlowEndPoint_ptr get_connected_fep (CORBA::Environment &env =
- CORBA::Environment::default_environment ())
+ virtual AVStreams::FlowEndPoint_ptr get_connected_fep (CORBA::Environment &env =
+ CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException,
AVStreams::notConnected,
AVStreams::notSupported));
@@ -953,42 +1193,42 @@ class TAO_ORBSVCS_Export TAO_FlowEndPoint :
virtual CORBA::Boolean use_flow_protocol (const char * fp_name,
const CORBA::Any & fp_settings,
- CORBA::Environment &env = CORBA::Environment::default_environment ())
+ CORBA::Environment &env = CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException,
- AVStreams::FPError,
+ AVStreams::FPError,
AVStreams::notSupported));
/// use the specified flow protocol.
virtual void set_format (const char * format,
- CORBA::Environment &env = CORBA::Environment::default_environment ())
+ CORBA::Environment &env = CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException,
AVStreams::notSupported));
// sets the data format.
virtual void set_dev_params (const CosPropertyService::Properties & new_settings,
- CORBA::Environment &env = CORBA::Environment::default_environment ())
+ CORBA::Environment &env = CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException,
- AVStreams::PropertyException,
+ AVStreams::PropertyException,
AVStreams::streamOpFailed));
// sets the device parameters.
virtual void set_protocol_restriction (const AVStreams::protocolSpec & the_spec,
- CORBA::Environment &env = CORBA::Environment::default_environment ())
+ CORBA::Environment &env = CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException,
AVStreams::notSupported));
// sets the list of protocols to be used.
virtual CORBA::Boolean is_fep_compatible (AVStreams::FlowEndPoint_ptr fep,
- CORBA::Environment &env = CORBA::Environment::default_environment ())
+ CORBA::Environment &env = CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException,
- AVStreams::formatMismatch,
+ AVStreams::formatMismatch,
AVStreams::deviceQosMismatch));
// checks whether the passed flowendpoint is compatible with this.
virtual CORBA::Boolean set_peer (AVStreams::FlowConnection_ptr the_fc,
AVStreams::FlowEndPoint_ptr the_peer_fep,
AVStreams::QoS & the_qos,
- CORBA::Environment &env = CORBA::Environment::default_environment ())
+ CORBA::Environment &env = CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException,
AVStreams::QoSRequestFailed,
AVStreams::streamOpFailed));
@@ -998,7 +1238,7 @@ class TAO_ORBSVCS_Export TAO_FlowEndPoint :
AVStreams::MCastConfigIf_ptr a_mcastconfigif,
AVStreams::QoS & the_qos,
CORBA::Environment &env =
- CORBA::Environment::default_environment ())
+ CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException,
AVStreams::QoSRequestFailed));
// sets the multicast peer flowendpoint, not implemented.
@@ -1008,47 +1248,82 @@ class TAO_ORBSVCS_Export TAO_FlowEndPoint :
const char * address,
const char * use_flow_protocol,
CORBA::Environment &env =
- CORBA::Environment::default_environment ())
+ CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException,
AVStreams::failedToConnect,
- AVStreams::FPError,
+ AVStreams::FPError,
+ AVStreams::QoSRequestFailed)) = 0;
+ // This should be implemented in both the FlowProducer and consumer and hence is
+ // pure virtual since we need to know the role of the flowendpoint to create appropriate
+ // protocol objects. eg. in SFP to create Producer Object/ Consumer Object.
+
+ virtual CORBA::Boolean connect_to_peer_i (TAO_FlowSpec_Entry::Role role,
+ AVStreams::QoS & the_qos,
+ const char * address,
+ const char * use_flow_protocol,
+ CORBA::Environment &env =
+ CORBA::Environment::default_environment ())
+ ACE_THROW_SPEC ((CORBA::SystemException,
+ AVStreams::failedToConnect,
+ AVStreams::FPError,
AVStreams::QoSRequestFailed));
// connect to the peer endpoint.
- virtual CORBA::Boolean handle_connect_to_peer (AVStreams::QoS & the_qos,
- const char * address,
- const char * use_flow_protocol,
- CORBA::Environment &env =
- CORBA::Environment::default_environment ());
- // hook method to be overridden by the application to handle the connection request.
-
virtual char * go_to_listen (AVStreams::QoS & the_qos,
CORBA::Boolean is_mcast,
- AVStreams::FlowProducer_ptr peer,
+ AVStreams::FlowEndPoint_ptr peer,
char *& flowProtocol,
CORBA::Environment &env =
- CORBA::Environment::default_environment ())
+ CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException,
- AVStreams::failedToListen,
- AVStreams::FPError,
+ AVStreams::failedToListen,
+ AVStreams::FPError,
+ AVStreams::QoSRequestFailed)) = 0;
+ // This should be implemented in both the FlowProducer and consumer and hence is
+ // pure virtual since we need to know the role of the flowendpoint to create appropriate
+ // protocol objects. eg. in SFP to create Producer Object/ Consumer Object.
+
+ virtual char * go_to_listen_i (TAO_FlowSpec_Entry::Role role,
+ AVStreams::QoS & the_qos,
+ CORBA::Boolean is_mcast,
+ AVStreams::FlowEndPoint_ptr peer,
+ char *& flowProtocol,
+ CORBA::Environment &env =
+ CORBA::Environment::default_environment ())
+ ACE_THROW_SPEC ((CORBA::SystemException,
+ AVStreams::failedToListen,
+ AVStreams::FPError,
AVStreams::QoSRequestFailed));
// listen request from the peer.
- virtual char * handle_go_to_listen (AVStreams::QoS & the_qos,
- CORBA::Boolean is_mcast,
- AVStreams::FlowProducer_ptr peer,
- char *& flowProtocol,
- CORBA::Environment &env = CORBA::Environment::default_environment ());
- // applications should override this method.
-
protected:
- AVStreams::StreamEndPoint_ptr related_sep_;
+ AVStreams::StreamEndPoint_var related_sep_;
// The related streamendpoint.
- AVStreams::FlowConnection_ptr related_flow_connection_;
+
+ AVStreams::FlowConnection_var related_flow_connection_;
// The related flow connection reference
- AVStreams::FlowEndPoint_ptr peer_fep_;
+
+ AVStreams::FlowEndPoint_var peer_fep_;
// The peer flowendpoint reference.
+
+ AVStreams::protocolSpec protocols_;
+ // Available protocols for this flowendpoint.
+
+ AVStreams::protocolSpec protocol_addresses_;
+ // Address information for the protocols.
+
+ AVStreams::MCastConfigIf_var mcast_peer_;
+ // The multicast peer endpoint.
+
+ CORBA::Boolean lock_;
+ // Lock.
+
+ CORBA::String_var format_;
+ CORBA::String_var flowname_;
+ CosPropertyService::Properties dev_params_;
+ TAO_AV_FlowSpecSet flow_spec_set_;
+ CORBA::String_var reverse_channel_;
};
class TAO_ORBSVCS_Export TAO_FlowProducer:
@@ -1056,15 +1331,59 @@ class TAO_ORBSVCS_Export TAO_FlowProducer:
public virtual TAO_FlowEndPoint,
public virtual PortableServer::RefCountServantBase
{
- public:
+public:
TAO_FlowProducer (void);
// default constructor
+ TAO_FlowProducer (const char *flowname,
+ AVStreams::protocolSpec protocols,
+ const char *format);
+
+ virtual char * get_rev_channel (const char * pcol_name,
+ CORBA::Environment &env = CORBA::Environment::default_environment ())
+ ACE_THROW_SPEC ((CORBA::SystemException));
+ // get the reverse channel, to be used for feedback for protocols like UDP.
+ // @@Naga: In the spec this is defined in the TAO_FlowProducer but it seems more reasonable for this
+ // to be in a FlowEndPoint since any of the flowendpoints can be made to listen. So in the case of
+ // UDP if the producer is listening and the consumer connects (logically) then the producer needs to
+ // know the reverse channel on its peer fep to send data to.
+
+ virtual void stop (CORBA::Environment &env =
+ CORBA::Environment::default_environment ())
+ ACE_THROW_SPEC ((CORBA::SystemException));
+ // stop this flow, to be overridden by the application.
+
+ virtual void start (CORBA::Environment &env =
+ CORBA::Environment::default_environment ())
+ ACE_THROW_SPEC ((CORBA::SystemException));
+ // start this flow, to be overridden by the application.
+
+ virtual char * go_to_listen (AVStreams::QoS & the_qos,
+ CORBA::Boolean is_mcast,
+ AVStreams::FlowEndPoint_ptr peer,
+ char *& flowProtocol,
+ CORBA::Environment &env =
+ CORBA::Environment::default_environment ())
+ ACE_THROW_SPEC ((CORBA::SystemException,
+ AVStreams::failedToListen,
+ AVStreams::FPError,
+ AVStreams::QoSRequestFailed));
+
+ virtual CORBA::Boolean connect_to_peer (AVStreams::QoS & the_qos,
+ const char * address,
+ const char * use_flow_protocol,
+ CORBA::Environment &env =
+ CORBA::Environment::default_environment ())
+ ACE_THROW_SPEC ((CORBA::SystemException,
+ AVStreams::failedToConnect,
+ AVStreams::FPError,
+ AVStreams::QoSRequestFailed));
+
virtual char * connect_mcast (AVStreams::QoS & the_qos,
CORBA::Boolean_out is_met,
const char * address,
const char * use_flow_protocol,
- CORBA::Environment &env = CORBA::Environment::default_environment ())
+ CORBA::Environment &env = CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException,
AVStreams::failedToConnect,
AVStreams::notSupported,
@@ -1073,18 +1392,14 @@ class TAO_ORBSVCS_Export TAO_FlowProducer:
// connect to the multicast address, not implemented.
- virtual char * get_rev_channel (const char * pcol_name,
- CORBA::Environment &env = CORBA::Environment::default_environment ())
- ACE_THROW_SPEC ((CORBA::SystemException));
- // get the reverse channel, to be used for feedback for protocols like UDP.
virtual void set_key (const AVStreams::key & the_key,
- CORBA::Environment &env = CORBA::Environment::default_environment ())
+ CORBA::Environment &env = CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException));
// sets the public key to be used for encryption of the data.
virtual void set_source_id (CORBA::Long source_id,
- CORBA::Environment &env =CORBA::Environment::default_environment())
+ CORBA::Environment &env =CORBA::Environment::default_environment())
ACE_THROW_SPEC ((CORBA::SystemException));
// sets the source id of this flow producer so that it can be used
// to distinguish this producer from others in the multicast case.
@@ -1092,6 +1407,7 @@ class TAO_ORBSVCS_Export TAO_FlowProducer:
protected:
CORBA::Long source_id_;
// source id of this producer.
+ CORBA::String_var peer_address_;
};
class TAO_ORBSVCS_Export TAO_FlowConsumer :
@@ -1099,94 +1415,47 @@ class TAO_ORBSVCS_Export TAO_FlowConsumer :
public virtual TAO_FlowEndPoint,
public virtual PortableServer::RefCountServantBase
{
- public:
+public:
TAO_FlowConsumer (void);
// default constructor.
+ TAO_FlowConsumer (const char *flowname,
+ AVStreams::protocolSpec protocols,
+ const char *format);
-};
-
-class TAO_ORBSVCS_Export TAO_FDev :
- public virtual POA_AVStreams::FDev,
- public virtual TAO_PropertySet,
- public virtual PortableServer::RefCountServantBase
-{
- public:
- TAO_FDev (void);
- // default constructor
-
- AVStreams::FlowProducer_ptr create_producer (AVStreams::FlowConnection_ptr the_requester,
- AVStreams::QoS & the_qos,
- CORBA::Boolean_out met_qos,
- char *& named_fdev,
- CORBA::Environment &env = CORBA::Environment::default_environment ())
- ACE_THROW_SPEC ((CORBA::SystemException,
- AVStreams::streamOpFailed,
- AVStreams::streamOpDenied,
- AVStreams::notSupported,
- AVStreams::QoSRequestFailed));
- // create a flow producer object.
-
- virtual AVStreams::FlowProducer_ptr make_producer (AVStreams::FlowConnection_ptr the_requester,
- AVStreams::QoS & the_qos,
- CORBA::Boolean_out met_qos,
- char *& named_fdev,
- CORBA::Environment &env = CORBA::Environment::default_environment ());
- // bridge method for the application to override the producer object
- // creation. Default implementation creates a TAO_FlowProducer.
-
- virtual AVStreams::FlowConsumer_ptr create_consumer (AVStreams::FlowConnection_ptr the_requester,
- AVStreams::QoS & the_qos,
- CORBA::Boolean_out met_qos,
- char *& named_fdev,
- CORBA::Environment &env = CORBA::Environment::default_environment ())
- ACE_THROW_SPEC ((CORBA::SystemException,
- AVStreams::streamOpFailed,
- AVStreams::streamOpDenied,
- AVStreams::notSupported,
- AVStreams::QoSRequestFailed));
- // create a flow consumer object.
+ virtual void stop (CORBA::Environment &env =
+ CORBA::Environment::default_environment ())
+ ACE_THROW_SPEC ((CORBA::SystemException));
+ // stop this flow, to be overridden by the application.
- virtual AVStreams::FlowConsumer_ptr make_consumer (AVStreams::FlowConnection_ptr the_requester,
- AVStreams::QoS & the_qos,
- CORBA::Boolean_out met_qos,
- char *& named_fdev,
- CORBA::Environment &env = CORBA::Environment::default_environment ());
- // bridge method for the application to override the consumer object
- // creation. Default implementation creates a TAO_FlowConsumer.
+ virtual void start (CORBA::Environment &env =
+ CORBA::Environment::default_environment ())
+ ACE_THROW_SPEC ((CORBA::SystemException));
+ // start this flow, to be overridden by the application.
- virtual AVStreams::FlowConnection_ptr bind (AVStreams::FDev_ptr peer_device,
- AVStreams::QoS & the_qos,
- CORBA::Boolean_out is_met,
- CORBA::Environment &env = CORBA::Environment::default_environment ())
+ virtual char * go_to_listen (AVStreams::QoS & the_qos,
+ CORBA::Boolean is_mcast,
+ AVStreams::FlowEndPoint_ptr peer,
+ char *& flowProtocol,
+ CORBA::Environment &env =
+ CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException,
- AVStreams::streamOpFailed,
+ AVStreams::failedToListen,
+ AVStreams::FPError,
AVStreams::QoSRequestFailed));
- // bind this FDev with another FDev.
- virtual AVStreams::FlowConnection_ptr bind_mcast (AVStreams::FDev_ptr first_peer,
- AVStreams::QoS & the_qos,
- CORBA::Boolean_out is_met,
- CORBA::Environment &env = CORBA::Environment::default_environment ())
+ virtual CORBA::Boolean connect_to_peer (AVStreams::QoS & the_qos,
+ const char * address,
+ const char * use_flow_protocol,
+ CORBA::Environment &env =
+ CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException,
- AVStreams::streamOpFailed,
+ AVStreams::failedToConnect,
+ AVStreams::FPError,
AVStreams::QoSRequestFailed));
- // multicast bind is not implemented yet.
-
- virtual void destroy (AVStreams::FlowEndPoint_ptr the_ep,
- const char * fdev_name,
- CORBA::Environment &env =
- CORBA::Environment::default_environment ())
- ACE_THROW_SPEC ((CORBA::SystemException,
- AVStreams::notSupported));
- // destroys this FDev.
-
-protected:
- AVStreams::FlowProducer_ptr producer_;
- AVStreams::FlowConsumer_ptr consumer_;
- // references to the created producers and consumers.
};
+
class TAO_ORBSVCS_Export TAO_MediaControl
:public virtual POA_AVStreams::MediaControl,
public virtual PortableServer::RefCountServantBase
@@ -1197,13 +1466,13 @@ class TAO_ORBSVCS_Export TAO_MediaControl
// = DESCRIPTION
// The following are to be handled by the specialized media control for the specific
// media like camera,speaker.
- public:
+public:
TAO_MediaControl (void);
// default constructor
virtual AVStreams::Position get_media_position (AVStreams::PositionOrigin an_origin,
AVStreams::PositionKey a_key,
- CORBA::Environment &env = CORBA::Environment::default_environment ())
+ CORBA::Environment &env = CORBA::Environment::default_environment ())
ACE_THROW_SPEC ((CORBA::SystemException,
AVStreams::MediaControl::PostionKeyNotSupported)) =0;
@@ -1235,127 +1504,38 @@ class TAO_ORBSVCS_Export TAO_MediaControl
};
-class TAO_ORBSVCS_Export TAO_Tokenizer
+class TAO_ORBSVCS_Export TAO_AV_QoS
{
public:
- TAO_Tokenizer (char *string,char delimiter);
+ TAO_AV_QoS (void);
// constructor.
- int parse (char *string,char delimiter);
- // parses the string and tokenizes it.
+ TAO_AV_QoS (AVStreams::streamQoS &stream_qos);
+ // constructor taking a stream qos parameter.
- char *token (void);
- // Returns the next token.
-
- int num_tokens (void);
- // Number of tokens.
-
- char *operator [] (size_t index) const;
-
-protected:
- ACE_Array<char*> token_array_;
- size_t count_;
- size_t num_tokens_;
-};
+ int set (AVStreams::streamQoS &stream_qos);
+ // sets the maps with the QoS paramter.
-class TAO_ORBSVCS_Export TAO_FlowSpec_Entry
-{
-public:
- // = TITLE
- // An helper entry class in the flow spec sequence passed to bind_devs.
- enum Direction
- {
- TAO_AV_INVALID = -1,
- TAO_AV_DIR_IN = 0,
- TAO_AV_DIR_OUT = 1,
- TAO_AV_DIR_INOUT = 2};
+ int get_flow_qos (const char *flowname,AVStreams::QoS &flow_qos);
+ // gets the flow_qos.
- TAO_FlowSpec_Entry (void);
- // constructor.
+ int convert (AVStreams::streamQoS &network_qos);
+ // converts the application level QoS to Network-level QoS.
- virtual int parse (char* flowSpec_entry) = 0;
- // construct the entry from a string specified by the flowSpec grammar.
-
- virtual ~TAO_FlowSpec_Entry (void);
- // virtual destructor.
-
- virtual int direction (void);
-
- virtual TAO_SFP* flow_protocol (void);
- // Accessor to the flow protocol.
-
- virtual ACE_Addr *carrier_protocol (void);
- // carrier protocol.
-
- virtual char *format (void);
- // format to be used for this flow.
protected:
- int parse_flow_protocol_string (char *flow_options_string);
- // parses the flow protocol string with tokens separated by :
-
- int set_direction (char *direction_string);
- // sets the direction flag.
-
- int parse_address (char *format_string);
- // sets the address for this flow.
-
- TAO_SFP *sfp_;
- // reference to the flowprotocol implementation.
-
- ACE_Addr *address_;
- // Addr information for the carrier protocol.
-
- char *format_;
- // format string.
-
- Direction direction_;
- // Direction of this flow.
-
- char *flowname_;
- // name of this flow.
-
- char *protocol_;
- // name of the protocol used.
-};
+ AVStreams::streamQoS stream_qos_;
+ // Stream Qos.
-class TAO_ORBSVCS_Export TAO_Forward_FlowSpec_Entry
- :public TAO_FlowSpec_Entry
-{
-public:
- enum Position {TAO_AV_FLOWNAME = 0,
- TAO_AV_DIRECTION = 1,
- TAO_AV_FORMAT = 2,
- TAO_AV_FLOW_PROTOCOL = 3,
- TAO_AV_ADDRESS = 4};
-
- virtual int parse (char* flowSpec_entry);
- // construct the entry from a string specified by the flowSpec grammar.
+ ACE_Hash_Map_Manager<TAO_String_Hash_Key,AVStreams::QoS,ACE_Null_Mutex> qos_map_;
};
-class TAO_ORBSVCS_Export TAO_Reverse_FlowSpec_Entry
- :public TAO_FlowSpec_Entry
-{
-public:
- enum Position {TAO_AV_FLOWNAME = 0,
- TAO_AV_ADDRESS = 1,
- TAO_AV_FLOW_PROTOCOL = 2,
- TAO_AV_DIRECTION = 3,
- TAO_AV_FORMAT = 4};
-
- virtual int parse (char* flowSpec_entry);
- // construct the entry from a string specified by the flowSpec grammar.
-};
-
-// class TAO_ORBSVCS_Export TAO_AV_QoS
-// {
-// public:
-// TAO_AV_QoS (void) ACE_THROW_SPEC ((CORBA::SystemException));
-// // constructor.
-
-// int convert (const AVStreams::streamQoS &application_qos,
-// AVStreams::streamQoS &network_qos) ACE_THROW_SPEC ((CORBA::SystemException));
-// // converts the application level QoS to Network-level QoS.
-// };
+#include "Transport.h"
+
+#if defined (__ACE_INLINE__)
+#include "AVStreams_i.i"
+#endif /* __ACE_INLINE__ */
+
+#include "Flows_T.h"
#endif /* AVSTREAMS_I_H */
diff --git a/TAO/orbsvcs/orbsvcs/AV/AVStreams_i.i b/TAO/orbsvcs/orbsvcs/AV/AVStreams_i.i
new file mode 100644
index 00000000000..6476b9736ee
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/AV/AVStreams_i.i
@@ -0,0 +1,31 @@
+/* -*- C++ -*- */
+// $Id$
+
+// AVStreams_i.i
+
+ACE_INLINE
+int
+TAO_AV_QoS::set (AVStreams::streamQoS &stream_qos)
+{
+ this->stream_qos_ = stream_qos;
+
+ for (u_int j=0;j<this->stream_qos_.length ();j++)
+ {
+ TAO_String_Hash_Key qos_key (CORBA::string_dup (this->stream_qos_[j].QoSType));
+ int result = this->qos_map_.bind (qos_key,this->stream_qos_[j]);
+ if (result < 0)
+ ACE_ERROR_RETURN ((LM_ERROR,"qos_map::bind failed\n"),-1);
+ }
+ return 0;
+}
+
+
+ACE_INLINE
+int
+TAO_AV_QoS::get_flow_qos (const char *flowname,AVStreams::QoS &flow_qos)
+{
+ int result = this->qos_map_.find (flowname, flow_qos);
+ if (result < 0)
+ ACE_ERROR_RETURN ((LM_DEBUG,"qos_map::find failed\n"),-1);
+ return 0;
+}
diff --git a/TAO/orbsvcs/orbsvcs/AV/AV_Core.h b/TAO/orbsvcs/orbsvcs/AV/AV_Core.h
new file mode 100644
index 00000000000..f98863df02a
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/AV/AV_Core.h
@@ -0,0 +1,185 @@
+/* -*- C++ -*- */
+
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// ORBSVCS (AVStreams)
+//
+// = FILENAME
+// AV_Core.h
+//
+// = AUTHOR
+// Nagarajan Surendran <naga@cs.wustl.edu>
+//
+//
+// ============================================================================
+
+#ifndef TAO_AV_CORE_H
+#define TAO_AV_CORE_H
+
+#include "tao/TAO.h"
+#include "orbsvcs/AVStreamsC.h"
+
+class TAO_Base_StreamEndPoint;
+class TAO_AV_Connector_Registry;
+class TAO_AV_Acceptor_Registry;
+class TAO_AV_Acceptor;
+class TAO_AV_Connector;
+class TAO_FlowSpec_Entry;
+
+//forward declaration.
+class TAO_AV_Transport_Factory;
+
+class TAO_Export TAO_AV_Transport_Item
+{
+public:
+ TAO_AV_Transport_Item (const ACE_CString &name);
+ // creator method, the Transport name can only be set when the
+ // object is created.
+
+ const ACE_CString &name (void);
+ // return a reference to the character representation of the Transport
+ // factories name.
+
+ TAO_AV_Transport_Factory *factory (void);
+ // return a pointer to the Transport factory.
+
+ void factory (TAO_AV_Transport_Factory *factory);
+ // set the factory pointer's valus.
+
+private:
+ ACE_CString name_;
+ // Transport factory name.
+
+ TAO_AV_Transport_Factory *factory_;
+ // pointer to factory object.
+};
+
+class TAO_AV_Flow_Protocol_Factory;
+
+class TAO_Export TAO_AV_Flow_Protocol_Item
+{
+public:
+ TAO_AV_Flow_Protocol_Item (const ACE_CString &name);
+ // creator method, the Flow_Protocol name can only be set when the
+ // object is created.
+
+ const ACE_CString &name (void);
+ // return a reference to the character representation of the Flow_Protocol
+ // factories name.
+
+ TAO_AV_Flow_Protocol_Factory *factory (void);
+ // return a pointer to the Flow_Protocol factory.
+
+ void factory (TAO_AV_Flow_Protocol_Factory *factory);
+ // set the factory pointer's valus.
+
+private:
+ ACE_CString name_;
+ // Flow_Protocol factory name.
+
+ TAO_AV_Flow_Protocol_Factory *factory_;
+ // pointer to factory object.
+};
+
+// typedefs for containers containing the list of loaded Flow_Protocol
+// factories.
+typedef ACE_Unbounded_Set<TAO_AV_Flow_Protocol_Item*>
+ TAO_AV_Flow_ProtocolFactorySet;
+
+typedef ACE_Unbounded_Set_Iterator<TAO_AV_Flow_Protocol_Item*>
+ TAO_AV_Flow_ProtocolFactorySetItor;
+
+typedef ACE_Unbounded_Set<TAO_AV_Transport_Item*>
+ TAO_AV_TransportFactorySet;
+
+typedef ACE_Unbounded_Set_Iterator<TAO_AV_Transport_Item*>
+ TAO_AV_TransportFactorySetItor;
+
+typedef ACE_Unbounded_Set <TAO_FlowSpec_Entry*> TAO_AV_FlowSpecSet;
+typedef ACE_Unbounded_Set_Iterator <TAO_FlowSpec_Entry*> TAO_AV_FlowSpecSetItor;
+
+class TAO_ORBSVCS_Export TAO_AV_Core
+{
+public:
+ enum EndPoint {TAO_AV_ENDPOINT_A,TAO_AV_ENDPOINT_B};
+
+ enum Protocol
+ {
+ TAO_AV_NOPROTOCOL = -1,
+ TAO_AV_TCP = 0,
+ TAO_AV_UDP = 1,
+ TAO_AV_AAL5 = 2,
+ TAO_AV_AAL3_4 = 3,
+ TAO_AV_AAL1 = 4,
+ TAO_AV_RTP_UDP = 5,
+ TAO_AV_RTP_AAL5 = 6,
+ TAO_AV_IPX = 7,
+ TAO_AV_SFP_UDP = 8,
+ TAO_AV_UDP_MCAST = 9,
+ TAO_AV_RTP_UDP_MCAST = 10,
+ TAO_AV_SFP_UDP_MCAST = 11
+ };
+
+ TAO_AV_Core (void);
+ // Default constructor.
+
+ ~TAO_AV_Core (void);
+ // Destructor.
+
+ int init (int &argc,
+ char *argv [],
+ CORBA::Environment &env);
+ int run (void);
+ int stop_run (void);
+ int init_forward_flows (TAO_Base_StreamEndPoint *endpoint,
+ TAO_AV_FlowSpecSet &flow_spec_set,
+ EndPoint direction,
+ AVStreams::flowSpec &flow_spec);
+ int init_reverse_flows (TAO_Base_StreamEndPoint *endpoint,
+ TAO_AV_FlowSpecSet &forward_flow_spec_set,
+ TAO_AV_FlowSpecSet &reverse_flow_spec_set,
+ EndPoint direction);
+ int init_transport_factories (void);
+ int init_flow_protocol_factories (void);
+
+ TAO_AV_Acceptor *get_acceptor (const char *flowname);
+ TAO_AV_Connector *get_connector (const char *flowname);
+ TAO_AV_Connector_Registry *connector_registry (void);
+ TAO_FlowSpec_Entry *get_flow_spec_entry (TAO_AV_FlowSpecSet &flow_spec_set,
+ const char *flowname);
+ // = Get the acceptor registry
+ TAO_AV_Acceptor_Registry *acceptor_registry (void);
+
+ // = Get the protocol factories
+ TAO_AV_Flow_ProtocolFactorySet *flow_protocol_factories (void);
+ TAO_AV_TransportFactorySet *transport_factories (void);
+ // = Set/get the <ACE_Reactor>.
+ void reactor (ACE_Reactor *r);
+ ACE_Reactor *reactor (void);
+ TAO_ORB_Manager *orb_manager (void);
+
+protected:
+ TAO_AV_Connector_Registry *connector_registry_;
+ // The connector registry which all active connecters must register
+ // themselves with.
+
+ TAO_AV_Acceptor_Registry *acceptor_registry_;
+ // The registry which maintains a list of acceptor factories for each
+ // loaded protocol.
+
+ TAO_AV_TransportFactorySet transport_factories_;
+ // Pointer to the list of transports loaded into this AV_Core instance.
+
+ TAO_AV_Flow_ProtocolFactorySet flow_protocol_factories_;
+ // Pointer to the list of flow protocol loaded into this AV_Core instance.
+
+ ACE_Reactor *reactor_;
+ CORBA::ORB_var orb_;
+ TAO_ORB_Manager orb_manager_;
+ CORBA::Boolean stop_run_;
+};
+
+#endif /* TAO_AV_CORE_H */
diff --git a/TAO/orbsvcs/orbsvcs/AV/Endpoint_Strategy.cpp b/TAO/orbsvcs/orbsvcs/AV/Endpoint_Strategy.cpp
index aff8c054509..ba0e5fd9521 100644
--- a/TAO/orbsvcs/orbsvcs/AV/Endpoint_Strategy.cpp
+++ b/TAO/orbsvcs/orbsvcs/AV/Endpoint_Strategy.cpp
@@ -10,7 +10,7 @@
//
// = AUTHOR
// Sumedh Mungee <sumedh@cs.wustl.edu>
-//
+//
//
// ============================================================================
@@ -91,7 +91,7 @@ TAO_AV_Endpoint_Process_Strategy::~TAO_AV_Endpoint_Process_Strategy (void)
// Spawns the process, and waits for it to finish booting.
// Then uses bind_to_naming_service, get_stream_endpoint, and get_vdev
// to get the object references to the various objects created in the
-// child
+// child
int
TAO_AV_Endpoint_Process_Strategy::activate (void)
{
@@ -109,7 +109,7 @@ TAO_AV_Endpoint_Process_Strategy::activate (void)
// Create a unique semaphore name, using my hostname, and pid.
char sem_str [BUFSIZ];
-
+
// create a unique semaphore name
ACE_OS::sprintf (sem_str,
"%s:%s:%ld",
@@ -124,7 +124,7 @@ TAO_AV_Endpoint_Process_Strategy::activate (void)
ACE_Process_Semaphore semaphore (0, // 0 means that the
// semaphore is locked initially
sem_str);
-
+
// wait until the child finishes booting
while (1)
{
@@ -150,7 +150,7 @@ TAO_AV_Endpoint_Process_Strategy::activate (void)
"(%P|%t) semaphore remove failed: %p\n",
"remove"),
-1);
-
+
ACE_DECLARE_NEW_CORBA_ENV;
ACE_TRY
{
@@ -170,7 +170,7 @@ TAO_AV_Endpoint_Process_Strategy::activate (void)
{
ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"TAO_AV_Endpoint_Process_Strategy::activate");
return -1;
- }
+ }
ACE_ENDTRY;
ACE_CHECK_RETURN (-1);
return 0;
@@ -220,7 +220,7 @@ TAO_AV_Endpoint_Process_Strategy::get_vdev (CORBA::Environment &ACE_TRY_ENV)
this->host_,
this->pid_);
- ACE_DEBUG ((LM_DEBUG,"(%P|%t)%s\n",vdev_name));
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"(%P|%t)%s\n",vdev_name));
// Create the name
CosNaming::Name VDev_Name (1);
@@ -278,15 +278,15 @@ TAO_AV_Endpoint_Process_Strategy_A::create_A (AVStreams::StreamEndPoint_A_ptr &s
{
// use the baseclass activate
if (this->activate () == -1)
- ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_ERROR_RETURN ((LM_ERROR,
"(%P|%t) TAO_AV_Endpoint_Process_Strategy: Error in activate ()\n"),
-1);
-
+
// return the object references
stream_endpoint = this->stream_endpoint_a_;
vdev = this->vdev_;
return 0;
-
+
}
// Gets the stream endpoint object reference from the naming service
@@ -302,11 +302,11 @@ TAO_AV_Endpoint_Process_Strategy_A::get_stream_endpoint (CORBA::Environment &ACE
this->host_,
this->pid_);
- ACE_DEBUG ((LM_DEBUG,"(%P|%t)%s\n",stream_endpoint_name));
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"(%P|%t)%s\n",stream_endpoint_name));
// Create the name
CosNaming::Name Stream_Endpoint_A_Name (1);
-
+
Stream_Endpoint_A_Name.length (1);
Stream_Endpoint_A_Name [0].id = CORBA::string_dup (stream_endpoint_name);
@@ -315,13 +315,13 @@ TAO_AV_Endpoint_Process_Strategy_A::get_stream_endpoint (CORBA::Environment &ACE
this->naming_context_->resolve (Stream_Endpoint_A_Name,
ACE_TRY_ENV);
ACE_TRY_CHECK;
-
+
// Narrow the reference
this->stream_endpoint_a_ =
AVStreams::StreamEndPoint_A::_narrow (stream_endpoint_a.in (),
ACE_TRY_ENV);
ACE_TRY_CHECK;
-
+
// Check for validity
if (CORBA::is_nil (this->stream_endpoint_a_))
ACE_ERROR_RETURN ((LM_ERROR,
@@ -362,11 +362,11 @@ TAO_AV_Endpoint_Process_Strategy_B::create_B (AVStreams::StreamEndPoint_B_ptr &s
ACE_TRY
{
if (this->activate () == -1)
- ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_ERROR_RETURN ((LM_ERROR,
"(%P|%t) TAO_AV_Endpoint_Process_Strategy: Error in activate ()\n"),
-1);
- ACE_DEBUG ((LM_DEBUG,"(%P|%t)TAO_AV_Endpoint_Process_Strategy_B::create_B ()\n: stream_endpoint is:%s\n",
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"(%P|%t)TAO_AV_Endpoint_Process_Strategy_B::create_B ()\n: stream_endpoint is:%s\n",
TAO_ORB_Core_instance ()->orb ()->object_to_string (this->stream_endpoint_b_,
ACE_TRY_ENV)));
ACE_TRY_CHECK;
@@ -396,14 +396,14 @@ TAO_AV_Endpoint_Process_Strategy_B::get_stream_endpoint (CORBA::Environment &ACE
this->host_,
this->pid_);
- ACE_DEBUG ((LM_DEBUG,"(%P|%t)%s\n",stream_endpoint_name));
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"(%P|%t)%s\n",stream_endpoint_name));
// Create the name
CosNaming::Name Stream_Endpoint_B_Name (1);
-
+
Stream_Endpoint_B_Name.length (1);
Stream_Endpoint_B_Name [0].id = CORBA::string_dup (stream_endpoint_name);
-
+
// Get the CORBA::Object reference
CORBA::Object_var stream_endpoint_b =
this->naming_context_->resolve (Stream_Endpoint_B_Name,
diff --git a/TAO/orbsvcs/orbsvcs/AV/Endpoint_Strategy.h b/TAO/orbsvcs/orbsvcs/AV/Endpoint_Strategy.h
index 4f014c5c53d..74ed5fbe2fb 100644
--- a/TAO/orbsvcs/orbsvcs/AV/Endpoint_Strategy.h
+++ b/TAO/orbsvcs/orbsvcs/AV/Endpoint_Strategy.h
@@ -5,7 +5,7 @@
// ============================================================================
//
// = LIBRARY
-// cos
+// ORBSVCS AVStreams
//
// = FILENAME
// Endpoint_Strategy.h
@@ -29,10 +29,11 @@
#endif /* _MSC_VER */
class TAO_ORBSVCS_Export TAO_AV_Endpoint_Strategy
-// = DESCRIPTION
-// Base class to define various endpoint strategies
-// used by the MMDevice to create the Endpoint and Vdev
{
+ // = DESCRIPTION
+ // Base class to define various endpoint strategies
+ // used by the MMDevice to create the Endpoint and Vdev
+
public:
TAO_AV_Endpoint_Strategy (void);
// Constructor
@@ -50,7 +51,7 @@ public:
CORBA::Environment &env);
// Called by the MMDevice, when it needs to create an B type endpoint
- protected:
+protected:
AVStreams::StreamEndPoint_A_ptr stream_endpoint_a_;
// The "A" stream endpoint
@@ -66,11 +67,12 @@ public:
class TAO_ORBSVCS_Export TAO_AV_Endpoint_Process_Strategy
: public TAO_AV_Endpoint_Strategy
-// = DESCRIPTION
-// Process-based strategy for creating endpoints
-// Abstract base class.
{
- public:
+ // = DESCRIPTION
+ // Process-based strategy for creating endpoints
+ // Abstract base class.
+
+public:
TAO_AV_Endpoint_Process_Strategy (ACE_Process_Options *process_options);
// Constructor. The process_options contain the name and arguments
// for the process to be created
@@ -82,7 +84,7 @@ class TAO_ORBSVCS_Export TAO_AV_Endpoint_Process_Strategy
// creates a new child process, and waits on a semaphore
// until the child process has finished creating the endpoints
- protected:
+protected:
virtual int bind_to_naming_service (CORBA::Environment &env);
// Bind to the naming service
@@ -113,17 +115,18 @@ class TAO_ORBSVCS_Export TAO_AV_Endpoint_Process_Strategy
class TAO_ORBSVCS_Export TAO_AV_Endpoint_Process_Strategy_A
: public TAO_AV_Endpoint_Process_Strategy
-// = DESCRIPTION
-// Process-based strategy to create "A" type endpoints
{
- public:
+ // = DESCRIPTION
+ // Process-based strategy to create "A" type endpoints
+
+public:
TAO_AV_Endpoint_Process_Strategy_A (ACE_Process_Options *process_options);
// Constructor
virtual ~TAO_AV_Endpoint_Process_Strategy_A (void);
// Destructor.
- protected:
+protected:
virtual int create_A (AVStreams::StreamEndPoint_A_ptr &stream_endpoint,
AVStreams::VDev_ptr &vdev,
CORBA::Environment &env);
@@ -138,17 +141,17 @@ class TAO_ORBSVCS_Export TAO_AV_Endpoint_Process_Strategy_A
class TAO_ORBSVCS_Export TAO_AV_Endpoint_Process_Strategy_B
: public TAO_AV_Endpoint_Process_Strategy
-// = DESCRIPTION
-// Process-based strategy to create "B" type endpoints
{
- public:
+ // = DESCRIPTION
+ // Process-based strategy to create "B" type endpoints
+public:
TAO_AV_Endpoint_Process_Strategy_B (ACE_Process_Options *process_options);
// Constructor
virtual ~TAO_AV_Endpoint_Process_Strategy_B (void);
// Destructor.
- protected:
+protected:
virtual int create_B (AVStreams::StreamEndPoint_B_ptr &stream_endpoint,
AVStreams::VDev_ptr &vdev,
CORBA::Environment &env);
diff --git a/TAO/orbsvcs/orbsvcs/AV/Endpoint_Strategy_T.cpp b/TAO/orbsvcs/orbsvcs/AV/Endpoint_Strategy_T.cpp
index c3bb4ff2714..010ca8ca740 100644
--- a/TAO/orbsvcs/orbsvcs/AV/Endpoint_Strategy_T.cpp
+++ b/TAO/orbsvcs/orbsvcs/AV/Endpoint_Strategy_T.cpp
@@ -31,15 +31,15 @@ TAO_AV_Endpoint_Reactive_Strategy <T_StreamEndpoint, T_VDev, T_MediaCtrl>::activ
{
this->activate_stream_endpoint (ACE_TRY_ENV);
ACE_TRY_CHECK;
- ACE_DEBUG ((LM_DEBUG,"(%P|%t)TAO_AV_Endpoint_Reactive_Strategy::activated stream_endpoint\n"));
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"(%P|%t)TAO_AV_Endpoint_Reactive_Strategy::activated stream_endpoint\n"));
this->activate_vdev (ACE_TRY_ENV);
ACE_TRY_CHECK;
- ACE_DEBUG ((LM_DEBUG,"(%P|%t)TAO_AV_Endpoint_Reactive_Strategy::activated vdev\n"));
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"(%P|%t)TAO_AV_Endpoint_Reactive_Strategy::activated vdev\n"));
this->activate_mediactrl (ACE_TRY_ENV);
ACE_TRY_CHECK;
- ACE_DEBUG ((LM_DEBUG,"(%P|%t)TAO_AV_Endpoint_Reactive_Strategy::activated mediactrl\n"));
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"(%P|%t)TAO_AV_Endpoint_Reactive_Strategy::activated mediactrl\n"));
}
ACE_CATCHANY
{
@@ -67,7 +67,7 @@ TAO_AV_Endpoint_Reactive_Strategy <T_StreamEndpoint, T_VDev, T_MediaCtrl>::activ
CORBA::String_var vdev_ior = this->orb_manager_->activate (vdev,
ACE_TRY_ENV);
ACE_TRY_CHECK;
- ACE_DEBUG ((LM_DEBUG,"(%P|%t)TAO_AV_Endpoint_Reactive_Strategy::activate_vdev, vdev ior is:%s\n",
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"(%P|%t)TAO_AV_Endpoint_Reactive_Strategy::activate_vdev, vdev ior is:%s\n",
vdev_ior. in ()));
// Save the object reference, so that create_A can return it
@@ -102,7 +102,7 @@ TAO_AV_Endpoint_Reactive_Strategy <T_StreamEndpoint, T_VDev, T_MediaCtrl>::activ
CORBA::String_var mediactrl_ior = this->orb_manager_->activate (media_ctrl,
ACE_TRY_ENV);
ACE_TRY_CHECK;
- ACE_DEBUG ((LM_DEBUG,"(%P|%t)TAO_AV_Endpoint_Reactive_Strategy::activate_mediactrl , media_ctrl ior is :%s\n",
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"(%P|%t)TAO_AV_Endpoint_Reactive_Strategy::activate_mediactrl , media_ctrl ior is :%s\n",
mediactrl_ior.in ()));
@@ -214,7 +214,7 @@ TAO_AV_Endpoint_Reactive_Strategy_A <T_StreamEndpoint, T_VDev, T_MediaCtrl>::act
CORBA::String_var stream_endpoint_ior = this->orb_manager_->activate (stream_endpoint_a,
ACE_TRY_ENV);
ACE_TRY_CHECK;
- ACE_DEBUG ((LM_DEBUG,"TAO_AV_Endpoint_Reactive_Strategy_A::activate_stream_endpoint,Stream Endpoint ior is : %s\n",stream_endpoint_ior.in ()));
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"TAO_AV_Endpoint_Reactive_Strategy_A::activate_stream_endpoint,Stream Endpoint ior is : %s\n",stream_endpoint_ior.in ()));
// Save the object references, so that create_a can return them
this->stream_endpoint_a_ = stream_endpoint_a->_this (ACE_TRY_ENV);
@@ -263,7 +263,7 @@ TAO_AV_Endpoint_Reactive_Strategy_B <T_StreamEndpoint, T_VDev, T_MediaCtrl>::act
CORBA::String_var stream_endpoint_ior = this->orb_manager_->activate (stream_endpoint_b,
ACE_TRY_ENV);
ACE_TRY_CHECK;
- ACE_DEBUG ((LM_DEBUG,"TAO_AV_Endpoint_Reactive_Strategy_B::activate_stream_endpoint,Stream Endpoint ior is : %s\n",stream_endpoint_ior.in ()));
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"TAO_AV_Endpoint_Reactive_Strategy_B::activate_stream_endpoint,Stream Endpoint ior is : %s\n",stream_endpoint_ior.in ()));
this->stream_endpoint_b_ = stream_endpoint_b->_this (ACE_TRY_ENV);
ACE_TRY_CHECK;
@@ -388,20 +388,20 @@ TAO_AV_Child_Process <T_StreamEndpoint, T_VDev, T_MediaCtrl>::activate_objects
CORBA::String_var stream_endpoint_ior = this->orb_manager_.activate (this->stream_endpoint_,
ACE_TRY_ENV);
ACE_TRY_CHECK;
- ACE_DEBUG ((LM_DEBUG,"(%P|%t)TAO_AV_Child_Process::activate_objects,stream_endpoint_ior :%s\n",stream_endpoint_ior.in ()));
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"(%P|%t)TAO_AV_Child_Process::activate_objects,stream_endpoint_ior :%s\n",stream_endpoint_ior.in ()));
// activate the vdev
CORBA::String_var vdev_ior = this->orb_manager_.activate (this->vdev_,
ACE_TRY_ENV);
ACE_TRY_CHECK;
- ACE_DEBUG ((LM_DEBUG,"(%P|%t)TAO_AV_Child_Process::activate_objects, vdev ior is :%s\n",vdev_ior.in ()));
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"(%P|%t)TAO_AV_Child_Process::activate_objects, vdev ior is :%s\n",vdev_ior.in ()));
// activate the media controller
CORBA::String_var media_ctrl_ior = this->orb_manager_.activate (this->media_ctrl_,
ACE_TRY_ENV);
ACE_TRY_CHECK;
- ACE_DEBUG ((LM_DEBUG,"(%P|%t)TAO_AV_Child_Process::activate_objects,media_ctrl_ior is: %s\n",media_ctrl_ior.in ()));
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"(%P|%t)TAO_AV_Child_Process::activate_objects,media_ctrl_ior is: %s\n",media_ctrl_ior.in ()));
}
ACE_CATCHANY
{
@@ -426,7 +426,7 @@ TAO_AV_Child_Process <T_StreamEndpoint, T_VDev, T_MediaCtrl>::bind_to_naming_se
ACE_ERROR_RETURN ((LM_ERROR,
" (%P|%t) Unable to resolve the Name Service.\n"),
-1);
- // ACE_DEBUG ((LM_DEBUG, "(%P|%t) %s:%d\n", __FILE__, __LINE__));
+ // if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG, "(%P|%t) %s:%d\n", __FILE__, __LINE__));
this->naming_context_ =
CosNaming::NamingContext::_narrow (naming_obj.in (),
ACE_TRY_ENV);
@@ -457,14 +457,14 @@ TAO_AV_Child_Process <T_StreamEndpoint, T_VDev, T_MediaCtrl>::register_vdev (CO
this->host_,
this->pid_);
- ACE_DEBUG ((LM_DEBUG,"(%P|%t)%s\n",vdev_name));
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"(%P|%t)%s\n",vdev_name));
// create the name
this->vdev_name_.length (1);
this->vdev_name_ [0].id = CORBA::string_dup (vdev_name);
// make the media controller a property of the vdev
CORBA::Any media_ctrl_property;
- CORBA::Object_var media_ctrl_obj =
+ CORBA::Object_var media_ctrl_obj =
this->media_ctrl_->_this (ACE_TRY_ENV);
ACE_TRY_CHECK;
media_ctrl_property <<= this->orb_manager_.orb ()->object_to_string (media_ctrl_obj.in (),
@@ -549,7 +549,7 @@ TAO_AV_Child_Process <T_StreamEndpoint_B, T_VDev, T_MediaCtrl>::release_semapho
this->host_,
pid);
- ACE_DEBUG ((LM_DEBUG,
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,
"(%P|%t) semaphore is %s\n",
sem_str));
@@ -580,7 +580,7 @@ TAO_AV_Child_Process <T_StreamEndpoint, T_VDev, T_MediaCtrl>::register_stream_e
ACE_TRY_CHECK;
this->stream_endpoint_->_remove_ref (ACE_TRY_ENV);
ACE_TRY_CHECK;
- // ACE_DEBUG ((LM_DEBUG, "(%P|%t) %s:%d\n", __FILE__, __LINE__));
+ // if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG, "(%P|%t) %s:%d\n", __FILE__, __LINE__));
// Create a name for the video control object
// subclasses can define their own name for the streamendpoint
// Register the stream endpoint object with the naming server.
@@ -634,7 +634,7 @@ template <class T_StreamEndpoint, class T_VDev , class T_MediaCtrl>
int
TAO_AV_Child_Process<T_StreamEndpoint, T_VDev, T_MediaCtrl>::make_mediactrl (T_MediaCtrl *&media_ctrl)
{
- ACE_DEBUG ((LM_DEBUG,"(%P|%t) TAO_AV_Child_Process::make_mediactrl ()\n"));
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"(%P|%t) TAO_AV_Child_Process::make_mediactrl ()\n"));
ACE_NEW_RETURN (media_ctrl,
T_MediaCtrl,
-1);
@@ -703,7 +703,7 @@ TAO_AV_Child_Process_A<T_StreamEndpoint, T_VDev, T_MediaCtrl>::TAO_AV_Child_Proc
this->host_,
this->pid_);
- ACE_DEBUG ((LM_DEBUG,"(%P|%t)%s\n",stream_endpoint_name));
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"(%P|%t)%s\n",stream_endpoint_name));
this->stream_endpoint_name_.length (1);
this->stream_endpoint_name_ [0].id = CORBA::string_dup (stream_endpoint_name);
}
@@ -729,7 +729,7 @@ TAO_AV_Child_Process_B<T_StreamEndpoint, T_VDev, T_MediaCtrl>::TAO_AV_Child_Proc
this->host_,
this->pid_);
- ACE_DEBUG ((LM_DEBUG,"(%P|%t)%s\n",stream_endpoint_name));
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"(%P|%t)%s\n",stream_endpoint_name));
this->stream_endpoint_name_.length (1);
this->stream_endpoint_name_ [0].id = CORBA::string_dup (stream_endpoint_name);
}
diff --git a/TAO/orbsvcs/orbsvcs/AV/Endpoint_Strategy_T.h b/TAO/orbsvcs/orbsvcs/AV/Endpoint_Strategy_T.h
index d88b3330638..ca805f98bfe 100644
--- a/TAO/orbsvcs/orbsvcs/AV/Endpoint_Strategy_T.h
+++ b/TAO/orbsvcs/orbsvcs/AV/Endpoint_Strategy_T.h
@@ -1,5 +1,23 @@
+/* -*- C++ -*- */
+
// $Id$
+// ============================================================================
+//
+// = LIBRARY
+// ORBSVCS AVStreams
+//
+// = FILENAME
+// Endpoint_Strategy_T.h
+//
+// = AUTHOR
+// Sumedh Mungee <sumedh@cs.wustl.edu>
+// Nagarajan Surendran <naga@cs.wustl.edu>
+//
+//
+// ============================================================================
+
+
#ifndef TAO_AV_ENDPOINT_STRATEGY_T_H
#define TAO_AV_ENDPOINT_STRATEGY_T_H
@@ -7,11 +25,12 @@
template <class T_StreamEndpoint, class T_VDev , class T_MediaCtrl>
class TAO_ORBSVCS_Export TAO_AV_Endpoint_Reactive_Strategy
- : public TAO_AV_Endpoint_Strategy
-// = DESCRIPTION
-// Reactive strategy base class
+: public TAO_AV_Endpoint_Strategy
{
- protected:
+ // = DESCRIPTION
+ // Reactive strategy base class
+
+protected:
TAO_AV_Endpoint_Reactive_Strategy (TAO_ORB_Manager *orb_manager);
// Constructor
@@ -51,10 +70,11 @@ class TAO_ORBSVCS_Export TAO_AV_Endpoint_Reactive_Strategy
template <class T_StreamEndpoint, class T_VDev , class T_MediaCtrl>
class TAO_ORBSVCS_Export TAO_AV_Endpoint_Reactive_Strategy_A
: public TAO_AV_Endpoint_Reactive_Strategy<T_StreamEndpoint, T_VDev , T_MediaCtrl>
-// = DESCRIPTION
-// Reactive strategy
{
- public:
+ // = DESCRIPTION
+ // Reactive strategy
+
+public:
TAO_AV_Endpoint_Reactive_Strategy_A (TAO_ORB_Manager *orb_manager);
// Constructor
@@ -70,17 +90,16 @@ class TAO_ORBSVCS_Export TAO_AV_Endpoint_Reactive_Strategy_A
CORBA::Environment &env);
// Called by the MMDevice, when it needs to create an A type endpoint
-
};
// ----------------------------------------------------------------------
template <class T_StreamEndpoint, class T_Vdev , class T_MediaCtrl>
class TAO_ORBSVCS_Export TAO_AV_Endpoint_Reactive_Strategy_B
: public TAO_AV_Endpoint_Reactive_Strategy <T_StreamEndpoint, T_Vdev, T_MediaCtrl>
-// = DESCRIPTION
-// Reactive strategy
{
- public:
+ // = DESCRIPTION
+ // Reactive strategy
+public:
TAO_AV_Endpoint_Reactive_Strategy_B (TAO_ORB_Manager *);
// Constructor.
@@ -101,9 +120,10 @@ class TAO_ORBSVCS_Export TAO_AV_Endpoint_Reactive_Strategy_B
template <class T_StreamEndpoint, class T_VDev , class T_MediaCtrl>
class TAO_ORBSVCS_Export TAO_AV_Child_Process
-// = DESCRIPTION
-// Helper class for the child process created in TAO_AV_Endpoint_Process_Strategy
{
+ // = DESCRIPTION
+ // Helper class for the child process created in TAO_AV_Endpoint_Process_Strategy
+
public:
TAO_AV_Child_Process ();
// Constructor
@@ -118,7 +138,7 @@ public:
int run (ACE_Time_Value *tv = 0);
// runs the ORB event loop
- protected:
+protected:
int activate_objects (int argc,
char **argv,
CORBA::Environment &env);
@@ -186,9 +206,10 @@ public:
template <class T_StreamEndpoint, class T_VDev , class T_MediaCtrl>
class TAO_ORBSVCS_Export TAO_AV_Child_Process_A
: public TAO_AV_Child_Process <T_StreamEndpoint, T_VDev, T_MediaCtrl>
-// = DESCRIPTION
-// Helper class for the child process created in TAO_AV_Child_Process
{
+ // = DESCRIPTION
+ // Helper class for the child process created in TAO_AV_Child_Process
+
public:
TAO_AV_Child_Process_A (void);
// Constructor.
@@ -202,9 +223,9 @@ public:
template <class T_StreamEndpoint, class T_VDev , class T_MediaCtrl>
class TAO_ORBSVCS_Export TAO_AV_Child_Process_B
: public TAO_AV_Child_Process <T_StreamEndpoint, T_VDev, T_MediaCtrl>
-// = DESCRIPTION
-// Helper class for the child process created in TAO_AV_Child_Process
{
+ // = DESCRIPTION
+ // Helper class for the child process created in TAO_AV_Child_Process
public:
TAO_AV_Child_Process_B (void);
// Constructor.
diff --git a/TAO/orbsvcs/orbsvcs/AV/FlowSpec_Entry.cpp b/TAO/orbsvcs/orbsvcs/AV/FlowSpec_Entry.cpp
new file mode 100644
index 00000000000..cb2edd12e21
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/AV/FlowSpec_Entry.cpp
@@ -0,0 +1,532 @@
+// $Id$
+
+//------------------------------------------------------------
+// TAO_FlowSpec_Entry
+//------------------------------------------------------------
+#include "FlowSpec_Entry.h"
+#include "tao/TAO.h"
+
+#if !defined (__ACE_INLINE__)
+#include "FlowSpec_Entry.i"
+#endif /* __ACE_INLINE__ */
+
+// constructor.
+TAO_FlowSpec_Entry::TAO_FlowSpec_Entry (void)
+ :address_ (0),
+ address_str_ (CORBA::string_dup ("")),
+ format_ (CORBA::string_dup ("")),
+ direction_ (TAO_AV_INVALID),
+ protocol_ (TAO_AV_Core::TAO_AV_NOPROTOCOL),
+ carrier_protocol_ (CORBA::string_dup ("")),
+ flow_protocol_ (CORBA::string_dup ("")),
+ use_flow_protocol_ (0),
+ entry_ (0),
+ is_multicast_ (0),
+ peer_addr_ (0),
+ local_addr_ (0),
+ transport_ (0),
+ handler_ (0),
+ protocol_object_ (0),
+ role_ (TAO_AV_INVALID_ROLE)
+{
+}
+
+// constructor.
+TAO_FlowSpec_Entry::TAO_FlowSpec_Entry (const char *flowname,
+ const char *direction,
+ const char *format_name,
+ const char *flow_protocol,
+ const char *carrier_protocol,
+ ACE_Addr *address)
+ :address_ (address),
+ address_str_ (0),
+ format_ (CORBA::string_dup (format_name)),
+ direction_str_ (CORBA::string_dup (direction)),
+ flowname_ (CORBA::string_dup (flowname)),
+ carrier_protocol_ (CORBA::string_dup (carrier_protocol)),
+ flow_protocol_ (CORBA::string_dup (flow_protocol)),
+ use_flow_protocol_ (0),
+ entry_ (0),
+ peer_addr_ (0),
+ local_addr_ (0),
+ transport_ (0),
+ handler_ (0),
+ protocol_object_ (0),
+ is_multicast_ (0),
+ role_ (TAO_AV_INVALID_ROLE)
+{
+ this->set_protocol ();
+ this->set_direction (this->direction_str_);
+ this->parse_flow_protocol_string (this->flow_protocol_);
+}
+
+TAO_FlowSpec_Entry::TAO_FlowSpec_Entry (const char *flowname,
+ const char *direction,
+ const char *format_name,
+ const char *flow_protocol,
+ const char *address)
+ :address_ (0),
+ address_str_ (CORBA::string_dup (address)),
+ format_ (CORBA::string_dup (format_name)),
+ direction_str_ (CORBA::string_dup (direction)),
+ flowname_ (CORBA::string_dup (flowname)),
+ carrier_protocol_ (0),
+ flow_protocol_ (CORBA::string_dup (flow_protocol)),
+ use_flow_protocol_ (0),
+ entry_ (0),
+ peer_addr_ (0),
+ local_addr_ (0),
+ transport_ (0),
+ handler_ (0),
+ protocol_object_ (0),
+ is_multicast_ (0),
+ role_ (TAO_AV_INVALID_ROLE)
+{
+ ACE_CString cstring(this->address_str_,0,0);
+ int colon_pos = cstring.find (':');
+ if (colon_pos != cstring.npos)
+ cstring[colon_pos] = ';';
+ this->address_str_ = cstring.rep ();
+ this->parse_flow_protocol_string (this->flow_protocol_);
+ this->parse_address (this->address_str_);
+ this->set_direction (this->direction_str_);
+}
+
+// Destructor.
+TAO_FlowSpec_Entry::~TAO_FlowSpec_Entry (void)
+{
+ CORBA::string_free (this->format_);
+ CORBA::string_free (this->direction_str_);
+ CORBA::string_free (this->flowname_);
+ CORBA::string_free (this->carrier_protocol_);
+}
+
+int
+TAO_FlowSpec_Entry::set_protocol (void)
+{
+ if (!this->use_flow_protocol_)
+ {
+ if (ACE_OS::strcasecmp (this->carrier_protocol_,"TCP") == 0)
+ this->protocol_ = TAO_AV_Core::TAO_AV_TCP;
+ else if (ACE_OS::strcasecmp (this->carrier_protocol_,"UDP") == 0)
+ this->protocol_ = TAO_AV_Core::TAO_AV_UDP;
+ else if (ACE_OS::strcasecmp (this->carrier_protocol_,"AAL5") == 0)
+ this->protocol_ = TAO_AV_Core::TAO_AV_AAL5;
+ else if (ACE_OS::strcasecmp (this->carrier_protocol_,"AAL3_4") == 0)
+ this->protocol_ = TAO_AV_Core::TAO_AV_AAL3_4;
+ else if (ACE_OS::strcasecmp (this->carrier_protocol_,"AAL1") == 0)
+ this->protocol_ = TAO_AV_Core::TAO_AV_AAL1;
+ else if (ACE_OS::strcasecmp (this->carrier_protocol_,"RTP/UDP") == 0)
+ this->protocol_ = TAO_AV_Core::TAO_AV_RTP_UDP;
+ else if (ACE_OS::strcasecmp (this->carrier_protocol_,"RTP/AAL5") == 0)
+ this->protocol_ = TAO_AV_Core::TAO_AV_RTP_AAL5;
+ else if (ACE_OS::strcasecmp (this->carrier_protocol_,"IPX") == 0)
+ this->protocol_ = TAO_AV_Core::TAO_AV_IPX;
+ else
+ {
+ this->protocol_ = TAO_AV_Core::TAO_AV_NOPROTOCOL;
+ return -1;
+ }
+ }
+ else
+ {
+ if (ACE_OS::strcasecmp (this->carrier_protocol_,"UDP") == 0)
+ {
+ this->protocol_ = TAO_AV_Core::TAO_AV_SFP_UDP;
+ }
+ else
+ {
+ this->protocol_ = TAO_AV_Core::TAO_AV_NOPROTOCOL;
+ return -1;
+ }
+ }
+ if (this->address_ != 0)
+ {
+ ACE_INET_Addr *inet_addr = ACE_dynamic_cast (ACE_INET_Addr*,this->address_);
+ char buf[BUFSIZ];
+ inet_addr->addr_to_string (buf,BUFSIZ);
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"TAO_FlowSpec_Entry::set_protocol:%s\n",buf));
+ if (IN_CLASSD (inet_addr->get_ip_address ()))
+ {
+ this->is_multicast_ = 1;
+ switch (this->protocol_)
+ {
+ case TAO_AV_Core::TAO_AV_UDP:
+ this->protocol_ = TAO_AV_Core::TAO_AV_UDP_MCAST;
+ break;
+ case TAO_AV_Core::TAO_AV_RTP_UDP:
+ this->protocol_ = TAO_AV_Core::TAO_AV_RTP_UDP_MCAST;
+ break;
+ case TAO_AV_Core::TAO_AV_SFP_UDP:
+ this->protocol_ = TAO_AV_Core::TAO_AV_SFP_UDP_MCAST;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ return 0;
+}
+
+int
+TAO_FlowSpec_Entry::parse_address (char *address)
+{
+ if (address == 0)
+ return 0;
+ if (ACE_OS::strcmp (address,"") == 0)
+ return 0;
+ TAO_Tokenizer protocol_tokenizer (address,'=');
+ this->carrier_protocol_ = protocol_tokenizer[0];
+
+ int result = this->set_protocol ();
+ if (result < 0)
+ return result;
+
+ if (protocol_tokenizer [1] != 0)
+ {
+ TAO_Tokenizer address_tokenizer (protocol_tokenizer[1],';');
+ char addr[BUFSIZ];
+ // convert to the ACE_Addr format.
+ ACE_OS::sprintf (addr,"%s:%s",address_tokenizer[0],address_tokenizer[1]);
+ switch (this->protocol_)
+ {
+ case TAO_AV_Core::TAO_AV_SFP_UDP:
+ case TAO_AV_Core::TAO_AV_RTP_UDP:
+ case TAO_AV_Core::TAO_AV_TCP:
+ case TAO_AV_Core::TAO_AV_UDP:
+ {
+ this->address_str_ = CORBA::string_dup (addr);
+ ACE_INET_Addr *inet_addr;
+ ACE_NEW_RETURN (inet_addr,
+ ACE_INET_Addr (addr),
+ -1);
+ this->address_ = inet_addr;
+ if (IN_CLASSD (inet_addr->get_ip_address ()))
+ {
+ this->is_multicast_ = 1;
+ switch (this->protocol_)
+ {
+ case TAO_AV_Core::TAO_AV_UDP:
+ this->protocol_ = TAO_AV_Core::TAO_AV_UDP_MCAST;
+ break;
+ case TAO_AV_Core::TAO_AV_RTP_UDP:
+ this->protocol_ = TAO_AV_Core::TAO_AV_RTP_UDP_MCAST;
+ break;
+ case TAO_AV_Core::TAO_AV_SFP_UDP:
+ this->protocol_ = TAO_AV_Core::TAO_AV_SFP_UDP_MCAST;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ break;
+ default:
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"ATM support not added yet\n"));
+ }
+ }
+ return 0;
+}
+
+char *
+TAO_FlowSpec_Entry::get_local_addr_str (void)
+{
+ if (this->local_addr_ == 0)
+ return 0;
+
+ switch (this->local_addr_->get_type ())
+ {
+ case AF_INET:
+ {
+ char *buf;
+ ACE_NEW_RETURN (buf,
+ char [BUFSIZ],
+ 0);
+ ACE_INET_Addr *inet_addr = ACE_dynamic_cast (ACE_INET_Addr *,this->local_addr_);
+ inet_addr->addr_to_string (buf,BUFSIZ);
+ ACE_CString cstring (buf,0,0);
+ int colon_pos = cstring.find (':');
+ if (colon_pos != cstring.npos)
+ cstring[colon_pos] = ';';
+ return cstring.rep ();
+ }
+ break;
+ default:
+ ACE_ERROR_RETURN ((LM_ERROR,"Address family not supported"),0);
+ }
+}
+
+//------------------------------------------------------------
+// TAO_Forward_FlowSpec_Entry
+//------------------------------------------------------------
+
+// default constructor.
+TAO_Forward_FlowSpec_Entry::TAO_Forward_FlowSpec_Entry (void)
+{
+}
+
+// constructor to construct the entry from the arguments.
+TAO_Forward_FlowSpec_Entry::TAO_Forward_FlowSpec_Entry (const char *flowname,
+ const char *direction,
+ const char *format_name ,
+ const char *flow_protocol ,
+ const char *carrier_protocol ,
+ ACE_Addr *address )
+ :TAO_FlowSpec_Entry (flowname,
+ direction,
+ format_name,
+ flow_protocol,
+ carrier_protocol,
+ address)
+{
+}
+
+// constructor to construct the entry from the arguments.
+TAO_Forward_FlowSpec_Entry::TAO_Forward_FlowSpec_Entry (const char *flowname,
+ const char *direction,
+ const char *format_name ,
+ const char *flow_protocol ,
+ const char *address )
+ :TAO_FlowSpec_Entry (flowname,
+ direction,
+ format_name,
+ flow_protocol,
+ address)
+{
+}
+
+int
+TAO_Forward_FlowSpec_Entry::parse (const char *flowSpec_entry)
+{
+ TAO_Tokenizer tokenizer (flowSpec_entry,'\\');
+
+ this->flowname_ = tokenizer [TAO_AV_FLOWNAME];
+
+ if (tokenizer [TAO_AV_DIRECTION] != 0)
+ this->set_direction (tokenizer [TAO_AV_DIRECTION]);
+
+ if (tokenizer [TAO_AV_FORMAT] != 0)
+ this->format_ = tokenizer [TAO_AV_FORMAT];
+
+ if (tokenizer [TAO_AV_ADDRESS] != 0)
+ if (this->parse_address (tokenizer [TAO_AV_ADDRESS]) < 0)
+ return -1;
+
+ if (tokenizer [TAO_AV_FLOW_PROTOCOL] != 0)
+ if (this->parse_flow_protocol_string (tokenizer [TAO_AV_FLOW_PROTOCOL]) < 0)
+ return -1;
+
+ return 0;
+}
+
+TAO_FlowSpec_Entry::Role
+TAO_Forward_FlowSpec_Entry::role (void)
+{
+ if (this->role_ != TAO_AV_INVALID_ROLE)
+ return this->role_;
+
+ switch (this->direction_)
+ {
+ case TAO_AV_DIR_IN:
+ // Forward IN means we're the Source.
+ return TAO_AV_PRODUCER;
+ case TAO_AV_DIR_OUT:
+ // Forward out means we're the sink.
+ return TAO_AV_CONSUMER;
+ default:
+ return TAO_AV_INVALID_ROLE;
+ }
+ return TAO_AV_INVALID_ROLE;
+}
+
+char *
+TAO_Forward_FlowSpec_Entry::entry_to_string (void)
+{
+ if (this->flowname_ == 0)
+ return 0;
+
+ ACE_NEW_RETURN (this->entry_,
+ char [BUFSIZ],
+ 0);
+
+ char address [BUFSIZ];
+ char address_str [BUFSIZ];
+ if (this->address_ != 0)
+ {
+ switch (this->protocol_)
+ {
+ case TAO_AV_Core::TAO_AV_SFP_UDP:
+ case TAO_AV_Core::TAO_AV_SFP_UDP_MCAST:
+ case TAO_AV_Core::TAO_AV_RTP_UDP:
+ case TAO_AV_Core::TAO_AV_RTP_UDP_MCAST:
+ case TAO_AV_Core::TAO_AV_UDP:
+ case TAO_AV_Core::TAO_AV_UDP_MCAST:
+ case TAO_AV_Core::TAO_AV_TCP:
+ {
+ ACE_INET_Addr *inet_addr = ACE_dynamic_cast (ACE_INET_Addr*,this->address_);
+ inet_addr->addr_to_string (address,BUFSIZ);
+ }
+ break;
+ default:
+ break;
+ }
+ ACE_CString cstring (address);
+ int colon_pos = cstring.find (':');
+ if (colon_pos != cstring.npos)
+ cstring[colon_pos] = ';';
+
+
+ ACE_OS::sprintf (address_str,"%s=%s",
+ this->carrier_protocol_,
+ cstring.c_str ());
+
+ }
+ else
+ ACE_OS::strcpy (address_str,this->carrier_protocol_);
+ ACE_OS::sprintf (this->entry_,
+ "%s\\%s\\%s\\%s\\%s",
+ this->flowname_,
+ this->direction_str_,
+ this->format_,
+ this->flow_protocol_,
+ address_str);
+
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"entry_to_string: entry = %s\n",this->entry_));
+ return this->entry_;
+}
+
+//------------------------------------------------------------
+// TAO_Reverse_FlowSpec_Entry
+//------------------------------------------------------------
+
+//default constructor.
+TAO_Reverse_FlowSpec_Entry::TAO_Reverse_FlowSpec_Entry (void)
+{
+}
+
+// constructor to construct an entry from the arguments.
+TAO_Reverse_FlowSpec_Entry::TAO_Reverse_FlowSpec_Entry (const char *flowname,
+ const char *direction,
+ const char *format_name ,
+ const char *flow_protocol ,
+ const char *carrier_protocol,
+ ACE_Addr *address)
+ :TAO_FlowSpec_Entry (flowname,
+ direction,
+ format_name,
+ flow_protocol,
+ carrier_protocol,
+ address)
+{
+}
+
+// constructor to construct an entry from the arguments.
+TAO_Reverse_FlowSpec_Entry::TAO_Reverse_FlowSpec_Entry (const char *flowname,
+ const char *direction,
+ const char *format_name ,
+ const char *flow_protocol ,
+ const char *address)
+ :TAO_FlowSpec_Entry (flowname,
+ direction,
+ format_name,
+ flow_protocol,
+ address)
+{
+}
+
+TAO_FlowSpec_Entry::Role
+TAO_Reverse_FlowSpec_Entry::role (void)
+{
+ if (this->role_ != TAO_AV_INVALID_ROLE)
+ return this->role_;
+ switch (this->direction_)
+ {
+ case TAO_AV_DIR_IN:
+ // Forward IN means we're the Source.
+ return TAO_AV_CONSUMER;
+ case TAO_AV_DIR_OUT:
+ // Forward out means we're the sink.
+ return TAO_AV_PRODUCER;
+ default:
+ return TAO_AV_INVALID_ROLE;
+ }
+ return TAO_AV_INVALID_ROLE;
+}
+
+int
+TAO_Reverse_FlowSpec_Entry::parse (const char *flowSpec_entry)
+{
+ TAO_Tokenizer tokenizer (flowSpec_entry,'\\');
+ this->flowname_ = tokenizer [TAO_AV_FLOWNAME];
+
+ if (tokenizer [TAO_AV_ADDRESS] != 0)
+ if (this->parse_address (tokenizer [TAO_AV_ADDRESS]) < 0)
+ return -1;
+
+ if (tokenizer [TAO_AV_FLOW_PROTOCOL] != 0)
+ if (this->parse_flow_protocol_string (tokenizer [TAO_AV_FLOW_PROTOCOL]) < 0)
+ return -1;
+
+ if (tokenizer [TAO_AV_DIRECTION] != 0)
+ this->set_direction (tokenizer [TAO_AV_DIRECTION]);
+
+ if (tokenizer [TAO_AV_FORMAT] != 0)
+ this->format_ = tokenizer [TAO_AV_FORMAT];
+
+ return 0;
+}
+
+
+char *
+TAO_Reverse_FlowSpec_Entry::entry_to_string (void)
+{
+ if (this->flowname_ == 0)
+ return 0;
+
+ ACE_NEW_RETURN (this->entry_,
+ char [BUFSIZ],
+ 0);
+
+
+ char address [BUFSIZ];
+ char address_str [BUFSIZ];
+ if (this->address_ != 0)
+ {
+
+ switch (this->protocol_)
+ {
+ case TAO_AV_Core::TAO_AV_RTP_UDP:
+ case TAO_AV_Core::TAO_AV_UDP:
+ case TAO_AV_Core::TAO_AV_UDP_MCAST:
+ case TAO_AV_Core::TAO_AV_TCP:
+ case TAO_AV_Core::TAO_AV_SFP_UDP:
+ {
+ ACE_INET_Addr *inet_addr = ACE_dynamic_cast (ACE_INET_Addr*,this->address_);
+ inet_addr->addr_to_string (address,BUFSIZ);
+ }
+ break;
+ default:
+ break;
+ }
+ ACE_CString cstring (address);
+ int colon_pos = cstring.find (':');
+ if (colon_pos != cstring.npos)
+ cstring[colon_pos] = ';';
+
+ ACE_OS::sprintf (address_str,"%s=%s",
+ this->carrier_protocol_,
+ cstring.c_str ());
+
+ }
+ else
+ ACE_OS::strcpy (address_str,"");
+ ACE_OS::sprintf (this->entry_,
+ "%s\\%s\\%s\\%s\\%s",
+ this->flowname_,
+ address_str,
+ this->flow_protocol_,
+ this->direction_str_,
+ this->format_);
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"entry_to_string: entry = %s\n",this->entry_));
+ return this->entry_;
+}
diff --git a/TAO/orbsvcs/orbsvcs/AV/FlowSpec_Entry.h b/TAO/orbsvcs/orbsvcs/AV/FlowSpec_Entry.h
new file mode 100644
index 00000000000..83ab0f9a4c0
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/AV/FlowSpec_Entry.h
@@ -0,0 +1,282 @@
+/* -*- C++ -*- */
+
+//$Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// ORBSVCS (AVStreams)
+//
+// = FILENAME
+// FlowSpec_Entry.h
+//
+// = AUTHOR
+// Nagarajan Surendran <naga@cs.wustl.edu>
+//
+//
+// ============================================================================
+
+#ifndef TAO_AV_FLOWSPEC_ENTRY_H
+#define TAO_AV_FLOWSPEC_ENTRY_H
+
+#include "orbsvcs/orbsvcs_export.h"
+#include "AV_Core.h"
+#include "ace/Addr.h"
+
+class TAO_ORBSVCS_Export TAO_Tokenizer
+{
+public:
+ TAO_Tokenizer (const char *string,char delimiter);
+ // constructor.
+
+ ~TAO_Tokenizer ();
+ // destructor.
+
+ int parse (const char *string,char delimiter);
+ // parses the string and tokenizes it.
+
+ char *token (void);
+ // Returns the next token.
+
+ int num_tokens (void);
+ // Number of tokens.
+
+ char *operator [] (size_t index) const;
+
+protected:
+ ACE_Array<char*> token_array_;
+ size_t count_;
+ size_t num_tokens_;
+ char string_ [BUFSIZ];
+};
+
+// Forward declaration.
+class TAO_AV_Transport;
+class TAO_AV_Flow_Handler;
+class TAO_AV_Protocol_Object;
+
+class TAO_ORBSVCS_Export TAO_FlowSpec_Entry
+{
+public:
+ // = TITLE
+ // An helper entry class in the flow spec sequence passed to bind_devs.
+ enum Direction
+ {
+ TAO_AV_INVALID = -1,
+ TAO_AV_DIR_IN = 0,
+ TAO_AV_DIR_OUT = 1
+ };
+
+ enum Role
+ {
+ TAO_AV_INVALID_ROLE = -1,
+ TAO_AV_PRODUCER = 0,
+ TAO_AV_CONSUMER = 1
+ };
+
+ TAO_FlowSpec_Entry (void);
+ // default constructor.
+
+ TAO_FlowSpec_Entry (const char *flowname,
+ const char *direction,
+ const char *format_name,
+ const char *flow_protocol,
+ const char *carrier_protocol,
+ ACE_Addr *address);
+ // constructor to construct an entry from the arguments.
+
+ TAO_FlowSpec_Entry (const char *flowname,
+ const char *direction,
+ const char *format_name,
+ const char *flow_protocol,
+ const char *address);
+
+ virtual int parse (const char* flowSpec_entry) = 0;
+ // construct the entry from a string specified by the flowSpec grammar.
+
+ virtual ~TAO_FlowSpec_Entry (void);
+ // virtual destructor.
+
+ int direction (void);
+ // accessor to the direction.
+
+ virtual Role role (void) = 0;
+ void role (Role role);
+ char * direction_str (void);
+ // string version of direction .
+
+ char *flow_protocol_str (void);
+ // accesor to the flow protocol string.
+
+ void flow_protocol_str (const char *flow_protocol_str);
+ // set the flow protocol string.
+
+ ACE_Addr *address (void);
+ // Address of the carrier protocol.
+
+ char * address_str (void);
+ // Address in string format i. hostname:port.
+
+ TAO_AV_Core::Protocol carrier_protocol (void);
+ // carrier protocol i.e TCP,UDP,RTP/UDP.
+
+ char * carrier_protocol_str (void);
+ // string version of carrier protocol.
+
+ char *format (void);
+ // format to be used for this flow.
+
+ const char *flowname (void);
+ // name of this flow.
+
+ virtual char *entry_to_string (void) = 0;
+ // converts the entry to a string.
+
+ int set_peer_addr (ACE_Addr *peer_addr);
+ ACE_Addr *get_peer_addr (void);
+ int set_local_addr (ACE_Addr *peer_addr);
+ ACE_Addr *get_local_addr (void);
+ char *get_local_addr_str (void);
+ TAO_AV_Transport *transport (void);
+ void transport (TAO_AV_Transport *transport);
+ TAO_AV_Flow_Handler* handler (void);
+ void handler (TAO_AV_Flow_Handler *handler);
+ TAO_AV_Protocol_Object* protocol_object (void);
+ void protocol_object (TAO_AV_Protocol_Object *object);
+
+ int parse_address (char *format_string);
+ // sets the address for this flow.
+
+ int is_multicast (void);
+ // returns true for a multicast address.
+
+protected:
+
+ int parse_flow_protocol_string (char *flow_options_string);
+ // parses the flow protocol string with tokens separated by :
+
+ int set_direction (char *direction_string);
+ // sets the direction flag.
+
+
+ int set_protocol (void);
+ // sets the protocol_ enum from the carrier_protocol_ string.
+
+ ACE_Addr *address_;
+ // Addr information for the carrier protocol.
+
+ char *address_str_;
+ // Addr in string format i.e hostname:port.
+
+ char *format_;
+ // format string.
+
+ Direction direction_;
+ // Direction of this flow.
+
+ char *direction_str_;
+ // string representation of the direction.
+
+ char *flowname_;
+ // name of this flow.
+
+ TAO_AV_Core::Protocol protocol_;
+ // name of the protocol used.
+
+ char *carrier_protocol_;
+ // carrier protocol string.
+
+ char *flow_protocol_;
+ // flow protocol string.
+
+ int use_flow_protocol_;
+ char *entry_;
+ // The flowspec entry;
+
+ int is_multicast_;
+ ACE_Addr *peer_addr_;
+ ACE_Addr *local_addr_;
+ TAO_AV_Transport *transport_;
+ TAO_AV_Flow_Handler *handler_;
+ TAO_AV_Protocol_Object *protocol_object_;
+ Role role_;
+};
+
+class TAO_ORBSVCS_Export TAO_Forward_FlowSpec_Entry
+ :public TAO_FlowSpec_Entry
+{
+public:
+ enum Position {TAO_AV_FLOWNAME = 0,
+ TAO_AV_DIRECTION = 1,
+ TAO_AV_FORMAT = 2,
+ TAO_AV_FLOW_PROTOCOL = 3,
+ TAO_AV_ADDRESS = 4};
+
+ TAO_Forward_FlowSpec_Entry (void);
+ // default constructor.
+
+ TAO_Forward_FlowSpec_Entry (const char *flowname,
+ const char *direction,
+ const char *format_name,
+ const char *flow_protocol,
+ const char *carrier_protocol,
+ ACE_Addr *address);
+ // constructor to construct an entry from the arguments.
+
+ TAO_Forward_FlowSpec_Entry (const char *flowname,
+ const char *direction,
+ const char *format_name,
+ const char *flow_protocol,
+ const char *address);
+
+ virtual char *entry_to_string (void);
+ // converts the entry to a string.
+
+ virtual Role role (void);
+ virtual int parse (const char* flowSpec_entry);
+ // construct the entry from a string specified by the flowSpec grammar.
+};
+
+class TAO_ORBSVCS_Export TAO_Reverse_FlowSpec_Entry
+ :public TAO_FlowSpec_Entry
+{
+public:
+ enum Position {TAO_AV_FLOWNAME = 0,
+ TAO_AV_ADDRESS = 1,
+ TAO_AV_FLOW_PROTOCOL = 2,
+ TAO_AV_DIRECTION = 3,
+ TAO_AV_FORMAT = 4};
+
+ TAO_Reverse_FlowSpec_Entry (void);
+ // default constructor.
+
+ TAO_Reverse_FlowSpec_Entry (const char *flowname,
+ const char *direction,
+ const char *format_name,
+ const char *flow_protocol,
+ const char *carrier_protocol,
+ ACE_Addr *address);
+ // constructor to construct an entry from the arguments.
+
+ TAO_Reverse_FlowSpec_Entry (const char *flowname,
+ const char *direction,
+ const char *format_name,
+ const char *flow_protocol,
+ const char *address);
+ // Takes the address in protocol=endpoint form.
+
+ virtual char *entry_to_string (void);
+ // converts the entry to a string.
+
+ virtual Role role (void);
+ virtual int parse (const char* flowSpec_entry);
+ // construct the entry from a string specified by the flowSpec grammar.
+};
+
+#include "Transport.h"
+
+#if defined (__ACE_INLINE__)
+#include "FlowSpec_Entry.i"
+#endif /* __ACE_INLINE__ */
+
+#endif /* TAO_AV_FLOWSPEC_ENTRY_H */
diff --git a/TAO/orbsvcs/orbsvcs/AV/FlowSpec_Entry.i b/TAO/orbsvcs/orbsvcs/AV/FlowSpec_Entry.i
new file mode 100644
index 00000000000..8522b9a55b4
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/AV/FlowSpec_Entry.i
@@ -0,0 +1,208 @@
+/* -*- C++ -*- */
+// $Id$
+
+// FlowSpec_Entry.i
+
+ACE_INLINE
+int
+TAO_FlowSpec_Entry::set_direction (char *direction)
+{
+ this->direction_str_ = direction;
+ if (direction == 0)
+ {
+ this->direction_ = TAO_AV_INVALID;
+ return -1;
+ }
+ if (ACE_OS::strcasecmp (direction,"in") == 0)
+ this->direction_ = TAO_AV_DIR_IN;
+ else if (ACE_OS::strcasecmp (direction,"out") == 0)
+ this->direction_ = TAO_AV_DIR_OUT;
+ return 0;
+}
+
+ACE_INLINE
+int
+TAO_FlowSpec_Entry::parse_flow_protocol_string (char *flow_string)
+{
+ if (flow_string == 0)
+ return 0;
+ if (ACE_OS::strncasecmp (flow_string,"sfp",3) == 0)
+ {
+ this->use_flow_protocol_ = 1;
+ // do some flow protocol processing.
+ this->flow_protocol_ = flow_string;
+ }
+ return 0;
+}
+
+ACE_INLINE
+int
+TAO_FlowSpec_Entry::direction (void)
+{
+ return this->direction_;
+}
+
+ACE_INLINE
+char *
+TAO_FlowSpec_Entry::direction_str (void)
+{
+ return this->direction_str_;
+}
+
+ACE_INLINE
+char *
+TAO_FlowSpec_Entry::flow_protocol_str (void)
+{
+ return this->flow_protocol_;
+}
+
+ACE_INLINE
+void
+TAO_FlowSpec_Entry::flow_protocol_str (const char *str)
+{
+ this->flow_protocol_ = CORBA::string_dup (str);
+}
+
+ACE_INLINE
+TAO_AV_Core::Protocol
+TAO_FlowSpec_Entry::carrier_protocol (void)
+{
+ return this->protocol_;
+}
+
+ACE_INLINE
+char *
+TAO_FlowSpec_Entry::carrier_protocol_str (void)
+{
+ return this->carrier_protocol_;
+}
+
+ACE_INLINE
+ACE_Addr *
+TAO_FlowSpec_Entry::address (void)
+{
+ return this->address_;
+}
+
+ACE_INLINE
+char *
+TAO_FlowSpec_Entry::address_str (void)
+{
+ return this->address_str_;
+}
+
+ACE_INLINE
+char*
+TAO_FlowSpec_Entry::format (void)
+{
+ return this->format_;
+}
+
+ACE_INLINE
+const char *
+TAO_FlowSpec_Entry::flowname (void)
+{
+ return this->flowname_;
+}
+
+
+ACE_INLINE
+int
+TAO_FlowSpec_Entry::set_peer_addr (ACE_Addr *peer_addr)
+{
+ this->peer_addr_ = peer_addr;
+ if (this->handler_ != 0)
+ this->handler_->set_remote_address (peer_addr);
+ return 0;
+}
+
+ACE_INLINE
+ACE_Addr *
+TAO_FlowSpec_Entry::get_peer_addr (void)
+{
+ return this->peer_addr_;
+}
+
+ACE_INLINE
+int
+TAO_FlowSpec_Entry::set_local_addr (ACE_Addr *local_addr)
+{
+ this->local_addr_ = local_addr;
+ return 0;
+}
+
+ACE_INLINE
+ACE_Addr*
+TAO_FlowSpec_Entry::get_local_addr (void)
+{
+ return this->local_addr_;
+}
+
+ACE_INLINE
+TAO_AV_Transport*
+TAO_FlowSpec_Entry::transport (void)
+{
+ return this->transport_;
+}
+
+ACE_INLINE
+void
+TAO_FlowSpec_Entry::transport (TAO_AV_Transport *transport)
+{
+ this->transport_ = transport;
+}
+
+ACE_INLINE
+TAO_AV_Flow_Handler *
+TAO_FlowSpec_Entry::handler (void)
+{
+ return this->handler_;
+}
+
+ACE_INLINE
+void
+TAO_FlowSpec_Entry::handler (TAO_AV_Flow_Handler *handler)
+{
+ this->handler_ = handler;
+// // Now remove the handler from the reactor if the handler is for a producer.
+// switch (this->role ())
+// {
+// case TAO_AV_PRODUCER:
+// {
+// ACE_Event_Handler *event_handler = handler->event_handler ();
+// int result = event_handler->reactor ()->remove_handler (event_handler,
+// ACE_Event_Handler::READ_MASK);
+// if (result < 0)
+// ACE_ERROR ((LM_ERROR,"TAO_FlowSpec_Entry::handler\n"));
+// break;
+// }
+// }
+}
+
+ACE_INLINE
+TAO_AV_Protocol_Object*
+TAO_FlowSpec_Entry::protocol_object (void)
+{
+ return this->protocol_object_;
+}
+
+ACE_INLINE
+void
+TAO_FlowSpec_Entry::protocol_object (TAO_AV_Protocol_Object *object)
+{
+ this->protocol_object_ = object;
+}
+
+ACE_INLINE
+int
+TAO_FlowSpec_Entry::is_multicast (void)
+{
+ return this->is_multicast_;
+}
+
+ACE_INLINE
+void
+TAO_FlowSpec_Entry::role (TAO_FlowSpec_Entry::Role role)
+{
+ this->role_ = role;
+}
diff --git a/TAO/orbsvcs/orbsvcs/AV/Flows_T.cpp b/TAO/orbsvcs/orbsvcs/AV/Flows_T.cpp
new file mode 100644
index 00000000000..77dc2ecea13
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/AV/Flows_T.cpp
@@ -0,0 +1,248 @@
+//$Id$
+
+#ifndef TAO_AV_FLOWS_T_C
+#define TAO_AV_FLOWS_T_C
+
+#include "Flows_T.h"
+
+
+// ------------------------------------------------------------
+// TAO_FDev
+// ------------------------------------------------------------
+
+// default constructor
+template <class T_Producer, class T_Consumer>
+TAO_FDev<T_Producer, T_Consumer>::TAO_FDev (void)
+{
+}
+
+template <class T_Producer, class T_Consumer>
+TAO_FDev<T_Producer, T_Consumer>::TAO_FDev (const char *flowname)
+ :flowname_ (flowname)
+{
+ ACE_DECLARE_NEW_CORBA_ENV;
+ ACE_TRY
+ {
+ CORBA::Any flowname_any;
+ flowname_any <<= flowname;
+ this->define_property ("Flow",
+ flowname_any,
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"TAO_FDev::TAO_FDev");
+ }
+ ACE_ENDTRY;
+ ACE_CHECK;
+}
+
+template <class T_Producer, class T_Consumer>
+TAO_FDev<T_Producer, T_Consumer>::~TAO_FDev (void)
+{
+ //no-op
+}
+
+template <class T_Producer, class T_Consumer>
+const char *
+TAO_FDev<T_Producer, T_Consumer>::flowname (void)
+{
+ return this->flowname_.in ();
+}
+
+template <class T_Producer, class T_Consumer>
+void
+TAO_FDev<T_Producer, T_Consumer>::flowname (const char *flow_name)
+{
+ ACE_DECLARE_NEW_CORBA_ENV;
+ ACE_TRY
+ {
+ CORBA::Any flowname_any;
+ flowname_any <<= flow_name;
+ this->define_property ("Flow",
+ flowname_any,
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"TAO_FDev::flowname");
+ }
+ ACE_ENDTRY;
+ ACE_CHECK;
+ this->flowname_ = flow_name;
+}
+
+template <class T_Producer, class T_Consumer>
+AVStreams::FlowProducer_ptr
+TAO_FDev<T_Producer, T_Consumer>::create_producer (AVStreams::FlowConnection_ptr the_requester,
+ AVStreams::QoS & the_qos,
+ CORBA::Boolean_out met_qos,
+ char *& named_fdev,
+ CORBA::Environment &ACE_TRY_ENV)
+ ACE_THROW_SPEC ((CORBA::SystemException,
+ AVStreams::streamOpFailed,
+ AVStreams::streamOpDenied,
+ AVStreams::notSupported,
+ AVStreams::QoSRequestFailed))
+{
+ // call the bridge method.
+ return this->make_producer (the_requester,
+ the_qos,
+ met_qos,
+ named_fdev,
+ ACE_TRY_ENV);
+}
+
+template <class T_Producer, class T_Consumer>
+// hook for the applications to override the creation process.
+AVStreams::FlowProducer_ptr
+TAO_FDev<T_Producer, T_Consumer>::make_producer (AVStreams::FlowConnection_ptr /* the_requester */,
+ AVStreams::QoS & /* the_qos */,
+ CORBA::Boolean_out /* met_qos */,
+ char *& /* named_fdev */,
+ CORBA::Environment &ACE_TRY_ENV)
+{
+ AVStreams::FlowProducer_ptr producer = AVStreams::FlowProducer::_nil ();
+ ACE_TRY
+ {
+ // Activate the producer implementation under the Root POA.
+ T_Producer *producer_i;
+ ACE_NEW_RETURN (producer_i,
+ T_Producer,
+ 0);
+ this->producer_list_.insert_tail (producer_i);
+ producer = producer_i->_this (ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"TAO_FDev::make_producer");
+ return producer;
+ }
+ ACE_ENDTRY;
+ ACE_CHECK_RETURN (producer);
+ return producer;
+}
+
+template <class T_Producer, class T_Consumer>
+// hook for the applications to override the consumer creation.
+AVStreams::FlowConsumer_ptr
+TAO_FDev<T_Producer, T_Consumer>::make_consumer (AVStreams::FlowConnection_ptr /* the_requester */,
+ AVStreams::QoS & /* the_qos */,
+ CORBA::Boolean_out /* met_qos */,
+ char *& /* named_fdev */,
+ CORBA::Environment &ACE_TRY_ENV)
+{
+ AVStreams::FlowConsumer_ptr consumer = AVStreams::FlowConsumer::_nil ();
+ ACE_TRY
+ {
+ // Activate the consumer implementation under the Root POA.
+ T_Consumer *consumer_i;
+ ACE_NEW_RETURN (consumer_i,
+ T_Consumer,
+ 0);
+ this->consumer_list_.insert_tail (consumer_i);
+ consumer = consumer_i->_this (ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"TAO_FDev::make_consumer");
+ return consumer;
+ }
+ ACE_ENDTRY;
+ ACE_CHECK_RETURN (consumer);
+ return consumer;
+}
+
+template <class T_Producer, class T_Consumer>
+AVStreams::FlowConsumer_ptr
+TAO_FDev<T_Producer, T_Consumer>::create_consumer (AVStreams::FlowConnection_ptr the_requester,
+ AVStreams::QoS & the_qos,
+ CORBA::Boolean_out met_qos,
+ char *& named_fdev,
+ CORBA::Environment &ACE_TRY_ENV)
+ ACE_THROW_SPEC ((CORBA::SystemException,
+ AVStreams::streamOpFailed,
+ AVStreams::streamOpDenied,
+ AVStreams::notSupported,
+ AVStreams::QoSRequestFailed))
+{
+ return this->make_consumer (the_requester,
+ the_qos,
+ met_qos,
+ named_fdev,
+ ACE_TRY_ENV);
+}
+
+template <class T_Producer, class T_Consumer>
+// not implemented yet.
+AVStreams::FlowConnection_ptr
+TAO_FDev<T_Producer, T_Consumer>::bind (AVStreams::FDev_ptr peer_device,
+ AVStreams::QoS & the_qos,
+ CORBA::Boolean_out is_met,
+ CORBA::Environment &ACE_TRY_ENV)
+ ACE_THROW_SPEC ((CORBA::SystemException,
+ AVStreams::streamOpFailed,
+ AVStreams::QoSRequestFailed))
+{
+ ACE_UNUSED_ARG (peer_device);
+ ACE_UNUSED_ARG (the_qos);
+ ACE_UNUSED_ARG (is_met);
+ ACE_UNUSED_ARG (ACE_TRY_ENV);
+ return 0;
+}
+
+template <class T_Producer, class T_Consumer>
+// multicast is not supported yet.
+AVStreams::FlowConnection_ptr
+TAO_FDev<T_Producer, T_Consumer>::bind_mcast (AVStreams::FDev_ptr first_peer,
+ AVStreams::QoS & the_qos,
+ CORBA::Boolean_out is_met,
+ CORBA::Environment &ACE_TRY_ENV)
+ ACE_THROW_SPEC ((CORBA::SystemException,
+ AVStreams::streamOpFailed,
+ AVStreams::QoSRequestFailed))
+{
+ ACE_UNUSED_ARG (first_peer);
+ ACE_UNUSED_ARG (the_qos);
+ ACE_UNUSED_ARG (is_met);
+ ACE_UNUSED_ARG (ACE_TRY_ENV);
+ return 0;
+}
+
+template <class T_Producer, class T_Consumer>
+void
+TAO_FDev<T_Producer, T_Consumer>::destroy (AVStreams::FlowEndPoint_ptr /* the_ep */,
+ const char * /* fdev_name */,
+ CORBA::Environment &/*ACE_TRY_ENV*/)
+ ACE_THROW_SPEC ((CORBA::SystemException,
+ AVStreams::notSupported))
+{
+ // @@ Shouldn't the parameters be made use of!
+ // Destroy/delete all the producers and consumers.
+ PRODUCER_LIST_ITERATOR producer_list_iterator (this->producer_list_);
+ TAO_FlowProducer *producer_i = 0;
+
+ while ((producer_i = producer_list_iterator.next ()) != 0)
+ {
+ deactivate_servant (producer_i);
+ delete producer_i;
+ }
+
+ CONSUMER_LIST_ITERATOR consumer_list_iterator (this->consumer_list_);
+ TAO_FlowConsumer *consumer_i = 0;
+
+ while ((consumer_i = consumer_list_iterator.next ()) != 0)
+ {
+ deactivate_servant (producer_i);
+ delete consumer_i;
+ }
+ int result = deactivate_servant (this);
+ if (result < 0)
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"TAO_StreamEndPoint::destroy failed\n"));
+}
+
+#endif /* TAO_AV_FLOWS_T_C */
diff --git a/TAO/orbsvcs/orbsvcs/AV/Flows_T.h b/TAO/orbsvcs/orbsvcs/AV/Flows_T.h
new file mode 100644
index 00000000000..268ce852846
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/AV/Flows_T.h
@@ -0,0 +1,126 @@
+/* -*- C++ -*- */
+
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// ORBSVCS AVStreams
+//
+// = FILENAME
+// Flows_T.h
+//
+// = AUTHOR
+// Nagarajan Surendran <naga@cs.wustl.edu>
+//
+//
+// ============================================================================
+
+#ifndef TAO_AV_FLOWS_T_H
+#define TAO_AV_FLOWS_T_H
+
+#include "AVStreams_i.h"
+
+template <class T_Producer, class T_Consumer>
+class TAO_ORBSVCS_Export TAO_FDev :
+ public virtual POA_AVStreams::FDev,
+ public virtual TAO_PropertySet,
+ public virtual PortableServer::RefCountServantBase
+{
+public:
+ TAO_FDev (void);
+ // default constructor
+
+ TAO_FDev (const char *flowname);
+ // constructor taking a flowname.
+
+ ~TAO_FDev (void);
+ // Destructor..
+
+ const char *flowname (void);
+ void flowname (const char *flowname);
+ // set/get the flowname.
+ AVStreams::FlowProducer_ptr create_producer (AVStreams::FlowConnection_ptr the_requester,
+ AVStreams::QoS & the_qos,
+ CORBA::Boolean_out met_qos,
+ char *& named_fdev,
+ CORBA::Environment &env = CORBA::Environment::default_environment ())
+ ACE_THROW_SPEC ((CORBA::SystemException,
+ AVStreams::streamOpFailed,
+ AVStreams::streamOpDenied,
+ AVStreams::notSupported,
+ AVStreams::QoSRequestFailed));
+ // create a flow producer object.
+
+ virtual AVStreams::FlowProducer_ptr make_producer (AVStreams::FlowConnection_ptr the_requester,
+ AVStreams::QoS & the_qos,
+ CORBA::Boolean_out met_qos,
+ char *& named_fdev,
+ CORBA::Environment &env = CORBA::Environment::default_environment ());
+ // bridge method for the application to override the producer object
+ // creation. Default implementation creates a TAO_FlowProducer.
+
+ virtual AVStreams::FlowConsumer_ptr create_consumer (AVStreams::FlowConnection_ptr the_requester,
+ AVStreams::QoS & the_qos,
+ CORBA::Boolean_out met_qos,
+ char *& named_fdev,
+ CORBA::Environment &env = CORBA::Environment::default_environment ())
+ ACE_THROW_SPEC ((CORBA::SystemException,
+ AVStreams::streamOpFailed,
+ AVStreams::streamOpDenied,
+ AVStreams::notSupported,
+ AVStreams::QoSRequestFailed));
+ // create a flow consumer object.
+
+ virtual AVStreams::FlowConsumer_ptr make_consumer (AVStreams::FlowConnection_ptr the_requester,
+ AVStreams::QoS & the_qos,
+ CORBA::Boolean_out met_qos,
+ char *& named_fdev,
+ CORBA::Environment &env = CORBA::Environment::default_environment ());
+ // bridge method for the application to override the consumer object
+ // creation. Default implementation creates a TAO_FlowConsumer.
+
+ virtual AVStreams::FlowConnection_ptr bind (AVStreams::FDev_ptr peer_device,
+ AVStreams::QoS & the_qos,
+ CORBA::Boolean_out is_met,
+ CORBA::Environment &env = CORBA::Environment::default_environment ())
+ ACE_THROW_SPEC ((CORBA::SystemException,
+ AVStreams::streamOpFailed,
+ AVStreams::QoSRequestFailed));
+ // bind this FDev with another FDev.
+
+ virtual AVStreams::FlowConnection_ptr bind_mcast (AVStreams::FDev_ptr first_peer,
+ AVStreams::QoS & the_qos,
+ CORBA::Boolean_out is_met,
+ CORBA::Environment &env = CORBA::Environment::default_environment ())
+ ACE_THROW_SPEC ((CORBA::SystemException,
+ AVStreams::streamOpFailed,
+ AVStreams::QoSRequestFailed));
+ // multicast bind is not implemented yet.
+
+ virtual void destroy (AVStreams::FlowEndPoint_ptr the_ep,
+ const char * fdev_name,
+ CORBA::Environment &env =
+ CORBA::Environment::default_environment ())
+ ACE_THROW_SPEC ((CORBA::SystemException,
+ AVStreams::notSupported));
+ // destroys this FDev.
+
+protected:
+ ACE_DLList <TAO_FlowProducer> producer_list_;
+ typedef ACE_DLList_Iterator <TAO_FlowProducer> PRODUCER_LIST_ITERATOR;
+ ACE_DLList <TAO_FlowConsumer> consumer_list_;
+ typedef ACE_DLList_Iterator <TAO_FlowConsumer> CONSUMER_LIST_ITERATOR;
+ CORBA::String_var flowname_;
+};
+
+
+#if defined (ACE_TEMPLATES_REQUIRE_SOURCE)
+#include "Flows_T.cpp"
+#endif /*ACE_TEMPLATES_REQUIRE_SOURCE */
+
+#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA)
+#pragma implementation ("Flows_T.cpp")
+#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */
+
+#endif /* TAO_AV_FLOWS_T_H */
diff --git a/TAO/orbsvcs/orbsvcs/AV/MCast.cpp b/TAO/orbsvcs/orbsvcs/AV/MCast.cpp
new file mode 100644
index 00000000000..6deb81ea0af
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/AV/MCast.cpp
@@ -0,0 +1,207 @@
+// $Id$
+
+#include "MCast.h"
+#include "Nil.h"
+#include "AVStreams_i.h"
+
+//------------------------------------------------------------
+//TAO_AV_UDP_MCast_Flow_Handler
+//------------------------------------------------------------
+
+TAO_AV_UDP_MCast_Flow_Handler::TAO_AV_UDP_MCast_Flow_Handler (void)
+{
+ ACE_NEW (transport_,
+ TAO_AV_UDP_MCast_Transport (this));
+ ACE_NEW (dgram_mcast_,
+ ACE_SOCK_Dgram_Mcast);
+}
+
+TAO_AV_UDP_MCast_Flow_Handler::~TAO_AV_UDP_MCast_Flow_Handler (void)
+{
+ delete this->transport_;
+ delete this->dgram_mcast_;
+}
+
+
+int
+TAO_AV_UDP_MCast_Flow_Handler::handle_input (ACE_HANDLE /*fd*/)
+{
+ this->protocol_object_->handle_input ();
+ return 0;
+}
+
+int
+TAO_AV_UDP_MCast_Flow_Handler::handle_timeout (const ACE_Time_Value &tv,
+ const void *arg)
+{
+ return TAO_AV_Flow_Handler::handle_timeout (tv,arg);
+}
+
+ACE_HANDLE
+TAO_AV_UDP_MCast_Flow_Handler::get_handle (void) const
+{
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"TAO_AV_UDP_MCast_Flow_Handler::get_handle "));
+ return this->get_mcast_socket ()->get_handle () ;
+}
+
+
+//------------------------------------------------------------
+// TAO_AV_UDP_MCast_Transport
+//------------------------------------------------------------
+
+TAO_AV_UDP_MCast_Transport::TAO_AV_UDP_MCast_Transport (void)
+ :handler_ (0)
+{
+}
+
+TAO_AV_UDP_MCast_Transport::TAO_AV_UDP_MCast_Transport (TAO_AV_UDP_MCast_Flow_Handler *handler)
+ :handler_ (handler)
+{
+}
+
+TAO_AV_UDP_MCast_Transport::~TAO_AV_UDP_MCast_Transport (void)
+{
+}
+
+int
+TAO_AV_UDP_MCast_Transport::open (ACE_Addr */*address*/)
+{
+ return 0;
+}
+
+int
+TAO_AV_UDP_MCast_Transport::close (void)
+{
+ return 0;
+}
+
+
+ACE_Addr*
+TAO_AV_UDP_MCast_Transport::get_peer_addr (void)
+{
+ return &this->peer_addr_;
+}
+
+ACE_Addr*
+TAO_AV_UDP_MCast_Transport::get_local_addr (void)
+{
+ this->handler_->get_mcast_socket ()->get_local_addr (this->local_addr_);
+ return &this->local_addr_;
+}
+
+ssize_t
+TAO_AV_UDP_MCast_Transport::send (const ACE_Message_Block *mblk, ACE_Time_Value *)
+{
+ // For the most part this was copied from GIOP::send_request and
+ // friends.
+
+ iovec iov[IOV_MAX];
+ int iovcnt = 0;
+ ssize_t n = 0;
+ ssize_t nbytes = 0;
+
+ for (const ACE_Message_Block *i = mblk;
+ i != 0;
+ i = i->cont ())
+ {
+ // Make sure there is something to send!
+ if (i->length () > 0)
+ {
+ iov[iovcnt].iov_base = i->rd_ptr ();
+ iov[iovcnt].iov_len = i->length ();
+ iovcnt++;
+
+ // The buffer is full make a OS call. @@ TODO this should
+ // be optimized on a per-platform basis, for instance, some
+ // platforms do not implement writev() there we should copy
+ // the data into a buffer and call send_n(). In other cases
+ // there may be some limits on the size of the iovec, there
+ // we should set IOV_MAX to that limit.
+ if (iovcnt == IOV_MAX)
+ {
+ n = this->handler_->get_mcast_socket ()->send ((const iovec *) iov,
+ iovcnt);
+
+ if (n < 1)
+ return n;
+
+ nbytes += n;
+ iovcnt = 0;
+ }
+ }
+ }
+
+ // Check for remaining buffers to be sent!
+ if (iovcnt != 0)
+ {
+ n = this->handler_->get_mcast_socket ()->send ((const iovec *) iov,
+ iovcnt);
+ if (n < 1)
+ return n;
+
+ nbytes += n;
+ }
+
+ return nbytes;
+}
+
+ssize_t
+TAO_AV_UDP_MCast_Transport::send (const char *buf,
+ size_t len,
+ ACE_Time_Value *)
+{
+// if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"TAO_AV_UDP_MCast_Transport::send "));
+// char addr [BUFSIZ];
+// this->peer_addr_.addr_to_string (addr,BUFSIZ);
+// if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"to %s\n",addr));
+
+ return this->handler_->get_mcast_socket ()->send (buf, len);
+}
+
+ssize_t
+TAO_AV_UDP_MCast_Transport::send (const iovec *iov,
+ int iovcnt,
+ ACE_Time_Value *)
+{
+ return this->handler_->get_mcast_socket ()->send (iov,
+ iovcnt,
+ 0);
+
+}
+
+ACE_INLINE int
+TAO_AV_UDP_MCast_Transport::mtu (void)
+{
+ return ACE_MAX_DGRAM_SIZE;
+}
+
+
+ACE_INLINE ssize_t
+TAO_AV_UDP_MCast_Transport::recv (char *buf,
+ size_t len,
+ ACE_Time_Value *)
+{
+ return this->handler_->get_mcast_socket ()->recv (buf, len,this->peer_addr_);
+}
+
+ACE_INLINE ssize_t
+TAO_AV_UDP_MCast_Transport::recv (char *buf,
+ size_t len,
+ int flags,
+ ACE_Time_Value *timeout)
+{
+ return this->handler_->get_mcast_socket ()->recv (buf,
+ len,
+ this->peer_addr_,
+ flags,
+ timeout);
+}
+
+
+ssize_t
+TAO_AV_UDP_MCast_Transport::recv (iovec *iov,
+ int /*iovcnt*/,
+ ACE_Time_Value *timeout)
+{
+ return handler_->get_mcast_socket ()->recv (iov,this->peer_addr_,0,timeout);
+}
diff --git a/TAO/orbsvcs/orbsvcs/AV/MCast.h b/TAO/orbsvcs/orbsvcs/AV/MCast.h
new file mode 100644
index 00000000000..530163eaa49
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/AV/MCast.h
@@ -0,0 +1,110 @@
+/* -*- C++ -*- */
+
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// ORBSVCS AVStreams
+//
+// = FILENAME
+// MCast.h
+//
+// = AUTHOR
+// Nagarajan Surendran <naga@cs.wustl.edu>
+//
+//
+// ============================================================================
+
+#ifndef TAO_AV_MCAST_H
+#define TAO_AV_MCAST_H
+
+#include "FlowSpec_Entry.h"
+#include "Protocol_Factory.h"
+#include "ace/INET_Addr.h"
+#include "ace/SOCK_Dgram_Mcast.h"
+
+class TAO_AV_UDP_MCast_Flow_Handler;
+
+class TAO_AV_UDP_MCast_Transport
+ :public TAO_AV_Transport
+{
+ // = TITLE
+ // A transport abstraction for Multicast dgram sockets.
+ //
+ // = DESCRIPTION
+ // Uses the ACE_SOCK_Dgram_Mcast to send the data.
+public:
+ TAO_AV_UDP_MCast_Transport (void);
+
+ TAO_AV_UDP_MCast_Transport (TAO_AV_UDP_MCast_Flow_Handler *handler);
+
+ virtual ~TAO_AV_UDP_MCast_Transport (void);
+
+ virtual int open (ACE_Addr *address);
+
+ virtual int close (void);
+
+ virtual int mtu (void);
+
+ virtual ACE_Addr *get_peer_addr (void);
+ virtual ACE_Addr *get_local_addr (void);
+ virtual ssize_t send (const ACE_Message_Block *mblk,
+ ACE_Time_Value *s = 0);
+ // Write the complete Message_Block chain to the connection.
+
+ virtual ssize_t send (const char *buf,
+ size_t len,
+ ACE_Time_Value *s = 0);
+ // Write the contents of the buffer of length len to the connection.
+
+ virtual ssize_t send (const iovec *iov,
+ int iovcnt,
+ ACE_Time_Value *s = 0);
+ // Write the contents of iovcnt iovec's to the connection.
+
+ virtual ssize_t recv (char *buf,
+ size_t len,
+ ACE_Time_Value *s = 0);
+ // Read len bytes from into buf.
+
+ virtual ssize_t recv (char *buf,
+ size_t len,
+ int flags,
+ ACE_Time_Value *s = 0);
+ // Read len bytes from into buf using flags.
+
+ virtual ssize_t recv (iovec *iov,
+ int iovcnt,
+ ACE_Time_Value *s = 0);
+ // Read received data into the iovec buffers.
+protected:
+ TAO_AV_UDP_MCast_Flow_Handler *handler_;
+ ACE_INET_Addr peer_addr_;
+ ACE_INET_Addr local_addr_;
+};
+
+class TAO_AV_UDP_MCast_Flow_Handler
+ :public virtual TAO_AV_Flow_Handler,
+ public virtual ACE_Event_Handler
+{
+public:
+ TAO_AV_UDP_MCast_Flow_Handler (void);
+ // Ctor
+ ~TAO_AV_UDP_MCast_Flow_Handler (void);
+ // Dtor
+ virtual ACE_HANDLE get_handle (void) const;
+ virtual int handle_input (ACE_HANDLE fd);
+ virtual int handle_timeout (const ACE_Time_Value &tv, const void *arg = 0);
+ ACE_SOCK_Dgram_Mcast *get_mcast_socket (void) const;
+ virtual ACE_Event_Handler* event_handler (void){ return this; }
+protected:
+ ACE_INET_Addr peer_addr_;
+ ACE_SOCK_Dgram_Mcast *dgram_mcast_;
+};
+
+#if defined(__ACE_INLINE__)
+#include "MCast.i"
+#endif /* __ACE_INLINE__ */
+
+#endif /* TAO_AV_MCAST_H */
diff --git a/TAO/orbsvcs/orbsvcs/AV/MCast.i b/TAO/orbsvcs/orbsvcs/AV/MCast.i
new file mode 100644
index 00000000000..29ea2a73d4f
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/AV/MCast.i
@@ -0,0 +1,13 @@
+// $Id$
+//------------------------------------------------------------
+// TAO_AV_UDP_MCast_Flow_Handler
+//-----------------------------------------------------------
+ACE_INLINE ACE_SOCK_Dgram_Mcast *
+TAO_AV_UDP_MCast_Flow_Handler::get_mcast_socket (void) const
+{
+ return this->dgram_mcast_;
+}
+
+
+
+
diff --git a/TAO/orbsvcs/orbsvcs/AV/Nil.cpp b/TAO/orbsvcs/orbsvcs/AV/Nil.cpp
new file mode 100644
index 00000000000..d084789c6b3
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/AV/Nil.cpp
@@ -0,0 +1,45 @@
+//$Id$
+
+#include "Nil.h"
+#include "FlowSpec_Entry.h"
+
+// //------------------------------------------------------------
+// // TAO_AV_UDP_MCast_Object
+// //------------------------------------------------------------
+
+
+// TAO_AV_UDP_MCast_Object::TAO_AV_UDP_MCast_Object (TAO_AV_Callback *callback,
+// TAO_AV_Transport *transport)
+// :TAO_AV_Protocol_Object (callback,transport)
+// {
+// }
+
+// TAO_AV_UDP_MCast_Object::~TAO_AV_UDP_MCast_Object (void)
+// {
+// //no-op
+// }
+
+// int
+// TAO_AV_UDP_MCast_Object::send_frame (ACE_Message_Block *frame,
+// TAO_AV_frame_info *frame_info)
+// {
+// int result = this->transport_->send (frame);
+// if (result < 0)
+// return result;
+// return 0;
+// }
+
+// int
+// TAO_AV_UDP_MCast_Object::send_frame (const iovec *iov,
+// int iovcnt,
+// TAO_AV_frame_info *frame_info)
+// {
+// return this->transport_->send (iov,iovcnt);
+// }
+
+// int
+// TAO_AV_UDP_MCast_Object::end_stream (void)
+// {
+// this->callback_->handle_end_stream ();
+// return 0;
+// }
diff --git a/TAO/orbsvcs/orbsvcs/AV/Nil.h b/TAO/orbsvcs/orbsvcs/AV/Nil.h
new file mode 100644
index 00000000000..350b038ad07
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/AV/Nil.h
@@ -0,0 +1,45 @@
+/* -*- C++ -*- */
+
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// ORBSVCS AVStreams
+//
+// = FILENAME
+// Nil.h
+//
+// = AUTHOR
+// Nagarajan Surendran <naga@cs.wustl.edu>
+//
+//
+// ============================================================================
+
+#ifndef TAO_AV_NIL_H
+#define TAO_AV_NIL_H
+
+#include "Policy.h"
+
+// class TAO_ORBSVCS_Export TAO_AV_UDP_MCast_Object : public TAO_AV_Protocol_Object
+// {
+// public:
+// TAO_AV_UDP_MCast_Object (TAO_AV_Callback *callback,
+// TAO_AV_Transport *transport = 0);
+
+// virtual ~TAO_AV_UDP_MCast_Object (void);
+// // Dtor
+
+// virtual int send_frame (ACE_Message_Block *frame,
+// TAO_AV_frame_info *frame_info = 0);
+// // send a data frame.
+
+// virtual int send_frame (const iovec *iov,
+// int iovcnt,
+// TAO_AV_frame_info *frame_info = 0);
+
+// virtual int end_stream (void);
+// // end the stream.
+// };
+
+#endif /* TAO_AV_NIL_H */
diff --git a/TAO/orbsvcs/orbsvcs/AV/Policy.cpp b/TAO/orbsvcs/orbsvcs/AV/Policy.cpp
new file mode 100644
index 00000000000..eb86ba138fa
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/AV/Policy.cpp
@@ -0,0 +1,148 @@
+// $Id$
+
+#include "Policy.h"
+#include "FlowSpec_Entry.h"
+
+TAO_AV_Policy::TAO_AV_Policy (CORBA::ULong type)
+ :type_ (type)
+{
+}
+
+
+TAO_AV_SSRC_Policy::TAO_AV_SSRC_Policy (CORBA::ULong ssrc)
+ :TAO_AV_Policy (TAO_AV_SSRC_POLICY),
+ ssrc_ (ssrc)
+{
+}
+
+
+TAO_AV_Payload_Type_Policy::TAO_AV_Payload_Type_Policy (int payload_type)
+ :TAO_AV_Policy (TAO_AV_PAYLOAD_TYPE_POLICY),
+ payload_type_ (payload_type)
+{
+}
+
+// TAO_AV_RTP_Sdes_Policy
+TAO_AV_RTCP_Sdes_Policy::TAO_AV_RTCP_Sdes_Policy (void)
+ :TAO_AV_Policy (TAO_AV_RTCP_SDES_POLICY)
+{
+}
+
+TAO_AV_SFP_Credit_Policy::TAO_AV_SFP_Credit_Policy (void)
+ :TAO_AV_Policy (TAO_AV_SFP_CREDIT_POLICY)
+{
+}
+
+// TAO_AV_Callback
+TAO_AV_Callback::TAO_AV_Callback (void)
+ :protocol_object_ (0)
+{
+}
+
+int
+TAO_AV_Callback::open (TAO_AV_Protocol_Object *object,
+ TAO_AV_Flow_Handler *handler)
+{
+ this->protocol_object_ = object;
+ this->handler_ = handler;
+ handler->callback (this);
+ return 0;
+}
+
+int
+TAO_AV_Callback::handle_start (void)
+{
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"TAO_AV_Callback::handle_start\n"));
+ return -1;
+}
+
+int
+TAO_AV_Callback::handle_stop (void)
+{
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"TAO_AV_Callback::handle_stop\n"));
+ return -1;
+}
+
+int
+TAO_AV_Callback::receive_frame (ACE_Message_Block */*frame*/,
+ TAO_AV_frame_info *,
+ const ACE_Addr &)
+{
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"TAO_AV_Callback::receive_frame\n"));
+ return -1;
+}
+
+int
+TAO_AV_Callback::receive_control_frame (ACE_Message_Block *,
+ const ACE_Addr& )
+{
+ return 0;
+}
+
+int
+TAO_AV_Callback::handle_destroy (void)
+{
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"TAO_AV_Callback::handle_end_stream\n"));
+ return -1;
+}
+
+void
+TAO_AV_Callback::get_timeout (ACE_Time_Value *&tv,
+ void *&arg)
+{
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"TAO_AV_Callback::get_timeout\n"));
+}
+
+int
+TAO_AV_Callback::handle_timeout (void *arg)
+{
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"TAO_AV_Callback::handle_timeout\n"));
+ return 0;
+}
+
+TAO_AV_PolicyList
+TAO_AV_Callback::get_policies (void)
+{
+ TAO_AV_PolicyList list;
+ return list;
+}
+
+// TAO_AV_Transport*
+// TAO_AV_Callback::transport (void)
+// {
+// return this->transport_;
+// }
+
+// void
+// TAO_AV_Callback::transport (TAO_AV_Transport *transport)
+// {
+// this->transport_ = transport;
+// }
+
+TAO_AV_Protocol_Object*
+TAO_AV_Callback::protocol_object (void)
+{
+ return this->protocol_object_;
+}
+
+// void
+// TAO_AV_Callback::protocol_object (TAO_AV_Protocol_Object *object)
+// {
+// this->protocol_object_ = object;
+// }
+
+int
+TAO_AV_Callback::schedule_timer (void)
+{
+ return this->handler_->schedule_timer ();
+}
+
+#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
+
+template class TAO_Unbounded_Sequence<TAO_AV_Policy*>;
+
+#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
+
+#pragma instantiate TAO_Unbounded_Sequence<TAO_AV_Policy*>
+
+#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */
diff --git a/TAO/orbsvcs/orbsvcs/AV/Policy.h b/TAO/orbsvcs/orbsvcs/AV/Policy.h
new file mode 100644
index 00000000000..cefec9b2725
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/AV/Policy.h
@@ -0,0 +1,163 @@
+/* -*- C++ -*- */
+
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// ORBSVCS AVStreams
+//
+// = FILENAME
+// Policy.h
+//
+// = AUTHOR
+// Nagarajan Surendran <naga@cs.wustl.edu>
+//
+//
+// ============================================================================
+
+#ifndef TAO_AV_POLICY_H
+#define TAO_AV_POLICY_H
+
+#include "ace/Addr.h"
+#include "tao/TAO.h"
+#include "tao/debug.h"
+#include "orbsvcs/orbsvcs_export.h"
+
+struct TAO_AV_frame_info
+{
+ CORBA::Boolean boundary_marker;
+ CORBA::Octet format;
+ // @@ Shouldn't this be a string.
+ CORBA::ULong timestamp;
+ CORBA::ULong ssrc;
+ CORBA::ULong sequence_num;
+};
+
+#define TAO_AV_SSRC_POLICY 100
+#define TAO_AV_PAYLOAD_TYPE_POLICY 101
+#define TAO_AV_TIMEOUT_POLICY 102
+#define TAO_AV_RTCP_SDES_POLICY 103
+#define TAO_AV_SFP_CREDIT_POLICY 104
+
+struct TAO_AV_RTCP_Sdes
+{
+ CORBA::String_var name_;
+ CORBA::String_var value_;
+};
+
+class TAO_ORBSVCS_Export TAO_AV_Policy
+{
+public:
+ TAO_AV_Policy (CORBA::ULong type);
+ CORBA::ULong type (void);
+protected:
+ CORBA::ULong type_;
+};
+
+class TAO_AV_SSRC_Policy
+ :public TAO_AV_Policy
+{
+public:
+ TAO_AV_SSRC_Policy (CORBA::ULong ssrc = 0);
+ CORBA::ULong value (void);
+ void value (CORBA::ULong ssrc);
+protected:
+ CORBA::ULong ssrc_;
+};
+
+class TAO_AV_Payload_Type_Policy
+ :public TAO_AV_Policy
+{
+public:
+ TAO_AV_Payload_Type_Policy (int payload_type = -1);
+ int value (void);
+ void value (int pt);
+protected:
+ int payload_type_;
+};
+
+
+class TAO_AV_RTCP_Sdes_Policy
+ :public TAO_AV_Policy
+{
+public:
+ TAO_AV_RTCP_Sdes_Policy (void);
+ TAO_AV_RTCP_Sdes &value (void);
+ void value (const TAO_AV_RTCP_Sdes& sdes_val);
+protected:
+ TAO_AV_RTCP_Sdes sdes_;
+};
+
+class TAO_AV_SFP_Credit_Policy : public TAO_AV_Policy
+{
+public:
+ TAO_AV_SFP_Credit_Policy (void);
+ int value (void);
+ void value (int val);
+protected:
+ int value_;
+};
+
+typedef TAO_Unbounded_Sequence<TAO_AV_Policy*> TAO_AV_PolicyList;
+
+class TAO_AV_Protocol_Object;
+class TAO_AV_Transport;
+class TAO_AV_Flow_Handler;
+
+class TAO_AV_Callback
+{
+ // = TITLE
+ // Callback class that the user will be implementing for receiving
+ // frames from the network and also for timer events.
+public:
+ TAO_AV_Callback (void);
+
+ int open (TAO_AV_Protocol_Object *object,
+ TAO_AV_Flow_Handler *handler);
+ // Called for opening the callback.
+
+ virtual int handle_start (void);
+ // Called during Streamctrl->start.
+
+ virtual int handle_stop (void);
+ // Called during Streamctrl->stop.
+
+ virtual int handle_timeout (void *arg);
+ // Called during timeout for Flow Producers.
+
+ virtual int schedule_timer (void);
+
+ virtual int receive_frame (ACE_Message_Block *frame,
+ TAO_AV_frame_info *frame_info = 0,
+ const ACE_Addr &address = ACE_Addr::sap_any);
+
+ // Called when a frame arrives for a FlowConsumer.
+
+ virtual int receive_control_frame (ACE_Message_Block *frame,
+ const ACE_Addr &address = ACE_Addr::sap_any);
+ // address from which the frame was received.
+
+ virtual int handle_destroy (void);
+ // Called during Streamctrl->destroy i.e tear_down of the stream
+
+ virtual void get_timeout (ACE_Time_Value *&tv,
+ void *&arg);
+ // Called to get the timeout. If tv is 0 then the framework stop
+ // calling this. This will be called during the start of the frame
+ // and also if schedule_timer is called to get the timeout.
+
+ TAO_AV_Protocol_Object *protocol_object (void);
+ // Accessor to protocol object.
+
+ virtual TAO_AV_PolicyList get_policies (void);
+ // get the policies for the protocol object.
+protected:
+ TAO_AV_Protocol_Object *protocol_object_;
+ TAO_AV_Flow_Handler *handler_;
+};
+
+#if defined(__ACE_INLINE__)
+#include "Policy.i"
+#endif /* __ACE_INLINE__ */
+#endif /* TAO_AV_POLICY_H */
diff --git a/TAO/orbsvcs/orbsvcs/AV/Policy.i b/TAO/orbsvcs/orbsvcs/AV/Policy.i
new file mode 100644
index 00000000000..0994186e6ed
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/AV/Policy.i
@@ -0,0 +1,75 @@
+/* -*- C++ -*- */
+// $Id$
+//--------------------------------------------------
+// TAO_AV_Policy
+//--------------------------------------------------
+
+ACE_INLINE CORBA::ULong
+TAO_AV_Policy::type (void)
+{
+ return this->type_;
+}
+
+//--------------------------------------------------
+// TAO_AV_SSRC_Policy
+//--------------------------------------------------
+
+ACE_INLINE CORBA::ULong
+TAO_AV_SSRC_Policy::value (void)
+{
+ return this->ssrc_;
+}
+
+
+ACE_INLINE void
+TAO_AV_SSRC_Policy::value (CORBA::ULong ssrc)
+{
+ this->ssrc_ = ssrc;
+}
+
+//--------------------------------------------------
+// TAO_AV_Payload_Type_Policy
+//--------------------------------------------------
+ACE_INLINE void
+TAO_AV_Payload_Type_Policy::value (int pt)
+{
+ this->payload_type_ = pt;
+}
+
+ACE_INLINE int
+TAO_AV_Payload_Type_Policy::value (void)
+{
+ return this->payload_type_;
+}
+
+
+// TAO_AV_RTCP_Sdes_Policy
+ACE_INLINE TAO_AV_RTCP_Sdes &
+TAO_AV_RTCP_Sdes_Policy::value (void)
+{
+ return this->sdes_;
+}
+
+ACE_INLINE void
+TAO_AV_RTCP_Sdes_Policy::value (const TAO_AV_RTCP_Sdes &sdes_val)
+{
+ this->sdes_ = sdes_val;
+}
+
+//----------------------------------------------------------------------
+// TAO_AV_SFP_Credit_Policy
+//----------------------------------------------------------------------
+
+ACE_INLINE
+void
+TAO_AV_SFP_Credit_Policy::value (int credit)
+{
+ this->value_ = credit;
+}
+
+ACE_INLINE
+int
+TAO_AV_SFP_Credit_Policy::value (void)
+{
+ return this->value_;
+}
diff --git a/TAO/orbsvcs/orbsvcs/AV/Protocol_Factory.cpp b/TAO/orbsvcs/orbsvcs/AV/Protocol_Factory.cpp
new file mode 100644
index 00000000000..ea6bf89ddda
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/AV/Protocol_Factory.cpp
@@ -0,0 +1,157 @@
+// $Id$
+
+
+#include "Protocol_Factory.h"
+#include "ace/Dynamic_Service.h"
+
+TAO_AV_Transport_Factory::TAO_AV_Transport_Factory (void)
+{
+}
+
+TAO_AV_Transport_Factory::~TAO_AV_Transport_Factory (void)
+{
+}
+
+int
+TAO_AV_Transport_Factory::init (int /* argc */,
+ char * /* argv */ [])
+{
+ return -1;
+}
+
+int
+TAO_AV_Transport_Factory::match_protocol (const char * /* protocol_string */)
+{
+ return 0;
+}
+
+TAO_AV_Acceptor *
+TAO_AV_Transport_Factory::make_acceptor (void)
+{
+ return 0;
+}
+
+TAO_AV_Connector *
+TAO_AV_Transport_Factory::make_connector (void)
+{
+ return 0;
+}
+
+// TAO_AV_Flow_Protocol_Factory
+TAO_AV_Flow_Protocol_Factory::TAO_AV_Flow_Protocol_Factory (void)
+{
+}
+
+TAO_AV_Flow_Protocol_Factory::~TAO_AV_Flow_Protocol_Factory (void)
+{
+}
+
+TAO_AV_Flow_Protocol_Factory::init (int /* argc */,
+ char * /* argv */ [])
+{
+ return -1;
+}
+
+int
+TAO_AV_Flow_Protocol_Factory::match_protocol (const char * /* protocol_string */)
+{
+ return 0;
+}
+
+TAO_AV_Protocol_Object*
+TAO_AV_Flow_Protocol_Factory::make_protocol_object (TAO_FlowSpec_Entry * /* entry */,
+ TAO_Base_StreamEndPoint * /* endpoint */ ,
+ TAO_AV_Flow_Handler * /* handler */,
+ TAO_AV_Transport * /* transport */)
+{
+ return 0;
+}
+
+const char *
+TAO_AV_Flow_Protocol_Factory::control_flow_factory (void)
+{
+ return 0;
+}
+
+//----------------------------------------------------------------------
+// TAO_AV_Protocol_Object
+//----------------------------------------------------------------------
+TAO_AV_Protocol_Object::TAO_AV_Protocol_Object (TAO_AV_Callback *callback,
+ TAO_AV_Transport *transport)
+ :transport_ (transport),
+ callback_ (callback)
+{
+}
+
+int
+TAO_AV_Protocol_Object::open (TAO_AV_Callback *callback,
+ TAO_AV_Transport *transport)
+{
+ this->callback_ = callback;
+ this->transport_ = transport;
+ return 0;
+}
+
+TAO_AV_Protocol_Object::~TAO_AV_Protocol_Object (void)
+{
+ //no-op
+}
+
+int
+TAO_AV_Protocol_Object::start (void)
+{
+ return this->callback_->handle_start ();
+}
+
+int
+TAO_AV_Protocol_Object::stop (void)
+{
+ return this->callback_->handle_stop ();
+}
+
+int
+TAO_AV_Protocol_Object::set_policies (const TAO_AV_PolicyList &policy_list)
+{
+ this->policy_list_ = policy_list;
+ return 0;
+}
+
+TAO_AV_PolicyList
+TAO_AV_Protocol_Object::get_policies (void)
+{
+ return this->policy_list_;
+}
+
+TAO_AV_Transport*
+TAO_AV_Protocol_Object::transport (void)
+{
+ return this->transport_;
+}
+
+// void
+// TAO_AV_Protocol_Object::transport (TAO_AV_Transport *transport)
+// {
+// this->transport_ = transport;
+// }
+
+void
+TAO_AV_Protocol_Object::control_object (TAO_AV_Protocol_Object * /* object */)
+{
+ return;
+}
+
+int
+TAO_AV_Protocol_Object::handle_control_input (ACE_Message_Block *,
+ const ACE_Addr &)
+{
+ ACE_DEBUG ((LM_DEBUG,"TAO_AV_Protocol_Object::handle_control_input\n"));
+ return 0;
+}
+
+#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
+template class ACE_Dynamic_Service<TAO_AV_Transport_Factory>;
+template class ACE_Dynamic_Service<TAO_AV_Flow_Protocol_Factory>;
+#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
+#pragma instantiate ACE_Dynamic_Service<TAO_AV_Transport_Factory>
+#pragma instantiate ACE_Dynamic_Service<TAO_AV_Flow_Protocol_Factory>
+#endif
diff --git a/TAO/orbsvcs/orbsvcs/AV/Protocol_Factory.h b/TAO/orbsvcs/orbsvcs/AV/Protocol_Factory.h
new file mode 100644
index 00000000000..53c22530af8
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/AV/Protocol_Factory.h
@@ -0,0 +1,100 @@
+/* -*- C++ -*- */
+
+// $Id$
+// ============================================================================
+//
+// = LIBRARY
+// ORBSVCS AVStreams
+//
+// = FILENAME
+// Protocol_Factory
+//
+// = AUTHOR
+// Nagarajan Surendran <naga@cs.wustl.edu>
+//
+//
+// ============================================================================
+
+#ifndef TAO_AV_PROTOCOL_FACTORY_T_H
+#define TAO_AV_PROTOCOL_FACTORY_T_H
+
+#include "ace/Service_Object.h"
+#include "Policy.h"
+#include "FlowSpec_Entry.h"
+
+class TAO_ORBSVCS_Export TAO_AV_Transport_Factory : public ACE_Service_Object
+{
+public:
+ TAO_AV_Transport_Factory (void);
+ virtual ~TAO_AV_Transport_Factory (void);
+ virtual int init (int argc, char *argv[]);
+ // Initialization hook.
+ virtual int match_protocol (const char *protocol_string);
+ virtual TAO_AV_Acceptor *make_acceptor (void);
+ virtual TAO_AV_Connector *make_connector (void);
+};
+
+class TAO_AV_Protocol_Object
+{
+public:
+ TAO_AV_Protocol_Object (void);
+
+ TAO_AV_Protocol_Object (TAO_AV_Callback *callback,
+ TAO_AV_Transport *transport);
+ // constructor.
+
+ virtual ~TAO_AV_Protocol_Object (void);
+ // Destructor
+
+ virtual int open (TAO_AV_Callback *callback,
+ TAO_AV_Transport *transport);
+
+ virtual int handle_input (void) = 0;
+
+ virtual int handle_control_input (ACE_Message_Block *control_frame,
+ const ACE_Addr &peer_address);
+ // Called on a control object.
+
+ virtual int set_policies (const TAO_AV_PolicyList &policy_list);
+ virtual TAO_AV_PolicyList get_policies (void);
+ // set/get policies.
+
+ virtual int start (void);
+ virtual int stop (void);
+ // start/stop the flow.
+
+ virtual int send_frame (ACE_Message_Block *frame,
+ TAO_AV_frame_info *frame_info = 0) = 0;
+ // send a data frame.
+
+ virtual int send_frame (const iovec *iov,
+ int iovcnt,
+ TAO_AV_frame_info *frame_info = 0) = 0;
+ // send a frame in iovecs.
+
+ virtual void control_object (TAO_AV_Protocol_Object *object);
+ virtual int destroy (void) = 0;
+ // end the stream.
+ TAO_AV_Transport *transport (void);
+protected:
+ TAO_AV_Transport *transport_;
+ TAO_AV_PolicyList policy_list_;
+ TAO_AV_Callback *callback_;
+};
+
+class TAO_ORBSVCS_Export TAO_AV_Flow_Protocol_Factory : public ACE_Service_Object
+{
+public:
+ TAO_AV_Flow_Protocol_Factory (void);
+ virtual ~TAO_AV_Flow_Protocol_Factory (void);
+ virtual int init (int argc, char *argv[]);
+ // Initialization hook.
+ virtual int match_protocol (const char *flow_string);
+ virtual TAO_AV_Protocol_Object* make_protocol_object (TAO_FlowSpec_Entry *entry,
+ TAO_Base_StreamEndPoint *endpoint,
+ TAO_AV_Flow_Handler *handler,
+ TAO_AV_Transport *transport);
+ virtual const char *control_flow_factory (void);
+};
+
+#endif /* TAO_AV_PROTOCOL_FACTORY_T_H */
diff --git a/TAO/orbsvcs/orbsvcs/AV/RTCP.cpp b/TAO/orbsvcs/orbsvcs/AV/RTCP.cpp
new file mode 100644
index 00000000000..41145960d59
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/AV/RTCP.cpp
@@ -0,0 +1,931 @@
+/*
+ * Copyright (c) 1994-1995 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and the Network Research Group at
+ * Lawrence Berkeley Laboratory.
+ * 4. Neither the name of the University nor of the Laboratory may be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+// $Id$
+#include "ntp-time.h"
+#include "RTCP.h"
+#include "media-timer.h"
+
+
+// TAO_AV_RTP_State
+TAO_AV_RTP_State::TAO_AV_RTP_State (void)
+ :bad_version_(0),
+ badoptions_(0),
+ badfmt_(0),
+ badext_(0),
+ nrunt_(0),
+ last_np_(0),
+ sdes_seq_(0),
+ rtcp_inv_bw_(0.),
+ rtcp_avg_size_(128.),
+ confid_(-1)
+{
+ ACE_NEW (pktbuf_,
+ u_char [2 * RTP_MTU]);
+}
+
+//------------------------------------------------------------
+// TAO_AV_RTCP
+//------------------------------------------------------------
+
+u_char*
+TAO_AV_RTCP::build_sdes_item (u_char* p,
+ int code,
+ TAO_AV_Source& s)
+{
+ const char* value = s.sdes (code);
+ if (value != 0)
+ {
+ int len = strlen (value);
+ *p++ = code;
+ *p++ = len;
+ memcpy (p, value, len);
+ p += len;
+ }
+ return (p);
+}
+
+int
+TAO_AV_RTCP::build_sdes (rtcphdr* rh,
+ TAO_AV_Source& ls,
+ TAO_AV_RTP_State *state)
+{
+ int flags = RTP_VERSION << 14 | 1 << 8 | RTCP_PT_SDES;
+ rh->rh_flags = htons (flags);
+ rh->rh_ssrc = ls.srcid ();
+ u_char* p = (u_char*) (rh + 1);
+ p = build_sdes_item (p, RTCP_SDES_CNAME, ls);
+
+ /*
+ * We always send a cname plus one other sdes
+ * There's a schedule for what we send sequenced by sdes_seq_:
+ * - send 'email' every 0th & 4th packet
+ * - send 'note' every 2nd packet
+ * - send 'tool' every 6th packet
+ * - send 'name' in all the odd slots
+ * (if 'note' is not the empty string, we switch the roles
+ * of name & note)
+ */
+ int nameslot, noteslot;
+ const char* note = ls.sdes (RTCP_SDES_NOTE);
+ if (note)
+ {
+ if (*note)
+ {
+ nameslot = RTCP_SDES_NOTE;
+ noteslot = RTCP_SDES_NAME;
+ } else
+ {
+ nameslot = RTCP_SDES_NAME;
+ noteslot = RTCP_SDES_NOTE;
+ }
+ }
+ else
+ {
+ nameslot = RTCP_SDES_NAME;
+ noteslot = RTCP_SDES_NAME;
+ }
+ u_int seq = (++state->sdes_seq_) & 0x7;
+ switch (seq)
+ {
+ case 0:
+ case 4:
+ p = build_sdes_item (p, RTCP_SDES_EMAIL, ls);
+ break;
+ case 2:
+ p = build_sdes_item (p, noteslot, ls);
+ break;
+ case 6:
+ p = build_sdes_item (p, RTCP_SDES_TOOL, ls);
+ break;
+ default:
+ p = build_sdes_item (p, nameslot, ls);
+ }
+
+ int len = p - (u_char*)rh;
+ int pad = 4 - (len & 3);
+ len += pad;
+ rh->rh_len = htons ( (len >> 2) - 1);
+ while (--pad >= 0)
+ *p++ = 0;
+
+ return (len);
+}
+
+int
+TAO_AV_RTCP::build_bye (rtcphdr* rh,
+ TAO_AV_Source& ls)
+{
+ int flags =
+ RTP_VERSION << 14 | 1 << 8 | RTCP_PT_BYE;
+ rh->rh_flags = ntohs (flags);
+ rh->rh_len = htons (1);
+ rh->rh_ssrc = ls.srcid ();
+ return (8);
+}
+
+void
+TAO_AV_RTCP::parse_rr_records (ACE_UINT32,
+ rtcp_rr*,
+ int,
+ const u_char*,
+ ACE_UINT32)
+{
+ if (TAO_debug_level > 0) ACE_DEBUG ( (LM_DEBUG,"TAO_AV_RTCP::parse_rr_records\n"));
+}
+
+void
+TAO_AV_RTCP::parse_sr (rtcphdr* rh,
+ int flags,
+ u_char*ep,
+ TAO_AV_Source* ps,
+ ACE_UINT32 addr,
+ TAO_AV_SourceManager *source_manager)
+{
+ rtcp_sr* sr = (rtcp_sr*) (rh + 1);
+ TAO_AV_Source* s;
+ ACE_UINT32 ssrc = rh->rh_ssrc;
+ if (ps->srcid () != ssrc)
+ s = source_manager->lookup (ssrc, ssrc, addr);
+ else
+ s = ps;
+
+ s->lts_ctrl (ACE_OS::gettimeofday ());
+ s->sts_ctrl (ntohl (sr->sr_ntp.upper) << 16 |
+ ntohl (sr->sr_ntp.lower) >> 16);
+
+ int cnt = flags >> 8 & 0x1f;
+ parse_rr_records (ssrc, (rtcp_rr*) (sr + 1), cnt, ep, addr);
+}
+
+void
+TAO_AV_RTCP::parse_rr (rtcphdr* rh,
+ int flags,
+ u_char* ep,
+ TAO_AV_Source* ps,
+ ACE_UINT32 addr,
+ TAO_AV_SourceManager *source_manager)
+{
+ TAO_AV_Source* s;
+ ACE_UINT32 ssrc = rh->rh_ssrc;
+ if (ps->srcid () != ssrc)
+ s = source_manager->lookup (ssrc, ssrc, addr);
+ else
+ s = ps;
+
+ s->lts_ctrl (ACE_OS::gettimeofday ());
+ int cnt = flags >> 8 & 0x1f;
+ parse_rr_records (ssrc, (rtcp_rr*) (rh + 1), cnt, ep, addr);
+}
+
+int
+TAO_AV_RTCP::sdesbody (ACE_UINT32* p,
+ u_char* ep,
+ TAO_AV_Source* ps,
+ ACE_UINT32 addr,
+ ACE_UINT32 ssrc,
+ TAO_AV_SourceManager *source_manager)
+{
+ TAO_AV_Source* s;
+ ACE_UINT32 srcid = *p;
+ if (ps->srcid () != srcid)
+ s = source_manager->lookup (srcid, ssrc, addr);
+ else
+ s = ps;
+ if (s == 0)
+ return (0);
+ /*
+ * Note ctrl packet since we will never see any direct ctrl packets
+ * from a TAO_AV_Source through a mixer (and we don't want the TAO_AV_Source to
+ * time out).
+ */
+ s->lts_ctrl (ACE_OS::gettimeofday ());
+
+ u_char* cp = (u_char*) (p + 1);
+ while (cp < ep)
+ {
+ char buf[256];
+
+ u_int type = cp[0];
+ if (type == 0)
+ {
+ /* end of chunk */
+ return ( ( (cp - (u_char*)p) >> 2) + 1);
+ }
+ u_int len = cp[1];
+ u_char* eopt = cp + len + 2;
+ if (eopt > ep)
+ return (0);
+
+ if (type >= RTCP_SDES_MIN && type <= RTCP_SDES_MAX)
+ {
+ memcpy (buf, (char*)&cp[2], len);
+ buf[len] = 0;
+ s->sdes (type, buf);
+ }
+ else
+ /*XXX*/;
+
+ cp = eopt;
+ }
+ return (0);
+}
+
+void
+TAO_AV_RTCP::parse_sdes (rtcphdr* rh,
+ int flags,
+ u_char* ep,
+ TAO_AV_Source* ps,
+ ACE_UINT32 addr,
+ ACE_UINT32 ssrc,
+ TAO_AV_SourceManager *source_manager)
+{
+ int cnt = flags >> 8 & 0x1f;
+ ACE_UINT32* p = (ACE_UINT32*)&rh->rh_ssrc;
+ while (--cnt >= 0)
+ {
+ int n = TAO_AV_RTCP::sdesbody (p, ep, ps, addr, ssrc, source_manager);
+ if (n == 0)
+ break;
+ p += n;
+ }
+ if (cnt >= 0)
+ ps->badsdes (1);
+}
+
+void
+TAO_AV_RTCP::parse_bye (rtcphdr* rh,
+ int flags,
+ u_char* ep,
+ TAO_AV_Source* ps,
+ TAO_AV_SourceManager *source_manager)
+{
+ int cnt = flags >> 8 & 0x1f;
+ ACE_UINT32* p = (ACE_UINT32*)&rh->rh_ssrc;
+
+ while (--cnt >= 0)
+ {
+ if (p >= (ACE_UINT32*)ep)
+ {
+ ps->badbye (1);
+ return;
+ }
+ TAO_AV_Source* s;
+ if (ps->srcid () != rh->rh_ssrc)
+ s = source_manager->consult (*p);
+ else
+ s = ps;
+ if (s != 0)
+ s->lts_done (ACE_OS::gettimeofday ());
+ ++p;
+ }
+}
+
+/*XXX check for buffer overflow*/
+/*
+ * Send an RTPv2 report packet.
+ */
+void
+TAO_AV_RTCP::send_report (int bye,
+ TAO_AV_Protocol_Object *protocol_object,
+ TAO_AV_SourceManager *source_manager,
+ TAO_AV_RTP_State *state,
+ TAO_AV_RTCP_Callback *callback)
+{
+ if (source_manager->localsrc () == 0)
+ return;
+ TAO_AV_Source& s = *source_manager->localsrc ();
+ rtcphdr* rh = (rtcphdr*)state->pktbuf_;
+ rh->rh_ssrc = s.srcid ();
+ int flags = RTP_VERSION << 14;
+ timeval now = ACE_OS::gettimeofday ();
+ s.lts_ctrl (now);
+ int we_sent = 0;
+ rtcp_rr* rr;
+ /*
+ * If we've sent data since our last sender report send a
+ * new report. The MediaTimer check is to make sure we still
+ * have a grabber -- if not, we won't be able to interpret the
+ * media timestamps so there's no point in sending an SR.
+ */
+ MediaTimer* mt = MediaTimer::instance ();
+ if (s.np () != state->last_np_ && mt) {
+ state->last_np_ = s.np ();
+ we_sent = 1;
+ flags |= RTCP_PT_SR;
+ rtcp_sr* sr = (rtcp_sr*) (rh + 1);
+ sr->sr_ntp = ntp64time (now);
+ sr->sr_ntp.upper = ACE_HTONL (sr->sr_ntp.upper);
+ sr->sr_ntp.lower = ACE_HTONL (sr->sr_ntp.lower);
+ sr->sr_ts = htonl (mt->ref_ts ());
+ sr->sr_np = htonl (s.np ());
+ sr->sr_nb = htonl (s.nb ());
+ rr = (rtcp_rr*) (sr + 1);
+ } else {
+ flags |= RTCP_PT_RR;
+ rr = (rtcp_rr*) (rh + 1);
+ }
+ int nrr = 0;
+ int nsrc = 0;
+ /*
+ * we don't want to inflate report interval if user has set
+ * the flag that causes all TAO_AV_Sources to be 'kept' so we
+ * consider TAO_AV_Sources 'inactive' if we haven't heard a control
+ * msg from them for ~32 reporting intervals.
+ */
+ u_int inactive = u_int (state->rint_ * (32./1000.));
+ if (inactive < 2)
+ inactive = 2;
+ for (TAO_AV_Source* sp = source_manager->sources (); sp != 0; sp = sp->next_) {
+ ++nsrc;
+ int received = sp->np () - sp->snp ();
+ if (received == 0) {
+ if (u_int (now.tv_sec - sp->lts_ctrl ().tv_sec) > inactive)
+ --nsrc;
+ continue;
+ }
+ sp->snp (sp->np ());
+ rr->rr_srcid = sp->srcid ();
+ int expected = sp->ns () - sp->sns ();
+ sp->sns (sp->ns ());
+ ACE_UINT32 v;
+ int lost = expected - received;
+ if (lost <= 0)
+ v = 0;
+ else
+ /* expected != 0 if lost > 0 */
+ v = ( (lost << 8) / expected) << 24;
+ /* XXX should saturate on over/underflow */
+ v |= (sp->ns () - sp->np ()) & 0xffffff;
+ rr->rr_loss = htonl (v);
+ rr->rr_ehsr = htonl (sp->ehs ());
+ rr->rr_dv = sp->delvar ();
+ rr->rr_lsr = htonl (sp->sts_ctrl ());
+ if (sp->lts_ctrl ().tv_sec == 0)
+ rr->rr_dlsr = 0;
+ else {
+ ACE_UINT32 ntp_now = ntptime (now);
+ ACE_UINT32 ntp_then = ntptime (sp->lts_ctrl ());
+ rr->rr_dlsr = htonl (ntp_now - ntp_then);
+ }
+ ++rr;
+ if (++nrr >= 31)
+ break;
+ }
+ flags |= nrr << 8;
+ rh->rh_flags = htons (flags);
+ int len = (u_char*)rr - state->pktbuf_;
+ rh->rh_len = htons ( (len >> 2) - 1);
+
+ if (bye)
+ len += build_bye ( (rtcphdr*)rr, s);
+ else
+ len += build_sdes ( (rtcphdr*)rr, s,state);
+
+ ACE_Message_Block mb ((char *)state->pktbuf_, len);
+ mb.wr_ptr (len);
+ protocol_object->send_frame (&mb);
+
+ state->rtcp_avg_size_ += RTCP_SIZE_GAIN * (double (len + 28) - state->rtcp_avg_size_);
+
+ /*
+ * compute the time to the next report. we do this here
+ * because we need to know if there were any active TAO_AV_Sources
+ * during the last report period (nrr above) & if we were
+ * a TAO_AV_Source. The bandwidth limit for rtcp traffic was set
+ * on startup from the session bandwidth. It is the inverse
+ * of bandwidth (ie., ms/byte) to avoid a divide below.
+ */
+ double ibw = state->rtcp_inv_bw_;
+ if (nrr) {
+ /* there were active TAO_AV_Sources */
+ if (we_sent) {
+ ibw *= 1./RTCP_SENDER_BW_FRACTION;
+ nsrc = nrr;
+ } else {
+ ibw *= 1./RTCP_RECEIVER_BW_FRACTION;
+ nsrc -= nrr;
+ }
+ }
+ double rint = state->rtcp_avg_size_ * double (nsrc) * ibw;
+ if (rint < RTCP_MIN_RPT_TIME * 1000.)
+ rint = RTCP_MIN_RPT_TIME * 1000.;
+ state->rint_ = rint;
+ callback->schedule (int (fmod (double (ACE_OS::rand ()), rint) + rint * .5 + .5));
+
+ source_manager->CheckActiveSources (rint);
+}
+
+int
+TAO_AV_RTCP::handle_input (ACE_Message_Block *data,
+ const ACE_Addr &peer_address,
+ rtcphdr &header,
+ TAO_AV_SourceManager *source_manager,
+ TAO_AV_RTP_State *state)
+{
+ int cc = data->length ();
+ int size_phdr = ACE_static_cast (int, sizeof (rtcphdr));
+ if (cc < size_phdr)
+ {
+ state->nrunt_++;
+ ACE_ERROR_RETURN ( (LM_ERROR,"TAO_AV_RTP::handle_input:invalid header\n"),-1);
+ }
+ if (peer_address == ACE_Addr::sap_any)
+ ACE_ERROR_RETURN ( (LM_ERROR,"TAO_AV_RTP::handle_input:get_peer_addr failed\n"),-1);
+ // @@ We need to be careful of this.
+ u_long addr = peer_address.hash ();
+ header = * (rtcphdr*) (data->rd_ptr ());
+ rtcphdr *rh = (rtcphdr *)data->rd_ptr ();
+ /*
+ * try to filter out junk: first thing in packet must be
+ * sr, rr or bye & version number must be correct.
+ */
+ switch (ntohs (rh->rh_flags) & 0xc0ff)
+ {
+ case RTP_VERSION << 14 | RTCP_PT_SR:
+ case RTP_VERSION << 14 | RTCP_PT_RR:
+ case RTP_VERSION << 14 | RTCP_PT_BYE:
+ break;
+ default:
+ /*
+ * XXX should further categorize this error -- it is
+ * likely that people mis-implement applications that
+ * don't put something other than SR,RR,BYE first.
+ */
+ ++state->bad_version_;
+ return -1;
+ }
+ /*
+ * at this point we think the packet's valid. Update our average
+ * size estimator. Also, there's valid ssrc so charge errors to it
+ */
+
+
+ double tmp = (cc + 28) - state->rtcp_avg_size_;
+ tmp *= RTCP_SIZE_GAIN;
+ state->rtcp_avg_size_ += ACE_static_cast (int, tmp);
+ /*
+ * First record in compound packet must be the ssrc of the
+ * sender of the packet. Pull it out here so we can use
+ * it in the sdes parsing, since the sdes record doesn't
+ * contain the ssrc of the sender (in the case of mixers).
+ */
+ ACE_UINT32 ssrc = rh->rh_ssrc;
+ TAO_AV_Source* ps = source_manager->lookup (ssrc, ssrc, addr);
+ if (ps == 0)
+ return 0;
+
+ /*
+ * Outer loop parses multiple RTCP records of a "compound packet".
+ * There is no framing between records. Boundaries are implicit
+ * and the overall length comes from UDP.
+ */
+ u_char* epack = (u_char*)rh + cc;
+ while ( (u_char*)rh < epack) {
+ u_int len = (ntohs (rh->rh_len) << 2) + 4;
+ u_char* ep = (u_char*)rh + len;
+ if (ep > epack) {
+ ps->badsesslen (1);
+ return 0;
+ }
+ u_int flags = ntohs (rh->rh_flags);
+ if (flags >> 14 != RTP_VERSION) {
+ ps->badsessver (1);
+ return 0;
+ }
+ switch (flags & 0xff) {
+
+ case RTCP_PT_SR:
+ TAO_AV_RTCP::parse_sr (rh, flags, ep, ps, addr, source_manager);
+ break;
+
+ case RTCP_PT_RR:
+ TAO_AV_RTCP::parse_rr (rh, flags, ep, ps, addr, source_manager);
+ break;
+
+ case RTCP_PT_SDES:
+ TAO_AV_RTCP::parse_sdes (rh, flags, ep, ps, addr, ssrc, source_manager);
+ break;
+
+ case RTCP_PT_BYE:
+ TAO_AV_RTCP::parse_bye (rh, flags, ep, ps, source_manager);
+ break;
+
+ default:
+ ps->badsessopt (1);
+ break;
+ }
+ rh = (rtcphdr*)ep;
+ }
+ return 0;
+}
+
+ACE_UINT32
+TAO_AV_RTCP::alloc_srcid (ACE_UINT32 addr)
+{
+ timeval tv;
+ ::gettimeofday(&tv, 0);
+ ACE_UINT32 srcid = ACE_UINT32 (tv.tv_sec + tv.tv_usec);
+ srcid += (ACE_UINT32)getuid();
+ srcid += (ACE_UINT32)getpid();
+ srcid += addr;
+ return (srcid);
+}
+
+
+// TAO_AV_RTCP_Flow_Factory
+TAO_AV_RTCP_Flow_Factory::TAO_AV_RTCP_Flow_Factory (void)
+{
+}
+
+TAO_AV_RTCP_Flow_Factory::~TAO_AV_RTCP_Flow_Factory (void)
+{
+}
+
+int
+TAO_AV_RTCP_Flow_Factory::match_protocol (const char *flow_string)
+{
+ if (ACE_OS::strncasecmp (flow_string,"RTCP",4) == 0)
+ return 1;
+ return 0;
+}
+
+int
+TAO_AV_RTCP_Flow_Factory::init (int /* argc */,
+ char * /* argv */ [])
+{
+ return 0;
+}
+
+TAO_AV_Protocol_Object*
+TAO_AV_RTCP_Flow_Factory::make_protocol_object (TAO_FlowSpec_Entry *entry,
+ TAO_Base_StreamEndPoint *endpoint,
+ TAO_AV_Flow_Handler *handler,
+ TAO_AV_Transport *transport)
+{
+ TAO_AV_Callback *callback = 0;
+ endpoint->get_control_callback (entry->flowname (),
+ callback);
+ if (callback == 0)
+ ACE_NEW_RETURN (callback,
+ TAO_AV_RTCP_Callback,
+ 0);
+ TAO_AV_Protocol_Object *object = 0;
+ ACE_NEW_RETURN (object,
+ TAO_AV_RTCP_Object (callback,
+ transport),
+ 0);
+ callback->open (object,
+ handler);
+ return object;
+}
+
+// TAO_AV_RTCP_Object
+int
+TAO_AV_RTCP_Object::handle_input (void)
+{
+ ACE_Message_Block *data;
+ size_t bufsiz = 2*this->transport_->mtu ();
+ ACE_NEW_RETURN (data,
+ ACE_Message_Block (bufsiz),
+ -1);
+ int n = this->transport_->recv (data->rd_ptr (),bufsiz);
+ if (n == 0)
+ ACE_ERROR_RETURN ( (LM_ERROR,"TAO_AV_RTP::handle_input:connection closed\n"),-1);
+ if (n < 0)
+ ACE_ERROR_RETURN ( (LM_ERROR,"TAO_AV_RTP::handle_input:recv error\n"),-1);
+ data->wr_ptr (n);
+ ACE_Addr *peer_addr = this->transport_->get_peer_addr ();
+ this->callback_->receive_control_frame (data,*peer_addr);
+ return 0;
+}
+
+int
+TAO_AV_RTCP_Object::send_frame (ACE_Message_Block *frame,
+ TAO_AV_frame_info *frame_info)
+{
+ return this->transport_->send (frame);
+}
+
+int
+TAO_AV_RTCP_Object::send_frame (const iovec *iov,
+ int iovcnt,
+ TAO_AV_frame_info *frame_info)
+{
+ return this->transport_->send (iov,
+ iovcnt);
+}
+
+TAO_AV_RTCP_Object::TAO_AV_RTCP_Object (TAO_AV_Callback *callback,
+ TAO_AV_Transport *transport)
+ :TAO_AV_Protocol_Object (callback,transport)
+{
+}
+
+TAO_AV_RTCP_Object::~TAO_AV_RTCP_Object (void)
+{
+}
+
+int
+TAO_AV_RTCP_Object::destroy (void)
+{
+ this->callback_->handle_destroy ();
+ return 0;
+}
+
+int
+TAO_AV_RTCP_Object::set_policies (const TAO_AV_PolicyList &policy_list)
+{
+ return -1;
+}
+
+int
+TAO_AV_RTCP_Object::start (void)
+{
+ return this->callback_->handle_start ();
+}
+
+int
+TAO_AV_RTCP_Object::stop (void)
+{
+ return this->callback_->handle_stop ();
+}
+
+int
+TAO_AV_RTCP_Object::handle_control_input (ACE_Message_Block *frame,
+ const ACE_Addr &peer_address)
+{
+// frame->rd_ptr ((size_t)0);
+// // Since the rd_ptr would have been moved ahead.
+ return this->callback_->receive_frame (frame,
+ 0,
+ peer_address);
+}
+
+// TAO_AV_RTCP_Callback
+TAO_AV_RTCP_Callback::TAO_AV_RTCP_Callback (void)
+{
+ ACE_NEW (source_manager_,
+ TAO_AV_SourceManager (this));
+
+ ACE_NEW (this->state_,
+ TAO_AV_RTP_State);
+}
+
+TAO_AV_RTCP_Callback::~TAO_AV_RTCP_Callback (void)
+{
+}
+
+TAO_AV_SourceManager*
+TAO_AV_RTCP_Callback::source_manager (void)
+{
+ return this->source_manager_;
+}
+
+TAO_AV_RTP_State*
+TAO_AV_RTCP_Callback::state (void)
+{
+ return this->state_;
+}
+
+int
+TAO_AV_RTCP_Callback::get_rtp_source (TAO_AV_Source *&source,
+ ACE_UINT32 srcid,
+ ACE_UINT32 ssrc,
+ ACE_UINT32 addr)
+{
+ ACE_NEW_RETURN (source,
+ TAO_AV_Source (srcid,
+ ssrc,
+ addr),
+ -1);
+ return 0;
+}
+
+void
+TAO_AV_RTCP_Callback::schedule (int ms)
+{
+ this->timeout_ = ms;
+}
+
+
+int
+TAO_AV_RTCP_Callback::handle_start (void)
+{
+ //
+ /*
+ * schedule a timer for our first report using half the
+ * min rtcp interval. This gives us some time before
+ * our first report to learn about other sources so our
+ * next report interval will account for them. The avg
+ * rtcp size was initialized to 128 bytes which is
+ * conservative (it assumes everyone else is generating
+ * SRs instead of RRs).
+ */
+ double rint = this->state_->rtcp_avg_size_ * this->state_->rtcp_inv_bw_;
+ if (rint < RTCP_MIN_RPT_TIME / 2. * 1000.)
+ rint = RTCP_MIN_RPT_TIME / 2. * 1000.;
+ this->state_->rint_ = rint;
+ this->timeout_ = int(fmod(double(ACE_OS::rand ()), rint) + rint * .5 + .5);
+ return 0;
+}
+
+int
+TAO_AV_RTCP_Callback::handle_stop (void)
+{
+ return 0;
+}
+
+int
+TAO_AV_RTCP_Callback::handle_timeout (void *arg)
+{
+ // Here we do the send_report.
+ TAO_AV_RTCP::send_report (0,
+ this->protocol_object_,
+ this->source_manager_,
+ this->state_,
+ this);
+ return 0;
+}
+
+void
+TAO_AV_RTCP_Callback::get_timeout (ACE_Time_Value *&tv,
+ void *&arg)
+{
+ // Here we do the RTCP timeout calculation.
+ ACE_NEW (tv,
+ ACE_Time_Value (0,this->timeout_*ACE_ONE_SECOND_IN_MSECS));
+}
+
+int
+TAO_AV_RTCP_Callback::handle_destroy (void)
+{
+ // Here we do the send_bye.
+ TAO_AV_RTCP::send_report (1,
+ this->protocol_object_,
+ this->source_manager_,
+ this->state_,
+ this);
+ return 0;
+}
+
+int
+TAO_AV_RTCP_Callback::receive_frame (ACE_Message_Block *frame,
+ TAO_AV_frame_info *,
+ const ACE_Addr &peer_address)
+{
+ char *buf = frame->rd_ptr ();
+ TAO_AV_RTP::rtphdr *rh = (TAO_AV_RTP::rtphdr *)buf;
+
+ frame->rd_ptr (sizeof (TAO_AV_RTP::rtphdr));
+ int result = this->demux (rh,
+ frame,
+ peer_address);
+ frame->rd_ptr (buf);
+
+ if (result < 0)
+ return result;
+
+ return 0;
+}
+
+
+int
+TAO_AV_RTCP_Callback::receive_control_frame (ACE_Message_Block *frame,
+ const ACE_Addr &peer_address)
+{
+ // Here we do the processing of the RTCP frames.
+ TAO_AV_RTCP::rtcphdr header;
+ int result = TAO_AV_RTCP::handle_input (frame,
+ peer_address,
+ header,
+ this->source_manager_,
+ this->state_);
+ if (result < 0)
+ ACE_ERROR_RETURN ((LM_ERROR,"TAO_AV_RTCP::handle_input failed\n"),-1);
+ return 0;
+}
+
+int
+TAO_AV_RTCP_Callback::demux (TAO_AV_RTP::rtphdr* rh,
+ ACE_Message_Block *data,
+ const ACE_Addr &address)
+{
+ char *bp = data->rd_ptr ();
+ int cc = data->length ();
+ if (cc < 0)
+ {
+ ++this->state_->nrunt_;
+ return -1;
+ }
+ ACE_UINT32 srcid = rh->rh_ssrc;
+ int flags = ntohs (rh->rh_flags);
+ if ( (flags & RTP_X) != 0)
+ {
+ /*
+ * the minimal-control audio/video profile
+ * explicitly forbids extensions
+ */
+ ++this->state_->badext_;
+ return -1;
+ }
+
+ // @@Naga:Maybe the framework itself could check for formats making use of
+ // the property service to query the formats supported for this flow.
+ /*
+ * Check for illegal payload types. Most likely this is
+ * a session packet arriving on the data port.
+ */
+// int fmt = flags & 0x7f;
+// if (!check_format (fmt))
+// {
+// ++state->badfmt_;
+// return;
+// }
+
+ u_long addr = address.hash ();
+ ACE_UINT16 seqno = ntohs (rh->rh_seqno);
+ TAO_AV_Source* s = this->source_manager_->demux (srcid, addr, seqno);
+ if (s == 0)
+ /*
+ * Takes a pair of validated packets before we will
+ * believe the source. This prevents a runaway
+ * allocation of Source data structures for a
+ * stream of garbage packets.
+ */
+ return -1;
+
+ ACE_Time_Value now = ACE_OS::gettimeofday ();
+ s->lts_data (now);
+ s->sts_data (rh->rh_ts);
+
+ int cnt = (flags >> 8) & 0xf;
+ if (cnt > 0)
+ {
+ u_char* nh = (u_char*)rh + (cnt << 2);
+ while (--cnt >= 0)
+ {
+ ACE_UINT32 csrc = * (ACE_UINT32*)bp;
+ bp += 4;
+ TAO_AV_Source* cs = this->source_manager_->lookup (csrc, srcid, addr);
+ cs->lts_data (now);
+ cs->action ();
+ }
+ /*XXX move header up so it's contiguous with data*/
+ TAO_AV_RTP::rtphdr hdr = *rh;
+ rh = (TAO_AV_RTP::rtphdr*)nh;
+ *rh = hdr;
+ }
+ else
+ s->action ();
+
+ return 0;
+ /*
+ * This is a data packet. If the source needs activation,
+ * or the packet format has changed, deal with this.
+ * Then, hand the packet off to the packet handler.
+ * XXX might want to be careful about flip-flopping
+ * here when format changes due to misordered packets
+ * (easy solution -- keep rtp seqno of last fmt change).
+ */
+}
+
+ACE_FACTORY_DEFINE (AV, TAO_AV_RTCP_Flow_Factory)
+ACE_STATIC_SVC_DEFINE (TAO_AV_RTCP_Flow_Factory,
+ ASYS_TEXT ("RTCP_Flow_Factory"),
+ ACE_SVC_OBJ_T,
+ &ACE_SVC_NAME (TAO_AV_RTCP_Flow_Factory),
+ ACE_Service_Type::DELETE_THIS |
+ ACE_Service_Type::DELETE_OBJ,
+ 0)
diff --git a/TAO/orbsvcs/orbsvcs/AV/RTCP.h b/TAO/orbsvcs/orbsvcs/AV/RTCP.h
new file mode 100644
index 00000000000..1e128cf708b
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/AV/RTCP.h
@@ -0,0 +1,296 @@
+/* -*- C++ -*- */
+// $Id$
+/*-
+ * Copyright (c) 1993-1994 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and the Network Research Group at
+ * Lawrence Berkeley Laboratory.
+ * 4. Neither the name of the University nor of the Laboratory may be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+// ============================================================================
+//
+// = LIBRARY
+// ORBSVCS AVStreams
+//
+// = FILENAME
+// RTCP.h
+//
+// = AUTHOR
+// Nagarajan Surendran <naga@cs.wustl.edu>
+//
+//
+// ============================================================================
+
+#ifndef TAO_AV_RTCP_H
+#define TAO_AV_RTCP_H
+
+#include "ace/OS.h"
+#include "source.h"
+#include "AVStreams_i.h"
+#include "UDP.h"
+#include <math.h>
+#include <stdlib.h>
+#include "RTP.h"
+
+// TAO_AV_RTP_State
+class TAO_AV_RTP_State
+{
+public:
+ TAO_AV_RTP_State (void);
+ int bad_version_;
+ u_int badoptions_;
+ u_int badfmt_;
+ u_int badext_;
+ u_int nrunt_;
+ ACE_UINT32 last_np_;
+ ACE_UINT32 sdes_seq_;
+ double rtcp_inv_bw_;
+ double rtcp_avg_size_; /* (estimated) average size of rtcp packets */
+ double rint_; /* current session report rate (in ms) */
+ int confid_;
+ u_char* pktbuf_;
+};
+
+class TAO_AV_RTCP_Callback;
+class TAO_AV_SourceManager;
+
+class TAO_AV_RTCP
+{
+public:
+ struct rtcphdr
+ {
+ ACE_UINT16 rh_flags; /* T:2 P:1 CNT:5 PT:8 */
+ ACE_UINT16 rh_len; /* length of message (in bytes) */
+ ACE_UINT32 rh_ssrc; /* synchronization src id */
+ };
+
+ struct ntp64
+ {
+ ACE_UINT32 upper; /* more significant 32 bits */
+ ACE_UINT32 lower; /* less significant 32 bits */
+ };
+
+ /*
+ * Sender report.
+ */
+ struct rtcp_sr {
+ ntp64 sr_ntp; /* 64-bit ntp timestamp */
+ ACE_UINT32 sr_ts; /* reference media timestamp */
+ ACE_UINT32 sr_np; /* no. packets sent */
+ ACE_UINT32 sr_nb; /* no. bytes sent */
+ };
+
+ /*
+ * Receiver report.
+ * Time stamps are middle 32-bits of ntp timestamp.
+ */
+ struct rtcp_rr {
+ ACE_UINT32 rr_srcid; /* sender being reported */
+ ACE_UINT32 rr_loss; /* loss stats (8:fraction, 24:cumulative)*/
+ ACE_UINT32 rr_ehsr; /* ext. highest seqno received */
+ ACE_UINT32 rr_dv; /* jitter (delay variance) */
+ ACE_UINT32 rr_lsr; /* orig. ts from last rr from this src */
+ ACE_UINT32 rr_dlsr; /* time from recpt of last rr to xmit time */
+ };
+
+ static int handle_input (ACE_Message_Block *data,
+ const ACE_Addr &peer_address,
+ rtcphdr &header,
+ TAO_AV_SourceManager *source_manager,
+ TAO_AV_RTP_State *state);
+
+ static int build_bye (rtcphdr* rh,
+ TAO_AV_Source& local);
+
+ static int build_sdes (rtcphdr* rh,
+ TAO_AV_Source& s,
+ TAO_AV_RTP_State *state);
+
+ static u_char* build_sdes_item (u_char* p,
+ int code,
+ TAO_AV_Source&);
+
+ static void parse_sr (rtcphdr* rh,
+ int flags,
+ u_char* ep,
+ TAO_AV_Source* ps,
+ ACE_UINT32 addr,
+ TAO_AV_SourceManager *source_manager);
+
+ static void parse_rr (rtcphdr* rh,
+ int flags,
+ u_char* ep,
+ TAO_AV_Source* ps,
+ ACE_UINT32 addr,
+ TAO_AV_SourceManager *source_manager);
+
+ static void parse_rr_records (ACE_UINT32 ssrc,
+ rtcp_rr* r,
+ int cnt,
+ const u_char* ep,
+ ACE_UINT32 addr);
+
+ static int sdesbody (ACE_UINT32* p,
+ u_char* ep,
+ TAO_AV_Source* ps,
+ ACE_UINT32 addr,
+ ACE_UINT32 ssrc,
+ TAO_AV_SourceManager *source_manager);
+
+ static void parse_sdes (rtcphdr* rh,
+ int flags,
+ u_char* ep,
+ TAO_AV_Source* ps,
+ ACE_UINT32 addr,
+ ACE_UINT32 ssrc,
+ TAO_AV_SourceManager *source_manager);
+
+ static void parse_bye (rtcphdr* rh,
+ int flags,
+ u_char* ep,
+ TAO_AV_Source* ps,
+ TAO_AV_SourceManager *source_manager);
+
+ static void send_report (int bye,
+ TAO_AV_Protocol_Object *object,
+ TAO_AV_SourceManager *source_manager,
+ TAO_AV_RTP_State *state,
+ TAO_AV_RTCP_Callback *callback);
+
+ static ACE_UINT32 alloc_srcid (ACE_UINT32 addr);
+};
+
+class TAO_AV_Callback;
+
+class TAO_ORBSVCS_Export TAO_AV_RTCP_Object : public TAO_AV_Protocol_Object
+{
+public:
+ TAO_AV_RTCP_Object (TAO_AV_Callback *callback,
+ TAO_AV_Transport *transport = 0);
+ // constructor.
+
+ virtual ~TAO_AV_RTCP_Object (void);
+ // Destructor
+
+ virtual int handle_input (void);
+ virtual int handle_control_input (ACE_Message_Block *frame,
+ const ACE_Addr &peer_address);
+
+ virtual int set_policies (const TAO_AV_PolicyList &policy_list);
+ // set/get policies.
+
+ virtual int start (void);
+ virtual int stop (void);
+ // start/stop the flow.
+
+ virtual int send_frame (ACE_Message_Block *frame,
+ TAO_AV_frame_info *frame_info = 0);
+ // send a data frame.
+
+ virtual int send_frame (const iovec *iov,
+ int iovcnt,
+ TAO_AV_frame_info *frame_info = 0);
+ // send a frame in iovecs.
+
+ virtual int destroy (void);
+ // end the stream.
+};
+
+
+class TAO_ORBSVCS_Export TAO_AV_RTCP_Flow_Factory
+ :public TAO_AV_Flow_Protocol_Factory
+{
+public:
+ TAO_AV_RTCP_Flow_Factory (void);
+ virtual ~TAO_AV_RTCP_Flow_Factory (void);
+ virtual int init (int argc, char *argv[]);
+ virtual int match_protocol (const char *flow_string);
+ virtual TAO_AV_Protocol_Object* make_protocol_object (TAO_FlowSpec_Entry *entry,
+ TAO_Base_StreamEndPoint *endpoint,
+ TAO_AV_Flow_Handler *handler,
+ TAO_AV_Transport *transport);
+};
+
+class TAO_ORBSVCS_Export TAO_AV_RTCP_Callback : public TAO_AV_Callback
+{
+public:
+ TAO_AV_RTCP_Callback (void);
+ // RTCP callback.
+
+ virtual ~TAO_AV_RTCP_Callback (void);
+ // virtual destructor.
+
+ virtual int handle_start (void);
+ // Called during Streamctrl->start.
+
+ virtual int handle_stop (void);
+ // Called during Streamctrl->stop.
+
+ virtual int handle_timeout (void *arg);
+ // Called during timeout for Flow Producers.
+
+ virtual int receive_frame (ACE_Message_Block *frame,
+ TAO_AV_frame_info *frame_info = 0,
+ const ACE_Addr &peer_address = ACE_Addr::sap_any);
+ // Called when a frame arrives for a FlowConsumer.
+
+ virtual int receive_control_frame (ACE_Message_Block *frame,
+ const ACE_Addr &peer_address = ACE_Addr::sap_any);
+
+ virtual int handle_destroy (void);
+ // Called during Streamctrl->destroy i.e tear_down of the stream
+ // @@coryan:Call it handle_destroy or handle_close.
+
+ virtual void get_timeout (ACE_Time_Value *&tv,
+ void *&arg);
+ // Called to get the timeout. If tv is 0 then the framework stop
+ // calling this.
+
+ int demux (TAO_AV_RTP::rtphdr* rh,
+ ACE_Message_Block *data,
+ const ACE_Addr &peer_address);
+
+ virtual int get_rtp_source (TAO_AV_Source *&source,
+ ACE_UINT32 srcid,
+ ACE_UINT32 ssrc,
+ ACE_UINT32 addr);
+ void schedule (int ms);
+ TAO_AV_SourceManager *source_manager (void);
+ TAO_AV_RTP_State *state (void);
+protected:
+ TAO_AV_SourceManager *source_manager_;
+ TAO_AV_RTP_State *state_;
+ int timeout_;
+};
+
+ACE_STATIC_SVC_DECLARE (TAO_AV_RTCP_Flow_Factory)
+ACE_FACTORY_DECLARE (TAO_ORBSVCS, TAO_AV_RTCP_Flow_Factory)
+
+#endif /* TAO_AV_RTCP_H */
diff --git a/TAO/orbsvcs/orbsvcs/AV/RTP.cpp b/TAO/orbsvcs/orbsvcs/AV/RTP.cpp
new file mode 100644
index 00000000000..b3e97a8a67b
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/AV/RTP.cpp
@@ -0,0 +1,344 @@
+/*
+ * Copyright (c) 1994-1995 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and the Network Research Group at
+ * Lawrence Berkeley Laboratory.
+ * 4. Neither the name of the University nor of the Laboratory may be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+// $Id$
+
+#include "RTP.h"
+#include "RTCP.h"
+#include "Nil.h"
+
+int
+TAO_AV_RTP::handle_input (ACE_Message_Block *&data,
+ TAO_AV_frame_info *&frame_info)
+{
+ int n = data->length ();
+ int size_phdr = ACE_static_cast (int, sizeof (rtphdr));
+ if (n < size_phdr)
+ ACE_ERROR_RETURN ( (LM_ERROR,"TAO_AV_RTP::handle_input:invalid header\n"),-1);
+ rtphdr* rh = (rtphdr*)data->rd_ptr ();
+ int version = * (u_char*)rh >> 6;
+ if (version != 2)
+ {
+ // state->bad_version_++;
+ ACE_ERROR_RETURN ( (LM_ERROR,"TAO_AV_RTP:bad version\n"),-1);
+ }
+ TAO_AV_RTP::rtphdr header;
+ header = *rh;
+ // data->rd_ptr (sizeof (rtphdr));
+ ACE_NEW_RETURN (frame_info,
+ TAO_AV_frame_info,
+ -1);
+ frame_info->boundary_marker = header.rh_flags & RTP_M;
+ frame_info->timestamp = header.rh_ts;
+ frame_info->ssrc = header.rh_ssrc;
+ frame_info->sequence_num = header.rh_seqno;
+ frame_info->format = header.rh_flags & 0x7f;
+ return 0;
+}
+
+
+ACE_INLINE
+int
+TAO_AV_RTP::write_header (rtphdr &header,
+ int format,
+ ACE_UINT16 &sequence_num,
+ ACE_UINT32 ts,
+ ACE_UINT32 ssrc,
+ CORBA::Boolean boundary_marker)
+{
+ int flags = RTP_VERSION << 14 | format;
+ if (boundary_marker)
+ flags |= RTP_M;
+ header.rh_flags = ntohs (flags);
+ header.rh_seqno = htons (sequence_num);
+ sequence_num++;
+ header.rh_ts = htonl (ts);
+ header.rh_ssrc = ssrc;
+ return 0;
+}
+
+// TAO_AV_RTP_Object
+
+int
+TAO_AV_RTP_Object::handle_input (void)
+{
+ TAO_AV_frame_info *frame_info = 0;
+
+ // Handles the incoming RTP packet input.
+
+ this->frame_.rd_ptr (this->frame_.base ());
+
+ int n = this->transport_->recv (this->frame_.rd_ptr (),
+ this->frame_.size ());
+ if (n == 0)
+ ACE_ERROR_RETURN ( (LM_ERROR,"TAO_AV_RTP::handle_input:connection closed\n"),-1);
+ if (n < 0)
+ ACE_ERROR_RETURN ( (LM_ERROR,"TAO_AV_RTP::handle_input:recv error\n"),-1);
+ this->frame_.wr_ptr (this->frame_.rd_ptr () + n);
+ ACE_Addr *addr = this->transport_->get_peer_addr ();
+
+ ACE_Message_Block* data = &this->frame_;
+ int result = TAO_AV_RTP::handle_input (data,
+ frame_info);
+ if (result < 0)
+ return 0;
+ this->control_object_->handle_control_input (data,
+ *addr);
+
+ this->frame_.rd_ptr (sizeof(TAO_AV_RTP::rtphdr));
+ result = this->callback_->receive_frame (&this->frame_,
+ frame_info,
+ *addr);
+
+ return 0;
+}
+
+int
+TAO_AV_RTP_Object::send_frame (ACE_Message_Block *frame,
+ TAO_AV_frame_info *frame_info)
+{
+ TAO_AV_RTP::rtphdr header;
+ int result = -1;
+ if (frame_info != 0)
+ {
+ result = TAO_AV_RTP::write_header (header,
+ frame_info->format,
+ this->sequence_num_,
+ frame_info->timestamp,
+ frame_info->ssrc,
+ frame_info->boundary_marker);
+ frame_info->sequence_num = this->sequence_num_;
+ }
+ else
+ {
+ result = TAO_AV_RTP::write_header (header,
+ 0,
+ this->sequence_num_,
+ 0,
+ 0,
+ 0);
+ }
+ if (result < 0)
+ return result;
+
+ ACE_Message_Block mb ((char *)&header,
+ sizeof (header));
+ mb.wr_ptr (sizeof (header));
+ mb.cont (frame);
+ result = this->transport_->send (&mb);
+ if (result < 0)
+ ACE_ERROR_RETURN ( (LM_ERROR,"TAO_AV_RTP::send_frame failed\n"),result);
+ return 0;
+}
+
+int
+TAO_AV_RTP_Object::send_frame (const iovec *iov,
+ int iovcnt,
+ TAO_AV_frame_info *frame_info)
+{
+ TAO_AV_RTP::rtphdr header;
+ int format = 0;
+ int result = -1;
+ if (frame_info != 0)
+ {
+ result = TAO_AV_RTP::write_header (header,
+ frame_info->format,
+ this->sequence_num_,
+ frame_info->timestamp,
+ frame_info->ssrc,
+ frame_info->boundary_marker);
+ frame_info->sequence_num = this->sequence_num_;
+ }
+ else
+ {
+ result = TAO_AV_RTP::write_header (header,
+ 0,
+ this->sequence_num_,
+ 0,
+ 0,
+ 0);
+ }
+ if (result < 0)
+ return result;
+
+ iovec send_iov[IOV_MAX];
+ send_iov [0].iov_base = (char *)&header;
+ send_iov [0].iov_len = sizeof(header);
+ for (int i=1;i<=iovcnt; i++)
+ send_iov [i] = iov [i-1];
+ result = this->transport_->send (send_iov,
+ iovcnt+1);
+ if (result < 0)
+ ACE_ERROR_RETURN ((LM_ERROR,"TAO_AV_RTP::send_frame failed\n"),result);
+ return 0;
+}
+
+TAO_AV_RTP_Object::TAO_AV_RTP_Object (TAO_AV_Callback *callback,
+ TAO_AV_Transport *transport)
+ :TAO_AV_Protocol_Object (callback,transport),
+ sequence_num_ (0),
+ control_object_ (0)
+{
+ this->sequence_num_ = ACE_OS::rand ();
+
+ this->frame_.size (2 * this->transport_->mtu ());
+}
+
+TAO_AV_RTP_Object::~TAO_AV_RTP_Object (void)
+{
+}
+
+int
+TAO_AV_RTP_Object::destroy (void)
+{
+ this->control_object_->destroy ();
+ this->callback_->handle_destroy ();
+ return 0;
+}
+
+int
+TAO_AV_RTP_Object::set_policies (const TAO_AV_PolicyList &policy_list)
+{
+ this->policy_list_ = policy_list;
+ u_int num_policies = this->policy_list_.length ();
+ TAO_AV_Policy *policy = 0;
+ for (u_int i=0; i< num_policies;i++)
+ {
+ policy = this->policy_list_ [i];
+ switch (policy->type ())
+ {
+ case TAO_AV_PAYLOAD_TYPE_POLICY:
+ {
+ TAO_AV_Payload_Type_Policy *payload_policy =
+ ACE_static_cast (TAO_AV_Payload_Type_Policy *,policy);
+ if (payload_policy == 0)
+ ACE_ERROR_RETURN ( (LM_ERROR,"TAO_AV_RTP_Object::send_frame:Payload policy not defined\n"),-1);
+ this->format_ = payload_policy->value ();
+ }
+ break;
+ case TAO_AV_SSRC_POLICY:
+ {
+ TAO_AV_SSRC_Policy *ssrc_policy =
+ ACE_static_cast (TAO_AV_SSRC_Policy *,policy);
+ if (ssrc_policy == 0)
+ ACE_ERROR_RETURN ( (LM_ERROR,"TAO_AV_RTP_Object::send_frame:SSRC policy not defined\n"),-1);
+ this->ssrc_ = ssrc_policy->value ();;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+void
+TAO_AV_RTP_Object::control_object (TAO_AV_Protocol_Object *object)
+{
+ this->control_object_ = object;
+}
+
+int
+TAO_AV_RTP_Object::start (void)
+{
+ this->control_object_->start ();
+ return this->callback_->handle_start ();
+}
+
+int
+TAO_AV_RTP_Object::stop (void)
+{
+ this->control_object_->stop ();
+ return this->callback_->handle_stop ();
+}
+
+// TAO_AV_RTP_Flow_Factory
+TAO_AV_RTP_Flow_Factory::TAO_AV_RTP_Flow_Factory (void)
+{
+}
+
+TAO_AV_RTP_Flow_Factory::~TAO_AV_RTP_Flow_Factory (void)
+{
+}
+
+int
+TAO_AV_RTP_Flow_Factory::init (int /* argc */,
+ char * /* argv */ [])
+{
+ return 0;
+}
+
+TAO_AV_Protocol_Object*
+TAO_AV_RTP_Flow_Factory::make_protocol_object (TAO_FlowSpec_Entry *entry,
+ TAO_Base_StreamEndPoint *endpoint,
+ TAO_AV_Flow_Handler *handler,
+ TAO_AV_Transport *transport)
+{
+ TAO_AV_Callback *callback = 0;
+ endpoint->get_callback (entry->flowname (),
+ callback);
+
+ TAO_AV_Protocol_Object *object = 0;
+ ACE_NEW_RETURN (object,
+ TAO_AV_RTP_Object (callback,
+ transport),
+ 0);
+ callback->open (object,
+ handler);
+ endpoint->set_protocol_object (entry->flowname (),
+ object);
+ return object;
+}
+
+int
+TAO_AV_RTP_Flow_Factory::match_protocol (const char *flow_string)
+{
+ if (ACE_OS::strncasecmp (flow_string,"RTP",3) == 0)
+ return 1;
+ return 0;
+}
+
+const char *
+TAO_AV_RTP_Flow_Factory::control_flow_factory (void)
+{
+ return "RTCP";
+}
+
+ACE_FACTORY_DEFINE (AV, TAO_AV_RTP_Flow_Factory)
+ACE_STATIC_SVC_DEFINE (TAO_AV_RTP_Flow_Factory,
+ ASYS_TEXT ("RTP_Flow_Factory"),
+ ACE_SVC_OBJ_T,
+ &ACE_SVC_NAME (TAO_AV_RTP_Flow_Factory),
+ ACE_Service_Type::DELETE_THIS |
+ ACE_Service_Type::DELETE_OBJ,
+ 0)
diff --git a/TAO/orbsvcs/orbsvcs/AV/RTP.h b/TAO/orbsvcs/orbsvcs/AV/RTP.h
new file mode 100644
index 00000000000..a6de439f594
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/AV/RTP.h
@@ -0,0 +1,299 @@
+/* -*- C++ -*- */
+
+/*-
+ * Copyright (c) 1993-1994 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and the Network Research Group at
+ * Lawrence Berkeley Laboratory.
+ * 4. Neither the name of the University nor of the Laboratory may be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// ORBSVCS AVStreams
+//
+// = FILENAME
+// RTP.h
+//
+// = AUTHOR
+// Nagarajan Surendran <naga@cs.wustl.edu>
+//
+//
+// ============================================================================
+
+#ifndef TAO_AV_RTP_H
+#define TAO_AV_RTP_H
+
+#include "Protocol_Factory.h"
+
+#define RTP_PT_BVC 22 /* Berkeley video codec */
+
+/* RTP standard content encodings for video */
+#define RTP_PT_RGB8 23 /* 8-bit dithered RGB */
+#define RTP_PT_HDCC 24 /* SGI proprietary */
+#define RTP_PT_CELLB 25 /* Sun CellB */
+#define RTP_PT_JPEG 26 /* JPEG */
+#define RTP_PT_CUSEEME 27 /* Cornell CU-SeeMe */
+#define RTP_PT_NV 28 /* Xerox PARC nv */
+#define RTP_PT_PICW 29 /* BB&N PictureWindow */
+#define RTP_PT_CPV 30 /* Concept/Bolter/Viewpoint codec */
+#define RTP_PT_H261 31 /* ITU H.261 */
+#define RTP_PT_MPEG 32 /* MPEG-I & MPEG-II */
+#define RTP_PT_MP2T 33 /* MPEG-II either audio or video */
+
+/* backward compat hack for decoding RTPv1 ivs streams */
+#define RTP_PT_H261_COMPAT 127
+
+/* RTP standard content encodings for audio */
+#define RTP_PT_PCMU 0
+#define RTP_PT_CELP 1
+#define RTP_PT_GSM 3
+#define RTP_PT_DVI 5
+#define RTP_PT_LPC 7
+
+
+/* Offset from UNIX's epoch to the NTP epoch in seconds (NTP's JAN_1970) */
+#define RTP_EPOCH_OFFSET 2208988800UL
+#define RTP_VERSION 2
+
+#define RTP_M 0x0080 /* Marker: significant event <e.g. frame boundary> */
+#define RTP_P 0x2000 /* Padding is present */
+#define RTP_X 0x1000 /* Extension Header is present */
+
+
+#define RTCP_PT_SR 200 /* sender report */
+#define RTCP_PT_RR 201 /* receiver report */
+#define RTCP_PT_SDES 202 /* source description */
+#define RTCP_SDES_CNAME 1 /* official name (mandatory) */
+#define RTCP_SDES_NAME 2 /* personal name (optional) */
+#define RTCP_SDES_EMAIL 3 /* e-mail addr (optional) */
+#define RTCP_SDES_PHONE 4 /* telephone # (optional) */
+#define RTCP_SDES_LOC 5 /* geographical location */
+#define RTCP_SDES_TOOL 6 /* name/(vers) of app */
+#define RTCP_SDES_NOTE 7 /* transient messages */
+#define RTCP_SDES_PRIV 8 /* private SDES extensions */
+#define RTCP_PT_BYE 203 /* end of participation */
+#define RTCP_PT_APP 204 /* application specific functions */
+
+#define RTCP_SDES_MIN 1
+
+
+/*
+ * Parameters controling the RTCP report rate timer.
+ */
+#define RTCP_SESSION_BW_FRACTION (0.05)
+#define RTCP_MIN_RPT_TIME (5.)
+#define RTCP_SENDER_BW_FRACTION (0.25)
+#define RTCP_RECEIVER_BW_FRACTION (1. - RTCP_SENDER_BW_FRACTION)
+#define RTCP_SIZE_GAIN (1./8.)
+
+/*
+ * Largest (user-level) packet size generated by our rtp applications.
+ * Individual video formats may use smaller mtu's.
+ */
+#define RTP_MTU 1024
+
+#define MAXHDR 24
+
+#include "Policy.h"
+#include "FlowSpec_Entry.h"
+#include "MCast.h"
+//------------------------------------------------------------
+// TAO_AV_RTP_UDP
+//------------------------------------------------------------
+
+
+class TAO_AV_SourceManager;
+class TAO_AV_RTCP_UDP_Flow_Handler;
+class TAO_AV_RTP_State;
+
+//------------------------------------------------------------
+// TAO_AV_RTP
+//------------------------------------------------------------
+
+
+class TAO_AV_RTP
+{
+public:
+ /* Basic RTP header */
+ struct rtphdr
+ {
+ ACE_UINT16 rh_flags; /* T:2 P:1 X:1 CC:4 M:1 PT:7 */
+ ACE_UINT16 rh_seqno; /* sequence number */
+ ACE_UINT32 rh_ts; /* media-specific time stamp */
+ ACE_UINT32 rh_ssrc; /* synchronization src id */
+ /* data sources follow per cc */
+ };
+
+ /*
+ * Motion JPEG encapsulation.
+ *
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | MBZ | frag offset |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Type | Q | Width | Height |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ * Type = Index into a table of predefined JPEG parameters
+ * Width = Width of input in 8-pixel blocks
+ * Height = Height of input in 8-pixel blocks
+ * Q = Quality factor (0-100 = std, >100 = custom)
+ * Frag offset = The byte offset into the frame for the data in
+ * this packet
+ */
+ struct jpeghdr
+ {
+ ACE_UINT32 off; /* fragment offset */
+ unsigned char type; /* id of jpeg decoder params */
+ unsigned char q; /* quantization factor (or table id) */
+ unsigned char width; /* 1/8 frame width */
+ unsigned char height; /* 1/8 frame height */
+ };
+
+ /*
+ * NV encapsulation.
+ */
+ struct nvhdr
+ {
+ ACE_UINT16 width;
+ ACE_UINT16 height;
+ /* nv data */
+ };
+
+ /*
+ * CellB encapsulation.
+ */
+ struct cellbhdr
+ {
+ ACE_UINT16 x;
+ ACE_UINT16 y;
+ ACE_UINT16 width;
+ ACE_UINT16 height;
+ /* cells */
+ };
+
+ /*
+ * H.261 encapsulation.
+ * See Internet draft.
+ *
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |SBIT |EBIT |I|V| GOBN | MBAP | QUANT | HMVD | VMVD |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+#ifdef notdef
+ struct h261hdr
+ {
+ ACE_UINT16 flags;
+ ACE_UINT16 off;
+ };
+#endif
+
+ struct bvchdr
+ {
+ unsigned char version;
+ unsigned char pad;
+ unsigned char width;
+ unsigned char height;
+ ACE_UINT32 quant;
+ unsigned char sbit;
+ unsigned char ebit;
+ ACE_UINT16 blkno;
+ };
+
+ static int handle_input (ACE_Message_Block *&data,
+ TAO_AV_frame_info *&frame_info);
+
+ static int write_header (rtphdr &header,
+ int format,
+ ACE_UINT16 &sequence_num,
+ ACE_UINT32 ts,
+ ACE_UINT32 ssrc,
+ CORBA::Boolean boundary_marker);
+
+};
+
+
+class TAO_AV_RTP_Object : public TAO_AV_Protocol_Object
+{
+public:
+ TAO_AV_RTP_Object (TAO_AV_Callback *callback,
+ TAO_AV_Transport *transport);
+
+ virtual ~TAO_AV_RTP_Object (void);
+
+ virtual int start (void);
+ virtual int stop (void);
+ virtual int handle_input (void);
+ virtual int send_frame (ACE_Message_Block *frame,
+ TAO_AV_frame_info *frame_info = 0);
+
+ virtual int send_frame (const iovec *iov,
+ int iovcnt,
+ TAO_AV_frame_info *frame_info = 0);
+
+ virtual int destroy (void);
+ virtual int set_policies (const TAO_AV_PolicyList &policy_list);
+ virtual void control_object (TAO_AV_Protocol_Object *object);
+
+protected:
+ ACE_UINT16 sequence_num_;
+ int format_;
+ CORBA::ULong ssrc_;
+ TAO_AV_Protocol_Object *control_object_;
+
+ ACE_Message_Block frame_;
+ // Pre-allocated memory to receive the data...
+};
+
+class TAO_ORBSVCS_Export TAO_AV_RTP_Flow_Factory : public TAO_AV_Flow_Protocol_Factory
+{
+public:
+ TAO_AV_RTP_Flow_Factory (void);
+ virtual ~TAO_AV_RTP_Flow_Factory (void);
+ virtual int init (int argc, char *argv[]);
+ // Initialization hook.
+ virtual int match_protocol (const char *flow_string);
+ virtual TAO_AV_Protocol_Object* make_protocol_object (TAO_FlowSpec_Entry *entry,
+ TAO_Base_StreamEndPoint *endpoint,
+ TAO_AV_Flow_Handler *handler,
+ TAO_AV_Transport *transport);
+ virtual const char*control_flow_factory (void);
+};
+
+ACE_STATIC_SVC_DECLARE (TAO_AV_RTP_Flow_Factory)
+ACE_FACTORY_DECLARE (TAO_ORBSVCS, TAO_AV_RTP_Flow_Factory)
+
+#endif /* TAO_AV_RTP_H */
diff --git a/TAO/orbsvcs/orbsvcs/AV/TCP.cpp b/TAO/orbsvcs/orbsvcs/AV/TCP.cpp
new file mode 100644
index 00000000000..a8a99fef6dd
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/AV/TCP.cpp
@@ -0,0 +1,677 @@
+// $Id$
+
+#include "TCP.h"
+#include "AVStreams_i.h"
+
+//------------------------------------------------------------
+// TAO_AV_TCP_Transport
+//------------------------------------------------------------
+
+TAO_AV_TCP_Transport::TAO_AV_TCP_Transport (void)
+ :handler_ (0)
+{
+}
+
+TAO_AV_TCP_Transport::TAO_AV_TCP_Transport (TAO_AV_TCP_Flow_Handler *handler)
+ :handler_ (handler)
+{
+}
+
+TAO_AV_TCP_Transport::~TAO_AV_TCP_Transport (void)
+{
+}
+
+int
+TAO_AV_TCP_Transport::open (ACE_Addr */*address*/)
+{
+ return 0;
+}
+
+int
+TAO_AV_TCP_Transport::close (void)
+{
+ return 0;
+}
+
+int
+TAO_AV_TCP_Transport::mtu (void)
+{
+ return -1;
+}
+
+ACE_Addr*
+TAO_AV_TCP_Transport::get_peer_addr (void)
+{
+ return 0;
+}
+
+ssize_t
+TAO_AV_TCP_Transport::send (const ACE_Message_Block *mblk, ACE_Time_Value *)
+{
+ // For the most part this was copied from GIOP::send_request and
+ // friends.
+
+ iovec iov[IOV_MAX];
+ int iovcnt = 0;
+ ssize_t n = 0;
+ ssize_t nbytes = 0;
+
+ for (const ACE_Message_Block *i = mblk;
+ i != 0;
+ i = i->cont ())
+ {
+ // Make sure there is something to send!
+ if (i->length () > 0)
+ {
+ iov[iovcnt].iov_base = i->rd_ptr ();
+ iov[iovcnt].iov_len = i->length ();
+ iovcnt++;
+
+ // The buffer is full make a OS call. @@ TODO this should
+ // be optimized on a per-platform basis, for instance, some
+ // platforms do not implement writev() there we should copy
+ // the data into a buffer and call send_n(). In other cases
+ // there may be some limits on the size of the iovec, there
+ // we should set IOV_MAX to that limit.
+ if (iovcnt == IOV_MAX)
+ {
+ n = this->handler_->peer ().sendv_n ((const iovec *) iov,
+ iovcnt);
+ if (n < 1)
+ return n;
+
+ nbytes += n;
+ iovcnt = 0;
+ }
+ }
+ }
+
+ // Check for remaining buffers to be sent!
+ if (iovcnt != 0)
+ {
+ n = this->handler_->peer ().sendv_n ((const iovec *) iov,
+ iovcnt);
+ if (n < 1)
+ return n;
+
+ nbytes += n;
+ }
+
+ return nbytes;
+}
+
+ssize_t
+TAO_AV_TCP_Transport::send (const char *buf,
+ size_t len,
+ ACE_Time_Value *)
+{
+ return this->handler_->peer ().send_n (buf, len);
+}
+
+ssize_t
+TAO_AV_TCP_Transport::send (const iovec *iov,
+ int iovcnt,
+ ACE_Time_Value *)
+{
+ return this->handler_->peer ().sendv_n ((const iovec *) iov,
+ iovcnt);
+}
+
+ssize_t
+TAO_AV_TCP_Transport::recv (char *buf,
+ size_t len,
+ ACE_Time_Value *)
+{
+ return this->handler_->peer ().recv (buf, len);
+}
+
+ssize_t
+TAO_AV_TCP_Transport::recv (char *buf,
+ size_t len,
+ int flags,
+ ACE_Time_Value *)
+{
+ return this->handler_->peer ().recv (buf,
+ len,
+ flags);
+}
+
+ssize_t
+TAO_AV_TCP_Transport::recv (iovec *iov,
+ int iovcnt,
+ ACE_Time_Value *)
+{
+ return handler_->peer ().recvv_n (iov, iovcnt);
+}
+
+//------------------------------------------------------------
+// TAO_AV_TCP_Protocol_Factory
+//------------------------------------------------------------
+
+TAO_AV_TCP_Factory::TAO_AV_TCP_Factory (void)
+{
+}
+
+TAO_AV_TCP_Factory::~TAO_AV_TCP_Factory (void)
+{
+}
+
+int
+TAO_AV_TCP_Factory::init (int /* argc */,
+ char * /* argv */ [])
+{
+ return 0;
+}
+
+int
+TAO_AV_TCP_Factory::match_protocol (const char *protocol_string)
+{
+ if (ACE_OS::strcasecmp (protocol_string,"TCP") == 0)
+ return 1;
+ return 0;
+}
+
+TAO_AV_Acceptor*
+TAO_AV_TCP_Factory::make_acceptor (void)
+{
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"TAO_AV_TCP_Factory::make_acceptor "));
+ TAO_AV_Acceptor *acceptor = 0;
+ ACE_NEW_RETURN (acceptor,
+ TAO_AV_TCP_Acceptor,
+ 0);
+ return acceptor;
+}
+
+TAO_AV_Connector*
+TAO_AV_TCP_Factory::make_connector (void)
+{
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"TAO_AV_TCP_Factory::make_connector "));
+ TAO_AV_Connector *connector = 0;
+ ACE_NEW_RETURN (connector,
+ TAO_AV_TCP_Connector,
+ 0);
+ return connector;
+}
+
+//------------------------------------------------------------
+// TAO_AV_TCP_Object
+//------------------------------------------------------------
+
+int
+TAO_AV_TCP_Object::handle_input (void)
+{
+ int n = this->transport_->recv (this->frame_.rd_ptr (),
+ this->frame_.size ());
+ if (n == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,"TAO_AV_TCP_Flow_Handler::handle_input recv failed\n"),-1);
+ if (n == 0)
+ ACE_ERROR_RETURN ((LM_ERROR,"TAO_AV_TCP_Flow_Handler::handle_input connection closed\n"),-1);
+ this->frame_.wr_ptr (this->frame_.rd_ptr () + n);
+
+ return this->callback_->receive_frame (&this->frame_);
+}
+
+int
+TAO_AV_TCP_Object::send_frame (ACE_Message_Block *frame,
+ TAO_AV_frame_info *frame_info)
+{
+ int result = this->transport_->send (frame);
+ if (result < 0)
+ return result;
+ return 0;
+}
+
+int
+TAO_AV_TCP_Object::send_frame (const iovec *iov,
+ int iovcnt,
+ TAO_AV_frame_info *frame_info)
+{
+ return this->transport_->send (iov,iovcnt);
+}
+
+TAO_AV_TCP_Object::TAO_AV_TCP_Object (TAO_AV_Callback *callback,
+ TAO_AV_Transport *transport)
+ :TAO_AV_Protocol_Object (callback,transport)
+{
+ // @@ Is this a good size?
+ this->frame_.size (BUFSIZ);
+}
+
+TAO_AV_TCP_Object::~TAO_AV_TCP_Object (void)
+{
+ // No-op
+}
+int
+TAO_AV_TCP_Object::destroy (void)
+{
+ this->callback_->handle_destroy ();
+ return 0;
+}
+
+//------------------------------------------------------------
+// TAO_AV_TCP_Flow_Factory
+//------------------------------------------------------------
+TAO_AV_TCP_Flow_Factory::TAO_AV_TCP_Flow_Factory (void)
+{
+}
+
+TAO_AV_TCP_Flow_Factory::~TAO_AV_TCP_Flow_Factory (void)
+{
+}
+
+int
+TAO_AV_TCP_Flow_Factory::init (int /* argc */,
+ char * /* argv */ [])
+{
+ return 0;
+}
+
+int
+TAO_AV_TCP_Flow_Factory::match_protocol (const char *flow_string)
+{
+ if (ACE_OS::strcasecmp (flow_string,"TCP") == 0)
+ return 1;
+ return 0;
+}
+
+TAO_AV_Protocol_Object*
+TAO_AV_TCP_Flow_Factory::make_protocol_object (TAO_FlowSpec_Entry *entry,
+ TAO_Base_StreamEndPoint *endpoint,
+ TAO_AV_Flow_Handler *handler,
+ TAO_AV_Transport *transport)
+{
+ TAO_AV_Callback *callback = 0;
+ endpoint->get_callback (entry->flowname (),
+ callback);
+
+ TAO_AV_TCP_Object *object = 0;
+ ACE_NEW_RETURN (object,
+ TAO_AV_TCP_Object (callback,
+ transport),
+ 0);
+ callback->open (object,
+ handler);
+ endpoint->set_protocol_object (entry->flowname (),
+ object);
+ return object;
+}
+
+//------------------------------------------------------------
+// TAO_AV_TCP_Base_Connector
+//------------------------------------------------------------
+
+int
+TAO_AV_TCP_Base_Connector::connector_open (TAO_AV_TCP_Connector *connector,
+ ACE_Reactor *reactor)
+{
+ this->connector_ = connector;
+ this->reactor_ = reactor;
+
+ int result = ACE_Connector <TAO_AV_TCP_Flow_Handler,ACE_SOCK_CONNECTOR>::open (reactor);
+ if (result < 0)
+ ACE_ERROR_RETURN ((LM_ERROR,"TAO_AV_TCP_Base_Connector::open failed\n"),-1);
+ return 0;
+}
+
+int
+TAO_AV_TCP_Base_Connector::make_svc_handler (TAO_AV_TCP_Flow_Handler *&tcp_handler)
+{
+ int result =
+ this->connector_->make_svc_handler (tcp_handler);
+ if (result < 0)
+ return result;
+ tcp_handler->reactor (this->reactor_);
+ return 0;
+}
+
+int
+TAO_AV_TCP_Base_Connector::connector_connect (TAO_AV_TCP_Flow_Handler *&handler,
+ const ACE_INET_Addr &remote_addr)
+{
+ int result = ACE_Connector <TAO_AV_TCP_Flow_Handler,ACE_SOCK_CONNECTOR>::connect (handler,
+ remote_addr);
+ if (result < 0)
+ ACE_ERROR_RETURN ((LM_ERROR,"TAO_AV_TCP_Base_Connector::connect failed\n"),-1);
+ return 0;
+}
+
+//------------------------------------------------------------
+// TAO_AV_TCP_Connector
+//------------------------------------------------------------
+TAO_AV_TCP_Connector::TAO_AV_TCP_Connector (void)
+{
+}
+
+TAO_AV_TCP_Connector::~TAO_AV_TCP_Connector (void)
+{
+}
+
+int
+TAO_AV_TCP_Connector::make_svc_handler (TAO_AV_TCP_Flow_Handler *&tcp_handler)
+{
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"TAO_AV_TCP_Connector::make_svc_handler\n"));
+ TAO_AV_Callback *callback = 0;
+ if (this->endpoint_ != 0)
+ {
+// this->endpoint_->get_callback (this->flowname_.c_str (),
+// callback);
+ ACE_NEW_RETURN (tcp_handler,
+ // TAO_AV_TCP_Flow_Handler (callback),
+ TAO_AV_TCP_Flow_Handler,
+ -1);
+ TAO_AV_Protocol_Object *object =
+ this->flow_protocol_factory_->make_protocol_object (this->entry_,
+ this->endpoint_,
+ tcp_handler,
+ tcp_handler->transport ());
+ tcp_handler->protocol_object (object);
+ // callback->protocol_object (object);
+// this->endpoint_->set_protocol_object (this->flowname_.c_str (),
+// object);
+ this->endpoint_->set_handler (this->flowname_.c_str (),tcp_handler);
+ this->entry_->protocol_object (object);
+ this->entry_->handler (tcp_handler);
+ }
+ return 0;
+}
+
+int
+TAO_AV_TCP_Connector::open (TAO_Base_StreamEndPoint *endpoint,
+ TAO_AV_Core *av_core,
+ TAO_AV_Flow_Protocol_Factory *factory)
+
+{
+ this->endpoint_ = endpoint;
+ this->flow_protocol_factory_ = factory;
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"TAO_AV_TCP_Connector::open "));
+ int result = this->connector_.connector_open(this,
+ av_core->reactor ());
+ return result;
+}
+
+int
+TAO_AV_TCP_Connector::connect (TAO_FlowSpec_Entry *entry,
+ TAO_AV_Transport *&transport)
+{
+ this->entry_ = entry;
+ this->flowname_ = entry->flowname ();
+ ACE_Addr *remote_addr = entry->address ();
+ ACE_INET_Addr *inet_addr = ACE_dynamic_cast (ACE_INET_Addr *,remote_addr);
+ TAO_AV_TCP_Flow_Handler *handler;
+ int result = this->connector_.connector_connect (handler,
+ *inet_addr);
+ if (result < 0)
+ ACE_ERROR_RETURN ((LM_ERROR,"TAO_AV_TCP_connector::open failed\n"),-1);
+ entry->handler (handler);
+ transport = handler->transport ();
+ return 0;
+}
+
+int
+TAO_AV_TCP_Connector::close (void)
+{
+ return 0;
+}
+
+//------------------------------------------------------------
+// TAO_AV_TCP_Base_Connector
+//------------------------------------------------------------
+
+int
+TAO_AV_TCP_Base_Acceptor::open (TAO_AV_TCP_Acceptor *acceptor,
+ ACE_Reactor *reactor,
+ const ACE_INET_Addr &local_addr,
+ TAO_FlowSpec_Entry *entry)
+{
+ this->acceptor_ = acceptor;
+ this->reactor_ = reactor;
+ this->entry_ = entry;
+
+ int result = ACE_Acceptor <TAO_AV_TCP_Flow_Handler,ACE_SOCK_ACCEPTOR>::open (local_addr,reactor);
+ if (result < 0)
+ ACE_ERROR_RETURN ((LM_ERROR,"TAO_AV_TCP_Base_Connector::open failed\n"),-1);
+ return 0;
+}
+
+int
+TAO_AV_TCP_Base_Acceptor::make_svc_handler (TAO_AV_TCP_Flow_Handler *&handler)
+{
+ int result = this->acceptor_->make_svc_handler (handler);
+ if (result < 0)
+ return result;
+ handler->reactor (this->reactor_);
+ this->entry_->handler (handler);
+ return 0;
+}
+
+
+//------------------------------------------------------------
+// TAO_AV_TCP_Acceptor
+//------------------------------------------------------------
+
+TAO_AV_TCP_Acceptor::TAO_AV_TCP_Acceptor (void)
+{
+}
+
+TAO_AV_TCP_Acceptor::~TAO_AV_TCP_Acceptor (void)
+{
+}
+
+int
+TAO_AV_TCP_Acceptor::make_svc_handler (TAO_AV_TCP_Flow_Handler *&tcp_handler)
+{
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"TAO_AV_TCP_Acceptor::make_svc_handler\n"));
+ // TAO_AV_Callback *callback = 0;
+ if (this->endpoint_ != 0)
+ {
+// this->endpoint_->get_callback (this->flowname_.c_str (),
+// callback);
+ ACE_NEW_RETURN (tcp_handler,
+ // TAO_AV_TCP_Flow_Handler (callback),
+ TAO_AV_TCP_Flow_Handler,
+ -1);
+ TAO_AV_Protocol_Object *object =
+// this->flow_protocol_factory_->make_protocol_object (callback,
+// tcp_handler->transport ());
+ this->flow_protocol_factory_->make_protocol_object (this->entry_,
+ this->endpoint_,
+ tcp_handler,
+ tcp_handler->transport ());
+ tcp_handler->protocol_object (object);
+ // callback->protocol_object (object);
+// this->endpoint_->set_protocol_object (this->flowname_.c_str (),
+// object);
+ this->endpoint_->set_handler (this->flowname_.c_str (),tcp_handler);
+ this->entry_->protocol_object (object);
+ this->entry_->handler (tcp_handler);
+ }
+ return 0;
+}
+
+int
+TAO_AV_TCP_Acceptor::open (TAO_Base_StreamEndPoint *endpoint,
+ TAO_AV_Core *av_core,
+ TAO_FlowSpec_Entry *entry,
+ TAO_AV_Flow_Protocol_Factory *factory)
+{
+ this->flow_protocol_factory_ = factory;
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"TAO_AV_TCP_Acceptor::open "));
+ this->av_core_ = av_core;
+ this->endpoint_ = endpoint;
+ this->entry_ = entry;
+ this->flowname_ = entry->flowname ();
+ ACE_Addr *address = entry->address ();
+ ACE_INET_Addr *inet_addr = (ACE_INET_Addr *) address;
+ inet_addr->set (inet_addr->get_port_number (),
+ inet_addr->get_host_name ());
+ char buf[BUFSIZ];
+ inet_addr->addr_to_string (buf,
+ BUFSIZ);
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"TAO_AV_TCP_Acceptor::open: %s",
+ buf));
+ int result = this->acceptor_.open (this,
+ av_core->reactor (),
+ *inet_addr,
+ entry);
+ if (result < 0)
+ ACE_ERROR_RETURN ((LM_ERROR,"TAO_AV_TCP_Acceptor::open failed"),-1);
+ entry->set_local_addr (address);
+ return 0;
+}
+
+int
+TAO_AV_TCP_Acceptor::open_default (TAO_Base_StreamEndPoint *endpoint,
+ TAO_AV_Core *av_core,
+ TAO_FlowSpec_Entry *entry,
+ TAO_AV_Flow_Protocol_Factory *factory)
+{
+ this->flow_protocol_factory_ = factory;
+ this->av_core_ = av_core;
+ this->endpoint_ = endpoint;
+ this->entry_ = entry;
+ this->flowname_ = entry->flowname ();
+ ACE_INET_Addr *address;
+ ACE_NEW_RETURN (address,
+ ACE_INET_Addr ("0"),
+ -1);
+ int result = this->acceptor_.open (this,
+ av_core->reactor (),
+ *address,
+ entry);
+
+ if (result < 0)
+ ACE_ERROR_RETURN ((LM_ERROR,"TAO_AV_TCP_Acceptor::open failed"),-1);
+ this->acceptor_.acceptor ().get_local_addr (*address);
+ address->set (address->get_port_number (),
+ address->get_host_name ());
+ char buf[BUFSIZ];
+ address->addr_to_string (buf,BUFSIZ);
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"TAO_AV_TCP_Acceptor::open_default: %s\n",buf));
+ entry->set_local_addr (address);
+ return 0;
+}
+
+
+int
+TAO_AV_TCP_Acceptor::close (void)
+{
+ return 0;
+}
+
+//------------------------------------------------------------
+// TAO_AV_TCP_Flow_Handler
+//------------------------------------------------------------
+
+TAO_AV_TCP_Flow_Handler::TAO_AV_TCP_Flow_Handler (TAO_AV_Callback *callback)
+ // :TAO_AV_Flow_Handler (callback)
+{
+ ACE_NEW (this->transport_,
+ TAO_AV_TCP_Transport (this));
+}
+
+TAO_AV_Transport *
+TAO_AV_TCP_Flow_Handler::transport (void)
+{
+ return this->transport_;
+}
+
+int
+TAO_AV_TCP_Flow_Handler::open (void *arg)
+{
+
+ int nodelay = 1;
+
+#if defined (TCP_NODELAY)
+ if (this->peer ().set_option (IPPROTO_TCP,
+ TCP_NODELAY,
+ (void *) &nodelay,
+ sizeof (nodelay)) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "NODELAY failed\n"),
+ -1);
+#endif /* TCP_NODELAY */
+
+ // Called by the <Strategy_Acceptor> when the handler is completely
+ // connected.
+ ACE_INET_Addr addr;
+
+ if (this->peer ().get_remote_addr (addr) == -1)
+ return -1;
+
+ char server[MAXHOSTNAMELEN + 16];
+
+ (void) addr.addr_to_string (server, sizeof (server));
+
+ if (TAO_debug_level > 0)
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,
+ "(%P|%t) connection to server <%s> on %d\n",
+ server, this->peer ().get_handle ()));
+
+ this->peer ().enable (ACE_NONBLOCK);
+ // Register the handler with the reactor.
+ if (this->reactor ()
+ && this->reactor ()->register_handler
+ (this,
+ ACE_Event_Handler::READ_MASK) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ASYS_TEXT ("%p\n"),
+ ASYS_TEXT ("unable to register client handler")),
+ -1);
+}
+
+int
+TAO_AV_TCP_Flow_Handler::handle_input (ACE_HANDLE /*fd*/)
+{
+ return this->protocol_object_->handle_input ();
+}
+
+int
+TAO_AV_TCP_Flow_Handler::handle_timeout (const ACE_Time_Value &tv,
+ const void *arg)
+{
+ return TAO_AV_Flow_Handler::handle_timeout (tv,arg);
+}
+
+#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
+template class ACE_Acceptor<TAO_AV_TCP_Flow_Handler, ACE_SOCK_ACCEPTOR>;
+template class ACE_Connector<TAO_AV_TCP_Flow_Handler, ACE_SOCK_CONNECTOR>;
+
+template class ACE_Svc_Tuple<TAO_AV_TCP_Flow_Handler>;
+template class ACE_Map_Entry<ACE_HANDLE, ACE_Svc_Tuple<TAO_AV_TCP_Flow_Handler> *>;
+template class ACE_Map_Manager<ACE_HANDLE, ACE_Svc_Tuple<TAO_AV_TCP_Flow_Handler> *, ACE_SYNCH_RW_MUTEX>;
+template class ACE_Map_Iterator_Base<ACE_HANDLE, ACE_Svc_Tuple<TAO_AV_TCP_Flow_Handler> *, ACE_SYNCH_RW_MUTEX>;
+template class ACE_Map_Iterator<ACE_HANDLE, ACE_Svc_Tuple<TAO_AV_TCP_Flow_Handler> *, ACE_SYNCH_RW_MUTEX>;
+template class ACE_Map_Reverse_Iterator<ACE_HANDLE, ACE_Svc_Tuple<TAO_AV_TCP_Flow_Handler> *, ACE_SYNCH_RW_MUTEX>;
+
+#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
+#pragma instantiate ACE_Acceptor<TAO_AV_TCP_Flow_Handler, ACE_SOCK_Acceptor, ACE_INET_Addr>
+#pragma instantiate ACE_Connector<TAO_AV_TCP_Flow_Handler, ACE_SOCK_Connector, ACE_INET_Addr>
+
+#pragma instantiate ACE_Svc_Tuple<TAO_AV_TCP_Flow_Handler>
+#pragma instantiate ACE_Map_Entry<ACE_HANDLE, ACE_Svc_Tuple<TAO_AV_TCP_Flow_Handler> *>
+#pragma instantiate ACE_Map_Manager<ACE_HANDLE, ACE_Svc_Tuple<TAO_AV_TCP_Flow_Handler> *, ACE_SYNCH_RW_MUTEX>
+#pragma instantiate ACE_Map_Iterator_Base<ACE_HANDLE, ACE_Svc_Tuple<TAO_AV_TCP_Flow_Handler> *, ACE_SYNCH_RW_MUTEX>
+#pragma instantiate ACE_Map_Iterator<ACE_HANDLE, ACE_Svc_Tuple<TAO_AV_TCP_Flow_Handler> *, ACE_SYNCH_RW_MUTEX>
+#pragma instantiate ACE_Map_Reverse_Iterator<ACE_HANDLE, ACE_Svc_Tuple<TAO_AV_TCP_Flow_Handler> *, ACE_SYNCH_RW_MUTEX>
+
+#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */
+
+ACE_STATIC_SVC_DEFINE (TAO_AV_TCP_Flow_Factory,
+ ASYS_TEXT ("TCP_Flow_Factory"),
+ ACE_SVC_OBJ_T,
+ &ACE_SVC_NAME (TAO_AV_TCP_Flow_Factory),
+ ACE_Service_Type::DELETE_THIS |
+ ACE_Service_Type::DELETE_OBJ,
+ 0)
+
+ACE_FACTORY_DEFINE (AV, TAO_AV_TCP_Flow_Factory)
+
+ACE_STATIC_SVC_DEFINE (TAO_AV_TCP_Factory,
+ ASYS_TEXT ("TCP_Factory"),
+ ACE_SVC_OBJ_T,
+ &ACE_SVC_NAME (TAO_AV_TCP_Factory),
+ ACE_Service_Type::DELETE_THIS |
+ ACE_Service_Type::DELETE_OBJ,
+ 0)
+
+ACE_FACTORY_DEFINE (AV, TAO_AV_TCP_Factory)
diff --git a/TAO/orbsvcs/orbsvcs/AV/TCP.h b/TAO/orbsvcs/orbsvcs/AV/TCP.h
new file mode 100644
index 00000000000..da9b2d37c04
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/AV/TCP.h
@@ -0,0 +1,236 @@
+/* -*- C++ -*- */
+
+// $Id$
+// ============================================================================
+//
+// = LIBRARY
+// ORBSVCS AVStreams
+//
+// = FILENAME
+// TCP.h
+//
+// = AUTHOR
+// Nagarajan Surendran <naga@cs.wustl.edu>
+//
+//
+// ============================================================================
+
+#if !defined TAO_AV_TCP_H
+#define TAO_AV_TCP_H
+
+#include "ace/OS.h"
+#include "Protocol_Factory.h"
+#include "FlowSpec_Entry.h"
+
+class TAO_ORBSVCS_Export TAO_AV_TCP_Factory : public TAO_AV_Transport_Factory
+{
+public:
+ TAO_AV_TCP_Factory (void);
+ virtual ~TAO_AV_TCP_Factory (void);
+ virtual int init (int argc, char *argv[]);
+ // Initialization hook.
+ virtual int match_protocol (const char *protocol_string);
+ virtual TAO_AV_Acceptor *make_acceptor (void);
+ virtual TAO_AV_Connector *make_connector (void);
+};
+
+class TAO_AV_TCP_Flow_Handler;
+
+class TAO_AV_TCP_Transport
+ :public TAO_AV_Transport
+{
+ // = TITLE
+ // A transport abstraction for socket streams.
+ //
+ // = DESCRIPTION
+ // Uses the ACE_SOCK_Stream to send the data.
+public:
+ TAO_AV_TCP_Transport (void);
+
+ TAO_AV_TCP_Transport (TAO_AV_TCP_Flow_Handler *handler);
+
+ virtual ~TAO_AV_TCP_Transport (void);
+
+ virtual int open (ACE_Addr *address);
+
+ virtual int close (void);
+
+ virtual int mtu (void);
+
+ virtual ACE_Addr *get_peer_addr (void);
+
+ virtual ssize_t send (const ACE_Message_Block *mblk,
+ ACE_Time_Value *s = 0);
+ // Write the complete Message_Block chain to the connection.
+
+ virtual ssize_t send (const char *buf,
+ size_t len,
+ ACE_Time_Value *s = 0);
+ // Write the contents of the buffer of length len to the connection.
+
+ virtual ssize_t send (const iovec *iov,
+ int iovcnt,
+ ACE_Time_Value *s = 0);
+ // Write the contents of iovcnt iovec's to the connection.
+
+ virtual ssize_t recv (char *buf,
+ size_t len,
+ ACE_Time_Value *s = 0);
+ // Read len bytes from into buf.
+
+ virtual ssize_t recv (char *buf,
+ size_t len,
+ int flags,
+ ACE_Time_Value *s = 0);
+ // Read len bytes from into buf using flags.
+
+ virtual ssize_t recv (iovec *iov,
+ int iovcnt,
+ ACE_Time_Value *s = 0);
+ // Read received data into the iovec buffers.
+protected:
+ TAO_AV_TCP_Flow_Handler *handler_;
+};
+
+class TAO_AV_TCP_Flow_Handler
+ :public virtual TAO_AV_Flow_Handler,
+ public ACE_Svc_Handler <ACE_SOCK_STREAM, ACE_NULL_SYNCH>
+{
+public:
+ TAO_AV_TCP_Flow_Handler (TAO_AV_Callback *callback = 0);
+ virtual TAO_AV_Transport *transport (void);
+ virtual int open (void * = 0);
+ virtual int handle_input (ACE_HANDLE fd);
+ virtual int handle_timeout (const ACE_Time_Value &tv, const void *arg = 0);
+ virtual ACE_Event_Handler* event_handler (void){ return this; }
+protected:
+ TAO_AV_Core *av_core_;
+};
+
+class TAO_AV_TCP_Acceptor;
+
+class TAO_AV_TCP_Base_Acceptor :public ACE_Acceptor <TAO_AV_TCP_Flow_Handler,ACE_SOCK_ACCEPTOR>
+{
+public:
+ virtual int open (TAO_AV_TCP_Acceptor *acceptor,
+ ACE_Reactor *reactor,
+ const ACE_INET_Addr &local_addr,
+ TAO_FlowSpec_Entry *entry);
+ virtual int make_svc_handler (TAO_AV_TCP_Flow_Handler *& handler);
+protected:
+ TAO_AV_TCP_Acceptor *acceptor_;
+ ACE_Reactor *reactor_;
+ TAO_FlowSpec_Entry *entry_;
+};
+
+class TAO_AV_TCP_Acceptor :public TAO_AV_Acceptor
+{
+public:
+ TAO_AV_TCP_Acceptor (void);
+ virtual ~TAO_AV_TCP_Acceptor (void);
+
+ virtual int open (TAO_Base_StreamEndPoint *endpoint,
+ TAO_AV_Core *av_core,
+ TAO_FlowSpec_Entry *entry,
+ TAO_AV_Flow_Protocol_Factory *factory);
+
+ virtual int open_default (TAO_Base_StreamEndPoint *endpoint,
+ TAO_AV_Core *av_core,
+ TAO_FlowSpec_Entry *entry,
+ TAO_AV_Flow_Protocol_Factory *factory);
+
+ virtual int close (void);
+ virtual int make_svc_handler (TAO_AV_TCP_Flow_Handler *&handler);
+protected:
+ TAO_AV_TCP_Base_Acceptor acceptor_;
+ TAO_FlowSpec_Entry *entry_;
+ TAO_Base_StreamEndPoint *endpoint_;
+ TAO_AV_Flow_Protocol_Factory *flow_protocol_factory_;
+};
+
+class TAO_AV_TCP_Connector;
+
+class TAO_AV_TCP_Base_Connector : public ACE_Connector <TAO_AV_TCP_Flow_Handler,ACE_SOCK_CONNECTOR>
+{
+public:
+ // To avoid warnings of open and connect hiding the base class functions these have to renamed.
+ int connector_open (TAO_AV_TCP_Connector *connector,
+ ACE_Reactor *reactor);
+ int connector_connect (TAO_AV_TCP_Flow_Handler *&handler,
+ const ACE_INET_Addr &remote_addr);
+ virtual int make_svc_handler (TAO_AV_TCP_Flow_Handler *& handler);
+protected:
+ TAO_AV_TCP_Connector *connector_;
+ ACE_Reactor *reactor_;
+};
+
+class TAO_AV_TCP_Connector : public TAO_AV_Connector
+{
+public:
+ TAO_AV_TCP_Connector (void);
+ virtual ~TAO_AV_TCP_Connector (void);
+
+ virtual int open (TAO_Base_StreamEndPoint *endpoint,
+ TAO_AV_Core *av_core,
+ TAO_AV_Flow_Protocol_Factory *factory);
+
+ virtual int connect (TAO_FlowSpec_Entry *entry,
+ TAO_AV_Transport *&transport);
+ virtual int close (void);
+ virtual int make_svc_handler (TAO_AV_TCP_Flow_Handler *&handler);
+protected:
+ TAO_AV_Core *av_core_;
+ TAO_AV_TCP_Base_Connector connector_;
+ TAO_Base_StreamEndPoint *endpoint_;
+ TAO_FlowSpec_Entry *entry_;
+ TAO_AV_Flow_Protocol_Factory *flow_protocol_factory_;
+};
+
+class TAO_ORBSVCS_Export TAO_AV_TCP_Object : public TAO_AV_Protocol_Object
+{
+public:
+ TAO_AV_TCP_Object (TAO_AV_Callback *callback,
+ TAO_AV_Transport *transport = 0);
+
+ virtual ~TAO_AV_TCP_Object (void);
+ // Dtor
+
+ virtual int handle_input (void);
+
+ virtual int send_frame (ACE_Message_Block *frame,
+ TAO_AV_frame_info *frame_info = 0);
+ // send a data frame.
+
+ virtual int send_frame (const iovec *iov,
+ int iovcnt,
+ TAO_AV_frame_info *frame_info = 0);
+
+ virtual int destroy (void);
+ // end the stream.
+
+private:
+ ACE_Message_Block frame_;
+ // Pre-allocated memory to receive the data...
+};
+
+class TAO_AV_TCP_Flow_Factory : public TAO_AV_Flow_Protocol_Factory
+{
+public:
+ TAO_AV_TCP_Flow_Factory (void);
+ virtual ~TAO_AV_TCP_Flow_Factory (void);
+ virtual int init (int argc, char *argv[]);
+ // Initialization hook.
+ virtual int match_protocol (const char *flow_string);
+ TAO_AV_Protocol_Object* make_protocol_object (TAO_FlowSpec_Entry *entry,
+ TAO_Base_StreamEndPoint *endpoint,
+ TAO_AV_Flow_Handler *handler,
+ TAO_AV_Transport *transport);
+};
+
+ACE_STATIC_SVC_DECLARE (TAO_AV_TCP_Flow_Factory)
+ACE_FACTORY_DECLARE (TAO_ORBSVCS, TAO_AV_TCP_Flow_Factory)
+
+ACE_STATIC_SVC_DECLARE (TAO_AV_TCP_Factory)
+ACE_FACTORY_DECLARE (TAO_ORBSVCS, TAO_AV_TCP_Factory)
+
+#endif /* TAO_AV_TCP_H */
diff --git a/TAO/orbsvcs/orbsvcs/AV/Transport.cpp b/TAO/orbsvcs/orbsvcs/AV/Transport.cpp
new file mode 100644
index 00000000000..eea7446020b
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/AV/Transport.cpp
@@ -0,0 +1,1249 @@
+// $Id$
+#include "tao/TAO.h"
+#include "AVStreams_i.h"
+#include "sfp.h"
+#include "MCast.h"
+#include "Nil.h"
+#include "RTP.h"
+#include "RTCP.h"
+#include "UDP.h"
+#include "TCP.h"
+#include "FlowSpec_Entry.h"
+
+#if !defined (__ACE_INLINE__)
+#include "Transport.i"
+#endif /* __ACE_INLINE__ */
+
+//------------------------------------------------------------
+// TAO_AV_Core
+//------------------------------------------------------------
+
+TAO_AV_Core::TAO_AV_Core (void)
+ :connector_registry_ (0),
+ acceptor_registry_ (0)
+{
+}
+
+TAO_AV_Core::~TAO_AV_Core (void)
+{
+ delete this->connector_registry_;
+ delete this->acceptor_registry_;
+}
+
+int
+TAO_AV_Core::init (int &argc,
+ char *argv [],
+ CORBA::Environment &env)
+{
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"TAO_AV_Core::init "));
+ // Init the orb manager.
+ int result = this->orb_manager_.init (argc,argv,env);
+ if (result < 0)
+ ACE_ERROR_RETURN ((LM_ERROR,"orb_manager::init"),result);
+ ACE_NEW_RETURN (this->connector_registry_,
+ TAO_AV_Connector_Registry,
+ -1);
+ ACE_NEW_RETURN (this->acceptor_registry_,
+ TAO_AV_Acceptor_Registry,
+ -1);
+ this->orb_ = this->orb_manager_.orb ();
+ this->reactor (this->orb_->orb_core ()->reactor ());
+ this->init_transport_factories ();
+ this->init_flow_protocol_factories ();
+ return 0;
+}
+
+int
+TAO_AV_Core::init_forward_flows (TAO_Base_StreamEndPoint *endpoint,
+ TAO_AV_FlowSpecSet &flow_spec_set,
+ TAO_AV_Core::EndPoint direction,
+ AVStreams::flowSpec &flow_spec)
+{
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"TAO_AV_Core::init_forward_flows\n"));
+ TAO_AV_FlowSpecSet address_flow_set;
+ TAO_AV_FlowSpecSet flow_set;
+ TAO_AV_FlowSpecSetItor end = flow_spec_set.end ();
+ for (TAO_AV_FlowSpecSetItor start = flow_spec_set.begin ();
+ start != end; ++start)
+ {
+ TAO_FlowSpec_Entry *entry = (*start);
+ switch (direction)
+ {
+ case TAO_AV_Core::TAO_AV_ENDPOINT_B:
+ {
+ switch (entry->direction ())
+ {
+ case TAO_FlowSpec_Entry::TAO_AV_DIR_IN:
+ entry->role (TAO_FlowSpec_Entry::TAO_AV_CONSUMER);
+ break;
+ case TAO_FlowSpec_Entry::TAO_AV_DIR_OUT:
+ entry->role (TAO_FlowSpec_Entry::TAO_AV_PRODUCER);
+ break;
+ }
+ }
+ default:
+ break;
+ }
+ ACE_Addr *address = entry->address ();
+ if (address != 0)
+ {
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"address given for flow %s",entry->flowname ()));
+ address_flow_set.insert (entry);
+ }
+ else
+ flow_set.insert (entry);
+ }
+ int result = -1;
+ switch (direction)
+ {
+ case TAO_AV_Core::TAO_AV_ENDPOINT_A:
+ if (address_flow_set.size () > 0)
+ {
+ result = this->acceptor_registry_->open (endpoint,
+ this,
+ address_flow_set);
+ if (result < 0)
+ ACE_ERROR_RETURN ((LM_ERROR,"TAO_AV_Core::init_forward_flows::acceptor_registry::open failed\n"),-1);
+ TAO_AV_FlowSpecSetItor end = address_flow_set.end ();
+ for (TAO_AV_FlowSpecSetItor start = address_flow_set.begin ();
+ start != end; ++start)
+ {
+ TAO_FlowSpec_Entry *entry = (*start);
+ switch (entry->direction ())
+ {
+ case TAO_FlowSpec_Entry::TAO_AV_DIR_IN:
+ {
+ if (entry->handler () != 0)
+ {
+ // For IN flows on the A side we should remove the handlers from the reactor.
+ ACE_Event_Handler *event_handler = entry->handler ()->event_handler ();
+ result = event_handler->reactor ()->remove_handler (event_handler,
+ ACE_Event_Handler::READ_MASK);
+ if (result < 0)
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"TAO_AV_Core::init_forward_flows: remove_handler failed\n"));
+ }
+ }
+ default:
+ break;
+ }
+ // Now if the address_set has been changed due to the addition of a control entry we should
+ // add that to the flow_spec_set also.
+ if (flow_spec_set.find (entry) < 0)
+ {
+ // entry doesn't exist so add it.
+ flow_spec_set.insert (entry);
+// size_t len = flow_spec.length ();
+// flow_spec.length (len+1);
+// flow_spec [len] = entry->entry_to_string ();
+ }
+ }
+ }
+ break;
+ case TAO_AV_Core::TAO_AV_ENDPOINT_B:
+ {
+ if (address_flow_set.size () > 0)
+ {
+ result = this->connector_registry_->open (endpoint,
+ this,
+ address_flow_set);
+ if (result == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,"TAO_AV_Core::init_Forward_flows: connector_registry open failed\n"),-1);
+ TAO_AV_FlowSpecSetItor end = address_flow_set.end ();
+ for (TAO_AV_FlowSpecSetItor start = address_flow_set.begin ();
+ start != end; ++start)
+ {
+ TAO_FlowSpec_Entry *entry = (*start);
+ switch (entry->direction ())
+ {
+ case TAO_FlowSpec_Entry::TAO_AV_DIR_OUT:
+ {
+ if (entry->handler () != 0)
+ {
+ // @@Naga: This wont be called in the case of Full Profile.
+ // For IN flows on the A side we should remove the handlers from the reactor.
+ ACE_Event_Handler *event_handler = entry->handler ()->event_handler ();
+ result = event_handler->reactor ()->remove_handler (event_handler,
+ ACE_Event_Handler::READ_MASK);
+ if (result < 0)
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"TAO_AV_Core::init_forward_flows: remove_handler failed\n"));
+ }
+ }
+ default:
+ break;
+ }
+ // Now if the address_set has been changed due to the addition of a control entry we should
+ // add that to the flow_spec_set also.
+ if (flow_spec_set.find (entry) < 0)
+ {
+ // entry doesn't exist so add it.
+ flow_spec_set.insert (entry);
+ }
+ }
+ }
+ if (flow_set.size () > 0)
+ {
+ result = this->acceptor_registry_->open (endpoint,
+ this,
+ flow_set);
+ if (result == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,"TAO_AV_Core::init_Forward_flows: Acceptor_registry open failed\n"),-1);
+ TAO_AV_FlowSpecSetItor end = address_flow_set.end ();
+ for (TAO_AV_FlowSpecSetItor start = address_flow_set.begin ();
+ start != end; ++start)
+ {
+ TAO_FlowSpec_Entry *entry = (*start);
+ switch (entry->direction ())
+ {
+ case TAO_FlowSpec_Entry::TAO_AV_DIR_OUT:
+ {
+ if (entry->handler () != 0)
+ {
+ // For IN flows on the A side we should remove the handlers from the reactor.
+ ACE_Event_Handler *event_handler = entry->handler ()->event_handler ();
+ result = event_handler->reactor ()->remove_handler (event_handler,
+ ACE_Event_Handler::READ_MASK);
+ if (result < 0)
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"TAO_AV_Core::init_forward_flows: remove_handler failed\n"));
+ }
+ }
+ default:
+ break;
+ }
+ // Now if the address_set has been changed due to the addition of a control entry we should
+ // add that to the flow_spec_set also.
+ if (flow_spec_set.find (entry) < 0)
+ {
+ // entry doesn't exist so add it.
+ flow_spec_set.insert (entry);
+ }
+ }
+ }
+
+ AVStreams::flowSpec new_flowspec (flow_spec_set.size ());
+ int i=0;
+ TAO_AV_FlowSpecSetItor connect_end = address_flow_set.end ();
+ TAO_AV_FlowSpecSetItor connect = address_flow_set.begin ();
+ for (;connect != connect_end; ++connect)
+ {
+ ACE_Addr *local_addr;
+ local_addr = (*connect)->get_local_addr ();
+ if (result == 0)
+ {
+ TAO_Reverse_FlowSpec_Entry entry ((*connect)->flowname (),
+ (*connect)->direction_str (),
+ (*connect)->format (),
+ (*connect)->flow_protocol_str (),
+ (*connect)->carrier_protocol_str (),
+ local_addr);
+
+ int len = new_flowspec.length ();
+ if (i == len)
+ new_flowspec.length (len+1);
+ new_flowspec [i++] = entry.entry_to_string ();
+ }
+ }
+ connect_end = flow_set.end ();
+ for (connect = flow_set.begin ();
+ connect != connect_end; ++connect)
+ {
+ ACE_Addr *local_addr;
+ local_addr = (*connect)->get_local_addr ();
+ if (result == 0)
+ {
+ TAO_Reverse_FlowSpec_Entry entry ((*connect)->flowname (),
+ (*connect)->direction_str (),
+ (*connect)->format (),
+ (*connect)->flow_protocol_str (),
+ (*connect)->carrier_protocol_str (),
+ local_addr);
+
+ int len = new_flowspec.length ();
+ if (i == len)
+ new_flowspec.length (len+1);
+ new_flowspec [i++] = entry.entry_to_string ();
+ }
+ }
+ // Change the reverse flow spec to be sent.
+ flow_spec = new_flowspec;
+ }
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
+int
+TAO_AV_Core::init_reverse_flows (TAO_Base_StreamEndPoint *endpoint,
+ TAO_AV_FlowSpecSet &forward_flow_spec_set,
+ TAO_AV_FlowSpecSet &reverse_flow_spec_set,
+ TAO_AV_Core::EndPoint direction)
+{
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"(%P|%t)TAO_AV_Core::init_reverse_flows\n"));
+ TAO_AV_FlowSpecSet acceptor_flow_set;
+ TAO_AV_FlowSpecSet connector_flow_set;
+ TAO_AV_FlowSpecSetItor end = reverse_flow_spec_set.end ();
+ TAO_AV_FlowSpecSetItor start = reverse_flow_spec_set.begin ();
+ for (;start != end; ++start)
+ {
+ TAO_FlowSpec_Entry *entry = (*start);
+ ACE_Addr *address = entry->address ();
+ if (address != 0)
+ {
+ if (this->get_acceptor (entry->flowname ())!= 0)
+ {
+ ACE_Addr *address = entry->address ();
+ TAO_FlowSpec_Entry *forward_entry =
+ this->get_flow_spec_entry (forward_flow_spec_set,
+ entry->flowname ());
+ if (forward_entry != 0)
+ forward_entry->set_peer_addr (address);
+ // Now we have to match the control and data flow objects.
+ // Check if there's a control object.
+ char control_flowname [BUFSIZ];
+ ACE_OS::sprintf (control_flowname,"%s_control",entry->flowname ());
+ TAO_FlowSpec_Entry *control_entry = this->get_flow_spec_entry (forward_flow_spec_set,
+ control_flowname);
+ if (control_entry != 0)
+ forward_entry->protocol_object ()->control_object (control_entry->protocol_object ());
+ }
+ else
+ connector_flow_set.insert (entry);
+ }
+ }
+ int result = -1;
+ switch (direction)
+ {
+ case TAO_AV_Core::TAO_AV_ENDPOINT_A:
+ result = this->connector_registry_->open (endpoint,
+ this,
+ connector_flow_set);
+ break;
+ default:
+ break;
+ }
+ if (result == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,"acceptor_registry::open"),-1);
+ return 0;
+}
+
+TAO_FlowSpec_Entry *
+TAO_AV_Core::get_flow_spec_entry (TAO_AV_FlowSpecSet &flow_spec_set,
+ const char *flowname)
+{
+ TAO_AV_FlowSpecSetItor end = flow_spec_set.end ();
+ TAO_AV_FlowSpecSetItor begin = flow_spec_set.begin ();
+ for (;
+ begin != end;
+ ++begin)
+ {
+ if (ACE_OS::strcmp ((*begin)->flowname (),flowname) == 0)
+ return (*begin);
+ }
+ return 0;
+}
+
+TAO_AV_Acceptor*
+TAO_AV_Core::get_acceptor (const char *flowname)
+{
+ TAO_AV_AcceptorSetItor acceptor =
+ this->acceptor_registry_->begin ();
+ TAO_AV_AcceptorSetItor end =
+ this->acceptor_registry_->end ();
+
+ for (;acceptor != end; ++acceptor)
+ {
+ if (ACE_OS::strcmp ((*acceptor)->flowname (),flowname) == 0)
+ return *acceptor;
+ }
+ return 0;
+}
+
+TAO_AV_Connector*
+TAO_AV_Core::get_connector (const char *flowname)
+{
+ TAO_AV_ConnectorSetItor connector =
+ this->connector_registry_->begin ();
+ TAO_AV_ConnectorSetItor end =
+ this->connector_registry_->end ();
+
+ for (;connector != end; ++connector)
+ {
+ if (ACE_OS::strcmp ((*connector)->flowname (),flowname) == 0)
+ return *connector;
+ }
+ return 0;
+}
+
+int
+TAO_AV_Core::init_transport_factories (void)
+{
+ TAO_AV_TransportFactorySetItor end = this->transport_factories_.end ();
+ TAO_AV_TransportFactorySetItor factory = this->transport_factories_.begin ();
+
+ if (factory == end)
+ {
+ TAO_AV_Transport_Factory *udp_factory = 0;
+ TAO_AV_Transport_Item *udp_item = 0;
+
+ udp_factory =
+ ACE_Dynamic_Service<TAO_AV_Transport_Factory>::instance ("UDP_Factory");
+ if (udp_factory == 0)
+ {
+ if (TAO_debug_level)
+ ACE_ERROR ((LM_WARNING,
+ "(%P|%t) WARNING - No %s found in Service Repository."
+ " Using default instance.\n",
+ "UDP Factory"));
+
+ ACE_NEW_RETURN (udp_factory,
+ TAO_AV_UDP_Factory,
+ -1);
+ }
+
+ ACE_NEW_RETURN (udp_item, TAO_AV_Transport_Item ("UDP_Factory"), -1);
+ udp_item->factory (udp_factory);
+
+ this->transport_factories_.insert (udp_item);
+
+ TAO_AV_Transport_Factory *tcp_factory = 0;
+ TAO_AV_Transport_Item *tcp_item = 0;
+
+ tcp_factory =
+ ACE_Dynamic_Service<TAO_AV_Transport_Factory>::instance ("TCP_Factory");
+ if (tcp_factory == 0)
+ {
+ if (TAO_debug_level)
+ ACE_ERROR ((LM_WARNING,
+ "(%P|%t) WARNING - No %s found in Service Repository."
+ " Using default instance.\n",
+ "TCP Factory"));
+
+ ACE_NEW_RETURN (tcp_factory,
+ TAO_AV_TCP_Factory,
+ -1);
+ }
+
+ ACE_NEW_RETURN (tcp_item, TAO_AV_Transport_Item ("TCP_Factory"), -1);
+ tcp_item->factory (tcp_factory);
+
+ this->transport_factories_.insert (tcp_item);
+
+
+ }
+ return 0;
+}
+
+int
+TAO_AV_Core::init_flow_protocol_factories (void)
+{
+ TAO_AV_Flow_ProtocolFactorySetItor end = this->flow_protocol_factories_.end ();
+ TAO_AV_Flow_ProtocolFactorySetItor factory = this->flow_protocol_factories_.begin ();
+
+ if (factory == end)
+ {
+ TAO_AV_Flow_Protocol_Factory *udp_flow_factory = 0;
+ TAO_AV_Flow_Protocol_Item *udp_item = 0;
+
+ udp_flow_factory =
+ ACE_Dynamic_Service<TAO_AV_Flow_Protocol_Factory>::instance ("UDP_Flow_Factory");
+ if (udp_flow_factory == 0)
+ {
+ if (TAO_debug_level)
+ ACE_ERROR ((LM_WARNING,
+ "(%P|%t) WARNING - No %s found in Service Repository."
+ " Using default instance.\n",
+ "UDP Flow Factory"));
+
+ ACE_NEW_RETURN (udp_flow_factory,
+ TAO_AV_UDP_Flow_Factory,
+ -1);
+ }
+
+ ACE_NEW_RETURN (udp_item, TAO_AV_Flow_Protocol_Item ("UDP_Flow_Factory"), -1);
+ udp_item->factory (udp_flow_factory);
+
+ this->flow_protocol_factories_.insert (udp_item);
+
+ TAO_AV_Flow_Protocol_Factory *tcp_flow_factory = 0;
+ TAO_AV_Flow_Protocol_Item *tcp_item = 0;
+
+ tcp_flow_factory =
+ ACE_Dynamic_Service<TAO_AV_Flow_Protocol_Factory>::instance ("TCP_Flow_Factory");
+ if (tcp_flow_factory == 0)
+ {
+ if (TAO_debug_level)
+ ACE_ERROR ((LM_WARNING,
+ "(%P|%t) WARNING - No %s found in Service Repository."
+ " Using default instance.\n",
+ "TCP Flow Factory"));
+
+ ACE_NEW_RETURN (tcp_flow_factory,
+ TAO_AV_TCP_Flow_Factory,
+ -1);
+ }
+
+ ACE_NEW_RETURN (tcp_item, TAO_AV_Flow_Protocol_Item ("TCP_Flow_Factory"), -1);
+ tcp_item->factory (tcp_flow_factory);
+
+ this->flow_protocol_factories_.insert (tcp_item);
+
+ TAO_AV_Flow_Protocol_Factory *rtp_flow_factory = 0;
+ TAO_AV_Flow_Protocol_Item *rtp_item = 0;
+
+ rtp_flow_factory =
+ ACE_Dynamic_Service<TAO_AV_Flow_Protocol_Factory>::instance ("RTP_Flow_Factory");
+ if (rtp_flow_factory == 0)
+ {
+ if (TAO_debug_level)
+ ACE_ERROR ((LM_WARNING,
+ "(%P|%t) WARNING - No %s found in Service Repository."
+ " Using default instance.\n",
+ "RTP Flow Factory"));
+
+ ACE_NEW_RETURN (rtp_flow_factory,
+ TAO_AV_RTP_Flow_Factory,
+ -1);
+ }
+
+ ACE_NEW_RETURN (rtp_item, TAO_AV_Flow_Protocol_Item ("RTP_Flow_Factory"), -1);
+ rtp_item->factory (rtp_flow_factory);
+
+ this->flow_protocol_factories_.insert (rtp_item);
+
+ TAO_AV_Flow_Protocol_Factory *rtcp_flow_factory = 0;
+ TAO_AV_Flow_Protocol_Item *rtcp_item = 0;
+
+ rtcp_flow_factory =
+ ACE_Dynamic_Service<TAO_AV_Flow_Protocol_Factory>::instance ("RTCP_Flow_Factory");
+ if (rtcp_flow_factory == 0)
+ {
+ if (TAO_debug_level)
+ ACE_ERROR ((LM_WARNING,
+ "(%P|%t) WARNING - No %s found in Service Repository."
+ " Using default instance.\n",
+ "RTCP Flow Factory"));
+
+ ACE_NEW_RETURN (rtcp_flow_factory,
+ TAO_AV_RTCP_Flow_Factory,
+ -1);
+ }
+
+ ACE_NEW_RETURN (rtcp_item, TAO_AV_Flow_Protocol_Item ("RTCP_Flow_Factory"), -1);
+ rtcp_item->factory (rtcp_flow_factory);
+
+ this->flow_protocol_factories_.insert (rtcp_item);
+
+ TAO_AV_Flow_Protocol_Factory *sfp_flow_factory = 0;
+ TAO_AV_Flow_Protocol_Item *sfp_item = 0;
+
+ sfp_flow_factory =
+ ACE_Dynamic_Service<TAO_AV_Flow_Protocol_Factory>::instance ("SFP_Flow_Factory");
+ if (sfp_flow_factory == 0)
+ {
+ if (TAO_debug_level)
+ ACE_ERROR ((LM_WARNING,
+ "(%P|%t) WARNING - No %s found in Service Repository."
+ " Using default instance.\n",
+ "SFP Flow Factory"));
+
+ ACE_NEW_RETURN (sfp_flow_factory,
+ TAO_AV_SFP_Factory,
+ -1);
+ }
+
+ ACE_NEW_RETURN (sfp_item, TAO_AV_Flow_Protocol_Item ("SFP_Flow_Factory"), -1);
+ sfp_item->factory (sfp_flow_factory);
+
+ this->flow_protocol_factories_.insert (sfp_item);
+ }
+ return 0;
+}
+
+//------------------------------------------------------------
+// TAO_AV_Transport_Item
+//------------------------------------------------------------
+TAO_AV_Transport_Item::TAO_AV_Transport_Item (const ACE_CString &name)
+ : name_ (name),
+ factory_ (0)
+{
+}
+
+//------------------------------------------------------------
+// TAO_AV_Transport_Item
+//------------------------------------------------------------
+TAO_AV_Flow_Protocol_Item::TAO_AV_Flow_Protocol_Item (const ACE_CString &name)
+ : name_ (name),
+ factory_ (0)
+{
+}
+
+//------------------------------------------------------------
+// TAO_AV_Connector_Registry
+//------------------------------------------------------------
+
+TAO_AV_Connector_Registry::TAO_AV_Connector_Registry (void)
+{
+}
+
+int
+TAO_AV_Connector_Registry::open (TAO_Base_StreamEndPoint *endpoint,
+ TAO_AV_Core *av_core,
+ TAO_AV_FlowSpecSet &flow_spec_set)
+{
+ TAO_AV_FlowSpecSetItor last_flowspec =
+ flow_spec_set.end ();
+ for (TAO_AV_FlowSpecSetItor flow_spec = flow_spec_set.begin ();
+ flow_spec != last_flowspec;
+ ++flow_spec)
+ {
+ TAO_FlowSpec_Entry *entry = (*flow_spec);
+ ACE_Addr *address = entry->address ();
+ const char *flow_protocol = entry->flow_protocol_str ();
+ const char *transport_protocol = entry->carrier_protocol_str ();
+ if (ACE_OS::strcmp (flow_protocol,"") == 0)
+ flow_protocol = transport_protocol;
+ if (address == 0)
+ {
+ // Protocol was specified without an endpoint. According to
+ // the "iioploc" spec, this is valid. As such, we extend
+ // this feature to all pluggable protocols. All TAO
+ // pluggable protocols are expected to have the ability to
+ // create a default endpoint.
+
+ ACE_ERROR_RETURN ((LM_ERROR,"Protocol was specified without an endpoint\n"),-1);
+ }
+ else
+ {
+ TAO_AV_Flow_ProtocolFactorySetItor flow_factory_end =
+ av_core->flow_protocol_factories ()->end ();
+
+ for (TAO_AV_Flow_ProtocolFactorySetItor flow_factory =
+ av_core->flow_protocol_factories ()->begin ();
+ flow_factory != flow_factory_end;
+ ++flow_factory)
+ {
+ if ((*flow_factory)->factory ()->match_protocol (flow_protocol))
+ {
+ // @@Naga:Instead of making a new connector every time we should try and see if a connector exists
+ // for this transport already and hence we can reuse it.
+ TAO_AV_TransportFactorySetItor transport_factory_end =
+ av_core->transport_factories ()->end ();
+ for (TAO_AV_TransportFactorySetItor transport_factory =
+ av_core->transport_factories ()->begin ();
+ transport_factory != transport_factory_end;
+ ++transport_factory)
+ {
+ if ((*transport_factory)->factory ()->match_protocol (transport_protocol))
+ {
+ TAO_AV_Connector *connector =
+ (*transport_factory)->factory ()->make_connector ();
+ if (connector != 0)
+ {
+ // add connector to list.
+ this->connectors_.insert (connector);
+
+ if (connector->open (endpoint,
+ av_core,
+ (*flow_factory)->factory ()) == -1)
+ return -1;
+ TAO_AV_Transport *transport = 0;
+ if (connector->connect (entry,
+ transport) == -1)
+ return -1;
+ entry->transport (transport);
+ break;
+ }
+ else
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "(%P|%t) Unable to create an "
+ "connector for <%s>\n",
+ entry->flowname ()),
+ -1);
+ }
+ else
+ continue;
+ }
+ // Now check if the flow factory has a control flow factory.
+ const char *control_factory_name
+ = (*flow_factory)->factory ()->control_flow_factory ();
+
+ if (control_factory_name != 0)
+ {
+ TAO_AV_Flow_ProtocolFactorySetItor control_factory_end =
+ av_core->flow_protocol_factories ()->end ();
+
+ for (TAO_AV_Flow_ProtocolFactorySetItor control_flow_factory =
+ av_core->flow_protocol_factories ()->begin ();
+ control_flow_factory != control_factory_end;
+ ++control_flow_factory)
+ {
+ if ((*control_flow_factory)->factory ()->match_protocol (control_factory_name))
+ {
+ char control_flowname [BUFSIZ];
+ ACE_OS::sprintf (control_flowname,"%s_control",entry->flowname ());
+ // Address will be one port number above the data port.
+ // @@ This requires a more generic solution. This is a hack.
+ TAO_Tokenizer address_str (CORBA::string_dup (entry->address_str ()),':');
+ int port = ACE_OS::atoi (address_str [1]);
+ // Increment the port.
+ port++;
+ char control_addr [BUFSIZ];
+ ACE_OS::sprintf (control_addr,"%s=%s:%d",
+ entry->carrier_protocol_str (),
+ address_str[0],port);
+ TAO_Forward_FlowSpec_Entry *control_entry = 0;
+ // We want to have the control entry as producer
+ // so timeout events will happen.
+ ACE_NEW_RETURN (control_entry,
+ TAO_Forward_FlowSpec_Entry (control_flowname,
+ "IN",
+ entry->format (),
+ entry->flow_protocol_str (),
+ control_addr),
+ -1);
+ // Add the control entry to the flow_spec_set that's passed so that the control entry
+ // will also be called during flow starts and stops. except that if the user specifies
+ // a flowspec in start then the control entry may not be in that but it has to be started
+ // if the flowspec has the associated data flow entry. @@ We'll leave this matter for now.
+ flow_spec_set.insert (control_entry);
+ for (TAO_AV_TransportFactorySetItor transport_factory =
+ av_core->transport_factories ()->begin ();
+ transport_factory != transport_factory_end;
+ ++transport_factory)
+ {
+ if ((*transport_factory)->factory ()->match_protocol (transport_protocol))
+ {
+ TAO_AV_Connector *connector =
+ (*transport_factory)->factory ()->make_connector ();
+ if (connector != 0)
+ {
+ // add connector to list.
+ this->connectors_.insert (connector);
+
+ if (connector->open (endpoint,
+ av_core,
+ (*control_flow_factory)->factory ()) == -1)
+ return -1;
+ TAO_AV_Transport *transport = 0;
+ if (connector->connect (control_entry,
+ transport) == -1)
+ return -1;
+ control_entry->transport (transport);
+ break;
+ }
+ else
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "(%P|%t) Unable to create an "
+ "connector for <%s>\n",
+ control_entry->flowname ()),
+ -1);
+ }
+ else
+ continue;
+ }
+ // Now set the control object on the data flow object.
+ entry->protocol_object ()->control_object (control_entry->protocol_object ());
+ }
+ }
+ }
+ }
+ else
+ continue;
+ }
+ }
+ }
+ return 0;
+}
+
+int
+TAO_AV_Connector_Registry::close_all (void)
+{
+ TAO_AV_ConnectorSetItor end =
+ this->connectors_.end ();
+
+ for (TAO_AV_ConnectorSetItor i = this->connectors_.begin ();
+ i != end;
+ ++i)
+ {
+ if (*i == 0)
+ continue;
+
+ (*i)->close ();
+
+ delete *i;
+ }
+
+ this->connectors_.reset ();
+ return 0;
+}
+
+TAO_AV_Connector_Registry::~TAO_AV_Connector_Registry (void)
+{
+ this->close_all ();
+}
+
+//------------------------------------------------------------
+// TAO_AV_Acceptor_Registry
+//------------------------------------------------------------
+
+TAO_AV_Acceptor_Registry::TAO_AV_Acceptor_Registry (void)
+{
+}
+
+TAO_AV_Acceptor_Registry::~TAO_AV_Acceptor_Registry (void)
+{
+}
+
+int
+TAO_AV_Acceptor_Registry::open (TAO_Base_StreamEndPoint *endpoint,
+ TAO_AV_Core *av_core,
+ TAO_AV_FlowSpecSet &flow_spec_set)
+{
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"TAO_AV_Acceptor_Registry::open"));
+ TAO_AV_FlowSpecSetItor last_flowspec =
+ flow_spec_set.end ();
+ for (TAO_AV_FlowSpecSetItor flow_spec = flow_spec_set.begin ();
+ flow_spec != last_flowspec;
+ ++flow_spec)
+ {
+ TAO_FlowSpec_Entry *entry = (*flow_spec);
+ ACE_Addr *address = entry->address ();
+ const char *flow_protocol = entry->flow_protocol_str ();
+ const char *transport_protocol = entry->carrier_protocol_str ();
+ if (ACE_OS::strcmp (flow_protocol,"") == 0)
+ flow_protocol = transport_protocol;
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"TAO_AV_Acceptor_Registry::protocol for flow %s is %d",
+ entry->flowname (),transport_protocol));
+ if (address == 0)
+ {
+ this->open_default (endpoint,av_core, entry);
+ continue;
+ }
+ else
+ {
+ // Now get the list of avaliable protocol factories.
+ TAO_AV_Flow_ProtocolFactorySetItor flow_factory_end =
+ av_core->flow_protocol_factories ()->end ();
+
+ for (TAO_AV_Flow_ProtocolFactorySetItor flow_factory =
+ av_core->flow_protocol_factories ()->begin ();
+ flow_factory != flow_factory_end;
+ ++flow_factory)
+ {
+ if ((*flow_factory)->factory ()->match_protocol (flow_protocol))
+ {
+ TAO_AV_TransportFactorySetItor transport_factory_end =
+ av_core->transport_factories ()->end ();
+ for (TAO_AV_TransportFactorySetItor transport_factory =
+ av_core->transport_factories ()->begin ();
+ transport_factory != transport_factory_end;
+ ++transport_factory)
+ {
+ if ((*transport_factory)->factory ()->match_protocol (transport_protocol))
+ {
+ TAO_AV_Acceptor *acceptor =
+ (*transport_factory)->factory ()->make_acceptor ();
+ if (acceptor != 0)
+ {
+ // add acceptor to list.
+ this->acceptors_.insert (acceptor);
+
+ if (acceptor->open (endpoint,
+ av_core,
+ entry,
+ (*flow_factory)->factory ()) == -1)
+ return -1;
+ break;
+ }
+ else
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "(%P|%t) Unable to create an "
+ "acceptor for <%s>\n",
+ entry->flowname ()),
+ -1);
+ }
+ else
+ continue;
+ }
+ // Now check if the flow factory has a control flow factory.
+ const char *control_factory_name
+ = (*flow_factory)->factory ()->control_flow_factory ();
+
+ if (control_factory_name != 0)
+ {
+ TAO_AV_Flow_ProtocolFactorySetItor control_factory_end =
+ av_core->flow_protocol_factories ()->end ();
+
+ for (TAO_AV_Flow_ProtocolFactorySetItor control_flow_factory =
+ av_core->flow_protocol_factories ()->begin ();
+ control_flow_factory != control_factory_end;
+ ++control_flow_factory)
+ {
+ if ((*control_flow_factory)->factory ()->match_protocol (control_factory_name))
+ {
+ char control_flowname [BUFSIZ];
+ ACE_OS::sprintf (control_flowname,"%s_control",entry->flowname ());
+ // Address will be one port number above the data port.
+ // @@ This requires a more generic solution. This is a hack.
+ TAO_Tokenizer address_str (CORBA::string_dup (entry->address_str ()),':');
+ int port = ACE_OS::atoi (address_str [1]);
+ // Increment the port.
+ port++;
+ char control_addr [BUFSIZ];
+ ACE_OS::sprintf (control_addr,"%s=%s:%d",
+ entry->carrier_protocol_str (),
+ address_str[0],port);
+ TAO_Forward_FlowSpec_Entry *control_entry = 0;
+ // We want to have the control entry as producer
+ // so timeout events will happen.
+ ACE_NEW_RETURN (control_entry,
+ TAO_Forward_FlowSpec_Entry (control_flowname,
+ "IN",
+ entry->format (),
+ entry->flow_protocol_str (),
+ control_addr),
+ -1);
+ // Add the control entry to the flow_spec_set that's passed so that the control entry
+ // will also be called during flow starts and stops. except that if the user specifies
+ // a flowspec in start then the control entry may not be in that but it has to be started
+ // if the flowspec has the associated data flow entry. @@ We'll leave this matter for now.
+ flow_spec_set.insert (control_entry);
+ TAO_AV_TransportFactorySetItor transport_factory_end =
+ av_core->transport_factories ()->end ();
+ for (TAO_AV_TransportFactorySetItor transport_factory =
+ av_core->transport_factories ()->begin ();
+ transport_factory != transport_factory_end;
+ ++transport_factory)
+ {
+ if ((*transport_factory)->factory ()->match_protocol (transport_protocol))
+ {
+ TAO_AV_Acceptor *acceptor =
+ (*transport_factory)->factory ()->make_acceptor ();
+ if (acceptor != 0)
+ {
+ // add acceptor to list.
+ this->acceptors_.insert (acceptor);
+
+ if (acceptor->open (endpoint,
+ av_core,
+ control_entry,
+ (*control_flow_factory)->factory ()) == -1)
+ return -1;
+ break;
+ }
+ else
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "(%P|%t) Unable to create an "
+ "acceptor for <%s>\n",
+ entry->flowname ()),
+ -1);
+ }
+ else
+ continue;
+ }
+ // Now set the control object on the data flow object.
+ entry->protocol_object ()->control_object (control_entry->protocol_object ());
+ }
+ }
+ }
+ }
+ else
+ continue;
+ }
+ }
+ }
+ return 0;
+}
+
+int
+TAO_AV_Acceptor_Registry::open_default (TAO_Base_StreamEndPoint *endpoint,
+ TAO_AV_Core *av_core,
+ TAO_FlowSpec_Entry *entry)
+{
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"TAO_AV_Acceptor_Registry::open_default "));
+ // No endpoints were specified, we let each protocol pick its own
+ // default...
+
+ TAO_AV_Flow_ProtocolFactorySetItor flow_factory_end =
+ av_core->flow_protocol_factories ()->end ();
+
+ const char *flow_protocol = entry->flow_protocol_str ();
+ const char *transport_protocol = entry->carrier_protocol_str ();
+
+ if (ACE_OS::strcmp (flow_protocol,"") == 0)
+ flow_protocol = transport_protocol;
+
+ // loop through loaded protocols looking for protocol_prefix
+ TAO_AV_Flow_ProtocolFactorySetItor flow_factory = av_core->flow_protocol_factories ()->begin ();
+ TAO_AV_TransportFactorySetItor transport_factory = av_core->transport_factories ()->begin ();
+ for (;
+ flow_factory != flow_factory_end;
+ ++flow_factory)
+ {
+ if (!(*flow_factory)->factory ()->match_protocol (flow_protocol))
+ {
+ // If we have no matching protocol then keep searching
+ // for one until the entire list of protocols has been
+ // searched.
+
+ if (TAO_debug_level > 0)
+ ACE_ERROR ((LM_ERROR,
+ "TAO (%P|%t) Unable to match protocol prefix "
+ "for <%s>\n",
+ flow_protocol));
+ continue;
+ }
+ else
+ {
+ TAO_AV_TransportFactorySetItor transport_factory_end =
+ av_core->transport_factories ()->end ();
+ for (;transport_factory != transport_factory_end;
+ ++transport_factory)
+ {
+ if (!(*transport_factory)->factory ()->match_protocol (transport_protocol))
+ {
+ // If we have no matching protocol then keep searching
+ // for one until the entire list of protocols has been
+ // searched.
+
+ if (TAO_debug_level > 0)
+ ACE_ERROR ((LM_ERROR,
+ "TAO (%P|%t) Unable to match protocol prefix "
+ "for <%s>\n",
+ flow_protocol));
+ continue;
+ }
+
+
+
+ // got it, make an acceptor
+ TAO_AV_Acceptor *acceptor =
+ (*transport_factory)->factory ()->make_acceptor ();
+
+ if (acceptor == 0)
+ {
+ if (TAO_debug_level > 0)
+ ACE_ERROR ((LM_ERROR,
+ "TAO (%P|%t) unable to create "
+ "an acceptor for <%d>\n",
+ transport_protocol));
+ continue;
+ }
+
+ if (acceptor->open_default (endpoint,
+ av_core,
+ entry,
+ (*flow_factory)->factory ()) == -1)
+ {
+ if (TAO_debug_level > 0)
+ ACE_ERROR ((LM_ERROR,
+ "TAO (%P|%t) unable to open "
+ "default acceptor for <%s>%p\n",
+ (*transport_factory)->name ().c_str (), ""));
+ continue;
+ }
+
+ this->acceptors_.insert (acceptor);
+ }
+ }
+ }
+ if (this->acceptors_.size () == 0)
+ {
+ if (TAO_debug_level > 0)
+ ACE_ERROR ((LM_ERROR,
+ "TAO (%P%t) cannot create any default acceptor\n"));
+ return -1;
+ }
+
+ return 0;
+}
+
+int
+TAO_AV_Acceptor_Registry::close_all (void)
+{
+ TAO_AV_AcceptorSetItor end =
+ this->acceptors_.end ();
+
+ for (TAO_AV_AcceptorSetItor i = this->acceptors_.begin ();
+ i != end;
+ ++i)
+ {
+ if (*i == 0)
+ continue;
+
+ (*i)->close ();
+
+ delete *i;
+ }
+
+ this->acceptors_.reset ();
+ return 0;
+}
+
+//----------------------------------------------------------------------
+// TAO_AV_Transport
+//----------------------------------------------------------------------
+
+TAO_AV_Transport::TAO_AV_Transport (void)
+{
+}
+
+// Virtual destructor.
+TAO_AV_Transport::~TAO_AV_Transport (void)
+{
+}
+
+ACE_Addr*
+TAO_AV_Transport::get_local_addr (void)
+{
+ return 0;
+}
+
+//----------------------------------------------------------------------
+// TAO_AV_Flow_Handler
+//----------------------------------------------------------------------
+
+//TAO_AV_Flow_Handler::TAO_AV_Flow_Handler (TAO_AV_Callback *callback)
+TAO_AV_Flow_Handler::TAO_AV_Flow_Handler (void)
+ :transport_ (0),
+ callback_ (0),
+ protocol_object_ (0)
+{
+}
+
+int
+TAO_AV_Flow_Handler::set_remote_address (ACE_Addr */* address */)
+{
+ return 0;
+}
+
+int
+TAO_AV_Flow_Handler::start (TAO_FlowSpec_Entry::Role role)
+{
+ this->callback_->handle_start ();
+ switch (role)
+ {
+ // only for producer we register for the timeout.
+ case TAO_FlowSpec_Entry::TAO_AV_PRODUCER:
+ {
+ this->schedule_timer ();
+ }
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
+int
+TAO_AV_Flow_Handler::schedule_timer (void)
+{
+ ACE_Event_Handler *event_handler = this->event_handler ();
+ ACE_Time_Value *tv = 0;
+ this->callback_->get_timeout (tv,
+ this->timeout_arg_);
+ if (tv == 0)
+ return 0;
+ this->timer_id_ = event_handler->reactor ()->schedule_timer (event_handler,
+ 0,
+ *tv);
+ if (this->timer_id_ < 0)
+ return -1;
+}
+
+int
+TAO_AV_Flow_Handler::stop (TAO_FlowSpec_Entry::Role role)
+{
+ this->callback_->handle_stop ();
+ switch (role)
+ {
+ case TAO_FlowSpec_Entry::TAO_AV_PRODUCER:
+ {
+ int result = this->event_handler ()->reactor ()->cancel_timer (this->timer_id_);
+ if (result < 0)
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"TAO_AV_Flow_Handler::stop:cancel_timer failed\n"));
+ }
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
+int
+TAO_AV_Flow_Handler::handle_timeout (const ACE_Time_Value &tv,
+ const void *arg)
+{
+ this->callback_->handle_timeout (this->timeout_arg_);
+ ACE_Event_Handler *event_handler = this->event_handler ();
+ ACE_Time_Value *timeout = 0;
+ this->callback_->get_timeout (timeout,
+ this->timeout_arg_);
+ if (timeout == 0)
+ return 0;
+ this->timer_id_ = event_handler->reactor ()->schedule_timer (event_handler,
+ 0,
+ *timeout);
+ return 0;
+}
+
+TAO_AV_Transport*
+TAO_AV_Flow_Handler::transport (void)
+{
+ return this->transport_;
+}
+
+void
+TAO_AV_Flow_Handler::protocol_object (TAO_AV_Protocol_Object *protocol_object)
+{
+ this->protocol_object_ = protocol_object;
+}
+
+TAO_AV_Protocol_Object*
+TAO_AV_Flow_Handler::protocol_object (void)
+{
+ return this->protocol_object_;
+}
+
+void
+TAO_AV_Flow_Handler::callback (TAO_AV_Callback *callback)
+{
+ this->callback_ = callback;
+}
+
+// TAO_AV_Connector
+TAO_AV_Connector::TAO_AV_Connector (void)
+{
+}
+
+TAO_AV_Connector::~TAO_AV_Connector (void)
+{
+}
+
+// TAO_AV_Acceptor
+TAO_AV_Acceptor::TAO_AV_Acceptor (void)
+{
+}
+
+TAO_AV_Acceptor::~TAO_AV_Acceptor (void)
+{
+}
+
+#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
+template class ACE_Node <TAO_AV_Connector*>;
+template class ACE_Node <TAO_AV_Acceptor*>;
+template class ACE_Unbounded_Set<TAO_AV_Acceptor*>;
+template class ACE_Unbounded_Set<TAO_AV_Connector*>;
+template class ACE_Unbounded_Set_Iterator<TAO_AV_Acceptor*>;
+template class ACE_Unbounded_Set_Iterator<TAO_AV_Connector*>;
+template class ACE_Singleton<TAO_AV_Core,ACE_Null_Mutex>;
+#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
+#pragma instantiate ACE_Node <TAO_AV_Connector*>
+#pragma instantiate ACE_Node <TAO_AV_Acceptor*>
+#pragma instantiate ACE_Unbounded_Set<TAO_AV_Connector*>
+#pragma instantiate ACE_Unbounded_Set<TAO_AV_Acceptor*>
+#pragma instantiate ACE_Unbounded_Set_Iterator<TAO_AV_Connector*>
+#pragma instantiate ACE_Unbounded_Set_Iterator<TAO_AV_Acceptor*>
+#pragma instantiate ACE_Singleton<TAO_AV_Core,ACE_Null_Mutex>
+#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */
diff --git a/TAO/orbsvcs/orbsvcs/AV/Transport.h b/TAO/orbsvcs/orbsvcs/AV/Transport.h
new file mode 100644
index 00000000000..c46fa19e51b
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/AV/Transport.h
@@ -0,0 +1,226 @@
+/* -*- C++ -*- */
+
+// $Id$
+// ============================================================================
+//
+// = LIBRARY
+// ORBSVCS AVStreams
+//
+// = FILENAME
+// Transport.h
+//
+// = AUTHOR
+// Nagarajan Surendran <naga@cs.wustl.edu>
+//
+//
+// ============================================================================
+
+#if !defined TAO_AV_TRANSPORT_H
+#define TAO_AV_TRANSPORT_H
+
+#include "ace/Acceptor.h"
+#include "ace/SOCK_Acceptor.h"
+#include "ace/Connector.h"
+#include "ace/SOCK_Connector.h"
+#include "ace/Addr.h"
+#include "ace/SOCK_Dgram.h"
+#include "orbsvcs/orbsvcs_export.h"
+#include "AV_Core.h"
+#include "FlowSpec_Entry.h"
+
+// Forward declarations.
+class TAO_AV_Protocol_Object;
+class TAO_AV_Callback;
+class TAO_AV_Transport;
+
+class TAO_AV_Flow_Handler
+{
+public:
+ TAO_AV_Flow_Handler (void);
+ // Constructor.
+
+ virtual int start (TAO_FlowSpec_Entry::Role role);
+ virtual int stop (TAO_FlowSpec_Entry::Role role);
+ // Start/stop the flow handler.
+
+ virtual int schedule_timer (void);
+ // Schedule timer. Uses the get_timeout method on the callback.
+
+ TAO_AV_Transport *transport (void);
+ // get the transport.
+
+ TAO_AV_Protocol_Object* protocol_object (void);
+ void protocol_object (TAO_AV_Protocol_Object *protocol_object);
+ // set/get protocol_object.
+
+ void callback (TAO_AV_Callback *callback);
+ // set the callback.
+
+ int handle_timeout (const ACE_Time_Value &tv, const void *arg = 0);
+ // Handle timeout. called from reactor.
+
+ virtual int set_remote_address (ACE_Addr *address);
+ // set the remote address.
+
+ virtual ACE_Event_Handler* event_handler (void) = 0;
+ // get the underlying event handler. To be overridden by the derived clases.
+
+protected:
+ TAO_AV_Transport *transport_;
+ TAO_AV_Callback *callback_;
+ TAO_AV_Protocol_Object *protocol_object_;
+ long timer_id_;
+ ACE_Reactor *reactor_;
+ void *timeout_arg_;
+};
+
+// Transports
+class TAO_ORBSVCS_Export TAO_AV_Transport
+{
+ // TITLE
+ // = A Base class for the different transport protocols.
+ //
+ // DESCRIPTION
+ // = All the different transports should derive and implement
+ // the open,close,send and recv methods.
+public:
+ TAO_AV_Transport (void);
+
+ virtual ~TAO_AV_Transport (void);
+
+ virtual int open (ACE_Addr *address) = 0;
+
+ virtual int close (void) = 0;
+
+ virtual int mtu (void) = 0;
+ virtual ACE_Addr *get_peer_addr (void) = 0;
+ virtual ACE_Addr *get_local_addr (void);
+ virtual ssize_t send (const ACE_Message_Block *mblk,
+ ACE_Time_Value *s = 0) = 0;
+ // Write the complete Message_Block chain to the connection.
+
+ virtual ssize_t send (const char *buf,
+ size_t len,
+ ACE_Time_Value *s = 0) = 0;
+ // Write the contents of the buffer of length len to the connection.
+
+ virtual ssize_t send (const iovec *iov,
+ int iovcnt,
+ ACE_Time_Value *s = 0) = 0;
+ // Write the contents of iovcnt iovec's to the connection.
+
+ virtual ssize_t recv (char *buf,
+ size_t len,
+ ACE_Time_Value *s = 0) = 0;
+ // Read len bytes from into buf.
+
+ virtual ssize_t recv (char *buf,
+ size_t len,
+ int flags,
+ ACE_Time_Value *s = 0) = 0;
+ // Read len bytes from into buf using flags.
+
+ virtual ssize_t recv (iovec *iov,
+ int iovcnt,
+ ACE_Time_Value *s = 0) = 0;
+ // Read received data into the iovec buffers.
+
+};
+
+class TAO_Base_StreamEndPoint;
+class TAO_AV_Core;
+class TAO_FlowSpec_Entry;
+
+class TAO_AV_Acceptor
+{
+public:
+ TAO_AV_Acceptor (void);
+ virtual ~TAO_AV_Acceptor (void);
+ virtual int open (TAO_Base_StreamEndPoint *endpoint,
+ TAO_AV_Core *av_core,
+ TAO_FlowSpec_Entry *entry,
+ TAO_AV_Flow_Protocol_Factory *factory) = 0;
+
+ virtual int open_default (TAO_Base_StreamEndPoint *endpoint,
+ TAO_AV_Core *av_core,
+ TAO_FlowSpec_Entry *entry,
+ TAO_AV_Flow_Protocol_Factory *factory) = 0;
+
+ const char *flowname ();
+ virtual int close (void) = 0;
+protected:
+ ACE_CString flowname_;
+ TAO_AV_Core *av_core_;
+ ACE_Addr *address_;
+};
+
+class TAO_AV_Connector
+{
+public:
+ TAO_AV_Connector (void);
+ virtual ~TAO_AV_Connector (void);
+ const char *flowname (void);
+
+ virtual int open (TAO_Base_StreamEndPoint *endpoint,
+ TAO_AV_Core *av_core,
+ TAO_AV_Flow_Protocol_Factory *factory) = 0;
+
+ virtual int connect (TAO_FlowSpec_Entry *entry,
+ TAO_AV_Transport *&transport) = 0;
+
+ virtual int close (void) = 0;
+protected:
+ ACE_CString flowname_;
+};
+
+
+typedef ACE_Unbounded_Set<TAO_AV_Connector*> TAO_AV_ConnectorSet;
+typedef ACE_Unbounded_Set_Iterator<TAO_AV_Connector*> TAO_AV_ConnectorSetItor;
+
+class TAO_ORBSVCS_Export TAO_AV_Connector_Registry
+{
+public:
+ TAO_AV_Connector_Registry (void);
+ ~TAO_AV_Connector_Registry (void);
+ int open (TAO_Base_StreamEndPoint *endpoint,
+ TAO_AV_Core *av_core,
+ TAO_AV_FlowSpecSet &flow_spec_set);
+ // int connect (TAO_FlowSpec_Entry *flowspec,
+ // TAO_AV_Transport *&transport);
+ int close_all (void);
+ // TAO_AV_Connector *get_connector (TAO_AV_Core::Protocol protocol);
+ // Return the connector bridges
+ TAO_AV_ConnectorSetItor begin (void);
+ TAO_AV_ConnectorSetItor end (void);
+protected:
+ TAO_AV_ConnectorSet connectors_;
+};
+
+typedef ACE_Unbounded_Set<TAO_AV_Acceptor*>
+ TAO_AV_AcceptorSet;
+typedef ACE_Unbounded_Set_Iterator<TAO_AV_Acceptor*>
+ TAO_AV_AcceptorSetItor;
+
+class TAO_ORBSVCS_Export TAO_AV_Acceptor_Registry
+{
+public:
+ TAO_AV_Acceptor_Registry (void);
+ ~TAO_AV_Acceptor_Registry (void);
+ int open (TAO_Base_StreamEndPoint *endpoint,
+ TAO_AV_Core *av_core,
+ TAO_AV_FlowSpecSet &flow_spec_set);
+ int close_all (void);
+ TAO_AV_AcceptorSetItor begin (void);
+ TAO_AV_AcceptorSetItor end (void);
+protected:
+ int open_default (TAO_Base_StreamEndPoint *endpoint,
+ TAO_AV_Core *av_core,
+ TAO_FlowSpec_Entry *entry);
+ TAO_AV_AcceptorSet acceptors_;
+};
+
+#if defined (__ACE_INLINE__)
+#include "Transport.i"
+#endif /* __ACE_INLINE__ */
+
+#endif /* TAO_AV_TRANSPORT_H */
diff --git a/TAO/orbsvcs/orbsvcs/AV/Transport.i b/TAO/orbsvcs/orbsvcs/AV/Transport.i
new file mode 100644
index 00000000000..68db1bcf5f0
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/AV/Transport.i
@@ -0,0 +1,180 @@
+/* -*- C++ -*- */
+// $Id$
+
+// Transport.i
+
+//------------------------------------------------------------
+// TAO_AV_Core
+//------------------------------------------------------------
+
+ACE_INLINE
+TAO_ORB_Manager*
+TAO_AV_Core::orb_manager (void)
+{
+ return &this->orb_manager_;
+}
+
+ACE_INLINE
+int
+TAO_AV_Core::stop_run (void)
+{
+ this->stop_run_ = 1;
+ return 0;
+}
+
+ACE_INLINE
+int
+TAO_AV_Core::run (void)
+{
+ this->stop_run_ = 0;
+ this->orb_manager_.activate_poa_manager ();
+ while (!this->stop_run_ && this->orb_->work_pending ())
+ this->orb_->perform_work ();
+ return 0;
+}
+
+ACE_INLINE
+void
+TAO_AV_Core::reactor (ACE_Reactor *r)
+{
+ this->reactor_ = r;
+}
+
+ACE_INLINE
+ACE_Reactor *
+TAO_AV_Core::reactor (void)
+{
+ return this->reactor_;
+}
+
+ACE_INLINE
+TAO_AV_Connector_Registry*
+TAO_AV_Core::connector_registry (void)
+{
+ return this->connector_registry_;
+}
+
+ACE_INLINE
+TAO_AV_Acceptor_Registry*
+TAO_AV_Core::acceptor_registry (void)
+{
+ return this->acceptor_registry_;
+}
+
+ACE_INLINE
+TAO_AV_TransportFactorySet *
+TAO_AV_Core::transport_factories (void)
+{
+ return &this->transport_factories_;
+}
+
+ACE_INLINE
+TAO_AV_Flow_ProtocolFactorySet*
+TAO_AV_Core::flow_protocol_factories (void)
+{
+ return &this->flow_protocol_factories_;
+}
+
+//------------------------------------------------------------
+// TAO_AV_Transport_Item
+//------------------------------------------------------------
+ACE_INLINE
+const ACE_CString &
+TAO_AV_Transport_Item::name (void)
+{
+ return this->name_;
+}
+
+ACE_INLINE
+TAO_AV_Transport_Factory *
+TAO_AV_Transport_Item::factory (void)
+{
+ return this->factory_;
+}
+
+ACE_INLINE
+void
+TAO_AV_Transport_Item::factory (TAO_AV_Transport_Factory *factory)
+{
+ this->factory_ = factory;
+}
+
+
+//------------------------------------------------------------
+// TAO_AV_Flow_Protocol_Item
+//------------------------------------------------------------
+ACE_INLINE
+const ACE_CString &
+TAO_AV_Flow_Protocol_Item::name (void)
+{
+ return this->name_;
+}
+
+ACE_INLINE
+TAO_AV_Flow_Protocol_Factory *
+TAO_AV_Flow_Protocol_Item::factory (void)
+{
+ return this->factory_;
+}
+
+ACE_INLINE
+void
+TAO_AV_Flow_Protocol_Item::factory (TAO_AV_Flow_Protocol_Factory *factory)
+{
+ this->factory_ = factory;
+}
+
+//------------------------------------------------------------
+// TAO_AV_Connector_Registry
+//------------------------------------------------------------
+
+ACE_INLINE
+TAO_AV_ConnectorSetItor
+TAO_AV_Connector_Registry::begin (void)
+{
+ return this->connectors_.begin ();
+}
+
+ACE_INLINE
+TAO_AV_ConnectorSetItor
+TAO_AV_Connector_Registry::end (void)
+{
+ return this->connectors_.end ();
+}
+
+//------------------------------------------------------------
+// TAO_AV_Acceptor_Registry
+//------------------------------------------------------------
+ACE_INLINE
+TAO_AV_AcceptorSetItor
+TAO_AV_Acceptor_Registry::begin (void)
+{
+ return this->acceptors_.begin ();
+}
+
+ACE_INLINE
+TAO_AV_AcceptorSetItor
+TAO_AV_Acceptor_Registry::end (void)
+{
+ return this->acceptors_.end ();
+}
+
+//------------------------------------------------------------
+// TAO_AV_Acceptor
+//------------------------------------------------------------
+ACE_INLINE
+const char *
+TAO_AV_Acceptor::flowname (void)
+{
+ return this->flowname_.c_str ();
+}
+
+//------------------------------------------------------------
+// TAO_AV_Connector
+//------------------------------------------------------------
+ACE_INLINE
+const char *
+TAO_AV_Connector::flowname (void)
+{
+ return this->flowname_.c_str ();
+}
diff --git a/TAO/orbsvcs/orbsvcs/AV/UDP.cpp b/TAO/orbsvcs/orbsvcs/AV/UDP.cpp
new file mode 100644
index 00000000000..fc7b0b42bb0
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/AV/UDP.cpp
@@ -0,0 +1,729 @@
+// $Id$
+
+#include "UDP.h"
+#include "AVStreams_i.h"
+#include "MCast.h"
+
+#if !defined (__ACE_INLINE__)
+#include "UDP.i"
+#endif /* __ACE_INLINE__ */
+
+//------------------------------------------------------------
+// TAO_AV_UDP_Flow_Handler
+//------------------------------------------------------------
+
+TAO_AV_UDP_Flow_Handler::TAO_AV_UDP_Flow_Handler (void)
+{
+ ACE_NEW (this->transport_,
+ TAO_AV_UDP_Transport (this));
+}
+
+TAO_AV_UDP_Flow_Handler::~TAO_AV_UDP_Flow_Handler (void)
+{
+ delete this->transport_;
+}
+
+TAO_AV_Transport *
+TAO_AV_UDP_Flow_Handler::transport (void)
+{
+ return this->transport_;
+}
+
+int
+TAO_AV_UDP_Flow_Handler::handle_input (ACE_HANDLE /*fd*/)
+{
+ this->protocol_object_->handle_input ();
+ return 0;
+}
+
+int
+TAO_AV_UDP_Flow_Handler::handle_timeout (const ACE_Time_Value &tv,
+ const void *arg)
+{
+ return TAO_AV_Flow_Handler::handle_timeout (tv,arg);
+}
+
+int
+TAO_AV_UDP_Flow_Handler::set_remote_address (ACE_Addr *address)
+{
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"TAO_AV_UDP_Flow_Handler::set_remote_address\n"));
+ ACE_INET_Addr *inet_addr = ACE_dynamic_cast (ACE_INET_Addr*,address);
+ this->peer_addr_ = *inet_addr;
+ TAO_AV_UDP_Transport *transport = ACE_dynamic_cast (TAO_AV_UDP_Transport*,this->transport_);
+ return transport->set_remote_address (*inet_addr);
+}
+
+
+ACE_HANDLE
+TAO_AV_UDP_Flow_Handler::get_handle (void) const
+{
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"TAO_AV_UDP_Flow_Handler::get_handle:%d\n",this->sock_dgram_.get_handle ()));
+ return this->sock_dgram_.get_handle () ;
+}
+
+//------------------------------------------------------------
+// TAO_AV_UDP_Transport
+//------------------------------------------------------------
+
+TAO_AV_UDP_Transport::TAO_AV_UDP_Transport (void)
+ :handler_ (0)
+{
+}
+
+TAO_AV_UDP_Transport::TAO_AV_UDP_Transport (TAO_AV_UDP_Flow_Handler *handler)
+ :handler_ (handler),
+ addr_ (0)
+{
+}
+
+TAO_AV_UDP_Transport::~TAO_AV_UDP_Transport (void)
+{
+}
+
+int
+TAO_AV_UDP_Transport::set_remote_address (const ACE_INET_Addr &address)
+{
+ this->peer_addr_ = address;
+ return 0;
+}
+
+int
+TAO_AV_UDP_Transport::open (ACE_Addr */*address*/)
+{
+ return 0;
+}
+
+int
+TAO_AV_UDP_Transport::close (void)
+{
+ return 0;
+}
+
+int
+TAO_AV_UDP_Transport::mtu (void)
+{
+ return ACE_MAX_DGRAM_SIZE;
+}
+
+ACE_Addr*
+TAO_AV_UDP_Transport::get_peer_addr (void)
+{
+ return &this->peer_addr_;
+}
+
+ssize_t
+TAO_AV_UDP_Transport::send (const ACE_Message_Block *mblk, ACE_Time_Value *)
+{
+ // For the most part this was copied from GIOP::send_request and
+ // friends.
+
+ iovec iov[IOV_MAX];
+ int iovcnt = 0;
+ ssize_t n = 0;
+ ssize_t nbytes = 0;
+
+ for (const ACE_Message_Block *i = mblk;
+ i != 0;
+ i = i->cont ())
+ {
+ // Make sure there is something to send!
+ if (i->length () > 0)
+ {
+ iov[iovcnt].iov_base = i->rd_ptr ();
+ iov[iovcnt].iov_len = i->length ();
+ iovcnt++;
+
+ // The buffer is full make a OS call. @@ TODO this should
+ // be optimized on a per-platform basis, for instance, some
+ // platforms do not implement writev() there we should copy
+ // the data into a buffer and call send_n(). In other cases
+ // there may be some limits on the size of the iovec, there
+ // we should set IOV_MAX to that limit.
+ if (iovcnt == IOV_MAX)
+ {
+ n = this->handler_->get_socket ()->send ((const iovec *) iov,
+ iovcnt,
+ this->peer_addr_);
+
+ if (n < 1)
+ return n;
+
+ nbytes += n;
+ iovcnt = 0;
+ }
+ }
+ }
+
+ // Check for remaining buffers to be sent!
+ if (iovcnt != 0)
+ {
+ n = this->handler_->get_socket ()->send ((const iovec *) iov,
+ iovcnt,
+ this->peer_addr_);
+
+ if (n < 1)
+ return n;
+
+ nbytes += n;
+ }
+
+ return nbytes;
+}
+
+ssize_t
+TAO_AV_UDP_Transport::send (const char *buf,
+ size_t len,
+ ACE_Time_Value *)
+{
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"TAO_AV_UDP_Transport::send "));
+ char addr [BUFSIZ];
+ this->peer_addr_.addr_to_string (addr,BUFSIZ);
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"to %s\n",addr));
+
+ return this->handler_->get_socket ()->send (buf, len,this->peer_addr_);
+}
+
+ssize_t
+TAO_AV_UDP_Transport::send (const iovec *iov,
+ int iovcnt,
+ ACE_Time_Value *)
+{
+ return this->handler_->get_socket ()->send ((const iovec *) iov,
+ iovcnt,
+ this->peer_addr_);
+
+}
+
+ssize_t
+TAO_AV_UDP_Transport::recv (char *buf,
+ size_t len,
+ ACE_Time_Value *)
+{
+ return this->handler_->get_socket ()->recv (buf, len,this->peer_addr_);
+}
+
+ssize_t
+TAO_AV_UDP_Transport::recv (char *buf,
+ size_t len,
+ int flags,
+ ACE_Time_Value *timeout)
+{
+ return this->handler_->get_socket ()->recv (buf,
+ len,
+ this->peer_addr_,
+ flags,
+ timeout);
+}
+
+ssize_t
+TAO_AV_UDP_Transport::recv (iovec *iov,
+ int /*iovcnt*/,
+ ACE_Time_Value *timeout)
+{
+ return handler_->get_socket ()->recv (iov,this->peer_addr_,0,timeout);
+}
+
+
+//------------------------------------------------------------
+// TAO_AV_UDP_Acceptor
+//------------------------------------------------------------
+
+TAO_AV_UDP_Acceptor::TAO_AV_UDP_Acceptor (void)
+{
+}
+
+TAO_AV_UDP_Acceptor::~TAO_AV_UDP_Acceptor (void)
+{
+}
+
+int
+TAO_AV_UDP_Acceptor::activate_svc_handler (TAO_AV_Flow_Handler *handler)
+{
+ ACE_Event_Handler *event_handler = handler->event_handler ();
+ int result = this->av_core_->reactor ()->register_handler (event_handler,
+ ACE_Event_Handler::READ_MASK);
+ return result;
+}
+
+int
+TAO_AV_UDP_Acceptor::open (TAO_Base_StreamEndPoint *endpoint,
+ TAO_AV_Core *av_core,
+ TAO_FlowSpec_Entry *entry,
+ TAO_AV_Flow_Protocol_Factory *factory)
+{
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"TAO_AV_UDP_Acceptor::open "));
+ this->av_core_ = av_core;
+ this->endpoint_ = endpoint;
+ this->entry_ = entry;
+ this->flow_protocol_factory_ = factory;
+ this->flowname_ = entry->flowname ();
+ ACE_INET_Addr *inet_addr = (ACE_INET_Addr *) entry->address ();
+// inet_addr->set (inet_addr->get_port_number (),
+// inet_addr->get_host_name ());
+ char buf[BUFSIZ];
+ inet_addr->addr_to_string (buf,
+ BUFSIZ);
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"TAO_AV_UDP_Acceptor::open: %s",
+ buf));
+ int result = this->open_i (inet_addr);
+ if (result < 0)
+ return result;
+ return 0;
+}
+
+int
+TAO_AV_UDP_Acceptor::open_default (TAO_Base_StreamEndPoint *endpoint,
+ TAO_AV_Core *av_core,
+ TAO_FlowSpec_Entry *entry,
+ TAO_AV_Flow_Protocol_Factory *factory)
+{
+ this->av_core_ = av_core;
+ this->endpoint_ = endpoint;
+ this->entry_ = entry;
+ this->flow_protocol_factory_ = factory;
+ this->flowname_ = entry->flowname ();
+ ACE_INET_Addr *address;
+ ACE_NEW_RETURN (address,
+ ACE_INET_Addr ("0"),
+ -1);
+ int result = this->open_i (address);
+ if (result < 0)
+ return result;
+ return 0;
+}
+
+int
+TAO_AV_UDP_Acceptor::open_i (ACE_INET_Addr *inet_addr)
+{
+ int result = -1;
+ // TAO_AV_Callback *callback = 0;
+// this->endpoint_->get_callback (this->flowname_.c_str (),
+// callback);
+ ACE_INET_Addr *local_addr;
+ TAO_AV_Flow_Handler *flow_handler = 0;
+ if (this->entry_->is_multicast ())
+ {
+ TAO_AV_UDP_MCast_Flow_Handler *handler;
+ ACE_NEW_RETURN (handler,
+ TAO_AV_UDP_MCast_Flow_Handler,
+ -1);
+ flow_handler = handler;
+ result = handler->get_mcast_socket ()->subscribe (*inet_addr);
+ if (result < 0)
+ ACE_ERROR_RETURN ((LM_ERROR,"TAO_AV_UDP_MCast_connector::subscribe failed\n"),-1);
+ // Now disable Multicast loopback.
+ // @@Should we make this a policy?
+ if (handler->get_mcast_socket ()->set_option (IP_MULTICAST_LOOP,
+ 0) < 0)
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"TAO_AV_UDP_MCast_Acceptor::multicast loop disable failed\n"));
+ // @@ This should also be policies.
+ int bufsize = 80 * 1024;
+ if (handler->get_mcast_socket ()->ACE_SOCK::set_option (SOL_SOCKET,
+ SO_RCVBUF,
+ (char *)&bufsize,
+ sizeof(bufsize)) < 0)
+ {
+ bufsize = 32 * 1024;
+ if (handler->get_mcast_socket ()->ACE_SOCK::set_option (SOL_SOCKET,
+ SO_RCVBUF,
+ (char *)&bufsize,
+ sizeof(bufsize)) < 0)
+ perror("SO_RCVBUF");
+ }
+ ACE_NEW_RETURN (local_addr,
+ ACE_INET_Addr (*inet_addr),
+ -1);
+ }
+ else
+ {
+ TAO_AV_UDP_Flow_Handler *handler;
+ ACE_NEW_RETURN (handler,
+ TAO_AV_UDP_Flow_Handler,
+ -1);
+ flow_handler = handler;
+ int result = handler->open (*inet_addr);
+ if (result < 0)
+ ACE_ERROR_RETURN ((LM_ERROR,"TAO_AV_UDP_Acceptor::handler_open failed\n"),-1);
+ // set the socket buffer sizes to 64k.
+ int sndbufsize = ACE_DEFAULT_MAX_SOCKET_BUFSIZ;
+ int rcvbufsize = ACE_DEFAULT_MAX_SOCKET_BUFSIZ;
+
+ if (handler->get_socket ()->set_option (SOL_SOCKET,
+ SO_SNDBUF,
+ (void *) &sndbufsize,
+ sizeof (sndbufsize)) == -1
+ && errno != ENOTSUP)
+ return 0;
+
+ else if (handler->get_socket ()->set_option (SOL_SOCKET,
+ SO_RCVBUF,
+ (void *) &rcvbufsize,
+ sizeof (rcvbufsize)) == -1
+ && errno != ENOTSUP)
+ return 0;
+
+ if (result < 0)
+ ACE_ERROR_RETURN ((LM_ERROR,"SOCK_Dgram::open failed\n"),-1);
+ ACE_NEW_RETURN (local_addr,
+ ACE_INET_Addr,
+ -1);
+ result = handler->get_socket ()->get_local_addr (*local_addr);
+ if (result < 0)
+ ACE_ERROR_RETURN ((LM_ERROR,"TAO_AV_Dgram_Connector::open: get_local_addr failed\n"),result);
+ local_addr->set (local_addr->get_port_number (),
+ local_addr->get_host_name ());
+ }
+ TAO_AV_Protocol_Object *object =
+ this->flow_protocol_factory_->make_protocol_object (this->entry_,
+ this->endpoint_,
+ flow_handler,
+ flow_handler->transport ());
+ flow_handler->protocol_object (object);
+ // callback->protocol_object (object);
+// this->endpoint_->set_protocol_object (this->flowname_.c_str (),
+// object);
+ this->endpoint_->set_handler (this->flowname_.c_str (),flow_handler);
+ this->entry_->protocol_object (object);
+
+ char buf[BUFSIZ];
+ local_addr->addr_to_string (buf,BUFSIZ);
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"TAO_AV_UDP_CONNECTOR::connect:%s \n",buf));
+ this->entry_->set_local_addr (local_addr);
+ this->entry_->handler (flow_handler);
+ // call activate svc handler.
+ return this->activate_svc_handler (flow_handler);
+}
+
+int
+TAO_AV_UDP_Acceptor::close (void)
+{
+ return 0;
+}
+
+//------------------------------------------------------------
+// TAO_AV_UDP_Connector
+//------------------------------------------------------------
+TAO_AV_UDP_Connector::TAO_AV_UDP_Connector (void)
+{
+}
+
+TAO_AV_UDP_Connector::~TAO_AV_UDP_Connector (void)
+{
+}
+
+int
+TAO_AV_UDP_Connector::open (TAO_Base_StreamEndPoint *endpoint,
+ TAO_AV_Core *av_core,
+ TAO_AV_Flow_Protocol_Factory *factory)
+
+{
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"TAO_AV_UDP_Connector::open "));
+ this->endpoint_ = endpoint;
+ this->av_core_ = av_core;
+ this->flow_protocol_factory_ = factory;
+ return 0;
+}
+
+int
+TAO_AV_UDP_Connector::connect (TAO_FlowSpec_Entry *entry,
+ TAO_AV_Transport *&transport)
+{
+ int result = -1;
+ this->entry_ = entry;
+ this->flowname_ = entry->flowname ();
+ ACE_Addr *remote_addr = entry->address ();
+ ACE_INET_Addr *local_addr;
+ ACE_NEW_RETURN (local_addr,
+ ACE_INET_Addr ("0"),
+ -1);
+
+ // TAO_AV_Callback *callback = 0;
+// this->endpoint_->get_callback (this->flowname_.c_str (),
+// callback);
+ ACE_INET_Addr *inet_addr = ACE_dynamic_cast (ACE_INET_Addr*,entry->address ());
+ TAO_AV_Flow_Handler *flow_handler = 0;
+ if (entry->is_multicast ())
+ {
+ TAO_AV_UDP_MCast_Flow_Handler *handler;
+ ACE_NEW_RETURN (handler,
+ // TAO_AV_UDP_MCast_Flow_Handler (callback),
+ TAO_AV_UDP_MCast_Flow_Handler,
+ -1);
+ flow_handler = handler;
+ result = handler->get_mcast_socket ()->subscribe (*inet_addr);
+ if (result < 0)
+ ACE_ERROR_RETURN ((LM_ERROR,"TAO_AV_UDP_MCast_connector::open failed\n"),-1);
+ // Now disable Multicast loopback.
+ // @@Should we make this a policy?
+ if (handler->get_mcast_socket ()->set_option (IP_MULTICAST_LOOP,
+ 0) < 0)
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"TAO_AV_UDP_MCast_Acceptor::multicast loop disable failed\n"));
+ // @@ This should also be policies.
+ int bufsize = 80 * 1024;
+ if (handler->get_mcast_socket ()->ACE_SOCK::set_option (SOL_SOCKET,
+ SO_RCVBUF,
+ (char *)&bufsize,
+ sizeof(bufsize)) < 0)
+ {
+ bufsize = 32 * 1024;
+ if (handler->get_mcast_socket ()->ACE_SOCK::set_option (SOL_SOCKET,
+ SO_RCVBUF,
+ (char *)&bufsize,
+ sizeof(bufsize)) < 0)
+ perror("SO_RCVBUF");
+ }
+ ACE_NEW_RETURN (local_addr,
+ ACE_INET_Addr (*inet_addr),
+ -1);
+ }
+ else
+ {
+ TAO_AV_UDP_Flow_Handler *handler;
+ ACE_NEW_RETURN (handler,
+ // TAO_AV_UDP_Flow_Handler (callback),
+ TAO_AV_UDP_Flow_Handler,
+ -1);
+ flow_handler = handler;
+ result = handler->open (*local_addr);
+ if (result < 0)
+ ACE_ERROR_RETURN ((LM_ERROR,"handler::open failed\n"),-1);
+ // set the socket buffer sizes to 64k.
+ int sndbufsize = ACE_DEFAULT_MAX_SOCKET_BUFSIZ;
+ int rcvbufsize = ACE_DEFAULT_MAX_SOCKET_BUFSIZ;
+
+ if (handler->get_socket ()->set_option (SOL_SOCKET,
+ SO_SNDBUF,
+ (void *) &sndbufsize,
+ sizeof (sndbufsize)) == -1
+ && errno != ENOTSUP)
+ return 0;
+
+ else if (handler->get_socket ()->set_option (SOL_SOCKET,
+ SO_RCVBUF,
+ (void *) &rcvbufsize,
+ sizeof (rcvbufsize)) == -1
+ && errno != ENOTSUP)
+ return 0;
+
+ handler->set_remote_address (inet_addr);
+ ACE_NEW_RETURN (local_addr,
+ ACE_INET_Addr,
+ -1);
+ result = handler->get_socket ()->get_local_addr (*local_addr);
+ if (result < 0)
+ ACE_ERROR_RETURN ((LM_ERROR,"TAO_AV_Dgram_Connector::open: get_local_addr failed\n"),result);
+ local_addr->set (local_addr->get_port_number (),
+ local_addr->get_host_name ());
+ }
+ TAO_AV_Protocol_Object *object =
+ this->flow_protocol_factory_->make_protocol_object (this->entry_,
+ this->endpoint_,
+ flow_handler,
+ flow_handler->transport ());
+ flow_handler->protocol_object (object);
+ // callback->protocol_object (object);
+// this->endpoint_->set_protocol_object (this->flowname_.c_str (),
+// object);
+ this->endpoint_->set_handler (this->flowname_.c_str (),flow_handler);
+ this->entry_->protocol_object (object);
+
+ char buf[BUFSIZ];
+ local_addr->addr_to_string (buf,BUFSIZ);
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"TAO_AV_UDP_CONNECTOR::connect:%s \n",buf));
+ entry->set_local_addr (local_addr);
+ entry->handler (flow_handler);
+ transport = flow_handler->transport ();
+ // call activate svc handler.
+ return this->activate_svc_handler (flow_handler);
+}
+
+int
+TAO_AV_UDP_Connector::activate_svc_handler (TAO_AV_Flow_Handler *handler)
+{
+ ACE_Event_Handler *event_handler = handler->event_handler ();
+ int result = this->av_core_->reactor ()->register_handler (event_handler,
+ ACE_Event_Handler::READ_MASK);
+ return result;
+}
+
+int
+TAO_AV_UDP_Connector::close (void)
+{
+ return 0;
+}
+
+//------------------------------------------------------------
+// TAO_AV_UDP_Protocol_Factory
+//------------------------------------------------------------
+
+TAO_AV_UDP_Factory::TAO_AV_UDP_Factory (void)
+{
+}
+
+TAO_AV_UDP_Factory::~TAO_AV_UDP_Factory (void)
+{
+}
+
+int
+TAO_AV_UDP_Factory::match_protocol (const char *protocol_string)
+{
+ if (ACE_OS::strstr (protocol_string,"UDP") != 0)
+ return 1;
+ return 0;
+}
+
+TAO_AV_Acceptor*
+TAO_AV_UDP_Factory::make_acceptor (void)
+{
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"TAO_AV_UDP_Factory::make_acceptor "));
+ TAO_AV_Acceptor *acceptor = 0;
+ ACE_NEW_RETURN (acceptor,
+ TAO_AV_UDP_Acceptor,
+ 0);
+ return acceptor;
+}
+
+TAO_AV_Connector*
+TAO_AV_UDP_Factory::make_connector (void)
+{
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"TAO_AV_UDP_Factory::make_connector "));
+ TAO_AV_Connector *connector = 0;
+ ACE_NEW_RETURN (connector,
+ TAO_AV_UDP_Connector,
+ 0);
+ return connector;
+}
+
+int
+TAO_AV_UDP_Factory::init (int /* argc */,
+ char * /* argv */ [])
+{
+ return 0;
+}
+
+//------------------------------------------------------------
+// TAO_AV_UDP_Object
+//------------------------------------------------------------
+
+int
+TAO_AV_UDP_Object::handle_input (void)
+{
+ int n = this->transport_->recv (this->frame_.rd_ptr (),
+ this->frame_.size ());
+ if (n == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,"TAO_AV_UDP_Flow_Handler::handle_input recv failed\n"),-1);
+ if (n == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,"TAO_AV_UDP_Flow_Handler::handle_input connection closed\n"),-1);
+ this->frame_.wr_ptr (this->frame_.rd_ptr () + n);
+
+ return this->callback_->receive_frame (&this->frame_);
+}
+
+int
+TAO_AV_UDP_Object::send_frame (ACE_Message_Block *frame,
+ TAO_AV_frame_info *frame_info)
+{
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"TAO_AV_UDP_Object::send_frame\n"));
+ int result = this->transport_->send (frame);
+ if (result < 0)
+ return result;
+ return 0;
+}
+
+int
+TAO_AV_UDP_Object::send_frame (const iovec *iov,
+ int iovcnt,
+ TAO_AV_frame_info *frame_info)
+{
+ return this->transport_->send (iov,iovcnt);
+}
+
+TAO_AV_UDP_Object::TAO_AV_UDP_Object (TAO_AV_Callback *callback,
+ TAO_AV_Transport *transport)
+ :TAO_AV_Protocol_Object (callback,transport)
+{
+ this->frame_.size (2 * this->transport_->mtu ());
+}
+
+TAO_AV_UDP_Object::~TAO_AV_UDP_Object (void)
+{
+ //no-op
+}
+
+int
+TAO_AV_UDP_Object::destroy (void)
+{
+ this->callback_->handle_destroy ();
+ return 0;
+}
+
+
+//------------------------------------------------------------
+// TAO_AV_UDP_Flow_Factory
+//------------------------------------------------------------
+TAO_AV_UDP_Flow_Factory::TAO_AV_UDP_Flow_Factory (void)
+{
+}
+
+TAO_AV_UDP_Flow_Factory::~TAO_AV_UDP_Flow_Factory (void)
+{
+}
+
+int
+TAO_AV_UDP_Flow_Factory::init (int /* argc */,
+ char * /* argv */ [])
+{
+ return 0;
+}
+
+int
+TAO_AV_UDP_Flow_Factory::match_protocol (const char *flow_string)
+{
+ if (ACE_OS::strcasecmp (flow_string,"UDP") == 0)
+ return 1;
+ return 0;
+}
+
+TAO_AV_Protocol_Object*
+TAO_AV_UDP_Flow_Factory::make_protocol_object (TAO_FlowSpec_Entry *entry,
+ TAO_Base_StreamEndPoint *endpoint,
+ TAO_AV_Flow_Handler *handler,
+ TAO_AV_Transport *transport)
+{
+ TAO_AV_Callback *callback = 0;
+ endpoint->get_callback (entry->flowname (),
+ callback);
+
+
+ TAO_AV_UDP_Object *object = 0;
+ ACE_NEW_RETURN (object,
+ TAO_AV_UDP_Object (callback,
+ transport),
+ 0);
+ callback->open (object,
+ handler);
+ endpoint->set_protocol_object (entry->flowname (),
+ object);
+ return object;
+}
+
+ACE_FACTORY_DEFINE (AV, TAO_AV_UDP_Flow_Factory)
+ACE_STATIC_SVC_DEFINE (TAO_AV_UDP_Flow_Factory,
+ ASYS_TEXT ("UDP_Flow_Factory"),
+ ACE_SVC_OBJ_T,
+ &ACE_SVC_NAME (TAO_AV_UDP_Flow_Factory),
+ ACE_Service_Type::DELETE_THIS |
+ ACE_Service_Type::DELETE_OBJ,
+ 0)
+
+ACE_FACTORY_DEFINE (AV, TAO_AV_UDP_Factory)
+
+ACE_STATIC_SVC_DEFINE (TAO_AV_UDP_Factory,
+ ASYS_TEXT ("UDP_Factory"),
+ ACE_SVC_OBJ_T,
+ &ACE_SVC_NAME (TAO_AV_UDP_Factory),
+ ACE_Service_Type::DELETE_THIS |
+ ACE_Service_Type::DELETE_OBJ,
+ 0)
+
+
diff --git a/TAO/orbsvcs/orbsvcs/AV/UDP.h b/TAO/orbsvcs/orbsvcs/AV/UDP.h
new file mode 100644
index 00000000000..f15031ff9e3
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/AV/UDP.h
@@ -0,0 +1,219 @@
+/* -*- C++ -*- */
+
+// $Id$
+// ============================================================================
+//
+// = LIBRARY
+// ORBSVCS AVStreams
+//
+// = FILENAME
+// UDP.h
+//
+// = AUTHOR
+// Nagarajan Surendran <naga@cs.wustl.edu>
+//
+//
+// ============================================================================
+
+#ifndef TAO_AV_UDP_H
+#define TAO_AV_UDP_H
+
+#include "ace/OS.h"
+#include "Protocol_Factory.h"
+
+class TAO_ORBSVCS_Export TAO_AV_UDP_Factory : public TAO_AV_Transport_Factory
+{
+public:
+ TAO_AV_UDP_Factory (void);
+ virtual ~TAO_AV_UDP_Factory (void);
+ virtual int init (int argc, char *argv[]);
+ // Initialization hook.
+ virtual int match_protocol (const char *protocol_string);
+ virtual TAO_AV_Acceptor *make_acceptor (void);
+ virtual TAO_AV_Connector *make_connector (void);
+};
+
+class TAO_AV_UDP_Flow_Handler;
+
+class TAO_AV_UDP_Transport
+ :public TAO_AV_Transport
+{
+ // = TITLE
+ // A transport abstraction for udp sockets.
+ //
+ // = DESCRIPTION
+ // Uses the ACE_SOCK_Dgram to send the data.
+public:
+ TAO_AV_UDP_Transport (void);
+
+ TAO_AV_UDP_Transport (TAO_AV_UDP_Flow_Handler *handler);
+
+ virtual ~TAO_AV_UDP_Transport (void);
+ virtual int open (ACE_Addr *addr);
+
+ virtual int close (void);
+
+ virtual int mtu (void);
+
+ virtual ACE_Addr *get_peer_addr (void);
+
+ virtual int set_remote_address (const ACE_INET_Addr &address);
+
+ virtual ssize_t send (const ACE_Message_Block *mblk,
+ ACE_Time_Value *s = 0);
+ // Write the complete Message_Block chain to the connection.
+
+ virtual ssize_t send (const char *buf,
+ size_t len,
+ ACE_Time_Value *s = 0);
+ // Write the contents of the buffer of length len to the connection.
+
+ virtual ssize_t send (const iovec *iov,
+ int iovcnt,
+ ACE_Time_Value *s = 0);
+ // Write the contents of iovcnt iovec's to the connection.
+
+ virtual ssize_t recv (char *buf,
+ size_t len,
+ ACE_Time_Value *s = 0);
+ // Read len bytes from into buf.
+
+ virtual ssize_t recv (char *buf,
+ size_t len,
+ int flags,
+ ACE_Time_Value *s = 0);
+ // Read len bytes from into buf using flags.
+
+ virtual ssize_t recv (iovec *iov,
+ int iovcnt,
+ ACE_Time_Value *s = 0);
+ // Read received data into the iovec buffers.
+protected:
+ TAO_AV_UDP_Flow_Handler *handler_;
+ ACE_Addr *addr_;
+ ACE_INET_Addr peer_addr_;
+};
+
+class TAO_AV_UDP_Flow_Handler
+ :public virtual TAO_AV_Flow_Handler,
+ public virtual ACE_Event_Handler
+{
+public:
+ TAO_AV_UDP_Flow_Handler (void);
+ //Ctor
+ ~TAO_AV_UDP_Flow_Handler (void);
+ // Dtor
+ int open (ACE_Addr &address);
+ virtual TAO_AV_Transport *transport (void);
+ virtual int set_remote_address (ACE_Addr *address);
+ virtual ACE_HANDLE get_handle (void) const;
+ virtual int handle_input (ACE_HANDLE fd);
+ virtual int handle_timeout (const ACE_Time_Value &tv, const void *arg = 0);
+ const ACE_SOCK_Dgram *get_socket (void) const;
+ virtual ACE_Event_Handler* event_handler (void){ return this; }
+protected:
+ TAO_AV_Core *av_core_;
+ ACE_INET_Addr peer_addr_;
+ ACE_SOCK_Dgram sock_dgram_;
+};
+
+class TAO_AV_UDP_Acceptor
+ :public TAO_AV_Acceptor
+{
+public:
+ TAO_AV_UDP_Acceptor (void);
+ virtual ~TAO_AV_UDP_Acceptor (void);
+ virtual int open (TAO_Base_StreamEndPoint *endpoint,
+ TAO_AV_Core *av_core,
+ TAO_FlowSpec_Entry *entry,
+ TAO_AV_Flow_Protocol_Factory *factory);
+
+ virtual int open_default (TAO_Base_StreamEndPoint *endpoint,
+ TAO_AV_Core *av_core,
+ TAO_FlowSpec_Entry *entry,
+ TAO_AV_Flow_Protocol_Factory *factory);
+
+ virtual int open_i (ACE_INET_Addr *address);
+
+ virtual int close (void);
+ virtual int activate_svc_handler (TAO_AV_Flow_Handler *handler);
+protected:
+ TAO_Base_StreamEndPoint *endpoint_;
+ TAO_FlowSpec_Entry *entry_;
+ TAO_AV_Flow_Protocol_Factory *flow_protocol_factory_;
+};
+
+class TAO_AV_UDP_Connector
+ :public TAO_AV_Connector
+{
+public:
+ TAO_AV_UDP_Connector (void);
+ ~TAO_AV_UDP_Connector (void);
+ virtual int open (TAO_Base_StreamEndPoint *endpoint,
+ TAO_AV_Core *av_core,
+ TAO_AV_Flow_Protocol_Factory *factory);
+
+ virtual int connect (TAO_FlowSpec_Entry *entry,
+ TAO_AV_Transport *&transport);
+ virtual int activate_svc_handler (TAO_AV_Flow_Handler *handler);
+ virtual int close (void);
+protected:
+ TAO_Base_StreamEndPoint *endpoint_;
+ TAO_AV_Core *av_core_;
+ TAO_FlowSpec_Entry *entry_;
+ TAO_AV_Flow_Protocol_Factory *flow_protocol_factory_;
+};
+
+class TAO_ORBSVCS_Export TAO_AV_UDP_Object : public TAO_AV_Protocol_Object
+{
+public:
+ TAO_AV_UDP_Object (TAO_AV_Callback *callback,
+ TAO_AV_Transport *transport = 0);
+
+ virtual ~TAO_AV_UDP_Object (void);
+ // Dtor
+
+ virtual int handle_input (void);
+
+ virtual int send_frame (ACE_Message_Block *frame,
+ TAO_AV_frame_info *frame_info = 0);
+ // send a data frame.
+
+ virtual int send_frame (const iovec *iov,
+ int iovcnt,
+ TAO_AV_frame_info *frame_info = 0);
+
+ virtual int destroy (void);
+ // end the stream.
+
+private:
+ ACE_Message_Block frame_;
+ // Pre-allocated memory to receive the data...
+};
+
+class TAO_AV_UDP_Flow_Factory : public TAO_AV_Flow_Protocol_Factory
+{
+public:
+ TAO_AV_UDP_Flow_Factory (void);
+ virtual ~TAO_AV_UDP_Flow_Factory (void);
+ virtual int init (int argc, char *argv[]);
+ // Initialization hook.
+ virtual int match_protocol (const char *flow_string);
+ TAO_AV_Protocol_Object* make_protocol_object (TAO_FlowSpec_Entry *entry,
+ TAO_Base_StreamEndPoint *endpoint,
+ TAO_AV_Flow_Handler *handler,
+ TAO_AV_Transport *transport);
+};
+
+ACE_STATIC_SVC_DECLARE (TAO_AV_UDP_Flow_Factory)
+ACE_FACTORY_DECLARE (TAO_ORBSVCS, TAO_AV_UDP_Flow_Factory)
+
+ACE_STATIC_SVC_DECLARE (TAO_AV_UDP_Factory)
+ACE_FACTORY_DECLARE (TAO_ORBSVCS, TAO_AV_UDP_Factory)
+
+
+#if defined(__ACE_INLINE__)
+#include "UDP.i"
+#endif /* __ACE_INLINE__ */
+
+#endif /* TAO_AV_UDP_H */
diff --git a/TAO/orbsvcs/orbsvcs/AV/UDP.i b/TAO/orbsvcs/orbsvcs/AV/UDP.i
new file mode 100644
index 00000000000..2406225e417
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/AV/UDP.i
@@ -0,0 +1,20 @@
+/* -*- C++ -*- */
+
+// $Id$
+
+//----------------------------------------------------------------------
+// TAO_AV_UDP_Flow_Handler
+//----------------------------------------------------------------------
+ACE_INLINE
+const ACE_SOCK_Dgram *
+TAO_AV_UDP_Flow_Handler::get_socket (void) const
+{
+ return &this->sock_dgram_;
+}
+
+ACE_INLINE
+int
+TAO_AV_UDP_Flow_Handler::open (ACE_Addr &address)
+{
+ return this->sock_dgram_.open (address);
+}
diff --git a/TAO/orbsvcs/orbsvcs/AV/media-timer.cpp b/TAO/orbsvcs/orbsvcs/AV/media-timer.cpp
new file mode 100644
index 00000000000..4f24ab9484a
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/AV/media-timer.cpp
@@ -0,0 +1,86 @@
+//$Id$
+/*
+ * Copyright (c) 1995 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Computer Systems
+ * Engineering Group at Lawrence Berkeley Laboratory.
+ * 4. Neither the name of the University nor of the Laboratory may be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+static const char rcsid[] =
+ "@(#) $Header$";
+
+#include <math.h>
+#include "media-timer.h"
+
+MediaTimer* MediaTimer::instance_;
+
+MediaTimer::MediaTimer()
+{
+ instance_ = this;
+ offset_ = ACE_OS::rand ();
+}
+
+MediaTimer::~MediaTimer()
+{
+ instance_ = 0;
+}
+
+/*
+ * Default media timestamp -- convert unix system clock
+ * into a 90Khz timestamp. Grabbers override this virtual
+ * method if they can provide their own time base.
+ *
+ * XXX
+ * We save the corresponding unix time stamp to handle the
+ * unix_ts() call the transmitter will make to get the correspondence
+ * between the media timestamp & unix time.
+ */
+ACE_UINT32 MediaTimer::media_ts()
+{
+ timeval tv;
+ ::gettimeofday(&tv, 0);
+ ACE_UINT32 u = tv.tv_usec;
+ u = (u << 3) + u; /* x 9 */
+ /* sec * 90Khz + (usec * 90Khz) / 1e6 */
+ u = tv.tv_sec * 90000 + (u / 100);
+ return (u + offset_);
+}
+
+/*
+ * compute media time corresponding to the current unix time.
+ * in this generic routine, this is the same as media_ts() but,
+ * if a grabber has hardware or kernel timestamping, this routine
+ * must compute the correspondence between the hardware timestamp
+ * and the unix clock and appropriately offset the timestamp to
+ * correspond to the current clock. (This information if vital
+ * for cross-media synchronization.)
+ */
+ACE_UINT32 MediaTimer::ref_ts()
+{
+ return (media_ts());
+}
diff --git a/TAO/orbsvcs/orbsvcs/AV/media-timer.h b/TAO/orbsvcs/orbsvcs/AV/media-timer.h
new file mode 100644
index 00000000000..9e316044168
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/AV/media-timer.h
@@ -0,0 +1,59 @@
+/* -*- C++ -*- */
+// $Id$
+/*
+ * Copyright (c) 1995 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Computer Systems
+ * Engineering Group at Lawrence Berkeley Laboratory.
+ * 4. Neither the name of the University nor of the Laboratory may be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#) $Header$
+ */
+
+#ifndef TAO_AV_MEDIA_TIMER_H
+#define TAO_AV_MEDIA_TIMER_H
+
+#include "ace/OS.h"
+long random (void);
+
+class MediaTimer
+{
+ public:
+ MediaTimer();
+ virtual ~MediaTimer();
+ static inline MediaTimer* instance() { return (instance_); }
+ virtual ACE_UINT32 media_ts();
+ virtual ACE_UINT32 ref_ts();
+ inline ACE_UINT32 offset() const { return (offset_); }
+ private:
+ static MediaTimer* instance_;
+ protected:
+ ACE_UINT32 offset_; /* random offset */
+};
+
+#endif /* TAO_AV_MEDIA_TIMER_H */
diff --git a/TAO/orbsvcs/orbsvcs/AV/ntp-time.h b/TAO/orbsvcs/orbsvcs/AV/ntp-time.h
new file mode 100644
index 00000000000..d6cf15ec3ae
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/AV/ntp-time.h
@@ -0,0 +1,96 @@
+/* -*- C++ -*- */
+// $Id$
+/*
+ * Copyright (c) 1995 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Network Research
+ * Group at Lawrence Berkeley National Laboratory.
+ * 4. Neither the name of the University nor of the Laboratory may be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#) $Header$
+ */
+#ifndef TAO_AV_NTP_TIME_H
+#define TAO_AV_NTP_TIME_H
+
+#include "ace/OS.h"
+#include "RTCP.h"
+
+/*
+ * convert microseconds to fraction of second * 2^32 (i.e., the lsw of
+ * a 64-bit ntp timestamp). This routine uses the factorization
+ * 2^32/10^6 = 4096 + 256 - 1825/32 which results in a max conversion
+ * error of 3 * 10^-7 and an average error of half that.
+ */
+ACE_INLINE u_int usec2ntp(u_int usec)
+{
+ u_int t = (usec * 1825) >> 5;
+ return ((usec << 12) + (usec << 8) - t);
+}
+
+/*
+ * Number of seconds between 1-Jan-1900 and 1-Jan-1970
+ */
+const ACE_UINT32 GETTIMEOFDAY_TO_NTP_OFFSET = 2208988800;
+
+/*
+ * Return a 64-bit ntp timestamp (UTC time relative to Jan 1, 1970).
+ * gettimeofday conveniently gives us the correct reference -- we just
+ * need to convert sec+usec to a 64-bit fixed point (with binary point
+ * at bit 32).
+ */
+ACE_INLINE TAO_AV_RTCP::ntp64
+ntp64time (timeval tv)
+{
+ TAO_AV_RTCP::ntp64 n;
+ n.upper = (u_int)tv.tv_sec + GETTIMEOFDAY_TO_NTP_OFFSET;
+ n.lower = usec2ntp((u_int)tv.tv_usec);
+ return (n);
+}
+
+ACE_INLINE ACE_UINT32
+ntptime (timeval t)
+{
+ u_int s = (u_int)t.tv_sec + GETTIMEOFDAY_TO_NTP_OFFSET;
+ return (s << 16 | usec2ntp((u_int)t.tv_usec) >> 16);
+}
+
+ACE_INLINE ACE_UINT32
+ntptime()
+{
+ struct timeval tv;
+ ::gettimeofday(&tv, 0);
+ return (ntptime(tv));
+}
+
+ACE_INLINE timeval unixtime()
+{
+ struct timeval tv;
+ ::gettimeofday(&tv, 0);
+ return (tv);
+}
+#endif /* TAO_AV_NTP_TIME_H */
diff --git a/TAO/orbsvcs/orbsvcs/AV/sfp.cpp b/TAO/orbsvcs/orbsvcs/AV/sfp.cpp
index bf08d0a3b74..cf7981db389 100644
--- a/TAO/orbsvcs/orbsvcs/AV/sfp.cpp
+++ b/TAO/orbsvcs/orbsvcs/AV/sfp.cpp
@@ -1,24 +1,32 @@
// $Id$
-#include "orbsvcs/AV/sfp.h"
+#include "sfp.h"
#include "ace/ARGV.h"
// default arguments to pass to use for the ORB
-const char *TAO_SFP::TAO_SFP_ORB_ARGUMENTS = "-ORBobjrefstyle URL";
+const char *TAO_SFP_Base::TAO_SFP_ORB_ARGUMENTS = "-ORBobjrefstyle URL";
// SFP magic numbers
-const char *TAO_SFP::TAO_SFP_MAGIC_NUMBER = "=SFP";
-const char *TAO_SFP::TAO_SFP_FRAGMENT_MAGIC_NUMBER = "FRAG";
-const char *TAO_SFP::TAO_SFP_START_MAGIC_NUMBER = "=STA";
-const char *TAO_SFP::TAO_SFP_CREDIT_MAGIC_NUMBER = "=CRE";
-const char *TAO_SFP::TAO_SFP_STARTREPLY_MAGIC_NUMBER = "=STR";
+const char *TAO_SFP_Base::TAO_SFP_MAGIC_NUMBER = "=SFP";
+const char *TAO_SFP_Base::TAO_SFP_FRAGMENT_MAGIC_NUMBER = "FRAG";
+const char *TAO_SFP_Base::TAO_SFP_START_MAGIC_NUMBER = "=STA";
+const char *TAO_SFP_Base::TAO_SFP_CREDIT_MAGIC_NUMBER = "=CRE";
+const char *TAO_SFP_Base::TAO_SFP_STARTREPLY_MAGIC_NUMBER = "=STR";
// SFP version 1.0
-const unsigned char TAO_SFP::TAO_SFP_MAJOR_VERSION = 1;
-const unsigned char TAO_SFP::TAO_SFP_MINOR_VERSION = 0;
+const unsigned char TAO_SFP_Base::TAO_SFP_MAJOR_VERSION = 1;
+const unsigned char TAO_SFP_Base::TAO_SFP_MINOR_VERSION = 0;
// lengths of various SFP headers
-const unsigned char TAO_SFP::TAO_SFP_FRAME_HEADER_LEN = 12;
+const unsigned char TAO_SFP_Base::TAO_SFP_FRAME_HEADER_LEN = 12;
+const unsigned char TAO_SFP_Base::TAO_SFP_MESSAGE_SIZE_OFFSET = 8;
+const unsigned char TAO_SFP_Base::TAO_SFP_FRAGMENT_SIZE_OFFSET = 16;
+
+u_int TAO_SFP_Base::frame_header_len;
+u_int TAO_SFP_Base::start_reply_len;
+u_int TAO_SFP_Base::start_len;
+u_int TAO_SFP_Base::credit_len;
+u_int TAO_SFP_Base::fragment_len;
int
operator< (const TAO_SFP_Fragment_Node& left,
@@ -27,82 +35,88 @@ operator< (const TAO_SFP_Fragment_Node& left,
return left.fragment_info_.frag_number < right.fragment_info_.frag_number;
}
-// constructor.
-TAO_SFP::TAO_SFP (CORBA::ORB_ptr orb,
- ACE_Reactor* reactor,
- ACE_Time_Value timeout1,
- ACE_Time_Value timeout2,
- SFP_Callback *callback)
- :orb_ (orb),
- reactor_ (reactor),
- start_tries_ (10),
- startReply_tries_ (10),
- timeout1_ (timeout1),
- timeout2_ (timeout2),
- callback_ (callback),
- sequence_num_ (0),
- credit_num_ (10),
- magic_number_len_ (sizeof (magic_number_)-1)
+
+//------------------------------------------------------------
+// TAO_SFP_Base
+//------------------------------------------------------------
+
+TAO_SFP_Base::TAO_SFP_Base (void)
{
+ TAO_OutputCDR output_cdr;
ACE_DECLARE_NEW_CORBA_ENV;
+ flowProtocol::frameHeader frame_header;
+ flowProtocol::fragment fragment;
+ flowProtocol::credit credit;
+ flowProtocol::Start start;
+ flowProtocol::StartReply start_reply;
ACE_TRY
{
// fill in the default frameHeader fields.
- this->frame_header_.magic_number [0] = '=';
- this->frame_header_.magic_number [1] = 'S';
- this->frame_header_.magic_number [2] = 'F';
- this->frame_header_.magic_number [3] = 'P';
- this->frame_header_.flags = TAO_ENCAP_BYTE_ORDER;
- this->output_cdr_.reset ();
- this->output_cdr_.encode (flowProtocol::_tc_frameHeader,
- &this->frame_header_,
- 0,
- ACE_TRY_ENV);
+ frame_header.magic_number [0] = '=';
+ frame_header.magic_number [1] = 'S';
+ frame_header.magic_number [2] = 'F';
+ frame_header.magic_number [3] = 'P';
+ frame_header.flags = TAO_ENCAP_BYTE_ORDER;
+ output_cdr.reset ();
+ output_cdr.encode (flowProtocol::_tc_frameHeader,
+ &frame_header,
+ 0,
+ ACE_TRY_ENV);
ACE_TRY_CHECK;
- this->frame_header_len_ = this->output_cdr_.total_length ();
+ frame_header_len = output_cdr.total_length ();
// fill in the default fragment message fields.
- this->fragment_.magic_number [0] = 'F';
- this->fragment_.magic_number [1] = 'R';
- this->fragment_.magic_number [2] = 'A';
- this->fragment_.magic_number [3] = 'G';
- this->output_cdr_.reset ();
- this->output_cdr_.encode (flowProtocol::_tc_fragment,
- &this->fragment_,
+ fragment.magic_number [0] = 'F';
+ fragment.magic_number [1] = 'R';
+ fragment.magic_number [2] = 'A';
+ fragment.magic_number [3] = 'G';
+ output_cdr.reset ();
+ output_cdr.encode (flowProtocol::_tc_fragment,
+ &fragment,
0,
ACE_TRY_ENV);
ACE_TRY_CHECK;
- this->fragment_len_ = this->output_cdr_.total_length ();
+ fragment_len = output_cdr.total_length ();
// fill in the default Start message fields.
- this->start_.magic_number [0] = '=';
- this->start_.magic_number [1] = 'S';
- this->start_.magic_number [2] = 'T';
- this->start_.magic_number [3] = 'A';
- this->start_.major_version = TAO_SFP_MAJOR_VERSION;
- this->start_.minor_version = TAO_SFP_MINOR_VERSION;
- this->start_.flags = 0;
- this->start_len_ = sizeof (this->start_);
+ start.magic_number [0] = '=';
+ start.magic_number [1] = 'S';
+ start.magic_number [2] = 'T';
+ start.magic_number [3] = 'A';
+ start.major_version = TAO_SFP_Base::TAO_SFP_MAJOR_VERSION;
+ start.minor_version = TAO_SFP_Base::TAO_SFP_MINOR_VERSION;
+ start.flags = 0;
+ output_cdr.reset ();
+ output_cdr.encode (flowProtocol::_tc_Start,
+ &start,
+ 0,
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ start_len = output_cdr.total_length ();
// fill in the default StartReply message fields.
- this->start_reply_.magic_number [0] = '=';
- this->start_reply_.magic_number [1] = 'S';
- this->start_reply_.magic_number [2] = 'T';
- this->start_reply_.magic_number [3] = 'R';
- this->start_reply_.flags = 0;
- this->start_reply_len_ = sizeof (this->start_reply_);
+ start_reply.magic_number [0] = '=';
+ start_reply.magic_number [1] = 'S';
+ start_reply.magic_number [2] = 'T';
+ start_reply.magic_number [3] = 'R';
+ start_reply.flags = 0;
+ output_cdr.reset ();
+ output_cdr.encode (flowProtocol::_tc_StartReply,
+ &start_reply,
+ 0,
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ start_reply_len = output_cdr.total_length ();
+
// fill in the default Credit message fields.
- this->credit_.magic_number [0] = '=';
- this->credit_.magic_number [1] = 'C';
- this->credit_.magic_number [2] = 'R';
- this->credit_.magic_number [3] = 'E';
- this->credit_len_ = sizeof (this->credit_);
- this->output_cdr_.reset ();
- // this->output_cdr_ <<= this->credit_;
- this->output_cdr_.reset ();
- this->output_cdr_.encode (flowProtocol::_tc_credit,
- &this->credit_,
- 0,
- ACE_TRY_ENV);
+ credit.magic_number [0] = '=';
+ credit.magic_number [1] = 'C';
+ credit.magic_number [2] = 'R';
+ credit.magic_number [3] = 'E';
+ output_cdr.reset ();
+ output_cdr.encode (flowProtocol::_tc_credit,
+ &credit,
+ 0,
+ ACE_TRY_ENV);
ACE_TRY_CHECK;
- this->credit_len_ = this->output_cdr_.total_length ();
+ credit_len = output_cdr.total_length ();
}
ACE_CATCHANY
{
@@ -111,859 +125,821 @@ TAO_SFP::TAO_SFP (CORBA::ORB_ptr orb,
ACE_ENDTRY;
}
-// Start the active end of the stream.
int
-TAO_SFP::start_stream (const char *receiver_addr)
+TAO_SFP_Base::handle_input (TAO_AV_Transport *transport,
+ TAO_SFP_Frame_State &state,
+ TAO_AV_frame_info *&frame_info)
{
int result;
- ACE_INET_Addr sender;
- result = this->connect_to_receiver (receiver_addr);
+ flowProtocol::MsgType msg_type;
+ result = TAO_SFP_Base::peek_message_type (transport,
+ msg_type);
if (result < 0)
return result;
- while (this->start_tries_ > 0)
+ // TAO_InputCDR &input = state.cdr;
+ switch (msg_type)
{
- result = this->send_start ();
- if (result != 0)
- return result;
- // Timed recv.
- char magic_number [MAGIC_NUMBER_LEN];
- ssize_t n =this->dgram_.recv (magic_number,
- this->magic_number_len_,
- sender,
- MSG_PEEK,
- &this->timeout1_);
- // ACE_DEBUG ((LM_DEBUG,"n = %d\n",n));
+ case flowProtocol::SimpleFrame_Msg:
+ case flowProtocol::Frame_Msg:
+ {
+ result = TAO_SFP_Base::peek_frame_header (transport,
+ state.frame_header_,
+ state.cdr);
+ if (result < 0)
+ return result;
+ int result =TAO_SFP_Base::read_frame (transport,
+ state.frame_header_,
+ state,
+ frame_info);
+ if (result < 0)
+ return result;
+ break;
+ }
+ case flowProtocol::Fragment_Msg:
+ {
+ result = TAO_SFP_Base::peek_fragment_header (transport,
+ state.fragment_,
+ state.cdr);
+ if (result < 0)
+ return result;
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"Fragment received\n"));
+ result = TAO_SFP_Base::read_fragment (transport,
+ state.fragment_,
+ state,
+ frame_info);
+ if (result < 0)
+ return result;
+ break;
+ }
+ case flowProtocol::EndofStream_Msg:
+ {
+ result = TAO_SFP_Base::read_endofstream_message (transport,
+ state.frame_header_,
+ state.cdr);
+ if (result < 0)
+ return result;
+ break;
+ }
+ default:
+ break;
+ }
+ return 0;
+}
+
+int
+TAO_SFP_Base::read_frame (TAO_AV_Transport *transport,
+ flowProtocol::frameHeader &frame_header,
+ TAO_SFP_Frame_State &state,
+ TAO_AV_frame_info *&frame_info)
+{
+ ACE_Message_Block *message_block = 0;
+ int result = -1;
+ ACE_DECLARE_NEW_CORBA_ENV;
+ ACE_TRY
+ {
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"Reading simple frame\n"));
+ // Check to see what the length of the message is.
+ int byte_order = frame_header.flags & 0x1;
+ int message_len = frame_header.message_size;
+
+// ACE_NEW_RETURN (message_block,
+// ACE_Message_Block (message_len),
+// 0);
+ state.static_frame_.rd_ptr (state.static_frame_.base ());
+ state.static_frame_.wr_ptr (state.static_frame_.base ());
+ int n = transport->recv (state.static_frame_.rd_ptr (),message_len);
if (n == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,"SFP::handle_input -peek"),0);
+ else if (n==0)
+ ACE_ERROR_RETURN ((LM_ERROR,"SFP::handle_input -peek"),0);
+ else if (n != message_len)
+ ACE_ERROR_RETURN ((LM_ERROR,"SFP::read_simple_frame:message truncated\n"),0);
+ message_block = &state.static_frame_;
+ // print the buffer.
+ // this->dump_buf (message,n);
+ // skip over the frame header.
+ message_block->rd_ptr (frame_header_len);
+ message_block->wr_ptr (n);
+ CORBA::ULong ssrc = 0;
+ TAO_SFP_Fragment_Table_Entry *fragment_entry = 0;
+ if (frame_header.flags & 0x2)
{
- if (errno == ETIME)
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"fragmented frame:0th fragment\n"));
+ state.more_fragments_ = 1;
+ ACE_Message_Block *data = 0;
+ switch (frame_header.message_type)
+ {
+ case flowProtocol::Frame_Msg:
+ {
+ // read the frame info.
+ ACE_Message_Block frame_info_mb (message_len-frame_header_len+ACE_CDR::MAX_ALIGNMENT);
+ ACE_CDR::mb_align (&frame_info_mb);
+ frame_info_mb.copy (message_block->rd_ptr (),
+ message_block->length ());
+ // print the buffer.
+ // this->dump_buf (message_block->rd_ptr (),16);
+ TAO_InputCDR frame_info_cdr (&frame_info_mb,byte_order);
+ frame_info_cdr.decode (flowProtocol::_tc_frame,
+ &state.frame_,
+ 0,
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"frame.timestamp = %d, frame.synchsource = %d, frame.sequence_num = %d\n",
+ state.frame_.timestamp,
+ state.frame_.synchSource,
+ state.frame_.sequence_num));
+ ssrc = state.frame_.synchSource;
+ // The remaining message in the CDR stream is the fragment data for frag.0
+ data = frame_info_cdr.start ()->clone ();
+ break;
+ }
+ case flowProtocol::SimpleFrame_Msg:
+ {
+ data = message_block->clone ();
+ break;
+ }
+ case flowProtocol::SequencedFrame_Msg:
+ break;
+ case flowProtocol::SpecialFrame_Msg:
+ break;
+ }
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"Length of 0th fragment= %d\n",data->length ()));
+ TAO_SFP_Fragment_Table *fragment_table = 0;
+ result = state.fragment_table_map_.find (ssrc,fragment_table);
+ if (result != 0)
{
- ACE_DEBUG ((LM_DEBUG,"Timed out in reading StartReply"));
- this->start_tries_ --;
- continue;
+ ACE_NEW_RETURN (fragment_table,
+ TAO_SFP_Fragment_Table,
+ -1);
+ result = state.fragment_table_map_.bind (ssrc,fragment_table);
+ if (result < 0)
+ ACE_ERROR_RETURN ((LM_ERROR,"TAO_SFP_Base::read_frame: fragment_table_map:bind failed\n"),-1);
}
+
+ TAO_SFP_Fragment_Node *new_node;
+ ACE_NEW_RETURN (new_node,
+ TAO_SFP_Fragment_Node,
+ 0);
+ new_node->fragment_info_.frag_sz = data->length ();
+ new_node->fragment_info_.frag_number = 0;
+ if (state.frame_.source_ids.length () > 0)
+ new_node->fragment_info_.source_id = state.frame_.source_ids [0];
else
- ACE_ERROR_RETURN ((LM_ERROR,"dgram recv error:%d,%p",errno,"recv"),-1);
+ new_node->fragment_info_.source_id = 0;
+ new_node->data_ = data;
+ // TAO_SFP_Base::dump_buf (data->rd_ptr (),data->length ());
+ if (fragment_table->find (state.frame_.sequence_num,fragment_entry) == 0)
+ {
+ // This case can happen where a nth (n > 0)fragment is received before the 0th fragment.
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"fragment table entry found for 0th fragment:\n"));
+ result = fragment_entry->fragment_set_.insert (*new_node);
+ if (result != 0)
+ ACE_ERROR_RETURN ((LM_ERROR,"insert for 0th fragment failed\n"),0);
+ // enter the frame info.
+
+ // check if all the fragments have been received.
+ state.frame_block_ = TAO_SFP_Base::check_all_fragments (fragment_entry);
+ if (state.frame_block_ != 0)
+ state.more_fragments_ = 0;
+ }
+ else
+ {
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"fragment table entry not found for 0th fragment\n"));
+ TAO_SFP_Fragment_Table_Entry *new_entry;
+ ACE_NEW_RETURN (new_entry,
+ TAO_SFP_Fragment_Table_Entry,
+ 0);
+ result = new_entry->fragment_set_.insert (*new_node);
+ if (result != 0)
+ ACE_ERROR_RETURN ((LM_ERROR,"insert for 0th fragment failed\n"),0);
+ fragment_entry = new_entry;
+ // not found. so bind a new entry.
+ result = fragment_table->bind (state.frame_.sequence_num,new_entry);
+ if (result != 0)
+ ACE_ERROR_RETURN ((LM_ERROR,"fragment table bind failed\n"),0);
+ if (frame_header.message_type & 4 )
+ fragment_entry->frame_info.boundary_marker = 1;
+ switch (frame_header.message_type)
+ {
+ case flowProtocol::Frame_Msg:
+ fragment_entry->frame_info.ssrc = state.frame_.synchSource;
+ fragment_entry->frame_info.timestamp = state.frame_.timestamp;
+ fragment_entry->frame_info.sequence_num = state.frame_.sequence_num;
+ break;
+ case flowProtocol::SimpleFrame_Msg:
+ fragment_entry->frame_info.ssrc =
+ fragment_entry->frame_info.timestamp =
+ fragment_entry->frame_info.sequence_num = 0;
+ break;
+ }
+ return 0;
+ }
}
- else if (n==0)
- ACE_ERROR_RETURN ((LM_ERROR,"SFP::start_stream -peek"),-1);
- // Null terminate the magic number.
- magic_number [this->magic_number_len_] = 0;
- // check if its startreply message.
- if (ACE_OS::strcmp (magic_number,TAO_SFP_STARTREPLY_MAGIC_NUMBER) == 0)
+ else
{
- ACE_DEBUG ((LM_DEBUG,"(%P|%t)StartReply message received\n"));
- flowProtocol::StartReply start_reply;
- n = this->dgram_.recv ((char *)&start_reply,
- sizeof (start_reply),
- sender);
- if (n != sizeof (start_reply))
- ACE_ERROR_RETURN ((LM_ERROR,"SFP::handle_input-StartReply\n"),0);
- // check for SFP version difference.??
- this->state_ = REPLY_RECEIVED;
+ state.more_fragments_ = 0;
+ state.frame_block_ = message_block;
+ }
+ if (state.more_fragments_ == 0)
+ {
+ if (fragment_entry != 0)
+ {
+ ACE_NEW_RETURN (frame_info,
+ TAO_AV_frame_info,
+ -1);
+ *frame_info = fragment_entry->frame_info;
+ }
}
- else
- ACE_ERROR_RETURN ((LM_ERROR,"Invalid message while StartReply expected\n"),0);
- // register the data handler.
- return this->register_dgram_handler ();
}
+ ACE_CATCHANY
+ {
+ ACE_TRY_ENV.print_exception ("read_simple_frame");
+ return 0;
+ }
+ ACE_ENDTRY;
+ ACE_CHECK_RETURN (0);
return 0;
}
-// Start the passive end of the stream.
int
-TAO_SFP::start_stream (const char *local_addr,int /* Credit */)
+TAO_SFP_Base::read_fragment (TAO_AV_Transport *transport,
+ flowProtocol::fragment &fragment,
+ TAO_SFP_Frame_State &state,
+ TAO_AV_frame_info *&frame_info)
{
- int result;
- ACE_INET_Addr sender;
+ TAO_SFP_Fragment_Table_Entry *fragment_entry = 0;
+ int result = -1;
- this->state_ = PASSIVE_START;
- ACE_INET_Addr myaddr (local_addr);
- result = this->dgram_.open (myaddr);
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"frag_number = %d, frag_size = %d,source_id = %d sequnce_num = %d\n",
+ fragment.frag_number,fragment.frag_sz,fragment.source_id,fragment.sequence_num));
+ ACE_Message_Block *data;
+ ACE_NEW_RETURN (data,
+ ACE_Message_Block(fragment.frag_sz),
+ -1);
+
+ // Read the fragment.
+ int n = transport->recv (data->wr_ptr (),fragment.frag_sz);
+ if ((n == -1) || (n==0))
+ ACE_ERROR_RETURN ((LM_ERROR,"TAO_SFP::read_fragment:%p",""),-1);
+ // move past the fragment header.
+ data->rd_ptr (fragment_len);
+ data->wr_ptr (n);
+ // TAO_SFP_Base::dump_buf (data->rd_ptr (),data->length ());
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"length of %dth fragment is: %d\n",
+ fragment.frag_number,
+ data->length ()));
+
+ TAO_SFP_Fragment_Node *new_node;
+ ACE_NEW_RETURN (new_node,
+ TAO_SFP_Fragment_Node,
+ -1);
+ new_node->fragment_info_ = fragment;
+ new_node->data_ = data;
+ TAO_SFP_Fragment_Table *fragment_table = 0;
+ result = state.fragment_table_map_.find (fragment.source_id,fragment_table);
if (result != 0)
- ACE_ERROR_RETURN ((LM_ERROR,"SFP::passive start- open failed\n"),-1);
-
- char magic_number[MAGIC_NUMBER_LEN];
- // Timed recv.
- ssize_t n =this->dgram_.recv (magic_number,
- this->magic_number_len_,
- sender,
- MSG_PEEK,
- &this->timeout2_);
- if ((n == -1) && (errno == ETIME))
{
- ACE_ERROR_RETURN ((LM_ERROR,"Timedout in reading Start"),-1);
+ ACE_NEW_RETURN (fragment_table,
+ TAO_SFP_Fragment_Table,
+ -1);
+ result = state.fragment_table_map_.bind (fragment.source_id,fragment_table);
+ if (result < 0)
+ ACE_ERROR_RETURN ((LM_ERROR,"TAO_SFP_Base::read_fragment:fragment_table_map:bind failed\n"),-1);
}
- else if (n==0)
- ACE_ERROR_RETURN ((LM_ERROR,"SFP::start_stream -peek"),-1);
- // Null terminate the magic_number.
- magic_number [this->magic_number_len_] = 0;
- if (ACE_OS::strcmp (magic_number,TAO_SFP_START_MAGIC_NUMBER) == 0)
+ if (fragment_table->find (fragment.sequence_num,fragment_entry) == 0)
{
- ACE_DEBUG ((LM_DEBUG,"Start received:"));
- // Read the start message.
- flowProtocol::Start start;
- n = this->dgram_.recv ((char *)&start,
- sizeof (start),
- sender);
- if (n != sizeof (start))
- ACE_ERROR_RETURN ((LM_ERROR,"SFP::handle_input - Start\n"),0);
- else
- ACE_DEBUG ((LM_DEBUG,"Start message consumed\n"));
- this->state_ = START_RECEIVED;
- this->receiver_inet_addr_.set (sender);
- // Now send a startReply message back.
- result = this->send_startReply ();
+ // Already an entry exists. Traverse the list and insert it at the right place.
+ result = fragment_entry->fragment_set_.insert (*new_node);
if (result != 0)
- return result;
- // Now we register a timeout handler until we receive a data
- // frame.
- result = this->reactor_->schedule_timer (this,
- 0,
- this->timeout1_);
- if (result == -1)
- ACE_ERROR_RETURN ((LM_ERROR,"schedule_timer failed\n"),result);
-
- // register the data handler.
- return this->register_dgram_handler ();
+ ACE_ERROR_RETURN ((LM_ERROR,"insert for %dth node failed\n",fragment.frag_number),-1);
+ // check if all the fragments have been received.
}
else
- ACE_ERROR_RETURN ((LM_ERROR,"Invalid messaged received while Start expected\n"),-1);
+ {
+ ACE_NEW_RETURN (fragment_entry,
+ TAO_SFP_Fragment_Table_Entry,
+ -1);
+ fragment_entry->fragment_set_.insert (*new_node);
+ // bind a new entry for this sequence number.
+ result = fragment_table->bind (fragment.sequence_num,fragment_entry);
+ if (result != 0)
+ ACE_ERROR_RETURN ((LM_ERROR,"bind for %dth fragment failed\n",
+ fragment.frag_number),-1);
+ }
+ if (!(fragment.flags & 0x2))
+ {
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"Last fragment received\n"));
+ // if bit 1 is not set then there are
+ // no more fragments.
+ fragment_entry->last_received_ = 1;
+ // since fragment number starts from 0 to n-1 we add 1.
+ fragment_entry->num_fragments_ = fragment.frag_number + 1;
+ }
+
+
+ state.frame_block_ = check_all_fragments (fragment_entry);
+ if (state.frame_block_ != 0)
+ {
+ state.more_fragments_ = 0;
+ ACE_NEW_RETURN (frame_info,
+ TAO_AV_frame_info,
+ -1);
+ *frame_info = fragment_entry->frame_info;
+ }
+ return 0;
}
-// Sends the ACE_Message_Block data as a frame, fragmenting if necessary.
-int
-TAO_SFP::send_frame (ACE_Message_Block *frame)
+ACE_Message_Block*
+TAO_SFP_Base::check_all_fragments (TAO_SFP_Fragment_Table_Entry *fragment_entry)
{
- ACE_TRY_NEW_ENV
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"table size: %d, num_fragments: %d\n",fragment_entry->fragment_set_.size (),fragment_entry->num_fragments_));
+ // check to see if all the frames have been received.
+ if (fragment_entry->fragment_set_.size () == fragment_entry->num_fragments_)
{
- if (this->credit_num_ > 0)
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"all fragments have been received\n"));
+ // all the fragments have been received
+ // we can now chain the ACE_Message_Blocks in the fragment_set_ and then return them
+ // back.
+ ACE_Message_Block *frame = 0,*head = 0;
+ FRAGMENT_SET_ITERATOR frag_iterator (fragment_entry->fragment_set_);
+ TAO_SFP_Fragment_Node *node;
+ for (;frag_iterator.next (node) != 0;frag_iterator.advance ())
{
- // if we have enough credit then we send.
- int total_length = 0;
- for (ACE_Message_Block *temp = frame;temp != 0;temp = temp->cont ())
- total_length += temp->length ();
- ACE_DEBUG ((LM_DEBUG,"total_length of frame=%d\n",total_length));
- if (total_length < (SFP_MAX_PACKET_SIZE -this->frame_header_len_))
- {
- // clear the output cdr.
- this->output_cdr_.reset ();
- // CDR encode the frame header.
- //(<<= isAvailable only in compiled marshalling!)
- this->frame_header_.message_type = flowProtocol::SimpleFrame_Msg;
- this->frame_header_.message_size = frame->length ()+this->frame_header_len_;
- this->output_cdr_.encode (flowProtocol::_tc_frameHeader,
- &this->frame_header_,
- 0,
- ACE_TRY_ENV);
- ACE_TRY_CHECK;
- // this->output_cdr_ <<= this->frame_header_;
- this->send_cdr_buffer (this->output_cdr_,frame);
- }
- else // larger frame,fragment and send it.
+ if (!head)
+ head = frame = node->data_;
+ else
{
- // set the fragments bit.
- this->frame_header_.flags |= 2;
- // This is a good maximum, because Dgrams cannot be longer than
- // 64K and the usual size for a CDR fragment is 512 bytes.
- // @@ TODO In the future we may need to allocate some memory
- // from the heap.
- int message_len = this->frame_header_len_;
- iovec iov[TAO_WRITEV_MAX];
- int iovcnt = 1;// since first iov is for frameHeader.
- flowProtocol::frame frame_info;
- frame_info.timestamp = 10;
- frame_info.synchSource = 10;
- frame_info.source_ids.length (1);
- frame_info.source_ids [0] = 1; // XXX random number.
- frame_info.sequence_num = this->sequence_num_;
- this->output_cdr_.reset ();
- this->output_cdr_.encode (flowProtocol::_tc_frame,
- &frame_info,
- 0,
- ACE_TRY_ENV);
- ACE_TRY_CHECK;
- ACE_DEBUG ((LM_DEBUG,"frame info length:%d\n",this->output_cdr_.total_length ()));
- for (const ACE_Message_Block* b = this->output_cdr_.begin ()->clone ();
- b != 0 && iovcnt < TAO_WRITEV_MAX;
- b = b->cont ())
- {
- // ACE_DEBUG ((LM_DEBUG,"iovcnt:%d\n",iovcnt));
- iov[iovcnt].iov_base = b->rd_ptr ();
- iov[iovcnt].iov_len = b->length ();
- message_len += b->length ();
- ACE_DEBUG ((LM_DEBUG,"send_cdr_buffer:length=%d\n",b->length ()));
- // print the buffer.
- // this->dump_buf (b->rd_ptr (),b->length ());
- iovcnt++;
- }
- ACE_Message_Block *mb = frame;
- int prev_len;
- while (mb != 0)
- {
- prev_len = message_len;
- message_len += mb->length ();
- if (message_len > SFP_MAX_PACKET_SIZE)
- {
- // get only the length that we can accomodate.
- size_t current_len = SFP_MAX_PACKET_SIZE - prev_len;
- if (current_len < mb->length ())
- {
- // The above condition is an assertion.
- iov [iovcnt].iov_base = mb->rd_ptr ();
- iov [iovcnt].iov_len = current_len;
- message_len += (current_len-mb->length ());
- mb->rd_ptr (current_len);
- iovcnt++;
- }
- break;
- }
- else
- {
- // we can accomodate this message block
- iov [iovcnt].iov_base = mb->rd_ptr ();
- iov [iovcnt].iov_len = mb->length ();
- message_len += mb->length ();
- iovcnt++;
- mb = mb->cont ();
- }
- }
- // This can be either a simpleframe or a sequenced frame,other types of frames.
- this->frame_header_.message_type = flowProtocol::Frame_Msg;
- this->frame_header_.message_size = message_len;
- ACE_DEBUG ((LM_DEBUG,"first fragment of size:%d\n",message_len- this->frame_header_len_));
- this->output_cdr_.reset ();
- this->output_cdr_.encode (flowProtocol::_tc_frameHeader,
- &this->frame_header_,
- 0,
- ACE_TRY_ENV);
- ACE_TRY_CHECK;
- // header will be only in the first cdr fragment.
- iov[0].iov_base = this->output_cdr_.begin ()->rd_ptr ();
- iov[0].iov_len = this->output_cdr_.begin ()->length ();
- ACE_DEBUG ((LM_DEBUG,"frame header len:%d\n",iov[0].iov_len));
- // send the first fragment.
- for (int i=0;i<iovcnt;i++)
- {
- // this->dump_buf (iov[i].iov_base,iov[i].iov_len);
- }
- ssize_t n = this->dgram_.send (iov,
- iovcnt,
- this->receiver_inet_addr_);
- if (n == -1)
- ACE_ERROR_RETURN ((LM_ERROR,
- "send_frame (%t) fragment 0 send failed %p\n", ""),-1);
- else if (n == 0)
- ACE_ERROR_RETURN ((LM_ERROR,
- "send_Frame (%t) EOF on send \n"),-1);
-
- int frag_number = 1;
- // If there is any more data send those as fragments.
- while (mb != 0)
- {
- message_len = this->fragment_len_;
- iovcnt = 1;// 1 is for the frag header.
- while (mb != 0)
- {
- prev_len = message_len;
- message_len += mb->length ();
- if (message_len > SFP_MAX_PACKET_SIZE)
- {
- // get only the length that we can accomodate.
- size_t current_len = SFP_MAX_PACKET_SIZE - prev_len;
- if (current_len < mb->length ())
- {
- // The above condition is an assertion.
- iov [iovcnt].iov_base = mb->rd_ptr ();
- iov [iovcnt].iov_len = current_len;
- message_len += (current_len - mb->length ());
- mb->rd_ptr (current_len);
- iovcnt++;
- }
- break;
- }
- else
- {
- // we can accomodate this message block
- iov [iovcnt].iov_base = mb->rd_ptr ();
- iov [iovcnt].iov_len = mb->length ();
- iovcnt++;
- mb = mb->cont ();
- }
- }
- this->fragment_.flags = TAO_ENCAP_BYTE_ORDER;
- if (mb == 0)
- {
- ACE_DEBUG ((LM_DEBUG,"sending the last fragment\n"));
- // This is the last fragment so clear the fragments bit.
- }
- else
- {
- // set the more fragments flag
- this->fragment_.flags |= 2;
- }
- // if there are no data blocks.
- if (iovcnt == 1)
- break;
- this->fragment_.frag_number = frag_number++;
- this->fragment_.sequence_num = this->sequence_num_;
- this->fragment_.frag_sz = message_len;
- this->fragment_.source_id = 0;
- this->output_cdr_.reset ();
- this->output_cdr_.encode (flowProtocol::_tc_fragment,
- &this->fragment_,
- 0,
- ACE_TRY_ENV);
- ACE_TRY_CHECK;
- ACE_DEBUG ((LM_DEBUG,"sending a fragment numbered %d of size %d\n",
- this->fragment_.frag_number,
- this->fragment_.frag_sz));
- // THe header will be only in the first cdr fragment.
- iov[0].iov_base = this->output_cdr_.begin ()->rd_ptr ();
- iov[0].iov_len = this->output_cdr_.begin ()->length ();
- // send the fragment now.
- // without the sleep the fragments gets lost!
- // probably because the UDP buffer queue on the sender side
- // is overflown it drops the packets.
- // XXX: This is a hack.
- ACE_OS::sleep (1);
- ssize_t n = this->dgram_.send (iov,
- iovcnt,
- this->receiver_inet_addr_);
- if ((n == -1) || (n==0))
- ACE_ERROR_RETURN ((LM_ERROR,"TAO_SFP::send_framed failed:%p\n",""),-1);
- }
+ frame->cont (node->data_);
+ frame = node->data_;
}
}
- else
- {
- // flow controlled so wait.
- }
+ return head;
+ }
+ return 0;
+}
+
+CORBA::Boolean
+TAO_SFP_Base::start_frame (CORBA::Octet flags,
+ flowProtocol::MsgType type,
+ TAO_OutputCDR &msg)
+{
+ ACE_DECLARE_NEW_CORBA_ENV;
+ msg.reset ();
+ flowProtocol::frameHeader frame_header;
+ ACE_TRY
+ {
+
+ frame_header.magic_number [0] = '=';
+ frame_header.magic_number [1] = 'S';
+ frame_header.magic_number [2] = 'F';
+ frame_header.magic_number [3] = 'P';
+ frame_header.flags = flags;
+ frame_header.message_type = type;
+ frame_header.message_size = 0;
+ msg.encode (flowProtocol::_tc_frameHeader,
+ &frame_header,
+ 0,
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK;
}
ACE_CATCHANY
{
- ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"TAO_SFP::send_frame");
- return -1;
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"TAO_SFP_Base::start_frame");
+ return 0;
}
ACE_ENDTRY;
- return 0;
+ ACE_CHECK_RETURN (0);
+ return 1;
}
-
-// creates a connected dgram.
-int
-TAO_SFP::connect_to_receiver (const char *receiver_addr)
+CORBA::Boolean
+TAO_SFP_Base::write_start_message (TAO_OutputCDR &msg)
{
- this->receiver_addr_ = ACE_OS::strdup (receiver_addr);
- // Get the local UDP address
- if (this->dgram_.open (ACE_Addr::sap_any) == -1)
- ACE_ERROR_RETURN ((LM_ERROR,"(%P|%t) datagram open failed %p\n"),1);
-
- // set the socket buffer sizes to 64k.
- int sndbufsize = ACE_DEFAULT_MAX_SOCKET_BUFSIZ;
- int rcvbufsize = ACE_DEFAULT_MAX_SOCKET_BUFSIZ;
-
- if (this->dgram_.set_option (SOL_SOCKET,
- SO_SNDBUF,
- (void *) &sndbufsize,
- sizeof (sndbufsize)) == -1
- && errno != ENOTSUP)
- return -1;
- else if (this->dgram_.set_option (SOL_SOCKET,
- SO_RCVBUF,
- (void *) &rcvbufsize,
- sizeof (rcvbufsize)) == -1
- && errno != ENOTSUP)
- return -1;
-
- this->receiver_inet_addr_.set (receiver_addr);
- return 0;
+ ACE_DECLARE_NEW_CORBA_ENV;
+ flowProtocol::Start start;
+ ACE_TRY
+ {
+ start.magic_number [0] = '=';
+ start.magic_number [1] = 'S';
+ start.magic_number [2] = 'T';
+ start.magic_number [3] = 'A';
+ start.major_version = TAO_SFP_MAJOR_VERSION;
+ start.minor_version = TAO_SFP_MINOR_VERSION;
+ start.flags = 0;
+ msg.encode (flowProtocol::_tc_Start,
+ &start,
+ 0,
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"TAO_SFP_Base::write_start_message");
+ return 0;
+ }
+ ACE_ENDTRY;
+ ACE_CHECK_RETURN (0);
+ return 1;
}
-// sends all the ACE_Message_Blocks in the current CDR stream.
-int
-TAO_SFP::send_cdr_buffer (TAO_OutputCDR &cdr,ACE_Message_Block *mb)
+CORBA::Boolean
+TAO_SFP_Base::write_start_reply_message (TAO_OutputCDR &msg)
{
- // This is a good maximum, because Dgrams cannot be longer than
- // 64K and the usual size for a CDR fragment is 512 bytes.
- // @@ TODO In the future we may need to allocate some memory
- // from the heap.
- iovec iov[TAO_WRITEV_MAX];
- int iovcnt = 0;
- const ACE_Message_Block* b = 0;
- for (b = cdr.begin ();
- b != cdr.end () && iovcnt < TAO_WRITEV_MAX;
- b = b->cont ())
+ ACE_DECLARE_NEW_CORBA_ENV;
+ flowProtocol::StartReply start_reply;
+ ACE_TRY
{
- iov[iovcnt].iov_base = b->rd_ptr ();
- iov[iovcnt].iov_len = b->length ();
- // ACE_DEBUG ((LM_DEBUG,"send_cdr_buffer:length=%d\n",b->length ()));
- // print the buffer.
- // this->dump_buf (b->rd_ptr (),b->length ());
- iovcnt++;
+ start_reply.magic_number [0] = '=';
+ start_reply.magic_number [1] = 'S';
+ start_reply.magic_number [2] = 'T';
+ start_reply.magic_number [3] = 'R';
+ start_reply.flags = 0;
+ msg.encode (flowProtocol::_tc_StartReply,
+ &start_reply,
+ 0,
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK;
}
- for (b = mb; b!=0 && iovcnt < TAO_WRITEV_MAX; b=b->cont ())
+ ACE_CATCHANY
{
- iov [iovcnt].iov_base = b->rd_ptr ();
- iov [iovcnt].iov_len = b->length ();
- iovcnt++;
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"TAO_SFP_Base::write_start_reply_message");
+ return 0;
}
- // send the message.
- ssize_t n = this->dgram_.send (iov,
- iovcnt,
- this->receiver_inet_addr_);
- if (n == -1)
+ ACE_ENDTRY;
+ ACE_CHECK_RETURN (0);
+ return 1;
+}
+
+CORBA::Boolean
+TAO_SFP_Base::write_credit_message (CORBA::ULong cred_num,
+ TAO_OutputCDR &msg)
+{
+ ACE_DECLARE_NEW_CORBA_ENV;
+ flowProtocol::credit credit;
+ ACE_TRY
{
- ACE_DEBUG ((LM_DEBUG,
- "SFP::send_cdr_buffer (%t) send failed %p\n", ""));
- return -1;
+ credit.magic_number [0] = '=';
+ credit.magic_number [1] = 'C';
+ credit.magic_number [2] = 'R';
+ credit.magic_number [3] = 'E';
+ credit.cred_num = cred_num;
+ msg.encode (flowProtocol::_tc_credit,
+ &credit,
+ 0,
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK;
}
- else if (n == 0)
+ ACE_CATCHANY
{
- ACE_DEBUG ((LM_DEBUG,
- "SFP::send_cdr_buffer (%t) EOF on send \n"));
- return -1;
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"TAO_SFP_Base::write_credit_message");
+ return 0;
}
- return 0;
+ ACE_ENDTRY;
+ ACE_CHECK_RETURN (0);
+ return 1;
}
-int
-TAO_SFP::send_start (void)
+CORBA::Boolean
+TAO_SFP_Base::write_fragment_message (CORBA::Octet flags,
+ CORBA::ULong fragment_number,
+ CORBA::ULong sequence_number,
+ CORBA::ULong source_id,
+ TAO_OutputCDR &msg)
{
- // copy the magic number into the message
- this->state_ = ACTIVE_START;
- // Now send the network byte ordered start message.
- int n = this->dgram_.send ((char *)&this->start_,
- this->start_len_,
- this->receiver_inet_addr_);
- if (n!= this->start_len_)
- ACE_ERROR_RETURN ((LM_ERROR,"start send failed\n"),-1);
-
- ACE_DEBUG ((LM_DEBUG," Start sent\n"));
- return 0;
+ ACE_DECLARE_NEW_CORBA_ENV;
+ msg.reset ();
+ flowProtocol::fragment fragment;
+ ACE_TRY
+ {
+ fragment.magic_number [0] = 'F';
+ fragment.magic_number [1] = 'R';
+ fragment.magic_number [2] = 'A';
+ fragment.magic_number [3] = 'G';
+ fragment.flags = flags;
+ fragment.frag_number = fragment_number;
+ fragment.sequence_num = sequence_number;
+ fragment.source_id = source_id;
+ msg.encode (flowProtocol::_tc_fragment,
+ &fragment,
+ 0,
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"TAO_SFP_Base::write_fragment_message");
+ return 0;
+ }
+ ACE_ENDTRY;
+ ACE_CHECK_RETURN (0);
+ return 1;
}
-int
-TAO_SFP::send_startReply (void)
+CORBA::Boolean
+TAO_SFP_Base::write_frame_message (CORBA::ULong timestamp,
+ CORBA::ULong synchSource,
+ flowProtocol::my_seq_ulong source_ids,
+ CORBA::ULong sequence_num,
+ TAO_OutputCDR &msg)
{
- int n = this->dgram_.send ((char *)&this->start_reply_,
- this->start_reply_len_,
- this->receiver_inet_addr_);
- if (n!= this->start_reply_len_)
- ACE_ERROR_RETURN ((LM_ERROR,"startreply send failed\n"),-1);
-
- ACE_DEBUG ((LM_DEBUG," startReply sent\n"));
- return 0;
+ ACE_DECLARE_NEW_CORBA_ENV;
+ flowProtocol::frame frame;
+ ACE_TRY
+ {
+ frame.timestamp = timestamp;
+ frame.synchSource = synchSource;
+ frame.source_ids = source_ids;
+ frame.sequence_num = sequence_num;
+ msg.encode (flowProtocol::_tc_frame,
+ &frame,
+ 0,
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"TAO_SFP_Base::write_frame_message");
+ return 0;
+ }
+ ACE_ENDTRY;
+ ACE_CHECK_RETURN (0);
+ return 1;
}
int
-TAO_SFP::handle_timeout (const ACE_Time_Value &/* tv */,
- const void * /* arg */)
+TAO_SFP_Base::send_message (TAO_AV_Transport *transport,
+ TAO_OutputCDR &stream,
+ ACE_Message_Block *mb)
{
- int result;
- // Handle the timeout for timeout1 and timeout2.
- switch (this->state_)
+ size_t total_len = stream.total_length ();
+ if (mb != 0)
{
- case ACTIVE_START:
- case PASSIVE_START:
- // Timingout for Start Messages.
- ACE_DEBUG ((LM_DEBUG,"Invalid state in handle_timeout\n"));
- break;
- case START_RECEIVED:
- // we need to reduce the startreply_tries and also reschedule
- // the timer.
- if (this->startReply_tries_ --)
+ for (ACE_Message_Block *temp = mb;temp != 0;temp = temp->cont ())
+ total_len += temp->length ();
+
+ char *buf = (char *) stream.buffer ();
+ size_t offset = TAO_SFP_MESSAGE_SIZE_OFFSET;
+ // second character distinguished =SFP and FRAG.
+ if (*(buf) == 'F')
{
- ACE_DEBUG ((LM_DEBUG,"Timed out on receiving Data Frame\n"));
- // send startreply.
- result = this->send_startReply ();
- if (result != 0)
- ACE_ERROR_RETURN ((LM_ERROR,"Error in sending startreply"),0);
- this->reactor_->schedule_timer (this,
- 0,
- this->timeout1_);
+ // Fragment message.
+ offset = TAO_SFP_FRAGMENT_SIZE_OFFSET;
}
+#if !defined (ACE_ENABLE_SWAP_ON_WRITE)
+ *ACE_reinterpret_cast (CORBA::ULong *, buf + offset) = total_len;
+#else
+ if (!stream->do_byte_swap ())
+ *ACE_reinterpret_cast (CORBA::ULong *,
+ buf + offset) = total_len;
else
- {
- this->end_stream ();
- }
- break;
- default:
- ACE_DEBUG ((LM_DEBUG,"Handle_timeout: No Action in this state %d",this->state_));
+ ACE_CDR::swap_4 (ACE_reinterpret_cast (char *,
+ &total_len),
+ buf + offset);
+#endif /* ACE_ENABLE_SWAP_ON_WRITE */
}
- return 0;
+ // we join the data block with the cdr block.
+ ACE_Message_Block *end = (ACE_Message_Block *)stream.end ();
+ if (end == 0)
+ {
+ // There is only one message block.
+ end = (ACE_Message_Block *)stream.begin ();
+ // TAO_SFP_Base::dump_buf (end->rd_ptr (),end->length ());
+ }
+ end->cont (mb);
+ ssize_t n = transport->send (stream.begin ());
+ if (n == -1)
+ {
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,
+ "TAO: (%P|%t) closing conn after fault %p\n",
+ "GIOP::send_request ()"));
+ return -1;
+ }
+ // EOF.
+ if (n == 0)
+ {
+ if (TAO_orbdebug)
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,
+ "TAO: (%P|%t) GIOP::send_request () "
+ "EOF, closing conn:\n"));
+ return -1;
+ }
+ return 1;
+
}
-// Handle_input is called when data arrives on the dgram
-// socket. Currently both the receiver and sender side input is
-// handled in this same handle_input ().
int
-TAO_SFP::handle_input (ACE_HANDLE /* fd */)
+TAO_SFP_Base::peek_message_type (TAO_AV_Transport *transport,
+ flowProtocol::MsgType &msg_type)
{
- // ACE_DEBUG ((LM_DEBUG,"TAO_SFP::handle_input\n"));
- flowProtocol::MsgType msg_type = flowProtocol::Start_Msg;
- ACE_INET_Addr sender;
- char peek_buffer [MAGIC_NUMBER_LEN+2];// 2 is for flags + message_type.
- int peek_len = MAGIC_NUMBER_LEN +2;
- ssize_t n =this->dgram_.recv (peek_buffer,
- peek_len,
- sender,
- MSG_PEEK);
- ACE_OS::strncpy (this->magic_number_,
+ char peek_buffer [TAO_SFP_MAGIC_NUMBER_LEN+2];// 2 is for flags + message_type.
+ int peek_len = TAO_SFP_MAGIC_NUMBER_LEN +2;
+ char magic_number [TAO_SFP_MAGIC_NUMBER_LEN+1];
+ ssize_t n =transport->recv (peek_buffer,
+ peek_len,
+ MSG_PEEK);
+ ACE_OS::strncpy (magic_number,
peek_buffer,
- this->magic_number_len_);
- this->magic_number_ [this->magic_number_len_] = 0;
+ TAO_SFP_MAGIC_NUMBER_LEN);
+ magic_number [TAO_SFP_MAGIC_NUMBER_LEN] = 0;
if (n == -1)
ACE_ERROR_RETURN ((LM_ERROR,"SFP::handle_input -peek"),-1);
else if (n==0)
- ACE_ERROR_RETURN ((LM_ERROR,"SFP::handle_input -peek"),0);
+ ACE_ERROR_RETURN ((LM_ERROR,"SFP::handle_input -peek"),-1);
- if (ACE_OS::strcmp (this->magic_number_,TAO_SFP_START_MAGIC_NUMBER) == 0)
+ if (ACE_OS::strcmp (magic_number,TAO_SFP_START_MAGIC_NUMBER) == 0)
{
- ACE_DEBUG ((LM_DEBUG,"(%P|%t)Start message received\n"));
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"(%P|%t)Start message received\n"));
msg_type = flowProtocol::Start_Msg;
}
- else if (ACE_OS::strcmp (this->magic_number_,TAO_SFP_STARTREPLY_MAGIC_NUMBER) == 0)
+ else if (ACE_OS::strcmp (magic_number,TAO_SFP_STARTREPLY_MAGIC_NUMBER) == 0)
{
- ACE_DEBUG ((LM_DEBUG,"(%P|%t)StartReply message received\n"));
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"(%P|%t)StartReply message received\n"));
msg_type = flowProtocol::StartReply_Msg;
}
- else if (ACE_OS::strcmp (this->magic_number_,TAO_SFP_MAGIC_NUMBER) == 0)
+ else if (ACE_OS::strcmp (magic_number,TAO_SFP_MAGIC_NUMBER) == 0)
{
- // ACE_DEBUG ((LM_DEBUG,"(%P|%t) frameHeader received\n"));
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"(%P|%t) frameHeader received\n"));
// msg_type = flowProtocol::SimpleFrame;
- msg_type = (flowProtocol::MsgType)peek_buffer [MESSAGE_TYPE_OFFSET];
- ACE_DEBUG ((LM_DEBUG,"Message Type = %d\n",msg_type));
+ msg_type = (flowProtocol::MsgType)peek_buffer [TAO_SFP_MESSAGE_TYPE_OFFSET];
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"Message Type = %d\n",msg_type));
}
- else if (ACE_OS::strcmp (this->magic_number_,TAO_SFP_FRAGMENT_MAGIC_NUMBER) == 0)
+ else if (ACE_OS::strcmp (magic_number,TAO_SFP_FRAGMENT_MAGIC_NUMBER) == 0)
{
- ACE_DEBUG ((LM_DEBUG,"(%P|%t) fragment Header received\n"));
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"(%P|%t) fragment Header received\n"));
msg_type = flowProtocol::Fragment_Msg;
}
- else if (ACE_OS::strcmp (this->magic_number_,TAO_SFP_CREDIT_MAGIC_NUMBER) == 0)
+ else if (ACE_OS::strcmp (magic_number,TAO_SFP_CREDIT_MAGIC_NUMBER) == 0)
{
- ACE_DEBUG ((LM_DEBUG,"(%P|%t) credit message received\n"));
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"(%P|%t) credit message received\n"));
msg_type = flowProtocol::Credit_Msg;
}
else
- ACE_ERROR_RETURN ((LM_ERROR,"TAO_SFP:Invalid magic number\n"),0);
- switch (this->state_)
- {
- case ACTIVE_START:
- // Check if we received a StartReply back.
- ACE_DEBUG ((LM_DEBUG,"Unexpected message while StartReply expected\n"));
- break;
- case PASSIVE_START:
- // Check if we received a Start from the Sender.
- ACE_DEBUG ((LM_DEBUG,"Unexpected message while Start expected\n"));
- break;
- case START_RECEIVED:
- // In this state we check for credit frames.
- switch (msg_type)
- {
- case flowProtocol::Credit_Msg:
- {
- flowProtocol::credit credit;
- n = this->dgram_.recv ((char *)&credit,
- sizeof (credit),
- sender);
- if (n != sizeof (credit))
- ACE_ERROR_RETURN ((LM_ERROR,"SFP::handle_input - Credit\n"),0);
- break;
- }
- case flowProtocol::Start_Msg:
- // consume the retransmitted start message.
- {
- flowProtocol::Start start;
- n = this->dgram_.recv ((char *)&start,
- sizeof (start),
- sender);
- if (n != sizeof (start))
- ACE_ERROR_RETURN ((LM_ERROR,"SFP::handle_input - Start\n"),0);
- else
- ACE_DEBUG ((LM_DEBUG,"Start message consumed\n"));
- break;
- }
+ ACE_ERROR_RETURN ((LM_ERROR,"TAO_SFP:Invalid magic number\n"),-1);
+ return 0;
+}
- case flowProtocol::Frame_Msg:
- case flowProtocol::SimpleFrame_Msg:
- {
- ACE_Message_Block * mb =this->read_simple_frame ();
- if (mb != 0)
- this->callback_->receive_frame (mb);
- else
- {
- if (!this->more_fragments_)
- {
- char buf[BUFSIZ];
- // consume the wrong UDP frame.
- this->dgram_.recv (buf,
- BUFSIZ,
- sender);
- }
- }
- break;
- }
- case flowProtocol::Fragment_Msg:
- {
- ACE_DEBUG ((LM_DEBUG,"Fragment received\n"));
- ACE_Message_Block *result = this->read_fragment ();
- // no more fragments.
- if (result != 0)
- this->callback_->receive_frame (result);
- break;
- }
- case flowProtocol::EndofStream_Msg:
- {
- char *buf;
- ACE_NEW_RETURN (buf,
- char [ this->frame_header_len_],
- -1);
- n = this->dgram_.recv (buf,
- this->frame_header_len_,
- sender);
- if (n == -1)
- ACE_ERROR_RETURN ((LM_ERROR,"Error reading EndofStream;%p",""),-1);
- this->callback_->end_stream ();
- return -1;
- }
- default:
- break;
- }
- break;
- case REPLY_RECEIVED:
- // In this state we check for Data frames.
- switch (msg_type)
+int
+TAO_SFP_Base::read_start_message (TAO_AV_Transport *transport,
+ flowProtocol::Start &start,
+ TAO_InputCDR &input)
+{
+ ACE_DECLARE_NEW_CORBA_ENV;
+ ACE_TRY
+ {
+ input.grow (start_len);
+ char *buf = input.rd_ptr ();
+ int n = transport->recv (buf,
+ start_len);
+ if (n != ACE_static_cast (int, start_len))
+ ACE_ERROR_RETURN ((LM_ERROR,"%p","TAO_SFP_Base::read_start\n"),0);
+ else
{
- case flowProtocol::StartReply_Msg:
- {
- flowProtocol::StartReply start_reply;
- n = this->dgram_.recv ((char *)&start_reply,
- sizeof (start_reply),
- sender);
- if (n != sizeof (start_reply))
- ACE_ERROR_RETURN ((LM_ERROR,"SFP::handle_input-StartReply\n"),0);
- else
- ACE_DEBUG ((LM_DEBUG,"start reply consumed\n"));
- }
- break;
- default:
- ACE_DEBUG ((LM_DEBUG,"Invalid message in state REPLY_RECEIVED\n"));
- break;
+ input.decode (flowProtocol::_tc_Start,
+ &start,
+ 0,
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK;
}
- break;
- default:
- break;
}
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"TAO_SFP_Base::read_start_message");
+ return -1;
+ }
+ ACE_ENDTRY;
+ ACE_CHECK_RETURN (-1);
return 0;
}
+
int
-TAO_SFP::end_stream (void)
+TAO_SFP_Base::read_start_reply_message (TAO_AV_Transport *transport,
+ flowProtocol::StartReply &start_reply,
+ TAO_InputCDR &input)
{
- int result = -1;
ACE_DECLARE_NEW_CORBA_ENV;
ACE_TRY
{
- ACE_DEBUG ((LM_DEBUG,"SFP - ending the stream\n"));
- // send the EndofStream message.
- this->frame_header_.flags = TAO_ENCAP_BYTE_ORDER;
- this->frame_header_.message_type = flowProtocol::EndofStream_Msg;
- this->output_cdr_.reset ();
- this->output_cdr_.encode (flowProtocol::_tc_frameHeader,
- &this->frame_header_,
- 0,
- ACE_TRY_ENV);
- ACE_TRY_CHECK;
- ssize_t n = this->dgram_.send (this->output_cdr_.begin ()->rd_ptr (),
- this->output_cdr_.begin ()->length (),
- this->receiver_inet_addr_);
- if ((n==-1) || (n==0))
- ACE_ERROR_RETURN ((LM_ERROR,"Error sending endofstream message:%p",""),-1);
- result = this->reactor_->remove_handler (this,
- ACE_Event_Handler::READ_MASK);
-
+ input.grow (start_len);
+ char *buf = input.rd_ptr ();
+ int n = transport->recv (buf,
+ start_reply_len);
+ if (n != ACE_static_cast (int, start_len))
+ ACE_ERROR_RETURN ((LM_ERROR,"%p","TAO_SFP_Base::read_start_reply_message"),0);
+ else
+ {
+ input.decode (flowProtocol::_tc_StartReply,
+ &start_reply,
+ 0,
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ }
}
ACE_CATCHANY
{
- ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"TAO_SFP::end_stream ()\n");
- return result;
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"TAO_SFP_Base::read_start_reply_message");
+ return -1;
}
ACE_ENDTRY;
ACE_CHECK_RETURN (-1);
- return result;
+ return 0;
}
int
-TAO_SFP::register_dgram_handler (void)
+TAO_SFP_Base::read_credit_message (TAO_AV_Transport *transport,
+ flowProtocol::credit &credit,
+ TAO_InputCDR &input)
{
- int result = this->reactor_->register_handler (this,
- ACE_Event_Handler::READ_MASK);
- return result;
-}
-
-ACE_HANDLE
-TAO_SFP::get_handle (void) const
-{
- return this->dgram_.get_handle ();
+ ACE_DECLARE_NEW_CORBA_ENV;
+ ACE_TRY
+ {
+ input.grow (start_len);
+ char *buf = input.rd_ptr ();
+ int n = transport->recv (buf,
+ credit_len);
+ if (n != ACE_static_cast (int, credit_len))
+ ACE_ERROR_RETURN ((LM_ERROR,"%p","TAO_SFP_Base::read_credit_message"),0);
+ else
+ {
+ input.decode (flowProtocol::_tc_credit,
+ &credit,
+ 0,
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ }
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"TAO_SFP_Base::read_credit_message");
+ return -1;
+ }
+ ACE_ENDTRY;
+ ACE_CHECK_RETURN (-1);
+ return 0;
}
-ACE_Message_Block *
-TAO_SFP::read_simple_frame (void)
+int
+TAO_SFP_Base::read_endofstream_message (TAO_AV_Transport *transport,
+ flowProtocol::frameHeader &endofstream,
+ TAO_InputCDR &input)
{
- ACE_Message_Block *message_block = 0;
ACE_DECLARE_NEW_CORBA_ENV;
ACE_TRY
{
- ACE_DEBUG ((LM_DEBUG,"Reading simple frame\n"));
- // Check to see what the length of the message is.
-
- flowProtocol::frameHeader frame_header;
-
- int result =
- this->read_frame_header (frame_header);
-
- if (result < 0)
- return 0;
- int byte_order = frame_header.flags & 0x1;
- int message_len = frame_header.message_size;
-
- ACE_NEW_RETURN (message_block,
- ACE_Message_Block (message_len),
- 0);
- ACE_INET_Addr sender;
- int n = this->dgram_.recv (message_block->wr_ptr (),message_len,sender);
- if (n == -1)
- ACE_ERROR_RETURN ((LM_ERROR,"SFP::handle_input -peek"),0);
- else if (n==0)
- ACE_ERROR_RETURN ((LM_ERROR,"SFP::handle_input -peek"),0);
- else if (n != message_len)
- ACE_ERROR_RETURN ((LM_ERROR,"SFP::read_simple_frame:message truncated\n"),0);
- // print the buffer.
- // this->dump_buf (message,n);
- // skip over the frame header.
- message_block->rd_ptr (this->frame_header_len_);
- message_block->wr_ptr (n);
- if (frame_header.flags & 0x2)
+ input.grow (start_len);
+ char *buf = input.rd_ptr ();
+ int n = transport->recv (buf,
+ frame_header_len);
+ if (n != ACE_static_cast (int, frame_header_len))
+ ACE_ERROR_RETURN ((LM_ERROR,"%p","TAO_SFP_Base::read_endofstream_message"),0);
+ else
{
- ACE_DEBUG ((LM_DEBUG,"fragmented frame:0th fragment\n"));
- this->more_fragments_ = 1;
- // read the frame info.
- ACE_Message_Block frame_info_mb (message_len-this->frame_header_len_+ACE_CDR::MAX_ALIGNMENT);
- ACE_CDR::mb_align (&frame_info_mb);
- frame_info_mb.copy (message_block->rd_ptr (),
- message_block->length ());
- // print the buffer.
- // this->dump_buf (message_block->rd_ptr (),16);
- TAO_InputCDR frame_info_cdr (&frame_info_mb,byte_order);
- flowProtocol::frame frame_info;
- frame_info_cdr.decode (flowProtocol::_tc_frame,
- &frame_info,
- 0,
- ACE_TRY_ENV);
+ input.decode (flowProtocol::_tc_frameHeader,
+ &endofstream,
+ 0,
+ ACE_TRY_ENV);
ACE_TRY_CHECK;
- ACE_DEBUG ((LM_DEBUG,"frame.timestamp = %d, frame.synchsource = %d, frame.sequence_num = %d\n",
- frame_info.timestamp,
- frame_info.synchSource,
- frame_info.sequence_num));
- // The remaining message in the CDR stream is the fragment data for frag.0
- ACE_Message_Block *data =
- frame_info_cdr.start ()->clone ();
- ACE_DEBUG ((LM_DEBUG,"Length of 0th fragment= %d\n",data->length ()));
- TAO_SFP_Fragment_Table_Entry *fragment_entry = 0;
- TAO_SFP_Fragment_Node *new_node;
- ACE_NEW_RETURN (new_node,
- TAO_SFP_Fragment_Node,
- 0);
- new_node->fragment_info_.frag_sz = data->length ();
- new_node->fragment_info_.frag_number = 0;
- new_node->fragment_info_.source_id = frame_info.source_ids [0];
- new_node->data_ = data;
- if (this->fragment_table_.find (frame_info.sequence_num,fragment_entry) == 0)
- {
- // This case can happen where a nth (n > 0)fragment is received before the 0th fragment.
- ACE_DEBUG ((LM_DEBUG,"fragment table entry found for 0th fragment:\n"));
- result = fragment_entry->fragment_set_.insert (*new_node);
- if (result != 0)
- ACE_ERROR_RETURN ((LM_ERROR,"insert for 0th fragment failed\n"),0);
- // check if all the fragments have been received.
- return check_all_fragments (fragment_entry);
- }
- else
- {
- ACE_DEBUG ((LM_DEBUG,"fragment table entry not found for 0th fragment\n"));
- TAO_SFP_Fragment_Table_Entry *new_entry;
- ACE_NEW_RETURN (new_entry,
- TAO_SFP_Fragment_Table_Entry,
- 0);
- result = new_entry->fragment_set_.insert (*new_node);
- if (result != 0)
- ACE_ERROR_RETURN ((LM_ERROR,"insert for 0th fragment failed\n"),0);
- // not found. so bind a new entry.
- result = this->fragment_table_.bind (frame_info.sequence_num,new_entry);
- if (result != 0)
- ACE_ERROR_RETURN ((LM_ERROR,"fragment table bind failed\n"),0);
- return 0;
- }
}
}
ACE_CATCHANY
{
- ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"read_simple_frame");
- return 0;
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"TAO_SFP_Base::read_credit_message");
+ return -1;
}
ACE_ENDTRY;
- ACE_CHECK_RETURN (0);
- return message_block;
+ ACE_CHECK_RETURN (-1);
+ return 0;
}
int
-TAO_SFP::read_frame_header (flowProtocol::frameHeader &frame_header)
+TAO_SFP_Base::peek_frame_header (TAO_AV_Transport *transport,
+ flowProtocol::frameHeader &header,
+ TAO_InputCDR &input)
{
ACE_DECLARE_NEW_CORBA_ENV;
ACE_TRY
{
- ACE_INET_Addr sender;
- char *buf;
- ACE_NEW_RETURN (buf,
- char [this->frame_header_len_+ACE_CDR::MAX_ALIGNMENT],
- 0);
- ssize_t n =this->dgram_.recv (buf,
- this->frame_header_len_,
- sender,
- MSG_PEEK);
- if (n == -1)
- ACE_ERROR_RETURN ((LM_ERROR,"SFP::read_simple_frame -peek:%p",""),0);
- else if (n==0)
- ACE_ERROR_RETURN ((LM_ERROR,"SFP::read_simple_frame -peek:%p",""),0);
- else if (n != this->frame_header_len_)
- ACE_ERROR_RETURN ((LM_ERROR,"SFP::read_simple_frame - not able to peek\n"),0);
- // print the buffer.
- // this->dump_buf (buf,n);
- ACE_Message_Block mb (n+ACE_CDR::MAX_ALIGNMENT);
- ACE_CDR::mb_align (&mb);
- int result
- = mb.copy (buf,n);
- if (result == -1)
- ACE_ERROR_RETURN ((LM_ERROR,"Message_Block::copy failed\n"),0);
- // buf[4] is the byte order.
- int byte_order = buf[4] & 0x1;
- // ACE_DEBUG ((LM_DEBUG,"mb len = %d,byte_order=%d\n",mb.length (),byte_order));
- TAO_InputCDR cdr (&mb,byte_order);
- // cdr >>= frame_header;
- cdr.decode (flowProtocol::_tc_frameHeader,
- &frame_header,
- 0,
- ACE_TRY_ENV);
- ACE_TRY_CHECK;
-
- ACE_DEBUG ((LM_DEBUG,"message_type = %d, message_size = %d,message_flags = %d\n",
- frame_header.message_type,frame_header.message_size,frame_header.flags));
-
+ input.grow (frame_header_len);
+ char *buf = input.rd_ptr ();
+ int n = transport->recv (buf,
+ frame_header_len,
+ MSG_PEEK);
+ if (n != ACE_static_cast (int, frame_header_len))
+ ACE_ERROR_RETURN ((LM_ERROR,"%p","TAO_SFP_Base::read_endofstream_message"),0);
+ else
+ {
+ input.decode (flowProtocol::_tc_frameHeader,
+ &header,
+ 0,
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ }
+ // TAO_SFP_Base::dump_buf (buf,n);
}
ACE_CATCHANY
{
- ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"TAO_SFP::read_frame_header");
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"TAO_SFP_Base::read_credit_message");
return -1;
}
ACE_ENDTRY;
@@ -971,161 +947,530 @@ TAO_SFP::read_frame_header (flowProtocol::frameHeader &frame_header)
return 0;
}
-ACE_Message_Block *
-TAO_SFP::read_fragment (void)
+int
+TAO_SFP_Base::peek_fragment_header (TAO_AV_Transport *transport,
+ flowProtocol::fragment &fragment,
+ TAO_InputCDR &input)
{
- TAO_SFP_Fragment_Table_Entry *fragment_entry = 0;
ACE_DECLARE_NEW_CORBA_ENV;
ACE_TRY
{
- flowProtocol::fragment fragment;
- ACE_INET_Addr sender;
- char *buf = 0;
- ACE_NEW_RETURN (buf,
- char [this->fragment_len_+ACE_CDR::MAX_ALIGNMENT],
- 0);
- ssize_t n =this->dgram_.recv (buf,
- this->fragment_len_,
- sender,
- MSG_PEEK);
- if (n == -1)
- ACE_ERROR_RETURN ((LM_ERROR,"SFP::read_fragment -peek:%p",""),0);
- else if (n==0)
- ACE_ERROR_RETURN ((LM_ERROR,"SFP::read_simple_frame -peek:%p",""),0);
- else if (n != this->fragment_len_)
- ACE_ERROR_RETURN ((LM_ERROR,"SFP::read_simple_frame - not able to peek\n"),0);
- // print the buffer.
- this->dump_buf (buf,n);
- ACE_Message_Block mb (n+ACE_CDR::MAX_ALIGNMENT);
- ACE_CDR::mb_align (&mb);
- int result
- = mb.copy (buf,n);
- if (result == -1)
- ACE_ERROR_RETURN ((LM_ERROR,"read_fragment::Message_Block::copy failed\n"),0);
- // buf[4] is the byte order.
- int byte_order = buf[4] & 0x1;
- ACE_DEBUG ((LM_DEBUG,"mb len = %d,byte_order=%d\n",mb.length (),byte_order));
- TAO_InputCDR cdr (&mb,byte_order);
- // cdr >>= frame_header;
- cdr.decode (flowProtocol::_tc_fragment,
- &fragment,
- 0,
- ACE_TRY_ENV);
- ACE_TRY_CHECK;
-
- ACE_DEBUG ((LM_DEBUG,"frag number = %d, frag size = %d,source id = %d\n",
- fragment.frag_number,fragment.frag_sz,fragment.source_id));
-
- ACE_Message_Block *data;
- ACE_NEW_RETURN (data,
- ACE_Message_Block(fragment.frag_sz),
- 0);
-
- // Read the fragment.
- n = this->dgram_.recv (data->wr_ptr (),fragment.frag_sz,sender);
- if ((n == -1) || (n==0))
- ACE_ERROR_RETURN ((LM_ERROR,"TAO_SFP::read_fragment:%p",""),0);
- // move past the fragment header.
- data->rd_ptr (this->fragment_len_);
- data->wr_ptr (n);
- ACE_DEBUG ((LM_DEBUG,"length of %dth fragment is: %d\n",
- fragment.frag_number,
- data->length ()));
-
- TAO_SFP_Fragment_Node *new_node;
- ACE_NEW_RETURN (new_node,
- TAO_SFP_Fragment_Node,
- 0);
- new_node->fragment_info_ = fragment;
- new_node->data_ = data;
- if (this->fragment_table_.find (fragment.sequence_num,fragment_entry) == 0)
+ input.grow (fragment_len);
+ char *buf = input.rd_ptr ();
+ int n = transport->recv (buf,
+ fragment_len,
+ MSG_PEEK);
+ if (n != ACE_static_cast (int, fragment_len))
+ ACE_ERROR_RETURN ((LM_ERROR,"%p","TAO_SFP_Base::read_endofstream_message"),0);
+ else
{
- // Already an entry exists. Traverse the list and insert it at the right place.
- result = fragment_entry->fragment_set_.insert (*new_node);
- if (result != 0)
- ACE_ERROR_RETURN ((LM_ERROR,"insert for %dth node failed\n",fragment.frag_number),0);
- // check if all the fragments have been received.
+ input.decode (flowProtocol::_tc_fragment,
+ &fragment,
+ 0,
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK;
}
- else
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"TAO_SFP_Base::read_credit_message");
+ return -1;
+ }
+ ACE_ENDTRY;
+ ACE_CHECK_RETURN (-1);
+ return 0;
+}
+
+void
+TAO_SFP_Base::dump_buf (char *buffer,int size)
+{
+ char *buf = buffer;
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"\n========================================\n"));
+ for (int i=0;i<size;i++)
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"%d ",buf[i]));
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"\n========================================\n"));
+}
+
+//------------------------------------------------------------
+// TAO_SFP_Object
+//------------------------------------------------------------
+
+TAO_SFP_Object::TAO_SFP_Object (TAO_AV_Callback *callback,
+ TAO_AV_Transport *transport)
+ :TAO_AV_Protocol_Object (callback,transport),
+ source_id_ (10),
+ max_credit_ (-1),
+ current_credit_ (-1)
+{
+ TAO_SFP_BASE::instance ();
+ this->state_.static_frame_.size (2* this->transport_->mtu ());
+}
+
+TAO_SFP_Object::~TAO_SFP_Object (void)
+{
+ //no-op
+}
+
+int
+TAO_SFP_Object::destroy (void)
+{
+ int result = -1;
+ TAO_OutputCDR out_stream;
+ result = TAO_SFP_Base::start_frame (TAO_ENCAP_BYTE_ORDER,
+ flowProtocol::EndofStream_Msg,
+ out_stream);
+ if (result < 0)
+ return result;
+ result = TAO_SFP_Base::send_message (this->transport_,
+ out_stream);
+ if (result < 0)
+ return result;
+ this->callback_->handle_destroy ();
+ return 0;
+}
+
+int
+TAO_SFP_Object::send_frame (ACE_Message_Block *frame,
+ TAO_AV_frame_info *frame_info)
+{
+ TAO_OutputCDR out_stream;
+ CORBA::Boolean result = 0;
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"TAO_SFP_Object::send_frame\n"));
+ CORBA::Octet flags = TAO_ENCAP_BYTE_ORDER;
+ if (this->transport_ == 0)
+ ACE_ERROR_RETURN ((LM_ERROR,"TAO_SFP_Object::send_frame: transport is null\n"),-1);
+ if (this->current_credit_ != 0)
+ {
+ // if we have enough credit then we send.
+ int total_length = 0;
+ for (ACE_Message_Block *temp = frame;temp != 0;temp = temp->cont ())
+ total_length += temp->length ();
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"total_length of frame=%d\n",total_length));
+ if (ACE_static_cast (u_int, total_length) < (TAO_SFP_MAX_PACKET_SIZE -TAO_SFP_Base::frame_header_len))
{
- ACE_NEW_RETURN (fragment_entry,
- TAO_SFP_Fragment_Table_Entry,
- 0);
- fragment_entry->fragment_set_.insert (*new_node);
- // bind a new entry for this sequence number.
- result = this->fragment_table_.bind (fragment.sequence_num,fragment_entry);
- if (result != 0)
- ACE_ERROR_RETURN ((LM_ERROR,"bind for %dth fragment failed\n",
- fragment.frag_number),0);
+ if (frame_info != 0)
+ {
+ if (frame_info->boundary_marker)
+ flags |= 4;
+ CORBA::Boolean result = TAO_SFP_Base::start_frame (flags,
+ flowProtocol::Frame_Msg,
+ out_stream);
+ if (result == 0)
+ return 0;
+ flowProtocol::my_seq_ulong source_ids;
+ source_ids.length (1);
+ source_ids [0] = 0;
+ TAO_SFP_Base::write_frame_message (frame_info->timestamp,
+ frame_info->ssrc,
+ source_ids,
+ this->sequence_num_,
+ out_stream);
+ }
+ else
+ {
+ CORBA::Boolean result = TAO_SFP_Base::start_frame (flags,
+ flowProtocol::SimpleFrame_Msg,
+ out_stream);
+ if (result == 0)
+ return 0;
+ }
+ TAO_SFP_Base::send_message (this->transport_,
+ out_stream,
+ frame);
}
- if (!(fragment.flags & 0x2))
+ else // larger frame,fragment and send it.
{
- ACE_DEBUG ((LM_DEBUG,"Last fragment received\n"));
- // if bit 1 is not set then there are
- // no more fragments.
- fragment_entry->last_received_ = 1;
- // since fragment number starts from 0 to n-1 we add 1.
- fragment_entry->num_fragments_ = fragment.frag_number + 1;
+ flags = flags | 2;
+ if (frame_info != 0)
+ {
+ if (frame_info->boundary_marker)
+ flags |= 4;
+ result = TAO_SFP_Base::start_frame (flags,
+ flowProtocol::Frame_Msg,
+ out_stream);
+ if (result == 0)
+ return result;
+ flowProtocol::my_seq_ulong source_ids;
+ source_ids.length (1);
+ source_ids [0] = 0;
+ TAO_SFP_Base::write_frame_message (frame_info->timestamp,
+ frame_info->ssrc,
+ source_ids,
+ this->sequence_num_,
+ out_stream);
+ }
+ else
+ {
+ CORBA::Boolean result = TAO_SFP_Base::start_frame (flags,
+ flowProtocol::SimpleFrame_Msg,
+ out_stream);
+ if (result == 0)
+ return 0;
+ }
+ size_t last_len,current_len;
+ int message_len = out_stream.total_length ();
+ ACE_Message_Block *mb = frame;
+ ACE_Message_Block *fragment_mb =
+ this->get_fragment (mb,
+ message_len,
+ last_len,
+ current_len);
+ // This can be either a simpleframe or a sequenced frame,other types of frames.
+ TAO_SFP_Base::send_message (this->transport_,
+ out_stream,
+ fragment_mb);
+ out_stream.reset ();
+ int frag_number = 1;
+ mb->length (last_len);
+ mb->rd_ptr (current_len);
+ // If there is any more data send those as fragments.
+ while (mb != 0)
+ {
+ message_len = TAO_SFP_Base::fragment_len;
+ fragment_mb = this->get_fragment (mb,
+ message_len,
+ last_len,
+ current_len);
+ if (mb == 0)
+ {
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"sending the last fragment\n"));
+ // This is the last fragment so clear the fragments bit.
+ flags = TAO_ENCAP_BYTE_ORDER;
+ }
+ if (fragment_mb == 0)
+ break;
+ if (frame_info != 0)
+ {
+ TAO_SFP_Base::write_fragment_message (flags,
+ frag_number++,
+ this->sequence_num_,
+ frame_info->ssrc,
+ out_stream);
+ }
+ else
+ {
+ TAO_SFP_Base::write_fragment_message (flags,
+ frag_number++,
+ this->sequence_num_,
+ 0,
+ out_stream);
+ }
+ // send the fragment now.
+ // without the sleep the fragments gets lost!
+ // probably because the UDP buffer queue on the sender side
+ // is overflown it drops the packets.
+ // XXX: This is a hack.
+ ACE_OS::sleep (1);
+ result = TAO_SFP_Base::send_message (this->transport_,
+ out_stream,
+ fragment_mb);
+ if (mb != 0)
+ {
+ mb->length (last_len);
+ mb->rd_ptr (current_len);
+ }
+ }
+ // Increment the sequence_num after sending the message.
+ this->sequence_num_++;
+ // Also reduce the number of credits.
+ if (this->max_credit_ > 0)
+ this->current_credit_--;
}
-
}
- ACE_CATCHANY
+ else
{
- ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"TAO_SFP::read_fragment");
- return 0;
+ // flow controlled so wait.
+ // A greater than 0 value indicates that flow control is being exercised.
+ return 1;
}
- ACE_ENDTRY;
- ACE_CHECK_RETURN (0);
- return check_all_fragments (fragment_entry);
+ return 0;
+}
+
+int
+TAO_SFP_Object::send_frame (const iovec *iov,
+ int iovcnt,
+ TAO_AV_frame_info *frame_info)
+{
+ ACE_ERROR_RETURN ((LM_ERROR,"TAO_AV_SFP_Object::send_frame"),-1);
}
ACE_Message_Block*
-TAO_SFP::check_all_fragments (TAO_SFP_Fragment_Table_Entry *fragment_entry)
+TAO_SFP_Object::get_fragment (ACE_Message_Block *&mb,
+ size_t initial_len,
+ size_t &last_mb_orig_len,
+ size_t &last_mb_current_len)
{
- ACE_DEBUG ((LM_DEBUG,"table size: %d, num_fragments: %d\n",fragment_entry->fragment_set_.size (),fragment_entry->num_fragments_));
- // check to see if all the frames have been received.
- if (fragment_entry->fragment_set_.size () == fragment_entry->num_fragments_)
+ ACE_Message_Block *fragment_mb = 0,*temp_mb = 0;
+ int prev_len,last_len = 0;
+ size_t current_len = 0;
+ size_t message_len = initial_len;
+ while (mb != 0)
{
- ACE_DEBUG ((LM_DEBUG,"all fragments have been received\n"));
- // all the fragments have been received
- // we can now chain the ACE_Message_Blocks in the fragment_set_ and then return them
- // back.
- ACE_Message_Block *frame = 0,*head = 0;
- FRAGMENT_SET_ITERATOR frag_iterator (fragment_entry->fragment_set_);
- TAO_SFP_Fragment_Node *node;
- for (;frag_iterator.next (node) != 0;frag_iterator.advance ())
+ prev_len = message_len;
+ message_len += mb->length ();
+ if (fragment_mb == 0)
+ fragment_mb = temp_mb = mb->duplicate ();
+ if (message_len > TAO_SFP_MAX_PACKET_SIZE)
{
-// ACE_Message_Block *block = node->data_;
-// char *buf =block->rd_ptr ();
-// ACE_DEBUG ((LM_DEBUG,"length of buf = %d\n",block->length ()));
-// for (int i=0;i<block->length ();i++)
-// ACE_DEBUG ((LM_DEBUG,"%c ",buf[i]));
-// ACE_DEBUG ((LM_DEBUG,"\n"));
-
- if (!head)
+ // get only the length that we can accomodate.
+ current_len = TAO_SFP_MAX_PACKET_SIZE - prev_len;
+ if (current_len < mb->length ())
{
- frame = node->data_;
- head = frame;
+ // The above condition is an assertion.
+ message_len += (current_len-mb->length ());
+ last_len = mb->length ();
+ mb->length (current_len);
+ temp_mb->length (current_len);
}
- else
+ break;
+ }
+ else
+ {
+ // we can accomodate this message block
+ message_len += mb->length ();
+ mb = mb->cont ();
+ temp_mb = temp_mb->cont ();
+ }
+ }
+ last_mb_orig_len = last_len;
+ last_mb_current_len = current_len;
+ return fragment_mb;
+}
+
+int
+TAO_SFP_Object::set_policies (const TAO_AV_PolicyList& policies)
+{
+ TAO_AV_Policy *policy = 0;
+ for (u_int i=0;i<policies.length ();i++)
+ {
+ policy = policies[i];
+ switch (policies[i]->type ())
+ {
+
+ case TAO_AV_SFP_CREDIT_POLICY:
+ {
+ TAO_AV_SFP_Credit_Policy *credit_policy =
+ ACE_reinterpret_cast (TAO_AV_SFP_Credit_Policy*,policy);
+ this->max_credit_ = credit_policy->value ();
+ }
+ default:
+ break;
+ }
+ }
+ return 0;
+}
+
+// TAO_SFP_Consumer_Object
+TAO_SFP_Consumer_Object::TAO_SFP_Consumer_Object (TAO_AV_Callback *callback,
+ TAO_AV_Transport *transport,
+ char *&sfp_options)
+ :TAO_SFP_Object (callback,transport)
+{
+ TAO_AV_PolicyList policies = callback->get_policies ();
+ if (policies.length () == 0)
+ return;
+ this->set_policies (policies);
+ if (this->max_credit_ > 0)
+ {
+ ACE_NEW (sfp_options,
+ char [BUFSIZ]);
+
+ ACE_OS::sprintf (sfp_options,
+ "sfp:1.0:credit=%d",
+ max_credit_);
+ }
+}
+
+int
+TAO_SFP_Consumer_Object::handle_input (void)
+{
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"TAO_SFP_Consumer_Object::handle_input\n"));
+ // This is the entry point for receiving data.
+ TAO_AV_frame_info *frame_info = 0;
+ int result = TAO_SFP_Base::handle_input (this->transport_,
+ this->state_,
+ frame_info);
+ if (result < 0)
+ ACE_ERROR_RETURN ((LM_ERROR,"ERROR in TAO_SFP_Consumer_Object::handle_input"),result);
+ if (this->state_.frame_header_.message_type == flowProtocol::EndofStream_Msg)
+ this->callback_->handle_destroy ();
+ if (this->state_.is_complete ())
+ {
+ this->callback_->receive_frame (this->state_.frame_block_,
+ frame_info);
+ // Now release the memory for the frame.
+ if (this->state_.frame_block_ != &this->state_.static_frame_)
+ {
+ ACE_Message_Block *temp = 0;
+ for (temp = this->state_.frame_block_;
+ temp != 0;
+ temp = temp->cont ())
{
- frame->cont (node->data_);
- frame = node->data_;
+ temp->release ();
+ delete temp;
}
}
- return head;
+ this->state_.reset ();
}
return 0;
}
-void
-TAO_SFP::dump_buf(char *buffer,int size)
+TAO_SFP_Producer_Object::TAO_SFP_Producer_Object (TAO_AV_Callback *callback,
+ TAO_AV_Transport *transport,
+ char *&sfp_options)
+ :TAO_SFP_Object (callback,transport),
+ credit_sequence_num_ (0)
+
+{
+ TAO_Tokenizer flow_string (sfp_options,':');
+ if (flow_string [2] != 0)
+ {
+ TAO_Tokenizer options (flow_string[2],'=');
+ if (options [1] != 0)
+ this->max_credit_ = ACE_OS::atoi (options[1]);
+ }
+}
+
+int
+TAO_SFP_Producer_Object::handle_input (void)
+{
+ // A producer can only receive credit messages.
+ int result;
+ flowProtocol::MsgType msg_type = flowProtocol::Start_Msg;
+ result = TAO_SFP_Base::peek_message_type (this->transport_,
+ msg_type);
+ if (result < 0)
+ return result;
+ switch (msg_type)
+ {
+ case flowProtocol::Credit_Msg:
+ {
+ flowProtocol::credit credit;
+ result = TAO_SFP_Base::read_credit_message (this->transport_,
+ credit,
+ this->state_.cdr);
+ if (result < 0)
+ return result;
+ if (!this->credit_sequence_num_)
+ this->credit_sequence_num_ = credit.cred_num;
+ else
+ {
+ // check that the sequence number is above the last sequence number
+ // else its a duplicate credit message so we can ignore it.
+ if (credit.cred_num <= this->credit_sequence_num_)
+ return 0;
+ else // Update our credit now.
+ this->current_credit_ = this->max_credit_;
+ }
+ }
+ break;
+ default:
+ {
+ ACE_Message_Block mb (2*this->transport_->mtu ());
+
+ // Ignore the rest of the message by just reading.
+ this->transport_->recv (mb.rd_ptr (),
+ mb.size ());
+ break;
+ }
+ }
+ return 0;
+}
+
+// TAO_AV_SFP_Factory
+TAO_AV_SFP_Factory::TAO_AV_SFP_Factory (void)
+{
+}
+
+TAO_AV_SFP_Factory::~TAO_AV_SFP_Factory (void)
{
- char *buf = buffer;
- ACE_DEBUG ((LM_DEBUG,"========================================n"));
- for (int i=0;i<size;i++)
- ACE_DEBUG ((LM_DEBUG,"%d ",buf[i]));
- ACE_DEBUG ((LM_DEBUG,"n========================================n"));
+}
+
+// Initialization hook from service configurator.
+int
+TAO_AV_SFP_Factory::init (int argc, char *argv[])
+{
+ return 0;
+}
+
+int
+TAO_AV_SFP_Factory::match_protocol (const char *flow_string)
+{
+ if (ACE_OS::strncasecmp (flow_string,"sfp",3) == 0)
+ return 1;
+ return 0;
+}
+
+TAO_AV_Protocol_Object*
+TAO_AV_SFP_Factory::make_protocol_object (TAO_FlowSpec_Entry *entry,
+ TAO_Base_StreamEndPoint *endpoint,
+ TAO_AV_Flow_Handler *handler,
+ TAO_AV_Transport *transport)
+{
+ TAO_AV_Protocol_Object *object = 0;
+ TAO_AV_Callback *callback = 0;
+ endpoint->get_callback (entry->flowname (),
+ callback);
+ char *flow_string = entry->flow_protocol_str ();
+ switch (entry->role ())
+ {
+ case TAO_FlowSpec_Entry::TAO_AV_PRODUCER:
+ {
+ ACE_NEW_RETURN (object,
+ TAO_SFP_Producer_Object (callback,
+ transport,
+ flow_string),
+ 0);
+ }
+ break;
+ case TAO_FlowSpec_Entry::TAO_AV_CONSUMER:
+ {
+ ACE_NEW_RETURN (object,
+ TAO_SFP_Consumer_Object (callback,
+ transport,
+ flow_string),
+ 0);
+ }
+ break;
+ case TAO_FlowSpec_Entry::TAO_AV_INVALID_ROLE:
+ return 0;
+ }
+ callback->open (object,
+ handler);
+ endpoint->set_protocol_object (entry->flowname (),
+ object);
+ return object;
+}
+
+//------------------------------------------------------------
+// TAO_SFP_Frame_State
+//------------------------------------------------------------
+
+TAO_SFP_Frame_State::TAO_SFP_Frame_State (void)
+ :cdr (new ACE_Data_Block (ACE_CDR::DEFAULT_BUFSIZE,
+ ACE_Message_Block::MB_DATA,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0),
+ TAO_ENCAP_BYTE_ORDER),
+ more_fragments_ (0),
+ frame_block_ (0)
+{
+}
+
+CORBA::Boolean
+TAO_SFP_Frame_State::is_complete (void)
+{
+ return (!this->more_fragments_) && (this->frame_block_);
+}
+
+int
+TAO_SFP_Frame_State::reset (void)
+{
+ this->frame_block_ = 0;
+ return 0;
}
#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
@@ -1134,6 +1479,7 @@ template class ACE_DNode<TAO_SFP_Fragment_Node>;
template class ACE_Equal_To<CORBA::ULong>;
template class ACE_Ordered_MultiSet<TAO_SFP_Fragment_Node>;
template class ACE_Ordered_MultiSet_Iterator<TAO_SFP_Fragment_Node>;
+
template class ACE_Hash_Map_Manager<CORBA::ULong,TAO_SFP_Fragment_Table_Entry*,ACE_Null_Mutex>;
template class ACE_Hash_Map_Manager_Ex<CORBA::ULong, TAO_SFP_Fragment_Table_Entry *, ACE_Hash<CORBA::ULong>, ACE_Equal_To<CORBA::ULong>, ACE_Null_Mutex>;
template class ACE_Hash_Map_Entry<CORBA::ULong, TAO_SFP_Fragment_Table_Entry *>;
@@ -1142,6 +1488,17 @@ template class ACE_Hash_Map_Reverse_Iterator_Ex<CORBA::ULong,TAO_SFP_Fragment_Ta
template class ACE_Hash_Map_Iterator_Ex<CORBA::ULong,TAO_SFP_Fragment_Table_Entry*,ACE_Hash<CORBA::ULong>,ACE_Equal_To<CORBA::ULong>,ACE_Null_Mutex>;
template class ACE_Hash_Map_Iterator<CORBA::ULong,TAO_SFP_Fragment_Table_Entry *,ACE_Null_Mutex>;
template class ACE_Hash_Map_Reverse_Iterator<CORBA::ULong,TAO_SFP_Fragment_Table_Entry *,ACE_Null_Mutex>;
+
+template class ACE_Hash_Map_Manager<CORBA::ULong,ACE_Hash_Map_Manager<CORBA::ULong,TAO_SFP_Fragment_Table_Entry*,ACE_Null_Mutex>*,ACE_Null_Mutex>;
+template class ACE_Hash_Map_Manager_Ex<CORBA::ULong, ACE_Hash_Map_Manager<CORBA::ULong,TAO_SFP_Fragment_Table_Entry*,ACE_Null_Mutex> *, ACE_Hash<CORBA::ULong>, ACE_Equal_To<CORBA::ULong>, ACE_Null_Mutex>;
+template class ACE_Hash_Map_Entry<CORBA::ULong, ACE_Hash_Map_Manager<CORBA::ULong,TAO_SFP_Fragment_Table_Entry*,ACE_Null_Mutex> *>;
+template class ACE_Hash_Map_Iterator_Base_Ex<CORBA::ULong, ACE_Hash_Map_Manager<CORBA::ULong,TAO_SFP_Fragment_Table_Entry*,ACE_Null_Mutex> *, ACE_Hash<CORBA::ULong>, ACE_Equal_To<CORBA::ULong>, ACE_Null_Mutex>;
+template class ACE_Hash_Map_Reverse_Iterator_Ex<CORBA::ULong,ACE_Hash_Map_Manager<CORBA::ULong,TAO_SFP_Fragment_Table_Entry*,ACE_Null_Mutex>*,ACE_Hash<CORBA::ULong>,ACE_Equal_To<CORBA::ULong>,ACE_Null_Mutex>;
+template class ACE_Hash_Map_Iterator_Ex<CORBA::ULong,ACE_Hash_Map_Manager<CORBA::ULong,TAO_SFP_Fragment_Table_Entry*,ACE_Null_Mutex>*,ACE_Hash<CORBA::ULong>,ACE_Equal_To<CORBA::ULong>,ACE_Null_Mutex>;
+template class ACE_Hash_Map_Iterator<CORBA::ULong,ACE_Hash_Map_Manager<CORBA::ULong,TAO_SFP_Fragment_Table_Entry*,ACE_Null_Mutex> *,ACE_Null_Mutex>;
+template class ACE_Hash_Map_Reverse_Iterator<CORBA::ULong,ACE_Hash_Map_Manager<CORBA::ULong,TAO_SFP_Fragment_Table_Entry*,ACE_Null_Mutex> *,ACE_Null_Mutex>;
+
+template class ACE_Singleton<TAO_SFP_Base, ACE_SYNCH_MUTEX>;
#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
#pragma instantiate ACE_DNode<TAO_SFP_Fragment_Node>
@@ -1156,4 +1513,24 @@ template class ACE_Hash_Map_Reverse_Iterator<CORBA::ULong,TAO_SFP_Fragment_Table
#pragma instantiate ACE_Equal_To<CORBA::ULong>
#pragma instantiate ACE_Hash_Map_Iterator<CORBA::ULong,TAO_SFP_Fragment_Table_Entry *,ACE_Null_Mutex>
#pragma instantiate ACE_Hash_Map_Reverse_Iterator<CORBA::ULong,TAO_SFP_Fragment_Table_Entry *,ACE_Null_Mutex>
+
+#pragma instantiate ACE_Hash_Map_Manager<CORBA::ULong,ACE_Hash_Map_Manager<CORBA::ULong,TAO_SFP_Fragment_Table_Entry*,ACE_Null_Mutex>*,ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Manager_Ex<CORBA::ULong, ACE_Hash_Map_Manager<CORBA::ULong,TAO_SFP_Fragment_Table_Entry*,ACE_Null_Mutex> *, ACE_Hash<CORBA::ULong>, ACE_Equal_To<CORBA::ULong>, ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Entry<CORBA::ULong, ACE_Hash_Map_Manager<CORBA::ULong,TAO_SFP_Fragment_Table_Entry*,ACE_Null_Mutex> *>
+#pragma instantiate ACE_Hash_Map_Iterator_Base_Ex<CORBA::ULong, ACE_Hash_Map_Manager<CORBA::ULong,TAO_SFP_Fragment_Table_Entry*,ACE_Null_Mutex> *, ACE_Hash<CORBA::ULong>, ACE_Equal_To<CORBA::ULong>, ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Reverse_Iterator_Ex<CORBA::ULong,ACE_Hash_Map_Manager<CORBA::ULong,TAO_SFP_Fragment_Table_Entry*,ACE_Null_Mutex>*,ACE_Hash<CORBA::ULong>,ACE_Equal_To<CORBA::ULong>,ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Iterator_Ex<CORBA::ULong,ACE_Hash_Map_Manager<CORBA::ULong,TAO_SFP_Fragment_Table_Entry*,ACE_Null_Mutex>*,ACE_Hash<CORBA::ULong>,ACE_Equal_To<CORBA::ULong>,ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Iterator<CORBA::ULong,ACE_Hash_Map_Manager<CORBA::ULong,TAO_SFP_Fragment_Table_Entry*,ACE_Null_Mutex> *,ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Reverse_Iterator<CORBA::ULong,ACE_Hash_Map_Manager<CORBA::ULong,TAO_SFP_Fragment_Table_Entry*,ACE_Null_Mutex> *,ACE_Null_Mutex>
+
+#pragma instantiate ACE_Singleton<TAO_SFP_Base, ACE_SYNCH_MUTEX>
#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */
+
+ACE_FACTORY_DEFINE (AV, TAO_AV_SFP_Factory)
+ACE_STATIC_SVC_DEFINE (TAO_AV_SFP_Factory,
+ ASYS_TEXT ("SFP_Factory"),
+ ACE_SVC_OBJ_T,
+ &ACE_SVC_NAME (TAO_AV_SFP_Factory),
+ ACE_Service_Type::DELETE_THIS |
+ ACE_Service_Type::DELETE_OBJ,
+ 0)
diff --git a/TAO/orbsvcs/orbsvcs/AV/sfp.h b/TAO/orbsvcs/orbsvcs/AV/sfp.h
index a399ab4ec58..f0151189c0a 100644
--- a/TAO/orbsvcs/orbsvcs/AV/sfp.h
+++ b/TAO/orbsvcs/orbsvcs/AV/sfp.h
@@ -4,13 +4,13 @@
// ============================================================================
//
// = LIBRARY
-// AVStreams.
+// ORBSVCS AVStreams.
//
// = FILENAME
// sfp.h
//
// = AUTHOR
-// Nagarajan Surendran <naga@cs.wustl.edu>
+// Nagarajan Surendran <naga@cs.wustl.edu>
//
// ============================================================================
@@ -22,41 +22,17 @@
#include "ace/SOCK_Dgram.h"
#include "ace/INET_Addr.h"
-#define MAGIC_NUMBER_LEN 5
-#define MESSAGE_TYPE_OFFSET 5
-#define TAO_WRITEV_MAX 128
+#include "Policy.h"
+#include "MCast.h"
+#include "AVStreams_i.h"
+#include "UDP.h"
+#define TAO_SFP_MAGIC_NUMBER_LEN 4
+#define TAO_SFP_MESSAGE_TYPE_OFFSET 5
+#define TAO_SFP_WRITEV_MAX 128
-#define SFP_MAX_PACKET_SIZE ACE_MAX_DGRAM_SIZE
-//#define SFP_MAX_PACKET_SIZE 100
-
-
-// various message class for SFP.
-
-class TAO_ORBSVCS_Export SFP_Callback
- // =TITLE
- // Callback interface for SFP.
- //
- // =Description
- // Application should create a callback object which they
- // register with the SFP. The SFP implementation notifies the
- // applicationn of any changes in the stream status like stream
- // established, stream ended.
-{
-public:
- virtual int start_failed (void) = 0;
- // This is called for both active and passive start.
-
- virtual int stream_established (void) = 0;
- // This is a callback for both active and passive stream
- // establshment.
-
- virtual int receive_frame (ACE_Message_Block *frame) =0;
- // upcall to the application to receive a frame.
-
- virtual void end_stream (void) = 0;
- // called when the EndofStream message is received.
-};
+#define TAO_SFP_MAX_PACKET_SIZE ACE_MAX_DGRAM_SIZE
+//#define TAO_SFP_MAX_PACKET_SIZE 132
class TAO_SFP_Fragment_Node
{
@@ -79,19 +55,38 @@ public:
{}
int last_received_;
size_t num_fragments_;
+ TAO_AV_frame_info frame_info;
ACE_Ordered_MultiSet<TAO_SFP_Fragment_Node> fragment_set_;
};
typedef ACE_Ordered_MultiSet_Iterator<TAO_SFP_Fragment_Node> FRAGMENT_SET_ITERATOR;
+typedef ACE_Hash_Map_Manager<CORBA::ULong,TAO_SFP_Fragment_Table_Entry*,ACE_Null_Mutex> TAO_SFP_Fragment_Table;
+typedef ACE_Hash_Map_Manager<CORBA::ULong,TAO_SFP_Fragment_Table*,ACE_Null_Mutex> TAO_SFP_Fragment_Table_Map;
+
+class TAO_ORBSVCS_Export TAO_SFP_Frame_State
+{
+public:
+ TAO_SFP_Frame_State (void);
+ CORBA::Boolean is_complete (void);
+
+ int reset (void);
+
+ TAO_InputCDR cdr;
+ // This is the InputCDR that will be used to decode the message.
+ flowProtocol::frameHeader frame_header_;
+ flowProtocol::fragment fragment_;
+ flowProtocol::frame frame_;
+ CORBA::Boolean more_fragments_;
+ ACE_Message_Block *frame_block_;
+ // boolean flags indicating that there are more fragments.
+ ACE_Message_Block static_frame_;
+ TAO_SFP_Fragment_Table_Map fragment_table_map_;
+};
-class TAO_ORBSVCS_Export TAO_SFP :public virtual ACE_Event_Handler
- // = TITLE
- // SFP implementation on UDP.
- //
- // = Description
- // This implements the methods to send and receive data octet
- // streams using the Simple Flow Protocol.
+class TAO_AV_Transport;
+class TAO_AV_Core;
+class TAO_ORBSVCS_Export TAO_SFP_Base
{
public:
// default arguments to pass to use for the ORB
@@ -108,8 +103,16 @@ public:
static const unsigned char TAO_SFP_MAJOR_VERSION;
static const unsigned char TAO_SFP_MINOR_VERSION;
-// lengths of various SFP headers
+ // lengths of various SFP headers
static const unsigned char TAO_SFP_FRAME_HEADER_LEN;
+ static const unsigned char TAO_SFP_MESSAGE_SIZE_OFFSET;
+ static const unsigned char TAO_SFP_FRAGMENT_SIZE_OFFSET;
+ static u_int frame_header_len;
+ static u_int start_reply_len;
+ static u_int start_len;
+ static u_int credit_len;
+ static u_int fragment_len;
+
enum State
{
ACTIVE_START,
@@ -120,143 +123,145 @@ public:
START_RECEIVED
};
- TAO_SFP (CORBA::ORB_ptr orb,
- ACE_Reactor* reactor,
- ACE_Time_Value timeout1,
- ACE_Time_Value timeout2,
- SFP_Callback *callback);
- // constructor.
-
- virtual int start_stream (const char *receiver_addr);
- // Actively start the stream by trying to connect to the UDP
- // receiver_addr in host:port format.
-
- virtual int start_stream (const char *local_addr,int credit_);
- // Passive start.
-
- virtual int send_frame (ACE_Message_Block *frame);
- // sends a single frame over UDP.
-
- virtual int end_stream (void);
- // terminates the stream.
-
- virtual int handle_input (ACE_HANDLE fd);
- // Callback when event happens on the dgram socket.
-
- virtual int handle_timeout (const ACE_Time_Value&, const void*);
- // Used for timeout for the number of tries for starting a stream.
-
- virtual ACE_HANDLE get_handle (void) const;
-private:
-
- ACE_Message_Block* read_simple_frame (void);
- // receives a single frame from the network.
-
- int read_frame_header (flowProtocol::frameHeader &frame_header);
- // reads the frame header from the peek buffer in the datagram.
-
- ACE_Message_Block* read_fragment (void);
- // reads a fragment from the wire.
-
- void create_local_dgram (void);
- // Create the local dgram endpoint.
-
- int connect_to_receiver (const char *receiver_addr);
- // Creates a connected dgram with the receiver addr.
-
- int send_start (void);
- // sends the start message to the receiver.
-
- int send_startReply (void);
- // sends the StartReply message to the receiver.
-
- int send_cdr_buffer (TAO_OutputCDR &cdr,
- ACE_Message_Block *mb);
- // sends the cdr buffer using iovecs.
-
- int register_dgram_handler (void);
- // registers the dgram socket with the reactor.
-
- ACE_Message_Block *check_all_fragments (TAO_SFP_Fragment_Table_Entry *fragment_entry);
- // checks if all the fragments for this entry has been received and returns the
- // head of the chain of message blocks for that frame.
-
- void dump_buf (char *buf,int n);
+ TAO_SFP_Base (void);
+ static CORBA::Boolean start_frame (CORBA::Octet flags,
+ flowProtocol::MsgType type,
+ TAO_OutputCDR &msg);
+
+ static CORBA::Boolean write_start_message (TAO_OutputCDR &msg);
+ static CORBA::Boolean write_start_reply_message (TAO_OutputCDR &msg);
+ static CORBA::Boolean write_credit_message (CORBA::ULong cred_num,
+ TAO_OutputCDR &msg);
+ static CORBA::Boolean write_fragment_message (CORBA::Octet flags,
+ CORBA::ULong fragment_number,
+ CORBA::ULong sequence_number,
+ CORBA::ULong source_id,
+ TAO_OutputCDR &msg);
+
+ static CORBA::Boolean write_frame_message (CORBA::ULong timestamp,
+ CORBA::ULong synchSource,
+ flowProtocol::my_seq_ulong source_ids,
+ CORBA::ULong sequence_num,
+ TAO_OutputCDR &msg);
+
+ static int send_message (TAO_AV_Transport *transport,
+ TAO_OutputCDR &stream,
+ ACE_Message_Block *mb = 0);
+ static int peek_message_type (TAO_AV_Transport *transport,
+ flowProtocol::MsgType &type);
+ static int read_start_message (TAO_AV_Transport *transport,
+ flowProtocol::Start &start,
+ TAO_InputCDR &cdr);
+ static int read_start_reply_message (TAO_AV_Transport *transport,
+ flowProtocol::StartReply &start_reply,
+ TAO_InputCDR &cdr);
+ static int read_credit_message (TAO_AV_Transport *transport,
+ flowProtocol::credit &credit,
+ TAO_InputCDR &cdr);
+ static int read_endofstream_message (TAO_AV_Transport *transport,
+ flowProtocol::frameHeader &endofstream,
+ TAO_InputCDR &cdr);
+
+ static int read_frame (TAO_AV_Transport *transport,
+ flowProtocol::frameHeader &frame_header,
+ TAO_SFP_Frame_State &state,
+ TAO_AV_frame_info *&frame_info);
+
+ static int read_fragment (TAO_AV_Transport *transport,
+ flowProtocol::fragment &fragment,
+ TAO_SFP_Frame_State &state,
+ TAO_AV_frame_info *&frame_info);
+
+ static int peek_frame_header (TAO_AV_Transport *transport,
+ flowProtocol::frameHeader &header,
+ TAO_InputCDR &cdr);
+
+ static int peek_fragment_header (TAO_AV_Transport *transport,
+ flowProtocol::fragment &fragment,
+ TAO_InputCDR &cdr);
+
+ static int handle_input (TAO_AV_Transport *transport,
+ TAO_SFP_Frame_State &state,
+ TAO_AV_frame_info *&frame_info);
+
+ static ACE_Message_Block* check_all_fragments (TAO_SFP_Fragment_Table_Entry *fragment_entry);
+
+protected:
+ static void dump_buf (char *buf,int n);
// dumps the buffer to the screen.
+};
- CORBA::ORB_ptr orb_;
- // ORB reference.
-
- ACE_Reactor* reactor_;
- // Used for registering the dgram handler.
-
- TAO_OutputCDR output_cdr_;
- // Use the TAO CDR decoder to decode everything
-
- // TAO_InputCDR input_cdr_;
- // Use the TAO CDR encoder to encode everything
-
- ACE_SOCK_Dgram dgram_;
- // Connection Oriented Dgram.
-
- int start_tries_;
- // Number of tries to send a Start message.
-
- int startReply_tries_;
- // Number of tries to send a StartReply message.
-
- ACE_Time_Value timeout1_;
- // Timeout used for Start on Sender side and also for Credit on
- // receiver side.
-
- ACE_Time_Value timeout2_;
- // Timeout used for StartReply on the receiver side and also for
- // CREDIT on the sender side.
-
- State state_;
- // State variable.
-
- const char *receiver_addr_;
- // The address of the receiver to which we're connected to.
-
- ACE_INET_Addr receiver_inet_addr_;
- // INET addr of the receiver.
+// Beware the SFP_Base code relies on the Singleton being initialized.
+typedef ACE_Singleton <TAO_SFP_Base,ACE_SYNCH_MUTEX> TAO_SFP_BASE;
- SFP_Callback *callback_;
- // Application Callback Object.
+class TAO_ORBSVCS_Export TAO_SFP_Object : public TAO_AV_Protocol_Object
+{
+public:
+ TAO_SFP_Object (TAO_AV_Callback *callback,
+ TAO_AV_Transport *transport);
+ // We should add a sfp options parameter.
+
+ virtual ~TAO_SFP_Object (void);
+ // Dtor
+
+ virtual int handle_input (void) = 0;
+ virtual int send_frame (ACE_Message_Block *frame,
+ TAO_AV_frame_info *frame_info = 0);
+
+ virtual int send_frame (const iovec *iov,
+ int iovcnt,
+ TAO_AV_frame_info *frame_info = 0);
+
+ virtual int destroy (void);
+ virtual int set_policies (const TAO_AV_PolicyList &policies);
+
+protected:
+ ACE_Message_Block *get_fragment (ACE_Message_Block *&frame,
+ size_t initial_len,
+ size_t &last_mb_orig_len,
+ size_t &last_mb_current_len);
+ CORBA::ULong sequence_num_;
+ CORBA::ULong source_id_;
+ CORBA::Long max_credit_;
+ CORBA::Long current_credit_;
+ TAO_SFP_Frame_State state_;
+};
- int sequence_num_;
- // sequence number of the packet.
+class TAO_ORBSVCS_Export TAO_SFP_Producer_Object : public TAO_SFP_Object
+{
+public:
+ TAO_SFP_Producer_Object (TAO_AV_Callback *callback,
+ TAO_AV_Transport *transport,
+ char *&flow_options);
+ virtual int handle_input (void);
+protected:
+ CORBA::ULong credit_sequence_num_;
+};
- flowProtocol::frameHeader frame_header_;
- ssize_t frame_header_len_;
- // frame header to be sent with all frames.
- // length of the frame header.
+class TAO_ORBSVCS_Export TAO_SFP_Consumer_Object : public TAO_SFP_Object
+{
+public:
+ TAO_SFP_Consumer_Object (TAO_AV_Callback *callback,
+ TAO_AV_Transport *transport,
+ char *&flow_options);
+ virtual int handle_input (void);
+};
- flowProtocol::fragment fragment_;
- ssize_t fragment_len_;
- // fragment header for each fragment.
-
- flowProtocol::Start start_;
- ssize_t start_len_;
- // Start message and its length.
-
- flowProtocol::StartReply start_reply_;
- ssize_t start_reply_len_;
- // StartReply message and its length.
-
- flowProtocol::credit credit_;
- ssize_t credit_len_;
- CORBA::ULong credit_num_;
- // Credit message and its length.
-
- char magic_number_[MAGIC_NUMBER_LEN];
- // used for peeking the magic_number.
- const size_t magic_number_len_;
- u_int more_fragments_;
- // boolean flags indicating that there are more fragments.
- ACE_Hash_Map_Manager<CORBA::ULong,TAO_SFP_Fragment_Table_Entry*,ACE_Null_Mutex> fragment_table_;
- // chain of fragments of the current frame.
+class TAO_ORBSVCS_Export TAO_AV_SFP_Factory : public TAO_AV_Flow_Protocol_Factory
+{
+public:
+ TAO_AV_SFP_Factory (void);
+ virtual ~TAO_AV_SFP_Factory (void);
+ virtual int init (int argc, char *argv[]);
+ // Initialization hook.
+ virtual int match_protocol (const char *flow_string);
+ virtual TAO_AV_Protocol_Object* make_protocol_object (TAO_FlowSpec_Entry *entry,
+ TAO_Base_StreamEndPoint *endpoint,
+ TAO_AV_Flow_Handler *handler,
+ TAO_AV_Transport *transport);
};
-#endif /* !defined (TAO_SFP_H) */
+ACE_STATIC_SVC_DECLARE (TAO_AV_SFP_Flow_Factory)
+ACE_FACTORY_DECLARE (TAO_ORBSVCS, TAO_AV_SFP_Flow_Factory)
+
+#endif /* TAO_SFP_H */
diff --git a/TAO/orbsvcs/orbsvcs/AV/source.cpp b/TAO/orbsvcs/orbsvcs/AV/source.cpp
new file mode 100644
index 00000000000..522f29bd6aa
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/AV/source.cpp
@@ -0,0 +1,531 @@
+/*
+ * Copyright (c) 1994-1995 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and the Network Research Group at
+ * Lawrence Berkeley Laboratory.
+ * 4. Neither the name of the University nor of the Laboratory may be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+// $Id$
+#include "ace/OS.h"
+#include "RTCP.h"
+#include "source.h"
+
+/* gray out src if no ctrl msgs for this many consecutive update intervals */
+#define CTRL_IDLE 8.
+
+#define SHASH(a) ((int)((((a) >> 20) ^ ((a) >> 10) ^ (a)) & (TAO_AV_SOURCE_HASH-1)))
+
+TAO_AV_Source::TAO_AV_Source (ACE_UINT32 srcid, ACE_UINT32 ssrc, ACE_UINT32 addr)
+ : next_ (0),
+ hlink_ (0),
+ srcid_ (srcid),
+ ssrc_ (ssrc),
+ addr_ (addr),
+ sts_data_ (0),
+ sts_ctrl_ (0),
+ fs_ (0),
+ cs_ (0),
+ np_ (0),
+ nf_ (0),
+ nb_ (0),
+ nm_ (0),
+ snp_ (0),
+ sns_ (0),
+ ndup_ (0),
+ nrunt_ (0),
+ badsesslen_ (0),
+ badsessver_ (0),
+ badsessopt_ (0),
+ badsdes_ (0),
+ badbye_ (0),
+ format_ (-1),
+ mute_ (0),
+ lost_ (0),
+ busy_ (0),
+ ismixer_ (0)
+{
+ lts_data_.tv_sec = 0;
+ lts_data_.tv_usec = 0;
+ lts_ctrl_.tv_sec = 0;
+ lts_ctrl_.tv_usec = 0;
+ lts_done_.tv_sec = 0;
+ lts_done_.tv_usec = 0;
+ /*
+ * Put an invalid seqno in each slot to guarantee that
+ * we don't count any initial dups by mistake.
+ */
+ int i;
+ for (i = 0; i < TAO_AV_SOURCE_NSEQ; ++i)
+ seqno_[i] = i + 1;
+
+ for (i = 0; i <= RTCP_SDES_MAX; ++i)
+ sdes_[i] = 0;
+}
+
+TAO_AV_Source::~TAO_AV_Source ()
+{
+ int i;
+ for (i = 0; i <= RTCP_SDES_MAX; ++i)
+ delete sdes_[i];
+}
+
+void
+TAO_AV_Source::sdes (int t, const char* s)
+{
+ char** p = &sdes_[t];
+ if (*p != 0 && strcmp (*p, s) == 0)
+ /* no change */
+ return;
+
+ delete *p;
+ int n = strlen (s);
+ if (n > 254)
+ n = 254;
+ ACE_NEW (*p,
+ char[n + 1]);
+ strncpy (*p, s, n + 1);
+}
+
+char*
+onestat (char* cp, const char* name, u_long v)
+{
+ sprintf (cp, "%s %lu ", name, v);
+ return (cp + strlen (cp));
+}
+
+char*
+TAO_AV_Source::stats (char* cp) const
+{
+ cp = onestat (cp, "Kilobits", nb () >> (10-3));
+ cp = onestat (cp, "Frames", nf ());
+ cp = onestat (cp, "Packets", np ());
+ int missing = ns () - np ();
+ if (missing < 0)
+ missing = 0;
+ cp = onestat (cp, "Missing", missing);
+ cp = onestat (cp, "Misordered", nm ());
+ cp = onestat (cp, "Runts", runt ());
+ cp = onestat (cp, "Dups", dups ());
+ cp = onestat (cp, "Bad-S-Len", badsesslen ());
+ cp = onestat (cp, "Bad-S-Ver", badsessver ());
+ cp = onestat (cp, "Bad-S-Opt", badsessopt ());
+ cp = onestat (cp, "Bad-Sdes", badsdes ());
+ cp = onestat (cp, "Bad-Bye", badbye ());
+ *--cp = 0;
+ return (cp);
+}
+
+int
+sdes_atoi (const char* s)
+{
+ if (strcasecmp (s, "cname") == 0)
+ return (RTCP_SDES_CNAME);
+ if (strcasecmp (s, "name") == 0)
+ return (RTCP_SDES_NAME);
+ if (strcasecmp (s, "email") == 0)
+ return (RTCP_SDES_EMAIL);
+ if (strcasecmp (s, "phone") == 0)
+ return (RTCP_SDES_PHONE);
+ if (strcasecmp (s, "loc") == 0 || strcasecmp (s, "location") == 0)
+ return (RTCP_SDES_LOC);
+ if (strcasecmp (s, "tool") == 0)
+ return (RTCP_SDES_TOOL);
+ if (strcasecmp (s, "note") == 0)
+ return (RTCP_SDES_NOTE);
+ return (-1);
+}
+
+void
+TAO_AV_Source::set_busy()
+{
+ busy_ = 1;
+}
+
+void
+TAO_AV_Source::clear_counters ()
+{
+ np_ = 0;
+ nf_ = 0;
+ nb_ = 0;
+ nm_ = 0;
+ snp_ = 0;
+ sns_ = 0;
+ ndup_ = 0;
+ nrunt_ = 0;
+
+ lts_data_.tv_sec = 0;
+ lts_data_.tv_usec = 0;
+ lts_ctrl_.tv_sec = 0;
+ lts_ctrl_.tv_usec = 0;
+ lts_done_.tv_sec = 0;
+ lts_done_.tv_usec = 0;
+}
+
+TAO_AV_SourceManager::TAO_AV_SourceManager (TAO_AV_RTCP_Callback *callback)
+ :nsources_ (0),
+ sources_ (0),
+ clock_ (0),
+ keep_sites_ (0),
+ site_drop_time_ (0),
+ localsrc_ (0),
+ callback_ (callback)
+{
+ memset ( (char*)hashtab_, 0, sizeof (hashtab_));
+}
+
+void
+TAO_AV_SourceManager::remove_from_hashtable (TAO_AV_Source* s)
+{
+ /* delete the TAO_AV_Source from hash table */
+ ACE_UINT32 srcid = s->srcid ();
+ int h = SHASH (srcid);
+ TAO_AV_Source** p = &hashtab_[h];
+ while (*p != s)
+ p = & (*p)->hlink_;
+ *p = (*p)->hlink_;
+}
+
+void
+TAO_AV_SourceManager::init (ACE_UINT32 localid, ACE_UINT32 localaddr)
+{
+ /*
+ * create the local object. remove it from the hash
+ * table since collision resolution changes local id
+ * (we special case detection of our own loopbed back packets)
+ */
+ // Make an upcall to get the source.
+ this->callback_->get_rtp_source (localsrc_,
+ localid,
+ localid,
+ localaddr);
+ enter (localsrc_);
+ remove_from_hashtable (localsrc_);
+ /*
+ * hack to prevent local TAO_AV_Source from turning gray at startup.
+ * we don't need to do a similar thing for external TAO_AV_Sources,
+ * because they are only created when a packet arrives.
+ */
+ localsrc_->lts_ctrl (ACE_OS::gettimeofday ());
+}
+
+TAO_AV_Source*
+TAO_AV_SourceManager::enter (TAO_AV_Source* s)
+{
+ s->next_ = sources_;
+ sources_ = s;
+
+ int h = SHASH (s->srcid ());
+ s->hlink_ = hashtab_[h];
+ hashtab_[h] = s;
+
+ ++nsources_;
+
+ return (s);
+}
+
+TAO_AV_Source*
+TAO_AV_SourceManager::consult (ACE_UINT32 srcid)
+{
+ int h = SHASH (srcid);
+ for (TAO_AV_Source* s = hashtab_[h]; s != 0; s = s->hlink_) {
+ /*XXX pulling these values into variable seems
+ to work around a DEC cpp bug */
+ ACE_UINT32 id = s->srcid ();
+ if (id == srcid)
+ return (s);
+ }
+ return (0);
+}
+
+TAO_AV_Source*
+TAO_AV_SourceManager::lookup (ACE_UINT32 srcid, ACE_UINT32 ssrc, ACE_UINT32 addr)
+{
+ TAO_AV_Source* s = consult (srcid);
+ if (s == 0) {
+ if (srcid == ssrc)
+ /*
+ * Heuristic: handle application re-starts
+ * gracefully. We have a new TAO_AV_Source that's
+ * not via a mixer. Try to find an existing
+ * entry from the same host.
+ */
+ s = lookup_duplicate (srcid, addr);
+
+ if (s == 0) {
+ this->callback_->get_rtp_source (s,
+ srcid,
+ ssrc,
+ addr);
+// ACE_NEW_RETURN (s,
+// TAO_AV_Source (srcid, ssrc, addr),
+// 0);
+ enter (s);
+ }
+ }
+ return (s);
+}
+
+/*
+ * Demux data packet to its TAO_AV_Source table entry. (We don't want an extra
+ * SSRC arg here because CSRC's via a mixer don't have their own data
+ * packets.) If we haven't seen this TAO_AV_Source yet, allocate it but
+ * wait until we see two in-order packets accepting the flow.
+ */
+TAO_AV_Source*
+TAO_AV_SourceManager::demux (ACE_UINT32 srcid, ACE_UINT32 addr, ACE_UINT16 seq)
+{
+ TAO_AV_Source* s = consult (srcid);
+ if (s == 0) {
+ s = lookup_duplicate (srcid, addr);
+ if (s == 0) {
+ /* CSRC=SSRC for data stream */
+
+ this->callback_->get_rtp_source (s,
+ srcid,
+ srcid,
+ addr);
+// ACE_NEW_RETURN (s,
+// TAO_AV_Source (srcid, srcid, addr),
+// 0);
+ enter (s);
+ }
+ /* it takes two in-seq packets to activate TAO_AV_Source */
+ s->fs (seq);
+ s->cs (seq);
+ // @@@Naga:We should take care of this using a policy for the
+ // number of packets to be validated before we accept a source.
+ return (0);
+ } else {
+ /*
+ * check for a srcid conflict or loop:
+ * - believe the new guy if the old guy said he's done.
+ * - otherwise, don't believe the new guy if we've heard
+ * from the old guy 'recently'.
+ */
+ if (s->addr () != addr) {
+ ACE_UINT32 t = s->lts_done ().tv_sec;
+ if (t == 0) {
+ t = s->lts_data ().tv_sec;
+ ACE_UINT32 now = ACE_OS::gettimeofday ().sec ();
+ if (t && int (now - t) <= 2)
+ return (0);
+ t = s->lts_ctrl ().tv_sec;
+ if (t && int (now - t) <= 30)
+ return (0);
+ }
+ s->addr (addr);
+ s->clear_counters ();
+ s->lost (0);
+ }
+ if (s->np () == 0 && s->nb () == 0) {
+ /*
+ * make sure we get 2 in-seq packets before
+ * accepting TAO_AV_Source.
+ */
+ if ( (ACE_UINT32) ( (ACE_UINT32)seq - s->cs () + 31) > 63) {
+ s->fs (seq);
+ s->cs (seq);
+ return (0);
+ }
+ }
+ }
+ return (s);
+}
+
+/*
+ * Try to find an entry in the TAO_AV_Source table with the same network
+ * address (i.e., a "duplicate entry") but possibly different srcid.
+ * As a side effect, refile the TAO_AV_Source under the new srcid.
+ *
+ * The idea here is to gracefully handle sites that restart (with
+ * a new srcid). If we assume that it takes a couple seconds to
+ * restart
+ *
+ */
+TAO_AV_Source*
+TAO_AV_SourceManager::lookup_duplicate (ACE_UINT32 srcid, ACE_UINT32 addr)
+{
+ /*XXX - should eventually be conditioned on cname not ipaddr */
+ /*
+ * could use hashing here, but this is rarely called.
+ */
+ register TAO_AV_Source* s;
+ for (s = sources_; s != 0; s = s->next_) {
+ /*
+ * if addresses match, take old entry if:
+ * - it sent a 'done', or
+ * - it hasn't sent any data for 2 seconds and
+ * and any control for 30 seconds.
+ */
+ if (s->addr () == addr) {
+ if (s->lts_done ().tv_sec != 0)
+ break;
+ ACE_UINT32 now = ACE_OS::gettimeofday ().sec ();
+ ACE_UINT32 t = s->lts_data ().tv_sec;
+ if (t == 0 || int (now - t) > 2) {
+ t = s->lts_ctrl ().tv_sec;
+ if (t == 0 || int (now - t) > 30)
+ break;
+ }
+ }
+ }
+ if (s) {
+ remove_from_hashtable (s);
+ s->srcid (srcid);
+ s->ssrc (srcid);
+ int h = SHASH (srcid);
+ s->hlink_ = hashtab_[h];
+ hashtab_[h] = s;
+ s->clear_counters ();
+ s->lost (0);
+ }
+ return (s);
+}
+
+void
+TAO_AV_SourceManager::remove (TAO_AV_Source* s)
+{
+ --nsources_;
+
+ remove_from_hashtable (s);
+
+ /* delete the TAO_AV_Source from list */
+ TAO_AV_Source** p = &sources_;
+ while (*p != s)
+ p = & (*p)->next_;
+ *p = (*p)->next_;
+
+ delete s;
+
+}
+
+/*
+ * Go through all the TAO_AV_Sources and see if any should be "grayed out"
+ * or removed altogether. 'msgint' is the current "report interval"
+ * in ms.
+ */
+void
+TAO_AV_SourceManager::CheckActiveSources (double msgint)
+{
+ ACE_UINT32 now = ACE_OS::gettimeofday ().sec ();
+ u_int max_idle = u_int (msgint * (CTRL_IDLE / 1000.));
+ if (max_idle == 0)
+ max_idle = 1;
+
+ TAO_AV_Source* n;
+ for (TAO_AV_Source* s = sources_; s != 0; s = n) {
+ n = s->next_;
+ ACE_UINT32 t = s->lts_done ().tv_sec;
+ if (t != 0) {
+ if (keep_sites_)
+ s->lost (1);
+ else
+ remove (s);
+ continue;
+ }
+ t = s->lts_ctrl ().tv_sec;
+ if (t == 0)
+ /*
+ * No session packets? Probably ivs or nv sender.
+ * Revert to the data time stamp.
+ */
+ t = s->lts_data ().tv_sec;
+
+ if (u_int (now - t) > max_idle) {
+ if (keep_sites_ || site_drop_time_ == 0 ||
+ u_int (now - t) < site_drop_time_)
+ s->lost (1);
+ else
+ remove (s);
+ } else
+ s->lost (0);
+ }
+}
+
+int
+TAO_AV_SourceManager::compare (const void* v0, const void* v1)
+{
+ const TAO_AV_Source* x = * (TAO_AV_Source**)v0;
+ const TAO_AV_Source* y = * (TAO_AV_Source**)v1;
+
+ const char* yn = y->sdes (RTCP_SDES_NAME);
+ if (yn == 0) {
+ yn = y->sdes (RTCP_SDES_CNAME);
+ if (yn == 0)
+ return (-1);
+ }
+ const char* xn = x->sdes (RTCP_SDES_NAME);
+ if (xn == 0) {
+ xn = x->sdes (RTCP_SDES_CNAME);
+ if (xn == 0)
+ return (1);
+ }
+ return (strcmp (xn, yn));
+}
+
+/*
+ * Sort the sources by name and format a corresponding list
+ * of ascii srcid's in the input buffer.
+ */
+void
+TAO_AV_SourceManager::sortactive (char* cp) const
+{
+ static int ntab;
+ static TAO_AV_Source** srctab;
+ if (srctab == 0) {
+ ntab = 2 * nsources_;
+ if (ntab < 32)
+ ntab = 32;
+ ACE_NEW (srctab,
+ TAO_AV_Source*[ntab]);
+ } else if (ntab < nsources_) {
+ ntab = 2 * nsources_;
+ delete srctab;
+ ACE_NEW (srctab,
+ TAO_AV_Source*[ntab]);
+ }
+ int n = 0;
+ for (TAO_AV_Source* s = sources_; s != 0; s = s->next_)
+ if (s->active () != 0)
+ /* source is active if it has a PacketHandler */
+ srctab[n++] = s;
+
+ if (n == 0) {
+ *cp = 0;
+ return;
+ }
+ qsort (srctab, n, sizeof (*srctab), compare);
+ for (int i = 0; i < n; ++i) {
+ strcpy (cp, srctab[i]->name ());
+ cp += strlen (cp);
+ *cp++ = ' ';
+ }
+ /* nuke trailing space */
+ cp[-1] = 0;
+}
diff --git a/TAO/orbsvcs/orbsvcs/AV/source.h b/TAO/orbsvcs/orbsvcs/AV/source.h
new file mode 100644
index 00000000000..5adafbfe2b1
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/AV/source.h
@@ -0,0 +1,225 @@
+/* -*- C++ -*- */
+// $Id$
+/*
+ * Copyright (c) 1994 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and the Network Research Group at
+ * Lawrence Berkeley Laboratory.
+ * 4. Neither the name of the University nor of the Laboratory may be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#) $Header$
+ */
+
+#ifndef TAO_AV_SOURCE_H
+#define TAO_AV_SOURCE_H
+
+#define RTCP_SDES_MAX 7
+
+#include "ace/OS.h"
+#include "tao/TAO.h"
+class TAO_AV_SourceManager;
+
+#define TAO_AV_SOURCE_HASH 1024
+
+class TAO_AV_Source
+{
+public:
+ TAO_AV_Source (ACE_UINT32 srcid, ACE_UINT32 ssrc, ACE_UINT32 addr);
+ virtual ~TAO_AV_Source (void);
+ void deactivate (void);
+
+ void action();
+ // @@Naga:My additions.
+ char *name ();
+ int active (void);
+ void active (int active);
+ virtual void set_busy();
+ ACE_UINT32 delvar () const;
+ void delvar (ACE_UINT32 v);
+
+ void lts_done (const timeval& now);
+ void lts_data (const timeval& now);
+ void lts_ctrl (const timeval& now);
+ void sts_data (ACE_UINT32 now);
+ void sts_ctrl (ACE_UINT32 now);
+
+ const timeval& lts_ctrl (void) const;
+ const timeval& lts_data (void) const;
+ const timeval& lts_done (void) const;
+ int sts_ctrl (void) const;
+ int sts_data (void) const;
+
+ const char* sdes (int t) const;
+ virtual void sdes (int t, const char* value);
+ ACE_UINT32 addr (void) const;
+ void addr (ACE_UINT32 a);
+ ACE_UINT32 srcid (void) const;
+ void srcid (ACE_UINT32 s);
+ ACE_UINT32 ssrc (void) const;
+ void ssrc (ACE_UINT32 s);
+ void format (int v);
+ int format (void) const;
+ void mute (int v);
+ int mute (void) const;
+ void ismixer (int v);
+ int ismixer (void) const;
+ void clear_counters (void);
+
+ /*XXX should start at random values*/
+ ACE_UINT32 nb (void) const;
+ ACE_UINT32 nf (void) const;
+ ACE_UINT32 np (void) const;
+ ACE_UINT32 nm (void) const;
+ ACE_UINT32 ns (void) const; /* no. expected */
+ ACE_UINT32 ehs (void) const;
+ ACE_UINT32 cs (void) const;
+ ACE_UINT32 snp (void) const;
+ ACE_UINT32 sns (void) const;
+ ACE_UINT32 runt (void) const;
+ ACE_UINT32 dups (void) const;
+ ACE_UINT32 badsesslen (void) const;
+ ACE_UINT32 badsessver (void) const;
+ ACE_UINT32 badsessopt (void) const;
+ ACE_UINT32 badsdes (void) const;
+ ACE_UINT32 badbye (void) const;
+ void nb (int v);
+ void nf (int v);
+ void np (int v);
+ void nm (int v);
+ void snp (int v);
+ void sns (int v);
+ void fs (int v);
+ void runt (int v);
+ void badsesslen (int v);
+ void badsessver (int v);
+ void badsessopt (int v);
+ void badsdes (int v);
+ void badbye (int v);
+ int cs (ACE_UINT16 v);
+ int checkseq (ACE_UINT16 v);
+ virtual void lost (int);
+
+ TAO_AV_Source* next_; /* link for TAO_AV_SourceManager TAO_AV_Source list */
+ TAO_AV_Source* hlink_; /* link for TAO_AV_SourceManager hash table */
+protected:
+ char* stats (char* cp) const;
+
+ // @@Naga:My additions
+ int active_;
+ char *name_;
+ int delvar_;
+ ACE_UINT32 srcid_; /* rtp global src id (CSRC), net order */
+ ACE_UINT32 ssrc_; /* rtp global sync src id (SSRC), net order) */
+ ACE_UINT32 addr_; /* address of sender (net order) */
+
+ ACE_UINT32 sts_data_; /* sndr ts from last data packet (net order) */
+ ACE_UINT32 sts_ctrl_; /* sndr ts from last control packet */
+ timeval lts_data_; /* local unix time for last data packet */
+ timeval lts_ctrl_; /* local unix time for last control packet */
+ timeval lts_done_; /* local unix time for bye packet */
+
+ ACE_UINT32 fs_; /* first seq. no received */
+ ACE_UINT32 cs_; /* current (most recent) seq. no received */
+ ACE_UINT32 np_; /* no. packets received */
+ ACE_UINT32 nf_; /* no. video frames received */
+ ACE_UINT32 nb_; /* no. bytes received */
+ ACE_UINT32 nm_; /* no. misordered packets detected */
+ ACE_UINT32 snp_; /* last advertised no. pkts received */
+ ACE_UINT32 sns_; /* last advertised no. pkts exptected */
+ ACE_UINT32 ndup_; /* no. of duplicate packets (via RTP seqno) */
+ ACE_UINT32 nrunt_; /* count of packets too small */
+
+ /* following errors are from session (rtcp) processing */
+ ACE_UINT32 badsesslen_; /* bad header length field */
+ ACE_UINT32 badsessver_; /* bad header version number */
+ ACE_UINT32 badsessopt_; /* unrecognized option */
+ ACE_UINT32 badsdes_; /* sdes cnt > available data */
+ ACE_UINT32 badbye_; /* bye cnt > available data */
+
+ int format_; /* RTP packet type */
+ int mute_; /* true if Source muted */
+ int lost_; /* true when signal lost */
+ int busy_; /* nonzero. during talk spurt */
+ int ismixer_; /* true if TAO_AV_Source has acted as a 'mixer' */
+
+#define TAO_AV_SOURCE_NSEQ 64
+ ACE_UINT16 seqno_[TAO_AV_SOURCE_NSEQ];
+ char* sdes_[RTCP_SDES_MAX + 1];
+};
+
+int sdes_atoi (const char* s);
+char* onestat (char* cp, const char* name, u_long v);
+class TAO_Base_StreamEndPoint;
+class TAO_AV_RTCP_Callback;
+
+class TAO_AV_SourceManager
+{
+public:
+ TAO_AV_SourceManager (TAO_AV_RTCP_Callback *callback);
+ void init (ACE_UINT32 localid, ACE_UINT32 localaddr);
+ TAO_AV_Source* lookup (ACE_UINT32 srcid, ACE_UINT32 ssrc, ACE_UINT32 addr);
+ TAO_AV_Source* demux (ACE_UINT32 srcid, ACE_UINT32 addr, ACE_UINT16 seq);
+ TAO_AV_Source* consult (ACE_UINT32 srcid);
+ int nsources (void) const;
+ TAO_AV_Source* sources (void) const;
+
+ void CheckActiveSources (double msgint);
+ void ListSources (void);
+
+ ACE_UINT32 clock (void) const;
+ TAO_AV_Source* localsrc (void) const;
+ void localsrc (TAO_AV_Source* src);
+
+ void sortactive (char*) const;
+ void remove (TAO_AV_Source*);
+ void keep_sites (int keep);
+ void site_drop_time (int time);
+ TAO_AV_Source* enter (TAO_AV_Source* s);
+protected:
+ static int compare (const void*, const void*);
+ void remove_from_hashtable (TAO_AV_Source* s);
+
+ TAO_AV_Source* lookup_duplicate (ACE_UINT32 srcid, ACE_UINT32 addr);
+
+ int nsources_;
+ TAO_AV_Source* sources_;
+ ACE_UINT32 clock_;
+ int keep_sites_;
+ u_int site_drop_time_;
+ TAO_AV_Source* localsrc_;
+ TAO_AV_Source* hashtab_[TAO_AV_SOURCE_HASH];
+
+ TAO_AV_RTCP_Callback *callback_;
+};
+
+#if defined (__ACE_INLINE__)
+#include "source.i"
+#endif /* __ACE_INLINE__ */
+
+#endif /* TAO_AV_Source_H */
diff --git a/TAO/orbsvcs/orbsvcs/AV/source.i b/TAO/orbsvcs/orbsvcs/AV/source.i
new file mode 100644
index 00000000000..73ed03d86b7
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/AV/source.i
@@ -0,0 +1,491 @@
+/* -*- C++ -*- */
+//$Id$
+/*-
+ * Copyright (c) 1993-1994 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and the Network Research Group at
+ * Lawrence Berkeley Laboratory.
+ * 4. Neither the name of the University nor of the Laboratory may be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+ACE_INLINE int
+TAO_AV_Source::checkseq (ACE_UINT16 v)
+{
+ int k = v & (TAO_AV_SOURCE_NSEQ-1);
+ if (seqno_[k] != v) {
+ seqno_[k] = v;
+ return (0);
+ } else {
+ ++ndup_;
+ return (-1);
+ }
+}
+
+ACE_INLINE int
+TAO_AV_Source::cs (ACE_UINT16 v)
+{
+ /*
+ * This routine updates a 32 bit sequence number based on
+ * the rtp packet's 16 bit seq. no.
+ */
+ register int c = cs_;
+ register int d = v - c;
+ if (d < -1024 || d > 1024) {
+ cs_ = v;
+ if (v < 512 && c > 0x10000-512) {
+ /*
+ * seq no. wrapped - subtract 64k from fs to
+ * account for it.
+ */
+ fs_ -= 0x10000;
+ } else {
+ /*
+ * the seq. no made a very large jump. assume
+ * that the other side restarted without telling
+ * us about it so just re-sync (i.e., pretend
+ * this was the first packet).
+ */
+ fs_ = v - 1;
+ np_ = 0;
+ nf_ = 0;
+ nb_ = 0;
+ snp_ = 0;
+ nm_ = 0;
+ }
+ } else if (d > 0) {
+ /* d <= 0 means duplicate or reordered packet - ignore */
+ cs_ = v;
+ if (d < 0)
+ /* out of order */
+ ++nm_;
+ }
+ return (checkseq (v));
+}
+
+ACE_INLINE void
+TAO_AV_Source::action (void)
+{
+ if (!busy_) set_busy();
+}
+
+ACE_INLINE char*
+TAO_AV_Source::name (void)
+{
+ return ACE_OS::strdup ("");
+}
+
+ACE_INLINE int
+TAO_AV_Source::active (void)
+{
+ return this->active_;
+}
+
+ACE_INLINE void
+TAO_AV_Source::active (int active)
+{
+ this->active_ = active;
+}
+
+ACE_INLINE ACE_UINT32
+TAO_AV_Source::delvar (void) const
+{
+ return this->delvar_;
+}
+
+ACE_INLINE void
+TAO_AV_Source::delvar (ACE_UINT32 v)
+{
+ this->delvar_ = v;
+}
+
+ACE_INLINE const timeval&
+TAO_AV_Source::lts_ctrl (void) const
+{
+ return (lts_ctrl_);
+}
+
+ACE_INLINE void
+TAO_AV_Source::lts_ctrl (const timeval& now)
+{
+ this->lts_ctrl_ = now;
+}
+
+ACE_INLINE const timeval&
+TAO_AV_Source::lts_data (void) const
+{
+ return (lts_data_);
+}
+
+ACE_INLINE void
+TAO_AV_Source::lts_data (const timeval& now)
+{
+ this->lts_data_ = now;
+}
+
+ACE_INLINE const timeval&
+TAO_AV_Source::lts_done (void) const
+{
+ return (lts_done_);
+}
+
+ACE_INLINE void
+TAO_AV_Source::lts_done (const timeval &now)
+{
+ this->lts_done_ = now;
+}
+
+ACE_INLINE int
+TAO_AV_Source::sts_ctrl (void) const
+{
+ return (sts_ctrl_);
+}
+
+ACE_INLINE void
+TAO_AV_Source::sts_ctrl (ACE_UINT32 now)
+{
+ this->sts_ctrl_ = now;
+}
+
+ACE_INLINE int
+TAO_AV_Source::sts_data (void) const
+{
+ return (sts_data_);
+}
+
+ACE_INLINE void
+TAO_AV_Source::sts_data (ACE_UINT32 now)
+{
+ this->sts_data_ = now;
+}
+
+ACE_INLINE const char*
+TAO_AV_Source::sdes (int t) const
+{
+ return (sdes_[t]);
+}
+
+ACE_INLINE ACE_UINT32
+TAO_AV_Source::addr (void) const
+{
+ return (addr_);
+}
+ACE_INLINE void
+TAO_AV_Source::addr (ACE_UINT32 a)
+{
+ addr_ = a;
+}
+
+ACE_INLINE ACE_UINT32
+TAO_AV_Source::srcid (void) const
+{
+ return (srcid_);
+}
+
+ACE_INLINE void
+TAO_AV_Source::srcid (ACE_UINT32 s)
+{
+ srcid_ = s;
+}
+
+ACE_INLINE ACE_UINT32
+TAO_AV_Source::ssrc (void) const
+{
+ return (ssrc_);
+}
+
+ACE_INLINE void
+TAO_AV_Source::ssrc (ACE_UINT32 s)
+{
+ ssrc_ = s;
+}
+
+ACE_INLINE void
+TAO_AV_Source::format (int v)
+{
+ format_ = v;
+}
+
+ACE_INLINE int
+TAO_AV_Source::format (void) const
+{
+ return (format_);
+}
+
+ACE_INLINE void
+TAO_AV_Source::mute (int v)
+{
+ mute_ = v;
+}
+
+ACE_INLINE int
+TAO_AV_Source::mute (void) const
+{
+ return (mute_);
+}
+
+ACE_INLINE void
+TAO_AV_Source::ismixer (int v)
+{
+ ismixer_ = v;
+}
+
+ACE_INLINE int
+TAO_AV_Source::ismixer (void) const
+{
+ return (ismixer_);
+}
+
+ACE_INLINE ACE_UINT32
+TAO_AV_Source::nb (void) const
+{
+ return (nb_);
+}
+
+ACE_INLINE ACE_UINT32
+TAO_AV_Source::nf (void) const
+{
+ return (nf_);
+}
+
+ACE_INLINE ACE_UINT32
+TAO_AV_Source::np (void) const
+{
+ return (np_);
+}
+
+ACE_INLINE ACE_UINT32
+TAO_AV_Source::nm (void) const
+{
+ return (nm_);
+}
+
+/* no. expected */
+ACE_INLINE ACE_UINT32
+TAO_AV_Source::ns (void) const
+{
+ return (cs_ - fs_);
+}
+
+ACE_INLINE ACE_UINT32
+TAO_AV_Source::ehs (void) const
+{
+ return (- (fs_ & 0xffff0000) | cs_);
+}
+
+ACE_INLINE ACE_UINT32
+TAO_AV_Source::cs (void) const
+{
+ return (cs_);
+}
+
+ACE_INLINE ACE_UINT32
+TAO_AV_Source::snp (void) const
+{
+ return (snp_);
+}
+
+ACE_INLINE ACE_UINT32
+TAO_AV_Source::sns (void) const
+{
+ return (sns_);
+}
+
+ACE_INLINE ACE_UINT32
+TAO_AV_Source::runt (void) const
+{
+ return (nrunt_);
+}
+
+ACE_INLINE ACE_UINT32
+TAO_AV_Source::dups (void) const
+{
+ return (ndup_);
+}
+
+ACE_INLINE ACE_UINT32
+TAO_AV_Source::badsesslen (void) const
+{
+ return (badsesslen_);
+}
+
+ACE_INLINE ACE_UINT32
+TAO_AV_Source::badsessver (void) const
+{
+ return (badsessver_);
+}
+
+ACE_INLINE ACE_UINT32
+TAO_AV_Source::badsessopt (void) const
+{
+ return (badsessopt_);
+}
+
+ACE_INLINE ACE_UINT32
+TAO_AV_Source::badsdes (void) const
+{
+ return (badsdes_);
+}
+
+ACE_INLINE ACE_UINT32
+TAO_AV_Source::badbye (void) const
+{
+ return (badbye_);
+}
+
+ACE_INLINE void
+TAO_AV_Source::nb (int v)
+{
+ nb_ += v;
+}
+
+ACE_INLINE void
+TAO_AV_Source::nf (int v)
+{
+ nf_ += v;
+}
+
+ACE_INLINE void
+TAO_AV_Source::np (int v)
+{
+ np_ += v;
+}
+
+ACE_INLINE void
+TAO_AV_Source::nm (int v)
+{
+ nm_ += v;
+}
+
+ACE_INLINE void
+TAO_AV_Source::snp (int v)
+{
+ snp_ = v;
+}
+
+ACE_INLINE void
+TAO_AV_Source::sns (int v)
+{
+ sns_ = v;
+}
+
+ACE_INLINE void
+TAO_AV_Source::fs (int v)
+{
+ fs_ = v;
+}
+
+ACE_INLINE void
+TAO_AV_Source::runt (int v)
+{
+ nrunt_ += v;
+}
+
+ACE_INLINE void
+TAO_AV_Source::badsesslen (int v)
+{
+ badsesslen_ += v;
+}
+
+ACE_INLINE void
+TAO_AV_Source::badsessver (int v)
+{
+ badsessver_ += v;
+}
+
+ACE_INLINE void
+TAO_AV_Source::badsessopt (int v)
+{
+ badsessopt_ += v;
+}
+
+ACE_INLINE void
+TAO_AV_Source::badsdes (int v)
+{
+ badsdes_ += v;
+}
+
+ACE_INLINE void
+TAO_AV_Source::badbye (int v)
+{
+ badbye_ += v;
+}
+
+ACE_INLINE void
+TAO_AV_Source::lost (int v)
+{
+ if (lost_ != v)
+ lost_ = v;
+}
+
+//------------------------------------------------------------
+// TAO_AV_SourceManager
+//------------------------------------------------------------
+
+ACE_INLINE int
+TAO_AV_SourceManager::nsources (void) const
+{
+ return (this->nsources_);
+}
+
+ACE_INLINE TAO_AV_Source*
+TAO_AV_SourceManager::sources (void) const
+{
+ return (this->sources_);
+}
+
+ACE_INLINE ACE_UINT32
+TAO_AV_SourceManager::clock (void) const
+{
+ return (clock_);
+}
+
+ACE_INLINE TAO_AV_Source*
+TAO_AV_SourceManager::localsrc (void) const
+{
+ return (localsrc_);
+}
+
+ACE_INLINE void
+TAO_AV_SourceManager::localsrc (TAO_AV_Source *src)
+{
+ this->localsrc_ = src;
+}
+
+ACE_INLINE void
+TAO_AV_SourceManager::keep_sites (int keep)
+{
+ this->keep_sites_ = keep;
+}
+
+ACE_INLINE void
+TAO_AV_SourceManager::site_drop_time (int time)
+{
+ this->site_drop_time_ = time;
+}
+