Send and receive imdn.

This commit is contained in:
Ghislain MARY 2016-12-07 14:14:47 +01:00
parent 41b9cf9c67
commit 9867c2fee7
17 changed files with 1431 additions and 776 deletions

View file

@ -595,6 +595,8 @@ void sal_set_callbacks(Sal *ctx, const SalCallbacks *cbs){
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.ping_reply==NULL)
ctx->callbacks.ping_reply=(SalOnPingReply)unimplemented_stub;
if (ctx->callbacks.auth_requested==NULL)

View file

@ -68,8 +68,13 @@ static bool_t is_im_iscomposing(belle_sip_header_content_type_t* content_type) {
&& 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(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"));
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"));
}
void sal_process_incoming_message(SalOp *op,const belle_sip_request_event_t *event){
@ -105,6 +110,16 @@ void sal_process_incoming_message(SalOp *op,const belle_sip_request_event_t *eve
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};

View file

@ -1187,6 +1187,13 @@ static void is_composing_received(SalOp *op, const SalIsComposing *is_composing)
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);
}
@ -1503,6 +1510,7 @@ SalCallbacks linphone_sal_callbacks={
text_received,
text_delivery_update,
is_composing_received,
imdn_received,
notify_refer,
subscribe_received,
incoming_subscribe_closed,

View file

@ -110,6 +110,69 @@ void linphone_chat_message_cbs_set_file_transfer_progress_indication(
}
BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneChatRoomCbs);
BELLE_SIP_INSTANCIATE_VPTR(LinphoneChatRoomCbs, belle_sip_object_t,
NULL, // destroy
NULL, // clone
NULL, // marshal
FALSE);
LinphoneChatRoomCbs *linphone_chat_room_cbs_new(void) {
return belle_sip_object_new(LinphoneChatRoomCbs);
}
LinphoneChatRoomCbs *linphone_chat_room_cbs_ref(LinphoneChatRoomCbs *cbs) {
belle_sip_object_ref(cbs);
return cbs;
}
void linphone_chat_room_cbs_unref(LinphoneChatRoomCbs *cbs) {
belle_sip_object_unref(cbs);
}
void *linphone_chat_room_cbs_get_user_data(const LinphoneChatRoomCbs *cbs) {
return cbs->user_data;
}
void linphone_chat_room_cbs_set_user_data(LinphoneChatRoomCbs *cbs, void *ud) {
cbs->user_data = ud;
}
LinphoneChatRoomCbsMsgStateChangedCb linphone_chat_room_cbs_get_msg_state_changed(const LinphoneChatRoomCbs *cbs) {
return cbs->msg_state_changed;
}
void linphone_chat_room_cbs_set_msg_state_changed(LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsMsgStateChangedCb cb) {
cbs->msg_state_changed = cb;
}
LinphoneChatRoomCbsFileTransferRecvCb linphone_chat_room_cbs_get_file_transfer_recv(const LinphoneChatRoomCbs *cbs) {
return cbs->file_transfer_recv;
}
void linphone_chat_room_cbs_set_file_transfer_recv(LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsFileTransferRecvCb cb) {
cbs->file_transfer_recv = cb;
}
LinphoneChatRoomCbsFileTransferSendCb linphone_chat_room_cbs_get_file_transfer_send(const LinphoneChatRoomCbs *cbs) {
return cbs->file_transfer_send;
}
void linphone_chat_room_cbs_set_file_transfer_send(LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsFileTransferSendCb cb) {
cbs->file_transfer_send = cb;
}
LinphoneChatRoomCbsFileTransferProgressIndicationCb linphone_chat_room_cbs_get_file_transfer_progress_indication(const LinphoneChatRoomCbs *cbs) {
return cbs->file_transfer_progress_indication;
}
void linphone_chat_room_cbs_set_file_transfer_progress_indication(LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsFileTransferProgressIndicationCb cb) {
cbs->file_transfer_progress_indication = cb;
}
BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneChatMessage);
static void _linphone_chat_room_destroy(LinphoneChatRoom *cr) {
@ -134,11 +197,18 @@ static void _linphone_chat_room_destroy(LinphoneChatRoom *cr) {
if (cr->pending_message)
linphone_chat_message_destroy(cr->pending_message);
ms_free(cr->peer);
if (cr->callbacks) {
linphone_chat_room_cbs_unref(cr->callbacks);
}
}
void linphone_chat_message_set_state(LinphoneChatMessage *msg, LinphoneChatMessageState state) {
/* do not invoke callbacks on orphan messages */
if (state != msg->state && msg->chat_room != NULL) {
if ((msg->state == LinphoneChatMessageStateDisplayed) && (state == LinphoneChatMessageStateDeliveredToUser)) {
/* If the message has been displayed we must not go back to the delivered to user state. */
return;
}
ms_message("Chat message %p: moving from state %s to %s", msg, linphone_chat_message_state_to_string(msg->state),
linphone_chat_message_state_to_string(state));
msg->state = state;
@ -148,6 +218,9 @@ void linphone_chat_message_set_state(LinphoneChatMessage *msg, LinphoneChatMessa
if (linphone_chat_message_cbs_get_msg_state_changed(msg->callbacks)) {
linphone_chat_message_cbs_get_msg_state_changed(msg->callbacks)(msg, msg->state);
}
if (linphone_chat_room_cbs_get_msg_state_changed(msg->chat_room->callbacks)) {
linphone_chat_room_cbs_get_msg_state_changed(msg->chat_room->callbacks)(msg->chat_room, msg, msg->state);
}
}
}
@ -188,6 +261,7 @@ BELLE_SIP_INSTANCIATE_VPTR(LinphoneChatRoom, belle_sip_object_t,
static LinphoneChatRoom *_linphone_core_create_chat_room_base(LinphoneCore *lc, LinphoneAddress *addr){
LinphoneChatRoom *cr = belle_sip_object_new(LinphoneChatRoom);
cr->lc = lc;
cr->callbacks = linphone_chat_room_cbs_new();
cr->peer = linphone_address_as_string(addr);
cr->peer_url = addr;
cr->unread_count = -1;
@ -428,6 +502,7 @@ void _linphone_chat_room_send_message(LinphoneChatRoom *cr, LinphoneChatMessage
msg->message = ms_strdup(message_not_encrypted);
}
msg->from = linphone_address_new(identity);
msg->message_id = ms_strdup(sal_op_get_call_id(op)); /* must be known at that time */
msg->storage_id = linphone_chat_message_store(msg);
if (cr->unread_count >= 0 && !msg->is_read)
@ -481,6 +556,7 @@ void linphone_chat_room_message_received(LinphoneChatRoom *cr, LinphoneCore *lc,
linphone_core_notify_message_received(lc, cr, msg);
cr->remote_is_composing = LinphoneIsComposingIdle;
linphone_core_notify_is_composing_received(cr->lc, cr);
linphone_chat_message_send_delivery_notification(msg);
}
LinphoneReason linphone_core_message_received(LinphoneCore *lc, SalOp *op, const SalMessage *sal_msg) {
@ -508,6 +584,7 @@ LinphoneReason linphone_core_message_received(LinphoneCore *lc, SalOp *op, const
msg->state = LinphoneChatMessageStateDelivered;
msg->is_read = FALSE;
msg->dir = LinphoneChatMessageIncoming;
msg->message_id = ms_strdup(sal_op_get_call_id(op));
ch = sal_op_get_recv_custom_header(op);
if (ch) {
@ -749,6 +826,88 @@ bool_t linphone_chat_room_is_remote_composing(const LinphoneChatRoom *cr) {
return (cr->remote_is_composing == LinphoneIsComposingActive) ? TRUE : FALSE;
}
static const char *imdn_prefix = "/imdn:imdn";
static void process_imdn(LinphoneChatRoom *cr, xmlparsing_context_t *xml_ctx) {
char xpath_str[MAX_XPATH_LENGTH];
xmlXPathObjectPtr imdn_object;
xmlXPathObjectPtr delivery_status_object;
xmlXPathObjectPtr display_status_object;
const char *message_id_str = NULL;
const char *datetime_str = NULL;
if (linphone_create_xml_xpath_context(xml_ctx) < 0)
return;
xmlXPathRegisterNs(xml_ctx->xpath_ctx, (const xmlChar *)"imdn",
(const xmlChar *)"urn:ietf:params:xml:ns:imdn");
imdn_object = linphone_get_xml_xpath_object_for_node_list(xml_ctx, imdn_prefix);
if (imdn_object != NULL) {
if ((imdn_object->nodesetval != NULL) && (imdn_object->nodesetval->nodeNr >= 1)) {
snprintf(xpath_str, sizeof(xpath_str), "%s[1]/imdn:message-id", imdn_prefix);
message_id_str = linphone_get_xml_text_content(xml_ctx, xpath_str);
snprintf(xpath_str, sizeof(xpath_str), "%s[1]/imdn:datetime", imdn_prefix);
datetime_str = linphone_get_xml_text_content(xml_ctx, xpath_str);
}
xmlXPathFreeObject(imdn_object);
}
if ((message_id_str != NULL) && (datetime_str != NULL)) {
LinphoneChatMessage *cm = linphone_chat_room_find_message(cr, message_id_str);
if (cm == NULL) {
ms_warning("Received IMDN for unknown message %s", message_id_str);
} else {
snprintf(xpath_str, sizeof(xpath_str), "%s[1]/imdn:delivery-notification/imdn:status", imdn_prefix);
delivery_status_object = linphone_get_xml_xpath_object_for_node_list(xml_ctx, xpath_str);
snprintf(xpath_str, sizeof(xpath_str), "%s[1]/imdn:display-notification/imdn:status", imdn_prefix);
display_status_object = linphone_get_xml_xpath_object_for_node_list(xml_ctx, xpath_str);
if (delivery_status_object != NULL) {
if ((delivery_status_object->nodesetval != NULL) && (delivery_status_object->nodesetval->nodeNr >= 1)) {
xmlNodePtr node = delivery_status_object->nodesetval->nodeTab[0];
if ((node->children != NULL) && (node->children->name != NULL) && (strcmp((const char *)node->children->name, "delivered") == 0)) {
linphone_chat_message_update_state(cm, LinphoneChatMessageStateDeliveredToUser);
}
}
xmlXPathFreeObject(delivery_status_object);
}
if (display_status_object != NULL) {
if ((display_status_object->nodesetval != NULL) && (display_status_object->nodesetval->nodeNr >= 1)) {
xmlNodePtr node = display_status_object->nodesetval->nodeTab[0];
if ((node->children != NULL) && (node->children->name != NULL) && (strcmp((const char *)node->children->name, "displayed") == 0)) {
linphone_chat_message_update_state(cm, LinphoneChatMessageStateDisplayed);
}
}
xmlXPathFreeObject(display_status_object);
}
linphone_chat_message_unref(cm);
}
}
if (message_id_str != NULL) linphone_free_xml_text_content(message_id_str);
if (datetime_str != NULL) linphone_free_xml_text_content(datetime_str);
}
static void linphone_chat_room_notify_imdn(LinphoneChatRoom *cr, const char *text) {
xmlparsing_context_t *xml_ctx = linphone_xmlparsing_context_new();
xmlSetGenericErrorFunc(xml_ctx, linphone_xmlparsing_genericxml_error);
xml_ctx->doc = xmlReadDoc((const unsigned char *)text, 0, NULL, 0);
if (xml_ctx->doc != NULL) {
process_imdn(cr, xml_ctx);
} else {
ms_warning("Wrongly formatted IMDN XML: %s", xml_ctx->errorBuffer);
}
linphone_xmlparsing_context_destroy(xml_ctx);
}
LinphoneReason linphone_core_imdn_received(LinphoneCore *lc, SalOp *op, const SalImdn *imdn) {
LinphoneAddress *addr = linphone_address_new(imdn->from);
LinphoneChatRoom *cr = _linphone_core_get_chat_room(lc, addr);
if (cr != NULL) {
linphone_chat_room_notify_imdn(cr, imdn->content);
}
linphone_address_destroy(addr);
return LinphoneReasonNone;
}
LinphoneCore *linphone_chat_room_get_lc(LinphoneChatRoom *cr) {
return linphone_chat_room_get_core(cr);
}
@ -912,6 +1071,143 @@ static void linphone_chat_room_send_is_composing_notification(LinphoneChatRoom *
}
}
enum ImdnType {
ImdnTypeDelivery,
ImdnTypeDisplay
};
static char *linphone_chat_message_create_imdn_xml(LinphoneChatMessage *cm, enum ImdnType imdn_type) {
xmlBufferPtr buf;
xmlTextWriterPtr writer;
int err;
char *content = NULL;
char *datetime = NULL;
buf = xmlBufferCreate();
if (buf == NULL) {
ms_error("Error creating the XML buffer");
return content;
}
writer = xmlNewTextWriterMemory(buf, 0);
if (writer == NULL) {
ms_error("Error creating the XML writer");
return content;
}
datetime = linphone_timestamp_to_rfc3339_string(linphone_chat_message_get_time(cm));
err = xmlTextWriterStartDocument(writer, "1.0", "UTF-8", NULL);
if (err >= 0) {
err = xmlTextWriterStartElementNS(writer, NULL, (const xmlChar *)"imdn",
(const xmlChar *)"urn:ietf:params:xml:ns:imdn");
}
if (err >= 0) {
err = xmlTextWriterWriteElement(writer, (const xmlChar *)"message-id", (const xmlChar *)linphone_chat_message_get_message_id(cm));
}
if (err >= 0) {
err = xmlTextWriterWriteElement(writer, (const xmlChar *)"datetime", (const xmlChar *)datetime);
}
if (err >= 0) {
if (imdn_type == ImdnTypeDelivery) {
err = xmlTextWriterStartElement(writer, (const xmlChar *)"delivery-notification");
} else {
err = xmlTextWriterStartElement(writer, (const xmlChar *)"display-notification");
}
}
if (err >= 0) {
err = xmlTextWriterStartElement(writer, (const xmlChar *)"status");
}
if (err >= 0) {
if (imdn_type == ImdnTypeDelivery) {
err = xmlTextWriterStartElement(writer, (const xmlChar *)"delivered");
} else {
err = xmlTextWriterStartElement(writer, (const xmlChar *)"displayed");
}
}
if (err >= 0) {
/* Close the "delivered" or "displayed" element. */
err = xmlTextWriterEndElement(writer);
}
if (err >= 0) {
/* Close the "status" element. */
err = xmlTextWriterEndElement(writer);
}
if (err >= 0) {
/* Close the "delivery-notification" or "display-notification" element. */
err = xmlTextWriterEndElement(writer);
}
if (err >= 0) {
/* Close the "imdn" element. */
err = xmlTextWriterEndElement(writer);
}
if (err >= 0) {
err = xmlTextWriterEndDocument(writer);
}
if (err > 0) {
/* xmlTextWriterEndDocument returns the size of the content. */
content = ms_strdup((char *)buf->content);
}
xmlFreeTextWriter(writer);
xmlBufferFree(buf);
ms_free(datetime);
return content;
}
static void linphone_chat_message_send_imdn(LinphoneChatMessage *cm, enum ImdnType imdn_type) {
SalOp *op = NULL;
const char *identity = NULL;
char *content = NULL;
LinphoneChatRoom *cr = linphone_chat_message_get_chat_room(cm);
LinphoneProxyConfig *proxy = linphone_core_lookup_known_proxy(cr->lc, cr->peer_url);
LinphoneImEncryptionEngine *imee = linphone_core_get_im_encryption_engine(cr->lc);
LinphoneChatMessage *msg;
if (proxy)
identity = linphone_proxy_config_get_identity(proxy);
else
identity = linphone_core_get_primary_contact(cr->lc);
/* Sending out of calls */
op = sal_op_new(cr->lc->sal);
linphone_configure_op(cr->lc, op, cr->peer_url, NULL,
lp_config_get_int(cr->lc->config, "sip", "chat_msg_with_contact", 0));
content = linphone_chat_message_create_imdn_xml(cm, imdn_type);
if (content != NULL) {
int retval = -1;
LinphoneAddress *from_addr = linphone_address_new(identity);
LinphoneAddress *to_addr = linphone_address_new(cr->peer);
msg = linphone_chat_room_create_message(cr, content);
linphone_chat_message_set_from_address(msg, from_addr);
linphone_chat_message_set_to_address(msg, to_addr);
msg->content_type = ms_strdup("message/imdn+xml");
if (imee) {
LinphoneImEncryptionEngineCbs *imee_cbs = linphone_im_encryption_engine_get_callbacks(imee);
LinphoneImEncryptionEngineOutgoingMessageCb cb_process_outgoing_message = linphone_im_encryption_engine_cbs_get_process_outgoing_message(imee_cbs);
if (cb_process_outgoing_message) {
retval = cb_process_outgoing_message(cr->lc, cr, msg);
}
}
if (retval <= 0) {
sal_message_send(op, identity, cr->peer, msg->content_type, msg->message, NULL);
}
linphone_chat_message_unref(msg);
linphone_address_destroy(from_addr);
linphone_address_destroy(to_addr);
ms_free(content);
}
sal_op_unref(op);
}
void linphone_chat_message_send_delivery_notification(LinphoneChatMessage *cm) {
linphone_chat_message_send_imdn(cm, ImdnTypeDelivery);
}
void linphone_chat_message_send_display_notification(LinphoneChatMessage *cm) {
linphone_chat_message_send_imdn(cm, ImdnTypeDisplay);
}
static char* utf8_to_char(uint32_t ic) {
char *result = ms_malloc(sizeof(char) * 5);
int size = 0;
@ -1043,6 +1339,10 @@ int linphone_chat_message_put_char(LinphoneChatMessage *msg, uint32_t character)
return 0;
}
const char* linphone_chat_message_get_message_id(const LinphoneChatMessage *cm) {
return cm->message_id;
}
static int linphone_chat_room_stop_composing(void *data, unsigned int revents) {
LinphoneChatRoom *cr = (LinphoneChatRoom *)data;
cr->is_composing = LinphoneIsComposingIdle;
@ -1095,6 +1395,10 @@ const char *linphone_chat_message_state_to_string(const LinphoneChatMessageState
return "LinphoneChatMessageStateFileTransferError";
case LinphoneChatMessageStateFileTransferDone:
return "LinphoneChatMessageStateFileTransferDone ";
case LinphoneChatMessageStateDeliveredToUser:
return "LinphoneChatMessageStateDeliveredToUser";
case LinphoneChatMessageStateDisplayed:
return "LinphoneChatMessageStateDisplayed";
}
return NULL;
}
@ -1254,6 +1558,8 @@ static void _linphone_chat_message_destroy(LinphoneChatMessage *msg) {
linphone_address_destroy(msg->from);
if (msg->to)
linphone_address_destroy(msg->to);
if (msg->message_id)
ms_free(msg->message_id);
if (msg->custom_headers)
sal_custom_header_free(msg->custom_headers);
if (msg->content_type)
@ -1299,6 +1605,10 @@ LinphoneChatMessageCbs *linphone_chat_message_get_callbacks(const LinphoneChatMe
return msg->callbacks;
}
LinphoneChatRoomCbs *linphone_chat_room_get_callbacks(const LinphoneChatRoom *room) {
return room->callbacks;
}
LinphoneCall *linphone_chat_room_get_call(const LinphoneChatRoom *room) {
return room->call;
}

View file

@ -81,13 +81,17 @@ static void linphone_chat_message_file_transfer_on_progress(belle_sip_body_handl
_release_http_request(msg);
return;
}
if (linphone_chat_message_cbs_get_file_transfer_progress_indication(msg->callbacks)) {
linphone_chat_message_cbs_get_file_transfer_progress_indication(msg->callbacks)(
msg, msg->file_transfer_information, offset, total);
if (linphone_chat_room_cbs_get_file_transfer_progress_indication(msg->chat_room->callbacks)) {
linphone_chat_room_cbs_get_file_transfer_progress_indication(msg->chat_room->callbacks)(msg->chat_room, msg, msg->file_transfer_information, offset, total);
} else {
/* Legacy: call back given by application level */
linphone_core_notify_file_transfer_progress_indication(msg->chat_room->lc, msg, msg->file_transfer_information,
offset, total);
if (linphone_chat_message_cbs_get_file_transfer_progress_indication(msg->callbacks)) {
linphone_chat_message_cbs_get_file_transfer_progress_indication(msg->callbacks)(
msg, msg->file_transfer_information, offset, total);
} else {
/* Legacy: call back given by application level */
linphone_core_notify_file_transfer_progress_indication(msg->chat_room->lc, msg, msg->file_transfer_information,
offset, total);
}
}
}
@ -111,9 +115,9 @@ static int on_send_body(belle_sip_user_body_handler_t *bh, belle_sip_message_t *
/* in case of file body handler, won't be called */
if (offset < linphone_content_get_size(msg->file_transfer_information)) {
/* get data from call back */
LinphoneChatMessageCbsFileTransferSendCb file_transfer_send_cb = linphone_chat_message_cbs_get_file_transfer_send(msg->callbacks);
if (file_transfer_send_cb) {
LinphoneBuffer *lb = file_transfer_send_cb(msg, msg->file_transfer_information, offset, *size);
LinphoneChatRoomCbsFileTransferSendCb cr_file_transfer_send_cb = linphone_chat_room_cbs_get_file_transfer_send(msg->chat_room->callbacks);
if (cr_file_transfer_send_cb) {
LinphoneBuffer *lb = cr_file_transfer_send_cb(msg->chat_room, msg, msg->file_transfer_information, offset, *size);
if (lb == NULL) {
*size = 0;
} else {
@ -122,8 +126,20 @@ static int on_send_body(belle_sip_user_body_handler_t *bh, belle_sip_message_t *
linphone_buffer_unref(lb);
}
} else {
/* Legacy */
linphone_core_notify_file_transfer_send(lc, msg, msg->file_transfer_information, (char *)buffer, size);
LinphoneChatMessageCbsFileTransferSendCb file_transfer_send_cb = linphone_chat_message_cbs_get_file_transfer_send(msg->callbacks);
if (file_transfer_send_cb) {
LinphoneBuffer *lb = file_transfer_send_cb(msg, msg->file_transfer_information, offset, *size);
if (lb == NULL) {
*size = 0;
} else {
*size = linphone_buffer_get_size(lb);
memcpy(buffer, linphone_buffer_get_content(lb), *size);
linphone_buffer_unref(lb);
}
} else {
/* Legacy */
linphone_core_notify_file_transfer_send(lc, msg, msg->file_transfer_information, (char *)buffer, size);
}
}
}
@ -397,13 +413,19 @@ static void on_recv_body(belle_sip_user_body_handler_t *bh, belle_sip_message_t
ms_free(decrypted_buffer);
if (retval <= 0) {
if (linphone_chat_message_cbs_get_file_transfer_recv(msg->callbacks)) {
if (linphone_chat_room_cbs_get_file_transfer_recv(msg->chat_room->callbacks)) {
LinphoneBuffer *lb = linphone_buffer_new_from_data(buffer, size);
linphone_chat_message_cbs_get_file_transfer_recv(msg->callbacks)(msg, msg->file_transfer_information, lb);
linphone_chat_room_cbs_get_file_transfer_recv(msg->chat_room->callbacks)(msg->chat_room, msg, msg->file_transfer_information, lb);
linphone_buffer_unref(lb);
} else {
/* Legacy: call back given by application level */
linphone_core_notify_file_transfer_recv(lc, msg, msg->file_transfer_information, (const char *)buffer, size);
if (linphone_chat_message_cbs_get_file_transfer_recv(msg->callbacks)) {
LinphoneBuffer *lb = linphone_buffer_new_from_data(buffer, size);
linphone_chat_message_cbs_get_file_transfer_recv(msg->callbacks)(msg, msg->file_transfer_information, lb);
linphone_buffer_unref(lb);
} else {
/* Legacy: call back given by application level */
linphone_core_notify_file_transfer_recv(lc, msg, msg->file_transfer_information, (const char *)buffer, size);
}
}
} else {
ms_warning("File transfer decrypt failed with code %d", (int)retval);
@ -428,16 +450,22 @@ static void on_recv_end(belle_sip_user_body_handler_t *bh, void *data) {
}
if (retval <= 0) {
if (linphone_chat_message_cbs_get_file_transfer_recv(msg->callbacks)) {
if (linphone_chat_room_cbs_get_file_transfer_recv(msg->chat_room->callbacks)) {
LinphoneBuffer *lb = linphone_buffer_new();
linphone_chat_message_cbs_get_file_transfer_recv(msg->callbacks)(msg, msg->file_transfer_information, lb);
linphone_chat_room_cbs_get_file_transfer_recv(msg->chat_room->callbacks)(msg->chat_room, msg, msg->file_transfer_information, lb);
linphone_buffer_unref(lb);
} else {
/* Legacy: call back given by application level */
linphone_core_notify_file_transfer_recv(lc, msg, msg->file_transfer_information, NULL, 0);
if (linphone_chat_message_cbs_get_file_transfer_recv(msg->callbacks)) {
LinphoneBuffer *lb = linphone_buffer_new();
linphone_chat_message_cbs_get_file_transfer_recv(msg->callbacks)(msg, msg->file_transfer_information, lb);
linphone_buffer_unref(lb);
} else {
/* Legacy: call back given by application level */
linphone_core_notify_file_transfer_recv(lc, msg, msg->file_transfer_information, NULL, 0);
}
}
}
if (retval <= 0 && linphone_chat_message_get_state(msg) != LinphoneChatMessageStateFileTransferError) {
linphone_chat_message_set_state(msg, LinphoneChatMessageStateFileTransferDone);
}

View file

@ -44,7 +44,7 @@ static void stop(int signum){
/**
* function invoked to report file transfer progress.
* */
static void file_transfer_progress_indication(LinphoneChatMessage *message, const LinphoneContent* content, size_t offset, size_t total) {
static void file_transfer_progress_indication(LinphoneChatRoom *room,LinphoneChatMessage *message, const LinphoneContent* content, size_t offset, size_t total) {
const LinphoneAddress* from_address = linphone_chat_message_get_from(message);
const LinphoneAddress* to_address = linphone_chat_message_get_to(message);
char *address = linphone_chat_message_is_outgoing(message)?linphone_address_as_string(to_address):linphone_address_as_string(from_address);
@ -59,7 +59,7 @@ static void file_transfer_progress_indication(LinphoneChatMessage *message, cons
/**
* function invoked when a file transfer is received.
**/
static void file_transfer_received(LinphoneChatMessage *message, const LinphoneContent* content, const LinphoneBuffer *buffer){
static void file_transfer_received(LinphoneChatRoom *room, LinphoneChatMessage *message, const LinphoneContent* content, const LinphoneBuffer *buffer){
FILE* file=NULL;
if (!linphone_chat_message_get_user_data(message)) {
/*first chunk, creating file*/
@ -85,7 +85,7 @@ char big_file [128000];
/*
* function called when the file transfer is initiated. file content should be feed into object LinphoneContent
* */
static LinphoneBuffer * file_transfer_send(LinphoneChatMessage *message, const LinphoneContent* content, size_t offset, size_t size){
static LinphoneBuffer * file_transfer_send(LinphoneChatRoom *room, LinphoneChatMessage *message, const LinphoneContent* content, size_t offset, size_t size){
size_t size_to_send = MIN(size, sizeof(big_file) - offset);
if (size == 0) return linphone_buffer_new(); /*end of file*/
return linphone_buffer_new_from_data((uint8_t *)big_file + offset, size_to_send);
@ -94,7 +94,7 @@ static LinphoneBuffer * file_transfer_send(LinphoneChatMessage *message, const
/*
* Call back to get delivery status of a message
* */
static void linphone_file_transfer_state_changed(LinphoneChatMessage* msg,LinphoneChatMessageState state) {
static void linphone_file_transfer_state_changed(LinphoneChatRoom *room,LinphoneChatMessage* msg,LinphoneChatMessageState state) {
const LinphoneAddress* to_address = linphone_chat_message_get_to(msg);
char *to = linphone_address_as_string(to_address);
printf("File transfer sent to [%s] delivery status is [%s] \n" , to
@ -123,7 +123,7 @@ int main(int argc, char *argv[]){
LinphoneChatRoom* chat_room;
LinphoneContent* content;
LinphoneChatMessage* chat_message;
LinphoneChatMessageCbs *cbs;
LinphoneChatRoomCbs *cbs;
/*seting dummy file content to something*/
for (i=0;i<sizeof(big_file);i+=strlen(big_file_content))
@ -157,6 +157,17 @@ int main(int argc, char *argv[]){
/*Next step is to create a chat room*/
chat_room = linphone_core_get_chat_room_from_uri(lc,dest_friend);
/**
* Fill the application callbacks. The file_transfer_received callback is used in order to get notifications
* about incoming file reception, file_transfer_send to feed file to be transfered and
* file_transfer_progress_indication to print progress.
*/
cbs = linphone_chat_room_get_callbacks(chat_room);
linphone_chat_room_cbs_set_file_transfer_recv(cbs, file_transfer_received);
linphone_chat_room_cbs_set_file_transfer_send(cbs, file_transfer_send);
linphone_chat_room_cbs_set_file_transfer_progress_indication(cbs, file_transfer_progress_indication);
linphone_chat_room_cbs_set_msg_state_changed(cbs, linphone_file_transfer_state_changed);
content = linphone_core_create_content(lc);
linphone_content_set_type(content,"text");
linphone_content_set_subtype(content,"plain");
@ -169,17 +180,6 @@ int main(int argc, char *argv[]){
printf("returned message is null\n");
}
/**
* Fill the application callbacks. The file_transfer_received callback is used in order to get notifications
* about incoming file reception, file_transfer_send to feed file to be transfered and
* file_transfer_progress_indication to print progress.
*/
cbs = linphone_chat_message_get_callbacks(chat_message);
linphone_chat_message_cbs_set_file_transfer_recv(cbs, file_transfer_received);
linphone_chat_message_cbs_set_file_transfer_send(cbs, file_transfer_send);
linphone_chat_message_cbs_set_file_transfer_progress_indication(cbs, file_transfer_progress_indication);
linphone_chat_message_cbs_set_msg_state_changed(cbs, linphone_file_transfer_state_changed);
/*initiating file transfer*/
linphone_chat_room_send_chat_message(chat_room, chat_message);

View file

@ -201,6 +201,7 @@ static int callback_all(void *data, int argc, char **argv, char **colName){
* | 9 | utc timestamp
* | 10 | app data text
* | 11 | linphone content id
* | 12 | message id
*/
static int create_chat_message(void *data, int argc, char **argv, char **colName){
LinphoneChatRoom *cr = (LinphoneChatRoom *)data;
@ -227,6 +228,7 @@ static int create_chat_message(void *data, int argc, char **argv, char **colName
new_message->storage_id=storage_id;
new_message->external_body_url= ms_strdup(argv[8]);
new_message->appdata = ms_strdup(argv[10]);
new_message->message_id = ms_strdup(argv[12]);
if (argv[11] != NULL) {
int id = atoi(argv[11]);
@ -309,7 +311,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);",
buf = sqlite3_mprintf("INSERT INTO history VALUES(NULL,%Q,%Q,%i,%Q,%Q,%i,%i,%Q,%lld,%Q,%i,%Q);",
local_contact,
peer,
msg->dir,
@ -320,7 +322,8 @@ unsigned int linphone_chat_message_store(LinphoneChatMessage *msg){
msg->external_body_url,
(int64_t)msg->time,
msg->appdata,
content_id
content_id,
msg->message_id
);
linphone_sql_request(lc->db,buf);
sqlite3_free(buf);
@ -527,6 +530,28 @@ bctbx_list_t *linphone_chat_room_get_history(LinphoneChatRoom *cr,int nb_message
return linphone_chat_room_get_history_range(cr, 0, nb_message-1);
}
LinphoneChatMessage * linphone_chat_room_find_message(LinphoneChatRoom *cr, const char *message_id) {
LinphoneCore *lc = linphone_chat_room_get_core(cr);
LinphoneChatMessage *cm = NULL;
char *buf;
char *peer;
if (lc->db == NULL) return NULL;
peer = linphone_address_as_string_uri_only(linphone_chat_room_get_peer_address(cr));
cr->messages_hist = NULL;
buf = sqlite3_mprintf("SELECT * FROM history WHERE remoteContact = %Q AND messageId = %Q", peer, message_id);
linphone_sql_request_message(lc->db, buf, cr);
sqlite3_free(buf);
if (cr->messages_hist) {
cm = (LinphoneChatMessage *)bctbx_list_nth_data(cr->messages_hist, 0);
}
cr->messages_hist = NULL;
ms_free(peer);
return cm;
}
void linphone_create_table(sqlite3* db){
char* errmsg=NULL;
int ret;
@ -681,6 +706,14 @@ void linphone_update_table(sqlite3* db) {
ms_debug("Table history content successfully for lime key storage data.");
}
}
// new field for message_id
ret = sqlite3_exec(db, "ALTER TABLE history ADD COLUMN messageId 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 message_id data.");
}
}
void linphone_message_storage_init_chat_rooms(LinphoneCore *lc) {
@ -764,7 +797,11 @@ bctbx_list_t *linphone_chat_room_get_history(LinphoneChatRoom *cr,int nb_message
return NULL;
}
LINPHONE_PUBLIC bctbx_list_t *linphone_chat_room_get_history_range(LinphoneChatRoom *cr, int begin, int end){
bctbx_list_t *linphone_chat_room_get_history_range(LinphoneChatRoom *cr, int begin, int end){
return NULL;
}
LinphoneChatMessage * linphone_chat_room_find_message(LinphoneChatRoom *cr, const char *message_id) {
return NULL;
}

View file

@ -249,6 +249,7 @@ struct _LinphoneChatMessage {
LinphoneChatMessageState state;
bool_t is_read;
unsigned int storage_id;
char *message_id;
SalOp *op;
LinphoneContent *file_transfer_information; /**< used to store file transfer information when the message is of file transfer type */
char *content_type; /**< is used to specified the type of message to be sent, used only for file transfer message */
@ -553,6 +554,7 @@ void linphone_proxy_config_write_to_config_file(struct _LpConfig* config,Linphon
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);
@ -608,12 +610,15 @@ void _linphone_proxy_config_release_ops(LinphoneProxyConfig *obj);
/*chat*/
void linphone_chat_room_release(LinphoneChatRoom *cr);
LinphoneChatRoomCbs *linphone_chat_room_cbs_new(void);
void linphone_chat_message_destroy(LinphoneChatMessage* msg);
void linphone_chat_message_update_state(LinphoneChatMessage *msg, LinphoneChatMessageState new_state);
void linphone_chat_message_set_state(LinphoneChatMessage *msg, LinphoneChatMessageState state);
void linphone_chat_message_send_delivery_notification(LinphoneChatMessage *cm);
void linphone_chat_message_send_display_notification(LinphoneChatMessage *cm);
int linphone_chat_room_upload_file(LinphoneChatMessage *msg);
void _linphone_chat_room_send_message(LinphoneChatRoom *cr, LinphoneChatMessage *msg);
LinphoneChatMessageCbs *linphone_chat_message_cbs_new(void);
LinphoneChatMessageCbs *linphone_chat_message_cbs_new(void); /* deprecated */
LinphoneChatRoom *_linphone_core_create_chat_room_from_call(LinphoneCall *call);
/**/
@ -689,10 +694,22 @@ typedef enum _LinphoneIsComposingState {
LinphoneIsComposingActive
} LinphoneIsComposingState;
struct _LinphoneChatRoomCbs {
belle_sip_object_t base;
void *user_data;
LinphoneChatRoomCbsMsgStateChangedCb msg_state_changed;
LinphoneChatRoomCbsFileTransferRecvCb file_transfer_recv; /**< Callback to store file received attached to a #LinphoneChatRoom */
LinphoneChatRoomCbsFileTransferSendCb file_transfer_send; /**< Callback to collect file chunk to be sent for a #LinphoneChatRoom */
LinphoneChatRoomCbsFileTransferProgressIndicationCb file_transfer_progress_indication; /**< Callback to indicate file transfer progress */
};
BELLE_SIP_DECLARE_VPTR(LinphoneChatRoomCbs);
struct _LinphoneChatRoom{
belle_sip_object_t base;
void *user_data;
struct _LinphoneCore *lc;
LinphoneChatRoomCbs *callbacks;
char *peer;
LinphoneAddress *peer_url;
MSList *messages_hist;
@ -1533,6 +1550,7 @@ BELLE_SIP_TYPE_ID(LinphoneCallParams),
BELLE_SIP_TYPE_ID(LinphoneChatMessage),
BELLE_SIP_TYPE_ID(LinphoneChatMessageCbs),
BELLE_SIP_TYPE_ID(LinphoneChatRoom),
BELLE_SIP_TYPE_ID(LinphoneChatRoomCbs),
BELLE_SIP_TYPE_ID(LinphoneContent),
BELLE_SIP_TYPE_ID(LinphoneImEncryptionEngine),
BELLE_SIP_TYPE_ID(LinphoneImEncryptionEngineCbs),

View file

@ -29,6 +29,7 @@ set(HEADER_FILES
call_log.h
call_params.h
call_stats.h
chat.h
conference.h
contactprovider.h
content.h

View file

@ -9,6 +9,7 @@ linphone_include_HEADERS=\
call_log.h \
call_params.h \
call_stats.h \
chat.h \
conference.h \
contactprovider.h \
content.h \

837
include/linphone/chat.h Normal file
View file

@ -0,0 +1,837 @@
/*
chat.h
Copyright (C) 2010-2016 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_CHAT_H_
#define LINPHONE_CHAT_H_
#ifdef __cplusplus
extern "C" {
#endif
/**
* @addtogroup chatroom
* @{
*/
/**
* An object to handle the callbacks for the handling a LinphoneChatMessage objects.
* @deprecated Use LinphoneChatRoomCbs instead.
*/
typedef struct _LinphoneChatMessageCbs LinphoneChatMessageCbs;
/**
* A chat room message to hold content to be sent.
* <br> Can be created by linphone_chat_room_create_message().
*/
typedef struct _LinphoneChatMessage LinphoneChatMessage;
/**
* An object to handle the callbacks for the handling of LinphoneChatMessage objects related to a LinphoneChatRoom.
*/
typedef struct _LinphoneChatRoomCbs LinphoneChatRoomCbs;
/**
* A chat room is the place where text messages are exchanged.
* <br> Can be created by linphone_core_create_chat_room().
*/
typedef struct _LinphoneChatRoom LinphoneChatRoom;
/**
* LinphoneChatMessageState is used to notify if messages have been succesfully delivered or not.
*/
typedef enum _LinphoneChatMessageState {
LinphoneChatMessageStateIdle, /**< Initial state */
LinphoneChatMessageStateInProgress, /**< Delivery in progress */
LinphoneChatMessageStateDelivered, /**< Message successfully delivered and acknowledged by server */
LinphoneChatMessageStateNotDelivered, /**< Message was not delivered */
LinphoneChatMessageStateFileTransferError, /**< Message was received(and acknowledged) but cannot get file from server */
LinphoneChatMessageStateFileTransferDone, /**< File transfer has been completed successfully. */
LinphoneChatMessageStateDeliveredToUser, /**< Message successfully delivered and acknowledged to destination */
LinphoneChatMessageStateDisplayed /**< Message displayed to the remote user */
} LinphoneChatMessageState;
typedef enum _LinphoneLimeState {
LinphoneLimeDisabled, /**< Lime is not used at all */
LinphoneLimeMandatory, /**< Lime is always used */
LinphoneLimePreferred, /**< Lime is used only if we already shared a secret with remote */
} LinphoneLimeState;
/**
* Call back used to notify message delivery status
* @param msg #LinphoneChatMessage object
* @param status LinphoneChatMessageState
* @param ud application user data
* @deprecated Use LinphoneChatRoomCbsMsgStateChangedCb instead.
*/
typedef void (*LinphoneChatMessageStateChangedCb)(LinphoneChatMessage* msg,LinphoneChatMessageState state,void* ud);
/**
* Call back used to notify message delivery status
* @param msg #LinphoneChatMessage object
* @param status LinphoneChatMessageState
* @deprecated Use LinphoneChatRoomCbsMsgStateChangedCb instead.
*/
typedef void (*LinphoneChatMessageCbsMsgStateChangedCb)(LinphoneChatMessage* msg, LinphoneChatMessageState state);
/**
* File transfer receive callback prototype. This function is called by the core upon an incoming File transfer is started. This function may be call several time for the same file in case of large file.
* @param message #LinphoneChatMessage message from which the body is received.
* @param content #LinphoneContent incoming content information
* @param buffer #LinphoneBuffer holding the received data. Empty buffer means end of file.
* @deprecated Use LinphoneChatRoomCbsFileTransferRecvCb instead.
*/
typedef void (*LinphoneChatMessageCbsFileTransferRecvCb)(LinphoneChatMessage *message, const LinphoneContent* content, const LinphoneBuffer *buffer);
/**
* File transfer send callback prototype. This function is called by the core when an outgoing file transfer is started. This function is called until size is set to 0.
* @param message #LinphoneChatMessage message from which the body is received.
* @param content #LinphoneContent outgoing content
* @param offset the offset in the file from where to get the data to be sent
* @param size the number of bytes expected by the framework
* @return A LinphoneBuffer object holding the data written by the application. An empty buffer means end of file.
* @deprecated Use LinphoneChatRoomCbsFileTransferSendCb instead.
*/
typedef LinphoneBuffer * (*LinphoneChatMessageCbsFileTransferSendCb)(LinphoneChatMessage *message, const LinphoneContent* content, size_t offset, size_t size);
/**
* File transfer progress indication callback prototype.
* @param message #LinphoneChatMessage message from which the body is received.
* @param content #LinphoneContent incoming content information
* @param offset The number of bytes sent/received since the beginning of the transfer.
* @param total The total number of bytes to be sent/received.
* @deprecated Use LinphoneChatRoomCbsFileTransferProgressIndicationCb instead.
*/
typedef void (*LinphoneChatMessageCbsFileTransferProgressIndicationCb)(LinphoneChatMessage *message, const LinphoneContent* content, size_t offset, size_t total);
/**
* Call back used to notify message delivery status
* @param room #LinphoneChatRoom object
* @param msg #LinphoneChatMessage object
* @param status LinphoneChatMessageState
*/
typedef void (*LinphoneChatRoomCbsMsgStateChangedCb)(LinphoneChatRoom *room, LinphoneChatMessage* msg, LinphoneChatMessageState state);
/**
* File transfer receive callback prototype. This function is called by the core upon an incoming File transfer is started. This function may be call several time for the same file in case of large file.
* @param room #LinphoneChatRoom object
* @param message #LinphoneChatMessage message from which the body is received.
* @param content #LinphoneContent incoming content information
* @param buffer #LinphoneBuffer holding the received data. Empty buffer means end of file.
*/
typedef void (*LinphoneChatRoomCbsFileTransferRecvCb)(LinphoneChatRoom *room, LinphoneChatMessage *message, const LinphoneContent* content, const LinphoneBuffer *buffer);
/**
* File transfer send callback prototype. This function is called by the core when an outgoing file transfer is started. This function is called until size is set to 0.
* @param room #LinphoneChatRoom object
* @param message #LinphoneChatMessage message from which the body is received.
* @param content #LinphoneContent outgoing content
* @param offset the offset in the file from where to get the data to be sent
* @param size the number of bytes expected by the framework
* @return A LinphoneBuffer object holding the data written by the application. An empty buffer means end of file.
*/
typedef LinphoneBuffer * (*LinphoneChatRoomCbsFileTransferSendCb)(LinphoneChatRoom *room, LinphoneChatMessage *message, const LinphoneContent* content, size_t offset, size_t size);
/**
* File transfer progress indication callback prototype.
* @param room #LinphoneChatRoom object
* @param message #LinphoneChatMessage message from which the body is received.
* @param content #LinphoneContent incoming content information
* @param offset The number of bytes sent/received since the beginning of the transfer.
* @param total The total number of bytes to be sent/received.
*/
typedef void (*LinphoneChatRoomCbsFileTransferProgressIndicationCb)(LinphoneChatRoom *room, LinphoneChatMessage *message, const LinphoneContent* content, size_t offset, size_t total);
LINPHONE_PUBLIC void linphone_core_set_chat_database_path(LinphoneCore *lc, const char *path);
/**
* Get path to the database file used for storing chat messages.
* @param lc the linphone core
* @return file path or NULL if not exist
**/
LINPHONE_PUBLIC const char *linphone_core_get_chat_database_path(const LinphoneCore *lc);
/**
* Get a chat room whose peer is the supplied address. If it does not exist yet, it will be created.
* No reference is transfered to the application. The LinphoneCore keeps a reference on the chat room.
* @param lc the linphone core
* @param addr a linphone address.
* @return #LinphoneChatRoom where messaging can take place.
**/
LINPHONE_PUBLIC LinphoneChatRoom *linphone_core_get_chat_room(LinphoneCore *lc, const LinphoneAddress *addr);
/**
* Get a chat room for messaging from a sip uri like sip:joe@sip.linphone.org. If it does not exist yet, it will be created.
* No reference is transfered to the application. The LinphoneCore keeps a reference on the chat room.
* @param lc A #LinphoneCore object
* @param to The destination address for messages.
* @return #LinphoneChatRoom where messaging can take place.
**/
LINPHONE_PUBLIC LinphoneChatRoom *linphone_core_get_chat_room_from_uri(LinphoneCore *lc, const char *to);
/**
* Removes a chatroom including all message history from the LinphoneCore.
* @param lc A #LinphoneCore object
* @param cr A #LinphoneChatRoom object
**/
LINPHONE_PUBLIC void linphone_core_delete_chat_room(LinphoneCore *lc, LinphoneChatRoom *cr);
/**
* Inconditionnaly disable incoming chat messages.
* @param lc A #LinphoneCore object
* @param deny_reason the deny reason (#LinphoneReasonNone has no effect).
**/
LINPHONE_PUBLIC void linphone_core_disable_chat(LinphoneCore *lc, LinphoneReason deny_reason);
/**
* Enable reception of incoming chat messages.
* By default it is enabled but it can be disabled with linphone_core_disable_chat().
* @param lc A #LinphoneCore object
**/
LINPHONE_PUBLIC void linphone_core_enable_chat(LinphoneCore *lc);
/**
* Returns whether chat is enabled.
* @param lc A #LinphoneCore object
**/
LINPHONE_PUBLIC bool_t linphone_core_chat_enabled(const LinphoneCore *lc);
/**
* Destroy a LinphoneChatRoom.
* @param cr #LinphoneChatRoom object
* @deprecated Use linphone_chat_room_unref() instead.
*/
LINPHONE_PUBLIC LINPHONE_DEPRECATED void linphone_chat_room_destroy(LinphoneChatRoom *cr);
/**
* Create a message attached to a dedicated chat room;
* @param cr the chat room.
* @param message text message, NULL if absent.
* @return a new #LinphoneChatMessage
*/
LINPHONE_PUBLIC LinphoneChatMessage* linphone_chat_room_create_message(LinphoneChatRoom *cr,const char* message);
/**
* Create a message attached to a dedicated chat room;
* @param cr the chat room.
* @param message text message, NULL if absent.
* @param external_body_url the URL given in external body or NULL.
* @param state the LinphoneChatMessage.State of the message.
* @param time the time_t at which the message has been received/sent.
* @param is_read TRUE if the message should be flagged as read, FALSE otherwise.
* @param is_incoming TRUE if the message has been received, FALSE otherwise.
* @return a new #LinphoneChatMessage
*/
LINPHONE_PUBLIC LinphoneChatMessage* linphone_chat_room_create_message_2(LinphoneChatRoom *cr, const char* message, const char* external_body_url, LinphoneChatMessageState state, time_t time, bool_t is_read, bool_t is_incoming);
/**
* Acquire a reference to the chat room.
* @param[in] cr The chat room.
* @return The same chat room.
**/
LINPHONE_PUBLIC LinphoneChatRoom *linphone_chat_room_ref(LinphoneChatRoom *cr);
/**
* Release reference to the chat room.
* @param[in] cr The chat room.
**/
LINPHONE_PUBLIC void linphone_chat_room_unref(LinphoneChatRoom *cr);
/**
* Retrieve the user pointer associated with the chat room.
* @param[in] cr The chat room.
* @return The user pointer associated with the chat room.
**/
LINPHONE_PUBLIC void *linphone_chat_room_get_user_data(const LinphoneChatRoom *cr);
/**
* Assign a user pointer to the chat room.
* @param[in] cr The chat room.
* @param[in] ud The user pointer to associate with the chat room.
**/
LINPHONE_PUBLIC void linphone_chat_room_set_user_data(LinphoneChatRoom *cr, void *ud);
/**
* Create a message attached to a dedicated chat room with a particular content.
* Use #linphone_chat_room_send_message to initiate the transfer
* @param cr the chat room.
* @param initial_content #LinphoneContent initial content. #LinphoneCoreVTable.file_transfer_send is invoked later to notify file transfer progress and collect next chunk of the message if #LinphoneContent.data is NULL.
* @return a new #LinphoneChatMessage
*/
LINPHONE_PUBLIC LinphoneChatMessage* linphone_chat_room_create_file_transfer_message(LinphoneChatRoom *cr, const LinphoneContent* initial_content);
/**
* get peer address \link linphone_core_get_chat_room() associated to \endlink this #LinphoneChatRoom
* @param cr #LinphoneChatRoom object
* @return #LinphoneAddress peer address
*/
LINPHONE_PUBLIC const LinphoneAddress* linphone_chat_room_get_peer_address(LinphoneChatRoom *cr);
/**
* Send a message to peer member of this chat room.
* @deprecated Use linphone_chat_room_send_chat_message() instead.
* @param cr #LinphoneChatRoom object
* @param msg message to be sent
*/
LINPHONE_PUBLIC LINPHONE_DEPRECATED void linphone_chat_room_send_message(LinphoneChatRoom *cr, const char *msg);
/**
* Send a message to peer member of this chat room.
* @param cr #LinphoneChatRoom object
* @param msg #LinphoneChatMessage message to be sent
* @param status_cb LinphoneChatMessageStateChangeCb status callback invoked when message is delivered or could not be delivered. May be NULL
* @param ud user data for the status cb.
* @deprecated Use linphone_chat_room_send_chat_message() instead.
* @note The LinphoneChatMessage must not be destroyed until the the callback is called.
* The LinphoneChatMessage reference is transfered to the function and thus doesn't need to be unref'd by the application.
*/
LINPHONE_PUBLIC LINPHONE_DEPRECATED void linphone_chat_room_send_message2(LinphoneChatRoom *cr, LinphoneChatMessage* msg,LinphoneChatMessageStateChangedCb status_cb,void* ud);
/**
* Send a message to peer member of this chat room.
* @param[in] cr LinphoneChatRoom object
* @param[in] msg LinphoneChatMessage object
* The state of the message sending will be notified via the callbacks defined in the LinphoneChatMessageCbs object that can be obtained
* by calling linphone_chat_message_get_callbacks().
* The LinphoneChatMessage reference is transfered to the function and thus doesn't need to be unref'd by the application.
*/
LINPHONE_PUBLIC void linphone_chat_room_send_chat_message(LinphoneChatRoom *cr, LinphoneChatMessage *msg);
/**
* Mark all messages of the conversation as read
* @param[in] cr The #LinphoneChatRoom object corresponding to the conversation.
*/
LINPHONE_PUBLIC void linphone_chat_room_mark_as_read(LinphoneChatRoom *cr);
/**
* Delete a message from the chat room history.
* @param[in] cr The #LinphoneChatRoom object corresponding to the conversation.
* @param[in] msg The #LinphoneChatMessage object to remove.
*/
LINPHONE_PUBLIC void linphone_chat_room_delete_message(LinphoneChatRoom *cr, LinphoneChatMessage *msg);
/**
* Delete all messages from the history
* @param[in] cr The #LinphoneChatRoom object corresponding to the conversation.
*/
LINPHONE_PUBLIC void linphone_chat_room_delete_history(LinphoneChatRoom *cr);
/**
* Gets the number of messages in a chat room.
* @param[in] cr The #LinphoneChatRoom object corresponding to the conversation for which size has to be computed
* @return the number of messages.
*/
LINPHONE_PUBLIC int linphone_chat_room_get_history_size(LinphoneChatRoom *cr);
/**
* Gets nb_message most recent messages from cr chat room, sorted from oldest to most recent.
* @param[in] cr The #LinphoneChatRoom object corresponding to the conversation for which messages should be retrieved
* @param[in] nb_message Number of message to retrieve. 0 means everything.
* @return \bctbx_list{LinphoneChatMessage}
*/
LINPHONE_PUBLIC bctbx_list_t *linphone_chat_room_get_history(LinphoneChatRoom *cr,int nb_message);
/**
* Gets the partial list of messages in the given range, sorted from oldest to most recent.
* @param[in] cr The #LinphoneChatRoom object corresponding to the conversation for which messages should be retrieved
* @param[in] begin The first message of the range to be retrieved. History most recent message has index 0.
* @param[in] end The last message of the range to be retrieved. History oldest message has index of history size - 1 (use #linphone_chat_room_get_history_size to retrieve history size)
* @return \bctbx_list{LinphoneChatMessage}
*/
LINPHONE_PUBLIC bctbx_list_t *linphone_chat_room_get_history_range(LinphoneChatRoom *cr, int begin, int end);
LINPHONE_PUBLIC LinphoneChatMessage * linphone_chat_room_find_message(LinphoneChatRoom *cr, const char *message_id);
/**
* Notifies the destination of the chat message being composed that the user is typing a new message.
* @param[in] cr The #LinphoneChatRoom object corresponding to the conversation for which a new message is being typed.
*/
LINPHONE_PUBLIC void linphone_chat_room_compose(LinphoneChatRoom *cr);
/**
* Tells whether the remote is currently composing a message.
* @param[in] cr The #LinphoneChatRoom object corresponding to the conversation.
* @return TRUE if the remote is currently composing a message, FALSE otherwise.
*/
LINPHONE_PUBLIC bool_t linphone_chat_room_is_remote_composing(const LinphoneChatRoom *cr);
/**
* Gets the number of unread messages in the chatroom.
* @param[in] cr The #LinphoneChatRoom object corresponding to the conversation.
* @return the number of unread messages.
*/
LINPHONE_PUBLIC int linphone_chat_room_get_unread_messages_count(LinphoneChatRoom *cr);
/**
* Returns back pointer to #LinphoneCore object.
* @deprecated use linphone_chat_room_get_core()
**/
LINPHONE_PUBLIC LINPHONE_DEPRECATED LinphoneCore* linphone_chat_room_get_lc(LinphoneChatRoom *cr);
/**
* Returns back pointer to #LinphoneCore object.
**/
LINPHONE_PUBLIC LinphoneCore* linphone_chat_room_get_core(LinphoneChatRoom *cr);
/**
* When realtime text is enabled #linphone_call_params_realtime_text_enabled, #LinphoneCoreIsComposingReceivedCb is call everytime a char is received from peer.
* At the end of remote typing a regular #LinphoneChatMessage is received with committed data from #LinphoneCoreMessageReceivedCb.
* @param[in] cr #LinphoneChatRoom object
* @returns RFC 4103/T.140 char
*/
LINPHONE_PUBLIC uint32_t linphone_chat_room_get_char(const LinphoneChatRoom *cr);
/**
* Returns true if lime is available for given peer
*
* @return true if zrtp secrets have already been shared and ready to use
*/
LINPHONE_PUBLIC bool_t linphone_chat_room_lime_available(LinphoneChatRoom *cr);
/**
* Returns an list of chat rooms
* @param[in] lc #LinphoneCore object
* @return \bctbx_list{LinphoneChatRoom}
**/
LINPHONE_PUBLIC const bctbx_list_t* linphone_core_get_chat_rooms(LinphoneCore *lc);
/**
* Get the LinphoneChatRoomCbs object associated with the LinphoneChatRoom.
* @param[in] room LinphoneChatRoom object
* @return The LinphoneChatRoomCbs object associated with the LinphoneChatRoom.
*/
LINPHONE_PUBLIC LinphoneChatRoomCbs * linphone_chat_room_get_callbacks(const LinphoneChatRoom *room);
/**
* Acquire a reference to the LinphoneChatRoomCbs object.
* @param[in] cbs LinphoneChatRoomCbs object.
* @return The same LinphoneChatRoomCbs object.
*/
LINPHONE_PUBLIC LinphoneChatRoomCbs * linphone_chat_room_cbs_ref(LinphoneChatRoomCbs *cbs);
/**
* Release reference to the LinphoneChatRoomCbs object.
* @param[in] cbs LinphoneChatRoomCbs object.
*/
LINPHONE_PUBLIC void linphone_chat_room_cbs_unref(LinphoneChatRoomCbs *cbs);
/**
* Retrieve the user pointer associated with the LinphoneChatRoomCbs object.
* @param[in] cbs LinphoneChatRoomCbs object.
* @return The user pointer associated with the LinphoneChatRoomCbs object.
*/
LINPHONE_PUBLIC void *linphone_chat_room_cbs_get_user_data(const LinphoneChatRoomCbs *cbs);
/**
* Assign a user pointer to the LinphoneChatRoomCbs object.
* @param[in] cbs LinphoneChatRoomCbs object.
* @param[in] ud The user pointer to associate with the LinphoneChatRoomCbs object.
*/
LINPHONE_PUBLIC void linphone_chat_room_cbs_set_user_data(LinphoneChatRoomCbs *cbs, void *ud);
/**
* Get the message state changed callback.
* @param[in] cbs LinphoneChatRoomCbs object.
* @return The current message state changed callback.
*/
LINPHONE_PUBLIC LinphoneChatRoomCbsMsgStateChangedCb linphone_chat_room_cbs_get_msg_state_changed(const LinphoneChatRoomCbs *cbs);
/**
* Set the message state changed callback.
* @param[in] cbs LinphoneChatRoomCbs object.
* @param[in] cb The message state changed callback to be used.
*/
LINPHONE_PUBLIC void linphone_chat_room_cbs_set_msg_state_changed(LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsMsgStateChangedCb cb);
/**
* Get the file transfer receive callback.
* @param[in] cbs LinphoneChatRoomCbs object.
* @return The current file transfer receive callback.
*/
LINPHONE_PUBLIC LinphoneChatRoomCbsFileTransferRecvCb linphone_chat_room_cbs_get_file_transfer_recv(const LinphoneChatRoomCbs *cbs);
/**
* Set the file transfer receive callback.
* @param[in] cbs LinphoneChatRoomCbs object.
* @param[in] cb The file transfer receive callback to be used.
*/
LINPHONE_PUBLIC void linphone_chat_room_cbs_set_file_transfer_recv(LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsFileTransferRecvCb cb);
/**
* Get the file transfer send callback.
* @param[in] cbs LinphoneChatRoomCbs object.
* @return The current file transfer send callback.
*/
LINPHONE_PUBLIC LinphoneChatRoomCbsFileTransferSendCb linphone_chat_room_cbs_get_file_transfer_send(const LinphoneChatRoomCbs *cbs);
/**
* Set the file transfer send callback.
* @param[in] cbs LinphoneChatRoomCbs object.
* @param[in] cb The file transfer send callback to be used.
*/
LINPHONE_PUBLIC void linphone_chat_room_cbs_set_file_transfer_send(LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsFileTransferSendCb cb);
/**
* Get the file transfer progress indication callback.
* @param[in] cbs LinphoneChatRoomCbs object.
* @return The current file transfer progress indication callback.
*/
LINPHONE_PUBLIC LinphoneChatRoomCbsFileTransferProgressIndicationCb linphone_chat_room_cbs_get_file_transfer_progress_indication(const LinphoneChatRoomCbs *cbs);
/**
* Set the file transfer progress indication callback.
* @param[in] cbs LinphoneChatRoomCbs object.
* @param[in] cb The file transfer progress indication callback to be used.
*/
LINPHONE_PUBLIC void linphone_chat_room_cbs_set_file_transfer_progress_indication(LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsFileTransferProgressIndicationCb cb);
LINPHONE_PUBLIC unsigned int linphone_chat_message_store(LinphoneChatMessage *msg);
/**
* Returns a #LinphoneChatMessageState as a string.
*/
LINPHONE_PUBLIC const char* linphone_chat_message_state_to_string(const LinphoneChatMessageState state);
/**
* Get the state of the message
*@param message #LinphoneChatMessage obj
*@return #LinphoneChatMessageState
*/
LINPHONE_PUBLIC LinphoneChatMessageState linphone_chat_message_get_state(const LinphoneChatMessage* message);
/**
* Duplicate a LinphoneChatMessage
**/
LINPHONE_PUBLIC LinphoneChatMessage* linphone_chat_message_clone(const LinphoneChatMessage* message);
/**
* Acquire a reference to the chat message.
* @param msg the chat message
* @return the same chat message
**/
LINPHONE_PUBLIC LinphoneChatMessage * linphone_chat_message_ref(LinphoneChatMessage *msg);
/**
* Release reference to the chat message.
* @param msg the chat message.
**/
LINPHONE_PUBLIC void linphone_chat_message_unref(LinphoneChatMessage *msg);
/**
* Destroys a LinphoneChatMessage.
**/
LINPHONE_PUBLIC void linphone_chat_message_destroy(LinphoneChatMessage* msg);
/** @deprecated Use linphone_chat_message_set_from_address() instead. */
#define linphone_chat_message_set_from(msg, addr) linphone_chat_message_set_from_address(msg, addr)
/**
* Set origin of the message
* @param[in] message #LinphoneChatMessage obj
* @param[in] from #LinphoneAddress origin of this message (copied)
*/
LINPHONE_PUBLIC void linphone_chat_message_set_from_address(LinphoneChatMessage* message, const LinphoneAddress* from);
/** @deprecated Use linphone_chat_message_get_from_address() instead. */
#define linphone_chat_message_get_from(msg) linphone_chat_message_get_from_address(msg)
/**
* Get origin of the message
* @param[in] message #LinphoneChatMessage obj
* @return #LinphoneAddress
*/
LINPHONE_PUBLIC const LinphoneAddress* linphone_chat_message_get_from_address(const LinphoneChatMessage* message);
#define linphone_chat_message_set_to(msg, addr) linphone_chat_message_set_to_address(msg, addr)
/**
* Set destination of the message
* @param[in] message #LinphoneChatMessage obj
* @param[in] addr #LinphoneAddress destination of this message (copied)
*/
LINPHONE_PUBLIC void linphone_chat_message_set_to_address(LinphoneChatMessage* message, const LinphoneAddress* addr);
/** @deprecated Use linphone_chat_message_get_to_address() instead. */
#define linphone_chat_message_get_to(msg) linphone_chat_message_get_to_address(msg)
/**
* Get destination of the message
* @param[in] message #LinphoneChatMessage obj
* @return #LinphoneAddress
*/
LINPHONE_PUBLIC const LinphoneAddress* linphone_chat_message_get_to_address(const LinphoneChatMessage* message);
/**
* Linphone message can carry external body as defined by rfc2017
* @param message #LinphoneChatMessage
* @return external body url or NULL if not present.
*/
LINPHONE_PUBLIC const char* linphone_chat_message_get_external_body_url(const LinphoneChatMessage* message);
/**
* Linphone message can carry external body as defined by rfc2017
*
* @param message a LinphoneChatMessage
* @param url ex: access-type=URL; URL="http://www.foo.com/file"
*/
LINPHONE_PUBLIC void linphone_chat_message_set_external_body_url(LinphoneChatMessage* message,const char* url);
/**
* Get the file_transfer_information (used by call backs to recover informations during a rcs file transfer)
*
* @param message #LinphoneChatMessage
* @return a pointer to the LinphoneContent structure or NULL if not present.
*/
LINPHONE_PUBLIC const LinphoneContent* linphone_chat_message_get_file_transfer_information(const LinphoneChatMessage* message);
/**
* Start the download of the file from remote server
*
* @param message #LinphoneChatMessage
* @param status_cb LinphoneChatMessageStateChangeCb status callback invoked when file is downloaded or could not be downloaded
* @param ud user data
* @deprecated Use linphone_chat_message_download_file() instead.
*/
LINPHONE_PUBLIC LINPHONE_DEPRECATED void linphone_chat_message_start_file_download(LinphoneChatMessage* message, LinphoneChatMessageStateChangedCb status_cb, void* ud);
/**
* Start the download of the file referenced in a LinphoneChatMessage from remote server.
* @param[in] message LinphoneChatMessage object.
*/
LINPHONE_PUBLIC int linphone_chat_message_download_file(LinphoneChatMessage *message);
/**
* Cancel an ongoing file transfer attached to this message.(upload or download)
* @param msg #LinphoneChatMessage
*/
LINPHONE_PUBLIC void linphone_chat_message_cancel_file_transfer(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.
* @param message #LinphoneChatMessage
* @return the application-specific data or NULL if none has been stored.
*/
LINPHONE_PUBLIC const char* linphone_chat_message_get_appdata(const LinphoneChatMessage* message);
/**
* 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.
*
* Invoking this function will attempt to update the message storage to reflect the changeif it is
* enabled.
*
* @param message #LinphoneChatMessage
* @param data the data to store into the message
*/
LINPHONE_PUBLIC void linphone_chat_message_set_appdata(LinphoneChatMessage* message, const char* data);
/**
* Get text part of this message
* @return text or NULL if no text.
*/
LINPHONE_PUBLIC const char* linphone_chat_message_get_text(const LinphoneChatMessage* message);
/**
* Get the time the message was sent.
*/
LINPHONE_PUBLIC time_t linphone_chat_message_get_time(const LinphoneChatMessage* message);
/**
* User pointer get function
*/
LINPHONE_PUBLIC void* linphone_chat_message_get_user_data(const LinphoneChatMessage* message);
/**
*User pointer set function
*/
LINPHONE_PUBLIC void linphone_chat_message_set_user_data(LinphoneChatMessage* message,void*);
/**
* Returns the chatroom this message belongs to.
**/
LINPHONE_PUBLIC LinphoneChatRoom* linphone_chat_message_get_chat_room(LinphoneChatMessage *msg);
LINPHONE_PUBLIC const LinphoneAddress* linphone_chat_message_get_peer_address(LinphoneChatMessage *msg);
/**
* Returns the origin address of a message if it was a outgoing message, or the destination address if it was an incoming message.
*@param message #LinphoneChatMessage obj
*@return #LinphoneAddress
*/
LINPHONE_PUBLIC LinphoneAddress *linphone_chat_message_get_local_address(const LinphoneChatMessage* message);
/**
* Add custom headers to the message.
* @param message the message
* @param header_name name of the header
* @param header_value header value
**/
LINPHONE_PUBLIC void linphone_chat_message_add_custom_header(LinphoneChatMessage* message, const char *header_name, const char *header_value);
/**
* Retrieve a custom header value given its name.
* @param message the message
* @param header_name header name searched
**/
LINPHONE_PUBLIC const char * linphone_chat_message_get_custom_header(LinphoneChatMessage* message, const char *header_name);
/**
* Removes a custom header from the message.
* @param message the message
* @param header_name name of the header to remove
**/
LINPHONE_PUBLIC void linphone_chat_message_remove_custom_header(LinphoneChatMessage *msg, const char *header_name);
/**
* Returns TRUE if the message has been read, otherwise returns FALSE.
* @param message the message
**/
LINPHONE_PUBLIC bool_t linphone_chat_message_is_read(LinphoneChatMessage* message);
/**
* Returns TRUE if the message has been sent, returns FALSE if the message has been received.
* @param message the message
**/
LINPHONE_PUBLIC bool_t linphone_chat_message_is_outgoing(LinphoneChatMessage* message);
/**
* Returns the id used to identify this message in the storage database
* @param message the message
* @return the id
*/
LINPHONE_PUBLIC unsigned int linphone_chat_message_get_storage_id(LinphoneChatMessage* message);
LINPHONE_PUBLIC LinphoneReason linphone_chat_message_get_reason(LinphoneChatMessage* msg);
/**
* Get full details about delivery error of a chat message.
* @param msg a LinphoneChatMessage
* @return a LinphoneErrorInfo describing the details.
**/
LINPHONE_PUBLIC const LinphoneErrorInfo *linphone_chat_message_get_error_info(const LinphoneChatMessage *msg);
/**
* Set the path to the file to read from or write to during the file transfer.
* @param[in] msg LinphoneChatMessage object
* @param[in] filepath The path to the file to use for the file transfer.
*/
LINPHONE_PUBLIC void linphone_chat_message_set_file_transfer_filepath(LinphoneChatMessage *msg, const char *filepath);
/**
* Get the path to the file to read from or write to during the file transfer.
* @param[in] msg LinphoneChatMessage object
* @return The path to the file to use for the file transfer.
*/
LINPHONE_PUBLIC const char * linphone_chat_message_get_file_transfer_filepath(LinphoneChatMessage *msg);
/**
* Fulfill a chat message char by char. Message linked to a Real Time Text Call send char in realtime following RFC 4103/T.140
* To commit a message, use #linphone_chat_room_send_message
* @param[in] msg LinphoneChatMessage
* @param[in] character T.140 char
* @returns 0 if succeed.
*/
LINPHONE_PUBLIC int linphone_chat_message_put_char(LinphoneChatMessage *msg,uint32_t character);
/**
* Get the message identifier.
* It is used to identify a message so that it can be notified as delivered and/or displayed.
* @param[in] cm LinphoneChatMessage object
* @return The message identifier.
*/
LINPHONE_PUBLIC const char* linphone_chat_message_get_message_id(const LinphoneChatMessage *cm);
/**
* get Curent Call associated to this chatroom if any
* To commit a message, use #linphone_chat_room_send_message
* @param[in] room LinphoneChatRomm
* @returns LinphoneCall or NULL.
*/
LINPHONE_PUBLIC LinphoneCall *linphone_chat_room_get_call(const LinphoneChatRoom *room);
/**
* Get the LinphoneChatMessageCbs object associated with the LinphoneChatMessage.
* @param[in] msg LinphoneChatMessage object
* @return The LinphoneChatMessageCbs object associated with the LinphoneChatMessage.
* @deprecated Use linphone_chat_room_get_callbacks() instead.
*/
LINPHONE_PUBLIC LinphoneChatMessageCbs * linphone_chat_message_get_callbacks(const LinphoneChatMessage *msg);
/**
* Acquire a reference to the LinphoneChatMessageCbs object.
* @param[in] cbs LinphoneChatMessageCbs object.
* @return The same LinphoneChatMessageCbs object.
* @deprecated Use linphone_chat_room_cbs_ref() instead.
*/
LINPHONE_PUBLIC LinphoneChatMessageCbs * linphone_chat_message_cbs_ref(LinphoneChatMessageCbs *cbs);
/**
* Release reference to the LinphoneChatMessageCbs object.
* @param[in] cbs LinphoneChatMessageCbs object.
* @deprecated Use linphone_chat_room_cbs_unref() instead.
*/
LINPHONE_PUBLIC void linphone_chat_message_cbs_unref(LinphoneChatMessageCbs *cbs);
/**
* Retrieve the user pointer associated with the LinphoneChatMessageCbs object.
* @param[in] cbs LinphoneChatMessageCbs object.
* @return The user pointer associated with the LinphoneChatMessageCbs object.
* @deprecated Use linphone_chat_room_cbs_get_user_data() instead.
*/
LINPHONE_PUBLIC void *linphone_chat_message_cbs_get_user_data(const LinphoneChatMessageCbs *cbs);
/**
* Assign a user pointer to the LinphoneChatMessageCbs object.
* @param[in] cbs LinphoneChatMessageCbs object.
* @param[in] ud The user pointer to associate with the LinphoneChatMessageCbs object.
* @deprecated Use linphone_chat_room_cbs_set_user_data() instead.
*/
LINPHONE_PUBLIC void linphone_chat_message_cbs_set_user_data(LinphoneChatMessageCbs *cbs, void *ud);
/**
* Get the message state changed callback.
* @param[in] cbs LinphoneChatMessageCbs object.
* @return The current message state changed callback.
* @deprecated Use linphone_chat_room_cbs_get_msg_state_changed() instead.
*/
LINPHONE_PUBLIC LinphoneChatMessageCbsMsgStateChangedCb linphone_chat_message_cbs_get_msg_state_changed(const LinphoneChatMessageCbs *cbs);
/**
* Set the message state changed callback.
* @param[in] cbs LinphoneChatMessageCbs object.
* @param[in] cb The message state changed callback to be used.
* @deprecated Use linphone_chat_room_cbs_set_msg_state_changed() instead.
*/
LINPHONE_PUBLIC void linphone_chat_message_cbs_set_msg_state_changed(LinphoneChatMessageCbs *cbs, LinphoneChatMessageCbsMsgStateChangedCb cb);
/**
* Get the file transfer receive callback.
* @param[in] cbs LinphoneChatMessageCbs object.
* @return The current file transfer receive callback.
* @deprecated Use linphone_chat_room_cbs_get_file_transfer_recv() instead.
*/
LINPHONE_PUBLIC LinphoneChatMessageCbsFileTransferRecvCb linphone_chat_message_cbs_get_file_transfer_recv(const LinphoneChatMessageCbs *cbs);
/**
* Set the file transfer receive callback.
* @param[in] cbs LinphoneChatMessageCbs object.
* @param[in] cb The file transfer receive callback to be used.
* @deprecated Use linphone_chat_room_cbs_set_file_transfer_recv() instead.
*/
LINPHONE_PUBLIC void linphone_chat_message_cbs_set_file_transfer_recv(LinphoneChatMessageCbs *cbs, LinphoneChatMessageCbsFileTransferRecvCb cb);
/**
* Get the file transfer send callback.
* @param[in] cbs LinphoneChatMessageCbs object.
* @return The current file transfer send callback.
* @deprecated Use linphone_chat_room_cbs_get_file_transfer_send() instead.
*/
LINPHONE_PUBLIC LinphoneChatMessageCbsFileTransferSendCb linphone_chat_message_cbs_get_file_transfer_send(const LinphoneChatMessageCbs *cbs);
/**
* Set the file transfer send callback.
* @param[in] cbs LinphoneChatMessageCbs object.
* @param[in] cb The file transfer send callback to be used.
* @deprecated Use linphone_chat_room_cbs_set_file_transfer_send() instead.
*/
LINPHONE_PUBLIC void linphone_chat_message_cbs_set_file_transfer_send(LinphoneChatMessageCbs *cbs, LinphoneChatMessageCbsFileTransferSendCb cb);
/**
* Get the file transfer progress indication callback.
* @param[in] cbs LinphoneChatMessageCbs object.
* @return The current file transfer progress indication callback.
* @deprecated Use linphone_chat_room_cbs_get_file_transfer_progress_indication() instead.
*/
LINPHONE_PUBLIC LinphoneChatMessageCbsFileTransferProgressIndicationCb linphone_chat_message_cbs_get_file_transfer_progress_indication(const LinphoneChatMessageCbs *cbs);
/**
* Set the file transfer progress indication callback.
* @param[in] cbs LinphoneChatMessageCbs object.
* @param[in] cb The file transfer progress indication callback to be used.
* @deprecated Use linphone_chat_room_cbs_set_file_transfer_progress_indication() instead.
*/
LINPHONE_PUBLIC void linphone_chat_message_cbs_set_file_transfer_progress_indication(LinphoneChatMessageCbs *cbs, LinphoneChatMessageCbsFileTransferProgressIndicationCb cb);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* LINPHONE_CHAT_H_ */

View file

@ -543,639 +543,7 @@ LINPHONE_PUBLIC const char *linphone_registration_state_to_string(LinphoneRegist
#include "linphone/auth_info.h"
#include "linphone/friendlist.h"
#include "linphone/linphone_proxy_config.h"
/**
* @addtogroup chatroom
* @{
*/
/**
* An object to handle the callbacks for the handling a LinphoneChatMessage objects.
*/
typedef struct _LinphoneChatMessageCbs LinphoneChatMessageCbs;
/**
* A chat room message to hold content to be sent.
* <br> Can be created by linphone_chat_room_create_message().
*/
typedef struct _LinphoneChatMessage LinphoneChatMessage;
/**
* A chat room is the place where text messages are exchanged.
* <br> Can be created by linphone_core_create_chat_room().
*/
typedef struct _LinphoneChatRoom LinphoneChatRoom;
/**
* LinphoneChatMessageState is used to notify if messages have been succesfully delivered or not.
*/
typedef enum _LinphoneChatMessageState {
LinphoneChatMessageStateIdle, /**< Initial state */
LinphoneChatMessageStateInProgress, /**< Delivery in progress */
LinphoneChatMessageStateDelivered, /**< Message successfully delivered and acknowledged by remote end point */
LinphoneChatMessageStateNotDelivered, /**< Message was not delivered */
LinphoneChatMessageStateFileTransferError, /**< Message was received(and acknowledged) but cannot get file from server */
LinphoneChatMessageStateFileTransferDone /**< File transfer has been completed successfully. */
} LinphoneChatMessageState;
typedef enum _LinphoneLimeState {
LinphoneLimeDisabled, /**< Lime is not used at all */
LinphoneLimeMandatory, /**< Lime is always used */
LinphoneLimePreferred, /**< Lime is used only if we already shared a secret with remote */
} LinphoneLimeState;
/**
* Call back used to notify message delivery status
* @param msg #LinphoneChatMessage object
* @param status LinphoneChatMessageState
* @param ud application user data
* @deprecated
*/
typedef void (*LinphoneChatMessageStateChangedCb)(LinphoneChatMessage* msg,LinphoneChatMessageState state,void* ud);
/**
* Call back used to notify message delivery status
* @param msg #LinphoneChatMessage object
* @param status LinphoneChatMessageState
*/
typedef void (*LinphoneChatMessageCbsMsgStateChangedCb)(LinphoneChatMessage* msg, LinphoneChatMessageState state);
/**
* File transfer receive callback prototype. This function is called by the core upon an incoming File transfer is started. This function may be call several time for the same file in case of large file.
* @param message #LinphoneChatMessage message from which the body is received.
* @param content #LinphoneContent incoming content information
* @param buffer #LinphoneBuffer holding the received data. Empty buffer means end of file.
*/
typedef void (*LinphoneChatMessageCbsFileTransferRecvCb)(LinphoneChatMessage *message, const LinphoneContent* content, const LinphoneBuffer *buffer);
/**
* File transfer send callback prototype. This function is called by the core when an outgoing file transfer is started. This function is called until size is set to 0.
* @param message #LinphoneChatMessage message from which the body is received.
* @param content #LinphoneContent outgoing content
* @param offset the offset in the file from where to get the data to be sent
* @param size the number of bytes expected by the framework
* @return A LinphoneBuffer object holding the data written by the application. An empty buffer means end of file.
*/
typedef LinphoneBuffer * (*LinphoneChatMessageCbsFileTransferSendCb)(LinphoneChatMessage *message, const LinphoneContent* content, size_t offset, size_t size);
/**
* File transfer progress indication callback prototype.
* @param message #LinphoneChatMessage message from which the body is received.
* @param content #LinphoneContent incoming content information
* @param offset The number of bytes sent/received since the beginning of the transfer.
* @param total The total number of bytes to be sent/received.
*/
typedef void (*LinphoneChatMessageCbsFileTransferProgressIndicationCb)(LinphoneChatMessage *message, const LinphoneContent* content, size_t offset, size_t total);
/**
* Sets the database filename where chat messages will be stored.
* If the file does not exist, it will be created.
* @param[in] lc LinphoneCore object
* @param[in] path The filesystem path to the database to stare the chat messages
* @ingroup initializing
**/
LINPHONE_PUBLIC void linphone_core_set_chat_database_path(LinphoneCore *lc, const char *path);
/**
* Get path to the database file used for storing chat messages.
* @param lc the linphone core
* @return file path or NULL if not exist
**/
LINPHONE_PUBLIC const char *linphone_core_get_chat_database_path(const LinphoneCore *lc);
/**
* Get a chat room whose peer is the supplied address. If it does not exist yet, it will be created.
* No reference is transfered to the application. The LinphoneCore keeps a reference on the chat room.
* @param lc the linphone core
* @param addr a linphone address.
* @return #LinphoneChatRoom where messaging can take place.
**/
LINPHONE_PUBLIC LinphoneChatRoom *linphone_core_get_chat_room(LinphoneCore *lc, const LinphoneAddress *addr);
/**
* Get a chat room for messaging from a sip uri like sip:joe@sip.linphone.org. If it does not exist yet, it will be created.
* No reference is transfered to the application. The LinphoneCore keeps a reference on the chat room.
* @param lc A #LinphoneCore object
* @param to The destination address for messages.
* @return #LinphoneChatRoom where messaging can take place.
**/
LINPHONE_PUBLIC LinphoneChatRoom *linphone_core_get_chat_room_from_uri(LinphoneCore *lc, const char *to);
/**
* Removes a chatroom including all message history from the LinphoneCore.
* @param lc A #LinphoneCore object
* @param cr A #LinphoneChatRoom object
**/
LINPHONE_PUBLIC void linphone_core_delete_chat_room(LinphoneCore *lc, LinphoneChatRoom *cr);
/**
* Inconditionnaly disable incoming chat messages.
* @param lc A #LinphoneCore object
* @param deny_reason the deny reason (#LinphoneReasonNone has no effect).
**/
LINPHONE_PUBLIC void linphone_core_disable_chat(LinphoneCore *lc, LinphoneReason deny_reason);
/**
* Enable reception of incoming chat messages.
* By default it is enabled but it can be disabled with linphone_core_disable_chat().
* @param lc A #LinphoneCore object
**/
LINPHONE_PUBLIC void linphone_core_enable_chat(LinphoneCore *lc);
/**
* Returns whether chat is enabled.
* @param lc A #LinphoneCore object
**/
LINPHONE_PUBLIC bool_t linphone_core_chat_enabled(const LinphoneCore *lc);
/**
* Destroy a LinphoneChatRoom.
* @param cr #LinphoneChatRoom object
* @deprecated Use linphone_chat_room_unref() instead.
*/
LINPHONE_PUBLIC LINPHONE_DEPRECATED void linphone_chat_room_destroy(LinphoneChatRoom *cr);
/**
* Create a message attached to a dedicated chat room;
* @param cr the chat room.
* @param message text message, NULL if absent.
* @return a new #LinphoneChatMessage
*/
LINPHONE_PUBLIC LinphoneChatMessage* linphone_chat_room_create_message(LinphoneChatRoom *cr,const char* message);
/**
* Create a message attached to a dedicated chat room;
* @param cr the chat room.
* @param message text message, NULL if absent.
* @param external_body_url the URL given in external body or NULL.
* @param state the LinphoneChatMessage.State of the message.
* @param time the time_t at which the message has been received/sent.
* @param is_read TRUE if the message should be flagged as read, FALSE otherwise.
* @param is_incoming TRUE if the message has been received, FALSE otherwise.
* @return a new #LinphoneChatMessage
*/
LINPHONE_PUBLIC LinphoneChatMessage* linphone_chat_room_create_message_2(LinphoneChatRoom *cr, const char* message, const char* external_body_url, LinphoneChatMessageState state, time_t time, bool_t is_read, bool_t is_incoming);
/**
* Acquire a reference to the chat room.
* @param[in] cr The chat room.
* @return The same chat room.
**/
LINPHONE_PUBLIC LinphoneChatRoom *linphone_chat_room_ref(LinphoneChatRoom *cr);
/**
* Release reference to the chat room.
* @param[in] cr The chat room.
**/
LINPHONE_PUBLIC void linphone_chat_room_unref(LinphoneChatRoom *cr);
/**
* Retrieve the user pointer associated with the chat room.
* @param[in] cr The chat room.
* @return The user pointer associated with the chat room.
**/
LINPHONE_PUBLIC void *linphone_chat_room_get_user_data(const LinphoneChatRoom *cr);
/**
* Assign a user pointer to the chat room.
* @param[in] cr The chat room.
* @param[in] ud The user pointer to associate with the chat room.
**/
LINPHONE_PUBLIC void linphone_chat_room_set_user_data(LinphoneChatRoom *cr, void *ud);
/**
* Create a message attached to a dedicated chat room with a particular content.
* Use #linphone_chat_room_send_message to initiate the transfer
* @param cr the chat room.
* @param initial_content #LinphoneContent initial content. #LinphoneCoreVTable.file_transfer_send is invoked later to notify file transfer progress and collect next chunk of the message if #LinphoneContent.data is NULL.
* @return a new #LinphoneChatMessage
*/
LINPHONE_PUBLIC LinphoneChatMessage* linphone_chat_room_create_file_transfer_message(LinphoneChatRoom *cr, const LinphoneContent* initial_content);
/**
* get peer address \link linphone_core_get_chat_room() associated to \endlink this #LinphoneChatRoom
* @param cr #LinphoneChatRoom object
* @return #LinphoneAddress peer address
*/
LINPHONE_PUBLIC const LinphoneAddress* linphone_chat_room_get_peer_address(LinphoneChatRoom *cr);
/**
* Send a message to peer member of this chat room.
* @deprecated Use linphone_chat_room_send_chat_message() instead.
* @param cr #LinphoneChatRoom object
* @param msg message to be sent
*/
LINPHONE_PUBLIC LINPHONE_DEPRECATED void linphone_chat_room_send_message(LinphoneChatRoom *cr, const char *msg);
/**
* Send a message to peer member of this chat room.
* @param cr #LinphoneChatRoom object
* @param msg #LinphoneChatMessage message to be sent
* @param status_cb LinphoneChatMessageStateChangeCb status callback invoked when message is delivered or could not be delivered. May be NULL
* @param ud user data for the status cb.
* @deprecated Use linphone_chat_room_send_chat_message() instead.
* @note The LinphoneChatMessage must not be destroyed until the the callback is called.
* The LinphoneChatMessage reference is transfered to the function and thus doesn't need to be unref'd by the application.
*/
LINPHONE_PUBLIC LINPHONE_DEPRECATED void linphone_chat_room_send_message2(LinphoneChatRoom *cr, LinphoneChatMessage* msg,LinphoneChatMessageStateChangedCb status_cb,void* ud);
/**
* Send a message to peer member of this chat room.
* @param[in] cr LinphoneChatRoom object
* @param[in] msg LinphoneChatMessage object
* The state of the message sending will be notified via the callbacks defined in the LinphoneChatMessageCbs object that can be obtained
* by calling linphone_chat_message_get_callbacks().
* The LinphoneChatMessage reference is transfered to the function and thus doesn't need to be unref'd by the application.
*/
LINPHONE_PUBLIC void linphone_chat_room_send_chat_message(LinphoneChatRoom *cr, LinphoneChatMessage *msg);
/**
* Mark all messages of the conversation as read
* @param[in] cr The #LinphoneChatRoom object corresponding to the conversation.
*/
LINPHONE_PUBLIC void linphone_chat_room_mark_as_read(LinphoneChatRoom *cr);
/**
* Delete a message from the chat room history.
* @param[in] cr The #LinphoneChatRoom object corresponding to the conversation.
* @param[in] msg The #LinphoneChatMessage object to remove.
*/
LINPHONE_PUBLIC void linphone_chat_room_delete_message(LinphoneChatRoom *cr, LinphoneChatMessage *msg);
/**
* Delete all messages from the history
* @param[in] cr The #LinphoneChatRoom object corresponding to the conversation.
*/
LINPHONE_PUBLIC void linphone_chat_room_delete_history(LinphoneChatRoom *cr);
/**
* Gets the number of messages in a chat room.
* @param[in] cr The #LinphoneChatRoom object corresponding to the conversation for which size has to be computed
* @return the number of messages.
*/
LINPHONE_PUBLIC int linphone_chat_room_get_history_size(LinphoneChatRoom *cr);
/**
* Gets nb_message most recent messages from cr chat room, sorted from oldest to most recent.
* @param[in] cr The #LinphoneChatRoom object corresponding to the conversation for which messages should be retrieved
* @param[in] nb_message Number of message to retrieve. 0 means everything.
* @return \bctbx_list{LinphoneChatMessage}
*/
LINPHONE_PUBLIC bctbx_list_t *linphone_chat_room_get_history(LinphoneChatRoom *cr,int nb_message);
/**
* Gets the partial list of messages in the given range, sorted from oldest to most recent.
* @param[in] cr The #LinphoneChatRoom object corresponding to the conversation for which messages should be retrieved
* @param[in] begin The first message of the range to be retrieved. History most recent message has index 0.
* @param[in] end The last message of the range to be retrieved. History oldest message has index of history size - 1 (use #linphone_chat_room_get_history_size to retrieve history size)
* @return \bctbx_list{LinphoneChatMessage}
*/
LINPHONE_PUBLIC bctbx_list_t *linphone_chat_room_get_history_range(LinphoneChatRoom *cr, int begin, int end);
/**
* Notifies the destination of the chat message being composed that the user is typing a new message.
* @param[in] cr The #LinphoneChatRoom object corresponding to the conversation for which a new message is being typed.
*/
LINPHONE_PUBLIC void linphone_chat_room_compose(LinphoneChatRoom *cr);
/**
* Tells whether the remote is currently composing a message.
* @param[in] cr The #LinphoneChatRoom object corresponding to the conversation.
* @return TRUE if the remote is currently composing a message, FALSE otherwise.
*/
LINPHONE_PUBLIC bool_t linphone_chat_room_is_remote_composing(const LinphoneChatRoom *cr);
/**
* Gets the number of unread messages in the chatroom.
* @param[in] cr The #LinphoneChatRoom object corresponding to the conversation.
* @return the number of unread messages.
*/
LINPHONE_PUBLIC int linphone_chat_room_get_unread_messages_count(LinphoneChatRoom *cr);
/**
* Returns back pointer to #LinphoneCore object.
* @deprecated use linphone_chat_room_get_core()
**/
LINPHONE_PUBLIC LINPHONE_DEPRECATED LinphoneCore* linphone_chat_room_get_lc(LinphoneChatRoom *cr);
/**
* Returns back pointer to #LinphoneCore object.
**/
LINPHONE_PUBLIC LinphoneCore* linphone_chat_room_get_core(LinphoneChatRoom *cr);
/**
* When realtime text is enabled #linphone_call_params_realtime_text_enabled, #LinphoneCoreIsComposingReceivedCb is call everytime a char is received from peer.
* At the end of remote typing a regular #LinphoneChatMessage is received with committed data from #LinphoneCoreMessageReceivedCb.
* @param[in] cr #LinphoneChatRoom object
* @returns RFC 4103/T.140 char
*/
LINPHONE_PUBLIC uint32_t linphone_chat_room_get_char(const LinphoneChatRoom *cr);
/**
* Returns true if lime is available for given peer
*
* @return true if zrtp secrets have already been shared and ready to use
*/
LINPHONE_PUBLIC bool_t linphone_chat_room_lime_available(LinphoneChatRoom *cr);
/**
* Returns an list of chat rooms
* @param[in] lc #LinphoneCore object
* @return \bctbx_list{LinphoneChatRoom}
**/
LINPHONE_PUBLIC const bctbx_list_t* linphone_core_get_chat_rooms(LinphoneCore *lc);
LINPHONE_PUBLIC unsigned int linphone_chat_message_store(LinphoneChatMessage *msg);
/**
* Returns a #LinphoneChatMessageState as a string.
*/
LINPHONE_PUBLIC const char* linphone_chat_message_state_to_string(const LinphoneChatMessageState state);
/**
* Get the state of the message
*@param message #LinphoneChatMessage obj
*@return #LinphoneChatMessageState
*/
LINPHONE_PUBLIC LinphoneChatMessageState linphone_chat_message_get_state(const LinphoneChatMessage* message);
/**
* Duplicate a LinphoneChatMessage
**/
LINPHONE_PUBLIC LinphoneChatMessage* linphone_chat_message_clone(const LinphoneChatMessage* message);
/**
* Acquire a reference to the chat message.
* @param msg the chat message
* @return the same chat message
**/
LINPHONE_PUBLIC LinphoneChatMessage * linphone_chat_message_ref(LinphoneChatMessage *msg);
/**
* Release reference to the chat message.
* @param msg the chat message.
**/
LINPHONE_PUBLIC void linphone_chat_message_unref(LinphoneChatMessage *msg);
/**
* Destroys a LinphoneChatMessage.
**/
LINPHONE_PUBLIC void linphone_chat_message_destroy(LinphoneChatMessage* msg);
/** @deprecated Use linphone_chat_message_set_from_address() instead. */
#define linphone_chat_message_set_from(msg, addr) linphone_chat_message_set_from_address(msg, addr)
/**
* Set origin of the message
* @param[in] message #LinphoneChatMessage obj
* @param[in] from #LinphoneAddress origin of this message (copied)
*/
LINPHONE_PUBLIC void linphone_chat_message_set_from_address(LinphoneChatMessage* message, const LinphoneAddress* from);
/** @deprecated Use linphone_chat_message_get_from_address() instead. */
#define linphone_chat_message_get_from(msg) linphone_chat_message_get_from_address(msg)
/**
* Get origin of the message
* @param[in] message #LinphoneChatMessage obj
* @return #LinphoneAddress
*/
LINPHONE_PUBLIC const LinphoneAddress* linphone_chat_message_get_from_address(const LinphoneChatMessage* message);
#define linphone_chat_message_set_to(msg, addr) linphone_chat_message_set_to_address(msg, addr)
/**
* Set destination of the message
* @param[in] message #LinphoneChatMessage obj
* @param[in] addr #LinphoneAddress destination of this message (copied)
*/
LINPHONE_PUBLIC void linphone_chat_message_set_to_address(LinphoneChatMessage* message, const LinphoneAddress* addr);
/** @deprecated Use linphone_chat_message_get_to_address() instead. */
#define linphone_chat_message_get_to(msg) linphone_chat_message_get_to_address(msg)
/**
* Get destination of the message
* @param[in] message #LinphoneChatMessage obj
* @return #LinphoneAddress
*/
LINPHONE_PUBLIC const LinphoneAddress* linphone_chat_message_get_to_address(const LinphoneChatMessage* message);
/**
* Linphone message can carry external body as defined by rfc2017
* @param message #LinphoneChatMessage
* @return external body url or NULL if not present.
*/
LINPHONE_PUBLIC const char* linphone_chat_message_get_external_body_url(const LinphoneChatMessage* message);
/**
* Linphone message can carry external body as defined by rfc2017
*
* @param message a LinphoneChatMessage
* @param url ex: access-type=URL; URL="http://www.foo.com/file"
*/
LINPHONE_PUBLIC void linphone_chat_message_set_external_body_url(LinphoneChatMessage* message,const char* url);
/**
* Get the file_transfer_information (used by call backs to recover informations during a rcs file transfer)
*
* @param message #LinphoneChatMessage
* @return a pointer to the LinphoneContent structure or NULL if not present.
*/
LINPHONE_PUBLIC const LinphoneContent* linphone_chat_message_get_file_transfer_information(const LinphoneChatMessage* message);
/**
* Start the download of the file from remote server
*
* @param message #LinphoneChatMessage
* @param status_cb LinphoneChatMessageStateChangeCb status callback invoked when file is downloaded or could not be downloaded
* @param ud user data
* @deprecated Use linphone_chat_message_download_file() instead.
*/
LINPHONE_PUBLIC LINPHONE_DEPRECATED void linphone_chat_message_start_file_download(LinphoneChatMessage* message, LinphoneChatMessageStateChangedCb status_cb, void* ud);
/**
* Start the download of the file referenced in a LinphoneChatMessage from remote server.
* @param[in] message LinphoneChatMessage object.
*/
LINPHONE_PUBLIC int linphone_chat_message_download_file(LinphoneChatMessage *message);
/**
* Cancel an ongoing file transfer attached to this message.(upload or download)
* @param msg #LinphoneChatMessage
*/
LINPHONE_PUBLIC void linphone_chat_message_cancel_file_transfer(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.
* @param message #LinphoneChatMessage
* @return the application-specific data or NULL if none has been stored.
*/
LINPHONE_PUBLIC const char* linphone_chat_message_get_appdata(const LinphoneChatMessage* message);
/**
* 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.
*
* Invoking this function will attempt to update the message storage to reflect the changeif it is
* enabled.
*
* @param message #LinphoneChatMessage
* @param data the data to store into the message
*/
LINPHONE_PUBLIC void linphone_chat_message_set_appdata(LinphoneChatMessage* message, const char* data);
/**
* Get text part of this message
* @return text or NULL if no text.
*/
LINPHONE_PUBLIC const char* linphone_chat_message_get_text(const LinphoneChatMessage* message);
/**
* Get the time the message was sent.
*/
LINPHONE_PUBLIC time_t linphone_chat_message_get_time(const LinphoneChatMessage* message);
/**
* User pointer get function
*/
LINPHONE_PUBLIC void* linphone_chat_message_get_user_data(const LinphoneChatMessage* message);
/**
*User pointer set function
*/
LINPHONE_PUBLIC void linphone_chat_message_set_user_data(LinphoneChatMessage* message,void*);
/**
* Returns the chatroom this message belongs to.
**/
LINPHONE_PUBLIC LinphoneChatRoom* linphone_chat_message_get_chat_room(LinphoneChatMessage *msg);
LINPHONE_PUBLIC const LinphoneAddress* linphone_chat_message_get_peer_address(LinphoneChatMessage *msg);
/**
* Returns the origin address of a message if it was a outgoing message, or the destination address if it was an incoming message.
*@param message #LinphoneChatMessage obj
*@return #LinphoneAddress
*/
LINPHONE_PUBLIC LinphoneAddress *linphone_chat_message_get_local_address(const LinphoneChatMessage* message);
/**
* Add custom headers to the message.
* @param message the message
* @param header_name name of the header
* @param header_value header value
**/
LINPHONE_PUBLIC void linphone_chat_message_add_custom_header(LinphoneChatMessage* message, const char *header_name, const char *header_value);
/**
* Retrieve a custom header value given its name.
* @param message the message
* @param header_name header name searched
**/
LINPHONE_PUBLIC const char * linphone_chat_message_get_custom_header(LinphoneChatMessage* message, const char *header_name);
/**
* Removes a custom header from the message.
* @param message the message
* @param header_name name of the header to remove
**/
LINPHONE_PUBLIC void linphone_chat_message_remove_custom_header(LinphoneChatMessage *msg, const char *header_name);
/**
* Returns TRUE if the message has been read, otherwise returns FALSE.
* @param message the message
**/
LINPHONE_PUBLIC bool_t linphone_chat_message_is_read(LinphoneChatMessage* message);
/**
* Returns TRUE if the message has been sent, returns FALSE if the message has been received.
* @param message the message
**/
LINPHONE_PUBLIC bool_t linphone_chat_message_is_outgoing(LinphoneChatMessage* message);
/**
* Returns the id used to identify this message in the storage database
* @param message the message
* @return the id
*/
LINPHONE_PUBLIC unsigned int linphone_chat_message_get_storage_id(LinphoneChatMessage* message);
LINPHONE_PUBLIC LinphoneReason linphone_chat_message_get_reason(LinphoneChatMessage* msg);
/**
* Get full details about delivery error of a chat message.
* @param msg a LinphoneChatMessage
* @return a LinphoneErrorInfo describing the details.
**/
LINPHONE_PUBLIC const LinphoneErrorInfo *linphone_chat_message_get_error_info(const LinphoneChatMessage *msg);
/**
* Set the path to the file to read from or write to during the file transfer.
* @param[in] msg LinphoneChatMessage object
* @param[in] filepath The path to the file to use for the file transfer.
*/
LINPHONE_PUBLIC void linphone_chat_message_set_file_transfer_filepath(LinphoneChatMessage *msg, const char *filepath);
/**
* Get the path to the file to read from or write to during the file transfer.
* @param[in] msg LinphoneChatMessage object
* @return The path to the file to use for the file transfer.
*/
LINPHONE_PUBLIC const char * linphone_chat_message_get_file_transfer_filepath(LinphoneChatMessage *msg);
/**
* Fulfill a chat message char by char. Message linked to a Real Time Text Call send char in realtime following RFC 4103/T.140
* To commit a message, use #linphone_chat_room_send_message
* @param[in] msg LinphoneChatMessage
* @param[in] character T.140 char
* @returns 0 if succeed.
*/
LINPHONE_PUBLIC int linphone_chat_message_put_char(LinphoneChatMessage *msg,uint32_t character);
/**
* get Curent Call associated to this chatroom if any
* To commit a message, use #linphone_chat_room_send_message
* @param[in] room LinphoneChatRomm
* @returns LinphoneCall or NULL.
*/
LINPHONE_PUBLIC LinphoneCall *linphone_chat_room_get_call(const LinphoneChatRoom *room);
/**
* Get the LinphoneChatMessageCbs object associated with the LinphoneChatMessage.
* @param[in] msg LinphoneChatMessage object
* @return The LinphoneChatMessageCbs object associated with the LinphoneChatMessage.
*/
LINPHONE_PUBLIC LinphoneChatMessageCbs * linphone_chat_message_get_callbacks(const LinphoneChatMessage *msg);
/**
* Acquire a reference to the LinphoneChatMessageCbs object.
* @param[in] cbs LinphoneChatMessageCbs object.
* @return The same LinphoneChatMessageCbs object.
*/
LINPHONE_PUBLIC LinphoneChatMessageCbs * linphone_chat_message_cbs_ref(LinphoneChatMessageCbs *cbs);
/**
* Release reference to the LinphoneChatMessageCbs object.
* @param[in] cbs LinphoneChatMessageCbs object.
*/
LINPHONE_PUBLIC void linphone_chat_message_cbs_unref(LinphoneChatMessageCbs *cbs);
/**
* Retrieve the user pointer associated with the LinphoneChatMessageCbs object.
* @param[in] cbs LinphoneChatMessageCbs object.
* @return The user pointer associated with the LinphoneChatMessageCbs object.
*/
LINPHONE_PUBLIC void *linphone_chat_message_cbs_get_user_data(const LinphoneChatMessageCbs *cbs);
/**
* Assign a user pointer to the LinphoneChatMessageCbs object.
* @param[in] cbs LinphoneChatMessageCbs object.
* @param[in] ud The user pointer to associate with the LinphoneChatMessageCbs object.
*/
LINPHONE_PUBLIC void linphone_chat_message_cbs_set_user_data(LinphoneChatMessageCbs *cbs, void *ud);
/**
* Get the message state changed callback.
* @param[in] cbs LinphoneChatMessageCbs object.
* @return The current message state changed callback.
*/
LINPHONE_PUBLIC LinphoneChatMessageCbsMsgStateChangedCb linphone_chat_message_cbs_get_msg_state_changed(const LinphoneChatMessageCbs *cbs);
/**
* Set the message state changed callback.
* @param[in] cbs LinphoneChatMessageCbs object.
* @param[in] cb The message state changed callback to be used.
*/
LINPHONE_PUBLIC void linphone_chat_message_cbs_set_msg_state_changed(LinphoneChatMessageCbs *cbs, LinphoneChatMessageCbsMsgStateChangedCb cb);
/**
* Get the file transfer receive callback.
* @param[in] cbs LinphoneChatMessageCbs object.
* @return The current file transfer receive callback.
*/
LINPHONE_PUBLIC LinphoneChatMessageCbsFileTransferRecvCb linphone_chat_message_cbs_get_file_transfer_recv(const LinphoneChatMessageCbs *cbs);
/**
* Set the file transfer receive callback.
* @param[in] cbs LinphoneChatMessageCbs object.
* @param[in] cb The file transfer receive callback to be used.
*/
LINPHONE_PUBLIC void linphone_chat_message_cbs_set_file_transfer_recv(LinphoneChatMessageCbs *cbs, LinphoneChatMessageCbsFileTransferRecvCb cb);
/**
* Get the file transfer send callback.
* @param[in] cbs LinphoneChatMessageCbs object.
* @return The current file transfer send callback.
*/
LINPHONE_PUBLIC LinphoneChatMessageCbsFileTransferSendCb linphone_chat_message_cbs_get_file_transfer_send(const LinphoneChatMessageCbs *cbs);
/**
* Set the file transfer send callback.
* @param[in] cbs LinphoneChatMessageCbs object.
* @param[in] cb The file transfer send callback to be used.
*/
LINPHONE_PUBLIC void linphone_chat_message_cbs_set_file_transfer_send(LinphoneChatMessageCbs *cbs, LinphoneChatMessageCbsFileTransferSendCb cb);
/**
* Get the file transfer progress indication callback.
* @param[in] cbs LinphoneChatMessageCbs object.
* @return The current file transfer progress indication callback.
*/
LINPHONE_PUBLIC LinphoneChatMessageCbsFileTransferProgressIndicationCb linphone_chat_message_cbs_get_file_transfer_progress_indication(const LinphoneChatMessageCbs *cbs);
/**
* Set the file transfer progress indication callback.
* @param[in] cbs LinphoneChatMessageCbs object.
* @param[in] cb The file transfer progress indication callback to be used.
*/
LINPHONE_PUBLIC void linphone_chat_message_cbs_set_file_transfer_progress_indication(LinphoneChatMessageCbs *cbs, LinphoneChatMessageCbsFileTransferProgressIndicationCb cb);
/**
* @}
*/
#include "linphone/chat.h"
/**

View file

@ -312,6 +312,11 @@ typedef struct SalIsComposing {
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);
@ -503,6 +508,7 @@ 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 (*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);
@ -541,6 +547,7 @@ typedef struct SalCallbacks{
SalOnTextReceived text_received;
SalOnTextDeliveryUpdate text_delivery_update;
SalOnIsComposingReceived is_composing_received;
SalOnImdnReceived imdn_received;
SalOnNotifyRefer notify_refer;
SalOnSubscribeReceived subscribe_received;
SalOnIncomingSubscribeClosed incoming_subscribe_closed;

View file

@ -64,13 +64,13 @@ static void message_forking(void) {
LinphoneCoreManager* marie2 = linphone_core_manager_new( "marie_rc");
bctbx_list_t* lcs=bctbx_list_append(NULL,marie->lc);
LinphoneChatRoom* chat_room = linphone_core_get_chat_room(pauline->lc, marie->identity);
LinphoneChatRoomCbs *cbs = linphone_chat_room_get_callbacks(chat_room);
LinphoneChatMessage* message = linphone_chat_room_create_message(chat_room,"Bli bli bli \n blu");
LinphoneChatMessageCbs *cbs = linphone_chat_message_get_callbacks(message);
lcs=bctbx_list_append(lcs,pauline->lc);
lcs=bctbx_list_append(lcs,marie2->lc);
linphone_chat_message_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed);
linphone_chat_room_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed);
linphone_chat_room_send_chat_message(chat_room, message);
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneMessageReceived,1,3000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneMessageReceived,1,1000));
@ -94,8 +94,8 @@ static void message_forking_with_unreachable_recipients(void) {
LinphoneCoreManager* marie3 = linphone_core_manager_new( "marie_rc");
bctbx_list_t* lcs=bctbx_list_append(NULL,marie->lc);
LinphoneChatRoom* chat_room = linphone_core_get_chat_room(pauline->lc, marie->identity);
LinphoneChatRoomCbs *cbs = linphone_chat_room_get_callbacks(chat_room);
LinphoneChatMessage* message = linphone_chat_room_create_message(chat_room,"Bli bli bli \n blu");
LinphoneChatMessageCbs *cbs = linphone_chat_message_get_callbacks(message);
lcs=bctbx_list_append(lcs,pauline->lc);
lcs=bctbx_list_append(lcs,marie2->lc);
@ -112,7 +112,7 @@ static void message_forking_with_unreachable_recipients(void) {
linphone_core_set_network_reachable(marie2->lc,FALSE);
linphone_core_set_network_reachable(marie3->lc,FALSE);
linphone_chat_message_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed);
linphone_chat_room_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed);
linphone_chat_room_send_chat_message(chat_room, message);
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneMessageReceived,1,3000));
BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneMessageDelivered,1,1000));
@ -144,8 +144,8 @@ static void message_forking_with_all_recipients_unreachable(void) {
LinphoneCoreManager* marie3 = linphone_core_manager_new( "marie_rc");
bctbx_list_t* lcs=bctbx_list_append(NULL,marie->lc);
LinphoneChatRoom* chat_room = linphone_core_get_chat_room(pauline->lc, marie->identity);
LinphoneChatRoomCbs *cbs = linphone_chat_room_get_callbacks(chat_room);
LinphoneChatMessage* message = linphone_chat_room_create_message(chat_room,"Bli bli bli \n blu");
LinphoneChatMessageCbs *cbs = linphone_chat_message_get_callbacks(message);
lcs=bctbx_list_append(lcs,pauline->lc);
lcs=bctbx_list_append(lcs,marie2->lc);
@ -164,7 +164,7 @@ static void message_forking_with_all_recipients_unreachable(void) {
linphone_core_set_network_reachable(marie2->lc,FALSE);
linphone_core_set_network_reachable(marie3->lc,FALSE);
linphone_chat_message_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed);
linphone_chat_room_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed);
linphone_chat_room_send_chat_message(chat_room, message);
BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneMessageInProgress,1,5000));
@ -772,8 +772,8 @@ static void call_ipv6_to_ipv4(void){
static void file_transfer_message_rcs_to_external_body_client(void) {
if (transport_supported(LinphoneTransportTls)) {
LinphoneChatRoom* chat_room;
LinphoneChatRoomCbs *cbs;
LinphoneChatMessage* message;
LinphoneChatMessageCbs *cbs;
LinphoneContent* content;
FILE *file_to_send = NULL;
size_t file_size;
@ -806,8 +806,11 @@ static void file_transfer_message_rcs_to_external_body_client(void) {
linphone_core_set_file_transfer_server(pauline->lc,"https://www.linphone.org:444/lft.php");
/* create a chatroom on pauline's side */
chat_room = linphone_core_get_chat_room(pauline->lc, marie->identity);
cbs = linphone_chat_room_get_callbacks(chat_room);
linphone_chat_room_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed);
linphone_chat_room_cbs_set_file_transfer_send(cbs, tester_file_transfer_send);
/* create a file transfer message */
content = linphone_core_create_content(pauline->lc);
linphone_content_set_type(content,"image");
@ -816,22 +819,19 @@ static void file_transfer_message_rcs_to_external_body_client(void) {
linphone_content_set_name(content,"nowebcamCIF.jpg");
message = linphone_chat_room_create_file_transfer_message(chat_room, content);
linphone_chat_message_set_user_data(message, file_to_send);
cbs = linphone_chat_message_get_callbacks(message);
{
int dummy=0;
wait_for_until(marie->lc,pauline->lc,&dummy,1,100); /*just to have time to purge message stored in the server*/
reset_counters(&marie->stat);
reset_counters(&pauline->stat);
}
linphone_chat_message_cbs_set_msg_state_changed(cbs,liblinphone_tester_chat_message_msg_state_changed);
linphone_chat_message_cbs_set_file_transfer_send(cbs, tester_file_transfer_send);
linphone_chat_room_send_chat_message(chat_room,message);
BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageExtBodyReceived,1));
if (marie->stat.last_received_chat_message ) {
cbs = linphone_chat_message_get_callbacks(marie->stat.last_received_chat_message);
linphone_chat_message_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed);
linphone_chat_message_cbs_set_file_transfer_recv(cbs, file_transfer_received);
cbs = linphone_chat_room_get_callbacks(marie->stat.last_received_chat_message->chat_room);
linphone_chat_room_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed);
linphone_chat_room_cbs_set_file_transfer_recv(cbs, file_transfer_received);
linphone_chat_message_download_file(marie->stat.last_received_chat_message);
}
BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageFileTransferDone,1));
@ -850,18 +850,17 @@ static void file_transfer_message_rcs_to_external_body_client(void) {
}
void send_file_transfer_message_using_external_body_url(LinphoneCoreManager *marie, LinphoneCoreManager *pauline) {
LinphoneChatMessageCbs *cbs;
LinphoneChatRoom *chat_room;
LinphoneChatRoomCbs *cbs;
LinphoneChatMessage *message;
/* create a chatroom on pauline's side */
chat_room = linphone_core_get_chat_room(pauline->lc, marie->identity);
cbs = linphone_chat_room_get_callbacks(chat_room);
linphone_chat_room_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed);
message = linphone_chat_room_create_message(chat_room, NULL);
cbs = linphone_chat_message_get_callbacks(message);
linphone_chat_message_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed);
linphone_chat_message_set_external_body_url(message, "https://www.linphone.org:444//tmp/54ec58280ace9_c30709218df8eaba61d1.jpg");
linphone_chat_room_send_chat_message(chat_room, message);

View file

@ -162,6 +162,8 @@ typedef struct _stats {
int number_of_LinphoneMessageDelivered;
int number_of_LinphoneMessageNotDelivered;
int number_of_LinphoneMessageFileTransferDone;
int number_of_LinphoneMessageDeliveredToUser;
int number_of_LinphoneMessageDisplayed;
int number_of_LinphoneIsComposingActiveReceived;
int number_of_LinphoneIsComposingIdleReceived;
int progress_of_LinphoneFileTransfer;
@ -305,10 +307,10 @@ void notify_presence_received(LinphoneCore *lc, LinphoneFriend * lf);
void notify_presence_received_for_uri_or_tel(LinphoneCore *lc, LinphoneFriend *lf, const char *uri_or_tel, const LinphonePresenceModel *presence);
void text_message_received(LinphoneCore *lc, LinphoneChatRoom *room, const LinphoneAddress *from_address, const char *message);
void message_received(LinphoneCore *lc, LinphoneChatRoom *room, LinphoneChatMessage* message);
void file_transfer_received(LinphoneChatMessage *message, const LinphoneContent* content, const LinphoneBuffer *buffer);
LinphoneBuffer * tester_file_transfer_send(LinphoneChatMessage *message, const LinphoneContent* content, size_t offset, size_t size);
void file_transfer_received(LinphoneChatRoom *room, LinphoneChatMessage *message, const LinphoneContent* content, const LinphoneBuffer *buffer);
LinphoneBuffer * tester_file_transfer_send(LinphoneChatRoom *room, LinphoneChatMessage *message, const LinphoneContent* content, size_t offset, size_t size);
LinphoneBuffer * tester_memory_file_transfer_send(LinphoneChatMessage *message, const LinphoneContent* content, size_t offset, size_t size);
void file_transfer_progress_indication(LinphoneChatMessage *message, const LinphoneContent* content, size_t offset, size_t total);
void file_transfer_progress_indication(LinphoneChatRoom *room, LinphoneChatMessage *message, const LinphoneContent* content, size_t offset, size_t total);
void is_composing_received(LinphoneCore *lc, LinphoneChatRoom *room);
void info_message_received(LinphoneCore *lc, LinphoneCall *call, const LinphoneInfoMessage *msg);
void new_subscription_requested(LinphoneCore *lc, LinphoneFriend *lf, const char *url);
@ -351,7 +353,7 @@ LinphoneCoreManager *get_manager(LinphoneCore *lc);
const char *liblinphone_tester_get_subscribe_content(void);
const char *liblinphone_tester_get_notify_content(void);
void liblinphone_tester_chat_message_state_change(LinphoneChatMessage* msg,LinphoneChatMessageState state,void* ud);
void liblinphone_tester_chat_message_msg_state_changed(LinphoneChatMessage *msg, LinphoneChatMessageState state);
void liblinphone_tester_chat_message_msg_state_changed(LinphoneChatRoom *room, LinphoneChatMessage *msg, LinphoneChatMessageState state);
void liblinphone_tester_check_rtcp(LinphoneCoreManager* caller, LinphoneCoreManager* callee);
void liblinphone_tester_clock_start(MSTimeSpec *start);
bool_t liblinphone_tester_clock_elapsed(const MSTimeSpec *start, int value_ms);

View file

@ -69,11 +69,10 @@ void message_received(LinphoneCore *lc, LinphoneChatRoom *room, LinphoneChatMess
/**
* function invoked when a file transfer is received.
* */
void file_transfer_received(LinphoneChatMessage *msg, const LinphoneContent* content, const LinphoneBuffer *buffer){
void file_transfer_received(LinphoneChatRoom *room, LinphoneChatMessage *msg, const LinphoneContent* content, const LinphoneBuffer *buffer){
FILE* file=NULL;
char *receive_file = NULL;
LinphoneChatRoom *cr = linphone_chat_message_get_chat_room(msg);
LinphoneCore *lc = linphone_chat_room_get_core(cr);
LinphoneCore *lc = linphone_chat_room_get_core(room);
if (linphone_chat_message_get_file_transfer_filepath(msg) != NULL) {
if (linphone_buffer_is_empty(buffer)) {
@ -107,7 +106,7 @@ void file_transfer_received(LinphoneChatMessage *msg, const LinphoneContent* con
/*
* function called when the file transfer is initiated. file content should be feed into object LinphoneContent
* */
LinphoneBuffer * tester_file_transfer_send(LinphoneChatMessage *msg, const LinphoneContent* content, size_t offset, size_t size){
LinphoneBuffer * tester_file_transfer_send(LinphoneChatRoom *room, LinphoneChatMessage *msg, const LinphoneContent* content, size_t offset, size_t size){
LinphoneBuffer *lb;
size_t file_size;
size_t size_to_send;
@ -136,9 +135,8 @@ LinphoneBuffer * tester_file_transfer_send(LinphoneChatMessage *msg, const Linph
/**
* function invoked to report file transfer progress.
* */
void file_transfer_progress_indication(LinphoneChatMessage *msg, const LinphoneContent* content, size_t offset, size_t total) {
LinphoneChatRoom *cr = linphone_chat_message_get_chat_room(msg);
LinphoneCore *lc = linphone_chat_room_get_core(cr);
void file_transfer_progress_indication(LinphoneChatRoom *room, LinphoneChatMessage *msg, const LinphoneContent* content, size_t offset, size_t total) {
LinphoneCore *lc = linphone_chat_room_get_core(room);
const LinphoneAddress* from_address = linphone_chat_message_get_from(msg);
const LinphoneAddress* to_address = linphone_chat_message_get_to(msg);
char *address = linphone_chat_message_is_outgoing(msg)?linphone_address_as_string(to_address):linphone_address_as_string(from_address);
@ -164,10 +162,10 @@ void is_composing_received(LinphoneCore *lc, LinphoneChatRoom *room) {
}
void liblinphone_tester_chat_message_state_change(LinphoneChatMessage* msg,LinphoneChatMessageState state,void* ud) {
liblinphone_tester_chat_message_msg_state_changed(msg, state);
liblinphone_tester_chat_message_msg_state_changed(msg->chat_room, msg, state);
}
void liblinphone_tester_chat_message_msg_state_changed(LinphoneChatMessage *msg, LinphoneChatMessageState state) {
void liblinphone_tester_chat_message_msg_state_changed(LinphoneChatRoom *room, LinphoneChatMessage *msg, LinphoneChatMessageState state) {
LinphoneChatRoom *cr = linphone_chat_message_get_chat_room(msg);
LinphoneCore *lc = linphone_chat_room_get_core(cr);
stats* counters = get_stats(lc);
@ -189,6 +187,12 @@ void liblinphone_tester_chat_message_msg_state_changed(LinphoneChatMessage *msg,
case LinphoneChatMessageStateFileTransferDone:
counters->number_of_LinphoneMessageFileTransferDone++;
return;
case LinphoneChatMessageStateDeliveredToUser:
counters->number_of_LinphoneMessageDeliveredToUser++;
return;
case LinphoneChatMessageStateDisplayed:
counters->number_of_LinphoneMessageDisplayed++;
return;
}
ms_error("Unexpected state [%s] for msg [%p]",linphone_chat_message_state_to_string(state), msg);
}
@ -211,7 +215,7 @@ void compare_files(const char *path1, const char *path2) {
LinphoneChatMessage* create_message_from_nowebcam(LinphoneChatRoom *chat_room) {
FILE *file_to_send = NULL;
LinphoneChatMessageCbs *cbs;
LinphoneChatRoomCbs *cbs;
LinphoneContent* content;
LinphoneChatMessage* msg;
size_t file_size;
@ -228,12 +232,12 @@ LinphoneChatMessage* create_message_from_nowebcam(LinphoneChatRoom *chat_room) {
linphone_content_set_size(content,file_size); /*total size to be transfered*/
linphone_content_set_name(content,"nowebcamCIF.jpg");
cbs = linphone_chat_room_get_callbacks(chat_room);
linphone_chat_room_cbs_set_file_transfer_send(cbs, tester_file_transfer_send);
linphone_chat_room_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed);
linphone_chat_room_cbs_set_file_transfer_progress_indication(cbs, file_transfer_progress_indication);
msg = linphone_chat_room_create_file_transfer_message(chat_room, content);
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_file_transfer_progress_indication(cbs, file_transfer_progress_indication);
linphone_chat_message_set_user_data(msg, file_to_send);
linphone_content_unref(content);
@ -242,7 +246,7 @@ LinphoneChatMessage* create_message_from_nowebcam(LinphoneChatRoom *chat_room) {
}
LinphoneChatMessage* create_file_transfer_message_from_nowebcam(LinphoneChatRoom *chat_room) {
LinphoneChatMessageCbs *cbs;
LinphoneChatRoomCbs *cbs;
LinphoneContent* content;
LinphoneChatMessage* msg;
char *send_filepath = bc_tester_res("images/nowebcamCIF.jpg");
@ -253,12 +257,12 @@ LinphoneChatMessage* create_file_transfer_message_from_nowebcam(LinphoneChatRoom
linphone_content_set_subtype(content,"jpeg");
linphone_content_set_name(content,"nowebcamCIF.jpg");
cbs = linphone_chat_room_get_callbacks(chat_room);
linphone_chat_room_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed);
linphone_chat_room_cbs_set_file_transfer_progress_indication(cbs, file_transfer_progress_indication);
msg = linphone_chat_room_create_file_transfer_message(chat_room, content);
linphone_chat_message_set_file_transfer_filepath(msg, send_filepath);
cbs = linphone_chat_message_get_callbacks(msg);
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_content_unref(content);
ms_free(send_filepath);
@ -266,9 +270,10 @@ LinphoneChatMessage* create_file_transfer_message_from_nowebcam(LinphoneChatRoom
}
void text_message_base(LinphoneCoreManager* marie, LinphoneCoreManager* pauline) {
LinphoneChatMessage* msg = linphone_chat_room_create_message(linphone_core_get_chat_room(pauline->lc,marie->identity),"Bli bli bli \n blu");
LinphoneChatMessageCbs *cbs = linphone_chat_message_get_callbacks(msg);
linphone_chat_message_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed);
LinphoneChatRoom *room = linphone_core_get_chat_room(pauline->lc, marie->identity);
LinphoneChatMessage* msg = linphone_chat_room_create_message(room, "Bli bli bli \n blu");
LinphoneChatRoomCbs *cbs = linphone_chat_room_get_callbacks(room);
linphone_chat_room_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed);
linphone_chat_room_send_chat_message(msg->chat_room,msg);
BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneMessageDelivered,1));
@ -382,14 +387,13 @@ static void text_message_with_ack(void) {
static void text_message_with_send_error(void) {
LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc");
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc");
LinphoneChatRoom* chat_room = linphone_core_get_chat_room(marie->lc, pauline->identity);
LinphoneChatRoomCbs *cbs = linphone_chat_room_get_callbacks(chat_room);
LinphoneChatMessage* msg = linphone_chat_room_create_message(chat_room,"Bli bli bli \n blu");
LinphoneChatMessageCbs *cbs = linphone_chat_message_get_callbacks(msg);
linphone_chat_room_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed);
/*simulate a network error*/
sal_set_send_error(marie->lc->sal, -1);
linphone_chat_message_cbs_set_msg_state_changed(cbs,liblinphone_tester_chat_message_msg_state_changed);
linphone_chat_room_send_chat_message(chat_room,msg);
/* check transient msg list: the msg should be in it, and should be the only one */
@ -417,13 +421,12 @@ static void text_message_with_external_body(void) {
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc");
LinphoneChatRoom* chat_room = linphone_core_get_chat_room(pauline->lc, marie->identity);
LinphoneChatRoomCbs *cbs = linphone_chat_room_get_callbacks(chat_room);
LinphoneChatMessage* msg = linphone_chat_room_create_message(chat_room,"Bli bli bli \n blu");
LinphoneChatMessageCbs *cbs = linphone_chat_message_get_callbacks(msg);
message_external_body_url="http://www.linphone.org";
linphone_chat_message_set_external_body_url(msg,message_external_body_url);
linphone_chat_message_cbs_set_msg_state_changed(cbs,liblinphone_tester_chat_message_msg_state_changed);
linphone_chat_room_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed);
linphone_chat_room_send_chat_message(chat_room,msg);
/* check transient msg list: the msg should be in it, and should be the only one */
@ -447,9 +450,8 @@ void transfer_message_base2(LinphoneCoreManager* marie, LinphoneCoreManager* pau
char *send_filepath = bc_tester_res("images/nowebcamCIF.jpg");
char *receive_filepath = bc_tester_file("receive_file.dump");
LinphoneChatRoom* chat_room;
LinphoneChatRoomCbs *cbs;
LinphoneChatMessage* msg;
LinphoneChatMessageCbs *cbs;
bctbx_list_t *msg_list = NULL;
/* Remove any previously downloaded file */
remove(receive_filepath);
@ -459,6 +461,11 @@ void transfer_message_base2(LinphoneCoreManager* marie, LinphoneCoreManager* pau
/* create a chatroom on pauline's side */
chat_room = linphone_core_get_chat_room(pauline->lc, marie->identity);
cbs = linphone_chat_room_get_callbacks(chat_room);
linphone_chat_room_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed);
linphone_chat_room_cbs_set_file_transfer_recv(cbs, file_transfer_received);
linphone_chat_room_cbs_set_file_transfer_progress_indication(cbs, file_transfer_progress_indication);
/* create a file transfer msg */
if (use_file_body_handler_in_upload) {
msg = create_file_transfer_message_from_nowebcam(chat_room);
@ -484,21 +491,7 @@ void transfer_message_base2(LinphoneCoreManager* marie, LinphoneCoreManager* pau
BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneRegistrationOk,pauline->stat.number_of_LinphoneRegistrationOk+1));
} else {
BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceivedWithFile,1));
if (marie->stat.last_received_chat_message) {
LinphoneChatMessage *recv_msg;
if (download_from_history) {
LinphoneChatRoom *marie_room = linphone_core_get_chat_room(marie->lc, pauline->identity);
msg_list = linphone_chat_room_get_history(marie_room,1);
BC_ASSERT_PTR_NOT_NULL(msg_list);
if (!msg_list) goto end;
recv_msg = (LinphoneChatMessage *)msg_list->data;
} else {
recv_msg = marie->stat.last_received_chat_message;
}
cbs = linphone_chat_message_get_callbacks(recv_msg);
linphone_chat_message_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed);
linphone_chat_message_cbs_set_file_transfer_recv(cbs, file_transfer_received);
linphone_chat_message_cbs_set_file_transfer_progress_indication(cbs, file_transfer_progress_indication);
if (marie->stat.last_received_chat_message ) {
if (use_file_body_handler_in_download) {
linphone_chat_message_set_file_transfer_filepath(recv_msg, receive_filepath);
}
@ -598,6 +591,7 @@ static void transfer_message_upload_cancelled(void) {
static void transfer_message_download_cancelled(void) {
LinphoneChatRoom* chat_room;
LinphoneChatRoomCbs *cbs;
LinphoneChatMessage* msg;
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc");
@ -607,16 +601,15 @@ static void transfer_message_download_cancelled(void) {
/* create a chatroom on pauline's side */
chat_room = linphone_core_get_chat_room(pauline->lc,marie->identity);
cbs = linphone_chat_room_get_callbacks(chat_room);
linphone_chat_room_cbs_set_file_transfer_progress_indication(cbs, file_transfer_progress_indication);
msg = create_message_from_nowebcam(chat_room);
linphone_chat_room_send_chat_message(chat_room,msg);
/* wait for marie to receive pauline's msg */
BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceivedWithFile,1));
if (marie->stat.last_received_chat_message ) { /* get last msg and use it to download file */
LinphoneChatMessageCbs *cbs = linphone_chat_message_get_callbacks(marie->stat.last_received_chat_message);
linphone_chat_message_cbs_set_file_transfer_progress_indication(cbs, file_transfer_progress_indication);
linphone_chat_message_start_file_download(marie->stat.last_received_chat_message, liblinphone_tester_chat_message_state_change, marie->lc);
/* wait for file to be 50% downloaded */
BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.progress_of_LinphoneFileTransfer, 50));
@ -636,8 +629,8 @@ static void transfer_message_download_cancelled(void) {
static void file_transfer_using_external_body_url(void) {
if (transport_supported(LinphoneTransportTls)) {
LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc");
LinphoneChatMessageCbs *cbs;
LinphoneChatRoom *chat_room;
LinphoneChatRoomCbs *cbs;
LinphoneChatMessage *msg;
LinphoneCoreManager *pauline = linphone_core_manager_new("pauline_rc");
@ -647,12 +640,11 @@ static void file_transfer_using_external_body_url(void) {
/* create a chatroom on pauline's side */
chat_room = linphone_core_get_chat_room(pauline->lc, marie->identity);
cbs = linphone_chat_room_get_callbacks(chat_room);
linphone_chat_room_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed);
msg = linphone_chat_room_create_message(chat_room, NULL);
cbs = linphone_chat_message_get_callbacks(msg);
linphone_chat_message_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed);
linphone_chat_message_set_external_body_url(msg, "https://www.linphone.org:444//tmp/54ec58280ace9_c30709218df8eaba61d1.jpg");
linphone_chat_room_send_chat_message(chat_room, msg);
@ -671,9 +663,10 @@ static void file_transfer_2_messages_simultaneously(void) {
if (transport_supported(LinphoneTransportTls)) {
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
LinphoneChatRoom* pauline_room;
LinphoneChatRoom *marie_room;
LinphoneChatRoomCbs *cbs;
LinphoneChatMessage* msg;
LinphoneChatMessage* msg2;
LinphoneChatMessageCbs *cbs;
char *send_filepath = bc_tester_res("images/nowebcamCIF.jpg");
char *receive_filepath = bc_tester_file("receive_file.dump");
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc");
@ -686,18 +679,21 @@ static void file_transfer_2_messages_simultaneously(void) {
/* create a chatroom on pauline's side */
pauline_room = linphone_core_get_chat_room(pauline->lc, marie->identity);
cbs = linphone_chat_room_get_callbacks(pauline_room);
linphone_chat_room_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed);
msg = create_message_from_nowebcam(pauline_room);
msg2 = create_message_from_nowebcam(pauline_room);
cbs = linphone_chat_message_get_callbacks(msg2);
linphone_chat_message_cbs_set_msg_state_changed(cbs,liblinphone_tester_chat_message_msg_state_changed);
BC_ASSERT_EQUAL((unsigned int)bctbx_list_size(linphone_core_get_chat_rooms(marie->lc)), 0, unsigned int, "%u");
if (bctbx_list_size(linphone_core_get_chat_rooms(marie->lc)) == 0) {
linphone_chat_room_send_chat_message(pauline_room,msg);
linphone_chat_room_send_chat_message(pauline_room,msg2);
if (BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceivedWithFile,1))) {
msg = linphone_chat_message_clone(marie->stat.last_received_chat_message);
marie_room = linphone_chat_message_get_chat_room(msg);
cbs = linphone_chat_room_get_callbacks(marie_room);
linphone_chat_room_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed);
linphone_chat_room_cbs_set_file_transfer_recv(cbs, file_transfer_received);
BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceivedWithFile,2));
msg2 = marie->stat.last_received_chat_message;
BC_ASSERT_EQUAL((unsigned int)bctbx_list_size(linphone_core_get_chat_rooms(marie->lc)), 1, unsigned int, "%u");
@ -712,16 +708,8 @@ static void file_transfer_2_messages_simultaneously(void) {
ms_error("%s", buf);
}
cbs = linphone_chat_message_get_callbacks(msg);
linphone_chat_message_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed);
linphone_chat_message_cbs_set_file_transfer_recv(cbs, file_transfer_received);
linphone_chat_message_download_file(msg);
cbs = linphone_chat_message_get_callbacks(msg2);
linphone_chat_message_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed);
linphone_chat_message_cbs_set_file_transfer_recv(cbs, file_transfer_received);
linphone_chat_message_download_file(msg2);
BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneFileTransferDownloadSuccessful,2));
BC_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageInProgress,4, int, "%d");
@ -743,12 +731,12 @@ static void text_message_denied(void) {
LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc");
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc");
LinphoneChatRoom* chat_room = linphone_core_get_chat_room(marie->lc, pauline->identity);
LinphoneChatRoomCbs *cbs = linphone_chat_room_get_callbacks(chat_room);
LinphoneChatMessage* msg = linphone_chat_room_create_message(chat_room,"Bli bli bli \n blu");
LinphoneChatMessageCbs *cbs = linphone_chat_message_get_callbacks(msg);
/*pauline doesn't want to be disturbed*/
linphone_core_disable_chat(pauline->lc,LinphoneReasonDoNotDisturb);
linphone_chat_message_cbs_set_msg_state_changed(cbs,liblinphone_tester_chat_message_msg_state_changed);
linphone_chat_room_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed);
linphone_chat_room_send_chat_message(chat_room,msg);
BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageNotDelivered,1));
@ -892,6 +880,37 @@ static void is_composing_notification_with_lime(void) {
_is_composing_notification(TRUE);
}
static void imdn_notifications(void) {
LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_new( "pauline_tcp_rc");
LinphoneChatRoom *pauline_chat_room = linphone_core_get_chat_room(pauline->lc, marie->identity);
LinphoneChatRoom *marie_chat_room;
LinphoneChatRoomCbs *cbs;
LinphoneChatMessage *cm;
bctbx_list_t *history;
cbs = linphone_chat_room_get_callbacks(pauline_chat_room);
linphone_chat_room_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed);
cm = linphone_chat_room_create_message(pauline_chat_room, "Tell me if you get my message");
linphone_chat_room_send_chat_message(pauline_chat_room, cm);
BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneMessageReceived, 1));
marie_chat_room = linphone_core_get_chat_room(marie->lc, pauline->identity);
history = linphone_chat_room_get_history(marie_chat_room, 1);
BC_ASSERT_EQUAL((int)bctbx_list_size(history), 1, int, "%d");
cm = (LinphoneChatMessage *)bctbx_list_nth_data(history, 0);
BC_ASSERT_PTR_NOT_NULL(cm);
if (cm != NULL) {
linphone_chat_message_notify_delivery(cm);
BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &pauline->stat.number_of_LinphoneMessageDeliveredToUser, 1));
linphone_chat_message_notify_display(cm);
BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &pauline->stat.number_of_LinphoneMessageDisplayed, 1));
bctbx_list_free_with_data(history, (bctbx_list_free_func)linphone_chat_message_unref);
}
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
}
static void lime_text_message(void) {
FILE *ZIDCacheMarieFD, *ZIDCachePaulineFD;
LinphoneChatRoom* chat_room;
@ -983,7 +1002,7 @@ void lime_transfer_message_base(bool_t encrypt_file,bool_t download_file_from_st
FILE *ZIDCacheMarieFD, *ZIDCachePaulineFD;
LinphoneCoreManager *marie, *pauline;
LinphoneChatMessage *msg;
LinphoneChatMessageCbs *cbs;
LinphoneChatRoomCbs *cbs;
char *pauline_id, *marie_id;
char *filepath;
char *send_filepath = bc_tester_res("images/nowebcamCIF.jpg");
@ -1052,9 +1071,9 @@ void lime_transfer_message_base(bool_t encrypt_file,bool_t download_file_from_st
} else {
recv_msg = marie->stat.last_received_chat_message;
}
cbs = linphone_chat_message_get_callbacks(recv_msg);
linphone_chat_message_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed);
linphone_chat_message_cbs_set_file_transfer_recv(cbs, file_transfer_received);
cbs = linphone_chat_room_get_callbacks(linphone_chat_message_get_chat_room(recv_msg));
linphone_chat_room_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed);
linphone_chat_room_cbs_set_file_transfer_recv(cbs, file_transfer_received);
content = linphone_chat_message_get_file_transfer_information(recv_msg);
if (!content) goto end;
if (encrypt_file)
@ -1523,9 +1542,9 @@ static void text_status_after_destroying_chat_room(void) {
static void file_transfer_not_sent_if_invalid_url(void) {
LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc");
LinphoneChatRoom *chatroom = linphone_core_get_chat_room_from_uri(marie->lc, "<sip:Jehan@sip.linphone.org>");
LinphoneChatRoomCbs *cbs = linphone_chat_room_get_callbacks(chatroom);
LinphoneChatMessage *msg = create_message_from_nowebcam(chatroom);
LinphoneChatMessageCbs *cbs = linphone_chat_message_get_callbacks(msg);
linphone_chat_message_cbs_set_msg_state_changed(cbs,liblinphone_tester_chat_message_msg_state_changed);
linphone_chat_room_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed);
linphone_core_set_file_transfer_server(marie->lc, "INVALID URL");
linphone_chat_room_send_chat_message(chatroom, msg);
BC_ASSERT_TRUE(wait_for_until(marie->lc, NULL, &marie->stat.number_of_LinphoneMessageNotDelivered, 1, 1000));
@ -1535,9 +1554,9 @@ static void file_transfer_not_sent_if_invalid_url(void) {
void file_transfer_io_error_base(char *server_url, bool_t destroy_room) {
LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc");
LinphoneChatRoom *chatroom = linphone_core_get_chat_room_from_uri(marie->lc, "<sip:Jehan@sip.linphone.org>");
LinphoneChatRoomCbs *cbs = linphone_chat_room_get_callbacks(chatroom);
LinphoneChatMessage *msg = create_message_from_nowebcam(chatroom);
LinphoneChatMessageCbs *cbs = linphone_chat_message_get_callbacks(msg);
linphone_chat_message_cbs_set_msg_state_changed(cbs,liblinphone_tester_chat_message_msg_state_changed);
linphone_chat_room_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed);
linphone_core_set_file_transfer_server(marie->lc, server_url);
linphone_chat_room_send_chat_message(chatroom, msg);
BC_ASSERT_TRUE(wait_for_until(marie->lc, NULL, &marie->stat.number_of_LinphoneMessageInProgress, 1, 1000));
@ -2002,14 +2021,14 @@ void chat_message_custom_headers(void) {
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc");
LinphoneChatRoom* chat_room = linphone_core_get_chat_room(pauline->lc, marie->identity);
LinphoneChatRoomCbs *cbs = linphone_chat_room_get_callbacks(chat_room);
LinphoneChatMessage* msg = linphone_chat_room_create_message(chat_room, "Lorem Ipsum");
LinphoneChatMessageCbs *cbs = linphone_chat_message_get_callbacks(msg);
linphone_chat_room_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed);
linphone_chat_message_add_custom_header(msg, "Test1", "Value1");
linphone_chat_message_add_custom_header(msg, "Test2", "Value2");
linphone_chat_message_remove_custom_header(msg, "Test1");
linphone_chat_message_cbs_set_msg_state_changed(cbs,liblinphone_tester_chat_message_msg_state_changed);
linphone_chat_room_send_chat_message(chat_room,msg);
BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceived,1));
@ -2053,6 +2072,7 @@ test_t message_tests[] = {
TEST_NO_TAG("Info message with body", info_message_with_body),
TEST_NO_TAG("IsComposing notification", is_composing_notification),
TEST_ONE_TAG("IsComposing notification lime", is_composing_notification_with_lime, "LIME"),
TEST_NO_TAG("IMDN notifications", imdn_notifications),
TEST_ONE_TAG("Lime text message", lime_text_message, "LIME"),
TEST_ONE_TAG("Lime text message to non lime", lime_text_message_to_non_lime, "LIME"),
TEST_ONE_TAG("Lime transfer message", lime_transfer_message, "LIME"),

View file

@ -44,7 +44,7 @@ static void helper(const char *progname) {
exit(0);
}
static void on_msg_state_changed(LinphoneChatMessage *msg, LinphoneChatMessageState state){
static void on_msg_state_changed(LinphoneChatRoom *room, LinphoneChatMessage *msg, LinphoneChatMessageState state){
switch(state){
case LinphoneChatMessageStateInProgress:
printf("Sending message...\n");
@ -57,6 +57,8 @@ static void on_msg_state_changed(LinphoneChatMessage *msg, LinphoneChatMessageSt
printf("Message transmitted succesfully.\n");
running = FALSE;
break;
case LinphoneChatMessageStateDeliveredToUser:
case LinphoneChatMessageStateDisplayed:
case LinphoneChatMessageStateFileTransferDone:
case LinphoneChatMessageStateFileTransferError:
case LinphoneChatMessageStateIdle:
@ -83,7 +85,7 @@ int main(int argc, char *argv[]){
LinphoneProxyConfig *cfg;
LinphoneChatMessage *msg;
LinphoneChatRoom *room;
LinphoneChatMessageCbs *cbs;
LinphoneChatRoomCbs *cbs;
char * text = NULL;
char *tmp;
@ -175,9 +177,9 @@ int main(int argc, char *argv[]){
linphone_proxy_config_unref(cfg);
room = linphone_core_get_chat_room(lc, to);
cbs = linphone_chat_room_get_callbacks(room);
linphone_chat_room_cbs_set_msg_state_changed(cbs, on_msg_state_changed);
msg = linphone_chat_room_create_message(room, text);
cbs = linphone_chat_message_get_callbacks(msg);
linphone_chat_message_cbs_set_msg_state_changed(cbs, on_msg_state_changed);
linphone_chat_room_send_chat_message(room, msg);
/* main loop for receiving notifications and doing background linphonecore work: */
while(running){