summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLuiz Augusto von Dentz <luiz.dentz@openbossa.org>2009-01-10 17:00:12 -0300
committerJohan Hedberg <johan.hedberg@nokia.com>2009-01-11 19:17:08 +0200
commitc4338c0b7a46d6288e350b8c05fc02ee28b4bdbc (patch)
tree4f0002fd8c6fb30a75cf3a08de526ea092dbb476 /src
parent2aad1cf41acbc69481915d24cef33fa721d4e1fd (diff)
Handle active connection using device object.
Diffstat (limited to 'src')
-rw-r--r--src/adapter.c194
-rw-r--r--src/adapter.h19
-rw-r--r--src/dbus-hci.c37
-rw-r--r--src/device.c76
-rw-r--r--src/device.h9
5 files changed, 149 insertions, 186 deletions
diff --git a/src/adapter.c b/src/adapter.c
index 5df012e6..458d536f 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -107,7 +107,7 @@ struct btd_adapter {
DBusMessage *discovery_cancel; /* discovery cancel message request */
GSList *passkey_agents;
struct agent *agent; /* For the new API */
- GSList *active_conn;
+ GSList *connections; /* Connected devices */
GSList *devices; /* Devices structure pointers */
GSList *mode_sessions; /* Request Mode sessions */
GSList *disc_sessions; /* Discovery sessions */
@@ -176,25 +176,6 @@ static inline DBusMessage *unsupported_major_class(DBusMessage *msg)
"Unsupported Major Class");
}
-static int active_conn_find_by_bdaddr(const void *data, const void *user_data)
-{
- const struct active_conn_info *con = data;
- const bdaddr_t *bdaddr = user_data;
-
- return bacmp(&con->bdaddr, bdaddr);
-}
-
-static int active_conn_find_by_handle(const void *data, const void *user_data)
-{
- const struct active_conn_info *dev = data;
- const uint16_t *handle = user_data;
-
- if (dev->handle == *handle)
- return 0;
-
- return -1;
-}
-
static void send_out_of_range(const char *path, GSList *l)
{
while (l) {
@@ -900,6 +881,21 @@ struct btd_device *adapter_find_device(struct btd_adapter *adapter, const char *
return device;
}
+struct btd_device *adapter_find_connection(struct btd_adapter *adapter,
+ uint16_t handle)
+{
+ GSList *l;
+
+ for (l = adapter->connections; l; l = l->next) {
+ struct btd_device *device = l->data;
+
+ if (device_has_connection(device, handle))
+ return device;
+ }
+
+ return NULL;
+}
+
static void adapter_update_devices(struct btd_adapter *adapter)
{
char **devices;
@@ -1816,20 +1812,6 @@ static int adapter_setup(struct btd_adapter *adapter, int dd)
return 0;
}
-static int active_conn_append(GSList **list, bdaddr_t *bdaddr,
- uint16_t handle)
-{
- struct active_conn_info *dev;
-
- dev = g_new0(struct active_conn_info, 1);
-
- bacpy(&dev->bdaddr, bdaddr);
- dev->handle = handle;
-
- *list = g_slist_append(*list, dev);
- return 0;
-}
-
static void create_stored_device_from_profiles(char *key, char *value,
void *user_data)
{
@@ -1904,6 +1886,36 @@ static void load_drivers(struct btd_adapter *adapter)
}
}
+static void load_connections(struct btd_adapter *adapter, int dd)
+{
+ struct hci_conn_list_req *cl = NULL;
+ struct hci_conn_info *ci;
+ int i;
+
+ cl = g_malloc0(10 * sizeof(*ci) + sizeof(*cl));
+
+ cl->dev_id = adapter->dev_id;
+ cl->conn_num = 10;
+ ci = cl->conn_info;
+
+ if (ioctl(dd, HCIGETCONNLIST, cl) != 0) {
+ g_free(cl);
+ return;
+ }
+
+ for (i = 0; i < cl->conn_num; i++, ci++) {
+ struct btd_device *device;
+ char address[18];
+
+ ba2str(&ci->bdaddr, address);
+ device = adapter_get_device(connection, adapter, address);
+ if (device)
+ adapter_add_connection(adapter, device, ci->handle);
+ }
+
+ g_free(cl);
+}
+
static int get_discoverable_timeout(const char *src)
{
int timeout;
@@ -1927,7 +1939,6 @@ static int get_pairable_timeout(const char *src)
static int adapter_up(struct btd_adapter *adapter, int dd)
{
char mode[14], srcaddr[18];
- int i;
uint8_t scan_mode;
gboolean powered, dev_down = FALSE;
@@ -1980,39 +1991,23 @@ static int adapter_up(struct btd_adapter *adapter, int dd)
}
proceed:
- if (dev_down == FALSE)
+ if (dev_down == FALSE) {
hci_send_cmd(dd, OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE,
1, &scan_mode);
- /* retrieve the active connections: address the scenario where
- * the are active connections before the daemon've started */
- if (adapter->initialized == FALSE) {
- struct hci_conn_list_req *cl = NULL;
- struct hci_conn_info *ci;
-
- cl = g_malloc0(10 * sizeof(*ci) + sizeof(*cl));
-
- cl->dev_id = adapter->dev_id;
- cl->conn_num = 10;
- ci = cl->conn_info;
-
- if (ioctl(dd, HCIGETCONNLIST, cl) == 0) {
- for (i = 0; i < cl->conn_num; i++, ci++)
- active_conn_append(&adapter->active_conn,
- &ci->bdaddr, ci->handle);
- }
-
- g_free(cl);
- }
-
- if (dev_down == FALSE)
emit_property_changed(connection, adapter->path,
ADAPTER_INTERFACE, "Powered",
DBUS_TYPE_BOOLEAN, &powered);
+ }
if (adapter->initialized == FALSE) {
load_drivers(adapter);
load_devices(adapter);
+
+ /* retrieve the active connections: address the scenario where
+ * the are active connections before the daemon've started */
+ load_connections(adapter, dd);
+
adapter->initialized = TRUE;
}
@@ -2211,10 +2206,9 @@ int adapter_stop(struct btd_adapter *adapter)
adapter->oor_devices = NULL;
}
- if (adapter->active_conn) {
- g_slist_foreach(adapter->active_conn, (GFunc) g_free, NULL);
- g_slist_free(adapter->active_conn);
- adapter->active_conn = NULL;
+ if (adapter->connections) {
+ g_slist_free(adapter->connections);
+ adapter->connections = NULL;
}
if (adapter->scan_mode == (SCAN_PAGE | SCAN_INQUIRY)) {
@@ -2645,62 +2639,43 @@ struct agent *adapter_get_agent(struct btd_adapter *adapter)
return adapter->agent;
}
-void adapter_add_active_conn(struct btd_adapter *adapter, bdaddr_t *bdaddr,
- uint16_t handle)
+void adapter_add_connection(struct btd_adapter *adapter,
+ struct btd_device *device, uint16_t handle)
{
- struct active_conn_info *dev;
-
- if (!adapter)
+ if (g_slist_find(adapter->connections, device)) {
+ error("Unable to add connection %d", handle);
return;
+ }
- dev = g_new0(struct active_conn_info, 1);
-
- bacpy(&dev->bdaddr, bdaddr);
- dev->handle = handle;
-
- adapter->active_conn = g_slist_append(adapter->active_conn, dev);
-}
-
-void adapter_remove_active_conn(struct btd_adapter *adapter,
- struct active_conn_info *dev)
-{
- if (!adapter || !adapter->active_conn)
- return;
+ device_add_connection(device, connection, handle);
- adapter->active_conn = g_slist_remove(adapter->active_conn, dev);
- g_free(dev);
+ adapter->connections = g_slist_append(adapter->connections, device);
}
-struct active_conn_info *adapter_search_active_conn_by_bdaddr(struct btd_adapter *adapter,
- bdaddr_t *bda)
+void adapter_remove_connection(struct btd_adapter *adapter,
+ struct btd_device *device, uint16_t handle)
{
- GSList *l;
-
- if (!adapter || !adapter->active_conn)
- return NULL;
+ bdaddr_t bdaddr;
- l = g_slist_find_custom(adapter->active_conn, bda,
- active_conn_find_by_bdaddr);
- if (l)
- return l->data;
+ if (!g_slist_find(adapter->connections, device)) {
+ error("No matching connection for handle %u", handle);
+ return;
+ }
- return NULL;
-}
+ device_remove_connection(device, connection, handle);
-struct active_conn_info *adapter_search_active_conn_by_handle(struct btd_adapter *adapter,
- uint16_t handle)
-{
- GSList *l;
+ adapter->connections = g_slist_remove(adapter->connections, device);
- if (!adapter || !adapter->active_conn)
- return NULL;
+ /* clean pending HCI cmds */
+ device_get_address(device, &bdaddr);
+ hci_req_queue_remove(adapter->dev_id, &bdaddr);
- l = g_slist_find_custom(adapter->active_conn, &handle,
- active_conn_find_by_handle);
- if (l)
- return l->data;
+ if (device_is_temporary(device)) {
+ const char *path = device_get_path(device);
- return NULL;
+ debug("Removing temporary device %s", path);
+ adapter_remove_device(connection, adapter, device);
+ }
}
gboolean adapter_has_discov_sessions(struct btd_adapter *adapter)
@@ -2761,12 +2736,15 @@ static int btd_adapter_authorize(struct btd_adapter *adapter, const bdaddr_t *ds
gboolean trusted;
const gchar *dev_path;
+ ba2str(dst, address);
+ device = adapter_find_device(adapter, address);
+ if (!device)
+ return -EPERM;
+
/* Device connected? */
- if (!g_slist_find_custom(adapter->active_conn,
- dst, active_conn_find_by_bdaddr))
+ if (!g_slist_find(adapter->connections, device))
return -ENOTCONN;
- ba2str(dst, address);
trusted = read_trust(&adapter->bdaddr, address, GLOBAL_TRUST);
if (trusted) {
diff --git a/src/adapter.h b/src/adapter.h
index 2f9068f2..6c63b7e0 100644
--- a/src/adapter.h
+++ b/src/adapter.h
@@ -53,11 +53,6 @@ struct remote_dev_info {
name_status_t name_status;
};
-struct active_conn_info {
- bdaddr_t bdaddr;
- uint16_t handle;
-};
-
struct hci_dev {
int ignore;
@@ -89,6 +84,8 @@ struct btd_device *adapter_get_device(DBusConnection *conn,
struct btd_device *adapter_find_device(struct btd_adapter *adapter, const char *dest);
+struct btd_device *adapter_find_connection(struct btd_adapter *adapter, uint16_t handle);
+
void adapter_remove_device(DBusConnection *conn, struct btd_adapter *adapter,
struct btd_device *device);
struct btd_device *adapter_create_device(DBusConnection *conn,
@@ -116,14 +113,10 @@ void adapter_update_oor_devices(struct btd_adapter *adapter);
void adapter_remove_oor_device(struct btd_adapter *adapter, char *peer_addr);
void adapter_mode_changed(struct btd_adapter *adapter, uint8_t scan_mode);
struct agent *adapter_get_agent(struct btd_adapter *adapter);
-void adapter_add_active_conn(struct btd_adapter *adapter, bdaddr_t *bdaddr,
- uint16_t handle);
-void adapter_remove_active_conn(struct btd_adapter *adapter,
- struct active_conn_info *dev);
-struct active_conn_info *adapter_search_active_conn_by_bdaddr(struct btd_adapter *adapter,
- bdaddr_t *bda);
-struct active_conn_info *adapter_search_active_conn_by_handle(struct btd_adapter *adapter,
- uint16_t handle);
+void adapter_add_connection(struct btd_adapter *adapter,
+ struct btd_device *device, uint16_t handle);
+void adapter_remove_connection(struct btd_adapter *adapter,
+ struct btd_device *device, uint16_t handle);
gboolean adapter_has_discov_sessions(struct btd_adapter *adapter);
struct btd_adapter_driver {
diff --git a/src/dbus-hci.c b/src/dbus-hci.c
index 0e574aff..49154a61 100644
--- a/src/dbus-hci.c
+++ b/src/dbus-hci.c
@@ -936,7 +936,7 @@ void hcid_dbus_link_key_notify(bdaddr_t *local, bdaddr_t *peer)
return;
}
- if (!device_get_connected(device))
+ if (!device_is_connected(device))
device_set_secmode3_conn(device, TRUE);
else if (!device_is_bonding(device, NULL))
hcid_dbus_bonding_process_complete(local, peer, 0);
@@ -970,20 +970,15 @@ void hcid_dbus_conn_complete(bdaddr_t *local, uint8_t status, uint16_t handle,
return;
}
- device_set_connected(device, connection, TRUE);
-
- /* add in the active connetions list */
- adapter_add_active_conn(adapter, peer, handle);
+ /* add in the device connetions list */
+ adapter_add_connection(adapter, device, handle);
}
void hcid_dbus_disconn_complete(bdaddr_t *local, uint8_t status,
uint16_t handle, uint8_t reason)
{
- char peer_addr[18];
struct btd_adapter *adapter;
struct btd_device *device;
- struct active_conn_info *dev;
- uint16_t dev_id;
if (status) {
error("Disconnection failed: 0x%02x", status);
@@ -996,31 +991,13 @@ void hcid_dbus_disconn_complete(bdaddr_t *local, uint8_t status,
return;
}
- dev = adapter_search_active_conn_by_handle(adapter, handle);
- if (!dev) {
- error("No matching connection for handle %u", handle);
+ device = adapter_find_connection(adapter, handle);
+ if (!device) {
+ error("No matching connection found for handle %u", handle);
return;
}
- ba2str(&dev->bdaddr, peer_addr);
-
- dev_id = adapter_get_dev_id(adapter);
-
- /* clean pending HCI cmds */
- hci_req_queue_remove(dev_id, &dev->bdaddr);
-
- adapter_remove_active_conn(adapter, dev);
-
- device = adapter_find_device(adapter, peer_addr);
- if (!device)
- return;
-
- device_set_connected(device, connection, FALSE);
-
- if (device_is_temporary(device)) {
- debug("Removing temporary device %s", peer_addr);
- adapter_remove_device(connection, adapter, device);
- }
+ adapter_remove_connection(adapter, device, handle);
}
int set_service_classes(int dd, const uint8_t *cls, uint8_t value)
diff --git a/src/device.c b/src/device.c
index 7891d1e5..8317dcb9 100644
--- a/src/device.c
+++ b/src/device.c
@@ -102,7 +102,7 @@ struct btd_device {
uint8_t cap;
uint8_t auth;
- gboolean connected;
+ uint16_t handle; /* Connection handle */
/* Whether were creating a security mode 3 connection */
gboolean secmode3;
@@ -225,7 +225,6 @@ static DBusMessage *get_properties(DBusConnection *conn,
uint32_t class;
int i;
GSList *l;
- struct active_conn_info *dev;
ba2str(&device->bdaddr, dstaddr);
@@ -287,13 +286,9 @@ static DBusMessage *get_properties(DBusConnection *conn,
dict_append_entry(&dict, "Trusted", DBUS_TYPE_BOOLEAN, &boolean);
/* Connected */
- dev = adapter_search_active_conn_by_bdaddr(adapter, &device->bdaddr);
- if (dev)
- boolean = TRUE;
- else
- boolean = FALSE;
-
- dict_append_entry(&dict, "Connected", DBUS_TYPE_BOOLEAN, &boolean);
+ boolean = (device->handle != 0);
+ dict_append_entry(&dict, "Connected", DBUS_TYPE_BOOLEAN,
+ &boolean);
/* UUIDs */
uuids = g_new0(char *, g_slist_length(device->uuids) + 1);
@@ -493,25 +488,18 @@ static DBusMessage *cancel_discover(DBusConnection *conn,
static gboolean disconnect_timeout(gpointer user_data)
{
struct btd_device *device = user_data;
- struct active_conn_info *ci;
disconnect_cp cp;
int dd;
uint16_t dev_id = adapter_get_dev_id(device->adapter);
device->disconn_timer = 0;
- ci = adapter_search_active_conn_by_bdaddr(device->adapter,
- &device->bdaddr);
-
- if (!ci)
- return FALSE;
-
dd = hci_open_dev(dev_id);
if (dd < 0)
goto fail;
memset(&cp, 0, sizeof(cp));
- cp.handle = htobs(ci->handle);
+ cp.handle = htobs(device->handle);
cp.reason = HCI_OE_USER_ENDED_CONNECTION;
hci_send_cmd(dd, OGF_LINK_CTL, OCF_DISCONNECT,
@@ -527,12 +515,8 @@ static DBusMessage *disconnect(DBusConnection *conn,
DBusMessage *msg, void *user_data)
{
struct btd_device *device = user_data;
- struct active_conn_info *dev;
-
- dev = adapter_search_active_conn_by_bdaddr(device->adapter,
- &device->bdaddr);
- if (!dev)
+ if (!device->handle)
return g_dbus_create_error(msg,
ERROR_INTERFACE ".NotConnected",
"Device is not connected");
@@ -563,16 +547,14 @@ static GDBusSignalTable device_signals[] = {
{ }
};
-gboolean device_get_connected(struct btd_device *device)
+gboolean device_is_connected(struct btd_device *device)
{
- return device->connected;
+ return (device->handle != 0);
}
-void device_set_connected(struct btd_device *device, DBusConnection *conn,
+static void device_set_connected(struct btd_device *device, DBusConnection *conn,
gboolean connected)
{
- device->connected = connected;
-
emit_property_changed(conn, device->path, DEVICE_INTERFACE,
"Connected", DBUS_TYPE_BOOLEAN, &connected);
@@ -588,6 +570,39 @@ void device_set_connected(struct btd_device *device, DBusConnection *conn,
}
}
+void device_add_connection(struct btd_device *device, DBusConnection *conn,
+ uint16_t handle)
+{
+ if (device->handle) {
+ error("%s: Unable to add connection %u, %u already exist)",
+ device->path, handle, device->handle);
+ return;
+ }
+
+ device->handle = handle;
+
+ device_set_connected(device, conn, TRUE);
+}
+
+void device_remove_connection(struct btd_device *device, DBusConnection *conn,
+ uint16_t handle)
+{
+ if (device->handle != handle) {
+ error("%s: Unable to remove connection %u, handle mismatch (%u)",
+ device->path, handle, device->handle);
+ return;
+ }
+
+ device->handle = 0;
+
+ device_set_connected(device, conn, FALSE);
+}
+
+gboolean device_has_connection(struct btd_device *device, uint16_t handle)
+{
+ return (handle == device->handle);
+}
+
void device_set_secmode3_conn(struct btd_device *device, gboolean enable)
{
device->secmode3 = enable;
@@ -626,7 +641,6 @@ struct btd_device *device_create(DBusConnection *conn, struct btd_adapter *adapt
static void device_remove_bonding(struct btd_device *device, DBusConnection *conn)
{
- struct active_conn_info *ci;
char filename[PATH_MAX + 1];
char *str, srcaddr[18], dstaddr[18];
int dd, dev_id;
@@ -661,10 +675,8 @@ static void device_remove_bonding(struct btd_device *device, DBusConnection *con
hci_delete_stored_link_key(dd, &device->bdaddr, 0, HCI_REQ_TIMEOUT);
/* Send the HCI disconnect command */
- ci = adapter_search_active_conn_by_bdaddr(device->adapter,
- &device->bdaddr);
- if (ci) {
- int err = hci_disconnect(dd, htobs(ci->handle),
+ if (device->handle) {
+ int err = hci_disconnect(dd, htobs(device->handle),
HCI_OE_USER_ENDED_CONNECTION,
HCI_REQ_TIMEOUT);
if (err < 0)
diff --git a/src/device.h b/src/device.h
index c9137f7c..2b2735c0 100644
--- a/src/device.h
+++ b/src/device.h
@@ -55,9 +55,7 @@ void device_set_temporary(struct btd_device *device, gboolean temporary);
void device_set_cap(struct btd_device *device, uint8_t cap);
void device_set_auth(struct btd_device *device, uint8_t auth);
uint8_t device_get_auth(struct btd_device *device);
-gboolean device_get_connected(struct btd_device *device);
-void device_set_connected(struct btd_device *device, DBusConnection *conn,
- gboolean connected);
+gboolean device_is_connected(struct btd_device *device);
void device_set_secmode3_conn(struct btd_device *device, gboolean enable);
DBusMessage *device_create_bonding(struct btd_device *device,
DBusConnection *conn, DBusMessage *msg,
@@ -70,6 +68,11 @@ int device_request_authentication(struct btd_device *device, auth_type_t type,
uint32_t passkey, void *cb);
void device_cancel_authentication(struct btd_device *device);
gboolean device_is_authenticating(struct btd_device *device);
+void device_add_connection(struct btd_device *device, DBusConnection *conn,
+ uint16_t handle);
+void device_remove_connection(struct btd_device *device, DBusConnection *conn,
+ uint16_t handle);
+gboolean device_has_connection(struct btd_device *device, uint16_t handle);
#define BTD_UUIDS(args...) ((const char *[]) { args, NULL } )