summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOlivier CrĂȘte <olivier.crete@collabora.com>2012-02-14 16:08:19 -0500
committerOlivier CrĂȘte <olivier.crete@collabora.com>2012-02-14 16:47:11 -0500
commit10cddfb8a7fc6780d2ae0d26550eebda4f632455 (patch)
tree0ebe7b898478fd97d69929f649383899d61783f6
parent40769c349d7cdc94d71b1d65e5e6dbf62baa8966 (diff)
Make SetSending work, also add tests for it
-rw-r--r--rakia/call-stream.c44
-rw-r--r--rakia/sip-media.c7
-rw-r--r--rakia/sip-session.c12
-rw-r--r--tests/twisted/Makefile.am1
-rw-r--r--tests/twisted/voip/calltest.py2
-rw-r--r--tests/twisted/voip/direction-change.py138
-rw-r--r--tests/twisted/voip/voip_test.py14
7 files changed, 189 insertions, 29 deletions
diff --git a/rakia/call-stream.c b/rakia/call-stream.c
index e3e42ae..50e02f8 100644
--- a/rakia/call-stream.c
+++ b/rakia/call-stream.c
@@ -351,12 +351,16 @@ rakia_call_stream_set_sending (TpBaseMediaCallStream *stream,
RakiaDirection current_direction =
rakia_sip_media_get_requested_direction (priv->media);
- if (current_direction & RAKIA_DIRECTION_SEND)
+ if (!!(current_direction & RAKIA_DIRECTION_SEND) == sending)
return TRUE;
- rakia_sip_media_set_requested_direction (priv->media,
- current_direction | RAKIA_DIRECTION_SEND);
+ if (sending)
+ rakia_sip_media_set_requested_direction (priv->media,
+ current_direction | RAKIA_DIRECTION_SEND);
+ else
+ rakia_sip_media_set_requested_direction (priv->media,
+ current_direction & ~RAKIA_DIRECTION_SEND);
return TRUE;
}
@@ -426,25 +430,37 @@ static void
media_direction_changed_cb (RakiaSipMedia *media, RakiaCallStream *self)
{
TpBaseCallStream *bcs = TP_BASE_CALL_STREAM (self);
-#if 0
+ 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));
- TpSendingState local_sending =
- tp_base_call_stream_get_local_sending_state (bcs);
- TpSendingState remote_sending =
- tp_base_call_stream_get_remote_sending_state (bcs, contact);
-#endif
- TpSendingState local_sending = TP_SENDING_STATE_NONE;
+ TpHandle self_handle = tp_base_channel_get_self_handle (
+ TP_BASE_CHANNEL (priv->channel));
RakiaDirection direction = rakia_sip_media_get_direction (media);
RakiaDirection requested_direction =
rakia_sip_media_get_requested_direction (media);
if (requested_direction & RAKIA_DIRECTION_SEND)
- local_sending = TP_SENDING_STATE_SENDING;
+ {
+ tp_base_call_stream_update_local_sending_state (bcs,
+ TP_SENDING_STATE_SENDING, self_handle,
+ TP_CALL_STATE_CHANGE_REASON_USER_REQUESTED, "", "User requested");
+ }
else if (direction & RAKIA_DIRECTION_SEND)
- local_sending = TP_SENDING_STATE_PENDING_SEND;
+ {
+ tp_base_call_stream_update_local_sending_state (bcs,
+ TP_SENDING_STATE_PENDING_SEND, contact,
+ TP_CALL_STATE_CHANGE_REASON_PROGRESS_MADE, "",
+ "Remote requested that we start sending");
+ }
+ else
+ {
+ tp_base_call_stream_update_local_sending_state (bcs,
+ TP_SENDING_STATE_NONE, self_handle,
+ TP_CALL_STATE_CHANGE_REASON_USER_REQUESTED, "", "User requested");
+ }
- tp_base_call_stream_update_local_sending_state (bcs,
- local_sending, 0, TP_CALL_STATE_CHANGE_REASON_PROGRESS_MADE, "", "");
+ if (requested_direction & RAKIA_DIRECTION_SEND &&
+ direction & RAKIA_DIRECTION_SEND)
+ tp_base_media_call_stream_set_local_sending (bmcs, TRUE);
}
diff --git a/rakia/sip-media.c b/rakia/sip-media.c
index 55d8c76..50c64f1 100644
--- a/rakia/sip-media.c
+++ b/rakia/sip-media.c
@@ -580,9 +580,7 @@ rakia_sip_media_set_direction (RakiaSipMedia *media,
{
RakiaSipMediaPrivate *priv = RAKIA_SIP_MEDIA_GET_PRIVATE (media);
- direction &= priv->requested_direction;
-
- media->priv->direction = direction;
+ priv->direction = direction;
g_signal_emit (media, signals[SIG_DIRECTION_CHANGED], 0);
}
@@ -785,7 +783,6 @@ static void push_remote_candidates (RakiaSipMedia *media)
}
-
/*
* Sets the remote candidates and codecs for this stream, as
* received via signaling.
@@ -856,6 +853,8 @@ rakia_sip_media_set_remote_media (RakiaSipMedia *media,
if (sdp_media_cmp (old_media, new_media) == 0)
{
MEDIA_DEBUG (media, "no media changes detected for the media");
+ /* Emit direct change anyway */
+ g_signal_emit (media, signals[SIG_DIRECTION_CHANGED], 0);
return TRUE;
}
diff --git a/rakia/sip-session.c b/rakia/sip-session.c
index 2aef92f..5e7a9d5 100644
--- a/rakia/sip-session.c
+++ b/rakia/sip-session.c
@@ -510,7 +510,8 @@ rakia_sip_session_receive_reinvite (RakiaSipSession *self)
priv_save_event (self);
- rakia_sip_session_change_state (self, RAKIA_SIP_SESSION_STATE_REINVITE_RECEIVED);
+ rakia_sip_session_change_state (self,
+ RAKIA_SIP_SESSION_STATE_REINVITE_RECEIVED);
}
@@ -616,10 +617,7 @@ rakia_sip_session_queued (RakiaSipSession *self)
static void
rakia_sip_session_receive_invite (RakiaSipSession *self)
{
- RakiaSipSessionPrivate *priv = RAKIA_SIP_SESSION_GET_PRIVATE (self);
-
- g_return_if_fail (priv->state == RAKIA_SIP_SESSION_STATE_CREATED);
- g_return_if_fail (priv->nua_op != NULL);
+ g_return_if_fail (self->priv->nua_op != NULL);
/* We'll do Ringing later instead */
/* nua_respond (priv->nua_op, SIP_183_SESSION_PROGRESS, TAG_END()); */
@@ -890,7 +888,6 @@ priv_update_remote_hold (RakiaSipSession *self)
RakiaSipMedia *media;
gboolean has_medias = FALSE;
gboolean remote_held = TRUE;
- guint direction;
guint i;
/* The call is remotely unheld if there's at least one sending media */
@@ -1408,7 +1405,8 @@ priv_nua_i_state_cb (RakiaSipSession *self,
}
- if (ss_state == nua_callstate_received)
+ if (ss_state == nua_callstate_received &&
+ priv->state == RAKIA_SIP_SESSION_STATE_CREATED)
{
/* Let's announce the new call now that the initial streams have
* been created
diff --git a/tests/twisted/Makefile.am b/tests/twisted/Makefile.am
index 8ce4182..62e816f 100644
--- a/tests/twisted/Makefile.am
+++ b/tests/twisted/Makefile.am
@@ -11,6 +11,7 @@ TWISTED_TESTS = \
test-self-alias.py \
text/initiate-requestotron.py \
voip/calltest.py \
+ voip/direction-change.py
voip/requestable-classes.py \
voip/ringing-queued.py \
$(NULL)
diff --git a/tests/twisted/voip/calltest.py b/tests/twisted/voip/calltest.py
index 0735711..7d952e7 100644
--- a/tests/twisted/voip/calltest.py
+++ b/tests/twisted/voip/calltest.py
@@ -455,7 +455,7 @@ def run(**params):
exec_test(lambda q, b, c, s:
run_call_test(q, b, c, s, True, **params))
exec_test(lambda q, b, c, s:
- run_call_test(q, b, c, s, False, **params))
+ run_call_test(q, b, c, s, False, **params))
if __name__ == '__main__':
run()
diff --git a/tests/twisted/voip/direction-change.py b/tests/twisted/voip/direction-change.py
new file mode 100644
index 0000000..9fdf40a
--- /dev/null
+++ b/tests/twisted/voip/direction-change.py
@@ -0,0 +1,138 @@
+import calltest
+import constants as cs
+from servicetest import (
+ EventPattern, call_async,
+ assertEquals, assertNotEquals, assertContains, assertLength,
+ assertDoesNotContain
+ )
+
+class DirectionChange(calltest.CallTest):
+
+ def stop_sending(self, content):
+
+ content.stream.SetSending(False)
+ self.q.expect('dbus-signal', signal='SendingStateChanged',
+ args=[cs.CALL_STREAM_FLOW_STATE_PENDING_STOP],
+ path=content.stream.__dbus_object_path__)
+
+ content.stream.Media.CompleteSendingStateChange(
+ cs.CALL_STREAM_FLOW_STATE_STOPPED)
+
+ o = self.q.expect_many(
+ EventPattern('dbus-signal', signal='SendingStateChanged',
+ args=[cs.CALL_STREAM_FLOW_STATE_STOPPED],
+ path=content.stream.__dbus_object_path__),
+ EventPattern('dbus-signal', signal='LocalSendingStateChanged',
+ path=content.stream.__dbus_object_path__),
+ EventPattern('sip-invite'))
+
+ assertEquals(cs.CALL_SENDING_STATE_NONE, o[1].args[0])
+ assertEquals(self.self_handle, o[1].args[1][0])
+ reinvite_event = o[2]
+
+ assertContains('a=recvonly', reinvite_event.sip_message.body)
+ self.context.check_call_sdp(reinvite_event.sip_message.body)
+ body = reinvite_event.sip_message.body.replace('recvonly','sendonly')
+
+ 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)
+
+ def start_sending(self, content):
+ content.stream.SetSending(True)
+
+ reinvite_event, lss = self.q.expect_many(
+ EventPattern('sip-invite'),
+ EventPattern('dbus-signal', signal='LocalSendingStateChanged',
+ path=content.stream.__dbus_object_path__))
+
+ assertEquals(cs.CALL_SENDING_STATE_SENDING, lss.args[0])
+ assertEquals(self.self_handle, lss.args[1][0])
+
+ assertDoesNotContain('a=recvonly', reinvite_event.sip_message.body)
+ assertDoesNotContain('a=sendonly', reinvite_event.sip_message.body)
+ assertDoesNotContain('a=inactive', reinvite_event.sip_message.body)
+ self.context.check_call_sdp(reinvite_event.sip_message.body)
+ self.context.accept(reinvite_event.sip_message)
+
+ ack_cseq = "%s ACK" % reinvite_event.cseq.split()[0]
+ self.q.expect_many(
+ EventPattern('sip-ack', cseq=ack_cseq),
+ EventPattern('dbus-signal', signal='SendingStateChanged',
+ args=[cs.CALL_STREAM_FLOW_STATE_PENDING_START]))
+
+ content.stream.Media.CompleteSendingStateChange(
+ cs.CALL_STREAM_FLOW_STATE_STARTED)
+
+ self.q.expect('dbus-signal', signal='SendingStateChanged',
+ args=[cs.CALL_STREAM_FLOW_STATE_STARTED],
+ path=content.stream.__dbus_object_path__)
+
+ def stop_start_user_requested(self, content):
+ self.stop_sending(content)
+ self.start_sending(content)
+
+
+ def stop_start_remote_requested(self, content):
+ lss_event = [
+ EventPattern('dbus-signal', signal='LocalSendingStateChanged')]
+ direction_events = [
+ EventPattern('dbus-signal', signal='SendingStateChanged'),
+ EventPattern('dbus-signal', signal='ReceivingStateChanged'),
+ ]
+
+ self.stop_sending(content)
+ self.q.forbid_events(lss_event)
+ self.q.forbid_events(direction_events)
+
+ self.context.reinvite([('audio','sendonly')])
+
+ acc = self.q.expect('sip-response', call_id=self.context.call_id,
+ code=200)
+ assertContains('a=recvonly', acc.sip_message.body)
+
+ self.context.check_call_sdp(acc.sip_message.body)
+ self.context.ack(acc.sip_message)
+
+ self.q.unforbid_events(lss_event)
+
+ self.context.reinvite([('audio','')])
+
+ acc, lss = self.q.expect_many(
+ EventPattern('sip-response', call_id=self.context.call_id,
+ code=200),
+ EventPattern('dbus-signal', signal='LocalSendingStateChanged'))
+ assertEquals(cs.CALL_SENDING_STATE_PENDING_SEND, lss.args[0])
+ assertEquals(self.remote_handle, lss.args[1][0])
+ assertContains('a=recvonly', acc.sip_message.body)
+
+ assertEquals(cs.CALL_STREAM_FLOW_STATE_STOPPED,
+ content.stream.Properties.Get(cs.CALL_STREAM_IFACE_MEDIA,
+ 'SendingState'))
+
+ self.context.check_call_sdp(acc.sip_message.body)
+ self.context.ack(acc.sip_message)
+
+ self.q.unforbid_events(direction_events)
+ self.start_sending(content)
+
+
+ def during_call(self):
+ content = self.contents[0]
+
+ remote_hold_event = [
+ EventPattern('dbus-signal', signal='CallStateChanged')]
+ self.q.forbid_events(remote_hold_event)
+
+ self.stop_start_user_requested(content)
+ self.stop_start_remote_requested(content)
+
+ self.q.unforbid_events(remote_hold_event)
+ return calltest.CallTest.during_call(self)
+
+
+
+
+if __name__ == '__main__':
+ calltest.run(klass=DirectionChange)
diff --git a/tests/twisted/voip/voip_test.py b/tests/twisted/voip/voip_test.py
index 3f7efe4..8079c02 100644
--- a/tests/twisted/voip/voip_test.py
+++ b/tests/twisted/voip/voip_test.py
@@ -46,6 +46,7 @@ class VoipTestContext(object):
self.peer_id = "sip:" + peer
self.sip_proxy = sip_proxy
self._cseq_id = 1
+ self.to = None
def dbusify_codecs(self, codecs):
dbussed_codecs = [ (id, name, rate, 1, False, params )
@@ -112,7 +113,7 @@ class VoipTestContext(object):
msg.body = body
msg.addHeader('content-length', '%d' % len(msg.body))
msg.addHeader('from', from_ or '<%s>;tag=XYZ' % self.peer_id)
- msg.addHeader('to', to_ or '<sip:testacc@127.0.0.1>')
+ msg.addHeader('to', to_ or self.to or '<sip:testacc@127.0.0.1>')
self._cseq_id += 1
additional_headers.setdefault('cseq', '%d %s' % (self._cseq_id, message_type))
for key, vals in additional_headers.items():
@@ -128,12 +129,14 @@ class VoipTestContext(object):
self.sip_proxy.sendMessage(destination, msg)
return msg
- def accept(self, invite_message):
+ def accept(self, invite_message, body=None):
self.call_id = invite_message.headers['call-id'][0]
+ if invite_message.headers['from'][0].find('tag='):
+ self.to = invite_message.headers['from'][0]
response = self.sip_proxy.responseFromRequest(200, invite_message)
# Echo rakia's SDP back to it. It doesn't care.
response.addHeader('content-type', 'application/sdp')
- response.body = invite_message.body
+ response.body = body or invite_message.body
response.addHeader('content-length', '%d' % len(response.body))
self.sip_proxy.deliverResponse(response)
return response
@@ -147,6 +150,11 @@ class VoipTestContext(object):
def ack(self, ok_message):
cseq = '%s ACK' % ok_message.headers['cseq'][0].split()[0]
self.send_message('ACK', call_id=self.call_id, cseq=cseq)
+
+ def reinvite(self, medias=[('audio',None)]):
+ body = self.get_call_sdp(medias)
+ return self.send_message('INVITE', body, content_type='application/sdp',
+ supported='timer, 100rel', call_id=self.call_id)
def incoming_call(self, medias=[('audio',None)]):
self.call_id = uuid.uuid4().hex