hfp: Add CNUM query to handsfree interface for subscriber number
authorAndrew Earl <andrewx.earl@intel.com>
Tue, 8 Apr 2014 08:21:47 +0000 (09:21 +0100)
committerDenis Kenzior <denkenz@gmail.com>
Thu, 10 Apr 2014 14:52:11 +0000 (09:52 -0500)
drivers/hfpmodem/handsfree.c

index e62fa26..81baaa1 100644 (file)
@@ -43,6 +43,8 @@
 #include "hfp.h"
 #include "slc.h"
 
+#define OFONO_HANDSFREE_CNUM_SERVICE_VOICE 4
+
 static const char *binp_prefix[] = { "+BINP:", NULL };
 static const char *bvra_prefix[] = { "+BVRA:", NULL };
 
@@ -125,6 +127,91 @@ static void ciev_notify(GAtResult *result, gpointer user_data)
        ofono_handsfree_battchg_notify(hf, value);
 }
 
+static void cnum_query_cb(gboolean ok, GAtResult *result, gpointer user_data)
+{
+       struct cb_data *cbd = user_data;
+       ofono_handsfree_cnum_query_cb_t cb = cbd->cb;
+       GAtResultIter iter;
+       struct ofono_phone_number *list = NULL;
+       int num = 0;
+       struct ofono_error error;
+
+       decode_at_error(&error, g_at_result_final_response(result));
+
+       if (!ok)
+               goto out;
+
+       g_at_result_iter_init(&iter, result);
+
+       while (g_at_result_iter_next(&iter, "+CNUM:"))
+               num++;
+
+       if (num == 0)
+               goto out;
+
+       list = g_new(struct ofono_phone_number, num);
+
+       g_at_result_iter_init(&iter, result);
+
+       for (num = 0; g_at_result_iter_next(&iter, "+CNUM:"); ) {
+               const char *number;
+               int len;
+               int service;
+               int type;
+
+               list[num].number[0] = '\0';
+               list[num].type = 129;
+
+               if (!g_at_result_iter_skip_next(&iter))
+                       continue;
+
+               if (!g_at_result_iter_next_string(&iter, &number))
+                       continue;
+
+               if (!g_at_result_iter_next_number(&iter, &type))
+                       continue;
+
+               if (!g_at_result_iter_skip_next(&iter))
+                       continue;
+
+               if (!g_at_result_iter_next_number(&iter, &service))
+                       continue;
+
+               if (service == OFONO_HANDSFREE_CNUM_SERVICE_VOICE) {
+                       len = strlen(number);
+                       if (len > OFONO_MAX_PHONE_NUMBER_LENGTH)
+                               len = OFONO_MAX_PHONE_NUMBER_LENGTH;
+                       strncpy(list[num].number, number, len);
+                       list[num].number[len] = '\0';
+                       list[num].type = type;
+
+                       DBG("cnum_notify:%s", list[num].number);
+                       num++;
+               }
+       }
+
+out:
+       cb(&error, num, list, cbd->data);
+
+       g_free(list);
+
+}
+
+static void at_cnum_query(struct ofono_handsfree *hf,
+                       ofono_handsfree_cnum_query_cb_t cb, void *data)
+{
+       struct hf_data *hd = ofono_handsfree_get_data(hf);
+       struct cb_data *cbd = cb_data_new(cb, data);
+
+       if (g_at_chat_send(hd->chat, "AT+CNUM", NULL,
+                                       cnum_query_cb, cbd, g_free) > 0)
+               return;
+
+       g_free(cbd);
+
+       CALLBACK_WITH_FAILURE(cb, -1, NULL, data);
+}
+
 static gboolean hfp_handsfree_register(gpointer user_data)
 {
        struct ofono_handsfree *hf = user_data;
@@ -283,6 +370,7 @@ static struct ofono_handsfree_driver driver = {
        .name                   = "hfpmodem",
        .probe                  = hfp_handsfree_probe,
        .remove                 = hfp_handsfree_remove,
+       .cnum_query             = at_cnum_query,
        .request_phone_number   = hfp_request_phone_number,
        .voice_recognition      = hfp_voice_recognition,
        .disable_nrec           = hfp_disable_nrec,