From ab30b93098eb13596c37e06e355bff7bbc1f83f4 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Wed, 13 Aug 2014 13:38:20 +0200 Subject: [PATCH 01/43] Blacklist linphone_core_get_video_devices() in the Python wrapper. --- tools/python/apixml2python.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/python/apixml2python.py b/tools/python/apixml2python.py index 810dc3edc..dd66dc1ec 100755 --- a/tools/python/apixml2python.py +++ b/tools/python/apixml2python.py @@ -71,6 +71,7 @@ blacklisted_functions = [ 'linphone_core_get_sip_transports_used', # missing LCSipTransports 'linphone_core_get_supported_video_sizes', # missing MSVideoSizeDef 'linphone_core_get_video_codecs', # missing PayloadType and MSList + 'linphone_core_get_video_devices', # returns a list of strings 'linphone_core_get_video_policy', # missing LinphoneVideoPolicy 'linphone_core_payload_type_enabled', # missing PayloadType 'linphone_core_payload_type_is_vbr', # missing PayloadType From d9f02dd6325974eb06ab589c22878c8df4497955 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Wed, 13 Aug 2014 13:38:39 +0200 Subject: [PATCH 02/43] Do not rely on the ChatRoom object to set the send message callback in the Python wrapper. --- .../handwritten_definitions.mustache | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/tools/python/apixml2python/handwritten_definitions.mustache b/tools/python/apixml2python/handwritten_definitions.mustache index dd19be207..73baddea6 100644 --- a/tools/python/apixml2python/handwritten_definitions.mustache +++ b/tools/python/apixml2python/handwritten_definitions.mustache @@ -197,9 +197,11 @@ static PyObject * pylinphone_Core_class_method_new_with_config(PyObject *cls, Py static void pylinphone_ChatRoom_callback_chat_message_state_changed(LinphoneChatMessage *msg, LinphoneChatMessageState state, void *ud) { PyGILState_STATE pygil_state; - PyObject * pycm = NULL; - PyObject * func = NULL; - pylinphone_ChatRoomObject *pycr = (pylinphone_ChatRoomObject *)ud; + PyObject *pycm = NULL; + PyObject *func = NULL; + PyObject *_dict = (PyObject *)ud; + PyObject *_cb = PyDict_GetItemString(_dict, "callback"); + PyObject *_ud = PyDict_GetItemString(_dict, "user_data"); pygil_state = PyGILState_Ensure(); pycm = linphone_chat_message_get_user_data(msg); @@ -207,8 +209,8 @@ static void pylinphone_ChatRoom_callback_chat_message_state_changed(LinphoneChat pycm = pylinphone_ChatMessage_new_from_native_ptr(&pylinphone_ChatMessageType, msg); } pylinphone_trace(1, "[PYLINPHONE] >>> %s(%p, %p [%p], %d, %p)", __FUNCTION__, pycm, msg, state, ud); - if ((pycr->send_message_cb != NULL) && PyCallable_Check(pycr->send_message_cb)) { - if (PyEval_CallObject(pycr->send_message_cb, Py_BuildValue("OiO", pycm, state, pycr->send_message_ud)) == NULL) { + if ((_cb != NULL) && PyCallable_Check(_cb)) { + if (PyEval_CallObject(_cb, Py_BuildValue("OiO", pycm, state, _ud)) == NULL) { PyErr_Print(); } } @@ -218,6 +220,7 @@ static void pylinphone_ChatRoom_callback_chat_message_state_changed(LinphoneChat static PyObject * pylinphone_ChatRoom_instance_method_send_message2(PyObject *self, PyObject *args) { PyObject *_chat_message; + PyObject *_dict; PyObject *_cb; PyObject *_ud; LinphoneChatMessage * _chat_message_native_ptr; @@ -234,18 +237,19 @@ static PyObject * pylinphone_ChatRoom_instance_method_send_message2(PyObject *se PyErr_SetString(PyExc_TypeError, "The msg argument must be a linphone.ChatMessage"); return NULL; } - if (!PyCallable_Check(_cb)) { + if ((_cb != Py_None) && !PyCallable_Check(_cb)) { PyErr_SetString(PyExc_TypeError, "The status_cb argument must be a callable"); return NULL; } if ((_chat_message_native_ptr = pylinphone_ChatMessage_get_native_ptr(_chat_message)) == NULL) { return NULL; } + _dict = PyDict_New(); + PyDict_SetItemString(_dict, "callback", _cb); + PyDict_SetItemString(_dict, "user_data", _ud); pylinphone_trace(1, "[PYLINPHONE] >>> %s(%p [%p], %p [%p], %p, %p)", __FUNCTION__, self, native_ptr, _chat_message, _chat_message_native_ptr, _cb, _ud); - ((pylinphone_ChatRoomObject *)self)->send_message_cb = _cb; - ((pylinphone_ChatRoomObject *)self)->send_message_ud = _ud; - linphone_chat_room_send_message2(native_ptr, _chat_message_native_ptr, pylinphone_ChatRoom_callback_chat_message_state_changed, self); + linphone_chat_room_send_message2(native_ptr, _chat_message_native_ptr, pylinphone_ChatRoom_callback_chat_message_state_changed, _dict); pylinphone_dispatch_messages(); pylinphone_trace(-1, "[PYLINPHONE] <<< %s -> None", __FUNCTION__); From 551fa6bc930ca830bf7459a5aaaf21900d336f03 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Wed, 13 Aug 2014 14:10:09 +0200 Subject: [PATCH 03/43] Blacklist linphone_core_get_audio_port_range() and linphone_core_get_video_port_range() functions in the Python wrapper. --- tools/python/apixml2python.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/python/apixml2python.py b/tools/python/apixml2python.py index dd66dc1ec..f71cbb7eb 100755 --- a/tools/python/apixml2python.py +++ b/tools/python/apixml2python.py @@ -59,6 +59,7 @@ blacklisted_functions = [ 'linphone_core_enable_payload_type', # missing PayloadType 'linphone_core_find_payload_type', # missing PayloadType 'linphone_core_get_audio_codecs', # missing PayloadType and MSList + 'linphone_core_get_audio_port_range', # to be handwritten because of result via arguments 'linphone_core_get_auth_info_list', # missing MSList 'linphone_core_get_call_logs', # missing MSList 'linphone_core_get_calls', # missing MSList @@ -73,6 +74,7 @@ blacklisted_functions = [ 'linphone_core_get_video_codecs', # missing PayloadType and MSList 'linphone_core_get_video_devices', # returns a list of strings 'linphone_core_get_video_policy', # missing LinphoneVideoPolicy + 'linphone_core_get_video_port_range', # to be handwritten because of result via arguments 'linphone_core_payload_type_enabled', # missing PayloadType 'linphone_core_payload_type_is_vbr', # missing PayloadType 'linphone_core_publish', # missing LinphoneContent From d5332aa80a66711e4c97fcf2430c0c3a1abd37b9 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Wed, 13 Aug 2014 14:11:27 +0200 Subject: [PATCH 04/43] Document arguments type in the Python wrapper. --- .../handwritten_definitions.mustache | 4 +-- tools/python/apixml2python/linphone.py | 36 ++++++++++++++++--- 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/tools/python/apixml2python/handwritten_definitions.mustache b/tools/python/apixml2python/handwritten_definitions.mustache index 73baddea6..6b6a4eecf 100644 --- a/tools/python/apixml2python/handwritten_definitions.mustache +++ b/tools/python/apixml2python/handwritten_definitions.mustache @@ -284,8 +284,8 @@ static int pylinphone_VideoSize_init(PyObject *self, PyObject *args, PyObject *k } static PyMemberDef pylinphone_VideoSize_members[] = { - { "width", T_INT, offsetof(pylinphone_VideoSizeObject, vs) + offsetof(MSVideoSize, width), 0, "The width of the video" }, - { "height", T_INT, offsetof(pylinphone_VideoSizeObject, vs) + offsetof(MSVideoSize, height), 0, "The height of the video" }, + { "width", T_INT, offsetof(pylinphone_VideoSizeObject, vs) + offsetof(MSVideoSize, width), 0, "[int] The width of the video" }, + { "height", T_INT, offsetof(pylinphone_VideoSizeObject, vs) + offsetof(MSVideoSize, height), 0, "[int] The height of the video" }, { NULL } /* Sentinel */ }; diff --git a/tools/python/apixml2python/linphone.py b/tools/python/apixml2python/linphone.py index 7d3fe6280..4a6fc98fd 100644 --- a/tools/python/apixml2python/linphone.py +++ b/tools/python/apixml2python/linphone.py @@ -151,7 +151,10 @@ class ArgumentType: self.fmt_str = 'i' self.cfmt_str = '%d' elif '*' in splitted_type: + self.type_str = 'linphone.' + strip_leading_linphone(self.basic_type) self.use_native_pointer = True + else: + self.type_str = 'linphone.' + strip_leading_linphone(self.basic_type) class MethodDefinition: @@ -849,11 +852,11 @@ class LinphoneModule(object): p['property_doc'] = '' if p.has_key('setter_xml_node'): p['setter_body'] = SetterMethodDefinition(self, c, p['setter_xml_node']).format() - p['property_doc'] = self.__format_doc(p['setter_xml_node'].find('briefdescription'), p['setter_xml_node'].find('detaileddescription')) + p['property_doc'] = self.__format_setter_doc(p['setter_xml_node']) if p.has_key('getter_xml_node'): p['getter_body'] = GetterMethodDefinition(self, c, p['getter_xml_node']).format() if p['property_doc'] == '': - p['property_doc'] = self.__format_doc(p['getter_xml_node'].find('briefdescription'), p['getter_xml_node'].find('detaileddescription')) + p['property_doc'] = self.__format_getter_doc(p['getter_xml_node']) except Exception, e: e.args += (c['class_name'], p['property_name']) raise @@ -932,14 +935,39 @@ class LinphoneModule(object): doc += "\n\nArguments:" for xml_method_arg in xml_method_args: arg_name = xml_method_arg.get('name') + arg_type = xml_method_arg.get('type') + arg_complete_type = xml_method_arg.get('completetype') + argument_type = ArgumentType(arg_type, arg_complete_type, self) arg_doc = self.__format_doc_content(None, xml_method_arg.find('description')) - doc += '\n\t' + arg_name + doc += '\n\t' + arg_name + ' [' + argument_type.type_str + ']' if arg_doc != '': doc += ': ' + arg_doc if xml_method_return is not None: + return_type = xml_method_return.get('type') return_complete_type = xml_method_return.get('completetype') if return_complete_type != 'void': return_doc = self.__format_doc_content(None, xml_method_return.find('description')) - doc += '\n\nReturns:\n\t' + return_doc + return_argument_type = ArgumentType(return_type, return_complete_type, self) + doc += '\n\nReturns:\n\t[' + return_argument_type.type_str + '] ' + return_doc + doc = self.__replace_doc_special_chars(doc) + return doc + + def __format_setter_doc(self, xml_node): + xml_method_arg = xml_node.findall('./arguments/argument')[1] + arg_type = xml_method_arg.get('type') + arg_complete_type = xml_method_arg.get('completetype') + argument_type = ArgumentType(arg_type, arg_complete_type, self) + doc = self.__format_doc_content(xml_node.find('briefdescription'), xml_node.find('detaileddescription')) + doc = '[' + argument_type.type_str + '] ' + doc + doc = self.__replace_doc_special_chars(doc) + return doc + + def __format_getter_doc(self, xml_node): + xml_method_return = xml_node.find('./return') + return_type = xml_method_return.get('type') + return_complete_type = xml_method_return.get('completetype') + return_argument_type = ArgumentType(return_type, return_complete_type, self) + doc = self.__format_doc_content(xml_node.find('briefdescription'), xml_node.find('detaileddescription')) + doc = '[' + return_argument_type.type_str + '] ' + doc doc = self.__replace_doc_special_chars(doc) return doc From efacfee3a3aa855c099210a7e0abb20d2f979b34 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Wed, 13 Aug 2014 14:28:48 +0200 Subject: [PATCH 05/43] Standardize user_data/user_pointer naming. --- coreapi/linphonecall.c | 4 ++-- coreapi/linphonecore.c | 4 ++-- coreapi/linphonecore.h | 16 ++++++++++++---- tools/python/apixml2python.py | 4 ---- 4 files changed, 16 insertions(+), 12 deletions(-) diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index c650894b3..459c8c92f 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -1146,7 +1146,7 @@ const LinphoneErrorInfo *linphone_call_get_error_info(const LinphoneCall *call){ * * return user_pointer an opaque user pointer that can be retrieved at any time **/ -void *linphone_call_get_user_pointer(LinphoneCall *call) +void *linphone_call_get_user_data(LinphoneCall *call) { return call->user_pointer; } @@ -1158,7 +1158,7 @@ void *linphone_call_get_user_pointer(LinphoneCall *call) * * the user_pointer is an opaque user pointer that can be retrieved at any time in the LinphoneCall **/ -void linphone_call_set_user_pointer(LinphoneCall *call, void *user_pointer) +void linphone_call_set_user_data(LinphoneCall *call, void *user_pointer) { call->user_pointer = user_pointer; } diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 6818b1415..93f30606e 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -288,14 +288,14 @@ const char *linphone_call_log_get_call_id(const LinphoneCallLog *cl){ /** * Assign a user pointer to the call log. **/ -void linphone_call_log_set_user_pointer(LinphoneCallLog *cl, void *up){ +void linphone_call_log_set_user_data(LinphoneCallLog *cl, void *up){ cl->user_pointer=up; } /** * Returns the user pointer associated with the call log. **/ -void *linphone_call_log_get_user_pointer(const LinphoneCallLog *cl){ +void *linphone_call_log_get_user_data(const LinphoneCallLog *cl){ return cl->user_pointer; } diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index 9fdb864df..b08c75395 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -356,8 +356,12 @@ LINPHONE_PUBLIC bool_t linphone_call_log_video_enabled(LinphoneCallLog *cl); LINPHONE_PUBLIC time_t linphone_call_log_get_start_date(LinphoneCallLog *cl); LINPHONE_PUBLIC int linphone_call_log_get_duration(LinphoneCallLog *cl); LINPHONE_PUBLIC float linphone_call_log_get_quality(LinphoneCallLog *cl); -LINPHONE_PUBLIC void linphone_call_log_set_user_pointer(LinphoneCallLog *cl, void *up); -LINPHONE_PUBLIC void *linphone_call_log_get_user_pointer(const LinphoneCallLog *cl); +/** @deprecated Use linphone_call_log_set_user_data() instead. */ +#define linphone_call_log_set_user_pointer(cl, ud) linphone_call_log_set_user_data(cl, ud) +LINPHONE_PUBLIC void linphone_call_log_set_user_data(LinphoneCallLog *cl, void *up); +/** @deprecated Use linphone_call_log_get_user_data() instead. */ +#define linphone_call_log_get_user_pointer(cl) linphone_call_log_get_user_data(cl) +LINPHONE_PUBLIC void *linphone_call_log_get_user_data(const LinphoneCallLog *cl); void linphone_call_log_set_ref_key(LinphoneCallLog *cl, const char *refkey); const char *linphone_call_log_get_ref_key(const LinphoneCallLog *cl); LINPHONE_PUBLIC const rtp_stats_t *linphone_call_log_get_local_stats(const LinphoneCallLog *cl); @@ -717,8 +721,12 @@ LINPHONE_PUBLIC const char* linphone_call_get_authentication_token(LinphoneCall LINPHONE_PUBLIC bool_t linphone_call_get_authentication_token_verified(LinphoneCall *call); LINPHONE_PUBLIC void linphone_call_set_authentication_token_verified(LinphoneCall *call, bool_t verified); LINPHONE_PUBLIC void linphone_call_send_vfu_request(LinphoneCall *call); -LINPHONE_PUBLIC void *linphone_call_get_user_pointer(LinphoneCall *call); -LINPHONE_PUBLIC void linphone_call_set_user_pointer(LinphoneCall *call, void *user_pointer); +/** @deprecated Use linphone_call_get_user_data() instead. */ +#define linphone_call_get_user_pointer(call) linphone_call_get_user_data(call) +LINPHONE_PUBLIC void *linphone_call_get_user_data(LinphoneCall *call); +/** @deprecated Use linphone_call_set_user_data() instead. */ +#define linphone_call_set_user_pointer(call, ud) linphone_call_set_user_data(call, ud) +LINPHONE_PUBLIC void linphone_call_set_user_data(LinphoneCall *call, void *user_data); LINPHONE_PUBLIC void linphone_call_set_next_video_frame_decoded_callback(LinphoneCall *call, LinphoneCallCbFunc cb, void* user_data); LINPHONE_PUBLIC LinphoneCallState linphone_call_get_transfer_state(LinphoneCall *call); LINPHONE_PUBLIC void linphone_call_zoom_video(LinphoneCall* call, float zoom_factor, float* cx, float* cy); diff --git a/tools/python/apixml2python.py b/tools/python/apixml2python.py index f71cbb7eb..34770b328 100755 --- a/tools/python/apixml2python.py +++ b/tools/python/apixml2python.py @@ -38,13 +38,9 @@ blacklisted_events = [ 'LinphoneCoreFileTransferSendCb' # missing LinphoneContent ] blacklisted_functions = [ - 'linphone_call_get_user_pointer', # rename to linphone_call_get_user_data - 'linphone_call_set_user_pointer', # rename to linphone_call_set_user_data 'linphone_call_log_get_local_stats', # missing rtp_stats_t 'linphone_call_log_get_remote_stats', # missing rtp_stats_t 'linphone_call_log_get_start_date', # missing time_t - 'linphone_call_log_get_user_pointer', # rename to linphone_call_log_get_user_data - 'linphone_call_log_set_user_pointer', # rename to linphone_call_log_set_user_data 'linphone_call_params_get_privacy', # missing LinphonePrivacyMask 'linphone_call_params_get_used_audio_codec', # missing PayloadType 'linphone_call_params_get_used_video_codec', # missing PayloadType From 0cc60a9d312ab603561cd6b42a7594175af3e0a6 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Wed, 13 Aug 2014 15:07:53 +0200 Subject: [PATCH 06/43] Remove useless variable definitions in the Python wrapper. --- tools/python/apixml2python/linphone.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/tools/python/apixml2python/linphone.py b/tools/python/apixml2python/linphone.py index 4a6fc98fd..884576a93 100644 --- a/tools/python/apixml2python/linphone.py +++ b/tools/python/apixml2python/linphone.py @@ -749,8 +749,6 @@ class LinphoneModule(object): ev['event_name'] = compute_event_name(ev['event_cname']) ev['event_doc'] = self.__format_doc(xml_event.find('briefdescription'), xml_event.find('detaileddescription')) self.events.append(ev) - elif c['class_name'] == 'ChatRoom': - c['class_object_members'] = "\tPyObject *send_message_cb;\n\tPyObject *send_message_ud;" xml_type_methods = xml_class.findall("./classmethods/classmethod") for xml_type_method in xml_type_methods: if xml_type_method.get('deprecated') == 'true': From 31ab25d815e2fa4237d9be074c388bc292cdcbcc Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Wed, 13 Aug 2014 16:10:48 +0200 Subject: [PATCH 07/43] Handle PayloadType objects in the Python wrapper. --- coreapi/linphonecall.c | 8 ++--- coreapi/linphonecore.c | 21 +++++++++-- coreapi/linphonecore.h | 68 ++++++++++++++++++++++++++++------- coreapi/misc.c | 10 +++--- tools/genapixml.py | 5 +++ tools/python/apixml2python.py | 8 ----- 6 files changed, 88 insertions(+), 32 deletions(-) diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 459c8c92f..9d8b6060c 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -1342,17 +1342,17 @@ void linphone_call_params_enable_video(LinphoneCallParams *cp, bool_t enabled){ } /** - * Returns the audio codec used in the call, described as a PayloadType structure. + * Returns the audio codec used in the call, described as a LinphonePayloadType structure. **/ -const PayloadType* linphone_call_params_get_used_audio_codec(const LinphoneCallParams *cp) { +const LinphonePayloadType* linphone_call_params_get_used_audio_codec(const LinphoneCallParams *cp) { return cp->audio_codec; } /** - * Returns the video codec used in the call, described as a PayloadType structure. + * Returns the video codec used in the call, described as a LinphonePayloadType structure. **/ -const PayloadType* linphone_call_params_get_used_video_codec(const LinphoneCallParams *cp) { +const LinphonePayloadType* linphone_call_params_get_used_video_codec(const LinphoneCallParams *cp) { return cp->video_codec; } diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 93f30606e..dbed18003 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -6260,8 +6260,8 @@ static PayloadType* find_payload_type_from_list(const char* type, int rate, int } -PayloadType* linphone_core_find_payload_type(LinphoneCore* lc, const char* type, int rate, int channels) { - PayloadType* result = find_payload_type_from_list(type, rate, channels, linphone_core_get_audio_codecs(lc)); +LinphonePayloadType* linphone_core_find_payload_type(LinphoneCore* lc, const char* type, int rate, int channels) { + LinphonePayloadType* result = find_payload_type_from_list(type, rate, channels, linphone_core_get_audio_codecs(lc)); if (result) { return result; } else { @@ -6714,3 +6714,20 @@ bool_t linphone_core_sdp_200_ack_enabled(const LinphoneCore *lc) { void linphone_core_set_file_transfer_server(LinphoneCore *core, const char * server_url) { core->file_transfer_server=ms_strdup(server_url); } + + +int linphone_payload_type_get_type(const LinphonePayloadType *pt) { + return pt->type; +} + +int linphone_payload_type_get_normal_bitrate(const LinphonePayloadType *pt) { + return pt->normal_bitrate; +} + +char * linphone_payload_type_get_mime_type(const LinphonePayloadType *pt) { + return pt->mime_type; +} + +int linphone_payload_type_get_channels(const LinphonePayloadType *pt) { + return pt->channels; +} diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index b08c75395..7147f30e7 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -247,6 +247,48 @@ LinphoneDictionary* lp_config_section_to_dict( const LpConfig* lpconfig, const c void lp_config_load_dict_to_section( LpConfig* lpconfig, const char* section, const LinphoneDictionary* dict); +/** + * @addtogroup media_parameters + * @{ +**/ + +/** + * Object representing an RTP payload type. + */ +typedef PayloadType LinphonePayloadType; + +/** + * Get the type of payload. + * @param[in] pt LinphonePayloadType object + * @return The type of payload. + */ +LINPHONE_PUBLIC int linphone_payload_type_get_type(const LinphonePayloadType *pt); + +/** + * Get the normal bitrate in bits/s. + * @param[in] pt LinphonePayloadType object + * @return The normal bitrate in bits/s. + */ +LINPHONE_PUBLIC int linphone_payload_type_get_normal_bitrate(const LinphonePayloadType *pt); + +/** + * Get the mime type. + * @param[in] pt LinphonePayloadType object + * @return The mime type. + */ +LINPHONE_PUBLIC char * linphone_payload_type_get_mime_type(const LinphonePayloadType *pt); + +/** + * Get the number of channels. + * @param[in] pt LinphonePayloadType object + * @return The number of channels. + */ +LINPHONE_PUBLIC int linphone_payload_type_get_channels(const LinphonePayloadType *pt); + +/** + * @} +**/ + #ifdef IN_LINPHONE #include "linphonefriend.h" #include "event.h" @@ -383,8 +425,8 @@ struct _LinphoneCallParams; **/ typedef struct _LinphoneCallParams LinphoneCallParams; -LINPHONE_PUBLIC const PayloadType* linphone_call_params_get_used_audio_codec(const LinphoneCallParams *cp); -LINPHONE_PUBLIC const PayloadType* linphone_call_params_get_used_video_codec(const LinphoneCallParams *cp); +LINPHONE_PUBLIC const LinphonePayloadType* linphone_call_params_get_used_audio_codec(const LinphoneCallParams *cp); +LINPHONE_PUBLIC const LinphonePayloadType* linphone_call_params_get_used_video_codec(const LinphoneCallParams *cp); LINPHONE_PUBLIC LinphoneCallParams * linphone_call_params_copy(const LinphoneCallParams *cp); LINPHONE_PUBLIC void linphone_call_params_enable_video(LinphoneCallParams *cp, bool_t enabled); LINPHONE_PUBLIC bool_t linphone_call_params_video_enabled(const LinphoneCallParams *cp); @@ -1887,48 +1929,48 @@ LINPHONE_PUBLIC int linphone_core_set_video_codecs(LinphoneCore *lc, MSList *cod /** * Tells whether the specified payload type is enabled. * @param[in] lc #LinphoneCore object. - * @param[in] pt The #PayloadType we want to know is enabled or not. + * @param[in] pt The #LinphonePayloadType we want to know is enabled or not. * @returns TRUE if the payload type is enabled, FALSE if disabled. * @ingroup media_parameters */ -LINPHONE_PUBLIC bool_t linphone_core_payload_type_enabled(LinphoneCore *lc, const PayloadType *pt); +LINPHONE_PUBLIC bool_t linphone_core_payload_type_enabled(LinphoneCore *lc, const LinphonePayloadType *pt); /** * Tells whether the specified payload type represents a variable bitrate codec. * @param[in] lc #LinphoneCore object. - * @param[in] pt The #PayloadType we want to know + * @param[in] pt The #LinphonePayloadType we want to know * @returns TRUE if the payload type represents a VBR codec, FALSE if disabled. * @ingroup media_parameters */ -LINPHONE_PUBLIC bool_t linphone_core_payload_type_is_vbr(LinphoneCore *lc, const PayloadType *pt); +LINPHONE_PUBLIC bool_t linphone_core_payload_type_is_vbr(LinphoneCore *lc, const LinphonePayloadType *pt); /** * Set an explicit bitrate (IP bitrate, not codec bitrate) for a given codec, in kbit/s. * @param[in] lc the #LinphoneCore object - * @param[in] pt the #PayloadType to modify. + * @param[in] pt the #LinphonePayloadType to modify. * @param[in] bitrate the IP bitrate in kbit/s. * @ingroup media_parameters **/ -LINPHONE_PUBLIC void linphone_core_set_payload_type_bitrate(LinphoneCore *lc, PayloadType *pt, int bitrate); +LINPHONE_PUBLIC void linphone_core_set_payload_type_bitrate(LinphoneCore *lc, LinphonePayloadType *pt, int bitrate); /** * Get the bitrate explicitely set with linphone_core_set_payload_type_bitrate(). * @param[in] lc the #LinphoneCore object - * @param[in] pt the #PayloadType to modify. + * @param[in] pt the #LinphonePayloadType to modify. * @return bitrate the IP bitrate in kbit/s, or -1 if an error occured. * @ingroup media_parameters **/ -LINPHONE_PUBLIC int linphone_core_get_payload_type_bitrate(LinphoneCore *lc, const PayloadType *pt); +LINPHONE_PUBLIC int linphone_core_get_payload_type_bitrate(LinphoneCore *lc, const LinphonePayloadType *pt); /** * Enable or disable the use of the specified payload type. * @param[in] lc #LinphoneCore object. - * @param[in] pt The #PayloadType to enable or disable. It can be retrieved using #linphone_core_find_payload_type + * @param[in] pt The #LinphonePayloadType to enable or disable. It can be retrieved using #linphone_core_find_payload_type * @param[in] enable TRUE to enable the payload type, FALSE to disable it. * @return 0 if successful, any other value otherwise. * @ingroup media_parameters */ -LINPHONE_PUBLIC int linphone_core_enable_payload_type(LinphoneCore *lc, PayloadType *pt, bool_t enable); +LINPHONE_PUBLIC int linphone_core_enable_payload_type(LinphoneCore *lc, LinphonePayloadType *pt, bool_t enable); /** * Wildcard value used by #linphone_core_find_payload_type to ignore rate in search algorithm @@ -1950,7 +1992,7 @@ LINPHONE_PUBLIC int linphone_core_enable_payload_type(LinphoneCore *lc, PayloadT * @param channels number of channels, can be #LINPHONE_FIND_PAYLOAD_IGNORE_CHANNELS * @return Returns NULL if not found. */ -LINPHONE_PUBLIC PayloadType* linphone_core_find_payload_type(LinphoneCore* lc, const char* type, int rate, int channels) ; +LINPHONE_PUBLIC LinphonePayloadType* linphone_core_find_payload_type(LinphoneCore* lc, const char* type, int rate, int channels) ; LINPHONE_PUBLIC int linphone_core_get_payload_type_number(LinphoneCore *lc, const PayloadType *pt); diff --git a/coreapi/misc.c b/coreapi/misc.c index 38b0efa5d..d4bf48cd5 100644 --- a/coreapi/misc.c +++ b/coreapi/misc.c @@ -69,7 +69,7 @@ static bool_t payload_type_enabled(const PayloadType *pt) { return (((pt)->flags & PAYLOAD_TYPE_ENABLED)!=0); } -bool_t linphone_core_payload_type_enabled(LinphoneCore *lc, const PayloadType *pt){ +bool_t linphone_core_payload_type_enabled(LinphoneCore *lc, const LinphonePayloadType *pt){ if (ms_list_find(lc->codecs_conf.audio_codecs, (PayloadType*) pt) || ms_list_find(lc->codecs_conf.video_codecs, (PayloadType*)pt)){ return payload_type_enabled(pt); } @@ -77,12 +77,12 @@ bool_t linphone_core_payload_type_enabled(LinphoneCore *lc, const PayloadType *p return FALSE; } -bool_t linphone_core_payload_type_is_vbr(LinphoneCore *lc, const PayloadType *pt){ +bool_t linphone_core_payload_type_is_vbr(LinphoneCore *lc, const LinphonePayloadType *pt){ if (pt->type==PAYLOAD_VIDEO) return TRUE; return !!(pt->flags & PAYLOAD_TYPE_IS_VBR); } -int linphone_core_enable_payload_type(LinphoneCore *lc, PayloadType *pt, bool_t enabled){ +int linphone_core_enable_payload_type(LinphoneCore *lc, LinphonePayloadType *pt, bool_t enabled){ if (ms_list_find(lc->codecs_conf.audio_codecs,pt) || ms_list_find(lc->codecs_conf.video_codecs,pt)){ payload_type_set_enable(pt,enabled); _linphone_core_codec_config_write(lc); @@ -108,7 +108,7 @@ const char *linphone_core_get_payload_type_description(LinphoneCore *lc, Payload return NULL; } -void linphone_core_set_payload_type_bitrate(LinphoneCore *lc, PayloadType *pt, int bitrate){ +void linphone_core_set_payload_type_bitrate(LinphoneCore *lc, LinphonePayloadType *pt, int bitrate){ if (ms_list_find(lc->codecs_conf.audio_codecs, (PayloadType*) pt) || ms_list_find(lc->codecs_conf.video_codecs, (PayloadType*)pt)){ if (pt->type==PAYLOAD_VIDEO || pt->flags & PAYLOAD_TYPE_IS_VBR){ pt->normal_bitrate=bitrate*1000; @@ -181,7 +181,7 @@ static int get_audio_payload_bandwidth(LinphoneCore *lc, const PayloadType *pt, }else return (int)ceil(get_audio_payload_bandwidth_from_codec_bitrate(pt)/1000.0);/*rounding codec bandwidth should be avoid, specially for AMR*/ } -int linphone_core_get_payload_type_bitrate(LinphoneCore *lc, const PayloadType *pt){ +int linphone_core_get_payload_type_bitrate(LinphoneCore *lc, const LinphonePayloadType *pt){ int maxbw=get_min_bandwidth(linphone_core_get_download_bandwidth(lc), linphone_core_get_upload_bandwidth(lc)); if (pt->type==PAYLOAD_AUDIO_CONTINUOUS || pt->type==PAYLOAD_AUDIO_PACKETIZED){ diff --git a/tools/genapixml.py b/tools/genapixml.py index 388870e2c..2c9286792 100755 --- a/tools/genapixml.py +++ b/tools/genapixml.py @@ -335,6 +335,11 @@ class Project: if st.associatedTypedef == td: self.add(CClass(st)) break + elif ('Linphone' + td.definition) == td.name: + st = CStruct(td.name) + st.associatedTypedef = td + self.add(st) + self.add(CClass(st)) # Sort classes by length of name (longest first), so that methods are put in the right class self.classes.sort(key = lambda c: len(c.name), reverse = True) for e in self.__events: diff --git a/tools/python/apixml2python.py b/tools/python/apixml2python.py index 34770b328..5b6876a34 100755 --- a/tools/python/apixml2python.py +++ b/tools/python/apixml2python.py @@ -42,8 +42,6 @@ blacklisted_functions = [ 'linphone_call_log_get_remote_stats', # missing rtp_stats_t 'linphone_call_log_get_start_date', # missing time_t 'linphone_call_params_get_privacy', # missing LinphonePrivacyMask - 'linphone_call_params_get_used_audio_codec', # missing PayloadType - 'linphone_call_params_get_used_video_codec', # missing PayloadType 'linphone_call_params_set_privacy', # missing LinphonePrivacyMask 'linphone_chat_message_get_file_transfer_information', # missing LinphoneContent 'linphone_chat_message_get_time', # missing time_t @@ -52,8 +50,6 @@ blacklisted_functions = [ 'linphone_chat_room_create_file_transfer_message', # missing LinphoneContent 'linphone_chat_room_create_message_2', # missing time_t 'linphone_core_can_we_add_call', # private function - 'linphone_core_enable_payload_type', # missing PayloadType - 'linphone_core_find_payload_type', # missing PayloadType 'linphone_core_get_audio_codecs', # missing PayloadType and MSList 'linphone_core_get_audio_port_range', # to be handwritten because of result via arguments 'linphone_core_get_auth_info_list', # missing MSList @@ -61,7 +57,6 @@ blacklisted_functions = [ 'linphone_core_get_calls', # missing MSList 'linphone_core_get_chat_rooms', # missing MSList 'linphone_core_get_default_proxy', # to be handwritten because of double pointer indirection - 'linphone_core_get_payload_type_bitrate', # missing PayloadType 'linphone_core_get_friend_list', # missing MSList 'linphone_core_get_proxy_config_list', # missing MSList 'linphone_core_get_sip_transports', # missing LCSipTransports @@ -71,14 +66,11 @@ blacklisted_functions = [ 'linphone_core_get_video_devices', # returns a list of strings 'linphone_core_get_video_policy', # missing LinphoneVideoPolicy 'linphone_core_get_video_port_range', # to be handwritten because of result via arguments - 'linphone_core_payload_type_enabled', # missing PayloadType - 'linphone_core_payload_type_is_vbr', # missing PayloadType 'linphone_core_publish', # missing LinphoneContent 'linphone_core_serialize_logs', # There is no use to wrap this function 'linphone_core_set_log_file', # There is no use to wrap this function 'linphone_core_set_log_handler', # Hand-written but put directly in the linphone module 'linphone_core_set_log_level', # There is no use to wrap this function - 'linphone_core_set_payload_type_bitrate', # missing PayloadType 'linphone_core_set_video_policy', # missing LinphoneVideoPolicy 'linphone_core_set_audio_codecs', # missing PayloadType and MSList 'linphone_core_set_sip_transports', # missing LCSipTransports From 8e7a9cbd744e753ce5e0ff0b9f82ab73a2636c6f Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Wed, 13 Aug 2014 16:32:22 +0200 Subject: [PATCH 08/43] Add definitions of the types of PayloadType in the Python wrapper. --- .../handwritten_definitions.mustache | 39 +++++++++++++++++++ .../apixml2python/linphone_module.mustache | 9 +++++ 2 files changed, 48 insertions(+) diff --git a/tools/python/apixml2python/handwritten_definitions.mustache b/tools/python/apixml2python/handwritten_definitions.mustache index 6b6a4eecf..30ceb33c7 100644 --- a/tools/python/apixml2python/handwritten_definitions.mustache +++ b/tools/python/apixml2python/handwritten_definitions.mustache @@ -365,3 +365,42 @@ PyObject * PyLinphoneVideoSize_FromMSVideoSize(MSVideoSize vs) { } return pyret; } + + +static PyObject * pylinphone_PayloadTypeType_module_method_string(PyObject *self, PyObject *args) { + const char *value_str = "[invalid]"; + int value; + PyObject *pyret; + if (!PyArg_ParseTuple(args, "i", &value)) { + return NULL; + } + pylinphone_trace(1, "[PYLINPHONE] >>> %s(%d)", __FUNCTION__, value); + switch (value) { + case PAYLOAD_AUDIO_CONTINUOUS: + value_str = "PAYLOAD_AUDIO_CONTINUOUS"; + break; + case PAYLOAD_AUDIO_PACKETIZED: + value_str = "PAYLOAD_AUDIO_PACKETIZED"; + break; + case PAYLOAD_VIDEO: + value_str = "PAYLOAD_VIDEO"; + break; + case PAYLOAD_TEXT: + value_str = "PAYLOAD_TEXT"; + break; + case PAYLOAD_OTHER: + value_str = "PAYLOAD_OTHER"; + break; + default: + break; + } + pyret = Py_BuildValue("z", value_str); + pylinphone_trace(-1, "[PYLINPHONE] <<< %s -> %p", __FUNCTION__, pyret); + return pyret; +} + +static PyMethodDef pylinphone_PayloadTypeType_ModuleMethods[] = { + { "string", pylinphone_PayloadTypeType_module_method_string, METH_VARARGS, "Get a string representation of a linphone.PayloadTypeType value." }, + /* Sentinel */ + { NULL, NULL, 0, NULL } +}; diff --git a/tools/python/apixml2python/linphone_module.mustache b/tools/python/apixml2python/linphone_module.mustache index ee072aeae..02f1920ac 100644 --- a/tools/python/apixml2python/linphone_module.mustache +++ b/tools/python/apixml2python/linphone_module.mustache @@ -258,6 +258,15 @@ PyMODINIT_FUNC initlinphone(void) { {{/enum_values}} {{/enums}} + menum = Py_InitModule3("PayloadTypeType", pylinphone_PayloadTypeType_ModuleMethods, "Type of linphone.PayloadType."); + if (menum == NULL) return; + if (PyModule_AddObject(m, "PayloadTypeType", menum) < 0) return; + if (PyModule_AddIntConstant(menum, "PAYLOAD_AUDIO_CONTINUOUS", PAYLOAD_AUDIO_CONTINUOUS) < 0) return; + if (PyModule_AddIntConstant(menum, "PAYLOAD_AUDIO_PACKETIZED", PAYLOAD_AUDIO_PACKETIZED) < 0) return; + if (PyModule_AddIntConstant(menum, "PAYLOAD_VIDEO", PAYLOAD_VIDEO) < 0) return; + if (PyModule_AddIntConstant(menum, "PAYLOAD_TEXT", PAYLOAD_TEXT) < 0) return; + if (PyModule_AddIntConstant(menum, "PAYLOAD_OTHER", PAYLOAD_OTHER) < 0) return; + {{#classes}} Py_INCREF(&pylinphone_{{class_name}}Type); PyModule_AddObject(m, "{{class_name}}", (PyObject *)&pylinphone_{{class_name}}Type); From ebad6bca11dc9449163794bdfc954bb21c3eac10 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Wed, 13 Aug 2014 18:11:08 +0200 Subject: [PATCH 09/43] Handwritten implementation of linphone_core_get_video_devices() in the Python wrapper. --- tools/python/apixml2python.py | 2 +- .../handwritten_declarations.mustache | 2 + .../handwritten_definitions.mustache | 27 +++++++++ tools/python/apixml2python/linphone.py | 59 ++++++++++++------- .../apixml2python/linphone_module.mustache | 3 + 5 files changed, 70 insertions(+), 23 deletions(-) diff --git a/tools/python/apixml2python.py b/tools/python/apixml2python.py index 5b6876a34..dd37e2027 100755 --- a/tools/python/apixml2python.py +++ b/tools/python/apixml2python.py @@ -63,7 +63,6 @@ blacklisted_functions = [ 'linphone_core_get_sip_transports_used', # missing LCSipTransports 'linphone_core_get_supported_video_sizes', # missing MSVideoSizeDef 'linphone_core_get_video_codecs', # missing PayloadType and MSList - 'linphone_core_get_video_devices', # returns a list of strings 'linphone_core_get_video_policy', # missing LinphoneVideoPolicy 'linphone_core_get_video_port_range', # to be handwritten because of result via arguments 'linphone_core_publish', # missing LinphoneContent @@ -94,6 +93,7 @@ blacklisted_functions = [ ] hand_written_functions = [ 'linphone_chat_room_send_message2', + 'linphone_core_get_video_devices', 'linphone_core_new', 'linphone_core_new_with_config' ] diff --git a/tools/python/apixml2python/handwritten_declarations.mustache b/tools/python/apixml2python/handwritten_declarations.mustache index 1d27b9963..4a50a848b 100644 --- a/tools/python/apixml2python/handwritten_declarations.mustache +++ b/tools/python/apixml2python/handwritten_declarations.mustache @@ -1,3 +1,5 @@ +static PyObject * pylinphone_Core_get_video_devices(PyObject *self, void *closure); + static PyTypeObject pylinphone_VideoSizeType; typedef struct { diff --git a/tools/python/apixml2python/handwritten_definitions.mustache b/tools/python/apixml2python/handwritten_definitions.mustache index 30ceb33c7..b3d043c32 100644 --- a/tools/python/apixml2python/handwritten_definitions.mustache +++ b/tools/python/apixml2python/handwritten_definitions.mustache @@ -114,6 +114,33 @@ static PyObject * pylinphone_module_method_set_log_handler(PyObject *self, PyObj Py_RETURN_NONE; } + +static PyObject * pylinphone_Core_get_video_devices(PyObject *self, void *closure) { + PyObject *_list; + char **_devices; + char *_device; + LinphoneCore *native_ptr = pylinphone_Core_get_native_ptr(self); + + if (native_ptr == NULL) { + PyErr_SetString(PyExc_TypeError, "Invalid linphone.Core instance"); + return NULL; + } + + pylinphone_trace(1, "[PYLINPHONE] >>> %s(%p [%p])", __FUNCTION__, self, native_ptr); + _devices = linphone_core_get_video_devices(native_ptr); + pylinphone_dispatch_messages(); + + _list = PyList_New(0); + while (*_devices != NULL) { + PyObject *_item = PyString_FromString(*_devices); + PyList_Append(_list, _item); + _devices++; + } + + pylinphone_trace(-1, "[PYLINPHONE] <<< %s -> %p", __FUNCTION__, _list); + return _list; +} + static PyObject * pylinphone_Core_class_method_new(PyObject *cls, PyObject *args) { LinphoneCore * cresult; pylinphone_CoreObject *self; diff --git a/tools/python/apixml2python/linphone.py b/tools/python/apixml2python/linphone.py index 884576a93..38253fd94 100644 --- a/tools/python/apixml2python/linphone.py +++ b/tools/python/apixml2python/linphone.py @@ -734,6 +734,7 @@ class LinphoneModule(object): c['class_type_methods'] = [] c['class_type_hand_written_methods'] = [] c['class_instance_hand_written_methods'] = [] + c['class_hand_written_properties'] = [] c['class_object_members'] = '' if c['class_name'] == 'Core': c['class_object_members'] = "\tPyObject *vtable_dict;" @@ -792,31 +793,45 @@ class LinphoneModule(object): p['property_name'] = property_name xml_property_getter = xml_property.find("./getter") xml_property_setter = xml_property.find("./setter") - if xml_property_getter is not None and ( - xml_property_getter.get('name') in blacklisted_functions or xml_property_getter.get('deprecated') == 'true'): - continue - if xml_property_setter is not None and ( - xml_property_setter.get('name') in blacklisted_functions or xml_property_setter.get('deprecated') == 'true'): - continue + handwritten_property = False if xml_property_getter is not None: - xml_property_getter.set('property_name', property_name) - p['getter_name'] = xml_property_getter.get('name').replace(c['class_c_function_prefix'], '') - p['getter_xml_node'] = xml_property_getter - p['getter_reference'] = "(getter)pylinphone_" + c['class_name'] + "_" + p['getter_name'] - p['getter_definition_begin'] = "static PyObject * pylinphone_" + c['class_name'] + "_" + p['getter_name'] + "(PyObject *self, void *closure) {" - p['getter_definition_end'] = "}" - else: - p['getter_reference'] = "NULL" + if xml_property_getter.get('name') in blacklisted_functions or xml_property_getter.get('deprecated') == 'true': + continue + elif xml_property_getter.get('name') in hand_written_functions: + handwritten_property = True if xml_property_setter is not None: - xml_property_setter.set('property_name', property_name) - p['setter_name'] = xml_property_setter.get('name').replace(c['class_c_function_prefix'], '') - p['setter_xml_node'] = xml_property_setter - p['setter_reference'] = "(setter)pylinphone_" + c['class_name'] + "_" + p['setter_name'] - p['setter_definition_begin'] = "static int pylinphone_" + c['class_name'] + "_" + p['setter_name'] + "(PyObject *self, PyObject *value, void *closure) {" - p['setter_definition_end'] = "}" + if xml_property_setter.get('name') in blacklisted_functions or xml_property_setter.get('deprecated') == 'true': + continue + elif xml_property_setter.get('name') in hand_written_functions: + handwritten_property = True + if handwritten_property: + p['getter_reference'] = 'NULL' + p['setter_reference'] = 'NULL' + if xml_property_getter is not None: + p['getter_reference'] = '(getter)pylinphone_' + c['class_name'] + '_get_' + p['property_name'] + if xml_property_setter is not None: + p['setter_reference'] = '(setter)pylinphone_' + c['class_name'] + '_set_' + p['property_name'] + c['class_hand_written_properties'].append(p) else: - p['setter_reference'] = "NULL" - c['class_properties'].append(p) + if xml_property_getter is not None: + xml_property_getter.set('property_name', property_name) + p['getter_name'] = xml_property_getter.get('name').replace(c['class_c_function_prefix'], '') + p['getter_xml_node'] = xml_property_getter + p['getter_reference'] = "(getter)pylinphone_" + c['class_name'] + "_" + p['getter_name'] + p['getter_definition_begin'] = "static PyObject * pylinphone_" + c['class_name'] + "_" + p['getter_name'] + "(PyObject *self, void *closure) {" + p['getter_definition_end'] = "}" + else: + p['getter_reference'] = "NULL" + if xml_property_setter is not None: + xml_property_setter.set('property_name', property_name) + p['setter_name'] = xml_property_setter.get('name').replace(c['class_c_function_prefix'], '') + p['setter_xml_node'] = xml_property_setter + p['setter_reference'] = "(setter)pylinphone_" + c['class_name'] + "_" + p['setter_name'] + p['setter_definition_begin'] = "static int pylinphone_" + c['class_name'] + "_" + p['setter_name'] + "(PyObject *self, PyObject *value, void *closure) {" + p['setter_definition_end'] = "}" + else: + p['setter_reference'] = "NULL" + c['class_properties'].append(p) self.classes.append(c) # Format events definitions for ev in self.events: diff --git a/tools/python/apixml2python/linphone_module.mustache b/tools/python/apixml2python/linphone_module.mustache index 02f1920ac..005f05edb 100644 --- a/tools/python/apixml2python/linphone_module.mustache +++ b/tools/python/apixml2python/linphone_module.mustache @@ -139,6 +139,9 @@ static PyMethodDef pylinphone_{{class_name}}_methods[] = { {{/class_properties}} static PyGetSetDef pylinphone_{{class_name}}_getseters[] = { +{{#class_hand_written_properties}} + { "{{property_name}}", {{getter_reference}}, {{setter_reference}}, "" }, +{{/class_hand_written_properties}} {{#class_properties}} { "{{property_name}}", {{getter_reference}}, {{setter_reference}}, "{{{property_doc}}}" }, {{/class_properties}} From 61d1f7b5de76f2208943bcbd877a3ceb830bbcc5 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Wed, 13 Aug 2014 19:24:01 +0200 Subject: [PATCH 10/43] allow fps change in linphone_core_update_call() --- coreapi/linphonecore.c | 1 + coreapi/message_storage.c | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index dbed18003..59c46fee2 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -3279,6 +3279,7 @@ int linphone_core_update_call(LinphoneCore *lc, LinphoneCall *call, const Linpho #ifdef VIDEO_ENABLED if ((call->videostream != NULL) && (call->state == LinphoneCallStreamsRunning)) { video_stream_set_sent_video_size(call->videostream,linphone_core_get_preferred_video_size(lc)); + video_stream_set_fps(call->videostream, linphone_core_get_preferred_framerate(lc)); if (call->camera_enabled && call->videostream->cam!=lc->video_conf.device){ video_stream_change_camera(call->videostream,lc->video_conf.device); }else video_stream_update_video_params(call->videostream); diff --git a/coreapi/message_storage.c b/coreapi/message_storage.c index 7caf4536b..d2f83b12a 100644 --- a/coreapi/message_storage.c +++ b/coreapi/message_storage.c @@ -54,6 +54,7 @@ static inline LinphoneChatMessage* get_transient_message(LinphoneChatRoom* cr, u static void create_chat_message(char **argv, void *data){ LinphoneChatRoom *cr = (LinphoneChatRoom *)data; LinphoneAddress *from; + LinphoneAddress *to; unsigned int storage_id = atoi(argv[0]); @@ -65,12 +66,18 @@ static void create_chat_message(char **argv, void *data){ if(atoi(argv[3])==LinphoneChatMessageIncoming){ new_message->dir=LinphoneChatMessageIncoming; from=linphone_address_new(argv[2]); + to=linphone_address_new(argv[1]); } else { new_message->dir=LinphoneChatMessageOutgoing; from=linphone_address_new(argv[1]); + to=linphone_address_new(argv[2]); } linphone_chat_message_set_from(new_message,from); linphone_address_destroy(from); + if (to){ + linphone_chat_message_set_to(new_message,to); + linphone_address_destroy(to); + } if( argv[9] != NULL ){ new_message->time = (time_t)atol(argv[9]); From 82e1a90ba69ecfc99a47bf83b62edd66ceba46d6 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Thu, 14 Aug 2014 11:21:33 +0200 Subject: [PATCH 11/43] Improve int types checking in the Python wrapper. --- tools/python/apixml2python/linphone.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tools/python/apixml2python/linphone.py b/tools/python/apixml2python/linphone.py index 38253fd94..2b57bf35f 100644 --- a/tools/python/apixml2python/linphone.py +++ b/tools/python/apixml2python/linphone.py @@ -70,20 +70,20 @@ class ArgumentType: elif self.basic_type == 'int': if 'unsigned' in splitted_type: self.type_str = 'unsigned int' - self.check_func = 'PyLong_Check' - self.convert_func = 'PyLong_AsUnsignedLong' + self.check_func = 'PyInt_Check' + self.convert_func = 'PyInt_AsUnsignedLongMask' self.fmt_str = 'I' self.cfmt_str = '%u' else: self.type_str = 'int' - self.check_func = 'PyLong_Check' - self.convert_func = 'PyLong_AsLong' + self.check_func = 'PyInt_Check' + self.convert_func = 'PyInt_AS_LONG' self.fmt_str = 'i' self.cfmt_str = '%d' elif self.basic_type in ['int8_t', 'int16_t' 'int32_t']: self.type_str = 'int' - self.check_func = 'PyLong_Check' - self.convert_func = 'PyLong_AsLong' + self.check_func = 'PyInt_Check' + self.convert_func = 'PyInt_AS_LONG' if self.basic_type == 'int8_t': self.fmt_str = 'c' elif self.basic_type == 'int16_t': @@ -93,8 +93,8 @@ class ArgumentType: self.cfmt_str = '%d' elif self.basic_type in ['uint8_t', 'uint16_t', 'uint32_t']: self.type_str = 'unsigned int' - self.check_func = 'PyLong_Check' - self.convert_func = 'PyLong_AsUnsignedLong' + self.check_func = 'PyInt_Check' + self.convert_func = 'PyInt_AsUnsignedLongMask' if self.basic_type == 'uint8_t': self.fmt_str = 'b' elif self.basic_type == 'uint16_t': @@ -116,8 +116,8 @@ class ArgumentType: self.cfmt_str = '%lu' elif self.basic_type == 'size_t': self.type_str = 'size_t' - self.check_func = 'PyLong_Check' - self.convert_func = 'PyLong_AsSsize_t' + self.check_func = 'PyInt_Check' + self.convert_func = 'PyInt_AsSsize_t' self.fmt_str = 'n' self.cfmt_str = '%lu' elif self.basic_type in ['float', 'double']: From e5d15ca06a73f8d80345accf6dd752dd963aab6f Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Thu, 14 Aug 2014 12:51:11 +0200 Subject: [PATCH 12/43] Improve argument checking in the Python wrapper. --- tools/python/apixml2python/linphone.py | 45 +++++++++++++++++++------- 1 file changed, 34 insertions(+), 11 deletions(-) diff --git a/tools/python/apixml2python/linphone.py b/tools/python/apixml2python/linphone.py index 2b57bf35f..e2e13b94b 100644 --- a/tools/python/apixml2python/linphone.py +++ b/tools/python/apixml2python/linphone.py @@ -195,7 +195,7 @@ class MethodDefinition: self.parse_tuple_format += argument_type.fmt_str if argument_type.use_native_pointer: body += "\tPyObject * " + arg_name + ";\n" - body += "\t" + arg_complete_type + " " + arg_name + "_native_ptr;\n" + body += "\t" + arg_complete_type + " " + arg_name + "_native_ptr = NULL;\n" elif strip_leading_linphone(arg_complete_type) in self.linphone_module.enum_names: body += "\tint " + arg_name + ";\n" else: @@ -217,9 +217,11 @@ class MethodDefinition: return \ """ {class_native_ptr_check_code} {parse_tuple_code} + {args_type_check_code} {args_native_ptr_check_code} """.format(class_native_ptr_check_code=class_native_ptr_check_code, parse_tuple_code=parse_tuple_code, + args_type_check_code=self.format_args_type_check(), args_native_ptr_check_code=self.format_args_native_pointer_check()) def format_enter_trace(self): @@ -349,6 +351,23 @@ class MethodDefinition: }} """.format(class_name=self.class_['class_name'], return_value=return_value) + def format_args_type_check(self): + body = '' + for xml_method_arg in self.xml_method_args: + arg_name = "_" + xml_method_arg.get('name') + arg_type = xml_method_arg.get('type') + arg_complete_type = xml_method_arg.get('completetype') + argument_type = ArgumentType(arg_type, arg_complete_type, self.linphone_module) + if argument_type.fmt_str == 'O': + body += \ +""" if (({arg_name} != Py_None) && !PyObject_IsInstance({arg_name}, (PyObject *)&pylinphone_{arg_type}Type)) {{ + PyErr_SetString(PyExc_TypeError, "The '{arg_name}' arguments must be a {type_str} instance."); + return NULL; + }} +""".format(arg_name=arg_name, arg_type=strip_leading_linphone(arg_type), type_str=argument_type.type_str) + body = body[1:] # Remove leading '\t' + return body + def format_args_native_pointer_check(self): body = '' for xml_method_arg in self.xml_method_args: @@ -358,10 +377,13 @@ class MethodDefinition: argument_type = ArgumentType(arg_type, arg_complete_type, self.linphone_module) if argument_type.fmt_str == 'O': body += \ -""" if (({arg_name}_native_ptr = pylinphone_{arg_type}_get_native_ptr({arg_name})) == NULL) {{ - return NULL; +""" if (({arg_name} != NULL) && ({arg_name} != Py_None)) {{ + if (({arg_name}_native_ptr = pylinphone_{arg_type}_get_native_ptr({arg_name})) == NULL) {{ + return NULL; + }} }} """.format(arg_name=arg_name, arg_type=strip_leading_linphone(arg_type)) + body = body[1:] # Remove leading '\t' return body def parse_method_node(self): @@ -510,8 +532,8 @@ class SetterMethodDefinition(MethodDefinition): def format_arguments_parsing(self): if self.first_argument_type.check_func is None: attribute_type_check_code = \ -"""if (!PyObject_IsInstance(value, (PyObject *)&pylinphone_{class_name}Type)) {{ - PyErr_SetString(PyExc_TypeError, "The {attribute_name} attribute value must be a linphone.{class_name} instance"); +"""if ((value != Py_None) && !PyObject_IsInstance(value, (PyObject *)&pylinphone_{class_name}Type)) {{ + PyErr_SetString(PyExc_TypeError, "The '{attribute_name}' attribute value must be a linphone.{class_name} instance."); return -1; }} """.format(class_name=self.first_arg_class, attribute_name=self.attribute_name) @@ -521,7 +543,7 @@ class SetterMethodDefinition(MethodDefinition): checknotnone = "(value != Py_None) && " attribute_type_check_code = \ """if ({checknotnone}!{checkfunc}(value)) {{ - PyErr_SetString(PyExc_TypeError, "The {attribute_name} attribute value must be a {type_str}"); + PyErr_SetString(PyExc_TypeError, "The '{attribute_name}' attribute value must be a {type_str}."); return -1; }} """.format(checknotnone=checknotnone, checkfunc=self.first_argument_type.check_func, attribute_name=self.attribute_name, type_str=self.first_argument_type.type_str) @@ -536,16 +558,17 @@ class SetterMethodDefinition(MethodDefinition): attribute_native_ptr_check_code = '' if self.first_argument_type.use_native_pointer: attribute_native_ptr_check_code = \ -"""{arg_name}_native_ptr = pylinphone_{arg_class}_get_native_ptr({arg_name}); - if ({arg_name}_native_ptr == NULL) {{ - PyErr_SetString(PyExc_TypeError, "Invalid linphone.{arg_class} instance"); - return -1; +"""if ({arg_name} != Py_None) {{ + if (({arg_name}_native_ptr = pylinphone_{arg_class}_get_native_ptr({arg_name})) == NULL) {{ + PyErr_SetString(PyExc_TypeError, "Invalid linphone.{arg_class} instance."); + return -1; + }} }} """.format(arg_name="_" + self.first_arg_name, arg_class=self.first_arg_class) return \ """ {native_ptr_check_code} if (value == NULL) {{ - PyErr_SetString(PyExc_TypeError, "Cannot delete the {attribute_name} attribute"); + PyErr_SetString(PyExc_TypeError, "Cannot delete the {attribute_name} attribute."); return -1; }} {attribute_type_check_code} From 067c8a9527be15688db798aa3736129a31241a82 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Thu, 14 Aug 2014 14:44:59 +0200 Subject: [PATCH 13/43] For functions returning or taking an MSList as an argument, specify what the MSList contains in the documentation. --- coreapi/authentication.c | 2 ++ coreapi/chat.c | 4 ++-- coreapi/help/Doxyfile.in | 2 +- coreapi/linphonecore.c | 14 ++++++++++++++ coreapi/linphonefriend.h | 3 ++- coreapi/proxy.c | 2 ++ tools/genapixml.py | 15 +++++++++++++++ tools/python/apixml2python.py | 3 ++- 8 files changed, 40 insertions(+), 5 deletions(-) diff --git a/coreapi/authentication.c b/coreapi/authentication.c index 59b3ea1b5..de7248316 100644 --- a/coreapi/authentication.c +++ b/coreapi/authentication.c @@ -378,6 +378,8 @@ void linphone_core_remove_auth_info(LinphoneCore *lc, const LinphoneAuthInfo *in /** * Returns an unmodifiable list of currently entered LinphoneAuthInfo. + * @param[in] lc The LinphoneCore object + * @return \mslist{LinphoneAuthInfo} **/ const MSList *linphone_core_get_auth_info_list(const LinphoneCore *lc){ return lc->auth_info; diff --git a/coreapi/chat.c b/coreapi/chat.c index c9ec8b6d5..66bde2968 100644 --- a/coreapi/chat.c +++ b/coreapi/chat.c @@ -246,8 +246,8 @@ bool_t linphone_core_chat_enabled(const LinphoneCore *lc){ /** * Returns an list of chat rooms - * @param lc #LinphoneCore object - * @return A list of #LinphoneChatRoom + * @param[in] lc #LinphoneCore object + * @return \mslist{LinphoneChatRoom} **/ MSList* linphone_core_get_chat_rooms(LinphoneCore *lc) { return lc->chatrooms; diff --git a/coreapi/help/Doxyfile.in b/coreapi/help/Doxyfile.in index 27068c53d..12facea9b 100644 --- a/coreapi/help/Doxyfile.in +++ b/coreapi/help/Doxyfile.in @@ -34,7 +34,7 @@ DETAILS_AT_TOP = NO INHERIT_DOCS = YES DISTRIBUTE_GROUP_DOC = NO TAB_SIZE = 8 -ALIASES = +ALIASES = mslist{1}="A list of \ref \1 objects. \xmlonly \1 \endxmlonly" OPTIMIZE_OUTPUT_FOR_C = YES OPTIMIZE_OUTPUT_JAVA = NO SUBGROUPING = YES diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 59c46fee2..34add6e0f 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -1466,6 +1466,8 @@ LinphoneCore *linphone_core_new_with_config(const LinphoneCoreVTable *vtable, st /** * Returns the list of available audio codecs. + * @param[in] lc The LinphoneCore object + * @return \mslist{PayloadType} * * This list is unmodifiable. The ->data field of the MSList points a PayloadType * structure holding the codec information. @@ -1480,6 +1482,8 @@ const MSList *linphone_core_get_audio_codecs(const LinphoneCore *lc) /** * Returns the list of available video codecs. + * @param[in] lc The LinphoneCore object + * @return \mslist{PayloadType} * * This list is unmodifiable. The ->data field of the MSList points a PayloadType * structure holding the codec information. @@ -1631,6 +1635,9 @@ LinphoneAddress *linphone_core_get_primary_contact_parsed(LinphoneCore *lc){ /** * Sets the list of audio codecs. + * @param[in] lc The LinphoneCore object + * @param[in] codecs \mslist{PayloadType} + * @return 0 * * @ingroup media_parameters * The list is taken by the LinphoneCore thus the application should not free it. @@ -1646,6 +1653,9 @@ int linphone_core_set_audio_codecs(LinphoneCore *lc, MSList *codecs) /** * Sets the list of video codecs. + * @param[in] lc The LinphoneCore object + * @param[in] codecs \mslist{PayloadType} + * @return 0 * * @ingroup media_parameters * The list is taken by the LinphoneCore thus the application should not free it. @@ -3672,6 +3682,8 @@ int linphone_core_terminate_all_calls(LinphoneCore *lc){ /** * Returns the current list of calls. + * @param[in] lc The LinphoneCore object + * @return \mslist{LinphoneCall} * * Note that this list is read-only and might be changed by the core after a function call to linphone_core_iterate(). * Similarly the LinphoneCall objects inside it might be destroyed without prior notice. @@ -4814,6 +4826,8 @@ LinphoneFirewallPolicy linphone_core_get_firewall_policy(const LinphoneCore *lc) /** * Get the list of call logs (past calls). + * @param[in] lc The LinphoneCore object + * @return \mslist{LinphoneCallLog} * * @ingroup call_logs **/ diff --git a/coreapi/linphonefriend.h b/coreapi/linphonefriend.h index 891bf7631..f64286c0e 100644 --- a/coreapi/linphonefriend.h +++ b/coreapi/linphonefriend.h @@ -356,7 +356,8 @@ LINPHONE_PUBLIC void linphone_core_reject_subscriber(LinphoneCore *lc, LinphoneF /** * Get Buddy list of LinphoneFriend - * @param lc #LinphoneCore object + * @param[in] lc #LinphoneCore object + * @return \mslist{LinphoneFriend} */ LINPHONE_PUBLIC const MSList * linphone_core_get_friend_list(const LinphoneCore *lc); diff --git a/coreapi/proxy.c b/coreapi/proxy.c index e6a33d556..d66dd30fd 100644 --- a/coreapi/proxy.c +++ b/coreapi/proxy.c @@ -1198,6 +1198,8 @@ int linphone_core_get_default_proxy(LinphoneCore *lc, LinphoneProxyConfig **conf /** * Returns an unmodifiable list of entered proxy configurations. + * @param[in] lc The LinphoneCore object + * @return \mslist{LinphoneProxyConfig} **/ const MSList *linphone_core_get_proxy_config_list(const LinphoneCore *lc){ return lc->sip_conf.proxies; diff --git a/tools/genapixml.py b/tools/genapixml.py index 2c9286792..4f834fb0c 100755 --- a/tools/genapixml.py +++ b/tools/genapixml.py @@ -72,6 +72,7 @@ class CArgument(CObject): def __init__(self, t, name = '', enums = [], structs = []): CObject.__init__(self, name) self.description = None + self.containedType = None keywords = [ 'const', 'struct', 'enum', 'signed', 'unsigned', 'short', 'long', '*' ] fullySplittedType = [] splittedType = t.strip().split(' ') @@ -302,6 +303,8 @@ class Project: para.remove(n) for n in para.findall('.//ref'): n.attrib = {} + for n in para.findall(".//mslist"): + para.remove(n) if descriptionNode.tag == 'parameterdescription': descriptionNode.tag = 'description' if descriptionNode.tag == 'simplesect': @@ -485,6 +488,10 @@ class Project: returnarg = CArgument(t, enums = self.enums, structs = self.__structs) returndesc = node.find("./detaileddescription/para/simplesect[@kind='return']") if returndesc is not None: + if returnarg.ctype == 'MSList': + n = returndesc.find('.//mslist') + if n is not None: + returnarg.containedType = n.text returnarg.description = self.__cleanDescription(returndesc) elif returnarg.completeType != 'void': missingDocWarning += "\tReturn value is not documented\n" @@ -504,6 +511,10 @@ class Project: for arg in argslist.arguments: for paramdesc in paramdescs: if arg.name == paramdesc.find('./parameternamelist').find('./parametername').text: + if arg.ctype == 'MSList': + n = paramdesc.find('.//mslist') + if n is not None: + arg.containedType = n.text arg.description = self.__cleanDescription(paramdesc.find('./parameterdescription')) missingDocWarning = '' for arg in argslist.arguments: @@ -594,12 +605,16 @@ class Generator: functionAttributes['location'] = f.location functionNode = ET.SubElement(parentNode, nodeName, functionAttributes) returnValueAttributes = { 'type' : f.returnArgument.ctype, 'completetype' : f.returnArgument.completeType } + if f.returnArgument.containedType is not None: + returnValueAttributes['containedtype'] = f.returnArgument.containedType returnValueNode = ET.SubElement(functionNode, 'return', returnValueAttributes) if f.returnArgument.description is not None: returnValueNode.append(f.returnArgument.description) argumentsNode = ET.SubElement(functionNode, 'arguments') for arg in f.arguments: argumentNodeAttributes = { 'name' : arg.name, 'type' : arg.ctype, 'completetype' : arg.completeType } + if arg.containedType is not None: + argumentNodeAttributes['containedtype'] = arg.containedType argumentNode = ET.SubElement(argumentsNode, 'argument', argumentNodeAttributes) if arg.description is not None: argumentNode.append(arg.description) diff --git a/tools/python/apixml2python.py b/tools/python/apixml2python.py index dd37e2027..79b2bae0b 100755 --- a/tools/python/apixml2python.py +++ b/tools/python/apixml2python.py @@ -67,11 +67,12 @@ blacklisted_functions = [ 'linphone_core_get_video_port_range', # to be handwritten because of result via arguments 'linphone_core_publish', # missing LinphoneContent 'linphone_core_serialize_logs', # There is no use to wrap this function + 'linphone_core_set_audio_codecs', # missing PayloadType and MSList 'linphone_core_set_log_file', # There is no use to wrap this function 'linphone_core_set_log_handler', # Hand-written but put directly in the linphone module 'linphone_core_set_log_level', # There is no use to wrap this function + 'linphone_core_set_video_codecs', # missing PayloadType and MSList 'linphone_core_set_video_policy', # missing LinphoneVideoPolicy - 'linphone_core_set_audio_codecs', # missing PayloadType and MSList 'linphone_core_set_sip_transports', # missing LCSipTransports 'linphone_core_subscribe', # missing LinphoneContent 'linphone_event_notify', # missing LinphoneContent From 448ff25b546486a06ae1bb70efcbaeed45964c1b Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Thu, 14 Aug 2014 15:50:13 +0200 Subject: [PATCH 14/43] Handle MSList type in the Python wrapper. --- tools/python/apixml2python/linphone.py | 72 ++++++++++++++----- .../apixml2python/linphone_module.mustache | 26 +++++++ 2 files changed, 80 insertions(+), 18 deletions(-) diff --git a/tools/python/apixml2python/linphone.py b/tools/python/apixml2python/linphone.py index e2e13b94b..109f6f5b2 100644 --- a/tools/python/apixml2python/linphone.py +++ b/tools/python/apixml2python/linphone.py @@ -15,6 +15,7 @@ # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +from sets import Set import sys @@ -38,9 +39,10 @@ def compute_event_name(s): class ArgumentType: - def __init__(self, basic_type, complete_type, linphone_module): + def __init__(self, basic_type, complete_type, contained_type, linphone_module): self.basic_type = basic_type self.complete_type = complete_type + self.contained_type = contained_type self.linphone_module = linphone_module self.type_str = None self.check_func = None @@ -51,6 +53,8 @@ class ArgumentType: self.use_native_pointer = False self.cast_convert_func_result = True self.__compute() + if self.basic_type == 'MSList' and self.contained_type is not None: + self.linphone_module.mslist_types.add(self.contained_type) def __compute(self): splitted_type = self.complete_type.split(' ') @@ -135,6 +139,13 @@ class ArgumentType: self.convert_func = 'PyInt_AsLong' self.fmt_str = 'i' self.cfmt_str = '%d' + elif self.basic_type == 'MSList': + self.type_str = 'list of linphone.' + self.contained_type + self.check_func = 'PyList_Check' + self.convert_func = 'PyList_AsMSListOf' + self.contained_type + self.convert_from_func = 'PyList_FromMSListOf' + self.contained_type + self.fmt_str = 'O' + self.cfmt_str = '%p' elif self.basic_type == 'MSVideoSize': self.type_str = 'linphone.VideoSize' self.check_func = 'PyLinphoneVideoSize_Check' @@ -165,6 +176,7 @@ class MethodDefinition: self.build_value_format = '' self.return_type = 'void' self.return_complete_type = 'void' + self.return_contained_type = None self.method_node = method_node self.class_ = class_ self.linphone_module = linphone_module @@ -178,9 +190,10 @@ class MethodDefinition: if self.xml_method_return is not None: self.return_type = self.xml_method_return.get('type') self.return_complete_type = self.xml_method_return.get('completetype') + self.return_contained_type = self.xml_method_return.get('containedtype') if self.return_complete_type != 'void': body += "\t" + self.return_complete_type + " cresult;\n" - argument_type = ArgumentType(self.return_type, self.return_complete_type, self.linphone_module) + argument_type = ArgumentType(self.return_type, self.return_complete_type, self.return_contained_type, self.linphone_module) self.build_value_format = argument_type.fmt_str if self.build_value_format == 'O': body += "\tPyObject * pyresult;\n" @@ -191,7 +204,8 @@ class MethodDefinition: arg_name = "_" + xml_method_arg.get('name') arg_type = xml_method_arg.get('type') arg_complete_type = xml_method_arg.get('completetype') - argument_type = ArgumentType(arg_type, arg_complete_type, self.linphone_module) + arg_contained_type = xml_method_arg.get('containedtype') + argument_type = ArgumentType(arg_type, arg_complete_type, arg_contained_type, self.linphone_module) self.parse_tuple_format += argument_type.fmt_str if argument_type.use_native_pointer: body += "\tPyObject * " + arg_name + ";\n" @@ -234,9 +248,10 @@ class MethodDefinition: arg_name = "_" + xml_method_arg.get('name') arg_type = xml_method_arg.get('type') arg_complete_type = xml_method_arg.get('completetype') + arg_contained_type = xml_method_arg.get('containedtype') if fmt != '': fmt += ', ' - argument_type = ArgumentType(arg_type, arg_complete_type, self.linphone_module) + argument_type = ArgumentType(arg_type, arg_complete_type, arg_contained_type, self.linphone_module) fmt += argument_type.cfmt_str args.append(arg_name) if argument_type.fmt_str == 'O': @@ -254,7 +269,8 @@ class MethodDefinition: arg_name = "_" + xml_method_arg.get('name') arg_type = xml_method_arg.get('type') arg_complete_type = xml_method_arg.get('completetype') - argument_type = ArgumentType(arg_type, arg_complete_type, self.linphone_module) + arg_contained_type = xml_method_arg.get('containedtype') + argument_type = ArgumentType(arg_type, arg_complete_type, arg_contained_type, self.linphone_module) if argument_type.convert_func is None: arg_names.append(arg_name + "_native_ptr") else: @@ -294,7 +310,7 @@ class MethodDefinition: }} """.format(func=ref_function, cast_type=self.remove_const_from_complete_type(self.return_complete_type)) else: - return_argument_type = ArgumentType(self.return_type, self.return_complete_type, self.linphone_module) + 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: convert_from_code = \ """pyresult = {convert_func}(cresult); @@ -357,7 +373,8 @@ class MethodDefinition: arg_name = "_" + xml_method_arg.get('name') arg_type = xml_method_arg.get('type') arg_complete_type = xml_method_arg.get('completetype') - argument_type = ArgumentType(arg_type, arg_complete_type, self.linphone_module) + arg_contained_type = xml_method_arg.get('containedtype') + argument_type = ArgumentType(arg_type, arg_complete_type, arg_contained_type, self.linphone_module) if argument_type.fmt_str == 'O': body += \ """ if (({arg_name} != Py_None) && !PyObject_IsInstance({arg_name}, (PyObject *)&pylinphone_{arg_type}Type)) {{ @@ -374,7 +391,8 @@ class MethodDefinition: arg_name = "_" + xml_method_arg.get('name') arg_type = xml_method_arg.get('type') arg_complete_type = xml_method_arg.get('completetype') - argument_type = ArgumentType(arg_type, arg_complete_type, self.linphone_module) + arg_contained_type = xml_method_arg.get('containedtype') + argument_type = ArgumentType(arg_type, arg_complete_type, arg_contained_type, self.linphone_module) if argument_type.fmt_str == 'O': body += \ """ if (({arg_name} != NULL) && ({arg_name} != Py_None)) {{ @@ -568,7 +586,7 @@ class SetterMethodDefinition(MethodDefinition): return \ """ {native_ptr_check_code} if (value == NULL) {{ - PyErr_SetString(PyExc_TypeError, "Cannot delete the {attribute_name} attribute."); + PyErr_SetString(PyExc_TypeError, "Cannot delete the '{attribute_name}' attribute."); return -1; }} {attribute_type_check_code} @@ -603,8 +621,9 @@ class SetterMethodDefinition(MethodDefinition): self.attribute_name = self.method_node.get('property_name') self.first_arg_type = self.xml_method_args[0].get('type') self.first_arg_complete_type = self.xml_method_args[0].get('completetype') + self.first_arg_contained_type = self.xml_method_args[0].get('containedtype') self.first_arg_name = self.xml_method_args[0].get('name') - self.first_argument_type = ArgumentType(self.first_arg_type, self.first_arg_complete_type, self.linphone_module) + self.first_argument_type = ArgumentType(self.first_arg_type, self.first_arg_complete_type, self.first_arg_contained_type, self.linphone_module) self.first_arg_class = strip_leading_linphone(self.first_arg_type) class EventCallbackMethodDefinition(MethodDefinition): @@ -621,7 +640,8 @@ class EventCallbackMethodDefinition(MethodDefinition): arg_name = 'py' + xml_method_arg.get('name') arg_type = xml_method_arg.get('type') arg_complete_type = xml_method_arg.get('completetype') - argument_type = ArgumentType(arg_type, arg_complete_type, self.linphone_module) + arg_contained_type = xml_method_arg.get('containedtype') + argument_type = ArgumentType(arg_type, arg_complete_type, arg_contained_type, self.linphone_module) if argument_type.fmt_str == 'O': specific += "\tPyObject * " + arg_name + " = NULL;\n" return "{common}\n{specific}".format(common=common, specific=specific) @@ -632,7 +652,8 @@ class EventCallbackMethodDefinition(MethodDefinition): arg_name = xml_method_arg.get('name') arg_type = xml_method_arg.get('type') arg_complete_type = xml_method_arg.get('completetype') - argument_type = ArgumentType(arg_type, arg_complete_type, self.linphone_module) + arg_contained_type = xml_method_arg.get('containedtype') + argument_type = ArgumentType(arg_type, arg_complete_type, arg_contained_type, self.linphone_module) if argument_type.fmt_str == 'O': type_class = self.find_class_definition(arg_type) get_user_data_code = '' @@ -655,9 +676,10 @@ class EventCallbackMethodDefinition(MethodDefinition): arg_name = xml_method_arg.get('name') arg_type = xml_method_arg.get('type') arg_complete_type = xml_method_arg.get('completetype') + arg_contained_type = xml_method_arg.get('containedtype') if fmt != '': fmt += ', ' - argument_type = ArgumentType(arg_type, arg_complete_type, self.linphone_module) + argument_type = ArgumentType(arg_type, arg_complete_type, arg_contained_type, self.linphone_module) fmt += argument_type.cfmt_str args.append(arg_name) args=', '.join(args) @@ -672,7 +694,8 @@ class EventCallbackMethodDefinition(MethodDefinition): arg_name = xml_method_arg.get('name') arg_type = xml_method_arg.get('type') arg_complete_type = xml_method_arg.get('completetype') - argument_type = ArgumentType(arg_type, arg_complete_type, self.linphone_module) + arg_contained_type = xml_method_arg.get('containedtype') + argument_type = ArgumentType(arg_type, arg_complete_type, arg_contained_type, self.linphone_module) fmt += argument_type.fmt_str if argument_type.fmt_str == 'O': args.append('py' + arg_name) @@ -713,6 +736,7 @@ class LinphoneModule(object): def __init__(self, tree, blacklisted_classes, blacklisted_events, blacklisted_functions, hand_written_functions): self.internal_instance_method_names = ['destroy', 'ref', 'unref'] self.internal_property_names = ['user_data'] + self.mslist_types = Set([]) self.enums = [] self.enum_names = [] xml_enums = tree.findall("./enums/enum") @@ -908,6 +932,14 @@ class LinphoneModule(object): except Exception, e: e.args += (c['class_name'], 'dealloc_body') raise + # Convert mslist_types to a list of dictionaries for the template + d = [] + for mslist_type in self.mslist_types: + t = {} + t['c_contained_type'] = mslist_type + t['python_contained_type'] = strip_leading_linphone(mslist_type) + d.append(t) + self.mslist_types = d def __format_doc_node(self, node): desc = '' @@ -973,7 +1005,8 @@ class LinphoneModule(object): arg_name = xml_method_arg.get('name') arg_type = xml_method_arg.get('type') arg_complete_type = xml_method_arg.get('completetype') - argument_type = ArgumentType(arg_type, arg_complete_type, self) + arg_contained_type = xml_method_arg.get('containedtype') + argument_type = ArgumentType(arg_type, arg_complete_type, arg_contained_type, self) arg_doc = self.__format_doc_content(None, xml_method_arg.find('description')) doc += '\n\t' + arg_name + ' [' + argument_type.type_str + ']' if arg_doc != '': @@ -981,9 +1014,10 @@ class LinphoneModule(object): if xml_method_return is not None: return_type = xml_method_return.get('type') return_complete_type = xml_method_return.get('completetype') + return_contained_type = xml_method_return.get('containedtype') if return_complete_type != 'void': return_doc = self.__format_doc_content(None, xml_method_return.find('description')) - return_argument_type = ArgumentType(return_type, return_complete_type, self) + return_argument_type = ArgumentType(return_type, return_complete_type, return_contained_type, self) doc += '\n\nReturns:\n\t[' + return_argument_type.type_str + '] ' + return_doc doc = self.__replace_doc_special_chars(doc) return doc @@ -992,7 +1026,8 @@ class LinphoneModule(object): xml_method_arg = xml_node.findall('./arguments/argument')[1] arg_type = xml_method_arg.get('type') arg_complete_type = xml_method_arg.get('completetype') - argument_type = ArgumentType(arg_type, arg_complete_type, self) + arg_contained_type = xml_method_arg.get('containedtype') + argument_type = ArgumentType(arg_type, arg_complete_type, arg_contained_type, self) doc = self.__format_doc_content(xml_node.find('briefdescription'), xml_node.find('detaileddescription')) doc = '[' + argument_type.type_str + '] ' + doc doc = self.__replace_doc_special_chars(doc) @@ -1002,7 +1037,8 @@ class LinphoneModule(object): xml_method_return = xml_node.find('./return') return_type = xml_method_return.get('type') return_complete_type = xml_method_return.get('completetype') - return_argument_type = ArgumentType(return_type, return_complete_type, self) + return_contained_type = xml_method_return.get('containedtype') + return_argument_type = ArgumentType(return_type, return_complete_type, return_contained_type, self) doc = self.__format_doc_content(xml_node.find('briefdescription'), xml_node.find('detaileddescription')) doc = '[' + return_argument_type.type_str + '] ' + doc doc = self.__replace_doc_special_chars(doc) diff --git a/tools/python/apixml2python/linphone_module.mustache b/tools/python/apixml2python/linphone_module.mustache index 005f05edb..62b626843 100644 --- a/tools/python/apixml2python/linphone_module.mustache +++ b/tools/python/apixml2python/linphone_module.mustache @@ -69,6 +69,32 @@ static PyObject * pylinphone_{{class_name}}_instance_method_{{method_name}}(PyOb {{/class_instance_hand_written_methods}} {{/classes}} +{{#mslist_types}} +PyObject * PyList_FromMSListOf{{c_contained_type}}(const MSList *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}}_new_from_native_ptr(&pylinphone_{{python_contained_type}}Type, native_ptr); + PyList_Append(pyl, item); + msl = ms_list_next(msl); + } + return pyl; +} + +MSList * PyList_AsMSListOf{{c_contained_type}}(PyObject *pyl) { + MSList *msl = NULL; + Py_ssize_t idx; + Py_ssize_t size = PyList_Size(pyl); + for (idx = 0; idx < size; idx++) { + PyObject *item = PyList_GetItem(pyl, idx); + {{c_contained_type}} *native_ptr = pylinphone_{{python_contained_type}}_get_native_ptr(item); + msl = ms_list_append(msl, native_ptr); + } + return msl; +} + +{{/mslist_types}} + {{#events}} {{{event_callback_definition}}} {{/events}} From 02bbe939b1223b2592dba057a3646101895928c9 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Thu, 14 Aug 2014 16:33:35 +0200 Subject: [PATCH 15/43] Generate the Python wrapper for the functions handling MSList objects. --- tools/python/apixml2python.py | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/tools/python/apixml2python.py b/tools/python/apixml2python.py index 79b2bae0b..f4c681fe7 100755 --- a/tools/python/apixml2python.py +++ b/tools/python/apixml2python.py @@ -50,28 +50,18 @@ blacklisted_functions = [ 'linphone_chat_room_create_file_transfer_message', # missing LinphoneContent 'linphone_chat_room_create_message_2', # missing time_t 'linphone_core_can_we_add_call', # private function - 'linphone_core_get_audio_codecs', # missing PayloadType and MSList 'linphone_core_get_audio_port_range', # to be handwritten because of result via arguments - 'linphone_core_get_auth_info_list', # missing MSList - 'linphone_core_get_call_logs', # missing MSList - 'linphone_core_get_calls', # missing MSList - 'linphone_core_get_chat_rooms', # missing MSList 'linphone_core_get_default_proxy', # to be handwritten because of double pointer indirection - 'linphone_core_get_friend_list', # missing MSList - 'linphone_core_get_proxy_config_list', # missing MSList 'linphone_core_get_sip_transports', # missing LCSipTransports 'linphone_core_get_sip_transports_used', # missing LCSipTransports 'linphone_core_get_supported_video_sizes', # missing MSVideoSizeDef - 'linphone_core_get_video_codecs', # missing PayloadType and MSList 'linphone_core_get_video_policy', # missing LinphoneVideoPolicy 'linphone_core_get_video_port_range', # to be handwritten because of result via arguments 'linphone_core_publish', # missing LinphoneContent 'linphone_core_serialize_logs', # There is no use to wrap this function - 'linphone_core_set_audio_codecs', # missing PayloadType and MSList 'linphone_core_set_log_file', # There is no use to wrap this function 'linphone_core_set_log_handler', # Hand-written but put directly in the linphone module 'linphone_core_set_log_level', # There is no use to wrap this function - 'linphone_core_set_video_codecs', # missing PayloadType and MSList 'linphone_core_set_video_policy', # missing LinphoneVideoPolicy 'linphone_core_set_sip_transports', # missing LCSipTransports 'linphone_core_subscribe', # missing LinphoneContent From 90c0306f66aad64a797690a98e84535b4672bf7e Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Thu, 14 Aug 2014 16:33:53 +0200 Subject: [PATCH 16/43] Fix compilation warnings. --- tools/python/apixml2python/handwritten_definitions.mustache | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tools/python/apixml2python/handwritten_definitions.mustache b/tools/python/apixml2python/handwritten_definitions.mustache index b3d043c32..41a563687 100644 --- a/tools/python/apixml2python/handwritten_definitions.mustache +++ b/tools/python/apixml2python/handwritten_definitions.mustache @@ -117,8 +117,7 @@ static PyObject * pylinphone_module_method_set_log_handler(PyObject *self, PyObj static PyObject * pylinphone_Core_get_video_devices(PyObject *self, void *closure) { PyObject *_list; - char **_devices; - char *_device; + const char **_devices; LinphoneCore *native_ptr = pylinphone_Core_get_native_ptr(self); if (native_ptr == NULL) { From 719b507b9faab1cbe1e77f2bf7151878553ee4e1 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Thu, 14 Aug 2014 17:48:43 +0200 Subject: [PATCH 17/43] Partial implementation of time_t in the Python wrapper. --- tools/python/apixml2python.py | 3 -- .../handwritten_declarations.mustache | 2 ++ .../handwritten_definitions.mustache | 33 +++++++++++++++++++ tools/python/apixml2python/linphone.py | 7 ++++ 4 files changed, 42 insertions(+), 3 deletions(-) diff --git a/tools/python/apixml2python.py b/tools/python/apixml2python.py index f4c681fe7..9fe7f214c 100755 --- a/tools/python/apixml2python.py +++ b/tools/python/apixml2python.py @@ -40,11 +40,9 @@ blacklisted_events = [ blacklisted_functions = [ 'linphone_call_log_get_local_stats', # missing rtp_stats_t 'linphone_call_log_get_remote_stats', # missing rtp_stats_t - 'linphone_call_log_get_start_date', # missing time_t 'linphone_call_params_get_privacy', # missing LinphonePrivacyMask 'linphone_call_params_set_privacy', # missing LinphonePrivacyMask 'linphone_chat_message_get_file_transfer_information', # missing LinphoneContent - 'linphone_chat_message_get_time', # missing time_t 'linphone_chat_message_start_file_download', # to be handwritten because of callback 'linphone_chat_message_state_to_string', # There is no use to wrap this function 'linphone_chat_room_create_file_transfer_message', # missing LinphoneContent @@ -70,7 +68,6 @@ blacklisted_functions = [ 'linphone_event_send_subscribe', # missing LinphoneContent 'linphone_event_update_publish', # missing LinphoneContent 'linphone_event_update_subscribe', # missing LinphoneContent - 'linphone_presence_model_get_timestamp', # missing time_t 'linphone_proxy_config_get_privacy', # missing LinphonePrivacyMask 'linphone_proxy_config_normalize_number', # to be handwritten because of result via arguments 'linphone_proxy_config_set_file_transfer_server', # defined but not implemented in linphone core diff --git a/tools/python/apixml2python/handwritten_declarations.mustache b/tools/python/apixml2python/handwritten_declarations.mustache index 4a50a848b..eac0ba4b3 100644 --- a/tools/python/apixml2python/handwritten_declarations.mustache +++ b/tools/python/apixml2python/handwritten_declarations.mustache @@ -10,3 +10,5 @@ typedef struct { int PyLinphoneVideoSize_Check(PyObject *p); MSVideoSize PyLinphoneVideoSize_AsMSVideoSize(PyObject *obj); PyObject * PyLinphoneVideoSize_FromMSVideoSize(MSVideoSize vs); +time_t PyDateTime_As_time_t(PyObject *obj); +PyObject * PyDateTime_From_time_t(time_t t); diff --git a/tools/python/apixml2python/handwritten_definitions.mustache b/tools/python/apixml2python/handwritten_definitions.mustache index 41a563687..5a602d515 100644 --- a/tools/python/apixml2python/handwritten_definitions.mustache +++ b/tools/python/apixml2python/handwritten_definitions.mustache @@ -393,6 +393,39 @@ PyObject * PyLinphoneVideoSize_FromMSVideoSize(MSVideoSize vs) { } +time_t PyDateTime_As_time_t(PyObject *obj) { +} + +PyObject * PyDateTime_From_time_t(time_t t) { + PyObject *pyret = NULL; + PyObject *datetime_module; + PyObject *datetime_class; + if (t == -1) { + Py_RETURN_NONE; + } + datetime_module = PyImport_ImportModule("datetime"); + if (datetime_module != NULL) { + PyObject *datetime_class = PyObject_GetAttrString(datetime_module, "datetime"); + if (datetime_class != NULL) { + PyObject *utcfromtimestamp = PyObject_GetAttrString(datetime_class, "utcfromtimestamp"); + if (utcfromtimestamp != NULL) { + pyret = PyEval_CallObject(utcfromtimestamp, Py_BuildValue("(f)", (float)t)); + if (pyret == NULL) { + PyErr_Print(); + } + Py_DECREF(utcfromtimestamp); + } + Py_DECREF(datetime_class); + } + Py_DECREF(datetime_module); + } + if (pyret == NULL) { + Py_RETURN_NONE; + } + return pyret; +} + + static PyObject * pylinphone_PayloadTypeType_module_method_string(PyObject *self, PyObject *args) { const char *value_str = "[invalid]"; int value; diff --git a/tools/python/apixml2python/linphone.py b/tools/python/apixml2python/linphone.py index 109f6f5b2..a7b1f21b0 100644 --- a/tools/python/apixml2python/linphone.py +++ b/tools/python/apixml2python/linphone.py @@ -139,6 +139,13 @@ class ArgumentType: self.convert_func = 'PyInt_AsLong' self.fmt_str = 'i' self.cfmt_str = '%d' + elif self.basic_type == 'time_t': + self.type_str = 'DateTime' + self.check_func = 'PyDateTime_Check' + self.convert_func = 'PyDateTime_As_time_t' + self.convert_from_func = 'PyDateTime_From_time_t' + self.fmt_str = 'O' + self.cfmt_str = '%p' elif self.basic_type == 'MSList': self.type_str = 'list of linphone.' + self.contained_type self.check_func = 'PyList_Check' From 4a335ba6e1b94c11e64720fd7a02e1c7873002a6 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Mon, 18 Aug 2014 13:42:45 +0200 Subject: [PATCH 18/43] Complete handling of time_t type in the Python wrapper. --- tools/python/apixml2python.py | 1 - .../handwritten_definitions.mustache | 18 ++++- tools/python/apixml2python/linphone.py | 80 ++++++++++++++----- .../apixml2python/linphone_module.mustache | 2 + 4 files changed, 79 insertions(+), 22 deletions(-) diff --git a/tools/python/apixml2python.py b/tools/python/apixml2python.py index 9fe7f214c..b1bf3ebb2 100755 --- a/tools/python/apixml2python.py +++ b/tools/python/apixml2python.py @@ -46,7 +46,6 @@ blacklisted_functions = [ 'linphone_chat_message_start_file_download', # to be handwritten because of callback 'linphone_chat_message_state_to_string', # There is no use to wrap this function 'linphone_chat_room_create_file_transfer_message', # missing LinphoneContent - 'linphone_chat_room_create_message_2', # missing time_t 'linphone_core_can_we_add_call', # private function 'linphone_core_get_audio_port_range', # to be handwritten because of result via arguments 'linphone_core_get_default_proxy', # to be handwritten because of double pointer indirection diff --git a/tools/python/apixml2python/handwritten_definitions.mustache b/tools/python/apixml2python/handwritten_definitions.mustache index 5a602d515..e52f55e3a 100644 --- a/tools/python/apixml2python/handwritten_definitions.mustache +++ b/tools/python/apixml2python/handwritten_definitions.mustache @@ -394,12 +394,28 @@ PyObject * PyLinphoneVideoSize_FromMSVideoSize(MSVideoSize vs) { time_t PyDateTime_As_time_t(PyObject *obj) { + time_t ret = -1; + PyObject *utctimetuple = PyObject_GetAttrString(obj, "utctimetuple"); + if (utctimetuple != NULL) { + PyObject *calendar_module = PyImport_ImportModule("calendar"); + if (calendar_module != NULL) { + PyObject *timegm = PyObject_GetAttrString(calendar_module, "timegm"); + if (timegm != NULL) { + PyObject *tuple = PyEval_CallObject(utctimetuple, Py_BuildValue("()")); + PyObject *pyres = PyEval_CallObject(timegm, Py_BuildValue("(O)", tuple)); + ret = (time_t)PyLong_AsLong(pyres); + Py_DECREF(timegm); + } + Py_DECREF(calendar_module); + } + Py_DECREF(utctimetuple); + } + return ret; } PyObject * PyDateTime_From_time_t(time_t t) { PyObject *pyret = NULL; PyObject *datetime_module; - PyObject *datetime_class; if (t == -1) { Py_RETURN_NONE; } diff --git a/tools/python/apixml2python/linphone.py b/tools/python/apixml2python/linphone.py index a7b1f21b0..145a3d9c9 100644 --- a/tools/python/apixml2python/linphone.py +++ b/tools/python/apixml2python/linphone.py @@ -50,6 +50,7 @@ class ArgumentType: self.convert_from_func = None self.fmt_str = 'O' self.cfmt_str = '%p' + self.cnativefmt_str = '%p' self.use_native_pointer = False self.cast_convert_func_result = True self.__compute() @@ -146,6 +147,7 @@ class ArgumentType: self.convert_from_func = 'PyDateTime_From_time_t' self.fmt_str = 'O' self.cfmt_str = '%p' + self.cnativefmt_str = "%ld" elif self.basic_type == 'MSList': self.type_str = 'list of linphone.' + self.contained_type self.check_func = 'PyList_Check' @@ -214,9 +216,12 @@ class MethodDefinition: arg_contained_type = xml_method_arg.get('containedtype') argument_type = ArgumentType(arg_type, arg_complete_type, arg_contained_type, self.linphone_module) self.parse_tuple_format += argument_type.fmt_str - if argument_type.use_native_pointer: + if argument_type.fmt_str == 'O' and argument_type.use_native_pointer: body += "\tPyObject * " + arg_name + ";\n" body += "\t" + arg_complete_type + " " + arg_name + "_native_ptr = NULL;\n" + elif argument_type.fmt_str == 'O' and argument_type.convert_func is not None: + body += "\tPyObject * " + arg_name + ";\n" + body += "\t" + arg_complete_type + " " + arg_name + "_native_obj;\n" elif strip_leading_linphone(arg_complete_type) in self.linphone_module.enum_names: body += "\tint " + arg_name + ";\n" else: @@ -235,15 +240,28 @@ class MethodDefinition: return NULL; }} """.format(fmt=self.parse_tuple_format, args=', '.join(map(lambda a: '&' + a, self.arg_names))) + args_conversion_code = '' + for xml_method_arg in self.xml_method_args: + arg_name = "_" + xml_method_arg.get('name') + arg_type = xml_method_arg.get('type') + arg_complete_type = xml_method_arg.get('completetype') + arg_contained_type = xml_method_arg.get('containedtype') + argument_type = ArgumentType(arg_type, arg_complete_type, arg_contained_type, self.linphone_module) + if argument_type.fmt_str == 'O' and argument_type.convert_func is not None: + args_conversion_code += \ +""" {arg_name}_native_obj = {convert_func}({arg_name}); +""".format(arg_name=arg_name, convert_func=argument_type.convert_func) return \ """ {class_native_ptr_check_code} {parse_tuple_code} {args_type_check_code} {args_native_ptr_check_code} + {args_conversion_code} """.format(class_native_ptr_check_code=class_native_ptr_check_code, parse_tuple_code=parse_tuple_code, args_type_check_code=self.format_args_type_check(), - args_native_ptr_check_code=self.format_args_native_pointer_check()) + args_native_ptr_check_code=self.format_args_native_pointer_check(), + args_conversion_code=args_conversion_code) def format_enter_trace(self): fmt = '' @@ -262,8 +280,11 @@ class MethodDefinition: fmt += argument_type.cfmt_str args.append(arg_name) if argument_type.fmt_str == 'O': - fmt += ' [' + argument_type.cfmt_str + ']' - args.append(arg_name) + fmt += ' [' + argument_type.cnativefmt_str + ']' + if argument_type.use_native_pointer: + args.append(arg_name + '_native_ptr') + else: + args.append(arg_name + '_native_obj') args = ', '.join(args) if args != '': args = ', ' + args @@ -278,8 +299,10 @@ class MethodDefinition: arg_complete_type = xml_method_arg.get('completetype') arg_contained_type = xml_method_arg.get('containedtype') argument_type = ArgumentType(arg_type, arg_complete_type, arg_contained_type, self.linphone_module) - if argument_type.convert_func is None: + if argument_type.fmt_str == 'O' and argument_type.use_native_pointer: arg_names.append(arg_name + "_native_ptr") + elif argument_type.fmt_str == 'O' and argument_type.convert_func is not None: + arg_names.append(arg_name + "_native_obj") else: arg_names.append(arg_name) if self.return_type != 'void': @@ -383,13 +406,22 @@ class MethodDefinition: arg_contained_type = xml_method_arg.get('containedtype') argument_type = ArgumentType(arg_type, arg_complete_type, arg_contained_type, self.linphone_module) if argument_type.fmt_str == 'O': - body += \ + if argument_type.use_native_pointer: + body += \ """ if (({arg_name} != Py_None) && !PyObject_IsInstance({arg_name}, (PyObject *)&pylinphone_{arg_type}Type)) {{ - PyErr_SetString(PyExc_TypeError, "The '{arg_name}' arguments must be a {type_str} instance."); + PyErr_SetString(PyExc_TypeError, "The '{arg_name}' argument must be a {type_str} instance."); return NULL; }} """.format(arg_name=arg_name, arg_type=strip_leading_linphone(arg_type), type_str=argument_type.type_str) - body = body[1:] # Remove leading '\t' + else: + body += \ +""" if (!{check_func}({arg_name})) {{ + PyErr_SetString(PyExc_TypeError, "The '{arg_name}' argument must be a {type_str} instance."); + return NULL; + }} +""".format(arg_name=arg_name, check_func=argument_type.check_func, type_str=argument_type.type_str) + if body != '': + body = body[1:] # Remove leading '\t' return body def format_args_native_pointer_check(self): @@ -400,7 +432,7 @@ class MethodDefinition: arg_complete_type = xml_method_arg.get('completetype') arg_contained_type = xml_method_arg.get('containedtype') argument_type = ArgumentType(arg_type, arg_complete_type, arg_contained_type, self.linphone_module) - if argument_type.fmt_str == 'O': + if argument_type.fmt_str == 'O' and argument_type.use_native_pointer: body += \ """ if (({arg_name} != NULL) && ({arg_name} != Py_None)) {{ if (({arg_name}_native_ptr = pylinphone_{arg_type}_get_native_ptr({arg_name})) == NULL) {{ @@ -408,7 +440,8 @@ class MethodDefinition: }} }} """.format(arg_name=arg_name, arg_type=strip_leading_linphone(arg_type)) - body = body[1:] # Remove leading '\t' + if body != '': + body = body[1:] # Remove leading '\t' return body def parse_method_node(self): @@ -572,14 +605,19 @@ class SetterMethodDefinition(MethodDefinition): return -1; }} """.format(checknotnone=checknotnone, checkfunc=self.first_argument_type.check_func, attribute_name=self.attribute_name, type_str=self.first_argument_type.type_str) - if self.first_argument_type.convert_func is None: - attribute_conversion_code = "{arg_name} = value;\n".format(arg_name="_" + self.first_arg_name) - else: + attribute_conversion_code = '' + if (self.first_argument_type.convert_func is None) or \ + (self.first_argument_type.fmt_str == 'O' and self.first_argument_type.convert_func is not None): + attribute_conversion_code += "{arg_name} = value;\n".format(arg_name="_" + self.first_arg_name) + if self.first_argument_type.convert_func is not None: cast_code = '' + suffix = '' if self.first_argument_type.cast_convert_func_result: cast_code = "({arg_type})".format(arg_type=self.first_arg_complete_type) - attribute_conversion_code = "{arg_name} = {cast_code}{convertfunc}(value);\n".format( - arg_name="_" + self.first_arg_name, cast_code=cast_code, convertfunc=self.first_argument_type.convert_func) + if self.first_argument_type.fmt_str == 'O' and self.first_argument_type.convert_func is not None: + suffix = '_native_obj' + attribute_conversion_code += "\t{arg_name}{suffix} = {cast_code}{convertfunc}(value);\n".format( + arg_name="_" + self.first_arg_name, suffix=suffix, cast_code=cast_code, convertfunc=self.first_argument_type.convert_func) attribute_native_ptr_check_code = '' if self.first_argument_type.use_native_pointer: attribute_native_ptr_check_code = \ @@ -606,13 +644,15 @@ class SetterMethodDefinition(MethodDefinition): attribute_native_ptr_check_code=attribute_native_ptr_check_code) def format_c_function_call(self): - use_native_ptr = '' - if self.first_argument_type.use_native_pointer: - use_native_ptr = '_native_ptr' + suffix = '' + if self.first_argument_type.fmt_str == 'O' and self.first_argument_type.use_native_pointer: + suffix = '_native_ptr' + elif self.first_argument_type.fmt_str == 'O' and self.first_argument_type.convert_func is not None: + suffix = '_native_obj' return \ -""" {method_name}(native_ptr, {arg_name}{use_native_ptr}); +""" {method_name}(native_ptr, {arg_name}{suffix}); pylinphone_dispatch_messages(); -""".format(arg_name="_" + self.first_arg_name, method_name=self.method_node.get('name'), use_native_ptr=use_native_ptr) +""".format(arg_name="_" + self.first_arg_name, method_name=self.method_node.get('name'), suffix=suffix) def format_return_trace(self): return "\tpylinphone_trace(-1, \"[PYLINPHONE] <<< %s -> 0\", __FUNCTION__);\n" diff --git a/tools/python/apixml2python/linphone_module.mustache b/tools/python/apixml2python/linphone_module.mustache index 62b626843..dcd0a7c3a 100644 --- a/tools/python/apixml2python/linphone_module.mustache +++ b/tools/python/apixml2python/linphone_module.mustache @@ -18,6 +18,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include #include +#include #include #include #include @@ -265,6 +266,7 @@ PyMODINIT_FUNC initlinphone(void) { PyObject *m; PyObject *menum; + PyDateTime_IMPORT; pylinphone_init_logging(); {{#classes}} From 0ac69b6969e2b7020c594437373f991dc918857f Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Mon, 18 Aug 2014 16:01:01 +0200 Subject: [PATCH 19/43] Update ms2 and oRTP submodules. --- mediastreamer2 | 2 +- oRTP | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mediastreamer2 b/mediastreamer2 index c82cc74f7..a1c7195ff 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit c82cc74f7341378ea3d21257448c427e4e7b91a1 +Subproject commit a1c7195ff8372ac1b77d71dce52c2d9da0173cc6 diff --git a/oRTP b/oRTP index 9d158c2da..b9534b1b2 160000 --- a/oRTP +++ b/oRTP @@ -1 +1 @@ -Subproject commit 9d158c2daf289bd826b855903e913786f90d5bad +Subproject commit b9534b1b2beb4bc549741e1f55a9c0bfe15d6c90 From 54c3f6efa9525151f06b26dc1dab7ae1a3cc8aa2 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Mon, 18 Aug 2014 16:12:05 +0200 Subject: [PATCH 20/43] Import linphone Python module with "import linphone". --- tools/python/linphone-daemon.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/python/linphone-daemon.py b/tools/python/linphone-daemon.py index 547aba918..a923c3ee9 100644 --- a/tools/python/linphone-daemon.py +++ b/tools/python/linphone-daemon.py @@ -3,7 +3,7 @@ import logging import sys import threading import time -from linphone import linphone +import linphone class Response: From e0675493479421d43b5ab62a7b5255ba9dfd4046 Mon Sep 17 00:00:00 2001 From: Guillaume BIENKOWSKI Date: Mon, 18 Aug 2014 17:01:59 +0200 Subject: [PATCH 21/43] Provide correct sample rate when G722 is involved --- coreapi/linphonecall.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 9d8b6060c..37a1079a3 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -236,6 +236,14 @@ static MSList *make_codec_list(LinphoneCore *lc, const MSList *codecs, int bandw for(it=codecs;it!=NULL;it=it->next){ PayloadType *pt=(PayloadType*)it->data; if (pt->flags & PAYLOAD_TYPE_ENABLED){ + int sample_rate = payload_type_get_rate(pt); + + if( strcasecmp("G722",pt->mime_type) == 0 ){ + /* G722 spec says 8000 but the codec actually requires 16000 */ + ms_debug("Correcting sample rate for G722"); + sample_rate = 16000; + } + if (bandwidth_limit>0 && !linphone_core_is_payload_type_usable_for_bandwidth(lc,pt,bandwidth_limit)){ ms_message("Codec %s/%i eliminated because of audio bandwidth constraint of %i kbit/s", pt->mime_type,pt->clock_rate,bandwidth_limit); @@ -244,7 +252,7 @@ static MSList *make_codec_list(LinphoneCore *lc, const MSList *codecs, int bandw if (linphone_core_check_payload_type_usability(lc,pt)){ l=ms_list_append(l,payload_type_clone(pt)); nb++; - if (max_sample_rate && payload_type_get_rate(pt)>*max_sample_rate) *max_sample_rate=payload_type_get_rate(pt); + if (max_sample_rate && sample_rate>*max_sample_rate) *max_sample_rate=sample_rate; } } if ((nb_codecs_limit > 0) && (nb >= nb_codecs_limit)) break; From 6ed82cb740677f08d1010c38fd44747b3dae9b93 Mon Sep 17 00:00:00 2001 From: Guillaume BIENKOWSKI Date: Mon, 18 Aug 2014 19:02:31 +0200 Subject: [PATCH 22/43] Add the equalizer location parameter to the "sound" section of lpconfig. Setting it to "mic" will place it in the input graph, rather than the default location in output graph. This allow to pre-amplify some frequencies in the input device. You still need to eq_active=1 and set eq_gains to what you want to amplify. --- coreapi/linphonecall.c | 7 +++++++ mediastreamer2 | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 37a1079a3..273990742 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -1710,6 +1710,13 @@ void linphone_call_init_audio_stream(LinphoneCall *call){ else if (strcasecmp(type,"full")==0) audio_stream_enable_echo_limiter(audiostream,ELControlFull); } + + /* equalizer location in the graph: 'mic' = in input graph, otherwise in output graph. + Any other value than mic will default to output graph for compatibility */ + const char *location = lp_config_get_string(lc->config,"sound","eq_location","hp"); + audiostream->eq_loc = (strcasecmp(location,"mic") == 0) ? MSEqualizerMic : MSEqualizerHP; + ms_error("Equalizer location: %s", location); + audio_stream_enable_gain_control(audiostream,TRUE); if (linphone_core_echo_cancellation_enabled(lc)){ int len,delay,framesize; diff --git a/mediastreamer2 b/mediastreamer2 index a1c7195ff..b1b9fc244 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit a1c7195ff8372ac1b77d71dce52c2d9da0173cc6 +Subproject commit b1b9fc244915ecccbba26db9440b077d5cafa85f From e745c956e7d8e4b68386c73fd8e0567df83a4688 Mon Sep 17 00:00:00 2001 From: Gautier Pelloux-Prayer Date: Tue, 19 Aug 2014 11:29:27 +0200 Subject: [PATCH 23/43] Add method to retrieve size of a conversation history and a part of it --- coreapi/linphonecore.h | 17 ++++- coreapi/linphonecore_jni.cc | 27 ++++++-- coreapi/message_storage.c | 55 +++++++++++++--- .../org/linphone/core/LinphoneChatRoom.java | 38 +++++++---- .../linphone/core/LinphoneChatRoomImpl.java | 54 ++++++++++----- tester/message_tester.c | 62 ++++++++++++++---- tester/messages.db | Bin 1821696 -> 3587072 bytes 7 files changed, 195 insertions(+), 58 deletions(-) diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index 7147f30e7..5c6ee82b5 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -1347,9 +1347,24 @@ LINPHONE_PUBLIC MSList *linphone_chat_room_get_history(LinphoneChatRoom *cr,int LINPHONE_PUBLIC void linphone_chat_room_mark_as_read(LinphoneChatRoom *cr); LINPHONE_PUBLIC void linphone_chat_room_delete_message(LinphoneChatRoom *cr, LinphoneChatMessage *msg); LINPHONE_PUBLIC void linphone_chat_room_delete_history(LinphoneChatRoom *cr); +/** + * Gets the number of messages in a chat room. + * @param[in] cr The #LinphoneChatRoom object corresponding to the conversation for which size has to be computed + * @return the number of messages. + */ +LINPHONE_PUBLIC int linphone_chat_room_get_history_size(LinphoneChatRoom *cr); /** - * Notify the destination of the chat message being composed that the user is typing a new message. + * Gets the partial list of messages in the given range, sorted from most recent to oldest. + * @param[in] cr The #LinphoneChatRoom object corresponding to the conversation for which messages should be retrieved + * @param[in] begin The first message of the range to be retrieved. History most recent message has index 0. + * @param[in] end The last message of the range to be retrieved. History oldest message has index of history size - 1 (use #linphone_chat_room_get_history_size to retrieve history size) + * @return the list of messages in the given range, or NULL if nothing has been found. + */ +LINPHONE_PUBLIC MSList *linphone_chat_room_get_history_range(LinphoneChatRoom *cr, int begin, int end); + +/** + * Notifies the destination of the chat message being composed that the user is typing a new message. * @param[in] cr The #LinphoneChatRoom object corresponding to the conversation for which a new message is being typed. */ LINPHONE_PUBLIC void linphone_chat_room_compose(LinphoneChatRoom *cr); diff --git a/coreapi/linphonecore_jni.cc b/coreapi/linphonecore_jni.cc index 92c253288..dfe90f7d5 100644 --- a/coreapi/linphonecore_jni.cc +++ b/coreapi/linphonecore_jni.cc @@ -2425,12 +2425,11 @@ extern "C" jlong Java_org_linphone_core_LinphoneCoreImpl_getFriendByAddress(JNIE env->ReleaseStringUTFChars(jaddress, address); return (jlong) lf; } -//LinphoneChatRoom -extern "C" jlongArray Java_org_linphone_core_LinphoneChatRoomImpl_getHistory(JNIEnv* env + +extern "C" jlongArray _LinphoneChatRoomImpl_getHistory(JNIEnv* env ,jobject thiz ,jlong ptr - ,jint limit) { - MSList* history = linphone_chat_room_get_history((LinphoneChatRoom*)ptr, limit); + ,MSList* history) { int historySize = ms_list_size(history); jlongArray jHistory = env->NewLongArray(historySize); jlong *jInternalArray = env->GetLongArrayElements(jHistory, NULL); @@ -2446,6 +2445,21 @@ extern "C" jlongArray Java_org_linphone_core_LinphoneChatRoomImpl_getHistory(JNI return jHistory; } +extern "C" jlongArray Java_org_linphone_core_LinphoneChatRoomImpl_getHistoryRange(JNIEnv* env + ,jobject thiz + ,jlong ptr + ,jint start + ,jint end) { + MSList* history = linphone_chat_room_get_history_range((LinphoneChatRoom*)ptr, start, end); + return _LinphoneChatRoomImpl_getHistory(env, thiz, ptr, history); +} +extern "C" jlongArray Java_org_linphone_core_LinphoneChatRoomImpl_getHistory(JNIEnv* env + ,jobject thiz + ,jlong ptr + ,jint limit) { + MSList* history = linphone_chat_room_get_history((LinphoneChatRoom*)ptr, limit); + return _LinphoneChatRoomImpl_getHistory(env, thiz, ptr, history); +} extern "C" jlong Java_org_linphone_core_LinphoneChatRoomImpl_getPeerAddress(JNIEnv* env ,jobject thiz ,jlong ptr) { @@ -2484,6 +2498,11 @@ extern "C" jlong Java_org_linphone_core_LinphoneChatRoomImpl_createLinphoneChatM return (jlong) chatMessage; } +extern "C" jint Java_org_linphone_core_LinphoneChatRoomImpl_getHistorySize (JNIEnv* env + ,jobject thiz + ,jlong ptr) { + return (jint) linphone_chat_room_get_history_size((LinphoneChatRoom*)ptr); +} extern "C" jint Java_org_linphone_core_LinphoneChatRoomImpl_getUnreadMessagesCount(JNIEnv* env ,jobject thiz ,jlong ptr) { diff --git a/coreapi/message_storage.c b/coreapi/message_storage.c index d2f83b12a..89120aee3 100644 --- a/coreapi/message_storage.c +++ b/coreapi/message_storage.c @@ -217,14 +217,14 @@ void linphone_chat_room_update_url(LinphoneChatRoom *cr, LinphoneChatMessage *ms sqlite3_free(buf); } -int linphone_chat_room_get_unread_messages_count(LinphoneChatRoom *cr){ +static int linphone_chat_room_get_messages_count(LinphoneChatRoom *cr, bool_t unread_only){ LinphoneCore *lc=linphone_chat_room_get_lc(cr); int numrows=0; if (lc->db==NULL) return 0; char *peer=linphone_address_as_string_uri_only(linphone_chat_room_get_peer_address(cr)); - char *buf=sqlite3_mprintf("SELECT count(*) FROM history WHERE remoteContact = %Q AND read = 0;",peer); + char *buf=sqlite3_mprintf("SELECT count(*) FROM history WHERE remoteContact = %Q %s;",peer,unread_only?"AND read = 0":""); sqlite3_stmt *selectStatement; int returnValue = sqlite3_prepare_v2(lc->db,buf,-1,&selectStatement,NULL); if (returnValue == SQLITE_OK){ @@ -238,6 +238,14 @@ int linphone_chat_room_get_unread_messages_count(LinphoneChatRoom *cr){ return numrows; } +int linphone_chat_room_get_unread_messages_count(LinphoneChatRoom *cr){ + return linphone_chat_room_get_messages_count(cr, TRUE); +} + +int linphone_chat_room_get_history_size(LinphoneChatRoom *cr){ + return linphone_chat_room_get_messages_count(cr, FALSE); +} + void linphone_chat_room_delete_message(LinphoneChatRoom *cr, LinphoneChatMessage *msg) { LinphoneCore *lc=cr->lc; @@ -260,31 +268,50 @@ void linphone_chat_room_delete_history(LinphoneChatRoom *cr){ ms_free(peer); } -MSList *linphone_chat_room_get_history(LinphoneChatRoom *cr,int nb_message){ +MSList *linphone_chat_room_get_history_range(LinphoneChatRoom *cr, int startm, int endm){ LinphoneCore *lc=linphone_chat_room_get_lc(cr); MSList *ret; char *buf; char *peer; uint64_t begin,end; + int buf_max_size = 512; if (lc->db==NULL) return NULL; - peer=linphone_address_as_string_uri_only(linphone_chat_room_get_peer_address(cr)); + peer = linphone_address_as_string_uri_only(linphone_chat_room_get_peer_address(cr)); + cr->messages_hist = NULL; - if (nb_message > 0) - buf=sqlite3_mprintf("SELECT * FROM history WHERE remoteContact = %Q ORDER BY id DESC LIMIT %i ;",peer,nb_message); - else - buf=sqlite3_mprintf("SELECT * FROM history WHERE remoteContact = %Q ORDER BY id DESC;",peer); + + /*since we want to append query parameters depending on arguments given, we use malloc instead of sqlite3_mprintf*/ + buf=ms_malloc(buf_max_size); + buf=sqlite3_snprintf(buf_max_size-1,buf,"SELECT * FROM history WHERE remoteContact = %Q ORDER BY id DESC",peer); + + if (endm>0&&endm>=startm){ + buf=sqlite3_snprintf(buf_max_size-1,buf,"%s LIMIT %i ",buf,endm+1-startm); + }else if(startm>0){ + ms_message("%s(): end is lower than start (%d < %d). No end assumed.",__FUNCTION__,endm,startm); + buf=sqlite3_snprintf(buf_max_size-1,buf,"%s LIMIT -1",buf); + } + + if (startm>0){ + buf=sqlite3_snprintf(buf_max_size-1,buf,"%s OFFSET %i ",buf,startm); + } + begin=ortp_get_cur_time_ms(); linphone_sql_request_message(lc->db,buf,cr); end=ortp_get_cur_time_ms(); - ms_message("linphone_chat_room_get_history(): completed in %i ms",(int)(end-begin)); - sqlite3_free(buf); + ms_message("%s(): completed in %i ms",__FUNCTION__, (int)(end-begin)); + ms_free(buf); ret=cr->messages_hist; cr->messages_hist=NULL; ms_free(peer); return ret; } +MSList *linphone_chat_room_get_history(LinphoneChatRoom *cr,int nb_message){ + return linphone_chat_room_get_history_range(cr, 0, nb_message); +} + + void linphone_close_storage(sqlite3* db){ sqlite3_close(db); } @@ -484,6 +511,10 @@ MSList *linphone_chat_room_get_history(LinphoneChatRoom *cr,int nb_message){ return NULL; } +LINPHONE_PUBLIC MSList *linphone_chat_room_get_history_range(LinphoneChatRoom *cr, int begin, int end){ + return NULL; +} + void linphone_chat_room_delete_message(LinphoneChatRoom *cr, LinphoneChatMessage *msg) { } @@ -506,4 +537,8 @@ int linphone_chat_room_get_unread_messages_count(LinphoneChatRoom *cr){ return 0; } +int linphone_chat_room_get_history_size(LinphoneChatRoom *cr){ + return 0; +} + #endif diff --git a/java/common/org/linphone/core/LinphoneChatRoom.java b/java/common/org/linphone/core/LinphoneChatRoom.java index c1e635c0a..0d677760c 100644 --- a/java/common/org/linphone/core/LinphoneChatRoom.java +++ b/java/common/org/linphone/core/LinphoneChatRoom.java @@ -21,8 +21,8 @@ package org.linphone.core; import org.linphone.core.LinphoneChatMessage.State; /** - * - * A chat room is the place where text messages are exchanged. + * + * A chat room is the place where text messages are exchanged. Can be created by linphone_core_create_chat_room(). * */ @@ -43,7 +43,7 @@ public interface LinphoneChatRoom { * @param chat message */ void sendMessage(LinphoneChatMessage message, LinphoneChatMessage.StateListener listener); - + /** * Create a LinphoneChatMessage * @param chatRoom chat room associated to the message @@ -51,31 +51,45 @@ public interface LinphoneChatRoom { * @return LinphoneChatMessage object */ LinphoneChatMessage createLinphoneChatMessage(String message); - + /** * Returns the chat history associated with the peer address associated with this chat room * @return an array of LinphoneChatMessage */ LinphoneChatMessage[] getHistory(); - + /** * Returns the chat history associated with the peer address associated with this chat room * @param limit the maximum number of messages to fetch * @return an array of LinphoneChatMessage */ LinphoneChatMessage[] getHistory(int limit); - + + /** + * Returns the chat history associated with the peer address associated with this chat room for the given range + * @param begin the first (most recent) message to retrieve. Newest message has index 0. If negative, use value 0 instead. + * @param end the last (oldest) message to retrieve. Oldest message has value "history size" - 1 (equivalent to -1). If negative or lower than begin value, value is given, use -1. + * @return an array of LinphoneChatMessage, empty if nothing has been found + */ + LinphoneChatMessage[] getHistoryRange(int begin, int end); + /** * Destroys a LinphoneChatRoom. */ void destroy(); - + /** * Returns the amount of unread messages associated with the peer of this chatRoom. * @return the amount of unread messages */ int getUnreadMessagesCount(); - + + /** + * Returns the amount of messages associated with the peer of this chatRoom. + * @return the amount of messages in the conversation + */ + int getHistorySize(); + /** * Deletes all the messages associated with the peer of this chat room */ @@ -91,24 +105,24 @@ public interface LinphoneChatRoom { * @return true if the remote is currently composing a message, false otherwise. */ boolean isRemoteComposing(); - + /** * Marks all the messages in this conversation as read */ void markAsRead(); - + /** * Deletes a message * @param message the message to delete */ void deleteMessage(LinphoneChatMessage message); - + /** * Update the value stored in the database for the external_body_url field * @param message to update */ void updateUrl(LinphoneChatMessage message); - + /** * Create a LinphoneChatMessage * @return LinphoneChatMessage object diff --git a/java/impl/org/linphone/core/LinphoneChatRoomImpl.java b/java/impl/org/linphone/core/LinphoneChatRoomImpl.java index b33f5db4b..5ca8e5628 100644 --- a/java/impl/org/linphone/core/LinphoneChatRoomImpl.java +++ b/java/impl/org/linphone/core/LinphoneChatRoomImpl.java @@ -27,9 +27,11 @@ class LinphoneChatRoomImpl implements LinphoneChatRoom { private native long getPeerAddress(long ptr); private native void sendMessage(long ptr, String message); private native void sendMessage2(long ptr, Object msg, long messagePtr, StateListener listener); + private native long[] getHistoryRange(long ptr, int begin, int end); private native long[] getHistory(long ptr, int limit); private native void destroy(long ptr); private native int getUnreadMessagesCount(long ptr); + private native int getHistorySize(long ptr); private native void deleteHistory(long ptr); private native void compose(long ptr); private native boolean isRemoteComposing(long ptr); @@ -53,7 +55,7 @@ class LinphoneChatRoomImpl implements LinphoneChatRoom { sendMessage(nativePtr,message); } } - + @Override public void sendMessage(LinphoneChatMessage message, StateListener listener) { synchronized(getCore()){ @@ -67,37 +69,43 @@ class LinphoneChatRoomImpl implements LinphoneChatRoom { return new LinphoneChatMessageImpl(createLinphoneChatMessage(nativePtr, message)); } } - + public LinphoneChatMessage[] getHistory() { synchronized(getCore()){ return getHistory(0); } } - + + public LinphoneChatMessage[] getHistoryRange(int begin, int end) { + synchronized(getCore()){ + long[] typesPtr = getHistoryRange(nativePtr, begin, end); + return getHistoryPrivate(typesPtr); + } + } + public LinphoneChatMessage[] getHistory(int limit) { synchronized(getCore()){ long[] typesPtr = getHistory(nativePtr, limit); - if (typesPtr == null) return null; - - LinphoneChatMessage[] messages = new LinphoneChatMessage[typesPtr.length]; - for (int i=0; i < messages.length; i++) { - messages[i] = new LinphoneChatMessageImpl(typesPtr[i]); - } - - return messages; + return getHistoryPrivate(typesPtr); } } - + public void destroy() { destroy(nativePtr); } - + public int getUnreadMessagesCount() { synchronized(getCore()){ return getUnreadMessagesCount(nativePtr); } } - + + public int getHistorySize() { + synchronized(getCore()){ + return getHistorySize(nativePtr); + } + } + public void deleteHistory() { synchronized(getCore()){ deleteHistory(nativePtr); @@ -115,27 +123,27 @@ class LinphoneChatRoomImpl implements LinphoneChatRoom { return isRemoteComposing(nativePtr); } } - + public void markAsRead() { synchronized(getCore()){ markAsRead(nativePtr); } } - + public void deleteMessage(LinphoneChatMessage message) { synchronized(getCore()){ if (message != null) deleteMessage(nativePtr, ((LinphoneChatMessageImpl)message).getNativePtr()); } } - + public void updateUrl(LinphoneChatMessage message) { synchronized(getCore()){ if (message != null) updateUrl(nativePtr, ((LinphoneChatMessageImpl)message).getNativePtr()); } } - + @Override public LinphoneChatMessage createLinphoneChatMessage(String message, String url, State state, long timestamp, boolean isRead, @@ -150,4 +158,14 @@ class LinphoneChatRoomImpl implements LinphoneChatRoom { public synchronized LinphoneCore getCore() { return (LinphoneCore)getCore(nativePtr); } + private LinphoneChatMessage[] getHistoryPrivate(long[] typesPtr) { + if (typesPtr == null) return null; + + LinphoneChatMessage[] messages = new LinphoneChatMessage[typesPtr.length]; + for (int i=0; i < messages.length; i++) { + messages[i] = new LinphoneChatMessageImpl(typesPtr[i]); + } + + return messages; + } } diff --git a/tester/message_tester.c b/tester/message_tester.c index d71f2db53..d8bd79174 100644 --- a/tester/message_tester.c +++ b/tester/message_tester.c @@ -754,12 +754,11 @@ static void is_composing_notification(void) { /* * Copy file "from" to file "to". * Destination file is truncated if existing. - * Return 1 on success, 0 on error (printing an error). + * Return 0 on success, positive value on error. */ static int message_tester_copy_file(const char *from, const char *to) { - char message[256]; FILE *in, *out; char buf[256]; size_t n; @@ -768,21 +767,17 @@ message_tester_copy_file(const char *from, const char *to) in=fopen(from, "r"); if ( in == NULL ) { - snprintf(message, 255, "Can't open %s for reading: %s\n", - from, strerror(errno)); - fprintf(stderr, "%s", message); - return 0; + ms_error("Can't open %s for reading: %s\n",from,strerror(errno)); + return 1; } /* Open "to" file for writing (will truncate existing files) */ out=fopen(to, "w"); if ( out == NULL ) { - snprintf(message, 255, "Can't open %s for writing: %s\n", - to, strerror(errno)); - fprintf(stderr, "%s", message); + ms_error("Can't open %s for writing: %s\n",to,strerror(errno)); fclose(in); - return 0; + return 2; } /* Copy data from "in" to "out" */ @@ -790,16 +785,17 @@ message_tester_copy_file(const char *from, const char *to) { if ( ! fwrite(buf, 1, n, out) ) { + ms_error("Could not write in %s: %s\n",to,strerror(errno)); fclose(in); fclose(out); - return 0; + return 3; } } fclose(in); fclose(out); - return 1; + return 0; } static int check_no_strange_time(void* data,int argc, char** argv,char** cNames) { @@ -814,7 +810,7 @@ static void message_storage_migration() { snprintf(src_db,sizeof(src_db), "%s/messages.db", liblinphone_tester_file_prefix); snprintf(tmp_db,sizeof(tmp_db), "%s/tmp.db", liblinphone_tester_writable_dir_prefix); - CU_ASSERT_EQUAL_FATAL(message_tester_copy_file(src_db, tmp_db), 1); + CU_ASSERT_EQUAL_FATAL(message_tester_copy_file(src_db, tmp_db), 0); // enable to test the performances of the migration step //linphone_core_message_storage_set_debug(marie->lc, TRUE); @@ -830,6 +826,45 @@ static void message_storage_migration() { CU_ASSERT(sqlite3_exec(marie->lc->db, "SELECT * FROM history WHERE time != '-1';", check_no_strange_time, NULL, NULL) == SQLITE_OK ); } +static void history_messages_count() { + LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc"); + LinphoneAddress *jehan_addr = linphone_address_new(""); + LinphoneChatRoom *chatroom; + MSList *messages; + char src_db[256]; + char tmp_db[256]; + snprintf(src_db,sizeof(src_db), "%s/messages.db", liblinphone_tester_file_prefix); + snprintf(tmp_db,sizeof(tmp_db), "%s/tmp.db", liblinphone_tester_writable_dir_prefix); + + CU_ASSERT_EQUAL_FATAL(message_tester_copy_file(src_db, tmp_db), 0); + + linphone_core_set_chat_database_path(marie->lc, tmp_db); + + chatroom = linphone_core_get_chat_room(marie->lc, jehan_addr); + CU_ASSERT_PTR_NOT_NULL(chatroom); + if (chatroom){ + MSList *history=linphone_chat_room_get_history(chatroom,0); + CU_ASSERT_EQUAL(linphone_chat_room_get_history_size(chatroom), 1270); + CU_ASSERT_EQUAL(ms_list_size(history), linphone_chat_room_get_history_size(chatroom)); + /*check the second most recent message*/ + CU_ASSERT_STRING_EQUAL(linphone_chat_message_get_text((LinphoneChatMessage *)history->next->data), "Fore and aft follow each other."); + + /*test offset+limit: retrieve the 42th latest message only and check its content*/ + messages=linphone_chat_room_get_history_range(chatroom, 42, 42); + CU_ASSERT_EQUAL(ms_list_size(messages), 1); + CU_ASSERT_STRING_EQUAL(linphone_chat_message_get_text((LinphoneChatMessage *)messages->data), "If you open yourself to the Tao is intangible and evasive, yet prefers to keep us at the mercy of the kingdom, then all of the streams of hundreds of valleys because of its limitless possibilities."); + + /*test offset without limit*/ + CU_ASSERT_EQUAL(ms_list_size(linphone_chat_room_get_history_range(chatroom, 1265, -1)), 1270-1265); + + /*test limit without offset*/ + CU_ASSERT_EQUAL(ms_list_size(linphone_chat_room_get_history_range(chatroom, 0, 5)), 6); + } + linphone_core_manager_destroy(marie); + linphone_address_destroy(jehan_addr); +} + + #endif test_t message_tests[] = { @@ -852,6 +887,7 @@ test_t message_tests[] = { { "IsComposing notification", is_composing_notification } #ifdef MSG_STORAGE_ENABLED ,{ "Database migration", message_storage_migration } + ,{ "History count", history_messages_count } #endif }; diff --git a/tester/messages.db b/tester/messages.db index 072aed397b2422206d0e6d819e2860e4aade95af..30fd10efb16cfa781f99d5fc3dd789a70b67547f 100644 GIT binary patch delta 662851 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
    X=Z=XGL{E=rTvSjZI?KD#X5BKTYgnE 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�(TxnU(zwe!ie? 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�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 G7JmU^M7fgy From 8d442bf774e0beb98d59d34e00c7b78f052eb8ee Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Tue, 19 Aug 2014 12:17:00 +0200 Subject: [PATCH 24/43] Fix bug 0001406: Missing crypto keys when adding video in an SAVP call. --- coreapi/linphonecall.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 273990742..6e652c477 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -313,7 +313,7 @@ static void setup_encryption_keys(LinphoneCall *call, SalMediaDescription *md){ for(i=0; inb_streams; i++) { if (!sal_stream_description_active(&md->streams[i])) continue; if (sal_stream_description_has_srtp(&md->streams[i]) == TRUE) { - if (keep_srtp_keys && old_md && sal_stream_description_has_srtp(&old_md->streams[i]) == TRUE){ + if (keep_srtp_keys && old_md && (sal_stream_description_active(&old_md->streams[i]) == TRUE) && (sal_stream_description_has_srtp(&old_md->streams[i]) == TRUE)) { int j; ms_message("Keeping same crypto keys."); for(j=0;j Date: Tue, 19 Aug 2014 12:25:49 +0200 Subject: [PATCH 25/43] Update ms2 --- mediastreamer2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediastreamer2 b/mediastreamer2 index b1b9fc244..d6b60a173 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit b1b9fc244915ecccbba26db9440b077d5cafa85f +Subproject commit d6b60a173628b12c9ab88c07c94c5b51b3ebbadd From ead5352fd8af820bfe46e5abfa9dddfcda62eac5 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Tue, 19 Aug 2014 12:56:43 +0200 Subject: [PATCH 26/43] Add unit tests for calls with several video switches. --- tester/call_tester.c | 90 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 89 insertions(+), 1 deletion(-) diff --git a/tester/call_tester.c b/tester/call_tester.c index a64193a3d..7e6d9f88e 100644 --- a/tester/call_tester.c +++ b/tester/call_tester.c @@ -26,6 +26,7 @@ #include "private.h" #include "liblinphone_tester.h" +static void srtp_call(void); static void call_base(LinphoneMediaEncryption mode, bool_t enable_video,bool_t enable_relay,LinphoneFirewallPolicy policy); static void disable_all_audio_codecs_except_one(LinphoneCore *lc, const char *mime); @@ -1142,7 +1143,42 @@ static bool_t add_video(LinphoneCoreManager* caller,LinphoneCoreManager* callee) /*send vfu*/ linphone_call_send_vfu_request(call_obj); return wait_for(caller->lc,callee->lc,&callee->stat.number_of_IframeDecoded,initial_callee_stat.number_of_IframeDecoded+1); - } else return 0; + } + return FALSE; +} + +static bool_t remove_video(LinphoneCoreManager *caller, LinphoneCoreManager *callee) { + LinphoneCallParams *callee_params; + LinphoneCall *call_obj; + stats initial_caller_stat = caller->stat; + stats initial_callee_stat = callee->stat; + + if (!linphone_core_get_current_call(callee->lc) + || (linphone_call_get_state(linphone_core_get_current_call(callee->lc)) != LinphoneCallStreamsRunning) + || !linphone_core_get_current_call(caller->lc) + || (linphone_call_get_state(linphone_core_get_current_call(caller->lc)) != LinphoneCallStreamsRunning)) { + ms_warning("bad state for removing video"); + return FALSE; + } + + if ((call_obj = linphone_core_get_current_call(callee->lc))) { + callee_params = linphone_call_params_copy(linphone_call_get_current_params(call_obj)); + + /* Remove video. */ + linphone_call_params_enable_video(callee_params, FALSE); + linphone_core_update_call(callee->lc, call_obj, callee_params); + + CU_ASSERT_TRUE(wait_for(caller->lc, callee->lc, &caller->stat.number_of_LinphoneCallUpdatedByRemote, initial_caller_stat.number_of_LinphoneCallUpdatedByRemote + 1)); + CU_ASSERT_TRUE(wait_for(caller->lc, callee->lc, &callee->stat.number_of_LinphoneCallUpdating, initial_callee_stat.number_of_LinphoneCallUpdating + 1)); + CU_ASSERT_TRUE(wait_for(caller->lc, callee->lc, &callee->stat.number_of_LinphoneCallStreamsRunning, initial_callee_stat.number_of_LinphoneCallStreamsRunning + 1)); + CU_ASSERT_TRUE(wait_for(caller->lc, callee->lc, &caller->stat.number_of_LinphoneCallStreamsRunning, initial_caller_stat.number_of_LinphoneCallStreamsRunning + 1)); + + CU_ASSERT_FALSE(linphone_call_params_video_enabled(linphone_call_get_current_params(linphone_core_get_current_call(callee->lc)))); + CU_ASSERT_FALSE(linphone_call_params_video_enabled(linphone_call_get_current_params(linphone_core_get_current_call(caller->lc)))); + + return TRUE; + } + return FALSE; } static void call_with_video_added(void) { @@ -1181,6 +1217,56 @@ static void call_with_video_added_random_ports(void) { linphone_core_manager_destroy(pauline); } +static void call_with_several_video_switches(void) { + int dummy = 0; + LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + CU_ASSERT_TRUE(call(pauline,marie)); + + CU_ASSERT_TRUE(add_video(pauline,marie)); + wait_for_until(pauline->lc,marie->lc,&dummy,1,1000); /* Wait for VFU request exchanges to be finished. */ + CU_ASSERT_TRUE(remove_video(pauline,marie)); + CU_ASSERT_TRUE(add_video(pauline,marie)); + wait_for_until(pauline->lc,marie->lc,&dummy,1,1000); /* Wait for VFU request exchanges to be finished. */ + CU_ASSERT_TRUE(remove_video(pauline,marie)); + /*just to sleep*/ + linphone_core_terminate_all_calls(pauline->lc); + CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallEnd,1)); + CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallEnd,1)); + + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); +} + +static void srtp_call_with_several_video_switches(void) { + int dummy = 0; + LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + + if (linphone_core_media_encryption_supported(marie->lc, LinphoneMediaEncryptionSRTP)) { + linphone_core_set_media_encryption(marie->lc, LinphoneMediaEncryptionSRTP); + linphone_core_set_media_encryption(pauline->lc, LinphoneMediaEncryptionSRTP); + + CU_ASSERT_TRUE(call(pauline,marie)); + + CU_ASSERT_TRUE(add_video(pauline,marie)); + wait_for_until(pauline->lc,marie->lc,&dummy,1,1000); /* Wait for VFU request exchanges to be finished. */ + CU_ASSERT_TRUE(remove_video(pauline,marie)); + CU_ASSERT_TRUE(add_video(pauline,marie)); + wait_for_until(pauline->lc,marie->lc,&dummy,1,1000); /* Wait for VFU request exchanges to be finished. */ + CU_ASSERT_TRUE(remove_video(pauline,marie)); + /*just to sleep*/ + linphone_core_terminate_all_calls(pauline->lc); + CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallEnd,1)); + CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallEnd,1)); + } else { + ms_warning("Not tested because SRTP is not available."); + } + + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); +} + static void call_with_declined_video_base(bool_t using_policy) { LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); @@ -2785,6 +2871,8 @@ test_t call_tests[] = { { "ZRTP ice video call", zrtp_video_ice_call }, { "Call with video added", call_with_video_added }, { "Call with video added (random ports)", call_with_video_added_random_ports }, + { "Call with several video switches", call_with_several_video_switches }, + { "SRTP call with several video switches", srtp_call_with_several_video_switches }, { "Call with video declined", call_with_declined_video}, { "Call with video declined using policy", call_with_declined_video_using_policy}, { "Call with multiple early media", multiple_early_media }, From 94d0b2dc7b8710a63db2ea09784185bdd990f22f Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Tue, 19 Aug 2014 14:45:00 +0200 Subject: [PATCH 27/43] Fix compilation with Visual Studio. --- coreapi/linphonecall.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 6e652c477..364471490 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -1687,6 +1687,7 @@ int linphone_call_prepare_ice(LinphoneCall *call, bool_t incoming_offer){ void linphone_call_init_audio_stream(LinphoneCall *call){ LinphoneCore *lc=call->core; AudioStream *audiostream; + const char *location; int dscp; if (call->audiostream != NULL) return; @@ -1713,7 +1714,7 @@ void linphone_call_init_audio_stream(LinphoneCall *call){ /* equalizer location in the graph: 'mic' = in input graph, otherwise in output graph. Any other value than mic will default to output graph for compatibility */ - const char *location = lp_config_get_string(lc->config,"sound","eq_location","hp"); + location = lp_config_get_string(lc->config,"sound","eq_location","hp"); audiostream->eq_loc = (strcasecmp(location,"mic") == 0) ? MSEqualizerMic : MSEqualizerHP; ms_error("Equalizer location: %s", location); From da96438eb7b40fc24d58b3994305e5a44ad55f10 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Tue, 19 Aug 2014 14:45:18 +0200 Subject: [PATCH 28/43] Fix documentation for automatic wrapper generation. --- coreapi/linphonecore.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index 5c6ee82b5..ec96715af 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -1359,7 +1359,7 @@ LINPHONE_PUBLIC int linphone_chat_room_get_history_size(LinphoneChatRoom *cr); * @param[in] cr The #LinphoneChatRoom object corresponding to the conversation for which messages should be retrieved * @param[in] begin The first message of the range to be retrieved. History most recent message has index 0. * @param[in] end The last message of the range to be retrieved. History oldest message has index of history size - 1 (use #linphone_chat_room_get_history_size to retrieve history size) - * @return the list of messages in the given range, or NULL if nothing has been found. + * @return \mslist{LinphoneChatMessage} */ LINPHONE_PUBLIC MSList *linphone_chat_room_get_history_range(LinphoneChatRoom *cr, int begin, int end); From c53f70e256c464fef9dc3eea88583ffdc069fc10 Mon Sep 17 00:00:00 2001 From: Gautier Pelloux-Prayer Date: Tue, 19 Aug 2014 15:06:38 +0200 Subject: [PATCH 29/43] Fix erroneous documentation from conversation history new methods --- coreapi/linphonecore.h | 2 +- coreapi/message_storage.c | 8 +++++--- java/common/org/linphone/core/LinphoneChatRoom.java | 2 +- tester/message_tester.c | 7 +++++++ 4 files changed, 14 insertions(+), 5 deletions(-) diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index ec96715af..773701d52 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -1355,7 +1355,7 @@ LINPHONE_PUBLIC void linphone_chat_room_delete_history(LinphoneChatRoom *cr); LINPHONE_PUBLIC int linphone_chat_room_get_history_size(LinphoneChatRoom *cr); /** - * Gets the partial list of messages in the given range, sorted from most recent to oldest. + * Gets the partial list of messages in the given range, sorted from oldest to most recent. * @param[in] cr The #LinphoneChatRoom object corresponding to the conversation for which messages should be retrieved * @param[in] begin The first message of the range to be retrieved. History most recent message has index 0. * @param[in] end The last message of the range to be retrieved. History oldest message has index of history size - 1 (use #linphone_chat_room_get_history_size to retrieve history size) diff --git a/coreapi/message_storage.c b/coreapi/message_storage.c index 89120aee3..adba8f00e 100644 --- a/coreapi/message_storage.c +++ b/coreapi/message_storage.c @@ -112,7 +112,7 @@ void linphone_sql_request_message(sqlite3 *db,const char *stmt,LinphoneChatRoom int ret; ret=sqlite3_exec(db,stmt,callback,cr,&errmsg); if(ret != SQLITE_OK) { - ms_error("Error in creation: %s.\n", errmsg); + ms_error("Error in creation: %s.", errmsg); sqlite3_free(errmsg); } } @@ -122,7 +122,7 @@ int linphone_sql_request(sqlite3* db,const char *stmt){ int ret; ret=sqlite3_exec(db,stmt,NULL,NULL,&errmsg); if(ret != SQLITE_OK) { - ms_error("linphone_sql_request: error sqlite3_exec(): %s.\n", errmsg); + ms_error("linphone_sql_request: error sqlite3_exec(): %s.", errmsg); sqlite3_free(errmsg); } return ret; @@ -134,7 +134,7 @@ void linphone_sql_request_all(sqlite3* db,const char *stmt, LinphoneCore* lc){ int ret; ret=sqlite3_exec(db,stmt,callback_all,lc,&errmsg); if(ret != SQLITE_OK) { - ms_error("linphone_sql_request_all: error sqlite3_exec(): %s.\n", errmsg); + ms_error("linphone_sql_request_all: error sqlite3_exec(): %s.", errmsg); sqlite3_free(errmsg); } } @@ -285,6 +285,8 @@ MSList *linphone_chat_room_get_history_range(LinphoneChatRoom *cr, int startm, i buf=ms_malloc(buf_max_size); buf=sqlite3_snprintf(buf_max_size-1,buf,"SELECT * FROM history WHERE remoteContact = %Q ORDER BY id DESC",peer); + if (startm<0) startm=0; + if (endm>0&&endm>=startm){ buf=sqlite3_snprintf(buf_max_size-1,buf,"%s LIMIT %i ",buf,endm+1-startm); }else if(startm>0){ diff --git a/java/common/org/linphone/core/LinphoneChatRoom.java b/java/common/org/linphone/core/LinphoneChatRoom.java index 0d677760c..722073779 100644 --- a/java/common/org/linphone/core/LinphoneChatRoom.java +++ b/java/common/org/linphone/core/LinphoneChatRoom.java @@ -66,7 +66,7 @@ public interface LinphoneChatRoom { LinphoneChatMessage[] getHistory(int limit); /** - * Returns the chat history associated with the peer address associated with this chat room for the given range + * Returns the chat history associated with the peer address associated with this chat room for the given range, sorted from oldest to most recent * @param begin the first (most recent) message to retrieve. Newest message has index 0. If negative, use value 0 instead. * @param end the last (oldest) message to retrieve. Oldest message has value "history size" - 1 (equivalent to -1). If negative or lower than begin value, value is given, use -1. * @return an array of LinphoneChatMessage, empty if nothing has been found diff --git a/tester/message_tester.c b/tester/message_tester.c index d8bd79174..9a0a21b6c 100644 --- a/tester/message_tester.c +++ b/tester/message_tester.c @@ -824,6 +824,9 @@ static void message_storage_migration() { // check that all messages have been migrated to the UTC time storage CU_ASSERT(sqlite3_exec(marie->lc->db, "SELECT * FROM history WHERE time != '-1';", check_no_strange_time, NULL, NULL) == SQLITE_OK ); + + linphone_core_manager_destroy(marie); + remove(tmp_db); } static void history_messages_count() { @@ -859,9 +862,13 @@ static void history_messages_count() { /*test limit without offset*/ CU_ASSERT_EQUAL(ms_list_size(linphone_chat_room_get_history_range(chatroom, 0, 5)), 6); + + /*test invalid start*/ + CU_ASSERT_EQUAL(ms_list_size(linphone_chat_room_get_history_range(chatroom, 1265, 1260)), 1270-1265); } linphone_core_manager_destroy(marie); linphone_address_destroy(jehan_addr); + remove(tmp_db); } From 031f3351356450b46cbbeaa28e42a9ccfa749fcc Mon Sep 17 00:00:00 2001 From: Guillaume BIENKOWSKI Date: Tue, 19 Aug 2014 16:57:43 +0200 Subject: [PATCH 30/43] Update ms2 --- mediastreamer2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediastreamer2 b/mediastreamer2 index d6b60a173..974f7ae2c 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit d6b60a173628b12c9ab88c07c94c5b51b3ebbadd +Subproject commit 974f7ae2c810a4662d4c1b6a644ee9d0be31e894 From 137688ce30784410a4dffa68191e5b8bf4519c33 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Tue, 19 Aug 2014 17:25:48 +0200 Subject: [PATCH 31/43] Prevent reference leak in Py_BuildValue in the Python wrapper. --- tools/python/apixml2python/linphone.py | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/tools/python/apixml2python/linphone.py b/tools/python/apixml2python/linphone.py index 145a3d9c9..80f6ea376 100644 --- a/tools/python/apixml2python/linphone.py +++ b/tools/python/apixml2python/linphone.py @@ -349,7 +349,7 @@ class MethodDefinition: else: result_variable = 'cresult' if result_variable != '': - build_value_code = "pyret = Py_BuildValue(\"{fmt}\", {result_variable});\n".format(fmt=self.build_value_format, result_variable=result_variable) + build_value_code = "pyret = Py_BuildValue(\"{fmt}\", {result_variable});\n".format(fmt=self.build_value_format.replace('O', 'N'), result_variable=result_variable) body = \ """ {c_function_call_code} pylinphone_dispatch_messages(); @@ -374,12 +374,7 @@ class MethodDefinition: def format_return_result(self): if self.return_complete_type != 'void': - if self.build_value_format == 'O': - return \ -""" Py_DECREF(pyresult); - return pyret;""" - else: - return "\treturn pyret;" + return "\treturn pyret;" return "\tPy_RETURN_NONE;" def format_return_none_trace(self): @@ -755,7 +750,7 @@ class EventCallbackMethodDefinition(MethodDefinition): PyErr_Print(); }} }} -""".format(fmt=fmt, args=args) +""".format(fmt=fmt.replace('O', 'N'), args=args) def format_return_trace(self): return "\tpylinphone_trace(-1, \"[PYLINPHONE] <<< %s\", __FUNCTION__);\n" From c8bd7e1007c466d5f244c0e82e8d8e5ebb563c2f Mon Sep 17 00:00:00 2001 From: Gautier Pelloux-Prayer Date: Wed, 20 Aug 2014 09:15:52 +0200 Subject: [PATCH 32/43] Fix android writable dir for tests --- coreapi/message_storage.c | 2 +- tester/tester.c | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/coreapi/message_storage.c b/coreapi/message_storage.c index adba8f00e..848c91017 100644 --- a/coreapi/message_storage.c +++ b/coreapi/message_storage.c @@ -122,7 +122,7 @@ int linphone_sql_request(sqlite3* db,const char *stmt){ int ret; ret=sqlite3_exec(db,stmt,NULL,NULL,&errmsg); if(ret != SQLITE_OK) { - ms_error("linphone_sql_request: error sqlite3_exec(): %s.", errmsg); + ms_error("linphone_sql_request: statement %s -> error sqlite3_exec(): %s.", stmt, errmsg); sqlite3_free(errmsg); } return ret; diff --git a/tester/tester.c b/tester/tester.c index 12dd60a4a..98a61c052 100644 --- a/tester/tester.c +++ b/tester/tester.c @@ -50,7 +50,11 @@ const char *liblinphone_tester_file_prefix="."; #endif /* TODO: have the same "static" for QNX and windows as above? */ +#ifdef ANDROID +const char *liblinphone_tester_writable_dir_prefix = "/data/data/org.linphone.tester/cache"; +#else const char *liblinphone_tester_writable_dir_prefix = "."; +#endif const char *userhostsfile = "tester_hosts"; From 7a79aa17bc4887b5b018021e06995bc4056e28fa Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Wed, 20 Aug 2014 14:47:02 +0200 Subject: [PATCH 33/43] Remove useless file. --- tools/python/setup.py | 27 --------------------------- 1 file changed, 27 deletions(-) delete mode 100644 tools/python/setup.py diff --git a/tools/python/setup.py b/tools/python/setup.py deleted file mode 100644 index bcd5dc419..000000000 --- a/tools/python/setup.py +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/python - -# Copyright (C) 2014 Belledonne Communications SARL -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -from distutils.core import setup, Extension - -m = Extension('linphone', - include_dirs = ['/home/ghislain/linphone-install/include'], - libraries = ['linphone'], - library_dirs = ['/home/ghislain/linphone-install/lib'], - sources = ['linphone.c'] -) -setup(name = 'Linphone', version = '1.0', description = 'Linphone package', ext_modules = [m]) From af6678a973e77f6b0bb2fb66e1ba08987c5be3a0 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Wed, 20 Aug 2014 14:53:57 +0200 Subject: [PATCH 34/43] Hand-written implementation of linphone_core_get_sound_devices() in the Python wrapper. --- tools/python/apixml2python.py | 1 + .../handwritten_declarations.mustache | 1 + .../handwritten_definitions.mustache | 25 +++++++++++++++++++ 3 files changed, 27 insertions(+) diff --git a/tools/python/apixml2python.py b/tools/python/apixml2python.py index b1bf3ebb2..712466e83 100755 --- a/tools/python/apixml2python.py +++ b/tools/python/apixml2python.py @@ -80,6 +80,7 @@ blacklisted_functions = [ ] hand_written_functions = [ 'linphone_chat_room_send_message2', + 'linphone_core_get_sound_devices', 'linphone_core_get_video_devices', 'linphone_core_new', 'linphone_core_new_with_config' diff --git a/tools/python/apixml2python/handwritten_declarations.mustache b/tools/python/apixml2python/handwritten_declarations.mustache index eac0ba4b3..d5be0a3c4 100644 --- a/tools/python/apixml2python/handwritten_declarations.mustache +++ b/tools/python/apixml2python/handwritten_declarations.mustache @@ -1,3 +1,4 @@ +static PyObject * pylinphone_Core_get_sound_devices(PyObject *self, void *closure); static PyObject * pylinphone_Core_get_video_devices(PyObject *self, void *closure); static PyTypeObject pylinphone_VideoSizeType; diff --git a/tools/python/apixml2python/handwritten_definitions.mustache b/tools/python/apixml2python/handwritten_definitions.mustache index e52f55e3a..bf1a4d7d6 100644 --- a/tools/python/apixml2python/handwritten_definitions.mustache +++ b/tools/python/apixml2python/handwritten_definitions.mustache @@ -115,6 +115,31 @@ static PyObject * pylinphone_module_method_set_log_handler(PyObject *self, PyObj } +static PyObject * pylinphone_Core_get_sound_devices(PyObject *self, void *closure) { + PyObject *_list; + const char **_devices; + LinphoneCore *native_ptr = pylinphone_Core_get_native_ptr(self); + + if (native_ptr == NULL) { + PyErr_SetString(PyExc_TypeError, "Invalid linphone.Core instance"); + return NULL; + } + + pylinphone_trace(1, "[PYLINPHONE] >>> %s(%p [%p])", __FUNCTION__, self, native_ptr); + _devices = linphone_core_get_sound_devices(native_ptr); + pylinphone_dispatch_messages(); + + _list = PyList_New(0); + while (*_devices != NULL) { + PyObject *_item = PyString_FromString(*_devices); + PyList_Append(_list, _item); + _devices++; + } + + pylinphone_trace(-1, "[PYLINPHONE] <<< %s -> %p", __FUNCTION__, _list); + return _list; +} + static PyObject * pylinphone_Core_get_video_devices(PyObject *self, void *closure) { PyObject *_list; const char **_devices; From eca15bf8c07daa2391ddda055ca6d08bc443c51d Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Wed, 20 Aug 2014 16:45:45 +0200 Subject: [PATCH 35/43] Use sphinx to generate the documentation of the Python wrapper. --- tools/python/apixml2python/linphone.py | 10 +- tools/python/doc/Makefile | 177 +++++++++++++++++ tools/python/doc/make.bat | 242 +++++++++++++++++++++++ tools/python/doc/source/conf.py | 260 +++++++++++++++++++++++++ tools/python/doc/source/index.rst | 26 +++ 5 files changed, 711 insertions(+), 4 deletions(-) create mode 100644 tools/python/doc/Makefile create mode 100644 tools/python/doc/make.bat create mode 100644 tools/python/doc/source/conf.py create mode 100644 tools/python/doc/source/index.rst diff --git a/tools/python/apixml2python/linphone.py b/tools/python/apixml2python/linphone.py index 80f6ea376..df810ee87 100644 --- a/tools/python/apixml2python/linphone.py +++ b/tools/python/apixml2python/linphone.py @@ -1041,8 +1041,8 @@ class LinphoneModule(object): method_type = xml_node.tag if method_type != 'classmethod' and len(xml_method_args) > 0: xml_method_args = xml_method_args[1:] + doc += '\n' if len(xml_method_args) > 0: - doc += "\n\nArguments:" for xml_method_arg in xml_method_args: arg_name = xml_method_arg.get('name') arg_type = xml_method_arg.get('type') @@ -1050,9 +1050,10 @@ class LinphoneModule(object): arg_contained_type = xml_method_arg.get('containedtype') argument_type = ArgumentType(arg_type, arg_complete_type, arg_contained_type, self) arg_doc = self.__format_doc_content(None, xml_method_arg.find('description')) - doc += '\n\t' + arg_name + ' [' + argument_type.type_str + ']' + doc += '\n:param ' + arg_name + ':' if arg_doc != '': - doc += ': ' + arg_doc + doc += ' ' + arg_doc + doc += '\n:type ' + arg_name + ': ' + argument_type.type_str if xml_method_return is not None: return_type = xml_method_return.get('type') return_complete_type = xml_method_return.get('completetype') @@ -1060,7 +1061,8 @@ class LinphoneModule(object): if return_complete_type != 'void': return_doc = self.__format_doc_content(None, xml_method_return.find('description')) return_argument_type = ArgumentType(return_type, return_complete_type, return_contained_type, self) - doc += '\n\nReturns:\n\t[' + return_argument_type.type_str + '] ' + return_doc + doc += '\n:returns: ' + return_doc + doc += '\n:rtype: ' + return_argument_type.type_str doc = self.__replace_doc_special_chars(doc) return doc diff --git a/tools/python/doc/Makefile b/tools/python/doc/Makefile new file mode 100644 index 000000000..b8c40c718 --- /dev/null +++ b/tools/python/doc/Makefile @@ -0,0 +1,177 @@ +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +PAPER = +BUILDDIR = build + +# User-friendly check for sphinx-build +ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) +$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) +endif + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source +# the i18n builder cannot share the environment and doctrees with the others +I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source + +.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext + +help: + @echo "Please use \`make ' where is one of" + @echo " html to make standalone HTML files" + @echo " dirhtml to make HTML files named index.html in directories" + @echo " singlehtml to make a single large HTML file" + @echo " pickle to make pickle files" + @echo " json to make JSON files" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " qthelp to make HTML files and a qthelp project" + @echo " devhelp to make HTML files and a Devhelp project" + @echo " epub to make an epub" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " latexpdf to make LaTeX files and run them through pdflatex" + @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" + @echo " text to make text files" + @echo " man to make manual pages" + @echo " texinfo to make Texinfo files" + @echo " info to make Texinfo files and run them through makeinfo" + @echo " gettext to make PO message catalogs" + @echo " changes to make an overview of all changed/added/deprecated items" + @echo " xml to make Docutils-native XML files" + @echo " pseudoxml to make pseudoxml-XML files for display purposes" + @echo " linkcheck to check all external links for integrity" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" + +clean: + rm -rf $(BUILDDIR)/* + +html: + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +dirhtml: + $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." + +singlehtml: + $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml + @echo + @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." + +pickle: + $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle + @echo + @echo "Build finished; now you can process the pickle files." + +json: + $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json + @echo + @echo "Build finished; now you can process the JSON files." + +htmlhelp: + $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp + @echo + @echo "Build finished; now you can run HTML Help Workshop with the" \ + ".hhp project file in $(BUILDDIR)/htmlhelp." + +qthelp: + $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp + @echo + @echo "Build finished; now you can run "qcollectiongenerator" with the" \ + ".qhcp project file in $(BUILDDIR)/qthelp, like this:" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Linphone.qhcp" + @echo "To view the help file:" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Linphone.qhc" + +devhelp: + $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp + @echo + @echo "Build finished." + @echo "To view the help file:" + @echo "# mkdir -p $$HOME/.local/share/devhelp/Linphone" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Linphone" + @echo "# devhelp" + +epub: + $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub + @echo + @echo "Build finished. The epub file is in $(BUILDDIR)/epub." + +latex: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo + @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." + @echo "Run \`make' in that directory to run these through (pdf)latex" \ + "(use \`make latexpdf' here to do that automatically)." + +latexpdf: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through pdflatex..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +latexpdfja: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through platex and dvipdfmx..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +text: + $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text + @echo + @echo "Build finished. The text files are in $(BUILDDIR)/text." + +man: + $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man + @echo + @echo "Build finished. The manual pages are in $(BUILDDIR)/man." + +texinfo: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo + @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." + @echo "Run \`make' in that directory to run these through makeinfo" \ + "(use \`make info' here to do that automatically)." + +info: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo "Running Texinfo files through makeinfo..." + make -C $(BUILDDIR)/texinfo info + @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." + +gettext: + $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale + @echo + @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." + +changes: + $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes + @echo + @echo "The overview file is in $(BUILDDIR)/changes." + +linkcheck: + $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck + @echo + @echo "Link check complete; look for any errors in the above output " \ + "or in $(BUILDDIR)/linkcheck/output.txt." + +doctest: + $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest + @echo "Testing of doctests in the sources finished, look at the " \ + "results in $(BUILDDIR)/doctest/output.txt." + +xml: + $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml + @echo + @echo "Build finished. The XML files are in $(BUILDDIR)/xml." + +pseudoxml: + $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml + @echo + @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." diff --git a/tools/python/doc/make.bat b/tools/python/doc/make.bat new file mode 100644 index 000000000..9c081c72b --- /dev/null +++ b/tools/python/doc/make.bat @@ -0,0 +1,242 @@ +@ECHO OFF + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set BUILDDIR=build +set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% source +set I18NSPHINXOPTS=%SPHINXOPTS% source +if NOT "%PAPER%" == "" ( + set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% + set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% +) + +if "%1" == "" goto help + +if "%1" == "help" ( + :help + echo.Please use `make ^` where ^ is one of + echo. html to make standalone HTML files + echo. dirhtml to make HTML files named index.html in directories + echo. singlehtml to make a single large HTML file + echo. pickle to make pickle files + echo. json to make JSON files + echo. htmlhelp to make HTML files and a HTML help project + echo. qthelp to make HTML files and a qthelp project + echo. devhelp to make HTML files and a Devhelp project + echo. epub to make an epub + echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter + echo. text to make text files + echo. man to make manual pages + echo. texinfo to make Texinfo files + echo. gettext to make PO message catalogs + echo. changes to make an overview over all changed/added/deprecated items + echo. xml to make Docutils-native XML files + echo. pseudoxml to make pseudoxml-XML files for display purposes + echo. linkcheck to check all external links for integrity + echo. doctest to run all doctests embedded in the documentation if enabled + goto end +) + +if "%1" == "clean" ( + for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i + del /q /s %BUILDDIR%\* + goto end +) + + +%SPHINXBUILD% 2> nul +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +if "%1" == "html" ( + %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/html. + goto end +) + +if "%1" == "dirhtml" ( + %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. + goto end +) + +if "%1" == "singlehtml" ( + %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. + goto end +) + +if "%1" == "pickle" ( + %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can process the pickle files. + goto end +) + +if "%1" == "json" ( + %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can process the JSON files. + goto end +) + +if "%1" == "htmlhelp" ( + %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can run HTML Help Workshop with the ^ +.hhp project file in %BUILDDIR%/htmlhelp. + goto end +) + +if "%1" == "qthelp" ( + %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can run "qcollectiongenerator" with the ^ +.qhcp project file in %BUILDDIR%/qthelp, like this: + echo.^> qcollectiongenerator %BUILDDIR%\qthelp\Linphone.qhcp + echo.To view the help file: + echo.^> assistant -collectionFile %BUILDDIR%\qthelp\Linphone.ghc + goto end +) + +if "%1" == "devhelp" ( + %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. + goto end +) + +if "%1" == "epub" ( + %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The epub file is in %BUILDDIR%/epub. + goto end +) + +if "%1" == "latex" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. + goto end +) + +if "%1" == "latexpdf" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + cd %BUILDDIR%/latex + make all-pdf + cd %BUILDDIR%/.. + echo. + echo.Build finished; the PDF files are in %BUILDDIR%/latex. + goto end +) + +if "%1" == "latexpdfja" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + cd %BUILDDIR%/latex + make all-pdf-ja + cd %BUILDDIR%/.. + echo. + echo.Build finished; the PDF files are in %BUILDDIR%/latex. + goto end +) + +if "%1" == "text" ( + %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The text files are in %BUILDDIR%/text. + goto end +) + +if "%1" == "man" ( + %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The manual pages are in %BUILDDIR%/man. + goto end +) + +if "%1" == "texinfo" ( + %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. + goto end +) + +if "%1" == "gettext" ( + %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The message catalogs are in %BUILDDIR%/locale. + goto end +) + +if "%1" == "changes" ( + %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes + if errorlevel 1 exit /b 1 + echo. + echo.The overview file is in %BUILDDIR%/changes. + goto end +) + +if "%1" == "linkcheck" ( + %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck + if errorlevel 1 exit /b 1 + echo. + echo.Link check complete; look for any errors in the above output ^ +or in %BUILDDIR%/linkcheck/output.txt. + goto end +) + +if "%1" == "doctest" ( + %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest + if errorlevel 1 exit /b 1 + echo. + echo.Testing of doctests in the sources finished, look at the ^ +results in %BUILDDIR%/doctest/output.txt. + goto end +) + +if "%1" == "xml" ( + %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The XML files are in %BUILDDIR%/xml. + goto end +) + +if "%1" == "pseudoxml" ( + %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml. + goto end +) + +:end diff --git a/tools/python/doc/source/conf.py b/tools/python/doc/source/conf.py new file mode 100644 index 000000000..125e5c6d9 --- /dev/null +++ b/tools/python/doc/source/conf.py @@ -0,0 +1,260 @@ +# -*- coding: utf-8 -*- +# +# Linphone documentation build configuration file, created by +# sphinx-quickstart on Wed Aug 20 15:37:38 2014. +# +# This file is execfile()d with the current directory set to its +# containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys +import os + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +#sys.path.insert(0, os.path.abspath('.')) + +# -- General configuration ------------------------------------------------ + +# If your documentation needs a minimal Sphinx version, state it here. +#needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + 'sphinx.ext.autodoc', +] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix of source filenames. +source_suffix = '.rst' + +# The encoding of source files. +#source_encoding = 'utf-8-sig' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'Linphone' +copyright = u'2014, Belledonne Communications' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = '3.7' +# The full version, including alpha/beta/rc tags. +release = '3.7.0' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +#language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +#today = '' +# Else, today_fmt is used as the format for a strftime call. +#today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = [] + +# The reST default role (used for this markup: `text`) to use for all +# documents. +#default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +#show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# A list of ignored prefixes for module index sorting. +#modindex_common_prefix = [] + +# If true, keep warnings as "system message" paragraphs in the built documents. +#keep_warnings = False + + +# -- Options for HTML output ---------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +html_theme = 'default' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +#html_theme_options = {} + +# Add any paths that contain custom themes here, relative to this directory. +#html_theme_path = [] + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +#html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +#html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +#html_logo = None + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +#html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# Add any extra paths that contain custom files (such as robots.txt or +# .htaccess) here, relative to this directory. These files are copied +# directly to the root of the documentation. +#html_extra_path = [] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +#html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +#html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +#html_additional_pages = {} + +# If false, no module index is generated. +#html_domain_indices = True + +# If false, no index is generated. +#html_use_index = True + +# If true, the index is split into individual pages for each letter. +#html_split_index = False + +# If true, links to the reST sources are added to the pages. +#html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +#html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +#html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = None + +# Output file base name for HTML help builder. +htmlhelp_basename = 'Linphonedoc' + + +# -- Options for LaTeX output --------------------------------------------- + +latex_elements = { +# The paper size ('letterpaper' or 'a4paper'). +#'papersize': 'letterpaper', + +# The font size ('10pt', '11pt' or '12pt'). +#'pointsize': '10pt', + +# Additional stuff for the LaTeX preamble. +#'preamble': '', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + ('index', 'Linphone.tex', u'Linphone Documentation', + u'Belledonne Communications', 'manual'), +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +#latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +#latex_use_parts = False + +# If true, show page references after internal links. +#latex_show_pagerefs = False + +# If true, show URL addresses after external links. +#latex_show_urls = False + +# Documents to append as an appendix to all manuals. +#latex_appendices = [] + +# If false, no module index is generated. +#latex_domain_indices = True + + +# -- Options for manual page output --------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + ('index', 'linphone', u'Linphone Documentation', + [u'Belledonne Communications'], 1) +] + +# If true, show URL addresses after external links. +#man_show_urls = False + + +# -- Options for Texinfo output ------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + ('index', 'Linphone', u'Linphone Documentation', + u'Belledonne Communications', 'Linphone', 'One line description of project.', + 'Miscellaneous'), +] + +# Documents to append as an appendix to all manuals. +#texinfo_appendices = [] + +# If false, no module index is generated. +#texinfo_domain_indices = True + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +#texinfo_show_urls = 'footnote' + +# If true, do not generate a @detailmenu in the "Top" node's menu. +#texinfo_no_detailmenu = False diff --git a/tools/python/doc/source/index.rst b/tools/python/doc/source/index.rst new file mode 100644 index 000000000..560b05f47 --- /dev/null +++ b/tools/python/doc/source/index.rst @@ -0,0 +1,26 @@ +.. Linphone documentation master file, created by + sphinx-quickstart on Wed Aug 20 15:37:38 2014. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to Linphone's documentation! +==================================== + +Contents: + +.. toctree:: + :maxdepth: 2 + +.. automodule:: linphone + :members: + :undoc-members: + +.. autoattribute:: linphone.__version__ + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`search` + From a53740de5f18426aaa6728f0381def365f625997 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Wed, 20 Aug 2014 18:07:40 +0200 Subject: [PATCH 36/43] fix call acceptance with policy test, by adding linphone_core_create_call_params(). --- README.mingw | 1 + coreapi/linphonecall.c | 2 +- coreapi/linphonecore.c | 13 ++++++++++++ coreapi/linphonecore.h | 3 +++ gtk/setupwizard.c | 23 ++++++++++++--------- oRTP | 2 +- tester/call_tester.c | 47 ++++++++++++++++++++++++++++++------------ 7 files changed, 66 insertions(+), 25 deletions(-) diff --git a/README.mingw b/README.mingw index 8b97ea1ef..eaa42b07f 100644 --- a/README.mingw +++ b/README.mingw @@ -63,6 +63,7 @@ cd /c/sources Building belle-sip ****************** + * make sure that java version 1.6 is available in the PATH. java-1.7 will not work with antlr generator. * download the sources with msys-git shell using the following command: $ git clone git://git.linphone.org/belle-sip.git * compile and install diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 364471490..a8dbcf61f 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -2273,7 +2273,7 @@ static void linphone_call_start_video_stream(LinphoneCall *call, const char *cna } }else ms_warning("No video stream accepted."); }else{ - ms_warning("No valid video stream defined."); + ms_message("No valid video stream defined."); } #endif } diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 34add6e0f..67582a2b0 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -6319,6 +6319,19 @@ LinphoneCallParams *linphone_core_create_default_call_parameters(LinphoneCore *l return p; } +/** + * Create a LinphoneCallParams suitable for linphone_core_invite_with_params(), linphone_core_accept_call_with_params(), linphone_core_accept_early_media_with_params(), + * linphone_core_accept_call_update(). + * The parameters are initialized according to the current LinphoneCore configuration and the current state of the LinphoneCall. + * @param lc the LinphoneCore + * @param call the call for which the parameters are to be build, or NULL in the case where the parameters are to be used for a new outgoing call. + * @return a new LinphoneCallParams + */ +LinphoneCallParams *linphone_core_create_call_params(LinphoneCore *lc, LinphoneCall *call){ + if (!call) return linphone_core_create_default_call_parameters(lc); + return linphone_call_params_copy(&call->params); +} + const char *linphone_reason_to_string(LinphoneReason err){ switch(err){ case LinphoneReasonNone: diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index 773701d52..b553322bf 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -1862,9 +1862,12 @@ LINPHONE_PUBLIC int linphone_core_accept_call_update(LinphoneCore *lc, LinphoneC * Get default call parameters reflecting current linphone core configuration * @param lc LinphoneCore object * @return LinphoneCallParams + * @deprecated use linphone_core_create_call_params() */ LINPHONE_PUBLIC LinphoneCallParams *linphone_core_create_default_call_parameters(LinphoneCore *lc); +LINPHONE_PUBLIC LinphoneCallParams *linphone_core_create_call_params(LinphoneCore *lc, LinphoneCall *call); + LINPHONE_PUBLIC LinphoneCall *linphone_core_get_call_by_remote_address(LinphoneCore *lc, const char *remote_address); LINPHONE_PUBLIC void linphone_core_send_dtmf(LinphoneCore *lc,char dtmf); diff --git a/gtk/setupwizard.c b/gtk/setupwizard.c index 27f7363b7..e3974c2f4 100644 --- a/gtk/setupwizard.c +++ b/gtk/setupwizard.c @@ -429,16 +429,19 @@ static void linphone_gtk_assistant_prepare(GtkWidget *assistant, GtkWidget *page linphone_core_add_auth_info(linphone_gtk_get_core(),info); linphone_address_destroy(identity); - // If account created on sip.linphone.org, we configure linphone to use TLS by default - if (strcmp(creator->domain, "sip:sip.linphone.org") == 0 && linphone_core_sip_transport_supported(linphone_gtk_get_core(),LinphoneTransportTls)) { - LinphoneAddress *addr=linphone_address_new(creator->domain); - char *tmp; - linphone_address_set_transport(addr, LinphoneTransportTls); - tmp=linphone_address_as_string(addr); - linphone_proxy_config_set_server_addr(cfg,tmp); - linphone_proxy_config_set_route(cfg,tmp); - ms_free(tmp); - linphone_address_destroy(addr); + if (strcmp(creator->domain, "sip:sip.linphone.org") == 0 ){ + linphone_proxy_config_enable_avpf(cfg,TRUE); + // If account created on sip.linphone.org, we configure linphone to use TLS by default + if (linphone_core_sip_transport_supported(linphone_gtk_get_core(),LinphoneTransportTls)) { + LinphoneAddress *addr=linphone_address_new(creator->domain); + char *tmp; + linphone_address_set_transport(addr, LinphoneTransportTls); + tmp=linphone_address_as_string(addr); + linphone_proxy_config_set_server_addr(cfg,tmp); + linphone_proxy_config_set_route(cfg,tmp); + ms_free(tmp); + linphone_address_destroy(addr); + } } if (linphone_core_add_proxy_config(linphone_gtk_get_core(),cfg)==-1) diff --git a/oRTP b/oRTP index b9534b1b2..007016485 160000 --- a/oRTP +++ b/oRTP @@ -1 +1 @@ -Subproject commit b9534b1b2beb4bc549741e1f55a9c0bfe15d6c90 +Subproject commit 00701648593b0fce93b3d519e281dd6f547db670 diff --git a/tester/call_tester.c b/tester/call_tester.c index 7e6d9f88e..c5453a2c9 100644 --- a/tester/call_tester.c +++ b/tester/call_tester.c @@ -160,10 +160,10 @@ void liblinphone_tester_check_rtcp(LinphoneCoreManager* caller, LinphoneCoreMana linphone_call_unref(c2); } -bool_t call_with_params(LinphoneCoreManager* caller_mgr +bool_t call_with_params2(LinphoneCoreManager* caller_mgr ,LinphoneCoreManager* callee_mgr , const LinphoneCallParams *caller_params - , const LinphoneCallParams *callee_params) { + , const LinphoneCallParams *callee_params, bool_t build_callee_params) { int retry=0; stats initial_caller=caller_mgr->stat; stats initial_callee=callee_mgr->stat; @@ -215,10 +215,16 @@ bool_t call_with_params(LinphoneCoreManager* caller_mgr } linphone_address_destroy(callee_from); } - if (callee_params) + if (callee_params){ linphone_core_accept_call_with_params(callee_mgr->lc,linphone_core_get_current_call(callee_mgr->lc),callee_params); - else + }else if (build_callee_params){ + LinphoneCallParams *default_params=linphone_core_create_call_params(callee_mgr->lc,linphone_core_get_current_call(callee_mgr->lc)); + ms_error("Created default call params with video=%i", linphone_call_params_video_enabled(default_params)); + linphone_core_accept_call_with_params(callee_mgr->lc,linphone_core_get_current_call(callee_mgr->lc),default_params); + linphone_call_params_destroy(default_params); + }else{ linphone_core_accept_call(callee_mgr->lc,linphone_core_get_current_call(callee_mgr->lc)); + } CU_ASSERT_TRUE(wait_for(callee_mgr->lc,caller_mgr->lc,&callee_mgr->stat.number_of_LinphoneCallConnected,initial_callee.number_of_LinphoneCallConnected+1)); CU_ASSERT_TRUE(wait_for(callee_mgr->lc,caller_mgr->lc,&caller_mgr->stat.number_of_LinphoneCallConnected,initial_callee.number_of_LinphoneCallConnected+1)); @@ -243,6 +249,14 @@ bool_t call_with_params(LinphoneCoreManager* caller_mgr } return result; } + +bool_t call_with_params(LinphoneCoreManager* caller_mgr + ,LinphoneCoreManager* callee_mgr + , const LinphoneCallParams *caller_params + , const LinphoneCallParams *callee_params){ + return call_with_params2(caller_mgr,callee_mgr,caller_params,callee_params,FALSE); +} + bool_t call_with_caller_params(LinphoneCoreManager* caller_mgr,LinphoneCoreManager* callee_mgr, const LinphoneCallParams *params) { return call_with_params(caller_mgr,callee_mgr,params,NULL); } @@ -1270,7 +1284,7 @@ static void srtp_call_with_several_video_switches(void) { static void call_with_declined_video_base(bool_t using_policy) { LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); - LinphoneCallParams* callee_params; + LinphoneCallParams* callee_params=NULL; LinphoneCallParams* caller_params; LinphoneCall* marie_call; LinphoneCall* pauline_call; @@ -1293,11 +1307,16 @@ static void call_with_declined_video_base(bool_t using_policy) { caller_params=linphone_core_create_default_call_parameters(pauline->lc); if (!using_policy) linphone_call_params_enable_video(caller_params,TRUE); - callee_params=linphone_core_create_default_call_parameters(marie->lc); - if (!using_policy) + + if (!using_policy){ + callee_params=linphone_core_create_default_call_parameters(marie->lc); linphone_call_params_enable_video(callee_params,FALSE); + } - CU_ASSERT_TRUE(call_with_params(pauline,marie,caller_params,callee_params)); + CU_ASSERT_TRUE(call_with_params2(pauline,marie,caller_params,callee_params,using_policy)); + + linphone_call_params_destroy(caller_params); + if (callee_params) linphone_call_params_destroy(callee_params); marie_call=linphone_core_get_current_call(marie->lc); pauline_call=linphone_core_get_current_call(pauline->lc); @@ -1320,7 +1339,7 @@ static void call_with_declined_video_using_policy(void) { } static void video_call_base(LinphoneCoreManager* pauline,LinphoneCoreManager* marie, bool_t using_policy) { - LinphoneCallParams* callee_params; + LinphoneCallParams* callee_params=NULL; LinphoneCallParams* caller_params; LinphoneCall* marie_call; LinphoneCall* pauline_call; @@ -1343,16 +1362,18 @@ static void video_call_base(LinphoneCoreManager* pauline,LinphoneCoreManager* ma caller_params=linphone_core_create_default_call_parameters(pauline->lc); if (!using_policy) linphone_call_params_enable_video(caller_params,TRUE); - callee_params=linphone_core_create_default_call_parameters(marie->lc); - if (!using_policy) + + if (!using_policy){ + callee_params=linphone_core_create_default_call_parameters(marie->lc); linphone_call_params_enable_video(callee_params,TRUE); + } - CU_ASSERT_TRUE(call_with_params(pauline,marie,caller_params,callee_params)); + CU_ASSERT_TRUE(call_with_params2(pauline,marie,caller_params,callee_params,using_policy)); marie_call=linphone_core_get_current_call(marie->lc); pauline_call=linphone_core_get_current_call(pauline->lc); linphone_call_params_destroy(caller_params); - linphone_call_params_destroy(callee_params); + if (callee_params) linphone_call_params_destroy(callee_params); if (marie_call && pauline_call ) { CU_ASSERT_TRUE(linphone_call_log_video_enabled(linphone_call_get_call_log(marie_call))); From 7b7a2570b76660987dfa8046cf233c773a0e60a2 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Wed, 20 Aug 2014 22:08:44 +0200 Subject: [PATCH 37/43] improve timing of tester --- tester/call_tester.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tester/call_tester.c b/tester/call_tester.c index c5453a2c9..e43444bd0 100644 --- a/tester/call_tester.c +++ b/tester/call_tester.c @@ -125,8 +125,8 @@ static void linphone_call_cb(LinphoneCall *call,void * user_data) { void liblinphone_tester_check_rtcp(LinphoneCoreManager* caller, LinphoneCoreManager* callee) { LinphoneCall *c1,*c2; - int i; int dummy=0; + MSTimeSpec ts; c1=linphone_core_get_current_call(caller->lc); c2=linphone_core_get_current_call(callee->lc); @@ -137,7 +137,9 @@ void liblinphone_tester_check_rtcp(LinphoneCoreManager* caller, LinphoneCoreMana if (!c1 || !c2) return; linphone_call_ref(c1); linphone_call_ref(c2); - for (i=0; i<24 /*=12s need at least one exchange of SR to maybe 10s*/; i++) { + + liblinphone_tester_clock_start(&ts); + do { if (linphone_call_get_audio_stats(c1)->round_trip_delay >0.0 && linphone_call_get_audio_stats(c2)->round_trip_delay >0.0 && (!linphone_call_log_video_enabled(linphone_call_get_call_log(c1)) || linphone_call_get_video_stats(c1)->round_trip_delay>0.0) @@ -146,8 +148,7 @@ void liblinphone_tester_check_rtcp(LinphoneCoreManager* caller, LinphoneCoreMana } wait_for_until(caller->lc,callee->lc,&dummy,1,500); /*just to sleep while iterating*/ - - } + }while (!liblinphone_tester_clock_elapsed(&ts,12000)); CU_ASSERT_TRUE(linphone_call_get_audio_stats(c1)->round_trip_delay>0.0); CU_ASSERT_TRUE(linphone_call_get_audio_stats(c2)->round_trip_delay>0.0); if (linphone_call_log_video_enabled(linphone_call_get_call_log(c1))) { From 9cdd062f48b16232dea32b8c4f94d079c9912c1c Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Thu, 21 Aug 2014 11:59:14 +0200 Subject: [PATCH 38/43] Update ms2 submodule. --- mediastreamer2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediastreamer2 b/mediastreamer2 index 974f7ae2c..cdc17ca02 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 974f7ae2c810a4662d4c1b6a644ee9d0be31e894 +Subproject commit cdc17ca02bd26ab1c0c99eb74e716ed4f3884700 From f40c178dc4988e5df47946b1a015bb5eb28108b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Grisez?= Date: Thu, 21 Aug 2014 15:33:25 +0200 Subject: [PATCH 39/43] Refactor "Call recording tester" --- mediastreamer2 | 2 +- tester/call_tester.c | 102 +++++++++++++++++++++---------------------- 2 files changed, 52 insertions(+), 52 deletions(-) diff --git a/mediastreamer2 b/mediastreamer2 index cdc17ca02..33cce2e74 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit cdc17ca02bd26ab1c0c99eb74e716ed4f3884700 +Subproject commit 33cce2e74956d37c98d120b2c1d19c1d19d2f9a0 diff --git a/tester/call_tester.c b/tester/call_tester.c index e43444bd0..e8ab0d021 100644 --- a/tester/call_tester.c +++ b/tester/call_tester.c @@ -2778,14 +2778,25 @@ static void savpf_to_savpf_call(void) { profile_call(TRUE, TRUE, TRUE, TRUE, "RTP/SAVPF"); } -static void call_recording() { +static char *create_filepath(const char *dir, const char *filename, const char *ext) { + char *filepath = ms_new0(char, strlen(dir) + strlen(filename) + strlen(ext) + 3); + strcpy(filepath, dir); + strcat(filepath, "/"); + strcat(filepath, filename); + strcat(filepath, "."); + strcat(filepath, ext); + return filepath; +} + +static void record_call(const char *filename, bool_t enableVideo) { LinphoneCoreManager *marie = NULL; LinphoneCoreManager *pauline = NULL; LinphoneCallParams *marieParams = NULL; LinphoneCallParams *paulineParams = NULL; LinphoneCall *callInst = NULL; - int dummy=0; - char *filepath = NULL; + const char **formats, *format; + char *filepath; + int dummy=0, i; #ifdef ANDROID #ifdef HAVE_OPENH264 @@ -2798,61 +2809,49 @@ static void call_recording() { marieParams = linphone_core_create_default_call_parameters(marie->lc); paulineParams = linphone_core_create_default_call_parameters(pauline->lc); -#ifdef ANDROID - const char dirname[] = "/sdcard/Movies/liblinphone_tester"; -#else - const char dirname[] = ".test"; -#endif - #ifdef VIDEO_ENABLED - const char filename[] = "recording.mkv"; -#else - const char filename[] = "recording.wav"; -#endif - - filepath = ms_new0(char, strlen(dirname) + strlen(filename) + 2); - strcpy(filepath, dirname); - strcat(filepath, "/"); - strcat(filepath, filename); - if(access(dirname, F_OK) != 0) { -#ifdef WIN32 - CU_ASSERT_EQUAL(mkdir(dirname),0); -#else - CU_ASSERT_EQUAL(mkdir(dirname, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH), 0); -#endif - } - CU_ASSERT_EQUAL(access(dirname, W_OK), 0); - if(access(filepath, F_OK) == 0) { - CU_ASSERT_EQUAL(remove(filepath), 0); - } - - linphone_call_params_set_record_file(marieParams, filepath); - -#ifdef VIDEO_ENABLED - if((linphone_core_find_payload_type(marie->lc, "H264", -1, -1) != NULL) && (linphone_core_find_payload_type(pauline->lc, "H264", -1, -1) != NULL)) { - linphone_call_params_enable_video(marieParams, TRUE); - linphone_call_params_enable_video(paulineParams, TRUE); - disable_all_video_codecs_except_one(marie->lc, "H264"); - disable_all_video_codecs_except_one(pauline->lc, "H264"); - } else { - ms_warning("call_recording(): the H264 payload has not been found. Only sound will be recorded"); + if(enableVideo) { + if((CU_ASSERT_PTR_NOT_NULL(linphone_core_find_payload_type(marie->lc, "H264", -1, -1))) + && (CU_ASSERT_PTR_NOT_NULL(linphone_core_find_payload_type(pauline->lc, "H264", -1, -1)))) { + linphone_call_params_enable_video(marieParams, TRUE); + linphone_call_params_enable_video(paulineParams, TRUE); + disable_all_video_codecs_except_one(marie->lc, "H264"); + disable_all_video_codecs_except_one(pauline->lc, "H264"); + } else { + ms_warning("call_recording(): the H264 payload has not been found. Only sound will be recorded"); + } } #endif - CU_ASSERT_TRUE(call_with_params(marie, pauline, marieParams, paulineParams)); - CU_ASSERT_PTR_NOT_NULL(callInst = linphone_core_get_current_call(marie->lc)); + formats = linphone_core_get_supported_file_formats(marie->lc); - ms_message("call_recording(): the call will be recorded into %s", filepath); - linphone_call_start_recording(callInst); - wait_for_until(marie->lc,pauline->lc,&dummy,1,10000); - linphone_call_stop_recording(callInst); - - CU_ASSERT_EQUAL(access(filepath, F_OK), 0); - end_call(marie, pauline); + for(i=0, format = formats[0]; format != NULL; i++, format = formats[i]) { + filepath = create_filepath(liblinphone_tester_writable_dir_prefix, filename, format); + remove(filepath); + linphone_call_params_set_record_file(marieParams, filepath); + if((CU_ASSERT_TRUE(call_with_params(marie, pauline, marieParams, paulineParams))) + && (CU_ASSERT_PTR_NOT_NULL(callInst = linphone_core_get_current_call(marie->lc)))) { + ms_message("call_recording(): start recording into %s", filepath); + linphone_call_start_recording(callInst); + wait_for_until(marie->lc,pauline->lc,&dummy,1,5000); + linphone_call_stop_recording(callInst); + end_call(marie, pauline); + CU_ASSERT_EQUAL(access(filepath, F_OK), 0); + remove(filepath); + } + ms_free(filepath); + } linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); - ms_free(filepath); +} + +static void audio_call_recording_test(void) { + record_call("recording", FALSE); +} + +static void video_call_recording_test(void) { + record_call("recording", TRUE); } test_t call_tests[] = { @@ -2865,6 +2864,7 @@ test_t call_tests[] = { { "Call failed because of codecs", call_failed_because_of_codecs }, { "Simple call", simple_call }, { "Outbound call with multiple proxy possible", call_outbound_with_multiple_proxy }, + { "Audio call recording", audio_call_recording_test }, #if 0 /* not yet activated because not implemented */ { "Multiple answers to a call", multiple_answers_call }, #endif @@ -2901,6 +2901,7 @@ test_t call_tests[] = { { "Call with ICE from video to non-video", call_with_ice_video_to_novideo}, { "Call with ICE and video added", call_with_ice_video_added }, { "Video call with ICE no matching audio codecs", video_call_with_ice_no_matching_audio_codecs }, + { "Video call recording", video_call_recording_test }, #endif { "SRTP ice call", srtp_ice_call }, { "ZRTP ice call", zrtp_ice_call }, @@ -2946,7 +2947,6 @@ test_t call_tests[] = { { "SAVPF to AVPF call", savpf_to_avpf_call }, { "SAVPF to SAVP call", savpf_to_savp_call }, { "SAVPF to SAVPF call", savpf_to_savpf_call }, - { "Call recording", call_recording } }; test_suite_t call_test_suite = { From b6a9bdeed5689835199a6a44e59e0d0a7e30f5da Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Thu, 21 Aug 2014 15:43:15 +0200 Subject: [PATCH 40/43] Use belle-sip reference counting for LinphoneProxyConfig and LinphoneCall objects. --- coreapi/linphonecall.c | 38 +++++++++------------ coreapi/linphonecore.h | 75 +++++++++++++++++++++++++++++++++++------- coreapi/misc.c | 12 ------- coreapi/private.h | 22 ++++++------- coreapi/proxy.c | 54 +++++++++++++++++++++--------- 5 files changed, 128 insertions(+), 73 deletions(-) diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index a8dbcf61f..dc339f09d 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -570,8 +570,6 @@ static void port_config_set(LinphoneCall *call, int stream_index, int min_port, static void linphone_call_init_common(LinphoneCall *call, LinphoneAddress *from, LinphoneAddress *to){ int min_port, max_port; ms_message("New LinphoneCall [%p] initialized (LinphoneCore version: %s)",call,linphone_core_get_version()); - call->magic=linphone_call_magic; - call->refcnt=1; call->state=LinphoneCallIdle; call->transfer_state = LinphoneCallIdle; call->media_start_time=0; @@ -647,8 +645,19 @@ static void linphone_call_outgoing_select_ip_version(LinphoneCall *call, Linphon }else call->af=AF_INET; } +static void linphone_call_destroy(LinphoneCall *obj); + +BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneCall); + +BELLE_SIP_INSTANCIATE_VPTR(LinphoneCall, belle_sip_object_t, + (belle_sip_object_destroy_t)linphone_call_destroy, + NULL, // clone + NULL, // marshal + FALSE +); + LinphoneCall * linphone_call_new_outgoing(struct _LinphoneCore *lc, LinphoneAddress *from, LinphoneAddress *to, const LinphoneCallParams *params, LinphoneProxyConfig *cfg){ - LinphoneCall *call=ms_new0(LinphoneCall,1); + LinphoneCall *call = belle_sip_object_new(LinphoneCall); call->dir=LinphoneCallOutgoing; call->core=lc; @@ -708,7 +717,7 @@ void linphone_call_set_compatible_incoming_call_parameters(LinphoneCall *call, c } LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *from, LinphoneAddress *to, SalOp *op){ - LinphoneCall *call=ms_new0(LinphoneCall,1); + LinphoneCall *call = belle_sip_object_new(LinphoneCall); const SalMediaDescription *md; LinphoneFirewallPolicy fpol; @@ -999,7 +1008,6 @@ static void linphone_call_destroy(LinphoneCall *obj) linphone_call_params_uninit(&obj->params); linphone_call_params_uninit(&obj->current_params); sal_error_info_reset(&obj->non_op_error); - ms_free(obj); } /** @@ -1007,27 +1015,13 @@ static void linphone_call_destroy(LinphoneCall *obj) * @{ **/ -/** - * Increments the call 's reference count. - * An application that wishes to retain a pointer to call object - * must use this function to unsure the pointer remains - * valid. Once the application no more needs this pointer, - * it must call linphone_call_unref(). -**/ LinphoneCall * linphone_call_ref(LinphoneCall *obj){ - obj->refcnt++; + belle_sip_object_ref(obj); return obj; } -/** - * Decrements the call object reference count. - * See linphone_call_ref(). -**/ void linphone_call_unref(LinphoneCall *obj){ - obj->refcnt--; - if (obj->refcnt==0){ - linphone_call_destroy(obj); - } + belle_sip_object_unref(obj); } /** @@ -1154,7 +1148,7 @@ const LinphoneErrorInfo *linphone_call_get_error_info(const LinphoneCall *call){ * * return user_pointer an opaque user pointer that can be retrieved at any time **/ -void *linphone_call_get_user_data(LinphoneCall *call) +void *linphone_call_get_user_data(const LinphoneCall *call) { return call->user_pointer; } diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index b553322bf..bfef5498b 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -729,6 +729,41 @@ typedef enum _LinphoneCallState{ LINPHONE_PUBLIC const char *linphone_call_state_to_string(LinphoneCallState cs); +/** + * Acquire a reference to the call. + * An application that wishes to retain a pointer to call object + * must use this function to unsure the pointer remains + * valid. Once the application no more needs this pointer, + * it must call linphone_call_unref(). + * @param[in] call The call. + * @return The same call. + * @ingroup call_control +**/ +LINPHONE_PUBLIC LinphoneCall *linphone_call_ref(LinphoneCall *call); + +/** + * Release reference to the call. + * @param[in] call The call. + * @ingroup call_control +**/ +LINPHONE_PUBLIC void linphone_call_unref(LinphoneCall *call); + +/** + * Retrieve the user pointer associated with the call. + * @param[in] call The call. + * @return The user pointer associated with the call. + * @ingroup call_control +**/ +LINPHONE_PUBLIC void *linphone_call_get_user_data(const LinphoneCall *call); + +/** + * Assign a user pointer to the call. + * @param[in] cfg The call. + * @param[in] ud The user pointer to associate with the call. + * @ingroup call_control +**/ +LINPHONE_PUBLIC void linphone_call_set_user_data(LinphoneCall *call, void *ud); + LINPHONE_PUBLIC LinphoneCore *linphone_call_get_core(const LinphoneCall *call); LINPHONE_PUBLIC LinphoneCallState linphone_call_get_state(const LinphoneCall *call); LINPHONE_PUBLIC bool_t linphone_call_asked_to_autoanswer(LinphoneCall *call); @@ -736,8 +771,6 @@ LINPHONE_PUBLIC const LinphoneAddress * linphone_core_get_current_call_remote_ad LINPHONE_PUBLIC const LinphoneAddress * linphone_call_get_remote_address(const LinphoneCall *call); LINPHONE_PUBLIC char *linphone_call_get_remote_address_as_string(const LinphoneCall *call); LINPHONE_PUBLIC LinphoneCallDir linphone_call_get_dir(const LinphoneCall *call); -LINPHONE_PUBLIC LinphoneCall * linphone_call_ref(LinphoneCall *call); -LINPHONE_PUBLIC void linphone_call_unref(LinphoneCall *call); LINPHONE_PUBLIC LinphoneCallLog *linphone_call_get_call_log(const LinphoneCall *call); LINPHONE_PUBLIC const char *linphone_call_get_refer_to(const LinphoneCall *call); LINPHONE_PUBLIC bool_t linphone_call_has_transfer_pending(const LinphoneCall *call); @@ -765,10 +798,8 @@ LINPHONE_PUBLIC void linphone_call_set_authentication_token_verified(LinphoneCal LINPHONE_PUBLIC void linphone_call_send_vfu_request(LinphoneCall *call); /** @deprecated Use linphone_call_get_user_data() instead. */ #define linphone_call_get_user_pointer(call) linphone_call_get_user_data(call) -LINPHONE_PUBLIC void *linphone_call_get_user_data(LinphoneCall *call); /** @deprecated Use linphone_call_set_user_data() instead. */ #define linphone_call_set_user_pointer(call, ud) linphone_call_set_user_data(call, ud) -LINPHONE_PUBLIC void linphone_call_set_user_data(LinphoneCall *call, void *user_data); LINPHONE_PUBLIC void linphone_call_set_next_video_frame_decoded_callback(LinphoneCall *call, LinphoneCallCbFunc cb, void* user_data); LINPHONE_PUBLIC LinphoneCallState linphone_call_get_transfer_state(LinphoneCall *call); LINPHONE_PUBLIC void linphone_call_zoom_video(LinphoneCall* call, float zoom_factor, float* cx, float* cy); @@ -860,6 +891,34 @@ typedef enum _LinphoneRegistrationState{ */ LINPHONE_PUBLIC const char *linphone_registration_state_to_string(LinphoneRegistrationState cs); LINPHONE_PUBLIC LinphoneProxyConfig *linphone_proxy_config_new(void); + +/** + * Acquire a reference to the proxy config. + * @param[in] cfg The proxy config. + * @return The same proxy config. +**/ +LINPHONE_PUBLIC LinphoneProxyConfig *linphone_proxy_config_ref(LinphoneProxyConfig *cfg); + +/** + * Release reference to the proxy config. + * @param[in] cfg The proxy config. +**/ +LINPHONE_PUBLIC void linphone_proxy_config_unref(LinphoneProxyConfig *cfg); + +/** + * Retrieve the user pointer associated with the proxy config. + * @param[in] cfg The proxy config. + * @return The user pointer associated with the proxy config. +**/ +LINPHONE_PUBLIC void *linphone_proxy_config_get_user_data(const LinphoneProxyConfig *cfg); + +/** + * Assign a user pointer to the proxy config. + * @param[in] cfg The proxy config. + * @param[in] ud The user pointer to associate with the proxy config. +**/ +LINPHONE_PUBLIC void linphone_proxy_config_set_user_data(LinphoneProxyConfig *cfg, void *ud); + LINPHONE_PUBLIC int linphone_proxy_config_set_server_addr(LinphoneProxyConfig *obj, const char *server_addr); LINPHONE_PUBLIC int linphone_proxy_config_set_identity(LinphoneProxyConfig *obj, const char *identity); LINPHONE_PUBLIC int linphone_proxy_config_set_route(LinphoneProxyConfig *obj, const char *route); @@ -1036,14 +1095,6 @@ LINPHONE_PUBLIC SipSetup *linphone_proxy_config_get_sip_setup(LinphoneProxyConfi * normalize a human readable phone number into a basic string. 888-444-222 becomes 888444222 */ LINPHONE_PUBLIC int linphone_proxy_config_normalize_number(LinphoneProxyConfig *proxy, const char *username, char *result, size_t result_len); -/* - * attached a user data to a proxy config - */ -LINPHONE_PUBLIC void linphone_proxy_config_set_user_data(LinphoneProxyConfig *cr, void * ud); -/* - * get user data to a proxy config. return null if any - */ -LINPHONE_PUBLIC void * linphone_proxy_config_get_user_data(LinphoneProxyConfig *cr); /** * Set default privacy policy for all calls routed through this proxy. diff --git a/coreapi/misc.c b/coreapi/misc.c index d4bf48cd5..47495ebe4 100644 --- a/coreapi/misc.c +++ b/coreapi/misc.c @@ -946,18 +946,6 @@ bool_t linphone_core_media_description_contains_video_stream(const SalMediaDescr return FALSE; } -LinphoneCall * is_a_linphone_call(void *user_pointer){ - LinphoneCall *call=(LinphoneCall*)user_pointer; - if (call==NULL) return NULL; - return call->magic==linphone_call_magic ? call : NULL; -} - -LinphoneProxyConfig * is_a_linphone_proxy_config(void *user_pointer){ - LinphoneProxyConfig *cfg=(LinphoneProxyConfig*)user_pointer; - if (cfg==NULL) return NULL; - return cfg->magic==linphone_proxy_config_magic ? cfg : NULL; -} - unsigned int linphone_core_get_audio_features(LinphoneCore *lc){ unsigned int ret=0; const char *features=lp_config_get_string(lc->config,"sound","features",NULL); diff --git a/coreapi/private.h b/coreapi/private.h index 2df416fba..14e86e48b 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -138,8 +138,6 @@ typedef struct _CallCallbackObj void * _user_data; }CallCallbackObj; -static const int linphone_call_magic=0x3343; - typedef enum _LinphoneChatMessageDir{ LinphoneChatMessageIncoming, LinphoneChatMessageOutgoing @@ -183,7 +181,8 @@ typedef struct _PortConfig{ struct _LinphoneCall { - int magic; /*used to distinguish from proxy config*/ + belle_sip_object_t base; + void *user_data; struct _LinphoneCore *core; SalErrorInfo non_op_error; int af; /*the address family to prefer for RTP path, guessed from signaling path*/ @@ -202,7 +201,6 @@ struct _LinphoneCall LinphoneCallState prevstate; LinphoneCallState transfer_state; /*idle if no transfer*/ LinphoneProxyConfig *dest_proxy; - int refcnt; void * user_pointer; PortConfig media_ports[2]; MSMediaStreamSessions sessions[2]; /*the rtp, srtp, zrtp contexts for each stream*/ @@ -252,6 +250,8 @@ struct _LinphoneCall bool_t paused_by_app; }; +BELLE_SIP_DECLARE_VPTR(LinphoneCall); + LinphoneCall * linphone_call_new_outgoing(struct _LinphoneCore *lc, LinphoneAddress *from, LinphoneAddress *to, const LinphoneCallParams *params, LinphoneProxyConfig *cfg); LinphoneCall * linphone_call_new_incoming(struct _LinphoneCore *lc, LinphoneAddress *from, LinphoneAddress *to, SalOp *op); @@ -402,12 +402,8 @@ extern SalCallbacks linphone_sal_callbacks; bool_t linphone_core_rtcp_enabled(const LinphoneCore *lc); bool_t linphone_core_symmetric_rtp_enabled(LinphoneCore*lc); -LinphoneCall * is_a_linphone_call(void *user_pointer); -LinphoneProxyConfig * is_a_linphone_proxy_config(void *user_pointer); - void linphone_core_queue_task(LinphoneCore *lc, belle_sip_source_func_t task_fun, void *data, const char *task_description); -static const int linphone_proxy_config_magic=0x7979; LINPHONE_PUBLIC bool_t linphone_proxy_config_address_equal(const LinphoneAddress *a, const LinphoneAddress *b); LINPHONE_PUBLIC bool_t linphone_proxy_config_is_server_config_changed(const LinphoneProxyConfig* obj); void _linphone_proxy_config_unregister(LinphoneProxyConfig *obj); @@ -418,7 +414,8 @@ void linphone_chat_message_destroy(LinphoneChatMessage* msg); struct _LinphoneProxyConfig { - int magic; + belle_sip_object_t base; + void *user_data; struct _LinphoneCore *lc; char *reg_proxy; char *reg_identity; @@ -447,7 +444,6 @@ struct _LinphoneProxyConfig bool_t pad; uint8_t avpf_rr_interval; uint8_t quality_reporting_interval; - void* user_data; time_t deletion_date; LinphonePrivacyMask privacy; /*use to check if server config has changed between edit() and done()*/ @@ -457,6 +453,8 @@ struct _LinphoneProxyConfig }; +BELLE_SIP_DECLARE_VPTR(LinphoneProxyConfig); + struct _LinphoneAuthInfo { char *username; @@ -925,7 +923,9 @@ BELLE_SIP_TYPE_ID(LinphoneContactSearch), BELLE_SIP_TYPE_ID(LinphoneContactProvider), BELLE_SIP_TYPE_ID(LinphoneLDAPContactProvider), BELLE_SIP_TYPE_ID(LinphoneLDAPContactSearch), -BELLE_SIP_TYPE_ID(LinphoneChatMessage) +BELLE_SIP_TYPE_ID(LinphoneChatMessage), +BELLE_SIP_TYPE_ID(LinphoneProxyConfig), +BELLE_SIP_TYPE_ID(LinphoneCall) BELLE_SIP_DECLARE_TYPES_END diff --git a/coreapi/proxy.c b/coreapi/proxy.c index d66dd30fd..4c21d61c7 100644 --- a/coreapi/proxy.c +++ b/coreapi/proxy.c @@ -99,8 +99,6 @@ static void linphone_proxy_config_init(LinphoneCore* lc, LinphoneProxyConfig *ob const char *contact_params = lc ? lp_config_get_default_string(lc->config, "proxy", "contact_parameters", NULL) : NULL; const char *contact_uri_params = lc ? lp_config_get_default_string(lc->config, "proxy", "contact_uri_parameters", NULL) : NULL; - memset(obj, 0, sizeof(LinphoneProxyConfig)); - obj->magic = linphone_proxy_config_magic; obj->expires = lc ? lp_config_get_default_int(lc->config, "proxy", "reg_expires", 3600) : 3600; obj->reg_sendregister = lc ? lp_config_get_default_int(lc->config, "proxy", "reg_sendregister", 0) : 0; obj->dial_prefix = dial_prefix ? ms_strdup(dial_prefix) : NULL; @@ -109,6 +107,7 @@ static void linphone_proxy_config_init(LinphoneCore* lc, LinphoneProxyConfig *ob obj->reg_identity = identity ? ms_strdup(identity) : NULL; obj->reg_proxy = proxy ? ms_strdup(proxy) : NULL; obj->reg_route = route ? ms_strdup(route) : NULL; + obj->domain = NULL; obj->realm = realm ? ms_strdup(realm) : NULL; obj->quality_reporting_enabled = lc ? lp_config_get_default_int(lc->config, "proxy", "quality_reporting_enabled", 0) : 0; obj->quality_reporting_collector = quality_reporting_collector ? ms_strdup(quality_reporting_collector) : NULL; @@ -133,20 +132,24 @@ LinphoneProxyConfig *linphone_proxy_config_new() { return linphone_core_create_proxy_config(NULL); } +static void _linphone_proxy_config_destroy(LinphoneProxyConfig *obj); + +BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneProxyConfig); + +BELLE_SIP_INSTANCIATE_VPTR(LinphoneProxyConfig, belle_sip_object_t, + (belle_sip_object_destroy_t)_linphone_proxy_config_destroy, + NULL, // clone + NULL, // marshal + FALSE +); + LinphoneProxyConfig * linphone_core_create_proxy_config(LinphoneCore *lc) { - LinphoneProxyConfig *obj=NULL; - obj=ms_new(LinphoneProxyConfig,1); + LinphoneProxyConfig *obj = belle_sip_object_new(LinphoneProxyConfig); linphone_proxy_config_init(lc,obj); return obj; } -/** - * Destroys a proxy config. - * - * @note: LinphoneProxyConfig that have been removed from LinphoneCore with - * linphone_core_remove_proxy_config() must not be freed. -**/ -void linphone_proxy_config_destroy(LinphoneProxyConfig *obj){ +void _linphone_proxy_config_destroy(LinphoneProxyConfig *obj){ if (obj->reg_proxy!=NULL) ms_free(obj->reg_proxy); if (obj->reg_identity!=NULL) ms_free(obj->reg_identity); if (obj->reg_route!=NULL) ms_free(obj->reg_route); @@ -162,7 +165,26 @@ void linphone_proxy_config_destroy(LinphoneProxyConfig *obj){ if (obj->contact_uri_params) ms_free(obj->contact_uri_params); if (obj->saved_proxy!=NULL) linphone_address_destroy(obj->saved_proxy); if (obj->saved_identity!=NULL) linphone_address_destroy(obj->saved_identity); - ms_free(obj); +} + +/** + * Destroys a proxy config. + * @deprecated + * + * @note: LinphoneProxyConfig that have been removed from LinphoneCore with + * linphone_core_remove_proxy_config() must not be freed. +**/ +void linphone_proxy_config_destroy(LinphoneProxyConfig *cfg) { + belle_sip_object_unref(cfg); +} + +LinphoneProxyConfig *linphone_proxy_config_ref(LinphoneProxyConfig *cfg) { + belle_sip_object_ref(cfg); + return cfg; +} + +void linphone_proxy_config_unref(LinphoneProxyConfig *cfg) { + belle_sip_object_unref(cfg); } /** @@ -1498,12 +1520,12 @@ void linphone_account_creator_destroy(LinphoneAccountCreator *obj){ } } -void linphone_proxy_config_set_user_data(LinphoneProxyConfig *cr, void * ud) { - cr->user_data=ud; +void linphone_proxy_config_set_user_data(LinphoneProxyConfig *cfg, void *ud) { + cfg->user_data = ud; } -void * linphone_proxy_config_get_user_data(LinphoneProxyConfig *cr) { - return cr->user_data; +void * linphone_proxy_config_get_user_data(const LinphoneProxyConfig *cfg) { + return cfg->user_data; } void linphone_proxy_config_set_state(LinphoneProxyConfig *cfg, LinphoneRegistrationState state, const char *message){ From 293ed89daab2458e327c609158d84b3fcfc489be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Grisez?= Date: Thu, 21 Aug 2014 15:51:50 +0200 Subject: [PATCH 41/43] Delete CU_ASSERT_PTR_NOT_NULL while H264 detection --- tester/call_tester.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tester/call_tester.c b/tester/call_tester.c index e8ab0d021..47606b7a3 100644 --- a/tester/call_tester.c +++ b/tester/call_tester.c @@ -2811,8 +2811,8 @@ static void record_call(const char *filename, bool_t enableVideo) { #ifdef VIDEO_ENABLED if(enableVideo) { - if((CU_ASSERT_PTR_NOT_NULL(linphone_core_find_payload_type(marie->lc, "H264", -1, -1))) - && (CU_ASSERT_PTR_NOT_NULL(linphone_core_find_payload_type(pauline->lc, "H264", -1, -1)))) { + if((linphone_core_find_payload_type(marie->lc, "H264", -1, -1) != NULL) + && (linphone_core_find_payload_type(pauline->lc, "H264", -1, -1) != NULL)) { linphone_call_params_enable_video(marieParams, TRUE); linphone_call_params_enable_video(paulineParams, TRUE); disable_all_video_codecs_except_one(marie->lc, "H264"); From c68dd94acbac973fa0face6c78460d2cad628bcf Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Thu, 21 Aug 2014 17:01:55 +0200 Subject: [PATCH 42/43] allow notification of registration_state_changed callback for removed proxy configs. --- coreapi/callbacks.c | 8 ++------ coreapi/linphonecore.c | 5 +++-- coreapi/private.h | 1 + coreapi/proxy.c | 22 +++++++++++++--------- gtk/main.c | 2 +- oRTP | 2 +- 6 files changed, 21 insertions(+), 19 deletions(-) diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c index c64a5d7e3..7a09fa76e 100644 --- a/coreapi/callbacks.c +++ b/coreapi/callbacks.c @@ -843,8 +843,8 @@ static void register_success(SalOp *op, bool_t registered){ LinphoneProxyConfig *cfg=(LinphoneProxyConfig*)sal_op_get_user_pointer(op); char *msg; - if (!cfg || cfg->deletion_date!=0){ - ms_message("Registration success for removed proxy config, ignored"); + if (!cfg){ + ms_message("Registration success for deleted proxy config, ignored"); return; } linphone_proxy_config_set_state(cfg, registered ? LinphoneRegistrationOk : LinphoneRegistrationCleared , @@ -868,10 +868,6 @@ static void register_failure(SalOp *op){ ms_warning("Registration failed for unknown proxy config."); return ; } - if (cfg->deletion_date!=0){ - ms_message("Registration failed for removed proxy config, ignored"); - return; - } if (details==NULL) details=_("no response timeout"); diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 67582a2b0..eb137bdd9 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -2200,9 +2200,10 @@ static void proxy_update(LinphoneCore *lc){ for(elem=lc->sip_conf.deleted_proxies;elem!=NULL;elem=next){ LinphoneProxyConfig* cfg = (LinphoneProxyConfig*)elem->data; next=elem->next; - if (ms_time(NULL) - cfg->deletion_date > 5) { + if (ms_time(NULL) - cfg->deletion_date > 32) { lc->sip_conf.deleted_proxies =ms_list_remove_link(lc->sip_conf.deleted_proxies,elem); - ms_message("clearing proxy config for [%s]",linphone_proxy_config_get_addr(cfg)); + ms_message("Proxy config for [%s] is definitely removed from core.",linphone_proxy_config_get_addr(cfg)); + _linphone_proxy_config_release_ops(cfg); linphone_proxy_config_destroy(cfg); } } diff --git a/coreapi/private.h b/coreapi/private.h index 14e86e48b..be8d8667f 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -407,6 +407,7 @@ void linphone_core_queue_task(LinphoneCore *lc, belle_sip_source_func_t task_fun LINPHONE_PUBLIC bool_t linphone_proxy_config_address_equal(const LinphoneAddress *a, const LinphoneAddress *b); LINPHONE_PUBLIC bool_t linphone_proxy_config_is_server_config_changed(const LinphoneProxyConfig* obj); void _linphone_proxy_config_unregister(LinphoneProxyConfig *obj); +void _linphone_proxy_config_release_ops(LinphoneProxyConfig *obj); /*chat*/ void linphone_chat_message_destroy(LinphoneChatMessage* msg); diff --git a/coreapi/proxy.c b/coreapi/proxy.c index 4c21d61c7..c96544e8b 100644 --- a/coreapi/proxy.c +++ b/coreapi/proxy.c @@ -149,6 +149,17 @@ LinphoneProxyConfig * linphone_core_create_proxy_config(LinphoneCore *lc) { return obj; } +void _linphone_proxy_config_release_ops(LinphoneProxyConfig *obj){ + if (obj->op) { + sal_op_release(obj->op); + obj->op=NULL; + } + if (obj->publish_op){ + sal_op_release(obj->publish_op); + obj->publish_op=NULL; + } +} + void _linphone_proxy_config_destroy(LinphoneProxyConfig *obj){ if (obj->reg_proxy!=NULL) ms_free(obj->reg_proxy); if (obj->reg_identity!=NULL) ms_free(obj->reg_identity); @@ -159,12 +170,11 @@ void _linphone_proxy_config_destroy(LinphoneProxyConfig *obj){ if (obj->realm!=NULL) ms_free(obj->realm); if (obj->type!=NULL) ms_free(obj->type); if (obj->dial_prefix!=NULL) ms_free(obj->dial_prefix); - if (obj->op) sal_op_release(obj->op); - if (obj->publish_op) sal_op_release(obj->publish_op); if (obj->contact_params) ms_free(obj->contact_params); if (obj->contact_uri_params) ms_free(obj->contact_uri_params); if (obj->saved_proxy!=NULL) linphone_address_destroy(obj->saved_proxy); if (obj->saved_identity!=NULL) linphone_address_destroy(obj->saved_identity); + _linphone_proxy_config_release_ops(obj); } /** @@ -467,9 +477,6 @@ static void linphone_proxy_config_register(LinphoneProxyConfig *obj){ linphone_proxy_config_set_state(obj,LinphoneRegistrationCleared,"Registration cleared"); } _linphone_proxy_config_unregister(obj); - - - } } @@ -1156,10 +1163,7 @@ void linphone_core_remove_proxy_config(LinphoneCore *lc, LinphoneProxyConfig *cf linphone_proxy_config_edit(cfg); linphone_proxy_config_enable_register(cfg,FALSE); linphone_proxy_config_done(cfg); - linphone_proxy_config_update(cfg); /*so that it has an effect*/ - - /*as cfg no longer in proxies, unregister will never be issued*/ - _linphone_proxy_config_unregister(cfg); + linphone_proxy_config_update(cfg); } if (lc->default_proxy==cfg){ lc->default_proxy=NULL; diff --git a/gtk/main.c b/gtk/main.c index a08681dde..2886f1d8d 100644 --- a/gtk/main.c +++ b/gtk/main.c @@ -1540,7 +1540,7 @@ static void update_registration_status(LinphoneProxyConfig *cfg, LinphoneRegistr }while(gtk_tree_model_iter_next(model,&iter)); } if (!found) { - g_warning("Could not find proxy config in combo box of identities."); + /*ignored, this is a notification for a removed proxy config.*/ return; } switch (rs){ diff --git a/oRTP b/oRTP index 007016485..49fc68957 160000 --- a/oRTP +++ b/oRTP @@ -1 +1 @@ -Subproject commit 00701648593b0fce93b3d519e281dd6f547db670 +Subproject commit 49fc68957126d1126be1eb0fcaaa6153480e93e4 From aa5f676dcdb70a68b3c6cb509f187e8e1622ef6a Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Thu, 21 Aug 2014 17:50:31 +0200 Subject: [PATCH 43/43] Improve fetching of the local IP to take into account the destination. --- coreapi/linphonecall.c | 59 ++++++++++++++++++++++++++++++++++++++++-- coreapi/linphonecore.c | 42 ++---------------------------- coreapi/private.h | 1 - 3 files changed, 59 insertions(+), 43 deletions(-) diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index dc339f09d..3e584318d 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -645,6 +645,61 @@ static void linphone_call_outgoing_select_ip_version(LinphoneCall *call, Linphon }else call->af=AF_INET; } +/** + * Fill the local ip that routes to the internet according to the destination, or guess it by other special means (upnp). + */ +static void linphone_call_get_local_ip(LinphoneCall *call, const LinphoneAddress *remote_addr){ + const char *ip; + int af = call->af; + const char *dest = NULL; + if (call->dest_proxy == NULL) { + struct addrinfo hints; + struct addrinfo *res = NULL; + int err; + const char *domain = linphone_address_get_domain(remote_addr); + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; + hints.ai_flags = AI_NUMERICHOST; + err = getaddrinfo(domain, NULL, &hints, &res); + if (err == 0) { + dest = domain; + } + } + if (linphone_core_get_firewall_policy(call->core)==LinphonePolicyUseNatAddress + && (ip=linphone_core_get_nat_address_resolved(call->core))!=NULL){ + strncpy(call->localip,ip,LINPHONE_IPADDR_SIZE); + return; + } +#ifdef BUILD_UPNP + else if (call->core->upnp != NULL && linphone_core_get_firewall_policy(call->core)==LinphonePolicyUseUpnp && + linphone_upnp_context_get_state(call->core->upnp) == LinphoneUpnpStateOk) { + ip = linphone_upnp_context_get_external_ipaddress(call->core->upnp); + strncpy(call->localip,ip,LINPHONE_IPADDR_SIZE); + return; + } +#endif //BUILD_UPNP + if (af==AF_UNSPEC){ + if (linphone_core_ipv6_enabled(call->core)){ + bool_t has_ipv6; + has_ipv6=linphone_core_get_local_ip_for(AF_INET6,dest,call->localip)==0; + if (strcmp(call->localip,"::1")!=0) + return; /*this machine has real ipv6 connectivity*/ + if (linphone_core_get_local_ip_for(AF_INET,dest,call->localip)==0 && strcmp(call->localip,"127.0.0.1")!=0) + return; /*this machine has only ipv4 connectivity*/ + if (has_ipv6){ + /*this machine has only local loopback for both ipv4 and ipv6, so prefer ipv6*/ + strncpy(call->localip,"::1",LINPHONE_IPADDR_SIZE); + return; + } + } + /*in all other cases use IPv4*/ + af=AF_INET; + } + if (linphone_core_get_local_ip_for(af,dest,call->localip)==0) + return; +} + static void linphone_call_destroy(LinphoneCall *obj); BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneCall); @@ -662,7 +717,7 @@ LinphoneCall * linphone_call_new_outgoing(struct _LinphoneCore *lc, LinphoneAddr call->dir=LinphoneCallOutgoing; call->core=lc; linphone_call_outgoing_select_ip_version(call,to,cfg); - linphone_core_get_local_ip(lc,call->af,call->localip); + linphone_call_get_local_ip(call, to); linphone_call_init_common(call,from,to); _linphone_call_params_copy(&call->params,params); @@ -748,7 +803,7 @@ LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *fro } linphone_address_clean(from); - linphone_core_get_local_ip(lc,call->af,call->localip); + linphone_call_get_local_ip(call, from); linphone_call_init_common(call, from, to); call->log->call_id=ms_strdup(sal_op_get_call_id(op)); /*must be known at that time*/ call->dest_proxy = linphone_core_lookup_known_proxy(call->core, to); diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index eb137bdd9..a3244e59d 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -1522,44 +1522,6 @@ int linphone_core_set_primary_contact(LinphoneCore *lc, const char *contact) } -/*Returns the local ip that routes to the internet, or guessed by other special means (upnp)*/ -/*result must be an array of chars at least LINPHONE_IPADDR_SIZE */ -void linphone_core_get_local_ip(LinphoneCore *lc, int af, char *result){ - const char *ip; - if (linphone_core_get_firewall_policy(lc)==LinphonePolicyUseNatAddress - && (ip=linphone_core_get_nat_address_resolved(lc))!=NULL){ - strncpy(result,ip,LINPHONE_IPADDR_SIZE); - return; - } -#ifdef BUILD_UPNP - else if (lc->upnp != NULL && linphone_core_get_firewall_policy(lc)==LinphonePolicyUseUpnp && - linphone_upnp_context_get_state(lc->upnp) == LinphoneUpnpStateOk) { - ip = linphone_upnp_context_get_external_ipaddress(lc->upnp); - strncpy(result,ip,LINPHONE_IPADDR_SIZE); - return; - } -#endif //BUILD_UPNP - if (af==AF_UNSPEC){ - if (linphone_core_ipv6_enabled(lc)){ - bool_t has_ipv6; - has_ipv6=linphone_core_get_local_ip_for(AF_INET6,NULL,result)==0; - if (strcmp(result,"::1")!=0) - return; /*this machine has real ipv6 connectivity*/ - if (linphone_core_get_local_ip_for(AF_INET,NULL,result)==0 && strcmp(result,"127.0.0.1")!=0) - return; /*this machine has only ipv4 connectivity*/ - if (has_ipv6){ - /*this machine has only local loopback for both ipv4 and ipv6, so prefer ipv6*/ - strncpy(result,"::1",LINPHONE_IPADDR_SIZE); - return; - } - } - /*in all other cases use IPv4*/ - af=AF_INET; - } - if (linphone_core_get_local_ip_for(af,NULL,result)==0) - return; -} - static void update_primary_contact(LinphoneCore *lc){ char *guessed=NULL; char tmp[LINPHONE_IPADDR_SIZE]; @@ -1574,7 +1536,7 @@ static void update_primary_contact(LinphoneCore *lc){ ms_error("Could not parse identity contact !"); url=linphone_address_new("sip:unknown@unkwownhost"); } - linphone_core_get_local_ip(lc, AF_UNSPEC, tmp); + linphone_core_get_local_ip_for(AF_UNSPEC, NULL, tmp); if (strcmp(tmp,"127.0.0.1")==0 || strcmp(tmp,"::1")==0 ){ ms_warning("Local loopback network only !"); lc->sip_conf.loopback_only=TRUE; @@ -2170,7 +2132,7 @@ static void monitor_network_state(LinphoneCore *lc, time_t curtime){ /* only do the network up checking every five seconds */ if (lc->network_last_check==0 || (curtime-lc->network_last_check)>=5){ - linphone_core_get_local_ip(lc,AF_UNSPEC,newip); + linphone_core_get_local_ip_for(AF_UNSPEC,NULL,newip); if (strcmp(newip,"::1")!=0 && strcmp(newip,"127.0.0.1")!=0){ new_status=TRUE; }else new_status=FALSE; /*no network*/ diff --git a/coreapi/private.h b/coreapi/private.h index be8d8667f..1ada4a618 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -292,7 +292,6 @@ void linphone_core_update_friends_subscriptions(LinphoneCore *lc, LinphoneProxyC int parse_hostname_to_addr(const char *server, struct sockaddr_storage *ss, socklen_t *socklen, int default_port); -void linphone_core_get_local_ip(LinphoneCore *lc, int af, char *result); bool_t host_has_ipv6_network(); bool_t lp_spawn_command_line_sync(const char *command, char **result,int *command_ret);