summaryrefslogtreecommitdiffstats
path: root/drivers/hfpmodem/handsfree.c
diff options
context:
space:
mode:
authorAndrew Earl <andrewx.earl@intel.com>2014-04-08 09:21:47 +0100
committerDenis Kenzior <denkenz@gmail.com>2014-04-10 09:52:11 -0500
commite7f055385f2e905a0d28be5c13f56a0f60ee5689 (patch)
tree096a82567b0a0ad91946d211cf6645c6f65744ad /drivers/hfpmodem/handsfree.c
parent8cfcfa45190de53ba857d1ac7ecf9c59a35b37c0 (diff)
downloadofono-e7f055385f2e905a0d28be5c13f56a0f60ee5689.tar.bz2
hfp: Add CNUM query to handsfree interface for subscriber number
Diffstat (limited to 'drivers/hfpmodem/handsfree.c')
-rw-r--r--drivers/hfpmodem/handsfree.c88
1 files changed, 88 insertions, 0 deletions
diff --git a/drivers/hfpmodem/handsfree.c b/drivers/hfpmodem/handsfree.c
index e62fa26d..81baaa19 100644
--- a/drivers/hfpmodem/handsfree.c
+++ b/drivers/hfpmodem/handsfree.c
@@ -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,