diff --git a/mms-lib/src/mms_codec.c b/mms-lib/src/mms_codec.c index 7e7fc10..571663d 100644 --- a/mms-lib/src/mms_codec.c +++ b/mms-lib/src/mms_codec.c @@ -90,7 +90,7 @@ enum mms_header { MMS_HEADER_SUBJECT = 0x16, MMS_HEADER_TO = 0x17, MMS_HEADER_TRANSACTION_ID = 0x18, - MMS_HEADER_RETRIEVE_STATUS = 0x19, + MMS_HEADER_RETRIEVE_STATUS = 0x19, MMS_HEADER_RETRIEVE_TEXT = 0x1a, MMS_HEADER_READ_STATUS = 0x1b, __MMS_HEADER_MAX = 0x1c, @@ -853,7 +853,8 @@ static gboolean extract_status(struct wsp_header_iter *iter, void *user) return FALSE; } -static gboolean extract_retrieve_status(struct wsp_header_iter *iter, void *user) +static gboolean extract_retrieve_status(struct wsp_header_iter *iter, + void *user) { unsigned char *out = user; const unsigned char *p; @@ -863,6 +864,7 @@ static gboolean extract_retrieve_status(struct wsp_header_iter *iter, void *user p = wsp_header_iter_get_val(iter); + /* Accept known codes, ignore unknown ones */ switch (p[0]) { case MMS_MESSAGE_RETRIEVE_STATUS_OK: case MMS_MESSAGE_RETRIEVE_STATUS_ERR_TRANS_FAILURE: @@ -873,10 +875,10 @@ static gboolean extract_retrieve_status(struct wsp_header_iter *iter, void *user case MMS_MESSAGE_RETRIEVE_STATUS_ERR_PERM_MESSAGE_NOT_FOUND: case MMS_MESSAGE_RETRIEVE_STATUS_ERR_PERM_CONTENT_UNSUPPORTED: *out = p[0]; - return TRUE; + break; } - return FALSE; + return TRUE; } static gboolean extract_read_status(struct wsp_header_iter *iter, void *user) @@ -1350,6 +1352,8 @@ static gboolean decode_retrieve_conf(struct wsp_header_iter *iter, HEADER_FLAG_MANDATORY, &out->rc.date, MMS_HEADER_READ_REPORT, 0, &out->rc.rr, + MMS_HEADER_RETRIEVE_STATUS, + 0, &out->rc.retrieve_status, MMS_HEADER_INVALID) == FALSE) return FALSE; diff --git a/mms-lib/src/mms_codec.h b/mms-lib/src/mms_codec.h index 74af7a3..f7b6141 100644 --- a/mms-lib/src/mms_codec.h +++ b/mms-lib/src/mms_codec.h @@ -120,6 +120,7 @@ struct mms_retrieve_conf { char *msgid; time_t date; gboolean rr; + enum mms_message_retrieve_status retrieve_status; }; struct mms_send_req { diff --git a/mms-lib/src/mms_task_decode.c b/mms-lib/src/mms_task_decode.c index 2e4bcf5..0cc90b6 100644 --- a/mms-lib/src/mms_task_decode.c +++ b/mms-lib/src/mms_task_decode.c @@ -102,7 +102,7 @@ mms_task_decode_make_content_id( static MMSMessage* -mms_task_decode_process_retrieve_conf( +mms_task_decode_retrieve_conf( MMSTask* task, const MMSPdu* pdu, const guint8* pdu_data, @@ -200,25 +200,54 @@ mms_task_decode_process_retrieve_conf( } static -MMSMessage* +void mms_task_decode_process_pdu( - MMSTask* task, - const guint8* data, - gsize len) + MMSTaskDecode* dec, + MMSPdu* pdu) { - MMSMessage* msg = NULL; - MMSPdu* pdu = g_new0(MMSPdu, 1); + MMSTask* task = &dec->task; + const void* data = g_mapped_file_get_contents(dec->map); + const gsize len = g_mapped_file_get_length(dec->map); if (mms_message_decode(data, len, pdu)) { if (pdu->type == MMS_MESSAGE_TYPE_RETRIEVE_CONF) { - msg = mms_task_decode_process_retrieve_conf(task, pdu, data, len); + struct mms_retrieve_conf* rc = &pdu->rc; + if (rc->retrieve_status == 0 /* no status at all */ || + rc->retrieve_status == MMS_MESSAGE_RETRIEVE_STATUS_OK) { + MMSMessage* msg; + msg = mms_task_decode_retrieve_conf(task, pdu, data, len); + if (msg) { + /* Successfully received and decoded MMS message */ + mms_task_queue_and_unref(task->delegate, + mms_task_ack_new(task->config, task->handler, + task->id, task->imsi, dec->transaction_id)); + mms_task_queue_and_unref(task->delegate, + mms_task_publish_new(task->config, task->handler, msg)); + mms_message_unref(msg); + return; + } + } else { + /* MMS server returned an error. Most likely, MMS message + * has expired. We need more MMS_RECEIVE_STATE values to + * better describe it to the user. */ + MMS_ERR("MMSC responded with %u", rc->retrieve_status); + mms_handler_message_receive_state_changed(task->handler, + task->id, MMS_RECEIVE_STATE_DOWNLOAD_ERROR); + return; + } } else { MMS_ERR("Unexpected MMS PDU type %u", (guint)pdu->type); } } else { MMS_ERR("Failed to decode MMS PDU"); } - mms_message_free(pdu); - return msg; + + /* Tell MMS server that we didn't understand this PDU */ + mms_task_queue_and_unref(task->delegate, + mms_task_notifyresp_new(task->config, task->handler, task->id, + task->imsi, dec->transaction_id, + MMS_MESSAGE_NOTIFY_STATUS_UNRECOGNISED)); + mms_handler_message_receive_state_changed(task->handler, task->id, + MMS_RECEIVE_STATE_DECODING_ERROR); } static @@ -226,25 +255,9 @@ void mms_task_decode_run( MMSTask* task) { - MMSTaskDecode* dec = MMS_TASK_DECODE(task); - const void* data = g_mapped_file_get_contents(dec->map); - const gsize size = g_mapped_file_get_length(dec->map); - MMSMessage* msg = mms_task_decode_process_pdu(task, data, size); - if (msg) { - mms_task_queue_and_unref(task->delegate, - mms_task_ack_new(task->config, task->handler, task->id, task->imsi, - dec->transaction_id)); - mms_task_queue_and_unref(task->delegate, - mms_task_publish_new(task->config, task->handler, msg)); - mms_message_unref(msg); - } else { - mms_handler_message_receive_state_changed(task->handler, task->id, - MMS_RECEIVE_STATE_DECODING_ERROR); - mms_task_queue_and_unref(task->delegate, - mms_task_notifyresp_new(task->config, task->handler, task->id, - task->imsi, dec->transaction_id, - MMS_MESSAGE_NOTIFY_STATUS_UNRECOGNISED)); - } + MMSPdu* pdu = g_new0(MMSPdu, 1); + mms_task_decode_process_pdu(MMS_TASK_DECODE(task), pdu); + mms_message_free(pdu); mms_task_set_state(task, MMS_TASK_STATE_DONE); } diff --git a/mms-lib/test/retrieve/data/MessageNotFound/m-notification.ind b/mms-lib/test/retrieve/data/MessageNotFound/m-notification.ind new file mode 100644 index 0000000..91799ac Binary files /dev/null and b/mms-lib/test/retrieve/data/MessageNotFound/m-notification.ind differ diff --git a/mms-lib/test/retrieve/data/MessageNotFound/m-retrieve.conf b/mms-lib/test/retrieve/data/MessageNotFound/m-retrieve.conf new file mode 100644 index 0000000..8fb8956 Binary files /dev/null and b/mms-lib/test/retrieve/data/MessageNotFound/m-retrieve.conf differ diff --git a/mms-lib/test/retrieve/test_retrieve.c b/mms-lib/test/retrieve/test_retrieve.c index 3163f9f..e563c51 100644 --- a/mms-lib/test/retrieve/test_retrieve.c +++ b/mms-lib/test/retrieve/test_retrieve.c @@ -209,6 +209,18 @@ static const TestDesc retrieve_tests[] = { MMS_MESSAGE_TYPE_NONE, TEST_PARTS_NONE, 0 + },{ + "MessageNotFound", + NULL, + "m-notification.ind", + "m-retrieve.conf", + SOUP_STATUS_OK, + MMS_CONTENT_TYPE, + NULL, + MMS_RECEIVE_STATE_DOWNLOAD_ERROR, + MMS_MESSAGE_TYPE_NONE, + TEST_PARTS_NONE, + 0 },{ "GarbageRetrieve", NULL,