diff options
author | Olivier CrĂȘte <olivier.crete@collabora.com> | 2012-02-14 16:08:19 -0500 |
---|---|---|
committer | Olivier CrĂȘte <olivier.crete@collabora.com> | 2012-02-14 16:47:11 -0500 |
commit | 10cddfb8a7fc6780d2ae0d26550eebda4f632455 (patch) | |
tree | 0ebe7b898478fd97d69929f649383899d61783f6 | |
parent | 40769c349d7cdc94d71b1d65e5e6dbf62baa8966 (diff) |
Make SetSending work, also add tests for it
-rw-r--r-- | rakia/call-stream.c | 44 | ||||
-rw-r--r-- | rakia/sip-media.c | 7 | ||||
-rw-r--r-- | rakia/sip-session.c | 12 | ||||
-rw-r--r-- | tests/twisted/Makefile.am | 1 | ||||
-rw-r--r-- | tests/twisted/voip/calltest.py | 2 | ||||
-rw-r--r-- | tests/twisted/voip/direction-change.py | 138 | ||||
-rw-r--r-- | tests/twisted/voip/voip_test.py | 14 |
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 |