summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorScott Murray <scott.murray@konsulko.com>2021-09-13 18:13:42 -0400
committerScott Murray <scott.murray@konsulko.com>2021-09-13 18:21:13 -0400
commitc301f67772c2a2c643dd47b2291f0c971f8006ce (patch)
treea3fd8eecbad86d26dd2fc3be44a4ab39a95bb4bc
parent495dbef34079fe860ba0c2cd83a07b086b5a2417 (diff)
Rework the adapter detection logic in the helper thread to use the initialization done signal to the main process to indicate that basic BlueZ D-Bus initialization has completed, then loop forever looking for an adapter as opposed to just trying once. This improves the behavior with hardware such as the TI Wilink chipset or the Broadcom chipset on Raspberry Pi 4, where the firmware loading delay may result in the HCI device not actually being available yet when the binding is started. Bug-AGL: SPEC-4060 Signed-off-by: Scott Murray <scott.murray@konsulko.com> Change-Id: I1da5c2e3168acd0f8f55dc75c2408647d03c0a4e
-rw-r--r--binding/bluetooth-api.c56
1 files changed, 35 insertions, 21 deletions
diff --git a/binding/bluetooth-api.c b/binding/bluetooth-api.c
index 2bcddd9..5022ba9 100644
--- a/binding/bluetooth-api.c
+++ b/binding/bluetooth-api.c
@@ -651,6 +651,8 @@ static gpointer bluetooth_func(gpointer ptr)
struct bluetooth_state *ns;
GMainLoop *loop;
int rc = 0;
+ unsigned int delay;
+ unsigned int attempt;
g_atomic_rc_box_acquire(id);
@@ -660,7 +662,7 @@ static gpointer bluetooth_func(gpointer ptr)
goto err_no_loop;
}
- /* real bluetooth init */
+ // Do BlueZ D-Bus related init
ns = bluetooth_init(loop);
if (!ns) {
AFB_ERROR("bluetooth_init() failed");
@@ -668,26 +670,38 @@ static gpointer bluetooth_func(gpointer ptr)
}
id->ns = ns;
- rc = bluetooth_select_init_adapter(id);
- if (rc > 0) {
- rc = bluetooth_register_agent(id);
- if (rc) {
- AFB_ERROR("bluetooth_register_agent() failed");
- goto err_no_service;
- }
- }
- else if (rc < 0) {
- goto err_no_service;
- }
- else {
- //fake it
- AFB_INFO("No adapter present, completed initialization");
- signal_init_done(id, 0);
+ rc = bluetooth_register_agent(id);
+ if (rc) {
+ AFB_ERROR("bluetooth_register_agent() failed");
+ goto err_no_agent;
}
- /* note that we wait for agent registration to signal done */
afb_api_set_userdata(id->api, ns);
- g_main_loop_run(loop);
+
+ // Let main process know initialization is done
+ signal_init_done(id, 0);
+
+ // Wait for an adapter to appear
+ rc = 0;
+ delay = 1;
+ attempt = 1;
+ while(rc <= 0) {
+ rc = bluetooth_select_init_adapter(id);
+ if (rc != 0)
+ break;
+
+ // Back off querying rate after the first 60 seconds
+ if (attempt++ == 60)
+ delay = 10;
+
+ sleep(delay);
+ }
+
+ if (rc > 0) {
+ g_main_loop_run(loop);
+ } else {
+ AFB_ERROR("bluetooth_select_init_adapter() failed");
+ }
g_main_loop_unref(ns->loop);
@@ -700,7 +714,7 @@ static gpointer bluetooth_func(gpointer ptr)
return NULL;
-err_no_service:
+err_no_agent:
bluetooth_cleanup(ns);
err_no_ns:
@@ -757,8 +771,8 @@ static int init(afb_api_t api)
afb_api_call_sync(api, "network-manager", "enable_technology", args, NULL, NULL, NULL);
global_thread = g_thread_new("agl-service-bluetooth",
- bluetooth_func,
- id);
+ bluetooth_func,
+ id);
AFB_INFO("bluetooth-binding waiting for init done");