summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOlivier CrĂȘte <olivier.crete@collabora.com>2012-03-02 19:50:03 -0500
committerOlivier CrĂȘte <olivier.crete@collabora.com>2012-03-02 19:50:03 -0500
commit7d7028b8bad8372a8f8c40e8bddf7c4dd403ac24 (patch)
tree9a17c6443c3f8ecf1ced6f5be1b0a356a3b9fee4
parent20dbc5534e6e4df88717d83a3c070f1377885560 (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.c8
-rw-r--r--rakia/call-content.c41
-rw-r--r--rakia/call-stream.c59
-rw-r--r--rakia/call-stream.h8
-rw-r--r--rakia/sip-media.c11
-rw-r--r--rakia/sip-media.h2
-rw-r--r--tests/twisted/voip/calltest.py7
-rw-r--r--tests/twisted/voip/direction-change.py116
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()