[Telepathy-commits] [mingle/master] Add outgoing google talk support

Sjoerd Simons sjoerd at luon.net
Mon Nov 24 06:18:41 PST 2008


---
 jingle.py |  107 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 98 insertions(+), 9 deletions(-)

diff --git a/jingle.py b/jingle.py
index 6cf1f72..bf482eb 100644
--- a/jingle.py
+++ b/jingle.py
@@ -412,7 +412,7 @@ class GoogleTransport(JingleGoogleTransport):
         return defer.succeed(self)
 
     def send_candidate(self, fscandidate):
-        candidate = domish.Element((None, 'candidate'))
+        candidate = domish.Element((ns.GOOGLE_S_SESSION, 'candidate'))
         self.fscandidate_to_candidate(candidate, fscandidate)
         self.content.send_transport_info(candidate)
 
@@ -437,6 +437,9 @@ class GoogleTransport(JingleGoogleTransport):
     def add_transport(self, parent):
         pass
 
+    def session_accept(self, parent):
+        pass
+
 class JingleRawudpTransport(JingleBaseTransport):
     def __init__(self, content):
         JingleBaseTransport.__init__(self, content)
@@ -696,6 +699,21 @@ class GoogleBaseContent(JingleContent):
             description)
         self.description.got_initiate(self.fssession, stream, description)
 
+    def base_prepare(self, contact):
+        # We got transport and descriptions going, now fire the session
+        self.remote_contact = contact
+        self.fssession = self.session.conference.get_session(
+            self.name, self.type)
+
+        dtransport = self.transport.prepare(self.fssession,
+            self.remote_contact)
+        ddescription = self.description.prepare(self.fssession)
+
+        dl = defer.DeferredList([dtransport, ddescription])
+        d = defer.Deferred()
+        dl.addCallback (lambda *args: d.callback(self))
+        return d
+
 class GoogleVideoContent(GoogleBaseContent):
     def __init__(self, session, initiator = True):
        GoogleBaseContent.__init__(self, session, "video",
@@ -706,6 +724,11 @@ class GoogleVideoContent(GoogleBaseContent):
         self.transport =  GoogleTransport(self, GoogleTransport.TYPE_VIDEO)
         self.base_got_initiate(description, contact)
 
+    def prepare(self, contact):
+        self.description = GoogleVideoDescription(self)
+        self.transport =  GoogleTransport(self, GoogleTransport.TYPE_VIDEO)
+        return self.base_prepare(contact)
+
 class GooglePhoneContent(GoogleBaseContent):
     def __init__(self, session, initiator = True):
        GoogleBaseContent.__init__(self, session, "audio",
@@ -716,6 +739,11 @@ class GooglePhoneContent(GoogleBaseContent):
         self.transport =  GoogleTransport(self)
         self.base_got_initiate(description, contact)
 
+    def prepare(self, contact):
+        self.description = GooglePhoneDescription(self)
+        self.transport =  GoogleTransport(self)
+        return self.base_prepare(contact)
+
 class JingleBaseSession:
     def __init__(self, client, conference = None):
         self.client = client
@@ -923,15 +951,19 @@ class GoogleSession(JingleBaseSession):
     SESSION_TYPE_PHONE = 0
     SESSION_TYPE_VIDEO = 1
 
-    def __init__(self, client, conference = None):
+    def __init__(self, client, conference = None, type = SESSION_TYPE_PHONE):
         JingleBaseSession.__init__(self, client, conference)
         self.namespace = ns.GOOGLE_S_SESSION
-        self.type  = self.SESSION_TYPE_PHONE
+        self.type = type
 
         self.action_dispatch = {
             'candidates': self.action_candidates,
+            'accept': self.action_accept,
         }
 
+        self.iq_handler_id = self.client.add_iq_handler('set',
+            self.namespace, 'session', self.got_google_iq)
+
     def contents_ready_for_accept(self, *args):
         iq = IQ(self.client.stream, 'set')
         iq['to'] = self.remote_jid.full()
@@ -965,7 +997,7 @@ class GoogleSession(JingleBaseSession):
 
             contents = [
                 GooglePhoneContent (self, initiator = False),
-                GoogleVideoContent (self, initiator = False)
+                GoogleVideoContent (self, initiator = False),
             ]
         elif description.uri == ns.GOOGLE_S_SESSION_PHONE:
             contents = [ GooglePhoneContent (self, initiator = False) ]
@@ -974,9 +1006,6 @@ class GoogleSession(JingleBaseSession):
             self.contents[c.name] = c
             c.got_initiate(description, contact)
 
-        self.iq_handler_id = self.client.add_iq_handler('set',
-            self.namespace, 'session', self.got_google_iq)
-
         dlist = []
         for c in self.contents.itervalues():
             dlist.append(c.ready_for_accept())
@@ -995,6 +1024,13 @@ class GoogleSession(JingleBaseSession):
 
         return make_iq_result(iq)
 
+    def action_accept(self, iq, session):
+        description = xpath.queryForNodes('/session/description', session)[0]
+        for c in self.contents.itervalues():
+           c.session_accept(description)
+
+        return make_iq_result(iq)
+
     def add_google_session_stanza(self, iq, type):
         session = iq.addElement((self.namespace, 'session'))
         session['type'] = type
@@ -1020,6 +1056,55 @@ class GoogleSession(JingleBaseSession):
             return self.action_dispatch[session['type']](iq, session)
         print iq
 
+    # Outgoing call
+    def send_session_initiate(self):
+        self.initiator = self.client.jid
+
+        iq = IQ(self.client.stream, 'set')
+        iq['to'] = self.remote_jid.full()
+        session = self.add_google_session_stanza(iq, 'initiate')
+        if self.type == GoogleSession.SESSION_TYPE_VIDEO:
+            description = session.addElement ((ns.GOOGLE_S_SESSION_VIDEO,
+                "description"))
+        else:
+            description = session.addElement ((ns.GOOGLE_S_SESSION_PHONE,
+                "description"))
+        map(lambda c: c.add_content(description), self.contents.values())
+        iq.addCallback(self.session_initiate_result)
+        iq.send()
+
+    def initiate(self, contact):
+        # Start initiating a new jingle to contact X
+        self.initiating = True
+        self.remote_jid = contact.jid
+
+        assert self.contents == {}
+
+        # If the conference already has sessions then reuse those
+        if self.type == GoogleSession.SESSION_TYPE_VIDEO:
+            contents = [ GoogleVideoContent (self, initiator = True),
+                GooglePhoneContent (self, initiator = True) ]
+        else:
+            contents = [ GooglePhoneContent (self, initiator = True) ]
+
+        for c in contents:
+            self.contents[c.name] = c
+
+        deferreds = []
+        for c in contents:
+            d = c.prepare(contact)
+            d.addCallback(self.content_prepared)
+            d.addErrback(self.content_preperation_failed, c)
+
+            deferreds.append(d)
+
+        dlist = defer.DeferredList(deferreds)
+        dlist.addCallback(self.content_preparation_finished)
+
+class GoogleVSession:
+    def __init__(self, client, conference = None):
+        GoogleSession.__init__(self, client, conference,
+            GoogleSession.SESSION_TYPE_VIDEO)
 
 class JingleStream:
     def __init__(self, fsstream, namespace):
@@ -1144,7 +1229,9 @@ class JingleConference(fs2.Conference):
 def get_session_for_ns(client, namespace):
     ns2type = { ns.OLD_JINGLE: JingleOldSession,
                 ns.JINGLE: JingleSession,
-                ns.GOOGLE_S_SESSION: GoogleSession
+                ns.GOOGLE_VIDEO_V1:  GoogleVSession,
+                ns.GOOGLE_S_SESSION: GoogleSession,
+                ns.GOOGLE_VOICE_V1:  GoogleSession,
               }
 
     if ns2type.has_key(namespace):
@@ -1155,7 +1242,9 @@ def get_session_for_capabilities(client, capabilities):
     nsorder = [ ns.JINGLE,
                 ns.JINGLE_TMP,
                 ns.OLD_JINGLE,
-                ns.GOOGLE_SESSION ]
+                ns.GOOGLE_VIDEO_V1,
+                ns.GOOGLE_VOICE_V1,
+                ns.GOOGLE_S_SESSION ]
     # Look at the contacts caps and get the right type of jingle session,
     # sorted by priority, note that not all namespace might be supported yet
     for namespace in nsorder:
-- 
1.5.6.5




More information about the Telepathy-commits mailing list