diff --git a/coreapi/conference.c b/coreapi/conference.c deleted file mode 100644 index 66898d9a2..000000000 --- a/coreapi/conference.c +++ /dev/null @@ -1,430 +0,0 @@ -/*************************************************************************** - * conference.c - * - * Mon Sep 12, 2011 - * Copyright 2011 Belledonne Communications - * Author: Simon Morlat - * Email simon dot morlat at linphone dot org - ****************************************************************************/ - -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include "private.h" -#include "lpconfig.h" - -#include "mediastreamer2/msvolume.h" - -/** - * @addtogroup conferencing - * @{ -**/ - - -static int convert_conference_to_call(LinphoneCore *lc); - -static void conference_check_init(LinphoneConference *ctx, int samplerate){ - if (ctx->conf==NULL){ - MSAudioConferenceParams params; - params.samplerate=samplerate; - ctx->conf=ms_audio_conference_new(¶ms); - ctx->terminated=FALSE; - } -} - -static void remove_local_endpoint(LinphoneConference *ctx){ - if (ctx->local_endpoint){ - ms_audio_conference_remove_member(ctx->conf,ctx->local_endpoint); - ms_audio_endpoint_release_from_stream(ctx->local_endpoint); - ctx->local_endpoint=NULL; - audio_stream_stop(ctx->local_participant); - ctx->local_participant=NULL; - rtp_profile_destroy(ctx->local_dummy_profile); - } -} - -static int linphone_conference_get_size(LinphoneConference *conf){ - if (conf->conf == NULL) { - return 0; - } - return ms_audio_conference_get_size(conf->conf) - (conf->record_endpoint ? 1 : 0); -} - -static int remote_participants_count(LinphoneConference *ctx) { - int count=linphone_conference_get_size(ctx); - if (count==0) return 0; - if (!ctx->local_participant) return count; - return count -1; -} - -void linphone_core_conference_check_uninit(LinphoneCore *lc){ - LinphoneConference *ctx=&lc->conf_ctx; - if (ctx->conf){ - int remote_count=remote_participants_count(ctx); - ms_message("conference_check_uninit(): size=%i",linphone_conference_get_size(ctx)); - if (remote_count==1 && !ctx->terminated){ - convert_conference_to_call(lc); - } - if (remote_count==0){ - if (ctx->local_participant!=NULL) - remove_local_endpoint(ctx); - if (ctx->record_endpoint){ - ms_audio_conference_remove_member(ctx->conf,ctx->record_endpoint); - ms_audio_endpoint_destroy(ctx->record_endpoint); - ctx->record_endpoint=NULL; - } - } - - if (ms_audio_conference_get_size(ctx->conf)==0){ - ms_audio_conference_destroy(ctx->conf); - ctx->conf=NULL; - } - } -} - -void linphone_call_add_to_conf(LinphoneCall *call, bool_t muted){ - LinphoneCore *lc=call->core; - LinphoneConference *conf=&lc->conf_ctx; - MSAudioEndpoint *ep; - call->params->has_video = FALSE; - call->camera_enabled = FALSE; - ep=ms_audio_endpoint_get_from_stream(call->audiostream,TRUE); - ms_audio_conference_add_member(conf->conf,ep); - ms_audio_conference_mute_member(conf->conf,ep,muted); - call->endpoint=ep; -} - -void linphone_call_remove_from_conf(LinphoneCall *call){ - LinphoneCore *lc=call->core; - LinphoneConference *conf=&lc->conf_ctx; - - ms_audio_conference_remove_member(conf->conf,call->endpoint); - ms_audio_endpoint_release_from_stream(call->endpoint); - call->endpoint=NULL; -} - -static RtpProfile *make_dummy_profile(int samplerate){ - RtpProfile *prof=rtp_profile_new("dummy"); - PayloadType *pt=payload_type_clone(&payload_type_l16_mono); - pt->clock_rate=samplerate; - rtp_profile_set_payload(prof,0,pt); - return prof; -} - -static void add_local_endpoint(LinphoneConference *conf,LinphoneCore *lc){ - /*create a dummy audiostream in order to extract the local part of it */ - /* network address and ports have no meaning and are not used here. */ - AudioStream *st=audio_stream_new(65000,65001,FALSE); - MSSndCard *playcard=lc->sound_conf.lsd_card ? - lc->sound_conf.lsd_card : lc->sound_conf.play_sndcard; - MSSndCard *captcard=lc->sound_conf.capt_sndcard; - const MSAudioConferenceParams *params=ms_audio_conference_get_params(conf->conf); - conf->local_dummy_profile=make_dummy_profile(params->samplerate); - - audio_stream_start_full(st, conf->local_dummy_profile, - "127.0.0.1", - 65000, - "127.0.0.1", - 65001, - 0, - 40, - NULL, - NULL, - playcard, - captcard, - linphone_core_echo_cancellation_enabled(lc) - ); - _post_configure_audio_stream(st,lc,FALSE); - conf->local_participant=st; - conf->local_endpoint=ms_audio_endpoint_get_from_stream(st,FALSE); - ms_audio_conference_add_member(conf->conf,conf->local_endpoint); - -} - -/** - * Returns the sound volume (mic input) of the local participant of the conference. - * @param lc the linphone core - * @return the measured input volume expressed in dbm0. - **/ -float linphone_core_get_conference_local_input_volume(LinphoneCore *lc){ - LinphoneConference *conf=&lc->conf_ctx; - AudioStream *st=conf->local_participant; - if (st && st->volsend && !conf->local_muted){ - float vol=0; - ms_filter_call_method(st->volsend,MS_VOLUME_GET,&vol); - return vol; - - } - return LINPHONE_VOLUME_DB_LOWEST; -} - -/** - * Merge a call into a conference. - * @param lc the linphone core - * @param call an established call, either in LinphoneCallStreamsRunning or LinphoneCallPaused state. - * - * If this is the first call that enters the conference, the virtual conference will be created automatically. - * If the local user was actively part of the call (ie not in paused state), then the local user is automatically entered into the conference. - * If the call was in paused state, then it is automatically resumed when entering into the conference. - * - * @return 0 if successful, -1 otherwise. -**/ -int linphone_core_add_to_conference(LinphoneCore *lc, LinphoneCall *call){ - LinphoneConference *conf=&lc->conf_ctx; - - if (call->current_params->in_conference){ - ms_error("Already in conference"); - return -1; - } - conference_check_init(&lc->conf_ctx, lp_config_get_int(lc->config, "sound","conference_rate",16000)); - - if (call->state==LinphoneCallPaused){ - call->params->in_conference=TRUE; - call->params->has_video=FALSE; - linphone_core_resume_call(lc,call); - }else if (call->state==LinphoneCallStreamsRunning){ - LinphoneCallParams *params=linphone_call_params_copy(linphone_call_get_current_params(call)); - params->in_conference=TRUE; - params->has_video=FALSE; - - if (call->audiostream || call->videostream){ - linphone_call_stop_media_streams(call); /*free the audio & video local resources*/ - linphone_call_init_media_streams(call); - } - if (call==lc->current_call){ - lc->current_call=NULL; - } - /*this will trigger a reINVITE that will later redraw the streams */ - /*FIXME probably a bit too much to just redraw streams !*/ - linphone_core_update_call(lc,call,params); - linphone_call_params_destroy(params); - add_local_endpoint(conf,lc); - }else{ - ms_error("Call is in state %s, it cannot be added to the conference.",linphone_call_state_to_string(call->state)); - return -1; - } - return 0; -} - -static int remove_from_conference(LinphoneCore *lc, LinphoneCall *call, bool_t active){ - int err=0; - char *str; - - if (!call->current_params->in_conference){ - if (call->params->in_conference){ - ms_warning("Not (yet) in conference, be patient"); - return -1; - }else{ - ms_error("Not in a conference."); - return -1; - } - } - call->params->in_conference=FALSE; - - str=linphone_call_get_remote_address_as_string(call); - ms_message("%s will be removed from conference", str); - ms_free(str); - if (active){ - LinphoneCallParams *params=linphone_call_params_copy(linphone_call_get_current_params(call)); - params->in_conference=FALSE; - // reconnect local audio with this call - if (linphone_core_is_in_conference(lc)){ - ms_message("Leaving conference for reconnecting with unique call."); - linphone_core_leave_conference(lc); - } - ms_message("Updating call to actually remove from conference"); - err=linphone_core_update_call(lc,call,params); - linphone_call_params_destroy(params); - } else{ - ms_message("Pausing call to actually remove from conference"); - err=_linphone_core_pause_call(lc,call); - } - return err; -} - -static int convert_conference_to_call(LinphoneCore *lc){ - int err=0; - MSList *calls=lc->calls; - - if (remote_participants_count(&lc->conf_ctx)!=1){ - ms_error("No unique call remaining in conference."); - return -1; - } - - while (calls) { - LinphoneCall *rc=(LinphoneCall*)calls->data; - calls=calls->next; - if (rc->params->in_conference) { // not using current_param - bool_t active_after_removed=linphone_core_is_in_conference(lc); - err=remove_from_conference(lc, rc, active_after_removed); - break; - } - } - return err; -} - -int linphone_core_remove_from_conference(LinphoneCore *lc, LinphoneCall *call){ - int err; - char * str=linphone_call_get_remote_address_as_string(call); - ms_message("Removing call %s from the conference", str); - ms_free(str); - err=remove_from_conference(lc,call, FALSE); - if (err){ - ms_error("Error removing participant from conference."); - return err; - } - - if (remote_participants_count(&lc->conf_ctx)==1){ - ms_message("conference size is 1: need to be converted to plain call"); - err=convert_conference_to_call(lc); - } else { - ms_message("the conference need not to be converted as size is %i", remote_participants_count(&lc->conf_ctx)); - } - return err; -} - -bool_t linphone_core_is_in_conference(const LinphoneCore *lc){ - return lc->conf_ctx.local_participant!=NULL; -} - -/** - * Moves the local participant out of the conference. - * @param lc the linphone core - * When the local participant is out of the conference, the remote participants can continue to talk normally. - * @return 0 if successful, -1 otherwise. -**/ -int linphone_core_leave_conference(LinphoneCore *lc){ - LinphoneConference *conf=&lc->conf_ctx; - if (linphone_core_is_in_conference(lc)) - remove_local_endpoint(conf); - return 0; -} - -/** - * Moves the local participant inside the conference. - * @param lc the linphone core - * - * Makes the local participant to join the conference. - * Typically, the local participant is by default always part of the conference when joining an active call into a conference. - * However, by calling linphone_core_leave_conference() and linphone_core_enter_conference() the application can decide to temporarily - * move out and in the local participant from the conference. - * - * @return 0 if successful, -1 otherwise -**/ -int linphone_core_enter_conference(LinphoneCore *lc){ - LinphoneConference *conf; - if (linphone_core_sound_resources_locked(lc)) { - return -1; - } - if (lc->current_call != NULL) { - _linphone_core_pause_call(lc, lc->current_call); - } - conf=&lc->conf_ctx; - if (conf->local_participant==NULL) add_local_endpoint(conf,lc); - return 0; -} - -/** - * Add all calls into a conference. - * @param lc the linphone core - * - * Merge all established calls (either in LinphoneCallStreamsRunning or LinphoneCallPaused) into a conference. - * - * @return 0 if successful, -1 otherwise -**/ -int linphone_core_add_all_to_conference(LinphoneCore *lc) { - MSList *calls=lc->calls; - while (calls) { - LinphoneCall *call=(LinphoneCall*)calls->data; - calls=calls->next; - if (!call->current_params->in_conference) { - linphone_core_add_to_conference(lc, call); - } - } - linphone_core_enter_conference(lc); - return 0; -} - -/** - * Terminates the conference and the calls associated with it. - * @param lc the linphone core - * - * All the calls that were merged to the conference are terminated, and the conference resources are destroyed. - * - * @return 0 if successful, -1 otherwise -**/ -int linphone_core_terminate_conference(LinphoneCore *lc) { - MSList *calls=lc->calls; - LinphoneConference *conf=&lc->conf_ctx; - conf->terminated=TRUE; - - while (calls) { - LinphoneCall *call=(LinphoneCall*)calls->data; - calls=calls->next; - if (call->current_params->in_conference) { - linphone_core_terminate_call(lc, call); - } - } - return 0; -} - -/** - * Returns the number of participants to the conference, including the local participant. - * @param lc the linphone core - * - * Typically, after merging two calls into the conference, there is total of 3 participants: - * the local participant (or local user), and two remote participants that were the destinations of the two previously establised calls. - * - * @return the number of participants to the conference -**/ -int linphone_core_get_conference_size(LinphoneCore *lc) { - LinphoneConference *conf=&lc->conf_ctx; - return linphone_conference_get_size(conf); -} - - -int linphone_core_start_conference_recording(LinphoneCore *lc, const char *path){ - LinphoneConference *conf=&lc->conf_ctx; - if (conf->conf == NULL) { - ms_warning("linphone_core_start_conference_recording(): no conference now."); - return -1; - } - if (conf->record_endpoint==NULL){ - conf->record_endpoint=ms_audio_endpoint_new_recorder(); - ms_audio_conference_add_member(conf->conf,conf->record_endpoint); - } - ms_audio_recorder_endpoint_start(conf->record_endpoint,path); - return 0; -} - -int linphone_core_stop_conference_recording(LinphoneCore *lc){ - LinphoneConference *conf=&lc->conf_ctx; - if (conf->conf == NULL) { - ms_warning("linphone_core_stop_conference_recording(): no conference now."); - return -1; - } - if (conf->record_endpoint==NULL){ - ms_warning("linphone_core_stop_conference_recording(): no record active."); - return -1; - } - ms_audio_recorder_endpoint_stop(conf->record_endpoint); - return 0; -} - -/** - * @} -**/ -