Commit 5193bb34 authored by Ghislain MARY's avatar Ghislain MARY

Add API to resend a chat message that has not been delivered.

parent 87cfca94
......@@ -159,6 +159,7 @@ belle_sip_request_t* sal_op_build_request(SalOp *op,const char* method) {
belle_sip_request_t *req;
belle_sip_uri_t* req_uri;
belle_sip_uri_t* to_uri;
belle_sip_header_call_id_t *call_id_header;
const SalAddress* to_address;
const MSList *elem=sal_op_get_route_addresses(op);
......@@ -189,11 +190,15 @@ belle_sip_request_t* sal_op_build_request(SalOp *op,const char* method) {
belle_sip_uri_set_secure(req_uri,sal_op_is_secure(op));
to_header = belle_sip_header_to_create(BELLE_SIP_HEADER_ADDRESS(to_address),NULL);
call_id_header = belle_sip_provider_create_call_id(prov);
if (sal_op_get_call_id(op)) {
belle_sip_header_call_id_set_call_id(call_id_header, sal_op_get_call_id(op));
}
req=belle_sip_request_create(
req_uri,
method,
belle_sip_provider_create_call_id(prov),
call_id_header,
belle_sip_header_cseq_create(20,method),
from_header,
to_header,
......
......@@ -1148,34 +1148,12 @@ static void refer_received(Sal *sal, SalOp *op, const char *referto){
}
}
static bool_t is_duplicate_msg(LinphoneCore *lc, const char *msg_id){
bctbx_list_t *elem=lc->last_recv_msg_ids;
bctbx_list_t *tail=NULL;
int i;
bool_t is_duplicate=FALSE;
for(i=0;elem!=NULL;elem=elem->next,i++){
if (strcmp((const char*)elem->data,msg_id)==0){
is_duplicate=TRUE;
}
tail=elem;
}
if (!is_duplicate){
lc->last_recv_msg_ids=bctbx_list_prepend(lc->last_recv_msg_ids,ms_strdup(msg_id));
}
if (i>=10){
ms_free(tail->data);
lc->last_recv_msg_ids=bctbx_list_erase_link(lc->last_recv_msg_ids,tail);
}
return is_duplicate;
}
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;
if (reason == LinphoneReasonNone && is_duplicate_msg(lc, msg->message_id) == FALSE) {
reason = linphone_core_message_received(lc, op, msg);
if (reason == LinphoneReasonNone) {
linphone_core_message_received(lc, op, msg);
}
sal_message_reply(op, linphone_reason_to_sal(reason));
if (!call) sal_op_release(op);
......
......@@ -383,7 +383,6 @@ void _linphone_chat_room_send_message(LinphoneChatRoom *cr, LinphoneChatMessage
msg->dir = LinphoneChatMessageOutgoing;
/* Check if we shall upload a file to a server */
if (msg->file_transfer_information != NULL && msg->content_type == NULL) {
/* open a transaction with the server and send an empty request(RCS5.1 section 3.5.4.8.3.1) */
......@@ -397,16 +396,20 @@ void _linphone_chat_room_send_message(LinphoneChatRoom *cr, LinphoneChatMessage
return;
}
} else {
SalOp *op = NULL;
SalOp *op = msg->op;
LinphoneCall *call=NULL;
char *content_type;
const char *identity = NULL;
char *message_not_encrypted = NULL;
char *clear_text_message = NULL;
char *clear_text_content_type = NULL;
if (msg->message) {
message_not_encrypted = ms_strdup(msg->message);
clear_text_message = ms_strdup(msg->message);
}
if (msg->content_type) {
clear_text_content_type = ms_strdup(msg->content_type);
}
/* Add to transient list */
linphone_chat_room_add_transient_message(cr, msg);
msg->time = ms_time(0);
......@@ -421,7 +424,7 @@ void _linphone_chat_room_send_message(LinphoneChatRoom *cr, LinphoneChatMessage
}
}
}
if (!identity) {
LinphoneProxyConfig *proxy = linphone_core_lookup_known_proxy(cr->lc, cr->peer_url);
if (proxy) {
......@@ -438,7 +441,7 @@ void _linphone_chat_room_send_message(LinphoneChatRoom *cr, LinphoneChatMessage
linphone_address_unref(msg->from);
}
msg->from = linphone_address_new(identity);
if (imee) {
LinphoneImEncryptionEngineCbs *imee_cbs = linphone_im_encryption_engine_get_callbacks(imee);
LinphoneImEncryptionEngineCbsOutgoingMessageCb cb_process_outgoing_message = linphone_im_encryption_engine_cbs_get_process_outgoing_message(imee_cbs);
......@@ -449,7 +452,7 @@ void _linphone_chat_room_send_message(LinphoneChatRoom *cr, LinphoneChatMessage
}
}
}
if (op == NULL) {
/*sending out of calls*/
msg->op = op = sal_op_new(cr->lc->sal);
......@@ -457,7 +460,7 @@ void _linphone_chat_room_send_message(LinphoneChatRoom *cr, LinphoneChatMessage
lp_config_get_int(cr->lc->config, "sip", "chat_msg_with_contact", 0));
sal_op_set_user_pointer(op, msg); /*if out of call, directly store msg*/
}
if (retval > 0) {
sal_error_info_set((SalErrorInfo *)sal_op_get_error_info(op), SalReasonNotAcceptable, retval, "Unable to encrypt IM", NULL);
store_or_update_chat_message(msg);
......@@ -481,10 +484,15 @@ void _linphone_chat_room_send_message(LinphoneChatRoom *cr, LinphoneChatMessage
ms_free(peer_uri);
}
if (msg->message && message_not_encrypted && strcmp(msg->message, message_not_encrypted) != 0) {
if (msg->message && clear_text_message && strcmp(msg->message, clear_text_message) != 0) {
// We replace the encrypted message by the original one so it can be correctly stored and displayed by the application
ms_free(msg->message);
msg->message = ms_strdup(message_not_encrypted);
msg->message = ms_strdup(clear_text_message);
}
if (msg->content_type && clear_text_content_type && (strcmp(msg->content_type, clear_text_content_type) != 0)) {
/* We replace the encrypted content type by the original one */
ms_free(msg->content_type);
msg->content_type = ms_strdup(clear_text_content_type);
}
msg->message_id = ms_strdup(sal_op_get_call_id(op)); /* must be known at that time */
store_or_update_chat_message(msg);
......@@ -495,8 +503,11 @@ void _linphone_chat_room_send_message(LinphoneChatRoom *cr, LinphoneChatMessage
linphone_chat_room_delete_composing_idle_timer(cr);
linphone_chat_room_delete_composing_refresh_timer(cr);
if (message_not_encrypted) {
ms_free(message_not_encrypted);
if (clear_text_message) {
ms_free(clear_text_message);
}
if (clear_text_content_type) {
ms_free(clear_text_content_type);
}
if (call && call->op == op) {
......@@ -648,6 +659,12 @@ LinphoneReason linphone_core_message_received(LinphoneCore *lc, SalOp *op, const
linphone_address_clean(addr);
cr = linphone_core_get_chat_room(lc, addr);
/* Check if this is a duplicate message */
if (linphone_chat_room_find_message(cr, sal_op_get_call_id(op)) != NULL) {
reason = lc->chat_deny_code;
goto end;
}
msg = linphone_chat_room_create_message(cr, sal_msg->text);
linphone_chat_message_set_content_type(msg, sal_msg->content_type);
linphone_chat_message_set_from(msg, cr->peer_url);
......@@ -950,6 +967,28 @@ void linphone_chat_room_send_chat_message(LinphoneChatRoom *cr, LinphoneChatMess
_linphone_chat_room_send_message(cr, msg);
}
void _linphone_chat_message_resend(LinphoneChatMessage *msg, bool_t ref_msg) {
LinphoneChatMessageState state = linphone_chat_message_get_state(msg);
LinphoneChatRoom *cr;
if (state != LinphoneChatMessageStateNotDelivered) {
ms_warning("Cannot resend chat message in state %s", linphone_chat_message_state_to_string(state));
return;
}
cr = linphone_chat_message_get_chat_room(msg);
if (ref_msg) linphone_chat_message_ref(msg);
_linphone_chat_room_send_message(cr, msg);
}
void linphone_chat_message_resend(LinphoneChatMessage *msg) {
_linphone_chat_message_resend(msg, FALSE);
}
void linphone_chat_message_resend_2(LinphoneChatMessage *msg) {
_linphone_chat_message_resend(msg, TRUE);
}
static char *linphone_chat_room_create_is_composing_xml(LinphoneChatRoom *cr) {
xmlBufferPtr buf;
xmlTextWriterPtr writer;
......
......@@ -5523,9 +5523,6 @@ static void linphone_core_uninit(LinphoneCore *lc)
bctbx_list_for_each(lc->call_logs,(void (*)(void*))linphone_call_log_unref);
lc->call_logs=bctbx_list_free(lc->call_logs);
bctbx_list_for_each(lc->last_recv_msg_ids,ms_free);
lc->last_recv_msg_ids=bctbx_list_free(lc->last_recv_msg_ids);
if(lc->zrtp_secrets_cache != NULL) {
ms_free(lc->zrtp_secrets_cache);
}
......
......@@ -1051,7 +1051,6 @@ struct _LinphoneCore
int max_calls;
LinphoneTunnel *tunnel;
char* device_id;
MSList *last_recv_msg_ids;
char *chat_db_file;
char *logs_db_file;
char *friends_db_file;
......
......@@ -412,6 +412,12 @@ LINPHONE_PUBLIC int linphone_chat_message_download_file(LinphoneChatMessage *mes
*/
LINPHONE_PUBLIC void linphone_chat_message_cancel_file_transfer(LinphoneChatMessage* msg);
/**
* Resend a chat message if it is in the 'not delivered' state for whatever reason.
* @param[in] msg LinphoneChatMessage object
*/
LINPHONE_PUBLIC void linphone_chat_message_resend(LinphoneChatMessage *msg);
/**
* Linphone message has an app-specific field that can store a text. The application might want
* to use it for keeping data over restarts, like thumbnail image path.
......
......@@ -44,12 +44,22 @@ extern "C" {
* @note Unlike linphone_chat_room_send_chat_message(), that function only takes a reference on the #LinphoneChatMessage
* instead of totaly takes ownership on it. Thus, the #LinphoneChatMessage object must be released by the API user after calling
* that function.
*
*
* @param[in] cr A chat room.
* @param[in] msg The message to send.
*/
LINPHONE_PUBLIC void linphone_chat_room_send_chat_message_2(LinphoneChatRoom *cr, LinphoneChatMessage *msg);
/**
* Resend a chat message if it is in the 'not delivered' state for whatever reason.
* @note Unlike linphone_chat_message_resend(), that function only takes a reference on the #LinphoneChatMessage
* instead of totaly takes ownership on it. Thus, the #LinphoneChatMessage object must be released by the API user after calling
* that function.
*
* @param[in] msg LinphoneChatMessage object
*/
LINPHONE_PUBLIC void linphone_chat_message_resend(LinphoneChatMessage *msg);
/**
* Accessor for the shared_ptr<BelCard> stored by a #LinphoneVcard
*/
......
......@@ -1090,7 +1090,8 @@ static void im_notification_policy_with_lime(void) {
static void _im_error_delivery_notification(bool_t online) {
FILE *ZIDCacheMarieFD, *ZIDCachePaulineFD;
LinphoneChatRoom *chat_room;
char *filepath;
char *marie_filepath;
char *pauline_filepath;
LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_new( "pauline_tcp_rc");
LinphoneChatMessage *msg;
......@@ -1114,13 +1115,12 @@ static void _im_error_delivery_notification(bool_t online) {
fclose(ZIDCacheMarieFD);
fclose(ZIDCachePaulineFD);
filepath = bc_tester_file("tmpZIDCacheMarie.xml");
linphone_core_set_zrtp_secrets_file(marie->lc, filepath);
bc_free(filepath);
marie_filepath = bc_tester_file("tmpZIDCacheMarie.xml");
linphone_core_set_zrtp_secrets_file(marie->lc, marie_filepath);
filepath = bc_tester_file("tmpZIDCachePauline.xml");
linphone_core_set_zrtp_secrets_file(pauline->lc, filepath);
bc_free(filepath);
pauline_filepath = bc_tester_file("tmpZIDCachePauline.xml");
linphone_core_set_zrtp_secrets_file(pauline->lc, pauline_filepath);
bc_free(pauline_filepath);
chat_room = linphone_core_get_chat_room(pauline->lc, marie->identity);
......@@ -1154,13 +1154,21 @@ static void _im_error_delivery_notification(bool_t online) {
wait_for_until(pauline->lc, marie->lc, &dummy, 1, 1500); /* Just to sleep while iterating */
BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneMessageReceived, 1, int, "%d"); /* Check the new message is not considered as received */
BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &pauline->stat.number_of_LinphoneMessageNotDelivered, 1));
/* Restore the ZID cache of the receiver and resend the chat message */
linphone_core_set_zrtp_secrets_file(marie->lc, marie_filepath);
linphone_chat_message_ref(msg);
linphone_chat_message_resend(msg);
BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneMessageReceived, 2)); /* Check the new message is now received */
BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &pauline->stat.number_of_LinphoneMessageDeliveredToUser, 1));
linphone_chat_message_unref(msg);
bc_free(marie_filepath);
end:
remove("tmpZIDCacheMarie.xml");
remove("tmpZIDCachePauline.xml");
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
remove("tmpZIDCacheMarie.xml");
remove("tmpZIDCachePauline.xml");
}
static void im_error_delivery_notification_online(void) {
......@@ -1260,7 +1268,11 @@ static void lime_text_message_to_non_lime(bool_t sender_policy_mandatory, bool_t
if (chat_room_size == 1) {
bctbx_list_t *history = linphone_chat_room_get_history(chat_room, 0);
LinphoneChatMessage *sent_msg = (LinphoneChatMessage *)bctbx_list_get_data(history);
BC_ASSERT_EQUAL((int)linphone_chat_message_get_state(sent_msg), (int)LinphoneChatMessageStateDelivered, int, "%d");
if (lime_key_available) {
BC_ASSERT_EQUAL((int)linphone_chat_message_get_state(sent_msg), (int)LinphoneChatMessageStateDelivered, int, "%d");
} else {
BC_ASSERT_EQUAL((int)linphone_chat_message_get_state(sent_msg), (int)LinphoneChatMessageStateNotDelivered, int, "%d");
}
bctbx_list_free_with_data(history, (bctbx_list_free_func)linphone_chat_message_unref);
}
} else {
......
......@@ -440,6 +440,7 @@ class CParser(object):
'linphone_factory_create_core_with_config', # manualy wrapped
'linphone_buffer_get_content',
'linphone_chat_room_send_chat_message', # overloaded
'linphone_chat_message_resend', # overloaded
'linphone_config_read_relative_file',
'linphone_vcard_get_belcard', # manualy wrapped
'linphone_chat_room_destroy', # was deprecated when the wrapper generator was made
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment