Linux bluetooth development
 help / color / mirror / Atom feed
* Re: [PATCH 7/7] Add /hfp/test_hfp_gw_register_3 and /hfp/test_hfp_gw_register_4
From: Marcel Holtmann @ 2014-03-04  8:51 UTC (permalink / raw)
  To: Marcin Kraglak; +Cc: linux-bluetooth@vger.kernel.org development
In-Reply-To: <CABD6X-+-pUjd36JQ_wb+LKQWimB4_TwL+aqk7koZkiLz_k5FaA@mail.gmail.com>

Hi Marcin,

>>> unit/test-hfp.c | 31 +++++++++++++++++++++++++++++++
>>> 1 file changed, 31 insertions(+)
>>> 
>>> diff --git a/unit/test-hfp.c b/unit/test-hfp.c
>>> index 5e4fc11..64ecc60 100644
>>> --- a/unit/test-hfp.c
>>> +++ b/unit/test-hfp.c
>>> @@ -266,6 +266,33 @@ static const struct test_data test_register_2 = {
>>>      .prefix = prefix_brsf
>>> };
>>> 
>>> +static const char atbrsf_read[] = {'A', 'T', '+', 'B', 'R', 'S', 'F', '?',
>>> +                                                                     '\r'};
>>> +
>> 
>>        = "AT+BRSF?\r";
>> 
>>> +static const struct test_data test_register_3 = {
>>> +     .command_cb = cmd_handler,
>>> +     .server_send = atbrsf_read,
>>> +     .data_len = sizeof(atbrsf_read),
>>> +     .expected_rsp = err_rsp,
>>> +     .expected_rsp_len = sizeof(err_rsp),
>>> +     .result_cb = prefix_handler,
>>> +     .expected_cmd_type = HFP_GW_CMD_TYPE_READ,
>>> +     .prefix = prefix_brsf
>>> +};
>>> +
>>> +static const char prefix_d[] = "D";
>> 
>> I wonder why here it is acceptable and above you are making the huge effort to give every character separately.
> 
> I thought it will be more readable if raw data passed to socket will
> be declared as array, not string. Prefixes are passed as strings,
> because they are used in hfp_gw_register()  Anyway Luiz suggested to
> use common framework for this test like raw_pdu(args...) ,
> define_test(name, function, args...), (it is used in test-avctp and
> test-avrcp). Will it look better for you?

besides the ending \0, what is actually the difference? It is just wasted effort to put in strings in array from. Just call strlen() instead of sizeof() and you have what you need.

The raw_pdu approach might actually work nicely. Since what you really want is to send an AT command and get the right response back from the gateway. In that sense it is similar to what we do for SDP and AVRCP. Of course you need to have also a preamble for the whole SLC setup. And in addition you want to test the stream handling by for example sending an AT command one byte at a time.

Regards

Marcel


^ permalink raw reply

* Re: [PATCH] Bluetooth:  Stop BCSP/H5 timer before cleaning up
From: Michael Knudsen @ 2014-03-04  8:19 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <20140304071456.GA30165@localhost.P-661HNU-F1>

On 03/04/2014 08:14 AM, Johan Hedberg wrote:
>>> When stopping BCSP/H5, stop the retransmission timer before proceeding
>>> to clean up packet queues.  The previous code had a race condition where
>>> the timer could trigger after the packet lists and protocol structure
>>> had been removed which lead to dereferencing NULL or use-after-free bugs.
>>
>> No interest?
>
> I was just discussing this yesterday with Marcel (that we seem to have
> forgotten about this patch). The only concern is whether it's safe to
> sleep in the *_close callbacks (since you use del_timer_sync). Have you
> verified that this doesn't cause any issues?

Our internal testing was reliably triggering the crash before and
has been stable since our fix went into local trees.  I expected
sleeping to be fine since the path is in process context, and I
found that slip uses the same approach:

	drivers/net/slip/slip.c:slip_close()

I think I saw other line disciplines that did the same but I don't
recall which ones.

Btw. if this is committed, there is a small typo in the message I
used:  Instead of ``lead'' it should be ``led''.

-m.

^ permalink raw reply

* Re: [PATCH BlueZ 03/16] android/avrcp-lib: Rework handler callback parameters
From: Andrei Emeltchenko @ 2014-03-04  8:05 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <CABBYNZ+2AasvfUbm8US6izAR8O1Vv91rLXb2a4R3kuM-PEUF4g@mail.gmail.com>

Hi Luiz,

On Mon, Mar 03, 2014 at 02:41:19PM +0200, Luiz Augusto von Dentz wrote:
> Hi Andrei,
> 
> On Mon, Mar 3, 2014 at 11:52 AM, Andrei Emeltchenko
> <andrei.emeltchenko.news@gmail.com> wrote:
> > Hi Luiz,
> >
> > On Sun, Mar 02, 2014 at 08:48:18PM +0200, Luiz Augusto von Dentz wrote:
> >> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
> >>
> >> This rework handler callback parameters to make it able to return
> >> proper error such as -EAGAIN to implement asynchronous responses.
> >> ---
> >>  android/avrcp-lib.c | 12 +++++++++---
> >>  android/avrcp-lib.h |  5 +++--
> >>  unit/test-avrcp.c   | 42 +++++++++++++++++++++---------------------
> >>  3 files changed, 33 insertions(+), 26 deletions(-)
> >>
> >> diff --git a/android/avrcp-lib.c b/android/avrcp-lib.c
> >> index cdad6ac..339be16 100644
> >> --- a/android/avrcp-lib.c
> >> +++ b/android/avrcp-lib.c
> >> @@ -125,6 +125,7 @@ static ssize_t handle_vendordep_pdu(struct avctp *conn, uint8_t transaction,
> >>       struct avrcp_header *pdu = (void *) operands;
> >>       uint32_t company_id = ntoh24(pdu->company_id);
> >>       uint16_t params_len = ntohs(pdu->params_len);
> >> +     ssize_t ret;
> >>
> >>       if (company_id != IEEEID_BTSIG) {
> >>               *code = AVC_CTYPE_NOT_IMPLEMENTED;
> >> @@ -159,12 +160,17 @@ static ssize_t handle_vendordep_pdu(struct avctp *conn, uint8_t transaction,
> >>               goto reject;
> >>       }
> >>
> >> -     *code = handler->func(session, transaction, &params_len,
> >> +     ret = handler->func(session, transaction, code, params_len,
> >>                                       pdu->params, session->control_data);
> >> +     if (ret < 0) {
> >> +             if (ret == -EAGAIN)
> >> +                     return ret;
> >> +             goto reject;
> >> +     }
> >>
> >> -     pdu->params_len = htons(params_len);
> >> +     pdu->params_len = htons(ret);
> >>
> >> -     return AVRCP_HEADER_LENGTH + params_len;
> >> +     return AVRCP_HEADER_LENGTH + ret;
> >>
> >>  reject:
> >>       pdu->params_len = htons(1);
> >> diff --git a/android/avrcp-lib.h b/android/avrcp-lib.h
> >> index a33bdfe..d7a805b 100644
> >> --- a/android/avrcp-lib.h
> >> +++ b/android/avrcp-lib.h
> >> @@ -79,8 +79,9 @@ struct avrcp;
> >>  struct avrcp_control_handler {
> >>       uint8_t id;
> >>       uint8_t code;
> >> -     uint8_t (*func) (struct avrcp *session, uint8_t transaction,
> >> -                     uint16_t *params_len, uint8_t *params, void *user_data);
> >> +     ssize_t (*func) (struct avrcp *session, uint8_t transaction,
> >> +                     uint8_t *code, uint16_t params_len, uint8_t *params,
> >> +                     void *user_data);
> >>  };
> >>
> >>  struct avrcp_passthrough_handler {
> >> diff --git a/unit/test-avrcp.c b/unit/test-avrcp.c
> >> index 302c331..2d5711b 100644
> >> --- a/unit/test-avrcp.c
> >> +++ b/unit/test-avrcp.c
> >> @@ -292,54 +292,54 @@ static const struct avrcp_passthrough_handler passthrough_handlers[] = {
> >>               { },
> >>  };
> >>
> >> -static uint8_t avrcp_handle_get_capabilities(struct avrcp *session,
> >> -                             uint8_t transaction, uint16_t *params_len,
> >> -                             uint8_t *params, void *user_data)
> >> +static ssize_t avrcp_handle_get_capabilities(struct avrcp *session,
> >> +                                     uint8_t transaction, uint8_t *code,
> >> +                                     uint16_t params_len, uint8_t *params,
> >> +                                     void *user_data)
> >>  {
> >>       uint32_t id = 0x001958;
> >>
> >> -     DBG("params[0] %d params_len %d", params[0], *params_len);
> >> -
> >> -     if (*params_len != 1)
> >> +     if (params_len != 1)
> >>               goto fail;
> >>
> >>       switch (params[0]) {
> >>       case CAP_COMPANY_ID:
> >> -             *params_len = 5;
> >>               params[1] = 1;
> >>               hton24(&params[2], id);
> >> -             return AVC_CTYPE_STABLE;
> >> +             *code = AVC_CTYPE_STABLE;
> >> +             return 5;
> >
> > What is 5? Shall we define constants or use formulas?
> 
> This is the param length, ideally we should define structs for all the
> PDUs.

I do agree here, currently the pointer magic generates warnings from
static analyzers so they are not useful much.

Best regards 
Andrei Emeltchenko 


^ permalink raw reply

* Re: [PATCH 7/7] Add /hfp/test_hfp_gw_register_3 and /hfp/test_hfp_gw_register_4
From: Marcin Kraglak @ 2014-03-04  7:16 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: linux-bluetooth@vger.kernel.org development
In-Reply-To: <E6E2219B-6B0E-435F-AA12-4194885D0691@holtmann.org>

Hi Marcel,

On 3 March 2014 16:23, Marcel Holtmann <marcel@holtmann.org> wrote:
> Hi Marcin,
>
>> unit/test-hfp.c | 31 +++++++++++++++++++++++++++++++
>> 1 file changed, 31 insertions(+)
>>
>> diff --git a/unit/test-hfp.c b/unit/test-hfp.c
>> index 5e4fc11..64ecc60 100644
>> --- a/unit/test-hfp.c
>> +++ b/unit/test-hfp.c
>> @@ -266,6 +266,33 @@ static const struct test_data test_register_2 = {
>>       .prefix = prefix_brsf
>> };
>>
>> +static const char atbrsf_read[] = {'A', 'T', '+', 'B', 'R', 'S', 'F', '?',
>> +                                                                     '\r'};
>> +
>
>         = "AT+BRSF?\r";
>
>> +static const struct test_data test_register_3 = {
>> +     .command_cb = cmd_handler,
>> +     .server_send = atbrsf_read,
>> +     .data_len = sizeof(atbrsf_read),
>> +     .expected_rsp = err_rsp,
>> +     .expected_rsp_len = sizeof(err_rsp),
>> +     .result_cb = prefix_handler,
>> +     .expected_cmd_type = HFP_GW_CMD_TYPE_READ,
>> +     .prefix = prefix_brsf
>> +};
>> +
>> +static const char prefix_d[] = "D";
>
> I wonder why here it is acceptable and above you are making the huge effort to give every character separately.
>
> Regards
>
> Marcel
>

I thought it will be more readable if raw data passed to socket will
be declared as array, not string. Prefixes are passed as strings,
because they are used in hfp_gw_register()  Anyway Luiz suggested to
use common framework for this test like raw_pdu(args...) ,
define_test(name, function, args...), (it is used in test-avctp and
test-avrcp). Will it look better for you?

BR
Marcin

^ permalink raw reply

* Re: [PATCH] Bluetooth:  Stop BCSP/H5 timer before cleaning up
From: Johan Hedberg @ 2014-03-04  7:14 UTC (permalink / raw)
  To: Michael Knudsen; +Cc: linux-bluetooth
In-Reply-To: <531563D2.1060301@samsung.com>

Hi Michael,

On Tue, Mar 04, 2014, Michael Knudsen wrote:
> On 02/18/2014 09:48 AM, Michael Knudsen wrote:
> >When stopping BCSP/H5, stop the retransmission timer before proceeding
> >to clean up packet queues.  The previous code had a race condition where
> >the timer could trigger after the packet lists and protocol structure
> >had been removed which lead to dereferencing NULL or use-after-free bugs.
> 
> No interest?

I was just discussing this yesterday with Marcel (that we seem to have
forgotten about this patch). The only concern is whether it's safe to
sleep in the *_close callbacks (since you use del_timer_sync). Have you
verified that this doesn't cause any issues?

Johan


^ permalink raw reply

* Re: [PATCH] Bluetooth:  Stop BCSP/H5 timer before cleaning up
From: Michael Knudsen @ 2014-03-04  5:25 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1392713288-12227-1-git-send-email-m.knudsen@samsung.com>

On 02/18/2014 09:48 AM, Michael Knudsen wrote:
> When stopping BCSP/H5, stop the retransmission timer before proceeding
> to clean up packet queues.  The previous code had a race condition where
> the timer could trigger after the packet lists and protocol structure
> had been removed which lead to dereferencing NULL or use-after-free bugs.

No interest?

-m.


^ permalink raw reply

* cannot connect Rock Candy Gesture Controller (wiimote) on Arch Linux
From: Mark E. Lee @ 2014-03-04  3:21 UTC (permalink / raw)
  To: linux-bluetooth

Salutations,

I recently purchased an off-brand wiimote from Target (USA). It is the
Rock Candy Gesture Controller (w/o motion plus). I have been unable to
connect to it via bluetooth on Arch Linux 64-bit (bluez 5.15-1). This
issue has been reported on GitHub
<https://github.com/dvdhrm/xwiimote/issues/43#issuecomment-36577704>.
I've reiterated my tests with the device below :

--OUTPUT of $ hcitool inq --iac=liac
Inquiring ...

00:17:AB:39:1C:70 clock offset: 0x5574 class: 0x002504

---OUTPUT of # hcitool info 00:17:AB:39:1C:70---
Inquiring ...
Requesting information ...
BD Address: 00:17:AB:39:1C:70
OUI Company: Nintendo Co., Ltd. (00-17-AB)
Device Name: Nintendo RVL-CNT-01
LMP Version: 3.0 (0x5) LMP Subversion: 0xc
Manufacturer: not assigned (771)
Features: 0xbc 0x02 0x04 0x38 0x08 0x00 0x00 0x00


---OUTPUT of $ hcitool inq---

Inquiring ...

---OUTPUT of $ hcitool scan---

Scanning ...

---OUTPUT of $ sdptool browse 00:17:AB:39:1C:70---
Browsing 00:17:AB:39:1C:70 ...

Service Search failed: Connection timed out

---OUTPUT of $ bluetoothctl; connect 00:17:AB:39:1C:70---

Device 00:17:AB:39:1C:70 not available

---OUTPUT of $ sdptool search 00:17:AB:39:1C:70---

Unknown service 00:17:AB:39:1C:70
----

Any help towards getting this device to work?

-- 
Mark E. Lee <mark@markelee.com>


^ permalink raw reply

* Re: Passive scanning of iBeacons results in a "Data Buffer Overflow"
From: Anderson Lizardo @ 2014-03-03 23:07 UTC (permalink / raw)
  To: Adam Warski; +Cc: BlueZ development
In-Reply-To: <A2B80C7C-697D-44E5-80EA-B398E62EE608@warski.org>

Hi Adam,

On Mon, Mar 3, 2014 at 5:25 PM, Adam Warski <adam@warski.org> wrote:
> But I guess even if it was a USB issue, it would be caught earlier? The advertisement packets have a certain preamble, and a CRC, so the shifted data would be discarded? Anyway, that doesn't seem to be the cause.

There are are a few things that point out to USB issue (in my opinion):

1) You said that having ethernet cable connected or not modifies the
behavior. on RPI, the ethernet chip is attached to the USB. As I said,
strange things happen to me as well when not using powered USB hub
(specially with WiFi dongles and USB cameras) :)

2) As you noticed, the "truncated" adv. packet is not being discarded
by the controller as we would expect. This means that the BT
controller is actually receiving a correct packet, but it is being
"truncated" when being sent to the host. The CRC/preamble, after
parsed and verified by the BT controller, is removed before sending
the packet to the host, so there is no way for the host do detect
corruptions between the BT controller and the kernel.

The dynamic debug messages may help identify whether there are
missing/truncated USB packets (there is a debug message in
btusb_intr_complete() from drivers/bluetooth/btusb.c to help identify
HCI reassembly issues).

Did you try using only the BT dongle and removing the Wifi one (and
connecting through ethernet cable)? Wifi dongles tend to be very power
hungry.

Also check whether the power source for the USB hub is working
properly... unfortunately I don't know how to check from the RPi side,
so you have to rely on first attaching it to the outlet, checking some
LED, and then attaching to the RPi. Also make sure the RPi uses its
own power adapter (instead of powering from the hub itself).

Well, at least you found a workaround (attaching an ethernet cable) :)

Best Regards,
-- 
Anderson Lizardo
http://www.indt.org/?lang=en
INdT - Manaus - Brazil

^ permalink raw reply

* Re: Passive scanning of iBeacons results in a "Data Buffer Overflow"
From: Adam Warski @ 2014-03-03 21:25 UTC (permalink / raw)
  To: Anderson Lizardo; +Cc: BlueZ development
In-Reply-To: <CAJdJm_P6gnpW5AhO9j4+LV6KX30J4sTWd_tWW=x=E+ejQq3cTQ@mail.gmail.com>


> I didn't notice that you were using Raspberry PI... To rule out USB
> power issues, can you try attaching a powered USB hub on the RPi, and
> then attach your BT dongle on it?
> 
> I always had strange/random problems on RPi with USB HW plugged
> directly on the USB port (except for pen drives, which work fine),
> even for devices which supposedly draw very little current.
> 
> Given that you are disabling duplicate filtering, every single
> Advertising packet is arriving at the host, so it is certainly using
> more power. Just not sure if that is the cause.

Same thing happens with a powered hub (with both WiFi and BT dongles plugged into the hub).

But I guess even if it was a USB issue, it would be caught earlier? The advertisement packets have a certain preamble, and a CRC, so the shifted data would be discarded? Anyway, that doesn’t seem to be the cause.

Adam

-- 
Adam Warski

http://twitter.com/#!/adamwarski
http://www.softwaremill.com
http://www.warski.org


^ permalink raw reply

* Re: Passive scanning of iBeacons results in a "Data Buffer Overflow"
From: Adam Warski @ 2014-03-03 21:06 UTC (permalink / raw)
  To: Anderson Lizardo; +Cc: BlueZ development
In-Reply-To: <CAJdJm_P6gnpW5AhO9j4+LV6KX30J4sTWd_tWW=x=E+ejQq3cTQ@mail.gmail.com>


On 03 Mar 2014, at 19:02, Anderson Lizardo <anderson.lizardo@openbossa.org> wrote:

> Hi Adam,
> 
> On Mon, Mar 3, 2014 at 11:26 AM, Adam Warski <adam@warski.org> wrote:
>> I'm wondering what this might mean exactly :) I guess it could point to the
>> specific USB/bluetooth drivers present in the raspbian 3.10 and ubuntu 3.11
>> kernels, right?
> 
> I didn't notice that you were using Raspberry PI... To rule out USB
> power issues, can you try attaching a powered USB hub on the RPi, and
> then attach your BT dongle on it?

During these experiments I found something very weird :)

The RPi has two dongles: WiFi and BT

Things *do* work, if the LAN cable is plugged in - even if the interface is down in the system.
The moment I pull the cable, I soon get the familiar buffer overflow and a flood of errors.
How is that possible? :)

That’s without a powered hub so far.

> I always had strange/random problems on RPi with USB HW plugged
> directly on the USB port (except for pen drives, which work fine),
> even for devices which supposedly draw very little current.
> 
> Given that you are disabling duplicate filtering, every single
> Advertising packet is arriving at the host, so it is certainly using
> more power. Just not sure if that is the cause.

So where is the filtering done? In the kernel driver?

Adam

-- 
Adam Warski

http://twitter.com/#!/adamwarski
http://www.softwaremill.com
http://www.warski.org


^ permalink raw reply

* Re: pull request: bluetooth-next 2014-02-28
From: John W. Linville @ 2014-03-03 20:34 UTC (permalink / raw)
  To: Gustavo Padovan, linux-wireless, linux-bluetooth, linux-kernel
In-Reply-To: <20140228193819.GA1700@joana>

On Fri, Feb 28, 2014 at 04:38:19PM -0300, Gustavo Padovan wrote:
> Hi John,
> 
> Another pull request to 3.15. Here we have the second part of the LE private
> feature, the LE auto-connect feature and improvements to the power off
> procedures. The rest are small improvements, clean up, and fixes.
> 
> Please pull or let me know of any problem. Thanks.
> 
> 	Gustavo
> 
> ---
> 
> The following changes since commit 668b7b19820b0801c425d31cc27fd6f499050e5c:
> 
>   Bluetooth: Fix iterating wrong list in hci_remove_irk() (2014-02-21 11:07:46 -0300)
> 
> are available in the git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git for-upstream
> 
> for you to fetch changes up to 81ad6fd9698f659dbabdc6cd3e1667a98eb2be3b:
> 
>   Bluetooth: Remove unnecessary stop_scan_complete function (2014-02-28 10:28:17 -0800)

Pulling now...

-- 
John W. Linville		Someday the world will need a hero, and you
linville@tuxdriver.com			might be all we have.  Be ready.

^ permalink raw reply

* Re: [PATCH 00/24] rfcomm fixes
From: Sander Eikelenboom @ 2014-03-03 19:38 UTC (permalink / raw)
  To: Marcel Holtmann
  Cc: Peter Hurley, Gustavo F. Padovan, Johan Hedberg, Gianluca Anzolin,
	Alexander Holler, Andrey Vihrov,
	bluez mailin list (linux-bluetooth@vger.kernel.org), linux-kernel
In-Reply-To: <1259174563.20140212120644@eikelenboom.it>


Wednesday, February 12, 2014, 12:06:44 PM, you wrote:

> Monday, February 10, 2014, 11:09:38 PM, you wrote:

>> Hi Peter,

>>> This patch series addresses a number of previously unknown issues
>>> with the RFCOMM tty device implementation, in addition to
>>> addressing the locking regression recently reported [1].
>>> 
>>> As Gianluca suggested and I agree, this series first reverts
>>> 3 of the 4 patches of 3.14-rc1 for bluetooth/rfcomm/tty.c.

>> so for 3.14 we should revert 3 patches. And then the other 21 are intended for 3.15 merge window.

>> I realize that we still have to deal with some breakage, but we do not want regressions and I clearly not going to take 24 patches for 3.14 at this point in time.

>> What I can do is take all 24 patches into bluetooth-next and let them sit for 1 week and have people test them. And then we go ahead with reverting 3 patches from 3.14. Does that make sense?

> Reverting those 3 patches works for me.

> --
> Sander

>> Regards

>> Marcel

Hi Marcel,

Ping... it seems these 3 reverts are still not in 3.14-rc5 to fix the regressions ?

--
Sander

^ permalink raw reply

* Re: Passive scanning of iBeacons results in a "Data Buffer Overflow"
From: Anderson Lizardo @ 2014-03-03 18:02 UTC (permalink / raw)
  To: Adam Warski; +Cc: BlueZ development
In-Reply-To: <0BA8DEFD-9E73-4A6A-A9E6-1957634CABF8@warski.org>

Hi Adam,

On Mon, Mar 3, 2014 at 11:26 AM, Adam Warski <adam@warski.org> wrote:
> I'm wondering what this might mean exactly :) I guess it could point to the
> specific USB/bluetooth drivers present in the raspbian 3.10 and ubuntu 3.11
> kernels, right?

I didn't notice that you were using Raspberry PI... To rule out USB
power issues, can you try attaching a powered USB hub on the RPi, and
then attach your BT dongle on it?

I always had strange/random problems on RPi with USB HW plugged
directly on the USB port (except for pen drives, which work fine),
even for devices which supposedly draw very little current.

Given that you are disabling duplicate filtering, every single
Advertising packet is arriving at the host, so it is certainly using
more power. Just not sure if that is the cause.

Best Regards,
-- 
Anderson Lizardo
http://www.indt.org/?lang=en
INdT - Manaus - Brazil

^ permalink raw reply

* Re: Receiving data in BLE non-connectable undirected advertisements
From: Marcel Holtmann @ 2014-03-03 15:28 UTC (permalink / raw)
  To: Benjamin Adler; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <531446EA.6020701@gmx.net>

Hi Benjamin,

>> You can just write an advertising receiver by using Bluetooth HCI
> > User Channel feature from the 3.13 kernel.  With the help of
> > src/shared/hci.c (if that license is acceptable to you), this is
> > trivial. If the license is not acceptable, then you have to
>> write your own HCI handling.
>> 
>> The BlueZ source code contains samples in form of tools/ibeacon.c
> > and others on how to write such small program for direct access
>> of the HCI interface. If you use this sample code, then please
> > comply with the license as well here.
> 
> regarding the license, this is more of a hobby project, so GPL is perfect.
> 
> Looking at hci.{c,h}, there is (except for the license) not a single comment that would help explain things (to bluetooth-newcomers). The functions might have descriptive names, but I'm missing the bigger picture.
> 
> Reading ibeacon.c, I get the impression the code is made for sending advertisements, not for receiving them. I might be wrong though, there's no comments either. None of the other filenames in tools/ made me hope I could find sample code for receiving non-connectable advertisements.
> 
> Marcel, could you either point me to some sample code, or help me understand hci.c (or list the required steps) so that I can write my own?

maybe you need to just read the HCI part of the Bluetooth Core specification. The tools/ibeacon.c is a perfect example on how to get started with HCI commands. You just need to figure out on how to do scanning instead of advertising.

Regards

Marcel


^ permalink raw reply

* Re: Passive scanning of iBeacons results in a "Data Buffer Overflow"
From: Adam Warski @ 2014-03-03 15:27 UTC (permalink / raw)
  To: Anderson Lizardo; +Cc: BlueZ development
In-Reply-To: <407CD6A9-AFA8-4A8A-BA2C-882D7A64EF40@warski.org>


> I messed up the model number, looked at the wrong dongle, TP-Link is the WiFi one ;)
> The bluetooth one is an IOGear GBU521 (http://www.iogear.com/product/GBU521/).
> 
> I don’t have another dongle right now (I tried a different IOGear, but same thing), but I’ll try setting a VM on my laptop/getting a different USB dongle.

I’ve setup an Ubuntu 13.10 VM (kernel 3.11.0-17), same dongle (IOGear), bluez 5.15, and it works without problems - at least for the past 15 minutes ;) (usually it work at most 2 minutes).

I’m wondering what this might mean exactly :) I guess it could point to the specific USB/bluetooth drivers present in the raspbian 3.10 and ubuntu 3.11 kernels, right? 

Adam

-- 
Adam Warski

http://twitter.com/#!/adamwarski
http://www.softwaremill.com
http://www.warski.org


^ permalink raw reply

* Re: [PATCH 7/7] Add /hfp/test_hfp_gw_register_3 and /hfp/test_hfp_gw_register_4
From: Marcel Holtmann @ 2014-03-03 15:23 UTC (permalink / raw)
  To: Marcin Kraglak; +Cc: linux-bluetooth
In-Reply-To: <1393835812-24238-7-git-send-email-marcin.kraglak@tieto.com>

Hi Marcin,

> unit/test-hfp.c | 31 +++++++++++++++++++++++++++++++
> 1 file changed, 31 insertions(+)
> 
> diff --git a/unit/test-hfp.c b/unit/test-hfp.c
> index 5e4fc11..64ecc60 100644
> --- a/unit/test-hfp.c
> +++ b/unit/test-hfp.c
> @@ -266,6 +266,33 @@ static const struct test_data test_register_2 = {
> 	.prefix = prefix_brsf
> };
> 
> +static const char atbrsf_read[] = {'A', 'T', '+', 'B', 'R', 'S', 'F', '?',
> +									'\r'};
> +

	= “AT+BRSF?\r”;

> +static const struct test_data test_register_3 = {
> +	.command_cb = cmd_handler,
> +	.server_send = atbrsf_read,
> +	.data_len = sizeof(atbrsf_read),
> +	.expected_rsp = err_rsp,
> +	.expected_rsp_len = sizeof(err_rsp),
> +	.result_cb = prefix_handler,
> +	.expected_cmd_type = HFP_GW_CMD_TYPE_READ,
> +	.prefix = prefix_brsf
> +};
> +
> +static const char prefix_d[] = "D”;

I wonder why here it is acceptable and above you are making the huge effort to give every character separately.

Regards

Marcel


^ permalink raw reply

* Re: [PATCH] android/hal-gatt: Add skeleton for GATT HAL
From: Szymon Janc @ 2014-03-03 15:17 UTC (permalink / raw)
  To: Jakub Tyszkowski; +Cc: linux-bluetooth
In-Reply-To: <1393844171-19866-1-git-send-email-jakub.tyszkowski@tieto.com>

Hi Jakub,

On Monday 03 of March 2014 11:56:11 Jakub Tyszkowski wrote:
> This adds skeleton with stubs and proper build system entries.
> ---
>  android/Android.mk      |   1 +
>  android/Makefile.am     |   1 +
>  android/hal-bluetooth.c |   3 +
>  android/hal-gatt.c      | 563 ++++++++++++++++++++++++++++++++++++++++++++++++
>  android/hal.h           |   4 +
>  5 files changed, 572 insertions(+)
>  create mode 100644 android/hal-gatt.c
> 
> diff --git a/android/Android.mk b/android/Android.mk
> index 56b86ba..6fd0f94 100644
> --- a/android/Android.mk
> +++ b/android/Android.mk
> @@ -118,6 +118,7 @@ LOCAL_SRC_FILES := \
>  	bluez/android/hal-a2dp.c \
>  	bluez/android/hal-avrcp.c \
>  	bluez/android/hal-handsfree.c \
> +	bluez/android/hal-gatt.c \
>  	bluez/android/hal-utils.c \
>  
>  LOCAL_C_INCLUDES += \
> diff --git a/android/Makefile.am b/android/Makefile.am
> index 31f905c..8abfff4 100644
> --- a/android/Makefile.am
> +++ b/android/Makefile.am
> @@ -55,6 +55,7 @@ android_bluetooth_default_la_SOURCES = android/hal.h android/hal-bluetooth.c \
>  					android/hal-a2dp.c \
>  					android/hal-avrcp.c \
>  					android/hal-handsfree.c \
> +					android/hal-gatt.c \
>  					android/hardware/bluetooth.h \
>  					android/hardware/bt_av.h \
>  					android/hardware/bt_gatt.h \
> diff --git a/android/hal-bluetooth.c b/android/hal-bluetooth.c
> index 6871f5d..f58f72c 100644
> --- a/android/hal-bluetooth.c
> +++ b/android/hal-bluetooth.c
> @@ -773,6 +773,9 @@ static const void *get_profile_interface(const char *profile_id)
>  	if (!strcmp(profile_id, BT_PROFILE_HANDSFREE_ID))
>  		return bt_get_handsfree_interface();
>  
> +	if (!strcmp(profile_id, BT_PROFILE_GATT_ID))
> +		return bt_get_gatt_interface();
> +
>  	return NULL;
>  }
>  
> diff --git a/android/hal-gatt.c b/android/hal-gatt.c
> new file mode 100644
> index 0000000..00cf888
> --- /dev/null
> +++ b/android/hal-gatt.c
> @@ -0,0 +1,563 @@
> +/*
> + * Copyright (C) 2014 Intel Corporation
> + *
> + * Licensed under the Apache License, Version 2.0 (the "License");
> + * you may not use this file except in compliance with the License.
> + * You may obtain a copy of the License at
> + *
> + *      http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing, software
> + * distributed under the License is distributed on an "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
> + * See the License for the specific language governing permissions and
> + * limitations under the License.
> + *
> + */
> +
> +#include <stdbool.h>
> +
> +#include "hal-log.h"
> +#include "hal.h"
> +#include "hal-msg.h"
> +#include "hal-ipc.h"
> +
> +static const btgatt_callbacks_t *cbs = NULL;
> +
> +static bool interface_ready(void)
> +{
> +	return cbs != NULL;
> +}
> +
> +/* Client Event Handlers */
> +
> +static void handle_register_client(void *buf, uint16_t len)
> +{
> +
> +}
> +
> +static void handle_scan_result(void *buf, uint16_t len)
> +{
> +
> +}
> +
> +static void handle_connect(void *buf, uint16_t len)
> +{
> +
> +}
> +
> +static void handle_disconnect(void *buf, uint16_t len)
> +{
> +
> +}
> +
> +static void handle_search_complete(void *buf, uint16_t len)
> +{
> +
> +}
> +
> +static void handle_search_result(void *buf, uint16_t len)
> +{
> +
> +}
> +
> +static void handle_get_characteristic(void *buf, uint16_t len)
> +{
> +
> +}
> +
> +static void handle_get_descriptor(void *buf, uint16_t len)
> +{
> +
> +}
> +
> +static void handle_get_included_service(void *buf, uint16_t len)
> +{
> +
> +}
> +
> +static void handle_register_for_notification(void *buf, uint16_t len)
> +{
> +
> +}
> +
> +static void handle_notify(void *buf, uint16_t len)
> +{
> +
> +}
> +
> +static void handle_read_characteristic(void *buf, uint16_t len)
> +{
> +
> +}
> +
> +static void handle_write_characteristic(void *buf, uint16_t len)
> +{
> +
> +}
> +
> +static void handle_read_descriptor(void *buf, uint16_t len)
> +{
> +
> +}
> +
> +static void handle_write_descriptor(void *buf, uint16_t len)
> +{
> +
> +}
> +
> +static void handle_execute_write(void *buf, uint16_t len)
> +{
> +
> +}
> +
> +static void handle_read_remote_rssi(void *buf, uint16_t len)
> +{
> +
> +}
> +
> +static void handle_listen(void *buf, uint16_t len)
> +{
> +
> +}
> +
> +/* Server Event Handlers */
> +
> +static void handle_register_server(void *buf, uint16_t len)
> +{
> +
> +}
> +
> +static void handle_connection(void *buf, uint16_t len)
> +{
> +
> +}
> +
> +static void handle_service_added(void *buf, uint16_t len)
> +{
> +
> +}
> +
> +static void handle_included_service_added(void *buf, uint16_t len)
> +{
> +
> +}
> +
> +static void handle_characteristic_added(void *buf, uint16_t len)
> +{
> +
> +}
> +
> +static void handle_descriptor_added(void *buf, uint16_t len)
> +{
> +
> +}
> +
> +static void handle_service_started(void *buf, uint16_t len)
> +{
> +
> +}
> +
> +static void handle_service_stopped(void *buf, uint16_t len)
> +{
> +
> +}
> +
> +static void handle_service_deleted(void *buf, uint16_t len)
> +{
> +
> +}
> +
> +static void handle_request_read(void *buf, uint16_t len)
> +{
> +
> +}
> +
> +static void handle_request_write(void *buf, uint16_t len)
> +{
> +
> +}
> +
> +static void handle_request_exec_write(void *buf, uint16_t len)
> +{
> +
> +}
> +
> +static void handle_response_confirmation(void *buf, uint16_t len)
> +{
> +
> +}
> +
> +/* handlers will be called from notification thread context,
> + * index in table equals to 'opcode - HAL_MINIMUM_EVENT' */
> +static const struct hal_ipc_handler ev_handlers[] = {
> +	/* Client Event Handlers */
> +	{handle_register_client, false,
> +			sizeof(struct hal_ev_gatt_client_register_client)},
> +	{handle_scan_result, true,
> +				sizeof(struct hal_ev_gatt_client_scan_result)},
> +	{handle_connect, false, sizeof(struct hal_ev_gatt_client_connect)},
> +	{handle_disconnect, false,
> +			sizeof(struct hal_ev_gatt_client_disconnect)},
> +	{handle_search_complete, false,
> +			sizeof(struct hal_ev_gatt_client_search_complete)},
> +	{handle_search_result, false,
> +			sizeof(struct hal_ev_gatt_client_search_result)},
> +	{handle_get_characteristic, false,
> +			sizeof(struct hal_ev_gatt_client_get_characteristic)},
> +	{handle_get_descriptor, false,
> +			sizeof(struct hal_ev_gatt_client_get_descriptor)},
> +	{handle_get_included_service, false,
> +			sizeof(struct hal_ev_gatt_client_get_inc_service)},
> +	{handle_register_for_notification, false,
> +			sizeof(struct hal_ev_gatt_client_reg_for_notif)},
> +	{handle_notify, true, sizeof(struct hal_ev_gatt_client_notify)},
> +	{handle_read_characteristic, true,
> +			sizeof(struct hal_ev_gatt_client_read_characteristic)},
> +	{handle_write_characteristic, false,
> +			sizeof(struct hal_ev_gatt_client_write_characteristic)},
> +	{handle_read_descriptor, false,
> +			sizeof(struct hal_ev_gatt_client_read_descriptor)},
> +	{handle_write_descriptor, false,
> +			sizeof(struct hal_ev_gatt_client_write_descriptor)},
> +	{handle_execute_write, false,
> +				sizeof(struct hal_ev_gatt_client_exec_write)},
> +	{handle_read_remote_rssi, false,
> +			sizeof(struct hal_ev_gatt_client_read_remote_rssi)},
> +	{handle_listen, false, sizeof(struct hal_ev_gatt_client_listen)},
> +
> +	/* Server Event Handlers */
> +	{handle_register_server, false,
> +				sizeof(struct hal_ev_gatt_server_register)},
> +	{handle_connection, false,
> +				sizeof(struct hal_ev_gatt_server_connection)},
> +	{handle_service_added, false,
> +			sizeof(struct hal_ev_gatt_server_service_added)},
> +	{handle_included_service_added, false,
> +			sizeof(struct hal_ev_gatt_server_service_added)},
> +	{handle_characteristic_added, false,
> +			sizeof(struct hal_ev_gatt_server_characteristic_added)},
> +	{handle_descriptor_added, false,
> +			sizeof(struct hal_ev_gatt_server_descriptor_added)},
> +	{handle_service_started, false,
> +			sizeof(struct hal_ev_gatt_server_service_started)},
> +	{handle_service_stopped, false,
> +			sizeof(struct hal_ev_gatt_server_service_stopped)},
> +	{handle_service_deleted, false,
> +			sizeof(struct hal_ev_gatt_server_service_deleted)},
> +	{handle_request_read, false,
> +			sizeof(struct hal_ev_gatt_server_request_read)},
> +	{handle_request_write, true,
> +			sizeof(struct hal_ev_gatt_server_request_write)},
> +	{handle_request_exec_write, false,
> +			sizeof(struct hal_ev_gatt_server_request_exec_write)},
> +	{handle_response_confirmation, false,
> +			sizeof(struct hal_ev_gatt_server_rsp_confirmation)},
> +};
> +
> +static bt_status_t init(const btgatt_callbacks_t *callbacks)
> +{
> +	struct hal_cmd_register_module cmd;
> +	int ret;
> +
> +	DBG("");
> +
> +	if (interface_ready())
> +		return BT_STATUS_DONE;
> +
> +	cbs = callbacks;
> +
> +	hal_ipc_register(HAL_SERVICE_ID_GATT, ev_handlers,
> +				sizeof(ev_handlers)/sizeof(ev_handlers[0]));
> +
> +	cmd.service_id = HAL_SERVICE_ID_GATT;
> +
> +	ret = hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_REGISTER_MODULE,
> +					sizeof(cmd), &cmd, 0, NULL, NULL);
> +
> +	if (ret != BT_STATUS_SUCCESS) {
> +		cbs = NULL;
> +		hal_ipc_unregister(HAL_SERVICE_ID_GATT);
> +	}
> +
> +	return ret;
> +}
> +
> +/* Client API */
> +
> +static bt_status_t register_client(bt_uuid_t *uuid)
> +{
> +	return BT_STATUS_UNSUPPORTED;
> +}
> +
> +static bt_status_t unregister_client(int client_if)
> +{
> +	return BT_STATUS_UNSUPPORTED;
> +}
> +
> +static bt_status_t scan(int client_if, bool start)
> +{
> +	return BT_STATUS_UNSUPPORTED;
> +}
> +
> +static bt_status_t connect(int client_if, const bt_bdaddr_t *bd_addr,
> +								bool is_direct)
> +{
> +	return BT_STATUS_UNSUPPORTED;
> +}
> +
> +static bt_status_t disconnect(int client_if, const bt_bdaddr_t *bd_addr,
> +								int conn_id)
> +{
> +	return BT_STATUS_UNSUPPORTED;
> +}
> +
> +static bt_status_t listen(int client_if, bool start)
> +{
> +	return BT_STATUS_UNSUPPORTED;
> +}
> +
> +static bt_status_t refresh(int client_if, const bt_bdaddr_t *bd_addr)
> +{
> +	return BT_STATUS_UNSUPPORTED;
> +}
> +
> +static bt_status_t search_service(int conn_id, bt_uuid_t *filter_uuid)
> +{
> +	return BT_STATUS_UNSUPPORTED;
> +}
> +
> +static bt_status_t get_included_service(int conn_id, btgatt_srvc_id_t *srvc_id,
> +				     btgatt_srvc_id_t *start_incl_srvc_id)
> +{
> +	return BT_STATUS_UNSUPPORTED;
> +}
> +
> +static bt_status_t get_characteristic(int conn_id, btgatt_srvc_id_t *srvc_id,
> +						btgatt_gatt_id_t *start_char_id)
> +{
> +	return BT_STATUS_UNSUPPORTED;
> +}
> +
> +static bt_status_t get_descriptor(int conn_id, btgatt_srvc_id_t *srvc_id,
> +					btgatt_gatt_id_t *char_id,
> +					btgatt_gatt_id_t *start_descr_id)
> +{
> +	return BT_STATUS_UNSUPPORTED;
> +}
> +
> +static bt_status_t read_characteristic(int conn_id, btgatt_srvc_id_t *srvc_id,
> +					btgatt_gatt_id_t *char_id,
> +					int auth_req)
> +{
> +	return BT_STATUS_UNSUPPORTED;
> +}
> +
> +static bt_status_t write_characteristic(int conn_id, btgatt_srvc_id_t *srvc_id,
> +				btgatt_gatt_id_t *char_id, int write_type,
> +				int len, int auth_req, char *p_value)
> +{
> +	return BT_STATUS_UNSUPPORTED;
> +}
> +
> +static bt_status_t read_descriptor(int conn_id, btgatt_srvc_id_t *srvc_id,
> +				btgatt_gatt_id_t *char_id,
> +				btgatt_gatt_id_t *descr_id, int auth_req)
> +{
> +	return BT_STATUS_UNSUPPORTED;
> +}
> +
> +static bt_status_t write_descriptor(int conn_id, btgatt_srvc_id_t *srvc_id,
> +				btgatt_gatt_id_t *char_id,
> +				btgatt_gatt_id_t *descr_id, int write_type,
> +				int len, int auth_req, char *p_value)
> +{
> +	return BT_STATUS_UNSUPPORTED;
> +}
> +
> +static bt_status_t execute_write(int conn_id, int execute)
> +{
> +	return BT_STATUS_UNSUPPORTED;
> +}
> +
> +static bt_status_t register_for_notification(int client_if,
> +						const bt_bdaddr_t *bd_addr,
> +						btgatt_srvc_id_t *srvc_id,
> +						btgatt_gatt_id_t *char_id)
> +{
> +	return BT_STATUS_UNSUPPORTED;
> +}
> +
> +static bt_status_t deregister_for_notification(int client_if,
> +			const bt_bdaddr_t *bd_addr, btgatt_srvc_id_t *srvc_id,
> +			btgatt_gatt_id_t *char_id)
> +{
> +	return BT_STATUS_UNSUPPORTED;
> +}
> +
> +static bt_status_t read_remote_rssi(int client_if, const bt_bdaddr_t *bd_addr)
> +{
> +	return BT_STATUS_UNSUPPORTED;
> +}
> +
> +static int get_device_type(const bt_bdaddr_t *bd_addr)
> +{
> +	return 0;
> +}
> +
> +static bt_status_t set_adv_data(int server_if, bool set_scan_rsp,
> +			bool include_name, bool include_txpower,
> +			int min_interval, int max_interval, int appearance,
> +			uint16_t manufacturer_len, char *manufacturer_data)
> +{
> +	return BT_STATUS_UNSUPPORTED;
> +}
> +
> +static bt_status_t test_command(int command, btgatt_test_params_t *params)
> +{
> +	return BT_STATUS_UNSUPPORTED;
> +}
> +
> +/* Server API */
> +
> +static bt_status_t register_server(bt_uuid_t *uuid)
> +{
> +	return BT_STATUS_UNSUPPORTED;
> +}
> +
> +static bt_status_t unregister_server(int server_if)
> +{
> +	return BT_STATUS_UNSUPPORTED;
> +}
> +
> +static bt_status_t server_connect(int server_if, const bt_bdaddr_t *bd_addr,
> +								bool is_direct)
> +{
> +	return BT_STATUS_UNSUPPORTED;
> +}
> +
> +static bt_status_t add_service(int server_if, btgatt_srvc_id_t *srvc_id,
> +								int num_handles)
> +{
> +	return BT_STATUS_UNSUPPORTED;
> +}
> +
> +static bt_status_t add_included_service(int server_if, int service_handle,
> +						int included_handle)
> +{
> +	return BT_STATUS_UNSUPPORTED;
> +}
> +
> +static bt_status_t add_characteristic(int server_if, int service_handle,
> +						bt_uuid_t *uuid, int properties,
> +						int permissions)
> +{
> +	return BT_STATUS_UNSUPPORTED;
> +}
> +
> +static bt_status_t add_descriptor(int server_if, int service_handle,
> +					bt_uuid_t *uuid, int permissions)
> +{
> +	return BT_STATUS_UNSUPPORTED;
> +}
> +
> +static bt_status_t start_service(int server_if, int service_handle,
> +								int transport)
> +{
> +	return BT_STATUS_UNSUPPORTED;
> +}
> +
> +static bt_status_t stop_service(int server_if, int service_handle)
> +{
> +	return BT_STATUS_UNSUPPORTED;
> +}
> +
> +static bt_status_t delete_service(int server_if, int service_handle)
> +{
> +	return BT_STATUS_UNSUPPORTED;
> +}
> +
> +static bt_status_t send_indication(int server_if, int attribute_handle,
> +					int conn_id, int len, int confirm,
> +					char *p_value)
> +{
> +	return BT_STATUS_UNSUPPORTED;
> +}
> +
> +static bt_status_t send_response(int conn_id, int trans_id, int status,
> +						btgatt_response_t *response)
> +{
> +	return BT_STATUS_UNSUPPORTED;
> +}
> +
> +static void cleanup(void)
> +{
> +	struct hal_cmd_unregister_module cmd;
> +
> +	DBG("");
> +
> +	if (!interface_ready())
> +		return;
> +
> +	cbs = NULL;
> +
> +	cmd.service_id = HAL_SERVICE_ID_GATT;
> +
> +	hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_UNREGISTER_MODULE,
> +					sizeof(cmd), &cmd, 0, NULL, NULL);
> +
> +	hal_ipc_unregister(HAL_SERVICE_ID_GATT);
> +}
> +
> +static btgatt_client_interface_t client_iface = {
> +	.register_client = register_client,
> +	.unregister_client = unregister_client,
> +	.scan = scan,
> +	.connect = connect,
> +	.disconnect = disconnect,
> +	.listen = listen,
> +	.refresh = refresh,
> +	.search_service = search_service,
> +	.get_included_service = get_included_service,
> +	.get_characteristic = get_characteristic,
> +	.get_descriptor = get_descriptor,
> +	.read_characteristic = read_characteristic,
> +	.write_characteristic = write_characteristic,
> +	.read_descriptor = read_descriptor,
> +	.write_descriptor = write_descriptor,
> +	.execute_write = execute_write,
> +	.register_for_notification = register_for_notification,
> +	.deregister_for_notification = deregister_for_notification,
> +	.read_remote_rssi = read_remote_rssi,
> +	.get_device_type = get_device_type,
> +	.set_adv_data = set_adv_data,
> +	.test_command = test_command,
> +};
> +
> +static btgatt_server_interface_t server_iface = {
> +	.register_server = register_server,
> +	.unregister_server = unregister_server,
> +	.connect = server_connect,
> +	.add_service = add_service,
> +	.add_included_service = add_included_service,
> +	.add_characteristic = add_characteristic,
> +	.add_descriptor = add_descriptor,
> +	.start_service = start_service,
> +	.stop_service = stop_service,
> +	.delete_service = delete_service,
> +	.send_indication = send_indication,
> +	.send_response = send_response,
> +};
> +
> +static btgatt_interface_t iface = {
> +	.size = sizeof(iface),
> +	.init = init,
> +	.cleanup = cleanup,
> +	.client = &client_iface,
> +	.server = &server_iface,
> +};
> +
> +btgatt_interface_t *bt_get_gatt_interface(void)
> +{
> +	return &iface;
> +}
> diff --git a/android/hal.h b/android/hal.h
> index 6fd2559..b1c0216 100644
> --- a/android/hal.h
> +++ b/android/hal.h
> @@ -22,6 +22,9 @@
>  #include <hardware/bt_av.h>
>  #include <hardware/bt_rc.h>
>  #include <hardware/bt_hf.h>
> +#include <hardware/bt_gatt.h>
> +#include <hardware/bt_gatt_client.h>
> +#include <hardware/bt_gatt_server.h>
>  
>  btsock_interface_t *bt_get_socket_interface(void);
>  bthh_interface_t *bt_get_hidhost_interface(void);
> @@ -29,6 +32,7 @@ btpan_interface_t *bt_get_pan_interface(void);
>  btav_interface_t *bt_get_a2dp_interface(void);
>  btrc_interface_t *bt_get_avrcp_interface(void);
>  bthf_interface_t *bt_get_handsfree_interface(void);
> +btgatt_interface_t *bt_get_gatt_interface(void);
>  
>  void bt_thread_associate(void);
>  void bt_thread_disassociate(void);
> 

Applied (with some minor changes), thanks.

-- 
Best regards, 
Szymon Janc

^ permalink raw reply

* Re: [PATCH v2 1/2] android/gatt: Add initial files
From: Szymon Janc @ 2014-03-03 15:16 UTC (permalink / raw)
  To: Grzegorz Kolodziejczyk; +Cc: linux-bluetooth
In-Reply-To: <1393858267-27487-1-git-send-email-grzegorz.kolodziejczyk@tieto.com>

Hi Grzegorz,

On Monday 03 of March 2014 15:51:06 Grzegorz Kolodziejczyk wrote:
> This adds initial daemon code for GATT profile.
> ---
>  android/Android.mk  |  1 +
>  android/Makefile.am |  1 +
>  android/gatt.c      | 44 ++++++++++++++++++++++++++++++++++++++++++++
>  android/gatt.h      | 25 +++++++++++++++++++++++++
>  android/main.c      | 14 ++++++++++++++
>  5 files changed, 85 insertions(+)
>  create mode 100644 android/gatt.c
>  create mode 100644 android/gatt.h
> 
> diff --git a/android/Android.mk b/android/Android.mk
> index 56b86ba..429a4b8 100644
> --- a/android/Android.mk
> +++ b/android/Android.mk
> @@ -42,6 +42,7 @@ LOCAL_SRC_FILES := \
>  	bluez/android/avrcp-lib.c \
>  	bluez/android/pan.c \
>  	bluez/android/handsfree.c \
> +	bluez/android/gatt.c
>  	bluez/src/log.c \
>  	bluez/src/shared/mgmt.c \
>  	bluez/src/shared/util.c \
> diff --git a/android/Makefile.am b/android/Makefile.am
> index 31f905c..6be6cda 100644
> --- a/android/Makefile.am
> +++ b/android/Makefile.am
> @@ -40,6 +40,7 @@ android_bluetoothd_SOURCES = android/main.c \
>  				android/socket.h android/socket.c \
>  				android/pan.h android/pan.c \
>  				android/handsfree.h android/handsfree.c \
> +				android/gatt.h android/gatt.c \
>  				btio/btio.h btio/btio.c \
>  				src/sdp-client.h src/sdp-client.c \
>  				profiles/network/bnep.h profiles/network/bnep.c
> diff --git a/android/gatt.c b/android/gatt.c
> new file mode 100644
> index 0000000..f577446
> --- /dev/null
> +++ b/android/gatt.c
> @@ -0,0 +1,44 @@
> +/*
> + *
> + *  BlueZ - Bluetooth protocol stack for Linux
> + *
> + *  Copyright (C) 2014  Intel Corporation. All rights reserved.
> + *
> + *
> + *  This library is free software; you can redistribute it and/or
> + *  modify it under the terms of the GNU Lesser General Public
> + *  License as published by the Free Software Foundation; either
> + *  version 2.1 of the License, or (at your option) any later version.
> + *
> + *  This library 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
> + *  Lesser General Public License for more details.
> + *
> + *  You should have received a copy of the GNU Lesser General Public
> + *  License along with this library; if not, write to the Free Software
> + *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
> + *
> + */
> +
> +#ifdef HAVE_CONFIG_H
> +#include <config.h>
> +#endif
> +
> +#include <stdbool.h>
> +#include <stdlib.h>
> +#include <stdint.h>
> +
> +#include "ipc.h"
> +#include "lib/bluetooth.h"
> +#include "gatt.h"
> +
> +bool bt_gatt_register(struct ipc *ipc, const bdaddr_t *addr)
> +{
> +	return false;
> +}
> +
> +void bt_gatt_unregister(void)
> +{
> +
> +}
> diff --git a/android/gatt.h b/android/gatt.h
> new file mode 100644
> index 0000000..d4392d9
> --- /dev/null
> +++ b/android/gatt.h
> @@ -0,0 +1,25 @@
> +/*
> + *
> + *  BlueZ - Bluetooth protocol stack for Linux
> + *
> + *  Copyright (C) 2014  Intel Corporation. All rights reserved.
> + *
> + *
> + *  This library is free software; you can redistribute it and/or
> + *  modify it under the terms of the GNU Lesser General Public
> + *  License as published by the Free Software Foundation; either
> + *  version 2.1 of the License, or (at your option) any later version.
> + *
> + *  This library 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
> + *  Lesser General Public License for more details.
> + *
> + *  You should have received a copy of the GNU Lesser General Public
> + *  License along with this library; if not, write to the Free Software
> + *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
> + *
> + */
> +
> +bool bt_gatt_register(struct ipc *ipc, const bdaddr_t *addr);
> +void bt_gatt_unregister(void);
> diff --git a/android/main.c b/android/main.c
> index a6742ef..104211a 100644
> --- a/android/main.c
> +++ b/android/main.c
> @@ -58,6 +58,7 @@
>  #include "pan.h"
>  #include "avrcp.h"
>  #include "handsfree.h"
> +#include "gatt.h"
>  
>  #define STARTUP_GRACE_SECONDS 5
>  #define SHUTDOWN_GRACE_SECONDS 10
> @@ -126,6 +127,13 @@ static void service_register(const void *buf, uint16_t len)
>  		}
>  
>  		break;
> +	case HAL_SERVICE_ID_GATT:
> +		if (!bt_gatt_register(hal_ipc, &adapter_bdaddr)) {
> +			status = HAL_STATUS_FAILED;
> +			goto failed;
> +		}
> +
> +		break;
>  	default:
>  		DBG("service %u not supported", m->service_id);
>  		status = HAL_STATUS_FAILED;
> @@ -175,6 +183,9 @@ static void service_unregister(const void *buf, uint16_t len)
>  	case HAL_SERVICE_ID_HANDSFREE:
>  		bt_handsfree_unregister();
>  		break;
> +	case HAL_SERVICE_ID_GATT:
> +		bt_gatt_unregister();
> +		break;
>  	default:
>  		/* This would indicate bug in HAL, as unregister should not be
>  		 * called in init failed */
> @@ -371,6 +382,9 @@ static void cleanup_services(void)
>  		case HAL_SERVICE_ID_HANDSFREE:
>  			bt_handsfree_unregister();
>  			break;
> +		case HAL_SERVICE_ID_GATT:
> +			bt_gatt_unregister();
> +			break;
>  		}
>  
>  		services[i] = false;
> 

Both patches applied, thanks.

-- 
Best regards, 
Szymon Janc

^ permalink raw reply

* Re: [PATCH] tools: Fix using uninitialized value
From: Johan Hedberg @ 2014-03-03 14:55 UTC (permalink / raw)
  To: Andrei Emeltchenko; +Cc: linux-bluetooth
In-Reply-To: <1393838024-18439-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

Hi Andrei,

On Mon, Mar 03, 2014, Andrei Emeltchenko wrote:
> Fixes warning:
> tools/ibeacon.c:150:14: warning: The left expression of the compound
> assignment is an uninitialized value. The computed value will also be
> garbage
>         cmd.data[2] |= 0x02;            /* LE General Discoverable Mode
> */
>         ~~~~~~~~~~~ ^
> 1 warning generated.
> ---
>  tools/ibeacon.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/tools/ibeacon.c b/tools/ibeacon.c
> index 458f9e7..2071c6b 100644
> --- a/tools/ibeacon.c
> +++ b/tools/ibeacon.c
> @@ -147,7 +147,7 @@ static void adv_tx_power_callback(const void *data, uint8_t size,
>  
>  	cmd.data[0] = 0x02;		/* Field length */
>  	cmd.data[1] = 0x01;		/* Flags */
> -	cmd.data[2] |= 0x02;		/* LE General Discoverable Mode */
> +	cmd.data[2] = 0x02;		/* LE General Discoverable Mode */
>  	cmd.data[2] |= 0x04;		/* BR/EDR Not Supported */
>  
>  	cmd.data[3] = 0x1a;		/* Field length */

Applied. Thanks.

Johan

^ permalink raw reply

* Re: [PATCH] tools/rfcomm-tester: Add bind after connected test case
From: Johan Hedberg @ 2014-03-03 14:52 UTC (permalink / raw)
  To: Andrzej Kaczmarek; +Cc: linux-bluetooth
In-Reply-To: <1392300683-13835-1-git-send-email-andrzej.kaczmarek@tieto.com>

Hi Andrzej,

On Thu, Feb 13, 2014, Andrzej Kaczmarek wrote:
> This testcase will check if it's possible to bind socket on the same
> channel number as used by some other socket connected to remote device.
> ---
>  tools/rfcomm-tester.c | 29 +++++++++++++++++++++++++++--
>  1 file changed, 27 insertions(+), 2 deletions(-)

Sorry for not getting around to this one earlier.

> @@ -389,10 +397,24 @@ static gboolean rc_connect_cb(GIOChannel *io, GIOCondition cond,
>  		return false;
>  	}
>  
> -	if (err < 0)
> +	if (!client_data->bind_channel) {
> +		if (err < 0)
> +			tester_test_failed();
> +		else
> +			tester_test_passed();
> +		return false;
> +	}
> +
> +	master_addr = hciemu_get_master_bdaddr(data->hciemu);
> +	sk = create_rfcomm_sock((bdaddr_t *) master_addr,
> +						client_data->bind_channel);
> +	if (sk < 0) {
>  		tester_test_failed();
> -	else
> +	} else {
> +		close(sk);
>  		tester_test_passed();
> +	}
> +
>  
>  	return false;
>  }

Considering that rc_connect_cb is a generic function used by many test
cases I find it strange to add this much extra code for it for a single
special case which is only needed by a single test case. I'd rather have
this in a separate function.

Either reuse the existing test_connect() and add a way to specify (in
the test case declaration) a custom function to pass to g_io_add_watch()
or then create completely new test function from scratch. This will help
avoid confusion when someone tries to understand what all the other
tests which do not need this extra hack are trying to do.

Johan

^ permalink raw reply

* [PATCH v2 2/2] android/gatt: Add stubs for GATT commands handlers
From: Grzegorz Kolodziejczyk @ 2014-03-03 14:51 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1393858267-27487-1-git-send-email-grzegorz.kolodziejczyk@tieto.com>

Add empty handlers for GATT IPC commands.
---
 android/gatt.c | 417 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 416 insertions(+), 1 deletion(-)

diff --git a/android/gatt.c b/android/gatt.c
index f577446..ce85af4 100644
--- a/android/gatt.c
+++ b/android/gatt.c
@@ -28,17 +28,432 @@
 #include <stdbool.h>
 #include <stdlib.h>
 #include <stdint.h>
+#include <glib.h>
 
 #include "ipc.h"
 #include "lib/bluetooth.h"
 #include "gatt.h"
+#include "src/log.h"
+#include "hal-msg.h"
+
+static struct ipc *hal_ipc = NULL;
+static bdaddr_t adapter_addr;
+
+static void handle_client_register(const void *buf, uint16_t len)
+{
+	DBG("");
+
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT, HAL_OP_GATT_CLIENT_REGISTER,
+							HAL_STATUS_FAILED);
+}
+
+static void handle_client_unregister(const void *buf, uint16_t len)
+{
+	DBG("");
+
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
+			HAL_OP_GATT_CLIENT_UNREGISTER, HAL_STATUS_FAILED);
+}
+
+static void handle_client_scan(const void *buf, uint16_t len)
+{
+	DBG("");
+
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT, HAL_OP_GATT_CLIENT_SCAN,
+							HAL_STATUS_FAILED);
+}
+
+static void handle_client_connect(const void *buf, uint16_t len)
+{
+	DBG("");
+
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT, HAL_OP_GATT_CLIENT_CONNECT,
+							HAL_STATUS_FAILED);
+}
+
+static void handle_client_disconnect(const void *buf, uint16_t len)
+{
+	DBG("");
+
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
+			HAL_OP_GATT_CLIENT_DISCONNECT, HAL_STATUS_FAILED);
+}
+
+static void handle_client_listen(const void *buf, uint16_t len)
+{
+	DBG("");
+
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT, HAL_OP_GATT_CLIENT_LISTEN,
+							HAL_STATUS_FAILED);
+}
+
+static void handle_client_refresh(const void *buf, uint16_t len)
+{
+	DBG("");
+
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT, HAL_OP_GATT_CLIENT_REFRESH,
+							HAL_STATUS_FAILED);
+}
+
+static void handle_client_search_service(const void *buf, uint16_t len)
+{
+	DBG("");
+
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
+			HAL_OP_GATT_CLIENT_SEARCH_SERVICE, HAL_STATUS_FAILED);
+}
+
+static void handle_client_get_included_service(const void *buf, uint16_t len)
+{
+	DBG("");
+
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
+					HAL_OP_GATT_CLIENT_GET_INCLUDED_SERVICE,
+					HAL_STATUS_FAILED);
+}
+
+static void handle_client_get_characteristic(const void *buf, uint16_t len)
+{
+	DBG("");
+
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
+					HAL_OP_GATT_CLIENT_GET_CHARACTERISTIC,
+					HAL_STATUS_FAILED);
+}
+
+static void handle_client_get_descriptor(const void *buf, uint16_t len)
+{
+	DBG("");
+
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
+			HAL_OP_GATT_CLIENT_GET_DESCRIPTOR, HAL_STATUS_FAILED);
+}
+
+static void handle_client_read_characteristic(const void *buf, uint16_t len)
+{
+	DBG("");
+
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
+					HAL_OP_GATT_CLIENT_READ_CHARACTERISTIC,
+					HAL_STATUS_FAILED);
+}
+
+static void handle_client_write_characteristic(const void *buf, uint16_t len)
+{
+	DBG("");
+
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
+					HAL_OP_GATT_CLIENT_WRITE_CHARACTERISTIC,
+					HAL_STATUS_FAILED);
+}
+
+static void handle_client_read_descriptor(const void *buf, uint16_t len)
+{
+	DBG("");
+
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
+			HAL_OP_GATT_CLIENT_READ_DESCRIPTOR, HAL_STATUS_FAILED);
+}
+
+static void handle_client_write_descriptor(const void *buf, uint16_t len)
+{
+	DBG("");
+
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
+			HAL_OP_GATT_CLIENT_WRITE_DESCRIPTOR, HAL_STATUS_FAILED);
+}
+
+static void handle_client_execute_write(const void *buf, uint16_t len)
+{
+	DBG("");
+
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
+			HAL_OP_GATT_CLIENT_EXECUTE_WRITE, HAL_STATUS_FAILED);
+}
+
+static void handle_client_register_for_notification(const void *buf,
+								uint16_t len)
+{
+	DBG("");
+
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
+				HAL_OP_GATT_CLIENT_REGISTER_FOR_NOTIFICATION,
+				HAL_STATUS_FAILED);
+}
+
+static void handle_client_deregister_for_notification(const void *buf,
+								uint16_t len)
+{
+	DBG("");
+
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
+				HAL_OP_GATT_CLIENT_DEREGISTER_FOR_NOTIFICATION,
+				HAL_STATUS_FAILED);
+}
+
+static void handle_client_read_remote_rssi(const void *buf, uint16_t len)
+{
+	DBG("");
+
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
+			HAL_OP_GATT_CLIENT_READ_REMOTE_RSSI, HAL_STATUS_FAILED);
+}
+
+static void handle_client_get_device_type(const void *buf, uint16_t len)
+{
+	DBG("");
+
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
+			HAL_OP_GATT_CLIENT_GET_DEVICE_TYPE, HAL_STATUS_FAILED);
+}
+
+static void handle_client_set_adv_data(const void *buf, uint16_t len)
+{
+	DBG("");
+
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
+			HAL_OP_GATT_CLIENT_SET_ADV_DATA, HAL_STATUS_FAILED);
+}
+
+static void handle_client_test_command(const void *buf, uint16_t len)
+{
+	DBG("");
+
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
+			HAL_OP_GATT_CLIENT_TEST_COMMAND, HAL_STATUS_FAILED);
+}
+
+static void handle_server_register(const void *buf, uint16_t len)
+{
+	DBG("");
+
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT, HAL_OP_GATT_SERVER_REGISTER,
+							HAL_STATUS_FAILED);
+}
+
+static void handle_server_unregister(const void *buf, uint16_t len)
+{
+	DBG("");
+
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
+			HAL_OP_GATT_SERVER_UNREGISTER, HAL_STATUS_FAILED);
+}
+
+static void handle_server_connect(const void *buf, uint16_t len)
+{
+	DBG("");
+
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT, HAL_OP_GATT_SERVER_CONNECT,
+							HAL_STATUS_FAILED);
+}
+
+static void handle_server_disconnect(const void *buf, uint16_t len)
+{
+	DBG("");
+
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
+			HAL_OP_GATT_SERVER_DISCONNECT, HAL_STATUS_FAILED);
+}
+
+static void handle_server_add_service(const void *buf, uint16_t len)
+{
+	DBG("");
+
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
+			HAL_OP_GATT_SERVER_ADD_SERVICE, HAL_STATUS_FAILED);
+}
+
+static void handle_server_add_included_service(const void *buf, uint16_t len)
+{
+	DBG("");
+
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
+			HAL_OP_GATT_SERVER_ADD_INC_SERVICE, HAL_STATUS_FAILED);
+}
+
+static void handle_server_add_characteristic(const void *buf, uint16_t len)
+{
+	DBG("");
+
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
+					HAL_OP_GATT_SERVER_ADD_CHARACTERISTIC,
+					HAL_STATUS_FAILED);
+}
+
+static void handle_server_add_descriptor(const void *buf, uint16_t len)
+{
+	DBG("");
+
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
+			HAL_OP_GATT_SERVER_ADD_DESCRIPTOR, HAL_STATUS_FAILED);
+}
+
+static void handle_server_start_service(const void *buf, uint16_t len)
+{
+	DBG("");
+
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
+			HAL_OP_GATT_SERVER_START_SERVICE, HAL_STATUS_FAILED);
+}
+
+static void handle_server_stop_service(const void *buf, uint16_t len)
+{
+	DBG("");
+
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
+			HAL_OP_GATT_SERVER_STOP_SERVICE, HAL_STATUS_FAILED);
+}
+
+static void handle_server_delete_service(const void *buf, uint16_t len)
+{
+	DBG("");
+
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
+			HAL_OP_GATT_SERVER_DELETE_SERVICE, HAL_STATUS_FAILED);
+}
+
+static void handle_server_send_indication(const void *buf, uint16_t len)
+{
+	DBG("");
+
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
+			HAL_OP_GATT_SERVER_SEND_INDICATION, HAL_STATUS_FAILED);
+}
+
+static void handle_server_send_response(const void *buf, uint16_t len)
+{
+	DBG("");
+
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
+			HAL_OP_GATT_SERVER_SEND_RESPONSE, HAL_STATUS_FAILED);
+}
+
+static const struct ipc_handler cmd_handlers[] = {
+	/* HAL_OP_GATT_CLIENT_REGISTER */
+	{handle_client_register, false,
+				sizeof(struct hal_cmd_gatt_client_register)},
+	/* HAL_OP_GATT_CLIENT_UNREGISTER */
+	{handle_client_unregister, false,
+				sizeof(struct hal_cmd_gatt_client_unregister)},
+	/* HAL_OP_GATT_CLIENT_SCAN */
+	{handle_client_scan, false,
+				sizeof(struct hal_cmd_gatt_client_scan)},
+	/* HAL_OP_GATT_CLIENT_CONNECT */
+	{handle_client_connect, false,
+				sizeof(struct hal_cmd_gatt_client_connect)},
+	/* HAL_OP_GATT_CLIENT_DISCONNECT */
+	{handle_client_disconnect, false,
+				sizeof(struct hal_cmd_gatt_client_disconnect)},
+	/* HAL_OP_GATT_CLIENT_LISTEN */
+	{handle_client_listen, false,
+				sizeof(struct hal_cmd_gatt_client_listen)},
+	/* HAL_OP_GATT_CLIENT_REFRESH */
+	{handle_client_refresh, false,
+				sizeof(struct hal_cmd_gatt_client_refresh)},
+	/* HAL_OP_GATT_CLIENT_SEARCH_SERVICE */
+	{handle_client_search_service, true,
+			sizeof(struct hal_cmd_gatt_client_search_service)},
+	/* HAL_OP_GATT_CLIENT_GET_INCLUDED_SERVICE */
+	{handle_client_get_included_service, true,
+		sizeof(struct hal_cmd_gatt_client_get_included_service)},
+	/* HAL_OP_GATT_CLIENT_GET_CHARACTERISTIC */
+	{handle_client_get_characteristic, true,
+			sizeof(struct hal_cmd_gatt_client_get_characteristic)},
+	/* HAL_OP_GATT_CLIENT_GET_DESCRIPTOR */
+	{handle_client_get_descriptor, true,
+			sizeof(struct hal_cmd_gatt_client_get_descriptor)},
+	/* HAL_OP_GATT_CLIENT_READ_CHARACTERISTIC */
+	{handle_client_read_characteristic, false,
+			sizeof(struct hal_cmd_gatt_client_read_characteristic)},
+	/* HAL_OP_GATT_CLIENT_WRITE_CHARACTERISTIC */
+	{handle_client_write_characteristic, true,
+		sizeof(struct hal_cmd_gatt_client_write_characteristic)},
+	/* HAL_OP_GATT_CLIENT_READ_DESCRIPTOR */
+	{handle_client_read_descriptor, false,
+			sizeof(struct hal_cmd_gatt_client_read_descriptor)},
+	/* HAL_OP_GATT_CLIENT_WRITE_DESCRIPTOR */
+	{handle_client_write_descriptor, true,
+			sizeof(struct hal_cmd_gatt_client_write_descriptor)},
+	/* HAL_OP_GATT_CLIENT_EXECUTE_WRITE */
+	{handle_client_execute_write, false,
+			sizeof(struct hal_cmd_gatt_client_execute_write)},
+	/* HAL_OP_GATT_CLIENT_REGISTER_FOR_NOTIFICATION */
+	{handle_client_register_for_notification, false,
+		sizeof(struct hal_cmd_gatt_client_register_for_notification)},
+	/* HAL_OP_GATT_CLIENT_DEREGISTER_FOR_NOTIFICATION */
+	{handle_client_deregister_for_notification, false,
+		sizeof(struct hal_cmd_gatt_client_deregister_for_notification)},
+	/* HAL_OP_GATT_CLIENT_READ_REMOTE_RSSI */
+	{handle_client_read_remote_rssi, false,
+			sizeof(struct hal_cmd_gatt_client_read_remote_rssi)},
+	/* HAL_OP_GATT_CLIENT_GET_DEVICE_TYPE */
+	{handle_client_get_device_type, false,
+			sizeof(struct hal_cmd_gatt_client_get_device_type)},
+	/* HAL_OP_GATT_CLIENT_SET_ADV_DATA */
+	{handle_client_set_adv_data, true,
+			sizeof(struct hal_cmd_gatt_client_set_adv_data)},
+	/* HAL_OP_GATT_CLIENT_TEST_COMMAND */
+	{handle_client_test_command, false,
+			sizeof(struct hal_cmd_gatt_client_test_command)},
+	/* HAL_OP_GATT_SERVER_REGISTER */
+	{handle_server_register, false,
+				sizeof(struct hal_cmd_gatt_server_register)},
+	/* HAL_OP_GATT_SERVER_UNREGISTER */
+	{handle_server_unregister, false,
+				sizeof(struct hal_cmd_gatt_server_unregister)},
+	/* HAL_OP_GATT_SERVER_CONNECT */
+	{handle_server_connect, false,
+				sizeof(struct hal_cmd_gatt_server_connect)},
+	/* HAL_OP_GATT_SERVER_DISCONNECT */
+	{handle_server_disconnect, false,
+				sizeof(struct hal_cmd_gatt_server_disconnect)},
+	/* HAL_OP_GATT_SERVER_ADD_SERVICE */
+	{handle_server_add_service, false,
+				sizeof(struct hal_cmd_gatt_server_add_service)},
+	/* HAL_OP_GATT_SERVER_ADD_INC_SERVICE */
+	{handle_server_add_included_service, false,
+			sizeof(struct hal_cmd_gatt_server_add_inc_service)},
+	/* HAL_OP_GATT_SERVER_ADD_CHARACTERISTIC */
+	{handle_server_add_characteristic, false,
+			sizeof(struct hal_cmd_gatt_server_add_characteristic)},
+	/* HAL_OP_GATT_SERVER_ADD_DESCRIPTOR */
+	{handle_server_add_descriptor, false,
+			sizeof(struct hal_cmd_gatt_server_add_descriptor)},
+	/* HAL_OP_GATT_SERVER_START_SERVICE */
+	{handle_server_start_service, false,
+			sizeof(struct hal_cmd_gatt_server_start_service)},
+	/* HAL_OP_GATT_SERVER_STOP_SERVICE */
+	{handle_server_stop_service, false,
+			sizeof(struct hal_cmd_gatt_server_stop_service)},
+	/* HAL_OP_GATT_SERVER_DELETE_SERVICE */
+	{handle_server_delete_service, false,
+			sizeof(struct hal_cmd_gatt_server_delete_service)},
+	/* HAL_OP_GATT_SERVER_SEND_INDICATION */
+	{handle_server_send_indication, true,
+			sizeof(struct hal_cmd_gatt_server_send_indication)},
+	/* HAL_OP_GATT_SERVER_SEND_RESPONSE */
+	{handle_server_send_response, true,
+			sizeof(struct hal_cmd_gatt_server_send_response)},
+};
 
 bool bt_gatt_register(struct ipc *ipc, const bdaddr_t *addr)
 {
-	return false;
+	DBG("");
+
+	bacpy(&adapter_addr, addr);
+
+	hal_ipc = ipc;
+
+	ipc_register(hal_ipc, HAL_SERVICE_ID_GATT, cmd_handlers,
+						G_N_ELEMENTS(cmd_handlers));
+
+	return true;
 }
 
 void bt_gatt_unregister(void)
 {
+	DBG("");
 
+	ipc_unregister(hal_ipc, HAL_SERVICE_ID_GATT);
+	hal_ipc = NULL;
 }
-- 
1.8.5.2


^ permalink raw reply related

* [PATCH v2 1/2] android/gatt: Add initial files
From: Grzegorz Kolodziejczyk @ 2014-03-03 14:51 UTC (permalink / raw)
  To: linux-bluetooth

This adds initial daemon code for GATT profile.
---
 android/Android.mk  |  1 +
 android/Makefile.am |  1 +
 android/gatt.c      | 44 ++++++++++++++++++++++++++++++++++++++++++++
 android/gatt.h      | 25 +++++++++++++++++++++++++
 android/main.c      | 14 ++++++++++++++
 5 files changed, 85 insertions(+)
 create mode 100644 android/gatt.c
 create mode 100644 android/gatt.h

diff --git a/android/Android.mk b/android/Android.mk
index 56b86ba..429a4b8 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -42,6 +42,7 @@ LOCAL_SRC_FILES := \
 	bluez/android/avrcp-lib.c \
 	bluez/android/pan.c \
 	bluez/android/handsfree.c \
+	bluez/android/gatt.c
 	bluez/src/log.c \
 	bluez/src/shared/mgmt.c \
 	bluez/src/shared/util.c \
diff --git a/android/Makefile.am b/android/Makefile.am
index 31f905c..6be6cda 100644
--- a/android/Makefile.am
+++ b/android/Makefile.am
@@ -40,6 +40,7 @@ android_bluetoothd_SOURCES = android/main.c \
 				android/socket.h android/socket.c \
 				android/pan.h android/pan.c \
 				android/handsfree.h android/handsfree.c \
+				android/gatt.h android/gatt.c \
 				btio/btio.h btio/btio.c \
 				src/sdp-client.h src/sdp-client.c \
 				profiles/network/bnep.h profiles/network/bnep.c
diff --git a/android/gatt.c b/android/gatt.c
new file mode 100644
index 0000000..f577446
--- /dev/null
+++ b/android/gatt.c
@@ -0,0 +1,44 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2014  Intel Corporation. All rights reserved.
+ *
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library 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
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+#include "ipc.h"
+#include "lib/bluetooth.h"
+#include "gatt.h"
+
+bool bt_gatt_register(struct ipc *ipc, const bdaddr_t *addr)
+{
+	return false;
+}
+
+void bt_gatt_unregister(void)
+{
+
+}
diff --git a/android/gatt.h b/android/gatt.h
new file mode 100644
index 0000000..d4392d9
--- /dev/null
+++ b/android/gatt.h
@@ -0,0 +1,25 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2014  Intel Corporation. All rights reserved.
+ *
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library 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
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+bool bt_gatt_register(struct ipc *ipc, const bdaddr_t *addr);
+void bt_gatt_unregister(void);
diff --git a/android/main.c b/android/main.c
index a6742ef..104211a 100644
--- a/android/main.c
+++ b/android/main.c
@@ -58,6 +58,7 @@
 #include "pan.h"
 #include "avrcp.h"
 #include "handsfree.h"
+#include "gatt.h"
 
 #define STARTUP_GRACE_SECONDS 5
 #define SHUTDOWN_GRACE_SECONDS 10
@@ -126,6 +127,13 @@ static void service_register(const void *buf, uint16_t len)
 		}
 
 		break;
+	case HAL_SERVICE_ID_GATT:
+		if (!bt_gatt_register(hal_ipc, &adapter_bdaddr)) {
+			status = HAL_STATUS_FAILED;
+			goto failed;
+		}
+
+		break;
 	default:
 		DBG("service %u not supported", m->service_id);
 		status = HAL_STATUS_FAILED;
@@ -175,6 +183,9 @@ static void service_unregister(const void *buf, uint16_t len)
 	case HAL_SERVICE_ID_HANDSFREE:
 		bt_handsfree_unregister();
 		break;
+	case HAL_SERVICE_ID_GATT:
+		bt_gatt_unregister();
+		break;
 	default:
 		/* This would indicate bug in HAL, as unregister should not be
 		 * called in init failed */
@@ -371,6 +382,9 @@ static void cleanup_services(void)
 		case HAL_SERVICE_ID_HANDSFREE:
 			bt_handsfree_unregister();
 			break;
+		case HAL_SERVICE_ID_GATT:
+			bt_gatt_unregister();
+			break;
 		}
 
 		services[i] = false;
-- 
1.8.5.2


^ permalink raw reply related

* Re: [PATCH 2/2] android/gatt: Add stubs for GATT commands handlers
From: Szymon Janc @ 2014-03-03 14:41 UTC (permalink / raw)
  To: Grzegorz Kolodziejczyk; +Cc: linux-bluetooth
In-Reply-To: <1393838957-26880-2-git-send-email-grzegorz.kolodziejczyk@tieto.com>

Hi Grzegorz,

On Monday 03 of March 2014 10:29:17 Grzegorz Kolodziejczyk wrote:
> Add empty handlers for GATT IPC commands.
> ---
>  android/gatt.c | 414 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 413 insertions(+), 1 deletion(-)
> 
> diff --git a/android/gatt.c b/android/gatt.c
> index f577446..7a01d15 100644
> --- a/android/gatt.c
> +++ b/android/gatt.c
> @@ -28,17 +28,429 @@
>  #include <stdbool.h>
>  #include <stdlib.h>
>  #include <stdint.h>
> +#include <glib.h>
>  
>  #include "ipc.h"
>  #include "lib/bluetooth.h"
>  #include "gatt.h"
> +#include "src/log.h"
> +#include "hal-msg.h"
> +
> +static struct ipc *hal_ipc = NULL;
> +static bdaddr_t adapter_addr;
> +
> +static void handle_client_register(const void *buf, uint16_t len)
> +{
> +	DBG("");
> +
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT, HAL_OP_GATT_CLIENT_REGISTER,
> +							HAL_STATUS_FAILED);
> +}
> +
> +static void handle_client_unregister(const void *buf, uint16_t len)
> +{
> +	DBG("");
> +
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
> +			HAL_OP_GATT_CLIENT_UNREGISTER, HAL_STATUS_FAILED);
> +}
> +
> +static void handle_client_scan(const void *buf, uint16_t len)
> +{
> +	DBG("");
> +
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT, HAL_OP_GATT_CLIENT_SCAN,
> +							HAL_STATUS_FAILED);
> +}
> +
> +static void handle_client_connect(const void *buf, uint16_t len)
> +{
> +	DBG("");
> +
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT, HAL_OP_GATT_CLIENT_CONNECT,
> +							HAL_STATUS_FAILED);
> +}
> +
> +static void handle_client_disconnect(const void *buf, uint16_t len)
> +{
> +	DBG("");
> +
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
> +			HAL_OP_GATT_CLIENT_DISCONNECT, HAL_STATUS_FAILED);
> +}
> +
> +static void handle_client_listen(const void *buf, uint16_t len)
> +{
> +	DBG("");
> +
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT, HAL_OP_GATT_CLIENT_LISTEN,
> +							HAL_STATUS_FAILED);
> +}
> +
> +static void handle_client_refresh(const void *buf, uint16_t len)
> +{
> +	DBG("");
> +
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT, HAL_OP_GATT_CLIENT_REFRESH,
> +							HAL_STATUS_FAILED);
> +}
> +
> +static void handle_client_search_service(const void *buf, uint16_t len)
> +{
> +	DBG("");
> +
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
> +			HAL_OP_GATT_CLIENT_SEARCH_SERVICE, HAL_STATUS_FAILED);
> +}
> +
> +static void handle_client_get_included_service(const void *buf, uint16_t len)
> +{
> +	DBG("");
> +
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
> +					HAL_OP_GATT_CLIENT_GET_INCLUDED_SERVICE,
> +					HAL_STATUS_FAILED);
> +}
> +
> +static void handle_client_get_characteristic(const void *buf, uint16_t len)
> +{
> +	DBG("");
> +
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
> +					HAL_OP_GATT_CLIENT_GET_CHARACTERISTIC,
> +					HAL_STATUS_FAILED);
> +}
> +
> +static void handle_client_get_descriptor(const void *buf, uint16_t len)
> +{
> +	DBG("");
> +
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
> +			HAL_OP_GATT_CLIENT_GET_DESCRIPTOR, HAL_STATUS_FAILED);
> +}
> +
> +static void handle_client_read_characteristic(const void *buf, uint16_t len)
> +{
> +	DBG("");
> +
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
> +					HAL_OP_GATT_CLIENT_READ_CHARACTERISTIC,
> +					HAL_STATUS_FAILED);
> +}
> +
> +static void handle_client_write_characteristic(const void *buf, uint16_t len)
> +{
> +	DBG("");
> +
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
> +					HAL_OP_GATT_CLIENT_WRITE_CHARACTERISTIC,
> +					HAL_STATUS_FAILED);
> +}
> +
> +static void handle_client_read_descriptor(const void *buf, uint16_t len)
> +{
> +	DBG("");
> +
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
> +			HAL_OP_GATT_CLIENT_READ_DESCRIPTOR, HAL_STATUS_FAILED);
> +}
> +
> +static void handle_client_write_descriptor(const void *buf, uint16_t len)
> +{
> +	DBG("");
> +
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
> +			HAL_OP_GATT_CLIENT_WRITE_DESCRIPTOR, HAL_STATUS_FAILED);
> +}
> +
> +static void handle_client_execute_write(const void *buf, uint16_t len)
> +{
> +	DBG("");
> +
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
> +			HAL_OP_GATT_CLIENT_EXECUTE_WRITE, HAL_STATUS_FAILED);
> +}
> +
> +static void handle_client_register_for_notification(const void *buf,
> +								uint16_t len)
> +{
> +	DBG("");
> +
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
> +				HAL_OP_GATT_CLIENT_REGISTER_FOR_NOTIFICATION,
> +				HAL_STATUS_FAILED);
> +}
> +
> +static void handle_client_deregister_for_notification(const void *buf,
> +								uint16_t len)
> +{
> +	DBG("");
> +
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
> +				HAL_OP_GATT_CLIENT_DEREGISTER_FOR_NOTIFICATION,
> +				HAL_STATUS_FAILED);
> +}
> +
> +static void handle_client_read_remote_rssi(const void *buf, uint16_t len)
> +{
> +	DBG("");
> +
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
> +			HAL_OP_GATT_CLIENT_READ_REMOTE_RSSI, HAL_STATUS_FAILED);
> +}
> +
> +static void handle_client_get_device_type(const void *buf, uint16_t len)
> +{
> +	DBG("");
> +
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
> +			HAL_OP_GATT_CLIENT_GET_DEVICE_TYPE, HAL_STATUS_FAILED);
> +}
> +
> +static void handle_client_set_adv_data(const void *buf, uint16_t len)
> +{
> +	DBG("");
> +
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
> +			HAL_OP_GATT_CLIENT_SET_ADV_DATA, HAL_STATUS_FAILED);
> +}
> +
> +static void handle_client_test_command(const void *buf, uint16_t len)
> +{
> +	DBG("");
> +
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
> +			HAL_OP_GATT_CLIENT_TEST_COMMAND, HAL_STATUS_FAILED);
> +}
> +
> +static void handle_server_register(const void *buf, uint16_t len)
> +{
> +	DBG("");
> +
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT, HAL_OP_GATT_SERVER_REGISTER,
> +							HAL_STATUS_FAILED);
> +}
> +
> +static void handle_server_unregister(const void *buf, uint16_t len)
> +{
> +	DBG("");
> +
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
> +			HAL_OP_GATT_SERVER_UNREGISTER, HAL_STATUS_FAILED);
> +}
> +
> +static void handle_server_connect(const void *buf, uint16_t len)
> +{
> +	DBG("");
> +
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT, HAL_OP_GATT_SERVER_CONNECT,
> +							HAL_STATUS_FAILED);
> +}
> +
> +static void handle_server_disconnect(const void *buf, uint16_t len)
> +{
> +	DBG("");
> +
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
> +			HAL_OP_GATT_SERVER_DISCONNECT, HAL_STATUS_FAILED);
> +}
> +
> +static void handle_server_add_service(const void *buf, uint16_t len)
> +{
> +	DBG("");
> +
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
> +			HAL_OP_GATT_SERVER_ADD_SERVICE, HAL_STATUS_FAILED);
> +}
> +
> +static void handle_server_add_included_service(const void *buf, uint16_t len)
> +{
> +	DBG("");
> +
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
> +			HAL_OP_GATT_SERVER_ADD_INC_SERVICE, HAL_STATUS_FAILED);
> +}
> +
> +static void handle_server_add_characteristic(const void *buf, uint16_t len)
> +{
> +	DBG("");
> +
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
> +					HAL_OP_GATT_SERVER_ADD_CHARACTERISTIC,
> +					HAL_STATUS_FAILED);
> +}
> +
> +static void handle_server_add_descriptor(const void *buf, uint16_t len)
> +{
> +	DBG("");
> +
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
> +			HAL_OP_GATT_SERVER_ADD_DESCRIPTOR, HAL_STATUS_FAILED);
> +}
> +
> +static void handle_server_start_service(const void *buf, uint16_t len)
> +{
> +	DBG("");
> +
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
> +			HAL_OP_GATT_SERVER_START_SERVICE, HAL_STATUS_FAILED);
> +}
> +
> +static void handle_server_stop_service(const void *buf, uint16_t len)
> +{
> +	DBG("");
> +
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
> +			HAL_OP_GATT_SERVER_STOP_SERVICE, HAL_STATUS_FAILED);
> +}
> +
> +static void handle_server_delete_service(const void *buf, uint16_t len)
> +{
> +	DBG("");
> +
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
> +			HAL_OP_GATT_SERVER_DELETE_SERVICE, HAL_STATUS_FAILED);
> +}
> +
> +static void handle_server_send_indication(const void *buf, uint16_t len)
> +{
> +	DBG("");
> +
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
> +			HAL_OP_GATT_SERVER_SEND_INDICATION, HAL_STATUS_FAILED);
> +}
> +
> +static void handle_server_send_response(const void *buf, uint16_t len)
> +{
> +	DBG("");
> +
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
> +			HAL_OP_GATT_SERVER_SEND_RESPONSE, HAL_STATUS_FAILED);
> +}
> +
> +static const struct ipc_handler cmd_handlers[] = {
> +	/* HAL_OP_GATT_CLIENT_REGISTER */
> +	{handle_client_register, false,
> +				sizeof(struct hal_cmd_gatt_client_register)},
> +	/* HAL_OP_GATT_CLIENT_UNREGISTER */
> +	{handle_client_unregister, false,
> +				sizeof(struct hal_cmd_gatt_client_unregister)},
> +	/* HAL_OP_GATT_CLIENT_SCAN */
> +	{handle_client_scan, false,
> +				sizeof(struct hal_cmd_gatt_client_scan)},
> +	/* HAL_OP_GATT_CLIENT_CONNECT */
> +	{handle_client_connect, false,
> +				sizeof(struct hal_cmd_gatt_client_connect)},
> +	/* HAL_OP_GATT_CLIENT_DISCONNECT */
> +	{handle_client_disconnect, false,
> +				sizeof(struct hal_cmd_gatt_client_disconnect)},
> +	/* HAL_OP_GATT_CLIENT_LISTEN */
> +	{handle_client_listen, false,
> +				sizeof(struct hal_cmd_gatt_client_listen)},
> +	/* HAL_OP_GATT_CLIENT_REFRESH */
> +	{handle_client_refresh, false,
> +				sizeof(struct hal_cmd_gatt_client_refresh)},
> +	/* HAL_OP_GATT_CLIENT_SEARCH_SERVICE */
> +	{handle_client_search_service, true,
> +			sizeof(struct hal_cmd_gatt_client_search_service)},
> +	/* HAL_OP_GATT_CLIENT_GET_INCLUDED_SERVICE */
> +	{handle_client_get_included_service, true,
> +		sizeof(struct hal_cmd_gatt_client_get_included_service)},
> +	/* HAL_OP_GATT_CLIENT_GET_CHARACTERISTIC */
> +	{handle_client_get_characteristic, true,
> +			sizeof(struct hal_cmd_gatt_client_get_characteristic)},
> +	/* HAL_OP_GATT_CLIENT_GET_DESCRIPTOR */
> +	{handle_client_get_descriptor, true,
> +			sizeof(struct hal_cmd_gatt_client_get_descriptor)},
> +	/* HAL_OP_GATT_CLIENT_READ_CHARACTERISTIC */
> +	{handle_client_read_characteristic, false,
> +			sizeof(struct hal_cmd_gatt_client_read_characteristic)},
> +	/* HAL_OP_GATT_CLIENT_WRITE_CHARACTERISTIC */
> +	{handle_client_write_characteristic, true,
> +		sizeof(struct hal_cmd_gatt_client_write_characteristic)},
> +	/* HAL_OP_GATT_CLIENT_READ_DESCRIPTOR */
> +	{handle_client_read_descriptor, false,
> +			sizeof(struct hal_cmd_gatt_client_read_descriptor)},
> +	/* HAL_OP_GATT_CLIENT_WRITE_DESCRIPTOR */
> +	{handle_client_write_descriptor, true,
> +			sizeof(struct hal_cmd_gatt_client_write_descriptor)},
> +	/* HAL_OP_GATT_CLIENT_EXECUTE_WRITE */
> +	{handle_client_execute_write, false,
> +			sizeof(struct hal_cmd_gatt_client_execute_write)},
> +	/* HAL_OP_GATT_CLIENT_REGISTER_FOR_NOTIFICATION */
> +	{handle_client_register_for_notification, false,
> +		sizeof(struct hal_cmd_gatt_client_register_for_notification)},
> +	/* HAL_OP_GATT_CLIENT_DEREGISTER_FOR_NOTIFICATION */
> +	{handle_client_deregister_for_notification, false,
> +		sizeof(struct hal_cmd_gatt_client_deregister_for_notification)},
> +	/* HAL_OP_GATT_CLIENT_READ_REMOTE_RSSI */
> +	{handle_client_read_remote_rssi, false,
> +			sizeof(struct hal_cmd_gatt_client_read_remote_rssi)},
> +	/* HAL_OP_GATT_CLIENT_GET_DEVICE_TYPE */
> +	{handle_client_get_device_type, false,
> +			sizeof(struct hal_cmd_gatt_client_get_device_type)},
> +	/* HAL_OP_GATT_CLIENT_SET_ADV_DATA */
> +	{handle_client_set_adv_data, true,
> +			sizeof(struct hal_cmd_gatt_client_set_adv_data)},
> +	/* HAL_OP_GATT_CLIENT_TEST_COMMAND */
> +	{handle_client_test_command, false,
> +			sizeof(struct hal_cmd_gatt_client_test_command)},
> +	/* HAL_OP_GATT_SERVER_REGISTER */
> +	{handle_server_register, false,
> +				sizeof(struct hal_cmd_gatt_server_register)},
> +	/* HAL_OP_GATT_SERVER_UNREGISTER */
> +	{handle_server_unregister, false,
> +				sizeof(struct hal_cmd_gatt_server_unregister)},
> +	/* HAL_OP_GATT_SERVER_CONNECT */
> +	{handle_server_connect, false,
> +				sizeof(struct hal_cmd_gatt_server_connect)},
> +	/* HAL_OP_GATT_SERVER_DISCONNECT */
> +	{handle_server_disconnect, false,
> +				sizeof(struct hal_cmd_gatt_server_disconnect)},
> +	/* HAL_OP_GATT_SERVER_ADD_SERVICE */
> +	{handle_server_add_service, false,
> +				sizeof(struct hal_cmd_gatt_server_add_service)},
> +	/* HAL_OP_GATT_SERVER_ADD_INC_SERVICE */
> +	{handle_server_add_included_service, false,
> +			sizeof(struct hal_cmd_gatt_server_add_inc_service)},
> +	/* HAL_OP_GATT_SERVER_ADD_CHARACTERISTIC */
> +	{handle_server_add_characteristic, false,
> +			sizeof(struct hal_cmd_gatt_server_add_characteristic)},
> +	/* HAL_OP_GATT_SERVER_ADD_DESCRIPTOR */
> +	{handle_server_add_descriptor, false,
> +			sizeof(struct hal_cmd_gatt_server_add_descriptor)},
> +	/* HAL_OP_GATT_SERVER_START_SERVICE */
> +	{handle_server_start_service, false,
> +			sizeof(struct hal_cmd_gatt_server_start_service)},
> +	/* HAL_OP_GATT_SERVER_STOP_SERVICE */
> +	{handle_server_stop_service, false,
> +			sizeof(struct hal_cmd_gatt_server_stop_service)},
> +	/* HAL_OP_GATT_SERVER_DELETE_SERVICE */
> +	{handle_server_delete_service, false,
> +			sizeof(struct hal_cmd_gatt_server_delete_service)},
> +	/* HAL_OP_GATT_SERVER_SEND_INDICATION */
> +	{handle_server_send_indication, true,
> +			sizeof(struct hal_cmd_gatt_server_send_indication)},
> +	/* HAL_OP_GATT_SERVER_SEND_RESPONSE */
> +	{handle_server_send_response, true,
> +			sizeof(struct hal_cmd_gatt_server_send_response)},
> +};
>  
>  bool bt_gatt_register(struct ipc *ipc, const bdaddr_t *addr)
>  {
> -	return false;
> +	DBG("");
> +
> +	bacpy(&adapter_addr, addr);
> +

This seems to be missing:
hal_ipc = hal;

> +	ipc_register(hal_ipc, HAL_SERVICE_ID_GATT, cmd_handlers,
> +						G_N_ELEMENTS(cmd_handlers));
> +
> +	return true;
>  }
>  
>  void bt_gatt_unregister(void)
>  {
> +	DBG("");
>  
> +	ipc_unregister(hal_ipc, HAL_SERVICE_ID_GATT);
>  }
> 

-- 
Best regards, 
Szymon Janc

^ permalink raw reply

* Re: [PATCH 1/2] android/gatt: Add initial files
From: Szymon Janc @ 2014-03-03 14:39 UTC (permalink / raw)
  To: Grzegorz Kolodziejczyk; +Cc: linux-bluetooth
In-Reply-To: <1393838957-26880-1-git-send-email-grzegorz.kolodziejczyk@tieto.com>

Hi Grzegorz,

On Monday 03 of March 2014 10:29:16 Grzegorz Kolodziejczyk wrote:
> This adds initial daemon code for GATT profile.
> ---
>  android/Android.mk  |  1 +
>  android/Makefile.am |  1 +
>  android/gatt.c      | 44 ++++++++++++++++++++++++++++++++++++++++++++
>  android/gatt.h      | 25 +++++++++++++++++++++++++
>  android/main.c      | 13 +++++++++++++
>  5 files changed, 84 insertions(+)
>  create mode 100644 android/gatt.c
>  create mode 100644 android/gatt.h
> 
> diff --git a/android/Android.mk b/android/Android.mk
> index 56b86ba..429a4b8 100644
> --- a/android/Android.mk
> +++ b/android/Android.mk
> @@ -42,6 +42,7 @@ LOCAL_SRC_FILES := \
>  	bluez/android/avrcp-lib.c \
>  	bluez/android/pan.c \
>  	bluez/android/handsfree.c \
> +	bluez/android/gatt.c
>  	bluez/src/log.c \
>  	bluez/src/shared/mgmt.c \
>  	bluez/src/shared/util.c \
> diff --git a/android/Makefile.am b/android/Makefile.am
> index 31f905c..6be6cda 100644
> --- a/android/Makefile.am
> +++ b/android/Makefile.am
> @@ -40,6 +40,7 @@ android_bluetoothd_SOURCES = android/main.c \
>  				android/socket.h android/socket.c \
>  				android/pan.h android/pan.c \
>  				android/handsfree.h android/handsfree.c \
> +				android/gatt.h android/gatt.c \
>  				btio/btio.h btio/btio.c \
>  				src/sdp-client.h src/sdp-client.c \
>  				profiles/network/bnep.h profiles/network/bnep.c
> diff --git a/android/gatt.c b/android/gatt.c
> new file mode 100644
> index 0000000..f577446
> --- /dev/null
> +++ b/android/gatt.c
> @@ -0,0 +1,44 @@
> +/*
> + *
> + *  BlueZ - Bluetooth protocol stack for Linux
> + *
> + *  Copyright (C) 2014  Intel Corporation. All rights reserved.
> + *
> + *
> + *  This library is free software; you can redistribute it and/or
> + *  modify it under the terms of the GNU Lesser General Public
> + *  License as published by the Free Software Foundation; either
> + *  version 2.1 of the License, or (at your option) any later version.
> + *
> + *  This library 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
> + *  Lesser General Public License for more details.
> + *
> + *  You should have received a copy of the GNU Lesser General Public
> + *  License along with this library; if not, write to the Free Software
> + *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
> + *
> + */
> +
> +#ifdef HAVE_CONFIG_H
> +#include <config.h>
> +#endif
> +
> +#include <stdbool.h>
> +#include <stdlib.h>
> +#include <stdint.h>
> +
> +#include "ipc.h"
> +#include "lib/bluetooth.h"
> +#include "gatt.h"
> +
> +bool bt_gatt_register(struct ipc *ipc, const bdaddr_t *addr)
> +{
> +	return false;

Indentation issue here.

> +}
> +
> +void bt_gatt_unregister(void)
> +{
> +
> +}
> diff --git a/android/gatt.h b/android/gatt.h
> new file mode 100644
> index 0000000..d4392d9
> --- /dev/null
> +++ b/android/gatt.h
> @@ -0,0 +1,25 @@
> +/*
> + *
> + *  BlueZ - Bluetooth protocol stack for Linux
> + *
> + *  Copyright (C) 2014  Intel Corporation. All rights reserved.
> + *
> + *
> + *  This library is free software; you can redistribute it and/or
> + *  modify it under the terms of the GNU Lesser General Public
> + *  License as published by the Free Software Foundation; either
> + *  version 2.1 of the License, or (at your option) any later version.
> + *
> + *  This library 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
> + *  Lesser General Public License for more details.
> + *
> + *  You should have received a copy of the GNU Lesser General Public
> + *  License along with this library; if not, write to the Free Software
> + *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
> + *
> + */
> +
> +bool bt_gatt_register(struct ipc *ipc, const bdaddr_t *addr);
> +void bt_gatt_unregister(void);
> diff --git a/android/main.c b/android/main.c
> index a6742ef..7b5ca9c 100644
> --- a/android/main.c
> +++ b/android/main.c
> @@ -58,6 +58,7 @@
>  #include "pan.h"
>  #include "avrcp.h"
>  #include "handsfree.h"
> +#include "gatt.h"
>  
>  #define STARTUP_GRACE_SECONDS 5
>  #define SHUTDOWN_GRACE_SECONDS 10
> @@ -125,6 +126,12 @@ static void service_register(const void *buf, uint16_t len)
>  			goto failed;
>  		}
>  

Break is missing here.

> +	case HAL_SERVICE_ID_GATT:
> +		if (!bt_gatt_register(hal_ipc, &adapter_bdaddr)) {
> +			status = HAL_STATUS_FAILED;
> +			goto failed;
> +		}
> +
>  		break;
>  	default:
>  		DBG("service %u not supported", m->service_id);
> @@ -175,6 +182,9 @@ static void service_unregister(const void *buf, uint16_t len)
>  	case HAL_SERVICE_ID_HANDSFREE:
>  		bt_handsfree_unregister();
>  		break;
> +	case HAL_SERVICE_ID_GATT:
> +		bt_gatt_unregister();
> +		break;
>  	default:
>  		/* This would indicate bug in HAL, as unregister should not be
>  		 * called in init failed */
> @@ -371,6 +381,9 @@ static void cleanup_services(void)
>  		case HAL_SERVICE_ID_HANDSFREE:
>  			bt_handsfree_unregister();
>  			break;
> +		case HAL_SERVICE_ID_GATT:
> +			bt_gatt_unregister();
> +			break;
>  		}
>  
>  		services[i] = false;
> 

-- 
Best regards, 
Szymon Janc

^ permalink raw reply

* Re: [PATCH v2] android/avrcp-lib: Fix destroy callback handling
From: Luiz Augusto von Dentz @ 2014-03-03 14:16 UTC (permalink / raw)
  To: Szymon Janc; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <1393842906-5883-1-git-send-email-szymon.janc@tieto.com>

Hi Szymon,

On Mon, Mar 3, 2014 at 12:35 PM, Szymon Janc <szymon.janc@tieto.com> wrote:
> AVRCP destroy callback was directly passed as AVCTP destroy callback
> resulting in struct avrcp not being freed on remote disconnect.
>
> This fix following Valgrind report:
>
> 931 (36 direct, 895 indirect) bytes in 1 blocks are definitely lost in
>      loss record 53 of 55
>    at 0x4896DC8: calloc (in /system/lib/valgrind/
>      vgpreload_memcheck-arm-linux.so)
>    by 0x48C5DB7: g_malloc0 (gmem.c:189)
>    by 0x118671: avrcp_new (avrcp-lib.c:219)
>    by 0x117D4F: connect_cb (avrcp.c:346)
>    by 0x12068B: connect_cb (btio.c:232)
>    by 0x48BD9C7: g_io_unix_dispatch (giounix.c:166)
>    by 0x48C2CCB: g_main_context_dispatch (gmain.c:2539)
>    by 0x48C2ED9: g_main_context_iterate.isra.19 (gmain.c:3146)
>    by 0x48C3167: g_main_loop_run (gmain.c:3340)
>    by 0x10BA03: main (main.c:490)
> ---
>
> v2: fix crash on local shutdown due to double call to avrcp_shutdown,
>     now avctp destroy callback is cleared when shuting down localy.
>
>  android/avrcp-lib.c | 23 ++++++++++++++++++++++-
>  1 file changed, 22 insertions(+), 1 deletion(-)
>
> diff --git a/android/avrcp-lib.c b/android/avrcp-lib.c
> index 26bcce1..c5cfa12 100644
> --- a/android/avrcp-lib.c
> +++ b/android/avrcp-lib.c
> @@ -98,6 +98,9 @@ struct avrcp {
>         const struct avrcp_passthrough_handler *passthrough_handlers;
>         void *passthrough_data;
>         unsigned int passthrough_id;
> +
> +       avrcp_destroy_cb_t destroy;
> +       void *destroy_data;
>  };
>
>  void avrcp_shutdown(struct avrcp *session)
> @@ -109,9 +112,15 @@ void avrcp_shutdown(struct avrcp *session)
>                 if (session->passthrough_id > 0)
>                         avctp_unregister_passthrough_handler(session->conn,
>                                                 session->passthrough_id);
> +
> +               /* clear destroy callback that would call shutdown again */
> +               avctp_set_destroy_cb(session->conn, NULL, NULL);
>                 avctp_shutdown(session->conn);
>         }
>
> +       if (session->destroy)
> +               session->destroy(session->destroy_data);
> +
>         g_free(session->tx_buf);
>         g_free(session);
>  }
> @@ -199,6 +208,15 @@ static bool handle_passthrough_pdu(struct avctp *conn, uint8_t op,
>         return handler->func(session);
>  }
>
> +static void disconnect_cb(void *data)
> +{
> +       struct avrcp *session = data;
> +
> +       session->conn = NULL;
> +
> +       avrcp_shutdown(session);
> +}
> +
>  struct avrcp *avrcp_new(int fd, size_t imtu, size_t omtu, uint16_t version)
>  {
>         struct avrcp *session;
> @@ -223,13 +241,16 @@ struct avrcp *avrcp_new(int fd, size_t imtu, size_t omtu, uint16_t version)
>                                                         handle_vendordep_pdu,
>                                                         session);
>
> +       avctp_set_destroy_cb(session->conn, disconnect_cb, session);
> +
>         return session;
>  }
>
>  void avrcp_set_destroy_cb(struct avrcp *session, avrcp_destroy_cb_t cb,
>                                                         void *user_data)
>  {
> -       avctp_set_destroy_cb(session->conn, cb, user_data);
> +       session->destroy = cb;
> +       session->destroy_data = user_data;
>  }
>
>  void avrcp_set_control_handlers(struct avrcp *session,
> --
> 1.8.5.3

Pushed, thanks.


-- 
Luiz Augusto von Dentz

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox