* Re: Read Characteristic Value vs. Read Long Characteristic Values
From: Anderson Lizardo @ 2011-01-26 18:28 UTC (permalink / raw)
To: Brian Gix; +Cc: BlueZ development
In-Reply-To: <1296064762.2656.137.camel@ubuntuLab1>
On Wed, Jan 26, 2011 at 1:59 PM, Brian Gix <bgix@codeaurora.org> wrote:
> Hi Anderson,
>
> On Wed, 2011-01-26 at 09:58 -0400, Anderson Lizardo wrote:
>> On Wed, Jan 26, 2011 at 9:33 AM, Anderson Lizardo
>> <anderson.lizardo@openbossa.org> wrote:
>> > Looks like more a PTS bug, but makes me wonder if it is not better for
>> > BlueZ to have separate procedures instead of this "automatic" usage of
>> > read blob request ?
>>
>> BTW, the test which presented this issue with sending spurious read
>> blob request is named "Read Characteristic Descriptors – by client". I
>> also can see that the behavior you implemented satisfies both "Read
>> Long Characteristic Value - by client" and "Read Long Characteristic
>> Descriptor - by client" tests. All theses tests come from the GATT TS
>> document.
>
> Can you tell me the specific Test Case number(s) that you are having
> difficulty testing? I do not have a current release of the PTS tool
> available to me at this time, although I do know that PTS is developed
> in parallel, and is just as prone to bugs as the rest of us. I should be
> able to test this stuff against the PTS guys at UPF week after next, and
> talk to the guys who are writing it.
At least these break with the current implementation:
TP/GAR/CL/BV-06-C (PTS does not expect a Read blob request after Read Request)
TP/GAR/CL/BI-12-C (test procedure expects Read Blob Request, not Read Request)
TP/GAR/CL/BI-13-C (same as above)
TP/GAR/CL/BI-14-C (same as above)
TP/GAR/CL/BI-28-C (same as above)
TP/GAR/CL/BV-07-C (same as above)
Except for the first test case, the specific requirement for a Read
Blob Request is defined on the test procedure of the GATT TS document
itself, so in these cases I don't think it's PTS bug.
Regards,
--
Anderson Lizardo
OpenBossa Labs - INdT
Manaus - Brazil
^ permalink raw reply
* Re: Read Characteristic Value vs. Read Long Characteristic Values
From: Brian Gix @ 2011-01-26 19:57 UTC (permalink / raw)
To: Anderson Lizardo; +Cc: BlueZ development
In-Reply-To: <AANLkTinbmiew-MBN7PxK5ePuObzBbHbqdteaB2nS3nty@mail.gmail.com>
On Wed, 2011-01-26 at 14:28 -0400, Anderson Lizardo wrote:
> On Wed, Jan 26, 2011 at 1:59 PM, Brian Gix <bgix@codeaurora.org> wrote:
> > Hi Anderson,
> >
> > On Wed, 2011-01-26 at 09:58 -0400, Anderson Lizardo wrote:
> >> On Wed, Jan 26, 2011 at 9:33 AM, Anderson Lizardo
> >> <anderson.lizardo@openbossa.org> wrote:
> >> > Looks like more a PTS bug, but makes me wonder if it is not better for
> >> > BlueZ to have separate procedures instead of this "automatic" usage of
> >> > read blob request ?
> >>
> >> BTW, the test which presented this issue with sending spurious read
> >> blob request is named "Read Characteristic Descriptors – by client". I
> >> also can see that the behavior you implemented satisfies both "Read
> >> Long Characteristic Value - by client" and "Read Long Characteristic
> >> Descriptor - by client" tests. All theses tests come from the GATT TS
> >> document.
> >
> > Can you tell me the specific Test Case number(s) that you are having
> > difficulty testing? I do not have a current release of the PTS tool
> > available to me at this time, although I do know that PTS is developed
> > in parallel, and is just as prone to bugs as the rest of us. I should be
> > able to test this stuff against the PTS guys at UPF week after next, and
> > talk to the guys who are writing it.
>
> At least these break with the current implementation:
>
> TP/GAR/CL/BV-06-C (PTS does not expect a Read blob request after Read Request)
This sounds like a PTS failure. The actual MSC will be followed, and
the fact that a follow READ_BLOB is made is outside the scope of the
test. If the PTS were working as a properly functioning server it
should respond with *something* even if it is "Command Not Supported" or
something, which would be handled correctly by bluez.
> TP/GAR/CL/BI-12-C (test procedure expects Read Blob Request, not Read Request)
> TP/GAR/CL/BI-13-C (same as above)
> TP/GAR/CL/BI-14-C (same as above)
These two tests will need special APIs written which do not necessarily
need to be exposed as upper layer APIs. The test in both cases is to
ensure that the client can properly handle error returns from the
server. These are not tests that a high level application would
typically be able to run, since using an invalid offset or handle should
never come up. However, these tests were likely added as robustness
tests for client to prevent, for example, denial of service attacks, or
other robustness issues made famous in the BT world by tools such as
Codenomicon's robustness suite.
Therefore, for these two tests, a test-only GATT API could be written
that specifies specific Handle and Offset arguments to a bare ATT
READ_BLOB call. But I would argue against including this as an upper
layer (D-Bus) API.
> TP/GAR/CL/BI-28-C (same as above)
The above Test API would again work for this. However, again, a properly
function high level Application should never be issuing an actual Read
to an attribute that has been flagged as Write Only, or Security
Required (withoutout the security in place).
> TP/GAR/CL/BV-07-C (same as above)
I believe this Test Case itself may be flawed. While it can also be
tested with the above described Test API, the "Read Long Characteristic
Values" GATT functionality is explicitly allowed as a chain from the
single pkt "Read Characteristic Value", from the Note (3rd Paragraph) of
page 562 in the Core 4.0 specification for GATT. (this is page 1922 of
the full Cove 4.0 PDF file) --> "Note: The Read Blob Request may be used
to read the remainder of an Attribute where the first part was read
using a simple Read Request."
The test cases are intended to ensure that the functionality used are
used correctly. They are not intended to force the usage of unneeded
functionality.
I will talk to the PTS guys at UPF, and make sure that the PIXIT lists
are setup such that the tests required for qualification correctly
mandate the correct subset of test cases as required by the ruling
specification.
>
> Except for the first test case, the specific requirement for a Read
> Blob Request is defined on the test procedure of the GATT TS document
> itself, so in these cases I don't think it's PTS bug.
>
> Regards,
--
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
* [PATCH] Set connection state to BT_DISCONN to avoid multiple responses
From: tim.bao @ 2011-01-27 1:21 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Bao Liang
From: Bao Liang <tim.bao@gmail.com>
This patch fixes a minor issue that two connection responses will be sent
for one L2CAP connection request. If the L2CAP connection request is first
blocked due to security reason and responded with reason "security block",
the state of the connection remains BT_CONNECT2. If a pairing procedure
completes successfully before the ACL connection is down, local host will
send another connection complete response. See the following packets
captured by hcidump.
2010-12-07 22:21:24.928096 < ACL data: handle 12 flags 0x00 dlen 16
0000: 0c 00 01 00 03 19 08 00 41 00 53 00 03 00 00 00 ........A.S.....
... ...
2010-12-07 22:21:35.791747 > HCI Event: Auth Complete (0x06) plen 3
status 0x00 handle 12
... ...
2010-12-07 22:21:35.872372 > ACL data: handle 12 flags 0x02 dlen 16
L2CAP(s): Connect rsp: dcid 0x0054 scid 0x0040 result 0 status 0
Connection successful
Signed-off-by: Bao Liang <tim.bao@gmail.com>
---
net/bluetooth/l2cap.c | 5 +++--
1 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index fadf26b..40d70db 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -844,9 +844,10 @@ static void __l2cap_sock_close(struct sock *sk, int reason)
struct l2cap_conn_rsp rsp;
__u16 result;
- if (bt_sk(sk)->defer_setup)
+ if (bt_sk(sk)->defer_setup) {
+ sk->sk_state = BT_DISCONN;
result = L2CAP_CR_SEC_BLOCK;
- else
+ } else
result = L2CAP_CR_BAD_PSM;
rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
--
1.7.1
^ permalink raw reply related
* Re: [PATCH] Set connection state to BT_DISCONN to avoid multiple responses
From: Ville Tervo @ 2011-01-27 7:40 UTC (permalink / raw)
To: ext tim.bao@gmail.com; +Cc: linux-bluetooth
In-Reply-To: <1296091276-2238-1-git-send-email-tim.bao@gmail.com>
Hi,
On Thu, Jan 27, 2011 at 09:21:16AM +0800, ext tim.bao@gmail.com wrote:
> From: Bao Liang <tim.bao@gmail.com>
>
> This patch fixes a minor issue that two connection responses will be sent
> for one L2CAP connection request. If the L2CAP connection request is first
> blocked due to security reason and responded with reason "security block",
> the state of the connection remains BT_CONNECT2. If a pairing procedure
> completes successfully before the ACL connection is down, local host will
> send another connection complete response. See the following packets
> captured by hcidump.
>
> 2010-12-07 22:21:24.928096 < ACL data: handle 12 flags 0x00 dlen 16
> 0000: 0c 00 01 00 03 19 08 00 41 00 53 00 03 00 00 00 ........A.S.....
> ... ...
>
> 2010-12-07 22:21:35.791747 > HCI Event: Auth Complete (0x06) plen 3
> status 0x00 handle 12
> ... ...
>
> 2010-12-07 22:21:35.872372 > ACL data: handle 12 flags 0x02 dlen 16
> L2CAP(s): Connect rsp: dcid 0x0054 scid 0x0040 result 0 status 0
> Connection successful
>
> Signed-off-by: Bao Liang <tim.bao@gmail.com>
> ---
> net/bluetooth/l2cap.c | 5 +++--
> 1 files changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
> index fadf26b..40d70db 100644
> --- a/net/bluetooth/l2cap.c
> +++ b/net/bluetooth/l2cap.c
> @@ -844,9 +844,10 @@ static void __l2cap_sock_close(struct sock *sk, int reason)
> struct l2cap_conn_rsp rsp;
> __u16 result;
>
> - if (bt_sk(sk)->defer_setup)
> + if (bt_sk(sk)->defer_setup) {
> + sk->sk_state = BT_DISCONN;
> result = L2CAP_CR_SEC_BLOCK;
> - else
> + } else
> result = L2CAP_CR_BAD_PSM;
>
> rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Shouldn't sk->sk_state be changed in all cases and not only when socket is
waiting for authorization?
Otherwise patch looks good to me.
--
Ville
^ permalink raw reply
* Re: [RFC 1/1] Device initialization and controller type resolving
From: Ville Tervo @ 2011-01-27 7:59 UTC (permalink / raw)
To: ext André Dieb; +Cc: linux-bluetooth
In-Reply-To: <AANLkTimqtWzKS4H+veJE2PCXH0o5CLJwrspMTfQyd=AR@mail.gmail.com>
Hi Andre,
On Wed, Jan 26, 2011 at 12:34:02PM -0200, ext André Dieb wrote:
> From: André Dieb Martins <andre.dieb@signove.com>
>
> This patch proposes to use LMP features in order to resolve the controller
> type. Currently there's very few code (mostly inside drivers) that cares
> about differentiating controller types (BR/EDR, BR/EDR/LE, LE only, AMP).
>
> Once determined dev_type, the idea would be to implement controller-type
> specific initialization procedures. There's an initialization code for BR/EDR
> devices and some early adaptation for BR/EDR/LE, but nothing regarding
> LE-only - and I'm willing to tackle that, based on your pointers.
>
> Would it be better to always let drivers modify their device's dev_type?
>
> What would be the correct approach?
>
> PS: Please don't bother the CC2540 hack. Consider it a joke :-).
Separate it to another patch then. I have these dongles but they had some
proprietary interface. From where did you get fw with hci interface? it would
be nice to test also with LE only hw.
>
> Signed-off-by: André Dieb Martins <andre.dieb@signove.com>
> ---
> include/net/bluetooth/hci.h | 78 ++++++++++++++++++++++++++++++-------
> include/net/bluetooth/hci_core.h | 3 +
> net/bluetooth/hci_core.c | 8 ++--
> net/bluetooth/hci_event.c | 24 ++++++++++++
> net/bluetooth/hci_sysfs.c | 4 ++
> 5 files changed, 98 insertions(+), 19 deletions(-)
>
> diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
> index 036fdae..ae9f095 100644
> --- a/include/net/bluetooth/hci.h
> +++ b/include/net/bluetooth/hci.h
> @@ -55,6 +55,8 @@
> /* HCI controller types */
> #define HCI_BREDR 0x00
> #define HCI_AMP 0x01
> +#define HCI_BREDRLE 0x02
> +#define HCI_LE 0x03
>
> /* HCI device quirks */
> enum {
> @@ -163,6 +165,8 @@ enum {
> #define LE_LINK 0x80
>
> /* LMP features */
> +
> +/* byte 0 */
> #define LMP_3SLOT 0x01
> #define LMP_5SLOT 0x02
> #define LMP_ENCRYPT 0x04
> @@ -172,6 +176,7 @@ enum {
> #define LMP_HOLD 0x40
> #define LMP_SNIFF 0x80
>
> +/* byte 1 */
> #define LMP_PARK 0x01
> #define LMP_RSSI 0x02
> #define LMP_QUALITY 0x04
> @@ -181,22 +186,65 @@ enum {
> #define LMP_ULAW 0x40
> #define LMP_ALAW 0x80
>
> -#define LMP_CVSD 0x01
> -#define LMP_PSCHEME 0x02
> +/* byte 2 */
> +#define LMP_CVSD 0x01
> +#define LMP_PSCHEME 0x02
> #define LMP_PCONTROL 0x04
> -
> -#define LMP_ESCO 0x80
> -
> -#define LMP_EV4 0x01
> -#define LMP_EV5 0x02
> -#define LMP_LE 0x40
> -
> -#define LMP_SNIFF_SUBR 0x02
> -#define LMP_EDR_ESCO_2M 0x20
> -#define LMP_EDR_ESCO_3M 0x40
> -#define LMP_EDR_3S_ESCO 0x80
> -
> -#define LMP_SIMPLE_PAIR 0x08
> +#define LMP_TSYNC 0x08
> +#define LMP_FLOWLAGLSB 0x10
> +#define LMP_FLOWLAGMB 0x20
> +#define LMP_FLOWLAGMSB 0x40
> +#define LMP_BROADCAST_ENCRYPTION 0x80
> +
> +/* byte 3 */
> +// 0x01 reserved
> +#define LMP_ENHANCED_DATA_RATE_2MBPS 0x02
> +#define LMP_ENHANCED_DATA_RATE_3MBPS 0x04
> +#define LMP_ENHANCED_INQUIRY_SCAN 0x08
> +#define LMP_INTERLACED_INQUIRY_SCAN 0x10
> +#define LMP_INTERLACED_PAGE_SCAN 0x20
> +#define LMP_RSSI_WITH_INQUIRY_RES 0x40
> +#define LMP_ESCO 0x80
> +
> +/* byte 4 */
> +#define LMP_EV4 0x01
> +#define LMP_EV5 0x02
> +// 0x04 reserved
> +#define LMP_AFH_CAPABLE_SLAVE 0x08
> +#define LMP_AFH_CLASSIF_SLAVE 0x10
> +#define LMP_NOT_BREDR 0x20
> +#define LMP_LE 0x40
> +#define LMP_3EDR 0x80
> +
> +/* byte 5 */
> +#define LMP_5EDR 0x01
> +#define LMP_SNIFF_SUBR 0x02
> +#define LMP_PAUSE_ENCRYP 0x04
> +#define LMP_AFH_CAPABLE_MASTER 0x08
> +#define LMP_AFH_CLASSIF_MASTER 0x10
> +#define LMP_EDR_ESCO_2M 0x20
> +#define LMP_EDR_ESCO_3M 0x40
> +#define LMP_EDR_3S_ESCO 0x80
> +
> +/* byte 6 */
> +#define LMP_EXT_INQ_RESPONSE 0x01
> +#define LMP_SIMUL_LE_BREDR_SAME_DEVICE 0x02
> +// 0x04 reserved for Core V4.0
> +#define LMP_SIMPLE_PAIR 0x08
> +#define LMP_ENCAPSULATED_PDU 0x10
> +#define LMP_ERR_DATA_REPORT 0x20
> +#define LMP_NONFLUSH_PACKET_BOUNDARY_FLAG 0x40
> +// 0x80 reserved for Core V4.0
> +
> +/* byte 7 */
> +#define LMP_LINK_SUPERVISION_TIMEOUT_CHANGED_EVENT 0x01
> +#define LMP_INQ_TX_POWER_LEVEL 0x02
> +#define LMP_ENHANCED_POWER_CONTROL 0x04
> +// 0x08 reserved
> +// 0x10 reserved
> +// 0x20 reserved
> +// 0x40 reserved
> +// 0x80 reserved
>
Add only definition you are using in the code.
> /* Connection modes */
> #define HCI_CM_ACTIVE 0x0000
> diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
> index cfbe56c..9a86281 100644
> --- a/include/net/bluetooth/hci_core.h
> +++ b/include/net/bluetooth/hci_core.h
> @@ -480,7 +480,10 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
> #define lmp_sniffsubr_capable(dev) ((dev)->features[5] & LMP_SNIFF_SUBR)
> #define lmp_esco_capable(dev) ((dev)->features[3] & LMP_ESCO)
> #define lmp_ssp_capable(dev) ((dev)->features[6] & LMP_SIMPLE_PAIR)
> +
Extra line here?
>
> #define lmp_le_capable(dev) ((dev)->features[4] & LMP_LE)
> +#define lmp_bredr_unsupported(dev) ((dev)->features[4] & LMP_NOT_BREDR)
> +#define lmp_le_only(dev) (lmp_le_capable(dev) &&
> lmp_bredr_unsupported(dev))
>
> /* ----- HCI protocols ----- */
> struct hci_proto {
> diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
> index 0e98ffb..b110114 100644
> --- a/net/bluetooth/hci_core.c
> +++ b/net/bluetooth/hci_core.c
> @@ -259,6 +259,8 @@ static void hci_le_init_req(struct hci_dev *hdev,
> unsigned long opt)
> {
> BT_DBG("%s", hdev->name);
>
> + BT_INFO("%s LE-specific initialization", hdev->name);
> +
I think these info messages could be left out from final version.
> /* Read LE buffer size */
> hci_send_cmd(hdev, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL);
> }
> @@ -501,10 +503,6 @@ int hci_dev_open(__u16 dev)
> if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
> set_bit(HCI_RAW, &hdev->flags);
>
> - /* Treat all non BR/EDR controllers as raw devices for now */
> - if (hdev->dev_type != HCI_BREDR)
> - set_bit(HCI_RAW, &hdev->flags);
> -
Won't this break AMP controller support?
> if (hdev->open(hdev)) {
> ret = -EIO;
> goto done;
> @@ -514,6 +512,8 @@ int hci_dev_open(__u16 dev)
> atomic_set(&hdev->cmd_cnt, 1);
> set_bit(HCI_INIT, &hdev->flags);
>
> + BT_INFO("Initializing %s", hdev->name);
> +
Ditto
> //__hci_request(hdev, hci_reset_req, 0, HZ);
> ret = __hci_request(hdev, hci_init_req, 0,
> msecs_to_jiffies(HCI_INIT_TIMEOUT));
> diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
> index 57560fb..18932a2 100644
> --- a/net/bluetooth/hci_event.c
> +++ b/net/bluetooth/hci_event.c
> @@ -445,6 +445,16 @@ static void hci_cc_read_local_commands(struct
> hci_dev *hdev, struct sk_buff *skb
> memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
> }
>
> +#define is_texas_dongle(hdev) \
> + (hdev->features[0] == 0x00 && \
> + hdev->features[1] == 0x00 && \
> + hdev->features[2] == 0x00 && \
> + hdev->features[3] == 0x60 && \
> + hdev->features[4] == 0x00 && \
> + hdev->features[5] == 0x00 && \
> + hdev->features[6] == 0x00 && \
> + hdev->features[7] == 0x00)
> +
Should be fixed in dongle fw. And if not possible maybe some quirk could be
used instead of device specific hacks.
> static void hci_cc_read_local_features(struct hci_dev *hdev, struct
> sk_buff *skb)
> {
> struct hci_rp_read_local_features *rp = (void *) skb->data;
> @@ -498,6 +508,20 @@ static void hci_cc_read_local_features(struct
> hci_dev *hdev, struct sk_buff *skb
> hdev->features[2], hdev->features[3],
> hdev->features[4], hdev->features[5],
> hdev->features[6], hdev->features[7]);
> +
> + /* Fix features endianess bug on CC2540 firmware */
> + if (is_texas_dongle(hdev)) {
> + hdev->features[3] = 0x00;
> + hdev->features[4] = 0x60;
> + }
> +
> + if (lmp_le_capable(hdev) && lmp_bredr_unsupported(hdev)) {
> + hdev->dev_type = HCI_LE;
> + BT_INFO("%s is a LE-only controller", hdev->name);
Ditto
> + } else if (lmp_le_capable(hdev)) {
> + hdev->dev_type = HCI_BREDRLE;
> + BT_INFO("%s is a BR/EDR/LE controller", hdev->name);
Ditto
> + }
> }
>
> static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
> diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
> index 5fce3d6..5846297 100644
> --- a/net/bluetooth/hci_sysfs.c
> +++ b/net/bluetooth/hci_sysfs.c
> @@ -196,6 +196,10 @@ static inline char *host_typetostr(int type)
> return "BR/EDR";
> case HCI_AMP:
> return "AMP";
> + case HCI_BREDRLE:
> + return "BR/EDR/LE";
> + case HCI_LE:
> + return "LE";
> default:
> return "UNKNOWN";
> }
--
Ville
^ permalink raw reply
* Re: Problems with L2CAP: deferred setup and MTU
From: Ville Tervo @ 2011-01-27 8:03 UTC (permalink / raw)
To: ext Gustavo F. Padovan; +Cc: Elvis Pfützenreuter, linux-bluetooth
In-Reply-To: <20110124190913.GB4300@joana>
Hi Gustavo,
On Mon, Jan 24, 2011 at 05:09:13PM -0200, ext Gustavo F. Padovan wrote:
> Hi Elvis,
>
> * Elvis Pfützenreuter <epx@signove.com> [2011-01-19 17:10:51 -0200]:
>
> > I am currently investigating two problems with L2CAP sockets. Since I am not a kernel guy, I will take an indefinite amount of time to find and fix them; perhaps someone else can find and fix it in 5 minutes, so I think it is worth reporting.
> >
> > First problem is ERTM x MTU, sockets configured with a MTU != 672. Normal sockets exchange MTU in initialization:
> >
> > ./l2test -P 4099 -I 1000 -O 1000
> > l2test[3211]: Connect from 00:1B:DC:0F:C8:A9 [imtu 1000, omtu 1000, flush_to 65535, mode 0, handle 12, class 0x480100]
> >
> > but ERTM sockets seem to ignore the setsockopt() value and exchange the default size (672):
> >
> > ./l2test -P 4099 -I 1000 -O 1000 -X ERTM
> > l2test[3228]: Connect from 00:1B:DC:0F:C8:A9 [imtu 1000, omtu 672, flush_to 65535, mode 3, handle 11, class 0x480100]
> >
> > (obviously the initiator side uses the same parameters)
>
> I pushed I fix for this to bluetooth-next-2.6
>
> Author: Gustavo F. Padovan <padovan@profusion.mobi>
> Date: Mon Jan 24 16:01:43 2011 -0200
>
> Bluetooth: Fix setting of MTU for ERTM and Streaming Mode
>
> The desired MTU should be sent in an Config_Req for all modes.
>
> Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
>
> diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
> index ff191b9..1ee18c6 100644
> --- a/net/bluetooth/l2cap.c
> +++ b/net/bluetooth/l2cap.c
> @@ -2588,11 +2588,11 @@ static int l2cap_build_conf_req(struct sock *sk, void *data)
> }
>
> done:
> + if (pi->imtu != L4CAP_DEFAULT_MTU)
^^^
Probably you noticed this typo already?
> + l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
> +
> switch (pi->mode) {
> case L2CAP_MODE_BASIC:
> - if (pi->imtu != L2CAP_DEFAULT_MTU)
> - l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
> -
> if (!(pi->conn->feat_mask & L2CAP_FEAT_ERTM) &&
> !(pi->conn->feat_mask & L2CAP_FEAT_STREAMING))
> break;
--
Ville
^ permalink raw reply
* Re: [PATCHv2] Bluetooth: flushable packet supports headers
From: Johan Hedberg @ 2011-01-27 9:01 UTC (permalink / raw)
To: Emeltchenko Andrei; +Cc: linux-bluetooth
In-Reply-To: <1295948747-11094-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
Hi Andrei,
On Tue, Jan 25, 2011, Emeltchenko Andrei wrote:
> Modify headers to enable support for flushable packets. Following
> commit: 8bcbd526c84724d8de087130d53e79da256e34bf to linux kernel
> implements functionality on kernel side.
> ---
> lib/bluetooth.h | 5 +++++
> lib/hci.h | 1 +
> 2 files changed, 6 insertions(+), 0 deletions(-)
Pushed upstream. Thanks.
Johan
^ permalink raw reply
* [RFC] l2test: add flushable cmd line options
From: Emeltchenko Andrei @ 2011-01-27 13:39 UTC (permalink / raw)
To: linux-bluetooth
From: Andrei Emeltchenko <andrei.emeltchenko@nokia.com>
---
test/l2test.c | 23 ++++++++++++++++++++++-
1 files changed, 22 insertions(+), 1 deletions(-)
diff --git a/test/l2test.c b/test/l2test.c
index 17883a9..ed19679 100644
--- a/test/l2test.c
+++ b/test/l2test.c
@@ -90,6 +90,9 @@ static bdaddr_t bdaddr;
static unsigned short psm = 10;
static unsigned short cid = 0;
+/* Flushable packet mode */
+static int unsigned flushable = 2;
+
/* Default number of frames to send (-1 = infinite) */
static int num_frames = -1;
@@ -301,6 +304,19 @@ static int do_connect(char *svr)
goto error;
}
+ /* Set flushable mode, when mode is incorrect pass through,
+ shall we handle bugs? */
+ if (flushable < 2) {
+ opt = flushable;
+ if (setsockopt(sk, SOL_BLUETOOTH, BT_FLUSHABLE,
+ &opt, sizeof(opt)) < 0) {
+ syslog(LOG_ERR, "Can't %s flushable mode: %s (%d)",
+ flushable? "set" : "reset",
+ strerror(errno), errno);
+ goto error;
+ }
+ }
+
/* Get current options */
memset(&opts, 0, sizeof(opts));
optlen = sizeof(opts);
@@ -1087,6 +1103,7 @@ static void usage(void)
"\t[-F fcs] use CRC16 check (default = 1)\n"
"\t[-Q num] Max Transmit value (default = 3)\n"
"\t[-Z size] Transmission Window size (default = 63)\n"
+ "\t[-f mode] Flushable mode\n"
"\t[-R] reliable mode\n"
"\t[-G] use connectionless channel (datagram)\n"
"\t[-U] use sock stream\n"
@@ -1104,7 +1121,7 @@ int main(int argc, char *argv[])
bacpy(&bdaddr, BDADDR_ANY);
- while ((opt=getopt(argc,argv,"rdscuwmntqxyzpb:i:P:I:O:J:B:N:L:W:C:D:X:F:Q:Z:RUGAESMT")) != EOF) {
+ while ((opt=getopt(argc,argv,"rdscuwmntqxyzpb:i:P:I:O:J:B:N:L:W:C:D:X:F:Q:Z:f:RUGAESMT")) != EOF) {
switch(opt) {
case 'r':
mode = RECV;
@@ -1268,6 +1285,10 @@ int main(int argc, char *argv[])
txwin_size = atoi(optarg);
break;
+ case 'f':
+ flushable = atoi(optarg);
+ break;
+
case 'J':
cid = atoi(optarg);
break;
--
1.7.1
^ permalink raw reply related
* Re: [RFC 1/1] Device initialization and controller type resolving
From: André Dieb @ 2011-01-27 13:58 UTC (permalink / raw)
To: Ville Tervo; +Cc: linux-bluetooth
In-Reply-To: <20110127075924.GJ874@null>
Hi Ville,
On Thu, Jan 27, 2011 at 5:59 AM, Ville Tervo <ville.tervo@nokia.com> wrote:
> Hi Andre,
>
> On Wed, Jan 26, 2011 at 12:34:02PM -0200, ext André Dieb wrote:
>> From: André Dieb Martins <andre.dieb@signove.com>
>>
>> This patch proposes to use LMP features in order to resolve the controller
>> type. Currently there's very few code (mostly inside drivers) that cares
>> about differentiating controller types (BR/EDR, BR/EDR/LE, LE only, AMP).
>>
>> Once determined dev_type, the idea would be to implement controller-type
>> specific initialization procedures. There's an initialization code for BR/EDR
>> devices and some early adaptation for BR/EDR/LE, but nothing regarding
>> LE-only - and I'm willing to tackle that, based on your pointers.
>>
>> Would it be better to always let drivers modify their device's dev_type?
>>
>> What would be the correct approach?
>>
>> PS: Please don't bother the CC2540 hack. Consider it a joke :-).
>
> Separate it to another patch then. I have these dongles but they had some
> proprietary interface. From where did you get fw with hci interface? it would
> be nice to test also with LE only hw.
>
Great to know there's more people interested in getting this working.
We were trying to use the proprietary fw. TI argued it supported BLE,
but we still couldn't use it properly - commands missing, events not
being generated, etc. There has been some development on this issue -
if you're interested check my blog's latest posts
(http://genuinepulse.blogspot.com).
If you're interested in helping us, my code is living under
http://gitorious.org/~dieb/bluetooth-next/dieb-bluetooth-next/commits/controller-type.
Also notice I rebased against 2.6-next and split it into separate
patches.
>>
>> Signed-off-by: André Dieb Martins <andre.dieb@signove.com>
>> ---
>> include/net/bluetooth/hci.h | 78 ++++++++++++++++++++++++++++++-------
>> include/net/bluetooth/hci_core.h | 3 +
>> net/bluetooth/hci_core.c | 8 ++--
>> net/bluetooth/hci_event.c | 24 ++++++++++++
>> net/bluetooth/hci_sysfs.c | 4 ++
>> 5 files changed, 98 insertions(+), 19 deletions(-)
>>
>> diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
>> index 036fdae..ae9f095 100644
>> --- a/include/net/bluetooth/hci.h
>> +++ b/include/net/bluetooth/hci.h
>> @@ -55,6 +55,8 @@
>> /* HCI controller types */
>> #define HCI_BREDR 0x00
>> #define HCI_AMP 0x01
>> +#define HCI_BREDRLE 0x02
>> +#define HCI_LE 0x03
>>
>> /* HCI device quirks */
>> enum {
>> @@ -163,6 +165,8 @@ enum {
>> #define LE_LINK 0x80
>>
>> /* LMP features */
>> +
>> +/* byte 0 */
>> #define LMP_3SLOT 0x01
>> #define LMP_5SLOT 0x02
>> #define LMP_ENCRYPT 0x04
>> @@ -172,6 +176,7 @@ enum {
>> #define LMP_HOLD 0x40
>> #define LMP_SNIFF 0x80
>>
>> +/* byte 1 */
>> #define LMP_PARK 0x01
>> #define LMP_RSSI 0x02
>> #define LMP_QUALITY 0x04
>> @@ -181,22 +186,65 @@ enum {
>> #define LMP_ULAW 0x40
>> #define LMP_ALAW 0x80
>>
>> -#define LMP_CVSD 0x01
>> -#define LMP_PSCHEME 0x02
>> +/* byte 2 */
>> +#define LMP_CVSD 0x01
>> +#define LMP_PSCHEME 0x02
>> #define LMP_PCONTROL 0x04
>> -
>> -#define LMP_ESCO 0x80
>> -
>> -#define LMP_EV4 0x01
>> -#define LMP_EV5 0x02
>> -#define LMP_LE 0x40
>> -
>> -#define LMP_SNIFF_SUBR 0x02
>> -#define LMP_EDR_ESCO_2M 0x20
>> -#define LMP_EDR_ESCO_3M 0x40
>> -#define LMP_EDR_3S_ESCO 0x80
>> -
>> -#define LMP_SIMPLE_PAIR 0x08
>> +#define LMP_TSYNC 0x08
>> +#define LMP_FLOWLAGLSB 0x10
>> +#define LMP_FLOWLAGMB 0x20
>> +#define LMP_FLOWLAGMSB 0x40
>> +#define LMP_BROADCAST_ENCRYPTION 0x80
>> +
>> +/* byte 3 */
>> +// 0x01 reserved
>> +#define LMP_ENHANCED_DATA_RATE_2MBPS 0x02
>> +#define LMP_ENHANCED_DATA_RATE_3MBPS 0x04
>> +#define LMP_ENHANCED_INQUIRY_SCAN 0x08
>> +#define LMP_INTERLACED_INQUIRY_SCAN 0x10
>> +#define LMP_INTERLACED_PAGE_SCAN 0x20
>> +#define LMP_RSSI_WITH_INQUIRY_RES 0x40
>> +#define LMP_ESCO 0x80
>> +
>> +/* byte 4 */
>> +#define LMP_EV4 0x01
>> +#define LMP_EV5 0x02
>> +// 0x04 reserved
>> +#define LMP_AFH_CAPABLE_SLAVE 0x08
>> +#define LMP_AFH_CLASSIF_SLAVE 0x10
>> +#define LMP_NOT_BREDR 0x20
>> +#define LMP_LE 0x40
>> +#define LMP_3EDR 0x80
>> +
>> +/* byte 5 */
>> +#define LMP_5EDR 0x01
>> +#define LMP_SNIFF_SUBR 0x02
>> +#define LMP_PAUSE_ENCRYP 0x04
>> +#define LMP_AFH_CAPABLE_MASTER 0x08
>> +#define LMP_AFH_CLASSIF_MASTER 0x10
>> +#define LMP_EDR_ESCO_2M 0x20
>> +#define LMP_EDR_ESCO_3M 0x40
>> +#define LMP_EDR_3S_ESCO 0x80
>> +
>> +/* byte 6 */
>> +#define LMP_EXT_INQ_RESPONSE 0x01
>> +#define LMP_SIMUL_LE_BREDR_SAME_DEVICE 0x02
>> +// 0x04 reserved for Core V4.0
>> +#define LMP_SIMPLE_PAIR 0x08
>> +#define LMP_ENCAPSULATED_PDU 0x10
>> +#define LMP_ERR_DATA_REPORT 0x20
>> +#define LMP_NONFLUSH_PACKET_BOUNDARY_FLAG 0x40
>> +// 0x80 reserved for Core V4.0
>> +
>> +/* byte 7 */
>> +#define LMP_LINK_SUPERVISION_TIMEOUT_CHANGED_EVENT 0x01
>> +#define LMP_INQ_TX_POWER_LEVEL 0x02
>> +#define LMP_ENHANCED_POWER_CONTROL 0x04
>> +// 0x08 reserved
>> +// 0x10 reserved
>> +// 0x20 reserved
>> +// 0x40 reserved
>> +// 0x80 reserved
>>
>
> Add only definition you are using in the code.
Ok.
>
>> /* Connection modes */
>> #define HCI_CM_ACTIVE 0x0000
>> diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
>> index cfbe56c..9a86281 100644
>> --- a/include/net/bluetooth/hci_core.h
>> +++ b/include/net/bluetooth/hci_core.h
>> @@ -480,7 +480,10 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
>> #define lmp_sniffsubr_capable(dev) ((dev)->features[5] & LMP_SNIFF_SUBR)
>> #define lmp_esco_capable(dev) ((dev)->features[3] & LMP_ESCO)
>> #define lmp_ssp_capable(dev) ((dev)->features[6] & LMP_SIMPLE_PAIR)
>> +
>
> Extra line here?
You're right. No need to separate those macros.
>
>>
>> #define lmp_le_capable(dev) ((dev)->features[4] & LMP_LE)
>> +#define lmp_bredr_unsupported(dev) ((dev)->features[4] & LMP_NOT_BREDR)
>> +#define lmp_le_only(dev) (lmp_le_capable(dev) &&
>> lmp_bredr_unsupported(dev))
>>
>> /* ----- HCI protocols ----- */
>> struct hci_proto {
>> diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
>> index 0e98ffb..b110114 100644
>> --- a/net/bluetooth/hci_core.c
>> +++ b/net/bluetooth/hci_core.c
>> @@ -259,6 +259,8 @@ static void hci_le_init_req(struct hci_dev *hdev,
>> unsigned long opt)
>> {
>> BT_DBG("%s", hdev->name);
>>
>> + BT_INFO("%s LE-specific initialization", hdev->name);
>> +
>
> I think these info messages could be left out from final version.
Sure.
>
>> /* Read LE buffer size */
>> hci_send_cmd(hdev, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL);
>> }
>> @@ -501,10 +503,6 @@ int hci_dev_open(__u16 dev)
>> if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
>> set_bit(HCI_RAW, &hdev->flags);
>>
>> - /* Treat all non BR/EDR controllers as raw devices for now */
>> - if (hdev->dev_type != HCI_BREDR)
>> - set_bit(HCI_RAW, &hdev->flags);
>> -
>
> Won't this break AMP controller support?
Yes. But it's not what I want to propose. I'd like to divide my
question in smaller ones. I'm sorry about the lame patch, my
experience with kernel-bt is pretty limited and I've just started
playing with it... experienced input is and will be very much
appreciated. :)
1. Can we determine all hdev->dev_type through LMP? Core V4.0
determines Read Local Supported Features Command must be supported by
all controllers, so perhaps we could resolve hdev->dev_type before
doing everything else.
2. Once determined (if possible) hdev->dev_type through LMP, we could
have something like:
// Common initialization for all types
hci_common_init_req();
// type-specific initialization
switch (hdev->dev_type) {
case HCI_BREDR:
hci_bredr_init_req();
break;
case HCI_BREDRLE:
hci_bredr_init_req();
hci_le_init_req();
break;
case HCI_LE:
hci_le_init_req();
break;
case HCI_AMP:
hci_amp_init();
break;
default: // RAW?
break;
}
>
>> if (hdev->open(hdev)) {
>> ret = -EIO;
>> goto done;
>> @@ -514,6 +512,8 @@ int hci_dev_open(__u16 dev)
>> atomic_set(&hdev->cmd_cnt, 1);
>> set_bit(HCI_INIT, &hdev->flags);
>>
>> + BT_INFO("Initializing %s", hdev->name);
>> +
>
> Ditto
>
>> //__hci_request(hdev, hci_reset_req, 0, HZ);
>> ret = __hci_request(hdev, hci_init_req, 0,
>> msecs_to_jiffies(HCI_INIT_TIMEOUT));
>> diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
>> index 57560fb..18932a2 100644
>> --- a/net/bluetooth/hci_event.c
>> +++ b/net/bluetooth/hci_event.c
>> @@ -445,6 +445,16 @@ static void hci_cc_read_local_commands(struct
>> hci_dev *hdev, struct sk_buff *skb
>> memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
>> }
>>
>> +#define is_texas_dongle(hdev) \
>> + (hdev->features[0] == 0x00 && \
>> + hdev->features[1] == 0x00 && \
>> + hdev->features[2] == 0x00 && \
>> + hdev->features[3] == 0x60 && \
>> + hdev->features[4] == 0x00 && \
>> + hdev->features[5] == 0x00 && \
>> + hdev->features[6] == 0x00 && \
>> + hdev->features[7] == 0x00)
>> +
>
> Should be fixed in dongle fw. And if not possible maybe some quirk could be
> used instead of device specific hacks.
>
Sure. I wonder if TI would provide us the fw's source or actually
provide a fixed fw.
>> static void hci_cc_read_local_features(struct hci_dev *hdev, struct
>> sk_buff *skb)
>> {
>> struct hci_rp_read_local_features *rp = (void *) skb->data;
>> @@ -498,6 +508,20 @@ static void hci_cc_read_local_features(struct
>> hci_dev *hdev, struct sk_buff *skb
>> hdev->features[2], hdev->features[3],
>> hdev->features[4], hdev->features[5],
>> hdev->features[6], hdev->features[7]);
>> +
>> + /* Fix features endianess bug on CC2540 firmware */
>> + if (is_texas_dongle(hdev)) {
>> + hdev->features[3] = 0x00;
>> + hdev->features[4] = 0x60;
>> + }
>> +
>> + if (lmp_le_capable(hdev) && lmp_bredr_unsupported(hdev)) {
>> + hdev->dev_type = HCI_LE;
>> + BT_INFO("%s is a LE-only controller", hdev->name);
>
> Ditto
>
>> + } else if (lmp_le_capable(hdev)) {
>> + hdev->dev_type = HCI_BREDRLE;
>> + BT_INFO("%s is a BR/EDR/LE controller", hdev->name);
>
> Ditto
>
>> + }
>> }
>>
>> static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
>> diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
>> index 5fce3d6..5846297 100644
>> --- a/net/bluetooth/hci_sysfs.c
>> +++ b/net/bluetooth/hci_sysfs.c
>> @@ -196,6 +196,10 @@ static inline char *host_typetostr(int type)
>> return "BR/EDR";
>> case HCI_AMP:
>> return "AMP";
>> + case HCI_BREDRLE:
>> + return "BR/EDR/LE";
>> + case HCI_LE:
>> + return "LE";
>> default:
>> return "UNKNOWN";
>> }
>
> --
> Ville
>
>
^ permalink raw reply
* Re: [PATCH] Set connection state to BT_DISCONN to avoid multiple responses
From: Liang Bao @ 2011-01-27 14:22 UTC (permalink / raw)
To: Ville Tervo; +Cc: linux-bluetooth
In-Reply-To: <20110127074034.GI874@null>
Hi,
2011/1/27 Ville Tervo <ville.tervo@nokia.com>:
> Hi,
>
> On Thu, Jan 27, 2011 at 09:21:16AM +0800, ext tim.bao@gmail.com wrote:
>> From: Bao Liang <tim.bao@gmail.com>
>>
>> This patch fixes a minor issue that two connection responses will be sent
>> for one L2CAP connection request. If the L2CAP connection request is first
>> blocked due to security reason and responded with reason "security block",
>> the state of the connection remains BT_CONNECT2. If a pairing procedure
>> completes successfully before the ACL connection is down, local host will
>> send another connection complete response. See the following packets
>> captured by hcidump.
>>
>> 2010-12-07 22:21:24.928096 < ACL data: handle 12 flags 0x00 dlen 16
>> 0000: 0c 00 01 00 03 19 08 00 41 00 53 00 03 00 00 00 ........A.S.....
>> ... ...
>>
>> 2010-12-07 22:21:35.791747 > HCI Event: Auth Complete (0x06) plen 3
>> status 0x00 handle 12
>> ... ...
>>
>> 2010-12-07 22:21:35.872372 > ACL data: handle 12 flags 0x02 dlen 16
>> L2CAP(s): Connect rsp: dcid 0x0054 scid 0x0040 result 0 status 0
>> Connection successful
>>
>> Signed-off-by: Bao Liang <tim.bao@gmail.com>
>> ---
>> net/bluetooth/l2cap.c | 5 +++--
>> 1 files changed, 3 insertions(+), 2 deletions(-)
>>
>> diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
>> index fadf26b..40d70db 100644
>> --- a/net/bluetooth/l2cap.c
>> +++ b/net/bluetooth/l2cap.c
>> @@ -844,9 +844,10 @@ static void __l2cap_sock_close(struct sock *sk, int reason)
>> struct l2cap_conn_rsp rsp;
>> __u16 result;
>>
>> - if (bt_sk(sk)->defer_setup)
>> + if (bt_sk(sk)->defer_setup) {
>> + sk->sk_state = BT_DISCONN;
>> result = L2CAP_CR_SEC_BLOCK;
>> - else
>> + } else
>> result = L2CAP_CR_BAD_PSM;
>>
>> rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
>
> Shouldn't sk->sk_state be changed in all cases and not only when socket is
> waiting for authorization?
In my opinion, it's really a rare case where a remote device will keep
connection open upon L2CAP_CR_BAD_PSM received. So my patch is based
on my experience with Logitech V470. But I can have a try moving the
assignment out. Thanks.
>
> Otherwise patch looks good to me.
>
> --
> Ville
>
^ permalink raw reply
* [PATCH] Add Health API document to distribution package
From: Elvis Pfützenreuter @ 2011-01-27 15:35 UTC (permalink / raw)
To: linux-bluetooth; +Cc: epx
---
Makefile.am | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index 5f96975..e6639a7 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -354,7 +354,7 @@ EXTRA_DIST += doc/manager-api.txt \
doc/service-api.txt doc/agent-api.txt doc/attribute-api.txt \
doc/serial-api.txt doc/network-api.txt \
doc/input-api.txt doc/audio-api.txt doc/control-api.txt \
- doc/hfp-api.txt doc/assigned-numbers.txt
+ doc/hfp-api.txt doc/health-api.txt doc/assigned-numbers.txt
AM_YFLAGS = -d
--
1.7.1
^ permalink raw reply related
* Re: [PATCH] Add Health API document to distribution package
From: Johan Hedberg @ 2011-01-27 15:55 UTC (permalink / raw)
To: Elvis Pfützenreuter; +Cc: linux-bluetooth
In-Reply-To: <1296142534-19809-1-git-send-email-epx@signove.com>
Hi Elvis,
On Thu, Jan 27, 2011, Elvis Pfützenreuter wrote:
> ---
> Makefile.am | 2 +-
> 1 files changed, 1 insertions(+), 1 deletions(-)
Pushed upstream. Thanks.
Johan
^ permalink raw reply
* Re: [PATCH] Set connection state to BT_DISCONN to avoid multiple responses
From: Gustavo F. Padovan @ 2011-01-27 16:03 UTC (permalink / raw)
To: Ville Tervo; +Cc: ext tim.bao@gmail.com, linux-bluetooth
In-Reply-To: <20110127074034.GI874@null>
Hi Ville,
* Ville Tervo <ville.tervo@nokia.com> [2011-01-27 09:40:34 +0200]:
> Hi,
>
> On Thu, Jan 27, 2011 at 09:21:16AM +0800, ext tim.bao@gmail.com wrote:
> > From: Bao Liang <tim.bao@gmail.com>
> >
> > This patch fixes a minor issue that two connection responses will be sent
> > for one L2CAP connection request. If the L2CAP connection request is first
> > blocked due to security reason and responded with reason "security block",
> > the state of the connection remains BT_CONNECT2. If a pairing procedure
> > completes successfully before the ACL connection is down, local host will
> > send another connection complete response. See the following packets
> > captured by hcidump.
> >
> > 2010-12-07 22:21:24.928096 < ACL data: handle 12 flags 0x00 dlen 16
> > 0000: 0c 00 01 00 03 19 08 00 41 00 53 00 03 00 00 00 ........A.S.....
> > ... ...
> >
> > 2010-12-07 22:21:35.791747 > HCI Event: Auth Complete (0x06) plen 3
> > status 0x00 handle 12
> > ... ...
> >
> > 2010-12-07 22:21:35.872372 > ACL data: handle 12 flags 0x02 dlen 16
> > L2CAP(s): Connect rsp: dcid 0x0054 scid 0x0040 result 0 status 0
> > Connection successful
> >
> > Signed-off-by: Bao Liang <tim.bao@gmail.com>
> > ---
> > net/bluetooth/l2cap.c | 5 +++--
> > 1 files changed, 3 insertions(+), 2 deletions(-)
> >
> > diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
> > index fadf26b..40d70db 100644
> > --- a/net/bluetooth/l2cap.c
> > +++ b/net/bluetooth/l2cap.c
> > @@ -844,9 +844,10 @@ static void __l2cap_sock_close(struct sock *sk, int reason)
> > struct l2cap_conn_rsp rsp;
> > __u16 result;
> >
> > - if (bt_sk(sk)->defer_setup)
> > + if (bt_sk(sk)->defer_setup) {
> > + sk->sk_state = BT_DISCONN;
> > result = L2CAP_CR_SEC_BLOCK;
> > - else
> > + } else
> > result = L2CAP_CR_BAD_PSM;
> >
> > rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
>
> Shouldn't sk->sk_state be changed in all cases and not only when socket is
> waiting for authorization?
I agree with you here. It's better treat all cases.
--
Gustavo F. Padovan
http://profusion.mobi
^ permalink raw reply
* Re: [PATCH v2] HDP: reject MDL reconnection with different MTU
From: Elvis Pfützenreuter @ 2011-01-27 18:55 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1295005808-9885-1-git-send-email-epx@signove.com>
Just to remember that this one's still in the line:
On 14 Jan 2011, at 09:50 , Elvis Pfützenreuter wrote:
> From: Elvis Pfutzenreuter <epx@signove.com>
>
> This patch implements refusal of a MDL reconnection if the new L2CAP
> connection presents a different MTU. Accordingly to HDP spec. item 3.5.
>
> It aims to pass the TC_SNK_HCT_BV_07_C PTS test. (It does not pass yet
> because PTS itself seems to have issues. See tickets 7212, 7214 and
> 7244 for details.)
> ---
> health/hdp.c | 21 +++++++++++++++++++--
> health/hdp_types.h | 2 ++
> 2 files changed, 21 insertions(+), 2 deletions(-)
>
> diff --git a/health/hdp.c b/health/hdp.c
> index dc1f803..278db68 100644
> --- a/health/hdp.c
> +++ b/health/hdp.c
> @@ -874,6 +874,7 @@ static gboolean check_channel_conf(struct hdp_channel *chan)
> GError *err = NULL;
> GIOChannel *io;
> uint8_t mode;
> + uint16_t imtu, omtu;
> int fd;
>
> fd = mcap_mdl_get_fd(chan->mdl);
> @@ -883,6 +884,8 @@ static gboolean check_channel_conf(struct hdp_channel *chan)
>
> if (!bt_io_get(io, BT_IO_L2CAP, &err,
> BT_IO_OPT_MODE, &mode,
> + BT_IO_OPT_IMTU, &imtu,
> + BT_IO_OPT_OMTU, &omtu,
> BT_IO_OPT_INVALID)) {
> error("Error: %s", err->message);
> g_io_channel_unref(io);
> @@ -894,13 +897,27 @@ static gboolean check_channel_conf(struct hdp_channel *chan)
>
> switch (chan->config) {
> case HDP_RELIABLE_DC:
> - return mode == L2CAP_MODE_ERTM;
> + if (mode != L2CAP_MODE_ERTM)
> + return FALSE;
> + break;
> case HDP_STREAMING_DC:
> - return mode == L2CAP_MODE_STREAMING;
> + if (mode != L2CAP_MODE_STREAMING)
> + return FALSE;
> + break;
> default:
> error("Error: Connected with unknown configuration");
> return FALSE;
> }
> +
> + DBG("MDL imtu %d omtu %d Channel imtu %d omtu %d", imtu, omtu,
> + chan->imtu, chan->omtu);
> +
> + if (!chan->imtu)
> + chan->imtu = imtu;
> + if (!chan->omtu)
> + chan->omtu = omtu;
> +
> + return chan->imtu == imtu && chan->omtu == omtu;
> }
>
> static void hdp_mcap_mdl_connected_cb(struct mcap_mdl *mdl, void *data)
> diff --git a/health/hdp_types.h b/health/hdp_types.h
> index fffdb32..7d23293 100644
> --- a/health/hdp_types.h
> +++ b/health/hdp_types.h
> @@ -120,6 +120,8 @@ struct hdp_channel {
> uint8_t config; /* Channel configuration */
> uint8_t mdep; /* Remote MDEP */
> uint16_t mdlid; /* Data channel Id */
> + uint16_t imtu; /* Channel incoming MTU */
> + uint16_t omtu; /* Channel outgoing MTU */
> struct hdp_echo_data *edata; /* private data used by echo channels */
> gint ref; /* Reference counter */
> };
> --
> 1.7.0.4
>
^ permalink raw reply
* [PATCH 1/6] Include check to readline lib on acinlude.m4
From: Sheldon Demario @ 2011-01-27 19:08 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Sheldon Demario
---
acinclude.m4 | 7 +++++++
1 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/acinclude.m4 b/acinclude.m4
index ecf4b4b..f27d4eb 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -153,6 +153,13 @@ AC_DEFUN([AC_PATH_SNDFILE], [
AC_SUBST(SNDFILE_LIBS)
])
+AC_DEFUN([AC_PATH_READLINE], [
+ AC_CHECK_LIB(readline, main,
+ [ readline_found=yes
+ AC_SUBST(READLINE_LIBS, "-lreadline")
+ ], readline_found=no)
+])
+
AC_DEFUN([AC_PATH_OUI], [
AC_ARG_WITH(ouifile,
AS_HELP_STRING([--with-ouifile=PATH],[Path to the oui.txt file @<:@auto@:>@]),
--
1.7.1
^ permalink raw reply related
* [PATCH 2/6] Add an interactive mode to gatttool
From: Sheldon Demario @ 2011-01-27 19:08 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Sheldon Demario
In-Reply-To: <1296155342-31956-1-git-send-email-sheldon.demario@openbossa.org>
We need a deeper control over the gatttool steps to make easier the
debug process.
---
Makefile.am | 2 +-
attrib/gatttool.c | 323 +++++++++++++++++++++++++++++++++++++++++++---------
configure.ac | 1 +
3 files changed, 269 insertions(+), 57 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index e6639a7..79abeed 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -180,7 +180,7 @@ bin_PROGRAMS += attrib/gatttool
attrib_gatttool_SOURCES = attrib/gatttool.c attrib/att.c attrib/gatt.c \
attrib/gattrib.c btio/btio.c \
src/glib-helper.h src/glib-helper.c
-attrib_gatttool_LDADD = lib/libbluetooth.la @GLIB_LIBS@
+attrib_gatttool_LDADD = lib/libbluetooth.la @GLIB_LIBS@ @READLINE_LIBS@
builtin_modules += attrib
builtin_sources += attrib/main.c \
diff --git a/attrib/gatttool.c b/attrib/gatttool.c
index 8e8ed8e..c347f6b 100644
--- a/attrib/gatttool.c
+++ b/attrib/gatttool.c
@@ -37,6 +37,9 @@
#include <bluetooth/sdp.h>
#include <bluetooth/sdp_lib.h>
+#include <readline/readline.h>
+#include <readline/history.h>
+
#include "att.h"
#include "btio.h"
#include "gattrib.h"
@@ -50,7 +53,7 @@ static gchar *opt_src = NULL;
static gchar *opt_dst = NULL;
static gchar *opt_value = NULL;
static gchar *opt_sec_level = "low";
-static uuid_t *opt_uuid = NULL;
+static uuid_t *opt_uuid;
static int opt_start = 0x0001;
static int opt_end = 0xffff;
static int opt_handle = -1;
@@ -63,8 +66,14 @@ static gboolean opt_listen = FALSE;
static gboolean opt_char_desc = FALSE;
static gboolean opt_le = FALSE;
static gboolean opt_char_write = FALSE;
-static GMainLoop *event_loop;
+static gboolean opt_interactive = FALSE;
+
+static GMainLoop *event_loop = NULL;
+static GIOChannel *iochannel = NULL;
static gboolean got_error = FALSE;
+static GAttrib *attrib = NULL;
+static GString *prompt = NULL;
+static GOptionContext *context = NULL;
struct characteristic_data {
GAttrib *attrib;
@@ -72,16 +81,72 @@ struct characteristic_data {
uint16_t end;
};
+enum state {
+ STATE_DISCONNECTED,
+ STATE_CONNECTING,
+ STATE_CONNECTED
+} conn_state;
+
+static void show_message(const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+
+ vprintf(format, ap);
+
+ va_end(ap);
+
+ rl_redisplay();
+}
+
+static char *get_prompt(void)
+{
+ if (conn_state == STATE_CONNECTING) {
+ g_string_assign(prompt, "Connecting... ");
+ return prompt->str;
+ }
+
+ if (conn_state == STATE_CONNECTED)
+ g_string_assign(prompt, "[CON]");
+ else
+ g_string_assign(prompt, "[ ]");
+
+ if (opt_le)
+ g_string_append(prompt, "[LE]");
+ else
+ g_string_append(prompt, "[BR]");
+
+ g_string_append(prompt, "> ");
+
+ return prompt->str;
+}
+
+static void set_state(enum state st)
+{
+ conn_state = st;
+ rl_set_prompt(get_prompt());
+ rl_redisplay();
+}
+
static void connect_cb(GIOChannel *io, GError *err, gpointer user_data)
{
if (err) {
- g_printerr("%s\n", err->message);
- got_error = TRUE;
- g_main_loop_quit(event_loop);
+ show_message("connect error: %s\n", err->message);
+ if (!opt_interactive) {
+ got_error = TRUE;
+ g_main_loop_quit(event_loop);
+ }
+ }
+
+ if (opt_interactive) {
+ attrib = g_attrib_new(iochannel);
+ set_state(STATE_CONNECTED);
}
}
-static GIOChannel *do_connect(gboolean le)
+static GIOChannel *do_connect(gboolean le, const gchar *dest,
+ BtIOConnect connect_cb)
{
GIOChannel *chan;
bdaddr_t sba, dba;
@@ -97,11 +162,11 @@ static GIOChannel *do_connect(gboolean le)
}
/* Remote device */
- if (opt_dst == NULL) {
+ if (dest == NULL) {
g_printerr("Remote Bluetooth address required\n");
return NULL;
}
- str2ba(opt_dst, &dba);
+ str2ba(dest, &dba);
/* Local adapter */
if (opt_src != NULL) {
@@ -232,6 +297,23 @@ static gboolean listen_start(gpointer user_data)
return FALSE;
}
+static gboolean cmd_disconnect(gpointer cmd)
+{
+ if (conn_state == STATE_DISCONNECTED)
+ return FALSE;
+
+ g_attrib_unref(attrib);
+ attrib = NULL;
+
+ g_io_channel_shutdown(iochannel, FALSE, NULL);
+ g_io_channel_unref(iochannel);
+ iochannel = NULL;
+
+ set_state(STATE_DISCONNECTED);
+
+ return FALSE;
+}
+
static gboolean primary(gpointer user_data)
{
GAttrib *attrib = user_data;
@@ -256,6 +338,24 @@ static void char_discovered_cb(GSList *characteristics, guint8 status,
goto done;
}
+ if (opt_interactive) {
+ rl_save_prompt();
+ for (l = characteristics; l; l = l->next) {
+ struct att_char *chars = l->data;
+
+ rl_message("handle = 0x%04x, char "
+ "properties = 0x%02x, char value "
+ "handle = 0x%04x, uuid = %s\n", chars->handle,
+ chars->properties, chars->value_handle, chars->uuid);
+ rl_on_new_line();
+ }
+
+ rl_restore_prompt();
+ rl_forced_update_display();
+
+ return;
+ }
+
for (l = characteristics; l; l = l->next) {
struct att_char *chars = l->data;
@@ -265,12 +365,16 @@ static void char_discovered_cb(GSList *characteristics, guint8 status,
}
done:
- g_main_loop_quit(event_loop);
+ if (opt_interactive)
+ g_main_loop_quit(event_loop);
}
static gboolean characteristics(gpointer user_data)
{
- GAttrib *attrib = user_data;
+ if (opt_interactive && conn_state != STATE_CONNECTED) {
+ show_message("Fail: disconnected\n");
+ return FALSE;
+ }
gatt_discover_char(attrib, opt_start, opt_end, char_discovered_cb, NULL);
@@ -487,6 +591,153 @@ static gboolean characteristics_desc(gpointer user_data)
return FALSE;
}
+static gboolean cmd_connect(gpointer cmd)
+{
+ const char **c = (const char **) cmd;
+ if (conn_state != STATE_DISCONNECTED)
+ return FALSE;
+
+ if (c[1] != NULL) {
+ g_free(opt_dst);
+ opt_dst = strdup(c[1]);
+ }
+
+ if (opt_dst == NULL) {
+ show_message("Remote Bluetooth address required\n");
+ return FALSE;
+ }
+
+ set_state(STATE_CONNECTING);
+ iochannel = do_connect(opt_le, opt_dst, connect_cb);
+ if (iochannel == NULL)
+ set_state(STATE_DISCONNECTED);
+
+ return FALSE;
+}
+
+static struct {
+ char *cmd;
+ gboolean (*func)(gpointer cmd);
+ char *param;
+ char *desc;
+} commands[] = {
+ { "connect", cmd_connect, "<bdaddr>", "Connect"},
+ { "disconnect", cmd_disconnect, NULL, "Disconnect"},
+ { "characteristics", characteristics, NULL,
+ "Characteristcs Discovery"},
+ { NULL, NULL, NULL, NULL}
+};
+
+static void parse_line(char *line_read)
+{
+ char **command;
+ int j;
+
+ if (!(line_read && *line_read))
+ return;
+
+ add_history(line_read);
+
+ line_read = g_strstrip(line_read);
+
+ command = g_strsplit(line_read, " ", -1);
+ for (j = 0; commands[j].cmd; j++) {
+ if (strcasecmp(commands[j].cmd, command[0]))
+ continue;
+
+ commands[j].func(command);
+ }
+
+ g_strfreev(command);
+}
+
+static gboolean prompt_read(GIOChannel *chan, GIOCondition cond,
+ gpointer user_data)
+{
+ if (cond & (G_IO_HUP | G_IO_ERR | G_IO_NVAL)) {
+ g_io_channel_unref(chan);
+ return FALSE;
+ }
+
+ if (conn_state != STATE_CONNECTING)
+ rl_callback_read_char();
+
+ return TRUE;
+}
+
+static int do_interactive(void)
+{
+ GIOChannel *pchan;
+ gint events;
+
+ event_loop = g_main_loop_new(NULL, FALSE);
+ prompt = g_string_new(NULL);
+
+ pchan = g_io_channel_unix_new(fileno(stdin));
+ g_io_channel_set_close_on_unref(pchan, TRUE);
+ events = G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL;
+ g_io_add_watch(pchan, events, prompt_read, NULL);
+
+ rl_callback_handler_install(get_prompt(), parse_line);
+
+ g_main_loop_run(event_loop);
+
+ cmd_disconnect(NULL);
+ rl_callback_handler_remove();
+ g_io_channel_unref(pchan);
+ g_main_loop_unref(event_loop);
+
+ return 0;
+}
+
+static void do_noninteractive(void)
+{
+ GSourceFunc callback;
+
+ if (opt_primary)
+ callback = primary;
+ else if (opt_characteristics)
+ callback = characteristics;
+ else if (opt_char_read)
+ callback = characteristics_read;
+ else if (opt_char_write)
+ callback = characteristics_write;
+ else if (opt_char_desc)
+ callback = characteristics_desc;
+ else {
+ gchar *help = g_option_context_get_help(context, TRUE, NULL);
+ g_print("%s\n", help);
+ g_free(help);
+ got_error = TRUE;
+ return;
+ }
+
+ iochannel = do_connect(opt_le, opt_dst, connect_cb);
+ if (iochannel == NULL) {
+ got_error = TRUE;
+ return;
+ }
+
+ attrib = g_attrib_new(iochannel);
+
+ event_loop = g_main_loop_new(NULL, FALSE);
+
+ if (opt_listen)
+ g_idle_add(listen_start, attrib);
+
+ g_idle_add(callback, attrib);
+
+ g_main_loop_run(event_loop);
+
+ g_attrib_unregister_all(attrib);
+
+ g_io_channel_unref(iochannel);
+
+ g_attrib_unref(attrib);
+
+ g_main_loop_unref(event_loop);
+}
+
static gboolean parse_uuid(const char *key, const char *value,
gpointer user_data, GError **error)
{
@@ -537,6 +788,8 @@ static GOptionEntry gatt_options[] = {
"Listen for notifications and indications", NULL },
{ "le", 0, 0, G_OPTION_ARG_NONE, &opt_le,
"Use Bluetooth Low Energy transport", NULL },
+ { "interactive", 'I', 0, G_OPTION_ARG_NONE, &opt_interactive,
+ "Use interactive mode", NULL },
{ NULL },
};
@@ -556,12 +809,8 @@ static GOptionEntry options[] = {
int main(int argc, char *argv[])
{
- GOptionContext *context;
GOptionGroup *gatt_group, *params_group, *char_rw_group;
GError *gerr = NULL;
- GAttrib *attrib;
- GIOChannel *chan;
- GSourceFunc callback;
context = g_option_context_new(NULL);
g_option_context_add_main_entries(context, options, NULL);
@@ -594,49 +843,11 @@ int main(int argc, char *argv[])
g_error_free(gerr);
}
- if (opt_primary)
- callback = primary;
- else if (opt_characteristics)
- callback = characteristics;
- else if (opt_char_read)
- callback = characteristics_read;
- else if (opt_char_write)
- callback = characteristics_write;
- else if (opt_char_desc)
- callback = characteristics_desc;
- else {
- gchar *help = g_option_context_get_help(context, TRUE, NULL);
- g_print("%s\n", help);
- g_free(help);
- got_error = TRUE;
- goto done;
- }
-
- chan = do_connect(opt_le);
- if (chan == NULL) {
- got_error = TRUE;
- goto done;
- }
-
- attrib = g_attrib_new(chan);
-
- event_loop = g_main_loop_new(NULL, FALSE);
-
- if (opt_listen)
- g_idle_add(listen_start, attrib);
-
- g_idle_add(callback, attrib);
-
- g_main_loop_run(event_loop);
-
- g_attrib_unregister_all(attrib);
-
- g_main_loop_unref(event_loop);
-
- g_io_channel_unref(chan);
- g_attrib_unref(attrib);
+ if (opt_interactive)
+ do_interactive();
+ else
+ do_noninteractive();
-done:
g_option_context_free(context);
g_free(opt_src);
g_free(opt_dst);
diff --git a/configure.ac b/configure.ac
index bebdc9c..3058fc6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -41,6 +41,7 @@ AC_PATH_ALSA
AC_PATH_GSTREAMER
AC_PATH_USB
AC_PATH_SNDFILE
+AC_PATH_READLINE
AC_PATH_OUI
AC_ARG_BLUEZ
--
1.7.1
^ permalink raw reply related
* [PATCH 3/6] Add support to primary services discover on interactive mode in gatttool
From: Sheldon Demario @ 2011-01-27 19:08 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Sheldon Demario
In-Reply-To: <1296155342-31956-1-git-send-email-sheldon.demario@openbossa.org>
---
attrib/gatttool.c | 48 +++++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 43 insertions(+), 5 deletions(-)
diff --git a/attrib/gatttool.c b/attrib/gatttool.c
index c347f6b..4e650a5 100644
--- a/attrib/gatttool.c
+++ b/attrib/gatttool.c
@@ -215,11 +215,27 @@ static void primary_all_cb(GSList *services, guint8 status, gpointer user_data)
GSList *l;
if (status) {
- g_printerr("Discover all primary services failed: %s\n",
+ show_message("Discover all primary services failed: %s\n",
att_ecode2str(status));
goto done;
}
+ if (opt_interactive) {
+ rl_save_prompt();
+ for (l = services; l; l = l->next) {
+ struct att_primary *prim = l->data;
+ rl_message("attr handle = 0x%04x, end grp "
+ "handle = 0x%04x uuid: %s\n", prim->start,
+ prim->end, prim->uuid);
+ rl_on_new_line();
+ }
+
+ rl_restore_prompt();
+ rl_forced_update_display();
+
+ return;
+ }
+
for (l = services; l; l = l->next) {
struct att_primary *prim = l->data;
g_print("attr handle = 0x%04x, end grp handle = 0x%04x "
@@ -227,7 +243,8 @@ static void primary_all_cb(GSList *services, guint8 status, gpointer user_data)
}
done:
- g_main_loop_quit(event_loop);
+ if (!opt_interactive)
+ g_main_loop_quit(event_loop);
}
static void primary_by_uuid_cb(GSList *ranges, guint8 status,
@@ -236,11 +253,26 @@ static void primary_by_uuid_cb(GSList *ranges, guint8 status,
GSList *l;
if (status != 0) {
- g_printerr("Discover primary services by UUID failed: %s\n",
+ show_message("Discover primary services by UUID failed: %s\n",
att_ecode2str(status));
goto done;
}
+ if (opt_interactive) {
+ rl_save_prompt();
+ for (l = ranges; l; l = l->next) {
+ struct att_range *range = l->data;
+ rl_message("Starting handle = 0x%04x Ending handle = 0x%04x",
+ range->start, range->end);
+ rl_on_new_line();
+ }
+
+ rl_restore_prompt();
+ rl_forced_update_display();
+
+ return;
+ }
+
for (l = ranges; l; l = l->next) {
struct att_range *range = l->data;
g_print("Starting handle: %04x Ending handle: %04x\n",
@@ -248,7 +280,8 @@ static void primary_by_uuid_cb(GSList *ranges, guint8 status,
}
done:
- g_main_loop_quit(event_loop);
+ if (!opt_interactive)
+ g_main_loop_quit(event_loop);
}
static void events_handler(const uint8_t *pdu, uint16_t len, gpointer user_data)
@@ -316,7 +349,10 @@ static gboolean cmd_disconnect(gpointer cmd)
static gboolean primary(gpointer user_data)
{
- GAttrib *attrib = user_data;
+ if (opt_interactive && conn_state != STATE_CONNECTED) {
+ show_message("Fail: disconnected\n");
+ return FALSE;
+ }
if (opt_uuid)
gatt_discover_primary(attrib, opt_uuid, primary_by_uuid_cb,
@@ -625,6 +661,8 @@ static struct {
{ "disconnect", cmd_disconnect, NULL, "Disconnect"},
{ "characteristics", characteristics, NULL,
"Characteristcs Discovery"},
+ { "primary", primary, NULL,
+ "Primary Service Discovery"},
{ NULL, NULL, NULL, NULL}
};
--
1.7.1
^ permalink raw reply related
* [PATCH 4/6] Add support to characteristics read on interactive mode in gatttool
From: Sheldon Demario @ 2011-01-27 19:09 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Sheldon Demario
In-Reply-To: <1296155342-31956-1-git-send-email-sheldon.demario@openbossa.org>
---
attrib/gatttool.c | 34 +++++++++++++++++++++++++++-------
1 files changed, 27 insertions(+), 7 deletions(-)
diff --git a/attrib/gatttool.c b/attrib/gatttool.c
index 4e650a5..f7d6056 100644
--- a/attrib/gatttool.c
+++ b/attrib/gatttool.c
@@ -424,21 +424,32 @@ static void char_read_cb(guint8 status, const guint8 *pdu, guint16 plen,
int i, vlen;
if (status != 0) {
- g_printerr("Characteristic value/descriptor read failed: %s\n",
- att_ecode2str(status));
+ show_message("Characteristic value/descriptor read "
+ "failed: %s\n", att_ecode2str(status));
goto done;
}
if (!dec_read_resp(pdu, plen, value, &vlen)) {
- g_printerr("Protocol error\n");
+ show_message("Protocol error\n");
goto done;
}
+
+ if (opt_interactive) {
+ g_print("\nCharacteristic value/descriptor: ");
+ for (i = 0; i < vlen; i++)
+ g_print("%02x ", value[i]);
+ g_print("\n");
+ rl_forced_update_display();
+
+ return;
+ }
+
g_print("Characteristic value/descriptor: ");
for (i = 0; i < vlen; i++)
g_print("%02x ", value[i]);
g_print("\n");
done:
- if (opt_listen == FALSE)
+ if ((opt_listen == FALSE) && (opt_interactive == FALSE))
g_main_loop_quit(event_loop);
}
@@ -474,6 +485,9 @@ static void char_read_by_uuid_cb(guint8 status, const guint8 *pdu,
for (j = 0; j < list->len - 2; j++, value++)
g_print("%02x ", *value);
g_print("\n");
+
+ if( opt_interactive)
+ rl_forced_update_display();
}
att_data_list_free(list);
@@ -486,12 +500,16 @@ static void char_read_by_uuid_cb(guint8 status, const guint8 *pdu,
return;
done:
g_free(char_data);
- g_main_loop_quit(event_loop);
+ if (!opt_interactive)
+ g_main_loop_quit(event_loop);
}
static gboolean characteristics_read(gpointer user_data)
{
- GAttrib *attrib = user_data;
+ if (opt_interactive && conn_state != STATE_CONNECTED) {
+ show_message("Fail: disconnected\n");
+ return FALSE;
+ }
if (opt_uuid != NULL) {
struct characteristic_data *char_data;
@@ -509,7 +527,8 @@ static gboolean characteristics_read(gpointer user_data)
if (opt_handle <= 0) {
g_printerr("A valid handle is required\n");
- g_main_loop_quit(event_loop);
+ if (!opt_interactive)
+ g_main_loop_quit(event_loop);
return FALSE;
}
@@ -663,6 +682,7 @@ static struct {
"Characteristcs Discovery"},
{ "primary", primary, NULL,
"Primary Service Discovery"},
+ { "char-read", characteristics_read, NULL, "Characteristcs read"},
{ NULL, NULL, NULL, NULL}
};
--
1.7.1
^ permalink raw reply related
* [PATCH 5/6] Add support to char descriptor discover on interactive mode in gatttool
From: Sheldon Demario @ 2011-01-27 19:09 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Sheldon Demario
In-Reply-To: <1296155342-31956-1-git-send-email-sheldon.demario@openbossa.org>
---
attrib/gatttool.c | 24 +++++++++++++++++++++---
1 files changed, 21 insertions(+), 3 deletions(-)
diff --git a/attrib/gatttool.c b/attrib/gatttool.c
index f7d6056..e66b554 100644
--- a/attrib/gatttool.c
+++ b/attrib/gatttool.c
@@ -612,6 +612,9 @@ static void char_desc_cb(guint8 status, const guint8 *pdu, guint16 plen,
if (list == NULL)
goto done;
+ if (opt_interactive)
+ rl_save_prompt();
+
for (i = 0; i < list->num; i++) {
char uuidstr[MAX_LEN_UUID_STR];
uint16_t handle;
@@ -627,19 +630,32 @@ static void char_desc_cb(guint8 status, const guint8 *pdu, guint16 plen,
sdp_uuid128_create(&uuid, &value[2]);
sdp_uuid2strn(&uuid, uuidstr, MAX_LEN_UUID_STR);
- g_print("handle = 0x%04x, uuid = %s\n", handle, uuidstr);
+ if (opt_interactive)
+ g_print("handle = 0x%04x, uuid = %s\n", handle, uuidstr);
+ else {
+ rl_message("handle = 0x%04x, uuid = %s\n", handle, uuidstr);
+ rl_on_new_line();
+ }
+ }
+
+ if (opt_interactive) {
+ rl_restore_prompt();
+ rl_forced_update_display();
}
att_data_list_free(list);
done:
- if (opt_listen == FALSE)
+ if ((opt_listen == FALSE) && (opt_interactive == FALSE))
g_main_loop_quit(event_loop);
}
static gboolean characteristics_desc(gpointer user_data)
{
- GAttrib *attrib = user_data;
+ if (opt_interactive && conn_state != STATE_CONNECTED) {
+ show_message("Fail: disconnected\n");
+ return FALSE;
+ }
gatt_find_info(attrib, opt_start, opt_end, char_desc_cb, NULL);
@@ -683,6 +699,8 @@ static struct {
{ "primary", primary, NULL,
"Primary Service Discovery"},
{ "char-read", characteristics_read, NULL, "Characteristcs read"},
+ { "char-desc", characteristics_desc, NULL,
+ "Characteristics descriptor discovery"},
{ NULL, NULL, NULL, NULL}
};
--
1.7.1
^ permalink raw reply related
* [PATCH 6/6] Add support to change uuid on interactive mode in gatttool
From: Sheldon Demario @ 2011-01-27 19:09 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Sheldon Demario
In-Reply-To: <1296155342-31956-1-git-send-email-sheldon.demario@openbossa.org>
---
attrib/gatttool.c | 53 +++++++++++++++++++++++++++++++++++++----------------
1 files changed, 37 insertions(+), 16 deletions(-)
diff --git a/attrib/gatttool.c b/attrib/gatttool.c
index e66b554..d39ee9c 100644
--- a/attrib/gatttool.c
+++ b/attrib/gatttool.c
@@ -686,6 +686,42 @@ static gboolean cmd_connect(gpointer cmd)
return FALSE;
}
+static gboolean parse_uuid(const char *key, const char *value,
+ gpointer user_data, GError **error)
+{
+ if (!value)
+ return FALSE;
+
+ opt_uuid = g_try_malloc(sizeof(uuid_t));
+ if (opt_uuid == NULL)
+ return FALSE;
+
+ if (bt_string2uuid(opt_uuid, value) < 0)
+ return FALSE;
+
+ return TRUE;
+}
+
+static gboolean cmd_uuid(gpointer cmd)
+{
+ const char **c = (const char **) cmd;
+ GError *gerr = NULL;
+
+ if (c[1] == NULL) {
+ char *uuid = bt_uuid2string(opt_uuid);
+ show_message("uuid: %s\n", uuid);
+ free(uuid);
+ return FALSE;
+ }
+
+ if (parse_uuid(NULL, c[1], NULL, &gerr) == FALSE) {
+ show_message("uuid: invalid argument\n");
+ return FALSE;
+ }
+
+ return FALSE;
+}
+
static struct {
char *cmd;
gboolean (*func)(gpointer cmd);
@@ -701,6 +737,7 @@ static struct {
{ "char-read", characteristics_read, NULL, "Characteristcs read"},
{ "char-desc", characteristics_desc, NULL,
"Characteristics descriptor discovery"},
+ { "uuid", cmd_uuid, "uuid", "Set uuid"},
{ NULL, NULL, NULL, NULL}
};
@@ -814,22 +851,6 @@ static void do_noninteractive(void)
g_main_loop_unref(event_loop);
}
-static gboolean parse_uuid(const char *key, const char *value,
- gpointer user_data, GError **error)
-{
- if (!value)
- return FALSE;
-
- opt_uuid = g_try_malloc(sizeof(uuid_t));
- if (opt_uuid == NULL)
- return FALSE;
-
- if (bt_string2uuid(opt_uuid, value) < 0)
- return FALSE;
-
- return TRUE;
-}
-
static GOptionEntry primary_char_options[] = {
{ "start", 's' , 0, G_OPTION_ARG_INT, &opt_start,
"Starting handle(optional)", "0x0001" },
--
1.7.1
^ permalink raw reply related
* RE: Attribute Server and Client TODOs
From: Inga Stotland @ 2011-01-27 19:30 UTC (permalink / raw)
To: 'Erin Yueh'; +Cc: 'Brian Gix', linux-bluetooth
In-Reply-To: <AANLkTi=gLKMvWuUeyjqGBQuWd5ztjjr10d44H4A1fFfZ@mail.gmail.com>
Hi Erin,
> Also, one of my compatriots is telling me that she cannot get the GATT
> Client D-Bus interface to work. I don't know if this is a simple lack
> of Introspection Data (required by d-feet), or if there is a build or
> configuration parameter that needs to be setup. I have just been using
> the gatttool to run my tests, and not going through D-Bus. If anybody
> has been using D-Bus for GATT Client testing, I would be interested in
> finding out if there is some setup requirements that I am missing.
>
I only modified EnableLE and AttributeServer two values in main.conf and
add --enable-attribute on building bluez. Then, it can work. I can use dbus-send
to query data. I also wrote the notes about setting up gatttool in bluez over
BR/EDR.
http://i-miss-erin.blogspot.com/2010/12/gatttool-in-bluez-over-bredr.html
> Thanks for your time.
>
>
> --
> Brian Gix
Thanks,
Erin Yueh
Thank you for your response about enabling GATT over D-Bus.
I was following the instructions from your notes.
However, when trying to test D-Bus operations for GATT, I cannot seem to get
org.bluez.Characteristic interface to register...
Have you been able to get GATT D-Bus interface to work just with BR/EDR (no LE)?
Thanks,
Inga Stotland
ingas@codeaurora.org
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum
^ permalink raw reply
* Re: [PATCH 1/6] Include check to readline lib on acinlude.m4
From: Ville Tervo @ 2011-01-28 5:37 UTC (permalink / raw)
To: ext Sheldon Demario; +Cc: linux-bluetooth
In-Reply-To: <1296155342-31956-1-git-send-email-sheldon.demario@openbossa.org>
Hi Sheldon,
On Thu, Jan 27, 2011 at 04:08:57PM -0300, ext Sheldon Demario wrote:
> ---
> acinclude.m4 | 7 +++++++
> 1 files changed, 7 insertions(+), 0 deletions(-)
>
> diff --git a/acinclude.m4 b/acinclude.m4
> index ecf4b4b..f27d4eb 100644
> --- a/acinclude.m4
> +++ b/acinclude.m4
> @@ -153,6 +153,13 @@ AC_DEFUN([AC_PATH_SNDFILE], [
> AC_SUBST(SNDFILE_LIBS)
> ])
>
> +AC_DEFUN([AC_PATH_READLINE], [
> + AC_CHECK_LIB(readline, main,
> + [ readline_found=yes
> + AC_SUBST(READLINE_LIBS, "-lreadline")
> + ], readline_found=no)
> +])
> +
This doesn't check if header files exists.
> AC_DEFUN([AC_PATH_OUI], [
> AC_ARG_WITH(ouifile,
> AS_HELP_STRING([--with-ouifile=PATH],[Path to the oui.txt file @<:@auto@:>@]),
--
Ville
^ permalink raw reply
* Re: Attribute Server and Client TODOs
From: Erin Yueh @ 2011-01-28 6:03 UTC (permalink / raw)
To: Inga Stotland; +Cc: Brian Gix, linux-bluetooth
In-Reply-To: <000001cbbe58$982b5fd0$c8821f70$@org>
Hi Inga,
On Fri, Jan 28, 2011 at 03:30, Inga Stotland <ingas@codeaurora.org> wrote:
[...]
> Thank you for your response about enabling GATT over D-Bus.
> I was following the instructions from your notes.
> However, when trying to test D-Bus operations for GATT, I cannot seem to get
> org.bluez.Characteristic interface to register...
> Have you been able to get GATT D-Bus interface to work just with BR/EDR (no LE)?
yup! I am able to use GATT related D-Bus interface to work with
BR/EDR. In the beginning, back to Bluez release 4.80, we can trigger
the discovering service when registering the client. Then it can store
few files in /var/lib/bluetooth/BT_ADDR. When we start bluetooth
daemon, it would register GATT D-Bus interface based on those files.
If you'd like to see those D-Bus interface, you could rollback to
release 4.80. You can use gatttoool to discover the primary service,
and copy 'primary', 'attributes' and 'characteristic' files. Then you
could use the latest Bluez, but move those files to the same folder.
You should be able to see the GATT D-Bus interface.
>
> Thanks,
>
> Inga Stotland
>
> ingas@codeaurora.org
> Employee of Qualcomm Innovation Center, Inc.
> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum
>
Regards,
Erin Yueh
^ permalink raw reply
* [PATCH] Bluetooth: Support SCO over HCI for Atheros AR300x Bluetooth device
From: Suraj Sumangala @ 2011-01-28 10:49 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Jothikumar.Mothilal, Suraj Sumangala
This patch adds SCO over HCI support to Atheros AR300x HCI transport
driver.
Signed-off-by: Suraj Sumangala <suraj@atheros.com>
---
drivers/bluetooth/hci_ath.c | 18 +++++++++---------
1 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/drivers/bluetooth/hci_ath.c b/drivers/bluetooth/hci_ath.c
index 6a160c1..161bd20 100644
--- a/drivers/bluetooth/hci_ath.c
+++ b/drivers/bluetooth/hci_ath.c
@@ -162,11 +162,6 @@ static int ath_enqueue(struct hci_uart *hu, struct sk_buff *skb)
{
struct ath_struct *ath = hu->priv;
- if (bt_cb(skb)->pkt_type == HCI_SCODATA_PKT) {
- kfree_skb(skb);
- return 0;
- }
-
/*
* Update power management enable flag with parameters of
* HCI sleep enable vendor specific HCI command.
@@ -183,10 +178,15 @@ static int ath_enqueue(struct hci_uart *hu, struct sk_buff *skb)
/* Prepend skb with frame type */
memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
- skb_queue_tail(&ath->txq, skb);
- set_bit(HCI_UART_SENDING, &hu->tx_state);
-
- schedule_work(&ath->ctxtsw);
+ if (bt_cb(skb)->pkt_type == HCI_SCODATA_PKT) {
+ skb_queue_head(&ath->txq, skb);
+ clear_bit(HCI_UART_SENDING, &hu->tx_state);
+ hci_uart_tx_wakeup(hu);
+ } else {
+ skb_queue_tail(&ath->txq, skb);
+ set_bit(HCI_UART_SENDING, &hu->tx_state);
+ schedule_work(&ath->ctxtsw);
+ }
return 0;
}
--
1.7.0.4
^ permalink raw reply related
* [PATCH 1/2] Fix not fetching current usb mode when obexd starts
From: Luiz Augusto von Dentz @ 2011-01-28 13:17 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.dentz-von@nokia.com>
Cable may be already plugged when obexd starts
---
plugins/usb.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 59 insertions(+), 6 deletions(-)
diff --git a/plugins/usb.c b/plugins/usb.c
index 949e94f..580e7b8 100644
--- a/plugins/usb.c
+++ b/plugins/usb.c
@@ -173,20 +173,27 @@ static void sig_usb(int sig)
{
}
+static void usb_set_mode(struct obex_server *server, const char *mode)
+{
+ DBG("%s", mode);
+
+ if (g_str_equal(mode, "ovi_suite") == TRUE)
+ usb_connect(server);
+ else if (g_str_equal(mode, "USB disconnected") == TRUE)
+ usb_disconnect(server);
+}
+
static gboolean handle_signal(DBusConnection *connection,
DBusMessage *message, void *user_data)
{
struct obex_server *server = user_data;
- const char *state;
+ const char *mode;
dbus_message_get_args(message, NULL,
- DBUS_TYPE_STRING, &state,
+ DBUS_TYPE_STRING, &mode,
DBUS_TYPE_INVALID);
- if (g_str_equal(state, "ovi_suite") == TRUE)
- usb_connect(server);
- else if (g_str_equal(state, "USB disconnected") == TRUE)
- usb_disconnect(server);
+ usb_set_mode(server, mode);
return TRUE;
}
@@ -197,18 +204,64 @@ static void usb_stop(void *data)
g_source_remove(id);
}
+static void mode_request_reply(DBusPendingCall *call, void *user_data)
+{
+ struct obex_server *server = user_data;
+ DBusMessage *reply = dbus_pending_call_steal_reply(call);
+ DBusError derr;
+
+ dbus_error_init(&derr);
+ if (dbus_set_error_from_message(&derr, reply)) {
+ error("usb: Replied with an error: %s, %s",
+ derr.name, derr.message);
+ dbus_error_free(&derr);
+ } else {
+ const char *mode;
+ dbus_message_get_args(reply, NULL,
+ DBUS_TYPE_STRING, &mode,
+ DBUS_TYPE_INVALID);
+
+ usb_set_mode(server, mode);
+ }
+
+ dbus_message_unref(reply);
+}
+
static void *usb_start(struct obex_server *server, int *err)
{
guint id;
+ DBusMessage *msg;
+ DBusPendingCall *call;
+
+ msg = dbus_message_new_method_call("com.meego.usb_moded",
+ "/com/meego/usb_moded",
+ "com.meego.usb_moded",
+ "mode_request");
+
+ if (dbus_connection_send_with_reply(connection,
+ msg, &call, -1) == FALSE) {
+ error("usb: unable to send mode_request");
+ goto fail;
+ }
+
+ dbus_pending_call_set_notify(call, mode_request_reply, server, NULL);
+ dbus_pending_call_unref(call);
id = g_dbus_add_signal_watch(connection, NULL, NULL,
"com.meego.usb_moded",
"sig_usb_state_ind",
handle_signal, server, NULL);
+
if (err != NULL)
*err = 0;
return GUINT_TO_POINTER(id);
+
+fail:
+ if (err != NULL)
+ *err = -1;
+
+ return NULL;
}
static struct obex_transport_driver driver = {
--
1.7.1
^ 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