mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-05-07 05:53:06 +00:00
add new method to create a conference from a list of participants.
This commit is contained in:
parent
8633c5b8b5
commit
3b0a9c0048
5 changed files with 158 additions and 31 deletions
|
|
@ -33,6 +33,15 @@
|
|||
|
||||
namespace Linphone {
|
||||
|
||||
template <typename _type>
|
||||
inline std::list<_type> toStd(const bctbx_list_t *l){
|
||||
std::list<_type> ret;
|
||||
for(; l != NULL; l = l->next){
|
||||
ret.push_back(static_cast<_type>(l->data));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
class Conference {
|
||||
public:
|
||||
class Participant {
|
||||
|
|
@ -82,7 +91,7 @@ public:
|
|||
void enableVideo(bool enable) {m_enableVideo = enable;}
|
||||
bool videoRequested() const {return m_enableVideo;}
|
||||
void setStateChangedCallback(LinphoneConferenceStateChangedCb cb, void *userData) {
|
||||
m_stateChangedCb =cb;
|
||||
m_stateChangedCb = cb;
|
||||
m_userData = userData;
|
||||
}
|
||||
|
||||
|
|
@ -99,6 +108,7 @@ public:
|
|||
|
||||
const Params &getCurrentParams() const {return m_currentParams;}
|
||||
|
||||
virtual int inviteAddresses(const std::list<const LinphoneAddress*> &addresses, const LinphoneCallParams *params) = 0;
|
||||
virtual int addParticipant(LinphoneCall *call) = 0;
|
||||
virtual int removeParticipant(LinphoneCall *call) = 0;
|
||||
virtual int removeParticipant(const LinphoneAddress *uri) = 0;
|
||||
|
|
@ -124,6 +134,9 @@ public:
|
|||
virtual void onCallTerminating(LinphoneCall *call) {};
|
||||
|
||||
LinphoneConferenceState getState() const {return m_state;}
|
||||
LinphoneCore *getCore()const{
|
||||
return m_core;
|
||||
}
|
||||
static const char *stateToString(LinphoneConferenceState state);
|
||||
|
||||
protected:
|
||||
|
|
@ -146,6 +159,7 @@ public:
|
|||
LocalConference(LinphoneCore *core, LinphoneConference *conf, const Params *params = NULL);
|
||||
virtual ~LocalConference();
|
||||
|
||||
virtual int inviteAddresses(const std::list<const LinphoneAddress*> &addresses, const LinphoneCallParams *params);
|
||||
virtual int addParticipant(LinphoneCall *call);
|
||||
virtual int removeParticipant(LinphoneCall *call);
|
||||
virtual int removeParticipant(const LinphoneAddress *uri);
|
||||
|
|
@ -183,6 +197,7 @@ public:
|
|||
RemoteConference(LinphoneCore *core, LinphoneConference *conf, const Params *params = NULL);
|
||||
virtual ~RemoteConference();
|
||||
|
||||
virtual int inviteAddresses(const std::list<const LinphoneAddress*> &addresses, const LinphoneCallParams *params);
|
||||
virtual int addParticipant(LinphoneCall *call);
|
||||
virtual int removeParticipant(LinphoneCall *call) {return -1;}
|
||||
virtual int removeParticipant(const LinphoneAddress *uri);
|
||||
|
|
@ -382,6 +397,31 @@ void LocalConference::addLocalEndpoint() {
|
|||
ms_audio_conference_add_member(m_conf,m_localEndpoint);
|
||||
}
|
||||
|
||||
int LocalConference::inviteAddresses(const std::list<const LinphoneAddress*> &addresses, const LinphoneCallParams *params){
|
||||
|
||||
for (auto it = addresses.begin(); it != addresses.end(); ++it){
|
||||
const LinphoneAddress *addr = *it;
|
||||
LinphoneCall * call = linphone_core_get_call_by_remote_address2(m_core, addr);
|
||||
if (!call){
|
||||
/*start a new call by indicating that it has to be put into the conference directlly*/
|
||||
LinphoneCallParams * new_params = params ? linphone_call_params_copy(params) : linphone_core_create_call_params(m_core, NULL);
|
||||
LinphoneCall *call;
|
||||
/*toggle this flag so the call is immediately added to the conference upon acceptance*/
|
||||
new_params->in_conference = TRUE;
|
||||
call = linphone_core_invite_address_with_params(m_core, addr, new_params);
|
||||
if (!call){
|
||||
ms_error("LocalConference::inviteAddresses(): could not invite participant");
|
||||
}
|
||||
linphone_call_params_unref(new_params);
|
||||
}else{
|
||||
/*there is already a call to this address, so simply join it to the local conference if not already done*/
|
||||
if (!call->current_params->in_conference)
|
||||
addParticipant(call);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int LocalConference::addParticipant(LinphoneCall *call) {
|
||||
if (call->current_params->in_conference){
|
||||
ms_error("Already in conference");
|
||||
|
|
@ -590,6 +630,7 @@ int LocalConference::stopRecording() {
|
|||
void LocalConference::onCallStreamStarting(LinphoneCall *call, bool isPausedByRemote) {
|
||||
call->params->has_video = FALSE;
|
||||
call->camera_enabled = FALSE;
|
||||
ms_message("LocalConference::onCallStreamStarting(): joining AudioStream [%p] of call [%p] into conference.", call->audiostream, call);
|
||||
MSAudioEndpoint *ep=ms_audio_endpoint_get_from_stream(call->audiostream,TRUE);
|
||||
ms_audio_conference_add_member(m_conf,ep);
|
||||
ms_audio_conference_mute_member(m_conf,ep,isPausedByRemote);
|
||||
|
|
@ -643,6 +684,11 @@ RemoteConference::~RemoteConference() {
|
|||
linphone_core_cbs_unref(m_coreCbs);
|
||||
}
|
||||
|
||||
int RemoteConference::inviteAddresses(const std::list<const LinphoneAddress *> &addresses, const LinphoneCallParams *params){
|
||||
ms_error("RemoteConference::inviteAddresses() not implemented");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int RemoteConference::addParticipant(LinphoneCall *call) {
|
||||
LinphoneAddress *addr;
|
||||
LinphoneCallParams *params;
|
||||
|
|
@ -1116,3 +1162,7 @@ bool_t linphone_conference_check_class(LinphoneConference *obj, LinphoneConferen
|
|||
default: return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
LinphoneStatus linphone_conference_invite_participants(LinphoneConference *obj, const bctbx_list_t *addresses, const LinphoneCallParams *params){
|
||||
return obj->conf->inviteAddresses(toStd<const LinphoneAddress*>(addresses), params);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3471,8 +3471,11 @@ LinphoneCall * linphone_core_invite_address_with_params(LinphoneCore *lc, const
|
|||
bool_t defer = FALSE;
|
||||
LinphoneCallParams *cp;
|
||||
|
||||
if (!(!linphone_call_params_audio_enabled(params) || linphone_call_params_get_audio_direction(params) == LinphoneMediaDirectionInactive)
|
||||
&& linphone_core_preempt_sound_resources(lc) == -1){
|
||||
if (!(!linphone_call_params_audio_enabled(params) ||
|
||||
linphone_call_params_get_audio_direction(params) == LinphoneMediaDirectionInactive ||
|
||||
linphone_call_params_get_local_conference_mode(params) == TRUE
|
||||
)
|
||||
&& linphone_core_preempt_sound_resources(lc) == -1) {
|
||||
ms_error("linphone_core_invite_address_with_params(): sound is required for this call but another call is already locking the sound resource. Call attempt is rejected.");
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -3776,7 +3779,7 @@ static int remote_address_compare(LinphoneCall *call, const LinphoneAddress *rad
|
|||
return !linphone_address_weak_equal (addr,raddr);
|
||||
}
|
||||
|
||||
LinphoneCall *linphone_core_get_call_by_remote_address(LinphoneCore *lc, const char *remote_address){
|
||||
LinphoneCall *linphone_core_get_call_by_remote_address(const LinphoneCore *lc, const char *remote_address){
|
||||
LinphoneCall *call=NULL;
|
||||
LinphoneAddress *raddr=linphone_address_new(remote_address);
|
||||
if (raddr) {
|
||||
|
|
@ -3786,8 +3789,12 @@ LinphoneCall *linphone_core_get_call_by_remote_address(LinphoneCore *lc, const c
|
|||
return call;
|
||||
}
|
||||
|
||||
LinphoneCall *linphone_core_get_call_by_remote_address2(LinphoneCore *lc, const LinphoneAddress *raddr){
|
||||
bctbx_list_t *elem=bctbx_list_find_custom(lc->calls,(int (*)(const void*,const void *))remote_address_compare,raddr);
|
||||
LinphoneCall *linphone_core_find_call_from_uri(const LinphoneCore *lc, const char *remote_address){
|
||||
return linphone_core_get_call_by_remote_address(lc, remote_address);
|
||||
}
|
||||
|
||||
LinphoneCall *linphone_core_get_call_by_remote_address2(const LinphoneCore *lc, const LinphoneAddress *raddr){
|
||||
const bctbx_list_t *elem=bctbx_list_find_custom(lc->calls,(int (*)(const void*,const void *))remote_address_compare,raddr);
|
||||
|
||||
if (elem) return (LinphoneCall*) elem->data;
|
||||
return NULL;
|
||||
|
|
@ -6580,29 +6587,6 @@ const char *linphone_core_get_user_certificates_path(LinphoneCore *lc){
|
|||
return lc->user_certificates_path;
|
||||
}
|
||||
|
||||
LinphoneCall* linphone_core_find_call_from_uri(const LinphoneCore *lc, const char *uri) {
|
||||
bctbx_list_t *calls;
|
||||
LinphoneCall *c;
|
||||
const LinphoneAddress *address;
|
||||
char *current_uri;
|
||||
|
||||
if (uri == NULL) return NULL;
|
||||
calls=lc->calls;
|
||||
while(calls) {
|
||||
c=(LinphoneCall*)calls->data;
|
||||
calls=calls->next;
|
||||
address = linphone_call_get_remote_address(c);
|
||||
current_uri=linphone_address_as_string_uri_only(address);
|
||||
if (strcmp(uri,current_uri)==0) {
|
||||
ms_free(current_uri);
|
||||
return c;
|
||||
} else {
|
||||
ms_free(current_uri);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool_t linphone_core_sound_resources_locked(LinphoneCore *lc){
|
||||
bctbx_list_t *elem;
|
||||
for(elem=lc->calls;elem!=NULL;elem=elem->next) {
|
||||
|
|
@ -7068,6 +7052,10 @@ LinphoneConference *linphone_core_create_conference_with_params(LinphoneCore *lc
|
|||
return lc->conf_ctx;
|
||||
}
|
||||
|
||||
LinphoneConferenceParams * linphone_core_create_conference_params(LinphoneCore *lc){
|
||||
return linphone_conference_params_new(lc);
|
||||
}
|
||||
|
||||
LinphoneStatus linphone_core_add_to_conference(LinphoneCore *lc, LinphoneCall *call) {
|
||||
LinphoneConference *conference = linphone_core_get_conference(lc);
|
||||
if(conference == NULL) {
|
||||
|
|
|
|||
|
|
@ -117,6 +117,14 @@ LINPHONE_PUBLIC LinphoneStatus linphone_conference_remove_participant(LinphoneCo
|
|||
*/
|
||||
LINPHONE_PUBLIC bctbx_list_t *linphone_conference_get_participants(const LinphoneConference *obj);
|
||||
|
||||
/**
|
||||
* Invite participants to the conference, by supplying a list of LinphoneAddress
|
||||
* @param obj The conference.
|
||||
* @param addresses bctbx_list_t of #LinphoneAddress object
|
||||
* @param params #LinphoneCallParams to use for inviting the participants.
|
||||
**/
|
||||
LINPHONE_PUBLIC LinphoneStatus linphone_conference_invite_participants(LinphoneConference *conf, const bctbx_list_t *addresses, const LinphoneCallParams *params);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1300,7 +1300,7 @@ LINPHONE_PUBLIC LinphoneCallParams *linphone_core_create_call_params(LinphoneCor
|
|||
* @return The call if it has been found, NULL otherwise
|
||||
* @ingroup call_control
|
||||
*/
|
||||
LINPHONE_PUBLIC LinphoneCall *linphone_core_get_call_by_remote_address(LinphoneCore *lc, const char *remote_address);
|
||||
LINPHONE_PUBLIC LinphoneCall *linphone_core_get_call_by_remote_address(const LinphoneCore *lc, const char *remote_address);
|
||||
|
||||
/**
|
||||
* Get the call with the remote_address specified
|
||||
|
|
@ -1310,7 +1310,7 @@ LINPHONE_PUBLIC LinphoneCall *linphone_core_get_call_by_remote_address(LinphoneC
|
|||
*
|
||||
* @ingroup call_control
|
||||
*/
|
||||
LINPHONE_PUBLIC LinphoneCall *linphone_core_get_call_by_remote_address2(LinphoneCore *lc, const LinphoneAddress *remote_address);
|
||||
LINPHONE_PUBLIC LinphoneCall *linphone_core_get_call_by_remote_address2(const LinphoneCore *lc, const LinphoneAddress *remote_address);
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -4013,6 +4013,14 @@ LINPHONE_PUBLIC LinphoneCall* linphone_core_find_call_from_uri(const LinphoneCor
|
|||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create some default conference parameters for instanciating a a conference with linphone_core_create_conference_with_params().
|
||||
* @param lc the core
|
||||
* @return conference parameters.
|
||||
**/
|
||||
LINPHONE_PUBLIC LinphoneConferenceParams * linphone_core_create_conference_params(LinphoneCore *lc);
|
||||
|
||||
|
||||
/**
|
||||
* Create a conference
|
||||
* @param lc The #LinphoneCore instance where the conference will be created inside.
|
||||
|
|
@ -4022,6 +4030,7 @@ LINPHONE_PUBLIC LinphoneCall* linphone_core_find_call_from_uri(const LinphoneCor
|
|||
*/
|
||||
LINPHONE_PUBLIC LinphoneConference *linphone_core_create_conference_with_params(LinphoneCore *lc, const LinphoneConferenceParams *params);
|
||||
|
||||
|
||||
/**
|
||||
* Add a participant to the conference. If no conference is going on
|
||||
* a new internal conference context is created and the participant is
|
||||
|
|
|
|||
|
|
@ -381,6 +381,77 @@ static void simple_conference(void) {
|
|||
linphone_core_manager_destroy(laure);
|
||||
}
|
||||
|
||||
|
||||
static void simple_conference_from_scratch(void){
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc");
|
||||
LinphoneCoreManager* laure = linphone_core_manager_new( "laure_rc_udp");
|
||||
LinphoneConference *conf;
|
||||
LinphoneConferenceParams *conf_params;
|
||||
LinphoneCall *pauline_call, *laure_call;
|
||||
bctbx_list_t *participants = NULL;
|
||||
bctbx_list_t *lcs = NULL;
|
||||
|
||||
lcs = bctbx_list_append(lcs, marie->lc);
|
||||
lcs = bctbx_list_append(lcs, pauline->lc);
|
||||
lcs = bctbx_list_append(lcs, laure->lc);
|
||||
|
||||
/*marie creates the conference*/
|
||||
conf_params = linphone_core_create_conference_params(marie->lc);
|
||||
linphone_conference_params_enable_video(conf_params, FALSE);
|
||||
conf = linphone_core_create_conference_with_params(marie->lc, conf_params);
|
||||
linphone_conference_params_unref(conf_params);
|
||||
|
||||
participants = bctbx_list_append(participants, pauline->identity);
|
||||
participants = bctbx_list_append(participants, laure->identity);
|
||||
|
||||
linphone_conference_invite_participants(conf, participants, NULL);
|
||||
|
||||
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallOutgoingProgress,2,2000));
|
||||
BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallIncomingReceived,1,10000));
|
||||
BC_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallIncomingReceived,1,10000));
|
||||
|
||||
pauline_call = linphone_core_get_current_call(pauline->lc);
|
||||
laure_call = linphone_core_get_current_call(laure->lc);
|
||||
|
||||
BC_ASSERT_PTR_NOT_NULL(pauline_call);
|
||||
BC_ASSERT_PTR_NOT_NULL(laure_call);
|
||||
|
||||
if (pauline_call && laure_call){
|
||||
const bctbx_list_t *marie_calls, *it;
|
||||
linphone_call_accept(pauline_call);
|
||||
linphone_call_accept(laure_call);
|
||||
|
||||
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallConnected,2,10000));
|
||||
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallStreamsRunning,2,3000));
|
||||
|
||||
/*make sure that the two calls from Marie's standpoint are in conference*/
|
||||
marie_calls = linphone_core_get_calls(marie->lc);
|
||||
BC_ASSERT_EQUAL(bctbx_list_size(marie_calls), 2, int, "%i");
|
||||
for (it = marie_calls; it != NULL; it = it->next){
|
||||
BC_ASSERT_TRUE(linphone_call_params_get_local_conference_mode(linphone_call_get_current_params((LinphoneCall*)it->data)) == TRUE);
|
||||
}
|
||||
/*wait a bit for the conference audio processing to run, despite we do not test it for the moment*/
|
||||
wait_for_list(lcs,NULL,0,5000);
|
||||
|
||||
linphone_core_terminate_conference(marie->lc);
|
||||
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,2,5000));
|
||||
BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,10000));
|
||||
BC_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallEnd,1,10000));
|
||||
|
||||
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallReleased,2,1000));
|
||||
BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallReleased,1,1000));
|
||||
BC_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallReleased,1,1000));
|
||||
}
|
||||
|
||||
linphone_core_manager_destroy(marie);
|
||||
linphone_core_manager_destroy(pauline);
|
||||
linphone_core_manager_destroy(laure);
|
||||
|
||||
bctbx_list_free(participants);
|
||||
bctbx_list_free(lcs);
|
||||
}
|
||||
|
||||
static void simple_encrypted_conference_with_ice(LinphoneMediaEncryption mode) {
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc");
|
||||
|
|
@ -1074,6 +1145,7 @@ test_t multi_call_tests[] = {
|
|||
TEST_NO_TAG("Incoming call accepted when outgoing call in outgoing ringing", incoming_call_accepted_when_outgoing_call_in_outgoing_ringing),
|
||||
TEST_NO_TAG("Incoming call accepted when outgoing call in outgoing ringing early media", incoming_call_accepted_when_outgoing_call_in_outgoing_ringing_early_media),
|
||||
TEST_NO_TAG("Simple conference", simple_conference),
|
||||
TEST_NO_TAG("Simple conference established from scractch", simple_conference_from_scratch),
|
||||
TEST_ONE_TAG("Simple conference with ICE", simple_conference_with_ice, "ICE"),
|
||||
TEST_ONE_TAG("Simple ZRTP conference with ICE", simple_zrtp_conference_with_ice, "ICE"),
|
||||
TEST_NO_TAG("Eject from 3 participants conference", eject_from_3_participants_local_conference),
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue