Commit b297a4cb authored by Ghislain MARY's avatar Ghislain MARY

Rework chat handling.

 - Add content type information in LIME encrypted message
 - Single entry point for all types of chat messages that are first decrypted if necessary and then handled according to their content type
 - Add possibility to send chat messages with a content type that is not 'text/plain'
 - Encrypt IMDN
parent 1c7fc21b
......@@ -591,12 +591,8 @@ void sal_set_callbacks(Sal *ctx, const SalCallbacks *cbs){
ctx->callbacks.notify_presence=(SalOnNotifyPresence)unimplemented_stub;
if (ctx->callbacks.subscribe_presence_received==NULL)
ctx->callbacks.subscribe_presence_received=(SalOnSubscribePresenceReceived)unimplemented_stub;
if (ctx->callbacks.text_received==NULL)
ctx->callbacks.text_received=(SalOnTextReceived)unimplemented_stub;
if (ctx->callbacks.is_composing_received==NULL)
ctx->callbacks.is_composing_received=(SalOnIsComposingReceived)unimplemented_stub;
if (ctx->callbacks.imdn_received == NULL)
ctx->callbacks.imdn_received = (SalOnImdnReceived)unimplemented_stub;
if (ctx->callbacks.message_received==NULL)
ctx->callbacks.message_received=(SalOnMessageReceived)unimplemented_stub;
if (ctx->callbacks.ping_reply==NULL)
ctx->callbacks.ping_reply=(SalOnPingReply)unimplemented_stub;
if (ctx->callbacks.auth_requested==NULL)
......@@ -618,6 +614,7 @@ void sal_uninit(Sal* sal){
belle_sip_object_unref(sal->listener);
if (sal->supported) belle_sip_object_unref(sal->supported);
bctbx_list_free_with_data(sal->supported_tags,ms_free);
bctbx_list_free_with_data(sal->supported_content_types, ms_free);
if (sal->uuid) ms_free(sal->uuid);
if (sal->root_ca) ms_free(sal->root_ca);
if (sal->root_ca_data) ms_free(sal->root_ca_data);
......@@ -1500,4 +1497,17 @@ void *sal_get_stack_impl(Sal *sal) {
return sal->stack;
}
bool_t sal_is_content_type_supported(const Sal *sal, const char *content_type) {
bctbx_list_t *item;
for (item = sal->supported_content_types; item != NULL; item = bctbx_list_next(item)) {
const char *item_content_type = (const char *)bctbx_list_get_data(item);
if (strcmp(item_content_type, content_type) == 0) return TRUE;
}
return FALSE;
}
void sal_add_content_type_support(Sal *sal, const char *content_type) {
if ((content_type != NULL) && (sal_is_content_type_supported(sal, content_type) == FALSE)) {
sal->supported_content_types = bctbx_list_append(sal->supported_content_types, ms_strdup(content_type));
}
}
......@@ -55,6 +55,7 @@ struct Sal{
SalOpSDPHandling default_sdp_handling;
bool_t pending_trans_checking; /*testing purpose*/
void *ssl_config;
bctbx_list_t *supported_content_types; /* list of char* */
};
typedef enum SalOpState {
......@@ -178,4 +179,5 @@ void _sal_op_add_custom_headers(SalOp *op, belle_sip_message_t *msg);
SalSubscribeStatus belle_sip_message_get_subscription_state(const belle_sip_message_t *msg);
#endif /* SAL_IMPL_H_ */
......@@ -24,7 +24,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
static void process_error( SalOp* op) {
if (op->dir == SalOpDirOutgoing) {
op->base.root->callbacks.text_delivery_update(op, SalTextDeliveryFailed);
op->base.root->callbacks.message_delivery_update(op, SalMessageDeliveryFailed);
} else {
ms_warning("unexpected io error for incoming message on op [%p]",op);
}
......@@ -46,35 +46,39 @@ static void process_timeout(void *user_ctx, const belle_sip_timeout_event_t *eve
static void process_response_event(void *op_base, const belle_sip_response_event_t *event){
SalOp* op = (SalOp*)op_base;
int code = belle_sip_response_get_status_code(belle_sip_response_event_get_response(event));
SalTextDeliveryStatus status;
SalMessageDeliveryStatus status;
sal_op_set_error_info_from_response(op,belle_sip_response_event_get_response(event));
if (code>=100 && code <200)
status=SalTextDeliveryInProgress;
status=SalMessageDeliveryInProgress;
else if (code>=200 && code <300)
status=SalTextDeliveryDone;
status=SalMessageDeliveryDone;
else
status=SalTextDeliveryFailed;
status=SalMessageDeliveryFailed;
op->base.root->callbacks.text_delivery_update(op,status);
op->base.root->callbacks.message_delivery_update(op,status);
}
static bool_t is_external_body(belle_sip_header_content_type_t* content_type) {
return strcmp("message",belle_sip_header_content_type_get_type(content_type))==0
&& strcmp("external-body",belle_sip_header_content_type_get_subtype(content_type))==0;
}
static bool_t is_im_iscomposing(belle_sip_header_content_type_t* content_type) {
return strcmp("application",belle_sip_header_content_type_get_type(content_type))==0
&& strcmp("im-iscomposing+xml",belle_sip_header_content_type_get_subtype(content_type))==0;
}
static bool_t is_imdn_xml(belle_sip_header_content_type_t *content_type) {
return (strcmp("message", belle_sip_header_content_type_get_type(content_type)) == 0)
&& (strcmp("imdn+xml", belle_sip_header_content_type_get_subtype(content_type)) == 0);
}
static void add_message_accept(SalOp *op, belle_sip_message_t *msg) {
bctbx_list_t *item;
const char *str;
char *old;
char *header = ms_strdup("xml/cipher, application/cipher.vnd.gsma.rcs-ft-http+xml");
for (item = op->base.root->supported_content_types; item != NULL; item = bctbx_list_next(item)) {
str = (const char *)bctbx_list_get_data(item);
old = header;
header = ms_strdup_printf("%s, %s", old, str);
ms_free(old);
}
static void add_message_accept(belle_sip_message_t *msg){
belle_sip_message_add_header(msg,belle_sip_header_create("Accept","text/plain, message/external-body, application/im-iscomposing+xml, xml/cipher, application/vnd.gsma.rcs-ft-http+xml, application/cipher.vnd.gsma.rcs-ft-http+xml, message/imdn+xml"));
belle_sip_message_add_header(msg, belle_sip_header_create("Accept", header));
ms_free(header);
}
void sal_process_incoming_message(SalOp *op,const belle_sip_request_event_t *event){
......@@ -95,72 +99,45 @@ void sal_process_incoming_message(SalOp *op,const belle_sip_request_event_t *eve
content_type=belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req),belle_sip_header_content_type_t);
if (content_type) {
SalMessage salmsg;
char message_id[256]={0};
if (op->pending_server_trans) belle_sip_object_unref(op->pending_server_trans);
op->pending_server_trans=server_transaction;
belle_sip_object_ref(op->pending_server_trans);
if (is_im_iscomposing(content_type)) {
SalIsComposing saliscomposing;
address=belle_sip_header_address_create(belle_sip_header_address_get_displayname(BELLE_SIP_HEADER_ADDRESS(from_header))
,belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(from_header)));
from=belle_sip_object_to_string(BELLE_SIP_OBJECT(address));
saliscomposing.from=from;
saliscomposing.text=belle_sip_message_get_body(BELLE_SIP_MESSAGE(req));
op->base.root->callbacks.is_composing_received(op,&saliscomposing);
belle_sip_object_unref(address);
belle_sip_free(from);
} else if (is_imdn_xml(content_type)) {
SalImdn salimdn;
address = belle_sip_header_address_create(belle_sip_header_address_get_displayname(BELLE_SIP_HEADER_ADDRESS(from_header)),
belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(from_header)));
from = belle_sip_object_to_string(BELLE_SIP_OBJECT(address));
salimdn.from = from;
salimdn.content = belle_sip_message_get_body(BELLE_SIP_MESSAGE(req));
op->base.root->callbacks.imdn_received(op, &salimdn);
belle_sip_object_unref(address);
belle_sip_free(from);
} else {
SalMessage salmsg;
char message_id[256]={0};
external_body=is_external_body(content_type);
address=belle_sip_header_address_create(belle_sip_header_address_get_displayname(BELLE_SIP_HEADER_ADDRESS(from_header))
,belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(from_header)));
from=belle_sip_object_to_string(BELLE_SIP_OBJECT(address));
snprintf(message_id,sizeof(message_id)-1,"%s%i"
,belle_sip_header_call_id_get_call_id(call_id)
,belle_sip_header_cseq_get_seq_number(cseq));
salmsg.from=from;
/* if we just deciphered a message, use the deciphered part(which can be a rcs xml body pointing to the file to retreive from server)*/
salmsg.text=(!external_body)?belle_sip_message_get_body(BELLE_SIP_MESSAGE(req)):NULL;
salmsg.url=NULL;
salmsg.content_type = ms_strdup_printf("%s/%s", belle_sip_header_content_type_get_type(content_type), belle_sip_header_content_type_get_subtype(content_type));
if (external_body && belle_sip_parameters_get_parameter(BELLE_SIP_PARAMETERS(content_type),"URL")) {
size_t url_length=strlen(belle_sip_parameters_get_parameter(BELLE_SIP_PARAMETERS(content_type),"URL"));
salmsg.url = ms_strdup(belle_sip_parameters_get_parameter(BELLE_SIP_PARAMETERS(content_type),"URL")+1); /* skip first "*/
((char*)salmsg.url)[url_length-2]='\0'; /*remove trailing "*/
}
salmsg.message_id=message_id;
salmsg.time=date ? belle_sip_header_date_get_time(date) : time(NULL);
op->base.root->callbacks.text_received(op,&salmsg);
belle_sip_object_unref(address);
belle_sip_free(from);
if (salmsg.url) ms_free((char*)salmsg.url);
ms_free((char *)salmsg.content_type);
external_body=is_external_body(content_type);
address=belle_sip_header_address_create(belle_sip_header_address_get_displayname(BELLE_SIP_HEADER_ADDRESS(from_header))
,belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(from_header)));
from=belle_sip_object_to_string(BELLE_SIP_OBJECT(address));
snprintf(message_id,sizeof(message_id)-1,"%s%i"
,belle_sip_header_call_id_get_call_id(call_id)
,belle_sip_header_cseq_get_seq_number(cseq));
salmsg.from=from;
/* if we just deciphered a message, use the deciphered part(which can be a rcs xml body pointing to the file to retreive from server)*/
salmsg.text=(!external_body)?belle_sip_message_get_body(BELLE_SIP_MESSAGE(req)):NULL;
salmsg.url=NULL;
salmsg.content_type = ms_strdup_printf("%s/%s", belle_sip_header_content_type_get_type(content_type), belle_sip_header_content_type_get_subtype(content_type));
if (external_body && belle_sip_parameters_get_parameter(BELLE_SIP_PARAMETERS(content_type),"URL")) {
size_t url_length=strlen(belle_sip_parameters_get_parameter(BELLE_SIP_PARAMETERS(content_type),"URL"));
salmsg.url = ms_strdup(belle_sip_parameters_get_parameter(BELLE_SIP_PARAMETERS(content_type),"URL")+1); /* skip first "*/
((char*)salmsg.url)[url_length-2]='\0'; /*remove trailing "*/
}
salmsg.message_id=message_id;
salmsg.time=date ? belle_sip_header_date_get_time(date) : time(NULL);
op->base.root->callbacks.message_received(op,&salmsg);
belle_sip_object_unref(address);
belle_sip_free(from);
if (salmsg.url) ms_free((char*)salmsg.url);
ms_free((char *)salmsg.content_type);
} else {
ms_error("Unsupported MESSAGE (no Content-Type)");
goto error;
resp = belle_sip_response_create_from_request(req, errcode);
add_message_accept(op, (belle_sip_message_t*)resp);
belle_sip_server_transaction_send_response(server_transaction,resp);
sal_op_release(op);
}
return;
error:
resp = belle_sip_response_create_from_request(req, errcode);
add_message_accept((belle_sip_message_t*)resp);
belle_sip_server_transaction_send_response(server_transaction,resp);
sal_op_release(op);
}
static void process_request_event(void *op_base, const belle_sip_request_event_t *event) {
......
......@@ -1169,7 +1169,7 @@ static bool_t is_duplicate_msg(LinphoneCore *lc, const char *msg_id){
}
static void text_received(SalOp *op, const SalMessage *msg){
static void message_received(SalOp *op, const SalMessage *msg){
LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op));
LinphoneCall *call=(LinphoneCall*)sal_op_get_user_pointer(op);
LinphoneReason reason = lc->chat_deny_code;
......@@ -1180,20 +1180,6 @@ static void text_received(SalOp *op, const SalMessage *msg){
if (!call) sal_op_release(op);
}
static void is_composing_received(SalOp *op, const SalIsComposing *is_composing) {
LinphoneCore *lc = (LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op));
LinphoneReason reason = linphone_core_is_composing_received(lc, op, is_composing);
sal_message_reply(op, linphone_reason_to_sal(reason));
sal_op_release(op);
}
static void imdn_received(SalOp *op, const SalImdn *imdn) {
LinphoneCore *lc = (LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op));
LinphoneReason reason = linphone_core_imdn_received(lc, op, imdn);
sal_message_reply(op, linphone_reason_to_sal(reason));
sal_op_release(op);
}
static void parse_presence_requested(SalOp *op, const char *content_type, const char *content_subtype, const char *body, SalPresenceModel **result) {
linphone_notify_parse_presence(content_type, content_subtype, body, result);
}
......@@ -1348,19 +1334,19 @@ static void notify_refer(SalOp *op, SalReferStatus status){
}
}
static LinphoneChatMessageState chatStatusSal2Linphone(SalTextDeliveryStatus status){
static LinphoneChatMessageState chatStatusSal2Linphone(SalMessageDeliveryStatus status){
switch(status){
case SalTextDeliveryInProgress:
case SalMessageDeliveryInProgress:
return LinphoneChatMessageStateInProgress;
case SalTextDeliveryDone:
case SalMessageDeliveryDone:
return LinphoneChatMessageStateDelivered;
case SalTextDeliveryFailed:
case SalMessageDeliveryFailed:
return LinphoneChatMessageStateNotDelivered;
}
return LinphoneChatMessageStateIdle;
}
static void text_delivery_update(SalOp *op, SalTextDeliveryStatus status){
static void message_delivery_update(SalOp *op, SalMessageDeliveryStatus status){
LinphoneChatMessage *chat_msg=(LinphoneChatMessage* )sal_op_get_user_pointer(op);
if (chat_msg == NULL) {
......@@ -1371,7 +1357,7 @@ static void text_delivery_update(SalOp *op, SalTextDeliveryStatus status){
if (chat_msg->chat_room != NULL) {
linphone_chat_message_update_state(chat_msg, chatStatusSal2Linphone(status));
}
if (status != SalTextDeliveryInProgress) { /*only release op if not in progress*/
if (status != SalMessageDeliveryInProgress) { /*only release op if not in progress*/
linphone_chat_message_destroy(chat_msg);
}
}
......@@ -1507,10 +1493,8 @@ SalCallbacks linphone_sal_callbacks={
vfu_request,
dtmf_received,
refer_received,
text_received,
text_delivery_update,
is_composing_received,
imdn_received,
message_received,
message_delivery_update,
notify_refer,
subscribe_received,
incoming_subscribe_closed,
......
This diff is collapsed.
This diff is collapsed.
......@@ -119,7 +119,7 @@ LINPHONE_PUBLIC void lime_freeKeys(limeURIKeys_t *associatedKeys);
* @return 0 on success, error code otherwise
*
*/
LINPHONE_PUBLIC int lime_encryptMessage(limeKey_t *key, uint8_t *plainMessage, uint32_t messageLength, uint8_t selfZID[12], uint8_t *encryptedMessage);
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
......@@ -170,13 +170,14 @@ LINPHONE_PUBLIC int lime_decryptMessage(limeKey_t *key, uint8_t *encryptedMessag
* Retrieve in cache the needed keys which are then updated. Output buffer is allocated and must be freed by caller
*
* @param[in,out] cacheBuffer The xmlDoc containing current cache, get the keys and selfZID from it, updated by this function with derivated keys
* @param[in] message The plain text message to be encrypted
* @param[in] content_type The content type of the message to encrypt
* @param[in] message The message content to be encrypted
* @param[in] peerURI The destination URI, associated keys will be found in cache
* @param[out] output The output buffer, allocated and set with the encrypted message xml body(null terminated string). Must be freed by caller
*
* @return 0 on success, error code otherwise
*/
LINPHONE_PUBLIC int lime_createMultipartMessage(xmlDocPtr cacheBuffer, uint8_t *message, uint8_t *peerURI, uint8_t **output);
LINPHONE_PUBLIC int lime_createMultipartMessage(xmlDocPtr cacheBuffer, const char *content_type, uint8_t *message, uint8_t *peerURI, uint8_t **output);
/**
* @brief decrypt a multipart xml message
......@@ -185,11 +186,11 @@ LINPHONE_PUBLIC int lime_createMultipartMessage(xmlDocPtr cacheBuffer, uint8_t *
* @param[in,out] cacheBuffer The xmlDoc containing current cache, get the key and selfZID from it, updated by this function with derivated keys
* @param[in] message The multipart message, contain one or several part identified by destination ZID, one shall match the self ZID retrieved from cache
* @param[out] output The output buffer, allocated and set with the decrypted message(null terminated string). Must be freed by caller
*
* @param[out] content_type The content type of the decrypted message
* @return 0 on success, error code otherwise
*/
LINPHONE_PUBLIC int lime_decryptMultipartMessage(xmlDocPtr cacheBuffer, uint8_t *message, uint8_t **output);
LINPHONE_PUBLIC int lime_decryptMultipartMessage(xmlDocPtr cacheBuffer, uint8_t *message, uint8_t **output, char **content_type);
/**
* @brief given a readable version of error code generated by Lime functions
......
......@@ -1997,9 +1997,10 @@ static void linphone_core_init(LinphoneCore * lc, LinphoneCoreCbs *cbs, LpConfig
#ifdef SQLITE_STORAGE_ENABLED
sqlite3_bctbx_vfs_register(0);
#endif
lc->vcard_context = linphone_vcard_context_new();
linphone_core_initialize_supported_content_types(lc);
remote_provisioning_uri = linphone_core_get_provisioning_uri(lc);
if (remote_provisioning_uri == NULL) {
linphone_configuring_terminated(lc, LinphoneConfiguringSkipped, NULL);
......@@ -7199,3 +7200,19 @@ void linphone_core_set_im_encryption_engine(LinphoneCore *lc, LinphoneImEncrypti
LinphoneImEncryptionEngine *linphone_core_get_im_encryption_engine(const LinphoneCore *lc) {
return lc->im_encryption_engine;
}
void linphone_core_initialize_supported_content_types(LinphoneCore *lc) {
sal_add_content_type_support(lc->sal, "text/plain");
sal_add_content_type_support(lc->sal, "message/external-body");
sal_add_content_type_support(lc->sal, "application/vnd.gsma.rcs-ft-http+xml");
sal_add_content_type_support(lc->sal, "application/im-iscomposing+xml");
sal_add_content_type_support(lc->sal, "message/imdn+xml");
}
bool_t linphone_core_is_content_type_supported(const LinphoneCore *lc, const char *content_type) {
return sal_is_content_type_supported(lc->sal, content_type);
}
void linphone_core_add_content_type_support(LinphoneCore *lc, const char *content_type) {
sal_add_content_type_support(lc->sal, content_type);
}
......@@ -203,16 +203,17 @@ static int callback_all(void *data, int argc, char **argv, char **colName){
* | 0 | storage_id
* | 1 | localContact
* | 2 | remoteContact
* | 3 | direction flag
* | 4 | message
* | 5 | time (unused now, used to be string-based timestamp)
* | 6 | read flag
* | 7 | status
* | 8 | external body url
* | 3 | direction flag (LinphoneChatMessageDir)
* | 4 | message (text content of the message)
* | 5 | time (unused now, used to be string-based timestamp, replaced by the utc timestamp)
* | 6 | read flag (no longer used, replaced by the LinphoneChatMessageStateDisplayed state)
* | 7 | status (LinphoneChatMessageState)
* | 8 | external body url (deprecated file transfer system)
* | 9 | utc timestamp
* | 10 | app data text
* | 11 | linphone content id
* | 12 | message id
* | 11 | linphone content id (LinphoneContent describing a file transfer)
* | 12 | message id (used for IMDN)
* | 13 | content type (of the message field [must be text representable])
*/
static int create_chat_message(void *data, int argc, char **argv, char **colName){
LinphoneChatRoom *cr = (LinphoneChatRoom *)data;
......@@ -245,6 +246,7 @@ static int create_chat_message(void *data, int argc, char **argv, char **colName
new_message->external_body_url= ms_strdup(argv[8]);
new_message->appdata = ms_strdup(argv[10]);
new_message->message_id = ms_strdup(argv[12]);
new_message->content_type = ms_strdup(argv[13]);
if (argv[11] != NULL) {
int id = atoi(argv[11]);
......@@ -253,6 +255,17 @@ static int create_chat_message(void *data, int argc, char **argv, char **colName
}
}
/* Fix content type for old messages that were stored without it */
if (new_message->content_type == NULL) {
if (new_message->file_transfer_information != NULL) {
new_message->content_type = ms_strdup("application/vnd.gsma.rcs-ft-http+xml");
} else if (new_message->external_body_url != NULL) {
new_message->content_type = ms_strdup("message/external-body");
} else {
new_message->content_type = ms_strdup("text/plain");
}
}
/* Add the new message to the weak messages list. */
linphone_chat_room_add_weak_message(cr, new_message);
}
......@@ -330,7 +343,7 @@ unsigned int linphone_chat_message_store(LinphoneChatMessage *msg){
peer=linphone_address_as_string_uri_only(linphone_chat_room_get_peer_address(msg->chat_room));
local_contact=linphone_address_as_string_uri_only(linphone_chat_message_get_local_address(msg));
buf = sqlite3_mprintf("INSERT INTO history VALUES(NULL,%Q,%Q,%i,%Q,%Q,%i,%i,%Q,%lld,%Q,%i,%Q);",
buf = sqlite3_mprintf("INSERT INTO history VALUES(NULL,%Q,%Q,%i,%Q,%Q,%i,%i,%Q,%lld,%Q,%i,%Q,%Q);",
local_contact,
peer,
msg->dir,
......@@ -342,7 +355,8 @@ unsigned int linphone_chat_message_store(LinphoneChatMessage *msg){
(int64_t)msg->time,
msg->appdata,
content_id,
msg->message_id
msg->message_id,
msg->content_type
);
linphone_sql_request(lc->db,buf);
sqlite3_free(buf);
......@@ -748,13 +762,21 @@ void linphone_update_table(sqlite3* db) {
if (ret != SQLITE_OK) {
ms_message("Table already up to date: %s", errmsg);
} else {
ms_message("Table history updated successfully for message_id data.");
ms_message("Table history updated successfully for messageId data.");
}
// Convert is_read to LinphoneChatMessageStateDisplayed
buf = sqlite3_mprintf("UPDATE history SET status=%i WHERE read=1 AND direction=%i;", LinphoneChatMessageStateDisplayed, LinphoneChatMessageIncoming);
linphone_sql_request(db, buf);
sqlite3_free(buf);
/* New field for content type */
ret = sqlite3_exec(db, "ALTER TABLE history ADD COLUMN content_type TEXT;", NULL, NULL, &errmsg);
if (ret != SQLITE_OK) {
ms_message("Table already up to date: %s", errmsg);
} else {
ms_message("Table history updated successfully for content_type data.");
}
}
void linphone_message_storage_init_chat_rooms(LinphoneCore *lc) {
......
......@@ -554,8 +554,6 @@ LinphoneProxyConfig *linphone_proxy_config_new_from_config_file(LinphoneCore *lc
void linphone_proxy_config_write_to_config_file(struct _LpConfig* config,LinphoneProxyConfig *obj, int index);
LinphoneReason linphone_core_message_received(LinphoneCore *lc, SalOp *op, const SalMessage *msg);
LinphoneReason linphone_core_is_composing_received(LinphoneCore *lc, SalOp *op, const SalIsComposing *is_composing);
LinphoneReason linphone_core_imdn_received(LinphoneCore *lc, SalOp *op, const SalImdn *imdn);
void linphone_core_real_time_text_received(LinphoneCore *lc, LinphoneChatRoom *cr, uint32_t character, LinphoneCall *call);
void linphone_call_init_stats(LinphoneCallStats *stats, int type);
......@@ -1093,9 +1091,7 @@ struct _LinphoneCore
char *tls_cert;
char *tls_key;
/*default resource list server*/
LinphoneAddress *default_rls_addr;
LinphoneAddress *default_rls_addr; /*default resource list server*/
LinphoneImEncryptionEngine *im_encryption_engine;
};
......@@ -1148,6 +1144,8 @@ bool_t linphone_core_is_payload_type_usable_for_bandwidth(LinphoneCore *lc, cons
#define linphone_core_ready(lc) ((lc)->state==LinphoneGlobalOn || (lc)->state==LinphoneGlobalShutdown)
void _linphone_core_configure_resolver(void);
void linphone_core_initialize_supported_content_types(LinphoneCore *lc);
struct _EcCalibrator{
MSFactory *factory;
ms_thread_t thread;
......
This diff is collapsed.
......@@ -3206,7 +3206,7 @@ LINPHONE_PUBLIC void linphone_core_set_root_ca_data(LinphoneCore *lc, const char
* Set the pointer to an externally provided ssl configuration for the crypto library
* @param lc #LinphoneCore object
* @param[in] ssl_config A pointer to an opaque structure which will be provided directly to the crypto library used in bctoolbox. Use with extra care.
* This ssl_config structure is responsability of the caller and will not be freed at the connection's end.
* This ssl_config structure is responsibility of the caller and will not be freed at the connection's end.
* @ingroup initializing
* @endinternal
*/
......@@ -3374,7 +3374,7 @@ LINPHONE_PUBLIC const bctbx_list_t * linphone_core_get_call_logs(LinphoneCore *l
/**
* Get the list of call logs (past calls) that matches the given #LinphoneAddress.
* At the contrary of linphone_core_get_call_logs, it is your responsability to unref the logs and free this list once you are done using it.
* At the contrary of linphone_core_get_call_logs, it is your responsibility to unref the logs and free this list once you are done using it.
* @param[in] lc LinphoneCore object
* @param[in] addr LinphoneAddress object
* @return \bctbx_list{LinphoneCallLog}
......@@ -4920,6 +4920,22 @@ LINPHONE_PUBLIC void linphone_core_set_im_encryption_engine(LinphoneCore *lc, Li
*/
LINPHONE_PUBLIC LinphoneImEncryptionEngine * linphone_core_get_im_encryption_engine(const LinphoneCore *lc);
/**
* Tells whether a content type is supported.
* @param[in] lc LinphoneCore object
* @param[in] content_type The content type to check
* @return A boolean value telling whether the specified content type is supported or not.
*/
LINPHONE_PUBLIC bool_t linphone_core_is_content_type_supported(const LinphoneCore *lc, const char *content_type);
/**
* Add support for the specified content type.
* It is the application responsibility to handle it correctly afterwards.
* @param[in] lc LinphoneCore object
* @param[in] content_type The content type to add support for
*/
LINPHONE_PUBLIC void linphone_core_add_content_type_support(LinphoneCore *lc, const char *content_type);
#include "linphone/ringtoneplayer.h"
#include "linphone/factory.h"
......
......@@ -307,16 +307,6 @@ typedef struct SalMessage{
time_t time;
}SalMessage;
typedef struct SalIsComposing {
const char *from;
const char *text;
} SalIsComposing;
typedef struct SalImdn {
const char *from;
const char *content;
} SalImdn;
#define SAL_MEDIA_DESCRIPTION_MAX_MESSAGE_ATTRIBUTES 5
SalMediaDescription *sal_media_description_new(void);
......@@ -447,11 +437,11 @@ typedef enum SalSubscribeStatus{
SalSubscribeTerminated
}SalSubscribeStatus;
typedef enum SalTextDeliveryStatus{
SalTextDeliveryInProgress,
SalTextDeliveryDone,
SalTextDeliveryFailed
}SalTextDeliveryStatus;
typedef enum SalMessageDeliveryStatus{
SalMessageDeliveryInProgress,
SalMessageDeliveryDone,
SalMessageDeliveryFailed
}SalMessageDeliveryStatus;
/**
* auth event mode
......@@ -505,10 +495,8 @@ typedef void (*SalOnRegisterFailure)(SalOp *op);
typedef void (*SalOnVfuRequest)(SalOp *op);
typedef void (*SalOnDtmfReceived)(SalOp *op, char dtmf);
typedef void (*SalOnRefer)(Sal *sal, SalOp *op, const char *referto);
typedef void (*SalOnTextReceived)(SalOp *op, const SalMessage *msg);
typedef void (*SalOnTextDeliveryUpdate)(SalOp *op, SalTextDeliveryStatus);
typedef void (*SalOnIsComposingReceived)(SalOp *op, const SalIsComposing *is_composing);
typedef void (*SalOnImdnReceived)(SalOp *op, const SalImdn *imdn);
typedef void (*SalOnMessageReceived)(SalOp *op, const SalMessage *msg);
typedef void (*SalOnMessageDeliveryUpdate)(SalOp *op, SalMessageDeliveryStatus);
typedef void (*SalOnNotifyRefer)(SalOp *op, SalReferStatus state);
typedef void (*SalOnSubscribeResponse)(SalOp *op, SalSubscribeStatus status, int will_retry);
typedef void (*SalOnNotify)(SalOp *op, SalSubscribeStatus status, const char *event, SalBodyHandler *body);
......@@ -544,10 +532,8 @@ typedef struct SalCallbacks{
SalOnVfuRequest vfu_request;
SalOnDtmfReceived dtmf_received;
SalOnRefer refer_received;
SalOnTextReceived text_received;
SalOnTextDeliveryUpdate text_delivery_update;
SalOnIsComposingReceived is_composing_received;
SalOnImdnReceived imdn_received;
SalOnMessageReceived message_received;
SalOnMessageDeliveryUpdate message_delivery_update;
SalOnNotifyRefer notify_refer;
SalOnSubscribeReceived subscribe_received;
SalOnIncomingSubscribeClosed incoming_subscribe_closed;
......@@ -644,6 +630,8 @@ void sal_use_tcp_tls_keepalive(Sal *ctx, bool_t enabled);
int sal_set_tunnel(Sal *ctx, void *tunnelclient);
/*Default value is true*/
void sal_enable_sip_update_method(Sal *ctx,bool_t value);
bool_t sal_is_content_type_supported(const Sal *sal, const char *content_type);
void sal_add_content_type_support(Sal *sal, const char *content_type);
/**
* returns keepalive period in ms
......
[Dolphin]
PreviewsShown=true
Timestamp=2015,8,3,13,7,36
Version=3
......@@ -130,9 +130,11 @@ set(RC_FILES
rcfiles/zero_length_params_rc
)
set(IMAGE_FILES
set(IMAGE_FILES
images/linphone.svg
images/nowebcamCIF.jpg
images/nowebcamVGA.jpg)
images/nowebcamVGA.jpg
)
set(VCARD_FILES
vcards/thousand_vcards.vcf
......
......@@ -78,7 +78,7 @@ RCFILES = \
rcfiles/friends_rc\
rcfiles/carddav_rc
IMAGE_FILES = images/nowebcamCIF.jpg images/nowebcamVGA.jpg
IMAGE_FILES = images/linphone.svg images/nowebcamCIF.jpg images/nowebcamVGA.jpg
VCARDS_FILE = vcards/vcards.vcf vcards/thousand_vcards.vcf
......
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 14.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 43363) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Calque_2" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="512px" height="512px" viewBox="0 0 512 512" enable-background="new 0 0 512 512" xml:space="preserve">
<g>
<g>
<path fill="#C95328" d="M512,433.229C512,476.562,476.557,512,433.228,512H78.768C35.452,512,0,476.562,0,433.229V78.763
C0,35.43,35.452,0,78.768,0h354.46C476.557,0,512,35.43,512,78.763V433.229z"/>
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="256.0044" y1="498.877" x2="256.0044" y2="13.1323">
<stop offset="0" style="stop-color:#E6B043"/>
<stop offset="0.5" style="stop-color:#C95328"/>
</linearGradient>
<path fill="url(#SVGID_1_)" d="M78.768,498.877c-36.188,0-65.632-29.438-65.632-65.648V78.763
c0-36.21,29.443-65.631,65.632-65.631h354.46c36.202,0,65.645,29.421,65.645,65.631v354.465c0,36.21-29.443,65.648-65.645,65.648
H78.768z"/>
</g>
<g>
<g>
<g>
<path fill="#C95328" d="M473.412,129.19c4.022,16.057,11.006,21.111,14.433,6.539c2.626-12.988-0.907-31.173-15.294-50.564
c-28.484-41.915-103.78-66.186-162.935-44.793c-31.137,11.984-24.661,13.922,7.499,7.175
c58.118-10.362,116.214,15.009,141.418,51.351C466.034,109.169,470.832,119.557,473.412,129.19z"/>
<path fill="#C95328" d="M419.015,143.098c7.494,14.941,12.717,26.531,19.203,25.729c6.259-0.803,15.077-12.937,11.313-29.547
c-2.509-10.809-8.09-22.524-17.543-33.749c-28.203-35.815-93.65-54.292-150.259-31.286
c-29.453,11.077-49.386,32.979-50.211,36.716c-1.109,4.036,18.227-9.882,45.146-18.015
c35.711-11.303,76.217-6.516,105.15,11.224C400.18,115.171,412.271,129.452,419.015,143.098z"/>
<path fill="#C95328" d="M272.768,116.451c-23.938,6.501-41.564,24.912-39.126,28.578c2.162,3.725,15.671-0.811,29.184-4.844
c8.038-2.487,16.081-3.953,23.938-4.465c25.749-1.574,45.468,6.943,57.738,17.625c11.416,9.433,22.448,19.878,31.148,19.694
c8.566-0.117,15.136-11.611,7.022-24.39c-8.806-13.192-24.526-26.198-47.588-32.772
C316.077,110.415,294.023,110.359,272.768,116.451z"/>
</g>
</g>
<g>
<g>
<path fill="#FFFFFF" d="M471.9,135.938c4.029,16.063,11.007,21.124,14.451,6.533c2.614-12.977-0.917-31.161-15.322-50.563
c-28.482-41.924-103.761-66.172-162.917-44.792c-31.146,11.995-24.653,13.946,7.502,7.184
c58.08-10.377,116.211,14.988,141.407,51.347C464.529,115.924,469.323,126.286,471.9,135.938z"/>
<path fill="#FFFFFF" d="M417.504,149.867c7.505,14.928,12.724,26.518,19.188,25.708c6.278-0.797,15.089-12.928,11.332-29.564
c-2.513-10.809-8.095-22.504-17.548-33.728C402.261,76.469,336.838,58,280.209,81.002
c-29.433,11.073-49.345,32.962-50.192,36.706c-1.089,4.03,18.224-9.864,45.125-17.983c35.73-11.315,76.235-6.557,105.167,11.199
C398.668,121.933,410.762,136.223,417.504,149.867z"/>
<path fill="#FFFFFF" d="M271.267,123.201c-23.948,6.485-41.572,24.917-39.134,28.582c2.168,3.729,15.69-0.8,29.175-4.826
c8.052-2.511,16.09-3.969,23.948-4.463c25.726-1.586,45.473,6.911,57.743,17.604c11.416,9.432,22.457,19.879,31.142,19.694
c8.571-0.115,15.134-11.604,7.032-24.405c-8.817-13.18-24.553-26.163-47.588-32.739
C314.582,117.183,292.515,117.094,271.267,123.201z"/>
</g>
</g>
</g>
<path fill="none" d="M78.768,499.246c-36.188,0-65.632-29.439-65.632-65.649V79.132c0-36.211,29.443-65.632,65.632-65.632h354.46
c36.202,0,65.645,29.421,65.645,65.632v354.465c0,36.21-29.443,65.649-65.645,65.649H78.768z"/>
<g>
<path fill="#C95328" d="M137.141,473.474c29.627,7.798,61.013,10.667,86.881,4.377c48.737-11.859,64.443-28.113,61.93-68.991
c0,0,0.908-19.719-40.68-18.982c-9.21,0.167-32.732,5.088-36.07,15.193c-3.342,10.114,1.719,20.368,1.991,25.324
s-13.443,11.676-19.206,12.246c-7.496,0.736-26.381-0.456-45.438-5.158l-0.82-0.211c-18.89-5.324-35.903-13.613-42.053-17.955
c-4.732-3.343-13.342-15.948-10.658-20.132c2.684-4.176,12.149-10.597,14.237-21.035c2.088-10.438-15.934-26.333-23.864-31.026
c-35.798-21.185-44.75-3.579-44.75-3.579c-22.373,34.308-16.737,56.193,19.789,90.57c19.386,18.245,48.101,31.245,77.711,39.097
L137.141,473.474z"/>
<path fill="#FFFFFF" d="M135.768,478.956c29.632,7.799,61.018,10.667,86.882,4.368c48.741-11.851,64.447-28.104,61.93-68.982
c0,0,0.912-19.728-40.676-18.982c-9.215,0.167-32.732,5.079-36.074,15.193c-3.338,10.114,1.719,20.368,1.996,25.324
c0.272,4.956-13.443,11.676-19.21,12.246c-7.491,0.736-26.382-0.456-45.435-5.158l-0.82-0.21
c-18.891-5.325-35.904-13.614-42.057-17.956c-4.728-3.343-13.342-15.957-10.658-20.132c2.689-4.176,12.149-10.597,14.241-21.035
c2.088-10.447-15.938-26.333-23.868-31.026c-35.794-21.185-44.746-3.588-44.746-3.588c-22.373,34.307-16.737,56.193,19.79,90.579
c19.386,18.236,48.097,31.245,77.71,39.097L135.768,478.956z"/>
</g>
<path fill="#C95328" d="M301.623,271.947l29.996-80.491l-103.663,42.298c-2.732-0.666-5.474-1.368-7.509-2.052
c-26.605-8.176-51.837-11.605-76.395-12.264c-32.062,0.658-61.403,5.438-87.325,15c-16.438,6.843-30.881,15.378-43.658,25.491
v45.518c2.197-2.176,4.412-4.324,6.815-6.201c12.97-10.264,26.605-17.729,40.943-23.211c14.329-4.771,27.969-8.167,40.921-10.229
c12.29-1.351,21.838-2.719,27.978-2.719c22.513,0,45.026,3.412,66.833,9.544c22.513,6.149,43.675,15.685,62.754,27.947
c18.443,12.982,34.127,28.667,45.724,47.745c6.833,11.614,11.596,21.869,15,32.79c3.408,10.22,5.447,20.456,5.447,30
c-0.667,19.097-6.811,37.526-19.096,53.877c-9.505,14.026-23.207,25.22-40.601,34.447h51.587
c7.053-5.859,14.189-12.649,21.759-20.78c8.189-9.535,15.698-21.132,21.163-34.816c6.123-13.631,9.54-28.64,9.54-44.99
c-0.697-28.658-7.509-54.605-21.847-77.088C335.719,302.632,320.04,285.605,301.623,271.947z"/>
<path fill="#FFFFFF" d="M299.688,280.614l30.004-80.518l-103.662,42.289c-2.732-0.675-5.474-1.351-7.509-2.044
c-26.605-8.184-51.833-11.604-76.399-12.254c-32.066,0.649-61.399,5.438-87.32,14.982c-15.759,6.579-29.645,14.729-42.035,24.281
v45.245c1.71-1.605,3.36-3.298,5.188-4.72c12.974-10.254,26.605-17.71,40.938-23.184c14.338-4.781,27.974-8.185,40.926-10.255
c12.29-1.333,21.838-2.719,27.978-2.719c22.518,0,45.026,3.43,66.829,9.544c22.513,6.157,43.684,15.701,62.763,27.982
c18.438,12.947,34.127,28.648,45.715,47.728c6.824,11.614,11.605,21.833,15.009,32.78c3.408,10.211,5.447,20.457,5.447,29.992
c-0.667,19.113-6.816,37.535-19.097,53.912c-6.623,9.754-15.324,18.131-25.842,25.456h46.868
c3.825-3.632,7.702-7.509,11.719-11.825c8.189-9.518,15.693-21.131,21.158-34.78c6.118-13.649,9.543-28.658,9.543-45.009