diff options
-rw-r--r-- | README.md | 1 | ||||
-rw-r--r-- | binding/CMakeLists.txt | 2 | ||||
-rw-r--r-- | binding/bluetooth-api.c | 41 | ||||
-rw-r--r-- | binding/bluetooth-api.h | 4 | ||||
-rw-r--r-- | binding/bluetooth-common.h | 8 | ||||
-rw-r--r-- | binding/bluetooth-conf.c | 71 | ||||
-rw-r--r-- | binding/bluetooth-util.c | 5 |
7 files changed, 127 insertions, 5 deletions
@@ -12,6 +12,7 @@ Bluetooth service uses the respective BlueZ package to connect to bluetooth devi | unsubscribe | unsubscribe to bluetooth events | *Request:* {"value": "device_changes"} | | managed_objects | retrieve managed bluetooth devices | see managed_objects verb section | | adapter_state | retrieve or change adapter scan settings | see adapter_state verb section | +| default_adapter | retrieve or change default adapter setting | *Request:* {"adapter": "hci1"} | | avrcp_controls | avrcp controls for MediaPlayer1 playback | see avrcp_controls verb section | | connect | connect to already paired device | see connect/disconnect verb section | | disconnect | disconnect to already connected device | see connect/disconnect verb section | diff --git a/binding/CMakeLists.txt b/binding/CMakeLists.txt index a4a8072..103838d 100644 --- a/binding/CMakeLists.txt +++ b/binding/CMakeLists.txt @@ -21,7 +21,7 @@ PROJECT_TARGET_ADD(afm-bluetooth-binding) # Define project Targets - add_library(afm-bluetooth-binding MODULE bluetooth-api.c bluetooth-agent.c bluetooth-rfkill.c bluetooth-util.c bluetooth-bluez.c) + add_library(afm-bluetooth-binding MODULE bluetooth-api.c bluetooth-agent.c bluetooth-conf.c bluetooth-rfkill.c bluetooth-util.c bluetooth-bluez.c) # Binder exposes a unique public entry point SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES diff --git a/binding/bluetooth-api.c b/binding/bluetooth-api.c index 0000d9b..a1f37e8 100644 --- a/binding/bluetooth-api.c +++ b/binding/bluetooth-api.c @@ -43,7 +43,7 @@ */ static GThread *global_thread; -static struct bluetooth_state *bluetooth_get_userdata(afb_req_t request) { +struct bluetooth_state *bluetooth_get_userdata(afb_req_t request) { afb_api_t api = afb_req_get_api(request); return afb_api_get_userdata(api); } @@ -556,6 +556,7 @@ static int init(afb_api_t api) { struct init_data init_data, *id = &init_data; gint64 end_time; + int ret; memset(id, 0, sizeof(*id)); id->init_done = FALSE; @@ -564,6 +565,12 @@ static int init(afb_api_t api) g_cond_init(&id->cond); g_mutex_init(&id->mutex); + ret = afb_daemon_require_api("persistence", 1); + if (ret < 0) { + AFB_ERROR("Cannot request data persistence service"); + return ret; + } + global_thread = g_thread_new("agl-service-bluetooth", bluetooth_func, id); @@ -590,6 +597,8 @@ static int init(afb_api_t api) else AFB_INFO("bluetooth-binding operational"); + id->ns->default_adapter = get_default_adapter(id->api); + return id->rc; } @@ -683,7 +692,7 @@ static void bluetooth_state(afb_req_t request) json_object *jresp; const char *adapter = afb_req_value(request, "adapter"); - adapter = BLUEZ_ROOT_PATH(adapter ? adapter : BLUEZ_DEFAULT_ADAPTER); + adapter = BLUEZ_ROOT_PATH(adapter ? adapter : ns->default_adapter); jresp = adapter_properties(ns, &error, adapter); if (!jresp) { @@ -702,7 +711,7 @@ static void bluetooth_adapter(afb_req_t request) const char *adapter = afb_req_value(request, "adapter"); const char *scan, *discoverable, *powered, *filter; - adapter = BLUEZ_ROOT_PATH(adapter ? adapter : BLUEZ_DEFAULT_ADAPTER); + adapter = BLUEZ_ROOT_PATH(adapter ? adapter : ns->default_adapter); scan = afb_req_value(request, "discovery"); if (scan) { @@ -796,6 +805,27 @@ static void bluetooth_adapter(afb_req_t request) bluetooth_state(request); } +static void bluetooth_default_adapter(afb_req_t request) +{ + struct bluetooth_state *ns = bluetooth_get_userdata(request); + const char *adapter = afb_req_value(request, "adapter"); + json_object *jresp = json_object_new_object(); + + call_work_lock(ns); + if (adapter) { + set_default_adapter(afb_req_get_api(request), adapter); + + if (ns->default_adapter) + g_free(ns->default_adapter); + ns->default_adapter = g_strdup(adapter); + } + + json_object_object_add(jresp, "adapter", json_object_new_string(ns->default_adapter)); + call_work_unlock(ns); + + afb_req_success(request, jresp, "Bluetooth - default adapter"); +} + static void connect_service_callback(void *user_data, GVariant *result, GError **error) { @@ -1182,6 +1212,11 @@ static const struct afb_verb_v3 bluetooth_verbs[] = { .callback = bluetooth_adapter, .info = "Set adapter mode and retrieve properties" }, { + .verb = "default_adapter", + .session = AFB_SESSION_NONE, + .callback = bluetooth_default_adapter, + .info = "Set default adapter for commands" + }, { .verb = "connect", .session = AFB_SESSION_NONE, .callback = bluetooth_connect_device, diff --git a/binding/bluetooth-api.h b/binding/bluetooth-api.h index cd6a775..5fa417a 100644 --- a/binding/bluetooth-api.h +++ b/binding/bluetooth-api.h @@ -40,6 +40,7 @@ #define BLUEZ_ROOT_PATH(_t) \ ({ \ + call_work_lock(ns); \ const char *__t = (_t); \ size_t __len = strlen(BLUEZ_PATH) + 1 + \ strlen(__t) + 1; \ @@ -47,6 +48,7 @@ __tpath = alloca(__len + 1 + 1); \ snprintf(__tpath, __len + 1, \ BLUEZ_PATH "/%s", __t); \ + call_work_unlock(ns); \ __tpath; \ }) @@ -120,6 +122,8 @@ static inline gboolean is_mediaplayer1_interface(const char *path) return ret; } +struct bluetooth_state *bluetooth_get_userdata(afb_req_t request); + struct call_work *call_work_create_unlocked(struct bluetooth_state *ns, const char *access_type, const char *type_arg, const char *method, const char *bluez_method, diff --git a/binding/bluetooth-common.h b/binding/bluetooth-common.h index 68e747b..8b21656 100644 --- a/binding/bluetooth-common.h +++ b/binding/bluetooth-common.h @@ -60,6 +60,9 @@ struct bluetooth_state { /* mediaplayer */ gchar *mediaplayer_path; + + /* adapter */ + gchar *default_adapter; }; struct init_data { @@ -99,6 +102,11 @@ int bluetooth_register_agent(struct init_data *id); void bluetooth_unregister_agent(struct bluetooth_state *ns); +/* conf methods in bluetooth-conf.c */ + +gchar *get_default_adapter(afb_api_t api); +int set_default_adapter(afb_api_t api, const char *adapter); + /* utility methods in bluetooth-util.c */ extern gboolean auto_lowercase_keys; diff --git a/binding/bluetooth-conf.c b/binding/bluetooth-conf.c new file mode 100644 index 0000000..d9edf98 --- /dev/null +++ b/binding/bluetooth-conf.c @@ -0,0 +1,71 @@ +/* + * Copyright 2018 Konsulko Group + * Author: Matt Ranostay <matt.ranostay@konsulko.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define _GNU_SOURCE +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <unistd.h> +#include <errno.h> + +#include <glib.h> +#include <stdlib.h> +#include <gio/gio.h> +#include <glib-object.h> + +#include <json-c/json.h> + +#define AFB_BINDING_VERSION 3 +#include <afb/afb-binding.h> + +#include "bluetooth-api.h" +#include "bluetooth-common.h" + +gchar *get_default_adapter(afb_api_t api) +{ + json_object *response, *query, *val; + gchar *adapter; + int ret; + + query = json_object_new_object(); + json_object_object_add(query, "key", json_object_new_string("default_adapter")); + + ret = afb_api_call_sync(api, "persistence", "read", query, &response, NULL, NULL); + if (ret < 0) + return g_strdup(BLUEZ_DEFAULT_ADAPTER); + + json_object_object_get_ex(response, "value", &val); + adapter = g_strdup(json_object_get_string(val)); + json_object_put(response); + + return adapter ? adapter : g_strdup(BLUEZ_DEFAULT_ADAPTER); +} + +int set_default_adapter(afb_api_t api, const char *adapter) +{ + json_object *response, *query; + int ret; + + query = json_object_new_object(); + json_object_object_add(query, "key", json_object_new_string("default_adapter")); + json_object_object_add(query, "value", json_object_new_string(adapter)); + + ret = afb_api_call_sync(api, "persistence", "update", query, &response, NULL, NULL); + json_object_put(response); + + return ret; +} diff --git a/binding/bluetooth-util.c b/binding/bluetooth-util.c index e8a0781..f07e5ed 100644 --- a/binding/bluetooth-util.c +++ b/binding/bluetooth-util.c @@ -1040,10 +1040,13 @@ void json_process_path(json_object *jresp, const char *path) { } gchar *return_bluez_path(afb_req_t request) { + struct bluetooth_state *ns = bluetooth_get_userdata(request); const char *adapter = afb_req_value(request, "adapter"); const char *device, *tmp; - adapter = adapter ? adapter : BLUEZ_DEFAULT_ADAPTER; + call_work_lock(ns); + adapter = adapter ? adapter : ns->default_adapter; + call_work_unlock(ns); device = afb_req_value(request, "device"); if (!device) |