From 3d9966f38f1d6ca12c9e9e2eace5181ba04844b4 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Tue, 8 Apr 2008 22:35:49 +0000 Subject: Fix CreatePairedDevice and CreateDevice behavior. --- hcid/adapter.c | 243 ++++++++++++-------------------------------------------- hcid/adapter.h | 5 +- hcid/dbus-hci.c | 98 +++++++++++++---------- hcid/device.c | 107 +++++++++++++++++++++++-- hcid/device.h | 8 +- 5 files changed, 213 insertions(+), 248 deletions(-) diff --git a/hcid/adapter.c b/hcid/adapter.c index 1ffce314..12e92695 100644 --- a/hcid/adapter.c +++ b/hcid/adapter.c @@ -69,14 +69,6 @@ #define NUM_ELEMENTS(table) (sizeof(table)/sizeof(const char *)) -struct create_device_req { - char address[18]; /* Destination address */ - DBusConnection *conn; /* Connection reference */ - DBusMessage *msg; /* Message reference */ - guint id; /* Listener id */ - char *agent_path; /* Agent object path */ -}; - struct mode_req { struct adapter *adapter; DBusConnection *conn; /* Connection reference */ @@ -239,18 +231,26 @@ int pending_remote_name_cancel(struct adapter *adapter) return err; } -static struct bonding_request_info *bonding_request_new(bdaddr_t *peer, - DBusConnection *conn, - DBusMessage *msg) +static struct bonding_request_info *bonding_request_new(DBusConnection *conn, + DBusMessage *msg, + struct adapter *adapter, + const char *address) { struct bonding_request_info *bonding; + struct device *device; bonding = g_new0(struct bonding_request_info, 1); - bacpy(&bonding->bdaddr, peer); - bonding->conn = dbus_connection_ref(conn); - bonding->rq = dbus_message_ref(msg); + bonding->msg = dbus_message_ref(msg); + + /* FIXME: should be removed on 4.0 */ + if (hcid_dbus_use_experimental()) { + device = adapter_get_device(conn, adapter, address); + device->temporary = TRUE; + } + + str2ba(address, &bonding->bdaddr); return bonding; } @@ -2254,19 +2254,11 @@ static void reply_authentication_failure(struct bonding_request_info *bonding) status = bonding->hci_status ? bonding->hci_status : HCI_AUTHENTICATION_FAILURE; - reply = new_authentication_return(bonding->rq, status); + reply = new_authentication_return(bonding->msg, status); if (reply) send_message_and_unref(bonding->conn, reply); } -static void create_device_req_free(struct create_device_req *create) -{ - dbus_connection_unref(create->conn); - dbus_message_unref(create->msg); - g_free(create->agent_path); - g_free(create); -} - struct device *adapter_find_device(struct adapter *adapter, const char *dest) { struct device *device; @@ -2334,7 +2326,7 @@ static gboolean create_bonding_conn_complete(GIOChannel *io, GIOCondition cond, if (cond & G_IO_NVAL) { error_authentication_canceled(adapter->bonding->conn, - adapter->bonding->rq); + adapter->bonding->msg); goto cleanup; } @@ -2343,7 +2335,7 @@ static gboolean create_bonding_conn_complete(GIOChannel *io, GIOCondition cond, if (!adapter->bonding->auth_active) error_connection_attempt_failed(adapter->bonding->conn, - adapter->bonding->rq, + adapter->bonding->msg, ENETDOWN); else reply_authentication_failure(adapter->bonding); @@ -2357,7 +2349,7 @@ static gboolean create_bonding_conn_complete(GIOChannel *io, GIOCondition cond, if (getsockopt(sk, SOL_SOCKET, SO_ERROR, &ret, &len) < 0) { error("Can't get socket error: %s (%d)", strerror(errno), errno); - error_failed_errno(adapter->bonding->conn, adapter->bonding->rq, + error_failed_errno(adapter->bonding->conn, adapter->bonding->msg, errno); goto failed; } @@ -2367,7 +2359,7 @@ static gboolean create_bonding_conn_complete(GIOChannel *io, GIOCondition cond, reply_authentication_failure(adapter->bonding); else error_connection_attempt_failed(adapter->bonding->conn, - adapter->bonding->rq, + adapter->bonding->msg, ret); goto failed; } @@ -2376,7 +2368,7 @@ static gboolean create_bonding_conn_complete(GIOChannel *io, GIOCondition cond, if (getsockopt(sk, SOL_L2CAP, L2CAP_CONNINFO, &cinfo, &len) < 0) { error("Can't get connection info: %s (%d)", strerror(errno), errno); - error_failed_errno(adapter->bonding->conn, adapter->bonding->rq, + error_failed_errno(adapter->bonding->conn, adapter->bonding->msg, errno); goto failed; } @@ -2384,7 +2376,7 @@ static gboolean create_bonding_conn_complete(GIOChannel *io, GIOCondition cond, dd = hci_open_dev(adapter->dev_id); if (dd < 0) { error_no_such_adapter(adapter->bonding->conn, - adapter->bonding->rq); + adapter->bonding->msg); goto failed; } @@ -2405,7 +2397,7 @@ static gboolean create_bonding_conn_complete(GIOChannel *io, GIOCondition cond, if (hci_send_req(dd, &rq, 500) < 0) { error("Unable to send HCI request: %s (%d)", strerror(errno), errno); - error_failed_errno(adapter->bonding->conn, adapter->bonding->rq, + error_failed_errno(adapter->bonding->conn, adapter->bonding->msg, errno); hci_close_dev(dd); goto failed; @@ -2414,7 +2406,7 @@ static gboolean create_bonding_conn_complete(GIOChannel *io, GIOCondition cond, if (rp.status) { error("HCI_Authentication_Requested failed with status 0x%02x", rp.status); - error_failed_errno(adapter->bonding->conn, adapter->bonding->rq, + error_failed_errno(adapter->bonding->conn, adapter->bonding->msg, bt_error(rp.status)); hci_close_dev(dd); goto failed; @@ -2436,18 +2428,12 @@ failed: cleanup: name_listener_remove(adapter->bonding->conn, - dbus_message_get_sender(adapter->bonding->rq), + dbus_message_get_sender(adapter->bonding->msg), (name_cb_t) create_bond_req_exit, adapter); bonding_request_free(adapter->bonding); adapter->bonding = NULL; - if (adapter->create) { - name_listener_id_remove(adapter->create->id); - create_device_req_free(adapter->create); - adapter->create = NULL; - } - return FALSE; } @@ -2489,7 +2475,7 @@ static DBusHandlerResult create_bonding(DBusConnection *conn, DBusMessage *msg, if (sk < 0) return error_connection_attempt_failed(conn, msg, 0); - adapter->bonding = bonding_request_new(&bdaddr, conn, msg); + adapter->bonding = bonding_request_new(conn, msg, adapter, address); if (!adapter->bonding) { close(sk); return DBUS_HANDLER_RESULT_NEED_MEMORY; @@ -2532,33 +2518,33 @@ static DBusHandlerResult adapter_cancel_bonding(DBusConnection *conn, { struct adapter *adapter = data; DBusMessage *reply; - bdaddr_t peer_bdaddr; - const char *peer_addr; + const char *address; + bdaddr_t bdaddr; GSList *l; + struct bonding_request_info *bonding = adapter->bonding; if (!adapter->up) return error_not_ready(conn, msg); if (!dbus_message_get_args(msg, NULL, - DBUS_TYPE_STRING, &peer_addr, + DBUS_TYPE_STRING, &address, DBUS_TYPE_INVALID)) return error_invalid_arguments(conn, msg, NULL); - if (check_address(peer_addr) < 0) + if (check_address(address) < 0) return error_invalid_arguments(conn, msg, NULL); - str2ba(peer_addr, &peer_bdaddr); - - if (!adapter->bonding || bacmp(&adapter->bonding->bdaddr, &peer_bdaddr)) + str2ba(address, &bdaddr); + if (!bonding || bacmp(&bonding->bdaddr, &bdaddr)) return error_bonding_not_in_progress(conn, msg); - if (strcmp(dbus_message_get_sender(adapter->bonding->rq), + if (strcmp(dbus_message_get_sender(adapter->bonding->msg), dbus_message_get_sender(msg))) return error_not_authorized(conn, msg); adapter->bonding->cancel = 1; - l = g_slist_find_custom(adapter->pin_reqs, &peer_bdaddr, pin_req_cmp); + l = g_slist_find_custom(adapter->pin_reqs, &bdaddr, pin_req_cmp); if (l) { struct pending_pin_info *pin_req = l->data; @@ -2579,7 +2565,7 @@ static DBusHandlerResult adapter_cancel_bonding(DBusConnection *conn, } hci_send_cmd(dd, OGF_LINK_CTL, OCF_PIN_CODE_NEG_REPLY, - 6, &peer_bdaddr); + 6, &bdaddr); hci_close_dev(dd); } @@ -3688,77 +3674,29 @@ static DBusHandlerResult list_devices(DBusConnection *conn, return send_message_and_unref(conn, reply); } -static void create_device_exit(const char *name, struct adapter *adapter) -{ - create_device_req_free(adapter->create); - adapter->create = NULL; -} - -static void discover_services_cb(gpointer user_data, sdp_list_t *recs, int err) +static DBusHandlerResult create_device(DBusConnection *conn, + DBusMessage *msg, void *data) { - sdp_list_t *seq, *next, *svcclass; - struct adapter *adapter = user_data; + struct adapter *adapter = data; struct device *device; - DBusMessage *reply; - GSList *uuids; - bdaddr_t src, dst; - - /* Onwer exitted? */ - if (!adapter->create) { - sdp_list_free(recs, (sdp_free_func_t) sdp_record_free); - return; - } - - if (err < 0) { - error_connection_attempt_failed(adapter->create->conn, - adapter->create->msg, -err); - goto failed; - } - - uuids = NULL; - for (seq = recs; seq; seq = next) { - sdp_record_t *rec = (sdp_record_t *) seq->data; - - if (!rec) - break; - - svcclass = NULL; - if (sdp_get_service_classes(rec, &svcclass) == 0) { - /* Extract the first element and skip the remainning */ - gchar *uuid_str = bt_uuid2string(svcclass->data); - if (uuid_str) { - if (!g_slist_find_custom(uuids, uuid_str, - (GCompareFunc) strcmp)) - uuids = g_slist_insert_sorted(uuids, - uuid_str, (GCompareFunc) strcmp); - else - g_free(uuid_str); - } - sdp_list_free(svcclass, free); - } + const gchar *address; - next = seq->next; - } + if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &address, + DBUS_TYPE_INVALID) == FALSE) + return error_invalid_arguments(conn, msg, NULL); - sdp_list_free(recs, (sdp_free_func_t) sdp_record_free); + if (adapter_find_device(adapter, address)) + return error_already_exists(conn, msg, "Device already exists"); - device = device_create(adapter->create->conn, adapter, - adapter->create->address, uuids); + device = device_create(conn, adapter, address, NULL); if (!device) - goto failed; + return DBUS_HANDLER_RESULT_NEED_MEMORY; device->temporary = FALSE; - /* Reply create device request */ - reply = dbus_message_new_method_return(adapter->create->msg); - if (!reply) - goto failed; - dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &device->path, - DBUS_TYPE_INVALID); - send_message_and_unref(adapter->create->conn, reply); + device_browse(device, conn, msg); - dbus_connection_emit_signal(adapter->create->conn, - dbus_message_get_path(adapter->create->msg), + dbus_connection_emit_signal(conn, dbus_message_get_path(msg), ADAPTER_INTERFACE, "DeviceCreated", DBUS_TYPE_OBJECT_PATH, &device->path, @@ -3766,90 +3704,9 @@ static void discover_services_cb(gpointer user_data, sdp_list_t *recs, int err) adapter->devices = g_slist_append(adapter->devices, device); - /* Store the device's profiles in the filesystem */ - str2ba(adapter->address, &src); - str2ba(adapter->create->address, &dst); - if (uuids) { - gchar *str = bt_list2string(uuids); - write_device_profiles(&src, &dst, str); - g_free(str); - } else - write_device_profiles(&src, &dst, ""); - - if (adapter->create->agent_path) - create_bonding(adapter->create->conn, adapter->create->msg, - adapter->create->address, - adapter->create->agent_path, adapter); - -failed: - name_listener_id_remove(adapter->create->id); - create_device_req_free(adapter->create); - adapter->create = NULL; -} - -static DBusHandlerResult discover_services(DBusConnection *conn, - DBusMessage *msg, const char *address, - const char *agent_path, void *data) -{ - struct adapter *adapter = data; - struct create_device_req *create; - bdaddr_t src, dst; - int err; - GSList *l; - - if (check_address(address) < 0) - return error_invalid_arguments(conn, msg, NULL); - - l = g_slist_find_custom(adapter->devices, address, - (GCompareFunc) device_address_cmp); - if (l && agent_path) - return create_bonding(conn, msg, address, agent_path, data); - else if (l && !agent_path) - return error_already_exists(conn, msg, "Device already exists"); - - if (adapter->create) { - adapter->create->agent_path = g_strdup(agent_path); - return DBUS_HANDLER_RESULT_HANDLED; - } - - str2ba(adapter->address, &src); - str2ba(address, &dst); - err = bt_discover_services(&src, &dst, - discover_services_cb, adapter, NULL); - if (err < 0) { - error("Discover services failed!"); - return error_connection_attempt_failed(conn, msg, -err); - } - - create = g_new0(struct create_device_req, 1); - create->conn = dbus_connection_ref(conn); - create->msg = dbus_message_ref(msg); - create->id = name_listener_add(conn, - dbus_message_get_sender(msg), - (name_cb_t) create_device_exit, adapter); - strcpy(create->address, address); - create->agent_path = g_strdup(agent_path); - adapter->create = create; - return DBUS_HANDLER_RESULT_HANDLED; } -static DBusHandlerResult create_device(DBusConnection *conn, - DBusMessage *msg, void *data) -{ - struct adapter *adapter = data; - const gchar *address; - - if (adapter->create) - return error_in_progress(conn, msg, "CreateDevice in progress"); - - if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &address, - DBUS_TYPE_INVALID) == FALSE) - return error_invalid_arguments(conn, msg, NULL); - - return discover_services(conn, msg, address, NULL, data); -} - static DBusHandlerResult create_paired_device(DBusConnection *conn, DBusMessage *msg, void *data) { @@ -3861,7 +3718,7 @@ static DBusHandlerResult create_paired_device(DBusConnection *conn, DBUS_TYPE_INVALID) == FALSE) return error_invalid_arguments(conn, msg, NULL); - return discover_services(conn, msg, address, agent_path, data); + return create_bonding(conn, msg, address, agent_path, data); } static gint device_path_cmp(struct device *device, const gchar *path) @@ -3905,7 +3762,7 @@ static DBusHandlerResult remove_device(DBusConnection *conn, DBUS_TYPE_OBJECT_PATH, &device->path, DBUS_TYPE_INVALID); - device_destroy(device, conn); + device_remove(device, conn); adapter->devices = g_slist_remove(adapter->devices, device); return send_message_and_unref(conn, reply); diff --git a/hcid/adapter.h b/hcid/adapter.h index b02c6ccb..3449aec4 100644 --- a/hcid/adapter.h +++ b/hcid/adapter.h @@ -53,9 +53,9 @@ struct remote_dev_info { }; struct bonding_request_info { - bdaddr_t bdaddr; DBusConnection *conn; - DBusMessage *rq; + DBusMessage *msg; + bdaddr_t bdaddr; GIOChannel *io; guint io_id; int hci_status; @@ -107,7 +107,6 @@ struct adapter { struct bonding_request_info *bonding; GSList *pin_reqs; struct pending_dc_info *pending_dc; - struct create_device_req *create; GSList *devices; /* Devices structure pointers */ GSList *sessions; /* Request Mode sessions */ }; diff --git a/hcid/dbus-hci.c b/hcid/dbus-hci.c index 0cc3af6a..e27df03f 100644 --- a/hcid/dbus-hci.c +++ b/hcid/dbus-hci.c @@ -69,8 +69,8 @@ void bonding_request_free(struct bonding_request_info *bonding) if (!bonding) return; - if (bonding->rq) - dbus_message_unref(bonding->rq); + if (bonding->msg) + dbus_message_unref(bonding->msg); if (bonding->conn) dbus_connection_unref(bonding->conn); @@ -332,9 +332,9 @@ static void reply_pending_requests(const char *path, struct adapter *adapter) /* pending bonding */ if (adapter->bonding) { - error_authentication_canceled(connection, adapter->bonding->rq); + error_authentication_canceled(connection, adapter->bonding->msg); name_listener_remove(connection, - dbus_message_get_sender(adapter->bonding->rq), + dbus_message_get_sender(adapter->bonding->msg), (name_cb_t) create_bond_req_exit, adapter); if (adapter->bonding->io_id) @@ -471,7 +471,7 @@ int unregister_adapter_path(const char *path) if (adapter->devices) { g_slist_foreach(adapter->devices, - (GFunc) device_destroy, connection); + (GFunc) device_remove, connection); g_slist_free(adapter->devices); } @@ -956,8 +956,7 @@ static void passkey_cb(struct agent *agent, DBusError *err, const char *passkey, str2ba(device->address, &dba); if (err) { - if (device->temporary) - device_remove(connection, device); + hci_send_cmd(dev, OGF_LINK_CTL, OCF_PIN_CODE_NEG_REPLY, 6, &dba); goto done; @@ -1050,6 +1049,10 @@ void hcid_dbus_bonding_process_complete(bdaddr_t *local, bdaddr_t *peer, const char *paddr = peer_addr; GSList *l; int id; + DBusMessage *reply; + struct device *device; + struct bonding_request_info *bonding; + void *d; ba2str(local, local_addr); ba2str(peer, peer_addr); @@ -1074,50 +1077,60 @@ void hcid_dbus_bonding_process_complete(bdaddr_t *local, bdaddr_t *peer, peer); l = g_slist_find_custom(adapter->pin_reqs, peer, pin_req_cmp); - if (l) { - void *d = l->data; - adapter->pin_reqs = g_slist_remove(adapter->pin_reqs, l->data); - g_free(d); + if (!l || status) + goto proceed; - if (!status) { - send_adapter_signal(connection, adapter->dev_id, - "BondingCreated", - DBUS_TYPE_STRING, &paddr, - DBUS_TYPE_INVALID); + d = l->data; + adapter->pin_reqs = g_slist_remove(adapter->pin_reqs, l->data); + g_free(d); - if (hcid_dbus_use_experimental()) { - struct device *device; - gboolean paired = TRUE; + send_adapter_signal(connection, adapter->dev_id, "BondingCreated", + DBUS_TYPE_STRING, &paddr, DBUS_TYPE_INVALID); - device = adapter_get_device(connection, adapter, paddr); - if (device) { - device->temporary = FALSE; - dbus_connection_emit_property_changed(connection, - device->path, DEVICE_INTERFACE, - "Paired", DBUS_TYPE_BOOLEAN, &paired); - } - } + if (hcid_dbus_use_experimental()) { + struct device *device; + gboolean paired = TRUE; + + device = adapter_get_device(connection, adapter, paddr); + if (device) { + dbus_connection_emit_property_changed(connection, + device->path, DEVICE_INTERFACE, + "Paired", DBUS_TYPE_BOOLEAN, &paired); } } +proceed: + release_passkey_agents(adapter, peer); - if (!adapter->bonding || bacmp(&adapter->bonding->bdaddr, peer)) + bonding = adapter->bonding; + if (!bonding || bacmp(&bonding->bdaddr, peer)) return; /* skip: no bonding req pending */ - if (adapter->bonding->cancel) { + if (bonding->cancel) { /* reply authentication canceled */ - error_authentication_canceled(connection, adapter->bonding->rq); - } else { - DBusMessage *reply; - /* reply authentication success or an error */ - reply = new_authentication_return(adapter->bonding->rq, - status); + error_authentication_canceled(connection, bonding->msg); + goto cleanup; + } + + /* reply authentication success or an error */ + if (dbus_message_is_method_call(bonding->msg, ADAPTER_INTERFACE, + "CreateBonding")) { + reply = new_authentication_return(bonding->msg, status); send_message_and_unref(connection, reply); + } else if ((device = adapter_find_device(adapter, paddr))) { + if (status) { + reply = new_authentication_return(bonding->msg, status); + send_message_and_unref(connection, reply); + } else { + device->temporary = FALSE; + device_browse(device, bonding->conn, bonding->msg); + } } +cleanup: name_listener_remove(connection, - dbus_message_get_sender(adapter->bonding->rq), + dbus_message_get_sender(adapter->bonding->msg), (name_cb_t) create_bond_req_exit, adapter); if (adapter->bonding->io_id) @@ -1996,15 +2009,15 @@ void hcid_dbus_disconn_complete(bdaddr_t *local, uint8_t status, if (adapter->bonding->cancel) { /* reply authentication canceled */ error_authentication_canceled(connection, - adapter->bonding->rq); + adapter->bonding->msg); } else { - reply = new_authentication_return(adapter->bonding->rq, + reply = new_authentication_return(adapter->bonding->msg, HCI_AUTHENTICATION_FAILURE); send_message_and_unref(connection, reply); } name_listener_remove(connection, - dbus_message_get_sender(adapter->bonding->rq), + dbus_message_get_sender(adapter->bonding->msg), (name_cb_t) create_bond_req_exit, adapter); if (adapter->bonding->io_id) @@ -2042,8 +2055,11 @@ void hcid_dbus_disconn_complete(bdaddr_t *local, uint8_t status, device->path, DEVICE_INTERFACE, "Connected", DBUS_TYPE_BOOLEAN, &connected); - if (device->temporary) - device_remove(connection, device); + if (device->temporary) { + adapter->devices = g_slist_remove(adapter->devices, + device); + device_remove(device, connection); + } } } diff --git a/hcid/device.c b/hcid/device.c index b0532712..32567851 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -59,11 +59,18 @@ #include "dbus-common.h" #include "dbus-hci.h" #include "error.h" +#include "glib-helper.h" #define MAX_DEVICES 16 #define DEVICE_INTERFACE "org.bluez.Device" +struct browse_req { + DBusConnection *conn; + DBusMessage *msg; + struct device *device; +}; + struct hci_peer { struct timeval lastseen; struct timeval lastused; @@ -1035,13 +1042,7 @@ struct device *device_create(DBusConnection *conn, struct adapter *adapter, return device; } -void device_remove(DBusConnection *conn, struct device *device) -{ - device_destroy(device, conn); - device_free(device); -} - -void device_destroy(struct device *device, DBusConnection *conn) +void device_remove(struct device *device, DBusConnection *conn) { debug("Removing device %s", device->path); @@ -1052,3 +1053,95 @@ gint device_address_cmp(struct device *device, const gchar *address) { return strcasecmp(device->address, address); } + +static void browse_cb(gpointer user_data, sdp_list_t *recs, int err) +{ + sdp_list_t *seq, *next, *svcclass; + struct browse_req *req = user_data; + struct device *device = req->device; + struct adapter *adapter = device->adapter; + bdaddr_t src, dst; + char **uuids; + int i; + GSList *l; + DBusMessage *reply; + + if (err < 0) + return; + + for (seq = recs; seq; seq = next) { + sdp_record_t *rec = (sdp_record_t *) seq->data; + + if (!rec) + break; + + svcclass = NULL; + if (sdp_get_service_classes(rec, &svcclass) == 0) { + /* Extract the first element and skip the remainning */ + gchar *uuid_str = bt_uuid2string(svcclass->data); + if (uuid_str) { + if (!g_slist_find_custom(device->uuids, uuid_str, + (GCompareFunc) strcmp)) + device->uuids = g_slist_insert_sorted(device->uuids, + uuid_str, (GCompareFunc) strcmp); + else + g_free(uuid_str); + } + sdp_list_free(svcclass, free); + } + + next = seq->next; + } + + sdp_list_free(recs, (sdp_free_func_t) sdp_record_free); + + /* Store the device's profiles in the filesystem */ + str2ba(adapter->address, &src); + str2ba(device->address, &dst); + if (device->uuids) { + gchar *str = bt_list2string(device->uuids); + write_device_profiles(&src, &dst, str); + g_free(str); + } else + write_device_profiles(&src, &dst, ""); + + uuids = g_new0(char *, g_slist_length(device->uuids) + 1); + for (i = 0, l = device->uuids; l; l = l->next, i++) + uuids[i] = l->data; + + dbus_connection_emit_property_changed(req->conn, device->path, + DEVICE_INTERFACE, "UUIDs", + DBUS_TYPE_ARRAY, &uuids); + g_free(uuids); + + /* Reply create device request */ + reply = dbus_message_new_method_return(req->msg); + if (!reply) + return; + + dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &device->path, + DBUS_TYPE_INVALID); + + send_message_and_unref(req->conn, reply); + + dbus_message_unref(req->msg); + dbus_connection_unref(req->conn); + g_free(req); +} + +int device_browse(struct device *device, DBusConnection *conn, + DBusMessage *msg) +{ + struct adapter *adapter = device->adapter; + struct browse_req *req; + bdaddr_t src, dst; + + req = g_new0(struct browse_req, 1); + req->conn = dbus_connection_ref(conn); + req->msg = dbus_message_ref(msg); + req->device = device; + + str2ba(adapter->address, &src); + str2ba(device->address, &dst); + return bt_discover_services(&src, &dst, browse_cb, req, NULL); +} diff --git a/hcid/device.h b/hcid/device.h index 318b2470..273d23d5 100644 --- a/hcid/device.h +++ b/hcid/device.h @@ -33,8 +33,8 @@ struct device { }; struct device *device_create(DBusConnection *conn, struct adapter *adapter, - const gchar *address, GSList *uuids); - -void device_remove(DBusConnection *conn, struct device *device); -void device_destroy(struct device *device, DBusConnection *conn); + const gchar *address, GSList *uuids); +void device_remove(struct device *device, DBusConnection *conn); gint device_address_cmp(struct device *device, const gchar *address); +int device_browse(struct device *device, DBusConnection *conn, + DBusMessage *msg); -- cgit