Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
10
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
BC
public
liblinphone
Commits
d1dc2238
Commit
d1dc2238
authored
Apr 13, 2018
by
Ghislain MARY
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Handle imdn namespace and Disposition-Notification header in CPIM.
parent
f4f642a4
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
210 additions
and
34 deletions
+210
-34
src/CMakeLists.txt
src/CMakeLists.txt
+2
-0
src/chat/chat-message/chat-message-p.h
src/chat/chat-message/chat-message-p.h
+19
-7
src/chat/chat-message/chat-message.cpp
src/chat/chat-message/chat-message.cpp
+7
-5
src/chat/chat-message/chat-message.h
src/chat/chat-message/chat-message.h
+5
-2
src/chat/chat-message/notification-message.cpp
src/chat/chat-message/notification-message.cpp
+55
-0
src/chat/chat-message/notification-message.h
src/chat/chat-message/notification-message.h
+50
-0
src/chat/chat-room/chat-room-p.h
src/chat/chat-room/chat-room-p.h
+1
-0
src/chat/chat-room/chat-room.cpp
src/chat/chat-room/chat-room.cpp
+13
-13
src/chat/modifier/cpim-chat-message-modifier.cpp
src/chat/modifier/cpim-chat-message-modifier.cpp
+58
-7
No files found.
src/CMakeLists.txt
View file @
d1dc2238
...
...
@@ -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/notification-message.h
chat/chat-room/abstract-chat-room-p.h
chat/chat-room/abstract-chat-room.h
chat/chat-room/basic-chat-room-p.h
...
...
@@ -190,6 +191,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/notification-message.cpp
chat/chat-room/abstract-chat-room.cpp
chat/chat-room/basic-chat-room.cpp
chat/chat-room/basic-to-client-group-chat-room.cpp
...
...
src/chat/chat-message/chat-message-p.h
View file @
d1dc2238
...
...
@@ -44,6 +44,7 @@ class ChatMessagePrivate : public ObjectPrivate {
friend
class
CpimChatMessageModifier
;
friend
class
EncryptionChatMessageModifier
;
friend
class
MultipartChatMessageModifier
;
friend
class
NotificationMessagePrivate
;
public:
enum
Step
{
...
...
@@ -99,6 +100,13 @@ public:
SalOp
*
getSalOp
()
const
;
void
setSalOp
(
SalOp
*
op
);
bool
getDisplayNotificationRequired
()
const
{
return
displayNotificationRequired
;
}
bool
getNegativeDeliveryNotificationRequired
()
const
{
return
negativeDeliveryNotificationRequired
;
}
bool
getPositiveDeliveryNotificationRequired
()
const
{
return
positiveDeliveryNotificationRequired
;
}
virtual
void
setDisplayNotificationRequired
(
bool
value
)
{
displayNotificationRequired
=
value
;
}
virtual
void
setNegativeDeliveryNotificationRequired
(
bool
value
)
{
negativeDeliveryNotificationRequired
=
value
;
}
virtual
void
setPositiveDeliveryNotificationRequired
(
bool
value
)
{
positiveDeliveryNotificationRequired
=
value
;
}
SalCustomHeader
*
getSalCustomHeaders
()
const
;
void
setSalCustomHeaders
(
SalCustomHeader
*
headers
);
...
...
@@ -156,11 +164,20 @@ public:
void
updateInDb
();
private:
ChatMessagePrivate
(
const
std
::
shared_ptr
<
AbstractChatRoom
>
&
cr
,
ChatMessage
::
Direction
dir
);
static
bool
validStateTransition
(
ChatMessage
::
State
currentState
,
ChatMessage
::
State
newState
);
public:
mutable
MainDbChatMessageKey
dbKey
;
protected:
bool
displayNotificationRequired
=
true
;
bool
negativeDeliveryNotificationRequired
=
true
;
bool
positiveDeliveryNotificationRequired
=
true
;
bool
toBeStored
=
true
;
private:
// TODO: Clean attributes.
time_t
time
=
::
ms_time
(
0
);
// TODO: Change me in all files.
std
::
string
imdnId
;
...
...
@@ -189,10 +206,6 @@ private:
// TODO: Remove my comment. VARIABLES OK.
// Do not expose.
public:
mutable
MainDbChatMessageKey
dbKey
;
private:
std
::
weak_ptr
<
AbstractChatRoom
>
chatRoom
;
ChatRoomId
chatRoomId
;
IdentityAddress
fromAddress
;
...
...
@@ -204,7 +217,6 @@ private:
std
::
list
<
Content
*
>
contents
;
bool
encryptionPrevented
=
false
;
bool
toBeStored
=
true
;
mutable
bool
contentsNotLoadedFromDatabase
=
false
;
L_DECLARE_PUBLIC
(
ChatMessage
);
};
...
...
src/chat/chat-message/chat-message.cpp
View file @
d1dc2238
...
...
@@ -457,7 +457,8 @@ void ChatMessagePrivate::setChatRoom (const shared_ptr<AbstractChatRoom> &cr) {
void
ChatMessagePrivate
::
sendImdn
(
Imdn
::
Type
imdnType
,
LinphoneReason
reason
)
{
L_Q
();
shared_ptr
<
ChatMessage
>
msg
=
q
->
getChatRoom
()
->
createChatMessage
();
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
);
...
...
@@ -468,7 +469,6 @@ void ChatMessagePrivate::sendImdn (Imdn::Type imdnType, LinphoneReason reason) {
if
(
reason
!=
LinphoneReasonNone
)
msg
->
getPrivate
()
->
setEncryptionPrevented
(
true
);
msg
->
setToBeStored
(
false
);
msg
->
getPrivate
()
->
addSalCustomHeader
(
PriorityHeader
::
HeaderName
,
PriorityHeader
::
NonUrgent
);
msg
->
getPrivate
()
->
send
();
...
...
@@ -523,9 +523,8 @@ void ChatMessagePrivate::notifyReceiving () {
// Legacy
q
->
getChatRoom
()
->
getPrivate
()
->
notifyChatMessageReceived
(
q
->
getSharedFromThis
());
if
(
(
get
ContentType
()
!=
ContentType
::
Imdn
)
&&
(
getContentType
()
!=
ContentType
::
ImIsComposing
))
{
if
(
get
PositiveDeliveryNotificationRequired
())
q
->
sendDeliveryNotification
(
LinphoneReasonNone
);
}
}
LinphoneReason
ChatMessagePrivate
::
receive
()
{
...
...
@@ -894,7 +893,10 @@ bool ChatMessagePrivate::validStateTransition (ChatMessage::State currentState,
// -----------------------------------------------------------------------------
ChatMessage
::
ChatMessage
(
const
shared_ptr
<
AbstractChatRoom
>
&
chatRoom
,
ChatMessage
::
Direction
direction
)
:
Object
(
*
new
ChatMessagePrivate
(
chatRoom
,
direction
)),
CoreAccessor
(
chatRoom
->
getCore
())
{
Object
(
*
new
ChatMessagePrivate
(
chatRoom
,
direction
)),
CoreAccessor
(
chatRoom
->
getCore
())
{
}
ChatMessage
::
ChatMessage
(
ChatMessagePrivate
&
p
)
:
Object
(
p
),
CoreAccessor
(
p
.
getPublic
()
->
getChatRoom
()
->
getCore
())
{
}
ChatMessage
::~
ChatMessage
()
{
...
...
src/chat/chat-message/chat-message.h
View file @
d1dc2238
...
...
@@ -61,7 +61,7 @@ public:
L_DECLARE_ENUM
(
State
,
L_ENUM_VALUES_CHAT_MESSAGE_STATE
);
L_DECLARE_ENUM
(
Direction
,
L_ENUM_VALUES_CHAT_MESSAGE_DIRECTION
);
~
ChatMessage
();
virtual
~
ChatMessage
();
// ----- TODO: Remove me.
void
cancelFileTransfer
();
...
...
@@ -93,7 +93,7 @@ public:
bool
isReadOnly
()
const
;
bool
getToBeStored
()
const
;
void
setToBeStored
(
bool
value
);
virtual
void
setToBeStored
(
bool
value
);
std
::
list
<
ParticipantImdnState
>
getParticipantsThatHaveDisplayed
()
const
;
std
::
list
<
ParticipantImdnState
>
getParticipantsThatHaveReceived
()
const
;
...
...
@@ -114,6 +114,9 @@ public:
bool
downloadFile
(
FileTransferContent
*
content
);
bool
isFileTransferInProgress
();
protected:
explicit
ChatMessage
(
ChatMessagePrivate
&
p
);
private:
ChatMessage
(
const
std
::
shared_ptr
<
AbstractChatRoom
>
&
chatRoom
,
ChatMessage
::
Direction
direction
);
...
...
src/chat/chat-message/notification-message.cpp
0 → 100644
View file @
d1dc2238
/*
* notification-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/chat-message-p.h"
#include "chat/chat-message/notification-message.h"
// =============================================================================
using
namespace
std
;
LINPHONE_BEGIN_NAMESPACE
class
NotificationMessagePrivate
:
public
ChatMessagePrivate
{
private:
NotificationMessagePrivate
(
const
std
::
shared_ptr
<
AbstractChatRoom
>
&
cr
,
ChatMessage
::
Direction
dir
)
:
ChatMessagePrivate
(
cr
,
dir
)
{}
void
setDisplayNotificationRequired
(
bool
value
)
override
{}
void
setNegativeDeliveryNotificationRequired
(
bool
value
)
override
{}
void
setPositiveDeliveryNotificationRequired
(
bool
value
)
override
{}
L_DECLARE_PUBLIC
(
NotificationMessage
);
};
// -----------------------------------------------------------------------------
NotificationMessage
::
NotificationMessage
(
const
shared_ptr
<
AbstractChatRoom
>
&
chatRoom
,
ChatMessage
::
Direction
direction
)
:
ChatMessage
(
*
new
NotificationMessagePrivate
(
chatRoom
,
direction
))
{
L_D
();
d
->
displayNotificationRequired
=
false
;
d
->
negativeDeliveryNotificationRequired
=
false
;
d
->
positiveDeliveryNotificationRequired
=
false
;
d
->
toBeStored
=
false
;
}
void
NotificationMessage
::
setToBeStored
(
bool
value
)
{
}
LINPHONE_END_NAMESPACE
src/chat/chat-message/notification-message.h
0 → 100644
View file @
d1dc2238
/*
* notification-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_NOTIFICATION_MESSAGE_H_
#define _L_NOTIFICATION_MESSAGE_H_
#include "chat/chat-message/chat-message.h"
// =============================================================================
LINPHONE_BEGIN_NAMESPACE
class
NotificationMessagePrivate
;
class
LINPHONE_PUBLIC
NotificationMessage
:
public
ChatMessage
{
public:
friend
class
ChatRoomPrivate
;
L_OVERRIDE_SHARED_FROM_THIS
(
NotificationMessage
);
virtual
~
NotificationMessage
()
=
default
;
void
setToBeStored
(
bool
value
)
override
;
private:
NotificationMessage
(
const
std
::
shared_ptr
<
AbstractChatRoom
>
&
chatRoom
,
ChatMessage
::
Direction
direction
);
L_DECLARE_PRIVATE
(
NotificationMessage
);
L_DISABLE_COPY
(
NotificationMessage
);
};
LINPHONE_END_NAMESPACE
#endif // ifndef _L_NOTIFICATION_MESSAGE_H_
src/chat/chat-room/chat-room-p.h
View file @
d1dc2238
...
...
@@ -54,6 +54,7 @@ public:
void
removeTransientEvent
(
const
std
::
shared_ptr
<
EventLog
>
&
eventLog
)
override
;
std
::
shared_ptr
<
ChatMessage
>
createChatMessage
(
ChatMessage
::
Direction
direction
);
std
::
shared_ptr
<
ChatMessage
>
createNotificationMessage
(
ChatMessage
::
Direction
direction
);
std
::
list
<
std
::
shared_ptr
<
ChatMessage
>>
findChatMessages
(
const
std
::
string
&
messageId
)
const
;
void
notifyChatMessageReceived
(
const
std
::
shared_ptr
<
ChatMessage
>
&
chatMessage
)
override
;
...
...
src/chat/chat-room/chat-room.cpp
View file @
d1dc2238
...
...
@@ -23,6 +23,7 @@
#include "c-wrapper/c-wrapper.h"
#include "chat/chat-message/chat-message-p.h"
#include "chat/chat-message/notification-message.h"
#include "chat/chat-room/chat-room-p.h"
#include "core/core-p.h"
#include "sip-tools/sip-headers.h"
...
...
@@ -84,8 +85,7 @@ void ChatRoomPrivate::sendIsComposingNotification () {
content
->
setContentType
(
ContentType
::
ImIsComposing
);
content
->
setBody
(
payload
);
shared_ptr
<
ChatMessage
>
chatMessage
=
createChatMessage
(
ChatMessage
::
Direction
::
Outgoing
);
chatMessage
->
setToBeStored
(
false
);
shared_ptr
<
ChatMessage
>
chatMessage
=
createNotificationMessage
(
ChatMessage
::
Direction
::
Outgoing
);
chatMessage
->
addContent
(
content
);
chatMessage
->
getPrivate
()
->
addSalCustomHeader
(
PriorityHeader
::
HeaderName
,
PriorityHeader
::
NonUrgent
);
chatMessage
->
getPrivate
()
->
addSalCustomHeader
(
"Expires"
,
"0"
);
...
...
@@ -121,6 +121,11 @@ shared_ptr<ChatMessage> ChatRoomPrivate::createChatMessage (ChatMessage::Directi
return
shared_ptr
<
ChatMessage
>
(
new
ChatMessage
(
q
->
getSharedFromThis
(),
direction
));
}
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
);
...
...
@@ -214,26 +219,21 @@ LinphoneReason ChatRoomPrivate::onSipMessageReceived (SalOp *op, const SalMessag
reason
=
msg
->
getPrivate
()
->
receive
();
if
(
reason
==
LinphoneReasonNotAcceptable
||
reason
==
LinphoneReasonUnknown
)
{
/* Return LinphoneReasonNone to avoid flexisip resending us a message we can't decrypt */
reason
=
LinphoneReasonNone
;
goto
end
;
// Return LinphoneReasonNone to avoid flexisip resending us a message we can't decrypt
return
LinphoneReasonNone
;
}
if
(
msg
->
getPrivate
()
->
getContentType
()
==
ContentType
::
ImIsComposing
)
{
onIsComposingReceived
(
msg
->
getFromAddress
(),
msg
->
getPrivate
()
->
getText
());
if
(
lp_config_get_int
(
linphone_core_get_config
(
cCore
),
"sip"
,
"deliver_imdn"
,
0
)
!=
1
)
{
goto
end
;
}
if
(
lp_config_get_int
(
linphone_core_get_config
(
cCore
),
"sip"
,
"deliver_imdn"
,
0
)
!=
1
)
return
reason
;
}
else
if
(
msg
->
getPrivate
()
->
getContentType
()
==
ContentType
::
Imdn
)
{
onImdnReceived
(
msg
);
if
(
lp_config_get_int
(
linphone_core_get_config
(
cCore
),
"sip"
,
"deliver_imdn"
,
0
)
!=
1
)
{
goto
end
;
}
if
(
lp_config_get_int
(
linphone_core_get_config
(
cCore
),
"sip"
,
"deliver_imdn"
,
0
)
!=
1
)
return
reason
;
}
onChatMessageReceived
(
msg
);
end:
return
reason
;
}
...
...
src/chat/modifier/cpim-chat-message-modifier.cpp
View file @
d1dc2238
...
...
@@ -17,6 +17,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "linphone/utils/utils.h"
#include "address/address.h"
#include "chat/chat-message/chat-message-p.h"
#include "chat/cpim/cpim.h"
...
...
@@ -42,12 +44,33 @@ ChatMessageModifier::Result CpimChatMessageModifier::encode (const shared_ptr<Ch
Cpim
::
ToHeader
cpimToHeader
;
cpimToHeader
.
setValue
(
cpimAddressAsString
(
message
->
getToAddress
()));
cpimMessage
.
addMessageHeader
(
cpimToHeader
);
char
token
[
13
];
belle_sip_random_token
(
token
,
sizeof
(
token
));
Cpim
::
MessageIdHeader
cpimMessageIdHeader
;
cpimMessageIdHeader
.
setValue
(
token
);
cpimMessage
.
addMessageHeader
(
cpimMessageIdHeader
);
message
->
getPrivate
()
->
setImdnMessageId
(
token
);
if
(
message
->
getPrivate
()
->
getPositiveDeliveryNotificationRequired
()
||
message
->
getPrivate
()
->
getDisplayNotificationRequired
()
)
{
const
string
imdnNamespace
=
"imdn"
;
Cpim
::
NsHeader
cpimNsHeader
;
cpimNsHeader
.
setValue
(
imdnNamespace
+
" <urn:ietf:params:imdn>"
);
cpimMessage
.
addMessageHeader
(
cpimNsHeader
);
char
token
[
13
];
belle_sip_random_token
(
token
,
sizeof
(
token
));
Cpim
::
GenericHeader
cpimMessageIdHeader
;
cpimMessageIdHeader
.
setName
(
"Message-ID"
);
// TODO: Replace by imdnNamespace + ".Message-ID");
cpimMessageIdHeader
.
setValue
(
token
);
cpimMessage
.
addMessageHeader
(
cpimMessageIdHeader
);
message
->
getPrivate
()
->
setImdnMessageId
(
token
);
Cpim
::
GenericHeader
dispositionNotificationHeader
;
dispositionNotificationHeader
.
setName
(
imdnNamespace
+
".Disposition-Notification"
);
vector
<
string
>
dispositionNotificationValues
;
if
(
message
->
getPrivate
()
->
getPositiveDeliveryNotificationRequired
())
dispositionNotificationValues
.
emplace_back
(
"positive-delivery"
);
if
(
message
->
getPrivate
()
->
getDisplayNotificationRequired
())
dispositionNotificationValues
.
emplace_back
(
"display"
);
dispositionNotificationHeader
.
setValue
(
Utils
::
join
(
dispositionNotificationValues
,
", "
));
cpimMessage
.
addMessageHeader
(
dispositionNotificationHeader
);
}
const
Content
*
content
;
if
(
!
message
->
getInternalContent
().
isEmpty
())
{
...
...
@@ -125,17 +148,45 @@ ChatMessageModifier::Result CpimChatMessageModifier::decode (const shared_ptr<Ch
}
newContent
.
setBody
(
cpimMessage
->
getContent
());
message
->
getPrivate
()
->
setPositiveDeliveryNotificationRequired
(
false
);
message
->
getPrivate
()
->
setNegativeDeliveryNotificationRequired
(
false
);
message
->
getPrivate
()
->
setDisplayNotificationRequired
(
false
);
Address
cpimFromAddress
;
Address
cpimToAddress
;
l
=
cpimMessage
->
getMessageHeaders
();
if
(
l
)
{
string
imdnNamespace
=
""
;
for
(
const
auto
&
header
:
*
l
.
get
())
{
if
(
header
->
getName
()
==
"NS"
)
{
string
val
=
header
->
getValue
();
size_t
startPos
=
0
;
startPos
=
val
.
find
(
"<"
,
startPos
);
if
(
startPos
==
string
::
npos
)
break
;
size_t
endPos
=
0
;
endPos
=
val
.
find
(
">"
,
startPos
);
if
(
endPos
==
string
::
npos
)
break
;
if
(
val
.
substr
(
startPos
,
endPos
)
==
"<urn:ietf:params:imdn>"
)
imdnNamespace
=
Utils
::
trim
(
val
.
substr
(
0
,
startPos
));
}
}
for
(
const
auto
&
header
:
*
l
.
get
())
{
if
(
header
->
getName
()
==
"From"
)
cpimFromAddress
=
Address
(
header
->
getValue
());
else
if
(
header
->
getName
()
==
"To"
)
cpimToAddress
=
Address
(
header
->
getValue
());
else
if
(
header
->
getName
()
==
"Message-ID"
)
else
if
(
(
header
->
getName
()
==
"Message-ID"
)
||
(
header
->
getName
()
==
(
imdnNamespace
+
".Message-ID"
)))
message
->
getPrivate
()
->
setImdnMessageId
(
header
->
getValue
());
else
if
((
header
->
getName
()
==
(
imdnNamespace
+
".Disposition-Notification"
)))
{
vector
<
string
>
values
=
Utils
::
split
(
header
->
getValue
(),
", "
);
for
(
const
auto
&
value
:
values
)
if
(
value
==
"positive-delivery"
)
message
->
getPrivate
()
->
setPositiveDeliveryNotificationRequired
(
true
);
else
if
(
value
==
"display"
)
message
->
getPrivate
()
->
setDisplayNotificationRequired
(
true
);
}
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment