summaryrefslogtreecommitdiffstats
path: root/binding/bluetooth-api.c
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 /binding/bluetooth-api.c
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
Diffstat (limited to 'binding/bluetooth-api.c')
-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");