diff options
author | Johan Hedberg <johan.hedberg@nokia.com> | 2010-12-30 15:03:57 +0200 |
---|---|---|
committer | Johan Hedberg <johan.hedberg@nokia.com> | 2010-12-30 15:06:16 +0200 |
commit | 6964bd2dd54d5cce7ce2588b0dcd0a3530e6fba9 (patch) | |
tree | 9010b09c62a4ff8a9793d646ea5beba76a621ba5 | |
parent | 3e1b64c81d0ef4ae92b601114aa06d85c735d646 (diff) | |
download | bluez-6964bd2dd54d5cce7ce2588b0dcd0a3530e6fba9.tar.gz |
mgmt: Implement set_pairable
This patch implements support for the set_pairable managment command.
Due to the async nature of it a new btd_adapter_pairable_changed
function is added to the core daemon.
-rw-r--r-- | doc/mgmt-api.txt | 16 | ||||
-rw-r--r-- | lib/mgmt.h | 4 | ||||
-rw-r--r-- | plugins/hciops.c | 9 | ||||
-rw-r--r-- | plugins/mgmtops.c | 75 | ||||
-rw-r--r-- | src/adapter.c | 28 | ||||
-rw-r--r-- | src/adapter.h | 2 |
6 files changed, 119 insertions, 15 deletions
diff --git a/doc/mgmt-api.txt b/doc/mgmt-api.txt index ba429501e..e785a5e17 100644 --- a/doc/mgmt-api.txt +++ b/doc/mgmt-api.txt @@ -107,6 +107,15 @@ Set Connectable Command Connectable (1 Octet) +Set Pairable Command +==================== + + Command Code: 0x0008 + Command Parameters: Controller_Index (2 Octets) + Pairable (1 Octet) + Return Paramters: Controller_Index (2 Octets) + Pairable (1 Octet) + Read Tracing Buffer Size Command ================================ @@ -216,3 +225,10 @@ Controller Connectable Event Event Code 0x0008 Event Parameters Controller_Index (2 Octets) Connectable (1 Octet) + +Controller Pairable Event +========================= + +Event Code 0x0009 +Event Parameters Controller_Index (2 Octets) + Pairable (1 Octet) diff --git a/lib/mgmt.h b/lib/mgmt.h index 3657f71d6..1c3094986 100644 --- a/lib/mgmt.h +++ b/lib/mgmt.h @@ -79,6 +79,8 @@ struct mgmt_mode { #define MGMT_OP_SET_CONNECTABLE 0x0007 +#define MGMT_OP_SET_PAIRABLE 0x0008 + #define MGMT_EV_CMD_COMPLETE 0x0001 struct mgmt_ev_cmd_complete { uint16_t opcode; @@ -112,3 +114,5 @@ struct mgmt_ev_index_removed { #define MGMT_EV_DISCOVERABLE 0x0007 #define MGMT_EV_CONNECTABLE 0x0008 + +#define MGMT_EV_PAIRABLE 0x0009 diff --git a/plugins/hciops.c b/plugins/hciops.c index 9861d6025..ad83eb24a 100644 --- a/plugins/hciops.c +++ b/plugins/hciops.c @@ -310,8 +310,15 @@ static int hciops_set_discoverable(int index, gboolean discoverable) static int hciops_set_pairable(int index, gboolean pairable) { + struct btd_adapter *adapter; + DBG("hci%d pairable %d", index, pairable); - return -ENOSYS; + + adapter = manager_find_adapter(&devs[index].bdaddr); + if (adapter) + btd_adapter_pairable_changed(adapter, pairable); + + return 0; } static int hciops_power_off(int index) diff --git a/plugins/mgmtops.c b/plugins/mgmtops.c index 32d88d33d..d4378d872 100644 --- a/plugins/mgmtops.c +++ b/plugins/mgmtops.c @@ -206,7 +206,7 @@ static int mgmt_set_discoverable(int index, gboolean discoverable) static int mgmt_set_pairable(int index, gboolean pairable) { DBG("index %d pairable %d", index, pairable); - return -ENOSYS; + return mgmt_set_mode(index, MGMT_OP_SET_PAIRABLE, pairable); } static int mgmt_update_powered(int index, uint8_t powered) @@ -261,7 +261,8 @@ static int mgmt_update_powered(int index, uint8_t powered) adapter_mode_changed(adapter, mode); } - mgmt_set_pairable(index, pairable); + if (info->pairable != pairable) + mgmt_set_pairable(index, pairable); return 0; } @@ -365,6 +366,38 @@ static void mgmt_connectable(int sk, void *buf, size_t len) adapter_mode_changed(adapter, mode); } +static void mgmt_pairable(int sk, void *buf, size_t len) +{ + struct mgmt_mode *ev = buf; + struct controller_info *info; + struct btd_adapter *adapter; + uint16_t index; + + if (len < sizeof(*ev)) { + error("Too small pairable event"); + return; + } + + index = btohs(bt_get_unaligned(&ev->index)); + + DBG("Controller %u pairable %u", index, ev->val); + + if (index > max_index) { + error("Unexpected index %u in pairable event", index); + return; + } + + info = &controllers[index]; + + info->pairable = ev->val ? TRUE : FALSE; + + adapter = manager_find_adapter(&info->bdaddr); + if (!adapter) + return; + + btd_adapter_pairable_changed(adapter, info->pairable); +} + static void read_index_list_complete(int sk, void *buf, size_t len) { struct mgmt_rp_read_index_list *rp = buf; @@ -549,6 +582,38 @@ static void set_connectable_complete(int sk, void *buf, size_t len) adapter_mode_changed(adapter, rp->val ? SCAN_PAGE : 0); } +static void set_pairable_complete(int sk, void *buf, size_t len) +{ + struct mgmt_mode *rp = buf; + struct controller_info *info; + struct btd_adapter *adapter; + uint16_t index; + + if (len < sizeof(*rp)) { + error("Too small set pairable complete event"); + return; + } + + index = btohs(bt_get_unaligned(&rp->index)); + + DBG("hci%d pairable %u", index, rp->val); + + if (index > max_index) { + error("Unexpected index %u in pairable complete", index); + return; + } + + info = &controllers[index]; + + info->pairable = rp->val ? TRUE : FALSE; + + adapter = manager_find_adapter(&info->bdaddr); + if (!adapter) + return; + + btd_adapter_pairable_changed(adapter, info->pairable); +} + static void mgmt_cmd_complete(int sk, void *buf, size_t len) { struct mgmt_ev_cmd_complete *ev = buf; @@ -582,6 +647,9 @@ static void mgmt_cmd_complete(int sk, void *buf, size_t len) case MGMT_OP_SET_CONNECTABLE: set_connectable_complete(sk, ev->data, len - sizeof(*ev)); break; + case MGMT_OP_SET_PAIRABLE: + set_pairable_complete(sk, ev->data, len - sizeof(*ev)); + break; default: error("Unknown command complete for opcode %u", opcode); break; @@ -685,6 +753,9 @@ static gboolean mgmt_event(GIOChannel *io, GIOCondition cond, gpointer user_data case MGMT_EV_CONNECTABLE: mgmt_connectable(sk, buf + MGMT_HDR_SIZE, len); break; + case MGMT_EV_PAIRABLE: + mgmt_pairable(sk, buf + MGMT_HDR_SIZE, len); + break; default: error("Unknown Management opcode %u", opcode); break; diff --git a/src/adapter.c b/src/adapter.c index e6a2081fa..87a8bebc2 100644 --- a/src/adapter.c +++ b/src/adapter.c @@ -546,6 +546,22 @@ static DBusMessage *set_powered(DBusConnection *conn, DBusMessage *msg, return NULL; } +void btd_adapter_pairable_changed(struct btd_adapter *adapter, + gboolean pairable) +{ + adapter->pairable = pairable; + + write_device_pairable(&adapter->bdaddr, pairable); + + emit_property_changed(connection, adapter->path, + ADAPTER_INTERFACE, "Pairable", + DBUS_TYPE_BOOLEAN, &pairable); + + if (pairable && adapter->pairable_timeout) + adapter_set_pairable_timeout(adapter, + adapter->pairable_timeout); +} + static DBusMessage *set_pairable(DBusConnection *conn, DBusMessage *msg, gboolean pairable, void *data) { @@ -566,20 +582,8 @@ static DBusMessage *set_pairable(DBusConnection *conn, DBusMessage *msg, return btd_error_failed(msg, strerror(-err)); store: - adapter->pairable = pairable; - adapter_ops->set_pairable(adapter->dev_id, pairable); - write_device_pairable(&adapter->bdaddr, pairable); - - emit_property_changed(connection, adapter->path, - ADAPTER_INTERFACE, "Pairable", - DBUS_TYPE_BOOLEAN, &pairable); - - if (pairable && adapter->pairable_timeout) - adapter_set_pairable_timeout(adapter, - adapter->pairable_timeout); - done: return msg ? dbus_message_new_method_return(msg) : NULL; } diff --git a/src/adapter.h b/src/adapter.h index 4599ea7d1..250c65e55 100644 --- a/src/adapter.h +++ b/src/adapter.h @@ -151,6 +151,8 @@ void adapter_service_insert(struct btd_adapter *adapter, void *rec); void adapter_service_remove(struct btd_adapter *adapter, void *rec); void btd_adapter_class_changed(struct btd_adapter *adapter, uint32_t new_class); +void btd_adapter_pairable_changed(struct btd_adapter *adapter, + gboolean pairable); struct agent *adapter_get_agent(struct btd_adapter *adapter); void adapter_add_connection(struct btd_adapter *adapter, |