* [PATCH 6/9] Add btd_error_not_available()
From: Gustavo F. Padovan @ 2010-12-06 19:10 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1291662648-10651-5-git-send-email-padovan@profusion.mobi>
---
audio/headset.c | 9 +++------
plugins/service.c | 16 +++-------------
src/error.c | 7 +++++++
src/error.h | 1 +
4 files changed, 14 insertions(+), 19 deletions(-)
diff --git a/audio/headset.c b/audio/headset.c
index c3d7f82..0413588 100644
--- a/audio/headset.c
+++ b/audio/headset.c
@@ -1792,8 +1792,7 @@ static DBusMessage *hs_play(DBusConnection *conn, DBusMessage *msg,
if (sco_hci) {
error("Refusing Headset.Play() because SCO HCI routing "
"is enabled");
- return g_dbus_create_error(msg, ERROR_INTERFACE ".NotAvailable",
- "Operation not Available");
+ return btd_error_not_available(msg);
}
switch (hs->state) {
@@ -1838,8 +1837,7 @@ static DBusMessage *hs_get_speaker_gain(DBusConnection *conn,
dbus_uint16_t gain;
if (hs->state < HEADSET_STATE_CONNECTED)
- return g_dbus_create_error(msg, ERROR_INTERFACE ".NotAvailable",
- "Operation not Available");
+ return btd_error_not_available(msg);
reply = dbus_message_new_method_return(msg);
if (!reply)
@@ -1864,8 +1862,7 @@ static DBusMessage *hs_get_mic_gain(DBusConnection *conn,
dbus_uint16_t gain;
if (hs->state < HEADSET_STATE_CONNECTED || slc == NULL)
- return g_dbus_create_error(msg, ERROR_INTERFACE ".NotAvailable",
- "Operation not Available");
+ return btd_error_not_available(msg);
reply = dbus_message_new_method_return(msg);
if (!reply)
diff --git a/plugins/service.c b/plugins/service.c
index 12e05c1..a71540c 100644
--- a/plugins/service.c
+++ b/plugins/service.c
@@ -337,12 +337,6 @@ static void exit_callback(DBusConnection *conn, void *user_data)
g_free(user_record);
}
-static inline DBusMessage *not_available(DBusMessage *msg)
-{
- return g_dbus_create_error(msg, ERROR_INTERFACE ".NotAvailable",
- "Not Available");
-}
-
static inline DBusMessage *failed(DBusMessage *msg)
{
return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed", "Failed");
@@ -417,9 +411,7 @@ static DBusMessage *update_record(DBusConnection *conn, DBusMessage *msg,
if (remove_record_from_server(handle) < 0) {
sdp_record_free(sdp_record);
- return g_dbus_create_error(msg,
- ERROR_INTERFACE ".NotAvailable",
- "Not Available");
+ return btd_error_not_available(msg);
}
if (serv_adapter->adapter)
@@ -463,9 +455,7 @@ static DBusMessage *update_xml_record(DBusConnection *conn,
user_record = find_record(serv_adapter, handle,
dbus_message_get_sender(msg));
if (!user_record)
- return g_dbus_create_error(msg,
- ERROR_INTERFACE ".NotAvailable",
- "Not Available");
+ return btd_error_not_available(msg);
sdp_record = sdp_xml_parse_record(record, len);
if (!sdp_record) {
@@ -550,7 +540,7 @@ static DBusMessage *remove_service_record(DBusConnection *conn,
sender = dbus_message_get_sender(msg);
if (remove_record(conn, sender, serv_adapter, handle) < 0)
- return not_available(msg);
+ return btd_error_not_available(msg);
return dbus_message_new_method_return(msg);
}
diff --git a/src/error.c b/src/error.c
index 9b18842..3f9acd9 100644
--- a/src/error.c
+++ b/src/error.c
@@ -83,3 +83,10 @@ DBusMessage *btd_error_in_progress(DBusMessage *msg)
".InProgress",
"In Progress");
}
+
+DBusMessage *btd_error_not_available(DBusMessage *msg)
+{
+ return g_dbus_create_error(msg, ERROR_INTERFACE
+ ".NotAvailable",
+ "Operation currently not available");
+}
diff --git a/src/error.h b/src/error.h
index b8066ce..623860e 100644
--- a/src/error.h
+++ b/src/error.h
@@ -34,4 +34,5 @@ DBusMessage *btd_error_invalid_args(DBusMessage *msg);
DBusMessage *btd_error_already_exists(DBusMessage *msg);
DBusMessage *btd_error_not_supported(DBusMessage *msg);
DBusMessage *btd_error_not_connected(DBusMessage *msg);
+DBusMessage *btd_error_not_available(DBusMessage *msg);
DBusMessage *btd_error_in_progress(DBusMessage *msg);
--
1.7.3.2
^ permalink raw reply related
* [PATCH 7/9] Add btd_error_busy()
From: Gustavo F. Padovan @ 2010-12-06 19:10 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1291662648-10651-6-git-send-email-padovan@profusion.mobi>
---
audio/headset.c | 4 +---
audio/sink.c | 6 ++----
audio/source.c | 3 +--
input/device.c | 6 ------
src/error.c | 6 ++++++
src/error.h | 1 +
6 files changed, 11 insertions(+), 15 deletions(-)
diff --git a/audio/headset.c b/audio/headset.c
index 0413588..8402789 100644
--- a/audio/headset.c
+++ b/audio/headset.c
@@ -1804,9 +1804,7 @@ static DBusMessage *hs_play(DBusConnection *conn, DBusMessage *msg,
hs->pending->msg = dbus_message_ref(msg);
return NULL;
}
- return g_dbus_create_error(msg, ERROR_INTERFACE
- ".InProgress",
- "Play in Progress");
+ return btd_error_busy(msg);
case HEADSET_STATE_PLAYING:
return g_dbus_create_error(msg, ERROR_INTERFACE
".AlreadyConnected",
diff --git a/audio/sink.c b/audio/sink.c
index e9a529b..37ba8c0 100644
--- a/audio/sink.c
+++ b/audio/sink.c
@@ -439,8 +439,7 @@ static DBusMessage *sink_connect(DBusConnection *conn,
"Unable to get a session");
if (sink->connect || sink->disconnect)
- return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
- "%s", strerror(EBUSY));
+ return btd_error_busy(msg);
if (sink->stream_state >= AVDTP_STATE_OPEN)
return g_dbus_create_error(msg, ERROR_INTERFACE
@@ -475,8 +474,7 @@ static DBusMessage *sink_disconnect(DBusConnection *conn,
return btd_error_not_connected(msg);
if (sink->connect || sink->disconnect)
- return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
- "%s", strerror(EBUSY));
+ return btd_error_busy(msg);
if (sink->stream_state < AVDTP_STATE_OPEN) {
DBusMessage *reply = dbus_message_new_method_return(msg);
diff --git a/audio/source.c b/audio/source.c
index 75f50ff..a6fd8e7 100644
--- a/audio/source.c
+++ b/audio/source.c
@@ -390,8 +390,7 @@ static DBusMessage *source_connect(DBusConnection *conn,
"Unable to get a session");
if (source->connect || source->disconnect)
- return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
- "%s", strerror(EBUSY));
+ return btd_error_busy(msg);
if (source->stream_state >= AVDTP_STATE_OPEN)
return g_dbus_create_error(msg, ERROR_INTERFACE
diff --git a/input/device.c b/input/device.c
index ac425a0..f7f96be 100644
--- a/input/device.c
+++ b/input/device.c
@@ -321,12 +321,6 @@ static inline DBusMessage *not_supported(DBusMessage *msg)
"Not supported");
}
-static inline DBusMessage *in_progress(DBusMessage *msg)
-{
- return g_dbus_create_error(msg, ERROR_INTERFACE ".InProgress",
- "Device connection already in progress");
-}
-
static inline DBusMessage *already_connected(DBusMessage *msg)
{
return g_dbus_create_error(msg, ERROR_INTERFACE ".AlreadyConnected",
diff --git a/src/error.c b/src/error.c
index 3f9acd9..cf3c54d 100644
--- a/src/error.c
+++ b/src/error.c
@@ -56,6 +56,12 @@ DBusMessage *btd_error_invalid_args(DBusMessage *msg)
"Invalid arguments in method call");
}
+DBusMessage *btd_error_busy(DBusMessage *msg)
+{
+ return g_dbus_create_error(msg, ERROR_INTERFACE ".InProgress",
+ "Operation already in progress");
+}
+
DBusMessage *btd_error_already_exists(DBusMessage *msg)
{
return g_dbus_create_error(msg,
diff --git a/src/error.h b/src/error.h
index 623860e..7ffd8b7 100644
--- a/src/error.h
+++ b/src/error.h
@@ -31,6 +31,7 @@ DBusHandlerResult error_common_reply(DBusConnection *conn, DBusMessage *msg,
const char *name, const char *descr);
DBusMessage *btd_error_invalid_args(DBusMessage *msg);
+DBusMessage *btd_error_busy(DBusMessage *msg);
DBusMessage *btd_error_already_exists(DBusMessage *msg);
DBusMessage *btd_error_not_supported(DBusMessage *msg);
DBusMessage *btd_error_not_connected(DBusMessage *msg);
--
1.7.3.2
^ permalink raw reply related
* [PATCH 8/9] Add btd_error_does_not_exist()
From: Gustavo F. Padovan @ 2010-12-06 19:10 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1291662648-10651-7-git-send-email-padovan@profusion.mobi>
---
plugins/service.c | 10 ++--------
serial/port.c | 12 ++----------
serial/proxy.c | 9 +--------
src/adapter.c | 13 ++++---------
src/error.c | 7 +++++++
src/error.h | 1 +
6 files changed, 17 insertions(+), 35 deletions(-)
diff --git a/plugins/service.c b/plugins/service.c
index a71540c..406ee7d 100644
--- a/plugins/service.c
+++ b/plugins/service.c
@@ -354,12 +354,6 @@ static inline DBusMessage *not_authorized(DBusMessage *msg)
"Not Authorized");
}
-static inline DBusMessage *does_not_exist(DBusMessage *msg)
-{
- return g_dbus_create_error(msg, ERROR_INTERFACE ".DoesNotExist",
- "Does Not Exist");
-}
-
static int add_xml_record(DBusConnection *conn, const char *sender,
struct service_adapter *serv_adapter,
const char *record, dbus_uint32_t *handle)
@@ -656,7 +650,7 @@ static DBusMessage *request_authorization(DBusConnection *conn,
auth = next_pending(serv_adapter);
if (auth == NULL)
- return does_not_exist(msg);
+ return btd_error_does_not_exist(msg);
if (serv_adapter->adapter)
adapter_get_address(serv_adapter->adapter, &src);
@@ -687,7 +681,7 @@ static DBusMessage *cancel_authorization(DBusConnection *conn,
auth = find_pending_by_sender(serv_adapter, sender);
if (auth == NULL)
- return does_not_exist(msg);
+ return btd_error_does_not_exist(msg);
if (serv_adapter->adapter)
adapter_get_address(serv_adapter->adapter, &src);
diff --git a/serial/port.c b/serial/port.c
index b593311..add8ae0 100644
--- a/serial/port.c
+++ b/serial/port.c
@@ -57,7 +57,6 @@
#include "port.h"
#define SERIAL_PORT_INTERFACE "org.bluez.Serial"
-#define ERROR_DOES_NOT_EXIST "org.bluez.Error.DoesNotExist"
#define MAX_OPEN_TRIES 5
#define OPEN_WAIT 300 /* ms. udev node creation retry wait */
@@ -235,13 +234,6 @@ void port_release_all(void)
g_slist_free(devices);
}
-static inline DBusMessage *does_not_exist(DBusMessage *msg,
- const char *description)
-{
- return g_dbus_create_error(msg, ERROR_INTERFACE ".DoesNotExist",
- "%s", description);
-}
-
static inline DBusMessage *failed(DBusMessage *msg, const char *description)
{
return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
@@ -497,7 +489,7 @@ static DBusMessage *port_connect(DBusConnection *conn,
channel = strtol(pattern, &endptr, 10);
if ((endptr && *endptr != '\0') || channel < 1 || channel > 30)
- return does_not_exist(msg, "Does not match");
+ return btd_error_does_not_exist(msg);
port = create_port(device, NULL, channel);
}
@@ -538,7 +530,7 @@ static DBusMessage *port_disconnect(DBusConnection *conn,
port = find_port(device->ports, dev);
if (!port)
- return does_not_exist(msg, "Port does not exist");
+ return btd_error_does_not_exist(msg);
if (!port->listener_id)
return failed(msg, "Not connected");
diff --git a/serial/proxy.c b/serial/proxy.c
index b2ced98..778deb0 100644
--- a/serial/proxy.c
+++ b/serial/proxy.c
@@ -131,13 +131,6 @@ static void proxy_free(struct serial_proxy *prx)
g_free(prx);
}
-static inline DBusMessage *does_not_exist(DBusMessage *msg,
- const char *description)
-{
- return g_dbus_create_error(msg, ERROR_INTERFACE ".DoesNotExist",
- "%s", description);
-}
-
static inline DBusMessage *failed(DBusMessage *msg, const char *description)
{
return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
@@ -1113,7 +1106,7 @@ static DBusMessage *remove_proxy(DBusConnection *conn,
l = g_slist_find_custom(adapter->proxies, path, proxy_pathcmp);
if (!l)
- return does_not_exist(msg, "Invalid proxy path");
+ return btd_error_does_not_exist(msg);
prx = l->data;
diff --git a/src/adapter.c b/src/adapter.c
index 2aa9977..2d47856 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -1794,9 +1794,8 @@ static DBusMessage *remove_device(DBusConnection *conn, DBusMessage *msg,
l = g_slist_find_custom(adapter->devices,
path, (GCompareFunc) device_path_cmp);
if (!l)
- return g_dbus_create_error(msg,
- ERROR_INTERFACE ".DoesNotExist",
- "Device does not exist");
+ return btd_error_does_not_exist(msg);
+
device = l->data;
if (device_is_temporary(device) || device_is_busy(device))
@@ -1832,9 +1831,7 @@ static DBusMessage *find_device(DBusConnection *conn, DBusMessage *msg,
l = g_slist_find_custom(adapter->devices,
address, (GCompareFunc) device_address_cmp);
if (!l)
- return g_dbus_create_error(msg,
- ERROR_INTERFACE ".DoesNotExist",
- "Device does not exist");
+ return btd_error_does_not_exist(msg);
device = l->data;
@@ -1905,9 +1902,7 @@ static DBusMessage *unregister_agent(DBusConnection *conn, DBusMessage *msg,
name = dbus_message_get_sender(msg);
if (!adapter->agent || !agent_matches(adapter->agent, name, path))
- return g_dbus_create_error(msg,
- ERROR_INTERFACE ".DoesNotExist",
- "No such agent");
+ return btd_error_does_not_exist(msg);
agent_free(adapter->agent);
adapter->agent = NULL;
diff --git a/src/error.c b/src/error.c
index cf3c54d..7c7d14e 100644
--- a/src/error.c
+++ b/src/error.c
@@ -96,3 +96,10 @@ DBusMessage *btd_error_not_available(DBusMessage *msg)
".NotAvailable",
"Operation currently not available");
}
+
+DBusMessage *btd_error_does_not_exist(DBusMessage *msg)
+{
+ return g_dbus_create_error(msg, ERROR_INTERFACE
+ ".DoesNotExist",
+ "Does Not Exist");
+}
diff --git a/src/error.h b/src/error.h
index 7ffd8b7..0ecbf6e 100644
--- a/src/error.h
+++ b/src/error.h
@@ -37,3 +37,4 @@ DBusMessage *btd_error_not_supported(DBusMessage *msg);
DBusMessage *btd_error_not_connected(DBusMessage *msg);
DBusMessage *btd_error_not_available(DBusMessage *msg);
DBusMessage *btd_error_in_progress(DBusMessage *msg);
+DBusMessage *btd_error_does_not_exist(DBusMessage *msg);
--
1.7.3.2
^ permalink raw reply related
* [PATCH 9/9] Add btd_error_not_authorized()
From: Gustavo F. Padovan @ 2010-12-06 19:10 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1291662648-10651-8-git-send-email-padovan@profusion.mobi>
---
attrib/client.c | 8 +-------
plugins/service.c | 22 ++++++++--------------
src/adapter.c | 8 +-------
src/device.c | 8 ++------
src/error.c | 7 +++++++
src/error.h | 1 +
6 files changed, 20 insertions(+), 34 deletions(-)
diff --git a/attrib/client.c b/attrib/client.c
index ac78fbd..0805492 100644
--- a/attrib/client.c
+++ b/attrib/client.c
@@ -191,12 +191,6 @@ static int watcher_cmp(gconstpointer a, gconstpointer b)
return g_strcmp0(watcher->path, match->path);
}
-static inline DBusMessage *not_authorized(DBusMessage *msg)
-{
- return g_dbus_create_error(msg, ERROR_INTERFACE ".NotAuthorized",
- "Not authorized");
-}
-
static void append_char_dict(DBusMessageIter *iter, struct characteristic *chr)
{
DBusMessageIter dict;
@@ -502,7 +496,7 @@ static DBusMessage *unregister_watcher(DBusConnection *conn,
l = g_slist_find_custom(prim->watchers, match, watcher_cmp);
watcher_free(match);
if (!l)
- return not_authorized(msg);
+ return btd_error_not_authorized(msg);
watcher = l->data;
g_dbus_remove_watch(conn, watcher->id);
diff --git a/plugins/service.c b/plugins/service.c
index 406ee7d..5267671 100644
--- a/plugins/service.c
+++ b/plugins/service.c
@@ -348,12 +348,6 @@ static inline DBusMessage *failed_strerror(DBusMessage *msg, int err)
"%s", strerror(err));
}
-static inline DBusMessage *not_authorized(DBusMessage *msg)
-{
- return g_dbus_create_error(msg, ERROR_INTERFACE ".NotAuthorized",
- "Not Authorized");
-}
-
static int add_xml_record(DBusConnection *conn, const char *sender,
struct service_adapter *serv_adapter,
const char *record, dbus_uint32_t *handle)
@@ -555,7 +549,7 @@ static void auth_cb(DBusError *derr, void *user_data)
if (derr) {
error("Access denied: %s", derr->message);
- reply = not_authorized(auth->msg);
+ reply = btd_error_not_authorized(auth->msg);
dbus_message_unref(auth->msg);
g_dbus_send_message(auth->conn, reply);
goto done;
@@ -612,20 +606,20 @@ static DBusMessage *request_authorization(DBusConnection *conn,
if (!user_record) {
user_record = find_record(serv_adapter_any, handle, sender);
if (!user_record)
- return not_authorized(msg);
+ return btd_error_not_authorized(msg);
}
record = sdp_record_find(user_record->handle);
if (record == NULL)
- return not_authorized(msg);
+ return btd_error_not_authorized(msg);
if (sdp_get_service_classes(record, &services) < 0) {
sdp_record_free(record);
- return not_authorized(msg);
+ return btd_error_not_authorized(msg);
}
if (services == NULL)
- return not_authorized(msg);
+ return btd_error_not_authorized(msg);
uuid = services->data;
uuid128 = sdp_uuid_to_uuid128(uuid);
@@ -634,7 +628,7 @@ static DBusMessage *request_authorization(DBusConnection *conn,
if (sdp_uuid2strn(uuid128, uuid_str, MAX_LEN_UUID_STR) < 0) {
bt_free(uuid128);
- return not_authorized(msg);
+ return btd_error_not_authorized(msg);
}
bt_free(uuid128);
@@ -662,7 +656,7 @@ static DBusMessage *request_authorization(DBusConnection *conn,
serv_adapter->pending_list = g_slist_remove(serv_adapter->pending_list,
auth);
g_free(auth);
- return not_authorized(msg);
+ return btd_error_not_authorized(msg);
}
return NULL;
@@ -690,7 +684,7 @@ static DBusMessage *cancel_authorization(DBusConnection *conn,
btd_cancel_authorization(&src, &auth->dst);
- reply = not_authorized(auth->msg);
+ reply = btd_error_not_authorized(auth->msg);
dbus_message_unref(auth->msg);
g_dbus_send_message(auth->conn, reply);
diff --git a/src/adapter.c b/src/adapter.c
index 2d47856..9199f24 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -164,12 +164,6 @@ static inline DBusMessage *not_in_progress(DBusMessage *msg, const char *str)
"%s", str);
}
-static inline DBusMessage *not_authorized(DBusMessage *msg)
-{
- return g_dbus_create_error(msg, ERROR_INTERFACE ".NotAuthorized",
- "Not authorized");
-}
-
static int found_device_cmp(const struct remote_dev_info *d1,
const struct remote_dev_info *d2)
{
@@ -1666,7 +1660,7 @@ static DBusMessage *cancel_device_creation(DBusConnection *conn,
return not_in_progress(msg, "Device creation not in progress");
if (!device_is_creating(device, sender))
- return not_authorized(msg);
+ return btd_error_not_authorized(msg);
device_set_temporary(device, TRUE);
diff --git a/src/device.c b/src/device.c
index 3f94efc..cfe00c5 100644
--- a/src/device.c
+++ b/src/device.c
@@ -727,17 +727,13 @@ static DBusMessage *cancel_discover(DBusConnection *conn,
if (!dbus_message_is_method_call(device->browse->msg, DEVICE_INTERFACE,
"DiscoverServices"))
- return g_dbus_create_error(msg,
- ERROR_INTERFACE ".NotAuthorized",
- "Not Authorized");
+ return btd_error_not_authorized(msg);
requestor = browse_request_get_requestor(device->browse);
/* only the discover requestor can cancel the inquiry process */
if (!requestor || !g_str_equal(requestor, sender))
- return g_dbus_create_error(msg,
- ERROR_INTERFACE ".NotAuthorized",
- "Not Authorized");
+ return btd_error_not_authorized(msg);
discover_services_reply(device->browse, -ECANCELED, NULL);
diff --git a/src/error.c b/src/error.c
index 7c7d14e..3c09567 100644
--- a/src/error.c
+++ b/src/error.c
@@ -103,3 +103,10 @@ DBusMessage *btd_error_does_not_exist(DBusMessage *msg)
".DoesNotExist",
"Does Not Exist");
}
+
+DBusMessage *btd_error_not_authorized(DBusMessage *msg)
+{
+ return g_dbus_create_error(msg, ERROR_INTERFACE
+ ".NotAuthorized",
+ "Operation Not Authorized");
+}
diff --git a/src/error.h b/src/error.h
index 0ecbf6e..a7028bd 100644
--- a/src/error.h
+++ b/src/error.h
@@ -38,3 +38,4 @@ DBusMessage *btd_error_not_connected(DBusMessage *msg);
DBusMessage *btd_error_not_available(DBusMessage *msg);
DBusMessage *btd_error_in_progress(DBusMessage *msg);
DBusMessage *btd_error_does_not_exist(DBusMessage *msg);
+DBusMessage *btd_error_not_authorized(DBusMessage *msg);
--
1.7.3.2
^ permalink raw reply related
* Re: [PATCH 2/2] bluetooth: Use printf extension %pMbt
From: Gustavo F. Padovan @ 2010-12-06 20:07 UTC (permalink / raw)
To: Joe Perches
Cc: Michał Mirosław, Marcel Holtmann, netdev,
David S. Miller, linux-bluetooth, linux-kernel
In-Reply-To: <1291661413.17494.219.camel@Joe-Laptop>
Hi Joe,
* Joe Perches <joe@perches.com> [2010-12-06 10:50:13 -0800]:
> On Mon, 2010-12-06 at 16:15 -0200, Gustavo F. Padovan wrote:
> > This patch doesn't apply to the bluetooth-next-2.6 tree.
> > Can you please rebase it against the bluetooth-next-2.6 tree?
>=20
> No worries, it was done against next-20101202.
>=20
> Do you care about using %pMR vs %pMbt as Micha=C5=82 suggested in
> https://lkml.org/lkml/2010/12/4/21 ?
I'm fine either way. It depends more if another subsystem will want to use
%pMR or not as you said.
--=20
Gustavo F. Padovan
http://profusion.mobi
^ permalink raw reply
* Re: [PATCH 2/3] Bluetooth: Add initial Bluetooth Management interface callbacks
From: Gustavo F. Padovan @ 2010-12-06 20:37 UTC (permalink / raw)
To: Anderson Lizardo, linux-bluetooth
In-Reply-To: <20101206142116.GA19084@jh-x301>
Hi Johan,
* Johan Hedberg <johan.hedberg@gmail.com> [2010-12-06 16:21:16 +0200]:
> Hi Anderson,
>
> On Mon, Dec 06, 2010, Anderson Lizardo wrote:
> > On Sun, Dec 5, 2010 at 2:19 PM, <johan.hedberg@gmail.com> wrote:
> > > +static void cmd_status(struct sock *sk, u16 cmd, u8 status)
> > > +{
> >
> > I see some inconsistence on how you calculate struct sizes on this
> > function. See below...
> >
> > > + struct sk_buff *skb;
> > > + struct mgmt_hdr *hdr;
> > > + struct mgmt_ev_cmd_status *ev;
> > > +
> > > + BT_DBG("sock %p", sk);
> > > +
> > > + skb = alloc_skb(sizeof(*hdr) + sizeof(*ev), GFP_ATOMIC);
> >
> > Here you use sizeof(<var>)
>
> Yep, in Chapter 14 of Documentation/CodingStyle this seems to be the
> preferred form.
>
> > > + if (!skb)
> > > + return;
> > > +
> > > + hdr = (void *) skb_put(skb, sizeof(struct mgmt_hdr));
> >
> > But here you use sizeof(<struct>). Could be sizeof(*hdr)?
>
> Yes, could be.
>
> > > +
> > > + hdr->opcode = cpu_to_le16(MGMT_EV_CMD_STATUS);
> > > + hdr->len = cpu_to_le16(3);
> >
> > and here a hard-coded size. Could be sizeof(struct mgmt_ev_cmd_status)?
>
> Yes, could be.
>
> > > + if (len != msglen - sizeof(struct mgmt_hdr)) {
> >
> > You could use sizeof(*hdr) here.
>
> Indeed.
>
> I suppose these style fixes should be as a separate patch since the
> original one already got acks from the relevant people? (if not, someone
> please enlighten me how the kernel patch process deals with comments
> received after acks :)
>From what I understand the Acked-by is more about the whole idea of the patch,
so to me it is fine to do such styles fixes and keep the ack in the patch. You
won't change essentials parts of the patch.
--
Gustavo F. Padovan
http://profusion.mobi
^ permalink raw reply
* Re: [PATCH 1/1] bluetooth: Fix NULL pointer dereference issue
From: Gustavo F. Padovan @ 2010-12-06 21:15 UTC (permalink / raw)
To: Yuri Ershov
Cc: marcel, davem, jprvita, linux-bluetooth, ville.tervo,
andrei.emeltchenko
In-Reply-To: <e98b2c6fd02b11300d82577cb54cfdb63e8400d2.1290678703.git.ext-yuri.ershov@nokia.com>
Hi Yuri,
* Yuri Ershov <ext-yuri.ershov@nokia.com> [2010-11-25 12:55:33 +0300]:
> This patch is an addition to my previous patch for this issue.
> The problem is in resynchronization between two loops:
> 1. Main controlling loop (l2cap_connect_req, l2cap_config_req,
> l2cap_config_rsp, l2cap_disconnect_req, etc.)
> 2. Loop waiting of BT_CONNECTED state of socket (l2cap_sock_accept,
> bt_accept_dequeue, etc.).
> In case of fast sequence of connect/disconnect operations the loop #1
> makes several cycles, while the loop #2 only has time to make one
> cycle and it results crash.
> The aim of the patch is to skeep handling of sockets queued for
> deletion.
>
> Signed-off-by: Yuri Ershov <ext-yuri.ershov@nokia.com>
> ---
> net/bluetooth/af_bluetooth.c | 2 ++
> net/bluetooth/l2cap.c | 6 ++++--
> 2 files changed, 6 insertions(+), 2 deletions(-)
>
> diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
> index c4cf3f5..f9389da 100644
> --- a/net/bluetooth/af_bluetooth.c
> +++ b/net/bluetooth/af_bluetooth.c
> @@ -200,6 +200,8 @@ struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock)
> BT_DBG("parent %p", parent);
>
> list_for_each_safe(p, n, &bt_sk(parent)->accept_q) {
> + if (n == p)
> + break;
So in which situations (n == p), or (p == p->next)? That should happen only
when p is the only element in the list, then p == head, right?
> sk = (struct sock *) list_entry(p, struct bt_sock, accept_q);
>
> lock_sock(sk);
> diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
> index 12b4aa2..29f30b0 100644
> --- a/net/bluetooth/l2cap.c
> +++ b/net/bluetooth/l2cap.c
> @@ -133,7 +133,8 @@ static struct sock *__l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, u16 cid)
> {
> struct sock *s;
> for (s = l->head; s; s = l2cap_pi(s)->next_c) {
> - if (l2cap_pi(s)->dcid == cid)
> + if ((l2cap_pi(s)->dcid == cid) &&
> + (sk->sk_state != BT_DISCONN) && (sk->sk_state != BT_CLOSED))
I think its better check for the cid first, and if it matches check for the
socket states, if they are BT_DISCONN or BT_CLOSED return NULL. Then you avoid
unnecessary loops here.
> break;
> }
> return s;
> @@ -143,7 +144,8 @@ static struct sock *__l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16 cid)
> {
> struct sock *s;
> for (s = l->head; s; s = l2cap_pi(s)->next_c) {
> - if (l2cap_pi(s)->scid == cid)
> + if ((l2cap_pi(s)->scid == cid) &&
> + (sk->sk_state != BT_DISCONN) && (sk->sk_state != BT_CLOSED))
> break;
Same for this one.
--
Gustavo F. Padovan
http://profusion.mobi
^ permalink raw reply
* Re: [PATCH v7] Bluetooth: btwilink driver
From: Gustavo F. Padovan @ 2010-12-06 21:23 UTC (permalink / raw)
To: Pavan Savoy; +Cc: marcel, linux-bluetooth, linux-kernel
In-Reply-To: <AANLkTiktDkjFH=aGbu3f+mkVUgmFDwB6xLW3e1VNXKtz@mail.gmail.com>
Hi Pavan,
* Pavan Savoy <pavan_savoy@ti.com> [2010-11-30 21:30:47 +0530]:
> Gustavo,
>=20
> On Tue, Nov 30, 2010 at 9:16 PM, Gustavo F. Padovan
> <padovan@profusion.mobi> wrote:
> > Hi Pavan,
> >
> > * pavan_savoy@ti.com <pavan_savoy@ti.com> [2010-11-26 04:20:57 -0500]:
> >
> >> From: Pavan Savoy <pavan_savoy@ti.com>
> >>
> >> Marcel, Gustavo,
> >>
> >> comments attended to from v5 and v6,
> >>
> >> 1. Inside ti_st_open, I previously only checked for EINPROGRESS & EPER=
M,
> >> Now I handle for EINPROGRESS - which is not really an error and
> >> return during all other error cases.
> >>
> >> 2. _write is still a function pointer and not an exported function, I
> >> need to change the underlying driver's code for this.
> >> However, previous lkml comments on the underlying driver's code
> >> suggested it to be kept as a function pointer and not EXPORT.
> >> Gustavo, Marcel - Please comment on this.
> >> Is this absolutely required? If so why?
> >>
> >> 3. test_and_set_bit of HCI_RUNNING is done at beginning of
> >> ti_st_open, and did not see issues during firmware download.
> >> However ideally I would still like to set HCI_RUNNING once the firmware
> >> download is done, because I don't want to allow a _send_frame during
> >> firmware download - Marcel, Gustavo - Please comment.
> >>
> >> 4. test_and_clear of HCI_RUNNING now done @ beginning of close.
> >>
> >> 5. EAGAIN on failure of st_write is to suggest to try and write again.
> >> I have never this happen - However only if UART goes bad this case may
> >> occur.
> >>
> >> 6. ti_st_tx_complete is very similar to hci_ldisc's tx_complete - in
> >> fact the code is pretty much borrowed from there.
> >> Marcel, Gustavo - Please suggest where should it be done? If not here.
> >>
> >> 7. comments cleaned-up + hst memory leak fixed when hci_alloc_dev fail=
s.
> >>
> >> 8. platform_driver registration inside module_init now is similar to
> >> other drivers.
> >>
> >> 9. Dan Carpenter's comments on leaking hst memory on failed
> >> hci_register_dev and empty space after quotes in debug statements
> >> fixed.
> >>
> >> Thanks for the comments...
> >> Sorry, for previously not being very clear on which comments were
> >> handled and which were not.
> >>
> >> -- patch description --
> >>
> >> This is the bluetooth protocol driver for the TI WiLink7 chipsets.
> >> Texas Instrument's WiLink chipsets combine wireless technologies
> >> like BT, FM, GPS and WLAN onto a single chip.
> >>
> >> This Bluetooth driver works on top of the TI_ST shared transport
> >> line discipline driver which also allows other drivers like
> >> FM V4L2 and GPS character driver to make use of the same UART interfac=
e.
> >>
> >> Kconfig and Makefile modifications to enable the Bluetooth
> >> driver for Texas Instrument's WiLink 7 chipset.
> >>
> >> Signed-off-by: Pavan Savoy <pavan_savoy@ti.com>
> >> ---
> >> =A0drivers/bluetooth/Kconfig =A0 =A0| =A0 10 ++
> >> =A0drivers/bluetooth/Makefile =A0 | =A0 =A01 +
> >> =A0drivers/bluetooth/btwilink.c | =A0363 +++++++++++++++++++++++++++++=
+++++++++++++
> >> =A03 files changed, 374 insertions(+), 0 deletions(-)
> >> =A0create mode 100644 drivers/bluetooth/btwilink.c
> >
> > So as part of reviewing this I took a look at your underlying driver and
> > I didn't like what I saw there, you are handling Bluetooth stuff inside
> > the core driver and that is just wrong. You have a Bluetooth driver here
> > then you have to leave the Bluetooth data handling to the Bluetooth
> > driver and do not do that in the core.
>=20
> Thanks for reviewing this and the underlying driver.
> yes, we do have Bluetooth/FM/GPS handling inside the TI ST driver, on
> addition of further technologies
> we do plan to have them inside the ST driver too.
>=20
> The understanding of BT or FM or GPS is required for the ST driver
> because, the data coming from the chip
> can either be of these technologies, further-more the data might not
> come in a set.
> As in, an a2dp/ftp ACL frame might come in 2 frames instead of 1, and
> in other cases,
> there might be a HCI-EVENT + FM CH8 data in a single frame received by th=
e UART.
Can't you differentiate Bluetooth data in a generic way, withou looking if =
it
is ACL, SCO or HCI EVENT? That done, you can just accumulate in a buffer all
the Bluetooth data you received in that stream then send it to Bluetooth
driver after finish that stream processing.
--=20
Gustavo F. Padovan
http://profusion.mobi
^ permalink raw reply
* Re: [PATCH 5/9] mfd: Add UART support for the ST-Ericsson CG2900.
From: Vitaly Wool @ 2010-12-06 21:24 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Par-Gunnar Hjalmdahl, Alan Cox, linus.walleij, linux-bluetooth,
linux-kernel, Marcel Holtmann
In-Reply-To: <201012061754.44592.arnd@arndb.de>
On Mon, Dec 6, 2010 at 5:54 PM, Arnd Bergmann <arnd@arndb.de> wrote:
>> But I was trying to make a different point here. On a basic level,
>> there's this cg2000 chip from STE that does BT, FM and GPS. There's
>> the chip from TI that does BT, FM and GPS, and there's the Broadcom
>> chip that does BT+FM. They all use HCI to access the other functions
>> of the combo chip and they do it in a really simiar way, with the
>> differences mostly in power management techniques. So I think it's
>> quite sensible to have some kind of framework that is suitable for
>> such devices.
>
> Yes, I agree 100% in principle. I could not find the code that
> Broadcom/TI FM and GPS stuff so far, can you point us to that?
Sure, the TI "shared transport" code is mostly at drivers/misc/ti-st.
Some Broadcom BCM43xx chips work in a similar way AFAIK but I'm not
sure about the mainline support for those.
> The cg2900 solution for this was to use MFD (plus another layer
> in the posted version, but that will go away I assume). Using
> MFD is not the only possibility here, but I could not see anything
> wrong with it either. Do you think we can move them all over to
> use MFD infrastructure?
I guess so but it's probably more of a detail than what I'm up to now :)
>> But generally speaking, isn't a line discipline/driver attached to a
>> tty? We can use dumb tty for e. g. SPI and still be able to use
>> hci_ll, right?
>
> I suggested that as well, but the point was made that this would
> add an unnecessary indirection for the SPI case, which is not
> really much like a serial port. It's certainly possible to do it
> like you say, but if we add a way to register the high-level
> protocols with an HCI-like multi-function device, we could
> also do it in a way that does not rely on tty-ldisc but keeps it
> as one of the options.
I actually don't think it's such a big indirection, I prefer to think
of it more as of the abstraction layer. If not use this, are we going
to have direct SPI device drivers? I'm afraid we might end up with a
huge duplication of code in that case.
Thanks,
Vitaly
^ permalink raw reply
* Re: [PATCH v7] Bluetooth: btwilink driver
From: Vitaly Wool @ 2010-12-06 21:35 UTC (permalink / raw)
To: Gustavo F. Padovan; +Cc: Pavan Savoy, marcel, linux-bluetooth, linux-kernel
In-Reply-To: <20101206212326.GI883@vigoh>
Hi Gustavo,
On Mon, Dec 6, 2010 at 10:23 PM, Gustavo F. Padovan
<padovan@profusion.mobi> wrote:
> Can't you differentiate Bluetooth data in a generic way, withou looking if it
> is ACL, SCO or HCI EVENT? That done, you can just accumulate in a buffer all
> the Bluetooth data you received in that stream then send it to Bluetooth
> driver after finish that stream processing.
I'm afraid he can't do this because he needs to route events to the
appropriate entity (BT/FM/GPS). I'm not sure how it can be done
without analyzing the incoming packet.
Thanks,
Vitaly
^ permalink raw reply
* [RFC v2 0/9] SMP Implementation
From: Vinicius Costa Gomes @ 2010-12-06 21:43 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Vinicius Costa Gomes
Hi,
Here goes just the SMP implementation (excluding Ville's LE patches).
Ville, I took the liberty of making the changes that Gustavo suggested to your
patches, the final result is here:
git://git.infradead.org/users/vcgomes/linux-2.6.git for-next
This tree is rebased on top of bluetooth-next.
Cheers
--
Anderson Briglia (3):
Bluetooth: Start SMP procedure
Bluetooth: simple SMP pairing negotiation
Bluetooth: LE SMP Cryptoolbox functions
Ville Tervo (1):
Bluetooth: Add SMP command structures
Vinicius Costa Gomes (5):
Bluetooth: Implement the first SMP commands
Bluetooth: Add support for using the crypto subsystem
Bluetooth: Add support for SMP confirmation checks
Bluetooth: Add support for LE Start Encryption
Bluetooth: Add support for resuming socket when SMP is finished
include/net/bluetooth/hci.h | 34 +++
include/net/bluetooth/hci_core.h | 7 +
include/net/bluetooth/l2cap.h | 5 +
include/net/bluetooth/smp.h | 80 ++++++
net/bluetooth/Makefile | 1 +
net/bluetooth/hci_conn.c | 47 +++
net/bluetooth/hci_core.c | 10 +
net/bluetooth/hci_event.c | 67 +++++
net/bluetooth/{l2cap.c => l2cap_core.c} | 78 ++++--
net/bluetooth/smp.c | 469 +++++++++++++++++++++++++++++++
10 files changed, 769 insertions(+), 29 deletions(-)
create mode 100644 include/net/bluetooth/smp.h
rename net/bluetooth/{l2cap.c => l2cap_core.c} (99%)
create mode 100644 net/bluetooth/smp.c
--
1.7.3.2
^ permalink raw reply
* [RFC v2 1/9] Bluetooth: Add SMP command structures
From: Vinicius Costa Gomes @ 2010-12-06 21:43 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Ville Tervo
In-Reply-To: <1291671832-13435-1-git-send-email-vinicius.gomes@openbossa.org>
From: Ville Tervo <ville.tervo@nokia.com>
Add command structures for security manager protocol.
Signed-off-by: Ville Tervo <ville.tervo@nokia.com>
---
include/net/bluetooth/smp.h | 76 +++++++++++++++++++++++++++++++++++++++++++
1 files changed, 76 insertions(+), 0 deletions(-)
create mode 100644 include/net/bluetooth/smp.h
diff --git a/include/net/bluetooth/smp.h b/include/net/bluetooth/smp.h
new file mode 100644
index 0000000..8f2edbf
--- /dev/null
+++ b/include/net/bluetooth/smp.h
@@ -0,0 +1,76 @@
+#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_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 {
+ __u16 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
+
+#endif /* __SMP_H */
--
1.7.3.2
^ permalink raw reply related
* [RFC v2 2/9] Bluetooth: Implement the first SMP commands
From: Vinicius Costa Gomes @ 2010-12-06 21:43 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Vinicius Costa Gomes, Anderson Briglia
In-Reply-To: <1291671832-13435-1-git-send-email-vinicius.gomes@openbossa.org>
These simple commands will allow the SMP procedure to be started
and terminated with a not supported error. This is the first step
toward something useful.
Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
Signed-off-by: Anderson Briglia <anderson.briglia@openbossa.org>
---
include/net/bluetooth/smp.h | 4 +
net/bluetooth/Makefile | 1 +
net/bluetooth/{l2cap.c => l2cap_core.c} | 0
net/bluetooth/smp.c | 144 +++++++++++++++++++++++++++++++
4 files changed, 149 insertions(+), 0 deletions(-)
rename net/bluetooth/{l2cap.c => l2cap_core.c} (100%)
create mode 100644 net/bluetooth/smp.c
diff --git a/include/net/bluetooth/smp.h b/include/net/bluetooth/smp.h
index 8f2edbf..b9603cc 100644
--- a/include/net/bluetooth/smp.h
+++ b/include/net/bluetooth/smp.h
@@ -73,4 +73,8 @@ struct smp_cmd_security_req {
#define SMP_UNSPECIFIED 0x08
#define SMP_REPEATED_ATTEMPTS 0x09
+/* SMP Commands */
+int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level);
+int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb);
+
#endif /* __SMP_H */
diff --git a/net/bluetooth/Makefile b/net/bluetooth/Makefile
index d1e433f..d138b23 100644
--- a/net/bluetooth/Makefile
+++ b/net/bluetooth/Makefile
@@ -11,3 +11,4 @@ obj-$(CONFIG_BT_CMTP) += cmtp/
obj-$(CONFIG_BT_HIDP) += hidp/
bluetooth-objs := af_bluetooth.o hci_core.o hci_conn.o hci_event.o hci_sock.o hci_sysfs.o lib.o
+l2cap-objs := l2cap_core.o smp.o
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap_core.c
similarity index 100%
rename from net/bluetooth/l2cap.c
rename to net/bluetooth/l2cap_core.c
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
new file mode 100644
index 0000000..e427d11
--- /dev/null
+++ b/net/bluetooth/smp.c
@@ -0,0 +1,144 @@
+/*
+ BlueZ - Bluetooth protocol stack for Linux
+ Copyright (C) 2010 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.
+*/
+
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h>
+#include <net/bluetooth/l2cap.h>
+#include <net/bluetooth/smp.h>
+
+static struct sk_buff *smp_build_cmd(struct l2cap_conn *conn, u8 code,
+ u16 dlen, void *data)
+{
+ struct sk_buff *skb;
+ struct l2cap_hdr *lh;
+ int len;
+
+ len = L2CAP_HDR_SIZE + 1 + dlen;
+
+ if (len > conn->mtu)
+ return NULL;
+
+ skb = bt_skb_alloc(len, GFP_ATOMIC);
+ if (!skb)
+ return NULL;
+
+ lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
+ lh->len = cpu_to_le16(1 + dlen);
+ lh->cid = cpu_to_le16(L2CAP_CID_SMP);
+
+ memcpy(skb_put(skb, 1), &code, 1);
+
+ memcpy(skb_put(skb, dlen), data, dlen);
+
+ return skb;
+}
+
+static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data)
+{
+ struct sk_buff *skb = smp_build_cmd(conn, code, len, data);
+
+ BT_DBG("code 0x%2.2x", code);
+
+ if (!skb)
+ return;
+
+ hci_send_acl(conn->hcon, skb, 0);
+}
+
+int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
+{
+ __u8 authreq;
+
+ BT_DBG("conn %p hcon %p level 0x%2.2x", conn, conn->hcon, sec_level);
+
+ switch (sec_level) {
+ case BT_SECURITY_MEDIUM:
+ /* Encrypted, no MITM protection */
+ authreq = 0x01;
+ break;
+
+ case BT_SECURITY_HIGH:
+ /* Bonding, MITM protection */
+ authreq = 0x05;
+ break;
+
+ case BT_SECURITY_LOW:
+ default:
+ return 1;
+ }
+
+ if (conn->hcon->link_mode & HCI_LM_MASTER) {
+ struct smp_cmd_pairing cp;
+ cp.io_capability = 0x00;
+ cp.oob_flag = 0x00;
+ cp.max_key_size = 16;
+ cp.init_key_dist = 0x00;
+ cp.resp_key_dist = 0x00;
+ cp.auth_req = authreq;
+ smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
+ } else {
+ struct smp_cmd_security_req cp;
+ cp.auth_req = authreq;
+ smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp);
+ }
+
+ return 0;
+}
+
+int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
+{
+ __u8 code = skb->data[0];
+ __u8 reason;
+ int err = 0;
+
+ skb_pull(skb, 1);
+
+ switch (code) {
+ case SMP_CMD_PAIRING_REQ:
+ reason = SMP_PAIRING_NOTSUPP;
+ smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, 1, &reason);
+ err = -1;
+ break;
+
+ case SMP_CMD_PAIRING_FAIL:
+ break;
+
+ case SMP_CMD_PAIRING_RSP:
+ case SMP_CMD_PAIRING_CONFIRM:
+ case SMP_CMD_PAIRING_RANDOM:
+ case SMP_CMD_ENCRYPT_INFO:
+ case SMP_CMD_MASTER_IDENT:
+ case SMP_CMD_IDENT_INFO:
+ case SMP_CMD_IDENT_ADDR_INFO:
+ case SMP_CMD_SIGN_INFO:
+ case SMP_CMD_SECURITY_REQ:
+ default:
+ BT_DBG("Unknown command code 0x%2.2x", code);
+
+ reason = SMP_CMD_NOTSUPP;
+ smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, 1, &reason);
+ err = -1;
+ }
+
+ kfree_skb(skb);
+ return err;
+}
--
1.7.3.2
^ permalink raw reply related
* [RFC v2 3/9] Bluetooth: Start SMP procedure
From: Vinicius Costa Gomes @ 2010-12-06 21:43 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Anderson Briglia, Vinicius Costa Gomes
In-Reply-To: <1291671832-13435-1-git-send-email-vinicius.gomes@openbossa.org>
From: Anderson Briglia <anderson.briglia@openbossa.org>
Start SMP procedure for LE connections. This modification intercepts l2cap
received frames and call proper SMP functions to start the SMP procedure. By
now, no keys are being used.
Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
Signed-off-by: Anderson Briglia <anderson.briglia@openbossa.org>
---
net/bluetooth/l2cap_core.c | 7 +++++++
net/bluetooth/smp.c | 2 +-
2 files changed, 8 insertions(+), 1 deletions(-)
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 69e5f80..674799c 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -54,6 +54,7 @@
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
#include <net/bluetooth/l2cap.h>
+#include <net/bluetooth/smp.h>
#define VERSION "2.15"
@@ -642,6 +643,8 @@ static void l2cap_conn_ready(struct l2cap_conn *conn)
l2cap_sock_clear_timer(sk);
sk->sk_state = BT_CONNECTED;
sk->sk_state_change(sk);
+ if (smp_conn_security(conn, l2cap_pi(sk)->sec_level))
+ BT_DBG("Insufficient security");
}
if (sk->sk_type != SOCK_SEQPACKET &&
@@ -4626,6 +4629,10 @@ static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
l2cap_conless_channel(conn, psm, skb);
break;
+ case L2CAP_CID_SMP:
+ smp_sig_channel(conn, skb);
+ break;
+
default:
l2cap_data_channel(conn, cid, skb);
break;
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index e427d11..e9dde5f 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -86,7 +86,7 @@ int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
return 1;
}
- if (conn->hcon->link_mode & HCI_LM_MASTER) {
+ if (conn->hcon->out) {
struct smp_cmd_pairing cp;
cp.io_capability = 0x00;
cp.oob_flag = 0x00;
--
1.7.3.2
^ permalink raw reply related
* [RFC v2 4/9] Bluetooth: simple SMP pairing negotiation
From: Vinicius Costa Gomes @ 2010-12-06 21:43 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Anderson Briglia, Vinicius Costa Gomes
In-Reply-To: <1291671832-13435-1-git-send-email-vinicius.gomes@openbossa.org>
From: Anderson Briglia <anderson.briglia@openbossa.org>
This implementation only exchanges SMP messages between the Host and the
Remote. No keys are being generated. TK and STK generation will be
provided in further patches.
Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
---
net/bluetooth/l2cap_core.c | 3 +-
net/bluetooth/smp.c | 114 ++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 112 insertions(+), 5 deletions(-)
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 674799c..da4f13d 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -4630,7 +4630,8 @@ static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
break;
case L2CAP_CID_SMP:
- smp_sig_channel(conn, skb);
+ if (smp_sig_channel(conn, skb))
+ l2cap_conn_del(conn->hcon, 0x05);
break;
default:
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index e9dde5f..b25010f 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -64,6 +64,102 @@ static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data)
hci_send_acl(conn->hcon, skb, 0);
}
+static void smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
+{
+ struct smp_cmd_pairing *rp = (void *) skb->data;
+
+ BT_DBG("");
+
+ skb_pull(skb, sizeof(struct smp_cmd_pairing));
+
+ rp->io_capability = 0x00;
+ rp->oob_flag = 0x00;
+ rp->max_key_size = 16;
+ rp->init_key_dist = 0x00;
+ rp->resp_key_dist = 0x00;
+ rp->auth_req &= 0x05;
+
+ smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(*rp), rp);
+}
+
+static void smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
+{
+ struct smp_cmd_pairing_confirm cp;
+
+ BT_DBG("");
+
+ memset(&cp, 0, sizeof(struct smp_cmd_pairing_confirm));
+
+ smp_send_cmd(conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp);
+}
+
+static void smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb)
+{
+ BT_DBG("");
+
+ if (conn->hcon->out) {
+ struct smp_cmd_pairing_random random;
+
+ BT_DBG("master");
+
+ memset(&random, 0, sizeof(struct smp_cmd_pairing_random));
+
+ smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(random),
+ &random);
+ } else {
+ struct smp_cmd_pairing_confirm confirm;
+
+ BT_DBG("slave");
+
+ memset(&confirm, 0, sizeof(struct smp_cmd_pairing_confirm));
+
+ smp_send_cmd(conn, SMP_CMD_PAIRING_CONFIRM, sizeof(confirm),
+ &confirm);
+ }
+}
+
+static void smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
+{
+ struct smp_cmd_pairing_random cp;
+
+ BT_DBG("");
+
+ skb_pull(skb, sizeof(struct smp_cmd_pairing_random));
+
+ /* FIXME: check if random matches */
+
+ if (conn->hcon->out) {
+ BT_DBG("master");
+ /* FIXME: start encryption */
+ } else {
+ BT_DBG("slave");
+
+ memset(&cp, 0, sizeof(struct smp_cmd_pairing_random));
+
+ smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(cp), &cp);
+ }
+}
+
+static void smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
+{
+ struct smp_cmd_security_req *rp = (void *) skb->data;
+ struct smp_cmd_pairing cp;
+
+ BT_DBG("");
+
+ skb_pull(skb, sizeof(struct smp_cmd_security_req));
+ memset(&cp, 0, sizeof(struct smp_cmd_pairing));
+
+ cp.io_capability = 0x00;
+ cp.oob_flag = 0x00;
+ cp.max_key_size = 16;
+ cp.init_key_dist = 0x00;
+ cp.resp_key_dist = 0x00;
+ cp.auth_req = rp->auth_req & 0x05;
+
+ smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
+}
+
int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
{
__u8 authreq;
@@ -114,23 +210,33 @@ int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
switch (code) {
case SMP_CMD_PAIRING_REQ:
- reason = SMP_PAIRING_NOTSUPP;
- smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, 1, &reason);
- err = -1;
+ smp_cmd_pairing_req(conn, skb);
break;
case SMP_CMD_PAIRING_FAIL:
break;
case SMP_CMD_PAIRING_RSP:
+ smp_cmd_pairing_rsp(conn, skb);
+ break;
+
+ case SMP_CMD_SECURITY_REQ:
+ smp_cmd_security_req(conn, skb);
+ break;
+
case SMP_CMD_PAIRING_CONFIRM:
+ smp_cmd_pairing_confirm(conn, skb);
+ break;
+
case SMP_CMD_PAIRING_RANDOM:
+ smp_cmd_pairing_random(conn, skb);
+ break;
+
case SMP_CMD_ENCRYPT_INFO:
case SMP_CMD_MASTER_IDENT:
case SMP_CMD_IDENT_INFO:
case SMP_CMD_IDENT_ADDR_INFO:
case SMP_CMD_SIGN_INFO:
- case SMP_CMD_SECURITY_REQ:
default:
BT_DBG("Unknown command code 0x%2.2x", code);
--
1.7.3.2
^ permalink raw reply related
* [RFC v2 5/9] Bluetooth: Add support for using the crypto subsystem
From: Vinicius Costa Gomes @ 2010-12-06 21:43 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Vinicius Costa Gomes
In-Reply-To: <1291671832-13435-1-git-send-email-vinicius.gomes@openbossa.org>
This will allow using the crypto subsystem for encrypting data. As SMP
(Security Manager Protocol) is implemented almost entirely on the host
side and the crypto module already implements the needed methods
(AES-128), it makes sense to use it.
Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
---
include/net/bluetooth/hci_core.h | 2 ++
net/bluetooth/hci_core.c | 10 ++++++++++
2 files changed, 12 insertions(+), 0 deletions(-)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 0687e2f..d0a9f5d 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -135,6 +135,8 @@ struct hci_dev {
__u32 req_status;
__u32 req_result;
+ struct crypto_blkcipher *tfm;
+
struct inquiry_cache inq_cache;
struct hci_conn_hash conn_hash;
struct list_head blacklist;
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 12c6735..b96c3dd 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -41,6 +41,7 @@
#include <linux/interrupt.h>
#include <linux/notifier.h>
#include <linux/rfkill.h>
+#include <linux/crypto.h>
#include <net/sock.h>
#include <asm/system.h>
@@ -961,6 +962,13 @@ int hci_register_dev(struct hci_dev *hdev)
if (!hdev->workqueue)
goto nomem;
+ hdev->tfm = crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC);
+ if (IS_ERR(hdev->tfm)) {
+ BT_ERR("Failed to load transform for ecb(aes): %ld",
+ PTR_ERR(hdev->tfm));
+ goto nomem;
+ }
+
hci_register_sysfs(hdev);
hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
@@ -1001,6 +1009,8 @@ int hci_unregister_dev(struct hci_dev *hdev)
for (i = 0; i < NUM_REASSEMBLY; i++)
kfree_skb(hdev->reassembly[i]);
+ crypto_free_blkcipher(hdev->tfm);
+
hci_notify(hdev, HCI_DEV_UNREG);
if (hdev->rfkill) {
--
1.7.3.2
^ permalink raw reply related
* [RFC v2 6/9] Bluetooth: LE SMP Cryptoolbox functions
From: Vinicius Costa Gomes @ 2010-12-06 21:43 UTC (permalink / raw)
To: linux-bluetooth
Cc: Anderson Briglia, Anderson Lizardo, Bruna Moreira,
Vinicius Costa Gomes
In-Reply-To: <1291671832-13435-1-git-send-email-vinicius.gomes@openbossa.org>
From: Anderson Briglia <anderson.briglia@openbossa.org>
This patch implements SMP crypto functions called ah, c1, s1 and e.
It also implements auxiliary functions. All These functions are needed
for SMP keys generation.
Signed-off-by: Anderson Briglia <anderson.briglia@openbossa.org>
Signed-off-by: Anderson Lizardo <anderson.lizardo@openbossa.org>
Signed-off-by: Bruna Moreira <bruna.moreira@openbossa.org>
Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
---
net/bluetooth/smp.c | 133 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 133 insertions(+), 0 deletions(-)
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index b25010f..b62160e 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -24,6 +24,139 @@
#include <net/bluetooth/hci_core.h>
#include <net/bluetooth/l2cap.h>
#include <net/bluetooth/smp.h>
+#include <linux/crypto.h>
+#include <crypto/b128ops.h>
+
+static inline void swap128(u8 src[16], u8 dst[16])
+{
+ int i;
+ for (i = 0; i < 16; i++)
+ dst[15 - i] = src[i];
+}
+
+static inline void swap56(u8 src[7], u8 dst[7])
+{
+ int i;
+ for (i = 0; i < 7; i++)
+ dst[6 - i] = src[i];
+}
+
+static int smp_e(struct crypto_blkcipher *tfm, const u8 *k, u8 *r)
+{
+ struct blkcipher_desc desc;
+ struct scatterlist sg;
+ int err, iv_len;
+ unsigned char iv[128];
+
+ if (tfm == NULL) {
+ BT_ERR("tfm %p", tfm);
+ err = -1;
+ goto out;
+ }
+
+ desc.tfm = tfm;
+ desc.flags = 0;
+
+ err = crypto_blkcipher_setkey(tfm, k, 16);
+ if (err) {
+ BT_ERR("cipher setkey failed: %d", err);
+ goto out;
+ }
+
+ sg_init_one(&sg, r, 16);
+
+ iv_len = crypto_blkcipher_ivsize(tfm);
+ if (iv_len) {
+ memset(&iv, 0xff, iv_len);
+ crypto_blkcipher_set_iv(tfm, iv, iv_len);
+ }
+
+ err = crypto_blkcipher_encrypt(&desc, &sg, &sg, 16);
+ if (err)
+ BT_ERR("Encrypt data error %d", err);
+
+out:
+ return err;
+}
+
+static int smp_c1(struct crypto_blkcipher *tfm, u8 k[16], u8 r[16],
+ u8 preq[7], u8 pres[7], u8 _iat, bdaddr_t *ia,
+ u8 _rat, bdaddr_t *ra, u8 res[16])
+{
+ u8 p1[16], p2[16], pair[7];
+ bdaddr_t addr;
+ int err;
+
+ /* p1 = pres || preq || _rat || _iat */
+ memset(p1, 0, 16);
+ swap56(pres, pair);
+
+ memcpy(p1, pair, 7);
+ swap56(preq, pair);
+
+ memcpy(p1 + 7, pair, 7);
+ *(p1 + 14) = _rat;
+ *(p1 + 15) = _iat;
+
+ /* p2 = padding || ia || ra */
+ memset(p2, 0, 16);
+ baswap(&addr, ia);
+ memcpy(p2 + 4, &addr, 6);
+ baswap(&addr, ra);
+ memcpy(p2 + 10, &addr, 6);
+
+ /* res = r XOR p1 */
+ u128_xor((u128 *) res, (u128 *) r, (u128 *) p1);
+
+ /* res = e(k, res) */
+ err = smp_e(tfm, k, res);
+ if (err) {
+ BT_ERR("Encrypt data error");
+ goto out;
+ }
+
+ /* res = res XOR p2 */
+ u128_xor((u128 *) res, (u128 *) res, (u128 *) p2);
+
+ /* res = e(k, res) */
+ err = smp_e(tfm, k, res);
+ if (err) {
+ BT_ERR("Encrypt data error");
+ goto out;
+ }
+
+out:
+ return err;
+}
+
+static int smp_s1(struct crypto_blkcipher *tfm, u8 k[16],
+ u8 r1[16], u8 r2[16], u8 _r[16])
+{
+ u8 r[16];
+ int err;
+
+ /* Just least significant octets from r1 and r2 are considered */
+ swap128(r1, r);
+ memcpy(_r, r + 8, 8);
+ swap128(r2, r);
+ memcpy(_r + 8, r + 8, 8);
+
+ err = smp_e(tfm, k, _r);
+ if (err) {
+ BT_ERR("smp_s1: Encrypt data error");
+ goto out;
+ }
+
+out:
+ return err;
+}
+
+static int smp_rand(u8 *buf)
+{
+ get_random_bytes(buf, 16);
+
+ return 0;
+}
static struct sk_buff *smp_build_cmd(struct l2cap_conn *conn, u8 code,
u16 dlen, void *data)
--
1.7.3.2
^ permalink raw reply related
* [RFC v2 7/9] Bluetooth: Add support for SMP confirmation checks
From: Vinicius Costa Gomes @ 2010-12-06 21:43 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Vinicius Costa Gomes
In-Reply-To: <1291671832-13435-1-git-send-email-vinicius.gomes@openbossa.org>
This adds supports for verifying the confirmation value that the
remote side has sent. This includes support for generating and sending
the random value used to produce the confirmation value.
Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
---
include/net/bluetooth/l2cap.h | 5 ++
net/bluetooth/smp.c | 121 ++++++++++++++++++++++++++++++++---------
2 files changed, 101 insertions(+), 25 deletions(-)
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index a3cb1ab..bcda2aa 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -290,6 +290,11 @@ struct l2cap_conn {
__u8 disc_reason;
+ __u8 preq[7];
+ __u8 pres[7];
+ __u8 prnd[16];
+ __u8 pcnf[16];
+
struct l2cap_chan_list chan_list;
};
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index b62160e..7d7e8ad 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -203,7 +203,9 @@ static void smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
BT_DBG("");
- skb_pull(skb, sizeof(struct smp_cmd_pairing));
+ conn->preq[0] = SMP_CMD_PAIRING_REQ;
+ memcpy(&conn->preq[1], rp, sizeof(*rp));
+ skb_pull(skb, sizeof(*rp));
rp->io_capability = 0x00;
rp->oob_flag = 0x00;
@@ -212,64 +214,125 @@ static void smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
rp->resp_key_dist = 0x00;
rp->auth_req &= 0x05;
+ conn->pres[0] = SMP_CMD_PAIRING_RSP;
+ memcpy(&conn->pres[1], rp, sizeof(rp));
+
smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(*rp), rp);
}
static void smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
{
+ struct smp_cmd_pairing *rp = (void *) skb->data;
struct smp_cmd_pairing_confirm cp;
+ struct crypto_blkcipher *tfm = conn->hcon->hdev->tfm;
+ int ret;
+ u8 k[16], res[16];
- BT_DBG("");
+ /* Just Works */
+ memset(k, 0, sizeof(k));
+
+ conn->pres[0] = SMP_CMD_PAIRING_RSP;
+ memcpy(&conn->pres[1], rp, sizeof(*rp));
+ skb_pull(skb, sizeof(*rp));
+
+ ret = smp_rand(conn->prnd);
+ if (ret)
+ return;
- memset(&cp, 0, sizeof(struct smp_cmd_pairing_confirm));
+ ret = smp_c1(tfm, k, conn->prnd, conn->preq, conn->pres, 0,
+ conn->src, 0, conn->dst, res);
+ if (ret)
+ return;
+
+ swap128(res, cp.confirm_val);
smp_send_cmd(conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp);
}
static void smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb)
{
+ struct crypto_blkcipher *tfm = conn->hcon->hdev->tfm;
+
BT_DBG("");
- if (conn->hcon->out) {
- struct smp_cmd_pairing_random random;
+ memcpy(conn->pcnf, skb->data, 16);
+ skb_pull(skb, 16);
- BT_DBG("master");
+ if (conn->hcon->out) {
+ u8 random[16];
- memset(&random, 0, sizeof(struct smp_cmd_pairing_random));
+ swap128(conn->prnd, random);
- smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(random),
- &random);
+ smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, 16, random);
} else {
- struct smp_cmd_pairing_confirm confirm;
+ struct smp_cmd_pairing_confirm cp;
+ int ret;
+ u8 k[16], res[16];
+
+ /* Just Works */
+ memset(k, 0, sizeof(k));
- BT_DBG("slave");
+ ret = smp_rand(conn->prnd);
+ if (ret)
+ return;
- memset(&confirm, 0, sizeof(struct smp_cmd_pairing_confirm));
+ ret = smp_c1(tfm, k, conn->prnd, conn->preq, conn->pres, 0,
+ conn->dst, 0, conn->src, res);
+ if (ret)
+ return;
- smp_send_cmd(conn, SMP_CMD_PAIRING_CONFIRM, sizeof(confirm),
- &confirm);
+ swap128(res, cp.confirm_val);
+
+ smp_send_cmd(conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp);
}
}
static void smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
{
- struct smp_cmd_pairing_random cp;
+ struct crypto_blkcipher *tfm = conn->hcon->hdev->tfm;
+ int ret;
+ u8 k[16], key[16], res[16], random[16], confirm[16], buf[128];
+
+ swap128(skb->data, random);
+ skb_pull(skb, 16);
+
+ memset(k, 0, sizeof(k));
+
+ if (conn->hcon->out)
+ ret = smp_c1(tfm, k, random, conn->preq, conn->pres, 0,
+ conn->src, 0, conn->dst, res);
+ else
+ ret = smp_c1(tfm, k, random, conn->preq, conn->pres, 0,
+ conn->dst, 0, conn->src, res);
+ if (ret)
+ return;
- BT_DBG("");
+ swap128(res, confirm);
- skb_pull(skb, sizeof(struct smp_cmd_pairing_random));
+ if (memcmp(conn->pcnf, confirm, 16) != 0) {
+ struct smp_cmd_pairing_fail cp;
- /* FIXME: check if random matches */
+ BT_ERR("Pairing failed (confirmation values mismatch)");
+ cp.reason = SMP_CONFIRM_FAILED;
+ smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(cp), &cp);
+ return;
+ }
if (conn->hcon->out) {
- BT_DBG("master");
- /* FIXME: start encryption */
+ smp_s1(tfm, k, random, conn->prnd, key);
+
+ hex_dump_to_buffer(key, sizeof(key), 16, 1, buf, sizeof(buf), 0);
+ BT_DBG("key %s", buf);
} else {
- BT_DBG("slave");
+ u8 r[16];
- memset(&cp, 0, sizeof(struct smp_cmd_pairing_random));
+ swap128(conn->prnd, r);
+ smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, 16, r);
- smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(cp), &cp);
+ smp_s1(tfm, k, conn->prnd, random, key);
+
+ hex_dump_to_buffer(key, sizeof(key), 16, 1, buf, sizeof(buf), 0);
+ BT_DBG("key %s", buf);
}
}
@@ -280,8 +343,9 @@ static void smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
BT_DBG("");
- skb_pull(skb, sizeof(struct smp_cmd_security_req));
- memset(&cp, 0, sizeof(struct smp_cmd_pairing));
+ skb_pull(skb, sizeof(*rp));
+
+ memset(&cp, 0, sizeof(cp));
cp.io_capability = 0x00;
cp.oob_flag = 0x00;
@@ -290,6 +354,9 @@ static void smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
cp.resp_key_dist = 0x00;
cp.auth_req = rp->auth_req & 0x05;
+ conn->preq[0] = SMP_CMD_PAIRING_REQ;
+ memcpy(&conn->preq[1], &cp, sizeof(cp));
+
smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
}
@@ -323,6 +390,10 @@ int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
cp.init_key_dist = 0x00;
cp.resp_key_dist = 0x00;
cp.auth_req = authreq;
+
+ conn->preq[0] = SMP_CMD_PAIRING_REQ;
+ memcpy(&conn->preq[1], &cp, sizeof(cp));
+
smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
} else {
struct smp_cmd_security_req cp;
--
1.7.3.2
^ permalink raw reply related
* [RFC v2 8/9] Bluetooth: Add support for LE Start Encryption
From: Vinicius Costa Gomes @ 2010-12-06 21:43 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Vinicius Costa Gomes
In-Reply-To: <1291671832-13435-1-git-send-email-vinicius.gomes@openbossa.org>
This adds support for starting SMP Phase 2 Encryption, when the initial
SMP negotiation is successful. This adds the LE Start Encryption and LE
Long Term Key Request commands and related events.
Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
---
include/net/bluetooth/hci.h | 34 +++++++++++++++++++
include/net/bluetooth/hci_core.h | 5 +++
net/bluetooth/hci_conn.c | 47 ++++++++++++++++++++++++++
net/bluetooth/hci_event.c | 67 ++++++++++++++++++++++++++++++++++++++
net/bluetooth/smp.c | 8 ++++-
5 files changed, 160 insertions(+), 1 deletions(-)
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index dff6ded..e6bed3f 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -626,6 +626,33 @@ struct hci_cp_le_create_conn {
#define HCI_OP_LE_CREATE_CONN_CANCEL 0x200e
+#define HCI_OP_LE_START_ENC 0x2019
+struct hci_cp_le_start_enc {
+ __le16 handle;
+ __u8 rand[8];
+ __le16 ediv;
+ __u8 ltk[16];
+} __packed;
+
+#define HCI_OP_LE_LTK_REPLY 0x201a
+struct hci_cp_le_ltk_reply {
+ __le16 handle;
+ __u8 ltk[16];
+} __packed;
+struct hci_rp_le_ltk_reply {
+ __u8 status;
+ __le16 handle;
+} __packed;
+
+#define HCI_OP_LE_LTK_NEG_REPLY 0x201b
+struct hci_cp_le_ltk_neg_reply {
+ __le16 handle;
+} __packed;
+struct hci_rp_le_ltk_neg_reply {
+ __u8 status;
+ __le16 handle;
+} __packed;
+
/* ---- HCI Events ---- */
#define HCI_EV_INQUIRY_COMPLETE 0x01
@@ -897,6 +924,13 @@ struct hci_ev_le_conn_complete {
__u8 clk_accurancy;
} __packed;
+#define HCI_EV_LE_LTK_REQ 0x05
+struct hci_ev_le_ltk_req {
+ __le16 handle;
+ __u8 random[8];
+ __le16 ediv;
+} __packed;
+
/* Internal events generated by Bluetooth stack */
#define HCI_EV_STACK_INTERNAL 0xfd
struct hci_ev_stack_internal {
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index d0a9f5d..c6c44eb 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -192,6 +192,7 @@ struct hci_conn {
__u8 sec_level;
__u8 power_save;
__u16 disc_timeout;
+ __u8 ltk[16];
unsigned long pend;
unsigned int sent;
@@ -713,4 +714,8 @@ struct hci_sec_filter {
void hci_req_complete(struct hci_dev *hdev, int result);
+void hci_le_start_enc(struct hci_conn *conn, u8 ltk[16]);
+void hci_le_ltk_reply(struct hci_conn *conn, u8 ltk[16]);
+void hci_le_ltk_neg_reply(struct hci_conn *conn);
+
#endif /* __HCI_CORE_H */
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index edfb48b..f919ddb 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -183,6 +183,53 @@ void hci_setup_sync(struct hci_conn *conn, __u16 handle)
hci_send_cmd(hdev, HCI_OP_SETUP_SYNC_CONN, sizeof(cp), &cp);
}
+void hci_le_start_enc(struct hci_conn *conn, u8 ltk[16])
+{
+ struct hci_dev *hdev = conn->hdev;
+ struct hci_cp_le_start_enc cp;
+
+ BT_DBG("%p", conn);
+
+ memset(&cp, 0, sizeof(cp));
+
+ cp.handle = cpu_to_le16(conn->handle);
+ memcpy(cp.ltk, ltk, 16);
+
+ hci_send_cmd(hdev, HCI_OP_LE_START_ENC, sizeof(cp), &cp);
+}
+EXPORT_SYMBOL(hci_le_start_enc);
+
+void hci_le_ltk_reply(struct hci_conn *conn, u8 ltk[16])
+{
+ struct hci_dev *hdev = conn->hdev;
+ struct hci_cp_le_ltk_reply cp;
+
+ BT_DBG("%p", conn);
+
+ memset(&cp, 0, sizeof(cp));
+
+ cp.handle = cpu_to_le16(conn->handle);
+ memcpy(&cp.ltk, ltk, sizeof(ltk));
+
+ hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
+}
+EXPORT_SYMBOL(hci_le_ltk_reply);
+
+void hci_le_ltk_neg_reply(struct hci_conn *conn)
+{
+ struct hci_dev *hdev = conn->hdev;
+ struct hci_cp_le_ltk_neg_reply cp;
+
+ BT_DBG("%p", conn);
+
+ memset(&cp, 0, sizeof(cp));
+
+ cp.handle = cpu_to_le16(conn->handle);
+
+ hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(cp), &cp);
+}
+EXPORT_SYMBOL(hci_le_ltk_neg_reply);
+
/* Device _must_ be locked */
void hci_sco_setup(struct hci_conn *conn, __u8 status)
{
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 55cdd6a..c90696f 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -559,6 +559,30 @@ static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
hci_req_complete(hdev, rp->status);
}
+static void hci_cc_le_ltk_reply(struct hci_dev *hdev, struct sk_buff *skb)
+{
+ struct hci_rp_le_ltk_reply *rp = (void *) skb->data;
+
+ BT_DBG("%s status 0x%x", hdev->name, rp->status);
+
+ if (rp->status)
+ return;
+
+ hci_req_complete(hdev, rp->status);
+}
+
+static void hci_cc_le_ltk_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
+{
+ struct hci_rp_le_ltk_neg_reply *rp = (void *) skb->data;
+
+ BT_DBG("%s status 0x%x", hdev->name, rp->status);
+
+ if (rp->status)
+ return;
+
+ hci_req_complete(hdev, rp->status);
+}
+
static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
{
BT_DBG("%s status 0x%x", hdev->name, status);
@@ -920,6 +944,11 @@ static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status)
hci_dev_unlock(hdev);
}
+static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status)
+{
+ BT_DBG("%s status 0x%x", hdev->name, status);
+}
+
static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
__u8 status = *((__u8 *) skb->data);
@@ -1440,6 +1469,14 @@ static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *sk
hci_cc_le_read_buffer_size(hdev, skb);
break;
+ case HCI_OP_LE_LTK_REPLY:
+ hci_cc_le_ltk_reply(hdev, skb);
+ break;
+
+ case HCI_OP_LE_LTK_NEG_REPLY:
+ hci_cc_le_ltk_neg_reply(hdev, skb);
+ break;
+
default:
BT_DBG("%s opcode 0x%x", hdev->name, opcode);
break;
@@ -1510,6 +1547,10 @@ static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
hci_cs_le_create_conn(hdev, ev->status);
break;
+ case HCI_OP_LE_START_ENC:
+ hci_cs_le_start_enc(hdev, ev->status);
+ break;
+
default:
BT_DBG("%s opcode 0x%x", hdev->name, opcode);
break;
@@ -2013,6 +2054,28 @@ unlock:
hci_dev_unlock(hdev);
}
+static inline void hci_le_ltk_request_evt(struct hci_dev *hdev,
+ struct sk_buff *skb)
+{
+ struct hci_ev_le_ltk_req *ev = (void *) skb->data;
+ struct hci_cp_le_ltk_reply cp;
+ struct hci_conn *conn;
+
+ BT_DBG("%s handle %d", hdev->name, cpu_to_le16(ev->handle));
+
+ hci_dev_lock(hdev);
+
+ conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
+
+ memset(&cp, 0, sizeof(cp));
+ cp.handle = cpu_to_le16(conn->handle);
+ memcpy(cp.ltk, conn->ltk, sizeof(conn->ltk));
+
+ hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
+
+ hci_dev_unlock(hdev);
+}
+
static inline void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
struct hci_ev_le_meta *le_ev = (void *) skb->data;
@@ -2024,6 +2087,10 @@ static inline void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
hci_le_conn_complete_evt(hdev, skb);
break;
+ case HCI_EV_LE_LTK_REQ:
+ hci_le_ltk_request_evt(hdev, skb);
+ break;
+
default:
break;
}
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 7d7e8ad..d19b8a2 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -289,7 +289,8 @@ static void smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb
static void smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
{
- struct crypto_blkcipher *tfm = conn->hcon->hdev->tfm;
+ struct hci_conn *hcon = conn->hcon;
+ struct crypto_blkcipher *tfm = hcon->hdev->tfm;
int ret;
u8 k[16], key[16], res[16], random[16], confirm[16], buf[128];
@@ -297,6 +298,7 @@ static void smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
skb_pull(skb, 16);
memset(k, 0, sizeof(k));
+ memset(hcon->ltk, 0, sizeof(hcon->ltk));
if (conn->hcon->out)
ret = smp_c1(tfm, k, random, conn->preq, conn->pres, 0,
@@ -320,6 +322,9 @@ static void smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
if (conn->hcon->out) {
smp_s1(tfm, k, random, conn->prnd, key);
+ swap128(key, hcon->ltk);
+
+ hci_le_start_enc(conn->hcon, hcon->ltk);
hex_dump_to_buffer(key, sizeof(key), 16, 1, buf, sizeof(buf), 0);
BT_DBG("key %s", buf);
@@ -330,6 +335,7 @@ static void smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, 16, r);
smp_s1(tfm, k, conn->prnd, random, key);
+ swap128(key, hcon->ltk);
hex_dump_to_buffer(key, sizeof(key), 16, 1, buf, sizeof(buf), 0);
BT_DBG("key %s", buf);
--
1.7.3.2
^ permalink raw reply related
* [RFC v2 9/9] Bluetooth: Add support for resuming socket when SMP is finished
From: Vinicius Costa Gomes @ 2010-12-06 21:43 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Vinicius Costa Gomes
In-Reply-To: <1291671832-13435-1-git-send-email-vinicius.gomes@openbossa.org>
This adds support for resuming the user space traffic when SMP
negotiation is complete.
Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
---
net/bluetooth/l2cap_core.c | 72 +++++++++++++++++++++++++------------------
net/bluetooth/smp.c | 9 +++++
2 files changed, 51 insertions(+), 30 deletions(-)
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index da4f13d..061248f 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -624,6 +624,22 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
}
}
+static void l2cap_chan_ready(struct sock *sk)
+{
+ struct sock *parent = bt_sk(sk)->parent;
+
+ BT_DBG("sk %p, parent %p", sk, parent);
+
+ l2cap_pi(sk)->conf_state = 0;
+ l2cap_sock_clear_timer(sk);
+
+ sk->sk_state = BT_CONNECTED;
+ sk->sk_state_change(sk);
+
+ if (parent)
+ parent->sk_data_ready(parent, 0);
+}
+
static void l2cap_conn_ready(struct l2cap_conn *conn)
{
struct l2cap_chan_list *l = &conn->chan_list;
@@ -640,14 +656,10 @@ static void l2cap_conn_ready(struct l2cap_conn *conn)
bh_lock_sock(sk);
if (conn->hcon->type == LE_LINK) {
- l2cap_sock_clear_timer(sk);
- sk->sk_state = BT_CONNECTED;
- sk->sk_state_change(sk);
if (smp_conn_security(conn, l2cap_pi(sk)->sec_level))
- BT_DBG("Insufficient security");
- }
+ l2cap_chan_ready(sk);
- if (sk->sk_type != SOCK_SEQPACKET &&
+ } else if (sk->sk_type != SOCK_SEQPACKET &&
sk->sk_type != SOCK_STREAM) {
l2cap_sock_clear_timer(sk);
sk->sk_state = BT_CONNECTED;
@@ -1199,7 +1211,7 @@ static int l2cap_do_connect(struct sock *sk)
sk->sk_type != SOCK_STREAM) {
l2cap_sock_clear_timer(sk);
sk->sk_state = BT_CONNECTED;
- } else
+ } else if (hcon->type == ACL_LINK)
l2cap_do_start(sk);
}
@@ -2162,6 +2174,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch
{
struct sock *sk = sock->sk;
struct bt_security sec;
+ struct l2cap_conn *conn;
int len, err = 0;
u32 opt;
@@ -2198,6 +2211,18 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch
}
l2cap_pi(sk)->sec_level = sec.level;
+
+ conn = l2cap_pi(sk)->conn;
+ if (conn && conn->hcon->type == LE_LINK) {
+ if (!conn->hcon->out) {
+ err = -EINVAL;
+ break;
+ }
+
+ sk->sk_state = BT_CONFIG;
+ smp_conn_security(conn, sec.level);
+ }
+
break;
case BT_DEFER_SETUP:
@@ -2410,29 +2435,6 @@ static int l2cap_sock_release(struct socket *sock)
return err;
}
-static void l2cap_chan_ready(struct sock *sk)
-{
- struct sock *parent = bt_sk(sk)->parent;
-
- BT_DBG("sk %p, parent %p", sk, parent);
-
- l2cap_pi(sk)->conf_state = 0;
- l2cap_sock_clear_timer(sk);
-
- if (!parent) {
- /* Outgoing channel.
- * Wake up socket sleeping on connect.
- */
- sk->sk_state = BT_CONNECTED;
- sk->sk_state_change(sk);
- } else {
- /* Incoming channel.
- * Wake up socket sleeping on accept.
- */
- parent->sk_data_ready(parent, 0);
- }
-}
-
/* Copy frame to all raw sockets on that connection */
static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
{
@@ -4753,6 +4755,16 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
bh_lock_sock(sk);
+ if (l2cap_pi(sk)->scid == L2CAP_CID_LE_DATA) {
+ if (!status && encrypt) {
+ l2cap_pi(sk)->sec_level = BT_SECURITY_MEDIUM;
+ l2cap_chan_ready(sk);
+ }
+
+ bh_unlock_sock(sk);
+ continue;
+ }
+
if (l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND) {
bh_unlock_sock(sk);
continue;
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index d19b8a2..c7a0e63 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -346,9 +346,13 @@ static void smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
{
struct smp_cmd_security_req *rp = (void *) skb->data;
struct smp_cmd_pairing cp;
+ struct hci_conn *hcon = conn->hcon;
BT_DBG("");
+ if (test_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend))
+ return;
+
skb_pull(skb, sizeof(*rp));
memset(&cp, 0, sizeof(cp));
@@ -364,10 +368,13 @@ static void smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
memcpy(&conn->preq[1], &cp, sizeof(cp));
smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
+
+ set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend);
}
int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
{
+ struct hci_conn *hcon = conn->hcon;
__u8 authreq;
BT_DBG("conn %p hcon %p level 0x%2.2x", conn, conn->hcon, sec_level);
@@ -407,6 +414,8 @@ int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp);
}
+ set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend);
+
return 0;
}
--
1.7.3.2
^ permalink raw reply related
* Re: [PATCH 5/9] mfd: Add UART support for the ST-Ericsson CG2900.
From: Arnd Bergmann @ 2010-12-06 23:07 UTC (permalink / raw)
To: Vitaly Wool
Cc: Par-Gunnar Hjalmdahl, Alan Cox, linus.walleij, linux-bluetooth,
linux-kernel, Marcel Holtmann
In-Reply-To: <AANLkTin_VOjz=bGCnANgp8G2SFFFOkT3TKRh50p5L1Gj@mail.gmail.com>
On Monday 06 December 2010 22:24:34 Vitaly Wool wrote:
> On Mon, Dec 6, 2010 at 5:54 PM, Arnd Bergmann <arnd@arndb.de> wrote:
>
> >> But I was trying to make a different point here. On a basic level,
> >> there's this cg2000 chip from STE that does BT, FM and GPS. There's
> >> the chip from TI that does BT, FM and GPS, and there's the Broadcom
> >> chip that does BT+FM. They all use HCI to access the other functions
> >> of the combo chip and they do it in a really simiar way, with the
> >> differences mostly in power management techniques. So I think it's
> >> quite sensible to have some kind of framework that is suitable for
> >> such devices.
> >
> > Yes, I agree 100% in principle. I could not find the code that
> > Broadcom/TI FM and GPS stuff so far, can you point us to that?
>
> Sure, the TI "shared transport" code is mostly at drivers/misc/ti-st.
>
> Some Broadcom BCM43xx chips work in a similar way AFAIK but I'm not
> sure about the mainline support for those.
Ah, it had not occured to me to look in drivers/misc. Looking at the
code over there, it becomes much clearer what your point is. Evidently
the ti-st driver implements a line discipline similar to, but conflicting
with hci_ldisc, and it has its own copy of the hci_ll code.
I guess this is exactly what we're trying to avoid having with the
cg2900 code ;-).
> > The cg2900 solution for this was to use MFD (plus another layer
> > in the posted version, but that will go away I assume). Using
> > MFD is not the only possibility here, but I could not see anything
> > wrong with it either. Do you think we can move them all over to
> > use MFD infrastructure?
>
> I guess so but it's probably more of a detail than what I'm up to now :)
Agreed.
> >> But generally speaking, isn't a line discipline/driver attached to a
> >> tty? We can use dumb tty for e. g. SPI and still be able to use
> >> hci_ll, right?
> >
> > I suggested that as well, but the point was made that this would
> > add an unnecessary indirection for the SPI case, which is not
> > really much like a serial port. It's certainly possible to do it
> > like you say, but if we add a way to register the high-level
> > protocols with an HCI-like multi-function device, we could
> > also do it in a way that does not rely on tty-ldisc but keeps it
> > as one of the options.
>
> I actually don't think it's such a big indirection, I prefer to think
> of it more as of the abstraction layer. If not use this, are we going
> to have direct SPI device drivers? I'm afraid we might end up with a
> huge duplication of code in that case.
The question is how it should be modeled in a better way than today.
I believe we already agree it should be something like
bt ti-radio st-e-radio ti-gps st-e-gps broadcom-radio ...
| | | | | | |
+---------+----------+---------+--+----------+----------+---------+
|
common-hci-module
|
+-----------+-----------+
| | | |
serial spi i2c ...
Any objections to this?
If you agree, I think we should discuss the alternatives for the common
module. I think you are saying we should make the common module a single
ldisc doing the multiplexing and have all transports register as ttys into
it, right?
What we discussed before was to split it into multiple modules, one for
the tty ldisc and one for the common code, and then have the spi/i2c/...
drivers feed into the common multiplexer without going through tty.
I don't currently see a significant advantage or disadvantage with either
approach.
Arnd
^ permalink raw reply
* EVT_NUM_COMP_PKTS and LE, GATT and SM
From: Brian Gix @ 2010-12-07 0:35 UTC (permalink / raw)
To: linux-bluetooth
Hi All,
I've have encountered a problem while using the gatttool, where my write
commands get clobbered by the LE ACL being disconnected prior to the ATT
(fixed channel 4) WRITE_CMD being sent over the LE based ACL link.
I believe this is fundamentally due to there being no dependency on the
EVT_NUM_COMP_PKTS event when gatttool decides that the WRITE_CMD has been
successfully sent. There is multiple parts to this.
1. In User space, the WRITE_CMD pkt is written to the socket. Gatttool
erroneously considers a successful socket write as completion, disconnects
the socket and exits.
2. In Kernel space, the ACL packet is added to an ACL queue, which is
separate from the CMD queue, which can allow either the Disconnect request,
or the ACL packet to be sent over the H4 link to the baseband.
3. In the baseband, due to LE clocking (and possible other baseband
activity) the ACL packet could be received first, and the Disconnect CMD
second, and still result in the connection being detached prior to Tx of the
ACL packet containing the ATT WRITE_CMD.
This is not an issue with any of the ATT READ/FIND/MTU or WRITE_REQ
transactions, because they require a response from the server. I believe
for ATT, this problem is restricted to the WRITE_CMD only, due to it's
unacknowledged nature.
However, this will also be an issue with the LE Security Manager, because as
stated in the Core Spec v4.0, Vol 3, in the last paragraph of 3.6.1 Key
Distribution on page 630 (of 656):
> Key distribution is complete in the device sending the final key
when it receives
> the baseband acknowledgement for that key and is complete in the
receiving
> device when it receives the final key being distributed.
This is intended to prevent exactly the kind of problem I am experiencing
with the ATT WRITE_CMD, and the acknowledgement from the baseband can only
be the EVT_NUM_COMP_PKTS event.
While talking to my colleagues here, we were thinking that the cleanest
method to get this accomplished would be by using the "select" method with
the ATT socket, where the socket could be marked as non-writable by the
kernel driver until the EVT_NUM_COMP_PKTS is received. The User space code
could then wait for the socket to become writeable before issuing the socket
disconnect.
If the Security manager is totally within the kernel, it probably does not
have to do as much work, however it does still need to wait on the
EVT_NUM_COMP_PKTS before disconnecting the remote device.
Has anybody else observed this issue with ATT WRITE_CMD? It could be getting
exacerbated by slow (115Kbps) H4 links that I am using, however the hcidump
tool confirms that the disconnect happens prior to the EVT_NUM_COMP_PKTS.
Brian Gix
bgix@codeaurora.org
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum
^ permalink raw reply
* RE: EVT_NUM_COMP_PKTS and LE, GATT and SM
From: Brian Gix @ 2010-12-07 0:46 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <002501cb95a6$b350fc50$19f2f4f0$@org>
Additional point--
> -----Original Message-----
> From: linux-bluetooth-owner@vger.kernel.org [mailto:linux-bluetooth-
> owner@vger.kernel.org] On Behalf Of Brian Gix
> Sent: 06 December, 2010 4:36 PM
> To: linux-bluetooth@vger.kernel.org
> Subject: EVT_NUM_COMP_PKTS and LE, GATT and SM
>
> Hi All,
>
> I've have encountered a problem while using the gatttool, where my
> write
> commands get clobbered by the LE ACL being disconnected prior to the
> ATT
> (fixed channel 4) WRITE_CMD being sent over the LE based ACL link.
>
> I believe this is fundamentally due to there being no dependency on the
> EVT_NUM_COMP_PKTS event when gatttool decides that the WRITE_CMD has
> been
> successfully sent. There is multiple parts to this.
>
> 1. In User space, the WRITE_CMD pkt is written to the socket. Gatttool
> erroneously considers a successful socket write as completion,
> disconnects
> the socket and exits.
>
> 2. In Kernel space, the ACL packet is added to an ACL queue, which is
> separate from the CMD queue, which can allow either the Disconnect
> request,
> or the ACL packet to be sent over the H4 link to the baseband.
>
> 3. In the baseband, due to LE clocking (and possible other baseband
> activity) the ACL packet could be received first, and the Disconnect
> CMD
> second, and still result in the connection being detached prior to Tx
> of the
> ACL packet containing the ATT WRITE_CMD.
>
> This is not an issue with any of the ATT READ/FIND/MTU or WRITE_REQ
> transactions, because they require a response from the server. I
> believe
> for ATT, this problem is restricted to the WRITE_CMD only, due to it's
> unacknowledged nature.
>
> However, this will also be an issue with the LE Security Manager,
> because as
> stated in the Core Spec v4.0, Vol 3, in the last paragraph of 3.6.1 Key
> Distribution on page 630 (of 656):
>
> > Key distribution is complete in the device sending the final
> key
> when it receives
> > the baseband acknowledgement for that key and is complete in
> the
> receiving
> > device when it receives the final key being distributed.
>
> This is intended to prevent exactly the kind of problem I am
> experiencing
> with the ATT WRITE_CMD, and the acknowledgement from the baseband can
> only
> be the EVT_NUM_COMP_PKTS event.
>
> While talking to my colleagues here, we were thinking that the cleanest
> method to get this accomplished would be by using the "select" method
> with the ATT socket, where the socket could be marked as non-writable
> by the kernel driver until the EVT_NUM_COMP_PKTS is received. The User
> space code could then wait for the socket to become writeable before
> issuing the socket disconnect.
This solution could be isolated to LE links (and perhaps even fixed
channel 4) because of the strict cmd-resp nature of ATT transactions.
This would cause the inability to queue multiple WRITE_CMDS before
disconnecting however.
> If the Security manager is totally within the kernel, it probably does
> not
> have to do as much work, however it does still need to wait on the
> EVT_NUM_COMP_PKTS before disconnecting the remote device.
>
> Has anybody else observed this issue with ATT WRITE_CMD? It could be
> getting
> exacerbated by slow (115Kbps) H4 links that I am using, however the
> hcidump
> tool confirms that the disconnect happens prior to the
> EVT_NUM_COMP_PKTS.
>
>
>
> Brian Gix
> bgix@codeaurora.org
> Employee of Qualcomm Innovation Center, Inc.
> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum
>
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-
> bluetooth" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* add NULL pointer check in hci
From: Jun Nie @ 2010-12-07 6:16 UTC (permalink / raw)
To: Vinicius Costa Gomes; +Cc: Brian Gix, linux-bluetooth
[-- Attachment #1: Type: text/plain, Size: 839 bytes --]
>From 6e396f74efeb13e468804c19249424cb3a5f93d8 Mon Sep 17 00:00:00 2001
From: Jun Nie <njun@marvell.com>
Date: Tue, 7 Dec 2010 14:03:38 +0800
Subject: [PATCH] bluetooth: add NULL pointer check in hci
Signed-off-by: Jun Nie <njun@marvell.com>
---
drivers/bluetooth/hci_ldisc.c | 6 ++++--
1 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
index 7201482..b58936c 100644
--- a/drivers/bluetooth/hci_ldisc.c
+++ b/drivers/bluetooth/hci_ldisc.c
@@ -311,8 +311,10 @@ static void hci_uart_tty_close(struct tty_struct *tty)
if (test_and_clear_bit(HCI_UART_PROTO_SET, &hu->flags)) {
hu->proto->close(hu);
- hci_unregister_dev(hdev);
- hci_free_dev(hdev);
+ if(hdev) {
+ hci_unregister_dev(hdev);
+ hci_free_dev(hdev);
+ }
}
}
}
--
1.7.0.4
[-- Attachment #2: 0001-bluetooth-add-NULL-pointer-check-in-hci.patch --]
[-- Type: text/x-diff, Size: 840 bytes --]
From 6e396f74efeb13e468804c19249424cb3a5f93d8 Mon Sep 17 00:00:00 2001
From: Jun Nie <njun@marvell.com>
Date: Tue, 7 Dec 2010 14:03:38 +0800
Subject: [PATCH] bluetooth: add NULL pointer check in hci
Signed-off-by: Jun Nie <njun@marvell.com>
---
drivers/bluetooth/hci_ldisc.c | 6 ++++--
1 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
index 7201482..b58936c 100644
--- a/drivers/bluetooth/hci_ldisc.c
+++ b/drivers/bluetooth/hci_ldisc.c
@@ -311,8 +311,10 @@ static void hci_uart_tty_close(struct tty_struct *tty)
if (test_and_clear_bit(HCI_UART_PROTO_SET, &hu->flags)) {
hu->proto->close(hu);
- hci_unregister_dev(hdev);
- hci_free_dev(hdev);
+ if(hdev) {
+ hci_unregister_dev(hdev);
+ hci_free_dev(hdev);
+ }
}
}
}
--
1.7.0.4
^ permalink raw reply related
* [PATCH 1/1] bluetooth: add NULL pointer check in hci
From: Jun Nie @ 2010-12-07 7:01 UTC (permalink / raw)
To: Vinicius Costa Gomes; +Cc: Brian Gix, linux-bluetooth
[-- Attachment #1: Type: text/plain, Size: 40 bytes --]
Resend it to fix checkpatch.pl warning.
[-- Attachment #2: 0001-bluetooth-add-NULL-pointer-check-in-hci.patch --]
[-- Type: text/x-diff, Size: 841 bytes --]
From 75dc111b5d9f62619bbeec803b15e84412ae050e Mon Sep 17 00:00:00 2001
From: Jun Nie <njun@marvell.com>
Date: Tue, 7 Dec 2010 14:03:38 +0800
Subject: [PATCH] bluetooth: add NULL pointer check in hci
Signed-off-by: Jun Nie <njun@marvell.com>
---
drivers/bluetooth/hci_ldisc.c | 6 ++++--
1 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
index 7201482..3c6cabc 100644
--- a/drivers/bluetooth/hci_ldisc.c
+++ b/drivers/bluetooth/hci_ldisc.c
@@ -311,8 +311,10 @@ static void hci_uart_tty_close(struct tty_struct *tty)
if (test_and_clear_bit(HCI_UART_PROTO_SET, &hu->flags)) {
hu->proto->close(hu);
- hci_unregister_dev(hdev);
- hci_free_dev(hdev);
+ if (hdev) {
+ hci_unregister_dev(hdev);
+ hci_free_dev(hdev);
+ }
}
}
}
--
1.7.0.4
^ 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