From: Pasi Miettinen <[email protected]>
---
include/history.h | 2 +
src/sms.c | 157 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
src/smsutil.h | 6 ++
3 files changed, 163 insertions(+), 2 deletions(-)
diff --git a/include/history.h b/include/history.h
index 300a4fb..17445f0 100644
--- a/include/history.h
+++ b/include/history.h
@@ -33,6 +33,8 @@ enum ofono_history_sms_status {
OFONO_HISTORY_SMS_STATUS_PENDING,
OFONO_HISTORY_SMS_STATUS_SUBMITTED,
OFONO_HISTORY_SMS_STATUS_SUBMIT_FAILED,
+ OFONO_HISTORY_SMS_STATUS_DELIVERED,
+ OFONO_HISTORY_SMS_STATUS_DELIVER_FAILED,
};
struct ofono_history_context {
diff --git a/src/sms.c b/src/sms.c
index 2d9088b..0a8bf05 100644
--- a/src/sms.c
+++ b/src/sms.c
@@ -67,6 +67,17 @@ struct ofono_sms {
const struct ofono_sms_driver *driver;
void *driver_data;
struct ofono_atom *atom;
+ GSList *pending_status_reports;
+};
+
+struct mr_number {
+ guint8 mr;
+ enum sms_status_report_state delivery_status;
+};
+
+struct pending_status_report_mr_numbers {
+ unsigned int ofono_msg_id;
+ GSList *pending_mr_numbers;
};
struct pending_pdu {
@@ -82,6 +93,7 @@ struct tx_queue_entry {
unsigned int msg_id;
unsigned int retry;
DBusMessage *msg;
+ gboolean status_report;
};
static void set_sca(struct ofono_sms *sms,
@@ -263,6 +275,47 @@ static DBusMessage *sms_set_property(DBusConnection *conn,
DBusMessage *msg,
return __ofono_error_invalid_args(msg);
}
+static void add_pending_status_report(struct ofono_sms *sms, int mr,
+ unsigned int msg_id)
+{
+ struct pending_status_report_mr_numbers *status_report_mr_numbers;
+ GSList *l;
+ struct mr_number *new_mr;
+
+ for (l = sms->pending_status_reports; l; l = l->next) {
+ status_report_mr_numbers = l->data;
+
+ if (status_report_mr_numbers->ofono_msg_id == msg_id) {
+ /*Relate new MR-number to existing ofono_msg_id*/
+ new_mr = g_new0(struct mr_number, 1);
+ new_mr->mr = mr;
+ new_mr->delivery_status = SMS_STATUS_REPORT_PENDING;
+ status_report_mr_numbers->pending_mr_numbers =
+ g_slist_append(status_report_mr_numbers-> \
+ pending_mr_numbers, new_mr);
+ return;
+ }
+ }
+
+ /*Create new ofono_msg_id and relate MR-number to it*/
+ status_report_mr_numbers =
+ g_new0(struct pending_status_report_mr_numbers, 1);
+
+ status_report_mr_numbers->ofono_msg_id = msg_id;
+
+ new_mr = g_new0(struct mr_number, 1);
+ new_mr->mr = mr;
+ new_mr->delivery_status = SMS_STATUS_REPORT_PENDING;
+ status_report_mr_numbers->pending_mr_numbers =
+ g_slist_append(status_report_mr_numbers-> \
+ pending_mr_numbers, new_mr);
+
+ sms->pending_status_reports =
+ g_slist_append(sms->pending_status_reports,
+ status_report_mr_numbers);
+
+}
+
static void tx_finished(const struct ofono_error *error, int mr, void *data)
{
struct ofono_sms *sms = data;
@@ -306,6 +359,9 @@ static void tx_finished(const struct ofono_error *error,
int mr, void *data)
entry->cur_pdu += 1;
entry->retry = 0;
+ if(entry->status_report)
+ add_pending_status_report(sms, mr, entry->msg_id);
+
if (entry->cur_pdu < entry->num_pdus) {
sms->tx_source = g_timeout_add(0, tx_next, sms);
return;
@@ -437,6 +493,7 @@ static DBusMessage *sms_send_message(DBusConnection *conn,
DBusMessage *msg,
entry->msg = dbus_message_ref(msg);
entry->msg_id = sms->next_msg_id++;
+ entry->status_report = ask_status_report;
g_queue_push_tail(sms->txq, entry);
@@ -542,11 +599,102 @@ static void dispatch_text_message(struct ofono_sms *sms,
}
}
+static void update_pending_status_report_mr_number(struct ofono_sms *sms,
+ guint8 mr, enum sms_status_report_state status_report_state)
+{
+ struct ofono_modem *modem = __ofono_atom_get_modem(sms->atom);
+ struct pending_status_report_mr_numbers *status_report_mr_numbers;
+ GSList *l;
+ GSList *i;
+ struct mr_number *current_mr;
+ gboolean delivery_successful;
+
+ /*Each ofono_msg_id can relate to 1-n mr_numbers*/
+ for (l = sms->pending_status_reports; l; l = l->next) {
+ delivery_successful = TRUE;
+ status_report_mr_numbers = l->data;
+
+ for(i = status_report_mr_numbers->pending_mr_numbers; i;
+ i = i->next) {
+ current_mr = i->data;
+
+ /*Message with current MR-number was delivered*/
+ if(current_mr->mr == mr &&
+ status_report_state ==
+ SMS_STATUS_REPORT_SENDING_SUCCEEDED) {
+ current_mr->delivery_status =
+ SMS_STATUS_REPORT_SENDING_SUCCEEDED;
+ }
+
+ if(current_mr->delivery_status ==
+ SMS_STATUS_REPORT_PENDING)
+ /*msg_id still relates to pending status
report*/
+ delivery_successful = FALSE;
+
+ /*If one part of the fragmented message is undelivered,
+ whole message is declared undelivered*/
+ if(current_mr->mr == mr &&
+ status_report_state ==
+ SMS_STATUS_REPORT_SENDING_FAILED) {
+
+ DBG("SMS-STATUS-REPORT: message %d not "\
+ "delivered", status_report_mr_numbers-> \
+ ofono_msg_id);
+
+ __ofono_history_sms_send_status(modem,
+ status_report_mr_numbers->ofono_msg_id,
+ time(NULL),
+ OFONO_HISTORY_SMS_STATUS_DELIVER_FAILED);
+
+ /*Free msg_id and relating MR-numbers*/
+ g_slist_foreach(status_report_mr_numbers-> \
+ pending_mr_numbers, (GFunc)g_free,
+ NULL);
+ g_slist_free(status_report_mr_numbers-> \
+ pending_mr_numbers);
+ sms->pending_status_reports =
+ g_slist_remove(sms-> \
+ pending_status_reports,
+ status_report_mr_numbers);
+ g_free(status_report_mr_numbers);
+
+ /*Received MR is handled*/
+ return;
+ }
+ }
+
+ /*all parts of the message succesfully delivered*/
+ if(delivery_successful) {
+ DBG("SMS-STATUS-REPORT: message %d delivered",
+ status_report_mr_numbers->ofono_msg_id);
+
+ __ofono_history_sms_send_status(modem,
+ status_report_mr_numbers->ofono_msg_id,
+ time(NULL),
+ OFONO_HISTORY_SMS_STATUS_DELIVERED);
+
+ /*Free msg_id and relating MR-numbers*/
+ g_slist_foreach(status_report_mr_numbers-> \
+ pending_mr_numbers, (GFunc)g_free, NULL);
+ g_slist_free(status_report_mr_numbers-> \
+ pending_mr_numbers);
+ sms->pending_status_reports =
+ g_slist_remove(sms->pending_status_reports,
+ status_report_mr_numbers);
+ g_free(status_report_mr_numbers);
+
+ /*Received MR is handled*/
+ return;
+ }
+ }
+}
+
static void dispatch_sms_status_report(struct ofono_sms *sms,
const enum sms_st *st,
const struct sms_address *raddr,
const struct sms_scts *scts,
- const struct sms_scts *dt)
+ const struct sms_scts *dt,
+ const guint8 mr)
{
DBusConnection *conn = ofono_dbus_get_connection();
const char *path = __ofono_atom_get_path(sms->atom);
@@ -606,11 +754,15 @@ static void dispatch_sms_status_report(struct ofono_sms
*sms,
str = sms_address_to_string(raddr);
ofono_dbus_dict_append(&dict, "Message was delivered to",
DBUS_TYPE_STRING, &str);
+ update_pending_status_report_mr_number(sms, mr,
+ SMS_STATUS_REPORT_SENDING_SUCCEEDED);
}
else{
str = sms_address_to_string(raddr);
ofono_dbus_dict_append(&dict, "Message was not delivered to",
DBUS_TYPE_STRING, &str);
+ update_pending_status_report_mr_number(sms, mr,
+ SMS_STATUS_REPORT_SENDING_FAILED);
}
/*dbus-message assembled*/
@@ -736,7 +888,8 @@ static void sms_status_report_dispatch(struct ofono_sms
*sms, GSList *sms_list)
dispatch_sms_status_report(sms, &s->status_report.st,
&s->status_report.raddr,
&s->status_report.scts,
- &s->status_report.dt);
+ &s->status_report.dt,
+ s->status_report.mr);
}
diff --git a/src/smsutil.h b/src/smsutil.h
index d55b83a..c5dc819 100644
--- a/src/smsutil.h
+++ b/src/smsutil.h
@@ -178,6 +178,12 @@ enum sms_pid_type {
SMS_PID_TYPE_USIM_DOWNLOAD = 0x7f,
};
+enum sms_status_report_state {
+ SMS_STATUS_REPORT_PENDING = 0,
+ SMS_STATUS_REPORT_SENDING_FAILED =1,
+ SMS_STATUS_REPORT_SENDING_SUCCEEDED = 2,
+};
+
enum cbs_language {
CBS_LANGUAGE_GERMAN = 0x0,
CBS_LANGUAGE_ENGLISH = 0x1,
--
1.6.0.4
_______________________________________________
ofono mailing list
[email protected]
http://lists.ofono.org/listinfo/ofono