Bluetooth: Add address type fields to mgmt messages that need them
authorJohan Hedberg <johan.hedberg@intel.com>
Mon, 7 Nov 2011 21:13:39 +0000 (23:13 +0200)
committerGustavo F. Padovan <padovan@profusion.mobi>
Tue, 8 Nov 2011 15:05:57 +0000 (13:05 -0200)
This patch adds address type info (typically BR/EDR vs LE) to management
messages that need this. This also ensures conformance to the latest
management API specification.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
include/net/bluetooth/hci_core.h
include/net/bluetooth/mgmt.h
net/bluetooth/hci_event.c
net/bluetooth/mgmt.c

index 4ebc882..e6071d0 100644 (file)
@@ -912,10 +912,10 @@ int mgmt_discoverable(u16 index, u8 discoverable);
 int mgmt_connectable(u16 index, u8 connectable);
 int mgmt_write_scan_failed(u16 index, u8 scan, u8 status);
 int mgmt_new_link_key(u16 index, struct link_key *key, u8 persistent);
-int mgmt_connected(u16 index, bdaddr_t *bdaddr, u8 link_type);
-int mgmt_disconnected(u16 index, bdaddr_t *bdaddr);
+int mgmt_connected(u16 index, bdaddr_t *bdaddr, u8 type);
+int mgmt_disconnected(u16 index, bdaddr_t *bdaddr, u8 type);
 int mgmt_disconnect_failed(u16 index);
-int mgmt_connect_failed(u16 index, bdaddr_t *bdaddr, u8 status);
+int mgmt_connect_failed(u16 index, bdaddr_t *bdaddr, u8 type, u8 status);
 int mgmt_pin_code_request(u16 index, bdaddr_t *bdaddr, u8 secure);
 int mgmt_pin_code_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status);
 int mgmt_pin_code_neg_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status);
@@ -928,8 +928,8 @@ int mgmt_auth_failed(u16 index, bdaddr_t *bdaddr, u8 status);
 int mgmt_set_local_name_complete(u16 index, u8 *name, u8 status);
 int mgmt_read_local_oob_data_reply_complete(u16 index, u8 *hash, u8 *randomizer,
                                                                u8 status);
-int mgmt_device_found(u16 index, bdaddr_t *bdaddr, u8 *dev_class, s8 rssi,
-                                                               u8 *eir);
+int mgmt_device_found(u16 index, bdaddr_t *bdaddr, u8 type, u8 *dev_class,
+                                                       s8 rssi, u8 *eir);
 int mgmt_remote_name(u16 index, bdaddr_t *bdaddr, u8 *name);
 int mgmt_inquiry_failed(u16 index, u8 status);
 int mgmt_discovering(u16 index, u8 discovering);
index fa33bc6..3e320c9 100644 (file)
@@ -128,10 +128,20 @@ struct mgmt_rp_disconnect {
        bdaddr_t bdaddr;
 } __packed;
 
+#define MGMT_ADDR_BREDR                        0x00
+#define MGMT_ADDR_LE                   0x01
+#define MGMT_ADDR_BREDR_LE             0x02
+#define MGMT_ADDR_INVALID              0xff
+
+struct mgmt_addr_info {
+       bdaddr_t bdaddr;
+       __u8 type;
+} __packed;
+
 #define MGMT_OP_GET_CONNECTIONS                0x0010
 struct mgmt_rp_get_connections {
        __le16 conn_count;
-       bdaddr_t conn[0];
+       struct mgmt_addr_info addr[0];
 } __packed;
 
 #define MGMT_OP_PIN_CODE_REPLY         0x0011
@@ -254,19 +264,12 @@ struct mgmt_ev_new_link_key {
 } __packed;
 
 #define MGMT_EV_CONNECTED              0x000B
-struct mgmt_ev_connected {
-       bdaddr_t bdaddr;
-       __u8 link_type;
-} __packed;
 
 #define MGMT_EV_DISCONNECTED           0x000C
-struct mgmt_ev_disconnected {
-       bdaddr_t bdaddr;
-} __packed;
 
 #define MGMT_EV_CONNECT_FAILED         0x000D
 struct mgmt_ev_connect_failed {
-       bdaddr_t bdaddr;
+       struct mgmt_addr_info addr;
        __u8 status;
 } __packed;
 
@@ -296,7 +299,7 @@ struct mgmt_ev_local_name_changed {
 
 #define MGMT_EV_DEVICE_FOUND           0x0012
 struct mgmt_ev_device_found {
-       bdaddr_t bdaddr;
+       struct mgmt_addr_info addr;
        __u8 dev_class[3];
        __s8 rssi;
        __u8 eir[HCI_MAX_EIR_LENGTH];
index 176ceca..2fced8c 100644 (file)
@@ -1404,8 +1404,8 @@ static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *
                data.rssi               = 0x00;
                data.ssp_mode           = 0x00;
                hci_inquiry_cache_update(hdev, &data);
-               mgmt_device_found(hdev->id, &info->bdaddr, info->dev_class, 0,
-                                                                       NULL);
+               mgmt_device_found(hdev->id, &info->bdaddr, ACL_LINK,
+                                               info->dev_class, 0, NULL);
        }
 
        hci_dev_unlock(hdev);
@@ -1471,7 +1471,8 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s
        } else {
                conn->state = BT_CLOSED;
                if (conn->type == ACL_LINK)
-                       mgmt_connect_failed(hdev->id, &ev->bdaddr, ev->status);
+                       mgmt_connect_failed(hdev->id, &ev->bdaddr, conn->type,
+                                                               ev->status);
        }
 
        if (conn->type == ACL_LINK)
@@ -1584,7 +1585,7 @@ static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff
        conn->state = BT_CLOSED;
 
        if (conn->type == ACL_LINK || conn->type == LE_LINK)
-               mgmt_disconnected(hdev->id, &conn->dst);
+               mgmt_disconnected(hdev->id, &conn->dst, conn->type);
 
        hci_proto_disconn_cfm(conn, ev->reason);
        hci_conn_del(conn);
@@ -2408,7 +2409,7 @@ static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct
                        data.rssi               = info->rssi;
                        data.ssp_mode           = 0x00;
                        hci_inquiry_cache_update(hdev, &data);
-                       mgmt_device_found(hdev->id, &info->bdaddr,
+                       mgmt_device_found(hdev->id, &info->bdaddr, ACL_LINK,
                                                info->dev_class, info->rssi,
                                                NULL);
                }
@@ -2425,7 +2426,7 @@ static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct
                        data.rssi               = info->rssi;
                        data.ssp_mode           = 0x00;
                        hci_inquiry_cache_update(hdev, &data);
-                       mgmt_device_found(hdev->id, &info->bdaddr,
+                       mgmt_device_found(hdev->id, &info->bdaddr, ACL_LINK,
                                                info->dev_class, info->rssi,
                                                NULL);
                }
@@ -2568,8 +2569,8 @@ static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct
                data.rssi               = info->rssi;
                data.ssp_mode           = 0x01;
                hci_inquiry_cache_update(hdev, &data);
-               mgmt_device_found(hdev->id, &info->bdaddr, info->dev_class,
-                                               info->rssi, info->data);
+               mgmt_device_found(hdev->id, &info->bdaddr, ACL_LINK,
+                               info->dev_class, info->rssi, info->data);
        }
 
        hci_dev_unlock(hdev);
@@ -2832,7 +2833,8 @@ static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff
        }
 
        if (ev->status) {
-               mgmt_connect_failed(hdev->id, &ev->bdaddr, ev->status);
+               mgmt_connect_failed(hdev->id, &ev->bdaddr, conn->type,
+                                                               ev->status);
                hci_proto_connect_cfm(conn, ev->status);
                conn->state = BT_CLOSED;
                hci_conn_del(conn);
index 1939053..4cb2f95 100644 (file)
@@ -1069,6 +1069,18 @@ failed:
        return err;
 }
 
+static u8 link_to_mgmt(u8 link_type)
+{
+       switch (link_type) {
+       case LE_LINK:
+               return MGMT_ADDR_LE;
+       case ACL_LINK:
+               return MGMT_ADDR_BREDR;
+       default:
+               return MGMT_ADDR_INVALID;
+       }
+}
+
 static int get_connections(struct sock *sk, u16 index)
 {
        struct mgmt_rp_get_connections *rp;
@@ -1092,7 +1104,7 @@ static int get_connections(struct sock *sk, u16 index)
                count++;
        }
 
-       rp_len = sizeof(*rp) + (count * sizeof(bdaddr_t));
+       rp_len = sizeof(*rp) + (count * sizeof(struct mgmt_addr_info));
        rp = kmalloc(rp_len, GFP_ATOMIC);
        if (!rp) {
                err = -ENOMEM;
@@ -1102,8 +1114,16 @@ static int get_connections(struct sock *sk, u16 index)
        put_unaligned_le16(count, &rp->conn_count);
 
        i = 0;
-       list_for_each_entry(c, &hdev->conn_hash.list, list)
-               bacpy(&rp->conn[i++], &c->dst);
+       list_for_each_entry(c, &hdev->conn_hash.list, list) {
+               bacpy(&rp->addr[i].bdaddr, &c->dst);
+               rp->addr[i].type = link_to_mgmt(c->type);
+               if (rp->addr[i].type == MGMT_ADDR_INVALID)
+                       continue;
+               i++;
+       }
+
+       /* Recalculate length in case of filtered SCO connections, etc */
+       rp_len = sizeof(*rp) + (i * sizeof(struct mgmt_addr_info));
 
        err = cmd_complete(sk, index, MGMT_OP_GET_CONNECTIONS, rp, rp_len);
 
@@ -2075,10 +2095,10 @@ int mgmt_new_link_key(u16 index, struct link_key *key, u8 persistent)
 
 int mgmt_connected(u16 index, bdaddr_t *bdaddr, u8 link_type)
 {
-       struct mgmt_ev_connected ev;
+       struct mgmt_addr_info ev;
 
        bacpy(&ev.bdaddr, bdaddr);
-       ev.link_type = link_type;
+       ev.type = link_to_mgmt(link_type);
 
        return mgmt_event(MGMT_EV_CONNECTED, index, &ev, sizeof(ev), NULL);
 }
@@ -2099,15 +2119,16 @@ static void disconnect_rsp(struct pending_cmd *cmd, void *data)
        mgmt_pending_remove(cmd);
 }
 
-int mgmt_disconnected(u16 index, bdaddr_t *bdaddr)
+int mgmt_disconnected(u16 index, bdaddr_t *bdaddr, u8 type)
 {
-       struct mgmt_ev_disconnected ev;
+       struct mgmt_addr_info ev;
        struct sock *sk = NULL;
        int err;
 
        mgmt_pending_foreach(MGMT_OP_DISCONNECT, index, disconnect_rsp, &sk);
 
        bacpy(&ev.bdaddr, bdaddr);
+       ev.type = link_to_mgmt(type);
 
        err = mgmt_event(MGMT_EV_DISCONNECTED, index, &ev, sizeof(ev), sk);
 
@@ -2133,11 +2154,12 @@ int mgmt_disconnect_failed(u16 index)
        return err;
 }
 
-int mgmt_connect_failed(u16 index, bdaddr_t *bdaddr, u8 status)
+int mgmt_connect_failed(u16 index, bdaddr_t *bdaddr, u8 type, u8 status)
 {
        struct mgmt_ev_connect_failed ev;
 
-       bacpy(&ev.bdaddr, bdaddr);
+       bacpy(&ev.addr.bdaddr, bdaddr);
+       ev.addr.type = link_to_mgmt(type);
        ev.status = status;
 
        return mgmt_event(MGMT_EV_CONNECT_FAILED, index, &ev, sizeof(ev), NULL);
@@ -2325,14 +2347,15 @@ int mgmt_read_local_oob_data_reply_complete(u16 index, u8 *hash, u8 *randomizer,
        return err;
 }
 
-int mgmt_device_found(u16 index, bdaddr_t *bdaddr, u8 *dev_class, s8 rssi,
-                                                               u8 *eir)
+int mgmt_device_found(u16 index, bdaddr_t *bdaddr, u8 type, u8 *dev_class,
+                                                       s8 rssi, u8 *eir)
 {
        struct mgmt_ev_device_found ev;
 
        memset(&ev, 0, sizeof(ev));
 
-       bacpy(&ev.bdaddr, bdaddr);
+       bacpy(&ev.addr.bdaddr, bdaddr);
+       ev.addr.type = link_to_mgmt(type);
        ev.rssi = rssi;
 
        if (eir)