Re: defining a BLE GATT server

2020-08-24 Thread Matias N.
You're right, maybe I'm caught on the callback interface because that is how it 
is
implemented now, but in the end there's always a packet you process.
I still wonder if also having L2CAP in kernel would be better since it deals
with multiple connection handling, packet fragmentation and so on (to me it is
like TCP, but maybe I'm reading it wrong).

Anyway, as I'm still finishing the link layer and I wouldn't want to get into 
this before
completing that. But it would be cool if you or someone else would be willing 
to look
into this further, I could then contribute to that effort.

I guess I will hack something locally to make a GATT server until we devise a 
clean way
to do it.

Best,
Matias

On Mon, Aug 24, 2020, at 01:06, Brennan Ashton wrote:
> On Sun, Aug 23, 2020, 8:45 PM Matias N.  wrote:
> 
> > Hi Brennan,
> >
> > Yes, as I understand the host layer is actually from (early?) Zephyr code.
> >
> > The way you suggest it should be done sounds very reasonable. However I
> > wonder if this is
> > always the right approach. Right now the HCI layer is using work queues to
> > handle
> > communication with different priorities. So I would guess that it would be
> > best to expose at
> > L2CAP level. From the looks of it, GATT is more like a library with
> > convenience functions, but
> > there are still many callbacks so the problem would be the same as now I
> > think. Are callbacks
> > abstracted via read/write on sockets in this case? Or what would be the
> > simplest way to
> > handle callbacks from OS to application? I can only think of POSIX
> > signals, but that feels quite
> > limited.
> 
> 
> I'm not sure I follow. Normally the kennel would expose the HCI socket and
> the you would issue a read on the socket to identify events to act on. That
> would include an action like reading a GATT entry. With bluez there is a
> user space daemon that does just that and then applications register via
> dbus. Here it would probably be less important to have the daemon since
> would likely only have a single application doing Bluetooth so you could
> just make the GATT a library.
> 
> The Bluez daemon also makes use of file descriptors for managing events if
> you want to use that instead of the dbus API.  So I suppose that could be
> used here as well I just don't see why we have GATT in the kernel. That
> seems like the wrong thing.
> 
> 
> BlueZ is also doing some things to handle some HCI events in the kernel you
> can fully unregister the device from connection management by requesting a
> BTUSER_CHAN which Zypher once again also supports in POSIX mode.
> 
> Reinventing this abstraction is probably not in our best interest.
> 
> 
> --Brennan
> 
> >
> 


Re: defining a BLE GATT server

2020-08-24 Thread Gregory Nutt




You're right, maybe I'm caught on the callback interface because that is how it 
is
implemented now, but in the end there's always a packet you process.
I still wonder if also having L2CAP in kernel would be better since it deals
with multiple connection handling, packet fragmentation and so on (to me it is
like TCP, but maybe I'm reading it wrong).
One of my longer term goals with BLE was to implement 6LoWPAN on top of 
L2CAP.  There are several implementations like that out there (although 
it does seem redundant).  In order to do that L2CAP would need to be 
inside the OS.





Re: defining a BLE GATT server

2020-08-24 Thread Gregory Nutt
Also, I understand that Xiaomi intends to replace the entire Bluetooth 
stack with a newer BT 5.0 stack.  I don't know if that is still a plan 
of record or not, but you probably should coordinate Bluetooth 
architectural changes with Xiao Xiang in any event.


Re: defining a BLE GATT server

2020-08-24 Thread Matias N.
Thanks for the heads up. Would be good to get Xiao Xiang's input on this
then. Maybe he already encountered this issue.

For now I'm working on the Link Layer, looking at 4.0 spec as a start.
If the host layer is reimplemented for 5.0 I understand it shouldn't invalidate
the LL in principle. But for any change on the host layer I would like to
know if there are plans or work in progress.

On Mon, Aug 24, 2020, at 11:47, Gregory Nutt wrote:
> Also, I understand that Xiaomi intends to replace the entire Bluetooth 
> stack with a newer BT 5.0 stack.  I don't know if that is still a plan 
> of record or not, but you probably should coordinate Bluetooth 
> architectural changes with Xiao Xiang in any event.
> 


Re: defining a BLE GATT server

2020-08-24 Thread Gregory Nutt




Thanks for the heads up. Would be good to get Xiao Xiang's input on this
then. Maybe he already encountered this issue.


You should also be aware of the wireless architectural principles of 
https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=139629397


Some of the things you have speculated about would be contrary to these 
principles.  The basic wireless rules are:


1. Network sockets are used to communicate with complex wireless 
networks (like bluetooth)


2. Character drivers should be avoided

3. Network interfaces must/should be compatible with corresponding Linux 
interfaces.


I think if there are features that you want to implement, you might 
first want to look at how those features are implemented in Linux.  That 
would be the correct way to proceed.





Re: defining a BLE GATT server

2020-08-24 Thread Brennan Ashton
On Mon, Aug 24, 2020 at 12:34 PM Gregory Nutt  wrote:
>
> Some of the things you have speculated about would be contrary to these
> principles.  The basic wireless rules are:
>
> 1. Network sockets are used to communicate with complex wireless
> networks (like bluetooth)
>
> 2. Character drivers should be avoided
>
> 3. Network interfaces must/should be compatible with corresponding Linux
> interfaces.
>
> I think if there are features that you want to implement, you might
> first want to look at how those features are implemented in Linux.  That
> would be the correct way to proceed.

I fully agree with this.  AF_BLUETOOTH is already in place, but it
only implements "BTPROTO_L2CAP" all of the GATT and
advertising/scanning related functionality is implemented over
"BTPROTO_HCI"


fd = socket(PF_BLUETOOTH, SOCK_RAW | SOCK_CLOEXEC | SOCK_NONBLOCK, BTPROTO_HCI);
addr.hci_family = AF_BLUETOOTH;
addr.hci_dev = dev_id;
addr.hci_channel = HCI_CHANNEL_RAW;

HCI event filters are then controlled via socket options with SOL_HCI
and HCI_FILTER

Most of these are defined in the NuttX bluetooth stack, but they have
not been implemented.
If you bind using HCI_CHANNEL_RAW and not the HCI_CHANNEL_USER the
Linux kernel will take care of some of the GAP related actions, there
is also a management socket that is exposed as well.

I see that there is an ioctl interface for the bluetooth network
driver, but I don't think this is really a good idea.  GATT is really
something that should be handled in userspace.

I finally have a few weeks off, so I can see about making some HCI
socket progress, going to take a bit to get hardware setup for it
though.

--Brennan


Re: defining a BLE GATT server

2020-08-24 Thread Gregory Nutt

On 8/24/2020 2:20 PM, Brennan Ashton wrote:

On Mon, Aug 24, 2020 at 12:34 PM Gregory Nutt  wrote:

Some of the things you have speculated about would be contrary to these
principles.  The basic wireless rules are:

1. Network sockets are used to communicate with complex wireless
networks (like bluetooth)

2. Character drivers should be avoided

3. Network interfaces must/should be compatible with corresponding Linux
interfaces.

I think if there are features that you want to implement, you might
first want to look at how those features are implemented in Linux.  That
would be the correct way to proceed.

I fully agree with this.  AF_BLUETOOTH is already in place, but it
only implements "BTPROTO_L2CAP" all of the GATT and
advertising/scanning related functionality is implemented over
"BTPROTO_HCI"


fd = socket(PF_BLUETOOTH, SOCK_RAW | SOCK_CLOEXEC | SOCK_NONBLOCK, BTPROTO_HCI);
addr.hci_family = AF_BLUETOOTH;
addr.hci_dev = dev_id;
addr.hci_channel = HCI_CHANNEL_RAW;

HCI event filters are then controlled via socket options with SOL_HCI
and HCI_FILTER

Most of these are defined in the NuttX bluetooth stack, but they have
not been implemented.
If you bind using HCI_CHANNEL_RAW and not the HCI_CHANNEL_USER the
Linux kernel will take care of some of the GAP related actions, there
is also a management socket that is exposed as well.

I see that there is an ioctl interface for the bluetooth network
driver, but I don't think this is really a good idea.  GATT is really
something that should be handled in userspace.

I finally have a few weeks off, so I can see about making some HCI
socket progress, going to take a bit to get hardware setup for it
though.

--Brennan


I have been puzzling through the Goobledegook GATT server (GGK, 
https://github.com/moovel/gatt-server fork).  It uses the Bluez D-Bus 
interface.  It is GPLv3 so not a candidate for porting.  And also not 
much use for understanding APIs since the OS interface is hidden inside 
of the Bluez D-Bus interface 
(https://core.docs.ubuntu.com/en/stacks/bluetooth/bluez/docs/reference/dbus-api)


I think there are several of us who would help with clean 
Linux-work-alike Bluetooth support.





Re: defining a BLE GATT server

2020-08-24 Thread Matias N.

> I see that there is an ioctl interface for the bluetooth network
> driver, but I don't think this is really a good idea.  GATT is really
> something that should be handled in userspace.

Yes, I've been using what exists at the host layer in NuttX, via the btsak 
application.
While it opens a socket specifying "L2CAP",  a lot of functionality is 
implemented
via ioctl calls which use gatt for example.

> I finally have a few weeks off, so I can see about making some HCI
> socket progress, going to take a bit to get hardware setup for it
> though.

Cool! I can help test this. I have two nrf52832 boards I'm using: Sparkfun 
breakout, used as sniffer using raccoon firmware and MakerDiary MDK as main dev 
platform. The MDK is quite good, has embedded debugger + uart via USB (using 
DAPLINK). 

BTW, I would like to CC Xiang to have him in the loop but I can't find his 
email address (only GitHub handle). Can you copy him?

Best,
Matias


Re: defining a BLE GATT server

2020-08-24 Thread Matias N.

> I have been puzzling through the Goobledegook GATT server (GGK, 
> https://github.com/moovel/gatt-server fork).  It uses the Bluez D-Bus 
> interface.  It is GPLv3 so not a candidate for porting.  And also not 
> much use for understanding APIs since the OS interface is hidden inside 
> of the Bluez D-Bus interface 
> (https://core.docs.ubuntu.com/en/stacks/bluetooth/bluez/docs/reference/dbus-api)

I think all the GATT logic in NuttX is very complete so it would be better to 
use that as a base.
Right now it kind of looks like a library already so I think it would mostly 
have to be reworked
to interface to the kernel part of the host layer via L2CAP sockets.

> I think there are several of us who would help with clean 
> Linux-work-alike Bluetooth support.

Great! As I mentioned, I can help test. I'm actually a bit blocked right now to 
continue work on the Link Layer
since I'm missing something generating useful traffic at GATT level.

Best,
Matias



Re: defining a BLE GATT server

2020-08-24 Thread Brennan Ashton
On Mon, Aug 24, 2020 at 1:40 PM Matias N.  wrote:
>
>
> > I have been puzzling through the Goobledegook GATT server (GGK,
> > https://github.com/moovel/gatt-server fork).  It uses the Bluez D-Bus
> > interface.  It is GPLv3 so not a candidate for porting.  And also not
> > much use for understanding APIs since the OS interface is hidden inside
> > of the Bluez D-Bus interface
> > (https://core.docs.ubuntu.com/en/stacks/bluetooth/bluez/docs/reference/dbus-api)
Yeah I am very familiar with this having shipped devices on top of the
dbus API.  The dbus API is provided by bluetoothd which intern is
using the kernel socket interface.  Goobledegook is not really
providing us anything here since the underlying bindings between
sockets and GATT are still in bluetoothd.

>
> I think all the GATT logic in NuttX is very complete so it would be better to 
> use that as a base.
> Right now it kind of looks like a library already so I think it would mostly 
> have to be reworked
> to interface to the kernel part of the host layer via L2CAP sockets

I think you are missing something here, the interface that needs to be
supported is not L2CAP, it is HCI.
You would need to write a binding between the link layer and HCI.
Long as your device implements the interfaces here
wireless/bluetooth/bt_hcicore.c we should already be in a great place.

--Brennan


Re: defining a BLE GATT server

2020-08-24 Thread Gregory Nutt

I have been puzzling through the Goobledegook GATT server (GGK,
https://github.com/moovel/gatt-server fork).  It uses the Bluez D-Bus
interface.  It is GPLv3 so not a candidate for porting.  And also not
much use for understanding APIs since the OS interface is hidden inside
of the Bluez D-Bus interface
(https://core.docs.ubuntu.com/en/stacks/bluetooth/bluez/docs/reference/dbus-api)

Yeah I am very familiar with this having shipped devices on top of the
dbus API.  The dbus API is provided by bluetoothd which intern is
using the kernel socket interface.  Goobledegook is not really
providing us anything here since the underlying bindings between
sockets and GATT are still in bluetoothd.
So would adding the appropriate socket types and ioctls then 
re-implementing the d-bus API make a reasonable portability layer? That 
could be a pretty well defined job.


Re: defining a BLE GATT server

2020-08-24 Thread Brennan Ashton
On Mon, Aug 24, 2020 at 2:25 PM Gregory Nutt  wrote:
>
> >>> I have been puzzling through the Goobledegook GATT server (GGK,
> >>> https://github.com/moovel/gatt-server fork).  It uses the Bluez D-Bus
> >>> interface.  It is GPLv3 so not a candidate for porting.  And also not
> >>> much use for understanding APIs since the OS interface is hidden inside
> >>> of the Bluez D-Bus interface
> >>> (https://core.docs.ubuntu.com/en/stacks/bluetooth/bluez/docs/reference/dbus-api)
> > Yeah I am very familiar with this having shipped devices on top of the
> > dbus API.  The dbus API is provided by bluetoothd which intern is
> > using the kernel socket interface.  Goobledegook is not really
> > providing us anything here since the underlying bindings between
> > sockets and GATT are still in bluetoothd.
> So would adding the appropriate socket types and ioctls then
> re-implementing the d-bus API make a reasonable portability layer? That
> could be a pretty well defined job.

You are going to hate dbus :)
Honestly it is designed to be a system wide message bus for
desktop/server software and defines even a wire message format that
supports things like introspection.   I think that is wrong for a
small embedded system.  That leaves the question of what should be
used for IPC for the GATT server daemon.  I suspect we could get far
using event file descriptors, but also just having a library where a
single application owns the GATT server is probably fine.  The dbus
service is nice because I can write a standalone application that
provides the BAT service for showing battery life, and then have
another application that broadcasts RPMs from a cadence sensor.

--Brennan


Re: defining a BLE GATT server

2020-08-24 Thread Matias N.

> I think you are missing something here, the interface that needs to be
> supported is not L2CAP, it is HCI.

So you suggest to implement L2CAP in userspace? I'm confused when you mention 
that there's a L2CAP socket
already and HCI socket needs to be added. Just to be clear, I have this stack 
in mind:


So to me HCI is the protocol that L2CAP speaks to the LL and L2CAP sits on top. 
For that reason my understanding
was that what was needed is to provide L2CAP to userspace via sockets.

> 
> You would need to write a binding between the link layer and HCI.
> Long as your device implements the interfaces here
> wireless/bluetooth/bt_hcicore.c we should already be in a great place.

I already have a Link Layer defined as an arch-independent upper-half that 
registers itself as a HCI capable
net device (same as UART based devices do). Then I have an arch-dependant 
lower-half link-layer, which I'm currently
working for NRF52. I can create a draft PR soon (after I finish upstreaming 
intermediate unrelated commits) if
you want to take a look.

> --Brennan
> 


Re: defining a BLE GATT server

2020-08-24 Thread Matias N.
I also think D-Bus does not seem to be appropriate for small systems. It is 
overkill.
Also, having a library implementing all functionality and then a daemon using 
that library
would be the best way. As Brennan mentions, in many use cases (such as mine) I 
would
only have a single bluetooth application.

On Mon, Aug 24, 2020, at 18:41, Brennan Ashton wrote:
> You are going to hate dbus :)
> Honestly it is designed to be a system wide message bus for
> desktop/server software and defines even a wire message format that
> supports things like introspection.   I think that is wrong for a
> small embedded system.  That leaves the question of what should be
> used for IPC for the GATT server daemon.  I suspect we could get far
> using event file descriptors, but also just having a library where a
> single application owns the GATT server is probably fine.  The dbus
> service is nice because I can write a standalone application that
> provides the BAT service for showing battery life, and then have
> another application that broadcasts RPMs from a cadence sensor.
> 
> --Brennan
> 


Re: defining a BLE GATT server

2020-08-24 Thread Brennan Ashton
On Mon, Aug 24, 2020 at 3:56 PM Matias N.  wrote:

> That's quite a strange stack arrangement. If you go to the BLE spec, the
> L2CAP sits above the HCI layer.
> I would guess that the arrow between L2CAP and Bluez actually speaks the
> HCI protocol and the "HCI sockets" allow you to directly call into the HCI
> layer. I was under the impression that you wouldn't need to "skip layers"
> to access all functionality of the LL, but I understand then why the
> proposal of exposing the HCI layer via sockets.
>

The HCI socket interface does not directly map to the HCI interface of the
controller.  There are three different channels defined:#define
HCI_CHANNEL_RAW 0
#define HCI_CHANNEL_RAW 0
#define HCI_CHANNEL_USER 1
#define HCI_CHANNEL_MONITOR 2
#define HCI_CHANNEL_CONTROL 3

HCI_CHANNEL_USER removes the rest of the bluetooth stack from the
controller so that you dont have things like the L2CAP interface messing
with the device.  This can be super useful, it's actually what I am using
to allow the NuttX sim to control my bluetooth hardware.
This is in contrast to HCI_CHANNEL_RAW which does not unhook the rest of
the stack so you can have multiple things now trying to control the
hardware and you have to be careful.  RAW is not recommended anymore.

HCI_CHANNEL_MONITOR is somewhat self explanatory, but it lets you see all
the transactions that are taking place over the HCI interface (including in
bluez core).  This is usually what something like wireshark will use.
HCI_CHANNEL_CONTROL  is the "new" control interface that speaks via the
management API.  This is what bluetoothd would be using to do things like
advertise a new service.

I wish this was better documented, but it is scattered around and bits of
knowledge that I picked up writing a bluetooth mesh stack before it was
included in Linux.

Hopefully that is helpful,
Brennan


Re: defining a BLE GATT server

2020-08-24 Thread Matias N.
Ah, ok, it was much more complex than what I thought. Thanks for the 
explanation!

On Mon, Aug 24, 2020, at 20:10, Brennan Ashton wrote:
> On Mon, Aug 24, 2020 at 3:56 PM Matias N.  wrote:
> 
> > That's quite a strange stack arrangement. If you go to the BLE spec, the
> > L2CAP sits above the HCI layer.
> > I would guess that the arrow between L2CAP and Bluez actually speaks the
> > HCI protocol and the "HCI sockets" allow you to directly call into the HCI
> > layer. I was under the impression that you wouldn't need to "skip layers"
> > to access all functionality of the LL, but I understand then why the
> > proposal of exposing the HCI layer via sockets.
> >
> 
> The HCI socket interface does not directly map to the HCI interface of the
> controller.  There are three different channels defined:#define
> HCI_CHANNEL_RAW 0
> #define HCI_CHANNEL_RAW 0
> #define HCI_CHANNEL_USER 1
> #define HCI_CHANNEL_MONITOR 2
> #define HCI_CHANNEL_CONTROL 3
> 
> HCI_CHANNEL_USER removes the rest of the bluetooth stack from the
> controller so that you dont have things like the L2CAP interface messing
> with the device.  This can be super useful, it's actually what I am using
> to allow the NuttX sim to control my bluetooth hardware.
> This is in contrast to HCI_CHANNEL_RAW which does not unhook the rest of
> the stack so you can have multiple things now trying to control the
> hardware and you have to be careful.  RAW is not recommended anymore.
> 
> HCI_CHANNEL_MONITOR is somewhat self explanatory, but it lets you see all
> the transactions that are taking place over the HCI interface (including in
> bluez core).  This is usually what something like wireshark will use.
> HCI_CHANNEL_CONTROL  is the "new" control interface that speaks via the
> management API.  This is what bluetoothd would be using to do things like
> advertise a new service.
> 
> I wish this was better documented, but it is scattered around and bits of
> knowledge that I picked up writing a bluetooth mesh stack before it was
> included in Linux.
> 
> Hopefully that is helpful,
> Brennan
>