Commit a3b52d99 authored by Ghislain MARY's avatar Ghislain MARY

Fix Python module.

parent d8a8849f
......@@ -172,7 +172,7 @@ void linphone_core_cbs_set_user_data(LinphoneCoreCbs *cbs, void *user_data) {
cbs->vtable->user_data = user_data;
}
void *linphone_core_cbs_get_user_data(LinphoneCoreCbs *cbs) {
void *linphone_core_cbs_get_user_data(const LinphoneCoreCbs *cbs) {
return cbs->vtable->user_data;
}
......
......@@ -53,9 +53,20 @@ LinphoneVcard* linphone_vcard_new(void) {
return NULL;
}
LinphoneVcard *linphone_factory_create_vcard(LinphoneFactory *factory) {
return NULL;
}
void linphone_vcard_free(LinphoneVcard *vCard) {
}
LinphoneVcard *linphone_vcard_ref(LinphoneVcard *vCard) {
return NULL;
}
void linphone_vcard_unref(LinphoneVcard *vCard) {
}
bctbx_list_t* linphone_vcard_context_get_vcard_list_from_file(LinphoneVcardContext *context, const char *filename) {
return NULL;
}
......
......@@ -310,12 +310,12 @@ static VTableReference * v_table_reference_new(LinphoneCoreCbs *cbs, bool_t inte
VTableReference *ref=ms_new0(VTableReference,1);
ref->valid=TRUE;
ref->internal = internal;
ref->cbs=(LinphoneCoreCbs *)belle_sip_object_ref(cbs);
ref->cbs=linphone_core_cbs_ref(cbs);
return ref;
}
void v_table_reference_destroy(VTableReference *ref){
belle_sip_object_unref(ref->cbs);
linphone_core_cbs_unref(ref->cbs);
ms_free(ref);
}
......@@ -328,7 +328,7 @@ void linphone_core_add_listener(LinphoneCore *lc, LinphoneCoreVTable *vtable){
LinphoneCoreCbs *cbs = linphone_factory_create_core_cbs(linphone_factory_get());
_linphone_core_cbs_set_v_table(cbs, vtable, FALSE);
_linphone_core_add_callbacks(lc, cbs, FALSE);
belle_sip_object_unref(cbs);
linphone_core_cbs_unref(cbs);
}
void linphone_core_add_callbacks(LinphoneCore *lc, LinphoneCoreCbs *cbs) {
......
......@@ -590,7 +590,6 @@ LINPHONE_PUBLIC LinphoneCall *linphone_chat_room_get_call(const LinphoneChatRoom
* Get the LinphoneChatMessageCbs object associated with the LinphoneChatMessage.
* @param[in] msg LinphoneChatMessage object
* @return The LinphoneChatMessageCbs object associated with the LinphoneChatMessage.
* @deprecated Use linphone_chat_room_get_callbacks() instead.
*/
LINPHONE_PUBLIC LinphoneChatMessageCbs * linphone_chat_message_get_callbacks(const LinphoneChatMessage *msg);
......
......@@ -376,6 +376,11 @@ LINPHONE_PUBLIC bool_t linphone_local_player_matroska_supported(void);
*/
LINPHONE_PUBLIC LinphoneAddress * linphone_core_create_address(LinphoneCore *lc, const char *address);
/**
* @addtogroup misc
* @{
*/
/**
* The LinphoneInfoMessage is an object representing an informational message sent or received by the core.
**/
......@@ -396,7 +401,7 @@ LINPHONE_PUBLIC LinphoneInfoMessage *linphone_core_create_info_message(LinphoneC
* @param call the call
* @param info the info message
**/
LINPHONE_PUBLIC int linphone_call_send_info_message(struct _LinphoneCall *call, const LinphoneInfoMessage *info);
LINPHONE_PUBLIC int linphone_call_send_info_message(LinphoneCall *call, const LinphoneInfoMessage *info);
/**
* Add a header to an info message to be sent.
......@@ -433,6 +438,9 @@ LINPHONE_PUBLIC const LinphoneContent * linphone_info_message_get_content(const
LINPHONE_PUBLIC void linphone_info_message_destroy(LinphoneInfoMessage *im);
LINPHONE_PUBLIC LinphoneInfoMessage *linphone_info_message_copy(const LinphoneInfoMessage *orig);
/**
* @}
*/
/**
......@@ -1089,7 +1097,7 @@ LINPHONE_PUBLIC void linphone_core_cbs_set_user_data(LinphoneCoreCbs *cbs, void
/**
* Get the user pointer.
*/
LINPHONE_PUBLIC void *linphone_core_cbs_get_user_data(LinphoneCoreCbs *cbs);
LINPHONE_PUBLIC void *linphone_core_cbs_get_user_data(const LinphoneCoreCbs *cbs);
/**
* Gets the current #LinphoneCoreCbs.
......
......@@ -66,11 +66,13 @@ LINPHONE_DEPRECATED LINPHONE_PUBLIC void linphone_vcard_free(LinphoneVcard *vCar
/**
* Take a ref on a #LinphoneVcard.
* @param[in] vCard LinphoneVcard object
*/
LINPHONE_PUBLIC LinphoneVcard *linphone_vcard_ref(LinphoneVcard *vCard);
/**
* Release a #LinphoneVcard.
* @param[in] vCard LinphoneVcard object
*/
LINPHONE_PUBLIC void linphone_vcard_unref(LinphoneVcard *vCard);
......
......@@ -32,6 +32,7 @@ blacklisted_classes = [
]
blacklisted_events = [
'LinphoneChatMessageStateChangedCb', # not respecting naming convention
'LinphoneCoreAuthInfoRequestedCb',
'LinphoneCoreInfoReceivedCb', # missing LinphoneInfoMessage
'LinphoneCoreNotifyReceivedCb', # missing LinphoneContent
'LinphoneCoreFileTransferProgressIndicationCb', # missing LinphoneContent
......@@ -46,7 +47,13 @@ blacklisted_functions = [
'linphone_call_params_set_privacy', # missing LinphonePrivacyMask
'linphone_chat_message_start_file_download', # callback function in parameter
'linphone_chat_message_state_to_string', # There is no use to wrap this function
'linphone_chat_room_send_chat_message', # Use linphone_chat_room_send_chat_message_2 instead
'linphone_chat_room_send_message2', # callback function in parameter
'linphone_config_for_each_entry', # to be handwritten because of callback
'linphone_config_for_each_section', # to be handwritten because of callback
'linphone_config_get_range', # to be handwritten because of result via arguments
'linphone_config_load_dict_to_section', # missing LinphoneDictionary
'linphone_config_section_to_dict', # missing LinphoneDictionary
'linphone_core_add_listener',
'linphone_core_can_we_add_call', # private function
'linphone_core_enable_log_collection', # need to handle class properties
......@@ -58,6 +65,8 @@ blacklisted_functions = [
'linphone_core_get_supported_video_sizes', # missing MSVideoSizeDef
'linphone_core_get_video_policy', # missing LinphoneVideoPolicy
'linphone_core_get_video_port_range', # to be handwritten because of result via arguments
'linphone_core_new', # replaced by linphone_factory_create_core
'linphone_core_new_with_config', # replaced by linphone_factory_create_core_with_config
'linphone_core_remove_listener',
'linphone_core_serialize_logs', # There is no use to wrap this function
'linphone_core_set_dns_servers',
......@@ -76,12 +85,8 @@ blacklisted_functions = [
'linphone_proxy_config_set_file_transfer_server', # defined but not implemented in linphone core
'linphone_proxy_config_set_privacy', # missing LinphonePrivacyMask
'linphone_tunnel_get_http_proxy', # to be handwritten because of double pointer indirection
'linphone_vcard_get_belcard', # specific to C++
'linphone_xml_rpc_request_new_with_args', # to be handwritten because of va_list
'lp_config_for_each_entry', # to be handwritten because of callback
'lp_config_for_each_section', # to be handwritten because of callback
'lp_config_get_range', # to be handwritten because of result via arguments
'lp_config_load_dict_to_section', # missing LinphoneDictionary
'lp_config_section_to_dict' # missing LinphoneDictionary
]
hand_written_functions = [
HandWrittenClassMethod('Buffer', 'new_from_data', 'linphone_buffer_new_from_data', "Create a new LinphoneBuffer object from existing data.\n\n:param data: The initial data to store in the LinphoneBuffer.\n:type data: ByteArray\n:returns: A new LinphoneBuffer object.\n:rtype: linphone.Buffer"),
......@@ -94,10 +99,9 @@ hand_written_functions = [
HandWrittenProperty('Core', 'sip_transports_used', 'linphone_core_get_sip_transports_used', None, "[:py:class:`linphone.SipTransports`] Retrieves the real port number assigned for each sip transport (udp, tcp, tls). A zero value means that the transport is not activated. If LC_SIP_TRANSPORT_RANDOM was passed to :py:attr:`linphone.Core.sip_transports`, the random port choosed by the system is returned."),
HandWrittenProperty('Core', 'sound_devices', 'linphone_core_get_sound_devices', None, "[list of string] Get the available sound devices."),
HandWrittenProperty('Core', 'video_devices', 'linphone_core_get_video_devices', None, "[list of string] Get the available video capture devices."),
HandWrittenProperty('LpConfig', 'sections_names', 'lp_config_get_sections_names', None, "[list of string] Get the sections' names in the lp config."),
HandWrittenClassMethod('Core', 'new', 'linphone_core_new', "Instantiate a LinphoneCore object.\n\n:param vtable: The callbacks.\n:type vtable: dictionary\n:param configPath: A path to a config file. If it does not exists it will be created. The config file is used to store all settings, call logs, friends, proxies... so that all these settings become persistent over the life of the LinphoneCore object. It is allowed to set to None. In that case LinphoneCore will not store any settings.\n:type configPath: string\n:param factoryConfigPath: A path to a read-only config file that can be used to store hard-coded preference such as proxy settings or internal preferences. The settings in this factory file always override the one in the normal config file. It is OPTIONAL, use None if unneeded.\n:type factoryConfigPath: string\n:rtype: linphone.Core"),
HandWrittenClassMethod('Core', 'new_with_config', 'linphone_core_new_with_config', "Instantiate a LinphoneCore object from a LpConfig.\n\n:param vtable: The callbacks.\n:type vtable: dictionary\n:param config: A LpConfig object holding the configuration of the LinphoneCore to be instantiated.\n:rtype: linphone.Core"),
HandWrittenDeallocMethod('Core', 'linphone_core_destroy')
HandWrittenProperty('Config', 'sections_names', 'linphone_config_get_sections_names', None, "[list of string] Get the sections' names in the lp config."),
HandWrittenInstanceMethod('Factory', 'create_core', 'linphone_factory_create_core', "Instanciate a LinphoneCore object.\n\nThe LinphoneCore object is the primary handle for doing all phone actions. It should be unique within your application.\n\n:param cbs: a LinphoneCoreCbs object holding your application callbacks. A reference will be taken on it until the destruciton of the core or the unregistration with linphone_core_remove_cbs().\n:type cbs: linphone.CoreCbs\n:param config_path: a path to a config file. If it does not exists it will be created. The config file is used to store all settings, call logs, friends, proxies... so that all these settings become persistent over the life of the LinphoneCore object. It is allowed to set a None config file. In that case LinphoneCore will not store any settings.\n:type config_path: string\n:param factory_config_path: a path to a read-only config file that can be used to to store hard-coded preference such as proxy settings or internal preferences. The settings in this factory file always override the one in the normal config file. It is OPTIONAL, use None if unneeded.\n:type factory_config_path: string\n:returns: \n:rtype: linphone.Core"),
HandWrittenInstanceMethod('Factory', 'create_core_with_config', 'linphone_factory_create_core_with_config', "Instantiates a LinphoneCore object with a given LpConfig.\n\n:param cbs: a LinphoneCoreCbs object holding your application callbacks. A reference will be taken on it until the destruciton of the core or the unregistration with linphone_core_remove_cbs().\n:type cbs: linphone.CoreCbs\n:param config: a pointer to an LpConfig object holding the configuration of the LinphoneCore to be instantiated.\n:type config: linphone.Config\n:returns: \n:rtype: linphone.Core"),
]
def generate(apixmlfile, outputfile):
......
static PyObject * pylinphone_Factory_instance_method_create_core(PyObject *self, PyObject *args);
static PyObject * pylinphone_Factory_instance_method_create_core_with_config(PyObject *self, PyObject *args);
static PyObject * pylinphone_Call_get_native_video_window_id(PyObject *self, void *closure);
static int pylinphone_Call_set_native_video_window_id(PyObject *self, PyObject *value, void *closure);
static PyObject * pylinphone_Core_get_native_preview_window_id(PyObject *self, void *closure);
......@@ -6,7 +8,6 @@ static PyObject * pylinphone_Core_get_native_video_window_id(PyObject *self, voi
static int pylinphone_Core_set_native_video_window_id(PyObject *self, PyObject *value, void *closure);
static PyObject * pylinphone_Core_get_sip_transports(PyObject *self, void *closure);
static int pylinphone_Core_set_sip_transports(PyObject *self, PyObject *value, void *closure);
static void pylinphone_Core_dealloc(PyObject *self);
static PyObject * pylinphone_Core_get_sip_transports_used(PyObject *self, void *closure);
static PyObject * pylinphone_Core_get_sound_devices(PyObject *self, void *closure);
static PyObject * pylinphone_Core_get_video_devices(PyObject *self, void *closure);
......@@ -44,4 +45,4 @@ static int pylinphone_Buffer_set_content(PyObject *self, PyObject *value, void *
static PyObject * pylinphone_Content_get_buffer(PyObject *self, void *closure);
static int pylinphone_Content_set_buffer(PyObject *self, PyObject *value, void *closure);
static PyObject * pylinphone_LpConfig_get_sections_names(PyObject *self, void *closure);
static PyObject * pylinphone_Config_get_sections_names(PyObject *self, void *closure);
......@@ -427,104 +427,107 @@ static void pylinphone_init_ms2_plugins(LinphoneCore *lc) {
linphone_core_reload_ms_plugins(lc, NULL);
}
static PyObject * pylinphone_Core_class_method_new(PyObject *cls, PyObject *args) {
static PyObject * pylinphone_Factory_instance_method_create_core(PyObject *self, PyObject *args) {
LinphoneCore * cresult;
pylinphone_CoreObject *self;
PyObject * pyresult;
PyObject * pyret;
LinphoneCoreVTable _vtable = { 0 };
PyObject * _vtable_dict;
const LinphoneFactory *native_ptr;
PyObject * _cbs;
LinphoneCoreCbs * _cbs_native_ptr = NULL;
const char * _config_path;
const char * _factory_config_path;
if (!PyArg_ParseTuple(args, "Ozz", &_vtable_dict, &_config_path, &_factory_config_path)) {
native_ptr = pylinphone_Factory_get_native_ptr(self);
if (native_ptr == NULL) {
PyErr_SetString(PyExc_TypeError, "Invalid linphone.Factory instance");
return NULL;
}
if (!PyDict_Check(_vtable_dict)) {
PyErr_SetString(PyExc_TypeError, "The first argument must be a dictionary");
if (!PyArg_ParseTuple(args, "Ozz", &_cbs, &_config_path, &_factory_config_path)) {
return NULL;
}
self = (pylinphone_CoreObject *)PyObject_CallObject((PyObject *) &pylinphone_CoreType, NULL);
if (self == NULL) {
if ((_cbs != Py_None) && !PyObject_IsInstance(_cbs, (PyObject *)&pylinphone_CoreCbsType)) {
PyErr_SetString(PyExc_TypeError, "The '_cbs' argument must be a linphone.CoreCbs instance.");
return NULL;
}
Py_INCREF(_vtable_dict);
self->vtable_dict = _vtable_dict;
{{#core_events}}
{{{event_vtable_reference}}}
{{/core_events}}
pylinphone_trace(1, "[PYLINPHONE] >>> %s(%p, \"%s\", \"%s\")", __FUNCTION__, _vtable_dict, _config_path, _factory_config_path);
cresult = linphone_core_new(&_vtable, _config_path, _factory_config_path, self);
self->native_ptr = cresult;
if ((_cbs != NULL) && (_cbs != Py_None)) {
if ((_cbs_native_ptr = pylinphone_CoreCbs_get_native_ptr(_cbs)) == NULL) {
return NULL;
}
}
pylinphone_trace(1, "[PYLINPHONE] >>> %s(%p [%p], %p [%p], \"%s\", \"%s\")", __FUNCTION__, self, native_ptr, _cbs, _cbs_native_ptr, _config_path, _factory_config_path);
cresult = linphone_factory_create_core(native_ptr, _cbs_native_ptr, _config_path, _factory_config_path);
Py_INCREF(_cbs);
pylinphone_init_ms2_plugins(cresult);
pyret = Py_BuildValue("O", self);
pylinphone_dispatch_messages();
pyresult = pylinphone_Core_from_native_ptr(&pylinphone_CoreType, cresult, FALSE);
pyret = Py_BuildValue("O", pyresult);
Py_XDECREF(pyresult);
pylinphone_trace(-1, "[PYLINPHONE] <<< %s -> %p", __FUNCTION__, pyret);
Py_DECREF(self);
return pyret;
}
static PyObject * pylinphone_Core_class_method_new_with_config(PyObject *cls, PyObject *args) {
static PyObject * pylinphone_Factory_instance_method_create_core_with_config(PyObject *self, PyObject *args) {
LinphoneCore * cresult;
pylinphone_CoreObject *self;
PyObject * pyresult;
PyObject * pyret;
LinphoneCoreVTable _vtable = { 0 };
PyObject * _vtable_dict;
const LinphoneFactory *native_ptr;
PyObject * _cbs;
LinphoneCoreCbs * _cbs_native_ptr = NULL;
PyObject * _config;
LpConfig * _config_native_ptr;
if (!PyArg_ParseTuple(args, "OO", &_vtable_dict, &_config)) {
LinphoneConfig * _config_native_ptr = NULL;
native_ptr = pylinphone_Factory_get_native_ptr(self);
if (native_ptr == NULL) {
PyErr_SetString(PyExc_TypeError, "Invalid linphone.Factory instance");
return NULL;
}
if (!PyDict_Check(_vtable_dict)) {
PyErr_SetString(PyExc_TypeError, "The first argument must be a dictionary");
if (!PyArg_ParseTuple(args, "OO", &_cbs, &_config)) {
return NULL;
}
if ((_config_native_ptr = pylinphone_LpConfig_get_native_ptr(_config)) == NULL) {
if ((_cbs != Py_None) && !PyObject_IsInstance(_cbs, (PyObject *)&pylinphone_CoreCbsType)) {
PyErr_SetString(PyExc_TypeError, "The '_cbs' argument must be a linphone.CoreCbs instance.");
return NULL;
}
self = (pylinphone_CoreObject *)PyObject_CallObject((PyObject *) &pylinphone_CoreType, NULL);
if (self == NULL) {
if ((_config != Py_None) && !PyObject_IsInstance(_config, (PyObject *)&pylinphone_ConfigType)) {
PyErr_SetString(PyExc_TypeError, "The '_config' argument must be a linphone.Config instance.");
return NULL;
}
Py_INCREF(_vtable_dict);
self->vtable_dict = _vtable_dict;
{{#core_events}}
{{{event_vtable_reference}}}
{{/core_events}}
pylinphone_trace(1, "[PYLINPHONE] >>> %s(%p [%p])", __FUNCTION__, _config, _config_native_ptr);
cresult = linphone_core_new_with_config(&_vtable, _config_native_ptr, self);
self->native_ptr = cresult;
if ((_config != NULL) && (_config != Py_None)) {
if ((_config_native_ptr = pylinphone_Config_get_native_ptr(_config)) == NULL) {
return NULL;
}
}
if ((_cbs != NULL) && (_cbs != Py_None)) {
if ((_cbs_native_ptr = pylinphone_CoreCbs_get_native_ptr(_cbs)) == NULL) {
return NULL;
}
}
pylinphone_trace(1, "[PYLINPHONE] >>> %s(%p [%p], %p [%p], %p [%p])", __FUNCTION__, self, native_ptr, _cbs, _cbs_native_ptr, _config, _config_native_ptr);
cresult = linphone_factory_create_core_with_config(native_ptr, _cbs_native_ptr, _config_native_ptr);
Py_INCREF(_cbs);
pylinphone_init_ms2_plugins(cresult);
pyret = Py_BuildValue("O", self);
pylinphone_dispatch_messages();
pyresult = pylinphone_Core_from_native_ptr(&pylinphone_CoreType, cresult, FALSE);
pyret = Py_BuildValue("O", pyresult);
Py_XDECREF(pyresult);
pylinphone_trace(-1, "[PYLINPHONE] <<< %s -> %p", __FUNCTION__, pyret);
Py_DECREF(self);
return pyret;
}
static void pylinphone_Core_dealloc(PyObject *self) {
LinphoneCore * native_ptr = pylinphone_Core_get_native_ptr(self);
if (Py_REFCNT(self) < 0) return;
pylinphone_trace(1, "[PYLINPHONE] >>> %s(%p [%p])", __FUNCTION__, self, native_ptr);
if (native_ptr != NULL) {
linphone_core_destroy(native_ptr);
}
pylinphone_dispatch_messages();
Py_XDECREF(((pylinphone_CoreObject *)self)->user_data);
Py_XDECREF(((pylinphone_CoreObject *)self)->vtable_dict);
self->ob_type->tp_free(self);
pylinphone_trace(-1, "[PYLINPHONE] <<< %s", __FUNCTION__);
}
......@@ -994,18 +997,18 @@ static int pylinphone_Content_set_buffer(PyObject *self, PyObject *value, void *
return 0;
}
static PyObject * pylinphone_LpConfig_get_sections_names(PyObject *self, void *closure) {
static PyObject * pylinphone_Config_get_sections_names(PyObject *self, void *closure) {
PyObject *_list;
const char **_names;
LpConfig *native_ptr = pylinphone_LpConfig_get_native_ptr(self);
LinphoneConfig *native_ptr = pylinphone_Config_get_native_ptr(self);
if (native_ptr == NULL) {
PyErr_SetString(PyExc_TypeError, "Invalid linphone.LpConfig instance");
PyErr_SetString(PyExc_TypeError, "Invalid linphone.Config instance");
return NULL;
}
pylinphone_trace(1, "[PYLINPHONE] >>> %s(%p [%p])", __FUNCTION__, self, native_ptr);
_names = lp_config_get_sections_names(native_ptr);
_names = linphone_config_get_sections_names(native_ptr);
pylinphone_dispatch_messages();
_list = PyList_New(0);
......
......@@ -383,6 +383,7 @@ class MethodDefinition:
arg_names = []
c_function_call_code = ''
cfree_argument_code = ''
python_ref_code = ''
for xml_method_arg in self.xml_method_args:
arg_name = "_" + xml_method_arg.get('name')
arg_type = xml_method_arg.get('type')
......@@ -410,17 +411,24 @@ class MethodDefinition:
if len(arg_names) > 0:
c_function_call_code += ', '
c_function_call_code += ', '.join(arg_names) + ");"
if self.method_name == 'add_callbacks':
python_ref_code = "Py_INCREF(_cbs);"
elif self.method_name == 'remove_callbacks':
python_ref_code = "Py_XDECREF(_cbs);"
from_native_pointer_code = ''
convert_from_code = ''
build_value_code = ''
cfree_code = ''
result_variable = ''
take_native_ref = 'TRUE'
if self.return_complete_type != 'void':
if self.build_value_format == 'O':
stripped_return_type = strip_leading_linphone(self.return_type)
return_type_class = self.find_class_definition(self.return_type)
if return_type_class is not None:
from_native_pointer_code = "pyresult = pylinphone_{return_type}_from_native_ptr(&pylinphone_{return_type}Type, cresult);\n".format(return_type=stripped_return_type)
if self.method_name.startswith('create'):
take_native_ref = 'FALSE'
from_native_pointer_code = "pyresult = pylinphone_{return_type}_from_native_ptr(&pylinphone_{return_type}Type, cresult, {take_native_ref});\n".format(return_type=stripped_return_type, take_native_ref=take_native_ref)
else:
return_argument_type = ArgumentType(self.return_type, self.return_complete_type, self.return_contained_type, self.linphone_module)
if return_argument_type.convert_from_func is not None:
......@@ -436,11 +444,15 @@ class MethodDefinition:
result_variable = 'cresult'
if result_variable != '':
build_value_code = "pyret = Py_BuildValue(\"{fmt}\", {result_variable});".format(fmt=self.build_value_format, result_variable=result_variable)
if take_native_ref == 'FALSE':
build_value_code += """
Py_XDECREF(pyresult);"""
if self.return_complete_type == 'char *':
cfree_code = 'ms_free(cresult);';
body = \
""" {c_function_call_code}
{cfree_argument_code}
{python_ref_code}
pylinphone_dispatch_messages();
{from_native_pointer_code}
{convert_from_code}
......@@ -448,6 +460,7 @@ class MethodDefinition:
{cfree_code}
""".format(c_function_call_code=c_function_call_code,
cfree_argument_code=cfree_argument_code,
python_ref_code=python_ref_code,
from_native_pointer_code=from_native_pointer_code,
convert_from_code=convert_from_code,
build_value_code=build_value_code,
......@@ -563,6 +576,15 @@ class MethodDefinition:
return c
return None
def find_property_definition(self, basic_type, property_name):
class_definition = self.find_class_definition(basic_type)
if class_definition is None:
return None
for p in class_definition['class_properties']:
if p['property_name'] == property_name:
return p
return None
def format(self):
self.parse_method_node()
body = self.format_local_variables_definition()
......@@ -646,7 +668,7 @@ class FromNativePointerMethodDefinition(MethodDefinition):
set_user_data_func_call = "{function_prefix}set_user_data(self->native_ptr, self);".format(function_prefix=self.class_['class_c_function_prefix'])
ref_native_pointer_code = ''
if self.class_['class_refcountable']:
ref_native_pointer_code = "{func}(self->native_ptr);".format(func=self.class_['class_c_function_prefix'] + "ref")
ref_native_pointer_code = "if (take_native_ref == TRUE) {func}(self->native_ptr);".format(func=self.class_['class_c_function_prefix'] + "ref")
return \
""" if (native_ptr == NULL) {{
{none_trace}
......@@ -858,6 +880,11 @@ class EventCallbackMethodDefinition(MethodDefinition):
nocallbacks_class_name = class_name
if class_name.endswith('Cbs'):
nocallbacks_class_name = class_name[:-3]
has_current_callbacks = self.find_property_definition(nocallbacks_class_name, 'current_callbacks')
if has_current_callbacks is not None:
get_callbacks_funcname = 'get_current_callbacks'
else:
get_callbacks_funcname = 'get_callbacks'
returnvars = self.format_local_return_variables_definition()
common = \
""" pylinphone_{class_name}Object *pyself = (pylinphone_{class_name}Object *){function_prefix}get_user_data(self);
......@@ -866,8 +893,8 @@ class EventCallbackMethodDefinition(MethodDefinition):
PyGILState_STATE pygil_state;""".format(class_name=nocallbacks_class_name, function_prefix=self.find_class_definition(nocallbacks_class_name)['class_c_function_prefix'])
if class_name.endswith('Cbs'):
common += """
pylinphone_{class_name}Object *pycbs = (pylinphone_{class_name}Object *){cbs_function_prefix}get_user_data({function_prefix}get_callbacks(self));
""".format(class_name=class_name, cbs_function_prefix=self.find_class_definition(class_name)['class_c_function_prefix'], function_prefix=self.find_class_definition(nocallbacks_class_name)['class_c_function_prefix'])
pylinphone_{class_name}Object *pycbs = (pylinphone_{class_name}Object *){cbs_function_prefix}get_user_data({function_prefix}{get_callbacks_funcname}(self));
""".format(class_name=class_name, cbs_function_prefix=self.find_class_definition(class_name)['class_c_function_prefix'], function_prefix=self.find_class_definition(nocallbacks_class_name)['class_c_function_prefix'], get_callbacks_funcname=get_callbacks_funcname)
specific = ''
for xml_method_arg in self.xml_method_args:
arg_name = xml_method_arg.get('name')
......@@ -889,14 +916,7 @@ class EventCallbackMethodDefinition(MethodDefinition):
argument_type = ArgumentType(self.return_type, self.return_complete_type, self.return_contained_type, self.linphone_module)
if argument_type.fmt_str == 'O':
return_str = 'NULL'
if self.class_['event_class'] == 'Core':
return \
""" if (Py_REFCNT(pyself) <= 0) return {return_str};
func = PyDict_GetItemString(pyself->vtable_dict, "{name}");
pygil_state = PyGILState_Ensure();
""".format(name=self.class_['event_name'], return_str=return_str)
else:
return \
return \
""" if (Py_REFCNT(pyself) <= 0) return {return_str};
func = pycbs->{event_name};
pygil_state = PyGILState_Ensure();
......@@ -941,7 +961,7 @@ class EventCallbackMethodDefinition(MethodDefinition):
create_python_objects_code += "\t\tpy{name} = {convert_from_func}({name});\n".format(name=arg_name, convert_from_func=argument_type.convert_from_func)
else:
type_class = self.find_class_definition(arg_type)
create_python_objects_code += "\t\tpy{name} = pylinphone_{arg_type}_from_native_ptr(&pylinphone_{arg_type}Type, {name});\n".format(name=arg_name, arg_type=strip_leading_linphone(arg_type))
create_python_objects_code += "\t\tpy{name} = pylinphone_{arg_type}_from_native_ptr(&pylinphone_{arg_type}Type, {name}, TRUE);\n".format(name=arg_name, arg_type=strip_leading_linphone(arg_type))
args=', '.join(args)
if self.return_complete_type != 'void':
argument_type = ArgumentType(self.return_type, self.return_complete_type, self.return_contained_type, self.linphone_module)
......@@ -1078,9 +1098,6 @@ class LinphoneModule(object):
c['class_object_members'] = []
c['class_object_members_code'] = ''
c['class_events'] = []
if c['class_name'] == 'Core':
c['class_object_members'].append("vtable_dict")
c['class_object_members_code'] = "\tPyObject *vtable_dict;"
xml_events = xml_class.findall("./events/event")
for xml_event in xml_events:
if xml_event.get('name') in blacklisted_events:
......@@ -1091,12 +1108,9 @@ class LinphoneModule(object):
ev['event_cname'] = xml_event.get('name')
ev['event_name'] = compute_event_name(ev['event_cname'], c['class_name'])
ev['event_doc'] = self.__format_doc(xml_event.find('briefdescription'), xml_event.find('detaileddescription'))
if c['class_name'] == 'Core':
self.core_events.append(ev)
else:
c['class_events'].append(ev)
c['class_object_members'].append(ev['event_name'])
c['class_object_members_code'] += "\tPyObject *" + ev['event_name'] + ";\n"
c['class_events'].append(ev)
c['class_object_members'].append(ev['event_name'])
c['class_object_members_code'] += "\tPyObject *" + ev['event_name'] + ";\n"
for hand_written_code in hand_written_codes:
if hand_written_code._class == c['class_name']:
if isinstance(hand_written_code, HandWrittenClassMethod):
......@@ -1190,9 +1204,6 @@ class LinphoneModule(object):
c['class_properties'].append(p)
self.classes.append(c)
# Format events definitions
for ev in self.core_events:
ev['event_callback_definition'] = EventCallbackMethodDefinition(self, ev, ev['event_name'], ev['event_xml_node']).format()
ev['event_vtable_reference'] = "_vtable.{name} = pylinphone_Core_callback_{name};".format(name=ev['event_name'])
for c in self.classes:
for ev in c['class_events']:
ev['event_callback_definition'] = EventCallbackMethodDefinition(self, ev, ev['event_name'], ev['event_xml_node']).format()
......
......@@ -19,9 +19,11 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include <Python.h>
#include <structmember.h>
#include <datetime.h>
#include <linphone/linphonecore.h>
#include <linphone/linphone_tunnel.h>
#include <linphone/linphonecore_utils.h>
#include <linphone/core.h>
#include <linphone/tunnel.h>
#include <linphone/core_utils.h>
#include <linphone/wrapper_utils.h>
#include <belle-sip/belle-sip.h>
#include <stdarg.h>
#include "gitversion.h"
......@@ -62,7 +64,7 @@ typedef struct {
{{#classes}}
static {{class_cname}} * pylinphone_{{class_name}}_get_native_ptr(PyObject *self);
static PyObject * pylinphone_{{class_name}}_from_native_ptr(PyTypeObject *type, const {{class_cname}} *native_ptr);
static PyObject * pylinphone_{{class_name}}_from_native_ptr(PyTypeObject *type, const {{class_cname}} *native_ptr, bool_t take_native_ref);
{{#class_type_hand_written_methods}}
static PyObject * pylinphone_{{class_name}}_class_method_{{method_name}}(PyObject *cls, PyObject *args);
{{/class_type_hand_written_methods}}
......@@ -76,7 +78,7 @@ PyObject * PyList_FromBctbxListOf{{c_contained_type}}(const bctbx_list_t *msl) {
PyObject *pyl = PyList_New(0);
while (msl != NULL) {
{{c_contained_type}} *native_ptr = ({{c_contained_type}} *)msl->data;
PyObject *item = pylinphone_{{python_contained_type}}_from_native_ptr(&pylinphone_{{python_contained_type}}Type, native_ptr);
PyObject *item = pylinphone_{{python_contained_type}}_from_native_ptr(&pylinphone_{{python_contained_type}}Type, native_ptr, TRUE);
PyList_Append(pyl, item);
msl = bctbx_list_next(msl);
}
......@@ -113,7 +115,7 @@ static {{class_cname}} * pylinphone_{{class_name}}_get_native_ptr(PyObject *self
return ((pylinphone_{{class_name}}Object *)self)->native_ptr;
}
static PyObject * pylinphone_{{class_name}}_from_native_ptr(PyTypeObject *type, const {{class_cname}} *native_ptr) {
static PyObject * pylinphone_{{class_name}}_from_native_ptr(PyTypeObject *type, const {{class_cname}} *native_ptr, bool_t take_native_ref) {
{{{from_native_pointer_body}}}
}
......
......@@ -39,7 +39,7 @@ linphone.set_log_handler(linphonetester_log_handler)
def create_address(domain):
addr = linphone.Address.new(None)
addr = linphone.Factory.get().create_address(None)
assert addr != None
addr.username = test_username
assert_equals(addr.username, test_username)
......@@ -121,7 +121,7 @@ class AccountManager:
self._create_account_on_server(account, cfg)
if original_ai is not None:
lc.remove_auth_info(original_ai)
ai = linphone.AuthInfo.new(account.modified_identity.username, None, account.password, None, None, account.modified_identity.domain)
ai = linphone.Factory.get().create_auth_info(account.modified_identity.username, None, account.password, None, None, account.modified_identity.domain)
lc.add_auth_info(ai)
return account.modified_identity
......@@ -132,18 +132,18 @@ class AccountManager:
return None
def _create_account_on_server(self, account, refcfg):
vtable = {}
tmp_identity = account.modified_identity.clone()
vtable['registration_state_changed'] = AccountManager.account_created_on_server_cb
vtable['auth_info_requested'] = AccountManager.account_created_auth_requested_cb
lc = CoreManager.configure_lc_from(vtable, tester_resources_path, None, account)
cbs = linphone.Factory.get().create_core_cbs()
cbs.registration_state_changed = AccountManager.account_created_on_server_cb
cbs.authentication_requested = AccountManager.account_created_auth_requested_cb
lc = CoreManager.configure_lc_from(cbs, tester_resources_path, None, account)
lc.sip_transports = linphone.SipTransports(-1, -1, -1, -1)
cfg = lc.create_proxy_config()
tmp_identity.secure = False
tmp_identity.password = account.password
tmp_identity.set_header("X-Create-Account", "yes")
cfg.identity_address = tmp_identity
server_addr = linphone.Address.new(refcfg.server_addr)
server_addr = linphone.Factory.get().create_address(refcfg.server_addr)
server_addr.secure = False
server_addr.transport = linphone.TransportType.Tcp;
server_addr.port = 0
......@@ -157,7 +157,7 @@ class AccountManager:
cfg.identity_address = account.modified_identity.clone()
cfg.identity_address.secure = False
cfg.done()
ai = linphone.AuthInfo.new(account.modified_identity.username, None, account.password, None, None, account.modified_identity.domain)
ai = linphone.Factory.get().create_auth_info(account.modified_identity.username, None, account.password, None, None, account.modified_identity.domain)
lc.add_auth_info(ai)
if AccountManager.wait_for_until(lc, None, lambda lc: lc.user_data().registered == True, 3000) != True:
linphonetester_logger.critical("[TESTER] Account for {identity} is not working on server.".format(identity=refcfg.identity_address.as_string()))
......@@ -289,12 +289,12 @@ class CoreManagerStats:
class CoreManager:
@classmethod
def configure_lc_from(cls, vtable, resources_path, rc_path, user_data=None):
def configure_lc_from(cls, cbs, resources_path, rc_path, user_data=None):
filepath = None
if rc_path is not None:
filepath = os.path.join(resources_path, rc_path)
assert_equals(os.path.isfile(filepath), True)
lc = linphone.Core.new(vtable, None, filepath)
lc = linphone.Factory.get().create_core(cbs, None, filepath)
linphone.testing.set_dns_user_hosts_file(lc, os.path.join(resources_path, 'tester_hosts'))
lc.root_ca = os.path.join(resources_path, 'certificates', 'cn', 'cafile.pem')
lc.ring = os.path.join(resources_path, 'sounds', 'oldphone.wav')
......@@ -419,10 +419,10 @@ class CoreManager:
raise Exception("Unexpected registration state")
@classmethod
def auth_info_requested(cls, lc, realm, username, domain):
def authentication_requested(cls, lc, auth_info, method):
manager = lc.user_data()
linphonetester_logger.info("[TESTER] Auth info requested for user id [{username}] at realm [{realm}]".format(
username=username, realm=realm))
username=auth_info.username, realm=auth_info.realm))
manager.stats.number_of_auth_info_requested +=1
@classmethod
......@@ -576,41 +576,22 @@ class CoreManager:
else:
manager.stats.number_of_LinphonePresenceActivityOffline += 1
def __init__(self, rc_file = None, check_for_proxies = True, vtable = {}):
if not vtable.has_key('registration_state_changed'):
vtable['registration_state_changed'] = CoreManager.registration_state_changed
if not vtable.has_key('auth_info_requested'):
vtable['auth_info_requested'] = CoreManager.auth_info_requested
if not vtable.has_key('call_state_changed'):
vtable['call_state_changed'] = CoreManager.call_state_changed
if not vtable.has_key('message_received'):
vtable['message_received'] = CoreManager.message_received
#if not vtable.has_key('is_composing_received'):
#vtable['is_composing_received'] = CoreManager.is_composing_received
if not vtable.has_key('new_subscription_requested'):
vtable['new_subscription_requested'] = CoreManager.new_subscription_requested
if not vtable.has_key('notify_presence_received'):
vtable['notify_presence_received'] = CoreManager.notify_presence_received
#if not vtable.has_key('transfer_state_changed'):
#vtable['transfer_state_changed'] = CoreManager.transfer_state_changed
#if not vtable.has_key('info_received'):
#vtable['info_received'] = CoreManager.info_received
#if not vtable.has_key('subscription_state_changed'):
#vtable['subscription_state_changed'] = CoreManager.subscription_state_changed
#if not vtable.has_key('notify_received'):
#vtable['notify_received'] = CoreManager.notify_received
#if not vtable.has_key('publish_state_changed'):
#vtable['publish_state_changed'] = CoreManager.publish_state_changed
#if not vtable.has_key('configuring_status'):
#vtable['configuring_status'] = CoreManager.configuring_status
#if not vtable.has_key('call_encryption_changed'):
#vtable['call_encryption_changed'] = CoreManager.call_encryption_changed
def __init__(self, rc_file = None, check_for_proxies = True, additional_cbs = None):
cbs = linphone.Factory.get().create_core_cbs()
cbs.registration_state_changed = CoreManager.registration_state_changed
cbs.authentication_requested = CoreManager.authentication_requested
cbs.call_state_changed = CoreManager.call_state_changed
cbs.message_received = CoreManager.message_received
cbs.new_subscription_requested = CoreManager.new_subscription_requested
cbs.notify_presence_received = CoreManager.notify_presence_received
self.identity = None
self.stats = CoreManagerStats()
rc_path = None