Commit 117ff964 authored by jehan's avatar jehan

Merge branch 'dev_lime_v2'

parents 94d1716b 48287957
......@@ -47,6 +47,7 @@ option(ENABLE_DAEMON "Enable the linphone daemon interface." YES)
option(ENABLE_DATE "Use build date in internal version number." NO)
option(ENABLE_DEBUG_LOGS "Turn on or off debug level logs." NO)
option(ENABLE_DOC "Enable API documentation generation." NO)
option(ENABLE_LIME_X3DH "Enable LIMEv2 and X3DH encryption protocol." YES)
option(ENABLE_JAVA_WRAPPER "Build the Java wrapper for Liblinphone." OFF)
option(ENABLE_JAVADOC "Add a target to generate documentation for Java API" NO)
option(ENABLE_LDAP "Enable LDAP support." NO)
......@@ -162,6 +163,14 @@ endif()
if(ENABLE_ASSISTANT)
set(BUILD_WIZARD 1)
endif()
if(ENABLE_LIME AND ENABLE_LIME_X3DH)
message(WARNING "Lime V1 and V2 cannot be used simultaneously! Using Lime V2 only instead.")
set(ENABLE_LIME FALSE)
endif()
if(ENABLE_LIME_X3DH)
find_package(Lime REQUIRED)
set(HAVE_LIME_X3DH TRUE)
endif()
if(ENABLE_LIME)
#bzrtp is only required for LIME
if(LINPHONE_BUILDER_GROUP_EXTERNAL_SOURCE_PATH_BUILDERS)
......@@ -270,6 +279,7 @@ set(STRICT_OPTIONS_OBJC )
if(MSVC)
list(APPEND STRICT_OPTIONS_CPP "/wd4995") # Disable "name was marked as #pragma deprecated" warnings
list(APPEND STRICT_OPTIONS_CPP "/wd4996") # Disable deprecated function warnings
list(APPEND STRICT_OPTIONS_CPP "/wd4800") # Disable warning for cast from bool_t to bool
if(ENABLE_STRICT)
list(APPEND STRICT_OPTIONS_CPP "/WX")
endif()
......
......@@ -11,6 +11,8 @@ Group changes to describe their impact on the project, as follows:
Security to invite users to upgrade in case of vulnerabilities.
## [Incomming]
- Implementation of bodyless subscription
- Parsing of Display name in presence NOTIFY
### Added
- Avoid some SIP DNS lookups by keeping SRV target names
......@@ -15,19 +15,19 @@ This library is used by Linphone. It's source code is available at *linphone-des
* **BcToolbox[2]:** portability layer
* **BelleSIP[3]:** SIP stack
* **Mediastreamer2[4]:** multimedia engine
* **Belcard[5]:** VCard support
* **Belcard[5]:** VCard4 support
* **libxml2**
* **zlib**
* **libsqlite3:** user data storage (disablable)
* **gettext** and **libintl**: internationalization support (disablable)
* **python interpreter** and **pystache**, **six** python module (needed for C++ wrapper and API documentaiton)
* **libsqlite3:** user data storage (can be disabled)
* **gettext** and **libintl**: internationalization support (can be disabled)
* **python interpreter** and **pystache**, **six** python module (needed for C++/C#/Java wrappers and API documentation)
* **doxygen** and **dot** (needed for C++ wrapper and API documentation)
## Optional dependencies
* **Bzrtp[6]**: zrtp stack used for Linphone Instant Messaging Encryption.
* For API documentatino generation: **sphinx**, **javasphinx**, **sphinx_csharp** python modules are needed.
* **Bzrtp[6]**: zrtp stack used to secure calls and for LIME (Linphone Instant Messaging Encryption).
* For API documentation generation: **sphinx**, **javasphinx**, **sphinx_csharp** python modules are needed.
## Build instructions
......@@ -47,9 +47,9 @@ This library is used by Linphone. It's source code is available at *linphone-des
* **`ENABLE_STRICT=NO`** : build without strict compilation flags (-Wall -Werror)
* **`ENABLE_DOC=YES`** : Make the reference documentation of liblinphone to generated
* **`ENABLE_UNIT_TESTS=NO`** : do not build testing binaries
* **`ENABLE_VCARD=NO`** : disable VCard support
* **`ENABLE_VCARD=NO`** : disable VCard4 support
* **`ENABLE_TOOLS=NO`** : do not build tool binaries
* **`ENABLE_LIME=YES`** : disable Linphone Instant Messaging Encryption
* **`ENABLE_LIME=NO`** : disable Linphone Instant Messaging Encryption
## Note for packagers
......
......@@ -46,4 +46,5 @@
#cmakedefine HAVE_CU_CURSES 1
#cmakedefine HAVE_LIBUDEV_H 0
#cmakedefine HAVE_LIME
#cmakedefine HAVE_LIME_X3DH
#cmakedefine ENABLE_UPDATE_CHECK 1
This diff is collapsed.
......@@ -33,7 +33,9 @@ struct _LinphoneAccountCreatorService {
LinphoneAccountCreatorRequestFunc account_creator_service_destructor_cb; /**< Destructor */
LinphoneAccountCreatorRequestFunc create_account_request_cb; /**< Request to create account */
LinphoneAccountCreatorRequestFunc delete_account_request_cb; /**< Request to delete account */
LinphoneAccountCreatorRequestFunc is_account_exist_request_cb; /**< Request to know if account exist */
LinphoneAccountCreatorRequestFunc get_confirmation_key_request_cb; /**< Request to get the confirmation key */
LinphoneAccountCreatorRequestFunc activate_account_request_cb; /**< Request to activate account */
LinphoneAccountCreatorRequestFunc is_account_activated_request_cb; /**< Request to know if account is activated */
......@@ -54,10 +56,12 @@ struct _LinphoneAccountCreatorCbs {
void *user_data;
LinphoneAccountCreatorCbsStatusCb create_account_response_cb; /**< Response of create_account request */
LinphoneAccountCreatorCbsStatusCb delete_account_response_cb; /**< Response of delete_account request */
LinphoneAccountCreatorCbsStatusCb is_account_exist_response_cb; /**< Response of is_account_exist request */
LinphoneAccountCreatorCbsStatusCb activate_account_response_cb; /**< Response of activate_account request */
LinphoneAccountCreatorCbsStatusCb is_account_activated_response_cb; /**< Response of is_account_activated request */
LinphoneAccountCreatorCbsStatusCb get_confirmation_key_response_cb; /**< Response of get_confirmation_key request */
LinphoneAccountCreatorCbsStatusCb link_account_response_cb; /**< Response of link_account request */
LinphoneAccountCreatorCbsStatusCb activate_alias_response_cb; /**< Response of activation alias */
......@@ -96,8 +100,14 @@ struct _LinphoneAccountCreator {
char *language; /**< User language */
char *activation_code; /**< Account validation code */
char *domain; /**< Domain */
char *algorithm; /**< Digest authentication algorithm */
LinphoneTransportType transport; /**< Transport used */
// test
bool_t account_created;
bool_t confirmation_key_received;
bool_t account_activated;
/* Deprecated */
char *route;
};
......
......@@ -93,8 +93,8 @@ static void call_received(SalCallOp *h) {
linphone_address_unref(toAddr);
linphone_address_unref(fromAddr);
if (sal_address_has_param(h->getRemoteContactAddress(), "text")) {
const char *oneToOneChatRoomStr = sal_custom_header_find(h->getRecvCustomHeaders(), "One-To-One-Chat-Room");
if (oneToOneChatRoomStr && (strcmp(oneToOneChatRoomStr, "true") == 0)) {
string oneToOneChatRoom = L_C_TO_STRING(sal_custom_header_find(h->getRecvCustomHeaders(), "One-To-One-Chat-Room"));
if (oneToOneChatRoom == "true") {
bool_t oneToOneChatRoomEnabled = linphone_config_get_bool(linphone_core_get_config(lc), "misc", "enable_one_to_one_chat_room", TRUE);
if (!oneToOneChatRoomEnabled) {
h->decline(SalReasonNotAcceptable);
......@@ -147,10 +147,13 @@ static void call_received(SalCallOp *h) {
chatRoom->deleteFromDb();
chatRoom.reset();
}
if (!chatRoom)
if (!chatRoom) {
string endToEndEncrypted = L_C_TO_STRING(sal_custom_header_find(h->getRecvCustomHeaders(), "End-To-End-Encrypted"));
bool encrypted = (endToEndEncrypted == "true");
chatRoom = L_GET_PRIVATE_FROM_C_OBJECT(lc)->createClientGroupChatRoom(
h->getSubject(), h->getRemoteContact(), h->getRemoteBody(), false
h->getSubject(), h->getRemoteContact(), h->getRemoteBody(), false, encrypted
);
}
const char *oneToOneChatRoomStr = sal_custom_header_find(h->getRecvCustomHeaders(), "One-To-One-Chat-Room");
if (oneToOneChatRoomStr && (strcmp(oneToOneChatRoomStr, "true") == 0))
......@@ -853,7 +856,7 @@ static void refer_received(SalOp *op, const SalAddress *refer_to){
ConferenceId(addr, IdentityAddress(op->getTo()))
);
if (!chatRoom)
chatRoom = L_GET_PRIVATE_FROM_C_OBJECT(lc)->createClientGroupChatRoom("", addr.asString(), Content(), false);
chatRoom = L_GET_PRIVATE_FROM_C_OBJECT(lc)->createClientGroupChatRoom("", addr.asString(), Content(), false, false);
chatRoom->join();
static_cast<SalReferOp *>(op)->reply(SalReasonNone);
return;
......
......@@ -99,6 +99,10 @@ LinphoneChatRoom *linphone_core_create_client_group_chat_room (LinphoneCore *lc,
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_client_group_chat_room_2 (LinphoneCore *lc, const char *subject, bool_t fallback, bool_t encrypted) {
return L_GET_C_BACK_PTR(L_GET_CPP_PTR_FROM_C_OBJECT(lc)->createClientGroupChatRoom(L_C_TO_STRING(subject), !!fallback, !!encrypted));
}
LinphoneChatRoom *_linphone_core_create_server_group_chat_room (LinphoneCore *lc, LinphonePrivate::SalCallOp *op) {
return _linphone_server_group_chat_room_new(lc, op);
}
......@@ -129,8 +133,22 @@ LinphoneChatRoom *linphone_core_find_one_to_one_chat_room (
) {
return L_GET_C_BACK_PTR(L_GET_CPP_PTR_FROM_C_OBJECT(lc)->findOneToOneChatRoom(
LinphonePrivate::IdentityAddress(*L_GET_CPP_PTR_FROM_C_OBJECT(local_addr)),
LinphonePrivate::IdentityAddress(*L_GET_CPP_PTR_FROM_C_OBJECT(participant_addr))
));
LinphonePrivate::IdentityAddress(*L_GET_CPP_PTR_FROM_C_OBJECT(participant_addr)),
false)
);
}
LinphoneChatRoom *linphone_core_find_one_to_one_chat_room_2 (
const LinphoneCore *lc,
const LinphoneAddress *local_addr,
const LinphoneAddress *participant_addr,
bool_t encrypted
) {
return L_GET_C_BACK_PTR(L_GET_CPP_PTR_FROM_C_OBJECT(lc)->findOneToOneChatRoom(
LinphonePrivate::IdentityAddress(*L_GET_CPP_PTR_FROM_C_OBJECT(local_addr)),
LinphonePrivate::IdentityAddress(*L_GET_CPP_PTR_FROM_C_OBJECT(participant_addr)),
!!encrypted)
);
}
int linphone_core_message_received(LinphoneCore *lc, LinphonePrivate::SalOp *op, const SalMessage *sal_msg) {
......
......@@ -866,7 +866,12 @@ LinphoneFriend * linphone_core_create_friend_with_address(LinphoneCore *lc, cons
#endif
void linphone_core_add_friend(LinphoneCore *lc, LinphoneFriend *lf) {
if (linphone_friend_list_add_friend(linphone_core_get_default_friend_list(lc), lf) != LinphoneFriendListOK) return;
LinphoneFriendList *friendList = linphone_core_get_default_friend_list(lc);
if (!friendList) {
friendList = linphone_core_create_friend_list(lc);
linphone_core_add_friend_list(lc, friendList);
}
if (linphone_friend_list_add_friend(friendList, lf) != LinphoneFriendListOK) return;
if (bctbx_list_find(lc->subscribers, lf)) {
/*if this friend was in the pending subscriber list, now remove it from this list*/
lc->subscribers = bctbx_list_remove(lc->subscribers, lf);
......
......@@ -218,6 +218,7 @@ static void linphone_friend_list_parse_multipart_related_body(LinphoneFriendList
LinphoneFriend *lf;
LinphoneContent *presence_part;
xmlXPathObjectPtr resource_object;
xmlXPathObjectPtr name_object;
char *version_str = NULL;
char *full_state_str = NULL;
char *uri = NULL;
......@@ -261,6 +262,35 @@ static void linphone_friend_list_parse_multipart_related_body(LinphoneFriendList
}
list->expected_notification_version = version + 1;
name_object = linphone_get_xml_xpath_object_for_node_list(xml_ctx, "/rlmi:list/rlmi:resource/rlmi:name/..");
if (name_object && name_object->nodesetval) {
for (i = 1; i <= name_object->nodesetval->nodeNr; i++) {
char *name = NULL;
LinphoneAddress* addr;
linphone_xml_xpath_context_set_node(xml_ctx, xmlXPathNodeSetItem(name_object->nodesetval, i-1));
name = linphone_get_xml_text_content(xml_ctx, "./rlmi:name");
uri = linphone_get_xml_text_content(xml_ctx, "./@uri");
if (!uri)
continue;
addr = linphone_address_new(uri);
if (!addr)
continue;
lf = linphone_friend_list_find_friend_by_address(list, addr);
linphone_address_unref(addr);
if (!lf && list->bodyless_subscription) {
lf = linphone_core_create_friend_with_address(list->lc, uri);
linphone_friend_list_add_friend(list, lf);
linphone_friend_unref(lf);
}
if (name) {
linphone_friend_set_name(lf, name);
linphone_free_xml_text_content(name);
}
}
}
if (name_object)
xmlXPathFreeObject(name_object);
resource_object = linphone_get_xml_xpath_object_for_node_list(xml_ctx, "/rlmi:list/rlmi:resource/rlmi:instance[@state=\"active\"]/..");
if (resource_object && resource_object->nodesetval) {
for (i = 1; i <= resource_object->nodesetval->nodeNr; i++) {
......
......@@ -117,11 +117,11 @@ void linphone_im_encryption_engine_cbs_set_process_outgoing_message(LinphoneImEn
}
LinphoneImEncryptionEngineCbsDownloadingFileCb linphone_im_encryption_engine_cbs_get_process_downloading_file(LinphoneImEncryptionEngineCbs *cbs) {
return cbs->process_downlading_file;
return cbs->process_downloading_file;
}
void linphone_im_encryption_engine_cbs_set_process_downloading_file(LinphoneImEncryptionEngineCbs *cbs, LinphoneImEncryptionEngineCbsDownloadingFileCb cb) {
cbs->process_downlading_file = cb;
cbs->process_downloading_file = cb;
}
LinphoneImEncryptionEngineCbsUploadingFileCb linphone_im_encryption_engine_cbs_get_process_uploading_file(LinphoneImEncryptionEngineCbs *cbs) {
......
......@@ -19,6 +19,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "linphone/api/c-content.h"
#include "bctoolbox/crypto.h"
#include "lime.h"
#ifdef HAVE_CONFIG_H
#include "config.h"
......@@ -26,7 +27,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#ifdef HAVE_LIME
#include "private.h"
#include "bctoolbox/crypto.h"
#include "bctoolbox/port.h"
#include "bzrtp/bzrtp.h"
......@@ -399,53 +399,6 @@ int lime_encryptMessage(limeKey_t *key, const uint8_t *plainMessage, uint32_t me
return 0;
}
int lime_encryptFile(void **cryptoContext, unsigned char *key, size_t length, char *plain, char *cipher) {
bctbx_aes_gcm_context_t *gcmContext;
if (key == NULL) return -1;
if (*cryptoContext == NULL) { /* first call to the function, allocate a crypto context and initialise it */
/* key contains 192bits of key || 64 bits of Initialisation Vector, no additional data */
gcmContext = bctbx_aes_gcm_context_new(key, 24, NULL, 0, key+24, 8, BCTBX_GCM_ENCRYPT);
*cryptoContext = gcmContext;
} else { /* this is not the first call, get the context */
gcmContext = (bctbx_aes_gcm_context_t *)*cryptoContext;
}
if (length != 0) {
bctbx_aes_gcm_process_chunk(gcmContext, (const uint8_t *)plain, length, (uint8_t *)cipher);
} else { /* lenght is 0, finish the stream, no tag to be generated */
bctbx_aes_gcm_finish(gcmContext, NULL, 0);
*cryptoContext = NULL;
}
return 0;
}
int lime_decryptFile(void **cryptoContext, unsigned char *key, size_t length, char *plain, char *cipher) {
bctbx_aes_gcm_context_t *gcmContext;
if (key == NULL) return -1;
if (*cryptoContext == NULL) { /* first call to the function, allocate a crypto context and initialise it */
/* key contains 192bits of key || 64 bits of Initialisation Vector, no additional data */
gcmContext = bctbx_aes_gcm_context_new(key, 24, NULL, 0, key+24, 8, BCTBX_GCM_DECRYPT);
*cryptoContext = gcmContext;
} else { /* this is not the first call, get the context */
gcmContext = (bctbx_aes_gcm_context_t *)*cryptoContext;
}
if (length != 0) {
bctbx_aes_gcm_process_chunk(gcmContext, (const unsigned char *)cipher, length, (unsigned char *)plain);
} else { /* lenght is 0, finish the stream */
bctbx_aes_gcm_finish(gcmContext, NULL, 0);
*cryptoContext = NULL;
}
return 0;
}
int lime_decryptMessage(limeKey_t *key, uint8_t *encryptedMessage, uint32_t messageLength, uint8_t selfZID[12], uint8_t *plainMessage) {
uint8_t authenticatedData[28];
int retval;
......@@ -947,9 +900,9 @@ int lime_im_encryption_engine_process_downloading_file_cb(LinphoneImEncryptionEn
return -1;
if (!buffer || size == 0)
return lime_decryptFile(linphone_content_get_cryptoContext_address(content), NULL, 0, NULL, NULL);
return bctbx_aes_gcm_decryptFile(linphone_content_get_cryptoContext_address(content), NULL, 0, NULL, NULL);
return lime_decryptFile(
return bctbx_aes_gcm_decryptFile(
linphone_content_get_cryptoContext_address(content),
(unsigned char *)linphone_content_get_key(content),
size,
......@@ -968,7 +921,7 @@ int lime_im_encryption_engine_process_uploading_file_cb(LinphoneImEncryptionEngi
return -1;
if (!buffer || *size == 0)
return lime_encryptFile(linphone_content_get_cryptoContext_address(content), NULL, 0, NULL, NULL);
return bctbx_aes_gcm_encryptFile(linphone_content_get_cryptoContext_address(content), NULL, 0, NULL, NULL);
size_t file_size = linphone_content_get_file_size(content);
if (file_size == 0) {
......@@ -977,7 +930,7 @@ int lime_im_encryption_engine_process_uploading_file_cb(LinphoneImEncryptionEngi
*size -= (*size % 16);
}
return lime_encryptFile(
return bctbx_aes_gcm_encryptFile(
linphone_content_get_cryptoContext_address(content),
(unsigned char *)linphone_content_get_key(content),
*size,
......@@ -1004,10 +957,8 @@ void lime_im_encryption_engine_generate_file_transfer_key_cb(LinphoneImEncryptio
#else /* HAVE_LIME */
bool_t lime_is_available() { return FALSE; }
int lime_decryptFile(void **cryptoContext, unsigned char *key, size_t length, char *plain, char *cipher) { return LIME_NOT_ENABLED;}
int lime_decryptMultipartMessage(void *cachedb, uint8_t *message, const char *selfURI, const char *peerURI, uint8_t **output, char **content_type, uint64_t validityTimeSpan) { return LIME_NOT_ENABLED;}
int lime_createMultipartMessage(void *cachedb, const char *contentType, uint8_t *message, const char *selfURI, const char *peerURI, uint8_t **output) { return LIME_NOT_ENABLED;}
int lime_encryptFile(void **cryptoContext, unsigned char *key, size_t length, char *plain, char *cipher) {return LIME_NOT_ENABLED;}
void lime_freeKeys(limeURIKeys_t *associatedKeys){
}
int lime_getCachedSndKeysByURI(void *cachedb, limeURIKeys_t *associatedKeys){
......@@ -1046,6 +997,7 @@ bool_t lime_im_encryption_engine_is_file_encryption_enabled_cb(LinphoneImEncrypt
void lime_im_encryption_engine_generate_file_transfer_key_cb(LinphoneImEncryptionEngine *engine, LinphoneChatRoom *room, LinphoneChatMessage *msg) {
}
#endif /* HAVE_LIME */
const char *lime_error_code_to_string(int errorCode) {
......
......@@ -126,34 +126,6 @@ LINPHONE_PUBLIC void lime_freeKeys(limeURIKeys_t *associatedKeys);
*/
LINPHONE_PUBLIC int lime_encryptMessage(limeKey_t *key, const uint8_t *plainMessage, uint32_t messageLength, uint8_t selfZID[12], uint8_t *encryptedMessage);
/**
* @brief Encrypt a file before transfering it to the server, encryption is done in several call, first one will be done with cryptoContext null, last one with length = 0
*
* @param[in,out] cryptoContext The context used to encrypt the file using AES-GCM. Is created at first call(if null)
* @param[in] key 256 bits : 192 bits of key || 64 bits of Initial Vector
* @param[in] length Length of data to be encrypted, if 0 it will conclude the encryption
* @param[in] plain Plain data to be encrypted (length bytes)
* @param[out] cipher Output to a buffer allocated by caller, at least length bytes available
*
* @return 0 on success, error code otherwise
*
*/
LINPHONE_PUBLIC int lime_encryptFile(void **cryptoContext, unsigned char *key, size_t length, char *plain, char *cipher);
/**
* @brief Decrypt a file retrieved from server, decryption is done in several call, first one will be done with cryptoContext null, last one with length = 0
*
* @param[in,out] cryptoContext The context used to decrypt the file using AES-GCM. Is created at first call(if null)
* @param[in] key 256 bits : 192 bits of key || 64 bits of Initial Vector
* @param[in] length Length of data to be decrypted, if 0 it will conclude the decryption
* @param[out] plain Output to a buffer allocated by caller, at least length bytes available
* @param[in] cipher Cipher text to be decrypted(length bytes)
*
* @return 0 on success, error code otherwise
*
*/
LINPHONE_PUBLIC int lime_decryptFile(void **cryptoContext, unsigned char *key, size_t length, char *plain, char *cipher);
/**
* @brief decrypt and authentify a message with the given key
*
......
......@@ -1205,6 +1205,9 @@ static void sound_config_read(LinphoneCore *lc) {
devid=lp_config_get_string(lc->config,"sound","capture_dev_id",NULL);
linphone_core_set_capture_device(lc,devid);
devid=lp_config_get_string(lc->config,"sound","media_dev_id",NULL);
linphone_core_set_media_device(lc,devid);
/*
tmp=lp_config_get_int(lc->config,"sound","play_lev",80);
linphone_core_set_play_level(lc,tmp);
......@@ -1324,37 +1327,33 @@ static void certificates_config_read(LinphoneCore *lc) {
}
static void bodyless_config_read(LinphoneCore *lc) {
const char *lists = lp_config_get_string(lc->config, "sip", "bodyless_lists", NULL);
if (!lists)
return;
// Clean previous friend lists
linphone_core_clear_bodyless_friend_lists(lc);
char tmp[256] = {0};
char name[256];
char *p, *n;
strncpy(tmp, lists, sizeof(tmp)-1);
for(p = tmp; *p != '\0'; p++) {
if (*p==' ')
continue;
n = strchr(p,',');
if (n)
*n = '\0';
sscanf(p, "%s", name);
bctbx_list_t *bodyless_lists = linphone_config_get_string_list(lc->config, "sip", "bodyless_lists", NULL);
while (bodyless_lists) {
char *name = (char *)bctbx_list_get_data(bodyless_lists);
bodyless_lists = bctbx_list_next(bodyless_lists);
LinphoneAddress *addr = linphone_address_new(name);
if(!addr)
if(!addr) {
bctbx_free(name);
continue;
}
ms_message("Found bodyless friendlist %s", name);
bctbx_free(name);
LinphoneFriendList *friendList = linphone_core_create_friend_list(lc);
linphone_friend_list_set_rls_uri(friendList, name);
linphone_friend_list_set_display_name(friendList, linphone_address_get_username(addr));
linphone_friend_list_set_rls_address(friendList, addr);
linphone_friend_list_set_display_name(
friendList,
linphone_address_get_display_name(addr)
? linphone_address_get_display_name(addr)
: linphone_address_get_username(addr)
);
linphone_address_unref(addr);
linphone_friend_list_set_subscription_bodyless(friendList, TRUE);
linphone_core_add_friend_list(lc, friendList);
if (!n)
break;
p = n;
linphone_friend_list_unref(friendList);
}
}
......@@ -1433,6 +1432,8 @@ static void sip_config_read(LinphoneCore *lc) {
tmp=lp_config_get_int(lc->config,"sip","delayed_timeout",4);
linphone_core_set_delayed_timeout(lc,tmp);
tmp=lp_config_get_int(lc->config,"app","auto_download_incoming_files_max_size",-1);
linphone_core_set_max_size_for_auto_download_incoming_files(lc, tmp);
/*In case of remote provisionning, function sip_config_read is initialy called in core_init, then in state ConfiguringSuccessfull*/
/*Accordingly, to avoid proxy_config to be added twice, it is mandatory to reset proxy config list from LinphoneCore*/
......@@ -2285,7 +2286,9 @@ static void _linphone_core_init_account_creator_service(LinphoneCore *lc) {
service->account_creator_service_constructor_cb = linphone_account_creator_constructor_linphone;
service->account_creator_service_destructor_cb = NULL;
service->create_account_request_cb = linphone_account_creator_create_account_linphone;
service->delete_account_request_cb = linphone_account_creator_delete_account_linphone;
service->is_account_exist_request_cb = linphone_account_creator_is_account_exist_linphone;
service->get_confirmation_key_request_cb = linphone_account_creator_get_confirmation_key_linphone;
service->activate_account_request_cb = linphone_account_creator_activate_account_linphone;
service->is_account_activated_request_cb = linphone_account_creator_is_account_activated_linphone;
service->link_account_request_cb = linphone_account_creator_link_phone_number_with_account_linphone;
......@@ -2763,6 +2766,16 @@ void linphone_core_remove_friend_list(LinphoneCore *lc, LinphoneFriendList *list
lc->friends_lists = bctbx_list_erase_link(lc->friends_lists, elem);
}
void linphone_core_clear_bodyless_friend_lists(LinphoneCore *lc) {
bctbx_list_t *copy = bctbx_list_copy(linphone_core_get_friends_lists((const LinphoneCore *)lc));
for (auto it = copy; it; it = bctbx_list_next(it)) {
LinphoneFriendList *friends = (LinphoneFriendList *)bctbx_list_get_data(copy);
if (linphone_friend_list_is_subscription_bodyless(friends))
linphone_core_remove_friend_list(lc, (LinphoneFriendList *)bctbx_list_get_data(copy));
}
bctbx_list_free(copy);
}
void linphone_core_add_friend_list(LinphoneCore *lc, LinphoneFriendList *list) {
if (!list->lc) {
list->lc = lc;
......@@ -3957,6 +3970,15 @@ void linphone_core_set_delayed_timeout(LinphoneCore *lc, int seconds){
lc->sip_conf.delayed_timeout=seconds;
}
int linphone_core_get_max_size_for_auto_download_incoming_files(LinphoneCore *lc) {
return lc->auto_download_incoming_files_max_size;
}
void linphone_core_set_max_size_for_auto_download_incoming_files(LinphoneCore *lc, int size) {
lc->auto_download_incoming_files_max_size = size;
lp_config_set_int(lc->config, "app", "auto_download_incoming_files_max_size", size);
}
void linphone_core_set_presence_info(LinphoneCore *lc, int minutes_away, const char *contact, LinphoneOnlineStatus os) {
LinphonePresenceModel *presence = NULL;
LinphonePresenceActivity *activity = NULL;
......@@ -4160,6 +4182,10 @@ int linphone_core_get_rec_level(LinphoneCore *lc) {
return lc->sound_conf.rec_lev;
}
int linphone_core_get_media_level(LinphoneCore *lc) {
return lc->sound_conf.media_lev;
}
void linphone_core_set_ring_level(LinphoneCore *lc, int level){
MSSndCard *sndcard;
lc->sound_conf.ring_lev = (char)level;
......@@ -4224,6 +4250,13 @@ void linphone_core_set_rec_level(LinphoneCore *lc, int level) {
if (sndcard) ms_snd_card_set_level(sndcard,MS_SND_CARD_CAPTURE,level);
}
void linphone_core_set_media_level(LinphoneCore *lc, int level) {
MSSndCard *sndcard;
lc->sound_conf.media_lev = (char)level;
sndcard=lc->sound_conf.media_sndcard;
if (sndcard) ms_snd_card_set_level(sndcard,MS_SND_CARD_PLAYBACK,level);
}
static MSSndCard *get_card_from_string_id(const char *devid, unsigned int cap, MSFactory *f){
MSSndCard *sndcard=NULL;
if (devid!=NULL){
......@@ -4286,6 +4319,14 @@ LinphoneStatus linphone_core_set_capture_device(LinphoneCore *lc, const char * d
return 0;
}
LinphoneStatus linphone_core_set_media_device(LinphoneCore *lc, const char * devid){
MSSndCard *card=get_card_from_string_id(devid,MS_SND_CARD_CAP_PLAYBACK, lc->factory);
lc->sound_conf.media_sndcard=card;
if (card && linphone_core_ready(lc))
lp_config_set_string(lc->config,"sound","media_dev_id",ms_snd_card_get_string_id(card));
return 0;
}
const char * linphone_core_get_ringer_device(LinphoneCore *lc) {
if (lc->sound_conf.ring_sndcard) return ms_snd_card_get_string_id(lc->sound_conf.ring_sndcard);
return NULL;
......@@ -4299,6 +4340,10 @@ const char * linphone_core_get_capture_device(LinphoneCore *lc) {
return lc->sound_conf.capt_sndcard ? ms_snd_card_get_string_id(lc->sound_conf.capt_sndcard) : NULL;
}
const char * linphone_core_get_media_device(LinphoneCore *lc) {
return lc->sound_conf.media_sndcard ? ms_snd_card_get_string_id(lc->sound_conf.media_sndcard) : NULL;
}
const char** linphone_core_get_sound_devices(LinphoneCore *lc){
return lc->sound_conf.cards;
}
......@@ -6728,6 +6773,23 @@ void *linphone_core_get_zrtp_cache_db(LinphoneCore *lc){
#endif /* SQLITE_STORAGE_ENABLED */
}
LinphoneZrtpPeerStatus linphone_core_get_zrtp_status(LinphoneCore *lc, const char *peerUri) {
int status = MS_ZRTP_PEER_STATUS_UNKNOWN;
if (lc->zrtp_cache_db) {
status = ms_zrtp_get_peer_status(lc->zrtp_cache_db, peerUri, &(lc->zrtp_cache_db_mutex));
}
switch (status) {
case MS_ZRTP_PEER_STATUS_UNKNOWN:
return LinphoneZrtpPeerStatusUnknown;
case MS_ZRTP_PEER_STATUS_INVALID:
return LinphoneZrtpPeerStatusInvalid;
case MS_ZRTP_PEER_STATUS_VALID:
return LinphoneZrtpPeerStatusValid;
default:
return LinphoneZrtpPeerStatusUnknown;
}
}
static void linphone_core_zrtp_cache_close(LinphoneCore *lc) {
if (lc->zrtp_cache_db) {
sqlite3_close(lc->zrtp_cache_db);
......@@ -7352,17 +7414,6 @@ const char *linphone_core_get_tls_key_path(const LinphoneCore *lc) {
return tls_key_path;
}
void linphone_core_set_im_encryption_engine(LinphoneCore *lc, LinphoneImEncryptionEngine *imee) {
if (lc->im_encryption_engine) {
linphone_im_encryption_engine_unref(lc->im_encryption_engine);
lc->im_encryption_engine = NULL;
}
if (imee) {
imee->lc = lc;
lc->im_encryption_engine = linphone_im_encryption_engine_ref(imee);
}
}
LinphoneImEncryptionEngine *linphone_core_get_im_encryption_engine(const LinphoneCore *lc) {
return lc->im_encryption_engine;
}
......
......@@ -36,8 +36,14 @@ LinphonePlayer *linphone_core_create_local_player(LinphoneCore *lc, const char *
LinphonePlayer *obj = linphone_player_new(lc);
MSSndCard *snd_card;
MSSndCardManager *snd_card_manager = ms_factory_get_snd_card_manager(lc->factory);
#ifdef __ANDROID__
if (sound_card_name == NULL) sound_card_name = linphone_core_get_media_device(lc);
snd_card = ms_snd_card_manager_get_card(snd_card_manager, sound_card_name);
ms_snd_card_set_stream_type(snd_card, MS_SND_CARD_STREAM_MEDIA);
#else
if (sound_card_name == NULL) sound_card_name = linphone_core_get_ringer_device(lc);
snd_card = ms_snd_card_manager_get_card(snd_card_manager, sound_card_name);
#endif
if (video_display_name == NULL) video_display_name = linphone_core_get_video_display_filter(lc);
obj->impl = ms_media_player_new(lc->factory, snd_card, video_display_name, window_id);
obj->open = _local_player_open;
......
......@@ -150,6 +150,11 @@ const LinphoneAddress *_linphone_proxy_config_get_contact_without_params (const
void linphone_friend_list_invalidate_subscriptions(LinphoneFriendList *list);
void linphone_friend_list_notify_presence_received(LinphoneFriendList *list, LinphoneEvent *lev, const LinphoneContent *body);
void linphone_friend_list_subscription_state_changed(LinphoneCore *lc, LinphoneEvent *lev, LinphoneSubscriptionState state);
/**
* Removes all bodyless friend lists.
* @param[in] lc #LinphoneCore object
*/
void linphone_core_clear_bodyless_friend_lists(LinphoneCore *lc);
void _linphone_friend_list_release(LinphoneFriendList *list);
/*get rls either from list or core if any*/
const LinphoneAddress * _linphone_friend_list_get_rls_address(const LinphoneFriendList *list);
......@@ -307,6 +312,7 @@ void _linphone_chat_room_notify_participant_device_added(LinphoneChatRoom *cr, c
void _linphone_chat_room_notify_participant_device_removed(LinphoneChatRoom *cr, const LinphoneEventLog *event_log);
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_security_event(LinphoneChatRoom *cr, const LinphoneEventLog *event_log);
void _linphone_chat_room_notify_subject_changed(LinphoneChatRoom *cr, const LinphoneEventLog *event_log);
void _linphone_chat_room_notify_conference_joined(LinphoneChatRoom *cr, const LinphoneEventLog *event_log);
void _linphone_chat_room_notify_conference_left(LinphoneChatRoom *cr, const LinphoneEventLog *event_log);
......