Bluetooth-SWB: SWB feature support.
Add support for Super Wide Band which
enhances current voice quality with
HD-Voice.
Change-Id: Iad9c5bd731a682edf7e837b51e243cb153b4398d
diff --git a/packages_apps_bluetooth_ext/jni/Android.bp b/packages_apps_bluetooth_ext/jni/Android.bp
index 66c59ac..cb15b77 100644
--- a/packages_apps_bluetooth_ext/jni/Android.bp
+++ b/packages_apps_bluetooth_ext/jni/Android.bp
@@ -25,6 +25,7 @@
"com_android_bluetooth_btservice_vendor_socket.cpp",
"com_android_bluetooth_avrcp_ext.cpp",
"com_android_bluetooth_ba.cpp",
+ "com_android_bluetooth_hf_vendor.cpp",
],
sanitize: {
never: true,
diff --git a/packages_apps_bluetooth_ext/jni/com_android_bluetooth_hf_vendor.cpp b/packages_apps_bluetooth_ext/jni/com_android_bluetooth_hf_vendor.cpp
new file mode 100644
index 0000000..f11d4cd
--- /dev/null
+++ b/packages_apps_bluetooth_ext/jni/com_android_bluetooth_hf_vendor.cpp
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2019, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define LOG_TAG "BluetoothVendorHfJni"
+
+#include "com_android_bluetooth.h"
+#include <hardware/vendor_hf.h>
+#include "utils/Log.h"
+#include "android_runtime/AndroidRuntime.h"
+
+namespace android {
+static btvendor_hf_interface_t *sBluetoothVendorHfInterface = NULL;
+static jobject mCallbacksObj = NULL;
+static jmethodID method_onSWB;
+
+static jbyteArray marshall_bda(RawAddress* bd_addr) {
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return nullptr;
+
+ jbyteArray addr = sCallbackEnv->NewByteArray(sizeof(RawAddress));
+ if (!addr) {
+ ALOGE("Fail to new jbyteArray bd addr");
+ return nullptr;
+ }
+ sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(RawAddress),
+ (jbyte*)bd_addr);
+ return addr;
+}
+
+static void SwbCallback(uint16_t swb_config, RawAddress* bd_addr) {
+
+ ALOGI("%s", __FUNCTION__);
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
+
+ ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
+ if (addr.get() == nullptr) return;
+ sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onSWB, swb_config,
+ addr.get());
+}
+
+static btvendor_hf_callbacks_t sBluetoothVendorHfCallbacks = {
+ sizeof(sBluetoothVendorHfCallbacks),
+ SwbCallback,
+};
+
+static void classInitNative(JNIEnv* env, jclass clazz) {
+
+ method_onSWB = env->GetMethodID(clazz, "onSWB", "(I[B)V");
+ ALOGI("%s: succeeds", __FUNCTION__);
+}
+
+static void initNative(JNIEnv *env, jobject object) {
+ const bt_interface_t* btInf;
+ bt_status_t status;
+
+ if ( (btInf = getBluetoothInterface()) == NULL) {
+ ALOGE("Bluetooth module is not loaded");
+ return;
+ }
+
+ if (mCallbacksObj != NULL) {
+ ALOGW("Cleaning up Bluetooth Vendor callback object");
+ env->DeleteGlobalRef(mCallbacksObj);
+ mCallbacksObj = NULL;
+ }
+
+ if ( (sBluetoothVendorHfInterface = (btvendor_hf_interface_t *)
+ btInf->get_profile_interface(BT_PROFILE_VENDOR_HF_ID)) == NULL) {
+ ALOGE("Failed to get Bluetooth Vendor Interface");
+ return;
+ }
+
+ if ( (status = sBluetoothVendorHfInterface->init(&sBluetoothVendorHfCallbacks))
+ != BT_STATUS_SUCCESS) {
+ ALOGE("Failed to initialize Bluetooth Vendor, status: %d", status);
+ sBluetoothVendorHfInterface = NULL;
+ return;
+ }
+ mCallbacksObj = env->NewGlobalRef(object);
+}
+
+static void cleanupNative(JNIEnv *env, jobject object) {
+ const bt_interface_t* btInf;
+
+ if ( (btInf = getBluetoothInterface()) == NULL) {
+ ALOGE("Bluetooth module is not loaded");
+ return;
+ }
+
+ if (sBluetoothVendorHfInterface !=NULL) {
+ ALOGW("Cleaning up Bluetooth Vendor Interface...");
+ sBluetoothVendorHfInterface->cleanup();
+ sBluetoothVendorHfInterface = NULL;
+ }
+
+ if (mCallbacksObj != NULL) {
+ ALOGW("Cleaning up Bluetooth Vendor callback object");
+ env->DeleteGlobalRef(mCallbacksObj);
+ mCallbacksObj = NULL;
+ }
+
+}
+
+/* native interface */
+static jint enableSwbNative(JNIEnv* env, jobject thiz, jboolean enable)
+{
+ if (sBluetoothVendorHfInterface == NULL) {
+ ALOGE("No Interface initialized");
+ return JNI_FALSE;
+ }
+
+ int ret = sBluetoothVendorHfInterface->enable_swb(enable);
+
+ if (ret != 0) {
+ ALOGE("%s: Failure", __func__);
+ return JNI_FALSE;
+ } else {
+ ALOGV("%s: Success :%d", __func__, enable);
+ }
+
+ return JNI_TRUE;
+}
+
+static JNINativeMethod sMethods[] = {
+ {"classInitNative", "()V", (void *) classInitNative},
+ {"initNative", "()V", (void *) initNative},
+ {"cleanupNative", "()V", (void *) cleanupNative},
+ { "enableSwbNative", "(Z)I", (void*)enableSwbNative},
+};
+
+int register_com_android_bluetooth_hfp_vendorhfservice(JNIEnv* env)
+{
+ ALOGE("%s:",__FUNCTION__);
+ return jniRegisterNativeMethods(env, "com/android/bluetooth/hfp/vendorhfservice",
+ sMethods, NELEM(sMethods));
+}
+
+} /* namespace android */
diff --git a/packages_apps_bluetooth_ext/src/hfp/vendorhfservice.java b/packages_apps_bluetooth_ext/src/hfp/vendorhfservice.java
new file mode 100644
index 0000000..e34999a
--- /dev/null
+++ b/packages_apps_bluetooth_ext/src/hfp/vendorhfservice.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2019, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.android.bluetooth.hfp;
+
+import android.util.Log;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import com.android.bluetooth.Utils;
+import android.content.Intent;
+import android.content.Context;
+
+final class vendorhfservice {
+ private static final String TAG = "BluetoothVendorHfService";
+ private HeadsetService mService;
+ private final BluetoothAdapter mAdapter = BluetoothAdapter.getDefaultAdapter();
+
+ static {
+ classInitNative();
+ }
+
+ public vendorhfservice(HeadsetService service) {
+ mService = service;
+ }
+
+ public void init(){
+ initNative();
+ }
+
+ public void cleanup() {
+ cleanupNative();
+ }
+
+ public int enableSwb(boolean enable) {
+ int ret = enableSwbNative(enable);
+ return ret;
+ }
+
+ private BluetoothDevice getDevice(byte[] address) {
+ BluetoothDevice local = mAdapter.getRemoteDevice(Utils.getAddressStringFromByte(address));
+ return local;
+ }
+
+ private void onSWB(int codec, byte[] address) {
+ /*HeadsetStackEvent event =
+ new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_SWB, codec, getDevice(address));
+ sendMessageToService(event);*/
+ }
+
+ private void sendMessageToService(HeadsetStackEvent event) {
+ HeadsetService service = HeadsetService.getHeadsetService();
+ if (service != null) {
+ service.messageFromNative(event);
+ } else {
+ Log.d(TAG,"FATAL: Stack sent event while service is not available: " + event);
+ }
+ }
+
+ private native void initNative();
+ private native static void classInitNative();
+ private native void cleanupNative();
+ private native int enableSwbNative(boolean enable);
+}
diff --git a/system_bt_ext/bta/Android.bp b/system_bt_ext/bta/Android.bp
index 8907668..b87a3ac 100644
--- a/system_bt_ext/bta/Android.bp
+++ b/system_bt_ext/bta/Android.bp
@@ -28,6 +28,7 @@
"ba/bta_ba.cc",
"tws_plus/ag/bta_ag_twsp_dev.cc",
"tws_plus/ag/bta_ag_twsp_sco.cc",
+ "swb/bta_ag_swb.cc"
],
shared_libs: [
"libcutils",
diff --git a/system_bt_ext/bta/include/bta_ag_swb.h b/system_bt_ext/bta/include/bta_ag_swb.h
new file mode 100644
index 0000000..95b77ca
--- /dev/null
+++ b/system_bt_ext/bta/include/bta_ag_swb.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2019, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _BTA_AG_SWB_H_
+#define _BTA_AG_SWB_H_
+
+#include "bta_ag_int.h"
+
+#define BTA_AG_SCO_SWB_SETTINGS_Q0_MASK 4
+#define BTA_AG_SCO_SWB_SETTINGS_Q1_MASK 8
+#define BTA_AG_SCO_SWB_SETTINGS_Q2_MASK 16
+#define BTA_AG_SCO_SWB_SETTINGS_Q3_MASK 32
+
+/* Events originated from HF side */
+#define BTA_AG_AT_QAC_EVT 253
+#define BTA_AG_AT_QCS_EVT 254
+#define BTA_AG_SWB_EVT 100 /* SWB SCO codec info */
+#define BTA_AG_LOCAL_RES_QAC 0x108
+#define BTA_AG_LOCAL_RES_QCS 0x109
+
+void bta_ag_swb_handle_vs_at_events(tBTA_AG_SCB* p_scb, uint16_t cmd, int16_t int_arg, tBTA_AG_VAL val);
+void bta_ag_send_qac(tBTA_AG_SCB* p_scb, tBTA_AG_DATA* p_data);
+void bta_ag_send_qcs(tBTA_AG_SCB* p_scb, tBTA_AG_DATA* p_data);
+tBTA_AG_PEER_CODEC bta_ag_parse_qac(tBTA_AG_SCB* p_scb, char* p_s);
+
+#endif//_BTA_AG_SWB_H_
diff --git a/system_bt_ext/bta/swb/bta_ag_swb.cc b/system_bt_ext/bta/swb/bta_ag_swb.cc
new file mode 100644
index 0000000..ead0572
--- /dev/null
+++ b/system_bt_ext/bta/swb/bta_ag_swb.cc
@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 2019, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <unistd.h>
+#include "bta_ag_swb.h"
+#include "internal_include/bt_trace.h"
+#include "bta_ag_int.h"
+#include "utl.h"
+#include "device/include/interop.h"
+
+#if (SWB_ENABLED == TRUE)
+
+void bta_ag_swb_handle_vs_at_events(tBTA_AG_SCB* p_scb, uint16_t cmd, int16_t int_arg, tBTA_AG_VAL val)
+{
+ APPL_TRACE_DEBUG("%s: p_scb : %x cmd : %d", __func__, p_scb, cmd);
+ switch(cmd) {
+ case BTA_AG_AT_QAC_EVT:
+ p_scb->codec_updated = true;
+ if (p_scb->peer_codecs & BTA_AG_SCO_SWB_SETTINGS_Q0_MASK) {
+ p_scb->sco_codec = BTA_AG_SCO_SWB_SETTINGS_Q0;
+ } else if (p_scb->peer_codecs & BTA_AG_CODEC_MSBC) {
+ p_scb->sco_codec = UUID_CODEC_MSBC;
+ }
+ bta_ag_send_qac(p_scb, NULL);
+ APPL_TRACE_DEBUG("Received AT+QAC, updating sco codec to SWB: %d", p_scb->sco_codec);
+ val.num = p_scb->peer_codecs;
+ break;
+ case BTA_AG_AT_QCS_EVT: {
+ tBTA_AG_PEER_CODEC codec_type, codec_sent;
+ alarm_cancel(p_scb->codec_negotiation_timer);
+
+ switch (int_arg) {
+ case BTA_AG_SCO_SWB_SETTINGS_Q0:
+ codec_type = BTA_AG_SCO_SWB_SETTINGS_Q0;
+ break;
+ case BTA_AG_SCO_SWB_SETTINGS_Q1:
+ codec_type = BTA_AG_SCO_SWB_SETTINGS_Q1;
+ break;
+ case BTA_AG_SCO_SWB_SETTINGS_Q2:
+ codec_type = BTA_AG_SCO_SWB_SETTINGS_Q2;
+ break;
+ case BTA_AG_SCO_SWB_SETTINGS_Q3:
+ codec_type = BTA_AG_SCO_SWB_SETTINGS_Q3;
+ break;
+ default:
+ APPL_TRACE_ERROR("Unknown codec_uuid %d", int_arg);
+ p_scb->is_swb_codec = false;
+ codec_type = BTA_AG_CODEC_MSBC;
+ p_scb->codec_fallback = true;
+ p_scb->sco_codec = BTA_AG_CODEC_MSBC;
+ break;
+ }
+
+ if (p_scb->codec_fallback)
+ codec_sent = BTA_AG_CODEC_MSBC;
+ else
+ codec_sent = p_scb->sco_codec;
+
+ if (codec_type == codec_sent)
+ bta_ag_sco_codec_nego(p_scb, true);
+ else
+ bta_ag_sco_codec_nego(p_scb, false);
+
+ /* send final codec info to callback */
+ val.num = codec_sent;
+ break;
+ }
+ }
+}
+
+/*******************************************************************************
+ *
+ * Function bta_ag_send_qcs
+ *
+ * Description Send +%QCS AT command to peer.
+ *
+ * Returns void
+ *
+ ******************************************************************************/
+void bta_ag_send_qcs(tBTA_AG_SCB* p_scb, tBTA_AG_DATA* p_data) {
+ uint16_t codec_uuid;
+ if (p_scb->codec_fallback) {
+ if (p_scb->peer_codecs & BTA_AG_CODEC_MSBC) {
+ codec_uuid = UUID_CODEC_MSBC;
+ } else {
+ codec_uuid = UUID_CODEC_CVSD;
+ }
+ } else {
+ codec_uuid = BTA_AG_SCO_SWB_SETTINGS_Q0;
+ }
+
+ /* send +BCS */
+ APPL_TRACE_DEBUG("send +QCS codec is %d", codec_uuid);
+ bta_ag_send_result(p_scb, BTA_AG_LOCAL_RES_QCS, NULL, codec_uuid);
+}
+
+/*******************************************************************************
+ *
+ * Function bta_ag_send_qac
+ *
+ * Description Send +%QAC AT command to peer.
+ *
+ * Returns void
+ *
+ ******************************************************************************/
+void bta_ag_send_qac(tBTA_AG_SCB* p_scb, tBTA_AG_DATA* p_data) {
+ /* send +BCS */
+ APPL_TRACE_DEBUG("send +QAC codecs suuported");
+ bta_ag_send_result(p_scb, BTA_AG_LOCAL_RES_QAC, "0,4,6,7", 0);
+ if (p_scb->sco_codec == BTA_AG_SCO_SWB_SETTINGS_Q0) {
+ p_scb->is_swb_codec = true;
+ }
+}
+
+tBTA_AG_PEER_CODEC bta_ag_parse_qac(tBTA_AG_SCB* p_scb, char* p_s) {
+ tBTA_AG_PEER_CODEC retval = BTA_AG_CODEC_NONE;
+ uint16_t codec_modes;
+ bool cont = false; /* Continue processing */
+ char* p;
+
+ while (p_s) {
+ /* skip to comma delimiter */
+ for (p = p_s; *p != ',' && *p != 0; p++)
+ ;
+
+ /* get integre value */
+ if (*p != 0) {
+ *p = 0;
+ cont = true;
+ } else
+ cont = false;
+
+ codec_modes = utl_str2int(p_s);
+ switch (codec_modes) {
+ case BTA_AG_SCO_SWB_SETTINGS_Q0:
+ retval |= BTA_AG_SCO_SWB_SETTINGS_Q0_MASK;
+ break;
+ case BTA_AG_SCO_SWB_SETTINGS_Q1:
+ retval |= BTA_AG_SCO_SWB_SETTINGS_Q1_MASK;
+ break;
+ case BTA_AG_SCO_SWB_SETTINGS_Q2:
+ retval |= BTA_AG_SCO_SWB_SETTINGS_Q2_MASK;
+ break;
+ case BTA_AG_SCO_SWB_SETTINGS_Q3:
+ retval |= BTA_AG_SCO_SWB_SETTINGS_Q3_MASK;
+ break;
+ default:
+ APPL_TRACE_ERROR("Unknown Codec UUID(%d) received", codec_modes);
+ break;
+ }
+
+ if (cont)
+ p_s = p + 1;
+ else
+ break;
+ }
+
+ return (retval);
+}
+#endif //#if (SWB_ENABLED == TRUE)
+
diff --git a/system_bt_ext/btif/Android.bp b/system_bt_ext/btif/Android.bp
index f6fbc99..59cfaf2 100644
--- a/system_bt_ext/btif/Android.bp
+++ b/system_bt_ext/btif/Android.bp
@@ -34,6 +34,7 @@
"src/btif_ba.cc",
"src/btif_twsp_hf.cc",
"src/btif_iot_config.cc",
+ "src/btif_vendor_hf.cc",
],
shared_libs: [
"libcutils",
diff --git a/system_bt_ext/btif/src/btif_vendor_hf.cc b/system_bt_ext/btif/src/btif_vendor_hf.cc
new file mode 100644
index 0000000..dc4895e
--- /dev/null
+++ b/system_bt_ext/btif/src/btif_vendor_hf.cc
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2019, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ ***********************************************************************/
+
+/************************************************************************************
+ *
+ * Filename: btif_vendor_hf.cc
+ *
+ * Description: Vendor Bluetooth Interface
+ *
+ *
+ ***********************************************************************************/
+
+#define LOG_TAG "bt_btif_vendor_hf"
+
+#include <hardware/vendor_hf.h>
+#include "btif_api.h"
+
+btvendor_hf_callbacks_t *bt_vendor_hf_callbacks = NULL;
+static bool swb_codec_status = false;
+
+/*******************************************************************************
+** VENDOR INTERFACE FUNCTIONS
+*******************************************************************************/
+
+/*******************************************************************************
+**
+** Function init
+**
+** Description initializes the vendor interface for HF
+**
+** Returns bt_status_t
+**
+*******************************************************************************/
+
+static bt_status_t init( btvendor_hf_callbacks_t* callbacks)
+{
+ bt_vendor_hf_callbacks = callbacks;
+ LOG_INFO(LOG_TAG,"init done");
+ return BT_STATUS_SUCCESS;
+}
+
+static void cleanup(void)
+{
+ LOG_INFO(LOG_TAG,"cleanup");
+ if (bt_vendor_hf_callbacks)
+ bt_vendor_hf_callbacks = NULL;
+}
+
+int enable_swb(bool enable) {
+ LOG_INFO(LOG_TAG,"%s: %d", __func__, enable);
+ swb_codec_status = enable;
+ return 0;
+}
+
+static const btvendor_hf_interface_t btvendorhfInterface = {
+ sizeof(btvendorhfInterface),
+ init,
+ cleanup,
+ enable_swb,
+};
+
+void btif_handle_vendor_hf_events(uint16_t event, uint16_t swb_config, RawAddress *bd_addr) {
+ HAL_CBACK(bt_vendor_hf_callbacks, swb_codec_cb, swb_config, bd_addr);
+}
+
+bool get_swb_codec_status() {
+ return swb_codec_status;
+}
+
+/*******************************************************************************
+**
+** Function btif_vendor_hf_get_interface
+**
+** Description Get the vendor callback interface
+**
+** Returns btvendor_hf_interface_t
+**
+*******************************************************************************/
+const btvendor_hf_interface_t *btif_vendor_hf_get_interface()
+{
+ BTIF_TRACE_EVENT("%s", __FUNCTION__);
+ return &btvendorhfInterface;
+}
+
diff --git a/vhal/include/hardware/vendor_hf.h b/vhal/include/hardware/vendor_hf.h
new file mode 100644
index 0000000..6399de6
--- /dev/null
+++ b/vhal/include/hardware/vendor_hf.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2019, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ANDROID_INCLUDE_BT_HF_VENDOR_H
+#define ANDROID_INCLUDE_BT_HF_VENDOR_H
+
+#include <hardware/bluetooth.h>
+
+__BEGIN_DECLS
+
+#define BT_PROFILE_VENDOR_HF_ID "vendorhfservice"
+
+void btif_handle_vendor_hf_events(uint16_t event, uint16_t swb_config, RawAddress *bd_addr);
+
+/* SWB callback events */
+typedef void (* bt_swb_update_callback)(uint16_t swb_codec_config, RawAddress *bd_addr);
+
+/** BT-Vendor hf callback structure. */
+typedef struct {
+ /** set to sizeof(BtVendorhfCallbacks) */
+ size_t size;
+ bt_swb_update_callback swb_codec_cb;
+} btvendor_hf_callbacks_t;
+
+
+/** Represents the standard BT-Vendor hf interface.
+ */
+typedef struct {
+ /** set to sizeof(BtVendorHfInterface) */
+ size_t size;
+
+ /**
+ * Register the BtVendorhf callbacks
+ */
+ bt_status_t (*init)( btvendor_hf_callbacks_t* callbacks );
+
+ /** Closes the interface. */
+ void (*cleanup)( void );
+
+ int (*enable_swb) (bool enable);
+} btvendor_hf_interface_t;
+
+__END_DECLS
+#endif /* ANDROID_INCLUDE_BT_VENDOR_H */
+