summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcrodrigu <crodrigu@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2001-11-13 19:22:54 +0000
committercrodrigu <crodrigu@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2001-11-13 19:22:54 +0000
commite67af10528ec50214bb3bf6a52293ab0d09c6210 (patch)
tree5ba4eeb8346331439f9b2412d515006bd2a85d83
parent4b01fdecf4e2b22f99d9feb37e1bf65199ed40c2 (diff)
downloadATCD-e67af10528ec50214bb3bf6a52293ab0d09c6210.tar.gz
ChangeLogTag: Wed Nov 13 14:14:24 2001 Craig Rodrigues <crodrigu@bbn.com>
-rw-r--r--TAO/ChangeLogs/ChangeLog-02a85
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/AVStreams_i.cpp259
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/AVStreams_i.h6
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/AV_Core.cpp100
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/AV_Core.h13
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/Endpoint_Strategy_T.cpp17
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/FlowSpec_Entry.cpp401
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/FlowSpec_Entry.h43
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/FlowSpec_Entry.i86
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/MCast.cpp12
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/MCast.h5
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/Protocol_Factory.cpp3
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/QoS_UDP.cpp61
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/QoS_UDP.h12
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/RTCP.cpp1258
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/RTCP.h250
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/RTCP_Channel.cpp361
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/RTCP_Channel.h217
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/RTCP_Packet.cpp1194
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/RTCP_Packet.h393
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/RTP.cpp589
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/RTP.h151
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/TCP.cpp18
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/TCP.h12
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/Transport.cpp546
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/Transport.h14
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/UDP.cpp446
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/UDP.h50
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/global.h31
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/md5.h49
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/md5c.c345
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/source.cpp541
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/source.h234
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/source.i491
34 files changed, 5359 insertions, 2934 deletions
diff --git a/TAO/ChangeLogs/ChangeLog-02a b/TAO/ChangeLogs/ChangeLog-02a
index 380e25f8a73..4ebcc637215 100644
--- a/TAO/ChangeLogs/ChangeLog-02a
+++ b/TAO/ChangeLogs/ChangeLog-02a
@@ -1,3 +1,88 @@
+Wed Nov 13 14:14:24 2001 Craig Rodrigues <crodrigu@bbn.com>
+
+ Fixes provided by Rob Ruff <rruff@scires.com>:
+
+ * orbsvcs/orbsvcs/AV/AVStreams_i.cpp:
+ * orbsvcs/orbsvcs/AV/AVStreams_i.i:
+ * orbsvcs/orbsvcs/AV/AV_Core.cpp:
+ * orbsvcs/orbsvcs/AV/AV_Core.h:
+ * orbsvcs/orbsvcs/AV/FlowSpec_Entry.cpp:
+ * orbsvcs/orbsvcs/AV/FlowSpec_Entry.h:
+ * orbsvcs/orbsvcs/AV/FlowSpec_Entry.i:
+ * orbsvcs/orbsvcs/AV/QoS_UDP.cpp:
+ * orbsvcs/orbsvcs/AV/QoS_UDP.h:
+ * orbsvcs/orbsvcs/AV/TCP.cpp:
+ * orbsvcs/orbsvcs/AV/TCP.h:
+ * orbsvcs/orbsvcs/AV/Transport.cpp:
+ * orbsvcs/orbsvcs/AV/Transport.h:
+ * orbsvcs/orbsvcs/AV/UDP.cpp:
+ * orbsvcs/orbsvcs/AV/UDP.h:
+ The previous implementation used separate flow specifications for the
+ data and control portions of the same stream. This meant that RTP
+ could not be used with the light profile of the AV service (since it
+ only allows one flow between stream endpoints). The code was modified
+ to allow data and control information to be passed as part of the
+ same flow.
+ * orbsvcs/orbsvcs/AV/AVStreams_i.cpp:
+ Added/renamed several properties defined in the CORBA AV spec.
+ Implemented the TAO_StreamCtrl::unbind operation.
+ Fixed several memory leaks.
+ * orbsvcs/orbsvcs/AV/AV_Core.cpp:
+ Added code to clean up transport/flow factories (fix memory leak).
+ Added get_transport_factory(const char *transport_protocol).
+ Added get_flow_protocol_factory(const char *flow_protocol).
+ * orbsvcs/orbsvcs/AV/AV_Core.h:
+ Added get_transport_factory(const char *transport_protocol).
+ Added get_flow_protocol_factory(const char *flow_protocol).
+ * orbsvcs/orbsvcs/AV/Endpoint_Strategy_T.cpp:
+ Added a remove_ref call to activate_mediactrl.
+ * orbsvcs/orbsvcs/AV/FlowSpec_Entry.cpp:
+ Changed the flow specification to better conform to the AV Service
+ spec.
+ * orbsvcs/orbsvcs/AV/MCast.cpp:
+ TAO_AV_UDP_MCast_Flow_Handler::handle_input now returns the value
+ returned by protocol_object->handle_input rather than 0.
+ * orbsvcs/orbsvcs/AV/MCast.h:
+ Made the TAO_AV_UDP_MCast_Flow_Handler destructor virtual.
+ * orbsvcs/orbsvcs/AV/RTCP.cpp:
+ * orbsvcs/orbsvcs/AV/RTCP.h:
+ Added full RFC compliant RTCP control protocol implementation.
+ Modified the ssrc allocation operation to use the MD5 algorithm to
+ more reliably choose a unique id.
+ * orbsvcs/orbsvcs/AV/RTCP_Channel.h: (added)
+ * orbsvcs/orbsvcs/AV/RTCP_Channel.cpp: (added)
+ These files contain two classes, one used to represent incoming RTP
+ streams and one to represent outgoing streams. They keep track of
+ transmission/reception statistics.
+ * orbsvcs/orbsvcs/AV/RTCP_Packet.h: (added)
+ * orbsvcs/orbsvcs/AV/RTCP_Packet.cpp: (added)
+ These files contain classes to represent each of the control packet
+ message types.
+ * orbsvcs/orbsvcs/AV/RTP.cpp:
+ * orbsvcs/orbsvcs/AV/RTP.h:
+ Made several changes to support the RTCP implementation.
+ Added a class to represent an RTP packet.
+ * orbsvcs/orbsvcs/AV/Transport.cpp:
+ Modified code to use the get_xxx_factory routines added to AV_Core
+ rather than doing the search in this file.
+ * orbsvcs/orbsvcs/AV/UDP.cpp:
+ When the protocol is RTP/UDP, an even/odd port pair will be reserved
+ as is called out in the RTP RFC.
+ The class TAO_AV_UDP_Connection_Setup was added to replace duplicated
+ code used for both the TAO_AV_UDP_Acceptor and TAO_AV_UDP_Connector.
+ * orbsvcs/orbsvcs/AV/global.h: (added)
+ * orbsvcs/orbsvcs/AV/md5.h: (added)
+ * orbsvcs/orbsvcs/AV/md5c.c: (added)
+ Used by the operation to allocate ssrc's in RTCP.cpp to help guarantee
+ a unique id.
+ * orbsvcs/orbsvcs/AV/source.cpp: (removed)
+ * orbsvcs/orbsvcs/AV/source.h: (removed)
+ * orbsvcs/orbsvcs/AV/source.i: (removed)
+ The functionality contained in these files is now implemented in the
+ RTCP*.* files.
+ * orbsvcs/orbsvcs/Makefile.av: (updated)
+ * orbsvcs/orbsvcs/AV.bor: (updated)
+
Tue Nov 13 08:58:13 2001 Ossama Othman <ossama@uci.edu>
* orbsvcs/orbsvcs/Notify/Notify_ProxyPushSupplier_i.cpp
diff --git a/TAO/orbsvcs/orbsvcs/AV/AVStreams_i.cpp b/TAO/orbsvcs/orbsvcs/AV/AVStreams_i.cpp
index cebba6f5191..5c289498b2d 100644
--- a/TAO/orbsvcs/orbsvcs/AV/AVStreams_i.cpp
+++ b/TAO/orbsvcs/orbsvcs/AV/AVStreams_i.cpp
@@ -96,7 +96,7 @@ TAO_Basic_StreamCtrl::stop (const AVStreams::flowSpec &flow_spec,
}
else
{
- // call start on all the flows.
+ // call stop on all the flows.
FlowConnection_Map_Iterator iterator (this->flow_connection_map_);
FlowConnection_Map_Entry *entry = 0;
for (;iterator.next (entry) != 0;iterator.advance ())
@@ -182,6 +182,7 @@ TAO_Basic_StreamCtrl::destroy (const AVStreams::flowSpec &flow_spec,
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 = TAO_AV_Core::get_flowname (flow_spec[i]);
@@ -193,9 +194,10 @@ TAO_Basic_StreamCtrl::destroy (const AVStreams::flowSpec &flow_spec,
ACE_TRY_CHECK;
}
}
+ }
else
{
- // call start on all the flows.
+ // call destroy on all the flows.
FlowConnection_Map_Iterator iterator (this->flow_connection_map_);
FlowConnection_Map_Entry *entry = 0;
for (;iterator.next (entry) != 0;iterator.advance ())
@@ -236,10 +238,10 @@ TAO_Basic_StreamCtrl::modify_QoS (AVStreams::streamQoS & new_qos,
in_flowspec.length (0);
out_flowspec.length (0);
-
+
int in_index = 0;
int out_index = 0;
-
+
for (u_int i=0;i < flowspec.length ();i++)
{
TAO_Forward_FlowSpec_Entry entry;
@@ -609,6 +611,7 @@ TAO_StreamCtrl::destroy (const AVStreams::flowSpec &flow_spec,
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 ())
@@ -625,7 +628,7 @@ TAO_StreamCtrl::destroy (const AVStreams::flowSpec &flow_spec,
}
ACE_CATCHANY
{
- ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "TAO_Basic_StreamCtrl::destroy");
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "TAO_StreamCtrl::destroy");
return;
}
ACE_ENDTRY;
@@ -703,13 +706,29 @@ TAO_StreamCtrl::bind_devs (AVStreams::MMDevice_ptr a_party,
ACE_TRY_ENV);
ACE_TRY_CHECK;
+ CORBA::Any vdev_a_any;
+ vdev_a_any <<= this->vdev_a_.in ();
+ this->sep_a_->define_property ("Related_VDev",
+ vdev_a_any,
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+
CORBA::Any streamendpoint_a_any;
streamendpoint_a_any <<= this->sep_a_.in ();
- this->vdev_a_->define_property ("Related_StreamEndpoint_A",
+ this->vdev_a_->define_property ("Related_StreamEndpoint",
streamendpoint_a_any,
ACE_TRY_ENV);
-
- ACE_TRY_CHECK;
+
+ ACE_TRY_CHECK;
+
+ AVStreams::MMDevice_ptr a_party_copy = AVStreams::MMDevice::_duplicate(a_party);
+
+ CORBA::Any mmdevice_a_any;
+ mmdevice_a_any <<= a_party_copy;
+ this->vdev_a_->define_property ("Related_MMDevice",
+ mmdevice_a_any,
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK;
// add the mmdevice, sep and vdev to the map.
MMDevice_Map_Entry map_entry;
@@ -765,14 +784,29 @@ TAO_StreamCtrl::bind_devs (AVStreams::MMDevice_ptr a_party,
ACE_TRY_ENV);
ACE_TRY_CHECK;
- CORBA::Any streamendpoint_b_any;
+ CORBA::Any vdev_b_any;
+ vdev_b_any <<= this->vdev_b_.in ();
+ this->sep_b_->define_property ("Related_VDev",
+ vdev_b_any,
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+
+ CORBA::Any streamendpoint_b_any;
streamendpoint_b_any <<= this->sep_b_.in ();
- this->vdev_b_->define_property ("Related_StreamEndpoint_B",
+ this->vdev_b_->define_property ("Related_StreamEndpoint",
streamendpoint_b_any,
ACE_TRY_ENV);
-
+
ACE_TRY_CHECK;
+ AVStreams::MMDevice_ptr b_party_copy = AVStreams::MMDevice::_duplicate(b_party);
+
+ CORBA::Any mmdevice_b_any;
+ mmdevice_b_any <<= b_party_copy;
+ this->vdev_b_->define_property ("Related_MMDevice",
+ mmdevice_b_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);
@@ -787,6 +821,30 @@ TAO_StreamCtrl::bind_devs (AVStreams::MMDevice_ptr a_party,
}
}
+ // Tell the endpoints about each other.
+ if ((!CORBA::is_nil (a_party)) && (!CORBA::is_nil (b_party)))
+ {
+ AVStreams::StreamEndPoint_A_var sep_b_peer;
+ AVStreams::StreamEndPoint_B_var sep_a_peer;
+ CORBA::Any sep_a_peer_any;
+ CORBA::Any sep_b_peer_any;
+
+ sep_a_peer = AVStreams::StreamEndPoint_B::_duplicate(this->sep_b_.in());
+ sep_b_peer = AVStreams::StreamEndPoint_A::_duplicate(this->sep_a_.in());
+
+ sep_a_peer_any <<= sep_a_peer.in();
+ sep_b_peer_any <<= sep_b_peer.in();
+ this->sep_a_->define_property ("PeerAdapter",
+ sep_a_peer_any,
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+
+ this->sep_b_->define_property ("PeerAdapter",
+ sep_b_peer_any,
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ }
+
// In the full profile case there's no VDev.
if (CORBA::is_nil (b_party) && (!CORBA::is_nil (this->vdev_a_.in ())))
{
@@ -1267,7 +1325,7 @@ TAO_StreamCtrl::bind (AVStreams::StreamEndPoint_A_ptr sep_a,
}
ACE_ENDTRY;
ACE_CHECK_RETURN (0);
- }
+ }
ACE_CATCHANY
{
// error was thrown because one of the streamendpoints is light profile.
@@ -1284,10 +1342,39 @@ 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_TRY
+ {
+ if (this->flow_connection_map_.current_size () > 0)
+ return;
+
+ AVStreams::flowSpec flow_spec;
+ flow_spec.length(0);
+
+ 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_StreamCtrl::unbind");
+ return;
+ }
+ ACE_ENDTRY;
+ ACE_CHECK;
}
void
@@ -1615,7 +1702,17 @@ TAO_Base_StreamEndPoint::set_flow_handler (const char *flowname,
ACE_CString flow_name_key (flowname);
if (this->flow_handler_map_.bind (flow_name_key, handler) != 0)
ACE_ERROR ((LM_ERROR,
- "Error in storing flow handler\n"));
+ "Error in storing flow handler\n"));
+}
+
+void
+TAO_Base_StreamEndPoint::set_control_flow_handler (const char *flowname,
+ TAO_AV_Flow_Handler *handler)
+{
+ ACE_CString flow_name_key (flowname);
+ if (this->control_flow_handler_map_.bind (flow_name_key, handler) != 0)
+ ACE_ERROR ((LM_ERROR,
+ "Error in storing control flow handler\n"));
}
// ----------------------------------------------------------------------
@@ -1721,11 +1818,11 @@ TAO_StreamEndPoint::connect (AVStreams::StreamEndPoint_ptr responder,
ACE_DEBUG ((LM_DEBUG,
"QoS is Specified\n"));
- int result = this->translate_qos (qos,
+ int result = this->translate_qos (qos,
network_qos);
if (result != 0)
if (TAO_debug_level > 0)
- ACE_DEBUG ((LM_DEBUG,
+ ACE_DEBUG ((LM_DEBUG,
"QoS translation failed\n"));
this->qos ().set (network_qos);
@@ -1746,14 +1843,16 @@ TAO_StreamEndPoint::connect (AVStreams::StreamEndPoint_ptr responder,
ACE_NEW_RETURN (entry,
TAO_Forward_FlowSpec_Entry,
0);
+
if (entry->parse (flow_spec[i]) == -1)
return 0;
+
if (TAO_debug_level > 0)
ACE_DEBUG ((LM_DEBUG, "TAO_StreamEndPoint::Connect: %s\n", entry->entry_to_string ()));
+
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,
@@ -1786,13 +1885,13 @@ TAO_StreamEndPoint::connect (AVStreams::StreamEndPoint_ptr responder,
TAO_Reverse_FlowSpec_Entry,
0);
if (entry->parse (flow_spec[i].in ()) == -1)
- ACE_ERROR_RETURN ((LM_ERROR,
- "Reverse_Flow_Spec_Set::parse failed\n"),
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Reverse_Flow_Spec_Set::parse failed\n"),
0);
if (TAO_debug_level > 0)
- ACE_DEBUG ((LM_DEBUG,
- "TAO_StreamEndPoint::Connect: Reverse Flow Spec %s\n",
+ ACE_DEBUG ((LM_DEBUG,
+ "TAO_StreamEndPoint::Connect: Reverse Flow Spec %s\n",
entry->entry_to_string ()));
this->reverse_flow_spec_set.insert (entry);
@@ -1803,8 +1902,8 @@ TAO_StreamEndPoint::connect (AVStreams::StreamEndPoint_ptr responder,
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"),
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "TAO_AV_Core::init_reverse_flows failed\n"),
0);
// Make the upcall to the app
@@ -1861,6 +1960,8 @@ TAO_StreamEndPoint::stop (const AVStreams::flowSpec &flow_spec,
TAO_FlowSpec_Entry *entry = *begin;
// (*begin)->protocol_object ()->stop ();
entry->handler ()->stop (entry->role ());
+ if (entry->control_handler () != 0)
+ entry->control_handler ()->stop (entry->role ());
break;
}
}
@@ -1875,6 +1976,8 @@ TAO_StreamEndPoint::stop (const AVStreams::flowSpec &flow_spec,
TAO_FlowSpec_Entry *entry = *begin;
// entry->protocol_object ()->stop ();
entry->handler ()->stop (entry->role ());
+ if (entry->control_handler () != 0)
+ entry->control_handler ()->stop (entry->role ());
}
}
}
@@ -1906,7 +2009,13 @@ TAO_StreamEndPoint::start (const AVStreams::flowSpec &flow_spec,
{
// entry->protocol_object ()->start ();
if (entry->handler () != 0)
+ {
entry->handler ()->start (entry->role ());
+ }
+ if (entry->control_handler () != 0)
+ {
+ entry->control_handler ()->start (entry->role ());
+ }
}
}
@@ -1919,7 +2028,13 @@ TAO_StreamEndPoint::start (const AVStreams::flowSpec &flow_spec,
{
// entry->protocol_object ()->start ();
if (entry->handler () != 0)
+ {
entry->handler ()->start (entry->role ());
+ }
+ if (entry->control_handler () != 0)
+ {
+ entry->control_handler ()->start (entry->role ());
+ }
}
}
}
@@ -1935,6 +2050,10 @@ TAO_StreamEndPoint::start (const AVStreams::flowSpec &flow_spec,
{
entry->handler ()->start (entry->role ());
}
+ if (entry->control_handler () != 0)
+ {
+ entry->control_handler ()->start (entry->role ());
+ }
}
end = this->reverse_flow_spec_set.end ();
@@ -1947,9 +2066,11 @@ TAO_StreamEndPoint::start (const AVStreams::flowSpec &flow_spec,
{
entry->handler ()->start (entry->role ());
}
-
+ if (entry->control_handler () != 0)
+ {
+ entry->control_handler ()->start (entry->role ());
+ }
}
-
}
}
@@ -1974,10 +2095,13 @@ TAO_StreamEndPoint::destroy (const AVStreams::flowSpec &flow_spec,
begin != end; ++begin)
{
TAO_FlowSpec_Entry *entry = *begin;
- if (ACE_OS::strcmp (entry->flowname (), flow_spec [i]) == 0)
+ TAO_Tokenizer flow_name (flow_spec [i], '\\');
+ if (ACE_OS::strcmp (entry->flowname (), flow_name[0]) == 0)
{
if (entry->protocol_object ())
- entry->protocol_object ()->destroy ();
+ {
+ entry->protocol_object ()->destroy ();
+ }
break;
}
}
@@ -1988,10 +2112,13 @@ TAO_StreamEndPoint::destroy (const AVStreams::flowSpec &flow_spec,
begin != end; ++begin)
{
TAO_FlowSpec_Entry *entry = *begin;
- if (ACE_OS::strcmp (entry->flowname (), flow_spec [i]) == 0)
+ TAO_Tokenizer flow_name (flow_spec [i], '\\');
+ if (ACE_OS::strcmp (entry->flowname (), flow_name[0]) == 0)
{
if (entry->protocol_object ())
- entry->protocol_object ()->destroy ();
+ {
+ entry->protocol_object ()->destroy ();
+ }
break;
}
}
@@ -2007,7 +2134,9 @@ TAO_StreamEndPoint::destroy (const AVStreams::flowSpec &flow_spec,
{
TAO_FlowSpec_Entry *entry = *begin;
if (entry->protocol_object ())
- entry->protocol_object ()->destroy ();
+ {
+ entry->protocol_object ()->destroy ();
+ }
}
}
{
@@ -2017,7 +2146,9 @@ TAO_StreamEndPoint::destroy (const AVStreams::flowSpec &flow_spec,
{
TAO_FlowSpec_Entry *entry = *begin;
if (entry->protocol_object ())
- entry->protocol_object ()->destroy ();
+ {
+ entry->protocol_object ()->destroy ();
+ }
}
}
}
@@ -2043,7 +2174,7 @@ TAO_StreamEndPoint::request_connection (AVStreams::StreamEndPoint_ptr /*initiato
{
if (TAO_debug_level > 0)
- ACE_DEBUG ((LM_DEBUG,
+ ACE_DEBUG ((LM_DEBUG,
"\n(%P|%t) TAO_StreamEndPoint::request_connection called"));
@@ -2090,14 +2221,13 @@ TAO_StreamEndPoint::request_connection (AVStreams::StreamEndPoint_ptr /*initiato
return 0;
}
if (TAO_debug_level > 0)
- ACE_DEBUG ((LM_DEBUG,
- "TAO_StreamEndPoint::request_connection Flow Spec %s",
+ ACE_DEBUG ((LM_DEBUG,
+ "TAO_StreamEndPoint::request_connection Flow Spec %s",
entry->entry_to_string ()));
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,
@@ -2129,7 +2259,7 @@ TAO_StreamEndPoint::change_qos (AVStreams::streamQoS &new_qos,
if (TAO_debug_level > 0)
ACE_DEBUG ((LM_DEBUG,
"TAO_StreamEndPoint::change_qos\n"));
-
+
TAO_AV_QoS qos (new_qos);
for (int i = 0; (unsigned) i < the_flows.length (); i++)
{
@@ -2470,6 +2600,7 @@ 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.
@@ -2663,6 +2794,7 @@ TAO_StreamEndPoint_A::multiconnect (AVStreams::streamQoS &stream_qos,
0);
flow_spec[i] = CORBA::string_dup (new_entry->entry_to_string ());
//new_entry->is_multicast (1);
+
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,
@@ -2963,9 +3095,16 @@ TAO_VDev::set_media_ctrl (CORBA::Object_ptr media_ctrl,
CORBA::Environment &ACE_TRY_ENV)
{
- ACE_UNUSED_ARG (media_ctrl);
+// ACE_UNUSED_ARG (media_ctrl);
ACE_UNUSED_ARG (ACE_TRY_ENV);
ACE_CHECK_RETURN (0);
+
+ // FIX MEMORY LEAK:
+ // since the media ctrl is not stored or used, delete it.
+ // cleaned up several memory leaks (according to BoundsChecker)
+
+ delete media_ctrl;
+
return 1;
}
@@ -3070,7 +3209,7 @@ TAO_VDev::modify_QoS (AVStreams::streamQoS &the_qos,
if (TAO_debug_level > 0)
ACE_DEBUG ((LM_DEBUG,
"TAO_VDev::modify_QoS\n"));
-
+
if (flowspec.length () != 0)
{
TAO_Forward_FlowSpec_Entry entry;
@@ -3079,12 +3218,12 @@ TAO_VDev::modify_QoS (AVStreams::streamQoS &the_qos,
if (direction == 0)
{
AVStreams::StreamEndPoint_A_ptr sep_a;
-
+
CORBA::Any_ptr streamendpoint_a_any =
- this->get_property_value ("Related_StreamEndpoint_A",
+ this->get_property_value ("Related_StreamEndpoint",
ACE_TRY_ENV);
ACE_CHECK_RETURN (0);
-
+
*streamendpoint_a_any >>= sep_a;
if (sep_a != 0)
{
@@ -3099,13 +3238,13 @@ TAO_VDev::modify_QoS (AVStreams::streamQoS &the_qos,
AVStreams::StreamEndPoint_B_ptr sep_b;
CORBA::Any_ptr streamendpoint_b_any =
- this->get_property_value ("Related_StreamEndpoint_B",
+ this->get_property_value ("Related_StreamEndpoint",
ACE_TRY_ENV);
ACE_CHECK_RETURN (0);
*streamendpoint_b_any >>= sep_b;
sep_b->modify_QoS (the_qos, flowspec, ACE_TRY_ENV);
ACE_CHECK_RETURN (0);
- }
+ }
}
return 1;
}
@@ -3395,12 +3534,16 @@ TAO_MMDevice::create_A (AVStreams::StreamCtrl_ptr streamctrl,
ACE_CHECK_RETURN (0);
AVStreams::StreamEndPoint_A_ptr sep_a = 0;
- AVStreams::StreamEndPoint_ptr sep = 0;
+ // FIX MEMORY LEAK:
+ // if this causes a problem it will have to be changed back. None were found
+ // during testing. This cleaned up many memory leaks according to BoundsChecker
+// AVStreams::StreamEndPoint_ptr sep;
+ AVStreams::StreamEndPoint_var sep;
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);
+ sep_a = AVStreams::StreamEndPoint_A::_narrow (sep.in(), ACE_TRY_ENV);
ACE_TRY_CHECK;
}
ACE_CATCHANY
@@ -3430,12 +3573,18 @@ TAO_MMDevice::create_B (AVStreams::StreamCtrl_ptr streamctrl,
AVStreams::noSuchFlow))
{
AVStreams::StreamEndPoint_B_ptr sep_b = AVStreams::StreamEndPoint_B::_nil ();
- AVStreams::StreamEndPoint_ptr sep;
+
+ // FIX MEMORY LEAK:
+ // if this causes a problem it will have to be changed back. None were found
+ // during testing. This cleaned up many memory leaks according to BoundsChecker
+// AVStreams::StreamEndPoint_ptr sep;
+ AVStreams::StreamEndPoint_var sep;
+
ACE_TRY
{
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);
+ sep_b = AVStreams::StreamEndPoint_B::_narrow (sep.in(), ACE_TRY_ENV);
ACE_TRY_CHECK;
}
ACE_CATCHANY
@@ -4017,7 +4166,6 @@ TAO_FlowConnection::add_producer (AVStreams::FlowProducer_ptr producer,
char buf [BUFSIZ];
mcast_addr.addr_to_string (buf, BUFSIZ);
ACE_OS::sprintf (mcast_address, "%s=%s", this->protocol_.in (), buf);
-
}
else
{
@@ -4028,6 +4176,7 @@ TAO_FlowConnection::add_producer (AVStreams::FlowProducer_ptr producer,
mcast_address,
this->fp_name_.in (),
ACE_TRY_ENV);
+
ACE_TRY_CHECK;
if (this->producer_address_.in () == 0)
{
@@ -4778,7 +4927,14 @@ TAO_FlowProducer::start (CORBA::Environment &/*ACE_TRY_ENV*/)
begin != end; ++begin)
{
TAO_FlowSpec_Entry *entry = (*begin);
- entry->handler ()->start (TAO_FlowSpec_Entry::TAO_AV_PRODUCER);
+ if (entry->handler () != 0)
+ {
+ entry->handler ()->start (TAO_FlowSpec_Entry::TAO_AV_PRODUCER);
+ }
+ if (entry->control_handler () != 0)
+ {
+ entry->control_handler ()->start (TAO_FlowSpec_Entry::TAO_AV_PRODUCER);
+ }
}
}
@@ -4931,7 +5087,9 @@ TAO_FlowConsumer::start (CORBA::Environment &/*ACE_TRY_ENV*/)
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);
+ {
+ (*begin)->handler ()->start (TAO_FlowSpec_Entry::TAO_AV_CONSUMER);
+ }
}
char *
@@ -5075,6 +5233,7 @@ TAO_Tokenizer::operator [] (size_t index) const
}
+
#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
diff --git a/TAO/orbsvcs/orbsvcs/AV/AVStreams_i.h b/TAO/orbsvcs/orbsvcs/AV/AVStreams_i.h
index c85a2989177..0de8277fc7e 100644
--- a/TAO/orbsvcs/orbsvcs/AV/AVStreams_i.h
+++ b/TAO/orbsvcs/orbsvcs/AV/AVStreams_i.h
@@ -527,12 +527,16 @@ public:
virtual void set_flow_handler (const char *flowname,
TAO_AV_Flow_Handler *handler);
+ virtual void set_control_flow_handler (const char *flowname,
+ TAO_AV_Flow_Handler *handler);
+
TAO_AV_QoS &qos (void);
-
+
protected:
TAO_AV_QoS qos_;
Flow_Handler_Map flow_handler_map_;
+ Flow_Handler_Map control_flow_handler_map_;
};
diff --git a/TAO/orbsvcs/orbsvcs/AV/AV_Core.cpp b/TAO/orbsvcs/orbsvcs/AV/AV_Core.cpp
index 92d501b3133..9cf546235b4 100644
--- a/TAO/orbsvcs/orbsvcs/AV/AV_Core.cpp
+++ b/TAO/orbsvcs/orbsvcs/AV/AV_Core.cpp
@@ -40,6 +40,28 @@ TAO_AV_Core::~TAO_AV_Core (void)
{
delete this->connector_registry_;
delete this->acceptor_registry_;
+
+ TAO_AV_TransportFactorySetItor transport_iter =
+ this->transport_factories_.begin();
+
+ while (transport_iter != this->transport_factories_.end())
+ {
+ delete (*transport_iter)->factory();
+ delete (*transport_iter);
+
+ transport_iter++;
+ }
+
+ TAO_AV_Flow_ProtocolFactorySetItor flow_iter =
+ this->flow_protocol_factories_.begin();
+
+ while (flow_iter != this->flow_protocol_factories_.end())
+ {
+ delete (*flow_iter)->factory();
+ delete (*flow_iter);
+
+ flow_iter++;
+ }
}
CORBA::ORB_ptr
@@ -139,7 +161,7 @@ TAO_AV_Core::init_forward_flows (TAO_Base_StreamEndPoint *endpoint,
TAO_AV_Core::EndPoint direction,
AVStreams::flowSpec &flow_spec)
{
- if (TAO_debug_level > 0)
+ if (TAO_debug_level > 0)
ACE_DEBUG ((LM_DEBUG,
"TAO_AV_Core::init_forward_flows\n"));
@@ -188,7 +210,7 @@ TAO_AV_Core::init_forward_flows (TAO_Base_StreamEndPoint *endpoint,
ACE_Addr *address = entry->address ();
if (address != 0)
{
- if (TAO_debug_level > 0)
+ if (TAO_debug_level > 0)
ACE_DEBUG ((LM_DEBUG,
"address given for flow %s",
entry->flowname ()));
@@ -231,7 +253,7 @@ TAO_AV_Core::init_forward_flows (TAO_Base_StreamEndPoint *endpoint,
result = event_handler->reactor ()->remove_handler (event_handler,
ACE_Event_Handler::READ_MASK);
if (result < 0)
- if (TAO_debug_level > 0)
+ if (TAO_debug_level > 0)
ACE_DEBUG ((LM_DEBUG,
"TAO_AV_Core::init_forward_flows: remove_handler failed\n"));
#endif /*ACE_HAS_RAPI*/
@@ -344,15 +366,18 @@ TAO_AV_Core::init_forward_flows (TAO_Base_StreamEndPoint *endpoint,
for (;connect != connect_end; ++connect)
{
ACE_Addr *local_addr;
+ ACE_Addr *local_control_addr;
local_addr = (*connect)->get_local_addr ();
- if (result == 0)
+ local_control_addr = (*connect)->get_local_control_addr ();
+ if (local_addr != 0)
{
TAO_Reverse_FlowSpec_Entry entry ((*connect)->flowname (),
(*connect)->direction_str (),
(*connect)->format (),
(*connect)->flow_protocol_str (),
(*connect)->carrier_protocol_str (),
- local_addr);
+ local_addr,
+ local_control_addr);
int len = new_flowspec.length ();
if (i == len)
@@ -367,16 +392,18 @@ TAO_AV_Core::init_forward_flows (TAO_Base_StreamEndPoint *endpoint,
connect != connect_end; ++connect)
{
ACE_Addr *local_addr;
+ ACE_Addr *local_control_addr;
local_addr = (*connect)->get_local_addr ();
- if (result == 0)
+ local_control_addr = (*connect)->get_local_control_addr ();
+ if (local_addr != 0)
{
-
TAO_Reverse_FlowSpec_Entry entry ((*connect)->flowname (),
(*connect)->direction_str (),
(*connect)->format (),
(*connect)->flow_protocol_str (),
(*connect)->carrier_protocol_str (),
- local_addr);
+ local_addr,
+ local_control_addr);
int len = new_flowspec.length ();
if (i == len)
@@ -472,7 +499,7 @@ TAO_AV_Core::init_reverse_flows (TAO_Base_StreamEndPoint *endpoint,
int result = -1;
switch (direction)
{
-
+
case TAO_AV_Core::TAO_AV_ENDPOINT_A:
{
result = this->connector_registry_->open (endpoint,
@@ -547,6 +574,49 @@ TAO_AV_Core::get_connector (const char *flowname)
return 0;
}
+TAO_AV_Flow_Protocol_Factory *
+TAO_AV_Core::get_flow_protocol_factory(const char *flow_protocol)
+{
+ if (flow_protocol == 0)
+ return 0;
+
+ for (TAO_AV_Flow_ProtocolFactorySetItor control_flow_factory =
+ this->flow_protocol_factories_.begin ();
+ control_flow_factory !=
+ this->flow_protocol_factories_.end ();
+ ++control_flow_factory)
+ {
+ if ((*control_flow_factory)->factory ()->match_protocol (flow_protocol))
+ {
+ return (*control_flow_factory)->factory ();
+ }
+ }
+
+ // Not found.
+ return 0;
+}
+
+TAO_AV_Transport_Factory *
+TAO_AV_Core::get_transport_factory(const char *transport_protocol)
+{
+ if (transport_protocol == 0)
+ return 0;
+
+ for (TAO_AV_TransportFactorySetItor transport_factory =
+ this->transport_factories_.begin ();
+ transport_factory != this->transport_factories_.end ();
+ ++transport_factory)
+ {
+ if ((*transport_factory)->factory ()->match_protocol (transport_protocol))
+ {
+ return (*transport_factory)->factory ();
+ }
+ }
+
+ // Not found.
+ return 0;
+}
+
int
TAO_AV_Core::load_default_transport_factories (void)
{
@@ -555,7 +625,7 @@ TAO_AV_Core::load_default_transport_factories (void)
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_str);
if (udp_factory == 0)
@@ -565,7 +635,7 @@ TAO_AV_Core::load_default_transport_factories (void)
"(%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);
@@ -588,7 +658,7 @@ TAO_AV_Core::load_default_transport_factories (void)
"(%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);
@@ -713,7 +783,7 @@ TAO_AV_Core::load_default_flow_protocol_factories (void)
this->flow_protocol_factories_.insert (udp_item);
#ifdef ACE_HAS_RAPI
-
+
const char *udp_qos_flow = "UDP_QoS_Flow_Factory";
TAO_AV_Flow_Protocol_Factory *udp_qos_flow_factory = 0;
TAO_AV_Flow_Protocol_Item *udp_qos_flow_item = 0;
@@ -845,7 +915,7 @@ TAO_AV_Core::init_flow_protocol_factories (void)
{
ACE_DEBUG ((LM_DEBUG,
"Loading default flow protocol factories\n"));
-
+
this->load_default_flow_protocol_factories ();
}
else
@@ -857,7 +927,7 @@ TAO_AV_Core::init_flow_protocol_factories (void)
ACE_DEBUG ((LM_DEBUG,
"%s \n",
name.c_str ()));
-
+
(*factory)->factory (
ACE_Dynamic_Service<TAO_AV_Flow_Protocol_Factory>::instance (name.c_str ()));
if ((*factory)->factory () == 0)
diff --git a/TAO/orbsvcs/orbsvcs/AV/AV_Core.h b/TAO/orbsvcs/orbsvcs/AV/AV_Core.h
index 2e12c35b9a3..e6714f92db1 100644
--- a/TAO/orbsvcs/orbsvcs/AV/AV_Core.h
+++ b/TAO/orbsvcs/orbsvcs/AV/AV_Core.h
@@ -27,7 +27,9 @@ class TAO_AV_Acceptor;
class TAO_AV_Connector;
class TAO_FlowSpec_Entry;
class TAO_AV_Transport_Item;
+class TAO_AV_Transport_Factory;
class TAO_AV_Flow_Protocol_Item;
+class TAO_AV_Flow_Protocol_Factory;
typedef ACE_Unbounded_Set <TAO_FlowSpec_Entry*> TAO_AV_FlowSpecSet;
typedef ACE_Unbounded_Set_Iterator <TAO_FlowSpec_Entry*> TAO_AV_FlowSpecSetItor;
@@ -41,7 +43,7 @@ typedef ACE_Unbounded_Set_Iterator<TAO_AV_Flow_Protocol_Item*> TAO_AV_Flow_Proto
/**
* @class TAO_AV_Core
- * @brief This class encapsulates access to the TAO AV Core's resources
+ * @brief This class encapsulates access to the TAO AV Core's resources
* and its state.
*/
class TAO_AV_Export TAO_AV_Core
@@ -67,6 +69,13 @@ public:
TAO_AV_QOS_UDP = 12
};
+ enum Flow_Component
+ {
+ TAO_AV_DATA = 1,
+ TAO_AV_CONTROL = 2,
+ TAO_AV_BOTH = 3
+ };
+
/// Default constructor.
TAO_AV_Core (void);
@@ -102,6 +111,8 @@ public:
// = Get the protocol factories
/// = Set/get the <ACE_Reactor>.
+ TAO_AV_Flow_Protocol_Factory *get_flow_protocol_factory(const char *flow_protocol);
+ TAO_AV_Transport_Factory *get_transport_factory(const char *transport_protocol);
TAO_AV_Flow_ProtocolFactorySet *flow_protocol_factories (void);
TAO_AV_TransportFactorySet *transport_factories (void);
void reactor (ACE_Reactor *r);
diff --git a/TAO/orbsvcs/orbsvcs/AV/Endpoint_Strategy_T.cpp b/TAO/orbsvcs/orbsvcs/AV/Endpoint_Strategy_T.cpp
index a5daa017629..dbeadcf634a 100644
--- a/TAO/orbsvcs/orbsvcs/AV/Endpoint_Strategy_T.cpp
+++ b/TAO/orbsvcs/orbsvcs/AV/Endpoint_Strategy_T.cpp
@@ -129,7 +129,7 @@ TAO_AV_Endpoint_Reactive_Strategy <T_StreamEndpoint, T_VDev, T_MediaCtrl>::activ
// Activate the mediactrl object under the root poa.
CORBA::String_var mediactrl_ior = this->activate_with_poa (media_ctrl,
ACE_TRY_ENV);
-
+
ACE_TRY_CHECK;
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 ()));
@@ -137,17 +137,20 @@ TAO_AV_Endpoint_Reactive_Strategy <T_StreamEndpoint, T_VDev, T_MediaCtrl>::activ
// Associate the media controller object reference with the vdev, as per the OMG spec
CORBA::Any anyval;
- CORBA::Object_var media_ctrl_obj
+ CORBA::Object_var media_ctrl_obj
= media_ctrl->_this (ACE_TRY_ENV);
ACE_TRY_CHECK;
-
+ media_ctrl->_remove_ref (ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+
anyval <<= this->orb_->object_to_string (media_ctrl_obj.in (),
ACE_TRY_ENV);
ACE_TRY_CHECK;
-
- this->vdev_->define_property ("Related_MediaCtrl",
- anyval,
- ACE_TRY_ENV);
+
+ this->vdev_->define_property ("Related_MediaCtrl",
+ anyval,
+ ACE_TRY_ENV);
+
ACE_TRY_CHECK;
}
ACE_CATCHANY
diff --git a/TAO/orbsvcs/orbsvcs/AV/FlowSpec_Entry.cpp b/TAO/orbsvcs/orbsvcs/AV/FlowSpec_Entry.cpp
index 1c853386025..27afeee6e72 100644
--- a/TAO/orbsvcs/orbsvcs/AV/FlowSpec_Entry.cpp
+++ b/TAO/orbsvcs/orbsvcs/AV/FlowSpec_Entry.cpp
@@ -5,6 +5,7 @@
//------------------------------------------------------------
#include "FlowSpec_Entry.h"
+#include "Protocol_Factory.h"
#include "tao/debug.h"
@@ -17,9 +18,12 @@
// constructor.
TAO_FlowSpec_Entry::TAO_FlowSpec_Entry (void)
:address_ (0),
+ control_address_ (0),
address_str_ (),
format_ (),
direction_ (TAO_AV_INVALID),
+ direction_str_ (),
+ flowname_ (),
protocol_ (TAO_AV_Core::TAO_AV_NOPROTOCOL),
carrier_protocol_ (),
flow_protocol_ (),
@@ -27,10 +31,15 @@ TAO_FlowSpec_Entry::TAO_FlowSpec_Entry (void)
entry_ (),
is_multicast_ (0),
peer_addr_ (0),
+ peer_control_addr_ (0),
local_addr_ (0),
+ local_control_addr_ (0),
transport_ (0),
+ control_transport_ (0),
handler_ (0),
+ control_handler_ (0),
protocol_object_ (0),
+ control_protocol_object_ (0),
role_ (TAO_AV_INVALID_ROLE)
{
}
@@ -41,8 +50,10 @@ TAO_FlowSpec_Entry::TAO_FlowSpec_Entry (const char *flowname,
const char *format_name,
const char *flow_protocol,
const char *carrier_protocol,
- ACE_Addr *address)
+ ACE_Addr *address,
+ ACE_Addr *control_address)
:address_ (address),
+ control_address_ (control_address),
address_str_ (),
format_ (format_name),
direction_str_ (direction ),
@@ -53,10 +64,15 @@ TAO_FlowSpec_Entry::TAO_FlowSpec_Entry (const char *flowname,
entry_ (),
is_multicast_ (0),
peer_addr_ (0),
+ peer_control_addr_ (0),
local_addr_ (0),
+ local_control_addr_ (0),
transport_ (0),
+ control_transport_ (0),
handler_ (0),
+ control_handler_ (0),
protocol_object_ (0),
+ control_protocol_object_ (0),
role_ (TAO_AV_INVALID_ROLE)
{
this->set_protocol ();
@@ -70,6 +86,7 @@ TAO_FlowSpec_Entry::TAO_FlowSpec_Entry (const char *flowname,
const char *flow_protocol,
const char *address)
:address_ (0),
+ control_address_ (0),
address_str_ ( address ),
format_ ( format_name ),
direction_str_ ( direction ),
@@ -80,25 +97,43 @@ TAO_FlowSpec_Entry::TAO_FlowSpec_Entry (const char *flowname,
entry_ (),
is_multicast_ (0),
peer_addr_ (0),
+ peer_control_addr_ (0),
local_addr_ (0),
+ local_control_addr_ (0),
transport_ (0),
+ control_transport_ (0),
handler_ (0),
+ control_handler_ (0),
protocol_object_ (0),
+ control_protocol_object_ (0),
role_ (TAO_AV_INVALID_ROLE)
{
- ACE_CString cstring(this->address_str_);
- int colon_pos = cstring.find (':');
- if (colon_pos != cstring.npos)
- cstring[colon_pos] = ';';
- this->address_str_ = cstring;
this->parse_flow_protocol_string (this->flow_protocol_.c_str() );
- this->parse_address (this->address_str_.c_str() );
+ this->parse_address (this->address_str_.c_str(), TAO_AV_Core::TAO_AV_DATA );
this->set_direction (this->direction_str_.c_str() );
}
// Destructor.
TAO_FlowSpec_Entry::~TAO_FlowSpec_Entry (void)
{
+ if (this->address_)
+ delete this->address_;
+
+ if (this->control_address_)
+ delete this->control_address_;
+
+ if (this->protocol_object_)
+ delete this->protocol_object_;
+
+ if (this->control_protocol_object_)
+ delete this->control_protocol_object_;
+
+ if (this->handler_)
+ delete this->handler_;
+
+ if (this->control_handler_)
+ delete this->control_handler_;
+
}
int
@@ -156,8 +191,6 @@ TAO_FlowSpec_Entry::set_protocol (void)
ACE_DEBUG ((LM_DEBUG,"TAO_FlowSpec_Entry::set_protocol:%s %x\n",buf, inet_addr->get_ip_address ()));
if (IN_CLASSD (inet_addr->get_ip_address ()))
{
-
-
this->is_multicast_ = 1;
switch (this->protocol_)
{
@@ -179,13 +212,15 @@ TAO_FlowSpec_Entry::set_protocol (void)
}
int
-TAO_FlowSpec_Entry::parse_address (const char *address)
+TAO_FlowSpec_Entry::parse_address (const char *address,
+ TAO_AV_Core::Flow_Component flow_comp)
{
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 ();
@@ -194,56 +229,140 @@ TAO_FlowSpec_Entry::parse_address (const char *address)
if (protocol_tokenizer [1] != 0)
{
- TAO_Tokenizer address_tokenizer (protocol_tokenizer[1],';');
- ACE_CString addr;
- // convert to the ACE_Addr format.
- addr = address_tokenizer[0];
- addr += ":";
- addr += address_tokenizer[1];
+ if ( (flow_comp == TAO_AV_Core::TAO_AV_DATA) ||
+ (flow_comp == TAO_AV_Core::TAO_AV_CONTROL) )
+ {
+ ACE_CString addr;
+ addr += protocol_tokenizer[1];
- switch (this->protocol_)
+ 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:
+ case TAO_AV_Core::TAO_AV_QOS_UDP:
+ {
+ if (flow_comp == TAO_AV_Core::TAO_AV_DATA)
+ this->address_str_ = addr;
+ ACE_INET_Addr *inet_addr;
+ ACE_NEW_RETURN (inet_addr,
+ ACE_INET_Addr (addr.c_str() ),
+ -1);
+ if (flow_comp == TAO_AV_Core::TAO_AV_DATA)
+ this->address_ = inet_addr;
+ else
+ this->control_address_ = inet_addr;
+
+ if (TAO_debug_level > 0)
+ ACE_DEBUG ((LM_DEBUG, "TAO_FlowSpec_Entry::parse_address %s %x\n", address,inet_addr->get_ip_address () ));
+
+ if (IN_CLASSD (inet_addr->get_ip_address ()))
+ {
+ if (TAO_debug_level > 0)
+ ACE_DEBUG ((LM_DEBUG, "TAO_FlowSpec_Entry::parse_address is multicast\n"));
+
+ 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"));
+ }
+ }
+ else
{
- 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:
- case TAO_AV_Core::TAO_AV_QOS_UDP:
- {
- this->address_str_ = addr;
- ACE_INET_Addr *inet_addr;
- ACE_NEW_RETURN (inet_addr,
- ACE_INET_Addr (addr.c_str() ),
- -1);
- this->address_ = inet_addr;
- if (TAO_debug_level > 0)
- ACE_DEBUG ((LM_DEBUG, "TAO_FlowSpec_Entry::parse_address %s %x\n", address,inet_addr->get_ip_address () ));
-
- if (IN_CLASSD (inet_addr->get_ip_address ()))
+ TAO_Tokenizer address_tokenizer (protocol_tokenizer[1], ':');
+ TAO_Tokenizer port_tokenizer (address_tokenizer[1], ';');
+ ACE_CString addr;
+ addr += address_tokenizer[0];
+ addr += ":";
+ addr += port_tokenizer[0];
+
+ short control_port = ACE_OS::atoi(port_tokenizer[0]) + 1;
+ char control_port_str[6];
+ sprintf (control_port_str, "%d", control_port);
+
+ ACE_CString control_addr = "";
+ if (ACE_OS::strcasecmp (this->carrier_protocol_.c_str(),"RTP/UDP") == 0)
+ {
+ control_addr += address_tokenizer[0];
+ control_addr += ":";
+ if (port_tokenizer[1] != 0)
+ control_addr += port_tokenizer[1];
+ else
+ control_addr += control_port_str;
+ }
+
+ 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:
+ case TAO_AV_Core::TAO_AV_QOS_UDP:
{
+ this->address_str_ = addr;
+ ACE_INET_Addr *inet_addr;
+ ACE_NEW_RETURN (inet_addr,
+ ACE_INET_Addr (addr.c_str() ),
+ -1);
+ this->address_ = inet_addr;
if (TAO_debug_level > 0)
- ACE_DEBUG ((LM_DEBUG, "TAO_FlowSpec_Entry::parse_address is multicast\n"));
+ ACE_DEBUG ((LM_DEBUG, "TAO_FlowSpec_Entry::parse_address %s %x\n", address,inet_addr->get_ip_address () ));
- this->is_multicast_ = 1;
- switch (this->protocol_)
+ if (ACE_OS::strcasecmp (this->carrier_protocol_.c_str(),"RTP/UDP") == 0)
{
- 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;
+ ACE_INET_Addr *control_inet_addr;
+ ACE_NEW_RETURN (control_inet_addr,
+ ACE_INET_Addr (control_addr.c_str() ),
+ -1);
+ this->control_address_ = control_inet_addr;
+ if (TAO_debug_level > 0)
+ ACE_DEBUG ((LM_DEBUG, "TAO_FlowSpec_Entry::parse_address %s %x\n", address,control_inet_addr->get_ip_address () ));
+ }
+
+ if (IN_CLASSD (inet_addr->get_ip_address ()))
+ {
+ if (TAO_debug_level > 0)
+ ACE_DEBUG ((LM_DEBUG, "TAO_FlowSpec_Entry::parse_address is multicast\n"));
+
+ 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"));
+ break;
+ default:
+ if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"ATM support not added yet\n"));
+ }
}
}
return 0;
@@ -267,9 +386,7 @@ TAO_FlowSpec_Entry::get_local_addr_str (void)
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 ();
}
default:
@@ -284,6 +401,7 @@ TAO_FlowSpec_Entry::get_local_addr_str (void)
// default constructor.
TAO_Forward_FlowSpec_Entry::TAO_Forward_FlowSpec_Entry (void)
{
+ // no-op.
}
// constructor to construct the entry from the arguments.
@@ -292,14 +410,17 @@ TAO_Forward_FlowSpec_Entry::TAO_Forward_FlowSpec_Entry (const char *flowname,
const char *format_name ,
const char *flow_protocol ,
const char *carrier_protocol ,
- ACE_Addr *address )
+ ACE_Addr *address,
+ ACE_Addr *control_address )
:TAO_FlowSpec_Entry (flowname,
direction,
format_name,
flow_protocol,
carrier_protocol,
- address)
+ address,
+ control_address)
{
+ // no-op.
}
// constructor to construct the entry from the arguments.
@@ -314,6 +435,12 @@ TAO_Forward_FlowSpec_Entry::TAO_Forward_FlowSpec_Entry (const char *flowname,
flow_protocol,
address)
{
+ // no-op.
+}
+
+TAO_Forward_FlowSpec_Entry::~TAO_Forward_FlowSpec_Entry (void)
+{
+ // no-op.
}
int
@@ -323,6 +450,11 @@ TAO_Forward_FlowSpec_Entry::parse (const char *flowSpec_entry)
this->flowname_ = tokenizer [TAO_AV_FLOWNAME];
+ if (TAO_debug_level > 0)
+ ACE_DEBUG ((LM_DEBUG,
+ "TAO_Forward_FlowSpec_Entry::parse %s\n",
+ flowSpec_entry));
+
if (tokenizer [TAO_AV_DIRECTION] != 0)
this->set_direction (tokenizer [TAO_AV_DIRECTION]);
@@ -330,7 +462,7 @@ TAO_Forward_FlowSpec_Entry::parse (const char *flowSpec_entry)
this->format_ = tokenizer [TAO_AV_FORMAT];
if (tokenizer [TAO_AV_ADDRESS] != 0)
- if (this->parse_address (tokenizer [TAO_AV_ADDRESS]) < 0)
+ if (this->parse_address (tokenizer [TAO_AV_ADDRESS], TAO_AV_Core::TAO_AV_BOTH) < 0)
return -1;
if (tokenizer [TAO_AV_FLOW_PROTOCOL] != 0)
@@ -363,10 +495,11 @@ const char *
TAO_Forward_FlowSpec_Entry::entry_to_string (void)
{
if (this->flowname_.length() == 0)
- return 0;
+ return "";
char address [BUFSIZ];
ACE_CString address_str;
+
if (this->address_ != 0)
{
switch (this->protocol_)
@@ -388,19 +521,76 @@ TAO_Forward_FlowSpec_Entry::entry_to_string (void)
break;
}
ACE_CString cstring (address);
- int colon_pos = cstring.find (':');
- if (colon_pos != cstring.npos)
- cstring[colon_pos] = ';';
-
address_str = this->carrier_protocol_;
address_str += "=";
address_str += cstring;
}
- else{
- address_str = this->carrier_protocol_;
- }
+ else
+ {
+ address_str = this->carrier_protocol_;
+ }
+
+ if ( (this->address_ != 0) &&
+ (this->control_address_ == 0) &&
+ (ACE_OS::strncasecmp (this->flow_protocol_.c_str(), "RTP", 3) == 0))
+ {
+ u_short control_port;
+
+ 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_QOS_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_);
+ control_port = inet_addr->get_port_number() + 1;
+ ACE_INET_Addr *inet_control_addr;
+ ACE_NEW_RETURN (inet_control_addr,
+ ACE_INET_Addr (control_port, inet_addr->get_host_addr ()),
+ "");
+ this->control_address_ = inet_control_addr;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (this->control_address_ != 0)
+ {
+ u_short control_port;
+
+ 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_QOS_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->control_address_);
+ control_port = inet_addr->get_port_number();
+ }
+ break;
+ default:
+ break;
+ }
+
+ address_str += ";";
+ char port_str[10];
+ sprintf(port_str, "%u", control_port);
+ address_str += port_str;
+ }
this->entry_ = this->flowname_;
this->entry_ += "\\";
@@ -423,6 +613,7 @@ TAO_Forward_FlowSpec_Entry::entry_to_string (void)
//default constructor.
TAO_Reverse_FlowSpec_Entry::TAO_Reverse_FlowSpec_Entry (void)
{
+ // no-op
}
// constructor to construct an entry from the arguments.
@@ -431,14 +622,17 @@ TAO_Reverse_FlowSpec_Entry::TAO_Reverse_FlowSpec_Entry (const char *flowname,
const char *format_name ,
const char *flow_protocol ,
const char *carrier_protocol,
- ACE_Addr *address)
+ ACE_Addr *address,
+ ACE_Addr *control_address )
:TAO_FlowSpec_Entry (flowname,
direction,
format_name,
flow_protocol,
carrier_protocol,
- address)
+ address,
+ control_address)
{
+ // no-op
}
// constructor to construct an entry from the arguments.
@@ -453,6 +647,12 @@ TAO_Reverse_FlowSpec_Entry::TAO_Reverse_FlowSpec_Entry (const char *flowname,
flow_protocol,
address)
{
+ // no-op.
+}
+
+TAO_Reverse_FlowSpec_Entry::~TAO_Reverse_FlowSpec_Entry (void)
+{
+ // no-op.
}
TAO_FlowSpec_Entry::Role
@@ -479,19 +679,24 @@ TAO_Reverse_FlowSpec_Entry::parse (const char *flowSpec_entry)
TAO_Tokenizer tokenizer (flowSpec_entry,'\\');
this->flowname_ = tokenizer [TAO_AV_FLOWNAME];
+ if (TAO_debug_level > 0)
+ ACE_DEBUG ((LM_DEBUG,
+ "TAO_Reverse_FlowSpec_Entry::parse %s\n",
+ flowSpec_entry));
+
if (tokenizer [TAO_AV_ADDRESS] != 0)
- if (this->parse_address (tokenizer [TAO_AV_ADDRESS]) < 0)
+ if (this->parse_address (tokenizer [TAO_AV_ADDRESS], TAO_AV_Core::TAO_AV_BOTH) < 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_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_FORMAT] != 0)
+// this->format_ = tokenizer [TAO_AV_FORMAT];
return 0;
}
@@ -501,13 +706,12 @@ const char *
TAO_Reverse_FlowSpec_Entry::entry_to_string (void)
{
if (this->flowname_.length() == 0)
- return 0;
+ return "";
char address [BUFSIZ];
ACE_CString address_str;
if (this->address_ != 0)
{
-
switch (this->protocol_)
{
case TAO_AV_Core::TAO_AV_RTP_UDP:
@@ -525,28 +729,57 @@ TAO_Reverse_FlowSpec_Entry::entry_to_string (void)
break;
}
ACE_CString cstring (address);
- int colon_pos = cstring.find (':');
- if (colon_pos != cstring.npos)
- cstring[colon_pos] = ';';
address_str = this->carrier_protocol_;
address_str += "=";
address_str += cstring;
}
- else{
- address_str = "";
- }
+ else
+ {
+ address_str = "";
+ }
+
+ if (this->control_address_ != 0)
+ {
+ u_short control_port;
+
+
+ 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_QOS_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->control_address_);
+ control_port = inet_addr->get_port_number();
+ }
+ break;
+ default:
+ break;
+ }
+
+ address_str += ";";
+ char port_str[10];
+ sprintf(port_str, "%u", control_port);
+ address_str += port_str;
+
+ }
this->entry_ = this->flowname_;
this->entry_ += "\\";
this->entry_ += address_str;
this->entry_ += "\\";
this->entry_ += this->flow_protocol_;
- this->entry_ += "\\";
- this->entry_ += this->direction_str_;
- this->entry_ += "\\";
- this->entry_ += format_;
+// this->entry_ += "\\";
+// this->entry_ += this->direction_str_;
+// this->entry_ += "\\";
+// this->entry_ += format_;
if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"entry_to_string: entry = %s\n",this->entry_.c_str() ));
return this->entry_.c_str();
diff --git a/TAO/orbsvcs/orbsvcs/AV/FlowSpec_Entry.h b/TAO/orbsvcs/orbsvcs/AV/FlowSpec_Entry.h
index 3fc8cf1d652..adb0ec1cb27 100644
--- a/TAO/orbsvcs/orbsvcs/AV/FlowSpec_Entry.h
+++ b/TAO/orbsvcs/orbsvcs/AV/FlowSpec_Entry.h
@@ -89,7 +89,8 @@ public:
const char *format_name,
const char *flow_protocol,
const char *carrier_protocol,
- ACE_Addr *address);
+ ACE_Addr *address,
+ ACE_Addr *control_address = 0);
TAO_FlowSpec_Entry (const char *flowname,
const char *direction,
@@ -119,6 +120,9 @@ public:
/// accessor to address of the carrier protocol.
ACE_Addr *address (void);
+ ACE_Addr *control_address (void);
+ void address (ACE_Addr *address);
+ void control_address (ACE_Addr *address);
/// Address in string format i. hostname:port.
const char * address_str (void) const;
@@ -140,18 +144,34 @@ public:
int set_peer_addr (ACE_Addr *peer_addr);
ACE_Addr *get_peer_addr (void);
- int set_local_addr (ACE_Addr *peer_addr);
+ int set_peer_control_addr (ACE_Addr *peer_control_addr);
+ ACE_Addr *get_peer_control_addr (void);
+
+ int set_local_addr (ACE_Addr *local_addr);
ACE_Addr *get_local_addr (void);
char *get_local_addr_str (void);
+ int set_local_control_addr (ACE_Addr *local_control_addr);
+ ACE_Addr *get_local_control_addr (void);
+ char *get_local_control_addr_str (void);
+
TAO_AV_Transport *transport (void);
void transport (TAO_AV_Transport *transport);
+ TAO_AV_Transport *control_transport (void);
+ void control_transport (TAO_AV_Transport *control_transport);
+
TAO_AV_Flow_Handler* handler (void);
void handler (TAO_AV_Flow_Handler *handler);
+ TAO_AV_Flow_Handler* control_handler (void);
+ void control_handler (TAO_AV_Flow_Handler *control_handler);
+
TAO_AV_Protocol_Object* protocol_object (void);
void protocol_object (TAO_AV_Protocol_Object *object);
+ TAO_AV_Protocol_Object* control_protocol_object (void);
+ void control_protocol_object (TAO_AV_Protocol_Object *object);
/// sets the address for this flow.
- int parse_address (const char *format_string);
+ int parse_address (const char *format_string,
+ TAO_AV_Core::Flow_Component flow_component);
/// returns true for a multicast address.
int is_multicast (void);
@@ -169,6 +189,7 @@ protected:
/// Addr information for the carrier protocol.
ACE_Addr *address_;
+ ACE_Addr *control_address_;
/// Addr in string format i.e hostname:port.
ACE_CString address_str_;
@@ -201,13 +222,19 @@ protected:
int is_multicast_;
ACE_Addr *peer_addr_;
+ ACE_Addr *peer_control_addr_;
ACE_Addr *local_addr_;
+ ACE_Addr *local_control_addr_;
TAO_AV_Transport *transport_;
+ TAO_AV_Transport *control_transport_;
TAO_AV_Flow_Handler *handler_;
+ TAO_AV_Flow_Handler *control_handler_;
TAO_AV_Protocol_Object *protocol_object_;
+ TAO_AV_Protocol_Object *control_protocol_object_;
Role role_;
};
+
/**
* @class TAO_Forward_FlowSpec_Entry
* @brief
@@ -231,7 +258,8 @@ public:
const char *format_name,
const char *flow_protocol,
const char *carrier_protocol,
- ACE_Addr *address);
+ ACE_Addr *address,
+ ACE_Addr *control_address = 0);
TAO_Forward_FlowSpec_Entry (const char *flowname,
const char *direction,
@@ -239,6 +267,8 @@ public:
const char *flow_protocol,
const char *address);
+ virtual ~TAO_Forward_FlowSpec_Entry (void);
+
/// converts the entry to a string.
virtual const char *entry_to_string (void);
@@ -271,7 +301,8 @@ public:
const char *format_name,
const char *flow_protocol,
const char *carrier_protocol,
- ACE_Addr *address);
+ ACE_Addr *address,
+ ACE_Addr *control_address = 0);
// Takes the address in protocol=endpoint form.
TAO_Reverse_FlowSpec_Entry (const char *flowname,
@@ -280,6 +311,8 @@ public:
const char *flow_protocol,
const char *address);
+ virtual ~TAO_Reverse_FlowSpec_Entry (void);
+
/// converts the entry to a string.
virtual const char *entry_to_string (void);
diff --git a/TAO/orbsvcs/orbsvcs/AV/FlowSpec_Entry.i b/TAO/orbsvcs/orbsvcs/AV/FlowSpec_Entry.i
index 110a4e40f9c..a15fbb6f00d 100644
--- a/TAO/orbsvcs/orbsvcs/AV/FlowSpec_Entry.i
+++ b/TAO/orbsvcs/orbsvcs/AV/FlowSpec_Entry.i
@@ -32,6 +32,13 @@ TAO_FlowSpec_Entry::parse_flow_protocol_string (const char *flow_string)
// do some flow protocol processing.
this->flow_protocol_ = flow_string;
}
+ if (ACE_OS::strncasecmp (flow_string,"rtp",3) == 0)
+ {
+ // TODO: this makes it work but should probably change
+// this->use_flow_protocol_ = 1;
+
+ this->flow_protocol_ = flow_string;
+ }
return 0;
}
@@ -85,6 +92,27 @@ TAO_FlowSpec_Entry::address (void)
}
ACE_INLINE
+void
+TAO_FlowSpec_Entry::address (ACE_Addr *addr)
+{
+ this->address_ = addr;
+}
+
+ACE_INLINE
+ACE_Addr *
+TAO_FlowSpec_Entry::control_address (void)
+{
+ return this->control_address_;
+}
+
+ACE_INLINE
+void
+TAO_FlowSpec_Entry::control_address (ACE_Addr *addr)
+{
+ this->control_address_ = addr;
+}
+
+ACE_INLINE
const char *
TAO_FlowSpec_Entry::address_str (void) const
{
@@ -132,6 +160,14 @@ TAO_FlowSpec_Entry::set_local_addr (ACE_Addr *local_addr)
}
ACE_INLINE
+int
+TAO_FlowSpec_Entry::set_local_control_addr (ACE_Addr *local_addr)
+{
+ this->local_control_addr_ = local_addr;
+ return 0;
+}
+
+ACE_INLINE
ACE_Addr*
TAO_FlowSpec_Entry::get_local_addr (void)
{
@@ -139,6 +175,13 @@ TAO_FlowSpec_Entry::get_local_addr (void)
}
ACE_INLINE
+ACE_Addr*
+TAO_FlowSpec_Entry::get_local_control_addr (void)
+{
+ return this->local_control_addr_;
+}
+
+ACE_INLINE
TAO_AV_Transport*
TAO_FlowSpec_Entry::transport (void)
{
@@ -153,6 +196,20 @@ TAO_FlowSpec_Entry::transport (TAO_AV_Transport *transport)
}
ACE_INLINE
+TAO_AV_Transport*
+TAO_FlowSpec_Entry::control_transport (void)
+{
+ return this->control_transport_;
+}
+
+ACE_INLINE
+void
+TAO_FlowSpec_Entry::control_transport (TAO_AV_Transport *control_transport)
+{
+ this->control_transport_ = control_transport;
+}
+
+ACE_INLINE
TAO_AV_Flow_Handler *
TAO_FlowSpec_Entry::handler (void)
{
@@ -160,10 +217,18 @@ TAO_FlowSpec_Entry::handler (void)
}
ACE_INLINE
+TAO_AV_Flow_Handler *
+TAO_FlowSpec_Entry::control_handler (void)
+{
+ return this->control_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 ())
// {
@@ -180,6 +245,13 @@ TAO_FlowSpec_Entry::handler (TAO_AV_Flow_Handler *handler)
}
ACE_INLINE
+void
+TAO_FlowSpec_Entry::control_handler (TAO_AV_Flow_Handler *handler)
+{
+ this->control_handler_ = handler;
+}
+
+ACE_INLINE
TAO_AV_Protocol_Object*
TAO_FlowSpec_Entry::protocol_object (void)
{
@@ -194,6 +266,20 @@ TAO_FlowSpec_Entry::protocol_object (TAO_AV_Protocol_Object *object)
}
ACE_INLINE
+TAO_AV_Protocol_Object*
+TAO_FlowSpec_Entry::control_protocol_object (void)
+{
+ return this->control_protocol_object_;
+}
+
+ACE_INLINE
+void
+TAO_FlowSpec_Entry::control_protocol_object (TAO_AV_Protocol_Object *object)
+{
+ this->control_protocol_object_ = object;
+}
+
+ACE_INLINE
int
TAO_FlowSpec_Entry::is_multicast (void)
{
diff --git a/TAO/orbsvcs/orbsvcs/AV/MCast.cpp b/TAO/orbsvcs/orbsvcs/AV/MCast.cpp
index 080db22025f..f6a6ab6a4dd 100644
--- a/TAO/orbsvcs/orbsvcs/AV/MCast.cpp
+++ b/TAO/orbsvcs/orbsvcs/AV/MCast.cpp
@@ -5,7 +5,7 @@
#include "AVStreams_i.h"
#include "tao/debug.h"
-#if !defined(__ACE_INLINE__)
+#if !defined (__ACE_INLINE__)
#include "MCast.i"
#endif /* __ACE_INLINE__ */
@@ -31,8 +31,8 @@ TAO_AV_UDP_MCast_Flow_Handler::~TAO_AV_UDP_MCast_Flow_Handler (void)
int
TAO_AV_UDP_MCast_Flow_Handler::handle_input (ACE_HANDLE /*fd*/)
{
- this->protocol_object_->handle_input ();
- return 0;
+ return this->protocol_object_->handle_input ();
+// return 0;
}
int
@@ -49,6 +49,11 @@ TAO_AV_UDP_MCast_Flow_Handler::get_handle (void) const
return this->get_mcast_socket ()->get_handle () ;
}
+void
+TAO_AV_UDP_MCast_Flow_Handler::set_peer_addr (ACE_INET_Addr *peer_addr)
+{
+ this->peer_addr_ = peer_addr;
+}
//------------------------------------------------------------
// TAO_AV_UDP_MCast_Transport
@@ -161,6 +166,7 @@ TAO_AV_UDP_MCast_Transport::send (const char *buf,
// if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG,"to %s\n",addr));
return this->handler_->get_mcast_socket ()->send (buf, len);
+
}
ssize_t
diff --git a/TAO/orbsvcs/orbsvcs/AV/MCast.h b/TAO/orbsvcs/orbsvcs/AV/MCast.h
index 745aaa517b4..1f5330ff8c1 100644
--- a/TAO/orbsvcs/orbsvcs/AV/MCast.h
+++ b/TAO/orbsvcs/orbsvcs/AV/MCast.h
@@ -94,14 +94,15 @@ public:
/// Ctor
/// Dtor
TAO_AV_UDP_MCast_Flow_Handler (void);
- ~TAO_AV_UDP_MCast_Flow_Handler (void);
+ virtual ~TAO_AV_UDP_MCast_Flow_Handler (void);
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; }
+ void set_peer_addr (ACE_INET_Addr *peer_addr);
protected:
- ACE_INET_Addr peer_addr_;
+ ACE_INET_Addr *peer_addr_;
ACE_SOCK_Dgram_Mcast *dgram_mcast_;
};
diff --git a/TAO/orbsvcs/orbsvcs/AV/Protocol_Factory.cpp b/TAO/orbsvcs/orbsvcs/AV/Protocol_Factory.cpp
index 9f491217f05..56379f64ac2 100644
--- a/TAO/orbsvcs/orbsvcs/AV/Protocol_Factory.cpp
+++ b/TAO/orbsvcs/orbsvcs/AV/Protocol_Factory.cpp
@@ -49,6 +49,7 @@ TAO_AV_Protocol_Object::TAO_AV_Protocol_Object (void)
:transport_ (0),
callback_ (0)
{
+ // no-op.
}
TAO_AV_Protocol_Object::TAO_AV_Protocol_Object (TAO_AV_Callback *callback,
@@ -56,6 +57,7 @@ TAO_AV_Protocol_Object::TAO_AV_Protocol_Object (TAO_AV_Callback *callback,
:transport_ (transport),
callback_ (callback)
{
+ // no-op.
}
int
@@ -69,7 +71,6 @@ TAO_AV_Protocol_Object::open (TAO_AV_Callback *callback,
TAO_AV_Protocol_Object::~TAO_AV_Protocol_Object (void)
{
- //no-op
}
int
diff --git a/TAO/orbsvcs/orbsvcs/AV/QoS_UDP.cpp b/TAO/orbsvcs/orbsvcs/AV/QoS_UDP.cpp
index d41fa1d5a16..dcf151a4691 100644
--- a/TAO/orbsvcs/orbsvcs/AV/QoS_UDP.cpp
+++ b/TAO/orbsvcs/orbsvcs/AV/QoS_UDP.cpp
@@ -76,7 +76,7 @@ TAO_AV_UDP_QoS_Session_Helper::set_qos (ACE_Flow_Spec &ace_flow_spec,
if (TAO_debug_level > 0)
ACE_DEBUG ((LM_DEBUG,
"Filled up the Receiver QoS parameters\n"));
-
+
}
ACE_QoS_Manager qos_manager = handler->get_socket ()->qos_manager ();
@@ -127,13 +127,13 @@ TAO_AV_UDP_QoS_Session_Helper::open_qos_session (TAO_AV_UDP_QoS_Flow_Handler *ha
// A QoS session is defined by the 3-tuple [DestAddr, DestPort,
// Protocol]. Initialize the QoS session.
if (qos_session->open (dest_addr,
- IPPROTO_UDP) == -1)
+ IPPROTO_UDP) == -1)
ACE_ERROR_RETURN ((LM_ERROR,
- "Error in opening the QoS session\n"),
- 0);
+ "Error in opening the QoS session\n"),
+ 0);
else
ACE_DEBUG ((LM_DEBUG,
- "QoS session opened successfully\n"));
+ "QoS session opened successfully\n"));
if (handler->flowspec_entry ()->role () == TAO_FlowSpec_Entry::TAO_AV_PRODUCER)
{
@@ -274,7 +274,7 @@ TAO_AV_UDP_QoS_Flow_Handler::translate (CosPropertyService::Properties &qos_para
ace_flow_spec->priority (priority);
}
}
-
+
return 0;
}
@@ -343,13 +343,13 @@ TAO_AV_UDP_QoS_Flow_Handler::handle_qos (ACE_HANDLE /*fd*/)
{
resv_confirm = 1;
}
-
+
if (this->qos_session_->flags () == ACE_QoS_Session::ACE_QOS_SENDER)
{
if (this->qos_session_->rsvp_event_type () == ACE_QoS_Session::RSVP_RESV_EVENT)
{
if( TAO_debug_level > 0 )
- {
+ {
ACE_DEBUG ((LM_DEBUG,
"(%N,%l) Resv Event Received\n"));
}
@@ -371,7 +371,7 @@ TAO_AV_UDP_QoS_Flow_Handler::handle_qos (ACE_HANDLE /*fd*/)
this->translate (ace_flow_spec,
new_qos [0].QoSParams);
}
-
+
AVStreams::Negotiator_var remote_negotiator;
this->negotiator_->negotiate (remote_negotiator.in (),
new_qos,
@@ -392,7 +392,7 @@ TAO_AV_UDP_QoS_Flow_Handler::handle_qos (ACE_HANDLE /*fd*/)
&qos_manager,
ace_qos);
}
- }
+ }
return 0;
}
@@ -511,12 +511,12 @@ TAO_AV_UDP_QoS_Flow_Handler::set_remote_address (ACE_Addr *address)
ACE_ERROR_RETURN ((LM_ERROR,
"QoS Session Open Failed (%N|%l)\n"),
-1);
-
+
ACE_INET_Addr local_addr;
this->get_socket ()->get_local_addr (local_addr);
this->qos_session_->source_port (local_addr.get_port_number ());
-
+
if (helper.activate_qos_handler (this->qos_session_,
this) == -1)
ACE_ERROR_RETURN ((LM_ERROR,
@@ -648,7 +648,7 @@ TAO_AV_UDP_QoS_Transport::send (const ACE_Message_Block *mblk,
}
size_t bytes_sent = 0;
-
+
// Check for remaining buffers to be sent!
if (iovcnt != 0)
{
@@ -670,7 +670,7 @@ TAO_AV_UDP_QoS_Transport::send (const ACE_Message_Block *mblk,
if (n < 1)
return n;
-
+
nbytes += bytes_sent;
}
@@ -682,7 +682,7 @@ TAO_AV_UDP_QoS_Transport::send (const char *buf,
size_t len,
ACE_Time_Value *)
{
- if (TAO_debug_level > 0)
+ if (TAO_debug_level > 0)
ACE_DEBUG ((LM_DEBUG,
"(%N,%l) TAO_AV_UDP_QoS_Transport::send "));
@@ -796,8 +796,11 @@ int
TAO_AV_UDP_QoS_Acceptor::open (TAO_Base_StreamEndPoint *endpoint,
TAO_AV_Core *av_core,
TAO_FlowSpec_Entry *entry,
- TAO_AV_Flow_Protocol_Factory *factory)
+ TAO_AV_Flow_Protocol_Factory *factory,
+ TAO_AV_Core::Flow_Component flow_comp)
{
+ ACE_UNUSED_ARG (flow_comp);
+
if (TAO_debug_level > 0)
ACE_DEBUG ((LM_DEBUG,
"(%N,%l) TAO_AV_UDP_QoS_Acceptor::open "));
@@ -832,8 +835,11 @@ int
TAO_AV_UDP_QoS_Acceptor::open_default (TAO_Base_StreamEndPoint *endpoint,
TAO_AV_Core *av_core,
TAO_FlowSpec_Entry *entry,
- TAO_AV_Flow_Protocol_Factory *factory)
+ TAO_AV_Flow_Protocol_Factory *factory,
+ TAO_AV_Core::Flow_Component flow_comp)
{
+ ACE_UNUSED_ARG (flow_comp);
+
this->av_core_ = av_core;
this->endpoint_ = endpoint;
this->entry_ = entry;
@@ -884,7 +890,7 @@ TAO_AV_UDP_QoS_Acceptor::open_i (ACE_INET_Addr *inet_addr)
FillQoSParams (qos_params,
0,
ace_qos);
-
+
TAO_AV_UDP_QoS_Flow_Handler* handler;
ACE_NEW_RETURN (handler,
@@ -937,7 +943,7 @@ TAO_AV_UDP_QoS_Acceptor::open_i (ACE_INET_Addr *inet_addr)
char dest_buf [BUFSIZ];
dest_addr.addr_to_string (dest_buf,
BUFSIZ);
-
+
if (TAO_debug_level > 0)
ACE_DEBUG ((LM_DEBUG,
"Session Address is %s\n",
@@ -950,7 +956,7 @@ TAO_AV_UDP_QoS_Acceptor::open_i (ACE_INET_Addr *inet_addr)
ACE_ERROR_RETURN ((LM_ERROR,
"QoS Session Open Failed (%N|%l)\n"),
-1);
-
+
handler->qos_session (this->qos_session_);
if (this->activate_svc_handler (handler) == -1)
@@ -972,7 +978,7 @@ TAO_AV_UDP_QoS_Acceptor::open_i (ACE_INET_Addr *inet_addr)
handler->translate (qos.QoSParams,
ace_flow_spec);
-
+
if (helper.set_qos (*ace_flow_spec,
handler) == -1)
@@ -1016,7 +1022,7 @@ TAO_AV_UDP_QoS_Acceptor::open_i (ACE_INET_Addr *inet_addr)
this->endpoint_->get_property_value ("Negotiator",
ACE_TRY_ENV);
ACE_TRY_CHECK_EX (negotiator);
-
+
*negotiator_any >>= negotiator;
handler->negotiator (negotiator);
}
@@ -1139,8 +1145,11 @@ TAO_AV_UDP_QoS_Connector::open (TAO_Base_StreamEndPoint *endpoint,
int
TAO_AV_UDP_QoS_Connector::connect (TAO_FlowSpec_Entry *entry,
- TAO_AV_Transport *&transport)
+ TAO_AV_Transport *&transport,
+ TAO_AV_Core::Flow_Component flow_comp)
{
+ ACE_UNUSED_ARG (flow_comp);
+
ACE_DECLARE_NEW_CORBA_ENV;
int result = 0;
this->entry_ = entry;
@@ -1167,7 +1176,7 @@ TAO_AV_UDP_QoS_Connector::connect (TAO_FlowSpec_Entry *entry,
ACE_INET_Addr *inet_addr = ACE_dynamic_cast (ACE_INET_Addr*,
entry->address ());
-
+
ACE_QoS_Params qos_params;
ACE_QoS* ace_qos = 0;
@@ -1255,7 +1264,7 @@ TAO_AV_UDP_QoS_Connector::connect (TAO_FlowSpec_Entry *entry,
qos);
if (qos_available == 0)
{
-
+
ACE_Flow_Spec* ace_flow_spec;
ACE_NEW_RETURN (ace_flow_spec,
ACE_Flow_Spec,
@@ -1284,7 +1293,7 @@ TAO_AV_UDP_QoS_Connector::connect (TAO_FlowSpec_Entry *entry,
flow_handler->transport ());
AVStreams::Negotiator_ptr negotiator;
-
+
ACE_TRY_EX (negotiator)
{
CORBA::Any_ptr negotiator_any =
diff --git a/TAO/orbsvcs/orbsvcs/AV/QoS_UDP.h b/TAO/orbsvcs/orbsvcs/AV/QoS_UDP.h
index 981f1c5a2da..7b60c2fa503 100644
--- a/TAO/orbsvcs/orbsvcs/AV/QoS_UDP.h
+++ b/TAO/orbsvcs/orbsvcs/AV/QoS_UDP.h
@@ -161,12 +161,16 @@ public:
virtual int open (TAO_Base_StreamEndPoint *endpoint,
TAO_AV_Core *av_core,
TAO_FlowSpec_Entry *entry,
- TAO_AV_Flow_Protocol_Factory *factory);
+ TAO_AV_Flow_Protocol_Factory *factory,
+ TAO_AV_Core::Flow_Component flow_comp =
+ TAO_AV_Core::TAO_AV_DATA);
virtual int open_default (TAO_Base_StreamEndPoint *endpoint,
TAO_AV_Core *av_core,
TAO_FlowSpec_Entry *entry,
- TAO_AV_Flow_Protocol_Factory *factory);
+ TAO_AV_Flow_Protocol_Factory *factory,
+ TAO_AV_Core::Flow_Component flow_comp =
+ TAO_AV_Core::TAO_AV_DATA);
virtual int open_i (ACE_INET_Addr *address);
@@ -194,7 +198,9 @@ public:
TAO_AV_Flow_Protocol_Factory *factory);
virtual int connect (TAO_FlowSpec_Entry *entry,
- TAO_AV_Transport *&transport);
+ TAO_AV_Transport *&transport,
+ TAO_AV_Core::Flow_Component flow_comp =
+ TAO_AV_Core::TAO_AV_DATA);
virtual int activate_svc_handler (TAO_AV_UDP_QoS_Flow_Handler *handler);
virtual int close (void);
diff --git a/TAO/orbsvcs/orbsvcs/AV/RTCP.cpp b/TAO/orbsvcs/orbsvcs/AV/RTCP.cpp
index cd661516434..7f2197c0622 100644
--- a/TAO/orbsvcs/orbsvcs/AV/RTCP.cpp
+++ b/TAO/orbsvcs/orbsvcs/AV/RTCP.cpp
@@ -37,543 +37,303 @@
#include "RTCP.h"
#include "media-timer.h"
#include "tao/debug.h"
+#include "global.h"
+#include "md5.h"
+#include "RTCP_Packet.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)
+int
+TAO_AV_RTCP_Callback::receive_control_frame (ACE_Message_Block *data,
+ const ACE_Addr &peer_address)
{
- 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 length = data->length ();
+ int more = length;
+ char *buf_ptr = data->rd_ptr ();
+ char first_rtcp_packet = 1;
+ RTCP_Channel_In *c;
-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)
+ // This code performs the RTCP Header validity checks detailed in RFC 1889
+ // Appendix A.2
+
+ while (more > 0)
{
- if (*note)
- {
- nameslot = RTCP_SDES_NOTE;
- noteslot = RTCP_SDES_NAME;
- } else
+ // the second byte of the control packet is the type
+ switch ((unsigned char)buf_ptr[length - more + 1])
+ {
+ case RTCP_PT_SR:
{
- nameslot = RTCP_SDES_NAME;
- noteslot = RTCP_SDES_NOTE;
+ RTCP_SR_Packet sr(&buf_ptr[length-more],
+ &more);
+
+ if (!sr.is_valid(first_rtcp_packet))
+ ACE_DEBUG ((LM_DEBUG,
+ "TAO_AV_RTCP_Callback::receive_control_frame - "
+ "warning invalid rtcp packet\n"));
+
+ if (this->inputs_.find (sr.ssrc (), c) == -1)
+ {
+ ACE_NEW_RETURN (c,
+ RTCP_Channel_In (sr.ssrc (),
+ &peer_address),
+ -1);
+ this->inputs_.bind (sr.ssrc (), c);
+ }
+ c->updateStatistics (&sr);
+
+ if (TAO_debug_level > 0)
+ sr.dump ();
+ break;
}
- }
- 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);
-}
+ case RTCP_PT_RR:
+ {
+ RTCP_RR_Packet rr(&buf_ptr[length-more],
+ &more);
+
+ if (!rr.is_valid(first_rtcp_packet))
+ ACE_DEBUG ((LM_DEBUG,
+ "TAO_AV_RTCP_Callback::receive_control_frame - "
+ "warning invalid rtcp packet\n"));
+
+ if (this->inputs_.find (rr.ssrc (), c) == -1)
+ {
+ ACE_NEW_RETURN (c,
+ RTCP_Channel_In (rr.ssrc (),
+ &peer_address),
+ -1);
+ this->inputs_.bind (rr.ssrc (), c);
+ }
+
+ c->updateStatistics (&rr);
+
+ if (TAO_debug_level > 0)
+ rr.dump ();
+ break;
+ }
+ case RTCP_PT_SDES:
+ {
+ RTCP_SDES_Packet sdes (&buf_ptr[length-more],
+ &more);
-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"));
-}
+ if (!sdes.is_valid(first_rtcp_packet))
+ ACE_DEBUG ((LM_DEBUG,
+ "TAO_AV_RTCP_Callback::receive_control_frame - "
+ "warning invalid rtcp packet\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 = ACE_reinterpret_cast (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;
+ if (TAO_debug_level > 0)
+ sdes.dump ();
+ break;
+ }
+ case RTCP_PT_BYE:
+ {
+ RTCP_BYE_Packet bye (&buf_ptr[length-more],
+ &more);
- s->lts_ctrl (ACE_OS::gettimeofday ());
- s->sts_ctrl (ntohl (sr->sr_ntp.upper) << 16 |
- ntohl (sr->sr_ntp.lower) >> 16);
+ if (!bye.is_valid(first_rtcp_packet))
+ ACE_DEBUG ((LM_DEBUG,
+ "TAO_AV_RTCP_Callback::receive_control_frame - "
+ "warning invalid rtcp packet\n"));
- int cnt = flags >> 8 & 0x1f;
- parse_rr_records (ssrc, ACE_reinterpret_cast (rtcp_rr*, (sr + 1)), cnt, ep, addr);
-}
+ // Inform the listener that a source(s) has left the session
+ ACE_UINT32 *ssrc_list;
+ unsigned char length;
-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;
+ bye.ssrc_list(&ssrc_list, length);
- s->lts_ctrl (ACE_OS::gettimeofday ());
- int cnt = flags >> 8 & 0x1f;
- parse_rr_records (ssrc, ACE_reinterpret_cast (rtcp_rr*, (rh + 1)), cnt, ep, addr);
-}
+ for (int i=0; i<length; i++)
+ {
+ RTCP_Channel_In *c = 0;
-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 ());
+ // remove the channel from the list
+ this->inputs_.unbind(ssrc_list[i], c);
- u_char* cp = (u_char*) (p + 1);
- while (cp < ep)
- {
- char buf[256];
+ if (c != 0)
+ delete c;
+ }
- 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 (TAO_debug_level > 0)
+ bye.dump ();
- if (type >= RTCP_SDES_MIN && type <= RTCP_SDES_MAX)
- {
- memcpy (buf, (char*)&cp[2], len);
- buf[len] = 0;
- s->sdes (type, buf);
- }
- else
- /*XXX*/;
+ break;
+ }
+ case RTCP_PT_APP:
+ // If we receive one of these, ignore it.
+ ACE_DEBUG ((LM_DEBUG,
+ "TAO_AV_RTCP_Callback::receive_control_frame - "
+ "APP packet - ignore\n"));
+ more -= (4 + (ACE_UINT16)buf_ptr[length - more + 2]);
+ break;
+ default:
+ ACE_DEBUG ((LM_DEBUG,
+ "TAO_AV_RTCP_Callback::receive_control_frame - "
+ "UNKNOWN packet type %u; ignore the rest\n",
+ (int)buf_ptr[length - more + 1]));
+ more = 0;
+ }
+
+ first_rtcp_packet = 0;
- 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);
+ if (more != 0)
+ ACE_DEBUG ((LM_DEBUG,
+ "TAO_AV_RTCP_Callback::receive_control_frame - "
+ "Error in overall packet length\n"));
+ return 0;
}
-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;
+ACE_INT32 random32 (int);
- while (--cnt >= 0)
+ACE_UINT32
+TAO_AV_RTCP::alloc_srcid (ACE_UINT32 addr)
+{
+ struct
{
- 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;
- }
+ int type;
+ ACE_Time_Value tv;
+ pid_t pid;
+ pid_t pgid;
+ pid_t ppid;
+ uid_t uid;
+ gid_t gid;
+ } s;
+
+ s.type = addr;
+ s.tv = ACE_OS::gettimeofday ();
+ s.pid = ACE_OS::getpid();
+ s.pgid = ACE_OS::getpgid(s.pid);
+ s.ppid = ACE_OS::getppid();
+ s.uid = ACE_OS::getuid();
+ s.gid = ACE_OS::getgid();
+
+ unsigned char *string_val = (unsigned char *) &s;
+ int length = sizeof(s);
+
+ MD5_CTX context;
+ union
+ {
+ char c[16];
+ u_long x[4];
+ } digest;
+ ACE_UINT32 r;
+ int i;
+
+ MD5Init (&context);
+ MD5Update (&context, string_val, length);
+ MD5Final ((unsigned char*)&digest, &context);
+ r=0;
+ for (i=0; i<3; i++)
+ r ^= digest.x[i];
+
+ return r;
+
+/* used to be this
+ ACE_Time_Value tv = ACE_OS::gettimeofday ();
+ ACE_UINT32 srcid = ACE_UINT32 (tv.sec () + tv.usec ());
+ srcid += (ACE_UINT32)ACE_OS::getuid();
+ srcid += (ACE_UINT32)ACE_OS::getpid();
+ srcid += addr;
+ return (srcid);
+*/
}
-/*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 = ACE_reinterpret_cast (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 = ACE_reinterpret_cast (rtcp_rr*, (sr + 1));
- } else {
- flags |= RTCP_PT_RR;
- rr = ACE_reinterpret_cast (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 ( ACE_reinterpret_cast (rtcphdr*,rr), s);
- else
- len += build_sdes ( ACE_reinterpret_cast (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 (TAO_AV_RTCP::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)
+double
+TAO_AV_RTCP::rtcp_interval (int members,
+ int senders,
+ double rtcp_bw,
+ int we_sent,
+ int packet_size,
+ int *avg_rtcp_size,
+ int initial)
+{
+ // Minimum time between RTCP packets from this site (in sec.).
+ // This time prevents the reports from 'clumping' when sessions
+ // are small and the law of large numbers isn't helping to smooth
+ // out the traffic. It also keeps the report interval from
+ // becoming ridiculously small during transient outages like a
+ // network partition.
+// double const RTCP_MIN_TIME = 5.0; (from RTP.h)
+
+ // Fraction of the RTCP bandwidth to be shared among active
+ // senders. (This fraction was chosen so that in a typical
+ // session with one or two active senders, the computed report
+ // time would be roughly equal to the minimum report time so that
+ // we don't unnecessarily slow down receiver reports.) The
+ // receiver fraction must be 1 - the sender fraction.
+// double const RTCP_SENDER_BW_FRACTION = 0.25; (from RTP.h)
+// double const RTCP_RCVR_BW_FRACTION = (1-RTCP_SENDER_BW_FRACTION); (from RTP.h)
+
+ // Gain (smoothing constant) for the low-pass filter that
+ // estimates the average RTCP packet size
+// double const RTCP_SIZE_GAIN = (1.0/16.0); (from RTP.h)
+
+ double t;
+ double rtcp_min_time = RTCP_MIN_RPT_TIME;
+ int n; // number of members for computation
+
+ // Very first call at application start-up uses half the min
+ // delay for quicker notification while still allowing some time
+ // before reporting for randomization and to learn about other
+ // sources so the report interval will converge to the correct
+ // interval more quickly. The average RTCP size is initialized
+ // to 128 octets which is conservative (it assumes everyone else
+ // is generating SRs instead of RRs: 20 IP + 8 UDP + 52 SR + 48
+ // SDES CNAME).
+ if (initial)
{
- 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;
+ // initialize the random number generator
+ ACE_OS::srand((unsigned int)avg_rtcp_size);
- /*
- * 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;
+ rtcp_min_time /= 2;
+ *avg_rtcp_size = 128;
}
- switch (flags & 0xff) {
- case RTCP_PT_SR:
- TAO_AV_RTCP::parse_sr (rh, flags, ep, ps, addr, source_manager);
- break;
+ // If there were active senders, give them at least a minimum
+ // share of the RTCP bandwidth. Otherwise all participants share
+ // the RTCP bandwidth equally.
+ n = members;
+ if ((senders > 0) && (senders < members*RTCP_SENDER_BW_FRACTION))
+ {
+ if (we_sent)
+ {
+ rtcp_bw *= RTCP_SENDER_BW_FRACTION;
+ n = senders;
+ }
+ else
+ {
+ rtcp_bw *= RTCP_RECEIVER_BW_FRACTION;
+ n -= senders;
+ }
+ }
- case RTCP_PT_RR:
- TAO_AV_RTCP::parse_rr (rh, flags, ep, ps, addr, source_manager);
- break;
+ // Update the average size estimate by the size of the report
+ // packet we just sent.
+ *avg_rtcp_size += (int)((packet_size - *avg_rtcp_size)*RTCP_SIZE_GAIN);
- case RTCP_PT_SDES:
- TAO_AV_RTCP::parse_sdes (rh, flags, ep, ps, addr, ssrc, source_manager);
- break;
+ // The effective number of sites times the average packet size is
+ // the total number of octets sent when each site sends a report.
+ // Dividing this by the effective bandwidth gives the time
+ // interval over which those packets must be sent in order to
+ // meet the bandwidth target, with a minimum enforced. In that
+ // time interval we send one report so this time is also our
+ // average time between reports.
+ t = (*avg_rtcp_size) * n / rtcp_bw;
+ if (t < rtcp_min_time)
+ t = rtcp_min_time;
- case RTCP_PT_BYE:
- TAO_AV_RTCP::parse_bye (rh, flags, ep, ps, source_manager);
- break;
+ // To avoid traffic bursts from unintended synchronization with
+ // other sites, we then pick our actual next report interval as a
+ // random number uniformly distributed between 0.5*t and 1.5*t.
- default:
- ps->badsessopt (1);
- break;
- }
- rh = (rtcphdr*)ep;
- }
- return 0;
-}
+ // TODO: this may not be right. need a random number between 0 and 1
+ int max_rand = 32768;
-ACE_UINT32
-TAO_AV_RTCP::alloc_srcid (ACE_UINT32 addr)
-{
- ACE_Time_Value tv = ACE_OS::gettimeofday ();
- ACE_UINT32 srcid = ACE_UINT32 (tv.sec () + tv.usec ());
- srcid += (ACE_UINT32)ACE_OS::getuid();
- srcid += (ACE_UINT32)ACE_OS::getpid();
- srcid += addr;
- return (srcid);
+ return t * ((double)ACE_OS::rand()/max_rand + 0.5);
+// return t * (drand48() + 0.5);
}
-double
-TAO_AV_RTCP::fmod (double dividend, double divisor)
-{
- //Method to calculate the fmod (x,y)
- int quotient = ACE_static_cast (int, (dividend / divisor));
- double product = quotient * divisor;
- double remainder = dividend - product;
- return remainder;
-}
-
// TAO_AV_RTCP_Flow_Factory
TAO_AV_RTCP_Flow_Factory::TAO_AV_RTCP_Flow_Factory (void)
@@ -588,7 +348,8 @@ int
TAO_AV_RTCP_Flow_Factory::match_protocol (const char *flow_string)
{
if (ACE_OS::strncasecmp (flow_string,"RTCP",4) == 0)
- return 1;
+ return 1;
+
return 0;
}
@@ -600,25 +361,27 @@ TAO_AV_RTCP_Flow_Factory::init (int /* argc */,
}
TAO_AV_Protocol_Object*
-TAO_AV_RTCP_Flow_Factory::make_protocol_object (TAO_FlowSpec_Entry *entry,
- TAO_Base_StreamEndPoint *endpoint,
+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_Callback *client_cb = 0;
+ TAO_AV_RTCP_Callback *rtcp_cb = 0;
+
+ // TODO: need to handle a client callback at some point
+// endpoint->get_control_callback (entry->flowname (),
+// client_cb);
+
TAO_AV_Protocol_Object *object = 0;
ACE_NEW_RETURN (object,
- TAO_AV_RTCP_Object (callback,
+ TAO_AV_RTCP_Object (client_cb,
+ rtcp_cb,
transport),
0);
- callback->open (object,
- handler);
+
+ rtcp_cb->open (object, handler);
+
return object;
}
@@ -626,19 +389,17 @@ TAO_AV_RTCP_Flow_Factory::make_protocol_object (TAO_FlowSpec_Entry *entry,
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);
+ ACE_Message_Block data (bufsiz);
+
+ 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);
+ data.wr_ptr (n);
ACE_Addr *peer_addr = this->transport_->get_peer_addr ();
- this->callback_->receive_control_frame (data,*peer_addr);
+ this->callback_->receive_control_frame (&data,*peer_addr);
return 0;
}
@@ -665,10 +426,14 @@ TAO_AV_RTCP_Object::send_frame (const char*,
return 0;
}
-TAO_AV_RTCP_Object::TAO_AV_RTCP_Object (TAO_AV_Callback *callback,
+TAO_AV_RTCP_Object::TAO_AV_RTCP_Object (TAO_AV_Callback *client_cb,
+ TAO_AV_RTCP_Callback *&rtcp_cb,
TAO_AV_Transport *transport)
- :TAO_AV_Protocol_Object (callback,transport)
+ :TAO_AV_Protocol_Object (&rtcp_cb_, transport)
{
+ rtcp_cb = &this->rtcp_cb_;
+ this->client_cb_ = client_cb;
+
}
TAO_AV_RTCP_Object::~TAO_AV_RTCP_Object (void)
@@ -678,6 +443,11 @@ TAO_AV_RTCP_Object::~TAO_AV_RTCP_Object (void)
int
TAO_AV_RTCP_Object::destroy (void)
{
+ TAO_AV_UDP_Transport *my_transport = ACE_dynamic_cast (TAO_AV_UDP_Transport*,
+ this->transport_);
+
+ my_transport->handler ()->cancel_timer ();
+
this->callback_->handle_destroy ();
return 0;
}
@@ -704,51 +474,45 @@ 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)
+int
+TAO_AV_RTCP_Object::handle_control_output (ACE_Message_Block *frame)
{
- ACE_NEW (source_manager_,
- TAO_AV_SourceManager (this));
+ TAO_AV_RTCP_Callback *cb = ACE_dynamic_cast (TAO_AV_RTCP_Callback*,
+ this->callback_);
- ACE_NEW (this->state_,
- TAO_AV_RTP_State);
+ return cb->send_frame (frame);
}
-TAO_AV_RTCP_Callback::~TAO_AV_RTCP_Callback (void)
+void
+TAO_AV_RTCP_Object::ts_offset (ACE_UINT32 ts_offset)
{
+ TAO_AV_RTCP_Callback *cb = ACE_dynamic_cast (TAO_AV_RTCP_Callback*,
+ this->callback_);
+ return cb->ts_offset (ts_offset);
}
-TAO_AV_SourceManager*
-TAO_AV_RTCP_Callback::source_manager (void)
+// TAO_AV_RTCP_Callback
+TAO_AV_RTCP_Callback::TAO_AV_RTCP_Callback (void)
+ :is_initial_timeout_(1),
+ packet_size_(0)
{
- return this->source_manager_;
-}
+ char cname[256];
+ char host[256];
+ ACE_OS::hostname(host, sizeof(host));
-TAO_AV_RTP_State*
-TAO_AV_RTCP_Callback::state (void)
-{
- return this->state_;
+ // TODO: determine username auto-magically?
+ ACE_OS::sprintf(cname, "username@%s", host);
+
+ this->output_.cname(cname);
}
-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;
+TAO_AV_RTCP_Callback::~TAO_AV_RTCP_Callback (void)
+{
}
void
@@ -757,25 +521,9 @@ 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(TAO_AV_RTCP::fmod(double(ACE_OS::rand ()), rint) + rint * .5 + .5);
return 0;
}
@@ -788,34 +536,244 @@ TAO_AV_RTCP_Callback::handle_stop (void)
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 this->send_report(0);
+}
+
+int
+TAO_AV_RTCP_Callback::send_report (int bye)
+{
+ // get the RTCP control object in order to get the ssrc
+ TAO_AV_RTCP_Object *rtcp_prot_obj = ACE_dynamic_cast (TAO_AV_RTCP_Object*,
+ this->protocol_object_);
+ ACE_UINT32 my_ssrc = rtcp_prot_obj->ssrc ();
+
+ RTCP_Packet *cp;
+ RTCP_SDES_Packet sdes;
+ ACE_CString value = "";
+ ACE_CString note = "";
+ ACE_UINT16 sdes_type = 0;
+ RTCP_BYE_Packet *bye_packet = 0; // only used for bye
+ ACE_UINT32 ssrc_list[1]; // only used for bye
+
+ // get an iterator for the incoming channels.
+ ACE_Hash_Map_Iterator<ACE_UINT32, RTCP_Channel_In*, ACE_Null_Mutex> iter (this->inputs_);
+ iter = this->inputs_.begin();
+
+ // first send an SR/RR
+ RR_Block *blocks = 0;
+ RR_Block *b_iter = 0;
+ RR_Block *b_ptr = 0;
+
+ while (iter != this->inputs_.end() )
+ {
+ if (!b_iter)
+ {
+ b_ptr = (*iter).int_id_->getRRBlock ();
+ if (b_ptr)
+ {
+ blocks = b_ptr;
+ b_iter = b_ptr;
+ }
+ }
+ else
+ {
+ b_ptr = (*iter).int_id_->getRRBlock ();
+ if (b_ptr)
+ {
+ b_iter->next_ = b_ptr;
+ }
+ }
+
+ iter++;
+ }
+
+ if (b_iter)
+ b_iter->next_ = 0;
+
+ if (this->output_.active ())
+ {
+ // get the NTP timestamp
+ ACE_Time_Value unix_now = ACE_OS::gettimeofday ();
+ TAO_AV_RTCP::ntp64 ntp_now = ntp64time (unix_now);
+ ACE_UINT32 rtp_ts = unix_now.sec () * 8000 + unix_now.usec () / 125 +
+ this->timestamp_offset_;
+ ACE_NEW_RETURN(cp,
+ RTCP_SR_Packet (my_ssrc,
+ ntp_now.upper,
+ ntp_now.lower,
+ rtp_ts,
+ this->output_.packets_sent (),
+ this->output_.octets_sent (),
+ blocks),
+ -1);
+ }
+ else
+ {
+ ACE_NEW_RETURN(cp,
+ RTCP_RR_Packet (my_ssrc,
+ blocks),
+ -1);
+ }
+
+ /*
+ * 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)
+ */
+
+ // TODO: need capability to change these settings
+ switch (this->sdes_count_%8)
+ {
+ case 0:
+ case 4:
+ value = "tao-users@wustl.edu";
+ sdes_type = RTCP_SDES_EMAIL;
+ break;
+ case 2:
+ if (note.length () > 0)
+ {
+ value = "Joe User";
+ sdes_type = RTCP_SDES_NAME;
+ }
+ else
+ {
+ value = note;
+ sdes_type = RTCP_SDES_NOTE;
+ }
+ break;
+ case 6:
+ value = "TAO A/V Service";
+ sdes_type = RTCP_SDES_TOOL;
+ break;
+ case 1:
+ case 3:
+ case 5:
+ case 7:
+ if (note.length () == 0)
+ {
+ value = "Joe User";
+ sdes_type = RTCP_SDES_NAME;
+ }
+ else
+ {
+ value = "An important note...";
+ sdes_type = RTCP_SDES_NOTE;
+ }
+ break;
+ }
+
+ ++this->sdes_count_;
+
+ sdes.add_item (my_ssrc,
+ RTCP_SDES_CNAME,
+ strlen(this->output_.cname()),
+ this->output_.cname());
+ if (bye)
+ {
+ ssrc_list[0] = rtcp_prot_obj->ssrc ();
+
+ ACE_NEW_RETURN (bye_packet,
+ RTCP_BYE_Packet(ssrc_list,
+ sizeof(ssrc_list)/sizeof(ssrc_list[0]),
+ "Got bored."),
+ -1);
+ }
+ else
+ sdes.add_item (my_ssrc, sdes_type, value.length (), value.c_str ());
+
+ // create the message block
+ char *cp_ptr;
+ char *sdes_ptr;
+ char *bye_ptr = 0;
+ ACE_UINT16 cp_length;
+ ACE_UINT16 sdes_length;
+ ACE_UINT16 bye_length = 0;
+ cp->get_packet_data (&cp_ptr, cp_length);
+ sdes.get_packet_data (&sdes_ptr, sdes_length);
+ if (bye_packet)
+ bye_packet->get_packet_data(&bye_ptr, bye_length);
+
+ ACE_Message_Block mb (cp_length + sdes_length + bye_length);
+
+ memcpy (mb.wr_ptr (), cp_ptr, cp_length);
+ mb.wr_ptr (cp_length);
+ memcpy (mb.wr_ptr (), sdes_ptr, sdes_length);
+ mb.wr_ptr (sdes_length);
+ if (bye_length)
+ {
+ memcpy (mb.wr_ptr (), bye_ptr, bye_length);
+ mb.wr_ptr (bye_length);
+ }
+
+ // send the report
+ this->protocol_object_->send_frame (&mb);
+
+ this->packet_size_ = cp_length + sdes_length + bye_length;
+
+ delete cp;
+ if (bye_packet)
+ delete bye_packet;
+
return 0;
}
void
+//TAO_AV_RTCP_Callback::get_timeout (ACE_Time_Value *tv,
TAO_AV_RTCP_Callback::get_timeout (ACE_Time_Value *&tv,
void *& /*arg*/)
{
+ int senders = 0;
+ int members = 1; // count self as member
+
+ // TODO: this should be 5% of the session bw
+ double rtcp_bw = 1000;
+ double interval;
+
+ ACE_Hash_Map_Iterator<ACE_UINT32, RTCP_Channel_In*, ACE_Null_Mutex> iter (this->inputs_);
+ iter = this->inputs_.begin();
+
+ if (this->output_.active ())
+ senders++;
+
+ // determine the number of senders and members of this session
+ while (iter != this->inputs_.end ())
+ {
+ if ((*iter).int_id_->active ())
+ {
+ if ((*iter).int_id_->sender ())
+ senders++;
+ members++;
+ }
+ iter++;
+ }
+
// Here we do the RTCP timeout calculation.
+ interval = TAO_AV_RTCP::rtcp_interval (members, // members
+ senders, // senders
+ rtcp_bw, // rtcp_bw
+ this->output_.active (), // we_sent
+ this->packet_size_, // packet_size
+ &this->avg_rtcp_size_, // avg_rtcp_size
+ this->is_initial_timeout_); // initial)
+
+ this->is_initial_timeout_ = 0;
+
ACE_NEW (tv,
- ACE_Time_Value (0,this->timeout_*ACE_ONE_SECOND_IN_MSECS));
+ ACE_Time_Value);
+
+ tv->sec ((int)interval);
+ tv->usec ((int)((interval - (int)interval) * 1000000));
}
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;
+ return this->send_report(1);
}
int
@@ -823,122 +781,40 @@ 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;
+ RTCP_Channel_In *c;
- frame->rd_ptr (sizeof (TAO_AV_RTP::rtphdr));
- int result = this->demux (rh,
- frame,
- peer_address);
- frame->rd_ptr (buf);
+ RTP_Packet packet (frame->rd_ptr(), frame->length());
- if (result < 0)
- return result;
+ if (this->inputs_.find (packet.ssrc(), c) < 0)
+ {
+ ACE_NEW_RETURN (c,
+ RTCP_Channel_In (packet.ssrc(),
+ &peer_address),
+ -1);
+
+ this->inputs_.bind (packet.ssrc(), c);
+ }
+ c->recv_rtp_packet (frame, &peer_address);
return 0;
}
-
int
-TAO_AV_RTCP_Callback::receive_control_frame (ACE_Message_Block *frame,
- const ACE_Addr &peer_address)
+TAO_AV_RTCP_Callback::send_frame (ACE_Message_Block *frame)
{
- // 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);
+ RTP_Packet packet (frame->rd_ptr(), frame->length());
+ this->output_.updateStatistics (&packet);
+
return 0;
}
-int
-TAO_AV_RTCP_Callback::demux (TAO_AV_RTP::rtphdr* rh,
- ACE_Message_Block *data,
- const ACE_Addr &address)
+void
+TAO_AV_RTCP_Callback::ts_offset (ACE_UINT32 offset)
{
- 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);
-
- long 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).
- */
+ this->timestamp_offset_ = offset;
}
+
ACE_FACTORY_DEFINE (TAO_AV, TAO_AV_RTCP_Flow_Factory)
ACE_STATIC_SVC_DEFINE (TAO_AV_RTCP_Flow_Factory,
ACE_TEXT ("RTCP_Flow_Factory"),
@@ -949,4 +825,26 @@ ACE_STATIC_SVC_DEFINE (TAO_AV_RTCP_Flow_Factory,
0)
+#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
+
+template class ACE_Hash_Map_Entry<ACE_UINT32,RTCP_Channel_In *>;
+template class ACE_Hash_Map_Manager<ACE_UINT32,RTCP_Channel_In *,ACE_Null_Mutex>;
+template class ACE_Hash_Map_Manager_Ex<ACE_UINT32, RTCP_Channel_In *, ACE_Hash<ACE_UINT32>, ACE_Equal_To<ACE_UINT32>, ACE_Null_Mutex>;
+template class ACE_Hash_Map_Iterator<ACE_UINT32,RTCP_Channel_In *,ACE_Null_Mutex>;
+template class ACE_Hash_Map_Iterator_Ex<ACE_UINT32, RTCP_Channel_In *, ACE_Hash<ACE_UINT32>, ACE_Equal_To<ACE_UINT32>, ACE_Null_Mutex>;
+template class ACE_Hash_Map_Iterator_Base_Ex<ACE_UINT32, RTCP_Channel_In *, ACE_Hash<ACE_UINT32>, ACE_Equal_To<ACE_UINT32>, ACE_Null_Mutex>;
+template class ACE_Hash_Map_Reverse_Iterator<ACE_UINT32,RTCP_Channel_In *,ACE_Null_Mutex>;
+template class ACE_Hash_Map_Reverse_Iterator_Ex<ACE_UINT32, RTCP_Channel_In *, ACE_Hash<ACE_UINT32>, ACE_Equal_To<ACE_UINT32>, ACE_Null_Mutex>;
+
+#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
+
+#pragma instantiate ACE_Hash_Map_Entry<ACE_UINT32,RTCP_Channel_In *>
+#pragma instantiate ACE_Hash_Map_Manager<ACE_UINT32,RTCP_Channel_In *,ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Manager_Ex<ACE_UINT32, RTCP_Channel_In *, ACE_Hash<ACE_UINT32>, ACE_Equal_To<ACE_UINT32>, ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Iterator<ACE_UINT32,RTCP_Channel_In *,ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Iterator_Ex<ACE_UINT32, RTCP_Channel_In *, ACE_Hash<ACE_UINT32>, ACE_Equal_To<ACE_UINT32>, ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Iterator_Base_Ex<ACE_UINT32, RTCP_Channel_In *, ACE_Hash<ACE_UINT32>, ACE_Equal_To<ACE_UINT32>, ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Reverse_Iterator<ACE_UINT32,RTCP_Channel_In *,ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Reverse_Iterator_Ex<ACE_UINT32, RTCP_Channel_In *, ACE_Hash<ACE_UINT32>, ACE_Equal_To<ACE_UINT32>, ACE_Null_Mutex>
+#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */
diff --git a/TAO/orbsvcs/orbsvcs/AV/RTCP.h b/TAO/orbsvcs/orbsvcs/AV/RTCP.h
index 8f8fba09a6c..aa54c808d6e 100644
--- a/TAO/orbsvcs/orbsvcs/AV/RTCP.h
+++ b/TAO/orbsvcs/orbsvcs/AV/RTCP.h
@@ -50,41 +50,20 @@
// FUZZ: disable check_for_math_include
#include "ace/OS.h"
-#include "orbsvcs/AV/source.h"
+#include "ace/Hash_Map_Manager.h"
#include "orbsvcs/AV/AVStreams_i.h"
#include "orbsvcs/AV/UDP.h"
#include <math.h>
#include <stdlib.h>
#include "orbsvcs/AV/RTP.h"
-/**
- * @class TAO_AV_RTP_State
- * @brief Encapsulate the state of an RTP session
- */
-class TAO_AV_Export 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_;
-};
+#include "RTCP_Channel.h"
class TAO_AV_RTCP_Callback;
-class TAO_AV_SourceManager;
/**
* @class TAO_AV_RTCP
- * @brief Encapsulate the header format for the Real Time Control
+ * @brief Encapsulate the header format for the Real Time Control
* Protocol (RTCP)
*/
class TAO_AV_Export TAO_AV_RTCP
@@ -101,143 +80,22 @@ public:
{
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 void send_report (ACE_Message_Block *mb);
static ACE_UINT32 alloc_srcid (ACE_UINT32 addr);
- static double fmod (double dividend, double divisor);
+ static double rtcp_interval (int members,
+ int senders,
+ double rtcp_bw,
+ int we_sent,
+ int packet_size,
+ int *avg_rtcp_size,
+ int initial);
};
-class TAO_AV_Callback;
-
-/**
- * @class TAO_AV_RTCP_Object
- * @brief TAO_AV_Protocol_Object for RTCP protocol
- */
-class TAO_AV_Export TAO_AV_RTCP_Object
- : public TAO_AV_Protocol_Object
-{
-public:
- /// constructor.
- TAO_AV_RTCP_Object (TAO_AV_Callback *callback,
- TAO_AV_Transport *transport = 0);
-
- /// Destructor
- virtual ~TAO_AV_RTCP_Object (void);
-
- virtual int handle_input (void);
- virtual int handle_control_input (ACE_Message_Block *frame,
- const ACE_Addr &peer_address);
-
- /// set/get policies.
- virtual int set_policies (const TAO_AV_PolicyList &policy_list);
-
- /// start/stop the flow.
- virtual int start (void);
- virtual int stop (void);
-
- /// send a data frame.
- virtual int send_frame (ACE_Message_Block *frame,
- TAO_AV_frame_info *frame_info = 0);
-
- /// send a frame in iovecs.
- virtual int send_frame (const iovec *iov,
- int iovcnt,
- TAO_AV_frame_info *frame_info = 0);
- virtual int send_frame (const char*buf,
- size_t len);
-
- /// end the stream.
- virtual int destroy (void);
-};
/**
* @class TAO_AV_Flow_Protocol_Factory
@@ -257,6 +115,9 @@ public:
TAO_AV_Transport *transport);
};
+class TAO_AV_Callback;
+
+
/**
* @class TAO_AV_RTCP_Callback
* @brief TAO_AV_Callback for RTCP protocol
@@ -283,6 +144,7 @@ public:
virtual int receive_frame (ACE_Message_Block *frame,
TAO_AV_frame_info *frame_info = 0,
const ACE_Addr &peer_address = ACE_Addr::sap_any);
+ int send_frame (ACE_Message_Block *frame);
virtual int receive_control_frame (ACE_Message_Block *frame,
const ACE_Addr &peer_address = ACE_Addr::sap_any);
@@ -296,23 +158,83 @@ public:
virtual void get_timeout (ACE_Time_Value *&tv,
void *&arg);
- 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);
+ int send_report(int bye);
void schedule (int ms);
- TAO_AV_SourceManager *source_manager (void);
TAO_AV_RTP_State *state (void);
+ void ts_offset (ACE_UINT32 offset);
+
protected:
- TAO_AV_SourceManager *source_manager_;
- TAO_AV_RTP_State *state_;
+ ACE_Hash_Map_Manager<ACE_UINT32, RTCP_Channel_In*, ACE_Null_Mutex> inputs_;
+ RTCP_Channel_Out output_;
int timeout_;
+ int timestamp_offset_;
+ int sdes_count_;
+
+ int is_initial_timeout_;
+ int avg_rtcp_size_;
+ int packet_size_;
+};
+
+class RTP_Packet;
+
+
+/**
+ * @class TAO_AV_RTCP_Object
+ * @brief TAO_AV_Protocol_Object for RTCP protocol
+ */
+class TAO_AV_Export TAO_AV_RTCP_Object
+ : public TAO_AV_Protocol_Object
+{
+public:
+ /// constructor.
+ TAO_AV_RTCP_Object (TAO_AV_Callback *client_cb,
+ TAO_AV_RTCP_Callback *&rtcp_cb,
+ TAO_AV_Transport *transport = 0);
+
+ /// Destructor
+ virtual ~TAO_AV_RTCP_Object (void);
+
+ virtual int handle_input (void);
+ virtual int handle_control_input (ACE_Message_Block *frame,
+ const ACE_Addr &peer_address);
+ virtual int handle_control_output (ACE_Message_Block *frame);
+
+ /// set/get policies.
+ virtual int set_policies (const TAO_AV_PolicyList &policy_list);
+
+ /// start/stop the flow.
+ virtual int start (void);
+ virtual int stop (void);
+
+ /// send a data frame.
+ virtual int send_frame (ACE_Message_Block *frame,
+ TAO_AV_frame_info *frame_info = 0);
+
+ /// send a frame in iovecs.
+ virtual int send_frame (const iovec *iov,
+ int iovcnt,
+ TAO_AV_frame_info *frame_info = 0);
+
+ virtual int send_frame (const char*buf,
+ size_t len);
+
+ /// end the stream.
+ virtual int destroy (void);
+
+ void ssrc (ACE_UINT32 ssrc) {this->ssrc_ = ssrc; }
+ ACE_UINT32 ssrc (void) { return this->ssrc_; }
+
+ void ts_offset (ACE_UINT32 ts_offset);
+
+
+private:
+ TAO_AV_Callback *client_cb_;
+ TAO_AV_RTCP_Callback rtcp_cb_;
+ ACE_UINT32 ssrc_;
};
+
+
ACE_STATIC_SVC_DECLARE (TAO_AV_RTCP_Flow_Factory)
ACE_FACTORY_DECLARE (TAO_AV, TAO_AV_RTCP_Flow_Factory)
diff --git a/TAO/orbsvcs/orbsvcs/AV/RTCP_Channel.cpp b/TAO/orbsvcs/orbsvcs/AV/RTCP_Channel.cpp
new file mode 100644
index 00000000000..9aaebbdf2d9
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/AV/RTCP_Channel.cpp
@@ -0,0 +1,361 @@
+// $Id$
+#include "ace/OS.h"
+
+#include "RTCP_Channel.h"
+#include "RTP.h"
+
+RTCP_Channel_In::RTCP_Channel_In (ACE_UINT32 ssrc,
+ const ACE_Addr *peer_addr)
+ : remote_ssrc_ (ssrc),
+ cname_ (""),
+ transit_ (0),
+ jitter_ (0.0),
+ first_data_packet_ (1),
+ ntp_ts_msw_ (0),
+ ntp_ts_lsw_ (0),
+ last_sr_time_ (0),
+ active_ (0),
+ no_data_counter_ (0),
+ data_since_last_report_ (0)
+{
+ const ACE_INET_Addr *const_inet_addr = ACE_dynamic_cast (const ACE_INET_Addr*,
+ peer_addr);
+
+ ACE_INET_Addr *inet_addr;
+ ACE_NEW (inet_addr,
+ ACE_INET_Addr (*const_inet_addr));
+
+ this->peer_address_ = inet_addr;
+}
+
+RTCP_Channel_In::~RTCP_Channel_In(void)
+{
+ delete this->peer_address_;
+}
+
+void
+RTCP_Channel_In::updateStatistics(RTP_Packet* dataPkt)
+{
+ ACE_Time_Value current_time;
+ ACE_UINT32 arrival;
+ int transit, d;
+
+ this->active_ = 0;
+
+ // determine if the source has been declared valid
+ if (update_seq(dataPkt->sn ()) == 0)
+ return;
+
+ // Set initial values if this is the first data packet.
+ if (this->first_data_packet_)
+ {
+ // store the initial timestamp
+ this->init_time_stamp_ = dataPkt->ts ();
+ this->init_local_time_ = ACE_OS::gettimeofday ();
+ this->first_data_packet_ = 0;
+ }
+
+ // Get the current time.
+ current_time = ACE_OS::gettimeofday ();
+
+ unsigned int samples_per_sec;
+ double samples_per_usec;
+
+
+ switch (dataPkt->pt())
+ {
+ case RTP_PT_PCMU:
+ case RTP_PT_CELP:
+ case RTP_PT_G721:
+ case RTP_PT_GSM:
+ case RTP_PT_DVI:
+ case RTP_PT_LPC:
+ case RTP_PT_PCMA:
+ case RTP_PT_G722:
+ samples_per_sec = 8000;
+ break;
+ case RTP_PT_L16_STEREO:
+ case RTP_PT_L16_MONO:
+ samples_per_sec = 44100;
+ break;
+ default:
+ samples_per_sec = 1000000;
+ };
+
+ samples_per_usec = samples_per_sec/1000000.0;
+
+ // Calculate the current timestamp.
+ arrival = (ACE_UINT32)((current_time.sec () -
+ this->init_local_time_.sec ()) * samples_per_sec +
+ ((double)(current_time.usec () -
+ (double)this->init_local_time_.usec ()) * samples_per_usec) +
+ this->init_time_stamp_);
+
+
+ // jitter calc from RFC 1889 app a.8
+ transit = arrival - dataPkt->ts ();
+ d = transit - this->transit_;
+ this->transit_ = transit;
+ if (d < 0)
+ d = -d;
+
+ // Calculate the inter-arrival jitter.
+ this->jitter_ += (1./16.)*((double)d - this->jitter_);
+
+ // Indicate that data has been received since the last report.
+ this->data_since_last_report_ = 1;
+
+ // Store the payload type.
+ this->payload_type_ = dataPkt->pt ();
+}
+
+int
+RTCP_Channel_In::updateStatistics(RTCP_SR_Packet *sr)
+{
+ // calculate the last SR time in 1/65536 sec.
+ ACE_Time_Value now = ACE_OS::gettimeofday ();
+ this->last_sr_time_ = (ACE_UINT32)
+ (now.sec () * 65536 +
+ now.usec () * 0.065536);
+
+ this->ntp_ts_msw_ = sr->ntp_ts_msw ();
+ this->ntp_ts_lsw_ = sr->ntp_ts_lsw ();
+
+ return 0;
+}
+
+int
+RTCP_Channel_In::updateStatistics(RTCP_RR_Packet */*rr*/)
+{
+ return 0;
+}
+
+void
+RTCP_Channel_In::init_seq(ACE_UINT16 seq)
+{
+ this->base_seq_ = seq - 1;
+ this->max_seq_ = seq;
+ this->bad_seq_ = RTP_SEQ_MOD + 1;
+ this->cycles_ = 0;
+ this->received_ = 0;
+ this->received_prior_ = 0;
+ this->expected_prior_ = 0;
+}
+
+int
+RTCP_Channel_In::update_seq(ACE_UINT16 seq)
+{
+ // The following is taken from RFC 1889 Appendix A.1
+ ACE_UINT16 udelta = seq - this->max_seq_;
+ const int MAX_DROPOUT = 3000;
+ const int MAX_MISORDER = 100;
+ const int MIN_SEQUENTIAL = 2;
+
+ // Source is not valid until MIN_SEQUENTIAL packets with
+ // sequential sequence numbers have been received.
+ if (this->probation_)
+ {
+ // packet is in sequence
+ if (seq == this->max_seq_ + (ACE_UINT16)1)
+ {
+ this->probation_ --;
+ this->max_seq_ = seq;
+ if (this->probation_ == 0)
+ {
+ this->init_seq(seq);
+ this->received_++;
+ return 1;
+ }
+ }
+ else
+ {
+ this->probation_ = MIN_SEQUENTIAL - 1;
+ this->max_seq_ = seq;
+ }
+ return 0;
+ }
+ else if (udelta < MAX_DROPOUT)
+ {
+ // in order, with permissible gap
+ if (seq < this->max_seq_)
+ {
+ // seq number wrapped - count another 64k cycle
+ this->cycles_+=RTP_SEQ_MOD;
+ }
+ this->max_seq_ = seq;
+ }
+ else if (udelta <= RTP_SEQ_MOD - MAX_MISORDER)
+ {
+ // the sequence number made a large jump
+ ACE_UINT32 temp = seq; // Borland reports a warning on the next line
+ // without this line.
+ if (temp == this->bad_seq_)
+ {
+ // two sequential packets, assume the other side restarted without
+ // telling us so just re-sync
+ // (i.e., pretend this was the first packet).
+ this->init_seq (seq);
+
+ ACE_DEBUG ((LM_DEBUG,
+ "RTCP_Channel_In: large jump in sequence number",
+ "; init seq\n"));
+ }
+ else
+ {
+ this->bad_seq_ = (seq+1)&(RTP_SEQ_MOD-1);
+ return 0;
+ }
+ }
+ else
+ {
+ // dup or reordered packet
+ }
+ this->received_++;
+
+ return 1;
+}
+
+void
+RTCP_Channel_In::recv_rtp_packet(ACE_Message_Block *mb,
+ const ACE_Addr *peer_address)
+{
+ if (*peer_address != *this->peer_address_)
+ ACE_DEBUG ((LM_DEBUG,
+ "RTCP_Channel_In::recv_rtp_packet - possible loop/collision detected"));
+
+ RTP_Packet data_packet(mb->rd_ptr (), mb->length ());
+
+ // make sure the packet is valid
+ if (data_packet.is_valid ())
+ this->updateStatistics(&data_packet);
+ else
+ ACE_DEBUG ((LM_DEBUG,
+ "RTCP_Channel_In::recvDataPacket - invalid RTP packet\n"));
+}
+
+
+RR_Block *
+RTCP_Channel_In::getRRBlock(void)
+{
+ // If no data has been received since the last report, don't create a block.
+ if (!this->data_since_last_report_)
+ {
+ this->no_data_counter_++;
+
+ // make the source inactive if significant time has passed since last report
+ if (this->no_data_counter_ == 32)
+ this->active_ = 0;
+
+ return 0;
+ }
+
+ this->no_data_counter_ = 0;
+
+ RR_Block *local_block_ptr = 0;
+
+ ACE_NEW_RETURN (local_block_ptr,
+ RR_Block,
+ 0);
+
+ ACE_OS::memset(local_block_ptr, 0, sizeof(RR_Block));
+
+ // Set the ssrc of the source this report is for.
+ local_block_ptr->ssrc_ = this->remote_ssrc_;
+
+ // Calculate packets expected/lost (from RFC 1889 Appendix A.3)
+ ACE_UINT32 extended_max;
+ ACE_UINT32 expected;
+ ACE_UINT32 expected_interval;
+ ACE_UINT32 received_interval;
+ int lost_interval;
+
+ extended_max = this->cycles_ + this->max_seq_;
+ expected = extended_max - this->base_seq_ + 1;
+
+ local_block_ptr->lost_ = expected - this->received_;
+ expected_interval = expected - this->expected_prior_;
+ this->expected_prior_ = expected;
+ received_interval = this->received_ - this->received_prior_;
+ this->received_prior_ = this->received_;
+ lost_interval = expected_interval - received_interval;
+
+ if ((expected_interval == 0) || (lost_interval <= 0))
+ local_block_ptr->fraction_ = 0;
+ else
+ local_block_ptr->fraction_ = (lost_interval << 8) / expected_interval;
+
+
+ local_block_ptr->last_seq_ = extended_max;
+
+ // taken from RFC 1889 App A.8
+ local_block_ptr->jitter_ = (ACE_UINT32)this->jitter_;
+
+ // calculate the last SR timestamp (lsr)
+ local_block_ptr->lsr_ = ((this->ntp_ts_msw_ & 0xFFFF) << 16) |
+ ((this->ntp_ts_lsw_ & 0xFFFF0000) >> 16);
+
+ // calculate the delay since last SR (dlsr)
+ ACE_Time_Value now = ACE_OS::gettimeofday ();
+ ACE_UINT32 now32 = (ACE_UINT32)
+ (now.sec () * 65536 +
+ now.usec () * 0.065536);
+
+ local_block_ptr->dlsr_ = now32 - this->last_sr_time_;
+
+ // indicate that no data has been received since the last report
+ this->data_since_last_report_ = 0;
+
+ return local_block_ptr;
+}
+
+RTCP_Channel_Out::RTCP_Channel_Out(void)
+ :cname_ ("cname"),
+ active_ (0),
+ timestamp_ (0),
+ timestamp_offset_ (0),
+ packets_sent_ (0),
+ octets_sent_ (0)
+{
+}
+
+RTCP_Channel_Out::~RTCP_Channel_Out(void)
+{
+}
+
+void
+RTCP_Channel_Out::updateStatistics (RTP_Packet *data_packet)
+{
+ // indicate that this source is active
+ this->active_ = 1;
+
+ // Update various counters.
+ this->octets_sent_ += data_packet->payload_size();
+ this->packets_sent_ ++;
+ this->seq_num_ = data_packet->sn ();
+ this->timestamp_ = data_packet->ts ();
+}
+
+ACE_UINT32
+RTCP_Channel_Out::timestamp (void)
+{
+ return this->timestamp_;
+}
+
+ACE_UINT32
+RTCP_Channel_Out::packets_sent (void)
+{
+ return this->packets_sent_;
+}
+
+ACE_UINT32
+RTCP_Channel_Out::octets_sent (void)
+{
+ return this->octets_sent_;
+}
+
+char
+RTCP_Channel_Out::active (void)
+{
+ return this->active_;
+}
+
diff --git a/TAO/orbsvcs/orbsvcs/AV/RTCP_Channel.h b/TAO/orbsvcs/orbsvcs/AV/RTCP_Channel.h
new file mode 100644
index 00000000000..66a63372f0f
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/AV/RTCP_Channel.h
@@ -0,0 +1,217 @@
+// $Id$
+
+#ifndef RTCP_CHANNEL_INCLUDE
+#define RTCP_CHANNEL_INCLUDE
+
+#include "ace/OS.h"
+#include "ace/Message_Block.h"
+#include "ace/SString.h"
+
+#include "RTP.h"
+#include "RTCP_Packet.h"
+
+/**
+ * @class RTCP_Channel_In
+ * @brief The RTCP_Channel_In class represents a single incoming data channel,
+ * or stream. The class has several responsibilities. When the class is
+ * instantiated, the incoming RTP traffic must be declared a valid source based
+ * on the RTP packets received. Once declared valie, this class is responsible
+ * for keeping up with reception statistics and other information. When an SR
+ * or RR is created (outside of this class), this class is used to get the
+ * Receiver Report block for this particular stream.
+ */
+
+class RTCP_Channel_In
+{
+public:
+ /// Constructor for an incoming channel. Requires the synchronization source
+ /// id and address of the sender.
+ RTCP_Channel_In(ACE_UINT32 ssrc,
+ const ACE_Addr *addr);
+
+ /// Destructor
+ ~RTCP_Channel_In(void);
+
+ /// This operation takes the incoming ACE_Message_Block, converts it to an
+ /// RTP_Packet and calls updateStatistics. It also uses compares the peer_addr
+ /// to the stored peer_address_ to check for loops.
+ void recv_rtp_packet (ACE_Message_Block *mb,
+ const ACE_Addr *peer_addr);
+
+ /// Takes statistics of incoming RTP traffic and creates a receiver report block.
+ RR_Block *getRRBlock(void);
+
+ /// Returns the delay since last sender report.
+ ACE_UINT32 dlsr (void);
+
+ /// Returns the last sender report timestamp.
+ ACE_UINT32 lsr (void);
+
+ /// Updates channel information with incoming sender report.
+ int updateStatistics(RTCP_SR_Packet *sr);
+
+ /// Updates channel information with incoming receiver report.
+ int updateStatistics(RTCP_RR_Packet *rr);
+
+ /// Returns 1 if data has been sent since the last report, 0 if not.
+ int sender (void) { return this->data_since_last_report_; }
+
+ /// Returns 1 if this is an active source, 0 if not.
+ int active (void) { return this->active_; }
+
+private:
+ /// Don't want default constructor.
+ RTCP_Channel_In(void);
+
+ /// Don't want copy constructor.
+ RTCP_Channel_In(const RTCP_Channel_In &ch);
+
+ /// The synchronization source id of the source this channel represents.
+ ACE_UINT32 remote_ssrc_;
+
+ /// The canonical name of the source this channel represents.
+ ACE_CString cname_;
+
+ // Used to declare a source valid
+ /// The highest sequence number seen.
+ ACE_UINT16 max_seq_;
+
+ /// The shifted count of sequence number cycles (ie when sequence number wraps)
+ ACE_UINT32 cycles_;
+
+ /// The first sequence number received.
+ ACE_UINT32 base_seq_;
+
+ /// last 'bad' sequence number + 1
+ ACE_UINT32 bad_seq_;
+
+ /// The number of in sequence packets until a source is declared valid.
+ ACE_UINT32 probation_;
+
+ /// The number of packets received.
+ ACE_UINT32 received_;
+
+ /// The packet expected at last interval.
+ ACE_UINT32 expected_prior_;
+
+ /// The packet received at last interval.
+ ACE_UINT32 received_prior_;
+
+ /// The last transit time.
+ ACE_UINT32 transit_;
+
+ /// The inter-arrival jitter measured in timestamp units.
+ double jitter_;
+
+ // Used for jitter calculations
+ /// Flag to indicate the first data packet received.
+ char first_data_packet_;
+
+ /// The first timestamp received.
+ ACE_UINT32 init_time_stamp_;
+
+ /// The local time that the initial packet was received.
+ ACE_Time_Value init_local_time_;
+
+ /// The address that the first RTP packet was received from.
+ ACE_Addr *peer_address_;
+
+ /// The most significant word of the last sender report NTP timestamp.
+ ACE_UINT32 ntp_ts_msw_;
+
+ /// The least significant word of the last sender report NTP timestamp.
+ ACE_UINT32 ntp_ts_lsw_;
+
+ /// The last sender report RTP timestamp.
+ ACE_UINT32 rtp_ts_;
+
+ /// The last time a sender report was received in 1/65536 seconds.
+ /// Used to calculate DLSR.
+ ACE_UINT32 last_sr_time_;
+
+ /// Flag to indicate whether or not the source is active.
+ int active_;
+
+ /// This is a counter to indicate the number of reporting intervals that have
+ /// passed since data has been received. After 32, declare the source inactive.
+ int no_data_counter_;
+
+ /// This flag indicates that data has been received since the last report was
+ /// sent.
+ char data_since_last_report_;
+
+ /// The RTP payload type.
+ int payload_type_;
+
+ /// This operation is used update statistics for the incoming RTP packet.
+ void updateStatistics(RTP_Packet *pkt);
+
+ /// This is called when the first RTP packet is received.
+ void init_seq(ACE_UINT16 seq);
+
+ /// This is called when each RTP packet is received. It is used to declare
+ /// a source as valid.
+ int update_seq(ACE_UINT16 seq);
+};
+
+/**
+ * @class RTCP_Channel_Out
+ * @brief The RTCP_Channel_Out class represents a single outgoing data channel,
+ * or stream. It keeps track of statistics such as number of packets sent and
+ * number of bytes sent.
+ */
+
+class RTCP_Channel_Out
+{
+public:
+ /// Constructor.
+ RTCP_Channel_Out(void);
+
+ /// Destructor.
+ ~RTCP_Channel_Out(void);
+
+ /// Update the channel statistics each time an RTP packet is sent.
+ void updateStatistics (RTP_Packet *pkt);
+
+ /// Returns the timestamp of the last RTP packet sent.
+ ACE_UINT32 timestamp (void);
+
+ /// Returns the number of packets sent.
+ ACE_UINT32 packets_sent (void);
+
+ /// Returns the number of octets sent.
+ ACE_UINT32 octets_sent (void);
+
+ /// Sets the canonical name of the source.
+ void cname (const char *cname) { this->cname_ = cname; }
+
+ /// Returns the canonical name of the source.
+ const char *cname (void) { return this->cname_.c_str(); }
+
+ /// Returns whether or not this source is active.
+ char active (void);
+
+private:
+ /// Holds the canonical name for this channel.
+ ACE_CString cname_;
+
+ /// Flag to indicate whether or not this channel is active.
+ char active_;
+
+ /// The sequence number of the last RTP packet sent.
+ unsigned int seq_num_;
+
+ /// The timestamp of the last RTP packet sent.
+ unsigned int timestamp_;
+
+ /// The initial offset of the timestamp.
+ unsigned int timestamp_offset_;
+
+ /// The total number of packets sent.
+ unsigned int packets_sent_;
+
+ /// The total numbef of octets sent.
+ unsigned int octets_sent_;
+};
+
+#endif
diff --git a/TAO/orbsvcs/orbsvcs/AV/RTCP_Packet.cpp b/TAO/orbsvcs/orbsvcs/AV/RTCP_Packet.cpp
new file mode 100644
index 00000000000..0d1d802ff73
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/AV/RTCP_Packet.cpp
@@ -0,0 +1,1194 @@
+// $Id$
+#include "RTCP_Packet.h"
+#include "RTP.h"
+
+RTCP_Packet::RTCP_Packet(void)
+{
+ this->chd_.ver_ = 2;
+ this->chd_.count_ = 0;
+ this->chd_.pad_ = 0;
+ this->chd_.length_ = 0;
+ this->packet_data_ = 0;
+}
+
+RTCP_Packet::RTCP_Packet(char* buffer)
+{
+ // Parse the common part of the control packet header.
+ this->chd_.ver_ = (buffer[0] & 0xC0) >> 6;
+
+ if (this->chd_.ver_ != RTP_VERSION)
+ ACE_DEBUG ((LM_DEBUG,
+ "RTCP_Packet::RTCP_Packet version incorrect"));
+
+ this->chd_.pad_ = (buffer[0] & 0x20) >> 5;
+ this->chd_.count_ = buffer[0] & 0x1F;
+ this->chd_.pt_ = buffer[1];
+ this->chd_.length_ = ntohs(*(ACE_UINT16*)&buffer[2]);
+ this->packet_data_ = 0;
+}
+
+RTCP_Packet::~RTCP_Packet(void)
+{
+}
+
+void
+RTCP_Packet::get_packet_data(char **buffer, ACE_UINT16 &length)
+{
+ length = this->packet_size();
+
+ // buiidPacket is defined for each child of RTCP_Packet
+ // buildPacket creates a snapshot of the RTCP packet in the buffer pktData
+ this->build_packet ();
+
+ *buffer = this->packet_data_;
+}
+
+int
+RTCP_Packet::is_valid (char is_first)
+{
+ // make sure the RTP version is correct
+ if (this->chd_.ver_ != RTP_VERSION)
+ return 0;
+
+ // these checks are only for the first RTCP packet in a compound packet
+ if (is_first)
+ {
+ // the payload type must be RR or SR
+ if ((this->chd_.pt_ != RTCP_PT_SR) && (this->chd_.pt_ != RTCP_PT_RR))
+ return 0;
+
+ // the padding bit must not be set
+ if (this->chd_.pad_ != 0)
+ return 0;
+ }
+
+ return 1;
+
+}
+
+/*
+ * RTCP_BYE_Packet
+ */
+
+RTCP_BYE_Packet::RTCP_BYE_Packet(ACE_UINT32 *ssrc_list,
+ unsigned char length,
+ const char *text)
+{
+ this->chd_.ver_ = 2;
+ this->chd_.count_ = length;
+ this->chd_.pt_ = RTCP_PT_BYE;
+
+ if (length)
+ {
+ ACE_NEW (this->ssrc_list_,
+ ACE_UINT32[length]);
+
+ this->ssrc_list_length_ = length;
+
+ for (int i=0; i<length; i++)
+ this->ssrc_list_[i] = ssrc_list[i];
+ }
+
+ // Optional - if there is a reason for leaving, store it.
+ // The reason is padded with extra zeros because the packet must
+ // end on an even 32-bit boundary.
+ memset(this->reason_, 0, sizeof(this->reason_));
+ if (text)
+ {
+ int text_length = ACE_OS::strlen(text);
+ memcpy(this->reason_, text, text_length);
+ this->reason_length_ = text_length;
+ }
+ else
+ this->reason_length_ = 0;
+
+ // Set the packet length
+ this->chd_.length_ = this->chd_.count_ + (this->reason_length_+1)/4;
+ if ((this->reason_length_+1)%4)
+ this->chd_.length_++;
+
+ this->packet_data_ = 0;
+}
+
+//==============================================================================
+
+RTCP_BYE_Packet::RTCP_BYE_Packet(char* buffer, int *len)
+ : RTCP_Packet(buffer)
+{
+ unsigned int index = 0;
+ unsigned int j;
+
+ // The common part of the header is initialized in the parent.
+ index=4;
+
+ ACE_NEW (this->ssrc_list_,
+ ACE_UINT32[this->chd_.count_]);
+ this->ssrc_list_length_ = this->chd_.count_;
+
+ // Store the source ids of the sources leaving the session
+ for (j=0; j<this->chd_.count_; j++)
+ {
+ this->ssrc_list_[j] = ntohl(*(ACE_UINT32*)&buffer[index]);
+ index+=4;
+ }
+
+ // Optional - store the reason for leaving
+ unsigned int temp = this->chd_.length_; // Borland reports a warning on the
+ // following line with out this.
+ memset(this->reason_, 0, sizeof(this->reason_));
+ if (temp > this->chd_.count_)
+ {
+ this->reason_length_ = buffer[index];
+ index++;
+ memcpy(this->reason_, &buffer[index], this->reason_length_);
+ index+=this->reason_length_;
+
+ }
+ else
+ this->reason_length_ = 0;
+
+ // Decrement the length by the size of this message. This is necessary
+ // because multiple RTCP packets may be contained in a single UDP packet.
+ *len-=(chd_.length_+1)*4;
+
+ this->packet_data_ = 0;
+}
+
+//==============================================================================
+
+RTCP_BYE_Packet::~RTCP_BYE_Packet(void)
+{
+ if (this->ssrc_list_)
+ delete []this->ssrc_list_;
+ if (this->packet_data_)
+ delete []this->packet_data_;
+}
+
+//==============================================================================
+
+unsigned int
+RTCP_BYE_Packet::packet_size(void)
+{
+ ACE_UINT16 size = (1+chd_.count_) * 4;
+
+ if (this->reason_length_ > 0)
+ {
+ size += this->reason_length_ + 1;
+ if (size%4)
+ size += 4 - size%4; // pad with zeros to even 32 bit bound
+ }
+
+ return size;
+}
+
+//==============================================================================
+
+void
+RTCP_BYE_Packet::ssrc_list(ACE_UINT32 **ssrc_list, unsigned char &length)
+{
+ *ssrc_list = this->ssrc_list_;
+ length = this->ssrc_list_length_;
+}
+
+//==============================================================================
+
+const char *
+RTCP_BYE_Packet::reason (void)
+{
+ ACE_CString reason = (const char *)this->reason_;
+
+ return reason.c_str();
+}
+
+//==============================================================================
+
+void
+RTCP_BYE_Packet::build_packet(void)
+{
+ unsigned int index;
+ unsigned int i;
+
+ if (this->packet_data_)
+ delete []this->packet_data_;
+
+ ACE_NEW (this->packet_data_,
+ char[this->packet_size()]);
+
+ index = 0;
+ this->packet_data_[index] = (this->chd_.ver_ << 6) |
+ (this->chd_.pad_ << 5) |
+ this->chd_.count_;
+ index++;
+ this->packet_data_[index] = this->chd_.pt_;
+ index++;
+ *((ACE_UINT16*)&this->packet_data_[index]) = htons(this->chd_.length_);
+ index+=2;
+
+ for (i=0; i<this->chd_.count_; i++)
+ {
+ *((ACE_UINT32*)&this->packet_data_[index]) = htonl(this->ssrc_list_[i]);
+ index+=4;
+ }
+
+ if (this->reason_)
+ {
+ this->packet_data_[index] = this->reason_length_;
+ index++;
+ memcpy(&this->packet_data_[index], this->reason_, this->reason_length_);
+ index += this->reason_length_;
+ while (index < this->packet_size())
+ {
+ this->packet_data_[index] = 0;
+ index ++;
+ }
+ }
+}
+
+void
+RTCP_BYE_Packet::dump (void)
+{
+ ACE_DEBUG ((LM_DEBUG,
+ "\nRTCP_BYE_Packet:: from ssrc(s) "));
+ for (int i=0; i< this->ssrc_list_length_; i++)
+ ACE_DEBUG ((LM_DEBUG,
+ "%u ",
+ this->ssrc_list_[i]));
+ ACE_DEBUG ((LM_DEBUG,
+ "\n Reason '%s'\n",
+ this->reason_));
+}
+
+RTCP_RR_Packet::RTCP_RR_Packet(ACE_UINT32 ssrc, RR_Block *blocks)
+{
+ RR_Block *block_ptr = blocks;
+
+ this->chd_.count_ = 0;
+ this->chd_.ver_ = 2;
+ this->chd_.pt_ = RTCP_PT_RR;
+ this->ssrc_ = ssrc;
+ this->rr_ = blocks;
+
+ while (block_ptr)
+ {
+ this->chd_.count_++;
+
+ // Can only have 31 receiver reports
+ if (this->chd_.count_ == 31)
+ {
+ block_ptr->next_ = 0;
+ break;
+ }
+
+ block_ptr = block_ptr->next_;
+ }
+
+ this->chd_.length_ = 1+6*this->chd_.count_; // + profile specific extensions ??
+
+ this->packet_data_ = 0;
+}
+
+//==============================================================================
+
+RTCP_RR_Packet::RTCP_RR_Packet (char* buffer,
+ int *len)
+ :RTCP_Packet (buffer)
+{
+ unsigned int i = 0;
+ RR_Block *local_block_ptr;
+
+ this->rr_ = 0;
+
+ // The common part of the header is initialized in the parent.
+ i=4;
+ this->ssrc_ = ntohl(*(ACE_UINT32*)&buffer[i]);
+ i+=4;
+ for (unsigned int j=0; j<this->chd_.count_; j++)
+ {
+ if (j==0)
+ {
+ ACE_NEW (this->rr_,
+ RR_Block);
+ local_block_ptr = this->rr_;
+ }
+ else
+ {
+ ACE_NEW (local_block_ptr->next_,
+ RR_Block);
+ local_block_ptr = local_block_ptr->next_;
+ }
+
+ local_block_ptr->next_ = 0;
+ local_block_ptr->ssrc_ = ntohl(*(ACE_UINT32*)&buffer[i]);
+ i+=4;
+ ACE_UINT32 temp = ntohl(*(ACE_UINT32*)&buffer[i]);
+ local_block_ptr->fraction_ = (temp&0xff000000) >> 24;
+ local_block_ptr->lost_ = temp & 0x00ffffff;
+ i+=4;
+ local_block_ptr->last_seq_ = ntohl(*(ACE_UINT32*)&buffer[i]);
+ i+=4;
+ local_block_ptr->jitter_ = ntohl(*(ACE_UINT32*)&buffer[i]);
+ i+=4;
+ local_block_ptr->lsr_ = ntohl(*(ACE_UINT32*)&buffer[i]);
+ i+=4;
+ local_block_ptr->dlsr_ = ntohl(*(ACE_UINT32*)&buffer[i]);
+ i+=4;
+ }
+
+ *len-=(this->chd_.length_+1)*4;
+
+ this->packet_data_ = 0;
+}
+
+//==============================================================================
+
+RTCP_RR_Packet::~RTCP_RR_Packet(void)
+{
+ RR_Block *prev;
+
+ if (this->rr_)
+ {
+ while (this->rr_)
+ {
+ prev = this->rr_;
+ this->rr_ = this->rr_->next_;
+ delete prev;
+ }
+ }
+
+ if (this->packet_data_)
+ delete []this->packet_data_;
+}
+
+//==============================================================================
+
+unsigned int
+RTCP_RR_Packet::packet_size(void)
+{
+ ACE_UINT16 size = (2+this->chd_.count_*6) * 4;
+ return size;
+}
+
+//==============================================================================
+
+void
+RTCP_RR_Packet::build_packet(void)
+{
+ int index;
+ RR_Block *local_block_ptr;
+
+ if (this->packet_data_)
+ delete []this->packet_data_;
+
+ ACE_NEW (this->packet_data_,
+ char [this->packet_size ()]);
+
+ index = 0;
+ this->packet_data_[index] = (this->chd_.ver_ << 6) |
+ (this->chd_.pad_ << 5) |
+ this->chd_.count_;
+ index++;
+ this->packet_data_[index] = chd_.pt_;
+ index++;
+ *((ACE_UINT16*)&this->packet_data_[index]) = htons(chd_.length_);
+ index+=2;
+ *((ACE_UINT32*)&this->packet_data_[index]) = htonl(this->ssrc_);
+ index+=4;
+
+ local_block_ptr = this->rr_;
+ while (local_block_ptr)
+ {
+ *((ACE_UINT32*)&this->packet_data_[index]) = htonl(local_block_ptr->ssrc_);
+ index+=4;
+ ACE_UINT32 temp = htonl((local_block_ptr->fraction_&0xff) << 24) &
+ local_block_ptr->lost_;
+ *((ACE_UINT32*)&this->packet_data_[index]) = temp;
+ index+=4;
+ *((ACE_UINT32*)&this->packet_data_[index]) = htonl(local_block_ptr->last_seq_);
+ index+=4;
+ *((ACE_UINT32*)&this->packet_data_[index]) = htonl(local_block_ptr->jitter_);
+ index+=4;
+ *((ACE_UINT32*)&this->packet_data_[index]) = htonl(local_block_ptr->lsr_);
+ index+=4;
+ *((ACE_UINT32*)&this->packet_data_[index]) = htonl(local_block_ptr->dlsr_);
+ index+=4;
+ local_block_ptr = local_block_ptr->next_;
+ }
+}
+
+void
+RTCP_RR_Packet::dump (void)
+{
+ RR_Block *b = this->rr_;
+ int count = 1;
+
+ ACE_DEBUG ((LM_DEBUG,
+ "\nRTCP_RR_Packet:: from %u - %d rr blocks follow.\n",
+ this->ssrc_,
+ this->chd_.count_));
+
+ while (b)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ " Block %d: ssrc %u; frac %u; lost %u; last seq %u\n",
+ count,
+ b->ssrc_,
+ b->fraction_,
+ b->lost_,
+ b->last_seq_));
+ ACE_DEBUG ((LM_DEBUG,
+ " jitter %u; lsr %u; dlsr %u;\n",
+ b->jitter_,
+ b->lsr_,
+ b->dlsr_));
+
+ b = b->next_;
+ ++count;
+ }
+}
+
+
+RTCP_SDES_Packet::RTCP_SDES_Packet(void) :
+ RTCP_Packet ()
+{
+ this->chd_.pt_ = RTCP_PT_SDES;
+ this->chunk_ = 0;
+ this->packet_data_ = 0;
+ this->num_chunks_ = 0;
+// this->num_items_ = 0;
+}
+
+//==============================================================================
+
+RTCP_SDES_Packet::RTCP_SDES_Packet(char* buffer, int *len):
+ RTCP_Packet (buffer)
+{
+ unsigned int i;
+ sdesChunk_t *cp; // pointer to chunk
+ sdesItem_t *ip; // pointer to item
+
+ // The common part of the control packet header is processed
+ // in the parent. It is 4 bytes long.
+
+ i=4;
+ for (unsigned int j=0; j<this->chd_.count_; j++)
+ {
+ if (j==0)
+ {
+ ACE_NEW (this->chunk_,
+ sdesChunk_t);
+ cp = this->chunk_;
+
+ this->num_chunks_ = 1;
+ }
+ else
+ {
+ ACE_NEW (cp->next_,
+ sdesChunk_t);
+ cp = cp->next_;
+
+ this->num_chunks_++;
+ }
+ cp->next_ = 0;
+ cp->item_ = 0;
+ cp->ssrc_ = ntohl(*(ACE_UINT32*)&buffer[i]);
+ i+=4;
+
+ while (buffer[i]!=RTCP_SDES_END)
+ {
+ if (!cp->item_)
+ {
+ ACE_NEW (cp->item_,
+ sdesItem_t);
+ ip = cp->item_;
+
+// this->num_items_ = 1;
+ }
+ else
+ {
+ ACE_NEW (ip->next_,
+ sdesItem_t);
+ ip = ip->next_;
+
+// this->num_items_++;
+ }
+ ip->next_ = 0;
+ ip->type_ = buffer[i];
+ i++;
+ if (ip->type_ != RTCP_SDES_PRIV)
+ {
+ ip->info_.standard_.length_ = buffer[i];
+ i++;
+ ACE_NEW (ip->info_.standard_.data_,
+ char[ip->info_.standard_.length_+1]);
+ memcpy(ip->info_.standard_.data_,
+ &buffer[i],
+ ip->info_.standard_.length_);
+ ip->info_.standard_.data_[ip->info_.standard_.length_] = 0;
+ i+=ip->info_.standard_.length_;
+ }
+ else
+ {
+ ip->info_.priv_.name_length_ = buffer[i];
+ i++;
+ ip->info_.priv_.data_length_ = buffer[i];
+ i++;
+ ACE_NEW (ip->info_.priv_.name_,
+ char[ip->info_.priv_.name_length_+1]);
+ memcpy(ip->info_.priv_.name_,
+ &buffer[i],
+ ip->info_.priv_.name_length_);
+ ip->info_.priv_.name_[ip->info_.priv_.name_length_] = 0;
+ i+=ip->info_.priv_.name_length_;
+ ACE_NEW (ip->info_.priv_.data_,
+ char[ip->info_.priv_.data_length_+1]);
+ memcpy(ip->info_.priv_.data_,
+ &buffer[i],
+ ip->info_.priv_.data_length_);
+ ip->info_.priv_.data_[ip->info_.priv_.data_length_] = 0;
+ i+=ip->info_.priv_.data_length_;
+ }
+ }
+ i++; // each chunk ends with a zero (END) item
+ // each chunk must end on an even 32 bit boundary
+ while (i%4) i++;
+ }
+
+ *len-=(this->chd_.length_+1)*4;
+
+ this->packet_data_ = 0;
+}
+
+//==============================================================================
+
+RTCP_SDES_Packet::~RTCP_SDES_Packet(void)
+{
+ sdesChunk_t *cp; // pointer to chunk
+ sdesChunk_t *cpprev;
+ sdesItem_t *ip; // pointer to item
+ sdesItem_t *ipprev;
+
+ cp = this->chunk_;
+ while (cp)
+ {
+ ip = cp->item_;
+ while (ip)
+ {
+ ipprev = ip;
+ ip = ip->next_;
+ if (ipprev->type_ != RTCP_SDES_PRIV)
+ {
+ delete []ipprev->info_.standard_.data_;
+ }
+ else
+ {
+ delete []ipprev->info_.priv_.name_;
+ delete []ipprev->info_.priv_.data_;
+ }
+
+ delete ipprev;
+ }
+ cpprev = cp;
+ cp = cp->next_;
+ delete cpprev;
+ }
+
+ if (this->packet_data_)
+ delete []this->packet_data_;
+}
+
+//==============================================================================
+
+void
+RTCP_SDES_Packet::add_chunk(ACE_UINT32 ssrc)
+{
+ sdesChunk_t *cp; // pointer to chunk
+
+ // If this is the first chunk.
+ if (chd_.count_ == 0)
+ {
+ ACE_NEW (this->chunk_,
+ sdesChunk_t);
+ this->chunk_->next_ = 0;
+ this->chunk_->item_ = 0;
+ cp = this->chunk_;
+ }
+ else
+ {
+ cp = this->chunk_;
+ while (cp->next_)
+ cp = cp->next_;
+
+ ACE_NEW (cp->next_,
+ sdesChunk_t);
+ cp = cp->next_;
+ cp->next_ = 0;
+ cp->item_ = 0;
+ }
+ cp->ssrc_ = ssrc; // store the source
+ chd_.count_++; // increment the source count
+}
+
+//==============================================================================
+
+void
+RTCP_SDES_Packet::add_item(ACE_UINT32 ssrc,
+ unsigned char type,
+ unsigned char length,
+ const char *data)
+{
+ sdesChunk_t *cp; // pointer to chunk
+ sdesItem_t *ip; // pointer to item
+
+ if (this->chunk_ == 0)
+ {
+ this->add_chunk(ssrc);
+ }
+ cp = this->chunk_;
+
+ while (cp != 0)
+ {
+ if (cp->ssrc_ == ssrc)
+ break;
+
+ if (!cp->next_)
+ {
+ this->add_chunk(ssrc);
+ cp = cp->next_;
+ break;
+ }
+ cp = cp->next_;
+ }
+
+ ip = cp->item_;
+ if (ip == 0)
+ {
+ ACE_NEW (cp->item_,
+ sdesItem_t);
+ ip = cp->item_;
+ ip->next_= 0;
+ }
+ else
+ {
+ while (ip->next_)
+ ip = ip->next_;
+
+ ACE_NEW (ip->next_,
+ sdesItem_t);
+ ip = ip->next_;
+ ip->next_ = 0;
+ }
+ ip->type_ = type;
+ if (length > 255)
+ {
+ length = 255;
+ ACE_DEBUG ((LM_DEBUG,
+ "RTCP_SDES_Packet::add_item - item too long"));
+ }
+ ip->info_.standard_.length_ = length;
+ ACE_NEW (ip->info_.standard_.data_,
+ char[length]);
+ memcpy(ip->info_.standard_.data_, data, length);
+}
+
+//==============================================================================
+
+void
+RTCP_SDES_Packet::add_priv_item(ACE_UINT32 ssrc,
+ unsigned char nameLength, const char* name,
+ unsigned char dataLength, const char* data)
+{
+ sdesChunk_t *cp; // pointer to chunk
+ sdesItem_t *ip; // pointer to item
+
+ if (this->chunk_ == 0)
+ {
+ this->add_chunk(ssrc);
+ }
+ cp = this->chunk_;
+
+ while (cp != 0)
+ {
+ if (cp->ssrc_ == ssrc)
+ break;
+
+ if (!cp->next_)
+ {
+ this->add_chunk(ssrc);
+ cp = cp->next_;
+ break;
+ }
+ cp = cp->next_;
+ }
+
+ ip = cp->item_;
+ if (ip == 0)
+ {
+ ACE_NEW (cp->item_,
+ sdesItem_t);
+ ip = cp->item_;
+ ip->next_ = 0;
+ }
+ else
+ {
+ while (ip->next_)
+ ip = ip->next_;
+
+ ACE_NEW (ip->next_,
+ sdesItem_t);
+ ip = ip->next_;
+ ip->next_ = 0;
+ }
+
+ ip->type_ = RTCP_SDES_PRIV;
+ if (nameLength > 255)
+ {
+ nameLength = 255;
+ ACE_DEBUG ((LM_DEBUG,
+ "RTCP_SDES_Packet::add_priv_item - name too long"));
+ }
+ if (dataLength > 255)
+ {
+ dataLength = 255;
+ ACE_DEBUG ((LM_DEBUG,
+ "RTCP_SDES_Packet::add_priv_item - data too long"));
+ }
+ ip->info_.priv_.name_length_ = nameLength;
+ ip->info_.priv_.data_length_ = dataLength;
+ ACE_NEW (ip->info_.priv_.name_,
+ char[nameLength]);
+ ACE_NEW (ip->info_.priv_.data_,
+ char[dataLength]);
+ memcpy(ip->info_.priv_.name_, name, nameLength);
+ memcpy(ip->info_.priv_.data_, data, dataLength);
+}
+
+//==============================================================================
+
+unsigned int
+RTCP_SDES_Packet::packet_size(void)
+{
+ int size;
+ sdesChunk_t *cp; // pointer to chunk
+ sdesItem_t *ip; // pointer to item
+
+ // Determine the size of the packet.
+ size = 4; // size of common header data in octets
+
+ cp = this->chunk_;
+ while (cp)
+ {
+ size += 4; // size of ssrc
+ ip = cp->item_;
+
+ while (ip && (ip->type_ != 0))
+ {
+ if (ip->type_ != RTCP_SDES_PRIV)
+ {
+ size += 2 + ip->info_.standard_.length_; // size of item
+ }
+ else
+ {
+ size += 3 + ip->info_.priv_.name_length_ + ip->info_.priv_.data_length_;
+ }
+ ip = ip->next_;
+ }
+ size += 4 - size%4; // pad with zeros to even 32 bit bound
+ cp = cp->next_;
+ }
+
+ chd_.length_ = size/4 - 1;
+
+ return size;
+}
+
+//==============================================================================
+
+void
+RTCP_SDES_Packet::build_packet(void)
+{
+ sdesChunk_t *cp; // pointer to chunk
+ sdesItem_t *ip; // pointer to item
+ int index, i;
+
+ if (this->packet_data_)
+ delete this->packet_data_;
+
+ ACE_NEW (this->packet_data_,
+ char[this->packet_size()]);
+
+ index = 0;
+ this->packet_data_[index] = (chd_.ver_ << 6) | (chd_.pad_ << 5) | chd_.count_;
+ index++;
+ this->packet_data_[index] = chd_.pt_;
+ index++;
+ *((ACE_UINT16*)&this->packet_data_[index]) = htons(chd_.length_);
+ index+=2;
+
+ cp = this->chunk_;
+ while (cp)
+ {
+ *((ACE_UINT32*)&this->packet_data_[index]) = htonl(cp->ssrc_);
+ index+=4;
+
+ ip = cp->item_;
+ while (ip && (ip->type_ != 0))
+ {
+ this->packet_data_[index] = ip->type_;
+ index++;
+ if (ip->type_ != RTCP_SDES_PRIV)
+ {
+ this->packet_data_[index] = ip->info_.standard_.length_;
+ index++;
+ for (i=0; i<ip->info_.standard_.length_; i++)
+ {
+ this->packet_data_[index] = ip->info_.standard_.data_[i];
+ index++;
+ }
+ }
+ else
+ {
+ this->packet_data_[index] = ip->info_.priv_.name_length_;
+ index++;
+ this->packet_data_[index] = ip->info_.priv_.data_length_;
+ index++;
+ for (i=0; i<ip->info_.priv_.name_length_; i++)
+ {
+ this->packet_data_[index] = ip->info_.priv_.name_[i];
+ index++;
+ }
+ for (i=0; i<ip->info_.priv_.data_length_; i++)
+ {
+ this->packet_data_[index] = ip->info_.priv_.data_[i];
+ index++;
+ }
+ }
+
+ ip = ip->next_;
+ }
+
+ this->packet_data_[index] = 0;
+ index++;
+
+ i=1;
+ while ((index)%4)
+ { // pad chunk with zeros to 32 bit bound
+ this->packet_data_[index] = 0;
+ index++;
+ i++;
+ }
+
+ // Store the number of bytes added. TODO: do we need this
+ // this->packet_data_[index - 1] = i;
+
+ cp = cp->next_;
+ }
+}
+
+void
+RTCP_SDES_Packet::dump (void)
+{
+ sdesItem_t *ip;
+
+ ACE_DEBUG ((LM_DEBUG,
+ "\nRTCP_SDES_Packet:: "));
+
+ if (this->num_chunks_ != 1)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "Mixers not currently supported.\n"));
+ return;
+ }
+
+ ACE_DEBUG ((LM_DEBUG,
+ "from ssrc %u\n",
+ this->chunk_->ssrc_));
+
+ // Loop through all of the items.
+ ip = this->chunk_->item_;
+
+ while (ip)
+ {
+ // If there is no data to store, continue.
+ if (ip->info_.standard_.length_ == 0)
+ {
+ ip = ip->next_;
+ continue;
+ }
+
+ switch (ip->type_)
+ {
+ case RTCP_SDES_END:
+ break;
+ case RTCP_SDES_CNAME:
+ ACE_DEBUG ((LM_DEBUG,
+ " CNAME '%s'\n",
+ ip->info_.standard_.data_));
+ break;
+ case RTCP_SDES_NAME:
+ ACE_DEBUG ((LM_DEBUG,
+ " NAME '%s'\n",
+ ip->info_.standard_.data_));
+ break;
+ case RTCP_SDES_EMAIL:
+ ACE_DEBUG ((LM_DEBUG,
+ " EMAIL '%s'\n",
+ ip->info_.standard_.data_));
+ break;
+ case RTCP_SDES_PHONE:
+ ACE_DEBUG ((LM_DEBUG,
+ " PHONE '%s'\n",
+ ip->info_.standard_.data_));
+ break;
+ case RTCP_SDES_LOC:
+ ACE_DEBUG ((LM_DEBUG,
+ " LOC '%s'\n",
+ ip->info_.standard_.data_));
+ break;
+ case RTCP_SDES_TOOL:
+ ACE_DEBUG ((LM_DEBUG,
+ " TOOL '%s'\n",
+ ip->info_.standard_.data_));
+ break;
+ case RTCP_SDES_NOTE:
+ ACE_DEBUG ((LM_DEBUG,
+ " NOTE '%s'\n",
+ ip->info_.standard_.data_));
+ break;
+ case RTCP_SDES_PRIV:
+ ACE_DEBUG ((LM_DEBUG,
+ " '%s' '%s'\n",
+ ip->info_.priv_.name_,
+ ip->info_.priv_.data_));
+ break;
+ }
+ ip = ip->next_;
+ }
+
+}
+
+RTCP_SR_Packet::RTCP_SR_Packet(ACE_UINT32 ssrc,
+ ACE_UINT32 ntp_ts_msw,
+ ACE_UINT32 ntp_ts_lsw,
+ ACE_UINT32 timestamp,
+ ACE_UINT32 packets_sent,
+ ACE_UINT32 octets_sent,
+ RR_Block *blocks)
+{
+ RR_Block *block_ptr= 0;
+ chd_.count_ = 0;
+ chd_.ver_ = 2;
+ chd_.pt_ = RTCP_PT_SR;
+
+ this->ssrc_ = ssrc;
+ this->ntp_ts_msw_ = ntp_ts_msw;
+ this->ntp_ts_lsw_ = ntp_ts_lsw;
+ this->rtp_ts_ = timestamp;
+ this->psent_ = packets_sent;
+ this->osent_ = octets_sent;
+ this->rr_ = blocks;
+
+ block_ptr = blocks;
+
+ while (block_ptr)
+ {
+ chd_.count_++;
+
+ // Can only have 31 receiver reports
+ if (this->chd_.count_ == 31)
+ {
+ block_ptr->next_ = 0;
+ break;
+ }
+
+ block_ptr = block_ptr->next_;
+ }
+
+ this->chd_.length_ = 6 + 6*chd_.count_; //+profile specific extensions ??
+
+ this->packet_data_ = 0;
+}
+
+//==============================================================================
+
+RTCP_SR_Packet::RTCP_SR_Packet (char* buffer,
+ int *len)
+ : RTCP_Packet (buffer)
+{
+ unsigned int i = 0;
+ RR_Block *local_block_ptr;
+
+ this->rr_ = 0;
+
+ // The common part of the header is initialized in the parent.
+ i=4;
+ this->ssrc_ = ntohl(*(ACE_UINT32*)&buffer[i]);
+ i+=4;
+ this->ntp_ts_msw_ = ntohl(*(ACE_UINT32*)&buffer[i]);
+ i+=4;
+ this->ntp_ts_lsw_ = ntohl(*(ACE_UINT32*)&buffer[i]);
+ i+=4;
+ this->rtp_ts_ = ntohl(*(ACE_UINT32*)&buffer[i]);
+ i+=4;
+ this->psent_ = ntohl(*(ACE_UINT32*)&buffer[i]);
+ i+=4;
+ this->osent_ = ntohl(*(ACE_UINT32*)&buffer[i]);
+ i+=4;
+ for (unsigned int j=0; j<this->chd_.count_; j++)
+ {
+ if (j==0)
+ {
+ ACE_NEW (local_block_ptr,
+ RR_Block);
+ this->rr_ = local_block_ptr;
+ }
+ else
+ {
+ ACE_NEW (local_block_ptr->next_,
+ RR_Block);
+ local_block_ptr = local_block_ptr->next_;
+ }
+
+ local_block_ptr->next_ = 0;
+ local_block_ptr->ssrc_ = ntohl(*(ACE_UINT32*)&buffer[i]);
+ i+=4;
+ ACE_UINT32 temp = ntohl(*(ACE_UINT32*)&buffer[i]);
+ local_block_ptr->fraction_ = (temp&0xff000000) >> 24;
+ local_block_ptr->lost_ = temp & 0x00ffffff;
+ i+=4;
+ local_block_ptr->last_seq_ = ntohl(*(ACE_UINT32*)&buffer[i]);
+ i+=4;
+ local_block_ptr->jitter_ = ntohl(*(ACE_UINT32*)&buffer[i]);
+ i+=4;
+ local_block_ptr->lsr_ = ntohl(*(ACE_UINT32*)&buffer[i]);
+ i+=4;
+ local_block_ptr->dlsr_ = ntohl(*(ACE_UINT32*)&buffer[i]);
+ i+=4;
+ }
+
+ *len-=(this->chd_.length_+1)*4;
+
+ this->packet_data_ = 0;
+}
+
+//==============================================================================
+
+RTCP_SR_Packet::~RTCP_SR_Packet(void)
+{
+ RR_Block *prev;
+
+ if (this->rr_)
+ {
+ while (this->rr_)
+ {
+ prev = this->rr_;
+ this->rr_ = this->rr_->next_;
+ delete prev;
+ }
+ }
+
+ if (this->packet_data_)
+ delete []this->packet_data_;
+}
+
+//==============================================================================
+
+unsigned int RTCP_SR_Packet::packet_size (void)
+{
+ ACE_UINT16 size = (2+chd_.count_*6) * 4; // + profile specific extensions ?
+ size += 20; // the first line is the same as RR; 20 more bytes for SR
+
+ return size;
+}
+
+//==============================================================================
+
+void RTCP_SR_Packet::build_packet(void)
+{
+ int index = 0;
+ RR_Block *local_block_ptr;
+
+ if (this->packet_data_)
+ delete []this->packet_data_;
+
+ ACE_NEW (this->packet_data_,
+ char[this->packet_size()]);
+
+ this->packet_data_[index] = (this->chd_.ver_ << 6) | (this->chd_.pad_ << 5) | this->chd_.count_;
+ index++;
+ this->packet_data_[index] = this->chd_.pt_;
+ index++;
+ *((ACE_UINT16*)&this->packet_data_[index]) = htons(this->chd_.length_);
+ index+=2;
+ *((ACE_UINT32*)&this->packet_data_[index]) = htonl(this->ssrc_);
+ index+=4;
+ *((ACE_UINT32*)&this->packet_data_[index]) = htonl(this->ntp_ts_msw_);
+ index+=4;
+ *((ACE_UINT32*)&this->packet_data_[index]) = htonl(this->ntp_ts_lsw_);
+ index+=4;
+ *((ACE_UINT32*)&this->packet_data_[index]) = htonl(this->rtp_ts_);
+ index+=4;
+ *((ACE_UINT32*)&this->packet_data_[index]) = htonl(this->psent_);
+ index+=4;
+ *((ACE_UINT32*)&this->packet_data_[index]) = htonl(this->osent_);
+ index+=4;
+
+ local_block_ptr = this->rr_;
+ while (local_block_ptr)
+ {
+ *((ACE_UINT32*)&this->packet_data_[index]) = htonl(local_block_ptr->ssrc_);
+ index+=4;
+ ACE_UINT32 temp = htonl((local_block_ptr->fraction_&0xff) << 24) &
+ local_block_ptr->lost_;
+ *((ACE_UINT32*)&this->packet_data_[index]) = temp;
+ index+=4;
+ *((ACE_UINT32*)&this->packet_data_[index]) = htonl(local_block_ptr->last_seq_);
+ index+=4;
+ *((ACE_UINT32*)&this->packet_data_[index]) = htonl(local_block_ptr->jitter_);
+ index+=4;
+ *((ACE_UINT32*)&this->packet_data_[index]) = htonl(local_block_ptr->lsr_);
+ index+=4;
+ *((ACE_UINT32*)&this->packet_data_[index]) = htonl(local_block_ptr->dlsr_);
+ index+=4;
+ local_block_ptr = local_block_ptr->next_;
+ }
+}
+
+void
+RTCP_SR_Packet::dump (void)
+{
+ RR_Block *b = this->rr_;
+ int count = 1;
+
+ ACE_DEBUG ((LM_DEBUG,
+ "\nRTCP_SR_Packet:: from %u - %d rr blocks follow.\n",
+ this->ssrc_,
+ this->chd_.count_));
+ ACE_DEBUG ((LM_DEBUG,
+ " NTP(sec) %u.%u; RTP ts %u\n",
+ this->ntp_ts_msw_,
+ this->ntp_ts_lsw_,
+ this->rtp_ts_));
+ ACE_DEBUG ((LM_DEBUG,
+ " packets sent %u; octets sent %u\n",
+ this->psent_,
+ this->osent_));
+
+ while (b)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ " Block %d: ssrc %u; frac %u; lost %u; last seq %u\n",
+ count,
+ b->ssrc_,
+ b->fraction_,
+ b->lost_,
+ b->last_seq_));
+ ACE_DEBUG ((LM_DEBUG,
+ " jitter %u; lsr %u; dlsr %u;\n",
+ b->jitter_,
+ b->lsr_,
+ b->dlsr_));
+
+ b = b->next_;
+ ++count;
+ }
+}
diff --git a/TAO/orbsvcs/orbsvcs/AV/RTCP_Packet.h b/TAO/orbsvcs/orbsvcs/AV/RTCP_Packet.h
new file mode 100644
index 00000000000..32163374aca
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/AV/RTCP_Packet.h
@@ -0,0 +1,393 @@
+// $Id$
+#ifndef RTCP_PACKET_INCLUDE
+#define RTCP_PACKET_INCLUDE
+
+#include "ace/OS.h"
+
+/**
+ * @struct RTCP_Common_Header
+ * @brief This is the header data that is common to all RTCP messages.
+ */
+typedef struct
+{
+ /// the RTP version being used
+ unsigned int ver_:2;
+
+ /// indicates whether or not the end of the packet is padded with zeros
+ unsigned int pad_:1;
+
+ /// this value varies by packet type
+ unsigned int count_:5;
+
+ /// RTCP packet type (eg BYE, SR, RR, SDES)
+ unsigned int pt_:8;
+
+ /// packet length in words without this word
+ ACE_UINT16 length_;
+} RTCP_Common_Header;
+
+/**
+ * @class RTCP_Packet
+ * @brief This is an abstract class from which all RTCP packet types are derived.
+ * It contains code used to validate the RTCP packet.
+ */
+
+class RTCP_Packet
+{
+public:
+ /// Constructor for outgoing RTCP packets.
+ RTCP_Packet(void);
+
+ /// Constructor for incoming RTCP packets.
+ RTCP_Packet(char *buffer);
+
+ /// Destructor
+ virtual ~RTCP_Packet() = 0;
+
+ /// Returns a pointer to a local buffer containing the packet.
+ void get_packet_data(char **buffer, ACE_UINT16 &length);
+
+ /// Returns the size of the packet.
+ /// Defined in child class.
+ virtual unsigned int packet_size(void) = 0;
+
+ /// Checks the validity of an RTCP packet. RTCP packets can be sent
+ /// together in a compound packet and is_first indicates the first packet
+ /// in a compound packet
+ int is_valid (char is_first);
+
+protected:
+ /// Header data common to all RTCP packets.
+ RTCP_Common_Header chd_;
+
+ /// Buffer to hold byte representation of the RTCP packet.
+ char *packet_data_;
+
+ /// Used to create the byte representation of the RTCP packet.
+ /// Defined in child class.
+ virtual void build_packet(void) = 0;
+};
+
+/**
+ * @class RTCP_BYE_Packet
+ * @brief The BYE RTCP packet is sent by a party when leaving an RTP session.
+ */
+
+class RTCP_BYE_Packet : public RTCP_Packet
+{
+public:
+ /// Constructor for outgoing BYE RTCP packets.
+ /// Takes a synchronization source id list, the list length (1 for non-mixers),
+ /// and an optional reason for leaving the session.
+ RTCP_BYE_Packet (ACE_UINT32 *srcList,
+ unsigned char length,
+ const char* text=0);
+
+ /// Constructor for incoming BYE RTCP packets.
+ RTCP_BYE_Packet (char *buffer,
+ int *len);
+
+ /// Destructor.
+ virtual ~RTCP_BYE_Packet (void);
+
+ /// Returns the size of the packet in bytes.
+ unsigned int packet_size (void);
+
+ /// Returns a pointer to a local list of synchronization source ids that are
+ /// leaving the session.
+ void ssrc_list (ACE_UINT32 **ssrc_list,
+ unsigned char &length);
+
+ /// Returns the reason for leaving the session.
+ const char *reason (void);
+
+ /// Prints the contents of the packet.
+ void dump (void);
+
+private:
+ /// Used to create the byte representation of the RTCP packet.
+ void build_packet();
+
+ /// List of synchronization source ids that are leaving the session.
+ ACE_UINT32 *ssrc_list_;
+
+ /// The number of ssrc's that are leaving the session (1 for non-mixers).
+ unsigned char ssrc_list_length_;
+
+ /// An optional reason for leaving the session.
+ char reason_[256];
+
+ /// The number of bytes in the reason for leaving the session.
+ unsigned char reason_length_;
+};
+
+/**
+ * @struct RR_Block
+ * @brief The receiver report block encapsulates the data that represents the
+ * reception statistics for a particular stream.
+ */
+
+struct RR_Block
+{
+ /// The synchronization source id of the source of the data.
+ ACE_UINT32 ssrc_;
+
+ /// The fraction of RTP data packets lost since the previous SR or RR was sent.
+ unsigned int fraction_:8;
+
+ /// The cumulative number of packets lost.
+ int lost_:24;
+
+ /// The highest extended sequence number received in an RTP packet.
+ ACE_UINT32 last_seq_;
+
+ /// An estimate of the statistical variance of the RTP data packet interarrival
+ /// time measured in timestamp units.
+ ACE_UINT32 jitter_;
+
+ /// The middle 32 bits of the NTP timestamp received in the most recent sender
+ /// report.
+ ACE_UINT32 lsr_;
+
+ /// The delay in 1/65536 seconds since receiving the last sender report.
+ ACE_UINT32 dlsr_;
+
+ /// Link to the next receiver report block.
+ RR_Block *next_;
+};
+
+/**
+ * @class RTCP_RR_Packet
+ * @brief The Receiver Report packet is sent by all members of a session that
+ * are not sending data. It contains a list of RR_Block to represent each
+ * source this party is receiving data from.
+ */
+
+class RTCP_RR_Packet : public RTCP_Packet
+{
+public:
+ /// Constructor for incoming receiver reports.
+ RTCP_RR_Packet (char *buffer, int* len);
+
+ /// Constructor for outgoing receiver reports.
+ RTCP_RR_Packet (ACE_UINT32 ssrc, RR_Block *blocks);
+
+ /// Destructor.
+ virtual ~RTCP_RR_Packet (void);
+
+ /// Returns the size of the packet in bytes.
+ unsigned int packet_size(void);
+
+ /// Returns the synchronization source id of the source sending this packet.
+ ACE_INT32 ssrc (void) { return this->ssrc_; }
+
+ /// Prints the contents of the packet.
+ void dump (void);
+
+private:
+ /// Used to create the byte representation of the RTCP packet.
+ void build_packet(void);
+
+ /// The synchronization source id of the sender of this report.
+ ACE_UINT32 ssrc_;
+
+ /// A linked list of the receiver report block(s) being sent.
+ RR_Block *rr_;
+};
+
+typedef struct sdesItem_s sdesItem_t;
+
+/**
+ * @struct sdesItem_s
+ * @brief This is a linked list of structures containing source description
+ * 'items' such as canonical name, email, location etc.
+ */
+
+struct sdesItem_s
+{
+ /// link to next item.
+ sdesItem_t *next_;
+
+ /// Type of item (eg canonical name).
+ unsigned char type_;
+
+ union
+ {
+ struct
+ {
+ /// Length of an item (in octets).
+ unsigned char length_;
+
+ /// Item text, not null-terminated.
+ char *data_;
+ } standard_;
+ struct
+ {
+ /// Length of the name of an item (in octets).
+ unsigned char name_length_;
+
+ /// Length of the item data (in octets).
+ unsigned char data_length_;
+
+ /// The name of the item, not null-terminated.
+ char *name_;
+
+ /// Item data, not null-terminated.
+ char *data_;
+ } priv_;
+ } info_;
+};
+
+typedef struct sdesChunk_s sdesChunk_t;
+
+/**
+ * @struct sdesChunk_s
+ * @brief This is a linked list of structures containing groups of source
+ * description items. A group of items for a particular synchronization source
+ * id is referred to as a 'chunk'.
+ */
+struct sdesChunk_s
+{
+ /// Link to next item.
+ sdesChunk_t *next_;
+
+ /// The synchronization source id that this chunk describes.
+ ACE_UINT32 ssrc_;
+
+ /// A linked list of items to describe this source.
+ sdesItem_t *item_;
+};
+
+/**
+ * @class RTCP_SDES_Packet
+ * @brief The Source Description packet is sent by all members of a session.
+ * At a minimum, the canonical name (or CNAME) is sent with each RTCP packet.
+ * Other items such as name, email, or location are included less frequently.
+ */
+class RTCP_SDES_Packet : public RTCP_Packet
+{
+public:
+ /// Constructor for incoming SDES packets.
+ RTCP_SDES_Packet(char* buffer, int *len);
+
+ /// Constructor for outgoing SDES packets.
+ RTCP_SDES_Packet(void);
+
+ /// Destructor.
+ virtual ~RTCP_SDES_Packet(void);
+
+ /// This will add a standard item of type and length for the ssrc specified.
+ /// When the first item for a ssrc is added, a chunk is created. Subsequent
+ /// items for that ssrc are added to the same chunk. New chunks are created
+ /// for each unique ssrc.
+ void add_item(ACE_UINT32 ssrc,
+ unsigned char type,
+ unsigned char length,
+ const char* data);
+
+ /// This will add a private item using the name and data for the ssrc specified.
+ /// When the first item for a ssrc is added, a chunk is created. Subsequent
+ /// items for that ssrc are added to the same chunk. New chunks are created
+ /// for each unique ssrc.
+ void add_priv_item(ACE_UINT32 ssrc,
+ unsigned char nameLength,
+ const char *name,
+ unsigned char dataLength,
+ const char *data);
+
+ /// Returns the size of the packet in bytes.
+ unsigned int packet_size(void);
+
+ /// Prints the contents of the packet.
+ void dump (void);
+
+ /// This returns the synchronization source id for this packet. This assumes
+ /// that this source is only receiving messages from end systems (i.e. only
+ /// one source id per SDES)
+ ACE_UINT32 ssrc (void) { return this->chunk_->ssrc_; }
+
+private:
+ /// Used to create the byte representation of the RTCP packet.
+ void build_packet(void);
+
+ /// Add a chunk to the packet.
+ void add_chunk(ACE_UINT32 ssrc);
+
+ /// The number of chunks contained in this packet.
+ /// 1 for end systems, 1+ for mixers
+ unsigned long num_chunks_;
+
+// unsigned long num_items_;
+
+ /// A linked list of chunks for this packet (only 1 for non-mixers).
+ sdesChunk_t *chunk_;
+};
+
+/**
+ * @class RTCP_SR_Packet
+ * @brief The Sender Report packet is sent by all members of a session that
+ * are sending data. It contains statistics on the data being sent out. It
+ * also contains a list of RR_Block to represent each source this party is
+ * receiving data from.
+ */
+
+class RTCP_SR_Packet : public RTCP_Packet
+{
+public:
+ /// Constructor for incoming SR packets.
+ RTCP_SR_Packet(char *buffer, int *len);
+
+ /// Constructor for outgoing SR packets.
+ RTCP_SR_Packet(ACE_UINT32 ssrcVal,
+ ACE_UINT32 ntpMSByte,
+ ACE_UINT32 ntpLSByte,
+ ACE_UINT32 timestamp,
+ ACE_UINT32 pktsSent,
+ ACE_UINT32 octetsSent,
+ RR_Block *rrBlocks);
+
+ /// Destructor
+ virtual ~RTCP_SR_Packet(void);
+
+ /// Returns the size of the packet in bytes.
+ unsigned int packet_size(void);
+
+ /// Returns the synchronization source id for the sender of this packet.
+ ACE_UINT32 ssrc (void) { return this->ssrc_; }
+
+ /// Returns the most significant word of the NTP timestamp.
+ ACE_UINT32 ntp_ts_msw (void) { return this->ntp_ts_msw_; }
+
+ /// Returns the least significant word of the NTP timestamp.
+ ACE_UINT32 ntp_ts_lsw (void) { return this->ntp_ts_lsw_; }
+
+ /// Prints the contents of the packet.
+ void dump (void);
+
+private:
+ /// Used to create the byte representation of the RTCP packet.
+ void build_packet(void);
+
+ /// The synchronization source id of the sender generating this report.
+ ACE_UINT32 ssrc_;
+
+ /// The most significant word of the NTP timestamp.
+ ACE_UINT32 ntp_ts_msw_;
+
+ /// The least significant word of the NTP timestamp.
+ ACE_UINT32 ntp_ts_lsw_;
+
+ /// The RTP timestamp
+ ACE_UINT32 rtp_ts_;
+
+ /// The total number of packets sent.
+ ACE_UINT32 psent_;
+
+ /// The total number of octets sent.
+ ACE_UINT32 osent_;
+
+ /// A linked list of receiver report blocks.
+ RR_Block *rr_;
+};
+
+#endif
diff --git a/TAO/orbsvcs/orbsvcs/AV/RTP.cpp b/TAO/orbsvcs/orbsvcs/AV/RTP.cpp
index 86004989792..ba4ffe21a8a 100644
--- a/TAO/orbsvcs/orbsvcs/AV/RTP.cpp
+++ b/TAO/orbsvcs/orbsvcs/AV/RTP.cpp
@@ -38,89 +38,310 @@
#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)
+// RTP_Packet
+
+// Constructor for RTP packets received
+RTP_Packet::RTP_Packet(char* buffer, int length)
+{
+ // skip the standard header info
+ int index = 12;
+
+ memcpy(this->packet_, buffer, length);
+
+ for (int j=0; j<(int)this->cc(); j++)
{
- // state->bad_version_++;
- ACE_ERROR_RETURN ( (LM_ERROR,"TAO_AV_RTP:bad version\n"),-1);
+ this->host_byte_order_csrc_list_[j] = ntohl(*(ACE_UINT32*)&buffer[index]);
+ index+=4;
}
- 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;
+
+ // ignore the header extension if there is one
+ if (this->ext())
+ {
+ index+=2;
+ int extension_data_size = ntohs(*(ACE_UINT16*)&buffer[index]);
+ index+=2;
+ index+=extension_data_size;
+
+ this->extension_bytes_ = 4 + extension_data_size;
+ }
+ else
+ this->extension_bytes_ = 0;
+
+ this->packet_size_ = length;
+ this->payload_size_ = length-index;
+
+ // This is necessary only for payload types that have 16 bit values to correct
+ // the network byte ordering.
+ if ((this->pt() == RTP_PT_L16_OTHER) ||
+ (this->pt() == RTP_PT_L16_STEREO) ||
+ (this->pt() == RTP_PT_L16_MONO))
+ {
+ for (int i=0; i < payload_size_; i+=2)
+ {
+ *(ACE_UINT16*)&this->host_byte_order_payload_[i] = ntohs(*(ACE_UINT16*)&this->packet_[index]);
+ index+=2;
+ }
+ }
+}
+
+RTP_Packet::RTP_Packet(unsigned char padding,
+ unsigned char marker,
+ unsigned char payload_type,
+ ACE_UINT32 seq_num,
+ ACE_UINT32 timestamp,
+ ACE_UINT32 ssrc,
+ unsigned char csrc_count,
+ ACE_UINT32 *csrc_list,
+ char *data,
+ ACE_UINT16 data_size)
+ :extension_bytes_(0)
+{
+ //size of header (in octets) without contributing sources
+ ACE_UINT16 size = 3*4;
+ int index = 0;
+
+ if (data_size > RTP_MTU-12)
+ {
+ data_size = RTP_MTU-12;
+ ACE_DEBUG ((LM_DEBUG, "\n(%N,%l) RTP_Packet: Warning - packet truncated\n"));
+ }
+
+ if (csrc_count > 15)
+ csrc_count = 15; // Only 15 contributing sources can be specified.
+
+ if (csrc_list != 0)
+ for (unsigned char i=0; i<csrc_count; i++)
+ {
+ size+=4;
+ this->host_byte_order_csrc_list_[i] = csrc_list[i];
+ }
+
+ this->packet_size_ = size + data_size;
+
+ index = 0;
+ this->packet_[index] = ((RTP_VERSION & 0x3) << 6) |
+ ((padding & 0x1) << 5) |
+ ((0 & 0x1) << 4) | // extension bit
+ ((csrc_count & 0xf));
+
+ index++;
+ this->packet_[index] = ((marker & 0x1) << 7 ) |
+ ((payload_type & 0x7f));
+ index++;
+ *((ACE_UINT16*)&this->packet_[index]) = (ACE_UINT16)htons(seq_num);
+ index+=2;
+ *((ACE_UINT32*)&this->packet_[index]) = (ACE_UINT32)htonl(timestamp);
+ index+=4;
+ *((ACE_UINT32*)&this->packet_[index]) = htonl(ssrc);
+ index+=4;
+
+ for (int i=0; i<csrc_count; i++)
+ {
+ *((ACE_UINT32*)&this->packet_[index]) = htonl(this->host_byte_order_csrc_list_[i]);
+ index+=4;
+ }
+
+ memcpy (this->host_byte_order_payload_, data, data_size);
+
+ this->payload_size_ = data_size;
+
+ // Correct byte ordering for multi-byte payload types.
+ if ((this->pt() == RTP_PT_L16_OTHER) ||
+ (this->pt() == RTP_PT_L16_STEREO) ||
+ (this->pt() == RTP_PT_L16_MONO))
+ {
+ for (int i=0; i<this->payload_size_; i+=2)
+ {
+ *(ACE_UINT16*)&this->packet_[index] = htons(*(ACE_UINT16*)&data[i]);
+ index+=2;
+ }
+ }
+ else
+ for (int i=0; i<this->payload_size_; i++)
+ {
+ this->packet_[index] = data[i];
+ index++;
+ }
+}
+
+RTP_Packet::~RTP_Packet(void)
+{
+}
+
+ACE_UINT16
+RTP_Packet::packet_size(void)
+{
+ return this->packet_size_;
+}
+
+ACE_UINT16
+RTP_Packet::payload_size(void)
+{
+ return this->payload_size_;
+}
+
+unsigned int
+RTP_Packet::ver (void)
+{
+ return ( this->packet_[0] & 0xC0 ) >> 6;
+}
+
+unsigned int
+RTP_Packet::pad (void)
+{
+ return ( this->packet_[0] & 0x20 ) >> 5;
+}
+
+unsigned int
+RTP_Packet::ext (void)
+{
+ return ( this->packet_[0] & 0x10 ) >> 4;
+}
+
+unsigned int
+RTP_Packet::cc (void)
+{
+ return ( this->packet_[0] & 0x0F ) ;
+}
+
+unsigned int
+RTP_Packet::mrk (void)
+{
+ return ( this->packet_[1] & 0x80 ) >> 7;
+}
+
+unsigned int
+RTP_Packet::pt (void)
+{
+ return ( this->packet_[1] & 0x7F ) ;
+}
+
+ACE_UINT16
+RTP_Packet::sn (void)
+{
+ return ntohs(*(ACE_UINT16*)(&this->packet_[2])) ;
+}
+
+ACE_UINT32
+RTP_Packet::ts (void)
+{
+ return ntohl(*(ACE_UINT32*)(&this->packet_[4])) ;
+}
+
+ACE_UINT32
+RTP_Packet::ssrc (void)
+{
+ return ntohl(*(ACE_UINT32*)(&this->packet_[8])) ;
}
+unsigned int
+RTP_Packet::ext_bytes (void)
+{
+ return this->extension_bytes_;
+}
+
+void
+RTP_Packet::get_frame_info (TAO_AV_frame_info *frame_info)
+{
+ frame_info->timestamp = this->mrk();
+ frame_info->timestamp = this->ts();
+ frame_info->ssrc = this->ssrc();
+ frame_info->sequence_num = this->sn();
+ frame_info->format = this->pt();
+}
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;
+RTP_Packet::is_valid (void)
+{
+ // taken from RFC 1889 - Appendix A.1
+
+ // make sure the RTP version is correct
+ if (this->ver() != RTP_VERSION)
+ return 0;
+
+ // make sure the payload type is not SR or RR
+ if ((this->pt() == RTCP_PT_SR) || (this->pt() == RTCP_PT_RR))
+ return 0;
+
+ // if the p bit is set, the last octet of the packet must contain a valid
+ // octet count, in particular, less than the total packet length minus
+ // the header size.
+ if (this->pad() != 0)
+ if ((unsigned int)this->packet_[this->packet_size_] >=
+ (this->packet_size_ - (12 + this->cc() + this->extension_bytes_)))
+ return 0;
+
+ // If there is an extension, it is ignored (taken care of in constructor)
+
+ // The length of the packet must be consistent with CC and payload type (if
+ // payloads have a known length)
+
+ return 1;
}
+void
+RTP_Packet::get_csrc_list (ACE_UINT32 **csrc_list, ACE_UINT16 &length)
+{
+ *csrc_list = this->host_byte_order_csrc_list_;
+ length = this->cc ();
+}
+
+void
+RTP_Packet::get_payload (char **payload, ACE_UINT16 &length)
+{
+ *payload = this->host_byte_order_payload_ ;
+ length = this->payload_size_;
+}
+
+void
+RTP_Packet::get_packet_data (char **packet, ACE_UINT16 &length)
+{
+ *packet = this->packet_;
+ length = this->packet_size_;
+}
+
+
// TAO_AV_RTP_Object
int
TAO_AV_RTP_Object::handle_input (void)
{
- TAO_AV_frame_info *frame_info = 0;
+ TAO_AV_frame_info frame_info;
- // Handles the incoming RTP packet input.
+ if (TAO_debug_level > 1)
+ ACE_DEBUG ((LM_DEBUG,
+ "\nTAO_AV_RTP_Object::handle_input\n"));
+ // 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;
-
if(this->control_object_)
- this->control_object_->handle_control_input (data,
- *addr);
+ this->control_object_->handle_control_input (&this->frame_, *addr);
- this->frame_.rd_ptr (sizeof(TAO_AV_RTP::rtphdr));
- result = this->callback_->receive_frame (&this->frame_,
- frame_info,
- *addr);
+ // Get payload that has been converted to host byte order
+ char *data_ptr;
+ ACE_UINT16 length;
+ RTP_Packet rtp_packet(this->frame_.rd_ptr (), this->frame_.length ());
+
+ rtp_packet.get_frame_info (&frame_info);
+ rtp_packet.get_payload(&data_ptr, length);
+
+ this->frame_.rd_ptr (this->frame_.base ());
+ memcpy (this->frame_.rd_ptr (), data_ptr, length);
+ this->frame_.wr_ptr (this->frame_.rd_ptr() + length);
+
+ this->callback_->receive_frame (&this->frame_, &frame_info, *addr);
return 0;
}
@@ -129,38 +350,116 @@ int
TAO_AV_RTP_Object::send_frame (ACE_Message_Block *frame,
TAO_AV_frame_info *frame_info)
{
- TAO_AV_RTP::rtphdr header;
+// ACE_Addr *addr = this->transport_->get_peer_addr ();
+
int result = -1;
+ RTP_Packet *rtp_packet;
+ ACE_UINT32 csrc_count = 0; // Assume for now no mixers/translators
+ ACE_UINT32 *csrc_list = 0;
+
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_;
+ if (frame_info->format != this->format_)
+ ACE_DEBUG ((LM_DEBUG,
+ "TAO_AV_RTP_Object::send_frame - error: format type mismatch"));
+ if (frame_info->ssrc != 0)
+ this->ssrc_ = frame_info->ssrc;
+
+ TAO_AV_RTCP_Object *rtcp_prot_obj = ACE_dynamic_cast (TAO_AV_RTCP_Object*,
+ this->control_object_);
+ // set the ssrc on the control object so the RTCP traffic can be matched
+ // to the RTP traffic
+ rtcp_prot_obj->ssrc(this->ssrc_);
+
+ ACE_NEW_RETURN (rtp_packet,
+ RTP_Packet (0, // padding
+ frame_info->boundary_marker, // marker
+ this->format_, // payload type
+ frame_info->sequence_num, // sequence num
+ frame_info->timestamp, // time stamp
+ this->ssrc_, // ssrc
+ csrc_count, // csrc count
+ csrc_list, // csrc list
+ frame->rd_ptr (), // data
+ frame->length ()), // data size
+ -1);
+
+ frame_info->sequence_num ++;
}
else
{
- ACE_Time_Value ts = ACE_OS::gettimeofday();
- result = TAO_AV_RTP::write_header (header,
- 0,
- this->sequence_num_,
- (ACE_UINT32)ts.msec(),
- 0,
- 0);
+ // TODO: For periodic RTP packets (constant rate), the RFC suggests
+ // increasing the clock by the number of samples each frame rather
+ // than relying on the system time
+
+ // The RFC specifies at least one timestamp unit per sample as well as a
+ // random offset. It used to be in milliseconds so I left it that way
+ // for non-audio streams.
+ unsigned int samples_per_sec;
+ double samples_per_usec;
+
+ switch (this->format_)
+ {
+ case RTP_PT_PCMU:
+ case RTP_PT_CELP:
+ case RTP_PT_G721:
+ case RTP_PT_GSM:
+ case RTP_PT_DVI:
+ case RTP_PT_LPC:
+ case RTP_PT_PCMA:
+ case RTP_PT_G722:
+ samples_per_sec = 8000;
+ break;
+ case RTP_PT_L16_STEREO:
+ case RTP_PT_L16_MONO:
+ samples_per_sec = 44100;
+ break;
+ default:
+ samples_per_sec = 1000000;
+ };
+
+ samples_per_usec = samples_per_sec/1000000.0;
+
+ ACE_Time_Value now = ACE_OS::gettimeofday();
+
+ ACE_UINT32 ts = (ACE_UINT32)
+ (now.sec () * samples_per_sec +
+ ((double)now.usec () * samples_per_usec) +
+ this->timestamp_offset_);
+
+ ACE_NEW_RETURN (rtp_packet,
+ RTP_Packet (0, // padding
+ 0, // marker
+ this->format_, // payload type
+ this->sequence_num_, // sequence num
+ ts, // time stamp
+ this->ssrc_, // ssrc
+ csrc_count, // csrc count
+ csrc_list, // csrc list
+ frame->rd_ptr (), // data
+ frame->length ()), // data size
+ -1);
+
+ this->sequence_num_ ++;
}
- if (result < 0)
- return result;
- ACE_Message_Block mb ((char *)&header,
- sizeof (header));
- mb.wr_ptr (sizeof (header));
- mb.cont (frame);
+ char *data_ptr;
+ ACE_UINT16 data_length;
+ rtp_packet->get_packet_data (&data_ptr, data_length);
+ ACE_Message_Block mb (data_ptr, data_length);
+ mb.wr_ptr (data_length);
+
result = this->transport_->send (&mb);
if (result < 0)
ACE_ERROR_RETURN ( (LM_ERROR,"TAO_AV_RTP::send_frame failed\n"),result);
+
+ TAO_AV_RTCP_Object *rtcp_prot_obj = ACE_dynamic_cast (TAO_AV_RTCP_Object*,
+ this->control_object_);
+ rtcp_prot_obj->handle_control_output (&mb);
+// rtcp_prot_obj->handle_control_output (rtp_packet);
+
+ delete rtp_packet;
+
return 0;
}
@@ -169,40 +468,116 @@ 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;
+ RTP_Packet *rtp_packet = 0;
+ ACE_UINT32 csrc_count = 0; // Assume for now no mixers/translators
+ ACE_UINT32 *csrc_list = 0;
+
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_;
+ if (frame_info->format != this->format_)
+ ACE_DEBUG ((LM_DEBUG,
+ "TAO_AV_RTP_Object::send_frame - error: format type mismatch"));
+ this->sequence_num_ = frame_info->sequence_num;
+ if (frame_info->ssrc != 0)
+ this->ssrc_ = frame_info->ssrc;
+
+ TAO_AV_RTCP_Object *rtcp_prot_obj = ACE_dynamic_cast (TAO_AV_RTCP_Object*,
+ this->control_object_);
+ // set the ssrc on the control object so the RTCP traffic can be matched
+ // to the RTP traffic
+ rtcp_prot_obj->ssrc(this->ssrc_);
+
+
+ ACE_NEW_RETURN (rtp_packet,
+ RTP_Packet (0, // padding
+ frame_info->boundary_marker, // marker
+ this->format_, // payload type
+ frame_info->sequence_num, // sequence num
+ frame_info->timestamp, // time stamp
+ this->ssrc_, // ssrc
+ csrc_count, // csrc count
+ csrc_list, // csrc list
+ (char *)iov[0].iov_base, // data
+ iov[0].iov_len), // data size
+ -1);
+
+ frame_info->sequence_num ++;
}
else
{
- result = TAO_AV_RTP::write_header (header,
- 0,
- this->sequence_num_,
- 0,
- 0,
- 0);
+ // TODO: For periodic RTP packets (constant rate), the RFC suggests
+ // increasing the clock by the number of samples each frame rather
+ // than relying on the system time
+
+ // The RFC specifies at least one timestamp unit per sample as well as a
+ // random offset. It used to be in milliseconds so I left it that way
+ // for non-audio streams.
+
+ unsigned int samples_per_sec;
+ double samples_per_usec;
+
+ switch (this->format_)
+ {
+ case RTP_PT_PCMU:
+ case RTP_PT_CELP:
+ case RTP_PT_G721:
+ case RTP_PT_GSM:
+ case RTP_PT_DVI:
+ case RTP_PT_LPC:
+ case RTP_PT_PCMA:
+ case RTP_PT_G722:
+ samples_per_sec = 8000;
+ break;
+ case RTP_PT_L16_STEREO:
+ case RTP_PT_L16_MONO:
+ samples_per_sec = 44100;
+ break;
+ default:
+ samples_per_sec = 1000000;
+ };
+
+ samples_per_usec = samples_per_sec/1000000.0;
+
+ ACE_Time_Value now = ACE_OS::gettimeofday();
+
+ ACE_UINT32 ts = (ACE_UINT32)
+ (now.sec () * samples_per_sec +
+ ((double)now.usec () * samples_per_usec) +
+ this->timestamp_offset_);
+
+ ACE_NEW_RETURN (rtp_packet,
+ RTP_Packet (0, // padding
+ 0, // marker
+ this->format_, // payload type
+ this->sequence_num_, // sequence num
+ ts, // time stamp
+ this->ssrc_, // ssrc
+ csrc_count, // csrc count
+ csrc_list, // csrc list
+ (char *)iov[0].iov_base, // data
+ iov[0].iov_len), // data size
+ -1);
+
+ this->sequence_num_ ++;
}
- if (result < 0)
- return result;
+
+ char *data_ptr;
+ ACE_UINT16 data_length;
+ rtp_packet->get_packet_data (&data_ptr, data_length);
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);
+ send_iov [0].iov_base = data_ptr;
+ send_iov [0].iov_len = data_length;
+ for (int i=1;i<iovcnt; i++)
+ send_iov [i] = iov [i];
+ result = this->transport_->send (send_iov, iovcnt);
+
+ delete rtp_packet;
+
if (result < 0)
ACE_ERROR_RETURN ((LM_ERROR,"TAO_AV_RTP::send_frame failed\n"),result);
+
return 0;
}
@@ -217,10 +592,11 @@ TAO_AV_RTP_Object::send_frame (const char*,
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->timestamp_offset_ = ACE_OS::rand ();
+ this->ssrc_ = TAO_AV_RTCP::alloc_srcid ((unsigned int)this);
this->frame_.size (2 * this->transport_->mtu ());
}
@@ -245,6 +621,7 @@ 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];
@@ -280,6 +657,10 @@ void
TAO_AV_RTP_Object::control_object (TAO_AV_Protocol_Object *object)
{
this->control_object_ = object;
+ TAO_AV_RTCP_Object *rtcp_prot_obj = ACE_dynamic_cast (TAO_AV_RTCP_Object*,
+ this->control_object_);
+ rtcp_prot_obj->ssrc (this->ssrc_);
+ rtcp_prot_obj->ts_offset (this->timestamp_offset_);
}
int
@@ -319,6 +700,7 @@ TAO_AV_RTP_Flow_Factory::make_protocol_object (TAO_FlowSpec_Entry *entry,
TAO_AV_Transport *transport)
{
TAO_AV_Callback *callback = 0;
+
endpoint->get_callback (entry->flowname (),
callback);
@@ -331,6 +713,7 @@ TAO_AV_RTP_Flow_Factory::make_protocol_object (TAO_FlowSpec_Entry *entry,
handler);
endpoint->set_protocol_object (entry->flowname (),
object);
+
return object;
}
@@ -338,7 +721,9 @@ int
TAO_AV_RTP_Flow_Factory::match_protocol (const char *flow_string)
{
if (ACE_OS::strncasecmp (flow_string,"RTP",3) == 0)
- return 1;
+ {
+ return 1;
+ }
return 0;
}
@@ -356,3 +741,5 @@ ACE_STATIC_SVC_DEFINE (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
index a3409f8bb6a..cc280e12f63 100644
--- a/TAO/orbsvcs/orbsvcs/AV/RTP.h
+++ b/TAO/orbsvcs/orbsvcs/AV/RTP.h
@@ -72,12 +72,21 @@
#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
-
+#define RTP_PT_PCMU 0 /* 8k */
+#define RTP_PT_CELP 1 /* 8k */
+#define RTP_PT_G721 2 /* 8k */
+#define RTP_PT_GSM 3 /* 8k */
+#define RTP_PT_DVI 5 /* 8k */
+#define RTP_PT_LPC 7 /* 8k */
+#define RTP_PT_PCMA 8 /* 8k */
+#define RTP_PT_G722 9 /* 8k */
+#define RTP_PT_L16_STEREO 10 /* 44.1k */
+#define RTP_PT_L16_MONO 11 /* 44.1k */
+
+/* TODO: keep??
+ non-standard encodings for audio
+ */
+#define RTP_PT_L16_OTHER 23 /* */
/* Offset from UNIX's epoch to the NTP epoch in seconds (NTP's JAN_1970) */
#define RTP_EPOCH_OFFSET 2208988800UL
@@ -91,6 +100,7 @@
#define RTCP_PT_SR 200 /* sender report */
#define RTCP_PT_RR 201 /* receiver report */
#define RTCP_PT_SDES 202 /* source description */
+#define RTCP_SDES_END 0 /* indicates the end of the sdes message */
#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) */
@@ -104,6 +114,8 @@
#define RTCP_SDES_MIN 1
+#define RTP_SEQ_MOD (1<<16)
+
/*
* Parameters controling the RTCP report rate timer.
@@ -118,21 +130,13 @@
* Largest (user-level) packet size generated by our rtp applications.
* Individual video formats may use smaller mtu's.
*/
-#define RTP_MTU 1024
+#define RTP_MTU 2*ACE_MAX_DGRAM_SIZE
#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
@@ -234,16 +238,112 @@ public:
ACE_UINT16 blkno;
};
- static int handle_input (ACE_Message_Block *&data,
- TAO_AV_frame_info *&frame_info);
+};
+
+/**
+ * @class RTP_Packet
+ * @brief This class encapsulates all the necessary information to break down
+ * or build up an RTP data packet as well as operations to access all data
+ * items in the packet.
+ */
+class RTP_Packet
+{
+public:
+ /// Constructor for incoming RTP packets.
+ RTP_Packet(char* buffer,
+ int length);
+
+ /// Constructor for outgoing RTP packets
+ RTP_Packet(unsigned char padding,
+ unsigned char marker,
+ unsigned char payloadType,
+ ACE_UINT32 sequenceNumber,
+ ACE_UINT32 timeStamp,
+ ACE_UINT32 syncSource,
+ unsigned char contribSourcCount,
+ ACE_UINT32 contribSourceList[],
+ char *data,
+ ACE_UINT16 dataSize);
+
+ /// Destructor
+ ~RTP_Packet(void);
+
+ /// Returns the size of the RTP packet in bytes.
+ ACE_UINT16 packet_size(void);
+
+ /// Returns the size of the payload in bytes.
+ ACE_UINT16 payload_size(void);
+
+ /// Populates the passed in frame_info.
+ void get_frame_info (TAO_AV_frame_info *frame_info);
+
+ /// Returns 1 if packet is valid and 0 if not.
+ int is_valid (void);
+
+ /// Returns the RTP version of the packet.
+ unsigned int ver (void);
- static int write_header (rtphdr &header,
- int format,
- ACE_UINT16 &sequence_num,
- ACE_UINT32 ts,
- ACE_UINT32 ssrc,
- CORBA::Boolean boundary_marker);
+ /// Returns 1 if the padding bit is set, 0 if not.
+ unsigned int pad (void);
+ /// Returns 1 if the header extension bit is set, 0 if not.
+ unsigned int ext (void);
+
+ /// Returns the number of bytes in the header extension or 0 if no extension.
+ unsigned int ext_bytes (void);
+
+ /// Returns the contributing source count.
+ /// This should only be non-zero for mixers.
+ unsigned int cc (void);
+
+ /// Returns 1 if the marker bit is set, 0 if not.
+ unsigned int mrk (void);
+
+ /// Returns the payload type of the packet.
+ unsigned int pt (void);
+
+ /// Returns the sequence number of the packet.
+ ACE_UINT16 sn (void);
+
+ /// Returns the timestamp of the packet.
+ ACE_UINT32 ts (void);
+
+ /// Returns the synchronization source id of the packet.
+ ACE_UINT32 ssrc (void);
+
+ /// Returns a pointer to the local contributing source list and its length.
+ /// This should be empty except for mixers.
+ /// RTP_Packet retains ownership.
+ void get_csrc_list (ACE_UINT32 **csrc_list, ACE_UINT16 &length);
+
+ /// Returns a pointer to the locally stored payload and its size in bytes.
+ /// The payload is returned in host byte order.
+ /// RTP_Packet retains ownership.
+ void get_payload (char **payload, ACE_UINT16 &size);
+
+ /// Returns a pointer to the locally stored rtp packet and its size in bytes.
+ /// RTP_Packet retains ownership.
+ void get_packet_data (char **packet, ACE_UINT16 &size);
+
+private:
+ /// Local buffer to hold the RTP packet.
+ char packet_[RTP_MTU];
+
+ /// Local buffer to hold the contributing source list with the values stored
+ /// in host byte order.
+ ACE_UINT32 host_byte_order_csrc_list_[15];
+
+ /// Local buffer to hold the payload with the values stored in host byte order.
+ char host_byte_order_payload_[RTP_MTU];
+
+ /// The number of bytes in the header extension - 0 if no extension.
+ unsigned int extension_bytes_;
+
+ /// The size of the overall data packet.
+ ACE_UINT16 packet_size_;
+
+ /// The size of the payload portion of the packet.
+ ACE_UINT16 payload_size_;
};
/**
@@ -277,14 +377,17 @@ public:
protected:
ACE_UINT16 sequence_num_;
+ ACE_UINT32 timestamp_offset_;
int format_;
- CORBA::ULong ssrc_;
+ ACE_UINT32 ssrc_;
TAO_AV_Protocol_Object *control_object_;
/// Pre-allocated memory to receive the data...
ACE_Message_Block frame_;
};
+
+
/**
* @class TAO_AV_RTP_Flow_Factory
* @brief
diff --git a/TAO/orbsvcs/orbsvcs/AV/TCP.cpp b/TAO/orbsvcs/orbsvcs/AV/TCP.cpp
index 06a7d21701d..9abda9f89c2 100644
--- a/TAO/orbsvcs/orbsvcs/AV/TCP.cpp
+++ b/TAO/orbsvcs/orbsvcs/AV/TCP.cpp
@@ -400,8 +400,11 @@ TAO_AV_TCP_Connector::open (TAO_Base_StreamEndPoint *endpoint,
int
TAO_AV_TCP_Connector::connect (TAO_FlowSpec_Entry *entry,
- TAO_AV_Transport *&transport)
+ TAO_AV_Transport *&transport,
+ TAO_AV_Core::Flow_Component flow_comp)
{
+ ACE_UNUSED_ARG (flow_comp);
+
this->entry_ = entry;
this->flowname_ = entry->flowname ();
ACE_Addr *remote_addr = entry->address ();
@@ -410,7 +413,7 @@ TAO_AV_TCP_Connector::connect (TAO_FlowSpec_Entry *entry,
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);
+ ACE_ERROR_RETURN ((LM_ERROR,"TAO_AV_TCP_connector::connect failed\n"),-1);
entry->handler (handler);
transport = handler->transport ();
return 0;
@@ -499,8 +502,11 @@ 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)
+ TAO_AV_Flow_Protocol_Factory *factory,
+ TAO_AV_Core::Flow_Component flow_comp)
{
+ ACE_UNUSED_ARG (flow_comp);
+
this->flow_protocol_factory_ = factory;
if (TAO_debug_level > 0)
@@ -546,8 +552,11 @@ 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)
+ TAO_AV_Flow_Protocol_Factory *factory,
+ TAO_AV_Core::Flow_Component flow_comp)
{
+ ACE_UNUSED_ARG (flow_comp);
+
this->flow_protocol_factory_ = factory;
this->av_core_ = av_core;
this->endpoint_ = endpoint;
@@ -713,4 +722,3 @@ ACE_STATIC_SVC_DEFINE (TAO_AV_TCP_Factory,
0)
ACE_FACTORY_DEFINE (TAO_AV, TAO_AV_TCP_Factory)
-
diff --git a/TAO/orbsvcs/orbsvcs/AV/TCP.h b/TAO/orbsvcs/orbsvcs/AV/TCP.h
index 44b16755b18..72ebf9dc14a 100644
--- a/TAO/orbsvcs/orbsvcs/AV/TCP.h
+++ b/TAO/orbsvcs/orbsvcs/AV/TCP.h
@@ -146,12 +146,16 @@ public:
virtual int open (TAO_Base_StreamEndPoint *endpoint,
TAO_AV_Core *av_core,
TAO_FlowSpec_Entry *entry,
- TAO_AV_Flow_Protocol_Factory *factory);
+ TAO_AV_Flow_Protocol_Factory *factory,
+ TAO_AV_Core::Flow_Component flow_component =
+ TAO_AV_Core::TAO_AV_DATA);
virtual int open_default (TAO_Base_StreamEndPoint *endpoint,
TAO_AV_Core *av_core,
TAO_FlowSpec_Entry *entry,
- TAO_AV_Flow_Protocol_Factory *factory);
+ TAO_AV_Flow_Protocol_Factory *factory,
+ TAO_AV_Core::Flow_Component flow_component =
+ TAO_AV_Core::TAO_AV_DATA);
virtual int close (void);
virtual int make_svc_handler (TAO_AV_TCP_Flow_Handler *&handler);
@@ -197,7 +201,9 @@ public:
TAO_AV_Flow_Protocol_Factory *factory);
virtual int connect (TAO_FlowSpec_Entry *entry,
- TAO_AV_Transport *&transport);
+ TAO_AV_Transport *&transport,
+ TAO_AV_Core::Flow_Component flow_comp =
+ TAO_AV_Core::TAO_AV_DATA);
virtual int close (void);
virtual int make_svc_handler (TAO_AV_TCP_Flow_Handler *&handler);
protected:
diff --git a/TAO/orbsvcs/orbsvcs/AV/Transport.cpp b/TAO/orbsvcs/orbsvcs/AV/Transport.cpp
index ce002056426..b9a04fd0598 100644
--- a/TAO/orbsvcs/orbsvcs/AV/Transport.cpp
+++ b/TAO/orbsvcs/orbsvcs/AV/Transport.cpp
@@ -23,7 +23,6 @@
#include "Transport.i"
#endif /* __ACE_INLINE__ */
-
//------------------------------------------------------------
// TAO_AV_Transport_Item
//------------------------------------------------------------
@@ -81,149 +80,81 @@ TAO_AV_Connector_Registry::open (TAO_Base_StreamEndPoint *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 ();
+ TAO_AV_Flow_Protocol_Factory *flow_factory =
+ av_core->get_flow_protocol_factory (flow_protocol);
+ TAO_AV_Transport_Factory *transport_factory =
+ av_core->get_transport_factory (transport_protocol);
- for (TAO_AV_Flow_ProtocolFactorySetItor flow_factory =
- av_core->flow_protocol_factories ()->begin ();
- flow_factory != flow_factory_end;
- ++flow_factory)
+ if ((flow_factory != 0) && (transport_factory != 0))
{
- 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)
- {
+ // @@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.
- 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);
+ TAO_AV_Connector *connector = transport_factory->make_connector ();
- if (connector->open (endpoint,
- av_core,
- (*flow_factory)->factory ()) == -1)
- return -1;
+ if (connector != 0)
+ {
+ // add connector to list.
+ this->connectors_.insert (connector);
+
+ if (connector->open (endpoint,
+ av_core,
+ flow_factory) == -1)
+ return -1;
+
+ TAO_AV_Transport *transport = 0;
+ if (connector->connect (entry,
+ transport,
+ TAO_AV_Core::TAO_AV_DATA) == -1)
+ return -1;
+ entry->transport (transport);
+ }
+ else
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "(%P|%t) Unable to create an "
+ "connector for <%s>\n",
+ entry->flowname ()),
+ -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 ();
+ // Now see if the flow factory has a control flow factory.
+ TAO_AV_Flow_Protocol_Factory *control_flow_factory =
+ av_core->get_flow_protocol_factory(flow_factory->control_flow_factory ());
- if (control_factory_name != 0)
- {
+ if (control_flow_factory != 0)
+ {
+ TAO_AV_Connector *control_connector =
+ transport_factory->make_connector ();
- TAO_AV_Flow_ProtocolFactorySetItor control_factory_end =
- av_core->flow_protocol_factories ()->end ();
+ if (control_connector != 0)
+ {
+ // add connector to list.
+ this->connectors_.insert (control_connector);
- 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 ());
- }
- }
+ if (control_connector->open (endpoint,
+ av_core,
+ control_flow_factory) == -1)
+ return -1;
+
+ TAO_AV_Transport *control_transport = 0;
+ if (control_connector->connect (entry,
+ control_transport,
+ TAO_AV_Core::TAO_AV_CONTROL) == -1)
+ return -1;
+ entry->control_transport (control_transport);
+
+ // Now set the control object on the data flow object.
+ entry->protocol_object ()->control_object (entry->control_protocol_object ());
}
+ else
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "(%P|%t) Unable to create an "
+ "connector for <%s>\n",
+ entry->flowname ()),
+ -1);
}
- else
- continue;
}
}
}
@@ -267,6 +198,7 @@ TAO_AV_Acceptor_Registry::TAO_AV_Acceptor_Registry (void)
TAO_AV_Acceptor_Registry::~TAO_AV_Acceptor_Registry (void)
{
+ this->close_all();
}
int
@@ -303,145 +235,72 @@ TAO_AV_Acceptor_Registry::open (TAO_Base_StreamEndPoint *endpoint,
if (address == 0)
{
retv = this->open_default (endpoint,
- av_core,
- entry);
+ av_core,
+ entry);
if(retv < 0)
return retv;
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)
+ TAO_AV_Flow_Protocol_Factory *flow_factory =
+ av_core->get_flow_protocol_factory (flow_protocol);
+
+ if (flow_protocol != 0)
{
- if ((*flow_factory)->factory ()->match_protocol (flow_protocol))
+ TAO_AV_Transport_Factory *transport_factory =
+ av_core->get_transport_factory (transport_protocol);
+
+ if (transport_protocol != 0)
{
- TAO_AV_TransportFactorySetItor transport_factory_end =
- av_core->transport_factories ()->end ();
-
- //int i = 1;
- for (TAO_AV_TransportFactorySetItor transport_factory =
- av_core->transport_factories ()->begin ();
- transport_factory != transport_factory_end;
- ++transport_factory)
+ TAO_AV_Acceptor *acceptor = transport_factory->make_acceptor ();
+ if (acceptor != 0)
{
+ // add acceptor to list.
+ this->acceptors_.insert (acceptor);
+
+ if (acceptor->open (endpoint,
+ av_core,
+ entry,
+ flow_factory,
+ TAO_AV_Core::TAO_AV_DATA) == -1)
+ return -1;
- if ((*transport_factory)->factory ()->match_protocol (transport_protocol))
+ TAO_AV_Flow_Protocol_Factory *control_flow_factory =
+ av_core->get_flow_protocol_factory (flow_factory->control_flow_factory ());
+
+ if (control_flow_factory != 0)
{
- TAO_AV_Acceptor *acceptor =
- (*transport_factory)->factory ()->make_acceptor ();
+ TAO_AV_Acceptor *acceptor = transport_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)
+ control_flow_factory,
+ TAO_AV_Core::TAO_AV_CONTROL) == -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 ();
+ // add acceptor to list.
+ this->acceptors_.insert (acceptor);
- if (control_factory_name != 0)
- {
- TAO_AV_Flow_ProtocolFactorySetItor control_factory_end =
- av_core->flow_protocol_factories ()->end ();
+ entry->protocol_object ()->control_object (entry->control_protocol_object ());
- 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
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "(%P|%t) Unable to create an "
+ "acceptor for <%s>\n",
+ entry->flowname ()),
+ -1);
}
}
+ else
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "(%P|%t) Unable to create an "
+ "acceptor for <%s>\n",
+ entry->flowname ()),
+ -1);
}
- else
- continue;
}
}
}
@@ -460,102 +319,100 @@ TAO_AV_Acceptor_Registry::open_default (TAO_Base_StreamEndPoint *endpoint,
// 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_Flow_Protocol_Factory *flow_factory =
+ av_core->get_flow_protocol_factory (flow_protocol);
- TAO_AV_TransportFactorySetItor transport_factory
- = av_core->transport_factories ()->begin ();
+ // No matching flow protocol.
+ if (flow_factory == 0)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "TAO (%P|%t) Unable to match protocol prefix "
+ "for <%s>\n",
+ flow_protocol),
+ -1);
- 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_DEBUG((LM_DEBUG, "(%N,%l) Matched flow_protocol: %s, Looking for transport protocol: %s\n", flow_protocol, transport_protocol));
+
+ TAO_AV_Transport_Factory *transport_factory =
+ av_core->get_transport_factory (transport_protocol);
- if (TAO_debug_level > 0)
- ACE_ERROR ((LM_ERROR,
+ if (transport_factory == 0)
+ ACE_ERROR_RETURN ((LM_ERROR,
"TAO (%P|%t) Unable to match protocol prefix "
"for <%s>\n",
- flow_protocol));
- continue;
- }
- else
- {
- if (TAO_debug_level > 0)
- ACE_DEBUG((LM_DEBUG, "(%N,%l) Matched flow_protocol: %s, Looking for transport protocol: %s\n", flow_protocol, transport_protocol));
- TAO_AV_TransportFactorySetItor transport_factory_end =
- av_core->transport_factories ()->end ();
-
- int matched_transport = 0;
- 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",
- transport_protocol));
- continue;
- }
+ transport_protocol),
+ -1);
+
+ // make an acceptor
+ TAO_AV_Acceptor *acceptor =
+ transport_factory->make_acceptor();
+
+ if (acceptor == 0)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "TAO (%P|%t) unable to create "
+ "an acceptor for <%d>\n",
+ transport_protocol),
+ -1);
+
+ if (acceptor->open_default (endpoint,
+ av_core,
+ entry,
+ flow_factory,
+ TAO_AV_Core::TAO_AV_DATA) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "TAO (%P|%t) unable to open "
+ "default acceptor for <%s>%p\n",
+ flow_protocol),
+ -1);
+
+ this->acceptors_.insert (acceptor);
+
+ const char *control_flow_factory_name = flow_factory->control_flow_factory ();
+
+ if (control_flow_factory_name != 0)
+ {
- matched_transport = 1;
+ TAO_AV_Flow_Protocol_Factory *control_flow_factory =
+ av_core->get_flow_protocol_factory (control_flow_factory_name);
- // got it, make an acceptor
- TAO_AV_Acceptor *acceptor =
- (*transport_factory)->factory ()->make_acceptor ();
+ if (control_flow_factory == 0)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "TAO (%P|%t) Unable to match control flow "
+ "for <%s>\n",
+ control_flow_factory_name),
+ -1);
- 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;
- }
+ TAO_AV_Acceptor *control_acceptor = transport_factory->make_acceptor ();
+
+ if (control_acceptor == 0)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "TAO (%P|%t) unable to create "
+ "an acceptor for <%d>\n",
+ transport_protocol),
+ -1);
- if (acceptor->open_default (endpoint,
+ if (control_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;
- }
+ control_flow_factory,
+ TAO_AV_Core::TAO_AV_CONTROL) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "TAO (%P|%t) unable to open "
+ "default acceptor for <%s>%p\n",
+ transport_protocol),
+ -1);
- this->acceptors_.insert (acceptor);
- }
- if( matched_transport == 0 ){
- ACE_ERROR ((LM_ERROR, "(%P|%t), %N:%l could not match transport protocol: %s\n",
- transport_protocol));
- return -1;
- }
- }
+ this->acceptors_.insert (control_acceptor);
+
+ entry->protocol_object ()->control_object (entry->control_protocol_object ());
}
+
if (this->acceptors_.size () == 0)
{
if (TAO_debug_level > 0)
@@ -620,6 +477,10 @@ TAO_AV_Flow_Handler::TAO_AV_Flow_Handler (void)
{
}
+TAO_AV_Flow_Handler::~TAO_AV_Flow_Handler(void)
+{
+}
+
int
TAO_AV_Flow_Handler::set_remote_address (ACE_Addr * /* address */)
{
@@ -649,19 +510,36 @@ 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_);
+
+ 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);
+
+// this->timer_id_ = event_handler->reactor ()->schedule_timer (event_handler,
+ this->timer_id_ =
+ TAO_AV_CORE::instance()->reactor ()->schedule_timer (event_handler,
+ 0,
+ *tv);
+
+ delete tv;
+
if (this->timer_id_ < 0)
return -1;
return 0;
}
+
+int
+TAO_AV_Flow_Handler::cancel_timer (void)
+{
+ ACE_Event_Handler *event_handler = this->event_handler ();
+ TAO_AV_CORE::instance()->reactor ()->cancel_timer (this->timer_id_);
+
+ return 0;
+}
+
+
int
TAO_AV_Flow_Handler::stop (TAO_FlowSpec_Entry::Role role)
{
@@ -688,13 +566,17 @@ TAO_AV_Flow_Handler::handle_timeout (const ACE_Time_Value & /*tv*/,
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_);
+
+ 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);
+
+ delete timeout;
+
return 0;
}
diff --git a/TAO/orbsvcs/orbsvcs/AV/Transport.h b/TAO/orbsvcs/orbsvcs/AV/Transport.h
index b418638e038..767cf800fb0 100644
--- a/TAO/orbsvcs/orbsvcs/AV/Transport.h
+++ b/TAO/orbsvcs/orbsvcs/AV/Transport.h
@@ -24,6 +24,7 @@
#include "ace/SOCK_Dgram.h"
#include "orbsvcs/AV/AV_export.h"
#include "FlowSpec_Entry.h"
+#include "AV_Core.h"
// Forward declarations.
class TAO_AV_Core;
@@ -106,12 +107,14 @@ public:
/// Constructor.
TAO_AV_Flow_Handler (void);
+ virtual ~TAO_AV_Flow_Handler (void);
/// Start/stop the flow handler.
virtual int start (TAO_FlowSpec_Entry::Role role);
virtual int stop (TAO_FlowSpec_Entry::Role role);
/// Schedule timer. Uses the get_timeout method on the callback.
virtual int schedule_timer (void);
+ virtual int cancel_timer (void);
/// get the transport.
TAO_AV_Transport *transport (void);
@@ -124,7 +127,7 @@ public:
void callback (TAO_AV_Callback *callback);
/// Handle timeout. called from reactor.
- int handle_timeout (const ACE_Time_Value &tv, const void *arg = 0);
+ virtual int handle_timeout (const ACE_Time_Value &tv, const void *arg = 0);
/// set the remote address.
virtual int set_remote_address (ACE_Addr *address);
@@ -212,12 +215,14 @@ public:
virtual int open (TAO_Base_StreamEndPoint *endpoint,
TAO_AV_Core *av_core,
TAO_FlowSpec_Entry *entry,
- TAO_AV_Flow_Protocol_Factory *factory) = 0;
+ TAO_AV_Flow_Protocol_Factory *factory,
+ TAO_AV_Core::Flow_Component flow_comp) = 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;
+ TAO_AV_Flow_Protocol_Factory *factory,
+ TAO_AV_Core::Flow_Component flow_comp) = 0;
const char *flowname ();
virtual int close (void) = 0;
@@ -243,7 +248,8 @@ public:
TAO_AV_Flow_Protocol_Factory *factory) = 0;
virtual int connect (TAO_FlowSpec_Entry *entry,
- TAO_AV_Transport *&transport) = 0;
+ TAO_AV_Transport *&transport,
+ TAO_AV_Core::Flow_Component flow_component) = 0;
virtual int close (void) = 0;
protected:
diff --git a/TAO/orbsvcs/orbsvcs/AV/UDP.cpp b/TAO/orbsvcs/orbsvcs/AV/UDP.cpp
index fcee016b6f4..6416a1eef3a 100644
--- a/TAO/orbsvcs/orbsvcs/AV/UDP.cpp
+++ b/TAO/orbsvcs/orbsvcs/AV/UDP.cpp
@@ -34,8 +34,7 @@ TAO_AV_UDP_Flow_Handler::transport (void)
int
TAO_AV_UDP_Flow_Handler::handle_input (ACE_HANDLE /*fd*/)
{
- this->protocol_object_->handle_input ();
- return 0;
+ return this->protocol_object_->handle_input ();
}
int
@@ -98,7 +97,7 @@ TAO_AV_UDP_Flow_Handler::change_qos(AVStreams::QoS qos)
if(!((dscp >= 0) && (dscp <= 63)))
{
dscp_flag = 0;
- ACE_DEBUG((LM_DEBUG, "(%N,%l) ECN value can only be (0-3) not %d\n", ecn));
+ ACE_DEBUG((LM_DEBUG, "(%N,%l) ECN value can only be (0-3) not %d\n", ecn));
return -1;
}
}
@@ -225,7 +224,7 @@ TAO_AV_UDP_Transport::send (const ACE_Message_Block *mblk, ACE_Time_Value *)
// we should set IOV_MAX to that limit.
if (iovcnt == IOV_MAX)
{
- n = this->handler_->get_socket ()->send ((const iovec *) iov,
+ n = this->handler_->get_socket ()->send ((const iovec *) iov,
iovcnt,
this->peer_addr_);
@@ -326,22 +325,32 @@ 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;
+
+ if (this->flow_component_ == TAO_AV_Core::TAO_AV_CONTROL)
+ handler->schedule_timer ();
+
+ 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)
+ TAO_AV_Flow_Protocol_Factory *factory,
+ TAO_AV_Core::Flow_Component flow_comp)
{
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_component_ = flow_comp;
this->flow_protocol_factory_ = factory;
this->flowname_ = entry->flowname ();
- ACE_INET_Addr *inet_addr = (ACE_INET_Addr *) entry->address ();
+ ACE_INET_Addr *inet_addr;
+ if (flow_comp == TAO_AV_Core::TAO_AV_DATA)
+ inet_addr = (ACE_INET_Addr *) entry->address ();
+ else
+ inet_addr = (ACE_INET_Addr *) entry->control_address ();
char buf[BUFSIZ];
inet_addr->addr_to_string (buf,
@@ -352,7 +361,7 @@ TAO_AV_UDP_Acceptor::open (TAO_Base_StreamEndPoint *endpoint,
"TAO_AV_UDP_Acceptor::open: %s",
buf));
- int result = this->open_i (inet_addr);
+ int result = this->open_i (inet_addr, 0);
if (result < 0)
return result;
@@ -363,121 +372,141 @@ 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)
+ TAO_AV_Flow_Protocol_Factory *factory,
+ TAO_AV_Core::Flow_Component flow_comp)
{
this->av_core_ = av_core;
this->endpoint_ = endpoint;
this->entry_ = entry;
+ this->flow_component_ = flow_comp;
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);
+ ACE_INET_Addr *address = 0;
+ if (flow_comp == TAO_AV_Core::TAO_AV_DATA)
+ ACE_NEW_RETURN (address,
+ ACE_INET_Addr ("0"),
+ -1);
+ int result = this->open_i (address, 1);
if (result < 0)
return result;
+
return 0;
}
int
-TAO_AV_UDP_Acceptor::open_i (ACE_INET_Addr *inet_addr)
+TAO_AV_UDP_Acceptor::open_i (ACE_INET_Addr *inet_addr,
+ int is_default_addr)
{
int result = -1;
ACE_INET_Addr *local_addr;
TAO_AV_Flow_Handler *flow_handler = 0;
- if (this->entry_->is_multicast ())
+ // if using a default address and this is the control flow component, the
+ // handler and local address are already set in the flow spec entry
+ if (is_default_addr &&
+ (this->flow_component_ == TAO_AV_Core::TAO_AV_CONTROL) &&
+ (ACE_OS::strcasecmp(this->entry_->flow_protocol_str (), "RTP") == 0))
{
- 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);
+ flow_handler = this->entry_->control_handler ();
- // Now disable Multicast loopback.
- // @@Should we make this a policy?
-#ifdef ACE_HAS_IP_MULTICAST
- 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.
-#endif /*ACE_HAS_IP_MULTICAST*/
- 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);
+ local_addr = ACE_dynamic_cast (ACE_INET_Addr*,
+ this->entry_->get_local_control_addr ());
}
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;
+ // this variable is only used for RTP/UDP; RFC 1889 requires an even/odd
+ // consecutive port pair
+ int get_new_port = 1;
- if (handler->get_socket ()->set_option (SOL_SOCKET,
- SO_SNDBUF,
- (void *) &sndbufsize,
- sizeof (sndbufsize)) == -1
- && errno != ENOTSUP)
- return 0;
+ while (get_new_port)
+ {
+ // assume the ports will be OK
+ get_new_port = 0;
- else if (handler->get_socket ()->set_option (SOL_SOCKET,
- SO_RCVBUF,
- (void *) &rcvbufsize,
- sizeof (rcvbufsize)) == -1
- && errno != ENOTSUP)
- return 0;
+ result = TAO_AV_UDP_Connection_Setup::setup (flow_handler,
+ inet_addr,
+ local_addr,
+ this->entry_->is_multicast (),
+ TAO_AV_UDP_Connection_Setup::ACCEPTOR);
- 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 ());
+ local_addr->set (local_addr->get_port_number (),
+ local_addr->get_host_name ());
+
+ if (is_default_addr)
+ {
+ if ((ACE_OS::strcasecmp(this->entry_->flow_protocol_str (), "RTP") == 0) &&
+ (this->flow_component_ == TAO_AV_Core::TAO_AV_DATA))
+ {
+ if (is_default_addr && local_addr->get_port_number ()%2 != 0)
+ {
+ // RTP port should be even
+ delete local_addr;
+ delete flow_handler;
+ get_new_port = 1;
+ }
+ else
+ {
+ ACE_INET_Addr *local_control_addr;
+ ACE_INET_Addr *control_inet_addr;
+ TAO_AV_Flow_Handler *control_flow_handler = 0;
+
+ ACE_NEW_RETURN (control_inet_addr,
+ ACE_INET_Addr ("0"),
+ -1);
+
+ TAO_AV_UDP_Connection_Setup::setup(control_flow_handler,
+ control_inet_addr,
+ local_control_addr,
+ this->entry_->is_multicast (),
+ TAO_AV_UDP_Connection_Setup::ACCEPTOR);
+
+ if (local_control_addr->get_port_number () !=
+ local_addr->get_port_number () +1)
+ {
+ delete control_inet_addr;
+ delete local_addr;
+ delete flow_handler;
+ delete local_control_addr;
+ delete control_flow_handler;
+ get_new_port = 1;
+ }
+ else
+ {
+ this->entry_->control_address (control_inet_addr);
+ this->entry_->set_local_control_addr (local_control_addr);
+ this->entry_->control_handler (control_flow_handler);
+ }
+ }
+ }
+ }
+ }
}
+
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_flow_handler (this->flowname_.c_str (),flow_handler);
- this->entry_->protocol_object (object);
+
+ if (this->flow_component_ == TAO_AV_Core::TAO_AV_DATA)
+ {
+ this->endpoint_->set_flow_handler (this->flowname_.c_str (),flow_handler);
+
+ this->entry_->protocol_object (object);
+ this->entry_->set_local_addr (local_addr);
+ this->entry_->handler (flow_handler);
+ this->entry_->address (inet_addr);
+ }
+ else
+ {
+ this->endpoint_->set_control_flow_handler (this->flowname_.c_str (),flow_handler);
+
+ this->entry_->control_protocol_object (object);
+ this->entry_->set_local_control_addr (local_addr);
+ this->entry_->control_handler (flow_handler);
+ }
char buf[BUFSIZ];
local_addr->addr_to_string (buf,BUFSIZ);
@@ -486,10 +515,7 @@ TAO_AV_UDP_Acceptor::open_i (ACE_INET_Addr *inet_addr)
"TAO_AV_UDP_ACCEPTOR::open:%s \n",
buf));
- this->entry_->set_local_addr (local_addr);
- this->entry_->handler (flow_handler);
-
-// call activate svc handler.
+ // call activate svc handler.
return this->activate_svc_handler (flow_handler);
}
@@ -525,21 +551,175 @@ TAO_AV_UDP_Connector::open (TAO_Base_StreamEndPoint *endpoint,
int
TAO_AV_UDP_Connector::connect (TAO_FlowSpec_Entry *entry,
- TAO_AV_Transport *&transport)
+ TAO_AV_Transport *&transport,
+ TAO_AV_Core::Flow_Component flow_component)
{
-
ACE_INET_Addr *local_addr;
int result = -1;
this->entry_ = entry;
this->flowname_ = entry->flowname ();
+ this->flow_component_ = flow_component;
- ACE_INET_Addr *inet_addr = ACE_dynamic_cast (ACE_INET_Addr*,
- entry->address ());
+ ACE_INET_Addr *inet_addr;
+
+ if (flow_component == TAO_AV_Core::TAO_AV_DATA)
+ inet_addr = ACE_dynamic_cast (ACE_INET_Addr*, entry->address ());
+ else
+ inet_addr = ACE_dynamic_cast (ACE_INET_Addr*, entry->control_address ());
TAO_AV_Flow_Handler *flow_handler = 0;
- if (entry->is_multicast ())
+ // if this is the control flow component, the
+ // handler and local address are already set in the flow spec entry
+ if ((flow_component == TAO_AV_Core::TAO_AV_CONTROL) &&
+ (ACE_OS::strcasecmp(this->entry_->flow_protocol_str (), "RTP") == 0) &&
+ !entry->is_multicast ())
+ {
+ flow_handler = this->entry_->control_handler ();
+ flow_handler->set_remote_address (inet_addr);
+
+ local_addr = ACE_dynamic_cast (ACE_INET_Addr*,
+ this->entry_->get_local_control_addr ());
+ }
+ else
+ {
+ // this variable is only used for RTP/UDP; RFC 1889 requires an even/odd
+ // consecutive port pair
+ int get_new_port = 1;
+
+ while (get_new_port)
+ {
+ // assume the ports will be OK
+ get_new_port = 0;
+
+ TAO_AV_UDP_Connection_Setup::setup (flow_handler,
+ inet_addr,
+ local_addr,
+ entry->is_multicast (),
+ TAO_AV_UDP_Connection_Setup::CONNECTOR);
+
+ if ((ACE_OS::strcasecmp(this->entry_->flow_protocol_str (), "RTP") == 0) &&
+ (flow_component == TAO_AV_Core::TAO_AV_DATA) &&
+ !entry->is_multicast ())
+ {
+ if (local_addr->get_port_number ()%2 != 0)
+ {
+ // RTP port should be even
+ delete local_addr;
+ delete flow_handler;
+ get_new_port = 1;
+ }
+ else
+ {
+ ACE_INET_Addr *local_control_addr;
+ ACE_INET_Addr *control_inet_addr;
+ TAO_AV_Flow_Handler *control_flow_handler = 0;
+
+ if (entry->is_multicast ())
+ control_inet_addr = ACE_dynamic_cast (ACE_INET_Addr*,
+ entry->control_address ()) ;
+
+ else
+ ACE_NEW_RETURN (control_inet_addr,
+ ACE_INET_Addr ("0"),
+ -1);
+
+ TAO_AV_UDP_Connection_Setup::setup(control_flow_handler,
+ control_inet_addr,
+ local_control_addr,
+ entry->is_multicast (),
+ TAO_AV_UDP_Connection_Setup::CONNECTOR);
+
+ if (local_control_addr->get_port_number () !=
+ local_addr->get_port_number () +1)
+ {
+ delete local_addr;
+ delete flow_handler;
+ delete local_control_addr;
+ delete control_flow_handler;
+ get_new_port = 1;
+ }
+ else
+ {
+ this->entry_->set_local_control_addr (local_control_addr);
+ this->entry_->control_handler (control_flow_handler);
+ }
+ }
+ }
+ }
+ }
+
+ 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);
+
+ if (flow_component == TAO_AV_Core::TAO_AV_DATA)
+ {
+ this->endpoint_->set_flow_handler (this->flowname_.c_str (),
+ flow_handler);
+ this->entry_->protocol_object (object);
+ entry->set_local_addr (local_addr);
+ entry->handler (flow_handler);
+ transport = flow_handler->transport ();
+ }
+ else
+ {
+ this->endpoint_->set_control_flow_handler (this->flowname_.c_str (),
+ flow_handler);
+ this->entry_->control_protocol_object (object);
+ entry->set_local_control_addr (local_addr);
+ entry->control_handler (flow_handler);
+ transport = flow_handler->transport ();
+ }
+
+ 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));
+
+ // 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);
+
+ if (this->flow_component_ == TAO_AV_Core::TAO_AV_CONTROL)
+ handler->schedule_timer ();
+
+ return result;
+}
+
+int
+TAO_AV_UDP_Connector::close (void)
+{
+ return 0;
+}
+
+//------------------------------------------------------------
+// TAO_AV_UDP_Connection_Setup
+//------------------------------------------------------------
+
+int
+TAO_AV_UDP_Connection_Setup::setup (TAO_AV_Flow_Handler *&flow_handler,
+ ACE_INET_Addr *inet_addr,
+ ACE_INET_Addr *&local_addr,
+ int is_multicast,
+ ConnectionType ct)
+{
+ int result;
+
+ if (is_multicast)
{
TAO_AV_UDP_MCast_Flow_Handler *handler;
ACE_NEW_RETURN (handler,
@@ -549,15 +729,16 @@ TAO_AV_UDP_Connector::connect (TAO_FlowSpec_Entry *entry,
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 defined (ACE_HAS_IP_MULTICAST)
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"));
+ if (TAO_debug_level > 0)
+ ACE_DEBUG ((LM_DEBUG,"TAO_AV_UDP_MCast_Acceptor::multicast loop disable failed\n"));
// @@ This should also be policies.
#endif /*ACE_HAS_IP_MULTICAST*/
@@ -575,12 +756,23 @@ TAO_AV_UDP_Connector::connect (TAO_FlowSpec_Entry *entry,
perror("SO_RCVBUF");
}
ACE_NEW_RETURN (local_addr,
- ACE_INET_Addr (*inet_addr),
+// ACE_INET_Addr ((u_short) 0),
+ ACE_INET_Addr ("0"),
-1);
+
+ if (ct == ACCEPTOR)
+ {
+ result = handler->get_mcast_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 ());
+ handler->set_peer_addr (local_addr);
+ }
}
else
{
-
ACE_NEW_RETURN (local_addr,
ACE_INET_Addr ("0"),
-1);
@@ -593,7 +785,6 @@ TAO_AV_UDP_Connector::connect (TAO_FlowSpec_Entry *entry,
flow_handler = handler;
result = handler->open (*local_addr);
-
if (result < 0)
ACE_ERROR_RETURN ((LM_ERROR,"handler::open failed\n"),-1);
@@ -607,7 +798,6 @@ TAO_AV_UDP_Connector::connect (TAO_FlowSpec_Entry *entry,
sizeof (sndbufsize)) == -1
&& errno != ENOTSUP)
return 0;
-
else if (handler->get_socket ()->set_option (SOL_SOCKET,
SO_RCVBUF,
(void *) &rcvbufsize,
@@ -618,53 +808,11 @@ TAO_AV_UDP_Connector::connect (TAO_FlowSpec_Entry *entry,
handler->set_remote_address (inet_addr);
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);
-
- this->endpoint_->set_flow_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;
+ return 1;
}
//------------------------------------------------------------
@@ -821,7 +969,6 @@ TAO_AV_UDP_Flow_Factory::make_protocol_object (TAO_FlowSpec_Entry *entry,
endpoint->get_callback (entry->flowname (),
callback);
-
TAO_AV_UDP_Object *object = 0;
ACE_NEW_RETURN (object,
TAO_AV_UDP_Object (callback,
@@ -844,7 +991,6 @@ ACE_STATIC_SVC_DEFINE (TAO_AV_UDP_Flow_Factory,
0)
ACE_FACTORY_DEFINE (TAO_AV, TAO_AV_UDP_Factory)
-
ACE_STATIC_SVC_DEFINE (TAO_AV_UDP_Factory,
ACE_TEXT ("UDP_Factory"),
ACE_SVC_OBJ_T,
diff --git a/TAO/orbsvcs/orbsvcs/AV/UDP.h b/TAO/orbsvcs/orbsvcs/AV/UDP.h
index d1817e52c02..b070df990a4 100644
--- a/TAO/orbsvcs/orbsvcs/AV/UDP.h
+++ b/TAO/orbsvcs/orbsvcs/AV/UDP.h
@@ -91,6 +91,8 @@ public:
int iovcnt,
ACE_Time_Value *s = 0);
+ TAO_AV_UDP_Flow_Handler *handler (void) { return this->handler_; }
+
protected:
TAO_AV_UDP_Flow_Handler *handler_;
ACE_Addr *addr_;
@@ -109,7 +111,7 @@ public:
///Ctor
/// Dtor
TAO_AV_UDP_Flow_Handler (void);
- ~TAO_AV_UDP_Flow_Handler (void);
+ virtual ~TAO_AV_UDP_Flow_Handler (void);
int open (ACE_Addr &address);
virtual TAO_AV_Transport *transport (void);
virtual int set_remote_address (ACE_Addr *address);
@@ -119,7 +121,7 @@ public:
const ACE_SOCK_Dgram *get_socket (void) const;
virtual ACE_Event_Handler* event_handler (void){ return this; }
/// Change the QoS
- virtual int change_qos (AVStreams::QoS);
+ virtual int change_qos (AVStreams::QoS);
protected:
TAO_AV_Core *av_core_;
@@ -140,21 +142,30 @@ public:
virtual int open (TAO_Base_StreamEndPoint *endpoint,
TAO_AV_Core *av_core,
TAO_FlowSpec_Entry *entry,
- TAO_AV_Flow_Protocol_Factory *factory);
+ TAO_AV_Flow_Protocol_Factory *factory,
+ TAO_AV_Core::Flow_Component flow_comp =
+ TAO_AV_Core::TAO_AV_DATA);
virtual int open_default (TAO_Base_StreamEndPoint *endpoint,
TAO_AV_Core *av_core,
TAO_FlowSpec_Entry *entry,
- TAO_AV_Flow_Protocol_Factory *factory);
+ TAO_AV_Flow_Protocol_Factory *factory,
+ TAO_AV_Core::Flow_Component flow_comp =
+ TAO_AV_Core::TAO_AV_DATA);
- virtual int open_i (ACE_INET_Addr *address);
+ virtual int open_i (ACE_INET_Addr *address, int is_default_open);
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_;
+ TAO_AV_Core::Flow_Component flow_component_;
+
+
};
/**
@@ -172,7 +183,9 @@ public:
TAO_AV_Flow_Protocol_Factory *factory);
virtual int connect (TAO_FlowSpec_Entry *entry,
- TAO_AV_Transport *&transport);
+ TAO_AV_Transport *&transport,
+ TAO_AV_Core::Flow_Component flow_comp =
+ TAO_AV_Core::TAO_AV_DATA);
virtual int activate_svc_handler (TAO_AV_Flow_Handler *handler);
virtual int close (void);
protected:
@@ -180,6 +193,29 @@ protected:
TAO_AV_Core *av_core_;
TAO_FlowSpec_Entry *entry_;
TAO_AV_Flow_Protocol_Factory *flow_protocol_factory_;
+ TAO_AV_Core::Flow_Component flow_component_;
+
+};
+
+/**
+ * @class TAO_AV_UDP_Connection_Setup
+ * @brief This class is a helper for the TAO_AV_UDP_Acceptor and
+ * TAO_AV_UDP_Connector. It basically just reduces duplicate code. It takes
+ * the address of the peer in the connection, whether or not it is a multicast
+ * connection, and whether it is a connector or acceptor; and creates the local
+ * address and flow handler associated with the connection.
+ */
+class TAO_AV_Export TAO_AV_UDP_Connection_Setup
+{
+public:
+ /// Indicates whether this setup is for a Connector or an Acceptor
+ enum ConnectionType {CONNECTOR, ACCEPTOR};
+
+ static int setup (TAO_AV_Flow_Handler *&flow_handler,
+ ACE_INET_Addr *inet_addr,
+ ACE_INET_Addr *&local_addr,
+ int is_multicast,
+ ConnectionType ct);
};
/**
@@ -218,7 +254,7 @@ private:
/**
* @class TAO_AV_UDP_Flow_Factory
- * @brief
+ * @brief
*/
class TAO_AV_Export TAO_AV_UDP_Flow_Factory : public TAO_AV_Flow_Protocol_Factory
{
diff --git a/TAO/orbsvcs/orbsvcs/AV/global.h b/TAO/orbsvcs/orbsvcs/AV/global.h
new file mode 100644
index 00000000000..2e98cc6315b
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/AV/global.h
@@ -0,0 +1,31 @@
+/* $Id$ */
+/* GLOBAL.H - RSAREF types and constants
+ */
+
+/* PROTOTYPES should be set to one if and only if the compiler supports
+ function argument prototyping.
+The following makes PROTOTYPES default to 0 if it has not already
+ been defined with C compiler flags.
+ */
+#ifndef PROTOTYPES
+#define PROTOTYPES 0
+#endif
+
+/* POINTER defines a generic pointer type */
+typedef unsigned char *POINTER;
+
+/* UINT2 defines a two byte word */
+typedef unsigned short int UINT2;
+
+/* UINT4 defines a four byte word */
+typedef unsigned long int UINT4;
+
+/* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
+If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
+ returns an empty list.
+ */
+#if PROTOTYPES
+#define PROTO_LIST(list) list
+#else
+#define PROTO_LIST(list) ()
+#endif
diff --git a/TAO/orbsvcs/orbsvcs/AV/md5.h b/TAO/orbsvcs/orbsvcs/AV/md5.h
new file mode 100644
index 00000000000..33b19b52299
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/AV/md5.h
@@ -0,0 +1,49 @@
+/* $Id$ */
+/* MD5.H - header file for MD5C.C
+ */
+
+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+rights reserved.
+
+License to copy and use this software is granted provided that it
+is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+Algorithm" in all material mentioning or referencing this software
+or this function.
+
+License is also granted to make and use derivative works provided
+that such works are identified as "derived from the RSA Data
+Security, Inc. MD5 Message-Digest Algorithm" in all material
+mentioning or referencing the derived work.
+
+RSA Data Security, Inc. makes no representations concerning either
+the merchantability of this software or the suitability of this
+software for any particular purpose. It is provided "as is"
+without express or implied warranty of any kind.
+
+These notices must be retained in any copies of any part of this
+documentation and/or software.
+ */
+
+/* MD5 context. */
+typedef struct {
+ UINT4 state[4]; /* state (ABCD) */
+ UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
+ unsigned char buffer[64]; /* input buffer */
+} MD5_CTX;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//void MD5Init PROTO_LIST ((MD5_CTX *));
+void MD5Init (MD5_CTX *);
+//void MD5Update PROTO_LIST
+// ((MD5_CTX *, unsigned char *, unsigned int));
+void MD5Update (MD5_CTX *, unsigned char *, unsigned int);
+//void MD5Final PROTO_LIST ((unsigned char [16], MD5_CTX *));
+void MD5Final (unsigned char [16], MD5_CTX *);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/TAO/orbsvcs/orbsvcs/AV/md5c.c b/TAO/orbsvcs/orbsvcs/AV/md5c.c
new file mode 100644
index 00000000000..b13d382289e
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/AV/md5c.c
@@ -0,0 +1,345 @@
+/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
+ */
+
+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+rights reserved.
+
+License to copy and use this software is granted provided that it
+is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+Algorithm" in all material mentioning or referencing this software
+or this function.
+
+License is also granted to make and use derivative works provided
+that such works are identified as "derived from the RSA Data
+Security, Inc. MD5 Message-Digest Algorithm" in all material
+mentioning or referencing the derived work.
+
+RSA Data Security, Inc. makes no representations concerning either
+the merchantability of this software or the suitability of this
+software for any particular purpose. It is provided "as is"
+without express or implied warranty of any kind.
+
+These notices must be retained in any copies of any part of this
+documentation and/or software.
+ */
+
+#include "global.h"
+#include "md5.h"
+
+/* Constants for MD5Transform routine.
+ */
+
+#define S11 7
+#define S12 12
+#define S13 17
+#define S14 22
+#define S21 5
+#define S22 9
+#define S23 14
+#define S24 20
+#define S31 4
+#define S32 11
+#define S33 16
+#define S34 23
+#define S41 6
+#define S42 10
+#define S43 15
+#define S44 21
+
+/*static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64]));
+static void Encode PROTO_LIST
+ ((unsigned char *, UINT4 *, unsigned int));
+static void Decode PROTO_LIST
+ ((UINT4 *, unsigned char *, unsigned int));
+static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int));
+static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int));*/
+static void MD5Transform (UINT4 [4], unsigned char [64]);
+static void Encode (unsigned char *, UINT4 *, unsigned int);
+static void Decode (UINT4 *, unsigned char *, unsigned int);
+static void MD5_memcpy (POINTER, POINTER, unsigned int);
+static void MD5_memset (POINTER, int, unsigned int);
+
+static unsigned char PADDING[64] = {
+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/* F, G, H and I are basic MD5 functions.
+ */
+#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
+#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define I(x, y, z) ((y) ^ ((x) | (~z)))
+
+/* ROTATE_LEFT rotates x left n bits.
+ */
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
+
+/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
+Rotation is separate from addition to prevent recomputation.
+ */
+#define FF(a, b, c, d, x, s, ac) { \
+ (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ }
+#define GG(a, b, c, d, x, s, ac) { \
+ (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ }
+#define HH(a, b, c, d, x, s, ac) { \
+ (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ }
+#define II(a, b, c, d, x, s, ac) { \
+ (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ }
+
+/* MD5 initialization. Begins an MD5 operation, writing a new context.
+ */
+void MD5Init (context)
+MD5_CTX *context; /* context */
+{
+ context->count[0] = context->count[1] = 0;
+ /* Load magic initialization constants.
+*/
+ context->state[0] = 0x67452301;
+ context->state[1] = 0xefcdab89;
+ context->state[2] = 0x98badcfe;
+ context->state[3] = 0x10325476;
+}
+
+/* MD5 block update operation. Continues an MD5 message-digest
+ operation, processing another message block, and updating the
+ context.
+ */
+void MD5Update (context, input, inputLen)
+MD5_CTX *context; /* context */
+unsigned char *input; /* input block */
+unsigned int inputLen; /* length of input block */
+{
+ unsigned int i, index, partLen;
+
+ /* Compute number of bytes mod 64 */
+ index = (unsigned int)((context->count[0] >> 3) & 0x3F);
+
+ /* Update number of bits */
+ if ((context->count[0] += ((UINT4)inputLen << 3))
+
+ < ((UINT4)inputLen << 3))
+ context->count[1]++;
+ context->count[1] += ((UINT4)inputLen >> 29);
+
+ partLen = 64 - index;
+
+ /* Transform as many times as possible.
+*/
+ if (inputLen >= partLen) {
+ MD5_memcpy
+ ((POINTER)&context->buffer[index], (POINTER)input, partLen);
+ MD5Transform (context->state, context->buffer);
+
+ for (i = partLen; i + 63 < inputLen; i += 64)
+ MD5Transform (context->state, &input[i]);
+
+ index = 0;
+ }
+ else
+ i = 0;
+
+ /* Buffer remaining input */
+ MD5_memcpy
+ ((POINTER)&context->buffer[index], (POINTER)&input[i],
+ inputLen-i);
+}
+
+/* MD5 finalization. Ends an MD5 message-digest operation, writing the
+ the message digest and zeroizing the context.
+ */
+void MD5Final (digest, context)
+unsigned char digest[16]; /* message digest */
+MD5_CTX *context; /* context */
+{
+ unsigned char bits[8];
+ unsigned int index, padLen;
+
+ /* Save number of bits */
+ Encode (bits, context->count, 8);
+
+ /* Pad out to 56 mod 64.
+*/
+ index = (unsigned int)((context->count[0] >> 3) & 0x3f);
+ padLen = (index < 56) ? (56 - index) : (120 - index);
+ MD5Update (context, PADDING, padLen);
+
+ /* Append length (before padding) */
+ MD5Update (context, bits, 8);
+
+ /* Store state in digest */
+ Encode (digest, context->state, 16);
+
+ /* Zeroize sensitive information.
+*/
+ MD5_memset ((POINTER)context, 0, sizeof (*context));
+}
+
+/* MD5 basic transformation. Transforms state based on block.
+ */
+static void MD5Transform (state, block)
+UINT4 state[4];
+unsigned char block[64];
+{
+ UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
+
+ Decode (x, block, 64);
+
+ /* Round 1 */
+ FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
+ FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
+ FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
+ FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
+ FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
+ FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
+ FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
+ FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
+ FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
+ FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
+ FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
+ FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
+ FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
+ FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
+ FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
+ FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
+
+ /* Round 2 */
+ GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
+ GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
+ GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
+ GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
+ GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
+ GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
+ GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
+ GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
+ GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
+ GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
+ GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
+
+ GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
+ GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
+ GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
+ GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
+ GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
+
+ /* Round 3 */
+ HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
+ HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
+ HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
+ HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
+ HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
+ HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
+ HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
+ HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
+ HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
+ HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
+ HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
+ HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
+ HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
+ HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
+ HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
+ HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
+
+ /* Round 4 */
+ II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
+ II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
+ II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
+ II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
+ II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
+ II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
+ II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
+ II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
+ II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
+ II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
+ II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
+ II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
+ II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
+ II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
+ II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
+ II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
+
+ state[0] += a;
+ state[1] += b;
+ state[2] += c;
+ state[3] += d;
+
+ /* Zeroize sensitive information.
+
+*/
+ MD5_memset ((POINTER)x, 0, sizeof (x));
+}
+
+/* Encodes input (UINT4) into output (unsigned char). Assumes len is
+ a multiple of 4.
+ */
+static void Encode (output, input, len)
+unsigned char *output;
+UINT4 *input;
+unsigned int len;
+{
+ unsigned int i, j;
+
+ for (i = 0, j = 0; j < len; i++, j += 4) {
+ output[j] = (unsigned char)(input[i] & 0xff);
+ output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
+ output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
+ output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
+ }
+}
+
+/* Decodes input (unsigned char) into output (UINT4). Assumes len is
+ a multiple of 4.
+ */
+static void Decode (output, input, len)
+UINT4 *output;
+unsigned char *input;
+unsigned int len;
+{
+ unsigned int i, j;
+
+ for (i = 0, j = 0; j < len; i++, j += 4)
+ output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
+ (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
+}
+
+/* Note: Replace "for loop" with standard memcpy if possible.
+ */
+
+static void MD5_memcpy (output, input, len)
+POINTER output;
+POINTER input;
+unsigned int len;
+{
+ unsigned int i;
+
+ for (i = 0; i < len; i++)
+
+ output[i] = input[i];
+}
+
+/* Note: Replace "for loop" with standard memset if possible.
+ */
+static void MD5_memset (output, value, len)
+POINTER output;
+int value;
+unsigned int len;
+{
+ unsigned int i;
+
+ for (i = 0; i < len; i++)
+ ((char *)output)[i] = (char)value;
+}
+
diff --git a/TAO/orbsvcs/orbsvcs/AV/source.cpp b/TAO/orbsvcs/orbsvcs/AV/source.cpp
deleted file mode 100644
index 0f214e70d1d..00000000000
--- a/TAO/orbsvcs/orbsvcs/AV/source.cpp
+++ /dev/null
@@ -1,541 +0,0 @@
-/*
- * 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"
-
-#if !defined (__ACE_INLINE__)
-#include "source.i"
-#endif /* __ACE_INLINE__ */
-
-/* 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)))
-
-extern "C" int
-compare_func (const void* v0, const void* v1)
-{
- return TAO_AV_SourceManager::compare (v0, v1);
-}
-
-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 (ACE_OS::strcasecmp (s, "cname") == 0)
- return (RTCP_SDES_CNAME);
- if (ACE_OS::strcasecmp (s, "name") == 0)
- return (RTCP_SDES_NAME);
- if (ACE_OS::strcasecmp (s, "email") == 0)
- return (RTCP_SDES_EMAIL);
- if (ACE_OS::strcasecmp (s, "phone") == 0)
- return (RTCP_SDES_PHONE);
- if (ACE_OS::strcasecmp (s, "loc") == 0 || ACE_OS::strcasecmp (s, "location") == 0)
- return (RTCP_SDES_LOC);
- if (ACE_OS::strcasecmp (s, "tool") == 0)
- return (RTCP_SDES_TOOL);
- if (ACE_OS::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;
- }
- ACE_OS::qsort (srctab, n, sizeof (*srctab), compare_func);
- 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
deleted file mode 100644
index 5b440766f1c..00000000000
--- a/TAO/orbsvcs/orbsvcs/AV/source.h
+++ /dev/null
@@ -1,234 +0,0 @@
-/* -*- 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
-#include "ace/pre.h"
-
-#define RTCP_SDES_MAX 7
-
-#include "ace/OS.h"
-#include "tao/PortableServer/ORB_Manager.h"
-
-class TAO_AV_SourceManager;
-
-extern "C"
-{
- int compare_func (const void* v0, const void* v1);
-}
-
-
-#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);
- static int compare (const void*, const void*);
-protected:
- 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__ */
-
-#include "ace/post.h"
-#endif /* TAO_AV_Source_H */
diff --git a/TAO/orbsvcs/orbsvcs/AV/source.i b/TAO/orbsvcs/orbsvcs/AV/source.i
deleted file mode 100644
index 23318862f4f..00000000000
--- a/TAO/orbsvcs/orbsvcs/AV/source.i
+++ /dev/null
@@ -1,491 +0,0 @@
-/* -*- 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;
-}
-