2013-10-07 07:38:01

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCHv1 00/15] Basic code for Android BlueZ

From: Andrei Emeltchenko <[email protected]>

Skeletons for Android Bluetooth and Socket HALs and BlueZ daemon.

Note: Still need rebase after patches from Frederic are applied.

Changes:
* PATCHv1: Rebased against applied fdanis patch set, moved SDP init from
adapter start to daemon start, other minor fixes.
* RFCv3: Rebased against recent FDanis patch set, fixed library build,
corrected process capabilities, corrected API header.
* RFCv2: Took comments from mailing list reviewers. Use single
makefile, remove mgmt library and directly link, remove adapter
code and use default_adapter pointer and other style changes.
Dropped some patches due to major changes.

Andrei Emeltchenko (15):
android: Supress missing initializers warnings
android: Add Adapter Bluetooth HAL template
android: Add Socket Bluetooth HAL template
android: Enable Socket interface
android: Start Android Bluetooth daemon
android: Add basic mgmt initialization sequence
android: Create HAL API header skeleton
android: Add adapter and device struct for BlueZ daemon
android: Add Android Makefile for libbluetooth
android: sdp: Reuse BlueZ SDP server in Android
android: Add cap to bind to port < 1024
android: Implement read_info_complete callback
android: Handle mgmt changed events
android: Add makefile for hciconfig
android: Add makefile for hcitool

Makefile.android | 9 +-
android/Android.mk | 166 +++++++++++++++
android/bt_adapter.c | 54 +++++
android/bt_adapter.h | 60 ++++++
android/hal.h | 18 ++
android/hal_bluetooth.c | 411 +++++++++++++++++++++++++++++++++++++
android/hal_bt_sock.c | 84 ++++++++
android/hal_msg.h | 255 +++++++++++++++++++++++
android/main.c | 521 +++++++++++++++++++++++++++++++++++++++++++++++
configure.ac | 4 +
10 files changed, 1580 insertions(+), 2 deletions(-)
create mode 100644 android/bt_adapter.c
create mode 100644 android/bt_adapter.h
create mode 100644 android/hal.h
create mode 100644 android/hal_bluetooth.c
create mode 100644 android/hal_bt_sock.c
create mode 100644 android/hal_msg.h

--
1.7.10.4



2013-10-14 13:39:29

by Michal Labedzki

[permalink] [raw]
Subject: Re: [PATCHv3 14/15] android: Add makefile for hciconfig

Hello Andrei,

If you want to have support for new format of BNSNOOP in Wireshark please
create new bug/feature request on Wireshark bugzilla:
https://bugs.wireshark.org/bugzilla/buglist.cgi?resolution=---&query_format=advanced&list_id=10586
Please attach example trace file(s).

Also if anyone known a bug in Wireshark or need new feature please use
bugzilla too.

There is a second way to sniffing Bluetooth with Wireshark: if you have two
Bluetooth USB dongles then you can sniffing over USB (optionally filtering
by "hci_usb" {+ is SCO in logs; - is that only for USB devices}).


By the way: Wireshark can support BlueZ BTSNOOP format, but btmon can
support "pcap" or "pcapng" format too. Most similar tools use them.

PS. Wireshark seems to decode whole Bluetooth stack, also tshark can be
replacement for your btmon.


Pozdrawiam / Best regards
-------------------------------------------------------------------------------------------------------------
Michał Łabędzki, Software Engineer
Tieto Corporation

Product Development Services
http://www.tieto.com / http://www.tieto.pl
---
ASCII: Michal Labedzki
location: Swobodna 1 Street, 50-088 Wrocław, Poland
room: 5.01 (desk next to 5.08)
---
Please note: The information contained in this message may be legally
privileged and confidential and protected from disclosure. If the reader of
this message is not the intended recipient, you are hereby notified that
any unauthorised use, distribution or copying of this communication is
strictly prohibited. If you have received this communication in error,
please notify us immediately by replying to the message and deleting it
from your computer. Thank You.
---
Please consider the environment before printing this e-mail.
---
Tieto Poland spółka z ograniczoną odpowiedzialnością z siedzibą w
Szczecinie, ul. Malczewskiego 26. Zarejestrowana w Sądzie Rejonowym
Szczecin-Centrum w Szczecinie, XIII Wydział Gospodarczy Krajowego Rejestru
Sądowego pod numerem 0000124858. NIP: 8542085557. REGON: 812023656. Kapitał
zakładowy: 4 271500 PLN

2013-10-14 12:06:11

by Marcel Holtmann

[permalink] [raw]
Subject: Re: [PATCHv3 14/15] android: Add makefile for hciconfig

Hi Andrei,

>>>
>>> ---
>>> android/Android.mk | 34 ++++++++++++++++++++++++++++++++++
>>> 1 file changed, 34 insertions(+)
>>>
>>> diff --git a/android/Android.mk b/android/Android.mk
>>> index e7a70d0..09c4579 100644
>>> --- a/android/Android.mk
>>> +++ b/android/Android.mk
>>> @@ -123,3 +123,37 @@ $(foreach file,$(lib_headers), $(shell ln -sf ../$(file) $(LOCAL_PATH)/../lib/bl
>>> LOCAL_MODULE := libbluetooth
>>>
>>> include $(BUILD_SHARED_LIBRARY)
>>> +
>>> +#
>>> +# hciconfig
>>> +#
>>
>> why are we building this one. Only btmgmt should be needed for testing. If at all.
>>
>
> Can btmon now save packet dump in a format understandable for wireshark?

btmon stores in the new BTSnoop format that allows for multiple controllers in the same trace. If Wireshark does not support these, then that should be fixed in Wireshark.

Regards

Marcel


2013-10-14 11:51:33

by Andrei Emeltchenko

[permalink] [raw]
Subject: Re: [PATCHv3 14/15] android: Add makefile for hciconfig

Hi Marcel,

On Wed, Oct 09, 2013 at 09:59:42PM +0200, Marcel Holtmann wrote:
> Hi Andrei,
>
> >
> > ---
> > android/Android.mk | 34 ++++++++++++++++++++++++++++++++++
> > 1 file changed, 34 insertions(+)
> >
> > diff --git a/android/Android.mk b/android/Android.mk
> > index e7a70d0..09c4579 100644
> > --- a/android/Android.mk
> > +++ b/android/Android.mk
> > @@ -123,3 +123,37 @@ $(foreach file,$(lib_headers), $(shell ln -sf ../$(file) $(LOCAL_PATH)/../lib/bl
> > LOCAL_MODULE := libbluetooth
> >
> > include $(BUILD_SHARED_LIBRARY)
> > +
> > +#
> > +# hciconfig
> > +#
>
> why are we building this one. Only btmgmt should be needed for testing. If at all.
>

Can btmon now save packet dump in a format understandable for wireshark?

Best regards
Andrei Emeltchenko


2013-10-10 13:27:01

by Andrei Emeltchenko

[permalink] [raw]
Subject: Re: [PATCHv3 08/15] android: Add adapter and device struct for BlueZ daemon

Hi Marcin,

On Thu, Oct 10, 2013 at 03:18:14PM +0200, Marcin Kraglak wrote:
> Hi Andrei,
>
> On 10 October 2013 14:30, Andrei Emeltchenko
> <[email protected]> wrote:
> > Hi Marcin,
> >
> > On Thu, Oct 10, 2013 at 11:07:00AM +0200, Marcin Kraglak wrote:
> >> Hi Andrei,
> >>
> >> On 8 October 2013 16:51, Andrei Emeltchenko
> >> <[email protected]> wrote:
> >> > From: Andrei Emeltchenko <[email protected]>
> >> >
> >> > Adapter structure in BlueZ daemon keeps track of default adapter
> >> > and device structure keeps track about found devices.
> >> > ---
> >> > android/bt_adapter.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++
> >> > android/bt_adapter.h | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++
> >> > 2 files changed, 116 insertions(+)
> >> > create mode 100644 android/bt_adapter.c
> >> > create mode 100644 android/bt_adapter.h
> >> >
> >> > diff --git a/android/bt_adapter.c b/android/bt_adapter.c
> >> > new file mode 100644
> >> > index 0000000..e21d50c
> >> > --- /dev/null
> >> > +++ b/android/bt_adapter.c
> >> > @@ -0,0 +1,56 @@
> >> > +/*
> >> > + *
> >> > + * BlueZ - Bluetooth protocol stack for Linux
> >> > + *
> >> > + * Copyright (C) 2013 Intel Corporation. All rights reserved.
> >> > + *
> >> > + *
> >> > + * This program is free software; you can redistribute it and/or modify
> >> > + * it under the terms of the GNU General Public License as published by
> >> > + * the Free Software Foundation; either version 2 of the License, or
> >> > + * (at your option) any later version.
> >> > + *
> >> > + * This program is distributed in the hope that it will be useful,
> >> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> >> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> >> > + * GNU General Public License for more details.
> >> > + *
> >> > + * You should have received a copy of the GNU General Public License
> >> > + * along with this program; if not, write to the Free Software
> >> > + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
> >> > + *
> >> > + */
> >> > +
> >> > +#include "bt_adapter.h"
> >> > +#include "log.h"
> >> > +#include "src/shared/mgmt.h"
> >> > +
> >> > +struct bt_adapter *bt_adapter_new(uint16_t index, struct mgmt *mgmt_if)
> >> > +{
> >> > + struct bt_adapter *adapter;
> >> > +
> >> > + adapter = g_try_new0(struct bt_adapter, 1);
> >> > + if (!adapter)
> >> > + return NULL;
> >> > +
> >> > + adapter->dev_id = index;
> >> > + adapter->mgmt = mgmt_ref(mgmt_if);
> >> > +
> >> > + return adapter;
> >> > +}
> >> > +
> >> > +void adapter_start(struct bt_adapter *adapter)
> >> > +{
> >> > + DBG("enabled %u", adapter->dev_id);
> >> > +
> >> > + /* TODO: CB: report scan mode */
> >> > +
> >> > + /* TODO: SDP start here */
> >> > +
> >> > + /* TODO: CB: report state on */
> >> > +}
> >> > +
> >> > +void adapter_stop(struct bt_adapter *adapter)
> >> > +{
> >> > + DBG("disabled %u", adapter->dev_id);
> >> > +}
> >> > diff --git a/android/bt_adapter.h b/android/bt_adapter.h
> >> > new file mode 100644
> >> > index 0000000..6877cc7
> >> > --- /dev/null
> >> > +++ b/android/bt_adapter.h
> >> > @@ -0,0 +1,60 @@
> >> > +/*
> >> > + *
> >> > + * BlueZ - Bluetooth protocol stack for Linux
> >> > + *
> >> > + * Copyright (C) 2013 Intel Corporation. All rights reserved.
> >> > + *
> >> > + *
> >> > + * This program is free software; you can redistribute it and/or modify
> >> > + * it under the terms of the GNU General Public License as published by
> >> > + * the Free Software Foundation; either version 2 of the License, or
> >> > + * (at your option) any later version.
> >> > + *
> >> > + * This program is distributed in the hope that it will be useful,
> >> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> >> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> >> > + * GNU General Public License for more details.
> >> > + *
> >> > + * You should have received a copy of the GNU General Public License
> >> > + * along with this program; if not, write to the Free Software
> >> > + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
> >> > + *
> >> > + */
> >> > +
> >> > +#include <stdio.h>
> >> > +#include <stdlib.h>
> >> > +#include <unistd.h>
> >> > +#include <glib.h>
> >> > +
> >> > +#include "lib/bluetooth.h"
> >> > +
> >> > +struct bt_device {
> >> > + int refcnt;
> >> > +
> >> > + bdaddr_t bdaddr;
> >> > + uint8_t bdaddr_type;
> >> > + uint32_t cod;
> >> > + char *name;
> >> > +};
> >>
> >> I'm not sure if we need struct bt_device. Shouldn't we just use bdaddr_t?
> >> All data from this struct will be cached in upper layers, so we don't need to
> >> store it in daemon.
> >
> > which upper layer?
> >
> > Best regards
> > Andrei Emeltchenko
> >
>
> I mean java layer in android framework.

I am not sure that we do not need these parameters. Let's try to have
this as minimal as possible.

Best regards
Andrei Emeltchenko

2013-10-10 13:18:14

by Marcin Kraglak

[permalink] [raw]
Subject: Re: [PATCHv3 08/15] android: Add adapter and device struct for BlueZ daemon

Hi Andrei,

On 10 October 2013 14:30, Andrei Emeltchenko
<[email protected]> wrote:
> Hi Marcin,
>
> On Thu, Oct 10, 2013 at 11:07:00AM +0200, Marcin Kraglak wrote:
>> Hi Andrei,
>>
>> On 8 October 2013 16:51, Andrei Emeltchenko
>> <[email protected]> wrote:
>> > From: Andrei Emeltchenko <[email protected]>
>> >
>> > Adapter structure in BlueZ daemon keeps track of default adapter
>> > and device structure keeps track about found devices.
>> > ---
>> > android/bt_adapter.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++
>> > android/bt_adapter.h | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++
>> > 2 files changed, 116 insertions(+)
>> > create mode 100644 android/bt_adapter.c
>> > create mode 100644 android/bt_adapter.h
>> >
>> > diff --git a/android/bt_adapter.c b/android/bt_adapter.c
>> > new file mode 100644
>> > index 0000000..e21d50c
>> > --- /dev/null
>> > +++ b/android/bt_adapter.c
>> > @@ -0,0 +1,56 @@
>> > +/*
>> > + *
>> > + * BlueZ - Bluetooth protocol stack for Linux
>> > + *
>> > + * Copyright (C) 2013 Intel Corporation. All rights reserved.
>> > + *
>> > + *
>> > + * This program is free software; you can redistribute it and/or modify
>> > + * it under the terms of the GNU General Public License as published by
>> > + * the Free Software Foundation; either version 2 of the License, or
>> > + * (at your option) any later version.
>> > + *
>> > + * This program is distributed in the hope that it will be useful,
>> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>> > + * GNU General Public License for more details.
>> > + *
>> > + * You should have received a copy of the GNU General Public License
>> > + * along with this program; if not, write to the Free Software
>> > + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
>> > + *
>> > + */
>> > +
>> > +#include "bt_adapter.h"
>> > +#include "log.h"
>> > +#include "src/shared/mgmt.h"
>> > +
>> > +struct bt_adapter *bt_adapter_new(uint16_t index, struct mgmt *mgmt_if)
>> > +{
>> > + struct bt_adapter *adapter;
>> > +
>> > + adapter = g_try_new0(struct bt_adapter, 1);
>> > + if (!adapter)
>> > + return NULL;
>> > +
>> > + adapter->dev_id = index;
>> > + adapter->mgmt = mgmt_ref(mgmt_if);
>> > +
>> > + return adapter;
>> > +}
>> > +
>> > +void adapter_start(struct bt_adapter *adapter)
>> > +{
>> > + DBG("enabled %u", adapter->dev_id);
>> > +
>> > + /* TODO: CB: report scan mode */
>> > +
>> > + /* TODO: SDP start here */
>> > +
>> > + /* TODO: CB: report state on */
>> > +}
>> > +
>> > +void adapter_stop(struct bt_adapter *adapter)
>> > +{
>> > + DBG("disabled %u", adapter->dev_id);
>> > +}
>> > diff --git a/android/bt_adapter.h b/android/bt_adapter.h
>> > new file mode 100644
>> > index 0000000..6877cc7
>> > --- /dev/null
>> > +++ b/android/bt_adapter.h
>> > @@ -0,0 +1,60 @@
>> > +/*
>> > + *
>> > + * BlueZ - Bluetooth protocol stack for Linux
>> > + *
>> > + * Copyright (C) 2013 Intel Corporation. All rights reserved.
>> > + *
>> > + *
>> > + * This program is free software; you can redistribute it and/or modify
>> > + * it under the terms of the GNU General Public License as published by
>> > + * the Free Software Foundation; either version 2 of the License, or
>> > + * (at your option) any later version.
>> > + *
>> > + * This program is distributed in the hope that it will be useful,
>> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>> > + * GNU General Public License for more details.
>> > + *
>> > + * You should have received a copy of the GNU General Public License
>> > + * along with this program; if not, write to the Free Software
>> > + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
>> > + *
>> > + */
>> > +
>> > +#include <stdio.h>
>> > +#include <stdlib.h>
>> > +#include <unistd.h>
>> > +#include <glib.h>
>> > +
>> > +#include "lib/bluetooth.h"
>> > +
>> > +struct bt_device {
>> > + int refcnt;
>> > +
>> > + bdaddr_t bdaddr;
>> > + uint8_t bdaddr_type;
>> > + uint32_t cod;
>> > + char *name;
>> > +};
>>
>> I'm not sure if we need struct bt_device. Shouldn't we just use bdaddr_t?
>> All data from this struct will be cached in upper layers, so we don't need to
>> store it in daemon.
>
> which upper layer?
>
> Best regards
> Andrei Emeltchenko
>

I mean java layer in android framework.

Regards
Marcin

2013-10-10 13:02:46

by Marcel Holtmann

[permalink] [raw]
Subject: Re: [PATCHv3 07/15] android: Create HAL API header skeleton

Hi Andrei,

>>>>> +#define HAL_MSG_OP_BT_SET_REMOTE_DEVICE_PROP 0x08
>>>>> +struct hal_msg_cp_bt_set_remote_device_prop {
>>>>> + __bdaddr_t bdaddr;
>>>>> + uint8_t type;
>>>>> + uint16_t len;
>>>>
>>>> Lets make these all align properly.
>>>
>>> Align with tabs? So this will be very different from lib/mgmt.h ?
>>
>> In monitor/bt.h, I did align them with spaces.
>
> Just to be sure: align structures with spaces always?

between uint16_t and len uses spaces to make them align. For everything else use tabs. This only applies to protocol data structures. See monitor/bt.h for how it is suppose to be done.

Regards

Marcel


2013-10-10 13:01:29

by Andrei Emeltchenko

[permalink] [raw]
Subject: Re: [PATCHv3 11/15] android: Add cap to bind to port < 1024

Hi Marcel,

On Wed, Oct 09, 2013 at 09:48:33PM +0200, Marcel Holtmann wrote:
> Hi Andrei,
>
> > For SDP server we need to bind to lower port, acquire this capability.
> > ---
> > android/main.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> > configure.ac | 4 ++++
> > 2 files changed, 75 insertions(+)
> >
> > diff --git a/android/main.c b/android/main.c
> > index 7968ed0..a100013 100644
> > --- a/android/main.c
> > +++ b/android/main.c
> > @@ -32,6 +32,22 @@
> > #include <stdlib.h>
> > #include <stdbool.h>
> > #include <string.h>
> > +#include <unistd.h>
> > +#include <errno.h>
> > +#include <sys/prctl.h>
> > +#include <linux/capability.h>
> > +
> > +/**
> > + * Include <sys/capability.h> for host build and
> > + * also for Android 4.3 when it is added to bionic
> > + */
>
> why focus on anything before Android 4.3?

Because we have currently 4.2.2 and test with hardware running 4.2.2. Do
you want us to write theoretical code? And do you believe that Google
magically fix everything in 4.4?

Best regards
Andrei Emeltchenko

2013-10-10 12:52:38

by Andrei Emeltchenko

[permalink] [raw]
Subject: Re: [PATCHv3 09/15] android: Add Android Makefile for libbluetooth

Hi Marcel,

On Thu, Oct 10, 2013 at 02:45:35PM +0200, Marcel Holtmann wrote:
> >>> +
> >>> +lib_headers := \
> >>> + bluetooth.h \
> >>> + hci.h \
> >>> + hci_lib.h \
> >>> + sco.h \
> >>> + l2cap.h \
> >>> + sdp.h \
> >>> + sdp_lib.h \
> >>> + rfcomm.h \
> >>> + bnep.h \
> >>> + cmtp.h \
> >>> + hidp.h \
> >>
> >> I would really prefer we do not install these.
> >
> > this creates directly bluetooth with links to headers since this is they
> > way BlueZ is referring to them. What do you propose here?
>
> I prefer that we do not install these headers or the shared library.
> Nothing outside of BlueZ build should need them.

They are not installed anywhere. Just links created locally.

Best regards
Andrei Emeltchenko

2013-10-10 12:48:41

by Andrei Emeltchenko

[permalink] [raw]
Subject: Re: [PATCHv3 07/15] android: Create HAL API header skeleton

Hi Marcel,

On Thu, Oct 10, 2013 at 02:35:37PM +0200, Marcel Holtmann wrote:
> >>> +#define HAL_MSG_OP_BT_SET_REMOTE_DEVICE_PROP 0x08
> >>> +struct hal_msg_cp_bt_set_remote_device_prop {
> >>> + __bdaddr_t bdaddr;
> >>> + uint8_t type;
> >>> + uint16_t len;
> >>
> >> Lets make these all align properly.
> >
> > Align with tabs? So this will be very different from lib/mgmt.h ?
>
> In monitor/bt.h, I did align them with spaces.

Just to be sure: align structures with spaces always?

Best regards
Andrei Emeltchenko

2013-10-10 12:45:35

by Marcel Holtmann

[permalink] [raw]
Subject: Re: [PATCHv3 09/15] android: Add Android Makefile for libbluetooth

Hi Andrei,

>>> Build libbluetooth library for Android.
>>> ---
>>> android/Android.mk | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>>> 1 file changed, 53 insertions(+)
>>>
>>> diff --git a/android/Android.mk b/android/Android.mk
>>> index f5fd863..8f95a66 100644
>>> --- a/android/Android.mk
>>> +++ b/android/Android.mk
>>> @@ -41,6 +41,7 @@ LOCAL_SHARED_LIBRARIES := \
>>> libglib \
>>>
>>> LOCAL_MODULE := bluetoothd
>>> +LOCAL_REQUIRED_MODULES := libbluetooth
>>>
>>> include $(BUILD_EXECUTABLE)
>>>
>>> @@ -63,3 +64,55 @@ LOCAL_MODULE_TAGS := optional
>>> LOCAL_MODULE_CLASS := SHARED_LIBRARIES
>>>
>>> include $(BUILD_SHARED_LIBRARY)
>>> +
>>> +#
>>> +# libbluetooth library
>>> +#
>>> +
>>> +include $(CLEAR_VARS)
>>> +
>>> +LOCAL_SRC_FILES := \
>>> + ../lib/bluetooth.c \
>>> + ../lib/sdp.c \
>>> + ../lib/hci.c \
>>> + ../lib/uuid.c \
>>
>> why are we building a shared library here. What is it useful for. Even
>> within BlueZ we do not install libbluetooth anymore.
>
> It is used for tools also like btmon, shall we include those files
> directly?

if that works, then yes, just include the files that are needed. The newer tools are actually limited to only a few functions. And we could work on getting libbluetooth dependency out of it.

For an autoconf based build it is not high priority sine we only build the library as an internal version that in the end gets statically linked. And unused functions will just be optimized out.

>
>>
>>> +
>>> +LOCAL_C_INCLUDES := \
>>> + $(LOCAL_PATH)/../lib/ \
>>> + $(LOCAL_PATH)/../src/shared \
>>
>> The library clearly does not include anything from src/shared/. So what is that doing here.
>>
>>> +
>>> +LOCAL_C_INCLUDES += \
>>> + $(call include-path-for, glib) \
>>> + $(call include-path-for, glib)/glib \
>>
>> The library clearly does not need GLib. So why are we doing that here.
>>
>>> +
>>> +LOCAL_CFLAGS += -O3
>>> +
>>> +# to suppress the "pointer of type 'void *' used in arithmetic" warning
>>> +LOCAL_CFLAGS += -Wno-pointer-arith
>>> +
>>> +# to suppress the "missing initializer near initialization" warning
>>> +LOCAL_CFLAGS += -Wno-missing-field-initializers
>>
>> Lets fix the actual warnings.
>>
>>> +
>>> +# Define missing flags for Android 4.2
>>> +LOCAL_CFLAGS += -DSOCK_CLOEXEC=02000000 -DSOCK_NONBLOCK=04000
>>
>> And are we sure that these flags are needed for the library.
>>
>>> +
>>> +lib_headers := \
>>> + bluetooth.h \
>>> + hci.h \
>>> + hci_lib.h \
>>> + sco.h \
>>> + l2cap.h \
>>> + sdp.h \
>>> + sdp_lib.h \
>>> + rfcomm.h \
>>> + bnep.h \
>>> + cmtp.h \
>>> + hidp.h \
>>
>> I would really prefer we do not install these.
>
> this creates directly bluetooth with links to headers since this is they
> way BlueZ is referring to them. What do you propose here?

I prefer that we do not install these headers or the shared library. Nothing outside of BlueZ build should need them.

Regards

Marcel


2013-10-10 12:43:49

by Andrei Emeltchenko

[permalink] [raw]
Subject: Re: [PATCHv3 09/15] android: Add Android Makefile for libbluetooth

Hi Marcel,

On Wed, Oct 09, 2013 at 09:43:18PM +0200, Marcel Holtmann wrote:
> Hi Andrei,
>
> > Build libbluetooth library for Android.
> > ---
> > android/Android.mk | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++
> > 1 file changed, 53 insertions(+)
> >
> > diff --git a/android/Android.mk b/android/Android.mk
> > index f5fd863..8f95a66 100644
> > --- a/android/Android.mk
> > +++ b/android/Android.mk
> > @@ -41,6 +41,7 @@ LOCAL_SHARED_LIBRARIES := \
> > libglib \
> >
> > LOCAL_MODULE := bluetoothd
> > +LOCAL_REQUIRED_MODULES := libbluetooth
> >
> > include $(BUILD_EXECUTABLE)
> >
> > @@ -63,3 +64,55 @@ LOCAL_MODULE_TAGS := optional
> > LOCAL_MODULE_CLASS := SHARED_LIBRARIES
> >
> > include $(BUILD_SHARED_LIBRARY)
> > +
> > +#
> > +# libbluetooth library
> > +#
> > +
> > +include $(CLEAR_VARS)
> > +
> > +LOCAL_SRC_FILES := \
> > + ../lib/bluetooth.c \
> > + ../lib/sdp.c \
> > + ../lib/hci.c \
> > + ../lib/uuid.c \
>
> why are we building a shared library here. What is it useful for. Even
> within BlueZ we do not install libbluetooth anymore.

It is used for tools also like btmon, shall we include those files
directly?

>
> > +
> > +LOCAL_C_INCLUDES := \
> > + $(LOCAL_PATH)/../lib/ \
> > + $(LOCAL_PATH)/../src/shared \
>
> The library clearly does not include anything from src/shared/. So what is that doing here.
>
> > +
> > +LOCAL_C_INCLUDES += \
> > + $(call include-path-for, glib) \
> > + $(call include-path-for, glib)/glib \
>
> The library clearly does not need GLib. So why are we doing that here.
>
> > +
> > +LOCAL_CFLAGS += -O3
> > +
> > +# to suppress the "pointer of type 'void *' used in arithmetic" warning
> > +LOCAL_CFLAGS += -Wno-pointer-arith
> > +
> > +# to suppress the "missing initializer near initialization" warning
> > +LOCAL_CFLAGS += -Wno-missing-field-initializers
>
> Lets fix the actual warnings.
>
> > +
> > +# Define missing flags for Android 4.2
> > +LOCAL_CFLAGS += -DSOCK_CLOEXEC=02000000 -DSOCK_NONBLOCK=04000
>
> And are we sure that these flags are needed for the library.
>
> > +
> > +lib_headers := \
> > + bluetooth.h \
> > + hci.h \
> > + hci_lib.h \
> > + sco.h \
> > + l2cap.h \
> > + sdp.h \
> > + sdp_lib.h \
> > + rfcomm.h \
> > + bnep.h \
> > + cmtp.h \
> > + hidp.h \
>
> I would really prefer we do not install these.

this creates directly bluetooth with links to headers since this is they
way BlueZ is referring to them. What do you propose here?

Best regards
Andrei Emeltchenko

2013-10-10 12:40:18

by Marcel Holtmann

[permalink] [raw]
Subject: Re: [PATCHv3 08/15] android: Add adapter and device struct for BlueZ daemon

Hi Andrei,

>>> Adapter structure in BlueZ daemon keeps track of default adapter
>>> and device structure keeps track about found devices.
>>> ---
>>> android/bt_adapter.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++
>>> android/bt_adapter.h | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++
>>> 2 files changed, 116 insertions(+)
>>> create mode 100644 android/bt_adapter.c
>>> create mode 100644 android/bt_adapter.h
>>>
>>> diff --git a/android/bt_adapter.c b/android/bt_adapter.c
>>> new file mode 100644
>>> index 0000000..e21d50c
>>> --- /dev/null
>>> +++ b/android/bt_adapter.c
>>> @@ -0,0 +1,56 @@
>>> +/*
>>> + *
>>> + * BlueZ - Bluetooth protocol stack for Linux
>>> + *
>>> + * Copyright (C) 2013 Intel Corporation. All rights reserved.
>>> + *
>>> + *
>>> + * This program is free software; you can redistribute it and/or modify
>>> + * it under the terms of the GNU General Public License as published by
>>> + * the Free Software Foundation; either version 2 of the License, or
>>> + * (at your option) any later version.
>>> + *
>>> + * This program is distributed in the hope that it will be useful,
>>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>>> + * GNU General Public License for more details.
>>> + *
>>> + * You should have received a copy of the GNU General Public License
>>> + * along with this program; if not, write to the Free Software
>>> + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
>>> + *
>>> + */
>>> +
>>> +#include "bt_adapter.h"
>>
>> the include of its own header should always be the last one. Never the first one.
>>
>>
>>> +#include "log.h"
>>> +#include "src/shared/mgmt.h"
>>> +
>>> +struct bt_adapter *bt_adapter_new(uint16_t index, struct mgmt *mgmt_if)
>>> +{
>>> + struct bt_adapter *adapter;
>>> +
>>> + adapter = g_try_new0(struct bt_adapter, 1);
>>> + if (!adapter)
>>> + return NULL;
>>
>> Since this all brand new code, use g_new0 and we just exit on memory allocation failures for our own data structures.
>>
>
> Do you mean exit(1)?

please understand on how g_new0 works.

>
>>> +
>>> + adapter->dev_id = index;
>>> + adapter->mgmt = mgmt_ref(mgmt_if);
>>> +
>>> + return adapter;
>>> +}
>>> +
>>> +void adapter_start(struct bt_adapter *adapter)
>>
>> Why does this now have no bt_ prefix?
>>
>>> +{
>>> + DBG("enabled %u", adapter->dev_id);
>>> +
>>> + /* TODO: CB: report scan mode */
>>> +
>>> + /* TODO: SDP start here */
>>> +
>>> + /* TODO: CB: report state on */
>>> +}
>>> +
>>> +void adapter_stop(struct bt_adapter *adapter)
>>> +{
>>> + DBG("disabled %u", adapter->dev_id);
>>> +}
>>> diff --git a/android/bt_adapter.h b/android/bt_adapter.h
>>> new file mode 100644
>>> index 0000000..6877cc7
>>> --- /dev/null
>>> +++ b/android/bt_adapter.h
>>> @@ -0,0 +1,60 @@
>>> +/*
>>> + *
>>> + * BlueZ - Bluetooth protocol stack for Linux
>>> + *
>>> + * Copyright (C) 2013 Intel Corporation. All rights reserved.
>>> + *
>>> + *
>>> + * This program is free software; you can redistribute it and/or modify
>>> + * it under the terms of the GNU General Public License as published by
>>> + * the Free Software Foundation; either version 2 of the License, or
>>> + * (at your option) any later version.
>>> + *
>>> + * This program is distributed in the hope that it will be useful,
>>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>>> + * GNU General Public License for more details.
>>> + *
>>> + * You should have received a copy of the GNU General Public License
>>> + * along with this program; if not, write to the Free Software
>>> + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
>>> + *
>>> + */
>>> +
>>> +#include <stdio.h>
>>> +#include <stdlib.h>
>>> +#include <unistd.h>
>>> +#include <glib.h>
>>> +
>>> +#include "lib/bluetooth.h"
>>> +
>>> +struct bt_device {
>>> + int refcnt;
>>> +
>>> + bdaddr_t bdaddr;
>>> + uint8_t bdaddr_type;
>>> + uint32_t cod;
>>> + char *name;
>>> +};
>>
>> Why is bt_device declared in bt_adapter.
>> And why are these public in the first place. Please hide these details.
>
> So do you want it to be added in main.c? Those structs are public also in
> BlueZ.

struct bt_adapter;

Just forward declare them in the header. The actual fields do not need to be public. As I said before, this is new code and not BlueZ code that is many years old. We follow brand new style here and not copy old mistakes.

Regards

Marcel


2013-10-10 12:38:08

by Marcel Holtmann

[permalink] [raw]
Subject: Re: [PATCHv3 06/15] android: Add basic mgmt initialization sequence

Hi Andrei,

>>> Initialize bluetooth controller via mgmt interface.
>>> ---
>>> Makefile.android | 4 +-
>>> android/Android.mk | 11 +++
>>> android/main.c | 189 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>>> 3 files changed, 203 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/Makefile.android b/Makefile.android
>>> index e161e6d..9a2c486 100644
>>> --- a/Makefile.android
>>> +++ b/Makefile.android
>>> @@ -1,7 +1,9 @@
>>> if ANDROID
>>> noinst_PROGRAMS += android/bluetoothd
>>>
>>> -android_bluetoothd_SOURCES = android/main.c src/log.c
>>> +android_bluetoothd_SOURCES = android/main.c src/log.c \
>>> + src/shared/util.h src/shared/util.c \
>>> + src/shared/mgmt.h src/shared/mgmt.c
>>> android_bluetoothd_LDADD = @GLIB_LIBS@
>>> endif
>>>
>>> diff --git a/android/Android.mk b/android/Android.mk
>>> index 2cabff4..f5fd863 100644
>>> --- a/android/Android.mk
>>> +++ b/android/Android.mk
>>> @@ -15,10 +15,15 @@ include $(CLEAR_VARS)
>>> LOCAL_SRC_FILES := \
>>> main.c \
>>> log.c \
>>> + ../src/shared/mgmt.c \
>>> + ../src/shared/util.c \
>>>
>>> LOCAL_C_INCLUDES := \
>>> $(call include-path-for, glib) \
>>> $(call include-path-for, glib)/glib \
>>> +
>>> +LOCAL_C_INCLUDES += \
>>> + $(LOCAL_PATH)/../ \
>>> $(LOCAL_PATH)/../src \
>> do we need these nested includes actually? We could also just fix the includes. BlueZ historically has not been good with clear includes. I started to fix this, but it seems I have not gotten to all of them yet.
>>
>
> So how do you want it to be? Here I just added BlueZ top-dir.
>
>>> LOCAL_CFLAGS := -DVERSION=\"$(BLUEZ_VERSION)\"
>>> @@ -26,6 +31,12 @@ LOCAL_CFLAGS := -DVERSION=\"$(BLUEZ_VERSION)\"
>>> # to suppress the "warning: missing initializer near initialization.." warning
>>> LOCAL_CFLAGS += -Wno-missing-field-initializers
>>>
>>> +# to suppress the "pointer of type 'void *' used in arithmetic" warning
>>> +LOCAL_CFLAGS += -Wno-pointer-arith
>>
>> Why do we need to suppress these warning. Can we not just fix them.
>>
>
> Is this fix good:
>
> diff --git a/src/shared/mgmt.c b/src/shared/mgmt.c
> index 2c79886..b2f5506 100644
> --- a/src/shared/mgmt.c
> +++ b/src/shared/mgmt.c
> @@ -55,7 +55,7 @@ struct mgmt {
> unsigned int next_notify_id;
> bool in_notify;
> bool destroyed;
> - void *buf;
> + uint8_t *buf;
> uint16_t len;
> mgmt_debug_func_t debug_callback;
> mgmt_destroy_func_t debug_destroy;
> @@ -299,7 +299,7 @@ static gboolean received_data(GIOChannel *channel,
> GIOCondition cond,
> if (bytes_read < MGMT_HDR_SIZE)
> return TRUE;
>
> - hdr = mgmt->buf;
> + hdr = (struct mgmt_hdr *) mgmt->buf;

are we using a different compiler or why does this happen on Android and not on a regular system like Fedora.

>>> +
>>> +# Define missing flags for Android 4.2
>>> +LOCAL_CFLAGS += -DSOCK_CLOEXEC=02000000 -DSOCK_NONBLOCK=04000
>>> +
>>
>> This thing is dangerous. Do we really bother with Android 4.2 support
>> and can not rely on a newer version that has this fixed properly in
>> bionic.
>
> The problem here is that our base android-ia from 01.org is based on
> 4.2.2. Do you still want to remove this?

I don't think we should care much about Android 4.2.2. Why is our base not updated to Android 4.3 yet. And as soon as 4.4 is out, we can ignore 4.3 as well. Chasing after old versions seems a bit pointless until someone actually integrated this into a product.

Regards

Marcel


2013-10-10 12:35:37

by Marcel Holtmann

[permalink] [raw]
Subject: Re: [PATCHv3 07/15] android: Create HAL API header skeleton

Hi Andrei,

>>> Header describes the protocol between Android HAL threads and BlueZ
>>> daemon.
>>> ---
>>> android/hal_msg.h | 255 +++++++++++++++++++++++++++++++++++++++++++++++++++++
>>> 1 file changed, 255 insertions(+)
>>> create mode 100644 android/hal_msg.h
>>>
>>> diff --git a/android/hal_msg.h b/android/hal_msg.h
>>> new file mode 100644
>>> index 0000000..c6bc883
>>> --- /dev/null
>>> +++ b/android/hal_msg.h
>>> @@ -0,0 +1,255 @@
>>> +/*
>>> + *
>>> + * BlueZ - Bluetooth protocol stack for Linux
>>> + *
>>> + * Copyright (C) 2013 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
>>> + *
>>> + */
>>> +
>>> +#ifndef __packed
>>> +#define __packed __attribute__((packed))
>>> +#endif
>
> you want different style from lib/mgmt.h ?

no idea why that is in there. It should not be.

>>
>> nowhere in the code we are using __packed. That is more a kernel thing. Just use the gcc style directly.
>>
>>> +
>>> +typedef struct {
>>> + uint8_t b[6];
>>> +} __packed __bdaddr_t;
>>
>> Just use a uint8_t bdaddr[6] instead.
>>
>>> +
>>> +struct hal_msg_hdr {
>>> + uint8_t service_id;
>>> + uint8_t opcode;
>>> + uint16_t len;
>>> + uint8_t payload[0];
>>
>> I would not include the payload[0] here.
>
> I know that the current approach is to magically add to pointer header
> size, but doesn't it looks better?

Not to me.

>
>>
>>> +} __packed;
>>> +
>>> +#define HAL_SERVICE_ID_CORE 0
>>> +#define HAL_SERVICE_ID_BLUETOOTH 1
>>> +#define HAL_SERVICE_ID_SOCK 2
>>> +#define HAL_SERVICE_ID_HIDHOST 3
>>> +#define HAL_SERVICE_ID_PAN 4
>>> +#define HAL_SERVICE_ID_HANDSFREE 5
>>> +#define HAL_SERVICE_ID_AD2P 6
>>> +#define HAL_SERVICE_ID_HEALTH 7
>>> +#define HAL_SERVICE_ID_AVRCP 8
>>> +#define HAL_SERVICE_ID_GATT 9
>>> +
>>> +/* Core Service */
>>> +
>>> +#define HAL_MSG_OP_ERROR 0x00
>>> +struct hal_msg_rp_error {
>>> + uint8_t status;
>>> +} __packed;
>>
>> using RSP, rsp, CMD, cmd, EVT and EVT seems to be clearer I think.
>
> So I want to be sure that I understand this right:
>
> hal_msg_rp_error => hal_msg_rsp_error
>
> hal_msg_cp_register_module => hal_msg_cmd_register_module
>
> this would be different from lib/mgmt.h

Since this is not a mgmt.h API, it does not need to follow it. mgmt is a kernel API and that is where some its parts are coming from. This is not a kernel API.

>
>>> +
>>> +#define HAL_MSG_OP_REGISTER_MODULE 0x01
>>> +struct hal_msg_cp_register_module {
>>> + uint8_t service_id;
>>> +} __packed;
>>> +struct hal_msg_rp_register_module {
>>> + uint8_t service_id;
>>> +} __packed;
>>> +
>>> +#define HAL_MSG_OP_UNREGISTER_MODULE 0x02
>>> +struct hal_msg_cp_unregister_module {
>>> + uint8_t service_id;
>>> +} __packed;
>>> +
>>> +/* Bluetooth Core HAL API */
>>> +
>>> +#define HAL_MSG_OP_BT_ENABLE 0x01
>>> +
>>> +#define HAL_MSG_OP_BT_DISABLE 0x02
>>> +
>>> +#define HAL_MSG_OP_BT_GET_ADAPTER_PROPS 0x03
>>> +
>>> +#define HAL_MSG_OP_BT_GET_ADAPTER_PROP 0x04
>>> +struct hal_msg_cp_bt_get_adapter_prop {
>>> + uint8_t type;
>>> +} __packed;
>>> +
>>> +#define HAL_MSG_OP_BT_SET_ADAPTER_PROP 0x05
>>> +struct hal_msg_cp_bt_set_adapter_prop {
>>> + uint8_t type;
>>> + uint16_t len;
>>> + uint8_t val[0];
>>> +} __packed;
>>> +
>>> +#define HAL_MSG_OP_BT_GET_REMOTE_DEVICE_PROPS 0x06
>>> +struct hal_msg_cp_bt_get_remote_device_props {
>>> + __bdaddr_t bdaddr;
>>> +} __packed;
>>> +
>>> +#define HAL_MSG_OP_BT_GET_REMOTE_DEVICE_PROP 0x07
>>> +struct hal_msg_cp_bt_get_remote_device_prop {
>>> + __bdaddr_t bdaddr;
>>> + uint8_t type;
>>> +} __packed;
>>> +
>>> +#define HAL_MSG_OP_BT_SET_REMOTE_DEVICE_PROP 0x08
>>> +struct hal_msg_cp_bt_set_remote_device_prop {
>>> + __bdaddr_t bdaddr;
>>> + uint8_t type;
>>> + uint16_t len;
>>
>> Lets make these all align properly.
>
> Align with tabs? So this will be very different from lib/mgmt.h ?

In monitor/bt.h, I did align them with spaces.

Regards

Marcel


2013-10-10 12:36:39

by Andrei Emeltchenko

[permalink] [raw]
Subject: Re: [PATCHv3 08/15] android: Add adapter and device struct for BlueZ daemon

On Wed, Oct 09, 2013 at 09:39:34PM +0200, Marcel Holtmann wrote:
> Hi Andrei,
>
> > Adapter structure in BlueZ daemon keeps track of default adapter
> > and device structure keeps track about found devices.
> > ---
> > android/bt_adapter.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++
> > android/bt_adapter.h | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++
> > 2 files changed, 116 insertions(+)
> > create mode 100644 android/bt_adapter.c
> > create mode 100644 android/bt_adapter.h
> >
> > diff --git a/android/bt_adapter.c b/android/bt_adapter.c
> > new file mode 100644
> > index 0000000..e21d50c
> > --- /dev/null
> > +++ b/android/bt_adapter.c
> > @@ -0,0 +1,56 @@
> > +/*
> > + *
> > + * BlueZ - Bluetooth protocol stack for Linux
> > + *
> > + * Copyright (C) 2013 Intel Corporation. All rights reserved.
> > + *
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License as published by
> > + * the Free Software Foundation; either version 2 of the License, or
> > + * (at your option) any later version.
> > + *
> > + * This program is distributed in the hope that it will be useful,
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> > + * GNU General Public License for more details.
> > + *
> > + * You should have received a copy of the GNU General Public License
> > + * along with this program; if not, write to the Free Software
> > + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
> > + *
> > + */
> > +
> > +#include "bt_adapter.h"
>
> the include of its own header should always be the last one. Never the first one.
>
>
> > +#include "log.h"
> > +#include "src/shared/mgmt.h"
> > +
> > +struct bt_adapter *bt_adapter_new(uint16_t index, struct mgmt *mgmt_if)
> > +{
> > + struct bt_adapter *adapter;
> > +
> > + adapter = g_try_new0(struct bt_adapter, 1);
> > + if (!adapter)
> > + return NULL;
>
> Since this all brand new code, use g_new0 and we just exit on memory allocation failures for our own data structures.
>

Do you mean exit(1)?

> > +
> > + adapter->dev_id = index;
> > + adapter->mgmt = mgmt_ref(mgmt_if);
> > +
> > + return adapter;
> > +}
> > +
> > +void adapter_start(struct bt_adapter *adapter)
>
> Why does this now have no bt_ prefix?
>
> > +{
> > + DBG("enabled %u", adapter->dev_id);
> > +
> > + /* TODO: CB: report scan mode */
> > +
> > + /* TODO: SDP start here */
> > +
> > + /* TODO: CB: report state on */
> > +}
> > +
> > +void adapter_stop(struct bt_adapter *adapter)
> > +{
> > + DBG("disabled %u", adapter->dev_id);
> > +}
> > diff --git a/android/bt_adapter.h b/android/bt_adapter.h
> > new file mode 100644
> > index 0000000..6877cc7
> > --- /dev/null
> > +++ b/android/bt_adapter.h
> > @@ -0,0 +1,60 @@
> > +/*
> > + *
> > + * BlueZ - Bluetooth protocol stack for Linux
> > + *
> > + * Copyright (C) 2013 Intel Corporation. All rights reserved.
> > + *
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License as published by
> > + * the Free Software Foundation; either version 2 of the License, or
> > + * (at your option) any later version.
> > + *
> > + * This program is distributed in the hope that it will be useful,
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> > + * GNU General Public License for more details.
> > + *
> > + * You should have received a copy of the GNU General Public License
> > + * along with this program; if not, write to the Free Software
> > + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
> > + *
> > + */
> > +
> > +#include <stdio.h>
> > +#include <stdlib.h>
> > +#include <unistd.h>
> > +#include <glib.h>
> > +
> > +#include "lib/bluetooth.h"
> > +
> > +struct bt_device {
> > + int refcnt;
> > +
> > + bdaddr_t bdaddr;
> > + uint8_t bdaddr_type;
> > + uint32_t cod;
> > + char *name;
> > +};
>
> Why is bt_device declared in bt_adapter.
> And why are these public in the first place. Please hide these details.

So do you want it to be added in main.c? Those structs are public also in
BlueZ.

Best regards
Andrei Emeltchenko


2013-10-10 12:30:22

by Andrei Emeltchenko

[permalink] [raw]
Subject: Re: [PATCHv3 08/15] android: Add adapter and device struct for BlueZ daemon

Hi Marcin,

On Thu, Oct 10, 2013 at 11:07:00AM +0200, Marcin Kraglak wrote:
> Hi Andrei,
>
> On 8 October 2013 16:51, Andrei Emeltchenko
> <[email protected]> wrote:
> > From: Andrei Emeltchenko <[email protected]>
> >
> > Adapter structure in BlueZ daemon keeps track of default adapter
> > and device structure keeps track about found devices.
> > ---
> > android/bt_adapter.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++
> > android/bt_adapter.h | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++
> > 2 files changed, 116 insertions(+)
> > create mode 100644 android/bt_adapter.c
> > create mode 100644 android/bt_adapter.h
> >
> > diff --git a/android/bt_adapter.c b/android/bt_adapter.c
> > new file mode 100644
> > index 0000000..e21d50c
> > --- /dev/null
> > +++ b/android/bt_adapter.c
> > @@ -0,0 +1,56 @@
> > +/*
> > + *
> > + * BlueZ - Bluetooth protocol stack for Linux
> > + *
> > + * Copyright (C) 2013 Intel Corporation. All rights reserved.
> > + *
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License as published by
> > + * the Free Software Foundation; either version 2 of the License, or
> > + * (at your option) any later version.
> > + *
> > + * This program is distributed in the hope that it will be useful,
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> > + * GNU General Public License for more details.
> > + *
> > + * You should have received a copy of the GNU General Public License
> > + * along with this program; if not, write to the Free Software
> > + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
> > + *
> > + */
> > +
> > +#include "bt_adapter.h"
> > +#include "log.h"
> > +#include "src/shared/mgmt.h"
> > +
> > +struct bt_adapter *bt_adapter_new(uint16_t index, struct mgmt *mgmt_if)
> > +{
> > + struct bt_adapter *adapter;
> > +
> > + adapter = g_try_new0(struct bt_adapter, 1);
> > + if (!adapter)
> > + return NULL;
> > +
> > + adapter->dev_id = index;
> > + adapter->mgmt = mgmt_ref(mgmt_if);
> > +
> > + return adapter;
> > +}
> > +
> > +void adapter_start(struct bt_adapter *adapter)
> > +{
> > + DBG("enabled %u", adapter->dev_id);
> > +
> > + /* TODO: CB: report scan mode */
> > +
> > + /* TODO: SDP start here */
> > +
> > + /* TODO: CB: report state on */
> > +}
> > +
> > +void adapter_stop(struct bt_adapter *adapter)
> > +{
> > + DBG("disabled %u", adapter->dev_id);
> > +}
> > diff --git a/android/bt_adapter.h b/android/bt_adapter.h
> > new file mode 100644
> > index 0000000..6877cc7
> > --- /dev/null
> > +++ b/android/bt_adapter.h
> > @@ -0,0 +1,60 @@
> > +/*
> > + *
> > + * BlueZ - Bluetooth protocol stack for Linux
> > + *
> > + * Copyright (C) 2013 Intel Corporation. All rights reserved.
> > + *
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License as published by
> > + * the Free Software Foundation; either version 2 of the License, or
> > + * (at your option) any later version.
> > + *
> > + * This program is distributed in the hope that it will be useful,
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> > + * GNU General Public License for more details.
> > + *
> > + * You should have received a copy of the GNU General Public License
> > + * along with this program; if not, write to the Free Software
> > + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
> > + *
> > + */
> > +
> > +#include <stdio.h>
> > +#include <stdlib.h>
> > +#include <unistd.h>
> > +#include <glib.h>
> > +
> > +#include "lib/bluetooth.h"
> > +
> > +struct bt_device {
> > + int refcnt;
> > +
> > + bdaddr_t bdaddr;
> > + uint8_t bdaddr_type;
> > + uint32_t cod;
> > + char *name;
> > +};
>
> I'm not sure if we need struct bt_device. Shouldn't we just use bdaddr_t?
> All data from this struct will be cached in upper layers, so we don't need to
> store it in daemon.

which upper layer?

Best regards
Andrei Emeltchenko


2013-10-10 12:29:14

by Andrei Emeltchenko

[permalink] [raw]
Subject: Re: [PATCHv3 07/15] android: Create HAL API header skeleton

On Wed, Oct 09, 2013 at 09:34:17PM +0200, Marcel Holtmann wrote:
> Hi Andrei,
>
> > Header describes the protocol between Android HAL threads and BlueZ
> > daemon.
> > ---
> > android/hal_msg.h | 255 +++++++++++++++++++++++++++++++++++++++++++++++++++++
> > 1 file changed, 255 insertions(+)
> > create mode 100644 android/hal_msg.h
> >
> > diff --git a/android/hal_msg.h b/android/hal_msg.h
> > new file mode 100644
> > index 0000000..c6bc883
> > --- /dev/null
> > +++ b/android/hal_msg.h
> > @@ -0,0 +1,255 @@
> > +/*
> > + *
> > + * BlueZ - Bluetooth protocol stack for Linux
> > + *
> > + * Copyright (C) 2013 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
> > + *
> > + */
> > +
> > +#ifndef __packed
> > +#define __packed __attribute__((packed))
> > +#endif

you want different style from lib/mgmt.h ?

>
> nowhere in the code we are using __packed. That is more a kernel thing. Just use the gcc style directly.
>
> > +
> > +typedef struct {
> > + uint8_t b[6];
> > +} __packed __bdaddr_t;
>
> Just use a uint8_t bdaddr[6] instead.
>
> > +
> > +struct hal_msg_hdr {
> > + uint8_t service_id;
> > + uint8_t opcode;
> > + uint16_t len;
> > + uint8_t payload[0];
>
> I would not include the payload[0] here.

I know that the current approach is to magically add to pointer header
size, but doesn't it looks better?

>
> > +} __packed;
> > +
> > +#define HAL_SERVICE_ID_CORE 0
> > +#define HAL_SERVICE_ID_BLUETOOTH 1
> > +#define HAL_SERVICE_ID_SOCK 2
> > +#define HAL_SERVICE_ID_HIDHOST 3
> > +#define HAL_SERVICE_ID_PAN 4
> > +#define HAL_SERVICE_ID_HANDSFREE 5
> > +#define HAL_SERVICE_ID_AD2P 6
> > +#define HAL_SERVICE_ID_HEALTH 7
> > +#define HAL_SERVICE_ID_AVRCP 8
> > +#define HAL_SERVICE_ID_GATT 9
> > +
> > +/* Core Service */
> > +
> > +#define HAL_MSG_OP_ERROR 0x00
> > +struct hal_msg_rp_error {
> > + uint8_t status;
> > +} __packed;
>
> using RSP, rsp, CMD, cmd, EVT and EVT seems to be clearer I think.

So I want to be sure that I understand this right:

hal_msg_rp_error => hal_msg_rsp_error

hal_msg_cp_register_module => hal_msg_cmd_register_module

this would be different from lib/mgmt.h

> > +
> > +#define HAL_MSG_OP_REGISTER_MODULE 0x01
> > +struct hal_msg_cp_register_module {
> > + uint8_t service_id;
> > +} __packed;
> > +struct hal_msg_rp_register_module {
> > + uint8_t service_id;
> > +} __packed;
> > +
> > +#define HAL_MSG_OP_UNREGISTER_MODULE 0x02
> > +struct hal_msg_cp_unregister_module {
> > + uint8_t service_id;
> > +} __packed;
> > +
> > +/* Bluetooth Core HAL API */
> > +
> > +#define HAL_MSG_OP_BT_ENABLE 0x01
> > +
> > +#define HAL_MSG_OP_BT_DISABLE 0x02
> > +
> > +#define HAL_MSG_OP_BT_GET_ADAPTER_PROPS 0x03
> > +
> > +#define HAL_MSG_OP_BT_GET_ADAPTER_PROP 0x04
> > +struct hal_msg_cp_bt_get_adapter_prop {
> > + uint8_t type;
> > +} __packed;
> > +
> > +#define HAL_MSG_OP_BT_SET_ADAPTER_PROP 0x05
> > +struct hal_msg_cp_bt_set_adapter_prop {
> > + uint8_t type;
> > + uint16_t len;
> > + uint8_t val[0];
> > +} __packed;
> > +
> > +#define HAL_MSG_OP_BT_GET_REMOTE_DEVICE_PROPS 0x06
> > +struct hal_msg_cp_bt_get_remote_device_props {
> > + __bdaddr_t bdaddr;
> > +} __packed;
> > +
> > +#define HAL_MSG_OP_BT_GET_REMOTE_DEVICE_PROP 0x07
> > +struct hal_msg_cp_bt_get_remote_device_prop {
> > + __bdaddr_t bdaddr;
> > + uint8_t type;
> > +} __packed;
> > +
> > +#define HAL_MSG_OP_BT_SET_REMOTE_DEVICE_PROP 0x08
> > +struct hal_msg_cp_bt_set_remote_device_prop {
> > + __bdaddr_t bdaddr;
> > + uint8_t type;
> > + uint16_t len;
>
> Lets make these all align properly.

Align with tabs? So this will be very different from lib/mgmt.h ?

Best regards
Andrei Emeltchenko


2013-10-10 09:59:54

by Andrei Emeltchenko

[permalink] [raw]
Subject: Re: [PATCHv3 06/15] android: Add basic mgmt initialization sequence

Hi Marcel,

On Wed, Oct 09, 2013 at 09:30:22PM +0200, Marcel Holtmann wrote:
> Hi Andrei,
>
> > Initialize bluetooth controller via mgmt interface.
> > ---
> > Makefile.android | 4 +-
> > android/Android.mk | 11 +++
> > android/main.c | 189 ++++++++++++++++++++++++++++++++++++++++++++++++++++
> > 3 files changed, 203 insertions(+), 1 deletion(-)
> >
> > diff --git a/Makefile.android b/Makefile.android
> > index e161e6d..9a2c486 100644
> > --- a/Makefile.android
> > +++ b/Makefile.android
> > @@ -1,7 +1,9 @@
> > if ANDROID
> > noinst_PROGRAMS += android/bluetoothd
> >
> > -android_bluetoothd_SOURCES = android/main.c src/log.c
> > +android_bluetoothd_SOURCES = android/main.c src/log.c \
> > + src/shared/util.h src/shared/util.c \
> > + src/shared/mgmt.h src/shared/mgmt.c
> > android_bluetoothd_LDADD = @GLIB_LIBS@
> > endif
> >
> > diff --git a/android/Android.mk b/android/Android.mk
> > index 2cabff4..f5fd863 100644
> > --- a/android/Android.mk
> > +++ b/android/Android.mk
> > @@ -15,10 +15,15 @@ include $(CLEAR_VARS)
> > LOCAL_SRC_FILES := \
> > main.c \
> > log.c \
> > + ../src/shared/mgmt.c \
> > + ../src/shared/util.c \
> >
> > LOCAL_C_INCLUDES := \
> > $(call include-path-for, glib) \
> > $(call include-path-for, glib)/glib \
> > +
> > +LOCAL_C_INCLUDES += \
> > + $(LOCAL_PATH)/../ \
> > $(LOCAL_PATH)/../src \
> do we need these nested includes actually? We could also just fix the includes. BlueZ historically has not been good with clear includes. I started to fix this, but it seems I have not gotten to all of them yet.
>

So how do you want it to be? Here I just added BlueZ top-dir.

> > LOCAL_CFLAGS := -DVERSION=\"$(BLUEZ_VERSION)\"
> > @@ -26,6 +31,12 @@ LOCAL_CFLAGS := -DVERSION=\"$(BLUEZ_VERSION)\"
> > # to suppress the "warning: missing initializer near initialization.." warning
> > LOCAL_CFLAGS += -Wno-missing-field-initializers
> >
> > +# to suppress the "pointer of type 'void *' used in arithmetic" warning
> > +LOCAL_CFLAGS += -Wno-pointer-arith
>
> Why do we need to suppress these warning. Can we not just fix them.
>

Is this fix good:

diff --git a/src/shared/mgmt.c b/src/shared/mgmt.c
index 2c79886..b2f5506 100644
--- a/src/shared/mgmt.c
+++ b/src/shared/mgmt.c
@@ -55,7 +55,7 @@ struct mgmt {
unsigned int next_notify_id;
bool in_notify;
bool destroyed;
- void *buf;
+ uint8_t *buf;
uint16_t len;
mgmt_debug_func_t debug_callback;
mgmt_destroy_func_t debug_destroy;
@@ -299,7 +299,7 @@ static gboolean received_data(GIOChannel *channel,
GIOCondition cond,
if (bytes_read < MGMT_HDR_SIZE)
return TRUE;

- hdr = mgmt->buf;
+ hdr = (struct mgmt_hdr *) mgmt->buf;
event = btohs(hdr->opcode);
index = btohs(hdr->index);
length = btohs(hdr->len);
@@ -309,7 +309,7 @@ static gboolean received_data(GIOChannel *channel,
GIOCondition cond,

switch (event) {
case MGMT_EV_CMD_COMPLETE:
- cc = mgmt->buf + MGMT_HDR_SIZE;
+ cc = (struct mgmt_ev_cmd_complete *) mgmt->buf +
MGMT_HDR_SIZE;
opcode = btohs(cc->opcode);

util_debug(mgmt->debug_callback, mgmt->debug_data,
@@ -320,7 +320,7 @@ static gboolean received_data(GIOChannel *channel,
GIOCondition cond,
mgmt->buf + MGMT_HDR_SIZE
+ 3);
break;
case MGMT_EV_CMD_STATUS:
- cs = mgmt->buf + MGMT_HDR_SIZE;
+ cs = (struct mgmt_ev_cmd_status *) mgmt->buf +
MGMT_HDR_SIZE;
opcode = btohs(cs->opcode);

util_debug(mgmt->debug_callback, mgmt->debug_data,

> > +
> > +# Define missing flags for Android 4.2
> > +LOCAL_CFLAGS += -DSOCK_CLOEXEC=02000000 -DSOCK_NONBLOCK=04000
> > +
>
> This thing is dangerous. Do we really bother with Android 4.2 support
> and can not rely on a newer version that has this fixed properly in
> bionic.

The problem here is that our base android-ia from 01.org is based on
4.2.2. Do you still want to remove this?

Best regards
Andrei Emeltchenko

2013-10-10 09:07:00

by Marcin Kraglak

[permalink] [raw]
Subject: Re: [PATCHv3 08/15] android: Add adapter and device struct for BlueZ daemon

Hi Andrei,

On 8 October 2013 16:51, Andrei Emeltchenko
<[email protected]> wrote:
> From: Andrei Emeltchenko <[email protected]>
>
> Adapter structure in BlueZ daemon keeps track of default adapter
> and device structure keeps track about found devices.
> ---
> android/bt_adapter.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++
> android/bt_adapter.h | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 116 insertions(+)
> create mode 100644 android/bt_adapter.c
> create mode 100644 android/bt_adapter.h
>
> diff --git a/android/bt_adapter.c b/android/bt_adapter.c
> new file mode 100644
> index 0000000..e21d50c
> --- /dev/null
> +++ b/android/bt_adapter.c
> @@ -0,0 +1,56 @@
> +/*
> + *
> + * BlueZ - Bluetooth protocol stack for Linux
> + *
> + * Copyright (C) 2013 Intel Corporation. All rights reserved.
> + *
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
> + *
> + */
> +
> +#include "bt_adapter.h"
> +#include "log.h"
> +#include "src/shared/mgmt.h"
> +
> +struct bt_adapter *bt_adapter_new(uint16_t index, struct mgmt *mgmt_if)
> +{
> + struct bt_adapter *adapter;
> +
> + adapter = g_try_new0(struct bt_adapter, 1);
> + if (!adapter)
> + return NULL;
> +
> + adapter->dev_id = index;
> + adapter->mgmt = mgmt_ref(mgmt_if);
> +
> + return adapter;
> +}
> +
> +void adapter_start(struct bt_adapter *adapter)
> +{
> + DBG("enabled %u", adapter->dev_id);
> +
> + /* TODO: CB: report scan mode */
> +
> + /* TODO: SDP start here */
> +
> + /* TODO: CB: report state on */
> +}
> +
> +void adapter_stop(struct bt_adapter *adapter)
> +{
> + DBG("disabled %u", adapter->dev_id);
> +}
> diff --git a/android/bt_adapter.h b/android/bt_adapter.h
> new file mode 100644
> index 0000000..6877cc7
> --- /dev/null
> +++ b/android/bt_adapter.h
> @@ -0,0 +1,60 @@
> +/*
> + *
> + * BlueZ - Bluetooth protocol stack for Linux
> + *
> + * Copyright (C) 2013 Intel Corporation. All rights reserved.
> + *
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
> + *
> + */
> +
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <unistd.h>
> +#include <glib.h>
> +
> +#include "lib/bluetooth.h"
> +
> +struct bt_device {
> + int refcnt;
> +
> + bdaddr_t bdaddr;
> + uint8_t bdaddr_type;
> + uint32_t cod;
> + char *name;
> +};

I'm not sure if we need struct bt_device. Shouldn't we just use bdaddr_t?
All data from this struct will be cached in upper layers, so we don't need to
store it in daemon.

> +
> +struct bt_adapter {
> + int refcnt;
> +
> + uint16_t dev_id;
> + struct mgmt *mgmt;
> + bdaddr_t bdaddr;
> + uint32_t dev_class;
> +
> + char *name;
> + char *short_name;
> +
> + uint32_t supported_settings;
> + uint32_t current_settings;
> +
> + GList *found_devices;
> +};
> +
> +struct bt_adapter *bt_adapter_new(uint16_t index, struct mgmt *mgmt_if);
> +
> +void adapter_start(struct bt_adapter *adapter);
> +void adapter_stop(struct bt_adapter *adapter);
> --
> 1.7.10.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html

Best regards
Marcin

2013-10-10 08:16:59

by Andrei Emeltchenko

[permalink] [raw]
Subject: Re: [PATCHv3 01/15] android: Supress missing initializers warnings

Hi Marcel,

On Thu, Oct 10, 2013 at 10:10:37AM +0200, Marcel Holtmann wrote:
> Hi Andrei,
>
> >>>>> These types of warnings are disabled in BlueZ makeifiles
> >>>>>
> >>>>> main.c:67:2: warning: missing initializer [-Wmissing-field-initializers]
> >>>>> main.c:67:2: warning: (near initialization for 'options[1].short_name')
> >>>>> [-Wmissing-field-initializers]
> >>>>> ---
> >>>>> android/Android.mk | 3 +++
> >>>>> 1 file changed, 3 insertions(+)
> >>>>>
> >>>>> diff --git a/android/Android.mk b/android/Android.mk
> >>>>> index ec820ac..5498b41 100644
> >>>>> --- a/android/Android.mk
> >>>>> +++ b/android/Android.mk
> >>>>> @@ -23,6 +23,9 @@ LOCAL_C_INCLUDES := \
> >>>>>
> >>>>> LOCAL_CFLAGS := -DVERSION=\"$(BLUEZ_VERSION)\"
> >>>>>
> >>>>> +# to suppress the "warning: missing initializer near initialization.." warning
> >>>>> +LOCAL_CFLAGS += -Wno-missing-field-initializers
> >>>>> +
> >>>>
> >>>> why are we doing this and not fixing the actual warning?
> >>>>
> >>>
> >>> Do you want me to initialize structures like
> >>>
> >>> {NULL, NULL, NULL, ... }
> >>>
> >>> this way it can be fixed.
> >>
> >> that is ugly and gets really complicated in the code over time. So I prefer we do not do that.
> >>
> >> Which structures does this affect. All of them?
> >
> > You can just try following patch and see:
> >
> > diff --git a/acinclude.m4 b/acinclude.m4
> > index 5bfa29d..4d6a42c 100644
> > --- a/acinclude.m4
> > +++ b/acinclude.m4
> > @@ -15,7 +15,6 @@ AC_DEFUN([COMPILER_FLAGS], [
> > if (test "$USE_MAINTAINER_MODE" = "yes"); then
> > with_cflags="$with_cflags -Wall -Werror -Wextra"
> > with_cflags="$with_cflags -Wno-unused-parameter"
> > - with_cflags="$with_cflags -Wno-missing-field-initializers"
> > with_cflags="$with_cflags -Wdeclaration-after-statement"
> > with_cflags="$with_cflags -Wmissing-declarations"
> > with_cflags="$with_cflags -Wredundant-decls"
>
> can we then have a global variable in Android.mk that lists all of our
> warning exceptions. Re-assigning them over and over again manually seems
> a rather bad idea.

We can create ANDROID_CFLAGS and include it to other targets. Is this
good?

Best regards
Andrei Emeltchenko

2013-10-10 08:10:37

by Marcel Holtmann

[permalink] [raw]
Subject: Re: [PATCHv3 01/15] android: Supress missing initializers warnings

Hi Andrei,

>>>>> These types of warnings are disabled in BlueZ makeifiles
>>>>>
>>>>> main.c:67:2: warning: missing initializer [-Wmissing-field-initializers]
>>>>> main.c:67:2: warning: (near initialization for 'options[1].short_name')
>>>>> [-Wmissing-field-initializers]
>>>>> ---
>>>>> android/Android.mk | 3 +++
>>>>> 1 file changed, 3 insertions(+)
>>>>>
>>>>> diff --git a/android/Android.mk b/android/Android.mk
>>>>> index ec820ac..5498b41 100644
>>>>> --- a/android/Android.mk
>>>>> +++ b/android/Android.mk
>>>>> @@ -23,6 +23,9 @@ LOCAL_C_INCLUDES := \
>>>>>
>>>>> LOCAL_CFLAGS := -DVERSION=\"$(BLUEZ_VERSION)\"
>>>>>
>>>>> +# to suppress the "warning: missing initializer near initialization.." warning
>>>>> +LOCAL_CFLAGS += -Wno-missing-field-initializers
>>>>> +
>>>>
>>>> why are we doing this and not fixing the actual warning?
>>>>
>>>
>>> Do you want me to initialize structures like
>>>
>>> {NULL, NULL, NULL, ... }
>>>
>>> this way it can be fixed.
>>
>> that is ugly and gets really complicated in the code over time. So I prefer we do not do that.
>>
>> Which structures does this affect. All of them?
>
> You can just try following patch and see:
>
> diff --git a/acinclude.m4 b/acinclude.m4
> index 5bfa29d..4d6a42c 100644
> --- a/acinclude.m4
> +++ b/acinclude.m4
> @@ -15,7 +15,6 @@ AC_DEFUN([COMPILER_FLAGS], [
> if (test "$USE_MAINTAINER_MODE" = "yes"); then
> with_cflags="$with_cflags -Wall -Werror -Wextra"
> with_cflags="$with_cflags -Wno-unused-parameter"
> - with_cflags="$with_cflags -Wno-missing-field-initializers"
> with_cflags="$with_cflags -Wdeclaration-after-statement"
> with_cflags="$with_cflags -Wmissing-declarations"
> with_cflags="$with_cflags -Wredundant-decls"

can we then have a global variable in Android.mk that lists all of our warning exceptions. Re-assigning them over and over again manually seems a rather bad idea.

Regards

Marcel


2013-10-10 08:07:01

by Andrei Emeltchenko

[permalink] [raw]
Subject: Re: [PATCHv3 01/15] android: Supress missing initializers warnings

Hi Marcel,

On Thu, Oct 10, 2013 at 09:35:40AM +0200, Marcel Holtmann wrote:
> Hi Andrei,
>
> >>> These types of warnings are disabled in BlueZ makeifiles
> >>>
> >>> main.c:67:2: warning: missing initializer [-Wmissing-field-initializers]
> >>> main.c:67:2: warning: (near initialization for 'options[1].short_name')
> >>> [-Wmissing-field-initializers]
> >>> ---
> >>> android/Android.mk | 3 +++
> >>> 1 file changed, 3 insertions(+)
> >>>
> >>> diff --git a/android/Android.mk b/android/Android.mk
> >>> index ec820ac..5498b41 100644
> >>> --- a/android/Android.mk
> >>> +++ b/android/Android.mk
> >>> @@ -23,6 +23,9 @@ LOCAL_C_INCLUDES := \
> >>>
> >>> LOCAL_CFLAGS := -DVERSION=\"$(BLUEZ_VERSION)\"
> >>>
> >>> +# to suppress the "warning: missing initializer near initialization.." warning
> >>> +LOCAL_CFLAGS += -Wno-missing-field-initializers
> >>> +
> >>
> >> why are we doing this and not fixing the actual warning?
> >>
> >
> > Do you want me to initialize structures like
> >
> > {NULL, NULL, NULL, ... }
> >
> > this way it can be fixed.
>
> that is ugly and gets really complicated in the code over time. So I prefer we do not do that.
>
> Which structures does this affect. All of them?

You can just try following patch and see:

diff --git a/acinclude.m4 b/acinclude.m4
index 5bfa29d..4d6a42c 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -15,7 +15,6 @@ AC_DEFUN([COMPILER_FLAGS], [
if (test "$USE_MAINTAINER_MODE" = "yes"); then
with_cflags="$with_cflags -Wall -Werror -Wextra"
with_cflags="$with_cflags -Wno-unused-parameter"
- with_cflags="$with_cflags -Wno-missing-field-initializers"
with_cflags="$with_cflags -Wdeclaration-after-statement"
with_cflags="$with_cflags -Wmissing-declarations"
with_cflags="$with_cflags -Wredundant-decls"


Best regards
Andrei Emeltchenko

2013-10-10 07:35:40

by Marcel Holtmann

[permalink] [raw]
Subject: Re: [PATCHv3 01/15] android: Supress missing initializers warnings

Hi Andrei,

>>> These types of warnings are disabled in BlueZ makeifiles
>>>
>>> main.c:67:2: warning: missing initializer [-Wmissing-field-initializers]
>>> main.c:67:2: warning: (near initialization for 'options[1].short_name')
>>> [-Wmissing-field-initializers]
>>> ---
>>> android/Android.mk | 3 +++
>>> 1 file changed, 3 insertions(+)
>>>
>>> diff --git a/android/Android.mk b/android/Android.mk
>>> index ec820ac..5498b41 100644
>>> --- a/android/Android.mk
>>> +++ b/android/Android.mk
>>> @@ -23,6 +23,9 @@ LOCAL_C_INCLUDES := \
>>>
>>> LOCAL_CFLAGS := -DVERSION=\"$(BLUEZ_VERSION)\"
>>>
>>> +# to suppress the "warning: missing initializer near initialization.." warning
>>> +LOCAL_CFLAGS += -Wno-missing-field-initializers
>>> +
>>
>> why are we doing this and not fixing the actual warning?
>>
>
> Do you want me to initialize structures like
>
> {NULL, NULL, NULL, ... }
>
> this way it can be fixed.

that is ugly and gets really complicated in the code over time. So I prefer we do not do that.

Which structures does this affect. All of them?

Regards

Marcel



2013-10-10 07:33:38

by Marcel Holtmann

[permalink] [raw]
Subject: Re: [PATCHv3 03/15] android: Add Socket Bluetooth HAL template

Hi Andrei,

>>> +static bt_status_t listen(btsock_type_t type, const char *service_name,
>>> + const uint8_t *uuid, int chan,
>>> + int *sock, int flags)
>>> +{
>>> + if ((uuid == NULL && chan <= 0) || sock == NULL) {
>>
>> we are moving away from uuid == NULL checks. Use !uuid instead.
>
> I do not like myself these kind of checks but since this seems to be BlueZ
> style. Should I change comparison val != NULL and val != 0 to !val ? Like
> in kernel?

yes, we are slowly moving towards val and !val checks. Especially for new code that coding style has to be enforced now.

Regards

Marcel


2013-10-10 06:58:27

by Andrei Emeltchenko

[permalink] [raw]
Subject: Re: [PATCHv3 01/15] android: Supress missing initializers warnings

Hi Marcel,

On Wed, Oct 09, 2013 at 09:11:04PM +0200, Marcel Holtmann wrote:
> Hi Andrei,
>
> > These types of warnings are disabled in BlueZ makeifiles
> >
> > main.c:67:2: warning: missing initializer [-Wmissing-field-initializers]
> > main.c:67:2: warning: (near initialization for 'options[1].short_name')
> > [-Wmissing-field-initializers]
> > ---
> > android/Android.mk | 3 +++
> > 1 file changed, 3 insertions(+)
> >
> > diff --git a/android/Android.mk b/android/Android.mk
> > index ec820ac..5498b41 100644
> > --- a/android/Android.mk
> > +++ b/android/Android.mk
> > @@ -23,6 +23,9 @@ LOCAL_C_INCLUDES := \
> >
> > LOCAL_CFLAGS := -DVERSION=\"$(BLUEZ_VERSION)\"
> >
> > +# to suppress the "warning: missing initializer near initialization.." warning
> > +LOCAL_CFLAGS += -Wno-missing-field-initializers
> > +
>
> why are we doing this and not fixing the actual warning?
>

Do you want me to initialize structures like

{NULL, NULL, NULL, ... }

this way it can be fixed.

Best regards
Andrei Emeltchenko

2013-10-10 06:56:33

by Andrei Emeltchenko

[permalink] [raw]
Subject: Re: [PATCHv3 03/15] android: Add Socket Bluetooth HAL template

Hi Marcel,

On Wed, Oct 09, 2013 at 09:14:05PM +0200, Marcel Holtmann wrote:
> > +static bt_status_t listen(btsock_type_t type, const char *service_name,
> > + const uint8_t *uuid, int chan,
> > + int *sock, int flags)
> > +{
> > + if ((uuid == NULL && chan <= 0) || sock == NULL) {
>
> we are moving away from uuid == NULL checks. Use !uuid instead.

I do not like myself these kind of checks but since this seems to be BlueZ
style. Should I change comparison val != NULL and val != 0 to !val ? Like
in kernel?

Best regards
Andrei Emeltchenko


2013-10-09 22:55:01

by Lucas De Marchi

[permalink] [raw]
Subject: Re: [PATCHv3 01/15] android: Supress missing initializers warnings

On Wed, Oct 9, 2013 at 4:11 PM, Marcel Holtmann <[email protected]> wrote:
> Hi Andrei,
>
>> These types of warnings are disabled in BlueZ makeifiles
>>
>> main.c:67:2: warning: missing initializer [-Wmissing-field-initializers]
>> main.c:67:2: warning: (near initialization for 'options[1].short_name')
>> [-Wmissing-field-initializers]
>> ---
>> android/Android.mk | 3 +++
>> 1 file changed, 3 insertions(+)
>>
>> diff --git a/android/Android.mk b/android/Android.mk
>> index ec820ac..5498b41 100644
>> --- a/android/Android.mk
>> +++ b/android/Android.mk
>> @@ -23,6 +23,9 @@ LOCAL_C_INCLUDES := \
>>
>> LOCAL_CFLAGS := -DVERSION=\"$(BLUEZ_VERSION)\"
>>
>> +# to suppress the "warning: missing initializer near initialization.." warning
>> +LOCAL_CFLAGS += -Wno-missing-field-initializers
>> +
>
> why are we doing this and not fixing the actual warning?

I guess because this is a stupid warning.

We do the same in autotools because otherwise we can't initialize
structs and rely on compiler setting the rest to 0. This is
particularly annoying on d-bus tables (see the exists and flags on the
end of the GDBusPropertyTable struct). I'm sure it's annoying in other
places, too.


Lucas De Marchi

2013-10-09 19:59:42

by Marcel Holtmann

[permalink] [raw]
Subject: Re: [PATCHv3 14/15] android: Add makefile for hciconfig

Hi Andrei,

>
> ---
> android/Android.mk | 34 ++++++++++++++++++++++++++++++++++
> 1 file changed, 34 insertions(+)
>
> diff --git a/android/Android.mk b/android/Android.mk
> index e7a70d0..09c4579 100644
> --- a/android/Android.mk
> +++ b/android/Android.mk
> @@ -123,3 +123,37 @@ $(foreach file,$(lib_headers), $(shell ln -sf ../$(file) $(LOCAL_PATH)/../lib/bl
> LOCAL_MODULE := libbluetooth
>
> include $(BUILD_SHARED_LIBRARY)
> +
> +#
> +# hciconfig
> +#

why are we building this one. Only btmgmt should be needed for testing. If at all.

Regards

Marcel


2013-10-09 19:58:44

by Marcel Holtmann

[permalink] [raw]
Subject: Re: [PATCHv3 13/15] android: Handle mgmt changed events

Hi Andrei,

> From: Andrei Emeltchenko <[email protected]>
>
> Add code handling changing adapter settings.
> ---
> android/main.c | 154 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 154 insertions(+)
>
> diff --git a/android/main.c b/android/main.c
> index a2ed8a4..c181d3a 100644
> --- a/android/main.c
> +++ b/android/main.c
> @@ -127,6 +127,159 @@ static void load_link_keys_complete(uint8_t status, uint16_t length,
> DBG("status %u", status);
> }
>
> +static void mgmt_local_name_changed_event(uint16_t index, uint16_t length,
> + const void *param, void *user_data)
> +{
> + struct bt_adapter *adapter = user_data;
> + const struct mgmt_cp_set_local_name *rp = param;
> +
> + if (length < sizeof(*rp)) {
> + error("Wrong size of local name changed parameters");
> + return;
> + }
> +
> + if (adapter != default_adapter) {
> + error("Wrong adapter %p", adapter);
> + return;
> + }

this check is rather useless if the events are all registered per adapter. With mgmt you can register events for a specific index.

> +
> + if (!g_strcmp0(adapter->short_name, (const char *) rp->short_name) &&
> + !g_strcmp0(adapter->name, (const char *) rp->name))
> + return;

Don't bother with the short name.

> +
> + DBG("name: %s short name: %s", rp->name, rp->short_name);
> +
> + g_free(adapter->name);
> + adapter->name = g_strdup((const char *) rp->name);
> +
> + g_free(adapter->short_name);
> + adapter->short_name = g_strdup((const char *) rp->short_name);
> +
> + /* TODO Update services if needed */
> +}
> +
> +static void settings_changed_connectable(struct bt_adapter *adapter)
> +{
> + /* TODO */
> +}
> +
> +static void settings_changed_discoverable(struct bt_adapter *adapter)
> +{
> + /* TODO */
> +}
> +
> +static void settings_changed(struct bt_adapter *adapter, uint32_t settings)
> +{
> + uint32_t changed_mask;
> +
> + changed_mask = adapter->current_settings ^ settings;
> +
> + adapter->current_settings = settings;
> +
> + DBG("0x%08x", changed_mask);
> +
> + if (changed_mask & MGMT_SETTING_POWERED) {
> + info("Powered");
> +
> + if (adapter->current_settings & MGMT_SETTING_POWERED)
> + adapter_start(adapter);
> + else
> + adapter_stop(adapter);
> + }
> +
> + /* Seems not needed for Android */
> + if (changed_mask & MGMT_SETTING_PAIRABLE)
> + DBG("Pairable");

We should always enable pairable when setting up the adapter.

> +
> + /*
> + * There are only 2 scan modes:
> + * CONNECTABLE and CONNECTABLE_DISCOVERABLE
> + */

I can not make heads or tails out of this comment.

> + if (changed_mask & MGMT_SETTING_CONNECTABLE) {
> + DBG("Connectable");
> +
> + settings_changed_connectable(adapter);
> + }
> +
> + if (changed_mask & MGMT_SETTING_DISCOVERABLE) {
> + DBG("Discoverable");
> +
> + settings_changed_discoverable(adapter);
> + }
> +}
> +
> +static void new_settings_callback(uint16_t index, uint16_t length,
> + const void *param, void *user_data)
> +{
> + struct bt_adapter *adapter = user_data;
> + uint32_t settings;
> +
> + if (length < sizeof(settings)) {
> + error("Wrong size of new settings parameters");
> + return;
> + }
> +
> + if (adapter != default_adapter) {
> + error("Wrong adapter %p", adapter);
> + return;
> + }
> +
> + settings = bt_get_le32(param);
> +
> + DBG("settings: 0x%8.8x -> 0x%8.8x", adapter->current_settings,
> + settings);
> +
> + if (settings == adapter->current_settings)
> + return;
> +
> + settings_changed(adapter, settings);
> +}
> +
> +static void mgmt_dev_class_changed_event(uint16_t index, uint16_t length,
> + const void *param, void *user_data)
> +{
> + struct bt_adapter *adapter = user_data;
> + const struct mgmt_cod *rp = param;
> + uint32_t dev_class;
> +
> + if (length < sizeof(*rp)) {
> + error("Wrong size of class of device changed parameters");
> + return;
> + }
> +
> + if (adapter != default_adapter) {
> + error("Wrong adapter %p", adapter);
> + return;
> + }
> +
> + dev_class = rp->val[0] | (rp->val[1] << 8) | (rp->val[2] << 16);
> +
> + if (dev_class == adapter->dev_class)
> + return;
> +
> + DBG("Class: 0x%06x", dev_class);
> +
> + adapter->dev_class = dev_class;
> +
> + /* TODO: Inform prop change: Class */
> +
> + /* TODO: Gatt attrib set*/
> +}
> +
> +static void register_mgmt_handlers(struct bt_adapter *adapter)
> +{
> + mgmt_register(adapter->mgmt, MGMT_EV_NEW_SETTINGS, adapter->dev_id,
> + new_settings_callback, adapter, NULL);
> +
> + mgmt_register(adapter->mgmt, MGMT_EV_CLASS_OF_DEV_CHANGED,
> + adapter->dev_id, mgmt_dev_class_changed_event,
> + adapter, NULL);
> +
> + mgmt_register(adapter->mgmt, MGMT_EV_LOCAL_NAME_CHANGED,
> + adapter->dev_id, mgmt_local_name_changed_event,
> + adapter, NULL);
> +}
> +
> static void load_link_keys(struct bt_adapter *adapter, GSList *keys)
> {
> struct mgmt_cp_load_link_keys *cp;
> @@ -187,6 +340,7 @@ static void read_info_complete(uint8_t status, uint16_t length,
> adapter->current_settings = btohs(rp->current_settings);
>
> /* TODO: Register all event notification handlers */
> + register_mgmt_handlers(default_adapter);
>
> if (adapter->current_settings & MGMT_SETTING_POWERED)
> adapter_start(adapter);

Regards

Marcel


2013-10-09 19:54:01

by Marcel Holtmann

[permalink] [raw]
Subject: Re: [PATCHv3 12/15] android: Implement read_info_complete callback

Hi Andrei,

> Handle read info complete callback from mgmt interface.
> ---
> android/main.c | 101 +++++++++++++++++++++++++++++++++++++++++++++++++-------
> 1 file changed, 89 insertions(+), 12 deletions(-)
>
> diff --git a/android/main.c b/android/main.c
> index a100013..a2ed8a4 100644
> --- a/android/main.c
> +++ b/android/main.c
> @@ -54,6 +54,7 @@
> #include "log.h"
> #include "hcid.h"
> #include "sdpd.h"
> +#include "bt_adapter.h"
>
> #include "lib/bluetooth.h"
> #include "lib/mgmt.h"
> @@ -69,6 +70,8 @@ static struct mgmt *mgmt_if = NULL;
> static uint8_t mgmt_version = 0;
> static uint8_t mgmt_revision = 0;
>
> +struct bt_adapter *default_adapter = NULL;
> +
> static int sdp_start(void)
> {
> DBG("");
> @@ -118,34 +121,108 @@ static GOptionEntry options[] = {
> { NULL }
> };
>
> -static void read_info_complete(uint8_t status, uint16_t length,
> +static void load_link_keys_complete(uint8_t status, uint16_t length,
> const void *param, void *user_data)
> {
> - /* TODO: Store Controller information */
> -
> - /**
> - * Register all event notification handlers for controller.
> - *
> - * The handlers are registered after a succcesful read of the
> - * controller info. From now on they can track updates and
> - * notifications.
> - */
> + DBG("status %u", status);
> }
>
> +static void load_link_keys(struct bt_adapter *adapter, GSList *keys)
> +{
> + struct mgmt_cp_load_link_keys *cp;
> + size_t key_len = g_slist_length(keys);
> + struct mgmt_link_key_info *key;
> + size_t len;
> +
> + DBG("");
> +
> + len = sizeof(*cp) + key_len * sizeof(*key);
> + cp = g_try_malloc0(len);
> + if (cp == NULL) {
> + error("%s: Not enough memory for link keys loading", __func__);
> + return;
> + }

I am really fine with just using g_malloc0 and aborting the program in case of memory allocation errors.

> +
> + cp->debug_keys = 0;
> + cp->key_count = htobs(key_len);
> +
> + mgmt_send(adapter->mgmt, MGMT_OP_LOAD_LINK_KEYS, adapter->dev_id, len,
> + cp, load_link_keys_complete, adapter, NULL);
> +
> + free(cp);
> +}
> +
> +static void read_info_complete(uint8_t status, uint16_t length,
> + const void *param, void *user_data)
> +{
> + struct bt_adapter *adapter = user_data;
> + const struct mgmt_rp_read_info *rp = param;
> +
> + DBG("");
> +
> + if (status != MGMT_STATUS_SUCCESS) {
> + error("Failed to read info for index %u: %s (0x%02x)",
> + adapter->dev_id, mgmt_errstr(status), status);
> + goto failed;
> + }
> +
> + if (length < sizeof(*rp)) {
> + error("Too small read info complete response");
> + goto failed;
> + }
> +
> + if (bacmp(&rp->bdaddr, BDADDR_ANY) == 0) {
> + error("No Bluetooth address for index %u", adapter->dev_id);
> + goto failed;
> + }
> +
> + /* Store adapter information */
> + bacpy(&adapter->bdaddr, &rp->bdaddr);
> + adapter->dev_class = rp->dev_class[0] | (rp->dev_class[1] << 8) |
> + (rp->dev_class[2] << 16);
> + adapter->name = g_strdup((const char *) rp->name);
> + adapter->short_name = g_strdup((const char *) rp->short_name);

Don't bother with the short name.

> +
> + adapter->supported_settings = btohs(rp->supported_settings);
> + adapter->current_settings = btohs(rp->current_settings);
> +
> + /* TODO: Register all event notification handlers */
> +
> + if (adapter->current_settings & MGMT_SETTING_POWERED)
> + adapter_start(adapter);
> +
> + /* dummy link keys loading */

The comment is wrong here. Just load the link keys. Even an empty list of keys needs to be loaded.

> + load_link_keys(adapter, NULL);
> +
> + return;
> +
> +failed:
> + default_adapter = NULL;
> +}
>
> static void mgmt_index_added_event(uint16_t index, uint16_t length,
> const void *param, void *user_data)
> {
> info("%s: index %u", __func__, index);
>
> + if (default_adapter != NULL) {

if (default_adapter)

> + DBG("skip event for index %d", index);

If you copy code from src/adapter.c that uses %u for the index, then be consistent.

> + return;
> + }
> +
> + default_adapter = bt_adapter_new(index, mgmt_if);
> + if (default_adapter == NULL) {

And here again, just assume memory allocation succeeds.

> + error("Unable to create new adapter for index %u", index);
> + return;
> + }
> +
> DBG("sending read info command for index %u", index);
>
> if (mgmt_send(mgmt_if, MGMT_OP_READ_INFO, index, 0, NULL,
> - read_info_complete, NULL, NULL) > 0)
> + read_info_complete, default_adapter, NULL) > 0)
> return;
>
> error("Failed to read adapter info for index %u", index);
> -
> }

Regards

Marcel


2013-10-09 19:48:33

by Marcel Holtmann

[permalink] [raw]
Subject: Re: [PATCHv3 11/15] android: Add cap to bind to port < 1024

Hi Andrei,

> For SDP server we need to bind to lower port, acquire this capability.
> ---
> android/main.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> configure.ac | 4 ++++
> 2 files changed, 75 insertions(+)
>
> diff --git a/android/main.c b/android/main.c
> index 7968ed0..a100013 100644
> --- a/android/main.c
> +++ b/android/main.c
> @@ -32,6 +32,22 @@
> #include <stdlib.h>
> #include <stdbool.h>
> #include <string.h>
> +#include <unistd.h>
> +#include <errno.h>
> +#include <sys/prctl.h>
> +#include <linux/capability.h>
> +
> +/**
> + * Include <sys/capability.h> for host build and
> + * also for Android 4.3 when it is added to bionic
> + */

why focus on anything before Android 4.3?

> +#if !defined(ANDROID) || (PLATFORM_SDK_VERSION > 17)
> +#include <sys/capability.h>
> +#endif
> +
> +#if defined(ANDROID)
> +#include <private/android_filesystem_config.h>
> +#endif
>
> #include <glib.h>
>
> @@ -279,6 +295,58 @@ static void cleanup_mgmt_interface(void)
> mgmt_if = NULL;
> }
>
> +static bool android_set_aid_and_cap(void)
> +{
> + struct __user_cap_header_struct header;
> + struct __user_cap_data_struct cap;
> +#if defined(ANDROID)
> + gid_t groups[] = {AID_NET_BT, AID_NET_BT_ADMIN, AID_NET_ADMIN};
> +#endif
> +
> + DBG("pid %d uid %d gid %d", getpid(), getuid(), getgid());
> +
> + header.version = _LINUX_CAPABILITY_VERSION;
> +
> + prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0);
> +
> +#if defined(ANDROID)
> + if (setgid(AID_BLUETOOTH) < 0)
> + warn("%s: setgid(): %s", __func__, strerror(errno));
> +
> + if (setuid(AID_BLUETOOTH) < 0)
> + warn("%s: setuid(): %s", __func__, strerror(errno));
> +#endif
> +
> + header.version = _LINUX_CAPABILITY_VERSION;
> + header.pid = 0;
> +
> + cap.effective = cap.permitted =
> + CAP_TO_MASK(CAP_SETGID) |
> + CAP_TO_MASK(CAP_NET_RAW) |
> + CAP_TO_MASK(CAP_NET_ADMIN) |
> + CAP_TO_MASK(CAP_NET_BIND_SERVICE);
> + cap.inheritable = 0;
> +
> + if (capset(&header, &cap) < 0) {
> + error("%s: capset(): %s", __func__, strerror(errno));
> + return false;
> + }
> +
> +#if defined(ANDROID)
> + if (setgroups(sizeof(groups)/sizeof(groups[0]), groups) < 0)
> + warn("%s: setgroups: %s", __func__, strerror(errno));
> +#endif
> + if (capget(&header, &cap) < 0)
> + error("%s: capget(): %s", __func__, strerror(errno));
> + else
> + DBG("Caps: eff: 0x%x, perm: 0x%x, inh: 0x%x", cap.effective,
> + cap.permitted, cap.inheritable);
> +
> + DBG("pid %d uid %d gid %d", getpid(), getuid(), getgid());
> +
> + return true;
> +}
> +
> int main(int argc, char *argv[])
> {
> GOptionContext *context;
> @@ -312,6 +380,9 @@ int main(int argc, char *argv[])
> sigaction(SIGINT, &sa, NULL);
> sigaction(SIGTERM, &sa, NULL);
>
> + if (android_set_aid_and_cap() == false)

Please check with if (!android?())

> + exit(EXIT_FAILURE);
> +

I prefer return EXIT_FAILURE;

> init_mgmt_interface();
> sdp_start();
>
> diff --git a/configure.ac b/configure.ac
> index 7b1f64a..5406434 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -247,4 +247,8 @@ AC_ARG_ENABLE(android, AC_HELP_STRING([--enable-android],
> [enable_android=${enableval}])
> AM_CONDITIONAL(ANDROID, test "${enable_android}" = "yes")
>
> +if (test "${android_daemon}" = "yes"); then
> + AC_CHECK_LIB(cap, capget, dummy=yes, AC_MSG_ERROR(libcap is required))
> +fi
> +
> AC_OUTPUT(Makefile src/bluetoothd.8 lib/bluez.pc)

REgards

Marcel


2013-10-09 19:45:58

by Marcel Holtmann

[permalink] [raw]
Subject: Re: [PATCHv3 10/15] android: sdp: Reuse BlueZ SDP server in Android

Hi Andei,

> Reuse existing SDP server code in Android GPL daemon.
> ---
> Makefile.android | 7 +++++--
> android/Android.mk | 7 +++++++
> android/bt_adapter.c | 2 --
> android/main.c | 28 ++++++++++++++++++++++++++++
> 4 files changed, 40 insertions(+), 4 deletions(-)
>
> diff --git a/Makefile.android b/Makefile.android
> index 9a2c486..d576b52 100644
> --- a/Makefile.android
> +++ b/Makefile.android
> @@ -2,9 +2,12 @@ if ANDROID
> noinst_PROGRAMS += android/bluetoothd
>
> android_bluetoothd_SOURCES = android/main.c src/log.c \
> + src/sdpd-database.c src/sdpd-server.c \
> + src/sdpd-service.c src/sdpd-request.c \
> src/shared/util.h src/shared/util.c \
> - src/shared/mgmt.h src/shared/mgmt.c
> -android_bluetoothd_LDADD = @GLIB_LIBS@
> + src/shared/mgmt.h src/shared/mgmt.c \
> + android/bt_adapter.h android/bt_adapter.c
> +android_bluetoothd_LDADD = lib/libbluetooth-internal.la @GLIB_LIBS@
> endif
>
> EXTRA_DIST += android/Android.mk android/log.c
> diff --git a/android/Android.mk b/android/Android.mk
> index 8f95a66..e7a70d0 100644
> --- a/android/Android.mk
> +++ b/android/Android.mk
> @@ -17,6 +17,11 @@ LOCAL_SRC_FILES := \
> log.c \
> ../src/shared/mgmt.c \
> ../src/shared/util.c \
> + bt_adapter.c \
> + ../src/sdpd-database.c \
> + ../src/sdpd-service.c \
> + ../src/sdpd-request.c \
> + ../src/sdpd-server.c \
>
> LOCAL_C_INCLUDES := \
> $(call include-path-for, glib) \
> @@ -25,6 +30,7 @@ LOCAL_C_INCLUDES := \
> LOCAL_C_INCLUDES += \
> $(LOCAL_PATH)/../ \
> $(LOCAL_PATH)/../src \
> + $(LOCAL_PATH)/../lib \
>
> LOCAL_CFLAGS := -DVERSION=\"$(BLUEZ_VERSION)\"
>
> @@ -39,6 +45,7 @@ LOCAL_CFLAGS += -DSOCK_CLOEXEC=02000000 -DSOCK_NONBLOCK=04000
>
> LOCAL_SHARED_LIBRARIES := \
> libglib \
> + libbluetooth \
>
> LOCAL_MODULE := bluetoothd
> LOCAL_REQUIRED_MODULES := libbluetooth
> diff --git a/android/bt_adapter.c b/android/bt_adapter.c
> index e21d50c..6b758bf 100644
> --- a/android/bt_adapter.c
> +++ b/android/bt_adapter.c
> @@ -45,8 +45,6 @@ void adapter_start(struct bt_adapter *adapter)
>
> /* TODO: CB: report scan mode */
>
> - /* TODO: SDP start here */
> -
> /* TODO: CB: report state on */
> }
>
> diff --git a/android/main.c b/android/main.c
> index 3580ac7..7968ed0 100644
> --- a/android/main.c
> +++ b/android/main.c
> @@ -36,6 +36,8 @@
> #include <glib.h>
>
> #include "log.h"
> +#include "hcid.h"

The hcid.h include is bogus. That should not be needed. If it is, then we need to fix that first.

> +#include "sdpd.h"
>
> #include "lib/bluetooth.h"
> #include "lib/mgmt.h"
> @@ -43,12 +45,36 @@
>
> #define SHUTDOWN_GRACE_SECONDS 10
>
> +struct main_opts main_opts;
> +
> static GMainLoop *event_loop;
> static struct mgmt *mgmt_if = NULL;
>
> static uint8_t mgmt_version = 0;
> static uint8_t mgmt_revision = 0;
>
> +static int sdp_start(void)
> +{
> + DBG("");
> +
> + /* TODO: add logic */
> +
> + /* sdpd-server use these settings */
> + memset(&main_opts, 0, sizeof(main_opts));

Then fix sdpd-server to not use these. I do not want this included.

> +
> + /* Use params: mtu = 0, flags = 0 */
> + return start_sdp_server(0, 0);
> +}
> +
> +static void sdp_stop(void)
> +{
> + DBG("");
> +
> + /* TODO: add logic */
> +
> + stop_sdp_server();
> +}
> +

Right now sdp_start and sdp_stop look like pointless wrappers around nothing.

> static gboolean quit_eventloop(gpointer user_data)
> {
> g_main_loop_quit(event_loop);
> @@ -287,11 +313,13 @@ int main(int argc, char *argv[])
> sigaction(SIGTERM, &sa, NULL);
>
> init_mgmt_interface();
> + sdp_start();
>
> DBG("Entering main loop");
>
> g_main_loop_run(event_loop);
>
> + sdp_stop();
> cleanup_mgmt_interface();
> g_main_loop_unref(event_loop);

Regards

Marcel


2013-10-09 19:43:18

by Marcel Holtmann

[permalink] [raw]
Subject: Re: [PATCHv3 09/15] android: Add Android Makefile for libbluetooth

Hi Andrei,

> Build libbluetooth library for Android.
> ---
> android/Android.mk | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 53 insertions(+)
>
> diff --git a/android/Android.mk b/android/Android.mk
> index f5fd863..8f95a66 100644
> --- a/android/Android.mk
> +++ b/android/Android.mk
> @@ -41,6 +41,7 @@ LOCAL_SHARED_LIBRARIES := \
> libglib \
>
> LOCAL_MODULE := bluetoothd
> +LOCAL_REQUIRED_MODULES := libbluetooth
>
> include $(BUILD_EXECUTABLE)
>
> @@ -63,3 +64,55 @@ LOCAL_MODULE_TAGS := optional
> LOCAL_MODULE_CLASS := SHARED_LIBRARIES
>
> include $(BUILD_SHARED_LIBRARY)
> +
> +#
> +# libbluetooth library
> +#
> +
> +include $(CLEAR_VARS)
> +
> +LOCAL_SRC_FILES := \
> + ../lib/bluetooth.c \
> + ../lib/sdp.c \
> + ../lib/hci.c \
> + ../lib/uuid.c \

why are we building a shared library here. What is it useful for. Even within BlueZ we do not install libbluetooth anymore.

> +
> +LOCAL_C_INCLUDES := \
> + $(LOCAL_PATH)/../lib/ \
> + $(LOCAL_PATH)/../src/shared \

The library clearly does not include anything from src/shared/. So what is that doing here.

> +
> +LOCAL_C_INCLUDES += \
> + $(call include-path-for, glib) \
> + $(call include-path-for, glib)/glib \

The library clearly does not need GLib. So why are we doing that here.

> +
> +LOCAL_CFLAGS += -O3
> +
> +# to suppress the "pointer of type 'void *' used in arithmetic" warning
> +LOCAL_CFLAGS += -Wno-pointer-arith
> +
> +# to suppress the "missing initializer near initialization" warning
> +LOCAL_CFLAGS += -Wno-missing-field-initializers

Lets fix the actual warnings.

> +
> +# Define missing flags for Android 4.2
> +LOCAL_CFLAGS += -DSOCK_CLOEXEC=02000000 -DSOCK_NONBLOCK=04000

And are we sure that these flags are needed for the library.

> +
> +lib_headers := \
> + bluetooth.h \
> + hci.h \
> + hci_lib.h \
> + sco.h \
> + l2cap.h \
> + sdp.h \
> + sdp_lib.h \
> + rfcomm.h \
> + bnep.h \
> + cmtp.h \
> + hidp.h \

I would really prefer we do not install these.

> +
> +$(shell mkdir -p $(LOCAL_PATH)/../lib/bluetooth)
> +
> +$(foreach file,$(lib_headers), $(shell ln -sf ../$(file) $(LOCAL_PATH)/../lib/bluetooth/$(file)))
> +
> +LOCAL_MODULE := libbluetooth
> +
> +include $(BUILD_SHARED_LIBRARY)

Regards

Marcel


2013-10-09 19:39:34

by Marcel Holtmann

[permalink] [raw]
Subject: Re: [PATCHv3 08/15] android: Add adapter and device struct for BlueZ daemon

Hi Andrei,

> Adapter structure in BlueZ daemon keeps track of default adapter
> and device structure keeps track about found devices.
> ---
> android/bt_adapter.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++
> android/bt_adapter.h | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 116 insertions(+)
> create mode 100644 android/bt_adapter.c
> create mode 100644 android/bt_adapter.h
>
> diff --git a/android/bt_adapter.c b/android/bt_adapter.c
> new file mode 100644
> index 0000000..e21d50c
> --- /dev/null
> +++ b/android/bt_adapter.c
> @@ -0,0 +1,56 @@
> +/*
> + *
> + * BlueZ - Bluetooth protocol stack for Linux
> + *
> + * Copyright (C) 2013 Intel Corporation. All rights reserved.
> + *
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
> + *
> + */
> +
> +#include "bt_adapter.h"

the include of its own header should always be the last one. Never the first one.


> +#include "log.h"
> +#include "src/shared/mgmt.h"
> +
> +struct bt_adapter *bt_adapter_new(uint16_t index, struct mgmt *mgmt_if)
> +{
> + struct bt_adapter *adapter;
> +
> + adapter = g_try_new0(struct bt_adapter, 1);
> + if (!adapter)
> + return NULL;

Since this all brand new code, use g_new0 and we just exit on memory allocation failures for our own data structures.

> +
> + adapter->dev_id = index;
> + adapter->mgmt = mgmt_ref(mgmt_if);
> +
> + return adapter;
> +}
> +
> +void adapter_start(struct bt_adapter *adapter)

Why does this now have no bt_ prefix?

> +{
> + DBG("enabled %u", adapter->dev_id);
> +
> + /* TODO: CB: report scan mode */
> +
> + /* TODO: SDP start here */
> +
> + /* TODO: CB: report state on */
> +}
> +
> +void adapter_stop(struct bt_adapter *adapter)
> +{
> + DBG("disabled %u", adapter->dev_id);
> +}
> diff --git a/android/bt_adapter.h b/android/bt_adapter.h
> new file mode 100644
> index 0000000..6877cc7
> --- /dev/null
> +++ b/android/bt_adapter.h
> @@ -0,0 +1,60 @@
> +/*
> + *
> + * BlueZ - Bluetooth protocol stack for Linux
> + *
> + * Copyright (C) 2013 Intel Corporation. All rights reserved.
> + *
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
> + *
> + */
> +
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <unistd.h>
> +#include <glib.h>
> +
> +#include "lib/bluetooth.h"
> +
> +struct bt_device {
> + int refcnt;
> +
> + bdaddr_t bdaddr;
> + uint8_t bdaddr_type;
> + uint32_t cod;
> + char *name;
> +};

Why is bt_device declared in bt_adapter. And why are these public in the first place. Please hide these details.

> +
> +struct bt_adapter {
> + int refcnt;
> +
> + uint16_t dev_id;

And now we are falling back to calling this dev_id. Do we need the index at all actually?

> + struct mgmt *mgmt;
> + bdaddr_t bdaddr;
> + uint32_t dev_class;
> +
> + char *name;
> + char *short_name;

If we are not using the short name, then don't bother storing it. Only implement things we really need.

> +
> + uint32_t supported_settings;
> + uint32_t current_settings;
> +
> + GList *found_devices;
> +};
> +
> +struct bt_adapter *bt_adapter_new(uint16_t index, struct mgmt *mgmt_if);
> +
> +void adapter_start(struct bt_adapter *adapter);
> +void adapter_stop(struct bt_adapter *adapter);

Regards

Marcel


2013-10-09 19:34:17

by Marcel Holtmann

[permalink] [raw]
Subject: Re: [PATCHv3 07/15] android: Create HAL API header skeleton

Hi Andrei,

> Header describes the protocol between Android HAL threads and BlueZ
> daemon.
> ---
> android/hal_msg.h | 255 +++++++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 255 insertions(+)
> create mode 100644 android/hal_msg.h
>
> diff --git a/android/hal_msg.h b/android/hal_msg.h
> new file mode 100644
> index 0000000..c6bc883
> --- /dev/null
> +++ b/android/hal_msg.h
> @@ -0,0 +1,255 @@
> +/*
> + *
> + * BlueZ - Bluetooth protocol stack for Linux
> + *
> + * Copyright (C) 2013 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
> + *
> + */
> +
> +#ifndef __packed
> +#define __packed __attribute__((packed))
> +#endif

nowhere in the code we are using __packed. That is more a kernel thing. Just use the gcc style directly.

> +
> +typedef struct {
> + uint8_t b[6];
> +} __packed __bdaddr_t;

Just use a uint8_t bdaddr[6] instead.

> +
> +struct hal_msg_hdr {
> + uint8_t service_id;
> + uint8_t opcode;
> + uint16_t len;
> + uint8_t payload[0];

I would not include the payload[0] here.

> +} __packed;
> +
> +#define HAL_SERVICE_ID_CORE 0
> +#define HAL_SERVICE_ID_BLUETOOTH 1
> +#define HAL_SERVICE_ID_SOCK 2
> +#define HAL_SERVICE_ID_HIDHOST 3
> +#define HAL_SERVICE_ID_PAN 4
> +#define HAL_SERVICE_ID_HANDSFREE 5
> +#define HAL_SERVICE_ID_AD2P 6
> +#define HAL_SERVICE_ID_HEALTH 7
> +#define HAL_SERVICE_ID_AVRCP 8
> +#define HAL_SERVICE_ID_GATT 9
> +
> +/* Core Service */
> +
> +#define HAL_MSG_OP_ERROR 0x00
> +struct hal_msg_rp_error {
> + uint8_t status;
> +} __packed;

using RSP, rsp, CMD, cmd, EVT and EVT seems to be clearer I think.

> +
> +#define HAL_MSG_OP_REGISTER_MODULE 0x01
> +struct hal_msg_cp_register_module {
> + uint8_t service_id;
> +} __packed;
> +struct hal_msg_rp_register_module {
> + uint8_t service_id;
> +} __packed;
> +
> +#define HAL_MSG_OP_UNREGISTER_MODULE 0x02
> +struct hal_msg_cp_unregister_module {
> + uint8_t service_id;
> +} __packed;
> +
> +/* Bluetooth Core HAL API */
> +
> +#define HAL_MSG_OP_BT_ENABLE 0x01
> +
> +#define HAL_MSG_OP_BT_DISABLE 0x02
> +
> +#define HAL_MSG_OP_BT_GET_ADAPTER_PROPS 0x03
> +
> +#define HAL_MSG_OP_BT_GET_ADAPTER_PROP 0x04
> +struct hal_msg_cp_bt_get_adapter_prop {
> + uint8_t type;
> +} __packed;
> +
> +#define HAL_MSG_OP_BT_SET_ADAPTER_PROP 0x05
> +struct hal_msg_cp_bt_set_adapter_prop {
> + uint8_t type;
> + uint16_t len;
> + uint8_t val[0];
> +} __packed;
> +
> +#define HAL_MSG_OP_BT_GET_REMOTE_DEVICE_PROPS 0x06
> +struct hal_msg_cp_bt_get_remote_device_props {
> + __bdaddr_t bdaddr;
> +} __packed;
> +
> +#define HAL_MSG_OP_BT_GET_REMOTE_DEVICE_PROP 0x07
> +struct hal_msg_cp_bt_get_remote_device_prop {
> + __bdaddr_t bdaddr;
> + uint8_t type;
> +} __packed;
> +
> +#define HAL_MSG_OP_BT_SET_REMOTE_DEVICE_PROP 0x08
> +struct hal_msg_cp_bt_set_remote_device_prop {
> + __bdaddr_t bdaddr;
> + uint8_t type;
> + uint16_t len;

Lets make these all align properly.

> + uint8_t val[0];
> +} __packed;
> +
> +#define HAL_MSG_OP_BT_GET_REMOTE_SERVICE_REC 0x09
> +struct hal_msg_cp_bt_get_remote_service_rec {
> + __bdaddr_t bdaddr;
> + uint8_t uuid[16];
> +} __packed;
> +
> +#define HAL_MSG_OP_BT_GET_REMOTE_SERVICE 0x0a
> +struct hal_msg_cp_bt_get_remote_service {
> + __bdaddr_t bdaddr;
> +} __packed;
> +
> +#define HAL_MSG_OP_BT_START_DISCOVERY 0x0b
> +
> +#define HAL_MSG_OP_BT_CANCEL_DISCOVERY 0x0c
> +
> +#define HAL_MSG_OP_BT_CREATE_BOND 0x0d
> +struct hal_msg_cp_bt_create_bond {
> + __bdaddr_t bdaddr;
> +} __packed;
> +
> +#define HAL_MSG_OP_BT_REMOVE_BOND 0x0d
> +struct hal_msg_cp_bt_remove_bond {
> + __bdaddr_t bdaddr;
> +} __packed;
> +
> +#define HAL_MSG_OP_BT_CANCEL_BOND 0x0f
> +struct hal_msg_cp_bt_cancel_bond {
> + __bdaddr_t bdaddr;
> +} __packed;
> +
> +#define HAL_MSG_OP_BT_PIN_REPLY 0x10
> +struct hal_msg_cp_bt_pin_reply {
> + __bdaddr_t bdaddr;
> + uint8_t accept;
> + uint8_t pin_len;
> + uint8_t pin_code[16];
> +} __packed;
> +
> +#define HAL_MSG_OP_BT_SSP_REPLY 0x11
> +struct hal_msg_cp_bt_ssp_reply {
> + __bdaddr_t bdaddr;
> + uint8_t ssp_variant;
> + uint8_t accept;
> + uint32_t passkey;
> +} __packed;
> +
> +#define HAL_MSG_OP_BT_DUT_MODE_CONF 0x12
> +struct hal_msg_cp_bt_dut_mode_conf {
> + uint8_t enable;
> +} __packed;
> +
> +#define HAL_MSG_OP_BT_DUT_MODE_SEND 0x13
> +struct hal_msg_cp_bt_dut_mode_send {
> + uint16_t opcode;
> + uint8_t len;
> + uint8_t data[0];
> +} __packed;
> +
> +#define HAL_MSG_OP_BT_LE_TEST_MODE 0x14
> +struct hal_msg_cp_bt_le_test_mode {
> + uint16_t opcode;
> + uint8_t len;
> + uint8_t data[0];
> +} __packed;
> +
> +/* Notifications and confirmations */
> +
> +#define HAL_MSG_EV_BT_ERROR 0x80
> +
> +#define HAL_MSG_EV_BT_ADAPTER_STATE_CHANGED 0x81
> +struct hal_msg_ev_bt_adapter_state_changed {
> + uint8_t state;
> +} __packed;
> +
> +#define HAL_MSG_EV_BT_ADAPTER_PROPS_CHANGED 0x82
> +struct hal_property {
> + uint8_t type;
> + uint16_t len;
> + uint8_t val[0];
> +} __packed;
> +struct hal_msg_ev_bt_adapter_props_changed {
> + uint8_t status;
> + uint8_t num_props;
> + struct hal_property props[0];
> +} __packed;
> +
> +#define HAL_MSG_EV_BT_REMOTE_DEVICE_PROPS 0x83
> +struct hal_msg_ev_bt_remote_device_props {
> + uint8_t status;
> + __bdaddr_t bdaddr;
> + uint8_t num_props;
> + struct hal_property props[0];
> +} __packed;
> +
> +#define HAL_MSG_EV_BT_DEVICE_FOUND 0x84
> +struct hal_msg_ev_bt_device_found {
> + uint8_t num_props;
> + struct hal_property props[0];
> +} __packed;
> +
> +#define HAL_MSG_EV_BT_DISCOVERY_STATE_CHANGED 0x85
> +struct hal_msg_ev_bt_discovery_state_changed {
> + uint8_t state;
> +} __packed;
> +
> +#define HAL_MSG_EV_BT_PIN_REQUEST 0x86
> +struct hal_msg_ev_bt_pin_request {
> + __bdaddr_t bdaddr;
> + uint8_t name[249 - 1];
> + uint8_t class_of_dev[3];
> +} __packed;
> +
> +#define HAL_MSG_EV_BT_SSP_REQUEST 0x87
> +struct hal_msg_ev_bt_ssp_request {
> + __bdaddr_t bdaddr;
> + uint8_t name[249 - 1];
> + uint8_t class_of_dev[3];
> + uint8_t pairing_variant;
> + uint32_t passkey;
> +} __packed;
> +
> +#define HAL_MSG_EV_BT_BOND_STATE_CHANGED 0x88
> +struct hal_msg_ev_bt_bond_state_changed {
> + uint8_t status;
> + __bdaddr_t bdaddr;
> + uint8_t state;
> +} __packed;
> +
> +#define HAL_MSG_EV_BT_ACL_STATE_CHANGED 0x89
> +struct hal_msg_ev_bt_acl_state_changed {
> + uint8_t status;
> + __bdaddr_t bdaddr;
> + uint8_t state;
> +} __packed;
> +
> +#define HAL_MSG_EV_BT_DUT_MODE_RECEIVE 0x8a
> +struct hal_msg_ev_bt_dut_mode_receive {
> + uint16_t opcode;
> + uint8_t len;
> + uint8_t data[0];
> +} __packed;
> +
> +#define HAL_MSG_EV_BT_LE_TEST_MODE 0x8b
> +struct hal_msg_ev_bt_le_test_mode {
> + uint8_t status;
> + uint16_t num_packets;
> +} __packed;

Regards

Marcel


2013-10-09 19:30:22

by Marcel Holtmann

[permalink] [raw]
Subject: Re: [PATCHv3 06/15] android: Add basic mgmt initialization sequence

Hi Andrei,

> Initialize bluetooth controller via mgmt interface.
> ---
> Makefile.android | 4 +-
> android/Android.mk | 11 +++
> android/main.c | 189 ++++++++++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 203 insertions(+), 1 deletion(-)
>
> diff --git a/Makefile.android b/Makefile.android
> index e161e6d..9a2c486 100644
> --- a/Makefile.android
> +++ b/Makefile.android
> @@ -1,7 +1,9 @@
> if ANDROID
> noinst_PROGRAMS += android/bluetoothd
>
> -android_bluetoothd_SOURCES = android/main.c src/log.c
> +android_bluetoothd_SOURCES = android/main.c src/log.c \
> + src/shared/util.h src/shared/util.c \
> + src/shared/mgmt.h src/shared/mgmt.c
> android_bluetoothd_LDADD = @GLIB_LIBS@
> endif
>
> diff --git a/android/Android.mk b/android/Android.mk
> index 2cabff4..f5fd863 100644
> --- a/android/Android.mk
> +++ b/android/Android.mk
> @@ -15,10 +15,15 @@ include $(CLEAR_VARS)
> LOCAL_SRC_FILES := \
> main.c \
> log.c \
> + ../src/shared/mgmt.c \
> + ../src/shared/util.c \
>
> LOCAL_C_INCLUDES := \
> $(call include-path-for, glib) \
> $(call include-path-for, glib)/glib \
> +
> +LOCAL_C_INCLUDES += \
> + $(LOCAL_PATH)/../ \
> $(LOCAL_PATH)/../src \

do we need these nested includes actually? We could also just fix the includes. BlueZ historically has not been good with clear includes. I started to fix this, but it seems I have not gotten to all of them yet.

>
> LOCAL_CFLAGS := -DVERSION=\"$(BLUEZ_VERSION)\"
> @@ -26,6 +31,12 @@ LOCAL_CFLAGS := -DVERSION=\"$(BLUEZ_VERSION)\"
> # to suppress the "warning: missing initializer near initialization.." warning
> LOCAL_CFLAGS += -Wno-missing-field-initializers
>
> +# to suppress the "pointer of type 'void *' used in arithmetic" warning
> +LOCAL_CFLAGS += -Wno-pointer-arith

Why do we need to suppress these warning. Can we not just fix them.

> +
> +# Define missing flags for Android 4.2
> +LOCAL_CFLAGS += -DSOCK_CLOEXEC=02000000 -DSOCK_NONBLOCK=04000
> +

This thing is dangerous. Do we really bother with Android 4.2 support and can not rely on a newer version that has this fixed properly in bionic.

> LOCAL_SHARED_LIBRARIES := \
> libglib \
>
> diff --git a/android/main.c b/android/main.c
> index f75b0a8..3580ac7 100644
> --- a/android/main.c
> +++ b/android/main.c
> @@ -25,6 +25,7 @@
> #include <config.h>
> #endif
>
> +#include <stdbool.h>
> #include <signal.h>
> #include <stdint.h>
> #include <stdio.h>
> @@ -36,9 +37,17 @@
>
> #include "log.h"
>
> +#include "lib/bluetooth.h"
> +#include "lib/mgmt.h"
> +#include "src/shared/mgmt.h"
> +
> #define SHUTDOWN_GRACE_SECONDS 10
>
> static GMainLoop *event_loop;
> +static struct mgmt *mgmt_if = NULL;
> +
> +static uint8_t mgmt_version = 0;
> +static uint8_t mgmt_revision = 0;
>
> static gboolean quit_eventloop(gpointer user_data)
> {
> @@ -67,6 +76,183 @@ static GOptionEntry options[] = {
> { NULL }
> };
>
> +static void read_info_complete(uint8_t status, uint16_t length,
> + const void *param, void *user_data)
> +{
> + /* TODO: Store Controller information */
> +
> + /**
> + * Register all event notification handlers for controller.
> + *
> + * The handlers are registered after a succcesful read of the
> + * controller info. From now on they can track updates and
> + * notifications.
> + */

This is not our comment style.

> +}
> +
> +
> +static void mgmt_index_added_event(uint16_t index, uint16_t length,
> + const void *param, void *user_data)
> +{
> + info("%s: index %u", __func__, index);
> +
> + DBG("sending read info command for index %u", index);
> +
> + if (mgmt_send(mgmt_if, MGMT_OP_READ_INFO, index, 0, NULL,
> + read_info_complete, NULL, NULL) > 0)
> + return;
> +
> + error("Failed to read adapter info for index %u", index);
> +
> +}

I prefer if we focus on one controller index and one controller index only. There is no need to bother reading information from controllers that we will never use.

> +
> +static void mgmt_index_removed_event(uint16_t index, uint16_t length,
> + const void *param, void *user_data)
> +{
> + info("%s: index %u", __func__, index);
> +}
> +
> +static void read_index_list_complete(uint8_t status, uint16_t length,
> + const void *param, void *user_data)
> +{
> + const struct mgmt_rp_read_index_list *rp = param;
> + uint16_t num;
> + int i;
> +
> + info(__func__);
> +
> + if (status != MGMT_STATUS_SUCCESS) {
> + error("%s: Failed to read index list: %s (0x%02x)",
> + __func__, mgmt_errstr(status), status);
> + return;
> + }
> +
> + if (length < sizeof(*rp)) {
> + error("%s: Wrong size of read index list response", __func__);
> + return;
> + }
> +
> + num = btohs(rp->num_controllers);
> +
> + DBG("%s: Number of controllers: %d", __func__, num);
> +
> + if (num * sizeof(uint16_t) + sizeof(*rp) != length) {
> + error("%s: Incorrect pkt size for index list rsp", __func__);
> + return;
> + }
> +
> + for (i = 0; i < num; i++) {
> + uint16_t index;
> +
> + index = btohs(rp->index[i]);
> +
> + DBG("%s: Found index %u", __func__, index);
> +
> + /**
> + * Use index added event notification.
> + */
> + mgmt_index_added_event(index, 0, NULL, NULL);
> + }

Same here. Lets just pick one controller and be done with it.

> +}
> +
> +

Avoid double empty lines.

> +static void read_commands_complete(uint8_t status, uint16_t length,
> + const void *param, void *user_data)
> +{
> + const struct mgmt_rp_read_commands *rp = param;
> + uint16_t num_commands, num_events;
> +
> + info(__func__);

These can not be info() ever. Make them DBG().

> +
> + if (status != MGMT_STATUS_SUCCESS) {
> + error("Failed to read supported commands: %s (0x%02x)",
> + mgmt_errstr(status), status);
> + return;
> + }
> +
> + if (length < sizeof(*rp)) {
> + error("Wrong size of read commands response");
> + return;
> + }
> +
> + num_commands = btohs(rp->num_commands);
> + num_events = btohs(rp->num_events);
> +
> + DBG("Number of commands: %d", num_commands);
> + DBG("Number of events: %d", num_events);
> +}

When copying code from src/adapter.c can we please at least be smart about it. Code that has no benefit should not be run. If it is currently not used, then leave it out for now.

> +
> +static void read_version_complete(uint8_t status, uint16_t length,
> + const void *param, void *user_data)
> +{
> + const struct mgmt_rp_read_version *rp = param;
> +
> + info(__func__);
> +
> + if (status != MGMT_STATUS_SUCCESS) {
> + error("Failed to read version information: %s (0x%02x)",
> + mgmt_errstr(status), status);
> + return;
> + }
> +
> + if (length < sizeof(*rp)) {
> + error("Wrong size response");
> + return;
> + }
> +
> + mgmt_version = rp->version;
> + mgmt_revision = btohs(rp->revision);
> +
> + info("Bluetooth management interface %u.%u initialized",
> + mgmt_version, mgmt_revision);
> +
> + if (mgmt_version < 1) {
> + error("Version 1.0 or later of management interface required");
> + abort();
> + }
> +
> + DBG("sending read supported commands command");
> +
> + mgmt_send(mgmt_if, MGMT_OP_READ_COMMANDS, MGMT_INDEX_NONE, 0, NULL,
> + read_commands_complete, NULL, NULL);
> +
> + mgmt_register(mgmt_if, MGMT_EV_INDEX_ADDED, MGMT_INDEX_NONE,
> + mgmt_index_added_event, NULL, NULL);
> + mgmt_register(mgmt_if, MGMT_EV_INDEX_REMOVED, MGMT_INDEX_NONE,
> + mgmt_index_removed_event, NULL, NULL);
> +
> + DBG("sending read index list command");
> +
> + if (mgmt_send(mgmt_if, MGMT_OP_READ_INDEX_LIST, MGMT_INDEX_NONE, 0,
> + NULL, read_index_list_complete, NULL, NULL) > 0)
> + return;
> +
> + error("Failed to read controller index list");
> +}
> +
> +static bool init_mgmt_interface(void)
> +{

If you are not using the return value, then do not return it.

> + mgmt_if = mgmt_new_default();
> + if (mgmt_if == NULL) {
> + error("Failed to access management interface");
> + return false;
> + }
> +
> + if (mgmt_send(mgmt_if, MGMT_OP_READ_VERSION, MGMT_INDEX_NONE, 0, NULL,
> + read_version_complete, NULL, NULL) == 0) {
> + error("Error sending READ_VERSION mgmt command");
> + return false;
> + }
> +
> + return true;
> +}
> +
> +static void cleanup_mgmt_interface(void)
> +{
> + mgmt_unref(mgmt_if);
> + mgmt_if = NULL;
> +}
> +
> int main(int argc, char *argv[])
> {
> GOptionContext *context;
> @@ -100,10 +286,13 @@ int main(int argc, char *argv[])
> sigaction(SIGINT, &sa, NULL);
> sigaction(SIGTERM, &sa, NULL);
>
> + init_mgmt_interface();
> +
> DBG("Entering main loop");
>
> g_main_loop_run(event_loop);
>
> + cleanup_mgmt_interface();
> g_main_loop_unref(event_loop);
>
> info("Exit");

Regards

Marcel


2013-10-09 19:19:32

by Marcel Holtmann

[permalink] [raw]
Subject: Re: [PATCHv3 05/15] android: Start Android Bluetooth daemon

Hi Andrei,

> From: Andrei Emeltchenko <[email protected]>
>
> Start Android Bluetooth daemon from HAL init(). Make sure
> that daemon is in "running" state.
> ---
> android/hal_bluetooth.c | 50 ++++++++++++++++++++++++++++++++++++++++++++---
> 1 file changed, 47 insertions(+), 3 deletions(-)
>
> diff --git a/android/hal_bluetooth.c b/android/hal_bluetooth.c
> index 00f3e8d..f1e306f 100644
> --- a/android/hal_bluetooth.c
> +++ b/android/hal_bluetooth.c
> @@ -23,11 +23,16 @@
> #include <hardware/bluetooth.h>
> #include <hardware/bt_sock.h>
>
> +#include <cutils/sockets.h>
> +#include <cutils/properties.h>
> +
> #define LOG_TAG "BlueZ"
> #include <cutils/log.h>
>
> #include "hal.h"
>
> +#define ANDROID_BLUEZ "bluetoothd"
> +

I think a more fitting name would we SERVICE_NAME or similar.

> bt_callbacks_t *bt_hal_cbacks = NULL;
>
> static bool interface_ready(void)
> @@ -35,6 +40,42 @@ static bool interface_ready(void)
> return bt_hal_cbacks != NULL;
> }
>
> +static bool is_svc_running(void)
> +{
> + char val[PROPERTY_VALUE_MAX];
> + int ret;

Is this variable used anywhere.

> +
> + ALOGD(__func__);
> +
> + if (property_get("init.svc." ANDROID_BLUEZ, val, NULL)) {
> + if (strcmp(val, "running") == 0)

These days I rather do !strcmp.

> + return true;
> + }
> +
> + return false;
> +}
> +
> +static bool start_bt_daemon(void)
> +{
> + int tries = 40; /* wait 4 seconds for completion */
> +
> + ALOGD(__func__);
> +
> + /* Start Android Bluetooth daemon service */
> + property_set("ctl.start", ANDROID_BLUEZ);
> +
> + while (tries-- > 0) {
> + if (is_svc_running() == true) {

We test with just if (is_svc_running()) these days.

> + ALOGI("Android BlueZ daemon started");
> + return true;
> + }
> +
> + usleep(100000);
> + }
> +
> + return false;
> +}

if you are using is_svc_running only in this one function, then why not just do it all in one function and be done with it.

> +
> static bool is_profile(const char *profile, const char *str)
> {
> return strcmp(profile, str) == 0;
> @@ -47,10 +88,13 @@ static int init(bt_callbacks_t *callbacks)
> if (interface_ready() == true)
> return BT_STATUS_SUCCESS;
>
> - /* store reference to user callbacks */
> - bt_hal_cbacks = callbacks;
> + if (start_bt_daemon() == true) {
> + /* TODO: open channel */
>
> - /* TODO: Init here bluezd task */
> + bt_hal_cbacks = callbacks;
> +
> + return BT_STATUS_SUCCESS;
> + }
>
> return BT_STATUS_UNSUPPORTED;
> }

Regards

Marcel


2013-10-09 19:15:49

by Marcel Holtmann

[permalink] [raw]
Subject: Re: [PATCHv3 04/15] android: Enable Socket interface

Hi Andrei,

> Returns socket interface, use header hal.h to avoid externs.
> ---
> android/hal.h | 18 ++++++++++++++++++
> android/hal_bluetooth.c | 11 +++++++++++
> 2 files changed, 29 insertions(+)
> create mode 100644 android/hal.h
>
> diff --git a/android/hal.h b/android/hal.h
> new file mode 100644
> index 0000000..40fbf03
> --- /dev/null
> +++ b/android/hal.h
> @@ -0,0 +1,18 @@
> +/*
> + * Copyright (C) 2013 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.
> + *
> + */
> +
> +btsock_interface_t *bt_get_sock_interface(void);
> diff --git a/android/hal_bluetooth.c b/android/hal_bluetooth.c
> index 9970374..00f3e8d 100644
> --- a/android/hal_bluetooth.c
> +++ b/android/hal_bluetooth.c
> @@ -21,10 +21,13 @@
> #include <stdbool.h>
>
> #include <hardware/bluetooth.h>
> +#include <hardware/bt_sock.h>
>
> #define LOG_TAG "BlueZ"
> #include <cutils/log.h>
>
> +#include "hal.h"
> +
> bt_callbacks_t *bt_hal_cbacks = NULL;
>
> static bool interface_ready(void)
> @@ -32,6 +35,11 @@ static bool interface_ready(void)
> return bt_hal_cbacks != NULL;
> }
>
> +static bool is_profile(const char *profile, const char *str)
> +{
> + return strcmp(profile, str) == 0;
> +}
> +
> static int init(bt_callbacks_t *callbacks)
> {
> ALOGD(__func__);
> @@ -246,6 +254,9 @@ static const void *get_profile_interface(const char *profile_id)
> if (interface_ready() == false)
> return NULL;
>
> + if (is_profile(profile_id, BT_PROFILE_SOCKETS_ID))
> + return bt_get_sock_interface();
> +

just use if (!strcmp(profile_id, BT_PROFILE?) here. It is as short and does not obfuscate with a function that does exactly the same anyway.

Regards

Marcel


2013-10-09 19:14:05

by Marcel Holtmann

[permalink] [raw]
Subject: Re: [PATCHv3 03/15] android: Add Socket Bluetooth HAL template

Hi Andrei,

> bt_sock HAL handles Bluetooth sockets for Android.
> ---
> android/Android.mk | 1 +
> android/hal_bt_sock.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 85 insertions(+)
> create mode 100644 android/hal_bt_sock.c
>
> diff --git a/android/Android.mk b/android/Android.mk
> index 7adbbcd..2cabff4 100644
> --- a/android/Android.mk
> +++ b/android/Android.mk
> @@ -41,6 +41,7 @@ include $(CLEAR_VARS)
>
> LOCAL_SRC_FILES := \
> hal_bluetooth.c \
> + hal_bt_sock.c \
>
> LOCAL_SHARED_LIBRARIES := \
> libcutils \
> diff --git a/android/hal_bt_sock.c b/android/hal_bt_sock.c
> new file mode 100644
> index 0000000..cbb42d1
> --- /dev/null
> +++ b/android/hal_bt_sock.c
> @@ -0,0 +1,84 @@
> +/*
> + * Copyright (C) 2013 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 <stdlib.h>
> +
> +#include <hardware/bluetooth.h>
> +#include <hardware/bt_sock.h>
> +
> +#define LOG_TAG "BlueZ"
> +#include <cutils/log.h>
> +
> +static bt_status_t btsock_listen_rfcomm(const char *service_name,
> + const uint8_t *uuid, int chan,
> + int *sock, int flags)
> +{
> + ALOGD(__func__);
> +
> + return BT_STATUS_UNSUPPORTED;
> +}
> +
> +static bt_status_t listen(btsock_type_t type, const char *service_name,
> + const uint8_t *uuid, int chan,
> + int *sock, int flags)
> +{
> + if ((uuid == NULL && chan <= 0) || sock == NULL) {

we are moving away from uuid == NULL checks. Use !uuid instead.

> + ALOGE("%s: invalid params: uuid %p, chan %d, sock %p",
> + __func__, uuid, chan, sock);
> + return BT_STATUS_PARM_INVALID;
> + }
> +
> + ALOGD("%s: uuid %p chan %d sock %p type %d service_name %s",
> + __func__, uuid, chan, sock, type, service_name);
> +
> + switch (type) {
> + case BTSOCK_RFCOMM:
> + return btsock_listen_rfcomm(service_name, uuid, chan,
> + sock, flags);
> + default:
> + ALOGE("%s: Socket type %d not supported", __func__, type);

I normally expect that even the default statement has a break; at the end.

> + }
> +
> + return BT_STATUS_UNSUPPORTED;
> +}
> +
> +static bt_status_t connect(const bt_bdaddr_t *bdaddr, btsock_type_t type,
> + const uint8_t *uuid, int chan,
> + int *sock, int flags)
> +{
> + if ((uuid == NULL && chan <= 0) || bdaddr == NULL || sock == NULL) {
> + ALOGE("invalid params: bd_addr %p, uuid %p, chan %d, sock %p",
> + bdaddr, uuid, chan, sock);
> + return BT_STATUS_PARM_INVALID;
> + }
> +
> + ALOGD("%s: uuid %p chan %d sock %p type %d", __func__, uuid, chan,
> + sock, type);
> +
> + return BT_STATUS_UNSUPPORTED;
> +}
> +
> +static btsock_interface_t btsock_if = {

Is this an Android issue in how they defined the APIs or why are these not static const.

> + sizeof(btsock_if),
> + listen,
> + connect
> +};
> +
> +btsock_interface_t *bt_get_sock_interface(void)
> +{
> + return &btsock_if;
> +}

Regards

Marcel


2013-10-09 19:11:04

by Marcel Holtmann

[permalink] [raw]
Subject: Re: [PATCHv3 01/15] android: Supress missing initializers warnings

Hi Andrei,

> These types of warnings are disabled in BlueZ makeifiles
>
> main.c:67:2: warning: missing initializer [-Wmissing-field-initializers]
> main.c:67:2: warning: (near initialization for 'options[1].short_name')
> [-Wmissing-field-initializers]
> ---
> android/Android.mk | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/android/Android.mk b/android/Android.mk
> index ec820ac..5498b41 100644
> --- a/android/Android.mk
> +++ b/android/Android.mk
> @@ -23,6 +23,9 @@ LOCAL_C_INCLUDES := \
>
> LOCAL_CFLAGS := -DVERSION=\"$(BLUEZ_VERSION)\"
>
> +# to suppress the "warning: missing initializer near initialization.." warning
> +LOCAL_CFLAGS += -Wno-missing-field-initializers
> +

why are we doing this and not fixing the actual warning?

Regards

Marcel


2013-10-08 14:51:13

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCHv3 05/15] android: Start Android Bluetooth daemon

From: Andrei Emeltchenko <[email protected]>

Start Android Bluetooth daemon from HAL init(). Make sure
that daemon is in "running" state.
---
android/hal_bluetooth.c | 50 ++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 47 insertions(+), 3 deletions(-)

diff --git a/android/hal_bluetooth.c b/android/hal_bluetooth.c
index 00f3e8d..f1e306f 100644
--- a/android/hal_bluetooth.c
+++ b/android/hal_bluetooth.c
@@ -23,11 +23,16 @@
#include <hardware/bluetooth.h>
#include <hardware/bt_sock.h>

+#include <cutils/sockets.h>
+#include <cutils/properties.h>
+
#define LOG_TAG "BlueZ"
#include <cutils/log.h>

#include "hal.h"

+#define ANDROID_BLUEZ "bluetoothd"
+
bt_callbacks_t *bt_hal_cbacks = NULL;

static bool interface_ready(void)
@@ -35,6 +40,42 @@ static bool interface_ready(void)
return bt_hal_cbacks != NULL;
}

+static bool is_svc_running(void)
+{
+ char val[PROPERTY_VALUE_MAX];
+ int ret;
+
+ ALOGD(__func__);
+
+ if (property_get("init.svc." ANDROID_BLUEZ, val, NULL)) {
+ if (strcmp(val, "running") == 0)
+ return true;
+ }
+
+ return false;
+}
+
+static bool start_bt_daemon(void)
+{
+ int tries = 40; /* wait 4 seconds for completion */
+
+ ALOGD(__func__);
+
+ /* Start Android Bluetooth daemon service */
+ property_set("ctl.start", ANDROID_BLUEZ);
+
+ while (tries-- > 0) {
+ if (is_svc_running() == true) {
+ ALOGI("Android BlueZ daemon started");
+ return true;
+ }
+
+ usleep(100000);
+ }
+
+ return false;
+}
+
static bool is_profile(const char *profile, const char *str)
{
return strcmp(profile, str) == 0;
@@ -47,10 +88,13 @@ static int init(bt_callbacks_t *callbacks)
if (interface_ready() == true)
return BT_STATUS_SUCCESS;

- /* store reference to user callbacks */
- bt_hal_cbacks = callbacks;
+ if (start_bt_daemon() == true) {
+ /* TODO: open channel */

- /* TODO: Init here bluezd task */
+ bt_hal_cbacks = callbacks;
+
+ return BT_STATUS_SUCCESS;
+ }

return BT_STATUS_UNSUPPORTED;
}
--
1.7.10.4


2013-10-08 14:51:15

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCHv3 07/15] android: Create HAL API header skeleton

From: Andrei Emeltchenko <[email protected]>

Header describes the protocol between Android HAL threads and BlueZ
daemon.
---
android/hal_msg.h | 255 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 255 insertions(+)
create mode 100644 android/hal_msg.h

diff --git a/android/hal_msg.h b/android/hal_msg.h
new file mode 100644
index 0000000..c6bc883
--- /dev/null
+++ b/android/hal_msg.h
@@ -0,0 +1,255 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2013 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
+ *
+ */
+
+#ifndef __packed
+#define __packed __attribute__((packed))
+#endif
+
+typedef struct {
+ uint8_t b[6];
+} __packed __bdaddr_t;
+
+struct hal_msg_hdr {
+ uint8_t service_id;
+ uint8_t opcode;
+ uint16_t len;
+ uint8_t payload[0];
+} __packed;
+
+#define HAL_SERVICE_ID_CORE 0
+#define HAL_SERVICE_ID_BLUETOOTH 1
+#define HAL_SERVICE_ID_SOCK 2
+#define HAL_SERVICE_ID_HIDHOST 3
+#define HAL_SERVICE_ID_PAN 4
+#define HAL_SERVICE_ID_HANDSFREE 5
+#define HAL_SERVICE_ID_AD2P 6
+#define HAL_SERVICE_ID_HEALTH 7
+#define HAL_SERVICE_ID_AVRCP 8
+#define HAL_SERVICE_ID_GATT 9
+
+/* Core Service */
+
+#define HAL_MSG_OP_ERROR 0x00
+struct hal_msg_rp_error {
+ uint8_t status;
+} __packed;
+
+#define HAL_MSG_OP_REGISTER_MODULE 0x01
+struct hal_msg_cp_register_module {
+ uint8_t service_id;
+} __packed;
+struct hal_msg_rp_register_module {
+ uint8_t service_id;
+} __packed;
+
+#define HAL_MSG_OP_UNREGISTER_MODULE 0x02
+struct hal_msg_cp_unregister_module {
+ uint8_t service_id;
+} __packed;
+
+/* Bluetooth Core HAL API */
+
+#define HAL_MSG_OP_BT_ENABLE 0x01
+
+#define HAL_MSG_OP_BT_DISABLE 0x02
+
+#define HAL_MSG_OP_BT_GET_ADAPTER_PROPS 0x03
+
+#define HAL_MSG_OP_BT_GET_ADAPTER_PROP 0x04
+struct hal_msg_cp_bt_get_adapter_prop {
+ uint8_t type;
+} __packed;
+
+#define HAL_MSG_OP_BT_SET_ADAPTER_PROP 0x05
+struct hal_msg_cp_bt_set_adapter_prop {
+ uint8_t type;
+ uint16_t len;
+ uint8_t val[0];
+} __packed;
+
+#define HAL_MSG_OP_BT_GET_REMOTE_DEVICE_PROPS 0x06
+struct hal_msg_cp_bt_get_remote_device_props {
+ __bdaddr_t bdaddr;
+} __packed;
+
+#define HAL_MSG_OP_BT_GET_REMOTE_DEVICE_PROP 0x07
+struct hal_msg_cp_bt_get_remote_device_prop {
+ __bdaddr_t bdaddr;
+ uint8_t type;
+} __packed;
+
+#define HAL_MSG_OP_BT_SET_REMOTE_DEVICE_PROP 0x08
+struct hal_msg_cp_bt_set_remote_device_prop {
+ __bdaddr_t bdaddr;
+ uint8_t type;
+ uint16_t len;
+ uint8_t val[0];
+} __packed;
+
+#define HAL_MSG_OP_BT_GET_REMOTE_SERVICE_REC 0x09
+struct hal_msg_cp_bt_get_remote_service_rec {
+ __bdaddr_t bdaddr;
+ uint8_t uuid[16];
+} __packed;
+
+#define HAL_MSG_OP_BT_GET_REMOTE_SERVICE 0x0a
+struct hal_msg_cp_bt_get_remote_service {
+ __bdaddr_t bdaddr;
+} __packed;
+
+#define HAL_MSG_OP_BT_START_DISCOVERY 0x0b
+
+#define HAL_MSG_OP_BT_CANCEL_DISCOVERY 0x0c
+
+#define HAL_MSG_OP_BT_CREATE_BOND 0x0d
+struct hal_msg_cp_bt_create_bond {
+ __bdaddr_t bdaddr;
+} __packed;
+
+#define HAL_MSG_OP_BT_REMOVE_BOND 0x0d
+struct hal_msg_cp_bt_remove_bond {
+ __bdaddr_t bdaddr;
+} __packed;
+
+#define HAL_MSG_OP_BT_CANCEL_BOND 0x0f
+struct hal_msg_cp_bt_cancel_bond {
+ __bdaddr_t bdaddr;
+} __packed;
+
+#define HAL_MSG_OP_BT_PIN_REPLY 0x10
+struct hal_msg_cp_bt_pin_reply {
+ __bdaddr_t bdaddr;
+ uint8_t accept;
+ uint8_t pin_len;
+ uint8_t pin_code[16];
+} __packed;
+
+#define HAL_MSG_OP_BT_SSP_REPLY 0x11
+struct hal_msg_cp_bt_ssp_reply {
+ __bdaddr_t bdaddr;
+ uint8_t ssp_variant;
+ uint8_t accept;
+ uint32_t passkey;
+} __packed;
+
+#define HAL_MSG_OP_BT_DUT_MODE_CONF 0x12
+struct hal_msg_cp_bt_dut_mode_conf {
+ uint8_t enable;
+} __packed;
+
+#define HAL_MSG_OP_BT_DUT_MODE_SEND 0x13
+struct hal_msg_cp_bt_dut_mode_send {
+ uint16_t opcode;
+ uint8_t len;
+ uint8_t data[0];
+} __packed;
+
+#define HAL_MSG_OP_BT_LE_TEST_MODE 0x14
+struct hal_msg_cp_bt_le_test_mode {
+ uint16_t opcode;
+ uint8_t len;
+ uint8_t data[0];
+} __packed;
+
+/* Notifications and confirmations */
+
+#define HAL_MSG_EV_BT_ERROR 0x80
+
+#define HAL_MSG_EV_BT_ADAPTER_STATE_CHANGED 0x81
+struct hal_msg_ev_bt_adapter_state_changed {
+ uint8_t state;
+} __packed;
+
+#define HAL_MSG_EV_BT_ADAPTER_PROPS_CHANGED 0x82
+struct hal_property {
+ uint8_t type;
+ uint16_t len;
+ uint8_t val[0];
+} __packed;
+struct hal_msg_ev_bt_adapter_props_changed {
+ uint8_t status;
+ uint8_t num_props;
+ struct hal_property props[0];
+} __packed;
+
+#define HAL_MSG_EV_BT_REMOTE_DEVICE_PROPS 0x83
+struct hal_msg_ev_bt_remote_device_props {
+ uint8_t status;
+ __bdaddr_t bdaddr;
+ uint8_t num_props;
+ struct hal_property props[0];
+} __packed;
+
+#define HAL_MSG_EV_BT_DEVICE_FOUND 0x84
+struct hal_msg_ev_bt_device_found {
+ uint8_t num_props;
+ struct hal_property props[0];
+} __packed;
+
+#define HAL_MSG_EV_BT_DISCOVERY_STATE_CHANGED 0x85
+struct hal_msg_ev_bt_discovery_state_changed {
+ uint8_t state;
+} __packed;
+
+#define HAL_MSG_EV_BT_PIN_REQUEST 0x86
+struct hal_msg_ev_bt_pin_request {
+ __bdaddr_t bdaddr;
+ uint8_t name[249 - 1];
+ uint8_t class_of_dev[3];
+} __packed;
+
+#define HAL_MSG_EV_BT_SSP_REQUEST 0x87
+struct hal_msg_ev_bt_ssp_request {
+ __bdaddr_t bdaddr;
+ uint8_t name[249 - 1];
+ uint8_t class_of_dev[3];
+ uint8_t pairing_variant;
+ uint32_t passkey;
+} __packed;
+
+#define HAL_MSG_EV_BT_BOND_STATE_CHANGED 0x88
+struct hal_msg_ev_bt_bond_state_changed {
+ uint8_t status;
+ __bdaddr_t bdaddr;
+ uint8_t state;
+} __packed;
+
+#define HAL_MSG_EV_BT_ACL_STATE_CHANGED 0x89
+struct hal_msg_ev_bt_acl_state_changed {
+ uint8_t status;
+ __bdaddr_t bdaddr;
+ uint8_t state;
+} __packed;
+
+#define HAL_MSG_EV_BT_DUT_MODE_RECEIVE 0x8a
+struct hal_msg_ev_bt_dut_mode_receive {
+ uint16_t opcode;
+ uint8_t len;
+ uint8_t data[0];
+} __packed;
+
+#define HAL_MSG_EV_BT_LE_TEST_MODE 0x8b
+struct hal_msg_ev_bt_le_test_mode {
+ uint8_t status;
+ uint16_t num_packets;
+} __packed;
--
1.7.10.4


2013-10-08 14:51:22

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCHv3 14/15] android: Add makefile for hciconfig

From: Andrei Emeltchenko <[email protected]>

---
android/Android.mk | 34 ++++++++++++++++++++++++++++++++++
1 file changed, 34 insertions(+)

diff --git a/android/Android.mk b/android/Android.mk
index e7a70d0..09c4579 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -123,3 +123,37 @@ $(foreach file,$(lib_headers), $(shell ln -sf ../$(file) $(LOCAL_PATH)/../lib/bl
LOCAL_MODULE := libbluetooth

include $(BUILD_SHARED_LIBRARY)
+
+#
+# hciconfig
+#
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+ ../tools/csr.c \
+ ../tools/csr_h4.c \
+ ../tools/hciconfig.c \
+
+LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH)/../lib \
+ $(LOCAL_PATH)/../src \
+
+LOCAL_C_INCLUDES += \
+ $(call include-path-for, glib) \
+ $(call include-path-for, glib)/glib \
+
+LOCAL_SHARED_LIBRARIES := \
+ libbluetooth
+
+# to suppress the "pointer of type 'void *' used in arithmetic" warning
+LOCAL_CFLAGS := -Wno-pointer-arith
+
+# to suppress the "warning: missing initializer near initialization.." warning
+LOCAL_CFLAGS += -Wno-missing-field-initializers
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
+LOCAL_MODULE_TAGS := eng
+LOCAL_MODULE := hciconfig
+
+include $(BUILD_EXECUTABLE)
--
1.7.10.4


2013-10-08 14:51:08

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCHv3 00/15] Basic code for Android BlueZ

From: Andrei Emeltchenko <[email protected]>

Skeletons for Android Bluetooth and Socket HALs and BlueZ daemon.

Code is located also here:
https://code.google.com/p/android-bluez.bluez/

Getting Started
https://code.google.com/p/android-bluez/wiki/GettingStarted

Changes:
* PATCHv3: Changed __ANDROID_API__ to ANDROID and PLATFORM_SDK_VERSION.
* PATCHv2: Fixed Szymon's comments from review.
* PATCHv1: Rebased against applied fdanis patch set, moved SDP init from
adapter start to daemon start, other minor fixes.
* RFCv3: Rebased against recent FDanis patch set, fixed library build,
corrected process capabilities, corrected API header.
* RFCv2: Took comments from mailing list reviewers. Use single
makefile, remove mgmt library and directly link, remove adapter
code and use default_adapter pointer and other style changes.
Dropped some patches due to major changes.

Andrei Emeltchenko (15):
android: Supress missing initializers warnings
android: Add Adapter Bluetooth HAL template
android: Add Socket Bluetooth HAL template
android: Enable Socket interface
android: Start Android Bluetooth daemon
android: Add basic mgmt initialization sequence
android: Create HAL API header skeleton
android: Add adapter and device struct for BlueZ daemon
android: Add Android Makefile for libbluetooth
android: sdp: Reuse BlueZ SDP server in Android
android: Add cap to bind to port < 1024
android: Implement read_info_complete callback
android: Handle mgmt changed events
android: Add makefile for hciconfig
android: Add makefile for hcitool

Makefile.android | 9 +-
android/Android.mk | 166 +++++++++++++++
android/bt_adapter.c | 54 +++++
android/bt_adapter.h | 60 ++++++
android/hal.h | 18 ++
android/hal_bluetooth.c | 403 ++++++++++++++++++++++++++++++++++++
android/hal_bt_sock.c | 84 ++++++++
android/hal_msg.h | 255 +++++++++++++++++++++++
android/main.c | 519 +++++++++++++++++++++++++++++++++++++++++++++++
configure.ac | 4 +
10 files changed, 1570 insertions(+), 2 deletions(-)
create mode 100644 android/bt_adapter.c
create mode 100644 android/bt_adapter.h
create mode 100644 android/hal.h
create mode 100644 android/hal_bluetooth.c
create mode 100644 android/hal_bt_sock.c
create mode 100644 android/hal_msg.h

--
1.7.10.4


2013-10-08 14:51:18

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCHv3 10/15] android: sdp: Reuse BlueZ SDP server in Android

From: Andrei Emeltchenko <[email protected]>

Reuse existing SDP server code in Android GPL daemon.
---
Makefile.android | 7 +++++--
android/Android.mk | 7 +++++++
android/bt_adapter.c | 2 --
android/main.c | 28 ++++++++++++++++++++++++++++
4 files changed, 40 insertions(+), 4 deletions(-)

diff --git a/Makefile.android b/Makefile.android
index 9a2c486..d576b52 100644
--- a/Makefile.android
+++ b/Makefile.android
@@ -2,9 +2,12 @@ if ANDROID
noinst_PROGRAMS += android/bluetoothd

android_bluetoothd_SOURCES = android/main.c src/log.c \
+ src/sdpd-database.c src/sdpd-server.c \
+ src/sdpd-service.c src/sdpd-request.c \
src/shared/util.h src/shared/util.c \
- src/shared/mgmt.h src/shared/mgmt.c
-android_bluetoothd_LDADD = @GLIB_LIBS@
+ src/shared/mgmt.h src/shared/mgmt.c \
+ android/bt_adapter.h android/bt_adapter.c
+android_bluetoothd_LDADD = lib/libbluetooth-internal.la @GLIB_LIBS@
endif

EXTRA_DIST += android/Android.mk android/log.c
diff --git a/android/Android.mk b/android/Android.mk
index 8f95a66..e7a70d0 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -17,6 +17,11 @@ LOCAL_SRC_FILES := \
log.c \
../src/shared/mgmt.c \
../src/shared/util.c \
+ bt_adapter.c \
+ ../src/sdpd-database.c \
+ ../src/sdpd-service.c \
+ ../src/sdpd-request.c \
+ ../src/sdpd-server.c \

LOCAL_C_INCLUDES := \
$(call include-path-for, glib) \
@@ -25,6 +30,7 @@ LOCAL_C_INCLUDES := \
LOCAL_C_INCLUDES += \
$(LOCAL_PATH)/../ \
$(LOCAL_PATH)/../src \
+ $(LOCAL_PATH)/../lib \

LOCAL_CFLAGS := -DVERSION=\"$(BLUEZ_VERSION)\"

@@ -39,6 +45,7 @@ LOCAL_CFLAGS += -DSOCK_CLOEXEC=02000000 -DSOCK_NONBLOCK=04000

LOCAL_SHARED_LIBRARIES := \
libglib \
+ libbluetooth \

LOCAL_MODULE := bluetoothd
LOCAL_REQUIRED_MODULES := libbluetooth
diff --git a/android/bt_adapter.c b/android/bt_adapter.c
index e21d50c..6b758bf 100644
--- a/android/bt_adapter.c
+++ b/android/bt_adapter.c
@@ -45,8 +45,6 @@ void adapter_start(struct bt_adapter *adapter)

/* TODO: CB: report scan mode */

- /* TODO: SDP start here */
-
/* TODO: CB: report state on */
}

diff --git a/android/main.c b/android/main.c
index 3580ac7..7968ed0 100644
--- a/android/main.c
+++ b/android/main.c
@@ -36,6 +36,8 @@
#include <glib.h>

#include "log.h"
+#include "hcid.h"
+#include "sdpd.h"

#include "lib/bluetooth.h"
#include "lib/mgmt.h"
@@ -43,12 +45,36 @@

#define SHUTDOWN_GRACE_SECONDS 10

+struct main_opts main_opts;
+
static GMainLoop *event_loop;
static struct mgmt *mgmt_if = NULL;

static uint8_t mgmt_version = 0;
static uint8_t mgmt_revision = 0;

+static int sdp_start(void)
+{
+ DBG("");
+
+ /* TODO: add logic */
+
+ /* sdpd-server use these settings */
+ memset(&main_opts, 0, sizeof(main_opts));
+
+ /* Use params: mtu = 0, flags = 0 */
+ return start_sdp_server(0, 0);
+}
+
+static void sdp_stop(void)
+{
+ DBG("");
+
+ /* TODO: add logic */
+
+ stop_sdp_server();
+}
+
static gboolean quit_eventloop(gpointer user_data)
{
g_main_loop_quit(event_loop);
@@ -287,11 +313,13 @@ int main(int argc, char *argv[])
sigaction(SIGTERM, &sa, NULL);

init_mgmt_interface();
+ sdp_start();

DBG("Entering main loop");

g_main_loop_run(event_loop);

+ sdp_stop();
cleanup_mgmt_interface();
g_main_loop_unref(event_loop);

--
1.7.10.4


2013-10-08 14:51:09

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCHv3 01/15] android: Supress missing initializers warnings

From: Andrei Emeltchenko <[email protected]>

These types of warnings are disabled in BlueZ makeifiles

main.c:67:2: warning: missing initializer [-Wmissing-field-initializers]
main.c:67:2: warning: (near initialization for 'options[1].short_name')
[-Wmissing-field-initializers]
---
android/Android.mk | 3 +++
1 file changed, 3 insertions(+)

diff --git a/android/Android.mk b/android/Android.mk
index ec820ac..5498b41 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -23,6 +23,9 @@ LOCAL_C_INCLUDES := \

LOCAL_CFLAGS := -DVERSION=\"$(BLUEZ_VERSION)\"

+# to suppress the "warning: missing initializer near initialization.." warning
+LOCAL_CFLAGS += -Wno-missing-field-initializers
+
LOCAL_SHARED_LIBRARIES := \
libglib \

--
1.7.10.4


2013-10-08 14:51:11

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCHv3 03/15] android: Add Socket Bluetooth HAL template

From: Andrei Emeltchenko <[email protected]>

bt_sock HAL handles Bluetooth sockets for Android.
---
android/Android.mk | 1 +
android/hal_bt_sock.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 85 insertions(+)
create mode 100644 android/hal_bt_sock.c

diff --git a/android/Android.mk b/android/Android.mk
index 7adbbcd..2cabff4 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -41,6 +41,7 @@ include $(CLEAR_VARS)

LOCAL_SRC_FILES := \
hal_bluetooth.c \
+ hal_bt_sock.c \

LOCAL_SHARED_LIBRARIES := \
libcutils \
diff --git a/android/hal_bt_sock.c b/android/hal_bt_sock.c
new file mode 100644
index 0000000..cbb42d1
--- /dev/null
+++ b/android/hal_bt_sock.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2013 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 <stdlib.h>
+
+#include <hardware/bluetooth.h>
+#include <hardware/bt_sock.h>
+
+#define LOG_TAG "BlueZ"
+#include <cutils/log.h>
+
+static bt_status_t btsock_listen_rfcomm(const char *service_name,
+ const uint8_t *uuid, int chan,
+ int *sock, int flags)
+{
+ ALOGD(__func__);
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static bt_status_t listen(btsock_type_t type, const char *service_name,
+ const uint8_t *uuid, int chan,
+ int *sock, int flags)
+{
+ if ((uuid == NULL && chan <= 0) || sock == NULL) {
+ ALOGE("%s: invalid params: uuid %p, chan %d, sock %p",
+ __func__, uuid, chan, sock);
+ return BT_STATUS_PARM_INVALID;
+ }
+
+ ALOGD("%s: uuid %p chan %d sock %p type %d service_name %s",
+ __func__, uuid, chan, sock, type, service_name);
+
+ switch (type) {
+ case BTSOCK_RFCOMM:
+ return btsock_listen_rfcomm(service_name, uuid, chan,
+ sock, flags);
+ default:
+ ALOGE("%s: Socket type %d not supported", __func__, type);
+ }
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static bt_status_t connect(const bt_bdaddr_t *bdaddr, btsock_type_t type,
+ const uint8_t *uuid, int chan,
+ int *sock, int flags)
+{
+ if ((uuid == NULL && chan <= 0) || bdaddr == NULL || sock == NULL) {
+ ALOGE("invalid params: bd_addr %p, uuid %p, chan %d, sock %p",
+ bdaddr, uuid, chan, sock);
+ return BT_STATUS_PARM_INVALID;
+ }
+
+ ALOGD("%s: uuid %p chan %d sock %p type %d", __func__, uuid, chan,
+ sock, type);
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static btsock_interface_t btsock_if = {
+ sizeof(btsock_if),
+ listen,
+ connect
+};
+
+btsock_interface_t *bt_get_sock_interface(void)
+{
+ return &btsock_if;
+}
--
1.7.10.4


2013-10-08 14:51:17

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCHv3 09/15] android: Add Android Makefile for libbluetooth

From: Andrei Emeltchenko <[email protected]>

Build libbluetooth library for Android.
---
android/Android.mk | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 53 insertions(+)

diff --git a/android/Android.mk b/android/Android.mk
index f5fd863..8f95a66 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -41,6 +41,7 @@ LOCAL_SHARED_LIBRARIES := \
libglib \

LOCAL_MODULE := bluetoothd
+LOCAL_REQUIRED_MODULES := libbluetooth

include $(BUILD_EXECUTABLE)

@@ -63,3 +64,55 @@ LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := SHARED_LIBRARIES

include $(BUILD_SHARED_LIBRARY)
+
+#
+# libbluetooth library
+#
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+ ../lib/bluetooth.c \
+ ../lib/sdp.c \
+ ../lib/hci.c \
+ ../lib/uuid.c \
+
+LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH)/../lib/ \
+ $(LOCAL_PATH)/../src/shared \
+
+LOCAL_C_INCLUDES += \
+ $(call include-path-for, glib) \
+ $(call include-path-for, glib)/glib \
+
+LOCAL_CFLAGS += -O3
+
+# to suppress the "pointer of type 'void *' used in arithmetic" warning
+LOCAL_CFLAGS += -Wno-pointer-arith
+
+# to suppress the "missing initializer near initialization" warning
+LOCAL_CFLAGS += -Wno-missing-field-initializers
+
+# Define missing flags for Android 4.2
+LOCAL_CFLAGS += -DSOCK_CLOEXEC=02000000 -DSOCK_NONBLOCK=04000
+
+lib_headers := \
+ bluetooth.h \
+ hci.h \
+ hci_lib.h \
+ sco.h \
+ l2cap.h \
+ sdp.h \
+ sdp_lib.h \
+ rfcomm.h \
+ bnep.h \
+ cmtp.h \
+ hidp.h \
+
+$(shell mkdir -p $(LOCAL_PATH)/../lib/bluetooth)
+
+$(foreach file,$(lib_headers), $(shell ln -sf ../$(file) $(LOCAL_PATH)/../lib/bluetooth/$(file)))
+
+LOCAL_MODULE := libbluetooth
+
+include $(BUILD_SHARED_LIBRARY)
--
1.7.10.4


2013-10-08 14:51:21

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCHv3 13/15] android: Handle mgmt changed events

From: Andrei Emeltchenko <[email protected]>

Add code handling changing adapter settings.
---
android/main.c | 154 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 154 insertions(+)

diff --git a/android/main.c b/android/main.c
index a2ed8a4..c181d3a 100644
--- a/android/main.c
+++ b/android/main.c
@@ -127,6 +127,159 @@ static void load_link_keys_complete(uint8_t status, uint16_t length,
DBG("status %u", status);
}

+static void mgmt_local_name_changed_event(uint16_t index, uint16_t length,
+ const void *param, void *user_data)
+{
+ struct bt_adapter *adapter = user_data;
+ const struct mgmt_cp_set_local_name *rp = param;
+
+ if (length < sizeof(*rp)) {
+ error("Wrong size of local name changed parameters");
+ return;
+ }
+
+ if (adapter != default_adapter) {
+ error("Wrong adapter %p", adapter);
+ return;
+ }
+
+ if (!g_strcmp0(adapter->short_name, (const char *) rp->short_name) &&
+ !g_strcmp0(adapter->name, (const char *) rp->name))
+ return;
+
+ DBG("name: %s short name: %s", rp->name, rp->short_name);
+
+ g_free(adapter->name);
+ adapter->name = g_strdup((const char *) rp->name);
+
+ g_free(adapter->short_name);
+ adapter->short_name = g_strdup((const char *) rp->short_name);
+
+ /* TODO Update services if needed */
+}
+
+static void settings_changed_connectable(struct bt_adapter *adapter)
+{
+ /* TODO */
+}
+
+static void settings_changed_discoverable(struct bt_adapter *adapter)
+{
+ /* TODO */
+}
+
+static void settings_changed(struct bt_adapter *adapter, uint32_t settings)
+{
+ uint32_t changed_mask;
+
+ changed_mask = adapter->current_settings ^ settings;
+
+ adapter->current_settings = settings;
+
+ DBG("0x%08x", changed_mask);
+
+ if (changed_mask & MGMT_SETTING_POWERED) {
+ info("Powered");
+
+ if (adapter->current_settings & MGMT_SETTING_POWERED)
+ adapter_start(adapter);
+ else
+ adapter_stop(adapter);
+ }
+
+ /* Seems not needed for Android */
+ if (changed_mask & MGMT_SETTING_PAIRABLE)
+ DBG("Pairable");
+
+ /*
+ * There are only 2 scan modes:
+ * CONNECTABLE and CONNECTABLE_DISCOVERABLE
+ */
+ if (changed_mask & MGMT_SETTING_CONNECTABLE) {
+ DBG("Connectable");
+
+ settings_changed_connectable(adapter);
+ }
+
+ if (changed_mask & MGMT_SETTING_DISCOVERABLE) {
+ DBG("Discoverable");
+
+ settings_changed_discoverable(adapter);
+ }
+}
+
+static void new_settings_callback(uint16_t index, uint16_t length,
+ const void *param, void *user_data)
+{
+ struct bt_adapter *adapter = user_data;
+ uint32_t settings;
+
+ if (length < sizeof(settings)) {
+ error("Wrong size of new settings parameters");
+ return;
+ }
+
+ if (adapter != default_adapter) {
+ error("Wrong adapter %p", adapter);
+ return;
+ }
+
+ settings = bt_get_le32(param);
+
+ DBG("settings: 0x%8.8x -> 0x%8.8x", adapter->current_settings,
+ settings);
+
+ if (settings == adapter->current_settings)
+ return;
+
+ settings_changed(adapter, settings);
+}
+
+static void mgmt_dev_class_changed_event(uint16_t index, uint16_t length,
+ const void *param, void *user_data)
+{
+ struct bt_adapter *adapter = user_data;
+ const struct mgmt_cod *rp = param;
+ uint32_t dev_class;
+
+ if (length < sizeof(*rp)) {
+ error("Wrong size of class of device changed parameters");
+ return;
+ }
+
+ if (adapter != default_adapter) {
+ error("Wrong adapter %p", adapter);
+ return;
+ }
+
+ dev_class = rp->val[0] | (rp->val[1] << 8) | (rp->val[2] << 16);
+
+ if (dev_class == adapter->dev_class)
+ return;
+
+ DBG("Class: 0x%06x", dev_class);
+
+ adapter->dev_class = dev_class;
+
+ /* TODO: Inform prop change: Class */
+
+ /* TODO: Gatt attrib set*/
+}
+
+static void register_mgmt_handlers(struct bt_adapter *adapter)
+{
+ mgmt_register(adapter->mgmt, MGMT_EV_NEW_SETTINGS, adapter->dev_id,
+ new_settings_callback, adapter, NULL);
+
+ mgmt_register(adapter->mgmt, MGMT_EV_CLASS_OF_DEV_CHANGED,
+ adapter->dev_id, mgmt_dev_class_changed_event,
+ adapter, NULL);
+
+ mgmt_register(adapter->mgmt, MGMT_EV_LOCAL_NAME_CHANGED,
+ adapter->dev_id, mgmt_local_name_changed_event,
+ adapter, NULL);
+}
+
static void load_link_keys(struct bt_adapter *adapter, GSList *keys)
{
struct mgmt_cp_load_link_keys *cp;
@@ -187,6 +340,7 @@ static void read_info_complete(uint8_t status, uint16_t length,
adapter->current_settings = btohs(rp->current_settings);

/* TODO: Register all event notification handlers */
+ register_mgmt_handlers(default_adapter);

if (adapter->current_settings & MGMT_SETTING_POWERED)
adapter_start(adapter);
--
1.7.10.4


2013-10-08 14:51:19

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCHv3 11/15] android: Add cap to bind to port < 1024

From: Andrei Emeltchenko <[email protected]>

For SDP server we need to bind to lower port, acquire this capability.
---
android/main.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
configure.ac | 4 ++++
2 files changed, 75 insertions(+)

diff --git a/android/main.c b/android/main.c
index 7968ed0..a100013 100644
--- a/android/main.c
+++ b/android/main.c
@@ -32,6 +32,22 @@
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/prctl.h>
+#include <linux/capability.h>
+
+/**
+ * Include <sys/capability.h> for host build and
+ * also for Android 4.3 when it is added to bionic
+ */
+#if !defined(ANDROID) || (PLATFORM_SDK_VERSION > 17)
+#include <sys/capability.h>
+#endif
+
+#if defined(ANDROID)
+#include <private/android_filesystem_config.h>
+#endif

#include <glib.h>

@@ -279,6 +295,58 @@ static void cleanup_mgmt_interface(void)
mgmt_if = NULL;
}

+static bool android_set_aid_and_cap(void)
+{
+ struct __user_cap_header_struct header;
+ struct __user_cap_data_struct cap;
+#if defined(ANDROID)
+ gid_t groups[] = {AID_NET_BT, AID_NET_BT_ADMIN, AID_NET_ADMIN};
+#endif
+
+ DBG("pid %d uid %d gid %d", getpid(), getuid(), getgid());
+
+ header.version = _LINUX_CAPABILITY_VERSION;
+
+ prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0);
+
+#if defined(ANDROID)
+ if (setgid(AID_BLUETOOTH) < 0)
+ warn("%s: setgid(): %s", __func__, strerror(errno));
+
+ if (setuid(AID_BLUETOOTH) < 0)
+ warn("%s: setuid(): %s", __func__, strerror(errno));
+#endif
+
+ header.version = _LINUX_CAPABILITY_VERSION;
+ header.pid = 0;
+
+ cap.effective = cap.permitted =
+ CAP_TO_MASK(CAP_SETGID) |
+ CAP_TO_MASK(CAP_NET_RAW) |
+ CAP_TO_MASK(CAP_NET_ADMIN) |
+ CAP_TO_MASK(CAP_NET_BIND_SERVICE);
+ cap.inheritable = 0;
+
+ if (capset(&header, &cap) < 0) {
+ error("%s: capset(): %s", __func__, strerror(errno));
+ return false;
+ }
+
+#if defined(ANDROID)
+ if (setgroups(sizeof(groups)/sizeof(groups[0]), groups) < 0)
+ warn("%s: setgroups: %s", __func__, strerror(errno));
+#endif
+ if (capget(&header, &cap) < 0)
+ error("%s: capget(): %s", __func__, strerror(errno));
+ else
+ DBG("Caps: eff: 0x%x, perm: 0x%x, inh: 0x%x", cap.effective,
+ cap.permitted, cap.inheritable);
+
+ DBG("pid %d uid %d gid %d", getpid(), getuid(), getgid());
+
+ return true;
+}
+
int main(int argc, char *argv[])
{
GOptionContext *context;
@@ -312,6 +380,9 @@ int main(int argc, char *argv[])
sigaction(SIGINT, &sa, NULL);
sigaction(SIGTERM, &sa, NULL);

+ if (android_set_aid_and_cap() == false)
+ exit(EXIT_FAILURE);
+
init_mgmt_interface();
sdp_start();

diff --git a/configure.ac b/configure.ac
index 7b1f64a..5406434 100644
--- a/configure.ac
+++ b/configure.ac
@@ -247,4 +247,8 @@ AC_ARG_ENABLE(android, AC_HELP_STRING([--enable-android],
[enable_android=${enableval}])
AM_CONDITIONAL(ANDROID, test "${enable_android}" = "yes")

+if (test "${android_daemon}" = "yes"); then
+ AC_CHECK_LIB(cap, capget, dummy=yes, AC_MSG_ERROR(libcap is required))
+fi
+
AC_OUTPUT(Makefile src/bluetoothd.8 lib/bluez.pc)
--
1.7.10.4


2013-10-08 14:51:14

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCHv3 06/15] android: Add basic mgmt initialization sequence

From: Andrei Emeltchenko <[email protected]>

Initialize bluetooth controller via mgmt interface.
---
Makefile.android | 4 +-
android/Android.mk | 11 +++
android/main.c | 189 ++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 203 insertions(+), 1 deletion(-)

diff --git a/Makefile.android b/Makefile.android
index e161e6d..9a2c486 100644
--- a/Makefile.android
+++ b/Makefile.android
@@ -1,7 +1,9 @@
if ANDROID
noinst_PROGRAMS += android/bluetoothd

-android_bluetoothd_SOURCES = android/main.c src/log.c
+android_bluetoothd_SOURCES = android/main.c src/log.c \
+ src/shared/util.h src/shared/util.c \
+ src/shared/mgmt.h src/shared/mgmt.c
android_bluetoothd_LDADD = @GLIB_LIBS@
endif

diff --git a/android/Android.mk b/android/Android.mk
index 2cabff4..f5fd863 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -15,10 +15,15 @@ include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
main.c \
log.c \
+ ../src/shared/mgmt.c \
+ ../src/shared/util.c \

LOCAL_C_INCLUDES := \
$(call include-path-for, glib) \
$(call include-path-for, glib)/glib \
+
+LOCAL_C_INCLUDES += \
+ $(LOCAL_PATH)/../ \
$(LOCAL_PATH)/../src \

LOCAL_CFLAGS := -DVERSION=\"$(BLUEZ_VERSION)\"
@@ -26,6 +31,12 @@ LOCAL_CFLAGS := -DVERSION=\"$(BLUEZ_VERSION)\"
# to suppress the "warning: missing initializer near initialization.." warning
LOCAL_CFLAGS += -Wno-missing-field-initializers

+# to suppress the "pointer of type 'void *' used in arithmetic" warning
+LOCAL_CFLAGS += -Wno-pointer-arith
+
+# Define missing flags for Android 4.2
+LOCAL_CFLAGS += -DSOCK_CLOEXEC=02000000 -DSOCK_NONBLOCK=04000
+
LOCAL_SHARED_LIBRARIES := \
libglib \

diff --git a/android/main.c b/android/main.c
index f75b0a8..3580ac7 100644
--- a/android/main.c
+++ b/android/main.c
@@ -25,6 +25,7 @@
#include <config.h>
#endif

+#include <stdbool.h>
#include <signal.h>
#include <stdint.h>
#include <stdio.h>
@@ -36,9 +37,17 @@

#include "log.h"

+#include "lib/bluetooth.h"
+#include "lib/mgmt.h"
+#include "src/shared/mgmt.h"
+
#define SHUTDOWN_GRACE_SECONDS 10

static GMainLoop *event_loop;
+static struct mgmt *mgmt_if = NULL;
+
+static uint8_t mgmt_version = 0;
+static uint8_t mgmt_revision = 0;

static gboolean quit_eventloop(gpointer user_data)
{
@@ -67,6 +76,183 @@ static GOptionEntry options[] = {
{ NULL }
};

+static void read_info_complete(uint8_t status, uint16_t length,
+ const void *param, void *user_data)
+{
+ /* TODO: Store Controller information */
+
+ /**
+ * Register all event notification handlers for controller.
+ *
+ * The handlers are registered after a succcesful read of the
+ * controller info. From now on they can track updates and
+ * notifications.
+ */
+}
+
+
+static void mgmt_index_added_event(uint16_t index, uint16_t length,
+ const void *param, void *user_data)
+{
+ info("%s: index %u", __func__, index);
+
+ DBG("sending read info command for index %u", index);
+
+ if (mgmt_send(mgmt_if, MGMT_OP_READ_INFO, index, 0, NULL,
+ read_info_complete, NULL, NULL) > 0)
+ return;
+
+ error("Failed to read adapter info for index %u", index);
+
+}
+
+static void mgmt_index_removed_event(uint16_t index, uint16_t length,
+ const void *param, void *user_data)
+{
+ info("%s: index %u", __func__, index);
+}
+
+static void read_index_list_complete(uint8_t status, uint16_t length,
+ const void *param, void *user_data)
+{
+ const struct mgmt_rp_read_index_list *rp = param;
+ uint16_t num;
+ int i;
+
+ info(__func__);
+
+ if (status != MGMT_STATUS_SUCCESS) {
+ error("%s: Failed to read index list: %s (0x%02x)",
+ __func__, mgmt_errstr(status), status);
+ return;
+ }
+
+ if (length < sizeof(*rp)) {
+ error("%s: Wrong size of read index list response", __func__);
+ return;
+ }
+
+ num = btohs(rp->num_controllers);
+
+ DBG("%s: Number of controllers: %d", __func__, num);
+
+ if (num * sizeof(uint16_t) + sizeof(*rp) != length) {
+ error("%s: Incorrect pkt size for index list rsp", __func__);
+ return;
+ }
+
+ for (i = 0; i < num; i++) {
+ uint16_t index;
+
+ index = btohs(rp->index[i]);
+
+ DBG("%s: Found index %u", __func__, index);
+
+ /**
+ * Use index added event notification.
+ */
+ mgmt_index_added_event(index, 0, NULL, NULL);
+ }
+}
+
+
+static void read_commands_complete(uint8_t status, uint16_t length,
+ const void *param, void *user_data)
+{
+ const struct mgmt_rp_read_commands *rp = param;
+ uint16_t num_commands, num_events;
+
+ info(__func__);
+
+ if (status != MGMT_STATUS_SUCCESS) {
+ error("Failed to read supported commands: %s (0x%02x)",
+ mgmt_errstr(status), status);
+ return;
+ }
+
+ if (length < sizeof(*rp)) {
+ error("Wrong size of read commands response");
+ return;
+ }
+
+ num_commands = btohs(rp->num_commands);
+ num_events = btohs(rp->num_events);
+
+ DBG("Number of commands: %d", num_commands);
+ DBG("Number of events: %d", num_events);
+}
+
+static void read_version_complete(uint8_t status, uint16_t length,
+ const void *param, void *user_data)
+{
+ const struct mgmt_rp_read_version *rp = param;
+
+ info(__func__);
+
+ if (status != MGMT_STATUS_SUCCESS) {
+ error("Failed to read version information: %s (0x%02x)",
+ mgmt_errstr(status), status);
+ return;
+ }
+
+ if (length < sizeof(*rp)) {
+ error("Wrong size response");
+ return;
+ }
+
+ mgmt_version = rp->version;
+ mgmt_revision = btohs(rp->revision);
+
+ info("Bluetooth management interface %u.%u initialized",
+ mgmt_version, mgmt_revision);
+
+ if (mgmt_version < 1) {
+ error("Version 1.0 or later of management interface required");
+ abort();
+ }
+
+ DBG("sending read supported commands command");
+
+ mgmt_send(mgmt_if, MGMT_OP_READ_COMMANDS, MGMT_INDEX_NONE, 0, NULL,
+ read_commands_complete, NULL, NULL);
+
+ mgmt_register(mgmt_if, MGMT_EV_INDEX_ADDED, MGMT_INDEX_NONE,
+ mgmt_index_added_event, NULL, NULL);
+ mgmt_register(mgmt_if, MGMT_EV_INDEX_REMOVED, MGMT_INDEX_NONE,
+ mgmt_index_removed_event, NULL, NULL);
+
+ DBG("sending read index list command");
+
+ if (mgmt_send(mgmt_if, MGMT_OP_READ_INDEX_LIST, MGMT_INDEX_NONE, 0,
+ NULL, read_index_list_complete, NULL, NULL) > 0)
+ return;
+
+ error("Failed to read controller index list");
+}
+
+static bool init_mgmt_interface(void)
+{
+ mgmt_if = mgmt_new_default();
+ if (mgmt_if == NULL) {
+ error("Failed to access management interface");
+ return false;
+ }
+
+ if (mgmt_send(mgmt_if, MGMT_OP_READ_VERSION, MGMT_INDEX_NONE, 0, NULL,
+ read_version_complete, NULL, NULL) == 0) {
+ error("Error sending READ_VERSION mgmt command");
+ return false;
+ }
+
+ return true;
+}
+
+static void cleanup_mgmt_interface(void)
+{
+ mgmt_unref(mgmt_if);
+ mgmt_if = NULL;
+}
+
int main(int argc, char *argv[])
{
GOptionContext *context;
@@ -100,10 +286,13 @@ int main(int argc, char *argv[])
sigaction(SIGINT, &sa, NULL);
sigaction(SIGTERM, &sa, NULL);

+ init_mgmt_interface();
+
DBG("Entering main loop");

g_main_loop_run(event_loop);

+ cleanup_mgmt_interface();
g_main_loop_unref(event_loop);

info("Exit");
--
1.7.10.4


2013-10-08 14:51:16

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCHv3 08/15] android: Add adapter and device struct for BlueZ daemon

From: Andrei Emeltchenko <[email protected]>

Adapter structure in BlueZ daemon keeps track of default adapter
and device structure keeps track about found devices.
---
android/bt_adapter.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++
android/bt_adapter.h | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 116 insertions(+)
create mode 100644 android/bt_adapter.c
create mode 100644 android/bt_adapter.h

diff --git a/android/bt_adapter.c b/android/bt_adapter.c
new file mode 100644
index 0000000..e21d50c
--- /dev/null
+++ b/android/bt_adapter.c
@@ -0,0 +1,56 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2013 Intel Corporation. All rights reserved.
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include "bt_adapter.h"
+#include "log.h"
+#include "src/shared/mgmt.h"
+
+struct bt_adapter *bt_adapter_new(uint16_t index, struct mgmt *mgmt_if)
+{
+ struct bt_adapter *adapter;
+
+ adapter = g_try_new0(struct bt_adapter, 1);
+ if (!adapter)
+ return NULL;
+
+ adapter->dev_id = index;
+ adapter->mgmt = mgmt_ref(mgmt_if);
+
+ return adapter;
+}
+
+void adapter_start(struct bt_adapter *adapter)
+{
+ DBG("enabled %u", adapter->dev_id);
+
+ /* TODO: CB: report scan mode */
+
+ /* TODO: SDP start here */
+
+ /* TODO: CB: report state on */
+}
+
+void adapter_stop(struct bt_adapter *adapter)
+{
+ DBG("disabled %u", adapter->dev_id);
+}
diff --git a/android/bt_adapter.h b/android/bt_adapter.h
new file mode 100644
index 0000000..6877cc7
--- /dev/null
+++ b/android/bt_adapter.h
@@ -0,0 +1,60 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2013 Intel Corporation. All rights reserved.
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <glib.h>
+
+#include "lib/bluetooth.h"
+
+struct bt_device {
+ int refcnt;
+
+ bdaddr_t bdaddr;
+ uint8_t bdaddr_type;
+ uint32_t cod;
+ char *name;
+};
+
+struct bt_adapter {
+ int refcnt;
+
+ uint16_t dev_id;
+ struct mgmt *mgmt;
+ bdaddr_t bdaddr;
+ uint32_t dev_class;
+
+ char *name;
+ char *short_name;
+
+ uint32_t supported_settings;
+ uint32_t current_settings;
+
+ GList *found_devices;
+};
+
+struct bt_adapter *bt_adapter_new(uint16_t index, struct mgmt *mgmt_if);
+
+void adapter_start(struct bt_adapter *adapter);
+void adapter_stop(struct bt_adapter *adapter);
--
1.7.10.4


2013-10-08 14:51:23

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCHv3 15/15] android: Add makefile for hcitool

From: Andrei Emeltchenko <[email protected]>

---
android/Android.mk | 38 ++++++++++++++++++++++++++++++++++++++
1 file changed, 38 insertions(+)

diff --git a/android/Android.mk b/android/Android.mk
index 09c4579..5798749 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -157,3 +157,41 @@ LOCAL_MODULE_TAGS := eng
LOCAL_MODULE := hciconfig

include $(BUILD_EXECUTABLE)
+
+#
+# hcitool
+#
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+ ../tools/hcitool.c \
+ ../src/oui.c \
+
+LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH)/../lib \
+ $(LOCAL_PATH)/../src \
+
+LOCAL_C_INCLUDES += \
+ $(call include-path-for, glib) \
+ $(call include-path-for, glib)/glib \
+
+LOCAL_CFLAGS := \
+ -DSTORAGEDIR=\"/tmp\" \
+ -DVERSION=\"$(BLUEZ_VERSION)\"
+
+# to suppress the "pointer of type 'void *' used in arithmetic" warning
+LOCAL_CFLAGS += -Wno-pointer-arith
+
+# to suppress the "warning: missing initializer near initialization.." warning
+LOCAL_CFLAGS += -Wno-missing-field-initializers
+
+LOCAL_SHARED_LIBRARIES := \
+ libbluetooth \
+ libglib \
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
+LOCAL_MODULE_TAGS := eng
+LOCAL_MODULE := hcitool
+
+include $(BUILD_EXECUTABLE)
--
1.7.10.4


2013-10-08 14:51:10

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCHv3 02/15] android: Add Adapter Bluetooth HAL template

From: Andrei Emeltchenko <[email protected]>

Add template for bluetooth.h Android HAL.
---
android/Android.mk | 19 +++
android/hal_bluetooth.c | 348 +++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 367 insertions(+)
create mode 100644 android/hal_bluetooth.c

diff --git a/android/Android.mk b/android/Android.mk
index 5498b41..7adbbcd 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -32,3 +32,22 @@ LOCAL_SHARED_LIBRARIES := \
LOCAL_MODULE := bluetoothd

include $(BUILD_EXECUTABLE)
+
+#
+# bluetooth.default.so HAL
+#
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+ hal_bluetooth.c \
+
+LOCAL_SHARED_LIBRARIES := \
+ libcutils \
+
+LOCAL_MODULE := bluetooth.default
+LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := SHARED_LIBRARIES
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/android/hal_bluetooth.c b/android/hal_bluetooth.c
new file mode 100644
index 0000000..9970374
--- /dev/null
+++ b/android/hal_bluetooth.c
@@ -0,0 +1,348 @@
+/*
+ * Copyright (C) 2013 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 <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdbool.h>
+
+#include <hardware/bluetooth.h>
+
+#define LOG_TAG "BlueZ"
+#include <cutils/log.h>
+
+bt_callbacks_t *bt_hal_cbacks = NULL;
+
+static bool interface_ready(void)
+{
+ return bt_hal_cbacks != NULL;
+}
+
+static int init(bt_callbacks_t *callbacks)
+{
+ ALOGD(__func__);
+
+ if (interface_ready() == true)
+ return BT_STATUS_SUCCESS;
+
+ /* store reference to user callbacks */
+ bt_hal_cbacks = callbacks;
+
+ /* TODO: Init here bluezd task */
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static int enable(void)
+{
+ ALOGD(__func__);
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static int disable(void)
+{
+ ALOGD(__func__);
+
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static void cleanup(void)
+{
+ ALOGD(__func__);
+
+ if (interface_ready() == false)
+ return;
+
+ bt_hal_cbacks = NULL;
+}
+
+static int get_adapter_properties(void)
+{
+ ALOGD(__func__);
+
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static int get_adapter_property(bt_property_type_t type)
+{
+ ALOGD(__func__);
+
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static int set_adapter_property(const bt_property_t *property)
+{
+ ALOGD(__func__);
+
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ if (property == NULL)
+ return BT_STATUS_PARM_INVALID;
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static int get_remote_device_properties(bt_bdaddr_t *remote_addr)
+{
+ ALOGD(__func__);
+
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static int get_remote_device_property(bt_bdaddr_t *remote_addr,
+ bt_property_type_t type)
+{
+ ALOGD(__func__);
+
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static int set_remote_device_property(bt_bdaddr_t *remote_addr,
+ const bt_property_t *property)
+{
+ ALOGD(__func__);
+
+ /* sanity check */
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static int get_remote_service_record(bt_bdaddr_t *remote_addr, bt_uuid_t *uuid)
+{
+ ALOGD(__func__);
+
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static int get_remote_services(bt_bdaddr_t *remote_addr)
+{
+ ALOGD(__func__);
+
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static int start_discovery(void)
+{
+ ALOGD(__func__);
+
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static int cancel_discovery(void)
+{
+ ALOGD(__func__);
+
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static int create_bond(const bt_bdaddr_t *bd_addr)
+{
+ ALOGD(__func__);
+
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ if (bd_addr == NULL)
+ return BT_STATUS_PARM_INVALID;
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static int cancel_bond(const bt_bdaddr_t *bd_addr)
+{
+ ALOGD(__func__);
+
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static int remove_bond(const bt_bdaddr_t *bd_addr)
+{
+ ALOGD(__func__);
+
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static int pin_reply(const bt_bdaddr_t *bd_addr, uint8_t accept,
+ uint8_t pin_len, bt_pin_code_t *pin_code)
+{
+ ALOGD(__func__);
+
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static int ssp_reply(const bt_bdaddr_t *bd_addr, bt_ssp_variant_t variant,
+ uint8_t accept, uint32_t passkey)
+{
+
+ ALOGD(__func__);
+
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ if (bd_addr == NULL)
+ return BT_STATUS_PARM_INVALID;
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static const void *get_profile_interface(const char *profile_id)
+{
+ ALOGD("%s: %s", __func__, profile_id);
+
+ if (interface_ready() == false)
+ return NULL;
+
+ return NULL;
+}
+
+static int dut_mode_configure(uint8_t enable)
+{
+ ALOGD(__func__);
+
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static int dut_mode_send(uint16_t opcode, uint8_t *buf, uint8_t len)
+{
+ ALOGD(__func__);
+
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+/**
+ * HAL Interface declaration
+ */
+static const bt_interface_t bluetooth_if = {
+ sizeof(bt_interface_t),
+ init,
+ enable,
+ disable,
+ cleanup,
+ get_adapter_properties,
+ get_adapter_property,
+ set_adapter_property,
+ get_remote_device_properties,
+ get_remote_device_property,
+ set_remote_device_property,
+ get_remote_service_record,
+ get_remote_services,
+ start_discovery,
+ cancel_discovery,
+ create_bond,
+ remove_bond,
+ cancel_bond,
+ pin_reply,
+ ssp_reply,
+ get_profile_interface,
+ dut_mode_configure,
+ dut_mode_send
+};
+
+static const bt_interface_t *get_bluetooth_interface(void)
+{
+ ALOGD(__func__);
+
+ return &bluetooth_if;
+}
+
+static int close_bluetooth(struct hw_device_t *device)
+{
+ ALOGD(__func__);
+
+ cleanup();
+
+ return 0;
+}
+
+static int open_bluetooth(const struct hw_module_t *module, char const *name,
+ struct hw_device_t **device)
+{
+ bluetooth_device_t *dev = malloc(sizeof(bluetooth_device_t));
+
+ ALOGD(__func__);
+
+ memset(dev, 0, sizeof(bluetooth_device_t));
+ dev->common.tag = HARDWARE_DEVICE_TAG;
+ dev->common.version = 0;
+ dev->common.module = (struct hw_module_t *) module;
+ dev->common.close = close_bluetooth;
+ dev->get_bluetooth_interface = get_bluetooth_interface;
+
+ *device = (struct hw_device_t *) dev;
+
+ return 0;
+}
+
+static struct hw_module_methods_t bluetooth_module_methods = {
+ .open = open_bluetooth,
+};
+
+struct hw_module_t HAL_MODULE_INFO_SYM = {
+ .tag = HARDWARE_MODULE_TAG,
+ .version_major = 1,
+ .version_minor = 0,
+ .id = BT_HARDWARE_MODULE_ID,
+ .name = "BlueZ Bluetooth stack",
+ .author = "Intel Corporation",
+ .methods = &bluetooth_module_methods
+};
--
1.7.10.4


2013-10-08 14:51:20

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCHv3 12/15] android: Implement read_info_complete callback

From: Andrei Emeltchenko <[email protected]>

Handle read info complete callback from mgmt interface.
---
android/main.c | 101 +++++++++++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 89 insertions(+), 12 deletions(-)

diff --git a/android/main.c b/android/main.c
index a100013..a2ed8a4 100644
--- a/android/main.c
+++ b/android/main.c
@@ -54,6 +54,7 @@
#include "log.h"
#include "hcid.h"
#include "sdpd.h"
+#include "bt_adapter.h"

#include "lib/bluetooth.h"
#include "lib/mgmt.h"
@@ -69,6 +70,8 @@ static struct mgmt *mgmt_if = NULL;
static uint8_t mgmt_version = 0;
static uint8_t mgmt_revision = 0;

+struct bt_adapter *default_adapter = NULL;
+
static int sdp_start(void)
{
DBG("");
@@ -118,34 +121,108 @@ static GOptionEntry options[] = {
{ NULL }
};

-static void read_info_complete(uint8_t status, uint16_t length,
+static void load_link_keys_complete(uint8_t status, uint16_t length,
const void *param, void *user_data)
{
- /* TODO: Store Controller information */
-
- /**
- * Register all event notification handlers for controller.
- *
- * The handlers are registered after a succcesful read of the
- * controller info. From now on they can track updates and
- * notifications.
- */
+ DBG("status %u", status);
}

+static void load_link_keys(struct bt_adapter *adapter, GSList *keys)
+{
+ struct mgmt_cp_load_link_keys *cp;
+ size_t key_len = g_slist_length(keys);
+ struct mgmt_link_key_info *key;
+ size_t len;
+
+ DBG("");
+
+ len = sizeof(*cp) + key_len * sizeof(*key);
+ cp = g_try_malloc0(len);
+ if (cp == NULL) {
+ error("%s: Not enough memory for link keys loading", __func__);
+ return;
+ }
+
+ cp->debug_keys = 0;
+ cp->key_count = htobs(key_len);
+
+ mgmt_send(adapter->mgmt, MGMT_OP_LOAD_LINK_KEYS, adapter->dev_id, len,
+ cp, load_link_keys_complete, adapter, NULL);
+
+ free(cp);
+}
+
+static void read_info_complete(uint8_t status, uint16_t length,
+ const void *param, void *user_data)
+{
+ struct bt_adapter *adapter = user_data;
+ const struct mgmt_rp_read_info *rp = param;
+
+ DBG("");
+
+ if (status != MGMT_STATUS_SUCCESS) {
+ error("Failed to read info for index %u: %s (0x%02x)",
+ adapter->dev_id, mgmt_errstr(status), status);
+ goto failed;
+ }
+
+ if (length < sizeof(*rp)) {
+ error("Too small read info complete response");
+ goto failed;
+ }
+
+ if (bacmp(&rp->bdaddr, BDADDR_ANY) == 0) {
+ error("No Bluetooth address for index %u", adapter->dev_id);
+ goto failed;
+ }
+
+ /* Store adapter information */
+ bacpy(&adapter->bdaddr, &rp->bdaddr);
+ adapter->dev_class = rp->dev_class[0] | (rp->dev_class[1] << 8) |
+ (rp->dev_class[2] << 16);
+ adapter->name = g_strdup((const char *) rp->name);
+ adapter->short_name = g_strdup((const char *) rp->short_name);
+
+ adapter->supported_settings = btohs(rp->supported_settings);
+ adapter->current_settings = btohs(rp->current_settings);
+
+ /* TODO: Register all event notification handlers */
+
+ if (adapter->current_settings & MGMT_SETTING_POWERED)
+ adapter_start(adapter);
+
+ /* dummy link keys loading */
+ load_link_keys(adapter, NULL);
+
+ return;
+
+failed:
+ default_adapter = NULL;
+}

static void mgmt_index_added_event(uint16_t index, uint16_t length,
const void *param, void *user_data)
{
info("%s: index %u", __func__, index);

+ if (default_adapter != NULL) {
+ DBG("skip event for index %d", index);
+ return;
+ }
+
+ default_adapter = bt_adapter_new(index, mgmt_if);
+ if (default_adapter == NULL) {
+ error("Unable to create new adapter for index %u", index);
+ return;
+ }
+
DBG("sending read info command for index %u", index);

if (mgmt_send(mgmt_if, MGMT_OP_READ_INFO, index, 0, NULL,
- read_info_complete, NULL, NULL) > 0)
+ read_info_complete, default_adapter, NULL) > 0)
return;

error("Failed to read adapter info for index %u", index);
-
}

static void mgmt_index_removed_event(uint16_t index, uint16_t length,
--
1.7.10.4


2013-10-08 14:51:12

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCHv3 04/15] android: Enable Socket interface

From: Andrei Emeltchenko <[email protected]>

Returns socket interface, use header hal.h to avoid externs.
---
android/hal.h | 18 ++++++++++++++++++
android/hal_bluetooth.c | 11 +++++++++++
2 files changed, 29 insertions(+)
create mode 100644 android/hal.h

diff --git a/android/hal.h b/android/hal.h
new file mode 100644
index 0000000..40fbf03
--- /dev/null
+++ b/android/hal.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2013 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.
+ *
+ */
+
+btsock_interface_t *bt_get_sock_interface(void);
diff --git a/android/hal_bluetooth.c b/android/hal_bluetooth.c
index 9970374..00f3e8d 100644
--- a/android/hal_bluetooth.c
+++ b/android/hal_bluetooth.c
@@ -21,10 +21,13 @@
#include <stdbool.h>

#include <hardware/bluetooth.h>
+#include <hardware/bt_sock.h>

#define LOG_TAG "BlueZ"
#include <cutils/log.h>

+#include "hal.h"
+
bt_callbacks_t *bt_hal_cbacks = NULL;

static bool interface_ready(void)
@@ -32,6 +35,11 @@ static bool interface_ready(void)
return bt_hal_cbacks != NULL;
}

+static bool is_profile(const char *profile, const char *str)
+{
+ return strcmp(profile, str) == 0;
+}
+
static int init(bt_callbacks_t *callbacks)
{
ALOGD(__func__);
@@ -246,6 +254,9 @@ static const void *get_profile_interface(const char *profile_id)
if (interface_ready() == false)
return NULL;

+ if (is_profile(profile_id, BT_PROFILE_SOCKETS_ID))
+ return bt_get_sock_interface();
+
return NULL;
}

--
1.7.10.4


2013-10-08 10:33:43

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCHv2 01/15] android: Supress missing initializers warnings

From: Andrei Emeltchenko <[email protected]>

These types of warnings are disabled in BlueZ makeifiles

main.c:67:2: warning: missing initializer [-Wmissing-field-initializers]
main.c:67:2: warning: (near initialization for 'options[1].short_name')
[-Wmissing-field-initializers]
---
android/Android.mk | 3 +++
1 file changed, 3 insertions(+)

diff --git a/android/Android.mk b/android/Android.mk
index ec820ac..5498b41 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -23,6 +23,9 @@ LOCAL_C_INCLUDES := \

LOCAL_CFLAGS := -DVERSION=\"$(BLUEZ_VERSION)\"

+# to suppress the "warning: missing initializer near initialization.." warning
+LOCAL_CFLAGS += -Wno-missing-field-initializers
+
LOCAL_SHARED_LIBRARIES := \
libglib \

--
1.7.10.4


2013-10-08 10:33:50

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCHv2 08/15] android: Add adapter and device struct for BlueZ daemon

From: Andrei Emeltchenko <[email protected]>

Adapter structure in BlueZ daemon keeps track of default adapter
and device structure keeps track about found devices.
---
android/bt_adapter.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++
android/bt_adapter.h | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 116 insertions(+)
create mode 100644 android/bt_adapter.c
create mode 100644 android/bt_adapter.h

diff --git a/android/bt_adapter.c b/android/bt_adapter.c
new file mode 100644
index 0000000..e21d50c
--- /dev/null
+++ b/android/bt_adapter.c
@@ -0,0 +1,56 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2013 Intel Corporation. All rights reserved.
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include "bt_adapter.h"
+#include "log.h"
+#include "src/shared/mgmt.h"
+
+struct bt_adapter *bt_adapter_new(uint16_t index, struct mgmt *mgmt_if)
+{
+ struct bt_adapter *adapter;
+
+ adapter = g_try_new0(struct bt_adapter, 1);
+ if (!adapter)
+ return NULL;
+
+ adapter->dev_id = index;
+ adapter->mgmt = mgmt_ref(mgmt_if);
+
+ return adapter;
+}
+
+void adapter_start(struct bt_adapter *adapter)
+{
+ DBG("enabled %u", adapter->dev_id);
+
+ /* TODO: CB: report scan mode */
+
+ /* TODO: SDP start here */
+
+ /* TODO: CB: report state on */
+}
+
+void adapter_stop(struct bt_adapter *adapter)
+{
+ DBG("disabled %u", adapter->dev_id);
+}
diff --git a/android/bt_adapter.h b/android/bt_adapter.h
new file mode 100644
index 0000000..6877cc7
--- /dev/null
+++ b/android/bt_adapter.h
@@ -0,0 +1,60 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2013 Intel Corporation. All rights reserved.
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <glib.h>
+
+#include "lib/bluetooth.h"
+
+struct bt_device {
+ int refcnt;
+
+ bdaddr_t bdaddr;
+ uint8_t bdaddr_type;
+ uint32_t cod;
+ char *name;
+};
+
+struct bt_adapter {
+ int refcnt;
+
+ uint16_t dev_id;
+ struct mgmt *mgmt;
+ bdaddr_t bdaddr;
+ uint32_t dev_class;
+
+ char *name;
+ char *short_name;
+
+ uint32_t supported_settings;
+ uint32_t current_settings;
+
+ GList *found_devices;
+};
+
+struct bt_adapter *bt_adapter_new(uint16_t index, struct mgmt *mgmt_if);
+
+void adapter_start(struct bt_adapter *adapter);
+void adapter_stop(struct bt_adapter *adapter);
--
1.7.10.4


2013-10-08 10:33:52

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCHv2 10/15] android: sdp: Reuse BlueZ SDP server in Android

From: Andrei Emeltchenko <[email protected]>

Reuse existing SDP server code in Android GPL daemon.
---
Makefile.android | 7 +++++--
android/Android.mk | 7 +++++++
android/bt_adapter.c | 2 --
android/main.c | 28 ++++++++++++++++++++++++++++
4 files changed, 40 insertions(+), 4 deletions(-)

diff --git a/Makefile.android b/Makefile.android
index 9a2c486..d576b52 100644
--- a/Makefile.android
+++ b/Makefile.android
@@ -2,9 +2,12 @@ if ANDROID
noinst_PROGRAMS += android/bluetoothd

android_bluetoothd_SOURCES = android/main.c src/log.c \
+ src/sdpd-database.c src/sdpd-server.c \
+ src/sdpd-service.c src/sdpd-request.c \
src/shared/util.h src/shared/util.c \
- src/shared/mgmt.h src/shared/mgmt.c
-android_bluetoothd_LDADD = @GLIB_LIBS@
+ src/shared/mgmt.h src/shared/mgmt.c \
+ android/bt_adapter.h android/bt_adapter.c
+android_bluetoothd_LDADD = lib/libbluetooth-internal.la @GLIB_LIBS@
endif

EXTRA_DIST += android/Android.mk android/log.c
diff --git a/android/Android.mk b/android/Android.mk
index 8f95a66..e7a70d0 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -17,6 +17,11 @@ LOCAL_SRC_FILES := \
log.c \
../src/shared/mgmt.c \
../src/shared/util.c \
+ bt_adapter.c \
+ ../src/sdpd-database.c \
+ ../src/sdpd-service.c \
+ ../src/sdpd-request.c \
+ ../src/sdpd-server.c \

LOCAL_C_INCLUDES := \
$(call include-path-for, glib) \
@@ -25,6 +30,7 @@ LOCAL_C_INCLUDES := \
LOCAL_C_INCLUDES += \
$(LOCAL_PATH)/../ \
$(LOCAL_PATH)/../src \
+ $(LOCAL_PATH)/../lib \

LOCAL_CFLAGS := -DVERSION=\"$(BLUEZ_VERSION)\"

@@ -39,6 +45,7 @@ LOCAL_CFLAGS += -DSOCK_CLOEXEC=02000000 -DSOCK_NONBLOCK=04000

LOCAL_SHARED_LIBRARIES := \
libglib \
+ libbluetooth \

LOCAL_MODULE := bluetoothd
LOCAL_REQUIRED_MODULES := libbluetooth
diff --git a/android/bt_adapter.c b/android/bt_adapter.c
index e21d50c..6b758bf 100644
--- a/android/bt_adapter.c
+++ b/android/bt_adapter.c
@@ -45,8 +45,6 @@ void adapter_start(struct bt_adapter *adapter)

/* TODO: CB: report scan mode */

- /* TODO: SDP start here */
-
/* TODO: CB: report state on */
}

diff --git a/android/main.c b/android/main.c
index 3580ac7..7968ed0 100644
--- a/android/main.c
+++ b/android/main.c
@@ -36,6 +36,8 @@
#include <glib.h>

#include "log.h"
+#include "hcid.h"
+#include "sdpd.h"

#include "lib/bluetooth.h"
#include "lib/mgmt.h"
@@ -43,12 +45,36 @@

#define SHUTDOWN_GRACE_SECONDS 10

+struct main_opts main_opts;
+
static GMainLoop *event_loop;
static struct mgmt *mgmt_if = NULL;

static uint8_t mgmt_version = 0;
static uint8_t mgmt_revision = 0;

+static int sdp_start(void)
+{
+ DBG("");
+
+ /* TODO: add logic */
+
+ /* sdpd-server use these settings */
+ memset(&main_opts, 0, sizeof(main_opts));
+
+ /* Use params: mtu = 0, flags = 0 */
+ return start_sdp_server(0, 0);
+}
+
+static void sdp_stop(void)
+{
+ DBG("");
+
+ /* TODO: add logic */
+
+ stop_sdp_server();
+}
+
static gboolean quit_eventloop(gpointer user_data)
{
g_main_loop_quit(event_loop);
@@ -287,11 +313,13 @@ int main(int argc, char *argv[])
sigaction(SIGTERM, &sa, NULL);

init_mgmt_interface();
+ sdp_start();

DBG("Entering main loop");

g_main_loop_run(event_loop);

+ sdp_stop();
cleanup_mgmt_interface();
g_main_loop_unref(event_loop);

--
1.7.10.4


2013-10-08 10:33:42

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCHv2 00/15] Basic code for Android BlueZ

From: Andrei Emeltchenko <[email protected]>

Skeletons for Android Bluetooth and Socket HALs and BlueZ daemon.

Code is located also here:
https://code.google.com/p/android-bluez.bluez/

Getting Started
https://code.google.com/p/android-bluez/wiki/GettingStarted

Changes:
* PATCHv2: Fixed Szymon's comments from review.
* PATCHv1: Rebased against applied fdanis patch set, moved SDP init from
adapter start to daemon start, other minor fixes.
* RFCv3: Rebased against recent FDanis patch set, fixed library build,
corrected process capabilities, corrected API header.
* RFCv2: Took comments from mailing list reviewers. Use single
makefile, remove mgmt library and directly link, remove adapter
code and use default_adapter pointer and other style changes.
Dropped some patches due to major changes.

Andrei Emeltchenko (15):
android: Supress missing initializers warnings
android: Add Adapter Bluetooth HAL template
android: Add Socket Bluetooth HAL template
android: Enable Socket interface
android: Start Android Bluetooth daemon
android: Add basic mgmt initialization sequence
android: Create HAL API header skeleton
android: Add adapter and device struct for BlueZ daemon
android: Add Android Makefile for libbluetooth
android: sdp: Reuse BlueZ SDP server in Android
android: Add cap to bind to port < 1024
android: Implement read_info_complete callback
android: Handle mgmt changed events
android: Add makefile for hciconfig
android: Add makefile for hcitool

Makefile.android | 9 +-
android/Android.mk | 166 +++++++++++++++
android/bt_adapter.c | 54 +++++
android/bt_adapter.h | 60 ++++++
android/hal.h | 18 ++
android/hal_bluetooth.c | 403 ++++++++++++++++++++++++++++++++++++
android/hal_bt_sock.c | 84 ++++++++
android/hal_msg.h | 255 +++++++++++++++++++++++
android/main.c | 519 +++++++++++++++++++++++++++++++++++++++++++++++
configure.ac | 4 +
10 files changed, 1570 insertions(+), 2 deletions(-)
create mode 100644 android/bt_adapter.c
create mode 100644 android/bt_adapter.h
create mode 100644 android/hal.h
create mode 100644 android/hal_bluetooth.c
create mode 100644 android/hal_bt_sock.c
create mode 100644 android/hal_msg.h

--
1.7.10.4


2013-10-08 10:33:45

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCHv2 03/15] android: Add Socket Bluetooth HAL template

From: Andrei Emeltchenko <[email protected]>

bt_sock HAL handles Bluetooth sockets for Android.
---
android/Android.mk | 1 +
android/hal_bt_sock.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 85 insertions(+)
create mode 100644 android/hal_bt_sock.c

diff --git a/android/Android.mk b/android/Android.mk
index 7adbbcd..2cabff4 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -41,6 +41,7 @@ include $(CLEAR_VARS)

LOCAL_SRC_FILES := \
hal_bluetooth.c \
+ hal_bt_sock.c \

LOCAL_SHARED_LIBRARIES := \
libcutils \
diff --git a/android/hal_bt_sock.c b/android/hal_bt_sock.c
new file mode 100644
index 0000000..cbb42d1
--- /dev/null
+++ b/android/hal_bt_sock.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2013 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 <stdlib.h>
+
+#include <hardware/bluetooth.h>
+#include <hardware/bt_sock.h>
+
+#define LOG_TAG "BlueZ"
+#include <cutils/log.h>
+
+static bt_status_t btsock_listen_rfcomm(const char *service_name,
+ const uint8_t *uuid, int chan,
+ int *sock, int flags)
+{
+ ALOGD(__func__);
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static bt_status_t listen(btsock_type_t type, const char *service_name,
+ const uint8_t *uuid, int chan,
+ int *sock, int flags)
+{
+ if ((uuid == NULL && chan <= 0) || sock == NULL) {
+ ALOGE("%s: invalid params: uuid %p, chan %d, sock %p",
+ __func__, uuid, chan, sock);
+ return BT_STATUS_PARM_INVALID;
+ }
+
+ ALOGD("%s: uuid %p chan %d sock %p type %d service_name %s",
+ __func__, uuid, chan, sock, type, service_name);
+
+ switch (type) {
+ case BTSOCK_RFCOMM:
+ return btsock_listen_rfcomm(service_name, uuid, chan,
+ sock, flags);
+ default:
+ ALOGE("%s: Socket type %d not supported", __func__, type);
+ }
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static bt_status_t connect(const bt_bdaddr_t *bdaddr, btsock_type_t type,
+ const uint8_t *uuid, int chan,
+ int *sock, int flags)
+{
+ if ((uuid == NULL && chan <= 0) || bdaddr == NULL || sock == NULL) {
+ ALOGE("invalid params: bd_addr %p, uuid %p, chan %d, sock %p",
+ bdaddr, uuid, chan, sock);
+ return BT_STATUS_PARM_INVALID;
+ }
+
+ ALOGD("%s: uuid %p chan %d sock %p type %d", __func__, uuid, chan,
+ sock, type);
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static btsock_interface_t btsock_if = {
+ sizeof(btsock_if),
+ listen,
+ connect
+};
+
+btsock_interface_t *bt_get_sock_interface(void)
+{
+ return &btsock_if;
+}
--
1.7.10.4


2013-10-08 10:33:55

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCHv2 13/15] android: Handle mgmt changed events

From: Andrei Emeltchenko <[email protected]>

Add code handling changing adapter settings.
---
android/main.c | 154 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 154 insertions(+)

diff --git a/android/main.c b/android/main.c
index 83aa6ed..a565030 100644
--- a/android/main.c
+++ b/android/main.c
@@ -127,6 +127,159 @@ static void load_link_keys_complete(uint8_t status, uint16_t length,
DBG("status %u", status);
}

+static void mgmt_local_name_changed_event(uint16_t index, uint16_t length,
+ const void *param, void *user_data)
+{
+ struct bt_adapter *adapter = user_data;
+ const struct mgmt_cp_set_local_name *rp = param;
+
+ if (length < sizeof(*rp)) {
+ error("Wrong size of local name changed parameters");
+ return;
+ }
+
+ if (adapter != default_adapter) {
+ error("Wrong adapter %p", adapter);
+ return;
+ }
+
+ if (!g_strcmp0(adapter->short_name, (const char *) rp->short_name) &&
+ !g_strcmp0(adapter->name, (const char *) rp->name))
+ return;
+
+ DBG("name: %s short name: %s", rp->name, rp->short_name);
+
+ g_free(adapter->name);
+ adapter->name = g_strdup((const char *) rp->name);
+
+ g_free(adapter->short_name);
+ adapter->short_name = g_strdup((const char *) rp->short_name);
+
+ /* TODO Update services if needed */
+}
+
+static void settings_changed_connectable(struct bt_adapter *adapter)
+{
+ /* TODO */
+}
+
+static void settings_changed_discoverable(struct bt_adapter *adapter)
+{
+ /* TODO */
+}
+
+static void settings_changed(struct bt_adapter *adapter, uint32_t settings)
+{
+ uint32_t changed_mask;
+
+ changed_mask = adapter->current_settings ^ settings;
+
+ adapter->current_settings = settings;
+
+ DBG("0x%08x", changed_mask);
+
+ if (changed_mask & MGMT_SETTING_POWERED) {
+ info("Powered");
+
+ if (adapter->current_settings & MGMT_SETTING_POWERED)
+ adapter_start(adapter);
+ else
+ adapter_stop(adapter);
+ }
+
+ /* Seems not needed for Android */
+ if (changed_mask & MGMT_SETTING_PAIRABLE)
+ DBG("Pairable");
+
+ /*
+ * There are only 2 scan modes:
+ * CONNECTABLE and CONNECTABLE_DISCOVERABLE
+ */
+ if (changed_mask & MGMT_SETTING_CONNECTABLE) {
+ DBG("Connectable");
+
+ settings_changed_connectable(adapter);
+ }
+
+ if (changed_mask & MGMT_SETTING_DISCOVERABLE) {
+ DBG("Discoverable");
+
+ settings_changed_discoverable(adapter);
+ }
+}
+
+static void new_settings_callback(uint16_t index, uint16_t length,
+ const void *param, void *user_data)
+{
+ struct bt_adapter *adapter = user_data;
+ uint32_t settings;
+
+ if (length < sizeof(settings)) {
+ error("Wrong size of new settings parameters");
+ return;
+ }
+
+ if (adapter != default_adapter) {
+ error("Wrong adapter %p", adapter);
+ return;
+ }
+
+ settings = bt_get_le32(param);
+
+ DBG("settings: 0x%8.8x -> 0x%8.8x", adapter->current_settings,
+ settings);
+
+ if (settings == adapter->current_settings)
+ return;
+
+ settings_changed(adapter, settings);
+}
+
+static void mgmt_dev_class_changed_event(uint16_t index, uint16_t length,
+ const void *param, void *user_data)
+{
+ struct bt_adapter *adapter = user_data;
+ const struct mgmt_cod *rp = param;
+ uint32_t dev_class;
+
+ if (length < sizeof(*rp)) {
+ error("Wrong size of class of device changed parameters");
+ return;
+ }
+
+ if (adapter != default_adapter) {
+ error("Wrong adapter %p", adapter);
+ return;
+ }
+
+ dev_class = rp->val[0] | (rp->val[1] << 8) | (rp->val[2] << 16);
+
+ if (dev_class == adapter->dev_class)
+ return;
+
+ DBG("Class: 0x%06x", dev_class);
+
+ adapter->dev_class = dev_class;
+
+ /* TODO: Inform prop change: Class */
+
+ /* TODO: Gatt attrib set*/
+}
+
+static void register_mgmt_handlers(struct bt_adapter *adapter)
+{
+ mgmt_register(adapter->mgmt, MGMT_EV_NEW_SETTINGS, adapter->dev_id,
+ new_settings_callback, adapter, NULL);
+
+ mgmt_register(adapter->mgmt, MGMT_EV_CLASS_OF_DEV_CHANGED,
+ adapter->dev_id, mgmt_dev_class_changed_event,
+ adapter, NULL);
+
+ mgmt_register(adapter->mgmt, MGMT_EV_LOCAL_NAME_CHANGED,
+ adapter->dev_id, mgmt_local_name_changed_event,
+ adapter, NULL);
+}
+
static void load_link_keys(struct bt_adapter *adapter, GSList *keys)
{
struct mgmt_cp_load_link_keys *cp;
@@ -187,6 +340,7 @@ static void read_info_complete(uint8_t status, uint16_t length,
adapter->current_settings = btohs(rp->current_settings);

/* TODO: Register all event notification handlers */
+ register_mgmt_handlers(default_adapter);

if (adapter->current_settings & MGMT_SETTING_POWERED)
adapter_start(adapter);
--
1.7.10.4


2013-10-08 10:33:49

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCHv2 07/15] android: Create HAL API header skeleton

From: Andrei Emeltchenko <[email protected]>

Header describes the protocol between Android HAL threads and BlueZ
daemon.
---
android/hal_msg.h | 255 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 255 insertions(+)
create mode 100644 android/hal_msg.h

diff --git a/android/hal_msg.h b/android/hal_msg.h
new file mode 100644
index 0000000..c6bc883
--- /dev/null
+++ b/android/hal_msg.h
@@ -0,0 +1,255 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2013 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
+ *
+ */
+
+#ifndef __packed
+#define __packed __attribute__((packed))
+#endif
+
+typedef struct {
+ uint8_t b[6];
+} __packed __bdaddr_t;
+
+struct hal_msg_hdr {
+ uint8_t service_id;
+ uint8_t opcode;
+ uint16_t len;
+ uint8_t payload[0];
+} __packed;
+
+#define HAL_SERVICE_ID_CORE 0
+#define HAL_SERVICE_ID_BLUETOOTH 1
+#define HAL_SERVICE_ID_SOCK 2
+#define HAL_SERVICE_ID_HIDHOST 3
+#define HAL_SERVICE_ID_PAN 4
+#define HAL_SERVICE_ID_HANDSFREE 5
+#define HAL_SERVICE_ID_AD2P 6
+#define HAL_SERVICE_ID_HEALTH 7
+#define HAL_SERVICE_ID_AVRCP 8
+#define HAL_SERVICE_ID_GATT 9
+
+/* Core Service */
+
+#define HAL_MSG_OP_ERROR 0x00
+struct hal_msg_rp_error {
+ uint8_t status;
+} __packed;
+
+#define HAL_MSG_OP_REGISTER_MODULE 0x01
+struct hal_msg_cp_register_module {
+ uint8_t service_id;
+} __packed;
+struct hal_msg_rp_register_module {
+ uint8_t service_id;
+} __packed;
+
+#define HAL_MSG_OP_UNREGISTER_MODULE 0x02
+struct hal_msg_cp_unregister_module {
+ uint8_t service_id;
+} __packed;
+
+/* Bluetooth Core HAL API */
+
+#define HAL_MSG_OP_BT_ENABLE 0x01
+
+#define HAL_MSG_OP_BT_DISABLE 0x02
+
+#define HAL_MSG_OP_BT_GET_ADAPTER_PROPS 0x03
+
+#define HAL_MSG_OP_BT_GET_ADAPTER_PROP 0x04
+struct hal_msg_cp_bt_get_adapter_prop {
+ uint8_t type;
+} __packed;
+
+#define HAL_MSG_OP_BT_SET_ADAPTER_PROP 0x05
+struct hal_msg_cp_bt_set_adapter_prop {
+ uint8_t type;
+ uint16_t len;
+ uint8_t val[0];
+} __packed;
+
+#define HAL_MSG_OP_BT_GET_REMOTE_DEVICE_PROPS 0x06
+struct hal_msg_cp_bt_get_remote_device_props {
+ __bdaddr_t bdaddr;
+} __packed;
+
+#define HAL_MSG_OP_BT_GET_REMOTE_DEVICE_PROP 0x07
+struct hal_msg_cp_bt_get_remote_device_prop {
+ __bdaddr_t bdaddr;
+ uint8_t type;
+} __packed;
+
+#define HAL_MSG_OP_BT_SET_REMOTE_DEVICE_PROP 0x08
+struct hal_msg_cp_bt_set_remote_device_prop {
+ __bdaddr_t bdaddr;
+ uint8_t type;
+ uint16_t len;
+ uint8_t val[0];
+} __packed;
+
+#define HAL_MSG_OP_BT_GET_REMOTE_SERVICE_REC 0x09
+struct hal_msg_cp_bt_get_remote_service_rec {
+ __bdaddr_t bdaddr;
+ uint8_t uuid[16];
+} __packed;
+
+#define HAL_MSG_OP_BT_GET_REMOTE_SERVICE 0x0a
+struct hal_msg_cp_bt_get_remote_service {
+ __bdaddr_t bdaddr;
+} __packed;
+
+#define HAL_MSG_OP_BT_START_DISCOVERY 0x0b
+
+#define HAL_MSG_OP_BT_CANCEL_DISCOVERY 0x0c
+
+#define HAL_MSG_OP_BT_CREATE_BOND 0x0d
+struct hal_msg_cp_bt_create_bond {
+ __bdaddr_t bdaddr;
+} __packed;
+
+#define HAL_MSG_OP_BT_REMOVE_BOND 0x0d
+struct hal_msg_cp_bt_remove_bond {
+ __bdaddr_t bdaddr;
+} __packed;
+
+#define HAL_MSG_OP_BT_CANCEL_BOND 0x0f
+struct hal_msg_cp_bt_cancel_bond {
+ __bdaddr_t bdaddr;
+} __packed;
+
+#define HAL_MSG_OP_BT_PIN_REPLY 0x10
+struct hal_msg_cp_bt_pin_reply {
+ __bdaddr_t bdaddr;
+ uint8_t accept;
+ uint8_t pin_len;
+ uint8_t pin_code[16];
+} __packed;
+
+#define HAL_MSG_OP_BT_SSP_REPLY 0x11
+struct hal_msg_cp_bt_ssp_reply {
+ __bdaddr_t bdaddr;
+ uint8_t ssp_variant;
+ uint8_t accept;
+ uint32_t passkey;
+} __packed;
+
+#define HAL_MSG_OP_BT_DUT_MODE_CONF 0x12
+struct hal_msg_cp_bt_dut_mode_conf {
+ uint8_t enable;
+} __packed;
+
+#define HAL_MSG_OP_BT_DUT_MODE_SEND 0x13
+struct hal_msg_cp_bt_dut_mode_send {
+ uint16_t opcode;
+ uint8_t len;
+ uint8_t data[0];
+} __packed;
+
+#define HAL_MSG_OP_BT_LE_TEST_MODE 0x14
+struct hal_msg_cp_bt_le_test_mode {
+ uint16_t opcode;
+ uint8_t len;
+ uint8_t data[0];
+} __packed;
+
+/* Notifications and confirmations */
+
+#define HAL_MSG_EV_BT_ERROR 0x80
+
+#define HAL_MSG_EV_BT_ADAPTER_STATE_CHANGED 0x81
+struct hal_msg_ev_bt_adapter_state_changed {
+ uint8_t state;
+} __packed;
+
+#define HAL_MSG_EV_BT_ADAPTER_PROPS_CHANGED 0x82
+struct hal_property {
+ uint8_t type;
+ uint16_t len;
+ uint8_t val[0];
+} __packed;
+struct hal_msg_ev_bt_adapter_props_changed {
+ uint8_t status;
+ uint8_t num_props;
+ struct hal_property props[0];
+} __packed;
+
+#define HAL_MSG_EV_BT_REMOTE_DEVICE_PROPS 0x83
+struct hal_msg_ev_bt_remote_device_props {
+ uint8_t status;
+ __bdaddr_t bdaddr;
+ uint8_t num_props;
+ struct hal_property props[0];
+} __packed;
+
+#define HAL_MSG_EV_BT_DEVICE_FOUND 0x84
+struct hal_msg_ev_bt_device_found {
+ uint8_t num_props;
+ struct hal_property props[0];
+} __packed;
+
+#define HAL_MSG_EV_BT_DISCOVERY_STATE_CHANGED 0x85
+struct hal_msg_ev_bt_discovery_state_changed {
+ uint8_t state;
+} __packed;
+
+#define HAL_MSG_EV_BT_PIN_REQUEST 0x86
+struct hal_msg_ev_bt_pin_request {
+ __bdaddr_t bdaddr;
+ uint8_t name[249 - 1];
+ uint8_t class_of_dev[3];
+} __packed;
+
+#define HAL_MSG_EV_BT_SSP_REQUEST 0x87
+struct hal_msg_ev_bt_ssp_request {
+ __bdaddr_t bdaddr;
+ uint8_t name[249 - 1];
+ uint8_t class_of_dev[3];
+ uint8_t pairing_variant;
+ uint32_t passkey;
+} __packed;
+
+#define HAL_MSG_EV_BT_BOND_STATE_CHANGED 0x88
+struct hal_msg_ev_bt_bond_state_changed {
+ uint8_t status;
+ __bdaddr_t bdaddr;
+ uint8_t state;
+} __packed;
+
+#define HAL_MSG_EV_BT_ACL_STATE_CHANGED 0x89
+struct hal_msg_ev_bt_acl_state_changed {
+ uint8_t status;
+ __bdaddr_t bdaddr;
+ uint8_t state;
+} __packed;
+
+#define HAL_MSG_EV_BT_DUT_MODE_RECEIVE 0x8a
+struct hal_msg_ev_bt_dut_mode_receive {
+ uint16_t opcode;
+ uint8_t len;
+ uint8_t data[0];
+} __packed;
+
+#define HAL_MSG_EV_BT_LE_TEST_MODE 0x8b
+struct hal_msg_ev_bt_le_test_mode {
+ uint8_t status;
+ uint16_t num_packets;
+} __packed;
--
1.7.10.4


2013-10-08 10:33:54

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCHv2 12/15] android: Implement read_info_complete callback

From: Andrei Emeltchenko <[email protected]>

Handle read info complete callback from mgmt interface.
---
android/main.c | 101 +++++++++++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 89 insertions(+), 12 deletions(-)

diff --git a/android/main.c b/android/main.c
index 4ef70bd..83aa6ed 100644
--- a/android/main.c
+++ b/android/main.c
@@ -54,6 +54,7 @@
#include "log.h"
#include "hcid.h"
#include "sdpd.h"
+#include "bt_adapter.h"

#include "lib/bluetooth.h"
#include "lib/mgmt.h"
@@ -69,6 +70,8 @@ static struct mgmt *mgmt_if = NULL;
static uint8_t mgmt_version = 0;
static uint8_t mgmt_revision = 0;

+struct bt_adapter *default_adapter = NULL;
+
static int sdp_start(void)
{
DBG("");
@@ -118,34 +121,108 @@ static GOptionEntry options[] = {
{ NULL }
};

-static void read_info_complete(uint8_t status, uint16_t length,
+static void load_link_keys_complete(uint8_t status, uint16_t length,
const void *param, void *user_data)
{
- /* TODO: Store Controller information */
-
- /**
- * Register all event notification handlers for controller.
- *
- * The handlers are registered after a succcesful read of the
- * controller info. From now on they can track updates and
- * notifications.
- */
+ DBG("status %u", status);
}

+static void load_link_keys(struct bt_adapter *adapter, GSList *keys)
+{
+ struct mgmt_cp_load_link_keys *cp;
+ size_t key_len = g_slist_length(keys);
+ struct mgmt_link_key_info *key;
+ size_t len;
+
+ DBG("");
+
+ len = sizeof(*cp) + key_len * sizeof(*key);
+ cp = g_try_malloc0(len);
+ if (cp == NULL) {
+ error("%s: Not enough memory for link keys loading", __func__);
+ return;
+ }
+
+ cp->debug_keys = 0;
+ cp->key_count = htobs(key_len);
+
+ mgmt_send(adapter->mgmt, MGMT_OP_LOAD_LINK_KEYS, adapter->dev_id, len,
+ cp, load_link_keys_complete, adapter, NULL);
+
+ free(cp);
+}
+
+static void read_info_complete(uint8_t status, uint16_t length,
+ const void *param, void *user_data)
+{
+ struct bt_adapter *adapter = user_data;
+ const struct mgmt_rp_read_info *rp = param;
+
+ DBG("");
+
+ if (status != MGMT_STATUS_SUCCESS) {
+ error("Failed to read info for index %u: %s (0x%02x)",
+ adapter->dev_id, mgmt_errstr(status), status);
+ goto failed;
+ }
+
+ if (length < sizeof(*rp)) {
+ error("Too small read info complete response");
+ goto failed;
+ }
+
+ if (bacmp(&rp->bdaddr, BDADDR_ANY) == 0) {
+ error("No Bluetooth address for index %u", adapter->dev_id);
+ goto failed;
+ }
+
+ /* Store adapter information */
+ bacpy(&adapter->bdaddr, &rp->bdaddr);
+ adapter->dev_class = rp->dev_class[0] | (rp->dev_class[1] << 8) |
+ (rp->dev_class[2] << 16);
+ adapter->name = g_strdup((const char *) rp->name);
+ adapter->short_name = g_strdup((const char *) rp->short_name);
+
+ adapter->supported_settings = btohs(rp->supported_settings);
+ adapter->current_settings = btohs(rp->current_settings);
+
+ /* TODO: Register all event notification handlers */
+
+ if (adapter->current_settings & MGMT_SETTING_POWERED)
+ adapter_start(adapter);
+
+ /* dummy link keys loading */
+ load_link_keys(adapter, NULL);
+
+ return;
+
+failed:
+ default_adapter = NULL;
+}

static void mgmt_index_added_event(uint16_t index, uint16_t length,
const void *param, void *user_data)
{
info("%s: index %u", __func__, index);

+ if (default_adapter != NULL) {
+ DBG("skip event for index %d", index);
+ return;
+ }
+
+ default_adapter = bt_adapter_new(index, mgmt_if);
+ if (default_adapter == NULL) {
+ error("Unable to create new adapter for index %u", index);
+ return;
+ }
+
DBG("sending read info command for index %u", index);

if (mgmt_send(mgmt_if, MGMT_OP_READ_INFO, index, 0, NULL,
- read_info_complete, NULL, NULL) > 0)
+ read_info_complete, default_adapter, NULL) > 0)
return;

error("Failed to read adapter info for index %u", index);
-
}

static void mgmt_index_removed_event(uint16_t index, uint16_t length,
--
1.7.10.4


2013-10-08 10:33:48

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCHv2 06/15] android: Add basic mgmt initialization sequence

From: Andrei Emeltchenko <[email protected]>

Initialize bluetooth controller via mgmt interface.
---
Makefile.android | 4 +-
android/Android.mk | 11 +++
android/main.c | 189 ++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 203 insertions(+), 1 deletion(-)

diff --git a/Makefile.android b/Makefile.android
index e161e6d..9a2c486 100644
--- a/Makefile.android
+++ b/Makefile.android
@@ -1,7 +1,9 @@
if ANDROID
noinst_PROGRAMS += android/bluetoothd

-android_bluetoothd_SOURCES = android/main.c src/log.c
+android_bluetoothd_SOURCES = android/main.c src/log.c \
+ src/shared/util.h src/shared/util.c \
+ src/shared/mgmt.h src/shared/mgmt.c
android_bluetoothd_LDADD = @GLIB_LIBS@
endif

diff --git a/android/Android.mk b/android/Android.mk
index 2cabff4..f5fd863 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -15,10 +15,15 @@ include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
main.c \
log.c \
+ ../src/shared/mgmt.c \
+ ../src/shared/util.c \

LOCAL_C_INCLUDES := \
$(call include-path-for, glib) \
$(call include-path-for, glib)/glib \
+
+LOCAL_C_INCLUDES += \
+ $(LOCAL_PATH)/../ \
$(LOCAL_PATH)/../src \

LOCAL_CFLAGS := -DVERSION=\"$(BLUEZ_VERSION)\"
@@ -26,6 +31,12 @@ LOCAL_CFLAGS := -DVERSION=\"$(BLUEZ_VERSION)\"
# to suppress the "warning: missing initializer near initialization.." warning
LOCAL_CFLAGS += -Wno-missing-field-initializers

+# to suppress the "pointer of type 'void *' used in arithmetic" warning
+LOCAL_CFLAGS += -Wno-pointer-arith
+
+# Define missing flags for Android 4.2
+LOCAL_CFLAGS += -DSOCK_CLOEXEC=02000000 -DSOCK_NONBLOCK=04000
+
LOCAL_SHARED_LIBRARIES := \
libglib \

diff --git a/android/main.c b/android/main.c
index f75b0a8..3580ac7 100644
--- a/android/main.c
+++ b/android/main.c
@@ -25,6 +25,7 @@
#include <config.h>
#endif

+#include <stdbool.h>
#include <signal.h>
#include <stdint.h>
#include <stdio.h>
@@ -36,9 +37,17 @@

#include "log.h"

+#include "lib/bluetooth.h"
+#include "lib/mgmt.h"
+#include "src/shared/mgmt.h"
+
#define SHUTDOWN_GRACE_SECONDS 10

static GMainLoop *event_loop;
+static struct mgmt *mgmt_if = NULL;
+
+static uint8_t mgmt_version = 0;
+static uint8_t mgmt_revision = 0;

static gboolean quit_eventloop(gpointer user_data)
{
@@ -67,6 +76,183 @@ static GOptionEntry options[] = {
{ NULL }
};

+static void read_info_complete(uint8_t status, uint16_t length,
+ const void *param, void *user_data)
+{
+ /* TODO: Store Controller information */
+
+ /**
+ * Register all event notification handlers for controller.
+ *
+ * The handlers are registered after a succcesful read of the
+ * controller info. From now on they can track updates and
+ * notifications.
+ */
+}
+
+
+static void mgmt_index_added_event(uint16_t index, uint16_t length,
+ const void *param, void *user_data)
+{
+ info("%s: index %u", __func__, index);
+
+ DBG("sending read info command for index %u", index);
+
+ if (mgmt_send(mgmt_if, MGMT_OP_READ_INFO, index, 0, NULL,
+ read_info_complete, NULL, NULL) > 0)
+ return;
+
+ error("Failed to read adapter info for index %u", index);
+
+}
+
+static void mgmt_index_removed_event(uint16_t index, uint16_t length,
+ const void *param, void *user_data)
+{
+ info("%s: index %u", __func__, index);
+}
+
+static void read_index_list_complete(uint8_t status, uint16_t length,
+ const void *param, void *user_data)
+{
+ const struct mgmt_rp_read_index_list *rp = param;
+ uint16_t num;
+ int i;
+
+ info(__func__);
+
+ if (status != MGMT_STATUS_SUCCESS) {
+ error("%s: Failed to read index list: %s (0x%02x)",
+ __func__, mgmt_errstr(status), status);
+ return;
+ }
+
+ if (length < sizeof(*rp)) {
+ error("%s: Wrong size of read index list response", __func__);
+ return;
+ }
+
+ num = btohs(rp->num_controllers);
+
+ DBG("%s: Number of controllers: %d", __func__, num);
+
+ if (num * sizeof(uint16_t) + sizeof(*rp) != length) {
+ error("%s: Incorrect pkt size for index list rsp", __func__);
+ return;
+ }
+
+ for (i = 0; i < num; i++) {
+ uint16_t index;
+
+ index = btohs(rp->index[i]);
+
+ DBG("%s: Found index %u", __func__, index);
+
+ /**
+ * Use index added event notification.
+ */
+ mgmt_index_added_event(index, 0, NULL, NULL);
+ }
+}
+
+
+static void read_commands_complete(uint8_t status, uint16_t length,
+ const void *param, void *user_data)
+{
+ const struct mgmt_rp_read_commands *rp = param;
+ uint16_t num_commands, num_events;
+
+ info(__func__);
+
+ if (status != MGMT_STATUS_SUCCESS) {
+ error("Failed to read supported commands: %s (0x%02x)",
+ mgmt_errstr(status), status);
+ return;
+ }
+
+ if (length < sizeof(*rp)) {
+ error("Wrong size of read commands response");
+ return;
+ }
+
+ num_commands = btohs(rp->num_commands);
+ num_events = btohs(rp->num_events);
+
+ DBG("Number of commands: %d", num_commands);
+ DBG("Number of events: %d", num_events);
+}
+
+static void read_version_complete(uint8_t status, uint16_t length,
+ const void *param, void *user_data)
+{
+ const struct mgmt_rp_read_version *rp = param;
+
+ info(__func__);
+
+ if (status != MGMT_STATUS_SUCCESS) {
+ error("Failed to read version information: %s (0x%02x)",
+ mgmt_errstr(status), status);
+ return;
+ }
+
+ if (length < sizeof(*rp)) {
+ error("Wrong size response");
+ return;
+ }
+
+ mgmt_version = rp->version;
+ mgmt_revision = btohs(rp->revision);
+
+ info("Bluetooth management interface %u.%u initialized",
+ mgmt_version, mgmt_revision);
+
+ if (mgmt_version < 1) {
+ error("Version 1.0 or later of management interface required");
+ abort();
+ }
+
+ DBG("sending read supported commands command");
+
+ mgmt_send(mgmt_if, MGMT_OP_READ_COMMANDS, MGMT_INDEX_NONE, 0, NULL,
+ read_commands_complete, NULL, NULL);
+
+ mgmt_register(mgmt_if, MGMT_EV_INDEX_ADDED, MGMT_INDEX_NONE,
+ mgmt_index_added_event, NULL, NULL);
+ mgmt_register(mgmt_if, MGMT_EV_INDEX_REMOVED, MGMT_INDEX_NONE,
+ mgmt_index_removed_event, NULL, NULL);
+
+ DBG("sending read index list command");
+
+ if (mgmt_send(mgmt_if, MGMT_OP_READ_INDEX_LIST, MGMT_INDEX_NONE, 0,
+ NULL, read_index_list_complete, NULL, NULL) > 0)
+ return;
+
+ error("Failed to read controller index list");
+}
+
+static bool init_mgmt_interface(void)
+{
+ mgmt_if = mgmt_new_default();
+ if (mgmt_if == NULL) {
+ error("Failed to access management interface");
+ return false;
+ }
+
+ if (mgmt_send(mgmt_if, MGMT_OP_READ_VERSION, MGMT_INDEX_NONE, 0, NULL,
+ read_version_complete, NULL, NULL) == 0) {
+ error("Error sending READ_VERSION mgmt command");
+ return false;
+ }
+
+ return true;
+}
+
+static void cleanup_mgmt_interface(void)
+{
+ mgmt_unref(mgmt_if);
+ mgmt_if = NULL;
+}
+
int main(int argc, char *argv[])
{
GOptionContext *context;
@@ -100,10 +286,13 @@ int main(int argc, char *argv[])
sigaction(SIGINT, &sa, NULL);
sigaction(SIGTERM, &sa, NULL);

+ init_mgmt_interface();
+
DBG("Entering main loop");

g_main_loop_run(event_loop);

+ cleanup_mgmt_interface();
g_main_loop_unref(event_loop);

info("Exit");
--
1.7.10.4


2013-10-08 10:33:57

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCHv2 15/15] android: Add makefile for hcitool

From: Andrei Emeltchenko <[email protected]>

---
android/Android.mk | 38 ++++++++++++++++++++++++++++++++++++++
1 file changed, 38 insertions(+)

diff --git a/android/Android.mk b/android/Android.mk
index 09c4579..5798749 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -157,3 +157,41 @@ LOCAL_MODULE_TAGS := eng
LOCAL_MODULE := hciconfig

include $(BUILD_EXECUTABLE)
+
+#
+# hcitool
+#
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+ ../tools/hcitool.c \
+ ../src/oui.c \
+
+LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH)/../lib \
+ $(LOCAL_PATH)/../src \
+
+LOCAL_C_INCLUDES += \
+ $(call include-path-for, glib) \
+ $(call include-path-for, glib)/glib \
+
+LOCAL_CFLAGS := \
+ -DSTORAGEDIR=\"/tmp\" \
+ -DVERSION=\"$(BLUEZ_VERSION)\"
+
+# to suppress the "pointer of type 'void *' used in arithmetic" warning
+LOCAL_CFLAGS += -Wno-pointer-arith
+
+# to suppress the "warning: missing initializer near initialization.." warning
+LOCAL_CFLAGS += -Wno-missing-field-initializers
+
+LOCAL_SHARED_LIBRARIES := \
+ libbluetooth \
+ libglib \
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
+LOCAL_MODULE_TAGS := eng
+LOCAL_MODULE := hcitool
+
+include $(BUILD_EXECUTABLE)
--
1.7.10.4


2013-10-08 10:33:44

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCHv2 02/15] android: Add Adapter Bluetooth HAL template

From: Andrei Emeltchenko <[email protected]>

Add template for bluetooth.h Android HAL.
---
android/Android.mk | 19 +++
android/hal_bluetooth.c | 348 +++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 367 insertions(+)
create mode 100644 android/hal_bluetooth.c

diff --git a/android/Android.mk b/android/Android.mk
index 5498b41..7adbbcd 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -32,3 +32,22 @@ LOCAL_SHARED_LIBRARIES := \
LOCAL_MODULE := bluetoothd

include $(BUILD_EXECUTABLE)
+
+#
+# bluetooth.default.so HAL
+#
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+ hal_bluetooth.c \
+
+LOCAL_SHARED_LIBRARIES := \
+ libcutils \
+
+LOCAL_MODULE := bluetooth.default
+LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := SHARED_LIBRARIES
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/android/hal_bluetooth.c b/android/hal_bluetooth.c
new file mode 100644
index 0000000..9970374
--- /dev/null
+++ b/android/hal_bluetooth.c
@@ -0,0 +1,348 @@
+/*
+ * Copyright (C) 2013 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 <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdbool.h>
+
+#include <hardware/bluetooth.h>
+
+#define LOG_TAG "BlueZ"
+#include <cutils/log.h>
+
+bt_callbacks_t *bt_hal_cbacks = NULL;
+
+static bool interface_ready(void)
+{
+ return bt_hal_cbacks != NULL;
+}
+
+static int init(bt_callbacks_t *callbacks)
+{
+ ALOGD(__func__);
+
+ if (interface_ready() == true)
+ return BT_STATUS_SUCCESS;
+
+ /* store reference to user callbacks */
+ bt_hal_cbacks = callbacks;
+
+ /* TODO: Init here bluezd task */
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static int enable(void)
+{
+ ALOGD(__func__);
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static int disable(void)
+{
+ ALOGD(__func__);
+
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static void cleanup(void)
+{
+ ALOGD(__func__);
+
+ if (interface_ready() == false)
+ return;
+
+ bt_hal_cbacks = NULL;
+}
+
+static int get_adapter_properties(void)
+{
+ ALOGD(__func__);
+
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static int get_adapter_property(bt_property_type_t type)
+{
+ ALOGD(__func__);
+
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static int set_adapter_property(const bt_property_t *property)
+{
+ ALOGD(__func__);
+
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ if (property == NULL)
+ return BT_STATUS_PARM_INVALID;
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static int get_remote_device_properties(bt_bdaddr_t *remote_addr)
+{
+ ALOGD(__func__);
+
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static int get_remote_device_property(bt_bdaddr_t *remote_addr,
+ bt_property_type_t type)
+{
+ ALOGD(__func__);
+
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static int set_remote_device_property(bt_bdaddr_t *remote_addr,
+ const bt_property_t *property)
+{
+ ALOGD(__func__);
+
+ /* sanity check */
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static int get_remote_service_record(bt_bdaddr_t *remote_addr, bt_uuid_t *uuid)
+{
+ ALOGD(__func__);
+
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static int get_remote_services(bt_bdaddr_t *remote_addr)
+{
+ ALOGD(__func__);
+
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static int start_discovery(void)
+{
+ ALOGD(__func__);
+
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static int cancel_discovery(void)
+{
+ ALOGD(__func__);
+
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static int create_bond(const bt_bdaddr_t *bd_addr)
+{
+ ALOGD(__func__);
+
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ if (bd_addr == NULL)
+ return BT_STATUS_PARM_INVALID;
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static int cancel_bond(const bt_bdaddr_t *bd_addr)
+{
+ ALOGD(__func__);
+
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static int remove_bond(const bt_bdaddr_t *bd_addr)
+{
+ ALOGD(__func__);
+
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static int pin_reply(const bt_bdaddr_t *bd_addr, uint8_t accept,
+ uint8_t pin_len, bt_pin_code_t *pin_code)
+{
+ ALOGD(__func__);
+
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static int ssp_reply(const bt_bdaddr_t *bd_addr, bt_ssp_variant_t variant,
+ uint8_t accept, uint32_t passkey)
+{
+
+ ALOGD(__func__);
+
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ if (bd_addr == NULL)
+ return BT_STATUS_PARM_INVALID;
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static const void *get_profile_interface(const char *profile_id)
+{
+ ALOGD("%s: %s", __func__, profile_id);
+
+ if (interface_ready() == false)
+ return NULL;
+
+ return NULL;
+}
+
+static int dut_mode_configure(uint8_t enable)
+{
+ ALOGD(__func__);
+
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static int dut_mode_send(uint16_t opcode, uint8_t *buf, uint8_t len)
+{
+ ALOGD(__func__);
+
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+/**
+ * HAL Interface declaration
+ */
+static const bt_interface_t bluetooth_if = {
+ sizeof(bt_interface_t),
+ init,
+ enable,
+ disable,
+ cleanup,
+ get_adapter_properties,
+ get_adapter_property,
+ set_adapter_property,
+ get_remote_device_properties,
+ get_remote_device_property,
+ set_remote_device_property,
+ get_remote_service_record,
+ get_remote_services,
+ start_discovery,
+ cancel_discovery,
+ create_bond,
+ remove_bond,
+ cancel_bond,
+ pin_reply,
+ ssp_reply,
+ get_profile_interface,
+ dut_mode_configure,
+ dut_mode_send
+};
+
+static const bt_interface_t *get_bluetooth_interface(void)
+{
+ ALOGD(__func__);
+
+ return &bluetooth_if;
+}
+
+static int close_bluetooth(struct hw_device_t *device)
+{
+ ALOGD(__func__);
+
+ cleanup();
+
+ return 0;
+}
+
+static int open_bluetooth(const struct hw_module_t *module, char const *name,
+ struct hw_device_t **device)
+{
+ bluetooth_device_t *dev = malloc(sizeof(bluetooth_device_t));
+
+ ALOGD(__func__);
+
+ memset(dev, 0, sizeof(bluetooth_device_t));
+ dev->common.tag = HARDWARE_DEVICE_TAG;
+ dev->common.version = 0;
+ dev->common.module = (struct hw_module_t *) module;
+ dev->common.close = close_bluetooth;
+ dev->get_bluetooth_interface = get_bluetooth_interface;
+
+ *device = (struct hw_device_t *) dev;
+
+ return 0;
+}
+
+static struct hw_module_methods_t bluetooth_module_methods = {
+ .open = open_bluetooth,
+};
+
+struct hw_module_t HAL_MODULE_INFO_SYM = {
+ .tag = HARDWARE_MODULE_TAG,
+ .version_major = 1,
+ .version_minor = 0,
+ .id = BT_HARDWARE_MODULE_ID,
+ .name = "BlueZ Bluetooth stack",
+ .author = "Intel Corporation",
+ .methods = &bluetooth_module_methods
+};
--
1.7.10.4


2013-10-08 10:33:53

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCHv2 11/15] android: Add cap to bind to port < 1024

From: Andrei Emeltchenko <[email protected]>

For SDP server we need to bind to lower port, acquire this capability.
---
android/main.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
configure.ac | 4 ++++
2 files changed, 75 insertions(+)

diff --git a/android/main.c b/android/main.c
index 7968ed0..4ef70bd 100644
--- a/android/main.c
+++ b/android/main.c
@@ -32,6 +32,22 @@
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/prctl.h>
+#include <linux/capability.h>
+
+/**
+ * Include <sys/capability.h> for host build and
+ * also for Android 4.3 when it is added to bionic
+ */
+#if !defined(__ANDROID_API__) || (__ANDROID_API__ > 17)
+#include <sys/capability.h>
+#endif
+
+#if defined(__ANDROID_API__)
+#include <private/android_filesystem_config.h>
+#endif

#include <glib.h>

@@ -279,6 +295,58 @@ static void cleanup_mgmt_interface(void)
mgmt_if = NULL;
}

+static bool android_set_aid_and_cap(void)
+{
+ struct __user_cap_header_struct header;
+ struct __user_cap_data_struct cap;
+#if defined(__ANDROID_API__)
+ gid_t groups[] = {AID_NET_BT, AID_NET_BT_ADMIN, AID_NET_ADMIN};
+#endif
+
+ DBG("pid %d uid %d gid %d", getpid(), getuid(), getgid());
+
+ header.version = _LINUX_CAPABILITY_VERSION;
+
+ prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0);
+
+#if defined(__ANDROID_API__)
+ if (setgid(AID_BLUETOOTH) < 0)
+ warn("%s: setgid(): %s", __func__, strerror(errno));
+
+ if (setuid(AID_BLUETOOTH) < 0)
+ warn("%s: setuid(): %s", __func__, strerror(errno));
+#endif
+
+ header.version = _LINUX_CAPABILITY_VERSION;
+ header.pid = 0;
+
+ cap.effective = cap.permitted =
+ CAP_TO_MASK(CAP_SETGID) |
+ CAP_TO_MASK(CAP_NET_RAW) |
+ CAP_TO_MASK(CAP_NET_ADMIN) |
+ CAP_TO_MASK(CAP_NET_BIND_SERVICE);
+ cap.inheritable = 0;
+
+ if (capset(&header, &cap) < 0) {
+ error("%s: capset(): %s", __func__, strerror(errno));
+ return false;
+ }
+
+#if defined(__ANDROID_API__)
+ if (setgroups(sizeof(groups)/sizeof(groups[0]), groups) < 0)
+ warn("%s: setgroups: %s", __func__, strerror(errno));
+#endif
+ if (capget(&header, &cap) < 0)
+ error("%s: capget(): %s", __func__, strerror(errno));
+ else
+ DBG("Caps: eff: 0x%x, perm: 0x%x, inh: 0x%x", cap.effective,
+ cap.permitted, cap.inheritable);
+
+ DBG("pid %d uid %d gid %d", getpid(), getuid(), getgid());
+
+ return true;
+}
+
int main(int argc, char *argv[])
{
GOptionContext *context;
@@ -312,6 +380,9 @@ int main(int argc, char *argv[])
sigaction(SIGINT, &sa, NULL);
sigaction(SIGTERM, &sa, NULL);

+ if (android_set_aid_and_cap() == false)
+ exit(EXIT_FAILURE);
+
init_mgmt_interface();
sdp_start();

diff --git a/configure.ac b/configure.ac
index 7b1f64a..5406434 100644
--- a/configure.ac
+++ b/configure.ac
@@ -247,4 +247,8 @@ AC_ARG_ENABLE(android, AC_HELP_STRING([--enable-android],
[enable_android=${enableval}])
AM_CONDITIONAL(ANDROID, test "${enable_android}" = "yes")

+if (test "${android_daemon}" = "yes"); then
+ AC_CHECK_LIB(cap, capget, dummy=yes, AC_MSG_ERROR(libcap is required))
+fi
+
AC_OUTPUT(Makefile src/bluetoothd.8 lib/bluez.pc)
--
1.7.10.4


2013-10-08 10:33:56

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCHv2 14/15] android: Add makefile for hciconfig

From: Andrei Emeltchenko <[email protected]>

---
android/Android.mk | 34 ++++++++++++++++++++++++++++++++++
1 file changed, 34 insertions(+)

diff --git a/android/Android.mk b/android/Android.mk
index e7a70d0..09c4579 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -123,3 +123,37 @@ $(foreach file,$(lib_headers), $(shell ln -sf ../$(file) $(LOCAL_PATH)/../lib/bl
LOCAL_MODULE := libbluetooth

include $(BUILD_SHARED_LIBRARY)
+
+#
+# hciconfig
+#
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+ ../tools/csr.c \
+ ../tools/csr_h4.c \
+ ../tools/hciconfig.c \
+
+LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH)/../lib \
+ $(LOCAL_PATH)/../src \
+
+LOCAL_C_INCLUDES += \
+ $(call include-path-for, glib) \
+ $(call include-path-for, glib)/glib \
+
+LOCAL_SHARED_LIBRARIES := \
+ libbluetooth
+
+# to suppress the "pointer of type 'void *' used in arithmetic" warning
+LOCAL_CFLAGS := -Wno-pointer-arith
+
+# to suppress the "warning: missing initializer near initialization.." warning
+LOCAL_CFLAGS += -Wno-missing-field-initializers
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
+LOCAL_MODULE_TAGS := eng
+LOCAL_MODULE := hciconfig
+
+include $(BUILD_EXECUTABLE)
--
1.7.10.4


2013-10-08 10:33:51

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCHv2 09/15] android: Add Android Makefile for libbluetooth

From: Andrei Emeltchenko <[email protected]>

Build libbluetooth library for Android.
---
android/Android.mk | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 53 insertions(+)

diff --git a/android/Android.mk b/android/Android.mk
index f5fd863..8f95a66 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -41,6 +41,7 @@ LOCAL_SHARED_LIBRARIES := \
libglib \

LOCAL_MODULE := bluetoothd
+LOCAL_REQUIRED_MODULES := libbluetooth

include $(BUILD_EXECUTABLE)

@@ -63,3 +64,55 @@ LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := SHARED_LIBRARIES

include $(BUILD_SHARED_LIBRARY)
+
+#
+# libbluetooth library
+#
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+ ../lib/bluetooth.c \
+ ../lib/sdp.c \
+ ../lib/hci.c \
+ ../lib/uuid.c \
+
+LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH)/../lib/ \
+ $(LOCAL_PATH)/../src/shared \
+
+LOCAL_C_INCLUDES += \
+ $(call include-path-for, glib) \
+ $(call include-path-for, glib)/glib \
+
+LOCAL_CFLAGS += -O3
+
+# to suppress the "pointer of type 'void *' used in arithmetic" warning
+LOCAL_CFLAGS += -Wno-pointer-arith
+
+# to suppress the "missing initializer near initialization" warning
+LOCAL_CFLAGS += -Wno-missing-field-initializers
+
+# Define missing flags for Android 4.2
+LOCAL_CFLAGS += -DSOCK_CLOEXEC=02000000 -DSOCK_NONBLOCK=04000
+
+lib_headers := \
+ bluetooth.h \
+ hci.h \
+ hci_lib.h \
+ sco.h \
+ l2cap.h \
+ sdp.h \
+ sdp_lib.h \
+ rfcomm.h \
+ bnep.h \
+ cmtp.h \
+ hidp.h \
+
+$(shell mkdir -p $(LOCAL_PATH)/../lib/bluetooth)
+
+$(foreach file,$(lib_headers), $(shell ln -sf ../$(file) $(LOCAL_PATH)/../lib/bluetooth/$(file)))
+
+LOCAL_MODULE := libbluetooth
+
+include $(BUILD_SHARED_LIBRARY)
--
1.7.10.4


2013-10-08 10:33:47

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCHv2 05/15] android: Start Android Bluetooth daemon

From: Andrei Emeltchenko <[email protected]>

Start Android Bluetooth daemon from HAL init(). Make sure
that daemon is in "running" state.
---
android/hal_bluetooth.c | 50 ++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 47 insertions(+), 3 deletions(-)

diff --git a/android/hal_bluetooth.c b/android/hal_bluetooth.c
index 00f3e8d..f1e306f 100644
--- a/android/hal_bluetooth.c
+++ b/android/hal_bluetooth.c
@@ -23,11 +23,16 @@
#include <hardware/bluetooth.h>
#include <hardware/bt_sock.h>

+#include <cutils/sockets.h>
+#include <cutils/properties.h>
+
#define LOG_TAG "BlueZ"
#include <cutils/log.h>

#include "hal.h"

+#define ANDROID_BLUEZ "bluetoothd"
+
bt_callbacks_t *bt_hal_cbacks = NULL;

static bool interface_ready(void)
@@ -35,6 +40,42 @@ static bool interface_ready(void)
return bt_hal_cbacks != NULL;
}

+static bool is_svc_running(void)
+{
+ char val[PROPERTY_VALUE_MAX];
+ int ret;
+
+ ALOGD(__func__);
+
+ if (property_get("init.svc." ANDROID_BLUEZ, val, NULL)) {
+ if (strcmp(val, "running") == 0)
+ return true;
+ }
+
+ return false;
+}
+
+static bool start_bt_daemon(void)
+{
+ int tries = 40; /* wait 4 seconds for completion */
+
+ ALOGD(__func__);
+
+ /* Start Android Bluetooth daemon service */
+ property_set("ctl.start", ANDROID_BLUEZ);
+
+ while (tries-- > 0) {
+ if (is_svc_running() == true) {
+ ALOGI("Android BlueZ daemon started");
+ return true;
+ }
+
+ usleep(100000);
+ }
+
+ return false;
+}
+
static bool is_profile(const char *profile, const char *str)
{
return strcmp(profile, str) == 0;
@@ -47,10 +88,13 @@ static int init(bt_callbacks_t *callbacks)
if (interface_ready() == true)
return BT_STATUS_SUCCESS;

- /* store reference to user callbacks */
- bt_hal_cbacks = callbacks;
+ if (start_bt_daemon() == true) {
+ /* TODO: open channel */

- /* TODO: Init here bluezd task */
+ bt_hal_cbacks = callbacks;
+
+ return BT_STATUS_SUCCESS;
+ }

return BT_STATUS_UNSUPPORTED;
}
--
1.7.10.4


2013-10-08 10:33:46

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCHv2 04/15] android: Enable Socket interface

From: Andrei Emeltchenko <[email protected]>

Returns socket interface, use header hal.h to avoid externs.
---
android/hal.h | 18 ++++++++++++++++++
android/hal_bluetooth.c | 11 +++++++++++
2 files changed, 29 insertions(+)
create mode 100644 android/hal.h

diff --git a/android/hal.h b/android/hal.h
new file mode 100644
index 0000000..40fbf03
--- /dev/null
+++ b/android/hal.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2013 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.
+ *
+ */
+
+btsock_interface_t *bt_get_sock_interface(void);
diff --git a/android/hal_bluetooth.c b/android/hal_bluetooth.c
index 9970374..00f3e8d 100644
--- a/android/hal_bluetooth.c
+++ b/android/hal_bluetooth.c
@@ -21,10 +21,13 @@
#include <stdbool.h>

#include <hardware/bluetooth.h>
+#include <hardware/bt_sock.h>

#define LOG_TAG "BlueZ"
#include <cutils/log.h>

+#include "hal.h"
+
bt_callbacks_t *bt_hal_cbacks = NULL;

static bool interface_ready(void)
@@ -32,6 +35,11 @@ static bool interface_ready(void)
return bt_hal_cbacks != NULL;
}

+static bool is_profile(const char *profile, const char *str)
+{
+ return strcmp(profile, str) == 0;
+}
+
static int init(bt_callbacks_t *callbacks)
{
ALOGD(__func__);
@@ -246,6 +254,9 @@ static const void *get_profile_interface(const char *profile_id)
if (interface_ready() == false)
return NULL;

+ if (is_profile(profile_id, BT_PROFILE_SOCKETS_ID))
+ return bt_get_sock_interface();
+
return NULL;
}

--
1.7.10.4


2013-10-07 12:26:25

by Andrei Emeltchenko

[permalink] [raw]
Subject: Re: [PATCHv1 12/15] android: Implement read_info_complete callback

On Mon, Oct 07, 2013 at 10:38:13AM +0300, Andrei Emeltchenko wrote:
> From: Andrei Emeltchenko <[email protected]>
>
> Handle read info complete callback from mgmt interface.
> ---
> android/main.c | 102 +++++++++++++++++++++++++++++++++++++++++++++++++-------
> 1 file changed, 90 insertions(+), 12 deletions(-)
>
> diff --git a/android/main.c b/android/main.c
> index dab54ce..3a63eb9 100644
> --- a/android/main.c
> +++ b/android/main.c
> @@ -54,6 +54,7 @@
> #include "log.h"
> #include "hcid.h"
> #include "sdpd.h"
> +#include "bt_adapter.h"
>
> #include "lib/bluetooth.h"
> #include "lib/mgmt.h"
> @@ -69,6 +70,8 @@ static struct mgmt *mgmt_if = NULL;
> static uint8_t mgmt_version = 0;
> static uint8_t mgmt_revision = 0;
>
> +struct bt_adapter *default_adapter = NULL;
> +
> static int sdp_start(void)
> {
> DBG("");
> @@ -118,34 +121,109 @@ static GOptionEntry options[] = {
> { NULL }
> };
>
> -static void read_info_complete(uint8_t status, uint16_t length,
> +static void load_link_keys_complete(uint8_t status, uint16_t length,
> const void *param, void *user_data)
> {
> - /* TODO: Store Controller information */
> -
> - /**
> - * Register all event notification handlers for controller.
> - *
> - * The handlers are registered after a succcesful read of the
> - * controller info. From now on they can track updates and
> - * notifications.
> - */
> + DBG("status %u", status);
> }
>
> +static void load_link_keys(struct bt_adapter *adapter, GSList *keys)
> +{
> + struct mgmt_cp_load_link_keys *cp;
> + uint16_t key_len = g_slist_length(keys);
> + struct mgmt_link_key_info *key;
> + uint16_t len;
> +
> + DBG("");
> +
> + len = sizeof(*cp) + key_len * sizeof(*key);
> + cp = malloc(len);
> + if (cp == NULL) {
> + error("%s: Not enough memory for link keys loading", __func__);
> + return;
> + }
> +
> + cp->debug_keys = 0;
> + cp->key_count = htobs(key_len);
> +
> + mgmt_send(adapter->mgmt, MGMT_OP_LOAD_LINK_KEYS, adapter->dev_id, len,
> + cp, load_link_keys_complete, adapter, NULL);
> +
> + free(cp);
> +}
> +
> +static void read_info_complete(uint8_t status, uint16_t length,
> + const void *param, void *user_data)
> +{
> + const struct mgmt_rp_read_info *rp = param;
> +
> + DBG("");
> +
> + if (status != MGMT_STATUS_SUCCESS) {
> + error("Failed to read info for index %u: %s (0x%02x)",
> + default_adapter->dev_id, mgmt_errstr(status), status);
> + goto failed;
> + }
> +
> + if (length < sizeof(*rp)) {
> + error("Too small read info complete response");
> + goto failed;
> + }
> +
> + if (bacmp(&rp->bdaddr, BDADDR_ANY) == 0) {
> + error("No Bluetooth address for index %u",
> + default_adapter->dev_id);
> + goto failed;
> + }
> +
> + /* Store adapter information */
> + bacpy(&default_adapter->bdaddr, &rp->bdaddr);
> + default_adapter->dev_class = rp->dev_class[0] |
> + (rp->dev_class[1] << 8) |
> + (rp->dev_class[2] << 16);
> + default_adapter->name = g_strdup((const char *) rp->name);
> + default_adapter->short_name = g_strdup((const char *) rp->short_name);
> +
> + default_adapter->supported_settings = btohs(rp->supported_settings);
> + default_adapter->current_settings = btohs(rp->current_settings);
> +
> + /* TODO: Register all event notification handlers */
> +
> + if (default_adapter->current_settings & MGMT_SETTING_POWERED)
> + adapter_start(default_adapter);
> +
> + /* dummy link keys loading */
> + load_link_keys(default_adapter, NULL);
> +
> + return;
> +
> +failed:
> + default_adapter = NULL;
> +}
>
> static void mgmt_index_added_event(uint16_t index, uint16_t length,
> const void *param, void *user_data)
> {
> info("%s: index %u", __func__, index);
>
> + if (default_adapter == NULL) {

sorry, this should be != NULL

I will send updated version soon.

Best regards
Andrei Emeltchenko


2013-10-07 12:14:09

by Szymon Janc

[permalink] [raw]
Subject: Re: [PATCHv1 11/15] android: Add cap to bind to port < 1024

Hi Andrei,

> From: Andrei Emeltchenko <[email protected]>
>
> For SDP server we need to bind to lower port, acquire this capability.
> ---
> android/main.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> configure.ac | 4 ++++
> 2 files changed, 76 insertions(+)
>
> diff --git a/android/main.c b/android/main.c
> index 7968ed0..dab54ce 100644
> --- a/android/main.c
> +++ b/android/main.c
> @@ -32,6 +32,22 @@
> #include <stdlib.h>
> #include <stdbool.h>
> #include <string.h>
> +#include <unistd.h>
> +#include <errno.h>
> +#include <sys/prctl.h>
> +#include <linux/capability.h>
> +
> +/**
> + * Include <sys/capability.h> for host build and
> + * also for Android 4.3 when it is added to bionic
> + */
> +#if !defined(__ANDROID_API__) || (__ANDROID_API__ > 17)
> +#include <sys/capability.h>
> +#endif
> +
> +#if defined(__ANDROID_API__)
> +#include <private/android_filesystem_config.h>
> +#endif
>
> #include <glib.h>
>
> @@ -279,6 +295,59 @@ static void cleanup_mgmt_interface(void)
> mgmt_if = NULL;
> }
>
> +static bool android_set_aid_and_cap()

Missing void in ().

> +{
> + struct __user_cap_header_struct header;
> + struct __user_cap_data_struct cap;
> +#if defined(__ANDROID_API__)
> + gid_t groups[] = {AID_NET_BT, AID_NET_BT_ADMIN, AID_BLUETOOTH,
> + AID_NET_ADMIN};
> +#endif
> +
> + DBG("pid %d uid %d gid %d", getpid(), getuid(), getgid());
> +
> + header.version = _LINUX_CAPABILITY_VERSION;
> +
> + prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0);
> +
> +#if defined(__ANDROID_API__)
> + if (setgid(AID_BLUETOOTH) < 0)
> + warn("%s: setgid(): %s", __func__, strerror(errno));
> +
> + if (setuid(AID_BLUETOOTH) < 0)
> + warn("%s: setuid(): %s", __func__, strerror(errno));
> +#endif
> +
> + header.version = _LINUX_CAPABILITY_VERSION;
> + header.pid = 0;
> +
> + cap.effective = cap.permitted =
> + CAP_TO_MASK(CAP_SETGID) |
> + CAP_TO_MASK(CAP_NET_RAW) |
> + CAP_TO_MASK(CAP_NET_ADMIN) |
> + CAP_TO_MASK(CAP_NET_BIND_SERVICE);
> + cap.inheritable = 0;
> +
> + if (capset(&header, &cap) < 0) {
> + error("%s: capset(): %s", __func__, strerror(errno));
> + return false;
> + }
> +
> +#if defined(__ANDROID_API__)
> + if (setgroups(sizeof(groups)/sizeof(groups[0]), groups) < 0)
> + warn("%s: setgroups: %s", __func__, strerror(errno));
> +#endif
> + if (capget(&header, &cap) < 0)
> + error("%s: capget(): %s", __func__, strerror(errno));
> + else
> + DBG("Caps: eff: 0x%x, perm: 0x%x, inh: 0x%x", cap.effective,
> + cap.permitted, cap.inheritable);
> +
> + DBG("pid %d uid %d gid %d", getpid(), getuid(), getgid());
> +
> + return true;
> +}
> +
> int main(int argc, char *argv[])
> {
> GOptionContext *context;
> @@ -312,6 +381,9 @@ int main(int argc, char *argv[])
> sigaction(SIGINT, &sa, NULL);
> sigaction(SIGTERM, &sa, NULL);
>
> + if (android_set_aid_and_cap() == false)
> + exit(EXIT_FAILURE);
> +
> init_mgmt_interface();
> sdp_start();
>
> diff --git a/configure.ac b/configure.ac
> index 7b1f64a..5406434 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -247,4 +247,8 @@ AC_ARG_ENABLE(android, AC_HELP_STRING([--enable-android],
> [enable_android=${enableval}])
> AM_CONDITIONAL(ANDROID, test "${enable_android}" = "yes")
>
> +if (test "${android_daemon}" = "yes"); then
> + AC_CHECK_LIB(cap, capget, dummy=yes, AC_MSG_ERROR(libcap is required))
> +fi
> +
> AC_OUTPUT(Makefile src/bluetoothd.8 lib/bluez.pc)
>

--
BR
Szymon Janc


2013-10-07 12:09:07

by Szymon Janc

[permalink] [raw]
Subject: Re: [PATCHv1 05/15] android: Start Android Bluetooth daemon

Hi Andrei,

On Monday 07 of October 2013 10:38:06 Andrei Emeltchenko wrote:
> From: Andrei Emeltchenko <[email protected]>
>
> Start Android Bluetooth daemon from HAL init(). Make sure
> that daemon is in "running" state.
> ---
> android/hal_bluetooth.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 53 insertions(+), 1 deletion(-)
>
> diff --git a/android/hal_bluetooth.c b/android/hal_bluetooth.c
> index 00f3e8d..f8139a7 100644
> --- a/android/hal_bluetooth.c
> +++ b/android/hal_bluetooth.c
> @@ -23,11 +23,16 @@
> #include <hardware/bluetooth.h>
> #include <hardware/bt_sock.h>
>
> +#include <cutils/sockets.h>
> +#include <cutils/properties.h>
> +
> #define LOG_TAG "BlueZ"
> #include <cutils/log.h>
>
> #include "hal.h"
>
> +#define ANDROID_BLUEZ "btd"

Shouldn't this be 'bluetoothd'?
Service name can be different than binary but I think we should keep it same
to avoid confusion.

> +
> bt_callbacks_t *bt_hal_cbacks = NULL;
>
> static bool interface_ready(void)
> @@ -35,6 +40,49 @@ static bool interface_ready(void)
> return bt_hal_cbacks != NULL;
> }
>
> +static bool is_running(const char *service_name)
> +{
> + char val[PROPERTY_VALUE_MAX];
> + char name[PROPERTY_KEY_MAX];
> + int ret;
> +
> + ALOGI(__func__);
> +
> + ret = snprintf(name, sizeof(name), "init.svc.%s", service_name);
> + if (ret > PROPERTY_KEY_MAX - 1) {
> + ALOGD("Service name '%s' is too long", service_name);
> + return false;
> + }
> +
> + if (property_get(name, val, NULL)) {

Maybe pass "init.svc."ANDROID_BLUEZ directly to property_get()?

> + if (strcmp(val, "running") == 0)
> + return true;
> + }
> +
> + return false;
> +}
> +
> +static bool start_bt_daemon(void)
> +{
> + int tries = 40; /* wait 4 seconds for completion */
> +
> + ALOGI(__func__);
> +
> + /* Start Android Bluetooth daemon service */
> + property_set("ctl.start", ANDROID_BLUEZ);
> +
> + while (tries-- > 0) {
> + if (is_running(ANDROID_BLUEZ) == true) {
> + ALOGI("Android BlueZ daemon started");
> + return true;
> + }
> +
> + usleep(100000);
> + }
> +
> + return false;
> +}
> +
> static bool is_profile(const char *profile, const char *str)
> {
> return strcmp(profile, str) == 0;
> @@ -50,7 +98,11 @@ static int init(bt_callbacks_t *callbacks)
> /* store reference to user callbacks */
> bt_hal_cbacks = callbacks;
>
> - /* TODO: Init here bluezd task */
> + if (start_bt_daemon() == true) {
> + /* TODO: open channel */
> +
> + return BT_STATUS_SUCCESS;
> + }

bt_hal_cbacks should be set back to NULL here.

>
> return BT_STATUS_UNSUPPORTED;
> }
>

--
BR
Szymon Janc


2013-10-07 07:38:15

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCHv1 14/15] android: Add makefile for hciconfig

From: Andrei Emeltchenko <[email protected]>

---
android/Android.mk | 34 ++++++++++++++++++++++++++++++++++
1 file changed, 34 insertions(+)

diff --git a/android/Android.mk b/android/Android.mk
index e7a70d0..09c4579 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -123,3 +123,37 @@ $(foreach file,$(lib_headers), $(shell ln -sf ../$(file) $(LOCAL_PATH)/../lib/bl
LOCAL_MODULE := libbluetooth

include $(BUILD_SHARED_LIBRARY)
+
+#
+# hciconfig
+#
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+ ../tools/csr.c \
+ ../tools/csr_h4.c \
+ ../tools/hciconfig.c \
+
+LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH)/../lib \
+ $(LOCAL_PATH)/../src \
+
+LOCAL_C_INCLUDES += \
+ $(call include-path-for, glib) \
+ $(call include-path-for, glib)/glib \
+
+LOCAL_SHARED_LIBRARIES := \
+ libbluetooth
+
+# to suppress the "pointer of type 'void *' used in arithmetic" warning
+LOCAL_CFLAGS := -Wno-pointer-arith
+
+# to suppress the "warning: missing initializer near initialization.." warning
+LOCAL_CFLAGS += -Wno-missing-field-initializers
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
+LOCAL_MODULE_TAGS := eng
+LOCAL_MODULE := hciconfig
+
+include $(BUILD_EXECUTABLE)
--
1.7.10.4


2013-10-07 07:38:08

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCHv1 07/15] android: Create HAL API header skeleton

From: Andrei Emeltchenko <[email protected]>

Header describes the protocol between Android HAL threads and BlueZ
daemon.
---
android/hal_msg.h | 255 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 255 insertions(+)
create mode 100644 android/hal_msg.h

diff --git a/android/hal_msg.h b/android/hal_msg.h
new file mode 100644
index 0000000..c6bc883
--- /dev/null
+++ b/android/hal_msg.h
@@ -0,0 +1,255 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2013 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
+ *
+ */
+
+#ifndef __packed
+#define __packed __attribute__((packed))
+#endif
+
+typedef struct {
+ uint8_t b[6];
+} __packed __bdaddr_t;
+
+struct hal_msg_hdr {
+ uint8_t service_id;
+ uint8_t opcode;
+ uint16_t len;
+ uint8_t payload[0];
+} __packed;
+
+#define HAL_SERVICE_ID_CORE 0
+#define HAL_SERVICE_ID_BLUETOOTH 1
+#define HAL_SERVICE_ID_SOCK 2
+#define HAL_SERVICE_ID_HIDHOST 3
+#define HAL_SERVICE_ID_PAN 4
+#define HAL_SERVICE_ID_HANDSFREE 5
+#define HAL_SERVICE_ID_AD2P 6
+#define HAL_SERVICE_ID_HEALTH 7
+#define HAL_SERVICE_ID_AVRCP 8
+#define HAL_SERVICE_ID_GATT 9
+
+/* Core Service */
+
+#define HAL_MSG_OP_ERROR 0x00
+struct hal_msg_rp_error {
+ uint8_t status;
+} __packed;
+
+#define HAL_MSG_OP_REGISTER_MODULE 0x01
+struct hal_msg_cp_register_module {
+ uint8_t service_id;
+} __packed;
+struct hal_msg_rp_register_module {
+ uint8_t service_id;
+} __packed;
+
+#define HAL_MSG_OP_UNREGISTER_MODULE 0x02
+struct hal_msg_cp_unregister_module {
+ uint8_t service_id;
+} __packed;
+
+/* Bluetooth Core HAL API */
+
+#define HAL_MSG_OP_BT_ENABLE 0x01
+
+#define HAL_MSG_OP_BT_DISABLE 0x02
+
+#define HAL_MSG_OP_BT_GET_ADAPTER_PROPS 0x03
+
+#define HAL_MSG_OP_BT_GET_ADAPTER_PROP 0x04
+struct hal_msg_cp_bt_get_adapter_prop {
+ uint8_t type;
+} __packed;
+
+#define HAL_MSG_OP_BT_SET_ADAPTER_PROP 0x05
+struct hal_msg_cp_bt_set_adapter_prop {
+ uint8_t type;
+ uint16_t len;
+ uint8_t val[0];
+} __packed;
+
+#define HAL_MSG_OP_BT_GET_REMOTE_DEVICE_PROPS 0x06
+struct hal_msg_cp_bt_get_remote_device_props {
+ __bdaddr_t bdaddr;
+} __packed;
+
+#define HAL_MSG_OP_BT_GET_REMOTE_DEVICE_PROP 0x07
+struct hal_msg_cp_bt_get_remote_device_prop {
+ __bdaddr_t bdaddr;
+ uint8_t type;
+} __packed;
+
+#define HAL_MSG_OP_BT_SET_REMOTE_DEVICE_PROP 0x08
+struct hal_msg_cp_bt_set_remote_device_prop {
+ __bdaddr_t bdaddr;
+ uint8_t type;
+ uint16_t len;
+ uint8_t val[0];
+} __packed;
+
+#define HAL_MSG_OP_BT_GET_REMOTE_SERVICE_REC 0x09
+struct hal_msg_cp_bt_get_remote_service_rec {
+ __bdaddr_t bdaddr;
+ uint8_t uuid[16];
+} __packed;
+
+#define HAL_MSG_OP_BT_GET_REMOTE_SERVICE 0x0a
+struct hal_msg_cp_bt_get_remote_service {
+ __bdaddr_t bdaddr;
+} __packed;
+
+#define HAL_MSG_OP_BT_START_DISCOVERY 0x0b
+
+#define HAL_MSG_OP_BT_CANCEL_DISCOVERY 0x0c
+
+#define HAL_MSG_OP_BT_CREATE_BOND 0x0d
+struct hal_msg_cp_bt_create_bond {
+ __bdaddr_t bdaddr;
+} __packed;
+
+#define HAL_MSG_OP_BT_REMOVE_BOND 0x0d
+struct hal_msg_cp_bt_remove_bond {
+ __bdaddr_t bdaddr;
+} __packed;
+
+#define HAL_MSG_OP_BT_CANCEL_BOND 0x0f
+struct hal_msg_cp_bt_cancel_bond {
+ __bdaddr_t bdaddr;
+} __packed;
+
+#define HAL_MSG_OP_BT_PIN_REPLY 0x10
+struct hal_msg_cp_bt_pin_reply {
+ __bdaddr_t bdaddr;
+ uint8_t accept;
+ uint8_t pin_len;
+ uint8_t pin_code[16];
+} __packed;
+
+#define HAL_MSG_OP_BT_SSP_REPLY 0x11
+struct hal_msg_cp_bt_ssp_reply {
+ __bdaddr_t bdaddr;
+ uint8_t ssp_variant;
+ uint8_t accept;
+ uint32_t passkey;
+} __packed;
+
+#define HAL_MSG_OP_BT_DUT_MODE_CONF 0x12
+struct hal_msg_cp_bt_dut_mode_conf {
+ uint8_t enable;
+} __packed;
+
+#define HAL_MSG_OP_BT_DUT_MODE_SEND 0x13
+struct hal_msg_cp_bt_dut_mode_send {
+ uint16_t opcode;
+ uint8_t len;
+ uint8_t data[0];
+} __packed;
+
+#define HAL_MSG_OP_BT_LE_TEST_MODE 0x14
+struct hal_msg_cp_bt_le_test_mode {
+ uint16_t opcode;
+ uint8_t len;
+ uint8_t data[0];
+} __packed;
+
+/* Notifications and confirmations */
+
+#define HAL_MSG_EV_BT_ERROR 0x80
+
+#define HAL_MSG_EV_BT_ADAPTER_STATE_CHANGED 0x81
+struct hal_msg_ev_bt_adapter_state_changed {
+ uint8_t state;
+} __packed;
+
+#define HAL_MSG_EV_BT_ADAPTER_PROPS_CHANGED 0x82
+struct hal_property {
+ uint8_t type;
+ uint16_t len;
+ uint8_t val[0];
+} __packed;
+struct hal_msg_ev_bt_adapter_props_changed {
+ uint8_t status;
+ uint8_t num_props;
+ struct hal_property props[0];
+} __packed;
+
+#define HAL_MSG_EV_BT_REMOTE_DEVICE_PROPS 0x83
+struct hal_msg_ev_bt_remote_device_props {
+ uint8_t status;
+ __bdaddr_t bdaddr;
+ uint8_t num_props;
+ struct hal_property props[0];
+} __packed;
+
+#define HAL_MSG_EV_BT_DEVICE_FOUND 0x84
+struct hal_msg_ev_bt_device_found {
+ uint8_t num_props;
+ struct hal_property props[0];
+} __packed;
+
+#define HAL_MSG_EV_BT_DISCOVERY_STATE_CHANGED 0x85
+struct hal_msg_ev_bt_discovery_state_changed {
+ uint8_t state;
+} __packed;
+
+#define HAL_MSG_EV_BT_PIN_REQUEST 0x86
+struct hal_msg_ev_bt_pin_request {
+ __bdaddr_t bdaddr;
+ uint8_t name[249 - 1];
+ uint8_t class_of_dev[3];
+} __packed;
+
+#define HAL_MSG_EV_BT_SSP_REQUEST 0x87
+struct hal_msg_ev_bt_ssp_request {
+ __bdaddr_t bdaddr;
+ uint8_t name[249 - 1];
+ uint8_t class_of_dev[3];
+ uint8_t pairing_variant;
+ uint32_t passkey;
+} __packed;
+
+#define HAL_MSG_EV_BT_BOND_STATE_CHANGED 0x88
+struct hal_msg_ev_bt_bond_state_changed {
+ uint8_t status;
+ __bdaddr_t bdaddr;
+ uint8_t state;
+} __packed;
+
+#define HAL_MSG_EV_BT_ACL_STATE_CHANGED 0x89
+struct hal_msg_ev_bt_acl_state_changed {
+ uint8_t status;
+ __bdaddr_t bdaddr;
+ uint8_t state;
+} __packed;
+
+#define HAL_MSG_EV_BT_DUT_MODE_RECEIVE 0x8a
+struct hal_msg_ev_bt_dut_mode_receive {
+ uint16_t opcode;
+ uint8_t len;
+ uint8_t data[0];
+} __packed;
+
+#define HAL_MSG_EV_BT_LE_TEST_MODE 0x8b
+struct hal_msg_ev_bt_le_test_mode {
+ uint8_t status;
+ uint16_t num_packets;
+} __packed;
--
1.7.10.4


2013-10-07 07:38:03

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCHv1 02/15] android: Add Adapter Bluetooth HAL template

From: Andrei Emeltchenko <[email protected]>

Add template for bluetooth.h Android HAL.
---
android/Android.mk | 19 +++
android/hal_bluetooth.c | 348 +++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 367 insertions(+)
create mode 100644 android/hal_bluetooth.c

diff --git a/android/Android.mk b/android/Android.mk
index 5498b41..7adbbcd 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -32,3 +32,22 @@ LOCAL_SHARED_LIBRARIES := \
LOCAL_MODULE := bluetoothd

include $(BUILD_EXECUTABLE)
+
+#
+# bluetooth.default.so HAL
+#
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+ hal_bluetooth.c \
+
+LOCAL_SHARED_LIBRARIES := \
+ libcutils \
+
+LOCAL_MODULE := bluetooth.default
+LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := SHARED_LIBRARIES
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/android/hal_bluetooth.c b/android/hal_bluetooth.c
new file mode 100644
index 0000000..9970374
--- /dev/null
+++ b/android/hal_bluetooth.c
@@ -0,0 +1,348 @@
+/*
+ * Copyright (C) 2013 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 <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdbool.h>
+
+#include <hardware/bluetooth.h>
+
+#define LOG_TAG "BlueZ"
+#include <cutils/log.h>
+
+bt_callbacks_t *bt_hal_cbacks = NULL;
+
+static bool interface_ready(void)
+{
+ return bt_hal_cbacks != NULL;
+}
+
+static int init(bt_callbacks_t *callbacks)
+{
+ ALOGD(__func__);
+
+ if (interface_ready() == true)
+ return BT_STATUS_SUCCESS;
+
+ /* store reference to user callbacks */
+ bt_hal_cbacks = callbacks;
+
+ /* TODO: Init here bluezd task */
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static int enable(void)
+{
+ ALOGD(__func__);
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static int disable(void)
+{
+ ALOGD(__func__);
+
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static void cleanup(void)
+{
+ ALOGD(__func__);
+
+ if (interface_ready() == false)
+ return;
+
+ bt_hal_cbacks = NULL;
+}
+
+static int get_adapter_properties(void)
+{
+ ALOGD(__func__);
+
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static int get_adapter_property(bt_property_type_t type)
+{
+ ALOGD(__func__);
+
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static int set_adapter_property(const bt_property_t *property)
+{
+ ALOGD(__func__);
+
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ if (property == NULL)
+ return BT_STATUS_PARM_INVALID;
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static int get_remote_device_properties(bt_bdaddr_t *remote_addr)
+{
+ ALOGD(__func__);
+
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static int get_remote_device_property(bt_bdaddr_t *remote_addr,
+ bt_property_type_t type)
+{
+ ALOGD(__func__);
+
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static int set_remote_device_property(bt_bdaddr_t *remote_addr,
+ const bt_property_t *property)
+{
+ ALOGD(__func__);
+
+ /* sanity check */
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static int get_remote_service_record(bt_bdaddr_t *remote_addr, bt_uuid_t *uuid)
+{
+ ALOGD(__func__);
+
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static int get_remote_services(bt_bdaddr_t *remote_addr)
+{
+ ALOGD(__func__);
+
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static int start_discovery(void)
+{
+ ALOGD(__func__);
+
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static int cancel_discovery(void)
+{
+ ALOGD(__func__);
+
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static int create_bond(const bt_bdaddr_t *bd_addr)
+{
+ ALOGD(__func__);
+
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ if (bd_addr == NULL)
+ return BT_STATUS_PARM_INVALID;
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static int cancel_bond(const bt_bdaddr_t *bd_addr)
+{
+ ALOGD(__func__);
+
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static int remove_bond(const bt_bdaddr_t *bd_addr)
+{
+ ALOGD(__func__);
+
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static int pin_reply(const bt_bdaddr_t *bd_addr, uint8_t accept,
+ uint8_t pin_len, bt_pin_code_t *pin_code)
+{
+ ALOGD(__func__);
+
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static int ssp_reply(const bt_bdaddr_t *bd_addr, bt_ssp_variant_t variant,
+ uint8_t accept, uint32_t passkey)
+{
+
+ ALOGD(__func__);
+
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ if (bd_addr == NULL)
+ return BT_STATUS_PARM_INVALID;
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static const void *get_profile_interface(const char *profile_id)
+{
+ ALOGD("%s: %s", __func__, profile_id);
+
+ if (interface_ready() == false)
+ return NULL;
+
+ return NULL;
+}
+
+static int dut_mode_configure(uint8_t enable)
+{
+ ALOGD(__func__);
+
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static int dut_mode_send(uint16_t opcode, uint8_t *buf, uint8_t len)
+{
+ ALOGD(__func__);
+
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+/**
+ * HAL Interface declaration
+ */
+static const bt_interface_t bluetooth_if = {
+ sizeof(bt_interface_t),
+ init,
+ enable,
+ disable,
+ cleanup,
+ get_adapter_properties,
+ get_adapter_property,
+ set_adapter_property,
+ get_remote_device_properties,
+ get_remote_device_property,
+ set_remote_device_property,
+ get_remote_service_record,
+ get_remote_services,
+ start_discovery,
+ cancel_discovery,
+ create_bond,
+ remove_bond,
+ cancel_bond,
+ pin_reply,
+ ssp_reply,
+ get_profile_interface,
+ dut_mode_configure,
+ dut_mode_send
+};
+
+static const bt_interface_t *get_bluetooth_interface(void)
+{
+ ALOGD(__func__);
+
+ return &bluetooth_if;
+}
+
+static int close_bluetooth(struct hw_device_t *device)
+{
+ ALOGD(__func__);
+
+ cleanup();
+
+ return 0;
+}
+
+static int open_bluetooth(const struct hw_module_t *module, char const *name,
+ struct hw_device_t **device)
+{
+ bluetooth_device_t *dev = malloc(sizeof(bluetooth_device_t));
+
+ ALOGD(__func__);
+
+ memset(dev, 0, sizeof(bluetooth_device_t));
+ dev->common.tag = HARDWARE_DEVICE_TAG;
+ dev->common.version = 0;
+ dev->common.module = (struct hw_module_t *) module;
+ dev->common.close = close_bluetooth;
+ dev->get_bluetooth_interface = get_bluetooth_interface;
+
+ *device = (struct hw_device_t *) dev;
+
+ return 0;
+}
+
+static struct hw_module_methods_t bluetooth_module_methods = {
+ .open = open_bluetooth,
+};
+
+struct hw_module_t HAL_MODULE_INFO_SYM = {
+ .tag = HARDWARE_MODULE_TAG,
+ .version_major = 1,
+ .version_minor = 0,
+ .id = BT_HARDWARE_MODULE_ID,
+ .name = "BlueZ Bluetooth stack",
+ .author = "Intel Corporation",
+ .methods = &bluetooth_module_methods
+};
--
1.7.10.4


2013-10-07 07:38:14

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCHv1 13/15] android: Handle mgmt changed events

From: Andrei Emeltchenko <[email protected]>

Add code handling changing adapter settings.
---
android/main.c | 154 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 154 insertions(+)

diff --git a/android/main.c b/android/main.c
index 3a63eb9..2cc4efc 100644
--- a/android/main.c
+++ b/android/main.c
@@ -127,6 +127,159 @@ static void load_link_keys_complete(uint8_t status, uint16_t length,
DBG("status %u", status);
}

+static void mgmt_local_name_changed_event(uint16_t index, uint16_t length,
+ const void *param, void *user_data)
+{
+ struct bt_adapter *adapter = user_data;
+ const struct mgmt_cp_set_local_name *rp = param;
+
+ if (length < sizeof(*rp)) {
+ error("Wrong size of local name changed parameters");
+ return;
+ }
+
+ if (adapter != default_adapter) {
+ error("Wrong adapter %p", adapter);
+ return;
+ }
+
+ if (!g_strcmp0(adapter->short_name, (const char *) rp->short_name) &&
+ !g_strcmp0(adapter->name, (const char *) rp->name))
+ return;
+
+ DBG("name: %s short name: %s", rp->name, rp->short_name);
+
+ g_free(adapter->name);
+ adapter->name = g_strdup((const char *) rp->name);
+
+ g_free(adapter->short_name);
+ adapter->short_name = g_strdup((const char *) rp->short_name);
+
+ /* TODO Update services if needed */
+}
+
+static void settings_changed_connectable(struct bt_adapter *adapter)
+{
+ /* TODO */
+}
+
+static void settings_changed_discoverable(struct bt_adapter *adapter)
+{
+ /* TODO */
+}
+
+static void settings_changed(struct bt_adapter *adapter, uint32_t settings)
+{
+ uint32_t changed_mask;
+
+ changed_mask = adapter->current_settings ^ settings;
+
+ adapter->current_settings = settings;
+
+ DBG("0x%08x", changed_mask);
+
+ if (changed_mask & MGMT_SETTING_POWERED) {
+ info("Powered");
+
+ if (adapter->current_settings & MGMT_SETTING_POWERED)
+ adapter_start(adapter);
+ else
+ adapter_stop(adapter);
+ }
+
+ /* Seems not needed for Android */
+ if (changed_mask & MGMT_SETTING_PAIRABLE)
+ DBG("Pairable");
+
+ /*
+ * There are only 2 scan modes:
+ * CONNECTABLE and CONNECTABLE_DISCOVERABLE
+ */
+ if (changed_mask & MGMT_SETTING_CONNECTABLE) {
+ DBG("Connectable");
+
+ settings_changed_connectable(adapter);
+ }
+
+ if (changed_mask & MGMT_SETTING_DISCOVERABLE) {
+ DBG("Discoverable");
+
+ settings_changed_discoverable(adapter);
+ }
+}
+
+static void new_settings_callback(uint16_t index, uint16_t length,
+ const void *param, void *user_data)
+{
+ struct bt_adapter *adapter = user_data;
+ uint32_t settings;
+
+ if (length < sizeof(settings)) {
+ error("Wrong size of new settings parameters");
+ return;
+ }
+
+ if (adapter != default_adapter) {
+ error("Wrong adapter %p", adapter);
+ return;
+ }
+
+ settings = bt_get_le32(param);
+
+ DBG("settings: 0x%8.8x -> 0x%8.8x", adapter->current_settings,
+ settings);
+
+ if (settings == adapter->current_settings)
+ return;
+
+ settings_changed(adapter, settings);
+}
+
+static void mgmt_dev_class_changed_event(uint16_t index, uint16_t length,
+ const void *param, void *user_data)
+{
+ struct bt_adapter *adapter = user_data;
+ const struct mgmt_cod *rp = param;
+ uint32_t dev_class;
+
+ if (length < sizeof(*rp)) {
+ error("Wrong size of class of device changed parameters");
+ return;
+ }
+
+ if (adapter != default_adapter) {
+ error("Wrong adapter %p", adapter);
+ return;
+ }
+
+ dev_class = rp->val[0] | (rp->val[1] << 8) | (rp->val[2] << 16);
+
+ if (dev_class == adapter->dev_class)
+ return;
+
+ DBG("Class: 0x%06x", dev_class);
+
+ adapter->dev_class = dev_class;
+
+ /* TODO: Inform prop change: Class */
+
+ /* TODO: Gatt attrib set*/
+}
+
+static void register_mgmt_handlers(struct bt_adapter *adapter)
+{
+ mgmt_register(adapter->mgmt, MGMT_EV_NEW_SETTINGS, adapter->dev_id,
+ new_settings_callback, adapter, NULL);
+
+ mgmt_register(adapter->mgmt, MGMT_EV_CLASS_OF_DEV_CHANGED,
+ adapter->dev_id, mgmt_dev_class_changed_event,
+ adapter, NULL);
+
+ mgmt_register(adapter->mgmt, MGMT_EV_LOCAL_NAME_CHANGED,
+ adapter->dev_id, mgmt_local_name_changed_event,
+ adapter, NULL);
+}
+
static void load_link_keys(struct bt_adapter *adapter, GSList *keys)
{
struct mgmt_cp_load_link_keys *cp;
@@ -188,6 +341,7 @@ static void read_info_complete(uint8_t status, uint16_t length,
default_adapter->current_settings = btohs(rp->current_settings);

/* TODO: Register all event notification handlers */
+ register_mgmt_handlers(default_adapter);

if (default_adapter->current_settings & MGMT_SETTING_POWERED)
adapter_start(default_adapter);
--
1.7.10.4


2013-10-07 07:38:06

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCHv1 05/15] android: Start Android Bluetooth daemon

From: Andrei Emeltchenko <[email protected]>

Start Android Bluetooth daemon from HAL init(). Make sure
that daemon is in "running" state.
---
android/hal_bluetooth.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 53 insertions(+), 1 deletion(-)

diff --git a/android/hal_bluetooth.c b/android/hal_bluetooth.c
index 00f3e8d..f8139a7 100644
--- a/android/hal_bluetooth.c
+++ b/android/hal_bluetooth.c
@@ -23,11 +23,16 @@
#include <hardware/bluetooth.h>
#include <hardware/bt_sock.h>

+#include <cutils/sockets.h>
+#include <cutils/properties.h>
+
#define LOG_TAG "BlueZ"
#include <cutils/log.h>

#include "hal.h"

+#define ANDROID_BLUEZ "btd"
+
bt_callbacks_t *bt_hal_cbacks = NULL;

static bool interface_ready(void)
@@ -35,6 +40,49 @@ static bool interface_ready(void)
return bt_hal_cbacks != NULL;
}

+static bool is_running(const char *service_name)
+{
+ char val[PROPERTY_VALUE_MAX];
+ char name[PROPERTY_KEY_MAX];
+ int ret;
+
+ ALOGI(__func__);
+
+ ret = snprintf(name, sizeof(name), "init.svc.%s", service_name);
+ if (ret > PROPERTY_KEY_MAX - 1) {
+ ALOGD("Service name '%s' is too long", service_name);
+ return false;
+ }
+
+ if (property_get(name, val, NULL)) {
+ if (strcmp(val, "running") == 0)
+ return true;
+ }
+
+ return false;
+}
+
+static bool start_bt_daemon(void)
+{
+ int tries = 40; /* wait 4 seconds for completion */
+
+ ALOGI(__func__);
+
+ /* Start Android Bluetooth daemon service */
+ property_set("ctl.start", ANDROID_BLUEZ);
+
+ while (tries-- > 0) {
+ if (is_running(ANDROID_BLUEZ) == true) {
+ ALOGI("Android BlueZ daemon started");
+ return true;
+ }
+
+ usleep(100000);
+ }
+
+ return false;
+}
+
static bool is_profile(const char *profile, const char *str)
{
return strcmp(profile, str) == 0;
@@ -50,7 +98,11 @@ static int init(bt_callbacks_t *callbacks)
/* store reference to user callbacks */
bt_hal_cbacks = callbacks;

- /* TODO: Init here bluezd task */
+ if (start_bt_daemon() == true) {
+ /* TODO: open channel */
+
+ return BT_STATUS_SUCCESS;
+ }

return BT_STATUS_UNSUPPORTED;
}
--
1.7.10.4


2013-10-07 07:38:09

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCHv1 08/15] android: Add adapter and device struct for BlueZ daemon

From: Andrei Emeltchenko <[email protected]>

Adapter structure in BlueZ daemon keeps track of default adapter
and device structure keeps track about found devices.
---
android/bt_adapter.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++
android/bt_adapter.h | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 116 insertions(+)
create mode 100644 android/bt_adapter.c
create mode 100644 android/bt_adapter.h

diff --git a/android/bt_adapter.c b/android/bt_adapter.c
new file mode 100644
index 0000000..e21d50c
--- /dev/null
+++ b/android/bt_adapter.c
@@ -0,0 +1,56 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2013 Intel Corporation. All rights reserved.
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include "bt_adapter.h"
+#include "log.h"
+#include "src/shared/mgmt.h"
+
+struct bt_adapter *bt_adapter_new(uint16_t index, struct mgmt *mgmt_if)
+{
+ struct bt_adapter *adapter;
+
+ adapter = g_try_new0(struct bt_adapter, 1);
+ if (!adapter)
+ return NULL;
+
+ adapter->dev_id = index;
+ adapter->mgmt = mgmt_ref(mgmt_if);
+
+ return adapter;
+}
+
+void adapter_start(struct bt_adapter *adapter)
+{
+ DBG("enabled %u", adapter->dev_id);
+
+ /* TODO: CB: report scan mode */
+
+ /* TODO: SDP start here */
+
+ /* TODO: CB: report state on */
+}
+
+void adapter_stop(struct bt_adapter *adapter)
+{
+ DBG("disabled %u", adapter->dev_id);
+}
diff --git a/android/bt_adapter.h b/android/bt_adapter.h
new file mode 100644
index 0000000..6877cc7
--- /dev/null
+++ b/android/bt_adapter.h
@@ -0,0 +1,60 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2013 Intel Corporation. All rights reserved.
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <glib.h>
+
+#include "lib/bluetooth.h"
+
+struct bt_device {
+ int refcnt;
+
+ bdaddr_t bdaddr;
+ uint8_t bdaddr_type;
+ uint32_t cod;
+ char *name;
+};
+
+struct bt_adapter {
+ int refcnt;
+
+ uint16_t dev_id;
+ struct mgmt *mgmt;
+ bdaddr_t bdaddr;
+ uint32_t dev_class;
+
+ char *name;
+ char *short_name;
+
+ uint32_t supported_settings;
+ uint32_t current_settings;
+
+ GList *found_devices;
+};
+
+struct bt_adapter *bt_adapter_new(uint16_t index, struct mgmt *mgmt_if);
+
+void adapter_start(struct bt_adapter *adapter);
+void adapter_stop(struct bt_adapter *adapter);
--
1.7.10.4


2013-10-07 07:38:12

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCHv1 11/15] android: Add cap to bind to port < 1024

From: Andrei Emeltchenko <[email protected]>

For SDP server we need to bind to lower port, acquire this capability.
---
android/main.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
configure.ac | 4 ++++
2 files changed, 76 insertions(+)

diff --git a/android/main.c b/android/main.c
index 7968ed0..dab54ce 100644
--- a/android/main.c
+++ b/android/main.c
@@ -32,6 +32,22 @@
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/prctl.h>
+#include <linux/capability.h>
+
+/**
+ * Include <sys/capability.h> for host build and
+ * also for Android 4.3 when it is added to bionic
+ */
+#if !defined(__ANDROID_API__) || (__ANDROID_API__ > 17)
+#include <sys/capability.h>
+#endif
+
+#if defined(__ANDROID_API__)
+#include <private/android_filesystem_config.h>
+#endif

#include <glib.h>

@@ -279,6 +295,59 @@ static void cleanup_mgmt_interface(void)
mgmt_if = NULL;
}

+static bool android_set_aid_and_cap()
+{
+ struct __user_cap_header_struct header;
+ struct __user_cap_data_struct cap;
+#if defined(__ANDROID_API__)
+ gid_t groups[] = {AID_NET_BT, AID_NET_BT_ADMIN, AID_BLUETOOTH,
+ AID_NET_ADMIN};
+#endif
+
+ DBG("pid %d uid %d gid %d", getpid(), getuid(), getgid());
+
+ header.version = _LINUX_CAPABILITY_VERSION;
+
+ prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0);
+
+#if defined(__ANDROID_API__)
+ if (setgid(AID_BLUETOOTH) < 0)
+ warn("%s: setgid(): %s", __func__, strerror(errno));
+
+ if (setuid(AID_BLUETOOTH) < 0)
+ warn("%s: setuid(): %s", __func__, strerror(errno));
+#endif
+
+ header.version = _LINUX_CAPABILITY_VERSION;
+ header.pid = 0;
+
+ cap.effective = cap.permitted =
+ CAP_TO_MASK(CAP_SETGID) |
+ CAP_TO_MASK(CAP_NET_RAW) |
+ CAP_TO_MASK(CAP_NET_ADMIN) |
+ CAP_TO_MASK(CAP_NET_BIND_SERVICE);
+ cap.inheritable = 0;
+
+ if (capset(&header, &cap) < 0) {
+ error("%s: capset(): %s", __func__, strerror(errno));
+ return false;
+ }
+
+#if defined(__ANDROID_API__)
+ if (setgroups(sizeof(groups)/sizeof(groups[0]), groups) < 0)
+ warn("%s: setgroups: %s", __func__, strerror(errno));
+#endif
+ if (capget(&header, &cap) < 0)
+ error("%s: capget(): %s", __func__, strerror(errno));
+ else
+ DBG("Caps: eff: 0x%x, perm: 0x%x, inh: 0x%x", cap.effective,
+ cap.permitted, cap.inheritable);
+
+ DBG("pid %d uid %d gid %d", getpid(), getuid(), getgid());
+
+ return true;
+}
+
int main(int argc, char *argv[])
{
GOptionContext *context;
@@ -312,6 +381,9 @@ int main(int argc, char *argv[])
sigaction(SIGINT, &sa, NULL);
sigaction(SIGTERM, &sa, NULL);

+ if (android_set_aid_and_cap() == false)
+ exit(EXIT_FAILURE);
+
init_mgmt_interface();
sdp_start();

diff --git a/configure.ac b/configure.ac
index 7b1f64a..5406434 100644
--- a/configure.ac
+++ b/configure.ac
@@ -247,4 +247,8 @@ AC_ARG_ENABLE(android, AC_HELP_STRING([--enable-android],
[enable_android=${enableval}])
AM_CONDITIONAL(ANDROID, test "${enable_android}" = "yes")

+if (test "${android_daemon}" = "yes"); then
+ AC_CHECK_LIB(cap, capget, dummy=yes, AC_MSG_ERROR(libcap is required))
+fi
+
AC_OUTPUT(Makefile src/bluetoothd.8 lib/bluez.pc)
--
1.7.10.4


2013-10-07 07:38:13

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCHv1 12/15] android: Implement read_info_complete callback

From: Andrei Emeltchenko <[email protected]>

Handle read info complete callback from mgmt interface.
---
android/main.c | 102 +++++++++++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 90 insertions(+), 12 deletions(-)

diff --git a/android/main.c b/android/main.c
index dab54ce..3a63eb9 100644
--- a/android/main.c
+++ b/android/main.c
@@ -54,6 +54,7 @@
#include "log.h"
#include "hcid.h"
#include "sdpd.h"
+#include "bt_adapter.h"

#include "lib/bluetooth.h"
#include "lib/mgmt.h"
@@ -69,6 +70,8 @@ static struct mgmt *mgmt_if = NULL;
static uint8_t mgmt_version = 0;
static uint8_t mgmt_revision = 0;

+struct bt_adapter *default_adapter = NULL;
+
static int sdp_start(void)
{
DBG("");
@@ -118,34 +121,109 @@ static GOptionEntry options[] = {
{ NULL }
};

-static void read_info_complete(uint8_t status, uint16_t length,
+static void load_link_keys_complete(uint8_t status, uint16_t length,
const void *param, void *user_data)
{
- /* TODO: Store Controller information */
-
- /**
- * Register all event notification handlers for controller.
- *
- * The handlers are registered after a succcesful read of the
- * controller info. From now on they can track updates and
- * notifications.
- */
+ DBG("status %u", status);
}

+static void load_link_keys(struct bt_adapter *adapter, GSList *keys)
+{
+ struct mgmt_cp_load_link_keys *cp;
+ uint16_t key_len = g_slist_length(keys);
+ struct mgmt_link_key_info *key;
+ uint16_t len;
+
+ DBG("");
+
+ len = sizeof(*cp) + key_len * sizeof(*key);
+ cp = malloc(len);
+ if (cp == NULL) {
+ error("%s: Not enough memory for link keys loading", __func__);
+ return;
+ }
+
+ cp->debug_keys = 0;
+ cp->key_count = htobs(key_len);
+
+ mgmt_send(adapter->mgmt, MGMT_OP_LOAD_LINK_KEYS, adapter->dev_id, len,
+ cp, load_link_keys_complete, adapter, NULL);
+
+ free(cp);
+}
+
+static void read_info_complete(uint8_t status, uint16_t length,
+ const void *param, void *user_data)
+{
+ const struct mgmt_rp_read_info *rp = param;
+
+ DBG("");
+
+ if (status != MGMT_STATUS_SUCCESS) {
+ error("Failed to read info for index %u: %s (0x%02x)",
+ default_adapter->dev_id, mgmt_errstr(status), status);
+ goto failed;
+ }
+
+ if (length < sizeof(*rp)) {
+ error("Too small read info complete response");
+ goto failed;
+ }
+
+ if (bacmp(&rp->bdaddr, BDADDR_ANY) == 0) {
+ error("No Bluetooth address for index %u",
+ default_adapter->dev_id);
+ goto failed;
+ }
+
+ /* Store adapter information */
+ bacpy(&default_adapter->bdaddr, &rp->bdaddr);
+ default_adapter->dev_class = rp->dev_class[0] |
+ (rp->dev_class[1] << 8) |
+ (rp->dev_class[2] << 16);
+ default_adapter->name = g_strdup((const char *) rp->name);
+ default_adapter->short_name = g_strdup((const char *) rp->short_name);
+
+ default_adapter->supported_settings = btohs(rp->supported_settings);
+ default_adapter->current_settings = btohs(rp->current_settings);
+
+ /* TODO: Register all event notification handlers */
+
+ if (default_adapter->current_settings & MGMT_SETTING_POWERED)
+ adapter_start(default_adapter);
+
+ /* dummy link keys loading */
+ load_link_keys(default_adapter, NULL);
+
+ return;
+
+failed:
+ default_adapter = NULL;
+}

static void mgmt_index_added_event(uint16_t index, uint16_t length,
const void *param, void *user_data)
{
info("%s: index %u", __func__, index);

+ if (default_adapter == NULL) {
+ DBG("skip event for index %d", index);
+ return;
+ }
+
+ default_adapter = bt_adapter_new(index, mgmt_if);
+ if (default_adapter == NULL) {
+ error("Unable to create new adapter for index %u", index);
+ return;
+ }
+
DBG("sending read info command for index %u", index);

if (mgmt_send(mgmt_if, MGMT_OP_READ_INFO, index, 0, NULL,
- read_info_complete, NULL, NULL) > 0)
+ read_info_complete, NULL, NULL) > 0)
return;

error("Failed to read adapter info for index %u", index);
-
}

static void mgmt_index_removed_event(uint16_t index, uint16_t length,
--
1.7.10.4


2013-10-07 07:38:07

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCHv1 06/15] android: Add basic mgmt initialization sequence

From: Andrei Emeltchenko <[email protected]>

Initialize bluetooth controller via mgmt interface.
---
Makefile.android | 4 +-
android/Android.mk | 11 +++
android/main.c | 189 ++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 203 insertions(+), 1 deletion(-)

diff --git a/Makefile.android b/Makefile.android
index e161e6d..9a2c486 100644
--- a/Makefile.android
+++ b/Makefile.android
@@ -1,7 +1,9 @@
if ANDROID
noinst_PROGRAMS += android/bluetoothd

-android_bluetoothd_SOURCES = android/main.c src/log.c
+android_bluetoothd_SOURCES = android/main.c src/log.c \
+ src/shared/util.h src/shared/util.c \
+ src/shared/mgmt.h src/shared/mgmt.c
android_bluetoothd_LDADD = @GLIB_LIBS@
endif

diff --git a/android/Android.mk b/android/Android.mk
index 2cabff4..f5fd863 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -15,10 +15,15 @@ include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
main.c \
log.c \
+ ../src/shared/mgmt.c \
+ ../src/shared/util.c \

LOCAL_C_INCLUDES := \
$(call include-path-for, glib) \
$(call include-path-for, glib)/glib \
+
+LOCAL_C_INCLUDES += \
+ $(LOCAL_PATH)/../ \
$(LOCAL_PATH)/../src \

LOCAL_CFLAGS := -DVERSION=\"$(BLUEZ_VERSION)\"
@@ -26,6 +31,12 @@ LOCAL_CFLAGS := -DVERSION=\"$(BLUEZ_VERSION)\"
# to suppress the "warning: missing initializer near initialization.." warning
LOCAL_CFLAGS += -Wno-missing-field-initializers

+# to suppress the "pointer of type 'void *' used in arithmetic" warning
+LOCAL_CFLAGS += -Wno-pointer-arith
+
+# Define missing flags for Android 4.2
+LOCAL_CFLAGS += -DSOCK_CLOEXEC=02000000 -DSOCK_NONBLOCK=04000
+
LOCAL_SHARED_LIBRARIES := \
libglib \

diff --git a/android/main.c b/android/main.c
index f75b0a8..3580ac7 100644
--- a/android/main.c
+++ b/android/main.c
@@ -25,6 +25,7 @@
#include <config.h>
#endif

+#include <stdbool.h>
#include <signal.h>
#include <stdint.h>
#include <stdio.h>
@@ -36,9 +37,17 @@

#include "log.h"

+#include "lib/bluetooth.h"
+#include "lib/mgmt.h"
+#include "src/shared/mgmt.h"
+
#define SHUTDOWN_GRACE_SECONDS 10

static GMainLoop *event_loop;
+static struct mgmt *mgmt_if = NULL;
+
+static uint8_t mgmt_version = 0;
+static uint8_t mgmt_revision = 0;

static gboolean quit_eventloop(gpointer user_data)
{
@@ -67,6 +76,183 @@ static GOptionEntry options[] = {
{ NULL }
};

+static void read_info_complete(uint8_t status, uint16_t length,
+ const void *param, void *user_data)
+{
+ /* TODO: Store Controller information */
+
+ /**
+ * Register all event notification handlers for controller.
+ *
+ * The handlers are registered after a succcesful read of the
+ * controller info. From now on they can track updates and
+ * notifications.
+ */
+}
+
+
+static void mgmt_index_added_event(uint16_t index, uint16_t length,
+ const void *param, void *user_data)
+{
+ info("%s: index %u", __func__, index);
+
+ DBG("sending read info command for index %u", index);
+
+ if (mgmt_send(mgmt_if, MGMT_OP_READ_INFO, index, 0, NULL,
+ read_info_complete, NULL, NULL) > 0)
+ return;
+
+ error("Failed to read adapter info for index %u", index);
+
+}
+
+static void mgmt_index_removed_event(uint16_t index, uint16_t length,
+ const void *param, void *user_data)
+{
+ info("%s: index %u", __func__, index);
+}
+
+static void read_index_list_complete(uint8_t status, uint16_t length,
+ const void *param, void *user_data)
+{
+ const struct mgmt_rp_read_index_list *rp = param;
+ uint16_t num;
+ int i;
+
+ info(__func__);
+
+ if (status != MGMT_STATUS_SUCCESS) {
+ error("%s: Failed to read index list: %s (0x%02x)",
+ __func__, mgmt_errstr(status), status);
+ return;
+ }
+
+ if (length < sizeof(*rp)) {
+ error("%s: Wrong size of read index list response", __func__);
+ return;
+ }
+
+ num = btohs(rp->num_controllers);
+
+ DBG("%s: Number of controllers: %d", __func__, num);
+
+ if (num * sizeof(uint16_t) + sizeof(*rp) != length) {
+ error("%s: Incorrect pkt size for index list rsp", __func__);
+ return;
+ }
+
+ for (i = 0; i < num; i++) {
+ uint16_t index;
+
+ index = btohs(rp->index[i]);
+
+ DBG("%s: Found index %u", __func__, index);
+
+ /**
+ * Use index added event notification.
+ */
+ mgmt_index_added_event(index, 0, NULL, NULL);
+ }
+}
+
+
+static void read_commands_complete(uint8_t status, uint16_t length,
+ const void *param, void *user_data)
+{
+ const struct mgmt_rp_read_commands *rp = param;
+ uint16_t num_commands, num_events;
+
+ info(__func__);
+
+ if (status != MGMT_STATUS_SUCCESS) {
+ error("Failed to read supported commands: %s (0x%02x)",
+ mgmt_errstr(status), status);
+ return;
+ }
+
+ if (length < sizeof(*rp)) {
+ error("Wrong size of read commands response");
+ return;
+ }
+
+ num_commands = btohs(rp->num_commands);
+ num_events = btohs(rp->num_events);
+
+ DBG("Number of commands: %d", num_commands);
+ DBG("Number of events: %d", num_events);
+}
+
+static void read_version_complete(uint8_t status, uint16_t length,
+ const void *param, void *user_data)
+{
+ const struct mgmt_rp_read_version *rp = param;
+
+ info(__func__);
+
+ if (status != MGMT_STATUS_SUCCESS) {
+ error("Failed to read version information: %s (0x%02x)",
+ mgmt_errstr(status), status);
+ return;
+ }
+
+ if (length < sizeof(*rp)) {
+ error("Wrong size response");
+ return;
+ }
+
+ mgmt_version = rp->version;
+ mgmt_revision = btohs(rp->revision);
+
+ info("Bluetooth management interface %u.%u initialized",
+ mgmt_version, mgmt_revision);
+
+ if (mgmt_version < 1) {
+ error("Version 1.0 or later of management interface required");
+ abort();
+ }
+
+ DBG("sending read supported commands command");
+
+ mgmt_send(mgmt_if, MGMT_OP_READ_COMMANDS, MGMT_INDEX_NONE, 0, NULL,
+ read_commands_complete, NULL, NULL);
+
+ mgmt_register(mgmt_if, MGMT_EV_INDEX_ADDED, MGMT_INDEX_NONE,
+ mgmt_index_added_event, NULL, NULL);
+ mgmt_register(mgmt_if, MGMT_EV_INDEX_REMOVED, MGMT_INDEX_NONE,
+ mgmt_index_removed_event, NULL, NULL);
+
+ DBG("sending read index list command");
+
+ if (mgmt_send(mgmt_if, MGMT_OP_READ_INDEX_LIST, MGMT_INDEX_NONE, 0,
+ NULL, read_index_list_complete, NULL, NULL) > 0)
+ return;
+
+ error("Failed to read controller index list");
+}
+
+static bool init_mgmt_interface(void)
+{
+ mgmt_if = mgmt_new_default();
+ if (mgmt_if == NULL) {
+ error("Failed to access management interface");
+ return false;
+ }
+
+ if (mgmt_send(mgmt_if, MGMT_OP_READ_VERSION, MGMT_INDEX_NONE, 0, NULL,
+ read_version_complete, NULL, NULL) == 0) {
+ error("Error sending READ_VERSION mgmt command");
+ return false;
+ }
+
+ return true;
+}
+
+static void cleanup_mgmt_interface(void)
+{
+ mgmt_unref(mgmt_if);
+ mgmt_if = NULL;
+}
+
int main(int argc, char *argv[])
{
GOptionContext *context;
@@ -100,10 +286,13 @@ int main(int argc, char *argv[])
sigaction(SIGINT, &sa, NULL);
sigaction(SIGTERM, &sa, NULL);

+ init_mgmt_interface();
+
DBG("Entering main loop");

g_main_loop_run(event_loop);

+ cleanup_mgmt_interface();
g_main_loop_unref(event_loop);

info("Exit");
--
1.7.10.4


2013-10-07 07:38:16

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCHv1 15/15] android: Add makefile for hcitool

From: Andrei Emeltchenko <[email protected]>

---
android/Android.mk | 38 ++++++++++++++++++++++++++++++++++++++
1 file changed, 38 insertions(+)

diff --git a/android/Android.mk b/android/Android.mk
index 09c4579..5798749 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -157,3 +157,41 @@ LOCAL_MODULE_TAGS := eng
LOCAL_MODULE := hciconfig

include $(BUILD_EXECUTABLE)
+
+#
+# hcitool
+#
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+ ../tools/hcitool.c \
+ ../src/oui.c \
+
+LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH)/../lib \
+ $(LOCAL_PATH)/../src \
+
+LOCAL_C_INCLUDES += \
+ $(call include-path-for, glib) \
+ $(call include-path-for, glib)/glib \
+
+LOCAL_CFLAGS := \
+ -DSTORAGEDIR=\"/tmp\" \
+ -DVERSION=\"$(BLUEZ_VERSION)\"
+
+# to suppress the "pointer of type 'void *' used in arithmetic" warning
+LOCAL_CFLAGS += -Wno-pointer-arith
+
+# to suppress the "warning: missing initializer near initialization.." warning
+LOCAL_CFLAGS += -Wno-missing-field-initializers
+
+LOCAL_SHARED_LIBRARIES := \
+ libbluetooth \
+ libglib \
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
+LOCAL_MODULE_TAGS := eng
+LOCAL_MODULE := hcitool
+
+include $(BUILD_EXECUTABLE)
--
1.7.10.4


2013-10-07 07:38:10

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCHv1 09/15] android: Add Android Makefile for libbluetooth

From: Andrei Emeltchenko <[email protected]>

Build libbluetooth library for Android.
---
android/Android.mk | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 53 insertions(+)

diff --git a/android/Android.mk b/android/Android.mk
index f5fd863..8f95a66 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -41,6 +41,7 @@ LOCAL_SHARED_LIBRARIES := \
libglib \

LOCAL_MODULE := bluetoothd
+LOCAL_REQUIRED_MODULES := libbluetooth

include $(BUILD_EXECUTABLE)

@@ -63,3 +64,55 @@ LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := SHARED_LIBRARIES

include $(BUILD_SHARED_LIBRARY)
+
+#
+# libbluetooth library
+#
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+ ../lib/bluetooth.c \
+ ../lib/sdp.c \
+ ../lib/hci.c \
+ ../lib/uuid.c \
+
+LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH)/../lib/ \
+ $(LOCAL_PATH)/../src/shared \
+
+LOCAL_C_INCLUDES += \
+ $(call include-path-for, glib) \
+ $(call include-path-for, glib)/glib \
+
+LOCAL_CFLAGS += -O3
+
+# to suppress the "pointer of type 'void *' used in arithmetic" warning
+LOCAL_CFLAGS += -Wno-pointer-arith
+
+# to suppress the "missing initializer near initialization" warning
+LOCAL_CFLAGS += -Wno-missing-field-initializers
+
+# Define missing flags for Android 4.2
+LOCAL_CFLAGS += -DSOCK_CLOEXEC=02000000 -DSOCK_NONBLOCK=04000
+
+lib_headers := \
+ bluetooth.h \
+ hci.h \
+ hci_lib.h \
+ sco.h \
+ l2cap.h \
+ sdp.h \
+ sdp_lib.h \
+ rfcomm.h \
+ bnep.h \
+ cmtp.h \
+ hidp.h \
+
+$(shell mkdir -p $(LOCAL_PATH)/../lib/bluetooth)
+
+$(foreach file,$(lib_headers), $(shell ln -sf ../$(file) $(LOCAL_PATH)/../lib/bluetooth/$(file)))
+
+LOCAL_MODULE := libbluetooth
+
+include $(BUILD_SHARED_LIBRARY)
--
1.7.10.4


2013-10-07 07:38:11

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCHv1 10/15] android: sdp: Reuse BlueZ SDP server in Android

From: Andrei Emeltchenko <[email protected]>

Reuse existing SDP server code in Android GPL daemon.
---
Makefile.android | 7 +++++--
android/Android.mk | 7 +++++++
android/bt_adapter.c | 2 --
android/main.c | 28 ++++++++++++++++++++++++++++
4 files changed, 40 insertions(+), 4 deletions(-)

diff --git a/Makefile.android b/Makefile.android
index 9a2c486..d576b52 100644
--- a/Makefile.android
+++ b/Makefile.android
@@ -2,9 +2,12 @@ if ANDROID
noinst_PROGRAMS += android/bluetoothd

android_bluetoothd_SOURCES = android/main.c src/log.c \
+ src/sdpd-database.c src/sdpd-server.c \
+ src/sdpd-service.c src/sdpd-request.c \
src/shared/util.h src/shared/util.c \
- src/shared/mgmt.h src/shared/mgmt.c
-android_bluetoothd_LDADD = @GLIB_LIBS@
+ src/shared/mgmt.h src/shared/mgmt.c \
+ android/bt_adapter.h android/bt_adapter.c
+android_bluetoothd_LDADD = lib/libbluetooth-internal.la @GLIB_LIBS@
endif

EXTRA_DIST += android/Android.mk android/log.c
diff --git a/android/Android.mk b/android/Android.mk
index 8f95a66..e7a70d0 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -17,6 +17,11 @@ LOCAL_SRC_FILES := \
log.c \
../src/shared/mgmt.c \
../src/shared/util.c \
+ bt_adapter.c \
+ ../src/sdpd-database.c \
+ ../src/sdpd-service.c \
+ ../src/sdpd-request.c \
+ ../src/sdpd-server.c \

LOCAL_C_INCLUDES := \
$(call include-path-for, glib) \
@@ -25,6 +30,7 @@ LOCAL_C_INCLUDES := \
LOCAL_C_INCLUDES += \
$(LOCAL_PATH)/../ \
$(LOCAL_PATH)/../src \
+ $(LOCAL_PATH)/../lib \

LOCAL_CFLAGS := -DVERSION=\"$(BLUEZ_VERSION)\"

@@ -39,6 +45,7 @@ LOCAL_CFLAGS += -DSOCK_CLOEXEC=02000000 -DSOCK_NONBLOCK=04000

LOCAL_SHARED_LIBRARIES := \
libglib \
+ libbluetooth \

LOCAL_MODULE := bluetoothd
LOCAL_REQUIRED_MODULES := libbluetooth
diff --git a/android/bt_adapter.c b/android/bt_adapter.c
index e21d50c..6b758bf 100644
--- a/android/bt_adapter.c
+++ b/android/bt_adapter.c
@@ -45,8 +45,6 @@ void adapter_start(struct bt_adapter *adapter)

/* TODO: CB: report scan mode */

- /* TODO: SDP start here */
-
/* TODO: CB: report state on */
}

diff --git a/android/main.c b/android/main.c
index 3580ac7..7968ed0 100644
--- a/android/main.c
+++ b/android/main.c
@@ -36,6 +36,8 @@
#include <glib.h>

#include "log.h"
+#include "hcid.h"
+#include "sdpd.h"

#include "lib/bluetooth.h"
#include "lib/mgmt.h"
@@ -43,12 +45,36 @@

#define SHUTDOWN_GRACE_SECONDS 10

+struct main_opts main_opts;
+
static GMainLoop *event_loop;
static struct mgmt *mgmt_if = NULL;

static uint8_t mgmt_version = 0;
static uint8_t mgmt_revision = 0;

+static int sdp_start(void)
+{
+ DBG("");
+
+ /* TODO: add logic */
+
+ /* sdpd-server use these settings */
+ memset(&main_opts, 0, sizeof(main_opts));
+
+ /* Use params: mtu = 0, flags = 0 */
+ return start_sdp_server(0, 0);
+}
+
+static void sdp_stop(void)
+{
+ DBG("");
+
+ /* TODO: add logic */
+
+ stop_sdp_server();
+}
+
static gboolean quit_eventloop(gpointer user_data)
{
g_main_loop_quit(event_loop);
@@ -287,11 +313,13 @@ int main(int argc, char *argv[])
sigaction(SIGTERM, &sa, NULL);

init_mgmt_interface();
+ sdp_start();

DBG("Entering main loop");

g_main_loop_run(event_loop);

+ sdp_stop();
cleanup_mgmt_interface();
g_main_loop_unref(event_loop);

--
1.7.10.4


2013-10-07 07:38:02

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCHv1 01/15] android: Supress missing initializers warnings

From: Andrei Emeltchenko <[email protected]>

These types of warnings are disabled in BlueZ makeifiles

main.c:67:2: warning: missing initializer [-Wmissing-field-initializers]
main.c:67:2: warning: (near initialization for 'options[1].short_name')
[-Wmissing-field-initializers]
---
android/Android.mk | 3 +++
1 file changed, 3 insertions(+)

diff --git a/android/Android.mk b/android/Android.mk
index ec820ac..5498b41 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -23,6 +23,9 @@ LOCAL_C_INCLUDES := \

LOCAL_CFLAGS := -DVERSION=\"$(BLUEZ_VERSION)\"

+# to suppress the "warning: missing initializer near initialization.." warning
+LOCAL_CFLAGS += -Wno-missing-field-initializers
+
LOCAL_SHARED_LIBRARIES := \
libglib \

--
1.7.10.4


2013-10-07 07:38:04

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCHv1 03/15] android: Add Socket Bluetooth HAL template

From: Andrei Emeltchenko <[email protected]>

bt_sock HAL handles Bluetooth sockets for Android.
---
android/Android.mk | 1 +
android/hal_bt_sock.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 85 insertions(+)
create mode 100644 android/hal_bt_sock.c

diff --git a/android/Android.mk b/android/Android.mk
index 7adbbcd..2cabff4 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -41,6 +41,7 @@ include $(CLEAR_VARS)

LOCAL_SRC_FILES := \
hal_bluetooth.c \
+ hal_bt_sock.c \

LOCAL_SHARED_LIBRARIES := \
libcutils \
diff --git a/android/hal_bt_sock.c b/android/hal_bt_sock.c
new file mode 100644
index 0000000..cbb42d1
--- /dev/null
+++ b/android/hal_bt_sock.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2013 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 <stdlib.h>
+
+#include <hardware/bluetooth.h>
+#include <hardware/bt_sock.h>
+
+#define LOG_TAG "BlueZ"
+#include <cutils/log.h>
+
+static bt_status_t btsock_listen_rfcomm(const char *service_name,
+ const uint8_t *uuid, int chan,
+ int *sock, int flags)
+{
+ ALOGD(__func__);
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static bt_status_t listen(btsock_type_t type, const char *service_name,
+ const uint8_t *uuid, int chan,
+ int *sock, int flags)
+{
+ if ((uuid == NULL && chan <= 0) || sock == NULL) {
+ ALOGE("%s: invalid params: uuid %p, chan %d, sock %p",
+ __func__, uuid, chan, sock);
+ return BT_STATUS_PARM_INVALID;
+ }
+
+ ALOGD("%s: uuid %p chan %d sock %p type %d service_name %s",
+ __func__, uuid, chan, sock, type, service_name);
+
+ switch (type) {
+ case BTSOCK_RFCOMM:
+ return btsock_listen_rfcomm(service_name, uuid, chan,
+ sock, flags);
+ default:
+ ALOGE("%s: Socket type %d not supported", __func__, type);
+ }
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static bt_status_t connect(const bt_bdaddr_t *bdaddr, btsock_type_t type,
+ const uint8_t *uuid, int chan,
+ int *sock, int flags)
+{
+ if ((uuid == NULL && chan <= 0) || bdaddr == NULL || sock == NULL) {
+ ALOGE("invalid params: bd_addr %p, uuid %p, chan %d, sock %p",
+ bdaddr, uuid, chan, sock);
+ return BT_STATUS_PARM_INVALID;
+ }
+
+ ALOGD("%s: uuid %p chan %d sock %p type %d", __func__, uuid, chan,
+ sock, type);
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static btsock_interface_t btsock_if = {
+ sizeof(btsock_if),
+ listen,
+ connect
+};
+
+btsock_interface_t *bt_get_sock_interface(void)
+{
+ return &btsock_if;
+}
--
1.7.10.4


2013-10-07 07:38:05

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCHv1 04/15] android: Enable Socket interface

From: Andrei Emeltchenko <[email protected]>

Returns socket interface, use header hal.h to avoid externs.
---
android/hal.h | 18 ++++++++++++++++++
android/hal_bluetooth.c | 11 +++++++++++
2 files changed, 29 insertions(+)
create mode 100644 android/hal.h

diff --git a/android/hal.h b/android/hal.h
new file mode 100644
index 0000000..40fbf03
--- /dev/null
+++ b/android/hal.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2013 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.
+ *
+ */
+
+btsock_interface_t *bt_get_sock_interface(void);
diff --git a/android/hal_bluetooth.c b/android/hal_bluetooth.c
index 9970374..00f3e8d 100644
--- a/android/hal_bluetooth.c
+++ b/android/hal_bluetooth.c
@@ -21,10 +21,13 @@
#include <stdbool.h>

#include <hardware/bluetooth.h>
+#include <hardware/bt_sock.h>

#define LOG_TAG "BlueZ"
#include <cutils/log.h>

+#include "hal.h"
+
bt_callbacks_t *bt_hal_cbacks = NULL;

static bool interface_ready(void)
@@ -32,6 +35,11 @@ static bool interface_ready(void)
return bt_hal_cbacks != NULL;
}

+static bool is_profile(const char *profile, const char *str)
+{
+ return strcmp(profile, str) == 0;
+}
+
static int init(bt_callbacks_t *callbacks)
{
ALOGD(__func__);
@@ -246,6 +254,9 @@ static const void *get_profile_interface(const char *profile_id)
if (interface_ready() == false)
return NULL;

+ if (is_profile(profile_id, BT_PROFILE_SOCKETS_ID))
+ return bt_get_sock_interface();
+
return NULL;
}

--
1.7.10.4