Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
liblinphone
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
10
Issues
10
List
Board
Labels
Milestones
Merge Requests
22
Merge Requests
22
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
External Wiki
External Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
BC
public
liblinphone
Commits
0db6249a
Commit
0db6249a
authored
Oct 06, 2017
by
Sylvain Berfini
🎩
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Simple ChatMessageMultipartModifier created + fixed a few things related to ChatMessages
parent
5dc6b956
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
171 additions
and
26 deletions
+171
-26
chat-message-p.h
src/chat/chat-message-p.h
+1
-1
chat-message.cpp
src/chat/chat-message.cpp
+24
-10
chat-room.cpp
src/chat/chat-room.cpp
+1
-1
cpim-chat-message-modifier.cpp
src/chat/modifier/cpim-chat-message-modifier.cpp
+1
-1
encryption-chat-message-modifier.cpp
src/chat/modifier/encryption-chat-message-modifier.cpp
+1
-1
multipart-chat-message-modifier.cpp
src/chat/modifier/multipart-chat-message-modifier.cpp
+79
-5
content-type.cpp
src/content/content-type.cpp
+43
-5
content-type.h
src/content/content-type.h
+4
-0
cpim-tester.cpp
tester/cpim-tester.cpp
+17
-2
No files found.
src/chat/chat-message-p.h
View file @
0db6249a
...
...
@@ -152,7 +152,7 @@ private:
bool
isFileTransferInProgressAndValid
();
int
startHttpTransfer
(
std
::
string
url
,
std
::
string
action
,
belle_http_request_listener_callbacks_t
*
cbs
);
void
releaseHttpRequest
();
void
createFileTransferInformationsFromVndGsmaRcsFtHttpXml
();
void
createFileTransferInformationsFromVndGsmaRcsFtHttpXml
(
std
::
string
body
);
L_DECLARE_PUBLIC
(
ChatMessage
);
};
...
...
src/chat/chat-message.cpp
View file @
0db6249a
...
...
@@ -888,12 +888,12 @@ void ChatMessagePrivate::releaseHttpRequest() {
}
}
void
ChatMessagePrivate
::
createFileTransferInformationsFromVndGsmaRcsFtHttpXml
()
{
void
ChatMessagePrivate
::
createFileTransferInformationsFromVndGsmaRcsFtHttpXml
(
string
body
)
{
xmlChar
*
file_url
=
NULL
;
xmlDocPtr
xmlMessageBody
;
xmlNodePtr
cur
;
/* parse the msg body to get all informations from it */
xmlMessageBody
=
xmlParseDoc
((
const
xmlChar
*
)
getText
()
.
c_str
());
xmlMessageBody
=
xmlParseDoc
((
const
xmlChar
*
)
body
.
c_str
());
LinphoneContent
*
content
=
linphone_content_new
();
setFileTransferInformation
(
content
);
...
...
@@ -1005,9 +1005,21 @@ LinphoneReason ChatMessagePrivate::receive() {
// End of message modification
// ---------------------------------------
if
((
errorCode
<=
0
)
&&
(
linphone_core_is_content_type_supported
(
chatRoom
->
getCore
(),
getContentType
().
asString
().
c_str
())
==
FALSE
))
{
errorCode
=
415
;
lError
()
<<
"Unsupported MESSAGE (content-type "
<<
getContentType
().
asString
()
<<
" not recognized)"
;
if
(
errorCode
<=
0
)
{
bool
foundSupportContentType
=
false
;
for
(
auto
it
=
contents
.
begin
();
it
!=
contents
.
end
();
it
++
)
{
if
(
linphone_core_is_content_type_supported
(
chatRoom
->
getCore
(),
it
->
getContentType
().
asString
().
c_str
()))
{
foundSupportContentType
=
true
;
break
;
}
else
{
lError
()
<<
"Unsupported content-type: "
<<
it
->
getContentType
().
asString
();
}
}
if
(
!
foundSupportContentType
)
{
errorCode
=
415
;
lError
()
<<
"No content-type in the contents list is supported..."
;
}
}
if
(
errorCode
>
0
)
{
...
...
@@ -1016,11 +1028,13 @@ LinphoneReason ChatMessagePrivate::receive() {
return
reason
;
}
if
(
getContentType
()
==
ContentType
::
FileTransfer
)
{
createFileTransferInformationsFromVndGsmaRcsFtHttpXml
();
store
=
true
;
}
else
if
(
getContentType
()
==
ContentType
::
PlainText
)
{
store
=
true
;
for
(
auto
it
=
contents
.
begin
();
it
!=
contents
.
end
();
it
++
)
{
if
(
it
->
getContentType
()
==
ContentType
::
FileTransfer
)
{
store
=
true
;
createFileTransferInformationsFromVndGsmaRcsFtHttpXml
(
it
->
getBodyAsString
());
}
else
if
(
it
->
getContentType
()
==
ContentType
::
PlainText
)
{
store
=
true
;
}
}
if
(
store
)
{
...
...
src/chat/chat-room.cpp
View file @
0db6249a
...
...
@@ -402,7 +402,7 @@ LinphoneReason ChatRoomPrivate::messageReceived (SalOp *op, const SalMessage *sa
Content
content
;
content
.
setContentType
(
salMsg
->
content_type
);
content
.
setBody
(
salMsg
->
text
?
salMsg
->
text
:
""
);
msg
->
add
Content
(
content
);
msg
->
setInternal
Content
(
content
);
msg
->
setToAddress
(
op
->
get_to
()
?
op
->
get_to
()
:
linphone_core_get_identity
(
core
));
msg
->
setFromAddress
(
peerAddress
);
...
...
src/chat/modifier/cpim-chat-message-modifier.cpp
View file @
0db6249a
...
...
@@ -24,7 +24,7 @@
#include "content/content.h"
#include "address/address.h"
#include "logger/logger.h"
#include "chat/chat-message
-p
.h"
#include "chat/chat-message.h"
// =============================================================================
...
...
src/chat/modifier/encryption-chat-message-modifier.cpp
View file @
0db6249a
...
...
@@ -26,7 +26,7 @@
#include "content/content.h"
#include "address/address.h"
#include "chat/chat-room.h"
#include "chat/chat-message
-p
.h"
#include "chat/chat-message.h"
// =============================================================================
...
...
src/chat/modifier/multipart-chat-message-modifier.cpp
View file @
0db6249a
...
...
@@ -18,8 +18,11 @@
*/
#include "multipart-chat-message-modifier.h"
#include "address/address.h"
#include "chat/chat-message-p.h"
#include "chat/chat-room.h"
#include "chat/chat-message.h"
#include "logger/logger.h"
// =============================================================================
...
...
@@ -29,15 +32,86 @@ LINPHONE_BEGIN_NAMESPACE
ChatMessageModifier
::
Result
MultipartChatMessageModifier
::
encode
(
shared_ptr
<
ChatMessage
>
message
,
int
*
errorCode
)
{
if
(
message
->
getContents
().
size
()
>
1
)
{
//TODO
LinphoneCore
*
lc
=
message
->
getChatRoom
()
->
getCore
();
char
tmp
[
64
];
lc
->
sal
->
create_uuid
(
tmp
,
sizeof
(
tmp
));
string
boundary
=
tmp
;
stringstream
multipartMessage
;
multipartMessage
<<
"--"
<<
boundary
;
for
(
auto
it
=
message
->
getContents
().
begin
();
it
!=
message
->
getContents
().
end
();
it
++
)
{
multipartMessage
<<
"
\r\n
"
;
multipartMessage
<<
"Content-Type: "
<<
it
->
getContentType
().
asString
()
<<
"
\r\n\r\n
"
;
multipartMessage
<<
it
->
getBodyAsString
()
<<
"
\r\n\r\n
"
;
multipartMessage
<<
"--"
<<
boundary
;
}
multipartMessage
<<
"--"
;
Content
newContent
;
ContentType
newContentType
(
"multipart/mixed"
);
newContentType
.
setParameter
(
"boundary="
+
boundary
);
newContent
.
setContentType
(
newContentType
);
newContent
.
setBody
(
multipartMessage
.
str
());
message
->
setInternalContent
(
newContent
);
return
ChatMessageModifier
::
Result
::
Done
;
}
return
ChatMessageModifier
::
Result
::
Skipped
;
}
}
ChatMessageModifier
::
Result
MultipartChatMessageModifier
::
decode
(
shared_ptr
<
ChatMessage
>
message
,
int
*
errorCode
)
{
//TODO
if
(
false
)
{
// Multipart required
if
(
message
->
getInternalContent
().
getContentType
().
getType
()
==
"multipart"
)
{
string
boundary
=
message
->
getInternalContent
().
getContentType
().
getParameter
();
if
(
boundary
.
empty
())
{
lError
()
<<
"Boundary parameter of content-type not found !"
;
return
ChatMessageModifier
::
Result
::
Error
;
}
size_t
pos
=
boundary
.
find
(
"="
);
if
(
pos
==
string
::
npos
)
{
lError
()
<<
"Parameter seems invalid: "
<<
boundary
;
return
ChatMessageModifier
::
Result
::
Error
;
}
boundary
=
"--"
+
boundary
.
substr
(
pos
+
1
);
lInfo
()
<<
"Multipart boundary is "
<<
boundary
;
const
vector
<
char
>
body
=
message
->
getInternalContent
().
getBody
();
string
contentsString
(
body
.
begin
(),
body
.
end
());
pos
=
contentsString
.
find
(
boundary
);
if
(
pos
==
string
::
npos
)
{
lError
()
<<
"Boundary not found in body !"
;
return
ChatMessageModifier
::
Result
::
Error
;
}
size_t
start
=
pos
+
boundary
.
length
()
+
2
;
// 2 is the size of \r\n
size_t
end
;
do
{
end
=
contentsString
.
find
(
boundary
,
start
);
if
(
end
!=
string
::
npos
)
{
string
contentString
=
contentsString
.
substr
(
start
,
end
-
start
);
size_t
contentTypePos
=
contentString
.
find
(
": "
)
+
2
;
// 2 is the size of :
size_t
endOfLinePos
=
contentString
.
find
(
"
\r\n
"
);
if
(
contentTypePos
>=
endOfLinePos
)
{
lError
()
<<
"Content should start by a 'Content-Type: ' line !"
;
continue
;
}
string
contentTypeString
=
contentString
.
substr
(
contentTypePos
,
endOfLinePos
-
contentTypePos
);
ContentType
contentType
(
contentTypeString
);
endOfLinePos
+=
4
;
// 4 is two time the size of \r\n
string
contentBody
=
contentString
.
substr
(
endOfLinePos
,
contentString
.
length
()
-
(
endOfLinePos
+
4
));
// 4 is two time the size of \r\n
Content
content
;
content
.
setContentType
(
contentType
);
content
.
setBody
(
contentBody
);
message
->
addContent
(
content
);
lInfo
()
<<
"Parsed and added content with type "
<<
contentType
.
asString
();
}
start
=
end
+
boundary
.
length
()
+
2
;
// 2 is the size of \r\n
}
while
(
end
!=
string
::
npos
);
return
ChatMessageModifier
::
Result
::
Done
;
}
...
...
src/content/content-type.cpp
View file @
0db6249a
...
...
@@ -20,7 +20,7 @@
#include "linphone/utils/utils.h"
#include "object/clonable-object-p.h"
#include "logger/logger.h"
#include "content-type.h"
// =============================================================================
...
...
@@ -33,6 +33,7 @@ class ContentTypePrivate : public ClonableObjectPrivate {
public
:
string
type
;
string
subType
;
string
parameter
;
};
// -----------------------------------------------------------------------------
...
...
@@ -52,13 +53,22 @@ ContentType::ContentType (const string &contentType) : ClonableObject(*new Conte
L_D
();
size_t
pos
=
contentType
.
find
(
'/'
);
size_t
posParam
=
contentType
.
find
(
"; "
);
size_t
end
=
contentType
.
length
();
if
(
pos
==
string
::
npos
)
return
;
if
(
setType
(
contentType
.
substr
(
0
,
pos
)))
{
if
(
!
setSubType
(
contentType
.
substr
(
pos
+
1
)))
if
(
posParam
!=
string
::
npos
)
{
end
=
posParam
;
}
if
(
!
setSubType
(
contentType
.
substr
(
pos
+
1
,
end
-
(
pos
+
1
))))
d
->
type
.
clear
();
}
if
(
posParam
!=
string
::
npos
)
{
setParameter
(
contentType
.
substr
(
posParam
+
2
));
// We remove the blankspace after the ;
}
}
ContentType
::
ContentType
(
const
string
&
type
,
const
string
&
subType
)
:
ClonableObject
(
*
new
ContentTypePrivate
)
{
...
...
@@ -70,19 +80,30 @@ ContentType::ContentType (const string &type, const string &subType) : ClonableO
}
}
ContentType
::
ContentType
(
const
ContentType
&
src
)
:
ContentType
(
src
.
getType
(),
src
.
getSubType
())
{}
ContentType
::
ContentType
(
const
string
&
type
,
const
string
&
subType
,
const
string
&
parameter
)
:
ClonableObject
(
*
new
ContentTypePrivate
)
{
L_D
();
if
(
setType
(
type
))
{
if
(
!
setSubType
(
subType
))
d
->
type
.
clear
();
}
setParameter
(
parameter
);
}
ContentType
::
ContentType
(
const
ContentType
&
src
)
:
ContentType
(
src
.
getType
(),
src
.
getSubType
(),
src
.
getParameter
())
{}
ContentType
&
ContentType
::
operator
=
(
const
ContentType
&
src
)
{
if
(
this
!=
&
src
)
{
setType
(
src
.
getType
());
setSubType
(
src
.
getSubType
());
setParameter
(
src
.
getParameter
());
}
return
*
this
;
}
bool
ContentType
::
operator
==
(
const
ContentType
&
contentType
)
const
{
return
getType
()
==
contentType
.
getType
()
&&
getSubType
()
==
contentType
.
getSubType
();
return
getType
()
==
contentType
.
getType
()
&&
getSubType
()
==
contentType
.
getSubType
()
&&
getParameter
()
==
contentType
.
getParameter
()
;
}
bool
ContentType
::
operator
!=
(
const
ContentType
&
contentType
)
const
{
...
...
@@ -117,6 +138,16 @@ bool ContentType::setSubType (const string &subType) {
return
false
;
}
const
string
&
ContentType
::
getParameter
()
const
{
L_D
();
return
d
->
parameter
;
}
void
ContentType
::
setParameter
(
const
string
&
parameter
)
{
L_D
();
d
->
parameter
=
parameter
;
}
bool
ContentType
::
isValid
()
const
{
L_D
();
return
!
d
->
type
.
empty
()
&&
!
d
->
subType
.
empty
();
...
...
@@ -124,7 +155,14 @@ bool ContentType::isValid () const {
string
ContentType
::
asString
()
const
{
L_D
();
return
isValid
()
?
d
->
type
+
"/"
+
d
->
subType
:
""
;
if
(
isValid
())
{
string
asString
=
d
->
type
+
"/"
+
d
->
subType
;
if
(
!
d
->
parameter
.
empty
())
{
asString
+=
"; "
+
d
->
parameter
;
}
return
asString
;
}
return
""
;
}
LINPHONE_END_NAMESPACE
src/content/content-type.h
View file @
0db6249a
...
...
@@ -32,6 +32,7 @@ class LINPHONE_PUBLIC ContentType : public ClonableObject {
public
:
ContentType
(
const
std
::
string
&
contentType
=
""
);
ContentType
(
const
std
::
string
&
type
,
const
std
::
string
&
subType
);
ContentType
(
const
std
::
string
&
type
,
const
std
::
string
&
subType
,
const
std
::
string
&
parameter
);
ContentType
(
const
ContentType
&
src
);
ContentType
&
operator
=
(
const
ContentType
&
src
);
...
...
@@ -52,6 +53,9 @@ public:
const
std
::
string
&
getSubType
()
const
;
bool
setSubType
(
const
std
::
string
&
subType
);
const
std
::
string
&
getParameter
()
const
;
void
setParameter
(
const
std
::
string
&
parameter
);
std
::
string
asString
()
const
;
static
const
ContentType
Cpim
;
...
...
tester/cpim-tester.cpp
View file @
0db6249a
...
...
@@ -382,7 +382,7 @@ static void build_message () {
BC_ASSERT_STRING_EQUAL
(
strMessage
.
c_str
(),
expectedMessage
.
c_str
());
}
static
void
cpim_chat_message_modifier
(
void
)
{
static
void
cpim_chat_message_modifier
_base
(
bool_t
use_multipart
)
{
LinphoneCoreManager
*
marie
=
linphone_core_manager_new
(
"marie_rc"
);
LinphoneCoreManager
*
pauline
=
linphone_core_manager_new
(
"pauline_tcp_rc"
);
LpConfig
*
config
=
linphone_core_get_config
(
marie
->
lc
);
...
...
@@ -392,6 +392,12 @@ static void cpim_chat_message_modifier(void) {
shared_ptr
<
ChatRoom
>
marieRoom
=
ObjectFactory
::
create
<
BasicChatRoom
>
(
marie
->
lc
,
paulineAddress
);
shared_ptr
<
ChatMessage
>
marieMessage
=
marieRoom
->
createMessage
(
"Hello CPIM"
);
if
(
use_multipart
)
{
Content
content
;
content
.
setContentType
(
ContentType
::
PlainText
);
content
.
setBody
(
"Hello Part 2"
);
marieMessage
->
addContent
(
content
);
}
marieRoom
->
sendMessage
(
marieMessage
);
BC_ASSERT_TRUE
(
wait_for
(
pauline
->
lc
,
marie
->
lc
,
&
pauline
->
stat
.
number_of_LinphoneMessageReceived
,
1
));
...
...
@@ -407,6 +413,14 @@ static void cpim_chat_message_modifier(void) {
linphone_core_manager_destroy
(
pauline
);
}
static
void
cpim_chat_message_modifier
(
void
)
{
cpim_chat_message_modifier_base
(
FALSE
);
}
static
void
cpim_chat_message_modifier_with_multipart_body
(
void
)
{
cpim_chat_message_modifier_base
(
TRUE
);
}
test_t
cpim_tests
[]
=
{
TEST_NO_TAG
(
"Parse minimal CPIM message"
,
parse_minimal_message
),
TEST_NO_TAG
(
"Set generic header name"
,
set_generic_header_name
),
...
...
@@ -417,7 +431,8 @@ test_t cpim_tests[] = {
TEST_NO_TAG
(
"Parse RFC example"
,
parse_rfc_example
),
TEST_NO_TAG
(
"Parse Message with generic header parameters"
,
parse_message_with_generic_header_parameters
),
TEST_NO_TAG
(
"Build Message"
,
build_message
),
TEST_NO_TAG
(
"CPIM chat message modifier"
,
cpim_chat_message_modifier
)
TEST_NO_TAG
(
"CPIM chat message modifier"
,
cpim_chat_message_modifier
),
TEST_NO_TAG
(
"CPIM chat message modifier with multipart body"
,
cpim_chat_message_modifier_with_multipart_body
),
};
test_suite_t
cpim_test_suite
=
{
...
...
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