2007-08-06 17:53:01 +02:00
|
|
|
##
|
|
|
|
## Copyright (C) 2006 Gajim Team
|
|
|
|
##
|
|
|
|
## This program is free software; you can redistribute it and/or modify
|
|
|
|
## it under the terms of the GNU General Public License as published
|
|
|
|
## by the Free Software Foundation; version 2 only.
|
|
|
|
##
|
|
|
|
## This program is distributed in the hope that it will be useful,
|
|
|
|
## but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
## GNU General Public License for more details.
|
|
|
|
##
|
|
|
|
''' Handles the jingle signalling protocol. '''
|
|
|
|
|
2009-09-13 11:02:49 +02:00
|
|
|
#TODO:
|
2009-09-16 13:55:54 +02:00
|
|
|
# * things in XEP 0176, including:
|
|
|
|
# - http://xmpp.org/extensions/xep-0176.html#protocol-restarts
|
|
|
|
# - http://xmpp.org/extensions/xep-0176.html#fallback
|
|
|
|
# * XEP 0177 (raw udp)
|
|
|
|
|
2009-09-13 11:02:49 +02:00
|
|
|
# * UI:
|
|
|
|
# - make state and codec informations available to the user
|
2009-09-18 20:17:35 +02:00
|
|
|
# - video integration
|
2009-09-13 11:02:49 +02:00
|
|
|
# * config:
|
|
|
|
# - codecs
|
|
|
|
# - STUN
|
2009-09-18 20:17:35 +02:00
|
|
|
|
2009-11-15 20:47:06 +01:00
|
|
|
# * figure out why it doesn't work with pidgin:
|
|
|
|
# That's maybe a bug in pidgin:
|
|
|
|
# http://xmpp.org/extensions/xep-0176.html#protocol-checks
|
2009-09-18 20:17:35 +02:00
|
|
|
|
2007-08-06 17:53:01 +02:00
|
|
|
import xmpp
|
2009-09-26 10:29:08 +02:00
|
|
|
import helpers
|
2007-08-06 17:53:01 +02:00
|
|
|
|
2009-11-15 20:47:06 +01:00
|
|
|
from jingle_session import JingleSession
|
|
|
|
from jingle_rtp import JingleAudio, JingleVideo
|
2009-09-13 11:02:49 +02:00
|
|
|
|
2009-09-17 23:36:26 +02:00
|
|
|
|
2007-08-06 17:53:01 +02:00
|
|
|
class ConnectionJingle(object):
|
|
|
|
''' This object depends on that it is a part of Connection class. '''
|
|
|
|
def __init__(self):
|
|
|
|
# dictionary: (jid, sessionid) => JingleSession object
|
|
|
|
self.__sessions = {}
|
|
|
|
|
|
|
|
# dictionary: (jid, iq stanza id) => JingleSession object,
|
|
|
|
# one time callbacks
|
|
|
|
self.__iq_responses = {}
|
|
|
|
|
2009-09-19 17:24:59 +02:00
|
|
|
def add_jingle(self, jingle):
|
2007-08-06 17:53:01 +02:00
|
|
|
''' Add a jingle session to a jingle stanza dispatcher
|
|
|
|
jingle - a JingleSession object.
|
|
|
|
'''
|
2009-09-16 20:41:12 +02:00
|
|
|
self.__sessions[(jingle.peerjid, jingle.sid)] = jingle
|
2007-08-06 17:53:01 +02:00
|
|
|
|
2009-10-16 19:04:04 +02:00
|
|
|
def delete_jingle_session(self, peerjid, sid):
|
2007-08-06 17:53:01 +02:00
|
|
|
''' Remove a jingle session from a jingle stanza dispatcher '''
|
2009-10-16 19:04:04 +02:00
|
|
|
key = (peerjid, sid)
|
|
|
|
if key in self.__sessions:
|
|
|
|
#FIXME: Move this elsewhere?
|
|
|
|
for content in self.__sessions[key].contents.values():
|
|
|
|
content.destroy()
|
|
|
|
self.__sessions[key].callbacks = []
|
|
|
|
del self.__sessions[key]
|
2007-08-06 17:53:01 +02:00
|
|
|
|
2007-08-07 01:19:57 +02:00
|
|
|
def _JingleCB(self, con, stanza):
|
2007-08-06 17:53:01 +02:00
|
|
|
''' The jingle stanza dispatcher.
|
|
|
|
Route jingle stanza to proper JingleSession object,
|
|
|
|
or create one if it is a new session.
|
|
|
|
TODO: Also check if the stanza isn't an error stanza, if so
|
|
|
|
route it adequatelly.'''
|
|
|
|
|
|
|
|
# get data
|
2009-09-25 20:41:22 +02:00
|
|
|
jid = helpers.get_full_jid_from_iq(stanza)
|
2007-08-06 17:53:01 +02:00
|
|
|
id = stanza.getID()
|
|
|
|
|
|
|
|
if (jid, id) in self.__iq_responses.keys():
|
|
|
|
self.__iq_responses[(jid, id)].stanzaCB(stanza)
|
|
|
|
del self.__iq_responses[(jid, id)]
|
|
|
|
raise xmpp.NodeProcessed
|
|
|
|
|
|
|
|
jingle = stanza.getTag('jingle')
|
2007-08-07 01:19:57 +02:00
|
|
|
if not jingle: return
|
2007-08-06 17:53:01 +02:00
|
|
|
sid = jingle.getAttr('sid')
|
|
|
|
|
|
|
|
# do we need to create a new jingle object
|
|
|
|
if (jid, sid) not in self.__sessions:
|
2009-09-28 22:23:48 +02:00
|
|
|
#TODO: tie-breaking and other things...
|
2007-08-07 18:34:09 +02:00
|
|
|
newjingle = JingleSession(con=self, weinitiate=False, jid=jid, sid=sid)
|
2009-09-19 17:24:59 +02:00
|
|
|
self.add_jingle(newjingle)
|
2007-08-06 17:53:01 +02:00
|
|
|
|
|
|
|
# we already have such session in dispatcher...
|
2007-08-07 18:34:09 +02:00
|
|
|
self.__sessions[(jid, sid)].stanzaCB(stanza)
|
|
|
|
|
|
|
|
raise xmpp.NodeProcessed
|
2007-08-06 17:53:01 +02:00
|
|
|
|
2009-09-13 11:02:49 +02:00
|
|
|
def startVoIP(self, jid):
|
2009-09-25 19:32:13 +02:00
|
|
|
if self.get_jingle_session(jid, media='audio'):
|
2009-09-26 21:55:43 +02:00
|
|
|
return self.get_jingle_session(jid, media='audio').sid
|
2009-09-25 13:52:44 +02:00
|
|
|
jingle = self.get_jingle_session(jid, media='video')
|
|
|
|
if jingle:
|
2009-11-15 20:47:06 +01:00
|
|
|
jingle.add_content('voice', JingleAudio(jingle))
|
2009-09-25 13:52:44 +02:00
|
|
|
else:
|
|
|
|
jingle = JingleSession(self, weinitiate=True, jid=jid)
|
|
|
|
self.add_jingle(jingle)
|
2009-11-15 20:47:06 +01:00
|
|
|
jingle.add_content('voice', JingleAudio(jingle))
|
2009-09-25 13:52:44 +02:00
|
|
|
jingle.start_session()
|
2009-09-17 14:48:15 +02:00
|
|
|
return jingle.sid
|
2009-09-16 20:41:12 +02:00
|
|
|
|
2009-09-25 13:52:44 +02:00
|
|
|
def startVideoIP(self, jid):
|
2009-09-25 19:32:13 +02:00
|
|
|
if self.get_jingle_session(jid, media='video'):
|
2009-09-26 21:55:43 +02:00
|
|
|
return self.get_jingle_session(jid, media='video').sid
|
2009-09-25 13:52:44 +02:00
|
|
|
jingle = self.get_jingle_session(jid, media='audio')
|
|
|
|
if jingle:
|
|
|
|
jingle.add_content('video', JingleVideo(jingle))
|
|
|
|
else:
|
|
|
|
jingle = JingleSession(self, weinitiate=True, jid=jid)
|
|
|
|
self.add_jingle(jingle)
|
|
|
|
jingle.add_content('video', JingleVideo(jingle))
|
|
|
|
jingle.start_session()
|
|
|
|
return jingle.sid
|
|
|
|
|
|
|
|
def get_jingle_session(self, jid, sid=None, media=None):
|
|
|
|
if sid:
|
|
|
|
if (jid, sid) in self.__sessions:
|
|
|
|
return self.__sessions[(jid, sid)]
|
|
|
|
else:
|
|
|
|
return None
|
|
|
|
elif media:
|
2009-09-25 19:32:13 +02:00
|
|
|
if media not in ('audio', 'video'):
|
2009-09-25 13:52:44 +02:00
|
|
|
return None
|
|
|
|
for session in self.__sessions.values():
|
2009-09-25 19:32:13 +02:00
|
|
|
if session.peerjid == jid and session.get_content(media):
|
|
|
|
return session
|
|
|
|
|
2009-09-25 13:52:44 +02:00
|
|
|
return None
|