From: Vinicius Costa Gomes <[email protected]>

This patch adds a function to monitor when the AG sends a new codec
before establishing the SCO connection.
---
 drivers/hfpmodem/slc.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++
 drivers/hfpmodem/slc.h |  4 +++
 2 files changed, 72 insertions(+)

diff --git a/drivers/hfpmodem/slc.c b/drivers/hfpmodem/slc.c
index b9b687b..905be68 100644
--- a/drivers/hfpmodem/slc.c
+++ b/drivers/hfpmodem/slc.c
@@ -53,6 +53,12 @@ struct slc_establish_data {
        gpointer userdata;
 };
 
+struct codec_watch {
+       struct hfp_slc_info *slc;
+       hfp_slc_codec_watch_cb_t cb;
+       gpointer user_data;
+};
+
 void hfp_slc_info_init(struct hfp_slc_info *info, guint16 version)
 {
        info->ag_features = 0;
@@ -355,3 +361,65 @@ void hfp_slc_establish(struct hfp_slc_info *info, 
hfp_slc_cb_t connect_cb,
        g_at_chat_send(info->chat, buf, brsf_prefix,
                                brsf_cb, sed, slc_establish_data_unref);
 }
+
+static void bcs_notify(GAtResult *result, gpointer user_data)
+{
+       struct codec_watch *watch = user_data;
+       struct hfp_slc_info *info = watch->slc;
+       unsigned char codecs[8];
+       GAtResultIter iter;
+       GString *str;
+       int i, value, len;
+
+
+       g_at_result_iter_init(&iter, result);
+
+       if (!g_at_result_iter_next(&iter, "+BCS:"))
+               return;
+
+       if (!g_at_result_iter_next_number(&iter, &value))
+               return;
+
+       /* If some codec matches, we confirm it */
+
+       len = ofono_handsfree_get_codecs(codecs, sizeof(codecs));
+       if (len < 0)
+               return;
+
+       for (i = 0; i < len; i++) {
+               if (codecs[i] == value) {
+
+                       DBG("Negotiated HFP codec: %d", value);
+                       watch->cb(value, watch->user_data);
+
+                       str = g_string_new("AT+BCS=");
+                       g_string_append_printf(str, "%d", value);
+                       goto done;
+               }
+       }
+
+       /* If none matches, we send our supported codecs again */
+       str = g_string_new("AT+BAC=");
+
+       for (i = 0; i < (len - 1); i++)
+               g_string_append_printf(str, "%d,", codecs[i]);
+
+       g_string_append_printf(str, "%d", codecs[i]);
+
+done:
+       g_at_chat_send(info->chat, str->str, NULL, NULL, NULL, NULL);
+       g_string_free(str, TRUE);
+}
+
+guint hfp_slc_codec_watch_register(struct hfp_slc_info *info,
+                               hfp_slc_codec_watch_cb_t cb, void *user_data)
+{
+       struct codec_watch *watch = g_new0(struct codec_watch, 1);
+
+       watch->slc = info;
+       watch->cb = cb;
+       watch->user_data = user_data;
+
+       return g_at_chat_register(info->chat, "+BCS:", bcs_notify, FALSE,
+                                                               watch, g_free);
+}
diff --git a/drivers/hfpmodem/slc.h b/drivers/hfpmodem/slc.h
index b71ffe9..95539c8 100644
--- a/drivers/hfpmodem/slc.h
+++ b/drivers/hfpmodem/slc.h
@@ -45,6 +45,7 @@ enum hfp_indicator {
 };
 
 typedef void (*hfp_slc_cb_t)(void *userdata);
+typedef void (*hfp_slc_codec_watch_cb_t)(unsigned char codec, void *userdata);
 
 struct hfp_slc_info {
        GAtChat *chat;
@@ -60,3 +61,6 @@ void hfp_slc_info_free(struct hfp_slc_info *info);
 
 void hfp_slc_establish(struct hfp_slc_info *info, hfp_slc_cb_t connect_cb,
                                hfp_slc_cb_t failed_cb, void *userdata);
+
+guint hfp_slc_codec_watch_register(struct hfp_slc_info *info,
+                               hfp_slc_codec_watch_cb_t cb, void *user_data);
-- 
1.7.11.7

_______________________________________________
ofono mailing list
[email protected]
http://lists.ofono.org/listinfo/ofono

Reply via email to