* Re: Are LE connections possible yet?
From: Claudio Takahasi @ 2010-12-03 18:07 UTC (permalink / raw)
To: Mike Tsai; +Cc: Brian Gix, linux-bluetooth@vger.kernel.org
In-Reply-To: <35B17FE5076C7040809188FBE7913F98406D794075@SC1EXMB-MBCL.global.atheros.com>
Hi All,
On Thu, Dec 2, 2010 at 10:21 PM, Mike Tsai <Mike.Tsai@atheros.com> wrote:
> Hi Brian,
>
> -----Original Message-----
> From: linux-bluetooth-owner@vger.kernel.org [mailto:linux-bluetooth-owner@vger.kernel.org] On Behalf Of Brian Gix
> Sent: Thursday, December 02, 2010 3:46 PM
> To: linux-bluetooth@vger.kernel.org
> Subject: Are LE connections possible yet?
>
> Hi All,
>
> I am bringing up an LE capable (BR/EDR/LE) baseband, and attempting to use
> it to establish a
> GATT/ATT connection over an LE link. However when executing the command:
>
> % ./tools/hcitool lecc 00:14:BB:55:66:77
>
> I get a very rapid failure of:
>
> "Could not create connection: Operation not permitted"
>
> The correct HCI command does not appear to be making it to the BR/EDR/LE
> baseband.
>
> It appears to be a socket issue of some sort. I can cause this error, when
> attached to the baseband, and:
> "Could not create connection: File descriptor in bad state"
>
> if I have not yet run hciattach.
>
> Other (BR/EDR) hcitool commands work as expected, such as "hcitool scan" and
> "hcitool inq"
> [MTsai]which kernel driver you are using? It seems the kernel does not know the LE create connection OpCode?
>
>
> 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
> --
> 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
>
For hcitool lecc it is not necessary a LE "capable" kernel, hcitool
sends the HCI commands from the userspace.
Try sudo hcitool lecc ... and don't forget putting the remote on
advertising mode: $hciconfig hcix leadv
If you want to test the connections managed by the kernel use Ville's kernel:
git://git.kernel.org/pub/scm/linux/kernel/git/vtervo/bluetooth-le-2.6.git
l2test support LE connections, use -J option to pass the fixed channel 4
Regards,
Claudio
^ permalink raw reply
* [PATCH v2 0/3] Basic attribute permission support
From: Anderson Lizardo @ 2010-12-03 18:26 UTC (permalink / raw)
To: linux-bluetooth
Hi,
Changes since V1:
* Simplified permission scheme according to discussion on IRC.
* Fixed incorrect error sent by server.
This patchset adds initial support for attribute permission checks. Currently,
only access and authentication permissions are checked. Authorization
permissions require integration with the BlueZ agent, which is not implemented
yet.
There are some pending issues necessary for a minimum complete attribute
permission support (all of them are being worked on):
* The attribute client, upon receiving the "Insufficient Encryption" error,
shall increase the security level and resend the failed request.
* The attribute server shall verify the connection permissions on each ATT
request, and not just once on connection callback.
* On kernel side, increasing the security level (using setsockopt()) shall
trigger SMP negotiation for a LE connection, blocking next socket I/O until
negotiation is finished.
* On BR/EDR, link encryption is mandatory for GATT (see Vol 3, Part G, 2.4
"Profile Fundamentals").
Albeit the above issues, we believe these patches are ready for commit.
Regards,
--
Anderson Lizardo
OpenBossa Labs - INdT
Manaus - Brazil
^ permalink raw reply
* [PATCH 1/3] Initial attribute permission implementation
From: Anderson Lizardo @ 2010-12-03 18:26 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Bruna Moreira
In-Reply-To: <1291400782-24736-1-git-send-email-anderson.lizardo@openbossa.org>
From: Bruna Moreira <bruna.moreira@openbossa.org>
Add enums for attribute read/write requirements, which may be "none",
"authentication required" or "authorization required". Additionally, a
"not permitted" requirement means that operation is not permitted,
allowing read-only or write-only attributes.
The attrib_db_add() API was changed to allow setting these requirements,
and the example server was changed to set requirements for its
attributes.
---
attrib/att.h | 10 ++++++
attrib/example.c | 80 +++++++++++++++++++++++++-------------------------
src/attrib-server.c | 5 ++-
src/attrib-server.h | 3 +-
4 files changed, 56 insertions(+), 42 deletions(-)
diff --git a/attrib/att.h b/attrib/att.h
index 7c98b4a..2c8c724 100644
--- a/attrib/att.h
+++ b/attrib/att.h
@@ -109,9 +109,19 @@
#define ATT_MAX_MTU 256
#define ATT_DEFAULT_MTU 23
+/* Requirements for read/write operations */
+enum {
+ ATT_NONE, /* No restrictions */
+ ATT_AUTHENTICATION, /* Authentication required */
+ ATT_AUTHORIZATION, /* Authorization required */
+ ATT_NOT_PERMITTED, /* Operation not permitted */
+};
+
struct attribute {
uint16_t handle;
uuid_t uuid;
+ int read_reqs;
+ int write_reqs;
int len;
uint8_t data[0];
};
diff --git a/attrib/example.c b/attrib/example.c
index c29e1e4..4307804 100644
--- a/attrib/example.c
+++ b/attrib/example.c
@@ -101,7 +101,7 @@ static int register_attributes(void)
u16 = htons(GENERIC_ACCESS_PROFILE_ID);
atval[0] = u16 >> 8;
atval[1] = u16;
- attrib_db_add(0x0001, &uuid, atval, 2);
+ attrib_db_add(0x0001, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 2);
/* GAP service: device name characteristic */
sdp_uuid16_create(&uuid, GATT_CHARAC_UUID);
@@ -111,20 +111,20 @@ static int register_attributes(void)
atval[2] = 0x00;
atval[3] = u16 >> 8;
atval[4] = u16;
- attrib_db_add(0x0004, &uuid, atval, 5);
+ attrib_db_add(0x0004, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 5);
/* GAP service: device name attribute */
sdp_uuid16_create(&uuid, GATT_CHARAC_DEVICE_NAME);
len = strlen(devname);
strncpy((char *) atval, devname, len);
- attrib_db_add(0x0006, &uuid, atval, len);
+ attrib_db_add(0x0006, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, len);
/* GATT service: primary service definition */
sdp_uuid16_create(&uuid, GATT_PRIM_SVC_UUID);
u16 = htons(GENERIC_ATTRIB_PROFILE_ID);
atval[0] = u16 >> 8;
atval[1] = u16;
- attrib_db_add(0x0010, &uuid, atval, 2);
+ attrib_db_add(0x0010, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 2);
/* GATT service: attributes opcodes characteristic */
sdp_uuid16_create(&uuid, GATT_CHARAC_UUID);
@@ -134,20 +134,20 @@ static int register_attributes(void)
atval[2] = 0x00;
atval[3] = u16 >> 8;
atval[4] = u16;
- attrib_db_add(0x0011, &uuid, atval, 5);
+ attrib_db_add(0x0011, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 5);
/* GATT service: attribute opcodes supported */
sdp_uuid16_create(&uuid, OPCODES_SUPPORTED_UUID);
atval[0] = 0xFF;
atval[1] = 0x01;
- attrib_db_add(0x0012, &uuid, atval, 2);
+ attrib_db_add(0x0012, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 2);
/* Battery state service: primary service definition */
sdp_uuid16_create(&uuid, GATT_PRIM_SVC_UUID);
u16 = htons(BATTERY_STATE_SVC_UUID);
atval[0] = u16 >> 8;
atval[1] = u16;
- attrib_db_add(0x0100, &uuid, atval, 2);
+ attrib_db_add(0x0100, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 2);
/* Battery: battery state characteristic */
sdp_uuid16_create(&uuid, GATT_CHARAC_UUID);
@@ -157,18 +157,18 @@ static int register_attributes(void)
atval[2] = 0x01;
atval[3] = u16 >> 8;
atval[4] = u16;
- attrib_db_add(0x0106, &uuid, atval, 5);
+ attrib_db_add(0x0106, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 5);
/* Battery: battery state attribute */
sdp_uuid16_create(&uuid, BATTERY_STATE_UUID);
atval[0] = 0x04;
- attrib_db_add(0x0110, &uuid, atval, 1);
+ attrib_db_add(0x0110, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 1);
/* Battery: Client Characteristic Configuration */
sdp_uuid16_create(&uuid, GATT_CLIENT_CHARAC_CFG_UUID);
atval[0] = 0x00;
atval[1] = 0x00;
- attrib_db_add(0x0111, &uuid, atval, 2);
+ attrib_db_add(0x0111, &uuid, ATT_NONE, ATT_AUTHENTICATION, atval, 2);
timeout_id = g_timeout_add_seconds(10, change_battery_state, NULL);
@@ -177,7 +177,7 @@ static int register_attributes(void)
u16 = htons(THERM_HUMIDITY_SVC_UUID);
atval[0] = u16 >> 8;
atval[1] = u16;
- attrib_db_add(0x0200, &uuid, atval, 2);
+ attrib_db_add(0x0200, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 2);
/* Thermometer: Include */
sdp_uuid16_create(&uuid, GATT_INCLUDE_UUID);
@@ -188,14 +188,14 @@ static int register_attributes(void)
atval[3] = 0x05;
atval[4] = u16 >> 8;
atval[5] = u16;
- attrib_db_add(0x0201, &uuid, atval, 6);
+ attrib_db_add(0x0201, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 6);
/* Thermometer: Include */
atval[0] = 0x50;
atval[1] = 0x05;
atval[2] = 0x68;
atval[3] = 0x05;
- attrib_db_add(0x0202, &uuid, atval, 4);
+ attrib_db_add(0x0202, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 4);
/* Thermometer: temperature characteristic */
sdp_uuid16_create(&uuid, GATT_CHARAC_UUID);
@@ -205,13 +205,13 @@ static int register_attributes(void)
atval[2] = 0x02;
atval[3] = u16 >> 8;
atval[4] = u16;
- attrib_db_add(0x0203, &uuid, atval, 5);
+ attrib_db_add(0x0203, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 5);
/* Thermometer: temperature characteristic value */
sdp_uuid16_create(&uuid, TEMPERATURE_UUID);
atval[0] = 0x8A;
atval[1] = 0x02;
- attrib_db_add(0x0204, &uuid, atval, 2);
+ attrib_db_add(0x0204, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 2);
/* Thermometer: temperature characteristic format */
sdp_uuid16_create(&uuid, GATT_CHARAC_FMT_UUID);
@@ -224,13 +224,13 @@ static int register_attributes(void)
u16 = htons(FMT_OUTSIDE_UUID);
atval[5] = u16 >> 8;
atval[6] = u16;
- attrib_db_add(0x0205, &uuid, atval, 7);
+ attrib_db_add(0x0205, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 7);
/* Thermometer: characteristic user description */
sdp_uuid16_create(&uuid, GATT_CHARAC_USER_DESC_UUID);
len = strlen(desc_out_temp);
strncpy((char *) atval, desc_out_temp, len);
- attrib_db_add(0x0206, &uuid, atval, len);
+ attrib_db_add(0x0206, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, len);
/* Thermometer: relative humidity characteristic */
sdp_uuid16_create(&uuid, GATT_CHARAC_UUID);
@@ -240,12 +240,12 @@ static int register_attributes(void)
atval[2] = 0x02;
atval[3] = u16 >> 8;
atval[4] = u16;
- attrib_db_add(0x0210, &uuid, atval, 5);
+ attrib_db_add(0x0210, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 5);
/* Thermometer: relative humidity value */
sdp_uuid16_create(&uuid, RELATIVE_HUMIDITY_UUID);
atval[0] = 0x27;
- attrib_db_add(0x0212, &uuid, atval, 1);
+ attrib_db_add(0x0212, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 1);
/* Thermometer: relative humidity characteristic format */
sdp_uuid16_create(&uuid, GATT_CHARAC_FMT_UUID);
@@ -260,20 +260,20 @@ static int register_attributes(void)
u16 = htons(FMT_OUTSIDE_UUID);
atval[6] = u16 >> 8;
atval[7] = u16;
- attrib_db_add(0x0213, &uuid, atval, 8);
+ attrib_db_add(0x0213, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 8);
/* Thermometer: characteristic user description */
sdp_uuid16_create(&uuid, GATT_CHARAC_USER_DESC_UUID);
len = strlen(desc_out_hum);
strncpy((char *) atval, desc_out_hum, len);
- attrib_db_add(0x0214, &uuid, atval, len);
+ attrib_db_add(0x0214, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, len);
/* Secondary Service: Manufacturer Service */
sdp_uuid16_create(&uuid, GATT_SND_SVC_UUID);
u16 = htons(MANUFACTURER_SVC_UUID);
atval[0] = u16 >> 8;
atval[1] = u16;
- attrib_db_add(0x0500, &uuid, atval, 2);
+ attrib_db_add(0x0500, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 2);
/* Manufacturer name characteristic definition */
sdp_uuid16_create(&uuid, GATT_CHARAC_UUID);
@@ -283,13 +283,13 @@ static int register_attributes(void)
atval[2] = 0x05;
atval[3] = u16 >> 8;
atval[4] = u16;
- attrib_db_add(0x0501, &uuid, atval, 5);
+ attrib_db_add(0x0501, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 5);
/* Manufacturer name characteristic value */
sdp_uuid16_create(&uuid, MANUFACTURER_NAME_UUID);
len = strlen(manufacturer_name1);
strncpy((char *) atval, manufacturer_name1, len);
- attrib_db_add(0x0502, &uuid, atval, len);
+ attrib_db_add(0x0502, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, len);
/* Manufacturer serial number characteristic */
sdp_uuid16_create(&uuid, GATT_CHARAC_UUID);
@@ -299,20 +299,20 @@ static int register_attributes(void)
atval[2] = 0x05;
atval[3] = u16 >> 8;
atval[4] = u16;
- attrib_db_add(0x0503, &uuid, atval, 5);
+ attrib_db_add(0x0503, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 5);
/* Manufacturer serial number characteristic value */
sdp_uuid16_create(&uuid, MANUFACTURER_SERIAL_UUID);
len = strlen(serial1);
strncpy((char *) atval, serial1, len);
- attrib_db_add(0x0504, &uuid, atval, len);
+ attrib_db_add(0x0504, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, len);
/* Secondary Service: Manufacturer Service */
sdp_uuid16_create(&uuid, GATT_SND_SVC_UUID);
u16 = htons(MANUFACTURER_SVC_UUID);
atval[0] = u16 >> 8;
atval[1] = u16;
- attrib_db_add(0x0505, &uuid, atval, 2);
+ attrib_db_add(0x0505, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 2);
/* Manufacturer name characteristic definition */
sdp_uuid16_create(&uuid, GATT_CHARAC_UUID);
@@ -322,14 +322,14 @@ static int register_attributes(void)
atval[2] = 0x05;
atval[3] = u16 >> 8;
atval[4] = u16;
- attrib_db_add(0x0506, &uuid, atval, 5);
+ attrib_db_add(0x0506, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 5);
/* Secondary Service: Vendor Specific Service */
sdp_uuid16_create(&uuid, GATT_SND_SVC_UUID);
u16 = htons(VENDOR_SPECIFIC_SVC_UUID);
atval[0] = u16 >> 8;
atval[1] = u16;
- attrib_db_add(0x0550, &uuid, atval, 2);
+ attrib_db_add(0x0550, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 2);
/* Vendor Specific Type characteristic definition */
sdp_uuid16_create(&uuid, GATT_CHARAC_UUID);
@@ -339,7 +339,7 @@ static int register_attributes(void)
atval[2] = 0x05;
atval[3] = u16 >> 8;
atval[4] = u16;
- attrib_db_add(0x0560, &uuid, atval, 5);
+ attrib_db_add(0x0560, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 5);
/* Vendor Specific Type characteristic value */
sdp_uuid16_create(&uuid, VENDOR_SPECIFIC_TYPE_UUID);
@@ -349,13 +349,13 @@ static int register_attributes(void)
atval[3] = 0x64;
atval[4] = 0x6F;
atval[5] = 0x72;
- attrib_db_add(0x0568, &uuid, atval, 6);
+ attrib_db_add(0x0568, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 6);
/* Manufacturer name attribute */
sdp_uuid16_create(&uuid, MANUFACTURER_NAME_UUID);
len = strlen(manufacturer_name2);
strncpy((char *) atval, manufacturer_name2, len);
- attrib_db_add(0x0507, &uuid, atval, len);
+ attrib_db_add(0x0507, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, len);
/* Characteristic: serial number */
sdp_uuid16_create(&uuid, GATT_CHARAC_UUID);
@@ -365,18 +365,18 @@ static int register_attributes(void)
atval[2] = 0x05;
atval[3] = u16 >> 8;
atval[4] = u16;
- attrib_db_add(0x0508, &uuid, atval, 5);
+ attrib_db_add(0x0508, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 5);
/* Serial number characteristic value */
sdp_uuid16_create(&uuid, MANUFACTURER_SERIAL_UUID);
len = strlen(serial2);
strncpy((char *) atval, serial2, len);
- attrib_db_add(0x0509, &uuid, atval, len);
+ attrib_db_add(0x0509, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, len);
/* Weight service: primary service definition */
sdp_uuid16_create(&uuid, GATT_PRIM_SVC_UUID);
memcpy(atval, prim_weight_uuid, 16);
- attrib_db_add(0x0680, &uuid, atval, 16);
+ attrib_db_add(0x0680, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 16);
/* Weight: include */
sdp_uuid16_create(&uuid, GATT_INCLUDE_UUID);
@@ -387,7 +387,7 @@ static int register_attributes(void)
atval[3] = 0x05;
atval[4] = u16 >> 8;
atval[5] = u16;
- attrib_db_add(0x0681, &uuid, atval, 6);
+ attrib_db_add(0x0681, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 6);
/* Weight: characteristic */
sdp_uuid16_create(&uuid, GATT_CHARAC_UUID);
@@ -395,7 +395,7 @@ static int register_attributes(void)
atval[1] = 0x83;
atval[2] = 0x06;
memcpy(atval + 3, char_weight_uuid, 16);
- attrib_db_add(0x0682, &uuid, atval, 19);
+ attrib_db_add(0x0682, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 19);
/* Weight: characteristic value */
sdp_uuid128_create(&uuid, char_weight_uuid);
@@ -403,7 +403,7 @@ static int register_attributes(void)
atval[1] = 0x55;
atval[2] = 0x00;
atval[3] = 0x00;
- attrib_db_add(0x0683, &uuid, atval, 4);
+ attrib_db_add(0x0683, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 4);
/* Weight: characteristic format */
sdp_uuid16_create(&uuid, GATT_CHARAC_FMT_UUID);
@@ -418,13 +418,13 @@ static int register_attributes(void)
u16 = htons(FMT_HANGING_UUID);
atval[6] = u16 >> 8;
atval[7] = u16;
- attrib_db_add(0x0684, &uuid, atval, 8);
+ attrib_db_add(0x0684, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 8);
/* Weight: characteristic user description */
sdp_uuid16_create(&uuid, GATT_CHARAC_USER_DESC_UUID);
len = strlen(desc_weight);
strncpy((char *) atval, desc_weight, len);
- attrib_db_add(0x0685, &uuid, atval, len);
+ attrib_db_add(0x0685, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, len);
return 0;
}
diff --git a/src/attrib-server.c b/src/attrib-server.c
index 41c0ffc..410ac98 100644
--- a/src/attrib-server.c
+++ b/src/attrib-server.c
@@ -760,7 +760,8 @@ void attrib_server_exit(void)
remove_record_from_server(sdp_handle);
}
-int attrib_db_add(uint16_t handle, uuid_t *uuid, const uint8_t *value, int len)
+int attrib_db_add(uint16_t handle, uuid_t *uuid, int read_reqs, int write_reqs,
+ const uint8_t *value, int len)
{
struct attribute *a;
@@ -769,6 +770,8 @@ int attrib_db_add(uint16_t handle, uuid_t *uuid, const uint8_t *value, int len)
a = g_malloc0(sizeof(struct attribute) + len);
a->handle = handle;
memcpy(&a->uuid, uuid, sizeof(uuid_t));
+ a->read_reqs = read_reqs;
+ a->write_reqs = write_reqs;
a->len = len;
memcpy(a->data, value, len);
diff --git a/src/attrib-server.h b/src/attrib-server.h
index 4a0afa6..ba90ff4 100644
--- a/src/attrib-server.h
+++ b/src/attrib-server.h
@@ -25,7 +25,8 @@
int attrib_server_init(void);
void attrib_server_exit(void);
-int attrib_db_add(uint16_t handle, uuid_t *uuid, const uint8_t *value, int len);
+int attrib_db_add(uint16_t handle, uuid_t *uuid, int read_reqs, int write_reqs,
+ const uint8_t *value, int len);
int attrib_db_update(uint16_t handle, uuid_t *uuid, const uint8_t *value,
int len);
int attrib_db_del(uint16_t handle);
--
1.7.0.4
^ permalink raw reply related
* [PATCH 2/3] Check attribute permissions in attribute server
From: Anderson Lizardo @ 2010-12-03 18:26 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Bruna Moreira
In-Reply-To: <1291400782-24736-1-git-send-email-anderson.lizardo@openbossa.org>
From: Bruna Moreira <bruna.moreira@openbossa.org>
The attribute server must verify if the operation (read/write) is
permitted before running the request, and send "Read Not Permitted" or
"Write Not Permitted" error response to client if appropriate.
---
TODO | 7 -----
src/attrib-server.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++----
2 files changed, 62 insertions(+), 13 deletions(-)
diff --git a/TODO b/TODO
index 49a9e76..32d3a61 100644
--- a/TODO
+++ b/TODO
@@ -136,13 +136,6 @@ ATT/GATT
Priority: Low
Complexity: C2
-- Attribute server shall implement attribute permission verification,
- returning an error code if necessary. See Volume 3, Part F, 3.2.5
- for more information.
-
- Priority: Low
- Complexity: C2
-
- Implement Client Characteristic Configuration support in the attribute
server to manage indications and notications. This is a per client attribute
to control how the client wants to receive reports of changes in a given
diff --git a/src/attrib-server.c b/src/attrib-server.c
index 410ac98..2ba21e9 100644
--- a/src/attrib-server.c
+++ b/src/attrib-server.c
@@ -138,6 +138,28 @@ static sdp_record_t *server_record_new(void)
return record;
}
+static uint8_t att_check_reqs(uint8_t opcode, int reqs)
+{
+ switch (opcode) {
+ case ATT_OP_READ_BY_GROUP_REQ:
+ case ATT_OP_READ_BY_TYPE_REQ:
+ case ATT_OP_READ_REQ:
+ case ATT_OP_READ_BLOB_REQ:
+ case ATT_OP_READ_MULTI_REQ:
+ if (reqs == ATT_NOT_PERMITTED)
+ return ATT_ECODE_READ_NOT_PERM;
+ break;
+ case ATT_OP_PREP_WRITE_REQ:
+ case ATT_OP_WRITE_REQ:
+ case ATT_OP_WRITE_CMD:
+ if (reqs == ATT_NOT_PERMITTED)
+ return ATT_ECODE_WRITE_NOT_PERM;
+ break;
+ }
+
+ return 0;
+}
+
static uint16_t read_by_group(uint16_t start, uint16_t end, uuid_t *uuid,
uint8_t *pdu, int len)
{
@@ -146,6 +168,7 @@ static uint16_t read_by_group(uint16_t start, uint16_t end, uuid_t *uuid,
struct group_elem *cur, *old = NULL;
GSList *l, *groups;
uint16_t length, last_handle, last_size = 0;
+ uint8_t status;
int i;
if (start > end || start == 0x0000)
@@ -189,6 +212,14 @@ static uint16_t read_by_group(uint16_t start, uint16_t end, uuid_t *uuid,
if (last_size && (last_size != a->len))
break;
+ status = att_check_reqs(ATT_OP_READ_BY_GROUP_REQ, a->read_reqs);
+ if (status) {
+ g_slist_foreach(groups, (GFunc) g_free, NULL);
+ g_slist_free(groups);
+ return enc_error_resp(ATT_OP_READ_BY_GROUP_REQ,
+ a->handle, status, pdu, len);
+ }
+
cur = g_new0(struct group_elem, 1);
cur->handle = a->handle;
cur->data = a->data;
@@ -247,6 +278,7 @@ static uint16_t read_by_type(uint16_t start, uint16_t end, uuid_t *uuid,
GSList *l, *types;
struct attribute *a;
uint16_t num, length;
+ uint8_t status;
int i;
if (start > end || start == 0x0000)
@@ -265,6 +297,13 @@ static uint16_t read_by_type(uint16_t start, uint16_t end, uuid_t *uuid,
if (sdp_uuid_cmp(&a->uuid, uuid) != 0)
continue;
+ status = att_check_reqs(ATT_OP_READ_BY_TYPE_REQ, a->read_reqs);
+ if (status) {
+ g_slist_free(types);
+ return enc_error_resp(ATT_OP_READ_BY_TYPE_REQ,
+ a->handle, status, pdu, len);
+ }
+
/* All elements must have the same length */
if (length == 0)
length = a->len;
@@ -472,6 +511,7 @@ static int attribute_cmp(gconstpointer a1, gconstpointer a2)
static uint16_t read_value(uint16_t handle, uint8_t *pdu, int len)
{
struct attribute *a;
+ uint8_t status;
GSList *l;
guint h = handle;
@@ -482,23 +522,41 @@ static uint16_t read_value(uint16_t handle, uint8_t *pdu, int len)
a = l->data;
+ status = att_check_reqs(ATT_OP_READ_REQ, a->read_reqs);
+ if (status)
+ return enc_error_resp(ATT_OP_READ_REQ, handle, status, pdu,
+ len);
+
return enc_read_resp(a->data, a->len, pdu, len);
}
-static void write_value(uint16_t handle, const uint8_t *value, int vlen)
+static uint16_t write_value(uint16_t handle, const uint8_t *value, int vlen,
+ uint8_t *pdu, int len)
{
struct attribute *a;
+ uint8_t status;
GSList *l;
guint h = handle;
uuid_t uuid;
l = g_slist_find_custom(database, GUINT_TO_POINTER(h), handle_cmp);
if (!l)
- return;
+ return enc_error_resp(ATT_OP_WRITE_REQ, handle,
+ ATT_ECODE_INVALID_HANDLE, pdu, len);
a = l->data;
+
+ status = att_check_reqs(ATT_OP_WRITE_REQ, a->write_reqs);
+ if (status)
+ return enc_error_resp(ATT_OP_WRITE_REQ, handle, status, pdu,
+ len);
+
memcpy(&uuid, &a->uuid, sizeof(uuid_t));
attrib_db_update(handle, &uuid, value, vlen);
+
+ pdu[0] = ATT_OP_WRITE_RESP;
+
+ return sizeof(pdu[0]);
}
static uint16_t mtu_exchange(struct gatt_channel *channel, uint16_t mtu,
@@ -582,14 +640,12 @@ static void channel_handler(const uint8_t *ipdu, uint16_t len,
goto done;
}
- write_value(start, value, vlen);
- opdu[0] = ATT_OP_WRITE_RESP;
- length = sizeof(opdu[0]);
+ length = write_value(start, value, vlen, opdu, channel->mtu);
break;
case ATT_OP_WRITE_CMD:
length = dec_write_cmd(ipdu, len, &start, value, &vlen);
if (length > 0)
- write_value(start, value, vlen);
+ write_value(start, value, vlen, opdu, channel->mtu);
return;
case ATT_OP_FIND_BY_TYPE_REQ:
length = dec_find_by_type_req(ipdu, len, &start, &end,
--
1.7.0.4
^ permalink raw reply related
* [PATCH 3/3] Check authentication permissions on attribute server
From: Anderson Lizardo @ 2010-12-03 18:26 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Anderson Lizardo
In-Reply-To: <1291400782-24736-1-git-send-email-anderson.lizardo@openbossa.org>
Attributes may require encryption for certain operations. This commit
adds checks to the attribute server which verify whether the current
connection is encrypted (by checking the security level) and the
attribute being accessed requires authentication. If encryption
requirements are not satisfied, the "Insufficient Encryption" error is
returned by the server.
Note that currently there is no actual distinction between
authentication and encryption. Currently, if an attribute requires
authentication, it is only checked whether the link is encrypted. Core
Specification, as of version 4.0, does not specify an explicit
"encryption" permission (see Vol. 3, Part F, 3.2.5 "Attribute
Permissions").
---
src/attrib-server.c | 57 +++++++++++++++++++++++++++++++++++---------------
1 files changed, 40 insertions(+), 17 deletions(-)
diff --git a/src/attrib-server.c b/src/attrib-server.c
index 2ba21e9..f2df853 100644
--- a/src/attrib-server.c
+++ b/src/attrib-server.c
@@ -57,6 +57,7 @@ struct gatt_channel {
GAttrib *attrib;
guint mtu;
guint id;
+ gboolean encrypted;
};
struct group_elem {
@@ -138,8 +139,15 @@ static sdp_record_t *server_record_new(void)
return record;
}
-static uint8_t att_check_reqs(uint8_t opcode, int reqs)
+static uint8_t att_check_reqs(struct gatt_channel *channel, uint8_t opcode,
+ int reqs)
{
+ /* FIXME: currently, it is assumed an encrypted link is enough for
+ * authentication. This will allow to enable the SMP negotiation once
+ * it is on upstream kernel. */
+ if (reqs == ATT_AUTHENTICATION && !channel->encrypted)
+ return ATT_ECODE_INSUFF_ENC;
+
switch (opcode) {
case ATT_OP_READ_BY_GROUP_REQ:
case ATT_OP_READ_BY_TYPE_REQ:
@@ -160,8 +168,9 @@ static uint8_t att_check_reqs(uint8_t opcode, int reqs)
return 0;
}
-static uint16_t read_by_group(uint16_t start, uint16_t end, uuid_t *uuid,
- uint8_t *pdu, int len)
+static uint16_t read_by_group(struct gatt_channel *channel, uint16_t start,
+ uint16_t end, uuid_t *uuid,
+ uint8_t *pdu, int len)
{
struct att_data_list *adl;
struct attribute *a;
@@ -212,7 +221,8 @@ static uint16_t read_by_group(uint16_t start, uint16_t end, uuid_t *uuid,
if (last_size && (last_size != a->len))
break;
- status = att_check_reqs(ATT_OP_READ_BY_GROUP_REQ, a->read_reqs);
+ status = att_check_reqs(channel, ATT_OP_READ_BY_GROUP_REQ,
+ a->read_reqs);
if (status) {
g_slist_foreach(groups, (GFunc) g_free, NULL);
g_slist_free(groups);
@@ -271,8 +281,9 @@ static uint16_t read_by_group(uint16_t start, uint16_t end, uuid_t *uuid,
return length;
}
-static uint16_t read_by_type(uint16_t start, uint16_t end, uuid_t *uuid,
- uint8_t *pdu, int len)
+static uint16_t read_by_type(struct gatt_channel *channel, uint16_t start,
+ uint16_t end, uuid_t *uuid,
+ uint8_t *pdu, int len)
{
struct att_data_list *adl;
GSList *l, *types;
@@ -297,7 +308,8 @@ static uint16_t read_by_type(uint16_t start, uint16_t end, uuid_t *uuid,
if (sdp_uuid_cmp(&a->uuid, uuid) != 0)
continue;
- status = att_check_reqs(ATT_OP_READ_BY_TYPE_REQ, a->read_reqs);
+ status = att_check_reqs(channel, ATT_OP_READ_BY_TYPE_REQ,
+ a->read_reqs);
if (status) {
g_slist_free(types);
return enc_error_resp(ATT_OP_READ_BY_TYPE_REQ,
@@ -508,7 +520,8 @@ static int attribute_cmp(gconstpointer a1, gconstpointer a2)
return attrib1->handle - attrib2->handle;
}
-static uint16_t read_value(uint16_t handle, uint8_t *pdu, int len)
+static uint16_t read_value(struct gatt_channel *channel, uint16_t handle,
+ uint8_t *pdu, int len)
{
struct attribute *a;
uint8_t status;
@@ -522,7 +535,7 @@ static uint16_t read_value(uint16_t handle, uint8_t *pdu, int len)
a = l->data;
- status = att_check_reqs(ATT_OP_READ_REQ, a->read_reqs);
+ status = att_check_reqs(channel, ATT_OP_READ_REQ, a->read_reqs);
if (status)
return enc_error_resp(ATT_OP_READ_REQ, handle, status, pdu,
len);
@@ -530,8 +543,9 @@ static uint16_t read_value(uint16_t handle, uint8_t *pdu, int len)
return enc_read_resp(a->data, a->len, pdu, len);
}
-static uint16_t write_value(uint16_t handle, const uint8_t *value, int vlen,
- uint8_t *pdu, int len)
+static uint16_t write_value(struct gatt_channel *channel, uint16_t handle,
+ const uint8_t *value, int vlen,
+ uint8_t *pdu, int len)
{
struct attribute *a;
uint8_t status;
@@ -546,7 +560,7 @@ static uint16_t write_value(uint16_t handle, const uint8_t *value, int vlen,
a = l->data;
- status = att_check_reqs(ATT_OP_WRITE_REQ, a->write_reqs);
+ status = att_check_reqs(channel, ATT_OP_WRITE_REQ, a->write_reqs);
if (status)
return enc_error_resp(ATT_OP_WRITE_REQ, handle, status, pdu,
len);
@@ -595,7 +609,8 @@ static void channel_handler(const uint8_t *ipdu, uint16_t len,
goto done;
}
- length = read_by_group(start, end, &uuid, opdu, channel->mtu);
+ length = read_by_group(channel, start, end, &uuid, opdu,
+ channel->mtu);
break;
case ATT_OP_READ_BY_TYPE_REQ:
length = dec_read_by_type_req(ipdu, len, &start, &end, &uuid);
@@ -604,7 +619,8 @@ static void channel_handler(const uint8_t *ipdu, uint16_t len,
goto done;
}
- length = read_by_type(start, end, &uuid, opdu, channel->mtu);
+ length = read_by_type(channel, start, end, &uuid, opdu,
+ channel->mtu);
break;
case ATT_OP_READ_REQ:
length = dec_read_req(ipdu, len, &start);
@@ -613,7 +629,7 @@ static void channel_handler(const uint8_t *ipdu, uint16_t len,
goto done;
}
- length = read_value(start, opdu, channel->mtu);
+ length = read_value(channel, start, opdu, channel->mtu);
break;
case ATT_OP_MTU_REQ:
length = dec_mtu_req(ipdu, len, &mtu);
@@ -640,12 +656,14 @@ static void channel_handler(const uint8_t *ipdu, uint16_t len,
goto done;
}
- length = write_value(start, value, vlen, opdu, channel->mtu);
+ length = write_value(channel, start, value, vlen, opdu,
+ channel->mtu);
break;
case ATT_OP_WRITE_CMD:
length = dec_write_cmd(ipdu, len, &start, value, &vlen);
if (length > 0)
- write_value(start, value, vlen, opdu, channel->mtu);
+ write_value(channel, start, value, vlen, opdu,
+ channel->mtu);
return;
case ATT_OP_FIND_BY_TYPE_REQ:
length = dec_find_by_type_req(ipdu, len, &start, &end,
@@ -682,6 +700,7 @@ static void connect_event(GIOChannel *io, GError *err, void *user_data)
{
struct gatt_channel *channel;
GError *gerr = NULL;
+ int sec_level;
if (err) {
error("%s", err->message);
@@ -693,6 +712,7 @@ static void connect_event(GIOChannel *io, GError *err, void *user_data)
bt_io_get(io, BT_IO_L2CAP, &gerr,
BT_IO_OPT_SOURCE_BDADDR, &channel->src,
BT_IO_OPT_DEST_BDADDR, &channel->dst,
+ BT_IO_OPT_SEC_LEVEL, &sec_level,
BT_IO_OPT_INVALID);
if (gerr) {
error("bt_io_get: %s", gerr->message);
@@ -705,6 +725,9 @@ static void connect_event(GIOChannel *io, GError *err, void *user_data)
channel->attrib = g_attrib_new(io);
channel->mtu = ATT_DEFAULT_MTU;
+ /* FIXME: the security level needs to checked on every request. */
+ channel->encrypted = sec_level > BT_IO_SEC_LOW;
+
channel->id = g_attrib_register(channel->attrib, GATTRIB_ALL_EVENTS,
channel_handler, channel, NULL);
--
1.7.0.4
^ permalink raw reply related
* [PATCH] Fix writing to GAttrib socket without POLLOUT event
From: Vinicius Costa Gomes @ 2010-12-03 18:28 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Vinicius Costa Gomes
If the GIOChannel is in the buffered state (the default) the watch
function is called without receiving a POLLOUT from the socket. GLib
adds a G_IO_OUT condition just because there is space in the GIOChannel
internal buffer.
The solution is disabling the internal buffer, which in turn, makes the
call of g_io_channel_flush() useless.
---
attrib/gattrib.c | 3 +--
1 files changed, 1 insertions(+), 2 deletions(-)
diff --git a/attrib/gattrib.c b/attrib/gattrib.c
index ed18168..1083519 100644
--- a/attrib/gattrib.c
+++ b/attrib/gattrib.c
@@ -248,8 +248,6 @@ static gboolean can_write_data(GIOChannel *io, GIOCondition cond,
if (iostat != G_IO_STATUS_NORMAL)
return FALSE;
- g_io_channel_flush(io, NULL);
-
if (cmd->expected == 0) {
g_queue_pop_head(attrib->queue);
command_destroy(cmd);
@@ -350,6 +348,7 @@ GAttrib *g_attrib_new(GIOChannel *io)
struct _GAttrib *attrib;
g_io_channel_set_encoding(io, NULL, NULL);
+ g_io_channel_set_buffered(io, FALSE);
attrib = g_try_new0(struct _GAttrib, 1);
if (attrib == NULL)
--
1.7.3.2
^ permalink raw reply related
* Re: [PATCH 1/5] Add device type to identify LE, BR/EDR or dual mode devices
From: Anderson Lizardo @ 2010-12-03 18:42 UTC (permalink / raw)
To: Claudio Takahasi; +Cc: linux-bluetooth
In-Reply-To: <1291386532-4985-1-git-send-email-claudio.takahasi@openbossa.org>
Hi Claudio,
On Fri, Dec 3, 2010 at 10:28 AM, Claudio Takahasi
<claudio.takahasi@openbossa.org> wrote:
> +static uint8_t flags2type(uint8_t flags)
> +{
> + /* Inferring the remote type based on the EIR Flags field */
> +
> + if (flags & EIR_SIM_CONTROLLER && flags & EIR_SIM_HOST)
> + return DUALMODE_TYPE;
Can the above be simplified to the following?
if (flags & (EIR_SIM_CONTROLLER | EIR_SIM_HOST))
I know the semantics will change slightly, but I suppose that either
host or controller supports simultaneous LE and BR/EDR, it can be
considered dual mode. It would no be necessary to have *both* bits set
(my impression).
> @@ -3082,6 +3098,7 @@ void adapter_update_device_from_info(struct btd_adapter *adapter,
> if (new_dev) {
> dev->le = TRUE;
> dev->evt_type = info->evt_type;
> + dev->type = LE_TYPE;
> } else if (dev->rssi == rssi)
> return;
>
Can you remind me why both dev->le and dev->type are necessary in
struct remote_dev_info ?
> @@ -3124,6 +3142,7 @@ void adapter_update_found_devices(struct btd_adapter *adapter, bdaddr_t *bdaddr,
> dev->alias = g_strdup(alias);
>
> dev->le = FALSE;
> + dev->type = BREDR_TYPE;
> dev->class = class;
> dev->legacy = legacy;
> dev->name_status = name_status;
Same question as above here too.
Regards,
--
Anderson Lizardo
OpenBossa Labs - INdT
Manaus - Brazil
^ permalink raw reply
* RE: Are LE connections possible yet?
From: Brian Gix @ 2010-12-03 19:01 UTC (permalink / raw)
To: 'Claudio Takahasi', 'Mike Tsai'; +Cc: linux-bluetooth
In-Reply-To: <AANLkTi=gWTQXcfisupHXs9qVpHbUbYZ1yxxqKf2Mm9EU@mail.gmail.com>
Hi Claudio & Mike
-----Original Message-----
From: Claudio Takahasi [mailto:claudio.takahasi@openbossa.org]
Sent: 03 December, 2010 10:07 AM
To: Mike Tsai
Cc: Brian Gix; linux-bluetooth@vger.kernel.org
Subject: Re: Are LE connections possible yet?
Hi All,
On Thu, Dec 2, 2010 at 10:21 PM, Mike Tsai <Mike.Tsai@atheros.com> wrote:
> Hi Brian,
>
> -----Original Message-----
> From: linux-bluetooth-owner@vger.kernel.org [mailto:linux-bluetooth-owner@vger.kernel.org] On Behalf Of Brian Gix
> Sent: Thursday, December 02, 2010 3:46 PM
> To: linux-bluetooth@vger.kernel.org
> Subject: Are LE connections possible yet?
>
> Hi All,
>
> I am bringing up an LE capable (BR/EDR/LE) baseband, and attempting to use
> it to establish a
> GATT/ATT connection over an LE link. However when executing the command:
>
> % ./tools/hcitool lecc 00:14:BB:55:66:77
>
> I get a very rapid failure of:
>
> "Could not create connection: Operation not permitted"
>
> The correct HCI command does not appear to be making it to the BR/EDR/LE
> baseband.
>
> It appears to be a socket issue of some sort. I can cause this error, when
> attached to the baseband, and:
> "Could not create connection: File descriptor in bad state"
>
> if I have not yet run hciattach.
>
> Other (BR/EDR) hcitool commands work as expected, such as "hcitool scan" and
> "hcitool inq"
> [MTsai]which kernel driver you are using? It seems the kernel does not know the LE create connection OpCode?
>
>
> 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
> --
> 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
>
For hcitool lecc it is not necessary a LE "capable" kernel, hcitool
sends the HCI commands from the userspace.
Try sudo hcitool lecc ... and don't forget putting the remote on
advertising mode: $hciconfig hcix leadv
If you want to test the connections managed by the kernel use Ville's kernel:
git://git.kernel.org/pub/scm/linux/kernel/git/vtervo/bluetooth-le-2.6.git
l2test support LE connections, use -J option to pass the fixed channel 4
[Gix] So I am cloning Ville's kernel as I type. I did get the LE connection up and running (raw LE ACL connections, "sudo" was the key) but I will need it to be talking on Fixed channel 4, because it is a non-bluez server that I am connecting to, which does use Fixed-4. This will probably take me the rest of the day.
[Gix] My next question is: How long until Ville's kernel is part of the tip?
[Gix] And how do I get gatttool to build? This may be academic until I get fixed channel 4 access via the new kernel.
Regards,
Claudio
^ permalink raw reply
* Re: Are LE connections possible yet?
From: Anderson Lizardo @ 2010-12-03 19:09 UTC (permalink / raw)
To: Brian Gix; +Cc: Claudio Takahasi, Mike Tsai, linux-bluetooth
In-Reply-To: <000301cb931c$74e56870$5eb03950$@org>
On Fri, Dec 3, 2010 at 3:01 PM, Brian Gix <bgix@codeaurora.org> wrote:
> [Gix] And how do I get gatttool to build? This may be academic until I get fixed channel 4 access via the new kernel.
gatttool is built along with bluez. Just be sure to use latest code
from GIT, and pass "--enable-attrib" to ./configure (or use
./bootstrap-configure)
Regards,
--
Anderson Lizardo
OpenBossa Labs - INdT
Manaus - Brazil
^ permalink raw reply
* LE Kernel (bluetooth-le-2.6) and LE Security Manager
From: Brian Gix @ 2010-12-03 19:11 UTC (permalink / raw)
To: linux-bluetooth
Hi Claudio, Johan & All,
Is this LE capable kernel that Ville is working on, the development stream
for the LE Security Manager? And if so, is it in a partial fleshed out
state?
> git://git.kernel.org/pub/scm/linux/kernel/git/vtervo/bluetooth-le-2.6.git
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: LE Kernel (bluetooth-le-2.6) and LE Security Manager
From: Vinicius Costa Gomes @ 2010-12-03 22:05 UTC (permalink / raw)
To: Brian Gix; +Cc: linux-bluetooth
In-Reply-To: <001c01cb931d$dc4cb3a0$94e61ae0$@org>
Hi Brian,
On 11:11 Fri 03 Dec, Brian Gix wrote:
>
> Hi Claudio, Johan & All,
>
> Is this LE capable kernel that Ville is working on, the development stream
> for the LE Security Manager? And if so, is it in a partial fleshed out
> state?
There is a simple implementation of SMP here[1] on my "devel" branch. I am
cleaning it up for sending it for review.
If you want to help, have any comments or just want to tell us what you are
working on, please drop by #bluez on freenode, or send an email.
>
> > git://git.kernel.org/pub/scm/linux/kernel/git/vtervo/bluetooth-le-2.6.git
>
>
> 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
Cheers,
--
Vinicius
[1] git://git.infradead.org/users/vcgomes/linux-2.6.git
^ permalink raw reply
* RE: LE Kernel (bluetooth-le-2.6) and LE Security Manager
From: Brian Gix @ 2010-12-04 0:40 UTC (permalink / raw)
To: 'Vinicius Costa Gomes', 'Gustavo F. Padovan',
'Ville Tervo'
Cc: linux-bluetooth
In-Reply-To: <20101203220534.GA16709@eris>
Hi Vinicius & Gustavo,
-----Original Message-----
From: Vinicius Costa Gomes [mailto:vinicius.gomes@openbossa.org]
Sent: 03 December, 2010 2:06 PM
To: Brian Gix
Cc: linux-bluetooth@vger.kernel.org
Subject: Re: LE Kernel (bluetooth-le-2.6) and LE Security Manager
Hi Brian,
On 11:11 Fri 03 Dec, Brian Gix wrote:
>
> Hi Claudio, Johan & All,
>
> Is this LE capable kernel that Ville is working on, the development stream
> for the LE Security Manager? And if so, is it in a partial fleshed out
> state?
There is a simple implementation of SMP here[1] on my "devel" branch. I am
cleaning it up for sending it for review.
If you want to help, have any comments or just want to tell us what you are
working on, please drop by #bluez on freenode, or send an email.
[Gix] Unfortunately, I can't access git.infradead.org. Gustavo, would it be
possible for you to pull Vinicius' devel branch from
git://git.infradead.org/users/vcgomes/linux-2.6.git to an le-devel branch on
your bluetooth-testing repository?
[Gix] I am trying to integrate Qualcomm's latest LE capable (BR/EDR/LE)
chipset with bluez. Additionally, I do have a working non-open-source
[Gix] host which has had it's LE Security Manager UPF tested, which I hope
to be able to use to help test/solidify the bluez version.
>
> >
git://git.kernel.org/pub/scm/linux/kernel/git/vtervo/bluetooth-le-2.6.git
>
>
> 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
Cheers,
--
Vinicius
[1] git://git.infradead.org/users/vcgomes/linux-2.6.git
^ permalink raw reply
* [PATCH 0/2] Add and use vsprintf extension %pMbt for bluetooth macs
From: Joe Perches @ 2010-12-04 2:33 UTC (permalink / raw)
To: Marcel Holtmann, Gustavo F. Padovan, linux-bluetooth; +Cc: netdev, linux-kernel
Using vsprintf extensions can save text and data.
Add %pMbt for the byte reversed output for bluetooth addresses.
Joe Perches (2):
vsprintf: Add %pMbt, bluetooth mac address
bluetooth: Use printf extension %pMbt
lib/vsprintf.c | 6 +++++-
net/bluetooth/bnep/core.c | 3 +--
net/bluetooth/cmtp/core.c | 2 +-
net/bluetooth/hci_conn.c | 6 +++---
net/bluetooth/hci_core.c | 8 ++++----
net/bluetooth/hci_event.c | 6 +++---
net/bluetooth/hci_sysfs.c | 10 +++++-----
net/bluetooth/hidp/core.c | 4 ++--
net/bluetooth/l2cap.c | 19 +++++++++----------
net/bluetooth/lib.c | 14 --------------
net/bluetooth/rfcomm/core.c | 16 ++++++++--------
net/bluetooth/rfcomm/sock.c | 8 ++++----
net/bluetooth/rfcomm/tty.c | 6 +++---
net/bluetooth/sco.c | 12 ++++++------
14 files changed, 54 insertions(+), 66 deletions(-)
--
1.7.3.2.245.g03276.dirty
^ permalink raw reply
* [PATCH 2/2] bluetooth: Use printf extension %pMbt
From: Joe Perches @ 2010-12-04 2:33 UTC (permalink / raw)
To: Marcel Holtmann, Gustavo F. Padovan
Cc: netdev, David S. Miller, linux-bluetooth, linux-kernel
In-Reply-To: <cover.1291419007.git.joe@perches.com>
Save some text and bss.
Remove function batostr so there's no possibility of bad output.
from the net/bluetooth directory:
$ size built-in.o.*
text data bss dec hex filename
293562 16265 70088 379915 5cc0b built-in.o.allyesconfig.new
294619 16269 70480 381368 5d1b8 built-in.o.allyesconfig.old
30359 772 56 31187 79d3 built-in.o.btonly.new
30555 776 92 31423 7abf built-in.o.btonly.old
Signed-off-by: Joe Perches <joe@perches.com>
---
net/bluetooth/bnep/core.c | 3 +--
net/bluetooth/cmtp/core.c | 2 +-
net/bluetooth/hci_conn.c | 6 +++---
net/bluetooth/hci_core.c | 8 ++++----
net/bluetooth/hci_event.c | 6 +++---
net/bluetooth/hci_sysfs.c | 10 +++++-----
net/bluetooth/hidp/core.c | 4 ++--
net/bluetooth/l2cap.c | 19 +++++++++----------
net/bluetooth/lib.c | 14 --------------
net/bluetooth/rfcomm/core.c | 16 ++++++++--------
net/bluetooth/rfcomm/sock.c | 8 ++++----
net/bluetooth/rfcomm/tty.c | 6 +++---
net/bluetooth/sco.c | 12 ++++++------
13 files changed, 49 insertions(+), 65 deletions(-)
diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c
index 5868597..3d4530f 100644
--- a/net/bluetooth/bnep/core.c
+++ b/net/bluetooth/bnep/core.c
@@ -199,8 +199,7 @@ static int bnep_ctrl_set_mcfilter(struct bnep_session *s, u8 *data, int len)
memcpy(a1, data, ETH_ALEN); data += ETH_ALEN;
a2 = data; data += ETH_ALEN;
- BT_DBG("mc filter %s -> %s",
- batostr((void *) a1), batostr((void *) a2));
+ BT_DBG("mc filter %pMbt -> %pMbt", a1, a2);
#define INCA(a) { int i = 5; while (i >=0 && ++a[i--] == 0); }
diff --git a/net/bluetooth/cmtp/core.c b/net/bluetooth/cmtp/core.c
index 8e5f292..f72bca7 100644
--- a/net/bluetooth/cmtp/core.c
+++ b/net/bluetooth/cmtp/core.c
@@ -344,7 +344,7 @@ int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock)
BT_DBG("mtu %d", session->mtu);
- sprintf(session->name, "%s", batostr(&bt_sk(sock->sk)->dst));
+ sprintf(session->name, "%pMbt", &bt_sk(sock->sk)->dst);
session->sock = sock;
session->state = BT_CONFIG;
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 0b1e460..d9e3eb3 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -221,7 +221,7 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
{
struct hci_conn *conn;
- BT_DBG("%s dst %s", hdev->name, batostr(dst));
+ BT_DBG("%s dst %pMbt", hdev->name, dst);
conn = kzalloc(sizeof(struct hci_conn), GFP_ATOMIC);
if (!conn)
@@ -325,7 +325,7 @@ struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src)
struct hci_dev *hdev = NULL;
struct list_head *p;
- BT_DBG("%s -> %s", batostr(src), batostr(dst));
+ BT_DBG("%pMbt -> %pMbt", src, dst);
read_lock_bh(&hci_dev_list_lock);
@@ -366,7 +366,7 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8
struct hci_conn *acl;
struct hci_conn *sco;
- BT_DBG("%s dst %s", hdev->name, batostr(dst));
+ BT_DBG("%s dst %pMbt", hdev->name, dst);
if (!(acl = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst))) {
if (!(acl = hci_conn_add(hdev, ACL_LINK, dst)))
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index bc2a052..47962af 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -338,7 +338,7 @@ struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, bdaddr_t *b
struct inquiry_cache *cache = &hdev->inq_cache;
struct inquiry_entry *e;
- BT_DBG("cache %p, %s", cache, batostr(bdaddr));
+ BT_DBG("cache %p, %pMbt", cache, bdaddr);
for (e = cache->list; e; e = e->next)
if (!bacmp(&e->data.bdaddr, bdaddr))
@@ -351,7 +351,7 @@ void hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data)
struct inquiry_cache *cache = &hdev->inq_cache;
struct inquiry_entry *e;
- BT_DBG("cache %p, %s", cache, batostr(&data->bdaddr));
+ BT_DBG("cache %p, %pMbt", cache, &data->bdaddr);
if (!(e = hci_inquiry_cache_lookup(hdev, &data->bdaddr))) {
/* Entry not in the cache. Add new one. */
@@ -1478,8 +1478,8 @@ static inline void hci_acl_tx_to(struct hci_dev *hdev)
list_for_each(p, &h->list) {
c = list_entry(p, struct hci_conn, list);
if (c->type == ACL_LINK && c->sent) {
- BT_ERR("%s killing stalled ACL connection %s",
- hdev->name, batostr(&c->dst));
+ BT_ERR("%s killing stalled ACL connection %pMbt",
+ hdev->name, &c->dst);
hci_acl_disconn(c, 0x13);
}
}
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 3c1957c..53f833f 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -566,7 +566,7 @@ static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
- BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->bdaddr), conn);
+ BT_DBG("%s bdaddr %pMbt conn %p", hdev->name, &cp->bdaddr, conn);
if (status) {
if (conn && conn->state == BT_CONNECT) {
@@ -984,8 +984,8 @@ static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *sk
struct hci_ev_conn_request *ev = (void *) skb->data;
int mask = hdev->link_mode;
- BT_DBG("%s bdaddr %s type 0x%x", hdev->name,
- batostr(&ev->bdaddr), ev->link_type);
+ BT_DBG("%s bdaddr %pMbt type 0x%x",
+ hdev->name, &ev->bdaddr, ev->link_type);
mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type);
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
index 5fce3d6..5dac407 100644
--- a/net/bluetooth/hci_sysfs.c
+++ b/net/bluetooth/hci_sysfs.c
@@ -37,7 +37,7 @@ static ssize_t show_link_type(struct device *dev, struct device_attribute *attr,
static ssize_t show_link_address(struct device *dev, struct device_attribute *attr, char *buf)
{
struct hci_conn *conn = dev_get_drvdata(dev);
- return sprintf(buf, "%s\n", batostr(&conn->dst));
+ return sprintf(buf, "%pMbt\n", &conn->dst);
}
static ssize_t show_link_features(struct device *dev, struct device_attribute *attr, char *buf)
@@ -236,7 +236,7 @@ static ssize_t show_class(struct device *dev, struct device_attribute *attr, cha
static ssize_t show_address(struct device *dev, struct device_attribute *attr, char *buf)
{
struct hci_dev *hdev = dev_get_drvdata(dev);
- return sprintf(buf, "%s\n", batostr(&hdev->bdaddr));
+ return sprintf(buf, "%pMbt\n", &hdev->bdaddr);
}
static ssize_t show_features(struct device *dev, struct device_attribute *attr, char *buf)
@@ -404,8 +404,8 @@ static int inquiry_cache_show(struct seq_file *f, void *p)
for (e = cache->list; e; e = e->next) {
struct inquiry_data *data = &e->data;
- seq_printf(f, "%s %d %d %d 0x%.2x%.2x%.2x 0x%.4x %d %d %u\n",
- batostr(&data->bdaddr),
+ seq_printf(f, "%pMbt %d %d %d 0x%.2x%.2x%.2x 0x%.4x %d %d %u\n",
+ &data->bdaddr,
data->pscan_rep_mode, data->pscan_period_mode,
data->pscan_mode, data->dev_class[2],
data->dev_class[1], data->dev_class[0],
@@ -442,7 +442,7 @@ static int blacklist_show(struct seq_file *f, void *p)
b = list_entry(l, struct bdaddr_list, list);
- seq_printf(f, "%s\n", batostr(&b->bdaddr));
+ seq_printf(f, "%pMbt\n", &b->bdaddr);
}
hci_dev_unlock_bh(hdev);
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c
index 29544c2..cde8827 100644
--- a/net/bluetooth/hidp/core.c
+++ b/net/bluetooth/hidp/core.c
@@ -787,8 +787,8 @@ static int hidp_setup_hid(struct hidp_session *session,
hid->country = req->country;
strncpy(hid->name, req->name, 128);
- strncpy(hid->phys, batostr(&bt_sk(session->ctrl_sock->sk)->src), 64);
- strncpy(hid->uniq, batostr(&bt_sk(session->ctrl_sock->sk)->dst), 64);
+ snprintf(hid->phys, 64, "%pMbt", &bt_sk(session->ctrl_sock->sk)->src);
+ snprintf(hid->uniq, 64, "%pMbt", &bt_sk(session->ctrl_sock->sk)->dst);
hid->dev.parent = hidp_get_device(session);
hid->ll_driver = &hidp_hid_driver;
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 12b4aa2..72b8306 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -1057,8 +1057,7 @@ static int l2cap_do_connect(struct sock *sk)
__u8 auth_type;
int err;
- BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst),
- l2cap_pi(sk)->psm);
+ BT_DBG("%pMbt -> %pMbt psm 0x%2.2x", src, dst, l2cap_pi(sk)->psm);
hdev = hci_get_route(dst, src);
if (!hdev)
@@ -4525,7 +4524,7 @@ static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
if (type != ACL_LINK)
return -EINVAL;
- BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
+ BT_DBG("hdev %s, bdaddr %pMbt", hdev->name, bdaddr);
/* Find listening sockets and check their link_mode */
read_lock(&l2cap_sk_list.lock);
@@ -4553,7 +4552,7 @@ static int l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
{
struct l2cap_conn *conn;
- BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
+ BT_DBG("hcon %p bdaddr %pMbt status %d", hcon, &hcon->dst, status);
if (hcon->type != ACL_LINK)
return -EINVAL;
@@ -4798,12 +4797,12 @@ static int l2cap_debugfs_show(struct seq_file *f, void *p)
sk_for_each(sk, node, &l2cap_sk_list.head) {
struct l2cap_pinfo *pi = l2cap_pi(sk);
- seq_printf(f, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d\n",
- batostr(&bt_sk(sk)->src),
- batostr(&bt_sk(sk)->dst),
- sk->sk_state, __le16_to_cpu(pi->psm),
- pi->scid, pi->dcid,
- pi->imtu, pi->omtu, pi->sec_level);
+ seq_printf(f, "%pMbt %pMbt %d %d 0x%4.4x 0x%4.4x %d %d %d\n",
+ &bt_sk(sk)->src,
+ &bt_sk(sk)->dst,
+ sk->sk_state, __le16_to_cpu(pi->psm),
+ pi->scid, pi->dcid,
+ pi->imtu, pi->omtu, pi->sec_level);
}
read_unlock_bh(&l2cap_sk_list.lock);
diff --git a/net/bluetooth/lib.c b/net/bluetooth/lib.c
index b826d1b..bfc8bbb 100644
--- a/net/bluetooth/lib.c
+++ b/net/bluetooth/lib.c
@@ -44,20 +44,6 @@ void baswap(bdaddr_t *dst, bdaddr_t *src)
}
EXPORT_SYMBOL(baswap);
-char *batostr(bdaddr_t *ba)
-{
- static char str[2][18];
- static int i = 1;
-
- i ^= 1;
- sprintf(str[i], "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
- ba->b[5], ba->b[4], ba->b[3],
- ba->b[2], ba->b[1], ba->b[0]);
-
- return str[i];
-}
-EXPORT_SYMBOL(batostr);
-
/* Bluetooth error codes to Unix errno mapping */
int bt_err(__u16 code)
{
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
index fa642aa..532e5ad 100644
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -393,8 +393,8 @@ static int __rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst,
int err = 0;
u8 dlci;
- BT_DBG("dlc %p state %ld %s %s channel %d",
- d, d->state, batostr(src), batostr(dst), channel);
+ BT_DBG("dlc %p state %ld %pMbt %pMbt channel %d",
+ d, d->state, src, dst, channel);
if (channel < 1 || channel > 30)
return -EINVAL;
@@ -692,7 +692,7 @@ static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src,
struct socket *sock;
struct sock *sk;
- BT_DBG("%s %s", batostr(src), batostr(dst));
+ BT_DBG("%pMbt %pMbt", src, dst);
*err = rfcomm_l2sock_create(&sock);
if (*err < 0)
@@ -2120,11 +2120,11 @@ static int rfcomm_dlc_debugfs_show(struct seq_file *f, void *x)
struct sock *sk = s->sock->sk;
struct rfcomm_dlc *d = list_entry(pp, struct rfcomm_dlc, list);
- seq_printf(f, "%s %s %ld %d %d %d %d\n",
- batostr(&bt_sk(sk)->src),
- batostr(&bt_sk(sk)->dst),
- d->state, d->dlci, d->mtu,
- d->rx_credits, d->tx_credits);
+ seq_printf(f, "%pMbt %pMbt %ld %d %d %d %d\n",
+ &bt_sk(sk)->src,
+ &bt_sk(sk)->dst,
+ d->state, d->dlci, d->mtu,
+ d->rx_credits, d->tx_credits);
}
}
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index 0207bd6..bbbc7479 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -350,7 +350,7 @@ static int rfcomm_sock_bind(struct socket *sock, struct sockaddr *addr, int addr
struct sock *sk = sock->sk;
int err = 0;
- BT_DBG("sk %p %s", sk, batostr(&sa->rc_bdaddr));
+ BT_DBG("sk %p %pMbt", sk, &sa->rc_bdaddr);
if (!addr || addr->sa_family != AF_BLUETOOTH)
return -EINVAL;
@@ -979,9 +979,9 @@ static int rfcomm_sock_debugfs_show(struct seq_file *f, void *p)
read_lock_bh(&rfcomm_sk_list.lock);
sk_for_each(sk, node, &rfcomm_sk_list.head) {
- seq_printf(f, "%s %s %d %d\n",
- batostr(&bt_sk(sk)->src),
- batostr(&bt_sk(sk)->dst),
+ seq_printf(f, "%pMbt %pMbt %d %d\n",
+ &bt_sk(sk)->src,
+ &bt_sk(sk)->dst,
sk->sk_state, rfcomm_pi(sk)->channel);
}
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c
index a9b81f5..740c99b 100644
--- a/net/bluetooth/rfcomm/tty.c
+++ b/net/bluetooth/rfcomm/tty.c
@@ -183,7 +183,7 @@ static struct device *rfcomm_get_device(struct rfcomm_dev *dev)
static ssize_t show_address(struct device *tty_dev, struct device_attribute *attr, char *buf)
{
struct rfcomm_dev *dev = dev_get_drvdata(tty_dev);
- return sprintf(buf, "%s\n", batostr(&dev->dst));
+ return sprintf(buf, "%pMbt\n", &dev->dst);
}
static ssize_t show_channel(struct device *tty_dev, struct device_attribute *attr, char *buf)
@@ -685,8 +685,8 @@ static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp)
if (!dev)
return -ENODEV;
- BT_DBG("dev %p dst %s channel %d opened %d", dev, batostr(&dev->dst),
- dev->channel, atomic_read(&dev->opened));
+ BT_DBG("dev %p dst %pMbt channel %d opened %d",
+ dev, &dev->dst, dev->channel, atomic_read(&dev->opened));
if (atomic_inc_return(&dev->opened) > 1)
return 0;
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index 66b9e5c..ac8370e 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -183,7 +183,7 @@ static int sco_connect(struct sock *sk)
struct hci_dev *hdev;
int err, type;
- BT_DBG("%s -> %s", batostr(src), batostr(dst));
+ BT_DBG("%pMbt -> %pMbt", src, dst);
if (!(hdev = hci_get_route(dst, src)))
return -EHOSTUNREACH;
@@ -457,7 +457,7 @@ static int sco_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_le
bdaddr_t *src = &sa->sco_bdaddr;
int err = 0;
- BT_DBG("sk %p %s", sk, batostr(&sa->sco_bdaddr));
+ BT_DBG("sk %p %pMbt", sk, src);
if (!addr || addr->sa_family != AF_BLUETOOTH)
return -EINVAL;
@@ -884,7 +884,7 @@ static int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type)
if (type != SCO_LINK && type != ESCO_LINK)
return -EINVAL;
- BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
+ BT_DBG("hdev %s, bdaddr %pMbt", hdev->name, bdaddr);
/* Find listening sockets */
read_lock(&sco_sk_list.lock);
@@ -905,7 +905,7 @@ static int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type)
static int sco_connect_cfm(struct hci_conn *hcon, __u8 status)
{
- BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
+ BT_DBG("hcon %p bdaddr %pMbt status %d", hcon, &hcon->dst, status);
if (hcon->type != SCO_LINK && hcon->type != ESCO_LINK)
return -EINVAL;
@@ -961,8 +961,8 @@ static int sco_debugfs_show(struct seq_file *f, void *p)
read_lock_bh(&sco_sk_list.lock);
sk_for_each(sk, node, &sco_sk_list.head) {
- seq_printf(f, "%s %s %d\n", batostr(&bt_sk(sk)->src),
- batostr(&bt_sk(sk)->dst), sk->sk_state);
+ seq_printf(f, "%pMbt %pMbt %d\n",
+ &bt_sk(sk)->src, &bt_sk(sk)->dst, sk->sk_state);
}
read_unlock_bh(&sco_sk_list.lock);
--
1.7.3.2.245.g03276.dirty
^ permalink raw reply related
* HID parser for Bluetooth devices
From: Viswanathan Sankararam @ 2010-12-04 18:36 UTC (permalink / raw)
To: linux-bluetooth
All, I am new to bluetooth. I am trying to understand where in Linux
stack a bluetooth HID device parser exists. Is it part of the
bluetooth HIDP driver or somehow hooks into the HID driver for USB HID
devices. Also I see that bluez sources has a directory called input
and an input.so file is created. What is the function of this library?
I would really appreciate an explanation of how bluez integrates with
Linxu input subsystem and HID parser.
Thanks
Vish
^ permalink raw reply
* Re: [compat-wireless] compat-wireless-2.6.37-rc4?
From: Luis R. Rodriguez @ 2010-12-04 21:29 UTC (permalink / raw)
To: sedat.dilek; +Cc: LKML, linux-wireless, linux-bluetooth
In-Reply-To: <AANLkTimr=ESQpid8yR-ZkK7uJcaOKoF9dAnmfPu1qiG3@mail.gmail.com>
On Thu, Dec 2, 2010 at 2:21 AM, Sedat Dilek <sedat.dilek@googlemail.com> wrote:
> Hi Luis,
>
> are you planning a stable compat-wireless-2.6.37-rc4 tarball?
>
> Kind Regards,
> - Sedat -
>
> [1] http://wireless.kernel.org/en/users/Download/stable/#Releases
>
Sure here:
http://www.orbit-lab.org/kernel/compat-wireless-2.6-stable/v2.6.37/compat-wireless-2.6.37-rc4-1.tar.bz2
ChangeLog:
http://www.orbit-lab.org/kernel/compat-wireless-2.6-stable/v2.6.37/ChangeLog-2.6.37-wireless
Sorry for the delay.
Luis
^ permalink raw reply
* Re: [PATCH] ath3k: reduce memory usage
From: Alexander Holler @ 2010-12-05 14:28 UTC (permalink / raw)
To: Bala Shanmugam
Cc: Gustavo F. Padovan, SongXing Xu, Luis Rodriguez, Vikram Kandukuri,
linux-bluetooth@vger.kernel.org
In-Reply-To: <4CF8CBB1.90506@atheros.com>
Hello,
Am 03.12.2010 11:51, schrieb Bala Shanmugam:
> I manually made these changes and its not working.
> I am unable to apply Alex patch taken from my office id.
> Alex can you send the patch to btlinuxmail@gmail.com.
The patch applies cleanly to 2.6.36.x and the current 2.6.37 as found in
Linus tree. I'm using that patch on an armv5, a x86_64 (both 2.6.36.1)
and on an armv7 with 2.6.37-rc4.
I've sent it to the above e-mail address.
Regards,
Alexander
^ permalink raw reply
* Initial Management interface patches (rebased)
From: johan.hedberg @ 2010-12-05 18:19 UTC (permalink / raw)
To: linux-bluetooth
Hi,
I'm resending these since the original set no longer applies cleanly to
bluetooth-next-2.6.git (due to some coding style cleanup patches that
were pushed there recently). I've kept the already received acks since
essentally there aren't other changes besides those meant to make these
apply cleanly.
Johan
^ permalink raw reply
* [PATCH 1/3] Bluetooth: Add Bluetooth Management interface definitions
From: johan.hedberg @ 2010-12-05 18:19 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Johan Hedberg
In-Reply-To: <1291573170-3708-1-git-send-email-johan.hedberg@gmail.com>
From: Johan Hedberg <johan.hedberg@nokia.com>
Add initial definitions for the new Bluetooth Management interface to
the bluetooth headers.
Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com>
Acked-by: Marcel Holtmann <marcel@holtmann.org>
---
include/net/bluetooth/hci.h | 4 +++
include/net/bluetooth/hci_core.h | 1 +
include/net/bluetooth/mgmt.h | 46 ++++++++++++++++++++++++++++++++++++++
3 files changed, 51 insertions(+), 0 deletions(-)
create mode 100644 include/net/bluetooth/mgmt.h
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index f3c5ed6..29a7a8c 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -934,9 +934,13 @@ static inline struct hci_sco_hdr *hci_sco_hdr(const struct sk_buff *skb)
struct sockaddr_hci {
sa_family_t hci_family;
unsigned short hci_dev;
+ unsigned short hci_channel;
};
#define HCI_DEV_NONE 0xffff
+#define HCI_CHANNEL_RAW 0
+#define HCI_CHANNEL_CONTROL 1
+
struct hci_filter {
unsigned long type_mask;
unsigned long event_mask[2];
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 9c08625..3e34359 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -668,6 +668,7 @@ struct hci_pinfo {
struct hci_dev *hdev;
struct hci_filter filter;
__u32 cmsg_mask;
+ unsigned short channel;
};
/* HCI security filter */
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
new file mode 100644
index 0000000..95974da
--- /dev/null
+++ b/include/net/bluetooth/mgmt.h
@@ -0,0 +1,46 @@
+/*
+ BlueZ - Bluetooth protocol stack for Linux
+
+ Copyright (C) 2010 Nokia Corporation
+
+ 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.
+*/
+
+struct mgmt_hdr {
+ __le16 opcode;
+ __le16 len;
+} __packed;
+#define MGMT_HDR_SIZE 4
+
+#define MGMT_EV_CMD_COMPLETE 0x0001
+struct mgmt_ev_cmd_complete {
+ __le16 opcode;
+ __u8 data[0];
+} __packed;
+
+#define MGMT_EV_CMD_STATUS 0x0002
+struct mgmt_ev_cmd_status {
+ __u8 status;
+ __le16 opcode;
+} __packed;
+
+#define MGMT_EV_CONTROLLER_ERROR 0x0003
+struct mgmt_ev_controller_error {
+ __le16 index;
+ __u8 error_code;
+} __packed;
--
1.7.2.3
^ permalink raw reply related
* [PATCH 2/3] Bluetooth: Add initial Bluetooth Management interface callbacks
From: johan.hedberg @ 2010-12-05 18:19 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Johan Hedberg
In-Reply-To: <1291573170-3708-1-git-send-email-johan.hedberg@gmail.com>
From: Johan Hedberg <johan.hedberg@nokia.com>
Add initial code for handling Bluetooth Management interface messages.
Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com>
Acked-by: Marcel Holtmann <marcel@holtmann.org>
Acked-by: Andrei Emeltchenko <andrei.emeltchenko@nokia.com>
---
include/net/bluetooth/hci_core.h | 3 +
net/bluetooth/Makefile | 2 +-
net/bluetooth/hci_sock.c | 39 +++++++++++++--
net/bluetooth/mgmt.c | 99 ++++++++++++++++++++++++++++++++++++++
4 files changed, 136 insertions(+), 7 deletions(-)
create mode 100644 net/bluetooth/mgmt.c
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 3e34359..1992fac 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -660,6 +660,9 @@ void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data);
/* ----- HCI Sockets ----- */
void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb);
+/* Management interface */
+int mgmt_control(struct sock *sk, struct msghdr *msg, size_t len);
+
/* HCI info for socket */
#define hci_pi(sk) ((struct hci_pinfo *) sk)
diff --git a/net/bluetooth/Makefile b/net/bluetooth/Makefile
index d1e433f..8b411d9 100644
--- a/net/bluetooth/Makefile
+++ b/net/bluetooth/Makefile
@@ -10,4 +10,4 @@ obj-$(CONFIG_BT_BNEP) += bnep/
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
+bluetooth-objs := af_bluetooth.o hci_core.o hci_conn.o hci_event.o mgmt.o hci_sock.o hci_sysfs.o lib.o
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index b3753ba..207be7a 100644
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -49,6 +49,8 @@
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
+static int enable_mgmt;
+
/* ----- HCI socket interface ----- */
static inline int hci_test_bit(int nr, void *addr)
@@ -353,25 +355,35 @@ static int hci_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long a
static int hci_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
{
- struct sockaddr_hci *haddr = (struct sockaddr_hci *) addr;
+ struct sockaddr_hci haddr;
struct sock *sk = sock->sk;
struct hci_dev *hdev = NULL;
- int err = 0;
+ int len, err = 0;
BT_DBG("sock %p sk %p", sock, sk);
- if (!haddr || haddr->hci_family != AF_BLUETOOTH)
+ if (!addr)
+ return -EINVAL;
+
+ memset(&haddr, 0, sizeof(haddr));
+ len = min_t(unsigned int, sizeof(haddr), addr_len);
+ memcpy(&haddr, addr, len);
+
+ if (haddr.hci_family != AF_BLUETOOTH)
+ return -EINVAL;
+
+ if (haddr.hci_channel != HCI_CHANNEL_RAW && !enable_mgmt)
return -EINVAL;
lock_sock(sk);
- if (hci_pi(sk)->hdev) {
+ if (sk->sk_state == BT_BOUND || hci_pi(sk)->hdev) {
err = -EALREADY;
goto done;
}
- if (haddr->hci_dev != HCI_DEV_NONE) {
- hdev = hci_dev_get(haddr->hci_dev);
+ if (haddr.hci_dev != HCI_DEV_NONE) {
+ hdev = hci_dev_get(haddr.hci_dev);
if (!hdev) {
err = -ENODEV;
goto done;
@@ -380,6 +392,7 @@ static int hci_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_le
atomic_inc(&hdev->promisc);
}
+ hci_pi(sk)->channel = haddr.hci_channel;
hci_pi(sk)->hdev = hdev;
sk->sk_state = BT_BOUND;
@@ -502,6 +515,17 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
lock_sock(sk);
+ switch (hci_pi(sk)->channel) {
+ case HCI_CHANNEL_RAW:
+ break;
+ case HCI_CHANNEL_CONTROL:
+ err = mgmt_control(sk, msg, len);
+ goto done;
+ default:
+ err = -EINVAL;
+ goto done;
+ }
+
hdev = hci_pi(sk)->hdev;
if (!hdev) {
err = -EBADFD;
@@ -831,3 +855,6 @@ void __exit hci_sock_cleanup(void)
proto_unregister(&hci_sk_proto);
}
+
+module_param(enable_mgmt, bool, 0644);
+MODULE_PARM_DESC(enable_mgmt, "Enable Management interface");
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
new file mode 100644
index 0000000..78255f1
--- /dev/null
+++ b/net/bluetooth/mgmt.c
@@ -0,0 +1,99 @@
+/*
+ BlueZ - Bluetooth protocol stack for Linux
+ Copyright (C) 2010 Nokia Corporation
+
+ 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.
+*/
+
+/* Bluetooth HCI Management interface */
+
+#include <asm/uaccess.h>
+#include <asm/unaligned.h>
+
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h>
+#include <net/bluetooth/mgmt.h>
+
+static void cmd_status(struct sock *sk, u16 cmd, u8 status)
+{
+ 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);
+ if (!skb)
+ return;
+
+ hdr = (void *) skb_put(skb, sizeof(struct mgmt_hdr));
+
+ hdr->opcode = cpu_to_le16(MGMT_EV_CMD_STATUS);
+ hdr->len = cpu_to_le16(3);
+
+ ev = (void *) skb_put(skb, sizeof(*ev));
+ ev->status = status;
+ put_unaligned_le16(cmd, &ev->opcode);
+
+ if (sock_queue_rcv_skb(sk, skb) < 0)
+ kfree_skb(skb);
+}
+
+int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
+{
+ unsigned char *buf;
+ struct mgmt_hdr *hdr;
+ u16 opcode, len;
+ int err;
+
+ BT_DBG("got %zu bytes", msglen);
+
+ if (msglen < sizeof(*hdr))
+ return -EINVAL;
+
+ buf = kmalloc(msglen, GFP_ATOMIC);
+ if (!buf)
+ return -ENOMEM;
+
+ if (memcpy_fromiovec(buf, msg->msg_iov, msglen)) {
+ err = -EFAULT;
+ goto done;
+ }
+
+ hdr = (struct mgmt_hdr *) buf;
+ opcode = get_unaligned_le16(&hdr->opcode);
+ len = get_unaligned_le16(&hdr->len);
+
+ if (len != msglen - sizeof(struct mgmt_hdr)) {
+ err = -EINVAL;
+ goto done;
+ }
+
+ switch (opcode) {
+ default:
+ BT_DBG("Unknown op %u", opcode);
+ cmd_status(sk, opcode, 0x01);
+ break;
+ }
+
+ err = msglen;
+
+done:
+ kfree(buf);
+ return err;
+}
--
1.7.2.3
^ permalink raw reply related
* [PATCH 3/3] Bluetooth: Make hci_send_to_sock usable for management control sockets
From: johan.hedberg @ 2010-12-05 18:19 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Johan Hedberg
In-Reply-To: <1291573170-3708-1-git-send-email-johan.hedberg@gmail.com>
From: Johan Hedberg <johan.hedberg@nokia.com>
In order to send data to management control sockets the function should:
- skip checks intended for raw HCI data and stack internal events
- make sure RAW HCI data or stack internal events don't go to
management control sockets
In order to accomplish this the patch adds a new member to the bluetooth
skb private data to flag skb's that are destined for management control
sockets.
Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com>
Acked-by: Marcel Holtmann <marcel@holtmann.org>
---
include/net/bluetooth/bluetooth.h | 1 +
net/bluetooth/hci_sock.c | 10 +++++++++-
2 files changed, 10 insertions(+), 1 deletions(-)
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
index d81ea79..0c5e725 100644
--- a/include/net/bluetooth/bluetooth.h
+++ b/include/net/bluetooth/bluetooth.h
@@ -144,6 +144,7 @@ struct bt_skb_cb {
__u8 tx_seq;
__u8 retries;
__u8 sar;
+ unsigned short channel;
};
#define bt_cb(skb) ((struct bt_skb_cb *)((skb)->cb))
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index 207be7a..f6c18ab 100644
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -104,6 +104,12 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb)
if (skb->sk == sk)
continue;
+ if (bt_cb(skb)->channel != hci_pi(sk)->channel)
+ continue;
+
+ if (bt_cb(skb)->channel == HCI_CHANNEL_CONTROL)
+ goto clone;
+
/* Apply filter */
flt = &hci_pi(sk)->filter;
@@ -127,12 +133,14 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb)
continue;
}
+clone:
nskb = skb_clone(skb, GFP_ATOMIC);
if (!nskb)
continue;
/* Put type byte before the data */
- memcpy(skb_push(nskb, 1), &bt_cb(nskb)->pkt_type, 1);
+ if (bt_cb(skb)->channel == HCI_CHANNEL_RAW)
+ memcpy(skb_push(nskb, 1), &bt_cb(nskb)->pkt_type, 1);
if (sock_queue_rcv_skb(sk, nskb))
kfree_skb(nskb);
--
1.7.2.3
^ permalink raw reply related
* Re: [PATCH 5/9] mfd: Add UART support for the ST-Ericsson CG2900.
From: Par-Gunnar Hjalmdahl @ 2010-12-06 9:06 UTC (permalink / raw)
To: Vitaly Wool
Cc: Alan Cox, linus.walleij, linux-bluetooth, linux-kernel,
Arnd Bergmann, Marcel Holtmann
In-Reply-To: <AANLkTim7brB0JecKXDNddt0am=Um457Kfbm6bRG_yzFM@mail.gmail.com>
Hi Vitaly,
2010/12/3 Vitaly Wool <vitalywool@gmail.com>:
> Hi Par,
>
> On Fri, Dec 3, 2010 at 10:16 AM, Par-Gunnar Hjalmdahl
> <pghatwork@gmail.com> wrote:
>> 2010/10/29 Alan Cox <alan@lxorguk.ukuu.org.uk>:
>
>> By the way, I will soon release a new patch set for CG2900 (hopefully
>> next week), which contains major rework. It's hard to explain
>> everything here and now but changes include:
>> =A0- Reuse of existing HCI line discipline under /drivers/bluetooth/.
>> Line discipline has been modified so it is selectable from protocol if
>> line discipline should register to Bluetooth stack or not.
>
> So is it true that if there's the other chip with similar
> functionality I have to implement support for, I'll have to pretty
> much duplicate your line discipline driver?
>
What will be in the protocol file, i.e. the same level as hci_h4.c,
hci_bcsp.c, etc, will be to ~80% vendor specific. The only H4 channels
that are in a standardized specification are the Bluetooth channels
1-4. Other channels such as FM and GPS are vendor specific. I've seen
that for example TI has the same channels for FM and GPS, but these
channels, 8 and 9, are in no way standardized. The CG2900 also carries
a number of other channels, such as debug and device channels, which
I'm pretty sure is individual for this chip.
This identification of the channels is also only one function, even
though it is an important function. There are also a lot of other code
regarding baud rate settings, low power handling, etc that I'm
positive will not apply to chips of other vendors. It is of course
possible that other chips from ST-Ericsson, current and future, will
be able to reuse this file, but as I said I doubt that other vendors
might be able to use it.
> Isn't it better to have a new line discipline that the standard
> drivers (H4, LL, ...) will be applicable to?
>
> ~Vitaly
>
I'm not certain what you mean. We are modifying the line discipline a
bit, but the only thing we have needed to do with existing protocol
drivers has been to add a boolean parameter for the protocol settings
(so they will register to the Bluetooth stack). I don't see why we
should create a new line discipline driver and then move the existing
protocol drivers to this.
/P-G
^ permalink raw reply
* Re: [PATCHv4 0/7] Support for out of band association model
From: Szymon Janc @ 2010-12-06 9:46 UTC (permalink / raw)
To: Mike Tsai; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <35B17FE5076C7040809188FBE7913F98406D68D125@SC1EXMB-MBCL.global.atheros.com>
Hi,
> [Mtsai correction]
> The local OOB data present is set when host send HCI command "Read Local OOB
> Data". And this "OOB data present" flag is sent over the air to peer device
> during pairing.
I think you confused local and remote OOB data.
This flag is about "OOB authentication data from remote device present".
Please see Vol.2 Part E. 7.1.29 "IO Capability Request Reply Command".
--
Szymon Janc
on behalf of ST-Ericsson
^ permalink raw reply
* Re: [PATCH 5/9] mfd: Add UART support for the ST-Ericsson CG2900.
From: Vitaly Wool @ 2010-12-06 9:46 UTC (permalink / raw)
To: Par-Gunnar Hjalmdahl
Cc: Alan Cox, linus.walleij, linux-bluetooth, linux-kernel,
Arnd Bergmann, Marcel Holtmann
In-Reply-To: <AANLkTik4T=PsMzB+umSQPLDPmeD-6sebgCtrQRePH_2h@mail.gmail.com>
Hi Par,
On Mon, Dec 6, 2010 at 10:06 AM, Par-Gunnar Hjalmdahl
<pghatwork@gmail.com> wrote:
>> So is it true that if there's the other chip with similar
>> functionality I have to implement support for, I'll have to pretty
>> much duplicate your line discipline driver?
>>
>
> What will be in the protocol file, i.e. the same level as hci_h4.c,
> hci_bcsp.c, etc, will be to ~80% vendor specific. The only H4 channels
> that are in a standardized specification are the Bluetooth channels
> 1-4. Other channels such as FM and GPS are vendor specific. I've seen
> that for example TI has the same channels for FM and GPS, but these
> channels, 8 and 9, are in no way standardized. The CG2900 also carries
> a number of other channels, such as debug and device channels, which
> I'm pretty sure is individual for this chip.
> This identification of the channels is also only one function, even
> though it is an important function. There are also a lot of other code
> regarding baud rate settings, low power handling, etc that I'm
> positive will not apply to chips of other vendors. It is of course
> possible that other chips from ST-Ericsson, current and future, will
> be able to reuse this file, but as I said I doubt that other vendors
> might be able to use it.
Wait. What level of abstraction is this file at if even some future
STE chips are not guaranteed to work with it? Is it at a level of
hardcoding the GPIO numbers?
>> Isn't it better to have a new line discipline that the standard
>> drivers (H4, LL, ...) will be applicable to?
> I'm not certain what you mean. We are modifying the line discipline a
> bit, but the only thing we have needed to do with existing protocol
> drivers has been to add a boolean parameter for the protocol settings
> (so they will register to the Bluetooth stack). I don't see why we
> should create a new line discipline driver and then move the existing
> protocol drivers to this.
Okay, let me try to be more specific. There's for instance
drivers/bluetooth/hci_ll.c which is the line discipline driver that is
meant to work with any BT chip supporting LL protocol. Your solution
seems to imply that one will have to create a variation of this
implementation for each BT chip supporting LL that will use your
shared transport implementation. Is it really the case?
Thanks,
Vitaly
^ permalink raw reply
* Re: [PATCH 5/9] mfd: Add UART support for the ST-Ericsson CG2900.
From: Par-Gunnar Hjalmdahl @ 2010-12-06 12:01 UTC (permalink / raw)
To: Vitaly Wool
Cc: Alan Cox, linus.walleij, linux-bluetooth, linux-kernel,
Arnd Bergmann, Marcel Holtmann
In-Reply-To: <AANLkTimjACtU_Mx5mDHkm9OpVJ4ueNWgZPsX3YjL0cTi@mail.gmail.com>
Hi Vitaly,
2010/12/6 Vitaly Wool <vitalywool@gmail.com>:
> Hi Par,
>
> On Mon, Dec 6, 2010 at 10:06 AM, Par-Gunnar Hjalmdahl
> <pghatwork@gmail.com> wrote:
>
>>> So is it true that if there's the other chip with similar
>>> functionality I have to implement support for, I'll have to pretty
>>> much duplicate your line discipline driver?
>>>
>>
>> What will be in the protocol file, i.e. the same level as hci_h4.c,
>> hci_bcsp.c, etc, will be to ~80% vendor specific. The only H4 channels
>> that are in a standardized specification are the Bluetooth channels
>> 1-4. Other channels such as FM and GPS are vendor specific. I've seen
>> that for example TI has the same channels for FM and GPS, but these
>> channels, 8 and 9, are in no way standardized. The CG2900 also carries
>> a number of other channels, such as debug and device channels, which
>> I'm pretty sure is individual for this chip.
>> This identification of the channels is also only one function, even
>> though it is an important function. There are also a lot of other code
>> regarding baud rate settings, low power handling, etc that I'm
>> positive will not apply to chips of other vendors. It is of course
>> possible that other chips from ST-Ericsson, current and future, will
>> be able to reuse this file, but as I said I doubt that other vendors
>> might be able to use it.
>
> Wait. What level of abstraction is this file at if even some future
> STE chips are not guaranteed to work with it? Is it at a level of
> hardcoding the GPIO numbers?
>
There are no GPIOs or similar in the driver code; those are defined
and used in the board specific files under the /arch/ files. What
could be a problem with a future chip would be if for example the HCI
command to change baud rate would change. We have no indication that
this will change, but I cannot give a lifetime guarantee that nothing
will ever change with how the chip startup is handled.
>>> Isn't it better to have a new line discipline that the standard
>>> drivers (H4, LL, ...) will be applicable to?
>
>> I'm not certain what you mean. We are modifying the line discipline a
>> bit, but the only thing we have needed to do with existing protocol
>> drivers has been to add a boolean parameter for the protocol settings
>> (so they will register to the Bluetooth stack). I don't see why we
>> should create a new line discipline driver and then move the existing
>> protocol drivers to this.
>
> Okay, let me try to be more specific. There's for instance
> drivers/bluetooth/hci_ll.c which is the line discipline driver that is
> meant to work with any BT chip supporting LL protocol. Your solution
> seems to imply that one will have to create a variation of this
> implementation for each BT chip supporting LL that will use your
> shared transport implementation. Is it really the case?
>
> Thanks,
> =A0 Vitaly
>
Well, from what I can see LL is an extension of the H4, basically it
adds sleep mode handling in a vendor specific way to the normal H4
protocol. So it is also based on the hci_h4 just as our file is. But
our file has basically nothing in common with what has been for the LL
file. We don't support any of the LL sleep commands for example.
So if I would make a driver for a combo chip supporting LL, I would
either modify the existing hci_ll.c or I would make a new file based
on hci_ll.c. There is not much you could really reuse from our new
file. Basically it would be the handling of any common channels, so if
you would for example have the same specification of FM and GPS you
could maybe save around 20 lines of common code, but you would
probably have to add a lot of more code just to keep the solution
generic.
One major difference is also that hci_ll never changes baud rate or
other settings. I assume that is done from hciattach during startup
instead. But we cannot run with that since we have to shut down the
chip when no user is connected in order to save power. This means that
we have to add vendor specific commands in order to for example set
baud rate. And then you run into these vendor specific problems. If
there would be a standardized specification on how to set baud rate
and how to put chip in sleep I assume things could be solved
differently, but that is not the case.
As a quick answer to your question: that would depend on the
difference between the different controllers, I guess. But CG2900
doesn't support the LL protocol so it is not an issue for that.
/P-G
^ permalink raw reply
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