summaryrefslogtreecommitdiff
path: root/cras/src/server/cras_bt_profile.c
diff options
context:
space:
mode:
Diffstat (limited to 'cras/src/server/cras_bt_profile.c')
-rw-r--r--cras/src/server/cras_bt_profile.c479
1 files changed, 0 insertions, 479 deletions
diff --git a/cras/src/server/cras_bt_profile.c b/cras/src/server/cras_bt_profile.c
deleted file mode 100644
index 9b4171fa..00000000
--- a/cras/src/server/cras_bt_profile.c
+++ /dev/null
@@ -1,479 +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 <stdlib.h>
-#include <string.h>
-#include <syslog.h>
-#include <unistd.h>
-
-#include "cras_bt_constants.h"
-#include "cras_bt_device.h"
-#include "cras_bt_profile.h"
-#include "cras_dbus_util.h"
-#include "utlist.h"
-
-#define PROFILE_INTROSPECT_XML \
- DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \
- "<node>\n" \
- " <interface name=\"org.bluez.Profile1\">\n" \
- " <method name=\"Release\">\n" \
- " </method>\n" \
- " <method name=\"NewConnection\">\n" \
- " <arg name=\"device\" type=\"o\" direction=\"in\">\n" \
- " <arg name=\"fd\" type=\"h\" direction=\"in\">\n" \
- " <arg name=\"fd_properties\" type=\"a{sv}\" direction=\"in\">\n" \
- " </method>\n" \
- " <method name=\"RequestDisconnection\">\n" \
- " <arg name=\"device\" type=\"o\" direction=\"in\">\n" \
- " </method>\n" \
- " <method name=\"Cancel\">\n" \
- " </method>\n" \
- " <interface name=\"" DBUS_INTERFACE_INTROSPECTABLE "\">\n" \
- " <method name=\"Introspect\">\n" \
- " <arg name=\"data\" type=\"s\" direction=\"out\"/>\n" \
- " </method>\n" \
- " </interface>\n" \
- "</node>\n"
-
-/* Profiles */
-static struct cras_bt_profile *profiles;
-
-static DBusHandlerResult cras_bt_profile_handle_release(DBusConnection *conn,
- DBusMessage *message,
- void *arg)
-{
- DBusMessage *reply;
- const char *profile_path;
- struct cras_bt_profile *profile;
-
- profile_path = dbus_message_get_path(message);
-
- profile = cras_bt_profile_get(profile_path);
- if (!profile)
- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-
- syslog(LOG_ERR, "Profile %s released by bluetoothd", profile->name);
- profile->release(profile);
-
- reply = dbus_message_new_method_return(message);
- if (!reply)
- return DBUS_HANDLER_RESULT_NEED_MEMORY;
- if (!dbus_connection_send(conn, reply, NULL)) {
- dbus_message_unref(reply);
- return DBUS_HANDLER_RESULT_NEED_MEMORY;
- }
-
- dbus_message_unref(reply);
-
- return DBUS_HANDLER_RESULT_HANDLED;
-}
-
-static DBusHandlerResult
-cras_bt_profile_handle_new_connection(DBusConnection *conn,
- DBusMessage *message, void *arg)
-{
- DBusMessageIter message_iter;
- DBusMessage *reply;
- const char *profile_path, *object_path;
- int fd = -1;
- int err;
- struct cras_bt_profile *profile;
- struct cras_bt_device *device;
-
- profile_path = dbus_message_get_path(message);
-
- dbus_message_iter_init(message, &message_iter);
- dbus_message_iter_get_basic(&message_iter, &object_path);
- dbus_message_iter_next(&message_iter);
-
- if (dbus_message_iter_get_arg_type(&message_iter) !=
- DBUS_TYPE_UNIX_FD) {
- syslog(LOG_ERR, "Argument not a valid unix file descriptor");
- goto invalid;
- }
-
- dbus_message_iter_get_basic(&message_iter, &fd);
- dbus_message_iter_next(&message_iter);
- if (fd < 0)
- goto invalid;
-
- profile = cras_bt_profile_get(profile_path);
- if (!profile)
- goto invalid;
-
- device = cras_bt_device_get(object_path);
- if (!device) {
- syslog(LOG_ERR, "Device %s not found at %s new connection",
- object_path, profile_path);
- device = cras_bt_device_create(conn, object_path);
- }
-
- err = profile->new_connection(conn, profile, device, fd);
- if (err) {
- syslog(LOG_INFO, "%s new connection rejected", profile->name);
- close(fd);
- reply = dbus_message_new_error(
- message, "org.chromium.Cras.Error.RejectNewConnection",
- "Possibly another headset already in use");
- if (!dbus_connection_send(conn, reply, NULL))
- return DBUS_HANDLER_RESULT_NEED_MEMORY;
-
- dbus_message_unref(reply);
- return DBUS_HANDLER_RESULT_HANDLED;
- }
-
- reply = dbus_message_new_method_return(message);
- if (!reply)
- return DBUS_HANDLER_RESULT_NEED_MEMORY;
- if (!dbus_connection_send(conn, reply, NULL)) {
- dbus_message_unref(reply);
- return DBUS_HANDLER_RESULT_NEED_MEMORY;
- }
-
- dbus_message_unref(reply);
- return DBUS_HANDLER_RESULT_HANDLED;
-
-invalid:
- if (fd >= 0)
- close(fd);
- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-}
-
-static DBusHandlerResult
-cras_bt_profile_handle_request_disconnection(DBusConnection *conn,
- DBusMessage *message, void *arg)
-{
- DBusMessageIter message_iter;
- DBusMessage *reply;
- const char *prpofile_path, *object_path;
- struct cras_bt_profile *profile;
- struct cras_bt_device *device;
-
- prpofile_path = dbus_message_get_path(message);
-
- dbus_message_iter_init(message, &message_iter);
- dbus_message_iter_get_basic(&message_iter, &object_path);
- dbus_message_iter_next(&message_iter);
-
- profile = cras_bt_profile_get(prpofile_path);
- if (!profile)
- goto invalid;
-
- device = cras_bt_device_get(object_path);
- if (!device)
- goto invalid;
-
- profile->request_disconnection(profile, device);
-
- reply = dbus_message_new_method_return(message);
- if (!reply)
- return DBUS_HANDLER_RESULT_NEED_MEMORY;
- if (!dbus_connection_send(conn, reply, NULL)) {
- dbus_message_unref(reply);
- return DBUS_HANDLER_RESULT_NEED_MEMORY;
- }
-
- dbus_message_unref(reply);
-
- return DBUS_HANDLER_RESULT_HANDLED;
-
-invalid:
- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-}
-
-static DBusHandlerResult cras_bt_profile_handle_cancel(DBusConnection *conn,
- DBusMessage *message,
- void *arg)
-{
- DBusMessage *reply;
- const char *profile_path;
- struct cras_bt_profile *profile;
-
- profile_path = dbus_message_get_path(message);
-
- profile = cras_bt_profile_get(profile_path);
- if (!profile)
- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-
- profile->cancel(profile);
-
- reply = dbus_message_new_method_return(message);
- if (!reply)
- return DBUS_HANDLER_RESULT_NEED_MEMORY;
- if (!dbus_connection_send(conn, reply, NULL)) {
- dbus_message_unref(reply);
- return DBUS_HANDLER_RESULT_NEED_MEMORY;
- }
-
- dbus_message_unref(reply);
-
- return DBUS_HANDLER_RESULT_HANDLED;
-}
-
-static DBusHandlerResult cras_bt_handle_profile_messages(DBusConnection *conn,
- DBusMessage *message,
- void *arg)
-{
- if (dbus_message_is_method_call(message, DBUS_INTERFACE_INTROSPECTABLE,
- "Introspect")) {
- DBusMessage *reply;
- const char *xml = PROFILE_INTROSPECT_XML;
-
- reply = dbus_message_new_method_return(message);
- if (!reply)
- return DBUS_HANDLER_RESULT_NEED_MEMORY;
- if (!dbus_message_append_args(reply, DBUS_TYPE_STRING, &xml,
- DBUS_TYPE_INVALID)) {
- dbus_message_unref(reply);
- return DBUS_HANDLER_RESULT_NEED_MEMORY;
- }
- if (!dbus_connection_send(conn, reply, NULL)) {
- dbus_message_unref(reply);
- return DBUS_HANDLER_RESULT_NEED_MEMORY;
- }
-
- dbus_message_unref(reply);
- return DBUS_HANDLER_RESULT_HANDLED;
- } else if (dbus_message_is_method_call(message, BLUEZ_INTERFACE_PROFILE,
- "Release")) {
- return cras_bt_profile_handle_release(conn, message, arg);
- } else if (dbus_message_is_method_call(message, BLUEZ_INTERFACE_PROFILE,
- "NewConnection")) {
- return cras_bt_profile_handle_new_connection(conn, message,
- arg);
- } else if (dbus_message_is_method_call(message, BLUEZ_INTERFACE_PROFILE,
- "RequestDisconnection")) {
- return cras_bt_profile_handle_request_disconnection(
- conn, message, arg);
- } else if (dbus_message_is_method_call(message, BLUEZ_INTERFACE_PROFILE,
- "Cancel")) {
- return cras_bt_profile_handle_cancel(conn, message, arg);
- } else {
- syslog(LOG_ERR, "Unknown Profile message");
- }
-
- return DBUS_HANDLER_RESULT_HANDLED;
-}
-
-static void cras_bt_on_register_profile(DBusPendingCall *pending_call,
- void *data)
-{
- DBusMessage *reply;
-
- 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, "RegisterProfile returned error: %s",
- dbus_message_get_error_name(reply));
- dbus_message_unref(reply);
-}
-
-int cras_bt_register_profile(DBusConnection *conn,
- struct cras_bt_profile *profile)
-{
- DBusMessage *method_call;
- DBusMessageIter message_iter;
- DBusMessageIter properties_array_iter;
- DBusPendingCall *pending_call;
-
- method_call = dbus_message_new_method_call(BLUEZ_SERVICE,
- PROFILE_MANAGER_OBJ_PATH,
- BLUEZ_PROFILE_MGMT_INTERFACE,
- "RegisterProfile");
-
- if (!method_call)
- return -ENOMEM;
-
- dbus_message_iter_init_append(method_call, &message_iter);
- dbus_message_iter_append_basic(&message_iter, DBUS_TYPE_OBJECT_PATH,
- &profile->object_path);
- dbus_message_iter_append_basic(&message_iter, DBUS_TYPE_STRING,
- &profile->uuid);
-
- dbus_message_iter_open_container(
- &message_iter, DBUS_TYPE_ARRAY,
- DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING DBUS_TYPE_STRING_AS_STRING
- DBUS_TYPE_VARIANT_AS_STRING
- DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
- &properties_array_iter);
-
- if (!append_key_value(&properties_array_iter, "Name", DBUS_TYPE_STRING,
- DBUS_TYPE_STRING_AS_STRING, &profile->name)) {
- dbus_message_unref(method_call);
- return -ENOMEM;
- }
-
- if (profile->record &&
- !append_key_value(&properties_array_iter, "ServiceRecord",
- DBUS_TYPE_STRING, DBUS_TYPE_STRING_AS_STRING,
- &profile->record)) {
- dbus_message_unref(method_call);
- return -ENOMEM;
- }
-
- if (!append_key_value(&properties_array_iter, "Version",
- DBUS_TYPE_UINT16, DBUS_TYPE_UINT16_AS_STRING,
- &profile->version)) {
- dbus_message_unref(method_call);
- return -ENOMEM;
- }
-
- if (profile->role &&
- !append_key_value(&properties_array_iter, "Role", DBUS_TYPE_STRING,
- DBUS_TYPE_STRING_AS_STRING, &profile->role)) {
- dbus_message_unref(method_call);
- return -ENOMEM;
- }
-
- if (profile->features &&
- !append_key_value(&properties_array_iter, "Features",
- DBUS_TYPE_UINT16, DBUS_TYPE_UINT16_AS_STRING,
- &profile->features)) {
- dbus_message_unref(method_call);
- return -ENOMEM;
- }
-
- dbus_message_iter_close_container(&message_iter,
- &properties_array_iter);
-
- if (!dbus_connection_send_with_reply(conn, method_call, &pending_call,
- DBUS_TIMEOUT_USE_DEFAULT)) {
- dbus_message_unref(method_call);
- return -ENOMEM;
- }
-
- dbus_message_unref(method_call);
- if (!pending_call)
- return -EIO;
-
- if (!dbus_pending_call_set_notify(
- pending_call, cras_bt_on_register_profile, NULL, NULL)) {
- dbus_pending_call_cancel(pending_call);
- dbus_pending_call_unref(pending_call);
- syslog(LOG_ERR, "register profile fail on set notify");
- return -ENOMEM;
- }
-
- return 0;
-}
-
-int cras_bt_unregister_profile(DBusConnection *conn,
- struct cras_bt_profile *profile)
-{
- DBusMessage *method_call;
- DBusMessageIter message_iter;
- DBusError dbus_error;
- DBusMessage *reply;
-
- method_call = dbus_message_new_method_call(BLUEZ_SERVICE,
- PROFILE_MANAGER_OBJ_PATH,
- BLUEZ_PROFILE_MGMT_INTERFACE,
- "UnregisterProfile");
-
- if (!method_call)
- return -ENOMEM;
- dbus_error_init(&dbus_error);
- dbus_message_iter_init_append(method_call, &message_iter);
- dbus_message_iter_append_basic(&message_iter, DBUS_TYPE_OBJECT_PATH,
- &profile->object_path);
- reply = dbus_connection_send_with_reply_and_block(
- conn, method_call, DBUS_TIMEOUT_USE_DEFAULT, &dbus_error);
-
- if (!reply) {
- dbus_error_free(&dbus_error);
- dbus_message_unref(method_call);
- return -EIO;
- }
-
- dbus_message_unref(method_call);
-
- if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) {
- syslog(LOG_ERR, "Unregister profile returned error: %s",
- dbus_message_get_error_name(reply));
- dbus_message_unref(reply);
- return -EIO;
- }
- dbus_message_unref(reply);
- return 0;
-}
-
-int cras_bt_register_profiles(DBusConnection *conn)
-{
- struct cras_bt_profile *profile;
- int err;
-
- DL_FOREACH (profiles, profile) {
- err = cras_bt_register_profile(conn, profile);
- if (err)
- return err;
- }
-
- return 0;
-}
-
-int cras_bt_add_profile(DBusConnection *conn, struct cras_bt_profile *profile)
-{
- static const DBusObjectPathVTable profile_vtable = {
- NULL, cras_bt_handle_profile_messages, NULL, NULL, NULL, NULL
- };
-
- DBusError dbus_error;
-
- dbus_error_init(&dbus_error);
-
- if (!dbus_connection_register_object_path(
- conn, profile->object_path, &profile_vtable, &dbus_error)) {
- syslog(LOG_ERR, "Could not register BT profile %s: %s",
- profile->object_path, dbus_error.message);
- dbus_error_free(&dbus_error);
- return -ENOMEM;
- }
-
- DL_APPEND(profiles, profile);
-
- return 0;
-}
-
-int cras_bt_rm_profile(DBusConnection *conn, struct cras_bt_profile *profile)
-{
- DL_DELETE(profiles, profile);
-
- if (!dbus_connection_unregister_object_path(conn,
- profile->object_path)) {
- syslog(LOG_ERR, "Could not unregister BT profile %s",
- profile->object_path);
- return -ENOMEM;
- }
- return 0;
-}
-
-void cras_bt_profile_reset()
-{
- struct cras_bt_profile *profile;
-
- DL_FOREACH (profiles, profile)
- profile->release(profile);
-}
-
-struct cras_bt_profile *cras_bt_profile_get(const char *path)
-{
- struct cras_bt_profile *profile;
- DL_FOREACH (profiles, profile) {
- if (strcmp(profile->object_path, path) == 0)
- return profile;
- }
-
- return NULL;
-}
-
-void cras_bt_profile_on_device_disconnected(struct cras_bt_device *device)
-{
- struct cras_bt_profile *profile;
- DL_FOREACH (profiles, profile)
- profile->request_disconnection(profile, device);
-}