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-15 12:00:09 +0000
commit0102bc389bf53c0c7c6faa637a5a1f26a2f020b4 (patch)
tree5cfc833ae538a15dd11dfdb2cf2643b07a2197ef
parentc80bb1626628b7d1eb10c1ac6f655ba8ed5c3f34 (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 (cherry picked from commit c301f67772c2a2c643dd47b2291f0c971f8006ce)
-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");