From: Inaky Perez-Gonzalez <[email protected]>

This adds state to outgoing/in-transit SMS messages. This will be used
later on for persistence / D-Bus, when the SMS life cycle is expanded.

The state is a variable in the 'struct tx_queue_entry' which gets
updated as messages go through the hoops.
---
 src/sms.c |  107 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 107 insertions(+), 0 deletions(-)

diff --git a/src/sms.c b/src/sms.c
index 87ea926..0bdfc45 100644
--- a/src/sms.c
+++ b/src/sms.c
@@ -50,6 +50,35 @@ static gboolean tx_next(gpointer user_data);
 
 static GSList *g_drivers = NULL;
 
+/*
+ * SMS TX message's state
+ *
+ * When a message is queued to be delivered, it will transition
+ * through a set of states.
+ *
+ * Allowed transition table (Allowed, Not-allowed) from left to right:
+ *
+ *          UNINITIALIZED     CANCELING  FAILED
+ *               | QUEUED DONE   | CANCELLED  EXPIRED
+ * UNINITIALIZED -    A     N    N    N    N    N
+ * QUEUED        N    -     A    A    N    A    N
+ * DONE          A    N     -    N    N    N    N
+ * CANCELING     N    N     N    -    A    A    A
+ * CANCELLED     A    N     N    N    -    N    N
+ * FAILED        A    N     N    N    N    -    N
+ * EXPIRED       A    N     N    N    N    N    -
+ */
+enum ofono_sms_tx_state {
+       OFONO_SMS_TX_ST_UNINITIALIZED,
+       OFONO_SMS_TX_ST_QUEUED,
+       OFONO_SMS_TX_ST_DONE,
+       OFONO_SMS_TX_ST_CANCELING,
+       OFONO_SMS_TX_ST_CANCELLED,
+       OFONO_SMS_TX_ST_FAILED,
+       OFONO_SMS_TX_ST_EXPIRED,
+       __OFONO_SMS_TX_ST_INVALID,
+};
+
 struct ofono_sms {
        int flags;
        DBusMessage *pending;
@@ -79,6 +108,7 @@ struct pending_pdu {
 
 /*
  * @name: Name for the SMS message object (used by D-Bus)
+ * @state: Current state of the (in-transit) SMS
  */
 struct tx_queue_entry {
        struct pending_pdu *pdus;
@@ -90,6 +120,7 @@ struct tx_queue_entry {
        gboolean status_report;
        struct sms_address receiver;
        char *name;
+       enum ofono_sms_tx_state state;
 };
 
 static void set_sca(struct ofono_sms *sms,
@@ -297,6 +328,77 @@ static DBusMessage *sms_set_property(DBusConnection *conn, 
DBusMessage *msg,
 }
 
 
+/* Check if a state transition is legal */
+static void ofono_sms_tx_state_check(const char *file, unsigned line,
+                                    const struct tx_queue_entry *entry,
+                                    enum ofono_sms_tx_state state_old,
+                                    enum ofono_sms_tx_state state_new,
+                                    unsigned states_allowed_bm)
+{
+       if (((1 << state_new) & states_allowed_bm) == 0)
+               ofono_warn("%s:%d: SW BUG? Forbidden state change "
+                          "%p %u -> %u\n",
+                          file, line, entry, state_old, state_new);
+}
+
+
+/*
+ * Set a pending SMS's state
+ *
+ * This is just syntatic sugar that validates that the transition is
+ * correct and warns out otherwise. The transition table is defined in
+ * the doc block for 'enum ofono_sms_tx_state'.
+ *
+ * In case of inconsistency, we just warn and press forward.
+ */
+#define ofono_sms_tx_state_set(entry, new_state) \
+       __ofono_sms_tx_state_set(entry, new_state, __FILE__, __LINE__)
+
+static void __ofono_sms_tx_state_set(struct tx_queue_entry *entry,
+                                    enum ofono_sms_tx_state state_new,
+                                    const char *file, unsigned line)
+{
+       enum ofono_sms_tx_state state_old = entry->state;
+
+       switch (state_old) {
+       case OFONO_SMS_TX_ST_UNINITIALIZED:
+               ofono_sms_tx_state_check(
+                       file, line, entry, state_old, state_new,
+                       1 << OFONO_SMS_TX_ST_QUEUED);
+               break;
+       case OFONO_SMS_TX_ST_QUEUED:
+               ofono_sms_tx_state_check(
+                       file, line, entry, state_old, state_new,
+                       1 << OFONO_SMS_TX_ST_DONE
+                       | 1 << OFONO_SMS_TX_ST_CANCELING
+                       | 1 << OFONO_SMS_TX_ST_FAILED);
+               break;
+       case OFONO_SMS_TX_ST_CANCELING:
+               ofono_sms_tx_state_check(
+                       file, line, entry, state_old, state_new,
+                       1 << OFONO_SMS_TX_ST_CANCELLED
+                       | 1 << OFONO_SMS_TX_ST_FAILED
+                       | 1 << OFONO_SMS_TX_ST_EXPIRED);
+               break;
+       case OFONO_SMS_TX_ST_DONE:
+       case OFONO_SMS_TX_ST_CANCELLED:
+       case OFONO_SMS_TX_ST_FAILED:
+       case OFONO_SMS_TX_ST_EXPIRED:
+               ofono_sms_tx_state_check(
+                       file, line, entry, state_old, state_new,
+                       1 << OFONO_SMS_TX_ST_UNINITIALIZED);
+               break;
+       case __OFONO_SMS_TX_ST_INVALID:
+       default:
+               ofono_warn("%s:%d: SW BUG? Bad state change %p %u -> %u\n",
+                          file, line, entry, state_old, state_new);
+       }
+       ofono_debug("%s:%d: SMS state change: %p %u -> %u\n",
+                   file, line, entry, state_old, state_new);
+       entry->state = state_new;
+}
+
+
 /*
  * Destroy/release the contents of a 'struct tx_queue_entry'
  *
@@ -307,6 +409,7 @@ static void tx_queue_entry_destroy(struct tx_queue_entry 
*entry)
 {
        g_free(entry->pdus);
        g_free(entry->name);
+       entry->state = __OFONO_SMS_TX_ST_INVALID;
 }
 
 static void tx_queue_entry_destroy_free(gpointer _entry, gpointer unused)
@@ -337,6 +440,7 @@ static void tx_finished(const struct ofono_error *error, 
int mr, void *data)
 
                DBG("Max retries reached, giving up");
 
+               ofono_sms_tx_state_set(entry, OFONO_SMS_TX_ST_CANCELING);
                entry = g_queue_pop_head(sms->txq);
                __ofono_dbus_pending_reply(&entry->msg,
                                        __ofono_error_failed(entry->msg));
@@ -345,6 +449,7 @@ static void tx_finished(const struct ofono_error *error, 
int mr, void *data)
                                        time(NULL),
                                        OFONO_HISTORY_SMS_STATUS_SUBMIT_FAILED);
 
+               ofono_sms_tx_state_set(entry, OFONO_SMS_TX_ST_FAILED);
                tx_queue_entry_destroy(entry);
                g_free(entry);
 
@@ -378,6 +483,7 @@ static void tx_finished(const struct ofono_error *error, 
int mr, void *data)
                                        time(NULL),
                                        OFONO_HISTORY_SMS_STATUS_SUBMITTED);
 
+       ofono_sms_tx_state_set(entry, OFONO_SMS_TX_ST_DONE);
        tx_queue_entry_destroy(entry);
        g_free(entry);
 
@@ -534,6 +640,7 @@ static DBusMessage *sms_send_message(DBusConnection *conn, 
DBusMessage *msg,
        ofono_debug("sms/entry %p name %s\n", entry, entry->name);
 
        g_queue_push_tail(sms->txq, entry);
+       ofono_sms_tx_state_set(entry, OFONO_SMS_TX_ST_QUEUED);
 
        modem = __ofono_atom_get_modem(sms->atom);
        __ofono_history_sms_send_pending(modem, entry->msg_id, to,
-- 
1.6.6.1

_______________________________________________
ofono mailing list
[email protected]
http://lists.ofono.org/listinfo/ofono

Reply via email to