OSDN Git Service

mgmt: Implement set_pairable
authorJohan Hedberg <johan.hedberg@nokia.com>
Thu, 30 Dec 2010 13:03:57 +0000 (15:03 +0200)
committerJohan Hedberg <johan.hedberg@nokia.com>
Thu, 30 Dec 2010 13:06:16 +0000 (15:06 +0200)
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.

doc/mgmt-api.txt
lib/mgmt.h
plugins/hciops.c
plugins/mgmtops.c
src/adapter.c
src/adapter.h

index ba42950..e785a5e 100644 (file)
@@ -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)
index 3657f71..1c30949 100644 (file)
@@ -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
index 9861d60..ad83eb2 100644 (file)
@@ -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)
index 32d88d3..d4378d8 100644 (file)
@@ -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;
index e6a2081..87a8beb 100644 (file)
@@ -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;
 }
index 4599ea7..250c65e 100644 (file)
@@ -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,