summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorOlivier CrĂȘte <olivier.crete@collabora.com>2012-01-31 14:36:12 +0000
committerOlivier CrĂȘte <olivier.crete@collabora.com>2012-02-10 13:34:39 +0100
commit6dc51e5bbe1c9a2a46e489967a94d366b35fe65e (patch)
tree0d34033c724551a3a9f23500ddba7a344cc121bd /tests
parentac815e6d8072d1cb2cf5e27ea8516d125809e473 (diff)
Port to Call1
Diffstat (limited to 'tests')
-rw-r--r--tests/twisted/Makefile.am1
-rw-r--r--tests/twisted/constants.py88
-rw-r--r--tests/twisted/sofiatest.py2
-rw-r--r--tests/twisted/voip/dtmf.py160
-rw-r--r--tests/twisted/voip/incoming-basics.py279
-rw-r--r--tests/twisted/voip/outgoing-basics.py359
-rw-r--r--tests/twisted/voip/voip_test.py124
7 files changed, 444 insertions, 569 deletions
diff --git a/tests/twisted/Makefile.am b/tests/twisted/Makefile.am
index 74645c2..816c77d 100644
--- a/tests/twisted/Makefile.am
+++ b/tests/twisted/Makefile.am
@@ -12,7 +12,6 @@ TWISTED_TESTS = \
text/initiate-requestotron.py \
voip/incoming-basics.py \
voip/outgoing-basics.py \
- voip/dtmf.py \
$(NULL)
TESTS =
diff --git a/tests/twisted/constants.py b/tests/twisted/constants.py
index c590b3d..e13197a 100644
--- a/tests/twisted/constants.py
+++ b/tests/twisted/constants.py
@@ -27,14 +27,13 @@ CHANNEL_IFACE_TUBE = CHANNEL + ".Interface.Tube"
CHANNEL_IFACE_SASL_AUTH = CHANNEL + ".Interface.SaslAuthentication.DRAFT"
CHANNEL_IFACE_CONFERENCE = CHANNEL + '.Interface.Conference'
-CHANNEL_TYPE_CALL = CHANNEL + ".Type.Call.DRAFT"
+CHANNEL_TYPE_CALL = CHANNEL + ".Type.Call1"
CHANNEL_TYPE_CONTACT_LIST = CHANNEL + ".Type.ContactList"
CHANNEL_TYPE_CONTACT_SEARCH = CHANNEL + ".Type.ContactSearch"
CHANNEL_TYPE_TEXT = CHANNEL + ".Type.Text"
CHANNEL_TYPE_TUBES = CHANNEL + ".Type.Tubes"
CHANNEL_TYPE_STREAM_TUBE = CHANNEL + ".Type.StreamTube"
CHANNEL_TYPE_DBUS_TUBE = CHANNEL + ".Type.DBusTube"
-CHANNEL_TYPE_STREAMED_MEDIA = CHANNEL + ".Type.StreamedMedia"
CHANNEL_TYPE_TEXT = CHANNEL + ".Type.Text"
CHANNEL_TYPE_FILE_TRANSFER = CHANNEL + ".Type.FileTransfer"
CHANNEL_TYPE_SERVER_AUTHENTICATION = \
@@ -56,35 +55,46 @@ INITIATOR_HANDLE = CHANNEL + '.InitiatorHandle'
INITIATOR_ID = CHANNEL + '.InitiatorID'
INTERFACES = CHANNEL + '.Interfaces'
-INITIAL_AUDIO = CHANNEL_TYPE_STREAMED_MEDIA + '.InitialAudio'
-INITIAL_VIDEO = CHANNEL_TYPE_STREAMED_MEDIA + '.InitialVideo'
-IMMUTABLE_STREAMS = CHANNEL_TYPE_STREAMED_MEDIA + '.ImmutableStreams'
-
-CALL_INITIAL_AUDIO = CHANNEL_TYPE_CALL + '.InitialAudio'
-CALL_INITIAL_VIDEO = CHANNEL_TYPE_CALL + '.InitialVideo'
-CALL_MUTABLE_CONTENTS = CHANNEL_TYPE_CALL + '.MutableContents'
+INITIAL_AUDIO = CHANNEL_TYPE_CALL + '.InitialAudio'
+INITIAL_VIDEO = CHANNEL_TYPE_CALL + '.InitialVideo'
+INITIAL_AUDIO_NAME = CHANNEL_TYPE_CALL + '.InitialAudioName'
+INITIAL_VIDEO_NAME = CHANNEL_TYPE_CALL + '.InitialVideoName'
+INITIAL_TRANSPORT = CHANNEL_TYPE_CALL + '.InitialTransport'
+MUTABLE_CONTENTS = CHANNEL_TYPE_CALL + '.MutableContents'
DTMF_INITIAL_TONES = CHANNEL_IFACE_DTMF + '.InitialTones'
-CALL_CONTENT = 'org.freedesktop.Telepathy.Call.Content.DRAFT'
+CALL_CONTENT = 'org.freedesktop.Telepathy.Call1.Content'
CALL_CONTENT_IFACE_MEDIA = \
- 'org.freedesktop.Telepathy.Call.Content.Interface.Media.DRAFT'
+ 'org.freedesktop.Telepathy.Call1.Content.Interface.Media'
-CALL_CONTENT_CODECOFFER = \
- 'org.freedesktop.Telepathy.Call.Content.CodecOffer.DRAFT'
+CALL_CONTENT_MEDIA_DESCRIPTION = \
+ 'org.freedesktop.Telepathy.Call1.Content.MediaDescription'
-CALL_STREAM = 'org.freedesktop.Telepathy.Call.Stream.DRAFT'
+CALL_STREAM = 'org.freedesktop.Telepathy.Call1.Stream'
CALL_STREAM_IFACE_MEDIA = \
- 'org.freedesktop.Telepathy.Call.Stream.Interface.Media.DRAFT'
+ 'org.freedesktop.Telepathy.Call1.Stream.Interface.Media'
+
+CALL_STREAM_ENDPOINT = 'org.freedesktop.Telepathy.Call1.Stream.Endpoint'
-CALL_STREAM_ENDPOINT = 'org.freedesktop.Telepathy.Call.Stream.Endpoint.DRAFT'
+
+CALL_STREAM_ENDPOINT_STATE_CONNECTING = 0
+CALL_STREAM_ENDPOINT_STATE_PROVISIONALLY_CONNECTED = 1
+CALL_STREAM_ENDPOINT_STATE_FULLY_CONNECTED = 2
+CALL_STREAM_ENDPOINT_STATE_EXHAUSTED_CANDIDATES = 3
+CALL_STREAM_ENDPOINT_STATE_FAILED = 4
CALL_MEDIA_TYPE_AUDIO = 0
CALL_MEDIA_TYPE_VIDEO = 1
-CALL_STREAM_TRANSPORT_RAW_UDP = 0
-CALL_STREAM_TRANSPORT_ICE = 1
-CALL_STREAM_TRANSPORT_GOOGLE = 2
+
+MEDIA_STREAM_BASE_PROTO_UDP = 0
+MEDIA_STREAM_BASE_PROTO_TCP = 1
+
+CALL_STREAM_TRANSPORT_UNKNOWN = 0
+CALL_STREAM_TRANSPORT_RAW_UDP = 1
+CALL_STREAM_TRANSPORT_ICE = 2
+
CALL_STATE_UNKNOWN = 0
CALL_STATE_PENDING_INITIATOR = 1
@@ -96,12 +106,17 @@ CALL_MEMBER_FLAG_RINGING = 1
CALL_MEMBER_FLAG_HELD = 2
CALL_DISPOSITION_NONE = 0
-CALL_DISPOSITION_EARLY_MEDIA = 1
-CALL_DISPOSITION_INITIAL = 2
+CALL_DISPOSITION_INITIAL = 1
CALL_SENDING_STATE_NONE = 0
CALL_SENDING_STATE_PENDING_SEND = 1
CALL_SENDING_STATE_SENDING = 2
+CALL_SENDING_STATE_PENDING_STOP_SENDING = 3
+
+CALL_STREAM_FLOW_STATE_STOPPED = 0
+CALL_STREAM_FLOW_STATE_PENDING_START = 1
+CALL_STREAM_FLOW_STATE_PENDING_STOP = 2
+CALL_STREAM_FLOW_STATE_STARTED = 3
SUBSCRIPTION_STATE_UNKNOWN = 0
SUBSCRIPTION_STATE_NO = 1
@@ -293,10 +308,24 @@ HSR_NONE = 0
HSR_REQUESTED = 1
HSR_RESOURCE_NOT_AVAILABLE = 2
-CALL_STATE_RINGING = 1
-CALL_STATE_QUEUED = 2
-CALL_STATE_HELD = 4
-CALL_STATE_FORWARDED = 8
+CALL_STATE_UNKNOWN = 0,
+CALL_STATE_PENDING_INITIATOR = 1
+CALL_STATE_INITIALISING = 2
+CALL_STATE_INITIALISED = 3
+CALL_STATE_ACCEPTED = 4
+CALL_STATE_ACTIVE = 5
+CALL_STATE_ENDED = 6
+
+
+CALL_MEMBER_FLAG_RINGING = 1
+CALL_MEMBER_FLAG_HELD = 2
+
+CALL_FLAG_LOCALLY_HELD = 1
+CALL_FLAG_LOCALLY_MUTED = 2
+CALL_FLAG_LOCALLY_RINGING = 4
+CALL_FLAG_LOCALLY_QUEUED = 8
+CALL_FLAG_FORWARDED = 16
+CALL_FLAG_CLEARING = 32
CONN_STATUS_CONNECTED = 0
CONN_STATUS_CONNECTING = 1
@@ -401,3 +430,12 @@ TLS_CERT_STATE_REJECTED = 2
TLS_REJECT_REASON_UNKNOWN = 0
TLS_REJECT_REASON_UNTRUSTED = 1
+
+
+CALL_CONTENT_PACKETIZATION_RTP = 0
+CALL_CONTENT_PACKETIZATION_RAW = 1
+CALL_CONTENT_PACKETIZATION_MSN_WEBCAM = 2
+
+CALL_SCR_UNKNOWN = 0
+CALL_SCR_PROGRESS_MADE = 1
+CALL_SCR_USER_REQUESTED = 2
diff --git a/tests/twisted/sofiatest.py b/tests/twisted/sofiatest.py
index 38276d2..ad85947 100644
--- a/tests/twisted/sofiatest.py
+++ b/tests/twisted/sofiatest.py
@@ -32,7 +32,7 @@ class SipProxy(sip.RegisterProxy):
def handle_request(self, message, addr):
if message.method == 'REGISTER':
- return sip.RegisterProxy.handle_request(self, message, addr)
+ return sip.RegisterProxy.handle_REGISTER_request(self, message, addr)
elif message.method == 'OPTIONS' and \
'REGISTRATION PROBE' == message.headers.get('subject','')[0]:
self.deliverResponse(self.responseFromRequest(200, message))
diff --git a/tests/twisted/voip/dtmf.py b/tests/twisted/voip/dtmf.py
deleted file mode 100644
index 4369bc3..0000000
--- a/tests/twisted/voip/dtmf.py
+++ /dev/null
@@ -1,160 +0,0 @@
-"""
-Test DTMF dialstring playback and signalling.
-"""
-
-from sofiatest import exec_test
-from servicetest import (
- call_async, wrap_channel, EventPattern,
- assertEquals, assertContains, assertLength, assertSameSets
- )
-from voip_test import VoipTestContext
-import constants as cs
-
-def setup_dtmf_channel(context, initial_tones=None):
- q = context.q
- bus = context.bus
- conn = context.conn
-
- conn.Connect()
- q.expect('dbus-signal', signal='StatusChanged', args=[0, 1])
-
- request_params = {
- cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAMED_MEDIA,
- cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT,
- cs.TARGET_ID: context.peer,
- cs.INITIAL_AUDIO: True,
- }
- if initial_tones:
- request_params[cs.DTMF_INITIAL_TONES] = initial_tones
-
- path = conn.Requests.CreateChannel(request_params)[0]
-
- chan = wrap_channel(bus.get_object(conn.bus_name, path), 'StreamedMedia',
- ['MediaSignalling', 'DTMF'])
-
- channel_props = chan.Properties.GetAll(cs.CHANNEL)
-
- assertContains(cs.CHANNEL_IFACE_DTMF, channel_props['Interfaces'])
-
- dtmf_props = chan.Properties.GetAll(cs.CHANNEL_IFACE_DTMF)
-
- if initial_tones:
- assertEquals(initial_tones, dtmf_props['InitialTones'])
- else:
- assertEquals('', dtmf_props['InitialTones'])
- assertEquals(False, dtmf_props['CurrentlySendingTones'])
-
- stream_handler = context.handle_audio_session(chan)
-
- invite_event = q.expect('sip-invite')
-
- context.accept(invite_event.sip_message)
-
- q.expect('dbus-signal', signal='SetRemoteCodecs')
-
- stream_handler.SupportedCodecs(context.get_audio_codecs_dbus())
- stream_handler.StreamState(cs.MEDIA_STREAM_STATE_CONNECTED)
-
- return chan
-
-def request_initial_tones(q, bus, conn, sip_proxy, peer='foo@bar.com'):
- context = VoipTestContext(q, conn, bus, sip_proxy, 'sip:testacc@127.0.0.1', peer)
-
- tones = '123'
-
- chan = setup_dtmf_channel(context, tones)
-
- q.expect_many(
- EventPattern('dbus-signal', signal='SendingTones', args=[tones]),
- EventPattern('dbus-signal', signal='StartTelephonyEvent', args=[int(tones[0])]))
-
- assertEquals(True, chan.Properties.Get(cs.CHANNEL_IFACE_DTMF, 'CurrentlySendingTones'))
-
- q.expect('dbus-signal', signal='StopTelephonyEvent')
-
- for i in range(1, len(tones) - 1):
- q.expect('dbus-signal', signal='StartTelephonyEvent', args=[int(tones[i])])
- q.expect('dbus-signal', signal='StopTelephonyEvent')
-
- q.expect('dbus-signal', signal='StoppedTones', args=[False])
-
- assertEquals(False, chan.Properties.Get(cs.CHANNEL_IFACE_DTMF, 'CurrentlySendingTones'))
-
-def multiple_tones(q, bus, conn, sip_proxy, peer='foo@bar.com'):
-
- context = VoipTestContext(q, conn, bus, sip_proxy, 'sip:testacc@127.0.0.1', peer)
-
- chan = setup_dtmf_channel(context)
-
- tones_deferred = '78'
- tones = '56w' + tones_deferred
-
- chan.DTMF.MultipleTones(tones)
-
- q.expect_many(
- EventPattern('dbus-signal', signal='SendingTones', args=[tones]),
- EventPattern('dbus-signal', signal='StartTelephonyEvent', args=[int(tones[0])]))
-
- dtmf_props = chan.Properties.GetAll(cs.CHANNEL_IFACE_DTMF)
- assertEquals(True, dtmf_props['CurrentlySendingTones'])
- assertEquals('', dtmf_props['DeferredTones'])
-
- q.expect('dbus-signal', signal='StopTelephonyEvent')
-
- q.expect('dbus-signal', signal='StartTelephonyEvent', args=[int(tones[1])])
- q.expect('dbus-signal', signal='StopTelephonyEvent')
-
- q.expect('dbus-signal', signal='TonesDeferred', args=[tones_deferred])
-
- dtmf_props = chan.Properties.GetAll(cs.CHANNEL_IFACE_DTMF)
-
- assertEquals(False, dtmf_props['CurrentlySendingTones'])
- assertEquals(tones_deferred, dtmf_props['DeferredTones'])
-
- chan.DTMF.MultipleTones(tones_deferred)
-
- q.expect_many(
- EventPattern('dbus-signal', signal='SendingTones', args=[tones_deferred]),
- EventPattern('dbus-signal', signal='StartTelephonyEvent', args=[int(tones_deferred[0])]))
-
- dtmf_props = chan.Properties.GetAll(cs.CHANNEL_IFACE_DTMF)
-
- assertEquals(True, dtmf_props['CurrentlySendingTones'])
- assertEquals('', dtmf_props['DeferredTones'])
-
- q.expect('dbus-signal', signal='StopTelephonyEvent')
-
- for i in range(1, len(tones_deferred) - 1):
- q.expect('dbus-signal', signal='StartTelephonyEvent', args=[int(tones_deferred[i])])
- q.expect('dbus-signal', signal='StopTelephonyEvent')
-
- q.expect('dbus-signal', signal='StoppedTones', args=[False])
-
-def bleep_bloop(q, bus, conn, sip_proxy, peer='foo@bar.com'):
-
- context = VoipTestContext(q, conn, bus, sip_proxy, 'sip:testacc@127.0.0.1', peer)
-
- chan = setup_dtmf_channel(context)
-
- call_async(q, chan.DTMF, 'StartTone', 666, 3)
- q.expect_many(
- EventPattern('dbus-signal', signal='StartTelephonyEvent'),
- EventPattern('dbus-signal', signal='SendingTones', args=['3']),
- EventPattern('dbus-return', method='StartTone'),
- )
-
- assertEquals(True, chan.Properties.Get(cs.CHANNEL_IFACE_DTMF, 'CurrentlySendingTones'))
-
- call_async(q, chan.DTMF, 'StopTone', 666)
- q.expect_many(
- EventPattern('dbus-signal', signal='StopTelephonyEvent'),
- EventPattern('dbus-signal', signal='StoppedTones', args=[True]),
- EventPattern('dbus-return', method='StopTone'),
- )
-
- assertEquals(False, chan.Properties.Get(cs.CHANNEL_IFACE_DTMF, 'CurrentlySendingTones'))
-
-if __name__ == '__main__':
- exec_test(request_initial_tones)
- exec_test(multiple_tones)
- exec_test(bleep_bloop)
diff --git a/tests/twisted/voip/incoming-basics.py b/tests/twisted/voip/incoming-basics.py
index 9ab3949..2a7890d 100644
--- a/tests/twisted/voip/incoming-basics.py
+++ b/tests/twisted/voip/incoming-basics.py
@@ -7,8 +7,8 @@ import dbus
from sofiatest import exec_test
from servicetest import (
make_channel_proxy, wrap_channel,
- EventPattern, call_async,
- assertEquals, assertContains, assertLength,
+ EventPattern, call_async, ProxyWrapper,
+ assertEquals, assertNotEquals, assertContains, assertLength,
)
import constants as cs
from voip_test import VoipTestContext
@@ -25,139 +25,178 @@ def test(q, bus, conn, sip_proxy, peer='foo@bar.com'):
# Try making a call to ourself. StreamedMedia should refuse this because
# the API doesn't support it.
context.incoming_call_from_self()
- q.expect('sip-response', code=501)
-
+ acc = q.expect('sip-response', code=501)
+
# Remote end calls us
context.incoming_call()
- nc, e = q.expect_many(
- EventPattern('dbus-signal', signal='NewChannels'),
- EventPattern('dbus-signal', signal='NewSessionHandler'),
- )[0:2]
+ nc = q.expect('dbus-signal', signal='NewChannels')
path, props = nc.args[0][0]
- ct = props[cs.CHANNEL_TYPE]
- ht = props[cs.CHANNEL + '.TargetHandleType']
- h = props[cs.CHANNEL + '.TargetHandle']
-
- assert ct == cs.CHANNEL_TYPE_STREAMED_MEDIA, ct
- assert ht == cs.HT_CONTACT, ht
- assert h == remote_handle, h
-
- media_chan = make_channel_proxy(conn, path, 'Channel.Interface.Group')
- media_iface = make_channel_proxy(conn, path, 'Channel.Type.StreamedMedia')
-
- # S-E was notified about new session handler, and calls Ready on it
- assert e.args[1] == 'rtp'
- session_handler = make_channel_proxy(conn, e.args[0], 'Media.SessionHandler')
- session_handler.Ready()
-
- nsh_event = q.expect('dbus-signal', signal='NewStreamHandler')
-
- # S-E gets notified about a newly-created stream
- stream_handler = make_channel_proxy(conn, nsh_event.args[0],
- 'Media.StreamHandler')
-
- streams = media_iface.ListStreams()
- assertLength(1, streams)
-
- stream_id, stream_handle, stream_type, _, stream_direction, pending_flags =\
- streams[0]
- assertEquals(remote_handle, stream_handle)
- assertEquals(cs.MEDIA_STREAM_TYPE_AUDIO, stream_type)
- assertEquals(cs.MEDIA_STREAM_DIRECTION_RECEIVE, stream_direction)
- assertEquals(cs.MEDIA_STREAM_PENDING_LOCAL_SEND, pending_flags)
-
- # Exercise channel properties
- channel_props = media_chan.GetAll(
- cs.CHANNEL, dbus_interface=dbus.PROPERTIES_IFACE)
- assertEquals(remote_handle, channel_props['TargetHandle'])
- assertEquals(cs.HT_CONTACT, channel_props['TargetHandleType'])
- assertEquals((cs.HT_CONTACT, remote_handle),
- media_chan.GetHandle(dbus_interface=cs.CHANNEL))
- assertEquals(context.peer_id, channel_props['TargetID'])
- assertEquals(context.peer_id, channel_props['InitiatorID'])
- assertEquals(remote_handle, channel_props['InitiatorHandle'])
- assertEquals(False, channel_props['Requested'])
-
- group_props = media_chan.GetAll(
- cs.CHANNEL_IFACE_GROUP, dbus_interface=dbus.PROPERTIES_IFACE)
-
- assert group_props['SelfHandle'] == self_handle, \
- (group_props['SelfHandle'], self_handle)
-
- flags = group_props['GroupFlags']
- assert flags & cs.GF_PROPERTIES, flags
- # Changing members in any way other than adding or removing yourself is
- # meaningless for incoming calls, and the flags need not be sent to change
- # your own membership.
- assert not flags & cs.GF_CAN_ADD, flags
- assert not flags & cs.GF_CAN_REMOVE, flags
- assert not flags & cs.GF_CAN_RESCIND, flags
-
- assert group_props['Members'] == [remote_handle], group_props['Members']
- assert group_props['RemotePendingMembers'] == [], \
- group_props['RemotePendingMembers']
- # We're local pending because remote_handle invited us.
- assert group_props['LocalPendingMembers'] == \
- [(self_handle, remote_handle, cs.GC_REASON_INVITED, '')], \
- unwrap(group_props['LocalPendingMembers'])
-
- streams = media_chan.ListStreams(
- dbus_interface=cs.CHANNEL_TYPE_STREAMED_MEDIA)
- assert len(streams) == 1, streams
- assert len(streams[0]) == 6, streams[0]
- # streams[0][0] is the stream identifier, which in principle we can't
- # make any assertion about (although in practice it's probably 1)
- assert streams[0][1] == remote_handle, (streams[0], remote_handle)
- assert streams[0][2] == cs.MEDIA_STREAM_TYPE_AUDIO, streams[0]
- # We haven't connected yet
- assert streams[0][3] == cs.MEDIA_STREAM_STATE_DISCONNECTED, streams[0]
- # In Gabble, incoming streams start off with remote send enabled, and
- # local send requested
- assert streams[0][4] == cs.MEDIA_STREAM_DIRECTION_RECEIVE, streams[0]
- assert streams[0][5] == cs.MEDIA_STREAM_PENDING_LOCAL_SEND, streams[0]
-
- # Connectivity checks happen before we have accepted the call
- stream_handler.NewNativeCandidate("fake", context.get_remote_transports_dbus())
- stream_handler.NativeCandidatesPrepared()
- stream_handler.Ready(context.get_audio_codecs_dbus())
- stream_handler.StreamState(cs.MEDIA_STREAM_STATE_CONNECTED)
- stream_handler.SupportedCodecs(context.get_audio_codecs_dbus())
-
- # At last, accept the call
- media_chan.AddMembers([self_handle], 'accepted')
-
- # Call is accepted, we become a member, and the stream that was pending
- # local send is now sending.
- memb, acc, _, _, _ = q.expect_many(
- EventPattern('dbus-signal', signal='MembersChanged',
- args=[u'', [self_handle], [], [], [], self_handle,
- cs.GC_REASON_NONE]),
- EventPattern('sip-response', call_id=context.call_id, code=200),
- EventPattern('dbus-signal', signal='SetStreamSending', args=[True]),
- EventPattern('dbus-signal', signal='SetStreamPlaying', args=[True]),
- EventPattern('dbus-signal', signal='StreamDirectionChanged',
- args=[stream_id, cs.MEDIA_STREAM_DIRECTION_BIDIRECTIONAL, 0]),
- )
+ assertEquals(cs.CHANNEL_TYPE_CALL, props[cs.CHANNEL_TYPE])
+ assertEquals(cs.HT_CONTACT, props[cs.CHANNEL + '.TargetHandleType'])
+ assertEquals(remote_handle, props[cs.CHANNEL + '.TargetHandle'])
+ assertEquals(remote_handle, props[cs.CHANNEL + '.InitiatorHandle'])
+ assertEquals(True, props[cs.CHANNEL_TYPE_CALL + '.InitialAudio'])
+ assertEquals(True, props[cs.CHANNEL_TYPE_CALL + '.MutableContents'])
+ assertEquals(False, props[cs.CHANNEL_TYPE_CALL + '.HardwareStreaming'])
+
+ chan = wrap_channel(bus.get_object(conn.bus_name, path), 'Call1')
+
+ call_props = chan.Properties.GetAll(cs.CHANNEL_TYPE_CALL)
+ assertEquals(cs.CALL_STATE_INITIALISING, call_props['CallState'])
+ assertEquals(0, call_props['CallFlags'])
+ assertEquals(False, call_props['HardwareStreaming'])
+ assertEquals(True, call_props['MutableContents'])
+ assertEquals(True, call_props['InitialAudio'])
+ assertEquals("initial_audio_1", call_props['InitialAudioName'])
+ assertEquals(False, call_props['InitialVideo'])
+ assertEquals("", call_props['InitialVideoName'])
+ assertEquals(cs.CALL_STREAM_TRANSPORT_RAW_UDP,
+ call_props['InitialTransport'])
+ assertEquals({remote_handle: 0}, call_props['CallMembers'])
+
+
+ assertLength(1, call_props['Contents'])
+
+ content = bus.get_object (conn.bus_name, call_props['Contents'][0])
+
+ content_props = content.GetAll(cs.CALL_CONTENT)
+ assertEquals(cs.CALL_DISPOSITION_INITIAL, content_props['Disposition'])
+ assertEquals("initial_audio_1", content_props['Name'])
+ assertLength(1, content_props['Streams'])
+
+ cmedia_props = content.GetAll(cs.CALL_CONTENT_IFACE_MEDIA)
+ assertLength(0, cmedia_props['RemoteMediaDescriptions'])
+ assertLength(0, cmedia_props['LocalMediaDescriptions'])
+ assertNotEquals('/', cmedia_props['MediaDescriptionOffer'][0])
+ assertEquals(cs.CALL_CONTENT_PACKETIZATION_RTP,
+ cmedia_props['Packetization'])
+ assertEquals(cs.CALL_SENDING_STATE_NONE, cmedia_props['CurrentDTMFState'])
- context.check_call_sdp(acc.sip_message.body)
+
+ stream = bus.get_object (conn.bus_name, content_props['Streams'][0])
+
+ stream = ProxyWrapper (stream, 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'])
+
+ 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'])
+ assertEquals(cs.CALL_STREAM_TRANSPORT_RAW_UDP, smedia_props['Transport'])
+ assertEquals([], smedia_props['LocalCandidates'])
+ assertEquals(("",""), smedia_props['LocalCredentials'])
+ assertEquals([], smedia_props['STUNServers'])
+ assertEquals([], smedia_props['RelayInfo'])
+ assertEquals(True, smedia_props['HasServerInfo'])
+ assertEquals([], smedia_props['Endpoints'])
+ assertEquals(False, smedia_props['ICERestartPending'])
+
+ md = bus.get_object (conn.bus_name,
+ cmedia_props['MediaDescriptionOffer'][0])
+ md.Accept(context.get_audio_md_dbus(remote_handle))
+
+ o = q.expect_many(
+ EventPattern('dbus-signal', signal='EndpointsChanged'),
+ EventPattern('dbus-signal', signal='MediaDescriptionOfferDone'),
+ EventPattern('dbus-signal', signal='LocalMediaDescriptionChanged'),
+ EventPattern('dbus-signal', signal='RemoteMediaDescriptionsChanged'))
+
+ assertLength(1, o[0].args[0])
+ assertEquals([], o[0].args[1])
+
+ endpoint = bus.get_object(conn.bus_name, o[0].args[0][0])
+ endpoint_props = endpoint.GetAll(cs.CALL_STREAM_ENDPOINT)
+ assertEquals(('',''), endpoint_props['RemoteCredentials'])
+ assertEquals(context.get_remote_candidates_dbus(),
+ endpoint_props['RemoteCandidates'])
+ assertLength(0, endpoint_props['EndpointState'])
+ assertEquals(cs.CALL_STREAM_TRANSPORT_RAW_UDP,
+ endpoint_props['Transport'])
+ assertEquals(False, endpoint_props['IsICELite'])
+
+ endpoint.SetEndpointState(1,
+ cs.CALL_STREAM_ENDPOINT_STATE_FULLY_CONNECTED,
+ dbus_interface=cs.CALL_STREAM_ENDPOINT)
+ endpoint.SetEndpointState(2,
+ cs.CALL_STREAM_ENDPOINT_STATE_FULLY_CONNECTED,
+ dbus_interface=cs.CALL_STREAM_ENDPOINT)
+
+
+ assertEquals({1: cs.CALL_STREAM_ENDPOINT_STATE_FULLY_CONNECTED,
+ 2: cs.CALL_STREAM_ENDPOINT_STATE_FULLY_CONNECTED},
+ endpoint.Get(cs.CALL_STREAM_ENDPOINT, 'EndpointState'))
+
+ o = q.expect('dbus-signal', signal='CallStateChanged')
+ assertEquals(cs.CALL_STATE_INITIALISED, o.args[0])
+
+ chan.Call1.SetQueued()
+
+ o = q.expect_many(
+ EventPattern('sip-response', call_id=context.call_id, code=182),
+ EventPattern('dbus-signal', signal='CallStateChanged'))
+ assertEquals(cs.CALL_STATE_INITIALISED, o[1].args[0])
+ assertEquals(cs.CALL_FLAG_LOCALLY_QUEUED, o[1].args[1])
+
+ chan.Call1.SetRinging()
+
+ o = q.expect_many(
+ EventPattern('sip-response', call_id=context.call_id, code=180),
+ EventPattern('dbus-signal', signal='CallStateChanged'))
+ assertEquals(cs.CALL_STATE_INITIALISED, o[1].args[0])
+ assertEquals(cs.CALL_FLAG_LOCALLY_RINGING, o[1].args[1])
+
+
+ chan.Call1.Accept()
+
+ o = q.expect_many(
+ EventPattern('dbus-signal', signal='CallStateChanged'),
+ EventPattern('dbus-signal', signal='CallStateChanged'),
+ EventPattern('dbus-signal', signal='ReceivingStateChanged',
+ args=[cs.CALL_STREAM_FLOW_STATE_PENDING_START]),
+ EventPattern('dbus-signal', signal='SendingStateChanged',
+ args=[cs.CALL_STREAM_FLOW_STATE_PENDING_START]))
+ assertEquals(cs.CALL_STATE_ACCEPTED, o[0].args[0])
+ assertEquals(cs.CALL_STATE_ACTIVE, o[1].args[0])
+
+
+ stream.Media.CompleteReceivingStateChange(
+ cs.CALL_STREAM_FLOW_STATE_STARTED)
+ stream.Media.CompleteSendingStateChange(cs.CALL_STREAM_FLOW_STATE_STARTED)
+
+ o = q.expect_many(
+ EventPattern('dbus-signal', signal='ReceivingStateChanged',
+ args=[cs.CALL_STREAM_FLOW_STATE_STARTED]),
+ EventPattern('dbus-signal', signal='SendingStateChanged',
+ args=[cs.CALL_STREAM_FLOW_STATE_STARTED]),
+ EventPattern('dbus-signal', signal='LocalSendingStateChanged'))
+ assertEquals(cs.CALL_SENDING_STATE_SENDING, o[2].args[0])
+
+ stream.Media.AddCandidates(context.get_remote_candidates_dbus())
+ stream.Media.FinishInitialCandidates()
+
+ acc = q.expect('sip-response', call_id=context.call_id, code=200)
+ context.check_call_sdp(acc.sip_message.body)
context.ack(acc.sip_message)
-
- # we are now both in members
- members = media_chan.GetMembers()
- assert set(members) == set([self_handle, remote_handle]), members
+
# Connected! Blah, blah, ...
# 'Nuff said
bye_msg = context.terminate()
- q.expect_many(EventPattern('dbus-signal', signal='Closed', path=path),
- EventPattern('sip-response', cseq=bye_msg.headers['cseq'][0]))
+ o = q.expect_many(
+ EventPattern('dbus-signal', signal='CallStateChanged', path=path),
+ EventPattern('sip-response', cseq=bye_msg.headers['cseq'][0]))
+ assertEquals(cs.CALL_STATE_ENDED, o[0].args[0])
if __name__ == '__main__':
exec_test(test)
exec_test(lambda q, bus, conn, stream:
- test(q, bus, conn, stream, 'foo@sip.bar.com'))
+ test(q, bus, conn, stream, 'foo@sip.bar.com'))
diff --git a/tests/twisted/voip/outgoing-basics.py b/tests/twisted/voip/outgoing-basics.py
index c8e93bc..8d4a161 100644
--- a/tests/twisted/voip/outgoing-basics.py
+++ b/tests/twisted/voip/outgoing-basics.py
@@ -7,36 +7,19 @@ import dbus
from sofiatest import exec_test
from servicetest import (
- wrap_channel, EventPattern, call_async,
- assertEquals, assertContains, assertLength, assertSameSets
+ wrap_channel, EventPattern, call_async, ProxyWrapper,
+ assertEquals, assertContains, assertLength, assertSameSets,
+ assertNotEquals
)
import constants as cs
from voip_test import VoipTestContext
-# There are various deprecated APIs for requesting calls, documented at
-# <http://telepathy.freedesktop.org/wiki/Requesting StreamedMedia channels>.
-# These are ordered from most recent to most deprecated.
CREATE = 0 # CreateChannel({TargetHandleType: Contact, TargetHandle: h});
# RequestStreams()
-REQUEST_ANONYMOUS = 1 # RequestChannel(HandleTypeNone, 0); RequestStreams()
-REQUEST_ANONYMOUS_AND_ADD = 2 # RequestChannel(HandleTypeNone, 0);
- # AddMembers([h], ...); RequestStreams(h,...)
-REQUEST_NONYMOUS = 3 # RequestChannel(HandleTypeContact, h);
- # RequestStreams(h, ...)
def create(q, bus, conn, sip_proxy, peer='foo@bar.com'):
worker(q, bus, conn, sip_proxy, CREATE, peer)
-def request_anonymous(q, bus, conn, sip_proxy, peer='publish@foo.com'):
- worker(q, bus, conn, sip_proxy, REQUEST_ANONYMOUS, peer)
-
-def request_anonymous_and_add(q, bus, conn, sip_proxy,
- peer='publish-subscribe@foo.com/Res'):
- worker(q, bus, conn, sip_proxy, REQUEST_ANONYMOUS_AND_ADD, peer)
-
-def request_nonymous(q, bus, conn, sip_proxy, peer='subscribe@foo.com'):
- worker(q, bus, conn, sip_proxy, REQUEST_NONYMOUS, peer)
-
def worker(q, bus, conn, sip_proxy, variant, peer):
conn.Connect()
q.expect('dbus-signal', signal='StatusChanged', args=[0, 1])
@@ -47,18 +30,13 @@ def worker(q, bus, conn, sip_proxy, variant, peer):
self_handle = conn.GetSelfHandle()
remote_handle = conn.RequestHandles(1, [context.peer])[0]
- if variant == REQUEST_NONYMOUS:
- path = conn.RequestChannel(cs.CHANNEL_TYPE_STREAMED_MEDIA,
- cs.HT_CONTACT, remote_handle, True)
- elif variant == CREATE:
- path = conn.Requests.CreateChannel({
- cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAMED_MEDIA,
+ path = conn.Requests.CreateChannel({
+ cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_CALL,
cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT,
cs.TARGET_HANDLE: remote_handle,
+ cs.INITIAL_AUDIO: True,
+ cs.INITIAL_AUDIO_NAME: "audiocontent",
})[0]
- else:
- path = conn.RequestChannel(cs.CHANNEL_TYPE_STREAMED_MEDIA,
- cs.HT_NONE, 0, True)
old_sig, new_sig = q.expect_many(
EventPattern('dbus-signal', signal='NewChannel',
@@ -68,172 +46,200 @@ def worker(q, bus, conn, sip_proxy, variant, peer):
cs.CHANNEL_TYPE_CONTACT_LIST not in e.args[0][0][1].values()),
)
- if variant == REQUEST_NONYMOUS or variant == CREATE:
- assertEquals( [path, cs.CHANNEL_TYPE_STREAMED_MEDIA, cs.HT_CONTACT,
- remote_handle, True], old_sig.args)
- else:
- assertEquals( [path, cs.CHANNEL_TYPE_STREAMED_MEDIA, cs.HT_NONE, 0,
- True], old_sig.args)
+ assertEquals( [path, cs.CHANNEL_TYPE_CALL, cs.HT_CONTACT,
+ remote_handle, True], old_sig.args)
assertLength(1, new_sig.args)
assertLength(1, new_sig.args[0]) # one channel
assertLength(2, new_sig.args[0][0]) # two struct members
emitted_props = new_sig.args[0][0][1]
- assertEquals(
- cs.CHANNEL_TYPE_STREAMED_MEDIA, emitted_props[cs.CHANNEL_TYPE])
+ assertEquals(cs.CHANNEL_TYPE_CALL, emitted_props[cs.CHANNEL_TYPE])
- if variant == REQUEST_NONYMOUS or variant == CREATE:
- assertEquals(remote_handle, emitted_props[cs.TARGET_HANDLE])
- assertEquals(cs.HT_CONTACT, emitted_props[cs.TARGET_HANDLE_TYPE])
- assertEquals(context.peer_id, emitted_props[cs.TARGET_ID])
- else:
- assertEquals(0, emitted_props[cs.TARGET_HANDLE])
- assertEquals(cs.HT_NONE, emitted_props[cs.TARGET_HANDLE_TYPE])
- assertEquals('', emitted_props[cs.TARGET_ID])
+ assertEquals(remote_handle, emitted_props[cs.TARGET_HANDLE])
+ assertEquals(cs.HT_CONTACT, emitted_props[cs.TARGET_HANDLE_TYPE])
+ assertEquals(context.peer_id, emitted_props[cs.TARGET_ID])
assertEquals(True, emitted_props[cs.REQUESTED])
assertEquals(self_handle, emitted_props[cs.INITIATOR_HANDLE])
assertEquals('sip:testacc@127.0.0.1', emitted_props[cs.INITIATOR_ID])
- chan = wrap_channel(bus.get_object(conn.bus_name, path), 'StreamedMedia',
- ['MediaSignalling'])
+ chan = wrap_channel(bus.get_object(conn.bus_name, path), 'Call1')
# Exercise basic Channel Properties
channel_props = chan.Properties.GetAll(cs.CHANNEL)
- assertEquals(cs.CHANNEL_TYPE_STREAMED_MEDIA,
+ assertEquals(cs.CHANNEL_TYPE_CALL,
channel_props.get('ChannelType'))
- if variant == REQUEST_NONYMOUS or variant == CREATE:
- assertEquals(remote_handle, channel_props['TargetHandle'])
- assertEquals(cs.HT_CONTACT, channel_props['TargetHandleType'])
- assertEquals(context.peer_id, channel_props['TargetID'])
- assertEquals((cs.HT_CONTACT, remote_handle), chan.GetHandle())
- else:
- assertEquals(0, channel_props['TargetHandle'])
- assertEquals(cs.HT_NONE, channel_props['TargetHandleType'])
- assertEquals('', channel_props['TargetID'])
- assertEquals((cs.HT_NONE, 0), chan.GetHandle())
-
- for interface in [
- cs.CHANNEL_IFACE_GROUP, cs.CHANNEL_IFACE_MEDIA_SIGNALLING,
- cs.TP_AWKWARD_PROPERTIES, cs.CHANNEL_IFACE_HOLD]:
+ assertEquals(remote_handle, channel_props['TargetHandle'])
+ assertEquals(cs.HT_CONTACT, channel_props['TargetHandleType'])
+ assertEquals(context.peer_id, channel_props['TargetID'])
+ assertEquals((cs.HT_CONTACT, remote_handle), chan.GetHandle())
+
+
+ for interface in [cs.CHANNEL_IFACE_HOLD, cs.CHANNEL_IFACE_DTMF]:
assertContains(interface, channel_props['Interfaces'])
assertEquals(True, channel_props['Requested'])
assertEquals('sip:testacc@127.0.0.1', channel_props['InitiatorID'])
assertEquals(conn.GetSelfHandle(), channel_props['InitiatorHandle'])
- # Exercise Group Properties
- group_props = chan.Properties.GetAll(cs.CHANNEL_IFACE_GROUP)
-
- assertEquals([self_handle], group_props['Members'])
- assertEquals([], group_props['LocalPendingMembers'])
-
- if variant == REQUEST_NONYMOUS:
- # In this variant, they're meant to be in RP even though we've sent
- # nothing
- assertEquals([remote_handle], group_props['RemotePendingMembers'])
- else:
- # For an anonymous channel, the peer isn't yet known; for a Create-d
- # channel, the peer only appears in RP when we actually send them the
- # session-initiate
- assertEquals([], group_props['RemotePendingMembers'])
-
- if variant == REQUEST_ANONYMOUS_AND_ADD:
- # but we should be allowed to add the peer.
- chan.Group.AddMembers([remote_handle], 'I love backwards compat')
-
- base_flags = cs.GF_PROPERTIES | cs.GF_CAN_REMOVE | cs.GF_CAN_RESCIND | cs.GF_MEMBERS_CHANGED_DETAILED
-
- if variant in [REQUEST_ANONYMOUS_AND_ADD, REQUEST_ANONYMOUS, CREATE]:
- expected_flags = base_flags | cs.GF_CAN_ADD
- else:
- expected_flags = base_flags
-
- assertEquals(bin(expected_flags), bin(group_props['GroupFlags']))
- assertEquals({}, group_props['HandleOwners'])
-
- assertEquals([], chan.StreamedMedia.ListStreams())
- streams = chan.StreamedMedia.RequestStreams(remote_handle,
- [cs.MEDIA_STREAM_TYPE_AUDIO])
- assertEquals(streams, chan.StreamedMedia.ListStreams())
- assertLength(1, streams)
-
- # streams[0][0] is the stream identifier, which in principle we can't
- # make any assertion about (although in practice it's probably 1)
-
- assertEquals((
- remote_handle,
- cs.MEDIA_STREAM_TYPE_AUDIO,
- # We haven't connected yet
- cs.MEDIA_STREAM_STATE_DISCONNECTED,
- # In Gabble, requested streams start off bidirectional
- cs.MEDIA_STREAM_DIRECTION_BIDIRECTIONAL,
- cs.MEDIA_STREAM_PENDING_REMOTE_SEND),
- streams[0][1:])
-
- stream_handler = context.handle_audio_session(chan)
-
- sh_props = stream_handler.GetAll(
- cs.STREAM_HANDLER, dbus_interface=dbus.PROPERTIES_IFACE)
- assertEquals('none', sh_props['NATTraversal'])
- assertEquals(True, sh_props['CreatedLocally'])
-
- if variant == CREATE:
- # When we actually send INVITE to the peer, they should pop up in remote
- # pending.
- invite_event, _ = q.expect_many(
- EventPattern('sip-invite'),
- EventPattern('dbus-signal', signal='MembersChanged',
- args=["", [], [], [], [remote_handle], self_handle,
- cs.GC_REASON_INVITED]),
- )
- else:
- invite_event = q.expect('sip-invite')
-
- # Check the Group interface's properties again. Regardless of the call
- # requesting API in use, the state should be the same here:
- group_props = chan.Properties.GetAll(cs.CHANNEL_IFACE_GROUP)
- assertContains('HandleOwners', group_props)
- assertEquals([self_handle], group_props['Members'])
- assertEquals([], group_props['LocalPendingMembers'])
- assertEquals([remote_handle], group_props['RemotePendingMembers'])
+ call_props = chan.Properties.GetAll(cs.CHANNEL_TYPE_CALL)
+ assertEquals(cs.CALL_STATE_PENDING_INITIATOR, call_props['CallState'])
+ assertEquals(0, call_props['CallFlags'])
+ assertEquals(False, call_props['HardwareStreaming'])
+ assertEquals(True, call_props['MutableContents'])
+ assertEquals(True, call_props['InitialAudio'])
+ assertEquals("audiocontent", call_props['InitialAudioName'])
+ assertEquals(False, call_props['InitialVideo'])
+ assertEquals("", call_props['InitialVideoName'])
+ assertEquals(cs.CALL_STREAM_TRANSPORT_RAW_UDP,
+ call_props['InitialTransport'])
+ assertEquals({remote_handle: 0}, call_props['CallMembers'])
+
+ assertLength(1, call_props['Contents'])
+
+ content = bus.get_object (conn.bus_name, call_props['Contents'][0])
+
+ content_props = content.GetAll(cs.CALL_CONTENT)
+ assertEquals(cs.CALL_DISPOSITION_INITIAL, content_props['Disposition'])
+ assertEquals("audiocontent", content_props['Name'])
+ assertLength(1, content_props['Streams'])
+
+ cmedia_props = content.GetAll(cs.CALL_CONTENT_IFACE_MEDIA)
+ assertLength(0, cmedia_props['RemoteMediaDescriptions'])
+ assertLength(0, cmedia_props['LocalMediaDescriptions'])
+ assertNotEquals('/', cmedia_props['MediaDescriptionOffer'][0])
+ assertEquals(cs.CALL_CONTENT_PACKETIZATION_RTP,
+ cmedia_props['Packetization'])
+ assertEquals(cs.CALL_SENDING_STATE_NONE, cmedia_props['CurrentDTMFState'])
+
+
+ stream = bus.get_object (conn.bus_name, content_props['Streams'][0])
+
+ stream = ProxyWrapper (stream, 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'])
+
+ 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'])
+ assertEquals(cs.CALL_STREAM_TRANSPORT_RAW_UDP, smedia_props['Transport'])
+ assertEquals([], smedia_props['LocalCandidates'])
+ assertEquals(("",""), smedia_props['LocalCredentials'])
+ assertEquals([], smedia_props['STUNServers'])
+ assertEquals([], smedia_props['RelayInfo'])
+ assertEquals(True, smedia_props['HasServerInfo'])
+ assertEquals([], smedia_props['Endpoints'])
+ assertEquals(False, smedia_props['ICERestartPending'])
+
+ chan.Call1.Accept()
+
+ q.expect ('dbus-signal', signal='ReceivingStateChanged',
+ args=[cs.CALL_STREAM_FLOW_STATE_PENDING_START])
+
+ stream.Media.CompleteReceivingStateChange(cs.CALL_STREAM_FLOW_STATE_STARTED)
+
+ md = bus.get_object (conn.bus_name, cmedia_props['MediaDescriptionOffer'][0])
+ md.Accept(context.get_audio_md_dbus(remote_handle))
+ q.expect_many(
+ EventPattern('dbus-signal', signal='MediaDescriptionOfferDone'),
+ EventPattern('dbus-signal', signal='LocalMediaDescriptionChanged'),
+ EventPattern('dbus-signal', signal='RemoteMediaDescriptionsChanged'))
+
+ mdo = content.Get(cs.CALL_CONTENT_IFACE_MEDIA, 'MediaDescriptionOffer')
+ assertEquals(('/', {}), mdo)
+
+
+ stream.Media.AddCandidates(context.get_remote_candidates_dbus())
+ stream.Media.FinishInitialCandidates()
+
+ q.expect('dbus-signal', signal='LocalCandidatesAdded')
+
+ invite_event = q.expect('sip-invite')
+
+
+ # Send Ringing
+ context.pr_respond(invite_event, 180)
+ o = q.expect('dbus-signal', signal='CallMembersChanged')
+ assertEquals(cs.CALL_MEMBER_FLAG_RINGING, o.args[0][remote_handle])
context.check_call_sdp(invite_event.sip_message.body)
context.accept(invite_event.sip_message)
ack_cseq = "%s ACK" % invite_event.cseq.split()[0]
- q.expect_many(
+
+ o = q.expect_many(
EventPattern('sip-ack', cseq=ack_cseq),
# Call accepted
- EventPattern('dbus-signal', signal='MembersChanged',
- args=['', [remote_handle], [], [], [], remote_handle,
- cs.GC_REASON_NONE]),
- EventPattern('dbus-signal', signal='SetRemoteCodecs'),
- ),
-
- stream_handler.SupportedCodecs(context.get_audio_codecs_dbus())
- stream_handler.StreamState(cs.MEDIA_STREAM_STATE_CONNECTED)
+ EventPattern('dbus-signal', signal='NewMediaDescriptionOffer'))
- # Time passes ... afterwards we close the chan
+ md = bus.get_object (conn.bus_name, o[1].args[0])
+ md.Accept(context.get_audio_md_dbus(remote_handle))
- chan.Group.RemoveMembers([self_handle], 'closed')
+ o = q.expect_many(
+ # Call accepted
+ EventPattern('dbus-signal', signal='CallStateChanged'),
+ EventPattern('dbus-signal', signal='EndpointsChanged'),
+ EventPattern('dbus-signal', signal='MediaDescriptionOfferDone'),
+ EventPattern('dbus-signal', signal='SendingStateChanged',
+ args=[cs.CALL_STREAM_FLOW_STATE_PENDING_START]),
+ EventPattern('dbus-signal', signal='LocalMediaDescriptionChanged'),
+ EventPattern('dbus-signal', signal='RemoteMediaDescriptionsChanged'))
+
+ mdo = content.Get(cs.CALL_CONTENT_IFACE_MEDIA, 'MediaDescriptionOffer')
+ assertEquals(('/', {}), mdo)
+
+ assertEquals(cs.CALL_STATE_ACCEPTED, o[0].args[0])
+ assertLength(0, o[1].args[1])
+
+ endpoint = bus.get_object(conn.bus_name, o[1].args[0][0])
+ endpoint_props = endpoint.GetAll(cs.CALL_STREAM_ENDPOINT)
+ assertEquals(('',''), endpoint_props['RemoteCredentials'])
+ assertEquals(context.get_remote_candidates_dbus(),
+ endpoint_props['RemoteCandidates'])
+ assertLength(0, endpoint_props['EndpointState'])
+ assertEquals(cs.CALL_STREAM_TRANSPORT_RAW_UDP,
+ endpoint_props['Transport'])
+ assertEquals(False, endpoint_props['IsICELite'])
+
+ endpoint.SetEndpointState(1,
+ cs.CALL_STREAM_ENDPOINT_STATE_FULLY_CONNECTED,
+ dbus_interface=cs.CALL_STREAM_ENDPOINT)
+ endpoint.SetEndpointState(2,
+ cs.CALL_STREAM_ENDPOINT_STATE_FULLY_CONNECTED,
+ dbus_interface=cs.CALL_STREAM_ENDPOINT)
+
+ assertEquals({1: cs.CALL_STREAM_ENDPOINT_STATE_FULLY_CONNECTED,
+ 2: cs.CALL_STREAM_ENDPOINT_STATE_FULLY_CONNECTED},
+ endpoint.Get(cs.CALL_STREAM_ENDPOINT, 'EndpointState'))
+
+ o = q.expect('dbus-signal', signal='CallStateChanged')
+ assertEquals(cs.CALL_STATE_ACTIVE, o.args[0])
+ # Time passes ... afterwards we close the chan
- mc_event, _, bye_event = q.expect_many(
- EventPattern('dbus-signal', signal='MembersChanged'),
- EventPattern('dbus-signal', signal='Close'),
- EventPattern('sip-bye', call_id=context.call_id),
- )
+ chan.Call1.Hangup(cs.CALL_SCR_USER_REQUESTED, "", "User hangs up")
+ ended_event, bye_event = q.expect_many(
+ EventPattern('dbus-signal', signal='CallStateChanged'),
+ EventPattern('sip-bye', call_id=context.call_id))
# Check that we're the actor
- assertEquals(self_handle, mc_event.args[5])
+ assertEquals(cs.CALL_STATE_ENDED, ended_event.args[0])
+ assertEquals(0, ended_event.args[1])
+ assertEquals((self_handle, cs.CALL_SCR_USER_REQUESTED, "",
+ "User hangs up"), ended_event.args[2])
# For completeness, reply to the BYE.
bye_response = sip_proxy.responseFromRequest(200, bye_event.sip_message)
sip_proxy.deliverResponse(bye_response)
+ chan.Close()
+
def rccs(q, bus, conn, stream):
"""
Tests that the connection's RequestableChannelClasses for StreamedMedia are
@@ -241,44 +247,43 @@ def rccs(q, bus, conn, stream):
"""
conn.Connect()
- q.expect('dbus-signal', signal='StatusChanged',
- args=[cs.CONN_STATUS_CONNECTED, cs.CSR_REQUESTED])
+
+ a = q.expect('dbus-signal', signal='StatusChanged',
+ args=[cs.CONN_STATUS_CONNECTING, cs.CSR_REQUESTED])
+
+ a = q.expect('dbus-signal', signal='StatusChanged',
+ args=[cs.CONN_STATUS_CONNECTED, cs.CSR_REQUESTED])
rccs = conn.Properties.Get(cs.CONN_IFACE_REQUESTS,
'RequestableChannelClasses')
# Test Channel.Type.StreamedMedia
media_classes = [ rcc for rcc in rccs
- if rcc[0][cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_STREAMED_MEDIA ]
+ if rcc[0][cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_CALL ]
- assertLength(1, media_classes)
+ assertLength(2, media_classes)
- fixed, allowed = media_classes[0]
+ for media_class in media_classes:
+ fixed, allowed = media_class
- assertEquals(cs.HT_CONTACT, fixed[cs.TARGET_HANDLE_TYPE])
+ assertEquals(cs.HT_CONTACT, fixed[cs.TARGET_HANDLE_TYPE])
+ assert fixed.has_key(cs.INITIAL_AUDIO) or fixed.has_key(cs.INITIAL_VIDEO)
- expected_allowed = [
- cs.TARGET_ID, cs.TARGET_HANDLE,
- cs.INITIAL_VIDEO, cs.INITIAL_AUDIO,
- cs.DTMF_INITIAL_TONES
- ]
+ expected_allowed = [
+ cs.TARGET_ID, cs.TARGET_HANDLE,
+ cs.INITIAL_VIDEO, cs.INITIAL_AUDIO,
+ cs.INITIAL_VIDEO_NAME, cs.INITIAL_AUDIO_NAME,
+ cs.INITIAL_TRANSPORT,
+ cs.DTMF_INITIAL_TONES,
+ ]
- allowed.sort()
- expected_allowed.sort()
- assertSameSets(expected_allowed, allowed)
+ allowed.sort()
+ expected_allowed.sort()
+ assertSameSets(expected_allowed, allowed)
if __name__ == '__main__':
exec_test(rccs)
exec_test(create)
- exec_test(request_anonymous)
- exec_test(request_anonymous_and_add)
- exec_test(request_nonymous)
exec_test(lambda q, b, c, s:
create(q, b, c, s, peer='foo@gw.bar.com'))
- exec_test(lambda q, b, c, s:
- request_anonymous(q, b, c, s, peer='foo@gw.bar.com'))
- exec_test(lambda q, b, c, s:
- request_anonymous_and_add(q, b, c, s, peer='foo@gw.bar.com'))
- exec_test(lambda q, b, c, s:
- request_nonymous(q, b, c, s, peer='foo@gw.bar.com'))
diff --git a/tests/twisted/voip/voip_test.py b/tests/twisted/voip/voip_test.py
index c8724af..95b9fdc 100644
--- a/tests/twisted/voip/voip_test.py
+++ b/tests/twisted/voip/voip_test.py
@@ -8,6 +8,7 @@ from servicetest import (
make_channel_proxy,
assertContains,
)
+import constants as cs
class VoipTestContext(object):
# Default audio codecs for the remote end
@@ -17,21 +18,23 @@ class VoipTestContext(object):
# Default video codecs for the remote end. I have no idea what's
# a suitable value here...
- video_codecs = [ ('WTF', 42, 80000, {}) ]
+ video_codecs = [ ('H264', 96, 90000, {}) ]
# Default candidates for the remote end
- remote_transports = [
- ( "192.168.0.1", # host
- 666, # port
- 0, # protocol = TP_MEDIA_STREAM_BASE_PROTO_UDP
- "RTP", # protocol subtype
- "AVP", # profile
- 1.0, # preference
- 0, # transport type = TP_MEDIA_STREAM_TRANSPORT_TYPE_LOCAL,
- "username",
- "password" ) ]
-
- _mline_template = 'm=audio %(port)s %(subtype)s/%(profile)s %(codec_ids)s'
+ remote_candidates = [
+ (1, # Component
+ "192.168.0.1", # ip
+ 2222, # port
+ {'protocol': cs.MEDIA_STREAM_BASE_PROTO_UDP,
+ 'priority': 0}),
+ (2, # Component
+ "192.168.0.1", # ip
+ 2223, # port
+ {'protocol': cs.MEDIA_STREAM_BASE_PROTO_UDP,
+ 'priority': 0})
+ ]
+
+ _mline_template = 'm=audio %(port)s RTP/AVP %(codec_ids)s'
_aline_template = 'a=rtpmap:%(codec_id)s %(name)s/%(rate)s'
def __init__(self, q, conn, bus, sip_proxy, our_uri, peer):
@@ -45,60 +48,31 @@ class VoipTestContext(object):
self._cseq_id = 1
def dbusify_codecs(self, codecs):
- dbussed_codecs = [ (id, name, 0, rate, 0, params )
+ dbussed_codecs = [ (id, name, rate, 1, False, params )
for (name, id, rate, params) in codecs ]
- return dbus.Array(dbussed_codecs, signature='(usuuua{ss})')
+ return dbus.Array(dbussed_codecs, signature='(usuuba{ss})')
def dbusify_codecs_with_params (self, codecs):
return self.dbusify_codecs(codecs)
- def get_audio_codecs_dbus(self):
- return self.dbusify_codecs(self.audio_codecs)
+ def get_md_dbus(self, codecs, remote_contact):
+ return dbus.Dictionary(
+ {cs.CALL_CONTENT_MEDIA_DESCRIPTION + ".Codecs": self.dbusify_codecs(codecs),
+ cs.CALL_CONTENT_MEDIA_DESCRIPTION + ".RemoteContact":
+ dbus.UInt32(remote_contact)},
+ signature='sv')
- def get_video_codecs_dbus(self):
- return self.dbusify_codecs(self.video_codecs)
+ def get_audio_md_dbus(self, remote_contact):
+ return self.get_md_dbus(self.audio_codecs, remote_contact)
- def dbusify_call_codecs(self, codecs):
- dbussed_codecs = [ (id, name, rate, 0, params)
- for (name, id, rate, params) in codecs ]
- return dbus.Array(dbussed_codecs, signature='(usuua{ss})')
-
- def dbusify_call_codecs_with_params(self, codecs):
- return dbusify_call_codecs (self, codecs)
-
- def get_call_audio_codecs_dbus(self):
- return self.dbusify_call_codecs(self.audio_codecs)
-
- def get_call_video_codecs_dbus(self):
- return self.dbusify_call_codecs(self.video_codecs)
-
-
- def get_remote_transports_dbus(self):
- return dbus.Array([
- (dbus.UInt32(1 + i), host, port, proto, subtype,
- profile, pref, transtype, user, pwd)
- for i, (host, port, proto, subtype, profile,
- pref, transtype, user, pwd)
- in enumerate(self.remote_transports) ],
- signature='(usuussduss)')
-
- def get_call_remote_transports_dbus(self):
- return dbus.Array([
- (1 , host, port,
- { "Type": transtype,
- "Foundation": "",
- "Protocol": proto,
- "Priority": int((1+i) * 65536),
- "Username": user,
- "Password": pwd }
- ) for i, (host, port, proto, subtype, profile,
- pref, transtype, user, pwd)
- in enumerate(self.remote_transports) ],
- signature='(usqa{sv})')
+ def get_video_md_dbus(self, remote_contact):
+ return self.get_md_dbus(self.video_codecs, remote_contact)
+
+ def get_remote_candidates_dbus(self):
+ return dbus.Array(self.remote_candidates, signature='(usua{sv})')
def get_call_sdp(self):
- (ip, port, protocol, subtype, profile, preference,
- transport, username, password) = self.remote_transports[0]
+ (component, ip, port, info) = self.remote_candidates[0]
codec_id_list = []
codec_list = []
@@ -124,8 +98,7 @@ class VoipTestContext(object):
codec_id_list.append(str(codec_id))
codec_ids = ' '.join(codec_id_list)
- (ip, port, protocol, subtype, profile, preference,
- transport, username, password) = self.remote_transports[0]
+ (component, ip, port, info) = self.remote_candidates[0]
assert self._mline_template % locals() in sdp_string
def send_message(self, message_type, body='', to_=None, from_=None,
@@ -161,6 +134,12 @@ class VoipTestContext(object):
response.addHeader('content-length', '%d' % len(response.body))
self.sip_proxy.deliverResponse(response)
return response
+
+ def pr_respond(self, invite_message, number):
+ self.call_id = invite_message.headers['call-id'][0]
+ response = self.sip_proxy.responseFromRequest(number, invite_message)
+ self.sip_proxy.deliverResponse(response)
+ return response
def ack(self, ok_message):
cseq = '%s ACK' % ok_message.headers['cseq'][0].split()[0]
@@ -181,28 +160,3 @@ class VoipTestContext(object):
def terminate(self):
return self.send_message('BYE', call_id=self.call_id)
-
- def handle_audio_session(self, chan):
- """
- Serves a SessionHandler and a StreamHandler for the MediaSignalling
- channel. Returns the interface proxy for StreamHandler.
- """
- session_handlers = chan.MediaSignalling.GetSessionHandlers()
- sh_path, sh_type = session_handlers[0]
-
- assert sh_type == 'rtp'
-
- session_handler = make_channel_proxy(self.conn, sh_path,
- 'Media.SessionHandler')
- session_handler.Ready()
-
- e = self.q.expect('dbus-signal', signal='NewStreamHandler')
-
- stream_handler = make_channel_proxy(self.conn, e.args[0],
- 'Media.StreamHandler')
-
- stream_handler.NewNativeCandidate("fake", self.get_remote_transports_dbus())
- stream_handler.NativeCandidatesPrepared()
- stream_handler.Ready(self.get_audio_codecs_dbus())
-
- return stream_handler