diff options
author | Matt Porter <mporter@konsulko.com> | 2018-05-10 12:41:35 -0400 |
---|---|---|
committer | Matt Porter <mporter@konsulko.com> | 2018-05-11 19:07:54 -0400 |
commit | 4e454de545544526cbea9d787df9ba76cb99d889 (patch) | |
tree | 23174d8ac18edf3b3d849b1747f5cf9810305814 | |
parent | 8256ad1306337dc343683f5479e1a08764f1111a (diff) |
telephony binding: support runtime change of BT HFP modem
The binding currently only queries for a BT HFP enabled modem
once at binding init time.
To support runtime modem changes, use BT binding events to
handle connection and disconnection of BT HFP devices. The
default voice call modem is now torn down on device disconnect
and initialized when a new BT HFP device is connected at runtime.
Bug-AGL: SPEC-1433
Change-Id: Icea7686ef5ecb80b0d33560e4499ca1fd6285147
Signed-off-by: Matt Porter <mporter@konsulko.com>
-rw-r--r-- | package/config.xml | 1 | ||||
-rw-r--r-- | telephony-binding/gdbus/ofono_manager.c | 28 | ||||
-rw-r--r-- | telephony-binding/telephony-binding.c | 142 |
3 files changed, 125 insertions, 46 deletions
diff --git a/package/config.xml b/package/config.xml index ac580f0..183aba1 100644 --- a/package/config.xml +++ b/package/config.xml @@ -10,6 +10,7 @@ <param name="windowmanager" value="ws" /> <param name="homescreen" value="ws" /> <param name="lib/libtelephony-binding.so" value="local" /> + <param name="Bluetooth-Manager" value="ws" /> </feature> <feature name="urn:AGL:widget:required-permission"> <param name="urn:AGL:permission::public:no-htdocs" value="required" /> diff --git a/telephony-binding/gdbus/ofono_manager.c b/telephony-binding/gdbus/ofono_manager.c index a77623d..98b0fdc 100644 --- a/telephony-binding/gdbus/ofono_manager.c +++ b/telephony-binding/gdbus/ofono_manager.c @@ -50,7 +50,6 @@ int ofono_manager_set_default_modem(const char *address) gchar *path, *key; const gchar *name = NULL, *type = NULL, *serial = NULL; gboolean powered = FALSE, online = FALSE; - GVariantIter *iter, *iter2 = NULL; int ret = 0; @@ -95,10 +94,6 @@ int ofono_manager_set_default_modem(const char *address) int ofono_manager_init() { - GVariant *out_arg = NULL, *next, *value; - GError *error = NULL; - GVariantIter *iter, *iter2 = NULL; - gchar *path, *key; int ret = 0; if (manager) { @@ -115,29 +110,6 @@ int ofono_manager_init() return -1; } - org_ofono_manager_call_get_modems_sync(manager, &out_arg, NULL, &error); - if (error == NULL) { - g_variant_get(out_arg, "a(oa{sv})", &iter); - next = g_variant_iter_next_value(iter); - if (next) { - g_variant_get(next, "(oa{sv})", &path, &iter2); - default_modem.path = path; - while (g_variant_iter_loop(iter2, "{sv}", &key, &value)) { - if (!strcmp(key, "Name")) - default_modem.name = g_variant_get_string(value, NULL); - else if (!strcmp(key, "Type")) - default_modem.type = g_variant_get_string(value, NULL); - else if (!strcmp(key, "Powered")) - default_modem.powered = g_variant_get_boolean(value); - else if (!strcmp(key, "Online")) - default_modem.online = g_variant_get_boolean(value); - } - } else { - ret = -1; - } - } else { - ret = -1; - } return ret; } diff --git a/telephony-binding/telephony-binding.c b/telephony-binding/telephony-binding.c index 6d8966c..3d0f06a 100644 --- a/telephony-binding/telephony-binding.c +++ b/telephony-binding/telephony-binding.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Konsulko Group + * Copyright (C) 2017-2018 Konsulko Group * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -178,6 +178,88 @@ static void *main_loop_thread(void *unused) return NULL; } +static int ofono_init_default_modem(void) +{ + int ret = 0; + const gchar *modem_path = ofono_manager_get_default_modem_path(); + + if (modem_path) { + vcm = ofono_voicecallmanager_init(modem_path, + incoming_call_cb, + dialing_call_cb, + terminated_call_cb); + if (!vcm) { + AFB_ERROR("failed to initialize voice call manager\n"); + ret = -1; + } + } else { + AFB_ERROR("default modem not set\n"); + ret = -1; + } + + return ret; +} + +static gboolean is_hfp_dev_and_init(struct json_object *dev) +{ + int ret; + gboolean hfp = FALSE; + struct json_object *name, *address, *hfp_connected; + json_object_object_get_ex(dev, "Name", &name); + json_object_object_get_ex(dev, "Address", &address); + json_object_object_get_ex(dev, "HFPConnected", &hfp_connected); + if (!strcmp(json_object_get_string(hfp_connected), "True")) { + ret = ofono_manager_set_default_modem(json_object_get_string(address)); + if (ret == 0) { + ofono_init_default_modem(); + hfp = TRUE; + } + } + + return hfp; +} + +static void discovery_result_cb(void *closure, int status, struct json_object *result) +{ + enum json_type type; + struct json_object *devs, *dev; + int i; + + json_object_object_foreach(result, key, val) { + type = json_object_get_type(val); + switch (type) { + case json_type_array: + json_object_object_get_ex(result, key, &devs); + for (i = 0; i < json_object_array_length(devs); i++) { + dev = json_object_array_get_idx(devs, i); + if (is_hfp_dev_and_init(dev)) + break; + } + break; + case json_type_string: + case json_type_boolean: + case json_type_double: + case json_type_int: + case json_type_object: + case json_type_null: + default: + break; + } + } +} + +static void ofono_hfp_init(void) +{ + struct json_object *args, *response; + + args = json_object_new_object(); + json_object_object_add(args , "value", json_object_new_string("connection")); + afb_service_call_sync("Bluetooth-Manager", "subscribe", args, &response); + + args = json_object_new_object(); + afb_service_call("Bluetooth-Manager", "discovery_result", args, discovery_result_cb, &response); +} + static int ofono_init(void) { pthread_t tid; @@ -188,29 +270,21 @@ static int ofono_init(void) incoming_call_event = afb_daemon_make_event("incomingCall"); terminated_call_event = afb_daemon_make_event("terminatedCall"); + ret = afb_daemon_require_api("Bluetooth-Manager", 1); + if (ret) { + AFB_ERROR("unable to initialize bluetooth binding"); + return -1; + } + /* Start the main loop thread */ pthread_create(&tid, NULL, main_loop_thread, NULL); ret = ofono_manager_init(); if (ret == 0) { - const gchar *modem_path = ofono_manager_get_default_modem_path(); - if (modem_path) { - AFB_DEBUG("modem_path: %s\n", modem_path); - vcm = ofono_voicecallmanager_init(modem_path, - incoming_call_cb, - dialing_call_cb, - terminated_call_cb); - if (!vcm) { - AFB_ERROR("failed to initialize voice call manager\n"); - ret = -1; - } - } else { - AFB_ERROR("default modem not set\n"); - ret = -1; - } + ofono_manager_invalidate_default_modem(); + ofono_hfp_init(); } else { - AFB_ERROR("failed to initialize ofono manager: " \ - "HFP device not connected or Bluetooth disabled\n"); + AFB_ERROR("failed to initialize ofono manager"); } return ret; @@ -257,9 +331,41 @@ static int init() return ofono_init(); } +static void process_connection_event(struct json_object *object) +{ + struct json_object *args, *response, *status_obj, *address_obj; + const char *status, *address; + + json_object_object_get_ex(object, "Status", &status_obj); + status = json_object_get_string(status_obj); + + if (!g_strcmp0(status, "connected")) { + args = json_object_new_object(); + afb_service_call("Bluetooth-Manager", "discovery_result", + args, discovery_result_cb, &response); + } else if (!g_strcmp0(status, "disconnected")) { + json_object_object_get_ex(object, "Address", &address_obj); + address = json_object_get_string(address_obj); + if (!g_strcmp0(address, ofono_manager_get_default_modem_address())) { + ofono_manager_invalidate_default_modem(); + ofono_voicecallmanager_free(vcm); + } + } else + AFB_ERROR("Unsupported connection status: %s\n", status); +} + +static void onevent(const char *event, struct json_object *object) +{ + if (!g_strcmp0(event, "Bluetooth-Manager/connection")) + process_connection_event(object); + else + AFB_ERROR("Unsupported event: %s\n", event); +} + const struct afb_binding_v2 afbBindingV2 = { .api = "telephony", .specification = NULL, .verbs = verbs, .init = init, + .onevent = onevent, }; |