From 85b5ca097ad41b7c33919780b265f2531b38e7c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Grisez?= Date: Thu, 12 Jan 2017 17:19:27 +0100 Subject: [PATCH] Reworking of Liblinphone API * Introduction of LinphoneFactory singleton class to create core-independent object like LinphoneAddress or LinphoneVcard. * Make several C structures inherite from belle_sip_object_t class: * LinphoneCore * LinphoneVcard * LinphoneAuthInfo * Creation of the LinphoneCoreCbs class that enable to store the callbacks used by LinphoneCore. --- coreapi/CMakeLists.txt | 1 + coreapi/address.c | 6 +- coreapi/authentication.c | 78 +++-- coreapi/chat.c | 5 + coreapi/conference.cc | 18 +- coreapi/factory.c | 79 +++++ coreapi/friend.c | 13 +- coreapi/linphonecore.c | 239 +++++++++++-- coreapi/private.h | 31 +- coreapi/vcard.cc | 74 ++-- coreapi/vtables.c | 53 ++- include/CMakeLists.txt | 1 + include/linphone/address.h | 4 +- include/linphone/core.h | 578 ++++++++++++++++++++++++++++---- include/linphone/event.h | 18 +- include/linphone/factory.h | 130 +++++++ include/linphone/vcard.h | 25 +- tester/call_single_tester.c | 2 +- tester/presence_server_tester.c | 9 +- tester/presence_tester.c | 8 +- 20 files changed, 1185 insertions(+), 187 deletions(-) create mode 100644 coreapi/factory.c create mode 100644 include/linphone/factory.h diff --git a/coreapi/CMakeLists.txt b/coreapi/CMakeLists.txt index 7caf1ab78..0f012bdaa 100644 --- a/coreapi/CMakeLists.txt +++ b/coreapi/CMakeLists.txt @@ -78,6 +78,7 @@ set(LINPHONE_SOURCE_FILES_C enum.c error_info.c event.c + factory.c friend.c friendlist.c im_notif_policy.c diff --git a/coreapi/address.c b/coreapi/address.c index 956f89cee..26b4eb9a1 100644 --- a/coreapi/address.c +++ b/coreapi/address.c @@ -21,13 +21,17 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "linphone/lpconfig.h" #include "private.h" -LinphoneAddress * linphone_address_new(const char *addr){ +LinphoneAddress * _linphone_address_new(const char *addr){ SalAddress *saddr=sal_address_new(addr); if (saddr==NULL) ms_error("Cannot create LinphoneAddress, bad uri [%s]",addr); return saddr; } +LinphoneAddress * linphone_address_new(const char *addr) { + return _linphone_address_new(addr); +} + LinphoneAddress * linphone_address_clone(const LinphoneAddress *addr){ return sal_address_clone(addr); } diff --git a/coreapi/authentication.c b/coreapi/authentication.c index c66ec2017..fe7adba61 100644 --- a/coreapi/authentication.c +++ b/coreapi/authentication.c @@ -26,13 +26,22 @@ #include "private.h" #include "linphone/lpconfig.h" -/** - * @addtogroup authentication - * @{ -**/ +static void _linphone_auth_info_uninit(LinphoneAuthInfo *obj); +static void _linphone_auth_info_copy(LinphoneAuthInfo *dst, const LinphoneAuthInfo *src); + +BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneAuthInfo); +BELLE_SIP_DECLARE_VPTR(LinphoneAuthInfo); +BELLE_SIP_INSTANCIATE_VPTR( + LinphoneAuthInfo, + belle_sip_object_t, + _linphone_auth_info_uninit, // destroy + _linphone_auth_info_copy, // clone + NULL, // marshal + FALSE +); LinphoneAuthInfo *linphone_auth_info_new(const char *username, const char *userid, const char *passwd, const char *ha1, const char *realm, const char *domain){ - LinphoneAuthInfo *obj=ms_new0(LinphoneAuthInfo,1); + LinphoneAuthInfo *obj=belle_sip_object_new(LinphoneAuthInfo); if (username!=NULL && (strlen(username)>0) ) obj->username=ms_strdup(username); if (userid!=NULL && (strlen(userid)>0)) obj->userid=ms_strdup(userid); if (passwd!=NULL && (strlen(passwd)>0)) obj->passwd=ms_strdup(passwd); @@ -42,19 +51,29 @@ LinphoneAuthInfo *linphone_auth_info_new(const char *username, const char *useri return obj; } +static void _linphone_auth_info_copy(LinphoneAuthInfo *dst, const LinphoneAuthInfo *src) { + if (src->username) dst->username = ms_strdup(src->username); + if (src->userid) dst->userid = ms_strdup(src->userid); + if (src->passwd) dst->passwd = ms_strdup(src->passwd); + if (src->ha1) dst->ha1 = ms_strdup(src->ha1); + if (src->realm) dst->realm = ms_strdup(src->realm); + if (src->domain) dst->domain = ms_strdup(src->domain); + if (src->tls_cert) dst->tls_cert = ms_strdup(src->tls_cert); + if (src->tls_key) dst->tls_key = ms_strdup(src->tls_key); + if (src->tls_cert_path) dst->tls_cert_path = ms_strdup(src->tls_cert_path); + if (src->tls_key_path) dst->tls_key_path = ms_strdup(src->tls_key_path); +} + LinphoneAuthInfo *linphone_auth_info_clone(const LinphoneAuthInfo *ai){ - LinphoneAuthInfo *obj=ms_new0(LinphoneAuthInfo,1); - if (ai->username) obj->username = ms_strdup(ai->username); - if (ai->userid) obj->userid = ms_strdup(ai->userid); - if (ai->passwd) obj->passwd = ms_strdup(ai->passwd); - if (ai->ha1) obj->ha1 = ms_strdup(ai->ha1); - if (ai->realm) obj->realm = ms_strdup(ai->realm); - if (ai->domain) obj->domain = ms_strdup(ai->domain); - if (ai->tls_cert) obj->tls_cert = ms_strdup(ai->tls_cert); - if (ai->tls_key) obj->tls_key = ms_strdup(ai->tls_key); - if (ai->tls_cert_path) obj->tls_cert_path = ms_strdup(ai->tls_cert_path); - if (ai->tls_key_path) obj->tls_key_path = ms_strdup(ai->tls_key_path); - return obj; + return LINPHONE_AUTH_INFO(belle_sip_object_clone(BELLE_SIP_OBJECT(ai))); +} + +LinphoneAuthInfo *linphone_auth_info_ref(LinphoneAuthInfo *obj) { + return LINPHONE_AUTH_INFO(belle_sip_object_ref(obj)); +} + +void linphone_auth_info_unref(LinphoneAuthInfo *obj) { + belle_sip_object_unref(obj); } const char *linphone_auth_info_get_username(const LinphoneAuthInfo *i) { @@ -178,10 +197,7 @@ void linphone_auth_info_set_tls_key_path(LinphoneAuthInfo *info, const char *tls if (tls_key_path && strlen(tls_key_path) > 0) info->tls_key_path = ms_strdup(tls_key_path); } -/** - * Destroys a LinphoneAuthInfo object. -**/ -void linphone_auth_info_destroy(LinphoneAuthInfo *obj){ +static void _linphone_auth_info_uninit(LinphoneAuthInfo *obj) { if (obj->username != NULL) ms_free(obj->username); if (obj->userid != NULL) ms_free(obj->userid); if (obj->passwd != NULL) ms_free(obj->passwd); @@ -192,7 +208,13 @@ void linphone_auth_info_destroy(LinphoneAuthInfo *obj){ if (obj->tls_key != NULL) ms_free(obj->tls_key); if (obj->tls_cert_path != NULL) ms_free(obj->tls_cert_path); if (obj->tls_key_path != NULL) ms_free(obj->tls_key_path); - ms_free(obj); +} + +/** + * Destroys a LinphoneAuthInfo object. +**/ +void linphone_auth_info_destroy(LinphoneAuthInfo *obj){ + belle_sip_object_unref(obj); } void linphone_auth_info_write_config(LpConfig *config, LinphoneAuthInfo *obj, int pos) { @@ -457,11 +479,6 @@ void linphone_core_add_auth_info(LinphoneCore *lc, const LinphoneAuthInfo *info) write_auth_infos(lc); } - -/** - * This method is used to abort a user authentication request initiated by LinphoneCore - * from the auth_info_requested callback of LinphoneCoreVTable. -**/ void linphone_core_abort_authentication(LinphoneCore *lc, LinphoneAuthInfo *info){ } @@ -479,9 +496,6 @@ const bctbx_list_t *linphone_core_get_auth_info_list(const LinphoneCore *lc){ return lc->auth_info; } -/** - * Clear all authentication information. -**/ void linphone_core_clear_all_auth_info(LinphoneCore *lc){ bctbx_list_t *elem; int i; @@ -493,7 +507,3 @@ void linphone_core_clear_all_auth_info(LinphoneCore *lc){ bctbx_list_free(lc->auth_info); lc->auth_info=NULL; } - -/** - * @} -**/ diff --git a/coreapi/chat.c b/coreapi/chat.c index a484763b8..e8cfe727e 100644 --- a/coreapi/chat.c +++ b/coreapi/chat.c @@ -916,6 +916,11 @@ void linphone_chat_room_send_message2(LinphoneChatRoom *cr, LinphoneChatMessage _linphone_chat_room_send_message(cr, msg); } +void linphone_chat_room_send_message_3(LinphoneChatRoom *cr, LinphoneChatMessage *msg) { + linphone_chat_message_ref(msg); + _linphone_chat_room_send_message(cr, msg); +} + void linphone_chat_room_send_chat_message(LinphoneChatRoom *cr, LinphoneChatMessage *msg) { _linphone_chat_room_send_message(cr, msg); } diff --git a/coreapi/conference.cc b/coreapi/conference.cc index 16b9f82a4..e3f25e231 100644 --- a/coreapi/conference.cc +++ b/coreapi/conference.cc @@ -208,7 +208,7 @@ private: const char *m_focusAddr; char *m_focusContact; LinphoneCall *m_focusCall; - LinphoneCoreVTable *m_vtable; + LinphoneCoreCbs *m_coreCbs; std::list m_pendingCalls; std::list m_transferingCalls; }; @@ -625,19 +625,19 @@ RemoteConference::RemoteConference(LinphoneCore *core, const Conference::Params m_focusAddr = NULL; m_focusContact = NULL; m_focusCall = NULL; - m_vtable = NULL; + m_coreCbs = NULL; m_focusAddr = lp_config_get_string(m_core->config, "misc", "conference_focus_addr", ""); - m_vtable = linphone_core_v_table_new(); - m_vtable->call_state_changed = callStateChangedCb; - m_vtable->transfer_state_changed = transferStateChanged; - linphone_core_v_table_set_user_data(m_vtable, this); - _linphone_core_add_listener(m_core, m_vtable, FALSE, TRUE); + m_coreCbs = linphone_factory_create_core_cbs(linphone_factory_get()); + linphone_core_cbs_set_call_state_changed(m_coreCbs, callStateChangedCb); + linphone_core_cbs_set_transfer_state_changed(m_coreCbs, transferStateChanged); + linphone_core_cbs_set_user_data(m_coreCbs, this); + _linphone_core_add_callbacks(m_core, m_coreCbs, TRUE); } RemoteConference::~RemoteConference() { terminate(); - linphone_core_remove_listener(m_core, m_vtable); - linphone_core_v_table_destroy(m_vtable); + linphone_core_remove_callbacks(m_core, m_coreCbs); + linphone_core_cbs_unref(m_coreCbs); } int RemoteConference::addParticipant(LinphoneCall *call) { diff --git a/coreapi/factory.c b/coreapi/factory.c new file mode 100644 index 000000000..924d67940 --- /dev/null +++ b/coreapi/factory.c @@ -0,0 +1,79 @@ +/* +linphone +Copyright (C) 2016 Belledonne Communications + +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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "private.h" + +extern LinphoneCore *_linphone_core_new_with_config(LinphoneCoreCbs *cbs, struct _LpConfig *config, void *userdata); +extern LinphoneCoreCbs *_linphone_core_cbs_new(void); +extern LinphoneAddress *_linphone_address_new(const char *addr); + +typedef belle_sip_object_t_vptr_t LinphoneFactory_vptr_t; + +struct _LinphoneFactory { + belle_sip_object_t base; +}; + +BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneFactory); +BELLE_SIP_INSTANCIATE_VPTR(LinphoneFactory, belle_sip_object_t, + NULL, // destroy + NULL, // clone + NULL, // Marshall + FALSE +); + +static LinphoneFactory *_factory = NULL; + +static void _linphone_factory_destroying_cb(void) { + if (_factory != NULL) { + belle_sip_object_unref(_factory); + _factory = NULL; + } +} + +LinphoneFactory *linphone_factory_get(void) { + if (_factory == NULL) { + _factory = belle_sip_object_new(LinphoneFactory); + atexit(_linphone_factory_destroying_cb); + } + return _factory; +} + +LinphoneCore *linphone_factory_create_core(const LinphoneFactory *factory, LinphoneCoreCbs *cbs, + const char *config_path, const char *factory_config_path) { + LpConfig *config = lp_config_new_with_factory(config_path, factory_config_path); + LinphoneCore *lc = _linphone_core_new_with_config(cbs, config, NULL); + lp_config_unref(config); + return lc; +} + +LinphoneCore *linphone_factory_create_core_with_config(const LinphoneFactory *factory, LinphoneCoreCbs *cbs, LinphoneConfig *config) { + return _linphone_core_new_with_config(cbs, config, NULL); +} + +LinphoneCoreCbs *linphone_factory_create_core_cbs(const LinphoneFactory *factory) { + return _linphone_core_cbs_new(); +} + +LinphoneAddress *linphone_factory_create_address(const LinphoneFactory *factory, const char *addr) { + return _linphone_address_new(addr); +} + +LinphoneAuthInfo *linphone_factory_create_auth_info(const LinphoneFactory *factory, const char *username, const char *userid, const char *passwd, const char *ha1, const char *realm, const char *domain) { + return linphone_auth_info_new(username, userid, passwd, ha1, realm, domain); +} diff --git a/coreapi/friend.c b/coreapi/friend.c index 508adddd7..b43c2206d 100644 --- a/coreapi/friend.c +++ b/coreapi/friend.c @@ -1223,7 +1223,7 @@ void linphone_core_friends_storage_init(LinphoneCore *lc) { int ret; const char *errmsg; sqlite3 *db; - const bctbx_list_t *friends_lists = NULL; + bctbx_list_t *friends_lists = NULL; linphone_core_friends_storage_close(lc); @@ -1246,14 +1246,15 @@ void linphone_core_friends_storage_init(LinphoneCore *lc) { friends_lists = linphone_core_fetch_friends_lists_from_db(lc); if (friends_lists) { + const bctbx_list_t *it; ms_warning("Replacing current default friend list by the one(s) from the database"); - lc->friends_lists = bctbx_list_free_with_data(lc->friends_lists, (void (*)(void*))linphone_friend_list_unref); - - while (friends_lists) { - LinphoneFriendList *list = (LinphoneFriendList *)bctbx_list_get_data(friends_lists); + lc->friends_lists = bctbx_list_free_with_data(lc->friends_lists, (bctbx_list_free_func)linphone_friend_list_unref); + + for (it=friends_lists;it!=NULL;it=bctbx_list_next(it)) { + LinphoneFriendList *list = (LinphoneFriendList *)bctbx_list_get_data(it); linphone_core_add_friend_list(lc, list); - friends_lists = bctbx_list_next(friends_lists); } + friends_lists = bctbx_list_free_with_data(friends_lists, (bctbx_list_free_func)linphone_friend_list_unref); } } diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index c0ffc626f..ffe3ae33e 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -105,6 +105,7 @@ static void set_network_reachable(LinphoneCore* lc,bool_t isReachable, time_t cu static void set_sip_network_reachable(LinphoneCore* lc,bool_t isReachable, time_t curtime); static void set_media_network_reachable(LinphoneCore* lc,bool_t isReachable); static void linphone_core_run_hooks(LinphoneCore *lc); +static void linphone_core_uninit(LinphoneCore *lc); #include "enum.h" #include "contact_providers_priv.h" @@ -130,6 +131,165 @@ static void toggle_video_preview(LinphoneCore *lc, bool_t val); extern SalCallbacks linphone_sal_callbacks; + +static void _linphone_core_cbs_uninit(LinphoneCoreCbs *cbs); + +typedef belle_sip_object_t_vptr_t LinphoneCoreCbs_vptr_t; +BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneCoreCbs); +BELLE_SIP_INSTANCIATE_VPTR(LinphoneCoreCbs, belle_sip_object_t, + _linphone_core_cbs_uninit, // destroy + NULL, // clone + NULL, // Marshall + FALSE +); + +LinphoneCoreCbs *_linphone_core_cbs_new(void) { + LinphoneCoreCbs *obj = belle_sip_object_new(LinphoneCoreCbs); + obj->vtable = ms_new0(LinphoneCoreVTable, 1); + obj->autorelease = TRUE; + return obj; +} + +static void _linphone_core_cbs_uninit(LinphoneCoreCbs *cbs) { + if (cbs->autorelease) ms_free(cbs->vtable); +} + +void _linphone_core_cbs_set_v_table(LinphoneCoreCbs *cbs, LinphoneCoreVTable *vtable, bool_t autorelease) { + ms_free(cbs->vtable); + cbs->vtable = vtable; + cbs->autorelease = autorelease; +} + +LinphoneCoreCbs *linphone_core_cbs_ref(LinphoneCoreCbs *cbs) { + return (LinphoneCoreCbs *)belle_sip_object_ref(cbs); +} + +void linphone_core_cbs_unref(LinphoneCoreCbs *cbs) { + belle_sip_object_unref(cbs); +} + +void linphone_core_cbs_set_user_data(LinphoneCoreCbs *cbs, void *user_data) { + cbs->vtable->user_data = user_data; +} + +void *linphone_core_cbs_get_user_data(LinphoneCoreCbs *cbs) { + return cbs->vtable->user_data; +} + +LinphoneCoreCbs *linphone_core_get_current_callbacks(const LinphoneCore *lc) { + return lc->current_cbs; +} + +void linphone_core_cbs_set_registration_state_changed(LinphoneCoreCbs *cbs, LinphoneCoreCbsRegistrationStateChangedCb cb) { + cbs->vtable->registration_state_changed = cb; +} + +void linphone_core_cbs_set_call_state_changed(LinphoneCoreCbs *cbs, LinphoneCoreCbsCallStateChangedCb cb) { + cbs->vtable->call_state_changed = cb; +} + +void linphone_core_cbs_set_notify_presence_received(LinphoneCoreCbs *cbs, LinphoneCoreCbsNotifyPresenceReceivedCb cb) { + cbs->vtable->notify_presence_received = cb; +} + +void linphone_core_cbs_set_notify_presence_received_for_uri_or_tel(LinphoneCoreCbs *cbs, LinphoneCoreCbsNotifyPresenceReceivedForUriOrTelCb cb) { + cbs->vtable->notify_presence_received_for_uri_or_tel = cb; +} + +void linphone_core_cbs_set_new_subscription_requested(LinphoneCoreCbs *cbs, LinphoneCoreCbsNewSubscriptionRequestedCb cb) { + cbs->vtable->new_subscription_requested = cb; +} + +void linphone_core_cbs_set_authentication_requested(LinphoneCoreCbs *cbs, LinphoneCoreCbsAuthenticationRequestedCb cb) { + cbs->vtable->authentication_requested = cb; +} + +void linphone_core_cbs_set_call_log_updated(LinphoneCoreCbs *cbs, LinphoneCoreCbsCallLogUpdatedCb cb) { + cbs->vtable->call_log_updated = cb; +} + +void linphone_core_cbs_set_message_received(LinphoneCoreCbs *cbs, LinphoneCoreCbsMessageReceivedCb cb) { + cbs->vtable->message_received = cb; +} + +void linphone_core_cbs_set_is_composing_received(LinphoneCoreCbs *cbs, LinphoneCoreCbsIsComposingReceivedCb cb) { + cbs->vtable->is_composing_received = cb; +} + +void linphone_core_cbs_set_dtmf_received(LinphoneCoreCbs *cbs, LinphoneCoreCbsDtmfReceivedCb cb) { + cbs->vtable->dtmf_received = cb; +} + +void linphone_core_cbs_set_refer_received(LinphoneCoreCbs *cbs, LinphoneCoreCbsReferReceivedCb cb) { + cbs->vtable->refer_received = cb; +} + +void linphone_core_cbs_set_call_encryption_changed(LinphoneCoreCbs *cbs, LinphoneCoreCbsCallEncryptionChangedCb cb) { + cbs->vtable->call_encryption_changed = cb; +} + +void linphone_core_cbs_set_transfer_state_changed(LinphoneCoreCbs *cbs, LinphoneCoreCbsTransferStateChangedCb cb) { + cbs->vtable->transfer_state_changed = cb; +} + +void linphone_core_cbs_set_buddy_info_updated(LinphoneCoreCbs *cbs, LinphoneCoreCbsBuddyInfoUpdatedCb cb) { + cbs->vtable->buddy_info_updated = cb; +} + +void linphone_core_cbs_set_call_stats_updated(LinphoneCoreCbs *cbs, LinphoneCoreCbsCallStatsUpdatedCb cb) { + cbs->vtable->call_stats_updated = cb; +} + +void linphone_core_cbs_set_info_received(LinphoneCoreCbs *cbs, LinphoneCoreCbsInfoReceivedCb cb) { + cbs->vtable->info_received = cb; +} + +void linphone_core_cbs_set_subscription_state_changed(LinphoneCoreCbs *cbs, LinphoneCoreCbsSubscriptionStateChangedCb cb) { + cbs->vtable->subscription_state_changed = cb; +} + +void linphone_core_cbs_set_notify_received(LinphoneCoreCbs *cbs, LinphoneCoreCbsNotifyReceivedCb cb) { + cbs->vtable->notify_received = cb; +} + +void linphone_core_cbs_set_publish_state_changed(LinphoneCoreCbs *cbs, LinphoneCoreCbsPublishStateChangedCb cb) { + cbs->vtable->publish_state_changed = cb; +} + +void linphone_core_cbs_set_configuring_status(LinphoneCoreCbs *cbs, LinphoneCoreCbsConfiguringStatusCb cb) { + cbs->vtable->configuring_status = cb; +} + +void linphone_core_cbs_set_network_reachable(LinphoneCoreCbs *cbs, LinphoneCoreCbsNetworkReachableCb cb) { + cbs->vtable->network_reachable = cb; +} + +void linphone_core_cbs_set_log_collection_upload_state_changed(LinphoneCoreCbs *cbs, LinphoneCoreCbsLogCollectionUploadStateChangedCb cb) { + cbs->vtable->log_collection_upload_state_changed = cb; +} + +void linphone_core_cbs_set_log_collection_upload_progress_indication(LinphoneCoreCbs *cbs, LinphoneCoreCbsLogCollectionUploadProgressIndicationCb cb) { + cbs->vtable->log_collection_upload_progress_indication = cb; +} + +void linphone_core_cbs_set_friend_list_created(LinphoneCoreCbs *cbs, LinphoneCoreCbsFriendListCreatedCb cb) { + cbs->vtable->friend_list_created = cb; +} + +void linphone_core_cbs_set_friend_list_removed(LinphoneCoreCbs *cbs, LinphoneCoreCbsFriendListRemovedCb cb) { + cbs->vtable->friend_list_removed = cb; +} + + +typedef belle_sip_object_t_vptr_t LinphoneCore_vptr_t; +BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneCore); +BELLE_SIP_INSTANCIATE_VPTR(LinphoneCore, belle_sip_object_t, + linphone_core_uninit, // destroy + NULL, // clone + NULL, // Marshall + FALSE +); + void lc_callback_obj_init(LCCallbackObj *obj,LinphoneCoreCbFunc func,void* ud) { obj->_func=func; obj->_user_data=ud; @@ -1771,10 +1931,9 @@ static void linphone_core_internal_subscription_state_changed(LinphoneCore *lc, } } -static void linphone_core_init(LinphoneCore * lc, const LinphoneCoreVTable *vtable, LpConfig *config, void * userdata){ +static void linphone_core_init(LinphoneCore * lc, LinphoneCoreCbs *cbs, LpConfig *config, void * userdata){ const char *remote_provisioning_uri = NULL; - LinphoneCoreVTable* local_vtable= linphone_core_v_table_new(); - LinphoneCoreVTable *internal_vtable = linphone_core_v_table_new(); + LinphoneCoreCbs *internal_cbs = _linphone_core_cbs_new(); ms_message("Initializing LinphoneCore %s", linphone_core_get_version()); @@ -1784,11 +1943,20 @@ static void linphone_core_init(LinphoneCore * lc, const LinphoneCoreVTable *vtab linphone_task_list_init(&lc->hooks); - internal_vtable->notify_received = linphone_core_internal_notify_received; - internal_vtable->subscription_state_changed = linphone_core_internal_subscription_state_changed; - _linphone_core_add_listener(lc, internal_vtable, TRUE, TRUE); - memcpy(local_vtable,vtable,sizeof(LinphoneCoreVTable)); - _linphone_core_add_listener(lc, local_vtable, TRUE, FALSE); + linphone_core_cbs_set_notify_received(internal_cbs, linphone_core_internal_notify_received); + linphone_core_cbs_set_subscription_state_changed(internal_cbs, linphone_core_internal_subscription_state_changed); + _linphone_core_add_callbacks(lc, internal_cbs, TRUE); + belle_sip_object_unref(internal_cbs); + + + if (cbs != NULL) { + _linphone_core_add_callbacks(lc, cbs, FALSE); + } else { + LinphoneCoreCbs *fallback_cbs = linphone_factory_create_core_cbs(linphone_factory_get()); + _linphone_core_add_callbacks(lc, fallback_cbs, FALSE); + belle_sip_object_unref(fallback_cbs); + } + linphone_core_set_state(lc,LinphoneGlobalStartup,"Starting up"); ortp_init(); @@ -1838,7 +2006,24 @@ static void linphone_core_init(LinphoneCore * lc, const LinphoneCoreVTable *vtab } // else linphone_core_start will be called after the remote provisioning (see linphone_core_iterate) } -LinphoneCore *linphone_core_new(const LinphoneCoreVTable *vtable, +LinphoneCore *_linphone_core_new_with_config(LinphoneCoreCbs *cbs, struct _LpConfig *config, void *userdata) { + LinphoneCore *core = belle_sip_object_new(LinphoneCore); + linphone_core_init(core, cbs, config, userdata); + return core; +} + +LinphoneCore *linphone_core_new_with_config(const LinphoneCoreVTable *vtable, struct _LpConfig *config, void *userdata) { + LinphoneCoreCbs *cbs = linphone_factory_create_core_cbs(linphone_factory_get());; + LinphoneCoreVTable *local_vtable = linphone_core_v_table_new(); + LinphoneCore *core = NULL; + if (vtable != NULL) *local_vtable = *vtable; + _linphone_core_cbs_set_v_table(cbs, local_vtable, TRUE); + core = _linphone_core_new_with_config(cbs, config, userdata); + linphone_core_cbs_unref(cbs); + return core; +} + +static LinphoneCore *_linphone_core_new(const LinphoneCoreVTable *vtable, const char *config_path, const char *factory_config_path, void * userdata) { LinphoneCore *lc; LpConfig *config = lp_config_new_with_factory(config_path, factory_config_path); @@ -1847,10 +2032,17 @@ LinphoneCore *linphone_core_new(const LinphoneCoreVTable *vtable, return lc; } -LinphoneCore *linphone_core_new_with_config(const LinphoneCoreVTable *vtable, struct _LpConfig *config, void *userdata) { - LinphoneCore *core = ms_new0(LinphoneCore, 1); - linphone_core_init(core, vtable, config, userdata); - return core; +LinphoneCore *linphone_core_new(const LinphoneCoreVTable *vtable, + const char *config_path, const char *factory_config_path, void * userdata) { + return _linphone_core_new(vtable, config_path, factory_config_path, userdata); +} + +LinphoneCore *linphone_core_ref(LinphoneCore *lc) { + return (LinphoneCore *)belle_sip_object_ref(BELLE_SIP_OBJECT(lc)); +} + +void linphone_core_unref(LinphoneCore *lc) { + belle_sip_object_unref(BELLE_SIP_OBJECT(lc)); } const bctbx_list_t *linphone_core_get_audio_codecs(const LinphoneCore *lc) { @@ -2347,12 +2539,12 @@ int linphone_core_set_sip_transports(LinphoneCore *lc, const LCSipTransports * t return _linphone_core_apply_transports(lc); } -int linphone_core_get_sip_transports(LinphoneCore *lc, LCSipTransports *tr){ +int linphone_core_get_sip_transports(LinphoneCore *lc, LinphoneSipTransports *tr){ memcpy(tr,&lc->sip_conf.transports,sizeof(*tr)); return 0; } -void linphone_core_get_sip_transports_used(LinphoneCore *lc, LCSipTransports *tr){ +void linphone_core_get_sip_transports_used(LinphoneCore *lc, LinphoneSipTransports *tr){ tr->udp_port=sal_get_listening_port(lc->sal,SalTransportUDP); tr->tcp_port=sal_get_listening_port(lc->sal,SalTransportTCP); tr->tls_port=sal_get_listening_port(lc->sal,SalTransportTLS); @@ -4440,9 +4632,6 @@ bool_t linphone_core_mic_enabled(LinphoneCore *lc) { return !call->audio_muted; } -// returns rtp transmission status for an active stream -// if audio is muted and config parameter rtp_no_xmit_on_audio_mute -// was set on then rtp transmission is also muted bool_t linphone_core_is_rtp_muted(LinphoneCore *lc){ LinphoneCall *call=linphone_core_get_current_call(lc); if (call==NULL){ @@ -5205,9 +5394,6 @@ void linphone_core_set_native_preview_window_id(LinphoneCore *lc, void *id){ #endif } -/** - * Can be used to disable video showing to free XV port -**/ void linphone_core_show_video(LinphoneCore *lc, bool_t show){ #ifdef VIDEO_ENABLED LinphoneCall *call=linphone_core_get_current_call(lc); @@ -5860,6 +6046,10 @@ LpConfig * linphone_core_create_lp_config(LinphoneCore *lc, const char *filename return lp_config_new(filename); } +LinphoneConfig * linphone_core_create_config(LinphoneCore *lc, const char *filename) { + return lp_config_new(filename); +} + static void linphone_core_uninit(LinphoneCore *lc) { bctbx_list_t *elem = NULL; @@ -6095,8 +6285,7 @@ ortp_socket_t linphone_core_get_sip_socket(LinphoneCore *lc){ } void linphone_core_destroy(LinphoneCore *lc){ - linphone_core_uninit(lc); - ms_free(lc); + linphone_core_unref(lc); } int linphone_core_get_calls_nb(const LinphoneCore *lc){ @@ -6268,6 +6457,10 @@ LinphoneCallParams *linphone_core_create_call_params(LinphoneCore *lc, LinphoneC return NULL; } +const char *linphone_error_to_string(LinphoneReason err){ + return linphone_reason_to_string(err); +} + void linphone_core_enable_keep_alive(LinphoneCore* lc,bool_t enable) { #ifdef BUILD_UPNP if (linphone_core_get_firewall_policy(lc)==LinphonePolicyUseUpnp) { diff --git a/coreapi/private.h b/coreapi/private.h index 02ad00503..90a7c7333 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -677,6 +677,7 @@ BELLE_SIP_DECLARE_VPTR(LinphoneProxyConfig); struct _LinphoneAuthInfo { + belle_sip_object_t base; char *username; char *realm; char *userid; @@ -950,8 +951,19 @@ void linphone_task_list_remove(LinphoneTaskList *t, LinphoneCoreIterateHook hook void linphone_task_list_run(LinphoneTaskList *t); void linphone_task_list_free(LinphoneTaskList *t); + +struct _LinphoneCoreCbs { + belle_sip_object_t base; + LinphoneCoreVTable *vtable; + bool_t autorelease; +}; + +void _linphone_core_cbs_set_v_table(LinphoneCoreCbs *cbs, LinphoneCoreVTable *vtable, bool_t autorelease); + + struct _LinphoneCore { + belle_sip_object_t base; MSFactory* factory; MSList* vtable_refs; int vtable_notify_recursion; @@ -1057,7 +1069,7 @@ struct _LinphoneCore char *file_transfer_server; const char **supported_formats; LinphoneContent *log_collection_upload_information; - LinphoneCoreVTable *current_vtable; // the latest vtable to call a callback, see linphone_core_get_current_vtable + LinphoneCoreCbs *current_cbs; // the latest LinphoneCoreCbs object to call a callback, see linphone_core_get_current_cbs() LinphoneRingtonePlayer *ringtoneplayer; #ifdef ANDROID jobject wifi_lock; @@ -1109,7 +1121,13 @@ void linphone_tunnel_destroy(LinphoneTunnel *tunnel); void linphone_tunnel_configure(LinphoneTunnel *tunnel); void linphone_tunnel_enable_logs_with_handler(LinphoneTunnel *tunnel, bool_t enabled, OrtpLogFunc logHandler); +/** + * Check if we do not have exceed the number of simultaneous call + * + * @ingroup call_control +**/ bool_t linphone_core_can_we_add_call(LinphoneCore *lc); + int linphone_core_add_call( LinphoneCore *lc, LinphoneCall *call); int linphone_core_del_call( LinphoneCore *lc, LinphoneCall *call); int linphone_core_get_calls_nb(const LinphoneCore *lc); @@ -1571,7 +1589,12 @@ BELLE_SIP_TYPE_ID(LinphoneXmlRpcSession), BELLE_SIP_TYPE_ID(LinphoneTunnelConfig), BELLE_SIP_TYPE_ID(LinphoneFriendListCbs), BELLE_SIP_TYPE_ID(LinphoneEvent), -BELLE_SIP_TYPE_ID(LinphoneNatPolicy) +BELLE_SIP_TYPE_ID(LinphoneNatPolicy), +BELLE_SIP_TYPE_ID(LinphoneCore), +BELLE_SIP_TYPE_ID(LinphoneCoreCbs), +BELLE_SIP_TYPE_ID(LinphoneFactory), +BELLE_SIP_TYPE_ID(LinphoneAuthInfo), +BELLE_SIP_TYPE_ID(LinphoneVcard), BELLE_SIP_DECLARE_TYPES_END @@ -1664,7 +1687,7 @@ void linphone_core_multicast_lock_release(LinphoneCore *lc); #endif struct _VTableReference{ - LinphoneCoreVTable *vtable; + LinphoneCoreCbs *cbs; bool_t valid; bool_t autorelease; bool_t internal; @@ -1674,7 +1697,7 @@ typedef struct _VTableReference VTableReference; void v_table_reference_destroy(VTableReference *ref); -LINPHONE_PUBLIC void _linphone_core_add_listener(LinphoneCore *lc, LinphoneCoreVTable *vtable, bool_t autorelease, bool_t internal); +LINPHONE_PUBLIC void _linphone_core_add_callbacks(LinphoneCore *lc, LinphoneCoreCbs *vtable, bool_t internal); #ifdef VIDEO_ENABLED LINPHONE_PUBLIC MSWebCam *linphone_call_get_video_device(const LinphoneCall *call); diff --git a/coreapi/vcard.cc b/coreapi/vcard.cc index f52aa1be5..4d1c8586d 100644 --- a/coreapi/vcard.cc +++ b/coreapi/vcard.cc @@ -23,6 +23,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "sal/sal.h" #include #include "linphone/core.h" +#include "private.h" #define VCARD_MD5_HASH_SIZE 16 @@ -32,17 +33,7 @@ struct _LinphoneVcardContext { void *user_data; }; -struct _LinphoneVcard { - shared_ptr belCard; - char *etag; - char *url; - unsigned char md5[VCARD_MD5_HASH_SIZE]; - bctbx_list_t *sip_addresses_cache; -}; - -#ifdef __cplusplus extern "C" { -#endif LinphoneVcardContext* linphone_vcard_context_new(void) { LinphoneVcardContext* context = ms_new0(LinphoneVcardContext, 1); @@ -67,25 +58,66 @@ void linphone_vcard_context_set_user_data(LinphoneVcardContext *context, void *d if (context) context->user_data = data; } -LinphoneVcard* linphone_vcard_new(void) { - LinphoneVcard* vCard = (LinphoneVcard*) ms_new0(LinphoneVcard, 1); +} // extern "C" + + +struct _LinphoneVcard { + belle_sip_object_t base; + shared_ptr belCard; + char *etag; + char *url; + unsigned char md5[VCARD_MD5_HASH_SIZE]; + bctbx_list_t *sip_addresses_cache; +}; + +extern "C" { + +static void _linphone_vcard_uninit(LinphoneVcard *vCard) { + if (vCard->etag) ms_free(vCard->etag); + if (vCard->url) ms_free(vCard->url); + linphone_vcard_clean_cache(vCard); + vCard->belCard.reset(); +} + +BELLE_SIP_DECLARE_VPTR(LinphoneVcard); +BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneVcard); +BELLE_SIP_INSTANCIATE_VPTR(LinphoneVcard, belle_sip_object_t, + _linphone_vcard_uninit, // destroy + NULL, // clone + NULL, // Marshall + FALSE +); + +static LinphoneVcard* _linphone_vcard_new(void) { + LinphoneVcard* vCard = belle_sip_object_new(LinphoneVcard); vCard->belCard = belcard::BelCardGeneric::create(); return vCard; } +LinphoneVcard *linphone_vcard_new(void) { + return _linphone_vcard_new(); +} + +LinphoneVcard *linphone_factory_create_vcard(LinphoneFactory *factory) { + return _linphone_vcard_new(); +} + static LinphoneVcard* linphone_vcard_new_from_belcard(shared_ptr belcard) { - LinphoneVcard* vCard = (LinphoneVcard*) ms_new0(LinphoneVcard, 1); + LinphoneVcard* vCard = belle_sip_object_new(LinphoneVcard); vCard->belCard = belcard; return vCard; } void linphone_vcard_free(LinphoneVcard *vCard) { - if (!vCard) return; - if (vCard->etag) ms_free(vCard->etag); - if (vCard->url) ms_free(vCard->url); - linphone_vcard_clean_cache(vCard); - vCard->belCard.reset(); - ms_free(vCard); + belle_sip_object_unref((belle_sip_object_t *)vCard); +} + +LinphoneVcard *linphone_vcard_ref(LinphoneVcard *vCard) { + return (LinphoneVcard *)belle_sip_object_ref((belle_sip_object_t *)vCard); +} + +void linphone_vcard_unref(LinphoneVcard *vCard) { + belle_sip_object_unref((belle_sip_object_t *)vCard); } bctbx_list_t* linphone_vcard_context_get_vcard_list_from_file(LinphoneVcardContext *context, const char *filename) { @@ -397,6 +429,4 @@ void linphone_vcard_clean_cache(LinphoneVcard *vCard) { vCard->sip_addresses_cache = NULL; } -#ifdef __cplusplus -} -#endif +} // extern "C" diff --git a/coreapi/vtables.c b/coreapi/vtables.c index d2e305acf..8677def98 100644 --- a/coreapi/vtables.c +++ b/coreapi/vtables.c @@ -38,7 +38,8 @@ void linphone_core_v_table_destroy(LinphoneCoreVTable* table) { } LinphoneCoreVTable *linphone_core_get_current_vtable(LinphoneCore *lc) { - return lc->current_vtable; + if (lc->current_cbs != NULL) return lc->current_cbs->vtable; + else return NULL; } static void cleanup_dead_vtable_refs(LinphoneCore *lc){ @@ -63,8 +64,8 @@ static void cleanup_dead_vtable_refs(LinphoneCore *lc){ bool_t has_cb = FALSE; \ lc->vtable_notify_recursion++;\ for (iterator=lc->vtable_refs; iterator!=NULL; iterator=iterator->next){\ - if ((ref=(VTableReference*)iterator->data)->valid && (lc->current_vtable=ref->vtable)->function_name) {\ - lc->current_vtable->function_name(__VA_ARGS__);\ + if ((ref=(VTableReference*)iterator->data)->valid && (lc->current_cbs=ref->cbs)->vtable->function_name) {\ + lc->current_cbs->vtable->function_name(__VA_ARGS__);\ has_cb = TRUE;\ }\ }\ @@ -76,8 +77,8 @@ static void cleanup_dead_vtable_refs(LinphoneCore *lc){ VTableReference *ref; \ lc->vtable_notify_recursion++;\ for (iterator=lc->vtable_refs; iterator!=NULL; iterator=iterator->next){\ - if ((ref=(VTableReference*)iterator->data)->valid && (lc->current_vtable=ref->vtable)->function_name && (ref->internal == internal_val)) {\ - lc->current_vtable->function_name(__VA_ARGS__);\ + if ((ref=(VTableReference*)iterator->data)->valid && (lc->current_cbs=ref->cbs)->vtable->function_name && (ref->internal == internal_val)) {\ + lc->current_cbs->vtable->function_name(__VA_ARGS__);\ }\ }\ lc->vtable_notify_recursion--; @@ -229,7 +230,7 @@ bool_t linphone_core_dtmf_received_has_listener(const LinphoneCore* lc) { bctbx_list_t* iterator; for (iterator=lc->vtable_refs; iterator!=NULL; iterator=iterator->next){ VTableReference *ref=(VTableReference*)iterator->data; - if (ref->valid && ref->vtable->dtmf_received) + if (ref->valid && ref->cbs->vtable->dtmf_received) return TRUE; } return FALSE; @@ -305,27 +306,33 @@ void linphone_core_notify_friend_list_removed(LinphoneCore *lc, LinphoneFriendLi cleanup_dead_vtable_refs(lc); } -static VTableReference * v_table_reference_new(LinphoneCoreVTable *vtable, bool_t autorelease, bool_t internal){ +static VTableReference * v_table_reference_new(LinphoneCoreCbs *cbs, bool_t internal){ VTableReference *ref=ms_new0(VTableReference,1); - ref->valid=1; - ref->autorelease=autorelease; + ref->valid=TRUE; ref->internal = internal; - ref->vtable=vtable; + ref->cbs=(LinphoneCoreCbs *)belle_sip_object_ref(cbs); return ref; } void v_table_reference_destroy(VTableReference *ref){ - if (ref->autorelease) linphone_core_v_table_destroy(ref->vtable); + belle_sip_object_unref(ref->cbs); ms_free(ref); } -void _linphone_core_add_listener(LinphoneCore *lc, LinphoneCoreVTable *vtable, bool_t autorelease, bool_t internal) { - ms_message("Vtable [%p] registered on core [%p]",vtable, lc); - lc->vtable_refs=bctbx_list_append(lc->vtable_refs,v_table_reference_new(vtable, autorelease, internal)); +void _linphone_core_add_callbacks(LinphoneCore *lc, LinphoneCoreCbs *vtable, bool_t internal) { + ms_message("Core callbacks [%p] registered on core [%p]", vtable, lc); + lc->vtable_refs=bctbx_list_append(lc->vtable_refs,v_table_reference_new(vtable, internal)); } void linphone_core_add_listener(LinphoneCore *lc, LinphoneCoreVTable *vtable){ - _linphone_core_add_listener(lc, vtable, FALSE, FALSE); + LinphoneCoreCbs *cbs = linphone_factory_create_core_cbs(linphone_factory_get()); + _linphone_core_cbs_set_v_table(cbs, vtable, FALSE); + _linphone_core_add_callbacks(lc, cbs, FALSE); + belle_sip_object_unref(cbs); +} + +void linphone_core_add_callbacks(LinphoneCore *lc, LinphoneCoreCbs *cbs) { + _linphone_core_add_callbacks(lc, cbs, FALSE); } void linphone_core_remove_listener(LinphoneCore *lc, const LinphoneCoreVTable *vtable) { @@ -333,7 +340,19 @@ void linphone_core_remove_listener(LinphoneCore *lc, const LinphoneCoreVTable *v ms_message("Vtable [%p] unregistered on core [%p]",vtable,lc); for(it=lc->vtable_refs; it!=NULL; it=it->next){ VTableReference *ref=(VTableReference*)it->data; - if (ref->vtable==vtable) - ref->valid=0; + if (ref->cbs->vtable==vtable) { + ref->valid=FALSE; + } + } +} + +void linphone_core_remove_callbacks(LinphoneCore *lc, const LinphoneCoreCbs *cbs) { + bctbx_list_t *it; + ms_message("Callbacks [%p] unregistered on core [%p]",cbs,lc); + for(it=lc->vtable_refs; it!=NULL; it=it->next){ + VTableReference *ref=(VTableReference*)it->data; + if (ref->cbs==cbs) { + ref->valid=FALSE; + } } } diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt index d1181db6c..879e2454d 100644 --- a/include/CMakeLists.txt +++ b/include/CMakeLists.txt @@ -38,6 +38,7 @@ set(HEADER_FILES dictionary.h error_info.h event.h + factory.h friend.h friendlist.h im_notif_policy.h diff --git a/include/linphone/address.h b/include/linphone/address.h index b717741bd..41dcabddf 100644 --- a/include/linphone/address.h +++ b/include/linphone/address.h @@ -122,7 +122,7 @@ LINPHONE_PUBLIC void linphone_address_clean(LinphoneAddress *uri); * Returns true if address refers to a secure location (sips) * @deprecated use linphone_address_get_secure() **/ -LINPHONE_PUBLIC bool_t linphone_address_is_secure(const LinphoneAddress *addr); +LINPHONE_DEPRECATED LINPHONE_PUBLIC bool_t linphone_address_is_secure(const LinphoneAddress *addr); /** * Returns true if address refers to a secure location (sips) @@ -231,7 +231,7 @@ LINPHONE_PUBLIC const char * linphone_address_get_uri_param(const LinphoneAddres * Destroys a LinphoneAddress object (actually calls linphone_address_unref()). * @deprecated Use linphone_address_unref() instead **/ -LINPHONE_PUBLIC void linphone_address_destroy(LinphoneAddress *u); +LINPHONE_DEPRECATED LINPHONE_PUBLIC void linphone_address_destroy(LinphoneAddress *u); /** * @} diff --git a/include/linphone/core.h b/include/linphone/core.h index 00a54823a..5e251d7d1 100644 --- a/include/linphone/core.h +++ b/include/linphone/core.h @@ -56,6 +56,11 @@ struct _LinphoneInfoMessage; */ typedef struct _LinphoneCore LinphoneCore; +/** + * Safely down-cast a belle_sip_object_t into LinphoneCore + * @ingroup initializing + */ +#define LINPHONE_CORE(object) BELLE_SIP_CAST(object, LinphoneCore) /** * Disable a sip transport @@ -83,7 +88,7 @@ typedef struct _LinphoneCore LinphoneCore; * Use with #linphone_core_set_sip_transports * @ingroup initializing */ -typedef struct _LCSipTransports{ +typedef struct _LinphoneSipTransports{ /** * SIP/UDP port. **/ @@ -100,7 +105,10 @@ typedef struct _LCSipTransports{ * SIP/TLS port * */ int tls_port; -} LCSipTransports; +} LinphoneSipTransports; + +/* set LCSipTransports to ensure backward compatibility */ +typedef struct _LinphoneSipTransports LCSipTransports; /** @@ -371,12 +379,55 @@ LINPHONE_PUBLIC LinphoneAddress * linphone_core_create_address(LinphoneCore *lc, **/ typedef struct _LinphoneInfoMessage LinphoneInfoMessage; +/** + * Creates an empty info message. + * @param lc the LinphoneCore + * @return a new LinphoneInfoMessage. + * + * The info message can later be filled with information using linphone_info_message_add_header() or linphone_info_message_set_content(), + * and finally sent with linphone_core_send_info_message(). +**/ LINPHONE_PUBLIC LinphoneInfoMessage *linphone_core_create_info_message(LinphoneCore*lc); + +/** + * Send a LinphoneInfoMessage through an established call + * @param call the call + * @param info the info message +**/ LINPHONE_PUBLIC int linphone_call_send_info_message(struct _LinphoneCall *call, const LinphoneInfoMessage *info); + +/** + * Add a header to an info message to be sent. + * @param im the info message + * @param name the header'name + * @param value the header's value +**/ LINPHONE_PUBLIC void linphone_info_message_add_header(LinphoneInfoMessage *im, const char *name, const char *value); + +/** + * Obtain a header value from a received info message. + * @param im the info message + * @param name the header'name + * @return the corresponding header's value, or NULL if not exists. +**/ LINPHONE_PUBLIC const char *linphone_info_message_get_header(const LinphoneInfoMessage *im, const char *name); + +/** + * Assign a content to the info message. + * @param im the linphone info message + * @param content the content described as a #LinphoneContent structure. + * All fields of the LinphoneContent are copied, thus the application can destroy/modify/recycloe the content object freely ater the function returns. +**/ LINPHONE_PUBLIC void linphone_info_message_set_content(LinphoneInfoMessage *im, const LinphoneContent *content); + +/** + * Returns the info message's content as a #LinphoneContent structure. +**/ LINPHONE_PUBLIC const LinphoneContent * linphone_info_message_get_content(const LinphoneInfoMessage *im); + +/** + * Destroy a LinphoneInfoMessage +**/ LINPHONE_PUBLIC void linphone_info_message_destroy(LinphoneInfoMessage *im); LINPHONE_PUBLIC LinphoneInfoMessage *linphone_info_message_copy(const LinphoneInfoMessage *orig); @@ -530,6 +581,7 @@ typedef enum _LinphoneRegistrationState{ LinphoneRegistrationFailed /** + +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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef LINPHONE_FACTORY_H +#define LINPHONE_FACTORY_H + +#include "linphone/core.h" + +#ifdef _cplusplus +extern "C" { +#endif + +/** + * @addtogroup initializing + * @{ + */ + +/** + * #LinphoneFactory is a singleton object devoted to the creation of all the object + * of Liblinphone that cannot created by #LinphoneCore or #LinphoneCore itself. + */ +typedef struct _LinphoneFactory LinphoneFactory; + +/** + * Create the #LinphoneFactory if that has not been done and return + * a pointer on it. + * @return A pointer on the #LinphoneFactory + */ +LINPHONE_PUBLIC LinphoneFactory *linphone_factory_get(void); + +/** + * Instanciate a #LinphoneCore object. + * + * The LinphoneCore object is the primary handle for doing all phone actions. + * It should be unique within your application. + * @param factory The #LinphoneFactory singleton. + * @param cbs a #LinphoneCoreCbs object holding your application callbacks. A reference + * will be taken on it until the destruciton of the core or the unregistration + * with linphone_core_remove_cbs(). + * @param config_path a path to a config file. If it does not exists it will be created. + * The config file is used to store all settings, call logs, friends, proxies... so that all these settings + * become persistent over the life of the LinphoneCore object. + * It is allowed to set a NULL config file. In that case LinphoneCore will not store any settings. + * @param factory_config_path a path to a read-only config file that can be used to + * to store hard-coded preference such as proxy settings or internal preferences. + * The settings in this factory file always override the one in the normal config file. + * It is OPTIONAL, use NULL if unneeded. + * @see linphone_core_new_with_config + */ +LINPHONE_PUBLIC LinphoneCore *linphone_factory_create_core(const LinphoneFactory *factory, LinphoneCoreCbs *cbs, + const char *config_path, const char *factory_config_path); + +/** + * Instantiates a LinphoneCore object with a given LpConfig. + * + * @param factory The #LinphoneFactory singleton. + * The LinphoneCore object is the primary handle for doing all phone actions. + * It should be unique within your application. + * @param cbs a #LinphoneCoreCbs object holding your application callbacks. A reference + * will be taken on it until the destruciton of the core or the unregistration + * with linphone_core_remove_cbs(). + * @param config a pointer to an LpConfig object holding the configuration of the LinphoneCore to be instantiated. + * @see linphone_core_new + */ +LINPHONE_PUBLIC LinphoneCore *linphone_factory_create_core_with_config(const LinphoneFactory *factory, LinphoneCoreCbs *cbs, LinphoneConfig *config); + +/** + * Instanciate a #LinphoneCoreCbs object. + * @return a new #LinponeCoreCbs. + */ +LINPHONE_PUBLIC LinphoneCoreCbs *linphone_factory_create_core_cbs(const LinphoneFactory *factory); + +/** + * Parse a string holding a SIP URI and create the according #LinphoneAddress object. + * @param factory The #LinphoneFactory singleton. + * @param addr A string holding the SIP URI to parse. + * @return A new #LinphoneAddress. + */ +LINPHONE_PUBLIC LinphoneAddress *linphone_factory_create_address(const LinphoneFactory *factory, const char *addr); + +/** + * Creates a #LinphoneAuthInfo object. + * The object can be created empty, that is with all arguments set to NULL. + * Username, userid, password, realm and domain can be set later using specific methods. + * At the end, username and passwd (or ha1) are required. + * @param factory The #LinphoneFactory singleton. + * @param username The username that needs to be authenticated + * @param userid The userid used for authenticating (use NULL if you don't know what it is) + * @param passwd The password in clear text + * @param ha1 The ha1-encrypted password if password is not given in clear text. + * @param realm The authentication domain (which can be larger than the sip domain. Unfortunately many SIP servers don't use this parameter. + * @param domain The SIP domain for which this authentication information is valid, if it has to be restricted for a single SIP domain. + * @return A #LinphoneAuthInfo object. linphone_auth_info_destroy() must be used to destroy it when no longer needed. The LinphoneCore makes a copy of LinphoneAuthInfo + * passed through linphone_core_add_auth_info(). + */ +LINPHONE_PUBLIC LinphoneAuthInfo *linphone_factory_create_auth_info(const LinphoneFactory *factory, const char *username, const char *userid, const char *passwd, const char *ha1, const char *realm, const char *domain); + +/** + * Create an empty #LinphoneVcard. + * @return a new #LinphoneVcard. + * @ingroup initializing + */ +LINPHONE_PUBLIC LinphoneVcard *linphone_factory_create_vcard(LinphoneFactory *factory); + +/** + * @} + */ + +#ifdef _cplusplus +} +#endif + + +#endif // LINPHONE_FACTORY_H diff --git a/include/linphone/vcard.h b/include/linphone/vcard.h index e87a38bb4..db7397605 100644 --- a/include/linphone/vcard.h +++ b/include/linphone/vcard.h @@ -26,6 +26,10 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #define LINPHONE_PUBLIC MS2_PUBLIC #endif +#ifndef LINPHONE_DEPRECATED +#define LINPHONE_DEPRECATED MS2_DEPRECATED +#endif + #ifdef __cplusplus extern "C" { @@ -41,17 +45,34 @@ extern "C" */ typedef struct _LinphoneVcard LinphoneVcard; +/** + * Cast a belle_sip_object_t into LinphoneVcard. + */ +#define LINPHONE_VCARD BELLE_SIP_CAST(object, LinphoneVcard) + /** * Creates a LinphoneVcard object that has a pointer to an empty vCard * @return a new LinphoneVcard object + * @deprecated Use linphone_factory_create_vcard() instead. */ -LINPHONE_PUBLIC LinphoneVcard* linphone_vcard_new(void); +LINPHONE_DEPRECATED LINPHONE_PUBLIC LinphoneVcard* linphone_vcard_new(void); /** * Deletes a LinphoneVcard object properly * @param[in] vCard the LinphoneVcard to destroy + * @deprecated Use linphone_vcard_unref() or belle_sip_object_unref() instead. */ -LINPHONE_PUBLIC void linphone_vcard_free(LinphoneVcard *vCard); +LINPHONE_DEPRECATED LINPHONE_PUBLIC void linphone_vcard_free(LinphoneVcard *vCard); + +/** + * Take a ref on a #LinphoneVcard. + */ +LINPHONE_PUBLIC LinphoneVcard *linphone_vcard_ref(LinphoneVcard *vCard); + +/** + * Release a #LinphoneVcard. + */ +LINPHONE_PUBLIC void linphone_vcard_unref(LinphoneVcard *vCard); /** * Returns the vCard4 representation of the LinphoneVcard. diff --git a/tester/call_single_tester.c b/tester/call_single_tester.c index 00c7a6086..77cb49ffe 100644 --- a/tester/call_single_tester.c +++ b/tester/call_single_tester.c @@ -2896,7 +2896,7 @@ static void call_rejected_because_wrong_credentials_with_params(const char* user linphone_core_set_user_agent(marie->lc,user_agent,NULL); } if (!enable_auth_req_cb) { - ((VTableReference*)(marie->lc->vtable_refs->data))->vtable->auth_info_requested=NULL; + ((VTableReference*)(marie->lc->vtable_refs->data))->cbs->vtable->auth_info_requested=NULL; linphone_core_add_auth_info(marie->lc,wrong_auth_info); } diff --git a/tester/presence_server_tester.c b/tester/presence_server_tester.c index e71d00217..aa17fff70 100644 --- a/tester/presence_server_tester.c +++ b/tester/presence_server_tester.c @@ -48,11 +48,12 @@ static void simple(void) { LinphonePresenceModel *pauline_presence = linphone_presence_model_new_with_activity(LinphonePresenceActivityDinner, NULL); LinphoneFriend* f = linphone_core_create_friend_with_address(marie->lc, get_identity(pauline)); LinphonePresenceActivity *activity = NULL; - LinphoneCoreVTable *vtable = linphone_core_v_table_new(); - vtable->publish_state_changed = linphone_publish_state_changed; - _linphone_core_add_listener(pauline->lc, vtable, TRUE, TRUE ); - + LinphoneCoreCbs *callbacks = linphone_factory_create_core_cbs(linphone_factory_get()); + linphone_core_cbs_set_publish_state_changed(callbacks, linphone_publish_state_changed); + _linphone_core_add_callbacks(pauline->lc, callbacks, TRUE); + linphone_core_cbs_unref(callbacks); + lp_config_set_int(marie->lc->config, "sip", "subscribe_expires", 40); linphone_core_set_user_agent(pauline->lc, "full-presence-support", NULL); linphone_core_set_user_agent(marie->lc, "full-presence-support", NULL); diff --git a/tester/presence_tester.c b/tester/presence_tester.c index 7efe16a72..01dd7f5f5 100644 --- a/tester/presence_tester.c +++ b/tester/presence_tester.c @@ -150,9 +150,11 @@ static void simple_publish_with_expire(int expires) { LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); LinphoneProxyConfig* proxy; LinphonePresenceModel* presence; - LinphoneCoreVTable *vtable = linphone_core_v_table_new(); - vtable->publish_state_changed = linphone_publish_state_changed; - _linphone_core_add_listener(marie->lc, vtable, TRUE, TRUE ); + LinphoneCoreCbs *cbs = linphone_factory_create_core_cbs(linphone_factory_get()); + + linphone_core_cbs_set_publish_state_changed(cbs, linphone_publish_state_changed); + _linphone_core_add_callbacks(marie->lc, cbs, TRUE); + linphone_core_cbs_unref(cbs); proxy = linphone_core_get_default_proxy_config(marie->lc); linphone_proxy_config_edit(proxy);