coding standards, and other few things

This commit is contained in:
Thibaut GIRKA 2009-09-19 17:24:59 +02:00
parent 6b99db8980
commit c162780a58
3 changed files with 122 additions and 125 deletions

View File

@ -1775,7 +1775,7 @@ class ChatControl(ChatControlBase, ChatCommands):
self.set_audio_state('connecting', sid) self.set_audio_state('connecting', sid)
def on_stop_audio_button_activate(self, *things): def on_stop_audio_button_activate(self, *things):
session = gajim.connections[self.account].getJingleSession( session = gajim.connections[self.account].get_jingle_session(
self.contact.get_full_jid(), self.audio_sid) self.contact.get_full_jid(), self.audio_sid)
if session: if session:
session.end_session() session.end_session()

View File

@ -50,7 +50,6 @@
# * handle different kinds of sink and src elements # * handle different kinds of sink and src elements
import gajim import gajim
import gobject
import xmpp import xmpp
import farsight, gst import farsight, gst
@ -65,9 +64,9 @@ def get_first_gst_element(elements):
#FIXME: Move it to JingleSession.States? #FIXME: Move it to JingleSession.States?
class JingleStates(object): class JingleStates(object):
''' States in which jingle session may exist. ''' ''' States in which jingle session may exist. '''
ended=0 ended = 0
pending=1 pending = 1
active=2 active = 2
#FIXME: Move it to JingleTransport.Type? #FIXME: Move it to JingleTransport.Type?
class TransportType(object): class TransportType(object):
@ -75,9 +74,6 @@ class TransportType(object):
datagram = 1 datagram = 1
streaming = 2 streaming = 2
class Error(Exception): pass
class WrongState(Error): pass
class OutOfOrder(Exception): class OutOfOrder(Exception):
''' Exception that should be raised when an action is received when in the wrong state. ''' ''' Exception that should be raised when an action is received when in the wrong state. '''
@ -110,7 +106,7 @@ class JingleSession(object):
# callbacks to call on proper contents # callbacks to call on proper contents
# use .prepend() to add new callbacks, especially when you're going # use .prepend() to add new callbacks, especially when you're going
# to send error instead of ack # to send error instead of ack
self.callbacks={ self.callbacks = {
'content-accept': [self.__contentAcceptCB, self.__defaultCB], 'content-accept': [self.__contentAcceptCB, self.__defaultCB],
'content-add': [self.__defaultCB], #TODO 'content-add': [self.__defaultCB], #TODO
'content-modify': [self.__defaultCB], #TODO 'content-modify': [self.__defaultCB], #TODO
@ -134,39 +130,37 @@ class JingleSession(object):
} }
''' Interaction with user ''' ''' Interaction with user '''
def approveSession(self): def approve_session(self):
''' Called when user accepts session in UI (when we aren't the initiator). ''' Called when user accepts session in UI (when we aren't the initiator).
''' '''
self.accepted = True self.accepted = True
self.acceptSession() self.accept_session()
def declineSession(self): def decline_session(self):
''' Called when user declines session in UI (when we aren't the initiator) ''' Called when user declines session in UI (when we aren't the initiator)
''' '''
reason = xmpp.Node('reason') reason = xmpp.Node('reason')
reason.addChild('decline') reason.addChild('decline')
self.__sessionTerminate(reason) self.__session_terminate(reason)
def end_session(self): def end_session(self):
''' Called when user stops or cancel session in UI. '''
reason = xmpp.Node('reason') reason = xmpp.Node('reason')
if self.state == JingleStates.active: if self.state == JingleStates.active:
reason.addChild('success') reason.addChild('success')
else: else:
reason.addChild('cancel') reason.addChild('cancel')
self.__sessionTerminate(reason) self.__session_terminate(reason)
''' Middle-level functions to manage contents. Handle local content ''' Middle-level functions to manage contents. Handle local content
cache and send change notifications. ''' cache and send change notifications. '''
def addContent(self, name, content, creator='we'): def add_content(self, name, content, creator='we'):
''' Add new content to session. If the session is active, ''' Add new content to session. If the session is active,
this will send proper stanza to update session. this will send proper stanza to update session.
The protocol prohibits changing that when pending. The protocol prohibits changing that when pending.
Creator must be one of ('we', 'peer', 'initiator', 'responder')''' Creator must be one of ('we', 'peer', 'initiator', 'responder')'''
assert creator in ('we', 'peer', 'initiator', 'responder') assert creator in ('we', 'peer', 'initiator', 'responder')
if self.state == JingleStates.pending:
raise WrongState
if (creator == 'we' and self.weinitiate) or (creator == 'peer' and \ if (creator == 'we' and self.weinitiate) or (creator == 'peer' and \
not self.weinitiate): not self.weinitiate):
creator = 'initiator' creator = 'initiator'
@ -175,47 +169,50 @@ class JingleSession(object):
creator = 'responder' creator = 'responder'
content.creator = creator content.creator = creator
content.name = name content.name = name
self.contents[(creator,name)] = content self.contents[(creator, name)] = content
if self.state == JingleStates.active: if self.state == JingleStates.active:
pass # TODO: send proper stanza, shouldn't be needed now pass # TODO: send proper stanza, shouldn't be needed now
def removeContent(self, creator, name): def remove_content(self, creator, name):
''' We do not need this now ''' ''' We do not need this now '''
pass pass
def modifyContent(self, creator, name, *someother): def modify_content(self, creator, name, *someother):
''' We do not need this now ''' ''' We do not need this now '''
pass pass
def acceptSession(self): def accept_session(self):
''' Check if all contents and user agreed to start session. ''' ''' Check if all contents and user agreed to start session. '''
if not self.weinitiate and self.accepted and \ if not self.weinitiate and self.accepted and \
self.state == JingleStates.pending and self.is_ready(): self.state == JingleStates.pending and self.is_ready():
self.__sessionAccept() self.__session_accept()
def is_ready(self): def is_ready(self):
''' Returns True when all codecs and candidates are ready
(for all contents). '''
return all((c.candidates_ready and c.p2psession.get_property('codecs-ready') return all((c.candidates_ready and c.p2psession.get_property('codecs-ready')
for c in self.contents.itervalues())) for c in self.contents.itervalues()))
''' Middle-level function to do stanza exchange. ''' ''' Middle-level function to do stanza exchange. '''
def startSession(self): def start_session(self):
''' Start session. ''' ''' Start session. '''
#FIXME: Start only once #FIXME: Start only once
if self.weinitiate and self.state == JingleStates.ended and self.is_ready(): if self.weinitiate and self.state == JingleStates.ended and self.is_ready():
self.__sessionInitiate() self.__session_initiate()
def sendSessionInfo(self): pass def send_session_info(self):
pass
def sendContentAccept(self, content): def send_content_accept(self, content):
assert self.state != JingleStates.ended assert self.state != JingleStates.ended
stanza, jingle = self.__makeJingle('content-accept') stanza, jingle = self.__make_jingle('content-accept')
jingle.addChild(node=content) jingle.addChild(node=content)
self.connection.connection.send(stanza) self.connection.connection.send(stanza)
def sendTransportInfo(self, content): def send_transport_info(self, content):
assert self.state!=JingleStates.ended assert self.state != JingleStates.ended
stanza, jingle = self.__makeJingle('transport-info') stanza, jingle = self.__make_jingle('transport-info')
jingle.addChild(node=content) jingle.addChild(node=content)
self.connection.connection.send(stanza) self.connection.connection.send(stanza)
@ -272,7 +269,7 @@ class JingleSession(object):
self.__dispatch_error(xmpp_error, jingle_error, text) self.__dispatch_error(xmpp_error, jingle_error, text)
#FIXME: Not sure when we would want to do that... #FIXME: Not sure when we would want to do that...
if xmpp_error == 'item-not-found': if xmpp_error == 'item-not-found':
self.connection.deleteJingle(self) self.connection.delete_jingle(self)
def __transportReplaceCB(self, stanza, jingle, error, action): def __transportReplaceCB(self, stanza, jingle, error, action):
for content in jingle.iterTags('content'): for content in jingle.iterTags('content'):
@ -286,16 +283,16 @@ class JingleSession(object):
#Anyway, content's transport is not modifiable yet #Anyway, content's transport is not modifiable yet
pass pass
else: else:
stanza, jingle = self.__makeJingle('transport-reject') stanza, jingle = self.__make_jingle('transport-reject')
c = jingle.setTag('content', attrs={'creator': creator, content = jingle.setTag('content', attrs={'creator': creator,
'name': name}) 'name': name})
c.setTag('transport', namespace=transport_ns) content.setTag('transport', namespace=transport_ns)
self.connection.connection.send(stanza) self.connection.connection.send(stanza)
raise xmpp.NodeProcessed raise xmpp.NodeProcessed
else: else:
#FIXME: This ressource is unknown to us, what should we do? #FIXME: This ressource is unknown to us, what should we do?
#For now, reject the transport #For now, reject the transport
stanza, jingle = self.__makeJingle('transport-reject') stanza, jingle = self.__make_jingle('transport-reject')
c = jingle.setTag('content', attrs={'creator': creator, c = jingle.setTag('content', attrs={'creator': creator,
'name': name}) 'name': name})
c.setTag('transport', namespace=transport_ns) c.setTag('transport', namespace=transport_ns)
@ -317,7 +314,7 @@ class JingleSession(object):
if len(self.contents) == 0: if len(self.contents) == 0:
reason = xmpp.Node('reason') reason = xmpp.Node('reason')
reason.setTag('success') #FIXME: Is it the good one? reason.setTag('success') #FIXME: Is it the good one?
self.__sessionTerminate(reason) self.__session_terminate(reason)
def __sessionAcceptCB(self, stanza, jingle, error, action): def __sessionAcceptCB(self, stanza, jingle, error, action):
if self.state != JingleStates.pending: #FIXME if self.state != JingleStates.pending: #FIXME
@ -363,9 +360,9 @@ class JingleSession(object):
if tran_ns == xmpp.NS_JINGLE_ICE_UDP: if tran_ns == xmpp.NS_JINGLE_ICE_UDP:
# we've got voip content # we've got voip content
if media == 'audio': if media == 'audio':
self.addContent(element['name'], JingleVoIP(self), 'peer') self.add_content(element['name'], JingleVoIP(self), 'peer')
else: else:
self.addContent(element['name'], JingleVideo(self), 'peer') self.add_content(element['name'], JingleVideo(self), 'peer')
contents.append((media,)) contents.append((media,))
transports_ok = True transports_ok = True
@ -375,7 +372,7 @@ class JingleSession(object):
reason = xmpp.Node('reason') reason = xmpp.Node('reason')
reason.setTag('unsupported-applications') reason.setTag('unsupported-applications')
self.__defaultCB(stanza, jingle, error, action) self.__defaultCB(stanza, jingle, error, action)
self.__sessionTerminate(reason) self.__session_terminate(reason)
raise xmpp.NodeProcessed raise xmpp.NodeProcessed
if not transports_ok: if not transports_ok:
@ -383,7 +380,7 @@ class JingleSession(object):
reason = xmpp.Node('reason') reason = xmpp.Node('reason')
reason.setTag('unsupported-transports') reason.setTag('unsupported-transports')
self.__defaultCB(stanza, jingle, error, action) self.__defaultCB(stanza, jingle, error, action)
self.__sessionTerminate(reason) self.__session_terminate(reason)
raise xmpp.NodeProcessed raise xmpp.NodeProcessed
self.state = JingleStates.pending self.state = JingleStates.pending
@ -401,7 +398,7 @@ class JingleSession(object):
cn.stanzaCB(stanza, content, error, action) cn.stanzaCB(stanza, content, error, action)
def __sessionTerminateCB(self, stanza, jingle, error, action): def __sessionTerminateCB(self, stanza, jingle, error, action):
self.connection.deleteJingle(self) self.connection.delete_jingle(self)
reason, text = self.__reason_from_stanza(jingle) reason, text = self.__reason_from_stanza(jingle)
if reason not in ('success', 'cancel', 'decline'): if reason not in ('success', 'cancel', 'decline'):
self.__dispatch_error(reason, reason, text) self.__dispatch_error(reason, reason, text)
@ -411,6 +408,11 @@ class JingleSession(object):
text = reason#TODO text = reason#TODO
self.connection.dispatch('JINGLE_DISCONNECTED', (self.peerjid, self.sid, text)) self.connection.dispatch('JINGLE_DISCONNECTED', (self.peerjid, self.sid, text))
def __broadcastAllCB(self, stanza, jingle, error, action):
''' Broadcast the stanza to all content handlers. '''
for content in self.contents.itervalues():
content.stanzaCB(stanza, None, error, action)
def __send_error(self, stanza, error, jingle_error=None, text=None): def __send_error(self, stanza, error, jingle_error=None, text=None):
err = xmpp.Error(stanza, error) err = xmpp.Error(stanza, error)
err.setNamespace(xmpp.NS_STANZAS) err.setNamespace(xmpp.NS_STANZAS)
@ -430,11 +432,6 @@ class JingleSession(object):
text = error text = error
self.connection.dispatch('JINGLE_ERROR', (self.peerjid, self.sid, text)) self.connection.dispatch('JINGLE_ERROR', (self.peerjid, self.sid, text))
def __broadcastAllCB(self, stanza, jingle, error, action):
''' Broadcast the stanza to all content handlers. '''
for content in self.contents.itervalues():
content.stanzaCB(stanza, None, error, action)
def __reason_from_stanza(self, stanza): def __reason_from_stanza(self, stanza):
reason = 'success' reason = 'success'
reasons = ['success', 'busy', 'cancel', 'connectivity-error', reasons = ['success', 'busy', 'cancel', 'connectivity-error',
@ -453,7 +450,7 @@ class JingleSession(object):
''' Methods that make/send proper pieces of XML. They check if the session ''' Methods that make/send proper pieces of XML. They check if the session
is in appropriate state. ''' is in appropriate state. '''
def __makeJingle(self, action): def __make_jingle(self, action):
stanza = xmpp.Iq(typ='set', to=xmpp.JID(self.peerjid)) stanza = xmpp.Iq(typ='set', to=xmpp.JID(self.peerjid))
attrs = {'action': action, attrs = {'action': action,
'sid': self.sid} 'sid': self.sid}
@ -464,46 +461,46 @@ class JingleSession(object):
jingle = stanza.addChild('jingle', attrs=attrs, namespace=xmpp.NS_JINGLE) jingle = stanza.addChild('jingle', attrs=attrs, namespace=xmpp.NS_JINGLE)
return stanza, jingle return stanza, jingle
def __appendContent(self, jingle, content): def __append_content(self, jingle, content):
''' Append <content/> element to <jingle/> element, ''' Append <content/> element to <jingle/> element,
with (full=True) or without (full=False) <content/> with (full=True) or without (full=False) <content/>
children. ''' children. '''
jingle.addChild('content', jingle.addChild('content',
attrs={'name': content.name, 'creator': content.creator}) attrs={'name': content.name, 'creator': content.creator})
def __appendContents(self, jingle): def __append_contents(self, jingle):
''' Append all <content/> elements to <jingle/>.''' ''' Append all <content/> elements to <jingle/>.'''
# TODO: integrate with __appendContent? # TODO: integrate with __appendContent?
# TODO: parameters 'name', 'content'? # TODO: parameters 'name', 'content'?
for content in self.contents.values(): for content in self.contents.values():
self.__appendContent(jingle, content) self.__append_content(jingle, content)
def __sessionInitiate(self): def __session_initiate(self):
assert self.state==JingleStates.ended assert self.state == JingleStates.ended
stanza, jingle = self.__makeJingle('session-initiate') stanza, jingle = self.__make_jingle('session-initiate')
self.__appendContents(jingle) self.__append_contents(jingle)
self.__broadcastCB(stanza, jingle, None, 'session-initiate-sent') self.__broadcastCB(stanza, jingle, None, 'session-initiate-sent')
self.connection.connection.send(stanza) self.connection.connection.send(stanza)
self.state = JingleStates.pending self.state = JingleStates.pending
def __sessionAccept(self): def __session_accept(self):
assert self.state==JingleStates.pending assert self.state == JingleStates.pending
stanza, jingle = self.__makeJingle('session-accept') stanza, jingle = self.__make_jingle('session-accept')
self.__appendContents(jingle) self.__append_contents(jingle)
self.__broadcastCB(stanza, jingle, None, 'session-accept-sent') self.__broadcastCB(stanza, jingle, None, 'session-accept-sent')
self.connection.connection.send(stanza) self.connection.connection.send(stanza)
self.state = JingleStates.active self.state = JingleStates.active
def __sessionInfo(self, payload=None): def __session_info(self, payload=None):
assert self.state != JingleStates.ended assert self.state != JingleStates.ended
stanza, jingle = self.__makeJingle('session-info') stanza, jingle = self.__make_jingle('session-info')
if payload: if payload:
jingle.addChild(node=payload) jingle.addChild(node=payload)
self.connection.connection.send(stanza) self.connection.connection.send(stanza)
def __sessionTerminate(self, reason=None): def __session_terminate(self, reason=None):
assert self.state != JingleStates.ended assert self.state != JingleStates.ended
stanza, jingle = self.__makeJingle('session-terminate') stanza, jingle = self.__make_jingle('session-terminate')
if reason is not None: if reason is not None:
jingle.addChild(node=reason) jingle.addChild(node=reason)
self.__broadcastAllCB(stanza, jingle, None, 'session-terminate-sent') self.__broadcastAllCB(stanza, jingle, None, 'session-terminate-sent')
@ -516,29 +513,29 @@ class JingleSession(object):
else: else:
text = reason text = reason
self.connection.dispatch('JINGLE_DISCONNECTED', (self.peerjid, self.sid, text)) self.connection.dispatch('JINGLE_DISCONNECTED', (self.peerjid, self.sid, text))
self.connection.deleteJingle(self) self.connection.delete_jingle(self)
def __contentAdd(self): def __content_add(self):
assert self.state == JingleStates.active assert self.state == JingleStates.active
def __contentAccept(self): def __content_accept(self):
assert self.state != JingleStates.ended assert self.state != JingleStates.ended
def __contentModify(self): def __content_modify(self):
assert self.state != JingleStates.ended assert self.state != JingleStates.ended
def __contentRemove(self): def __content_remove(self):
assert self.state != JingleStates.ended assert self.state != JingleStates.ended
def content_negociated(self, media): def content_negociated(self, media):
self.connection.dispatch('JINGLE_CONNECTED', (self.peerjid, self.sid, self.connection.dispatch('JINGLE_CONNECTED', (self.peerjid, self.sid,
media)) media))
class JingleTransport(object): #TODO:
''' An abstraction of a transport in Jingle sessions. ''' #class JingleTransport(object):
#TODO: Complete # ''' An abstraction of a transport in Jingle sessions. '''
def __init__(self): # def __init__(self):
pass#TODO: Complete # pass
class JingleContent(object): class JingleContent(object):
@ -595,7 +592,7 @@ class JingleContent(object):
cand.priority = int(candidate['priority']) cand.priority = int(candidate['priority'])
if candidate['protocol'] == 'udp': if candidate['protocol'] == 'udp':
cand.proto=farsight.NETWORK_PROTOCOL_UDP cand.proto = farsight.NETWORK_PROTOCOL_UDP
else: else:
# we actually don't handle properly different tcp options in jingle # we actually don't handle properly different tcp options in jingle
cand.proto = farsight.NETWORK_PROTOCOL_TCP cand.proto = farsight.NETWORK_PROTOCOL_TCP
@ -629,7 +626,7 @@ class JingleContent(object):
farsight.CANDIDATE_TYPE_PRFLX: 'prlfx', farsight.CANDIDATE_TYPE_PRFLX: 'prlfx',
farsight.CANDIDATE_TYPE_RELAY: 'relay', farsight.CANDIDATE_TYPE_RELAY: 'relay',
farsight.CANDIDATE_TYPE_MULTICAST: 'multicast'} farsight.CANDIDATE_TYPE_MULTICAST: 'multicast'}
attrs={ attrs = {
'component': candidate.component_id, 'component': candidate.component_id,
'foundation': '1', # hack 'foundation': '1', # hack
'generation': '0', 'generation': '0',
@ -640,26 +637,27 @@ class JingleContent(object):
} }
if candidate.type in types: if candidate.type in types:
attrs['type'] = types[candidate.type] attrs['type'] = types[candidate.type]
if candidate.proto==farsight.NETWORK_PROTOCOL_UDP: if candidate.proto == farsight.NETWORK_PROTOCOL_UDP:
attrs['protocol'] = 'udp' attrs['protocol'] = 'udp'
else: else:
# we actually don't handle properly different tcp options in jingle # we actually don't handle properly different tcp options in jingle
attrs['protocol'] = 'tcp' attrs['protocol'] = 'tcp'
return xmpp.Node('candidate', attrs=attrs) return xmpp.Node('candidate', attrs=attrs)
def iterCandidates(self): def iter_candidates(self):
for candidate in self.candidates: for candidate in self.candidates:
yield self.__candidate(candidate) yield self.__candidate(candidate)
def send_candidate(self, candidate): def send_candidate(self, candidate):
c = self.__content() content = self.__content()
t = c.addChild(xmpp.NS_JINGLE_ICE_UDP + ' transport') transport = content.addChild(xmpp.NS_JINGLE_ICE_UDP + ' transport')
if candidate.username: t['ufrag'] = candidate.username if candidate.username and candidate.password:
if candidate.password: t['pwd'] = candidate.password transport['ufrag'] = candidate.username
transport['pwd'] = candidate.password
t.addChild(node=self.__candidate(candidate)) transport.addChild(node=self.__candidate(candidate))
self.session.sendTransportInfo(c) self.session.send_transport_info(content)
def __fillJingleStanza(self, stanza, content, error, action): def __fillJingleStanza(self, stanza, content, error, action):
''' Add our things to session-initiate stanza. ''' ''' Add our things to session-initiate stanza. '''
@ -672,7 +670,7 @@ class JingleContent(object):
else: else:
attrs = {} attrs = {}
content.addChild(xmpp.NS_JINGLE_ICE_UDP + ' transport', attrs=attrs, content.addChild(xmpp.NS_JINGLE_ICE_UDP + ' transport', attrs=attrs,
payload=self.iterCandidates()) payload=self.iter_candidates())
class JingleRTPContent(JingleContent): class JingleRTPContent(JingleContent):
def __init__(self, session, media, node=None): def __init__(self, session, media, node=None):
@ -690,7 +688,7 @@ class JingleRTPContent(JingleContent):
self.callbacks['session-terminate'] += [self.__stop] self.callbacks['session-terminate'] += [self.__stop]
self.callbacks['session-terminate-sent'] += [self.__stop] self.callbacks['session-terminate-sent'] += [self.__stop]
def setupStream(self): def setup_stream(self):
# pipeline and bus # pipeline and bus
self.pipeline = gst.Pipeline() self.pipeline = gst.Pipeline()
bus = self.pipeline.get_bus() bus = self.pipeline.get_bus()
@ -714,7 +712,7 @@ class JingleRTPContent(JingleContent):
def _fillContent(self, content): def _fillContent(self, content):
content.addChild(xmpp.NS_JINGLE_RTP + ' description', content.addChild(xmpp.NS_JINGLE_RTP + ' description',
attrs={'media': self.media}, payload=self.iterCodecs()) attrs={'media': self.media}, payload=self.iter_codecs())
def _on_gst_message(self, bus, message): def _on_gst_message(self, bus, message):
if message.type == gst.MESSAGE_ELEMENT: if message.type == gst.MESSAGE_ELEMENT:
@ -725,12 +723,12 @@ class JingleRTPContent(JingleContent):
elif name == 'farsight-recv-codecs-changed': elif name == 'farsight-recv-codecs-changed':
pass pass
elif name == 'farsight-codecs-changed': elif name == 'farsight-codecs-changed':
self.session.acceptSession() self.session.accept_session()
self.session.startSession() self.session.start_session()
elif name == 'farsight-local-candidates-prepared': elif name == 'farsight-local-candidates-prepared':
self.candidates_ready = True self.candidates_ready = True
self.session.acceptSession() self.session.accept_session()
self.session.startSession() self.session.start_session()
elif name == 'farsight-new-local-candidate': elif name == 'farsight-new-local-candidate':
candidate = message.structure['candidate'] candidate = message.structure['candidate']
self.candidates.append(candidate) self.candidates.append(candidate)
@ -746,8 +744,8 @@ class JingleRTPContent(JingleContent):
self.p2pstream.set_property('direction', farsight.DIRECTION_BOTH) self.p2pstream.set_property('direction', farsight.DIRECTION_BOTH)
self.session.content_negociated(self.media) self.session.content_negociated(self.media)
#if not self.session.weinitiate: #FIXME: one more FIXME... #if not self.session.weinitiate: #FIXME: one more FIXME...
# self.session.sendContentAccept(self.__content((xmpp.Node( # self.session.send_content_accept(self.__content((xmpp.Node(
# 'description', payload=self.iterCodecs()),))) # 'description', payload=self.iter_codecs()),)))
elif name == 'farsight-error': elif name == 'farsight-error':
print 'Farsight error #%d!' % message.structure['error-no'] print 'Farsight error #%d!' % message.structure['error-no']
print 'Message: %s' % message.structure['error-msg'] print 'Message: %s' % message.structure['error-msg']
@ -757,7 +755,8 @@ class JingleRTPContent(JingleContent):
def __getRemoteCodecsCB(self, stanza, content, error, action): def __getRemoteCodecsCB(self, stanza, content, error, action):
''' Get peer codecs from what we get from peer. ''' ''' Get peer codecs from what we get from peer. '''
if self.got_codecs: return if self.got_codecs:
return
codecs = [] codecs = []
for codec in content.getTag('description').iterTags('payload-type'): for codec in content.getTag('description').iterTags('payload-type'):
@ -770,26 +769,27 @@ class JingleRTPContent(JingleContent):
c.optional_params = [(str(p['name']), str(p['value'])) for p in \ c.optional_params = [(str(p['name']), str(p['value'])) for p in \
codec.iterTags('parameter')] codec.iterTags('parameter')]
codecs.append(c) codecs.append(c)
if len(codecs) == 0: return
#FIXME: Handle this case: if len(codecs) > 0:
# glib.GError: There was no intersection between the remote codecs and #FIXME: Handle this case:
# the local ones # glib.GError: There was no intersection between the remote codecs and
self.p2pstream.set_remote_codecs(codecs) # the local ones
self.got_codecs = True self.p2pstream.set_remote_codecs(codecs)
self.got_codecs = True
def iterCodecs(self): def iter_codecs(self):
codecs=self.p2psession.get_property('codecs') codecs = self.p2psession.get_property('codecs')
for codec in codecs: for codec in codecs:
a = {'name': codec.encoding_name, attrs = {'name': codec.encoding_name,
'id': codec.id, 'id': codec.id,
'channels': codec.channels} 'channels': codec.channels}
if codec.clock_rate: a['clockrate']=codec.clock_rate if codec.clock_rate:
attrs['clockrate'] = codec.clock_rate
if codec.optional_params: if codec.optional_params:
p = (xmpp.Node('parameter', {'name': name, 'value': value}) payload = (xmpp.Node('parameter', {'name': name, 'value': value})
for name, value in codec.optional_params) for name, value in codec.optional_params)
else: p = () else: payload = ()
yield xmpp.Node('payload-type', a, p) yield xmpp.Node('payload-type', attrs, payload)
def __stop(self, *things): def __stop(self, *things):
self.pipeline.set_state(gst.STATE_NULL) self.pipeline.set_state(gst.STATE_NULL)
@ -803,12 +803,12 @@ class JingleVoIP(JingleRTPContent):
over an ICE UDP protocol. ''' over an ICE UDP protocol. '''
def __init__(self, session, node=None): def __init__(self, session, node=None):
JingleRTPContent.__init__(self, session, 'audio', node) JingleRTPContent.__init__(self, session, 'audio', node)
self.setupStream() self.setup_stream()
''' Things to control the gstreamer's pipeline ''' ''' Things to control the gstreamer's pipeline '''
def setupStream(self): def setup_stream(self):
JingleRTPContent.setupStream(self) JingleRTPContent.setup_stream(self)
# Configure SPEEX # Configure SPEEX
#FIXME: codec ID is an important thing for psi (and pidgin?) #FIXME: codec ID is an important thing for psi (and pidgin?)
@ -858,14 +858,14 @@ class JingleVoIP(JingleRTPContent):
class JingleVideo(JingleRTPContent): class JingleVideo(JingleRTPContent):
def __init__(self, session, node=None): def __init__(self, session, node=None):
JingleRTPContent.__init__(self, session, 'video', node) JingleRTPContent.__init__(self, session, 'video', node)
self.setupStream() self.setup_stream()
''' Things to control the gstreamer's pipeline ''' ''' Things to control the gstreamer's pipeline '''
def setupStream(self): def setup_stream(self):
#TODO: Everything is not working properly: #TODO: Everything is not working properly:
# sometimes, one window won't show up, # sometimes, one window won't show up,
# sometimes it'll freeze... # sometimes it'll freeze...
JingleRTPContent.setupStream(self) JingleRTPContent.setup_stream(self)
# the local parts # the local parts
src_vid = gst.element_factory_make('v4l2src') src_vid = gst.element_factory_make('v4l2src')
videoscale = gst.element_factory_make('videoscale') videoscale = gst.element_factory_make('videoscale')
@ -904,13 +904,13 @@ class ConnectionJingle(object):
# one time callbacks # one time callbacks
self.__iq_responses = {} self.__iq_responses = {}
def addJingle(self, jingle): def add_jingle(self, jingle):
''' Add a jingle session to a jingle stanza dispatcher ''' Add a jingle session to a jingle stanza dispatcher
jingle - a JingleSession object. jingle - a JingleSession object.
''' '''
self.__sessions[(jingle.peerjid, jingle.sid)] = jingle self.__sessions[(jingle.peerjid, jingle.sid)] = jingle
def deleteJingle(self, jingle): def delete_jingle(self, jingle):
''' Remove a jingle session from a jingle stanza dispatcher ''' ''' Remove a jingle session from a jingle stanza dispatcher '''
del self.__sessions[(jingle.peerjid, jingle.sid)] del self.__sessions[(jingle.peerjid, jingle.sid)]
@ -937,24 +937,21 @@ class ConnectionJingle(object):
# do we need to create a new jingle object # do we need to create a new jingle object
if (jid, sid) not in self.__sessions: if (jid, sid) not in self.__sessions:
newjingle = JingleSession(con=self, weinitiate=False, jid=jid, sid=sid) newjingle = JingleSession(con=self, weinitiate=False, jid=jid, sid=sid)
self.addJingle(newjingle) self.add_jingle(newjingle)
# we already have such session in dispatcher... # we already have such session in dispatcher...
self.__sessions[(jid, sid)].stanzaCB(stanza) self.__sessions[(jid, sid)].stanzaCB(stanza)
raise xmpp.NodeProcessed raise xmpp.NodeProcessed
def addJingleIqCallback(self, jid, id, jingle):
self.__iq_responses[(jid, id)] = jingle
def startVoIP(self, jid): def startVoIP(self, jid):
jingle = JingleSession(self, weinitiate=True, jid=jid) jingle = JingleSession(self, weinitiate=True, jid=jid)
self.addJingle(jingle) self.add_jingle(jingle)
jingle.addContent('voice', JingleVoIP(jingle)) jingle.add_content('voice', JingleVoIP(jingle))
jingle.startSession() jingle.start_session()
return jingle.sid return jingle.sid
def getJingleSession(self, jid, sid): def get_jingle_session(self, jid, sid):
try: try:
return self.__sessions[(jid, sid)] return self.__sessions[(jid, sid)]
except KeyError: except KeyError:

View File

@ -4470,10 +4470,10 @@ class VoIPCallReceivedDialog(object):
def on_voip_call_received_messagedialog_response(self, dialog, response): def on_voip_call_received_messagedialog_response(self, dialog, response):
# we've got response from user, either stop connecting or accept the call # we've got response from user, either stop connecting or accept the call
session = gajim.connections[self.account].getJingleSession(self.fjid, session = gajim.connections[self.account].get_jingle_session(self.fjid,
self.sid) self.sid)
if response==gtk.RESPONSE_YES: if response==gtk.RESPONSE_YES:
session.approveSession() session.approve_session()
jid = gajim.get_jid_without_resource(self.fjid) jid = gajim.get_jid_without_resource(self.fjid)
resource = gajim.get_resource_from_jid(self.fjid) resource = gajim.get_resource_from_jid(self.fjid)
ctrl = gajim.interface.msg_win_mgr.get_control(self.fjid, self.account) ctrl = gajim.interface.msg_win_mgr.get_control(self.fjid, self.account)
@ -4489,7 +4489,7 @@ class VoIPCallReceivedDialog(object):
ctrl = gajim.interface.new_chat(contact, self.account) ctrl = gajim.interface.new_chat(contact, self.account)
ctrl.set_audio_state('connecting', self.sid) ctrl.set_audio_state('connecting', self.sid)
else: # response==gtk.RESPONSE_NO else: # response==gtk.RESPONSE_NO
session.declineSession() session.decline_session()
dialog.destroy() dialog.destroy()