dispatch iq-result for a jingle iq stanza, start listener after iq-result on session-initiate.

This commit is contained in:
Zhenchao Li 2010-07-03 16:22:47 +08:00
parent 2203755734
commit d0adcb1a05
6 changed files with 80 additions and 7 deletions

View File

@ -84,16 +84,26 @@ class ConnectionJingle(object):
raise xmpp.NodeProcessed
jingle = stanza.getTag('jingle')
if not jingle: return
sid = jingle.getAttr('sid')
# a jingle element is not necessary in iq-result stanza
# don't check for that
if jingle:
sid = jingle.getAttr('sid')
else:
sid = None
for sesn in self.__sessions.values():
if id in sesn.iq_ids:
sesn.on_stanza(stanza)
return
# do we need to create a new jingle object
if sid not in self.__sessions:
#TODO: tie-breaking and other things...
newjingle = JingleSession(con=self, weinitiate=False, jid=jid, sid=sid)
newjingle = JingleSession(con=self, weinitiate=False, jid=jid,
iq_id = id, sid=sid)
self.__sessions[sid] = newjingle
# we already have such session in dispatcher...
self.__sessions[sid].collect_iq_id(id)
self.__sessions[sid].on_stanza(stanza)
# Delete invalid/unneeded sessions
if sid in self.__sessions and self.__sessions[sid].state == JingleStates.ended:

View File

@ -23,6 +23,8 @@ import gajim
import xmpp
from jingle_content import contents, JingleContent
from jingle_transport import JingleTransportICEUDP, JingleTransportSocks5
from common import helpers
import logging
log = logging.getLogger('gajim.c.jingle_ft')
@ -42,6 +44,7 @@ class JingleFileTransfer(JingleContent):
self.callbacks['transport-replace'] += [self.__on_transport_replace] #fallback transport method
self.callbacks['transport-reject'] += [self.__on_transport_reject]
self.callbacks['transport-info'] += [self.__on_transport_info]
self.callbacks['iq-result'] += [self.__on_iq_result]
self.file_props = file_props
if file_props is None:
@ -51,6 +54,7 @@ class JingleFileTransfer(JingleContent):
if self.file_props is not None:
self.file_props['sender'] = session.ourjid
self.file_props['receiver'] = session.peerjid
self.file_props['session-type'] = 'jingle'
self.file_props['sid'] = session.sid
self.file_props['transfered_size'] = []
@ -129,6 +133,25 @@ class JingleFileTransfer(JingleContent):
def __on_transport_info(self, stanza, content, error, action):
log.info("__on_transport_info")
def __on_iq_result(self, stanza, content, error, action):
log.info("__on_iq_result")
if self.weinitiate:
receiver = self.file_props['receiver']
sender = self.file_props['sender']
sha_str = helpers.get_auth_sha(self.file_props['sid'], sender, receiver)
self.file_props['sha_str'] = sha_str
port = gajim.config.get('file_transfers_port')
listener = gajim.socks5queue.start_listener(port, sha_str,
self._store_socks5_sid, self.file_props['sid'])
if not listener:
return
# send error message, notify the user
def _fill_content(self, content):
description_node = xmpp.simplexml.Node(tag=xmpp.NS_JINGLE_FILE_TRANSFER + ' description')
@ -144,6 +167,11 @@ class JingleFileTransfer(JingleContent):
description_node.addChild(node=sioffer)
content.addChild(node=description_node)
def _store_socks5_sid(self, sid, hash_id):
# callback from socsk5queue.start_listener
self.file_props['hash'] = hash_id
return
def get_content(desc):
return JingleFileTransfer

View File

@ -30,6 +30,8 @@ import gajim #Get rid of that?
import xmpp
from jingle_transport import get_jingle_transport
from jingle_content import get_jingle_content, JingleContentSetupException
import logging
log = logging.getLogger("gajim.c.jingle_session")
# FIXME: Move it to JingleSession.States?
class JingleStates(object):
@ -58,7 +60,7 @@ class JingleSession(object):
negotiated between an initiator and a responder.
"""
def __init__(self, con, weinitiate, jid, sid=None):
def __init__(self, con, weinitiate, jid, iq_id = None, sid=None):
"""
con -- connection object,
weinitiate -- boolean, are we the initiator?
@ -83,6 +85,14 @@ class JingleSession(object):
if not sid:
sid = con.connection.getAnID()
self.sid = sid # sessionid
# iq stanza id, used to determine which sessions to summon callback
# later on when iq-result stanza arrives
if iq_id is not None:
self.iq_ids = [iq_id]
else:
self.iq_ids = []
self.accepted = True # is this session accepted by user
@ -110,10 +120,14 @@ class JingleSession(object):
'transport-replace': [self.__broadcast, self.__on_transport_replace], #TODO
'transport-accept': [self.__ack], #TODO
'transport-reject': [self.__ack], #TODO
'iq-result': [],
'iq-result': [self.__broadcast],
'iq-error': [self.__on_error],
}
def collect_iq_id(self, iq_id):
if iq_id is not None:
self.iq_ids.append(iq_id)
def approve_session(self):
"""
Called when user accepts session in UI (when we aren't the initiator)
@ -463,6 +477,17 @@ class JingleSession(object):
"""
Broadcast the stanza contents to proper content handlers
"""
#if jingle is None: # it is a iq-result stanza
# for cn in self.contents.values():
# cn.on_stanza(stanza, None, error, action)
# return
# special case: iq-result stanza does not come with a jingle element
if action == 'iq-result':
for cn in self.contents.values():
cn.on_stanza(stanza, None, error, action)
return
for content in jingle.iterTags('content'):
name = content['name']
creator = content['creator']
@ -606,6 +631,7 @@ class JingleSession(object):
self.__append_contents(jingle)
self.__broadcast(stanza, jingle, None, 'session-initiate-sent')
self.connection.connection.send(stanza)
self.collect_iq_id(stanza.getID())
self.state = JingleStates.pending
def __session_accept(self):
@ -614,6 +640,7 @@ class JingleSession(object):
self.__append_contents(jingle)
self.__broadcast(stanza, jingle, None, 'session-accept-sent')
self.connection.connection.send(stanza)
self.collect_iq_id(stanza.getID())
self.state = JingleStates.active
def __session_info(self, payload=None):

View File

@ -147,7 +147,8 @@ class ConnectionBytestream:
if not gajim.socks5queue.get_file_props(session.ourjid, sid):
gajim.socks5queue.add_file_props(session.ourjid, file_props)
gajim.socks5queue.connect_to_hosts(session.ourjid, sid,
None, None)
lambda streamhost: log.info("connected to" + str(streamhost)),
lambda a, b, c, d: log.info("connect error!" + a + b + c + d))
return
iq = xmpp.Iq(to=unicode(file_props['sender']), typ='result')

View File

@ -35,6 +35,10 @@ from errno import EISCONN
from errno import EINPROGRESS
from errno import EAFNOSUPPORT
from xmpp.idlequeue import IdleObject
import logging
log = logging.getLogger('gajim.c.socks5')
MAX_BUFF_LEN = 65536
# after foo seconds without activity label transfer as 'stalled'
@ -257,6 +261,7 @@ class SocksQueue:
def send_file(self, file_props, account):
if 'hash' in file_props and file_props['hash'] in self.senders:
log.info("socks5: sending file")
sender = self.senders[file_props['hash']]
file_props['streamhost-used'] = True
sender.account = account
@ -269,6 +274,8 @@ class SocksQueue:
file_props['last-time'] = self.idlequeue.current_time()
file_props['received-len'] = 0
sender.file_props = file_props
else:
log.info("socks5: NOT sending file")
def add_file_props(self, account, file_props):
"""

View File

@ -37,7 +37,7 @@ from hashlib import sha256
from hmac import HMAC
from common import crypto
if gajim.HAVE_PYCRYPTO:
if gajim.HAVE_PYCRYPTO and False:
from Crypto.Cipher import AES
from Crypto.PublicKey import RSA