diff options
Diffstat (limited to 'cras/src/server/cras_bt_adapter.c')
-rw-r--r-- | cras/src/server/cras_bt_adapter.c | 383 |
1 files changed, 0 insertions, 383 deletions
diff --git a/cras/src/server/cras_bt_adapter.c b/cras/src/server/cras_bt_adapter.c deleted file mode 100644 index bcdecefa..00000000 --- a/cras/src/server/cras_bt_adapter.c +++ /dev/null @@ -1,383 +0,0 @@ -/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include <dbus/dbus.h> - -#include <errno.h> -#include <stdint.h> -#include <stdlib.h> -#include <string.h> -#include <syslog.h> -#include <sys/socket.h> -#include <sys/ioctl.h> - -#include "bluetooth.h" -#include "cras_bt_adapter.h" -#include "cras_bt_constants.h" -#include "utlist.h" - -/* - * Object to represent a bluetooth adapter on the system. Used to query the - * capabilities regarding certain bluetooth audio. - * Members: - * conn - The dbus connection used to send message to bluetoothd. - * object_path - Object path of the bluetooth adapter. - * address - The BT address of this adapter. - * name - The readable name of this adapter. - * bluetooth_class - The bluetooth class of device. - * powered - Powered on or off. - * bus_type - Type of bus this adapter runs on. - * wide_band_speech - If this adapter supports wide band speech. - */ -struct cras_bt_adapter { - DBusConnection *conn; - char *object_path; - char *address; - char *name; - uint32_t bluetooth_class; - int powered; - int bus_type; - int wide_band_speech; - - struct cras_bt_adapter *prev, *next; -}; - -static struct cras_bt_adapter *adapters; - -static int cras_bt_adapter_query_bus_type(struct cras_bt_adapter *adapter) -{ - static const char *hci_str = "hci"; - struct hci_dev_info dev_info; - char *pos; - int ctl, err; - - /* Object path [variable prefix]/{hci0,hci1,...} */ - pos = strstr(adapter->object_path, hci_str); - if (!pos) - return -1; - - ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); - if (ctl < 0) { - syslog(LOG_ERR, "Error creating HCI ctl socket"); - return -1; - } - - /* dev_id = 0 for hci0 */ - dev_info.type = 0; - dev_info.dev_id = atoi(pos + 3); - err = ioctl(ctl, HCIGETDEVINFO, (void *)&dev_info); - if (err) { - syslog(LOG_ERR, "HCI get dev info error %s", strerror(errno)); - close(ctl); - return -1; - } - if ((dev_info.type & 0x0f) < HCI_BUS_MAX) - adapter->bus_type = (dev_info.type & 0x0f); - - close(ctl); - return 0; -} - -struct cras_bt_adapter *cras_bt_adapter_create(DBusConnection *conn, - const char *object_path) -{ - struct cras_bt_adapter *adapter; - - adapter = calloc(1, sizeof(*adapter)); - if (adapter == NULL) - return NULL; - - adapter->conn = conn; - adapter->object_path = strdup(object_path); - if (adapter->object_path == NULL) { - free(adapter); - return NULL; - } - - DL_APPEND(adapters, adapter); - - /* Set bus type to USB as default when query fails. */ - if (cras_bt_adapter_query_bus_type(adapter)) - adapter->bus_type = HCI_USB; - - return adapter; -} - -void cras_bt_adapter_destroy(struct cras_bt_adapter *adapter) -{ - DL_DELETE(adapters, adapter); - - free(adapter->object_path); - free(adapter->address); - free(adapter->name); - free(adapter); -} - -void cras_bt_adapter_reset() -{ - while (adapters) { - syslog(LOG_INFO, "Bluetooth Adapter: %s removed", - adapters->address); - cras_bt_adapter_destroy(adapters); - } -} - -struct cras_bt_adapter *cras_bt_adapter_get(const char *object_path) -{ - struct cras_bt_adapter *adapter; - - if (object_path == NULL) - return NULL; - - DL_FOREACH (adapters, adapter) { - if (strcmp(adapter->object_path, object_path) == 0) - return adapter; - } - - return NULL; -} - -size_t cras_bt_adapter_get_list(struct cras_bt_adapter ***adapter_list_out) -{ - struct cras_bt_adapter *adapter; - struct cras_bt_adapter **adapter_list = NULL; - size_t num_adapters = 0; - - DL_FOREACH (adapters, adapter) { - struct cras_bt_adapter **tmp; - - tmp = realloc(adapter_list, - sizeof(adapter_list[0]) * (num_adapters + 1)); - if (!tmp) { - free(adapter_list); - return -ENOMEM; - } - - adapter_list = tmp; - adapter_list[num_adapters++] = adapter; - } - - *adapter_list_out = adapter_list; - return num_adapters; -} - -const char *cras_bt_adapter_object_path(const struct cras_bt_adapter *adapter) -{ - return adapter->object_path; -} - -const char *cras_bt_adapter_address(const struct cras_bt_adapter *adapter) -{ - return adapter->address; -} - -const char *cras_bt_adapter_name(const struct cras_bt_adapter *adapter) -{ - return adapter->name; -} - -int cras_bt_adapter_powered(const struct cras_bt_adapter *adapter) -{ - return adapter->powered; -} - -int cras_bt_adapter_wbs_supported(struct cras_bt_adapter *adapter) -{ - return adapter->wide_band_speech; -} - -static void bt_adapter_set_powered(struct cras_bt_adapter *adapter, int powered) -{ - adapter->powered = powered; - if (powered) - cras_bt_adapter_get_supported_capabilities(adapter); -} - -void cras_bt_adapter_update_properties(struct cras_bt_adapter *adapter, - DBusMessageIter *properties_array_iter, - DBusMessageIter *invalidated_array_iter) -{ - while (dbus_message_iter_get_arg_type(properties_array_iter) != - DBUS_TYPE_INVALID) { - DBusMessageIter properties_dict_iter, variant_iter; - const char *key; - int type; - - dbus_message_iter_recurse(properties_array_iter, - &properties_dict_iter); - - dbus_message_iter_get_basic(&properties_dict_iter, &key); - dbus_message_iter_next(&properties_dict_iter); - - dbus_message_iter_recurse(&properties_dict_iter, &variant_iter); - type = dbus_message_iter_get_arg_type(&variant_iter); - - if (type == DBUS_TYPE_STRING) { - const char *value; - - dbus_message_iter_get_basic(&variant_iter, &value); - - if (strcmp(key, "Address") == 0) { - free(adapter->address); - adapter->address = strdup(value); - - } else if (strcmp(key, "Alias") == 0) { - free(adapter->name); - adapter->name = strdup(value); - } - - } else if (type == DBUS_TYPE_UINT32) { - uint32_t value; - - dbus_message_iter_get_basic(&variant_iter, &value); - - if (strcmp(key, "Class") == 0) - adapter->bluetooth_class = value; - - } else if (type == DBUS_TYPE_BOOLEAN) { - int value; - - dbus_message_iter_get_basic(&variant_iter, &value); - - if (strcmp(key, "Powered") == 0) - bt_adapter_set_powered(adapter, value); - } - - dbus_message_iter_next(properties_array_iter); - } - - while (invalidated_array_iter && - dbus_message_iter_get_arg_type(invalidated_array_iter) != - DBUS_TYPE_INVALID) { - const char *key; - - dbus_message_iter_get_basic(invalidated_array_iter, &key); - - if (strcmp(key, "Address") == 0) { - free(adapter->address); - adapter->address = NULL; - } else if (strcmp(key, "Alias") == 0) { - free(adapter->name); - adapter->name = NULL; - } else if (strcmp(key, "Class") == 0) { - adapter->bluetooth_class = 0; - } else if (strcmp(key, "Powered") == 0) { - adapter->powered = 0; - } - - dbus_message_iter_next(invalidated_array_iter); - } -} - -int cras_bt_adapter_on_usb(struct cras_bt_adapter *adapter) -{ - return !!(adapter->bus_type == HCI_USB); -} - -/* - * Expect to receive supported capabilities in reply, like below format: - * array [ - * dict entry( - * string "wide band speech" - * variant - * boolean <value> - * ) - * ] - */ -static void on_get_supported_capabilities_reply(DBusPendingCall *pending_call, - void *data) -{ - DBusMessage *reply; - DBusMessageIter message_iter, capabilities; - struct cras_bt_adapter *adapter; - - reply = dbus_pending_call_steal_reply(pending_call); - dbus_pending_call_unref(pending_call); - - if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) { - syslog(LOG_ERR, - "GetSupportedCapabilities message replied error: %s", - dbus_message_get_error_name(reply)); - goto get_supported_capabilities_err; - } - - if (!dbus_message_iter_init(reply, &message_iter)) { - syslog(LOG_ERR, "GetSupportedCapabilities reply doesn't have" - "argument"); - goto get_supported_capabilities_err; - } - - DL_FOREACH (adapters, adapter) { - if (adapter == (struct cras_bt_adapter *)data) - break; - } - if (NULL == adapter) - goto get_supported_capabilities_err; - - dbus_message_iter_recurse(&message_iter, &capabilities); - - while (dbus_message_iter_get_arg_type(&capabilities) != - DBUS_TYPE_INVALID) { - DBusMessageIter cap_dict_iter, variant_iter; - const char *key; - int type; - - dbus_message_iter_recurse(&capabilities, &cap_dict_iter); - - dbus_message_iter_get_basic(&cap_dict_iter, &key); - dbus_message_iter_next(&cap_dict_iter); - - dbus_message_iter_recurse(&cap_dict_iter, &variant_iter); - type = dbus_message_iter_get_arg_type(&variant_iter); - - if (type == DBUS_TYPE_BOOLEAN) { - int value; - - dbus_message_iter_get_basic(&variant_iter, &value); - - if (strcmp(key, "wide band speech") == 0) - adapter->wide_band_speech = value; - } - - dbus_message_iter_next(&capabilities); - } - -get_supported_capabilities_err: - dbus_message_unref(reply); -} - -int cras_bt_adapter_get_supported_capabilities(struct cras_bt_adapter *adapter) -{ - DBusMessage *method_call; - DBusError dbus_error; - DBusPendingCall *pending_call; - - method_call = dbus_message_new_method_call(BLUEZ_SERVICE, - adapter->object_path, - BLUEZ_INTERFACE_ADAPTER, - "GetSupportedCapabilities"); - if (!method_call) - return -ENOMEM; - - dbus_error_init(&dbus_error); - if (!dbus_connection_send_with_reply(adapter->conn, method_call, - &pending_call, - DBUS_TIMEOUT_USE_DEFAULT)) { - dbus_message_unref(method_call); - syslog(LOG_ERR, - "Failed to send GetSupportedCapabilities message"); - return -EIO; - } - - dbus_message_unref(method_call); - if (!dbus_pending_call_set_notify(pending_call, - on_get_supported_capabilities_reply, - adapter, NULL)) { - dbus_pending_call_cancel(pending_call); - dbus_pending_call_unref(pending_call); - return -EIO; - } - return 0; -} |