Simplify CallWaiting plugin interface
authorDenis Kenzior <denkenz@gmail.com>
Thu, 28 May 2009 16:21:26 +0000 (11:21 -0500)
committerDenis Kenzior <denkenz@gmail.com>
Thu, 28 May 2009 23:25:45 +0000 (18:25 -0500)
The use of a struct with status & cls seemed pointless when only
a single integer can work just as well.

Also the Fax & Data attributes have been squished.  oFono does
not yet support those call types.

drivers/atmodem/call-waiting.c
src/call-waiting.c
src/driver.h

index cd3370c..2e978d5 100644 (file)
@@ -45,11 +45,11 @@ static void ccwa_query_cb(gboolean ok, GAtResult *result, gpointer user_data)
 {
        struct cb_data *cbd = user_data;
        ofono_call_waiting_status_cb_t cb = cbd->cb;
+       int conditions = 0;
+       int status;
+       int cls;
        struct ofono_error error;
        GAtResultIter iter;
-       int num = 0;
-       struct ofono_cw_condition *list = NULL;
-       int i;
 
        dump_response("ccwa_query_cb", ok, result);
        decode_at_error(&error, g_at_result_final_response(result));
@@ -59,40 +59,18 @@ static void ccwa_query_cb(gboolean ok, GAtResult *result, gpointer user_data)
 
        g_at_result_iter_init(&iter, result);
 
-       while (g_at_result_iter_next(&iter, "+CCWA:"))
-               num += 1;
-
-       /* Specification is really unclear about this
-        * generate status=0 for all classes just in case
-        */
-       if (num == 0) {
-               list = g_new(struct ofono_cw_condition, 1);
-               num = 1;
-
-               list->status = 0;
-               list->cls = GPOINTER_TO_INT(cbd->user);
-
-               goto out;
-       }
-
-       list = g_new(struct ofono_cw_condition, num);
-
-       g_at_result_iter_init(&iter, result);
-       num = 0;
-
        while (g_at_result_iter_next(&iter, "+CCWA:")) {
-               g_at_result_iter_next_number(&iter, &(list[num].status));
-               g_at_result_iter_next_number(&iter, &(list[num].cls));
+               g_at_result_iter_next_number(&iter, &status);
+               g_at_result_iter_next_number(&iter, &cls);
 
-               num += 1;
+               if (status == 1)
+                       conditions |= cls;
        }
 
-       for (i = 0; i < num; i++)
-               ofono_debug("ccwa_cb: %d, %d", list[i].status, list[i].cls);
+       ofono_debug("CW enabled for: %d", conditions);
 
 out:
-       cb(&error, num, list, cbd->data);
-       g_free(list);
+       cb(&error, conditions, cbd->data);
 }
 
 static void at_ccwa_query(struct ofono_modem *modem, int cls,
@@ -122,7 +100,7 @@ error:
 
        {
                DECLARE_FAILURE(error);
-               cb(&error, 0, NULL, data);
+               cb(&error, 0, data);
        }
 }
 
index e91218f..29773b8 100644 (file)
@@ -47,53 +47,19 @@ struct call_waiting_data {
        struct ofono_call_waiting_ops *ops;
        int flags;
        DBusMessage *pending;
-       GSList *cw_list;
+       int conditions;
        int ss_req_type;
        int ss_req_cls;
 };
 
-static const char *enabled = "enabled";
-static const char *disabled = "disabled";
-
 static void cw_register_ss_controls(struct ofono_modem *modem);
 static void cw_unregister_ss_controls(struct ofono_modem *modem);
 
-static gint cw_condition_compare(gconstpointer a, gconstpointer b)
-{
-       const struct ofono_cw_condition *ca = a;
-       const struct ofono_cw_condition *cb = b;
-
-       if (ca->cls < cb->cls)
-               return -1;
-
-       if (ca->cls > cb->cls)
-               return 1;
-
-       return 0;
-}
-
-static gint cw_condition_find_with_cls(gconstpointer a, gconstpointer b)
-{
-       const struct ofono_cw_condition *c = a;
-       int cls = GPOINTER_TO_INT(b);
-
-       if (c->cls < cls)
-               return -1;
-
-       if (c->cls > cls)
-               return 1;
-
-       return 0;
-}
-
 static struct call_waiting_data *call_waiting_create()
 {
        struct call_waiting_data *r;
 
-       r = g_try_new0(struct call_waiting_data, 1);
-
-       if (!r)
-               return r;
+       r = g_new0(struct call_waiting_data, 1);
 
        return r;
 }
@@ -105,132 +71,59 @@ static void call_waiting_destroy(gpointer data)
 
        cw_unregister_ss_controls(modem);
 
-       g_slist_foreach(cw->cw_list, (GFunc)g_free, NULL);
-       g_slist_free(cw->cw_list);
-
        g_free(cw);
 }
 
-static void cw_cond_list_print(GSList *list)
-{
-       GSList *l;
-       struct ofono_cw_condition *cond;
-
-       for (l = list; l; l = l->next) {
-               cond = l->data;
-
-               ofono_debug("CW condition status: %d, class: %d",
-                               cond->status, cond->cls);
-       }
-}
-
-static GSList *cw_cond_list_create(int total,
-                                       const struct ofono_cw_condition *list)
-{
-       GSList *l = NULL;
-       int i;
-       int j;
-       struct ofono_cw_condition *cond;
-
-       /* Specification is not really clear on how the results are reported,
-        * most modems report it as multiple list items, one for each class
-        * however, specification does leave room for a single compound value
-        * to be reported
-        */
-       for (i = 0; i < total; i++) {
-               for (j = 1; j <= BEARER_CLASS_PAD; j = j << 1) {
-                       if (!(list[i].cls & j))
-                               continue;
-
-                       if (list[i].status == 0)
-                               continue;
-
-                       cond = g_new0(struct ofono_cw_condition, 1);
-
-                       memcpy(cond, &list[i], sizeof(struct ofono_cw_condition));
-                       cond->cls = j;
-
-                       l = g_slist_insert_sorted(l, cond,
-                                                       cw_condition_compare);
-               }
-       }
-
-       return l;
-}
-
-static void set_new_cond_list(struct ofono_modem *modem, GSList *new_cw_list)
+static void update_conditions(struct ofono_modem *modem, int new_conditions,
+                               int mask)
 {
        struct call_waiting_data *cw = modem->call_waiting;
        DBusConnection *conn = dbus_gsm_connection();
-       GSList *n;
-       GSList *o;
-       struct ofono_cw_condition *nc;
-       struct ofono_cw_condition *oc;
        char buf[64];
+       int j;
+       const char *value;
 
-       for (n = new_cw_list; n; n = n->next) {
-               nc = n->data;
-
-               if (nc->cls > BEARER_CLASS_FAX)
+       for (j = 1; j <= BEARER_CLASS_PAD; j = j << 1) {
+               if ((j & mask) == 0)
                        continue;
 
-               sprintf(buf, "%s", bearer_class_to_string(nc->cls));
-
-               o = g_slist_find_custom(cw->cw_list, GINT_TO_POINTER(nc->cls),
-                                       cw_condition_find_with_cls);
-
-               if (o) {
-                       g_free(o->data);
-                       cw->cw_list = g_slist_remove(cw->cw_list, o->data);
-               } else {
-                       dbus_gsm_signal_property_changed(conn, modem->path,
-                                                       CALL_WAITING_INTERFACE,
-                                                       buf, DBUS_TYPE_STRING,
-                                                       &enabled);
-               }
-       }
-
-       for (o = cw->cw_list; o; o = o->next) {
-               oc = o->data;
+               if ((cw->conditions & j) == (new_conditions & j))
+                       continue;
 
-               sprintf(buf, "%s", bearer_class_to_string(oc->cls));
+               if (new_conditions & j)
+                       value = "enabled";
+               else
+                       value = "disabled";
 
+               sprintf(buf, "%s", bearer_class_to_string(j));
                dbus_gsm_signal_property_changed(conn, modem->path,
                                                        CALL_WAITING_INTERFACE,
                                                        buf, DBUS_TYPE_STRING,
-                                                       &disabled);
+                                                       &value);
        }
 
-       g_slist_foreach(cw->cw_list, (GFunc)g_free, NULL);
-       g_slist_free(cw->cw_list);
-
-       cw->cw_list = new_cw_list;
+       cw->conditions = new_conditions;
 }
 
 static void property_append_cw_conditions(DBusMessageIter *dict,
-                                               GSList *cw_list, int mask)
+                                               int conditions, int mask)
 {
-       GSList *l;
        int i;
-       struct ofono_cw_condition *cw;
        const char *prop;
+       const char *value;
 
-       for (i = 1, l = cw_list; i <= BEARER_CLASS_PAD; i = i << 1) {
+       for (i = 1; i <= BEARER_CLASS_PAD; i = i << 1) {
                if (!(mask & i))
                        continue;
 
                prop = bearer_class_to_string(i);
 
-               while (l && (cw = l->data) && (cw->cls < i))
-                       l = l->next;
-
-               if (!l || cw->cls != i) {
-                       dbus_gsm_dict_append(dict, prop, DBUS_TYPE_STRING,
-                                               &disabled);
-                       continue;
-               }
+               if (conditions & i)
+                       value = "enabled";
+               else
+                       value = "disabled";
 
-               dbus_gsm_dict_append(dict, prop, DBUS_TYPE_STRING, &enabled);
+               dbus_gsm_dict_append(dict, prop, DBUS_TYPE_STRING, &value);
        }
 }
 
@@ -263,7 +156,7 @@ static void generate_ss_query_reply(struct ofono_modem *modem)
        dbus_message_iter_open_container(&vstruct, DBUS_TYPE_ARRAY,
                                        PROPERTIES_ARRAY_SIGNATURE, &dict);
 
-       property_append_cw_conditions(&dict, cw->cw_list, cw->ss_req_cls);
+       property_append_cw_conditions(&dict, cw->conditions, cw->ss_req_cls);
 
        dbus_message_iter_close_container(&vstruct, &dict);
 
@@ -274,13 +167,11 @@ static void generate_ss_query_reply(struct ofono_modem *modem)
        dbus_gsm_pending_reply(&cw->pending, reply);
 }
 
-static void cw_ss_query_callback(const struct ofono_error *error, int num,
-                                       struct ofono_cw_condition *cond_list,
+static void cw_ss_query_callback(const struct ofono_error *error, int status,
                                        void *data)
 {
        struct ofono_modem *modem = data;
        struct call_waiting_data *cw = modem->call_waiting;
-       GSList *l;
 
        if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
                ofono_debug("setting CW via SS failed");
@@ -292,11 +183,7 @@ static void cw_ss_query_callback(const struct ofono_error *error, int num,
                return;
        }
 
-       l = cw_cond_list_create(num, cond_list);
-
-       cw_cond_list_print(l);
-
-       set_new_cond_list(modem, l);
+       update_conditions(modem, status, BEARER_CLASS_VOICE);
        cw->flags |= CALL_WAITING_FLAG_CACHED;
 
        generate_ss_query_reply(modem);
@@ -427,30 +314,26 @@ static DBusMessage *generate_get_properties_reply(struct ofono_modem *modem,
                                                PROPERTIES_ARRAY_SIGNATURE,
                                                &dict);
 
-       property_append_cw_conditions(&dict, cw->cw_list, BEARER_CLASS_DEFAULT);
+       property_append_cw_conditions(&dict, cw->conditions,
+                                       BEARER_CLASS_VOICE);
 
        dbus_message_iter_close_container(&iter, &dict);
 
        return reply;
 }
 
-static void cw_query_callback(const struct ofono_error *error, int num,
-                               struct ofono_cw_condition *cond_list, void *data)
+static void cw_query_callback(const struct ofono_error *error, int status,
+                               void *data)
 {
        struct ofono_modem *modem = data;
        struct call_waiting_data *cw = modem->call_waiting;
-       GSList *l = NULL;
 
        if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
                ofono_debug("Error during cw query");
                goto out;
        }
 
-       l = cw_cond_list_create(num, cond_list);
-
-       cw_cond_list_print(l);
-
-       set_new_cond_list(modem, l);
+       update_conditions(modem, status, BEARER_CLASS_VOICE);
        cw->flags |= CALL_WAITING_FLAG_CACHED;
 
 out:
@@ -484,12 +367,11 @@ static DBusMessage *cw_get_properties(DBusConnection *conn, DBusMessage *msg,
        return NULL;
 }
 
-static void set_query_callback(const struct ofono_error *error, int num,
-                               struct ofono_cw_condition *cond_list, void *data)
+static void set_query_callback(const struct ofono_error *error, int status,
+                               void *data)
 {
        struct ofono_modem *modem = data;
        struct call_waiting_data *cw = modem->call_waiting;
-       GSList *l = NULL;
 
        if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
                ofono_error("CW set succeeded, but query failed!");
@@ -503,11 +385,7 @@ static void set_query_callback(const struct ofono_error *error, int num,
        dbus_gsm_pending_reply(&cw->pending,
                                dbus_message_new_method_return(cw->pending));
 
-       l = cw_cond_list_create(num, cond_list);
-
-       cw_cond_list_print(l);
-
-       set_new_cond_list(modem, l);
+       update_conditions(modem, status, BEARER_CLASS_VOICE);
 }
 
 static void set_callback(const struct ofono_error *error, void *data)
index d6927db..4a5dac3 100644 (file)
@@ -90,12 +90,6 @@ struct ofono_cf_condition {
        int time;
 };
 
-/* 27.007 Section 7.12 Call Waiting */
-struct ofono_cw_condition {
-       int status;
-       int cls;
-};
-
 /* 27.007 Section 7.1 Subscriber Number */
 struct ofono_own_number {
        struct ofono_phone_number phone_number;
@@ -150,8 +144,7 @@ typedef void (*ofono_clir_setting_cb_t)(const struct ofono_error *error,
                                        int override, int network, void *data);
 
 typedef void (*ofono_call_waiting_status_cb_t)(const struct ofono_error *error,
-                                       int num, struct ofono_cw_condition *cond,
-                                       void *data);
+                                               int status, void *data);
 
 typedef void (*ofono_call_meter_query_cb_t)(const struct ofono_error *error,
                                        int value, void *data);