From 3c28b14440ea03662085e40397967b421a1ddedb Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Thu, 21 Sep 2017 15:33:44 +0200 Subject: [PATCH] Use the c-tools for the Call object. --- coreapi/callbacks.c | 2 +- coreapi/info.c | 10 +- coreapi/linphonecall.c | 1528 +--------------------- coreapi/linphonecore.c | 14 +- coreapi/private.h | 67 +- include/CMakeLists.txt | 3 + include/linphone/api/c-call-cbs.h | 169 +++ include/linphone/api/c-call-stats.h | 201 +++ include/linphone/api/c-call.h | 794 +++++++++++ include/linphone/api/c-callbacks.h | 62 + include/linphone/api/c-types.h | 19 +- include/linphone/call.h | 906 +------------ include/linphone/call_stats.h | 162 +-- include/linphone/callbacks.h | 61 - include/linphone/types.h | 19 - src/CMakeLists.txt | 3 + src/c-wrapper/api/c-call-cbs.cpp | 125 ++ src/c-wrapper/api/c-call-stats.cpp | 343 +++++ src/c-wrapper/api/c-call.cpp | 1212 +++++++++++++++++ src/c-wrapper/c-wrapper.h | 2 + src/call/call-p.h | 4 - src/call/call.cpp | 12 +- src/call/call.h | 6 +- src/conference/session/call-session-p.h | 4 +- src/conference/session/call-session.cpp | 8 +- src/conference/session/call-session.h | 2 +- src/conference/session/media-session-p.h | 4 +- src/conference/session/media-session.cpp | 93 +- src/conference/session/media-session.h | 8 +- src/nat/ice-agent.cpp | 38 +- 30 files changed, 3052 insertions(+), 2829 deletions(-) create mode 100644 include/linphone/api/c-call-cbs.h create mode 100644 include/linphone/api/c-call-stats.h create mode 100644 include/linphone/api/c-call.h create mode 100644 src/c-wrapper/api/c-call-cbs.cpp create mode 100644 src/c-wrapper/api/c-call-stats.cpp create mode 100644 src/c-wrapper/api/c-call.cpp diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c index e7d79f0cf..6e1e27880 100644 --- a/coreapi/callbacks.c +++ b/coreapi/callbacks.c @@ -169,7 +169,7 @@ static void call_received(SalOp *h) { LinphoneCall *call = linphone_call_new_incoming(lc, fromAddr, toAddr, h); linphone_address_unref(fromAddr); linphone_address_unref(toAddr); - L_GET_PRIVATE(linphone_call_get_cpp_obj(call).get())->startIncomingNotification(); + L_GET_PRIVATE_FROM_C_STRUCT(call, Call)->startIncomingNotification(); } static void call_rejected(SalOp *h){ diff --git a/coreapi/info.c b/coreapi/info.c index e6b09b8e3..364f5cfab 100644 --- a/coreapi/info.c +++ b/coreapi/info.c @@ -76,12 +76,6 @@ LinphoneInfoMessage *linphone_core_create_info_message(LinphoneCore *lc){ return belle_sip_object_new(LinphoneInfoMessage); } -LinphoneStatus linphone_call_send_info_message(LinphoneCall *call, const LinphoneInfoMessage *info) { - SalBodyHandler *body_handler = sal_body_handler_from_content(info->content); - sal_op_set_sent_custom_header(linphone_call_get_op(call), info->headers); - return sal_send_info(linphone_call_get_op(call), NULL, NULL, body_handler); -} - void linphone_info_message_add_header(LinphoneInfoMessage *im, const char *name, const char *value){ im->headers=sal_custom_header_append(im->headers, name, value); } @@ -98,6 +92,10 @@ const LinphoneContent * linphone_info_message_get_content(const LinphoneInfoMess return (im->content && linphone_content_get_type(im->content)) ? im->content : NULL; } +SalCustomHeader *linphone_info_message_get_headers (const LinphoneInfoMessage *im) { + return im->headers; +} + void linphone_core_notify_info_message(LinphoneCore* lc,SalOp *op, SalBodyHandler *body_handler){ LinphoneCall *call=(LinphoneCall*)sal_op_get_user_pointer(op); if (call){ diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index dded5e4ef..9962d373a 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -18,174 +18,13 @@ 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. */ -#ifdef _WIN32 -#include -#endif -#include "linphone/core.h" -#include "linphone/sipsetup.h" -#include "linphone/lpconfig.h" + +#include +#include + +#include "linphone/types.h" + #include "private.h" -#include "conference_private.h" - -#include -#include -#include - -#include "mediastreamer2/mediastream.h" -#include "mediastreamer2/msvolume.h" -#include "mediastreamer2/msequalizer.h" -#include "mediastreamer2/msfileplayer.h" -#include "mediastreamer2/msjpegwriter.h" -#include "mediastreamer2/msogl.h" -#include "mediastreamer2/mseventqueue.h" -#include "mediastreamer2/mssndcard.h" -#include "mediastreamer2/msrtt4103.h" - -#include - -// For migration purpose. -#include "address/address-p.h" -#include "c-wrapper/c-wrapper.h" -#include "call/call.h" -#include "call/call-p.h" -#include "conference/params/media-session-params-p.h" - -struct _LinphoneCall{ - belle_sip_object_t base; - void *user_data; - bctbx_list_t *callbacks; /* A list of LinphoneCallCbs object */ - LinphoneCallCbs *current_cbs; /* The current LinphoneCallCbs object used to call a callback */ - std::shared_ptr call; - LinphoneCallParams *currentParamsCache; - LinphoneCallParams *paramsCache; - LinphoneCallParams *remoteParamsCache; - LinphoneAddress *remoteAddressCache; - char *remoteContactCache; - - struct _LinphoneCore *core; - LinphoneErrorInfo *ei; - SalMediaDescription *localdesc; - SalMediaDescription *resultdesc; - struct _LinphoneCallLog *log; - SalOp *op; - SalOp *ping_op; - LinphoneCallState transfer_state; /*idle if no transfer*/ - struct _AudioStream *audiostream; /**/ - struct _VideoStream *videostream; - struct _TextStream *textstream; - MSAudioEndpoint *endpoint; /*used for conferencing*/ - char *refer_to; - LinphoneCallParams *params; - LinphoneCallParams *current_params; - LinphoneCallParams *remote_params; - LinphoneCallStats *audio_stats; - LinphoneCallStats *video_stats; - LinphoneCallStats *text_stats; - LinphoneCall *referer; /*when this call is the result of a transfer, referer is set to the original call that caused the transfer*/ - LinphoneCall *transfer_target;/*if this call received a transfer request, then transfer_target points to the new call created to the refer target */ - LinphonePlayer *player; - char *dtmf_sequence; /*DTMF sequence needed to be sent using #dtmfs_timer*/ - belle_sip_source_t *dtmfs_timer; /*DTMF timer needed to send a DTMF sequence*/ - LinphoneChatRoom *chat_room; - LinphoneConference *conf_ref; /**> Point on the associated conference if this call is part of a conference. NULL instead. */ - bool_t refer_pending; - bool_t defer_update; - bool_t was_automatically_paused; - bool_t paused_by_app; - bool_t broken; /*set to TRUE when the call is in broken state due to network disconnection or transport */ - bool_t need_localip_refresh; - bool_t reinvite_on_cancel_response_requested; - bool_t non_op_error; /*set when the LinphoneErrorInfo was set at higher level than sal*/ -}; - -BELLE_SIP_DECLARE_VPTR_NO_EXPORT(LinphoneCall); - - -typedef belle_sip_object_t_vptr_t LinphoneCallCbs_vptr_t; -BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneCallCbs); -BELLE_SIP_INSTANCIATE_VPTR(LinphoneCallCbs, belle_sip_object_t, - NULL, // destroy - NULL, // clone - NULL, // Marshall - FALSE -); - -LinphoneCallCbs *_linphone_call_cbs_new(void) { - LinphoneCallCbs *obj = belle_sip_object_new(LinphoneCallCbs); - return obj; -} - -LinphoneCallCbs *linphone_call_cbs_ref(LinphoneCallCbs *cbs) { - return (LinphoneCallCbs *)belle_sip_object_ref(cbs); -} - -void linphone_call_cbs_unref(LinphoneCallCbs *cbs) { - belle_sip_object_unref(cbs); -} - -void *linphone_call_cbs_get_user_data(const LinphoneCallCbs *cbs) { - return cbs->user_data; -} - -void linphone_call_cbs_set_user_data(LinphoneCallCbs *cbs, void *user_data) { - cbs->user_data = user_data; -} - -LinphoneCallCbsDtmfReceivedCb linphone_call_cbs_get_dtmf_received(LinphoneCallCbs *cbs) { - return cbs->dtmf_received_cb; -} - -void linphone_call_cbs_set_dtmf_received(LinphoneCallCbs *cbs, LinphoneCallCbsDtmfReceivedCb cb) { - cbs->dtmf_received_cb = cb; -} - -LinphoneCallCbsEncryptionChangedCb linphone_call_cbs_get_encryption_changed(LinphoneCallCbs *cbs) { - return cbs->encryption_changed_cb; -} - -void linphone_call_cbs_set_encryption_changed(LinphoneCallCbs *cbs, LinphoneCallCbsEncryptionChangedCb cb) { - cbs->encryption_changed_cb = cb; -} - -LinphoneCallCbsInfoMessageReceivedCb linphone_call_cbs_get_info_message_received(LinphoneCallCbs *cbs) { - return cbs->info_message_received_cb; -} - -void linphone_call_cbs_set_info_message_received(LinphoneCallCbs *cbs, LinphoneCallCbsInfoMessageReceivedCb cb) { - cbs->info_message_received_cb = cb; -} - -LinphoneCallCbsStateChangedCb linphone_call_cbs_get_state_changed(LinphoneCallCbs *cbs) { - return cbs->state_changed_cb; -} - -void linphone_call_cbs_set_state_changed(LinphoneCallCbs *cbs, LinphoneCallCbsStateChangedCb cb) { - cbs->state_changed_cb = cb; -} - -LinphoneCallCbsStatsUpdatedCb linphone_call_cbs_get_stats_updated(LinphoneCallCbs *cbs) { - return cbs->stats_updated_cb; -} - -void linphone_call_cbs_set_stats_updated(LinphoneCallCbs *cbs, LinphoneCallCbsStatsUpdatedCb cb) { - cbs->stats_updated_cb = cb; -} - -LinphoneCallCbsTransferStateChangedCb linphone_call_cbs_get_transfer_state_changed(LinphoneCallCbs *cbs) { - return cbs->transfer_state_changed_cb; -} - -void linphone_call_cbs_set_transfer_state_changed(LinphoneCallCbs *cbs, LinphoneCallCbsTransferStateChangedCb cb) { - cbs->transfer_state_changed_cb = cb; -} - -LinphoneCallCbsAckProcessingCb linphone_call_cbs_get_ack_processing(LinphoneCallCbs *cbs){ - return cbs->ack_processing; -} - -void linphone_call_cbs_set_ack_processing(LinphoneCallCbs *cbs, LinphoneCallCbsAckProcessingCb cb){ - cbs->ack_processing = cb; -} bool_t linphone_call_state_is_early(LinphoneCallState state){ @@ -217,99 +56,6 @@ bool_t linphone_call_state_is_early(LinphoneCallState state){ return FALSE; } -MSWebCam *get_nowebcam_device(MSFactory* f){ -#ifdef VIDEO_ENABLED - return ms_web_cam_manager_get_cam(ms_factory_get_web_cam_manager(f),"StaticImage: Static picture"); -#else - return NULL; -#endif -} - -LinphoneCore *linphone_call_get_core(const LinphoneCall *call) { - return linphone_call_get_cpp_obj(call)->getCore(); -} - -const char * linphone_call_get_authentication_token(LinphoneCall *call) { - std::string token = linphone_call_get_cpp_obj(call)->getAuthenticationToken(); - return token.empty() ? nullptr : token.c_str(); -} - -bool_t linphone_call_get_authentication_token_verified(const LinphoneCall *call) { - return linphone_call_get_cpp_obj(call)->getAuthenticationTokenVerified(); -} - -void linphone_call_set_authentication_token_verified(LinphoneCall *call, bool_t verified) { - linphone_call_get_cpp_obj(call)->setAuthenticationTokenVerified(verified); -} - -bool_t is_payload_type_number_available(const bctbx_list_t *l, int number, const PayloadType *ignore){ - const bctbx_list_t *elem; - for (elem=l; elem!=NULL; elem=elem->next){ - const PayloadType *pt=(PayloadType*)elem->data; - if (pt!=ignore && payload_type_get_number(pt)==number) return FALSE; - } - return TRUE; -} - -void linphone_call_update_local_media_description_from_ice_or_upnp(LinphoneCall *call){ -} - -void linphone_call_make_local_media_description(LinphoneCall *call) { -} - -void linphone_call_create_op(LinphoneCall *call){ -#if 0 - if (call->op) sal_op_release(call->op); - call->op=sal_op_new(call->core->sal); - sal_op_set_user_pointer(call->op,call); - if (linphone_call_params_get_referer(call->params)) - sal_call_set_referer(call->op,linphone_call_params_get_referer(call->params)->op); - linphone_configure_op(call->core,call->op,call->log->to,linphone_call_params_get_custom_headers(call->params),FALSE); - if (linphone_call_params_get_privacy(call->params) != LinphonePrivacyDefault) - sal_op_set_privacy(call->op,(SalPrivacyMask)linphone_call_params_get_privacy(call->params)); - /*else privacy might be set by proxy */ -#endif -} - -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(LinphoneCore *lc, const LinphoneAddress *from, const LinphoneAddress *to, const LinphoneCallParams *params, LinphoneProxyConfig *cfg){ - LinphoneCall *call = belle_sip_object_new(LinphoneCall); - call->currentParamsCache = linphone_call_params_new_for_wrapper(); - call->paramsCache = linphone_call_params_new_for_wrapper(); - call->remoteParamsCache = linphone_call_params_new_for_wrapper(); - call->remoteAddressCache = linphone_address_new(nullptr); - call->call = std::make_shared(call, lc, LinphoneCallOutgoing, - *L_GET_CPP_PTR_FROM_C_STRUCT(from, Address), *L_GET_CPP_PTR_FROM_C_STRUCT(to, Address), - cfg, nullptr, L_GET_CPP_PTR_FROM_C_STRUCT(params, MediaSessionParams)); - return call; -} - -LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, const LinphoneAddress *from, const LinphoneAddress *to, SalOp *op) { - LinphoneCall *call = belle_sip_object_new(LinphoneCall); - call->currentParamsCache = linphone_call_params_new_for_wrapper(); - call->paramsCache = linphone_call_params_new_for_wrapper(); - call->remoteParamsCache = linphone_call_params_new_for_wrapper(); - call->remoteAddressCache = linphone_address_new(nullptr); - call->call = std::make_shared(call, lc, LinphoneCallIncoming, - *L_GET_CPP_PTR_FROM_C_STRUCT(from, Address), *L_GET_CPP_PTR_FROM_C_STRUCT(to, Address), - nullptr, op, nullptr); - L_GET_PRIVATE(linphone_call_get_cpp_obj(call).get())->initiateIncoming(); - return call; -} - -static void linphone_call_free_media_resources(LinphoneCall *call){ -} - const char *linphone_call_state_to_string(LinphoneCallState cs){ switch (cs){ case LinphoneCallIdle: @@ -358,266 +104,6 @@ const char *linphone_call_state_to_string(LinphoneCallState cs){ return "undefined state"; } -void linphone_call_set_state(LinphoneCall *call, LinphoneCallState cstate, const char *message){ -} - -static void linphone_call_destroy(LinphoneCall *obj) { - ms_message("Call [%p] freed.", obj); - obj->call = nullptr; - if (obj->currentParamsCache) { - linphone_call_params_unref(obj->currentParamsCache); - obj->currentParamsCache = nullptr; - } - if (obj->paramsCache) { - linphone_call_params_unref(obj->paramsCache); - obj->paramsCache = nullptr; - } - if (obj->remoteParamsCache) { - linphone_call_params_unref(obj->remoteParamsCache); - obj->remoteParamsCache = nullptr; - } - if (obj->remoteAddressCache) { - linphone_address_unref(obj->remoteAddressCache); - obj->remoteAddressCache = nullptr; - } - bctbx_list_free_with_data(obj->callbacks, (bctbx_list_free_func)linphone_call_cbs_unref); - if (obj->audiostream || obj->videostream){ - linphone_call_free_media_resources(obj); - } - if (obj->audio_stats) { - linphone_call_stats_unref(obj->audio_stats); - obj->audio_stats = NULL; - } - if (obj->video_stats) { - linphone_call_stats_unref(obj->video_stats); - obj->video_stats = NULL; - } - if (obj->text_stats) { - linphone_call_stats_unref(obj->text_stats); - obj->text_stats = NULL; - } - if (obj->op!=NULL) { - sal_op_release(obj->op); - obj->op=NULL; - } - if (obj->resultdesc!=NULL) { - sal_media_description_unref(obj->resultdesc); - obj->resultdesc=NULL; - } - if (obj->localdesc!=NULL) { - sal_media_description_unref(obj->localdesc); - obj->localdesc=NULL; - } - if (obj->ping_op) { - sal_op_release(obj->ping_op); - obj->ping_op=NULL; - } - if (obj->refer_to){ - ms_free(obj->refer_to); - obj->refer_to=NULL; - } - if (obj->referer){ - linphone_call_unref(obj->referer); - obj->referer=NULL; - } - if (obj->transfer_target){ - linphone_call_unref(obj->transfer_target); - obj->transfer_target=NULL; - } - if (obj->log) { - linphone_call_log_unref(obj->log); - obj->log=NULL; - } - if (obj->dtmfs_timer) { - linphone_call_cancel_dtmfs(obj); - } - if (obj->params){ - linphone_call_params_unref(obj->params); - obj->params=NULL; - } - if (obj->current_params){ - linphone_call_params_unref(obj->current_params); - obj->current_params=NULL; - } - if (obj->remote_params != NULL) { - linphone_call_params_unref(obj->remote_params); - obj->remote_params=NULL; - } - if (obj->ei) linphone_error_info_unref(obj->ei); -} - -LinphoneCall * linphone_call_ref(LinphoneCall *obj){ - belle_sip_object_ref(obj); - return obj; -} - -void linphone_call_unref(LinphoneCall *obj){ - belle_sip_object_unref(obj); -} - -const LinphoneCallParams * linphone_call_get_current_params(LinphoneCall *call){ - L_SET_CPP_PTR_FROM_C_STRUCT(call->currentParamsCache, linphone_call_get_cpp_obj(call)->getCurrentParams()); - return call->currentParamsCache; -} - -const LinphoneCallParams * linphone_call_get_remote_params(LinphoneCall *call) { - const LinphonePrivate::MediaSessionParams *remoteParams = linphone_call_get_cpp_obj(call)->getRemoteParams(); - if (!remoteParams) - return nullptr; - L_SET_CPP_PTR_FROM_C_STRUCT(call->remoteParamsCache, remoteParams); - return call->remoteParamsCache; -} - -const LinphoneAddress * linphone_call_get_remote_address(const LinphoneCall *call) { - L_SET_CPP_PTR_FROM_C_STRUCT(call->remoteAddressCache, &linphone_call_get_cpp_obj(call)->getRemoteAddress()); - return call->remoteAddressCache; -} - -const LinphoneAddress * linphone_call_get_to_address(const LinphoneCall *call){ -#if 0 - return (const LinphoneAddress *)sal_op_get_to_address(call->op); -#else - return nullptr; -#endif -} - -const char *linphone_call_get_to_header(const LinphoneCall *call, const char *name){ -#if 0 - return sal_custom_header_find(sal_op_get_recv_custom_header(call->op),name); -#else - return nullptr; -#endif -} - -char * linphone_call_get_remote_address_as_string(const LinphoneCall *call) { - return ms_strdup(linphone_call_get_cpp_obj(call)->getRemoteAddressAsString().c_str()); -} - -const LinphoneAddress * linphone_call_get_diversion_address(const LinphoneCall *call){ -#if 0 - return call->op?(const LinphoneAddress *)sal_op_get_diversion_address(call->op):NULL; -#else - return nullptr; -#endif -} - -LinphoneCallState linphone_call_get_state(const LinphoneCall *call) { - return linphone_call_get_cpp_obj(call)->getState(); -} - -LinphoneReason linphone_call_get_reason(const LinphoneCall *call) { - return linphone_call_get_cpp_obj(call)->getReason(); -} - -const LinphoneErrorInfo * linphone_call_get_error_info(const LinphoneCall *call) { - return linphone_call_get_cpp_obj(call)->getErrorInfo(); -} - -void *linphone_call_get_user_data(const LinphoneCall *call) { - return call->user_data; -} - -void linphone_call_set_user_data(LinphoneCall *call, void *user_pointer) { - call->user_data = user_pointer; -} - -LinphoneCallLog *linphone_call_get_call_log(const LinphoneCall *call){ - return linphone_call_get_cpp_obj(call)->getLog(); -} - -const char *linphone_call_get_refer_to(const LinphoneCall *call){ -#if 0 - return call->refer_to; -#else - return nullptr; -#endif -} - -LinphoneCall *linphone_call_get_transferer_call(const LinphoneCall *call){ -#if 0 - return call->referer; -#else - return nullptr; -#endif -} - -LinphoneCall *linphone_call_get_transfer_target_call(const LinphoneCall *call){ -#if 0 - return call->transfer_target; -#else - return nullptr; -#endif -} - -LinphoneCallDir linphone_call_get_dir(const LinphoneCall *call) { - return linphone_call_log_get_dir(linphone_call_get_log(call)); -} - -const char *linphone_call_get_remote_user_agent(LinphoneCall *call){ -#if 0 - if (call->op){ - return sal_op_get_remote_ua (call->op); - } - return NULL; -#else - return nullptr; -#endif -} - -const char * linphone_call_get_remote_contact(LinphoneCall *call) { - std::string contact = linphone_call_get_cpp_obj(call)->getRemoteContact(); - if (contact.empty()) - return nullptr; - if (call->remoteContactCache) - bctbx_free(call->remoteContactCache); - call->remoteContactCache = bctbx_strdup(contact.c_str()); - return call->remoteContactCache; -} - -bool_t linphone_call_has_transfer_pending(const LinphoneCall *call){ -#if 0 - return call->refer_pending; -#else - return FALSE; -#endif -} - -int linphone_call_get_duration(const LinphoneCall *call) { - return linphone_call_get_cpp_obj(call)->getDuration(); -} - -LinphoneCall *linphone_call_get_replaced_call(LinphoneCall *call){ -#if 0 - SalOp *op=sal_call_get_replaces(call->op); - if (op){ - return (LinphoneCall*)sal_op_get_user_pointer(op); - } - return NULL; -#else - return nullptr; -#endif -} - -void linphone_call_enable_camera(LinphoneCall *call, bool_t enable) { - linphone_call_get_cpp_obj(call)->enableCamera(enable); -} - -void linphone_call_send_vfu_request(LinphoneCall *call) { - linphone_call_get_cpp_obj(call)->sendVfuRequest(); -} - -LinphoneStatus linphone_call_take_video_snapshot(LinphoneCall *call, const char *file) { - return linphone_call_get_cpp_obj(call)->takeVideoSnapshot(file ? file : ""); -} - -LinphoneStatus linphone_call_take_preview_snapshot(LinphoneCall *call, const char *file) { - return linphone_call_get_cpp_obj(call)->takePreviewSnapshot(file ? file : ""); -} - -bool_t linphone_call_camera_enabled (const LinphoneCall *call) { - return linphone_call_get_cpp_obj(call)->cameraEnabled(); -} - /** * @ingroup call_control * @return string value of LinphonePrivacy enum @@ -635,1010 +121,8 @@ const char* linphone_privacy_to_string(LinphonePrivacy privacy) { } } -void linphone_call_set_next_video_frame_decoded_callback(LinphoneCall *call, LinphoneCallCbFunc cb, void* user_data) { - linphone_call_get_cpp_obj(call)->setNextVideoFrameDecodedCallback(cb, user_data); -} - -void linphone_call_init_media_streams(LinphoneCall *call){ -} - -#if 0 -static int dtmf_tab[16]={'0','1','2','3','4','5','6','7','8','9','*','#','A','B','C','D'}; - -static void linphone_core_dtmf_received(LinphoneCall *call, int dtmf){ - if (dtmf<0 || dtmf>15){ - ms_warning("Bad dtmf value %i",dtmf); - return; - } - linphone_call_notify_dtmf_received(call, dtmf_tab[dtmf]); -} -#endif - void set_playback_gain_db(AudioStream *st, float gain){ if (st->volrecv){ ms_filter_call_method(st->volrecv,MS_VOLUME_SET_DB_GAIN,&gain); }else ms_warning("Could not apply playback gain: gain control wasn't activated."); } - -/*This function is not static because used internally in linphone-daemon project*/ -void _post_configure_audio_stream(AudioStream *st, LinphoneCore *lc, bool_t muted){ -} - -#if 0 -static void setup_ring_player(LinphoneCore *lc, LinphoneCall *call){ - int pause_time=3000; - audio_stream_play(call->audiostream,lc->sound_conf.ringback_tone); - ms_filter_call_method(call->audiostream->soundread,MS_FILE_PLAYER_LOOP,&pause_time); -} -#endif - -#if 0 -static bool_t linphone_call_sound_resources_available(LinphoneCall *call){ - LinphoneCore *lc=call->core; - LinphoneCall *current=linphone_core_get_current_call(lc); - return !linphone_core_is_in_conference(lc) && - (current==NULL || current==call); -} -#endif - -void linphone_call_delete_upnp_session(LinphoneCall *call){ -} - -void linphone_call_stop_media_streams(LinphoneCall *call){ -} - -void linphone_call_enable_echo_cancellation(LinphoneCall *call, bool_t enable) { - linphone_call_get_cpp_obj(call)->enableEchoCancellation(enable); -} - -bool_t linphone_call_echo_cancellation_enabled(const LinphoneCall *call) { - return linphone_call_get_cpp_obj(call)->echoCancellationEnabled(); -} - -void linphone_call_enable_echo_limiter(LinphoneCall *call, bool_t val) { - linphone_call_get_cpp_obj(call)->enableEchoLimiter(val); -} - -bool_t linphone_call_echo_limiter_enabled(const LinphoneCall *call) { - return linphone_call_get_cpp_obj(call)->echoLimiterEnabled(); -} - -float linphone_call_get_play_volume(const LinphoneCall *call) { - return linphone_call_get_cpp_obj(call)->getPlayVolume(); -} - -float linphone_call_get_record_volume(const LinphoneCall *call) { - return linphone_call_get_cpp_obj(call)->getRecordVolume(); -} - -float linphone_call_get_speaker_volume_gain(const LinphoneCall *call) { - return linphone_call_get_cpp_obj(call)->getSpeakerVolumeGain(); -} - -void linphone_call_set_speaker_volume_gain(LinphoneCall *call, float volume) { - linphone_call_get_cpp_obj(call)->setSpeakerVolumeGain(volume); -} - -float linphone_call_get_microphone_volume_gain(const LinphoneCall *call) { - return linphone_call_get_cpp_obj(call)->getMicrophoneVolumeGain(); -} - -void linphone_call_set_microphone_volume_gain(LinphoneCall *call, float volume) { - linphone_call_get_cpp_obj(call)->setMicrophoneVolumeGain(volume); -} - -float linphone_call_get_current_quality(const LinphoneCall *call) { - return linphone_call_get_cpp_obj(call)->getCurrentQuality(); -} - -float linphone_call_get_average_quality(const LinphoneCall *call) { - return linphone_call_get_cpp_obj(call)->getAverageQuality(); -} - -void linphone_call_stats_update(LinphoneCallStats *stats, MediaStream *stream) { - PayloadType *pt; - RtpSession *session = stream->sessions.rtp_session; - const MSQualityIndicator *qi = media_stream_get_quality_indicator(stream); - if (qi) { - stats->local_late_rate=ms_quality_indicator_get_local_late_rate(qi); - stats->local_loss_rate=ms_quality_indicator_get_local_loss_rate(qi); - } - media_stream_get_local_rtp_stats(stream, &stats->rtp_stats); - pt = rtp_profile_get_payload(rtp_session_get_profile(session), rtp_session_get_send_payload_type(session)); - stats->clockrate = pt ? pt->clock_rate : 8000; -} - -MediaStream * linphone_call_get_stream(LinphoneCall *call, LinphoneStreamType type) { - return L_GET_PRIVATE(linphone_call_get_cpp_obj(call).get())->getMediaStream(type); -} - -void _linphone_call_stats_clone(LinphoneCallStats *dst, const LinphoneCallStats *src) { - /* - * Save the belle_sip_object_t part, copy the entire structure and restore the belle_sip_object_t part - */ - belle_sip_object_t tmp = dst->base; - memcpy(dst, src, sizeof(LinphoneCallStats)); - dst->base = tmp; - - dst->received_rtcp = NULL; - dst->sent_rtcp = NULL; -} - -LinphoneCallStats *linphone_call_get_stats(LinphoneCall *call, LinphoneStreamType type) { - return linphone_call_get_cpp_obj(call)->getStats(type); -} - -LinphoneCallStats *linphone_call_get_audio_stats(LinphoneCall *call) { - return linphone_call_get_cpp_obj(call)->getAudioStats(); -} - -LinphoneCallStats *linphone_call_get_video_stats(LinphoneCall *call) { - return linphone_call_get_cpp_obj(call)->getVideoStats(); -} - -LinphoneCallStats *linphone_call_get_text_stats(LinphoneCall *call) { - return linphone_call_get_cpp_obj(call)->getTextStats(); -} - -bool_t linphone_call_media_in_progress(const LinphoneCall *call) { - return linphone_call_get_cpp_obj(call)->mediaInProgress(); -} - -BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneCallStats); - -BELLE_SIP_INSTANCIATE_VPTR(LinphoneCallStats, belle_sip_object_t, - NULL, // destroy - _linphone_call_stats_clone, // clone - NULL, // marshal - TRUE -); - -LinphoneCallStats *linphone_call_stats_new() { - LinphoneCallStats *stats = belle_sip_object_new(LinphoneCallStats); - return stats; -} - -LinphoneCallStats* linphone_call_stats_ref(LinphoneCallStats* stats) { - return (LinphoneCallStats*) belle_sip_object_ref(stats); -} - -void linphone_call_stats_unref(LinphoneCallStats* stats) { - belle_sip_object_unref(stats); -} - -void *linphone_call_stats_get_user_data(const LinphoneCallStats *stats) { - return stats->user_data; -} - -void linphone_call_stats_set_user_data(LinphoneCallStats *stats, void *data) { - stats->user_data = data; -} - -LinphoneStreamType linphone_call_stats_get_type(const LinphoneCallStats *stats) { - return stats->type; -} - -float linphone_call_stats_get_sender_loss_rate(const LinphoneCallStats *stats) { - const report_block_t *srb = NULL; - - if (!stats || !stats->sent_rtcp) - return 0.0; - /* Perform msgpullup() to prevent crashes in rtcp_is_SR() or rtcp_is_RR() if the RTCP packet is composed of several mblk_t structure */ - if (stats->sent_rtcp->b_cont != NULL) - msgpullup(stats->sent_rtcp, -1); - - do{ - if (rtcp_is_SR(stats->sent_rtcp)) - srb = rtcp_SR_get_report_block(stats->sent_rtcp, 0); - else if (rtcp_is_RR(stats->sent_rtcp)) - srb = rtcp_RR_get_report_block(stats->sent_rtcp, 0); - if (srb) break; - }while (rtcp_next_packet(stats->sent_rtcp)); - rtcp_rewind(stats->sent_rtcp); - if (!srb) - return 0.0; - return 100.0f * (float)report_block_get_fraction_lost(srb) / 256.0f; -} - -float linphone_call_stats_get_receiver_loss_rate(const LinphoneCallStats *stats) { - const report_block_t *rrb = NULL; - - if (!stats || !stats->received_rtcp) - return 0.0; - /* Perform msgpullup() to prevent crashes in rtcp_is_SR() or rtcp_is_RR() if the RTCP packet is composed of several mblk_t structure */ - if (stats->received_rtcp->b_cont != NULL) - msgpullup(stats->received_rtcp, -1); - - do{ - if (rtcp_is_RR(stats->received_rtcp)) - rrb = rtcp_RR_get_report_block(stats->received_rtcp, 0); - else if (rtcp_is_SR(stats->received_rtcp)) - rrb = rtcp_SR_get_report_block(stats->received_rtcp, 0); - if (rrb) break; - }while (rtcp_next_packet(stats->received_rtcp)); - rtcp_rewind(stats->received_rtcp); - if (!rrb) - return 0.0; - return 100.0f * (float)report_block_get_fraction_lost(rrb) / 256.0f; -} - -float linphone_call_stats_get_local_loss_rate(const LinphoneCallStats *stats) { - return stats->local_loss_rate; -} - -float linphone_call_stats_get_local_late_rate(const LinphoneCallStats *stats) { - return stats->local_late_rate; -} - -float linphone_call_stats_get_sender_interarrival_jitter(const LinphoneCallStats *stats) { - const report_block_t *srb = NULL; - - if (!stats || !stats->sent_rtcp) - return 0.0; - /* Perform msgpullup() to prevent crashes in rtcp_is_SR() or rtcp_is_RR() if the RTCP packet is composed of several mblk_t structure */ - if (stats->sent_rtcp->b_cont != NULL) - msgpullup(stats->sent_rtcp, -1); - if (rtcp_is_SR(stats->sent_rtcp)) - srb = rtcp_SR_get_report_block(stats->sent_rtcp, 0); - else if (rtcp_is_RR(stats->sent_rtcp)) - srb = rtcp_RR_get_report_block(stats->sent_rtcp, 0); - if (!srb) - return 0.0; - if (stats->clockrate == 0) - return 0.0; - return (float)report_block_get_interarrival_jitter(srb) / (float)stats->clockrate; -} - -float linphone_call_stats_get_receiver_interarrival_jitter(const LinphoneCallStats *stats) { - const report_block_t *rrb = NULL; - - if (!stats || !stats->received_rtcp) - return 0.0; - /* Perform msgpullup() to prevent crashes in rtcp_is_SR() or rtcp_is_RR() if the RTCP packet is composed of several mblk_t structure */ - if (stats->received_rtcp->b_cont != NULL) - msgpullup(stats->received_rtcp, -1); - if (rtcp_is_SR(stats->received_rtcp)) - rrb = rtcp_SR_get_report_block(stats->received_rtcp, 0); - else if (rtcp_is_RR(stats->received_rtcp)) - rrb = rtcp_RR_get_report_block(stats->received_rtcp, 0); - if (!rrb) - return 0.0; - if (stats->clockrate == 0) - return 0.0; - return (float)report_block_get_interarrival_jitter(rrb) / (float)stats->clockrate; -} - -const rtp_stats_t *linphone_call_stats_get_rtp_stats(const LinphoneCallStats *stats) { - return &stats->rtp_stats; -} - -uint64_t linphone_call_stats_get_late_packets_cumulative_number(const LinphoneCallStats *stats) { - return linphone_call_stats_get_rtp_stats(stats)->outoftime; -} - -float linphone_call_stats_get_download_bandwidth(const LinphoneCallStats *stats) { - return stats->download_bandwidth; -} - -float linphone_call_stats_get_upload_bandwidth(const LinphoneCallStats *stats) { - return stats->upload_bandwidth; -} - -LinphoneIceState linphone_call_stats_get_ice_state(const LinphoneCallStats *stats) { - return stats->ice_state; -} - -LinphoneUpnpState linphone_call_stats_get_upnp_state(const LinphoneCallStats *stats) { - return stats->upnp_state; -} - -LinphoneAddressFamily linphone_call_stats_get_ip_family_of_remote(const LinphoneCallStats *stats) { - return (LinphoneAddressFamily)stats->rtp_remote_family; -} - -float linphone_call_stats_get_jitter_buffer_size_ms(const LinphoneCallStats *stats) { - return stats->jitter_stats.jitter_buffer_size_ms; -} - -float linphone_call_stats_get_round_trip_delay(const LinphoneCallStats *stats) { - return stats->round_trip_delay; -} - -void linphone_call_start_recording(LinphoneCall *call) { - linphone_call_get_cpp_obj(call)->startRecording(); -} - -void linphone_call_stop_recording(LinphoneCall *call) { - linphone_call_get_cpp_obj(call)->stopRecording(); -} - -#if 0 -static void linphone_call_lost(LinphoneCall *call){ - LinphoneCore *lc = call->core; - char *temp = NULL; - char *from = NULL; - - from = linphone_call_get_remote_address_as_string(call); - temp = ms_strdup_printf("Media connectivity with %s is lost, call is going to be closed.", from ? from : "?"); - if (from) ms_free(from); - ms_message("LinphoneCall [%p]: %s", call, temp); - linphone_core_notify_display_warning(lc, temp); - call->non_op_error = TRUE; - linphone_error_info_set(call->ei,NULL, LinphoneReasonIOError, 503, "Media lost", NULL); - linphone_call_terminate(call); - linphone_core_play_named_tone(lc, LinphoneToneCallLost); - ms_free(temp); -} -#endif - -/*do not change the prototype of this function, it is also used internally in linphone-daemon.*/ -void linphone_call_stats_fill(LinphoneCallStats *stats, MediaStream *ms, OrtpEvent *ev){ - OrtpEventType evt=ortp_event_get_type(ev); - OrtpEventData *evd=ortp_event_get_data(ev); - - if (evt == ORTP_EVENT_RTCP_PACKET_RECEIVED) { - stats->round_trip_delay = rtp_session_get_round_trip_propagation(ms->sessions.rtp_session); - if(stats->received_rtcp != NULL) - freemsg(stats->received_rtcp); - stats->received_rtcp = evd->packet; - stats->rtcp_received_via_mux = evd->info.socket_type == OrtpRTPSocket; - evd->packet = NULL; - stats->updated = LINPHONE_CALL_STATS_RECEIVED_RTCP_UPDATE; - linphone_call_stats_update(stats,ms); - } else if (evt == ORTP_EVENT_RTCP_PACKET_EMITTED) { - memcpy(&stats->jitter_stats, rtp_session_get_jitter_stats(ms->sessions.rtp_session), sizeof(jitter_stats_t)); - if (stats->sent_rtcp != NULL) - freemsg(stats->sent_rtcp); - stats->sent_rtcp = evd->packet; - evd->packet = NULL; - stats->updated = LINPHONE_CALL_STATS_SENT_RTCP_UPDATE; - linphone_call_stats_update(stats,ms); - } -} - -void linphone_call_stats_uninit(LinphoneCallStats *stats){ - if (stats->received_rtcp) { - freemsg(stats->received_rtcp); - stats->received_rtcp=NULL; - } - if (stats->sent_rtcp){ - freemsg(stats->sent_rtcp); - stats->sent_rtcp=NULL; - } -} - -LinphoneCallState linphone_call_get_transfer_state(LinphoneCall *call) { -#if 0 - return call->transfer_state; -#else - return LinphoneCallIdle; -#endif -} - -void linphone_call_set_transfer_state(LinphoneCall* call, LinphoneCallState state) { -#if 0 - if (state != call->transfer_state) { - ms_message("Transfer state for call [%p] changed from [%s] to [%s]",call - ,linphone_call_state_to_string(call->transfer_state) - ,linphone_call_state_to_string(state)); - call->transfer_state = state; - linphone_call_notify_transfer_state_changed(call, state); - } -#endif -} - -bool_t linphone_call_is_in_conference(const LinphoneCall *call) { -#if 0 - return linphone_call_params_get_in_conference(call->params); -#else - return FALSE; -#endif -} - -LinphoneConference *linphone_call_get_conference(const LinphoneCall *call) { -#if 0 - return call->conf_ref; -#else - return nullptr; -#endif -} - -void linphone_call_zoom_video(LinphoneCall* call, float zoom_factor, float* cx, float* cy) { - linphone_call_get_cpp_obj(call)->zoomVideo(zoom_factor, cx, cy); -} - -LinphonePlayer *linphone_call_get_player(LinphoneCall *call){ -#if 0 - if (call->player==NULL) - call->player=linphone_call_build_player(call); - return call->player; -#else - return nullptr; -#endif -} - - -void linphone_call_set_params(LinphoneCall *call, const LinphoneCallParams *params){ -#if 0 - if ( call->state == LinphoneCallOutgoingInit || call->state == LinphoneCallIncomingReceived){ - _linphone_call_set_new_params(call, params); - } - else { - ms_error("linphone_call_set_params() invalid state %s to call this function", linphone_call_state_to_string(call->state)); - } -#endif -} - - -void _linphone_call_set_new_params(LinphoneCall *call, const LinphoneCallParams *params){ -} - -const LinphoneCallParams * linphone_call_get_params(LinphoneCall *call) { - L_SET_CPP_PTR_FROM_C_STRUCT(call->paramsCache, linphone_call_get_cpp_obj(call)->getParams()); - return call->paramsCache; -} - -#if 0 -static int send_dtmf_handler(void *data, unsigned int revents){ - LinphoneCall *call = (LinphoneCall*)data; - /*By default we send DTMF RFC2833 if we do not have enabled SIP_INFO but we can also send RFC2833 and SIP_INFO*/ - if (linphone_core_get_use_rfc2833_for_dtmf(call->core)!=0 || linphone_core_get_use_info_for_dtmf(call->core)==0) - { - /* In Band DTMF */ - if (call->audiostream!=NULL){ - audio_stream_send_dtmf(call->audiostream,*call->dtmf_sequence); - } - else - { - ms_error("Cannot send RFC2833 DTMF when we are not in communication."); - return FALSE; - } - } - if (linphone_core_get_use_info_for_dtmf(call->core)!=0){ - /* Out of Band DTMF (use INFO method) */ - sal_call_send_dtmf(call->op,*call->dtmf_sequence); - } - - /*this check is needed because linphone_call_send_dtmf does not set the timer since its a single character*/ - if (call->dtmfs_timer!=NULL) { - memmove(call->dtmf_sequence, call->dtmf_sequence+1, strlen(call->dtmf_sequence)); - } - /* continue only if the dtmf sequence is not empty*/ - if (call->dtmf_sequence!=NULL&&*call->dtmf_sequence!='\0') { - return TRUE; - } else { - linphone_call_cancel_dtmfs(call); - return FALSE; - } -} -#endif - -LinphoneStatus linphone_call_send_dtmf(LinphoneCall *call, char dtmf) { -#if 0 - if (call==NULL){ - ms_warning("linphone_call_send_dtmf(): invalid call, canceling DTMF."); - return -1; - } - call->dtmf_sequence = &dtmf; - send_dtmf_handler(call,0); - call->dtmf_sequence = NULL; - return 0; -#else - return 0; -#endif -} - -LinphoneStatus linphone_call_send_dtmfs(LinphoneCall *call,const char *dtmfs) { -#if 0 - if (call==NULL){ - ms_warning("linphone_call_send_dtmfs(): invalid call, canceling DTMF sequence."); - return -1; - } - if (call->dtmfs_timer!=NULL){ - ms_warning("linphone_call_send_dtmfs(): a DTMF sequence is already in place, canceling DTMF sequence."); - return -2; - } - if (dtmfs != NULL) { - int delay_ms = lp_config_get_int(call->core->config,"net","dtmf_delay_ms",200); - call->dtmf_sequence = ms_strdup(dtmfs); - call->dtmfs_timer = sal_create_timer(call->core->sal, send_dtmf_handler, call, delay_ms, "DTMF sequence timer"); - } - return 0; -#else - return 0; -#endif -} - -void linphone_call_cancel_dtmfs(LinphoneCall *call) { -#if 0 - /*nothing to do*/ - if (!call || !call->dtmfs_timer) return; - - sal_cancel_timer(call->core->sal, call->dtmfs_timer); - belle_sip_object_unref(call->dtmfs_timer); - call->dtmfs_timer = NULL; - if (call->dtmf_sequence != NULL) { - ms_free(call->dtmf_sequence); - call->dtmf_sequence = NULL; - } -#endif -} - -void * linphone_call_get_native_video_window_id(const LinphoneCall *call) { - return linphone_call_get_cpp_obj(call)->getNativeVideoWindowId(); -} - -void linphone_call_set_native_video_window_id(LinphoneCall *call, void *id) { - linphone_call_get_cpp_obj(call)->setNativeVideoWindowId(id); -} - -void linphone_call_set_audio_route(LinphoneCall *call, LinphoneAudioRoute route) { -#if 0 - if (call != NULL && call->audiostream != NULL){ - audio_stream_set_audio_route(call->audiostream, (MSAudioRoute) route); - } -#endif -} - -LinphoneChatRoom * linphone_call_get_chat_room(LinphoneCall *call) { -#if 0 - if (!call->chat_room){ - if (call->state != LinphoneCallReleased && call->state != LinphoneCallEnd){ - call->chat_room = _linphone_core_create_chat_room_from_call(call); - } - } - return call->chat_room; -#else - return nullptr; -#endif -} - -int linphone_call_get_stream_count(const LinphoneCall *call) { - return linphone_call_get_cpp_obj(call)->getStreamCount(); -} - -MSFormatType linphone_call_get_stream_type(const LinphoneCall *call, int stream_index) { - return linphone_call_get_cpp_obj(call)->getStreamType(stream_index); -} - -RtpTransport * linphone_call_get_meta_rtp_transport(const LinphoneCall *call, int stream_index) { - return linphone_call_get_cpp_obj(call)->getMetaRtpTransport(stream_index); -} - -RtpTransport * linphone_call_get_meta_rtcp_transport(const LinphoneCall *call, int stream_index) { - return linphone_call_get_cpp_obj(call)->getMetaRtcpTransport(stream_index); -} - -LinphoneStatus linphone_call_pause(LinphoneCall *call) { - return linphone_call_get_cpp_obj(call)->pause(); -} - -/* Internal version that does not play tone indication*/ -int _linphone_call_pause(LinphoneCall *call) { - return 0; -} - -LinphoneStatus linphone_call_resume(LinphoneCall *call) { - return linphone_call_get_cpp_obj(call)->resume(); -} - -#if 0 -static void terminate_call(LinphoneCall *call) { -} -#endif - -LinphoneStatus linphone_call_terminate(LinphoneCall *call) { - return linphone_call_get_cpp_obj(call)->terminate(); -} - -LinphoneStatus linphone_call_terminate_with_error_info(LinphoneCall *call , const LinphoneErrorInfo *ei) { - return linphone_call_get_cpp_obj(call)->terminate(ei); -} - -LinphoneStatus linphone_call_redirect(LinphoneCall *call, const char *redirect_uri) { -#if 0 - char *real_url = NULL; - LinphoneCore *lc; - LinphoneAddress *real_parsed_url; - SalErrorInfo sei; - - if (call->state != LinphoneCallIncomingReceived) { - ms_error("Bad state for call redirection."); - return -1; - } - - lc = linphone_call_get_core(call); - real_parsed_url = linphone_core_interpret_url(lc, redirect_uri); - if (!real_parsed_url) { - /* Bad url */ - ms_error("Bad redirect URI: %s", redirect_uri ? redirect_uri : "NULL"); - return -1; - } - - memset(&sei, 0, sizeof(sei)); - real_url = linphone_address_as_string(real_parsed_url); - sal_error_info_set(&sei,SalReasonRedirect, "SIP", 0, NULL, NULL); - sal_call_decline_with_error_info(call->op, &sei, real_url); - ms_free(real_url); - linphone_error_info_set(call->ei, NULL, LinphoneReasonMovedPermanently, 302, "Call redirected", NULL); - call->non_op_error = TRUE; - terminate_call(call); - linphone_address_unref(real_parsed_url); - sal_error_info_reset(&sei); - return 0; -#else - return 0; -#endif -} - -LinphoneStatus linphone_call_decline(LinphoneCall *call, LinphoneReason reason) { - return linphone_call_get_cpp_obj(call)->decline(reason); -} - -LinphoneStatus linphone_call_decline_with_error_info(LinphoneCall *call, const LinphoneErrorInfo *ei) { - return linphone_call_get_cpp_obj(call)->decline(ei); -} - -LinphoneStatus linphone_call_accept(LinphoneCall *call) { - return linphone_call_get_cpp_obj(call)->accept(nullptr); -} - -LinphoneStatus linphone_call_accept_with_params(LinphoneCall *call, const LinphoneCallParams *params) { - return linphone_call_get_cpp_obj(call)->accept(params ? L_GET_CPP_PTR_FROM_C_STRUCT(params, MediaSessionParams) : nullptr); -} - -LinphoneStatus linphone_call_accept_early_media(LinphoneCall* call) { - return linphone_call_get_cpp_obj(call)->acceptEarlyMedia(); -} - -LinphoneStatus linphone_call_accept_early_media_with_params(LinphoneCall *call, const LinphoneCallParams *params) { - return linphone_call_get_cpp_obj(call)->acceptEarlyMedia(params ? L_GET_CPP_PTR_FROM_C_STRUCT(params, MediaSessionParams) : nullptr); -} - -LinphoneStatus linphone_call_update(LinphoneCall *call, const LinphoneCallParams *params) { - return linphone_call_get_cpp_obj(call)->update(params ? L_GET_CPP_PTR_FROM_C_STRUCT(params, MediaSessionParams) : nullptr); -} - -int linphone_call_start_update(LinphoneCall *call) { - return 0; -} - -LinphoneStatus linphone_call_defer_update(LinphoneCall *call) { -#if 0 - if (call->state != LinphoneCallUpdatedByRemote) { - ms_error("linphone_call_defer_update() not done in state LinphoneCallUpdatedByRemote"); - return -1; - } - - if (call->expect_media_in_ack) { - ms_error("linphone_call_defer_update() is not possible during a late offer incoming reINVITE (INVITE without SDP)"); - return -1; - } - - call->defer_update=TRUE; - return 0; -#else - return 0; -#endif -} - -int linphone_call_start_accept_update(LinphoneCall *call, LinphoneCallState next_state, const char *state_info) { - return 0; -} - -LinphoneStatus linphone_call_accept_update(LinphoneCall *call, const LinphoneCallParams *params) { - return linphone_call_get_cpp_obj(call)->acceptUpdate(params ? L_GET_CPP_PTR_FROM_C_STRUCT(params, MediaSessionParams) : nullptr); -} - -LinphoneStatus linphone_call_transfer(LinphoneCall *call, const char *refer_to) { -#if 0 - char *real_url = NULL; - LinphoneCore *lc = linphone_call_get_core(call); - LinphoneAddress *real_parsed_url = linphone_core_interpret_url(lc, refer_to); - - if (!real_parsed_url) { - /* bad url */ - return -1; - } - //lc->call = NULL; // Do not do that you will lose the call afterward... - real_url = linphone_address_as_string(real_parsed_url); - sal_call_refer(call->op, real_url); - ms_free(real_url); - linphone_address_unref(real_parsed_url); - linphone_call_set_transfer_state(call, LinphoneCallOutgoingInit); - return 0; -#else - return 0; -#endif -} - -LinphoneStatus linphone_call_transfer_to_another(LinphoneCall *call, LinphoneCall *dest) { -#if 0 - int result = sal_call_refer_with_replaces (call->op, dest->op); - linphone_call_set_transfer_state(call, LinphoneCallOutgoingInit); - return result; -#else - return 0; -#endif -} - -int linphone_call_proceed_with_invite_if_ready(LinphoneCall *call, LinphoneProxyConfig *dest_proxy) { - return 0; -} - -int linphone_call_start_invite(LinphoneCall *call, const LinphoneAddress *destination /* = NULL if to be taken from the call log */) { - return 0; -} - -void linphone_call_set_broken(LinphoneCall *call){ -#if 0 - switch(call->state){ - /*for all the early states, we prefer to drop the call*/ - case LinphoneCallOutgoingInit: - case LinphoneCallOutgoingProgress: - case LinphoneCallOutgoingRinging: - case LinphoneCallOutgoingEarlyMedia: - case LinphoneCallIncomingReceived: - case LinphoneCallIncomingEarlyMedia: - /*during the early states, the SAL layer reports the failure from the dialog or transaction layer, - * hence, there is nothing special to do*/ - //break; - case LinphoneCallStreamsRunning: - case LinphoneCallUpdating: - case LinphoneCallPausing: - case LinphoneCallResuming: - case LinphoneCallPaused: - case LinphoneCallPausedByRemote: - case LinphoneCallUpdatedByRemote: - /*during these states, the dialog is established. A failure of a transaction is not expected to close it. - * Instead we have to repair the dialog by sending a reINVITE*/ - call->broken = TRUE; - call->need_localip_refresh = TRUE; - break; - default: - ms_error("linphone_call_set_broken() unimplemented case."); - break; - } -#endif -} - -#if 0 -static void linphone_call_repair_by_invite_with_replaces(LinphoneCall *call) { - const char *call_id = sal_op_get_call_id(call->op); - const char *from_tag = sal_call_get_local_tag(call->op); - const char *to_tag = sal_call_get_remote_tag(call->op); - sal_op_kill_dialog(call->op); - linphone_call_create_op(call); - sal_call_set_replaces(call->op, call_id, from_tag, to_tag); - linphone_call_start_invite(call, NULL); -} -#endif - -void linphone_call_reinvite_to_recover_from_connection_loss(LinphoneCall *call) { -#if 0 - LinphoneCallParams *params; - ms_message("LinphoneCall[%p] is going to be updated (reINVITE) in order to recover from lost connectivity", call); - if (call->ice_session){ - ice_session_reset(call->ice_session, IR_Controlling); - } - params = linphone_core_create_call_params(call->core, call); - linphone_call_update(call, params); - linphone_call_params_unref(params); -#endif -} - -void linphone_call_repair_if_broken(LinphoneCall *call){ -#if 0 - SalErrorInfo sei; - if (!call->broken) return; - if (!call->core->media_network_reachable) return; - - memset(&sei, 0, sizeof(sei)); - - /*Make sure that the proxy from which we received this call, or to which we routed this call is registered first*/ - if (call->dest_proxy){ - /*in all other cases, ie no proxy config, or a proxy config for which no registration was requested, we can start the - * call repair immediately.*/ - if (linphone_proxy_config_register_enabled(call->dest_proxy) - && linphone_proxy_config_get_state(call->dest_proxy) != LinphoneRegistrationOk) return; - } - - switch (call->state){ - case LinphoneCallUpdating: - case LinphoneCallPausing: - if (sal_call_dialog_request_pending(call->op)) { - /* Need to cancel first re-INVITE as described in section 5.5 of RFC 6141 */ - sal_call_cancel_invite(call->op); - call->reinvite_on_cancel_response_requested = TRUE; - } - break; - case LinphoneCallStreamsRunning: - case LinphoneCallPaused: - case LinphoneCallPausedByRemote: - if (!sal_call_dialog_request_pending(call->op)) { - linphone_call_reinvite_to_recover_from_connection_loss(call); - } - break; - case LinphoneCallUpdatedByRemote: - if (sal_call_dialog_request_pending(call->op)) { - sal_error_info_set(&sei, SalReasonServiceUnavailable,"SIP", 0, NULL, NULL); - sal_call_decline_with_error_info(call->op, &sei,NULL); - } - linphone_call_reinvite_to_recover_from_connection_loss(call); - break; - case LinphoneCallOutgoingInit: - case LinphoneCallOutgoingProgress: - sal_call_cancel_invite(call->op); - call->reinvite_on_cancel_response_requested = TRUE; - break; - case LinphoneCallOutgoingEarlyMedia: - case LinphoneCallOutgoingRinging: - linphone_call_repair_by_invite_with_replaces(call); - break; - case LinphoneCallIncomingEarlyMedia: - case LinphoneCallIncomingReceived: - /* Keep the call broken until a forked INVITE is received from the server. */ - break; - default: - ms_warning("linphone_call_repair_if_broken(): don't know what to do in state [%s]", linphone_call_state_to_string(call->state)); - call->broken = FALSE; - break; - } - sal_error_info_reset(&sei); -#endif -} - -void linphone_call_refresh_sockets(LinphoneCall *call){ -#if 0 - int i; - for (i=0; i < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; ++i){ - MSMediaStreamSessions *mss = &call->sessions[i]; - if (mss->rtp_session){ - rtp_session_refresh_sockets(mss->rtp_session); - } - } -#endif -} - -void linphone_call_replace_op(LinphoneCall *call, SalOp *op) { -#if 0 - SalOp *oldop = call->op; - LinphoneCallState oldstate = linphone_call_get_state(call); - call->op = op; - sal_op_set_user_pointer(call->op, call); - sal_call_set_local_media_description(call->op, call->localdesc); - switch (linphone_call_get_state(call)) { - case LinphoneCallIncomingEarlyMedia: - case LinphoneCallIncomingReceived: - sal_call_notify_ringing(call->op, (linphone_call_get_state(call) == LinphoneCallIncomingEarlyMedia) ? TRUE : FALSE); - break; - case LinphoneCallConnected: - case LinphoneCallStreamsRunning: - sal_call_accept(call->op); - break; - default: - ms_warning("linphone_call_replace_op(): don't know what to do in state [%s]", linphone_call_state_to_string(call->state)); - break; - } - switch (oldstate) { - case LinphoneCallIncomingEarlyMedia: - case LinphoneCallIncomingReceived: - sal_op_set_user_pointer(oldop, NULL); /* To make the call does not get terminated by terminating this op. */ - /* Do not terminate a forked INVITE */ - if (sal_call_get_replaces(op)) { - sal_call_terminate(oldop); - } else { - sal_op_kill_dialog(oldop); - } - break; - case LinphoneCallConnected: - case LinphoneCallStreamsRunning: - sal_call_terminate(oldop); - sal_op_kill_dialog(oldop); - break; - default: - break; - } - sal_op_release(oldop); -#endif -} - -void linphone_call_ogl_render(const LinphoneCall *call) { -#if 0 - #ifdef VIDEO_ENABLED - - VideoStream *stream = call->videostream; - if (stream && stream->output && ms_filter_get_id(stream->output) == MS_OGL_ID) - ms_filter_call_method(stream->output, MS_OGL_RENDER, NULL); - - #endif -#endif -} - -void linphone_call_add_callbacks(LinphoneCall *call, LinphoneCallCbs *cbs) { - call->callbacks = bctbx_list_append(call->callbacks, linphone_call_cbs_ref(cbs)); -} - -void linphone_call_remove_callbacks(LinphoneCall *call, LinphoneCallCbs *cbs) { - call->callbacks = bctbx_list_remove(call->callbacks, cbs); - linphone_call_cbs_unref(cbs); -} - -LinphoneCallCbs *linphone_call_get_current_callbacks(const LinphoneCall *call) { - return call->current_cbs; -} - -#define NOTIFY_IF_EXIST(function_name, ...) \ - bctbx_list_t* iterator; \ - for (iterator = call->callbacks; iterator != NULL; iterator = bctbx_list_next(iterator)) { \ - call->current_cbs = (LinphoneCallCbs *)bctbx_list_get_data(iterator); \ - if (call->current_cbs->function_name != NULL) { \ - call->current_cbs->function_name(__VA_ARGS__); \ - } \ - } - -void linphone_call_notify_state_changed(LinphoneCall *call, LinphoneCallState cstate, const char *message) { - NOTIFY_IF_EXIST(state_changed_cb, call, cstate, message) - linphone_core_notify_call_state_changed(linphone_call_get_core(call), call, cstate, message); -} - -void linphone_call_notify_dtmf_received(LinphoneCall *call, int dtmf) { - NOTIFY_IF_EXIST(dtmf_received_cb, call, dtmf) - linphone_core_notify_dtmf_received(linphone_call_get_core(call), call, dtmf); -} - -void linphone_call_notify_encryption_changed(LinphoneCall *call, bool_t on, const char *authentication_token) { - NOTIFY_IF_EXIST(encryption_changed_cb, call, on, authentication_token) - linphone_core_notify_call_encryption_changed(linphone_call_get_core(call), call, on, authentication_token); -} - -void linphone_call_notify_transfer_state_changed(LinphoneCall *call, LinphoneCallState cstate) { - NOTIFY_IF_EXIST(transfer_state_changed_cb, call, cstate) - linphone_core_notify_transfer_state_changed(linphone_call_get_core(call), call, cstate); -} - -void linphone_call_notify_stats_updated(LinphoneCall *call, const LinphoneCallStats *stats) { - NOTIFY_IF_EXIST(stats_updated_cb, call, stats) - linphone_core_notify_call_stats_updated(linphone_call_get_core(call), call, stats); -} - -void linphone_call_notify_info_message_received(LinphoneCall *call, const LinphoneInfoMessage *msg) { - NOTIFY_IF_EXIST(info_message_received_cb, call, msg) - linphone_core_notify_info_received(linphone_call_get_core(call), call, msg); -} - -void linphone_call_notify_ack_processing(LinphoneCall *call, LinphoneHeaders *msg, bool_t is_received) { - NOTIFY_IF_EXIST(ack_processing, call, msg, is_received) -} - -SalOp * linphone_call_get_op(const LinphoneCall *call) { - return L_GET_PRIVATE(linphone_call_get_cpp_obj(call).get())->getOp(); -} - -LinphoneProxyConfig * linphone_call_get_dest_proxy(const LinphoneCall *call) { - return L_GET_PRIVATE(linphone_call_get_cpp_obj(call).get())->getDestProxy(); -} - -LinphoneCallLog * linphone_call_get_log(const LinphoneCall *call) { - return linphone_call_get_call_log(call); -} - -IceSession * linphone_call_get_ice_session(const LinphoneCall *call) { - return L_GET_PRIVATE(linphone_call_get_cpp_obj(call).get())->getIceSession(); -} - -bool_t linphone_call_get_audio_muted(const LinphoneCall *call) { - return L_GET_PRIVATE(linphone_call_get_cpp_obj(call).get())->getAudioMuted(); -} - -void linphone_call_set_audio_muted(LinphoneCall *call, bool_t value) { - L_GET_PRIVATE(linphone_call_get_cpp_obj(call).get())->setAudioMuted(value); -} - -bool_t linphone_call_get_all_muted(const LinphoneCall *call) { - return linphone_call_get_cpp_obj(call)->getAllMuted(); -} - -std::shared_ptr linphone_call_get_cpp_obj(const LinphoneCall *call) { - return call->call; -} diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 4f2412b6f..c646bfbdc 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -454,14 +454,6 @@ int lc_callback_obj_invoke(LCCallbackObj *obj, LinphoneCore *lc){ return 0; } -bool_t linphone_call_asked_to_autoanswer(LinphoneCall *call){ - //return TRUE if the unique(for the moment) incoming call asked to be autoanswered - if(call) - return sal_call_autoanswer_asked(linphone_call_get_op(call)); - else - return FALSE; -} - int linphone_core_get_current_call_duration(const LinphoneCore *lc){ LinphoneCall *call=linphone_core_get_current_call((LinphoneCore *)lc); if (call) return linphone_call_get_duration(call); @@ -3232,7 +3224,7 @@ void linphone_core_iterate(LinphoneCore *lc){ /* Get immediately a reference to next one in case the one we are going to examine is destroyed * and removed during linphone_call_start_invite() */ calls = bctbx_list_next(calls); - L_GET_PRIVATE(linphone_call_get_cpp_obj(call).get())->iterate(current_real_time, one_second_elapsed); + L_GET_PRIVATE_FROM_C_STRUCT(call, Call)->iterate(current_real_time, one_second_elapsed); } if (linphone_core_video_preview_enabled(lc)){ @@ -3558,9 +3550,9 @@ LinphoneCall * linphone_core_invite_address_with_params(LinphoneCore *lc, const if (linphone_call_params_get_local_conference_mode(params) == FALSE) #endif lc->current_call=call; - bool defer = L_GET_PRIVATE(linphone_call_get_cpp_obj(call).get())->initiateOutgoing(); + bool defer = L_GET_PRIVATE_FROM_C_STRUCT(call, Call)->initiateOutgoing(); if (!defer) { - if (L_GET_PRIVATE(linphone_call_get_cpp_obj(call).get())->startInvite(nullptr) != 0) { + if (L_GET_PRIVATE_FROM_C_STRUCT(call, Call)->startInvite(nullptr) != 0) { /* The call has already gone to error and released state, so do not return it */ call = nullptr; } diff --git a/coreapi/private.h b/coreapi/private.h index 2b57ff947..fab87f38f 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -228,19 +228,7 @@ typedef struct _PortConfig{ int rtcp_port; }PortConfig; -struct _LinphoneCallCbs { - belle_sip_object_t base; - void *user_data; - LinphoneCallCbsDtmfReceivedCb dtmf_received_cb; - LinphoneCallCbsEncryptionChangedCb encryption_changed_cb; - LinphoneCallCbsInfoMessageReceivedCb info_message_received_cb; - LinphoneCallCbsStateChangedCb state_changed_cb; - LinphoneCallCbsStatsUpdatedCb stats_updated_cb; - LinphoneCallCbsTransferStateChangedCb transfer_state_changed_cb; - LinphoneCallCbsAckProcessingCb ack_processing; -}; - -LinphoneCallCbs * _linphone_call_cbs_new(void); +LinphoneCallCbs *_linphone_call_cbs_new(void); void linphone_call_notify_state_changed(LinphoneCall *call, LinphoneCallState cstate, const char *message); @@ -416,8 +404,21 @@ LINPHONE_PUBLIC void linphone_core_enable_short_turn_refresh(LinphoneCore *lc, b void linphone_call_update_ice_state_in_call_stats(LinphoneCall *call); LINPHONE_PUBLIC void linphone_call_stats_fill(LinphoneCallStats *stats, MediaStream *ms, OrtpEvent *ev); void linphone_call_stats_update(LinphoneCallStats *stats, MediaStream *stream); -void linphone_call_stats_uninit(LinphoneCallStats *stats); +LinphoneCallStats *_linphone_call_stats_new(void); +void _linphone_call_stats_uninit(LinphoneCallStats *stats); void _linphone_call_stats_clone(LinphoneCallStats *dst, const LinphoneCallStats *src); +void _linphone_call_stats_set_ice_state (LinphoneCallStats *stats, LinphoneIceState state); +void _linphone_call_stats_set_type (LinphoneCallStats *stats, LinphoneStreamType type); +void _linphone_call_stats_set_received_rtcp (LinphoneCallStats *stats, mblk_t *m); +void _linphone_call_stats_set_sent_rtcp (LinphoneCallStats *stats, mblk_t *m); +int _linphone_call_stats_get_updated (const LinphoneCallStats *stats); +void _linphone_call_stats_set_updated (LinphoneCallStats *stats, int updated); +void _linphone_call_stats_set_rtp_stats (LinphoneCallStats *stats, const rtp_stats_t *rtpStats); +void _linphone_call_stats_set_download_bandwidth (LinphoneCallStats *stats, float bandwidth); +void _linphone_call_stats_set_upload_bandwidth (LinphoneCallStats *stats, float bandwidth); +void _linphone_call_stats_set_rtcp_download_bandwidth (LinphoneCallStats *stats, float bandwidth); +void _linphone_call_stats_set_rtcp_upload_bandwidth (LinphoneCallStats *stats, float bandwidth); +void _linphone_call_stats_set_ip_family_of_remote (LinphoneCallStats *stats, LinphoneAddressFamily family); void linphone_call_update_local_media_description_from_ice_or_upnp(LinphoneCall *call); void linphone_call_update_ice_from_remote_media_description(LinphoneCall *call, const SalMediaDescription *md, bool_t is_offer); void linphone_call_clear_unused_ice_candidates(LinphoneCall *call, const SalMediaDescription *md); @@ -1520,7 +1521,6 @@ void linphone_error_info_from_sal_op(LinphoneErrorInfo *ei, const SalOp *op); void payload_type_set_enable(OrtpPayloadType *pt, bool_t value); bool_t payload_type_enabled(const OrtpPayloadType *pt); -bool_t is_payload_type_number_available(const MSList *l, int number, const OrtpPayloadType *ignore); LinphonePayloadType *linphone_payload_type_new(LinphoneCore *lc, OrtpPayloadType *ortp_pt); bool_t _linphone_core_check_payload_type_usability(const LinphoneCore *lc, const OrtpPayloadType *pt); OrtpPayloadType *linphone_payload_type_get_ortp_pt(const LinphonePayloadType *pt); @@ -1592,40 +1592,6 @@ BELLE_SIP_DECLARE_VPTR_NO_EXPORT(LinphoneVideoActivationPolicy); LINPHONE_PUBLIC LinphoneVideoActivationPolicy *linphone_video_activation_policy_new(void); -/** - * The LinphoneCallStats objects carries various statistic informations regarding quality of audio or video streams. - * - * To receive these informations periodically and as soon as they are computed, the application is invited to place a #LinphoneCoreCallStatsUpdatedCb callback in the LinphoneCoreVTable structure - * it passes for instantiating the LinphoneCore object (see linphone_core_new() ). - * - * At any time, the application can access last computed statistics using linphone_call_get_audio_stats() or linphone_call_get_video_stats(). -**/ -struct _LinphoneCallStats { - belle_sip_object_t base; - void *user_data; - LinphoneStreamType type; /**< Type of the stream which the stats refer to */ - jitter_stats_t jitter_stats; /**. + */ + +#ifndef _C_CALL_CBS_H_ +#define _C_CALL_CBS_H_ + +#include "linphone/api/c-callbacks.h" +#include "linphone/api/c-types.h" + +// ============================================================================= + +#ifdef __cplusplus + extern "C" { +#endif // ifdef __cplusplus + +/** + * @addtogroup call_control + * @{ + */ + +/** + * Acquire a reference to the LinphoneCallCbs object. + * @param[in] cbs LinphoneCallCbs object. + * @return The same LinphoneCallCbs object. + */ +LINPHONE_PUBLIC LinphoneCallCbs *linphone_call_cbs_ref (LinphoneCallCbs *cbs); + +/** + * Release reference to the LinphoneCallCbs object. + * @param[in] cbs LinphoneCallCbs object. + */ +LINPHONE_PUBLIC void linphone_call_cbs_unref (LinphoneCallCbs *cbs); + +/** + * Retrieve the user pointer associated with the LinphoneCallCbs object. + * @param[in] cbs LinphoneCallCbs object. + * @return The user pointer associated with the LinphoneCallCbs object. + */ +LINPHONE_PUBLIC void *linphone_call_cbs_get_user_data (const LinphoneCallCbs *cbs); + +/** + * Assign a user pointer to the LinphoneCallCbs object. + * @param[in] cbs LinphoneCallCbs object. + * @param[in] ud The user pointer to associate with the LinphoneCallCbs object. + */ +LINPHONE_PUBLIC void linphone_call_cbs_set_user_data (LinphoneCallCbs *cbs, void *ud); + +/** + * Get the dtmf received callback. + * @param[in] cbs LinphoneCallCbs object. + * @return The current dtmf received callback. + */ +LINPHONE_PUBLIC LinphoneCallCbsDtmfReceivedCb linphone_call_cbs_get_dtmf_received (LinphoneCallCbs *cbs); + +/** + * Set the dtmf received callback. + * @param[in] cbs LinphoneCallCbs object. + * @param[in] cb The dtmf received callback to be used. + */ +LINPHONE_PUBLIC void linphone_call_cbs_set_dtmf_received (LinphoneCallCbs *cbs, LinphoneCallCbsDtmfReceivedCb cb); + +/** + * Get the encryption changed callback. + * @param[in] cbs LinphoneCallCbs object. + * @return The current encryption changed callback. + */ +LINPHONE_PUBLIC LinphoneCallCbsEncryptionChangedCb linphone_call_cbs_get_encryption_changed (LinphoneCallCbs *cbs); + +/** + * Set the encryption changed callback. + * @param[in] cbs LinphoneCallCbs object. + * @param[in] cb The encryption changed callback to be used. + */ +LINPHONE_PUBLIC void linphone_call_cbs_set_encryption_changed (LinphoneCallCbs *cbs, LinphoneCallCbsEncryptionChangedCb cb); + +/** + * Get the info message received callback. + * @param[in] cbs LinphoneCallCbs object. + * @return The current info message received callback. + */ +LINPHONE_PUBLIC LinphoneCallCbsInfoMessageReceivedCb linphone_call_cbs_get_info_message_received (LinphoneCallCbs *cbs); + +/** + * Set the info message received callback. + * @param[in] cbs LinphoneCallCbs object. + * @param[in] cb The info message received callback to be used. + */ +LINPHONE_PUBLIC void linphone_call_cbs_set_info_message_received (LinphoneCallCbs *cbs, LinphoneCallCbsInfoMessageReceivedCb cb); + +/** + * Get the state changed callback. + * @param[in] cbs LinphoneCallCbs object. + * @return The current state changed callback. + */ +LINPHONE_PUBLIC LinphoneCallCbsStateChangedCb linphone_call_cbs_get_state_changed (LinphoneCallCbs *cbs); + +/** + * Set the state changed callback. + * @param[in] cbs LinphoneCallCbs object. + * @param[in] cb The state changed callback to be used. + */ +LINPHONE_PUBLIC void linphone_call_cbs_set_state_changed (LinphoneCallCbs *cbs, LinphoneCallCbsStateChangedCb cb); + +/** + * Get the stats updated callback. + * @param[in] cbs LinphoneCallCbs object. + * @return The current stats updated callback. + */ +LINPHONE_PUBLIC LinphoneCallCbsStatsUpdatedCb linphone_call_cbs_get_stats_updated (LinphoneCallCbs *cbs); + +/** + * Set the stats updated callback. + * @param[in] cbs LinphoneCallCbs object. + * @param[in] cb The stats updated callback to be used. + */ +LINPHONE_PUBLIC void linphone_call_cbs_set_stats_updated (LinphoneCallCbs *cbs, LinphoneCallCbsStatsUpdatedCb cb); + +/** + * Get the transfer state changed callback. + * @param[in] cbs LinphoneCallCbs object. + * @return The current transfer state changed callback. + */ +LINPHONE_PUBLIC LinphoneCallCbsTransferStateChangedCb linphone_call_cbs_get_transfer_state_changed (LinphoneCallCbs *cbs); + +/** + * Set the transfer state changed callback. + * @param[in] cbs LinphoneCallCbs object. + * @param[in] cb The transfer state changed callback to be used. + */ +LINPHONE_PUBLIC void linphone_call_cbs_set_transfer_state_changed (LinphoneCallCbs *cbs, LinphoneCallCbsTransferStateChangedCb cb); + +/** + * Get the ACK processing callback. + * @param[in] cbs LinphoneCallCbs object. + * @return The current ack processing callback. + */ +LINPHONE_PUBLIC LinphoneCallCbsAckProcessingCb linphone_call_cbs_get_ack_processing (LinphoneCallCbs *cbs); + +/** + * Set ACK processing callback. + * @param[in] cbs LinphoneCallCbs object. + * @param[in] cb The ack processing callback to be used. + */ +LINPHONE_PUBLIC void linphone_call_cbs_set_ack_processing (LinphoneCallCbs *cbs, LinphoneCallCbsAckProcessingCb cb); + +/** + * @} + */ + +#ifdef __cplusplus + } +#endif // ifdef __cplusplus + +#endif // ifndef _C_CALL_CBS_H_ diff --git a/include/linphone/api/c-call-stats.h b/include/linphone/api/c-call-stats.h new file mode 100644 index 000000000..0d631f652 --- /dev/null +++ b/include/linphone/api/c-call-stats.h @@ -0,0 +1,201 @@ +/* + * c-call-stats.h + * Copyright (C) 2017 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 3 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, see . + */ + +#ifndef _C_CALL_STATS_H_ +#define _C_CALL_STATS_H_ + +#include + +#include "linphone/api/c-callbacks.h" +#include "linphone/api/c-types.h" + +// ============================================================================= + +#ifdef __cplusplus + extern "C" { +#endif // ifdef __cplusplus + +/** + * @addtogroup call_misc + * @{ + */ + +#define LINPHONE_CALL_STATS_AUDIO ((int)LinphoneStreamTypeAudio) +#define LINPHONE_CALL_STATS_VIDEO ((int)LinphoneStreamTypeVideo) +#define LINPHONE_CALL_STATS_TEXT ((int)LinphoneStreamTypeText) + +#define LINPHONE_CALL_STATS_RECEIVED_RTCP_UPDATE (1 << 0) /**< received_rtcp field of LinphoneCallStats object has been updated */ +#define LINPHONE_CALL_STATS_SENT_RTCP_UPDATE (1 << 1) /**< sent_rtcp field of LinphoneCallStats object has been updated */ +#define LINPHONE_CALL_STATS_PERIODICAL_UPDATE (1 << 2) /**< Every seconds LinphoneCallStats object has been updated */ + +/** + * Increment refcount. + * @param[in] stats LinphoneCallStats object + * @ingroup misc +**/ +LINPHONE_PUBLIC LinphoneCallStats *linphone_call_stats_ref (LinphoneCallStats *stats); + +/** + * Decrement refcount and possibly free the object. + * @param[in] stats LinphoneCallStats object + * @ingroup misc +**/ +LINPHONE_PUBLIC void linphone_call_stats_unref (LinphoneCallStats *stats); + +/** + * Gets the user data in the LinphoneCallStats object + * @param[in] stats the LinphoneCallStats + * @return the user data + * @ingroup misc +*/ +LINPHONE_PUBLIC void *linphone_call_stats_get_user_data (const LinphoneCallStats *stats); + +/** + * Sets the user data in the LinphoneCallStats object + * @param[in] stats the LinphoneCallStats object + * @param[in] data the user data + * @ingroup misc +*/ +LINPHONE_PUBLIC void linphone_call_stats_set_user_data (LinphoneCallStats *stats, void *data); + +/** + * Get the type of the stream the stats refer to. + * @param[in] stats LinphoneCallStats object + * @return The type of the stream the stats refer to + */ +LINPHONE_PUBLIC LinphoneStreamType linphone_call_stats_get_type (const LinphoneCallStats *stats); + +/** + * Get the local loss rate since last report + * @return The sender loss rate +**/ +LINPHONE_PUBLIC float linphone_call_stats_get_sender_loss_rate (const LinphoneCallStats *stats); + +/** + * Gets the remote reported loss rate since last report + * @return The receiver loss rate +**/ +LINPHONE_PUBLIC float linphone_call_stats_get_receiver_loss_rate (const LinphoneCallStats *stats); + +/** + * Get the local loss rate since last report + * @return The local loss rate +**/ +LINPHONE_PUBLIC float linphone_call_stats_get_local_loss_rate (const LinphoneCallStats *stats); + +/** + * Gets the local late rate since last report + * @return The local late rate +**/ +LINPHONE_PUBLIC float linphone_call_stats_get_local_late_rate (const LinphoneCallStats *stats); + +/** + * Gets the local interarrival jitter + * @param[in] stats LinphoneCallStats object + * @return The interarrival jitter at last emitted sender report +**/ +LINPHONE_PUBLIC float linphone_call_stats_get_sender_interarrival_jitter (const LinphoneCallStats *stats); + +/** + * Gets the remote reported interarrival jitter + * @param[in] stats LinphoneCallStats object + * @return The interarrival jitter at last received receiver report +**/ +LINPHONE_PUBLIC float linphone_call_stats_get_receiver_interarrival_jitter (const LinphoneCallStats *stats); + +LINPHONE_PUBLIC const rtp_stats_t *linphone_call_stats_get_rtp_stats (const LinphoneCallStats *stats); + +/** + * Gets the cumulative number of late packets + * @param[in] stats LinphoneCallStats object + * @return The cumulative number of late packets +**/ +LINPHONE_PUBLIC uint64_t linphone_call_stats_get_late_packets_cumulative_number (const LinphoneCallStats *stats); + +/** + * Get the bandwidth measurement of the received stream, expressed in kbit/s, including IP/UDP/RTP headers. + * @param[in] stats LinphoneCallStats object + * @return The bandwidth measurement of the received stream in kbit/s. + */ +LINPHONE_PUBLIC float linphone_call_stats_get_download_bandwidth (const LinphoneCallStats *stats); + +/** + * Get the bandwidth measurement of the sent stream, expressed in kbit/s, including IP/UDP/RTP headers. + * @param[in] stats LinphoneCallStats object + * @return The bandwidth measurement of the sent stream in kbit/s. + */ +LINPHONE_PUBLIC float linphone_call_stats_get_upload_bandwidth (const LinphoneCallStats *stats); + +/** + * Get the bandwidth measurement of the received RTCP, expressed in kbit/s, including IP/UDP/RTP headers. + * @param[in] stats LinphoneCallStats object + * @return The bandwidth measurement of the received RTCP in kbit/s. + */ +LINPHONE_PUBLIC float linphone_call_stats_get_rtcp_download_bandwidth (const LinphoneCallStats *stats); + +/** + * Get the bandwidth measurement of the sent RTCP, expressed in kbit/s, including IP/UDP/RTP headers. + * @param[in] stats LinphoneCallStats object + * @return The bandwidth measurement of the sent RTCP in kbit/s. + */ +LINPHONE_PUBLIC float linphone_call_stats_get_rtcp_upload_bandwidth( const LinphoneCallStats *stats); + +/** + * Get the state of ICE processing. + * @param[in] stats LinphoneCallStats object + * @return The state of ICE processing. + */ +LINPHONE_PUBLIC LinphoneIceState linphone_call_stats_get_ice_state (const LinphoneCallStats *stats); + +/** + * Get the state of uPnP processing. + * @param[in] stats LinphoneCallStats object + * @return The state of uPnP processing. + */ +LINPHONE_PUBLIC LinphoneUpnpState linphone_call_stats_get_upnp_state (const LinphoneCallStats *stats); + +/** + * Get the IP address family of the remote peer. + * @param[in] stats LinphoneCallStats object + * @return The IP address family of the remote peer. + */ +LINPHONE_PUBLIC LinphoneAddressFamily linphone_call_stats_get_ip_family_of_remote (const LinphoneCallStats *stats); + +/** + * Get the jitter buffer size in ms. + * @param[in] stats LinphoneCallStats object + * @return The jitter buffer size in ms. + */ +LINPHONE_PUBLIC float linphone_call_stats_get_jitter_buffer_size_ms (const LinphoneCallStats *stats); + +/** + * Get the round trip delay in s. + * @param[in] stats LinphoneCallStats object + * @return The round trip delay in s. + */ +LINPHONE_PUBLIC float linphone_call_stats_get_round_trip_delay (const LinphoneCallStats *stats); + +/** + * @} + */ + +#ifdef __cplusplus + } +#endif // ifdef __cplusplus + +#endif // ifndef _C_CALL_STATS_H_ diff --git a/include/linphone/api/c-call.h b/include/linphone/api/c-call.h new file mode 100644 index 000000000..4087a6480 --- /dev/null +++ b/include/linphone/api/c-call.h @@ -0,0 +1,794 @@ +/* + * c-call.h + * Copyright (C) 2017 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 3 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, see . + */ + +#ifndef _C_CALL_H_ +#define _C_CALL_H_ + +#include + +#include "linphone/api/c-types.h" + +// ============================================================================= + +#ifdef __cplusplus + extern "C" { +#endif // ifdef __cplusplus + +/** + * @addtogroup call_control + * @{ + */ + +/** + * 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. +**/ +LINPHONE_PUBLIC LinphoneCall *linphone_call_ref (LinphoneCall *call); + +/** + * Release reference to the call. + * @param[in] call The call. +**/ +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. +**/ +LINPHONE_PUBLIC void *linphone_call_get_user_data (const LinphoneCall *call); + +/** + * Assign a user pointer to the call. + * @param[in] call The call. + * @param[in] ud The user pointer to associate with the call. +**/ +LINPHONE_PUBLIC void linphone_call_set_user_data (LinphoneCall *call, void *ud); + +/** + * Get the core that has created the specified call. + * @param[in] call LinphoneCall object + * @return The LinphoneCore object that has created the specified call. + */ +LINPHONE_PUBLIC LinphoneCore * linphone_call_get_core (const LinphoneCall *call); + +/** + * Retrieves the call's current state. +**/ +LINPHONE_PUBLIC LinphoneCallState linphone_call_get_state (const LinphoneCall *call); + +/** + * Tell whether a call has been asked to autoanswer + * @param[in] call LinphoneCall object + * @return A boolean value telling whether the call has been asked to autoanswer +**/ +LINPHONE_PUBLIC bool_t linphone_call_asked_to_autoanswer (LinphoneCall *call); + +/** + * Returns the remote address associated to this call +**/ +LINPHONE_PUBLIC const LinphoneAddress *linphone_call_get_remote_address (const LinphoneCall *call); + +/** + * Returns the to address with its headers associated to this call +**/ +LINPHONE_PUBLIC const LinphoneAddress *linphone_call_get_to_address (const LinphoneCall * call); + +/** + * Returns the value of the header name +**/ +LINPHONE_PUBLIC const char *linphone_call_get_to_header (const LinphoneCall *call, const char *name); + +/** + * Returns the remote address associated to this call as a string. + * The result string must be freed by user using ms_free(). +**/ +LINPHONE_PUBLIC char *linphone_call_get_remote_address_as_string (const LinphoneCall *call); + +/** + * Returns the diversion address associated to this call +**/ +LINPHONE_PUBLIC const LinphoneAddress * linphone_call_get_diversion_address (const LinphoneCall *call); + +/** + * Returns direction of the call (incoming or outgoing). +**/ +LINPHONE_PUBLIC LinphoneCallDir linphone_call_get_dir (const LinphoneCall *call); + +/** + * Gets the call log associated to this call. + * @param[in] call LinphoneCall object + * @return The LinphoneCallLog associated with the specified LinphoneCall +**/ +LINPHONE_PUBLIC LinphoneCallLog *linphone_call_get_call_log (const LinphoneCall *call); + +/** + * Gets the refer-to uri (if the call was transfered). + * @param[in] call LinphoneCall object + * @return The refer-to uri of the call (if it was transfered) +**/ +LINPHONE_PUBLIC const char *linphone_call_get_refer_to (const LinphoneCall *call); + +/** + * Returns true if this calls has received a transfer that has not been + * executed yet. + * Pending transfers are executed when this call is being paused or closed, + * locally or by remote endpoint. + * If the call is already paused while receiving the transfer request, the + * transfer immediately occurs. +**/ +LINPHONE_PUBLIC bool_t linphone_call_has_transfer_pending (const LinphoneCall *call); + +/** + * Gets the transferer if this call was started automatically as a result of an incoming transfer request. + * The call in which the transfer request was received is returned in this case. + * @param[in] call LinphoneCall object + * @return The transferer call if the specified call was started automatically as a result of an incoming transfer request, NULL otherwise +**/ +LINPHONE_PUBLIC LinphoneCall *linphone_call_get_transferer_call (const LinphoneCall *call); + +/** + * When this call has received a transfer request, returns the new call that was automatically created as a result of the transfer. +**/ +LINPHONE_PUBLIC LinphoneCall *linphone_call_get_transfer_target_call (const LinphoneCall *call); + +/** + * Returns the call object this call is replacing, if any. + * Call replacement can occur during call transfers. + * By default, the core automatically terminates the replaced call and accept the new one. + * This function allows the application to know whether a new incoming call is a one that replaces another one. +**/ +LINPHONE_PUBLIC LinphoneCall *linphone_call_get_replaced_call (LinphoneCall *call); + +/** + * Returns call's duration in seconds. +**/ +LINPHONE_PUBLIC int linphone_call_get_duration (const LinphoneCall *call); + +/** + * Returns current parameters associated to the call. +**/ +LINPHONE_PUBLIC const LinphoneCallParams *linphone_call_get_current_params (LinphoneCall *call); + +/** + * Returns call parameters proposed by remote. + * + * This is useful when receiving an incoming call, to know whether the remote party + * supports video, encryption or whatever. +**/ +LINPHONE_PUBLIC const LinphoneCallParams *linphone_call_get_remote_params (LinphoneCall *call); + +/** + * Indicate whether camera input should be sent to remote end. +**/ +LINPHONE_PUBLIC void linphone_call_enable_camera (LinphoneCall *lc, bool_t enabled); + +/** + * Returns TRUE if camera pictures are allowed to be sent to the remote party. +**/ +LINPHONE_PUBLIC bool_t linphone_call_camera_enabled (const LinphoneCall *lc); + +/** + * Take a photo of currently received video and write it into a jpeg file. + * Note that the snapshot is asynchronous, an application shall not assume that the file is created when the function returns. + * @param call a LinphoneCall + * @param file a path where to write the jpeg content. + * @return 0 if successfull, -1 otherwise (typically if jpeg format is not supported). +**/ +LINPHONE_PUBLIC LinphoneStatus linphone_call_take_video_snapshot (LinphoneCall *call, const char *file); + +/** + * Take a photo of currently captured video and write it into a jpeg file. + * Note that the snapshot is asynchronous, an application shall not assume that the file is created when the function returns. + * @param call a LinphoneCall + * @param file a path where to write the jpeg content. + * @return 0 if successfull, -1 otherwise (typically if jpeg format is not supported). +**/ +LINPHONE_PUBLIC LinphoneStatus linphone_call_take_preview_snapshot (LinphoneCall *call, const char *file); + +/** + * Returns the reason for a call termination (either error or normal termination) +**/ +LINPHONE_PUBLIC LinphoneReason linphone_call_get_reason (const LinphoneCall *call); + +/** + * Returns full details about call errors or termination reasons. + * @param call LinphoneCall object on which we want the information error + * @return LinphoneErrorInfo object holding the reason error. + */ +LINPHONE_PUBLIC const LinphoneErrorInfo *linphone_call_get_error_info (const LinphoneCall *call); + +/** + * Returns the far end's user agent description string, if available. +**/ +LINPHONE_PUBLIC const char *linphone_call_get_remote_user_agent (LinphoneCall *call); + +/** + * Returns the far end's sip contact as a string, if available. +**/ +LINPHONE_PUBLIC const char *linphone_call_get_remote_contact (LinphoneCall *call); + +/** + * Returns the ZRTP authentication token to verify. + * @param call the LinphoneCall + * @return the authentication token to verify. +**/ +LINPHONE_PUBLIC const char *linphone_call_get_authentication_token (LinphoneCall *call); + +/** + * Returns whether ZRTP authentication token is verified. + * If not, it must be verified by users as described in ZRTP procedure. + * Once done, the application must inform of the results with linphone_call_set_authentication_token_verified(). + * @param call the LinphoneCall + * @return TRUE if authentication token is verifed, false otherwise. +**/ +LINPHONE_PUBLIC bool_t linphone_call_get_authentication_token_verified (const LinphoneCall *call); + +/** + * Set the result of ZRTP short code verification by user. + * If remote party also does the same, it will update the ZRTP cache so that user's verification will not be required for the two users. + * @param call the LinphoneCall + * @param verified whether the ZRTP SAS is verified. +**/ +LINPHONE_PUBLIC void linphone_call_set_authentication_token_verified (LinphoneCall *call, bool_t verified); + +/** + * Request remote side to send us a Video Fast Update. +**/ +LINPHONE_PUBLIC void linphone_call_send_vfu_request (LinphoneCall *call); + +LINPHONE_PUBLIC void linphone_call_set_next_video_frame_decoded_callback (LinphoneCall *call, LinphoneCallCbFunc cb, void *ud); + +/** + * Returns the current transfer state, if a transfer has been initiated from this call. + * @see linphone_core_transfer_call() , linphone_core_transfer_call_to_another() +**/ +LINPHONE_PUBLIC LinphoneCallState linphone_call_get_transfer_state (LinphoneCall *call); + +/** + * Perform a zoom of the video displayed during a call. + * @param call the call. + * @param zoom_factor a floating point number describing the zoom factor. A value 1.0 corresponds to no zoom applied. + * @param cx a floating point number pointing the horizontal center of the zoom to be applied. This value should be between 0.0 and 1.0. + * @param cy a floating point number pointing the vertical center of the zoom to be applied. This value should be between 0.0 and 1.0. + * + * cx and cy are updated in return in case their coordinates were too excentrated for the requested zoom factor. The zoom ensures that all the screen is fullfilled with the video. +**/ +LINPHONE_PUBLIC void linphone_call_zoom_video (LinphoneCall *call, float zoom_factor, float *cx, float *cy); + +/** + * Send the specified dtmf. + * + * The dtmf is automatically played to the user. + * @param call The LinphoneCall object + * @param dtmf The dtmf name specified as a char, such as '0', '#' etc... + * @return 0 if successful, -1 on error. +**/ +LINPHONE_PUBLIC LinphoneStatus linphone_call_send_dtmf (LinphoneCall *call, char dtmf); + +/** + * Send a list of dtmf. + * + * The dtmfs are automatically sent to remote, separated by some needed customizable delay. + * Sending is canceled if the call state changes to something not LinphoneCallStreamsRunning. + * @param call The LinphoneCall object + * @param dtmfs A dtmf sequence such as '123#123123' + * @return -2 if there is already a DTMF sequence, -1 if call is not ready, 0 otherwise. +**/ +LINPHONE_PUBLIC LinphoneStatus linphone_call_send_dtmfs (LinphoneCall *call, const char *dtmfs); + +/** + * Stop current DTMF sequence sending. + * + * Please note that some DTMF could be already sent, + * depending on when this function call is delayed from #linphone_call_send_dtmfs. This + * function will be automatically called if call state change to anything but LinphoneCallStreamsRunning. + * @param call The LinphoneCall object +**/ +LINPHONE_PUBLIC void linphone_call_cancel_dtmfs (LinphoneCall *call); + +/** + * Return TRUE if this call is currently part of a conference + * @param call #LinphoneCall + * @return TRUE if part of a conference. + * @deprecated Use linphone_call_get_conference() instead. + * @donotwrap + */ +LINPHONE_PUBLIC LINPHONE_DEPRECATED bool_t linphone_call_is_in_conference (const LinphoneCall *call); + +/** + * Return the associated conference object + * @param call #LinphoneCall + * @return A pointer on #LinphoneConference or NULL if the call is not part of any conference. + */ +LINPHONE_PUBLIC LinphoneConference *linphone_call_get_conference (const LinphoneCall *call); + +/** + * Change the playback output device (currently only used for blackberry) + * @param call + * @param route the wanted audio route (earpiece, speaker, ...) +**/ +LINPHONE_PUBLIC void linphone_call_set_audio_route (LinphoneCall *call, LinphoneAudioRoute route); + +/** + * Returns the number of stream for the given call. + * Currently there is only two (Audio, Video), but later there will be more. + * @param call + * @return 2 +**/ +LINPHONE_PUBLIC int linphone_call_get_stream_count (const LinphoneCall *call); + +/** + * Returns the type of stream for the given stream index. + * @param call + * @param stream_index + * @return the type (MSAudio, MSVideo, MSText) of the stream of given index. +**/ +LINPHONE_PUBLIC MSFormatType linphone_call_get_stream_type (const LinphoneCall *call, int stream_index); + +/** + * Returns the meta rtp transport for the given stream index. + * @param call + * @param stream_index + * @return a pointer to the meta rtp transport if it exists, NULL otherwise +**/ +LINPHONE_PUBLIC RtpTransport *linphone_call_get_meta_rtp_transport (const LinphoneCall *call, int stream_index); + +/** + * Returns the meta rtcp transport for the given stream index. + * @param call + * @param stream_index + * @return a pointer to the meta rtcp transport if it exists, NULL otherwise +**/ +LINPHONE_PUBLIC RtpTransport *linphone_call_get_meta_rtcp_transport (const LinphoneCall *call, int stream_index); + +/** + * Pauses the call. If a music file has been setup using linphone_core_set_play_file(), + * this file will be played to the remote user. + * The only way to resume a paused call is to call linphone_call_resume(). + * @param[in] call LinphoneCall object + * @return 0 on success, -1 on failure + * @see linphone_call_resume() +**/ +LINPHONE_PUBLIC LinphoneStatus linphone_call_pause (LinphoneCall *call); + +/** + * Resumes a call. + * The call needs to have been paused previously with linphone_call_pause(). + * @param[in] call LinphoneCall object + * @return 0 on success, -1 on failure + * @see linphone_call_pause() +**/ +LINPHONE_PUBLIC LinphoneStatus linphone_call_resume (LinphoneCall *call); + +/** + * Terminates a call. + * @param[in] call LinphoneCall object + * @return 0 on success, -1 on failure +**/LINPHONE_PUBLIC LinphoneStatus linphone_call_terminate (LinphoneCall *call); + +/** + * Terminates a call. + * @param[in] call LinphoneCall object + * @param[in] ei LinphoneErrorInfo + * @return 0 on success, -1 on failure +**/ +LINPHONE_PUBLIC LinphoneStatus linphone_call_terminate_with_error_info (LinphoneCall *call, const LinphoneErrorInfo *ei); + +/** + * Redirect the specified call to the given redirect URI. + * @param[in] call A LinphoneCall object + * @param[in] redirect_uri The URI to redirect the call to + * @return 0 if successful, -1 on error. + */ +LINPHONE_PUBLIC LinphoneStatus linphone_call_redirect (LinphoneCall *call, const char *redirect_uri); + +/** + * Decline a pending incoming call, with a reason. + * @param[in] call A LinphoneCall object that must be in the IncomingReceived state + * @param[in] reason The reason for rejecting the call: LinphoneReasonDeclined or LinphoneReasonBusy + * @return 0 on success, -1 on failure +**/ +LINPHONE_PUBLIC LinphoneStatus linphone_call_decline (LinphoneCall *call, LinphoneReason reason); + +/** + * Decline a pending incoming call, with a LinphoneErrorInfo object. + * @param[in] call A LinphoneCall object that must be in the IncomingReceived state + * @param[in] ei LinphoneErrorInfo containing more information on the call rejection. + * @return 0 on success, -1 on failure + */ +LINPHONE_PUBLIC int linphone_call_decline_with_error_info (LinphoneCall *call, const LinphoneErrorInfo *ei); + +/** + * Accept an incoming call. + * + * Basically the application is notified of incoming calls within the + * call_state_changed callback of the #LinphoneCoreVTable structure, where it will receive + * a LinphoneCallIncoming event with the associated LinphoneCall object. + * The application can later accept the call using this method. + * @param[in] call A LinphoneCall object + * @return 0 on success, -1 on failure +**/ +LINPHONE_PUBLIC LinphoneStatus linphone_call_accept (LinphoneCall *call); + +/** + * Accept an incoming call, with parameters. + * + * Basically the application is notified of incoming calls within the + * call_state_changed callback of the #LinphoneCoreVTable structure, where it will receive + * a LinphoneCallIncoming event with the associated LinphoneCall object. + * The application can later accept the call using this method. + * @param[in] call A LinphoneCall object + * @param[in] params The specific parameters for this call, for example whether video is accepted or not. Use NULL to use default parameters + * @return 0 on success, -1 on failure +**/ +LINPHONE_PUBLIC LinphoneStatus linphone_call_accept_with_params (LinphoneCall *call, const LinphoneCallParams *params); + +/** + * Accept an early media session for an incoming call. + * This is identical as calling linphone_call_accept_early_media_with_params() with NULL parameters. + * @param[in] call A LinphoneCall object + * @return 0 if successful, -1 otherwise + * @see linphone_call_accept_early_media_with_params() +**/ +LINPHONE_PUBLIC LinphoneStatus linphone_call_accept_early_media (LinphoneCall *call); + +/** + * When receiving an incoming, accept to start a media session as early-media. + * This means the call is not accepted but audio & video streams can be established if the remote party supports early media. + * However, unlike after call acceptance, mic and camera input are not sent during early-media, though received audio & video are played normally. + * The call can then later be fully accepted using linphone_call_accept() or linphone_call_accept_with_params(). + * @param[in] call A LinphoneCall object + * @param[in] params The call parameters to use (can be NULL) + * @return 0 if successful, -1 otherwise +**/ +LINPHONE_PUBLIC LinphoneStatus linphone_call_accept_early_media_with_params (LinphoneCall *call, const LinphoneCallParams *params); + +/** + * Updates a running call according to supplied call parameters or parameters changed in the LinphoneCore. + * In this version this is limited to the following use cases: + * - setting up/down the video stream according to the video parameter of the LinphoneCallParams (see linphone_call_params_enable_video() ). + * - changing the size of the transmitted video after calling linphone_core_set_preferred_video_size() + * In case no changes are requested through the LinphoneCallParams argument, then this argument can be omitted and set to NULL. + * WARNING: Updating a call in the LinphoneCallPaused state will still result in a paused call even if the media directions set in the + * params are sendrecv. To resume a paused call, you need to call linphone_call_resume(). + * + * @param[in] call A LinphoneCall object + * @param[in] params The new call parameters to use (may be NULL) + * @return 0 if successful, -1 otherwise. +**/ +LINPHONE_PUBLIC LinphoneStatus linphone_call_update (LinphoneCall *call, const LinphoneCallParams *params); + +/** + * When receiving a #LinphoneCallUpdatedByRemote state notification, prevent LinphoneCore from performing an automatic answer. + * + * When receiving a #LinphoneCallUpdatedByRemote state notification (ie an incoming reINVITE), the default behaviour of + * LinphoneCore is defined by the "defer_update_default" option of the "sip" section of the config. If this option is 0 (the default) + * then the LinphoneCore automatically answers the reINIVTE with call parameters unchanged. + * However when for example when the remote party updated the call to propose a video stream, it can be useful + * to prompt the user before answering. This can be achieved by calling linphone_core_defer_call_update() during + * the call state notification, to deactivate the automatic answer that would just confirm the audio but reject the video. + * Then, when the user responds to dialog prompt, it becomes possible to call linphone_call_accept_update() to answer + * the reINVITE, with eventually video enabled in the LinphoneCallParams argument. + * + * The #LinphoneCallUpdatedByRemote notification can also arrive when receiving an INVITE without SDP. In such case, an unchanged offer is made + * in the 200Ok, and when the ACK containing the SDP answer is received, #LinphoneCallUpdatedByRemote is triggered to notify the application of possible + * changes in the media session. However in such case defering the update has no meaning since we just generating an offer. + * + * @param[in] call A LinphoneCall object + * @return 0 if successful, -1 if the linphone_call_defer_update() was done outside a valid #LinphoneCallUpdatedByRemote notification +**/ +LINPHONE_PUBLIC LinphoneStatus linphone_call_defer_update (LinphoneCall *call); + +/** + * Accept call modifications initiated by other end. + * + * This call may be performed in response to a #LinphoneCallUpdatedByRemote state notification. + * When such notification arrives, the application can decide to call linphone_call_defer_update() so that it can + * have the time to prompt the user. linphone_call_get_remote_params() can be used to get information about the call parameters + * requested by the other party, such as whether a video stream is requested. + * + * When the user accepts or refuse the change, linphone_call_accept_update() can be done to answer to the other party. + * If params is NULL, then the same call parameters established before the update request will continue to be used (no change). + * If params is not NULL, then the update will be accepted according to the parameters passed. + * Typical example is when a user accepts to start video, then params should indicate that video stream should be used + * (see linphone_call_params_enable_video()). + * @param[in] call A LinphoneCall object + * @param[in] params A LinphoneCallParams object describing the call parameters to accept + * @return 0 if successful, -1 otherwise (actually when this function call is performed outside ot #LinphoneCallUpdatedByRemote state) +**/ +LINPHONE_PUBLIC LinphoneStatus linphone_call_accept_update (LinphoneCall *call, const LinphoneCallParams *params); + +/** + * Performs a simple call transfer to the specified destination. + * The remote endpoint is expected to issue a new call to the specified destination. + * The current call remains active and thus can be later paused or terminated. + * It is possible to follow the progress of the transfer provided that transferee sends notification about it. + * In this case, the transfer_state_changed callback of the #LinphoneCoreVTable is invoked to notify of the state of the new call at the other party. + * The notified states are #LinphoneCallOutgoingInit , #LinphoneCallOutgoingProgress, #LinphoneCallOutgoingRinging and #LinphoneCallConnected. + * @param[in] call The call to be transfered + * @param[in] refer_to The destination the call is to be refered to + * @return 0 on success, -1 on failure +**/ +LINPHONE_PUBLIC LinphoneStatus linphone_call_transfer (LinphoneCall *call, const char *refer_to); + +/** + * Transfers a call to destination of another running call. This is used for "attended transfer" scenarios. + * The transfered call is supposed to be in paused state, so that it is able to accept the transfer immediately. + * The destination call is a call previously established to introduce the transfered person. + * This method will send a transfer request to the transfered person. The phone of the transfered is then + * expected to automatically call to the destination of the transfer. The receiver of the transfer will then automatically + * close the call with us (the 'dest' call). + * It is possible to follow the progress of the transfer provided that transferee sends notification about it. + * In this case, the transfer_state_changed callback of the #LinphoneCoreVTable is invoked to notify of the state of the new call at the other party. + * The notified states are #LinphoneCallOutgoingInit , #LinphoneCallOutgoingProgress, #LinphoneCallOutgoingRinging and #LinphoneCallConnected. + * @param[in] call A running call you want to transfer + * @param[in] dest A running call whose remote person will receive the transfer + * @return 0 on success, -1 on failure +**/ +LINPHONE_PUBLIC LinphoneStatus linphone_call_transfer_to_another (LinphoneCall *call, LinphoneCall *dest); + +/** + * @} + */ + +/** + * @addtogroup media_parameters + * @{ + */ + +/** + * Get the native window handle of the video window, casted as an unsigned long. +**/ +LINPHONE_PUBLIC void * linphone_call_get_native_video_window_id(const LinphoneCall *call); + +/** + * Set the native video window id where the video is to be displayed. + * For MacOS, Linux, Windows: if not set or 0 a window will be automatically created, unless the special id -1 is given. +**/ +LINPHONE_PUBLIC void linphone_call_set_native_video_window_id(LinphoneCall *call, void * id); + +/** + * Enables or disable echo cancellation for this call + * @param call + * @param val +**/ +LINPHONE_PUBLIC void linphone_call_enable_echo_cancellation(LinphoneCall *call, bool_t val) ; + +/** + * Returns TRUE if echo cancellation is enabled. +**/ +LINPHONE_PUBLIC bool_t linphone_call_echo_cancellation_enabled(const LinphoneCall *call); + +/** + * Enables or disable echo limiter for this call + * @param call + * @param val +**/ +LINPHONE_PUBLIC void linphone_call_enable_echo_limiter(LinphoneCall *call, bool_t val); + +/** + * Returns TRUE if echo limiter is enabled. +**/ +LINPHONE_PUBLIC bool_t linphone_call_echo_limiter_enabled(const LinphoneCall *call); + +/** + * @} + */ + +/** + * @addtogroup call_misc + * @{ + */ + +/** + * Create a new chat room for messaging from a call if not already existing, else return existing one. + * No reference is given to the caller: the chat room will be deleted when the call is ended. + * @param call #LinphoneCall object + * @return #LinphoneChatRoom where messaging can take place. + */ +LINPHONE_PUBLIC LinphoneChatRoom * linphone_call_get_chat_room(LinphoneCall *call); + +/** + * Get the mesured playback volume level (received from remote) in dbm0. + * @param call The call. + * @return float Volume level in percentage. + */ +LINPHONE_PUBLIC float linphone_call_get_play_volume(const LinphoneCall *call); + +/** + * Get the mesured record volume level (sent to remote) in dbm0. + * @param call The call. + * @return float Volume level in percentage. + */ +LINPHONE_PUBLIC float linphone_call_get_record_volume(const LinphoneCall *call); + +/** + * Get speaker volume gain. + * If the sound backend supports it, the returned gain is equal to the gain set + * with the system mixer. + * @param call The call. + * @return Percenatge of the max supported volume gain. Valid values are in [ 0.0 : 1.0 ]. + * In case of failure, a negative value is returned + */ +LINPHONE_PUBLIC float linphone_call_get_speaker_volume_gain(const LinphoneCall *call); + +/** + * Set speaker volume gain. + * If the sound backend supports it, the new gain will synchronized with the system mixer. + * @param call The call. + * @param volume Percentage of the max supported gain. Valid values are in [ 0.0 : 1.0 ]. + */ +LINPHONE_PUBLIC void linphone_call_set_speaker_volume_gain(LinphoneCall *call, float volume); + +/** + * Get microphone volume gain. + * If the sound backend supports it, the returned gain is equal to the gain set + * with the system mixer. + * @param call The call. + * @return double Percenatge of the max supported volume gain. Valid values are in [ 0.0 : 1.0 ]. + * In case of failure, a negative value is returned + */ +LINPHONE_PUBLIC float linphone_call_get_microphone_volume_gain(const LinphoneCall *call); + +/** + * Set microphone volume gain. + * If the sound backend supports it, the new gain will synchronized with the system mixer. + * @param call The call. + * @param volume Percentage of the max supported gain. Valid values are in [ 0.0 : 1.0 ]. + */ +LINPHONE_PUBLIC void linphone_call_set_microphone_volume_gain(LinphoneCall *call, float volume); + +/** + * Obtain real-time quality rating of the call + * + * Based on local RTP statistics and RTCP feedback, a quality rating is computed and updated + * during all the duration of the call. This function returns its value at the time of the function call. + * It is expected that the rating is updated at least every 5 seconds or so. + * The rating is a floating point number comprised between 0 and 5. + * + * 4-5 = good quality
+ * 3-4 = average quality
+ * 2-3 = poor quality
+ * 1-2 = very poor quality
+ * 0-1 = can't be worse, mostly unusable
+ * + * @return The function returns -1 if no quality measurement is available, for example if no + * active audio stream exist. Otherwise it returns the quality rating. +**/ +LINPHONE_PUBLIC float linphone_call_get_current_quality(const LinphoneCall *call); + +/** + * Returns call quality averaged over all the duration of the call. + * + * See linphone_call_get_current_quality() for more details about quality measurement. +**/ +LINPHONE_PUBLIC float linphone_call_get_average_quality(const LinphoneCall *call); + +/** + * Start call recording. + * The output file where audio is recorded must be previously specified with linphone_call_params_set_record_file(). +**/ +LINPHONE_PUBLIC void linphone_call_start_recording(LinphoneCall *call); + +/** + * Stop call recording. +**/ +LINPHONE_PUBLIC void linphone_call_stop_recording(LinphoneCall *call); + +/** + * Get a player associated with the call to play a local file and stream it to the remote peer. + * @param[in] call LinphoneCall object + * @return A LinphonePlayer object + */ +LINPHONE_PUBLIC LinphonePlayer * linphone_call_get_player(LinphoneCall *call); + +/** + * Indicates whether an operation is in progress at the media side. + * It can be a bad idea to initiate signaling operations (adding video, pausing the call, removing video, changing video parameters) while + * the media is busy in establishing the connection (typically ICE connectivity checks). It can result in failures generating loss of time + * in future operations in the call. + * Applications are invited to check this function after each call state change to decide whether certain operations are permitted or not. + * @param call the call + * @return TRUE if media is busy in establishing the connection, FALSE otherwise. +**/ +LINPHONE_PUBLIC bool_t linphone_call_media_in_progress(const LinphoneCall *call); + +/** + * Call generic OpenGL render for a given call. + * @param call The call. + */ +LINPHONE_PUBLIC void linphone_call_ogl_render(const LinphoneCall *call); + +/** + * Send a LinphoneInfoMessage through an established call + * @param call the call + * @param info the info message +**/ +LINPHONE_PUBLIC LinphoneStatus linphone_call_send_info_message(LinphoneCall *call, const LinphoneInfoMessage *info); + +/** + * Return a copy of the call statistics for a particular stream type. + * @param call the call + * @param type the stream type +**/ +LINPHONE_PUBLIC LinphoneCallStats *linphone_call_get_stats(LinphoneCall *call, LinphoneStreamType type); + +LINPHONE_PUBLIC LinphoneCallStats *linphone_call_get_audio_stats(LinphoneCall *call); + +LINPHONE_PUBLIC LinphoneCallStats *linphone_call_get_video_stats(LinphoneCall *call); + +LINPHONE_PUBLIC LinphoneCallStats *linphone_call_get_text_stats(LinphoneCall *call); + +/** + * Add a listener in order to be notified of LinphoneCall events. Once an event is received, registred LinphoneCallCbs are + * invoked sequencially. + * @param[in] call LinphoneCall object to monitor. + * @param[in] cbs A LinphoneCallCbs object holding the callbacks you need. A reference is taken by the LinphoneCall until you invoke linphone_call_remove_callbacks(). + */ +LINPHONE_PUBLIC void linphone_call_add_callbacks(LinphoneCall *call, LinphoneCallCbs *cbs); + +/** + * Remove a listener from a LinphoneCall + * @param[in] call LinphoneCall object + * @param[in] cbs LinphoneCallCbs object to remove. + */ +LINPHONE_PUBLIC void linphone_call_remove_callbacks(LinphoneCall *call, LinphoneCallCbs *cbs); + +/** + * Gets the current LinphoneCallCbs. + * This is meant only to be called from a callback to be able to get the user_data associated with the LinphoneCallCbs that is calling the callback. + * @param[in] call LinphoneCall object + * @return The LinphoneCallCbs that has called the last callback + */ +LINPHONE_PUBLIC LinphoneCallCbs *linphone_call_get_current_callbacks(const LinphoneCall *call); + +/** + * Set call parameters - advanced and not recommended feature - use with caution. + * Local call parameters applicable to an outgoing or incoming shall usually be passed to linphone_core_invite_address_with_params() or + * linphone_call_accept_with_params(). + * However, in some cases it might be desirable from a software design standpoint to modify local parameters outside of the application layer, typically + * in the purpose of implementing a custom logic including special headers in INVITE or 200Ok requests, driven by a call_state_changed listener method. + * This function accepts to assign a new LinphoneCallParams only in LinphoneCallOutgoingInit and LinphoneCallIncomingReceived states. + * @param call the LinphoneCall object +**/ +LINPHONE_PUBLIC void linphone_call_set_params(LinphoneCall *call, const LinphoneCallParams *params); + +/** + * Returns local parameters associated with the call. + * This is typically the parameters passed at call initiation to linphone_core_invite_address_with_params() or linphone_call_accept_with_params(), or some default + * parameters if no LinphoneCallParams was explicitely passed during call initiation. + * @param call the LinphoneCall object + * @return the call's local parameters. + **/ +LINPHONE_PUBLIC const LinphoneCallParams * linphone_call_get_params(LinphoneCall *call); + +/** + * @} + */ + +#ifdef __cplusplus + } +#endif // ifdef __cplusplus + +#endif // ifndef _C_CALL_H_ diff --git a/include/linphone/api/c-callbacks.h b/include/linphone/api/c-callbacks.h index d44de7925..347f03552 100644 --- a/include/linphone/api/c-callbacks.h +++ b/include/linphone/api/c-callbacks.h @@ -29,6 +29,68 @@ extern "C" { #endif // ifdef __cplusplus +/** + * @addtogroup call_control + * @{ +**/ + +/** + * Callback for being notified of received DTMFs. + * @param call LinphoneCall object that received the dtmf + * @param dtmf The ascii code of the dtmf + */ +typedef void (*LinphoneCallCbsDtmfReceivedCb)(LinphoneCall *call, int dtmf); + +/** + * Call encryption changed callback. + * @param call LinphoneCall object whose encryption is changed. + * @param on Whether encryption is activated. + * @param authentication_token An authentication_token, currently set for ZRTP kind of encryption only. + */ +typedef void (*LinphoneCallCbsEncryptionChangedCb)(LinphoneCall *call, bool_t on, const char *authentication_token); + +/** + * Callback for receiving info messages. + * @param call LinphoneCall whose info message belongs to. + * @param msg LinphoneInfoMessage object. + */ +typedef void (*LinphoneCallCbsInfoMessageReceivedCb)(LinphoneCall *call, const LinphoneInfoMessage *msg); + +/** + * Call state notification callback. + * @param call LinphoneCall whose state is changed. + * @param cstate The new state of the call + * @param message An informational message about the state. + */ +typedef void (*LinphoneCallCbsStateChangedCb)(LinphoneCall *call, LinphoneCallState cstate, const char *message); + +/** + * Callback for receiving quality statistics for calls. + * @param call LinphoneCall object whose statistics are notified + * @param stats LinphoneCallStats object + */ +typedef void (*LinphoneCallCbsStatsUpdatedCb)(LinphoneCall *call, const LinphoneCallStats *stats); + +/** + * Callback for notifying progresses of transfers. + * @param call LinphoneCall that was transfered + * @param cstate The state of the call to transfer target at the far end. + */ +typedef void (*LinphoneCallCbsTransferStateChangedCb)(LinphoneCall *call, LinphoneCallState cstate); + +/** + * Callback for notifying the processing SIP ACK messages. + * @param call LinphoneCall for which an ACK is being received or sent + * @param ack the ACK message + * @param is_received if TRUE this ACK is an incoming one, otherwise it is an ACK about to be sent. + */ +typedef void (*LinphoneCallCbsAckProcessingCb)(LinphoneCall *call, LinphoneHeaders *ack, bool_t is_received); + +/** + * @} +**/ + + /** * @addtogroup chatroom * @{ diff --git a/include/linphone/api/c-types.h b/include/linphone/api/c-types.h index be2d44f2b..7cf35f798 100644 --- a/include/linphone/api/c-types.h +++ b/include/linphone/api/c-types.h @@ -69,11 +69,24 @@ typedef unsigned char bool_t; */ typedef struct _LinphoneAddress LinphoneAddress; +/** + * The LinphoneCall object represents a call issued or received by the LinphoneCore + * @ingroup call_control +**/ typedef struct _LinphoneCall LinphoneCall; -// ----------------------------------------------------------------------------- -// Chatroom. -// ----------------------------------------------------------------------------- +/** Callback prototype */ +typedef void (*LinphoneCallCbFunc) (LinphoneCall *call, void *ud); + +/** + * That class holds all the callbacks which are called by LinphoneCall objects. + * + * Use linphone_factory_create_call_cbs() to create an instance. Then, call the + * callback setters on the events you need to monitor and pass the object to + * a LinphoneCall instance through linphone_call_add_callbacks(). + * @ingroup call_control + */ +typedef struct _LinphoneCallCbs LinphoneCallCbs; /** * A chat room is the place where text messages are exchanged. diff --git a/include/linphone/call.h b/include/linphone/call.h index 94ffd09c1..9446df88e 100644 --- a/include/linphone/call.h +++ b/include/linphone/call.h @@ -20,910 +20,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #ifndef LINPHONE_CALL_H #define LINPHONE_CALL_H -#include -#include "linphone/types.h" - -/** - * @addtogroup call_control - * @{ - */ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * 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. -**/ -LINPHONE_PUBLIC LinphoneCall * linphone_call_ref(LinphoneCall *call); - -/** - * Release reference to the call. - * @param[in] call The call. -**/ -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. -**/ -LINPHONE_PUBLIC void * linphone_call_get_user_data(const LinphoneCall *call); - -/** - * Assign a user pointer to the call. - * @param[in] call The call. - * @param[in] ud The user pointer to associate with the call. -**/ -LINPHONE_PUBLIC void linphone_call_set_user_data(LinphoneCall *call, void *ud); - -/** - * Get the core that has created the specified call. - * @param[in] call LinphoneCall object - * @return The LinphoneCore object that has created the specified call. - */ -LINPHONE_PUBLIC LinphoneCore * linphone_call_get_core(const LinphoneCall *call); - -/** - * Retrieves the call's current state. -**/ -LINPHONE_PUBLIC LinphoneCallState linphone_call_get_state(const LinphoneCall *call); - -/** - * Tell whether a call has been asked to autoanswer - * @param[in] call LinphoneCall object - * @return A boolean value telling whether the call has been asked to autoanswer -**/ -LINPHONE_PUBLIC bool_t linphone_call_asked_to_autoanswer(LinphoneCall *call); - -/** - * Returns the remote address associated to this call -**/ -LINPHONE_PUBLIC const LinphoneAddress * linphone_call_get_remote_address(const LinphoneCall *call); - -/** - * Returns the to address with its headers associated to this call -**/ -LINPHONE_PUBLIC const LinphoneAddress * linphone_call_get_to_address(const LinphoneCall * call); - -/** - * Returns the value of the header name -**/ -LINPHONE_PUBLIC const char * linphone_call_get_to_header(const LinphoneCall *call, const char *name); - -/** - * Returns the remote address associated to this call as a string. - * The result string must be freed by user using ms_free(). -**/ -LINPHONE_PUBLIC char * linphone_call_get_remote_address_as_string(const LinphoneCall *call); - -/** - * Returns the diversion address associated to this call -**/ -LINPHONE_PUBLIC const LinphoneAddress * linphone_call_get_diversion_address(const LinphoneCall *call); - -/** - * Returns direction of the call (incoming or outgoing). -**/ -LINPHONE_PUBLIC LinphoneCallDir linphone_call_get_dir(const LinphoneCall *call); - -/** - * Gets the call log associated to this call. - * @param[in] call LinphoneCall object - * @return The LinphoneCallLog associated with the specified LinphoneCall -**/ -LINPHONE_PUBLIC LinphoneCallLog * linphone_call_get_call_log(const LinphoneCall *call); - -/** - * Gets the refer-to uri (if the call was transfered). - * @param[in] call LinphoneCall object - * @return The refer-to uri of the call (if it was transfered) -**/ -LINPHONE_PUBLIC const char * linphone_call_get_refer_to(const LinphoneCall *call); - -/** - * Returns true if this calls has received a transfer that has not been - * executed yet. - * Pending transfers are executed when this call is being paused or closed, - * locally or by remote endpoint. - * If the call is already paused while receiving the transfer request, the - * transfer immediately occurs. -**/ -LINPHONE_PUBLIC bool_t linphone_call_has_transfer_pending(const LinphoneCall *call); - -/** - * Gets the transferer if this call was started automatically as a result of an incoming transfer request. - * The call in which the transfer request was received is returned in this case. - * @param[in] call LinphoneCall object - * @return The transferer call if the specified call was started automatically as a result of an incoming transfer request, NULL otherwise -**/ -LINPHONE_PUBLIC LinphoneCall * linphone_call_get_transferer_call(const LinphoneCall *call); - -/** - * When this call has received a transfer request, returns the new call that was automatically created as a result of the transfer. -**/ -LINPHONE_PUBLIC LinphoneCall * linphone_call_get_transfer_target_call(const LinphoneCall *call); - -/** - * Returns the call object this call is replacing, if any. - * Call replacement can occur during call transfers. - * By default, the core automatically terminates the replaced call and accept the new one. - * This function allows the application to know whether a new incoming call is a one that replaces another one. -**/ -LINPHONE_PUBLIC LinphoneCall * linphone_call_get_replaced_call(LinphoneCall *call); - -/** - * Returns call's duration in seconds. -**/ -LINPHONE_PUBLIC int linphone_call_get_duration(const LinphoneCall *call); - -/** - * Returns current parameters associated to the call. -**/ -LINPHONE_PUBLIC const LinphoneCallParams * linphone_call_get_current_params(LinphoneCall *call); - -/** - * Returns call parameters proposed by remote. - * - * This is useful when receiving an incoming call, to know whether the remote party - * supports video, encryption or whatever. -**/ -LINPHONE_PUBLIC const LinphoneCallParams * linphone_call_get_remote_params(LinphoneCall *call); - -/** - * Indicate whether camera input should be sent to remote end. -**/ -LINPHONE_PUBLIC void linphone_call_enable_camera(LinphoneCall *lc, bool_t enabled); - -/** - * Returns TRUE if camera pictures are allowed to be sent to the remote party. -**/ -LINPHONE_PUBLIC bool_t linphone_call_camera_enabled(const LinphoneCall *lc); - -/** - * Take a photo of currently received video and write it into a jpeg file. - * Note that the snapshot is asynchronous, an application shall not assume that the file is created when the function returns. - * @param call a LinphoneCall - * @param file a path where to write the jpeg content. - * @return 0 if successfull, -1 otherwise (typically if jpeg format is not supported). -**/ -LINPHONE_PUBLIC LinphoneStatus linphone_call_take_video_snapshot(LinphoneCall *call, const char *file); - -/** - * Take a photo of currently captured video and write it into a jpeg file. - * Note that the snapshot is asynchronous, an application shall not assume that the file is created when the function returns. - * @param call a LinphoneCall - * @param file a path where to write the jpeg content. - * @return 0 if successfull, -1 otherwise (typically if jpeg format is not supported). -**/ -LINPHONE_PUBLIC LinphoneStatus linphone_call_take_preview_snapshot(LinphoneCall *call, const char *file); - -/** - * Returns the reason for a call termination (either error or normal termination) -**/ -LINPHONE_PUBLIC LinphoneReason linphone_call_get_reason(const LinphoneCall *call); - - -/** - * Returns full details about call errors or termination reasons. - * @param call LinphoneCall object on which we want the information error - * @return LinphoneErrorInfo object holding the reason error. - */ -LINPHONE_PUBLIC const LinphoneErrorInfo *linphone_call_get_error_info(const LinphoneCall *call); - -/** - * Returns the far end's user agent description string, if available. -**/ -LINPHONE_PUBLIC const char *linphone_call_get_remote_user_agent(LinphoneCall *call); - -/** - * Returns the far end's sip contact as a string, if available. -**/ -LINPHONE_PUBLIC const char *linphone_call_get_remote_contact(LinphoneCall *call); - -/** - * Returns the ZRTP authentication token to verify. - * @param call the LinphoneCall - * @return the authentication token to verify. -**/ -LINPHONE_PUBLIC const char * linphone_call_get_authentication_token(LinphoneCall *call); - -/** - * Returns whether ZRTP authentication token is verified. - * If not, it must be verified by users as described in ZRTP procedure. - * Once done, the application must inform of the results with linphone_call_set_authentication_token_verified(). - * @param call the LinphoneCall - * @return TRUE if authentication token is verifed, false otherwise. -**/ -LINPHONE_PUBLIC bool_t linphone_call_get_authentication_token_verified(const LinphoneCall *call); - -/** - * Set the result of ZRTP short code verification by user. - * If remote party also does the same, it will update the ZRTP cache so that user's verification will not be required for the two users. - * @param call the LinphoneCall - * @param verified whether the ZRTP SAS is verified. -**/ -LINPHONE_PUBLIC void linphone_call_set_authentication_token_verified(LinphoneCall *call, bool_t verified); - -/** - * Request remote side to send us a Video Fast Update. -**/ -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) - -/** @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_next_video_frame_decoded_callback(LinphoneCall *call, LinphoneCallCbFunc cb, void *user_data); - -/** - * Returns the current transfer state, if a transfer has been initiated from this call. - * @see linphone_core_transfer_call() , linphone_core_transfer_call_to_another() -**/ -LINPHONE_PUBLIC LinphoneCallState linphone_call_get_transfer_state(LinphoneCall *call); - -/** - * Perform a zoom of the video displayed during a call. - * @param call the call. - * @param zoom_factor a floating point number describing the zoom factor. A value 1.0 corresponds to no zoom applied. - * @param cx a floating point number pointing the horizontal center of the zoom to be applied. This value should be between 0.0 and 1.0. - * @param cy a floating point number pointing the vertical center of the zoom to be applied. This value should be between 0.0 and 1.0. - * - * cx and cy are updated in return in case their coordinates were too excentrated for the requested zoom factor. The zoom ensures that all the screen is fullfilled with the video. -**/ -LINPHONE_PUBLIC void linphone_call_zoom_video(LinphoneCall *call, float zoom_factor, float *cx, float *cy); - -/** - * Send the specified dtmf. - * - * The dtmf is automatically played to the user. - * @param call The LinphoneCall object - * @param dtmf The dtmf name specified as a char, such as '0', '#' etc... - * @return 0 if successful, -1 on error. -**/ -LINPHONE_PUBLIC LinphoneStatus linphone_call_send_dtmf(LinphoneCall *call, char dtmf); - -/** - * Send a list of dtmf. - * - * The dtmfs are automatically sent to remote, separated by some needed customizable delay. - * Sending is canceled if the call state changes to something not LinphoneCallStreamsRunning. - * @param call The LinphoneCall object - * @param dtmfs A dtmf sequence such as '123#123123' - * @return -2 if there is already a DTMF sequence, -1 if call is not ready, 0 otherwise. -**/ -LINPHONE_PUBLIC LinphoneStatus linphone_call_send_dtmfs(LinphoneCall *call, const char *dtmfs); - -/** - * Stop current DTMF sequence sending. - * - * Please note that some DTMF could be already sent, - * depending on when this function call is delayed from #linphone_call_send_dtmfs. This - * function will be automatically called if call state change to anything but LinphoneCallStreamsRunning. - * @param call The LinphoneCall object -**/ -LINPHONE_PUBLIC void linphone_call_cancel_dtmfs(LinphoneCall *call); - -/** - * Return TRUE if this call is currently part of a conference - * @param call #LinphoneCall - * @return TRUE if part of a conference. - * @deprecated Use linphone_call_get_conference() instead. - * @donotwrap - */ -LINPHONE_PUBLIC LINPHONE_DEPRECATED bool_t linphone_call_is_in_conference(const LinphoneCall *call); - -/** - * Return the associated conference object - * @param call #LinphoneCall - * @return A pointer on #LinphoneConference or NULL if the call is not part of any conference. - */ -LINPHONE_PUBLIC LinphoneConference * linphone_call_get_conference(const LinphoneCall *call); - -/** - * Change the playback output device (currently only used for blackberry) - * @param call - * @param route the wanted audio route (earpiece, speaker, ...) -**/ -LINPHONE_PUBLIC void linphone_call_set_audio_route(LinphoneCall *call, LinphoneAudioRoute route); - -/** - * Returns the number of stream for the given call. - * Currently there is only two (Audio, Video), but later there will be more. - * @param call - * @return 2 -**/ -LINPHONE_PUBLIC int linphone_call_get_stream_count(const LinphoneCall *call); - -/** - * Returns the type of stream for the given stream index. - * @param call - * @param stream_index - * @return the type (MSAudio, MSVideo, MSText) of the stream of given index. -**/ -LINPHONE_PUBLIC MSFormatType linphone_call_get_stream_type(const LinphoneCall *call, int stream_index); - -/** - * Returns the meta rtp transport for the given stream index. - * @param call - * @param stream_index - * @return a pointer to the meta rtp transport if it exists, NULL otherwise -**/ -LINPHONE_PUBLIC RtpTransport * linphone_call_get_meta_rtp_transport(const LinphoneCall *call, int stream_index); - -/** - * Returns the meta rtcp transport for the given stream index. - * @param call - * @param stream_index - * @return a pointer to the meta rtcp transport if it exists, NULL otherwise -**/ -LINPHONE_PUBLIC RtpTransport * linphone_call_get_meta_rtcp_transport(const LinphoneCall *call, int stream_index); - -/** - * Pauses the call. If a music file has been setup using linphone_core_set_play_file(), - * this file will be played to the remote user. - * The only way to resume a paused call is to call linphone_call_resume(). - * @param[in] call LinphoneCall object - * @return 0 on success, -1 on failure - * @see linphone_call_resume() -**/ -LINPHONE_PUBLIC LinphoneStatus linphone_call_pause(LinphoneCall *call); - -/** - * Resumes a call. - * The call needs to have been paused previously with linphone_call_pause(). - * @param[in] call LinphoneCall object - * @return 0 on success, -1 on failure - * @see linphone_call_pause() -**/ -LINPHONE_PUBLIC LinphoneStatus linphone_call_resume(LinphoneCall *call); - -/** - * Terminates a call. - * @param[in] call LinphoneCall object - * @return 0 on success, -1 on failure -**/LINPHONE_PUBLIC LinphoneStatus linphone_call_terminate(LinphoneCall *call); - - -/** - * Terminates a call. - * @param[in] call LinphoneCall object - * @param[in] ei LinphoneErrorInfo - * @return 0 on success, -1 on failure -**/ -LINPHONE_PUBLIC LinphoneStatus linphone_call_terminate_with_error_info(LinphoneCall *call, const LinphoneErrorInfo *ei); - -/** - * Redirect the specified call to the given redirect URI. - * @param[in] call A LinphoneCall object - * @param[in] redirect_uri The URI to redirect the call to - * @return 0 if successful, -1 on error. - */ -LINPHONE_PUBLIC LinphoneStatus linphone_call_redirect(LinphoneCall *call, const char *redirect_uri); - -/** - * Decline a pending incoming call, with a reason. - * @param[in] call A LinphoneCall object that must be in the IncomingReceived state - * @param[in] reason The reason for rejecting the call: LinphoneReasonDeclined or LinphoneReasonBusy - * @return 0 on success, -1 on failure -**/ -LINPHONE_PUBLIC LinphoneStatus linphone_call_decline(LinphoneCall * call, LinphoneReason reason); - -/** - * Decline a pending incoming call, with a LinphoneErrorInfo object. - * @param[in] call A LinphoneCall object that must be in the IncomingReceived state - * @param[in] ei LinphoneErrorInfo containing more information on the call rejection. - * @return 0 on success, -1 on failure - */ -LINPHONE_PUBLIC int linphone_call_decline_with_error_info(LinphoneCall * call, const LinphoneErrorInfo *ei); - -/** - * Accept an incoming call. - * - * Basically the application is notified of incoming calls within the - * call_state_changed callback of the #LinphoneCoreVTable structure, where it will receive - * a LinphoneCallIncoming event with the associated LinphoneCall object. - * The application can later accept the call using this method. - * @param[in] call A LinphoneCall object - * @return 0 on success, -1 on failure -**/ -LINPHONE_PUBLIC LinphoneStatus linphone_call_accept(LinphoneCall *call); - -/** - * Accept an incoming call, with parameters. - * - * Basically the application is notified of incoming calls within the - * call_state_changed callback of the #LinphoneCoreVTable structure, where it will receive - * a LinphoneCallIncoming event with the associated LinphoneCall object. - * The application can later accept the call using this method. - * @param[in] call A LinphoneCall object - * @param[in] params The specific parameters for this call, for example whether video is accepted or not. Use NULL to use default parameters - * @return 0 on success, -1 on failure -**/ -LINPHONE_PUBLIC LinphoneStatus linphone_call_accept_with_params(LinphoneCall *call, const LinphoneCallParams *params); - -/** - * Accept an early media session for an incoming call. - * This is identical as calling linphone_call_accept_early_media_with_params() with NULL parameters. - * @param[in] call A LinphoneCall object - * @return 0 if successful, -1 otherwise - * @see linphone_call_accept_early_media_with_params() -**/ -LINPHONE_PUBLIC LinphoneStatus linphone_call_accept_early_media(LinphoneCall *call); - -/** - * When receiving an incoming, accept to start a media session as early-media. - * This means the call is not accepted but audio & video streams can be established if the remote party supports early media. - * However, unlike after call acceptance, mic and camera input are not sent during early-media, though received audio & video are played normally. - * The call can then later be fully accepted using linphone_call_accept() or linphone_call_accept_with_params(). - * @param[in] call A LinphoneCall object - * @param[in] params The call parameters to use (can be NULL) - * @return 0 if successful, -1 otherwise -**/ -LINPHONE_PUBLIC LinphoneStatus linphone_call_accept_early_media_with_params(LinphoneCall *call, const LinphoneCallParams *params); - -/** - * Updates a running call according to supplied call parameters or parameters changed in the LinphoneCore. - * In this version this is limited to the following use cases: - * - setting up/down the video stream according to the video parameter of the LinphoneCallParams (see linphone_call_params_enable_video() ). - * - changing the size of the transmitted video after calling linphone_core_set_preferred_video_size() - * In case no changes are requested through the LinphoneCallParams argument, then this argument can be omitted and set to NULL. - * WARNING: Updating a call in the LinphoneCallPaused state will still result in a paused call even if the media directions set in the - * params are sendrecv. To resume a paused call, you need to call linphone_call_resume(). - * - * @param[in] call A LinphoneCall object - * @param[in] params The new call parameters to use (may be NULL) - * @return 0 if successful, -1 otherwise. -**/ -LINPHONE_PUBLIC LinphoneStatus linphone_call_update(LinphoneCall *call, const LinphoneCallParams *params); - -/** - * When receiving a #LinphoneCallUpdatedByRemote state notification, prevent LinphoneCore from performing an automatic answer. - * - * When receiving a #LinphoneCallUpdatedByRemote state notification (ie an incoming reINVITE), the default behaviour of - * LinphoneCore is defined by the "defer_update_default" option of the "sip" section of the config. If this option is 0 (the default) - * then the LinphoneCore automatically answers the reINIVTE with call parameters unchanged. - * However when for example when the remote party updated the call to propose a video stream, it can be useful - * to prompt the user before answering. This can be achieved by calling linphone_core_defer_call_update() during - * the call state notification, to deactivate the automatic answer that would just confirm the audio but reject the video. - * Then, when the user responds to dialog prompt, it becomes possible to call linphone_call_accept_update() to answer - * the reINVITE, with eventually video enabled in the LinphoneCallParams argument. - * - * The #LinphoneCallUpdatedByRemote notification can also arrive when receiving an INVITE without SDP. In such case, an unchanged offer is made - * in the 200Ok, and when the ACK containing the SDP answer is received, #LinphoneCallUpdatedByRemote is triggered to notify the application of possible - * changes in the media session. However in such case defering the update has no meaning since we just generating an offer. - * - * @param[in] call A LinphoneCall object - * @return 0 if successful, -1 if the linphone_call_defer_update() was done outside a valid #LinphoneCallUpdatedByRemote notification -**/ -LINPHONE_PUBLIC LinphoneStatus linphone_call_defer_update(LinphoneCall *call); - -/** - * Accept call modifications initiated by other end. - * - * This call may be performed in response to a #LinphoneCallUpdatedByRemote state notification. - * When such notification arrives, the application can decide to call linphone_call_defer_update() so that it can - * have the time to prompt the user. linphone_call_get_remote_params() can be used to get information about the call parameters - * requested by the other party, such as whether a video stream is requested. - * - * When the user accepts or refuse the change, linphone_call_accept_update() can be done to answer to the other party. - * If params is NULL, then the same call parameters established before the update request will continue to be used (no change). - * If params is not NULL, then the update will be accepted according to the parameters passed. - * Typical example is when a user accepts to start video, then params should indicate that video stream should be used - * (see linphone_call_params_enable_video()). - * @param[in] call A LinphoneCall object - * @param[in] params A LinphoneCallParams object describing the call parameters to accept - * @return 0 if successful, -1 otherwise (actually when this function call is performed outside ot #LinphoneCallUpdatedByRemote state) -**/ -LINPHONE_PUBLIC LinphoneStatus linphone_call_accept_update(LinphoneCall *call, const LinphoneCallParams *params); - -/** - * Performs a simple call transfer to the specified destination. - * The remote endpoint is expected to issue a new call to the specified destination. - * The current call remains active and thus can be later paused or terminated. - * It is possible to follow the progress of the transfer provided that transferee sends notification about it. - * In this case, the transfer_state_changed callback of the #LinphoneCoreVTable is invoked to notify of the state of the new call at the other party. - * The notified states are #LinphoneCallOutgoingInit , #LinphoneCallOutgoingProgress, #LinphoneCallOutgoingRinging and #LinphoneCallConnected. - * @param[in] call The call to be transfered - * @param[in] refer_to The destination the call is to be refered to - * @return 0 on success, -1 on failure -**/ -LINPHONE_PUBLIC LinphoneStatus linphone_call_transfer(LinphoneCall *call, const char *refer_to); - -/** - * Transfers a call to destination of another running call. This is used for "attended transfer" scenarios. - * The transfered call is supposed to be in paused state, so that it is able to accept the transfer immediately. - * The destination call is a call previously established to introduce the transfered person. - * This method will send a transfer request to the transfered person. The phone of the transfered is then - * expected to automatically call to the destination of the transfer. The receiver of the transfer will then automatically - * close the call with us (the 'dest' call). - * It is possible to follow the progress of the transfer provided that transferee sends notification about it. - * In this case, the transfer_state_changed callback of the #LinphoneCoreVTable is invoked to notify of the state of the new call at the other party. - * The notified states are #LinphoneCallOutgoingInit , #LinphoneCallOutgoingProgress, #LinphoneCallOutgoingRinging and #LinphoneCallConnected. - * @param[in] call A running call you want to transfer - * @param[in] dest A running call whose remote person will receive the transfer - * @return 0 on success, -1 on failure -**/ -LINPHONE_PUBLIC LinphoneStatus linphone_call_transfer_to_another(LinphoneCall *call, LinphoneCall *dest); - - -/** - * Acquire a reference to the LinphoneCallCbs object. - * @param[in] cbs LinphoneCallCbs object. - * @return The same LinphoneCallCbs object. - */ -LINPHONE_PUBLIC LinphoneCallCbs *linphone_call_cbs_ref(LinphoneCallCbs *cbs); - -/** - * Release reference to the LinphoneCallCbs object. - * @param[in] cbs LinphoneCallCbs object. - */ -LINPHONE_PUBLIC void linphone_call_cbs_unref(LinphoneCallCbs *cbs); - -/** - * Retrieve the user pointer associated with the LinphoneCallCbs object. - * @param[in] cbs LinphoneCallCbs object. - * @return The user pointer associated with the LinphoneCallCbs object. - */ -LINPHONE_PUBLIC void *linphone_call_cbs_get_user_data(const LinphoneCallCbs *cbs); - -/** - * Assign a user pointer to the LinphoneCallCbs object. - * @param[in] cbs LinphoneCallCbs object. - * @param[in] ud The user pointer to associate with the LinphoneCallCbs object. - */ -LINPHONE_PUBLIC void linphone_call_cbs_set_user_data(LinphoneCallCbs *cbs, void *user_data); - -/** - * Get the dtmf received callback. - * @param[in] cbs LinphoneCallCbs object. - * @return The current dtmf received callback. - */ -LINPHONE_PUBLIC LinphoneCallCbsDtmfReceivedCb linphone_call_cbs_get_dtmf_received(LinphoneCallCbs *cbs); - -/** - * Set the dtmf received callback. - * @param[in] cbs LinphoneCallCbs object. - * @param[in] cb The dtmf received callback to be used. - */ -LINPHONE_PUBLIC void linphone_call_cbs_set_dtmf_received(LinphoneCallCbs *cbs, LinphoneCallCbsDtmfReceivedCb cb); - -/** - * Get the encryption changed callback. - * @param[in] cbs LinphoneCallCbs object. - * @return The current encryption changed callback. - */ -LINPHONE_PUBLIC LinphoneCallCbsEncryptionChangedCb linphone_call_cbs_get_encryption_changed(LinphoneCallCbs *cbs); - -/** - * Set the encryption changed callback. - * @param[in] cbs LinphoneCallCbs object. - * @param[in] cb The encryption changed callback to be used. - */ -LINPHONE_PUBLIC void linphone_call_cbs_set_encryption_changed(LinphoneCallCbs *cbs, LinphoneCallCbsEncryptionChangedCb cb); - -/** - * Get the info message received callback. - * @param[in] cbs LinphoneCallCbs object. - * @return The current info message received callback. - */ -LINPHONE_PUBLIC LinphoneCallCbsInfoMessageReceivedCb linphone_call_cbs_get_info_message_received(LinphoneCallCbs *cbs); - -/** - * Set the info message received callback. - * @param[in] cbs LinphoneCallCbs object. - * @param[in] cb The info message received callback to be used. - */ -LINPHONE_PUBLIC void linphone_call_cbs_set_info_message_received(LinphoneCallCbs *cbs, LinphoneCallCbsInfoMessageReceivedCb cb); - -/** - * Get the state changed callback. - * @param[in] cbs LinphoneCallCbs object. - * @return The current state changed callback. - */ -LINPHONE_PUBLIC LinphoneCallCbsStateChangedCb linphone_call_cbs_get_state_changed(LinphoneCallCbs *cbs); - -/** - * Set the state changed callback. - * @param[in] cbs LinphoneCallCbs object. - * @param[in] cb The state changed callback to be used. - */ -LINPHONE_PUBLIC void linphone_call_cbs_set_state_changed(LinphoneCallCbs *cbs, LinphoneCallCbsStateChangedCb cb); - -/** - * Get the stats updated callback. - * @param[in] cbs LinphoneCallCbs object. - * @return The current stats updated callback. - */ -LINPHONE_PUBLIC LinphoneCallCbsStatsUpdatedCb linphone_call_cbs_get_stats_updated(LinphoneCallCbs *cbs); - -/** - * Set the stats updated callback. - * @param[in] cbs LinphoneCallCbs object. - * @param[in] cb The stats updated callback to be used. - */ -LINPHONE_PUBLIC void linphone_call_cbs_set_stats_updated(LinphoneCallCbs *cbs, LinphoneCallCbsStatsUpdatedCb cb); - -/** - * Get the transfer state changed callback. - * @param[in] cbs LinphoneCallCbs object. - * @return The current transfer state changed callback. - */ -LINPHONE_PUBLIC LinphoneCallCbsTransferStateChangedCb linphone_call_cbs_get_transfer_state_changed(LinphoneCallCbs *cbs); - -/** - * Set the transfer state changed callback. - * @param[in] cbs LinphoneCallCbs object. - * @param[in] cb The transfer state changed callback to be used. - */ -LINPHONE_PUBLIC void linphone_call_cbs_set_transfer_state_changed(LinphoneCallCbs *cbs, LinphoneCallCbsTransferStateChangedCb cb); - -/** - * Get the ACK processing callback. - * @param[in] cbs LinphoneCallCbs object. - * @return The current ack processing callback. - */ -LINPHONE_PUBLIC LinphoneCallCbsAckProcessingCb linphone_call_cbs_get_ack_processing(LinphoneCallCbs *cbs); - -/** - * Set ACK processing callback. - * @param[in] cbs LinphoneCallCbs object. - * @param[in] cb The ack processing callback to be used. - */ -LINPHONE_PUBLIC void linphone_call_cbs_set_ack_processing(LinphoneCallCbs *cbs, LinphoneCallCbsAckProcessingCb cb); - -/** - * @} - */ - - -/** - * @addtogroup media_parameters - * @{ - */ - -/** - * Get the native window handle of the video window, casted as an unsigned long. -**/ -LINPHONE_PUBLIC void * linphone_call_get_native_video_window_id(const LinphoneCall *call); - -/** - * Set the native video window id where the video is to be displayed. - * For MacOS, Linux, Windows: if not set or 0 a window will be automatically created, unless the special id -1 is given. -**/ -LINPHONE_PUBLIC void linphone_call_set_native_video_window_id(LinphoneCall *call, void * id); - -/** - * Enables or disable echo cancellation for this call - * @param call - * @param val -**/ -LINPHONE_PUBLIC void linphone_call_enable_echo_cancellation(LinphoneCall *call, bool_t val) ; - -/** - * Returns TRUE if echo cancellation is enabled. -**/ -LINPHONE_PUBLIC bool_t linphone_call_echo_cancellation_enabled(const LinphoneCall *call); - -/** - * Enables or disable echo limiter for this call - * @param call - * @param val -**/ -LINPHONE_PUBLIC void linphone_call_enable_echo_limiter(LinphoneCall *call, bool_t val); - -/** - * Returns TRUE if echo limiter is enabled. -**/ -LINPHONE_PUBLIC bool_t linphone_call_echo_limiter_enabled(const LinphoneCall *call); - -/** - * @} - */ - -/** - * @addtogroup call_misc - * @{ - */ - -/** - * Create a new chat room for messaging from a call if not already existing, else return existing one. - * No reference is given to the caller: the chat room will be deleted when the call is ended. - * @param call #LinphoneCall object - * @return #LinphoneChatRoom where messaging can take place. - */ -LINPHONE_PUBLIC LinphoneChatRoom * linphone_call_get_chat_room(LinphoneCall *call); - -/** - * Get the mesured playback volume level (received from remote) in dbm0. - * @param call The call. - * @return float Volume level in percentage. - */ -LINPHONE_PUBLIC float linphone_call_get_play_volume(const LinphoneCall *call); - -/** - * Get the mesured record volume level (sent to remote) in dbm0. - * @param call The call. - * @return float Volume level in percentage. - */ -LINPHONE_PUBLIC float linphone_call_get_record_volume(const LinphoneCall *call); - -/** - * Get speaker volume gain. - * If the sound backend supports it, the returned gain is equal to the gain set - * with the system mixer. - * @param call The call. - * @return Percenatge of the max supported volume gain. Valid values are in [ 0.0 : 1.0 ]. - * In case of failure, a negative value is returned - */ -LINPHONE_PUBLIC float linphone_call_get_speaker_volume_gain(const LinphoneCall *call); - -/** - * Set speaker volume gain. - * If the sound backend supports it, the new gain will synchronized with the system mixer. - * @param call The call. - * @param volume Percentage of the max supported gain. Valid values are in [ 0.0 : 1.0 ]. - */ -LINPHONE_PUBLIC void linphone_call_set_speaker_volume_gain(LinphoneCall *call, float volume); - -/** - * Get microphone volume gain. - * If the sound backend supports it, the returned gain is equal to the gain set - * with the system mixer. - * @param call The call. - * @return double Percenatge of the max supported volume gain. Valid values are in [ 0.0 : 1.0 ]. - * In case of failure, a negative value is returned - */ -LINPHONE_PUBLIC float linphone_call_get_microphone_volume_gain(const LinphoneCall *call); - -/** - * Set microphone volume gain. - * If the sound backend supports it, the new gain will synchronized with the system mixer. - * @param call The call. - * @param volume Percentage of the max supported gain. Valid values are in [ 0.0 : 1.0 ]. - */ -LINPHONE_PUBLIC void linphone_call_set_microphone_volume_gain(LinphoneCall *call, float volume); - -/** - * Obtain real-time quality rating of the call - * - * Based on local RTP statistics and RTCP feedback, a quality rating is computed and updated - * during all the duration of the call. This function returns its value at the time of the function call. - * It is expected that the rating is updated at least every 5 seconds or so. - * The rating is a floating point number comprised between 0 and 5. - * - * 4-5 = good quality
- * 3-4 = average quality
- * 2-3 = poor quality
- * 1-2 = very poor quality
- * 0-1 = can't be worse, mostly unusable
- * - * @return The function returns -1 if no quality measurement is available, for example if no - * active audio stream exist. Otherwise it returns the quality rating. -**/ -LINPHONE_PUBLIC float linphone_call_get_current_quality(const LinphoneCall *call); - -/** - * Returns call quality averaged over all the duration of the call. - * - * See linphone_call_get_current_quality() for more details about quality measurement. -**/ -LINPHONE_PUBLIC float linphone_call_get_average_quality(const LinphoneCall *call); - -/** - * Start call recording. - * The output file where audio is recorded must be previously specified with linphone_call_params_set_record_file(). -**/ -LINPHONE_PUBLIC void linphone_call_start_recording(LinphoneCall *call); - -/** - * Stop call recording. -**/ -LINPHONE_PUBLIC void linphone_call_stop_recording(LinphoneCall *call); - -/** - * Get a player associated with the call to play a local file and stream it to the remote peer. - * @param[in] call LinphoneCall object - * @return A LinphonePlayer object - */ -LINPHONE_PUBLIC LinphonePlayer * linphone_call_get_player(LinphoneCall *call); - -/** - * Indicates whether an operation is in progress at the media side. - * It can be a bad idea to initiate signaling operations (adding video, pausing the call, removing video, changing video parameters) while - * the media is busy in establishing the connection (typically ICE connectivity checks). It can result in failures generating loss of time - * in future operations in the call. - * Applications are invited to check this function after each call state change to decide whether certain operations are permitted or not. - * @param call the call - * @return TRUE if media is busy in establishing the connection, FALSE otherwise. -**/ -LINPHONE_PUBLIC bool_t linphone_call_media_in_progress(const LinphoneCall *call); - -/** - * Call generic OpenGL render for a given call. - * @param call The call. - */ -LINPHONE_PUBLIC void linphone_call_ogl_render(const LinphoneCall *call); - - - -/** - * Send a LinphoneInfoMessage through an established call - * @param call the call - * @param info the info message -**/ -LINPHONE_PUBLIC LinphoneStatus linphone_call_send_info_message(LinphoneCall *call, const LinphoneInfoMessage *info); - -/** - * Return a copy of the call statistics for a particular stream type. - * @param call the call - * @param type the stream type -**/ -LINPHONE_PUBLIC LinphoneCallStats *linphone_call_get_stats(LinphoneCall *call, LinphoneStreamType type); - -LINPHONE_PUBLIC LinphoneCallStats *linphone_call_get_audio_stats(LinphoneCall *call); - -LINPHONE_PUBLIC LinphoneCallStats *linphone_call_get_video_stats(LinphoneCall *call); - -LINPHONE_PUBLIC LinphoneCallStats *linphone_call_get_text_stats(LinphoneCall *call); - -/** - * Add a listener in order to be notified of LinphoneCall events. Once an event is received, registred LinphoneCallCbs are - * invoked sequencially. - * @param[in] call LinphoneCall object to monitor. - * @param[in] cbs A LinphoneCallCbs object holding the callbacks you need. A reference is taken by the LinphoneCall until you invoke linphone_call_remove_callbacks(). - */ -LINPHONE_PUBLIC void linphone_call_add_callbacks(LinphoneCall *call, LinphoneCallCbs *cbs); - -/** - * Remove a listener from a LinphoneCall - * @param[in] call LinphoneCall object - * @param[in] cbs LinphoneCallCbs object to remove. - */ -LINPHONE_PUBLIC void linphone_call_remove_callbacks(LinphoneCall *call, LinphoneCallCbs *cbs); - -/** - * Gets the current LinphoneCallCbs. - * This is meant only to be called from a callback to be able to get the user_data associated with the LinphoneCallCbs that is calling the callback. - * @param[in] call LinphoneCall object - * @return The LinphoneCallCbs that has called the last callback - */ -LINPHONE_PUBLIC LinphoneCallCbs *linphone_call_get_current_callbacks(const LinphoneCall *call); - -/** - * Set call parameters - advanced and not recommended feature - use with caution. - * Local call parameters applicable to an outgoing or incoming shall usually be passed to linphone_core_invite_address_with_params() or - * linphone_call_accept_with_params(). - * However, in some cases it might be desirable from a software design standpoint to modify local parameters outside of the application layer, typically - * in the purpose of implementing a custom logic including special headers in INVITE or 200Ok requests, driven by a call_state_changed listener method. - * This function accepts to assign a new LinphoneCallParams only in LinphoneCallOutgoingInit and LinphoneCallIncomingReceived states. - * @param call the LinphoneCall object -**/ -LINPHONE_PUBLIC void linphone_call_set_params(LinphoneCall *call, const LinphoneCallParams *params); - -/** - * Returns local parameters associated with the call. - * This is typically the parameters passed at call initiation to linphone_core_invite_address_with_params() or linphone_call_accept_with_params(), or some default - * parameters if no LinphoneCallParams was explicitely passed during call initiation. - * @param call the LinphoneCall object - * @return the call's local parameters. - **/ -LINPHONE_PUBLIC const LinphoneCallParams * linphone_call_get_params(LinphoneCall *call); - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif +#include "linphone/api/c-call.h" #endif /* LINPHONE_CALL_H */ diff --git a/include/linphone/call_stats.h b/include/linphone/call_stats.h index ff2074dba..bbed92e75 100644 --- a/include/linphone/call_stats.h +++ b/include/linphone/call_stats.h @@ -20,164 +20,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #ifndef LINPHONE_CALL_STATS_H #define LINPHONE_CALL_STATS_H -#include "linphone/types.h" +#include "linphone/api/c-call-stats.h" -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @addtogroup call_misc - * @{ - */ - -#define LINPHONE_CALL_STATS_AUDIO ((int)LinphoneStreamTypeAudio) -#define LINPHONE_CALL_STATS_VIDEO ((int)LinphoneStreamTypeVideo) -#define LINPHONE_CALL_STATS_TEXT ((int)LinphoneStreamTypeText) - -#define LINPHONE_CALL_STATS_RECEIVED_RTCP_UPDATE (1 << 0) /**< received_rtcp field of LinphoneCallStats object has been updated */ -#define LINPHONE_CALL_STATS_SENT_RTCP_UPDATE (1 << 1) /**< sent_rtcp field of LinphoneCallStats object has been updated */ -#define LINPHONE_CALL_STATS_PERIODICAL_UPDATE (1 << 2) /**< Every seconds LinphoneCallStats object has been updated */ - -/** - * Increment refcount. - * @param[in] stats LinphoneCallStats object - * @ingroup misc -**/ -LINPHONE_PUBLIC LinphoneCallStats *linphone_call_stats_ref(LinphoneCallStats *stats); - -/** - * Decrement refcount and possibly free the object. - * @param[in] stats LinphoneCallStats object - * @ingroup misc -**/ -LINPHONE_PUBLIC void linphone_call_stats_unref(LinphoneCallStats *stats); - -/** - * Gets the user data in the LinphoneCallStats object - * @param[in] stats the LinphoneCallStats - * @return the user data - * @ingroup misc -*/ -LINPHONE_PUBLIC void *linphone_call_stats_get_user_data(const LinphoneCallStats *stats); - -/** - * Sets the user data in the LinphoneCallStats object - * @param[in] stats the LinphoneCallStats object - * @param[in] data the user data - * @ingroup misc -*/ -LINPHONE_PUBLIC void linphone_call_stats_set_user_data(LinphoneCallStats *stats, void *data); - -/** - * Get the type of the stream the stats refer to. - * @param[in] stats LinphoneCallStats object - * @return The type of the stream the stats refer to - */ -LINPHONE_PUBLIC LinphoneStreamType linphone_call_stats_get_type(const LinphoneCallStats *stats); - -/** - * Get the local loss rate since last report - * @return The sender loss rate -**/ -LINPHONE_PUBLIC float linphone_call_stats_get_sender_loss_rate(const LinphoneCallStats *stats); - -/** - * Gets the remote reported loss rate since last report - * @return The receiver loss rate -**/ -LINPHONE_PUBLIC float linphone_call_stats_get_receiver_loss_rate(const LinphoneCallStats *stats); - -/** - * Get the local loss rate since last report - * @return The local loss rate -**/ -LINPHONE_PUBLIC float linphone_call_stats_get_local_loss_rate(const LinphoneCallStats *stats); - -/** - * Gets the local late rate since last report - * @return The local late rate -**/ -LINPHONE_PUBLIC float linphone_call_stats_get_local_late_rate(const LinphoneCallStats *stats); - -/** - * Gets the local interarrival jitter - * @param[in] stats LinphoneCallStats object - * @return The interarrival jitter at last emitted sender report -**/ -LINPHONE_PUBLIC float linphone_call_stats_get_sender_interarrival_jitter(const LinphoneCallStats *stats); - -/** - * Gets the remote reported interarrival jitter - * @param[in] stats LinphoneCallStats object - * @return The interarrival jitter at last received receiver report -**/ -LINPHONE_PUBLIC float linphone_call_stats_get_receiver_interarrival_jitter(const LinphoneCallStats *stats); - -LINPHONE_PUBLIC const rtp_stats_t *linphone_call_stats_get_rtp_stats(const LinphoneCallStats *stats); - -/** - * Gets the cumulative number of late packets - * @param[in] stats LinphoneCallStats object - * @return The cumulative number of late packets -**/ -LINPHONE_PUBLIC uint64_t linphone_call_stats_get_late_packets_cumulative_number(const LinphoneCallStats *stats); - -/** - * Get the bandwidth measurement of the received stream, expressed in kbit/s, including IP/UDP/RTP headers. - * @param[in] stats LinphoneCallStats object - * @return The bandwidth measurement of the received stream in kbit/s. - */ -LINPHONE_PUBLIC float linphone_call_stats_get_download_bandwidth(const LinphoneCallStats *stats); - -/** - * Get the bandwidth measurement of the sent stream, expressed in kbit/s, including IP/UDP/RTP headers. - * @param[in] stats LinphoneCallStats object - * @return The bandwidth measurement of the sent stream in kbit/s. - */ -LINPHONE_PUBLIC float linphone_call_stats_get_upload_bandwidth(const LinphoneCallStats *stats); - -/** - * Get the state of ICE processing. - * @param[in] stats LinphoneCallStats object - * @return The state of ICE processing. - */ -LINPHONE_PUBLIC LinphoneIceState linphone_call_stats_get_ice_state(const LinphoneCallStats *stats); - -/** - * Get the state of uPnP processing. - * @param[in] stats LinphoneCallStats object - * @return The state of uPnP processing. - */ -LINPHONE_PUBLIC LinphoneUpnpState linphone_call_stats_get_upnp_state(const LinphoneCallStats *stats); - -/** - * Get the IP address family of the remote peer. - * @param[in] stats LinphoneCallStats object - * @return The IP address family of the remote peer. - */ -LINPHONE_PUBLIC LinphoneAddressFamily linphone_call_stats_get_ip_family_of_remote(const LinphoneCallStats *stats); - -/** - * Get the jitter buffer size in ms. - * @param[in] stats LinphoneCallStats object - * @return The jitter buffer size in ms. - */ -LINPHONE_PUBLIC float linphone_call_stats_get_jitter_buffer_size_ms(const LinphoneCallStats *stats); - -/** - * Get the round trip delay in s. - * @param[in] stats LinphoneCallStats object - * @return The round trip delay in s. - */ -LINPHONE_PUBLIC float linphone_call_stats_get_round_trip_delay(const LinphoneCallStats *stats); - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif /* LINPHONE_ADDRESS_H */ +#endif /* LINPHONE_CALL_STATS_H */ diff --git a/include/linphone/callbacks.h b/include/linphone/callbacks.h index d99128a2d..1c9b8b9ba 100644 --- a/include/linphone/callbacks.h +++ b/include/linphone/callbacks.h @@ -34,67 +34,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * @} **/ -/** - * @addtogroup call_control - * @{ -**/ - -/** - * Callback for being notified of received DTMFs. - * @param call LinphoneCall object that received the dtmf - * @param dtmf The ascii code of the dtmf - */ -typedef void (*LinphoneCallCbsDtmfReceivedCb)(LinphoneCall *call, int dtmf); - -/** - * Call encryption changed callback. - * @param call LinphoneCall object whose encryption is changed. - * @param on Whether encryption is activated. - * @param authentication_token An authentication_token, currently set for ZRTP kind of encryption only. - */ -typedef void (*LinphoneCallCbsEncryptionChangedCb)(LinphoneCall *call, bool_t on, const char *authentication_token); - -/** - * Callback for receiving info messages. - * @param call LinphoneCall whose info message belongs to. - * @param msg LinphoneInfoMessage object. - */ -typedef void (*LinphoneCallCbsInfoMessageReceivedCb)(LinphoneCall *call, const LinphoneInfoMessage *msg); - -/** - * Call state notification callback. - * @param call LinphoneCall whose state is changed. - * @param cstate The new state of the call - * @param message An informational message about the state. - */ -typedef void (*LinphoneCallCbsStateChangedCb)(LinphoneCall *call, LinphoneCallState cstate, const char *message); - -/** - * Callback for receiving quality statistics for calls. - * @param call LinphoneCall object whose statistics are notified - * @param stats LinphoneCallStats object - */ -typedef void (*LinphoneCallCbsStatsUpdatedCb)(LinphoneCall *call, const LinphoneCallStats *stats); - -/** - * Callback for notifying progresses of transfers. - * @param call LinphoneCall that was transfered - * @param cstate The state of the call to transfer target at the far end. - */ -typedef void (*LinphoneCallCbsTransferStateChangedCb)(LinphoneCall *call, LinphoneCallState cstate); - -/** - * Callback for notifying the processing SIP ACK messages. - * @param call LinphoneCall for which an ACK is being received or sent - * @param ack the ACK message - * @param is_received if TRUE this ACK is an incoming one, otherwise it is an ACK about to be sent. - */ -typedef void (*LinphoneCallCbsAckProcessingCb)(LinphoneCall *call, LinphoneHeaders *ack, bool_t is_received); - -/** - * @} -**/ - /** * @addtogroup initializing * @{ diff --git a/include/linphone/types.h b/include/linphone/types.h index 3abe0f1bd..9690ed1d2 100644 --- a/include/linphone/types.h +++ b/include/linphone/types.h @@ -241,25 +241,6 @@ typedef enum _LinphoneAVPFMode { **/ typedef struct _LinphoneBuffer LinphoneBuffer; -/** - * The LinphoneCall object represents a call issued or received by the LinphoneCore - * @ingroup call_control -**/ -typedef struct _LinphoneCall LinphoneCall; - -/** - * That class holds all the callbacks which are called by LinphoneCall objects. - * - * Use linphone_factory_create_call_cbs() to create an instance. Then, call the - * callback setters on the events you need to monitor and pass the object to - * a LinphoneCall instance through linphone_call_add_callbacks(). - * @ingroup call_control - */ -typedef struct _LinphoneCallCbs LinphoneCallCbs; - -/** Callback prototype */ -typedef void (*LinphoneCallCbFunc)(LinphoneCall *call, void *user_data); - /** * Enum representing the direction of a call. * @ingroup call_logs diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3915f3584..edda58ab5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -103,7 +103,10 @@ set(LINPHONE_CXX_OBJECTS_PRIVATE_HEADER_FILES set(LINPHONE_CXX_OBJECTS_SOURCE_FILES address/address.cpp c-wrapper/api/c-address.cpp + c-wrapper/api/c-call.cpp + c-wrapper/api/c-call-cbs.cpp c-wrapper/api/c-call-params.cpp + c-wrapper/api/c-call-stats.cpp c-wrapper/api/c-chat-message.cpp c-wrapper/api/c-chat-message-cbs.cpp c-wrapper/api/c-chat-room.cpp diff --git a/src/c-wrapper/api/c-call-cbs.cpp b/src/c-wrapper/api/c-call-cbs.cpp new file mode 100644 index 000000000..241be5ab7 --- /dev/null +++ b/src/c-wrapper/api/c-call-cbs.cpp @@ -0,0 +1,125 @@ +/* + * c-call-cbs.cpp + * Copyright (C) 2017 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 3 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, see . + */ + +#include "linphone/api/c-call-cbs.h" + +#include "c-wrapper/c-wrapper.h" + +// ============================================================================= + +struct _LinphoneCallCbs { + belle_sip_object_t base; + void *userData; + LinphoneCallCbsDtmfReceivedCb dtmfReceivedCb; + LinphoneCallCbsEncryptionChangedCb encryptionChangedCb; + LinphoneCallCbsInfoMessageReceivedCb infoMessageReceivedCb; + LinphoneCallCbsStateChangedCb stateChangedCb; + LinphoneCallCbsStatsUpdatedCb statsUpdatedCb; + LinphoneCallCbsTransferStateChangedCb transferStateChangedCb; + LinphoneCallCbsAckProcessingCb ackProcessing; +}; + +BELLE_SIP_DECLARE_VPTR_NO_EXPORT(LinphoneCallCbs); + +BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneCallCbs); + +BELLE_SIP_INSTANCIATE_VPTR(LinphoneCallCbs, belle_sip_object_t, + NULL, // destroy + NULL, // clone + NULL, // marshal + FALSE +); + +// ============================================================================= + +LinphoneCallCbs *_linphone_call_cbs_new (void) { + return belle_sip_object_new(LinphoneCallCbs); +} + +LinphoneCallCbs *linphone_call_cbs_ref (LinphoneCallCbs *cbs) { + belle_sip_object_ref(cbs); + return cbs; +} + +void linphone_call_cbs_unref (LinphoneCallCbs *cbs) { + belle_sip_object_unref(cbs); +} + +void *linphone_call_cbs_get_user_data (const LinphoneCallCbs *cbs) { + return cbs->userData; +} + +void linphone_call_cbs_set_user_data (LinphoneCallCbs *cbs, void *ud) { + cbs->userData = ud; +} + +LinphoneCallCbsDtmfReceivedCb linphone_call_cbs_get_dtmf_received (LinphoneCallCbs *cbs) { + return cbs->dtmfReceivedCb; +} + +void linphone_call_cbs_set_dtmf_received (LinphoneCallCbs *cbs, LinphoneCallCbsDtmfReceivedCb cb) { + cbs->dtmfReceivedCb = cb; +} + +LinphoneCallCbsEncryptionChangedCb linphone_call_cbs_get_encryption_changed (LinphoneCallCbs *cbs) { + return cbs->encryptionChangedCb; +} + +void linphone_call_cbs_set_encryption_changed (LinphoneCallCbs *cbs, LinphoneCallCbsEncryptionChangedCb cb) { + cbs->encryptionChangedCb = cb; +} + +LinphoneCallCbsInfoMessageReceivedCb linphone_call_cbs_get_info_message_received (LinphoneCallCbs *cbs) { + return cbs->infoMessageReceivedCb; +} + +void linphone_call_cbs_set_info_message_received (LinphoneCallCbs *cbs, LinphoneCallCbsInfoMessageReceivedCb cb) { + cbs->infoMessageReceivedCb = cb; +} + +LinphoneCallCbsStateChangedCb linphone_call_cbs_get_state_changed (LinphoneCallCbs *cbs) { + return cbs->stateChangedCb; +} + +void linphone_call_cbs_set_state_changed (LinphoneCallCbs *cbs, LinphoneCallCbsStateChangedCb cb) { + cbs->stateChangedCb = cb; +} + +LinphoneCallCbsStatsUpdatedCb linphone_call_cbs_get_stats_updated (LinphoneCallCbs *cbs) { + return cbs->statsUpdatedCb; +} + +void linphone_call_cbs_set_stats_updated (LinphoneCallCbs *cbs, LinphoneCallCbsStatsUpdatedCb cb) { + cbs->statsUpdatedCb = cb; +} + +LinphoneCallCbsTransferStateChangedCb linphone_call_cbs_get_transfer_state_changed (LinphoneCallCbs *cbs) { + return cbs->transferStateChangedCb; +} + +void linphone_call_cbs_set_transfer_state_changed (LinphoneCallCbs *cbs, LinphoneCallCbsTransferStateChangedCb cb) { + cbs->transferStateChangedCb = cb; +} + +LinphoneCallCbsAckProcessingCb linphone_call_cbs_get_ack_processing (LinphoneCallCbs *cbs){ + return cbs->ackProcessing; +} + +void linphone_call_cbs_set_ack_processing (LinphoneCallCbs *cbs, LinphoneCallCbsAckProcessingCb cb){ + cbs->ackProcessing = cb; +} diff --git a/src/c-wrapper/api/c-call-stats.cpp b/src/c-wrapper/api/c-call-stats.cpp new file mode 100644 index 000000000..a4cbe1c9f --- /dev/null +++ b/src/c-wrapper/api/c-call-stats.cpp @@ -0,0 +1,343 @@ +/* + * c-call-stats.cpp + * Copyright (C) 2017 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 3 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, see . + */ + +#include "linphone/api/c-call-stats.h" + +#include "c-wrapper/c-wrapper.h" + +// ============================================================================= + +void _linphone_call_stats_clone (LinphoneCallStats *dst, const LinphoneCallStats *src); + +/** + * The LinphoneCallStats objects carries various statistic informations regarding quality of audio or video streams. + * + * To receive these informations periodically and as soon as they are computed, the application is invited to place a #LinphoneCoreCallStatsUpdatedCb callback in the LinphoneCoreVTable structure + * it passes for instantiating the LinphoneCore object (see linphone_core_new() ). + * + * At any time, the application can access last computed statistics using linphone_call_get_audio_stats() or linphone_call_get_video_stats(). +**/ +struct _LinphoneCallStats { + belle_sip_object_t base; + void *user_data; + LinphoneStreamType type; /**< Type of the stream which the stats refer to */ + jitter_stats_t jitter_stats; /**received_rtcp) { + freemsg(stats->received_rtcp); + stats->received_rtcp=NULL; + } + if (stats->sent_rtcp){ + freemsg(stats->sent_rtcp); + stats->sent_rtcp=NULL; + } +} + +void _linphone_call_stats_clone (LinphoneCallStats *dst, const LinphoneCallStats *src) { + /* + * Save the belle_sip_object_t part, copy the entire structure and restore the belle_sip_object_t part + */ + belle_sip_object_t tmp = dst->base; + memcpy(dst, src, sizeof(LinphoneCallStats)); + dst->base = tmp; + + dst->received_rtcp = NULL; + dst->sent_rtcp = NULL; +} + +void _linphone_call_stats_set_ice_state (LinphoneCallStats *stats, LinphoneIceState state) { + stats->ice_state = state; +} + +void _linphone_call_stats_set_type (LinphoneCallStats *stats, LinphoneStreamType type) { + stats->type = type; +} + +void _linphone_call_stats_set_received_rtcp (LinphoneCallStats *stats, mblk_t *m) { + stats->received_rtcp = m; +} + +void _linphone_call_stats_set_sent_rtcp (LinphoneCallStats *stats, mblk_t *m) { + stats->sent_rtcp = m; +} + +int _linphone_call_stats_get_updated (const LinphoneCallStats *stats) { + return stats->updated; +} + +void _linphone_call_stats_set_updated (LinphoneCallStats *stats, int updated) { + stats->updated = updated; +} + +void _linphone_call_stats_set_rtp_stats (LinphoneCallStats *stats, const rtp_stats_t *rtpStats) { + memcpy(&(stats->rtp_stats), rtpStats, sizeof(*rtpStats)); +} + +void _linphone_call_stats_set_download_bandwidth (LinphoneCallStats *stats, float bandwidth) { + stats->download_bandwidth = bandwidth; +} + +void _linphone_call_stats_set_upload_bandwidth (LinphoneCallStats *stats, float bandwidth) { + stats->upload_bandwidth = bandwidth; +} + +void _linphone_call_stats_set_rtcp_download_bandwidth (LinphoneCallStats *stats, float bandwidth) { + stats->rtcp_download_bandwidth = bandwidth; +} + +void _linphone_call_stats_set_rtcp_upload_bandwidth (LinphoneCallStats *stats, float bandwidth) { + stats->rtcp_upload_bandwidth = bandwidth; +} + +void _linphone_call_stats_set_ip_family_of_remote (LinphoneCallStats *stats, LinphoneAddressFamily family) { + stats->rtp_remote_family = family; +} + +// ============================================================================= +// Public functions +// ============================================================================= + +LinphoneCallStats *linphone_call_stats_ref (LinphoneCallStats* stats) { + return (LinphoneCallStats*) belle_sip_object_ref(stats); +} + +void linphone_call_stats_unref (LinphoneCallStats* stats) { + belle_sip_object_unref(stats); +} + +void *linphone_call_stats_get_user_data (const LinphoneCallStats *stats) { + return stats->user_data; +} + +void linphone_call_stats_set_user_data (LinphoneCallStats *stats, void *data) { + stats->user_data = data; +} + +void linphone_call_stats_update (LinphoneCallStats *stats, MediaStream *stream) { + PayloadType *pt; + RtpSession *session = stream->sessions.rtp_session; + const MSQualityIndicator *qi = media_stream_get_quality_indicator(stream); + if (qi) { + stats->local_late_rate=ms_quality_indicator_get_local_late_rate(qi); + stats->local_loss_rate=ms_quality_indicator_get_local_loss_rate(qi); + } + media_stream_get_local_rtp_stats(stream, &stats->rtp_stats); + pt = rtp_profile_get_payload(rtp_session_get_profile(session), rtp_session_get_send_payload_type(session)); + stats->clockrate = pt ? pt->clock_rate : 8000; +} + +/*do not change the prototype of this function, it is also used internally in linphone-daemon.*/ +void linphone_call_stats_fill (LinphoneCallStats *stats, MediaStream *ms, OrtpEvent *ev) { + OrtpEventType evt=ortp_event_get_type(ev); + OrtpEventData *evd=ortp_event_get_data(ev); + + if (evt == ORTP_EVENT_RTCP_PACKET_RECEIVED) { + stats->round_trip_delay = rtp_session_get_round_trip_propagation(ms->sessions.rtp_session); + if(stats->received_rtcp != NULL) + freemsg(stats->received_rtcp); + stats->received_rtcp = evd->packet; + stats->rtcp_received_via_mux = evd->info.socket_type == OrtpRTPSocket; + evd->packet = NULL; + stats->updated = LINPHONE_CALL_STATS_RECEIVED_RTCP_UPDATE; + linphone_call_stats_update(stats,ms); + } else if (evt == ORTP_EVENT_RTCP_PACKET_EMITTED) { + memcpy(&stats->jitter_stats, rtp_session_get_jitter_stats(ms->sessions.rtp_session), sizeof(jitter_stats_t)); + if (stats->sent_rtcp != NULL) + freemsg(stats->sent_rtcp); + stats->sent_rtcp = evd->packet; + evd->packet = NULL; + stats->updated = LINPHONE_CALL_STATS_SENT_RTCP_UPDATE; + linphone_call_stats_update(stats,ms); + } +} + +LinphoneStreamType linphone_call_stats_get_type (const LinphoneCallStats *stats) { + return stats->type; +} + +float linphone_call_stats_get_sender_loss_rate (const LinphoneCallStats *stats) { + const report_block_t *srb = NULL; + + if (!stats || !stats->sent_rtcp) + return 0.0; + /* Perform msgpullup() to prevent crashes in rtcp_is_SR() or rtcp_is_RR() if the RTCP packet is composed of several mblk_t structure */ + if (stats->sent_rtcp->b_cont != NULL) + msgpullup(stats->sent_rtcp, -1); + + do{ + if (rtcp_is_SR(stats->sent_rtcp)) + srb = rtcp_SR_get_report_block(stats->sent_rtcp, 0); + else if (rtcp_is_RR(stats->sent_rtcp)) + srb = rtcp_RR_get_report_block(stats->sent_rtcp, 0); + if (srb) break; + }while (rtcp_next_packet(stats->sent_rtcp)); + rtcp_rewind(stats->sent_rtcp); + if (!srb) + return 0.0; + return 100.0f * (float)report_block_get_fraction_lost(srb) / 256.0f; +} + +float linphone_call_stats_get_receiver_loss_rate (const LinphoneCallStats *stats) { + const report_block_t *rrb = NULL; + + if (!stats || !stats->received_rtcp) + return 0.0; + /* Perform msgpullup() to prevent crashes in rtcp_is_SR() or rtcp_is_RR() if the RTCP packet is composed of several mblk_t structure */ + if (stats->received_rtcp->b_cont != NULL) + msgpullup(stats->received_rtcp, -1); + + do{ + if (rtcp_is_RR(stats->received_rtcp)) + rrb = rtcp_RR_get_report_block(stats->received_rtcp, 0); + else if (rtcp_is_SR(stats->received_rtcp)) + rrb = rtcp_SR_get_report_block(stats->received_rtcp, 0); + if (rrb) break; + }while (rtcp_next_packet(stats->received_rtcp)); + rtcp_rewind(stats->received_rtcp); + if (!rrb) + return 0.0; + return 100.0f * (float)report_block_get_fraction_lost(rrb) / 256.0f; +} + +float linphone_call_stats_get_local_loss_rate (const LinphoneCallStats *stats) { + return stats->local_loss_rate; +} + +float linphone_call_stats_get_local_late_rate (const LinphoneCallStats *stats) { + return stats->local_late_rate; +} + +float linphone_call_stats_get_sender_interarrival_jitter (const LinphoneCallStats *stats) { + const report_block_t *srb = NULL; + + if (!stats || !stats->sent_rtcp) + return 0.0; + /* Perform msgpullup() to prevent crashes in rtcp_is_SR() or rtcp_is_RR() if the RTCP packet is composed of several mblk_t structure */ + if (stats->sent_rtcp->b_cont != NULL) + msgpullup(stats->sent_rtcp, -1); + if (rtcp_is_SR(stats->sent_rtcp)) + srb = rtcp_SR_get_report_block(stats->sent_rtcp, 0); + else if (rtcp_is_RR(stats->sent_rtcp)) + srb = rtcp_RR_get_report_block(stats->sent_rtcp, 0); + if (!srb) + return 0.0; + if (stats->clockrate == 0) + return 0.0; + return (float)report_block_get_interarrival_jitter(srb) / (float)stats->clockrate; +} + +float linphone_call_stats_get_receiver_interarrival_jitter (const LinphoneCallStats *stats) { + const report_block_t *rrb = NULL; + + if (!stats || !stats->received_rtcp) + return 0.0; + /* Perform msgpullup() to prevent crashes in rtcp_is_SR() or rtcp_is_RR() if the RTCP packet is composed of several mblk_t structure */ + if (stats->received_rtcp->b_cont != NULL) + msgpullup(stats->received_rtcp, -1); + if (rtcp_is_SR(stats->received_rtcp)) + rrb = rtcp_SR_get_report_block(stats->received_rtcp, 0); + else if (rtcp_is_RR(stats->received_rtcp)) + rrb = rtcp_RR_get_report_block(stats->received_rtcp, 0); + if (!rrb) + return 0.0; + if (stats->clockrate == 0) + return 0.0; + return (float)report_block_get_interarrival_jitter(rrb) / (float)stats->clockrate; +} + +const rtp_stats_t *linphone_call_stats_get_rtp_stats (const LinphoneCallStats *stats) { + return &stats->rtp_stats; +} + +uint64_t linphone_call_stats_get_late_packets_cumulative_number (const LinphoneCallStats *stats) { + return linphone_call_stats_get_rtp_stats(stats)->outoftime; +} + +float linphone_call_stats_get_download_bandwidth (const LinphoneCallStats *stats) { + return stats->download_bandwidth; +} + +float linphone_call_stats_get_upload_bandwidth (const LinphoneCallStats *stats) { + return stats->upload_bandwidth; +} + +float linphone_call_stats_get_rtcp_download_bandwidth (const LinphoneCallStats *stats) { + return stats->rtcp_download_bandwidth; +} + +float linphone_call_stats_get_rtcp_upload_bandwidth (const LinphoneCallStats *stats) { + return stats->rtcp_upload_bandwidth; +} + +LinphoneIceState linphone_call_stats_get_ice_state (const LinphoneCallStats *stats) { + return stats->ice_state; +} + +LinphoneUpnpState linphone_call_stats_get_upnp_state (const LinphoneCallStats *stats) { + return stats->upnp_state; +} + +LinphoneAddressFamily linphone_call_stats_get_ip_family_of_remote (const LinphoneCallStats *stats) { + return (LinphoneAddressFamily)stats->rtp_remote_family; +} + +float linphone_call_stats_get_jitter_buffer_size_ms (const LinphoneCallStats *stats) { + return stats->jitter_stats.jitter_buffer_size_ms; +} + +float linphone_call_stats_get_round_trip_delay (const LinphoneCallStats *stats) { + return stats->round_trip_delay; +} diff --git a/src/c-wrapper/api/c-call.cpp b/src/c-wrapper/api/c-call.cpp new file mode 100644 index 000000000..717dd83e0 --- /dev/null +++ b/src/c-wrapper/api/c-call.cpp @@ -0,0 +1,1212 @@ +/* + * c-call.cpp + * Copyright (C) 2017 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 3 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, see . + */ + +#include "linphone/api/c-call.h" +#include "linphone/api/c-call-cbs.h" +#include "linphone/api/c-call-stats.h" +#include "linphone/wrapper_utils.h" + +#include "c-wrapper/c-wrapper.h" +#include "call/call-p.h" +#include "call/call.h" +#include "conference/params/media-session-params-p.h" + +// ============================================================================= + +#define GET_CPP_PTR(obj) L_GET_CPP_PTR_FROM_C_STRUCT(obj, Call) +#define GET_CPP_PRIVATE_PTR(obj) L_GET_PRIVATE_FROM_C_STRUCT(obj, Call) + +using namespace std; + +static void _linphone_call_constructor (LinphoneCall *call); +static void _linphone_call_destructor (LinphoneCall *call); + +L_DECLARE_C_STRUCT_IMPL_WITH_XTORS(Call, Call, + _linphone_call_constructor, _linphone_call_destructor, + bctbx_list_t *callbacks; /* A list of LinphoneCallCbs object */ + LinphoneCallCbs *currentCbs; /* The current LinphoneCallCbs object used to call a callback */ + LinphoneCallParams *currentParamsCache; + LinphoneCallParams *paramsCache; + LinphoneCallParams *remoteParamsCache; + LinphoneAddress *remoteAddressCache; + char *remoteContactCache; + /* TODO: all the fields need to be removed */ + struct _LinphoneCore *core; + LinphoneErrorInfo *ei; + SalMediaDescription *localdesc; + SalMediaDescription *resultdesc; + struct _LinphoneCallLog *log; + SalOp *op; + SalOp *ping_op; + LinphoneCallState transfer_state; /*idle if no transfer*/ + struct _AudioStream *audiostream; /**/ + struct _VideoStream *videostream; + struct _TextStream *textstream; + MSAudioEndpoint *endpoint; /*used for conferencing*/ + char *refer_to; + LinphoneCallParams *params; + LinphoneCallParams *current_params; + LinphoneCallParams *remote_params; + LinphoneCallStats *audio_stats; + LinphoneCallStats *video_stats; + LinphoneCallStats *text_stats; + LinphoneCall *referer; /*when this call is the result of a transfer, referer is set to the original call that caused the transfer*/ + LinphoneCall *transfer_target;/*if this call received a transfer request, then transfer_target points to the new call created to the refer target */ + LinphonePlayer *player; + char *dtmf_sequence; /*DTMF sequence needed to be sent using #dtmfs_timer*/ + belle_sip_source_t *dtmfs_timer; /*DTMF timer needed to send a DTMF sequence*/ + LinphoneChatRoom *chat_room; + LinphoneConference *conf_ref; /**> Point on the associated conference if this call is part of a conference. NULL instead. */ + bool_t refer_pending; + bool_t defer_update; + bool_t was_automatically_paused; + bool_t paused_by_app; + bool_t broken; /*set to TRUE when the call is in broken state due to network disconnection or transport */ + bool_t need_localip_refresh; + bool_t reinvite_on_cancel_response_requested; + bool_t non_op_error; /*set when the LinphoneErrorInfo was set at higher level than sal*/ +) + +static void _linphone_call_constructor (LinphoneCall *call) { +} + +static void _linphone_call_destructor (LinphoneCall *call) { + if (call->currentParamsCache) { + linphone_call_params_unref(call->currentParamsCache); + call->currentParamsCache = nullptr; + } + if (call->paramsCache) { + linphone_call_params_unref(call->paramsCache); + call->paramsCache = nullptr; + } + if (call->remoteParamsCache) { + linphone_call_params_unref(call->remoteParamsCache); + call->remoteParamsCache = nullptr; + } + if (call->remoteAddressCache) { + linphone_address_unref(call->remoteAddressCache); + call->remoteAddressCache = nullptr; + } + bctbx_list_free_with_data(call->callbacks, (bctbx_list_free_func)linphone_call_cbs_unref); + if (call->audio_stats) { + linphone_call_stats_unref(call->audio_stats); + call->audio_stats = nullptr; + } + if (call->video_stats) { + linphone_call_stats_unref(call->video_stats); + call->video_stats = nullptr; + } + if (call->text_stats) { + linphone_call_stats_unref(call->text_stats); + call->text_stats = nullptr; + } + if (call->op) { + sal_op_release(call->op); + call->op=nullptr; + } + if (call->resultdesc) { + sal_media_description_unref(call->resultdesc); + call->resultdesc=nullptr; + } + if (call->localdesc) { + sal_media_description_unref(call->localdesc); + call->localdesc=nullptr; + } + if (call->ping_op) { + sal_op_release(call->ping_op); + call->ping_op=nullptr; + } + if (call->refer_to){ + ms_free(call->refer_to); + call->refer_to=nullptr; + } + if (call->referer){ + linphone_call_unref(call->referer); + call->referer=nullptr; + } + if (call->transfer_target){ + linphone_call_unref(call->transfer_target); + call->transfer_target=nullptr; + } + if (call->log) { + linphone_call_log_unref(call->log); + call->log=nullptr; + } + if (call->dtmfs_timer) { + linphone_call_cancel_dtmfs(call); + } + if (call->params){ + linphone_call_params_unref(call->params); + call->params=nullptr; + } + if (call->current_params){ + linphone_call_params_unref(call->current_params); + call->current_params=nullptr; + } + if (call->remote_params) { + linphone_call_params_unref(call->remote_params); + call->remote_params=nullptr; + } + if (call->ei) linphone_error_info_unref(call->ei); +} + + +// ============================================================================= +// TODO: To remove! +// ============================================================================= + +MSWebCam *get_nowebcam_device (MSFactory* f) { +#ifdef VIDEO_ENABLED + return ms_web_cam_manager_get_cam(ms_factory_get_web_cam_manager(f),"StaticImage: Static picture"); +#else + return nullptr; +#endif +} + +void linphone_call_update_local_media_description_from_ice_or_upnp (LinphoneCall *call) {} + +void linphone_call_make_local_media_description (LinphoneCall *call) {} + +void linphone_call_create_op (LinphoneCall *call) { +#if 0 + if (call->op) sal_op_release(call->op); + call->op=sal_op_new(call->core->sal); + sal_op_set_user_pointer(call->op,call); + if (linphone_call_params_get_referer(call->params)) + sal_call_set_referer(call->op,linphone_call_params_get_referer(call->params)->op); + linphone_configure_op(call->core,call->op,call->log->to,linphone_call_params_get_custom_headers(call->params),FALSE); + if (linphone_call_params_get_privacy(call->params) != LinphonePrivacyDefault) + sal_op_set_privacy(call->op,(SalPrivacyMask)linphone_call_params_get_privacy(call->params)); + /*else privacy might be set by proxy */ +#endif +} + +void linphone_call_set_state (LinphoneCall *call, LinphoneCallState cstate, const char *message) {} + +void linphone_call_init_media_streams (LinphoneCall *call) {} + +#if 0 +static int dtmf_tab[16]={'0','1','2','3','4','5','6','7','8','9','*','#','A','B','C','D'}; + +static void linphone_core_dtmf_received (LinphoneCall *call, int dtmf) { + if (dtmf<0 || dtmf>15){ + ms_warning("Bad dtmf value %i",dtmf); + return; + } + linphone_call_notify_dtmf_received(call, dtmf_tab[dtmf]); +} +#endif + +/*This function is not static because used internally in linphone-daemon project*/ +void _post_configure_audio_stream (AudioStream *st, LinphoneCore *lc, bool_t muted) {} + +#if 0 +static void setup_ring_player (LinphoneCore *lc, LinphoneCall *call) { + int pause_time=3000; + audio_stream_play(call->audiostream,lc->sound_conf.ringback_tone); + ms_filter_call_method(call->audiostream->soundread,MS_FILE_PLAYER_LOOP,&pause_time); +} +#endif + +#if 0 +static bool_t linphone_call_sound_resources_available (LinphoneCall *call) { + LinphoneCore *lc=call->core; + LinphoneCall *current=linphone_core_get_current_call(lc); + return !linphone_core_is_in_conference(lc) && + (current==nullptr || current==call); +} +#endif + +void linphone_call_delete_upnp_session (LinphoneCall *call) {} + +void linphone_call_stop_media_streams (LinphoneCall *call) {} + +#if 0 +static void linphone_call_lost (LinphoneCall *call) { + LinphoneCore *lc = call->core; + char *temp = nullptr; + char *from = nullptr; + + from = linphone_call_get_remote_address_as_string(call); + temp = ms_strdup_printf("Media connectivity with %s is lost, call is going to be closed.", from ? from : "?"); + if (from) ms_free(from); + ms_message("LinphoneCall [%p]: %s", call, temp); + linphone_core_notify_display_warning(lc, temp); + call->non_op_error = TRUE; + linphone_error_info_set(call->ei,nullptr, LinphoneReasonIOError, 503, "Media lost", nullptr); + linphone_call_terminate(call); + linphone_core_play_named_tone(lc, LinphoneToneCallLost); + ms_free(temp); +} +#endif + +void linphone_call_set_transfer_state (LinphoneCall *call, LinphoneCallState state) { +#if 0 + if (state != call->transfer_state) { + ms_message("Transfer state for call [%p] changed from [%s] to [%s]",call + ,linphone_call_state_to_string(call->transfer_state) + ,linphone_call_state_to_string(state)); + call->transfer_state = state; + linphone_call_notify_transfer_state_changed(call, state); + } +#endif +} + +void _linphone_call_set_new_params (LinphoneCall *call, const LinphoneCallParams *params) {} + +#if 0 +static int send_dtmf_handler (void *data, unsigned int revents) { + LinphoneCall *call = (LinphoneCall*)data; + /*By default we send DTMF RFC2833 if we do not have enabled SIP_INFO but we can also send RFC2833 and SIP_INFO*/ + if (linphone_core_get_use_rfc2833_for_dtmf(call->core)!=0 || linphone_core_get_use_info_for_dtmf(call->core)==0) + { + /* In Band DTMF */ + if (call->audiostream){ + audio_stream_send_dtmf(call->audiostream,*call->dtmf_sequence); + } + else + { + ms_error("Cannot send RFC2833 DTMF when we are not in communication."); + return FALSE; + } + } + if (linphone_core_get_use_info_for_dtmf(call->core)!=0){ + /* Out of Band DTMF (use INFO method) */ + sal_call_send_dtmf(call->op,*call->dtmf_sequence); + } + + /*this check is needed because linphone_call_send_dtmf does not set the timer since its a single character*/ + if (call->dtmfs_timer) { + memmove(call->dtmf_sequence, call->dtmf_sequence+1, strlen(call->dtmf_sequence)); + } + /* continue only if the dtmf sequence is not empty*/ + if (call->dtmf_sequence && *call->dtmf_sequence!='\0') { + return TRUE; + } else { + linphone_call_cancel_dtmfs(call); + return FALSE; + } +} +#endif + +/* Internal version that does not play tone indication*/ +int _linphone_call_pause (LinphoneCall *call) { + return 0; +} + +#if 0 +static void terminate_call (LinphoneCall *call) {} +#endif + +int linphone_call_start_update (LinphoneCall *call) { + return 0; +} + +int linphone_call_start_accept_update (LinphoneCall *call, LinphoneCallState next_state, const char *state_info) { + return 0; +} + +int linphone_call_proceed_with_invite_if_ready (LinphoneCall *call, LinphoneProxyConfig *dest_proxy) { + return 0; +} + +int linphone_call_start_invite (LinphoneCall *call, const LinphoneAddress *destination /* = NULL if to be taken from the call log */) { + return 0; +} + +void linphone_call_replace_op (LinphoneCall *call, SalOp *op) { +#if 0 + SalOp *oldop = call->op; + LinphoneCallState oldstate = linphone_call_get_state(call); + call->op = op; + sal_op_set_user_pointer(call->op, call); + sal_call_set_local_media_description(call->op, call->localdesc); + switch (linphone_call_get_state(call)) { + case LinphoneCallIncomingEarlyMedia: + case LinphoneCallIncomingReceived: + sal_call_notify_ringing(call->op, (linphone_call_get_state(call) == LinphoneCallIncomingEarlyMedia) ? TRUE : FALSE); + break; + case LinphoneCallConnected: + case LinphoneCallStreamsRunning: + sal_call_accept(call->op); + break; + default: + ms_warning("linphone_call_replace_op(): don't know what to do in state [%s]", linphone_call_state_to_string(call->state)); + break; + } + switch (oldstate) { + case LinphoneCallIncomingEarlyMedia: + case LinphoneCallIncomingReceived: + sal_op_set_user_pointer(oldop, nullptr); /* To make the call does not get terminated by terminating this op. */ + /* Do not terminate a forked INVITE */ + if (sal_call_get_replaces(op)) { + sal_call_terminate(oldop); + } else { + sal_op_kill_dialog(oldop); + } + break; + case LinphoneCallConnected: + case LinphoneCallStreamsRunning: + sal_call_terminate(oldop); + sal_op_kill_dialog(oldop); + break; + default: + break; + } + sal_op_release(oldop); +#endif +} + + +// ============================================================================= +// Private functions. +// ============================================================================= + +#if 0 +static void linphone_call_repair_by_invite_with_replaces (LinphoneCall *call) { + const char *call_id = sal_op_get_call_id(call->op); + const char *from_tag = sal_call_get_local_tag(call->op); + const char *to_tag = sal_call_get_remote_tag(call->op); + sal_op_kill_dialog(call->op); + linphone_call_create_op(call); + sal_call_set_replaces(call->op, call_id, from_tag, to_tag); + linphone_call_start_invite(call, nullptr); +} +#endif + +MediaStream *linphone_call_get_stream (LinphoneCall *call, LinphoneStreamType type) { + return GET_CPP_PRIVATE_PTR(call)->getMediaStream(type); +} + +void linphone_call_set_broken (LinphoneCall *call) { +#if 0 + switch(call->state){ + /*for all the early states, we prefer to drop the call*/ + case LinphoneCallOutgoingInit: + case LinphoneCallOutgoingProgress: + case LinphoneCallOutgoingRinging: + case LinphoneCallOutgoingEarlyMedia: + case LinphoneCallIncomingReceived: + case LinphoneCallIncomingEarlyMedia: + /*during the early states, the SAL layer reports the failure from the dialog or transaction layer, + * hence, there is nothing special to do*/ + //break; + case LinphoneCallStreamsRunning: + case LinphoneCallUpdating: + case LinphoneCallPausing: + case LinphoneCallResuming: + case LinphoneCallPaused: + case LinphoneCallPausedByRemote: + case LinphoneCallUpdatedByRemote: + /*during these states, the dialog is established. A failure of a transaction is not expected to close it. + * Instead we have to repair the dialog by sending a reINVITE*/ + call->broken = TRUE; + call->need_localip_refresh = TRUE; + break; + default: + ms_error("linphone_call_set_broken() unimplemented case."); + break; + } +#endif +} + +void linphone_call_reinvite_to_recover_from_connection_loss (LinphoneCall *call) { +#if 0 + LinphoneCallParams *params; + ms_message("LinphoneCall[%p] is going to be updated (reINVITE) in order to recover from lost connectivity", call); + if (call->ice_session){ + ice_session_reset(call->ice_session, IR_Controlling); + } + params = linphone_core_create_call_params(call->core, call); + linphone_call_update(call, params); + linphone_call_params_unref(params); +#endif +} + +void linphone_call_repair_if_broken (LinphoneCall *call) { +#if 0 + SalErrorInfo sei; + if (!call->broken) return; + if (!call->core->media_network_reachable) return; + + memset(&sei, 0, sizeof(sei)); + + /*Make sure that the proxy from which we received this call, or to which we routed this call is registered first*/ + if (call->dest_proxy){ + /*in all other cases, ie no proxy config, or a proxy config for which no registration was requested, we can start the + * call repair immediately.*/ + if (linphone_proxy_config_register_enabled(call->dest_proxy) + && linphone_proxy_config_get_state(call->dest_proxy) != LinphoneRegistrationOk) return; + } + + switch (call->state){ + case LinphoneCallUpdating: + case LinphoneCallPausing: + if (sal_call_dialog_request_pending(call->op)) { + /* Need to cancel first re-INVITE as described in section 5.5 of RFC 6141 */ + sal_call_cancel_invite(call->op); + call->reinvite_on_cancel_response_requested = TRUE; + } + break; + case LinphoneCallStreamsRunning: + case LinphoneCallPaused: + case LinphoneCallPausedByRemote: + if (!sal_call_dialog_request_pending(call->op)) { + linphone_call_reinvite_to_recover_from_connection_loss(call); + } + break; + case LinphoneCallUpdatedByRemote: + if (sal_call_dialog_request_pending(call->op)) { + sal_error_info_set(&sei, SalReasonServiceUnavailable,"SIP", 0, nullptr, nullptr); + sal_call_decline_with_error_info(call->op, &sei,nullptr); + } + linphone_call_reinvite_to_recover_from_connection_loss(call); + break; + case LinphoneCallOutgoingInit: + case LinphoneCallOutgoingProgress: + sal_call_cancel_invite(call->op); + call->reinvite_on_cancel_response_requested = TRUE; + break; + case LinphoneCallOutgoingEarlyMedia: + case LinphoneCallOutgoingRinging: + linphone_call_repair_by_invite_with_replaces(call); + break; + case LinphoneCallIncomingEarlyMedia: + case LinphoneCallIncomingReceived: + /* Keep the call broken until a forked INVITE is received from the server. */ + break; + default: + ms_warning("linphone_call_repair_if_broken(): don't know what to do in state [%s]", linphone_call_state_to_string(call->state)); + call->broken = FALSE; + break; + } + sal_error_info_reset(&sei); +#endif +} + +void linphone_call_refresh_sockets (LinphoneCall *call) { +#if 0 + int i; + for (i=0; i < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; ++i){ + MSMediaStreamSessions *mss = &call->sessions[i]; + if (mss->rtp_session){ + rtp_session_refresh_sockets(mss->rtp_session); + } + } +#endif +} + +SalOp * linphone_call_get_op (const LinphoneCall *call) { + return GET_CPP_PRIVATE_PTR(call)->getOp(); +} + +LinphoneProxyConfig * linphone_call_get_dest_proxy (const LinphoneCall *call) { + return GET_CPP_PRIVATE_PTR(call)->getDestProxy(); +} + +LinphoneCallLog * linphone_call_get_log (const LinphoneCall *call) { + return linphone_call_get_call_log(call); +} + +IceSession * linphone_call_get_ice_session (const LinphoneCall *call) { + return GET_CPP_PRIVATE_PTR(call)->getIceSession(); +} + +bool_t linphone_call_get_audio_muted (const LinphoneCall *call) { + return GET_CPP_PRIVATE_PTR(call)->getAudioMuted(); +} + +void linphone_call_set_audio_muted (LinphoneCall *call, bool_t value) { + GET_CPP_PRIVATE_PTR(call)->setAudioMuted(value); +} + +bool_t linphone_call_get_all_muted (const LinphoneCall *call) { + return GET_CPP_PTR(call)->getAllMuted(); +} + +#define NOTIFY_IF_EXIST(cbName, functionName, ...) \ + for (bctbx_list_t *it = call->callbacks; it; it = bctbx_list_next(it)) { \ + call->currentCbs = reinterpret_cast(bctbx_list_get_data(it)); \ + LinphoneCallCbs ## cbName ## Cb cb = linphone_call_cbs_get_ ## functionName (call->currentCbs); \ + if (cb) \ + cb(__VA_ARGS__); \ + } + +void linphone_call_notify_state_changed (LinphoneCall *call, LinphoneCallState cstate, const char *message) { + NOTIFY_IF_EXIST(StateChanged, state_changed, call, cstate, message) + linphone_core_notify_call_state_changed(linphone_call_get_core(call), call, cstate, message); +} + +void linphone_call_notify_dtmf_received (LinphoneCall *call, int dtmf) { + NOTIFY_IF_EXIST(DtmfReceived, dtmf_received, call, dtmf) + linphone_core_notify_dtmf_received(linphone_call_get_core(call), call, dtmf); +} + +void linphone_call_notify_encryption_changed (LinphoneCall *call, bool_t on, const char *authentication_token) { + NOTIFY_IF_EXIST(EncryptionChanged, encryption_changed, call, on, authentication_token) + linphone_core_notify_call_encryption_changed(linphone_call_get_core(call), call, on, authentication_token); +} + +void linphone_call_notify_transfer_state_changed (LinphoneCall *call, LinphoneCallState cstate) { + NOTIFY_IF_EXIST(TransferStateChanged, transfer_state_changed, call, cstate) + linphone_core_notify_transfer_state_changed(linphone_call_get_core(call), call, cstate); +} + +void linphone_call_notify_stats_updated (LinphoneCall *call, const LinphoneCallStats *stats) { + NOTIFY_IF_EXIST(StatsUpdated, stats_updated, call, stats) + linphone_core_notify_call_stats_updated(linphone_call_get_core(call), call, stats); +} + +void linphone_call_notify_info_message_received (LinphoneCall *call, const LinphoneInfoMessage *msg) { + NOTIFY_IF_EXIST(InfoMessageReceived, info_message_received, call, msg) + linphone_core_notify_info_received(linphone_call_get_core(call), call, msg); +} + +void linphone_call_notify_ack_processing (LinphoneCall *call, LinphoneHeaders *msg, bool_t is_received) { + NOTIFY_IF_EXIST(AckProcessing, ack_processing, call, msg, is_received) +} + + +// ============================================================================= +// Public functions. +// ============================================================================= + +LinphoneCore *linphone_call_get_core (const LinphoneCall *call) { + return GET_CPP_PTR(call)->getCore(); +} + +LinphoneCallState linphone_call_get_state (const LinphoneCall *call) { + return GET_CPP_PTR(call)->getState(); +} + +bool_t linphone_call_asked_to_autoanswer (LinphoneCall *call) { + //return TRUE if the unique(for the moment) incoming call asked to be autoanswered + if (call) + return sal_call_autoanswer_asked(linphone_call_get_op(call)); + return FALSE; +} + +const LinphoneAddress *linphone_call_get_remote_address (const LinphoneCall *call) { + L_SET_CPP_PTR_FROM_C_STRUCT(call->remoteAddressCache, &GET_CPP_PTR(call)->getRemoteAddress()); + return call->remoteAddressCache; +} + +const LinphoneAddress *linphone_call_get_to_address (const LinphoneCall *call){ +#if 0 + return (const LinphoneAddress *)sal_op_get_to_address(call->op); +#else + return nullptr; +#endif +} + +const char *linphone_call_get_to_header (const LinphoneCall *call, const char *name) { +#if 0 + return sal_custom_header_find(sal_op_get_recv_custom_header(call->op),name); +#else + return nullptr; +#endif +} + +char *linphone_call_get_remote_address_as_string (const LinphoneCall *call) { + return ms_strdup(GET_CPP_PTR(call)->getRemoteAddressAsString().c_str()); +} + +const LinphoneAddress *linphone_call_get_diversion_address (const LinphoneCall *call) { +#if 0 + return call->op?(const LinphoneAddress *)sal_op_get_diversion_address(call->op):nullptr; +#else + return nullptr; +#endif +} + +LinphoneCallDir linphone_call_get_dir (const LinphoneCall *call) { + return linphone_call_log_get_dir(linphone_call_get_log(call)); +} + +LinphoneCallLog *linphone_call_get_call_log (const LinphoneCall *call) { + return GET_CPP_PTR(call)->getLog(); +} + +const char *linphone_call_get_refer_to (const LinphoneCall *call) { +#if 0 + return call->refer_to; +#else + return nullptr; +#endif +} + +bool_t linphone_call_has_transfer_pending (const LinphoneCall *call) { +#if 0 + return call->refer_pending; +#else + return FALSE; +#endif +} + +LinphoneCall *linphone_call_get_transferer_call (const LinphoneCall *call) { +#if 0 + return call->referer; +#else + return nullptr; +#endif +} + +LinphoneCall *linphone_call_get_transfer_target_call (const LinphoneCall *call) { +#if 0 + return call->transfer_target; +#else + return nullptr; +#endif +} + +LinphoneCall *linphone_call_get_replaced_call (LinphoneCall *call) { +#if 0 + SalOp *op=sal_call_get_replaces(call->op); + if (op){ + return (LinphoneCall*)sal_op_get_user_pointer(op); + } + return nullptr; +#else + return nullptr; +#endif +} + +int linphone_call_get_duration (const LinphoneCall *call) { + return GET_CPP_PTR(call)->getDuration(); +} + +const LinphoneCallParams *linphone_call_get_current_params(LinphoneCall *call) { + L_SET_CPP_PTR_FROM_C_STRUCT(call->currentParamsCache, GET_CPP_PTR(call)->getCurrentParams()); + return call->currentParamsCache; +} + +const LinphoneCallParams *linphone_call_get_remote_params(LinphoneCall *call) { + const LinphonePrivate::MediaSessionParams *remoteParams = GET_CPP_PTR(call)->getRemoteParams(); + if (!remoteParams) + return nullptr; + L_SET_CPP_PTR_FROM_C_STRUCT(call->remoteParamsCache, remoteParams); + return call->remoteParamsCache; +} + +void linphone_call_enable_camera (LinphoneCall *call, bool_t enable) { + GET_CPP_PTR(call)->enableCamera(enable); +} + +bool_t linphone_call_camera_enabled (const LinphoneCall *call) { + return GET_CPP_PTR(call)->cameraEnabled(); +} + +LinphoneStatus linphone_call_take_video_snapshot (LinphoneCall *call, const char *file) { + return GET_CPP_PTR(call)->takeVideoSnapshot(file ? file : ""); +} + +LinphoneStatus linphone_call_take_preview_snapshot (LinphoneCall *call, const char *file) { + return GET_CPP_PTR(call)->takePreviewSnapshot(file ? file : ""); +} + +LinphoneReason linphone_call_get_reason (const LinphoneCall *call) { + return GET_CPP_PTR(call)->getReason(); +} + +const LinphoneErrorInfo *linphone_call_get_error_info (const LinphoneCall *call) { + return GET_CPP_PTR(call)->getErrorInfo(); +} + +const char *linphone_call_get_remote_user_agent (LinphoneCall *call) { +#if 0 + if (call->op){ + return sal_op_get_remote_ua (call->op); + } + return nullptr; +#else + return nullptr; +#endif +} + +const char * linphone_call_get_remote_contact (LinphoneCall *call) { + std::string contact = GET_CPP_PTR(call)->getRemoteContact(); + if (contact.empty()) + return nullptr; + if (call->remoteContactCache) + bctbx_free(call->remoteContactCache); + call->remoteContactCache = bctbx_strdup(contact.c_str()); + return call->remoteContactCache; +} + +const char *linphone_call_get_authentication_token (LinphoneCall *call) { + std::string token = GET_CPP_PTR(call)->getAuthenticationToken(); + return token.empty() ? nullptr : token.c_str(); +} + +bool_t linphone_call_get_authentication_token_verified (const LinphoneCall *call) { + return GET_CPP_PTR(call)->getAuthenticationTokenVerified(); +} + +void linphone_call_set_authentication_token_verified (LinphoneCall *call, bool_t verified) { + GET_CPP_PTR(call)->setAuthenticationTokenVerified(verified); +} + +void linphone_call_send_vfu_request (LinphoneCall *call) { + GET_CPP_PTR(call)->sendVfuRequest(); +} + +void linphone_call_set_next_video_frame_decoded_callback (LinphoneCall *call, LinphoneCallCbFunc cb, void *ud) { + GET_CPP_PTR(call)->setNextVideoFrameDecodedCallback(cb, ud); +} + +LinphoneCallState linphone_call_get_transfer_state (LinphoneCall *call) { +#if 0 + return call->transfer_state; +#else + return LinphoneCallIdle; +#endif +} + +void linphone_call_zoom_video (LinphoneCall* call, float zoom_factor, float* cx, float* cy) { + GET_CPP_PTR(call)->zoomVideo(zoom_factor, cx, cy); +} + +LinphoneStatus linphone_call_send_dtmf (LinphoneCall *call, char dtmf) { +#if 0 + if (!call){ + ms_warning("linphone_call_send_dtmf(): invalid call, canceling DTMF."); + return -1; + } + call->dtmf_sequence = &dtmf; + send_dtmf_handler(call,0); + call->dtmf_sequence = nullptr; + return 0; +#else + return 0; +#endif +} + +LinphoneStatus linphone_call_send_dtmfs (LinphoneCall *call, const char *dtmfs) { +#if 0 + if (!call){ + ms_warning("linphone_call_send_dtmfs(): invalid call, canceling DTMF sequence."); + return -1; + } + if (call->dtmfs_timer){ + ms_warning("linphone_call_send_dtmfs(): a DTMF sequence is already in place, canceling DTMF sequence."); + return -2; + } + if (dtmfs) { + int delay_ms = lp_config_get_int(call->core->config,"net","dtmf_delay_ms",200); + call->dtmf_sequence = ms_strdup(dtmfs); + call->dtmfs_timer = sal_create_timer(call->core->sal, send_dtmf_handler, call, delay_ms, "DTMF sequence timer"); + } + return 0; +#else + return 0; +#endif +} + +void linphone_call_cancel_dtmfs (LinphoneCall *call) { +#if 0 + /*nothing to do*/ + if (!call || !call->dtmfs_timer) return; + + sal_cancel_timer(call->core->sal, call->dtmfs_timer); + belle_sip_object_unref(call->dtmfs_timer); + call->dtmfs_timer = nullptr; + if (call->dtmf_sequence) { + ms_free(call->dtmf_sequence); + call->dtmf_sequence = nullptr; + } +#endif +} + +bool_t linphone_call_is_in_conference (const LinphoneCall *call) { +#if 0 + return linphone_call_params_get_in_conference(call->params); +#else + return FALSE; +#endif +} + +LinphoneConference *linphone_call_get_conference (const LinphoneCall *call) { +#if 0 + return call->conf_ref; +#else + return nullptr; +#endif +} + +void linphone_call_set_audio_route (LinphoneCall *call, LinphoneAudioRoute route) { +#if 0 + if (call && call->audiostream){ + audio_stream_set_audio_route(call->audiostream, (MSAudioRoute) route); + } +#endif +} + +int linphone_call_get_stream_count (const LinphoneCall *call) { + return GET_CPP_PTR(call)->getStreamCount(); +} + +MSFormatType linphone_call_get_stream_type (const LinphoneCall *call, int stream_index) { + return GET_CPP_PTR(call)->getStreamType(stream_index); +} + +RtpTransport *linphone_call_get_meta_rtp_transport (const LinphoneCall *call, int stream_index) { + return GET_CPP_PTR(call)->getMetaRtpTransport(stream_index); +} + +RtpTransport *linphone_call_get_meta_rtcp_transport (const LinphoneCall *call, int stream_index) { + return GET_CPP_PTR(call)->getMetaRtcpTransport(stream_index); +} + +LinphoneStatus linphone_call_pause (LinphoneCall *call) { + return GET_CPP_PTR(call)->pause(); +} + +LinphoneStatus linphone_call_resume (LinphoneCall *call) { + return GET_CPP_PTR(call)->resume(); +} + +LinphoneStatus linphone_call_terminate (LinphoneCall *call) { + return GET_CPP_PTR(call)->terminate(); +} + +LinphoneStatus linphone_call_terminate_with_error_info (LinphoneCall *call , const LinphoneErrorInfo *ei) { + return GET_CPP_PTR(call)->terminate(ei); +} + +LinphoneStatus linphone_call_redirect (LinphoneCall *call, const char *redirect_uri) { +#if 0 + char *real_url = nullptr; + LinphoneCore *lc; + LinphoneAddress *real_parsed_url; + SalErrorInfo sei; + + if (call->state != LinphoneCallIncomingReceived) { + ms_error("Bad state for call redirection."); + return -1; + } + + lc = linphone_call_get_core(call); + real_parsed_url = linphone_core_interpret_url(lc, redirect_uri); + if (!real_parsed_url) { + /* Bad url */ + ms_error("Bad redirect URI: %s", redirect_uri ? redirect_uri : "NULL"); + return -1; + } + + memset(&sei, 0, sizeof(sei)); + real_url = linphone_address_as_string(real_parsed_url); + sal_error_info_set(&sei,SalReasonRedirect, "SIP", 0, nullptr, nullptr); + sal_call_decline_with_error_info(call->op, &sei, real_url); + ms_free(real_url); + linphone_error_info_set(call->ei, nullptr, LinphoneReasonMovedPermanently, 302, "Call redirected", nullptr); + call->non_op_error = TRUE; + terminate_call(call); + linphone_address_unref(real_parsed_url); + sal_error_info_reset(&sei); + return 0; +#else + return 0; +#endif +} + +LinphoneStatus linphone_call_decline (LinphoneCall *call, LinphoneReason reason) { + return GET_CPP_PTR(call)->decline(reason); +} + +LinphoneStatus linphone_call_decline_with_error_info (LinphoneCall *call, const LinphoneErrorInfo *ei) { + return GET_CPP_PTR(call)->decline(ei); +} + +LinphoneStatus linphone_call_accept (LinphoneCall *call) { + return GET_CPP_PTR(call)->accept(nullptr); +} + +LinphoneStatus linphone_call_accept_with_params (LinphoneCall *call, const LinphoneCallParams *params) { + return GET_CPP_PTR(call)->accept(params ? L_GET_CPP_PTR_FROM_C_STRUCT(params, MediaSessionParams) : nullptr); +} + +LinphoneStatus linphone_call_accept_early_media (LinphoneCall* call) { + return GET_CPP_PTR(call)->acceptEarlyMedia(); +} + +LinphoneStatus linphone_call_accept_early_media_with_params (LinphoneCall *call, const LinphoneCallParams *params) { + return GET_CPP_PTR(call)->acceptEarlyMedia(params ? L_GET_CPP_PTR_FROM_C_STRUCT(params, MediaSessionParams) : nullptr); +} + +LinphoneStatus linphone_call_update (LinphoneCall *call, const LinphoneCallParams *params) { + return GET_CPP_PTR(call)->update(params ? L_GET_CPP_PTR_FROM_C_STRUCT(params, MediaSessionParams) : nullptr); +} + +LinphoneStatus linphone_call_defer_update (LinphoneCall *call) { +#if 0 + if (call->state != LinphoneCallUpdatedByRemote) { + ms_error("linphone_call_defer_update() not done in state LinphoneCallUpdatedByRemote"); + return -1; + } + + if (call->expect_media_in_ack) { + ms_error("linphone_call_defer_update() is not possible during a late offer incoming reINVITE (INVITE without SDP)"); + return -1; + } + + call->defer_update=TRUE; + return 0; +#else + return 0; +#endif +} + +LinphoneStatus linphone_call_accept_update (LinphoneCall *call, const LinphoneCallParams *params) { + return GET_CPP_PTR(call)->acceptUpdate(params ? L_GET_CPP_PTR_FROM_C_STRUCT(params, MediaSessionParams) : nullptr); +} + +LinphoneStatus linphone_call_transfer (LinphoneCall *call, const char *refer_to) { +#if 0 + char *real_url = nullptr; + LinphoneCore *lc = linphone_call_get_core(call); + LinphoneAddress *real_parsed_url = linphone_core_interpret_url(lc, refer_to); + + if (!real_parsed_url) { + /* bad url */ + return -1; + } + //lc->call = nullptr; // Do not do that you will lose the call afterward... + real_url = linphone_address_as_string(real_parsed_url); + sal_call_refer(call->op, real_url); + ms_free(real_url); + linphone_address_unref(real_parsed_url); + linphone_call_set_transfer_state(call, LinphoneCallOutgoingInit); + return 0; +#else + return 0; +#endif +} + +LinphoneStatus linphone_call_transfer_to_another (LinphoneCall *call, LinphoneCall *dest) { +#if 0 + int result = sal_call_refer_with_replaces (call->op, dest->op); + linphone_call_set_transfer_state(call, LinphoneCallOutgoingInit); + return result; +#else + return 0; +#endif +} + +void *linphone_call_get_native_video_window_id (const LinphoneCall *call) { + return GET_CPP_PTR(call)->getNativeVideoWindowId(); +} + +void linphone_call_set_native_video_window_id (LinphoneCall *call, void *id) { + GET_CPP_PTR(call)->setNativeVideoWindowId(id); +} + +void linphone_call_enable_echo_cancellation (LinphoneCall *call, bool_t enable) { + GET_CPP_PTR(call)->enableEchoCancellation(enable); +} + +bool_t linphone_call_echo_cancellation_enabled (const LinphoneCall *call) { + return GET_CPP_PTR(call)->echoCancellationEnabled(); +} + +void linphone_call_enable_echo_limiter (LinphoneCall *call, bool_t val) { + GET_CPP_PTR(call)->enableEchoLimiter(val); +} + +bool_t linphone_call_echo_limiter_enabled (const LinphoneCall *call) { + return GET_CPP_PTR(call)->echoLimiterEnabled(); +} + +LinphoneChatRoom *linphone_call_get_chat_room (LinphoneCall *call) { +#if 0 + if (!call->chat_room){ + if (call->state != LinphoneCallReleased && call->state != LinphoneCallEnd){ + call->chat_room = _linphone_core_create_chat_room_from_call(call); + } + } + return call->chat_room; +#else + return nullptr; +#endif +} + +float linphone_call_get_play_volume (const LinphoneCall *call) { + return GET_CPP_PTR(call)->getPlayVolume(); +} + +float linphone_call_get_record_volume (const LinphoneCall *call) { + return GET_CPP_PTR(call)->getRecordVolume(); +} + +float linphone_call_get_speaker_volume_gain (const LinphoneCall *call) { + return GET_CPP_PTR(call)->getSpeakerVolumeGain(); +} + +void linphone_call_set_speaker_volume_gain( LinphoneCall *call, float volume) { + GET_CPP_PTR(call)->setSpeakerVolumeGain(volume); +} + +float linphone_call_get_microphone_volume_gain (const LinphoneCall *call) { + return GET_CPP_PTR(call)->getMicrophoneVolumeGain(); +} + +void linphone_call_set_microphone_volume_gain (LinphoneCall *call, float volume) { + GET_CPP_PTR(call)->setMicrophoneVolumeGain(volume); +} + +float linphone_call_get_current_quality (const LinphoneCall *call) { + return GET_CPP_PTR(call)->getCurrentQuality(); +} + +float linphone_call_get_average_quality (const LinphoneCall *call) { + return GET_CPP_PTR(call)->getAverageQuality(); +} + +void linphone_call_start_recording (LinphoneCall *call) { + GET_CPP_PTR(call)->startRecording(); +} + +void linphone_call_stop_recording (LinphoneCall *call) { + GET_CPP_PTR(call)->stopRecording(); +} + +LinphonePlayer *linphone_call_get_player (LinphoneCall *call) { +#if 0 + if (!call->player) + call->player=linphone_call_build_player(call); + return call->player; +#else + return nullptr; +#endif +} + +bool_t linphone_call_media_in_progress (const LinphoneCall *call) { + return GET_CPP_PTR(call)->mediaInProgress(); +} + +void linphone_call_ogl_render (const LinphoneCall *call) { +#if 0 + #ifdef VIDEO_ENABLED + + VideoStream *stream = call->videostream; + if (stream && stream->output && ms_filter_get_id(stream->output) == MS_OGL_ID) + ms_filter_call_method(stream->output, MS_OGL_RENDER, nullptr); + + #endif +#endif +} + +LinphoneStatus linphone_call_send_info_message (LinphoneCall *call, const LinphoneInfoMessage *info) { + SalBodyHandler *body_handler = sal_body_handler_from_content(linphone_info_message_get_content(info)); + sal_op_set_sent_custom_header(linphone_call_get_op(call), linphone_info_message_get_headers(info)); + return sal_send_info(linphone_call_get_op(call), nullptr, nullptr, body_handler); +} + +LinphoneCallStats *linphone_call_get_stats (LinphoneCall *call, LinphoneStreamType type) { + return GET_CPP_PTR(call)->getStats(type); +} + +LinphoneCallStats *linphone_call_get_audio_stats (LinphoneCall *call) { + return GET_CPP_PTR(call)->getAudioStats(); +} + +LinphoneCallStats *linphone_call_get_video_stats (LinphoneCall *call) { + return GET_CPP_PTR(call)->getVideoStats(); +} + +LinphoneCallStats *linphone_call_get_text_stats (LinphoneCall *call) { + return GET_CPP_PTR(call)->getTextStats(); +} + +void linphone_call_add_callbacks (LinphoneCall *call, LinphoneCallCbs *cbs) { + call->callbacks = bctbx_list_append(call->callbacks, linphone_call_cbs_ref(cbs)); +} + +void linphone_call_remove_callbacks (LinphoneCall *call, LinphoneCallCbs *cbs) { + call->callbacks = bctbx_list_remove(call->callbacks, cbs); + linphone_call_cbs_unref(cbs); +} + +LinphoneCallCbs *linphone_call_get_current_callbacks (const LinphoneCall *call) { + return call->currentCbs; +} + +void linphone_call_set_params (LinphoneCall *call, const LinphoneCallParams *params) { +#if 0 + if ( call->state == LinphoneCallOutgoingInit || call->state == LinphoneCallIncomingReceived){ + _linphone_call_set_new_params(call, params); + } + else { + ms_error("linphone_call_set_params() invalid state %s to call this function", linphone_call_state_to_string(call->state)); + } +#endif +} + +const LinphoneCallParams *linphone_call_get_params (LinphoneCall *call) { + L_SET_CPP_PTR_FROM_C_STRUCT(call->paramsCache, GET_CPP_PTR(call)->getParams()); + return call->paramsCache; +} + +// ============================================================================= +// Reference and user data handling functions. +// ============================================================================= + +LinphoneCall *linphone_call_ref (LinphoneCall *call) { + belle_sip_object_ref(call); + return call; +} + +void linphone_call_unref (LinphoneCall *call) { + belle_sip_object_unref(call); +} + +void *linphone_call_get_user_data (const LinphoneCall *call) { + return L_GET_USER_DATA_FROM_C_STRUCT(call, Call); +} + +void linphone_call_set_user_data (LinphoneCall *call, void *ud) { + L_SET_USER_DATA_FROM_C_STRUCT(call, ud, Call); +} + +// ============================================================================= +// Constructor and destructor functions. +// ============================================================================= + +LinphoneCall *linphone_call_new_outgoing (LinphoneCore *lc, const LinphoneAddress *from, const LinphoneAddress *to, const LinphoneCallParams *params, LinphoneProxyConfig *cfg) { + LinphoneCall *call = L_INIT(Call); + L_SET_CPP_PTR_FROM_C_STRUCT(call, std::make_shared(call, lc, LinphoneCallOutgoing, + *L_GET_CPP_PTR_FROM_C_STRUCT(from, Address), *L_GET_CPP_PTR_FROM_C_STRUCT(to, Address), + cfg, nullptr, L_GET_CPP_PTR_FROM_C_STRUCT(params, MediaSessionParams))); + call->currentParamsCache = linphone_call_params_new_for_wrapper(); + call->paramsCache = linphone_call_params_new_for_wrapper(); + call->remoteParamsCache = linphone_call_params_new_for_wrapper(); + call->remoteAddressCache = linphone_address_new(nullptr); + return call; +} + +LinphoneCall *linphone_call_new_incoming (LinphoneCore *lc, const LinphoneAddress *from, const LinphoneAddress *to, SalOp *op) { + LinphoneCall *call = L_INIT(Call); + L_SET_CPP_PTR_FROM_C_STRUCT(call, std::make_shared(call, lc, LinphoneCallIncoming, + *L_GET_CPP_PTR_FROM_C_STRUCT(from, Address), *L_GET_CPP_PTR_FROM_C_STRUCT(to, Address), + nullptr, op, nullptr)); + call->currentParamsCache = linphone_call_params_new_for_wrapper(); + call->paramsCache = linphone_call_params_new_for_wrapper(); + call->remoteParamsCache = linphone_call_params_new_for_wrapper(); + call->remoteAddressCache = linphone_address_new(nullptr); + GET_CPP_PRIVATE_PTR(call)->initiateIncoming(); + return call; +} diff --git a/src/c-wrapper/c-wrapper.h b/src/c-wrapper/c-wrapper.h index 90f0fb112..704f78866 100644 --- a/src/c-wrapper/c-wrapper.h +++ b/src/c-wrapper/c-wrapper.h @@ -27,6 +27,8 @@ #define L_REGISTER_TYPE(C_TYPE) \ extern Linphone ## C_TYPE *_linphone_ ## C_TYPE ## _init (); +#define L_INIT(C_TYPE) \ + _linphone_ ## C_TYPE ## _init () // ============================================================================= diff --git a/src/call/call-p.h b/src/call/call-p.h index d0035ac9c..29b4236ba 100644 --- a/src/call/call-p.h +++ b/src/call/call-p.h @@ -30,10 +30,6 @@ // ============================================================================= -extern std::shared_ptr linphone_call_get_cpp_obj(const LinphoneCall *call); - -// ============================================================================= - LINPHONE_BEGIN_NAMESPACE class CallPrivate : public ObjectPrivate, CallListener { diff --git a/src/call/call.cpp b/src/call/call.cpp index 678468ea4..994be2887 100644 --- a/src/call/call.cpp +++ b/src/call/call.cpp @@ -372,13 +372,13 @@ LinphoneCallLog * Call::getLog () const { return d->getActiveSession()->getLog(); } -RtpTransport * Call::getMetaRtcpTransport (int streamIndex) { - L_D(Call); +RtpTransport * Call::getMetaRtcpTransport (int streamIndex) const { + L_D(const Call); return static_cast(d->getActiveSession().get())->getMetaRtcpTransport(streamIndex); } -RtpTransport * Call::getMetaRtpTransport (int streamIndex) { - L_D(Call); +RtpTransport * Call::getMetaRtpTransport (int streamIndex) const { + L_D(const Call); return static_cast(d->getActiveSession().get())->getMetaRtpTransport(streamIndex); } @@ -447,8 +447,8 @@ LinphoneCallStats * Call::getStats (LinphoneStreamType type) const { return static_cast(d->getActiveSession().get())->getStats(type); } -int Call::getStreamCount () { - L_D(Call); +int Call::getStreamCount () const { + L_D(const Call); return static_cast(d->getActiveSession().get())->getStreamCount(); } diff --git a/src/call/call.h b/src/call/call.h index 2cb14bf3d..ad13c8b9c 100644 --- a/src/call/call.h +++ b/src/call/call.h @@ -76,8 +76,8 @@ public: int getDuration () const; const LinphoneErrorInfo * getErrorInfo () const; LinphoneCallLog * getLog () const; - RtpTransport * getMetaRtcpTransport (int streamIndex); - RtpTransport * getMetaRtpTransport (int streamIndex); + RtpTransport * getMetaRtcpTransport (int streamIndex) const; + RtpTransport * getMetaRtpTransport (int streamIndex) const; float getMicrophoneVolumeGain () const; void * getNativeVideoWindowId () const; const MediaSessionParams * getParams () const; @@ -91,7 +91,7 @@ public: float getSpeakerVolumeGain () const; LinphoneCallState getState () const; LinphoneCallStats * getStats (LinphoneStreamType type) const; - int getStreamCount (); + int getStreamCount () const; MSFormatType getStreamType (int streamIndex) const; LinphoneCallStats * getTextStats () const; LinphoneCallStats * getVideoStats () const; diff --git a/src/conference/session/call-session-p.h b/src/conference/session/call-session-p.h index 857c33105..34de3ea3f 100644 --- a/src/conference/session/call-session-p.h +++ b/src/conference/session/call-session-p.h @@ -67,7 +67,7 @@ protected: virtual LinphoneStatus startAcceptUpdate (LinphoneCallState nextState, const std::string &stateInfo); virtual LinphoneStatus startUpdate (); virtual void terminate (); - virtual void updateCurrentParams (); + virtual void updateCurrentParams () const; void setContactOp (); @@ -83,7 +83,7 @@ protected: CallSessionListener *listener = nullptr; CallSessionParams *params = nullptr; - CallSessionParams *currentParams = nullptr; + mutable CallSessionParams *currentParams = nullptr; CallSessionParams *remoteParams = nullptr; LinphoneCallDir direction = LinphoneCallOutgoing; diff --git a/src/conference/session/call-session.cpp b/src/conference/session/call-session.cpp index 7054a20d8..481db6bd2 100644 --- a/src/conference/session/call-session.cpp +++ b/src/conference/session/call-session.cpp @@ -512,7 +512,7 @@ LinphoneStatus CallSessionPrivate::checkForAcceptation () const { bctbx_list_t *copy = bctbx_list_copy(linphone_core_get_calls(core)); for (bctbx_list_t *it = copy; it != nullptr; it = bctbx_list_next(it)) { LinphoneCall *call = reinterpret_cast(bctbx_list_get_data(it)); - shared_ptr session = linphone_call_get_cpp_obj(call)->getPrivate()->getActiveSession(); + shared_ptr session = L_GET_PRIVATE_FROM_C_STRUCT(call, Call)->getActiveSession(); if (session.get() == q) continue; switch (session->getState()) { case LinphoneCallOutgoingInit: @@ -668,7 +668,7 @@ void CallSessionPrivate::terminate () { setState(LinphoneCallEnd, "Call terminated"); } -void CallSessionPrivate::updateCurrentParams () {} +void CallSessionPrivate::updateCurrentParams () const {} // ----------------------------------------------------------------------------- @@ -1087,8 +1087,8 @@ string CallSession::getRemoteUserAgent () const { return string(); } -CallSessionParams * CallSession::getCurrentParams () { - L_D(CallSession); +CallSessionParams * CallSession::getCurrentParams () const { + L_D(const CallSession); d->updateCurrentParams(); return d->currentParams; } diff --git a/src/conference/session/call-session.h b/src/conference/session/call-session.h index db46a9871..96dcbf2bf 100644 --- a/src/conference/session/call-session.h +++ b/src/conference/session/call-session.h @@ -51,7 +51,7 @@ public: LinphoneStatus terminate (const LinphoneErrorInfo *ei = nullptr); LinphoneStatus update (const CallSessionParams *csp); - CallSessionParams *getCurrentParams (); + CallSessionParams *getCurrentParams () const; LinphoneCallDir getDirection () const; int getDuration () const; const LinphoneErrorInfo * getErrorInfo () const; diff --git a/src/conference/session/media-session-p.h b/src/conference/session/media-session-p.h index 210f2df2a..8a65ea4ca 100644 --- a/src/conference/session/media-session-p.h +++ b/src/conference/session/media-session-p.h @@ -219,7 +219,7 @@ private: LinphoneStatus startAcceptUpdate (LinphoneCallState nextState, const std::string &stateInfo) override; LinphoneStatus startUpdate () override; void terminate () override; - void updateCurrentParams () override; + void updateCurrentParams () const override; void accept (const MediaSessionParams *params); LinphoneStatus acceptUpdate (const CallSessionParams *csp, LinphoneCallState nextState, const std::string &stateInfo) override; @@ -236,7 +236,7 @@ private: static const int ecStateMaxLen; MediaSessionParams *params = nullptr; - MediaSessionParams *currentParams = nullptr; + mutable MediaSessionParams *currentParams = nullptr; MediaSessionParams *remoteParams = nullptr; AudioStream *audioStream = nullptr; diff --git a/src/conference/session/media-session.cpp b/src/conference/session/media-session.cpp index 1613e6282..b079be8b1 100644 --- a/src/conference/session/media-session.cpp +++ b/src/conference/session/media-session.cpp @@ -72,11 +72,11 @@ MediaSessionPrivate::MediaSessionPrivate (const Conference &conference, const Ca params = new MediaSessionParams(*(reinterpret_cast(csp))); currentParams = new MediaSessionParams(); - audioStats = linphone_call_stats_ref(linphone_call_stats_new()); + audioStats = linphone_call_stats_ref(_linphone_call_stats_new()); initStats(audioStats, LinphoneStreamTypeAudio); - videoStats = linphone_call_stats_ref(linphone_call_stats_new()); + videoStats = linphone_call_stats_ref(_linphone_call_stats_new()); initStats(videoStats, LinphoneStreamTypeVideo); - textStats = linphone_call_stats_ref(linphone_call_stats_new()); + textStats = linphone_call_stats_ref(_linphone_call_stats_new()); initStats(textStats, LinphoneStreamTypeText); int minPort, maxPort; @@ -498,9 +498,9 @@ void MediaSessionPrivate::deactivateIce () { videoStream->ms.ice_check_list = nullptr; if (textStream) textStream->ms.ice_check_list = nullptr; - audioStats->ice_state = LinphoneIceStateNotActivated; - videoStats->ice_state = LinphoneIceStateNotActivated; - textStats->ice_state = LinphoneIceStateNotActivated; + _linphone_call_stats_set_ice_state(audioStats, LinphoneIceStateNotActivated); + _linphone_call_stats_set_ice_state(videoStats, LinphoneIceStateNotActivated); + _linphone_call_stats_set_ice_state(textStats, LinphoneIceStateNotActivated); stopStreamsForIceGathering(); } @@ -845,10 +845,10 @@ void MediaSessionPrivate::updateRemoteSessionIdAndVer () { // ----------------------------------------------------------------------------- void MediaSessionPrivate::initStats (LinphoneCallStats *stats, LinphoneStreamType type) { - stats->type = type; - stats->received_rtcp = nullptr; - stats->sent_rtcp = nullptr; - stats->ice_state = LinphoneIceStateNotActivated; + _linphone_call_stats_set_type(stats, type); + _linphone_call_stats_set_received_rtcp(stats, nullptr); + _linphone_call_stats_set_sent_rtcp(stats, nullptr); + _linphone_call_stats_set_ice_state(stats, LinphoneIceStateNotActivated); } void MediaSessionPrivate::notifyStatsUpdated (int streamIndex) const { @@ -861,8 +861,8 @@ void MediaSessionPrivate::notifyStatsUpdated (int streamIndex) const { stats = textStats; else return; - if (stats->updated) { - switch (stats->updated) { + if (_linphone_call_stats_get_updated(stats)) { + switch (_linphone_call_stats_get_updated(stats)) { case LINPHONE_CALL_STATS_RECEIVED_RTCP_UPDATE: case LINPHONE_CALL_STATS_SENT_RTCP_UPDATE: #if 0 @@ -874,7 +874,7 @@ void MediaSessionPrivate::notifyStatsUpdated (int streamIndex) const { } if (listener) listener->onStatsUpdated(stats); - stats->updated = 0; + _linphone_call_stats_set_updated(stats, 0); } } @@ -924,8 +924,7 @@ int MediaSessionPrivate::selectFixedPort (int streamIndex, pair portRa bool alreadyUsed = false; for (const bctbx_list_t *elem = linphone_core_get_calls(core); elem != nullptr; elem = bctbx_list_next(elem)) { LinphoneCall *lcall = reinterpret_cast(bctbx_list_get_data(elem)); - CallPrivate *callp = linphone_call_get_cpp_obj(lcall)->getPrivate(); - MediaSession *session = dynamic_cast(callp->getConference()->getActiveParticipant()->getPrivate()->getSession().get()); + MediaSession *session = dynamic_cast(L_GET_PRIVATE_FROM_C_STRUCT(lcall, Call)->getConference()->getActiveParticipant()->getPrivate()->getSession().get()); int existingPort = session->getPrivate()->mediaPorts[streamIndex].rtpPort; if (existingPort == triedPort) { alreadyUsed = true; @@ -947,8 +946,7 @@ int MediaSessionPrivate::selectRandomPort (int streamIndex, pair portR if (triedPort < portRange.first) triedPort = portRange.first + 2; for (const bctbx_list_t *elem = linphone_core_get_calls(core); elem != nullptr; elem = bctbx_list_next(elem)) { LinphoneCall *lcall = reinterpret_cast(bctbx_list_get_data(elem)); - CallPrivate *callp = linphone_call_get_cpp_obj(lcall)->getPrivate(); - MediaSession *session = dynamic_cast(callp->getConference()->getActiveParticipant()->getPrivate()->getSession().get()); + MediaSession *session = dynamic_cast(L_GET_PRIVATE_FROM_C_STRUCT(lcall, Call)->getConference()->getActiveParticipant()->getPrivate()->getSession().get()); int existingPort = session->getPrivate()->mediaPorts[streamIndex].rtpPort; if (existingPort == triedPort) { alreadyUsed = true; @@ -2069,9 +2067,9 @@ void MediaSessionPrivate::freeResources () { iceAgent->deleteSession(); for (int i = 0; i < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; i++) ms_media_stream_sessions_uninit(&sessions[i]); - linphone_call_stats_uninit(audioStats); - linphone_call_stats_uninit(videoStats); - linphone_call_stats_uninit(textStats); + _linphone_call_stats_uninit(audioStats); + _linphone_call_stats_uninit(videoStats); + _linphone_call_stats_uninit(textStats); } void MediaSessionPrivate::handleIceEvents (OrtpEvent *ev) { @@ -3409,8 +3407,8 @@ void MediaSessionPrivate::fillLogStats (MediaStream *st) { void MediaSessionPrivate::updateRtpStats (LinphoneCallStats *stats, int streamIndex) { if (sessions[streamIndex].rtp_session) { const rtp_stats_t *rtpStats = rtp_session_get_stats(sessions[streamIndex].rtp_session); - if (stats) - memcpy(&(stats->rtp_stats), rtpStats, sizeof(*rtpStats)); + if (rtpStats) + _linphone_call_stats_set_rtp_stats(stats, rtpStats); } } @@ -3604,12 +3602,12 @@ void MediaSessionPrivate::reportBandwidth () { reportBandwidthForStream(&textStream->ms, LinphoneStreamTypeText); lInfo() << "Bandwidth usage for CallSession [" << q << "]:\n" << fixed << setprecision(2) << - "\tRTP audio=[d=" << audioStats->download_bandwidth << ",u=" << audioStats->upload_bandwidth << - "], video=[d=" << videoStats->download_bandwidth << ",u=" << videoStats->upload_bandwidth << - "], text=[d=" << textStats->download_bandwidth << ",u=" << textStats->upload_bandwidth << "] kbits/sec\n" << - "\tRTCP audio=[d=" << audioStats->rtcp_download_bandwidth << ",u=" << audioStats->rtcp_upload_bandwidth << - "], video=[d=" << videoStats->rtcp_download_bandwidth << ",u=" << videoStats->rtcp_upload_bandwidth << - "], text=[d=" << textStats->rtcp_download_bandwidth << ",u=" << textStats->rtcp_upload_bandwidth << "] kbits/sec"; + "\tRTP audio=[d=" << linphone_call_stats_get_download_bandwidth(audioStats) << ",u=" << linphone_call_stats_get_upload_bandwidth(audioStats) << + "], video=[d=" << linphone_call_stats_get_download_bandwidth(videoStats) << ",u=" << linphone_call_stats_get_upload_bandwidth(videoStats) << + "], text=[d=" << linphone_call_stats_get_download_bandwidth(textStats) << ",u=" << linphone_call_stats_get_upload_bandwidth(textStats) << "] kbits/sec\n" << + "\tRTCP audio=[d=" << linphone_call_stats_get_rtcp_download_bandwidth(audioStats) << ",u=" << linphone_call_stats_get_rtcp_upload_bandwidth(audioStats) << + "], video=[d=" << linphone_call_stats_get_rtcp_download_bandwidth(videoStats) << ",u=" << linphone_call_stats_get_rtcp_upload_bandwidth(videoStats) << + "], text=[d=" << linphone_call_stats_get_rtcp_download_bandwidth(textStats) << ",u=" << linphone_call_stats_get_rtcp_upload_bandwidth(textStats) << "] kbits/sec"; } void MediaSessionPrivate::reportBandwidthForStream (MediaStream *ms, LinphoneStreamType type) { @@ -3624,19 +3622,20 @@ void MediaSessionPrivate::reportBandwidthForStream (MediaStream *ms, LinphoneStr return; bool active = ms ? (media_stream_get_state(ms) == MSStreamStarted) : false; - stats->download_bandwidth = active ? (float)(media_stream_get_down_bw(ms) * 1e-3) : 0.f; - stats->upload_bandwidth = active ? (float)(media_stream_get_up_bw(ms) * 1e-3) : 0.f; - stats->rtcp_download_bandwidth = active ? (float)(media_stream_get_rtcp_down_bw(ms) * 1e-3) : 0.f; - stats->rtcp_upload_bandwidth = active ? (float)(media_stream_get_rtcp_up_bw(ms) * 1e-3) : 0.f; - stats->rtp_remote_family = active ? (ortp_stream_is_ipv6(&ms->sessions.rtp_session->rtp.gs) ? LinphoneAddressFamilyInet6 : LinphoneAddressFamilyInet) : LinphoneAddressFamilyUnspec; + _linphone_call_stats_set_download_bandwidth(stats, active ? (float)(media_stream_get_down_bw(ms) * 1e-3) : 0.f); + _linphone_call_stats_set_upload_bandwidth(stats, active ? (float)(media_stream_get_up_bw(ms) * 1e-3) : 0.f); + _linphone_call_stats_set_rtcp_download_bandwidth(stats, active ? (float)(media_stream_get_rtcp_down_bw(ms) * 1e-3) : 0.f); + _linphone_call_stats_set_rtcp_upload_bandwidth(stats, active ? (float)(media_stream_get_rtcp_up_bw(ms) * 1e-3) : 0.f); + _linphone_call_stats_set_ip_family_of_remote(stats, + active ? (ortp_stream_is_ipv6(&ms->sessions.rtp_session->rtp.gs) ? LinphoneAddressFamilyInet6 : LinphoneAddressFamilyInet) : LinphoneAddressFamilyUnspec); if (core->send_call_stats_periodical_updates) { if (active) linphone_call_stats_update(stats, ms); - stats->updated |= LINPHONE_CALL_STATS_PERIODICAL_UPDATE; + _linphone_call_stats_set_updated(stats, _linphone_call_stats_get_updated(stats) | LINPHONE_CALL_STATS_PERIODICAL_UPDATE); if (listener) listener->onStatsUpdated(stats); - stats->updated = 0; + _linphone_call_stats_set_updated(stats, 0); } } @@ -3767,7 +3766,7 @@ void MediaSessionPrivate::terminate () { CallSessionPrivate::terminate(); } -void MediaSessionPrivate::updateCurrentParams () { +void MediaSessionPrivate::updateCurrentParams () const { CallSessionPrivate::updateCurrentParams(); LinphoneVideoDefinition *vdef = linphone_video_definition_new(MS_VIDEO_SIZE_UNKNOWN_W, MS_VIDEO_SIZE_UNKNOWN_H, nullptr); @@ -4516,8 +4515,8 @@ float MediaSession::getAverageQuality () const { return MediaSessionPrivate::aggregateQualityRatings(audioRating, videoRating); } -MediaSessionParams * MediaSession::getCurrentParams () { - L_D(MediaSession); +MediaSessionParams * MediaSession::getCurrentParams () const { + L_D(const MediaSession); d->updateCurrentParams(); return d->currentParams; } @@ -4538,8 +4537,8 @@ const MediaSessionParams * MediaSession::getMediaParams () const { return d->params; } -RtpTransport * MediaSession::getMetaRtcpTransport (int streamIndex) { - L_D(MediaSession); +RtpTransport * MediaSession::getMetaRtcpTransport (int streamIndex) const { + L_D(const MediaSession); if ((streamIndex < 0) || (streamIndex >= getStreamCount())) return nullptr; RtpTransport *metaRtp; @@ -4548,8 +4547,8 @@ RtpTransport * MediaSession::getMetaRtcpTransport (int streamIndex) { return metaRtcp; } -RtpTransport * MediaSession::getMetaRtpTransport (int streamIndex) { - L_D(MediaSession); +RtpTransport * MediaSession::getMetaRtpTransport (int streamIndex) const { + L_D(const MediaSession); if ((streamIndex < 0) || (streamIndex >= getStreamCount())) return nullptr; RtpTransport *metaRtp; @@ -4676,7 +4675,7 @@ LinphoneCallStats * MediaSession::getStats (LinphoneStreamType type) const { if (type == LinphoneStreamTypeUnknown) return nullptr; LinphoneCallStats *stats = nullptr; - LinphoneCallStats *statsCopy = linphone_call_stats_new(); + LinphoneCallStats *statsCopy = _linphone_call_stats_new(); if (type == LinphoneStreamTypeAudio) stats = d->audioStats; else if (type == LinphoneStreamTypeVideo) @@ -4690,7 +4689,7 @@ LinphoneCallStats * MediaSession::getStats (LinphoneStreamType type) const { return statsCopy; } -int MediaSession::getStreamCount () { +int MediaSession::getStreamCount () const { /* TODO: Revisit when multiple media streams will be implemented */ #ifdef VIDEO_ENABLED if (getCurrentParams()->realtimeTextEnabled()) @@ -4725,9 +4724,9 @@ LinphoneCallStats * MediaSession::getVideoStats () const { bool MediaSession::mediaInProgress () const { L_D(const MediaSession); - if ((d->audioStats->ice_state == LinphoneIceStateInProgress) - || (d->videoStats->ice_state == LinphoneIceStateInProgress) - || (d->textStats->ice_state == LinphoneIceStateInProgress)) + if ((linphone_call_stats_get_ice_state(d->audioStats) == LinphoneIceStateInProgress) + || (linphone_call_stats_get_ice_state(d->videoStats) == LinphoneIceStateInProgress) + || (linphone_call_stats_get_ice_state(d->textStats) == LinphoneIceStateInProgress)) return true; /* TODO: could check zrtp state */ return false; diff --git a/src/conference/session/media-session.h b/src/conference/session/media-session.h index 3403746ea..e27c1c7e2 100644 --- a/src/conference/session/media-session.h +++ b/src/conference/session/media-session.h @@ -69,11 +69,11 @@ public: std::string getAuthenticationToken () const; bool getAuthenticationTokenVerified () const; float getAverageQuality () const; - MediaSessionParams *getCurrentParams (); + MediaSessionParams *getCurrentParams () const; float getCurrentQuality () const; const MediaSessionParams *getMediaParams () const; - RtpTransport * getMetaRtcpTransport (int streamIndex); - RtpTransport * getMetaRtpTransport (int streamIndex); + RtpTransport * getMetaRtcpTransport (int streamIndex) const; + RtpTransport * getMetaRtpTransport (int streamIndex) const; float getMicrophoneVolumeGain () const; void * getNativeVideoWindowId () const; const CallSessionParams *getParams () const override; @@ -82,7 +82,7 @@ public: const MediaSessionParams *getRemoteParams (); float getSpeakerVolumeGain () const; LinphoneCallStats * getStats (LinphoneStreamType type) const; - int getStreamCount (); + int getStreamCount () const; MSFormatType getStreamType (int streamIndex) const; LinphoneCallStats * getTextStats () const; LinphoneCallStats * getVideoStats () const; diff --git a/src/nat/ice-agent.cpp b/src/nat/ice-agent.cpp index 00cc5219a..63605b3bd 100644 --- a/src/nat/ice-agent.cpp +++ b/src/nat/ice-agent.cpp @@ -233,35 +233,35 @@ void IceAgent::updateIceStateInCallStats () { LinphoneCallStats *textStats = mediaSession.getPrivate()->getStats(LinphoneStreamTypeText); IceSessionState sessionState = ice_session_state(iceSession); if ((sessionState == IS_Completed) || ((sessionState == IS_Failed) && ice_session_has_completed_check_list(iceSession))) { - audioStats->ice_state = LinphoneIceStateNotActivated; + _linphone_call_stats_set_ice_state(audioStats, LinphoneIceStateNotActivated); if (audioCheckList && mediaSession.getMediaParams()->audioEnabled()) updateIceStateInCallStatsForStream(audioStats, audioCheckList); - videoStats->ice_state = LinphoneIceStateNotActivated; + _linphone_call_stats_set_ice_state(videoStats, LinphoneIceStateNotActivated); if (videoCheckList && mediaSession.getMediaParams()->videoEnabled()) updateIceStateInCallStatsForStream(videoStats, videoCheckList); - textStats->ice_state = LinphoneIceStateNotActivated; + _linphone_call_stats_set_ice_state(textStats, LinphoneIceStateNotActivated); if (textCheckList && mediaSession.getMediaParams()->realtimeTextEnabled()) updateIceStateInCallStatsForStream(textStats, textCheckList); } else if (sessionState == IS_Running) { if (audioCheckList && mediaSession.getMediaParams()->audioEnabled()) - audioStats->ice_state = LinphoneIceStateInProgress; + _linphone_call_stats_set_ice_state(audioStats, LinphoneIceStateInProgress); if (videoCheckList && mediaSession.getMediaParams()->videoEnabled()) - videoStats->ice_state = LinphoneIceStateInProgress; + _linphone_call_stats_set_ice_state(videoStats, LinphoneIceStateInProgress); if (textCheckList && mediaSession.getMediaParams()->realtimeTextEnabled()) - textStats->ice_state = LinphoneIceStateInProgress; + _linphone_call_stats_set_ice_state(textStats, LinphoneIceStateInProgress); } else { if (audioCheckList && mediaSession.getMediaParams()->audioEnabled()) - audioStats->ice_state = LinphoneIceStateFailed; + _linphone_call_stats_set_ice_state(audioStats, LinphoneIceStateFailed); if (videoCheckList && mediaSession.getMediaParams()->videoEnabled()) - videoStats->ice_state = LinphoneIceStateFailed; + _linphone_call_stats_set_ice_state(videoStats, LinphoneIceStateFailed); if (textCheckList && mediaSession.getMediaParams()->realtimeTextEnabled()) - textStats->ice_state = LinphoneIceStateFailed; + _linphone_call_stats_set_ice_state(textStats, LinphoneIceStateFailed); } - lInfo() << "CallSession [" << &mediaSession << "] New ICE state: audio: [" << linphone_ice_state_to_string(audioStats->ice_state) - << "] video: [" << linphone_ice_state_to_string(videoStats->ice_state) - << "] text: [" << linphone_ice_state_to_string(textStats->ice_state) << "]"; + lInfo() << "CallSession [" << &mediaSession << "] New ICE state: audio: [" << linphone_ice_state_to_string(linphone_call_stats_get_ice_state(audioStats)) + << "] video: [" << linphone_ice_state_to_string(linphone_call_stats_get_ice_state(videoStats)) + << "] text: [" << linphone_ice_state_to_string(linphone_call_stats_get_ice_state(textStats)) << "]"; } void IceAgent::updateLocalMediaDescriptionFromIce (SalMediaDescription *desc) { @@ -387,7 +387,7 @@ void IceAgent::addLocalIceCandidates (int family, const char *addr, IceCheckList ice_add_local_candidate(audioCl, "host", family, addr, rtpPort, 1, nullptr); ice_add_local_candidate(audioCl, "host", family, addr, rtcpPort, 2, nullptr); LinphoneCallStats *audioStats = mediaSession.getPrivate()->getStats(LinphoneStreamTypeAudio); - audioStats->ice_state = LinphoneIceStateInProgress; + _linphone_call_stats_set_ice_state(audioStats, LinphoneIceStateInProgress); } LinphoneCore *core = mediaSession.getPrivate()->getCore(); if (linphone_core_video_enabled(core) && videoCl && (ice_check_list_state(videoCl) != ICL_Completed) && !ice_check_list_candidates_gathered(videoCl)) { @@ -396,7 +396,7 @@ void IceAgent::addLocalIceCandidates (int family, const char *addr, IceCheckList ice_add_local_candidate(videoCl, "host", family, addr, rtpPort, 1, nullptr); ice_add_local_candidate(videoCl, "host", family, addr, rtcpPort, 2, nullptr); LinphoneCallStats *videoStats = mediaSession.getPrivate()->getStats(LinphoneStreamTypeVideo); - videoStats->ice_state = LinphoneIceStateInProgress; + _linphone_call_stats_set_ice_state(videoStats, LinphoneIceStateInProgress); } if (mediaSession.getMediaParams()->realtimeTextEnabled() && textCl && (ice_check_list_state(textCl) != ICL_Completed) && !ice_check_list_candidates_gathered(textCl)) { int rtpPort = mediaSession.getPrivate()->getRtpPort(LinphoneStreamTypeText); @@ -404,7 +404,7 @@ void IceAgent::addLocalIceCandidates (int family, const char *addr, IceCheckList ice_add_local_candidate(textCl, "host", family, addr, rtpPort, 1, nullptr); ice_add_local_candidate(textCl, "host", family, addr, rtcpPort, 2, nullptr); LinphoneCallStats *textStats = mediaSession.getPrivate()->getStats(LinphoneStreamTypeText); - textStats->ice_state = LinphoneIceStateInProgress; + _linphone_call_stats_set_ice_state(textStats, LinphoneIceStateInProgress); } } @@ -671,14 +671,14 @@ void IceAgent::updateIceStateInCallStatsForStream (LinphoneCallStats *stats, Ice if (ice_check_list_state(cl) == ICL_Completed) { switch (ice_check_list_selected_valid_candidate_type(cl)) { case ICT_HostCandidate: - stats->ice_state = LinphoneIceStateHostConnection; + _linphone_call_stats_set_ice_state(stats, LinphoneIceStateHostConnection); break; case ICT_ServerReflexiveCandidate: case ICT_PeerReflexiveCandidate: - stats->ice_state = LinphoneIceStateReflexiveConnection; + _linphone_call_stats_set_ice_state(stats, LinphoneIceStateReflexiveConnection); break; case ICT_RelayedCandidate: - stats->ice_state = LinphoneIceStateRelayConnection; + _linphone_call_stats_set_ice_state(stats, LinphoneIceStateRelayConnection); break; case ICT_CandidateInvalid: case ICT_CandidateTypeMax: @@ -686,7 +686,7 @@ void IceAgent::updateIceStateInCallStatsForStream (LinphoneCallStats *stats, Ice break; } } else - stats->ice_state = LinphoneIceStateFailed; + _linphone_call_stats_set_ice_state(stats, LinphoneIceStateFailed); } LINPHONE_END_NAMESPACE