mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-01-18 11:38:08 +00:00
Add ImdnMessage class.
This commit is contained in:
parent
75c981df03
commit
2888e84392
12 changed files with 300 additions and 53 deletions
|
|
@ -35,6 +35,7 @@ set(LINPHONE_CXX_OBJECTS_PRIVATE_HEADER_FILES
|
|||
call/remote-conference-call.h
|
||||
chat/chat-message/chat-message-p.h
|
||||
chat/chat-message/chat-message.h
|
||||
chat/chat-message/imdn-message.h
|
||||
chat/chat-message/is-composing-message.h
|
||||
chat/chat-message/notification-message.h
|
||||
chat/chat-message/notification-message-p.h
|
||||
|
|
@ -193,6 +194,7 @@ set(LINPHONE_CXX_OBJECTS_SOURCE_FILES
|
|||
call/local-conference-call.cpp
|
||||
call/remote-conference-call.cpp
|
||||
chat/chat-message/chat-message.cpp
|
||||
chat/chat-message/imdn-message.cpp
|
||||
chat/chat-message/is-composing-message.cpp
|
||||
chat/chat-message/notification-message.cpp
|
||||
chat/chat-room/abstract-chat-room.cpp
|
||||
|
|
|
|||
|
|
@ -154,8 +154,6 @@ public:
|
|||
|
||||
bool downloadFile ();
|
||||
|
||||
void sendImdn (Imdn::Type imdnType, LinphoneReason reason);
|
||||
|
||||
void notifyReceiving ();
|
||||
LinphoneReason receive ();
|
||||
void send ();
|
||||
|
|
|
|||
|
|
@ -179,7 +179,7 @@ void ChatMessagePrivate::setState (ChatMessage::State newState, bool force) {
|
|||
|
||||
if (state == ChatMessage::State::FileTransferDone && !hasFileTransferContent()) {
|
||||
// We wait until the file has been downloaded to send the displayed IMDN
|
||||
q->sendDisplayNotification();
|
||||
static_cast<ChatRoomPrivate *>(q->getChatRoom()->getPrivate())->sendDisplayNotification(q->getSharedFromThis());
|
||||
setState(ChatMessage::State::Displayed);
|
||||
} else {
|
||||
updateInDb();
|
||||
|
|
@ -454,26 +454,6 @@ void ChatMessagePrivate::setChatRoom (const shared_ptr<AbstractChatRoom> &cr) {
|
|||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void ChatMessagePrivate::sendImdn (Imdn::Type imdnType, LinphoneReason reason) {
|
||||
L_Q();
|
||||
|
||||
auto chatRoomPrivate = static_cast<ChatRoomPrivate *>(q->getChatRoom()->getPrivate());
|
||||
shared_ptr<ChatMessage> msg = chatRoomPrivate->createNotificationMessage(ChatMessage::Direction::Outgoing);
|
||||
|
||||
Content *content = new Content();
|
||||
content->setContentDisposition(ContentDisposition::Notification);
|
||||
content->setContentType(ContentType::Imdn);
|
||||
content->setBody(Imdn::createXml(imdnId, time, imdnType, reason));
|
||||
msg->addContent(content);
|
||||
|
||||
if (reason != LinphoneReasonNone)
|
||||
msg->getPrivate()->setEncryptionPrevented(true);
|
||||
|
||||
msg->getPrivate()->addSalCustomHeader(PriorityHeader::HeaderName, PriorityHeader::NonUrgent);
|
||||
|
||||
msg->getPrivate()->send();
|
||||
}
|
||||
|
||||
static void forceUtf8Content (Content &content) {
|
||||
// TODO: Deal with other content type in the future.
|
||||
ContentType contentType = content.getContentType();
|
||||
|
|
@ -524,7 +504,7 @@ void ChatMessagePrivate::notifyReceiving () {
|
|||
q->getChatRoom()->getPrivate()->notifyChatMessageReceived(q->getSharedFromThis());
|
||||
|
||||
if (getPositiveDeliveryNotificationRequired())
|
||||
q->sendDeliveryNotification(LinphoneReasonNone);
|
||||
static_cast<ChatRoomPrivate *>(q->getChatRoom()->getPrivate())->sendDeliveryNotification(q->getSharedFromThis());
|
||||
}
|
||||
|
||||
LinphoneReason ChatMessagePrivate::receive () {
|
||||
|
|
@ -549,7 +529,10 @@ LinphoneReason ChatMessagePrivate::receive () {
|
|||
chatRoom->getPrivate()->notifyUndecryptableChatMessageReceived(q->getSharedFromThis());
|
||||
reason = linphone_error_code_to_reason(errorCode);
|
||||
if (getNegativeDeliveryNotificationRequired()) {
|
||||
q->sendDeliveryNotification(reason);
|
||||
static_cast<ChatRoomPrivate *>(q->getChatRoom()->getPrivate())->sendDeliveryErrorNotification(
|
||||
q->getSharedFromThis(),
|
||||
reason
|
||||
);
|
||||
}
|
||||
return reason;
|
||||
} else if (result == ChatMessageModifier::Result::Suspended) {
|
||||
|
|
@ -635,7 +618,10 @@ LinphoneReason ChatMessagePrivate::receive () {
|
|||
if (errorCode > 0) {
|
||||
reason = linphone_error_code_to_reason(errorCode);
|
||||
if (getNegativeDeliveryNotificationRequired()) {
|
||||
q->sendDeliveryNotification(reason);
|
||||
static_cast<ChatRoomPrivate *>(q->getChatRoom()->getPrivate())->sendDeliveryErrorNotification(
|
||||
q->getSharedFromThis(),
|
||||
reason
|
||||
);
|
||||
}
|
||||
return reason;
|
||||
}
|
||||
|
|
@ -1123,22 +1109,6 @@ void ChatMessage::send () {
|
|||
getChatRoom()->getPrivate()->sendChatMessage(getSharedFromThis());
|
||||
}
|
||||
|
||||
void ChatMessage::sendDeliveryNotification (LinphoneReason reason) {
|
||||
L_D();
|
||||
|
||||
LinphoneImNotifPolicy *policy = linphone_core_get_im_notif_policy(getCore()->getCCore());
|
||||
if (linphone_im_notif_policy_get_send_imdn_delivered(policy))
|
||||
d->sendImdn(Imdn::Type::Delivery, reason);
|
||||
}
|
||||
|
||||
void ChatMessage::sendDisplayNotification () {
|
||||
L_D();
|
||||
|
||||
LinphoneImNotifPolicy *policy = linphone_core_get_im_notif_policy(getCore()->getCCore());
|
||||
if (linphone_im_notif_policy_get_send_imdn_displayed(policy))
|
||||
d->sendImdn(Imdn::Type::Display, LinphoneReasonNone);
|
||||
}
|
||||
|
||||
bool ChatMessage::downloadFile(FileTransferContent *fileTransferContent) {
|
||||
L_D();
|
||||
return d->fileTransferChatMessageModifier.downloadFile(getSharedFromThis(), fileTransferContent);
|
||||
|
|
|
|||
|
|
@ -66,8 +66,6 @@ public:
|
|||
// ----- TODO: Remove me.
|
||||
void cancelFileTransfer ();
|
||||
int putCharacter (uint32_t character);
|
||||
void sendDeliveryNotification (LinphoneReason reason);
|
||||
void sendDisplayNotification ();
|
||||
void setIsSecured (bool isSecured);
|
||||
// ----- TODO: Remove me.
|
||||
|
||||
|
|
|
|||
76
src/chat/chat-message/imdn-message.cpp
Normal file
76
src/chat/chat-message/imdn-message.cpp
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* imdn-message.cpp
|
||||
* Copyright (C) 2010-2018 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.
|
||||
*/
|
||||
|
||||
#include "chat/chat-message/notification-message-p.h"
|
||||
#include "chat/chat-message/imdn-message.h"
|
||||
#include "content/content-disposition.h"
|
||||
#include "sip-tools/sip-headers.h"
|
||||
|
||||
// =============================================================================
|
||||
|
||||
using namespace std;
|
||||
|
||||
LINPHONE_BEGIN_NAMESPACE
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
ImdnMessage::ImdnMessage (
|
||||
const shared_ptr<AbstractChatRoom> &chatRoom,
|
||||
const list<const shared_ptr<ChatMessage>> &deliveredMessages,
|
||||
const list<const shared_ptr<ChatMessage>> &displayedMessages
|
||||
) : NotificationMessage(*new NotificationMessagePrivate(chatRoom, ChatMessage::Direction::Outgoing)) {
|
||||
L_D();
|
||||
|
||||
for (const auto &message : deliveredMessages) {
|
||||
Content *content = new Content();
|
||||
content->setContentDisposition(ContentDisposition::Notification);
|
||||
content->setContentType(ContentType::Imdn);
|
||||
content->setBody(Imdn::createXml(message->getImdnMessageId(), message->getTime(), Imdn::Type::Delivery, LinphoneReasonNone));
|
||||
addContent(content);
|
||||
}
|
||||
for (const auto &message : displayedMessages) {
|
||||
Content *content = new Content();
|
||||
content->setContentDisposition(ContentDisposition::Notification);
|
||||
content->setContentType(ContentType::Imdn);
|
||||
content->setBody(Imdn::createXml(message->getImdnMessageId(), message->getTime(), Imdn::Type::Display, LinphoneReasonNone));
|
||||
addContent(content);
|
||||
}
|
||||
|
||||
d->addSalCustomHeader(PriorityHeader::HeaderName, PriorityHeader::NonUrgent);
|
||||
}
|
||||
|
||||
ImdnMessage::ImdnMessage (
|
||||
const shared_ptr<AbstractChatRoom> &chatRoom,
|
||||
const list<Imdn::MessageReason> &nonDeliveredMessages
|
||||
) : NotificationMessage(*new NotificationMessagePrivate(chatRoom, ChatMessage::Direction::Outgoing)) {
|
||||
L_D();
|
||||
|
||||
for (const auto &mr : nonDeliveredMessages) {
|
||||
Content *content = new Content();
|
||||
content->setContentDisposition(ContentDisposition::Notification);
|
||||
content->setContentType(ContentType::Imdn);
|
||||
content->setBody(Imdn::createXml(mr.message->getImdnMessageId(), mr.message->getTime(), Imdn::Type::Delivery, mr.reason));
|
||||
addContent(content);
|
||||
}
|
||||
|
||||
d->addSalCustomHeader(PriorityHeader::HeaderName, PriorityHeader::NonUrgent);
|
||||
d->setEncryptionPrevented(true);
|
||||
}
|
||||
|
||||
LINPHONE_END_NAMESPACE
|
||||
54
src/chat/chat-message/imdn-message.h
Normal file
54
src/chat/chat-message/imdn-message.h
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* imdn-message.h
|
||||
* Copyright (C) 2010-2018 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 _L_IMDN_MESSAGE_H_
|
||||
#define _L_IMDN_MESSAGE_H_
|
||||
|
||||
#include "chat/chat-message/notification-message.h"
|
||||
|
||||
// =============================================================================
|
||||
|
||||
LINPHONE_BEGIN_NAMESPACE
|
||||
|
||||
class LINPHONE_PUBLIC ImdnMessage : public NotificationMessage {
|
||||
public:
|
||||
friend class ChatRoomPrivate;
|
||||
|
||||
L_OVERRIDE_SHARED_FROM_THIS(ImdnMessage);
|
||||
|
||||
virtual ~ImdnMessage () = default;
|
||||
|
||||
private:
|
||||
ImdnMessage (
|
||||
const std::shared_ptr<AbstractChatRoom> &chatRoom,
|
||||
const std::list<const std::shared_ptr<ChatMessage>> &deliveredMessages,
|
||||
const std::list<const std::shared_ptr<ChatMessage>> &displayedMessages
|
||||
);
|
||||
ImdnMessage (
|
||||
const std::shared_ptr<AbstractChatRoom> &chatRoom,
|
||||
const std::list<Imdn::MessageReason> &nonDeliveredMessages
|
||||
);
|
||||
|
||||
L_DECLARE_PRIVATE(NotificationMessage);
|
||||
L_DISABLE_COPY(ImdnMessage);
|
||||
};
|
||||
|
||||
LINPHONE_END_NAMESPACE
|
||||
|
||||
#endif // ifndef _L_IMDN_MESSAGE_H_
|
||||
|
|
@ -28,6 +28,7 @@
|
|||
LINPHONE_BEGIN_NAMESPACE
|
||||
|
||||
class NotificationMessagePrivate : public ChatMessagePrivate {
|
||||
friend class ImdnMessage;
|
||||
friend class IsComposingMessage;
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#include "abstract-chat-room-p.h"
|
||||
#include "chat-room-id.h"
|
||||
#include "chat-room.h"
|
||||
#include "chat/notification/imdn.h"
|
||||
#include "chat/notification/is-composing.h"
|
||||
|
||||
// =============================================================================
|
||||
|
|
@ -54,10 +55,18 @@ public:
|
|||
void removeTransientEvent (const std::shared_ptr<EventLog> &eventLog) override;
|
||||
|
||||
std::shared_ptr<ChatMessage> createChatMessage (ChatMessage::Direction direction);
|
||||
std::shared_ptr<ChatMessage> createImdnMessage (
|
||||
const std::list<const std::shared_ptr<ChatMessage>> &deliveredMessages,
|
||||
const std::list<const std::shared_ptr<ChatMessage>> &displayedMessages
|
||||
);
|
||||
std::shared_ptr<ChatMessage> createImdnMessage (const std::list<Imdn::MessageReason> &nonDeliveredMessages);
|
||||
std::shared_ptr<ChatMessage> createIsComposingMessage ();
|
||||
std::shared_ptr<ChatMessage> createNotificationMessage (ChatMessage::Direction direction);
|
||||
std::list<std::shared_ptr<ChatMessage>> findChatMessages (const std::string &messageId) const;
|
||||
|
||||
void sendDeliveryErrorNotification (const std::shared_ptr<ChatMessage> &message, LinphoneReason reason);
|
||||
void sendDeliveryNotification (const std::shared_ptr<ChatMessage> &message);
|
||||
void sendDisplayNotification (const std::shared_ptr<ChatMessage> &message);
|
||||
|
||||
void notifyChatMessageReceived (const std::shared_ptr<ChatMessage> &chatMessage) override;
|
||||
void notifyIsComposingReceived (const Address &remoteAddress, bool isComposing);
|
||||
void notifyStateChanged ();
|
||||
|
|
@ -86,6 +95,7 @@ private:
|
|||
time_t creationTime = std::time(nullptr);
|
||||
time_t lastUpdateTime = std::time(nullptr);
|
||||
|
||||
std::unique_ptr<Imdn> imdnHandler;
|
||||
std::unique_ptr<IsComposing> isComposingHandler;
|
||||
|
||||
bool isComposing = false;
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@
|
|||
|
||||
#include "c-wrapper/c-wrapper.h"
|
||||
#include "chat/chat-message/chat-message-p.h"
|
||||
#include "chat/chat-message/imdn-message.h"
|
||||
#include "chat/chat-message/is-composing-message.h"
|
||||
#include "chat/chat-message/notification-message.h"
|
||||
#include "chat/chat-room/chat-room-p.h"
|
||||
#include "core/core-p.h"
|
||||
#include "logger/logger.h"
|
||||
|
|
@ -109,16 +109,24 @@ shared_ptr<ChatMessage> ChatRoomPrivate::createChatMessage (ChatMessage::Directi
|
|||
return shared_ptr<ChatMessage>(new ChatMessage(q->getSharedFromThis(), direction));
|
||||
}
|
||||
|
||||
shared_ptr<ChatMessage> ChatRoomPrivate::createImdnMessage (
|
||||
const list<const shared_ptr<ChatMessage>> &deliveredMessages,
|
||||
const list<const shared_ptr<ChatMessage>> &displayedMessages
|
||||
) {
|
||||
L_Q();
|
||||
return shared_ptr<ChatMessage>(new ImdnMessage(q->getSharedFromThis(), deliveredMessages, displayedMessages));
|
||||
}
|
||||
|
||||
shared_ptr<ChatMessage> ChatRoomPrivate::createImdnMessage (const list<Imdn::MessageReason> &nonDeliveredMessages) {
|
||||
L_Q();
|
||||
return shared_ptr<ChatMessage>(new ImdnMessage(q->getSharedFromThis(), nonDeliveredMessages));
|
||||
}
|
||||
|
||||
shared_ptr<ChatMessage> ChatRoomPrivate::createIsComposingMessage () {
|
||||
L_Q();
|
||||
return shared_ptr<ChatMessage>(new IsComposingMessage(q->getSharedFromThis(), *isComposingHandler.get(), isComposing));
|
||||
}
|
||||
|
||||
shared_ptr<ChatMessage> ChatRoomPrivate::createNotificationMessage (ChatMessage::Direction direction) {
|
||||
L_Q();
|
||||
return shared_ptr<ChatMessage>(new NotificationMessage(q->getSharedFromThis(), direction));
|
||||
}
|
||||
|
||||
list<shared_ptr<ChatMessage>> ChatRoomPrivate::findChatMessages (const string &messageId) const {
|
||||
L_Q();
|
||||
return q->getCore()->getPrivate()->mainDb->findChatMessages(q->getChatRoomId(), messageId);
|
||||
|
|
@ -126,6 +134,29 @@ list<shared_ptr<ChatMessage>> ChatRoomPrivate::findChatMessages (const string &m
|
|||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void ChatRoomPrivate::sendDeliveryErrorNotification (const shared_ptr<ChatMessage> &message, LinphoneReason reason) {
|
||||
L_Q();
|
||||
LinphoneImNotifPolicy *policy = linphone_core_get_im_notif_policy(q->getCore()->getCCore());
|
||||
if (linphone_im_notif_policy_get_send_imdn_delivered(policy))
|
||||
imdnHandler->notifyDeliveryError(message, reason);
|
||||
}
|
||||
|
||||
void ChatRoomPrivate::sendDeliveryNotification (const shared_ptr<ChatMessage> &message) {
|
||||
L_Q();
|
||||
LinphoneImNotifPolicy *policy = linphone_core_get_im_notif_policy(q->getCore()->getCCore());
|
||||
if (linphone_im_notif_policy_get_send_imdn_delivered(policy))
|
||||
imdnHandler->notifyDelivery(message);
|
||||
}
|
||||
|
||||
void ChatRoomPrivate::sendDisplayNotification (const shared_ptr<ChatMessage> &message) {
|
||||
L_Q();
|
||||
LinphoneImNotifPolicy *policy = linphone_core_get_im_notif_policy(q->getCore()->getCCore());
|
||||
if (linphone_im_notif_policy_get_send_imdn_displayed(policy))
|
||||
imdnHandler->notifyDisplay(message);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void ChatRoomPrivate::notifyChatMessageReceived (const shared_ptr<ChatMessage> &chatMessage) {
|
||||
L_Q();
|
||||
LinphoneChatRoom *cr = getCChatRoom();
|
||||
|
|
@ -279,6 +310,7 @@ ChatRoom::ChatRoom (ChatRoomPrivate &p, const shared_ptr<Core> &core, const Chat
|
|||
L_D();
|
||||
|
||||
d->chatRoomId = chatRoomId;
|
||||
d->imdnHandler.reset(new Imdn(this));
|
||||
d->isComposingHandler.reset(new IsComposing(core->getCCore(), d));
|
||||
}
|
||||
|
||||
|
|
@ -440,7 +472,7 @@ void ChatRoom::markAsRead () {
|
|||
for (auto &chatMessage : dCore->mainDb->getUnreadChatMessages(d->chatRoomId)) {
|
||||
// Do not send display notification for file transfer until it has been downloaded (it won't have a file transfer content anymore)
|
||||
if (!chatMessage->getPrivate()->hasFileTransferContent()) {
|
||||
chatMessage->sendDisplayNotification();
|
||||
d->sendDisplayNotification(chatMessage);
|
||||
chatMessage->getPrivate()->setState(ChatMessage::State::Displayed, true); // True will ensure the setState won't update the database so it will be done below by the markChatMessagesAsRead
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ class ChatRoomPrivate;
|
|||
class LINPHONE_PUBLIC ChatRoom : public AbstractChatRoom {
|
||||
public:
|
||||
friend class ChatMessagePrivate;
|
||||
friend class Imdn;
|
||||
friend class ProxyChatRoomPrivate;
|
||||
|
||||
L_OVERRIDE_SHARED_FROM_THIS(ChatRoom);
|
||||
|
|
|
|||
|
|
@ -17,8 +17,10 @@
|
|||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "chat/chat-message/chat-message-p.h"
|
||||
#include "chat/chat-room/chat-room.h"
|
||||
#include "chat/chat-room/chat-room-p.h"
|
||||
#include "core/core.h"
|
||||
#include "logger/logger.h"
|
||||
|
||||
|
|
@ -32,6 +34,46 @@ LINPHONE_BEGIN_NAMESPACE
|
|||
|
||||
const string Imdn::imdnPrefix = "/imdn:imdn";
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
Imdn::Imdn (ChatRoom *chatRoom) : chatRoom(chatRoom) {}
|
||||
|
||||
Imdn::~Imdn () {
|
||||
stopTimer();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void Imdn::notifyDelivery (const shared_ptr<ChatMessage> &message) {
|
||||
if (find(deliveredMessages.begin(), deliveredMessages.end(), message) == deliveredMessages.end()) {
|
||||
deliveredMessages.push_back(message);
|
||||
startTimer();
|
||||
}
|
||||
}
|
||||
|
||||
void Imdn::notifyDeliveryError (const shared_ptr<ChatMessage> &message, LinphoneReason reason) {
|
||||
auto it = find_if(nonDeliveredMessages.begin(), nonDeliveredMessages.end(), [message](const MessageReason mr) {
|
||||
return message == mr.message;
|
||||
});
|
||||
if (it == nonDeliveredMessages.end()) {
|
||||
nonDeliveredMessages.emplace_back(message, reason);
|
||||
startTimer();
|
||||
}
|
||||
}
|
||||
|
||||
void Imdn::notifyDisplay (const shared_ptr<ChatMessage> &message) {
|
||||
auto it = find(deliveredMessages.begin(), deliveredMessages.end(), message);
|
||||
if (it != deliveredMessages.end())
|
||||
deliveredMessages.erase(it);
|
||||
|
||||
if (find(displayedMessages.begin(), displayedMessages.end(), message) == displayedMessages.end()) {
|
||||
displayedMessages.push_back(message);
|
||||
startTimer();
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
string Imdn::createXml (const string &id, time_t time, Imdn::Type imdnType, LinphoneReason reason) {
|
||||
xmlBufferPtr buf;
|
||||
xmlTextWriterPtr writer;
|
||||
|
|
@ -144,6 +186,8 @@ void Imdn::parse (const shared_ptr<ChatMessage> &chatMessage) {
|
|||
linphone_xmlparsing_context_destroy(xmlCtx);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void Imdn::parse (const shared_ptr<ChatMessage> &imdnMessage, xmlparsing_context_t *xmlCtx) {
|
||||
char xpathStr[MAX_XPATH_LENGTH];
|
||||
char *messageIdStr = nullptr;
|
||||
|
|
@ -208,4 +252,38 @@ void Imdn::parse (const shared_ptr<ChatMessage> &imdnMessage, xmlparsing_context
|
|||
linphone_free_xml_text_content(datetimeStr);
|
||||
}
|
||||
|
||||
int Imdn::timerExpired (void *data, unsigned int revents) {
|
||||
Imdn *d = reinterpret_cast<Imdn *>(data);
|
||||
d->stopTimer();
|
||||
d->send();
|
||||
return BELLE_SIP_STOP;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void Imdn::send () {
|
||||
if (!deliveredMessages.empty() || !displayedMessages.empty())
|
||||
chatRoom->getPrivate()->createImdnMessage(deliveredMessages, displayedMessages)->send();
|
||||
if (!nonDeliveredMessages.empty())
|
||||
chatRoom->getPrivate()->createImdnMessage(nonDeliveredMessages)->send();
|
||||
}
|
||||
|
||||
void Imdn::startTimer () {
|
||||
unsigned int duration = 500;
|
||||
if (!timer)
|
||||
timer = chatRoom->getCore()->getCCore()->sal->create_timer(timerExpired, this, duration, "imdn timeout");
|
||||
else
|
||||
belle_sip_source_set_timeout(timer, duration);
|
||||
}
|
||||
|
||||
void Imdn::stopTimer () {
|
||||
if (timer) {
|
||||
auto core = chatRoom->getCore()->getCCore();
|
||||
if (core && core->sal)
|
||||
core->sal->cancel_timer(timer);
|
||||
belle_sip_object_unref(timer);
|
||||
timer = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
LINPHONE_END_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
LINPHONE_BEGIN_NAMESPACE
|
||||
|
||||
class ChatMessage;
|
||||
class ChatRoom;
|
||||
|
||||
class Imdn {
|
||||
|
|
@ -37,14 +38,40 @@ public:
|
|||
Display
|
||||
};
|
||||
|
||||
struct MessageReason {
|
||||
MessageReason (const std::shared_ptr<ChatMessage> &message, LinphoneReason reason)
|
||||
: message(message), reason(reason) {}
|
||||
|
||||
const std::shared_ptr<ChatMessage> message;
|
||||
LinphoneReason reason;
|
||||
};
|
||||
|
||||
Imdn (ChatRoom *chatRoom);
|
||||
~Imdn ();
|
||||
|
||||
void notifyDelivery (const std::shared_ptr<ChatMessage> &message);
|
||||
void notifyDeliveryError (const std::shared_ptr<ChatMessage> &message, LinphoneReason reason);
|
||||
void notifyDisplay (const std::shared_ptr<ChatMessage> &message);
|
||||
|
||||
static std::string createXml (const std::string &id, time_t time, Imdn::Type imdnType, LinphoneReason reason);
|
||||
static void parse (const std::shared_ptr<ChatMessage> &chatMessage);
|
||||
|
||||
private:
|
||||
static void parse (const std::shared_ptr<ChatMessage> &chatMessage, xmlparsing_context_t *xmlCtx);
|
||||
static int timerExpired (void *data, unsigned int revents);
|
||||
|
||||
void send ();
|
||||
void startTimer ();
|
||||
void stopTimer ();
|
||||
|
||||
private:
|
||||
static const std::string imdnPrefix;
|
||||
|
||||
ChatRoom *chatRoom = nullptr;
|
||||
std::list<const std::shared_ptr<ChatMessage>> deliveredMessages;
|
||||
std::list<const std::shared_ptr<ChatMessage>> displayedMessages;
|
||||
std::list<MessageReason> nonDeliveredMessages;
|
||||
belle_sip_source_t *timer = nullptr;
|
||||
};
|
||||
|
||||
LINPHONE_END_NAMESPACE
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue