Manual handling of global_state_changed callback in the Python wrapper.

This commit is contained in:
Ghislain MARY 2014-07-31 14:44:23 +02:00
parent 67c8c4df73
commit 3519575570
4 changed files with 45 additions and 30 deletions

View file

@ -79,15 +79,30 @@ static PyObject * pylinphone_module_method_set_log_handler(PyObject *self, PyObj
Py_RETURN_NONE;
}
static void pylinphone_Core_callback_global_state_changed(LinphoneCore *lc, LinphoneGlobalState gstate, const char *message) {
pylinphone_CoreObject *pylc = (pylinphone_CoreObject *)linphone_core_get_user_data(lc);
PyObject *func = PyDict_GetItemString(pylc->vtable_dict, "global_state_changed");
if ((func != NULL) && PyFunction_Check(func)) {
if (PyEval_CallFunction(func, "Ois", pylc, gstate, message) == NULL) {
PyErr_Print();
}
}
}
static PyObject * pylinphone_Core_class_method_new(PyObject *cls, PyObject *args) {
LinphoneCore * cresult;
pylinphone_CoreObject *self;
PyObject * pyret;
LinphoneCoreVTable _vtable = { 0 };
PyObject * _vtable_dict;
const char * _config_path;
const char * _factory_config_path;
if (!PyArg_ParseTuple(args, "zz", &_config_path, &_factory_config_path)) {
if (!PyArg_ParseTuple(args, "Ozz", &_vtable_dict, &_config_path, &_factory_config_path)) {
return NULL;
}
if (!PyDict_Check(_vtable_dict)) {
PyErr_SetString(PyExc_TypeError, "The first argument must be a dictionary");
return NULL;
}
@ -95,6 +110,9 @@ static PyObject * pylinphone_Core_class_method_new(PyObject *cls, PyObject *args
if (self == NULL) {
return NULL;
}
Py_INCREF(_vtable_dict);
self->vtable_dict = _vtable_dict;
_vtable.global_state_changed = pylinphone_Core_callback_global_state_changed;
pylinphone_trace(1, "[PYLINPHONE] >>> %s(\"%s\", \"%s\")", __FUNCTION__, _config_path, _factory_config_path);
cresult = linphone_core_new(&_vtable, _config_path, _factory_config_path, self);

View file

@ -578,6 +578,9 @@ class LinphoneModule(object):
c['class_has_user_data'] = False
c['class_type_methods'] = []
c['class_type_hand_written_methods'] = []
c['class_object_members'] = ''
if c['class_name'] == 'Core':
c['class_object_members'] = "\tPyObject *vtable_dict;"
xml_type_methods = xml_class.findall("./classmethods/classmethod")
for xml_type_method in xml_type_methods:
if xml_type_method.get('deprecated') == 'true':

View file

@ -42,6 +42,7 @@ static PyTypeObject pylinphone_{{class_name}}Type;
typedef struct {
PyObject_HEAD
{{class_cname}} *native_ptr;
{{{class_object_members}}}
} pylinphone_{{class_name}}Object;
{{/classes}}

View file

@ -1,7 +1,5 @@
import linphone
import logging
import signal
import sys
import threading
import time
@ -36,44 +34,39 @@ logging.addLevelName(logging.DEBUG, "\033[1;37m%s\033[1;0m" % logging.getLevelNa
logging.addLevelName(logging.INFO, "\033[1;36m%s\033[1;0m" % logging.getLevelName(logging.INFO))
logging.addLevelName(logging.WARNING, "\033[1;31m%s\033[1;0m" % logging.getLevelName(logging.WARNING))
logging.addLevelName(logging.ERROR, "\033[1;41m%s\033[1;0m" % logging.getLevelName(logging.ERROR))
logging.basicConfig(level=logging.DEBUG, format="%(asctime)s.%(msecs)-3d %(levelname)s: %(message)s", datefmt="%H:%M:%S")
logging.basicConfig(level=logging.INFO, format="%(asctime)s.%(msecs)03d %(levelname)s: %(message)s", datefmt="%H:%M:%S")
# Define the linphone module log handler
def log_handler(level, msg):
method = getattr(logging, level)
if not msg.strip().startswith('[PYLINPHONE]'):
msg = '[CORE] ' + msg
method(msg)
def test_friend():
f = linphone.Friend.new()
print(f.address)
a1 = linphone.Address.new("sip:cotcot@sip.linphone.org")
print(a1.username)
print(a1.domain)
a1.domain = "sip2.linphone.org"
print(a1.domain)
f.address = a1
a2 = f.address
def signal_handler(signal, frame):
cont = False
raise KeyError("Ctrl+C")
# Define the iteration function
def iterate(kwargs):
core = kwargs['core']
core.iterate()
def interact():
choice = raw_input('> ')
if choice == "quit":
return False
return True
def global_state_changed(core, state, message):
logging.warning("[PYTHON] global_state_changed: " + str(state) + ", " + message)
if state == linphone.GlobalState.GlobalOn:
logging.warning("[PYTHON] core version: " + str(core.version))
# Create a linphone core and iterate every 20 ms
linphone.set_log_handler(log_handler)
core = linphone.Core.new(None, None)
callbacks = {
'global_state_changed':global_state_changed
}
core = linphone.Core.new(callbacks, None, None)
interval = IntervalTimer(0.02, iterate, kwargs={'core':core})
signal.signal(signal.SIGINT, signal_handler)
try:
interval.start()
signal.pause()
except KeyError:
interval.stop()
del interval
del core
interval.start()
while interact():
pass
interval.stop()