From e7f055385f2e905a0d28be5c13f56a0f60ee5689 Mon Sep 17 00:00:00 2001 From: Andrew Earl Date: Tue, 8 Apr 2014 09:21:47 +0100 Subject: [PATCH] hfp: Add CNUM query to handsfree interface for subscriber number --- drivers/hfpmodem/handsfree.c | 88 ++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) 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,