Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 48264f06 authored by Johan Hedberg's avatar Johan Hedberg Committed by Gustavo Padovan
Browse files

Bluetooth: Add public/random LE address information to mgmt messages



It's necessary to know the distinction between public and random LE
addresses so the mgmt interface also needs to distinguish between them.

Signed-off-by: default avatarJohan Hedberg <johan.hedberg@intel.com>
Signed-off-by: default avatarGustavo F. Padovan <padovan@profusion.mobi>
parent 1eb54c8a
Loading
Loading
Loading
Loading
+8 −6
Original line number Diff line number Diff line
@@ -915,11 +915,13 @@ int mgmt_connectable(struct hci_dev *hdev, u8 connectable);
int mgmt_write_scan_failed(struct hci_dev *hdev, u8 scan, u8 status);
int mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key,
								u8 persistent);
int mgmt_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
int mgmt_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
int mgmt_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
								u8 addr_type);
int mgmt_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
								u8 addr_type);
int mgmt_disconnect_failed(struct hci_dev *hdev);
int mgmt_connect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type,
								u8 status);
int mgmt_connect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
						u8 addr_type, u8 status);
int mgmt_pin_code_request(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 secure);
int mgmt_pin_code_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
								u8 status);
@@ -935,8 +937,8 @@ int mgmt_auth_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 status);
int mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status);
int mgmt_read_local_oob_data_reply_complete(struct hci_dev *hdev, u8 *hash,
						u8 *randomizer, u8 status);
int mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type,
					u8 *dev_class, s8 rssi, u8 *eir);
int mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
				u8 addr_type, u8 *dev_class, s8 rssi, u8 *eir);
int mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *name);
int mgmt_inquiry_failed(struct hci_dev *hdev, u8 status);
int mgmt_discovering(struct hci_dev *hdev, u8 discovering);
+2 −2
Original line number Diff line number Diff line
@@ -129,8 +129,8 @@ struct mgmt_rp_disconnect {
} __packed;

#define MGMT_ADDR_BREDR			0x00
#define MGMT_ADDR_LE			0x01
#define MGMT_ADDR_BREDR_LE		0x02
#define MGMT_ADDR_LE_PUBLIC		0x01
#define MGMT_ADDR_LE_RANDOM		0x02
#define MGMT_ADDR_INVALID		0xff

struct mgmt_addr_info {
+12 −9
Original line number Diff line number Diff line
@@ -1437,7 +1437,7 @@ 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, &info->bdaddr, ACL_LINK,
		mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
						info->dev_class, 0, NULL);
	}

@@ -1472,7 +1472,8 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s
			conn->state = BT_CONFIG;
			hci_conn_hold(conn);
			conn->disc_timeout = HCI_DISCONN_TIMEOUT;
			mgmt_connected(hdev, &ev->bdaddr, conn->type);
			mgmt_connected(hdev, &ev->bdaddr, conn->type,
							conn->dst_type);
		} else
			conn->state = BT_CONNECTED;

@@ -1505,7 +1506,7 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s
		conn->state = BT_CLOSED;
		if (conn->type == ACL_LINK)
			mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
								ev->status);
						conn->dst_type, ev->status);
	}

	if (conn->type == ACL_LINK)
@@ -1620,7 +1621,8 @@ 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, &conn->dst, conn->type);
		mgmt_disconnected(hdev, &conn->dst, conn->type,
							conn->dst_type);

	hci_proto_disconn_cfm(conn, ev->reason);
	hci_conn_del(conn);
@@ -2444,7 +2446,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, &info->bdaddr, ACL_LINK,
			mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
						info->dev_class, info->rssi,
						NULL);
		}
@@ -2461,7 +2463,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, &info->bdaddr, ACL_LINK,
			mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
						info->dev_class, info->rssi,
						NULL);
		}
@@ -2604,7 +2606,7 @@ 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, &info->bdaddr, ACL_LINK,
		mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
				info->dev_class, info->rssi, info->data);
	}

@@ -2868,14 +2870,15 @@ static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff
	}

	if (ev->status) {
		mgmt_connect_failed(hdev, &ev->bdaddr, conn->type, ev->status);
		mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
						conn->dst_type, ev->status);
		hci_proto_connect_cfm(conn, ev->status);
		conn->state = BT_CLOSED;
		hci_conn_del(conn);
		goto unlock;
	}

	mgmt_connected(hdev, &ev->bdaddr, conn->type);
	mgmt_connected(hdev, &ev->bdaddr, conn->type, conn->dst_type);

	conn->sec_level = BT_SECURITY_LOW;
	conn->handle = __le16_to_cpu(ev->handle);
+22 −13
Original line number Diff line number Diff line
@@ -1063,11 +1063,18 @@ static int disconnect(struct sock *sk, u16 index, unsigned char *data, u16 len)
	return err;
}

static u8 link_to_mgmt(u8 link_type)
static u8 link_to_mgmt(u8 link_type, u8 addr_type)
{
	switch (link_type) {
	case LE_LINK:
		return MGMT_ADDR_LE;
		switch (addr_type) {
		case ADDR_LE_DEV_PUBLIC:
			return MGMT_ADDR_LE_PUBLIC;
		case ADDR_LE_DEV_RANDOM:
			return MGMT_ADDR_LE_RANDOM;
		default:
			return MGMT_ADDR_INVALID;
		}
	case ACL_LINK:
		return MGMT_ADDR_BREDR;
	default:
@@ -1110,7 +1117,7 @@ static int get_connections(struct sock *sk, u16 index)
	i = 0;
	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);
		rp->addr[i].type = link_to_mgmt(c->type, c->dst_type);
		if (rp->addr[i].type == MGMT_ADDR_INVALID)
			continue;
		i++;
@@ -2088,12 +2095,13 @@ int mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key,
	return mgmt_event(MGMT_EV_NEW_LINK_KEY, hdev, &ev, sizeof(ev), NULL);
}

int mgmt_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type)
int mgmt_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
								u8 addr_type)
{
	struct mgmt_addr_info ev;

	bacpy(&ev.bdaddr, bdaddr);
	ev.type = link_to_mgmt(link_type);
	ev.type = link_to_mgmt(link_type, addr_type);

	return mgmt_event(MGMT_EV_CONNECTED, hdev, &ev, sizeof(ev), NULL);
}
@@ -2114,7 +2122,8 @@ static void disconnect_rsp(struct pending_cmd *cmd, void *data)
	mgmt_pending_remove(cmd);
}

int mgmt_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
int mgmt_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
								u8 addr_type)
{
	struct mgmt_addr_info ev;
	struct sock *sk = NULL;
@@ -2123,7 +2132,7 @@ int mgmt_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
	mgmt_pending_foreach(MGMT_OP_DISCONNECT, hdev, disconnect_rsp, &sk);

	bacpy(&ev.bdaddr, bdaddr);
	ev.type = link_to_mgmt(type);
	ev.type = link_to_mgmt(link_type, addr_type);

	err = mgmt_event(MGMT_EV_DISCONNECTED, hdev, &ev, sizeof(ev), sk);

@@ -2149,13 +2158,13 @@ int mgmt_disconnect_failed(struct hci_dev *hdev)
	return err;
}

int mgmt_connect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type,
								u8 status)
int mgmt_connect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
						u8 addr_type, u8 status)
{
	struct mgmt_ev_connect_failed ev;

	bacpy(&ev.addr.bdaddr, bdaddr);
	ev.addr.type = link_to_mgmt(type);
	ev.addr.type = link_to_mgmt(link_type, addr_type);
	ev.status = status;

	return mgmt_event(MGMT_EV_CONNECT_FAILED, hdev, &ev, sizeof(ev), NULL);
@@ -2342,15 +2351,15 @@ int mgmt_read_local_oob_data_reply_complete(struct hci_dev *hdev, u8 *hash,
	return err;
}

int mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type,
					u8 *dev_class, s8 rssi, u8 *eir)
int mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
				u8 addr_type, u8 *dev_class, s8 rssi, u8 *eir)
{
	struct mgmt_ev_device_found ev;

	memset(&ev, 0, sizeof(ev));

	bacpy(&ev.addr.bdaddr, bdaddr);
	ev.addr.type = link_to_mgmt(type);
	ev.addr.type = link_to_mgmt(link_type, addr_type);
	ev.rssi = rssi;

	if (eir)