Commit ad9370af authored by Emmanuel Gil Peyrot's avatar Emmanuel Gil Peyrot

Fix a bunch of issues in common.jingle*.

parent 57fb80f1
......@@ -142,6 +142,10 @@ SHOW_LIST = ['offline', 'connecting', 'online', 'chat', 'away', 'xa', 'dnd',
# zeroconf account name
ZEROCONF_ACC_NAME = 'Local'
# These will be set in gajim.gui_interface.
idlequeue = None
socks5queue = None
HAVE_ZEROCONF = True
try:
__import__('avahi')
......
......@@ -28,19 +28,21 @@ Handles the jingle signalling protocol
# * config:
# - codecs
import logging
import nbxmpp
from common import helpers
from common import gajim
from common.jingle_session import JingleSession, JingleStates
if gajim.HAVE_FARSTREAM:
from common.jingle_rtp import JingleAudio, JingleVideo
from common.jingle_ft import JingleFileTransfer
from common.jingle_transport import JingleTransportSocks5, JingleTransportIBB
if gajim.HAVE_FARSTREAM:
from common.jingle_rtp import JingleAudio, JingleVideo
import logging
logger = logging.getLogger('gajim.c.jingle')
class ConnectionJingle(object):
"""
This object depends on that it is a part of Connection class.
......@@ -80,7 +82,7 @@ class ConnectionJingle(object):
try:
jid = helpers.get_full_jid_from_iq(stanza)
except helpers.InvalidFormat:
logger.warn('Invalid JID: %s, ignoring it' % stanza.getFrom())
logger.warning('Invalid JID: %s, ignoring it', stanza.getFrom())
return
id_ = stanza.getID()
if (jid, id_) in self.__iq_responses.keys():
......@@ -102,14 +104,14 @@ class ConnectionJingle(object):
if sid not in self._sessions:
#TODO: tie-breaking and other things...
newjingle = JingleSession(con=self, weinitiate=False, jid=jid,
iq_id=id_, sid=sid)
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:
self._sessions[sid].state == JingleStates.ENDED:
self.delete_jingle_session(sid)
raise nbxmpp.NodeProcessed
......@@ -132,20 +134,20 @@ class ConnectionJingle(object):
jingle = self.get_jingle_session(jid, media='audio')
if jingle:
jingle.add_content('video', JingleVideo(jingle, in_xid=in_xid,
out_xid=out_xid))
out_xid=out_xid))
else:
jingle = JingleSession(self, weinitiate=True, jid=jid)
self._sessions[jingle.sid] = jingle
jingle.add_content('video', JingleVideo(jingle, in_xid=in_xid,
out_xid=out_xid))
out_xid=out_xid))
jingle.start_session()
return jingle.sid
def start_file_transfer(self, jid, file_props, request=False):
logger.info("start file transfer with file: %s" % file_props)
logger.info("start file transfer with file: %s", file_props)
contact = gajim.contacts.get_contact_with_highest_priority(self.name,
gajim.get_jid_without_resource(jid))
if gajim.contacts.is_gc_contact(self.name,jid):
gajim.get_jid_without_resource(jid))
if gajim.contacts.is_gc_contact(self.name, jid):
gcc = jid.split('/')
if len(gcc) == 2:
contact = gajim.contacts.get_gc_contact(self.name, gcc[0], gcc[1])
......@@ -162,7 +164,8 @@ class ConnectionJingle(object):
elif contact.supports(nbxmpp.NS_JINGLE_IBB):
transport = JingleTransportIBB()
c = JingleFileTransfer(jingle, transport=transport,
file_props=file_props, use_security=use_security)
file_props=file_props,
use_security=use_security)
file_props.algo = self.__hash_support(contact)
jingle.add_content('file' + helpers.get_random_string_16(), c)
jingle.start_session()
......
......@@ -37,7 +37,7 @@ class JingleContentSetupException(Exception):
"""
class JingleContent(object):
class JingleContent:
"""
An abstraction of content in Jingle sessions
"""
......@@ -48,8 +48,8 @@ class JingleContent(object):
# will be filled by JingleSession.add_content()
# don't uncomment these lines, we will catch more buggy code then
# (a JingleContent not added to session shouldn't send anything)
#self.creator = None
#self.name = None
self.creator = None
self.name = None
self.accepted = False
self.sent = False
self.negotiated = False
......@@ -59,35 +59,39 @@ class JingleContent(object):
self.senders = 'both' #FIXME
self.allow_sending = True # Used for stream direction, attribute 'senders'
# These were found by the Politie
self.file_props = None
self.use_security = None
self.callbacks = {
# these are called when *we* get stanzas
'content-accept': [self.__on_transport_info,
self.__on_content_accept],
'content-add': [self.__on_transport_info],
'content-modify': [],
'content-reject': [],
'content-remove': [],
'description-info': [],
'security-info': [],
'session-accept': [self.__on_transport_info,
self.__on_content_accept],
'session-info': [],
'session-initiate': [self.__on_transport_info],
'session-terminate': [],
'transport-info': [self.__on_transport_info],
'transport-replace': [self.__on_transport_replace],
'transport-accept': [],
'transport-reject': [],
'iq-result': [],
'iq-error': [],
# these are called when *we* sent these stanzas
'content-accept-sent': [self.__fill_jingle_stanza,
self.__on_content_accept],
'content-add-sent': [self.__fill_jingle_stanza],
'session-initiate-sent': [self.__fill_jingle_stanza],
'session-accept-sent': [self.__fill_jingle_stanza,
self.__on_content_accept],
'session-terminate-sent': [],
# these are called when *we* get stanzas
'content-accept': [self.__on_transport_info,
self.__on_content_accept],
'content-add': [self.__on_transport_info],
'content-modify': [],
'content-reject': [],
'content-remove': [],
'description-info': [],
'security-info': [],
'session-accept': [self.__on_transport_info,
self.__on_content_accept],
'session-info': [],
'session-initiate': [self.__on_transport_info],
'session-terminate': [],
'transport-info': [self.__on_transport_info],
'transport-replace': [self.__on_transport_replace],
'transport-accept': [],
'transport-reject': [],
'iq-result': [],
'iq-error': [],
# these are called when *we* sent these stanzas
'content-accept-sent': [self.__fill_jingle_stanza,
self.__on_content_accept],
'content-add-sent': [self.__fill_jingle_stanza],
'session-initiate-sent': [self.__fill_jingle_stanza],
'session-accept-sent': [self.__fill_jingle_stanza,
self.__on_content_accept],
'session-terminate-sent': [],
}
def is_ready(self):
......@@ -134,8 +138,8 @@ class JingleContent(object):
if payload is None:
payload = []
return nbxmpp.Node('content',
attrs={'name': self.name, 'creator': self.creator},
payload=payload)
attrs={'name': self.name, 'creator': self.creator},
payload=payload)
def send_candidate(self, candidate):
"""
......@@ -191,17 +195,16 @@ class JingleContent(object):
file_tag.addChild(node=node)
if self.file_props.type_ == 'r':
if self.file_props.hash_:
h = file_tag.addChild('hash', attrs={
'algo': self.file_props.algo}, namespace=nbxmpp.NS_HASHES,
payload=self.file_props.hash_)
file_tag.addChild('hash', attrs={'algo': self.file_props.algo},
namespace=nbxmpp.NS_HASHES,
payload=self.file_props.hash_)
else:
# if the file is less than 10 mb, then it is small
# lets calculate it right away
if self.file_props.size < 10000000 and not \
self.file_props.hash_:
h = self._calcHash()
if h:
file_tag.addChild(node=h)
if self.file_props.size < 10000000 and not self.file_props.hash_:
hash_data = content._compute_hash()
if hash_data:
file_tag.addChild(node=hash_data)
pjid = gajim.get_jid_without_resource(self.session.peerjid)
file_info = {'name' : self.file_props.name,
'file-name' : self.file_props.file_name,
......@@ -223,9 +226,9 @@ class JingleContent(object):
cert = load_cert_file(certpath)
if cert:
try:
digest_algo = cert.get_signature_algorithm().decode('utf-8'
).split('With')[0]
except AttributeError as e:
digest_algo = (cert.get_signature_algorithm()
.decode('utf-8').split('With')[0])
except AttributeError:
# Old py-OpenSSL is missing get_signature_algorithm
digest_algo = "sha256"
security.addChild('fingerprint').addData(cert.digest(
......@@ -240,5 +243,3 @@ class JingleContent(object):
def destroy(self):
self.callbacks = None
del self.session.contents[(self.creator, self.name)]
......@@ -19,41 +19,47 @@
Handles Jingle File Transfer (XEP 0234)
"""
import os
import hashlib
from common import gajim
import logging
import os
import threading
from enum import IntEnum
import nbxmpp
from common import gajim
from common import configpaths
from . import jingle_xtls
from common import jingle_xtls
from common.jingle_content import contents, JingleContent
from common.jingle_transport import *
from common.jingle_transport import JingleTransportSocks5, TransportType
from common import helpers
from common.connection_handlers_events import FileRequestReceivedEvent
import threading
import logging
from common.jingle_ftstates import *
from common.jingle_ftstates import (
StateInitialized, StateCandSent, StateCandReceived, StateTransfering,
StateCandSentAndRecv, StateTransportReplace)
log = logging.getLogger('gajim.c.jingle_ft')
STATE_NOT_STARTED = 0
STATE_INITIALIZED = 1
# We send the candidates and we are waiting for a reply
STATE_CAND_SENT = 2
# We received the candidates and we are waiting to reply
STATE_CAND_RECEIVED = 3
# We have sent and received the candidates
# This also includes any candidate-error received or sent
STATE_CAND_SENT_AND_RECEIVED = 4
STATE_TRANSPORT_REPLACE = 5
# We are transfering the file
STATE_TRANSFERING = 6
class State(IntEnum):
NOT_STARTED = 0
INITIALIZED = 1
# We send the candidates and we are waiting for a reply
CAND_SENT = 2
# We received the candidates and we are waiting to reply
CAND_RECEIVED = 3
# We have sent and received the candidates
# This also includes any candidate-error received or sent
CAND_SENT_AND_RECEIVED = 4
TRANSPORT_REPLACE = 5
# We are transfering the file
TRANSFERING = 6
class JingleFileTransfer(JingleContent):
def __init__(self, session, transport=None, file_props=None,
use_security=False):
use_security=False):
JingleContent.__init__(self, session, transport)
log.info("transport value: %s" % transport)
log.info("transport value: %s", transport)
# events we might be interested in
self.callbacks['session-initiate'] += [self.__on_session_initiate]
self.callbacks['session-initiate-sent'] += [
......@@ -85,29 +91,31 @@ class JingleFileTransfer(JingleContent):
self.file_props.sid = session.sid
self.file_props.transfered_size = []
self.file_props.transport_sid = self.transport.sid
log.info("FT request: %s" % file_props)
log.info("FT request: %s", file_props)
if transport is None:
self.transport = JingleTransportSocks5()
self.transport.set_connection(session.connection)
self.transport.set_file_props(self.file_props)
self.transport.set_our_jid(session.ourjid)
log.info('ourjid: %s' % session.ourjid)
log.info('ourjid: %s', session.ourjid)
self.session = session
self.media = 'file'
self.nominated_cand = {}
if gajim.contacts.is_gc_contact(session.connection.name,
session.peerjid):
session.peerjid):
roomjid = session.peerjid.split('/')[0]
dstaddr = hashlib.sha1(('%s%s%s' % (self.file_props.sid,
session.ourjid, roomjid)).encode('utf-8')).hexdigest()
session.ourjid, roomjid))
.encode('utf-8')).hexdigest()
self.file_props.dstaddr = dstaddr
self.state = STATE_NOT_STARTED
self.states = {STATE_INITIALIZED : StateInitialized(self),
STATE_CAND_SENT : StateCandSent(self),
STATE_CAND_RECEIVED : StateCandReceived(self),
STATE_TRANSFERING : StateTransfering(self),
STATE_TRANSPORT_REPLACE : StateTransportReplace(self),
STATE_CAND_SENT_AND_RECEIVED : StateCandSentAndRecv(self)
self.state = State.NOT_STARTED
self.states = {
State.INITIALIZED : StateInitialized(self),
State.CAND_SENT : StateCandSent(self),
State.CAND_RECEIVED : StateCandReceived(self),
State.TRANSFERING : StateTransfering(self),
State.TRANSPORT_REPLACE : StateTransportReplace(self),
State.CAND_SENT_AND_RECEIVED : StateCandSentAndRecv(self)
}
if jingle_xtls.PYOPENSSL_PRESENT:
......@@ -129,8 +137,10 @@ class JingleFileTransfer(JingleContent):
def __on_session_initiate(self, stanza, content, error, action):
log.debug("Jingle FT request received")
gajim.nec.push_incoming_event(FileRequestReceivedEvent(None,
conn=self.session.connection, stanza=stanza, jingle_content=content,
FT_content=self))
conn=self.session.connection,
stanza=stanza,
jingle_content=content,
FT_content=self))
if self.session.request:
# accept the request
self.session.approve_content(self.media, self.name)
......@@ -141,10 +151,11 @@ class JingleFileTransfer(JingleContent):
def __send_hash(self):
# Send hash in a session info
checksum = nbxmpp.Node(tag='checksum', payload=[nbxmpp.Node(tag='file',
payload=[self._calcHash()])])
checksum = nbxmpp.Node(tag='checksum',
payload=[nbxmpp.Node(tag='file',
payload=[self._compute_hash()])])
checksum.setNamespace(nbxmpp.NS_JINGLE_FILE_TRANSFER)
self.session.__session_info(checksum )
self.session.__session_info(checksum)
pjid = gajim.get_jid_without_resource(self.session.peerjid)
file_info = {'name' : self.file_props.name,
'file-name' : self.file_props.file_name,
......@@ -155,13 +166,13 @@ class JingleFileTransfer(JingleContent):
}
self.session.connection.set_file_info(file_info)
def _calcHash(self):
def _compute_hash(self):
# Caculates the hash and returns a xep-300 hash stanza
if self.file_props.algo == None:
if self.file_props.algo is None:
return
try:
file_ = open(self.file_props.file_name, 'rb')
except:
except IOError:
# can't open file
return
h = nbxmpp.Hashes()
......@@ -192,30 +203,31 @@ class JingleFileTransfer(JingleContent):
fingerprint = fingerprint.getData()
self.x509_fingerprint = fingerprint
if not jingle_xtls.check_cert(gajim.get_jid_without_resource(
self.session.responder), fingerprint):
self.session.responder), fingerprint):
id_ = jingle_xtls.send_cert_request(con,
self.session.responder)
self.session.responder)
jingle_xtls.key_exchange_pend(id_,
self.continue_session_accept, [stanza])
self.continue_session_accept,
[stanza])
raise nbxmpp.NodeProcessed
self.continue_session_accept(stanza)
def continue_session_accept(self, stanza):
con = self.session.connection
if self.state == STATE_TRANSPORT_REPLACE:
if self.state == State.TRANSPORT_REPLACE:
# If we are requesting we don't have the file
if self.session.werequest:
raise nbxmpp.NodeProcessed
# We send the file
self.__state_changed(STATE_TRANSFERING)
self.__state_changed(State.TRANSFERING)
raise nbxmpp.NodeProcessed
self.file_props.streamhosts = self.transport.remote_candidates
# Calculate file hash in a new thread
# if we haven't sent the hash already.
if self.file_props.hash_ is None and self.file_props.algo and \
not self.werequest:
self.hashThread = threading.Thread(target=self.__send_hash)
self.hashThread.start()
not self.werequest:
self.hash_thread = threading.Thread(target=self.__send_hash)
self.hash_thread.start()
for host in self.file_props.streamhosts:
host['initiator'] = self.session.initiator
host['target'] = self.session.responder
......@@ -225,11 +237,13 @@ class JingleFileTransfer(JingleContent):
fingerprint = 'client'
if self.transport.type_ == TransportType.SOCKS5:
gajim.socks5queue.connect_to_hosts(self.session.connection.name,
self.file_props.sid, self.on_connect,
self._on_connect_error, fingerprint=fingerprint,
receiving=False)
self.file_props.sid,
self.on_connect,
self._on_connect_error,
fingerprint=fingerprint,
receiving=False)
raise nbxmpp.NodeProcessed
self.__state_changed(STATE_TRANSFERING)
self.__state_changed(State.TRANSFERING)
raise nbxmpp.NodeProcessed
def __on_session_terminate(self, stanza, content, error, action):
......@@ -249,78 +263,78 @@ class JingleFileTransfer(JingleContent):
def __on_transport_info(self, stanza, content, error, action):
log.info("__on_transport_info")
candError = content.getTag('transport').getTag('candidate-error')
candUsed = content.getTag('transport').getTag('candidate-used')
if (candError or candUsed) and \
self.state >= STATE_CAND_SENT_AND_RECEIVED:
cand_error = content.getTag('transport').getTag('candidate-error')
cand_used = content.getTag('transport').getTag('candidate-used')
if (cand_error or cand_used) and \
self.state >= State.CAND_SENT_AND_RECEIVED:
raise nbxmpp.NodeProcessed
if candError:
if cand_error:
if not gajim.socks5queue.listener.connections:
gajim.socks5queue.listener.disconnect()
self.nominated_cand['peer-cand'] = False
if self.state == STATE_CAND_SENT:
if self.state == State.CAND_SENT:
if not self.nominated_cand['our-cand'] and \
not self.nominated_cand['peer-cand']:
if not self.weinitiate:
return
self.__state_changed(STATE_TRANSPORT_REPLACE)
self.__state_changed(State.TRANSPORT_REPLACE)
else:
response = stanza.buildReply('result')
response.delChild(response.getQuery())
self.session.connection.connection.send(response)
self.__state_changed(STATE_TRANSFERING)
self.__state_changed(State.TRANSFERING)
raise nbxmpp.NodeProcessed
else:
args = {'candError' : True}
self.__state_changed(STATE_CAND_RECEIVED, args)
args = {'cand_error' : True}
self.__state_changed(State.CAND_RECEIVED, args)
return
if candUsed:
streamhost_cid = candUsed.getAttr('cid')
if cand_used:
streamhost_cid = cand_used.getAttr('cid')
streamhost_used = None
for cand in self.transport.candidates:
if cand['candidate_id'] == streamhost_cid:
streamhost_used = cand
break
if streamhost_used == None or streamhost_used['type'] == 'proxy':
if streamhost_used is None or streamhost_used['type'] == 'proxy':
if gajim.socks5queue.listener and \
not gajim.socks5queue.listener.connections:
gajim.socks5queue.listener.disconnect()
if content.getTag('transport').getTag('activated'):
self.state = STATE_TRANSFERING
self.state = State.TRANSFERING
jid = gajim.get_jid_without_resource(self.session.ourjid)
gajim.socks5queue.send_file(self.file_props,
self.session.connection.name, 'client')
self.session.connection.name, 'client')
return
args = {'content' : content,
'sendCand' : False}
if self.state == STATE_CAND_SENT:
self.__state_changed(STATE_CAND_SENT_AND_RECEIVED, args)
self.__state_changed(STATE_TRANSFERING)
args = {'content': content,
'sendCand': False}
if self.state == State.CAND_SENT:
self.__state_changed(State.CAND_SENT_AND_RECEIVED, args)
self.__state_changed(State.TRANSFERING)
raise nbxmpp.NodeProcessed
else:
self.__state_changed(STATE_CAND_RECEIVED, args)
self.__state_changed(State.CAND_RECEIVED, args)
def __on_iq_result(self, stanza, content, error, action):
log.info("__on_iq_result")
if self.state == STATE_NOT_STARTED:
self.__state_changed(STATE_INITIALIZED)
elif self.state == STATE_CAND_SENT_AND_RECEIVED:
if self.state == State.NOT_STARTED:
self.__state_changed(State.INITIALIZED)
elif self.state == State.CAND_SENT_AND_RECEIVED:
if not self.nominated_cand['our-cand'] and \
not self.nominated_cand['peer-cand']:
if not self.weinitiate:
return
self.__state_changed(STATE_TRANSPORT_REPLACE)
self.__state_changed(State.TRANSPORT_REPLACE)
return
# initiate transfer
self.__state_changed(STATE_TRANSFERING)
self.__state_changed(State.TRANSFERING)
def __transport_setup(self, stanza=None, content=None, error=None,
action=None):
action=None):
# Sets up a few transport specific things for the file transfer
if self.transport.type_ == TransportType.IBB:
# No action required, just set the state to transfering
self.state = STATE_TRANSFERING
self.state = State.TRANSFERING
else:
self._listen_host()
......@@ -334,19 +348,19 @@ class JingleFileTransfer(JingleContent):
args = {'streamhost' : streamhost,
'sendCand' : True}
self.nominated_cand['our-cand'] = streamhost
self.__sendCand(args)
self.__send_candidate(args)
def _on_connect_error(self, sid):
log.info('connect error, sid=' + sid)
args = {'candError' : True,
'sendCand' : True}
self.__sendCand(args)
self.__send_candidate(args)
def __sendCand(self, args):
if self.state == STATE_CAND_RECEIVED:
self.__state_changed(STATE_CAND_SENT_AND_RECEIVED, args)
def __send_candidate(self, args):
if self.state == State.CAND_RECEIVED:
self.__state_changed(State.CAND_SENT_AND_RECEIVED, args)
else:
self.__state_changed(STATE_CAND_SENT, args)
self.__state_changed(State.CAND_SENT, args)
def _store_socks5_sid(self, sid, hash_id):
# callback from socsk5queue.start_listener
......@@ -356,44 +370,40 @@ class JingleFileTransfer(JingleContent):
receiver = self.file_props.receiver
sender = self.file_props.sender
sha_str = helpers.get_auth_sha(self.file_props.sid, sender,
receiver)
receiver)
self.file_props.sha_str = sha_str
port = gajim.config.get('file_transfers_port')
fingerprint = None
if self.use_security:
fingerprint = 'server'
if self.weinitiate:
listener = gajim.socks5queue.start_listener(port, sha_str,
self._store_socks5_sid, self.file_props,
fingerprint=fingerprint, typ='sender')
else:
listener = gajim.socks5queue.start_listener(port, sha_str,
self._store_socks5_sid, self.file_props,
fingerprint=fingerprint, typ='receiver')
listener = gajim.socks5queue.start_listener(port, sha_str,
self._store_socks5_sid,
self.file_props,
fingerprint=fingerprint,
typ='sender' if self.weinitiate else 'receiver')
if not listener:
# send error message, notify the user
return
def isOurCandUsed(self):
def is_our_candidate_used(self):
'''
If this method returns true then the candidate we nominated will be
used, if false, the candidate nominated by peer will be used
'''
if self.nominated_cand['peer-cand'] == False:
if not self.nominated_cand['peer-cand']:
return True
if self.nominated_cand['our-cand'] == False:
if not self.nominated_cand['our-cand']:
return False
peer_pr = int(self.nominated_cand['peer-cand']['priority'])
our_pr = int(self.nominated_cand['our-cand']['priority'])
if peer_pr != our_pr:
return our_pr > peer_pr
else:
return self.weinitiate
return self.weinitiate
def start_IBB_transfer(self):
def start_ibb_transfer(self):
if self.file_props.type_ == 's':
self.__state_changed(STATE_TRANSFERING)
self.__state_changed(State.TRANSFERING)
def get_content(desc):
......
......@@ -13,11 +13,14 @@
## You should have received a copy of the GNU General Public License
## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
from common import gajim
import nbxmpp
from common.jingle_transport import *
from common import gajim
from common.jingle_transport import TransportType
from common.socks5 import Socks5ReceiverClient, Socks5SenderClient
import logging
log = logging.getLogger('gajim.c.jingle_ftstates')
class JingleFileTransferStates:
'''
......@@ -31,7 +34,7 @@ class JingleFileTransferStates:
'''
This method MUST be overriden by a subclass
'''
raise Exception('This is an abstract method!!')
raise NotImplementedError('This is an abstract method!')
class StateInitialized(JingleFileTransferStates):
......@@ -50,8 +53,10 @@ class StateInitialized(JingleFileTransferStates):
fingerprint = 'client'
# Connect to the candidate host, on success call on_connect method
gajim.socks5queue.connect_to_hosts(self.jft.session.connection.name,
self.jft.file_props.sid, self.jft.on_connect,
self.jft._on_connect_error, fingerprint=fingerprint)
self.jft.file_props.sid,
self.jft.on_connect,
self.jft._on_connect_error,
fingerprint=fingerprint)
class StateCandSent(JingleFileTransferStates):
......@@ -59,7 +64,7 @@ class StateCandSent(JingleFileTransferStates):
This state sends our nominated candidate
'''
def _sendCand(self, args):
def _send_candidate(self, args):
if 'candError' in args:
self.jft.nominated_cand['our-cand'] = False
self.jft.send_error_candidate()
......@@ -80,16 +85,16 @@ class StateCandSent(JingleFileTransferStates):
self.jft.session.send_transport_info(content)
def action(self, args=None):
self._sendCand(args)
self._send_candidate(args)
class StateCandReceived(JingleFileTransferStates):
class StateCandReceived(JingleFileTransferStates):
'''
This state happens when we receive a candidate.
It takes the arguments: canError if we receive a candidate-error
'''
def _recvCand(self, args):
def _recv_candidate(self, args):
if 'candError' in args:
return
content = args['content']
......@@ -100,17 +105,17 @@ class StateCandReceived(JingleFileTransferStates):
if cand['candidate_id'] == streamhost_cid:
streamhost_used = cand
break
if streamhost_used == None:
if streamhost_used is None:
log.info("unknow streamhost")
return
# We save the candidate nominated by peer
self.jft.nominated_cand['peer-cand'] = streamhost_used
def action(self, args=None):