From 0102bc389bf53c0c7c6faa637a5a1f26a2f020b4 Mon Sep 17 00:00:00 2001 From: Scott Murray Date: Mon, 13 Sep 2021 18:13:42 -0400 Subject: Rework adapter detection logic 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 Change-Id: I1da5c2e3168acd0f8f55dc75c2408647d03c0a4e (cherry picked from commit c301f67772c2a2c643dd47b2291f0c971f8006ce) --- binding/bluetooth-api.c | 56 ++++++++++++++++++++++++++++++------------------- 1 file 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"); -- cgit 1.2.3-korg