diff options
author | Olivier CrĂȘte <olivier.crete@collabora.com> | 2012-03-02 19:50:03 -0500 |
---|---|---|
committer | Olivier CrĂȘte <olivier.crete@collabora.com> | 2012-03-02 19:50:03 -0500 |
commit | 7d7028b8bad8372a8f8c40e8bddf7c4dd403ac24 (patch) | |
tree | 9a17c6443c3f8ecf1ced6f5be1b0a356a3b9fee4 | |
parent | 20dbc5534e6e4df88717d83a3c070f1377885560 (diff) |
Put all direction control code in the stream
Also, the Content is set on the Stream at creation time
-rw-r--r-- | rakia/call-channel.c | 8 | ||||
-rw-r--r-- | rakia/call-content.c | 41 | ||||
-rw-r--r-- | rakia/call-stream.c | 59 | ||||
-rw-r--r-- | rakia/call-stream.h | 8 | ||||
-rw-r--r-- | rakia/sip-media.c | 11 | ||||
-rw-r--r-- | rakia/sip-media.h | 2 | ||||
-rw-r--r-- | tests/twisted/voip/calltest.py | 7 | ||||
-rw-r--r-- | tests/twisted/voip/direction-change.py | 116 |
8 files changed, 161 insertions, 91 deletions
diff --git a/rakia/call-channel.c b/rakia/call-channel.c index 23de0cf..e777cf6 100644 --- a/rakia/call-channel.c +++ b/rakia/call-channel.c @@ -554,6 +554,14 @@ new_content (RakiaCallChannel *self, name = free_name = g_strdup_printf ("%s %u", media_type_name, self->priv->last_content_no); + /* We already request bidi for initial media, + * the client can change it before accepting. + */ + if (disposition == TP_CALL_CONTENT_DISPOSITION_INITIAL) + rakia_sip_media_set_requested_direction (media, + RAKIA_DIRECTION_BIDIRECTIONAL); + + content = rakia_call_content_new (self, media, object_path, tp_base_channel_get_connection (bchan), name, media_type, creator, disposition); diff --git a/rakia/call-content.c b/rakia/call-content.c index b159ca1..314b04a 100644 --- a/rakia/call-content.c +++ b/rakia/call-content.c @@ -375,53 +375,16 @@ rakia_call_content_add_stream (RakiaCallContent *self) { RakiaCallContentPrivate *priv = self->priv; TpBaseCallContent *bcc = TP_BASE_CALL_CONTENT (self); - TpHandle creator; gchar *object_path; - TpSendingState local_sending_state; - TpSendingState remote_sending_state; - - g_object_get (self, "creator", &creator, NULL); - - if (rakia_sip_media_get_requested_direction (priv->media) & - RAKIA_DIRECTION_SEND) - { - if (!tp_base_call_channel_is_accepted ( - TP_BASE_CALL_CHANNEL (priv->channel)) && - !tp_base_channel_is_requested (TP_BASE_CHANNEL (priv->channel))) - local_sending_state = TP_SENDING_STATE_PENDING_SEND; - else - local_sending_state = TP_SENDING_STATE_SENDING; - } - else - { - local_sending_state = TP_SENDING_STATE_NONE; - } - - - if (rakia_sip_media_get_requested_direction (priv->media) & - RAKIA_DIRECTION_RECEIVE) - remote_sending_state = TP_SENDING_STATE_PENDING_SEND; - else - remote_sending_state = TP_SENDING_STATE_NONE; object_path = g_strdup_printf ("%s/Stream", tp_base_call_content_get_object_path (bcc)); - priv->stream = rakia_call_stream_new (priv->channel, priv->media, + priv->stream = rakia_call_stream_new (self, priv->media, object_path, TP_STREAM_TRANSPORT_TYPE_RAW_UDP, - tp_base_call_content_get_connection (bcc), - local_sending_state); + tp_base_call_content_get_connection (bcc)); g_free (object_path); - tp_base_call_stream_update_remote_sending_state ( - TP_BASE_CALL_STREAM (priv->stream), - tp_base_channel_get_target_handle (TP_BASE_CHANNEL (priv->channel)), - remote_sending_state, creator, - TP_CALL_STATE_CHANGE_REASON_PROGRESS_MADE, "", ""); - tp_base_call_content_add_stream (bcc, TP_BASE_CALL_STREAM (priv->stream)); - - tp_base_media_call_stream_update_receiving_state ( - TP_BASE_MEDIA_CALL_STREAM (priv->stream)); } static void diff --git a/rakia/call-stream.c b/rakia/call-stream.c index 5cd79c3..cc558f2 100644 --- a/rakia/call-stream.c +++ b/rakia/call-stream.c @@ -71,8 +71,7 @@ G_DEFINE_TYPE (RakiaCallStream, rakia_call_stream, /* properties */ enum { - PROP_CHANNEL = 1, - PROP_SIP_MEDIA, + PROP_SIP_MEDIA = 1, PROP_CAN_REQUEST_RECEIVING, LAST_PROPERTY }; @@ -111,9 +110,6 @@ rakia_call_stream_set_property (GObject *object, switch (property_id) { - case PROP_CHANNEL: - priv->channel = g_value_get_pointer (value); - break; case PROP_SIP_MEDIA: priv->media = g_value_dup_object (value); break; @@ -179,11 +175,6 @@ rakia_call_stream_class_init (RakiaCallStreamClass *rakia_call_stream_class) g_object_class_override_property (object_class, PROP_CAN_REQUEST_RECEIVING, "can-request-receiving"); - param_spec = g_param_spec_pointer ("channel", "RakiaCallChannel object", - "Call Channel", - G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS); - g_object_class_install_property (object_class, PROP_CHANNEL, param_spec); - param_spec = g_param_spec_object ("sip-media", "RakiaSipMedia object", "SIP media object that is used for this SIP media channel object.", RAKIA_TYPE_SIP_MEDIA, @@ -196,12 +187,17 @@ rakia_call_stream_constructed (GObject *object) { RakiaCallStream *self = RAKIA_CALL_STREAM (object); RakiaCallStreamPrivate *priv = self->priv; + TpBaseCallStream *bcs = TP_BASE_CALL_STREAM (object); TpBaseMediaCallStream *bmcs = TP_BASE_MEDIA_CALL_STREAM (object); + TpHandle contact; GPtrArray *stun_array; GPtrArray *relay_array; gchar *stun_server = NULL; guint stun_port = 0; + g_object_get (self, "channel", &priv->channel, NULL); + contact = tp_base_channel_get_target_handle (TP_BASE_CHANNEL (priv->channel)); + g_signal_connect_object (priv->media, "remote-candidates-updated", G_CALLBACK (media_remote_candidates_updated_cb), self, 0); g_signal_connect_object (priv->media, "direction-changed", @@ -236,10 +232,23 @@ rakia_call_stream_constructed (GObject *object) G_CALLBACK (receiving_updated_cb), NULL); receiving_updated_cb (self); - G_OBJECT_CLASS (rakia_call_stream_parent_class)->constructed (object); -} + /* Put the initial value */ + if (rakia_sip_media_get_requested_direction (priv->media) & + RAKIA_DIRECTION_RECEIVE) + tp_base_call_stream_update_remote_sending_state (bcs, contact, + TP_SENDING_STATE_PENDING_SEND, 0, + TP_CALL_STATE_CHANGE_REASON_PROGRESS_MADE, "", ""); + else + tp_base_call_stream_update_remote_sending_state (bcs, contact, + TP_SENDING_STATE_NONE, 0, + TP_CALL_STATE_CHANGE_REASON_PROGRESS_MADE, "", ""); + rakia_call_stream_update_direction (self); + tp_base_media_call_stream_update_receiving_state ( + TP_BASE_MEDIA_CALL_STREAM (self)); + G_OBJECT_CLASS (rakia_call_stream_parent_class)->constructed (object); +} void rakia_call_stream_dispose (GObject *object) @@ -549,20 +558,19 @@ media_remote_candidates_updated_cb (RakiaSipMedia *media, RakiaCallStream *self) } RakiaCallStream * -rakia_call_stream_new (RakiaCallChannel *channel, +rakia_call_stream_new ( + RakiaCallContent *content, RakiaSipMedia *media, const gchar *object_path, TpStreamTransportType transport, - TpBaseConnection *connection, - TpSendingState local_sending_state) + TpBaseConnection *connection) { return g_object_new (RAKIA_TYPE_CALL_STREAM, - "channel", channel, + "content", content, "sip-media", media, "object-path", object_path, "transport", transport, "connection", connection, - "local-sending-state", local_sending_state, NULL); } @@ -572,10 +580,9 @@ rakia_call_stream_update_direction (RakiaCallStream *self) TpBaseCallStream *bcs = TP_BASE_CALL_STREAM (self); TpBaseMediaCallStream *bmcs = TP_BASE_MEDIA_CALL_STREAM (self); RakiaCallStreamPrivate *priv = self->priv; - TpHandle contact = tp_base_channel_get_target_handle ( - TP_BASE_CHANNEL (priv->channel)); - TpHandle self_handle = tp_base_channel_get_self_handle ( - TP_BASE_CHANNEL (priv->channel)); + TpBaseChannel *bchan = TP_BASE_CHANNEL (priv->channel); + TpHandle contact = tp_base_channel_get_target_handle (bchan); + TpHandle self_handle = tp_base_channel_get_self_handle (bchan); RakiaDirection direction = rakia_sip_media_get_direction (priv->media); RakiaDirection remote_direction = rakia_sip_media_get_remote_direction (priv->media); @@ -585,14 +592,22 @@ rakia_call_stream_update_direction (RakiaCallStream *self) tp_base_media_call_channel_get_local_hold_state ( TP_BASE_MEDIA_CALL_CHANNEL (priv->channel), NULL); + DEBUG ("direction: %s requested: %s remote: %s hold: %d", + rakia_direction_to_string (direction), + rakia_direction_to_string (requested_direction), + rakia_direction_to_string (remote_direction), + hold_state != TP_LOCAL_HOLD_STATE_UNHELD); + if ((direction & RAKIA_DIRECTION_SEND || + !rakia_sip_media_has_remote_media (priv->media) || hold_state != TP_LOCAL_HOLD_STATE_UNHELD) && requested_direction & RAKIA_DIRECTION_SEND) { tp_base_call_stream_update_local_sending_state (bcs, TP_SENDING_STATE_SENDING, self_handle, TP_CALL_STATE_CHANGE_REASON_USER_REQUESTED, "", "User requested"); - tp_base_media_call_stream_set_local_sending (bmcs, TRUE); + if (rakia_sip_media_has_remote_media (priv->media)) + tp_base_media_call_stream_set_local_sending (bmcs, TRUE); } else if (remote_direction & RAKIA_DIRECTION_SEND) { diff --git a/rakia/call-stream.h b/rakia/call-stream.h index 3d03d68..ccc15ab 100644 --- a/rakia/call-stream.h +++ b/rakia/call-stream.h @@ -25,7 +25,7 @@ #include <telepathy-glib/base-media-call-stream.h> -#include "rakia/call-channel.h" +#include "rakia/call-content.h" #include "rakia/sip-media.h" G_BEGIN_DECLS @@ -62,12 +62,12 @@ GType rakia_call_stream_get_type (void); (G_TYPE_INSTANCE_GET_CLASS ((obj), RAKIA_TYPE_CALL_STREAM, \ RakiaCallStreamClass)) -RakiaCallStream * rakia_call_stream_new (RakiaCallChannel *channel, +RakiaCallStream * rakia_call_stream_new ( + RakiaCallContent *content, RakiaSipMedia *media, const gchar *object_path, TpStreamTransportType transport, - TpBaseConnection *connection, - TpSendingState local_sending_state); + TpBaseConnection *connection); void rakia_call_stream_update_direction (RakiaCallStream *self); diff --git a/rakia/sip-media.c b/rakia/sip-media.c index 845291f..14c867c 100644 --- a/rakia/sip-media.c +++ b/rakia/sip-media.c @@ -373,7 +373,14 @@ priv_get_sdp_direction (RakiaSipMedia *media, gboolean authoritative) RakiaSipMediaPrivate *priv = RAKIA_SIP_MEDIA_GET_PRIVATE (media); RakiaDirection direction = priv->requested_direction; - if (!authoritative) + DEBUG ("req: %s auth: %d remote: %p %s hold: %d", + rakia_direction_to_string (direction), + authoritative, + priv->remote_media, + rakia_direction_to_string (rakia_sip_media_get_remote_direction (media)), + priv->hold_requested); + + if (!authoritative && priv->remote_media) direction &= rakia_sip_media_get_remote_direction (media); /* Don't allow send, only receive if a hold is requested */ @@ -583,7 +590,7 @@ rakia_sip_media_get_remote_direction (RakiaSipMedia *media) RakiaSipMediaPrivate *priv = RAKIA_SIP_MEDIA_GET_PRIVATE (media); if (priv->remote_media == NULL) - return RAKIA_DIRECTION_BIDIRECTIONAL; + return RAKIA_DIRECTION_NONE; return rakia_direction_from_remote_media (priv->remote_media); } diff --git a/rakia/sip-media.h b/rakia/sip-media.h index 07553d9..73598aa 100644 --- a/rakia/sip-media.h +++ b/rakia/sip-media.h @@ -173,6 +173,8 @@ gboolean rakia_sip_media_get_hold_requested (RakiaSipMedia *media); void rakia_sip_media_set_can_receive (RakiaSipMedia *media, gboolean can_receive); +gboolean rakia_sip_media_has_remote_media (RakiaSipMedia *media); + const gchar *rakia_direction_to_string (RakiaDirection direction); G_END_DECLS diff --git a/tests/twisted/voip/calltest.py b/tests/twisted/voip/calltest.py index 490faee..e24ff55 100644 --- a/tests/twisted/voip/calltest.py +++ b/tests/twisted/voip/calltest.py @@ -115,15 +115,14 @@ class CallTest: assertEquals(cs.CALL_SENDING_STATE_SENDING, stream_props['LocalSendingState']) - if initial or not incoming: + if incoming: assertEquals( - {self.remote_handle: cs.CALL_SENDING_STATE_PENDING_SEND}, + {self.remote_handle: cs.CALL_SENDING_STATE_SENDING}, stream_props['RemoteMembers']) else: assertEquals( - {self.remote_handle: cs.CALL_SENDING_STATE_SENDING}, + {self.remote_handle: cs.CALL_SENDING_STATE_PENDING_SEND}, stream_props['RemoteMembers']) - smedia_props = content.stream.Properties.GetAll( cs.CALL_STREAM_IFACE_MEDIA) diff --git a/tests/twisted/voip/direction-change.py b/tests/twisted/voip/direction-change.py index 3fb797a..cd69940 100644 --- a/tests/twisted/voip/direction-change.py +++ b/tests/twisted/voip/direction-change.py @@ -536,6 +536,9 @@ class DirectionChange(calltest.CallTest): self.receiving = False + assert self.contents[0].stream.Properties.Get(cs.CALL_STREAM_IFACE_MEDIA, + 'SendingState') == cs.CALL_STREAM_FLOW_STATE_STARTED + content.stream.Media.ReportReceivingFailure( cs.CALL_SCR_MEDIA_ERROR, "", "receiving error") @@ -553,7 +556,7 @@ class DirectionChange(calltest.CallTest): assertContains('a=sendonly', reinvite_event.sip_message.body) self.context.check_call_sdp(reinvite_event.sip_message.body) body = reinvite_event.sip_message.body.replace( - 'sendonly', self.receiving and 'recvonly' or 'inactive') + 'sendonly', self.sending and 'recvonly' or 'inactive') self.context.accept(reinvite_event.sip_message, body) @@ -563,17 +566,18 @@ class DirectionChange(calltest.CallTest): self.start_receiving(content) - def add_content_during_hold(self): - incoming = False - content_path = self.chan.Call1.AddContent( - "NewContent", cs.MEDIA_STREAM_TYPE_AUDIO, - cs.MEDIA_STREAM_DIRECTION_BIDIRECTIONAL) + def add_local_content_during_hold(self): media_unhold_events = [ EventPattern('dbus-signal', signal='SendingStateChanged'), EventPattern('dbus-signal', signal='ReceivingStateChanged')] self.q.forbid_events(media_unhold_events) + content_path = self.chan.Call1.AddContent( + "NewContent", cs.MEDIA_STREAM_TYPE_AUDIO, + cs.MEDIA_STREAM_DIRECTION_BIDIRECTIONAL) + + self.q.expect('dbus-signal', signal='ContentAdded', args=[content_path]) @@ -594,19 +598,11 @@ class DirectionChange(calltest.CallTest): stream_props = stream.Properties.GetAll(cs.CALL_STREAM) assertEquals(True, stream_props['CanRequestReceiving']) - if incoming: - assertEquals(cs.CALL_SENDING_STATE_PENDING_SEND, - stream_props['LocalSendingState']) - assertEquals( - {self.remote_handle: cs.CALL_SENDING_STATE_SENDING}, - stream_props['RemoteMembers']) - - else: - assertEquals( - {self.remote_handle: cs.CALL_SENDING_STATE_PENDING_SEND}, - stream_props['RemoteMembers']) - assertEquals(cs.CALL_SENDING_STATE_SENDING, - stream_props['LocalSendingState']) + assertEquals( + {self.remote_handle: cs.CALL_SENDING_STATE_PENDING_SEND}, + stream_props['RemoteMembers']) + assertEquals(cs.CALL_SENDING_STATE_SENDING, + stream_props['LocalSendingState']) smedia_props = stream.Properties.GetAll( cs.CALL_STREAM_IFACE_MEDIA) @@ -652,6 +648,79 @@ class DirectionChange(calltest.CallTest): self.q.unforbid_events(media_unhold_events) + + def add_remote_content_during_hold(self): + + media_unhold_events = [ + EventPattern('dbus-signal', signal='SendingStateChanged'), + EventPattern('dbus-signal', signal='ReceivingStateChanged')] + self.q.forbid_events(media_unhold_events) + + self.context.reinvite([('audio', 'recvonly'), ('audio', None)]) + + ca = self.q.expect('dbus-signal', signal='ContentAdded') + + content = self.bus.get_object (self.conn.bus_name, ca.args[0]) + + content_props = content.GetAll(cs.CALL_CONTENT) + assertEquals(cs.CALL_DISPOSITION_NONE, content_props['Disposition']) + assertEquals(cs.MEDIA_STREAM_TYPE_AUDIO, content_props['Type']) + + assertLength(1, content_props['Streams']) + + tmpstream = self.bus.get_object (self.conn.bus_name, + content_props['Streams'][0]) + + stream = ProxyWrapper (tmpstream, cs.CALL_STREAM, + {'Media': cs.CALL_STREAM_IFACE_MEDIA}) + + stream_props = stream.Properties.GetAll(cs.CALL_STREAM) + assertEquals(True, stream_props['CanRequestReceiving']) + assertEquals(cs.CALL_SENDING_STATE_PENDING_SEND, + stream_props['LocalSendingState']) + assertEquals( + {self.remote_handle: cs.CALL_SENDING_STATE_SENDING}, + stream_props['RemoteMembers']) + + smedia_props = stream.Properties.GetAll( + cs.CALL_STREAM_IFACE_MEDIA) + assertEquals(cs.CALL_SENDING_STATE_NONE, smedia_props['SendingState']) + assertEquals(cs.CALL_SENDING_STATE_NONE, + smedia_props['ReceivingState']) + + mdo = content.Get(cs.CALL_CONTENT_IFACE_MEDIA, + 'MediaDescriptionOffer') + md = self.bus.get_object (self.conn.bus_name, mdo[0]) + md.Accept(self.context.get_audio_md_dbus( + self.remote_handle)) + + self.add_candidates(stream) + + acc = self.q.expect('sip-response', code=200) + self.context.check_call_sdp( + acc.sip_message.body, + [('audio', 'sendonly'), ('audio', 'inactive')]) + self.context.ack(acc.sip_message) + + content.Remove() + + + reinvite_event = self.q.expect('sip-invite') + + self.context.check_call_sdp(reinvite_event.sip_message.body, + self.medias) + body = reinvite_event.sip_message.body.replace( + 'sendonly', self.receiving and 'recvonly' or 'inactive') + + self.context.accept(reinvite_event.sip_message, body) + + ack_cseq = "%s ACK" % reinvite_event.cseq.split()[0] + self.q.expect('sip-ack', cseq=ack_cseq) + + + self.q.unforbid_events(media_unhold_events) + + def during_call(self): content = self.contents[0] @@ -664,20 +733,27 @@ class DirectionChange(calltest.CallTest): self.stop_start_receiving_user_requested(content) + self.running_check() + self.reject_stop_receiving(content) self.stop_start_receiving_user_requested(content) self.reject_start_receiving(content) + self.running_check() + self.sending_failed(content) self.receiving_failed(content) + self.running_check() + direction_change_events = \ self.stream_dbus_signal_event('LocalSendingStateChanged') + \ self.stream_dbus_signal_event('RemoteMembersChanged') self.q.forbid_events(direction_change_events) self.hold() - self.add_content_during_hold() + self.add_local_content_during_hold() + self.add_remote_content_during_hold() self.unhold_fail(receiving=True) self.unhold_fail(receiving=False) self.unhold_succeed() |