summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--hcid/adapter.c45
-rw-r--r--hcid/adapter.h1
-rw-r--r--hcid/agent.c37
-rw-r--r--hcid/agent.h3
-rw-r--r--hcid/dbus-hci.c11
5 files changed, 54 insertions, 43 deletions
diff --git a/hcid/adapter.c b/hcid/adapter.c
index 06082b92..c6756d21 100644
--- a/hcid/adapter.c
+++ b/hcid/adapter.c
@@ -69,6 +69,12 @@
#define NUM_ELEMENTS(table) (sizeof(table)/sizeof(const char *))
+#define IO_CAPABILITY_DISPLAYONLY 0x00
+#define IO_CAPABILITY_DISPLAYYESNO 0x01
+#define IO_CAPABILITY_KEYBOARDONLY 0x02
+#define IO_CAPABILITY_NOINPUTOUTPUT 0x03
+#define IO_CAPABILITY_INVALID 0xFF
+
struct mode_req {
struct adapter *adapter;
DBusConnection *conn; /* Connection reference */
@@ -276,7 +282,7 @@ static struct bonding_request_info *bonding_request_new(DBusConnection *conn,
struct adapter *adapter,
const char *address,
const char *agent_path,
- const char *capability)
+ uint8_t capability)
{
struct bonding_request_info *bonding;
struct device *device;
@@ -289,8 +295,7 @@ static struct bonding_request_info *bonding_request_new(DBusConnection *conn,
if (agent_path)
device->agent = agent_create(adapter,
dbus_message_get_sender(msg),
- agent_path,
- capability, NULL,
+ agent_path, capability,
(agent_remove_cb) device_agent_removed,
device);
}
@@ -299,6 +304,7 @@ static struct bonding_request_info *bonding_request_new(DBusConnection *conn,
bonding->conn = dbus_connection_ref(conn);
bonding->msg = dbus_message_ref(msg);
+ bonding->adapter = adapter;
str2ba(address, &bonding->bdaddr);
@@ -2663,7 +2669,7 @@ static void create_bond_req_exit(void *user_data)
static DBusMessage *create_bonding(DBusConnection *conn, DBusMessage *msg,
const char *address, const char *agent_path,
- const char *capability, void *data)
+ uint8_t capability, void *data)
{
char filename[PATH_MAX + 1];
char *str;
@@ -2745,7 +2751,7 @@ static DBusHandlerResult adapter_create_bonding(DBusConnection *conn,
return error_invalid_arguments(conn, msg, NULL);
return send_message_and_unref(conn,
- create_bonding(conn, msg, address, NULL, NULL, data));
+ create_bonding(conn, msg, address, NULL, 0, data));
}
static DBusHandlerResult adapter_cancel_bonding(DBusConnection *conn,
@@ -3937,10 +3943,26 @@ static DBusMessage *create_device(DBusConnection *conn,
return NULL;
}
+static uint8_t parse_io_capability(const char *capability)
+{
+ if (g_str_equal(capability, ""))
+ return IO_CAPABILITY_DISPLAYYESNO;
+ if (g_str_equal(capability, "DisplayOnly"))
+ return IO_CAPABILITY_DISPLAYONLY;
+ if (g_str_equal(capability, "DisplayYesNo"))
+ return IO_CAPABILITY_DISPLAYYESNO;
+ if (g_str_equal(capability, "KeyboardOnly"))
+ return IO_CAPABILITY_KEYBOARDONLY;
+ if (g_str_equal(capability, "NoInputOutput"))
+ return IO_CAPABILITY_NOINPUTOUTPUT;
+ return IO_CAPABILITY_INVALID;
+}
+
static DBusMessage *create_paired_device(DBusConnection *conn,
DBusMessage *msg, void *data)
{
const gchar *address, *agent_path, *capability;
+ uint8_t cap;
if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &address,
DBUS_TYPE_OBJECT_PATH, &agent_path,
@@ -3951,7 +3973,11 @@ static DBusMessage *create_paired_device(DBusConnection *conn,
if (check_address(address) < 0)
return invalid_args(msg);
- return create_bonding(conn, msg, address, agent_path, capability,
+ cap = parse_io_capability(capability);
+ if (cap == IO_CAPABILITY_INVALID)
+ return invalid_args(msg);
+
+ return create_bonding(conn, msg, address, agent_path, cap,
data);
}
@@ -4029,6 +4055,7 @@ static DBusMessage *register_agent(DBusConnection *conn,
const char *path, *name, *capability;
struct agent *agent;
struct adapter *adapter = data;
+ uint8_t cap;
if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
DBUS_TYPE_STRING, &capability, DBUS_TYPE_INVALID))
@@ -4039,9 +4066,13 @@ static DBusMessage *register_agent(DBusConnection *conn,
ERROR_INTERFACE ".AlreadyExists",
"Agent already exists");
+ cap = parse_io_capability(capability);
+ if (cap == IO_CAPABILITY_INVALID)
+ return invalid_args(msg);
+
name = dbus_message_get_sender(msg);
- agent = agent_create(adapter, name, path, NULL, capability,
+ agent = agent_create(adapter, name, path, cap,
(agent_remove_cb) agent_removed, adapter);
if (!agent)
return g_dbus_create_error(msg,
diff --git a/hcid/adapter.h b/hcid/adapter.h
index 17eed7bd..1666e659 100644
--- a/hcid/adapter.h
+++ b/hcid/adapter.h
@@ -55,6 +55,7 @@ struct remote_dev_info {
struct bonding_request_info {
DBusConnection *conn;
DBusMessage *msg;
+ struct adapter *adapter;
bdaddr_t bdaddr;
GIOChannel *io;
guint io_id;
diff --git a/hcid/agent.c b/hcid/agent.c
index 0791c769..2335f09c 100644
--- a/hcid/agent.c
+++ b/hcid/agent.c
@@ -63,13 +63,11 @@ typedef enum {
struct agent {
struct adapter *adapter;
- char *addr;
char *name;
char *path;
- char *capability;
+ uint8_t capability;
struct agent_request *request;
int exited;
- guint timeout;
agent_remove_cb remove_cb;
void *remove_cb_data;
guint listener_id;
@@ -174,9 +172,6 @@ static void agent_free(struct agent *agent)
agent_request_free(agent->request);
}
- if (agent->timeout)
- g_source_remove(agent->timeout);
-
if (!agent->exited) {
g_dbus_remove_watch(connection, agent->listener_id);
agent_release(agent);
@@ -184,26 +179,12 @@ static void agent_free(struct agent *agent)
g_free(agent->name);
g_free(agent->path);
- g_free(agent->capability);
- g_free(agent->addr);
g_free(agent);
}
-static gboolean agent_timeout(struct agent *agent)
-{
- debug("Agent at %s, %s timed out", agent->name, agent->path);
-
- agent->timeout = 0;
-
- agent_free(agent);
-
- return FALSE;
-}
-
struct agent *agent_create(struct adapter *adapter, const char *name,
- const char *path, const char *address,
- const char *capability,
+ const char *path, uint8_t capability,
agent_remove_cb cb, void *remove_cb_data)
{
struct agent *agent;
@@ -216,16 +197,10 @@ struct agent *agent_create(struct adapter *adapter, const char *name,
agent->adapter = adapter;
agent->name = g_strdup(name);
agent->path = g_strdup(path);
- agent->capability = g_strdup(capability);
+ agent->capability = capability;
agent->remove_cb = cb;
agent->remove_cb_data = remove_cb_data;
- if (address) {
- agent->addr = g_strdup(address);
- agent->timeout = g_timeout_add(AGENT_TIMEOUT,
- (GSourceFunc) agent_timeout, agent);
- }
-
agent->listener_id = g_dbus_add_disconnect_watch(connection, name,
agent_exited, agent,
NULL);
@@ -341,9 +316,6 @@ done:
agent->request = NULL;
agent_request_free(req);
-
- if (agent->addr)
- agent_free(agent);
}
int agent_authorize(struct agent *agent,
@@ -461,9 +433,6 @@ done:
dbus_pending_call_cancel(req->call);
agent_request_free(req);
-
- if (agent->addr)
- agent_free(agent);
}
int agent_request_pincode(struct agent *agent, struct device *device,
diff --git a/hcid/agent.h b/hcid/agent.h
index ad648178..22f79aa4 100644
--- a/hcid/agent.h
+++ b/hcid/agent.h
@@ -33,8 +33,7 @@ typedef void (*agent_pincode_cb) (struct agent *agent, DBusError *err,
typedef void (*agent_remove_cb) (struct agent *agent, void *user_data);
struct agent *agent_create(struct adapter *adapter, const char *name,
- const char *path, const char *address,
- const char *capability,
+ const char *path, uint8_t capability,
agent_remove_cb cb, void *remove_cb_data);
int agent_destroy(struct agent *agent, gboolean exited);
diff --git a/hcid/dbus-hci.c b/hcid/dbus-hci.c
index 679170ff..1b7c9cfa 100644
--- a/hcid/dbus-hci.c
+++ b/hcid/dbus-hci.c
@@ -63,6 +63,9 @@ static DBusConnection *connection = NULL;
void bonding_request_free(struct bonding_request_info *bonding)
{
+ struct device *device;
+ char address[18];
+
if (!bonding)
return;
@@ -75,6 +78,14 @@ void bonding_request_free(struct bonding_request_info *bonding)
if (bonding->io)
g_io_channel_unref(bonding->io);
+ ba2str(&bonding->bdaddr, address);
+
+ device = adapter_get_device(connection, bonding->adapter, address);
+ if (device && device->agent) {
+ agent_destroy(device->agent, FALSE);
+ device->agent = NULL;
+ }
+
g_free(bonding);
}