* [PATCHv2] Bluetooth: fix crash by disabling tasklet in sock accept
From: Emeltchenko Andrei @ 2011-01-20 8:38 UTC (permalink / raw)
To: linux-bluetooth
From: Andrei Emeltchenko <andrei.emeltchenko@nokia.com>
Crash can happen when tasklet handling connect/disconnect requests
preempts socket accept. Can be reproduced with "l2test -r" on one
side and several "l2test -c -b 1000 -i hci0 -P 10 <bdaddr>" on the
other side.
disable taskets in socket accept and change lock_sock and release_sock
to bh_lock_sock and bh_unlock_sock since we have to use spinlocks and
there is no need to mark sock as owned by user.
...
[ 3555.897247] Unable to handle kernel NULL pointer dereference at virtual
address 000000bc
[ 3555.915039] pgd = cab9c000
[ 3555.917785] [000000bc] *pgd=8bf3d031, *pte=00000000, *ppte=00000000
[ 3555.928314] Internal error: Oops: 17 [#1] PREEMPT
[ 3555.999786] CPU: 0 Not tainted (2.6.32.21-13874-g67918ef #65)
...
[ 3556.005981] PC is at bt_accept_unlink+0x20/0x58 [bluetooth]
[ 3556.011627] LR is at bt_accept_dequeue+0x3c/0xe8 [bluetooth]
...
[ 3556.161285] [<bf0007fc>] (bt_accept_unlink+0x20/0x58 [bluetooth]) from
[<bf000870>] (bt_accept_dequeue+0x3c/0xe8 [bluetooth])
[ 3556.172729] [<bf000870>] (bt_accept_dequeue+0x3c/0xe8 [bluetooth]) from
[<bf324df8>] (l2cap_sock_accept+0x100/0x15c [l2cap])
[ 3556.184082] [<bf324df8>] (l2cap_sock_accept+0x100/0x15c [l2cap]) from
[<c026a0a8>] (sys_accept4+0x120/0x1e0)
[ 3556.193969] [<c026a0a8>] (sys_accept4+0x120/0x1e0) from [<c002c9a0>]
(ret_fast_syscall+0x0/0x2c)
[ 3556.202819] Code: e5813000 e5901164 e580c160 e580c15c (e1d13bbc)
...
Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@nokia.com>
---
net/bluetooth/af_bluetooth.c | 12 ++++++++----
1 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
index a6732b5..f545566 100644
--- a/net/bluetooth/af_bluetooth.c
+++ b/net/bluetooth/af_bluetooth.c
@@ -199,14 +199,15 @@ struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock)
BT_DBG("parent %p", parent);
+ local_bh_disable();
list_for_each_safe(p, n, &bt_sk(parent)->accept_q) {
sk = (struct sock *) list_entry(p, struct bt_sock, accept_q);
- lock_sock(sk);
+ bh_lock_sock(sk);
/* FIXME: Is this check still needed */
if (sk->sk_state == BT_CLOSED) {
- release_sock(sk);
+ bh_unlock_sock(sk);
bt_accept_unlink(sk);
continue;
}
@@ -216,12 +217,15 @@ struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock)
bt_accept_unlink(sk);
if (newsock)
sock_graft(sk, newsock);
- release_sock(sk);
+ bh_unlock_sock(sk);
+ local_bh_enable();
return sk;
}
- release_sock(sk);
+ bh_unlock_sock(sk);
}
+ local_bh_enable();
+
return NULL;
}
EXPORT_SYMBOL(bt_accept_dequeue);
--
1.7.1
^ permalink raw reply related
* Re: [PATCH] Update a2dpsink to use new Acquire API
From: Johan Hedberg @ 2011-01-20 9:29 UTC (permalink / raw)
To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <1295515781-16658-1-git-send-email-luiz.dentz@gmail.com>
Hi Luiz,
On Thu, Jan 20, 2011, Luiz Augusto von Dentz wrote:
> ---
> audio/gstavdtpsink.c | 19 +++++++------------
> 1 files changed, 7 insertions(+), 12 deletions(-)
Thanks. Pushed upstream.
Johan
^ permalink raw reply
* [PATCH] Update a2dpsink to use new Acquire API
From: Luiz Augusto von Dentz @ 2011-01-20 9:29 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.dentz-von@nokia.com>
---
audio/gstavdtpsink.c | 19 +++++++------------
1 files changed, 7 insertions(+), 12 deletions(-)
diff --git a/audio/gstavdtpsink.c b/audio/gstavdtpsink.c
index 48fa24d..ce1365a 100644
--- a/audio/gstavdtpsink.c
+++ b/audio/gstavdtpsink.c
@@ -1280,16 +1280,7 @@ static gboolean gst_avdtp_sink_transport_parse_property(GstAvdtpSink *self,
break;
}
- case DBUS_TYPE_UINT16: {
- uint16_t value;
- dbus_message_iter_get_basic(&variant_i, &value);
-
- if (g_str_equal(key, "OMTU") == TRUE)
- self->data->link_mtu = value;
-
- break;
- }
- case DBUS_TYPE_STRING: {
+ case DBUS_TYPE_STRING: {
const char *value;
dbus_message_iter_get_basic(&variant_i, &value);
@@ -1328,6 +1319,7 @@ static gboolean gst_avdtp_sink_transport_acquire(GstAvdtpSink *self)
DBusError err;
const char *access_type = "w";
int fd;
+ uint16_t imtu, omtu;
dbus_error_init(&err);
@@ -1348,7 +1340,9 @@ static gboolean gst_avdtp_sink_transport_acquire(GstAvdtpSink *self)
goto fail;
if (dbus_message_get_args(reply, &err, DBUS_TYPE_UNIX_FD, &fd,
- DBUS_TYPE_INVALID) == FALSE)
+ DBUS_TYPE_UINT16, &imtu,
+ DBUS_TYPE_UINT16, &omtu,
+ DBUS_TYPE_INVALID) == FALSE)
goto fail;
dbus_message_unref(reply);
@@ -1356,7 +1350,8 @@ static gboolean gst_avdtp_sink_transport_acquire(GstAvdtpSink *self)
self->stream = g_io_channel_unix_new(fd);
g_io_channel_set_encoding(self->stream, NULL, NULL);
g_io_channel_set_close_on_unref(self->stream, TRUE);
- GST_DEBUG_OBJECT(self, "stream_fd=%d", fd);
+ self->data->link_mtu = omtu;
+ GST_DEBUG_OBJECT(self, "stream_fd=%d mtu=%d", fd, omtu);
return TRUE;
--
1.7.1
^ permalink raw reply related
* Re: [PATCH 1/3] Fix default GATT/ATT MTU sizes
From: Johan Hedberg @ 2011-01-20 9:32 UTC (permalink / raw)
To: Brian Gix
Cc: linux-bluetooth, vinicius.gomes, claudio.takahasi, padovan,
rshaffer
In-Reply-To: <1295474453-8495-2-git-send-email-bgix@codeaurora.org>
Hi Brian,
On Wed, Jan 19, 2011, Brian Gix wrote:
> + if (io == le_io)
> + channel->mtu = ATT_DEFAULT_LE_MTU;
> + else
> + channel->mtu = ATT_DEFAULT_L2CAP_MTU;
> +
I don't think that will work. le_io is the server socket and io is the
new client socket. So they will never be one and the same. Did you
actually test this code?
Johan
^ permalink raw reply
* Re: [PATCH 2/3] Fix Handle range if Pri/Sec Service is Empty
From: Johan Hedberg @ 2011-01-20 9:33 UTC (permalink / raw)
To: Brian Gix
Cc: linux-bluetooth, vinicius.gomes, claudio.takahasi, padovan,
rshaffer
In-Reply-To: <1295474453-8495-3-git-send-email-bgix@codeaurora.org>
Hi Brian,
On Wed, Jan 19, 2011, Brian Gix wrote:
> ---
> src/attrib-server.c | 1 +
> 1 files changed, 1 insertions(+), 0 deletions(-)
>
> diff --git a/src/attrib-server.c b/src/attrib-server.c
> index 04bc1ec..f38d61a 100644
> --- a/src/attrib-server.c
> +++ b/src/attrib-server.c
> @@ -242,6 +242,7 @@ static uint16_t read_by_group(struct gatt_channel *channel, uint16_t start,
>
> last_size = a->len;
> old = cur;
> + last_handle = cur->handle;
> }
>
> if (groups == NULL)
Pushed upstream. Thanks.
Johan
^ permalink raw reply
* Re: [PATCH 3/3] Add READ_BLOB_REQUEST support to attribute server
From: Johan Hedberg @ 2011-01-20 9:35 UTC (permalink / raw)
To: Brian Gix
Cc: linux-bluetooth, vinicius.gomes, claudio.takahasi, padovan,
rshaffer
In-Reply-To: <1295474453-8495-4-git-send-email-bgix@codeaurora.org>
Hi Brian,
On Wed, Jan 19, 2011, Brian Gix wrote:
> ---
> attrib/att.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
> attrib/att.h | 6 +++++-
> src/attrib-server.c | 39 +++++++++++++++++++++++++++++++++++++--
> 3 files changed, 86 insertions(+), 3 deletions(-)
This one has also been pushed upstream. Thanks.
Johan
^ permalink raw reply
* [PATCH] Fix duplicate characteristics
From: Bruna Moreira @ 2011-01-20 13:27 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Bruna Moreira
The Discover() operation (from DBus API) was registering the same
characteristics after running several times. This can be checked using
test-attrib.
---
attrib/client.c | 7 +++++++
1 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/attrib/client.c b/attrib/client.c
index 767d1c1..44638d3 100644
--- a/attrib/client.c
+++ b/attrib/client.c
@@ -870,6 +870,13 @@ static void char_discovered_cb(GSList *characteristics, guint8 status,
for (l = characteristics; l; l = l->next) {
struct att_char *current_chr = l->data;
struct characteristic *chr;
+ guint handle = current_chr->value_handle;
+ GSList *lchr;
+
+ lchr = g_slist_find_custom(prim->chars,
+ GUINT_TO_POINTER(handle), characteristic_handle_cmp);
+ if (lchr)
+ continue;
chr = g_new0(struct characteristic, 1);
chr->prim = prim;
--
1.7.0.4
^ permalink raw reply related
* Problem with inquiry result with rssi
From: Ulrich Bürgi @ 2011-01-20 15:44 UTC (permalink / raw)
To: linux-bluetooth
Hello everyone,
I'm encountering a strange behavior regarding inquiry results. I'm
working on a C program, which has a method called 'scanner_start'. This
method performs an inquiry and reports the corresponding addresses and
RSSI values of all results.
When I just call this method and do nothing else, it works as intended.
However, if I do anything prior to that, I only get 'normal' inquiry
results without RSSI.
As example, this works:
/* do nothing here */
scanner_start();
/* do something here */
whereas this fails:
/* do nothing here */
int i;
scanner_start();
/* do something here */
Below is the complete source code needed to reproduce this behavior.
I cannot really imagine, how an unused declaration can have an impact on
the inquiry results. Does anybody have a clue, how this could be?
Thank you,
Ulrich
--
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/poll.h>
#include <sys/ioctl.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <bluetooth/hci_lib.h>
static void print_result(bdaddr_t *bdaddr, char has_rssi, int rssi)
{
char addr[18];
ba2str(bdaddr, addr);
printf("%17s", addr);
if(has_rssi)
printf(" RSSI:%d", rssi);
else
printf(" RSSI:n/a");
printf("\n");
fflush(NULL);
}
static void scanner_start()
{
int dev_id, sock = 0;
struct hci_filter flt;
inquiry_cp cp;
unsigned char buf[HCI_MAX_EVENT_SIZE], *ptr;
hci_event_hdr *hdr;
char canceled = 0;
inquiry_info_with_rssi *info_rssi;
inquiry_info *info;
int results, i, len;
struct pollfd p;
dev_id = hci_get_route(NULL);
sock = hci_open_dev( dev_id );
if (dev_id < 0 || sock < 0) {
perror("Can't open socket");
return;
}
hci_filter_clear(&flt);
hci_filter_set_ptype(HCI_EVENT_PKT, &flt);
hci_filter_set_event(EVT_INQUIRY_RESULT, &flt);
hci_filter_set_event(EVT_INQUIRY_RESULT_WITH_RSSI, &flt);
hci_filter_set_event(EVT_INQUIRY_COMPLETE, &flt);
if (setsockopt(sock, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) {
perror("Can't set HCI filter");
return;
}
if (hci_send_cmd(sock, OGF_HOST_CTL, OCF_WRITE_INQUIRY_MODE,
WRITE_INQUIRY_MODE_RP_SIZE, &cp) < 0) {
perror("Can't set inquiry mode");
return;
}
memset (&cp, 0, sizeof(cp));
cp.lap[2] = 0x9e;
cp.lap[1] = 0x8b;
cp.lap[0] = 0x33;
cp.num_rsp = 0;
cp.length = 0x30;
printf("Starting inquiry with RSSI...\n");
if (hci_send_cmd (sock, OGF_LINK_CTL, OCF_INQUIRY, INQUIRY_CP_SIZE,
&cp) < 0) {
perror("Can't start inquiry");
return;
}
p.fd = sock;
p.events = POLLIN | POLLERR | POLLHUP;
while(!canceled) {
p.revents = 0;
/* poll the BT device for an event */
if (poll(&p, 1, -1) > 0) {
len = read(sock, buf, sizeof(buf));
if (len < 0)
continue;
else if (len == 0)
break;
hdr = (void *) (buf + 1);
ptr = buf + (1 + HCI_EVENT_HDR_SIZE);
results = ptr[0];
switch (hdr->evt) {
case EVT_INQUIRY_RESULT:
for (i = 0; i < results; i++) {
info = (void *)ptr + (sizeof(*info) * i) + 1;
print_result(&info->bdaddr, 0, 0);
}
break;
case EVT_INQUIRY_RESULT_WITH_RSSI:
for (i = 0; i < results; i++) {
info_rssi = (void *)ptr + (sizeof(*info_rssi) * i) + 1;
print_result(&info_rssi->bdaddr, 1, info_rssi->rssi);
}
break;
case EVT_INQUIRY_COMPLETE:
canceled = 1;
break;
}
}
}
close(sock);
}
int main(int argc, char **argv)
{
//int i; /* causes inq. result to have no rssi value */
scanner_start();
return 0;
}
^ permalink raw reply
* [PATCH 0/1] Fix incoming attrib-server connection MTUs
From: Brian Gix @ 2011-01-20 19:09 UTC (permalink / raw)
To: linux-bluetooth; +Cc: vinicius.gomes, claudio.takahasi, johan.hedberg, padovan
This patch fixes bug detected by Johan.
The reworked patch passes a user_data argument to the bt_io_listen
call which identifies the server IO channel (le_io or l2cap_io). This
is propegated to the eventual connect_event, and used to set up the
correct default MTU for the underlying RF carrier channel.
As stated in the previous patches, this default MTU is important when
reading long Attributes, because some/most remote GATT clients assume
completion of an Attribute read when a shorter-than-MTU result is returned,
making it important for the server to completely fill the response
packets when possible.
--
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] Fix incoming attrib-server connection MTUs
From: Brian Gix @ 2011-01-20 19:09 UTC (permalink / raw)
To: linux-bluetooth
Cc: vinicius.gomes, claudio.takahasi, johan.hedberg, padovan,
Brian Gix
In-Reply-To: <1295550541-30535-1-git-send-email-bgix@codeaurora.org>
It is important for the Attribute Server to be aware of and
completely fill response packets up to the full MTU when
reading long attributes. Some remote devices will only request
additional (READ_BLOB) data if the preceding read sent the
maximum amount of data.
Incoming connections are identified as L2CAP or LE by pointers
to the Service IO channel the incoming connection was recieved on
in the user_data parameter. L2CAP channels are set to the BR/EDR minimum
MTU of 48, and LE channels to the LE payload size of 23.
---
attrib/att.h | 3 ++-
attrib/gatt.c | 28 ++++++++++++++--------------
src/attrib-server.c | 13 +++++++++----
3 files changed, 25 insertions(+), 19 deletions(-)
diff --git a/attrib/att.h b/attrib/att.h
index 29ab0e6..1caa62a 100644
--- a/attrib/att.h
+++ b/attrib/att.h
@@ -107,7 +107,8 @@
#define ATT_MAX_MTU 256
-#define ATT_DEFAULT_MTU 23
+#define ATT_DEFAULT_L2CAP_MTU 48
+#define ATT_DEFAULT_LE_MTU 23
/* Requirements for read/write operations */
enum {
diff --git a/attrib/gatt.c b/attrib/gatt.c
index 5d7887e..f3b513e 100644
--- a/attrib/gatt.c
+++ b/attrib/gatt.c
@@ -105,7 +105,7 @@ static void primary_by_uuid_cb(guint8 status, const guint8 *ipdu,
struct discover_primary *dp = user_data;
GSList *ranges, *last;
struct att_range *range;
- uint8_t opdu[ATT_DEFAULT_MTU];
+ uint8_t opdu[ATT_DEFAULT_LE_MTU];
guint16 oplen;
int err = 0;
@@ -195,7 +195,7 @@ static void primary_all_cb(guint8 status, const guint8 *ipdu, guint16 iplen,
err = 0;
if (end != 0xffff) {
- uint8_t opdu[ATT_DEFAULT_MTU];
+ uint8_t opdu[ATT_DEFAULT_LE_MTU];
guint16 oplen = encode_discover_primary(end + 1, 0xffff, NULL,
opdu, sizeof(opdu));
@@ -214,7 +214,7 @@ guint gatt_discover_primary(GAttrib *attrib, uuid_t *uuid, gatt_cb_t func,
gpointer user_data)
{
struct discover_primary *dp;
- uint8_t pdu[ATT_DEFAULT_MTU];
+ uint8_t pdu[ATT_DEFAULT_LE_MTU];
GAttribResultFunc cb;
guint16 plen;
@@ -245,7 +245,7 @@ static void char_discovered_cb(guint8 status, const guint8 *ipdu, guint16 iplen,
struct discover_char *dc = user_data;
struct att_data_list *list;
unsigned int i, err;
- uint8_t opdu[ATT_DEFAULT_MTU];
+ uint8_t opdu[ATT_DEFAULT_LE_MTU];
guint16 oplen;
uuid_t uuid;
uint16_t last = 0;
@@ -314,7 +314,7 @@ done:
guint gatt_discover_char(GAttrib *attrib, uint16_t start, uint16_t end,
gatt_cb_t func, gpointer user_data)
{
- uint8_t pdu[ATT_DEFAULT_MTU];
+ uint8_t pdu[ATT_DEFAULT_LE_MTU];
struct discover_char *dc;
guint16 plen;
uuid_t uuid;
@@ -342,7 +342,7 @@ guint gatt_read_char_by_uuid(GAttrib *attrib, uint16_t start, uint16_t end,
uuid_t *uuid, GAttribResultFunc func,
gpointer user_data)
{
- uint8_t pdu[ATT_DEFAULT_MTU];
+ uint8_t pdu[ATT_DEFAULT_LE_MTU];
guint16 plen;
plen = enc_read_by_type_req(start, end, uuid, pdu, sizeof(pdu));
@@ -381,7 +381,7 @@ static void read_blob_helper(guint8 status, const guint8 *rpdu, guint16 rlen,
gpointer user_data)
{
struct read_long_data *long_read = user_data;
- uint8_t pdu[ATT_DEFAULT_MTU];
+ uint8_t pdu[ATT_DEFAULT_LE_MTU];
guint8 *tmp;
guint16 plen;
guint id;
@@ -402,7 +402,7 @@ static void read_blob_helper(guint8 status, const guint8 *rpdu, guint16 rlen,
long_read->buffer = tmp;
long_read->size += rlen - 1;
- if (rlen < ATT_DEFAULT_MTU)
+ if (rlen < ATT_DEFAULT_LE_MTU)
goto done;
plen = enc_read_blob_req(long_read->handle, long_read->size - 1,
@@ -427,11 +427,11 @@ static void read_char_helper(guint8 status, const guint8 *rpdu,
guint16 rlen, gpointer user_data)
{
struct read_long_data *long_read = user_data;
- uint8_t pdu[ATT_DEFAULT_MTU];
+ uint8_t pdu[ATT_DEFAULT_LE_MTU];
guint16 plen;
guint id;
- if (status != 0 || rlen < ATT_DEFAULT_MTU)
+ if (status != 0 || rlen < ATT_DEFAULT_LE_MTU)
goto done;
long_read->buffer = g_malloc(rlen);
@@ -461,7 +461,7 @@ done:
guint gatt_read_char(GAttrib *attrib, uint16_t handle, GAttribResultFunc func,
gpointer user_data)
{
- uint8_t pdu[ATT_DEFAULT_MTU];
+ uint8_t pdu[ATT_DEFAULT_LE_MTU];
guint16 plen;
guint id;
struct read_long_data *long_read;
@@ -493,7 +493,7 @@ guint gatt_read_char(GAttrib *attrib, uint16_t handle, GAttribResultFunc func,
guint gatt_write_char(GAttrib *attrib, uint16_t handle, uint8_t *value,
int vlen, GAttribResultFunc func, gpointer user_data)
{
- uint8_t pdu[ATT_DEFAULT_MTU];
+ uint8_t pdu[ATT_DEFAULT_LE_MTU];
guint16 plen;
plen = enc_write_req(handle, value, vlen, pdu, sizeof(pdu));
@@ -504,7 +504,7 @@ guint gatt_write_char(GAttrib *attrib, uint16_t handle, uint8_t *value,
guint gatt_find_info(GAttrib *attrib, uint16_t start, uint16_t end,
GAttribResultFunc func, gpointer user_data)
{
- uint8_t pdu[ATT_DEFAULT_MTU];
+ uint8_t pdu[ATT_DEFAULT_LE_MTU];
guint16 plen;
plen = enc_find_info_req(start, end, pdu, sizeof(pdu));
@@ -518,7 +518,7 @@ guint gatt_find_info(GAttrib *attrib, uint16_t start, uint16_t end,
guint gatt_write_cmd(GAttrib *attrib, uint16_t handle, uint8_t *value, int vlen,
GDestroyNotify notify, gpointer user_data)
{
- uint8_t pdu[ATT_DEFAULT_MTU];
+ uint8_t pdu[ATT_DEFAULT_LE_MTU];
guint16 plen;
plen = enc_write_cmd(handle, value, vlen, pdu, sizeof(pdu));
diff --git a/src/attrib-server.c b/src/attrib-server.c
index 923bde7..f03a5b9 100644
--- a/src/attrib-server.c
+++ b/src/attrib-server.c
@@ -737,6 +737,7 @@ done:
static void connect_event(GIOChannel *io, GError *err, void *user_data)
{
struct gatt_channel *channel;
+ GIOChannel **server_io = user_data;
GError *gerr = NULL;
if (err) {
@@ -758,8 +759,12 @@ static void connect_event(GIOChannel *io, GError *err, void *user_data)
return;
}
+ if (server_io == &l2cap_io)
+ channel->mtu = ATT_DEFAULT_L2CAP_MTU;
+ else
+ channel->mtu = ATT_DEFAULT_LE_MTU;
+
channel->attrib = g_attrib_new(io);
- channel->mtu = ATT_DEFAULT_MTU;
g_io_channel_unref(io);
channel->id = g_attrib_register(channel->attrib, GATTRIB_ALL_EVENTS,
@@ -775,7 +780,7 @@ static void confirm_event(GIOChannel *io, void *user_data)
{
GError *gerr = NULL;
- if (bt_io_accept(io, connect_event, NULL, NULL, &gerr) == FALSE) {
+ if (bt_io_accept(io, connect_event, user_data, NULL, &gerr) == FALSE) {
error("bt_io_accept: %s", gerr->message);
g_error_free(gerr);
g_io_channel_unref(io);
@@ -824,7 +829,7 @@ int attrib_server_init(void)
/* BR/EDR socket */
l2cap_io = bt_io_listen(BT_IO_L2CAP, NULL, confirm_event,
- NULL, NULL, &gerr,
+ &l2cap_io, NULL, &gerr,
BT_IO_OPT_SOURCE_BDADDR, BDADDR_ANY,
BT_IO_OPT_PSM, GATT_PSM,
BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
@@ -857,7 +862,7 @@ int attrib_server_init(void)
/* LE socket */
le_io = bt_io_listen(BT_IO_L2CAP, NULL, confirm_event,
- NULL, NULL, &gerr,
+ &le_io, NULL, &gerr,
BT_IO_OPT_SOURCE_BDADDR, BDADDR_ANY,
BT_IO_OPT_CID, GATT_CID,
BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
--
1.7.1
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 related
* [PATCH] Partial implementation of LE events and commands dump.
From: André Dieb Martins @ 2011-01-20 19:18 UTC (permalink / raw)
To: linux-bluetooth; +Cc: André Dieb Martins
---
parser/hci.c | 226 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 226 insertions(+), 0 deletions(-)
diff --git a/parser/hci.c b/parser/hci.c
index 014c8cd..d9bac9b 100644
--- a/parser/hci.c
+++ b/parser/hci.c
@@ -704,6 +704,59 @@ static char *authentication2str(uint8_t authentication)
}
}
+static char *eventmask2str(uint8_t mask[8])
+{
+ int i;
+
+ for (i = 0; i < 7; i++) {
+ if (mask[i] != 0x00)
+ return "Reserved";
+ }
+
+ switch (mask[7]) {
+ case 0x00:
+ return "No LE events specified";
+ case 0x01:
+ return "LE Connection Complete Event";
+ case 0x02:
+ return "LE Advertising Report Event";
+ case 0x04:
+ return "LE Connection Update Complete Event";
+ case 0x08:
+ return "LE Read Remote Used Features Complete Event";
+ case 0x10:
+ return "LE Long Term Key Request Event";
+ case 0x1F:
+ return "Default";
+ default:
+ return "Reserved";
+ }
+}
+
+static char *lefeatures2str(uint8_t features[8])
+{
+ if (features[0] & 0x01)
+ return "Link Layer supports LE Encryption";
+
+ return "RFU";
+}
+
+static char *filterpolicy2str(uint8_t policy)
+{
+ switch (policy) {
+ case 0x00:
+ return "Allow scan from any, connection from any";
+ case 0x01:
+ return "Allow scan from white list, connection from any";
+ case 0x02:
+ return "Allow scan from any, connection from white list";
+ case 0x03:
+ return "Allow scan and connection from white list";
+ default:
+ return "Reserved";
+ }
+}
+
static inline void ext_inquiry_response_dump(int level, struct frame *frm)
{
void *ptr = frm->ptr;
@@ -1499,6 +1552,85 @@ static inline void le_create_connection_dump(int level, struct frame *frm)
printf("bdaddr %s type %d\n", addr, cp->peer_bdaddr_type);
}
+static inline void le_set_event_mask_dump(int level, struct frame *frm)
+{
+ int i;
+ le_set_event_mask_cp *cp = frm->ptr;
+
+ p_indent(level, frm);
+ printf("mask 0x");
+ for (i = 0; i < 8; i++)
+ printf("%.2x", cp->mask[i]);
+
+ printf(" (%s)\n", eventmask2str(cp->mask));
+}
+
+static inline void le_set_random_address_dump(int level, struct frame *frm)
+{
+ char addr[18];
+ le_set_random_address_cp *cp = frm->ptr;
+
+ p_indent(level, frm);
+ p_ba2str(&cp->bdaddr, addr);
+ printf("bdaddr %s\n", addr);
+}
+
+
+static inline void le_set_advertising_parameters_dump(int level, struct frame *frm)
+{
+ char addr[18];
+ le_set_advertising_parameters_cp *cp = frm->ptr;
+
+ p_indent(level, frm);
+ printf("min 0x%04xms max 0x%04xms\n", cp->min_interval, cp->max_interval);
+
+ p_indent(level, frm);
+ printf("type 0x%02x (%s) ownbdaddr 0x%02x (%s)\n", cp->advtype,
+ evttype2str(cp->advtype), cp->own_bdaddr_type,
+ bdaddrtype2str(cp->own_bdaddr_type));
+
+ p_indent(level, frm);
+ p_ba2str(&cp->direct_bdaddr, addr);
+ printf("directbdaddr 0x%02x (%s) %s\n", cp->direct_bdaddr_type,
+ bdaddrtype2str(cp->direct_bdaddr_type), addr);
+
+ p_indent(level, frm);
+ printf("channelmap 0x%02x filterpolicy 0x%02x (%s)\n",
+ cp->chan_map, cp->filter, filterpolicy2str(cp->filter));
+}
+
+static inline void le_set_scan_parameters_dump(int level, struct frame *frm)
+{
+ le_set_scan_parameters_cp *cp = frm->ptr;
+
+ p_indent(level, frm);
+ printf("type 0x%02x (%s)\n", cp->type,
+ cp->type == 0x00 ? "passive" : "active");
+
+ p_indent(level, frm);
+ printf("interval %04xms window %04xms\n", cp->interval, cp->window);
+
+ p_indent(level, frm);
+ printf("own address: 0x%02x (%s) policy: %s\n", cp->own_bdaddr_type,
+ bdaddrtype2str(cp->own_bdaddr_type),
+ (cp->filter == 0x00 ? "All" :
+ (cp->filter == 0x01 ? "white list only" : "reserved")));
+}
+
+static inline void le_set_scan_enable_dump(int level, struct frame *frm)
+{
+ le_set_scan_enable_cp *cp = frm->ptr;
+
+ p_indent(level, frm);
+ printf("value 0x%02x (%s)\n", cp->enable,
+ (cp->enable == 0x00 ? "scanning disabled" :
+ "scanning enabled"));
+
+ p_indent(level, frm);
+ printf("filter duplicates 0x%02x (%s)\n", cp->filter_dup,
+ (cp->filter_dup == 0x00 ? "disabled" : "enabled"));
+}
+
static inline void command_dump(int level, struct frame *frm)
{
hci_command_hdr *hdr = frm->ptr;
@@ -1790,6 +1922,25 @@ static inline void command_dump(int level, struct frame *frm)
case OGF_LE_CTL:
switch (ocf) {
+ case OCF_LE_SET_EVENT_MASK:
+ le_set_event_mask_dump(level + 1, frm);
+ return;
+ case OCF_LE_READ_BUFFER_SIZE:
+ case OCF_LE_READ_LOCAL_SUPPORTED_FEATURES:
+ case OCF_LE_READ_ADVERTISING_CHANNEL_TX_POWER:
+ return;
+ case OCF_LE_SET_RANDOM_ADDRESS:
+ le_set_random_address_dump(level + 1, frm);
+ return;
+ case OCF_LE_SET_ADVERTISING_PARAMETERS:
+ le_set_advertising_parameters_dump(level + 1, frm);
+ return;
+ case OCF_LE_SET_SCAN_PARAMETERS:
+ le_set_scan_parameters_dump(level + 1, frm);
+ return;
+ case OCF_LE_SET_SCAN_ENABLE:
+ le_set_scan_enable_dump(level + 1, frm);
+ return;
case OCF_LE_CREATE_CONN:
le_create_connection_dump(level + 1, frm);
return;
@@ -2455,6 +2606,50 @@ static inline void write_remote_amp_assoc_dump(int level, struct frame *frm)
}
}
+static inline void le_read_buffer_size_response_dump(int level, struct frame *frm)
+{
+ le_read_buffer_size_rp *rp = frm->ptr;
+
+ p_indent(level, frm);
+ printf("status 0x%2.2x pktlen 0x%4.4x maxpkt 0x%2.2x\n", rp->status,
+ rp->pkt_len, rp->max_pkt);
+
+ if (rp->status > 0) {
+ p_indent(level, frm);
+ printf("Error: %s\n", status2str(rp->status));
+ }
+}
+
+static inline void le_read_local_supported_features_dump(int level, struct frame *frm)
+{
+ int i;
+ le_read_local_supported_features_rp *rp = frm->ptr;
+
+ p_indent(level, frm);
+ printf("status 0x%2.2x features 0x", rp->status);
+ for (i = 0; i < 8; i++)
+ printf("%2.2x", rp->features[i]);
+ printf(" (%s)\n", lefeatures2str(rp->features));
+
+ if (rp->status > 0) {
+ p_indent(level, frm);
+ printf("Error: %s\n", status2str(rp->status));
+ }
+}
+
+static inline void le_read_advertising_channel_tx_power_dump(int level, struct frame *frm)
+{
+ le_read_advertising_channel_tx_power_rp *rp = frm->ptr;
+
+ p_indent(level, frm);
+ printf("status 0x%2.2x level 0x%x (dBm)\n", rp->status, rp->level);
+
+ if (rp->status > 0) {
+ p_indent(level, frm);
+ printf("Error: %s\n", status2str(rp->status));
+ }
+}
+
static inline void cmd_complete_dump(int level, struct frame *frm)
{
evt_cmd_complete *evt = frm->ptr;
@@ -2700,6 +2895,37 @@ static inline void cmd_complete_dump(int level, struct frame *frm)
return;
}
break;
+
+ case OGF_LE_CTL:
+ switch (ocf) {
+ case OCF_LE_SET_EVENT_MASK:
+ case OCF_LE_SET_RANDOM_ADDRESS:
+ case OCF_LE_SET_ADVERTISING_PARAMETERS:
+ case OCF_LE_SET_ADVERTISING_DATA:
+ case OCF_LE_SET_SCAN_RESPONSE_DATA:
+ case OCF_LE_SET_ADVERTISE_ENABLE:
+ case OCF_LE_SET_SCAN_PARAMETERS:
+ case OCF_LE_SET_SCAN_ENABLE:
+ case OCF_LE_CREATE_CONN:
+ case OCF_LE_CLEAR_WHITE_LIST:
+ case OCF_LE_ADD_DEVICE_TO_WHITE_LIST:
+ case OCF_LE_REMOVE_DEVICE_FROM_WHITE_LIST:
+ case OCF_LE_SET_HOST_CHANNEL_CLASSIFICATION:
+ case OCF_LE_RECEIVER_TEST:
+ case OCF_LE_TRANSMITTER_TEST:
+ status_response_dump(level, frm);
+ return;
+ case OCF_LE_READ_BUFFER_SIZE:
+ le_read_buffer_size_response_dump(level, frm);
+ return;
+ case OCF_LE_READ_LOCAL_SUPPORTED_FEATURES:
+ le_read_local_supported_features_dump(level, frm);
+ return;
+ case OCF_LE_READ_ADVERTISING_CHANNEL_TX_POWER:
+ le_read_advertising_channel_tx_power_dump(level, frm);
+ return;
+ }
+ break;
}
raw_dump(level, frm);
--
1.7.1
^ permalink raw reply related
* [PATCH] Fix uninitialized struct sockaddr_hci memory passed to bind()
From: Anderson Lizardo @ 2011-01-20 21:02 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Anderson Lizardo
The bind() call in open_socket() was passing a struct sockaddr_hci to
bind() with two uninitialized bytes. This caused "Invalid argument" errors
on kernels which do strict checks of struct sockaddr_hci fields.
---
src/hcidump.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/src/hcidump.c b/src/hcidump.c
index b8eb1e4..97aae5d 100644
--- a/src/hcidump.c
+++ b/src/hcidump.c
@@ -603,6 +603,7 @@ static int open_socket(int dev, unsigned long flags)
}
/* Bind socket to the HCI device */
+ memset(&addr, 0, sizeof(addr));
addr.hci_family = AF_BLUETOOTH;
addr.hci_dev = dev;
if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
--
1.7.0.4
^ permalink raw reply related
* New subscription request to list Bluez-devel from zahir_wp@yahoo.ca
From: bluez-devel-owner @ 2011-01-20 23:17 UTC (permalink / raw)
To: bluez-devel-owner
Your authorization is required for a mailing list subscription request
approval:
For: zahir_wp@yahoo.ca
List: bluez-devel@lists.sourceforge.net
At your convenience, visit:
https://lists.sourceforge.net/lists/admindb/bluez-devel
to process the request.
^ permalink raw reply
* Re: Problem with inquiry result with rssi
From: Vinicius Gomes @ 2011-01-21 4:58 UTC (permalink / raw)
To: Ulrich Bürgi; +Cc: linux-bluetooth
In-Reply-To: <4D385855.2050709@iam.unibe.ch>
SGkgVWxyaWNoLAoKT24gVGh1LCBKYW4gMjAsIDIwMTEgYXQgMTI6NDQgUE0sIFVscmljaCBCw7xy
Z2kgPGJ1ZXJnaUBpYW0udW5pYmUuY2g+IHdyb3RlOgo+IEhlbGxvIGV2ZXJ5b25lLAo+Cj4gSSdt
IGVuY291bnRlcmluZyBhIHN0cmFuZ2UgYmVoYXZpb3IgcmVnYXJkaW5nIGlucXVpcnkgcmVzdWx0
cy4gSSdtIHdvcmtpbmcKPiBvbiBhIEMgcHJvZ3JhbSwgd2hpY2ggaGFzIGEgbWV0aG9kIGNhbGxl
ZCAnc2Nhbm5lcl9zdGFydCcuIFRoaXMgbWV0aG9kCj4gcGVyZm9ybXMgYW4gaW5xdWlyeSBhbmQg
cmVwb3J0cyB0aGUgY29ycmVzcG9uZGluZyBhZGRyZXNzZXMgYW5kIFJTU0kgdmFsdWVzCj4gb2Yg
YWxsIHJlc3VsdHMuCj4gV2hlbiBJIGp1c3QgY2FsbCB0aGlzIG1ldGhvZCBhbmQgZG8gbm90aGlu
ZyBlbHNlLCBpdCB3b3JrcyBhcyBpbnRlbmRlZC4KPiBIb3dldmVyLCBpZiBJIGRvIGFueXRoaW5n
IHByaW9yIHRvIHRoYXQsIEkgb25seSBnZXQgJ25vcm1hbCcgaW5xdWlyeSByZXN1bHRzCj4gd2l0
aG91dCBSU1NJLgo+Cj4gQXMgZXhhbXBsZSwgdGhpcyB3b3JrczoKPiAvKiBkbyBub3RoaW5nIGhl
cmUgKi8KPiBzY2FubmVyX3N0YXJ0KCk7Cj4gLyogZG8gc29tZXRoaW5nIGhlcmUgKi8KPgo+IHdo
ZXJlYXMgdGhpcyBmYWlsczoKPiAvKiBkbyBub3RoaW5nIGhlcmUgKi8KPiBpbnQgaTsKPiBzY2Fu
bmVyX3N0YXJ0KCk7Cj4gLyogZG8gc29tZXRoaW5nIGhlcmUgKi8KPgo+IEJlbG93IGlzIHRoZSBj
b21wbGV0ZSBzb3VyY2UgY29kZSBuZWVkZWQgdG8gcmVwcm9kdWNlIHRoaXMgYmVoYXZpb3IuCj4K
PiBJIGNhbm5vdCByZWFsbHkgaW1hZ2luZSwgaG93IGFuIHVudXNlZCBkZWNsYXJhdGlvbiBjYW4g
aGF2ZSBhbiBpbXBhY3Qgb24gdGhlCj4gaW5xdWlyeSByZXN1bHRzLiBEb2VzIGFueWJvZHkgaGF2
ZSBhIGNsdWUsIGhvdyB0aGlzIGNvdWxkIGJlPwo+Cj4gVGhhbmsgeW91LAo+IFVscmljaAo+Cj4g
LS0KPgo+ICNpbmNsdWRlIDxzdGRpby5oPgo+ICNpbmNsdWRlIDxzdGRsaWIuaD4KPiAjaW5jbHVk
ZSA8dW5pc3RkLmg+Cj4gI2luY2x1ZGUgPHN5cy9zb2NrZXQuaD4KPiAjaW5jbHVkZSA8c3lzL3Bv
bGwuaD4KPiAjaW5jbHVkZSA8c3lzL2lvY3RsLmg+Cj4gI2luY2x1ZGUgPGJsdWV0b290aC9ibHVl
dG9vdGguaD4KPiAjaW5jbHVkZSA8Ymx1ZXRvb3RoL2hjaS5oPgo+ICNpbmNsdWRlIDxibHVldG9v
dGgvaGNpX2xpYi5oPgo+Cj4gc3RhdGljIHZvaWQgcHJpbnRfcmVzdWx0KGJkYWRkcl90ICpiZGFk
ZHIsIGNoYXIgaGFzX3Jzc2ksIGludCByc3NpKQo+IHsKPiDCoCDCoCDCoCDCoGNoYXIgYWRkclsx
OF07Cj4KPiDCoCDCoCDCoCDCoGJhMnN0cihiZGFkZHIsIGFkZHIpOwo+Cj4gwqAgwqAgwqAgwqBw
cmludGYoIiUxN3MiLCBhZGRyKTsKPiDCoCDCoCDCoCDCoGlmKGhhc19yc3NpKQo+IMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgcHJpbnRmKCIgUlNTSTolZCIsIHJzc2kpOwo+IMKgIMKgIMKgIMKgZWxz
ZQo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgcHJpbnRmKCIgUlNTSTpuL2EiKTsKPiDCoCDCoCDC
oCDCoHByaW50ZigiXG4iKTsKPiDCoCDCoCDCoCDCoGZmbHVzaChOVUxMKTsKPiB9Cj4KPgo+IHN0
YXRpYyB2b2lkIHNjYW5uZXJfc3RhcnQoKQo+IHsKPiDCoCDCoCDCoCDCoGludCBkZXZfaWQsIHNv
Y2sgPSAwOwo+IMKgIMKgIMKgIMKgc3RydWN0IGhjaV9maWx0ZXIgZmx0Owo+IMKgIMKgIMKgIMKg
aW5xdWlyeV9jcCBjcDsKPiDCoCDCoCDCoCDCoHVuc2lnbmVkIGNoYXIgYnVmW0hDSV9NQVhfRVZF
TlRfU0laRV0sICpwdHI7Cj4gwqAgwqAgwqAgwqBoY2lfZXZlbnRfaGRyICpoZHI7Cj4gwqAgwqAg
wqAgwqBjaGFyIGNhbmNlbGVkID0gMDsKPiDCoCDCoCDCoCDCoGlucXVpcnlfaW5mb193aXRoX3Jz
c2kgKmluZm9fcnNzaTsKPiDCoCDCoCDCoCDCoGlucXVpcnlfaW5mbyAqaW5mbzsKPiDCoCDCoCDC
oCDCoGludCByZXN1bHRzLCBpLCBsZW47Cj4gwqAgwqAgwqAgwqBzdHJ1Y3QgcG9sbGZkIHA7Cj4K
PiDCoCDCoCDCoCDCoGRldl9pZCA9IGhjaV9nZXRfcm91dGUoTlVMTCk7Cj4gwqAgwqAgwqAgwqBz
b2NrID0gaGNpX29wZW5fZGV2KCBkZXZfaWQgKTsKPiDCoCDCoCDCoCDCoGlmIChkZXZfaWQgPCAw
IHx8IHNvY2sgPCAwKSB7Cj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBwZXJyb3IoIkNhbid0IG9w
ZW4gc29ja2V0Iik7Cj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqByZXR1cm47Cj4gwqAgwqAgwqAg
wqB9Cj4KPiDCoCDCoCDCoCDCoGhjaV9maWx0ZXJfY2xlYXIoJmZsdCk7Cj4gwqAgwqAgwqAgwqBo
Y2lfZmlsdGVyX3NldF9wdHlwZShIQ0lfRVZFTlRfUEtULCAmZmx0KTsKPiDCoCDCoCDCoCDCoGhj
aV9maWx0ZXJfc2V0X2V2ZW50KEVWVF9JTlFVSVJZX1JFU1VMVCwgJmZsdCk7Cj4gwqAgwqAgwqAg
wqBoY2lfZmlsdGVyX3NldF9ldmVudChFVlRfSU5RVUlSWV9SRVNVTFRfV0lUSF9SU1NJLCAmZmx0
KTsKPiDCoCDCoCDCoCDCoGhjaV9maWx0ZXJfc2V0X2V2ZW50KEVWVF9JTlFVSVJZX0NPTVBMRVRF
LCAmZmx0KTsKPiDCoCDCoCDCoCDCoGlmIChzZXRzb2Nrb3B0KHNvY2ssIFNPTF9IQ0ksIEhDSV9G
SUxURVIsICZmbHQsIHNpemVvZihmbHQpKSA8IDApIHsKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oHBlcnJvcigiQ2FuJ3Qgc2V0IEhDSSBmaWx0ZXIiKTsKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oHJldHVybjsKPiDCoCDCoCDCoCDCoH0KPgo+IMKgIMKgIMKgIMKgaWYgKGhjaV9zZW5kX2NtZChz
b2NrLCBPR0ZfSE9TVF9DVEwsIE9DRl9XUklURV9JTlFVSVJZX01PREUsCj4gV1JJVEVfSU5RVUlS
WV9NT0RFX1JQX1NJWkUsICZjcCkgPCAwKSB7CgpUYWtpbmcgYSBsb29rIGF0IHlvdXIgY29kZSwg
YSBmZXcgdGhpbmdzIGxvb2sgb3V0IG9mIHBsYWNlOiB5b3UgYXJlCnVzaW5nIGNwIHVuaW5pdGlh
bGl6ZWQsIGl0IGlzIGV4cGVjdGluZyBhIHdyaXRlX2lucXVpcnlfbW9kZV9jcCwgbm90IGEKaW5x
dWlyeV9jcCBhbmQgdGhlIHBsZW4gcGFyYW1ldGVyIHNlZW1zIHdyb25nLgoKRGVjbGFyaW5nIChv
ciBub3QpIHRoZSB2YXJpYWJsZSBpIGlzIG1lc3Npbmcgd2l0aCB0aGUgc3RhY2sgc3RhdGUgYW5k
CmFmZmVjdGluZyB0aGUgdmFsdWUgdGhhdCBnb2VzIGludG8gY3AuCgo+IMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgcGVycm9yKCJDYW4ndCBzZXQgaW5xdWlyeSBtb2RlIik7Cj4gwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqByZXR1cm47Cj4gwqAgwqAgwqAgwqB9Cj4KPiDCoCDCoCDCoCDCoG1lbXNldCAo
JmNwLCAwLCBzaXplb2YoY3ApKTsKPiDCoCDCoCDCoCDCoGNwLmxhcFsyXSA9IDB4OWU7Cj4gwqAg
wqAgwqAgwqBjcC5sYXBbMV0gPSAweDhiOwo+IMKgIMKgIMKgIMKgY3AubGFwWzBdID0gMHgzMzsK
PiDCoCDCoCDCoCDCoGNwLm51bV9yc3AgPSAwOwo+IMKgIMKgIMKgIMKgY3AubGVuZ3RoID0gMHgz
MDsKPgo+IMKgIMKgIMKgIMKgcHJpbnRmKCJTdGFydGluZyBpbnF1aXJ5IHdpdGggUlNTSS4uLlxu
Iik7Cj4KPiDCoCDCoCDCoCDCoGlmIChoY2lfc2VuZF9jbWQgKHNvY2ssIE9HRl9MSU5LX0NUTCwg
T0NGX0lOUVVJUlksIElOUVVJUllfQ1BfU0laRSwKPiAmY3ApIDwgMCkgewo+IMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgcGVycm9yKCJDYW4ndCBzdGFydCBpbnF1aXJ5Iik7Cj4gwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqByZXR1cm47Cj4gwqAgwqAgwqAgwqB9Cj4KPiDCoCDCoCDCoCDCoHAuZmQgPSBz
b2NrOwo+IMKgIMKgIMKgIMKgcC5ldmVudHMgPSBQT0xMSU4gfCBQT0xMRVJSIHwgUE9MTEhVUDsK
Pgo+IMKgIMKgIMKgIMKgd2hpbGUoIWNhbmNlbGVkKSB7Cj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqBwLnJldmVudHMgPSAwOwo+Cj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAvKiBwb2xsIHRoZSBC
VCBkZXZpY2UgZm9yIGFuIGV2ZW50ICovCj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBpZiAocG9s
bCgmcCwgMSwgLTEpID4gMCkgewo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
bGVuID0gcmVhZChzb2NrLCBidWYsIHNpemVvZihidWYpKTsKPgo+IMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgaWYgKGxlbiA8IDApCj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBjb250aW51ZTsKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoGVsc2UgaWYgKGxlbiA9PSAwKQo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgYnJlYWs7Cj4KPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoGhkciA9ICh2b2lkICopIChidWYgKyAxKTsKPiDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoHB0ciA9IGJ1ZiArICgxICsgSENJX0VWRU5UX0hEUl9TSVpFKTsK
Pgo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgcmVzdWx0cyA9IHB0clswXTsK
Pgo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgc3dpdGNoIChoZHItPmV2dCkg
ewo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgY2FzZSBF
VlRfSU5RVUlSWV9SRVNVTFQ6Cj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBmb3IgKGkgPSAwOyBpIDwgcmVzdWx0czsgaSsrKSB7Cj4g
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqBpbmZvID0gKHZvaWQgKilwdHIgKwo+IChzaXplb2YoKmluZm8pICogaSkg
KyAxOwo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgcHJpbnRfcmVzdWx0KCZpbmZvLT5iZGFkZHIsCj4gMCwgMCk7
Cj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqB9Cj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqBicmVhazsKPgo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgY2FzZSBFVlRfSU5RVUlSWV9SRVNVTFRfV0lUSF9SU1NJOgo+IMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgZm9yIChp
ID0gMDsgaSA8IHJlc3VsdHM7IGkrKykgewo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgaW5mb19yc3NpID0gKHZv
aWQgKilwdHIgKwo+IChzaXplb2YoKmluZm9fcnNzaSkgKiBpKSArIDE7Cj4KPiDCoHByaW50X3Jl
c3VsdCgmaW5mb19yc3NpLT5iZGFkZHIsIDEsIGluZm9fcnNzaS0+cnNzaSk7Cj4gwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqB9Cj4gwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBi
cmVhazsKPgo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
Y2FzZSBFVlRfSU5RVUlSWV9DT01QTEVURToKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGNhbmNlbGVkID0gMTsKPiDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGJyZWFrOwo+
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgfQo+IMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgfQo+IMKgIMKgIMKgIMKgfQo+IMKgIMKgIMKgIMKgY2xvc2Uoc29jayk7Cj4gfQo+Cj4g
aW50IG1haW4oaW50IGFyZ2MsIGNoYXIgKiphcmd2KQo+IHsKPiDCoCDCoCDCoCDCoC8vaW50IGk7
IC8qIGNhdXNlcyBpbnEuIHJlc3VsdCB0byBoYXZlIG5vIHJzc2kgdmFsdWUgKi8KPiDCoCDCoCDC
oCDCoHNjYW5uZXJfc3RhcnQoKTsKPiDCoCDCoCDCoCDCoHJldHVybiAwOwo+IH0KPiAtLQo+IFRv
IHVuc3Vic2NyaWJlIGZyb20gdGhpcyBsaXN0OiBzZW5kIHRoZSBsaW5lICJ1bnN1YnNjcmliZSBs
aW51eC1ibHVldG9vdGgiCj4gaW4KPiB0aGUgYm9keSBvZiBhIG1lc3NhZ2UgdG8gbWFqb3Jkb21v
QHZnZXIua2VybmVsLm9yZwo+IE1vcmUgbWFqb3Jkb21vIGluZm8gYXQgwqBodHRwOi8vdmdlci5r
ZXJuZWwub3JnL21ham9yZG9tby1pbmZvLmh0bWwKPgoKCkNoZWVycywKLS0gClZpbmljaXVzCg==
^ permalink raw reply
* How to close bluetooth? Using rfkill?
From: zhangfei gao @ 2011-01-21 5:51 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Johan Hedberg
Hi Johan,
Is there any general method to open/close bluetooth, using rfkill or
pm_runtime_get/put_* API.
Currently we use rfkill to close bluetooth, however we met dead lock
issue, for mutex_lock(&rfkill_global_mutex).
So we use workaround to rmmod bt.ko first, or revert the rfkill patch
in hci_core.c.
BT/WIFI device have chip select pin, we register one rfkill with
sd8x_set_block, and control chip select pin to open/close bt/wifi/fm.
for example:
rfkill unblock bluetooth to open bt
rfkill block bluetooth to close bt
When "rfkill block bluetooth",
rfkill_fop_write->mutex_lock(&rfkill_global_mutex)->rfkill_set_block->sd8x_set_block->waiting
for card is freed.
BT driver will call
hci_unregister_dev->rfkill_unregister->mutex_lock(&rfkill_global_mutex);
So mutex_lock(&rfkill_global_mutex) will be dead locked.
If so, do we have to use other method to control chip select pin to
control bt power, such as pm_runtime_get/put_* API.
Thanks in advance.
^ permalink raw reply
* Re: [PATCH] Fix duplicate characteristics
From: Johan Hedberg @ 2011-01-21 6:46 UTC (permalink / raw)
To: Bruna Moreira; +Cc: linux-bluetooth
In-Reply-To: <1295530067-6022-1-git-send-email-bruna.moreira@openbossa.org>
Hi Bruna,
On Thu, Jan 20, 2011, Bruna Moreira wrote:
> The Discover() operation (from DBus API) was registering the same
> characteristics after running several times. This can be checked using
> test-attrib.
> ---
> attrib/client.c | 7 +++++++
> 1 files changed, 7 insertions(+), 0 deletions(-)
Pushed upstream. Thanks.
Johan
^ permalink raw reply
* Re: [PATCH] Fix incoming attrib-server connection MTUs
From: Johan Hedberg @ 2011-01-21 6:50 UTC (permalink / raw)
To: Brian Gix; +Cc: linux-bluetooth, vinicius.gomes, claudio.takahasi, padovan
In-Reply-To: <1295550541-30535-2-git-send-email-bgix@codeaurora.org>
Hi Brian,
On Thu, Jan 20, 2011, Brian Gix wrote:
> It is important for the Attribute Server to be aware of and completely
> fill response packets up to the full MTU when reading long attributes.
> Some remote devices will only request additional (READ_BLOB) data if
> the preceding read sent the maximum amount of data.
>
> Incoming connections are identified as L2CAP or LE by pointers to the
> Service IO channel the incoming connection was recieved on in the
> user_data parameter. L2CAP channels are set to the BR/EDR minimum MTU
> of 48, and LE channels to the LE payload size of 23.
> ---
> attrib/att.h | 3 ++-
> attrib/gatt.c | 28 ++++++++++++++--------------
> src/attrib-server.c | 13 +++++++++----
> 3 files changed, 25 insertions(+), 19 deletions(-)
Thanks for the updated patch. It looks good now and has been pushed
upstream.
Johan
^ permalink raw reply
* Re: [PATCH] Partial implementation of LE events and commands dump.
From: Johan Hedberg @ 2011-01-21 6:55 UTC (permalink / raw)
To: André Dieb Martins; +Cc: linux-bluetooth
In-Reply-To: <1295551093-6718-1-git-send-email-andre.dieb@signove.com>
Hi André
On Thu, Jan 20, 2011, André Dieb Martins wrote:
> ---
> parser/hci.c | 226 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> 1 files changed, 226 insertions(+), 0 deletions(-)
The patch has been pushed upstream. Thanks.
Johan
^ permalink raw reply
* Re: [PATCH] Fix uninitialized struct sockaddr_hci memory passed to bind()
From: Johan Hedberg @ 2011-01-21 6:56 UTC (permalink / raw)
To: Anderson Lizardo; +Cc: linux-bluetooth
In-Reply-To: <1295557368-9737-1-git-send-email-anderson.lizardo@openbossa.org>
Hi,
On Thu, Jan 20, 2011, Anderson Lizardo wrote:
> The bind() call in open_socket() was passing a struct sockaddr_hci to
> bind() with two uninitialized bytes. This caused "Invalid argument" errors
> on kernels which do strict checks of struct sockaddr_hci fields.
> ---
> src/hcidump.c | 1 +
> 1 files changed, 1 insertions(+), 0 deletions(-)
Pushed upstream. Thanks.
Johan
^ permalink raw reply
* Re: Problem with inquiry result with rssi
From: Ulrich Bürgi @ 2011-01-21 9:14 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <AANLkTinWBAvaFv-nS7gPvfGzWyC8S3vzm_BpfKo3qWhb@mail.gmail.com>
Hi Vinicius,
>> if (hci_send_cmd(sock, OGF_HOST_CTL, OCF_WRITE_INQUIRY_MODE,
>> WRITE_INQUIRY_MODE_RP_SIZE,&cp)< 0) {
>
> Taking a look at your code, a few things look out of place: you are
> using cp uninitialized, it is expecting a write_inquiry_mode_cp, not a
> inquiry_cp and the plen parameter seems wrong.
Silly me! How could I have missed this?
Well, now I use write_inquiry_mode_cp with a mode set to 0x01 and the
proper plen.
Everything works as expected!
Thank you very much for the quick help!
Ulrich
^ permalink raw reply
* [PATCH 1/7] Create a file to hold the generic code from gatttool
From: Sheldon Demario @ 2011-01-21 13:46 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Sheldon Demario
We need a interactive tool that should be similar to gatttool in
features. So we can share some code between them.
---
Makefile.am | 3 +-
attrib/gatttool.c | 85 +----------------------------------
attrib/gtcommon.c | 130 +++++++++++++++++++++++++++++++++++++++++++++++++++++
attrib/gtcommon.h | 45 ++++++++++++++++++
4 files changed, 178 insertions(+), 85 deletions(-)
create mode 100644 attrib/gtcommon.c
create mode 100644 attrib/gtcommon.h
diff --git a/Makefile.am b/Makefile.am
index 5f96975..5274435 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -179,7 +179,8 @@ 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
+ src/glib-helper.h src/glib-helper.c \
+ attrib/gtcommon.h attrib/gtcommon.c
attrib_gatttool_LDADD = lib/libbluetooth.la @GLIB_LIBS@
builtin_modules += attrib
diff --git a/attrib/gatttool.c b/attrib/gatttool.c
index 8e8ed8e..e5ebad1 100644
--- a/attrib/gatttool.c
+++ b/attrib/gatttool.c
@@ -42,27 +42,11 @@
#include "gattrib.h"
#include "glib-helper.h"
#include "gatt.h"
+#include "gtcommon.h"
/* Minimum MTU for L2CAP connections over BR/EDR */
#define ATT_MIN_MTU_L2CAP 48
-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 int opt_start = 0x0001;
-static int opt_end = 0xffff;
-static int opt_handle = -1;
-static int opt_mtu = 0;
-static int opt_psm = 0x1f;
-static gboolean opt_primary = FALSE;
-static gboolean opt_characteristics = FALSE;
-static gboolean opt_char_read = FALSE;
-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 got_error = FALSE;
@@ -487,73 +471,6 @@ static gboolean characteristics_desc(gpointer user_data)
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 GOptionEntry primary_char_options[] = {
- { "start", 's' , 0, G_OPTION_ARG_INT, &opt_start,
- "Starting handle(optional)", "0x0001" },
- { "end", 'e' , 0, G_OPTION_ARG_INT, &opt_end,
- "Ending handle(optional)", "0xffff" },
- { "uuid", 'u', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK,
- parse_uuid, "UUID16 or UUID128(optional)", "0x1801"},
- { NULL },
-};
-
-static GOptionEntry char_rw_options[] = {
- { "handle", 'a' , 0, G_OPTION_ARG_INT, &opt_handle,
- "Read/Write characteristic by handle(required)", "0x0001" },
- { "value", 'n' , 0, G_OPTION_ARG_STRING, &opt_value,
- "Write characteristic value (required for write operation)",
- "0x0001" },
- {NULL},
-};
-
-static GOptionEntry gatt_options[] = {
- { "primary", 0, 0, G_OPTION_ARG_NONE, &opt_primary,
- "Primary Service Discovery", NULL },
- { "characteristics", 0, 0, G_OPTION_ARG_NONE, &opt_characteristics,
- "Characteristics Discovery", NULL },
- { "char-read", 0, 0, G_OPTION_ARG_NONE, &opt_char_read,
- "Characteristics Value/Descriptor Read", NULL },
- { "char-write", 0, 0, G_OPTION_ARG_NONE, &opt_char_write,
- "Characteristics Value Write", NULL },
- { "char-desc", 0, 0, G_OPTION_ARG_NONE, &opt_char_desc,
- "Characteristics Descriptor Discovery", NULL },
- { "listen", 0, 0, G_OPTION_ARG_NONE, &opt_listen,
- "Listen for notifications and indications", NULL },
- { "le", 0, 0, G_OPTION_ARG_NONE, &opt_le,
- "Use Bluetooth Low Energy transport", NULL },
- { NULL },
-};
-
-static GOptionEntry options[] = {
- { "adapter", 'i', 0, G_OPTION_ARG_STRING, &opt_src,
- "Specify local adapter interface", "hciX" },
- { "device", 'b', 0, G_OPTION_ARG_STRING, &opt_dst,
- "Specify remote Bluetooth address", "MAC" },
- { "mtu", 'm', 0, G_OPTION_ARG_INT, &opt_mtu,
- "Specify the MTU size", "MTU" },
- { "psm", 'p', 0, G_OPTION_ARG_INT, &opt_psm,
- "Specify the PSM for GATT/ATT over BR/EDR", "PSM" },
- { "sec-level", 'l', 0, G_OPTION_ARG_STRING, &opt_sec_level,
- "Set security level. Default: low", "[low | medium | high]"},
- { NULL },
-};
-
int main(int argc, char *argv[])
{
GOptionContext *context;
diff --git a/attrib/gtcommon.c b/attrib/gtcommon.c
new file mode 100644
index 0000000..ebf47e9
--- /dev/null
+++ b/attrib/gtcommon.c
@@ -0,0 +1,130 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2011 Nokia Corporation
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include <errno.h>
+#include <glib.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <unistd.h>
+
+#include <bluetooth/bluetooth.h>
+#include <bluetooth/hci.h>
+#include <bluetooth/hci_lib.h>
+#include <bluetooth/sdp.h>
+#include <bluetooth/sdp_lib.h>
+
+#include "att.h"
+#include "btio.h"
+#include "gattrib.h"
+#include "glib-helper.h"
+#include "gatt.h"
+
+#include "gtcommon.h"
+
+gchar *opt_src = NULL;
+gchar *opt_dst = NULL;
+gchar *opt_value = NULL;
+gchar *opt_sec_level = "low";
+uuid_t *opt_uuid;
+int opt_start = 0x0001;
+int opt_end = 0xffff;
+int opt_handle = -1;
+int opt_mtu = 0;
+int opt_psm = 0x1f;
+gboolean opt_primary = FALSE;
+gboolean opt_characteristics = FALSE;
+gboolean opt_char_read = FALSE;
+gboolean opt_listen = FALSE;
+gboolean opt_char_desc = FALSE;
+gboolean opt_le = FALSE;
+gboolean opt_char_write = FALSE;
+
+static gboolean parse_uuid(const char *key, const char *value,
+ gpointer user_data, GError **gerr)
+{
+ 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) {
+ g_free(opt_uuid);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+GOptionEntry primary_char_options[] = {
+ { "start", 's' , 0, G_OPTION_ARG_INT, &opt_start,
+ "Starting handle(optional)", "0x0001" },
+ { "end", 'e' , 0, G_OPTION_ARG_INT, &opt_end,
+ "Ending handle(optional)", "0xffff" },
+ { "uuid", 'u', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK,
+ parse_uuid, "UUID16 or UUID128(optional)", "0x1801"},
+ { NULL },
+};
+
+GOptionEntry char_rw_options[] = {
+ { "handle", 'a' , 0, G_OPTION_ARG_INT, &opt_handle,
+ "Read/Write characteristic by handle(required)", "0x0001" },
+ { "value", 'n' , 0, G_OPTION_ARG_STRING, &opt_value,
+ "Write characteristic value (required for write operation)",
+ "0x0001" },
+ {NULL},
+};
+
+GOptionEntry gatt_options[] = {
+ { "primary", 0, 0, G_OPTION_ARG_NONE, &opt_primary,
+ "Primary Service Discovery", NULL },
+ { "characteristics", 0, 0, G_OPTION_ARG_NONE, &opt_characteristics,
+ "Characteristics Discovery", NULL },
+ { "char-read", 0, 0, G_OPTION_ARG_NONE, &opt_char_read,
+ "Characteristics Value/Descriptor Read", NULL },
+ { "char-write", 0, 0, G_OPTION_ARG_NONE, &opt_char_write,
+ "Characteristics Value Write", NULL },
+ { "char-desc", 0, 0, G_OPTION_ARG_NONE, &opt_char_desc,
+ "Characteristics Descriptor Discovery", NULL },
+ { "listen", 0, 0, G_OPTION_ARG_NONE, &opt_listen,
+ "Listen for notifications and indications", NULL },
+ { "le", 0, 0, G_OPTION_ARG_NONE, &opt_le,
+ "Use Bluetooth Low Energy transport", NULL },
+ { NULL },
+};
+
+GOptionEntry options[] = {
+ { "adapter", 'i', 0, G_OPTION_ARG_STRING, &opt_src,
+ "Specify local adapter interface", "hciX" },
+ { "device", 'b', 0, G_OPTION_ARG_STRING, &opt_dst,
+ "Specify remote Bluetooth address", "MAC" },
+ { "mtu", 'm', 0, G_OPTION_ARG_INT, &opt_mtu,
+ "Specify the MTU size", "MTU" },
+ { "psm", 'p', 0, G_OPTION_ARG_INT, &opt_psm,
+ "Specify the PSM for GATT/ATT over BR/EDR", "PSM" },
+ { "sec-level", 'l', 0, G_OPTION_ARG_STRING, &opt_sec_level,
+ "Set security level. Default: low", "[low | medium | high]"},
+ { NULL },
+};
+
diff --git a/attrib/gtcommon.h b/attrib/gtcommon.h
new file mode 100644
index 0000000..30e8e37
--- /dev/null
+++ b/attrib/gtcommon.h
@@ -0,0 +1,45 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2011 Nokia Corporation
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+extern gchar *opt_src;
+extern gchar *opt_dst;
+extern gchar *opt_value;
+extern gchar *opt_sec_level;
+extern uuid_t *opt_uuid;
+extern int opt_start;
+extern int opt_end;
+extern int opt_handle;
+extern int opt_mtu;
+extern int opt_psm;
+extern gboolean opt_primary;
+extern gboolean opt_characteristics;
+extern gboolean opt_char_read;
+extern gboolean opt_listen;
+extern gboolean opt_char_desc;
+extern gboolean opt_le;
+extern gboolean opt_char_write;
+
+extern GOptionEntry primary_char_options[];
+extern GOptionEntry char_rw_options[];
+extern GOptionEntry gatt_options[];
+extern GOptionEntry options[];
--
1.7.1
^ permalink raw reply related
* [PATCH 2/7] Move do_connect from gatttool to gtcommon
From: Sheldon Demario @ 2011-01-21 13:46 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Sheldon Demario
In-Reply-To: <1295617586-3398-1-git-send-email-sheldon.demario@openbossa.org>
---
attrib/gatttool.c | 70 +----------------------------------------------------
attrib/gtcommon.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++
attrib/gtcommon.h | 5 ++++
3 files changed, 69 insertions(+), 69 deletions(-)
diff --git a/attrib/gatttool.c b/attrib/gatttool.c
index e5ebad1..e87ff0c 100644
--- a/attrib/gatttool.c
+++ b/attrib/gatttool.c
@@ -40,13 +40,9 @@
#include "att.h"
#include "btio.h"
#include "gattrib.h"
-#include "glib-helper.h"
#include "gatt.h"
#include "gtcommon.h"
-/* Minimum MTU for L2CAP connections over BR/EDR */
-#define ATT_MIN_MTU_L2CAP 48
-
static GMainLoop *event_loop;
static gboolean got_error = FALSE;
@@ -65,70 +61,6 @@ static void connect_cb(GIOChannel *io, GError *err, gpointer user_data)
}
}
-static GIOChannel *do_connect(gboolean le)
-{
- GIOChannel *chan;
- bdaddr_t sba, dba;
- GError *err = NULL;
- BtIOSecLevel sec_level;
-
- /* This check is required because currently setsockopt() returns no
- * errors for MTU values smaller than the allowed minimum. */
- if (opt_mtu != 0 && opt_mtu < ATT_MIN_MTU_L2CAP) {
- g_printerr("MTU cannot be smaller than %d\n",
- ATT_MIN_MTU_L2CAP);
- return NULL;
- }
-
- /* Remote device */
- if (opt_dst == NULL) {
- g_printerr("Remote Bluetooth address required\n");
- return NULL;
- }
- str2ba(opt_dst, &dba);
-
- /* Local adapter */
- if (opt_src != NULL) {
- if (!strncmp(opt_src, "hci", 3))
- hci_devba(atoi(opt_src + 3), &sba);
- else
- str2ba(opt_src, &sba);
- } else
- bacpy(&sba, BDADDR_ANY);
-
- if (strcmp(opt_sec_level, "medium") == 0)
- sec_level = BT_IO_SEC_MEDIUM;
- else if (strcmp(opt_sec_level, "high") == 0)
- sec_level = BT_IO_SEC_HIGH;
- else
- sec_level = BT_IO_SEC_LOW;
-
- if (le)
- chan = bt_io_connect(BT_IO_L2CAP, connect_cb, NULL, NULL, &err,
- BT_IO_OPT_SOURCE_BDADDR, &sba,
- BT_IO_OPT_DEST_BDADDR, &dba,
- BT_IO_OPT_CID, GATT_CID,
- BT_IO_OPT_OMTU, opt_mtu,
- BT_IO_OPT_SEC_LEVEL, sec_level,
- BT_IO_OPT_INVALID);
- else
- chan = bt_io_connect(BT_IO_L2CAP, connect_cb, NULL, NULL, &err,
- BT_IO_OPT_SOURCE_BDADDR, &sba,
- BT_IO_OPT_DEST_BDADDR, &dba,
- BT_IO_OPT_PSM, opt_psm,
- BT_IO_OPT_OMTU, opt_mtu,
- BT_IO_OPT_SEC_LEVEL, sec_level,
- BT_IO_OPT_INVALID);
-
- if (err) {
- g_printerr("%s\n", err->message);
- g_error_free(err);
- return NULL;
- }
-
- return chan;
-}
-
static void primary_all_cb(GSList *services, guint8 status, gpointer user_data)
{
GSList *l;
@@ -529,7 +461,7 @@ int main(int argc, char *argv[])
goto done;
}
- chan = do_connect(opt_le);
+ chan = do_connect(opt_le, opt_dst, connect_cb);
if (chan == NULL) {
got_error = TRUE;
goto done;
diff --git a/attrib/gtcommon.c b/attrib/gtcommon.c
index ebf47e9..0759990 100644
--- a/attrib/gtcommon.c
+++ b/attrib/gtcommon.c
@@ -128,3 +128,66 @@ GOptionEntry options[] = {
{ NULL },
};
+GIOChannel *do_connect(gboolean le, gchar *dest, BtIOConnect connect_cb)
+{
+ GIOChannel *chan;
+ bdaddr_t sba, dba;
+ GError *err = NULL;
+ BtIOSecLevel sec_level;
+
+ /* This check is required because currently setsockopt() returns no
+ * errors for MTU values smaller than the allowed minimum. */
+ if (opt_mtu != 0 && opt_mtu < ATT_MIN_MTU_L2CAP) {
+ g_printerr("MTU cannot be smaller than %d\n",
+ ATT_MIN_MTU_L2CAP);
+ return NULL;
+ }
+
+ /* Remote device */
+ if (dest == NULL) {
+ g_printerr("Remote Bluetooth address required\n");
+ return NULL;
+ }
+ str2ba(dest, &dba);
+
+ /* Local adapter */
+ if (opt_src != NULL) {
+ if (!strncmp(opt_src, "hci", 3))
+ hci_devba(atoi(opt_src + 3), &sba);
+ else
+ str2ba(opt_src, &sba);
+ } else
+ bacpy(&sba, BDADDR_ANY);
+
+ if (strcmp(opt_sec_level, "medium") == 0)
+ sec_level = BT_IO_SEC_MEDIUM;
+ else if (strcmp(opt_sec_level, "high") == 0)
+ sec_level = BT_IO_SEC_HIGH;
+ else
+ sec_level = BT_IO_SEC_LOW;
+
+ if (le)
+ chan = bt_io_connect(BT_IO_L2CAP, connect_cb, NULL, NULL, &err,
+ BT_IO_OPT_SOURCE_BDADDR, &sba,
+ BT_IO_OPT_DEST_BDADDR, &dba,
+ BT_IO_OPT_CID, GATT_CID,
+ BT_IO_OPT_OMTU, opt_mtu,
+ BT_IO_OPT_SEC_LEVEL, sec_level,
+ BT_IO_OPT_INVALID);
+ else
+ chan = bt_io_connect(BT_IO_L2CAP, connect_cb, NULL, NULL, &err,
+ BT_IO_OPT_SOURCE_BDADDR, &sba,
+ BT_IO_OPT_DEST_BDADDR, &dba,
+ BT_IO_OPT_PSM, opt_psm,
+ BT_IO_OPT_OMTU, opt_mtu,
+ BT_IO_OPT_SEC_LEVEL, sec_level,
+ BT_IO_OPT_INVALID);
+
+ if (err) {
+ g_printerr("%s\n", err->message);
+ g_error_free(err);
+ return NULL;
+ }
+
+ return chan;
+}
diff --git a/attrib/gtcommon.h b/attrib/gtcommon.h
index 30e8e37..ead2f5b 100644
--- a/attrib/gtcommon.h
+++ b/attrib/gtcommon.h
@@ -21,6 +21,9 @@
*
*/
+/* Minimum MTU for L2CAP connections over BR/EDR */
+#define ATT_MIN_MTU_L2CAP 48
+
extern gchar *opt_src;
extern gchar *opt_dst;
extern gchar *opt_value;
@@ -39,6 +42,8 @@ extern gboolean opt_char_desc;
extern gboolean opt_le;
extern gboolean opt_char_write;
+GIOChannel *do_connect(gboolean le, gchar *dest, BtIOConnect connect_db);
+
extern GOptionEntry primary_char_options[];
extern GOptionEntry char_rw_options[];
extern GOptionEntry gatt_options[];
--
1.7.1
^ permalink raw reply related
* [PATCH 3/7] Initial version of igatttool - a interactive gatttool
From: Sheldon Demario @ 2011-01-21 13:46 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Sheldon Demario
In-Reply-To: <1295617586-3398-1-git-send-email-sheldon.demario@openbossa.org>
Due the qualification tests, we need a deeper control over the
gatttool's steps.
---
Makefile.am | 7 ++-
attrib/igatttool.c | 225 ++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 231 insertions(+), 1 deletions(-)
create mode 100644 attrib/igatttool.c
diff --git a/Makefile.am b/Makefile.am
index 5274435..79365ad 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -175,7 +175,7 @@ builtin_sources += plugins/service.c
endif
if ATTRIBPLUGIN
-bin_PROGRAMS += attrib/gatttool
+bin_PROGRAMS += attrib/gatttool attrib/igatttool
attrib_gatttool_SOURCES = attrib/gatttool.c attrib/att.c attrib/gatt.c \
attrib/gattrib.c btio/btio.c \
@@ -183,6 +183,11 @@ attrib_gatttool_SOURCES = attrib/gatttool.c attrib/att.c attrib/gatt.c \
attrib/gtcommon.h attrib/gtcommon.c
attrib_gatttool_LDADD = lib/libbluetooth.la @GLIB_LIBS@
+attrib_igatttool_SOURCES = attrib/igatttool.c btio/btio.c \
+ attrib/gtcommon.h attrib/gtcommon.c \
+ src/glib-helper.h src/glib-helper.c
+attrib_igatttool_LDADD = lib/libbluetooth.la @GLIB_LIBS@ -lreadline
+
builtin_modules += attrib
builtin_sources += attrib/main.c \
attrib/manager.h attrib/manager.c \
diff --git a/attrib/igatttool.c b/attrib/igatttool.c
new file mode 100644
index 0000000..9cd2a1e
--- /dev/null
+++ b/attrib/igatttool.c
@@ -0,0 +1,225 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2011 Nokia Corporation
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <readline/readline.h>
+#include <readline/history.h>
+#include <glib.h>
+
+#include <bluetooth/bluetooth.h>
+#include <bluetooth/hci.h>
+#include <bluetooth/sdp.h>
+
+#include "btio.h"
+
+#include "gtcommon.h"
+
+GIOChannel *iochannel = NULL;
+GMainLoop *main_loop = NULL;
+gboolean status = FALSE;
+GString *prompt = NULL;
+
+enum state {
+ STATE_DISCONNECTED,
+ STATE_CONNECTING,
+ STATE_CONNECTED
+} conn_state;
+
+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 show_message(const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+
+ vprintf(format, ap);
+
+ va_end(ap);
+
+ rl_redisplay();
+}
+
+static void set_state(enum state st)
+{
+ conn_state = st;
+ rl_set_prompt(get_prompt());
+ rl_redisplay();
+}
+
+static void connect_cb(GIOChannel *io, GError *gerr, gpointer user_data)
+{
+ if (gerr) {
+ show_message("connect error: %s\n", gerr->message);
+ set_state(STATE_DISCONNECTED);
+ return;
+ }
+
+ set_state(STATE_CONNECTED);
+}
+
+static void cmd_connect(char **cmd)
+{
+ if (conn_state != STATE_DISCONNECTED)
+ return;
+
+ if (cmd[1] != NULL) {
+ g_free(opt_dst);
+ opt_dst = strdup(cmd[1]);
+ }
+
+ if (opt_dst == NULL) {
+ show_message("Remote Bluetooth address required\n");
+ return;
+ }
+
+ set_state(STATE_CONNECTING);
+ iochannel = do_connect(opt_le, opt_dst, connect_cb);
+ if (iochannel == NULL)
+ set_state(STATE_DISCONNECTED);
+}
+
+static void cmd_disconnect(char **cmd)
+{
+ if (conn_state == STATE_DISCONNECTED)
+ return;
+
+ g_io_channel_shutdown(iochannel, FALSE, NULL);
+ g_io_channel_unref(iochannel);
+ iochannel = NULL;
+
+ set_state(STATE_DISCONNECTED);
+}
+
+static void cmd_exit(char **cmd)
+{
+ g_main_loop_quit(main_loop);
+}
+
+static struct {
+ char *cmd;
+ void (*func)(char **cmd);
+ char *param;
+ char *desc;
+} commands[] = {
+ { "connect", cmd_connect, "<bdaddr>", "Connect"},
+ { "disconnect", cmd_disconnect, NULL, "Disconnect"},
+ { "exit", cmd_exit, NULL, "Exit"},
+ { 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;
+}
+
+int main(int argc, char *argv[])
+{
+ GOptionContext *context;
+ GIOChannel *pchan;
+ GError *gerr;
+ gint events;
+
+ context = g_option_context_new(NULL);
+ g_option_context_add_main_entries(context, options, NULL);
+
+ if (g_option_context_parse(context, &argc, &argv, &gerr) == FALSE) {
+ g_printerr("%s\n", gerr->message);
+ g_error_free(gerr);
+ exit(1);
+ }
+
+ main_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(main_loop);
+
+ cmd_disconnect(NULL);
+ rl_callback_handler_remove();
+ g_io_channel_unref(pchan);
+ g_main_loop_unref(main_loop);
+ g_option_context_free(context);
+
+ return 0;
+}
--
1.7.1
^ permalink raw reply related
* [PATCH 4/7] Add psm option to interactive gatttool
From: Sheldon Demario @ 2011-01-21 13:46 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Sheldon Demario
In-Reply-To: <1295617586-3398-1-git-send-email-sheldon.demario@openbossa.org>
---
attrib/igatttool.c | 13 +++++++++++++
1 files changed, 13 insertions(+), 0 deletions(-)
diff --git a/attrib/igatttool.c b/attrib/igatttool.c
index 9cd2a1e..29290ed 100644
--- a/attrib/igatttool.c
+++ b/attrib/igatttool.c
@@ -137,6 +137,18 @@ static void cmd_exit(char **cmd)
g_main_loop_quit(main_loop);
}
+static void cmd_psm(char **opt)
+{
+ if (opt[1] == NULL)
+ return;
+
+ if (conn_state == STATE_DISCONNECTED || opt[1] != NULL)
+ opt_psm = atoi(opt[1]);
+
+ rl_set_prompt(get_prompt());
+ rl_redisplay();
+}
+
static struct {
char *cmd;
void (*func)(char **cmd);
@@ -146,6 +158,7 @@ static struct {
{ "connect", cmd_connect, "<bdaddr>", "Connect"},
{ "disconnect", cmd_disconnect, NULL, "Disconnect"},
{ "exit", cmd_exit, NULL, "Exit"},
+ { "psm", cmd_psm, "<psm>", "Set psm"},
{ NULL, NULL, NULL, NULL}
};
--
1.7.1
^ permalink raw reply related
* [PATCH 5/7] Add transport option to interactive gatttool
From: Sheldon Demario @ 2011-01-21 13:46 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Sheldon Demario
In-Reply-To: <1295617586-3398-1-git-send-email-sheldon.demario@openbossa.org>
---
attrib/igatttool.c | 18 ++++++++++++++++++
1 files changed, 18 insertions(+), 0 deletions(-)
diff --git a/attrib/igatttool.c b/attrib/igatttool.c
index 29290ed..e0d8b44 100644
--- a/attrib/igatttool.c
+++ b/attrib/igatttool.c
@@ -137,6 +137,23 @@ static void cmd_exit(char **cmd)
g_main_loop_quit(main_loop);
}
+static void cmd_transport(char **cmd)
+{
+ if (cmd[1] == NULL)
+ return;
+
+ if (conn_state != STATE_DISCONNECTED)
+ return;
+
+ if (strcasecmp(cmd[1], "le") == 0)
+ opt_le = TRUE;
+ else if (strcasecmp(cmd[1], "br") == 0)
+ opt_le = FALSE;
+
+ rl_set_prompt(get_prompt());
+ rl_redisplay();
+}
+
static void cmd_psm(char **opt)
{
if (opt[1] == NULL)
@@ -158,6 +175,7 @@ static struct {
{ "connect", cmd_connect, "<bdaddr>", "Connect"},
{ "disconnect", cmd_disconnect, NULL, "Disconnect"},
{ "exit", cmd_exit, NULL, "Exit"},
+ { "transport", cmd_transport, "<LE | BR>", "Set transport"},
{ "psm", cmd_psm, "<psm>", "Set psm"},
{ NULL, NULL, NULL, NULL}
};
--
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