Changeset 8467 for branches/jingle
- Timestamp:
- 08/07/07 18:34:09 (16 months ago)
- Location:
- branches/jingle/src
- Files:
-
- 2 modified
-
chat_control.py (modified) (1 diff)
-
common/jingle.py (modified) (16 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/jingle/src/chat_control.py
r8461 r8467 1193 1193 1194 1194 def _on_start_voip_menuitem_activate(self, *things): 1195 print 'Start VoiP' 1196 gajim.connections[self.account].startVoiP(self.contact.jid) 1195 gajim.connections[self.account].startVoiP(self.contact.jid+'/'+self.contact.resource) 1197 1196 1198 1197 def _update_gpg(self): -
branches/jingle/src/common/jingle.py
r8461 r8467 31 31 ''' This represents one jingle session. ''' 32 32 __metaclass__=meta.VerboseClassType 33 def __init__(self, con, weinitiate, jid ):33 def __init__(self, con, weinitiate, jid, sid=None): 34 34 ''' con -- connection object, 35 35 weinitiate -- boolean, are we the initiator? … … 48 48 # what state is session in? (one from JingleStates) 49 49 self.state=JingleStates.ended 50 self.sid=con.connection.getAnID() # sessionid 50 if not sid: 51 sid=con.connection.getAnID() 52 self.sid=sid # sessionid 51 53 52 54 # callbacks to call on proper contents 53 # use .prepend() to add new callbacks 54 self.callbacks=dict((key, [self.__defaultCB]) for key in 55 ('content-add', 'content-modify', 56 'content-remove', 'session-accept', 'session-info', 57 'session-initiate', 'session-terminate', 58 'transport-info')) 59 self.callbacks['iq-result']=[] 60 self.callbacks['iq-error']=[] 61 62 self.callbacks['content-accept']=[self.__contentAcceptCB, self.__defaultCB] 55 # use .prepend() to add new callbacks, especially when you're going 56 # to send error instead of ack 57 self.callbacks={ 58 'content-accept': [self.__contentAcceptCB, self.__defaultCB], 59 'content-add': [self.__defaultCB], 60 'content-modify': [self.__defaultCB], 61 'content-remove': [self.__defaultCB], 62 'session-accept': [self.__contentAcceptCB, self.__defaultCB], 63 'session-info': [self.__defaultCB], 64 'session-initiate': [self.__sessionInitiateCB, self.__defaultCB], 65 'session-terminate': [self.__defaultCB], 66 'transport-info': [self.__defaultCB], 67 'iq-result': [], 68 'iq-error': [], 69 } 63 70 64 71 ''' Middle-level functions to manage contents. Handle local content … … 94 101 def startSession(self): 95 102 ''' Start session. ''' 96 self.__sessionInitiate( self)103 self.__sessionInitiate() 97 104 98 105 def sendSessionInfo(self): pass … … 129 136 and stop processing. ''' 130 137 response = stanza.buildReply('result') 131 self.connection.send(response) 132 raise xmpp.NodeProcessed 138 self.connection.connection.send(response) 133 139 134 140 def __contentAcceptCB(self, stanza, jingle, error): … … 141 147 142 148 149 def sessionInitiateCB(self, stanza): 150 ''' We got a jingle session request from other entity, 151 therefore we are the receiver... Unpack the data. ''' 152 jingle = stanza.getTag('jingle') 153 self.initiator = jingle['initiator'] 154 self.responder = self.ourjid 155 self.jid = self.initiator 156 157 fail = True 158 for element in jingle.iterTags('content'): 159 # checking what kind of session this will be 160 desc_ns = element.getTag('description').getNamespace() 161 tran_ns = element.getTag('transport').getNamespace() 162 if desc_ns==xmpp.NS_JINGLE_AUDIO and tran_ns==xmpp.NS_JINGLE_ICE_UDP: 163 # we've got voip content 164 self.addContent(element['name'], JingleVoiP(self, node=element), 'peer') 165 fail = False 166 167 if fail: 168 # TODO: we should send <unsupported-content/> inside too 169 self.connection.connection.send( 170 xmpp.Error(stanza, xmpp.NS_STANZAS + 'feature-not-implemented')) 171 self.connection.deleteJingle(self) 172 raise xmpp.NodeProcessed 173 174 self.state = JingleStates.pending 175 143 176 ''' Methods that make/send proper pieces of XML. They check if the session 144 177 is in appropriate state. ''' 145 178 def __makeJingle(self, action): 146 stanza = xmpp.Iq(typ='set', to=xmpp.JID(self. jid))179 stanza = xmpp.Iq(typ='set', to=xmpp.JID(self.peerjid)) 147 180 jingle = stanza.addChild('jingle', attrs={ 148 181 'xmlns': 'http://www.xmpp.org/extensions/xep-0166.html#ns', … … 162 195 jingle.addChild('content', 163 196 attrs={'name': content.name, 'creator': content.creator}) 164 return c165 197 166 198 def __appendContents(self, jingle, full=True): … … 175 207 stanza, jingle = self.__makeJingle('session-initiate') 176 208 self.__appendContents(jingle) 177 self.connection. send(jingle)209 self.connection.connection.send(stanza) 178 210 179 211 def __sessionAccept(self): … … 181 213 stanza, jingle = self.__jingle('session-accept') 182 214 self.__appendContents(jingle, False) 183 self.connection. send(stanza)215 self.connection.connection.send(stanza) 184 216 self.state=JingleStates.active 185 217 … … 189 221 if payload: 190 222 jingle.addChild(node=payload) 191 self.connection. send(stanza)223 self.connection.connection.send(stanza) 192 224 193 225 def __sessionTerminate(self): 194 226 assert self.state!=JingleStates.ended 195 227 stanza, jingle = self.__jingle('session-terminate') 196 self.connection. send(stanza)228 self.connection.connection.send(stanza) 197 229 198 230 def __contentAdd(self): … … 212 244 213 245 '''Callbacks''' 214 def sessionInitiateCB(self, stanza):215 ''' We got a jingle session request from other entity,216 therefore we are the receiver... Unpack the data. '''217 jingle = stanza.getTag('jingle')218 self.initiator = jingle['initiator']219 self.responder = self.ourjid220 self.jid = self.initiator221 self.state = JingleStates.pending222 self.sid = jingle['sid']223 for element in jingle.iterTags('content'):224 content={'creator': 'initiator',225 'name': element['name'],226 'description': element.getTag('description'),227 'transport': element.getTag('transport')}228 if element.has_attr('profile'):229 content['profile']=element['profile']230 self.contents[('initiator', content['name'])]=content231 232 246 def sessionTerminateCB(self, stanza): pass 247 248 class Codec(object): 249 ''' This class keeps description of a single codec. ''' 250 def __init__(self, name, id=None, **params): 251 ''' Create new codec description. ''' 252 self.name = name 253 self.id = id 254 self.attrs = {'name': self.name, 'id': self.id, 'channels': 1} 255 for key in ('channels', 'clockrate', 'maxptime', 'ptime'): 256 if key in params: 257 self.attrs[key]=params[key] 258 del params[key] 259 self.params = params 260 261 def __eq__(a, b): 262 ''' Compare two codec descriptions. ''' 263 # TODO: check out what should be tested... 264 if a.name!=b.name: return False 265 # ... 266 return True 267 268 def toXML(self): 269 return xmpp.Node('payload', 270 attrs=self.attrs, 271 payload=(xmpp.Node('parameter', {'name': k, 'value': v}) for k,v in self.params)) 233 272 234 273 class JingleAudioSession(object): 235 274 __metaclass__=meta.VerboseClassType 236 class Codec(object): 237 ''' This class keeps description of a single codec. ''' 238 def __init__(self, name, id=None, **params): 239 ''' Create new codec description. ''' 240 self.name = name 241 self.id = id 242 self.attrs = {'name': self.name, 'id': self.id, 'channels': 1} 243 for key in ('channels', 'clockrate', 'maxptime', 'ptime'): 244 if key in params: 245 self.attrs[key]=params[key] 246 del params[key] 247 self.params = params 248 249 def __eq__(a, b): 250 ''' Compare two codec descriptions. ''' 251 # TODO: check out what should be tested... 252 if a.name!=b.name: return False 253 # ... 254 return True 255 256 def toXML(self): 257 return xmpp.Node('payload', 258 attrs=self.attrs, 259 payload=(xmpp.Node('parameter', {'name': k, 'value': v}) for k,v in self.params)) 260 261 def __init__(self, content): 275 def __init__(self, content, fromNode): 262 276 self.content = content 263 277 264 278 self.initiator_codecs=[] 265 279 self.responder_codecs=[] 280 281 if fromNode: 282 # read all codecs peer understand 283 for payload in fromNode.iterTags('payload-type'): 284 attrs = fromNode.getAttrs().copy() 285 for param in fromNode.iterTags('parameter'): 286 attrs[param['name']]=param['value'] 287 self.initiator_codecs.append(Codec(**attrs)) 266 288 267 289 def sessionInitiateCB(self, stanza, ourcontent): … … 285 307 out = [] 286 308 ids = range(128) 287 for codec in other :309 for codec in other_l: 288 310 if codec in our_l: 289 311 out.append(codec) … … 305 327 def __codecsList(self, codecs): 306 328 ''' Prepares a description element with codecs given as a parameter. ''' 307 return xmpp.Node('description', 308 xmlns=xmpp.NS_JINGLE_AUDIO, 329 return xmpp.Node(xmpp.NS_JINGLE_AUDIO+' description', 309 330 payload=(codec.toXML() for codec in codecs)) 310 331 … … 330 351 def toXML(self): 331 352 ''' ICE-UDP doesn't send much in its transport stanza... ''' 332 return xmpp.Node( 'transport', xmlns=xmpp.JINGLE_ICE_UDP)353 return xmpp.Node(xmpp.NS_JINGLE_ICE_UDP+' transport') 333 354 334 355 class JingleVoiP(object): … … 336 357 over an ICE UDP protocol. ''' 337 358 __metaclass__=meta.VerboseClassType 338 def __init__(self): 339 self.audio = JingleAudioSession(self) 359 def __init__(self, session, node=None): 360 self.session = session 361 362 if node is None: 363 self.audio = JingleAudioSession(self) 364 else: 365 self.audio = JingleAudioSession(self, node.getTag('content')) 340 366 self.transport = JingleICEUDPSession(self) 341 367 … … 344 370 return xmpp.Node('content', 345 371 attrs={'name': self.name, 'creator': self.creator, 'profile': 'RTP/AVP'}, 346 childs=[self.audio.toXML(), self.transport.toXML()]) 347 348 def _sessionInitiateCB(self): 349 ''' Called when we initiate the session. ''' 350 self.transport._sessionInitiateCB() 372 payload=[self.audio.toXML(), self.transport.toXML()]) 351 373 352 374 class ConnectionJingle(object): … … 392 414 # do we need to create a new jingle object 393 415 if (jid, sid) not in self.__sessions: 394 # we should check its type here...395 newjingle = Jingle AudioSession(con=self, weinitiate=False, jid=jid)416 # TODO: we should check its type here... 417 newjingle = JingleSession(con=self, weinitiate=False, jid=jid, sid=sid) 396 418 self.addJingle(newjingle) 397 419 398 420 # we already have such session in dispatcher... 399 return self.__sessions[(jid, sid)].stanzaCB(stanza) 421 self.__sessions[(jid, sid)].stanzaCB(stanza) 422 423 raise xmpp.NodeProcessed 400 424 401 425 def addJingleIqCallback(self, jid, id, jingle):
