Bluetooth: load btaddr from NV if QCOM_BT_USE_BTNV is set
- OSS builds never set QCPATH, so we should instead use libdl
so devices that need to read btaddr from NV can still build
from source.
Change-Id: Ib38dc356c7a3458f57935d113e068e6637d4795f
diff --git a/libbt-vendor/Android.mk b/libbt-vendor/Android.mk
index 6ef6902..e3a9dfb 100644
--- a/libbt-vendor/Android.mk
+++ b/libbt-vendor/Android.mk
@@ -77,10 +77,15 @@
LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_SHARED_LIBRARIES)
endif
-ifneq ($(QCPATH),)
+ifeq ($(QCOM_BT_USE_BTNV),true)
LOCAL_CFLAGS += -DBT_NV_SUPPORT
+ifeq ($(QCPATH),)
+LOCAL_SHARED_LIBRARIES += libdl
+LOCAL_CFLAGS += -DBT_NV_SUPPORT_DL
+else
LOCAL_SHARED_LIBRARIES += libbtnv
endif
+endif
LOCAL_CFLAGS += -Wno-unused-variable
LOCAL_CFLAGS += -Wno-unused-label
diff --git a/libbt-vendor/src/bt_vendor_persist.cpp b/libbt-vendor/src/bt_vendor_persist.cpp
index 519e826..db895fd 100644
--- a/libbt-vendor/src/bt_vendor_persist.cpp
+++ b/libbt-vendor/src/bt_vendor_persist.cpp
@@ -27,7 +27,27 @@
#include "bt_vendor_persist.h"
#ifdef BT_NV_SUPPORT
+#ifdef BT_NV_SUPPORT_DL
+#include <dlfcn.h>
+// All figured out through investigation of this code...
+typedef struct {
+ unsigned char bd_addr[6];
+ // This is a bit dangerous, but this struct
+ // is unknown (however not used outside of this context)
+ unsigned char unknown[58];
+} nv_persist_item_type;
+typedef enum {
+ NV_SUCCESS = 0,
+} nv_persist_stat_enum_type;
+#define TRUE 1
+#define FALSE 0
+#define NV_BD_ADDR_I 1
+// ...except this, which was found through experimentation
+#define NV_READ_F 0
+#else
#include "bt_nv.h"
+#endif
+#define LOG_TAG "QCOM-BTNV"
#include <utils/Log.h>
/*===========================================================================
@@ -56,11 +76,28 @@
nv_persist_item_type my_nv_item;
nv_persist_stat_enum_type cmd_result;
boolean result = FALSE;
+#ifdef BT_NV_SUPPORT_DL
+ int (*bt_nv_cmd)(int, int, nv_persist_item_type *, int);
+ void *lib = dlopen("libbtnv.so", RTLD_NOW);
+
+ if (!lib) {
+ ALOGE("Failed to open libbtnv.so: %s", dlerror());
+ return FALSE;
+ }
+
+ bt_nv_cmd = (int (*)(int, int, nv_persist_item_type *, int))dlsym(lib, "bt_nv_cmd");
+ if (!bt_nv_cmd) {
+ ALOGE("Failed to find bt_nv_cmd: %s", dlerror());
+ dlclose(lib);
+ return FALSE;
+ }
+#endif
switch(nv_item)
{
case NV_BD_ADDR_I:
- cmd_result = (nv_persist_stat_enum_type)bt_nv_cmd(NV_READ_F, NV_BD_ADDR_I, &my_nv_item);
+ // A strange default parameter is used here. A debugger shows 4 parameters being passed.
+ cmd_result = (nv_persist_stat_enum_type)bt_nv_cmd(NV_READ_F, NV_BD_ADDR_I, &my_nv_item, 0);
ALOGI("CMD result: %d", cmd_result);
if (NV_SUCCESS != cmd_result)
{
@@ -86,6 +123,9 @@
}
break;
}
+#ifdef BT_NV_SUPPORT_DL
+ dlclose(lib);
+#endif
return result;
}
#endif /* End of BT_NV_SUPPORT */