summaryrefslogtreecommitdiffstats
path: root/drivers/hfpmodem
diff options
context:
space:
mode:
authorDenis Kenzior <denkenz@gmail.com>2014-01-19 21:39:26 -0600
committerDenis Kenzior <denkenz@gmail.com>2014-10-20 13:40:28 -0500
commitfa105c4ba6dbb7acce585ab6e00f71f2aba9db8f (patch)
tree942f90d777f1bcaaf39818fe36562149b0faf3fd /drivers/hfpmodem
parent99c03292ad43de02374e75d3db867fa657d7291e (diff)
downloadofono-fa105c4ba6dbb7acce585ab6e00f71f2aba9db8f.tar.bz2
hfp: Add initial SLC negotiation for HFP 1.7
Diffstat (limited to 'drivers/hfpmodem')
-rw-r--r--drivers/hfpmodem/slc.c95
1 files changed, 94 insertions, 1 deletions
diff --git a/drivers/hfpmodem/slc.c b/drivers/hfpmodem/slc.c
index 34f2d5c0..5e1fa28b 100644
--- a/drivers/hfpmodem/slc.c
+++ b/drivers/hfpmodem/slc.c
@@ -41,10 +41,12 @@
#include "hfp.h"
#include "slc.h"
+static const char *none_prefix[] = { NULL };
static const char *brsf_prefix[] = { "+BRSF:", NULL };
static const char *cind_prefix[] = { "+CIND:", NULL };
static const char *cmer_prefix[] = { "+CMER:", NULL };
static const char *chld_prefix[] = { "+CHLD:", NULL };
+static const char *bind_prefix[] = { "+BIND:", NULL };
struct slc_establish_data {
gint ref_count;
@@ -107,6 +109,90 @@ static void slc_established(struct slc_establish_data *sed)
sed->connect_cb(sed->userdata);
}
+static void bind_query_cb(gboolean ok, GAtResult *result, gpointer user_data)
+{
+ struct slc_establish_data *sed = user_data;
+ GAtResultIter iter;
+ int hf_indicator;
+ int enabled;
+
+ if (!ok)
+ goto error;
+
+ g_at_result_iter_init(&iter, result);
+
+ while (g_at_result_iter_next(&iter, "+BIND:")) {
+ if (!g_at_result_iter_next_number(&iter, &hf_indicator))
+ goto error;
+
+ if (!g_at_result_iter_next_number(&iter, &enabled))
+ goto error;
+
+ ofono_info("AG wants indicator %d %s",
+ hf_indicator, enabled ? "enabled" : "disabled");
+ }
+
+ slc_established(sed);
+ return;
+
+error:
+ slc_failed(sed);
+}
+
+static void bind_support_cb(gboolean ok, GAtResult *result, gpointer user_data)
+{
+ struct slc_establish_data *sed = user_data;
+ struct hfp_slc_info *info = sed->info;
+ GAtResultIter iter;
+ int hf_indicator;
+
+ if (!ok)
+ goto error;
+
+ g_at_result_iter_init(&iter, result);
+
+ if (!g_at_result_iter_next(&iter, "+BIND:"))
+ goto error;
+
+ if (!g_at_result_iter_open_list(&iter))
+ goto error;
+
+ while (g_at_result_iter_next_number(&iter, &hf_indicator)) {
+ ofono_info("AG supports the following indicator: %d",
+ hf_indicator);
+
+ if (hf_indicator == HFP_HF_INDICATOR_ENHANCED_SAFETY)
+ ofono_info("Distracted Driving Reduction");
+ }
+
+ if (!g_at_result_iter_close_list(&iter))
+ goto error;
+
+ slc_establish_data_ref(sed);
+ g_at_chat_send(info->chat, "AT+BIND?", bind_prefix,
+ bind_query_cb, sed, slc_establish_data_unref);
+
+ return;
+
+error:
+ slc_failed(sed);
+}
+
+static void bind_set_cb(gboolean ok, GAtResult *result, gpointer user_data)
+{
+ struct slc_establish_data *sed = user_data;
+ struct hfp_slc_info *info = sed->info;
+
+ if (!ok) {
+ slc_failed(sed);
+ return;
+ }
+
+ slc_establish_data_ref(sed);
+ g_at_chat_send(info->chat, "AT+BIND=?", bind_prefix,
+ bind_support_cb, sed, slc_establish_data_unref);
+}
+
static void chld_cb(gboolean ok, GAtResult *result, gpointer user_data)
{
struct slc_establish_data *sed = user_data;
@@ -148,7 +234,14 @@ static void chld_cb(gboolean ok, GAtResult *result, gpointer user_data)
info->ag_mpty_features = ag_mpty_feature;
- slc_established(sed);
+ if (info->ag_features & HFP_AG_FEATURE_HF_INDICATORS &&
+ info->hf_features & HFP_HF_FEATURE_HF_INDICATORS) {
+ slc_establish_data_ref(sed);
+ g_at_chat_send(info->chat, "AT+BIND=1", none_prefix,
+ bind_set_cb, sed, slc_establish_data_unref);
+ } else
+ slc_established(sed);
+
return;
error: