Bluetooth: mgmt: Make use of mgmt_send_event_skb in MGMT_EV_DEVICE_FOUND

This makes use of mgmt_alloc_skb to build MGMT_EV_DEVICE_FOUND so the
data is copied directly to skb that is then sent using
mgmt_send_event_skb eliminating the necessity of intermediary buffers.
Signed-off-by: default avatarLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
parent 8aca46f9
...@@ -335,6 +335,12 @@ static int mgmt_event(u16 event, struct hci_dev *hdev, void *data, u16 len, ...@@ -335,6 +335,12 @@ static int mgmt_event(u16 event, struct hci_dev *hdev, void *data, u16 len,
HCI_SOCK_TRUSTED, skip_sk); HCI_SOCK_TRUSTED, skip_sk);
} }
static int mgmt_event_skb(struct sk_buff *skb, struct sock *skip_sk)
{
return mgmt_send_event_skb(HCI_CHANNEL_CONTROL, skb, HCI_SOCK_TRUSTED,
skip_sk);
}
static u8 le_addr_type(u8 mgmt_addr_type) static u8 le_addr_type(u8 mgmt_addr_type)
{ {
if (mgmt_addr_type == BDADDR_LE_PUBLIC) if (mgmt_addr_type == BDADDR_LE_PUBLIC)
...@@ -9550,9 +9556,8 @@ void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, ...@@ -9550,9 +9556,8 @@ void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
u8 addr_type, u8 *dev_class, s8 rssi, u32 flags, u8 addr_type, u8 *dev_class, s8 rssi, u32 flags,
u8 *eir, u16 eir_len, u8 *scan_rsp, u8 scan_rsp_len) u8 *eir, u16 eir_len, u8 *scan_rsp, u8 scan_rsp_len)
{ {
char buf[512]; struct sk_buff *skb;
struct mgmt_ev_device_found *ev = (void *)buf; struct mgmt_ev_device_found *ev;
size_t ev_size;
/* Don't send events for a non-kernel initiated discovery. With /* Don't send events for a non-kernel initiated discovery. With
* LE one exception is if we have pend_le_reports > 0 in which * LE one exception is if we have pend_le_reports > 0 in which
...@@ -9587,13 +9592,13 @@ void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, ...@@ -9587,13 +9592,13 @@ void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
} }
} }
/* Make sure that the buffer is big enough. The 5 extra bytes /* Allocate skb. The 5 extra bytes are for the potential CoD field */
* are for the potential CoD field. skb = mgmt_alloc_skb(hdev, MGMT_EV_DEVICE_FOUND,
*/ sizeof(*ev) + eir_len + scan_rsp_len + 5);
if (sizeof(*ev) + eir_len + scan_rsp_len + 5 > sizeof(buf)) if (!skb)
return; return;
memset(buf, 0, sizeof(buf)); ev = skb_put(skb, sizeof(*ev));
/* In case of device discovery with BR/EDR devices (pre 1.2), the /* In case of device discovery with BR/EDR devices (pre 1.2), the
* RSSI value was reported as 0 when not available. This behavior * RSSI value was reported as 0 when not available. This behavior
...@@ -9614,35 +9619,39 @@ void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, ...@@ -9614,35 +9619,39 @@ void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
if (eir_len > 0) if (eir_len > 0)
/* Copy EIR or advertising data into event */ /* Copy EIR or advertising data into event */
memcpy(ev->eir, eir, eir_len); skb_put_data(skb, eir, eir_len);
if (dev_class && !eir_get_data(eir, eir_len, EIR_CLASS_OF_DEV, NULL)) {
u8 eir_cod[5];
if (dev_class && !eir_get_data(ev->eir, eir_len, EIR_CLASS_OF_DEV, eir_len += eir_append_data(eir_cod, 0, EIR_CLASS_OF_DEV,
NULL)) dev_class, 3);
eir_len = eir_append_data(ev->eir, eir_len, EIR_CLASS_OF_DEV, skb_put_data(skb, eir_cod, sizeof(eir_cod));
dev_class, 3); }
if (scan_rsp_len > 0) if (scan_rsp_len > 0)
/* Append scan response data to event */ /* Append scan response data to event */
memcpy(ev->eir + eir_len, scan_rsp, scan_rsp_len); skb_put_data(skb, scan_rsp, scan_rsp_len);
ev->eir_len = cpu_to_le16(eir_len + scan_rsp_len); ev->eir_len = cpu_to_le16(eir_len + scan_rsp_len);
ev_size = sizeof(*ev) + eir_len + scan_rsp_len;
mgmt_event(MGMT_EV_DEVICE_FOUND, hdev, ev, ev_size, NULL); mgmt_event_skb(skb, NULL);
} }
void mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, void mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
u8 addr_type, s8 rssi, u8 *name, u8 name_len) u8 addr_type, s8 rssi, u8 *name, u8 name_len)
{ {
struct sk_buff *skb;
struct mgmt_ev_device_found *ev; struct mgmt_ev_device_found *ev;
char buf[sizeof(*ev) + HCI_MAX_NAME_LENGTH + 2];
u16 eir_len; u16 eir_len;
u32 flags; u32 flags;
ev = (struct mgmt_ev_device_found *) buf; if (name_len)
skb = mgmt_alloc_skb(hdev, MGMT_EV_DEVICE_FOUND, 2 + name_len);
memset(buf, 0, sizeof(buf)); else
skb = mgmt_alloc_skb(hdev, MGMT_EV_DEVICE_FOUND, 0);
ev = skb_put(skb, sizeof(*ev));
bacpy(&ev->addr.bdaddr, bdaddr); bacpy(&ev->addr.bdaddr, bdaddr);
ev->addr.type = link_to_bdaddr(link_type, addr_type); ev->addr.type = link_to_bdaddr(link_type, addr_type);
ev->rssi = rssi; ev->rssi = rssi;
...@@ -9651,6 +9660,7 @@ void mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, ...@@ -9651,6 +9660,7 @@ void mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
eir_len = eir_append_data(ev->eir, 0, EIR_NAME_COMPLETE, name, eir_len = eir_append_data(ev->eir, 0, EIR_NAME_COMPLETE, name,
name_len); name_len);
flags = 0; flags = 0;
skb_put(skb, eir_len);
} else { } else {
eir_len = 0; eir_len = 0;
flags = MGMT_DEV_FOUND_NAME_REQUEST_FAILED; flags = MGMT_DEV_FOUND_NAME_REQUEST_FAILED;
...@@ -9659,7 +9669,7 @@ void mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, ...@@ -9659,7 +9669,7 @@ void mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
ev->eir_len = cpu_to_le16(eir_len); ev->eir_len = cpu_to_le16(eir_len);
ev->flags = cpu_to_le32(flags); ev->flags = cpu_to_le32(flags);
mgmt_event(MGMT_EV_DEVICE_FOUND, hdev, ev, sizeof(*ev) + eir_len, NULL); mgmt_event_skb(skb, NULL);
} }
void mgmt_discovering(struct hci_dev *hdev, u8 discovering) void mgmt_discovering(struct hci_dev *hdev, u8 discovering)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment