Merge branch 'dev_refactor_cpp' into dev_doc_generator

This commit is contained in:
François Grisez 2018-04-10 17:26:53 +02:00
commit 0e7ae694d7
86 changed files with 3443 additions and 508 deletions

View file

@ -53,7 +53,7 @@ if(WIN32)
endif()
add_executable(linphonecsh ${LINPHONECSH_SOURCE_FILES})
target_link_libraries(linphonecsh ${LINPHONE_LIBS_FOR_TOOLS} ${ORTP_LIBRARIES})
target_link_libraries(linphonecsh ${LINPHONE_LIBS_FOR_TOOLS} ${BCTOOLBOX_CORE_LIBRARIES} ${ORTP_LIBRARIES})
set_target_properties(linphonecsh PROPERTIES LINK_FLAGS "${LINPHONE_LDFLAGS}")
set(INSTALL_TARGETS linphonec linphonecsh)

View file

@ -84,6 +84,7 @@ set(LINPHONE_SOURCE_FILES_C
linphonecore.c
linphone_tunnel_config.c
localplayer.c
logging.c
lpc2xml.c
lpconfig.c
lsd.c

View file

@ -41,6 +41,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "call/call-p.h"
#include "chat/chat-message/chat-message-p.h"
#include "chat/chat-room/chat-room.h"
#include "chat/chat-room/client-group-chat-room-p.h"
#include "chat/chat-room/server-group-chat-room-p.h"
#include "conference/participant.h"
#include "conference/session/call-session-p.h"
@ -56,8 +57,14 @@ using namespace LinphonePrivate;
static void register_failure(SalOp *op);
static void call_received(SalCallOp *h) {
/* Look if this INVITE is for a call that has already been notified but broken because of network failure */
LinphoneCore *lc = reinterpret_cast<LinphoneCore *>(h->get_sal()->get_user_pointer());
if (linphone_core_get_global_state(lc) != LinphoneGlobalOn) {
h->decline(SalReasonServiceUnavailable, nullptr);
return;
}
/* Look if this INVITE is for a call that has already been notified but broken because of network failure */
if (L_GET_PRIVATE_FROM_C_OBJECT(lc)->inviteReplacesABrokenCall(h))
return;
@ -107,16 +114,28 @@ static void call_received(SalCallOp *h) {
// TODO: handle media conference creation if the "text" feature tag is not present
return;
} else if (sal_address_has_param(h->get_remote_contact_address(), "text")) {
shared_ptr<AbstractChatRoom> chatRoom = L_GET_CPP_PTR_FROM_C_OBJECT(lc)->findChatRoom(
ChatRoomId(IdentityAddress(h->get_to()), IdentityAddress(h->get_to()))
);
if (chatRoom) {
L_GET_PRIVATE(static_pointer_cast<ServerGroupChatRoom>(chatRoom))->confirmJoining(h);
linphone_address_unref(toAddr);
linphone_address_unref(fromAddr);
linphone_address_unref(toAddr);
linphone_address_unref(fromAddr);
if (linphone_core_conference_server_enabled(lc)) {
shared_ptr<AbstractChatRoom> chatRoom = L_GET_CPP_PTR_FROM_C_OBJECT(lc)->findChatRoom(
ChatRoomId(IdentityAddress(h->get_to()), IdentityAddress(h->get_to()))
);
if (chatRoom) {
L_GET_PRIVATE(static_pointer_cast<ServerGroupChatRoom>(chatRoom))->confirmJoining(h);
} else {
//invite is for an unknown chatroom
h->decline(SalReasonNotFound, nullptr);
}
} else {
//invite is for an unknown chatroom
h->decline(SalReasonNotFound, nullptr);
shared_ptr<AbstractChatRoom> chatRoom = L_GET_CPP_PTR_FROM_C_OBJECT(lc)->findChatRoom(
ChatRoomId(IdentityAddress(h->get_from()), IdentityAddress(h->get_to()))
);
if (!chatRoom) {
chatRoom = L_GET_PRIVATE_FROM_C_OBJECT(lc)->createClientGroupChatRoom(
L_C_TO_STRING(h->get_subject()), h->get_remote_contact(), h->get_remote_body(), false
);
}
L_GET_PRIVATE(static_pointer_cast<ClientGroupChatRoom>(chatRoom))->confirmJoining(h);
}
return;
} else {
@ -201,7 +220,8 @@ static void call_rejected(SalCallOp *h){
static void call_ringing(SalOp *h) {
LinphonePrivate::CallSession *session = reinterpret_cast<LinphonePrivate::CallSession *>(h->get_user_pointer());
if (!session) return;
L_GET_PRIVATE(session)->remoteRinging();
auto sessionRef = session->getSharedFromThis();
L_GET_PRIVATE(sessionRef)->remoteRinging();
}
/*
@ -215,7 +235,8 @@ static void call_accepted(SalOp *op) {
ms_warning("call_accepted: CallSession no longer exists");
return;
}
L_GET_PRIVATE(session)->accepted();
auto sessionRef = session->getSharedFromThis();
L_GET_PRIVATE(sessionRef)->accepted();
}
/* this callback is called when an incoming re-INVITE/ SIP UPDATE modifies the session*/
@ -225,7 +246,8 @@ static void call_updating(SalOp *op, bool_t is_update) {
ms_warning("call_updating: CallSession no longer exists");
return;
}
L_GET_PRIVATE(session)->updating(!!is_update);
auto sessionRef = session->getSharedFromThis();
L_GET_PRIVATE(sessionRef)->updating(!!is_update);
}
@ -235,7 +257,8 @@ static void call_ack_received(SalOp *op, SalCustomHeader *ack) {
ms_warning("call_ack_received(): no CallSession for which an ack is expected");
return;
}
L_GET_PRIVATE(session)->ackReceived(reinterpret_cast<LinphoneHeaders *>(ack));
auto sessionRef = session->getSharedFromThis();
L_GET_PRIVATE(sessionRef)->ackReceived(reinterpret_cast<LinphoneHeaders *>(ack));
}
@ -245,25 +268,26 @@ static void call_ack_being_sent(SalOp *op, SalCustomHeader *ack) {
ms_warning("call_ack_being_sent(): no CallSession for which an ack is supposed to be sent");
return;
}
L_GET_PRIVATE(session)->ackBeingSent(reinterpret_cast<LinphoneHeaders *>(ack));
auto sessionRef = session->getSharedFromThis();
L_GET_PRIVATE(sessionRef)->ackBeingSent(reinterpret_cast<LinphoneHeaders *>(ack));
}
static void call_terminated(SalOp *op, const char *from) {
LinphonePrivate::CallSession *session = reinterpret_cast<LinphonePrivate::CallSession *>(op->get_user_pointer());
if (!session)
return;
L_GET_PRIVATE(session)->terminated();
auto sessionRef = session->getSharedFromThis();
L_GET_PRIVATE(sessionRef)->terminated();
}
static void call_failure(SalOp *op) {
shared_ptr<LinphonePrivate::CallSession> session;
if (op->get_user_pointer())
session = reinterpret_cast<LinphonePrivate::CallSession *>(op->get_user_pointer())->getSharedFromThis();
LinphonePrivate::CallSession *session = reinterpret_cast<LinphonePrivate::CallSession *>(op->get_user_pointer());
if (!session) {
ms_warning("Failure reported on already terminated CallSession");
return;
}
L_GET_PRIVATE(session)->failure();
auto sessionRef = session->getSharedFromThis();
L_GET_PRIVATE(sessionRef)->failure();
}
static void call_released(SalOp *op) {
@ -273,7 +297,8 @@ static void call_released(SalOp *op) {
* when declining an incoming call with busy because maximum number of calls is reached. */
return;
}
L_GET_PRIVATE(session)->setState(LinphonePrivate::CallSession::State::Released, "Call released");
auto sessionRef = session->getSharedFromThis();
L_GET_PRIVATE(sessionRef)->setState(LinphonePrivate::CallSession::State::Released, "Call released");
}
static void call_cancel_done(SalOp *op) {
@ -282,7 +307,8 @@ static void call_cancel_done(SalOp *op) {
ms_warning("Cancel done reported on already terminated CallSession");
return;
}
L_GET_PRIVATE(session)->cancelDone();
auto sessionRef = session->getSharedFromThis();
L_GET_PRIVATE(sessionRef)->cancelDone();
}
static void auth_failure(SalOp *op, SalAuthInfo* info) {
@ -344,24 +370,26 @@ static void vfu_request(SalOp *op) {
LinphonePrivate::CallSession *session = reinterpret_cast<LinphonePrivate::CallSession *>(op->get_user_pointer());
if (!session)
return;
LinphonePrivate::MediaSession *mediaSession = dynamic_cast<LinphonePrivate::MediaSession *>(session);
if (!mediaSession) {
auto sessionRef = session->getSharedFromThis();
auto mediaSessionRef = dynamic_pointer_cast<LinphonePrivate::MediaSession>(sessionRef);
if (!mediaSessionRef) {
ms_warning("VFU request but no MediaSession!");
return;
}
L_GET_PRIVATE(mediaSession)->sendVfu();
L_GET_PRIVATE(mediaSessionRef)->sendVfu();
}
static void dtmf_received(SalOp *op, char dtmf) {
LinphonePrivate::CallSession *session = reinterpret_cast<LinphonePrivate::CallSession *>(op->get_user_pointer());
if (!session)
return;
LinphonePrivate::MediaSession *mediaSession = dynamic_cast<LinphonePrivate::MediaSession *>(session);
if (!mediaSession) {
auto sessionRef = session->getSharedFromThis();
auto mediaSessionRef = dynamic_pointer_cast<LinphonePrivate::MediaSession>(sessionRef);
if (!mediaSessionRef) {
ms_warning("DTMF received but no MediaSession!");
return;
}
L_GET_PRIVATE(mediaSession)->dtmfReceived(dtmf);
L_GET_PRIVATE(mediaSessionRef)->dtmfReceived(dtmf);
}
static void call_refer_received(SalOp *op, const SalAddress *referTo) {
@ -372,7 +400,8 @@ static void call_refer_received(SalOp *op, const SalAddress *referTo) {
if (referToAddr.isValid())
method = referToAddr.getMethodParam();
if (session && (method.empty() || (method == "INVITE"))) {
L_GET_PRIVATE(session)->referred(referToAddr);
auto sessionRef = session->getSharedFromThis();
L_GET_PRIVATE(sessionRef)->referred(referToAddr);
} else {
LinphoneCore *lc = reinterpret_cast<LinphoneCore *>(op->get_sal()->get_user_pointer());
linphone_core_notify_refer_received(lc, addrStr);
@ -382,6 +411,12 @@ static void call_refer_received(SalOp *op, const SalAddress *referTo) {
static void message_received(SalOp *op, const SalMessage *msg){
LinphoneCore *lc=(LinphoneCore *)op->get_sal()->get_user_pointer();
if (linphone_core_get_global_state(lc) != LinphoneGlobalOn) {
static_cast<SalMessageOp *>(op)->reply(SalReasonServiceUnavailable);
return;
}
LinphoneCall *call=(LinphoneCall*)op->get_user_pointer();
LinphoneReason reason = lc->chat_deny_code;
if (reason == LinphoneReasonNone) {
@ -414,6 +449,10 @@ static void notify_presence(SalOp *op, SalSubscribeStatus ss, SalPresenceModel *
static void subscribe_presence_received(SalPresenceOp *op, const char *from){
LinphoneCore *lc=(LinphoneCore *)op->get_sal()->get_user_pointer();
if (linphone_core_get_global_state(lc) != LinphoneGlobalOn) {
op->decline(SalReasonServiceUnavailable);
return;
}
linphone_subscription_new(lc,op,from);
}
@ -428,7 +467,8 @@ static void ping_reply(SalOp *op) {
ms_warning("Ping reply without CallSession attached...");
return;
}
L_GET_PRIVATE(session)->pingReply();
auto sessionRef = session->getSharedFromThis();
L_GET_PRIVATE(sessionRef)->pingReply();
}
static bool_t fill_auth_info_with_client_certificate(LinphoneCore *lc, SalAuthInfo* sai) {
@ -531,6 +571,7 @@ static void notify_refer(SalOp *op, SalReferStatus status) {
ms_warning("Receiving notify_refer for unknown CallSession");
return;
}
auto sessionRef = session->getSharedFromThis();
LinphonePrivate::CallSession::State cstate;
switch (status) {
case SalReferTrying:
@ -544,9 +585,9 @@ static void notify_refer(SalOp *op, SalReferStatus status) {
cstate = LinphonePrivate::CallSession::State::Error;
break;
}
L_GET_PRIVATE(session)->setTransferState(cstate);
L_GET_PRIVATE(sessionRef)->setTransferState(cstate);
if (cstate == LinphonePrivate::CallSession::State::Connected)
session->terminate(); // Automatically terminate the call as the transfer is complete
sessionRef->terminate(); // Automatically terminate the call as the transfer is complete
}
static LinphoneChatMessageState chatStatusSal2Linphone(SalMessageDeliveryStatus status){
@ -575,7 +616,8 @@ static void info_received(SalOp *op, SalBodyHandler *body_handler) {
LinphonePrivate::CallSession *session = reinterpret_cast<LinphonePrivate::CallSession *>(op->get_user_pointer());
if (!session)
return;
L_GET_PRIVATE(session)->infoReceived(body_handler);
auto sessionRef = session->getSharedFromThis();
L_GET_PRIVATE(sessionRef)->infoReceived(body_handler);
}
static void subscribe_response(SalOp *op, SalSubscribeStatus status, int will_retry){
@ -622,6 +664,11 @@ static void subscribe_received(SalSubscribeOp *op, const char *eventname, const
LinphoneEvent *lev=(LinphoneEvent*)op->get_user_pointer();
LinphoneCore *lc=(LinphoneCore *)op->get_sal()->get_user_pointer();
if (linphone_core_get_global_state(lc) != LinphoneGlobalOn) {
op->decline(SalReasonServiceUnavailable);
return;
}
if (lev==NULL) {
lev=linphone_event_new_with_op(lc,op,LinphoneSubscriptionIncoming,eventname);
linphone_event_set_state(lev,LinphoneSubscriptionIncomingReceived);
@ -700,6 +747,12 @@ static void refer_received(SalOp *op, const SalAddress *refer_to){
bctbx_free(refer_uri);
if (addr.isValid()) {
LinphoneCore *lc = reinterpret_cast<LinphoneCore *>(op->get_sal()->get_user_pointer());
if (linphone_core_get_global_state(lc) != LinphoneGlobalOn) {
static_cast<SalReferOp *>(op)->reply(SalReasonDeclined);
return;
}
if (addr.hasUriParam("method") && (addr.getUriParamValue("method") == "BYE")) {
if (linphone_core_conference_server_enabled(lc)) {
// Removal of a participant at the server side
@ -730,34 +783,51 @@ static void refer_received(SalOp *op, const SalAddress *refer_to){
}
static_cast<SalReferOp *>(op)->reply(SalReasonDeclined);
}
} else if (addr.hasParam("admin")) {
LinphoneChatRoom *cr = L_GET_C_BACK_PTR(L_GET_CPP_PTR_FROM_C_OBJECT(lc)->findChatRoom(
ChatRoomId(IdentityAddress(op->get_to()), IdentityAddress(op->get_to()))
));
if (cr) {
Address fromAddr(op->get_from());
std::shared_ptr<Participant> participant = L_GET_CPP_PTR_FROM_C_OBJECT(cr)->findParticipant(fromAddr);
if (!participant || !participant->isAdmin()) {
static_cast<SalReferOp *>(op)->reply(SalReasonDeclined);
return;
}
participant = L_GET_CPP_PTR_FROM_C_OBJECT(cr)->findParticipant(addr);
if (participant) {
bool value = Utils::stob(addr.getParamValue("admin"));
L_GET_CPP_PTR_FROM_C_OBJECT(cr)->setParticipantAdminStatus(participant, value);
} else {
if (linphone_core_conference_server_enabled(lc)) {
shared_ptr<AbstractChatRoom> chatRoom = L_GET_CPP_PTR_FROM_C_OBJECT(lc)->findChatRoom(
ChatRoomId(IdentityAddress(op->get_to()), IdentityAddress(op->get_to()))
);
LinphoneChatRoom *cr = L_GET_C_BACK_PTR(chatRoom);
if (cr) {
Address fromAddr(op->get_from());
shared_ptr<Participant> participant = chatRoom->findParticipant(fromAddr);
if (!participant || !participant->isAdmin()) {
static_cast<SalReferOp *>(op)->reply(SalReasonDeclined);
return;
}
if (addr.hasParam("admin")) {
participant = chatRoom->findParticipant(addr);
if (participant) {
bool value = Utils::stob(addr.getParamValue("admin"));
chatRoom->setParticipantAdminStatus(participant, value);
static_cast<SalReferOp *>(op)->reply(SalReasonNone);
return;
}
} else {
participant = L_GET_PRIVATE(static_pointer_cast<ServerGroupChatRoom>(chatRoom))->findFilteredParticipant(addr);
if (!participant) {
list<IdentityAddress> identAddresses;
identAddresses.push_back(addr);
L_GET_PRIVATE(static_pointer_cast<ServerGroupChatRoom>(chatRoom))->checkCompatibleParticipants(
IdentityAddress(op->get_remote_contact()),
identAddresses
);
static_cast<SalReferOp *>(op)->reply(SalReasonNone);
return;
}
}
}
} else {
shared_ptr<AbstractChatRoom> chatRoom = L_GET_CPP_PTR_FROM_C_OBJECT(lc)->findChatRoom(
ChatRoomId(addr, IdentityAddress(op->get_to()))
);
if (!chatRoom)
chatRoom = L_GET_PRIVATE_FROM_C_OBJECT(lc)->createClientGroupChatRoom("", addr.asString(), Content(), false);
chatRoom->join();
static_cast<SalReferOp *>(op)->reply(SalReasonNone);
return;
}
} else {
shared_ptr<AbstractChatRoom> chatRoom = L_GET_CPP_PTR_FROM_C_OBJECT(lc)->findChatRoom(
ChatRoomId(addr, IdentityAddress(op->get_to()))
);
if (!chatRoom)
chatRoom = L_GET_PRIVATE_FROM_C_OBJECT(lc)->createClientGroupChatRoom("", addr.asString(), false);
chatRoom->join();
static_cast<SalReferOp *>(op)->reply(SalReasonNone);
return;
}
}
}

View file

@ -84,8 +84,8 @@ LinphoneChatRoom *linphone_core_get_chat_room (LinphoneCore *lc, const LinphoneA
return L_GET_C_BACK_PTR(L_GET_CPP_PTR_FROM_C_OBJECT(lc)->getOrCreateBasicChatRoom(*L_GET_CPP_PTR_FROM_C_OBJECT(addr)));
}
LinphoneChatRoom *linphone_core_create_client_group_chat_room (LinphoneCore *lc, const char *subject) {
return L_GET_C_BACK_PTR(L_GET_CPP_PTR_FROM_C_OBJECT(lc)->createClientGroupChatRoom(L_C_TO_STRING(subject)));
LinphoneChatRoom *linphone_core_create_client_group_chat_room (LinphoneCore *lc, const char *subject, bool_t fallback) {
return L_GET_C_BACK_PTR(L_GET_CPP_PTR_FROM_C_OBJECT(lc)->createClientGroupChatRoom(L_C_TO_STRING(subject), !!fallback));
}
LinphoneChatRoom *_linphone_core_create_server_group_chat_room (LinphoneCore *lc, LinphonePrivate::SalCallOp *op) {

View file

@ -167,6 +167,7 @@ static LinphoneCore *_linphone_factory_create_core (
LpConfig *config = lp_config_new_with_factory(config_path, factory_config_path);
LinphoneCore *lc = _linphone_core_new_with_config(cbs, config, user_data, system_context, automatically_start);
lp_config_unref(config);
bctbx_uninit_logger();
return lc;
}

View file

@ -31,6 +31,11 @@ if (ENABLE_DOC OR ENABLE_CXX_WRAPPER OR ENABLE_CSHARP_WRAPPER OR ENABLE_JAVA_WRA
endforeach ()
string(CONCAT DOXYGEN_INPUT ${DOXYGEN_INPUT} " \"${CMAKE_CURRENT_SOURCE_DIR}\"")
string(CONCAT DOXYGEN_INPUT ${DOXYGEN_INPUT} " \"${PROJECT_SOURCE_DIR}/coreapi/help/examples/C\"")
if(ENABLE_DOC)
set(GENERATE_HTML "YES")
else()
set(GENERATE_HTML "NO")
endif()
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile)
set(DOC_INPUT_FILES ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile
${CMAKE_CURRENT_SOURCE_DIR}/doxygen.dox
@ -39,14 +44,15 @@ if (ENABLE_DOC OR ENABLE_CXX_WRAPPER OR ENABLE_CSHARP_WRAPPER OR ENABLE_JAVA_WRA
set(XML_DIR "${CMAKE_CURRENT_BINARY_DIR}/xml")
set(LINPHONE_DOXYGEN_XML_DIR ${XML_DIR} PARENT_SCOPE)
add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/html/index.html" "${XML_DIR}/index.xml"
COMMAND ${CMAKE_COMMAND} -E remove -f html/* xml/*
COMMAND ${CMAKE_COMMAND} -E remove -f html/* xml/*
COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile
DEPENDS ${DOC_INPUT_FILES}
)
add_custom_target(linphone-doc ALL DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/html/index.html" "${XML_DIR}/index.xml")
install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/html" "${XML_DIR}"
DESTINATION "${CMAKE_INSTALL_DATADIR}/doc/linphone-${LINPHONE_VERSION}")
if(ENABLE_DOC)
install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/html" "${XML_DIR}"
DESTINATION "${CMAKE_INSTALL_DATADIR}/doc/linphone-${LINPHONE_VERSION}")
endif()
else()
if (ENABLE_CXX_WRAPPER)
message(FATAL_ERROR "The dot program is needed to generate the linphone documentation. You can get it from http://www.graphviz.org/.")

View file

@ -1045,7 +1045,7 @@ IGNORE_PREFIX =
# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output
# The default value is: YES.
GENERATE_HTML = YES
GENERATE_HTML = ${GENERATE_HTML}
# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a
# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
@ -1589,7 +1589,7 @@ EXTRA_SEARCH_MAPPINGS =
# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output.
# The default value is: YES.
GENERATE_LATEX = YES
GENERATE_LATEX = NO
# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a
# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
@ -1825,7 +1825,7 @@ RTF_SOURCE_CODE = NO
# classes and files.
# The default value is: NO.
GENERATE_MAN = YES
GENERATE_MAN = NO
# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a
# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of

View file

@ -21,7 +21,9 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "linphone/core.h"
#include "linphone/sipsetup.h"
#include "linphone/lpconfig.h"
#include "linphone/logging.h"
#include "private.h"
#include "logging-private.h"
#include "quality_reporting.h"
#include "lime.h"
#include "conference_private.h"
@ -500,40 +502,17 @@ void linphone_core_set_log_file(FILE *file) {
}
void linphone_core_set_log_level(OrtpLogLevel loglevel) {
unsigned int mask = loglevel;
switch (loglevel) {
case ORTP_TRACE:
case ORTP_DEBUG:
mask |= ORTP_DEBUG;
BCTBX_NO_BREAK;
case ORTP_MESSAGE:
mask |= ORTP_MESSAGE;
BCTBX_NO_BREAK;
case ORTP_WARNING:
mask |= ORTP_WARNING;
BCTBX_NO_BREAK;
case ORTP_ERROR:
mask |= ORTP_ERROR;
BCTBX_NO_BREAK;
case ORTP_FATAL:
mask |= ORTP_FATAL;
break;
case ORTP_LOGLEV_END:
break;
}
linphone_core_set_log_level_mask(mask);
LinphoneLoggingService *log_service = linphone_logging_service_get();
linphone_logging_service_set_log_level(log_service, _bctbx_log_level_to_linphone_log_level(loglevel));
}
void linphone_core_set_log_level_mask(unsigned int loglevel) {
bctbx_set_log_level_mask("bctbx", (int)loglevel);
bctbx_set_log_level_mask("ortp", (int)loglevel);
bctbx_set_log_level_mask("mediastreamer", (int)loglevel);
bctbx_set_log_level_mask("bzrtp", (int)loglevel); /*need something to set log level for all domains*/
bctbx_set_log_level_mask("linphone", (int)loglevel);
sal_set_log_level((OrtpLogLevel)loglevel);
void linphone_core_set_log_level_mask(unsigned int mask) {
LinphoneLoggingService *log_service = linphone_logging_service_get();
linphone_logging_service_set_log_level_mask(log_service, _bctbx_log_mask_to_linphone_log_mask(mask));
}
unsigned int linphone_core_get_log_level_mask(void) {
return bctbx_get_log_level_mask(ORTP_LOG_DOMAIN);
LinphoneLoggingService *log_service = linphone_logging_service_get();
return linphone_logging_service_get_log_level_mask(log_service);
}
static int _open_log_collection_file_with_idx(int idx) {
struct stat statbuf;
@ -2299,6 +2278,8 @@ static void linphone_core_init(LinphoneCore * lc, LinphoneCoreCbs *cbs, LpConfig
lc->vcard_context = linphone_vcard_context_new();
linphone_core_initialize_supported_content_types(lc);
lc->bw_controller = ms_bandwidth_controller_new();
getPlatformHelpers(lc)->setDnsServers();
LinphoneFriendList *list = linphone_core_create_friend_list(lc);
linphone_friend_list_set_display_name(list, "_default");
@ -2341,17 +2322,6 @@ void linphone_core_start (LinphoneCore *lc) {
}
}
#ifdef __ANDROID__
static void _linphone_core_set_platform_helpers(LinphoneCore *lc, LinphonePrivate::PlatformHelpers *ph){
if (lc->platform_helper) delete getPlatformHelpers(lc);
lc->platform_helper = ph;
}
static void _linphone_core_set_system_context(LinphoneCore *lc, void *system_context){
_linphone_core_set_platform_helpers(lc, LinphonePrivate::createAndroidPlatformHelpers(lc, system_context));
}
#endif
LinphoneCore *_linphone_core_new_with_config(LinphoneCoreCbs *cbs, struct _LpConfig *config, void *userdata, void *system_context, bool_t automatically_start) {
LinphoneCore *core = L_INIT(Core);
Core::create(core);

View file

@ -4462,7 +4462,7 @@ extern "C" jlong Java_org_linphone_core_LinphoneChatRoomImpl_getPeerAddress(JNIE
,jlong ptr) {
return (jlong) linphone_chat_room_get_peer_address((LinphoneChatRoom*)ptr);
}
extern "C" jlong Java_org_linphone_core_LinphoneChatRoomImpl_createLinphoneChatMessage(JNIEnv* env
extern "C" jobject Java_org_linphone_core_LinphoneChatRoomImpl_createLinphoneChatMessage(JNIEnv* env
,jobject thiz
,jlong ptr
,jstring jmessage) {
@ -4470,29 +4470,10 @@ extern "C" jlong Java_org_linphone_core_LinphoneChatRoomImpl_createLinphoneChatM
LinphoneChatMessage *chatMessage = linphone_chat_room_create_message((LinphoneChatRoom *)ptr, message);
ReleaseStringUTFChars(env, jmessage, message);
return (jlong) chatMessage;
return getChatMessage(env, chatMessage);
}
extern "C" jlong Java_org_linphone_core_LinphoneChatRoomImpl_createLinphoneChatMessage2(JNIEnv* env
,jobject thiz
,jlong ptr
,jstring jmessage
,jstring jurl
,jint state
,jlong time
,jboolean read
,jboolean incoming) {
const char* message = GetStringUTFChars(env, jmessage);
const char* url = GetStringUTFChars(env, jurl);
LinphoneChatMessage *chatMessage = linphone_chat_room_create_message_2(
(LinphoneChatRoom *)ptr, message, url, (LinphoneChatMessageState)state,
(time_t)time, read, incoming);
ReleaseStringUTFChars(env, jmessage, message);
ReleaseStringUTFChars(env, jurl, url);
return (jlong) chatMessage;
}
extern "C" jint Java_org_linphone_core_LinphoneChatRoomImpl_getHistorySize (JNIEnv* env
,jobject thiz
,jlong ptr) {
@ -4527,7 +4508,7 @@ extern "C" void Java_org_linphone_core_LinphoneChatRoomImpl_markAsRead(JNIEnv*
}
extern "C" jlong Java_org_linphone_core_LinphoneChatRoomImpl_createFileTransferMessage(JNIEnv* env, jobject thiz, jlong ptr, jstring jname, jstring jtype, jstring jsubtype, jint data_size) {
extern "C" jobject Java_org_linphone_core_LinphoneChatRoomImpl_createFileTransferMessage(JNIEnv* env, jobject thiz, jlong ptr, jstring jname, jstring jtype, jstring jsubtype, jint data_size) {
LinphoneCore *lc = linphone_chat_room_get_core((LinphoneChatRoom*) ptr);
LinphoneContent * content = linphone_core_create_content(lc);
LinphoneChatMessage *message = NULL;
@ -4548,7 +4529,7 @@ extern "C" jlong Java_org_linphone_core_LinphoneChatRoomImpl_createFileTransferM
linphone_content_unref(content);
return (jlong) message;
return getChatMessage(env, message);
}
extern "C" jboolean Java_org_linphone_core_LinphoneChatRoomImpl_islimeAvailable(JNIEnv *env, jobject thiz, jlong ptr) {
@ -4726,6 +4707,22 @@ extern "C" void Java_org_linphone_core_LinphoneChatMessageImpl_reSend(JNIEnv* e
linphone_chat_message_resend_2((LinphoneChatMessage*)ptr);
}
static jobject getMessageListener(JNIEnv *env, LinphoneChatMessage *msg){
jobject listener = (jobject) linphone_chat_message_get_message_state_changed_cb_user_data(msg);
if (listener == NULL) {
ms_error("message_state_changed() notification without listener");
return NULL;
}
listener = env->NewLocalRef(listener); //promote the weak ref into a local ref*/
if (listener == NULL){
ms_error("message_state_changed() listener is no longer valid");
linphone_chat_message_set_message_state_changed_cb_user_data(msg, NULL);
return NULL;
}
return listener;
}
static void message_state_changed(LinphoneChatMessage* msg, LinphoneChatMessageState state) {
JNIEnv *env = 0;
jint result = jvm->AttachCurrentThread(&env,NULL);
@ -4734,12 +4731,9 @@ static void message_state_changed(LinphoneChatMessage* msg, LinphoneChatMessageS
return;
}
jobject listener = (jobject) linphone_chat_message_get_message_state_changed_cb_user_data(msg);
jobject listener = getMessageListener(env, msg);
if (!listener) return;
if (listener == NULL) {
ms_error("message_state_changed() notification without listener");
return ;
}
jclass clazz = (jclass) env->GetObjectClass(listener);
jmethodID method = env->GetMethodID(clazz, "onLinphoneChatMessageStateChanged","(Lorg/linphone/core/LinphoneChatMessage;Lorg/linphone/core/LinphoneChatMessage$State;)V");
jobject jmessage = getChatMessage(env, msg);
@ -4749,14 +4743,7 @@ static void message_state_changed(LinphoneChatMessage* msg, LinphoneChatMessageS
LinphoneCore *lc = linphone_chat_room_get_core(room);
LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc);
env->CallVoidMethod(listener, method, jmessage, env->CallStaticObjectMethod(ljb->chatMessageStateClass, ljb->chatMessageStateFromIntId, (jint)state));
if (state == LinphoneChatMessageStateDisplayed) {
env->DeleteGlobalRef(listener);
linphone_chat_message_set_message_state_changed_cb_user_data(msg, NULL);
}
if (jmessage) {
env->DeleteLocalRef(jmessage);
}
env->DeleteLocalRef(listener);
}
static void file_transfer_progress_indication(LinphoneChatMessage *msg, const LinphoneContent* content, size_t offset, size_t total) {
@ -4767,7 +4754,8 @@ static void file_transfer_progress_indication(LinphoneChatMessage *msg, const Li
return;
}
jobject listener = (jobject) linphone_chat_message_get_message_state_changed_cb_user_data(msg);
jobject listener = getMessageListener(env, msg);
if (!listener) return;
jclass clazz = (jclass) env->GetObjectClass(listener);
jmethodID method = env->GetMethodID(clazz, "onLinphoneChatMessageFileTransferProgressChanged", "(Lorg/linphone/core/LinphoneChatMessage;Lorg/linphone/core/LinphoneContent;II)V");
env->DeleteLocalRef(clazz);
@ -4790,7 +4778,8 @@ static void file_transfer_recv(LinphoneChatMessage *msg, const LinphoneContent*
return;
}
jobject listener = (jobject) linphone_chat_message_get_message_state_changed_cb_user_data(msg);
jobject listener = getMessageListener(env, msg);
if (!listener) return;
jclass clazz = (jclass) env->GetObjectClass(listener);
jmethodID method = env->GetMethodID(clazz, "onLinphoneChatMessageFileTransferReceived", "(Lorg/linphone/core/LinphoneChatMessage;Lorg/linphone/core/LinphoneContent;Lorg/linphone/core/LinphoneBuffer;)V");
env->DeleteLocalRef(clazz);
@ -4819,7 +4808,8 @@ static LinphoneBuffer* file_transfer_send(LinphoneChatMessage *msg, const Linph
return buffer;
}
jobject listener = (jobject) linphone_chat_message_get_message_state_changed_cb_user_data(msg);
jobject listener = getMessageListener(env, msg);
if (!listener) return NULL;
jclass clazz = (jclass) env->GetObjectClass(listener);
jmethodID method = env->GetMethodID(clazz, "onLinphoneChatMessageFileTransferSent","(Lorg/linphone/core/LinphoneChatMessage;Lorg/linphone/core/LinphoneContent;IILorg/linphone/core/LinphoneBuffer;)V");
env->DeleteLocalRef(clazz);
@ -4840,12 +4830,15 @@ static LinphoneBuffer* file_transfer_send(LinphoneChatMessage *msg, const Linph
return buffer;
}
/*
* When the listener is set, we must take a global reference to the listener and the message, so that
* we are able to notify the state changes of the message, until it reaches its final state
*/
extern "C" void Java_org_linphone_core_LinphoneChatMessageImpl_setListener(JNIEnv* env, jobject thiz, jlong ptr, jobject jlistener) {
jobject listener = env->NewGlobalRef(jlistener);
LinphoneChatMessage *message = (LinphoneChatMessage *)ptr;
LinphoneChatMessageCbs *cbs;
linphone_chat_message_set_message_state_changed_cb_user_data(message, listener);
linphone_chat_message_set_message_state_changed_cb_user_data(message, env->NewWeakGlobalRef(jlistener));
cbs = linphone_chat_message_get_callbacks(message);
linphone_chat_message_cbs_set_msg_state_changed(cbs, message_state_changed);
linphone_chat_message_cbs_set_file_transfer_progress_indication(cbs, file_transfer_progress_indication);
@ -4857,10 +4850,15 @@ extern "C" void Java_org_linphone_core_LinphoneChatMessageImpl_unref(JNIEnv* en
,jobject thiz
,jlong ptr) {
jobject wref = (jobject)linphone_chat_message_get_user_data((LinphoneChatMessage*)ptr);
jobject listener_wref = (jobject) linphone_chat_message_get_message_state_changed_cb_user_data((LinphoneChatMessage*)ptr);
linphone_chat_message_set_user_data((LinphoneChatMessage*)ptr, NULL);
if (wref){
env->DeleteWeakGlobalRef(wref);
}
if (listener_wref){
linphone_chat_message_set_message_state_changed_cb_user_data((LinphoneChatMessage*)ptr, NULL);
env->DeleteWeakGlobalRef(listener_wref);
}
linphone_chat_message_unref((LinphoneChatMessage*)ptr);
}
@ -4895,34 +4893,6 @@ extern "C" void Java_org_linphone_core_LinphoneChatRoomImpl_sendMessage(JNIEnv*
ReleaseStringUTFChars(env, jmessage, message);
}
static void chat_room_impl_callback(LinphoneChatMessage* msg, LinphoneChatMessageState state, void* ud) {
JNIEnv *env = 0;
jint result = jvm->AttachCurrentThread(&env,NULL);
if (result != 0) {
ms_error("cannot attach VM\n");
return;
}
jobject listener = (jobject) ud;
jclass clazz = (jclass) env->GetObjectClass(listener);
jmethodID method = env->GetMethodID(clazz, "onLinphoneChatMessageStateChanged","(Lorg/linphone/core/LinphoneChatMessage;Lorg/linphone/core/LinphoneChatMessage$State;)V");
jobject jmessage=(jobject)linphone_chat_message_get_user_data(msg);
LinphoneChatRoom *room = linphone_chat_message_get_chat_room(msg);
LinphoneCore *lc = linphone_chat_room_get_core(room);
LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc);
env->CallVoidMethod(
listener,
method,
jmessage,
env->CallStaticObjectMethod(ljb->chatMessageStateClass,ljb->chatMessageStateFromIntId,(jint)state));
if (state == LinphoneChatMessageStateDisplayed ) {
env->DeleteGlobalRef(listener);
env->DeleteGlobalRef(jmessage);
linphone_chat_message_set_user_data(msg,NULL);
}
}
extern "C" jobject Java_org_linphone_core_LinphoneChatRoomImpl_getCore(JNIEnv* env
,jobject thiz
@ -4933,36 +4903,13 @@ extern "C" jobject Java_org_linphone_core_LinphoneChatRoomImpl_getCore(JNIEnv*
return core;
}
extern "C" void Java_org_linphone_core_LinphoneChatRoomImpl_sendMessage2(JNIEnv* env
,jobject thiz
,jlong chatroom_ptr
,jobject message
,jlong messagePtr
,jobject jlistener) {
jobject listener = env->NewGlobalRef(jlistener);
LinphoneChatMessage *msg = (LinphoneChatMessage *)messagePtr;
message = env->NewGlobalRef(message);
linphone_chat_message_ref(msg);
linphone_chat_message_set_user_data(msg, message);
LinphoneChatMessageCbs *cbs;
cbs = linphone_chat_message_get_callbacks(msg);
linphone_chat_message_cbs_set_user_data(cbs, (void *)listener);
linphone_chat_message_cbs_set_msg_state_changed(cbs, message_state_changed);
linphone_chat_message_cbs_set_file_transfer_progress_indication(cbs, file_transfer_progress_indication);
linphone_chat_message_cbs_set_file_transfer_recv(cbs, file_transfer_recv);
linphone_chat_message_cbs_set_file_transfer_send(cbs, file_transfer_send);
linphone_chat_room_send_chat_message_2((LinphoneChatRoom*)chatroom_ptr, msg);
}
extern "C" void Java_org_linphone_core_LinphoneChatRoomImpl_sendChatMessage(JNIEnv* env
,jobject thiz
,jlong chatroom_ptr
,jobject message
,jlong messagePtr) {
message = env->NewGlobalRef(message);
linphone_chat_message_set_user_data((LinphoneChatMessage*)messagePtr, message);
linphone_chat_room_send_chat_message_2((LinphoneChatRoom*)chatroom_ptr, (LinphoneChatMessage*)messagePtr);
}

61
coreapi/logging-private.h Normal file
View file

@ -0,0 +1,61 @@
/*
logging-private.h
Copyright (C) 2017 Belledonne Communications SARL
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 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 _LOGGING_PRIVATE_H_
#define _LOGGING_PRIVATE_H_
#include <bctoolbox/logging.h>
#include "linphone/logging.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Converts a #BctbxLogLevel into #LinphoneLogLevel.
*/
LinphoneLogLevel _bctbx_log_level_to_linphone_log_level(BctbxLogLevel level);
/**
* @brief Converts a mask of #BctbxLogLevel into a mask of #LinphoneLogLevel.
*/
unsigned int _bctbx_log_mask_to_linphone_log_mask(unsigned int mask);
/**
* @brief Converts a #LinphoneLogLevel into #BctbxLogLevel.
*/
BctbxLogLevel _linphone_log_level_to_bctbx_log_level(LinphoneLogLevel level);
/**
* @brief Converts a mask of #LinphoneLogLevel into a mask of #BctbxLogLevel.
*/
unsigned int _linphone_log_mask_to_bctbx_log_mask(unsigned int mask);
/**
* @brief Releases the instance pointer of the singleton.
* @note You should not need to call this function since it is automatically done
* at process ending.
*/
void _linphone_logging_service_clean(void);
#ifdef __cplusplus
}
#endif
#endif // _LOGGING_PRIVATE_H_

261
coreapi/logging.c Normal file
View file

@ -0,0 +1,261 @@
/*
log.c
Copyright (C) 2017 Belledonne Communications SARL
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 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 <algorithm>
#include <map>
#include <bctoolbox/logging.h>
#include <belle-sip/object.h>
#include <mediastreamer2/mscommon.h>
#include "linphone/logging.h"
#include "c-wrapper/c-wrapper.h"
#include "logging-private.h"
struct _LinphoneLoggingService {
belle_sip_object_t base;
LinphoneLoggingServiceCbs *cbs;
bctbx_log_handler_t *log_handler;
};
BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneLoggingService);
BELLE_SIP_DECLARE_VPTR_NO_EXPORT(LinphoneLoggingService);
struct _LinphoneLoggingServiceCbs {
belle_sip_object_t base;
void *user_data;
LinphoneLoggingServiceCbsLogMessageWrittenCb message_event_cb;
};
BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneLoggingServiceCbs);
BELLE_SIP_DECLARE_VPTR_NO_EXPORT(LinphoneLoggingServiceCbs);
static LinphoneLoggingServiceCbs *_linphone_logging_service_cbs_new(void);
static LinphoneLoggingService *_linphone_logging_service_instance = NULL;
static std::map<LinphoneLogLevel, BctbxLogLevel> _linphone_log_level_to_bctbx_log_level_map = {
{ LinphoneLogLevelDebug , BCTBX_LOG_DEBUG },
{ LinphoneLogLevelTrace , BCTBX_LOG_TRACE },
{ LinphoneLogLevelMessage , BCTBX_LOG_MESSAGE },
{ LinphoneLogLevelWarning , BCTBX_LOG_WARNING },
{ LinphoneLogLevelError , BCTBX_LOG_ERROR },
{ LinphoneLogLevelFatal , BCTBX_LOG_FATAL }
};
LinphoneLogLevel _bctbx_log_level_to_linphone_log_level(BctbxLogLevel level) {
auto &tmap = _linphone_log_level_to_bctbx_log_level_map;
auto predicate = [level](const std::pair<LinphoneLogLevel, BctbxLogLevel> &tuple)->bool{return tuple.second==level;};
auto response = std::find_if(tmap.cbegin(), tmap.cend(), predicate);
if (response != tmap.cend()) {
return response->first;
} else {
ms_warning("%s(): invalid argurement [%d]", __FUNCTION__, level);
return LinphoneLogLevelDebug;
}
}
unsigned int _bctbx_log_mask_to_linphone_log_mask(unsigned int mask) {
unsigned int res = 0;
auto &tmap = _linphone_log_level_to_bctbx_log_level_map;
for (auto it=tmap.cbegin(); it!=tmap.cend(); it++) {
if (mask & it->second) {
mask&=~it->second;
res|=it->first;
}
}
if (mask != 0) {
ms_fatal("%s(): invalid flag set in mask [%x]", __FUNCTION__, mask);
}
return res;
}
BctbxLogLevel _linphone_log_level_to_bctbx_log_level(LinphoneLogLevel level) {
try {
return _linphone_log_level_to_bctbx_log_level_map.at(level);
} catch (const std::out_of_range &e) {
ms_fatal("%s(): invalid argument [%d]", __FUNCTION__, level);
return BCTBX_LOG_LOGLEV_END;
}
}
unsigned int _linphone_log_mask_to_bctbx_log_mask(unsigned int mask) {
unsigned int res = 0;
auto &tmap = _linphone_log_level_to_bctbx_log_level_map;
for (auto it=tmap.cbegin(); it!=tmap.cend(); it++) {
if (mask & it->first) {
mask&=~it->first;
res|=it->second;
}
}
if (mask != 0) {
ms_fatal("%s(): invalid flag set in mask [%x]", __FUNCTION__, mask);
}
return res;
}
static void _log_handler_on_message_written_cb(void *info,const char *domain, BctbxLogLevel lev, const char *fmt, va_list args) {
LinphoneLoggingService *service = (LinphoneLoggingService *)info;
if (service->cbs->message_event_cb) {
char *message = bctbx_strdup_vprintf(fmt, args);
service->cbs->message_event_cb(service, domain, _bctbx_log_level_to_linphone_log_level(lev), message);
bctbx_free(message);
}
}
static void _log_handler_destroy_cb(bctbx_log_handler_t *handler) {
LinphoneLoggingService *service = (LinphoneLoggingService *)bctbx_log_handler_get_user_data(handler);
service->log_handler = NULL;
}
static LinphoneLoggingService *_linphone_logging_service_new(void) {
LinphoneLoggingService *service = belle_sip_object_new(LinphoneLoggingService);
service->log_handler = bctbx_create_log_handler(_log_handler_on_message_written_cb, _log_handler_destroy_cb, service);
service->cbs = _linphone_logging_service_cbs_new();
bctbx_add_log_handler(service->log_handler);
return service;
}
LinphoneLoggingService *linphone_logging_service_get(void) {
if (_linphone_logging_service_instance == NULL) {
_linphone_logging_service_instance = _linphone_logging_service_new();
atexit(_linphone_logging_service_clean);
}
return _linphone_logging_service_instance;
}
void _linphone_logging_service_clean(void) {
if (_linphone_logging_service_instance) {
linphone_logging_service_unref(_linphone_logging_service_instance);
_linphone_logging_service_instance = NULL;
}
}
LinphoneLoggingService *linphone_logging_service_ref(LinphoneLoggingService *service) {
return (LinphoneLoggingService *)belle_sip_object_ref(service);
}
void linphone_logging_service_unref(LinphoneLoggingService *service) {
belle_sip_object_ref(service);
}
static void _linphone_logging_service_uninit(LinphoneLoggingService *log_service) {
if (log_service->log_handler) bctbx_remove_log_handler(log_service->log_handler);
linphone_logging_service_cbs_unref(log_service->cbs);
}
void linphone_logging_service_release_instance(void) {
if (_linphone_logging_service_instance) {
belle_sip_object_unref(BELLE_SIP_OBJECT(_linphone_logging_service_instance));
}
_linphone_logging_service_instance = NULL;
}
LinphoneLoggingServiceCbs *linphone_logging_service_get_callbacks(const LinphoneLoggingService *log_service) {
return log_service->cbs;
}
static const char *_linphone_logging_service_log_domains[] = {
"bctbx",
"belle-sip",
"ortp",
"mediastreamer",
"bzrtp",
"linphone",
NULL
};
void linphone_logging_service_set_log_level(LinphoneLoggingService *log_service, LinphoneLogLevel loglevel) {
const char **domain;
for (domain=_linphone_logging_service_log_domains; *domain; domain++) {
bctbx_set_log_level(*domain, _linphone_log_level_to_bctbx_log_level(loglevel));
}
}
void linphone_logging_service_set_log_level_mask(LinphoneLoggingService *log_service, unsigned int mask) {
const char **domain;
for (domain=_linphone_logging_service_log_domains; *domain; domain++) {
bctbx_set_log_level_mask(*domain, (int)_linphone_log_mask_to_bctbx_log_mask(mask));
}
}
unsigned int linphone_logging_service_get_log_level_mask(const LinphoneLoggingService *log_service) {
return _bctbx_log_mask_to_linphone_log_mask(bctbx_get_log_level_mask(ORTP_LOG_DOMAIN));
}
void linphone_logging_service_set_log_file(const LinphoneLoggingService *service, const char *dir, const char *filename, size_t max_size) {
bctbx_log_handler_t *log_handler = bctbx_create_file_log_handler((uint64_t)max_size, dir, filename, NULL);
bctbx_add_log_handler(log_handler);
}
BELLE_SIP_INSTANCIATE_VPTR(LinphoneLoggingService, belle_sip_object_t,
_linphone_logging_service_uninit, // uninit
NULL, // clone
NULL, // marshal
FALSE // unown
);
static LinphoneLoggingServiceCbs *_linphone_logging_service_cbs_new(void) {
return belle_sip_object_new(LinphoneLoggingServiceCbs);
}
LinphoneLoggingServiceCbs *linphone_logging_service_cbs_ref(LinphoneLoggingServiceCbs *cbs) {
return (LinphoneLoggingServiceCbs *)belle_sip_object_ref(cbs);
}
void linphone_logging_service_cbs_unref(LinphoneLoggingServiceCbs *cbs) {
belle_sip_object_unref(cbs);
}
void linphone_logging_service_cbs_set_log_message_written(LinphoneLoggingServiceCbs *cbs, LinphoneLoggingServiceCbsLogMessageWrittenCb cb) {
cbs->message_event_cb = cb;
}
LinphoneLoggingServiceCbsLogMessageWrittenCb linphone_logging_service_cbs_get_log_message_written(const LinphoneLoggingServiceCbs *cbs) {
return cbs->message_event_cb;
}
void linphone_logging_service_cbs_set_user_data(LinphoneLoggingServiceCbs *cbs, void *user_data) {
cbs->user_data = user_data;
}
void *linphone_logging_service_cbs_get_user_data(const LinphoneLoggingServiceCbs *cbs) {
return cbs->user_data;
}
BELLE_SIP_INSTANCIATE_VPTR(LinphoneLoggingServiceCbs, belle_sip_object_t,
NULL, // uninit
NULL, // clone
NULL, // marshal
FALSE // unown
);

View file

@ -919,8 +919,11 @@ void linphone_core_report_call_log(LinphoneCore *lc, LinphoneCallLog *call_log){
}
linphone_address_unref(conference_factory_addr);
}
const char *username = linphone_address_get_username(call_log->to);
if (username && (strstr(username, "chatroom-") == username))
const char *usernameFrom = linphone_address_get_username(call_log->from);
const char *usernameTo = linphone_address_get_username(call_log->to);
if ((usernameFrom && (strstr(usernameFrom, "chatroom-") == usernameFrom))
|| (usernameTo && (strstr(usernameTo, "chatroom-") == usernameTo))
)
return;
// End of workaround

View file

@ -238,7 +238,6 @@ LinphoneFriend * linphone_friend_new_from_config_file(struct _LinphoneCore *lc,
void linphone_proxy_config_update(LinphoneProxyConfig *cfg);
LinphoneProxyConfig * linphone_core_lookup_known_proxy(LinphoneCore *lc, const LinphoneAddress *uri);
const char *linphone_core_find_best_identity(LinphoneCore *lc, const LinphoneAddress *to);
int linphone_core_get_local_ip_for(int type, const char *dest, char *result);
LINPHONE_PUBLIC void linphone_core_get_local_ip(LinphoneCore *lc, int af, const char *dest, char *result);
LinphoneProxyConfig *linphone_proxy_config_new_from_config_file(LinphoneCore *lc, int index);
@ -288,6 +287,7 @@ void _linphone_chat_room_notify_participant_device_removed(LinphoneChatRoom *cr,
void _linphone_chat_room_notify_participant_admin_status_changed(LinphoneChatRoom *cr, const LinphoneEventLog *event_log);
void _linphone_chat_room_notify_state_changed(LinphoneChatRoom *cr, LinphoneChatRoomState newState);
void _linphone_chat_room_notify_subject_changed(LinphoneChatRoom *cr, const LinphoneEventLog *event_log);
void _linphone_chat_room_notify_all_information_received(LinphoneChatRoom *cr);
void _linphone_chat_room_notify_undecryptable_message_received(LinphoneChatRoom *cr, LinphoneChatMessage *msg);
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);

View file

@ -48,6 +48,7 @@ extern "C" {
LINPHONE_PUBLIC LinphoneVcardContext *linphone_core_get_vcard_context(const LinphoneCore *lc);
LINPHONE_PUBLIC bool_t linphone_core_rtcp_enabled(const LinphoneCore *lc);
LINPHONE_PUBLIC void linphone_core_get_local_ip(LinphoneCore *lc, int af, const char *dest, char *result);
LINPHONE_PUBLIC int linphone_core_get_local_ip_for(int type, const char *dest, char *result);
LINPHONE_PUBLIC void linphone_core_enable_forced_ice_relay(LinphoneCore *lc, bool_t enable);
LINPHONE_PUBLIC void linphone_core_set_zrtp_not_available_simulation(LinphoneCore *lc, bool_t enabled);
LINPHONE_PUBLIC belle_http_provider_t *linphone_core_get_http_provider(const LinphoneCore *lc);

View file

@ -48,6 +48,7 @@ set(ROOT_HEADER_FILES
im_notif_policy.h
info_message.h
ldapprovider.h
logging.h
lpconfig.h
misc.h
nat_policy.h

View file

@ -338,6 +338,7 @@ LINPHONE_PUBLIC LinphoneConference *linphone_call_get_conference (const Linphone
* Change the playback output device (currently only used for blackberry)
* @param call
* @param route the wanted audio route (earpiece, speaker, ...)
* @donotwrap
**/
LINPHONE_PUBLIC void linphone_call_set_audio_route (LinphoneCall *call, LinphoneAudioRoute route);
@ -474,9 +475,8 @@ LINPHONE_PUBLIC LinphoneStatus linphone_call_accept_early_media_with_params (Lin
/**
* Updates a running call according to supplied call parameters or parameters changed in the LinphoneCore.
* In this version this is limited to the following use cases:
* - setting up/down the video stream according to the video parameter of the #LinphoneCallParams (see linphone_call_params_enable_video() ).
* - changing the size of the transmitted video after calling linphone_core_set_preferred_video_size()
* It triggers a SIP reINVITE in order to perform a new offer/answer of media capabilities.
* Changing the size of the transmitted video after calling #linphone_core_set_preferred_video_size() can be used by passing NULL as params argument.
* In case no changes are requested through the #LinphoneCallParams argument, then this argument can be omitted and set to NULL.
* WARNING: Updating a call in the #LinphoneCallPaused state will still result in a paused call even if the media directions set in the
* params are sendrecv. To resume a paused call, you need to call linphone_call_resume().

View file

@ -235,6 +235,12 @@ typedef void (*LinphoneChatRoomCbsParticipantDeviceAddedCb) (LinphoneChatRoom *c
*/
typedef void (*LinphoneChatRoomCbsParticipantDeviceRemovedCb) (LinphoneChatRoom *cr, const LinphoneEventLog *event_log);
/**
* Callback used to notify a chat room has received all its information.
* @param[in] cr #LinphoneChatRoom object
*/
typedef void (*LinphoneChatRoomCbsAllInformationReceivedCb) (LinphoneChatRoom *cr);
/**
* Callback used when a group chat room is created server-side to generate the address of the chat room.
* The function linphone_chat_room_set_conference_address() needs to be called by this callback.

View file

@ -369,6 +369,8 @@ LINPHONE_PUBLIC const char* linphone_chat_message_get_text_content(const Linphon
*/
LINPHONE_PUBLIC bool_t linphone_chat_message_is_file_transfer_in_progress(LinphoneChatMessage *msg);
LINPHONE_PUBLIC bctbx_list_t *linphone_chat_message_get_participants_in_state (const LinphoneChatMessage *msg, const LinphoneChatMessageState state);
/**
* @}
*/

View file

@ -229,6 +229,20 @@ LINPHONE_PUBLIC LinphoneChatRoomCbsParticipantDeviceRemovedCb linphone_chat_room
*/
LINPHONE_PUBLIC void linphone_chat_room_cbs_set_participant_device_removed (LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsParticipantDeviceRemovedCb cb);
/**
* Get the all information received callback.
* @param[in] cbs LinphoneChatRoomCbs object.
* @return The current all information received callback.
*/
LINPHONE_PUBLIC LinphoneChatRoomCbsAllInformationReceivedCb linphone_chat_room_cbs_get_all_information_received (const LinphoneChatRoomCbs *cbs);
/**
* Set the all information received callback.
* @param[in] cbs LinphoneChatRoomCbs object.
* @param[in] cb The all information received callback to be used.
*/
LINPHONE_PUBLIC void linphone_chat_room_cbs_set_all_information_received (LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsAllInformationReceivedCb cb);
/**
* Get the conference address generation callback.
* @param[in] cbs #LinphoneChatRoomCbs object

View file

@ -227,6 +227,12 @@ LINPHONE_PUBLIC int linphone_chat_room_get_history_events_size(LinphoneChatRoom
*/
LINPHONE_PUBLIC LinphoneChatMessage *linphone_chat_room_get_last_message_in_history(LinphoneChatRoom *cr);
/**
* Gets the chat message sent or received in this chat room that matches the message_id
* @param[in] cr The #LinphoneChatRoom object corresponding to the conversation for which the message should be retrieved
* @param[in] message_id The id of the message to find
* @return the #LinphoneChatMessage
*/
LINPHONE_PUBLIC LinphoneChatMessage * linphone_chat_room_find_message(LinphoneChatRoom *cr, const char *message_id);
/**

View file

@ -52,6 +52,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "linphone/im_encryption_engine.h"
#include "linphone/im_notif_policy.h"
#include "linphone/info_message.h"
#include "linphone/logging.h"
#include "linphone/lpconfig.h"
#include "linphone/misc.h"
#include "linphone/nat_policy.h"
@ -165,7 +166,8 @@ typedef struct _LinphoneCoreVTable{
LinphoneCoreNotifyPresenceReceivedCb notify_presence_received; /**< Notify received presence events*/
LinphoneCoreNotifyPresenceReceivedForUriOrTelCb notify_presence_received_for_uri_or_tel; /**< Notify received presence events*/
LinphoneCoreNewSubscriptionRequestedCb new_subscription_requested; /**< Notify about pending presence subscription request */
LINPHONE_DEPRECATED LinphoneCoreAuthInfoRequestedCb auth_info_requested; /**< @deprecated Use authentication_requested instead. Ask the application some authentication information */
LINPHONE_DEPRECATED LinphoneCoreAuthInfoRequestedCb auth_info_requested; /** @brief Ask the application some authentication information.
@deprecated Use authentication_requested instead. Deprecated since 2016-09-21 */
LinphoneCoreAuthenticationRequestedCb authentication_requested; /**< Ask the application some authentication information */
LinphoneCoreCallLogUpdatedCb call_log_updated; /**< Notifies that call log list has been updated */
LinphoneCoreMessageReceivedCb message_received; /**< a message is received, can be text or external body*/
@ -181,11 +183,16 @@ typedef struct _LinphoneCoreVTable{
LinphoneCoreSubscriptionStateChangedCb subscription_state_changed; /**<Notifies subscription state change */
LinphoneCoreNotifyReceivedCb notify_received; /**< Notifies a an event notification, see linphone_core_subscribe() */
LinphoneCorePublishStateChangedCb publish_state_changed;/**Notifies publish state change (only from #LinphoneEvent api)*/
LinphoneCoreConfiguringStatusCb configuring_status; /** Notifies configuring status changes */
LINPHONE_DEPRECATED LinphoneCoreTextMessageReceivedCb text_received; /**< @deprecated, use #message_received instead <br> A text message has been received */
LINPHONE_DEPRECATED LinphoneCoreFileTransferRecvCb file_transfer_recv; /**< @deprecated Callback to store file received attached to a #LinphoneChatMessage */
LINPHONE_DEPRECATED LinphoneCoreFileTransferSendCb file_transfer_send; /**< @deprecated Callback to collect file chunk to be sent for a #LinphoneChatMessage */
LINPHONE_DEPRECATED LinphoneCoreFileTransferProgressIndicationCb file_transfer_progress_indication; /**< @deprecated Callback to indicate file transfer progress */
LinphoneCoreConfiguringStatusCb configuring_status; /**< Notifies configuring status changes
@deprecated Deprecated since 2015-11-19. */
LINPHONE_DEPRECATED LinphoneCoreTextMessageReceivedCb text_received; /**< @brief A text message has been received.
@deprecated Use #message_received instead. Deprecated since 2015-11-19. */
LINPHONE_DEPRECATED LinphoneCoreFileTransferRecvCb file_transfer_recv; /**< @brief Callback to store file received attached to a #LinphoneChatMessage.
@deprecated Deprecated since 2015-11-19. */
LINPHONE_DEPRECATED LinphoneCoreFileTransferSendCb file_transfer_send; /**< @brief Callback to collect file chunk to be sent for a #LinphoneChatMessage.
@deprecated Deprecated since 2015-11-19. */
LINPHONE_DEPRECATED LinphoneCoreFileTransferProgressIndicationCb file_transfer_progress_indication; /**< @brief Callback to indicate file transfer progress.
@deprecated Deprecated since 2015-11-19. */
LinphoneCoreNetworkReachableCb network_reachable; /**< Callback to report IP network status (I.E up/down )*/
LinphoneCoreLogCollectionUploadStateChangedCb log_collection_upload_state_changed; /**< Callback to upload collected logs */
LinphoneCoreLogCollectionUploadProgressIndicationCb log_collection_upload_progress_indication; /**< Callback to indicate log collection upload progress */
@ -800,25 +807,28 @@ LINPHONE_PUBLIC void linphone_core_reset_log_collection(void);
/**
* @bref Define a log handler.
* @param logfunc The function pointer of the log handler.
* @deprecated Use #linphone_log_service_set_log_handler() instead. Deprecated since 2017-10-10.
* @donotwrap
*/
LINPHONE_PUBLIC void linphone_core_set_log_handler(OrtpLogFunc logfunc);
LINPHONE_PUBLIC LINPHONE_DEPRECATED void linphone_core_set_log_handler(OrtpLogFunc logfunc);
/**
* @brief Define a log file.
*
* If the file pointer passed as an argument is NULL, stdout is used instead.
* @param file A pointer to the FILE structure of the file to write to.
* @deprecated Use #linphone_log_service_set_file() instead. Deprecated since 2017-10-10.
* @donotwrap
*/
LINPHONE_PUBLIC void linphone_core_set_log_file(FILE *file);
LINPHONE_PUBLIC LINPHONE_DEPRECATED void linphone_core_set_log_file(FILE *file);
/**
* @brief Define the minimum level for logging.
* @param loglevel Minimum level for logging messages.
* @deprecated Use #linphone_logging_service_set_log_level() instead. Deprecated since 2017-10-10.
* @donotwrap
**/
LINPHONE_PUBLIC void linphone_core_set_log_level(OrtpLogLevel loglevel);
LINPHONE_PUBLIC LINPHONE_DEPRECATED void linphone_core_set_log_level(OrtpLogLevel loglevel);
/**
* Define the log level using mask.
@ -826,22 +836,25 @@ LINPHONE_PUBLIC void linphone_core_set_log_level(OrtpLogLevel loglevel);
* The loglevel parameter is a bitmask parameter. Therefore to enable only warning and error
* messages, use ORTP_WARNING | ORTP_ERROR. To disable logs, simply set loglevel to 0.
*
* @param loglevel A bitmask of the log levels to set.
* @param mask A bitmask of the log levels to set.
* @deprecated Use #linphone_logging_service_set_log_level() instead. Deprecated since 2017-10-10.
*/
LINPHONE_PUBLIC void linphone_core_set_log_level_mask(unsigned int loglevel);
LINPHONE_PUBLIC LINPHONE_DEPRECATED void linphone_core_set_log_level_mask(unsigned int mask);
/**
* Get defined log level mask.
*
* @return The loglevel parameter is a bitmask parameter. Therefore to enable only warning and error
* messages, use ORTP_WARNING | ORTP_ERROR. To disable logs, simply set loglevel to 0.
* @deprecated Use #linphone_logging_service_get_log_level_mask() instead. Deprecated since 2017-10-10.
*/
LINPHONE_PUBLIC unsigned int linphone_core_get_log_level_mask(void);
LINPHONE_PUBLIC LINPHONE_DEPRECATED unsigned int linphone_core_get_log_level_mask(void);
/**
* Enable logs in supplied FILE*.
* @param file a C FILE* where to fprintf logs. If null stdout is used.
* @deprecated Use #linphone_core_set_log_file and #linphone_core_set_log_level instead.
* @deprecated Use #linphone_core_set_log_file and #linphone_core_set_log_level() instead.
* Deprecated since 2017-01-12.
* @donotwrap
**/
LINPHONE_DEPRECATED LINPHONE_PUBLIC void linphone_core_enable_logs(FILE *file);
@ -851,13 +864,14 @@ LINPHONE_DEPRECATED LINPHONE_PUBLIC void linphone_core_enable_logs(FILE *file);
* @param logfunc The address of a OrtpLogFunc callback whose protoype is
* typedef void (*OrtpLogFunc)(OrtpLogLevel lev, const char *fmt, va_list args);
* @deprecated Use #linphone_core_set_log_handler and #linphone_core_set_log_level instead.
* Deprecated since 2017-01-12.
* @donotwrap
**/
LINPHONE_DEPRECATED LINPHONE_PUBLIC void linphone_core_enable_logs_with_cb(OrtpLogFunc logfunc);
/**
* Entirely disable logging.
* @deprecated Use #linphone_core_set_log_level instead.
* @deprecated Use #linphone_core_set_log_level() instead. Deprecated since 2017-01-12.
* @donotwrap
**/
LINPHONE_DEPRECATED LINPHONE_PUBLIC void linphone_core_disable_logs(void);
@ -879,13 +893,15 @@ LINPHONE_PUBLIC const char *linphone_core_get_version(void);
LINPHONE_PUBLIC const char *linphone_core_get_user_agent(LinphoneCore *lc);
/**
* @deprecated 2016-12-20: Use #linphone_core_get_user_agent instead.
* @deprecated Use #linphone_core_get_user_agent() instead.
* Deprecated since 2015-11-19.
* @donotwrap
**/
LINPHONE_PUBLIC LINPHONE_DEPRECATED const char *linphone_core_get_user_agent_name(void);
/**
* @deprecated 2016-12-20: Use #linphone_core_get_user_agent instead.
* @deprecated Use #linphone_core_get_user_agent instead.
* Deprecated since 2015-11-19.
* @donotwrap
**/
LINPHONE_PUBLIC LINPHONE_DEPRECATED const char *linphone_core_get_user_agent_version(void);
@ -903,8 +919,8 @@ LINPHONE_PUBLIC LINPHONE_DEPRECATED const char *linphone_core_get_user_agent_ver
* @param vtable a #LinphoneCoreVTable structure holding your application callbacks
* @param config_path a path to a config file. If it does not exists it will be created.
* The config file is used to store all settings, call logs, friends, proxies... so that all these settings
* become persistent over the life of the LinphoneCore object.
* It is allowed to set a NULL config file. In that case LinphoneCore will not store any settings.
* become persistent over the life of the LinphoneCore object.
* It is allowed to set a NULL config file. In that case LinphoneCore will not store any settings.
* @param factory_config_path a path to a read-only config file that can be used to
* to store hard-coded preference such as proxy settings or internal preferences.
* The settings in this factory file always override the one in the normal config file.
@ -912,7 +928,7 @@ LINPHONE_PUBLIC LINPHONE_DEPRECATED const char *linphone_core_get_user_agent_ver
* @param userdata an opaque user pointer that can be retrieved at any time (for example in
* callbacks) using linphone_core_get_user_data().
* @see linphone_core_new_with_config
* @deprecated 2017-01-12: Use linphone_factory_create_core() instead.
* @deprecated Use #linphone_factory_create_core() instead. Deprecated since 2017-01-12.
* @donotwrap
**/
LINPHONE_DEPRECATED LINPHONE_PUBLIC LinphoneCore *linphone_core_new(const LinphoneCoreVTable *vtable,
@ -929,7 +945,7 @@ LINPHONE_DEPRECATED LINPHONE_PUBLIC LinphoneCore *linphone_core_new(const Linpho
* @param userdata an opaque user pointer that can be retrieved at any time (for example in
* callbacks) using linphone_core_get_user_data().
* @see linphone_core_new
* @deprecated 2017-01-12: Use linphone_factory_create_core_with_config() instead.
* @deprecated Use #linphone_factory_create_core_with_config() instead. Deprecated since 2017-01-12.
* @donotwrap
**/
LINPHONE_DEPRECATED LINPHONE_PUBLIC LinphoneCore *linphone_core_new_with_config(const LinphoneCoreVTable *vtable, LpConfig *config, void *userdata);
@ -980,7 +996,7 @@ LINPHONE_PUBLIC void linphone_core_iterate(LinphoneCore *lc);
* add a listener to be notified of linphone core events. Once events are received, registered vtable are invoked in order.
* @param vtable a #LinphoneCoreVTable structure holding your application callbacks. Object is owned by linphone core until linphone_core_remove_listener.
* @param lc object
* @deprecated Use linphone_core_add_callbacks() instead.
* @deprecated Use linphone_core_add_callbacks() instead. Deprecated since 2017-01-12.
* @donotwrap
*/
LINPHONE_DEPRECATED LINPHONE_PUBLIC void linphone_core_add_listener(LinphoneCore *lc, LinphoneCoreVTable *vtable);
@ -999,7 +1015,7 @@ LINPHONE_PUBLIC void linphone_core_add_callbacks(LinphoneCore *lc, LinphoneCoreC
* remove a listener registred by linphone_core_add_listener.
* @param lc object
* @param vtable a #LinphoneCoreVTable structure holding your application callbacks.
* @deprecated Use linphone_core_remove_callbacks() instead.
* @deprecated Use linphone_core_remove_callbacks() instead. Deprecated since 2017-01-12.
* @donotwrap
*/
LINPHONE_DEPRECATED LINPHONE_PUBLIC void linphone_core_remove_listener(LinphoneCore *lc, const LinphoneCoreVTable *vtable);
@ -1079,7 +1095,8 @@ LINPHONE_PUBLIC LinphoneCall * linphone_core_invite_with_params(LinphoneCore *lc
LINPHONE_PUBLIC LinphoneCall * linphone_core_invite_address_with_params(LinphoneCore *lc, const LinphoneAddress *addr, const LinphoneCallParams *params);
/**
* Performs a simple call transfer to the specified destination.
* @brief Performs a simple call transfer to the specified destination.
*
* The remote endpoint is expected to issue a new call to the specified destination.
* The current call remains active and thus can be later paused or terminated.
* It is possible to follow the progress of the transfer provided that transferee sends notification about it.
@ -1090,12 +1107,13 @@ LINPHONE_PUBLIC LinphoneCall * linphone_core_invite_address_with_params(Linphone
* @param[in] refer_to The destination the call is to be refered to
* @return 0 on success, -1 on failure
* @ingroup call_control
* @deprecated Use linphone_call_transfer() instead
* @deprecated Use #linphone_call_transfer() instead. Deprecated since 2017-02-13.
**/
LINPHONE_PUBLIC LINPHONE_DEPRECATED LinphoneStatus linphone_core_transfer_call(LinphoneCore *lc, LinphoneCall *call, const char *refer_to);
/**
* Transfers a call to destination of another running call. This is used for "attended transfer" scenarios.
* @brief Transfers a call to destination of another running call. This is used for "attended transfer" scenarios.
*
* The transfered call is supposed to be in paused state, so that it is able to accept the transfer immediately.
* The destination call is a call previously established to introduce the transfered person.
* This method will send a transfer request to the transfered person. The phone of the transfered is then
@ -1109,12 +1127,13 @@ LINPHONE_PUBLIC LINPHONE_DEPRECATED LinphoneStatus linphone_core_transfer_call(L
* @param[in] dest A running call whose remote person will receive the transfer
* @return 0 on success, -1 on failure
* @ingroup call_control
* @deprecated Use linphone_call_transfer_to_another() instead
* @deprecated Use #linphone_call_transfer_to_another() instead. Deprecated since 2017-02-13.
**/
LINPHONE_PUBLIC LINPHONE_DEPRECATED LinphoneStatus linphone_core_transfer_call_to_another(LinphoneCore *lc, LinphoneCall *call, LinphoneCall *dest);
/**
* Start a new call as a consequence of a transfer request received from a call.
* @brief Start a new call as a consequence of a transfer request received from a call.
*
* This function is for advanced usage: the execution of transfers is automatically managed by the LinphoneCore. However if an application
* wants to have control over the call parameters for the new call, it should call this function immediately during the #LinphoneCallRefered notification.
* @see LinphoneCoreVTable::call_state_changed
@ -1129,7 +1148,8 @@ LINPHONE_PUBLIC LinphoneCall * linphone_core_start_refered_call(LinphoneCore *lc
#define linphone_core_inc_invite_pending(lc) linphone_core_is_incoming_invite_pending(lc)
/**
* Tells whether there is an incoming invite pending.
* @brief Tells whether there is an incoming invite pending.
*
* @ingroup call_control
* @param[in] lc #LinphoneCore object
* @return A boolean telling whether an incoming invite is pending or not.
@ -1153,7 +1173,7 @@ LINPHONE_PUBLIC bool_t linphone_core_in_call(const LinphoneCore *lc);
LINPHONE_PUBLIC LinphoneCall *linphone_core_get_current_call(const LinphoneCore *lc);
/**
* Accept an incoming call.
* @brief Accept an incoming call.
*
* Basically the application is notified of incoming calls within the
* call_state_changed callback of the #LinphoneCoreVTable structure, where it will receive
@ -1163,12 +1183,12 @@ LINPHONE_PUBLIC LinphoneCall *linphone_core_get_current_call(const LinphoneCore
* @param[in] call The #LinphoneCall object representing the call to be answered
* @return 0 on success, -1 on failure
* @ingroup call_control
* @deprecated Use linphone_call_accept() instead
* @deprecated Use #linphone_call_accept() instead. Deprecated since 2017-02-13.
**/
LINPHONE_PUBLIC LINPHONE_DEPRECATED LinphoneStatus linphone_core_accept_call(LinphoneCore *lc, LinphoneCall *call);
/**
* Accept an incoming call, with parameters.
* @brief Accept an incoming call, with parameters.
*
* Basically the application is notified of incoming calls within the
* call_state_changed callback of the #LinphoneCoreVTable structure, where it will receive
@ -1180,12 +1200,13 @@ LINPHONE_PUBLIC LINPHONE_DEPRECATED LinphoneStatus linphone_core_accept_call(Lin
* @param[in] params The specific parameters for this call, for example whether video is accepted or not. Use NULL to use default parameters
* @return 0 on success, -1 on failure
* @ingroup call_control
* @deprecated Use linphone_call_accept_with_params() instead
* @deprecated Use #linphone_call_accept_with_params() instead. Deprecated since 2017-02-13.
**/
LINPHONE_PUBLIC LINPHONE_DEPRECATED LinphoneStatus linphone_core_accept_call_with_params(LinphoneCore *lc, LinphoneCall *call, const LinphoneCallParams *params);
/**
* When receiving an incoming, accept to start a media session as early-media.
* @brief When receiving an incoming, accept to start a media session as early-media.
*
* This means the call is not accepted but audio & video streams can be established if the remote party supports early media.
* However, unlike after call acceptance, mic and camera input are not sent during early-media, though received audio & video are played normally.
* The call can then later be fully accepted using linphone_core_accept_call() or linphone_core_accept_call_with_params().
@ -1194,29 +1215,31 @@ LINPHONE_PUBLIC LINPHONE_DEPRECATED LinphoneStatus linphone_core_accept_call_wit
* @param[in] params The call parameters to use (can be NULL)
* @return 0 if successful, -1 otherwise
* @ingroup call_control
* @deprecated Use linphone_call_accept_early_media_with_params() instead
* @deprecated Use linphone_call_accept_early_media_with_params() instead.
**/
LINPHONE_PUBLIC LINPHONE_DEPRECATED LinphoneStatus linphone_core_accept_early_media_with_params(LinphoneCore* lc, LinphoneCall* call, const LinphoneCallParams* params);
/**
* Accept an early media session for an incoming call.
* @brief Accept an early media session for an incoming call.
*
* This is identical as calling linphone_core_accept_early_media_with_params() with NULL call parameters.
* @param[in] lc #LinphoneCore object
* @param[in] call The incoming call to accept
* @return 0 if successful, -1 otherwise
* @ingroup call_control
* @see linphone_core_accept_early_media_with_params()
* @deprecated Use linphone_call_accept_early_media() instead
* @deprecated Use #linphone_call_accept_early_media() instead. Deprecated since 2017-02-13.
**/
LINPHONE_PUBLIC LINPHONE_DEPRECATED LinphoneStatus linphone_core_accept_early_media(LinphoneCore* lc, LinphoneCall* call);
/**
* Terminates a call.
* @brief Terminates a call.
*
* @param[in] lc #LinphoneCore object
* @param[in] call The #LinphoneCall object representing the call to be terminated
* @return 0 on success, -1 on failure
* @ingroup call_control
* @deprecated Use linphone_call_terminate() instead
* @deprecated Use #linphone_call_terminate() instead. Deprecated since 2017-02-13.
**/
LINPHONE_PUBLIC LINPHONE_DEPRECATED LinphoneStatus linphone_core_terminate_call(LinphoneCore *lc, LinphoneCall *call);
@ -1227,18 +1250,18 @@ LINPHONE_PUBLIC LINPHONE_DEPRECATED LinphoneStatus linphone_core_terminate_call(
* @param[in] redirect_uri The URI to redirect the call to
* @return 0 if successful, -1 on error.
* @ingroup call_control
* @deprecated Use linphone_call_redirect() instead
* @deprecated Use #linphone_call_redirect() instead. Deprecated since 2017-02-13.
*/
LINPHONE_PUBLIC LINPHONE_DEPRECATED LinphoneStatus linphone_core_redirect_call(LinphoneCore *lc, LinphoneCall *call, const char *redirect_uri);
/**
* Decline a pending incoming call, with a reason.
* @brief Decline a pending incoming call, with a reason.
* @param[in] lc #LinphoneCore object
* @param[in] call The #LinphoneCall to decline, must be in the IncomingReceived state
* @param[in] reason The reason for rejecting the call: #LinphoneReasonDeclined or #LinphoneReasonBusy
* @return 0 on success, -1 on failure
* @ingroup call_control
* @deprecated Use linphone_call_decline() instead
* @deprecated Use #linphone_call_decline() instead. Deprecated since 2017-02-13.
**/
LINPHONE_PUBLIC LINPHONE_DEPRECATED LinphoneStatus linphone_core_decline_call(LinphoneCore *lc, LinphoneCall * call, LinphoneReason reason);
@ -1251,15 +1274,16 @@ LINPHONE_PUBLIC LINPHONE_DEPRECATED LinphoneStatus linphone_core_decline_call(Li
LINPHONE_PUBLIC LinphoneStatus linphone_core_terminate_all_calls(LinphoneCore *lc);
/**
* Pauses the call. If a music file has been setup using linphone_core_set_play_file(),
* @biref Pauses the call. If a music file has been setup using linphone_core_set_play_file(),
* this file will be played to the remote user.
*
* The only way to resume a paused call is to call linphone_core_resume_call().
* @param[in] lc #LinphoneCore object
* @param[in] call The call to pause
* @return 0 on success, -1 on failure
* @ingroup call_control
* @see linphone_core_resume_call()
* @deprecated Use linphone_call_pause() instead
* @deprecated Use #linphone_call_pause() instead. Deprecated since 2017-02-13.
**/
LINPHONE_PUBLIC LINPHONE_DEPRECATED LinphoneStatus linphone_core_pause_call(LinphoneCore *lc, LinphoneCall *call);
@ -1272,19 +1296,21 @@ LINPHONE_PUBLIC LINPHONE_DEPRECATED LinphoneStatus linphone_core_pause_call(Linp
LINPHONE_PUBLIC LinphoneStatus linphone_core_pause_all_calls(LinphoneCore *lc);
/**
* Resumes a call.
* @brief Resumes a call.
*
* The call needs to have been paused previously with linphone_core_pause_call().
* @param[in] lc #LinphoneCore object
* @param[in] call The call to resume
* @return 0 on success, -1 on failure
* @ingroup call_control
* @see linphone_core_pause_call()
* @deprecated Use linphone_call_resume() instead
* @deprecated Use #linphone_call_resume() instead. Deprecated since 2017-02-13.
**/
LINPHONE_PUBLIC LINPHONE_DEPRECATED LinphoneStatus linphone_core_resume_call(LinphoneCore *lc, LinphoneCall *call);
/**
* Updates a running call according to supplied call parameters or parameters changed in the LinphoneCore.
* @brief Updates a running call according to supplied call parameters or parameters changed in the LinphoneCore.
*
* In this version this is limited to the following use cases:
* - setting up/down the video stream according to the video parameter of the #LinphoneCallParams (see linphone_call_params_enable_video() ).
* - changing the size of the transmitted video after calling linphone_core_set_preferred_video_size()
@ -1297,7 +1323,7 @@ LINPHONE_PUBLIC LINPHONE_DEPRECATED LinphoneStatus linphone_core_resume_call(Lin
* @param[in] params The new call parameters to use (may be NULL)
* @return 0 if successful, -1 otherwise.
* @ingroup call_control
* @deprecated Use linphone_call_update() instead
* @deprecated Use #linphone_call_update() instead. Deprecated since 2017-02-13.
**/
LINPHONE_PUBLIC LINPHONE_DEPRECATED LinphoneStatus linphone_core_update_call(LinphoneCore *lc, LinphoneCall *call, const LinphoneCallParams *params);
@ -1326,7 +1352,7 @@ LINPHONE_PUBLIC LINPHONE_DEPRECATED LinphoneStatus linphone_core_update_call(Lin
LINPHONE_PUBLIC LINPHONE_DEPRECATED LinphoneStatus linphone_core_defer_call_update(LinphoneCore *lc, LinphoneCall *call);
/**
* Accept call modifications initiated by other end.
* @brief Accept call modifications initiated by other end.
*
* This call may be performed in response to a #LinphoneCallUpdatedByRemote state notification.
* When such notification arrives, the application can decide to call linphone_core_defer_update_call() so that it can
@ -1343,7 +1369,7 @@ LINPHONE_PUBLIC LINPHONE_DEPRECATED LinphoneStatus linphone_core_defer_call_upda
* @param[in] params A #LinphoneCallParams object describing the call parameters to accept
* @return 0 if successful, -1 otherwise (actually when this function call is performed outside ot #LinphoneCallUpdatedByRemote state)
* @ingroup call_control
* @deprecated Use linphone_call_accept_update() instead
* @deprecated Use #linphone_call_accept_update() instead. Deprecated since 2017-02-13.
**/
LINPHONE_PUBLIC LINPHONE_DEPRECATED LinphoneStatus linphone_core_accept_call_update(LinphoneCore *lc, LinphoneCall *call, const LinphoneCallParams *params);
@ -1379,13 +1405,13 @@ LINPHONE_PUBLIC LinphoneCall *linphone_core_get_call_by_remote_address2(const Li
/**
* Send the specified dtmf.
* @brief Send the specified dtmf.
*
* @ingroup media_parameters
* @deprecated Use #linphone_call_send_dtmf instead.
* This function only works during calls. The dtmf is automatically played to the user.
* @param lc The #LinphoneCore object
* @param dtmf The dtmf name specified as a char, such as '0', '#' etc...
* @deprecated Use #linphone_call_send_dtmf instead. Deprecated since 2015-11-23.
* @ingroup media_parameters
* @donotwrap
**/
LINPHONE_PUBLIC LINPHONE_DEPRECATED void linphone_core_send_dtmf(LinphoneCore *lc, char dtmf);
@ -4950,13 +4976,14 @@ LINPHONE_DEPRECATED LINPHONE_PUBLIC const char *linphone_core_get_chat_database_
/**
* Create a client-side group chat room. When calling this function the chat room is only created
* at the client-side and is empty. Pou need to call linphone_chat_room_add_participants() to
* at the client-side and is empty. You need to call linphone_chat_room_add_participants() to
* create at the server side and add participants to it.
* @param[in] lc A #LinphoneCore object
* @param[in] subject The subject of the group chat room
* @param[in] fallback Boolean value telling whether we should plan on being able to fallback to a basic chat room if the client-side group chat room creation fails
* @return The newly created client-side group chat room.
*/
LINPHONE_PUBLIC LinphoneChatRoom * linphone_core_create_client_group_chat_room(LinphoneCore *lc, const char *subject);
LINPHONE_PUBLIC LinphoneChatRoom * linphone_core_create_client_group_chat_room(LinphoneCore *lc, const char *subject, bool_t fallback);
/**
* Get a basic chat room whose peer is the supplied address. If it does not exist yet, it will be created.

178
include/linphone/logging.h Normal file
View file

@ -0,0 +1,178 @@
/*
logging.h
Copyright (C) 2017 Belledonne Communications SARL
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 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 _LINPHONE_LOG_H_
#define _LINPHONE_LOG_H_
#include "types.h"
#include "defs.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @addtogroup logging
* @{
*/
/**
* @brief Singleton class giving access to logging features.
*/
typedef struct _LinphoneLoggingService LinphoneLoggingService;
/**
* @brief Listener for #LinphoneLoggingService.
*/
typedef struct _LinphoneLoggingServiceCbs LinphoneLoggingServiceCbs;
/**
* @brief Verbosity levels of log messages.
*/
typedef enum _LinphoneLogLevel {
LinphoneLogLevelDebug = 1, /**< @brief Level for debug messages. */
LinphoneLogLevelTrace = 1<<1, /**< @brief Level for traces. */
LinphoneLogLevelMessage = 1<<2, /**< @brief Level for information messages. */
LinphoneLogLevelWarning = 1<<3, /**< @brief Level for warning messages. */
LinphoneLogLevelError = 1<<4, /**< @brief Level for error messages. */
LinphoneLogLevelFatal = 1<<5 /**< @brief Level for fatal error messages. */
} LinphoneLogLevel;
/**
* @brief Type of callbacks called each time liblinphone write a log message.
*
* @param log_service A pointer on the logging service singleton.
* @param domain A string describing which sub-library of liblinphone the message is coming from.
* @param lev Verbosity level of the message.
* @param message Content of the message.
*/
typedef void (*LinphoneLoggingServiceCbsLogMessageWrittenCb)(LinphoneLoggingService *log_service, const char *domain, LinphoneLogLevel lev, const char *message);
/**
* @brief Gets the singleton logging service object.
*
* The singleton is automatically instantiated if it hasn't
* been done yet.
*
* @return A pointer on the singleton.
*/
LINPHONE_PUBLIC LinphoneLoggingService *linphone_logging_service_get(void);
/**
* @brief Increases the reference counter.
*/
LINPHONE_PUBLIC LinphoneLoggingService *linphone_logging_service_ref(LinphoneLoggingService *service);
/**
* @brief Decreases the reference counter and destroy the object
* if the counter reaches 0.
*/
LINPHONE_PUBLIC void linphone_logging_service_unref(LinphoneLoggingService *service);
/**
* @brief Gets the logging service listener.
*/
LINPHONE_PUBLIC LinphoneLoggingServiceCbs *linphone_logging_service_get_callbacks(const LinphoneLoggingService *log_service);
/**
* @brief Set the verbosity of the log.
*
* For instance, a level of #LinphoneLogLevelMessage will let pass fatal, error, warning and message-typed messages
* whereas trace and debug messages will be dumped out.
*/
LINPHONE_PUBLIC void linphone_logging_service_set_log_level(LinphoneLoggingService *log_service, LinphoneLogLevel level);
/**
* @brief Sets the types of messages that will be authorized to be written in the log.
* @param log_service The logging service singleton.
* @param mask Example: #LinphoneLogLevelMessage|#LinphoneLogLevelError will ONLY let pass message-typed and error messages.
* @note Calling that function reset the log level that has been specified by #linphone_logging_service_set_log_level().
*/
LINPHONE_PUBLIC void linphone_logging_service_set_log_level_mask(LinphoneLoggingService *log_service, unsigned int mask);
/**
* @brief Gets the log level mask.
*/
LINPHONE_PUBLIC unsigned int linphone_logging_service_get_log_level_mask(const LinphoneLoggingService *log_service);
/**
* @brief Enables logging in a file.
*
* That function enables an internal log handler that writes log messages in
* log-rotated files.
*
* @param dir Directory where to create the distinct parts of the log.
* @param filename Name of the log file.
* @param max_size The maximal size of each part of the log. The log rotating is triggered
* each time the currently opened log part reach that limit.
*/
LINPHONE_PUBLIC void linphone_logging_service_set_log_file(const LinphoneLoggingService *service, const char *dir, const char *filename, size_t max_size);
/**
* @brief Increases the reference counter.
*/
LINPHONE_PUBLIC LinphoneLoggingServiceCbs *linphone_logging_service_cbs_ref(LinphoneLoggingServiceCbs *cbs);
/**
* @brief Decreases the reference counter.
*
* The object is automatically destroyed once the counter reach 0.
*/
LINPHONE_PUBLIC void linphone_logging_service_cbs_unref(LinphoneLoggingServiceCbs *cbs);
/**
* @brief Sets the callback to call each time liblinphone writes a log message.
*/
LINPHONE_PUBLIC void linphone_logging_service_cbs_set_log_message_written(LinphoneLoggingServiceCbs *cbs, LinphoneLoggingServiceCbsLogMessageWrittenCb cb);
/**
* @brief Gets the value of the message event callback.
*/
LINPHONE_PUBLIC LinphoneLoggingServiceCbsLogMessageWrittenCb linphone_logging_service_cbs_get_log_message_written(const LinphoneLoggingServiceCbs *cbs);
/**
* @brief Pass a pointer on a custom object.
*
* That pointer can be get back by callbacks by using #linphone_logging_service_get_cbs() and #linphone_logging_service_cbs_get_user_data().
*/
LINPHONE_PUBLIC void linphone_logging_service_cbs_set_user_data(LinphoneLoggingServiceCbs *cbs, void *user_data);
/**
* @brief Gets the user_data pointer back.
*/
LINPHONE_PUBLIC void *linphone_logging_service_cbs_get_user_data(const LinphoneLoggingServiceCbs *cbs);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif // _LINPHONE_LOG_H_

View file

@ -115,11 +115,6 @@ public interface LinphoneChatRoom {
*/
void deleteMessage(LinphoneChatMessage message);
/**
* Create a LinphoneChatMessage
* @return LinphoneChatMessage object
*/
LinphoneChatMessage createLinphoneChatMessage(String message, String url, State state, long timestamp, boolean isRead, boolean isIncoming);
/**
* Returns a back pointer to the core managing the chat room.

View file

@ -25,7 +25,7 @@ import org.linphone.core.LinphoneCall;
@SuppressWarnings("deprecation")
class LinphoneChatRoomImpl implements LinphoneChatRoom {
protected final long nativePtr;
private native long createLinphoneChatMessage(long ptr, String message);
private native Object createLinphoneChatMessage(long ptr, String message);
private native long getPeerAddress(long ptr);
private native void sendMessage(long ptr, String message);
private native void sendMessage2(long ptr, Object msg, long messagePtr, StateListener listener);
@ -39,9 +39,6 @@ class LinphoneChatRoomImpl implements LinphoneChatRoom {
private native boolean isRemoteComposing(long ptr);
private native void markAsRead(long ptr);
private native void deleteMessage(long room, long message);
private native long createLinphoneChatMessage2(long ptr, String message,
String url, int state, long timestamp, boolean isRead,
boolean isIncoming);
private native void sendChatMessage(long ptr, Object message, long messagePtr);
private native void finalize(long nativePtr);
private native boolean islimeAvailable(long nativePtr);
@ -77,7 +74,7 @@ class LinphoneChatRoomImpl implements LinphoneChatRoom {
@Override
public LinphoneChatMessage createLinphoneChatMessage(String message) {
synchronized(getCore()){
return new LinphoneChatMessageImpl(createLinphoneChatMessage(nativePtr, message));
return (LinphoneChatMessage)createLinphoneChatMessage(nativePtr, message);
}
}
@ -144,15 +141,6 @@ class LinphoneChatRoomImpl implements LinphoneChatRoom {
}
}
@Override
public LinphoneChatMessage createLinphoneChatMessage(String message,
String url, State state, long timestamp, boolean isRead,
boolean isIncoming) {
synchronized(getCore()){
return new LinphoneChatMessageImpl(createLinphoneChatMessage2(
nativePtr, message, url, state.value(), timestamp / 1000, isRead, isIncoming));
}
}
private native Object getCore(long nativePtr);
@Override
public synchronized LinphoneCore getCore() {
@ -162,11 +150,11 @@ class LinphoneChatRoomImpl implements LinphoneChatRoom {
return (LinphoneChatMessage[]) typesPtr;
}
private native long createFileTransferMessage(long ptr, String name, String type, String subtype, int size);
private native Object createFileTransferMessage(long ptr, String name, String type, String subtype, int size);
@Override
public LinphoneChatMessage createFileTransferMessage(LinphoneContent content) {
synchronized(getCore()) {
return new LinphoneChatMessageImpl(createFileTransferMessage(nativePtr, content.getName(), content.getType(), content.getSubtype(), content.getRealSize()));
return (LinphoneChatMessage)createFileTransferMessage(nativePtr, content.getName(), content.getType(), content.getSubtype(), content.getRealSize());
}
}
@Override

View file

@ -31,6 +31,7 @@
#include "chat/notification/imdn.h"
#include "content/content-type.h"
#include "content/content.h"
#include "conference/participant.h"
// =============================================================================
@ -246,6 +247,10 @@ bool_t linphone_chat_message_is_file_transfer_in_progress(LinphoneChatMessage *m
return L_GET_CPP_PTR_FROM_C_OBJECT(msg)->isFileTransferInProgress();
}
bctbx_list_t *linphone_chat_message_get_participants_in_state (const LinphoneChatMessage *msg, const LinphoneChatMessageState state) {
return L_GET_RESOLVED_C_LIST_FROM_CPP_LIST(L_GET_PRIVATE_FROM_C_OBJECT(msg)->getParticipantsInState((LinphonePrivate::ChatMessage::State) state));
}
// =============================================================================
// Old listener
// =============================================================================

View file

@ -35,6 +35,7 @@ struct _LinphoneChatRoomCbs {
LinphoneChatRoomCbsParticipantAdminStatusChangedCb participantAdminStatusChangedCb;
LinphoneChatRoomCbsStateChangedCb stateChangedCb;
LinphoneChatRoomCbsSubjectChangedCb subjectChangedCb;
LinphoneChatRoomCbsAllInformationReceivedCb allInformationReceivedCb;
LinphoneChatRoomCbsUndecryptableMessageReceivedCb undecryptableMessageReceivedCb;
LinphoneChatRoomCbsChatMessageReceivedCb chatMessageReceivedCb;
LinphoneChatRoomCbsChatMessageSentCb chatMessageSentCb;
@ -176,6 +177,14 @@ void linphone_chat_room_cbs_set_participant_device_removed (LinphoneChatRoomCbs
cbs->participantDeviceRemovedCb = cb;
}
LinphoneChatRoomCbsAllInformationReceivedCb linphone_chat_room_cbs_get_all_information_received (const LinphoneChatRoomCbs *cbs) {
return cbs->allInformationReceivedCb;
}
void linphone_chat_room_cbs_set_all_information_received (LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsAllInformationReceivedCb cb) {
cbs->allInformationReceivedCb = cb;
}
LinphoneChatRoomCbsConferenceAddressGenerationCb linphone_chat_room_cbs_get_conference_address_generation (const LinphoneChatRoomCbs *cbs) {
return cbs->conferenceAddressGenerationCb;
}

View file

@ -442,6 +442,7 @@ const bctbx_list_t *linphone_chat_room_get_callbacks_list(const LinphoneChatRoom
if (cb) \
cb(__VA_ARGS__); \
} \
linphone_chat_room_set_current_callbacks(cr, nullptr); \
bctbx_list_free(callbacksCopy);
void _linphone_chat_room_notify_is_composing_received(LinphoneChatRoom *cr, const LinphoneAddress *remoteAddr, bool_t isComposing) {
@ -480,6 +481,10 @@ void _linphone_chat_room_notify_subject_changed(LinphoneChatRoom *cr, const Linp
NOTIFY_IF_EXIST(SubjectChanged, subject_changed, cr, event_log)
}
void _linphone_chat_room_notify_all_information_received(LinphoneChatRoom *cr) {
NOTIFY_IF_EXIST(AllInformationReceived, all_information_received, cr)
}
void _linphone_chat_room_notify_undecryptable_message_received(LinphoneChatRoom *cr, LinphoneChatMessage *msg) {
NOTIFY_IF_EXIST(UndecryptableMessageReceived, undecryptable_message_received, cr, msg)
}

View file

@ -100,6 +100,8 @@ BELLE_SIP_TYPE_ID(LinphoneImNotifPolicy),
BELLE_SIP_TYPE_ID(LinphoneInfoMessage),
BELLE_SIP_TYPE_ID(LinphoneLDAPContactProvider),
BELLE_SIP_TYPE_ID(LinphoneLDAPContactSearch),
BELLE_SIP_TYPE_ID(LinphoneLoggingService),
BELLE_SIP_TYPE_ID(LinphoneLoggingServiceCbs),
BELLE_SIP_TYPE_ID(LinphoneNatPolicy),
BELLE_SIP_TYPE_ID(LinphonePayloadType),
BELLE_SIP_TYPE_ID(LinphonePlayer),

View file

@ -59,6 +59,7 @@ public:
void setDirection (ChatMessage::Direction dir);
void setParticipantState (const IdentityAddress &participantAddress, ChatMessage::State newState);
std::list<std::shared_ptr<Participant>> getParticipantsInState (const ChatMessage::State state) const;
void setState (ChatMessage::State newState, bool force = false);
void setTime (time_t time);

View file

@ -34,6 +34,7 @@
#include "chat/modifier/encryption-chat-message-modifier.h"
#include "chat/modifier/file-transfer-chat-message-modifier.h"
#include "chat/modifier/multipart-chat-message-modifier.h"
#include "conference/participant.h"
#include "content/file-content.h"
#include "content/content.h"
#include "core/core.h"
@ -122,6 +123,29 @@ void ChatMessagePrivate::setParticipantState (const IdentityAddress &participant
setState(ChatMessage::State::DeliveredToUser);
}
list<shared_ptr<Participant>> ChatMessagePrivate::getParticipantsInState (const ChatMessage::State state) const {
L_Q();
list<shared_ptr<Participant>> participantsInState;
if (!(q->getChatRoom()->getCapabilities() & AbstractChatRoom::Capabilities::Conference) || !dbKey.isValid()) {
return participantsInState;
}
unique_ptr<MainDb> &mainDb = q->getChatRoom()->getCore()->getPrivate()->mainDb;
shared_ptr<EventLog> eventLog = mainDb->getEventFromKey(dbKey);
list<IdentityAddress> addressesInState = mainDb->getChatMessageParticipantsInState(eventLog, state);
const list<shared_ptr<Participant>> &participants = q->getChatRoom()->getParticipants();
for (IdentityAddress addr : addressesInState) {
for (const auto &participant : participants) {
if (participant->getAddress() == addr) {
participantsInState.push_back(participant);
}
}
}
return participantsInState;
}
void ChatMessagePrivate::setState (ChatMessage::State newState, bool force) {
L_Q();
@ -476,7 +500,7 @@ static void forceUtf8Content (Content &content) {
void ChatMessagePrivate::notifyReceiving () {
L_Q();
LinphoneChatRoom *chatRoom = L_GET_C_BACK_PTR(q->getChatRoom());
LinphoneChatRoom *chatRoom = static_pointer_cast<ChatRoom>(q->getChatRoom())->getPrivate()->getCChatRoom();
if ((getContentType() != ContentType::Imdn) && (getContentType() != ContentType::ImIsComposing)) {
_linphone_chat_room_notify_chat_message_should_be_stored(chatRoom, L_GET_C_BACK_PTR(q->getSharedFromThis()));
if (toBeStored)

View file

@ -39,6 +39,7 @@ class AbstractChatRoom;
class Content;
class FileTransferContent;
class ChatMessagePrivate;
class Participant;
class LINPHONE_PUBLIC ChatMessage : public Object, public CoreAccessor {
friend class BasicToClientGroupChatRoom;

View file

@ -88,7 +88,7 @@ void BasicChatRoom::addParticipants (const list<IdentityAddress> &, const CallSe
lError() << "addParticipants() is not allowed on a BasicChatRoom";
}
void BasicChatRoom::removeParticipant (const shared_ptr<const Participant> &) {
void BasicChatRoom::removeParticipant (const shared_ptr<Participant> &) {
lError() << "removeParticipant() is not allowed on a BasicChatRoom";
}

View file

@ -48,7 +48,7 @@ public:
void addParticipant (const IdentityAddress &addr, const CallSessionParams *params, bool hasMedia) override;
void addParticipants (const std::list<IdentityAddress> &addresses, const CallSessionParams *params, bool hasMedia) override;
void removeParticipant (const std::shared_ptr<const Participant> &participant) override;
void removeParticipant (const std::shared_ptr<Participant> &participant) override;
void removeParticipants (const std::list<std::shared_ptr<Participant>> &participants) override;
std::shared_ptr<Participant> findParticipant (const IdentityAddress &addr) const override;

View file

@ -78,7 +78,7 @@ public:
}
migrationRealTime = currentRealTime;
clientGroupChatRoom = static_pointer_cast<ClientGroupChatRoom>(
chatRoom->getCore()->getPrivate()->createClientGroupChatRoom(chatRoom->getSubject(), "", false)
chatRoom->getCore()->getPrivate()->createClientGroupChatRoom(chatRoom->getSubject(), "", Content(), false)
);
clientGroupChatRoom->getPrivate()->setCallSessionListener(this);
clientGroupChatRoom->getPrivate()->setChatRoomListener(this);

View file

@ -30,6 +30,7 @@ class ChatRoomPrivate;
class LINPHONE_PUBLIC ChatRoom : public AbstractChatRoom {
public:
friend class ChatMessagePrivate;
friend class ProxyChatRoomPrivate;
L_OVERRIDE_SHARED_FROM_THIS(ChatRoom);

View file

@ -35,6 +35,7 @@ public:
void notifyReceived (const std::string &body);
void multipartNotifyReceived (const std::string &body);
void confirmJoining (SalCallOp *op);
void setCallSessionListener (CallSessionListener *listener);
void setChatRoomListener (ChatRoomListener *listener) { chatRoomListener = listener; }
@ -47,12 +48,16 @@ public:
void onCallSessionSetReleased (const std::shared_ptr<CallSession> &session) override;
void onCallSessionStateChanged (const std::shared_ptr<CallSession> &session, CallSession::State state, const std::string &message) override;
void onChatRoomCreated (const Address &remoteContact);
private:
void acceptSession (const std::shared_ptr<CallSession> &session);
CallSessionListener *callSessionListener = this;
ChatRoomListener *chatRoomListener = this;
ClientGroupChatRoom::CapabilitiesMask capabilities = ClientGroupChatRoom::Capabilities::Conference;
bool deletionOnTerminationEnabled = false;
BackgroundTask bgTask;
BackgroundTask bgTask { "Subscribe/notify of full state conference" };
L_DECLARE_PUBLIC(ClientGroupChatRoom);
};

View file

@ -101,6 +101,31 @@ void ClientGroupChatRoomPrivate::setCallSessionListener (CallSessionListener *li
}
}
void ClientGroupChatRoomPrivate::confirmJoining (SalCallOp *op) {
L_Q();
L_Q_T(RemoteConference, qConference);
auto focus = qConference->getPrivate()->focus;
bool previousSession = (focus->getPrivate()->getSession() != nullptr);
auto session = focus->getPrivate()->createSession(*q, nullptr, false, this);
session->configure(LinphoneCallIncoming, nullptr, op, Address(op->get_from()), Address(op->get_to()));
session->startIncomingNotification(false);
if (!previousSession) {
setState(ClientGroupChatRoom::State::CreationPending);
// Handle participants addition
list<IdentityAddress> identAddresses = ClientGroupChatRoom::parseResourceLists(op->get_remote_body());
for (const auto &addr : identAddresses) {
auto participant = q->findParticipant(addr);
if (!participant) {
participant = make_shared<Participant>(addr);
qConference->getPrivate()->participants.push_back(participant);
}
}
}
acceptSession(session);
}
// -----------------------------------------------------------------------------
void ClientGroupChatRoomPrivate::onChatRoomInsertRequested (const shared_ptr<AbstractChatRoom> &chatRoom) {
@ -139,14 +164,11 @@ void ClientGroupChatRoomPrivate::onCallSessionStateChanged (
if (newState == CallSession::State::Connected) {
if (q->getState() == ChatRoom::State::CreationPending) {
IdentityAddress addr(session->getRemoteContactAddress()->asStringUriOnly());
q->onConferenceCreated(addr);
if (session->getRemoteContactAddress()->hasParam("isfocus")) {
bgTask.start(q->getCore(), 32); // It will be stopped when receiving the first notify
qConference->getPrivate()->eventHandler->subscribe(q->getChatRoomId());
}
onChatRoomCreated(*session->getRemoteContactAddress());
} else if (q->getState() == ChatRoom::State::TerminationPending)
qConference->getPrivate()->focus->getPrivate()->getSession()->terminate();
} else if (newState == CallSession::State::End) {
q->onConferenceTerminated(q->getConferenceAddress());
} else if (newState == CallSession::State::Released) {
if (q->getState() == ChatRoom::State::TerminationPending) {
if (session->getReason() == LinphoneReasonNone) {
@ -174,23 +196,46 @@ void ClientGroupChatRoomPrivate::onCallSessionStateChanged (
}
}
void ClientGroupChatRoomPrivate::onChatRoomCreated (const Address &remoteContact) {
L_Q();
L_Q_T(RemoteConference, qConference);
IdentityAddress addr(remoteContact);
q->onConferenceCreated(addr);
if (remoteContact.hasParam("isfocus")) {
bgTask.start(q->getCore(), 32); // It will be stopped when receiving the first notify
qConference->getPrivate()->eventHandler->subscribe(q->getChatRoomId());
}
}
// -----------------------------------------------------------------------------
void ClientGroupChatRoomPrivate::acceptSession (const shared_ptr<CallSession> &session) {
if (session->getState() == CallSession::State::UpdatedByRemote)
session->acceptUpdate();
else
session->accept();
}
// =============================================================================
ClientGroupChatRoom::ClientGroupChatRoom (
const shared_ptr<Core> &core,
const string &uri,
const IdentityAddress &me,
const string &subject
const string &subject,
const Content &content
) : ChatRoom(*new ClientGroupChatRoomPrivate, core, ChatRoomId(IdentityAddress(), me)),
RemoteConference(core, me, nullptr) {
L_D_T(RemoteConference, dConference);
L_D();
IdentityAddress focusAddr(uri);
dConference->focus = make_shared<Participant>(focusAddr);
dConference->focus->getPrivate()->addDevice(focusAddr);
RemoteConference::setSubject(subject);
d->bgTask.setName("Subscribe/notify of full state conference");
list<IdentityAddress> identAddresses = Conference::parseResourceLists(content);
for (const auto &addr : identAddresses)
dConference->participants.push_back(make_shared<Participant>(addr));
}
ClientGroupChatRoom::ClientGroupChatRoom (
@ -251,7 +296,7 @@ ClientGroupChatRoom::CapabilitiesMask ClientGroupChatRoom::getCapabilities () co
}
bool ClientGroupChatRoom::hasBeenLeft () const {
return getState() != State::Created;
return (getState() != State::Created);
}
bool ClientGroupChatRoom::canHandleParticipants () const {
@ -328,7 +373,7 @@ void ClientGroupChatRoom::addParticipants (
}
}
void ClientGroupChatRoom::removeParticipant (const shared_ptr<const Participant> &participant) {
void ClientGroupChatRoom::removeParticipant (const shared_ptr<Participant> &participant) {
LinphoneCore *cCore = getCore()->getCCore();
SalReferOp *referOp = new SalReferOp(cCore->sal);
@ -422,7 +467,8 @@ void ClientGroupChatRoom::join () {
if (session) {
if (getState() != ChatRoom::State::TerminationPending)
session->startInvite(nullptr, "", nullptr);
d->setState(ChatRoom::State::CreationPending);
if (getState() != ChatRoom::State::Created)
d->setState(ChatRoom::State::CreationPending);
}
}
@ -454,6 +500,7 @@ void ClientGroupChatRoom::onConferenceCreated (const IdentityAddress &addr) {
dConference->focus->getPrivate()->addDevice(addr);
d->chatRoomId = ChatRoomId(addr, d->chatRoomId.getLocalAddress());
d->chatRoomListener->onChatRoomInsertRequested(getSharedFromThis());
d->setState(ChatRoom::State::Created);
}
void ClientGroupChatRoom::onConferenceKeywordsChanged (const vector<string> &keywords) {
@ -464,6 +511,7 @@ void ClientGroupChatRoom::onConferenceKeywordsChanged (const vector<string> &key
void ClientGroupChatRoom::onConferenceTerminated (const IdentityAddress &addr) {
L_D();
L_D_T(RemoteConference, dConference);
dConference->eventHandler->unsubscribe();
dConference->eventHandler->resetLastNotify();
d->setState(ChatRoom::State::Terminated);
d->addEvent(make_shared<ConferenceEvent>(
@ -479,21 +527,26 @@ void ClientGroupChatRoom::onConferenceTerminated (const IdentityAddress &addr) {
void ClientGroupChatRoom::onFirstNotifyReceived (const IdentityAddress &addr) {
L_D();
d->setState(ChatRoom::State::Created);
bool performMigration = false;
shared_ptr<AbstractChatRoom> chatRoom;
if (getParticipantCount() == 1) {
ChatRoomId id(getParticipants().front()->getAddress(), getMe()->getAddress());
shared_ptr<AbstractChatRoom> chatRoom = getCore()->findChatRoom(id);
if (chatRoom && (chatRoom->getCapabilities() & ChatRoom::Capabilities::Basic)) {
BasicToClientGroupChatRoom::migrate(getSharedFromThis(), chatRoom);
d->bgTask.stop();
return;
}
chatRoom = getCore()->findChatRoom(id);
if (chatRoom && (chatRoom->getCapabilities() & ChatRoom::Capabilities::Basic))
performMigration = true;
}
d->chatRoomListener->onChatRoomInsertInDatabaseRequested(getSharedFromThis());
if (performMigration)
BasicToClientGroupChatRoom::migrate(getSharedFromThis(), chatRoom);
else
d->chatRoomListener->onChatRoomInsertInDatabaseRequested(getSharedFromThis());
LinphoneChatRoom *cr = d->getCChatRoom();
_linphone_chat_room_notify_all_information_received(cr);
d->bgTask.stop();
// TODO: Bug. Event is inserted many times.
// Avoid this in the future. Deal with signals/slots system.
#if 0

View file

@ -43,7 +43,8 @@ public:
const std::shared_ptr<Core> &core,
const std::string &factoryUri,
const IdentityAddress &me,
const std::string &subject
const std::string &subject,
const Content &content
);
ClientGroupChatRoom (
@ -77,7 +78,7 @@ public:
void addParticipant (const IdentityAddress &addr, const CallSessionParams *params, bool hasMedia) override;
void addParticipants (const std::list<IdentityAddress> &addresses, const CallSessionParams *params, bool hasMedia) override;
void removeParticipant (const std::shared_ptr<const Participant> &participant) override;
void removeParticipant (const std::shared_ptr<Participant> &participant) override;
void removeParticipants (const std::list<std::shared_ptr<Participant>> &participants) override;
std::shared_ptr<Participant> findParticipant (const IdentityAddress &addr) const override;

View file

@ -79,10 +79,15 @@ public:
cgcr->getPrivate()->setCallSessionListener(nullptr);
cgcr->getPrivate()->setChatRoomListener(nullptr);
Core::deleteChatRoom(q->getSharedFromThis());
setupProxy();
LinphoneChatRoom *lcr = L_GET_C_BACK_PTR(q);
shared_ptr<AbstractChatRoom> bcr = cgcr->getCore()->getOrCreateBasicChatRoom(invitedAddresses.front());
L_SET_CPP_PTR_FROM_C_OBJECT(lcr, bcr);
/* getOrCreateBasicChatRoom will automatically set the state to Instantiated and Created
* but because CPP ptr hasn't been set yet in this case the application's ChatRoom won't be notified
* that's why we set both states again here... */
bcr->getPrivate()->setState(ChatRoom::State::Instantiated);
bcr->getPrivate()->setState(ChatRoom::State::Created);
return;
}
cgcr->getPrivate()->onCallSessionStateChanged(session, newState, message);

View file

@ -248,7 +248,7 @@ void ProxyChatRoom::addParticipants (
return d->chatRoom->addParticipants(addresses, params, hasMedia);
}
void ProxyChatRoom::removeParticipant (const shared_ptr<const Participant> &participant) {
void ProxyChatRoom::removeParticipant (const shared_ptr<Participant> &participant) {
L_D();
d->chatRoom->removeParticipant(participant);
}

View file

@ -97,7 +97,7 @@ public:
bool hasMedia
) override;
void removeParticipant (const std::shared_ptr<const Participant> &participant) override;
void removeParticipant (const std::shared_ptr<Participant> &participant) override;
void removeParticipants (const std::list<std::shared_ptr<Participant>> &participants) override;
std::shared_ptr<Participant> findParticipant (const IdentityAddress &participantAddress) const override;

View file

@ -91,6 +91,7 @@ private:
static void copyMessageHeaders (const std::shared_ptr<Message> &fromMessage, const std::shared_ptr<ChatMessage> &toMessage);
void byeDevice (const std::shared_ptr<ParticipantDevice> &device);
void designateAdmin ();
void dispatchMessage (const std::shared_ptr<Message> &message, const std::string &uri);
void finalizeCreation ();
@ -100,7 +101,7 @@ private:
void queueMessage (const std::shared_ptr<Message> &msg, const IdentityAddress &deviceAddress);
void removeNonPresentParticipants (const std::list <IdentityAddress> &compatibleParticipants);
void onParticipantDeviceLeft (const std::shared_ptr<const CallSession> &session);
void onParticipantDeviceLeft (const std::shared_ptr<ParticipantDevice> &device);
// ChatRoomListener
void onChatRoomInsertRequested (const std::shared_ptr<AbstractChatRoom> &chatRoom) override;

View file

@ -84,6 +84,8 @@ void ServerGroupChatRoomPrivate::addParticipantDevice (const IdentityAddress &pa
void ServerGroupChatRoomPrivate::addCompatibleParticipants (const IdentityAddress &deviceAddr, const list<IdentityAddress> &participantCompatible) {}
void ServerGroupChatRoomPrivate::checkCompatibleParticipants (const IdentityAddress &deviceAddr, const list<IdentityAddress> &addressesToCheck) {}
// -----------------------------------------------------------------------------
LinphoneReason ServerGroupChatRoomPrivate::onSipMessageReceived (SalOp *, const SalMessage *) {
@ -92,6 +94,8 @@ LinphoneReason ServerGroupChatRoomPrivate::onSipMessageReceived (SalOp *, const
// -----------------------------------------------------------------------------
void ServerGroupChatRoomPrivate::byeDevice (const shared_ptr<ParticipantDevice> &device) {}
void ServerGroupChatRoomPrivate::designateAdmin () {}
void ServerGroupChatRoomPrivate::dispatchMessage (const shared_ptr<Message> &message, const string &uri) {}
@ -112,7 +116,7 @@ void ServerGroupChatRoomPrivate::removeNonPresentParticipants (const list <Ident
// -----------------------------------------------------------------------------
void ServerGroupChatRoomPrivate::onParticipantDeviceLeft (const shared_ptr<const CallSession> &session) {}
void ServerGroupChatRoomPrivate::onParticipantDeviceLeft (const shared_ptr<ParticipantDevice> &device) {}
// -----------------------------------------------------------------------------
@ -187,7 +191,7 @@ void ServerGroupChatRoom::addParticipant (const IdentityAddress &, const CallSes
void ServerGroupChatRoom::addParticipants (const list<IdentityAddress> &, const CallSessionParams *, bool) {}
void ServerGroupChatRoom::removeParticipant (const shared_ptr<const Participant> &) {}
void ServerGroupChatRoom::removeParticipant (const shared_ptr<Participant> &participant) {}
void ServerGroupChatRoom::removeParticipants (const list<shared_ptr<Participant>> &) {}

View file

@ -68,7 +68,7 @@ public:
bool hasMedia
) override;
void removeParticipant (const std::shared_ptr<const Participant> &participant) override;
void removeParticipant (const std::shared_ptr<Participant> &participant) override;
void removeParticipants (const std::list<std::shared_ptr<Participant>> &participants) override;
std::shared_ptr<Participant> findParticipant (const IdentityAddress &participantAddress) const override;

View file

@ -55,7 +55,7 @@ public:
virtual const std::string &getSubject () const = 0;
virtual void join () = 0;
virtual void leave () = 0;
virtual void removeParticipant (const std::shared_ptr<const Participant> &participant) = 0;
virtual void removeParticipant (const std::shared_ptr<Participant> &participant) = 0;
virtual void removeParticipants (const std::list<std::shared_ptr<Participant>> &participants) = 0;
virtual void setParticipantAdminStatus (const std::shared_ptr<Participant> &participant, bool isAdmin) = 0;
virtual void setSubject (const std::string &subject) = 0;

View file

@ -19,8 +19,12 @@
#include "conference-p.h"
#include "conference/session/call-session-p.h"
#include "content/content.h"
#include "content/content-disposition.h"
#include "content/content-type.h"
#include "logger/logger.h"
#include "participant-p.h"
#include "xml/resource-lists.h"
// =============================================================================
@ -97,7 +101,7 @@ void Conference::join () {}
void Conference::leave () {}
void Conference::removeParticipant (const shared_ptr<const Participant> &participant) {
void Conference::removeParticipant (const shared_ptr<Participant> &participant) {
lError() << "Conference class does not handle removeParticipant() generically";
}
@ -154,6 +158,8 @@ shared_ptr<ParticipantDevice> Conference::findParticipantDevice (const shared_pt
return nullptr;
}
// -----------------------------------------------------------------------------
bool Conference::isMe (const IdentityAddress &addr) const {
L_D();
IdentityAddress cleanedAddr(addr);
@ -163,4 +169,46 @@ bool Conference::isMe (const IdentityAddress &addr) const {
return cleanedMeAddr == cleanedAddr;
}
// -----------------------------------------------------------------------------
string Conference::getResourceLists (const list<IdentityAddress> &addresses) const {
Xsd::ResourceLists::ResourceLists rl = Xsd::ResourceLists::ResourceLists();
Xsd::ResourceLists::ListType l = Xsd::ResourceLists::ListType();
for (const auto &addr : addresses) {
Xsd::ResourceLists::EntryType entry = Xsd::ResourceLists::EntryType(addr.asString());
l.getEntry().push_back(entry);
}
rl.getList().push_back(l);
Xsd::XmlSchema::NamespaceInfomap map;
stringstream xmlBody;
serializeResourceLists(xmlBody, rl, map);
return xmlBody.str();
}
// -----------------------------------------------------------------------------
list<IdentityAddress> Conference::parseResourceLists (const Content &content) {
if ((content.getContentType() == ContentType::ResourceLists)
&& ((content.getContentDisposition().weakEqual(ContentDisposition::RecipientList))
|| (content.getContentDisposition().weakEqual(ContentDisposition::RecipientListHistory))
)
) {
istringstream data(content.getBodyAsString());
unique_ptr<Xsd::ResourceLists::ResourceLists> rl(Xsd::ResourceLists::parseResourceLists(
data,
Xsd::XmlSchema::Flags::dont_validate
));
list<IdentityAddress> addresses;
for (const auto &l : rl->getList()) {
for (const auto &entry : l.getEntry()) {
IdentityAddress addr(entry.getUri());
addresses.push_back(move(addr));
}
}
return addresses;
}
return list<IdentityAddress>();
}
LINPHONE_END_NAMESPACE

View file

@ -34,6 +34,7 @@ class CallSession;
class CallSessionListener;
class CallSessionPrivate;
class ConferencePrivate;
class Content;
class ParticipantDevice;
class LINPHONE_PUBLIC Conference :
@ -62,11 +63,14 @@ public:
const std::string &getSubject () const override;
void join () override;
void leave () override;
void removeParticipant (const std::shared_ptr<const Participant> &participant) override;
void removeParticipant (const std::shared_ptr<Participant> &participant) override;
void removeParticipants (const std::list<std::shared_ptr<Participant>> &participants) override;
void setParticipantAdminStatus (const std::shared_ptr<Participant> &participant, bool isAdmin) override;
void setSubject (const std::string &subject) override;
std::string getResourceLists (const std::list<IdentityAddress> &addresses) const;
static std::list<IdentityAddress> parseResourceLists (const Content &content);
protected:
explicit Conference (
ConferencePrivate &p,

View file

@ -17,14 +17,10 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#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"
#include "logger/logger.h"
#include "participant-p.h"
#include "xml/resource-lists.h"
// =============================================================================
@ -59,7 +55,7 @@ void LocalConference::addParticipant (const IdentityAddress &addr, const CallSes
d->activeParticipant = participant;
}
void LocalConference::removeParticipant (const shared_ptr<const Participant> &participant) {
void LocalConference::removeParticipant (const shared_ptr<Participant> &participant) {
L_D();
for (const auto &p : d->participants) {
if (participant->getAddress() == p->getAddress()) {
@ -69,25 +65,4 @@ void LocalConference::removeParticipant (const shared_ptr<const Participant> &pa
}
}
list<IdentityAddress> LocalConference::parseResourceLists (const Content &content) {
if ((content.getContentType() == ContentType::ResourceLists)
&& (content.getContentDisposition() == ContentDisposition::RecipientList)
) {
istringstream data(content.getBodyAsString());
unique_ptr<Xsd::ResourceLists::ResourceLists> rl(Xsd::ResourceLists::parseResourceLists(
data,
Xsd::XmlSchema::Flags::dont_validate
));
list<IdentityAddress> addresses;
for (const auto &l : rl->getList()) {
for (const auto &entry : l.getEntry()) {
IdentityAddress addr(entry.getUri());
addresses.push_back(move(addr));
}
}
return addresses;
}
return list<IdentityAddress>();
}
LINPHONE_END_NAMESPACE

View file

@ -26,7 +26,6 @@
LINPHONE_BEGIN_NAMESPACE
class Content;
class LocalConferencePrivate;
class LocalConference : public Conference {
@ -38,9 +37,7 @@ public:
/* ConferenceInterface */
void addParticipant (const IdentityAddress &addr, const CallSessionParams *params, bool hasMedia) override;
void removeParticipant (const std::shared_ptr<const Participant> &participant) override;
static std::list<IdentityAddress> parseResourceLists (const Content &content);
void removeParticipant (const std::shared_ptr<Participant> &participant) override;
private:
L_DECLARE_PRIVATE(LocalConference);

View file

@ -29,7 +29,7 @@ LINPHONE_BEGIN_NAMESPACE
ParticipantDevice::ParticipantDevice () {}
ParticipantDevice::ParticipantDevice (const Participant *participant, const IdentityAddress &gruu)
ParticipantDevice::ParticipantDevice (Participant *participant, const IdentityAddress &gruu)
: mParticipant(participant), mGruu(gruu) {}
ParticipantDevice::~ParticipantDevice () {

View file

@ -44,13 +44,13 @@ public:
};
ParticipantDevice ();
explicit ParticipantDevice (const Participant *participant, const IdentityAddress &gruu);
explicit ParticipantDevice (Participant *participant, const IdentityAddress &gruu);
virtual ~ParticipantDevice ();
bool operator== (const ParticipantDevice &device) const;
inline const IdentityAddress &getAddress () const { return mGruu; }
const Participant *getParticipant () const { return mParticipant; }
Participant *getParticipant () const { return mParticipant; }
inline std::shared_ptr<CallSession> getSession () const { return mSession; }
inline void setSession (std::shared_ptr<CallSession> session) { mSession = session; }
inline State getState () const { return mState; }
@ -63,7 +63,7 @@ public:
bool isValid () const { return mGruu.isValid(); }
private:
const Participant *mParticipant = nullptr;
Participant *mParticipant = nullptr;
IdentityAddress mGruu;
std::shared_ptr<CallSession> mSession;
LinphoneEvent *mConferenceSubscribeEvent = nullptr;

View file

@ -21,7 +21,6 @@
#include "logger/logger.h"
#include "participant-p.h"
#include "remote-conference-p.h"
#include "xml/resource-lists.h"
// =============================================================================
@ -59,7 +58,7 @@ void RemoteConference::addParticipant (const IdentityAddress &addr, const CallSe
d->activeParticipant = participant;
}
void RemoteConference::removeParticipant (const shared_ptr<const Participant> &participant) {
void RemoteConference::removeParticipant (const shared_ptr<Participant> &participant) {
L_D();
for (const auto &p : d->participants) {
if (participant->getAddress() == p->getAddress()) {
@ -69,21 +68,6 @@ void RemoteConference::removeParticipant (const shared_ptr<const Participant> &p
}
}
string RemoteConference::getResourceLists (const list<IdentityAddress> &addresses) const {
Xsd::ResourceLists::ResourceLists rl = Xsd::ResourceLists::ResourceLists();
Xsd::ResourceLists::ListType l = Xsd::ResourceLists::ListType();
for (const auto &addr : addresses) {
Xsd::ResourceLists::EntryType entry = Xsd::ResourceLists::EntryType(addr.asString());
l.getEntry().push_back(entry);
}
rl.getList().push_back(l);
Xsd::XmlSchema::NamespaceInfomap map;
stringstream xmlBody;
serializeResourceLists(xmlBody, rl, map);
return xmlBody.str();
}
// -----------------------------------------------------------------------------
void RemoteConference::onConferenceCreated (const IdentityAddress &) {}

View file

@ -38,9 +38,7 @@ public:
/* ConferenceInterface */
void addParticipant (const IdentityAddress &addr, const CallSessionParams *params, bool hasMedia) override;
void removeParticipant (const std::shared_ptr<const Participant> &participant) override;
std::string getResourceLists (const std::list<IdentityAddress> &addresses) const;
void removeParticipant (const std::shared_ptr<Participant> &participant) override;
protected:
/* ConferenceListener */

View file

@ -92,7 +92,8 @@ void CallSessionPrivate::setState (CallSession::State newState, const string &me
case CallSession::State::Error:
switch (linphone_error_info_get_reason(q->getErrorInfo())) {
case LinphoneReasonDeclined:
log->status = LinphoneCallDeclined;
if (log->status != LinphoneCallMissed) // Do not re-change the status of a call if it's already set
log->status = LinphoneCallDeclined;
break;
case LinphoneReasonNotAnswered:
if (log->dir == LinphoneCallIncoming)
@ -470,7 +471,7 @@ void CallSessionPrivate::updatedByRemote () {
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);

View file

@ -1920,8 +1920,7 @@ int MediaSessionPrivate::getVideoBandwidth (const SalMediaDescription *md, const
else if (md->bandwidth > 0) {
/* Case where b=AS is given globally, not per stream */
remoteBandwidth = PayloadTypeHandler::getRemainingBandwidthForVideo(md->bandwidth, audioBandwidth);
} else
remoteBandwidth = lp_config_get_int(linphone_core_get_config(q->getCore()->getCCore()), "net", "default_max_bandwidth", 1500);
}
return PayloadTypeHandler::getMinBandwidth(PayloadTypeHandler::getRemainingBandwidthForVideo(linphone_core_get_upload_bandwidth(q->getCore()->getCCore()), audioBandwidth), remoteBandwidth);
}
@ -1998,7 +1997,7 @@ void MediaSessionPrivate::applyJitterBufferParams (RtpSession *session, Linphone
JBParameters params;
rtp_session_get_jitter_buffer_params(session, &params);
params.min_size = lp_config_get_int(config, "rtp", "jitter_buffer_min_size", 40);
params.max_size = lp_config_get_int(config, "rtp", "jitter_buffer_max_size", 250);
params.max_size = lp_config_get_int(config, "rtp", "jitter_buffer_max_size", 500);
params.max_packets = params.max_size * 200 / 1000; /* Allow 200 packet per seconds, quite large */
const char *algo = lp_config_get_string(config, "rtp", "jitter_buffer_algorithm", "rls");
params.buffer_algorithm = jitterBufferNameToAlgo(algo ? algo : "");

View file

@ -63,10 +63,13 @@ ContentDisposition &ContentDisposition::operator= (const ContentDisposition &oth
return *this;
}
bool ContentDisposition::operator== (const ContentDisposition &other) const {
bool ContentDisposition::weakEqual (const ContentDisposition &other) const {
L_D();
return d->disposition == other.getPrivate()->disposition
&& getParameter() == other.getParameter();
return d->disposition == other.getPrivate()->disposition;
}
bool ContentDisposition::operator== (const ContentDisposition &other) const {
return weakEqual(other) && (getParameter() == other.getParameter());
}
bool ContentDisposition::operator!= (const ContentDisposition &other) const {

View file

@ -35,6 +35,7 @@ public:
ContentDisposition &operator= (const ContentDisposition &other);
bool weakEqual (const ContentDisposition &other) const;
bool operator== (const ContentDisposition &other) const;
bool operator!= (const ContentDisposition &other) const;

View file

@ -103,10 +103,12 @@ ContentType &ContentType::operator= (const ContentType &other) {
return *this;
}
bool ContentType::weakEqual (const ContentType &other) const {
return (getType() == other.getType()) && (getSubType() == other.getSubType());
}
bool ContentType::operator== (const ContentType &other) const {
return getType() == other.getType() &&
getSubType() == other.getSubType() &&
getParameter() == other.getParameter();
return weakEqual(other) && (getParameter() == other.getParameter());
}
bool ContentType::operator!= (const ContentType &other) const {

View file

@ -37,6 +37,7 @@ public:
ContentType &operator= (const ContentType &other);
bool weakEqual (const ContentType &other) const;
bool operator== (const ContentType &other) const;
bool operator!= (const ContentType &other) const;

View file

@ -100,7 +100,7 @@ shared_ptr<AbstractChatRoom> CorePrivate::createBasicChatRoom (
return chatRoom;
}
shared_ptr<AbstractChatRoom> CorePrivate::createClientGroupChatRoom (const string &subject, const string &uri, bool fallback) {
shared_ptr<AbstractChatRoom> CorePrivate::createClientGroupChatRoom (const string &subject, const string &uri, const Content &content, bool fallback) {
L_Q();
string usedUri;
@ -135,7 +135,7 @@ shared_ptr<AbstractChatRoom> CorePrivate::createClientGroupChatRoom (const strin
shared_ptr<AbstractChatRoom> chatRoom;
{
shared_ptr<ClientGroupChatRoom> clientGroupChatRoom = make_shared<ClientGroupChatRoom>(
q->getSharedFromThis(), usedUri, IdentityAddress(from), subject
q->getSharedFromThis(), usedUri, IdentityAddress(from), subject, content
);
ClientGroupChatRoomPrivate *dClientGroupChatRoom = clientGroupChatRoom->getPrivate();
@ -265,9 +265,9 @@ shared_ptr<AbstractChatRoom> Core::findOneToOneChatRoom (
return nullptr;
}
shared_ptr<AbstractChatRoom> Core::createClientGroupChatRoom (const string &subject) {
shared_ptr<AbstractChatRoom> Core::createClientGroupChatRoom (const string &subject, bool fallback) {
L_D();
return d->createClientGroupChatRoom(subject);
return d->createClientGroupChatRoom(subject, "", Content(), fallback);
}
shared_ptr<AbstractChatRoom> Core::getOrCreateBasicChatRoom (const ChatRoomId &chatRoomId, bool isRtt) {

View file

@ -61,7 +61,7 @@ public:
void insertChatRoom (const std::shared_ptr<AbstractChatRoom> &chatRoom);
void insertChatRoomWithDb (const std::shared_ptr<AbstractChatRoom> &chatRoom);
std::shared_ptr<AbstractChatRoom> createBasicChatRoom (const ChatRoomId &chatRoomId, AbstractChatRoom::CapabilitiesMask capabilities);
std::shared_ptr<AbstractChatRoom> createClientGroupChatRoom (const std::string &subject, const std::string &uri = "", bool fallback = true);
std::shared_ptr<AbstractChatRoom> createClientGroupChatRoom (const std::string &subject, const std::string &uri = "", const Content &content = Content(), bool fallback = true);
void replaceChatRoom (const std::shared_ptr<AbstractChatRoom> &replacedChatRoom, const std::shared_ptr<AbstractChatRoom> &newChatRoom);
std::unique_ptr<MainDb> mainDb;

View file

@ -101,7 +101,7 @@ public:
const IdentityAddress &participantAddress
) const;
std::shared_ptr<AbstractChatRoom> createClientGroupChatRoom (const std::string &subject);
std::shared_ptr<AbstractChatRoom> createClientGroupChatRoom (const std::string &subject, bool fallback = true);
std::shared_ptr<AbstractChatRoom> createClientGroupChatRoom (
const std::string &subject,
const IdentityAddress &localAddress

View file

@ -1970,6 +1970,30 @@ list<ChatMessage::State> MainDb::getChatMessageParticipantStates (const shared_p
};
}
list<IdentityAddress> MainDb::getChatMessageParticipantsInState (const shared_ptr<EventLog> &eventLog, const ChatMessage::State state) const {
return L_DB_TRANSACTION {
L_D();
const EventLogPrivate *dEventLog = eventLog->getPrivate();
MainDbKeyPrivate *dEventKey = static_cast<MainDbKey &>(dEventLog->dbKey).getPrivate();
const long long &eventId = dEventKey->storageId;
int stateInt = static_cast<int>(state);
list<IdentityAddress> participantsAddresses;
static const string query = "SELECT sip_address.value"
" FROM sip_address, chat_message_participant"
" WHERE event_id = :eventId AND state = :state"
" AND sip_address.id = chat_message_participant.participant_sip_address_id";
soci::rowset<soci::row> rows = (d->dbSession.getBackendSession()->prepare << query, soci::use(eventId), soci::use(stateInt));
for (const auto &row : rows) {
participantsAddresses.push_back(IdentityAddress(row.get<string>(0)));
}
return participantsAddresses;
};
}
ChatMessage::State MainDb::getChatMessageParticipantState (
const shared_ptr<EventLog> &eventLog,
const IdentityAddress &participantAddress

View file

@ -91,6 +91,7 @@ public:
std::list<std::shared_ptr<ChatMessage>> getUnreadChatMessages (const ChatRoomId &chatRoomId) const;
std::list<ChatMessage::State> getChatMessageParticipantStates (const std::shared_ptr<EventLog> &eventLog) const;
std::list<IdentityAddress> getChatMessageParticipantsInState (const std::shared_ptr<EventLog> &eventLog, const ChatMessage::State state) const;
ChatMessage::State getChatMessageParticipantState (
const std::shared_ptr<EventLog> &eventLog,
const IdentityAddress &participantAddress

View file

@ -317,10 +317,12 @@ void IceAgent::updateLocalMediaDescriptionFromIce (SalMediaDescription *desc) {
}
if (firstCl)
result = !!ice_check_list_selected_valid_local_candidate(firstCl, &rtpCandidate, nullptr);
if (result)
if (result) {
strncpy(desc->addr, rtpCandidate->taddr.ip, sizeof(desc->addr));
else
} else {
lWarning() << "If ICE has completed successfully, rtp_candidate should be set!";
ice_dump_valid_list(firstCl);
}
}
strncpy(desc->ice_pwd, ice_session_local_pwd(iceSession), sizeof(desc->ice_pwd));

View file

@ -237,7 +237,7 @@ void SalCallOp::cancelling_invite(const SalErrorInfo *info) {
Content SalCallOp::extract_body(belle_sip_message_t *message) {
Content body;
belle_sip_header_content_type_t *content_type = belle_sip_message_get_header_by_type(message, belle_sip_header_content_type_t);
belle_sip_header_content_disposition_t *contentDisposition = belle_sip_message_get_header_by_type(message, belle_sip_header_content_disposition_t);
belle_sip_header_content_disposition_t *contentDispositionHeader = belle_sip_message_get_header_by_type(message, belle_sip_header_content_disposition_t);
belle_sip_header_content_length_t *content_length = belle_sip_message_get_header_by_type(message, belle_sip_header_content_length_t);
const char *type_str = content_type ? belle_sip_header_content_type_get_type(content_type) : NULL;
const char *subtype_str = content_type ? belle_sip_header_content_type_get_subtype(content_type) : NULL;
@ -245,10 +245,13 @@ Content SalCallOp::extract_body(belle_sip_message_t *message) {
const char *body_str = belle_sip_message_get_body(message);
if (type_str && subtype_str) body.setContentType(ContentType(type_str, subtype_str));
if (contentDisposition)
body.setContentDisposition(
ContentDisposition(belle_sip_header_content_disposition_get_content_disposition(contentDisposition))
);
if (contentDispositionHeader) {
auto contentDisposition = ContentDisposition(belle_sip_header_content_disposition_get_content_disposition(contentDispositionHeader));
if (belle_sip_parameters_has_parameter(BELLE_SIP_PARAMETERS(contentDispositionHeader), "handling")) {
contentDisposition.setParameter("handling=" + string(belle_sip_parameters_get_parameter(BELLE_SIP_PARAMETERS(contentDispositionHeader), "handling")));
}
body.setContentDisposition(contentDisposition);
}
if (length > 0 && body_str) body.setBody(body_str, length);
return body;
}
@ -497,7 +500,9 @@ void SalCallOp::process_response_cb(void *op_base, const belle_sip_response_even
}
break;
case BELLE_SIP_DIALOG_TERMINATED: {
if (strcmp("INVITE",method)==0 && code >= 300){
if ((code >= 300)
&& ((strcmp("INVITE", method) == 0) || (strcmp("BYE", method) == 0))
) {
op->set_error(response, TRUE);
}
}
@ -1037,7 +1042,7 @@ int SalCallOp::decline(SalReason reason, const char *redirection /*optional*/){
}
belle_sip_header_reason_t *SalCallOp::make_reason_header( const SalErrorInfo *info){
if (info != NULL){
if (info && info->reason != SalReasonNone) {
belle_sip_header_reason_t* reason = BELLE_SIP_HEADER_REASON(belle_sip_header_reason_new());
belle_sip_header_reason_set_text(reason, info->status_string);
belle_sip_header_reason_set_protocol(reason,info->protocol);
@ -1123,25 +1128,25 @@ int SalCallOp::update(const char *subject, bool_t no_user_consent) {
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){
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){
if (cancel) {
if (info && info->reason != SalReasonNone) {
belle_sip_header_reason_t* reason = make_reason_header(info);
belle_sip_message_add_header(BELLE_SIP_MESSAGE(cancel),BELLE_SIP_HEADER(reason));
}
send_request(cancel);
return 0;
}else if (this->dialog){
} 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
* because already terminated*/
switch(state){
switch(state) {
case BELLE_SIP_DIALOG_EARLY:
case BELLE_SIP_DIALOG_NULL:
/*force kill the dialog*/
@ -1303,7 +1308,7 @@ int SalCallOp::terminate_with_error(const SalErrorInfo *info) {
int ret = 0;
memset(&sei, 0, sizeof(sei));
if (info == NULL && dialog_state != BELLE_SIP_DIALOG_CONFIRMED && this->dir == Dir::Incoming){
if (info == NULL && dialog_state != BELLE_SIP_DIALOG_CONFIRMED && this->dir == Dir::Incoming) {
/*the purpose of this line is to set a default SalErrorInfo for declining an incoming call (not yet established of course) */
sal_error_info_set(&sei,SalReasonDeclined, "SIP", 0, NULL, NULL);
p_sei = &sei;
@ -1318,7 +1323,7 @@ int SalCallOp::terminate_with_error(const SalErrorInfo *info) {
switch(dialog_state) {
case BELLE_SIP_DIALOG_CONFIRMED: {
belle_sip_request_t * req = belle_sip_dialog_create_request(this->dialog,"BYE");
if (info != NULL){
if (info && info->reason != SalReasonNone) {
belle_sip_header_reason_t* reason = make_reason_header(info);
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(reason));
}
@ -1334,7 +1339,7 @@ int SalCallOp::terminate_with_error(const SalErrorInfo *info) {
} else if (this->pending_client_trans){
if (belle_sip_transaction_get_state(BELLE_SIP_TRANSACTION(this->pending_client_trans)) == BELLE_SIP_TRANSACTION_PROCEEDING){
cancelling_invite(p_sei);
}else{
} else {
/* Case where the CANCEL cannot be sent because no provisional response was received so far.
* The Op must be kept for the time of the transaction in case a response is received later.
* The state is passed to Terminating to remember to terminate later.
@ -1351,7 +1356,7 @@ int SalCallOp::terminate_with_error(const SalErrorInfo *info) {
if (this->dir == Dir::Incoming) {
decline_with_error_info(p_sei,NULL);
this->state=State::Terminated;
} else {
} else {
cancelling_invite(p_sei);
}
break;

View file

@ -27,6 +27,8 @@
// =============================================================================
using namespace std;
LINPHONE_BEGIN_NAMESPACE
void BackgroundTask::sHandleTimeout (void *context) {
@ -43,7 +45,7 @@ void BackgroundTask::handleSalTimeout () {
stop();
}
void BackgroundTask::start (const std::shared_ptr<Core> &core, int maxDurationSeconds) {
void BackgroundTask::start (const shared_ptr<Core> &core, int maxDurationSeconds) {
if (mName.empty()) {
lError() << "No name was set on background task";
return;

View file

@ -35,23 +35,17 @@ class Core;
class BackgroundTask {
public:
BackgroundTask () {}
BackgroundTask (const std::string &name) {}
virtual ~BackgroundTask () {
stop();
}
BackgroundTask (const std::string &name) : mName(name) {}
virtual ~BackgroundTask () { stop(); }
void setName (const std::string &name) {
mName = name;
}
void setName (const std::string &name) { mName = name; }
const std::string &getName () const {
return mName;
}
const std::string &getName () const { return mName; }
/**
* Start a long running task for at most max_duration_seconds, after which it is automatically terminated
*/
void start (const std::shared_ptr<Core> &core, int maxDurationSeconds = 15 * 60); // 15 min by default, like on iOS
void start (const std::shared_ptr<Core> &core, int maxDurationSeconds = 15 * 60); // 15 min by default, like on iOS
void stop ();
protected:

View file

@ -821,11 +821,11 @@ static void multiple_answers_call_with_media_relay(void) {
linphone_core_remove_supported_tag(pauline->lc,"gruu");
linphone_core_remove_supported_tag(marie1->lc,"gruu");
linphone_core_remove_supported_tag(marie2->lc,"gruu");
linphone_core_manager_start(pauline, TRUE);
linphone_core_manager_start(marie1, TRUE);
linphone_core_manager_start(marie2, TRUE);
LinphoneCall* call1, *call2;
bctbx_list_t* lcs = bctbx_list_append(NULL,pauline->lc);
@ -1038,7 +1038,7 @@ static void terminate_call_with_error(void) {
linphone_call_ref(out_call);
ei = linphone_error_info_new();
linphone_error_info_set(ei, NULL, LinphoneReasonNone, 200, "Call refused for security reason", NULL);
linphone_error_info_set(ei, NULL, LinphoneReasonUnknown, 200, "Call refused for security reason", NULL);
BC_ASSERT_TRUE(wait_for(caller_mgr->lc, callee_mgr->lc, &caller_mgr->stat.number_of_LinphoneCallOutgoingInit,1));
BC_ASSERT_TRUE(wait_for(caller_mgr->lc, callee_mgr->lc, &callee_mgr->stat.number_of_LinphoneCallIncomingReceived, 1));
@ -1093,7 +1093,7 @@ static void cancel_call_with_error(void) {
linphone_call_ref(out_call);
ei = linphone_error_info_new();
linphone_error_info_set(ei, NULL, LinphoneReasonNone, 600, "Call has been cancelled", NULL);
linphone_error_info_set(ei, NULL, LinphoneReasonUnknown, 600, "Call has been cancelled", NULL);
BC_ASSERT_TRUE(wait_for(caller_mgr->lc, callee_mgr->lc, &caller_mgr->stat.number_of_LinphoneCallOutgoingInit,1));
BC_ASSERT_TRUE(wait_for(caller_mgr->lc, callee_mgr->lc, &callee_mgr->stat.number_of_LinphoneCallIncomingReceived, 1));
@ -1421,8 +1421,8 @@ static void call_declined_with_error(void) {
LinphoneErrorInfo *ei = linphone_factory_create_error_info(factory);
LinphoneErrorInfo *reason_ei = linphone_factory_create_error_info(factory);
linphone_error_info_set(ei, "SIP", LinphoneReasonUnknown, 603, "Decline", NULL); //ordre des arguments à vérifier
linphone_error_info_set(reason_ei, "hardware", LinphoneReasonUnknown, 66, "J'ai plus de batterie", NULL);
linphone_error_info_set(ei, "SIP", LinphoneReasonDeclined, 603, "Decline", NULL); //ordre des arguments à vérifier
linphone_error_info_set(reason_ei, "hardware", LinphoneReasonDeclined, 66, "J'ai plus de batterie", NULL);
linphone_error_info_set_sub_error_info(ei, reason_ei);
@ -3153,22 +3153,25 @@ static void early_media_call_with_ringing_base(bool_t network_change){
_linphone_call_add_local_desc_changed_flag(marie_call, SAL_MEDIA_DESCRIPTION_NETWORK_CHANGED);
}
linphone_call_accept(linphone_core_get_current_call(pauline->lc));
BC_ASSERT_TRUE(wait_for_list(lcs, &marie->stat.number_of_LinphoneCallConnected, 1,1000));
connected_time=ms_get_cur_time_ms();
BC_ASSERT_TRUE(wait_for_list(lcs, &marie->stat.number_of_LinphoneCallStreamsRunning, 1,1000));
BC_ASSERT_PTR_EQUAL(marie_call, linphone_core_get_current_call(marie->lc));
BC_ASSERT_FALSE(linphone_call_get_all_muted(marie_call));
liblinphone_tester_check_rtcp(marie, pauline);
/*just to have a call duration !=0*/
wait_for_list(lcs,&dummy,1,2000);
end_call(pauline, marie);
ended_time=ms_get_cur_time_ms();
BC_ASSERT_LOWER( labs((long)((linphone_call_log_get_duration(marie_call_log)*1000) - (int64_t)(ended_time - connected_time))), 1000, long, "%ld");
if (linphone_core_get_current_call(pauline->lc)
&& linphone_call_get_state(linphone_core_get_current_call(pauline->lc)) == LinphoneCallIncomingEarlyMedia) {
linphone_call_accept(linphone_core_get_current_call(pauline->lc));
BC_ASSERT_TRUE(wait_for_list(lcs, &marie->stat.number_of_LinphoneCallConnected, 1,1000));
connected_time=ms_get_cur_time_ms();
BC_ASSERT_TRUE(wait_for_list(lcs, &marie->stat.number_of_LinphoneCallStreamsRunning, 1,1000));
BC_ASSERT_PTR_EQUAL(marie_call, linphone_core_get_current_call(marie->lc));
BC_ASSERT_FALSE(linphone_call_get_all_muted(marie_call));
liblinphone_tester_check_rtcp(marie, pauline);
/*just to have a call duration !=0*/
wait_for_list(lcs,&dummy,1,2000);
end_call(pauline, marie);
ended_time=ms_get_cur_time_ms();
BC_ASSERT_LOWER( labs((long)((linphone_call_log_get_duration(marie_call_log)*1000) - (int64_t)(ended_time - connected_time))), 1000, long, "%ld");
}
bctbx_list_free(lcs);
}
@ -5908,7 +5911,7 @@ static void call_with_ice_without_stun2(void){
static void call_with_ice_stun_not_responding(void){
LinphoneCoreManager * marie = linphone_core_manager_new( "marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
/*set dummy stun servers*/
linphone_core_set_stun_server(marie->lc, "belledonne-communications.com:443");
linphone_core_set_stun_server(pauline->lc, "belledonne-communications.com:443");

View file

@ -2072,6 +2072,97 @@ static void video_call_with_high_bandwidth_available(void) {
linphone_core_manager_destroy(pauline);
}
static void video_call_expected_fps_for_specified_bandwidth(int bandwidth, int fps, const char *resolution) {
LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_new("pauline_rc");
LinphoneVideoPolicy pol = {0};
OrtpNetworkSimulatorParams simparams = { 0 };
if (ms_factory_get_cpu_count(linphone_core_get_ms_factory(marie->lc)) >= 2) {
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, resolution);
simparams.mode = OrtpNetworkSimulatorOutbound;
simparams.enabled = TRUE;
simparams.max_bandwidth = (float)bandwidth;
simparams.max_buffer_size = bandwidth;
simparams.latency = 60;
linphone_core_set_network_simulator_params(marie->lc, &simparams);
if (BC_ASSERT_TRUE(call(marie, pauline))){
LinphoneCall *call = linphone_core_get_current_call(marie->lc);
/*wait for the first TMMBR*/
BC_ASSERT_TRUE(wait_for_until(marie->lc, pauline->lc, &marie->stat.last_tmmbr_value_received, 1, 10000));
VideoStream *vstream = (VideoStream *)linphone_call_get_stream(call, LinphoneStreamTypeVideo);
BC_ASSERT_EQUAL((int)vstream->configured_fps, fps, int, "%d");
end_call(marie, pauline);
}
} else {
BC_PASS("Test requires at least a dual core");
}
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
}
/*
* This test simulates a video call with a lower bandwidth than the required_bitrate of the lowest given configuration.
* The stream from pauline to marie is not under test.
* It checks that after a few seconds marie, after receiving a TMMBR, has her fps set to the lowest given configuration.
* This test requires at least a computer with 2 CPUs.
*
**/
static void video_call_expected_fps_for_low_bandwidth(void) {
#if defined(__ANDROID__) || (TARGET_OS_IPHONE == 1) || defined(__arm__) || defined(_M_ARM)
video_call_expected_fps_for_specified_bandwidth(80000, 10, "qvga");
#else
video_call_expected_fps_for_specified_bandwidth(250000, 15, "vga");
#endif
}
/*
* This test simulates a video call with a regular bandwidth that is between a given configuration.
* The stream from pauline to marie is not under test.
* It checks that after a few seconds marie, after receiving a TMMBR, has her fps set to the expected given configuration.
* This test requires at least a computer with 2 CPUs.
*
**/
static void video_call_expected_fps_for_regular_bandwidth(void) {
#if defined(__ANDROID__) || (TARGET_OS_IPHONE == 1) || defined(__arm__) || defined(_M_ARM)
video_call_expected_fps_for_specified_bandwidth(500000, 12, "vga");
#else
video_call_expected_fps_for_specified_bandwidth(450000, 25, "vga");
#endif
}
/*
* This test simulates a video call with a higher bandwidth than the bitrate_limit of the highest given configuration.
* The stream from pauline to marie is not under test.
* It checks that after a few seconds marie, after receiving a TMMBR, has her fps set to the highest given configuration.
* This test requires at least a computer with 2 CPUs.
*
**/
static void video_call_expected_fps_for_high_bandwidth(void) {
#if defined(__ANDROID__) || (TARGET_OS_IPHONE == 1) || defined(__arm__) || defined(_M_ARM)
video_call_expected_fps_for_specified_bandwidth(400000, 12, "qcif");
#else
video_call_expected_fps_for_specified_bandwidth(5000000, 30, "vga");
#endif
}
test_t call_video_tests[] = {
#ifdef VIDEO_ENABLED
TEST_NO_TAG("Call paused resumed with video", call_paused_resumed_with_video),
@ -2140,7 +2231,10 @@ test_t call_video_tests[] = {
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 high bandwidth available", video_call_with_high_bandwidth_available)
TEST_NO_TAG("Video call with high bandwidth available", video_call_with_high_bandwidth_available),
TEST_NO_TAG("Video call expected FPS for low bandwidth", video_call_expected_fps_for_low_bandwidth),
TEST_NO_TAG("Video call expected FPS for regular bandwidth", video_call_expected_fps_for_regular_bandwidth),
TEST_NO_TAG("Video call expected FPS for high bandwidth", video_call_expected_fps_for_high_bandwidth)
#endif
};

View file

@ -58,15 +58,18 @@ FILE *sip_start(const char *senario, const char* dest_username, const char *pass
char *dest;
char *command;
FILE *file;
char local_ip[64];
if (linphone_address_get_port(dest_addres)>0)
dest = ms_strdup_printf("%s:%i",linphone_address_get_domain(dest_addres),linphone_address_get_port(dest_addres));
else
dest = ms_strdup_printf("%s",linphone_address_get_domain(dest_addres));
linphone_core_get_local_ip_for(AF_INET, linphone_address_get_domain(dest_addres), local_ip);
//until errors logs are handled correctly and stop breaks output, they will be DISABLED
command = ms_strdup_printf(SIPP_COMMAND" -sf %s -s %s %s -trace_err -trace_msg -rtp_echo -m 1 -d 1000 -ap %s 2>/dev/null",senario
command = ms_strdup_printf(SIPP_COMMAND" -sf %s -s %s %s -i %s -trace_err -trace_msg -rtp_echo -m 1 -d 1000 -ap %s 2>/dev/null",senario
,dest_username
,dest
,local_ip
,(passwd?passwd:"none"));
ms_message("Starting sipp command [%s]",command);
@ -109,8 +112,8 @@ LinphoneAddress * linphone_core_manager_resolve(LinphoneCoreManager *mgr, const
,&addrinfo);
dest=linphone_address_new(NULL);
wait_for(mgr->lc, mgr->lc, (int*)&addrinfo, 1);
wait_for_until(mgr->lc, mgr->lc, (int*)&addrinfo, 1,2000);
err=bctbx_getnameinfo((struct sockaddr*)addrinfo->ai_addr,addrinfo->ai_addrlen,ipstring,INET6_ADDRSTRLEN,NULL,0,NI_NUMERICHOST);
if (err !=0 ){
ms_error("linphone_core_manager_resolve(): getnameinfo error %s", gai_strerror(err));
@ -168,7 +171,7 @@ static void call_with_audio_mline_before_video_in_sdp(void) {
linphone_core_iterate(mgr->lc);
scen = bc_tester_res("sipp/call_with_audio_mline_before_video_in_sdp.xml");
sipp_out = sip_start(scen, linphone_address_get_username(mgr->identity), NULL, mgr->identity);
if (sipp_out) {
@ -365,12 +368,23 @@ static test_t tests[] = {
};
#endif
static bool_t previous_liblinphonetester_ipv6;
static void before_each(void) {
previous_liblinphonetester_ipv6=liblinphonetester_ipv6;
liblinphonetester_ipv6=FALSE; /*sipp do not support ipv6 and remote port*/
liblinphone_tester_before_each();
}
static void after_each(void) {
liblinphonetester_ipv6=previous_liblinphonetester_ipv6;
liblinphone_tester_after_each();
}
test_suite_t complex_sip_call_test_suite = {
"Complex SIP Case",
NULL,
NULL,
liblinphone_tester_before_each,
liblinphone_tester_after_each,
before_each,
after_each,
#if HAVE_SIPP
sizeof(tests) / sizeof(tests[0]),
tests

File diff suppressed because it is too large Load diff

View file

@ -69,6 +69,7 @@ static void chat_room_participant_device_added (LinphoneChatRoom *cr, const Linp
static void chat_room_state_changed (LinphoneChatRoom *cr, LinphoneChatRoomState newState) {
LinphoneCore *core = linphone_chat_room_get_core(cr);
LinphoneCoreManager *manager = (LinphoneCoreManager *)linphone_core_get_user_data(core);
ms_message("ChatRoom [%p] state changed: %d", cr, newState);
switch (newState) {
case LinphoneChatRoomStateNone:
break;
@ -105,6 +106,12 @@ static void chat_room_subject_changed (LinphoneChatRoom *cr, const LinphoneEvent
manager->stat.number_of_subject_changed++;
}
static void chat_room_all_information_received (LinphoneChatRoom *cr) {
LinphoneCore *core = linphone_chat_room_get_core(cr);
LinphoneCoreManager *manager = (LinphoneCoreManager *)linphone_core_get_user_data(core);
manager->stat.number_of_LinphoneChatRoomAllInformationReceived++;
}
static void core_chat_room_state_changed (LinphoneCore *core, LinphoneChatRoom *cr, LinphoneChatRoomState state) {
if (state == LinphoneChatRoomStateInstantiated) {
LinphoneChatRoomCbs *cbs = linphone_factory_create_chat_room_cbs(linphone_factory_get());
@ -115,6 +122,7 @@ static void core_chat_room_state_changed (LinphoneCore *core, LinphoneChatRoom *
linphone_chat_room_cbs_set_state_changed(cbs, chat_room_state_changed);
linphone_chat_room_cbs_set_subject_changed(cbs, chat_room_subject_changed);
linphone_chat_room_cbs_set_participant_device_added(cbs, chat_room_participant_device_added);
linphone_chat_room_cbs_set_all_information_received(cbs, chat_room_all_information_received);
linphone_chat_room_add_callbacks(cr, cbs);
linphone_chat_room_cbs_unref(cbs);
}
@ -180,9 +188,9 @@ static void _send_file_plus_text(LinphoneChatRoom* cr, const char *sendFilepath,
cbs = linphone_chat_message_get_callbacks(msg);
linphone_chat_message_cbs_set_file_transfer_send(cbs, tester_file_transfer_send);
linphone_chat_message_cbs_set_msg_state_changed(cbs,liblinphone_tester_chat_message_msg_state_changed);
linphone_chat_message_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed);
linphone_chat_message_cbs_set_file_transfer_progress_indication(cbs, file_transfer_progress_indication);
linphone_chat_room_send_chat_message(cr, msg);
linphone_chat_message_send(msg);
linphone_content_unref(content);
linphone_chat_message_unref(msg);
}
@ -255,6 +263,7 @@ static void start_core_for_conference(bctbx_list_t *coreManagerList) {
static LinphoneChatRoom * check_creation_chat_room_client_side(bctbx_list_t *lcs, LinphoneCoreManager *lcm, stats *initialStats, const LinphoneAddress *confAddr, const char* subject, int participantNumber, bool_t isAdmin) {
BC_ASSERT_TRUE(wait_for_list(lcs, &lcm->stat.number_of_LinphoneChatRoomStateCreationPending, initialStats->number_of_LinphoneChatRoomStateCreationPending + 1, 5000));
BC_ASSERT_TRUE(wait_for_list(lcs, &lcm->stat.number_of_LinphoneChatRoomStateCreated, initialStats->number_of_LinphoneChatRoomStateCreated + 1, 10000));
BC_ASSERT_TRUE(wait_for_list(lcs, &lcm->stat.number_of_LinphoneChatRoomAllInformationReceived, initialStats->number_of_LinphoneChatRoomAllInformationReceived + 1, 10000));
char *deviceIdentity = linphone_core_get_device_identity(lcm->lc);
LinphoneAddress *localAddr = linphone_address_new(deviceIdentity);
bctbx_free(deviceIdentity);
@ -273,7 +282,7 @@ static LinphoneChatRoom * check_creation_chat_room_client_side(bctbx_list_t *lcs
}
static LinphoneChatRoom * create_chat_room_client_side(bctbx_list_t *lcs, LinphoneCoreManager *lcm, stats *initialStats, bctbx_list_t *participantsAddresses, const char* initialSubject, int expectedParticipantSize) {
LinphoneChatRoom *chatRoom = linphone_core_create_client_group_chat_room(lcm->lc, initialSubject);
LinphoneChatRoom *chatRoom = linphone_core_create_client_group_chat_room(lcm->lc, initialSubject, FALSE);
if (!chatRoom) return NULL;
BC_ASSERT_TRUE(wait_for_list(lcs, &lcm->stat.number_of_LinphoneChatRoomStateInstantiated, initialStats->number_of_LinphoneChatRoomStateInstantiated + 1, 100));
@ -284,6 +293,7 @@ static LinphoneChatRoom * create_chat_room_client_side(bctbx_list_t *lcs, Linpho
// Check that the chat room is correctly created on Marie's side and that the participants are added
BC_ASSERT_TRUE(wait_for_list(lcs, &lcm->stat.number_of_LinphoneChatRoomStateCreationPending, initialStats->number_of_LinphoneChatRoomStateCreationPending + 1, 10000));
BC_ASSERT_TRUE(wait_for_list(lcs, &lcm->stat.number_of_LinphoneChatRoomStateCreated, initialStats->number_of_LinphoneChatRoomStateCreated + 1, 10000));
BC_ASSERT_TRUE(wait_for_list(lcs, &lcm->stat.number_of_LinphoneChatRoomAllInformationReceived, initialStats->number_of_LinphoneChatRoomAllInformationReceived + 1, 10000));
BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(chatRoom),
(expectedParticipantSize >= 0) ? expectedParticipantSize : (int)bctbx_list_size(participantsAddresses),
int, "%d");
@ -1528,13 +1538,14 @@ static void group_chat_room_reinvited_after_removed_base (bool_t offline_when_re
bctbx_list_t *tmpCoresManagerList = bctbx_list_append(NULL, laure);
bctbx_list_t *tmpCoresList = init_core_for_conference(tmpCoresManagerList);
bctbx_list_free(tmpCoresManagerList);
initialLaureStats = laure->stat;
linphone_core_manager_start(laure, TRUE);
coresList = bctbx_list_concat(coresList, tmpCoresList);
coresManagerList = bctbx_list_append(coresManagerList, laure);
}
if (!offline_when_reinvited)
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneChatRoomStateTerminated, initialLaureStats.number_of_LinphoneChatRoomStateTerminated + 1, 3000));
wait_for_list(coresList,0, 1, 2000);
initialLaureStats = laure->stat;
// Marie adds Laure to the chat room
participantsAddresses = bctbx_list_append(participantsAddresses, laureAddr);
@ -1550,16 +1561,13 @@ static void group_chat_room_reinvited_after_removed_base (bool_t offline_when_re
bctbx_list_t *tmpCoresManagerList = bctbx_list_append(NULL, laure);
bctbx_list_t *tmpCoresList = init_core_for_conference(tmpCoresManagerList);
bctbx_list_free(tmpCoresManagerList);
initialLaureStats = laure->stat;
linphone_core_manager_start(laure, TRUE);
coresList = bctbx_list_concat(coresList, tmpCoresList);
coresManagerList = bctbx_list_append(coresManagerList, laure);
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneChatRoomStateCreationPending, initialLaureStats.number_of_LinphoneChatRoomStateCreationPending + 1, 5000));
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneChatRoomStateCreated, initialLaureStats.number_of_LinphoneChatRoomStateCreated + 2, 5000));
} else {
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneChatRoomStateCreationPending, initialLaureStats.number_of_LinphoneChatRoomStateCreationPending + 1, 5000));
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneChatRoomStateCreated, initialLaureStats.number_of_LinphoneChatRoomStateCreated + 1, 5000));
}
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneChatRoomStateCreationPending, initialLaureStats.number_of_LinphoneChatRoomStateCreationPending + 1, 5000));
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneChatRoomStateCreated, initialLaureStats.number_of_LinphoneChatRoomStateCreated + 1, 5000));
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneChatRoomAllInformationReceived, initialLaureStats.number_of_LinphoneChatRoomAllInformationReceived + 1, 5000));
BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(marieCr), 2, int, "%d");
BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(paulineCr), 2, int, "%d");
char *laureIdentity = linphone_core_get_device_identity(laure->lc);
@ -2131,7 +2139,7 @@ static void group_chat_room_fallback_to_basic_chat_room (void) {
stats initialPaulineStats = pauline->stat;
// Marie creates a new group chat room
LinphoneChatRoom *marieCr = linphone_core_create_client_group_chat_room(marie->lc, "Fallback");
LinphoneChatRoom *marieCr = linphone_core_create_client_group_chat_room(marie->lc, "Fallback", TRUE);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneChatRoomStateInstantiated, initialMarieStats.number_of_LinphoneChatRoomStateInstantiated + 1, 100));
// Add participants
@ -2187,13 +2195,13 @@ static void group_chat_room_creation_fails_if_invited_participants_dont_support_
stats initialMarieStats = marie->stat;
// Marie creates a new group chat room
LinphoneChatRoom *marieCr = linphone_core_create_client_group_chat_room(marie->lc, "Hello there");
LinphoneChatRoom *marieCr = linphone_core_create_client_group_chat_room(marie->lc, "Hello there", FALSE);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneChatRoomStateInstantiated, initialMarieStats.number_of_LinphoneChatRoomStateInstantiated + 1, 100));
// Add participants
linphone_chat_room_add_participants(marieCr, participantsAddresses);
// Check that the group chat room creation fails and that a fallback to a basic chat room is done
// Check that the group chat room creation fails
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneChatRoomStateCreationPending, initialMarieStats.number_of_LinphoneChatRoomStateCreationPending + 1, 10000));
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneChatRoomStateCreationFailed, initialMarieStats.number_of_LinphoneChatRoomStateCreationFailed + 1, 10000));
bctbx_list_free_with_data(participantsAddresses, (bctbx_list_free_func)linphone_address_unref);
@ -2301,12 +2309,14 @@ static void group_chat_room_migrate_from_basic_chat_room (void) {
linphone_chat_message_unref(msg);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneChatRoomStateCreationPending, initialMarieStats.number_of_LinphoneChatRoomStateCreationPending + 1, 10000));
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneChatRoomStateCreated, initialMarieStats.number_of_LinphoneChatRoomStateCreated + 1, 10000));
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneChatRoomAllInformationReceived, initialMarieStats.number_of_LinphoneChatRoomAllInformationReceived + 1, 10000));
BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(marieCr) & LinphoneChatRoomCapabilitiesConference);
BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(marieCr), 1, int, "%d");
BC_ASSERT_EQUAL(linphone_chat_room_get_history_size(marieCr), 2, int, "%d");
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneChatRoomStateCreationPending, initialPaulineStats.number_of_LinphoneChatRoomStateCreationPending + 1, 10000));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneChatRoomStateCreated, initialPaulineStats.number_of_LinphoneChatRoomStateCreated + 1, 10000));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneChatRoomAllInformationReceived, initialPaulineStats.number_of_LinphoneChatRoomAllInformationReceived + 1, 10000));
BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(paulineCr) & LinphoneChatRoomCapabilitiesConference);
BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(paulineCr), 1, int, "%d");
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, initialPaulineStats.number_of_LinphoneMessageReceived + 1, 1000));
@ -2357,7 +2367,7 @@ static void group_chat_room_migrate_from_basic_to_client_fail (void) {
stats initialPaulineStats = pauline->stat;
// Marie creates a new group chat room
LinphoneChatRoom *marieCr = linphone_core_create_client_group_chat_room(marie->lc, "Fallback");
LinphoneChatRoom *marieCr = linphone_core_create_client_group_chat_room(marie->lc, "Fallback", TRUE);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneChatRoomStateInstantiated, initialMarieStats.number_of_LinphoneChatRoomStateInstantiated + 1, 100));
// Add participants
@ -2430,6 +2440,7 @@ static void group_chat_room_migrate_from_basic_to_client_fail (void) {
BC_ASSERT_EQUAL(linphone_chat_room_get_history_size(paulineCr), 4, int, "%d");
// Activate groupchat on Pauline's side and wait for 5 seconds, the migration should now be done on next message sending
lp_config_set_int(linphone_core_get_config(marie->lc),"misc","basic_to_client_group_chat_room_migration_timer",5);
linphone_core_set_linphone_specs(pauline->lc, "groupchat");
linphone_core_set_network_reachable(pauline->lc, FALSE);
wait_for_list(coresList, &dummy, 1, 1000);
@ -2439,12 +2450,14 @@ static void group_chat_room_migrate_from_basic_to_client_fail (void) {
linphone_chat_message_send(msg);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneChatRoomStateCreationPending, initialMarieStats.number_of_LinphoneChatRoomStateCreationPending + 2, 10000));
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneChatRoomStateCreated, initialMarieStats.number_of_LinphoneChatRoomStateCreated + 1, 10000));
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneChatRoomAllInformationReceived, initialMarieStats.number_of_LinphoneChatRoomAllInformationReceived + 1, 10000));
BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(marieCr) & LinphoneChatRoomCapabilitiesConference);
BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(marieCr), 1, int, "%d");
BC_ASSERT_EQUAL(linphone_chat_room_get_history_size(marieCr), 5, int, "%d");
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneChatRoomStateCreationPending, initialPaulineStats.number_of_LinphoneChatRoomStateCreationPending + 1, 10000));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneChatRoomStateCreated, initialPaulineStats.number_of_LinphoneChatRoomStateCreated + 1, 10000));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneChatRoomAllInformationReceived, initialPaulineStats.number_of_LinphoneChatRoomAllInformationReceived + 1, 10000));
BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(paulineCr) & LinphoneChatRoomCapabilitiesConference);
BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(paulineCr), 1, int, "%d");
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, initialPaulineStats.number_of_LinphoneMessageReceived + 3, 1000));
@ -2508,13 +2521,13 @@ static void group_chat_donot_room_migrate_from_basic_chat_room (void) {
linphone_chat_message_send(msg);
linphone_chat_message_unref(msg);
BC_ASSERT_FALSE(wait_for_list(coresList, &marie->stat.number_of_LinphoneChatRoomStateCreationPending, initialMarieStats.number_of_LinphoneChatRoomStateCreationPending + 1, 10000));
BC_ASSERT_FALSE(wait_for_list(coresList, &marie->stat.number_of_LinphoneChatRoomStateCreated, initialMarieStats.number_of_LinphoneChatRoomStateCreated + 1, 10000));
BC_ASSERT_FALSE(wait_for_list(coresList, &marie->stat.number_of_LinphoneChatRoomStateCreated, initialMarieStats.number_of_LinphoneChatRoomStateCreated + 1, 3000));
BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(marieCr) & LinphoneChatRoomCapabilitiesBasic);
BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(marieCr), 1, int, "%d");
BC_ASSERT_EQUAL(linphone_chat_room_get_history_size(marieCr), 2, int, "%d");
BC_ASSERT_FALSE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneChatRoomStateCreationPending, initialPaulineStats.number_of_LinphoneChatRoomStateCreationPending + 1, 10000));
BC_ASSERT_FALSE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneChatRoomStateCreated, initialPaulineStats.number_of_LinphoneChatRoomStateCreated + 1, 10000));
BC_ASSERT_FALSE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneChatRoomStateCreated, initialPaulineStats.number_of_LinphoneChatRoomStateCreated + 1, 3000));
BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(paulineCr) & LinphoneChatRoomCapabilitiesBasic);
BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(paulineCr), 1, int, "%d");
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, initialPaulineStats.number_of_LinphoneMessageReceived + 1, 1000));
@ -2791,10 +2804,10 @@ static void group_chat_room_unique_one_to_one_chat_room_recreated_from_message_w
static void group_chat_room_unique_one_to_one_chat_room_recreated_from_message_2 (void) {
LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc");
/*create a second device for marie, but it is inactive after registration in this test*/
// Create a second device for Marie, but it is inactive after registration in this test
LinphoneCoreManager *marie2 = linphone_core_manager_create("marie_rc");
/*Create a seconde device for pauline, but again inactivate after registration*/
LinphoneCoreManager *pauline2 = linphone_core_manager_create("marie_rc");
// Create a second device for Pauline, but again inactivate it after registration
LinphoneCoreManager *pauline2 = linphone_core_manager_create("pauline_rc");
bctbx_list_t *coresManagerList = NULL;
bctbx_list_t *participantsAddresses = NULL;
coresManagerList = bctbx_list_append(coresManagerList, marie);
@ -2806,6 +2819,8 @@ static void group_chat_room_unique_one_to_one_chat_room_recreated_from_message_2
participantsAddresses = bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc)));
stats initialMarieStats = marie->stat;
stats initialPaulineStats = pauline->stat;
stats initialMarie2Stats = marie2->stat;
stats initialPauline2Stats = pauline2->stat;
linphone_core_set_network_reachable(marie2->lc, FALSE);
linphone_core_set_network_reachable(pauline2->lc, FALSE);
@ -2851,13 +2866,22 @@ static void group_chat_room_unique_one_to_one_chat_room_recreated_from_message_2
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, initialPaulineStats.number_of_LinphoneMessageReceived + 1, 10000));
BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(pauline->stat.last_received_chat_message), textMessage);
linphone_chat_message_unref(message);
// Clean db from chat room
linphone_core_manager_delete_chat_room(marie, marieCr, coresList);
}
linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList);
wait_for_list(coresList, 0, 1, 2000);
// Clean db from chat room
linphone_core_set_network_reachable(marie2->lc, TRUE);
linphone_core_set_network_reachable(pauline2->lc, TRUE);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie2->stat.number_of_LinphoneChatRoomStateCreationPending, initialMarie2Stats.number_of_LinphoneChatRoomStateCreationPending + 1, 3000));
BC_ASSERT_TRUE(wait_for_list(coresList, &marie2->stat.number_of_LinphoneChatRoomStateCreated, initialMarie2Stats.number_of_LinphoneChatRoomStateCreated + 1, 3000));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline2->stat.number_of_LinphoneChatRoomStateCreationPending, initialPauline2Stats.number_of_LinphoneChatRoomStateCreationPending + 1, 3000));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline2->stat.number_of_LinphoneChatRoomStateCreated, initialPauline2Stats.number_of_LinphoneChatRoomStateCreated + 1, 3000));
linphone_core_manager_delete_chat_room(marie, marieCr, coresList);
linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneChatRoomStateTerminated, initialMarieStats.number_of_LinphoneChatRoomStateTerminated + 1, 3000));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneChatRoomStateTerminated, initialPaulineStats.number_of_LinphoneChatRoomStateTerminated + 1, 3000));
BC_ASSERT_TRUE(wait_for_list(coresList, &marie2->stat.number_of_LinphoneChatRoomStateTerminated, initialMarie2Stats.number_of_LinphoneChatRoomStateTerminated + 1, 3000));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline2->stat.number_of_LinphoneChatRoomStateTerminated, initialPauline2Stats.number_of_LinphoneChatRoomStateTerminated + 1, 3000));
BC_ASSERT_EQUAL(linphone_core_get_call_history_size(marie->lc), 0, int,"%i");
BC_ASSERT_EQUAL(linphone_core_get_call_history_size(pauline->lc), 0, int,"%i");
BC_ASSERT_PTR_NULL(linphone_core_get_call_logs(marie->lc));
@ -2866,8 +2890,6 @@ static void group_chat_room_unique_one_to_one_chat_room_recreated_from_message_2
linphone_address_unref(confAddr);
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_set_network_reachable(marie2->lc, TRUE);
linphone_core_set_network_reachable(pauline2->lc, TRUE);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(marie2);
@ -2946,6 +2968,9 @@ static void group_chat_room_join_one_to_one_chat_room_with_a_new_device (void) {
linphone_chat_message_unref(message);
// Clean db from chat room
int previousNbRegistrationOk = marie1->stat.number_of_LinphoneRegistrationOk;
linphone_core_set_network_reachable(marie1->lc, TRUE);
wait_for_until(marie1->lc, NULL, &marie1->stat.number_of_LinphoneRegistrationOk, previousNbRegistrationOk + 1, 2000);
linphone_core_manager_delete_chat_room(marie2, marie2Cr, coresList);
linphone_core_delete_chat_room(marie1->lc, marie1Cr);
linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList);
@ -2985,6 +3010,7 @@ static void group_chat_room_new_unique_one_to_one_chat_room_after_both_participa
// Both participants delete the chat room
linphone_core_manager_delete_chat_room(marie, marieCr, coresList);
linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList);
wait_for_list(coresList, 0, 1, 3000);
// Marie re-creates a chat room with Pauline
initialMarieStats = marie->stat;
@ -3271,7 +3297,7 @@ test_t group_chat_tests[] = {
TEST_NO_TAG("Unique one-to-one chatroom", group_chat_room_unique_one_to_one_chat_room),
TEST_NO_TAG("Unique one-to-one chatroom recreated from message", group_chat_room_unique_one_to_one_chat_room_recreated_from_message),
TEST_ONE_TAG("Unique one-to-one chatroom recreated from message with app restart", group_chat_room_unique_one_to_one_chat_room_recreated_from_message_with_app_restart, "LeaksMemory"),
TEST_NO_TAG("Join one-to-one chat room with a new device", group_chat_room_join_one_to_one_chat_room_with_a_new_device),
TEST_ONE_TAG("Join one-to-one chat room with a new device", group_chat_room_join_one_to_one_chat_room_with_a_new_device, "LeaksMemory"),
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),

View file

@ -182,6 +182,7 @@ typedef struct _stats {
int number_of_LinphoneIsComposingIdleReceived;
int progress_of_LinphoneFileTransfer;
int number_of_LinphoneChatRoomAllInformationReceived;
int number_of_LinphoneChatRoomStateInstantiated;
int number_of_LinphoneChatRoomStateCreationPending;
int number_of_LinphoneChatRoomStateCreated;

View file

@ -788,7 +788,7 @@ static void presence_list_subscribe_network_changes(void) {
linphone_core_set_presence_model(pauline->lc, presence);
linphone_presence_model_unref(presence);
BC_ASSERT_TRUE(wait_for_until(laure->lc, pauline->lc, &laure->stat.number_of_LinphonePresenceActivityAway, 1, 6000));
BC_ASSERT_TRUE(wait_for_until(laure->lc, pauline->lc, &laure->stat.number_of_LinphonePresenceActivityAway, 2, 6000));
lf = linphone_friend_list_find_friend_by_uri(linphone_core_get_default_friend_list(laure->lc), pauline_identity);
BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusAway, int, "%d");
@ -829,6 +829,28 @@ static void long_term_presence_base(const char* addr, bool_t exist, const char*
linphone_friend_unref(friend2);
linphone_core_manager_destroy(pauline);
}
static void long_term_presence_large_number_of_subs(void) {
int i=0;
LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
linphone_core_set_user_agent(pauline->lc, "bypass", NULL);
LinphoneFriendList *friends = linphone_core_create_friend_list(pauline->lc);
linphone_friend_list_set_rls_uri(friends, "sip:rls@sip.example.org");
for (i = 0 ; i <1000; i++ ) {
char user_id[256];
snprintf(user_id, sizeof(user_id), "sip:user_%i@sip.example.org",i);
LinphoneFriend* friend2 =linphone_core_create_friend_with_address(pauline->lc, user_id);
linphone_friend_list_add_friend(friends,friend2);
linphone_friend_unref(friend2);
}
linphone_core_add_friend_list(pauline->lc, friends);
linphone_friend_list_unref(friends);
BC_ASSERT_TRUE(wait_for(pauline->lc,NULL,&pauline->stat.number_of_NotifyPresenceReceived,i));
linphone_core_manager_destroy(pauline);
}
static void long_term_presence_existing_friend(void) {
// this friend is not online, but is known from flexisip to be registered (see flexisip/userdb.conf),
// so we expect to get a report that he is currently not online
@ -1739,6 +1761,7 @@ test_t presence_server_tests[] = {
TEST_ONE_TAG("Long term presence with +164 phone, without sip",long_term_presence_with_e164_phone_without_sip, "longterm"),
TEST_ONE_TAG("Long term presence with phone, without sip",long_term_presence_with_phone_without_sip, "longterm"),
TEST_ONE_TAG("Long term presence with cross references", long_term_presence_with_crossed_references,"longtern"),
TEST_ONE_TAG("Long term presence with large number of subs", long_term_presence_large_number_of_subs,"longtern"),
TEST_NO_TAG("Subscriber no longer reachable using server",subscriber_no_longer_reachable),
TEST_NO_TAG("Subscribe with late publish", subscribe_with_late_publish),
TEST_NO_TAG("Multiple publish aggregation", multiple_publish_aggregation),

View file

@ -1,7 +1,7 @@
[sip]
sip_port=5092
sip_tcp_port=5092
sip_tls_port=5093
sip_port=-1
sip_tcp_port=-1
sip_tls_port=-1
default_proxy=0
ping_with_options=0

View file

@ -1,7 +1,7 @@
[sip]
sip_port=5092
sip_tcp_port=5092
sip_tls_port=5093
sip_port=-1
sip_tcp_port=-1
sip_tls_port=-1
default_proxy=0
ping_with_options=0

View file

@ -1,7 +1,7 @@
[sip]
sip_port=5092
sip_tcp_port=5092
sip_tls_port=5093
sip_port=-1
sip_tcp_port=-1
sip_tls_port=-1
default_proxy=0
ping_with_options=0

View file

@ -29,7 +29,7 @@ subscribe=0
[misc]
enable_basic_to_client_group_chat_room_migration=1
basic_to_client_group_chat_room_migration_timer=10
basic_to_client_group_chat_room_migration_timer=180
[rtp]
audio_rtp_port=18070-28000

View file

@ -1,7 +1,7 @@
[sip]
sip_port=5072
sip_tcp_port=5072
sip_tls_port=5073
sip_port=-1
sip_tcp_port=-1
sip_tls_port=-1
default_proxy=0
[auth_info_0]

View file

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="UTF-8"?>
<config xmlns="http://www.linphone.org/xsds/lpconfig.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.linphone.org/xsds/lpconfig.xsd lpconfig.xsd">
<section name="sip">
<entry name="sip_port">-1</entry>
<entry name="sip_tcp_port">-1</entry>
<entry name="sip_tls_port">-1</entry>
<entry name="default_proxy">0</entry>
<entry name="ping_with_options">0</entry>
<entry name="register_only_when_network_is_up">0</entry>
<entry name="composing_idle_timeout">1</entry>
</section>
<section name="auth_info_0">
<entry name="username">marie</entry>
<entry name="userid">marie</entry>
<entry name="passwd">secret</entry>
<!--entry name="ha1">c4ce0fe4c1c82e4b700726e085aee9b3</entry-->
<entry name="realm">sip.example.org</entry>
</section>
<section name="proxy_0">
<entry name="reg_proxy">sip.example.org;transport=tcp</entry>
<entry name="reg_route">sip.example.org;transport=tcp;lr</entry>
<entry name="reg_identity">sip:marie@sip.example.org</entry>
<entry name="reg_expires">3600</entry>
<entry name="reg_sendregister">1</entry>
<entry name="publish">0</entry>
<entry name="dial_escape_plus">0</entry>
</section>
<section name="friend_0">
<entry name="url">"Paupoche" &lt;sip:pauline@sip.example.org&gt;</entry>
<entry name="pol">accept</entry>
<entry name="subscribe">0</entry>
</section>
<section name="rtp">
<entry name="audio_rtp_port">8070</entry>
<entry name="video_rtp_port">9072</entry>
</section>
<section name="video">
<entry name="display">0</entry>
<entry name="capture">0</entry>
<entry name="show_local">0</entry>
<entry name="size">vga</entry>
<entry name="enabled">0</entry>
<entry name="self_view">0</entry>
<entry name="automatically_initiate">0</entry>
<entry name="automatically_accept">0</entry>
<entry name="device">StaticImage: Static picture</entry>
</section>
<section name="sound">
<entry name="echocancellation">0 #to not overload cpu in case of VG</entry>
</section>
</config>

View file

@ -38,10 +38,11 @@
Content-Length: [len]
<?xml version="1.0" encoding="UTF-8"?>
<presence xmlns:dm="urn:ietf:params:xml:ns:pidf:data-model" xmlns:rpid="urn:ietf:params:xml:ns:pidf:rpid" entity="sip:[service]@sip.example.org" xmlns="urn:ietf:params:xml:ns:pidf">
<presence xmlns:dm="urn:ietf:params:xml:ns:pidf:data-model" xmlns:rpid="urn:ietf:params:xml:ns:pidf:rpid" xmlns:pidfonline="http://www.linphone.org/xsds/pidfonline.xsd" entity="sip:[service]@sip.example.org" xmlns="urn:ietf:params:xml:ns:pidf">
<tuple id="jjlson">
<status>
<basic>open</basic>
<pidfonline:online/>
</status>
<contact priority="0.8">sip:[service]@[local_ip]:[local_port]</contact>
<timestamp>2015-09-28T15:49:00Z</timestamp>
@ -74,10 +75,11 @@
Content-Length: [len]
<?xml version="1.0" encoding="UTF-8"?>
<presence xmlns:dm="urn:ietf:params:xml:ns:pidf:data-model" xmlns:rpid="urn:ietf:params:xml:ns:pidf:rpid" entity="sip:[service]@sip.example.org" xmlns="urn:ietf:params:xml:ns:pidf">
<presence xmlns:dm="urn:ietf:params:xml:ns:pidf:data-model" xmlns:rpid="urn:ietf:params:xml:ns:pidf:rpid" xmlns:pidfonline="http://www.linphone.org/xsds/pidfonline.xsd" entity="sip:[service]@sip.example.org" xmlns="urn:ietf:params:xml:ns:pidf">
<tuple id="jjlson">
<status>
<basic>open</basic>
<pidfonline:online/>
</status>
<contact priority="0.8">sip:[service]@[local_ip]:[local_port]</contact>
<timestamp>2015-09-28T15:49:00Z</timestamp>

View file

@ -19,6 +19,8 @@
#include <stdio.h>
#include <stdlib.h>
#include "linphone/core.h"
#include "linphone/logging.h"
#include "logging-private.h"
#include "liblinphone_tester.h"
#include <bctoolbox/tester.h>
#include "tester_utils.h"
@ -503,7 +505,7 @@ void linphone_core_manager_uninit(LinphoneCoreManager *mgr) {
linphone_core_cbs_unref(mgr->cbs);
manager_count--;
linphone_core_set_log_level(old_log_level);
linphone_core_set_log_level_mask(old_log_level);
}
void linphone_core_manager_wait_for_stun_resolution(LinphoneCoreManager *mgr) {

View file

@ -364,8 +364,12 @@ static void friends_sqlite_store_lot_of_friends(void) {
char* errmsg = NULL;
int ret;
char *buf;
char *friends_db = bc_tester_file("friends.db");
unlink(friends_db);
ret = sqlite3_open(friends_db, &db);
bc_free(friends_db);
ret = sqlite3_open(linphone_core_get_friends_database_path(lc), &db);
BC_ASSERT_TRUE(ret ==SQLITE_OK);
ret = sqlite3_exec(db,"BEGIN",0,0,&errmsg);
BC_ASSERT_TRUE(ret ==SQLITE_OK);
@ -432,8 +436,12 @@ static void friends_sqlite_find_friend_in_lot_of_friends(void) {
char *buf;
bctoolboxTimeSpec t1;
bctoolboxTimeSpec t2;
char *friends_db = bc_tester_file("friends.db");
unlink(friends_db);
ret = sqlite3_open(friends_db, &db);
bc_free(friends_db);
ret = sqlite3_open(linphone_core_get_friends_database_path(lc), &db);
BC_ASSERT_TRUE(ret ==SQLITE_OK);
ret = sqlite3_exec(db,"BEGIN",0,0,&errmsg);
BC_ASSERT_TRUE(ret ==SQLITE_OK);

View file

@ -21,6 +21,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include <linphone/linphone_tunnel.h>
#include <linphone/linphonecore_utils.h>
#include <linphone/wrapper_utils.h>
#include <linphone/logging.h>
#include "linphone++/linphone.hh"
#include "tools.hh"

View file

@ -95,6 +95,11 @@ public {{#isLinphoneFactory}}abstract class{{/isLinphoneFactory}}{{#isNotLinphon
abstract public OpenH264DownloadHelper createOpenH264DownloadHelper(Context context);
/**
* Gets the LoggingService singleton
*/
abstract public LoggingService getLoggingService();
abstract public void setDebugMode(boolean enable, String tag);
abstract public Core getCore(long ptr);
@ -176,6 +181,12 @@ class {{classImplName}} {{#isLinphoneFactory}}extends{{/isLinphoneFactory}}{{#is
return getCore(nativePtr, ptr);
}
@Override
public LoggingService getLoggingService() {
LoggingService l = new LoggingServiceImpl(0);
return l.get();
}
@Override
public native void setDebugMode(boolean enable, String tag);
{{/isLinphoneFactory}}