From 74b978057e7b3f8cad2952c0fe50a17a118339ad Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 13 Mar 2007 18:13:28 +0000 Subject: Add skeleton for manager interface --- input/manager.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 input/manager.c (limited to 'input/manager.c') diff --git a/input/manager.c b/input/manager.c new file mode 100644 index 00000000..ab45339f --- /dev/null +++ b/input/manager.c @@ -0,0 +1,37 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2004-2007 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "manager.h" + +int input_init(void) +{ + return 0; +} + +void input_exit(void) +{ +} -- cgit From f2c6a6f2debcccfb51d239834c3cf91a2c3a6c40 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Mon, 19 Mar 2007 14:58:44 +0000 Subject: Moving input functions to the right files --- input/manager.c | 854 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 854 insertions(+) (limited to 'input/manager.c') diff --git a/input/manager.c b/input/manager.c index ab45339f..143471bc 100644 --- a/input/manager.c +++ b/input/manager.c @@ -25,13 +25,867 @@ #include #endif +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include "dbus.h" +#include "logging.h" +#include "textfile.h" + +#include "error.h" +#include "storage.h" +#include "device.h" #include "manager.h" +const char *pnp_uuid = "00001200-0000-1000-8000-00805f9b34fb"; +const char *hid_uuid = "00001124-0000-1000-8000-00805f9b34fb"; +const char *headset_uuid = "00001108-0000-1000-8000-00805f9b34fb"; + +struct pending_req { + char *adapter_path; /* Local adapter D-Bus path */ + bdaddr_t src; /* Local adapter BT address */ + bdaddr_t dst; /* Peer BT address */ + DBusConnection *conn; + DBusMessage *msg; + sdp_record_t *pnp_rec; + sdp_record_t *hid_rec; +}; + +struct input_manager { + bdaddr_t src; /* Local adapter BT address */ + GSList *paths; /* Input registered paths */ +}; + +static DBusConnection *connection = NULL; + +static struct pending_req *pending_req_new(DBusConnection *conn, + DBusMessage *msg, const char *adapter_path, + bdaddr_t *src, bdaddr_t *dst) +{ + struct pending_req *pr; + pr = g_try_new0(struct pending_req, 1); + if (!pr) + return NULL; + + pr->adapter_path = g_strdup(adapter_path); + bacpy(&pr->src, src); + bacpy(&pr->dst, dst); + pr->conn = dbus_connection_ref(conn); + pr->msg = dbus_message_ref(msg); + + return pr; +} + +static void pending_req_free(struct pending_req *pr) +{ + if (!pr) + return; + if (pr->adapter_path) + g_free(pr->adapter_path); + if (pr->conn) + dbus_connection_unref(pr->conn); + if (pr->msg) + dbus_message_unref(pr->msg); + if (pr->pnp_rec) + sdp_record_free(pr->pnp_rec); + if (pr->hid_rec) + sdp_record_free(pr->hid_rec); + g_free(pr); +} + +#if 0 +static int path_bdaddr_cmp(const char *path, const bdaddr_t *bdaddr) +{ + struct input_device *idev; + + if (!dbus_connection_get_object_path_data(connection, path, + (void *) &idev)) + return -1; + + if (!idev) + return -1; + + return bacmp(&idev->dst, bdaddr); +} +#endif +static int get_record(struct pending_req *pr, uint32_t handle, + DBusPendingCallNotifyFunction cb) +{ + DBusMessage *msg; + DBusPendingCall *pending; + char addr[18]; + const char *paddr = addr; + + msg = dbus_message_new_method_call("org.bluez", pr->adapter_path, + "org.bluez.Adapter", "GetRemoteServiceRecord"); + if (!msg) + return -1; + + ba2str(&pr->dst, addr); + dbus_message_append_args(msg, + DBUS_TYPE_STRING, &paddr, + DBUS_TYPE_UINT32, &handle, + DBUS_TYPE_INVALID); + + if (dbus_connection_send_with_reply(pr->conn, msg, &pending, -1) == FALSE) { + error("Can't send D-Bus message."); + return -1; + } + + dbus_pending_call_set_notify(pending, cb, pr, NULL); + dbus_message_unref(msg); + + return 0; +} + +static int get_handles(struct pending_req *pr, const char *uuid, + DBusPendingCallNotifyFunction cb) +{ + DBusMessage *msg; + DBusPendingCall *pending; + char addr[18]; + const char *paddr = addr; + + msg = dbus_message_new_method_call("org.bluez", pr->adapter_path, + "org.bluez.Adapter", "GetRemoteServiceHandles"); + if (!msg) + return -1; + + ba2str(&pr->dst, addr); + dbus_message_append_args(msg, + DBUS_TYPE_STRING, &paddr, + DBUS_TYPE_STRING, &uuid, + DBUS_TYPE_INVALID); + + if (dbus_connection_send_with_reply(pr->conn, msg, &pending, -1) == FALSE) { + error("Can't send D-Bus message."); + return -1; + } + + dbus_pending_call_set_notify(pending, cb, pr, NULL); + dbus_message_unref(msg); + + return 0; +} + +static void extract_hid_record(sdp_record_t *rec, struct hidp_connadd_req *req) +{ + sdp_data_t *pdlist, *pdlist2; + uint8_t attr_val; + + pdlist = sdp_data_get(rec, 0x0101); + pdlist2 = sdp_data_get(rec, 0x0102); + if (pdlist) { + if (pdlist2) { + if (strncmp(pdlist->val.str, pdlist2->val.str, 5)) { + strncpy(req->name, pdlist2->val.str, 127); + strcat(req->name, " "); + } + strncat(req->name, pdlist->val.str, 127 - strlen(req->name)); + } else + strncpy(req->name, pdlist->val.str, 127); + } else { + pdlist2 = sdp_data_get(rec, 0x0100); + if (pdlist2) + strncpy(req->name, pdlist2->val.str, 127); + } + + pdlist = sdp_data_get(rec, SDP_ATTR_HID_PARSER_VERSION); + req->parser = pdlist ? pdlist->val.uint16 : 0x0100; + + pdlist = sdp_data_get(rec, SDP_ATTR_HID_DEVICE_SUBCLASS); + req->subclass = pdlist ? pdlist->val.uint8 : 0; + + pdlist = sdp_data_get(rec, SDP_ATTR_HID_COUNTRY_CODE); + req->country = pdlist ? pdlist->val.uint8 : 0; + + pdlist = sdp_data_get(rec, SDP_ATTR_HID_VIRTUAL_CABLE); + attr_val = pdlist ? pdlist->val.uint8 : 0; + if (attr_val) + req->flags |= (1 << HIDP_VIRTUAL_CABLE_UNPLUG); + + pdlist = sdp_data_get(rec, SDP_ATTR_HID_BOOT_DEVICE); + attr_val = pdlist ? pdlist->val.uint8 : 0; + if (attr_val) + req->flags |= (1 << HIDP_BOOT_PROTOCOL_MODE); + + pdlist = sdp_data_get(rec, SDP_ATTR_HID_DESCRIPTOR_LIST); + if (pdlist) { + pdlist = pdlist->val.dataseq; + pdlist = pdlist->val.dataseq; + pdlist = pdlist->next; + + req->rd_data = g_try_malloc0(pdlist->unitSize); + if (req->rd_data) { + memcpy(req->rd_data, (unsigned char *) pdlist->val.str, pdlist->unitSize); + req->rd_size = pdlist->unitSize; + } + } +} + +static void extract_pnp_record(sdp_record_t *rec, struct hidp_connadd_req *req) +{ + sdp_data_t *pdlist; + + pdlist = sdp_data_get(rec, SDP_ATTR_VENDOR_ID); + req->vendor = pdlist ? pdlist->val.uint16 : 0x0000; + + pdlist = sdp_data_get(rec, SDP_ATTR_PRODUCT_ID); + req->product = pdlist ? pdlist->val.uint16 : 0x0000; + + pdlist = sdp_data_get(rec, SDP_ATTR_VERSION); + req->version = pdlist ? pdlist->val.uint16 : 0x0000; +} + +static void hid_record_reply(DBusPendingCall *call, void *data) +{ + DBusMessage *reply = dbus_pending_call_steal_reply(call); + DBusMessage *pr_reply; + struct input_manager *mgr; + struct pending_req *pr = data; + struct hidp_connadd_req hidp; + DBusError derr; + uint8_t *rec_bin; + const char *path; + int len, scanned; + + dbus_error_init(&derr); + if (dbus_set_error_from_message(&derr, reply)) { + err_generic(pr->conn, pr->msg, derr.name, derr.message); + error("%s: %s", derr.name, derr.message); + goto fail; + } + + if (!dbus_message_get_args(reply, &derr, + DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &rec_bin, &len, + DBUS_TYPE_INVALID)) { + err_not_supported(pr->conn, pr->msg); + error("%s: %s", derr.name, derr.message); + goto fail; + } + + if (len == 0) { + err_not_supported(pr->conn, pr->msg); + error("Invalid HID service record length"); + goto fail; + } + + pr->hid_rec = sdp_extract_pdu(rec_bin, &scanned); + if (!pr->hid_rec) { + err_not_supported(pr->conn, pr->msg); + goto fail; + } + + memset(&hidp, 0, sizeof(struct hidp_connadd_req)); + extract_hid_record(pr->hid_rec, &hidp); + if (pr->pnp_rec) + extract_pnp_record(pr->pnp_rec, &hidp); + + store_device_info(&pr->src, &pr->dst, &hidp); + + if (input_device_register(pr->conn, &pr->src, + &pr->dst, &hidp, &path) < 0) { + err_failed(pr->conn, pr->msg, "D-Bus path registration failed"); + goto fail; + } + + dbus_connection_get_object_path_data(pr->conn, INPUT_PATH, (void *) &mgr); + mgr->paths = g_slist_append(mgr->paths, g_strdup(path)); + + pr_reply = dbus_message_new_method_return(pr->msg); + dbus_message_append_args(pr_reply, + DBUS_TYPE_STRING, &path, + DBUS_TYPE_INVALID); + send_message_and_unref(pr->conn, pr_reply); +fail: + dbus_error_free(&derr); + pending_req_free(pr); + dbus_message_unref(reply); + dbus_pending_call_unref(call); +} + +static void hid_handle_reply(DBusPendingCall *call, void *data) +{ + DBusMessage *reply = dbus_pending_call_steal_reply(call); + struct pending_req *pr = data; + uint32_t *phandle; + DBusError derr; + int len; + + dbus_error_init(&derr); + if (dbus_set_error_from_message(&derr, reply)) { + err_generic(pr->conn, pr->msg, derr.name, derr.message); + error("%s: %s", derr.name, derr.message); + goto fail; + } + + if (!dbus_message_get_args(reply, &derr, + DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &phandle, &len, + DBUS_TYPE_INVALID)) { + err_not_supported(pr->conn, pr->msg); + error("%s: %s", derr.name, derr.message); + goto fail; + } + + if (len == 0) { + err_not_supported(pr->conn, pr->msg); + error("HID record handle not found"); + goto fail; + } + + if (get_record(pr, *phandle, hid_record_reply) < 0) { + err_not_supported(pr->conn, pr->msg); + error("HID service attribute request failed"); + goto fail; + } else { + /* Wait record reply */ + goto done; + } +fail: + dbus_error_free(&derr); + pending_req_free(pr); +done: + dbus_message_unref(reply); + dbus_pending_call_unref(call); +} + +static void pnp_record_reply(DBusPendingCall *call, void *data) +{ + DBusMessage *reply = dbus_pending_call_steal_reply(call); + struct pending_req *pr = data; + DBusError derr; + uint8_t *rec_bin; + int len, scanned; + + dbus_error_init(&derr); + if (dbus_set_error_from_message(&derr, reply)) { + err_generic(pr->conn, pr->msg, derr.name, derr.message); + error("%s: %s", derr.name, derr.message); + goto fail; + } + + if (!dbus_message_get_args(reply, &derr, + DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &rec_bin, &len, + DBUS_TYPE_INVALID)) { + err_not_supported(pr->conn, pr->msg); + error("%s: %s", derr.name, derr.message); + goto fail; + } + + if (len == 0) { + err_not_supported(pr->conn, pr->msg); + error("Invalid PnP service record length"); + goto fail; + } + + pr->pnp_rec = sdp_extract_pdu(rec_bin, &scanned); + if (get_handles(pr, hid_uuid, hid_handle_reply) < 0) { + err_not_supported(pr->conn, pr->msg); + error("HID service search request failed"); + goto fail; + } else { + /* Wait handle reply */ + goto done; + } + +fail: + dbus_error_free(&derr); + pending_req_free(pr); +done: + dbus_message_unref(reply); + dbus_pending_call_unref(call); +} + +static void pnp_handle_reply(DBusPendingCall *call, void *data) +{ + DBusMessage *reply = dbus_pending_call_steal_reply(call); + struct pending_req *pr = data; + DBusError derr; + uint32_t *phandle; + int len; + + dbus_error_init(&derr); + if (dbus_set_error_from_message(&derr, reply)) { + err_generic(pr->conn, pr->msg, derr.name, derr.message); + error("%s: %s", derr.name, derr.message); + goto fail; + } + + if (!dbus_message_get_args(reply, &derr, + DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &phandle, &len, + DBUS_TYPE_INVALID)) { + err_not_supported(pr->conn, pr->msg); + error("%s: %s", derr.name, derr.message); + goto fail; + } + + if (len == 0) { + /* PnP is optional: Ignore it and request the HID handle */ + if (get_handles(pr, hid_uuid, hid_handle_reply) < 0) { + err_not_supported(pr->conn, pr->msg); + error("HID service search request failed"); + goto fail; + } + } else { + /* Request PnP record */ + if (get_record(pr, *phandle, pnp_record_reply) < 0) { + err_not_supported(pr->conn, pr->msg); + error("PnP service attribute request failed"); + goto fail; + } + } + + /* Wait HID handle reply or PnP record reply */ + goto done; + +fail: + dbus_error_free(&derr); + pending_req_free(pr); +done: + dbus_message_unref(reply); + dbus_pending_call_unref(call); +} + +static void headset_record_reply(DBusPendingCall *call, void *data) +{ + DBusMessage *reply = dbus_pending_call_steal_reply(call); + DBusMessage *pr_reply; + DBusError derr; + struct input_manager *mgr; + struct pending_req *pr = data; + uint8_t *rec_bin; + sdp_record_t *rec; + sdp_list_t *protos; + const char *path; + int len, scanned; + uint8_t ch; + + dbus_error_init(&derr); + if (dbus_set_error_from_message(&derr, reply)) { + err_generic(pr->conn, pr->msg, derr.name, derr.message); + error("%s: %s", derr.name, derr.message); + goto fail; + } + + if (!dbus_message_get_args(reply, &derr, + DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &rec_bin, &len, + DBUS_TYPE_INVALID)) { + err_not_supported(pr->conn, pr->msg); + error("%s: %s", derr.name, derr.message); + goto fail; + } + + if (len == 0) { + err_not_supported(pr->conn, pr->msg); + error("Invalid headset service record length"); + goto fail; + } + + rec = sdp_extract_pdu(rec_bin, &scanned); + if (!rec) { + err_not_supported(pr->conn, pr->msg); + goto fail; + } + + if (sdp_get_access_protos(rec, &protos) < 0) { + err_not_supported(pr->conn, pr->msg); + goto fail; + } + + ch = sdp_get_proto_port(protos, RFCOMM_UUID); + sdp_list_foreach(protos, (sdp_list_func_t)sdp_list_free, NULL); + sdp_list_free(protos, NULL); + sdp_record_free(rec); + + if (ch <= 0) { + err_not_supported(pr->conn, pr->msg); + error("Invalid RFCOMM channel"); + goto fail; + } + + /* FIXME: Store the fake input data */ + + if (fake_input_register(pr->conn, &pr->src, &pr->dst, ch, &path) < 0) { + error("D-Bus path registration failed:%s", path); + err_failed(pr->conn, pr->msg, "Path registration failed"); + goto fail; + } + + dbus_connection_get_object_path_data(pr->conn, INPUT_PATH, (void *) &mgr); + mgr->paths = g_slist_append(mgr->paths, g_strdup(path)); + + pr_reply = dbus_message_new_method_return(pr->msg); + dbus_message_append_args(pr_reply, + DBUS_TYPE_STRING, &path, + DBUS_TYPE_INVALID); + send_message_and_unref(pr->conn, pr_reply); +fail: + dbus_error_free(&derr); + pending_req_free(pr); + dbus_message_unref(reply); + dbus_pending_call_unref(call); +} + +static void headset_handle_reply(DBusPendingCall *call, void *data) +{ + DBusMessage *reply = dbus_pending_call_steal_reply(call); + struct pending_req *pr = data; + DBusError derr; + uint32_t *phandle; + int len; + + dbus_error_init(&derr); + if (dbus_set_error_from_message(&derr, reply)) { + err_generic(pr->conn, pr->msg, derr.name, derr.message); + error("%s: %s", derr.name, derr.message); + goto fail; + } + + if (!dbus_message_get_args(reply, &derr, + DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &phandle, &len, + DBUS_TYPE_INVALID)) { + err_not_supported(pr->conn, pr->msg); + error("%s: %s", derr.name, derr.message); + goto fail; + } + + if (len == 0) { + err_not_supported(pr->conn, pr->msg); + error("Headset record handle not found"); + goto fail; + } + + if (get_record(pr, *phandle, headset_record_reply) < 0) { + err_not_supported(pr->conn, pr->msg); + error("Headset service attribute request failed"); + goto fail; + } else { + /* Wait record reply */ + goto done; + } +fail: + dbus_error_free(&derr); + pending_req_free(pr); +done: + dbus_message_unref(reply); + dbus_pending_call_unref(call); +} + +static DBusHandlerResult manager_create_device(DBusConnection *conn, + DBusMessage *msg, void *data) +{ + struct input_manager *mgr = data; + struct pending_req *pr; + DBusError derr; + char adapter[18], adapter_path[32]; + const char *addr; + bdaddr_t dst; + uint32_t cls = 0; + int dev_id; + + dbus_error_init(&derr); + if (!dbus_message_get_args(msg, &derr, + DBUS_TYPE_STRING, &addr, + DBUS_TYPE_INVALID)) { + err_generic(conn, msg, derr.name, derr.message); + dbus_error_free(&derr); + return DBUS_HANDLER_RESULT_HANDLED; + } + + str2ba(addr, &dst); +#if 0 + /* FIXME */ + l = g_slist_find_custom(mgr->paths, &dst, + (GCompareFunc) path_bdaddr_cmp); + if (l) + return err_already_exists(conn, msg, "Input Already exists"); +#endif + /* FIXME: Move the following code to pending_req_new() */ + ba2str(&mgr->src, adapter); + dev_id = hci_devid(adapter); + snprintf(adapter_path, 32, "/org/bluez/hci%d", dev_id); + + if (read_device_class(&mgr->src, &dst, &cls) < 0) { + error("Device class not available"); + return err_not_supported(conn, msg); + } + + pr = pending_req_new(conn, msg, adapter_path, &mgr->src, &dst); + if (!pr) + return DBUS_HANDLER_RESULT_NEED_MEMORY; + + switch (cls & 0x1f00) { + case 0x0500: /* Peripheral */ + if (get_handles(pr, pnp_uuid, pnp_handle_reply) < 0) { + pending_req_free(pr); + return err_not_supported(conn, msg); + } + break; + case 0x0400: /* Fake input */ + if (get_handles(pr, headset_uuid, + headset_handle_reply) < 0) { + pending_req_free(pr); + return err_not_supported(conn, msg); + } + break; + default: + pending_req_free(pr); + return err_not_supported(conn, msg); + } + + return DBUS_HANDLER_RESULT_HANDLED; +} + +static DBusHandlerResult manager_remove_device(DBusConnection *conn, + DBusMessage *msg, void *data) +{ + struct input_manager *mgr = data; + DBusMessage *reply; + DBusError derr; + GSList *l; + const char *path; + + dbus_error_init(&derr); + if (!dbus_message_get_args(msg, &derr, + DBUS_TYPE_STRING, &path, + DBUS_TYPE_INVALID)) { + err_generic(conn, msg, derr.name, derr.message); + dbus_error_free(&derr); + return DBUS_HANDLER_RESULT_HANDLED; + } + + l = g_slist_find_custom(mgr->paths, path, (GCompareFunc) strcmp); + if (!l) + return err_does_not_exist(conn, msg, "Input doesn't exist"); + + reply = dbus_message_new_method_return(msg); + if (!reply) + return DBUS_HANDLER_RESULT_NEED_MEMORY; + + g_free(l->data); + mgr->paths = g_slist_remove(mgr->paths, l->data); + + /* FIXME: how retrieve the destination address */ + //del_stored_device_info(&mgr->src, &idev->dst); + + if (input_device_unregister(conn, path) < 0) { + dbus_message_unref(reply); + return err_failed(conn, msg, "D-Bus path unregistration failed"); + } + + return send_message_and_unref(conn, reply); +} + +static DBusHandlerResult manager_list_devices(DBusConnection *conn, + DBusMessage *msg, void *data) +{ + struct input_manager *mgr = data; + DBusMessageIter iter, iter_array; + DBusMessage *reply; + GSList *paths; + + reply = dbus_message_new_method_return(msg); + if (!reply) + return DBUS_HANDLER_RESULT_NEED_MEMORY; + + dbus_message_iter_init_append(reply, &iter); + dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, + DBUS_TYPE_STRING_AS_STRING, &iter_array); + + for (paths = mgr->paths; paths != NULL; paths = paths->next) { + const char *ppath = paths->data; + dbus_message_iter_append_basic(&iter_array, + DBUS_TYPE_STRING, &ppath); + } + + dbus_message_iter_close_container(&iter, &iter_array); + + return send_message_and_unref(conn, reply); +} +static DBusHandlerResult manager_message(DBusConnection *conn, + DBusMessage *msg, void *data) +{ + const char *path, *iface, *member; + + path = dbus_message_get_path(msg); + iface = dbus_message_get_interface(msg); + member = dbus_message_get_member(msg); + + /* Catching fallback paths */ + if (strcmp(INPUT_PATH, path) != 0) + return err_unknown_device(conn, msg); + + /* Accept messages from the input manager interface only */ + if (strcmp(INPUT_MANAGER_INTERFACE, iface)) + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + + if (strcmp(member, "ListDevices") == 0) + return manager_list_devices(conn, msg, data); + + if (strcmp(member, "CreateDevice") == 0) + return manager_create_device(conn, msg, data); + + if (strcmp(member, "RemoveDevice") == 0) + return manager_remove_device(conn, msg, data); + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +static void input_manager_free(struct input_manager *mgr) +{ + if (!mgr) + return; + + if (mgr->paths) { + g_slist_foreach(mgr->paths, (GFunc) free, NULL); + g_slist_free(mgr->paths); + } + + g_free(mgr); +} + +static void manager_unregister(DBusConnection *conn, void *data) +{ + struct input_manager *mgr = data; + + info("Unregistered manager path"); + + input_manager_free(mgr); +} + +/* Virtual table to handle manager object path hierarchy */ +static const DBusObjectPathVTable manager_table = { + .message_function = manager_message, + .unregister_function = manager_unregister, +}; + +/* + * Stored inputs registration functions + */ + +static void stored_input(char *key, char *value, void *data) +{ + struct input_manager *mgr = data; + const char *path; + struct hidp_connadd_req hidp; + bdaddr_t dst; + + str2ba(key, &dst); + + memset(&hidp, 0, sizeof(struct hidp_connadd_req)); + if (parse_stored_device_info(value, &hidp) < 0) { + return; + } + + if (input_device_register(connection, &mgr->src, &dst, &hidp, &path) < 0) + return; + + mgr->paths = g_slist_append(mgr->paths, g_strdup(path)); +} + +static int register_stored_inputs(struct input_manager *mgr) +{ + char filename[PATH_MAX + 1]; + char addr[18]; + + ba2str(&mgr->src, addr); + create_name(filename, PATH_MAX, STORAGEDIR, addr, "input"); + textfile_foreach(filename, stored_input, mgr); + + return 0; +} + int input_init(void) { + struct input_manager *mgr; + bdaddr_t src; + int dev_id; + + connection = init_dbus(NULL, NULL, NULL); + if (!connection) + return -1; + + dbus_connection_set_exit_on_disconnect(connection, TRUE); + + mgr = g_new0(struct input_manager, 1); + + /* Fallback to catch invalid device path */ + if (!dbus_connection_register_fallback(connection, INPUT_PATH, + &manager_table, mgr)) { + error("D-Bus failed to register %s path", INPUT_PATH); + goto fail; + } + + info("Registered input manager path:%s", INPUT_PATH); + + /* Set the default adapter */ + bacpy(&src, BDADDR_ANY); + dev_id = hci_get_route(&src); + if (dev_id < 0) { + error("Bluetooth device not available"); + goto fail; + } + + if (hci_devba(dev_id, &src) < 0) { + error("Can't get local adapter device info"); + goto fail; + } + + bacpy(&mgr->src, &src); + /* Register well known HID devices */ + register_stored_inputs(mgr); + return 0; + +fail: + input_manager_free(mgr); + + return -1; } void input_exit(void) { + dbus_connection_unregister_object_path(connection, INPUT_PATH); + + dbus_connection_unref(connection); +} + +void internal_service(const char *identifier) +{ + DBusMessage *msg, *reply; + const char *name = "Input Service Debug", *desc = ""; + + info("Registering service"); + + msg = dbus_message_new_method_call("org.bluez", "/org/bluez", + "org.bluez.Database", "RegisterService"); + if (!msg) { + error("Can't create service register method"); + return; + } + + dbus_message_append_args(msg, DBUS_TYPE_STRING, &identifier, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_STRING, &desc, DBUS_TYPE_INVALID); + + reply = dbus_connection_send_with_reply_and_block(connection, msg, -1, NULL); + if (!reply) { + error("Can't register service"); + return; + } + + dbus_message_unref(msg); + dbus_message_unref(reply); + + dbus_connection_flush(connection); } -- cgit From d307da66278af3505e2bb1a35de4ef2ccefb9a6d Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Mon, 19 Mar 2007 15:17:15 +0000 Subject: input: moving "struct input_device" to device.h --- input/manager.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'input/manager.c') diff --git a/input/manager.c b/input/manager.c index 143471bc..38020a22 100644 --- a/input/manager.c +++ b/input/manager.c @@ -103,7 +103,6 @@ static void pending_req_free(struct pending_req *pr) g_free(pr); } -#if 0 static int path_bdaddr_cmp(const char *path, const bdaddr_t *bdaddr) { struct input_device *idev; @@ -117,7 +116,7 @@ static int path_bdaddr_cmp(const char *path, const bdaddr_t *bdaddr) return bacmp(&idev->dst, bdaddr); } -#endif + static int get_record(struct pending_req *pr, uint32_t handle, DBusPendingCallNotifyFunction cb) { @@ -589,6 +588,7 @@ static DBusHandlerResult manager_create_device(DBusConnection *conn, DBusError derr; char adapter[18], adapter_path[32]; const char *addr; + GSList *l; bdaddr_t dst; uint32_t cls = 0; int dev_id; @@ -603,13 +603,12 @@ static DBusHandlerResult manager_create_device(DBusConnection *conn, } str2ba(addr, &dst); -#if 0 - /* FIXME */ + l = g_slist_find_custom(mgr->paths, &dst, (GCompareFunc) path_bdaddr_cmp); if (l) return err_already_exists(conn, msg, "Input Already exists"); -#endif + /* FIXME: Move the following code to pending_req_new() */ ba2str(&mgr->src, adapter); dev_id = hci_devid(adapter); -- cgit From 17033a18b3ee31d14b19f52d2328a2ba80f4ce1f Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Mon, 19 Mar 2007 17:30:08 +0000 Subject: input: code cleanup --- input/manager.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'input/manager.c') diff --git a/input/manager.c b/input/manager.c index 38020a22..ea34960b 100644 --- a/input/manager.c +++ b/input/manager.c @@ -68,15 +68,21 @@ struct input_manager { static DBusConnection *connection = NULL; -static struct pending_req *pending_req_new(DBusConnection *conn, - DBusMessage *msg, const char *adapter_path, +static struct pending_req *pending_req_new(DBusConnection *conn, DBusMessage *msg, bdaddr_t *src, bdaddr_t *dst) { + char adapter[18], adapter_path[32]; struct pending_req *pr; + int dev_id; + pr = g_try_new0(struct pending_req, 1); if (!pr) return NULL; + ba2str(src, adapter); + dev_id = hci_devid(adapter); + snprintf(adapter_path, 32, "/org/bluez/hci%d", dev_id); + pr->adapter_path = g_strdup(adapter_path); bacpy(&pr->src, src); bacpy(&pr->dst, dst); @@ -586,12 +592,10 @@ static DBusHandlerResult manager_create_device(DBusConnection *conn, struct input_manager *mgr = data; struct pending_req *pr; DBusError derr; - char adapter[18], adapter_path[32]; const char *addr; GSList *l; bdaddr_t dst; uint32_t cls = 0; - int dev_id; dbus_error_init(&derr); if (!dbus_message_get_args(msg, &derr, @@ -609,17 +613,12 @@ static DBusHandlerResult manager_create_device(DBusConnection *conn, if (l) return err_already_exists(conn, msg, "Input Already exists"); - /* FIXME: Move the following code to pending_req_new() */ - ba2str(&mgr->src, adapter); - dev_id = hci_devid(adapter); - snprintf(adapter_path, 32, "/org/bluez/hci%d", dev_id); - if (read_device_class(&mgr->src, &dst, &cls) < 0) { error("Device class not available"); return err_not_supported(conn, msg); } - pr = pending_req_new(conn, msg, adapter_path, &mgr->src, &dst); + pr = pending_req_new(conn, msg, &mgr->src, &dst); if (!pr) return DBUS_HANDLER_RESULT_NEED_MEMORY; -- cgit From ab0791e294f317f970e5dc288c2d9f87fd22a4e2 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Mon, 19 Mar 2007 17:49:20 +0000 Subject: input: delete the stored input date when RemoveDevice is called --- input/manager.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'input/manager.c') diff --git a/input/manager.c b/input/manager.c index ea34960b..2675b5cb 100644 --- a/input/manager.c +++ b/input/manager.c @@ -114,7 +114,7 @@ static int path_bdaddr_cmp(const char *path, const bdaddr_t *bdaddr) struct input_device *idev; if (!dbus_connection_get_object_path_data(connection, path, - (void *) &idev)) + (void *) &idev)) return -1; if (!idev) @@ -648,6 +648,7 @@ static DBusHandlerResult manager_remove_device(DBusConnection *conn, DBusMessage *msg, void *data) { struct input_manager *mgr = data; + struct input_device *idev; DBusMessage *reply; DBusError derr; GSList *l; @@ -673,8 +674,10 @@ static DBusHandlerResult manager_remove_device(DBusConnection *conn, g_free(l->data); mgr->paths = g_slist_remove(mgr->paths, l->data); - /* FIXME: how retrieve the destination address */ - //del_stored_device_info(&mgr->src, &idev->dst); + if (!dbus_connection_get_object_path_data(connection, path, (void *) &idev)) + return err_does_not_exist(conn, msg, "Input doesn't exist"); + + del_stored_device_info(&mgr->src, &idev->dst); if (input_device_unregister(conn, path) < 0) { dbus_message_unref(reply); -- cgit From aa2c3ce4dcbbe498216407141479e20410d55b77 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Wed, 21 Mar 2007 14:40:19 +0000 Subject: input: code cleanup --- input/manager.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'input/manager.c') diff --git a/input/manager.c b/input/manager.c index 2675b5cb..2ad8948e 100644 --- a/input/manager.c +++ b/input/manager.c @@ -30,9 +30,9 @@ #include #include #include +#include #include #include -#include #include @@ -42,10 +42,10 @@ #include "logging.h" #include "textfile.h" -#include "error.h" -#include "storage.h" #include "device.h" +#include "error.h" #include "manager.h" +#include "storage.h" const char *pnp_uuid = "00001200-0000-1000-8000-00805f9b34fb"; const char *hid_uuid = "00001124-0000-1000-8000-00805f9b34fb"; -- cgit From c95cdbbf157765752d7d9f8700ee721587d56f70 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Wed, 21 Mar 2007 19:19:27 +0000 Subject: input: return an input error instead of forward it(from hcid). --- input/manager.c | 52 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 14 deletions(-) (limited to 'input/manager.c') diff --git a/input/manager.c b/input/manager.c index 2ad8948e..4a973023 100644 --- a/input/manager.c +++ b/input/manager.c @@ -266,8 +266,12 @@ static void hid_record_reply(DBusPendingCall *call, void *data) dbus_error_init(&derr); if (dbus_set_error_from_message(&derr, reply)) { - err_generic(pr->conn, pr->msg, derr.name, derr.message); - error("%s: %s", derr.name, derr.message); + if (dbus_error_has_name(&derr, "org.bluez.Error.ConnectionAttemptFailed")) + err_connection_failed(pr->conn, pr->msg, derr.message); + else + err_not_supported(pr->conn, pr->msg); + + error("GetRemoteServiceRecord failed: %s(%s)", derr.name, derr.message); goto fail; } @@ -329,8 +333,12 @@ static void hid_handle_reply(DBusPendingCall *call, void *data) dbus_error_init(&derr); if (dbus_set_error_from_message(&derr, reply)) { - err_generic(pr->conn, pr->msg, derr.name, derr.message); - error("%s: %s", derr.name, derr.message); + if (dbus_error_has_name(&derr, "org.bluez.Error.ConnectionAttemptFailed")) + err_connection_failed(pr->conn, pr->msg, derr.message); + else + err_not_supported(pr->conn, pr->msg); + + error("GetRemoteServiceHandles: %s(%s)", derr.name, derr.message); goto fail; } @@ -374,8 +382,12 @@ static void pnp_record_reply(DBusPendingCall *call, void *data) dbus_error_init(&derr); if (dbus_set_error_from_message(&derr, reply)) { - err_generic(pr->conn, pr->msg, derr.name, derr.message); - error("%s: %s", derr.name, derr.message); + if (dbus_error_has_name(&derr, "org.bluez.Error.ConnectionAttemptFailed")) + err_connection_failed(pr->conn, pr->msg, derr.message); + else + err_not_supported(pr->conn, pr->msg); + + error("GetRemoteServiceRecord: %s(%s)", derr.name, derr.message); goto fail; } @@ -421,8 +433,12 @@ static void pnp_handle_reply(DBusPendingCall *call, void *data) dbus_error_init(&derr); if (dbus_set_error_from_message(&derr, reply)) { - err_generic(pr->conn, pr->msg, derr.name, derr.message); - error("%s: %s", derr.name, derr.message); + if (dbus_error_has_name(&derr, "org.bluez.Error.ConnectionAttemptFailed")) + err_connection_failed(pr->conn, pr->msg, derr.message); + else + err_not_supported(pr->conn, pr->msg); + + error("GetRemoteServiceHandles: %s(%s)", derr.name, derr.message); goto fail; } @@ -477,8 +493,12 @@ static void headset_record_reply(DBusPendingCall *call, void *data) dbus_error_init(&derr); if (dbus_set_error_from_message(&derr, reply)) { - err_generic(pr->conn, pr->msg, derr.name, derr.message); - error("%s: %s", derr.name, derr.message); + if (dbus_error_has_name(&derr, "org.bluez.Error.ConnectionAttemptFailed")) + err_connection_failed(pr->conn, pr->msg, derr.message); + else + err_not_supported(pr->conn, pr->msg); + + error("GetRemoteServiceRecord: %s(%s)", derr.name, derr.message); goto fail; } @@ -551,8 +571,12 @@ static void headset_handle_reply(DBusPendingCall *call, void *data) dbus_error_init(&derr); if (dbus_set_error_from_message(&derr, reply)) { - err_generic(pr->conn, pr->msg, derr.name, derr.message); - error("%s: %s", derr.name, derr.message); + if (dbus_error_has_name(&derr, "org.bluez.Error.ConnectionAttemptFailed")) + err_connection_failed(pr->conn, pr->msg, derr.message); + else + err_not_supported(pr->conn, pr->msg); + + error("GetRemoteServiceHandles: %s(%s)", derr.name, derr.message); goto fail; } @@ -601,7 +625,7 @@ static DBusHandlerResult manager_create_device(DBusConnection *conn, if (!dbus_message_get_args(msg, &derr, DBUS_TYPE_STRING, &addr, DBUS_TYPE_INVALID)) { - err_generic(conn, msg, derr.name, derr.message); + err_invalid_args(conn, msg, derr.message); dbus_error_free(&derr); return DBUS_HANDLER_RESULT_HANDLED; } @@ -658,7 +682,7 @@ static DBusHandlerResult manager_remove_device(DBusConnection *conn, if (!dbus_message_get_args(msg, &derr, DBUS_TYPE_STRING, &path, DBUS_TYPE_INVALID)) { - err_generic(conn, msg, derr.name, derr.message); + err_invalid_args(conn, msg, derr.message); dbus_error_free(&derr); return DBUS_HANDLER_RESULT_HANDLED; } -- cgit From 07701210404d9bc7153af287cb58e7ea329fd8a8 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Thu, 22 Mar 2007 13:34:37 +0000 Subject: input: minor code standard fixes --- input/manager.c | 50 +++++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 25 deletions(-) (limited to 'input/manager.c') diff --git a/input/manager.c b/input/manager.c index 4a973023..2faef35d 100644 --- a/input/manager.c +++ b/input/manager.c @@ -61,7 +61,7 @@ struct pending_req { sdp_record_t *hid_rec; }; -struct input_manager { +struct manager { bdaddr_t src; /* Local adapter BT address */ GSList *paths; /* Input registered paths */ }; @@ -111,7 +111,7 @@ static void pending_req_free(struct pending_req *pr) static int path_bdaddr_cmp(const char *path, const bdaddr_t *bdaddr) { - struct input_device *idev; + struct device *idev; if (!dbus_connection_get_object_path_data(connection, path, (void *) &idev)) @@ -256,7 +256,7 @@ static void hid_record_reply(DBusPendingCall *call, void *data) { DBusMessage *reply = dbus_pending_call_steal_reply(call); DBusMessage *pr_reply; - struct input_manager *mgr; + struct manager *mgr; struct pending_req *pr = data; struct hidp_connadd_req hidp; DBusError derr; @@ -482,7 +482,7 @@ static void headset_record_reply(DBusPendingCall *call, void *data) DBusMessage *reply = dbus_pending_call_steal_reply(call); DBusMessage *pr_reply; DBusError derr; - struct input_manager *mgr; + struct manager *mgr; struct pending_req *pr = data; uint8_t *rec_bin; sdp_record_t *rec; @@ -610,10 +610,10 @@ done: dbus_pending_call_unref(call); } -static DBusHandlerResult manager_create_device(DBusConnection *conn, - DBusMessage *msg, void *data) +static DBusHandlerResult create_device(DBusConnection *conn, + DBusMessage *msg, void *data) { - struct input_manager *mgr = data; + struct manager *mgr = data; struct pending_req *pr; DBusError derr; const char *addr; @@ -668,11 +668,11 @@ static DBusHandlerResult manager_create_device(DBusConnection *conn, return DBUS_HANDLER_RESULT_HANDLED; } -static DBusHandlerResult manager_remove_device(DBusConnection *conn, - DBusMessage *msg, void *data) +static DBusHandlerResult remove_device(DBusConnection *conn, + DBusMessage *msg, void *data) { - struct input_manager *mgr = data; - struct input_device *idev; + struct manager *mgr = data; + struct device *idev; DBusMessage *reply; DBusError derr; GSList *l; @@ -711,10 +711,10 @@ static DBusHandlerResult manager_remove_device(DBusConnection *conn, return send_message_and_unref(conn, reply); } -static DBusHandlerResult manager_list_devices(DBusConnection *conn, - DBusMessage *msg, void *data) +static DBusHandlerResult list_devices(DBusConnection *conn, + DBusMessage *msg, void *data) { - struct input_manager *mgr = data; + struct manager *mgr = data; DBusMessageIter iter, iter_array; DBusMessage *reply; GSList *paths; @@ -755,18 +755,18 @@ static DBusHandlerResult manager_message(DBusConnection *conn, return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; if (strcmp(member, "ListDevices") == 0) - return manager_list_devices(conn, msg, data); + return list_devices(conn, msg, data); if (strcmp(member, "CreateDevice") == 0) - return manager_create_device(conn, msg, data); + return create_device(conn, msg, data); if (strcmp(member, "RemoveDevice") == 0) - return manager_remove_device(conn, msg, data); + return remove_device(conn, msg, data); return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } -static void input_manager_free(struct input_manager *mgr) +static void manager_free(struct manager *mgr) { if (!mgr) return; @@ -781,11 +781,11 @@ static void input_manager_free(struct input_manager *mgr) static void manager_unregister(DBusConnection *conn, void *data) { - struct input_manager *mgr = data; + struct manager *mgr = data; info("Unregistered manager path"); - input_manager_free(mgr); + manager_free(mgr); } /* Virtual table to handle manager object path hierarchy */ @@ -800,7 +800,7 @@ static const DBusObjectPathVTable manager_table = { static void stored_input(char *key, char *value, void *data) { - struct input_manager *mgr = data; + struct manager *mgr = data; const char *path; struct hidp_connadd_req hidp; bdaddr_t dst; @@ -818,7 +818,7 @@ static void stored_input(char *key, char *value, void *data) mgr->paths = g_slist_append(mgr->paths, g_strdup(path)); } -static int register_stored_inputs(struct input_manager *mgr) +static int register_stored_inputs(struct manager *mgr) { char filename[PATH_MAX + 1]; char addr[18]; @@ -832,7 +832,7 @@ static int register_stored_inputs(struct input_manager *mgr) int input_init(void) { - struct input_manager *mgr; + struct manager *mgr; bdaddr_t src; int dev_id; @@ -842,7 +842,7 @@ int input_init(void) dbus_connection_set_exit_on_disconnect(connection, TRUE); - mgr = g_new0(struct input_manager, 1); + mgr = g_new0(struct manager, 1); /* Fallback to catch invalid device path */ if (!dbus_connection_register_fallback(connection, INPUT_PATH, @@ -873,7 +873,7 @@ int input_init(void) return 0; fail: - input_manager_free(mgr); + manager_free(mgr); return -1; } -- cgit From 40ebcf393b790a4e6553e1314b29f0f34b3377a3 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 27 Mar 2007 10:27:01 +0000 Subject: Improve integration with D-Bus system bus --- input/manager.c | 36 +++--------------------------------- 1 file changed, 3 insertions(+), 33 deletions(-) (limited to 'input/manager.c') diff --git a/input/manager.c b/input/manager.c index 2faef35d..a4269df3 100644 --- a/input/manager.c +++ b/input/manager.c @@ -830,15 +830,13 @@ static int register_stored_inputs(struct manager *mgr) return 0; } -int input_init(void) +int input_init(DBusConnection *conn) { struct manager *mgr; bdaddr_t src; int dev_id; - connection = init_dbus(NULL, NULL, NULL); - if (!connection) - return -1; + connection = dbus_connection_ref(conn); dbus_connection_set_exit_on_disconnect(connection, TRUE); @@ -883,34 +881,6 @@ void input_exit(void) dbus_connection_unregister_object_path(connection, INPUT_PATH); dbus_connection_unref(connection); -} - -void internal_service(const char *identifier) -{ - DBusMessage *msg, *reply; - const char *name = "Input Service Debug", *desc = ""; - - info("Registering service"); - - msg = dbus_message_new_method_call("org.bluez", "/org/bluez", - "org.bluez.Database", "RegisterService"); - if (!msg) { - error("Can't create service register method"); - return; - } - - dbus_message_append_args(msg, DBUS_TYPE_STRING, &identifier, - DBUS_TYPE_STRING, &name, - DBUS_TYPE_STRING, &desc, DBUS_TYPE_INVALID); - - reply = dbus_connection_send_with_reply_and_block(connection, msg, -1, NULL); - if (!reply) { - error("Can't register service"); - return; - } - - dbus_message_unref(msg); - dbus_message_unref(reply); - dbus_connection_flush(connection); + connection = NULL; } -- cgit From 9691f47c9f858b4ae512e6d3b78bd1bb398bec06 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 27 Mar 2007 10:40:42 +0000 Subject: Service must start even if there is no adapter available --- input/manager.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'input/manager.c') diff --git a/input/manager.c b/input/manager.c index a4269df3..7a8ce746 100644 --- a/input/manager.c +++ b/input/manager.c @@ -834,7 +834,9 @@ int input_init(DBusConnection *conn) { struct manager *mgr; bdaddr_t src; +#if 0 int dev_id; +#endif connection = dbus_connection_ref(conn); @@ -853,6 +855,7 @@ int input_init(DBusConnection *conn) /* Set the default adapter */ bacpy(&src, BDADDR_ANY); +#if 0 dev_id = hci_get_route(&src); if (dev_id < 0) { error("Bluetooth device not available"); @@ -863,6 +866,7 @@ int input_init(DBusConnection *conn) error("Can't get local adapter device info"); goto fail; } +#endif bacpy(&mgr->src, &src); /* Register well known HID devices */ -- cgit From 1826edb5d4e3998ba026d2d0436bbbae9047ed3a Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Wed, 4 Apr 2007 21:36:45 +0000 Subject: input: Added authorization support for incomming connections --- input/manager.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'input/manager.c') diff --git a/input/manager.c b/input/manager.c index 7a8ce746..567ea6ee 100644 --- a/input/manager.c +++ b/input/manager.c @@ -43,6 +43,7 @@ #include "textfile.h" #include "device.h" +#include "server.h" #include "error.h" #include "manager.h" #include "storage.h" @@ -872,6 +873,8 @@ int input_init(DBusConnection *conn) /* Register well known HID devices */ register_stored_inputs(mgr); + server_start(connection); + return 0; fail: @@ -884,6 +887,8 @@ void input_exit(void) { dbus_connection_unregister_object_path(connection, INPUT_PATH); + server_stop(); + dbus_connection_unref(connection); connection = NULL; -- cgit From 15746ba2445be8a8952263d829d5363e27690ea4 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Wed, 11 Apr 2007 16:00:33 +0000 Subject: input manager: use the default adapter to create a new device. --- input/manager.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'input/manager.c') diff --git a/input/manager.c b/input/manager.c index 567ea6ee..11aa65a4 100644 --- a/input/manager.c +++ b/input/manager.c @@ -619,8 +619,9 @@ static DBusHandlerResult create_device(DBusConnection *conn, DBusError derr; const char *addr; GSList *l; - bdaddr_t dst; + bdaddr_t src, dst; uint32_t cls = 0; + int dev_id; dbus_error_init(&derr); if (!dbus_message_get_args(msg, &derr, @@ -631,6 +632,18 @@ static DBusHandlerResult create_device(DBusConnection *conn, return DBUS_HANDLER_RESULT_HANDLED; } + /* Get the default adapter */ + dev_id = hci_get_route(NULL); + if (dev_id < 0) { + error("Bluetooth adapter not available"); + return err_failed(conn, msg, "Adapter not available"); + } + + if (hci_devba(dev_id, &src) < 0) { + error("Can't get local adapter device info"); + return err_failed(conn, msg, "Adapter not available"); + } + str2ba(addr, &dst); l = g_slist_find_custom(mgr->paths, &dst, @@ -638,12 +651,12 @@ static DBusHandlerResult create_device(DBusConnection *conn, if (l) return err_already_exists(conn, msg, "Input Already exists"); - if (read_device_class(&mgr->src, &dst, &cls) < 0) { + if (read_device_class(&src, &dst, &cls) < 0) { error("Device class not available"); return err_not_supported(conn, msg); } - pr = pending_req_new(conn, msg, &mgr->src, &dst); + pr = pending_req_new(conn, msg, &src, &dst); if (!pr) return DBUS_HANDLER_RESULT_NEED_MEMORY; -- cgit From 56943b11d7ab291467d8e7fa4551cd1f21b09402 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Wed, 11 Apr 2007 16:10:07 +0000 Subject: input manager: delete the stored input info based on the input device source/destination address --- input/manager.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'input/manager.c') diff --git a/input/manager.c b/input/manager.c index 11aa65a4..075d82d1 100644 --- a/input/manager.c +++ b/input/manager.c @@ -715,7 +715,7 @@ static DBusHandlerResult remove_device(DBusConnection *conn, if (!dbus_connection_get_object_path_data(connection, path, (void *) &idev)) return err_does_not_exist(conn, msg, "Input doesn't exist"); - del_stored_device_info(&mgr->src, &idev->dst); + del_stored_device_info(&idev->src, &idev->dst); if (input_device_unregister(conn, path) < 0) { dbus_message_unref(reply); -- cgit From fcaa89e46ffa24f02bea8c5942733a3ab738457c Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Wed, 11 Apr 2007 18:39:15 +0000 Subject: input manager: read all /var/lib/bluetooth/*/input files when the service starts --- input/manager.c | 64 ++++++++++++++++++++++++++++++++------------------------- 1 file changed, 36 insertions(+), 28 deletions(-) (limited to 'input/manager.c') diff --git a/input/manager.c b/input/manager.c index 075d82d1..6053de65 100644 --- a/input/manager.c +++ b/input/manager.c @@ -25,6 +25,8 @@ #include #endif +#include +#include #include #include @@ -63,8 +65,8 @@ struct pending_req { }; struct manager { - bdaddr_t src; /* Local adapter BT address */ - GSList *paths; /* Input registered paths */ + bdaddr_t src; + GSList *paths; /* Input registered paths */ }; static DBusConnection *connection = NULL; @@ -826,31 +828,53 @@ static void stored_input(char *key, char *value, void *data) return; } + /* FIXME: Ignore already registered devices */ if (input_device_register(connection, &mgr->src, &dst, &hidp, &path) < 0) return; mgr->paths = g_slist_append(mgr->paths, g_strdup(path)); } -static int register_stored_inputs(struct manager *mgr) +static void register_stored_inputs(struct manager *mgr) { + char dirname[PATH_MAX + 1]; char filename[PATH_MAX + 1]; - char addr[18]; + struct dirent *de; + DIR *dir; + int dev_id; - ba2str(&mgr->src, addr); - create_name(filename, PATH_MAX, STORAGEDIR, addr, "input"); - textfile_foreach(filename, stored_input, mgr); + dev_id = hci_get_route(BDADDR_ANY); + if (dev_id < 0) { + error("Bluetooth device not available"); + return; + } - return 0; + if (hci_devba(dev_id, &mgr->src) < 0) { + error("Can't get local adapter device info"); + return; + } + + snprintf(dirname, PATH_MAX, "%s", STORAGEDIR); + + dir = opendir(dirname); + if (!dir) + return; + + while ((de = readdir(dir)) != NULL) { + if (!isdigit(de->d_name[0])) + continue; + + create_name(filename, PATH_MAX, STORAGEDIR, + de->d_name, "input"); + textfile_foreach(filename, stored_input, mgr); + } + + closedir(dir); } int input_init(DBusConnection *conn) { struct manager *mgr; - bdaddr_t src; -#if 0 - int dev_id; -#endif connection = dbus_connection_ref(conn); @@ -867,22 +891,6 @@ int input_init(DBusConnection *conn) info("Registered input manager path:%s", INPUT_PATH); - /* Set the default adapter */ - bacpy(&src, BDADDR_ANY); -#if 0 - dev_id = hci_get_route(&src); - if (dev_id < 0) { - error("Bluetooth device not available"); - goto fail; - } - - if (hci_devba(dev_id, &src) < 0) { - error("Can't get local adapter device info"); - goto fail; - } -#endif - - bacpy(&mgr->src, &src); /* Register well known HID devices */ register_stored_inputs(mgr); -- cgit From b950614676315d8e180f02ad5eee8da505e18f44 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Wed, 11 Apr 2007 18:58:10 +0000 Subject: input manager: fixed code standard --- input/manager.c | 63 ++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 38 insertions(+), 25 deletions(-) (limited to 'input/manager.c') diff --git a/input/manager.c b/input/manager.c index 6053de65..61719c05 100644 --- a/input/manager.c +++ b/input/manager.c @@ -50,18 +50,18 @@ #include "manager.h" #include "storage.h" -const char *pnp_uuid = "00001200-0000-1000-8000-00805f9b34fb"; -const char *hid_uuid = "00001124-0000-1000-8000-00805f9b34fb"; -const char *headset_uuid = "00001108-0000-1000-8000-00805f9b34fb"; +const char *pnp_uuid = "00001200-0000-1000-8000-00805f9b34fb"; +const char *hid_uuid = "00001124-0000-1000-8000-00805f9b34fb"; +const char *headset_uuid = "00001108-0000-1000-8000-00805f9b34fb"; struct pending_req { - char *adapter_path; /* Local adapter D-Bus path */ - bdaddr_t src; /* Local adapter BT address */ - bdaddr_t dst; /* Peer BT address */ - DBusConnection *conn; - DBusMessage *msg; - sdp_record_t *pnp_rec; - sdp_record_t *hid_rec; + char *adapter_path; /* Local adapter D-Bus path */ + bdaddr_t src; /* Local adapter BT address */ + bdaddr_t dst; /* Peer BT address */ + DBusConnection *conn; + DBusMessage *msg; + sdp_record_t *pnp_rec; + sdp_record_t *hid_rec; }; struct manager { @@ -71,8 +71,8 @@ struct manager { static DBusConnection *connection = NULL; -static struct pending_req *pending_req_new(DBusConnection *conn, DBusMessage *msg, - bdaddr_t *src, bdaddr_t *dst) +static struct pending_req *pending_req_new(DBusConnection *conn, + DBusMessage *msg, bdaddr_t *src, bdaddr_t *dst) { char adapter[18], adapter_path[32]; struct pending_req *pr; @@ -269,12 +269,14 @@ static void hid_record_reply(DBusPendingCall *call, void *data) dbus_error_init(&derr); if (dbus_set_error_from_message(&derr, reply)) { - if (dbus_error_has_name(&derr, "org.bluez.Error.ConnectionAttemptFailed")) + if (dbus_error_has_name(&derr, + "org.bluez.Error.ConnectionAttemptFailed")) err_connection_failed(pr->conn, pr->msg, derr.message); else err_not_supported(pr->conn, pr->msg); - error("GetRemoteServiceRecord failed: %s(%s)", derr.name, derr.message); + error("GetRemoteServiceRecord failed: %s(%s)", + derr.name, derr.message); goto fail; } @@ -336,12 +338,14 @@ static void hid_handle_reply(DBusPendingCall *call, void *data) dbus_error_init(&derr); if (dbus_set_error_from_message(&derr, reply)) { - if (dbus_error_has_name(&derr, "org.bluez.Error.ConnectionAttemptFailed")) + if (dbus_error_has_name(&derr, + "org.bluez.Error.ConnectionAttemptFailed")) err_connection_failed(pr->conn, pr->msg, derr.message); else err_not_supported(pr->conn, pr->msg); - error("GetRemoteServiceHandles: %s(%s)", derr.name, derr.message); + error("GetRemoteServiceHandles: %s(%s)", + derr.name, derr.message); goto fail; } @@ -385,12 +389,14 @@ static void pnp_record_reply(DBusPendingCall *call, void *data) dbus_error_init(&derr); if (dbus_set_error_from_message(&derr, reply)) { - if (dbus_error_has_name(&derr, "org.bluez.Error.ConnectionAttemptFailed")) + if (dbus_error_has_name(&derr, + "org.bluez.Error.ConnectionAttemptFailed")) err_connection_failed(pr->conn, pr->msg, derr.message); else err_not_supported(pr->conn, pr->msg); - error("GetRemoteServiceRecord: %s(%s)", derr.name, derr.message); + error("GetRemoteServiceRecord: %s(%s)", + derr.name, derr.message); goto fail; } @@ -436,12 +442,14 @@ static void pnp_handle_reply(DBusPendingCall *call, void *data) dbus_error_init(&derr); if (dbus_set_error_from_message(&derr, reply)) { - if (dbus_error_has_name(&derr, "org.bluez.Error.ConnectionAttemptFailed")) + if (dbus_error_has_name(&derr, + "org.bluez.Error.ConnectionAttemptFailed")) err_connection_failed(pr->conn, pr->msg, derr.message); else err_not_supported(pr->conn, pr->msg); - error("GetRemoteServiceHandles: %s(%s)", derr.name, derr.message); + error("GetRemoteServiceHandles: %s(%s)", + derr.name, derr.message); goto fail; } @@ -496,12 +504,14 @@ static void headset_record_reply(DBusPendingCall *call, void *data) dbus_error_init(&derr); if (dbus_set_error_from_message(&derr, reply)) { - if (dbus_error_has_name(&derr, "org.bluez.Error.ConnectionAttemptFailed")) + if (dbus_error_has_name(&derr, + "org.bluez.Error.ConnectionAttemptFailed")) err_connection_failed(pr->conn, pr->msg, derr.message); else err_not_supported(pr->conn, pr->msg); - error("GetRemoteServiceRecord: %s(%s)", derr.name, derr.message); + error("GetRemoteServiceRecord: %s(%s)", + derr.name, derr.message); goto fail; } @@ -574,12 +584,14 @@ static void headset_handle_reply(DBusPendingCall *call, void *data) dbus_error_init(&derr); if (dbus_set_error_from_message(&derr, reply)) { - if (dbus_error_has_name(&derr, "org.bluez.Error.ConnectionAttemptFailed")) + if (dbus_error_has_name(&derr, + "org.bluez.Error.ConnectionAttemptFailed")) err_connection_failed(pr->conn, pr->msg, derr.message); else err_not_supported(pr->conn, pr->msg); - error("GetRemoteServiceHandles: %s(%s)", derr.name, derr.message); + error("GetRemoteServiceHandles: %s(%s)", + derr.name, derr.message); goto fail; } @@ -714,7 +726,8 @@ static DBusHandlerResult remove_device(DBusConnection *conn, g_free(l->data); mgr->paths = g_slist_remove(mgr->paths, l->data); - if (!dbus_connection_get_object_path_data(connection, path, (void *) &idev)) + if (!dbus_connection_get_object_path_data(connection, + path, (void *) &idev)) return err_does_not_exist(conn, msg, "Input doesn't exist"); del_stored_device_info(&idev->src, &idev->dst); -- cgit From 94a49f14f2be23349b65f353daa1d20bb9cfc8cf Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 11 Apr 2007 20:25:40 +0000 Subject: Use global device list for manager --- input/manager.c | 129 ++++++++++++++++++++++++-------------------------------- 1 file changed, 54 insertions(+), 75 deletions(-) (limited to 'input/manager.c') diff --git a/input/manager.c b/input/manager.c index 61719c05..d55699ee 100644 --- a/input/manager.c +++ b/input/manager.c @@ -50,9 +50,9 @@ #include "manager.h" #include "storage.h" -const char *pnp_uuid = "00001200-0000-1000-8000-00805f9b34fb"; -const char *hid_uuid = "00001124-0000-1000-8000-00805f9b34fb"; -const char *headset_uuid = "00001108-0000-1000-8000-00805f9b34fb"; +static const char *pnp_uuid = "00001200-0000-1000-8000-00805f9b34fb"; +static const char *hid_uuid = "00001124-0000-1000-8000-00805f9b34fb"; +static const char *headset_uuid = "00001108-0000-1000-8000-00805f9b34fb"; struct pending_req { char *adapter_path; /* Local adapter D-Bus path */ @@ -64,10 +64,7 @@ struct pending_req { sdp_record_t *hid_rec; }; -struct manager { - bdaddr_t src; - GSList *paths; /* Input registered paths */ -}; +static GSList *device_paths = NULL; /* Input registered paths */ static DBusConnection *connection = NULL; @@ -99,16 +96,22 @@ static void pending_req_free(struct pending_req *pr) { if (!pr) return; + if (pr->adapter_path) g_free(pr->adapter_path); + if (pr->conn) dbus_connection_unref(pr->conn); + if (pr->msg) dbus_message_unref(pr->msg); + if (pr->pnp_rec) sdp_record_free(pr->pnp_rec); + if (pr->hid_rec) sdp_record_free(pr->hid_rec); + g_free(pr); } @@ -235,7 +238,8 @@ static void extract_hid_record(sdp_record_t *rec, struct hidp_connadd_req *req) req->rd_data = g_try_malloc0(pdlist->unitSize); if (req->rd_data) { - memcpy(req->rd_data, (unsigned char *) pdlist->val.str, pdlist->unitSize); + memcpy(req->rd_data, (unsigned char *) pdlist->val.str, + pdlist->unitSize); req->rd_size = pdlist->unitSize; } } @@ -259,7 +263,6 @@ static void hid_record_reply(DBusPendingCall *call, void *data) { DBusMessage *reply = dbus_pending_call_steal_reply(call); DBusMessage *pr_reply; - struct manager *mgr; struct pending_req *pr = data; struct hidp_connadd_req hidp; DBusError derr; @@ -313,14 +316,16 @@ static void hid_record_reply(DBusPendingCall *call, void *data) goto fail; } - dbus_connection_get_object_path_data(pr->conn, INPUT_PATH, (void *) &mgr); - mgr->paths = g_slist_append(mgr->paths, g_strdup(path)); + device_paths = g_slist_append(device_paths, g_strdup(path)); pr_reply = dbus_message_new_method_return(pr->msg); + dbus_message_append_args(pr_reply, - DBUS_TYPE_STRING, &path, - DBUS_TYPE_INVALID); + DBUS_TYPE_STRING, &path, + DBUS_TYPE_INVALID); + send_message_and_unref(pr->conn, pr_reply); + fail: dbus_error_free(&derr); pending_req_free(pr); @@ -371,9 +376,11 @@ static void hid_handle_reply(DBusPendingCall *call, void *data) /* Wait record reply */ goto done; } + fail: dbus_error_free(&derr); pending_req_free(pr); + done: dbus_message_unref(reply); dbus_pending_call_unref(call); @@ -427,6 +434,7 @@ static void pnp_record_reply(DBusPendingCall *call, void *data) fail: dbus_error_free(&derr); pending_req_free(pr); + done: dbus_message_unref(reply); dbus_pending_call_unref(call); @@ -483,6 +491,7 @@ static void pnp_handle_reply(DBusPendingCall *call, void *data) fail: dbus_error_free(&derr); pending_req_free(pr); + done: dbus_message_unref(reply); dbus_pending_call_unref(call); @@ -493,7 +502,6 @@ static void headset_record_reply(DBusPendingCall *call, void *data) DBusMessage *reply = dbus_pending_call_steal_reply(call); DBusMessage *pr_reply; DBusError derr; - struct manager *mgr; struct pending_req *pr = data; uint8_t *rec_bin; sdp_record_t *rec; @@ -541,7 +549,7 @@ static void headset_record_reply(DBusPendingCall *call, void *data) } ch = sdp_get_proto_port(protos, RFCOMM_UUID); - sdp_list_foreach(protos, (sdp_list_func_t)sdp_list_free, NULL); + sdp_list_foreach(protos, (sdp_list_func_t) sdp_list_free, NULL); sdp_list_free(protos, NULL); sdp_record_free(rec); @@ -559,14 +567,16 @@ static void headset_record_reply(DBusPendingCall *call, void *data) goto fail; } - dbus_connection_get_object_path_data(pr->conn, INPUT_PATH, (void *) &mgr); - mgr->paths = g_slist_append(mgr->paths, g_strdup(path)); + device_paths = g_slist_append(device_paths, g_strdup(path)); pr_reply = dbus_message_new_method_return(pr->msg); + dbus_message_append_args(pr_reply, DBUS_TYPE_STRING, &path, DBUS_TYPE_INVALID); + send_message_and_unref(pr->conn, pr_reply); + fail: dbus_error_free(&derr); pending_req_free(pr); @@ -617,9 +627,11 @@ static void headset_handle_reply(DBusPendingCall *call, void *data) /* Wait record reply */ goto done; } + fail: dbus_error_free(&derr); pending_req_free(pr); + done: dbus_message_unref(reply); dbus_pending_call_unref(call); @@ -628,7 +640,6 @@ done: static DBusHandlerResult create_device(DBusConnection *conn, DBusMessage *msg, void *data) { - struct manager *mgr = data; struct pending_req *pr; DBusError derr; const char *addr; @@ -660,8 +671,8 @@ static DBusHandlerResult create_device(DBusConnection *conn, str2ba(addr, &dst); - l = g_slist_find_custom(mgr->paths, &dst, - (GCompareFunc) path_bdaddr_cmp); + l = g_slist_find_custom(device_paths, &dst, + (GCompareFunc) path_bdaddr_cmp); if (l) return err_already_exists(conn, msg, "Input Already exists"); @@ -699,7 +710,6 @@ static DBusHandlerResult create_device(DBusConnection *conn, static DBusHandlerResult remove_device(DBusConnection *conn, DBusMessage *msg, void *data) { - struct manager *mgr = data; struct device *idev; DBusMessage *reply; DBusError derr; @@ -715,7 +725,7 @@ static DBusHandlerResult remove_device(DBusConnection *conn, return DBUS_HANDLER_RESULT_HANDLED; } - l = g_slist_find_custom(mgr->paths, path, (GCompareFunc) strcmp); + l = g_slist_find_custom(device_paths, path, (GCompareFunc) strcmp); if (!l) return err_does_not_exist(conn, msg, "Input doesn't exist"); @@ -724,7 +734,7 @@ static DBusHandlerResult remove_device(DBusConnection *conn, return DBUS_HANDLER_RESULT_NEED_MEMORY; g_free(l->data); - mgr->paths = g_slist_remove(mgr->paths, l->data); + device_paths = g_slist_remove(device_paths, l->data); if (!dbus_connection_get_object_path_data(connection, path, (void *) &idev)) @@ -743,7 +753,6 @@ static DBusHandlerResult remove_device(DBusConnection *conn, static DBusHandlerResult list_devices(DBusConnection *conn, DBusMessage *msg, void *data) { - struct manager *mgr = data; DBusMessageIter iter, iter_array; DBusMessage *reply; GSList *paths; @@ -756,16 +765,17 @@ static DBusHandlerResult list_devices(DBusConnection *conn, dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING_AS_STRING, &iter_array); - for (paths = mgr->paths; paths != NULL; paths = paths->next) { + for (paths = device_paths; paths != NULL; paths = paths->next) { const char *ppath = paths->data; dbus_message_iter_append_basic(&iter_array, - DBUS_TYPE_STRING, &ppath); + DBUS_TYPE_STRING, &ppath); } dbus_message_iter_close_container(&iter, &iter_array); return send_message_and_unref(conn, reply); } + static DBusHandlerResult manager_message(DBusConnection *conn, DBusMessage *msg, void *data) { @@ -795,26 +805,13 @@ static DBusHandlerResult manager_message(DBusConnection *conn, return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } -static void manager_free(struct manager *mgr) -{ - if (!mgr) - return; - - if (mgr->paths) { - g_slist_foreach(mgr->paths, (GFunc) free, NULL); - g_slist_free(mgr->paths); - } - - g_free(mgr); -} - static void manager_unregister(DBusConnection *conn, void *data) { - struct manager *mgr = data; - info("Unregistered manager path"); - manager_free(mgr); + g_slist_foreach(device_paths, (GFunc) free, NULL); + + g_slist_free(device_paths); } /* Virtual table to handle manager object path hierarchy */ @@ -829,43 +826,31 @@ static const DBusObjectPathVTable manager_table = { static void stored_input(char *key, char *value, void *data) { - struct manager *mgr = data; const char *path; struct hidp_connadd_req hidp; - bdaddr_t dst; + bdaddr_t dst, *src = data; str2ba(key, &dst); memset(&hidp, 0, sizeof(struct hidp_connadd_req)); - if (parse_stored_device_info(value, &hidp) < 0) { + + if (parse_stored_device_info(value, &hidp) < 0) return; - } /* FIXME: Ignore already registered devices */ - if (input_device_register(connection, &mgr->src, &dst, &hidp, &path) < 0) + if (input_device_register(connection, src, &dst, &hidp, &path) < 0) return; - mgr->paths = g_slist_append(mgr->paths, g_strdup(path)); + device_paths = g_slist_append(device_paths, g_strdup(path)); } -static void register_stored_inputs(struct manager *mgr) +static void register_stored_inputs(void) { char dirname[PATH_MAX + 1]; char filename[PATH_MAX + 1]; struct dirent *de; DIR *dir; - int dev_id; - - dev_id = hci_get_route(BDADDR_ANY); - if (dev_id < 0) { - error("Bluetooth device not available"); - return; - } - - if (hci_devba(dev_id, &mgr->src) < 0) { - error("Can't get local adapter device info"); - return; - } + bdaddr_t src; snprintf(dirname, PATH_MAX, "%s", STORAGEDIR); @@ -878,8 +863,11 @@ static void register_stored_inputs(struct manager *mgr) continue; create_name(filename, PATH_MAX, STORAGEDIR, - de->d_name, "input"); - textfile_foreach(filename, stored_input, mgr); + de->d_name, "input"); + + str2ba(de->d_name, &src); + + textfile_foreach(filename, stored_input, &src); } closedir(dir); @@ -887,34 +875,25 @@ static void register_stored_inputs(struct manager *mgr) int input_init(DBusConnection *conn) { - struct manager *mgr; - connection = dbus_connection_ref(conn); dbus_connection_set_exit_on_disconnect(connection, TRUE); - mgr = g_new0(struct manager, 1); - /* Fallback to catch invalid device path */ if (!dbus_connection_register_fallback(connection, INPUT_PATH, - &manager_table, mgr)) { + &manager_table, NULL)) { error("D-Bus failed to register %s path", INPUT_PATH); - goto fail; + return -1; } info("Registered input manager path:%s", INPUT_PATH); /* Register well known HID devices */ - register_stored_inputs(mgr); + register_stored_inputs(); server_start(connection); return 0; - -fail: - manager_free(mgr); - - return -1; } void input_exit(void) -- cgit From eca0800a92771ee23890fdf54a70629bcbca648c Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Wed, 11 Apr 2007 21:18:27 +0000 Subject: fixed commentary --- input/manager.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'input/manager.c') diff --git a/input/manager.c b/input/manager.c index d55699ee..bd75dc5a 100644 --- a/input/manager.c +++ b/input/manager.c @@ -837,7 +837,10 @@ static void stored_input(char *key, char *value, void *data) if (parse_stored_device_info(value, &hidp) < 0) return; - /* FIXME: Ignore already registered devices */ + /* + * Repeated entries for the same remote device are + * acceptable since the source is different. + */ if (input_device_register(connection, src, &dst, &hidp, &path) < 0) return; -- cgit From e3aec1dd412fc0adb0587edf750979e4d18906b0 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 12 Apr 2007 09:59:15 +0000 Subject: Keep the device structure local --- input/manager.c | 31 ++++++++++--------------------- 1 file changed, 10 insertions(+), 21 deletions(-) (limited to 'input/manager.c') diff --git a/input/manager.c b/input/manager.c index bd75dc5a..f74349df 100644 --- a/input/manager.c +++ b/input/manager.c @@ -115,20 +115,6 @@ static void pending_req_free(struct pending_req *pr) g_free(pr); } -static int path_bdaddr_cmp(const char *path, const bdaddr_t *bdaddr) -{ - struct device *idev; - - if (!dbus_connection_get_object_path_data(connection, path, - (void *) &idev)) - return -1; - - if (!idev) - return -1; - - return bacmp(&idev->dst, bdaddr); -} - static int get_record(struct pending_req *pr, uint32_t handle, DBusPendingCallNotifyFunction cb) { @@ -637,6 +623,16 @@ done: dbus_pending_call_unref(call); } +static int path_bdaddr_cmp(const char *path, const bdaddr_t *bdaddr) +{ + bdaddr_t src, dst; + + if (input_device_get_bdaddr(connection, path, &src, &dst) < 0) + return -1; + + return bacmp(&dst, bdaddr); +} + static DBusHandlerResult create_device(DBusConnection *conn, DBusMessage *msg, void *data) { @@ -710,7 +706,6 @@ static DBusHandlerResult create_device(DBusConnection *conn, static DBusHandlerResult remove_device(DBusConnection *conn, DBusMessage *msg, void *data) { - struct device *idev; DBusMessage *reply; DBusError derr; GSList *l; @@ -736,12 +731,6 @@ static DBusHandlerResult remove_device(DBusConnection *conn, g_free(l->data); device_paths = g_slist_remove(device_paths, l->data); - if (!dbus_connection_get_object_path_data(connection, - path, (void *) &idev)) - return err_does_not_exist(conn, msg, "Input doesn't exist"); - - del_stored_device_info(&idev->src, &idev->dst); - if (input_device_unregister(conn, path) < 0) { dbus_message_unref(reply); return err_failed(conn, msg, "D-Bus path unregistration failed"); -- cgit From 4f32f865517ba5c6a65550d39504a44065b9d013 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Tue, 17 Apr 2007 13:22:58 +0000 Subject: input: Connect/disconnect to the control and interrupt psm at the ending of CreateDevice --- input/manager.c | 174 ++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 151 insertions(+), 23 deletions(-) (limited to 'input/manager.c') diff --git a/input/manager.c b/input/manager.c index f74349df..d339c007 100644 --- a/input/manager.c +++ b/input/manager.c @@ -27,7 +27,9 @@ #include #include +#include #include +#include #include #include @@ -62,6 +64,7 @@ struct pending_req { DBusMessage *msg; sdp_record_t *pnp_rec; sdp_record_t *hid_rec; + int ctrl_sock; }; static GSList *device_paths = NULL; /* Input registered paths */ @@ -245,15 +248,151 @@ static void extract_pnp_record(sdp_record_t *rec, struct hidp_connadd_req *req) req->version = pdlist ? pdlist->val.uint16 : 0x0000; } +static gboolean interrupt_connect_cb(GIOChannel *chan, + GIOCondition cond, struct pending_req *pr) +{ + struct hidp_connadd_req hidp; + DBusMessage *reply; + const char *path; + int isk, ret, err; + socklen_t len; + + if (cond & G_IO_NVAL) { + err = EHOSTDOWN; + isk = -1; + goto failed; + } + + if (cond & (G_IO_HUP | G_IO_ERR)) { + err = EINTR; + isk = -1; + error("Hangup or error on HIDP interrupt socket"); + goto failed; + + } + + isk = g_io_channel_unix_get_fd(chan); + + len = sizeof(ret); + if (getsockopt(isk, SOL_SOCKET, SO_ERROR, &ret, &len) < 0) { + err = errno; + error("getsockopt(SO_ERROR): %s (%d)", strerror(err), err); + goto failed; + } + + if (ret != 0) { + err = ret; + error("connect(): %s (%d)", strerror(ret), ret); + goto failed; + } + + + memset(&hidp, 0, sizeof(struct hidp_connadd_req)); + extract_hid_record(pr->hid_rec, &hidp); + if (pr->pnp_rec) + extract_pnp_record(pr->pnp_rec, &hidp); + + store_device_info(&pr->src, &pr->dst, &hidp); + + if (input_device_register(pr->conn, &pr->src, + &pr->dst, &hidp, &path) < 0) { + err_failed(pr->conn, pr->msg, "path registration failed"); + goto cleanup; + } + + device_paths = g_slist_append(device_paths, g_strdup(path)); + + /* Replying to the requestor */ + reply = dbus_message_new_method_return(pr->msg); + + dbus_message_append_args(reply, + DBUS_TYPE_STRING, &path, + DBUS_TYPE_INVALID); + + send_message_and_unref(pr->conn, reply); + + goto cleanup; +failed: + err_connection_failed(pr->conn, pr->msg, strerror(err)); + +cleanup: + if (isk > 0) + close(isk); + + close(pr->ctrl_sock); + pending_req_free(pr); + g_io_channel_unref(chan); + + return FALSE; +} + +static gboolean control_connect_cb(GIOChannel *chan, + GIOCondition cond, struct pending_req *pr) +{ + int ret, csk, err; + socklen_t len; + + if (cond & G_IO_NVAL) { + err = EHOSTDOWN; + csk = -1; + goto failed; + } + + if (cond & (G_IO_HUP | G_IO_ERR)) { + err = EINTR; + csk = -1; + error("Hangup or error on HIDP control socket"); + goto failed; + + } + + csk = g_io_channel_unix_get_fd(chan); + /* Set HID control channel */ + pr->ctrl_sock = csk; + + len = sizeof(ret); + if (getsockopt(csk, SOL_SOCKET, SO_ERROR, &ret, &len) < 0) { + err = errno; + error("getsockopt(SO_ERROR): %s (%d)", strerror(err), err); + goto failed; + } + + if (ret != 0) { + err = ret; + error("connect(): %s (%d)", strerror(ret), ret); + goto failed; + } + + /* Connect to the HID interrupt channel */ + if (l2cap_connect(&pr->src, &pr->dst, L2CAP_PSM_HIDP_INTR, + (GIOFunc) interrupt_connect_cb, pr) < 0) { + + err = errno; + error("L2CAP connect failed:%s (%d)", strerror(errno), errno); + goto failed; + } + + g_io_channel_unref(chan); + return FALSE; + +failed: + if (csk > 0) + close(csk); + + err_connection_failed(pr->conn, pr->msg, strerror(err)); + pending_req_free(pr); + + g_io_channel_unref(chan); + + return FALSE; +} + static void hid_record_reply(DBusPendingCall *call, void *data) { DBusMessage *reply = dbus_pending_call_steal_reply(call); - DBusMessage *pr_reply; struct pending_req *pr = data; - struct hidp_connadd_req hidp; DBusError derr; uint8_t *rec_bin; - const char *path; int len, scanned; dbus_error_init(&derr); @@ -289,29 +428,18 @@ static void hid_record_reply(DBusPendingCall *call, void *data) goto fail; } - memset(&hidp, 0, sizeof(struct hidp_connadd_req)); - extract_hid_record(pr->hid_rec, &hidp); - if (pr->pnp_rec) - extract_pnp_record(pr->pnp_rec, &hidp); - - store_device_info(&pr->src, &pr->dst, &hidp); - - if (input_device_register(pr->conn, &pr->src, - &pr->dst, &hidp, &path) < 0) { - err_failed(pr->conn, pr->msg, "D-Bus path registration failed"); + if (l2cap_connect(&pr->src, &pr->dst, L2CAP_PSM_HIDP_CTRL, + (GIOFunc) control_connect_cb, pr) < 0) { + int err = errno; + error("L2CAP connect failed:%s (%d)", strerror(err), err); + err_connection_failed(pr->conn, pr->msg, strerror(err)); goto fail; - } - - device_paths = g_slist_append(device_paths, g_strdup(path)); - pr_reply = dbus_message_new_method_return(pr->msg); - - dbus_message_append_args(pr_reply, - DBUS_TYPE_STRING, &path, - DBUS_TYPE_INVALID); - - send_message_and_unref(pr->conn, pr_reply); + } + dbus_message_unref(reply); + dbus_pending_call_unref(call); + return; fail: dbus_error_free(&derr); pending_req_free(pr); -- cgit From f9398eaf08b49c1e8af5bc87a4b19d862ab5a4de Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Tue, 17 Apr 2007 19:36:28 +0000 Subject: input: fixed io channel unref and socket close --- input/manager.c | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) (limited to 'input/manager.c') diff --git a/input/manager.c b/input/manager.c index d339c007..b7cfc117 100644 --- a/input/manager.c +++ b/input/manager.c @@ -257,6 +257,8 @@ static gboolean interrupt_connect_cb(GIOChannel *chan, int isk, ret, err; socklen_t len; + isk = g_io_channel_unix_get_fd(chan); + if (cond & G_IO_NVAL) { err = EHOSTDOWN; isk = -1; @@ -264,15 +266,12 @@ static gboolean interrupt_connect_cb(GIOChannel *chan, } if (cond & (G_IO_HUP | G_IO_ERR)) { - err = EINTR; - isk = -1; + err = EHOSTDOWN; error("Hangup or error on HIDP interrupt socket"); goto failed; } - isk = g_io_channel_unix_get_fd(chan); - len = sizeof(ret); if (getsockopt(isk, SOL_SOCKET, SO_ERROR, &ret, &len) < 0) { err = errno; @@ -286,7 +285,6 @@ static gboolean interrupt_connect_cb(GIOChannel *chan, goto failed; } - memset(&hidp, 0, sizeof(struct hidp_connadd_req)); extract_hid_record(pr->hid_rec, &hidp); if (pr->pnp_rec) @@ -321,7 +319,6 @@ cleanup: close(pr->ctrl_sock); pending_req_free(pr); - g_io_channel_unref(chan); return FALSE; } @@ -332,6 +329,8 @@ static gboolean control_connect_cb(GIOChannel *chan, int ret, csk, err; socklen_t len; + csk = g_io_channel_unix_get_fd(chan); + if (cond & G_IO_NVAL) { err = EHOSTDOWN; csk = -1; @@ -339,14 +338,12 @@ static gboolean control_connect_cb(GIOChannel *chan, } if (cond & (G_IO_HUP | G_IO_ERR)) { - err = EINTR; - csk = -1; + err = EHOSTDOWN; error("Hangup or error on HIDP control socket"); goto failed; } - csk = g_io_channel_unix_get_fd(chan); /* Set HID control channel */ pr->ctrl_sock = csk; @@ -372,7 +369,6 @@ static gboolean control_connect_cb(GIOChannel *chan, goto failed; } - g_io_channel_unref(chan); return FALSE; failed: @@ -382,8 +378,6 @@ failed: err_connection_failed(pr->conn, pr->msg, strerror(err)); pending_req_free(pr); - g_io_channel_unref(chan); - return FALSE; } -- cgit From 5e225e3d197b9a02617153ac570755cc4d13226b Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Tue, 17 Apr 2007 20:40:45 +0000 Subject: input: dbus_pending_call_unref code standard --- input/manager.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'input/manager.c') diff --git a/input/manager.c b/input/manager.c index b7cfc117..41bafd20 100644 --- a/input/manager.c +++ b/input/manager.c @@ -143,6 +143,7 @@ static int get_record(struct pending_req *pr, uint32_t handle, } dbus_pending_call_set_notify(pending, cb, pr, NULL); + dbus_pending_call_unref(pending); dbus_message_unref(msg); return 0; @@ -173,6 +174,7 @@ static int get_handles(struct pending_req *pr, const char *uuid, } dbus_pending_call_set_notify(pending, cb, pr, NULL); + dbus_pending_call_unref(pending); dbus_message_unref(msg); return 0; @@ -431,14 +433,12 @@ static void hid_record_reply(DBusPendingCall *call, void *data) } dbus_message_unref(reply); - dbus_pending_call_unref(call); return; fail: dbus_error_free(&derr); pending_req_free(pr); dbus_message_unref(reply); - dbus_pending_call_unref(call); } static void hid_handle_reply(DBusPendingCall *call, void *data) @@ -491,7 +491,6 @@ fail: done: dbus_message_unref(reply); - dbus_pending_call_unref(call); } static void pnp_record_reply(DBusPendingCall *call, void *data) @@ -545,7 +544,6 @@ fail: done: dbus_message_unref(reply); - dbus_pending_call_unref(call); } static void pnp_handle_reply(DBusPendingCall *call, void *data) @@ -602,7 +600,6 @@ fail: done: dbus_message_unref(reply); - dbus_pending_call_unref(call); } static void headset_record_reply(DBusPendingCall *call, void *data) @@ -689,7 +686,6 @@ fail: dbus_error_free(&derr); pending_req_free(pr); dbus_message_unref(reply); - dbus_pending_call_unref(call); } static void headset_handle_reply(DBusPendingCall *call, void *data) @@ -742,7 +738,6 @@ fail: done: dbus_message_unref(reply); - dbus_pending_call_unref(call); } static int path_bdaddr_cmp(const char *path, const bdaddr_t *bdaddr) -- cgit From c506053c991016d372948a912201fdc8b03d175f Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Wed, 18 Apr 2007 19:33:34 +0000 Subject: input: fixed seg fault when RemoveDevice is called and there is a pending connection request --- input/manager.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'input/manager.c') diff --git a/input/manager.c b/input/manager.c index 41bafd20..f9c273fe 100644 --- a/input/manager.c +++ b/input/manager.c @@ -827,6 +827,7 @@ static DBusHandlerResult remove_device(DBusConnection *conn, DBusError derr; GSList *l; const char *path; + int err; dbus_error_init(&derr); if (!dbus_message_get_args(msg, &derr, @@ -845,14 +846,15 @@ static DBusHandlerResult remove_device(DBusConnection *conn, if (!reply) return DBUS_HANDLER_RESULT_NEED_MEMORY; - g_free(l->data); - device_paths = g_slist_remove(device_paths, l->data); - - if (input_device_unregister(conn, path) < 0) { + err = input_device_unregister(conn, path); + if (err < 0) { dbus_message_unref(reply); - return err_failed(conn, msg, "D-Bus path unregistration failed"); + return err_failed(conn, msg, strerror(-err)); } + g_free(l->data); + device_paths = g_slist_remove(device_paths, l->data); + return send_message_and_unref(conn, reply); } -- cgit From 319cc14e14afcce95aa9299fd3b357d8d4e596cd Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Fri, 4 May 2007 09:55:29 +0000 Subject: Input Service support for phones --- input/manager.c | 1 + 1 file changed, 1 insertion(+) (limited to 'input/manager.c') diff --git a/input/manager.c b/input/manager.c index f9c273fe..de4ad0e3 100644 --- a/input/manager.c +++ b/input/manager.c @@ -800,6 +800,7 @@ static DBusHandlerResult create_device(DBusConnection *conn, switch (cls & 0x1f00) { case 0x0500: /* Peripheral */ + case 0x0200: /* Phone */ if (get_handles(pr, pnp_uuid, pnp_handle_reply) < 0) { pending_req_free(pr); return err_not_supported(conn, msg); -- cgit From e4d113429614e120642e00e3a0a67c0ef62778ce Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 9 May 2007 10:05:28 +0000 Subject: Add support for FinishRemoteServiceTransaction --- input/manager.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) (limited to 'input/manager.c') diff --git a/input/manager.c b/input/manager.c index de4ad0e3..230740e2 100644 --- a/input/manager.c +++ b/input/manager.c @@ -383,6 +383,41 @@ failed: return FALSE; } +static void finish_sdp_transaction(bdaddr_t *dba) +{ + char address[18], *addr_ptr = address; + DBusMessage *msg, *reply; + DBusError derr; + + ba2str(dba, address); + + msg = dbus_message_new_method_call("org.bluez", "/org/bluez/hci0", + "org.bluez.Adapter", + "FinishRemoteServiceTransaction"); + if (!msg) { + error("Unable to allocate new method call"); + return; + } + + dbus_message_append_args(msg, DBUS_TYPE_STRING, &addr_ptr, + DBUS_TYPE_INVALID); + + dbus_error_init(&derr); + reply = dbus_connection_send_with_reply_and_block(connection, msg, + -1, &derr); + + dbus_message_unref(msg); + + if (dbus_error_is_set(&derr) || dbus_set_error_from_message(&derr, reply)) { + error("FinishRemoteServiceTransaction(%s) failed: %s", + address, derr.message); + dbus_error_free(&derr); + return; + } + + dbus_message_unref(reply); +} + static void hid_record_reply(DBusPendingCall *call, void *data) { DBusMessage *reply = dbus_pending_call_steal_reply(call); @@ -404,6 +439,8 @@ static void hid_record_reply(DBusPendingCall *call, void *data) goto fail; } + finish_sdp_transaction(&pr->dst); + if (!dbus_message_get_args(reply, &derr, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &rec_bin, &len, DBUS_TYPE_INVALID)) { -- cgit From 74416c5f12cc79cd0769220fa68b0f1bcaeb279e Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 9 May 2007 14:53:34 +0000 Subject: Convert to using generic dbus message dispatching --- input/manager.c | 72 ++++++++++++++++++++++++--------------------------------- 1 file changed, 30 insertions(+), 42 deletions(-) (limited to 'input/manager.c') diff --git a/input/manager.c b/input/manager.c index 230740e2..bd87c5fb 100644 --- a/input/manager.c +++ b/input/manager.c @@ -43,6 +43,7 @@ #include #include "dbus.h" +#include "dbus-helper.h" #include "logging.h" #include "textfile.h" @@ -922,35 +923,6 @@ static DBusHandlerResult list_devices(DBusConnection *conn, return send_message_and_unref(conn, reply); } -static DBusHandlerResult manager_message(DBusConnection *conn, - DBusMessage *msg, void *data) -{ - const char *path, *iface, *member; - - path = dbus_message_get_path(msg); - iface = dbus_message_get_interface(msg); - member = dbus_message_get_member(msg); - - /* Catching fallback paths */ - if (strcmp(INPUT_PATH, path) != 0) - return err_unknown_device(conn, msg); - - /* Accept messages from the input manager interface only */ - if (strcmp(INPUT_MANAGER_INTERFACE, iface)) - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - - if (strcmp(member, "ListDevices") == 0) - return list_devices(conn, msg, data); - - if (strcmp(member, "CreateDevice") == 0) - return create_device(conn, msg, data); - - if (strcmp(member, "RemoveDevice") == 0) - return remove_device(conn, msg, data); - - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; -} - static void manager_unregister(DBusConnection *conn, void *data) { info("Unregistered manager path"); @@ -960,12 +932,6 @@ static void manager_unregister(DBusConnection *conn, void *data) g_slist_free(device_paths); } -/* Virtual table to handle manager object path hierarchy */ -static const DBusObjectPathVTable manager_table = { - .message_function = manager_message, - .unregister_function = manager_unregister, -}; - /* * Stored inputs registration functions */ @@ -1022,19 +988,41 @@ static void register_stored_inputs(void) closedir(dir); } +static DBusMethodVTable manager_methods[] = { + { "ListDevices", list_devices, "", "as" }, + { "CreateDevice", create_device, "s", "s" }, + { "RemoveDevice", remove_device, "s", "" }, + { NULL, NULL, NULL, NULL }, +}; + +static DBusSignalVTable manager_signals[] = { + { "DeviceCreated", "s" }, + { "DeviceRemoved", "s" }, + { NULL, NULL } +}; + int input_init(DBusConnection *conn) { - connection = dbus_connection_ref(conn); - - dbus_connection_set_exit_on_disconnect(connection, TRUE); + dbus_connection_set_exit_on_disconnect(conn, TRUE); - /* Fallback to catch invalid device path */ - if (!dbus_connection_register_fallback(connection, INPUT_PATH, - &manager_table, NULL)) { + if (!dbus_connection_create_object_path(conn, INPUT_PATH, + NULL, manager_unregister)) { error("D-Bus failed to register %s path", INPUT_PATH); return -1; } + if (!dbus_connection_register_interface(conn, INPUT_PATH, + INPUT_MANAGER_INTERFACE, + manager_methods, + manager_signals, NULL)) { + error("Failed to register %s interface to %s", + INPUT_MANAGER_INTERFACE, INPUT_PATH); + dbus_connection_destroy_object_path(connection, INPUT_PATH); + return -1; + } + + connection = dbus_connection_ref(conn); + info("Registered input manager path:%s", INPUT_PATH); /* Register well known HID devices */ @@ -1047,7 +1035,7 @@ int input_init(DBusConnection *conn) void input_exit(void) { - dbus_connection_unregister_object_path(connection, INPUT_PATH); + dbus_connection_destroy_object_path(connection, INPUT_PATH); server_stop(); -- cgit From 0bf3861da5ad7f4f2310029e2b42ae964a9e3aa5 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Thu, 21 Jun 2007 22:06:33 +0000 Subject: input: removed session_data structure and added watch for Disconnect signal --- input/manager.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'input/manager.c') diff --git a/input/manager.c b/input/manager.c index bd87c5fb..03c914ee 100644 --- a/input/manager.c +++ b/input/manager.c @@ -954,9 +954,12 @@ static void stored_input(char *key, char *value, void *data) * acceptable since the source is different. */ if (input_device_register(connection, src, &dst, &hidp, &path) < 0) - return; + goto cleanup; device_paths = g_slist_append(device_paths, g_strdup(path)); +cleanup: + if (hidp.rd_data) + g_free(hidp.rd_data); } static void register_stored_inputs(void) -- cgit From 0762886602369f99a473dc95cc288def7b6e363c Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Fri, 22 Jun 2007 17:11:10 +0000 Subject: input: convert hidd to input --- input/manager.c | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) (limited to 'input/manager.c') diff --git a/input/manager.c b/input/manager.c index 03c914ee..666c0e44 100644 --- a/input/manager.c +++ b/input/manager.c @@ -962,6 +962,34 @@ cleanup: g_free(hidp.rd_data); } +/* hidd to input transition function */ +static void stored_hidd(char *key, char *value, void *data) +{ + struct hidp_connadd_req hidp; + char *str, filename[PATH_MAX + 1], addr[18]; + bdaddr_t dst, *src = data; + + ba2str(src, addr); + create_name(filename, PATH_MAX, STORAGEDIR, addr, "input"); + + str = textfile_get(filename, key); + if (str) { + /* Skip: entry found in input file */ + free(str); + return; + } + + memset(&hidp, 0, sizeof(struct hidp_connadd_req)); + + if (parse_stored_hidd(value, &hidp) < 0) + return; + + str2ba(key, &dst); + store_device_info(src, &dst, &hidp); + if (hidp.rd_data) + g_free(hidp.rd_data); +} + static void register_stored_inputs(void) { char dirname[PATH_MAX + 1]; @@ -980,10 +1008,16 @@ static void register_stored_inputs(void) if (!isdigit(de->d_name[0])) continue; + str2ba(de->d_name, &src); + + /* move the hidd entries to the input storage */ create_name(filename, PATH_MAX, STORAGEDIR, - de->d_name, "input"); + de->d_name, "hidd"); + textfile_foreach(filename, stored_hidd, &src); - str2ba(de->d_name, &src); + /* load the input stored devices */ + create_name(filename, PATH_MAX, STORAGEDIR, + de->d_name, "input"); textfile_foreach(filename, stored_input, &src); } -- cgit From 7fb02908be38aaa273643ac6b78c5d72e40ae545 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Fri, 22 Jun 2007 19:14:38 +0000 Subject: input: fixed CreateDevice - verify the src and the dst address to discover if the device already exists --- input/manager.c | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) (limited to 'input/manager.c') diff --git a/input/manager.c b/input/manager.c index 666c0e44..74654893 100644 --- a/input/manager.c +++ b/input/manager.c @@ -778,23 +778,12 @@ done: dbus_message_unref(reply); } -static int path_bdaddr_cmp(const char *path, const bdaddr_t *bdaddr) -{ - bdaddr_t src, dst; - - if (input_device_get_bdaddr(connection, path, &src, &dst) < 0) - return -1; - - return bacmp(&dst, bdaddr); -} - static DBusHandlerResult create_device(DBusConnection *conn, DBusMessage *msg, void *data) { struct pending_req *pr; DBusError derr; const char *addr; - GSList *l; bdaddr_t src, dst; uint32_t cls = 0; int dev_id; @@ -821,10 +810,7 @@ static DBusHandlerResult create_device(DBusConnection *conn, } str2ba(addr, &dst); - - l = g_slist_find_custom(device_paths, &dst, - (GCompareFunc) path_bdaddr_cmp); - if (l) + if (input_device_is_registered(&src, &dst)) return err_already_exists(conn, msg, "Input Already exists"); if (read_device_class(&src, &dst, &cls) < 0) { -- cgit From 2639da11e06cc2d91c7c3416068333587f2b5df1 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Fri, 3 Aug 2007 13:43:24 +0000 Subject: input: added epox_endian_quirk function --- input/manager.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'input/manager.c') diff --git a/input/manager.c b/input/manager.c index 74654893..75ab1c15 100644 --- a/input/manager.c +++ b/input/manager.c @@ -181,6 +181,31 @@ static int get_handles(struct pending_req *pr, const char *uuid, return 0; } +static void epox_endian_quirk(unsigned char *data, int size) +{ + /* USAGE_PAGE (Keyboard) 05 07 + * USAGE_MINIMUM (0) 19 00 + * USAGE_MAXIMUM (65280) 2A 00 FF <= must be FF 00 + * LOGICAL_MINIMUM (0) 15 00 + * LOGICAL_MAXIMUM (65280) 26 00 FF <= must be FF 00 + */ + unsigned char pattern[] = { 0x05, 0x07, 0x19, 0x00, 0x2a, 0x00, 0xff, + 0x15, 0x00, 0x26, 0x00, 0xff }; + int i; + + if (!data) + return; + + for (i = 0; i < size - sizeof(pattern); i++) { + if (!memcmp(data + i, pattern, sizeof(pattern))) { + data[i + 5] = 0xff; + data[i + 6] = 0x00; + data[i + 10] = 0xff; + data[i + 11] = 0x00; + } + } +} + static void extract_hid_record(sdp_record_t *rec, struct hidp_connadd_req *req) { sdp_data_t *pdlist, *pdlist2; @@ -233,6 +258,7 @@ static void extract_hid_record(sdp_record_t *rec, struct hidp_connadd_req *req) memcpy(req->rd_data, (unsigned char *) pdlist->val.str, pdlist->unitSize); req->rd_size = pdlist->unitSize; + epox_endian_quirk(req->rd_data, req->rd_size); } } } -- cgit From 5aef8f33ebb1fb537e13ffeb336eb1d886a7adca Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Mon, 27 Aug 2007 13:50:32 +0000 Subject: input: don't send DeviceCreated signal when the daemon starts --- input/manager.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'input/manager.c') diff --git a/input/manager.c b/input/manager.c index 75ab1c15..47638278 100644 --- a/input/manager.c +++ b/input/manager.c @@ -327,6 +327,11 @@ static gboolean interrupt_connect_cb(GIOChannel *chan, goto cleanup; } + dbus_connection_emit_signal(pr->conn, INPUT_PATH, + INPUT_MANAGER_INTERFACE, "DeviceCreated", + DBUS_TYPE_STRING, &path, + DBUS_TYPE_INVALID); + device_paths = g_slist_append(device_paths, g_strdup(path)); /* Replying to the requestor */ @@ -736,6 +741,11 @@ static void headset_record_reply(DBusPendingCall *call, void *data) goto fail; } + dbus_connection_emit_signal(pr->conn, INPUT_PATH, + INPUT_MANAGER_INTERFACE, "DeviceCreated", + DBUS_TYPE_STRING, &path, + DBUS_TYPE_INVALID); + device_paths = g_slist_append(device_paths, g_strdup(path)); pr_reply = dbus_message_new_method_return(pr->msg); -- cgit From 56e8f3fc3c15ceb035cda16d9dada129674cfeff Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Thu, 30 Aug 2007 13:45:58 +0000 Subject: Fix socket validity checks --- input/manager.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'input/manager.c') diff --git a/input/manager.c b/input/manager.c index 47638278..5dfb0641 100644 --- a/input/manager.c +++ b/input/manager.c @@ -348,7 +348,7 @@ failed: err_connection_failed(pr->conn, pr->msg, strerror(err)); cleanup: - if (isk > 0) + if (isk >= 0) close(isk); close(pr->ctrl_sock); @@ -406,7 +406,7 @@ static gboolean control_connect_cb(GIOChannel *chan, return FALSE; failed: - if (csk > 0) + if (csk >= 0) close(csk); err_connection_failed(pr->conn, pr->msg, strerror(err)); -- cgit From 4e7fe8b13bd4cd3c82da00e812e812898a366b3b Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Tue, 2 Oct 2007 17:54:40 +0000 Subject: input: minor leak and code standard --- input/manager.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'input/manager.c') diff --git a/input/manager.c b/input/manager.c index 5dfb0641..1468b910 100644 --- a/input/manager.c +++ b/input/manager.c @@ -140,6 +140,7 @@ static int get_record(struct pending_req *pr, uint32_t handle, if (dbus_connection_send_with_reply(pr->conn, msg, &pending, -1) == FALSE) { error("Can't send D-Bus message."); + dbus_message_unref(msg); return -1; } @@ -158,7 +159,7 @@ static int get_handles(struct pending_req *pr, const char *uuid, char addr[18]; const char *paddr = addr; - msg = dbus_message_new_method_call("org.bluez", pr->adapter_path, + msg = dbus_message_new_method_call("org.bluez", pr->adapter_path, "org.bluez.Adapter", "GetRemoteServiceHandles"); if (!msg) return -1; @@ -171,6 +172,7 @@ static int get_handles(struct pending_req *pr, const char *uuid, if (dbus_connection_send_with_reply(pr->conn, msg, &pending, -1) == FALSE) { error("Can't send D-Bus message."); + dbus_message_unref(msg); return -1; } -- cgit From 09616172377cf146517c1eb821cb5f5d9cb2a188 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Tue, 2 Oct 2007 18:20:44 +0000 Subject: input: removed mem leak(HID desc list attribute) --- input/manager.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'input/manager.c') diff --git a/input/manager.c b/input/manager.c index 1468b910..dc209a44 100644 --- a/input/manager.c +++ b/input/manager.c @@ -356,6 +356,9 @@ cleanup: close(pr->ctrl_sock); pending_req_free(pr); + if (hidp.rd_data) + g_free(hidp.rd_data); + return FALSE; } -- cgit From 07ebeadd853277fa7b7fae80abb84c17bf1d303b Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Thu, 4 Oct 2007 15:48:32 +0000 Subject: input: added CreateSecureDevice --- input/manager.c | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 85 insertions(+), 10 deletions(-) (limited to 'input/manager.c') diff --git a/input/manager.c b/input/manager.c index dc209a44..cd2e8a1d 100644 --- a/input/manager.c +++ b/input/manager.c @@ -229,10 +229,10 @@ static void extract_hid_record(sdp_record_t *rec, struct hidp_connadd_req *req) if (pdlist2) strncpy(req->name, pdlist2->val.str, 127); } - + pdlist = sdp_data_get(rec, SDP_ATTR_HID_PARSER_VERSION); req->parser = pdlist ? pdlist->val.uint16 : 0x0100; - + pdlist = sdp_data_get(rec, SDP_ATTR_HID_DEVICE_SUBCLASS); req->subclass = pdlist ? pdlist->val.uint8 : 0; @@ -420,7 +420,35 @@ failed: return FALSE; } -static void finish_sdp_transaction(bdaddr_t *dba) +static void create_bonding_reply(DBusPendingCall *call, void *data) +{ + DBusMessage *reply = dbus_pending_call_steal_reply(call); + struct pending_req *pr = data; + DBusError derr; + + dbus_error_init(&derr); + if (dbus_set_error_from_message(&derr, reply)) { + error("CreateBonding failed: %s(%s)", + derr.name, derr.message); + err_authentication_failed(pr->conn, pr->msg); + dbus_error_free(&derr); + dbus_message_unref(reply); + pending_req_free(pr); + return; + } + + dbus_message_unref(reply); + + if (l2cap_connect(&pr->src, &pr->dst, L2CAP_PSM_HIDP_CTRL, + (GIOFunc) control_connect_cb, pr) < 0) { + int err = errno; + err_connection_failed(pr->conn, pr->msg, strerror(err)); + error("L2CAP connect failed:%s (%d)", strerror(err), err); + pending_req_free(pr); + } +} + +static void finish_sdp_transaction(bdaddr_t *dba) { char address[18], *addr_ptr = address; DBusMessage *msg, *reply; @@ -455,6 +483,32 @@ static void finish_sdp_transaction(bdaddr_t *dba) dbus_message_unref(reply); } +static int create_bonding(struct pending_req *pr) +{ + DBusPendingCall *pending; + DBusMessage *msg; + char address[18], *addr_ptr = address; + + msg = dbus_message_new_method_call("org.bluez", pr->adapter_path, + "org.bluez.Adapter", "CreateBonding"); + if (!msg) { + error("Unable to allocate new method call"); + return -1; + } + + ba2str(&pr->dst, address); + dbus_message_append_args(msg, DBUS_TYPE_STRING, &addr_ptr, DBUS_TYPE_INVALID); + if (dbus_connection_send_with_reply(pr->conn, msg, &pending, -1) == FALSE) { + error("Can't send D-Bus message."); + dbus_message_unref(msg); + return -1; + } + dbus_pending_call_set_notify(pending, create_bonding_reply, pr, NULL); + dbus_pending_call_unref(pending); + dbus_message_unref(msg); + return 0; +} + static void hid_record_reply(DBusPendingCall *call, void *data) { DBusMessage *reply = dbus_pending_call_steal_reply(call); @@ -498,16 +552,36 @@ static void hid_record_reply(DBusPendingCall *call, void *data) goto fail; } + dbus_message_unref(reply); + + if (strcmp("CreateSecureDevice", dbus_message_get_member(pr->msg)) == 0) { + sdp_data_t *d; + + /* Pairing mandatory for keyboard and combo */ + d = sdp_data_get(pr->hid_rec, SDP_ATTR_HID_DEVICE_SUBCLASS); + if (d && (d->val.uint8 & 0x40) && + !has_bonding(&pr->src, &pr->dst)) { + if (create_bonding(pr) < 0) { + err_authentication_failed(pr->conn, pr->msg); + goto fail; + } + /* Wait bonding reply */ + return; + } + + /* Otherwise proceede L2CAP connection */ + } + + /* No encryption or link key already exists -- connect control channel */ if (l2cap_connect(&pr->src, &pr->dst, L2CAP_PSM_HIDP_CTRL, (GIOFunc) control_connect_cb, pr) < 0) { int err = errno; error("L2CAP connect failed:%s (%d)", strerror(err), err); err_connection_failed(pr->conn, pr->msg, strerror(err)); goto fail; - } - dbus_message_unref(reply); + /* Wait L2CAP connect */ return; fail: dbus_error_free(&derr); @@ -966,7 +1040,7 @@ static void manager_unregister(DBusConnection *conn, void *data) static void stored_input(char *key, char *value, void *data) { const char *path; - struct hidp_connadd_req hidp; + struct hidp_connadd_req hidp; bdaddr_t dst, *src = data; str2ba(key, &dst); @@ -992,7 +1066,7 @@ cleanup: /* hidd to input transition function */ static void stored_hidd(char *key, char *value, void *data) { - struct hidp_connadd_req hidp; + struct hidp_connadd_req hidp; char *str, filename[PATH_MAX + 1], addr[18]; bdaddr_t dst, *src = data; @@ -1053,9 +1127,10 @@ static void register_stored_inputs(void) } static DBusMethodVTable manager_methods[] = { - { "ListDevices", list_devices, "", "as" }, - { "CreateDevice", create_device, "s", "s" }, - { "RemoveDevice", remove_device, "s", "" }, + { "ListDevices", list_devices, "", "as" }, + { "CreateDevice", create_device, "s", "s" }, + { "CreateSecureDevice", create_device, "s", "s" }, + { "RemoveDevice", remove_device, "s", "" }, { NULL, NULL, NULL, NULL }, }; -- cgit From 3571ae843629585caf996c73200bbbfd05c260a6 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Fri, 12 Oct 2007 11:00:32 +0000 Subject: Fix hidp_connad_req usage --- input/manager.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'input/manager.c') diff --git a/input/manager.c b/input/manager.c index cd2e8a1d..13e5cdba 100644 --- a/input/manager.c +++ b/input/manager.c @@ -288,6 +288,8 @@ static gboolean interrupt_connect_cb(GIOChannel *chan, int isk, ret, err; socklen_t len; + memset(&hidp, 0, sizeof(hidp)); + isk = g_io_channel_unix_get_fd(chan); if (cond & G_IO_NVAL) { @@ -316,7 +318,6 @@ static gboolean interrupt_connect_cb(GIOChannel *chan, goto failed; } - memset(&hidp, 0, sizeof(struct hidp_connadd_req)); extract_hid_record(pr->hid_rec, &hidp); if (pr->pnp_rec) extract_pnp_record(pr->pnp_rec, &hidp); @@ -1045,7 +1046,7 @@ static void stored_input(char *key, char *value, void *data) str2ba(key, &dst); - memset(&hidp, 0, sizeof(struct hidp_connadd_req)); + memset(&hidp, 0, sizeof(hidp)); if (parse_stored_device_info(value, &hidp) < 0) return; @@ -1080,7 +1081,7 @@ static void stored_hidd(char *key, char *value, void *data) return; } - memset(&hidp, 0, sizeof(struct hidp_connadd_req)); + memset(&hidp, 0, sizeof(hidp)); if (parse_stored_hidd(value, &hidp) < 0) return; -- cgit From 7e88afe4f8307c092172ff3c3b76c2f95ab00293 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Mon, 26 Nov 2007 13:43:17 +0000 Subject: Update services to new error codes and helper functions --- input/manager.c | 121 ++++++++++++++++++++++++++++++++------------------------ 1 file changed, 70 insertions(+), 51 deletions(-) (limited to 'input/manager.c') diff --git a/input/manager.c b/input/manager.c index 13e5cdba..7bdf6d30 100644 --- a/input/manager.c +++ b/input/manager.c @@ -326,7 +326,7 @@ static gboolean interrupt_connect_cb(GIOChannel *chan, if (input_device_register(pr->conn, &pr->src, &pr->dst, &hidp, &path) < 0) { - err_failed(pr->conn, pr->msg, "path registration failed"); + error_failed(pr->conn, pr->msg, "path registration failed"); goto cleanup; } @@ -348,7 +348,7 @@ static gboolean interrupt_connect_cb(GIOChannel *chan, goto cleanup; failed: - err_connection_failed(pr->conn, pr->msg, strerror(err)); + error_connection_attempt_failed(pr->conn, pr->msg, err); cleanup: if (isk >= 0) @@ -415,7 +415,7 @@ failed: if (csk >= 0) close(csk); - err_connection_failed(pr->conn, pr->msg, strerror(err)); + error_connection_attempt_failed(pr->conn, pr->msg, err); pending_req_free(pr); return FALSE; @@ -431,7 +431,7 @@ static void create_bonding_reply(DBusPendingCall *call, void *data) if (dbus_set_error_from_message(&derr, reply)) { error("CreateBonding failed: %s(%s)", derr.name, derr.message); - err_authentication_failed(pr->conn, pr->msg); + error_failed(pr->conn, pr->msg, "Authentication failed (CreateBonding)"); dbus_error_free(&derr); dbus_message_unref(reply); pending_req_free(pr); @@ -443,7 +443,7 @@ static void create_bonding_reply(DBusPendingCall *call, void *data) if (l2cap_connect(&pr->src, &pr->dst, L2CAP_PSM_HIDP_CTRL, (GIOFunc) control_connect_cb, pr) < 0) { int err = errno; - err_connection_failed(pr->conn, pr->msg, strerror(err)); + error_connection_attempt_failed(pr->conn, pr->msg, err); error("L2CAP connect failed:%s (%d)", strerror(err), err); pending_req_free(pr); } @@ -520,11 +520,14 @@ static void hid_record_reply(DBusPendingCall *call, void *data) dbus_error_init(&derr); if (dbus_set_error_from_message(&derr, reply)) { + /* FIXME : to not try to be clever about + hcid error but forward as is to the user */ if (dbus_error_has_name(&derr, "org.bluez.Error.ConnectionAttemptFailed")) - err_connection_failed(pr->conn, pr->msg, derr.message); + error_connection_attempt_failed(pr->conn, + pr->msg, EIO); else - err_not_supported(pr->conn, pr->msg); + error_not_supported(pr->conn, pr->msg); error("GetRemoteServiceRecord failed: %s(%s)", derr.name, derr.message); @@ -536,20 +539,20 @@ static void hid_record_reply(DBusPendingCall *call, void *data) if (!dbus_message_get_args(reply, &derr, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &rec_bin, &len, DBUS_TYPE_INVALID)) { - err_not_supported(pr->conn, pr->msg); + error_not_supported(pr->conn, pr->msg); error("%s: %s", derr.name, derr.message); goto fail; } if (len == 0) { - err_not_supported(pr->conn, pr->msg); + error_not_supported(pr->conn, pr->msg); error("Invalid HID service record length"); goto fail; } pr->hid_rec = sdp_extract_pdu(rec_bin, &scanned); if (!pr->hid_rec) { - err_not_supported(pr->conn, pr->msg); + error_not_supported(pr->conn, pr->msg); goto fail; } @@ -563,7 +566,8 @@ static void hid_record_reply(DBusPendingCall *call, void *data) if (d && (d->val.uint8 & 0x40) && !has_bonding(&pr->src, &pr->dst)) { if (create_bonding(pr) < 0) { - err_authentication_failed(pr->conn, pr->msg); + error_failed(pr->conn, pr->msg, + "Unable to initialize bonding process"); goto fail; } /* Wait bonding reply */ @@ -578,7 +582,7 @@ static void hid_record_reply(DBusPendingCall *call, void *data) (GIOFunc) control_connect_cb, pr) < 0) { int err = errno; error("L2CAP connect failed:%s (%d)", strerror(err), err); - err_connection_failed(pr->conn, pr->msg, strerror(err)); + error_connection_attempt_failed(pr->conn, pr->msg, err); goto fail; } @@ -600,11 +604,14 @@ static void hid_handle_reply(DBusPendingCall *call, void *data) dbus_error_init(&derr); if (dbus_set_error_from_message(&derr, reply)) { + /* FIXME : to not try to be clever about + hcid error but forward as is to the user */ if (dbus_error_has_name(&derr, "org.bluez.Error.ConnectionAttemptFailed")) - err_connection_failed(pr->conn, pr->msg, derr.message); + error_connection_attempt_failed(pr->conn, + pr->msg, EIO); else - err_not_supported(pr->conn, pr->msg); + error_not_supported(pr->conn, pr->msg); error("GetRemoteServiceHandles: %s(%s)", derr.name, derr.message); @@ -614,19 +621,19 @@ static void hid_handle_reply(DBusPendingCall *call, void *data) if (!dbus_message_get_args(reply, &derr, DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &phandle, &len, DBUS_TYPE_INVALID)) { - err_not_supported(pr->conn, pr->msg); + error_not_supported(pr->conn, pr->msg); error("%s: %s", derr.name, derr.message); goto fail; } if (len == 0) { - err_not_supported(pr->conn, pr->msg); + error_not_supported(pr->conn, pr->msg); error("HID record handle not found"); goto fail; } if (get_record(pr, *phandle, hid_record_reply) < 0) { - err_not_supported(pr->conn, pr->msg); + error_not_supported(pr->conn, pr->msg); error("HID service attribute request failed"); goto fail; } else { @@ -652,11 +659,14 @@ static void pnp_record_reply(DBusPendingCall *call, void *data) dbus_error_init(&derr); if (dbus_set_error_from_message(&derr, reply)) { + /* FIXME : to not try to be clever about + hcid error but forward as is to the user */ if (dbus_error_has_name(&derr, "org.bluez.Error.ConnectionAttemptFailed")) - err_connection_failed(pr->conn, pr->msg, derr.message); + error_connection_attempt_failed(pr->conn, pr->msg, + EIO); else - err_not_supported(pr->conn, pr->msg); + error_not_supported(pr->conn, pr->msg); error("GetRemoteServiceRecord: %s(%s)", derr.name, derr.message); @@ -666,20 +676,20 @@ static void pnp_record_reply(DBusPendingCall *call, void *data) if (!dbus_message_get_args(reply, &derr, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &rec_bin, &len, DBUS_TYPE_INVALID)) { - err_not_supported(pr->conn, pr->msg); + error_not_supported(pr->conn, pr->msg); error("%s: %s", derr.name, derr.message); goto fail; } if (len == 0) { - err_not_supported(pr->conn, pr->msg); + error_not_supported(pr->conn, pr->msg); error("Invalid PnP service record length"); goto fail; } pr->pnp_rec = sdp_extract_pdu(rec_bin, &scanned); if (get_handles(pr, hid_uuid, hid_handle_reply) < 0) { - err_not_supported(pr->conn, pr->msg); + error_not_supported(pr->conn, pr->msg); error("HID service search request failed"); goto fail; } else { @@ -705,11 +715,14 @@ static void pnp_handle_reply(DBusPendingCall *call, void *data) dbus_error_init(&derr); if (dbus_set_error_from_message(&derr, reply)) { + /* FIXME : to not try to be clever about + hcid error but forward as is to the user */ if (dbus_error_has_name(&derr, "org.bluez.Error.ConnectionAttemptFailed")) - err_connection_failed(pr->conn, pr->msg, derr.message); + error_connection_attempt_failed(pr->conn, pr->msg, + EIO); else - err_not_supported(pr->conn, pr->msg); + error_not_supported(pr->conn, pr->msg); error("GetRemoteServiceHandles: %s(%s)", derr.name, derr.message); @@ -719,7 +732,7 @@ static void pnp_handle_reply(DBusPendingCall *call, void *data) if (!dbus_message_get_args(reply, &derr, DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &phandle, &len, DBUS_TYPE_INVALID)) { - err_not_supported(pr->conn, pr->msg); + error_not_supported(pr->conn, pr->msg); error("%s: %s", derr.name, derr.message); goto fail; } @@ -727,14 +740,14 @@ static void pnp_handle_reply(DBusPendingCall *call, void *data) if (len == 0) { /* PnP is optional: Ignore it and request the HID handle */ if (get_handles(pr, hid_uuid, hid_handle_reply) < 0) { - err_not_supported(pr->conn, pr->msg); + error_not_supported(pr->conn, pr->msg); error("HID service search request failed"); goto fail; } } else { /* Request PnP record */ if (get_record(pr, *phandle, pnp_record_reply) < 0) { - err_not_supported(pr->conn, pr->msg); + error_not_supported(pr->conn, pr->msg); error("PnP service attribute request failed"); goto fail; } @@ -766,11 +779,14 @@ static void headset_record_reply(DBusPendingCall *call, void *data) dbus_error_init(&derr); if (dbus_set_error_from_message(&derr, reply)) { + /* FIXME : to not try to be clever about + hcid error but forward as is to the user */ if (dbus_error_has_name(&derr, "org.bluez.Error.ConnectionAttemptFailed")) - err_connection_failed(pr->conn, pr->msg, derr.message); + error_connection_attempt_failed(pr->conn, pr->msg, + EIO); else - err_not_supported(pr->conn, pr->msg); + error_not_supported(pr->conn, pr->msg); error("GetRemoteServiceRecord: %s(%s)", derr.name, derr.message); @@ -780,25 +796,25 @@ static void headset_record_reply(DBusPendingCall *call, void *data) if (!dbus_message_get_args(reply, &derr, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &rec_bin, &len, DBUS_TYPE_INVALID)) { - err_not_supported(pr->conn, pr->msg); + error_not_supported(pr->conn, pr->msg); error("%s: %s", derr.name, derr.message); goto fail; } if (len == 0) { - err_not_supported(pr->conn, pr->msg); + error_not_supported(pr->conn, pr->msg); error("Invalid headset service record length"); goto fail; } rec = sdp_extract_pdu(rec_bin, &scanned); if (!rec) { - err_not_supported(pr->conn, pr->msg); + error_not_supported(pr->conn, pr->msg); goto fail; } if (sdp_get_access_protos(rec, &protos) < 0) { - err_not_supported(pr->conn, pr->msg); + error_not_supported(pr->conn, pr->msg); goto fail; } @@ -808,7 +824,7 @@ static void headset_record_reply(DBusPendingCall *call, void *data) sdp_record_free(rec); if (ch <= 0) { - err_not_supported(pr->conn, pr->msg); + error_not_supported(pr->conn, pr->msg); error("Invalid RFCOMM channel"); goto fail; } @@ -817,7 +833,7 @@ static void headset_record_reply(DBusPendingCall *call, void *data) if (fake_input_register(pr->conn, &pr->src, &pr->dst, ch, &path) < 0) { error("D-Bus path registration failed:%s", path); - err_failed(pr->conn, pr->msg, "Path registration failed"); + error_failed(pr->conn, pr->msg, "Path registration failed"); goto fail; } @@ -852,11 +868,14 @@ static void headset_handle_reply(DBusPendingCall *call, void *data) dbus_error_init(&derr); if (dbus_set_error_from_message(&derr, reply)) { + /* FIXME : to not try to be clever about + hcid error but forward as is to the user */ if (dbus_error_has_name(&derr, "org.bluez.Error.ConnectionAttemptFailed")) - err_connection_failed(pr->conn, pr->msg, derr.message); + error_connection_attempt_failed(pr->conn, pr->msg, + EIO); else - err_not_supported(pr->conn, pr->msg); + error_not_supported(pr->conn, pr->msg); error("GetRemoteServiceHandles: %s(%s)", derr.name, derr.message); @@ -866,19 +885,19 @@ static void headset_handle_reply(DBusPendingCall *call, void *data) if (!dbus_message_get_args(reply, &derr, DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &phandle, &len, DBUS_TYPE_INVALID)) { - err_not_supported(pr->conn, pr->msg); + error_not_supported(pr->conn, pr->msg); error("%s: %s", derr.name, derr.message); goto fail; } if (len == 0) { - err_not_supported(pr->conn, pr->msg); + error_not_supported(pr->conn, pr->msg); error("Headset record handle not found"); goto fail; } if (get_record(pr, *phandle, headset_record_reply) < 0) { - err_not_supported(pr->conn, pr->msg); + error_not_supported(pr->conn, pr->msg); error("Headset service attribute request failed"); goto fail; } else { @@ -908,7 +927,7 @@ static DBusHandlerResult create_device(DBusConnection *conn, if (!dbus_message_get_args(msg, &derr, DBUS_TYPE_STRING, &addr, DBUS_TYPE_INVALID)) { - err_invalid_args(conn, msg, derr.message); + error_invalid_arguments(conn, msg, derr.message); dbus_error_free(&derr); return DBUS_HANDLER_RESULT_HANDLED; } @@ -917,21 +936,21 @@ static DBusHandlerResult create_device(DBusConnection *conn, dev_id = hci_get_route(NULL); if (dev_id < 0) { error("Bluetooth adapter not available"); - return err_failed(conn, msg, "Adapter not available"); + return error_failed(conn, msg, "Adapter not available"); } if (hci_devba(dev_id, &src) < 0) { error("Can't get local adapter device info"); - return err_failed(conn, msg, "Adapter not available"); + return error_failed(conn, msg, "Adapter not available"); } str2ba(addr, &dst); if (input_device_is_registered(&src, &dst)) - return err_already_exists(conn, msg, "Input Already exists"); + return error_already_exists(conn, msg, "Input Already exists"); if (read_device_class(&src, &dst, &cls) < 0) { error("Device class not available"); - return err_not_supported(conn, msg); + return error_not_supported(conn, msg); } pr = pending_req_new(conn, msg, &src, &dst); @@ -943,19 +962,19 @@ static DBusHandlerResult create_device(DBusConnection *conn, case 0x0200: /* Phone */ if (get_handles(pr, pnp_uuid, pnp_handle_reply) < 0) { pending_req_free(pr); - return err_not_supported(conn, msg); + return error_not_supported(conn, msg); } break; case 0x0400: /* Fake input */ if (get_handles(pr, headset_uuid, headset_handle_reply) < 0) { pending_req_free(pr); - return err_not_supported(conn, msg); + return error_not_supported(conn, msg); } break; default: pending_req_free(pr); - return err_not_supported(conn, msg); + return error_not_supported(conn, msg); } return DBUS_HANDLER_RESULT_HANDLED; @@ -974,14 +993,14 @@ static DBusHandlerResult remove_device(DBusConnection *conn, if (!dbus_message_get_args(msg, &derr, DBUS_TYPE_STRING, &path, DBUS_TYPE_INVALID)) { - err_invalid_args(conn, msg, derr.message); + error_invalid_arguments(conn, msg, derr.message); dbus_error_free(&derr); return DBUS_HANDLER_RESULT_HANDLED; } l = g_slist_find_custom(device_paths, path, (GCompareFunc) strcmp); if (!l) - return err_does_not_exist(conn, msg, "Input doesn't exist"); + return error_does_not_exist(conn, msg, "Input doesn't exist"); reply = dbus_message_new_method_return(msg); if (!reply) @@ -990,7 +1009,7 @@ static DBusHandlerResult remove_device(DBusConnection *conn, err = input_device_unregister(conn, path); if (err < 0) { dbus_message_unref(reply); - return err_failed(conn, msg, strerror(-err)); + return error_failed_errno(conn, msg, -err); } g_free(l->data); -- cgit From e823c15e43a6f924779e466d434c51157002d9ee Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 2 Feb 2008 03:37:05 +0000 Subject: Update copyright information --- input/manager.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'input/manager.c') diff --git a/input/manager.c b/input/manager.c index 7bdf6d30..a717c909 100644 --- a/input/manager.c +++ b/input/manager.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2004-2007 Marcel Holtmann + * Copyright (C) 2004-2008 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify -- cgit From 29efa57d5a27b0cf5997381053be9cc48b2c2e80 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 22 Mar 2008 15:37:36 +0000 Subject: Convert input service into a plugin --- input/manager.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'input/manager.c') diff --git a/input/manager.c b/input/manager.c index a717c909..953b44ac 100644 --- a/input/manager.c +++ b/input/manager.c @@ -1160,7 +1160,7 @@ static DBusSignalVTable manager_signals[] = { { NULL, NULL } }; -int input_init(DBusConnection *conn) +int input_manager_init(DBusConnection *conn) { dbus_connection_set_exit_on_disconnect(conn, TRUE); @@ -1192,7 +1192,7 @@ int input_init(DBusConnection *conn) return 0; } -void input_exit(void) +void input_manager_exit(void) { dbus_connection_destroy_object_path(connection, INPUT_PATH); -- cgit From 1152fc72d35de616d5d2d3a29525fd6aacb852f9 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Thu, 27 Mar 2008 14:05:37 +0000 Subject: Remove blocking call of FinishRemoteServiceTransaction. --- input/manager.c | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) (limited to 'input/manager.c') diff --git a/input/manager.c b/input/manager.c index 953b44ac..2e138c6b 100644 --- a/input/manager.c +++ b/input/manager.c @@ -452,8 +452,7 @@ static void create_bonding_reply(DBusPendingCall *call, void *data) static void finish_sdp_transaction(bdaddr_t *dba) { char address[18], *addr_ptr = address; - DBusMessage *msg, *reply; - DBusError derr; + DBusMessage *msg; ba2str(dba, address); @@ -468,20 +467,7 @@ static void finish_sdp_transaction(bdaddr_t *dba) dbus_message_append_args(msg, DBUS_TYPE_STRING, &addr_ptr, DBUS_TYPE_INVALID); - dbus_error_init(&derr); - reply = dbus_connection_send_with_reply_and_block(connection, msg, - -1, &derr); - - dbus_message_unref(msg); - - if (dbus_error_is_set(&derr) || dbus_set_error_from_message(&derr, reply)) { - error("FinishRemoteServiceTransaction(%s) failed: %s", - address, derr.message); - dbus_error_free(&derr); - return; - } - - dbus_message_unref(reply); + send_message_and_unref(connection, msg); } static int create_bonding(struct pending_req *pr) -- cgit From 279e85d6da77c74f04e5fc605dd8074bfe56b5a5 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Fri, 25 Apr 2008 20:01:09 +0000 Subject: Make input service to use libbluetooth-glib convenient functions. --- input/manager.c | 532 ++++++++------------------------------------------------ 1 file changed, 68 insertions(+), 464 deletions(-) (limited to 'input/manager.c') diff --git a/input/manager.c b/input/manager.c index 2e138c6b..4b25843d 100644 --- a/input/manager.c +++ b/input/manager.c @@ -52,10 +52,7 @@ #include "error.h" #include "manager.h" #include "storage.h" - -static const char *pnp_uuid = "00001200-0000-1000-8000-00805f9b34fb"; -static const char *hid_uuid = "00001124-0000-1000-8000-00805f9b34fb"; -static const char *headset_uuid = "00001108-0000-1000-8000-00805f9b34fb"; +#include "glib-helper.h" struct pending_req { char *adapter_path; /* Local adapter D-Bus path */ @@ -119,70 +116,6 @@ static void pending_req_free(struct pending_req *pr) g_free(pr); } -static int get_record(struct pending_req *pr, uint32_t handle, - DBusPendingCallNotifyFunction cb) -{ - DBusMessage *msg; - DBusPendingCall *pending; - char addr[18]; - const char *paddr = addr; - - msg = dbus_message_new_method_call("org.bluez", pr->adapter_path, - "org.bluez.Adapter", "GetRemoteServiceRecord"); - if (!msg) - return -1; - - ba2str(&pr->dst, addr); - dbus_message_append_args(msg, - DBUS_TYPE_STRING, &paddr, - DBUS_TYPE_UINT32, &handle, - DBUS_TYPE_INVALID); - - if (dbus_connection_send_with_reply(pr->conn, msg, &pending, -1) == FALSE) { - error("Can't send D-Bus message."); - dbus_message_unref(msg); - return -1; - } - - dbus_pending_call_set_notify(pending, cb, pr, NULL); - dbus_pending_call_unref(pending); - dbus_message_unref(msg); - - return 0; -} - -static int get_handles(struct pending_req *pr, const char *uuid, - DBusPendingCallNotifyFunction cb) -{ - DBusMessage *msg; - DBusPendingCall *pending; - char addr[18]; - const char *paddr = addr; - - msg = dbus_message_new_method_call("org.bluez", pr->adapter_path, - "org.bluez.Adapter", "GetRemoteServiceHandles"); - if (!msg) - return -1; - - ba2str(&pr->dst, addr); - dbus_message_append_args(msg, - DBUS_TYPE_STRING, &paddr, - DBUS_TYPE_STRING, &uuid, - DBUS_TYPE_INVALID); - - if (dbus_connection_send_with_reply(pr->conn, msg, &pending, -1) == FALSE) { - error("Can't send D-Bus message."); - dbus_message_unref(msg); - return -1; - } - - dbus_pending_call_set_notify(pending, cb, pr, NULL); - dbus_pending_call_unref(pending); - dbus_message_unref(msg); - - return 0; -} - static void epox_endian_quirk(unsigned char *data, int size) { /* USAGE_PAGE (Keyboard) 05 07 @@ -279,42 +212,17 @@ static void extract_pnp_record(sdp_record_t *rec, struct hidp_connadd_req *req) req->version = pdlist ? pdlist->val.uint16 : 0x0000; } -static gboolean interrupt_connect_cb(GIOChannel *chan, - GIOCondition cond, struct pending_req *pr) +static void interrupt_connect_cb(GIOChannel *chan, int err, gpointer user_data) { + struct pending_req *pr = user_data; struct hidp_connadd_req hidp; DBusMessage *reply; const char *path; - int isk, ret, err; - socklen_t len; memset(&hidp, 0, sizeof(hidp)); - isk = g_io_channel_unix_get_fd(chan); - - if (cond & G_IO_NVAL) { - err = EHOSTDOWN; - isk = -1; - goto failed; - } - - if (cond & (G_IO_HUP | G_IO_ERR)) { - err = EHOSTDOWN; - error("Hangup or error on HIDP interrupt socket"); - goto failed; - - } - - len = sizeof(ret); - if (getsockopt(isk, SOL_SOCKET, SO_ERROR, &ret, &len) < 0) { - err = errno; - error("getsockopt(SO_ERROR): %s (%d)", strerror(err), err); - goto failed; - } - - if (ret != 0) { - err = ret; - error("connect(): %s (%d)", strerror(ret), ret); + if (err < 0) { + error("connect(): %s (%d)", strerror(-err), -err); goto failed; } @@ -351,74 +259,38 @@ failed: error_connection_attempt_failed(pr->conn, pr->msg, err); cleanup: - if (isk >= 0) - close(isk); - close(pr->ctrl_sock); pending_req_free(pr); if (hidp.rd_data) g_free(hidp.rd_data); - - return FALSE; } -static gboolean control_connect_cb(GIOChannel *chan, - GIOCondition cond, struct pending_req *pr) +static void control_connect_cb(GIOChannel *chan, int err, gpointer user_data) { - int ret, csk, err; - socklen_t len; - - csk = g_io_channel_unix_get_fd(chan); - - if (cond & G_IO_NVAL) { - err = EHOSTDOWN; - csk = -1; - goto failed; - } + struct pending_req *pr = user_data; - if (cond & (G_IO_HUP | G_IO_ERR)) { - err = EHOSTDOWN; - error("Hangup or error on HIDP control socket"); + if (err < 0) { + error("connect(): %s (%d)", strerror(-err), -err); goto failed; - } /* Set HID control channel */ - pr->ctrl_sock = csk; - - len = sizeof(ret); - if (getsockopt(csk, SOL_SOCKET, SO_ERROR, &ret, &len) < 0) { - err = errno; - error("getsockopt(SO_ERROR): %s (%d)", strerror(err), err); - goto failed; - } - - if (ret != 0) { - err = ret; - error("connect(): %s (%d)", strerror(ret), ret); - goto failed; - } + pr->ctrl_sock = g_io_channel_unix_get_fd(chan); /* Connect to the HID interrupt channel */ - if (l2cap_connect(&pr->src, &pr->dst, L2CAP_PSM_HIDP_INTR, - (GIOFunc) interrupt_connect_cb, pr) < 0) { - - err = errno; - error("L2CAP connect failed:%s (%d)", strerror(errno), errno); + err = bt_l2cap_connect(&pr->src, &pr->dst, L2CAP_PSM_HIDP_INTR, + interrupt_connect_cb, pr); + if (err < 0) { + error("L2CAP connect failed:%s (%d)", strerror(-err), -err); goto failed; } - return FALSE; + return; failed: - if (csk >= 0) - close(csk); - - error_connection_attempt_failed(pr->conn, pr->msg, err); + error_connection_attempt_failed(pr->conn, pr->msg, -err); pending_req_free(pr); - - return FALSE; } static void create_bonding_reply(DBusPendingCall *call, void *data) @@ -426,6 +298,7 @@ static void create_bonding_reply(DBusPendingCall *call, void *data) DBusMessage *reply = dbus_pending_call_steal_reply(call); struct pending_req *pr = data; DBusError derr; + int err; dbus_error_init(&derr); if (dbus_set_error_from_message(&derr, reply)) { @@ -440,36 +313,15 @@ static void create_bonding_reply(DBusPendingCall *call, void *data) dbus_message_unref(reply); - if (l2cap_connect(&pr->src, &pr->dst, L2CAP_PSM_HIDP_CTRL, - (GIOFunc) control_connect_cb, pr) < 0) { - int err = errno; - error_connection_attempt_failed(pr->conn, pr->msg, err); - error("L2CAP connect failed:%s (%d)", strerror(err), err); + err = bt_l2cap_connect(&pr->src, &pr->dst, L2CAP_PSM_HIDP_CTRL, + control_connect_cb, pr); + if (err < 0) { + error("L2CAP connect failed:%s (%d)", strerror(-err), -err); + error_connection_attempt_failed(pr->conn, pr->msg, -err); pending_req_free(pr); } } -static void finish_sdp_transaction(bdaddr_t *dba) -{ - char address[18], *addr_ptr = address; - DBusMessage *msg; - - ba2str(dba, address); - - msg = dbus_message_new_method_call("org.bluez", "/org/bluez/hci0", - "org.bluez.Adapter", - "FinishRemoteServiceTransaction"); - if (!msg) { - error("Unable to allocate new method call"); - return; - } - - dbus_message_append_args(msg, DBUS_TYPE_STRING, &addr_ptr, - DBUS_TYPE_INVALID); - - send_message_and_unref(connection, msg); -} - static int create_bonding(struct pending_req *pr) { DBusPendingCall *pending; @@ -496,53 +348,23 @@ static int create_bonding(struct pending_req *pr) return 0; } -static void hid_record_reply(DBusPendingCall *call, void *data) +static void hid_record_cb(sdp_list_t *recs, int err, gpointer user_data) { - DBusMessage *reply = dbus_pending_call_steal_reply(call); - struct pending_req *pr = data; - DBusError derr; - uint8_t *rec_bin; - int len, scanned; + struct pending_req *pr = user_data; - dbus_error_init(&derr); - if (dbus_set_error_from_message(&derr, reply)) { - /* FIXME : to not try to be clever about - hcid error but forward as is to the user */ - if (dbus_error_has_name(&derr, - "org.bluez.Error.ConnectionAttemptFailed")) - error_connection_attempt_failed(pr->conn, - pr->msg, EIO); - else - error_not_supported(pr->conn, pr->msg); - - error("GetRemoteServiceRecord failed: %s(%s)", - derr.name, derr.message); - goto fail; - } - - finish_sdp_transaction(&pr->dst); - - if (!dbus_message_get_args(reply, &derr, - DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &rec_bin, &len, - DBUS_TYPE_INVALID)) { + if (err < 0) { error_not_supported(pr->conn, pr->msg); - error("%s: %s", derr.name, derr.message); + error("SDP search error: %s (%d)", strerror(-err), -err); goto fail; } - if (len == 0) { + if (!recs || !recs->data) { error_not_supported(pr->conn, pr->msg); error("Invalid HID service record length"); goto fail; } - pr->hid_rec = sdp_extract_pdu(rec_bin, &scanned); - if (!pr->hid_rec) { - error_not_supported(pr->conn, pr->msg); - goto fail; - } - - dbus_message_unref(reply); + pr->hid_rec = recs->data; if (strcmp("CreateSecureDevice", dbus_message_get_member(pr->msg)) == 0) { sdp_data_t *d; @@ -564,240 +386,76 @@ static void hid_record_reply(DBusPendingCall *call, void *data) } /* No encryption or link key already exists -- connect control channel */ - if (l2cap_connect(&pr->src, &pr->dst, L2CAP_PSM_HIDP_CTRL, - (GIOFunc) control_connect_cb, pr) < 0) { - int err = errno; - error("L2CAP connect failed:%s (%d)", strerror(err), err); - error_connection_attempt_failed(pr->conn, pr->msg, err); + err = bt_l2cap_connect(&pr->src, &pr->dst, L2CAP_PSM_HIDP_CTRL, + control_connect_cb, pr); + if (err < 0) { + error("L2CAP connect failed:%s (%d)", strerror(-err), -err); + error_connection_attempt_failed(pr->conn, pr->msg, -err); goto fail; } /* Wait L2CAP connect */ return; -fail: - dbus_error_free(&derr); - pending_req_free(pr); - dbus_message_unref(reply); -} - -static void hid_handle_reply(DBusPendingCall *call, void *data) -{ - DBusMessage *reply = dbus_pending_call_steal_reply(call); - struct pending_req *pr = data; - uint32_t *phandle; - DBusError derr; - int len; - - dbus_error_init(&derr); - if (dbus_set_error_from_message(&derr, reply)) { - /* FIXME : to not try to be clever about - hcid error but forward as is to the user */ - if (dbus_error_has_name(&derr, - "org.bluez.Error.ConnectionAttemptFailed")) - error_connection_attempt_failed(pr->conn, - pr->msg, EIO); - else - error_not_supported(pr->conn, pr->msg); - - error("GetRemoteServiceHandles: %s(%s)", - derr.name, derr.message); - goto fail; - } - - if (!dbus_message_get_args(reply, &derr, - DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &phandle, &len, - DBUS_TYPE_INVALID)) { - error_not_supported(pr->conn, pr->msg); - error("%s: %s", derr.name, derr.message); - goto fail; - } - - if (len == 0) { - error_not_supported(pr->conn, pr->msg); - error("HID record handle not found"); - goto fail; - } - - if (get_record(pr, *phandle, hid_record_reply) < 0) { - error_not_supported(pr->conn, pr->msg); - error("HID service attribute request failed"); - goto fail; - } else { - /* Wait record reply */ - goto done; - } fail: - dbus_error_free(&derr); pending_req_free(pr); - -done: - dbus_message_unref(reply); } -static void pnp_record_reply(DBusPendingCall *call, void *data) +static void pnp_record_cb(sdp_list_t *recs, int err, gpointer user_data) { - DBusMessage *reply = dbus_pending_call_steal_reply(call); - struct pending_req *pr = data; - DBusError derr; - uint8_t *rec_bin; - int len, scanned; + struct pending_req *pr = user_data; + uuid_t uuid; - dbus_error_init(&derr); - if (dbus_set_error_from_message(&derr, reply)) { - /* FIXME : to not try to be clever about - hcid error but forward as is to the user */ - if (dbus_error_has_name(&derr, - "org.bluez.Error.ConnectionAttemptFailed")) - error_connection_attempt_failed(pr->conn, pr->msg, - EIO); - else - error_not_supported(pr->conn, pr->msg); - - error("GetRemoteServiceRecord: %s(%s)", - derr.name, derr.message); - goto fail; - } - - if (!dbus_message_get_args(reply, &derr, - DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &rec_bin, &len, - DBUS_TYPE_INVALID)) { + if (err < 0) { error_not_supported(pr->conn, pr->msg); - error("%s: %s", derr.name, derr.message); + error("SDP search error: %s (%d)", strerror(-err), -err); goto fail; } - if (len == 0) { + if (!recs || !recs->data) { error_not_supported(pr->conn, pr->msg); error("Invalid PnP service record length"); goto fail; } - pr->pnp_rec = sdp_extract_pdu(rec_bin, &scanned); - if (get_handles(pr, hid_uuid, hid_handle_reply) < 0) { + pr->pnp_rec = recs->data; + sdp_uuid16_create(&uuid, HID_SVCLASS_ID); + err = bt_search_service(&pr->src, &pr->dst, &uuid, hid_record_cb, + pr, NULL); + if (err < 0) { error_not_supported(pr->conn, pr->msg); error("HID service search request failed"); goto fail; - } else { - /* Wait handle reply */ - goto done; } -fail: - dbus_error_free(&derr); - pending_req_free(pr); - -done: - dbus_message_unref(reply); -} - -static void pnp_handle_reply(DBusPendingCall *call, void *data) -{ - DBusMessage *reply = dbus_pending_call_steal_reply(call); - struct pending_req *pr = data; - DBusError derr; - uint32_t *phandle; - int len; - - dbus_error_init(&derr); - if (dbus_set_error_from_message(&derr, reply)) { - /* FIXME : to not try to be clever about - hcid error but forward as is to the user */ - if (dbus_error_has_name(&derr, - "org.bluez.Error.ConnectionAttemptFailed")) - error_connection_attempt_failed(pr->conn, pr->msg, - EIO); - else - error_not_supported(pr->conn, pr->msg); - - error("GetRemoteServiceHandles: %s(%s)", - derr.name, derr.message); - goto fail; - } - - if (!dbus_message_get_args(reply, &derr, - DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &phandle, &len, - DBUS_TYPE_INVALID)) { - error_not_supported(pr->conn, pr->msg); - error("%s: %s", derr.name, derr.message); - goto fail; - } - - if (len == 0) { - /* PnP is optional: Ignore it and request the HID handle */ - if (get_handles(pr, hid_uuid, hid_handle_reply) < 0) { - error_not_supported(pr->conn, pr->msg); - error("HID service search request failed"); - goto fail; - } - } else { - /* Request PnP record */ - if (get_record(pr, *phandle, pnp_record_reply) < 0) { - error_not_supported(pr->conn, pr->msg); - error("PnP service attribute request failed"); - goto fail; - } - } - - /* Wait HID handle reply or PnP record reply */ - goto done; + return; fail: - dbus_error_free(&derr); pending_req_free(pr); - -done: - dbus_message_unref(reply); } -static void headset_record_reply(DBusPendingCall *call, void *data) +static void headset_record_cb(sdp_list_t *recs, int err, gpointer user_data) { - DBusMessage *reply = dbus_pending_call_steal_reply(call); - DBusMessage *pr_reply; - DBusError derr; - struct pending_req *pr = data; - uint8_t *rec_bin; + struct pending_req *pr = user_data; + DBusMessage *reply; sdp_record_t *rec; sdp_list_t *protos; const char *path; - int len, scanned; uint8_t ch; - dbus_error_init(&derr); - if (dbus_set_error_from_message(&derr, reply)) { - /* FIXME : to not try to be clever about - hcid error but forward as is to the user */ - if (dbus_error_has_name(&derr, - "org.bluez.Error.ConnectionAttemptFailed")) - error_connection_attempt_failed(pr->conn, pr->msg, - EIO); - else - error_not_supported(pr->conn, pr->msg); - - error("GetRemoteServiceRecord: %s(%s)", - derr.name, derr.message); - goto fail; - } - - if (!dbus_message_get_args(reply, &derr, - DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &rec_bin, &len, - DBUS_TYPE_INVALID)) { + if (err < 0) { error_not_supported(pr->conn, pr->msg); - error("%s: %s", derr.name, derr.message); + error("SDP search error: %s (%d)", strerror(-err), -err); goto fail; } - if (len == 0) { + if (!recs || !recs->data) { error_not_supported(pr->conn, pr->msg); error("Invalid headset service record length"); goto fail; } - rec = sdp_extract_pdu(rec_bin, &scanned); - if (!rec) { - error_not_supported(pr->conn, pr->msg); - goto fail; - } + rec = recs->data; if (sdp_get_access_protos(rec, &protos) < 0) { error_not_supported(pr->conn, pr->msg); @@ -830,73 +488,16 @@ static void headset_record_reply(DBusPendingCall *call, void *data) device_paths = g_slist_append(device_paths, g_strdup(path)); - pr_reply = dbus_message_new_method_return(pr->msg); + reply = dbus_message_new_method_return(pr->msg); - dbus_message_append_args(pr_reply, + dbus_message_append_args(reply, DBUS_TYPE_STRING, &path, DBUS_TYPE_INVALID); - send_message_and_unref(pr->conn, pr_reply); - -fail: - dbus_error_free(&derr); - pending_req_free(pr); - dbus_message_unref(reply); -} - -static void headset_handle_reply(DBusPendingCall *call, void *data) -{ - DBusMessage *reply = dbus_pending_call_steal_reply(call); - struct pending_req *pr = data; - DBusError derr; - uint32_t *phandle; - int len; - - dbus_error_init(&derr); - if (dbus_set_error_from_message(&derr, reply)) { - /* FIXME : to not try to be clever about - hcid error but forward as is to the user */ - if (dbus_error_has_name(&derr, - "org.bluez.Error.ConnectionAttemptFailed")) - error_connection_attempt_failed(pr->conn, pr->msg, - EIO); - else - error_not_supported(pr->conn, pr->msg); - - error("GetRemoteServiceHandles: %s(%s)", - derr.name, derr.message); - goto fail; - } - - if (!dbus_message_get_args(reply, &derr, - DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &phandle, &len, - DBUS_TYPE_INVALID)) { - error_not_supported(pr->conn, pr->msg); - error("%s: %s", derr.name, derr.message); - goto fail; - } - - if (len == 0) { - error_not_supported(pr->conn, pr->msg); - error("Headset record handle not found"); - goto fail; - } - - if (get_record(pr, *phandle, headset_record_reply) < 0) { - error_not_supported(pr->conn, pr->msg); - error("Headset service attribute request failed"); - goto fail; - } else { - /* Wait record reply */ - goto done; - } + send_message_and_unref(pr->conn, reply); fail: - dbus_error_free(&derr); pending_req_free(pr); - -done: - dbus_message_unref(reply); } static DBusHandlerResult create_device(DBusConnection *conn, @@ -907,7 +508,9 @@ static DBusHandlerResult create_device(DBusConnection *conn, const char *addr; bdaddr_t src, dst; uint32_t cls = 0; - int dev_id; + int dev_id, err; + uuid_t uuid; + bt_callback_t cb; dbus_error_init(&derr); if (!dbus_message_get_args(msg, &derr, @@ -946,23 +549,24 @@ static DBusHandlerResult create_device(DBusConnection *conn, switch (cls & 0x1f00) { case 0x0500: /* Peripheral */ case 0x0200: /* Phone */ - if (get_handles(pr, pnp_uuid, pnp_handle_reply) < 0) { - pending_req_free(pr); - return error_not_supported(conn, msg); - } + sdp_uuid16_create(&uuid, PNP_INFO_SVCLASS_ID); + cb = pnp_record_cb; break; case 0x0400: /* Fake input */ - if (get_handles(pr, headset_uuid, - headset_handle_reply) < 0) { - pending_req_free(pr); - return error_not_supported(conn, msg); - } + sdp_uuid16_create(&uuid, HEADSET_SVCLASS_ID); + cb = headset_record_cb; break; default: pending_req_free(pr); return error_not_supported(conn, msg); } + err = bt_search_service(&src, &dst, &uuid, cb, pr, NULL); + if (err < 0) { + pending_req_free(pr); + return error_not_supported(conn, msg); + } + return DBUS_HANDLER_RESULT_HANDLED; } -- cgit From 0c5239ae4bd876e113ecc78ae383bac9483c2a83 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Tue, 29 Apr 2008 20:35:57 +0000 Subject: Fix possible memory leak where the records lists were not freed. --- input/manager.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) (limited to 'input/manager.c') diff --git a/input/manager.c b/input/manager.c index 4b25843d..8d0a9160 100644 --- a/input/manager.c +++ b/input/manager.c @@ -60,8 +60,8 @@ struct pending_req { bdaddr_t dst; /* Peer BT address */ DBusConnection *conn; DBusMessage *msg; - sdp_record_t *pnp_rec; - sdp_record_t *hid_rec; + sdp_list_t *pnp_recs; + sdp_list_t *hid_recs; int ctrl_sock; }; @@ -107,11 +107,11 @@ static void pending_req_free(struct pending_req *pr) if (pr->msg) dbus_message_unref(pr->msg); - if (pr->pnp_rec) - sdp_record_free(pr->pnp_rec); + if (pr->pnp_recs) + sdp_list_free(pr->pnp_recs, (sdp_free_func_t) sdp_record_free); - if (pr->hid_rec) - sdp_record_free(pr->hid_rec); + if (pr->hid_recs) + sdp_list_free(pr->hid_recs, (sdp_free_func_t) sdp_record_free); g_free(pr); } @@ -226,9 +226,9 @@ static void interrupt_connect_cb(GIOChannel *chan, int err, gpointer user_data) goto failed; } - extract_hid_record(pr->hid_rec, &hidp); - if (pr->pnp_rec) - extract_pnp_record(pr->pnp_rec, &hidp); + extract_hid_record(pr->hid_recs->data, &hidp); + if (pr->pnp_recs) + extract_pnp_record(pr->pnp_recs->data, &hidp); store_device_info(&pr->src, &pr->dst, &hidp); @@ -364,13 +364,14 @@ static void hid_record_cb(sdp_list_t *recs, int err, gpointer user_data) goto fail; } - pr->hid_rec = recs->data; + pr->hid_recs = recs; if (strcmp("CreateSecureDevice", dbus_message_get_member(pr->msg)) == 0) { sdp_data_t *d; /* Pairing mandatory for keyboard and combo */ - d = sdp_data_get(pr->hid_rec, SDP_ATTR_HID_DEVICE_SUBCLASS); + d = sdp_data_get(pr->hid_recs->data, + SDP_ATTR_HID_DEVICE_SUBCLASS); if (d && (d->val.uint8 & 0x40) && !has_bonding(&pr->src, &pr->dst)) { if (create_bonding(pr) < 0) { @@ -418,7 +419,7 @@ static void pnp_record_cb(sdp_list_t *recs, int err, gpointer user_data) goto fail; } - pr->pnp_rec = recs->data; + pr->pnp_recs = recs; sdp_uuid16_create(&uuid, HID_SVCLASS_ID); err = bt_search_service(&pr->src, &pr->dst, &uuid, hid_record_cb, pr, NULL); -- cgit From c13abd60b0fd396820fe8160b893e95df7ed286b Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Wed, 30 Apr 2008 18:46:19 +0000 Subject: input: close interrupt channel after CreateDevice has been called --- input/manager.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'input/manager.c') diff --git a/input/manager.c b/input/manager.c index 8d0a9160..d7476cd7 100644 --- a/input/manager.c +++ b/input/manager.c @@ -260,6 +260,8 @@ failed: cleanup: close(pr->ctrl_sock); + g_io_channel_close(chan); + g_io_channel_unref(chan); pending_req_free(pr); if (hidp.rd_data) -- cgit From 2d5441331d402a0d78c4b84a028df076f6aab8cf Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Wed, 30 Apr 2008 19:37:46 +0000 Subject: Fix possible memory leak when closing control channel. --- input/manager.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'input/manager.c') diff --git a/input/manager.c b/input/manager.c index d7476cd7..9f8dcf66 100644 --- a/input/manager.c +++ b/input/manager.c @@ -62,7 +62,7 @@ struct pending_req { DBusMessage *msg; sdp_list_t *pnp_recs; sdp_list_t *hid_recs; - int ctrl_sock; + GIOChannel *ctrl_channel; }; static GSList *device_paths = NULL; /* Input registered paths */ @@ -259,7 +259,8 @@ failed: error_connection_attempt_failed(pr->conn, pr->msg, err); cleanup: - close(pr->ctrl_sock); + g_io_channel_close(pr->ctrl_channel); + g_io_channel_unref(pr->ctrl_channel); g_io_channel_close(chan); g_io_channel_unref(chan); pending_req_free(pr); @@ -278,7 +279,7 @@ static void control_connect_cb(GIOChannel *chan, int err, gpointer user_data) } /* Set HID control channel */ - pr->ctrl_sock = g_io_channel_unix_get_fd(chan); + pr->ctrl_channel = chan; /* Connect to the HID interrupt channel */ err = bt_l2cap_connect(&pr->src, &pr->dst, L2CAP_PSM_HIDP_INTR, -- cgit From fd18cec597d56cb2ad322ba04c5ed1b5516f7df3 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Mon, 5 May 2008 17:55:29 +0000 Subject: Fix possible double free in case of connecting to interrupt psm fails. --- input/manager.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'input/manager.c') diff --git a/input/manager.c b/input/manager.c index 9f8dcf66..51085279 100644 --- a/input/manager.c +++ b/input/manager.c @@ -226,6 +226,9 @@ static void interrupt_connect_cb(GIOChannel *chan, int err, gpointer user_data) goto failed; } + g_io_channel_close(chan); + g_io_channel_unref(chan); + extract_hid_record(pr->hid_recs->data, &hidp); if (pr->pnp_recs) extract_pnp_record(pr->pnp_recs->data, &hidp); @@ -261,8 +264,6 @@ failed: cleanup: g_io_channel_close(pr->ctrl_channel); g_io_channel_unref(pr->ctrl_channel); - g_io_channel_close(chan); - g_io_channel_unref(chan); pending_req_free(pr); if (hidp.rd_data) -- cgit From f85b9560ece47c94ec82466cba9c44da715591d9 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Wed, 7 May 2008 18:39:36 +0000 Subject: Make bt_l2cap_connect to take mtu as paramter. --- input/manager.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'input/manager.c') diff --git a/input/manager.c b/input/manager.c index 51085279..1c024c9c 100644 --- a/input/manager.c +++ b/input/manager.c @@ -283,7 +283,7 @@ static void control_connect_cb(GIOChannel *chan, int err, gpointer user_data) pr->ctrl_channel = chan; /* Connect to the HID interrupt channel */ - err = bt_l2cap_connect(&pr->src, &pr->dst, L2CAP_PSM_HIDP_INTR, + err = bt_l2cap_connect(&pr->src, &pr->dst, L2CAP_PSM_HIDP_INTR, 0, interrupt_connect_cb, pr); if (err < 0) { error("L2CAP connect failed:%s (%d)", strerror(-err), -err); @@ -317,7 +317,7 @@ static void create_bonding_reply(DBusPendingCall *call, void *data) dbus_message_unref(reply); - err = bt_l2cap_connect(&pr->src, &pr->dst, L2CAP_PSM_HIDP_CTRL, + err = bt_l2cap_connect(&pr->src, &pr->dst, L2CAP_PSM_HIDP_CTRL, 0, control_connect_cb, pr); if (err < 0) { error("L2CAP connect failed:%s (%d)", strerror(-err), -err); @@ -391,7 +391,7 @@ static void hid_record_cb(sdp_list_t *recs, int err, gpointer user_data) } /* No encryption or link key already exists -- connect control channel */ - err = bt_l2cap_connect(&pr->src, &pr->dst, L2CAP_PSM_HIDP_CTRL, + err = bt_l2cap_connect(&pr->src, &pr->dst, L2CAP_PSM_HIDP_CTRL, 0, control_connect_cb, pr); if (err < 0) { error("L2CAP connect failed:%s (%d)", strerror(-err), -err); -- cgit From e7d668ac9e813bc9922ee7d771848bd8822d5d1f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 8 May 2008 20:23:45 +0000 Subject: Move D-Bus watch functions into libgdbus --- input/manager.c | 1 - 1 file changed, 1 deletion(-) (limited to 'input/manager.c') diff --git a/input/manager.c b/input/manager.c index 1c024c9c..11e14514 100644 --- a/input/manager.c +++ b/input/manager.c @@ -42,7 +42,6 @@ #include -#include "dbus.h" #include "dbus-helper.h" #include "logging.h" #include "textfile.h" -- cgit From 15ea15b3a752f0487bc50d0ea04925f1b9d33dcb Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 8 May 2008 22:19:14 +0000 Subject: Move D-Bus object and interface helpers into libgdbus --- input/manager.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'input/manager.c') diff --git a/input/manager.c b/input/manager.c index 11e14514..618641f1 100644 --- a/input/manager.c +++ b/input/manager.c @@ -39,10 +39,9 @@ #include #include - #include +#include -#include "dbus-helper.h" #include "logging.h" #include "textfile.h" -- cgit From 2ce4523624b67b48da037beceffe5710144850ec Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 14 May 2008 21:49:07 +0000 Subject: Add support for IdleTimeout config option --- input/manager.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'input/manager.c') diff --git a/input/manager.c b/input/manager.c index 618641f1..13ca178d 100644 --- a/input/manager.c +++ b/input/manager.c @@ -63,6 +63,8 @@ struct pending_req { GIOChannel *ctrl_channel; }; +static int idle_timeout = 0; + static GSList *device_paths = NULL; /* Input registered paths */ static DBusConnection *connection = NULL; @@ -227,6 +229,8 @@ static void interrupt_connect_cb(GIOChannel *chan, int err, gpointer user_data) g_io_channel_close(chan); g_io_channel_unref(chan); + hidp.idle_to = idle_timeout * 60; + extract_hid_record(pr->hid_recs->data, &hidp); if (pr->pnp_recs) extract_pnp_record(pr->pnp_recs->data, &hidp); @@ -753,9 +757,18 @@ static DBusSignalVTable manager_signals[] = { { NULL, NULL } }; -int input_manager_init(DBusConnection *conn) +int input_manager_init(DBusConnection *conn, GKeyFile *config) { - dbus_connection_set_exit_on_disconnect(conn, TRUE); + GError *err = NULL; + + if (config) { + idle_timeout = g_key_file_get_integer(config, "General", + "IdleTimeout", &err); + if (err) { + debug("input.conf: %s", err->message); + g_error_free(err); + } + } if (!dbus_connection_create_object_path(conn, INPUT_PATH, NULL, manager_unregister)) { -- cgit From 0094809955895c974fbe95f2d3ed13f420a6a6ed Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Wed, 14 May 2008 22:16:16 +0000 Subject: Make bt_io_callback_t to take both source and destination. --- input/manager.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'input/manager.c') diff --git a/input/manager.c b/input/manager.c index 13ca178d..9ed1f195 100644 --- a/input/manager.c +++ b/input/manager.c @@ -212,7 +212,9 @@ static void extract_pnp_record(sdp_record_t *rec, struct hidp_connadd_req *req) req->version = pdlist ? pdlist->val.uint16 : 0x0000; } -static void interrupt_connect_cb(GIOChannel *chan, int err, gpointer user_data) +static void interrupt_connect_cb(GIOChannel *chan, int err, + const bdaddr_t *src, const bdaddr_t *dst, + gpointer user_data) { struct pending_req *pr = user_data; struct hidp_connadd_req hidp; @@ -272,7 +274,8 @@ cleanup: g_free(hidp.rd_data); } -static void control_connect_cb(GIOChannel *chan, int err, gpointer user_data) +static void control_connect_cb(GIOChannel *chan, int err, const bdaddr_t *src, + const bdaddr_t *dst, gpointer user_data) { struct pending_req *pr = user_data; -- cgit From fd9b76b9b1e225da8c8d5626fd5cca8e2b78158d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 27 May 2008 12:19:50 +0000 Subject: Convert input manager to use gdbus API --- input/manager.c | 119 ++++++++++++++++++++++++++++++-------------------------- 1 file changed, 63 insertions(+), 56 deletions(-) (limited to 'input/manager.c') diff --git a/input/manager.c b/input/manager.c index 9ed1f195..c5e075cc 100644 --- a/input/manager.c +++ b/input/manager.c @@ -510,11 +510,34 @@ fail: pending_req_free(pr); } -static DBusHandlerResult create_device(DBusConnection *conn, +static inline DBusMessage *adapter_not_available(DBusMessage *msg) +{ + return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed", + "Adapter not available"); +} + +static inline DBusMessage *already_exists(DBusMessage *msg) +{ + return g_dbus_create_error(msg, ERROR_INTERFACE ".AlreadyExists", + "Input Already exists"); +} + +static inline DBusMessage *not_supported(DBusMessage *msg) +{ + return g_dbus_create_error(msg, ERROR_INTERFACE ".NotSupported", + "Not supported"); +} + +static inline DBusMessage *does_not_exist(DBusMessage *msg) +{ + return g_dbus_create_error(msg, ERROR_INTERFACE ".AlreadyExists", + "Input doesn't exist"); +} + +static DBusMessage *create_device(DBusConnection *conn, DBusMessage *msg, void *data) { struct pending_req *pr; - DBusError derr; const char *addr; bdaddr_t src, dst; uint32_t cls = 0; @@ -522,39 +545,34 @@ static DBusHandlerResult create_device(DBusConnection *conn, uuid_t uuid; bt_callback_t cb; - dbus_error_init(&derr); - if (!dbus_message_get_args(msg, &derr, - DBUS_TYPE_STRING, &addr, - DBUS_TYPE_INVALID)) { - error_invalid_arguments(conn, msg, derr.message); - dbus_error_free(&derr); - return DBUS_HANDLER_RESULT_HANDLED; - } + if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &addr, + DBUS_TYPE_INVALID)) + return NULL; /* Get the default adapter */ dev_id = hci_get_route(NULL); if (dev_id < 0) { error("Bluetooth adapter not available"); - return error_failed(conn, msg, "Adapter not available"); + return adapter_not_available(msg); } if (hci_devba(dev_id, &src) < 0) { error("Can't get local adapter device info"); - return error_failed(conn, msg, "Adapter not available"); + return adapter_not_available(msg); } str2ba(addr, &dst); if (input_device_is_registered(&src, &dst)) - return error_already_exists(conn, msg, "Input Already exists"); + return already_exists(msg); if (read_device_class(&src, &dst, &cls) < 0) { error("Device class not available"); - return error_not_supported(conn, msg); + return not_supported(msg); } pr = pending_req_new(conn, msg, &src, &dst); if (!pr) - return DBUS_HANDLER_RESULT_NEED_MEMORY; + return NULL; switch (cls & 0x1f00) { case 0x0500: /* Peripheral */ @@ -568,57 +586,51 @@ static DBusHandlerResult create_device(DBusConnection *conn, break; default: pending_req_free(pr); - return error_not_supported(conn, msg); + return not_supported(msg); } err = bt_search_service(&src, &dst, &uuid, cb, pr, NULL); if (err < 0) { pending_req_free(pr); - return error_not_supported(conn, msg); + return not_supported(msg); } - return DBUS_HANDLER_RESULT_HANDLED; + return NULL; } -static DBusHandlerResult remove_device(DBusConnection *conn, +static DBusMessage *remove_device(DBusConnection *conn, DBusMessage *msg, void *data) { DBusMessage *reply; - DBusError derr; GSList *l; const char *path; int err; - dbus_error_init(&derr); - if (!dbus_message_get_args(msg, &derr, - DBUS_TYPE_STRING, &path, - DBUS_TYPE_INVALID)) { - error_invalid_arguments(conn, msg, derr.message); - dbus_error_free(&derr); - return DBUS_HANDLER_RESULT_HANDLED; - } + if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &path, + DBUS_TYPE_INVALID)) + return NULL; l = g_slist_find_custom(device_paths, path, (GCompareFunc) strcmp); if (!l) - return error_does_not_exist(conn, msg, "Input doesn't exist"); + return does_not_exist(msg); reply = dbus_message_new_method_return(msg); if (!reply) - return DBUS_HANDLER_RESULT_NEED_MEMORY; + return NULL; err = input_device_unregister(conn, path); if (err < 0) { dbus_message_unref(reply); - return error_failed_errno(conn, msg, -err); + return create_errno_message(msg, -err); } g_free(l->data); device_paths = g_slist_remove(device_paths, l->data); - return send_message_and_unref(conn, reply); + return reply; } -static DBusHandlerResult list_devices(DBusConnection *conn, +static DBusMessage *list_devices(DBusConnection *conn, DBusMessage *msg, void *data) { DBusMessageIter iter, iter_array; @@ -627,7 +639,7 @@ static DBusHandlerResult list_devices(DBusConnection *conn, reply = dbus_message_new_method_return(msg); if (!reply) - return DBUS_HANDLER_RESULT_NEED_MEMORY; + return NULL; dbus_message_iter_init_append(reply, &iter); dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, @@ -641,10 +653,10 @@ static DBusHandlerResult list_devices(DBusConnection *conn, dbus_message_iter_close_container(&iter, &iter_array); - return send_message_and_unref(conn, reply); + return reply; } -static void manager_unregister(DBusConnection *conn, void *data) +static void manager_unregister(void *data) { info("Unregistered manager path"); @@ -746,18 +758,20 @@ static void register_stored_inputs(void) closedir(dir); } -static DBusMethodVTable manager_methods[] = { - { "ListDevices", list_devices, "", "as" }, - { "CreateDevice", create_device, "s", "s" }, - { "CreateSecureDevice", create_device, "s", "s" }, - { "RemoveDevice", remove_device, "s", "" }, - { NULL, NULL, NULL, NULL }, +static GDBusMethodTable manager_methods[] = { + { "ListDevices", "", "as", list_devices }, + { "CreateDevice", "s", "s", create_device, + G_DBUS_METHOD_FLAG_ASYNC }, + { "CreateSecureDevice", "s", "s", create_device, + G_DBUS_METHOD_FLAG_ASYNC }, + { "RemoveDevice", "s", "", remove_device }, + { } }; -static DBusSignalVTable manager_signals[] = { +static GDBusSignalTable manager_signals[] = { { "DeviceCreated", "s" }, { "DeviceRemoved", "s" }, - { NULL, NULL } + { } }; int input_manager_init(DBusConnection *conn, GKeyFile *config) @@ -773,19 +787,11 @@ int input_manager_init(DBusConnection *conn, GKeyFile *config) } } - if (!dbus_connection_create_object_path(conn, INPUT_PATH, - NULL, manager_unregister)) { - error("D-Bus failed to register %s path", INPUT_PATH); - return -1; - } - - if (!dbus_connection_register_interface(conn, INPUT_PATH, - INPUT_MANAGER_INTERFACE, - manager_methods, - manager_signals, NULL)) { + if (g_dbus_register_interface(conn, INPUT_PATH, INPUT_MANAGER_INTERFACE, + manager_methods, manager_signals, NULL, + NULL, manager_unregister) == FALSE) { error("Failed to register %s interface to %s", INPUT_MANAGER_INTERFACE, INPUT_PATH); - dbus_connection_destroy_object_path(connection, INPUT_PATH); return -1; } @@ -803,7 +809,8 @@ int input_manager_init(DBusConnection *conn, GKeyFile *config) void input_manager_exit(void) { - dbus_connection_destroy_object_path(connection, INPUT_PATH); + g_dbus_unregister_interface(connection, INPUT_PATH, + INPUT_MANAGER_INTERFACE); server_stop(); -- cgit From ee47f9f75ecc4ea8756f9b301905ec7de5ac07a3 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 27 May 2008 18:05:38 +0000 Subject: Use message sending helpers --- input/manager.c | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) (limited to 'input/manager.c') diff --git a/input/manager.c b/input/manager.c index c5e075cc..b65ccb16 100644 --- a/input/manager.c +++ b/input/manager.c @@ -218,7 +218,6 @@ static void interrupt_connect_cb(GIOChannel *chan, int err, { struct pending_req *pr = user_data; struct hidp_connadd_req hidp; - DBusMessage *reply; const char *path; memset(&hidp, 0, sizeof(hidp)); @@ -252,16 +251,11 @@ static void interrupt_connect_cb(GIOChannel *chan, int err, device_paths = g_slist_append(device_paths, g_strdup(path)); - /* Replying to the requestor */ - reply = dbus_message_new_method_return(pr->msg); - - dbus_message_append_args(reply, - DBUS_TYPE_STRING, &path, - DBUS_TYPE_INVALID); - - send_message_and_unref(pr->conn, reply); + g_dbus_send_reply(pr->conn, pr->msg, DBUS_TYPE_STRING, &path, + DBUS_TYPE_INVALID); goto cleanup; + failed: error_connection_attempt_failed(pr->conn, pr->msg, err); @@ -447,7 +441,6 @@ fail: static void headset_record_cb(sdp_list_t *recs, int err, gpointer user_data) { struct pending_req *pr = user_data; - DBusMessage *reply; sdp_record_t *rec; sdp_list_t *protos; const char *path; @@ -498,13 +491,8 @@ static void headset_record_cb(sdp_list_t *recs, int err, gpointer user_data) device_paths = g_slist_append(device_paths, g_strdup(path)); - reply = dbus_message_new_method_return(pr->msg); - - dbus_message_append_args(reply, - DBUS_TYPE_STRING, &path, - DBUS_TYPE_INVALID); - - send_message_and_unref(pr->conn, reply); + g_dbus_send_reply(pr->conn, pr->msg, DBUS_TYPE_STRING, &path, + DBUS_TYPE_INVALID); fail: pending_req_free(pr); -- cgit From e8961085b8d3dabc5550a4f1b309ae06065d14b4 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 27 May 2008 18:16:17 +0000 Subject: Convert the input device handling to gdbus API --- input/manager.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) (limited to 'input/manager.c') diff --git a/input/manager.c b/input/manager.c index b65ccb16..aae101fd 100644 --- a/input/manager.c +++ b/input/manager.c @@ -332,7 +332,7 @@ static int create_bonding(struct pending_req *pr) char address[18], *addr_ptr = address; msg = dbus_message_new_method_call("org.bluez", pr->adapter_path, - "org.bluez.Adapter", "CreateBonding"); + "org.bluez.Adapter", "CreateBonding"); if (!msg) { error("Unable to allocate new method call"); return -1; @@ -589,7 +589,6 @@ static DBusMessage *create_device(DBusConnection *conn, static DBusMessage *remove_device(DBusConnection *conn, DBusMessage *msg, void *data) { - DBusMessage *reply; GSList *l; const char *path; int err; @@ -602,20 +601,14 @@ static DBusMessage *remove_device(DBusConnection *conn, if (!l) return does_not_exist(msg); - reply = dbus_message_new_method_return(msg); - if (!reply) - return NULL; - err = input_device_unregister(conn, path); - if (err < 0) { - dbus_message_unref(reply); + if (err < 0) return create_errno_message(msg, -err); - } g_free(l->data); device_paths = g_slist_remove(device_paths, l->data); - return reply; + return g_dbus_create_reply(msg, DBUS_TYPE_INVALID); } static DBusMessage *list_devices(DBusConnection *conn, -- cgit From 7c426c4c7e234e28a4dffcb7d88feb0eeefcd5ce Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Wed, 28 May 2008 07:39:21 +0000 Subject: input: removed old authorization method --- input/manager.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'input/manager.c') diff --git a/input/manager.c b/input/manager.c index aae101fd..65c51fb5 100644 --- a/input/manager.c +++ b/input/manager.c @@ -783,7 +783,7 @@ int input_manager_init(DBusConnection *conn, GKeyFile *config) /* Register well known HID devices */ register_stored_inputs(); - server_start(connection); + server_start(); return 0; } -- cgit From f80a7215275b229a597cf8d2bbc7e4e208af522c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 7 Jun 2008 19:30:24 +0000 Subject: Use g_dbus_emit_signal for sending D-Bus signals --- input/manager.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'input/manager.c') diff --git a/input/manager.c b/input/manager.c index 65c51fb5..2dfb9b2d 100644 --- a/input/manager.c +++ b/input/manager.c @@ -244,7 +244,7 @@ static void interrupt_connect_cb(GIOChannel *chan, int err, goto cleanup; } - dbus_connection_emit_signal(pr->conn, INPUT_PATH, + g_dbus_emit_signal(pr->conn, INPUT_PATH, INPUT_MANAGER_INTERFACE, "DeviceCreated", DBUS_TYPE_STRING, &path, DBUS_TYPE_INVALID); @@ -484,7 +484,7 @@ static void headset_record_cb(sdp_list_t *recs, int err, gpointer user_data) goto fail; } - dbus_connection_emit_signal(pr->conn, INPUT_PATH, + g_dbus_emit_signal(pr->conn, INPUT_PATH, INPUT_MANAGER_INTERFACE, "DeviceCreated", DBUS_TYPE_STRING, &path, DBUS_TYPE_INVALID); -- cgit