Skip to content

Commit

Permalink
Preliminary support for sending MMS messages
Browse files Browse the repository at this point in the history
  • Loading branch information
monich committed Feb 25, 2014
1 parent c4e3725 commit 7fdf73e
Show file tree
Hide file tree
Showing 26 changed files with 1,705 additions and 10 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -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
2 changes: 1 addition & 1 deletion mms-engine/Makefile
Expand Up @@ -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) \
Expand Down
2 changes: 2 additions & 0 deletions mms-engine/mms-engine.pro
Expand Up @@ -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
Expand Down
88 changes: 88 additions & 0 deletions mms-engine/mms_engine.c
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
52 changes: 51 additions & 1 deletion mms-handler-dbus/src/mms_handler_dbus.c
Expand Up @@ -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(
Expand All @@ -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(
Expand All @@ -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;
}

Expand Down
11 changes: 6 additions & 5 deletions mms-lib/Makefile
Expand Up @@ -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
Expand Down
17 changes: 17 additions & 0 deletions mms-lib/include/mms_dispatcher.h
Expand Up @@ -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,
Expand Down
36 changes: 36 additions & 0 deletions mms-lib/include/mms_handler.h
Expand Up @@ -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;
Expand All @@ -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);
Expand Down Expand Up @@ -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 */

/*
Expand Down
2 changes: 2 additions & 0 deletions mms-lib/include/mms_lib_log.h
Expand Up @@ -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)\
Expand Down
9 changes: 9 additions & 0 deletions mms-lib/include/mms_lib_types.h
Expand Up @@ -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;
Expand All @@ -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 {
Expand Down
4 changes: 4 additions & 0 deletions mms-lib/mms-lib.pro
Expand Up @@ -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 \
Expand All @@ -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 \
Expand Down

0 comments on commit 7fdf73e

Please sign in to comment.