* [PATCH v2 1/2] Bluetooth: Move discovery state check inside hci_dev_lock()
From: Jaganath Kanakkassery @ 2012-12-21 12:50 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Jaganath Kanakkassery
In-Reply-To: <1356094225-12706-1-git-send-email-jaganath.k@samsung.com>
After checking the discovery state, if other thread modifies it
then it will be overwritten by the assignment in the first thread.
Signed-off-by: Jaganath Kanakkassery <jaganath.k@samsung.com>
---
net/bluetooth/hci_event.c | 9 ++++-----
net/bluetooth/mgmt.c | 4 ----
2 files changed, 4 insertions(+), 9 deletions(-)
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 9fb656b..e248e7c 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1106,14 +1106,13 @@ static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
clear_bit(HCI_LE_SCAN, &hdev->dev_flags);
+ hci_dev_lock(hdev);
if (hdev->discovery.type == DISCOV_TYPE_INTERLEAVED &&
- hdev->discovery.state == DISCOVERY_FINDING) {
+ hdev->discovery.state == DISCOVERY_FINDING)
mgmt_interleaved_discovery(hdev);
- } else {
- hci_dev_lock(hdev);
+ else
hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
- hci_dev_unlock(hdev);
- }
+ hci_dev_unlock(hdev);
break;
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 729fb8c..d6c0d78 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -2289,14 +2289,10 @@ int mgmt_interleaved_discovery(struct hci_dev *hdev)
BT_DBG("%s", hdev->name);
- hci_dev_lock(hdev);
-
err = hci_do_inquiry(hdev, INQUIRY_LEN_BREDR_LE);
if (err < 0)
hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
- hci_dev_unlock(hdev);
-
return err;
}
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 2/2] Bluetooth: Fix stop discovery while in STARTING state
From: Jaganath Kanakkassery @ 2012-12-21 12:50 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Jaganath Kanakkassery
In-Reply-To: <1356094225-12706-1-git-send-email-jaganath.k@samsung.com>
If stop_discovery() is called when discovery state is STARTING, it
will be failed currently. This patch fixes this.
Signed-off-by: Jaganath Kanakkassery <jaganath.k@samsung.com>
---
include/net/bluetooth/hci_core.h | 2 ++
net/bluetooth/hci_event.c | 14 ++++++++++++--
net/bluetooth/mgmt.c | 31 ++++++++++++++++++++++++++++++-
3 files changed, 44 insertions(+), 3 deletions(-)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 119fcb6..c2886b7 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -64,6 +64,7 @@ struct discovery_state {
DISCOVERY_RESOLVING,
DISCOVERY_STOPPING,
} state;
+ u8 discovering;
struct list_head all; /* All devices found during inquiry */
struct list_head unknown; /* Name state not known */
struct list_head resolve; /* Name needs to be resolved */
@@ -1066,6 +1067,7 @@ int mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
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_start_discovery_failed(struct hci_dev *hdev, u8 status);
+int mgmt_start_discovery_complete(struct hci_dev *hdev, u8 status);
int mgmt_stop_discovery_failed(struct hci_dev *hdev, u8 status);
int mgmt_discovering(struct hci_dev *hdev, u8 discovering);
int mgmt_interleaved_discovery(struct hci_dev *hdev);
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index e248e7c..b486458 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1092,7 +1092,12 @@ static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
set_bit(HCI_LE_SCAN, &hdev->dev_flags);
hci_dev_lock(hdev);
- hci_discovery_set_state(hdev, DISCOVERY_FINDING);
+ if (hdev->discovery.state == DISCOVERY_STOPPING) {
+ hci_cancel_le_scan(hdev);
+ mgmt_start_discovery_complete(hdev, 0);
+ } else {
+ hci_discovery_set_state(hdev, DISCOVERY_FINDING);
+ }
hci_dev_unlock(hdev);
break;
@@ -1189,7 +1194,12 @@ static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
set_bit(HCI_INQUIRY, &hdev->flags);
hci_dev_lock(hdev);
- hci_discovery_set_state(hdev, DISCOVERY_FINDING);
+ if (hdev->discovery.state == DISCOVERY_STOPPING) {
+ hci_cancel_inquiry(hdev);
+ mgmt_start_discovery_complete(hdev, 0);
+ } else {
+ hci_discovery_set_state(hdev, DISCOVERY_FINDING);
+ }
hci_dev_unlock(hdev);
}
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index d6c0d78..ba4171f 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -2385,7 +2385,8 @@ static int stop_discovery(struct sock *sk, struct hci_dev *hdev, void *data,
hci_dev_lock(hdev);
- if (!hci_discovery_active(hdev)) {
+ if (hdev->discovery.state != DISCOVERY_STARTING &&
+ !hci_discovery_active(hdev)) {
err = cmd_complete(sk, hdev->id, MGMT_OP_STOP_DISCOVERY,
MGMT_STATUS_REJECTED, &mgmt_cp->type,
sizeof(mgmt_cp->type));
@@ -2433,6 +2434,10 @@ static int stop_discovery(struct sock *sk, struct hci_dev *hdev, void *data,
break;
+ case DISCOVERY_STARTING:
+ err = 0;
+ break;
+
default:
BT_DBG("unknown discovery state %u", hdev->discovery.state);
err = -EFAULT;
@@ -3624,6 +3629,25 @@ int mgmt_start_discovery_failed(struct hci_dev *hdev, u8 status)
return err;
}
+int mgmt_start_discovery_complete(struct hci_dev *hdev, u8 status)
+{
+ struct pending_cmd *cmd;
+ u8 type;
+ int err;
+
+ cmd = mgmt_pending_find(MGMT_OP_START_DISCOVERY, hdev);
+ if (!cmd)
+ return -ENOENT;
+
+ type = hdev->discovery.type;
+
+ err = cmd_complete(cmd->sk, hdev->id, cmd->opcode, mgmt_status(status),
+ &type, sizeof(type));
+ mgmt_pending_remove(cmd);
+
+ return err;
+}
+
int mgmt_stop_discovery_failed(struct hci_dev *hdev, u8 status)
{
struct pending_cmd *cmd;
@@ -3660,6 +3684,11 @@ int mgmt_discovering(struct hci_dev *hdev, u8 discovering)
mgmt_pending_remove(cmd);
}
+ if (hdev->discovery.discovering == discovering)
+ return 0;
+
+ hdev->discovery.discovering = discovering;
+
memset(&ev, 0, sizeof(ev));
ev.type = hdev->discovery.type;
ev.discovering = discovering;
--
1.7.9.5
^ permalink raw reply related
* [PATCH] adapter: Fix setting discoverable mode from settings
From: Szymon Janc @ 2012-12-21 13:13 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
Discoverable mode was not set to correct value read from settings.
---
src/adapter.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/adapter.c b/src/adapter.c
index 55f03a4..6ff20e1 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -2630,7 +2630,7 @@ static void load_config(struct btd_adapter *adapter)
} else if (stored_discoverable != adapter->discoverable) {
if (adapter->connectable)
mgmt_set_discoverable(adapter->dev_id,
- adapter->discoverable,
+ stored_discoverable,
adapter->discov_timeout);
else
adapter->toggle_discoverable = true;
--
1.8.0
^ permalink raw reply related
* [PATCH 1/2] Bluetooth: Fix to update EIR for uuid16 properly
From: Syam Sidhardhan @ 2012-12-21 13:44 UTC (permalink / raw)
To: linux-bluetooth
If we register a uuid other than uuid16, especially custom 128 bit uuid
then nothing is updated in the EIR and it was broken.
After registering a 16 bit uuid. ex: "sdptool add SP", we can see the
uuid in the EIR as below.
< 0000: 01 52 0c f1 00 08 09 52 65 64 77 6f 6f 64 15 03 .R.....Redwood..
0010: 01 11 32 11 2f 11 06 11 05 11 0a 11 0e 11 0c 11 ..2./...........
0020: 1f 11 12 11 00 00 00 00 00 00 00 00 00 00 00 00 ................
0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00f0: 00 00 00 00 00 .....
> 0000: 04 0e 04 01 52 0c 00 ....R..
But after register a user defined 128 bit uuid, nothing is
updated in the EIR.
< 0000: 01 52 0c f1 00 08 09 52 65 64 77 6f 6f 64 00 00 .R.....Redwood..
0010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00f0: 00 00 00 00 00 .....
> 0000: 04 0e 04 01 52 0c 00 ....R..
With this fix, we can see the EIR is updated properly.
Signed-off-by: Syam Sidhardhan <s.syam@samsung.com>
---
net/bluetooth/mgmt.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index f559b96..512a3f5 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -514,8 +514,6 @@ static void create_eir(struct hci_dev *hdev, u8 *data)
u16 uuid16;
uuid16 = get_uuid16(uuid->uuid);
- if (uuid16 == 0)
- return;
if (uuid16 < 0x1100)
continue;
--
1.7.9.5
^ permalink raw reply related
* [PATCH 2/2] Bluetooth: Fix ACL alive for long in case of non pariable devices
From: Syam Sidhardhan @ 2012-12-21 13:44 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1356097469-24073-1-git-send-email-s.syam@samsung.com>
For certain devices (ex: HID mouse), support for authentication,
pairing and bonding is optional. For such devices, the ACL alive
for too long after the l2cap disconnection.
To avoid keep ACL alive for too long, set the ACL timeout back to
HCI_DISCONN_TIMEOUT when l2cap is connected.
commit id:a9ea3ed9b71cc3271dd59e76f65748adcaa76422 might have introduce
this issue.
Signed-off-by: Sang-Ki Park <sangki79.park@samsung.com>
Signed-off-by: Syam Sidhardhan <s.syam@samsung.com>
---
I'm not sure whether we need hci_conn_hold() and hci_conn_put() across
while updating the disc_timeout. In certain other places in the code
it's done. Ex: hci_auth_complete_evt(), hci_link_key_notify_evt() etc.
Here I took that as the reference.
net/bluetooth/l2cap_core.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 82a3bdc..7a544c2 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -1360,7 +1360,6 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn)
sk = chan->sk;
hci_conn_hold(conn->hcon);
- conn->hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
bacpy(&bt_sk(sk)->src, conn->src);
bacpy(&bt_sk(sk)->dst, conn->dst);
@@ -1380,6 +1379,10 @@ static void l2cap_conn_ready(struct l2cap_conn *conn)
BT_DBG("conn %p", conn);
+ hci_conn_hold(conn->hcon);
+ conn->hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
+ hci_conn_put(conn->hcon);
+
if (!hcon->out && hcon->type == LE_LINK)
l2cap_le_conn_ready(conn);
--
1.7.9.5
^ permalink raw reply related
* Re: [PATCH] adapter: Fix setting discoverable mode from settings
From: Johan Hedberg @ 2012-12-21 13:52 UTC (permalink / raw)
To: Szymon Janc; +Cc: linux-bluetooth
In-Reply-To: <1356095585-14353-1-git-send-email-szymon.janc@tieto.com>
Hi Szymon,
On Fri, Dec 21, 2012, Szymon Janc wrote:
> Discoverable mode was not set to correct value read from settings.
> ---
> src/adapter.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
Applied. Thanks.
Johan
^ permalink raw reply
* [PATCH BlueZ 1/4] core: Use ERROR_INTERFACE instead of org.bluez.Error
From: Anderson Lizardo @ 2012-12-21 16:25 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Anderson Lizardo
This will simplify changing interface name later (e.g. adding
versioning).
---
src/adapter.c | 4 ++--
src/agent.c | 5 +++--
src/device.c | 2 +-
3 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/src/adapter.c b/src/adapter.c
index 6ff20e1..c1cb763 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -736,7 +736,7 @@ static void service_auth_cancel(struct service_auth *auth)
DBusError derr;
dbus_error_init(&derr);
- dbus_set_error_const(&derr, "org.bluez.Error.Canceled", NULL);
+ dbus_set_error_const(&derr, ERROR_INTERFACE ".Canceled", NULL);
auth->cb(&derr, auth->user_data);
@@ -3105,7 +3105,7 @@ static gboolean process_auth_queue(gpointer user_data)
adapter->auth_idle_id = 0;
dbus_error_init(&err);
- dbus_set_error_const(&err, "org.bluez.Error.Rejected", NULL);
+ dbus_set_error_const(&err, ERROR_INTERFACE ".Rejected", NULL);
while (!g_queue_is_empty(adapter->auths)) {
struct service_auth *auth = adapter->auths->head->data;
diff --git a/src/agent.c b/src/agent.c
index 71e13c2..9b3fd28 100644
--- a/src/agent.c
+++ b/src/agent.c
@@ -206,7 +206,8 @@ void agent_unref(struct agent *agent)
agent_cb cb;
dbus_error_init(&err);
- dbus_set_error_const(&err, "org.bluez.Error.Failed", "Canceled");
+ dbus_set_error_const(&err, ERROR_INTERFACE ".Failed",
+ "Canceled");
switch (agent->request->type) {
case AGENT_REQUEST_PINCODE:
@@ -439,7 +440,7 @@ static void pincode_reply(DBusPendingCall *call, void *user_data)
if (len > 16 || len < 1) {
error("Invalid PIN length (%zu) from agent", len);
- dbus_set_error_const(&err, "org.bluez.Error.InvalidArgs",
+ dbus_set_error_const(&err, ERROR_INTERFACE ".InvalidArgs",
"Invalid passkey length");
cb(agent, &err, NULL, req->user_data);
dbus_error_free(&err);
diff --git a/src/device.c b/src/device.c
index 3cfb816..17c6cf7 100644
--- a/src/device.c
+++ b/src/device.c
@@ -3908,7 +3908,7 @@ static void cancel_authentication(struct authentication_req *auth)
auth->agent = NULL;
dbus_error_init(&err);
- dbus_set_error_const(&err, "org.bluez.Error.Canceled", NULL);
+ dbus_set_error_const(&err, ERROR_INTERFACE ".Canceled", NULL);
switch (auth->type) {
case AUTH_TYPE_PINCODE:
--
1.7.9.5
^ permalink raw reply related
* [PATCH BlueZ 2/4] sap: Use btd_error_* functions
From: Anderson Lizardo @ 2012-12-21 16:25 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Anderson Lizardo
In-Reply-To: <1356107103-18039-1-git-send-email-anderson.lizardo@openbossa.org>
These helper functions are available for plugins and simplify error
handling code.
---
profiles/sap/sap-dummy.c | 24 +++++++++---------------
profiles/sap/server.c | 14 +++-----------
2 files changed, 12 insertions(+), 26 deletions(-)
diff --git a/profiles/sap/sap-dummy.c b/profiles/sap/sap-dummy.c
index ffaf847..f68e048 100644
--- a/profiles/sap/sap-dummy.c
+++ b/profiles/sap/sap-dummy.c
@@ -31,6 +31,7 @@
#include <stdint.h>
#include "dbus-common.h"
+#include "error.h"
#include "log.h"
#include "sap.h"
@@ -234,12 +235,6 @@ void sap_set_transport_protocol_req(void *sap_device,
sap_transport_protocol_rsp(sap_device, SAP_RESULT_NOT_SUPPORTED);
}
-static inline DBusMessage *invalid_args(DBusMessage *msg)
-{
- return g_dbus_create_error(msg, "org.bluez.Error.InvalidArguments",
- "Invalid arguments in method call");
-}
-
static DBusMessage *ongoing_call(DBusConnection *conn, DBusMessage *msg,
void *data)
{
@@ -247,7 +242,7 @@ static DBusMessage *ongoing_call(DBusConnection *conn, DBusMessage *msg,
if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_BOOLEAN, &ongoing,
DBUS_TYPE_INVALID))
- return invalid_args(msg);
+ return btd_error_invalid_args(msg);
if (ongoing_call_status && !ongoing) {
/* An ongoing call has finished. Continue connection.*/
@@ -269,12 +264,12 @@ static DBusMessage *max_msg_size(DBusConnection *conn, DBusMessage *msg,
dbus_uint32_t size;
if (sim_card_conn_status == SIM_CONNECTED)
- return g_dbus_create_error(msg, "org.bluez.Error.Failed",
+ return btd_error_failed(msg,
"Can't change msg size when connected.");
if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_UINT32, &size,
DBUS_TYPE_INVALID))
- return invalid_args(msg);
+ return btd_error_invalid_args(msg);
max_msg_size_supported = size;
@@ -287,8 +282,7 @@ static DBusMessage *disconnect_immediate(DBusConnection *conn, DBusMessage *msg,
void *data)
{
if (sim_card_conn_status == SIM_DISCONNECTED)
- return g_dbus_create_error(msg, "org.bluez.Error.Failed",
- "Already disconnected.");
+ return btd_error_failed(msg, "Already disconnected.");
sim_card_conn_status = SIM_DISCONNECTED;
sap_disconnect_ind(sap_data, SAP_DISCONNECTION_TYPE_IMMEDIATE);
@@ -304,12 +298,12 @@ static DBusMessage *card_status(DBusConnection *conn, DBusMessage *msg,
DBG("status %d", sim_card_conn_status);
if (sim_card_conn_status != SIM_CONNECTED)
- return g_dbus_create_error(msg, "org.bluez.Error.Failed",
+ return btd_error_failed(msg,
"Can't change msg size when not connected.");
if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_UINT32, &status,
DBUS_TYPE_INVALID))
- return invalid_args(msg);
+ return btd_error_invalid_args(msg);
switch (status) {
case 0: /* card removed */
@@ -331,8 +325,8 @@ static DBusMessage *card_status(DBusConnection *conn, DBusMessage *msg,
break;
default:
- return g_dbus_create_error(msg, "org.bluez.Error.Failed",
- "Unknown card status. Use 0, 1 or 2.");
+ return btd_error_failed(msg,
+ "Unknown card status. Use 0, 1 or 2.");
}
DBG("Card status changed to %d", status);
diff --git a/profiles/sap/server.c b/profiles/sap/server.c
index 01caa33..0fa4e7c 100644
--- a/profiles/sap/server.c
+++ b/profiles/sap/server.c
@@ -1260,29 +1260,21 @@ static void connect_confirm_cb(GIOChannel *io, gpointer data)
DBG("Authorizing incoming SAP connection from %s", dstaddr);
}
-static inline DBusMessage *message_failed(DBusMessage *msg,
- const char *description)
-{
- return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed", "%s",
- description);
-}
-
static DBusMessage *disconnect(DBusConnection *conn, DBusMessage *msg,
void *data)
{
struct sap_server *server = data;
if (!server)
- return message_failed(msg, "Server internal error.");
+ return btd_error_failed(msg, "Server internal error.");
DBG("conn %p", server->conn);
if (!server->conn)
- return message_failed(msg, "Client already disconnected");
+ return btd_error_failed(msg, "Client already disconnected");
if (disconnect_req(server, SAP_DISCONNECTION_TYPE_GRACEFUL) < 0)
- return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
- "There is no active connection");
+ return btd_error_failed(msg, "There is no active connection");
return dbus_message_new_method_return(msg);
}
--
1.7.9.5
^ permalink raw reply related
* [PATCH BlueZ 3/4] obexd: Simplify org.bluez.Error.InvalidArguments handling
From: Anderson Lizardo @ 2012-12-21 16:25 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Anderson Lizardo
In-Reply-To: <1356107103-18039-1-git-send-email-anderson.lizardo@openbossa.org>
Use a helper function to void code duplication.
---
obexd/plugins/bluetooth.c | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/obexd/plugins/bluetooth.c b/obexd/plugins/bluetooth.c
index 8985c83..e28a94f 100644
--- a/obexd/plugins/bluetooth.c
+++ b/obexd/plugins/bluetooth.c
@@ -104,6 +104,12 @@ drop:
return;
}
+static DBusMessage *invalid_args(DBusMessage *msg)
+{
+ return g_dbus_create_error(msg, "org.bluez.Error.InvalidArguments",
+ "Invalid arguments in method call");
+}
+
static DBusMessage *profile_new_connection(DBusConnection *conn,
DBusMessage *msg, void *data)
{
@@ -115,26 +121,20 @@ static DBusMessage *profile_new_connection(DBusConnection *conn,
dbus_message_iter_init(msg, &args);
if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_OBJECT_PATH)
- return g_dbus_create_error(msg,
- "org.bluez.Error.InvalidArguments",
- "Invalid arguments in method call");
+ return invalid_args(msg);
dbus_message_iter_get_basic(&args, &device);
dbus_message_iter_next(&args);
if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_UNIX_FD)
- return g_dbus_create_error(msg,
- "org.bluez.Error.InvalidArguments",
- "Invalid arguments in method call");
+ return invalid_args(msg);
dbus_message_iter_get_basic(&args, &fd);
io = g_io_channel_unix_new(fd);
if (io == NULL)
- return g_dbus_create_error(msg,
- "org.bluez.Error.InvalidArguments",
- "Invalid arguments in method call");
+ return invalid_args(msg);
DBG("device %s", device);
--
1.7.9.5
^ permalink raw reply related
* [PATCH BlueZ 4/4] build: Fix installing udev rules file when $(srcdir) != $(builddir)
From: Anderson Lizardo @ 2012-12-21 16:25 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Anderson Lizardo
In-Reply-To: <1356107103-18039-1-git-send-email-anderson.lizardo@openbossa.org>
Path to files on source tree should be prefixed with $(srcdir),
otherwise they are not found if $(srcdir) != $(builddir).
---
Makefile.am | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Makefile.am b/Makefile.am
index 350a9e8..8852e04 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -278,7 +278,7 @@ src/builtin.h: src/genbuiltin $(builtin_sources)
$(AM_V_GEN)$(srcdir)/src/genbuiltin $(builtin_modules) > $@
tools/%.rules:
- $(AM_V_GEN)cp $(subst 97-,,$@) $@
+ $(AM_V_GEN)cp $(srcdir)/$(subst 97-,,$@) $@
$(lib_libbluetooth_la_OBJECTS): $(local_headers)
--
1.7.9.5
^ permalink raw reply related
* Bluetooth stack issues across suspend/resume
From: Karl Relton @ 2012-12-21 16:57 UTC (permalink / raw)
To: linux-bluetooth
With various testing and investigation, it seems that there are 3
different issues that can plague a user who has bluetooth keyboard/mouse
and wants to do a suspend/resume on their computer.
1) On resume, a kernel OOPS in the hidp module in linux 3.3 and above.
see https://bugzilla.kernel.org/show_bug.cgi?id=50541
This obviously kills the users system completely (repeatable for me on
vast majority of resumes).
2) If #1 is worked around, then a race in the hci system of the
keyboard/mouse device being deleted/re-added. I can't find a kernel bug
report for it, but this msg is on the case, albeit with a rejected
patch:
http://www.spinics.net/lists/linux-bluetooth/msg16303.html
There seem to be various downstream reports - this is one:
https://bugs.launchpad.net/ubuntu/+source/linux/+bug/888828
3) If you get past 2), then you would hope all would be well. However
now the Xserver refuses to receive events from the re-added
mouse/keyboard.
The Xorg log file reports:
[ 2149.898] (**) evdev: Apple Wireless Keyboard: Device:
"/dev/input/event10"
[ 2149.898] (WW) evdev: Apple Wireless Keyboard: device file is
duplicate. Ignoring.
[ 2149.904] (EE) PreInit returned 8 for "Apple Wireless Keyboard"
[ 2149.904] (II) UnloadModule: "evdev"
The reason is discussed by google chrome developers here:
http://code.google.com/p/chromium-os/issues/detail?id=33813
The udev events for the mouse/keyboard removal have their prefix
removed, which means they are ignored by the Xserver.
The google developers are correct - on my system I can see (for Linux
3.7 at least):
KERNEL[2213.152339] remove /hci0/hci0:46/input14/mouse2 (input)
UDEV [2213.152975] remove /hci0/hci0:46/input14/mouse2 (input)
KERNEL[2213.160374] remove /hci0/hci0:46/input14/event10 (input)
UDEV [2213.160919] remove /hci0/hci0:46/input14/event10 (input)
Note with Linux 3.2 the remove events have the full path (back in 3.2 it
all just works for me, btw).
I'm guessing the 3) may be 'deliberate' in the way the driver code is
handling device removal (when the bluetooth adaptor is reset),
'orphaning' the keyboard/mouse devices before they later get properly
removed. It is having an unfortunate effect on the userspace software
that needs them however.
Issues 1) and 2) are certainly problems with the driver itself - making
systems unusable across suspend/resume.
Regards
Karl
^ permalink raw reply
* Re: [RFC/RFT] rtk_btusb: Bluetooth driver for Realtek RTL8723AE combo device
From: Larry Finger @ 2012-12-21 18:09 UTC (permalink / raw)
To: Marcel Holtmann
Cc: linville, Gustavo Padovan, Johan Hedberg, linux-wireless,
linux-bluetooth, Champion Chen
In-Reply-To: <1356074247.29264.11.camel@aeonflux>
On 12/21/2012 01:17 AM, Marcel Holtmann wrote:
>
> NAK. This is pretty much a blunt copy of btusb.c and not acceptable.
>
> And last time I checked, I own a big portion of btusb.c and I find it
> funny how that copyright just got replaced. 2015? Really? Time travel
> much lately ;)
>
> There have been patches for hdev->setup stage and discussions on
> creating a mini-driver approach on the mailing list. That is the way to
> go.
Marcel,
Sorry that I did not look into the copyright issue more. I knew that this was
mostly a copy of btusb.c, and I should have been more careful. There was no
intent on my part to steal your stuff.
I am not a subscriber to linux-bluetooth, and I have not previously seen the
discussions/patches on the hdev->setup and mini-driver. What is the current
status of the setup patches? I could not find them in the wireless-testing tree.
Thanks,
Larry
^ permalink raw reply
* [RFC -v2 00/16] Completely remove socket dependency from l2cap_core.c
From: Gustavo Padovan @ 2012-12-21 18:10 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Gustavo Padovan
From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
This is the last series of patches to completely remove the l2cap socket usage
in the l2cap_core.c file. We now have a C API to access L2CAP and as a next
step we should convert RFCOMM to use this API.
v2: adressed comments from Lizardo and Andrei.
Gustavo Padovan (16):
Bluetooth: Add src and dst info to struct l2cap_chan
Bluetooth: Remove sk_sndtimeo from l2cap_core.c
Bluetooth: extend state_change() call to report errors too
Bluetooth: add l2cap_state_change_and_error()
Bluetooth: Add missing braces to an "else if"
Bluetooth: use l2cap_chan_ready() instead of duplicate code
Bluetooth: duplicate DEFER_SETUP flag on l2cap_chan
Bluetooth: Improving locking in l2cap_conn_start()
Bluetooth: lock socket in defer_cb call
Bluetooth: Remove socket lock from state_change() in l2cap_core
Bluetooth: remove parent socket usage from l2cap_core.c
Bluetooth: Use abstract chan->data in comparison
Bluetooth: Move l2cap_wait_ack() to l2cap_sock.c
Bluetooth: Create l2cap->ops->resume()
Bluetooth: Create l2cap->ops->set_shutdown()
Bluetooth: Remove sk member from struct l2cap_chan
include/net/bluetooth/l2cap.h | 22 ++++-
net/bluetooth/a2mp.c | 4 +-
net/bluetooth/l2cap_core.c | 200 ++++++++++++------------------------------
net/bluetooth/l2cap_sock.c | 96 +++++++++++++++++---
net/bluetooth/rfcomm/core.c | 15 ++--
5 files changed, 169 insertions(+), 168 deletions(-)
--
1.8.0.2
^ permalink raw reply
* [RFC -v2 01/16] Bluetooth: Add src and dst info to struct l2cap_chan
From: Gustavo Padovan @ 2012-12-21 18:10 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Gustavo Padovan
In-Reply-To: <1356113459-7932-1-git-send-email-gustavo@padovan.org>
From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
Adding these two info to l2cap_chan makes the l2cap_core.c a little more
independent of the struct sock.
Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
include/net/bluetooth/l2cap.h | 3 +++
net/bluetooth/l2cap_core.c | 46 ++++++++++++++++++-------------------------
net/bluetooth/l2cap_sock.c | 6 +++---
net/bluetooth/rfcomm/core.c | 15 +++++++-------
4 files changed, 33 insertions(+), 37 deletions(-)
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index cdd3302..6040743 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -435,6 +435,9 @@ struct l2cap_seq_list {
struct l2cap_chan {
struct sock *sk;
+ bdaddr_t src;
+ bdaddr_t dst;
+
struct l2cap_conn *conn;
struct hci_conn *hs_hcon;
struct hci_chan *hs_hchan;
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 82a3bdc..ae51965 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -148,7 +148,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;
@@ -1305,7 +1305,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;
@@ -1315,16 +1314,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;
@@ -1338,7 +1337,7 @@ static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid,
static void l2cap_le_conn_ready(struct l2cap_conn *conn)
{
- struct sock *parent, *sk;
+ struct sock *parent;
struct l2cap_chan *chan, *pchan;
BT_DBG("");
@@ -1357,13 +1356,11 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn)
if (!chan)
goto clean;
- sk = chan->sk;
-
hci_conn_hold(conn->hcon);
conn->hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
- bacpy(&bt_sk(sk)->src, conn->src);
- bacpy(&bt_sk(sk)->dst, conn->dst);
+ bacpy(&chan->src, conn->src);
+ bacpy(&chan->dst, conn->dst);
l2cap_chan_add(conn, chan);
@@ -1572,7 +1569,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;
@@ -1582,16 +1578,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;
@@ -1607,7 +1603,7 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
bdaddr_t *dst, u8 dst_type)
{
struct sock *sk = chan->sk;
- bdaddr_t *src = &bt_sk(sk)->src;
+ bdaddr_t *src = &chan->src;
struct l2cap_conn *conn;
struct hci_conn *hcon;
struct hci_dev *hdev;
@@ -1674,9 +1670,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;
@@ -3637,8 +3631,8 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
hci_conn_hold(conn->hcon);
- bacpy(&bt_sk(sk)->src, conn->src);
- bacpy(&bt_sk(sk)->dst, conn->dst);
+ bacpy(&chan->src, conn->src);
+ bacpy(&chan->dst, conn->dst);
chan->psm = psm;
chan->dcid = scid;
chan->local_amp_id = amp_id;
@@ -6274,17 +6268,16 @@ 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;
@@ -6568,10 +6561,9 @@ 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 1bcfb84..0977966 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -97,7 +97,7 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
__le16_to_cpu(la.l2_psm) == L2CAP_PSM_RFCOMM)
chan->sec_level = BT_SECURITY_SDP;
- bacpy(&bt_sk(sk)->src, &la.l2_bdaddr);
+ bacpy(&chan->src, &la.l2_bdaddr);
chan->state = BT_BOUND;
sk->sk_state = BT_BOUND;
@@ -259,11 +259,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);
}
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
index 201fdf7..15dc078 100644
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -632,13 +632,13 @@ static struct rfcomm_session *rfcomm_session_get(bdaddr_t *src, bdaddr_t *dst)
{
struct rfcomm_session *s;
struct list_head *p, *n;
- struct bt_sock *sk;
+ struct l2cap_chan *chan;
list_for_each_safe(p, n, &session_list) {
s = list_entry(p, struct rfcomm_session, list);
- sk = bt_sk(s->sock->sk);
+ chan = l2cap_pi(s->sock->sk)->chan;
- if ((!bacmp(src, BDADDR_ANY) || !bacmp(&sk->src, src)) &&
- !bacmp(&sk->dst, dst))
+ if ((!bacmp(src, BDADDR_ANY) || !bacmp(&chan->src, src)) &&
+ !bacmp(&chan->dst, dst))
return s;
}
return NULL;
@@ -727,9 +727,9 @@ void rfcomm_session_getaddr(struct rfcomm_session *s, bdaddr_t *src, bdaddr_t *d
{
struct sock *sk = s->sock->sk;
if (src)
- bacpy(src, &bt_sk(sk)->src);
+ bacpy(src, &l2cap_pi(sk)->chan->src);
if (dst)
- bacpy(dst, &bt_sk(sk)->dst);
+ bacpy(dst, &l2cap_pi(sk)->chan->dst);
}
/* ---- RFCOMM frame sending ---- */
@@ -2126,7 +2126,8 @@ static int rfcomm_dlc_debugfs_show(struct seq_file *f, void *x)
struct sock *sk = s->sock->sk;
seq_printf(f, "%pMR %pMR %ld %d %d %d %d\n",
- &bt_sk(sk)->src, &bt_sk(sk)->dst,
+ &l2cap_pi(sk)->chan->src,
+ &l2cap_pi(sk)->chan->dst,
d->state, d->dlci, d->mtu,
d->rx_credits, d->tx_credits);
}
--
1.8.0.2
^ permalink raw reply related
* [RFC -v2 02/16] Bluetooth: Remove sk_sndtimeo from l2cap_core.c
From: Gustavo Padovan @ 2012-12-21 18:10 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Gustavo Padovan
In-Reply-To: <1356113459-7932-1-git-send-email-gustavo@padovan.org>
From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
We now have a new struct member in l2cap_chan to store this value for
access inside l2cap_core.c
Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
include/net/bluetooth/l2cap.h | 1 +
net/bluetooth/l2cap_core.c | 7 +++----
net/bluetooth/l2cap_sock.c | 1 +
3 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 6040743..cf94e68 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -480,6 +480,7 @@ struct l2cap_chan {
__u8 tx_state;
__u8 rx_state;
+ unsigned long sndtimeo;
unsigned long conf_state;
unsigned long conn_state;
unsigned long flags;
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index ae51965..c854789 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -630,7 +630,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) {
- __set_chan_timer(chan, sk->sk_sndtimeo);
+ __set_chan_timer(chan, chan->sndtimeo);
l2cap_send_disconn_req(chan, reason);
} else
l2cap_chan_del(chan, reason);
@@ -1602,7 +1602,6 @@ static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
bdaddr_t *dst, u8 dst_type)
{
- struct sock *sk = chan->sk;
bdaddr_t *src = &chan->src;
struct l2cap_conn *conn;
struct hci_conn *hcon;
@@ -1716,7 +1715,7 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
l2cap_chan_lock(chan);
l2cap_state_change(chan, BT_CONNECT);
- __set_chan_timer(chan, sk->sk_sndtimeo);
+ __set_chan_timer(chan, chan->sndtimeo);
if (hcon->state == BT_CONNECTED) {
if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
@@ -3641,7 +3640,7 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
dcid = chan->scid;
- __set_chan_timer(chan, sk->sk_sndtimeo);
+ __set_chan_timer(chan, chan->sndtimeo);
chan->ident = cmd->ident;
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 0977966..221aef9 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -1178,6 +1178,7 @@ static void l2cap_sock_init(struct sock *sk, struct sock *parent)
/* Default config options */
chan->flush_to = L2CAP_DEFAULT_FLUSH_TO;
+ chan->sndtimeo = sk->sk_sndtimeo;
chan->data = sk;
chan->ops = &l2cap_chan_ops;
--
1.8.0.2
^ permalink raw reply related
* [RFC -v2 03/16] Bluetooth: extend state_change() call to report errors too
From: Gustavo Padovan @ 2012-12-21 18:10 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Gustavo Padovan
In-Reply-To: <1356113459-7932-1-git-send-email-gustavo@padovan.org>
From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
Now l2cap_core doesn't need to touch sk_err element anymore, it just tell
l2cap_sock via this call which error it wants to set.
Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
include/net/bluetooth/l2cap.h | 2 +-
net/bluetooth/a2mp.c | 2 +-
net/bluetooth/l2cap_core.c | 6 ++----
net/bluetooth/l2cap_sock.c | 6 +++++-
4 files changed, 9 insertions(+), 7 deletions(-)
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index cf94e68..4f28a8c 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -550,7 +550,7 @@ struct l2cap_ops {
void (*teardown) (struct l2cap_chan *chan, int err);
void (*close) (struct l2cap_chan *chan);
void (*state_change) (struct l2cap_chan *chan,
- int state);
+ int state, int err);
void (*ready) (struct l2cap_chan *chan);
void (*defer) (struct l2cap_chan *chan);
struct sk_buff *(*alloc_skb) (struct l2cap_chan *chan,
diff --git a/net/bluetooth/a2mp.c b/net/bluetooth/a2mp.c
index eb0f4b1..ad6e42f 100644
--- a/net/bluetooth/a2mp.c
+++ b/net/bluetooth/a2mp.c
@@ -671,7 +671,7 @@ static void a2mp_chan_close_cb(struct l2cap_chan *chan)
l2cap_chan_put(chan);
}
-static void a2mp_chan_state_change_cb(struct l2cap_chan *chan, int state)
+static void a2mp_chan_state_change_cb(struct l2cap_chan *chan, int state, int err)
{
struct amp_mgr *mgr = chan->data;
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index c854789..7a56596 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -216,7 +216,7 @@ static void __l2cap_state_change(struct l2cap_chan *chan, int state)
state_to_string(state));
chan->state = state;
- chan->ops->state_change(chan, state);
+ chan->ops->state_change(chan, state, 0);
}
static void l2cap_state_change(struct l2cap_chan *chan, int state)
@@ -230,9 +230,7 @@ static void l2cap_state_change(struct l2cap_chan *chan, int state)
static inline void __l2cap_chan_set_err(struct l2cap_chan *chan, int err)
{
- struct sock *sk = chan->sk;
-
- sk->sk_err = err;
+ chan->ops->state_change(chan, chan->state, err);
}
static inline void l2cap_chan_set_err(struct l2cap_chan *chan, int err)
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 221aef9..8adea0f 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -1044,11 +1044,15 @@ static void l2cap_sock_teardown_cb(struct l2cap_chan *chan, int err)
release_sock(sk);
}
-static void l2cap_sock_state_change_cb(struct l2cap_chan *chan, int state)
+static void l2cap_sock_state_change_cb(struct l2cap_chan *chan, int state,
+ int err)
{
struct sock *sk = chan->data;
sk->sk_state = state;
+
+ if (err)
+ sk->sk_err = err;
}
static struct sk_buff *l2cap_sock_alloc_skb_cb(struct l2cap_chan *chan,
--
1.8.0.2
^ permalink raw reply related
* [RFC -v2 04/16] Bluetooth: add l2cap_state_change_and_error()
From: Gustavo Padovan @ 2012-12-21 18:10 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Gustavo Padovan
In-Reply-To: <1356113459-7932-1-git-send-email-gustavo@padovan.org>
From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
Add helper to set both state and error at the same time.
Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
net/bluetooth/l2cap_core.c | 18 ++++++++++--------
1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 7a56596..cdd7f44 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -228,9 +228,15 @@ static void l2cap_state_change(struct l2cap_chan *chan, int state)
release_sock(sk);
}
-static inline void __l2cap_chan_set_err(struct l2cap_chan *chan, int err)
+static void l2cap_state_change_and_error(struct l2cap_chan *chan, int state,
+ int err)
{
- chan->ops->state_change(chan, chan->state, err);
+ struct sock *sk = chan->sk;
+
+ lock_sock(sk);
+ chan->state = state;
+ chan->ops->state_change(chan, state, err);
+ release_sock(sk);
}
static inline void l2cap_chan_set_err(struct l2cap_chan *chan, int err)
@@ -238,7 +244,7 @@ static inline void l2cap_chan_set_err(struct l2cap_chan *chan, int err)
struct sock *sk = chan->sk;
lock_sock(sk);
- __l2cap_chan_set_err(chan, err);
+ chan->ops->state_change(chan, chan->state, err);
release_sock(sk);
}
@@ -1180,7 +1186,6 @@ static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err)
{
- struct sock *sk = chan->sk;
struct l2cap_conn *conn = chan->conn;
struct l2cap_disconn_req req;
@@ -1203,10 +1208,7 @@ static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err)
l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_DISCONN_REQ,
sizeof(req), &req);
- lock_sock(sk);
- __l2cap_state_change(chan, BT_DISCONN);
- __l2cap_chan_set_err(chan, err);
- release_sock(sk);
+ l2cap_state_change_and_error(chan, BT_DISCONN, err);
}
/* ---- L2CAP connections ---- */
--
1.8.0.2
^ permalink raw reply related
* [RFC -v2 05/16] Bluetooth: Add missing braces to an "else if"
From: Gustavo Padovan @ 2012-12-21 18:10 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Gustavo Padovan
In-Reply-To: <1356113459-7932-1-git-send-email-gustavo@padovan.org>
From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
Trivial change in the coding style.
Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
net/bluetooth/l2cap_core.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index cdd7f44..2ad952b 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -1406,8 +1406,9 @@ static void l2cap_conn_ready(struct l2cap_conn *conn)
sk->sk_state_change(sk);
release_sock(sk);
- } else if (chan->state == BT_CONNECT)
+ } else if (chan->state == BT_CONNECT) {
l2cap_do_start(chan);
+ }
l2cap_chan_unlock(chan);
}
--
1.8.0.2
^ permalink raw reply related
* [RFC -v2 06/16] Bluetooth: use l2cap_chan_ready() instead of duplicate code
From: Gustavo Padovan @ 2012-12-21 18:10 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Gustavo Padovan
In-Reply-To: <1356113459-7932-1-git-send-email-gustavo@padovan.org>
From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
l2cap_chan_ready() does exactly what we want here avoiding duplicate code.
Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
net/bluetooth/l2cap_core.c | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 2ad952b..af8783a 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -1399,12 +1399,7 @@ static void l2cap_conn_ready(struct l2cap_conn *conn)
l2cap_chan_ready(chan);
} else if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
- struct sock *sk = chan->sk;
- __clear_chan_timer(chan);
- lock_sock(sk);
- __l2cap_state_change(chan, BT_CONNECTED);
- sk->sk_state_change(sk);
- release_sock(sk);
+ l2cap_chan_ready(chan);
} else if (chan->state == BT_CONNECT) {
l2cap_do_start(chan);
--
1.8.0.2
^ permalink raw reply related
* [RFC -v2 07/16] Bluetooth: duplicate DEFER_SETUP flag on l2cap_chan
From: Gustavo Padovan @ 2012-12-21 18:10 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Gustavo Padovan
In-Reply-To: <1356113459-7932-1-git-send-email-gustavo@padovan.org>
From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
Now l2cap_chan also has the DEFER_SETUP flag, so we don't need to access
the bt_sk(sk) to read this flag inside l2cap_core.c. We need to kep it
duplicate since it is used in Bluetooth socket code as well.
Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
include/net/bluetooth/l2cap.h | 1 +
net/bluetooth/l2cap_core.c | 16 +++++++---------
net/bluetooth/l2cap_sock.c | 7 +++++--
3 files changed, 13 insertions(+), 11 deletions(-)
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 4f28a8c..0c76c55 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -635,6 +635,7 @@ enum {
CONN_REJ_ACT,
CONN_SEND_FBIT,
CONN_RNR_SENT,
+ CONN_DEFER_SETUP,
};
/* Definitions for flags in l2cap_chan */
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index af8783a..4cc49f3 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -620,10 +620,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:
@@ -646,7 +644,7 @@ void l2cap_chan_close(struct l2cap_chan *chan, int reason)
struct l2cap_conn_rsp rsp;
__u16 result;
- if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags))
+ if (test_bit(CONN_DEFER_SETUP, &chan->conn_state))
result = L2CAP_CR_SEC_BLOCK;
else
result = L2CAP_CR_BAD_PSM;
@@ -1255,8 +1253,8 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
if (l2cap_chan_check_security(chan)) {
lock_sock(sk);
- if (test_bit(BT_SK_DEFER_SETUP,
- &bt_sk(sk)->flags)) {
+ if (test_bit(CONN_DEFER_SETUP,
+ &chan->conn_state)) {
rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
chan->ops->defer(chan);
@@ -3642,7 +3640,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(CONN_DEFER_SETUP, &chan->conn_state)) {
__l2cap_state_change(chan, BT_CONNECT2);
result = L2CAP_CR_PEND;
status = L2CAP_CS_AUTHOR_PEND;
@@ -6402,8 +6400,8 @@ 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(CONN_DEFER_SETUP,
+ &chan->conn_state)) {
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 8adea0f..9cd6fba 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -659,10 +659,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(CONN_DEFER_SETUP, &chan->conn_state);
+ } else {
clear_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags);
+ clear_bit(CONN_DEFER_SETUP, &chan->conn_state);
+ }
break;
case BT_FLUSHABLE:
--
1.8.0.2
^ permalink raw reply related
* [RFC -v2 08/16] Bluetooth: Improving locking in l2cap_conn_start()
From: Gustavo Padovan @ 2012-12-21 18:10 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Gustavo Padovan
In-Reply-To: <1356113459-7932-1-git-send-email-gustavo@padovan.org>
From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
Since we don't read bt_sk(sk) in here anymore we can remove the lock from
the block and only use it when calling l2cap_state_change().
Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
net/bluetooth/l2cap_core.c | 13 +++----------
1 file changed, 3 insertions(+), 10 deletions(-)
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 4cc49f3..110a702 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -1252,7 +1252,6 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
rsp.dcid = cpu_to_le16(chan->scid);
if (l2cap_chan_check_security(chan)) {
- lock_sock(sk);
if (test_bit(CONN_DEFER_SETUP,
&chan->conn_state)) {
rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
@@ -1260,11 +1259,10 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
chan->ops->defer(chan);
} else {
- __l2cap_state_change(chan, BT_CONFIG);
+ l2cap_state_change(chan, BT_CONFIG);
rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
}
- release_sock(sk);
} else {
rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
@@ -6393,12 +6391,9 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
__set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
}
} else if (chan->state == BT_CONNECT2) {
- struct sock *sk = chan->sk;
struct l2cap_conn_rsp rsp;
__u16 res, stat;
- lock_sock(sk);
-
if (!status) {
if (test_bit(CONN_DEFER_SETUP,
&chan->conn_state)) {
@@ -6406,19 +6401,17 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
stat = L2CAP_CS_AUTHOR_PEND;
chan->ops->defer(chan);
} else {
- __l2cap_state_change(chan, BT_CONFIG);
+ l2cap_state_change(chan, BT_CONFIG);
res = L2CAP_CR_SUCCESS;
stat = L2CAP_CS_NO_INFO;
}
} else {
- __l2cap_state_change(chan, BT_DISCONN);
+ l2cap_state_change(chan, BT_DISCONN);
__set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
res = L2CAP_CR_SEC_BLOCK;
stat = L2CAP_CS_NO_INFO;
}
- release_sock(sk);
-
rsp.scid = cpu_to_le16(chan->dcid);
rsp.dcid = cpu_to_le16(chan->scid);
rsp.result = cpu_to_le16(res);
--
1.8.0.2
^ permalink raw reply related
* [RFC -v2 09/16] Bluetooth: lock socket in defer_cb call
From: Gustavo Padovan @ 2012-12-21 18:10 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Gustavo Padovan
In-Reply-To: <1356113459-7932-1-git-send-email-gustavo@padovan.org>
From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
Since we removed the lock around the ops->defer() call inside
l2cap_core.c we need now to protect the defer_cb call.
Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
net/bluetooth/l2cap_sock.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 9cd6fba..6a95d37 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -1096,11 +1096,15 @@ static void l2cap_sock_ready_cb(struct l2cap_chan *chan)
static void l2cap_sock_defer_cb(struct l2cap_chan *chan)
{
- struct sock *sk = chan->data;
- struct sock *parent = bt_sk(sk)->parent;
+ struct sock *parent, *sk = chan->data;
+
+ lock_sock(sk);
+ parent = bt_sk(sk)->parent;
if (parent)
parent->sk_data_ready(parent, 0);
+
+ release_sock(sk);
}
static struct l2cap_ops l2cap_chan_ops = {
--
1.8.0.2
^ permalink raw reply related
* [RFC -v2 10/16] Bluetooth: Remove socket lock from state_change() in l2cap_core
From: Gustavo Padovan @ 2012-12-21 18:10 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Gustavo Padovan
In-Reply-To: <1356113459-7932-1-git-send-email-gustavo@padovan.org>
From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
This simplifies a lot the state change handling inside l2cap_core.c,
we got rid of __l2cap_state_change() and l2cap_state_change() doesn't lock
the socket anymore, instead the socket is locked inside the ops user code
in l2cap_sock.c.
In some places we were not using the locked version, and now we are using
it. There is no side effect in locking the socket in these places.
Handle the operation of lock the socket to ops user benefit A2MP, since
there is no socket lock there it doesn't need any special function in
l2cap work without touching socket locks.
Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
net/bluetooth/l2cap_core.c | 32 +++++++-------------------------
net/bluetooth/l2cap_sock.c | 4 ++++
2 files changed, 11 insertions(+), 25 deletions(-)
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 110a702..2c4458a 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -210,7 +210,7 @@ static u16 l2cap_alloc_cid(struct l2cap_conn *conn)
return 0;
}
-static void __l2cap_state_change(struct l2cap_chan *chan, int state)
+static void l2cap_state_change(struct l2cap_chan *chan, int state)
{
BT_DBG("chan %p %s -> %s", chan, state_to_string(chan->state),
state_to_string(state));
@@ -219,33 +219,16 @@ static void __l2cap_state_change(struct l2cap_chan *chan, int state)
chan->ops->state_change(chan, state, 0);
}
-static void l2cap_state_change(struct l2cap_chan *chan, int state)
-{
- struct sock *sk = chan->sk;
-
- lock_sock(sk);
- __l2cap_state_change(chan, state);
- release_sock(sk);
-}
-
static void l2cap_state_change_and_error(struct l2cap_chan *chan, int state,
int err)
{
- struct sock *sk = chan->sk;
-
- lock_sock(sk);
chan->state = state;
chan->ops->state_change(chan, state, err);
- release_sock(sk);
}
static inline void l2cap_chan_set_err(struct l2cap_chan *chan, int err)
{
- struct sock *sk = chan->sk;
-
- lock_sock(sk);
chan->ops->state_change(chan, chan->state, err);
- release_sock(sk);
}
static void __set_retrans_timer(struct l2cap_chan *chan)
@@ -1219,7 +1202,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);
@@ -3639,7 +3621,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(CONN_DEFER_SETUP, &chan->conn_state)) {
- __l2cap_state_change(chan, BT_CONNECT2);
+ l2cap_state_change(chan, BT_CONNECT2);
result = L2CAP_CR_PEND;
status = L2CAP_CS_AUTHOR_PEND;
chan->ops->defer(chan);
@@ -3649,21 +3631,21 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
* physical link is up.
*/
if (amp_id) {
- __l2cap_state_change(chan, BT_CONNECT2);
+ l2cap_state_change(chan, BT_CONNECT2);
result = L2CAP_CR_PEND;
} else {
- __l2cap_state_change(chan, BT_CONFIG);
+ l2cap_state_change(chan, BT_CONFIG);
result = L2CAP_CR_SUCCESS;
}
status = L2CAP_CS_NO_INFO;
}
} else {
- __l2cap_state_change(chan, BT_CONNECT2);
+ l2cap_state_change(chan, BT_CONNECT2);
result = L2CAP_CR_PEND;
status = L2CAP_CS_AUTHEN_PEND;
}
} else {
- __l2cap_state_change(chan, BT_CONNECT2);
+ l2cap_state_change(chan, BT_CONNECT2);
result = L2CAP_CR_PEND;
status = L2CAP_CS_NO_INFO;
}
@@ -4542,7 +4524,7 @@ static void l2cap_do_create(struct l2cap_chan *chan, int result,
sizeof(rsp), &rsp);
if (result == L2CAP_CR_SUCCESS) {
- __l2cap_state_change(chan, BT_CONFIG);
+ l2cap_state_change(chan, BT_CONFIG);
set_bit(CONF_REQ_SENT, &chan->conf_state);
l2cap_send_cmd(chan->conn, l2cap_get_ident(chan->conn),
L2CAP_CONF_REQ,
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 6a95d37..cf8f187 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -1052,10 +1052,14 @@ static void l2cap_sock_state_change_cb(struct l2cap_chan *chan, int state,
{
struct sock *sk = chan->data;
+ lock_sock(sk);
+
sk->sk_state = state;
if (err)
sk->sk_err = err;
+
+ release_sock(sk);
}
static struct sk_buff *l2cap_sock_alloc_skb_cb(struct l2cap_chan *chan,
--
1.8.0.2
^ permalink raw reply related
* [RFC -v2 11/16] Bluetooth: remove parent socket usage from l2cap_core.c
From: Gustavo Padovan @ 2012-12-21 18:10 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Gustavo Padovan
In-Reply-To: <1356113459-7932-1-git-send-email-gustavo@padovan.org>
From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
Since we do not touch the parent sock in l2cap_core.c anymore we don't
need to lock it there anymore. That lock was replaced by the
l2cap_chan_lock and inside the new_connection() call for l2cap_sock.c the
parent lock is locked, so the operations that uses it can be performed
safely.
The l2cap_chan_lock give us the needed protection to handle the incoming
connections.
Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
net/bluetooth/l2cap_core.c | 16 ++++------------
net/bluetooth/l2cap_sock.c | 4 ++++
2 files changed, 8 insertions(+), 12 deletions(-)
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 2c4458a..6d62bfb 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -1315,7 +1315,6 @@ static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid,
static void l2cap_le_conn_ready(struct l2cap_conn *conn)
{
- struct sock *parent;
struct l2cap_chan *chan, *pchan;
BT_DBG("");
@@ -1326,9 +1325,7 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn)
if (!pchan)
return;
- parent = pchan->sk;
-
- lock_sock(parent);
+ l2cap_chan_lock(pchan);
chan = pchan->ops->new_connection(pchan);
if (!chan)
@@ -1345,7 +1342,7 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn)
l2cap_chan_ready(chan);
clean:
- release_sock(parent);
+ l2cap_chan_unlock(pchan);
}
static void l2cap_conn_ready(struct l2cap_conn *conn)
@@ -3562,7 +3559,6 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
struct l2cap_conn_rsp rsp;
struct l2cap_chan *chan = NULL, *pchan;
- struct sock *parent, *sk = NULL;
int result, status = L2CAP_CS_NO_INFO;
u16 dcid = 0, scid = __le16_to_cpu(req->scid);
@@ -3577,10 +3573,8 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
goto sendresp;
}
- parent = pchan->sk;
-
mutex_lock(&conn->chan_lock);
- lock_sock(parent);
+ l2cap_chan_lock(pchan);
/* Check if the ACL is secure enough (if not SDP) */
if (psm != __constant_cpu_to_le16(L2CAP_PSM_SDP) &&
@@ -3600,8 +3594,6 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
if (!chan)
goto response;
- sk = chan->sk;
-
hci_conn_hold(conn->hcon);
bacpy(&chan->src, conn->src);
@@ -3651,7 +3643,7 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
}
response:
- release_sock(parent);
+ l2cap_chan_unlock(pchan);
mutex_unlock(&conn->chan_lock);
sendresp:
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index cf8f187..3d76de8 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -943,6 +943,8 @@ static struct l2cap_chan *l2cap_sock_new_connection_cb(struct l2cap_chan *chan)
{
struct sock *sk, *parent = chan->data;
+ lock_sock(parent);
+
/* Check for backlog size */
if (sk_acceptq_is_full(parent)) {
BT_DBG("backlog full %d", parent->sk_ack_backlog);
@@ -960,6 +962,8 @@ static struct l2cap_chan *l2cap_sock_new_connection_cb(struct l2cap_chan *chan)
bt_accept_enqueue(parent, sk);
+ release_sock(parent);
+
return l2cap_pi(sk)->chan;
}
--
1.8.0.2
^ permalink raw reply related
* [RFC -v2 12/16] Bluetooth: Use abstract chan->data in comparison
From: Gustavo Padovan @ 2012-12-21 18:10 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Gustavo Padovan
In-Reply-To: <1356113459-7932-1-git-send-email-gustavo@padovan.org>
From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
If the L2CAP user is l2cap_sock.c chan->data is a pointer to the l2cap
socket so chan->sk and chan->data are the same thing. Then we can just
compare with chan->data instead.
Non-socket users will have skb->sk = NULL, thus this change does not
interfere in other users.
Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
include/net/bluetooth/l2cap.h | 2 +-
net/bluetooth/l2cap_core.c | 3 +--
2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 0c76c55..6986140 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -536,7 +536,7 @@ struct l2cap_chan {
struct list_head list;
struct list_head global_l;
- void *data;
+ void *data; /* l2cap user data. eg: sk for sockets */
struct l2cap_ops *ops;
struct mutex lock;
};
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 6d62bfb..935534c 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -2677,12 +2677,11 @@ static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
mutex_lock(&conn->chan_lock);
list_for_each_entry(chan, &conn->chan_l, list) {
- struct sock *sk = chan->sk;
if (chan->chan_type != L2CAP_CHAN_RAW)
continue;
/* Don't send frame to the socket it came from */
- if (skb->sk == sk)
+ if (skb->sk && skb->sk == chan->data)
continue;
nskb = skb_clone(skb, GFP_KERNEL);
if (!nskb)
--
1.8.0.2
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox