From f3d3444a4d7f76e79841c59c78105a45295cc4b0 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Sat, 5 Oct 2013 12:01:04 +0200 Subject: Bluetooth: Rename HCI_LE_PERIPHERAL to HCI_ADVERTISING This flag is used to indicate whether we want to have advertising enabled or not, so give it a more suitable name. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- include/net/bluetooth/hci.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/net') diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index b90eec5e9c06..e8bba05686d1 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -118,7 +118,7 @@ enum { HCI_SSP_ENABLED, HCI_HS_ENABLED, HCI_LE_ENABLED, - HCI_LE_PERIPHERAL, + HCI_ADVERTISING, HCI_CONNECTABLE, HCI_DISCOVERABLE, HCI_LINK_SECURITY, -- cgit v1.2.3 From d2f5a196d7b401b79e2321b24cc0ac8636ffbc17 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Sat, 5 Oct 2013 12:01:05 +0200 Subject: Bluetooth: Add public mgmt function to send New Settings event A function is needed so that the HCI event processing can ask the mgmt code to emit a new settings event. This is necessary e.g. when the event processing does updates to mgmt related states without any dependency of actual mgmt commands. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- include/net/bluetooth/hci_core.h | 1 + net/bluetooth/mgmt.c | 5 +++++ 2 files changed, 6 insertions(+) (limited to 'include/net') diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index e09c30577b3a..079c5c55c829 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -1123,6 +1123,7 @@ void hci_sock_dev_event(struct hci_dev *hdev, int event); int mgmt_control(struct sock *sk, struct msghdr *msg, size_t len); int mgmt_index_added(struct hci_dev *hdev); int mgmt_index_removed(struct hci_dev *hdev); +int mgmt_new_settings(struct hci_dev *hdev); int mgmt_set_powered_failed(struct hci_dev *hdev, int err); int mgmt_powered(struct hci_dev *hdev, u8 powered); int mgmt_discoverable(struct hci_dev *hdev, u8 discoverable); diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 7e43d376e2e6..6e808d1d78f3 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -890,6 +890,11 @@ static int new_settings(struct hci_dev *hdev, struct sock *skip) return mgmt_event(MGMT_EV_NEW_SETTINGS, hdev, &ev, sizeof(ev), skip); } +int mgmt_new_settings(struct hci_dev *hdev) +{ + return new_settings(hdev, NULL); +} + struct cmd_lookup { struct sock *sk; struct hci_dev *hdev; -- cgit v1.2.3 From f822c411b26ce0353c8b97877e53a12e4f895ca1 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 5 Oct 2013 11:47:41 -0700 Subject: Bluetooth: Remove useless external function to count controllers The list of controllers can be counted ahead of time and inline inside the AMP discover handling. There is no need to export such a function at all. In addition just count the AMP controller and only allocated space for a single mandatory BR/EDR controller. No need to allocate more space than needed. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- include/net/bluetooth/hci_core.h | 13 ------------- net/bluetooth/a2mp.c | 10 +++++++++- 2 files changed, 9 insertions(+), 14 deletions(-) (limited to 'include/net') diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 079c5c55c829..db650baf8177 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -704,19 +704,6 @@ static inline void hci_set_drvdata(struct hci_dev *hdev, void *data) dev_set_drvdata(&hdev->dev, data); } -/* hci_dev_list shall be locked */ -static inline uint8_t __hci_num_ctrl(void) -{ - uint8_t count = 0; - struct list_head *p; - - list_for_each(p, &hci_dev_list) { - count++; - } - - return count; -} - struct hci_dev *hci_dev_get(int index); struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src); diff --git a/net/bluetooth/a2mp.c b/net/bluetooth/a2mp.c index eb0f05e09cd5..a6e45e177b3d 100644 --- a/net/bluetooth/a2mp.c +++ b/net/bluetooth/a2mp.c @@ -129,6 +129,7 @@ static int a2mp_discover_req(struct amp_mgr *mgr, struct sk_buff *skb, struct a2mp_discov_rsp *rsp; u16 ext_feat; u8 num_ctrl; + struct hci_dev *hdev; if (len < sizeof(*req)) return -EINVAL; @@ -152,7 +153,14 @@ static int a2mp_discover_req(struct amp_mgr *mgr, struct sk_buff *skb, read_lock(&hci_dev_list_lock); - num_ctrl = __hci_num_ctrl(); + /* at minimum the BR/EDR needs to be listed */ + num_ctrl = 1; + + list_for_each_entry(hdev, &hci_dev_list, list) { + if (hdev->dev_type == HCI_AMP) + num_ctrl++; + } + len = num_ctrl * sizeof(struct a2mp_cl) + sizeof(*rsp); rsp = kmalloc(len, GFP_ATOMIC); if (!rsp) { -- cgit v1.2.3 From 7c13823d5b6b7cf06adeb5d56d2435fc0d97383f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 5 Oct 2013 11:47:42 -0700 Subject: Bluetooth: Add constants for AMP controller type Add the constants for BR/EDR and 802.11 AMP controller types. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- include/net/bluetooth/hci.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include/net') diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index e8bba05686d1..8e3076ebb8ad 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -66,6 +66,10 @@ /* First BR/EDR Controller shall have ID = 0 */ #define HCI_BREDR_ID 0 +/* AMP controller types */ +#define AMP_TYPE_BREDR 0x00 +#define AMP_TYPE_80211 0x01 + /* AMP controller status */ #define AMP_CTRL_POWERED_DOWN 0x00 #define AMP_CTRL_BLUETOOTH_ONLY 0x01 -- cgit v1.2.3 From ece6912648da3fcf257a40774e3aad531c3e5fac Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 5 Oct 2013 11:47:43 -0700 Subject: Bluetooth: Separate AMP controller type from HCI device type There are two defined HCI device types. One is for BR/EDR controllers and the other is for AMP controllers. The HCI device type is not the same as the AMP controller type. It just happens that currently the defined types match, but that is not guaranteed. Split the usage of AMP controller type into its own domain so that it is possible to separate between BR/EDR controllers, 802.11 AMP controllers and any other AMP technology that might be defined in the future. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- include/net/bluetooth/hci_core.h | 2 +- net/bluetooth/a2mp.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'include/net') diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index db650baf8177..4cb355b023a4 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -803,7 +803,7 @@ static inline bool hci_amp_capable(void) read_lock(&hci_dev_list_lock); list_for_each_entry(hdev, &hci_dev_list, list) - if (hdev->amp_type == HCI_AMP && + if (hdev->amp_type != AMP_TYPE_BREDR && test_bit(HCI_UP, &hdev->flags)) ret = true; read_unlock(&hci_dev_list_lock); diff --git a/net/bluetooth/a2mp.c b/net/bluetooth/a2mp.c index a6e45e177b3d..b2ef3d392a0e 100644 --- a/net/bluetooth/a2mp.c +++ b/net/bluetooth/a2mp.c @@ -78,7 +78,7 @@ u8 __next_ident(struct amp_mgr *mgr) static inline void __a2mp_cl_bredr(struct a2mp_cl *cl) { cl->id = 0; - cl->type = 0; + cl->type = AMP_TYPE_BREDR; cl->status = 1; } @@ -352,7 +352,7 @@ static int a2mp_getampassoc_req(struct amp_mgr *mgr, struct sk_buff *skb, tmp = amp_mgr_lookup_by_state(READ_LOC_AMP_ASSOC); hdev = hci_dev_get(req->id); - if (!hdev || hdev->amp_type == HCI_BREDR || tmp) { + if (!hdev || hdev->amp_type == AMP_TYPE_BREDR || tmp) { struct a2mp_amp_assoc_rsp rsp; rsp.id = req->id; @@ -459,7 +459,7 @@ static int a2mp_createphyslink_req(struct amp_mgr *mgr, struct sk_buff *skb, rsp.remote_id = req->local_id; hdev = hci_dev_get(req->remote_id); - if (!hdev || hdev->amp_type != HCI_AMP) { + if (!hdev || hdev->amp_type == AMP_TYPE_BREDR) { rsp.status = A2MP_STATUS_INVALID_CTRL_ID; goto send_rsp; } @@ -879,7 +879,7 @@ void a2mp_send_getinfo_rsp(struct hci_dev *hdev) rsp.id = hdev->id; rsp.status = A2MP_STATUS_INVALID_CTRL_ID; - if (hdev->amp_type != HCI_BREDR) { + if (hdev->amp_type != AMP_TYPE_BREDR) { rsp.status = 0; rsp.total_bw = cpu_to_le32(hdev->amp_total_bw); rsp.max_bw = cpu_to_le32(hdev->amp_max_bw); -- cgit v1.2.3 From 6ed971ca4f6bd96e26b3166cb5a94f7f8158fe77 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 5 Oct 2013 11:47:44 -0700 Subject: Bluetooth: Use explicit AMP controller id value for BR/EDR The special AMP controller id 0 is reserved for the BR/EDR controller that has the main link. It is a fixed value and so use a constant for this throughout the code to make it more visible when the handling is for the BR/EDR channel or when it is for the AMP channel. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- include/net/bluetooth/hci.h | 2 +- net/bluetooth/a2mp.c | 4 ++-- net/bluetooth/l2cap_core.c | 28 ++++++++++++++-------------- 3 files changed, 17 insertions(+), 17 deletions(-) (limited to 'include/net') diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index 8e3076ebb8ad..393eabc0d21f 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -64,7 +64,7 @@ #define HCI_AMP 0x01 /* First BR/EDR Controller shall have ID = 0 */ -#define HCI_BREDR_ID 0 +#define AMP_ID_BREDR 0x00 /* AMP controller types */ #define AMP_TYPE_BREDR 0x00 diff --git a/net/bluetooth/a2mp.c b/net/bluetooth/a2mp.c index b2ef3d392a0e..6d62d3140cf8 100644 --- a/net/bluetooth/a2mp.c +++ b/net/bluetooth/a2mp.c @@ -77,7 +77,7 @@ u8 __next_ident(struct amp_mgr *mgr) static inline void __a2mp_cl_bredr(struct a2mp_cl *cl) { - cl->id = 0; + cl->id = AMP_ID_BREDR; cl->type = AMP_TYPE_BREDR; cl->status = 1; } @@ -216,7 +216,7 @@ static int a2mp_discover_rsp(struct amp_mgr *mgr, struct sk_buff *skb, BT_DBG("Remote AMP id %d type %d status %d", cl->id, cl->type, cl->status); - if (cl->id != HCI_BREDR_ID && cl->type == HCI_AMP) { + if (cl->id != AMP_ID_BREDR && cl->type == HCI_AMP) { struct a2mp_info_req req; found = true; diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 02dba4e6df96..b0208e20390c 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -3046,8 +3046,8 @@ int l2cap_ertm_init(struct l2cap_chan *chan) skb_queue_head_init(&chan->tx_q); - chan->local_amp_id = 0; - chan->move_id = 0; + chan->local_amp_id = AMP_ID_BREDR; + chan->move_id = AMP_ID_BREDR; chan->move_state = L2CAP_MOVE_STABLE; chan->move_role = L2CAP_MOVE_ROLE_NONE; @@ -3100,7 +3100,7 @@ static inline bool __l2cap_efs_supported(struct l2cap_conn *conn) static void __l2cap_set_ertm_timeouts(struct l2cap_chan *chan, struct l2cap_conf_rfc *rfc) { - if (chan->local_amp_id && chan->hs_hcon) { + if (chan->local_amp_id != AMP_ID_BREDR && chan->hs_hcon) { u64 ertm_to = chan->hs_hcon->hdev->amp_be_flush_to; /* Class 1 devices have must have ERTM timeouts @@ -3791,12 +3791,12 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn, * The connection will succeed after the * physical link is up. */ - if (amp_id) { - __l2cap_state_change(chan, BT_CONNECT2); - result = L2CAP_CR_PEND; - } else { + if (amp_id == AMP_ID_BREDR) { __l2cap_state_change(chan, BT_CONFIG); result = L2CAP_CR_SUCCESS; + } else { + __l2cap_state_change(chan, BT_CONNECT2); + result = L2CAP_CR_PEND; } status = L2CAP_CS_NO_INFO; } @@ -4423,7 +4423,7 @@ static int l2cap_create_channel_req(struct l2cap_conn *conn, BT_DBG("psm 0x%2.2x, scid 0x%4.4x, amp_id %d", psm, scid, req->amp_id); /* For controller id 0 make BR/EDR connection */ - if (req->amp_id == HCI_BREDR_ID) { + if (req->amp_id == AMP_ID_BREDR) { l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP, req->amp_id); return 0; @@ -4658,7 +4658,7 @@ void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan, if (chan->state != BT_CONNECTED) { /* Ignore logical link if channel is on BR/EDR */ - if (chan->local_amp_id) + if (chan->local_amp_id != AMP_ID_BREDR) l2cap_logical_finish_create(chan, hchan); } else { l2cap_logical_finish_move(chan, hchan); @@ -4669,7 +4669,7 @@ void l2cap_move_start(struct l2cap_chan *chan) { BT_DBG("chan %p", chan); - if (chan->local_amp_id == HCI_BREDR_ID) { + if (chan->local_amp_id == AMP_ID_BREDR) { if (chan->chan_policy != BT_CHANNEL_POLICY_AMP_PREFERRED) return; chan->move_role = L2CAP_MOVE_ROLE_INITIATOR; @@ -4868,7 +4868,7 @@ static inline int l2cap_move_channel_req(struct l2cap_conn *conn, goto send_move_response; } - if (req->dest_amp_id) { + if (req->dest_amp_id != AMP_ID_BREDR) { struct hci_dev *hdev; hdev = hci_dev_get(req->dest_amp_id); if (!hdev || hdev->dev_type != HCI_AMP || @@ -4898,7 +4898,7 @@ static inline int l2cap_move_channel_req(struct l2cap_conn *conn, chan->move_id = req->dest_amp_id; icid = chan->dcid; - if (!req->dest_amp_id) { + if (req->dest_amp_id == AMP_ID_BREDR) { /* Moving to BR/EDR */ if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) { chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY; @@ -5090,7 +5090,7 @@ static int l2cap_move_channel_confirm(struct l2cap_conn *conn, if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM) { if (result == L2CAP_MC_CONFIRMED) { chan->local_amp_id = chan->move_id; - if (!chan->local_amp_id) + if (chan->local_amp_id == AMP_ID_BREDR) __release_logical_link(chan); } else { chan->move_id = chan->local_amp_id; @@ -5130,7 +5130,7 @@ static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn, if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM_RSP) { chan->local_amp_id = chan->move_id; - if (!chan->local_amp_id && chan->hs_hchan) + if (chan->local_amp_id == AMP_ID_BREDR && chan->hs_hchan) __release_logical_link(chan); l2cap_move_done(chan); -- cgit v1.2.3 From 536619e86d9398a20063f7c3d15deb9dcc234097 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 5 Oct 2013 11:47:45 -0700 Subject: Bluetooth: Rename AMP status constants and use them The AMP controller status constants need to be actually used to avoid crypted hardcoded numbers. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- include/net/bluetooth/hci.h | 14 +++++++------- net/bluetooth/a2mp.c | 2 +- net/bluetooth/hci_core.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) (limited to 'include/net') diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index 393eabc0d21f..9f8d1c1f0414 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -71,13 +71,13 @@ #define AMP_TYPE_80211 0x01 /* AMP controller status */ -#define AMP_CTRL_POWERED_DOWN 0x00 -#define AMP_CTRL_BLUETOOTH_ONLY 0x01 -#define AMP_CTRL_NO_CAPACITY 0x02 -#define AMP_CTRL_LOW_CAPACITY 0x03 -#define AMP_CTRL_MEDIUM_CAPACITY 0x04 -#define AMP_CTRL_HIGH_CAPACITY 0x05 -#define AMP_CTRL_FULL_CAPACITY 0x06 +#define AMP_STATUS_POWERED_DOWN 0x00 +#define AMP_STATUS_BLUETOOTH_ONLY 0x01 +#define AMP_STATUS_NO_CAPACITY 0x02 +#define AMP_STATUS_LOW_CAPACITY 0x03 +#define AMP_STATUS_MEDIUM_CAPACITY 0x04 +#define AMP_STATUS_HIGH_CAPACITY 0x05 +#define AMP_STATUS_FULL_CAPACITY 0x06 /* HCI device quirks */ enum { diff --git a/net/bluetooth/a2mp.c b/net/bluetooth/a2mp.c index 6d62d3140cf8..6dfef731825f 100644 --- a/net/bluetooth/a2mp.c +++ b/net/bluetooth/a2mp.c @@ -79,7 +79,7 @@ static inline void __a2mp_cl_bredr(struct a2mp_cl *cl) { cl->id = AMP_ID_BREDR; cl->type = AMP_TYPE_BREDR; - cl->status = 1; + cl->status = AMP_STATUS_BLUETOOTH_ONLY; } /* hci_dev_list shall be locked */ diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index aa63ebb114d4..0d5fe0843f5e 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -1381,7 +1381,7 @@ static int hci_dev_do_close(struct hci_dev *hdev) } /* Controller radio is available but is currently powered down */ - hdev->amp_status = 0; + hdev->amp_status = AMP_STATUS_POWERED_DOWN; memset(hdev->eir, 0, sizeof(hdev->eir)); memset(hdev->dev_class, 0, sizeof(hdev->dev_class)); -- cgit v1.2.3 From 80d58d0b5b18b68addad61e228ced167f8b80dd3 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 5 Oct 2013 11:47:48 -0700 Subject: Bluetooth: Move hci_amp_capable() function into L2CAP core The hci_amp_capable() function has only a single user inside the L2CAP core. Instead of exporting the function, place it next to its user. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- include/net/bluetooth/hci_core.h | 16 ---------------- net/bluetooth/l2cap_core.c | 16 ++++++++++++++++ 2 files changed, 16 insertions(+), 16 deletions(-) (limited to 'include/net') diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 4cb355b023a4..82c397451261 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -795,22 +795,6 @@ void hci_conn_del_sysfs(struct hci_conn *conn); #define lmp_host_le_capable(dev) (!!((dev)->features[1][0] & LMP_HOST_LE)) #define lmp_host_le_br_capable(dev) (!!((dev)->features[1][0] & LMP_HOST_LE_BREDR)) -/* returns true if at least one AMP active */ -static inline bool hci_amp_capable(void) -{ - struct hci_dev *hdev; - bool ret = false; - - read_lock(&hci_dev_list_lock); - list_for_each_entry(hdev, &hci_dev_list, list) - if (hdev->amp_type != AMP_TYPE_BREDR && - test_bit(HCI_UP, &hdev->flags)) - ret = true; - read_unlock(&hci_dev_list_lock); - - return ret; -} - /* ----- HCI protocols ----- */ #define HCI_PROTO_DEFER 0x01 diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index b0208e20390c..2efdb17d87a3 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -1012,6 +1012,22 @@ static inline int __l2cap_no_conn_pending(struct l2cap_chan *chan) return !test_bit(CONF_CONNECT_PEND, &chan->conf_state); } +/* returns true if at least one AMP active */ +static inline bool hci_amp_capable(void) +{ + struct hci_dev *hdev; + bool ret = false; + + read_lock(&hci_dev_list_lock); + list_for_each_entry(hdev, &hci_dev_list, list) + if (hdev->amp_type != AMP_TYPE_BREDR && + test_bit(HCI_UP, &hdev->flags)) + ret = true; + read_unlock(&hci_dev_list_lock); + + return ret; +} + static bool __amp_capable(struct l2cap_chan *chan) { struct l2cap_conn *conn = chan->conn; -- cgit v1.2.3 From 1e191893f38e89796d948af0516b7e29594dab99 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 6 Oct 2013 02:34:38 -0700 Subject: Bluetooth: Add HCI structure for LE advertising parameters command Add the basic HCI structure for building the LE advertising parameters command. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- include/net/bluetooth/hci.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'include/net') diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index 9f8d1c1f0414..9b0e3f9aa1c3 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -1046,6 +1046,18 @@ struct hci_rp_le_read_local_features { #define HCI_OP_LE_SET_RANDOM_ADDR 0x2005 +#define HCI_OP_LE_SET_ADV_PARAM 0x2006 +struct hci_cp_le_set_adv_param { + __le16 min_interval; + __le16 max_interval; + __u8 type; + __u8 own_address_type; + __u8 direct_addr_type; + bdaddr_t direct_addr; + __u8 channel_map; + __u8 filter_policy; +} __packed; + #define HCI_OP_LE_READ_ADV_TX_POWER 0x2007 struct hci_rp_le_read_adv_tx_power { __u8 status; -- cgit v1.2.3 From c2f5ebd2148860537762c8d0d687efed73c2c2d0 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 6 Oct 2013 03:03:46 -0700 Subject: Bluetooth: Add constants for LE advertising types Add constants for ADV_IND, ADV_DIRECT_IND, ADV_SCAN_IND and ADV_NONCONN_IND advertising types. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- include/net/bluetooth/hci.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include/net') diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index 9b0e3f9aa1c3..3616ea794eb1 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -1046,6 +1046,11 @@ struct hci_rp_le_read_local_features { #define HCI_OP_LE_SET_RANDOM_ADDR 0x2005 +#define LE_ADV_IND 0x00 +#define LE_ADV_DIRECT_IND 0x01 +#define LE_ADV_SCAN_IND 0x02 +#define LE_ADV_NONCONN_IND 0x03 + #define HCI_OP_LE_SET_ADV_PARAM 0x2006 struct hci_cp_le_set_adv_param { __le16 min_interval; -- cgit v1.2.3 From 5976e60811723220678ebdb2ea06fbb52fe900bd Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 6 Oct 2013 04:08:14 -0700 Subject: Bluetooth: Use helper function for re-enabling advertising When the all LE connections have been disconneted, then it is up to the host to re-enable advertising at that point. To ensure that the correct advertising parameters are used, force the usage of the common helper to enable advertising. The change just moves the manual enabling of advertising from the event handler into the management core so that the helper can be actually shared. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- include/net/bluetooth/hci_core.h | 1 + net/bluetooth/hci_event.c | 36 +----------------------------------- net/bluetooth/mgmt.c | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 35 insertions(+), 35 deletions(-) (limited to 'include/net') diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 82c397451261..869f6ad602d1 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -1151,6 +1151,7 @@ int mgmt_device_blocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type); int mgmt_device_unblocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type); bool mgmt_valid_hdev(struct hci_dev *hdev); int mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, u8 persistent); +void mgmt_reenable_advertising(struct hci_dev *hdev); /* HCI info for socket */ #define hci_pi(sk) ((struct hci_pinfo *) sk) diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 6eaef6ed9522..224210ce82fc 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -1796,40 +1796,6 @@ static u8 hci_to_mgmt_reason(u8 err) } } -static void adv_enable_complete(struct hci_dev *hdev, u8 status) -{ - BT_DBG("%s status %u", hdev->name, status); - - /* Clear the advertising mgmt setting if we failed to re-enable it */ - if (status) { - clear_bit(HCI_ADVERTISING, &hdev->dev_flags); - mgmt_new_settings(hdev); - } -} - -static void reenable_advertising(struct hci_dev *hdev) -{ - struct hci_request req; - u8 enable = 0x01; - - if (hdev->conn_hash.le_num) - return; - - if (!test_bit(HCI_ADVERTISING, &hdev->dev_flags)) - return; - - hci_req_init(&req, hdev); - hci_req_add(&req, HCI_OP_LE_SET_ADV_ENABLE, sizeof(enable), &enable); - - /* If this fails we have no option but to let user space know - * that we've disabled advertising. - */ - if (hci_req_run(&req, adv_enable_complete) < 0) { - clear_bit(HCI_ADVERTISING, &hdev->dev_flags); - mgmt_new_settings(hdev); - } -} - static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_disconn_complete *ev = (void *) skb->data; @@ -1878,7 +1844,7 @@ static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) * is timed out due to Directed Advertising." */ if (type == LE_LINK) - reenable_advertising(hdev); + mgmt_reenable_advertising(hdev); } unlock: diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index b78a0eefe03e..381faf600195 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -4660,3 +4660,36 @@ int mgmt_device_unblocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) return mgmt_event(MGMT_EV_DEVICE_UNBLOCKED, hdev, &ev, sizeof(ev), cmd ? cmd->sk : NULL); } + +static void adv_enable_complete(struct hci_dev *hdev, u8 status) +{ + BT_DBG("%s status %u", hdev->name, status); + + /* Clear the advertising mgmt setting if we failed to re-enable it */ + if (status) { + clear_bit(HCI_ADVERTISING, &hdev->dev_flags); + mgmt_new_settings(hdev); + } +} + +void mgmt_reenable_advertising(struct hci_dev *hdev) +{ + struct hci_request req; + + if (hdev->conn_hash.le_num) + return; + + if (!test_bit(HCI_ADVERTISING, &hdev->dev_flags)) + return; + + hci_req_init(&req, hdev); + enable_advertising(&req); + + /* If this fails we have no option but to let user space know + * that we've disabled advertising. + */ + if (hci_req_run(&req, adv_enable_complete) < 0) { + clear_bit(HCI_ADVERTISING, &hdev->dev_flags); + mgmt_new_settings(hdev); + } +} -- cgit v1.2.3 From a6d811ed28f7c49e869b4076a00969c4028cda0d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 6 Oct 2013 04:11:12 -0700 Subject: Bluetooth: Remove no longer needed mgmt_new_settings() function The mgmt_new_settings() function was only needed to handle the error case when re-enabling advertising failed. Since that is now handled internally inside the management core, this function is not needed anymore. So just remove it. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- include/net/bluetooth/hci_core.h | 1 - net/bluetooth/mgmt.c | 9 ++------- 2 files changed, 2 insertions(+), 8 deletions(-) (limited to 'include/net') diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 869f6ad602d1..30e0fbb92b0a 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -1094,7 +1094,6 @@ void hci_sock_dev_event(struct hci_dev *hdev, int event); int mgmt_control(struct sock *sk, struct msghdr *msg, size_t len); int mgmt_index_added(struct hci_dev *hdev); int mgmt_index_removed(struct hci_dev *hdev); -int mgmt_new_settings(struct hci_dev *hdev); int mgmt_set_powered_failed(struct hci_dev *hdev, int err); int mgmt_powered(struct hci_dev *hdev, u8 powered); int mgmt_discoverable(struct hci_dev *hdev, u8 discoverable); diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 381faf600195..dd48e2a88c50 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -890,11 +890,6 @@ static int new_settings(struct hci_dev *hdev, struct sock *skip) return mgmt_event(MGMT_EV_NEW_SETTINGS, hdev, &ev, sizeof(ev), skip); } -int mgmt_new_settings(struct hci_dev *hdev) -{ - return new_settings(hdev, NULL); -} - struct cmd_lookup { struct sock *sk; struct hci_dev *hdev; @@ -4668,7 +4663,7 @@ static void adv_enable_complete(struct hci_dev *hdev, u8 status) /* Clear the advertising mgmt setting if we failed to re-enable it */ if (status) { clear_bit(HCI_ADVERTISING, &hdev->dev_flags); - mgmt_new_settings(hdev); + new_settings(hdev, NULL); } } @@ -4690,6 +4685,6 @@ void mgmt_reenable_advertising(struct hci_dev *hdev) */ if (hci_req_run(&req, adv_enable_complete) < 0) { clear_bit(HCI_ADVERTISING, &hdev->dev_flags); - mgmt_new_settings(hdev); + new_settings(hdev, NULL); } } -- cgit v1.2.3 From 1514b8928e5d8273920b26276cd9617b6dbc7760 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 6 Oct 2013 08:25:01 -0700 Subject: Bluetooth: Remove mgmt_valid_hdev() helper function The helper function mgmt_valid_hdev() is more obfuscating the code then it makes it easier to read. So intead of this helper, use the direct check for BR/EDR device type. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- include/net/bluetooth/hci_core.h | 1 - net/bluetooth/hci_core.c | 4 ++-- net/bluetooth/mgmt.c | 24 ++++++++---------------- 3 files changed, 10 insertions(+), 19 deletions(-) (limited to 'include/net') diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 30e0fbb92b0a..d80d4311ccb0 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -1148,7 +1148,6 @@ int mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, int mgmt_discovering(struct hci_dev *hdev, u8 discovering); int mgmt_device_blocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type); int mgmt_device_unblocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type); -bool mgmt_valid_hdev(struct hci_dev *hdev); int mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, u8 persistent); void mgmt_reenable_advertising(struct hci_dev *hdev); diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index bf3c5b0c22b9..d9626aad7ade 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -1254,7 +1254,7 @@ static int hci_dev_do_open(struct hci_dev *hdev) hci_notify(hdev, HCI_DEV_UP); if (!test_bit(HCI_SETUP, &hdev->dev_flags) && !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags) && - mgmt_valid_hdev(hdev)) { + hdev->dev_type == HCI_BREDR) { hci_dev_lock(hdev); mgmt_powered(hdev, 1); hci_dev_unlock(hdev); @@ -1394,7 +1394,7 @@ static int hci_dev_do_close(struct hci_dev *hdev) hdev->dev_flags &= ~HCI_PERSISTENT_MASK; if (!test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags) && - mgmt_valid_hdev(hdev)) { + hdev->dev_type == HCI_BREDR) { hci_dev_lock(hdev); mgmt_powered(hdev, 0); hci_dev_unlock(hdev); diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index dd48e2a88c50..9702079833fc 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -182,11 +182,6 @@ static u8 mgmt_status_table[] = { MGMT_STATUS_CONNECT_FAILED, /* MAC Connection Failed */ }; -bool mgmt_valid_hdev(struct hci_dev *hdev) -{ - return hdev->dev_type == HCI_BREDR; -} - static u8 mgmt_status(u8 hci_status) { if (hci_status < ARRAY_SIZE(mgmt_status_table)) @@ -322,10 +317,8 @@ static int read_index_list(struct sock *sk, struct hci_dev *hdev, void *data, count = 0; list_for_each_entry(d, &hci_dev_list, list) { - if (!mgmt_valid_hdev(d)) - continue; - - count++; + if (d->dev_type == HCI_BREDR) + count++; } rp_len = sizeof(*rp) + (2 * count); @@ -343,11 +336,10 @@ static int read_index_list(struct sock *sk, struct hci_dev *hdev, void *data, if (test_bit(HCI_USER_CHANNEL, &d->dev_flags)) continue; - if (!mgmt_valid_hdev(d)) - continue; - - rp->index[count++] = cpu_to_le16(d->id); - BT_DBG("Added hci%u", d->id); + if (d->dev_type == HCI_BREDR) { + rp->index[count++] = cpu_to_le16(d->id); + BT_DBG("Added hci%u", d->id); + } } rp->num_controllers = cpu_to_le16(count); @@ -3790,7 +3782,7 @@ done: int mgmt_index_added(struct hci_dev *hdev) { - if (!mgmt_valid_hdev(hdev)) + if (hdev->dev_type != HCI_BREDR) return -ENOTSUPP; return mgmt_event(MGMT_EV_INDEX_ADDED, hdev, NULL, 0, NULL); @@ -3800,7 +3792,7 @@ int mgmt_index_removed(struct hci_dev *hdev) { u8 status = MGMT_STATUS_INVALID_INDEX; - if (!mgmt_valid_hdev(hdev)) + if (hdev->dev_type != HCI_BREDR) return -ENOTSUPP; mgmt_pending_foreach(0, hdev, cmd_status_rsp, &status); -- cgit v1.2.3 From bf6b56db0acbe844c96fe36ab65eb7a53c6d8654 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 6 Oct 2013 23:55:45 -0700 Subject: Bluetooth: Make mgmt_index_added() and mgmt_index_removed() return void The return value from mgmt_index_added() and mgmt_index_removed() functions is never used. So do not pretend that returning an error would actually be handled and just make both functions return void. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- include/net/bluetooth/hci_core.h | 4 ++-- net/bluetooth/mgmt.c | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'include/net') diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index d80d4311ccb0..1e6f584d5149 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -1092,8 +1092,8 @@ void hci_sock_dev_event(struct hci_dev *hdev, int event); #define DISCOV_BREDR_INQUIRY_LEN 0x08 int mgmt_control(struct sock *sk, struct msghdr *msg, size_t len); -int mgmt_index_added(struct hci_dev *hdev); -int mgmt_index_removed(struct hci_dev *hdev); +void mgmt_index_added(struct hci_dev *hdev); +void mgmt_index_removed(struct hci_dev *hdev); int mgmt_set_powered_failed(struct hci_dev *hdev, int err); int mgmt_powered(struct hci_dev *hdev, u8 powered); int mgmt_discoverable(struct hci_dev *hdev, u8 discoverable); diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 3f628fd71b4e..811c41192ec7 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -3782,24 +3782,24 @@ done: return err; } -int mgmt_index_added(struct hci_dev *hdev) +void mgmt_index_added(struct hci_dev *hdev) { if (hdev->dev_type != HCI_BREDR) - return -ENOTSUPP; + return; - return mgmt_event(MGMT_EV_INDEX_ADDED, hdev, NULL, 0, NULL); + mgmt_event(MGMT_EV_INDEX_ADDED, hdev, NULL, 0, NULL); } -int mgmt_index_removed(struct hci_dev *hdev) +void mgmt_index_removed(struct hci_dev *hdev) { u8 status = MGMT_STATUS_INVALID_INDEX; if (hdev->dev_type != HCI_BREDR) - return -ENOTSUPP; + return; mgmt_pending_foreach(0, hdev, cmd_status_rsp, &status); - return mgmt_event(MGMT_EV_INDEX_REMOVED, hdev, NULL, 0, NULL); + mgmt_event(MGMT_EV_INDEX_REMOVED, hdev, NULL, 0, NULL); } static void set_bredr_scan(struct hci_request *req) -- cgit v1.2.3 From 3eec705e42d19b3d3e367fcb88693c24175bdbc6 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 6 Oct 2013 23:55:46 -0700 Subject: Bluetooth: Make mgmt_set_powered_failed() return void The return value of mgmt_set_powered_failed() function is never used and so make the function just return void. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- include/net/bluetooth/hci_core.h | 2 +- net/bluetooth/mgmt.c | 8 +++----- 2 files changed, 4 insertions(+), 6 deletions(-) (limited to 'include/net') diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 1e6f584d5149..62e2fc1bc7cc 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -1094,7 +1094,7 @@ void hci_sock_dev_event(struct hci_dev *hdev, int event); int mgmt_control(struct sock *sk, struct msghdr *msg, size_t len); void mgmt_index_added(struct hci_dev *hdev); void mgmt_index_removed(struct hci_dev *hdev); -int mgmt_set_powered_failed(struct hci_dev *hdev, int err); +void mgmt_set_powered_failed(struct hci_dev *hdev, int err); int mgmt_powered(struct hci_dev *hdev, u8 powered); int mgmt_discoverable(struct hci_dev *hdev, u8 discoverable); int mgmt_connectable(struct hci_dev *hdev, u8 connectable); diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 811c41192ec7..5da7464e57a5 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -3934,25 +3934,23 @@ new_settings: return err; } -int mgmt_set_powered_failed(struct hci_dev *hdev, int err) +void mgmt_set_powered_failed(struct hci_dev *hdev, int err) { struct pending_cmd *cmd; u8 status; cmd = mgmt_pending_find(MGMT_OP_SET_POWERED, hdev); if (!cmd) - return -ENOENT; + return; if (err == -ERFKILL) status = MGMT_STATUS_RFKILLED; else status = MGMT_STATUS_FAILED; - err = cmd_status(cmd->sk, hdev->id, MGMT_OP_SET_POWERED, status); + cmd_status(cmd->sk, hdev->id, MGMT_OP_SET_POWERED, status); mgmt_pending_remove(cmd); - - return err; } int mgmt_discoverable(struct hci_dev *hdev, u8 discoverable) -- cgit v1.2.3 From 7892924c7d5d74be8ad52316000a78fe96379044 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 6 Oct 2013 23:55:47 -0700 Subject: Bluetooth: Make mgmt_disconnect_failed() return void The return value of mgmt_disconnect_failed() function is not used so change it to just return void. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- include/net/bluetooth/hci_core.h | 4 ++-- net/bluetooth/mgmt.c | 13 +++++-------- 2 files changed, 7 insertions(+), 10 deletions(-) (limited to 'include/net') diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 62e2fc1bc7cc..429969fdb9f3 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -1106,8 +1106,8 @@ int mgmt_device_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, u8 *dev_class); int mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, u8 addr_type, u8 reason); -int mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, - u8 link_type, u8 addr_type, u8 status); +void mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, + u8 link_type, u8 addr_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); diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 5da7464e57a5..a35f28e9172e 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -4143,29 +4143,26 @@ int mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr, return err; } -int mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, - u8 link_type, u8 addr_type, u8 status) +void mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, + u8 link_type, u8 addr_type, u8 status) { struct mgmt_rp_disconnect rp; struct pending_cmd *cmd; - int err; mgmt_pending_foreach(MGMT_OP_UNPAIR_DEVICE, hdev, unpair_device_rsp, hdev); cmd = mgmt_pending_find(MGMT_OP_DISCONNECT, hdev); if (!cmd) - return -ENOENT; + return; bacpy(&rp.addr.bdaddr, bdaddr); rp.addr.type = link_to_bdaddr(link_type, addr_type); - err = cmd_complete(cmd->sk, cmd->index, MGMT_OP_DISCONNECT, - mgmt_status(status), &rp, sizeof(rp)); + cmd_complete(cmd->sk, cmd->index, MGMT_OP_DISCONNECT, + mgmt_status(status), &rp, sizeof(rp)); mgmt_pending_remove(cmd); - - return err; } int mgmt_connect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, -- cgit v1.2.3 From 445608d078bf7f7fe975792a940ffac83f495fa9 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 6 Oct 2013 23:55:48 -0700 Subject: Bluetooth: Make mgmt_connect_failed() return void The return value of mgmt_connect_failed() function is not used so change it to just return void. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- include/net/bluetooth/hci_core.h | 4 ++-- net/bluetooth/mgmt.c | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'include/net') diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 429969fdb9f3..d982458a96e3 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -1108,8 +1108,8 @@ int mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, u8 addr_type, u8 reason); void mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, u8 addr_type, u8 status); -int mgmt_connect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, - u8 addr_type, u8 status); +void 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); diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index a35f28e9172e..bd32c430cdfe 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -4165,8 +4165,8 @@ void mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, mgmt_pending_remove(cmd); } -int mgmt_connect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, - u8 addr_type, u8 status) +void mgmt_connect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, + u8 addr_type, u8 status) { struct mgmt_ev_connect_failed ev; @@ -4174,7 +4174,7 @@ int mgmt_connect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, ev.addr.type = link_to_bdaddr(link_type, addr_type); ev.status = mgmt_status(status); - return mgmt_event(MGMT_EV_CONNECT_FAILED, hdev, &ev, sizeof(ev), NULL); + mgmt_event(MGMT_EV_CONNECT_FAILED, hdev, &ev, sizeof(ev), NULL); } int mgmt_pin_code_request(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 secure) -- cgit v1.2.3 From ecd90ae7f600270d68b471f87c66d5b41ce5a974 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 6 Oct 2013 23:55:49 -0700 Subject: Bluetooth: Make mgmt_device_connected() return void The return value of mgmt_device_connected() function is not used and so just change it to return void. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- include/net/bluetooth/hci_core.h | 6 +++--- net/bluetooth/mgmt.c | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'include/net') diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index d982458a96e3..48569442ec17 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -1101,9 +1101,9 @@ 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, bool persistent); -int mgmt_device_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, - u8 addr_type, u32 flags, u8 *name, u8 name_len, - u8 *dev_class); +void mgmt_device_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, + u8 addr_type, u32 flags, u8 *name, u8 name_len, + u8 *dev_class); int mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, u8 addr_type, u8 reason); void mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index bd32c430cdfe..9029e67b3341 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -4056,9 +4056,9 @@ int mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, u8 persistent) NULL); } -int mgmt_device_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, - u8 addr_type, u32 flags, u8 *name, u8 name_len, - u8 *dev_class) +void mgmt_device_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, + u8 addr_type, u32 flags, u8 *name, u8 name_len, + u8 *dev_class) { char buf[512]; struct mgmt_ev_device_connected *ev = (void *) buf; @@ -4079,8 +4079,8 @@ int mgmt_device_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, ev->eir_len = cpu_to_le16(eir_len); - return mgmt_event(MGMT_EV_DEVICE_CONNECTED, hdev, buf, - sizeof(*ev) + eir_len, NULL); + mgmt_event(MGMT_EV_DEVICE_CONNECTED, hdev, buf, + sizeof(*ev) + eir_len, NULL); } static void disconnect_rsp(struct pending_cmd *cmd, void *data) -- cgit v1.2.3 From 9b80ec5e8e66ada404ad65ce61a1de70fee0fbbd Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 6 Oct 2013 23:55:50 -0700 Subject: Bluetooth: Make mgmt_device_disconnected() return void The return value of mgmt_device_disconnected() function is not used and so just change it to return void. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- include/net/bluetooth/hci_core.h | 4 ++-- net/bluetooth/mgmt.c | 10 +++------- 2 files changed, 5 insertions(+), 9 deletions(-) (limited to 'include/net') diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 48569442ec17..2b0bc31ec785 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -1104,8 +1104,8 @@ int mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key, void mgmt_device_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, u8 addr_type, u32 flags, u8 *name, u8 name_len, u8 *dev_class); -int mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr, - u8 link_type, u8 addr_type, u8 reason); +void mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr, + u8 link_type, u8 addr_type, u8 reason); void mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, u8 addr_type, u8 status); void mgmt_connect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 9029e67b3341..b9cd5829672e 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -4118,12 +4118,11 @@ static void unpair_device_rsp(struct pending_cmd *cmd, void *data) mgmt_pending_remove(cmd); } -int mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr, - u8 link_type, u8 addr_type, u8 reason) +void mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr, + u8 link_type, u8 addr_type, u8 reason) { struct mgmt_ev_device_disconnected ev; struct sock *sk = NULL; - int err; mgmt_pending_foreach(MGMT_OP_DISCONNECT, hdev, disconnect_rsp, &sk); @@ -4131,16 +4130,13 @@ int mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr, ev.addr.type = link_to_bdaddr(link_type, addr_type); ev.reason = reason; - err = mgmt_event(MGMT_EV_DEVICE_DISCONNECTED, hdev, &ev, sizeof(ev), - sk); + mgmt_event(MGMT_EV_DEVICE_DISCONNECTED, hdev, &ev, sizeof(ev), sk); if (sk) sock_put(sk); mgmt_pending_foreach(MGMT_OP_UNPAIR_DEVICE, hdev, unpair_device_rsp, hdev); - - return err; } void mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, -- cgit v1.2.3 From 901801b9a420e58969e039731dd007ae104842d3 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 6 Oct 2013 23:55:51 -0700 Subject: Bluetooth: Make mgmt_device_found() return void The return value of mgmt_device_found() function is not used and so just change it to return void. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- include/net/bluetooth/hci_core.h | 6 +++--- net/bluetooth/mgmt.c | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) (limited to 'include/net') diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 2b0bc31ec785..5b738a2d1786 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -1140,9 +1140,9 @@ int mgmt_set_class_of_dev_complete(struct hci_dev *hdev, u8 *dev_class, 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 link_type, - u8 addr_type, u8 *dev_class, s8 rssi, u8 cfm_name, - u8 ssp, u8 *eir, u16 eir_len); +void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, + u8 addr_type, u8 *dev_class, s8 rssi, u8 cfm_name, + u8 ssp, u8 *eir, u16 eir_len); int mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, u8 addr_type, s8 rssi, u8 *name, u8 name_len); int mgmt_discovering(struct hci_dev *hdev, u8 discovering); diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index b9cd5829672e..abf500b3b265 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -4524,20 +4524,20 @@ 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 link_type, - u8 addr_type, u8 *dev_class, s8 rssi, u8 cfm_name, u8 - ssp, u8 *eir, u16 eir_len) +void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, + u8 addr_type, u8 *dev_class, s8 rssi, u8 cfm_name, u8 + ssp, u8 *eir, u16 eir_len) { char buf[512]; struct mgmt_ev_device_found *ev = (void *) buf; size_t ev_size; if (!hci_discovery_active(hdev)) - return -EPERM; + return; /* Leave 5 bytes for a potential CoD field */ if (sizeof(*ev) + eir_len + 5 > sizeof(buf)) - return -EINVAL; + return; memset(buf, 0, sizeof(buf)); @@ -4559,7 +4559,7 @@ int mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, ev->eir_len = cpu_to_le16(eir_len); ev_size = sizeof(*ev) + eir_len; - return mgmt_event(MGMT_EV_DEVICE_FOUND, hdev, ev, ev_size, NULL); + mgmt_event(MGMT_EV_DEVICE_FOUND, hdev, ev, ev_size, NULL); } int mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, -- cgit v1.2.3 From 9cf12aee8bf5eb219c79089fb4556ad1d2066585 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 6 Oct 2013 23:55:52 -0700 Subject: Bluetooth: Make mgmt_remote_name() return void The return value of mgmt_remote_name() function is not used and so just change it to return void. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- include/net/bluetooth/hci_core.h | 4 ++-- net/bluetooth/mgmt.c | 7 +++---- 2 files changed, 5 insertions(+), 6 deletions(-) (limited to 'include/net') diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 5b738a2d1786..960c64b92415 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -1143,8 +1143,8 @@ int mgmt_read_local_oob_data_reply_complete(struct hci_dev *hdev, u8 *hash, void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, u8 addr_type, u8 *dev_class, s8 rssi, u8 cfm_name, u8 ssp, u8 *eir, u16 eir_len); -int mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, - u8 addr_type, s8 rssi, u8 *name, u8 name_len); +void mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, + u8 addr_type, s8 rssi, u8 *name, u8 name_len); int mgmt_discovering(struct hci_dev *hdev, u8 discovering); int mgmt_device_blocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type); int mgmt_device_unblocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type); diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index abf500b3b265..4a4545e1e44d 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -4562,8 +4562,8 @@ void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, mgmt_event(MGMT_EV_DEVICE_FOUND, hdev, ev, ev_size, NULL); } -int mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, - u8 addr_type, s8 rssi, u8 *name, u8 name_len) +void mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, + u8 addr_type, s8 rssi, u8 *name, u8 name_len) { struct mgmt_ev_device_found *ev; char buf[sizeof(*ev) + HCI_MAX_NAME_LENGTH + 2]; @@ -4582,8 +4582,7 @@ int mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, ev->eir_len = cpu_to_le16(eir_len); - return mgmt_event(MGMT_EV_DEVICE_FOUND, hdev, ev, - sizeof(*ev) + eir_len, NULL); + mgmt_event(MGMT_EV_DEVICE_FOUND, hdev, ev, sizeof(*ev) + eir_len, NULL); } int mgmt_discovering(struct hci_dev *hdev, u8 discovering) -- cgit v1.2.3 From 2f1e063bc035dbbdb9174cc5f55f073a28780aa8 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 6 Oct 2013 23:55:53 -0700 Subject: Bluetooth: Make mgmt_discovering() return void The return value of mgmt_discovering() function is not used and so just change it to return void. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- include/net/bluetooth/hci_core.h | 2 +- net/bluetooth/mgmt.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'include/net') diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 960c64b92415..c06552769644 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -1145,7 +1145,7 @@ void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, u8 ssp, u8 *eir, u16 eir_len); void mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, u8 addr_type, s8 rssi, u8 *name, u8 name_len); -int mgmt_discovering(struct hci_dev *hdev, u8 discovering); +void mgmt_discovering(struct hci_dev *hdev, u8 discovering); int mgmt_device_blocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type); int mgmt_device_unblocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type); int mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, u8 persistent); diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 4a4545e1e44d..4070bb05d304 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -4585,7 +4585,7 @@ void mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, mgmt_event(MGMT_EV_DEVICE_FOUND, hdev, ev, sizeof(*ev) + eir_len, NULL); } -int mgmt_discovering(struct hci_dev *hdev, u8 discovering) +void mgmt_discovering(struct hci_dev *hdev, u8 discovering) { struct mgmt_ev_discovering ev; struct pending_cmd *cmd; @@ -4609,7 +4609,7 @@ int mgmt_discovering(struct hci_dev *hdev, u8 discovering) ev.type = hdev->discovery.type; ev.discovering = discovering; - return mgmt_event(MGMT_EV_DISCOVERING, hdev, &ev, sizeof(ev), NULL); + mgmt_event(MGMT_EV_DISCOVERING, hdev, &ev, sizeof(ev), NULL); } int mgmt_device_blocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) -- cgit v1.2.3 From 7528ca1c5a3821951695e0e55daf192097a9925a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 7 Oct 2013 03:55:52 -0700 Subject: Bluetooth: Read location data on AMP controller init When initializing an AMP controller, read its current known location data so that it can be analyzed later on. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- include/net/bluetooth/hci.h | 2 ++ net/bluetooth/hci_core.c | 3 +++ 2 files changed, 5 insertions(+) (limited to 'include/net') diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index 3616ea794eb1..c8a91cb20173 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -851,6 +851,8 @@ struct hci_rp_read_inq_rsp_tx_power { #define HCI_OP_SET_EVENT_MASK_PAGE_2 0x0c63 +#define HCI_OP_READ_LOCATION_DATA 0x0c64 + #define HCI_OP_READ_FLOW_CONTROL_MODE 0x0c66 struct hci_rp_read_flow_control_mode { __u8 status; diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 99f83abbcaa6..967739c0285b 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -318,6 +318,9 @@ static void amp_init(struct hci_request *req) /* Read Data Blk size */ hci_req_add(req, HCI_OP_READ_DATA_BLOCK_SIZE, 0, NULL); + + /* Read Location Data */ + hci_req_add(req, HCI_OP_READ_LOCATION_DATA, 0, NULL); } static void hci_init1_req(struct hci_request *req, unsigned long opt) -- cgit v1.2.3 From 324d36ed26a22bc14b2dd4505f3dba3fb2676bcc Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 10 Oct 2013 10:50:06 -0700 Subject: Bluetooth: Remove hdev->ioctl driver callback Since there is no use of hdev->ioctl by any Bluetooth driver since ever, so just lets remove it. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- include/net/bluetooth/hci_core.h | 1 - net/bluetooth/hci_sock.c | 5 +---- 2 files changed, 1 insertion(+), 5 deletions(-) (limited to 'include/net') diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index c06552769644..237bf8c03fb4 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -287,7 +287,6 @@ struct hci_dev { int (*setup)(struct hci_dev *hdev); int (*send)(struct sk_buff *skb); void (*notify)(struct hci_dev *hdev, unsigned int evt); - int (*ioctl)(struct hci_dev *hdev, unsigned int cmd, unsigned long arg); }; #define HCI_PHY_HANDLE(handle) (handle & 0xff) diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index 5b2d3f3c9b67..3beaa0594009 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c @@ -553,10 +553,7 @@ static int hci_sock_bound_ioctl(struct sock *sk, unsigned int cmd, return hci_sock_blacklist_del(hdev, (void __user *) arg); } - if (hdev->ioctl) - return hdev->ioctl(hdev, cmd, arg); - - return -EINVAL; + return -ENOIOCTLCMD; } static int hci_sock_ioctl(struct socket *sock, unsigned int cmd, -- cgit v1.2.3 From 7ef9fbf08818fa1cb8ae89fca29f193dd78d5dd8 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 10 Oct 2013 14:54:14 -0700 Subject: Bluetooth: Move amp.h header file into net/bluetooth/ The amp.h header file is only used internally by the bluetooth.ko module and is not a public API. So make it local to the core Bluetooth module. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- include/net/bluetooth/amp.h | 54 --------------------------------------------- net/bluetooth/a2mp.c | 3 ++- net/bluetooth/amp.c | 3 ++- net/bluetooth/amp.h | 54 +++++++++++++++++++++++++++++++++++++++++++++ net/bluetooth/hci_event.c | 3 ++- net/bluetooth/l2cap_core.c | 3 ++- 6 files changed, 62 insertions(+), 58 deletions(-) delete mode 100644 include/net/bluetooth/amp.h create mode 100644 net/bluetooth/amp.h (limited to 'include/net') diff --git a/include/net/bluetooth/amp.h b/include/net/bluetooth/amp.h deleted file mode 100644 index 7ea3db77ba89..000000000000 --- a/include/net/bluetooth/amp.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - Copyright (c) 2011,2012 Intel Corp. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 and - only version 2 as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. -*/ - -#ifndef __AMP_H -#define __AMP_H - -struct amp_ctrl { - struct list_head list; - struct kref kref; - __u8 id; - __u16 assoc_len_so_far; - __u16 assoc_rem_len; - __u16 assoc_len; - __u8 *assoc; -}; - -int amp_ctrl_put(struct amp_ctrl *ctrl); -void amp_ctrl_get(struct amp_ctrl *ctrl); -struct amp_ctrl *amp_ctrl_add(struct amp_mgr *mgr, u8 id); -struct amp_ctrl *amp_ctrl_lookup(struct amp_mgr *mgr, u8 id); -void amp_ctrl_list_flush(struct amp_mgr *mgr); - -struct hci_conn *phylink_add(struct hci_dev *hdev, struct amp_mgr *mgr, - u8 remote_id, bool out); - -int phylink_gen_key(struct hci_conn *hcon, u8 *data, u8 *len, u8 *type); - -void amp_read_loc_info(struct hci_dev *hdev, struct amp_mgr *mgr); -void amp_read_loc_assoc_frag(struct hci_dev *hdev, u8 phy_handle); -void amp_read_loc_assoc(struct hci_dev *hdev, struct amp_mgr *mgr); -void amp_read_loc_assoc_final_data(struct hci_dev *hdev, - struct hci_conn *hcon); -void amp_create_phylink(struct hci_dev *hdev, struct amp_mgr *mgr, - struct hci_conn *hcon); -void amp_accept_phylink(struct hci_dev *hdev, struct amp_mgr *mgr, - struct hci_conn *hcon); -void amp_write_remote_assoc(struct hci_dev *hdev, u8 handle); -void amp_write_rem_assoc_continue(struct hci_dev *hdev, u8 handle); -void amp_physical_cfm(struct hci_conn *bredr_hcon, struct hci_conn *hs_hcon); -void amp_create_logical_link(struct l2cap_chan *chan); -void amp_disconnect_logical_link(struct hci_chan *hchan); -void amp_destroy_logical_link(struct hci_chan *hchan, u8 reason); - -#endif /* __AMP_H */ diff --git a/net/bluetooth/a2mp.c b/net/bluetooth/a2mp.c index b38d07477c20..9ae32cef1762 100644 --- a/net/bluetooth/a2mp.c +++ b/net/bluetooth/a2mp.c @@ -16,7 +16,8 @@ #include #include #include -#include + +#include "amp.h" /* Global AMP Manager list */ LIST_HEAD(amp_mgr_list); diff --git a/net/bluetooth/amp.c b/net/bluetooth/amp.c index d459ed43c779..b7b8f4eed661 100644 --- a/net/bluetooth/amp.c +++ b/net/bluetooth/amp.c @@ -15,9 +15,10 @@ #include #include #include -#include #include +#include "amp.h" + /* Remote AMP Controllers interface */ void amp_ctrl_get(struct amp_ctrl *ctrl) { diff --git a/net/bluetooth/amp.h b/net/bluetooth/amp.h new file mode 100644 index 000000000000..7ea3db77ba89 --- /dev/null +++ b/net/bluetooth/amp.h @@ -0,0 +1,54 @@ +/* + Copyright (c) 2011,2012 Intel Corp. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 and + only version 2 as published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. +*/ + +#ifndef __AMP_H +#define __AMP_H + +struct amp_ctrl { + struct list_head list; + struct kref kref; + __u8 id; + __u16 assoc_len_so_far; + __u16 assoc_rem_len; + __u16 assoc_len; + __u8 *assoc; +}; + +int amp_ctrl_put(struct amp_ctrl *ctrl); +void amp_ctrl_get(struct amp_ctrl *ctrl); +struct amp_ctrl *amp_ctrl_add(struct amp_mgr *mgr, u8 id); +struct amp_ctrl *amp_ctrl_lookup(struct amp_mgr *mgr, u8 id); +void amp_ctrl_list_flush(struct amp_mgr *mgr); + +struct hci_conn *phylink_add(struct hci_dev *hdev, struct amp_mgr *mgr, + u8 remote_id, bool out); + +int phylink_gen_key(struct hci_conn *hcon, u8 *data, u8 *len, u8 *type); + +void amp_read_loc_info(struct hci_dev *hdev, struct amp_mgr *mgr); +void amp_read_loc_assoc_frag(struct hci_dev *hdev, u8 phy_handle); +void amp_read_loc_assoc(struct hci_dev *hdev, struct amp_mgr *mgr); +void amp_read_loc_assoc_final_data(struct hci_dev *hdev, + struct hci_conn *hcon); +void amp_create_phylink(struct hci_dev *hdev, struct amp_mgr *mgr, + struct hci_conn *hcon); +void amp_accept_phylink(struct hci_dev *hdev, struct amp_mgr *mgr, + struct hci_conn *hcon); +void amp_write_remote_assoc(struct hci_dev *hdev, u8 handle); +void amp_write_rem_assoc_continue(struct hci_dev *hdev, u8 handle); +void amp_physical_cfm(struct hci_conn *bredr_hcon, struct hci_conn *hs_hcon); +void amp_create_logical_link(struct l2cap_chan *chan); +void amp_disconnect_logical_link(struct hci_chan *hchan); +void amp_destroy_logical_link(struct hci_chan *hchan, u8 reason); + +#endif /* __AMP_H */ diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index ada3bf4d7e2a..67316b3e9304 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -30,7 +30,8 @@ #include #include #include -#include + +#include "amp.h" /* Handle HCI Event packets */ diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 06e7173c2d13..09f6f61423ff 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -38,7 +38,8 @@ #include #include #include -#include + +#include "amp.h" bool disable_ertm; -- cgit v1.2.3 From 7024728ee534d739380dc4fd31f020cfc6e86c28 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 10 Oct 2013 14:54:15 -0700 Subject: Bluetooth: Move a2mp.h header file into net/bluetooth/ The a2mp.h header file is only used internally by the bluetooth.ko module and is not a public API. So make it local to the core Bluetooth module. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- include/net/bluetooth/a2mp.h | 150 ------------------------------------------- net/bluetooth/a2mp.c | 2 +- net/bluetooth/a2mp.h | 150 +++++++++++++++++++++++++++++++++++++++++++ net/bluetooth/amp.c | 2 +- net/bluetooth/hci_conn.c | 3 +- net/bluetooth/hci_event.c | 2 +- net/bluetooth/l2cap_core.c | 2 +- 7 files changed, 156 insertions(+), 155 deletions(-) delete mode 100644 include/net/bluetooth/a2mp.h create mode 100644 net/bluetooth/a2mp.h (limited to 'include/net') diff --git a/include/net/bluetooth/a2mp.h b/include/net/bluetooth/a2mp.h deleted file mode 100644 index 487b54c1308f..000000000000 --- a/include/net/bluetooth/a2mp.h +++ /dev/null @@ -1,150 +0,0 @@ -/* - Copyright (c) 2010,2011 Code Aurora Forum. All rights reserved. - Copyright (c) 2011,2012 Intel Corp. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 and - only version 2 as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. -*/ - -#ifndef __A2MP_H -#define __A2MP_H - -#include - -#define A2MP_FEAT_EXT 0x8000 - -enum amp_mgr_state { - READ_LOC_AMP_INFO, - READ_LOC_AMP_ASSOC, - READ_LOC_AMP_ASSOC_FINAL, - WRITE_REMOTE_AMP_ASSOC, -}; - -struct amp_mgr { - struct list_head list; - struct l2cap_conn *l2cap_conn; - struct l2cap_chan *a2mp_chan; - struct l2cap_chan *bredr_chan; - struct kref kref; - __u8 ident; - __u8 handle; - unsigned long state; - unsigned long flags; - - struct list_head amp_ctrls; - struct mutex amp_ctrls_lock; -}; - -struct a2mp_cmd { - __u8 code; - __u8 ident; - __le16 len; - __u8 data[0]; -} __packed; - -/* A2MP command codes */ -#define A2MP_COMMAND_REJ 0x01 -struct a2mp_cmd_rej { - __le16 reason; - __u8 data[0]; -} __packed; - -#define A2MP_DISCOVER_REQ 0x02 -struct a2mp_discov_req { - __le16 mtu; - __le16 ext_feat; -} __packed; - -struct a2mp_cl { - __u8 id; - __u8 type; - __u8 status; -} __packed; - -#define A2MP_DISCOVER_RSP 0x03 -struct a2mp_discov_rsp { - __le16 mtu; - __le16 ext_feat; - struct a2mp_cl cl[0]; -} __packed; - -#define A2MP_CHANGE_NOTIFY 0x04 -#define A2MP_CHANGE_RSP 0x05 - -#define A2MP_GETINFO_REQ 0x06 -struct a2mp_info_req { - __u8 id; -} __packed; - -#define A2MP_GETINFO_RSP 0x07 -struct a2mp_info_rsp { - __u8 id; - __u8 status; - __le32 total_bw; - __le32 max_bw; - __le32 min_latency; - __le16 pal_cap; - __le16 assoc_size; -} __packed; - -#define A2MP_GETAMPASSOC_REQ 0x08 -struct a2mp_amp_assoc_req { - __u8 id; -} __packed; - -#define A2MP_GETAMPASSOC_RSP 0x09 -struct a2mp_amp_assoc_rsp { - __u8 id; - __u8 status; - __u8 amp_assoc[0]; -} __packed; - -#define A2MP_CREATEPHYSLINK_REQ 0x0A -#define A2MP_DISCONNPHYSLINK_REQ 0x0C -struct a2mp_physlink_req { - __u8 local_id; - __u8 remote_id; - __u8 amp_assoc[0]; -} __packed; - -#define A2MP_CREATEPHYSLINK_RSP 0x0B -#define A2MP_DISCONNPHYSLINK_RSP 0x0D -struct a2mp_physlink_rsp { - __u8 local_id; - __u8 remote_id; - __u8 status; -} __packed; - -/* A2MP response status */ -#define A2MP_STATUS_SUCCESS 0x00 -#define A2MP_STATUS_INVALID_CTRL_ID 0x01 -#define A2MP_STATUS_UNABLE_START_LINK_CREATION 0x02 -#define A2MP_STATUS_NO_PHYSICAL_LINK_EXISTS 0x02 -#define A2MP_STATUS_COLLISION_OCCURED 0x03 -#define A2MP_STATUS_DISCONN_REQ_RECVD 0x04 -#define A2MP_STATUS_PHYS_LINK_EXISTS 0x05 -#define A2MP_STATUS_SECURITY_VIOLATION 0x06 - -extern struct list_head amp_mgr_list; -extern struct mutex amp_mgr_list_lock; - -struct amp_mgr *amp_mgr_get(struct amp_mgr *mgr); -int amp_mgr_put(struct amp_mgr *mgr); -u8 __next_ident(struct amp_mgr *mgr); -struct l2cap_chan *a2mp_channel_create(struct l2cap_conn *conn, - struct sk_buff *skb); -struct amp_mgr *amp_mgr_lookup_by_state(u8 state); -void a2mp_send(struct amp_mgr *mgr, u8 code, u8 ident, u16 len, void *data); -void a2mp_discover_amp(struct l2cap_chan *chan); -void a2mp_send_getinfo_rsp(struct hci_dev *hdev); -void a2mp_send_getampassoc_rsp(struct hci_dev *hdev, u8 status); -void a2mp_send_create_phy_link_req(struct hci_dev *hdev, u8 status); -void a2mp_send_create_phy_link_rsp(struct hci_dev *hdev, u8 status); - -#endif /* __A2MP_H */ diff --git a/net/bluetooth/a2mp.c b/net/bluetooth/a2mp.c index 9ae32cef1762..7e25be3e8a79 100644 --- a/net/bluetooth/a2mp.c +++ b/net/bluetooth/a2mp.c @@ -15,8 +15,8 @@ #include #include #include -#include +#include "a2mp.h" #include "amp.h" /* Global AMP Manager list */ diff --git a/net/bluetooth/a2mp.h b/net/bluetooth/a2mp.h new file mode 100644 index 000000000000..487b54c1308f --- /dev/null +++ b/net/bluetooth/a2mp.h @@ -0,0 +1,150 @@ +/* + Copyright (c) 2010,2011 Code Aurora Forum. All rights reserved. + Copyright (c) 2011,2012 Intel Corp. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 and + only version 2 as published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. +*/ + +#ifndef __A2MP_H +#define __A2MP_H + +#include + +#define A2MP_FEAT_EXT 0x8000 + +enum amp_mgr_state { + READ_LOC_AMP_INFO, + READ_LOC_AMP_ASSOC, + READ_LOC_AMP_ASSOC_FINAL, + WRITE_REMOTE_AMP_ASSOC, +}; + +struct amp_mgr { + struct list_head list; + struct l2cap_conn *l2cap_conn; + struct l2cap_chan *a2mp_chan; + struct l2cap_chan *bredr_chan; + struct kref kref; + __u8 ident; + __u8 handle; + unsigned long state; + unsigned long flags; + + struct list_head amp_ctrls; + struct mutex amp_ctrls_lock; +}; + +struct a2mp_cmd { + __u8 code; + __u8 ident; + __le16 len; + __u8 data[0]; +} __packed; + +/* A2MP command codes */ +#define A2MP_COMMAND_REJ 0x01 +struct a2mp_cmd_rej { + __le16 reason; + __u8 data[0]; +} __packed; + +#define A2MP_DISCOVER_REQ 0x02 +struct a2mp_discov_req { + __le16 mtu; + __le16 ext_feat; +} __packed; + +struct a2mp_cl { + __u8 id; + __u8 type; + __u8 status; +} __packed; + +#define A2MP_DISCOVER_RSP 0x03 +struct a2mp_discov_rsp { + __le16 mtu; + __le16 ext_feat; + struct a2mp_cl cl[0]; +} __packed; + +#define A2MP_CHANGE_NOTIFY 0x04 +#define A2MP_CHANGE_RSP 0x05 + +#define A2MP_GETINFO_REQ 0x06 +struct a2mp_info_req { + __u8 id; +} __packed; + +#define A2MP_GETINFO_RSP 0x07 +struct a2mp_info_rsp { + __u8 id; + __u8 status; + __le32 total_bw; + __le32 max_bw; + __le32 min_latency; + __le16 pal_cap; + __le16 assoc_size; +} __packed; + +#define A2MP_GETAMPASSOC_REQ 0x08 +struct a2mp_amp_assoc_req { + __u8 id; +} __packed; + +#define A2MP_GETAMPASSOC_RSP 0x09 +struct a2mp_amp_assoc_rsp { + __u8 id; + __u8 status; + __u8 amp_assoc[0]; +} __packed; + +#define A2MP_CREATEPHYSLINK_REQ 0x0A +#define A2MP_DISCONNPHYSLINK_REQ 0x0C +struct a2mp_physlink_req { + __u8 local_id; + __u8 remote_id; + __u8 amp_assoc[0]; +} __packed; + +#define A2MP_CREATEPHYSLINK_RSP 0x0B +#define A2MP_DISCONNPHYSLINK_RSP 0x0D +struct a2mp_physlink_rsp { + __u8 local_id; + __u8 remote_id; + __u8 status; +} __packed; + +/* A2MP response status */ +#define A2MP_STATUS_SUCCESS 0x00 +#define A2MP_STATUS_INVALID_CTRL_ID 0x01 +#define A2MP_STATUS_UNABLE_START_LINK_CREATION 0x02 +#define A2MP_STATUS_NO_PHYSICAL_LINK_EXISTS 0x02 +#define A2MP_STATUS_COLLISION_OCCURED 0x03 +#define A2MP_STATUS_DISCONN_REQ_RECVD 0x04 +#define A2MP_STATUS_PHYS_LINK_EXISTS 0x05 +#define A2MP_STATUS_SECURITY_VIOLATION 0x06 + +extern struct list_head amp_mgr_list; +extern struct mutex amp_mgr_list_lock; + +struct amp_mgr *amp_mgr_get(struct amp_mgr *mgr); +int amp_mgr_put(struct amp_mgr *mgr); +u8 __next_ident(struct amp_mgr *mgr); +struct l2cap_chan *a2mp_channel_create(struct l2cap_conn *conn, + struct sk_buff *skb); +struct amp_mgr *amp_mgr_lookup_by_state(u8 state); +void a2mp_send(struct amp_mgr *mgr, u8 code, u8 ident, u16 len, void *data); +void a2mp_discover_amp(struct l2cap_chan *chan); +void a2mp_send_getinfo_rsp(struct hci_dev *hdev); +void a2mp_send_getampassoc_rsp(struct hci_dev *hdev, u8 status); +void a2mp_send_create_phy_link_req(struct hci_dev *hdev, u8 status); +void a2mp_send_create_phy_link_rsp(struct hci_dev *hdev, u8 status); + +#endif /* __A2MP_H */ diff --git a/net/bluetooth/amp.c b/net/bluetooth/amp.c index b7b8f4eed661..5497ed3f2e3d 100644 --- a/net/bluetooth/amp.c +++ b/net/bluetooth/amp.c @@ -14,9 +14,9 @@ #include #include #include -#include #include +#include "a2mp.h" #include "amp.h" /* Remote AMP Controllers interface */ diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index dedd1ea5dd4c..8141c8d83139 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -28,9 +28,10 @@ #include #include -#include #include +#include "a2mp.h" + struct sco_param { u16 pkt_type; u16 max_latency; diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 67316b3e9304..bbe2d292c4a9 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -29,8 +29,8 @@ #include #include #include -#include +#include "a2mp.h" #include "amp.h" /* Handle HCI Event packets */ diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 09f6f61423ff..947e18691e92 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -37,8 +37,8 @@ #include #include #include -#include +#include "a2mp.h" #include "amp.h" bool disable_ertm; -- cgit v1.2.3 From ac4b7236610cef99821f40f44a74030b85d85270 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 10 Oct 2013 14:54:16 -0700 Subject: Bluetooth: Move smp.h header file into net/bluetooth/ The smp.h header file is only used internally by the bluetooth.ko module and is not a public API. So make it local to the core Bluetooth module. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- include/net/bluetooth/smp.h | 146 -------------------------------------------- net/bluetooth/hci_conn.c | 2 +- net/bluetooth/l2cap_core.c | 2 +- net/bluetooth/l2cap_sock.c | 3 +- net/bluetooth/mgmt.c | 3 +- net/bluetooth/smp.c | 3 +- net/bluetooth/smp.h | 146 ++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 154 insertions(+), 151 deletions(-) delete mode 100644 include/net/bluetooth/smp.h create mode 100644 net/bluetooth/smp.h (limited to 'include/net') diff --git a/include/net/bluetooth/smp.h b/include/net/bluetooth/smp.h deleted file mode 100644 index f8ba07f3e5fa..000000000000 --- a/include/net/bluetooth/smp.h +++ /dev/null @@ -1,146 +0,0 @@ -/* - BlueZ - Bluetooth protocol stack for Linux - Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 as - published by the Free Software Foundation; - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - SOFTWARE IS DISCLAIMED. -*/ - -#ifndef __SMP_H -#define __SMP_H - -struct smp_command_hdr { - __u8 code; -} __packed; - -#define SMP_CMD_PAIRING_REQ 0x01 -#define SMP_CMD_PAIRING_RSP 0x02 -struct smp_cmd_pairing { - __u8 io_capability; - __u8 oob_flag; - __u8 auth_req; - __u8 max_key_size; - __u8 init_key_dist; - __u8 resp_key_dist; -} __packed; - -#define SMP_IO_DISPLAY_ONLY 0x00 -#define SMP_IO_DISPLAY_YESNO 0x01 -#define SMP_IO_KEYBOARD_ONLY 0x02 -#define SMP_IO_NO_INPUT_OUTPUT 0x03 -#define SMP_IO_KEYBOARD_DISPLAY 0x04 - -#define SMP_OOB_NOT_PRESENT 0x00 -#define SMP_OOB_PRESENT 0x01 - -#define SMP_DIST_ENC_KEY 0x01 -#define SMP_DIST_ID_KEY 0x02 -#define SMP_DIST_SIGN 0x04 - -#define SMP_AUTH_NONE 0x00 -#define SMP_AUTH_BONDING 0x01 -#define SMP_AUTH_MITM 0x04 - -#define SMP_CMD_PAIRING_CONFIRM 0x03 -struct smp_cmd_pairing_confirm { - __u8 confirm_val[16]; -} __packed; - -#define SMP_CMD_PAIRING_RANDOM 0x04 -struct smp_cmd_pairing_random { - __u8 rand_val[16]; -} __packed; - -#define SMP_CMD_PAIRING_FAIL 0x05 -struct smp_cmd_pairing_fail { - __u8 reason; -} __packed; - -#define SMP_CMD_ENCRYPT_INFO 0x06 -struct smp_cmd_encrypt_info { - __u8 ltk[16]; -} __packed; - -#define SMP_CMD_MASTER_IDENT 0x07 -struct smp_cmd_master_ident { - __le16 ediv; - __u8 rand[8]; -} __packed; - -#define SMP_CMD_IDENT_INFO 0x08 -struct smp_cmd_ident_info { - __u8 irk[16]; -} __packed; - -#define SMP_CMD_IDENT_ADDR_INFO 0x09 -struct smp_cmd_ident_addr_info { - __u8 addr_type; - bdaddr_t bdaddr; -} __packed; - -#define SMP_CMD_SIGN_INFO 0x0a -struct smp_cmd_sign_info { - __u8 csrk[16]; -} __packed; - -#define SMP_CMD_SECURITY_REQ 0x0b -struct smp_cmd_security_req { - __u8 auth_req; -} __packed; - -#define SMP_PASSKEY_ENTRY_FAILED 0x01 -#define SMP_OOB_NOT_AVAIL 0x02 -#define SMP_AUTH_REQUIREMENTS 0x03 -#define SMP_CONFIRM_FAILED 0x04 -#define SMP_PAIRING_NOTSUPP 0x05 -#define SMP_ENC_KEY_SIZE 0x06 -#define SMP_CMD_NOTSUPP 0x07 -#define SMP_UNSPECIFIED 0x08 -#define SMP_REPEATED_ATTEMPTS 0x09 - -#define SMP_MIN_ENC_KEY_SIZE 7 -#define SMP_MAX_ENC_KEY_SIZE 16 - -#define SMP_FLAG_TK_VALID 1 -#define SMP_FLAG_CFM_PENDING 2 -#define SMP_FLAG_MITM_AUTH 3 - -struct smp_chan { - struct l2cap_conn *conn; - u8 preq[7]; /* SMP Pairing Request */ - u8 prsp[7]; /* SMP Pairing Response */ - u8 prnd[16]; /* SMP Pairing Random (local) */ - u8 rrnd[16]; /* SMP Pairing Random (remote) */ - u8 pcnf[16]; /* SMP Pairing Confirm */ - u8 tk[16]; /* SMP Temporary Key */ - u8 enc_key_size; - unsigned long smp_flags; - struct crypto_blkcipher *tfm; - struct work_struct confirm; - struct work_struct random; - -}; - -/* SMP Commands */ -int smp_conn_security(struct hci_conn *hcon, __u8 sec_level); -int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb); -int smp_distribute_keys(struct l2cap_conn *conn, __u8 force); -int smp_user_confirm_reply(struct hci_conn *conn, u16 mgmt_op, __le32 passkey); - -void smp_chan_destroy(struct l2cap_conn *conn); - -#endif /* __SMP_H */ diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 8141c8d83139..139587159200 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -28,8 +28,8 @@ #include #include -#include +#include "smp.h" #include "a2mp.h" struct sco_param { diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 947e18691e92..a7d10c3596e3 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -36,8 +36,8 @@ #include #include #include -#include +#include "smp.h" #include "a2mp.h" #include "amp.h" diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 1daa4c579eb2..69e42db8a707 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -32,7 +32,8 @@ #include #include #include -#include + +#include "smp.h" static struct bt_sock_list l2cap_sk_list = { .lock = __RW_LOCK_UNLOCKED(l2cap_sk_list.lock) diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 9a069b532bde..143dd7319981 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -30,7 +30,8 @@ #include #include #include -#include + +#include "smp.h" #define MGMT_VERSION 1 #define MGMT_REVISION 4 diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 884b2081a262..9272094bd429 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c @@ -28,7 +28,8 @@ #include #include #include -#include + +#include "smp.h" #define SMP_TIMEOUT msecs_to_jiffies(30000) diff --git a/net/bluetooth/smp.h b/net/bluetooth/smp.h new file mode 100644 index 000000000000..f8ba07f3e5fa --- /dev/null +++ b/net/bluetooth/smp.h @@ -0,0 +1,146 @@ +/* + BlueZ - Bluetooth protocol stack for Linux + Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + SOFTWARE IS DISCLAIMED. +*/ + +#ifndef __SMP_H +#define __SMP_H + +struct smp_command_hdr { + __u8 code; +} __packed; + +#define SMP_CMD_PAIRING_REQ 0x01 +#define SMP_CMD_PAIRING_RSP 0x02 +struct smp_cmd_pairing { + __u8 io_capability; + __u8 oob_flag; + __u8 auth_req; + __u8 max_key_size; + __u8 init_key_dist; + __u8 resp_key_dist; +} __packed; + +#define SMP_IO_DISPLAY_ONLY 0x00 +#define SMP_IO_DISPLAY_YESNO 0x01 +#define SMP_IO_KEYBOARD_ONLY 0x02 +#define SMP_IO_NO_INPUT_OUTPUT 0x03 +#define SMP_IO_KEYBOARD_DISPLAY 0x04 + +#define SMP_OOB_NOT_PRESENT 0x00 +#define SMP_OOB_PRESENT 0x01 + +#define SMP_DIST_ENC_KEY 0x01 +#define SMP_DIST_ID_KEY 0x02 +#define SMP_DIST_SIGN 0x04 + +#define SMP_AUTH_NONE 0x00 +#define SMP_AUTH_BONDING 0x01 +#define SMP_AUTH_MITM 0x04 + +#define SMP_CMD_PAIRING_CONFIRM 0x03 +struct smp_cmd_pairing_confirm { + __u8 confirm_val[16]; +} __packed; + +#define SMP_CMD_PAIRING_RANDOM 0x04 +struct smp_cmd_pairing_random { + __u8 rand_val[16]; +} __packed; + +#define SMP_CMD_PAIRING_FAIL 0x05 +struct smp_cmd_pairing_fail { + __u8 reason; +} __packed; + +#define SMP_CMD_ENCRYPT_INFO 0x06 +struct smp_cmd_encrypt_info { + __u8 ltk[16]; +} __packed; + +#define SMP_CMD_MASTER_IDENT 0x07 +struct smp_cmd_master_ident { + __le16 ediv; + __u8 rand[8]; +} __packed; + +#define SMP_CMD_IDENT_INFO 0x08 +struct smp_cmd_ident_info { + __u8 irk[16]; +} __packed; + +#define SMP_CMD_IDENT_ADDR_INFO 0x09 +struct smp_cmd_ident_addr_info { + __u8 addr_type; + bdaddr_t bdaddr; +} __packed; + +#define SMP_CMD_SIGN_INFO 0x0a +struct smp_cmd_sign_info { + __u8 csrk[16]; +} __packed; + +#define SMP_CMD_SECURITY_REQ 0x0b +struct smp_cmd_security_req { + __u8 auth_req; +} __packed; + +#define SMP_PASSKEY_ENTRY_FAILED 0x01 +#define SMP_OOB_NOT_AVAIL 0x02 +#define SMP_AUTH_REQUIREMENTS 0x03 +#define SMP_CONFIRM_FAILED 0x04 +#define SMP_PAIRING_NOTSUPP 0x05 +#define SMP_ENC_KEY_SIZE 0x06 +#define SMP_CMD_NOTSUPP 0x07 +#define SMP_UNSPECIFIED 0x08 +#define SMP_REPEATED_ATTEMPTS 0x09 + +#define SMP_MIN_ENC_KEY_SIZE 7 +#define SMP_MAX_ENC_KEY_SIZE 16 + +#define SMP_FLAG_TK_VALID 1 +#define SMP_FLAG_CFM_PENDING 2 +#define SMP_FLAG_MITM_AUTH 3 + +struct smp_chan { + struct l2cap_conn *conn; + u8 preq[7]; /* SMP Pairing Request */ + u8 prsp[7]; /* SMP Pairing Response */ + u8 prnd[16]; /* SMP Pairing Random (local) */ + u8 rrnd[16]; /* SMP Pairing Random (remote) */ + u8 pcnf[16]; /* SMP Pairing Confirm */ + u8 tk[16]; /* SMP Temporary Key */ + u8 enc_key_size; + unsigned long smp_flags; + struct crypto_blkcipher *tfm; + struct work_struct confirm; + struct work_struct random; + +}; + +/* SMP Commands */ +int smp_conn_security(struct hci_conn *hcon, __u8 sec_level); +int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb); +int smp_distribute_keys(struct l2cap_conn *conn, __u8 force); +int smp_user_confirm_reply(struct hci_conn *conn, u16 mgmt_op, __le32 passkey); + +void smp_chan_destroy(struct l2cap_conn *conn); + +#endif /* __SMP_H */ -- cgit v1.2.3 From e1a26170692dc1e5fbe0ccd98ef86cc9fcd31a64 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 10 Oct 2013 16:52:43 -0700 Subject: Bluetooth: Provide hdev parameter to hci_recv_frame() driver callback To avoid casting skb->dev into hdev, just let the drivers provide the hdev directly when calling hci_recv_frame() function. This patch also fixes up all drivers to provide the hdev. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- drivers/bluetooth/bfusb.c | 3 +-- drivers/bluetooth/bluecard_cs.c | 3 +-- drivers/bluetooth/bpa10x.c | 4 +--- drivers/bluetooth/bt3c_cs.c | 3 +-- drivers/bluetooth/btmrvl_sdio.c | 8 +++----- drivers/bluetooth/btsdio.c | 3 +-- drivers/bluetooth/btuart_cs.c | 3 +-- drivers/bluetooth/btwilink.c | 4 +--- drivers/bluetooth/dtl1_cs.c | 3 +-- drivers/bluetooth/hci_bcsp.c | 5 ++--- drivers/bluetooth/hci_h5.c | 2 +- drivers/bluetooth/hci_ll.c | 13 ++++++------- drivers/bluetooth/hci_vhci.c | 3 +-- include/net/bluetooth/hci_core.h | 2 +- net/bluetooth/hci_core.c | 6 ++---- 15 files changed, 24 insertions(+), 41 deletions(-) (limited to 'include/net') diff --git a/drivers/bluetooth/bfusb.c b/drivers/bluetooth/bfusb.c index 66faad0c6237..b7b5bb879f08 100644 --- a/drivers/bluetooth/bfusb.c +++ b/drivers/bluetooth/bfusb.c @@ -318,7 +318,6 @@ static inline int bfusb_recv_block(struct bfusb_data *data, int hdr, unsigned ch return -ENOMEM; } - skb->dev = (void *) data->hdev; bt_cb(skb)->pkt_type = pkt_type; data->reassembly = skb; @@ -333,7 +332,7 @@ static inline int bfusb_recv_block(struct bfusb_data *data, int hdr, unsigned ch memcpy(skb_put(data->reassembly, len), buf, len); if (hdr & 0x08) { - hci_recv_frame(data->reassembly); + hci_recv_frame(data->hdev, data->reassembly); data->reassembly = NULL; } diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c index aa872c9b3fc2..395acde99d78 100644 --- a/drivers/bluetooth/bluecard_cs.c +++ b/drivers/bluetooth/bluecard_cs.c @@ -399,7 +399,6 @@ static void bluecard_receive(bluecard_info_t *info, unsigned int offset) if (info->rx_state == RECV_WAIT_PACKET_TYPE) { - info->rx_skb->dev = (void *) info->hdev; bt_cb(info->rx_skb)->pkt_type = buf[i]; switch (bt_cb(info->rx_skb)->pkt_type) { @@ -477,7 +476,7 @@ static void bluecard_receive(bluecard_info_t *info, unsigned int offset) break; case RECV_WAIT_DATA: - hci_recv_frame(info->rx_skb); + hci_recv_frame(info->hdev, info->rx_skb); info->rx_skb = NULL; break; diff --git a/drivers/bluetooth/bpa10x.c b/drivers/bluetooth/bpa10x.c index 2fe4a8031348..3188fb48bf4b 100644 --- a/drivers/bluetooth/bpa10x.c +++ b/drivers/bluetooth/bpa10x.c @@ -129,8 +129,6 @@ static int bpa10x_recv(struct hci_dev *hdev, int queue, void *buf, int count) return -ENOMEM; } - skb->dev = (void *) hdev; - data->rx_skb[queue] = skb; scb = (void *) skb->cb; @@ -155,7 +153,7 @@ static int bpa10x_recv(struct hci_dev *hdev, int queue, void *buf, int count) data->rx_skb[queue] = NULL; bt_cb(skb)->pkt_type = scb->type; - hci_recv_frame(skb); + hci_recv_frame(hdev, skb); } count -= len; buf += len; diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c index 673455cbde4c..d8e4b0d7926e 100644 --- a/drivers/bluetooth/bt3c_cs.c +++ b/drivers/bluetooth/bt3c_cs.c @@ -247,7 +247,6 @@ static void bt3c_receive(bt3c_info_t *info) if (info->rx_state == RECV_WAIT_PACKET_TYPE) { - info->rx_skb->dev = (void *) info->hdev; bt_cb(info->rx_skb)->pkt_type = inb(iobase + DATA_L); inb(iobase + DATA_H); //printk("bt3c: PACKET_TYPE=%02x\n", bt_cb(info->rx_skb)->pkt_type); @@ -318,7 +317,7 @@ static void bt3c_receive(bt3c_info_t *info) break; case RECV_WAIT_DATA: - hci_recv_frame(info->rx_skb); + hci_recv_frame(info->hdev, info->rx_skb); info->rx_skb = NULL; break; diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c index 332475e400cf..fabcf5bb48af 100644 --- a/drivers/bluetooth/btmrvl_sdio.c +++ b/drivers/bluetooth/btmrvl_sdio.c @@ -600,15 +600,14 @@ static int btmrvl_sdio_card_to_host(struct btmrvl_private *priv) case HCI_SCODATA_PKT: case HCI_EVENT_PKT: bt_cb(skb)->pkt_type = type; - skb->dev = (void *)hdev; skb_put(skb, buf_len); skb_pull(skb, SDIO_HEADER_LEN); if (type == HCI_EVENT_PKT) { if (btmrvl_check_evtpkt(priv, skb)) - hci_recv_frame(skb); + hci_recv_frame(hdev, skb); } else { - hci_recv_frame(skb); + hci_recv_frame(hdev, skb); } hdev->stat.byte_rx += buf_len; @@ -616,12 +615,11 @@ static int btmrvl_sdio_card_to_host(struct btmrvl_private *priv) case MRVL_VENDOR_PKT: bt_cb(skb)->pkt_type = HCI_VENDOR_PKT; - skb->dev = (void *)hdev; skb_put(skb, buf_len); skb_pull(skb, SDIO_HEADER_LEN); if (btmrvl_process_event(priv, skb)) - hci_recv_frame(skb); + hci_recv_frame(hdev, skb); hdev->stat.byte_rx += buf_len; break; diff --git a/drivers/bluetooth/btsdio.c b/drivers/bluetooth/btsdio.c index 4a9909713874..72fe49e60359 100644 --- a/drivers/bluetooth/btsdio.c +++ b/drivers/bluetooth/btsdio.c @@ -157,10 +157,9 @@ static int btsdio_rx_packet(struct btsdio_data *data) data->hdev->stat.byte_rx += len; - skb->dev = (void *) data->hdev; bt_cb(skb)->pkt_type = hdr[3]; - err = hci_recv_frame(skb); + err = hci_recv_frame(data->hdev, skb); if (err < 0) return err; diff --git a/drivers/bluetooth/btuart_cs.c b/drivers/bluetooth/btuart_cs.c index 970e2d3dd3c2..d0b89ecf1c59 100644 --- a/drivers/bluetooth/btuart_cs.c +++ b/drivers/bluetooth/btuart_cs.c @@ -198,7 +198,6 @@ static void btuart_receive(btuart_info_t *info) if (info->rx_state == RECV_WAIT_PACKET_TYPE) { - info->rx_skb->dev = (void *) info->hdev; bt_cb(info->rx_skb)->pkt_type = inb(iobase + UART_RX); switch (bt_cb(info->rx_skb)->pkt_type) { @@ -265,7 +264,7 @@ static void btuart_receive(btuart_info_t *info) break; case RECV_WAIT_DATA: - hci_recv_frame(info->rx_skb); + hci_recv_frame(info->hdev, info->rx_skb); info->rx_skb = NULL; break; diff --git a/drivers/bluetooth/btwilink.c b/drivers/bluetooth/btwilink.c index 60abf596f60e..5e10fb0a7e05 100644 --- a/drivers/bluetooth/btwilink.c +++ b/drivers/bluetooth/btwilink.c @@ -108,10 +108,8 @@ static long st_receive(void *priv_data, struct sk_buff *skb) return -EFAULT; } - skb->dev = (void *) lhst->hdev; - /* Forward skb to HCI core layer */ - err = hci_recv_frame(skb); + err = hci_recv_frame(lhst->hdev, skb); if (err < 0) { BT_ERR("Unable to push skb to HCI core(%d)", err); return err; diff --git a/drivers/bluetooth/dtl1_cs.c b/drivers/bluetooth/dtl1_cs.c index c43aff8ec995..29451413bc04 100644 --- a/drivers/bluetooth/dtl1_cs.c +++ b/drivers/bluetooth/dtl1_cs.c @@ -256,9 +256,8 @@ static void dtl1_receive(dtl1_info_t *info) case 0x83: case 0x84: /* send frame to the HCI layer */ - info->rx_skb->dev = (void *) info->hdev; bt_cb(info->rx_skb)->pkt_type &= 0x0f; - hci_recv_frame(info->rx_skb); + hci_recv_frame(info->hdev, info->rx_skb); break; default: /* unknown packet */ diff --git a/drivers/bluetooth/hci_bcsp.c b/drivers/bluetooth/hci_bcsp.c index 57e502e06080..0bc87f7abd95 100644 --- a/drivers/bluetooth/hci_bcsp.c +++ b/drivers/bluetooth/hci_bcsp.c @@ -522,7 +522,7 @@ static void bcsp_complete_rx_pkt(struct hci_uart *hu) memcpy(skb_push(bcsp->rx_skb, HCI_EVENT_HDR_SIZE), &hdr, HCI_EVENT_HDR_SIZE); bt_cb(bcsp->rx_skb)->pkt_type = HCI_EVENT_PKT; - hci_recv_frame(bcsp->rx_skb); + hci_recv_frame(hu->hdev, bcsp->rx_skb); } else { BT_ERR ("Packet for unknown channel (%u %s)", bcsp->rx_skb->data[1] & 0x0f, @@ -536,7 +536,7 @@ static void bcsp_complete_rx_pkt(struct hci_uart *hu) /* Pull out BCSP hdr */ skb_pull(bcsp->rx_skb, 4); - hci_recv_frame(bcsp->rx_skb); + hci_recv_frame(hu->hdev, bcsp->rx_skb); } bcsp->rx_state = BCSP_W4_PKT_DELIMITER; @@ -655,7 +655,6 @@ static int bcsp_recv(struct hci_uart *hu, void *data, int count) bcsp->rx_count = 0; return 0; } - bcsp->rx_skb->dev = (void *) hu->hdev; break; } break; diff --git a/drivers/bluetooth/hci_h5.c b/drivers/bluetooth/hci_h5.c index b6154d5a07a5..f6f497450560 100644 --- a/drivers/bluetooth/hci_h5.c +++ b/drivers/bluetooth/hci_h5.c @@ -340,7 +340,7 @@ static void h5_complete_rx_pkt(struct hci_uart *hu) /* Remove Three-wire header */ skb_pull(h5->rx_skb, 4); - hci_recv_frame(h5->rx_skb); + hci_recv_frame(hu->hdev, h5->rx_skb); h5->rx_skb = NULL; break; diff --git a/drivers/bluetooth/hci_ll.c b/drivers/bluetooth/hci_ll.c index cfc767938589..58a9541feba6 100644 --- a/drivers/bluetooth/hci_ll.c +++ b/drivers/bluetooth/hci_ll.c @@ -346,14 +346,14 @@ static int ll_enqueue(struct hci_uart *hu, struct sk_buff *skb) return 0; } -static inline int ll_check_data_len(struct ll_struct *ll, int len) +static inline int ll_check_data_len(struct hci_dev *hdev, struct ll_struct *ll, int len) { int room = skb_tailroom(ll->rx_skb); BT_DBG("len %d room %d", len, room); if (!len) { - hci_recv_frame(ll->rx_skb); + hci_recv_frame(hdev, ll->rx_skb); } else if (len > room) { BT_ERR("Data length is too large"); kfree_skb(ll->rx_skb); @@ -395,7 +395,7 @@ static int ll_recv(struct hci_uart *hu, void *data, int count) switch (ll->rx_state) { case HCILL_W4_DATA: BT_DBG("Complete data"); - hci_recv_frame(ll->rx_skb); + hci_recv_frame(hu->hdev, ll->rx_skb); ll->rx_state = HCILL_W4_PACKET_TYPE; ll->rx_skb = NULL; @@ -406,7 +406,7 @@ static int ll_recv(struct hci_uart *hu, void *data, int count) BT_DBG("Event header: evt 0x%2.2x plen %d", eh->evt, eh->plen); - ll_check_data_len(ll, eh->plen); + ll_check_data_len(hu->hdev, ll, eh->plen); continue; case HCILL_W4_ACL_HDR: @@ -415,7 +415,7 @@ static int ll_recv(struct hci_uart *hu, void *data, int count) BT_DBG("ACL header: dlen %d", dlen); - ll_check_data_len(ll, dlen); + ll_check_data_len(hu->hdev, ll, dlen); continue; case HCILL_W4_SCO_HDR: @@ -423,7 +423,7 @@ static int ll_recv(struct hci_uart *hu, void *data, int count) BT_DBG("SCO header: dlen %d", sh->dlen); - ll_check_data_len(ll, sh->dlen); + ll_check_data_len(hu->hdev, ll, sh->dlen); continue; } } @@ -494,7 +494,6 @@ static int ll_recv(struct hci_uart *hu, void *data, int count) return -ENOMEM; } - ll->rx_skb->dev = (void *) hu->hdev; bt_cb(ll->rx_skb)->pkt_type = type; } diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c index c04a3e6fb37c..0fd522e85a71 100644 --- a/drivers/bluetooth/hci_vhci.c +++ b/drivers/bluetooth/hci_vhci.c @@ -179,10 +179,9 @@ static inline ssize_t vhci_get_user(struct vhci_data *data, return -ENODEV; } - skb->dev = (void *) data->hdev; bt_cb(skb)->pkt_type = pkt_type; - ret = hci_recv_frame(skb); + ret = hci_recv_frame(data->hdev, skb); break; case HCI_VENDOR_PKT: diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 237bf8c03fb4..29b81476424c 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -755,7 +755,7 @@ int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr); void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb); -int hci_recv_frame(struct sk_buff *skb); +int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb); int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count); int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count); diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 6cc2f86499f8..4f0d4b443171 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -2485,9 +2485,8 @@ int hci_resume_dev(struct hci_dev *hdev) EXPORT_SYMBOL(hci_resume_dev); /* Receive frame from HCI drivers */ -int hci_recv_frame(struct sk_buff *skb) +int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb) { - struct hci_dev *hdev = (struct hci_dev *) skb->dev; if (!hdev || (!test_bit(HCI_UP, &hdev->flags) && !test_bit(HCI_INIT, &hdev->flags))) { kfree_skb(skb); @@ -2546,7 +2545,6 @@ static int hci_reassembly(struct hci_dev *hdev, int type, void *data, scb->expect = hlen; scb->pkt_type = type; - skb->dev = (void *) hdev; hdev->reassembly[index] = skb; } @@ -2606,7 +2604,7 @@ static int hci_reassembly(struct hci_dev *hdev, int type, void *data, /* Complete frame */ bt_cb(skb)->pkt_type = type; - hci_recv_frame(skb); + hci_recv_frame(hdev, skb); hdev->reassembly[index] = NULL; return remain; -- cgit v1.2.3 From 7bd8f09f69f8a190f9b8334a07bb0a9237612314 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 11 Oct 2013 06:19:18 -0700 Subject: Bluetooth: Add hdev parameter to hdev->send driver callback Instead of masking hdev inside the skb->dev parameter, hand it directly to the driver as a parameter to hdev->send. This makes the driver interface more clear and simpler. This patch fixes all drivers to accept and handle the new parameter of hdev->send callback. Special care has been taken for bpa10x and btusb drivers that require having skb->dev set to hdev for the URB transmit complete handlers. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- drivers/bluetooth/bfusb.c | 3 +-- drivers/bluetooth/bluecard_cs.c | 3 +-- drivers/bluetooth/bpa10x.c | 5 +++-- drivers/bluetooth/bt3c_cs.c | 3 +-- drivers/bluetooth/btmrvl_main.c | 4 +--- drivers/bluetooth/btsdio.c | 3 +-- drivers/bluetooth/btuart_cs.c | 3 +-- drivers/bluetooth/btusb.c | 5 +++-- drivers/bluetooth/btwilink.c | 5 +---- drivers/bluetooth/dtl1_cs.c | 3 +-- drivers/bluetooth/hci_ldisc.c | 3 +-- drivers/bluetooth/hci_ll.c | 1 - drivers/bluetooth/hci_vhci.c | 3 +-- include/net/bluetooth/hci_core.h | 2 +- net/bluetooth/hci_core.c | 4 +--- 15 files changed, 18 insertions(+), 32 deletions(-) (limited to 'include/net') diff --git a/drivers/bluetooth/bfusb.c b/drivers/bluetooth/bfusb.c index b7b5bb879f08..a6758490fa61 100644 --- a/drivers/bluetooth/bfusb.c +++ b/drivers/bluetooth/bfusb.c @@ -464,9 +464,8 @@ static int bfusb_close(struct hci_dev *hdev) return 0; } -static int bfusb_send_frame(struct sk_buff *skb) +static int bfusb_send_frame(struct hci_dev *hdev, struct sk_buff *skb) { - struct hci_dev *hdev = (struct hci_dev *) skb->dev; struct bfusb_data *data; struct sk_buff *nskb; unsigned char buf[3]; diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c index 395acde99d78..9194a1ba897f 100644 --- a/drivers/bluetooth/bluecard_cs.c +++ b/drivers/bluetooth/bluecard_cs.c @@ -658,10 +658,9 @@ static int bluecard_hci_close(struct hci_dev *hdev) } -static int bluecard_hci_send_frame(struct sk_buff *skb) +static int bluecard_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb) { bluecard_info_t *info; - struct hci_dev *hdev = (struct hci_dev *)(skb->dev); if (!hdev) { BT_ERR("Frame for unknown HCI device (hdev=NULL)"); diff --git a/drivers/bluetooth/bpa10x.c b/drivers/bluetooth/bpa10x.c index 3188fb48bf4b..b9e4e621fb10 100644 --- a/drivers/bluetooth/bpa10x.c +++ b/drivers/bluetooth/bpa10x.c @@ -350,9 +350,8 @@ static int bpa10x_flush(struct hci_dev *hdev) return 0; } -static int bpa10x_send_frame(struct sk_buff *skb) +static int bpa10x_send_frame(struct hci_dev *hdev, struct sk_buff *skb) { - struct hci_dev *hdev = (struct hci_dev *) skb->dev; struct bpa10x_data *data = hci_get_drvdata(hdev); struct usb_ctrlrequest *dr; struct urb *urb; @@ -364,6 +363,8 @@ static int bpa10x_send_frame(struct sk_buff *skb) if (!test_bit(HCI_RUNNING, &hdev->flags)) return -EBUSY; + skb->dev = (void *) hdev; + urb = usb_alloc_urb(0, GFP_ATOMIC); if (!urb) return -ENOMEM; diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c index d8e4b0d7926e..fcd5fe993ad0 100644 --- a/drivers/bluetooth/bt3c_cs.c +++ b/drivers/bluetooth/bt3c_cs.c @@ -415,10 +415,9 @@ static int bt3c_hci_close(struct hci_dev *hdev) } -static int bt3c_hci_send_frame(struct sk_buff *skb) +static int bt3c_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb) { bt3c_info_t *info; - struct hci_dev *hdev = (struct hci_dev *)(skb->dev); unsigned long flags; if (!hdev) { diff --git a/drivers/bluetooth/btmrvl_main.c b/drivers/bluetooth/btmrvl_main.c index 8ac4d938d89c..547a447149d3 100644 --- a/drivers/bluetooth/btmrvl_main.c +++ b/drivers/bluetooth/btmrvl_main.c @@ -187,7 +187,6 @@ static int btmrvl_send_sync_cmd(struct btmrvl_private *priv, u16 cmd_no, bt_cb(skb)->pkt_type = MRVL_VENDOR_PKT; - skb->dev = (void *) priv->btmrvl_dev.hcidev; skb_queue_head(&priv->adapter->tx_queue, skb); priv->btmrvl_dev.sendcmdflag = true; @@ -356,9 +355,8 @@ static void btmrvl_free_adapter(struct btmrvl_private *priv) priv->adapter = NULL; } -static int btmrvl_send_frame(struct sk_buff *skb) +static int btmrvl_send_frame(struct hci_dev *hdev, struct sk_buff *skb) { - struct hci_dev *hdev = (struct hci_dev *) skb->dev; struct btmrvl_private *priv = NULL; BT_DBG("type=%d, len=%d", skb->pkt_type, skb->len); diff --git a/drivers/bluetooth/btsdio.c b/drivers/bluetooth/btsdio.c index 72fe49e60359..b61440aaee65 100644 --- a/drivers/bluetooth/btsdio.c +++ b/drivers/bluetooth/btsdio.c @@ -254,9 +254,8 @@ static int btsdio_flush(struct hci_dev *hdev) return 0; } -static int btsdio_send_frame(struct sk_buff *skb) +static int btsdio_send_frame(struct hci_dev *hdev, struct sk_buff *skb) { - struct hci_dev *hdev = (struct hci_dev *) skb->dev; struct btsdio_data *data = hci_get_drvdata(hdev); BT_DBG("%s", hdev->name); diff --git a/drivers/bluetooth/btuart_cs.c b/drivers/bluetooth/btuart_cs.c index d0b89ecf1c59..f567cd8424c3 100644 --- a/drivers/bluetooth/btuart_cs.c +++ b/drivers/bluetooth/btuart_cs.c @@ -423,10 +423,9 @@ static int btuart_hci_close(struct hci_dev *hdev) } -static int btuart_hci_send_frame(struct sk_buff *skb) +static int btuart_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb) { btuart_info_t *info; - struct hci_dev *hdev = (struct hci_dev *)(skb->dev); if (!hdev) { BT_ERR("Frame for unknown HCI device (hdev=NULL)"); diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index faa429f7d8a1..621069cb3053 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -716,9 +716,8 @@ static int btusb_flush(struct hci_dev *hdev) return 0; } -static int btusb_send_frame(struct sk_buff *skb) +static int btusb_send_frame(struct hci_dev *hdev, struct sk_buff *skb) { - struct hci_dev *hdev = (struct hci_dev *) skb->dev; struct btusb_data *data = hci_get_drvdata(hdev); struct usb_ctrlrequest *dr; struct urb *urb; @@ -730,6 +729,8 @@ static int btusb_send_frame(struct sk_buff *skb) if (!test_bit(HCI_RUNNING, &hdev->flags)) return -EBUSY; + skb->dev = (void *) hdev; + switch (bt_cb(skb)->pkt_type) { case HCI_COMMAND_PKT: urb = usb_alloc_urb(0, GFP_ATOMIC); diff --git a/drivers/bluetooth/btwilink.c b/drivers/bluetooth/btwilink.c index 5e10fb0a7e05..f038dba19e36 100644 --- a/drivers/bluetooth/btwilink.c +++ b/drivers/bluetooth/btwilink.c @@ -251,14 +251,11 @@ static int ti_st_close(struct hci_dev *hdev) return err; } -static int ti_st_send_frame(struct sk_buff *skb) +static int ti_st_send_frame(struct hci_dev *hdev, struct sk_buff *skb) { - struct hci_dev *hdev; struct ti_st *hst; long len; - hdev = (struct hci_dev *)skb->dev; - if (!test_bit(HCI_RUNNING, &hdev->flags)) return -EBUSY; diff --git a/drivers/bluetooth/dtl1_cs.c b/drivers/bluetooth/dtl1_cs.c index 29451413bc04..ad1a2f9dc772 100644 --- a/drivers/bluetooth/dtl1_cs.c +++ b/drivers/bluetooth/dtl1_cs.c @@ -382,10 +382,9 @@ static int dtl1_hci_close(struct hci_dev *hdev) } -static int dtl1_hci_send_frame(struct sk_buff *skb) +static int dtl1_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb) { dtl1_info_t *info; - struct hci_dev *hdev = (struct hci_dev *)(skb->dev); struct sk_buff *s; nsh_t nsh; diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index bc68a440d432..b04054675c48 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c @@ -234,9 +234,8 @@ static int hci_uart_close(struct hci_dev *hdev) } /* Send frames from HCI layer */ -static int hci_uart_send_frame(struct sk_buff *skb) +static int hci_uart_send_frame(struct hci_dev *hdev, struct sk_buff *skb) { - struct hci_dev* hdev = (struct hci_dev *) skb->dev; struct hci_uart *hu; if (!hdev) { diff --git a/drivers/bluetooth/hci_ll.c b/drivers/bluetooth/hci_ll.c index 58a9541feba6..69a90b1b5ff5 100644 --- a/drivers/bluetooth/hci_ll.c +++ b/drivers/bluetooth/hci_ll.c @@ -110,7 +110,6 @@ static int send_hcill_cmd(u8 cmd, struct hci_uart *hu) /* prepare packet */ hcill_packet = (struct hcill_cmd *) skb_put(skb, 1); hcill_packet->cmd = cmd; - skb->dev = (void *) hu->hdev; /* send packet */ skb_queue_tail(&ll->txq, skb); diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c index 0fd522e85a71..e6f591969d95 100644 --- a/drivers/bluetooth/hci_vhci.c +++ b/drivers/bluetooth/hci_vhci.c @@ -81,9 +81,8 @@ static int vhci_flush(struct hci_dev *hdev) return 0; } -static int vhci_send_frame(struct sk_buff *skb) +static int vhci_send_frame(struct hci_dev *hdev, struct sk_buff *skb) { - struct hci_dev* hdev = (struct hci_dev *) skb->dev; struct vhci_data *data; if (!hdev) { diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 29b81476424c..0e01dc257880 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -285,7 +285,7 @@ struct hci_dev { int (*close)(struct hci_dev *hdev); int (*flush)(struct hci_dev *hdev); int (*setup)(struct hci_dev *hdev); - int (*send)(struct sk_buff *skb); + int (*send)(struct hci_dev *hdev, struct sk_buff *skb); void (*notify)(struct hci_dev *hdev, unsigned int evt); }; diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 4f0d4b443171..a097a623912a 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -2713,9 +2713,7 @@ static void hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb) /* Get rid of skb owner, prior to sending to the driver. */ skb_orphan(skb); - skb->dev = (void *) hdev; - - if (hdev->send(skb) < 0) + if (hdev->send(hdev, skb) < 0) BT_ERR("%s sending frame failed", hdev->name); } -- cgit v1.2.3 From bef64738e3fb87eabc6fbeededad0c44ea173384 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 11 Oct 2013 08:23:19 -0700 Subject: Bluetooth: Make LE scan interval and window a controller option The scan interval and window for LE passive scanning and connection establishment should be configurable on a per controller basis. So introduce a setting that later on will allow modifying it. This setting does not affect LE active scanning during device discovery phase. As long as that phase uses interleaved discovery, it will continuously scan. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- include/net/bluetooth/hci_core.h | 2 ++ net/bluetooth/hci_conn.c | 4 ++-- net/bluetooth/hci_core.c | 3 +++ 3 files changed, 7 insertions(+), 2 deletions(-) (limited to 'include/net') diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 0e01dc257880..690045498420 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -164,6 +164,8 @@ struct hci_dev { __u16 page_scan_interval; __u16 page_scan_window; __u8 page_scan_type; + __u16 le_scan_interval; + __u16 le_scan_window; __u16 devid_source; __u16 devid_vendor; diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 139587159200..c52bfb7e44fd 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -562,8 +562,8 @@ static int hci_create_le_conn(struct hci_conn *conn) hci_req_init(&req, hdev); memset(&cp, 0, sizeof(cp)); - cp.scan_interval = __constant_cpu_to_le16(0x0060); - cp.scan_window = __constant_cpu_to_le16(0x0030); + cp.scan_interval = cpu_to_le16(hdev->le_scan_interval); + cp.scan_window = cpu_to_le16(hdev->le_scan_window); bacpy(&cp.peer_addr, &conn->dst); cp.peer_addr_type = conn->dst_type; if (bacmp(&hdev->bdaddr, BDADDR_ANY)) diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index a097a623912a..1910dc2d33cf 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -2273,6 +2273,9 @@ struct hci_dev *hci_alloc_dev(void) hdev->sniff_max_interval = 800; hdev->sniff_min_interval = 80; + hdev->le_scan_interval = 0x0060; + hdev->le_scan_window = 0x0030; + mutex_init(&hdev->lock); mutex_init(&hdev->req_lock); -- cgit v1.2.3 From 14b49b9a49f0d80ef9a3ce7991b373f93016f5e4 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 11 Oct 2013 08:23:20 -0700 Subject: Bluetooth: Add management command for setting LE scan parameters The scan interval and window parameters are used for LE passive background scanning and connection establishment. This allows userspace to change the values. These two values should be kept in sync with whatever is used for the scan parameters service on remote devices. And it puts the controlling daemon (for example bluetoothd) in charge of setting the values. Main use case would be to switch between two sets of values. One for foreground applications and one for background applications. At this moment, the values are only used for manual connection establishment, but soon that should be extended to background scanning and automatic connection establishment. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- include/net/bluetooth/mgmt.h | 7 +++++++ net/bluetooth/mgmt.c | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) (limited to 'include/net') diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h index 2ad433bb9a2e..518c5c84e39a 100644 --- a/include/net/bluetooth/mgmt.h +++ b/include/net/bluetooth/mgmt.h @@ -362,6 +362,13 @@ struct mgmt_cp_set_static_address { } __packed; #define MGMT_SET_STATIC_ADDRESS_SIZE 6 +#define MGMT_OP_SET_SCAN_PARAMS 0x002C +struct mgmt_cp_set_scan_params { + __le16 interval; + __le16 window; +} __packed; +#define MGMT_SET_SCAN_PARAMS_SIZE 4 + #define MGMT_EV_CMD_COMPLETE 0x0001 struct mgmt_ev_cmd_complete { __le16 opcode; diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 143dd7319981..f57ec19547af 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -3374,6 +3374,43 @@ static int set_static_address(struct sock *sk, struct hci_dev *hdev, return err; } +static int set_scan_params(struct sock *sk, struct hci_dev *hdev, + void *data, u16 len) +{ + struct mgmt_cp_set_scan_params *cp = data; + __u16 interval, window; + int err; + + BT_DBG("%s", hdev->name); + + if (!lmp_le_capable(hdev)) + return cmd_status(sk, hdev->id, MGMT_OP_SET_SCAN_PARAMS, + MGMT_STATUS_NOT_SUPPORTED); + + interval = __le16_to_cpu(cp->interval); + + if (interval < 0x0004 || interval > 0x4000) + return cmd_status(sk, hdev->id, MGMT_OP_SET_SCAN_PARAMS, + MGMT_STATUS_INVALID_PARAMS); + + window = __le16_to_cpu(cp->window); + + if (window < 0x0004 || window > 0x4000) + return cmd_status(sk, hdev->id, MGMT_OP_SET_SCAN_PARAMS, + MGMT_STATUS_INVALID_PARAMS); + + hci_dev_lock(hdev); + + hdev->le_scan_interval = interval; + hdev->le_scan_window = window; + + err = cmd_complete(sk, hdev->id, MGMT_OP_SET_SCAN_PARAMS, 0, NULL, 0); + + hci_dev_unlock(hdev); + + return err; +} + static void fast_connectable_complete(struct hci_dev *hdev, u8 status) { struct pending_cmd *cmd; @@ -3710,6 +3747,7 @@ static const struct mgmt_handler { { set_advertising, false, MGMT_SETTING_SIZE }, { set_bredr, false, MGMT_SETTING_SIZE }, { set_static_address, false, MGMT_SET_STATIC_ADDRESS_SIZE }, + { set_scan_params, false, MGMT_SET_SCAN_PARAMS_SIZE }, }; -- cgit v1.2.3 From 3124b84309a0699c98bdc0ef1fc8cd5e058ad5fa Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 12 Oct 2013 07:19:32 -0700 Subject: Bluetooth: Allow 3D profile to use security mode 4 level 0 The PSM 0x0021 is dedicated to the 3D profile and has permission to use security mode 4 level 0 for L2CAP connectionless unicast data transfers. When establishing a L2CAP connectionless channel on PSM 0x0021, it will no longer force Secure Simple Pairing. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- include/net/bluetooth/l2cap.h | 1 + net/bluetooth/l2cap_core.c | 10 ++++++++++ net/bluetooth/l2cap_sock.c | 4 ++++ 3 files changed, 15 insertions(+) (limited to 'include/net') diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index f141b5f6e4f1..12523c79eb3b 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -237,6 +237,7 @@ struct l2cap_conn_rsp { /* protocol/service multiplexer (PSM) */ #define L2CAP_PSM_SDP 0x0001 #define L2CAP_PSM_RFCOMM 0x0003 +#define L2CAP_PSM_3DSP 0x0021 /* channel indentifier */ #define L2CAP_CID_SIGNALING 0x0001 diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index cc51cb860c40..e932ffda5445 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -688,6 +688,16 @@ static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan) return HCI_AT_NO_BONDING; } break; + case L2CAP_CHAN_CONN_LESS: + if (chan->psm == __constant_cpu_to_le16(L2CAP_PSM_3DSP)) { + if (chan->sec_level == BT_SECURITY_LOW) + chan->sec_level = BT_SECURITY_SDP; + } + if (chan->sec_level == BT_SECURITY_HIGH) + return HCI_AT_NO_BONDING_MITM; + else + return HCI_AT_NO_BONDING; + break; case L2CAP_CHAN_CONN_ORIENTED: if (chan->psm == __constant_cpu_to_le16(L2CAP_PSM_SDP)) { if (chan->sec_level == BT_SECURITY_LOW) diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index bee98ebfae4d..bd6fe7fd2737 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -101,6 +101,10 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) goto done; switch (chan->chan_type) { + case L2CAP_CHAN_CONN_LESS: + if (__le16_to_cpu(la.l2_psm) == L2CAP_PSM_3DSP) + chan->sec_level = BT_SECURITY_SDP; + break; case L2CAP_CHAN_CONN_ORIENTED: if (__le16_to_cpu(la.l2_psm) == L2CAP_PSM_SDP || __le16_to_cpu(la.l2_psm) == L2CAP_PSM_RFCOMM) -- cgit v1.2.3 From d40bffbc4e9afce9c0be6ea399b4103f72e50ec2 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 12 Oct 2013 08:18:18 -0700 Subject: Bluetooth: The L2CAP fixed channel connectionless data is supported The implementation actually supports the L2CAP connectionless data channel. So set it as supported in the fixed channels bitmask. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- include/net/bluetooth/l2cap.h | 1 + net/bluetooth/l2cap_core.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'include/net') diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 12523c79eb3b..56f540e7a8fc 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -131,6 +131,7 @@ struct l2cap_conninfo { /* L2CAP fixed channels */ #define L2CAP_FC_L2CAP 0x02 +#define L2CAP_FC_CONNLESS 0x04 #define L2CAP_FC_A2MP 0x08 /* L2CAP Control Field bit masks */ diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index e932ffda5445..8b5437c44c7b 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -44,7 +44,7 @@ bool disable_ertm; static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN; -static u8 l2cap_fixed_chan[8] = { L2CAP_FC_L2CAP, }; +static u8 l2cap_fixed_chan[8] = { L2CAP_FC_L2CAP | L2CAP_FC_CONNLESS, }; static LIST_HEAD(chan_list); static DEFINE_RWLOCK(chan_list_lock); -- cgit v1.2.3 From a4de24d4370d0e7fbfbc47244ceb203e959b23aa Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 13 Oct 2013 02:23:41 -0700 Subject: Bluetooth: Remove l2cap_conn->src and l2cap_conn->dst pointers The l2cap_conn->src and l2cap_conn->dst pointers are no longer in use and so just remove them. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- include/net/bluetooth/l2cap.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'include/net') diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 56f540e7a8fc..1a929afe4f16 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -559,9 +559,6 @@ struct l2cap_conn { struct hci_conn *hcon; struct hci_chan *hchan; - bdaddr_t *dst; - bdaddr_t *src; - unsigned int mtu; __u32 feat_mask; -- cgit v1.2.3 From 79d95a19a445f5758571b3342064f2c1e40b6c5f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 13 Oct 2013 03:57:38 -0700 Subject: Bluetooth: Remove pointless bdaddr_to_le() helper function The bdaddr_to_le() function tries to convert the internal address type to one that matches the HCI address type for LE. It does not handle any address types not used by LE and in the end just make the code a lot harder to read. So instead of just hiding behind a magic function, just convert the internal address type where it needs to be converted. And it turns out that these are only two cases anyway. One when creating new LE connections and the other when loading the long term keys. In both cases this makes it more clear on what it going on. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- include/net/bluetooth/hci_core.h | 2 -- net/bluetooth/hci_conn.c | 5 ++++- net/bluetooth/hci_core.c | 12 ------------ net/bluetooth/mgmt.c | 10 +++++++--- 4 files changed, 11 insertions(+), 18 deletions(-) (limited to 'include/net') diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 690045498420..7889495da843 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -1187,8 +1187,6 @@ void hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max, void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __u8 rand[8], __u8 ltk[16]); -u8 bdaddr_to_le(u8 bdaddr_type); - #define SCO_AIRMODE_MASK 0x0003 #define SCO_AIRMODE_CVSD 0x0000 #define SCO_AIRMODE_TRANSP 0x0003 diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index c52bfb7e44fd..bb32f48b88f9 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -622,7 +622,10 @@ static struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst, if (!conn) return ERR_PTR(-ENOMEM); - conn->dst_type = bdaddr_to_le(dst_type); + if (dst_type == BDADDR_LE_PUBLIC) + conn->dst_type = ADDR_LE_DEV_PUBLIC; + else + conn->dst_type = ADDR_LE_DEV_RANDOM; conn->state = BT_CONNECT; conn->out = true; conn->link_mode |= HCI_LM_MASTER; diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 082f3966f894..0e05edee0962 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -3695,15 +3695,3 @@ static void hci_cmd_work(struct work_struct *work) } } } - -u8 bdaddr_to_le(u8 bdaddr_type) -{ - switch (bdaddr_type) { - case BDADDR_LE_PUBLIC: - return ADDR_LE_DEV_PUBLIC; - - default: - /* Fallback to LE Random address type */ - return ADDR_LE_DEV_RANDOM; - } -} diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 338878c13571..020f95b84b09 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -3678,15 +3678,19 @@ static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev, for (i = 0; i < key_count; i++) { struct mgmt_ltk_info *key = &cp->keys[i]; - u8 type; + u8 type, addr_type; + + if (key->addr.type == BDADDR_LE_PUBLIC) + addr_type = ADDR_LE_DEV_PUBLIC; + else + addr_type = ADDR_LE_DEV_RANDOM; if (key->master) type = HCI_SMP_LTK; else type = HCI_SMP_LTK_SLAVE; - hci_add_ltk(hdev, &key->addr.bdaddr, - bdaddr_to_le(key->addr.type), + hci_add_ltk(hdev, &key->addr.bdaddr, addr_type, type, 0, key->authenticated, key->val, key->enc_size, key->ediv, key->rand); } -- cgit v1.2.3 From e7c4096e16f0e362c6cf902baab0de37ebfc1266 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 13 Oct 2013 03:57:39 -0700 Subject: Bluetooth: Store the source address type of LE connections When establishing LE connections, it is possible to use a public address (if available) or a random address. The type of address is only known when creating connections, so make sure it is stored in hci_conn structure. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- include/net/bluetooth/hci_core.h | 1 + net/bluetooth/hci_conn.c | 11 +++++++---- 2 files changed, 8 insertions(+), 4 deletions(-) (limited to 'include/net') diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 7889495da843..714da9ea465e 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -300,6 +300,7 @@ struct hci_conn { bdaddr_t dst; __u8 dst_type; + __u8 src_type; __u16 handle; __u16 state; __u8 mode; diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index bb32f48b88f9..d9f7f93b813e 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -566,10 +566,7 @@ static int hci_create_le_conn(struct hci_conn *conn) cp.scan_window = cpu_to_le16(hdev->le_scan_window); bacpy(&cp.peer_addr, &conn->dst); cp.peer_addr_type = conn->dst_type; - if (bacmp(&hdev->bdaddr, BDADDR_ANY)) - cp.own_address_type = ADDR_LE_DEV_PUBLIC; - else - cp.own_address_type = ADDR_LE_DEV_RANDOM; + cp.own_address_type = conn->src_type; cp.conn_interval_min = __constant_cpu_to_le16(0x0028); cp.conn_interval_max = __constant_cpu_to_le16(0x0038); cp.supervision_timeout = __constant_cpu_to_le16(0x002a); @@ -626,6 +623,12 @@ static struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst, conn->dst_type = ADDR_LE_DEV_PUBLIC; else conn->dst_type = ADDR_LE_DEV_RANDOM; + + if (bacmp(&hdev->bdaddr, BDADDR_ANY)) + conn->src_type = ADDR_LE_DEV_PUBLIC; + else + conn->src_type = ADDR_LE_DEV_RANDOM; + conn->state = BT_CONNECT; conn->out = true; conn->link_mode |= HCI_LM_MASTER; -- cgit v1.2.3 From 662e8820f38dcc458e0d4769194db5ed3469224f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 13 Oct 2013 05:23:59 -0700 Subject: Bluetooth: Store source address of HCI connections The source addressed was based on the public address of the HCI device, but with LE connections this not always the case. For example single mode LE-only controllers would use a static random address. And this address is configured by userspace. To not complicate the lookup of what kind of address is in use, store the correct source address for each HCI connection. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- include/net/bluetooth/hci_core.h | 1 + net/bluetooth/hci_conn.c | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'include/net') diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 714da9ea465e..0326b160b89a 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -300,6 +300,7 @@ struct hci_conn { bdaddr_t dst; __u8 dst_type; + bdaddr_t src; __u8 src_type; __u16 handle; __u16 state; diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index d9f7f93b813e..ff04b051792d 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -381,6 +381,7 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst) return NULL; bacpy(&conn->dst, dst); + bacpy(&conn->src, &hdev->bdaddr); conn->hdev = hdev; conn->type = type; conn->mode = HCI_CM_ACTIVE; @@ -624,10 +625,12 @@ static struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst, else conn->dst_type = ADDR_LE_DEV_RANDOM; - if (bacmp(&hdev->bdaddr, BDADDR_ANY)) + if (bacmp(&conn->src, BDADDR_ANY)) { conn->src_type = ADDR_LE_DEV_PUBLIC; - else + } else { + bacpy(&conn->src, &hdev->static_addr); conn->src_type = ADDR_LE_DEV_RANDOM; + } conn->state = BT_CONNECT; conn->out = true; -- cgit v1.2.3 From 7eafc59e2f547fce3a31b3e2d03c14d57e9162b2 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 13 Oct 2013 08:12:47 -0700 Subject: Bluetooth: Store address information in L2CAP channel structure With the effort of abstracting the L2CAP socket from the underlying L2CAP channel it is important to store the source and destination address information directly in the L2CAP channel structure. Direct access to the HCI connection address information is not possible since they might not be avaiable at L2CAP channel creation time. The address information will be updated when the underlying BR/EDR or LE connection status changes. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- include/net/bluetooth/l2cap.h | 2 ++ net/bluetooth/l2cap_core.c | 61 +++++++++++++++++-------------------------- net/bluetooth/l2cap_sock.c | 6 ++--- 3 files changed, 29 insertions(+), 40 deletions(-) (limited to 'include/net') diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 1a929afe4f16..26b5066e74e2 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -444,6 +444,8 @@ struct l2cap_chan { __u8 state; + bdaddr_t dst; + bdaddr_t src; __le16 psm; __u16 dcid; __u16 scid; diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 062e28e4722b..be3e0f8c6f8b 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -149,7 +149,7 @@ static struct l2cap_chan *__l2cap_global_chan_by_addr(__le16 psm, bdaddr_t *src) struct l2cap_chan *c; list_for_each_entry(c, &chan_list, global_l) { - if (c->sport == psm && !bacmp(&bt_sk(c->sk)->src, src)) + if (c->sport == psm && !bacmp(&c->src, src)) return c; } return NULL; @@ -621,10 +621,8 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err) void l2cap_chan_close(struct l2cap_chan *chan, int reason) { struct l2cap_conn *conn = chan->conn; - struct sock *sk = chan->sk; - BT_DBG("chan %p state %s sk %p", chan, state_to_string(chan->state), - sk); + BT_DBG("chan %p state %s", chan, state_to_string(chan->state)); switch (chan->state) { case BT_LISTEN: @@ -635,6 +633,7 @@ void l2cap_chan_close(struct l2cap_chan *chan, int reason) case BT_CONFIG: if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && conn->hcon->type == ACL_LINK) { + struct sock *sk = chan->sk; __set_chan_timer(chan, sk->sk_sndtimeo); l2cap_send_disconn_req(chan, reason); } else @@ -644,6 +643,7 @@ void l2cap_chan_close(struct l2cap_chan *chan, int reason) case BT_CONNECT2: if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && conn->hcon->type == ACL_LINK) { + struct sock *sk = chan->sk; struct l2cap_conn_rsp rsp; __u16 result; @@ -1257,8 +1257,6 @@ static void l2cap_conn_start(struct l2cap_conn *conn) mutex_lock(&conn->chan_lock); list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) { - struct sock *sk = chan->sk; - l2cap_chan_lock(chan); if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) { @@ -1284,6 +1282,7 @@ static void l2cap_conn_start(struct l2cap_conn *conn) l2cap_start_connection(chan); } else if (chan->state == BT_CONNECT2) { + struct sock *sk = chan->sk; struct l2cap_conn_rsp rsp; char buf[128]; rsp.scid = cpu_to_le16(chan->dcid); @@ -1341,8 +1340,6 @@ static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid, read_lock(&chan_list_lock); list_for_each_entry(c, &chan_list, global_l) { - struct sock *sk = c->sk; - if (state && c->state != state) continue; @@ -1351,16 +1348,16 @@ static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid, int src_any, dst_any; /* Exact match. */ - src_match = !bacmp(&bt_sk(sk)->src, src); - dst_match = !bacmp(&bt_sk(sk)->dst, dst); + src_match = !bacmp(&c->src, src); + dst_match = !bacmp(&c->dst, dst); if (src_match && dst_match) { read_unlock(&chan_list_lock); return c; } /* Closest match */ - src_any = !bacmp(&bt_sk(sk)->src, BDADDR_ANY); - dst_any = !bacmp(&bt_sk(sk)->dst, BDADDR_ANY); + src_any = !bacmp(&c->src, BDADDR_ANY); + dst_any = !bacmp(&c->dst, BDADDR_ANY); if ((src_match && dst_any) || (src_any && dst_match) || (src_any && dst_any)) c1 = c; @@ -1399,8 +1396,8 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn) chan->dcid = L2CAP_CID_ATT; - bacpy(&bt_sk(chan->sk)->src, &conn->hcon->src); - bacpy(&bt_sk(chan->sk)->dst, &conn->hcon->dst); + bacpy(&chan->src, &conn->hcon->src); + bacpy(&chan->dst, &conn->hcon->dst); __l2cap_chan_add(conn, chan); @@ -1721,8 +1718,6 @@ static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm, read_lock(&chan_list_lock); list_for_each_entry(c, &chan_list, global_l) { - struct sock *sk = c->sk; - if (state && c->state != state) continue; @@ -1731,16 +1726,16 @@ static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm, int src_any, dst_any; /* Exact match. */ - src_match = !bacmp(&bt_sk(sk)->src, src); - dst_match = !bacmp(&bt_sk(sk)->dst, dst); + src_match = !bacmp(&c->src, src); + dst_match = !bacmp(&c->dst, dst); if (src_match && dst_match) { read_unlock(&chan_list_lock); return c; } /* Closest match */ - src_any = !bacmp(&bt_sk(sk)->src, BDADDR_ANY); - dst_any = !bacmp(&bt_sk(sk)->dst, BDADDR_ANY); + src_any = !bacmp(&c->src, BDADDR_ANY); + dst_any = !bacmp(&c->dst, BDADDR_ANY); if ((src_match && dst_any) || (src_any && dst_match) || (src_any && dst_any)) c1 = c; @@ -1762,10 +1757,10 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, __u8 auth_type; int err; - BT_DBG("%pMR -> %pMR (type %u) psm 0x%2.2x", &bt_sk(sk)->src, dst, + BT_DBG("%pMR -> %pMR (type %u) psm 0x%2.2x", &chan->src, dst, dst_type, __le16_to_cpu(psm)); - hdev = hci_get_route(dst, &bt_sk(sk)->src); + hdev = hci_get_route(dst, &chan->src); if (!hdev) return -EHOSTUNREACH; @@ -1822,9 +1817,7 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, } /* Set destination address and psm */ - lock_sock(sk); - bacpy(&bt_sk(sk)->dst, dst); - release_sock(sk); + bacpy(&chan->dst, dst); chan->psm = psm; chan->dcid = cid; @@ -1857,9 +1850,7 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, } /* Update source addr of the socket */ - lock_sock(sk); - bacpy(&bt_sk(sk)->src, &hcon->src); - release_sock(sk); + bacpy(&chan->src, &hcon->src); l2cap_chan_unlock(chan); l2cap_chan_add(conn, chan); @@ -3798,8 +3789,8 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn, */ conn->hcon->disc_timeout = HCI_DISCONN_TIMEOUT; - bacpy(&bt_sk(sk)->src, &conn->hcon->src); - bacpy(&bt_sk(sk)->dst, &conn->hcon->dst); + bacpy(&chan->src, &conn->hcon->src); + bacpy(&chan->dst, &conn->hcon->dst); chan->psm = psm; chan->dcid = scid; chan->local_amp_id = amp_id; @@ -6542,17 +6533,15 @@ int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr) /* Find listening sockets and check their link_mode */ read_lock(&chan_list_lock); list_for_each_entry(c, &chan_list, global_l) { - struct sock *sk = c->sk; - if (c->state != BT_LISTEN) continue; - if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) { + if (!bacmp(&c->src, &hdev->bdaddr)) { lm1 |= HCI_LM_ACCEPT; if (test_bit(FLAG_ROLE_SWITCH, &c->flags)) lm1 |= HCI_LM_MASTER; exact++; - } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) { + } else if (!bacmp(&c->src, BDADDR_ANY)) { lm2 |= HCI_LM_ACCEPT; if (test_bit(FLAG_ROLE_SWITCH, &c->flags)) lm2 |= HCI_LM_MASTER; @@ -6840,10 +6829,8 @@ static int l2cap_debugfs_show(struct seq_file *f, void *p) read_lock(&chan_list_lock); list_for_each_entry(c, &chan_list, global_l) { - struct sock *sk = c->sk; - seq_printf(f, "%pMR %pMR %d %d 0x%4.4x 0x%4.4x %d %d %d %d\n", - &bt_sk(sk)->src, &bt_sk(sk)->dst, + &c->src, &c->dst, c->state, __le16_to_cpu(c->psm), c->scid, c->dcid, c->imtu, c->omtu, c->sec_level, c->mode); diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index bd6fe7fd2737..9fe80d228c19 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -112,7 +112,7 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) break; } - bacpy(&bt_sk(sk)->src, &la.l2_bdaddr); + bacpy(&chan->src, &la.l2_bdaddr); chan->state = BT_BOUND; sk->sk_state = BT_BOUND; @@ -274,11 +274,11 @@ static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, if (peer) { la->l2_psm = chan->psm; - bacpy(&la->l2_bdaddr, &bt_sk(sk)->dst); + bacpy(&la->l2_bdaddr, &chan->dst); la->l2_cid = cpu_to_le16(chan->dcid); } else { la->l2_psm = chan->sport; - bacpy(&la->l2_bdaddr, &bt_sk(sk)->src); + bacpy(&la->l2_bdaddr, &chan->src); la->l2_cid = cpu_to_le16(chan->scid); } -- cgit v1.2.3 From 4f1654e08464abad06487e173661cb73721d27a7 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 13 Oct 2013 08:50:41 -0700 Subject: Bluetooth: Return the correct address type for L2CAP sockets The L2CAP sockets can use BR/EDR public, LE public and LE random addresses for various combinations of source and destination devices. So make sure that getsockname(), getpeername() and accept() return the correct address type. For this the address type of the source and destination is stored with the L2CAP channel information. The stored address type is not the one specific for the HCI protocol. It is the address type used for the L2CAP sockets and the management interface. The underlying HCI connections store the HCI address type. If needed, it gets converted to the socket address type. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- include/net/bluetooth/l2cap.h | 5 +++-- net/bluetooth/l2cap_core.c | 18 ++++++++++++++++++ net/bluetooth/l2cap_sock.c | 3 +++ 3 files changed, 24 insertions(+), 2 deletions(-) (limited to 'include/net') diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 26b5066e74e2..a27d51dc39a4 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -445,8 +445,11 @@ struct l2cap_chan { __u8 state; bdaddr_t dst; + __u8 dst_type; bdaddr_t src; + __u8 src_type; __le16 psm; + __le16 sport; __u16 dcid; __u16 scid; @@ -457,8 +460,6 @@ struct l2cap_chan { __u8 chan_type; __u8 chan_policy; - __le16 sport; - __u8 sec_level; __u8 ident; diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index be3e0f8c6f8b..769c379b3eeb 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -59,6 +59,18 @@ static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err); static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control, struct sk_buff_head *skbs, u8 event); +static inline __u8 bdaddr_type(struct hci_conn *hcon, __u8 type) +{ + if (hcon->type == LE_LINK) { + if (type == ADDR_LE_DEV_PUBLIC) + return BDADDR_LE_PUBLIC; + else + return BDADDR_LE_RANDOM; + } + + return BDADDR_BREDR; +} + /* ---- L2CAP channels ---- */ static struct l2cap_chan *__l2cap_get_chan_by_dcid(struct l2cap_conn *conn, @@ -1398,6 +1410,8 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn) bacpy(&chan->src, &conn->hcon->src); bacpy(&chan->dst, &conn->hcon->dst); + chan->src_type = bdaddr_type(conn->hcon, conn->hcon->src_type); + chan->dst_type = bdaddr_type(conn->hcon, conn->hcon->dst_type); __l2cap_chan_add(conn, chan); @@ -1818,6 +1832,7 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, /* Set destination address and psm */ bacpy(&chan->dst, dst); + chan->dst_type = dst_type; chan->psm = psm; chan->dcid = cid; @@ -1851,6 +1866,7 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, /* Update source addr of the socket */ bacpy(&chan->src, &hcon->src); + chan->src_type = bdaddr_type(hcon, hcon->src_type); l2cap_chan_unlock(chan); l2cap_chan_add(conn, chan); @@ -3791,6 +3807,8 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn, bacpy(&chan->src, &conn->hcon->src); bacpy(&chan->dst, &conn->hcon->dst); + chan->src_type = bdaddr_type(conn->hcon, conn->hcon->src_type); + chan->dst_type = bdaddr_type(conn->hcon, conn->hcon->dst_type); chan->psm = psm; chan->dcid = scid; chan->local_amp_id = amp_id; diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 9fe80d228c19..6262e23b71a4 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -113,6 +113,7 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) } bacpy(&chan->src, &la.l2_bdaddr); + chan->src_type = la.l2_bdaddr_type; chan->state = BT_BOUND; sk->sk_state = BT_BOUND; @@ -276,10 +277,12 @@ static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, la->l2_psm = chan->psm; bacpy(&la->l2_bdaddr, &chan->dst); la->l2_cid = cpu_to_le16(chan->dcid); + la->l2_bdaddr_type = chan->dst_type; } else { la->l2_psm = chan->sport; bacpy(&la->l2_bdaddr, &chan->src); la->l2_cid = cpu_to_le16(chan->scid); + la->l2_bdaddr_type = chan->src_type; } return 0; -- cgit v1.2.3 From 041987cff6fb7d2e7acd5897390ad0eef575ed39 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 13 Oct 2013 10:15:22 -0700 Subject: Bluetooth: Use SCO addresses from HCI connection directly Instead of storing a pointer to the addresses for the HCI device and HCI connection, use them directly. With the recent changes to address tracking of HCI connections, this becomes simple. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- include/net/bluetooth/sco.h | 3 --- net/bluetooth/sco.c | 20 ++++++++------------ 2 files changed, 8 insertions(+), 15 deletions(-) (limited to 'include/net') diff --git a/include/net/bluetooth/sco.h b/include/net/bluetooth/sco.h index e252a31ee6b6..94703a25d1c2 100644 --- a/include/net/bluetooth/sco.h +++ b/include/net/bluetooth/sco.h @@ -55,9 +55,6 @@ struct sco_conninfo { struct sco_conn { struct hci_conn *hcon; - bdaddr_t *dst; - bdaddr_t *src; - spinlock_t lock; struct sock *sk; diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index 96bd388d93a4..2cc8f425613a 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c @@ -92,9 +92,6 @@ static struct sco_conn *sco_conn_add(struct hci_conn *hcon) hcon->sco_data = conn; conn->hcon = hcon; - conn->src = &hdev->bdaddr; - conn->dst = &hcon->dst; - if (hdev->sco_mtu > 0) conn->mtu = hdev->sco_mtu; else @@ -156,16 +153,14 @@ static int sco_chan_add(struct sco_conn *conn, struct sock *sk, static int sco_connect(struct sock *sk) { - bdaddr_t *src = &bt_sk(sk)->src; - bdaddr_t *dst = &bt_sk(sk)->dst; struct sco_conn *conn; struct hci_conn *hcon; struct hci_dev *hdev; int err, type; - BT_DBG("%pMR -> %pMR", src, dst); + BT_DBG("%pMR -> %pMR", &bt_sk(sk)->src, &bt_sk(sk)->dst); - hdev = hci_get_route(dst, src); + hdev = hci_get_route(&bt_sk(sk)->dst, &bt_sk(sk)->src); if (!hdev) return -EHOSTUNREACH; @@ -182,7 +177,8 @@ static int sco_connect(struct sock *sk) goto done; } - hcon = hci_connect_sco(hdev, type, dst, sco_pi(sk)->setting); + hcon = hci_connect_sco(hdev, type, &bt_sk(sk)->dst, + sco_pi(sk)->setting); if (IS_ERR(hcon)) { err = PTR_ERR(hcon); goto done; @@ -196,7 +192,7 @@ static int sco_connect(struct sock *sk) } /* Update source addr of the socket */ - bacpy(src, conn->src); + bacpy(&bt_sk(sk)->src, &hcon->src); err = sco_chan_add(conn, sk, NULL); if (err) @@ -999,7 +995,7 @@ static void sco_conn_ready(struct sco_conn *conn) } else { sco_conn_lock(conn); - parent = sco_get_sock_listen(conn->src); + parent = sco_get_sock_listen(&conn->hcon->src); if (!parent) { sco_conn_unlock(conn); return; @@ -1017,8 +1013,8 @@ static void sco_conn_ready(struct sco_conn *conn) sco_sock_init(sk, parent); - bacpy(&bt_sk(sk)->src, conn->src); - bacpy(&bt_sk(sk)->dst, conn->dst); + bacpy(&bt_sk(sk)->src, &conn->hcon->src); + bacpy(&bt_sk(sk)->dst, &conn->hcon->dst); hci_conn_hold(conn->hcon); __sco_chan_add(conn, sk, parent); -- cgit v1.2.3 From eea963641bf548bda164b92aa20ccda56c5cf349 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 13 Oct 2013 10:34:01 -0700 Subject: Bluetooth: Store SCO address information in its own socket structure The address information of SCO sockets should be stored in its own socket structure. Trying to generalize them is not helpful since different transports have different address types. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- include/net/bluetooth/sco.h | 2 ++ net/bluetooth/sco.c | 36 ++++++++++++++++++------------------ 2 files changed, 20 insertions(+), 18 deletions(-) (limited to 'include/net') diff --git a/include/net/bluetooth/sco.h b/include/net/bluetooth/sco.h index 94703a25d1c2..2019d1a0996a 100644 --- a/include/net/bluetooth/sco.h +++ b/include/net/bluetooth/sco.h @@ -69,6 +69,8 @@ struct sco_conn { struct sco_pinfo { struct bt_sock bt; + bdaddr_t src; + bdaddr_t dst; __u32 flags; __u16 setting; struct sco_conn *conn; diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index 2cc8f425613a..a92aebac56ca 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c @@ -158,9 +158,9 @@ static int sco_connect(struct sock *sk) struct hci_dev *hdev; int err, type; - BT_DBG("%pMR -> %pMR", &bt_sk(sk)->src, &bt_sk(sk)->dst); + BT_DBG("%pMR -> %pMR", &sco_pi(sk)->src, &sco_pi(sk)->dst); - hdev = hci_get_route(&bt_sk(sk)->dst, &bt_sk(sk)->src); + hdev = hci_get_route(&sco_pi(sk)->dst, &sco_pi(sk)->src); if (!hdev) return -EHOSTUNREACH; @@ -177,7 +177,7 @@ static int sco_connect(struct sock *sk) goto done; } - hcon = hci_connect_sco(hdev, type, &bt_sk(sk)->dst, + hcon = hci_connect_sco(hdev, type, &sco_pi(sk)->dst, sco_pi(sk)->setting); if (IS_ERR(hcon)) { err = PTR_ERR(hcon); @@ -192,7 +192,7 @@ static int sco_connect(struct sock *sk) } /* Update source addr of the socket */ - bacpy(&bt_sk(sk)->src, &hcon->src); + bacpy(&sco_pi(sk)->src, &hcon->src); err = sco_chan_add(conn, sk, NULL); if (err) @@ -266,7 +266,7 @@ static struct sock *__sco_get_sock_listen_by_addr(bdaddr_t *ba) if (sk->sk_state != BT_LISTEN) continue; - if (!bacmp(&bt_sk(sk)->src, ba)) + if (!bacmp(&sco_pi(sk)->src, ba)) return sk; } @@ -287,11 +287,11 @@ static struct sock *sco_get_sock_listen(bdaddr_t *src) continue; /* Exact match. */ - if (!bacmp(&bt_sk(sk)->src, src)) + if (!bacmp(&sco_pi(sk)->src, src)) break; /* Closest match */ - if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) + if (!bacmp(&sco_pi(sk)->src, BDADDR_ANY)) sk1 = sk; } @@ -471,7 +471,7 @@ static int sco_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_le goto done; } - bacpy(&bt_sk(sk)->src, &sa->sco_bdaddr); + bacpy(&sco_pi(sk)->src, &sa->sco_bdaddr); sk->sk_state = BT_BOUND; @@ -501,7 +501,7 @@ static int sco_sock_connect(struct socket *sock, struct sockaddr *addr, int alen lock_sock(sk); /* Set destination address and psm */ - bacpy(&bt_sk(sk)->dst, &sa->sco_bdaddr); + bacpy(&sco_pi(sk)->dst, &sa->sco_bdaddr); err = sco_connect(sk); if (err) @@ -518,7 +518,7 @@ done: static int sco_sock_listen(struct socket *sock, int backlog) { struct sock *sk = sock->sk; - bdaddr_t *src = &bt_sk(sk)->src; + bdaddr_t *src = &sco_pi(sk)->src; int err = 0; BT_DBG("sk %p backlog %d", sk, backlog); @@ -622,9 +622,9 @@ static int sco_sock_getname(struct socket *sock, struct sockaddr *addr, int *len *len = sizeof(struct sockaddr_sco); if (peer) - bacpy(&sa->sco_bdaddr, &bt_sk(sk)->dst); + bacpy(&sa->sco_bdaddr, &sco_pi(sk)->dst); else - bacpy(&sa->sco_bdaddr, &bt_sk(sk)->src); + bacpy(&sa->sco_bdaddr, &sco_pi(sk)->src); return 0; } @@ -1013,8 +1013,8 @@ static void sco_conn_ready(struct sco_conn *conn) sco_sock_init(sk, parent); - bacpy(&bt_sk(sk)->src, &conn->hcon->src); - bacpy(&bt_sk(sk)->dst, &conn->hcon->dst); + bacpy(&sco_pi(sk)->src, &conn->hcon->src); + bacpy(&sco_pi(sk)->dst, &conn->hcon->dst); hci_conn_hold(conn->hcon); __sco_chan_add(conn, sk, parent); @@ -1047,8 +1047,8 @@ int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags) if (sk->sk_state != BT_LISTEN) continue; - if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr) || - !bacmp(&bt_sk(sk)->src, BDADDR_ANY)) { + if (!bacmp(&sco_pi(sk)->src, &hdev->bdaddr) || + !bacmp(&sco_pi(sk)->src, BDADDR_ANY)) { lm |= HCI_LM_ACCEPT; if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) @@ -1107,8 +1107,8 @@ static int sco_debugfs_show(struct seq_file *f, void *p) read_lock(&sco_sk_list.lock); sk_for_each(sk, &sco_sk_list.head) { - seq_printf(f, "%pMR %pMR %d\n", &bt_sk(sk)->src, - &bt_sk(sk)->dst, sk->sk_state); + seq_printf(f, "%pMR %pMR %d\n", &sco_pi(sk)->src, + &sco_pi(sk)->dst, sk->sk_state); } read_unlock(&sco_sk_list.lock); -- cgit v1.2.3 From 94a86df01082557e2de45865e538d7fb6c46231c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 13 Oct 2013 10:34:02 -0700 Subject: Bluetooth: Store RFCOMM address information in its own socket structure The address information of RFCOMM sockets should be stored in its own socket structure. Trying to generalize them is not helpful since different transports have different address types. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- include/net/bluetooth/rfcomm.h | 2 ++ net/bluetooth/rfcomm/sock.c | 28 +++++++++++++++------------- 2 files changed, 17 insertions(+), 13 deletions(-) (limited to 'include/net') diff --git a/include/net/bluetooth/rfcomm.h b/include/net/bluetooth/rfcomm.h index 7afd4199d6b6..3588f48bfd35 100644 --- a/include/net/bluetooth/rfcomm.h +++ b/include/net/bluetooth/rfcomm.h @@ -300,6 +300,8 @@ struct rfcomm_conninfo { struct rfcomm_pinfo { struct bt_sock bt; + bdaddr_t src; + bdaddr_t dst; struct rfcomm_dlc *dlc; u8 channel; u8 sec_level; diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index 072938dc527d..df17276eb32b 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c @@ -87,7 +87,8 @@ static void rfcomm_sk_state_change(struct rfcomm_dlc *d, int err) parent->sk_data_ready(parent, 0); } else { if (d->state == BT_CONNECTED) - rfcomm_session_getaddr(d->session, &bt_sk(sk)->src, NULL); + rfcomm_session_getaddr(d->session, + &rfcomm_pi(sk)->src, NULL); sk->sk_state_change(sk); } @@ -110,7 +111,7 @@ static struct sock *__rfcomm_get_sock_by_addr(u8 channel, bdaddr_t *src) sk_for_each(sk, &rfcomm_sk_list.head) { if (rfcomm_pi(sk)->channel == channel && - !bacmp(&bt_sk(sk)->src, src)) + !bacmp(&rfcomm_pi(sk)->src, src)) break; } @@ -132,11 +133,11 @@ static struct sock *rfcomm_get_sock_by_channel(int state, u8 channel, bdaddr_t * if (rfcomm_pi(sk)->channel == channel) { /* Exact match. */ - if (!bacmp(&bt_sk(sk)->src, src)) + if (!bacmp(&rfcomm_pi(sk)->src, src)) break; /* Closest match */ - if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) + if (!bacmp(&rfcomm_pi(sk)->src, BDADDR_ANY)) sk1 = sk; } } @@ -355,7 +356,7 @@ static int rfcomm_sock_bind(struct socket *sock, struct sockaddr *addr, int addr err = -EADDRINUSE; } else { /* Save source address */ - bacpy(&bt_sk(sk)->src, &sa->rc_bdaddr); + bacpy(&rfcomm_pi(sk)->src, &sa->rc_bdaddr); rfcomm_pi(sk)->channel = sa->rc_channel; sk->sk_state = BT_BOUND; } @@ -393,13 +394,14 @@ static int rfcomm_sock_connect(struct socket *sock, struct sockaddr *addr, int a } sk->sk_state = BT_CONNECT; - bacpy(&bt_sk(sk)->dst, &sa->rc_bdaddr); + bacpy(&rfcomm_pi(sk)->dst, &sa->rc_bdaddr); rfcomm_pi(sk)->channel = sa->rc_channel; d->sec_level = rfcomm_pi(sk)->sec_level; d->role_switch = rfcomm_pi(sk)->role_switch; - err = rfcomm_dlc_open(d, &bt_sk(sk)->src, &sa->rc_bdaddr, sa->rc_channel); + err = rfcomm_dlc_open(d, &rfcomm_pi(sk)->src, &sa->rc_bdaddr, + sa->rc_channel); if (!err) err = bt_sock_wait_state(sk, BT_CONNECTED, sock_sndtimeo(sk, flags & O_NONBLOCK)); @@ -429,7 +431,7 @@ static int rfcomm_sock_listen(struct socket *sock, int backlog) } if (!rfcomm_pi(sk)->channel) { - bdaddr_t *src = &bt_sk(sk)->src; + bdaddr_t *src = &rfcomm_pi(sk)->src; u8 channel; err = -EINVAL; @@ -530,9 +532,9 @@ static int rfcomm_sock_getname(struct socket *sock, struct sockaddr *addr, int * sa->rc_family = AF_BLUETOOTH; sa->rc_channel = rfcomm_pi(sk)->channel; if (peer) - bacpy(&sa->rc_bdaddr, &bt_sk(sk)->dst); + bacpy(&sa->rc_bdaddr, &rfcomm_pi(sk)->dst); else - bacpy(&sa->rc_bdaddr, &bt_sk(sk)->src); + bacpy(&sa->rc_bdaddr, &rfcomm_pi(sk)->src); *len = sizeof(struct sockaddr_rc); return 0; @@ -951,8 +953,8 @@ int rfcomm_connect_ind(struct rfcomm_session *s, u8 channel, struct rfcomm_dlc * bt_sock_reclassify_lock(sk, BTPROTO_RFCOMM); rfcomm_sock_init(sk, parent); - bacpy(&bt_sk(sk)->src, &src); - bacpy(&bt_sk(sk)->dst, &dst); + bacpy(&rfcomm_pi(sk)->src, &src); + bacpy(&rfcomm_pi(sk)->dst, &dst); rfcomm_pi(sk)->channel = channel; sk->sk_state = BT_CONFIG; @@ -979,7 +981,7 @@ static int rfcomm_sock_debugfs_show(struct seq_file *f, void *p) sk_for_each(sk, &rfcomm_sk_list.head) { seq_printf(f, "%pMR %pMR %d %d\n", - &bt_sk(sk)->src, &bt_sk(sk)->dst, + &rfcomm_pi(sk)->src, &rfcomm_pi(sk)->dst, sk->sk_state, rfcomm_pi(sk)->channel); } -- cgit v1.2.3 From 5f6cd79f477743cab98fd49feb03a39e0138b32f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 13 Oct 2013 10:34:03 -0700 Subject: Bluetooth: Remove src and dst fields from bt_sock structure Every socket protocol now stores its own address information. So just remove the generic src and dst fields since they are no longer needed. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- include/net/bluetooth/bluetooth.h | 2 -- net/bluetooth/af_bluetooth.c | 4 +--- 2 files changed, 1 insertion(+), 5 deletions(-) (limited to 'include/net') diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h index 5fd510675cfa..1d6e484e08ef 100644 --- a/include/net/bluetooth/bluetooth.h +++ b/include/net/bluetooth/bluetooth.h @@ -218,8 +218,6 @@ void baswap(bdaddr_t *dst, bdaddr_t *src); struct bt_sock { struct sock sk; - bdaddr_t src; - bdaddr_t dst; struct list_head accept_q; struct sock *parent; unsigned long flags; diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c index e6e1278dca89..9c7e4edc6504 100644 --- a/net/bluetooth/af_bluetooth.c +++ b/net/bluetooth/af_bluetooth.c @@ -617,15 +617,13 @@ static int bt_seq_show(struct seq_file *seq, void *v) struct bt_sock *bt = bt_sk(sk); seq_printf(seq, - "%pK %-6d %-6u %-6u %-6u %-6lu %pMR %pMR %-6lu", + "%pK %-6d %-6u %-6u %-6u %-6lu %-6lu", sk, atomic_read(&sk->sk_refcnt), sk_rmem_alloc_get(sk), sk_wmem_alloc_get(sk), from_kuid(seq_user_ns(seq), sock_i_uid(sk)), sock_i_ino(sk), - &bt->src, - &bt->dst, bt->parent? sock_i_ino(bt->parent): 0LU); if (l->custom_seq_show) { -- cgit v1.2.3 From d97636980f6ba7344c8aa6fa349b9059c60ee478 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 13 Oct 2013 12:55:28 -0700 Subject: Bluetooth: Add support for per socket msg_name callback This allows to add a per socket msg_name callback that can be used for updating the msg_name information for recvmsg() system calls. This feature is used by another patch to support address information on L2CAP connectionless channels. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- include/net/bluetooth/bluetooth.h | 1 + net/bluetooth/af_bluetooth.c | 15 +++++++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) (limited to 'include/net') diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h index 1d6e484e08ef..896aad80bc4d 100644 --- a/include/net/bluetooth/bluetooth.h +++ b/include/net/bluetooth/bluetooth.h @@ -221,6 +221,7 @@ struct bt_sock { struct list_head accept_q; struct sock *parent; unsigned long flags; + void (*skb_msg_name)(struct sk_buff *, void *, int *); }; enum { diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c index 9c7e4edc6504..f0aadeac4455 100644 --- a/net/bluetooth/af_bluetooth.c +++ b/net/bluetooth/af_bluetooth.c @@ -221,12 +221,12 @@ int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock, if (flags & (MSG_OOB)) return -EOPNOTSUPP; - msg->msg_namelen = 0; - skb = skb_recv_datagram(sk, flags, noblock, &err); if (!skb) { - if (sk->sk_shutdown & RCV_SHUTDOWN) + if (sk->sk_shutdown & RCV_SHUTDOWN) { + msg->msg_namelen = 0; return 0; + } return err; } @@ -238,9 +238,16 @@ int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock, skb_reset_transport_header(skb); err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied); - if (err == 0) + if (err == 0) { sock_recv_ts_and_drops(msg, sk, skb); + if (bt_sk(sk)->skb_msg_name) + bt_sk(sk)->skb_msg_name(skb, msg->msg_name, + &msg->msg_namelen); + else + msg->msg_namelen = 0; + } + skb_free_datagram(sk, skb); return err ? : copied; -- cgit v1.2.3 From 2edf870d198adeb43d5a2a5ddfa7e3cea4fc999b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 13 Oct 2013 12:55:29 -0700 Subject: Bluetooth: Provide msg_name callback for L2CAP connectionless channels The L2CAP connectionless channels use SOCK_DGRAM and recvmsg() and need to receive the remote BD_ADDR and PSM information via msg_name from the recvmsg() system call. So in case the L2CAP socket is for connectionless channels, provide a msg_name callback that can update the data. Also store the remote BD_ADDR and PSM in the skb so it can be extracted later on. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- include/net/bluetooth/bluetooth.h | 2 ++ net/bluetooth/l2cap_core.c | 4 ++++ net/bluetooth/l2cap_sock.c | 15 ++++++++++++++- 3 files changed, 20 insertions(+), 1 deletion(-) (limited to 'include/net') diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h index 896aad80bc4d..bf2ddffdae2d 100644 --- a/include/net/bluetooth/bluetooth.h +++ b/include/net/bluetooth/bluetooth.h @@ -284,6 +284,8 @@ struct bt_skb_cb { __u8 force_active; struct l2cap_ctrl control; struct hci_req_ctrl req; + bdaddr_t bdaddr; + __le16 psm; }; #define bt_cb(skb) ((struct bt_skb_cb *)((skb)->cb)) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 769c379b3eeb..f6b5f94cbf39 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -6459,6 +6459,10 @@ static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, if (chan->imtu < skb->len) goto drop; + /* Store remote BD_ADDR and PSM for msg_name */ + bacpy(&bt_cb(skb)->bdaddr, &conn->hcon->dst); + bt_cb(skb)->psm = psm; + if (!chan->ops->recv(chan, skb)) return; diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 8fe9f497c645..f1b462faf649 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -1137,6 +1137,19 @@ static void l2cap_sock_destruct(struct sock *sk) skb_queue_purge(&sk->sk_write_queue); } +static void l2cap_skb_msg_name(struct sk_buff *skb, void *msg_name, + int *msg_namelen) +{ + struct sockaddr_l2 *la = (struct sockaddr_l2 *) msg_name; + + memset(la, 0, sizeof(struct sockaddr_l2)); + la->l2_family = AF_BLUETOOTH; + la->l2_psm = bt_cb(skb)->psm; + bacpy(&la->l2_bdaddr, &bt_cb(skb)->bdaddr); + + *msg_namelen = sizeof(struct sockaddr_l2); +} + static void l2cap_sock_init(struct sock *sk, struct sock *parent) { struct l2cap_chan *chan = l2cap_pi(sk)->chan; @@ -1163,13 +1176,13 @@ static void l2cap_sock_init(struct sock *sk, struct sock *parent) security_sk_clone(parent, sk); } else { - switch (sk->sk_type) { case SOCK_RAW: chan->chan_type = L2CAP_CHAN_RAW; break; case SOCK_DGRAM: chan->chan_type = L2CAP_CHAN_CONN_LESS; + bt_sk(sk)->skb_msg_name = l2cap_skb_msg_name; break; case SOCK_SEQPACKET: case SOCK_STREAM: -- cgit v1.2.3 From bdc257830760a784370ae4ab2d682b252b983e77 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 14 Oct 2013 02:45:34 -0700 Subject: Bluetooth: Introduce L2CAP channel flag for defer setup The L2CAP core should not look into the socket flags to figure out the setting of defer setup. So introduce a L2CAP channel flag that mirrors the socket flag. Since the defer setup option is only set in one place this becomes a really easy thing to do. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- include/net/bluetooth/l2cap.h | 1 + net/bluetooth/l2cap_core.c | 15 +++++++-------- net/bluetooth/l2cap_sock.c | 7 +++++-- 3 files changed, 13 insertions(+), 10 deletions(-) (limited to 'include/net') diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index a27d51dc39a4..1a38edee38e4 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -652,6 +652,7 @@ enum { FLAG_FLUSHABLE, FLAG_EXT_CTRL, FLAG_EFS_ENABLE, + FLAG_DEFER_SETUP, }; enum { diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index f6b5f94cbf39..e5819cb67372 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -655,14 +655,14 @@ void l2cap_chan_close(struct l2cap_chan *chan, int reason) case BT_CONNECT2: if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && conn->hcon->type == ACL_LINK) { - struct sock *sk = chan->sk; struct l2cap_conn_rsp rsp; __u16 result; - if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) + if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) result = L2CAP_CR_SEC_BLOCK; else result = L2CAP_CR_BAD_PSM; + l2cap_state_change(chan, BT_DISCONN); rsp.scid = cpu_to_le16(chan->dcid); @@ -1294,16 +1294,16 @@ static void l2cap_conn_start(struct l2cap_conn *conn) l2cap_start_connection(chan); } else if (chan->state == BT_CONNECT2) { - struct sock *sk = chan->sk; struct l2cap_conn_rsp rsp; char buf[128]; rsp.scid = cpu_to_le16(chan->dcid); rsp.dcid = cpu_to_le16(chan->scid); if (l2cap_chan_check_security(chan)) { + struct sock *sk = chan->sk; + lock_sock(sk); - if (test_bit(BT_SK_DEFER_SETUP, - &bt_sk(sk)->flags)) { + if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) { rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND); rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHOR_PEND); chan->ops->defer(chan); @@ -3823,7 +3823,7 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn, if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) { if (l2cap_chan_check_security(chan)) { - if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) { + if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) { __l2cap_state_change(chan, BT_CONNECT2); result = L2CAP_CR_PEND; status = L2CAP_CS_AUTHOR_PEND; @@ -6693,8 +6693,7 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) lock_sock(sk); if (!status) { - if (test_bit(BT_SK_DEFER_SETUP, - &bt_sk(sk)->flags)) { + if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) { res = L2CAP_CR_PEND; stat = L2CAP_CS_AUTHOR_PEND; chan->ops->defer(chan); diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index f1b462faf649..f5d957328545 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -672,10 +672,13 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, break; } - if (opt) + if (opt) { set_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags); - else + set_bit(FLAG_DEFER_SETUP, &chan->flags); + } else { clear_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags); + clear_bit(FLAG_DEFER_SETUP, &chan->flags); + } break; case BT_FLUSHABLE: -- cgit v1.2.3 From d97c899bde330cd1c76c3a162558177563a74362 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 14 Oct 2013 02:53:54 -0700 Subject: Bluetooth: Introduce L2CAP channel callback for resuming Clearing the BT_SK_SUSPEND socket flag from the L2CAP core is causing a dependency on the socket. So intead of doing that, use a channel callback into the socket handling to resume. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- include/net/bluetooth/l2cap.h | 1 + net/bluetooth/l2cap_core.c | 6 +----- net/bluetooth/l2cap_sock.c | 9 +++++++++ 3 files changed, 11 insertions(+), 5 deletions(-) (limited to 'include/net') diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 1a38edee38e4..07757a2af942 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -554,6 +554,7 @@ struct l2cap_ops { int state); void (*ready) (struct l2cap_chan *chan); void (*defer) (struct l2cap_chan *chan); + void (*resume) (struct l2cap_chan *chan); struct sk_buff *(*alloc_skb) (struct l2cap_chan *chan, unsigned long len, int nb); }; diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index e5819cb67372..0c3446da1ec9 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -6669,11 +6669,7 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) if (!status && (chan->state == BT_CONNECTED || chan->state == BT_CONFIG)) { - struct sock *sk = chan->sk; - - clear_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags); - sk->sk_state_change(sk); - + chan->ops->resume(chan); l2cap_check_encryption(chan, encrypt); l2cap_chan_unlock(chan); continue; diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index f5d957328545..fcf012a422fd 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -1112,6 +1112,14 @@ static void l2cap_sock_defer_cb(struct l2cap_chan *chan) parent->sk_data_ready(parent, 0); } +static void l2cap_sock_resume_cb(struct l2cap_chan *chan) +{ + struct sock *sk = chan->data; + + clear_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags); + sk->sk_state_change(sk); +} + static struct l2cap_ops l2cap_chan_ops = { .name = "L2CAP Socket Interface", .new_connection = l2cap_sock_new_connection_cb, @@ -1121,6 +1129,7 @@ static struct l2cap_ops l2cap_chan_ops = { .state_change = l2cap_sock_state_change_cb, .ready = l2cap_sock_ready_cb, .defer = l2cap_sock_defer_cb, + .resume = l2cap_sock_resume_cb, .alloc_skb = l2cap_sock_alloc_skb_cb, }; -- cgit v1.2.3 From b4cb9fb25e9eae749f456e9e94446650389e736b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 14 Oct 2013 13:56:16 -0700 Subject: Bluetooth: Read number of supported IAC on controller setup When initializing a controller make sure to read out the number of supported IAC and store its result. This value is needed to determine if limited discoverable for BR/EDR can be configured or not. Signed-off-by: Marcel Holtmann Signed-off-by: Gustavo Padovan --- include/net/bluetooth/hci.h | 6 ++++++ include/net/bluetooth/hci_core.h | 1 + net/bluetooth/hci_core.c | 6 +++++- net/bluetooth/hci_event.c | 19 +++++++++++++++++++ 4 files changed, 31 insertions(+), 1 deletion(-) (limited to 'include/net') diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index c8a91cb20173..8567f44aa618 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -815,6 +815,12 @@ struct hci_cp_host_buffer_size { __le16 sco_max_pkt; } __packed; +#define HCI_OP_READ_NUM_SUPPORTED_IAC 0x0c38 +struct hci_rp_read_num_supported_iac { + __u8 status; + __u8 num_iac; +} __packed; + #define HCI_OP_WRITE_INQUIRY_MODE 0x0c45 #define HCI_MAX_EIR_LENGTH 240 diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 0326b160b89a..4e208420d84c 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -159,6 +159,7 @@ struct hci_dev { __u16 manufacturer; __u16 lmp_subver; __u16 voice_setting; + __u8 num_iac; __u8 io_capability; __s8 inq_tx_power; __u16 page_scan_interval; diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 0e05edee0962..b5ef05e66a2d 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -370,6 +370,9 @@ static void bredr_setup(struct hci_request *req) /* Read Voice Setting */ hci_req_add(req, HCI_OP_READ_VOICE_SETTING, 0, NULL); + /* Read Number of Supported IAC */ + hci_req_add(req, HCI_OP_READ_NUM_SUPPORTED_IAC, 0, NULL); + /* Clear Event Filters */ flt_type = HCI_FLT_CLEAR_ALL; hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &flt_type); @@ -2271,7 +2274,8 @@ struct hci_dev *hci_alloc_dev(void) hdev->pkt_type = (HCI_DM1 | HCI_DH1 | HCI_HV1); hdev->esco_type = (ESCO_HV1); hdev->link_mode = (HCI_LM_ACCEPT); - hdev->io_capability = 0x03; /* No Input No Output */ + hdev->num_iac = 0x01; /* One IAC support is mandatory */ + hdev->io_capability = 0x03; /* No Input No Output */ hdev->inq_tx_power = HCI_TX_POWER_INVALID; hdev->adv_tx_power = HCI_TX_POWER_INVALID; diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index da2bc3d3d289..5391469ff1a5 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -418,6 +418,21 @@ static void hci_cc_write_voice_setting(struct hci_dev *hdev, hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING); } +static void hci_cc_read_num_supported_iac(struct hci_dev *hdev, + struct sk_buff *skb) +{ + struct hci_rp_read_num_supported_iac *rp = (void *) skb->data; + + BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); + + if (rp->status) + return; + + hdev->num_iac = rp->num_iac; + + BT_DBG("%s num iac %d", hdev->name, hdev->num_iac); +} + static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb) { __u8 status = *((__u8 *) skb->data); @@ -2135,6 +2150,10 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) hci_cc_write_voice_setting(hdev, skb); break; + case HCI_OP_READ_NUM_SUPPORTED_IAC: + hci_cc_read_num_supported_iac(hdev, skb); + break; + case HCI_OP_WRITE_SSP_MODE: hci_cc_write_ssp_mode(hdev, skb); break; -- cgit v1.2.3 From 4b836f393bd8ed111857a6ee1865e44627266ec6 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 14 Oct 2013 14:06:36 -0700 Subject: Bluetooth: Read current IAC LAP on controller setup Read the current IAC LAP values when initializing the controller. The values are not used, but it is good to have them in the trace files for debugging purposes. Signed-off-by: Marcel Holtmann Signed-off-by: Gustavo Padovan --- include/net/bluetooth/hci.h | 2 ++ net/bluetooth/hci_core.c | 3 +++ 2 files changed, 5 insertions(+) (limited to 'include/net') diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index 8567f44aa618..b096f5f73789 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -821,6 +821,8 @@ struct hci_rp_read_num_supported_iac { __u8 num_iac; } __packed; +#define HCI_OP_READ_CURRENT_IAC_LAP 0x0c39 + #define HCI_OP_WRITE_INQUIRY_MODE 0x0c45 #define HCI_MAX_EIR_LENGTH 240 diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index b5ef05e66a2d..7add9c96e32c 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -373,6 +373,9 @@ static void bredr_setup(struct hci_request *req) /* Read Number of Supported IAC */ hci_req_add(req, HCI_OP_READ_NUM_SUPPORTED_IAC, 0, NULL); + /* Read Current IAC LAP */ + hci_req_add(req, HCI_OP_READ_CURRENT_IAC_LAP, 0, NULL); + /* Clear Event Filters */ flt_type = HCI_FLT_CLEAR_ALL; hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &flt_type); -- cgit v1.2.3