Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
M
mms-engine
Project overview
Project overview
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
mer-core
mms-engine
Commits
7fdf73ed
Commit
7fdf73ed
authored
Feb 25, 2014
by
Slava Monich
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Preliminary support for sending MMS messages
parent
c4e37255
Changes
26
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
26 changed files
with
1705 additions
and
10 deletions
+1705
-10
.gitignore
.gitignore
+1
-0
mms-engine/Makefile
mms-engine/Makefile
+1
-1
mms-engine/mms-engine.pro
mms-engine/mms-engine.pro
+2
-0
mms-engine/mms_engine.c
mms-engine/mms_engine.c
+88
-0
mms-handler-dbus/src/mms_handler_dbus.c
mms-handler-dbus/src/mms_handler_dbus.c
+51
-1
mms-lib/Makefile
mms-lib/Makefile
+6
-5
mms-lib/include/mms_dispatcher.h
mms-lib/include/mms_dispatcher.h
+17
-0
mms-lib/include/mms_handler.h
mms-lib/include/mms_handler.h
+36
-0
mms-lib/include/mms_lib_log.h
mms-lib/include/mms_lib_log.h
+2
-0
mms-lib/include/mms_lib_types.h
mms-lib/include/mms_lib_types.h
+9
-0
mms-lib/mms-lib.pro
mms-lib/mms-lib.pro
+4
-0
mms-lib/src/mms_attachment.c
mms-lib/src/mms_attachment.c
+301
-0
mms-lib/src/mms_attachment.h
mms-lib/src/mms_attachment.h
+75
-0
mms-lib/src/mms_codec.c
mms-lib/src/mms_codec.c
+16
-0
mms-lib/src/mms_codec.h
mms-lib/src/mms_codec.h
+1
-0
mms-lib/src/mms_dispatcher.c
mms-lib/src/mms_dispatcher.c
+35
-0
mms-lib/src/mms_file_util.c
mms-lib/src/mms_file_util.c
+60
-0
mms-lib/src/mms_file_util.h
mms-lib/src/mms_file_util.h
+7
-0
mms-lib/src/mms_handler.c
mms-lib/src/mms_handler.c
+32
-0
mms-lib/src/mms_task.h
mms-lib/src/mms_task.h
+22
-0
mms-lib/src/mms_task_encode.c
mms-lib/src/mms_task_encode.c
+507
-0
mms-lib/src/mms_task_http.c
mms-lib/src/mms_task_http.c
+2
-2
mms-lib/src/mms_task_send.c
mms-lib/src/mms_task_send.c
+145
-0
mms-lib/test/common/Makefile
mms-lib/test/common/Makefile
+1
-1
mms-send/Makefile
mms-send/Makefile
+129
-0
mms-send/mms-send.c
mms-send/mms-send.c
+155
-0
No files found.
.gitignore
View file @
7fdf73ed
...
...
@@ -24,3 +24,4 @@ mms-handler-dbus/test/mms_handler_dbus_client/build
mms-dump/build
mms-dump/mms_dump.ncb
mms-dump/mms_dump.opt
mms-send/build
mms-engine/Makefile
View file @
7fdf73ed
...
...
@@ -90,7 +90,7 @@ endif
DEBUG_CFLAGS
=
$(DEBUG_FLAGS)
$(DEBUG_DEFS)
$(CFLAGS)
RELEASE_CFLAGS
=
$(RELEASE_FLAGS)
$(RELEASE_DEFS)
$(CFLAGS)
LIBS
=
$(
shell
pkg-config
--libs
$(LIB_PKGS)
)
LIBS
=
$(
shell
pkg-config
--libs
$(LIB_PKGS)
)
-lmagic
DEBUG_LIBS
=
\
$(MMS_OFONO_DEBUG_LIB)
\
$(MMS_HANDLER_DEBUG_LIB)
\
...
...
mms-engine/mms-engine.pro
View file @
7fdf73ed
...
...
@@ -35,6 +35,8 @@ CONFIG(debug, debug|release) {
LIBS
+=
$$
MMS_LIB_DIR
/
build
/
release
/
libmms
-
lib
.
a
}
LIBS
+=
-
lmagic
MMS_ENGINE_DBUS_XML
=
$$
DBUS_INTERFACE_DIR
/
org
.
nemomobile
.
MmsEngine
.
xml
MMS_ENGINE_DBUS_H
=
org
.
nemomobile
.
MmsEngine
.
h
org_nemomobile_mmsengine_h
.
input
=
MMS_ENGINE_DBUS_XML
...
...
mms-engine/mms_engine.c
View file @
7fdf73ed
...
...
@@ -39,6 +39,7 @@ struct mms_engine {
gboolean
stopped
;
gboolean
keep_running
;
guint
start_timeout_id
;
gulong
send_message_id
;
gulong
push_signal_id
;
gulong
push_notify_signal_id
;
gulong
receive_signal_id
;
...
...
@@ -129,6 +130,89 @@ mms_engine_handle_test(
}
#endif
/* ENABLE_TEST */
/* org.nemomobile.MmsEngine.sendMessage */
static
gboolean
mms_engine_handle_send_message
(
OrgNemomobileMmsEngine
*
proxy
,
GDBusMethodInvocation
*
call
,
int
database_id
,
const
char
*
imsi_to
,
const
char
*
const
*
to
,
const
char
*
const
*
cc
,
const
char
*
const
*
bcc
,
const
char
*
subject
,
guint
flags
,
GVariant
*
attachments
,
MMSEngine
*
engine
)
{
if
(
to
&&
*
to
)
{
unsigned
int
i
;
char
*
to_list
=
g_strjoinv
(
","
,
(
char
**
)
to
);
char
*
cc_list
=
NULL
;
char
*
bcc_list
=
NULL
;
char
*
id
=
NULL
;
char
*
imsi
;
MMSAttachmentInfo
*
parts
;
GArray
*
info
=
g_array_sized_new
(
FALSE
,
FALSE
,
sizeof
(
*
parts
),
0
);
GError
*
error
=
NULL
;
/* Extract attachment info */
char
*
fn
=
NULL
;
char
*
ct
=
NULL
;
char
*
cid
=
NULL
;
GVariantIter
*
iter
=
NULL
;
g_variant_get
(
attachments
,
"a(sss)"
,
&
iter
);
while
(
g_variant_iter_loop
(
iter
,
"(sss)"
,
&
fn
,
&
ct
,
&
cid
))
{
MMSAttachmentInfo
part
;
part
.
file_name
=
g_strdup
(
fn
);
part
.
content_type
=
g_strdup
(
ct
);
part
.
content_id
=
g_strdup
(
cid
);
g_array_append_vals
(
info
,
&
part
,
1
);
}
/* Convert address lists into comma-separated strings
* expected by mms_dispatcher_send_message and mms_codec */
if
(
cc
&&
*
cc
)
cc_list
=
g_strjoinv
(
","
,
(
char
**
)
cc
);
if
(
bcc
&&
*
bcc
)
bcc_list
=
g_strjoinv
(
","
,
(
char
**
)
bcc
);
if
(
database_id
>
0
)
id
=
g_strdup_printf
(
"%u"
,
database_id
);
/* Queue the message */
parts
=
(
void
*
)
info
->
data
;
imsi
=
mms_dispatcher_send_message
(
engine
->
dispatcher
,
id
,
imsi_to
,
to_list
,
cc_list
,
bcc_list
,
subject
,
flags
,
parts
,
info
->
len
,
&
error
);
if
(
imsi
)
{
if
(
mms_dispatcher_start
(
engine
->
dispatcher
))
{
mms_engine_start_timeout_cancel
(
engine
);
}
org_nemomobile_mms_engine_complete_send_message
(
proxy
,
call
,
imsi
);
g_free
(
imsi
);
}
else
{
g_dbus_method_invocation_return_error
(
call
,
G_DBUS_ERROR
,
G_DBUS_ERROR_FAILED
,
"%s"
,
MMS_ERRMSG
(
error
));
g_error_free
(
error
);
}
for
(
i
=
0
;
i
<
info
->
len
;
i
++
)
{
g_free
((
void
*
)
parts
[
i
].
file_name
);
g_free
((
void
*
)
parts
[
i
].
content_type
);
g_free
((
void
*
)
parts
[
i
].
content_id
);
}
g_free
(
to_list
);
g_free
(
cc_list
);
g_free
(
bcc_list
);
g_free
(
id
);
g_array_unref
(
info
);
g_variant_iter_free
(
iter
);
}
else
{
g_dbus_method_invocation_return_error
(
call
,
G_DBUS_ERROR
,
G_DBUS_ERROR_FAILED
,
"Missing recipient"
);
}
return
TRUE
;
}
/* org.nemomobile.MmsEngine.receiveMessage */
static
gboolean
...
...
@@ -343,6 +427,9 @@ mms_engine_new(
mms
->
log_modules
=
log_modules
;
mms
->
log_count
=
log_count
;
mms
->
proxy
=
org_nemomobile_mms_engine_skeleton_new
();
mms
->
send_message_id
=
g_signal_connect
(
mms
->
proxy
,
"handle-send-message"
,
G_CALLBACK
(
mms_engine_handle_send_message
),
mms
);
mms
->
push_signal_id
=
g_signal_connect
(
mms
->
proxy
,
"handle-push"
,
G_CALLBACK
(
mms_engine_handle_push
),
mms
);
...
...
@@ -486,6 +573,7 @@ mms_engine_dispose(
#ifdef ENABLE_TEST
g_signal_handler_disconnect
(
e
->
proxy
,
e
->
test_signal_id
);
#endif
g_signal_handler_disconnect
(
e
->
proxy
,
e
->
send_message_id
);
g_signal_handler_disconnect
(
e
->
proxy
,
e
->
push_signal_id
);
g_signal_handler_disconnect
(
e
->
proxy
,
e
->
push_notify_signal_id
);
g_signal_handler_disconnect
(
e
->
proxy
,
e
->
receive_signal_id
);
...
...
mms-handler-dbus/src/mms_handler_dbus.c
View file @
7fdf73ed
...
...
@@ -131,7 +131,7 @@ mms_handler_dbus_message_received(
return
ok
;
}
/* Updates message state in the database */
/* Updates message
receive
state in the database */
static
gboolean
mms_handler_dbus_message_receive_state_changed
(
...
...
@@ -155,6 +155,53 @@ mms_handler_dbus_message_receive_state_changed(
return
ok
;
}
/* Updates message send state in the database */
static
gboolean
mms_handler_dbus_message_send_state_changed
(
MMSHandler
*
handler
,
const
char
*
id
,
MMS_SEND_STATE
state
)
{
gboolean
ok
=
FALSE
;
OrgNemomobileMmsHandler
*
proxy
=
mms_handler_dbus_connect
(
handler
);
MMS_ASSERT
(
id
&&
id
[
0
]);
if
(
id
&&
id
[
0
]
&&
proxy
)
{
GError
*
error
=
NULL
;
if
(
org_nemomobile_mms_handler_call_message_send_state_changed_sync
(
proxy
,
id
,
state
,
NULL
,
&
error
))
{
ok
=
TRUE
;
}
else
{
MMS_ERR
(
"%s"
,
MMS_ERRMSG
(
error
));
g_error_free
(
error
);
}
}
return
ok
;
}
/* Message has been sent */
gboolean
mms_handler_dbus_message_sent
(
MMSHandler
*
handler
,
const
char
*
id
,
const
char
*
msgid
)
{
gboolean
ok
=
FALSE
;
OrgNemomobileMmsHandler
*
proxy
=
mms_handler_dbus_connect
(
handler
);
MMS_ASSERT
(
id
&&
id
[
0
]);
if
(
id
&&
id
[
0
]
&&
msgid
&&
msgid
[
0
]
&&
proxy
)
{
GError
*
error
=
NULL
;
if
(
org_nemomobile_mms_handler_call_message_sent_sync
(
proxy
,
id
,
msgid
,
NULL
,
&
error
))
{
ok
=
TRUE
;
}
else
{
MMS_ERR
(
"%s"
,
MMS_ERRMSG
(
error
));
g_error_free
(
error
);
}
}
return
ok
;
}
static
void
mms_handler_dbus_dispose
(
...
...
@@ -177,6 +224,9 @@ mms_handler_dbus_class_init(
klass
->
fn_message_received
=
mms_handler_dbus_message_received
;
klass
->
fn_message_receive_state_changed
=
mms_handler_dbus_message_receive_state_changed
;
klass
->
fn_message_send_state_changed
=
mms_handler_dbus_message_send_state_changed
;
klass
->
fn_message_sent
=
mms_handler_dbus_message_sent
;
G_OBJECT_CLASS
(
klass
)
->
dispose
=
mms_handler_dbus_dispose
;
}
...
...
mms-lib/Makefile
View file @
7fdf73ed
...
...
@@ -15,11 +15,12 @@ all: debug release
# Sources
#
SRC
=
mms_codec.c mms_connection.c mms_connman.c mms_dispatcher.c
\
mms_error.c mms_handler.c mms_lib_util.c mms_file_util.c mms_log.c
\
mms_message.c mms_task.c mms_task_ack.c mms_task_decode.c
\
mms_task_http.c mms_task_notification.c mms_task_notifyresp.c
\
mms_task_publish.c mms_task_read.c mms_task_retrieve.c mms_util.c
SRC
=
mms_attachment.c mms_codec.c mms_connection.c mms_connman.c
\
mms_dispatcher.c mms_error.c mms_handler.c mms_lib_util.c mms_file_util.c
\
mms_log.c mms_message.c mms_task.c mms_task_ack.c mms_task_decode.c
\
mms_task_encode.c mms_task_http.c mms_task_notification.c
\
mms_task_notifyresp.c mms_task_publish.c mms_task_read.c
\
mms_task_retrieve.c mms_task_send.c mms_util.c
#
# Directories
...
...
mms-lib/include/mms_dispatcher.h
View file @
7fdf73ed
...
...
@@ -79,6 +79,23 @@ mms_dispatcher_send_read_report(
MMSReadStatus
status
,
GError
**
error
);
char
*
mms_dispatcher_send_message
(
MMSDispatcher
*
dispatcher
,
const
char
*
id
,
const
char
*
imsi
,
const
char
*
to
,
const
char
*
cc
,
const
char
*
bcc
,
const
char
*
subject
,
unsigned
int
flags
,
const
MMSAttachmentInfo
*
parts
,
unsigned
int
nparts
,
GError
**
error
);
#define MMS_SEND_FLAG_REQUEST_DELIVERY_REPORT (0x01)
#define MMS_SEND_FLAG_REQUEST_READ_REPORT (0x02)
void
mms_dispatcher_cancel
(
MMSDispatcher
*
dispatcher
,
...
...
mms-lib/include/mms_handler.h
View file @
7fdf73ed
...
...
@@ -28,6 +28,18 @@ typedef enum _mmm_receive_state {
MMS_RECEIVE_STATE_DECODING_ERROR
}
MMS_RECEIVE_STATE
;
/* Send state */
typedef
enum
_mmm_send_state
{
MMS_SEND_STATE_INVALID
=
-
1
,
MMS_SEND_STATE_ENCODING
,
MMS_SEND_STATE_TOO_BIG
,
MMS_SEND_STATE_SENDING
,
MMS_SEND_STATE_DEFERRED
,
MMS_SEND_STATE_NO_SPACE
,
MMS_SEND_STATE_SEND_ERROR
,
MMS_SEND_STATE_REFUSED
}
MMS_SEND_STATE
;
/* Class */
typedef
struct
mms_handler_class
{
GObjectClass
parent
;
...
...
@@ -53,6 +65,18 @@ typedef struct mms_handler_class {
MMSHandler
*
handler
,
/* Handler instance */
MMSMessage
*
msg
);
/* Decoded message */
/* Sets the send state */
gboolean
(
*
fn_message_send_state_changed
)(
MMSHandler
*
handler
,
/* Handler instance */
const
char
*
id
,
/* Handler record id */
MMS_SEND_STATE
state
);
/* Receive state */
/* Message has been sent */
gboolean
(
*
fn_message_sent
)(
MMSHandler
*
handler
,
/* Handler instance */
const
char
*
id
,
/* Handler record id */
const
char
*
msgid
);
/* Message id assigned by operator */
}
MMSHandlerClass
;
GType
mms_handler_get_type
(
void
);
...
...
@@ -86,6 +110,18 @@ mms_handler_message_received(
MMSHandler
*
handler
,
/* Handler instance */
MMSMessage
*
msg
);
/* Decoded message */
gboolean
mms_handler_message_send_state_changed
(
MMSHandler
*
handler
,
/* Handler instance */
const
char
*
id
,
/* Handler record id */
MMS_SEND_STATE
state
);
/* Receive state */
gboolean
mms_handler_message_sent
(
MMSHandler
*
handler
,
/* Handler instance */
const
char
*
id
,
/* Handler record id */
const
char
*
msgid
);
/* Message id assigned by operator */
#endif
/* JOLLA_MMS_HANDLER_H */
/*
...
...
mms-lib/include/mms_lib_log.h
View file @
7fdf73ed
...
...
@@ -21,9 +21,11 @@
log(mms_dispatcher_log)\
log(mms_handler_log)\
log(mms_message_log)\
log(mms_attachment_log)\
log(mms_task_log)\
log(mms_task_http_log)\
log(mms_task_decode_log)\
log(mms_task_encode_log)\
log(mms_task_notification_log)\
log(mms_task_retrieve_log)\
log(mms_task_publish_log)\
...
...
mms-lib/include/mms_lib_types.h
View file @
7fdf73ed
...
...
@@ -49,6 +49,13 @@ typedef struct mms_config {
gboolean
send_dr
;
/* Allow sending delivery reports */
}
MMSConfig
;
/* Attachment information */
typedef
struct
mms_attachment_info
{
const
char
*
file_name
;
/* Full path name */
const
char
*
content_type
;
/* Content type */
const
char
*
content_id
;
/* Content id */
}
MMSAttachmentInfo
;
/* Types */
typedef
GObject
MMSHandler
;
typedef
GObject
MMSConnMan
;
...
...
@@ -57,9 +64,11 @@ typedef struct mms_dispatcher MMSDispatcher;
typedef
struct
mms_connection
MMSConnection
;
typedef
struct
mms_message
MMSPdu
;
typedef
struct
_mms_message
MMSMessage
;
typedef
struct
_mms_attachment
MMSAttachment
;
/* MMS content type */
#define MMS_CONTENT_TYPE "application/vnd.wap.mms-message"
#define SMIL_CONTENT_TYPE "application/smil"
/* MMS read status */
typedef
enum
mms_read_status
{
...
...
mms-lib/mms-lib.pro
View file @
7fdf73ed
...
...
@@ -14,6 +14,7 @@ CONFIG(debug, debug|release) {
}
SOURCES
+=
\
src
/
mms_attachment
.
c
\
src
/
mms_codec
.
c
\
src
/
mms_connection
.
c
\
src
/
mms_connman
.
c
\
...
...
@@ -27,15 +28,18 @@ SOURCES += \
src
/
mms_task
.
c
\
src
/
mms_task_ack
.
c
\
src
/
mms_task_decode
.
c
\
src
/
mms_task_encode
.
c
\
src
/
mms_task_http
.
c
\
src
/
mms_task_notification
.
c
\
src
/
mms_task_notifyresp
.
c
\
src
/
mms_task_publish
.
c
\
src
/
mms_task_read
.
c
\
src
/
mms_task_retrieve
.
c
\
src
/
mms_task_send
.
c
\
src
/
mms_util
.
c
HEADERS
+=
\
src
/
mms_attachment
.
h
\
src
/
mms_codec
.
h
\
src
/
mms_error
.
h
\
src
/
mms_file_util
.
h
\
...
...
mms-lib/src/mms_attachment.c
0 → 100644
View file @
7fdf73ed
/*
* Copyright (C) 2013-2014 Jolla Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* 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.
*
*/
#include "mms_attachment.h"
#include "mms_file_util.h"
#include "mms_codec.h"
#include <magic.h>
/* Logging */
#define MMS_LOG_MODULE_NAME mms_attachment_log
#include "mms_lib_log.h"
#include "mms_error.h"
MMS_LOG_MODULE_DEFINE
(
"mms-attachment"
);
#define MMS_ATTACHMENT_DEFAULT_TYPE "application/octet-stream"
G_DEFINE_TYPE
(
MMSAttachment
,
mms_attachment
,
G_TYPE_OBJECT
);
#define MMS_ATTACHMENT(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj), MMS_TYPE_ATTACHMENT, MMSAttachment))
#define MMS_ATTACHMENT_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS((obj), MMS_TYPE_ATTACHMENT, MMSAttachmentClass))
#define REGION_TEXT "Text"
#define REGION_MEDIA "Media"
#define MEDIA_TEXT "text"
#define MEDIA_IMAGE "img"
#define MEDIA_VIDEO "video"
#define MEDIA_AUDIO "audio"
#define MEDIA_OTHER "ref"
static
void
mms_attachment_finalize
(
GObject
*
object
)
{
MMSAttachment
*
at
=
MMS_ATTACHMENT
(
object
);
g_mapped_file_unref
(
at
->
map
);
if
(
!
at
->
config
->
keep_temp_files
&&
!
(
at
->
flags
&
MMS_ATTACHMENT_DONT_DELETE_FILES
))
{
char
*
dir
=
g_path_get_dirname
(
at
->
file_name
);
remove
(
at
->
file_name
);
rmdir
(
dir
);
g_free
(
dir
);
}
g_free
(
at
->
file_name
);
g_free
(
at
->
content_type
);
g_free
(
at
->
content_location
);
g_free
(
at
->
content_id
);
G_OBJECT_CLASS
(
mms_attachment_parent_class
)
->
finalize
(
object
);
}
static
void
mms_attachment_class_init
(
MMSAttachmentClass
*
klass
)
{
G_OBJECT_CLASS
(
klass
)
->
finalize
=
mms_attachment_finalize
;
}
static
void
mms_attachment_init
(
MMSAttachment
*
attachment
)
{
MMS_VERBOSE_
(
"%p"
,
attachment
);
}
static
char
*
mms_attachment_get_path
(
const
char
*
file
,
GError
**
error
)
{
char
*
path
=
g_malloc
(
PATH_MAX
);
if
(
realpath
(
file
,
path
))
{
if
(
g_file_test
(
path
,
G_FILE_TEST_IS_REGULAR
))
{
char
*
fname
=
g_strdup
(
path
);
g_free
(
path
);
return
fname
;
}
else
{
MMS_ERROR
(
error
,
MMS_LIB_ERROR_IO
,
"%s not found"
,
file
);
}
}
else
{
MMS_ERROR
(
error
,
MMS_LIB_ERROR_IO
,
"%s: %s
\n
"
,
file
,
strerror
(
errno
));
}
return
NULL
;
}
gboolean
mms_attachment_write_smil
(
FILE
*
f
,
MMSAttachment
**
ats
,
int
n
,
GError
**
error
)
{
if
(
fputs
(
"<!DOCTYPE smil PUBLIC
\"
-//W3C//DTD SMIL 1.0//EN
\"
"
"
\"
http://www.w3.org/TR/REC-smil/SMIL10.dtd
\"
>
\n
"
"<smil>
\n
"
" <head>
\n
"
" <layout>
\n
"
" <root-layout height=
\"
160
\"
width=
\"
120
\"
/>
\n
"
" <region fit=
\"
scroll
\"
height=
\"
100%
\"
left=
\"
0
\"
"
"top=
\"
0
\"
width=
\"
100%
\"
id=
\"
"
REGION_TEXT
"
\"
/>
\n
"
" <region fit=
\"
meet
\"
height=
\"
100%
\"
left=
\"
0
\"
"
"top=
\"
0
\"
width=
\"
100%
\"
id=
\"
"
REGION_MEDIA
"
\"
/>
\n
"
" </layout>
\n
"
" </head>
\n
"
" <body>
\n
"
" <par dur=
\"
5000ms
\"
>
\n
"
,
f
)
>=
0
)
{
int
i
;
for
(
i
=
0
;
i
<
n
;
i
++
)
{
const
MMSAttachment
*
at
=
ats
[
i
];
const
char
*
elem
;
const
char
*
region
;
MMS_ASSERT
(
!
(
at
->
flags
&
MMS_ATTACHMENT_SMIL
));
if
(
g_str_has_prefix
(
at
->
content_type
,
"text/"
))
{
elem
=
"text"
;
region
=
REGION_TEXT
;
}
else
{
region
=
REGION_MEDIA
;
if
(
g_str_has_prefix
(
at
->
content_type
,
"image/"
))
{
elem
=
"img"
;
}
else
if
(
g_str_has_prefix
(
at
->
content_type
,
"video/"
))
{
elem
=
"video"
;
}
else
if
(
g_str_has_prefix
(
at
->
content_type
,
"audio/"
))
{
elem
=
"audio"
;
}
else
{
elem
=
"ref"
;
}
}
if
(
fprintf
(
f
,
" <%s src=
\"
%s
\"
region=
\"
%s
\"
/>
\n
"
,
elem
,
at
->
content_location
,
region
)
<
0
)
{
break
;
}
}
if
(
i
==
n
&&
fputs
(
" </par>
\n
</body>
\n
</smil>
\n
"
,
f
)
>=
0
)
{
return
TRUE
;
}
}
MMS_ERROR
(
error
,
MMS_LIB_ERROR_IO
,
"Error writing SMIL: %s"
,
strerror
(
errno
));
return
FALSE
;
}
MMSAttachment
*
mms_attachment_new_smil
(
const
MMSConfig
*
config
,
const
char
*
path
,
MMSAttachment
**
ats
,
int
n
,
GError
**
error
)
{
MMSAttachment
*
smil
=
NULL
;
int
fd
=
open
(
path
,
O_CREAT
|
O_RDWR
|
O_TRUNC
,
MMS_FILE_PERM
);
if
(
fd
>=
0
)
{
FILE
*
f
=
fdopen
(
fd
,
"w"
);
if
(
f
)
{
gboolean
ok
=
mms_attachment_write_smil
(
f
,
ats
,
n
,
error
);
fclose
(
f
);
if
(
ok
)
{
MMSAttachmentInfo
ai
;
ai
.
file_name
=
path
;
ai
.
content_type
=
SMIL_CONTENT_TYPE
"; charset=utf-8"
;
ai
.
content_id
=
NULL
;
smil
=
mms_attachment_new
(
config
,
&
ai
,
error
);
MMS_ASSERT
(
smil
&&
(
smil
->
flags
&
MMS_ATTACHMENT_SMIL
));
}
}
else
{
MMS_ERROR
(
error
,
MMS_LIB_ERROR_IO
,
"Failed to open file %s: %s"
,
path
,
strerror
(
errno
));
close
(
fd
);
}
}
else
{
MMS_ERROR
(
error
,
MMS_LIB_ERROR_IO
,
"Failed to create file %s: %s"
,
path
,
strerror
(
errno
));
}
return
smil
;
}
MMSAttachment
*
mms_attachment_new
(
const
MMSConfig
*
config
,
const
MMSAttachmentInfo
*
info
,
GError
**
error
)
{
char
*
path
=
mms_attachment_get_path
(
info
->
file_name
,
error
);
if
(
path
)
{
GMappedFile
*
map
=
g_mapped_file_new
(
path
,
FALSE
,
error
);
if
(
map
)
{
MMSAttachment
*
at
=
g_object_new
(
MMS_TYPE_ATTACHMENT
,
NULL
);
at
->
config
=
config
;
at
->
file_name
=
path
;
at
->
map
=
map
;
if
(
info
->
content_type
)
{
char
**
ct
=
mms_parse_http_content_type
(
info
->
content_type
);
if
(
ct
)
{
at
->
content_type
=
mms_unparse_http_content_type
(
ct
);
if
(
!
strcmp
(
ct
[
0
],
SMIL_CONTENT_TYPE
))
{
at
->
flags
|=
MMS_ATTACHMENT_SMIL
;
}
g_strfreev
(
ct
);
}
}
if
(
!
at
->
content_type
)
{
/* Use magic to determine mime type */
const
char
*
default_charset
=
"utf-8"
;
const
char
*
content_type
=
NULL
;
const
char
*
charset
=
NULL
;
const
char
*
ct
[
4
];
int
n
;
magic_t
magic
=
magic_open
(
MAGIC_MIME_TYPE
);
if
(
magic
)
{
if
(
magic_load
(
magic
,
NULL
)
==
0
)
{
content_type
=
magic_file
(
magic
,
path
);
}
}
/* Magic detects SMIL as text/html */
if
((
!
content_type
||
g_str_has_prefix
(
content_type
,
"text/"
))
&&
mms_file_is_smil
(
path
))
{
content_type
=
SMIL_CONTENT_TYPE
;
}
if
(
!
content_type
)
{
MMS_WARN
(
"No mime type for %s"
,
path
);
content_type
=
MMS_ATTACHMENT_DEFAULT_TYPE
;
}
if
(
!
strcmp
(
content_type
,
SMIL_CONTENT_TYPE
))
{
at
->
flags
|=
MMS_ATTACHMENT_SMIL
;
charset
=
default_charset
;
}
else
if
(
g_str_has_prefix
(
content_type
,
"text/"
))
{
charset
=
default_charset
;
}
n
=
0
;
ct
[
n
++
]
=
content_type
;
if
(
charset
)
{
ct
[
n
++
]
=
"charset"
;
ct
[
n
++
]
=
charset
;
}
ct
[
n
++
]
=
NULL
;
at
->
content_type
=
mms_unparse_http_content_type
((
char
**
)
ct
);
if
(
magic
)
magic_close
(
magic
);
}
at
->
content_location
=
g_path_get_basename
(
path
);
at
->
content_id
=
(
info
->
content_id
&&
info
->
content_id
[
0
])
?
g_strdup
(
info
->
content_id
)
:
g_strdup
(
at
->
content_location
);
MMS_DEBUG
(
"%s: %s"
,
path
,
at
->
content_type
);
return
at
;
}
g_free
(
path
);
}
return
NULL
;
}
MMSAttachment
*
mms_attachment_ref
(
MMSAttachment
*
at
)
{
if
(
at
)
g_object_ref
(
MMS_ATTACHMENT
(
at
));
return
at
;
}
void
mms_attachment_unref
(
MMSAttachment
*
at
)
{
if
(
at
)
g_object_unref
(
MMS_ATTACHMENT
(
at
));
}
/*
* Local Variables:
* mode: C
* c-basic-offset: 4
* indent-tabs-mode: nil
* End:
*/
mms-lib/src/mms_attachment.h
0 → 100644
View file @
7fdf73ed
/*
* Copyright (C) 2013-2014 Jolla Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* 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.
*
*/
#ifndef JOLLA_MMS_ATTACHMENT_H
#define JOLLA_MMS_ATTACHMENT_H
#include "mms_lib_types.h"
/* Attachment object */
struct
_mms_attachment
{
GObject
parent
;
/* Parent object */
const
MMSConfig
*
config
;
/* Immutable configuration */
char
*
file_name
;
/* Full path name */
char
*
content_type
;
/* Content type */
char
*
content_id
;
/* Content id */
char
*
content_location
;
/* Content location */
GMappedFile
*
map
;
/* Mapped attachment file */
unsigned
int
flags
;
/* Flags: */
#define MMS_ATTACHMENT_SMIL (0x01)
#define MMS_ATTACHMENT_DONT_DELETE_FILES (0x02)
};
typedef
struct
mms_attachment_class
{
GObjectClass
parent
;
}
MMSAttachmentClass
;
GType
mms_attachment_get_type
(
void
);
#define MMS_TYPE_ATTACHMENT (mms_attachment_get_type())
#define MMS_ATTACHMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), \
MMS_TYPE_ATTACHMENT, MMSAttachmentClass))
MMSAttachment
*
mms_attachment_new
(
const
MMSConfig
*
config
,
const
MMSAttachmentInfo
*
info
,
GError
**
error
);