mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-02-07 14:18:25 +00:00
Merge branch 'dev_refactor_cpp' into dev_chatroom_list_subscription
This commit is contained in:
commit
1394899408
58 changed files with 1082 additions and 292 deletions
|
|
@ -975,7 +975,7 @@ linphonec_idle_call ()
|
|||
linphone_core_iterate(opm);
|
||||
if (answer_call){
|
||||
fprintf (stdout, "-------auto answering to call-------\n" );
|
||||
linphone_core_accept_call(opm,NULL);
|
||||
linphone_core_accept_call(opm, linphone_core_get_current_call(opm));
|
||||
answer_call=FALSE;
|
||||
}
|
||||
/* auto call handling */
|
||||
|
|
|
|||
|
|
@ -156,11 +156,11 @@ static char *argv_to_line(int argc, char *argv[]) {
|
|||
}
|
||||
#endif
|
||||
|
||||
#define MAX_ARGS 10
|
||||
#define MAX_ARGS 20
|
||||
|
||||
#ifndef _WIN32
|
||||
static void spawn_linphonec(int argc, char *argv[]){
|
||||
char * args[MAX_ARGS];
|
||||
char * args[MAX_ARGS+1];
|
||||
int i,j;
|
||||
pid_t pid;
|
||||
j=0;
|
||||
|
|
@ -168,10 +168,10 @@ static void spawn_linphonec(int argc, char *argv[]){
|
|||
args[j++]="--pipe";
|
||||
args[j++]="-c";
|
||||
args[j++]="/dev/null";
|
||||
for(i=0;i<argc;++i){
|
||||
for(i=0;i<argc && i<MAX_ARGS;++i){
|
||||
args[j++]=argv[i];
|
||||
}
|
||||
args[j++]=NULL;
|
||||
args[j]=NULL;
|
||||
|
||||
#ifdef __uClinux__
|
||||
pid = vfork();
|
||||
|
|
|
|||
|
|
@ -256,7 +256,9 @@ static void call_terminated(SalOp *op, const char *from) {
|
|||
}
|
||||
|
||||
static void call_failure(SalOp *op) {
|
||||
std::shared_ptr<LinphonePrivate::CallSession> session = reinterpret_cast<LinphonePrivate::CallSession *>(op->get_user_pointer())->getSharedFromThis();
|
||||
shared_ptr<LinphonePrivate::CallSession> session;
|
||||
if (op->get_user_pointer())
|
||||
session = reinterpret_cast<LinphonePrivate::CallSession *>(op->get_user_pointer())->getSharedFromThis();
|
||||
if (!session) {
|
||||
ms_warning("Failure reported on already terminated CallSession");
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -3437,11 +3437,16 @@ LinphoneCall * linphone_core_start_refered_call(LinphoneCore *lc, LinphoneCall *
|
|||
system.
|
||||
*/
|
||||
static bctbx_list_t *make_routes_for_proxy(LinphoneProxyConfig *proxy, const LinphoneAddress *dest){
|
||||
bctbx_list_t *ret=NULL;
|
||||
const char *local_route=linphone_proxy_config_get_route(proxy);
|
||||
const LinphoneAddress *srv_route=linphone_proxy_config_get_service_route(proxy);
|
||||
if (local_route){
|
||||
ret=bctbx_list_append(ret,sal_address_new(local_route));
|
||||
bctbx_list_t *ret = NULL;
|
||||
const bctbx_list_t *proxy_routes = linphone_proxy_config_get_routes(proxy);
|
||||
bctbx_list_t *proxy_routes_iterator = (bctbx_list_t *)proxy_routes;
|
||||
const LinphoneAddress *srv_route = linphone_proxy_config_get_service_route(proxy);
|
||||
while (proxy_routes_iterator) {
|
||||
const char *local_route = (const char *)bctbx_list_get_data(proxy_routes_iterator);
|
||||
if (local_route) {
|
||||
ret = bctbx_list_append(ret, sal_address_new(local_route));
|
||||
}
|
||||
proxy_routes_iterator = bctbx_list_next(proxy_routes_iterator);
|
||||
}
|
||||
if (srv_route){
|
||||
ret=bctbx_list_append(ret,sal_address_clone(L_GET_PRIVATE_FROM_C_OBJECT(srv_route)->getInternalAddress()));
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ void linphone_call_notify_transfer_state_changed(LinphoneCall *call, LinphoneCal
|
|||
void linphone_call_notify_stats_updated(LinphoneCall *call, const LinphoneCallStats *stats);
|
||||
void linphone_call_notify_info_message_received(LinphoneCall *call, const LinphoneInfoMessage *msg);
|
||||
void linphone_call_notify_ack_processing(LinphoneCall *call, LinphoneHeaders *msg, bool_t is_received);
|
||||
void linphone_call_notify_tmmbr_received(LinphoneCall *call, int stream_index, int tmmbr);
|
||||
|
||||
LinphoneCall * linphone_call_new_outgoing(struct _LinphoneCore *lc, const LinphoneAddress *from, const LinphoneAddress *to, const LinphoneCallParams *params, LinphoneProxyConfig *cfg);
|
||||
LinphoneCall * linphone_call_new_incoming(struct _LinphoneCore *lc, const LinphoneAddress *from, const LinphoneAddress *to, LinphonePrivate::SalCallOp *op);
|
||||
|
|
@ -291,8 +292,10 @@ void _linphone_chat_room_notify_undecryptable_message_received(LinphoneChatRoom
|
|||
void _linphone_chat_room_notify_chat_message_received(LinphoneChatRoom *cr, const LinphoneEventLog *event_log);
|
||||
void _linphone_chat_room_notify_chat_message_sent(LinphoneChatRoom *cr, const LinphoneEventLog *event_log);
|
||||
void _linphone_chat_room_notify_conference_address_generation(LinphoneChatRoom *cr);
|
||||
void _linphone_chat_room_notify_participant_device_fetched(LinphoneChatRoom *cr, const LinphoneAddress *participantAddr);
|
||||
void _linphone_chat_room_notify_participant_device_fetch_requested(LinphoneChatRoom *cr, const LinphoneAddress *participantAddr);
|
||||
void _linphone_chat_room_notify_participants_capabilities_checked(LinphoneChatRoom *cr, const LinphoneAddress *deviceAddr, const bctbx_list_t *participantsAddr);
|
||||
void _linphone_chat_room_notify_participant_registration_subscription_requested(LinphoneChatRoom *cr, const LinphoneAddress *participantAddr);
|
||||
void _linphone_chat_room_notify_participant_registration_unsubscription_requested(LinphoneChatRoom *cr, const LinphoneAddress *participantAddr);
|
||||
void _linphone_chat_room_notify_chat_message_should_be_stored(LinphoneChatRoom *cr, LinphoneChatMessage *msg);
|
||||
void _linphone_chat_room_clear_callbacks (LinphoneChatRoom *cr);
|
||||
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ struct _LinphoneProxyConfig
|
|||
LinphoneAddress* identity_address;
|
||||
LinphoneAddress *contact_address;
|
||||
LinphoneAddress *contact_address_without_params;
|
||||
char *reg_route;
|
||||
bctbx_list_t *reg_routes;
|
||||
char *quality_reporting_collector;
|
||||
char *realm;
|
||||
char *contact_params;
|
||||
|
|
|
|||
104
coreapi/proxy.c
104
coreapi/proxy.c
|
|
@ -20,6 +20,7 @@ Copyright (C) 2000 Simon MORLAT (simon.morlat@linphone.org)
|
|||
|
||||
#include <ctype.h>
|
||||
|
||||
#include <bctoolbox/defs.h>
|
||||
#include "linphone/core_utils.h"
|
||||
#include "linphone/core.h"
|
||||
#include "linphone/lpconfig.h"
|
||||
|
|
@ -113,7 +114,7 @@ static void linphone_proxy_config_init(LinphoneCore* lc, LinphoneProxyConfig *cf
|
|||
const char *dial_prefix = lc ? lp_config_get_default_string(lc->config,"proxy","dial_prefix",NULL) : NULL;
|
||||
const char *identity = lc ? lp_config_get_default_string(lc->config, "proxy", "reg_identity", NULL) : NULL;
|
||||
const char *proxy = lc ? lp_config_get_default_string(lc->config, "proxy", "reg_proxy", NULL) : NULL;
|
||||
const char *route = lc ? lp_config_get_default_string(lc->config, "proxy", "reg_route", NULL) : NULL;
|
||||
const char *route = lc ? lp_config_get_default_string(lc->config, "proxy", "reg_route", NULL) : NULL; //TODO return list instead of string
|
||||
const char *realm = lc ? lp_config_get_default_string(lc->config, "proxy", "realm", NULL) : NULL;
|
||||
const char *quality_reporting_collector = lc ? lp_config_get_default_string(lc->config, "proxy", "quality_reporting_collector", NULL) : NULL;
|
||||
const char *contact_params = lc ? lp_config_get_default_string(lc->config, "proxy", "contact_parameters", NULL) : NULL;
|
||||
|
|
@ -130,7 +131,7 @@ static void linphone_proxy_config_init(LinphoneCore* lc, LinphoneProxyConfig *cf
|
|||
cfg->identity_address = identity ? linphone_address_new(identity) : NULL;
|
||||
cfg->reg_identity = cfg->identity_address ? linphone_address_as_string(cfg->identity_address) : NULL;
|
||||
cfg->reg_proxy = proxy ? ms_strdup(proxy) : NULL;
|
||||
cfg->reg_route = route ? ms_strdup(route) : NULL;
|
||||
cfg->reg_routes = route ? bctbx_list_append(cfg->reg_routes, ms_strdup(route)) : NULL; //TODO get list directly
|
||||
cfg->realm = realm ? ms_strdup(realm) : NULL;
|
||||
cfg->quality_reporting_enabled = lc ? !!lp_config_get_default_int(lc->config, "proxy", "quality_reporting_enabled", 0) : 0;
|
||||
cfg->quality_reporting_collector = quality_reporting_collector ? ms_strdup(quality_reporting_collector) : NULL;
|
||||
|
|
@ -183,13 +184,18 @@ bool_t linphone_proxy_config_compute_publish_params_hash(LinphoneProxyConfig * c
|
|||
char hash[33];
|
||||
char saved;
|
||||
unsigned long long previous_hash[2];
|
||||
bctbx_list_t *routes_iterator = cfg->reg_routes;
|
||||
previous_hash[0] = cfg->previous_publish_config_hash[0];
|
||||
previous_hash[1] = cfg->previous_publish_config_hash[1];
|
||||
|
||||
source = ms_strcat_printf(source, "%i",cfg->privacy);
|
||||
source=append_linphone_address(cfg->identity_address, source);
|
||||
source=append_string(cfg->reg_proxy,source);
|
||||
source=append_string(cfg->reg_route,source);
|
||||
while (routes_iterator) {
|
||||
const char *route = (const char *)bctbx_list_get_data(routes_iterator);
|
||||
source=append_string(route,source);
|
||||
routes_iterator = bctbx_list_next(routes_iterator);
|
||||
}
|
||||
source=append_string(cfg->realm,source);
|
||||
source = ms_strcat_printf(source, "%i",cfg->publish_expires);
|
||||
source = ms_strcat_printf(source, "%i",cfg->publish);
|
||||
|
|
@ -235,7 +241,7 @@ void _linphone_proxy_config_destroy(LinphoneProxyConfig *cfg){
|
|||
if (cfg->reg_proxy!=NULL) ms_free(cfg->reg_proxy);
|
||||
if (cfg->reg_identity!=NULL) ms_free(cfg->reg_identity);
|
||||
if (cfg->identity_address!=NULL) linphone_address_unref(cfg->identity_address);
|
||||
if (cfg->reg_route!=NULL) ms_free(cfg->reg_route);
|
||||
if (cfg->reg_routes!=NULL) bctbx_list_free_with_data(cfg->reg_routes, ms_free);
|
||||
if (cfg->quality_reporting_collector!=NULL) ms_free(cfg->quality_reporting_collector);
|
||||
if (cfg->ssctx!=NULL) sip_setup_context_free(cfg->ssctx);
|
||||
if (cfg->realm!=NULL) ms_free(cfg->realm);
|
||||
|
|
@ -348,9 +354,9 @@ const char *linphone_proxy_config_get_domain(const LinphoneProxyConfig *cfg){
|
|||
|
||||
LinphoneStatus linphone_proxy_config_set_route(LinphoneProxyConfig *cfg, const char *route)
|
||||
{
|
||||
if (cfg->reg_route!=NULL){
|
||||
ms_free(cfg->reg_route);
|
||||
cfg->reg_route=NULL;
|
||||
if (cfg->reg_routes != NULL) {
|
||||
bctbx_list_free_with_data(cfg->reg_routes, ms_free);
|
||||
cfg->reg_routes = NULL;
|
||||
}
|
||||
if (route!=NULL && route[0] !='\0'){
|
||||
SalAddress *addr;
|
||||
|
|
@ -362,7 +368,7 @@ LinphoneStatus linphone_proxy_config_set_route(LinphoneProxyConfig *cfg, const c
|
|||
addr=sal_address_new(tmp);
|
||||
if (addr!=NULL){
|
||||
sal_address_destroy(addr);
|
||||
cfg->reg_route=tmp;
|
||||
cfg->reg_routes = bctbx_list_append(cfg->reg_routes, tmp);
|
||||
return 0;
|
||||
}else{
|
||||
ms_free(tmp);
|
||||
|
|
@ -373,6 +379,37 @@ LinphoneStatus linphone_proxy_config_set_route(LinphoneProxyConfig *cfg, const c
|
|||
}
|
||||
}
|
||||
|
||||
LinphoneStatus linphone_proxy_config_set_routes(LinphoneProxyConfig *cfg, const bctbx_list_t *routes) {
|
||||
if (cfg->reg_routes != NULL) {
|
||||
bctbx_list_free_with_data(cfg->reg_routes, ms_free);
|
||||
cfg->reg_routes = NULL;
|
||||
}
|
||||
bctbx_list_t *iterator = (bctbx_list_t *)routes;
|
||||
while (iterator != NULL) {
|
||||
char *route = (char *)bctbx_list_get_data(iterator);
|
||||
if (route != NULL && route[0] !='\0') {
|
||||
SalAddress *addr;
|
||||
char *tmp;
|
||||
/*try to prepend 'sip:' */
|
||||
if (strstr(route,"sip:") == NULL && strstr(route,"sips:") == NULL) {
|
||||
tmp = ms_strdup_printf("sip:%s",route);
|
||||
} else {
|
||||
tmp = ms_strdup(route);
|
||||
}
|
||||
addr = sal_address_new(tmp);
|
||||
if (addr != NULL) {
|
||||
sal_address_destroy(addr);
|
||||
cfg->reg_routes = bctbx_list_append(cfg->reg_routes, tmp);
|
||||
} else {
|
||||
ms_free(tmp);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
iterator = bctbx_list_next(iterator);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool_t linphone_proxy_config_check(LinphoneCore *lc, LinphoneProxyConfig *cfg){
|
||||
if (cfg->reg_proxy==NULL)
|
||||
return FALSE;
|
||||
|
|
@ -790,6 +827,13 @@ LinphoneAddress* linphone_proxy_config_normalize_sip_uri(LinphoneProxyConfig *pr
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void linphone_proxy_config_set_etag(LinphoneProxyConfig *cfg,const char* sip_etag) {
|
||||
if (cfg->sip_etag) ms_free(cfg->sip_etag);
|
||||
if (sip_etag)
|
||||
cfg->sip_etag = ms_strdup(sip_etag);
|
||||
else
|
||||
cfg->sip_etag = NULL;
|
||||
}
|
||||
/**
|
||||
* Commits modification made to the proxy configuration.
|
||||
**/
|
||||
|
|
@ -831,11 +875,7 @@ LinphoneStatus linphone_proxy_config_done(LinphoneProxyConfig *cfg)
|
|||
ms_message("Publish params have changed on proxy config [%p]",cfg);
|
||||
if (cfg->presence_publish_event) {
|
||||
if (cfg->publish) {
|
||||
const char * sip_etag = linphone_event_get_custom_header(cfg->presence_publish_event, "SIP-ETag");
|
||||
if (sip_etag) {
|
||||
if (cfg->sip_etag) ms_free(cfg->sip_etag);
|
||||
cfg->sip_etag = ms_strdup(sip_etag);
|
||||
}
|
||||
linphone_proxy_config_set_etag(cfg, linphone_event_get_custom_header(cfg->presence_publish_event, "SIP-ETag"));
|
||||
}
|
||||
/*publish is terminated*/
|
||||
linphone_event_terminate(cfg->presence_publish_event);
|
||||
|
|
@ -934,8 +974,13 @@ void _linphone_proxy_config_unpublish(LinphoneProxyConfig *obj) {
|
|||
}
|
||||
}
|
||||
|
||||
const char *linphone_proxy_config_get_route(const LinphoneProxyConfig *cfg){
|
||||
return cfg->reg_route;
|
||||
const char *linphone_proxy_config_get_route(const LinphoneProxyConfig *cfg) {
|
||||
if (cfg->reg_routes) return (const char *)bctbx_list_get_data(cfg->reg_routes);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const bctbx_list_t* linphone_proxy_config_get_routes(const LinphoneProxyConfig *cfg) {
|
||||
return cfg->reg_routes;
|
||||
}
|
||||
|
||||
const LinphoneAddress *linphone_proxy_config_get_identity_address(const LinphoneProxyConfig *cfg){
|
||||
|
|
@ -1116,8 +1161,8 @@ void linphone_proxy_config_write_to_config_file(LpConfig *config, LinphoneProxyC
|
|||
if (cfg->reg_proxy!=NULL){
|
||||
lp_config_set_string(config,key,"reg_proxy",cfg->reg_proxy);
|
||||
}
|
||||
if (cfg->reg_route!=NULL){
|
||||
lp_config_set_string(config,key,"reg_route",cfg->reg_route);
|
||||
if (cfg->reg_routes != NULL) {
|
||||
lp_config_set_string_list(config, key, "reg_route", cfg->reg_routes);
|
||||
}
|
||||
if (cfg->reg_identity!=NULL){
|
||||
lp_config_set_string(config,key,"reg_identity",cfg->reg_identity);
|
||||
|
|
@ -1187,7 +1232,10 @@ LinphoneProxyConfig *linphone_proxy_config_new_from_config_file(LinphoneCore* lc
|
|||
|
||||
CONFIGURE_STRING_VALUE(cfg,config,key,identity,"reg_identity")
|
||||
CONFIGURE_STRING_VALUE(cfg,config,key,server_addr,"reg_proxy")
|
||||
CONFIGURE_STRING_VALUE(cfg,config,key,route,"reg_route")
|
||||
bctbx_list_t *routes = linphone_config_get_string_list(config, key, "reg_route", NULL);
|
||||
linphone_proxy_config_set_routes(cfg, routes);
|
||||
if (routes)
|
||||
bctbx_list_free_with_data(routes, (bctbx_list_free_func)bctbx_free);
|
||||
|
||||
CONFIGURE_STRING_VALUE(cfg,config,key,realm,"realm")
|
||||
|
||||
|
|
@ -1498,9 +1546,23 @@ void linphone_proxy_config_set_nat_policy(LinphoneProxyConfig *cfg, LinphoneNatP
|
|||
}
|
||||
|
||||
void linphone_proxy_config_notify_publish_state_changed(LinphoneProxyConfig *cfg, LinphonePublishState state) {
|
||||
if ((cfg->presence_publish_event != NULL) && ((state == LinphonePublishCleared) || (state == LinphonePublishError))) {
|
||||
linphone_event_unref(cfg->presence_publish_event);
|
||||
cfg->presence_publish_event = NULL;
|
||||
|
||||
if (cfg->presence_publish_event != NULL) {
|
||||
switch (state) {
|
||||
case LinphonePublishCleared:
|
||||
linphone_proxy_config_set_etag(cfg,NULL);
|
||||
BCTBX_NO_BREAK;
|
||||
case LinphonePublishError:
|
||||
linphone_event_unref(cfg->presence_publish_event);
|
||||
cfg->presence_publish_event = NULL;
|
||||
break;
|
||||
case LinphonePublishOk:
|
||||
linphone_proxy_config_set_etag(cfg,linphone_event_get_custom_header(cfg->presence_publish_event, "SIP-ETag"));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -159,6 +159,20 @@ LINPHONE_PUBLIC LinphoneCallCbsAckProcessingCb linphone_call_cbs_get_ack_process
|
|||
*/
|
||||
LINPHONE_PUBLIC void linphone_call_cbs_set_ack_processing (LinphoneCallCbs *cbs, LinphoneCallCbsAckProcessingCb cb);
|
||||
|
||||
/**
|
||||
* Get the TMMBR received callback.
|
||||
* @param[in] cbs LinphoneCallCbs object.
|
||||
* @return The current TMMBR received callback.
|
||||
*/
|
||||
LINPHONE_PUBLIC LinphoneCallCbsTmmbrReceivedCb linphone_call_cbs_get_tmmbr_received(LinphoneCallCbs *cbs);
|
||||
|
||||
/**
|
||||
* Set the TMMBR received callback.
|
||||
* @param[in] cbs LinphoneCallCbs object.
|
||||
* @param[in] cb The TMMBR received callback to be used.
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_call_cbs_set_tmmbr_received(LinphoneCallCbs *cbs, LinphoneCallCbsTmmbrReceivedCb cb);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -87,6 +87,14 @@ typedef void (*LinphoneCallCbsTransferStateChangedCb)(LinphoneCall *call, Linpho
|
|||
*/
|
||||
typedef void (*LinphoneCallCbsAckProcessingCb)(LinphoneCall *call, LinphoneHeaders *ack, bool_t is_received);
|
||||
|
||||
/**
|
||||
* Callback for notifying a received TMMBR.
|
||||
* @param call LinphoneCall for which the TMMBR has changed
|
||||
* @param stream_index the index of the current stream
|
||||
* @param tmmbr the value of the received TMMBR
|
||||
*/
|
||||
typedef void (*LinphoneCallCbsTmmbrReceivedCb)(LinphoneCall *call, int stream_index, int tmmbr);
|
||||
|
||||
/**
|
||||
* @}
|
||||
**/
|
||||
|
|
@ -239,7 +247,7 @@ typedef void (*LinphoneChatRoomCbsConferenceAddressGenerationCb) (LinphoneChatRo
|
|||
* @param[in] cr #LinphoneChatRoom object
|
||||
* @param[in] participantAddr #LinphoneAddress object
|
||||
*/
|
||||
typedef void (*LinphoneChatRoomCbsParticipantDeviceFetchedCb) (LinphoneChatRoom *cr, const LinphoneAddress *participantAddr);
|
||||
typedef void (*LinphoneChatRoomCbsParticipantDeviceFetchRequestedCb) (LinphoneChatRoom *cr, const LinphoneAddress *participantAddr);
|
||||
|
||||
/**
|
||||
* Callback used when a group chat room server is checking participants capabilities.
|
||||
|
|
@ -249,6 +257,20 @@ typedef void (*LinphoneChatRoomCbsParticipantDeviceFetchedCb) (LinphoneChatRoom
|
|||
*/
|
||||
typedef void (*LinphoneChatRoomCbsParticipantsCapabilitiesCheckedCb) (LinphoneChatRoom *cr, const LinphoneAddress *deviceAddr, const bctbx_list_t *participantsAddr);
|
||||
|
||||
/**
|
||||
* Callback used when a group chat room server is subscribing to registration state of a participant.
|
||||
* @param[in] cr #LinphoneChatRoom object
|
||||
* @param[in] participantAddr #LinphoneAddress object
|
||||
*/
|
||||
typedef void (*LinphoneChatRoomCbsParticipantRegistrationSubscriptionRequestedCb) (LinphoneChatRoom *cr, const LinphoneAddress *participantAddr);
|
||||
|
||||
/**
|
||||
* Callback used when a group chat room server is unsubscribing to registration state of a participant.
|
||||
* @param[in] cr #LinphoneChatRoom object
|
||||
* @param[in] participantAddr #LinphoneAddress object
|
||||
*/
|
||||
typedef void (*LinphoneChatRoomCbsParticipantRegistrationUnsubscriptionRequestedCb) (LinphoneChatRoom *cr, const LinphoneAddress *participantAddr);
|
||||
|
||||
/**
|
||||
* Callback used to tell the core whether or not to store the incoming message in db or not using linphone_chat_message_set_to_be_stored().
|
||||
* @param[in] cr #LinphoneChatRoom object
|
||||
|
|
|
|||
|
|
@ -244,18 +244,18 @@ LINPHONE_PUBLIC LinphoneChatRoomCbsConferenceAddressGenerationCb linphone_chat_r
|
|||
LINPHONE_PUBLIC void linphone_chat_room_cbs_set_conference_address_generation (LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsConferenceAddressGenerationCb cb);
|
||||
|
||||
/**
|
||||
* Get the participant device getting callback.
|
||||
* Get the participant device fetching callback.
|
||||
* @param[in] cbs LinphoneChatRoomCbs object
|
||||
* @return The participant device getting callback
|
||||
* @return The participant device fetching callback
|
||||
*/
|
||||
LINPHONE_PUBLIC LinphoneChatRoomCbsParticipantDeviceFetchedCb linphone_chat_room_cbs_get_participant_device_fetched (const LinphoneChatRoomCbs *cbs);
|
||||
LINPHONE_PUBLIC LinphoneChatRoomCbsParticipantDeviceFetchRequestedCb linphone_chat_room_cbs_get_participant_device_fetch_requested (const LinphoneChatRoomCbs *cbs);
|
||||
|
||||
/**
|
||||
* Set the participant device getting callback.
|
||||
* Set the participant device fetching callback.
|
||||
* @param[in] cbs LinphoneChatRoomCbs object
|
||||
* @param[in] cb The participant device getting callback to be used
|
||||
* @param[in] cb The participant device fetching callback to be used
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_chat_room_cbs_set_participant_device_fetched (LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsParticipantDeviceFetchedCb cb);
|
||||
LINPHONE_PUBLIC void linphone_chat_room_cbs_set_participant_device_fetch_requested (LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsParticipantDeviceFetchRequestedCb cb);
|
||||
|
||||
/**
|
||||
* Get the participants capabilities callback.
|
||||
|
|
@ -271,6 +271,34 @@ LINPHONE_PUBLIC LinphoneChatRoomCbsParticipantsCapabilitiesCheckedCb linphone_ch
|
|||
*/
|
||||
LINPHONE_PUBLIC void linphone_chat_room_cbs_set_participants_capabilities_checked (LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsParticipantsCapabilitiesCheckedCb cb);
|
||||
|
||||
/**
|
||||
* Get the participant registration subscription callback.
|
||||
* @param[in] cbs LinphoneChatRoomCbs object
|
||||
* @return The participant registration subscription callback
|
||||
*/
|
||||
LINPHONE_PUBLIC LinphoneChatRoomCbsParticipantRegistrationSubscriptionRequestedCb linphone_chat_room_cbs_get_participant_registration_subscription_requested (const LinphoneChatRoomCbs *cbs);
|
||||
|
||||
/**
|
||||
* Set the participant registration subscription callback.
|
||||
* @param[in] cbs LinphoneChatRoomCbs object
|
||||
* @param[in] cb The participant registration subscription callback to be used
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_chat_room_cbs_set_participant_registration_subscription_requested (LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsParticipantRegistrationSubscriptionRequestedCb cb);
|
||||
|
||||
/**
|
||||
* Get the participant registration unsubscription callback.
|
||||
* @param[in] cbs LinphoneChatRoomCbs object
|
||||
* @return The participant registration unsubscription callback
|
||||
*/
|
||||
LINPHONE_PUBLIC LinphoneChatRoomCbsParticipantRegistrationUnsubscriptionRequestedCb linphone_chat_room_cbs_get_participant_registration_unsubscription_requested (const LinphoneChatRoomCbs *cbs);
|
||||
|
||||
/**
|
||||
* Set the participant registration unsubscription callback.
|
||||
* @param[in] cbs LinphoneChatRoomCbs object
|
||||
* @param[in] cb The participant registration unsubscription callback to be used
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_chat_room_cbs_set_participant_registration_unsubscription_requested (LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsParticipantRegistrationUnsubscriptionRequestedCb cb);
|
||||
|
||||
/**
|
||||
* Get the message should be stored callback.
|
||||
* @param[in] cbs LinphoneChatRoomCbs object
|
||||
|
|
|
|||
|
|
@ -454,13 +454,22 @@ LINPHONE_PUBLIC void linphone_chat_room_set_conference_address (LinphoneChatRoom
|
|||
|
||||
/**
|
||||
* Set the participant device. This function needs to be called from the
|
||||
* LinphoneChatRoomCbsParticipantDeviceFetchedCb callback and only there.
|
||||
* LinphoneChatRoomCbsParticipantDeviceFetchRequestedCb callback and only there.
|
||||
* @param[in] cr A LinphoneChatRoom object
|
||||
* @param[in] partAddr The participant address
|
||||
* @param[in] partDevices \bctbx_list{LinphoneAddress} list of the participant devices to be used by the group chat room
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_chat_room_set_participant_devices (LinphoneChatRoom *cr, const LinphoneAddress *partAddr, const bctbx_list_t *partDevices);
|
||||
|
||||
/**
|
||||
* Add a participant device.
|
||||
* This is to used if a new device registers itself after the chat room creation.
|
||||
* @param[in] cr A #LinphoneChatRoom object
|
||||
* @param[in] participantAddress The address of the participant for which a new device is to be added
|
||||
* @param[in] deviceAddress The address of the new device to be added
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_chat_room_add_participant_device (LinphoneChatRoom *cr, const LinphoneAddress *participantAddress, const LinphoneAddress *deviceAddress);
|
||||
|
||||
/**
|
||||
* Set the participant device. This function needs to be called from the
|
||||
* LinphoneChatRoomCbsParticipantsCapabilitiesCheckedCb callback and only there.
|
||||
|
|
|
|||
|
|
@ -99,6 +99,16 @@ LINPHONE_PUBLIC LinphoneStatus linphone_proxy_config_set_identity_address(Linpho
|
|||
**/
|
||||
LINPHONE_PUBLIC LinphoneStatus linphone_proxy_config_set_route(LinphoneProxyConfig *cfg, const char *route);
|
||||
|
||||
/**
|
||||
* Sets a list of SIP route.
|
||||
* When a route is set, all outgoing calls will go to the route's destination if this proxy
|
||||
* is the default one (see linphone_core_set_default_proxy() ).
|
||||
* @param[in] cfg the #LinphoneProxyConfig
|
||||
* @param[in] routes A \bctbx_list{const char *} of routes
|
||||
* @return -1 if routes are invalid, 0 otherwise.
|
||||
**/
|
||||
LINPHONE_PUBLIC LinphoneStatus linphone_proxy_config_set_routes(LinphoneProxyConfig *cfg, const bctbx_list_t *routes);
|
||||
|
||||
/**
|
||||
* Sets the registration expiration time in seconds.
|
||||
**/
|
||||
|
|
@ -257,9 +267,17 @@ LINPHONE_PUBLIC void linphone_proxy_config_set_realm(LinphoneProxyConfig *cfg, c
|
|||
|
||||
/**
|
||||
* @return the route set for this proxy configuration.
|
||||
* @deprecated Use linphone_proxy_config_get_routes() instead.
|
||||
**/
|
||||
LINPHONE_PUBLIC const char *linphone_proxy_config_get_route(const LinphoneProxyConfig *cfg);
|
||||
|
||||
/**
|
||||
* Gets the list of the routes set for this proxy config.
|
||||
* @param[in] cfg #LinphoneProxyConfig object.
|
||||
* @return \bctbx_list{const char *} the list of routes.
|
||||
*/
|
||||
LINPHONE_PUBLIC const bctbx_list_t* linphone_proxy_config_get_routes(const LinphoneProxyConfig *cfg);
|
||||
|
||||
/**
|
||||
* @return the SIP identity that belongs to this proxy configuration.
|
||||
**/
|
||||
|
|
|
|||
|
|
@ -107,6 +107,8 @@ namespace Utils {
|
|||
return str ? str : "";
|
||||
}
|
||||
|
||||
LINPHONE_PUBLIC std::string trim (const std::string &str);
|
||||
|
||||
template<typename T>
|
||||
LINPHONE_PUBLIC const T &getEmptyConstRefObject () {
|
||||
static const T object;
|
||||
|
|
|
|||
|
|
@ -94,6 +94,7 @@ set(LINPHONE_CXX_OBJECTS_PRIVATE_HEADER_FILES
|
|||
conference/session/media-session.h
|
||||
conference/session/port-config.h
|
||||
containers/lru-cache.h
|
||||
content/content-disposition.h
|
||||
content/content-manager.h
|
||||
content/content-p.h
|
||||
content/content-type.h
|
||||
|
|
@ -220,6 +221,7 @@ set(LINPHONE_CXX_OBJECTS_SOURCE_FILES
|
|||
conference/remote-conference.cpp
|
||||
conference/session/call-session.cpp
|
||||
conference/session/media-session.cpp
|
||||
content/content-disposition.cpp
|
||||
content/content-manager.cpp
|
||||
content/content-type.cpp
|
||||
content/content.cpp
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ struct _LinphoneCallCbs {
|
|||
LinphoneCallCbsStatsUpdatedCb statsUpdatedCb;
|
||||
LinphoneCallCbsTransferStateChangedCb transferStateChangedCb;
|
||||
LinphoneCallCbsAckProcessingCb ackProcessing;
|
||||
LinphoneCallCbsTmmbrReceivedCb tmmbrReceivedCb;
|
||||
};
|
||||
|
||||
BELLE_SIP_DECLARE_VPTR_NO_EXPORT(LinphoneCallCbs);
|
||||
|
|
@ -124,3 +125,11 @@ LinphoneCallCbsAckProcessingCb linphone_call_cbs_get_ack_processing (LinphoneCal
|
|||
void linphone_call_cbs_set_ack_processing (LinphoneCallCbs *cbs, LinphoneCallCbsAckProcessingCb cb){
|
||||
cbs->ackProcessing = cb;
|
||||
}
|
||||
|
||||
LinphoneCallCbsTmmbrReceivedCb linphone_call_cbs_get_tmmbr_received (LinphoneCallCbs *cbs) {
|
||||
return cbs->tmmbrReceivedCb;
|
||||
}
|
||||
|
||||
void linphone_call_cbs_set_tmmbr_received (LinphoneCallCbs *cbs, LinphoneCallCbsTmmbrReceivedCb cb) {
|
||||
cbs->tmmbrReceivedCb = cb;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -206,6 +206,10 @@ void linphone_call_notify_ack_processing (LinphoneCall *call, LinphoneHeaders *m
|
|||
NOTIFY_IF_EXIST(AckProcessing, ack_processing, call, msg, is_received)
|
||||
}
|
||||
|
||||
void linphone_call_notify_tmmbr_received (LinphoneCall *call, int stream_index, int tmmbr) {
|
||||
NOTIFY_IF_EXIST(TmmbrReceived, tmmbr_received, call, stream_index, tmmbr)
|
||||
}
|
||||
|
||||
|
||||
// =============================================================================
|
||||
// Public functions.
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ const char *linphone_chat_message_get_external_body_url(const LinphoneChatMessag
|
|||
}
|
||||
|
||||
void linphone_chat_message_set_external_body_url(LinphoneChatMessage *msg, const char *url) {
|
||||
|
||||
L_GET_PRIVATE_FROM_C_OBJECT(msg)->setExternalBodyUrl(L_C_TO_STRING(url));
|
||||
}
|
||||
|
||||
time_t linphone_chat_message_get_time(const LinphoneChatMessage *msg) {
|
||||
|
|
|
|||
|
|
@ -39,8 +39,10 @@ struct _LinphoneChatRoomCbs {
|
|||
LinphoneChatRoomCbsChatMessageReceivedCb chatMessageReceivedCb;
|
||||
LinphoneChatRoomCbsChatMessageSentCb chatMessageSentCb;
|
||||
LinphoneChatRoomCbsConferenceAddressGenerationCb conferenceAddressGenerationCb;
|
||||
LinphoneChatRoomCbsParticipantDeviceFetchedCb participantDeviceFetchedCb;
|
||||
LinphoneChatRoomCbsParticipantDeviceFetchRequestedCb participantDeviceFetchRequestedCb;
|
||||
LinphoneChatRoomCbsParticipantsCapabilitiesCheckedCb participantsCapabilitiesChecked;
|
||||
LinphoneChatRoomCbsParticipantRegistrationSubscriptionRequestedCb participantRegistrationSubscriptionRequestedCb;
|
||||
LinphoneChatRoomCbsParticipantRegistrationUnsubscriptionRequestedCb participantRegistrationUnsubscriptionRequestedCb;
|
||||
LinphoneChatRoomCbsShouldChatMessageBeStoredCb shouldMessageBeStoredCb;
|
||||
};
|
||||
|
||||
|
|
@ -182,12 +184,12 @@ void linphone_chat_room_cbs_set_conference_address_generation (LinphoneChatRoomC
|
|||
cbs->conferenceAddressGenerationCb = cb;
|
||||
}
|
||||
|
||||
LinphoneChatRoomCbsParticipantDeviceFetchedCb linphone_chat_room_cbs_get_participant_device_fetched (const LinphoneChatRoomCbs *cbs) {
|
||||
return cbs->participantDeviceFetchedCb;
|
||||
LinphoneChatRoomCbsParticipantDeviceFetchRequestedCb linphone_chat_room_cbs_get_participant_device_fetch_requested (const LinphoneChatRoomCbs *cbs) {
|
||||
return cbs->participantDeviceFetchRequestedCb;
|
||||
}
|
||||
|
||||
void linphone_chat_room_cbs_set_participant_device_fetched (LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsParticipantDeviceFetchedCb cb) {
|
||||
cbs->participantDeviceFetchedCb = cb;
|
||||
void linphone_chat_room_cbs_set_participant_device_fetch_requested (LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsParticipantDeviceFetchRequestedCb cb) {
|
||||
cbs->participantDeviceFetchRequestedCb = cb;
|
||||
}
|
||||
|
||||
LinphoneChatRoomCbsParticipantsCapabilitiesCheckedCb linphone_chat_room_cbs_get_participants_capabilities_checked (const LinphoneChatRoomCbs *cbs) {
|
||||
|
|
@ -198,6 +200,22 @@ void linphone_chat_room_cbs_set_participants_capabilities_checked (LinphoneChatR
|
|||
cbs->participantsCapabilitiesChecked = cb;
|
||||
}
|
||||
|
||||
LinphoneChatRoomCbsParticipantRegistrationSubscriptionRequestedCb linphone_chat_room_cbs_get_participant_registration_subscription_requested (const LinphoneChatRoomCbs *cbs) {
|
||||
return cbs->participantRegistrationSubscriptionRequestedCb;
|
||||
}
|
||||
|
||||
void linphone_chat_room_cbs_set_participant_registration_subscription_requested (LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsParticipantRegistrationSubscriptionRequestedCb cb) {
|
||||
cbs->participantRegistrationSubscriptionRequestedCb = cb;
|
||||
}
|
||||
|
||||
LinphoneChatRoomCbsParticipantRegistrationUnsubscriptionRequestedCb linphone_chat_room_cbs_get_participant_registration_unsubscription_requested (const LinphoneChatRoomCbs *cbs) {
|
||||
return cbs->participantRegistrationUnsubscriptionRequestedCb;
|
||||
}
|
||||
|
||||
void linphone_chat_room_cbs_set_participant_registration_unsubscription_requested (LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsParticipantRegistrationUnsubscriptionRequestedCb cb) {
|
||||
cbs->participantRegistrationUnsubscriptionRequestedCb = cb;
|
||||
}
|
||||
|
||||
LinphoneChatRoomCbsShouldChatMessageBeStoredCb linphone_chat_room_cbs_get_chat_message_should_be_stored( LinphoneChatRoomCbs *cbs) {
|
||||
return cbs->shouldMessageBeStoredCb;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -382,6 +382,16 @@ void linphone_chat_room_set_participant_devices (LinphoneChatRoom *cr, const Lin
|
|||
bctbx_free(addrStr);
|
||||
}
|
||||
|
||||
void linphone_chat_room_add_participant_device (LinphoneChatRoom *cr, const LinphoneAddress *participantAddress, const LinphoneAddress *deviceAddress) {
|
||||
char *participantAddressStr = linphone_address_as_string(participantAddress);
|
||||
char *deviceAddressStr = linphone_address_as_string(deviceAddress);
|
||||
LinphonePrivate::ServerGroupChatRoomPrivate *sgcr = dynamic_cast<LinphonePrivate::ServerGroupChatRoomPrivate *>(L_GET_PRIVATE_FROM_C_OBJECT(cr));
|
||||
if (sgcr)
|
||||
sgcr->addParticipantDevice(LinphonePrivate::IdentityAddress(participantAddressStr), LinphonePrivate::IdentityAddress(deviceAddressStr));
|
||||
bctbx_free(participantAddressStr);
|
||||
bctbx_free(deviceAddressStr);
|
||||
}
|
||||
|
||||
void linphone_chat_room_add_compatible_participants (LinphoneChatRoom *cr, const LinphoneAddress *deviceAddr, const bctbx_list_t *participantsCompatible) {
|
||||
list<LinphonePrivate::Address> lPartsComp = L_GET_RESOLVED_CPP_LIST_FROM_C_LIST(participantsCompatible, Address);
|
||||
LinphonePrivate::ServerGroupChatRoomPrivate *sgcr = dynamic_cast<LinphonePrivate::ServerGroupChatRoomPrivate *>(L_GET_PRIVATE_FROM_C_OBJECT(cr));
|
||||
|
|
@ -486,14 +496,22 @@ void _linphone_chat_room_notify_conference_address_generation(LinphoneChatRoom *
|
|||
NOTIFY_IF_EXIST(ConferenceAddressGeneration, conference_address_generation, cr)
|
||||
}
|
||||
|
||||
void _linphone_chat_room_notify_participant_device_fetched(LinphoneChatRoom *cr, const LinphoneAddress *participantAddr) {
|
||||
NOTIFY_IF_EXIST(ParticipantDeviceFetched, participant_device_fetched, cr, participantAddr)
|
||||
void _linphone_chat_room_notify_participant_device_fetch_requested(LinphoneChatRoom *cr, const LinphoneAddress *participantAddr) {
|
||||
NOTIFY_IF_EXIST(ParticipantDeviceFetchRequested, participant_device_fetch_requested, cr, participantAddr)
|
||||
}
|
||||
|
||||
void _linphone_chat_room_notify_participants_capabilities_checked(LinphoneChatRoom *cr, const LinphoneAddress *deviceAddr, const bctbx_list_t *participantsAddr) {
|
||||
NOTIFY_IF_EXIST(ParticipantsCapabilitiesChecked, participants_capabilities_checked, cr, deviceAddr, participantsAddr)
|
||||
}
|
||||
|
||||
void _linphone_chat_room_notify_participant_registration_subscription_requested(LinphoneChatRoom *cr, const LinphoneAddress *participantAddr) {
|
||||
NOTIFY_IF_EXIST(ParticipantRegistrationSubscriptionRequested, participant_registration_subscription_requested, cr, participantAddr)
|
||||
}
|
||||
|
||||
void _linphone_chat_room_notify_participant_registration_unsubscription_requested(LinphoneChatRoom *cr, const LinphoneAddress *participantAddr) {
|
||||
NOTIFY_IF_EXIST(ParticipantRegistrationUnsubscriptionRequested, participant_registration_unsubscription_requested, cr, participantAddr)
|
||||
}
|
||||
|
||||
void _linphone_chat_room_notify_chat_message_should_be_stored(LinphoneChatRoom *cr, LinphoneChatMessage *msg) {
|
||||
NOTIFY_IF_EXIST(ShouldChatMessageBeStored, chat_message_should_be_stored, cr, msg)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -110,6 +110,7 @@ private:
|
|||
bool areSoundResourcesAvailable (const std::shared_ptr<CallSession> &session) override;
|
||||
bool isPlayingRingbackTone (const std::shared_ptr<CallSession> &session) override;
|
||||
void onRealTimeTextCharacterReceived (const std::shared_ptr<CallSession> &session, RealtimeTextReceivedCharacter *character) override;
|
||||
void onTmmbrReceived(const std::shared_ptr<CallSession> &session, int streamIndex, int tmmbr) override;
|
||||
|
||||
mutable LinphonePlayer *player = nullptr;
|
||||
|
||||
|
|
|
|||
|
|
@ -491,6 +491,11 @@ void CallPrivate::onRealTimeTextCharacterReceived (const shared_ptr<CallSession>
|
|||
getChatRoom()->getPrivate()->realtimeTextReceived(data->character, q->getSharedFromThis());
|
||||
}
|
||||
|
||||
void CallPrivate::onTmmbrReceived (const shared_ptr<CallSession> &session, int streamIndex, int tmmbr) {
|
||||
L_Q();
|
||||
linphone_call_notify_tmmbr_received(L_GET_C_BACK_PTR(q), streamIndex, tmmbr);
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
|
||||
Call::Call (CallPrivate &p, shared_ptr<Core> core) : Object(p), CoreAccessor(core) {
|
||||
|
|
|
|||
|
|
@ -105,6 +105,7 @@ public:
|
|||
std::string getSalCustomHeaderValue (const std::string &name);
|
||||
|
||||
void loadFileTransferUrlFromBodyToContent ();
|
||||
std::string createFakeFileTransferFromUrl(const std::string &url);
|
||||
|
||||
void setChatRoom (const std::shared_ptr<AbstractChatRoom> &chatRoom);
|
||||
|
||||
|
|
@ -127,6 +128,7 @@ public:
|
|||
void setAppdata (const std::string &appData);
|
||||
|
||||
const std::string &getExternalBodyUrl () const;
|
||||
void setExternalBodyUrl (const std::string &url);
|
||||
|
||||
bool hasTextContent () const;
|
||||
const Content* getTextContent () const;
|
||||
|
|
@ -161,6 +163,7 @@ private:
|
|||
time_t time = ::ms_time(0); // TODO: Change me in all files.
|
||||
std::string imdnId;
|
||||
std::string rttMessage;
|
||||
std::string externalBodyUrl;
|
||||
bool isSecured = false;
|
||||
mutable bool isReadOnly = false;
|
||||
Content internalContent;
|
||||
|
|
|
|||
|
|
@ -147,7 +147,13 @@ void ChatMessagePrivate::setState (ChatMessage::State newState, bool force) {
|
|||
if (cbs && linphone_chat_message_cbs_get_msg_state_changed(cbs))
|
||||
linphone_chat_message_cbs_get_msg_state_changed(cbs)(msg, (LinphoneChatMessageState)state);
|
||||
|
||||
updateInDb();
|
||||
if (state == ChatMessage::State::FileTransferDone && !hasFileTransferContent()) {
|
||||
// We wait until the file has been downloaded to send the displayed IMDN
|
||||
q->sendDisplayNotification();
|
||||
setState(ChatMessage::State::Displayed);
|
||||
} else {
|
||||
updateInDb();
|
||||
}
|
||||
}
|
||||
|
||||
belle_http_request_t *ChatMessagePrivate::getHttpRequest () const {
|
||||
|
|
@ -236,26 +242,29 @@ void ChatMessagePrivate::setFileTransferFilepath (const string &path) {
|
|||
|
||||
const string &ChatMessagePrivate::getAppdata () const {
|
||||
for (const Content *c : getContents()) {
|
||||
if (c->isFile()) {
|
||||
FileContent *fileContent = (FileContent *)c;
|
||||
return fileContent->getAppData("legacy");
|
||||
if (!c->getAppData("legacy").empty()) {
|
||||
return c->getAppData("legacy");
|
||||
}
|
||||
}
|
||||
return Utils::getEmptyConstRefObject<string>();
|
||||
}
|
||||
|
||||
void ChatMessagePrivate::setAppdata (const string &data) {
|
||||
for (const Content *c : getContents()) {
|
||||
if (c->isFile()) {
|
||||
FileContent *fileContent = (FileContent *)c;
|
||||
fileContent->setAppData("legacy", data);
|
||||
break;
|
||||
}
|
||||
bool contentFound = false;
|
||||
for (Content *c : getContents()) {
|
||||
c->setAppData("legacy", data);
|
||||
contentFound = true;
|
||||
break;
|
||||
}
|
||||
if (contentFound) {
|
||||
updateInDb();
|
||||
}
|
||||
updateInDb();
|
||||
}
|
||||
|
||||
const string &ChatMessagePrivate::getExternalBodyUrl () const {
|
||||
if (!externalBodyUrl.empty()) {
|
||||
return externalBodyUrl;
|
||||
}
|
||||
if (hasFileTransferContent()) {
|
||||
FileTransferContent *content = (FileTransferContent*) getFileTransferContent();
|
||||
return content->getFileUrl();
|
||||
|
|
@ -263,6 +272,10 @@ const string &ChatMessagePrivate::getExternalBodyUrl () const {
|
|||
return Utils::getEmptyConstRefObject<string>();
|
||||
}
|
||||
|
||||
void ChatMessagePrivate::setExternalBodyUrl (const string &url) {
|
||||
externalBodyUrl = url;
|
||||
}
|
||||
|
||||
const ContentType &ChatMessagePrivate::getContentType () {
|
||||
loadContentsFromDatabase();
|
||||
if (direction == ChatMessage::Direction::Incoming) {
|
||||
|
|
@ -390,6 +403,10 @@ void ChatMessagePrivate::loadFileTransferUrlFromBodyToContent() {
|
|||
fileTransferChatMessageModifier.decode(q->getSharedFromThis(), errorCode);
|
||||
}
|
||||
|
||||
std::string ChatMessagePrivate::createFakeFileTransferFromUrl(const std::string &url) {
|
||||
return fileTransferChatMessageModifier.createFakeFileTransferFromUrl(url);
|
||||
}
|
||||
|
||||
void ChatMessagePrivate::setChatRoom (const shared_ptr<AbstractChatRoom> &cr) {
|
||||
chatRoom = cr;
|
||||
chatRoomId = cr->getChatRoomId();
|
||||
|
|
@ -410,7 +427,7 @@ void ChatMessagePrivate::sendImdn (Imdn::Type imdnType, LinphoneReason reason) {
|
|||
shared_ptr<ChatMessage> msg = q->getChatRoom()->createChatMessage();
|
||||
|
||||
Content *content = new Content();
|
||||
content->setContentType("message/imdn+xml");
|
||||
content->setContentType(ContentType::Imdn);
|
||||
content->setBody(Imdn::createXml(imdnId, time, imdnType, reason));
|
||||
msg->addContent(*content);
|
||||
|
||||
|
|
@ -711,14 +728,18 @@ void ChatMessagePrivate::send () {
|
|||
if (internalContent.isEmpty()) {
|
||||
if (contents.size() > 0) {
|
||||
internalContent = *(contents.front());
|
||||
} else {
|
||||
} else if (externalBodyUrl.empty()) { // When using external body url, there is no content
|
||||
lError() << "Trying to send a message without any content !";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
auto msgOp = dynamic_cast<SalMessageOpInterface *>(op);
|
||||
if (internalContent.getContentType().isValid()) {
|
||||
if (!externalBodyUrl.empty()) {
|
||||
char *content_type = ms_strdup_printf("message/external-body; access-type=URL; URL=\"%s\"", externalBodyUrl.c_str());
|
||||
msgOp->send_message(content_type, NULL);
|
||||
ms_free(content_type);
|
||||
} else if (internalContent.getContentType().isValid()) {
|
||||
msgOp->send_message(internalContent.getContentType().asString().c_str(), internalContent.getBodyAsUtf8String().c_str());
|
||||
} else {
|
||||
msgOp->send_message(ContentType::PlainText.asString().c_str(), internalContent.getBodyAsUtf8String().c_str());
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
#include "chat/chat-room/chat-room-p.h"
|
||||
#include "core/core-p.h"
|
||||
#include "sip-tools/sip-headers.h"
|
||||
#include "logger/logger.h"
|
||||
|
||||
// =============================================================================
|
||||
|
||||
|
|
@ -193,8 +194,14 @@ LinphoneReason ChatRoomPrivate::onSipMessageReceived (SalOp *op, const SalMessag
|
|||
);
|
||||
|
||||
Content content;
|
||||
content.setContentType(message->content_type);
|
||||
content.setBodyFromUtf8(message->text ? message->text : "");
|
||||
if (message->url && (ContentType(message->content_type) == ContentType::ExternalBody)) {
|
||||
lInfo() << "Received a message with an external body URL " << message->url;
|
||||
content.setContentType(ContentType::FileTransfer);
|
||||
content.setBody(msg->getPrivate()->createFakeFileTransferFromUrl(message->url));
|
||||
} else {
|
||||
content.setContentType(ContentType(message->content_type));
|
||||
content.setBodyFromUtf8(message->text ? message->text : "");
|
||||
}
|
||||
msg->setInternalContent(content);
|
||||
|
||||
msg->getPrivate()->setTime(message->time);
|
||||
|
|
@ -438,8 +445,11 @@ void ChatRoom::markAsRead () {
|
|||
|
||||
CorePrivate *dCore = getCore()->getPrivate();
|
||||
for (auto &chatMessage : dCore->mainDb->getUnreadChatMessages(d->chatRoomId)) {
|
||||
chatMessage->sendDisplayNotification();
|
||||
chatMessage->getPrivate()->setState(ChatMessage::State::Displayed, true);
|
||||
// Do not send display notification for file transfer until it has been downloaded (it won't have a file transfer content anymore)
|
||||
if (!chatMessage->getPrivate()->hasFileTransferContent()) {
|
||||
chatMessage->sendDisplayNotification();
|
||||
chatMessage->getPrivate()->setState(ChatMessage::State::Displayed, true); // True will ensure the setState won't update the database so it will be done below by the markChatMessagesAsRead
|
||||
}
|
||||
}
|
||||
|
||||
dCore->mainDb->markChatMessagesAsRead(d->chatRoomId);
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@
|
|||
#include "conference/participant-device.h"
|
||||
#include "conference/remote-conference-p.h"
|
||||
#include "conference/session/call-session-p.h"
|
||||
#include "content/content-disposition.h"
|
||||
#include "content/content-type.h"
|
||||
#include "core/core-p.h"
|
||||
#include "logger/logger.h"
|
||||
#include "sal/refer-op.h"
|
||||
|
|
@ -319,8 +321,8 @@ void ClientGroupChatRoom::addParticipants (
|
|||
|
||||
Content content;
|
||||
content.setBody(getResourceLists(addressesList));
|
||||
content.setContentType("application/resource-lists+xml");
|
||||
content.setContentDisposition("recipient-list");
|
||||
content.setContentType(ContentType::ResourceLists);
|
||||
content.setContentDisposition(ContentDisposition::RecipientList);
|
||||
// TODO: Activate compression
|
||||
//if (linphone_core_content_encoding_supported(getCore()->getCCore(), "deflate"))
|
||||
// content.setContentEncoding("deflate");
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ public:
|
|||
|
||||
void setConferenceAddress (const IdentityAddress &conferenceAddress);
|
||||
void setParticipantDevices (const IdentityAddress &addr, const std::list<IdentityAddress> &devices);
|
||||
void addParticipantDevice (const IdentityAddress &participantAddress, const IdentityAddress &deviceAddress);
|
||||
void addCompatibleParticipants (const IdentityAddress &deviceAddr, const std::list<IdentityAddress> &compatibleParticipants);
|
||||
void checkCompatibleParticipants (const IdentityAddress &deviceAddr, const std::list<IdentityAddress> &addressesToCheck);
|
||||
|
||||
|
|
@ -67,17 +68,29 @@ public:
|
|||
|
||||
private:
|
||||
struct Message {
|
||||
Message (const std::string &from, const std::string &contentType, const std::string &text) : fromAddr(from) {
|
||||
Message (const std::string &from, const ContentType &contentType, const std::string &text, const SalCustomHeader *salCustomHeaders)
|
||||
: fromAddr(from)
|
||||
{
|
||||
content.setContentType(contentType);
|
||||
if (!text.empty())
|
||||
content.setBodyFromUtf8(text);
|
||||
if (salCustomHeaders)
|
||||
customHeaders = sal_custom_header_clone(salCustomHeaders);
|
||||
}
|
||||
|
||||
~Message () {
|
||||
if (customHeaders)
|
||||
sal_custom_header_free(customHeaders);
|
||||
}
|
||||
|
||||
IdentityAddress fromAddr;
|
||||
Content content;
|
||||
std::chrono::system_clock::time_point timestamp = std::chrono::system_clock::now();
|
||||
SalCustomHeader *customHeaders = nullptr;
|
||||
};
|
||||
|
||||
static void copyMessageHeaders (const std::shared_ptr<Message> &fromMessage, const std::shared_ptr<ChatMessage> &toMessage);
|
||||
|
||||
void designateAdmin ();
|
||||
void dispatchMessage (const std::shared_ptr<Message> &message, const std::string &uri);
|
||||
void finalizeCreation ();
|
||||
|
|
|
|||
|
|
@ -80,6 +80,8 @@ void ServerGroupChatRoomPrivate::setConferenceAddress (const IdentityAddress &)
|
|||
|
||||
void ServerGroupChatRoomPrivate::setParticipantDevices (const IdentityAddress &addr, const list<IdentityAddress> &devices) {}
|
||||
|
||||
void ServerGroupChatRoomPrivate::addParticipantDevice (const IdentityAddress &participantAddress, const IdentityAddress &deviceAddress) {}
|
||||
|
||||
void ServerGroupChatRoomPrivate::addCompatibleParticipants (const IdentityAddress &deviceAddr, const list<IdentityAddress> &participantCompatible) {}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -968,4 +968,18 @@ void FileTransferChatMessageModifier::releaseHttpRequest () {
|
|||
}
|
||||
}
|
||||
|
||||
string FileTransferChatMessageModifier::createFakeFileTransferFromUrl(const string &url) {
|
||||
string fileName = url.substr(url.find_last_of("/") + 1);
|
||||
stringstream fakeXml;
|
||||
fakeXml << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n";
|
||||
fakeXml << "<file xmlns=\"urn:gsma:params:xml:ns:rcs:rcs:fthttp\">\r\n";
|
||||
fakeXml << "<file-info type=\"file\">\r\n";
|
||||
fakeXml << "<file-name>" << fileName << "</file-name>\r\n";
|
||||
fakeXml << "<content-type>application/binary</content-type>\r\n";
|
||||
fakeXml << "<data url = \"" << url << "\"/>\r\n";
|
||||
fakeXml << "</file-info>\r\n";
|
||||
fakeXml << "</file>";
|
||||
return fakeXml.str();
|
||||
}
|
||||
|
||||
LINPHONE_END_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ public:
|
|||
int downloadFile(const std::shared_ptr<ChatMessage> &message, FileTransferContent *fileTransferContent);
|
||||
void cancelFileTransfer();
|
||||
bool isFileTransferInProgressAndValid();
|
||||
std::string createFakeFileTransferFromUrl(const std::string &url);
|
||||
|
||||
private:
|
||||
int uploadFile();
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
*/
|
||||
|
||||
#include "content/content.h"
|
||||
#include "content/content-disposition.h"
|
||||
#include "content/content-type.h"
|
||||
#include "handlers/local-conference-event-handler.h"
|
||||
#include "local-conference-p.h"
|
||||
|
|
@ -70,7 +71,7 @@ void LocalConference::removeParticipant (const shared_ptr<const Participant> &pa
|
|||
|
||||
list<IdentityAddress> LocalConference::parseResourceLists (const Content &content) {
|
||||
if ((content.getContentType() == ContentType::ResourceLists)
|
||||
&& (content.getContentDisposition() == "recipient-list")
|
||||
&& (content.getContentDisposition() == ContentDisposition::RecipientList)
|
||||
) {
|
||||
istringstream data(content.getBodyAsString());
|
||||
unique_ptr<Xsd::ResourceLists::ResourceLists> rl(Xsd::ResourceLists::parseResourceLists(
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ public:
|
|||
virtual void onIncomingCallSessionTimeoutCheck (const std::shared_ptr<CallSession> &session, int elapsed, bool oneSecondElapsed) {}
|
||||
virtual void onInfoReceived (const std::shared_ptr<CallSession> &session, const LinphoneInfoMessage *im) {}
|
||||
virtual void onNoMediaTimeoutCheck (const std::shared_ptr<CallSession> &session, bool oneSecondElapsed) {}
|
||||
virtual void onTmmbrReceived (const std::shared_ptr<CallSession> &session, int streamIndex, int tmmbr) {}
|
||||
|
||||
virtual void onEncryptionChanged (const std::shared_ptr<CallSession> &session, bool activated, const std::string &authToken) {}
|
||||
|
||||
|
|
|
|||
|
|
@ -134,6 +134,7 @@ protected:
|
|||
bool broken = false;
|
||||
bool deferIncomingNotification = false;
|
||||
bool deferUpdate = false;
|
||||
bool deferUpdateInternal = false;
|
||||
bool needLocalIpRefresh = false;
|
||||
bool nonOpError = false; /* Set when the LinphoneErrorInfo was set at higher level than sal */
|
||||
bool notifyRinging = true;
|
||||
|
|
|
|||
|
|
@ -467,9 +467,10 @@ void CallSessionPrivate::updated (bool isUpdate) {
|
|||
void CallSessionPrivate::updatedByRemote () {
|
||||
L_Q();
|
||||
setState(CallSession::State::UpdatedByRemote,"Call updated by remote");
|
||||
if (deferUpdate) {
|
||||
if (state == CallSession::State::UpdatedByRemote)
|
||||
lInfo() << "CallSession [" << q << "]: UpdatedByRemoted was signaled but defered. LinphoneCore expects the application to call CallSession::acceptUpdate() later";
|
||||
if (deferUpdate || deferUpdateInternal) {
|
||||
if (state == CallSession::State::UpdatedByRemote && !deferUpdateInternal){
|
||||
lInfo() << "CallSession [" << q << "]: UpdatedByRemoted was signaled but defered. LinphoneCore expects the application to call linphone_call_accept_update() later";
|
||||
}
|
||||
} else {
|
||||
if (state == CallSession::State::UpdatedByRemote)
|
||||
q->acceptUpdate(nullptr);
|
||||
|
|
@ -820,8 +821,9 @@ void CallSessionPrivate::repairIfBroken () {
|
|||
case CallSession::State::Pausing:
|
||||
if (op->dialog_request_pending()) {
|
||||
// Need to cancel first re-INVITE as described in section 5.5 of RFC 6141
|
||||
op->cancel_invite();
|
||||
reinviteOnCancelResponseRequested = true;
|
||||
if (op->cancel_invite() == 0){
|
||||
reinviteOnCancelResponseRequested = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CallSession::State::StreamsRunning:
|
||||
|
|
@ -839,8 +841,9 @@ void CallSessionPrivate::repairIfBroken () {
|
|||
break;
|
||||
case CallSession::State::OutgoingInit:
|
||||
case CallSession::State::OutgoingProgress:
|
||||
op->cancel_invite();
|
||||
reinviteOnCancelResponseRequested = true;
|
||||
if (op->cancel_invite() == 0){
|
||||
reinviteOnCancelResponseRequested = true;
|
||||
}
|
||||
break;
|
||||
case CallSession::State::OutgoingEarlyMedia:
|
||||
case CallSession::State::OutgoingRinging:
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ public:
|
|||
void setParams (MediaSessionParams *msp);
|
||||
void setRemoteParams (MediaSessionParams *msp);
|
||||
|
||||
IceSession *getIceSession () const { return iceAgent->getIceSession(); }
|
||||
IceSession *getIceSession () const { return iceAgent ? iceAgent->getIceSession() : nullptr; }
|
||||
|
||||
SalMediaDescription *getLocalDesc () const { return localDesc; }
|
||||
|
||||
|
|
@ -254,7 +254,6 @@ private:
|
|||
int sendDtmf ();
|
||||
|
||||
void stunAuthRequestedCb (const char *realm, const char *nonce, const char **username, const char **password, const char **ha1);
|
||||
|
||||
private:
|
||||
static const std::string ecStateStore;
|
||||
static const int ecStateMaxLen;
|
||||
|
|
@ -284,8 +283,8 @@ private:
|
|||
int mainTextStreamIndex = LINPHONE_CALL_STATS_TEXT;
|
||||
|
||||
LinphoneNatPolicy *natPolicy = nullptr;
|
||||
StunClient *stunClient = nullptr;
|
||||
IceAgent *iceAgent = nullptr;
|
||||
std::unique_ptr<StunClient> stunClient;
|
||||
std::unique_ptr<IceAgent> iceAgent;
|
||||
|
||||
// The address family to prefer for RTP path, guessed from signaling path.
|
||||
int af;
|
||||
|
|
@ -325,6 +324,7 @@ private:
|
|||
bool automaticallyPaused = false;
|
||||
bool pausedByApp = false;
|
||||
bool recordActive = false;
|
||||
bool incomingIceReinvitePending = false;
|
||||
|
||||
std::string onHoldFile;
|
||||
|
||||
|
|
|
|||
|
|
@ -382,6 +382,8 @@ void MediaSessionPrivate::updated (bool isUpdate) {
|
|||
CallSessionPrivate::updated(isUpdate);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void MediaSessionPrivate::updating (bool isUpdate) {
|
||||
L_Q();
|
||||
SalMediaDescription *rmd = op->get_remote_media_description();
|
||||
|
|
@ -702,6 +704,10 @@ shared_ptr<Participant> MediaSessionPrivate::getMe () const {
|
|||
|
||||
void MediaSessionPrivate::setState (CallSession::State newState, const string &message) {
|
||||
L_Q();
|
||||
SalMediaDescription *rmd;
|
||||
|
||||
lInfo()<<"MediaSessionPrivate::setState";
|
||||
|
||||
/* Take a ref on the session otherwise it might get destroyed during the call to setState */
|
||||
shared_ptr<CallSession> sessionRef = q->getSharedFromThis();
|
||||
if ((newState != state) && (newState != CallSession::State::StreamsRunning))
|
||||
|
|
@ -709,6 +715,21 @@ void MediaSessionPrivate::setState (CallSession::State newState, const string &m
|
|||
CallSessionPrivate::setState(newState, message);
|
||||
if (listener)
|
||||
listener->onCallSessionStateChangedForReporting(q->getSharedFromThis());
|
||||
switch(newState){
|
||||
case CallSession::State::UpdatedByRemote:
|
||||
/*Handle specifically the case of an incoming ICE-concluded reINVITE*/
|
||||
lInfo()<<"Checking for ICE reINVITE";
|
||||
rmd = op->get_remote_media_description();
|
||||
if (iceAgent && rmd != nullptr && iceAgent->checkIceReinviteNeedsDeferedResponse(rmd)){
|
||||
deferUpdate = true;
|
||||
deferUpdateInternal = true;
|
||||
incomingIceReinvitePending = true;
|
||||
lInfo()<<"CallSession [" << q << "]: ICE reinvite received, but one or more check-lists are not completed. Response will be sent later, when ICE has completed";
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
@ -1177,7 +1198,7 @@ string MediaSessionPrivate::getPublicIpForStream (int streamIndex) {
|
|||
void MediaSessionPrivate::runStunTestsIfNeeded () {
|
||||
L_Q();
|
||||
if (linphone_nat_policy_stun_enabled(natPolicy) && !(linphone_nat_policy_ice_enabled(natPolicy) || linphone_nat_policy_turn_enabled(natPolicy))) {
|
||||
stunClient = new StunClient(q->getCore());
|
||||
stunClient = makeUnique<StunClient>(q->getCore());
|
||||
int ret = stunClient->run(mediaPorts[mainAudioStreamIndex].rtpPort, mediaPorts[mainVideoStreamIndex].rtpPort, mediaPorts[mainTextStreamIndex].rtpPort);
|
||||
if (ret >= 0)
|
||||
pingTime = ret;
|
||||
|
|
@ -2191,11 +2212,14 @@ void MediaSessionPrivate::handleIceEvents (OrtpEvent *ev) {
|
|||
OrtpEventData *evd = ortp_event_get_data(ev);
|
||||
if (evt == ORTP_EVENT_ICE_SESSION_PROCESSING_FINISHED) {
|
||||
if (iceAgent->hasCompletedCheckList()) {
|
||||
/* At least one ICE session has succeeded, so perform a call update */
|
||||
/* The ICE session has succeeded, so perform a call update */
|
||||
if (iceAgent->isControlling() && q->getCurrentParams()->getPrivate()->getUpdateCallWhenIceCompleted()) {
|
||||
MediaSessionParams newParams(*getParams());
|
||||
newParams.getPrivate()->setInternalCallUpdate(true);
|
||||
q->update(&newParams);
|
||||
}else if (!iceAgent->isControlling() && incomingIceReinvitePending){
|
||||
q->acceptUpdate(nullptr);
|
||||
incomingIceReinvitePending = false;
|
||||
}
|
||||
startDtlsOnAllStreams();
|
||||
}
|
||||
|
|
@ -2238,6 +2262,7 @@ void MediaSessionPrivate::handleIceEvents (OrtpEvent *ev) {
|
|||
}
|
||||
|
||||
void MediaSessionPrivate::handleStreamEvents (int streamIndex) {
|
||||
L_Q();
|
||||
MediaStream *ms = (streamIndex == mainAudioStreamIndex) ? &audioStream->ms :
|
||||
(streamIndex == mainVideoStreamIndex ? &videoStream->ms : &textStream->ms);
|
||||
if (ms) {
|
||||
|
|
@ -2272,14 +2297,28 @@ void MediaSessionPrivate::handleStreamEvents (int streamIndex) {
|
|||
stats = videoStats;
|
||||
else
|
||||
stats = textStats;
|
||||
|
||||
OrtpEventType evt = ortp_event_get_type(ev);
|
||||
OrtpEventData *evd = ortp_event_get_data(ev);
|
||||
|
||||
/*This MUST be done before any call to "linphone_call_stats_fill" since it has ownership over evd->packet*/
|
||||
if (evt == ORTP_EVENT_RTCP_PACKET_RECEIVED) {
|
||||
do {
|
||||
if (evd->packet && rtcp_is_RTPFB(evd->packet)) {
|
||||
if (rtcp_RTPFB_get_type(evd->packet) == RTCP_RTPFB_TMMBR) {
|
||||
listener->onTmmbrReceived(q->getSharedFromThis(), streamIndex, (int)rtcp_RTPFB_tmmbr_get_max_bitrate(evd->packet));
|
||||
}
|
||||
}
|
||||
} while (rtcp_next_packet(evd->packet));
|
||||
rtcp_rewind(evd->packet);
|
||||
}
|
||||
|
||||
/* And yes the MediaStream must be taken at each iteration, because it may have changed due to the handling of events
|
||||
* in this loop*/
|
||||
ms = getMediaStream(streamIndex);
|
||||
if (ms)
|
||||
linphone_call_stats_fill(stats, ms, ev);
|
||||
notifyStatsUpdated(streamIndex);
|
||||
OrtpEventType evt = ortp_event_get_type(ev);
|
||||
OrtpEventData *evd = ortp_event_get_data(ev);
|
||||
if (evt == ORTP_EVENT_ZRTP_ENCRYPTION_CHANGED) {
|
||||
if (streamIndex == mainAudioStreamIndex)
|
||||
audioStreamEncryptionChanged(!!evd->info.zrtp_stream_encrypted);
|
||||
|
|
@ -2621,7 +2660,7 @@ void MediaSessionPrivate::startAudioStream (CallSession::State targetState, bool
|
|||
if (playcard) {
|
||||
ms_snd_card_set_stream_type(playcard, MS_SND_CARD_STREAM_VOICE);
|
||||
}
|
||||
|
||||
media_stream_set_max_network_bitrate(&audioStream->ms, linphone_core_get_upload_bandwidth(q->getCore()->getCCore()) * 1000);
|
||||
bool useEc = captcard && linphone_core_echo_cancellation_enabled(q->getCore()->getCCore());
|
||||
audio_stream_enable_echo_canceller(audioStream, useEc);
|
||||
if (playcard && (stream->max_rate > 0))
|
||||
|
|
@ -2860,6 +2899,7 @@ void MediaSessionPrivate::startVideoStream (CallSession::State targetState) {
|
|||
getCurrentParams()->getPrivate()->setUsedVideoCodec(rtp_profile_get_payload(videoProfile, usedPt));
|
||||
getCurrentParams()->enableVideo(true);
|
||||
rtp_session_enable_rtcp_mux(videoStream->ms.sessions.rtp_session, vstream->rtcp_mux);
|
||||
media_stream_set_max_network_bitrate(&videoStream->ms, linphone_core_get_upload_bandwidth(q->getCore()->getCCore()) * 1000);
|
||||
if (q->getCore()->getCCore()->video_conf.preview_vsize.width != 0)
|
||||
video_stream_set_preview_size(videoStream, q->getCore()->getCCore()->video_conf.preview_vsize);
|
||||
video_stream_set_fps(videoStream, linphone_core_get_preferred_framerate(q->getCore()->getCCore()));
|
||||
|
|
@ -3924,7 +3964,7 @@ MediaSession::MediaSession (const shared_ptr<Core> &core, shared_ptr<Participant
|
|||
d->setPortConfig(d->mainTextStreamIndex, make_pair(minPort, maxPort));
|
||||
|
||||
memset(d->sessions, 0, sizeof(d->sessions));
|
||||
d->iceAgent = new IceAgent(*this);
|
||||
d->iceAgent = makeUnique<IceAgent>(*this);
|
||||
|
||||
lInfo() << "New MediaSession [" << this << "] initialized (LinphoneCore version: " << linphone_core_get_version() << ")";
|
||||
}
|
||||
|
|
@ -3942,9 +3982,6 @@ MediaSession::~MediaSession () {
|
|||
linphone_call_stats_unref(d->textStats);
|
||||
if (d->natPolicy)
|
||||
linphone_nat_policy_unref(d->natPolicy);
|
||||
if (d->stunClient)
|
||||
delete d->stunClient;
|
||||
delete d->iceAgent;
|
||||
if (d->localDesc)
|
||||
sal_media_description_unref(d->localDesc);
|
||||
if (d->biggestDesc)
|
||||
|
|
|
|||
107
src/content/content-disposition.cpp
Normal file
107
src/content/content-disposition.cpp
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* content-disposition.cpp
|
||||
* Copyright (C) 2010-2018 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 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "linphone/utils/utils.h"
|
||||
|
||||
#include "content-disposition.h"
|
||||
#include "object/clonable-object-p.h"
|
||||
|
||||
// =============================================================================
|
||||
|
||||
using namespace std;
|
||||
|
||||
LINPHONE_BEGIN_NAMESPACE
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
class ContentDispositionPrivate : public ClonableObjectPrivate {
|
||||
public:
|
||||
string disposition;
|
||||
string parameter;
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
const ContentDisposition ContentDisposition::RecipientList("recipient-list");
|
||||
const ContentDisposition ContentDisposition::RecipientListHistory("recipient-list-history; handling=optional");
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
ContentDisposition::ContentDisposition (const string &disposition) : ClonableObject(*new ContentDispositionPrivate) {
|
||||
L_D();
|
||||
size_t posParam = disposition.find(";");
|
||||
d->disposition = Utils::trim(disposition.substr(0, posParam));
|
||||
if (posParam != string::npos)
|
||||
setParameter(Utils::trim(disposition.substr(posParam + 1)));
|
||||
}
|
||||
|
||||
ContentDisposition::ContentDisposition (const ContentDisposition &other)
|
||||
: ContentDisposition(other.asString()) {}
|
||||
|
||||
ContentDisposition &ContentDisposition::operator= (const ContentDisposition &other) {
|
||||
L_D();
|
||||
if (this != &other) {
|
||||
d->disposition = other.getPrivate()->disposition;
|
||||
setParameter(other.getParameter());
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool ContentDisposition::operator== (const ContentDisposition &other) const {
|
||||
L_D();
|
||||
return d->disposition == other.getPrivate()->disposition
|
||||
&& getParameter() == other.getParameter();
|
||||
}
|
||||
|
||||
bool ContentDisposition::operator!= (const ContentDisposition &other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
bool ContentDisposition::isEmpty () const {
|
||||
L_D();
|
||||
return d->disposition.empty();
|
||||
}
|
||||
|
||||
bool ContentDisposition::isValid () const {
|
||||
L_D();
|
||||
return !d->disposition.empty();
|
||||
}
|
||||
|
||||
const string &ContentDisposition::getParameter () const {
|
||||
L_D();
|
||||
return d->parameter;
|
||||
}
|
||||
|
||||
void ContentDisposition::setParameter (const string ¶meter) {
|
||||
L_D();
|
||||
d->parameter = parameter;
|
||||
}
|
||||
|
||||
string ContentDisposition::asString () const {
|
||||
L_D();
|
||||
if (isValid()) {
|
||||
string asString = d->disposition;
|
||||
if (!d->parameter.empty())
|
||||
asString += ";" + d->parameter;
|
||||
return asString;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
LINPHONE_END_NAMESPACE
|
||||
63
src/content/content-disposition.h
Normal file
63
src/content/content-disposition.h
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* content-disposition.h
|
||||
* Copyright (C) 2010-2018 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 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef _L_CONTENT_DISPOSITION_H_
|
||||
#define _L_CONTENT_DISPOSITION_H_
|
||||
|
||||
#include "object/clonable-object.h"
|
||||
|
||||
// =============================================================================
|
||||
|
||||
LINPHONE_BEGIN_NAMESPACE
|
||||
|
||||
class ContentDispositionPrivate;
|
||||
|
||||
class LINPHONE_PUBLIC ContentDisposition : public ClonableObject {
|
||||
public:
|
||||
explicit ContentDisposition (const std::string &contentDisposition = "");
|
||||
ContentDisposition (const ContentDisposition &other);
|
||||
|
||||
ContentDisposition &operator= (const ContentDisposition &other);
|
||||
|
||||
bool operator== (const ContentDisposition &other) const;
|
||||
bool operator!= (const ContentDisposition &other) const;
|
||||
|
||||
// Delete these operators to prevent putting complicated content-disposition strings
|
||||
// in the code. Instead define static const ContentDisposition objects below.
|
||||
bool operator== (const std::string &other) const = delete;
|
||||
bool operator!= (const std::string &other) const = delete;
|
||||
|
||||
bool isEmpty () const;
|
||||
bool isValid () const;
|
||||
|
||||
const std::string &getParameter () const;
|
||||
void setParameter (const std::string ¶meter);
|
||||
|
||||
std::string asString () const;
|
||||
|
||||
static const ContentDisposition RecipientList;
|
||||
static const ContentDisposition RecipientListHistory;
|
||||
|
||||
private:
|
||||
L_DECLARE_PRIVATE(ContentDisposition);
|
||||
};
|
||||
|
||||
LINPHONE_END_NAMESPACE
|
||||
|
||||
#endif // ifndef _L_CONTENT_DISPOSITION_H_
|
||||
|
|
@ -20,6 +20,7 @@
|
|||
#ifndef _L_CONTENT_P_H_
|
||||
#define _L_CONTENT_P_H_
|
||||
|
||||
#include "content-disposition.h"
|
||||
#include "content-type.h"
|
||||
#include "content.h"
|
||||
#include "object/clonable-object-p.h"
|
||||
|
|
@ -32,7 +33,7 @@ class ContentPrivate : public ClonableObjectPrivate {
|
|||
private:
|
||||
std::vector<char> body;
|
||||
ContentType contentType;
|
||||
std::string contentDisposition;
|
||||
ContentDisposition contentDisposition;
|
||||
std::string contentEncoding;
|
||||
std::list<std::pair<std::string, std::string>> headers;
|
||||
|
||||
|
|
|
|||
|
|
@ -57,20 +57,20 @@ ContentType::ContentType (const string &contentType) : ClonableObject(*new Conte
|
|||
L_D();
|
||||
|
||||
size_t pos = contentType.find('/');
|
||||
size_t posParam = contentType.find("; ");
|
||||
size_t posParam = contentType.find(";");
|
||||
size_t end = contentType.length();
|
||||
if (pos == string::npos)
|
||||
return;
|
||||
|
||||
if (setType(contentType.substr(0, pos))) {
|
||||
if (setType(Utils::trim(contentType.substr(0, pos)))) {
|
||||
if (posParam != string::npos)
|
||||
end = posParam;
|
||||
if (!setSubType(contentType.substr(pos + 1, end - (pos + 1))))
|
||||
if (!setSubType(Utils::trim(contentType.substr(pos + 1, end - (pos + 1)))))
|
||||
d->type.clear();
|
||||
}
|
||||
|
||||
if (posParam != string::npos)
|
||||
setParameter(contentType.substr(posParam + 2)); // We remove the blankspace after the ;.
|
||||
setParameter(Utils::trim(contentType.substr(posParam + 1)));
|
||||
}
|
||||
|
||||
ContentType::ContentType (const string &type, const string &subType) : ClonableObject(*new ContentTypePrivate) {
|
||||
|
|
|
|||
|
|
@ -118,17 +118,12 @@ void Content::setContentType (const ContentType &contentType) {
|
|||
d->contentType = contentType;
|
||||
}
|
||||
|
||||
void Content::setContentType (const string &contentType) {
|
||||
L_D();
|
||||
d->contentType = ContentType(contentType);
|
||||
}
|
||||
|
||||
const string &Content::getContentDisposition () const {
|
||||
const ContentDisposition &Content::getContentDisposition () const {
|
||||
L_D();
|
||||
return d->contentDisposition;
|
||||
}
|
||||
|
||||
void Content::setContentDisposition (const string &contentDisposition) {
|
||||
void Content::setContentDisposition (const ContentDisposition &contentDisposition) {
|
||||
L_D();
|
||||
d->contentDisposition = contentDisposition;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ L_DECL_C_STRUCT(LinphoneContent);
|
|||
|
||||
LINPHONE_BEGIN_NAMESPACE
|
||||
|
||||
class ContentDisposition;
|
||||
class ContentType;
|
||||
class ContentPrivate;
|
||||
|
||||
|
|
@ -49,10 +50,9 @@ public:
|
|||
|
||||
const ContentType &getContentType () const;
|
||||
void setContentType (const ContentType &contentType);
|
||||
void setContentType (const std::string &contentType);
|
||||
|
||||
const std::string &getContentDisposition () const;
|
||||
void setContentDisposition (const std::string &contentDisposition);
|
||||
const ContentDisposition &getContentDisposition () const;
|
||||
void setContentDisposition (const ContentDisposition &contentDisposition);
|
||||
|
||||
const std::string &getContentEncoding () const;
|
||||
void setContentEncoding (const std::string &contentEncoding);
|
||||
|
|
|
|||
|
|
@ -738,4 +738,35 @@ void IceAgent::updateIceStateInCallStatsForStream (LinphoneCallStats *stats, Ice
|
|||
}
|
||||
}
|
||||
|
||||
bool IceAgent::checkIceReinviteNeedsDeferedResponse(SalMediaDescription *md){
|
||||
int i,j;
|
||||
IceCheckList *cl;
|
||||
|
||||
if (!iceSession) return false;
|
||||
|
||||
if (ice_session_state(iceSession) != IS_Running ) return false;
|
||||
|
||||
for (i = 0; i < md->nb_streams; i++) {
|
||||
SalStreamDescription *stream = &md->streams[i];
|
||||
cl = ice_session_check_list(iceSession, i);
|
||||
|
||||
if (cl==NULL) continue;
|
||||
if (stream->ice_mismatch == TRUE) {
|
||||
return false;
|
||||
}
|
||||
if (stream->rtp_port == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ice_check_list_state(cl) != ICL_Running) continue;
|
||||
|
||||
for (j = 0; j < SAL_MEDIA_DESCRIPTION_MAX_ICE_CANDIDATES; j++) {
|
||||
const SalIceRemoteCandidate *remote_candidate = &stream->ice_remote_candidates[j];
|
||||
if (remote_candidate->addr[0] != '\0') return true;
|
||||
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
LINPHONE_END_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -66,6 +66,11 @@ public:
|
|||
void updateFromRemoteMediaDescription (const SalMediaDescription *localDesc, const SalMediaDescription *remoteDesc, bool isOffer);
|
||||
void updateIceStateInCallStats ();
|
||||
void updateLocalMediaDescriptionFromIce (SalMediaDescription *desc);
|
||||
/*
|
||||
* Checks if an incoming offer with ICE needs a delayed answer, because the ice session hasn't completed yet with
|
||||
* connecvity checks.
|
||||
*/
|
||||
bool checkIceReinviteNeedsDeferedResponse(SalMediaDescription *md);
|
||||
|
||||
private:
|
||||
void addLocalIceCandidates (int family, const char *addr, IceCheckList *audioCl, IceCheckList *videoCl, IceCheckList *textCl);
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
#include <bctoolbox/defs.h>
|
||||
#include <belle-sip/provider.h>
|
||||
|
||||
#include "content/content-disposition.h"
|
||||
#include "content/content-type.h"
|
||||
|
||||
using namespace std;
|
||||
|
|
@ -102,7 +103,7 @@ belle_sip_header_allow_t *SalCallOp::create_allow(bool_t enable_update) {
|
|||
|
||||
int SalCallOp::set_custom_body(belle_sip_message_t *msg, const Content &body) {
|
||||
ContentType contentType = body.getContentType();
|
||||
string contentDisposition = body.getContentDisposition();
|
||||
auto contentDisposition = body.getContentDisposition();
|
||||
string contentEncoding = body.getContentEncoding();
|
||||
size_t bodySize = body.getBody().size();
|
||||
|
||||
|
|
@ -115,8 +116,10 @@ int SalCallOp::set_custom_body(belle_sip_message_t *msg, const Content &body) {
|
|||
belle_sip_header_content_type_t *content_type = belle_sip_header_content_type_create(contentType.getType().c_str(), contentType.getSubType().c_str());
|
||||
belle_sip_message_add_header(msg, BELLE_SIP_HEADER(content_type));
|
||||
}
|
||||
if (!contentDisposition.empty()) {
|
||||
belle_sip_header_content_disposition_t *contentDispositionHeader = belle_sip_header_content_disposition_create(contentDisposition.c_str());
|
||||
if (contentDisposition.isValid()) {
|
||||
belle_sip_header_content_disposition_t *contentDispositionHeader = belle_sip_header_content_disposition_create(
|
||||
contentDisposition.asString().c_str()
|
||||
);
|
||||
belle_sip_message_add_header(msg, BELLE_SIP_HEADER(contentDispositionHeader));
|
||||
}
|
||||
if (!contentEncoding.empty())
|
||||
|
|
@ -243,7 +246,9 @@ Content SalCallOp::extract_body(belle_sip_message_t *message) {
|
|||
|
||||
if (type_str && subtype_str) body.setContentType(ContentType(type_str, subtype_str));
|
||||
if (contentDisposition)
|
||||
body.setContentDisposition(belle_sip_header_content_disposition_get_content_disposition(contentDisposition));
|
||||
body.setContentDisposition(
|
||||
ContentDisposition(belle_sip_header_content_disposition_get_content_disposition(contentDisposition))
|
||||
);
|
||||
if (length > 0 && body_str) body.setBody(body_str, length);
|
||||
return body;
|
||||
}
|
||||
|
|
@ -1115,9 +1120,15 @@ int SalCallOp::update(const char *subject, bool_t no_user_consent) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
void SalCallOp::cancel_invite_with_info(const SalErrorInfo *info) {
|
||||
int SalCallOp::cancel_invite_with_info(const SalErrorInfo *info) {
|
||||
belle_sip_request_t* cancel;
|
||||
ms_message("Cancelling INVITE request from [%s] to [%s] ",get_from(), get_to());
|
||||
|
||||
if (this->pending_client_trans == NULL){
|
||||
ms_warning("There is no transaction to cancel.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
cancel = belle_sip_client_transaction_create_cancel(this->pending_client_trans);
|
||||
if (cancel){
|
||||
if (info != NULL){
|
||||
|
|
@ -1125,6 +1136,7 @@ void SalCallOp::cancel_invite_with_info(const SalErrorInfo *info) {
|
|||
belle_sip_message_add_header(BELLE_SIP_MESSAGE(cancel),BELLE_SIP_HEADER(reason));
|
||||
}
|
||||
send_request(cancel);
|
||||
return 0;
|
||||
}else if (this->dialog){
|
||||
belle_sip_dialog_state_t state = belle_sip_dialog_get_state(this->dialog);;
|
||||
/*case where the response received is invalid (could not establish a dialog), but the transaction is not cancellable
|
||||
|
|
@ -1140,6 +1152,7 @@ void SalCallOp::cancel_invite_with_info(const SalErrorInfo *info) {
|
|||
break;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
SalMediaDescription *SalCallOp::get_final_media_description() {
|
||||
|
|
|
|||
|
|
@ -45,8 +45,8 @@ public:
|
|||
int decline(SalReason reason, const char *redirection /*optional*/);
|
||||
int decline_with_error_info(const SalErrorInfo *info, const SalAddress *redirectionAddr /*optional*/);
|
||||
int update(const char *subject, bool_t no_user_consent);
|
||||
void cancel_invite() {cancel_invite_with_info(NULL);}
|
||||
void cancel_invite_with_info(const SalErrorInfo *info);
|
||||
int cancel_invite() { return cancel_invite_with_info(NULL);}
|
||||
int cancel_invite_with_info(const SalErrorInfo *info);
|
||||
int refer(const char *refer_to_);
|
||||
int refer_with_replaces(SalCallOp *other_call_op);
|
||||
int set_referer(SalCallOp *refered_call);
|
||||
|
|
|
|||
|
|
@ -118,7 +118,6 @@ void Sal::process_request_event_cb (void *ud, const belle_sip_request_event_t *e
|
|||
op->fill_cbs();
|
||||
}else if (strcmp("REFER",method)==0) {
|
||||
op=new SalReferOp(sal);
|
||||
op->fill_cbs();
|
||||
}else if (strcmp("OPTIONS",method)==0) {
|
||||
resp=belle_sip_response_create_from_request(req,200);
|
||||
belle_sip_provider_send_response(sal->prov,resp);
|
||||
|
|
|
|||
|
|
@ -175,6 +175,12 @@ char *Utils::utf8ToChar (uint32_t ic) {
|
|||
return result;
|
||||
}
|
||||
|
||||
string Utils::trim (const string &str) {
|
||||
auto itFront = find_if_not(str.begin(), str.end(), [] (int c) { return isspace(c); });
|
||||
auto itBack = find_if_not(str.rbegin(), str.rend(), [] (int c) { return isspace(c); }).base();
|
||||
return (itBack <= itFront ? string() : string(itFront, itBack));
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
tm Utils::getTimeTAsTm (time_t time) {
|
||||
|
|
|
|||
|
|
@ -30,7 +30,17 @@
|
|||
#define unlink _unlink
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* With IPV6, Flexisip automatically switches to TCP, so it's no more possible to really have Laure configured with UDP
|
||||
* Anyway for IPV4, it's still a good opportunity to test UDP.
|
||||
*/
|
||||
static const char* get_laure_rc(void) {
|
||||
if (liblinphone_tester_ipv6_available()) {
|
||||
return "laure_tcp_rc";
|
||||
} else {
|
||||
return "laure_rc_udp";
|
||||
}
|
||||
}
|
||||
static void call_waiting_indication_with_param(bool_t enable_caller_privacy) {
|
||||
bctbx_list_t *iterator;
|
||||
bctbx_list_t* lcs;
|
||||
|
|
@ -45,7 +55,7 @@ static void call_waiting_indication_with_param(bool_t enable_caller_privacy) {
|
|||
linphone_core_remove_supported_tag(pauline->lc,"gruu");
|
||||
linphone_core_manager_start(pauline,TRUE);
|
||||
LinphoneCoreManager *laure = ms_new0(LinphoneCoreManager, 1);
|
||||
linphone_core_manager_init(laure, "laure_rc_udp", NULL);
|
||||
linphone_core_manager_init(laure, get_laure_rc(), NULL);
|
||||
linphone_core_remove_supported_tag(laure->lc,"gruu");
|
||||
linphone_core_manager_start(laure, TRUE);
|
||||
LinphoneCallParams *laure_params=linphone_core_create_call_params(laure->lc, NULL);
|
||||
|
|
@ -187,7 +197,7 @@ static void second_call_allowed_if_not_using_audio(void){
|
|||
static void incoming_call_accepted_when_outgoing_call_in_state(LinphoneCallState state) {
|
||||
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");
|
||||
LinphoneCoreManager* laure = linphone_core_manager_new( get_laure_rc());
|
||||
bctbx_list_t* lcs;
|
||||
LinphoneCallParams *laure_params=linphone_core_create_call_params(laure->lc, NULL);
|
||||
LinphoneCallParams *marie_params=linphone_core_create_call_params(marie->lc, NULL);
|
||||
|
|
@ -385,7 +395,7 @@ end:
|
|||
static void simple_conference(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");
|
||||
LinphoneCoreManager* laure = linphone_core_manager_new( get_laure_rc());
|
||||
simple_conference_base(marie,pauline,laure, NULL, FALSE);
|
||||
linphone_core_manager_destroy(marie);
|
||||
linphone_core_manager_destroy(pauline);
|
||||
|
|
@ -396,7 +406,7 @@ static void simple_conference(void) {
|
|||
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");
|
||||
LinphoneCoreManager* laure = linphone_core_manager_new( get_laure_rc());
|
||||
LinphoneConference *conf;
|
||||
LinphoneConferenceParams *conf_params;
|
||||
LinphoneCall *pauline_call, *laure_call;
|
||||
|
|
@ -469,7 +479,7 @@ static void simple_conference_from_scratch(void){
|
|||
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");
|
||||
LinphoneCoreManager* laure = linphone_core_manager_new( "laure_rc_udp");
|
||||
LinphoneCoreManager* laure = linphone_core_manager_new( get_laure_rc());
|
||||
|
||||
if (linphone_core_media_encryption_supported(marie->lc,mode)) {
|
||||
linphone_core_set_firewall_policy(marie->lc,LinphonePolicyUseIce);
|
||||
|
|
@ -504,7 +514,7 @@ static void simple_zrtp_conference_with_ice(void) {
|
|||
static void conference_hang_up_call_on_hold(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");
|
||||
LinphoneCoreManager* laure = linphone_core_manager_new(get_laure_rc());
|
||||
simple_conference_base(marie, pauline, laure, NULL, TRUE);
|
||||
linphone_core_manager_destroy(marie);
|
||||
linphone_core_manager_destroy(pauline);
|
||||
|
|
@ -514,7 +524,7 @@ static void conference_hang_up_call_on_hold(void) {
|
|||
static void simple_call_transfer(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");
|
||||
LinphoneCoreManager* laure = linphone_core_manager_new( get_laure_rc());
|
||||
LinphoneCall* pauline_called_by_marie;
|
||||
LinphoneCall *marie_calling_pauline;
|
||||
LinphoneCall *marie_calling_laure;
|
||||
|
|
@ -579,7 +589,7 @@ end:
|
|||
static void unattended_call_transfer(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");
|
||||
LinphoneCoreManager* laure = linphone_core_manager_new( get_laure_rc());
|
||||
LinphoneCall* pauline_called_by_marie;
|
||||
|
||||
char* laure_identity=linphone_address_as_string(laure->identity);
|
||||
|
|
@ -668,7 +678,7 @@ static void unattended_call_transfer_with_error(void) {
|
|||
static void call_transfer_existing_call(bool_t outgoing_call) {
|
||||
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");
|
||||
LinphoneCoreManager* laure = linphone_core_manager_new( get_laure_rc());
|
||||
LinphoneCall* marie_call_pauline;
|
||||
LinphoneCall* pauline_called_by_marie;
|
||||
LinphoneCall* marie_call_laure;
|
||||
|
|
@ -768,7 +778,7 @@ static void call_transfer_existing_call_incoming_call(void) {
|
|||
static void call_transfer_existing_ringing_call(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");
|
||||
LinphoneCoreManager *laure = linphone_core_manager_new(get_laure_rc());
|
||||
LinphoneCall *marie_call_pauline;
|
||||
LinphoneCall *pauline_called_by_marie;
|
||||
LinphoneCall *marie_call_laure;
|
||||
|
|
@ -934,7 +944,7 @@ end:
|
|||
static void eject_from_3_participants_local_conference(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");
|
||||
LinphoneCoreManager* laure = linphone_core_manager_new( get_laure_rc());
|
||||
|
||||
eject_from_3_participants_conference(marie, pauline, laure, NULL);
|
||||
|
||||
|
|
@ -946,7 +956,7 @@ static void eject_from_3_participants_local_conference(void) {
|
|||
static void eject_from_4_participants_conference(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");
|
||||
LinphoneCoreManager* laure = linphone_core_manager_new( get_laure_rc());
|
||||
LinphoneCoreManager* michelle = linphone_core_manager_new( "michelle_rc_udp");
|
||||
int timeout_ms = 5000;
|
||||
stats initial_laure_stat;
|
||||
|
|
@ -1038,7 +1048,7 @@ end:
|
|||
void simple_remote_conference(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");
|
||||
LinphoneCoreManager *laure = linphone_core_manager_new(get_laure_rc());
|
||||
LinphoneConferenceServer *focus = linphone_conference_server_new("conference_focus_rc", TRUE);
|
||||
LpConfig *marie_config = linphone_core_get_config(marie->lc);
|
||||
LinphoneProxyConfig *focus_proxy_config = linphone_core_get_default_proxy_config(((LinphoneCoreManager *)focus)->lc);
|
||||
|
|
@ -1064,7 +1074,7 @@ void simple_remote_conference(void) {
|
|||
void simple_remote_conference_shut_down_focus(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");
|
||||
LinphoneCoreManager *laure = linphone_core_manager_new(get_laure_rc());
|
||||
LinphoneConferenceServer *focus = linphone_conference_server_new("conference_focus_rc", FALSE);
|
||||
LpConfig *marie_config = linphone_core_get_config(marie->lc);
|
||||
LinphoneProxyConfig *focus_proxy_config = linphone_core_get_default_proxy_config(((LinphoneCoreManager *)focus)->lc);
|
||||
|
|
@ -1090,7 +1100,7 @@ void simple_remote_conference_shut_down_focus(void) {
|
|||
void eject_from_3_participants_remote_conference(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");
|
||||
LinphoneCoreManager* laure = linphone_core_manager_new( get_laure_rc());
|
||||
LinphoneConferenceServer *focus = linphone_conference_server_new("conference_focus_rc", TRUE);
|
||||
LpConfig *marie_config = linphone_core_get_config(marie->lc);
|
||||
LinphoneProxyConfig *focus_proxy_config = linphone_core_get_default_proxy_config(((LinphoneCoreManager *)focus)->lc);
|
||||
|
|
@ -1116,7 +1126,7 @@ void eject_from_3_participants_remote_conference(void) {
|
|||
void do_not_stop_ringing_when_declining_one_of_two_incoming_calls(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");
|
||||
LinphoneCoreManager* laure = linphone_core_manager_new( get_laure_rc());
|
||||
LinphoneCall* pauline_called_by_marie;
|
||||
LinphoneCall* pauline_called_by_laure;
|
||||
LinphoneCallParams *laure_params=linphone_core_create_call_params(laure->lc, NULL);
|
||||
|
|
|
|||
|
|
@ -2008,6 +2008,70 @@ static void video_call_with_thin_congestion(void){
|
|||
linphone_core_manager_destroy(pauline);
|
||||
}
|
||||
|
||||
static void on_tmmbr_received(LinphoneCall *call, int stream_index, int tmmbr) {
|
||||
if (stream_index == _linphone_call_get_main_video_stream_index(call)) {
|
||||
stats* stat = get_stats(linphone_call_get_core(call));
|
||||
stat->tmmbr_received_from_cb = tmmbr;
|
||||
}
|
||||
}
|
||||
|
||||
static void call_created(LinphoneCore *lc, LinphoneCall *call) {
|
||||
LinphoneCallCbs *cbs = linphone_factory_create_call_cbs(linphone_factory_get());
|
||||
linphone_call_cbs_set_tmmbr_received(cbs, on_tmmbr_received);
|
||||
linphone_call_add_callbacks(call, cbs);
|
||||
linphone_call_cbs_unref(cbs);
|
||||
}
|
||||
|
||||
/*
|
||||
* This test simulates a higher bandwith available from marie than expected.
|
||||
* The stream from pauline to marie is not under test.
|
||||
* It checks that after a few seconds marie received a TMMBR with the approximate value corresponding to the new bandwidth.
|
||||
*
|
||||
**/
|
||||
static void video_call_with_high_bandwidth_available(void) {
|
||||
LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc");
|
||||
LinphoneCoreManager *pauline = linphone_core_manager_new("pauline_rc");
|
||||
LinphoneVideoPolicy pol = {0};
|
||||
OrtpNetworkSimulatorParams simparams = { 0 };
|
||||
LinphoneCoreCbs *core_cbs = linphone_factory_create_core_cbs(linphone_factory_get());
|
||||
|
||||
linphone_core_set_video_device(marie->lc, "Mire: Mire (synthetic moving picture)");
|
||||
linphone_core_enable_video_capture(marie->lc, TRUE);
|
||||
linphone_core_enable_video_display(marie->lc, TRUE);
|
||||
linphone_core_enable_video_capture(pauline->lc, TRUE);
|
||||
linphone_core_enable_video_display(pauline->lc, TRUE);
|
||||
|
||||
pol.automatically_accept = TRUE;
|
||||
pol.automatically_initiate = TRUE;
|
||||
linphone_core_set_video_policy(marie->lc, &pol);
|
||||
linphone_core_set_video_policy(pauline->lc, &pol);
|
||||
|
||||
linphone_core_set_preferred_video_size_by_name(marie->lc, "vga");
|
||||
simparams.mode = OrtpNetworkSimulatorOutbound;
|
||||
simparams.enabled = TRUE;
|
||||
simparams.max_bandwidth = 1000000;
|
||||
simparams.max_buffer_size = (int)simparams.max_bandwidth;
|
||||
simparams.latency = 60;
|
||||
|
||||
linphone_core_set_network_simulator_params(marie->lc, &simparams);
|
||||
|
||||
linphone_core_cbs_set_call_created(core_cbs, call_created);
|
||||
linphone_core_add_callbacks(marie->lc, core_cbs);
|
||||
|
||||
if (BC_ASSERT_TRUE(call(marie, pauline))){
|
||||
/*wait a little in order to have traffic*/
|
||||
BC_ASSERT_TRUE(wait_for_until(marie->lc, pauline->lc, NULL, 5, 50000));
|
||||
|
||||
BC_ASSERT_GREATER((float)marie->stat.last_tmmbr_value_received, 870000.f, float, "%f");
|
||||
BC_ASSERT_LOWER((float)marie->stat.last_tmmbr_value_received, 1150000.f, float, "%f");
|
||||
|
||||
end_call(marie, pauline);
|
||||
}
|
||||
linphone_core_cbs_unref(core_cbs);
|
||||
linphone_core_manager_destroy(marie);
|
||||
linphone_core_manager_destroy(pauline);
|
||||
}
|
||||
|
||||
test_t call_video_tests[] = {
|
||||
#ifdef VIDEO_ENABLED
|
||||
TEST_NO_TAG("Call paused resumed with video", call_paused_resumed_with_video),
|
||||
|
|
@ -2073,10 +2137,11 @@ test_t call_video_tests[] = {
|
|||
TEST_NO_TAG("Classic video entry phone setup", classic_video_entry_phone_setup),
|
||||
TEST_NO_TAG("Incoming REINVITE with invalid SDP in ACK", incoming_reinvite_with_invalid_ack_sdp),
|
||||
TEST_NO_TAG("Outgoing REINVITE with invalid SDP in ACK", outgoing_reinvite_with_invalid_ack_sdp),
|
||||
#endif
|
||||
TEST_NO_TAG("Video call with no audio and no video codec", video_call_with_no_audio_and_no_video_codec),
|
||||
TEST_NO_TAG("Call with early media and no SDP in 200 Ok with video", call_with_early_media_and_no_sdp_in_200_with_video),
|
||||
TEST_NO_TAG("Video call with thin congestion", video_call_with_thin_congestion)
|
||||
TEST_NO_TAG("Video call with thin congestion", video_call_with_thin_congestion),
|
||||
TEST_NO_TAG("Video call with high bandwidth available", video_call_with_high_bandwidth_available)
|
||||
#endif
|
||||
};
|
||||
|
||||
test_suite_t call_video_test_suite = {"Video Call", NULL, NULL, liblinphone_tester_before_each, liblinphone_tester_after_each,
|
||||
|
|
|
|||
|
|
@ -1388,7 +1388,7 @@ static void on_refer_received(SalOp *op, const SalAddress *refer_to) {
|
|||
Sal *sal = sal_op_get_sal(op);
|
||||
LinphoneCoreManager *receiver = (LinphoneCoreManager*)sal_get_user_pointer(sal);
|
||||
receiver->stat.number_of_LinphoneCallRefered++;
|
||||
sal_release_op(op);
|
||||
|
||||
}
|
||||
|
||||
void resend_refer_other_devices(void) {
|
||||
|
|
|
|||
|
|
@ -2874,7 +2874,6 @@ static void group_chat_room_unique_one_to_one_chat_room_recreated_from_message_2
|
|||
linphone_core_manager_destroy(pauline2);
|
||||
}
|
||||
|
||||
|
||||
static void group_chat_room_join_one_to_one_chat_room_with_a_new_device (void) {
|
||||
LinphoneCoreManager *marie1 = linphone_core_manager_create("marie_rc");
|
||||
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc");
|
||||
|
|
@ -2925,16 +2924,11 @@ static void group_chat_room_join_one_to_one_chat_room_with_a_new_device (void) {
|
|||
coresManagerList = bctbx_list_concat(coresManagerList, newCoresManagerList);
|
||||
coresList = bctbx_list_concat(coresList, newCoresList);
|
||||
|
||||
// Marie2 creates a new one-to-one chat room with Pauline
|
||||
// Marie2 gets the one-to-one chat room with Pauline
|
||||
stats initialMarie2Stats = marie2->stat;
|
||||
participantsAddresses = bctbx_list_append(NULL, linphone_address_new(linphone_core_get_identity(pauline->lc)));
|
||||
LinphoneChatRoom *marie2Cr = create_chat_room_client_side(coresList, marie2, &initialMarie2Stats, participantsAddresses, initialSubject, -1);
|
||||
LinphoneChatRoom *marie2Cr = check_creation_chat_room_client_side(coresList, marie2, &initialMarie2Stats, confAddr, initialSubject, 1, FALSE);
|
||||
BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(marie2Cr) & LinphoneChatRoomCapabilitiesOneToOne);
|
||||
|
||||
// Check that the created address is the same as before
|
||||
const LinphoneAddress *newConfAddr = linphone_chat_room_get_conference_address(marie2Cr);
|
||||
BC_ASSERT_TRUE(linphone_address_weak_equal(confAddr, newConfAddr));
|
||||
|
||||
// Marie2 sends a new message
|
||||
textMessage = "Fine and you?";
|
||||
message = _send_message(marie2Cr, textMessage);
|
||||
|
|
@ -3179,6 +3173,65 @@ static void find_one_to_one_chat_room (void) {
|
|||
linphone_core_manager_destroy(chloe);
|
||||
}
|
||||
|
||||
static void group_chat_room_new_device_after_creation (void) {
|
||||
LinphoneCoreManager *marie1 = linphone_core_manager_create("marie_rc");
|
||||
LinphoneCoreManager *pauline1 = linphone_core_manager_create("pauline_rc");
|
||||
LinphoneCoreManager *pauline2 = linphone_core_manager_create("pauline_rc");
|
||||
LinphoneCoreManager *laure = linphone_core_manager_create("laure_tcp_rc");
|
||||
bctbx_list_t *coresManagerList = NULL;
|
||||
bctbx_list_t *participantsAddresses = NULL;
|
||||
coresManagerList = bctbx_list_append(coresManagerList, marie1);
|
||||
coresManagerList = bctbx_list_append(coresManagerList, pauline1);
|
||||
coresManagerList = bctbx_list_append(coresManagerList, pauline2);
|
||||
coresManagerList = bctbx_list_append(coresManagerList, laure);
|
||||
bctbx_list_t *coresList = init_core_for_conference(coresManagerList);
|
||||
start_core_for_conference(coresManagerList);
|
||||
participantsAddresses = bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline1->lc)));
|
||||
participantsAddresses = bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(laure->lc)));
|
||||
stats initialMarie1Stats = marie1->stat;
|
||||
stats initialPauline1Stats = pauline1->stat;
|
||||
stats initialPauline2Stats = pauline2->stat;
|
||||
stats initialLaureStats = laure->stat;
|
||||
|
||||
// Marie creates a new group chat room
|
||||
const char *initialSubject = "Colleagues";
|
||||
LinphoneChatRoom *marie1Cr = create_chat_room_client_side(coresList, marie1, &initialMarie1Stats, participantsAddresses, initialSubject, -1);
|
||||
participantsAddresses = NULL;
|
||||
const LinphoneAddress *confAddr = linphone_chat_room_get_conference_address(marie1Cr);
|
||||
|
||||
// Check that the chat room is correctly created on Pauline1 and Pauline2's sides and that the participants are added
|
||||
LinphoneChatRoom *pauline1Cr = check_creation_chat_room_client_side(coresList, pauline1, &initialPauline1Stats, confAddr, initialSubject, 2, FALSE);
|
||||
LinphoneChatRoom *pauline2Cr = check_creation_chat_room_client_side(coresList, pauline2, &initialPauline2Stats, confAddr, initialSubject, 2, FALSE);
|
||||
|
||||
// Check that the chat room is correctly created on Laure's side and that the participants are added
|
||||
LinphoneChatRoom *laureCr = check_creation_chat_room_client_side(coresList, laure, &initialLaureStats, confAddr, initialSubject, 2, FALSE);
|
||||
|
||||
// Marie adds a new device
|
||||
LinphoneCoreManager *marie2 = linphone_core_manager_create("marie_rc");
|
||||
stats initialMarie2Stats = marie2->stat;
|
||||
bctbx_list_t *tmpCoresManagerList = bctbx_list_append(NULL, marie2);
|
||||
bctbx_list_t *tmpCoresList = init_core_for_conference(tmpCoresManagerList);
|
||||
coresList = bctbx_list_concat(coresList, tmpCoresList);
|
||||
start_core_for_conference(tmpCoresManagerList);
|
||||
bctbx_list_free(tmpCoresManagerList);
|
||||
LinphoneChatRoom *marie2Cr = check_creation_chat_room_client_side(coresList, marie2, &initialMarie2Stats, confAddr, initialSubject, 2, TRUE);
|
||||
|
||||
// Clean db from chat room
|
||||
linphone_core_manager_delete_chat_room(marie1, marie1Cr, coresList);
|
||||
linphone_core_delete_chat_room(marie2->lc, marie2Cr);
|
||||
linphone_core_manager_delete_chat_room(pauline1, pauline1Cr, coresList);
|
||||
linphone_core_delete_chat_room(pauline2->lc, pauline2Cr);
|
||||
linphone_core_manager_delete_chat_room(laure, laureCr, coresList);
|
||||
|
||||
bctbx_list_free(coresList);
|
||||
bctbx_list_free(coresManagerList);
|
||||
linphone_core_manager_destroy(marie1);
|
||||
linphone_core_manager_destroy(marie2);
|
||||
linphone_core_manager_destroy(pauline1);
|
||||
linphone_core_manager_destroy(pauline2);
|
||||
linphone_core_manager_destroy(laure);
|
||||
}
|
||||
|
||||
test_t group_chat_tests[] = {
|
||||
TEST_NO_TAG("Group chat room creation server", group_chat_room_creation_server),
|
||||
TEST_ONE_TAG("Add participant", group_chat_room_add_participant, "LeaksMemory"),
|
||||
|
|
@ -3222,7 +3275,8 @@ test_t group_chat_tests[] = {
|
|||
TEST_NO_TAG("New unique one-to-one chatroom after both participants left", group_chat_room_new_unique_one_to_one_chat_room_after_both_participants_left),
|
||||
TEST_NO_TAG("Unique one-to-one chatroom re-created from the party that deleted it, with inactive devices", group_chat_room_unique_one_to_one_chat_room_recreated_from_message_2),
|
||||
TEST_NO_TAG("IMDN for group chat room", imdn_for_group_chat_room),
|
||||
TEST_NO_TAG("Find one to one chat room", find_one_to_one_chat_room)
|
||||
TEST_NO_TAG("Find one to one chat room", find_one_to_one_chat_room),
|
||||
TEST_NO_TAG("New device after group chat room creation", group_chat_room_new_device_after_creation)
|
||||
};
|
||||
|
||||
test_suite_t group_chat_test_suite = {
|
||||
|
|
|
|||
|
|
@ -283,6 +283,7 @@ typedef struct _stats {
|
|||
int number_of_rtcp_generic_nack;
|
||||
int number_of_tmmbr_received;
|
||||
int last_tmmbr_value_received;
|
||||
int tmmbr_received_from_cb;
|
||||
|
||||
int number_of_participants_added;
|
||||
int number_of_participant_admin_statuses_changed;
|
||||
|
|
|
|||
|
|
@ -28,9 +28,14 @@
|
|||
#include <zlib.h>
|
||||
#endif
|
||||
|
||||
#ifdef __ANDROID__
|
||||
#include "android/api-level.h"
|
||||
#endif
|
||||
|
||||
/*getline is POSIX 2008, not available on many systems.*/
|
||||
#if (defined(__ANDROID__) && !defined(__LP64__)) || defined(_WIN32) || defined(__QNX__)
|
||||
|
||||
/*It is declared since NDK14 unified headers, that can be detected by the presence of __ANDROID_API_O__ define*/
|
||||
#if (defined(__ANDROID__) && __ANDROID_API__ <= 16) || defined(_WIN32) || defined(__QNX__)
|
||||
/* This code is public domain -- Will Hartung 4/9/09 */
|
||||
static ssize_t getline(char **lineptr, size_t *n, FILE *stream) {
|
||||
char *bufptr = NULL;
|
||||
|
|
|
|||
|
|
@ -503,9 +503,13 @@ void transfer_message_base2(LinphoneCoreManager* marie, LinphoneCoreManager* pau
|
|||
} else {
|
||||
BC_ASSERT_TRUE(wait_for_until(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceivedWithFile,1, 60000));
|
||||
if (marie->stat.last_received_chat_message) {
|
||||
LinphoneChatRoom *marie_room = linphone_core_get_chat_room(marie->lc, pauline->identity);
|
||||
linphone_chat_room_mark_as_read(marie_room);
|
||||
// We shoudln't get displayed IMDN until file has been downloaded
|
||||
BC_ASSERT_FALSE(wait_for_until(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneMessageDisplayed,1, 5000));
|
||||
|
||||
LinphoneChatMessage *recv_msg;
|
||||
if (download_from_history) {
|
||||
LinphoneChatRoom *marie_room = linphone_core_get_chat_room(marie->lc, pauline->identity);
|
||||
msg_list = linphone_chat_room_get_history(marie_room,1);
|
||||
BC_ASSERT_PTR_NOT_NULL(msg_list);
|
||||
if (!msg_list) goto end;
|
||||
|
|
@ -529,12 +533,13 @@ void transfer_message_base2(LinphoneCoreManager* marie, LinphoneCoreManager* pau
|
|||
belle_http_provider_set_recv_error(linphone_core_get_http_provider(marie->lc), -1);
|
||||
BC_ASSERT_TRUE(wait_for_until(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneMessageNotDelivered,1, 10000));
|
||||
belle_http_provider_set_recv_error(linphone_core_get_http_provider(marie->lc), 0);
|
||||
BC_ASSERT_FALSE(wait_for_until(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneMessageDisplayed,1, 5000));
|
||||
} else {
|
||||
/* wait for a long time in case the DNS SRV resolution takes times - it should be immediate though */
|
||||
if (BC_ASSERT_TRUE(wait_for_until(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneFileTransferDownloadSuccessful,1,55000))) {
|
||||
compare_files(send_filepath, receive_filepath);
|
||||
|
||||
}
|
||||
BC_ASSERT_TRUE(wait_for_until(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneMessageDisplayed,1, 5000));
|
||||
}
|
||||
}
|
||||
BC_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageInProgress,2, int, "%d"); //sent twice because of file transfer
|
||||
|
|
@ -549,41 +554,48 @@ end:
|
|||
}
|
||||
|
||||
void transfer_message_base(bool_t upload_error, bool_t download_error, bool_t use_file_body_handler_in_upload,
|
||||
bool_t use_file_body_handler_in_download, bool_t download_from_history) {
|
||||
bool_t use_file_body_handler_in_download, bool_t download_from_history, bool_t enable_imdn) {
|
||||
if (transport_supported(LinphoneTransportTls)) {
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc");
|
||||
|
||||
if (enable_imdn) {
|
||||
lp_config_set_int(linphone_core_get_config(pauline->lc), "sip", "deliver_imdn", 1);
|
||||
lp_config_set_int(linphone_core_get_config(marie->lc), "sip", "deliver_imdn", 1);
|
||||
linphone_im_notif_policy_enable_all(linphone_core_get_im_notif_policy(marie->lc));
|
||||
linphone_im_notif_policy_enable_all(linphone_core_get_im_notif_policy(pauline->lc));
|
||||
}
|
||||
transfer_message_base2(marie,pauline,upload_error,download_error, use_file_body_handler_in_upload, use_file_body_handler_in_download, download_from_history);
|
||||
linphone_core_manager_destroy(pauline);
|
||||
linphone_core_manager_destroy(marie);
|
||||
}
|
||||
}
|
||||
static void transfer_message(void) {
|
||||
transfer_message_base(FALSE, FALSE, FALSE, FALSE, FALSE);
|
||||
transfer_message_base(FALSE, FALSE, FALSE, FALSE, FALSE, TRUE);
|
||||
}
|
||||
|
||||
static void transfer_message_2(void) {
|
||||
transfer_message_base(FALSE, FALSE, TRUE, FALSE, FALSE);
|
||||
transfer_message_base(FALSE, FALSE, TRUE, FALSE, FALSE, TRUE);
|
||||
}
|
||||
|
||||
static void transfer_message_3(void) {
|
||||
transfer_message_base(FALSE, FALSE, FALSE, TRUE, FALSE);
|
||||
transfer_message_base(FALSE, FALSE, FALSE, TRUE, FALSE, TRUE);
|
||||
}
|
||||
|
||||
static void transfer_message_4(void) {
|
||||
transfer_message_base(FALSE, FALSE, TRUE, TRUE, FALSE);
|
||||
transfer_message_base(FALSE, FALSE, TRUE, TRUE, FALSE, TRUE);
|
||||
}
|
||||
|
||||
static void transfer_message_from_history(void) {
|
||||
transfer_message_base(FALSE, FALSE, TRUE, TRUE, TRUE);
|
||||
transfer_message_base(FALSE, FALSE, TRUE, TRUE, TRUE, TRUE);
|
||||
}
|
||||
|
||||
static void transfer_message_with_upload_io_error(void) {
|
||||
transfer_message_base(TRUE, FALSE, FALSE, FALSE, FALSE);
|
||||
transfer_message_base(TRUE, FALSE, FALSE, FALSE, FALSE, TRUE);
|
||||
}
|
||||
|
||||
static void transfer_message_with_download_io_error(void) {
|
||||
transfer_message_base(FALSE, TRUE, FALSE, FALSE, FALSE);
|
||||
transfer_message_base(FALSE, TRUE, FALSE, FALSE, FALSE, TRUE);
|
||||
}
|
||||
|
||||
static void transfer_message_upload_cancelled(void) {
|
||||
|
|
@ -730,6 +742,52 @@ static void file_transfer_2_messages_simultaneously(void) {
|
|||
}
|
||||
}
|
||||
|
||||
static void file_transfer_external_body_url(bool_t use_file_body_handler_in_download) {
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc");
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc");
|
||||
LinphoneChatRoom* chat_room = linphone_core_get_chat_room(marie->lc, pauline->identity);
|
||||
LinphoneChatMessage* msg = linphone_chat_room_create_message(chat_room, NULL);
|
||||
LinphoneChatMessageCbs *cbs = linphone_chat_message_get_callbacks(msg);
|
||||
char *receive_filepath = bc_tester_file("receive_file.dump");
|
||||
|
||||
linphone_chat_message_set_external_body_url(msg, "https://www.linphone.org/img/linphone-open-source-voip-projectX2.png");
|
||||
linphone_chat_message_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed);
|
||||
linphone_chat_room_send_chat_message(chat_room, msg);
|
||||
linphone_chat_message_unref(msg);
|
||||
|
||||
BC_ASSERT_TRUE(wait_for_until(pauline->lc, marie->lc, &pauline->stat.number_of_LinphoneMessageReceivedWithFile, 1, 60000));
|
||||
|
||||
if (pauline->stat.last_received_chat_message) {
|
||||
LinphoneChatMessage *recv_msg = pauline->stat.last_received_chat_message;
|
||||
cbs = linphone_chat_message_get_callbacks(recv_msg);
|
||||
linphone_chat_message_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed);
|
||||
linphone_chat_message_cbs_set_file_transfer_recv(cbs, file_transfer_received);
|
||||
linphone_chat_message_cbs_set_file_transfer_progress_indication(cbs, file_transfer_progress_indication);
|
||||
if (use_file_body_handler_in_download) {
|
||||
/* Remove any previously downloaded file */
|
||||
remove(receive_filepath);
|
||||
linphone_chat_message_set_file_transfer_filepath(recv_msg, receive_filepath);
|
||||
}
|
||||
linphone_chat_message_download_file(recv_msg);
|
||||
|
||||
/* wait for a long time in case the DNS SRV resolution takes times - it should be immediate though */
|
||||
BC_ASSERT_TRUE(wait_for_until(pauline->lc, marie->lc, &pauline->stat.number_of_LinphoneFileTransferDownloadSuccessful, 1, 55000));
|
||||
}
|
||||
|
||||
remove(receive_filepath);
|
||||
bc_free(receive_filepath);
|
||||
linphone_core_manager_destroy(marie);
|
||||
linphone_core_manager_destroy(pauline);
|
||||
}
|
||||
|
||||
static void file_transfer_using_external_body_url(void) {
|
||||
file_transfer_external_body_url(FALSE);
|
||||
}
|
||||
|
||||
static void file_transfer_using_external_body_url_2(void) {
|
||||
file_transfer_external_body_url(TRUE);
|
||||
}
|
||||
|
||||
static void text_message_denied(void) {
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc");
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc");
|
||||
|
|
@ -2130,6 +2188,10 @@ void file_transfer_with_http_proxy(void) {
|
|||
if (transport_supported(LinphoneTransportTls)) {
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc");
|
||||
lp_config_set_int(linphone_core_get_config(pauline->lc), "sip", "deliver_imdn", 1);
|
||||
lp_config_set_int(linphone_core_get_config(marie->lc), "sip", "deliver_imdn", 1);
|
||||
linphone_im_notif_policy_enable_all(linphone_core_get_im_notif_policy(marie->lc));
|
||||
linphone_im_notif_policy_enable_all(linphone_core_get_im_notif_policy(pauline->lc));
|
||||
linphone_core_set_http_proxy_host(marie->lc, "sip.linphone.org");
|
||||
transfer_message_base2(marie,pauline,FALSE,FALSE,FALSE,FALSE,FALSE);
|
||||
linphone_core_manager_destroy(pauline);
|
||||
|
|
@ -2439,6 +2501,8 @@ test_t message_tests[] = {
|
|||
TEST_NO_TAG("Transfer message upload cancelled", transfer_message_upload_cancelled),
|
||||
TEST_NO_TAG("Transfer message download cancelled", transfer_message_download_cancelled),
|
||||
TEST_NO_TAG("Transfer 2 messages simultaneously", file_transfer_2_messages_simultaneously),
|
||||
TEST_NO_TAG("Transfer using external body URL", file_transfer_using_external_body_url),
|
||||
TEST_NO_TAG("Transfer using external body URL 2", file_transfer_using_external_body_url_2),
|
||||
TEST_NO_TAG("Text message denied", text_message_denied),
|
||||
TEST_NO_TAG("IsComposing notification", is_composing_notification),
|
||||
TEST_NO_TAG("IMDN notifications", imdn_notifications),
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ static void chat_message_multipart_modifier_base(bool first_file_transfer, bool
|
|||
if (first_file_transfer) {
|
||||
char *send_filepath = bc_tester_res("sounds/sintel_trailer_opus_h264.mkv");
|
||||
FileContent *content = new FileContent();
|
||||
content->setContentType("video/mkv");
|
||||
content->setContentType(ContentType("video/mkv"));
|
||||
content->setFilePath(send_filepath);
|
||||
content->setFileName("sintel_trailer_opus_h264.mkv");
|
||||
marieMessage->addContent(*content);
|
||||
|
|
@ -65,7 +65,7 @@ static void chat_message_multipart_modifier_base(bool first_file_transfer, bool
|
|||
if (second_file_transfer) {
|
||||
char *send_filepath = bc_tester_res("vcards/vcards.vcf");
|
||||
FileContent *content = new FileContent();
|
||||
content->setContentType("file/vcf");
|
||||
content->setContentType(ContentType("file/vcf"));
|
||||
content->setFilePath(send_filepath);
|
||||
content->setFileName("vcards.vcf");
|
||||
marieMessage->addContent(*content);
|
||||
|
|
|
|||
|
|
@ -1571,8 +1571,157 @@ static void extended_notify_sub_unsub_sub2(void) {
|
|||
|
||||
bctbx_list_free(lcs);
|
||||
}
|
||||
static void simple_publish_with_expire(int expires) {
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
|
||||
LinphoneProxyConfig* proxy;
|
||||
LinphonePresenceModel* presence;
|
||||
LinphoneCoreCbs *cbs = linphone_factory_create_core_cbs(linphone_factory_get());
|
||||
|
||||
linphone_core_cbs_set_publish_state_changed(cbs, linphone_publish_state_changed);
|
||||
_linphone_core_add_callbacks(marie->lc, cbs, TRUE);
|
||||
linphone_core_cbs_unref(cbs);
|
||||
|
||||
proxy = linphone_core_get_default_proxy_config(marie->lc);
|
||||
linphone_proxy_config_edit(proxy);
|
||||
if (expires > 0) {
|
||||
linphone_proxy_config_set_publish_expires(proxy,expires);
|
||||
}
|
||||
linphone_proxy_config_enable_publish(proxy,TRUE);
|
||||
linphone_proxy_config_done(proxy);
|
||||
|
||||
BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishProgress,1));
|
||||
BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishOk,1));
|
||||
|
||||
presence = linphone_presence_model_new();
|
||||
linphone_presence_model_set_basic_status(presence, LinphonePresenceBasicStatusClosed);
|
||||
linphone_core_set_presence_model(marie->lc,presence);
|
||||
linphone_presence_model_unref(presence);
|
||||
|
||||
BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishProgress,2));
|
||||
BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishOk,2));
|
||||
|
||||
linphone_proxy_config_edit(proxy);
|
||||
linphone_proxy_config_done(proxy);
|
||||
/*make sure no publish is sent*/
|
||||
BC_ASSERT_FALSE(wait_for_until(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishProgress,3,2000));
|
||||
|
||||
linphone_proxy_config_edit(proxy);
|
||||
linphone_proxy_config_enable_publish(proxy,FALSE);
|
||||
linphone_proxy_config_done(proxy);
|
||||
|
||||
|
||||
/*fixme PUBLISH state machine is too simple, clear state should only be propagated at API level when 200ok is received*/
|
||||
/*BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishProgress,3));*/
|
||||
wait_for_until(marie->lc,marie->lc,NULL,0,2000);
|
||||
BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishCleared,1));
|
||||
|
||||
linphone_proxy_config_edit(proxy);
|
||||
linphone_proxy_config_enable_publish(proxy,TRUE);
|
||||
linphone_proxy_config_done(proxy);
|
||||
BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishProgress,3));
|
||||
BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishOk,3));
|
||||
|
||||
linphone_proxy_config_edit(proxy);
|
||||
linphone_proxy_config_set_publish_expires(proxy, linphone_proxy_config_get_publish_expires(proxy)+1);
|
||||
linphone_proxy_config_done(proxy);
|
||||
BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishProgress,4));
|
||||
BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishOk,4));
|
||||
|
||||
linphone_core_manager_stop(marie);
|
||||
BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishCleared,3,int,"%i"); /*yes it is 3 because when we change the expires, a new LinphoneEvent is created*/
|
||||
BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishOk,4,int,"%i");
|
||||
linphone_core_manager_destroy(marie);
|
||||
}
|
||||
|
||||
static void simple_publish(void) {
|
||||
simple_publish_with_expire(-1);
|
||||
}
|
||||
|
||||
static void publish_with_expires(void) {
|
||||
simple_publish_with_expire(2);
|
||||
}
|
||||
|
||||
static void publish_with_dual_identity(void) {
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new("multi_account_rc");
|
||||
const bctbx_list_t* proxies;
|
||||
LinphoneCoreCbs *cbs = linphone_factory_create_core_cbs(linphone_factory_get());
|
||||
|
||||
linphone_core_cbs_set_publish_state_changed(cbs, linphone_publish_state_changed);
|
||||
_linphone_core_add_callbacks(pauline->lc, cbs, TRUE);
|
||||
linphone_core_cbs_unref(cbs);
|
||||
|
||||
for (proxies = linphone_core_get_proxy_config_list(pauline->lc); proxies!=NULL; proxies = proxies->next) {
|
||||
LinphoneProxyConfig *proxy = (LinphoneProxyConfig *) proxies->data;
|
||||
linphone_proxy_config_edit(proxy);
|
||||
linphone_proxy_config_enable_publish(proxy,TRUE);
|
||||
linphone_proxy_config_done(proxy);
|
||||
}
|
||||
|
||||
BC_ASSERT_TRUE(wait_for(pauline->lc,pauline->lc,&pauline->stat.number_of_LinphonePublishProgress,4));
|
||||
BC_ASSERT_TRUE(wait_for(pauline->lc,pauline->lc,&pauline->stat.number_of_LinphonePublishOk,4));
|
||||
|
||||
linphone_core_manager_stop(pauline);
|
||||
BC_ASSERT_EQUAL(pauline->stat.number_of_LinphonePublishCleared,4,int,"%i");
|
||||
BC_ASSERT_EQUAL(pauline->stat.number_of_LinphonePublishOk,4,int,"%i");
|
||||
linphone_core_manager_destroy(pauline);
|
||||
|
||||
}
|
||||
static void publish_with_network_state_changes(void) {
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
|
||||
LinphoneFriend* marie_as_friend = linphone_core_create_friend_with_address(pauline->lc, get_identity(marie));
|
||||
|
||||
LinphoneProxyConfig* proxy;
|
||||
LinphoneCoreCbs *cbs = linphone_factory_create_core_cbs(linphone_factory_get());
|
||||
|
||||
linphone_core_cbs_set_publish_state_changed(cbs, linphone_publish_state_changed);
|
||||
_linphone_core_add_callbacks(marie->lc, cbs,TRUE);
|
||||
linphone_core_cbs_unref(cbs);
|
||||
|
||||
linphone_core_set_user_agent(marie->lc, "full-presence-support", NULL);
|
||||
linphone_core_set_user_agent(marie->lc, "full-presence-support-bypass", NULL);
|
||||
|
||||
proxy = linphone_core_get_default_proxy_config(marie->lc);
|
||||
linphone_proxy_config_edit(proxy);
|
||||
linphone_proxy_config_enable_publish(proxy,TRUE);
|
||||
linphone_proxy_config_done(proxy);
|
||||
|
||||
BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishProgress,1));
|
||||
BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishOk,1));
|
||||
|
||||
linphone_core_set_network_reachable(marie->lc, FALSE);
|
||||
BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphoneRegistrationNone,1));
|
||||
BC_ASSERT_FALSE(wait_for_until(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishProgress,2,1000));
|
||||
BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishOk,1,int,"%i");
|
||||
BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishError,0,int,"%i");
|
||||
|
||||
linphone_core_set_network_reachable(marie->lc, TRUE);
|
||||
BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishProgress,2));
|
||||
BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishOk,2));
|
||||
|
||||
|
||||
|
||||
linphone_core_manager_stop(marie);
|
||||
BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishCleared,1,int,"%i"); /*yes it is 3 because when we change the expires, a new LinphoneEvent is created*/
|
||||
BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishOk,2,int,"%i");
|
||||
linphone_core_manager_destroy(marie);
|
||||
|
||||
/*make sure there is no remaining publish caused by network failure*/
|
||||
linphone_core_set_user_agent(pauline->lc, "full-presence-support", NULL);
|
||||
linphone_core_set_user_agent(pauline->lc, "full-presence-support-bypass", NULL);
|
||||
linphone_core_add_friend(pauline->lc, marie_as_friend);
|
||||
|
||||
BC_ASSERT_TRUE(wait_for(pauline->lc,pauline->lc,&pauline->stat.number_of_LinphonePresenceActivityAway,1));
|
||||
linphone_friend_unref(marie_as_friend);
|
||||
linphone_core_manager_destroy(pauline);
|
||||
|
||||
}
|
||||
|
||||
test_t presence_server_tests[] = {
|
||||
TEST_NO_TAG("Simple Publish", simple_publish),
|
||||
TEST_NO_TAG("Publish with 2 identities", publish_with_dual_identity),
|
||||
TEST_NO_TAG("Simple Publish with expires", publish_with_expires),
|
||||
TEST_ONE_TAG("Publish with network state changes", publish_with_network_state_changes, "presence"),
|
||||
TEST_NO_TAG("Simple", simple),
|
||||
TEST_NO_TAG("Fast activity change", fast_activity_change),
|
||||
TEST_NO_TAG("Forked subscribe with late publish", test_forked_subscribe_notify_publish),
|
||||
|
|
|
|||
|
|
@ -142,101 +142,6 @@ void notify_presence_received_for_uri_or_tel(LinphoneCore *lc, LinphoneFriend *l
|
|||
counters->number_of_NotifyPresenceReceivedForUriOrTel++;
|
||||
}
|
||||
|
||||
static void simple_publish_with_expire(int expires) {
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
|
||||
LinphoneProxyConfig* proxy;
|
||||
LinphonePresenceModel* presence;
|
||||
LinphoneCoreCbs *cbs = linphone_factory_create_core_cbs(linphone_factory_get());
|
||||
|
||||
linphone_core_cbs_set_publish_state_changed(cbs, linphone_publish_state_changed);
|
||||
_linphone_core_add_callbacks(marie->lc, cbs, TRUE);
|
||||
linphone_core_cbs_unref(cbs);
|
||||
|
||||
proxy = linphone_core_get_default_proxy_config(marie->lc);
|
||||
linphone_proxy_config_edit(proxy);
|
||||
if (expires > 0) {
|
||||
linphone_proxy_config_set_publish_expires(proxy,expires);
|
||||
}
|
||||
linphone_proxy_config_enable_publish(proxy,TRUE);
|
||||
linphone_proxy_config_done(proxy);
|
||||
|
||||
BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishProgress,1));
|
||||
BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishOk,1));
|
||||
|
||||
presence = linphone_presence_model_new();
|
||||
linphone_presence_model_set_basic_status(presence, LinphonePresenceBasicStatusClosed);
|
||||
linphone_core_set_presence_model(marie->lc,presence);
|
||||
linphone_presence_model_unref(presence);
|
||||
|
||||
BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishProgress,2));
|
||||
BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishOk,2));
|
||||
|
||||
linphone_proxy_config_edit(proxy);
|
||||
linphone_proxy_config_done(proxy);
|
||||
/*make sure no publish is sent*/
|
||||
BC_ASSERT_FALSE(wait_for_until(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishProgress,3,2000));
|
||||
|
||||
linphone_proxy_config_edit(proxy);
|
||||
linphone_proxy_config_enable_publish(proxy,FALSE);
|
||||
linphone_proxy_config_done(proxy);
|
||||
|
||||
|
||||
/*fixme PUBLISH state machine is too simple, clear state should only be propagated at API level when 200ok is received*/
|
||||
/*BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishProgress,3));*/
|
||||
wait_for_until(marie->lc,marie->lc,NULL,0,2000);
|
||||
BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishCleared,1));
|
||||
|
||||
linphone_proxy_config_edit(proxy);
|
||||
linphone_proxy_config_enable_publish(proxy,TRUE);
|
||||
linphone_proxy_config_done(proxy);
|
||||
BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishProgress,3));
|
||||
BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishOk,3));
|
||||
|
||||
linphone_proxy_config_edit(proxy);
|
||||
linphone_proxy_config_set_publish_expires(proxy, linphone_proxy_config_get_publish_expires(proxy)+1);
|
||||
linphone_proxy_config_done(proxy);
|
||||
BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishProgress,4));
|
||||
BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishOk,4));
|
||||
|
||||
linphone_core_manager_stop(marie);
|
||||
BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishCleared,3,int,"%i"); /*yes it is 3 because when we change the expires, a new LinphoneEvent is created*/
|
||||
BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishOk,4,int,"%i");
|
||||
linphone_core_manager_destroy(marie);
|
||||
}
|
||||
|
||||
static void simple_publish(void) {
|
||||
simple_publish_with_expire(-1);
|
||||
}
|
||||
|
||||
static void publish_with_expires(void) {
|
||||
simple_publish_with_expire(2);
|
||||
}
|
||||
|
||||
static void publish_with_dual_identity(void) {
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new("multi_account_rc");
|
||||
const bctbx_list_t* proxies;
|
||||
LinphoneCoreCbs *cbs = linphone_factory_create_core_cbs(linphone_factory_get());
|
||||
|
||||
linphone_core_cbs_set_publish_state_changed(cbs, linphone_publish_state_changed);
|
||||
_linphone_core_add_callbacks(pauline->lc, cbs, TRUE);
|
||||
linphone_core_cbs_unref(cbs);
|
||||
|
||||
for (proxies = linphone_core_get_proxy_config_list(pauline->lc); proxies!=NULL; proxies = proxies->next) {
|
||||
LinphoneProxyConfig *proxy = (LinphoneProxyConfig *) proxies->data;
|
||||
linphone_proxy_config_edit(proxy);
|
||||
linphone_proxy_config_enable_publish(proxy,TRUE);
|
||||
linphone_proxy_config_done(proxy);
|
||||
}
|
||||
|
||||
BC_ASSERT_TRUE(wait_for(pauline->lc,pauline->lc,&pauline->stat.number_of_LinphonePublishProgress,4));
|
||||
BC_ASSERT_TRUE(wait_for(pauline->lc,pauline->lc,&pauline->stat.number_of_LinphonePublishOk,4));
|
||||
|
||||
linphone_core_manager_stop(pauline);
|
||||
BC_ASSERT_EQUAL(pauline->stat.number_of_LinphonePublishCleared,4,int,"%i");
|
||||
BC_ASSERT_EQUAL(pauline->stat.number_of_LinphonePublishOk,4,int,"%i");
|
||||
linphone_core_manager_destroy(pauline);
|
||||
|
||||
}
|
||||
static bool_t subscribe_to_callee_presence(LinphoneCoreManager* caller_mgr,LinphoneCoreManager* callee_mgr) {
|
||||
stats initial_caller=caller_mgr->stat;
|
||||
stats initial_callee=callee_mgr->stat;
|
||||
|
|
@ -306,40 +211,6 @@ static void subscribe_failure_handle_by_app(void) {
|
|||
linphone_core_manager_destroy(pauline);
|
||||
}
|
||||
|
||||
static void publish_with_network_state_changes(void) {
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
|
||||
LinphoneProxyConfig* proxy;
|
||||
LinphoneCoreCbs *cbs = linphone_factory_create_core_cbs(linphone_factory_get());
|
||||
|
||||
linphone_core_cbs_set_publish_state_changed(cbs, linphone_publish_state_changed);
|
||||
_linphone_core_add_callbacks(marie->lc, cbs,TRUE);
|
||||
linphone_core_cbs_unref(cbs);
|
||||
|
||||
proxy = linphone_core_get_default_proxy_config(marie->lc);
|
||||
linphone_proxy_config_edit(proxy);
|
||||
linphone_proxy_config_enable_publish(proxy,TRUE);
|
||||
linphone_proxy_config_done(proxy);
|
||||
|
||||
BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishProgress,1));
|
||||
BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishOk,1));
|
||||
|
||||
linphone_core_set_network_reachable(marie->lc, FALSE);
|
||||
BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphoneRegistrationNone,1));
|
||||
BC_ASSERT_FALSE(wait_for_until(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishProgress,2,1000));
|
||||
BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishOk,1,int,"%i");
|
||||
BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishError,0,int,"%i");
|
||||
|
||||
linphone_core_set_network_reachable(marie->lc, TRUE);
|
||||
BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishProgress,2));
|
||||
BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishOk,2));
|
||||
|
||||
|
||||
linphone_core_manager_stop(marie);
|
||||
BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishCleared,1,int,"%i"); /*yes it is 3 because when we change the expires, a new LinphoneEvent is created*/
|
||||
BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishOk,2,int,"%i");
|
||||
linphone_core_manager_destroy(marie);
|
||||
}
|
||||
|
||||
static void simple_subscribe(void) {
|
||||
LinphoneCoreManager* marie = presence_linphone_core_manager_new("marie");
|
||||
LinphoneCoreManager* pauline = presence_linphone_core_manager_new("pauline");
|
||||
|
|
@ -640,14 +511,10 @@ test_t presence_tests[] = {
|
|||
TEST_ONE_TAG("Simple Subscribe", simple_subscribe,"presence"),
|
||||
TEST_ONE_TAG("Simple Subscribe with early NOTIFY", simple_subscribe_with_early_notify,"presence"),
|
||||
TEST_NO_TAG("Simple Subscribe with friend from rc", simple_subscribe_with_friend_from_rc),
|
||||
TEST_NO_TAG("Simple Publish", simple_publish),
|
||||
TEST_NO_TAG("Publish with 2 identities", publish_with_dual_identity),
|
||||
TEST_NO_TAG("Simple Publish with expires", publish_with_expires),
|
||||
TEST_ONE_TAG("Publish with network state changes", publish_with_network_state_changes, "presence"),
|
||||
/*TEST_ONE_TAG("Call with presence", call_with_presence, "LeaksMemory"),*/
|
||||
TEST_NO_TAG("Unsubscribe while subscribing", unsubscribe_while_subscribing),
|
||||
TEST_NO_TAG("Presence information", presence_information),
|
||||
TEST_NO_TAG("App managed presence failure", subscribe_failure_handle_by_app),
|
||||
TEST_ONE_TAG("App managed presence failure", subscribe_failure_handle_by_app,"presence"),
|
||||
TEST_NO_TAG("Presence SUBSCRIBE forked", subscribe_presence_forked),
|
||||
TEST_NO_TAG("Presence SUBSCRIBE expired", subscribe_presence_expired),
|
||||
};
|
||||
|
|
|
|||
|
|
@ -243,12 +243,36 @@ static void load_dynamic_proxy_config(void) {
|
|||
|
||||
}
|
||||
|
||||
static void single_route(void) {
|
||||
LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc");
|
||||
LinphoneProxyConfig *marie_cfg = linphone_core_get_default_proxy_config(marie->lc);
|
||||
BC_ASSERT_PTR_NOT_NULL(marie_cfg);
|
||||
|
||||
const bctbx_list_t *routes = linphone_proxy_config_get_routes(marie_cfg);
|
||||
BC_ASSERT_PTR_NOT_NULL(routes);
|
||||
BC_ASSERT_EQUAL(bctbx_list_size(routes), 1, int, "%d");
|
||||
const char *route = (const char *)bctbx_list_get_data(routes);
|
||||
BC_ASSERT_STRING_EQUAL(linphone_proxy_config_get_route(marie_cfg), "sip:sip.example.org;transport=tcp;lr");
|
||||
BC_ASSERT_STRING_EQUAL(route, "sip:sip.example.org;transport=tcp;lr");
|
||||
|
||||
linphone_proxy_config_set_route(marie_cfg, "sip.linphone.org");
|
||||
routes = linphone_proxy_config_get_routes(marie_cfg);
|
||||
BC_ASSERT_PTR_NOT_NULL(routes);
|
||||
BC_ASSERT_EQUAL(bctbx_list_size(routes), 1, int, "%d");
|
||||
route = (const char *)bctbx_list_get_data(routes);
|
||||
BC_ASSERT_STRING_EQUAL(linphone_proxy_config_get_route(marie_cfg), "sip:sip.linphone.org");
|
||||
BC_ASSERT_STRING_EQUAL(route, "sip:sip.linphone.org");
|
||||
|
||||
linphone_core_manager_destroy(marie);
|
||||
}
|
||||
|
||||
test_t proxy_config_tests[] = {
|
||||
TEST_NO_TAG("Phone normalization without proxy", phone_normalization_without_proxy),
|
||||
TEST_NO_TAG("Phone normalization with proxy", phone_normalization_with_proxy),
|
||||
TEST_NO_TAG("Phone normalization with dial escape plus", phone_normalization_with_dial_escape_plus),
|
||||
TEST_NO_TAG("SIP URI normalization", sip_uri_normalization),
|
||||
TEST_NO_TAG("Load new default value for proxy config", load_dynamic_proxy_config)
|
||||
TEST_NO_TAG("Load new default value for proxy config", load_dynamic_proxy_config),
|
||||
TEST_NO_TAG("Single route", single_route)
|
||||
};
|
||||
|
||||
test_suite_t proxy_config_test_suite = {"Proxy config", NULL, NULL, liblinphone_tester_before_each, liblinphone_tester_after_each,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue