mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-05-03 20:46:28 +00:00
Moved send code from ChatRoom to ChatMessage
This commit is contained in:
parent
33d7a384af
commit
8d39bbe9b1
5 changed files with 146 additions and 142 deletions
|
|
@ -91,9 +91,7 @@ LinphoneChatMessageCbs *linphone_chat_message_get_callbacks(const LinphoneChatMe
|
|||
// =============================================================================
|
||||
|
||||
LinphoneChatRoom *linphone_chat_message_get_chat_room(const LinphoneChatMessage *msg) {
|
||||
shared_ptr<const LinphonePrivate::ChatMessage> message = L_GET_CPP_PTR_FROM_C_OBJECT(msg);
|
||||
shared_ptr<LinphonePrivate::ChatRoom> room = message->getChatRoom();
|
||||
return L_GET_C_BACK_PTR(room);
|
||||
return L_GET_C_BACK_PTR(L_GET_CPP_PTR_FROM_C_OBJECT(msg)->getChatRoom());
|
||||
}
|
||||
|
||||
const char *linphone_chat_message_get_external_body_url(const LinphoneChatMessage *msg) {
|
||||
|
|
|
|||
|
|
@ -97,6 +97,8 @@ public:
|
|||
// -----------------------------------------------------------------------------
|
||||
|
||||
void sendImdn(ImdnType imdnType, LinphoneReason reason);
|
||||
|
||||
void send();
|
||||
|
||||
private:
|
||||
std::shared_ptr<ChatRoom> chatRoom;
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@
|
|||
#include "content/content.h"
|
||||
#include "chat-room-p.h"
|
||||
#include "real-time-text-chat-room.h"
|
||||
#include "modifier/multipart-chat-message-modifier.h"
|
||||
#include "modifier/cpim-chat-message-modifier.h"
|
||||
|
||||
#include "ortp/b64.h"
|
||||
|
||||
|
|
@ -83,7 +85,7 @@ void ChatMessagePrivate::setState(ChatMessage::State s) {
|
|||
linphone_chat_message_get_message_state_changed_cb(msg)(msg, (LinphoneChatMessageState)state, linphone_chat_message_get_message_state_changed_cb_user_data(msg));
|
||||
}
|
||||
LinphoneChatMessageCbs *cbs = linphone_chat_message_get_callbacks(msg);
|
||||
if (linphone_chat_message_cbs_get_msg_state_changed(cbs)) {
|
||||
if (cbs && linphone_chat_message_cbs_get_msg_state_changed(cbs)) {
|
||||
linphone_chat_message_cbs_get_msg_state_changed(cbs)(msg, linphone_chat_message_get_state(msg));
|
||||
}
|
||||
}
|
||||
|
|
@ -585,8 +587,7 @@ void ChatMessagePrivate::processResponseFromPostFile(const belle_http_response_e
|
|||
first_part_header = "form-data; name=\"File\"; filename=\"filename.txt\"";
|
||||
} else {
|
||||
// temporary storage for the Content-disposition header value
|
||||
first_part_header = "form-data; name=\"File\"; filename=\"%s\"";
|
||||
first_part_header = first_part_header + linphone_content_get_name(cFileTransferInformation);
|
||||
first_part_header = "form-data; name=\"File\"; filename=\"" +string(linphone_content_get_name(cFileTransferInformation)) + "\"";
|
||||
}
|
||||
|
||||
// create a user body handler to take care of the file and add the content disposition and content-type headers
|
||||
|
|
@ -683,7 +684,7 @@ void ChatMessagePrivate::processResponseFromPostFile(const belle_http_response_e
|
|||
setContentType("application/vnd.gsma.rcs-ft-http+xml");
|
||||
q->updateState(ChatMessage::State::FileTransferDone);
|
||||
releaseHttpRequest();
|
||||
//TODO chatRoom->sendMessage(q);
|
||||
send();
|
||||
fileUploadEndBackgroundTask();
|
||||
} else {
|
||||
ms_warning("Received empty response from server, file transfer failed");
|
||||
|
|
@ -793,7 +794,7 @@ void ChatMessagePrivate::processIoErrorUpload(const belle_sip_io_error_event_t *
|
|||
ms_error("I/O Error during file upload of msg [%p]", this);
|
||||
q->updateState(ChatMessage::State::NotDelivered);
|
||||
releaseHttpRequest();
|
||||
//TODO chatRoom->getPrivate()->removeTransientMessage(q);
|
||||
chatRoom->getPrivate()->removeTransientMessage(q->getSharedPtr());
|
||||
}
|
||||
|
||||
static void _chat_message_process_auth_requested_upload(void *data, belle_sip_auth_event *event) {
|
||||
|
|
@ -806,7 +807,7 @@ void ChatMessagePrivate::processAuthRequestedUpload(const belle_sip_auth_event *
|
|||
ms_error("Error during file upload: auth requested for msg [%p]", this);
|
||||
q->updateState(ChatMessage::State::NotDelivered);
|
||||
releaseHttpRequest();
|
||||
//TODO chatRoom->getPrivate()->removeTransientMessage(q);
|
||||
chatRoom->getPrivate()->removeTransientMessage(q->getSharedPtr());
|
||||
}
|
||||
|
||||
static void _chat_message_process_io_error_download(void *data, const belle_sip_io_error_event_t *event) {
|
||||
|
|
@ -886,6 +887,132 @@ void ChatMessagePrivate::releaseHttpRequest() {
|
|||
}
|
||||
}
|
||||
|
||||
void ChatMessagePrivate::send() {
|
||||
L_Q();
|
||||
SalOp *op = salOp;
|
||||
LinphoneCall *call = NULL;
|
||||
|
||||
if (lp_config_get_int(chatRoom->getCore()->config, "sip", "chat_use_call_dialogs", 0) != 0) {
|
||||
call = linphone_core_get_call_by_remote_address(chatRoom->getCore(), chatRoom->getPeerAddress().asString().c_str());
|
||||
if (call) {
|
||||
if (linphone_call_get_state(call) == LinphoneCallConnected || linphone_call_get_state(call) == LinphoneCallStreamsRunning ||
|
||||
linphone_call_get_state(call) == LinphoneCallPaused || linphone_call_get_state(call) == LinphoneCallPausing ||
|
||||
linphone_call_get_state(call) == LinphoneCallPausedByRemote) {
|
||||
ms_message("send SIP msg through the existing call.");
|
||||
op = linphone_call_get_op(call);
|
||||
string identity = linphone_core_find_best_identity(chatRoom->getCore(), linphone_call_get_remote_address(call));
|
||||
if (identity.empty()) {
|
||||
LinphoneAddress *addr = linphone_address_new(chatRoom->getPeerAddress().asString().c_str());
|
||||
LinphoneProxyConfig *proxy = linphone_core_lookup_known_proxy(chatRoom->getCore(), addr);
|
||||
if (proxy) {
|
||||
identity = L_GET_CPP_PTR_FROM_C_OBJECT(linphone_proxy_config_get_identity_address(proxy))->asString();
|
||||
} else {
|
||||
identity = linphone_core_get_primary_contact(chatRoom->getCore());
|
||||
}
|
||||
linphone_address_unref(addr);
|
||||
}
|
||||
q->setFromAddress(identity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!op) {
|
||||
LinphoneAddress *peer = linphone_address_new(chatRoom->getPeerAddress().asString().c_str());
|
||||
/* Sending out of call */
|
||||
salOp = op = new SalMessageOp(chatRoom->getCore()->sal);
|
||||
linphone_configure_op(
|
||||
chatRoom->getCore(), op, peer, getSalCustomHeaders(),
|
||||
!!lp_config_get_int(chatRoom->getCore()->config, "sip", "chat_msg_with_contact", 0)
|
||||
);
|
||||
op->set_user_pointer(L_GET_C_BACK_PTR(q)); /* If out of call, directly store msg */
|
||||
linphone_address_unref(peer);
|
||||
}
|
||||
|
||||
// ---------------------------------------
|
||||
// Start of message modification
|
||||
// ---------------------------------------
|
||||
|
||||
string clearTextMessage;
|
||||
string clearTextContentType;
|
||||
|
||||
if (!getText().empty()) {
|
||||
clearTextMessage = getText().c_str();
|
||||
}
|
||||
if (!getContentType().empty()) {
|
||||
clearTextContentType = getContentType();
|
||||
}
|
||||
|
||||
int retval = -1;
|
||||
LinphoneImEncryptionEngine *imee = chatRoom->getCore()->im_encryption_engine;
|
||||
if (imee) {
|
||||
LinphoneImEncryptionEngineCbs *imeeCbs = linphone_im_encryption_engine_get_callbacks(imee);
|
||||
LinphoneImEncryptionEngineCbsOutgoingMessageCb cbProcessOutgoingMessage = linphone_im_encryption_engine_cbs_get_process_outgoing_message(imeeCbs);
|
||||
if (cbProcessOutgoingMessage) {
|
||||
//TODO retval = cbProcessOutgoingMessage(imee, L_GET_C_BACK_PTR(chatRoom), L_GET_C_BACK_PTR(this));
|
||||
if (retval == 0) {
|
||||
isSecured = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (retval > 0) {
|
||||
sal_error_info_set((SalErrorInfo *)op->get_error_info(), SalReasonNotAcceptable, "SIP", retval, "Unable to encrypt IM", nullptr);
|
||||
q->updateState(ChatMessage::State::NotDelivered);
|
||||
q->store();
|
||||
return;
|
||||
}
|
||||
|
||||
if (contents.size() > 1) {
|
||||
MultipartChatMessageModifier mcmm;
|
||||
mcmm.encode(this);
|
||||
}
|
||||
|
||||
if (lp_config_get_int(chatRoom->getCore()->config, "sip", "use_cpim", 0) == 1) {
|
||||
CpimChatMessageModifier ccmm;
|
||||
ccmm.encode(this);
|
||||
}
|
||||
|
||||
// ---------------------------------------
|
||||
// End of message modification
|
||||
// ---------------------------------------
|
||||
|
||||
if (!externalBodyUrl.empty()) {
|
||||
char *content_type = ms_strdup_printf("message/external-body; access-type=URL; URL=\"%s\"", externalBodyUrl.c_str());
|
||||
auto msgOp = dynamic_cast<SalMessageOpInterface *>(op);
|
||||
msgOp->send_message(from.asString().c_str(), chatRoom->getPeerAddress().asString().c_str(), content_type, nullptr, nullptr);
|
||||
ms_free(content_type);
|
||||
} else {
|
||||
auto msgOp = dynamic_cast<SalMessageOpInterface *>(op);
|
||||
if (!getContentType().empty()) {
|
||||
msgOp->send_message(from.asString().c_str(), chatRoom->getPeerAddress().asString().c_str(), getContentType().c_str(), getText().c_str(), chatRoom->getPeerAddress().asStringUriOnly().c_str());
|
||||
} else {
|
||||
msgOp->send_message(from.asString().c_str(), chatRoom->getPeerAddress().asString().c_str(), getText().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
if (!getText().empty() && getText() == clearTextMessage) {
|
||||
/* We replace the encrypted message by the original one so it can be correctly stored and displayed by the application */
|
||||
setText(clearTextMessage);
|
||||
}
|
||||
if (!getContentType().empty() && getContentType() == clearTextContentType) {
|
||||
/* We replace the encrypted content type by the original one */
|
||||
setContentType(clearTextContentType);
|
||||
}
|
||||
q->setId(op->get_call_id()); /* must be known at that time */
|
||||
|
||||
if (call && linphone_call_get_op(call) == op) {
|
||||
/* In this case, chat delivery status is not notified, so unrefing chat message right now */
|
||||
/* Might be better fixed by delivering status, but too costly for now */
|
||||
return;
|
||||
}
|
||||
|
||||
/* If operation failed, we should not change message state */
|
||||
if (q->isOutgoing()) {
|
||||
setIsReadOnly(true);
|
||||
setState(ChatMessage::State::InProgress);
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// =============================================================================
|
||||
|
|
@ -1150,7 +1277,7 @@ void ChatMessage::sendDisplayNotification() {
|
|||
int ChatMessage::uploadFile() {
|
||||
L_D();
|
||||
|
||||
if (d->httpRequest){
|
||||
if (d->httpRequest) {
|
||||
ms_error("linphone_chat_room_upload_file(): there is already an upload in progress.");
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -1246,4 +1373,8 @@ int ChatMessage::putCharacter(uint32_t character) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
shared_ptr<ChatMessage> ChatMessage::getSharedPtr() {
|
||||
return static_pointer_cast<ChatMessage>(shared_from_this());
|
||||
}
|
||||
|
||||
LINPHONE_END_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -143,6 +143,7 @@ public:
|
|||
void removeCustomHeader(const std::string &headerName);
|
||||
|
||||
protected:
|
||||
std::shared_ptr<ChatMessage> getSharedPtr();
|
||||
explicit ChatMessage(ChatMessagePrivate &p);
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -23,8 +23,6 @@
|
|||
|
||||
#include "c-wrapper/c-wrapper.h"
|
||||
#include "chat-room-p.h"
|
||||
#include "modifier/multipart-chat-message-modifier.h"
|
||||
#include "modifier/cpim-chat-message-modifier.h"
|
||||
#include "imdn.h"
|
||||
#include "content/content.h"
|
||||
#include "chat-message-p.h"
|
||||
|
|
@ -770,150 +768,24 @@ void ChatRoom::sendMessage (shared_ptr<ChatMessage> msg) {
|
|||
d->addTransientMessage(msg);
|
||||
/* Store the message so that even if the upload is stopped, it can be done again */
|
||||
d->storeOrUpdateMessage(msg);
|
||||
|
||||
msg->getPrivate()->setState(ChatMessage::State::InProgress);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
SalOp *op = msg->getPrivate()->getSalOp();
|
||||
LinphoneCall *call = nullptr;
|
||||
string identity;
|
||||
char *clearTextMessage = nullptr;
|
||||
char *clearTextContentType = nullptr;
|
||||
LinphoneAddress *peer = linphone_address_new(d->peerAddress.asString().c_str());
|
||||
|
||||
if (!msg->getPrivate()->getText().empty()) {
|
||||
clearTextMessage = ms_strdup(msg->getPrivate()->getText().c_str());
|
||||
}
|
||||
if (!msg->getPrivate()->getContentType().empty()) {
|
||||
clearTextContentType = ms_strdup(msg->getPrivate()->getContentType().c_str());
|
||||
}
|
||||
|
||||
/* Add to transient list */
|
||||
d->addTransientMessage(msg);
|
||||
|
||||
msg->getPrivate()->setTime(ms_time(0));
|
||||
msg->getPrivate()->send();
|
||||
|
||||
if (lp_config_get_int(d->core->config, "sip", "chat_use_call_dialogs", 0) != 0) {
|
||||
call = linphone_core_get_call_by_remote_address(d->core, d->peerAddress.asString().c_str());
|
||||
if (call) {
|
||||
if (linphone_call_get_state(call) == LinphoneCallConnected || linphone_call_get_state(call) == LinphoneCallStreamsRunning ||
|
||||
linphone_call_get_state(call) == LinphoneCallPaused || linphone_call_get_state(call) == LinphoneCallPausing ||
|
||||
linphone_call_get_state(call) == LinphoneCallPausedByRemote) {
|
||||
ms_message("send SIP msg through the existing call.");
|
||||
op = linphone_call_get_op(call);
|
||||
identity = linphone_core_find_best_identity(d->core, linphone_call_get_remote_address(call));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (identity.empty()) {
|
||||
LinphoneProxyConfig *proxy = linphone_core_lookup_known_proxy(d->core, peer);
|
||||
if (proxy) {
|
||||
identity = L_GET_CPP_PTR_FROM_C_OBJECT(linphone_proxy_config_get_identity_address(proxy))->asString();
|
||||
} else {
|
||||
identity = linphone_core_get_primary_contact(d->core);
|
||||
}
|
||||
}
|
||||
msg->setFromAddress(identity);
|
||||
|
||||
// ---------------------------------------
|
||||
// Start of message modification
|
||||
// ---------------------------------------
|
||||
|
||||
int retval = -1;
|
||||
LinphoneImEncryptionEngine *imee = d->core->im_encryption_engine;
|
||||
if (imee) {
|
||||
LinphoneImEncryptionEngineCbs *imeeCbs = linphone_im_encryption_engine_get_callbacks(imee);
|
||||
LinphoneImEncryptionEngineCbsOutgoingMessageCb cbProcessOutgoingMessage = linphone_im_encryption_engine_cbs_get_process_outgoing_message(imeeCbs);
|
||||
if (cbProcessOutgoingMessage) {
|
||||
retval = cbProcessOutgoingMessage(imee, L_GET_C_BACK_PTR(this), L_GET_C_BACK_PTR(msg));
|
||||
if (retval == 0) {
|
||||
msg->setIsSecured(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (msg->getContents().size() > 1) {
|
||||
MultipartChatMessageModifier mcmm;
|
||||
mcmm.encode(msg->getPrivate());
|
||||
}
|
||||
|
||||
if (lp_config_get_int(d->core->config, "sip", "use_cpim", 0) == 1) {
|
||||
CpimChatMessageModifier ccmm;
|
||||
ccmm.encode(msg->getPrivate());
|
||||
}
|
||||
|
||||
// ---------------------------------------
|
||||
// End of message modification
|
||||
// ---------------------------------------
|
||||
|
||||
if (!op) {
|
||||
/* Sending out of call */
|
||||
msg->getPrivate()->setSalOp(op = new SalMessageOp(d->core->sal));
|
||||
linphone_configure_op(
|
||||
d->core, op, peer, msg->getPrivate()->getSalCustomHeaders(),
|
||||
!!lp_config_get_int(d->core->config, "sip", "chat_msg_with_contact", 0)
|
||||
);
|
||||
op->set_user_pointer(L_GET_C_BACK_PTR(msg)); /* If out of call, directly store msg */
|
||||
}
|
||||
|
||||
if (retval > 0) {
|
||||
sal_error_info_set((SalErrorInfo *)op->get_error_info(), SalReasonNotAcceptable, "SIP", retval, "Unable to encrypt IM", nullptr);
|
||||
d->storeOrUpdateMessage(msg);
|
||||
msg->updateState(ChatMessage::State::NotDelivered);
|
||||
linphone_address_unref(peer);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!msg->getExternalBodyUrl().empty()) {
|
||||
char *content_type = ms_strdup_printf("message/external-body; access-type=URL; URL=\"%s\"", msg->getExternalBodyUrl().c_str());
|
||||
auto msgOp = dynamic_cast<SalMessageOpInterface *>(op);
|
||||
msgOp->send_message(identity.c_str(), d->peerAddress.asString().c_str(), content_type, nullptr, nullptr);
|
||||
ms_free(content_type);
|
||||
} else {
|
||||
auto msgOp = dynamic_cast<SalMessageOpInterface *>(op);
|
||||
if (!msg->getPrivate()->getContentType().empty()) {
|
||||
msgOp->send_message(identity.c_str(), d->peerAddress.asString().c_str(), msg->getPrivate()->getContentType().c_str(), msg->getPrivate()->getText().c_str(), d->peerAddress.asStringUriOnly().c_str());
|
||||
} else {
|
||||
msgOp->send_message(identity.c_str(), d->peerAddress.asString().c_str(), msg->getPrivate()->getText().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
if (!msg->getPrivate()->getText().empty() && clearTextMessage && strcmp(msg->getPrivate()->getText().c_str(), clearTextMessage) != 0) {
|
||||
/* We replace the encrypted message by the original one so it can be correctly stored and displayed by the application */
|
||||
msg->getPrivate()->setText(clearTextMessage);
|
||||
}
|
||||
if (!msg->getPrivate()->getContentType().empty() && clearTextContentType && (strcmp(msg->getPrivate()->getContentType().c_str(), clearTextContentType) != 0)) {
|
||||
/* We replace the encrypted content type by the original one */
|
||||
msg->getPrivate()->setContentType(clearTextContentType);
|
||||
}
|
||||
msg->setId(op->get_call_id()); /* must be known at that time */
|
||||
d->storeOrUpdateMessage(msg);
|
||||
|
||||
if (d->isComposing)
|
||||
d->isComposing = false;
|
||||
d->isComposingHandler.stopIdleTimer();
|
||||
d->isComposingHandler.stopRefreshTimer();
|
||||
|
||||
if (clearTextMessage) {
|
||||
ms_free(clearTextMessage);
|
||||
}
|
||||
if (clearTextContentType) {
|
||||
ms_free(clearTextContentType);
|
||||
}
|
||||
linphone_address_unref(peer);
|
||||
|
||||
if (call && linphone_call_get_op(call) == op) {
|
||||
/* In this case, chat delivery status is not notified, so unrefing chat message right now */
|
||||
/* Might be better fixed by delivering status, but too costly for now */
|
||||
d->removeTransientMessage(msg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* If operation failed, we should not change message state */
|
||||
if (msg->isOutgoing()) {
|
||||
msg->getPrivate()->setIsReadOnly(true);
|
||||
msg->getPrivate()->setState(ChatMessage::State::InProgress);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue