]> sjero.net Git - linphone/blob - coreapi/conference.c
Merge branch 'dev_conference'
[linphone] / coreapi / conference.c
1 /***************************************************************************
2  *            conference.c
3  *
4  *  Mon Sep 12, 2011
5  *  Copyright  2011  Belledonne Communications
6  *  Author: Simon Morlat
7  *  Email simon dot morlat at linphone dot org
8  ****************************************************************************/
9
10 /*
11  *  This program is free software; you can redistribute it and/or modify
12  *  it under the terms of the GNU General Public License as published by
13  *  the Free Software Foundation; either version 2 of the License, or
14  *  (at your option) any later version.
15  *
16  *  This program is distributed in the hope that it will be useful,
17  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  *  GNU General Public License for more details.
20  *
21  *  You should have received a copy of the GNU General Public License
22  *  along with this program; if not, write to the Free Software
23  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24  */
25  
26 #include "private.h"
27
28
29 static void conference_check_init(LinphoneConference *ctx){
30         if (ctx->conf==NULL){
31                 ctx->conf=ms_audio_conference_new();
32         }
33 }
34
35 static void remove_local_endpoint(LinphoneConference *ctx){
36         if (ctx->local_endpoint){
37                 ms_audio_conference_remove_member(ctx->conf,ctx->local_endpoint);
38                 ms_audio_endpoint_release_from_stream(ctx->local_endpoint);
39                 ctx->local_endpoint=NULL;
40                 audio_stream_stop(ctx->local_participant);
41                 ctx->local_participant=NULL;
42         }
43 }
44
45 static void conference_check_uninit(LinphoneConference *ctx){
46         if (ctx->conf){
47                 if (ctx->conf->nmembers==0){
48                         remove_local_endpoint(ctx);
49                         ms_audio_conference_destroy(ctx->conf);
50                         ctx->conf=NULL;
51                 }
52         }
53 }
54
55
56 void linphone_call_add_to_conf(LinphoneCall *call){
57         LinphoneCore *lc=call->core;
58         LinphoneConference *conf=&lc->conf_ctx;
59         MSAudioEndpoint *ep;
60         ep=ms_audio_endpoint_get_from_stream(call->audiostream,TRUE);
61         ms_audio_conference_add_member(conf->conf,ep);
62         call->endpoint=ep;
63 }
64
65 void linphone_call_remove_from_conf(LinphoneCall *call){
66         LinphoneCore *lc=call->core;
67         LinphoneConference *conf=&lc->conf_ctx;
68         
69         ms_audio_conference_remove_member(conf->conf,call->endpoint);
70         ms_audio_endpoint_release_from_stream(call->endpoint);
71         call->endpoint=NULL;
72         conference_check_uninit(conf);
73 }
74
75 static void add_local_endpoint(LinphoneConference *conf,LinphoneCore *lc){
76         /*create a dummy audiostream in order to extract the local part of it */
77         /* network address and ports have no meaning and are not used here. */
78         AudioStream *st=audio_stream_new(65000,FALSE);
79         MSSndCard *playcard=lc->sound_conf.lsd_card ? 
80                         lc->sound_conf.lsd_card : lc->sound_conf.play_sndcard;
81         MSSndCard *captcard=lc->sound_conf.capt_sndcard;
82         
83         audio_stream_start_full(st, &av_profile,
84                                 "127.0.0.1",
85                                 65000,
86                                 65001,
87                                 0,
88                                 40,
89                                 NULL,
90                                 NULL,
91                                 playcard,
92                                 captcard,
93                                 linphone_core_echo_cancellation_enabled(lc)
94                                 );
95         _post_configure_audio_stream(st,lc,FALSE);
96         conf->local_participant=st;
97         conf->local_endpoint=ms_audio_endpoint_get_from_stream(st,FALSE);
98         ms_audio_conference_add_member(conf->conf,conf->local_endpoint);
99 }
100
101 int linphone_core_add_to_conference(LinphoneCore *lc, LinphoneCall *call){
102         LinphoneCallParams params;
103         LinphoneConference *conf=&lc->conf_ctx;
104         
105         if (call->current_params.in_conference){
106                 ms_error("Already in conference");
107                 return -1;
108         }
109         conference_check_init(&lc->conf_ctx);
110         call->params.in_conference=TRUE;
111         call->params.has_video=FALSE;
112         params=call->params;
113         if (call->state==LinphoneCallPaused)
114                 linphone_core_resume_call(lc,call);
115         else if (call->state==LinphoneCallStreamsRunning){
116                 /*this will trigger a reINVITE that will later redraw the streams */
117                 if (call->audiostream || call->videostream)
118                         linphone_call_stop_media_streams (call); /*free the audio & video local resources*/
119                 linphone_core_update_call(lc,call,&params);
120                 add_local_endpoint(conf,lc);
121         }else{
122                 ms_error("Call is in state %s, it cannot be added to the conference.",linphone_call_state_to_string(call->state));
123                 return -1;
124         }
125         return 0;
126 }
127
128 int linphone_core_remove_from_conference(LinphoneCore *lc, LinphoneCall *call){
129         if (!call->current_params.in_conference){
130                 if (call->params.in_conference){
131                         ms_warning("Not (yet) in conference, be patient");
132                         return -1;
133                 }else{
134                         ms_error("Not in a conference.");
135                         return -1;
136                 }
137         }
138         call->params.in_conference=FALSE;
139         return linphone_core_pause_call(lc,call);
140 }
141
142 bool_t linphone_core_is_in_conference(const LinphoneCore *lc){
143         return lc->conf_ctx.local_participant!=NULL;
144 }
145
146 int linphone_core_leave_conference(LinphoneCore *lc){
147         LinphoneConference *conf=&lc->conf_ctx;
148         if (linphone_core_is_in_conference(lc))
149                 remove_local_endpoint(conf);
150         return 0;
151 }
152
153
154 int linphone_core_enter_conference(LinphoneCore *lc){
155         LinphoneConference *conf=&lc->conf_ctx;
156         if (conf->local_participant==NULL) add_local_endpoint(conf,lc);
157         return 0;
158 }
159
160 int linphone_core_add_all_to_conference(LinphoneCore *lc) {return 0;}
161 int linphone_core_terminate_conference(LinphoneCore *lc) {return 0;}
162 int linphone_core_get_conference_size(LinphoneCore *lc) {return 0;}