[Telepathy-commits] [mingle/master] Implement the ICE udp transport

Sjoerd Simons sjoerd at luon.net
Mon Nov 24 13:25:44 PST 2008


---
 jingle.py |  101 +++++++++++++++++++++++++++++++++++++++++++-----------------
 1 files changed, 72 insertions(+), 29 deletions(-)

diff --git a/jingle.py b/jingle.py
index 0a7ab70..bca959f 100644
--- a/jingle.py
+++ b/jingle.py
@@ -212,7 +212,8 @@ def get_available_transports():
         available farsight transmitters
      """
     mapping = { "rawudp": [ ns.JINGLE_TRANSPORT_RAW_UDP ],
-                "nice": [ ns.GOOGLE_TRANSPORT_P2P ] }
+                "nice": [ ns.GOOGLE_TRANSPORT_P2P,
+                    ns.JINGLE_TRANSPORT_ICE ] }
     transmitters = fs2.get_available_transmitters()
     transports = []
 
@@ -232,8 +233,6 @@ class JingleBaseTransport:
     def __init__(self, content):
         self.content = content
         self.namespace = None
-        self.transmitter = None
-        self.transmitter_params = {}
 
         self.connected_deferred = None
         self.connected = False
@@ -246,9 +245,13 @@ class JingleBaseTransport:
           'username': ('username', str),
           'password': ('password', str),
           'address': ('ip', str),
+          'ip': ('ip', str),
+          'foundation': ('foundation', str),
           'preference': ('priority', lambda x: int(float(x))),
+          'priority': ('priority', int),
           'port': ('port', int),
           'protocol': ('proto', {'udp': 0, 'tcp': 1}.__getitem__),
+          'component': ('component_id', int),
           'name': ('component_id', {'rtp': farsight.COMPONENT_RTP,
              'rtcp': farsight.COMPONENT_RTCP,
              'video_rtcp' : farsight.COMPONENT_RTCP,
@@ -273,9 +276,16 @@ class JingleBaseTransport:
     def add_transport(self, parent):
         return parent.addElement((self.namespace, 'transport'))
 
-    def candidate_to_fscandidate(self, candidate):
+    def candidate_to_fscandidate(self, transport, candidate):
         fscandidate = farsight.Candidate()
 
+        # Real jingle puts some keys in the transport"
+        if transport != None:
+            if transport.hasAttribute("ufrag"):
+                fscandidate.username = str(transport["ufrag"])
+            if transport.hasAttribute("pwd"):
+                fscandidate.password = str(transport["pwd"])
+
         for a in candidate.attributes.iterkeys():
             if not self.candidate2farsight.has_key(a):
                 print "MISSING CONVERSION: %s" % a
@@ -292,26 +302,29 @@ class JingleBaseTransport:
     def transport_info(self, content):
         # content is a content stanza with transport info for us, aka a
         # candidate
-        candidates = \
-            xpath.queryForNodes('/content/transport[@xmlns="%s"]/candidate' %
+        transports = xpath.queryForNodes('/content/transport[@xmlns="%s"]' %
                 self.namespace, content)
 
-        if candidates == None:
+        if transports == None:
             return
 
-        for c in candidates:
-            fscandidate = self.candidate_to_fscandidate(c)
-            if fscandidate != None:
-                self.fsstream.add_remote_candidate(fscandidate)
+        for t in transports:
+            candidates = xpath.queryForNodes('/transport/candidate', t)
+            if candidates == None:
+                return
+            for c in candidates:
+                fscandidate = self.candidate_to_fscandidate(t, c)
+                if fscandidate != None:
+                    self.fsstream.add_remote_candidate(fscandidate)
 
-    def fscandidate_to_candidate(self, candidate, fscandidate):
+    def fscandidate_to_candidate(self, transport, candidate, fscandidate):
         # Fill the candidate xml with the info from the fscandidate
         pass
 
     def send_candidate(self, fscandidate):
         transport = domish.Element((self.namespace, 'transport'))
         candidate = transport.addElement('candidate')
-        self.fscandidate_to_candidate(candidate, fscandidate)
+        self.fscandidate_to_candidate(transport, candidate, fscandidate)
         self.content.send_transport_info(transport)
 
     def new_local_candidate(self, fscandidate):
@@ -359,11 +372,8 @@ class JingleGoogleTransport(JingleBaseTransport):
     def __init__(self, content):
         JingleBaseTransport.__init__(self, content)
         self.namespace = ns.GOOGLE_TRANSPORT_P2P
-        self.transmitter = "nice"
-        self.transmitter_params['compatibility-mode'] = 1
-        self.transmitter_params['debug'] = False
 
-    def fscandidate_to_candidate(self, candidate, fscandidate):
+    def fscandidate_to_candidate(self, transport, candidate, fscandidate):
         candidate['address'] = fscandidate.ip
         candidate['port'] = str(fscandidate.port)
         candidate['protocol'] = \
@@ -397,7 +407,7 @@ class GoogleTransport(JingleGoogleTransport):
     def transport_info(self, candidate):
         # content is a content stanza with transport info for us, aka a
         # candidate
-        fscandidate = self.candidate_to_fscandidate(candidate)
+        fscandidate = self.candidate_to_fscandidate(None, candidate)
         if fscandidate != None:
           self.fsstream.add_remote_candidate(fscandidate)
 
@@ -413,10 +423,10 @@ class GoogleTransport(JingleGoogleTransport):
 
     def send_candidate(self, fscandidate):
         candidate = domish.Element((ns.GOOGLE_S_SESSION, 'candidate'))
-        self.fscandidate_to_candidate(candidate, fscandidate)
+        self.fscandidate_to_candidate(None, candidate, fscandidate)
         self.content.send_transport_info(candidate)
 
-    def candidate_to_fscandidate(self, candidate):
+    def candidate_to_fscandidate(self, transport, candidate):
         if candidate.hasAttribute("name"):
             if self.type == GoogleTransport.TYPE_AUDIO:
                 if "video" in candidate["name"]:
@@ -426,11 +436,12 @@ class GoogleTransport(JingleGoogleTransport):
                 if not "video" in candidate["name"]:
                     return
 
-        return JingleGoogleTransport.candidate_to_fscandidate(self, candidate)
+        return JingleGoogleTransport.candidate_to_fscandidate(self,
+            transport, candidate)
 
-    def fscandidate_to_candidate(self, candidate, fscandidate):
+    def fscandidate_to_candidate(self, trnasport, candidate, fscandidate):
         JingleGoogleTransport.fscandidate_to_candidate(self, \
-            candidate, fscandidate)
+            transport, candidate, fscandidate)
         if self.type == GoogleTransport.TYPE_VIDEO:
              candidate['name'] = "video_" + candidate['name']
 
@@ -444,7 +455,6 @@ class JingleRawudpTransport(JingleBaseTransport):
     def __init__(self, content):
         JingleBaseTransport.__init__(self, content)
         self.namespace = ns.JINGLE_TRANSPORT_RAW_UDP
-        self.transmitter = "rawudp"
         # Deferred to wait on the availability of local candiates
         self.candidate_deferred = None
 
@@ -459,7 +469,7 @@ class JingleRawudpTransport(JingleBaseTransport):
 
         transport = JingleBaseTransport.add_transport(self, parent)
         candidate = transport.addElement('candidate')
-        self.fscandidate_to_candidate(candidate, fscandidate)
+        self.fscandidate_to_candidate(transport, candidate, fscandidate)
 
     def fscandidate_to_candidate(self, candidate, fscandidate):
         candidate['address'] = fscandidate.ip
@@ -476,9 +486,9 @@ class JingleRawudpTransport(JingleBaseTransport):
             dlist.append (self.candidate_deferred)
         return defer.DeferredList(dlist)
 
-    def candidate_to_fscandidate(self, candidate):
+    def candidate_to_fscandidate(self, transport, candidate):
         fscandidate = JingleBaseTransport.candidate_to_fscandidate(self,
-            candidate)
+            transport, candidate)
         fscandidate.component_id = farsight.COMPONENT_RTP
 
         return fscandidate
@@ -490,6 +500,34 @@ class JingleRawudpTransport(JingleBaseTransport):
             self.candidate_deferred = defer.Deferred()
             return self.candidate_deferred
 
+class JingleICETransport(JingleBaseTransport):
+    def __init__(self, content):
+        JingleBaseTransport.__init__(self, content)
+        self.namespace = ns.JINGLE_TRANSPORT_ICE
+
+    def fscandidate_to_candidate(self, transport, candidate, fscandidate):
+        transport['ufrag'] = fscandidate.username
+        transport['pwd'] = fscandidate.password
+
+        candidate['ip'] = fscandidate.ip
+        candidate['port'] = str(fscandidate.port)
+        candidate['protocol'] = \
+          {farsight.NETWORK_PROTOCOL_UDP: 'udp',
+           farsight.NETWORK_PROTOCOL_TCP: 'tcp'}[fscandidate.proto]
+        candidate['component'] = str(fscandidate.component_id)
+        candidate['generation'] = '0'
+        candidate['foundation'] = fscandidate.foundation
+        candidate['priority'] = str(fscandidate.priority)
+        candidate['network'] = "0"
+        candidate['type'] = \
+            { farsight.CANDIDATE_TYPE_HOST: "host",
+              farsight.CANDIDATE_TYPE_SRFLX: "srflx",
+              farsight.CANDIDATE_TYPE_PRFLX: "prflx",
+              farsight.CANDIDATE_TYPE_RELAY: "relay",
+              farsight.CANDIDATE_TYPE_MULTICAST: "multicast"
+            }[fscandidate.type]
+
+
 class JingleContent:
     # A jingle content, session is the jingle session, type is the media type
     def __init__(self, session, name, type = None, initiator = True):
@@ -555,7 +593,8 @@ class JingleContent:
         if not namespace in get_available_transports():
             return None
 
-        caps2transport = { ns.GOOGLE_TRANSPORT_P2P: JingleGoogleTransport,
+        caps2transport = { ns.JINGLE_TRANSPORT_ICE: JingleICETransport,
+                           ns.GOOGLE_TRANSPORT_P2P: JingleGoogleTransport,
                            ns.JINGLE_TRANSPORT_RAW_UDP: JingleRawudpTransport
                          }
         if caps2transport.has_key(namespace):
@@ -1180,7 +1219,11 @@ class JingleConference(fs2.Conference):
                   'stun-ip': "69.0.208.27",
                   'stun-port': 3478
                 }),
-            ns.JINGLE_TRANSPORT_RAW_UDP: ("rawudp", {} )
+            ns.JINGLE_TRANSPORT_RAW_UDP: ("rawudp", {} ),
+            ns.JINGLE_TRANSPORT_ICE: ("nice",
+                { 'stun-ip': "69.0.208.27",
+                  'stun-port': 3478
+                })
         }
 
         if not namespace in get_available_transports():
-- 
1.5.6.5



More information about the Telepathy-commits mailing list