Changeset 8532 for branches/jingle
- Timestamp:
- 08/21/07 20:18:48 (16 months ago)
- Files:
-
- 1 modified
-
branches/jingle/src/common/jingle.py (modified) (14 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/jingle/src/common/jingle.py
r8524 r8532 22 22 sys.setdlopenflags(dl.RTLD_NOW | dl.RTLD_LOCAL) 23 23 24 import meta25 26 24 class JingleStates(object): 27 25 ''' States in which jingle session may exist. ''' … … 36 34 class JingleSession(object): 37 35 ''' This represents one jingle session. ''' 38 __metaclass__=meta.VerboseClassType39 36 def __init__(self, con, weinitiate, jid, sid=None): 40 37 ''' con -- connection object, … … 76 73 77 74 # for making streams using farsight 78 import gc79 gc.disable()80 print self.weinitiate, "#farsight_session_factory_make"81 75 self.p2psession = farsight.farsight_session_factory_make('rtp') 82 76 self.p2psession.connect('error', self.on_p2psession_error) … … 191 185 cn.stanzaCB(stanza, content, error, action) 192 186 193 def on_p2psession_error(self, *anything): 194 print self.weinitiate, "Farsight session error!" 187 def on_p2psession_error(self, *anything): pass 195 188 196 189 ''' Methods that make/send proper pieces of XML. They check if the session … … 269 262 def sessionTerminateCB(self, stanza): pass 270 263 271 class Codec(object):272 ''' This class keeps description of a single codec. '''273 def __init__(self, name, id=None, **params):274 ''' Create new codec description. '''275 self.name = name276 self.id = id277 self.attrs = {'name': self.name, 'id': self.id, 'channels': 1}278 for key in ('channels', 'clockrate', 'maxptime', 'ptime'):279 if key in params:280 self.attrs[key]=params[key]281 del params[key]282 self.params = params283 284 def __eq__(a, b):285 ''' Compare two codec descriptions. '''286 # TODO: check out what should be tested...287 if a.name!=b.name: return False288 # ...289 return True290 291 def toXML(self):292 return xmpp.Node('payload-type',293 attrs=self.attrs,294 payload=(xmpp.Node('parameter', {'name': k, 'value': v}) for k,v in self.params))295 296 class JingleAudioSession(object):297 # __metaclass__=meta.VerboseClassType298 def __init__(self, content, fromNode):299 self.content = content300 301 self.initiator_codecs=[]302 self.responder_codecs=[]303 304 if fromNode:305 # read all codecs peer understand306 for payload in fromNode.iterTags('payload-type'):307 attrs = fromNode.getAttrs().copy()308 for param in fromNode.iterTags('parameter'):309 attrs[param['name']]=param['value']310 self.initiator_codecs.append(Codec(**attrs))311 312 def sessionInitiateCB(self, stanza, ourcontent):313 pass314 315 ''' "Negotiation" of codecs... simply presenting what *we* can do, nothing more... '''316 def getOurCodecs(self, other=None):317 ''' Get a list of codecs we support. Try to get them in the same318 order as the codecs of our peer. If other!=None, raise319 a NoCommonCodec error if no codecs both sides support (None means320 we are initiating the connection and we don't know the other321 peer's codecs.) '''322 # for now we "understand" only one codec -- speex with clockrate 16000323 # so we have an easy job to do... (codecs sorted in order of preference)324 supported_codecs=[325 Codec('speex', clockrate='16000'),326 ]327 328 if other is not None:329 other_l = other330 else:331 other_l = []332 our_l = supported_codecs[:]333 out = []334 ids = range(128)335 for codec in other_l:336 if codec in our_l:337 out.append(codec)338 our_l.remove(codec)339 try: ids.remove(codec.id)340 except ValueError: pass # when id is not a dynamic one341 342 if other is not None and len(out)==0:343 raise NoCommonCodec344 345 for codec in our_l:346 if not codec.id or codec.id not in ids:347 codec.id = ids.pop()348 out.append(codec)349 350 return out351 352 ''' Methods for making proper pieces of XML. '''353 def __codecsList(self, codecs):354 ''' Prepares a description element with codecs given as a parameter. '''355 return xmpp.Node(xmpp.NS_JINGLE_AUDIO+' description',356 payload=(codec.toXML() for codec in codecs))357 358 def toXML(self):359 if not self.initiator_codecs:360 # we are the initiator, so just send our codecs361 self.initiator_codecs = self.getOurCodecs()362 return self.__codecsList(self.initiator_codecs)363 else:364 # we are the responder, we SHOULD adjust our codec list365 self.responder_codecs = self.getOurCodecs(self.initiator_codecs)366 return self.__codecsList(self.responder_codecs)367 368 264 class JingleContent(object): 369 265 ''' An abstraction of content in Jingle sessions. ''' … … 379 275 ''' Jingle VoiP sessions consist of audio content transported 380 276 over an ICE UDP protocol. ''' 381 # __metaclass__=meta.VerboseClassType382 277 def __init__(self, session, node=None): 383 278 JingleContent.__init__(self, session, node) … … 423 318 if len(codecs)==0: return 424 319 425 print self.session.weinitiate, "#farsight_stream_set_remote_codecs"426 320 self.p2pstream.set_remote_codecs(codecs) 427 321 self.got_codecs=True … … 432 326 for candidate in content.getTag('transport').iterTags('candidate'): 433 327 cand={ 434 'candidate_id': candidate['cid'],328 'candidate_id': self.session.connection.connection.getAnID(), 435 329 'component': int(candidate['component']), 436 330 'ip': candidate['ip'], … … 452 346 453 347 candidates.append(cand) 454 print self.session.weinitiate, "#add_remote_candidate"455 348 self.p2pstream.add_remote_candidate(candidates) 456 349 … … 471 364 472 365 def setupStream(self): 473 print self.session.weinitiate, "#farsight_session_create_stream"474 366 self.p2pstream = self.session.p2psession.create_stream( 475 367 farsight.MEDIA_TYPE_AUDIO, farsight.STREAM_DIRECTION_BOTH) … … 484 376 self.p2pstream.set_remote_codecs(self.p2pstream.get_local_codecs()) 485 377 486 print self.session.weinitiate, "#farsight_stream_prepare_transports"487 378 self.p2pstream.prepare_transports() 488 379 489 print self.session.weinitiate, "#farsight_stream_set_active_codec"490 380 self.p2pstream.set_active_codec(8) #??? 491 381 … … 500 390 src.set_property('is-live', True) 501 391 502 print self.session.weinitiate, "#farsight_stream_set_sink"503 392 self.p2pstream.set_sink(sink) 504 print self.session.weinitiate, "#farsight_stream_set_source"505 393 self.p2pstream.set_source(src) 506 394 507 395 def on_p2pstream_error(self, *whatever): pass 508 def on_p2pstream_new_active_candidate_pair(self, stream, native, remote): 509 print self.session.weinitiate, "##new_active_candidate_pair" 510 #print "New native candidate pair: %s, %s" % (native, remote) 511 def on_p2pstream_codec_changed(self, stream, codecid): 512 print self.session.weinitiate, "##codec_changed" 513 #print "Codec changed: %d" % codecid 396 def on_p2pstream_new_active_candidate_pair(self, stream, native, remote): pass 397 def on_p2pstream_codec_changed(self, stream, codecid): pass 514 398 def on_p2pstream_native_candidates_prepared(self, *whatever): 515 print self.session.weinitiate, "##native_candidates_prepared"516 #print "Native candidates prepared: %r" % whatever517 399 for candidate in self.p2pstream.get_native_candidate_list(): 518 400 self.send_candidate(candidate) 519 401 def on_p2pstream_state_changed(self, stream, state, dir): 520 print self.session.weinitiate, "##state_changed"521 #print "State: %d, Dir: %d" % (state, dir)522 402 if state==farsight.STREAM_STATE_CONNECTED: 523 print self.session.weinitiate, "#farsight_stream_signal_native_candidates_prepared"524 403 stream.signal_native_candidates_prepared() 525 print self.session.weinitiate, "#farsight_stream_start"526 404 stream.start() 527 405 def on_p2pstream_new_native_candidate(self, p2pstream, candidate_id): 528 print self.session.weinitiate, "##new_native_candidate"529 print self.session.weinitiate, "#get_native_candidate"530 406 candidates = p2pstream.get_native_candidate(candidate_id) 531 print self.session.weinitiate, "#!", repr(candidates)532 407 533 408 for candidate in candidates: … … 535 410 def send_candidate(self, candidate): 536 411 attrs={ 537 'cid': candidate['candidate_id'],538 412 'component': candidate['component'], 539 413 'foundation': '1', # hack 540 414 'generation': '0', 541 'type': candidate['type'],542 415 'ip': candidate['ip'], 543 416 'network': '0', … … 558 431 559 432 def iterCodecs(self): 560 print self.session.weinitiate, "#farsight_stream_get_local_codecs"561 433 codecs=self.p2pstream.get_local_codecs() 562 434 for codec in codecs:
