handsfree-audio: Detect transparent SCO in kernel
authorVinicius Costa Gomes <vcgomes@gmail.com>
Wed, 11 Sep 2013 00:09:41 +0000 (21:09 -0300)
committerDenis Kenzior <denkenz@gmail.com>
Thu, 12 Sep 2013 18:17:40 +0000 (13:17 -0500)
Deferred SCO setup is not enough for HFP 1.6 wideband codec support.
Wideband speech also requires Transparent SCO to be enabled in the
kernel.

include/handsfree-audio.h
plugins/hfp_hf_bluez5.c
src/handsfree-audio.c

index 846a032..03e3b38 100644 (file)
@@ -53,7 +53,7 @@ ofono_bool_t ofono_handsfree_card_set_codec(struct ofono_handsfree_card *card,
 
 ofono_bool_t ofono_handsfree_audio_has_wideband(void);
 
-ofono_bool_t ofono_handsfree_audio_has_defer_setup(void);
+ofono_bool_t ofono_handsfree_audio_has_transparent_sco(void);
 
 void ofono_handsfree_card_set_data(struct ofono_handsfree_card *card,
                                        void *data);
index 9f402f7..74c6495 100644 (file)
@@ -632,7 +632,7 @@ static void connect_handler(DBusConnection *conn, void *user_data)
         * Assuming that if defer_setup is supported, then SCO transparent
         * mode is also supported
        */
-       if (ofono_handsfree_audio_has_defer_setup())
+       if (ofono_handsfree_audio_has_transparent_sco())
                features |= HFP_SDP_HF_FEATURE_WIDEBAND_SPEECH;
 
        DBG("Registering External Profile handler ...");
index adb8f73..9604191 100644 (file)
@@ -67,6 +67,7 @@ static guint sco_watch = 0;
 static GSList *drivers = 0;
 static ofono_bool_t has_wideband = FALSE;
 static int defer_setup = 1;
+static ofono_bool_t transparent_sco = FALSE;
 
 static uint16_t codec2setting(uint8_t codec)
 {
@@ -192,7 +193,9 @@ static int sco_init(void)
 {
        GIOChannel *sco_io;
        struct sockaddr_sco saddr;
+       struct bt_voice voice;
        int sk;
+       socklen_t len;
 
        sk = socket(PF_BLUETOOTH, SOCK_SEQPACKET | O_NONBLOCK | SOCK_CLOEXEC,
                                                                BTPROTO_SCO);
@@ -216,6 +219,13 @@ static int sco_init(void)
                                                strerror(errno), errno);
        }
 
+       memset(&voice, 0, sizeof(voice));
+       len = sizeof(voice);
+
+       if (defer_setup && getsockopt(sk, SOL_BLUETOOTH, BT_VOICE,
+                                               &voice, &len) == 0)
+               transparent_sco = TRUE;
+
        if (listen(sk, 5) < 0) {
                close(sk);
                return -errno;
@@ -599,9 +609,9 @@ ofono_bool_t ofono_handsfree_audio_has_wideband(void)
        return has_wideband;
 }
 
-ofono_bool_t ofono_handsfree_audio_has_defer_setup(void)
+ofono_bool_t ofono_handsfree_audio_has_transparent_sco(void)
 {
-       return defer_setup == 1;
+       return transparent_sco;
 }
 
 static void agent_free(struct agent *agent)
@@ -721,12 +731,12 @@ static DBusMessage *am_agent_register(DBusConnection *conn,
        DBG("Agent %s registered with the CODECs:%s%s", sender,
                has_cvsd ? " CVSD" : "", has_msbc ? " mSBC" : "");
 
-       if (has_msbc && defer_setup == 1)
+       if (has_msbc && transparent_sco)
                has_wideband = TRUE;
        else {
                has_wideband = FALSE;
                DBG("Wideband speech disabled: %s", has_msbc ?
-                       "no SCO defer setup support" : "no mSBC support");
+                       "no Transparent SCO support" : "no mSBC support");
        }
 
        if (has_cvsd == FALSE) {