Jingle: farsight bindings define constants now

This commit is contained in:
Tomasz Melcer 2007-08-12 21:22:25 +00:00
parent c00c05dd93
commit 5bb2fa9a0c
3 changed files with 105 additions and 27 deletions

View File

@ -104,13 +104,13 @@ static void dict_to_farsight_transport_info(PyObject* dict, FarsightTransportInf
fti->preference = get_double_from_dict(dict, "preference"); fti->preference = get_double_from_dict(dict, "preference");
fti->type = get_long_from_dict(dict, "type"); fti->type = get_long_from_dict(dict, "type");
if (PyError_Occurred()) return; if (PyErr_Occurred()) return;
/* optional */ /* optional */
fti->username = get_str_from_dict(dict, "username"); fti->username = get_str_from_dict(dict, "username");
fti->password = get_str_from_dict(dict, "password"); fti->password = get_str_from_dict(dict, "password");
PyError_Clear(); PyErr_Clear();
} }
/* GArray must be freed if not NULL; /* GArray must be freed if not NULL;
@ -124,7 +124,7 @@ static void dict_to_farsight_codec(PyObject* dict, FarsightCodec* fc, GArray** f
fc->id = get_long_from_dict(dict, "id"); fc->id = get_long_from_dict(dict, "id");
fc->encoding_name = get_str_from_dict(dict, "encoding_name"); fc->encoding_name = get_str_from_dict(dict, "encoding_name");
if (PyError_Occured()) return; if (PyErr_Occurred()) return;
/* optional data */ /* optional data */
fc->media_type = get_long_from_dict(dict, "media_type"); fc->media_type = get_long_from_dict(dict, "media_type");
@ -335,14 +335,14 @@ static PyObject* _wrap_farsight_stream_set_remote_candidate_list(PyGObject *self
&g_array_index(candidate_array, FarsightTransportInfo, i)); &g_array_index(candidate_array, FarsightTransportInfo, i));
} }
if(!PyError_Occurred()) { if(!PyErr_Occurred()) {
farsight_stream_set_remote_candidate_list(FARSIGHT_STREAM(self->obj), candidate_list); farsight_stream_set_remote_candidate_list(FARSIGHT_STREAM(self->obj), candidate_list);
} }
g_array_free(candidate_array, FALSE); g_array_free(candidate_array, FALSE);
g_list_free(candidate_list); g_list_free(candidate_list);
if(!PyError_Occurred()) { if(!PyErr_Occurred()) {
Py_INCREF(Py_None); Py_INCREF(Py_None);
return Py_None; return Py_None;
} else { } else {
@ -379,7 +379,7 @@ static PyObject* _wrap_farsight_stream_set_remote_codecs(PyGObject *self,
&g_array_index(codecs_array, FarsightCodec, i)); &g_array_index(codecs_array, FarsightCodec, i));
} }
if (!PyError_Occurred()) { if (!PyErr_Occurred()) {
farsight_stream_set_remote_codecs(FARSIGHT_STREAM(self->obj), codecs_list); farsight_stream_set_remote_codecs(FARSIGHT_STREAM(self->obj), codecs_list);
} }
@ -387,7 +387,7 @@ static PyObject* _wrap_farsight_stream_set_remote_codecs(PyGObject *self,
g_array_free(codecs_array, FALSE); g_array_free(codecs_array, FALSE);
g_list_free(codecs_list); g_list_free(codecs_list);
if (!PyError_Occurred()) { if (!PyErr_Occurred()) {
Py_INCREF(Py_None); Py_INCREF(Py_None);
return Py_None; return Py_None;
} else { } else {

View File

@ -1,5 +1,9 @@
#include <pygobject.h> #include <pygobject.h>
#include <stdio.h> #include <stdio.h>
#include <farsight/farsight-codec.h>
#include <farsight/farsight-stream.h>
#include <farsight/farsight-transmitter.h>
void farsight_register_classes (PyObject *d); void farsight_register_classes (PyObject *d);
extern PyMethodDef farsight_functions[]; extern PyMethodDef farsight_functions[];
@ -16,7 +20,49 @@ initfarsight(void)
farsight_register_classes (d); farsight_register_classes (d);
// farsight_add_constants(m, 'FARSIGHT_TYPE_'); PyModule_AddIntConstant(m, "MEDIA_TYPE_AUDIO", FARSIGHT_MEDIA_TYPE_AUDIO);
PyModule_AddIntConstant(m, "MEDIA_TYPE_VIDEO", FARSIGHT_MEDIA_TYPE_VIDEO);
PyModule_AddIntConstant(m, "STREAM_DIRECTION_NONE", FARSIGHT_STREAM_DIRECTION_NONE);
PyModule_AddIntConstant(m, "STREAM_DIRECTION_SENDONLY", FARSIGHT_STREAM_DIRECTION_SENDONLY);
PyModule_AddIntConstant(m, "STREAM_DIRECTION_RECEIVEONLY", FARSIGHT_STREAM_DIRECTION_RECEIVEONLY);
PyModule_AddIntConstant(m, "STREAM_DIRECTION_BOTH", FARSIGHT_STREAM_DIRECTION_BOTH);
PyModule_AddIntConstant(m, "STREAM_STATE_DISCONNECTED", FARSIGHT_STREAM_STATE_DISCONNECTED);
PyModule_AddIntConstant(m, "STREAM_STATE_CONNECTING", FARSIGHT_STREAM_STATE_CONNECTING);
PyModule_AddIntConstant(m, "STREAM_STATE_CONNECTED", FARSIGHT_STREAM_STATE_CONNECTED);
PyModule_AddIntConstant(m, "STREAM_ERROR_EOS", FARSIGHT_STREAM_ERROR_EOS);
PyModule_AddIntConstant(m, "STREAM_UNKNOWN_ERROR", FARSIGHT_STREAM_UNKNOWN_ERROR);
PyModule_AddIntConstant(m, "STREAM_ERROR_UNKNOWN", FARSIGHT_STREAM_UNKNOWN_ERROR);
PyModule_AddIntConstant(m, "STREAM_ERROR_TIMEOUT", FARSIGHT_STREAM_ERROR_TIMEOUT);
PyModule_AddIntConstant(m, "STREAM_ERROR_NETWORK", FARSIGHT_STREAM_ERROR_NETWORK);
PyModule_AddIntConstant(m, "STREAM_ERROR_PIPELINE_SETUP", FARSIGHT_STREAM_ERROR_PIPELINE_SETUP);
PyModule_AddIntConstant(m, "STREAM_ERROR_RESOURCE", FARSIGHT_STREAM_ERROR_RESOURCE);
PyModule_AddIntConstant(m, "DTMF_EVENT_0", FARSIGHT_DTMF_EVENT_0);
PyModule_AddIntConstant(m, "DTMF_EVENT_1", FARSIGHT_DTMF_EVENT_1);
PyModule_AddIntConstant(m, "DTMF_EVENT_2", FARSIGHT_DTMF_EVENT_2);
PyModule_AddIntConstant(m, "DTMF_EVENT_3", FARSIGHT_DTMF_EVENT_3);
PyModule_AddIntConstant(m, "DTMF_EVENT_4", FARSIGHT_DTMF_EVENT_4);
PyModule_AddIntConstant(m, "DTMF_EVENT_5", FARSIGHT_DTMF_EVENT_5);
PyModule_AddIntConstant(m, "DTMF_EVENT_6", FARSIGHT_DTMF_EVENT_6);
PyModule_AddIntConstant(m, "DTMF_EVENT_7", FARSIGHT_DTMF_EVENT_7);
PyModule_AddIntConstant(m, "DTMF_EVENT_8", FARSIGHT_DTMF_EVENT_8);
PyModule_AddIntConstant(m, "DTMF_EVENT_9", FARSIGHT_DTMF_EVENT_9);
PyModule_AddIntConstant(m, "DTMF_EVENT_STAR", FARSIGHT_DTMF_EVENT_STAR);
PyModule_AddIntConstant(m, "DTMF_EVENT_POUND", FARSIGHT_DTMF_EVENT_POUND);
PyModule_AddIntConstant(m, "DTMF_EVENT_A", FARSIGHT_DTMF_EVENT_A);
PyModule_AddIntConstant(m, "DTMF_EVENT_B", FARSIGHT_DTMF_EVENT_B);
PyModule_AddIntConstant(m, "DTMF_EVENT_C", FARSIGHT_DTMF_EVENT_C);
PyModule_AddIntConstant(m, "DTMF_EVENT_D", FARSIGHT_DTMF_EVENT_D);
PyModule_AddIntConstant(m, "DTMF_METHOD_AUTO", FARSIGHT_DTMF_METHOD_AUTO);
PyModule_AddIntConstant(m, "DTMF_METHOD_RTP_RFC4733", FARSIGHT_DTMF_METHOD_RTP_RFC4733);
PyModule_AddIntConstant(m, "DTMF_METHOD_SOUND", FARSIGHT_DTMF_METHOD_SOUND);
PyModule_AddIntConstant(m, "TRANSMITTER_STATE_DISCONNECTED", FARSIGHT_TRANSMITTER_STATE_DISCONNECTED);
PyModule_AddIntConstant(m, "TRANSMITTER_STATE_CONNECTING", FARSIGHT_TRANSMITTER_STATE_CONNECTING);
PyModule_AddIntConstant(m, "TRANSMITTER_STATE_CONNECTED", FARSIGHT_TRANSMITTER_STATE_CONNECTED);
PyModule_AddIntConstant(m, "CANDIDATE_TYPE_LOCAL", FARSIGHT_CANDIDATE_TYPE_LOCAL);
PyModule_AddIntConstant(m, "CANDIDATE_TYPE_DERIVED", FARSIGHT_CANDIDATE_TYPE_DERIVED);
PyModule_AddIntConstant(m, "CANDIDATE_TYPE_RELAY", FARSIGHT_CANDIDATE_TYPE_RELAY);
PyModule_AddIntConstant(m, "NETWORK_PROTOCOL_UDP", FARSIGHT_NETWORK_PROTOCOL_UDP);
PyModule_AddIntConstant(m, "NETWORK_PROTOCOL_TCP", FARSIGHT_NETWORK_PROTOCOL_TCP);
if (PyErr_Occurred ()) { if (PyErr_Occurred ()) {
PyErr_Print(); PyErr_Print();

View File

@ -20,10 +20,6 @@ import sys, dl, gst
sys.setdlopenflags(dl.RTLD_NOW | dl.RTLD_GLOBAL) sys.setdlopenflags(dl.RTLD_NOW | dl.RTLD_GLOBAL)
import farsight import farsight
sys.setdlopenflags(dl.RTLD_NOW | dl.RTLD_LOCAL) sys.setdlopenflags(dl.RTLD_NOW | dl.RTLD_LOCAL)
FARSIGHT_MEDIA_TYPE_AUDIO=0
FARSIGHT_STREAM_DIRECTION_BOTH=3
FARSIGHT_NETWORK_PROTOCOL_UDP=0
FARSIGHT_CANDIDATE_TYPE_LOCAL=0
import meta import meta
@ -84,21 +80,21 @@ class JingleSession(object):
''' 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, initiator='we'): def addContent(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.
Initiator must be one of ('we', 'peer', 'initiator', 'responder')''' Creator must be one of ('we', 'peer', 'initiator', 'responder')'''
if self.state==JingleStates.pending: if self.state==JingleStates.pending:
raise WrongState raise WrongState
if (initiator=='we' and self.weinitiate) or (initiator=='peer' and not self.weinitiate): if (creator=='we' and self.weinitiate) or (creator=='peer' and not self.weinitiate):
initiator='initiator' creator='initiator'
elif (initiator=='peer' and self.weinitiate) or (initiator=='we' and not self.weinitiate): elif (creator=='peer' and self.weinitiate) or (creator=='we' and not self.weinitiate):
initiator='responder' creator='responder'
content.creator = initiator content.creator = creator
content.name = name content.name = name
self.contents[(initiator,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
@ -117,7 +113,6 @@ class JingleSession(object):
self.__sessionInitiate() self.__sessionInitiate()
def sendSessionInfo(self): pass def sendSessionInfo(self): pass
def sendTransportInfo(self): pass
''' Callbacks. ''' ''' Callbacks. '''
def stanzaCB(self, stanza): def stanzaCB(self, stanza):
@ -165,7 +160,7 @@ class JingleSession(object):
therefore we are the receiver... Unpack the data. ''' therefore we are the receiver... Unpack the data. '''
self.initiator = jingle['initiator'] self.initiator = jingle['initiator']
self.responder = self.ourjid self.responder = self.ourjid
self.jid = self.initiator self.peerjid = self.initiator
fail = True fail = True
for element in jingle.iterTags('content'): for element in jingle.iterTags('content'):
@ -255,8 +250,11 @@ class JingleSession(object):
def __contentRemove(self): def __contentRemove(self):
assert self.state!=JingleStates.ended assert self.state!=JingleStates.ended
def __transportInfo(self): def sendTransportInfo(self, content):
assert self.state!=JingleStates.ended assert self.state!=JingleStates.ended
stanza, jingle = self.__makeJingle('transport-info')
jingle.addChild(node=content)
self.connection.connection.send(stanza)
'''Callbacks''' '''Callbacks'''
def sessionTerminateCB(self, stanza): pass def sessionTerminateCB(self, stanza): pass
@ -368,12 +366,22 @@ class JingleICEUDPSession(object):
''' ICE-UDP doesn't send much in its transport stanza... ''' ''' ICE-UDP doesn't send much in its transport stanza... '''
return xmpp.Node(xmpp.NS_JINGLE_ICE_UDP+' transport') return xmpp.Node(xmpp.NS_JINGLE_ICE_UDP+' transport')
class JingleVoiP(object): class JingleContent(object):
''' An abstraction of content in Jingle sessions. '''
def __init__(self, session, node=None):
self.session = session
# 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
class JingleVoiP(JingleContent):
''' Jingle VoiP sessions consist of audio content transported ''' Jingle VoiP sessions consist of audio content transported
over an ICE UDP protocol. ''' over an ICE UDP protocol. '''
__metaclass__=meta.VerboseClassType __metaclass__=meta.VerboseClassType
def __init__(self, session, node=None): def __init__(self, session, node=None):
self.session = session JingleContent.__init__(self, session, node)
self.codecs = None self.codecs = None
#if node is None: #if node is None:
@ -392,8 +400,15 @@ class JingleVoiP(object):
xmpp.Node(xmpp.NS_JINGLE_ICE_UDP+' transport') xmpp.Node(xmpp.NS_JINGLE_ICE_UDP+' transport')
]) ])
def __content(self, payload=[]):
''' Build a XML content-wrapper for our data. '''
return xmpp.Node('content',
attrs={'name': self.name, 'creator': self.creator, 'profile': 'RTP/AVP'},
payload=payload)
def setupStream(self): def setupStream(self):
self.p2pstream = self.session.p2psession.create_stream(FARSIGHT_MEDIA_TYPE_AUDIO, FARSIGHT_STREAM_DIRECTION_BOTH) self.p2pstream = self.session.p2psession.create_stream(
farsight.MEDIA_TYPE_AUDIO, farsight.STREAM_DIRECTION_BOTH)
self.p2pstream.set_property('transmitter', 'libjingle') self.p2pstream.set_property('transmitter', 'libjingle')
self.p2pstream.connect('error', self.on_p2pstream_error) self.p2pstream.connect('error', self.on_p2pstream_error)
self.p2pstream.connect('new-active-candidate-pair', self.on_p2pstream_new_active_candidate_pair) self.p2pstream.connect('new-active-candidate-pair', self.on_p2pstream_new_active_candidate_pair)
@ -409,8 +424,25 @@ class JingleVoiP(object):
def on_p2pstream_native_candidates_prepared(self, *whatever): pass def on_p2pstream_native_candidates_prepared(self, *whatever): pass
def on_p2pstream_state_changed(self, *whatever): pass def on_p2pstream_state_changed(self, *whatever): pass
def on_p2pstream_new_native_candidate(self, p2pstream, candidate_id): def on_p2pstream_new_native_candidate(self, p2pstream, candidate_id):
candidate = p2pstream.get_native_candidate(candidate_id) candidates = p2pstream.get_native_candidate(candidate_id)
for candidate in candidates:
attrs={
'component': candidate['component'],
'foundation': '1', # hack
'generation': '0',
'ip': candidate['ip'],
'network': '0',
'port': candidate['port'],
'priority': int(100000*candidate['preference']), # hack
'protocol': candidate['proto']==farsight.NETWORK_PROTOCOL_UDP and 'udp' or 'tcp',
}
if 'username' in candidate: attrs['ufrag']=candidate['username']
if 'password' in candidate: attrs['pwd']=candidate['password']
c=self.__content()
t=c.addChild(xmpp.NS_JINGLE_ICE_UDP+' transport')
t.addChild('candidate', attrs=attrs)
self.session.sendTransportInfo(c)
def getCodecs(self): def getCodecs(self):
codecs=self.p2pstream.get_local_codecs() codecs=self.p2pstream.get_local_codecs()