 Alright, so I guess we can get started. My name is Johan Hedberg. I work at the Open Source Technology Center at Intel and I've been working with Zephyr now for about two years, specifically on the Bluetooth support there. And in this talk I'll be going through basically what we have right now in Zephyr, what kind of hardware you can run the Bluetooth functionality on, what features it has and basic steps for creating devices and applications using Zephyr and Bluetooth. So before we go into the specifics of Zephyr, just a quick summary of what I'm mostly talking about I'll talk about Bluetooth support, I'll talk about Bluetooth low energy which is a rather new addition to the Bluetooth specification. It was introduced in 2010 for the Bluetooth 4.0 specification and it's gone through various names in its history. There was the Bluetooth smart marketing name that the Bluetooth SIG was using for quite a long time but they have dropped it now so it's just called Bluetooth low energy and in very many places here it referred to simply as BLE. It's the same 2.4 GHz frequency as classic Bluetooth but it's a little bit different when it comes to the radio modulation. You get, well you got until Bluetooth 4.2 about the same range and one megabit per second bandwidth. Bluetooth 5 which came out just at the end of last year improves on both of these aspects. You get up to 2 megabits per second and about four times the range. With the range of course you have to compromise with the throughput of the data that you get. Unlike Bluetooth Classic you get drastically smaller power consumption with low energy. You can run for years with a small coin cell battery and devices supporting Bluetooth low energy are generally categorized in two different types of devices. One is pure Bluetooth low energy devices or so-called single mode devices that only have the low energy radio. This would typically be sensors like a heart rate belt or something like that. And then the other type is the one which also supports the Bluetooth Classic and these are so-called dual mode devices. And that's what you would find on a PC for example or on your mobile phone. And Bluetooth low energy is perfect for internal things kind of use cases as I'll try to outline throughout this presentation. So there's ever Bluetooth stack. It's part of the core Zephyr open source as such. We are 4.2 compliant. We've been working on 5.0 features ever since the specification went out but that's something that's going to continue basically throughout this year as we add more and more of those features. We are feature complete when it comes to the mandatory set of features but there's lots of optional things in the Bluetooth specification and we are working on adding those as we get good use cases for them. We have many optional features that you will not find in many typical Bluetooth stacks. One such thing is the L2CAP connection or the channels for LE which is a prerequisite for doing IPv6 over LE. The six log pan protocol and IPSP is the high level profile for that. We have LE secure connections which is a security enhancement from Bluetooth 4.2 which improves on the security of the pairing. We have data length extensions which is a 4.2 feature as well for the controller. Even though I'm mostly going to be talking about Bluetooth Low Energy, we also have Bluetooth Classic support in Zephyr. So it's possible to build devices that utilize both low energy and Bluetooth Classic or only Bluetooth Classic. I'll talk a little bit more about that later. The stack consists of a controller part and the host part and you can build either or I'll go into the details later. But the main thing is that we are using a standard HCI protocol between the host and the controller. Whether they are running on the same CPU or whether we have them split with a Bluetooth controller on one and host on another CPU. And since Zephyr 1.6 we have support for the Bluetooth controller role as well. This is a fairly new thing when it comes to open source. There haven't been pretty much any open source Bluetooth controller implementations before last year. But I'll give some more details on that also later in the presentation. So the general architecture that we have. We have a fairly high level set of APIs that we expose the APIs to applications. And the main two profiles that application would be talking to is the generic access profile and the generic attribute profile. The generic access profile is kind of everything which doesn't fall into a very specific use case. So this would include discovering devices or being discoverable yourself. The profile generally groups roles into two different pairs. You have so called connection oriented use cases where you're creating connections between two devices. There you have one devices which is called the peripheral. That would typically be your sensor type of device and the one that connects to the peripheral is called the central. Your phone for example. You can also do connection less use cases where you have a device that's looking for other devices so called beacons. This device that's looking for them is called the observer and then the opposing role is called the broadcaster. You can configure Zephyr to support any kind of combination of these roles. As I briefly mentioned earlier we have IPv6 over LA support which is a fairly unique thing I would say when it comes to Bluetooth stacks. Not many Bluetooth stacks support that. I'm not really sure why it hasn't gotten that much traction yet in the industry. But that's something that you can do with Zephyr. The main reference we've been using for testing this is Linux because that's one of the few other stacks we know of. The blue Z stack that supports IPv6 over LA. Then below all of these profiles we have an abstraction we call the HDI driver which basically hides away the details of how we talk to the Bluetooth controller. Whether it's running on the same CPU or if it's connected through some kind of physical transport like UART or SPI or USB. And if it's on the same CPU then it's just basically buffers like passed in runtime memory from the host to the controller or vice versa. But it's always a standard HCI. And we've been able to test this on lots of different hardware. We're able to run this on just normal PC hardware in QM1, use any Bluetooth adapter there. I'll have a bit more about that later as well as then actual microcontroller boards. We have quite many in our device library. And you can configure pretty much any aspect of this stack through KQuantific, disable the features that you don't want. Adjust the buffer sizes to match your use cases, the buffer counts, how many connections you need, how many devices you need and so on. All of these are configurable. A little bit about the stack, how it's set up at runtime. So specifically the host side of the stack. So at the bottom we have the HCI driver which hides away the details of talking to the controller. We have two threads which handle two directions of data coming from the controller and going to the controller. This is something by the way that has recently improved in Zephyr for the 1.7 release. In Zephyr 1.6 and earlier there wasn't any API to wait on multiple kernel objects in a single call. So we were forced to have multiple transmission threads for every single connection because every connection has its own transmission queue. So we need to have a separate thread to wait on that queue and process data from it. Zephyr 1.7 is introducing a new K-Poll API which allows us to wait on multiple kernel objects in one go. So we've been able to merge together the connection TX threads into a single one and also include the HCI command sending thread into this one. So there's one TX thread and then there's one RX thread for data coming from the controller. Just a quick summary of the types of data that's going to and from the controller. From the controller we are either getting HCI events which is basically kind of signaling or metadata related stuff and then you have data going over connections. If you're connected to other devices which is called ACL data and you have the same in the other direction except instead of HCI events you have HCI commands that we send to the controller. If the HCI driver inherently has some kind of thread of its own we also have the ability to say that don't bother creating a separate thread on the host side. Just use the same thread for the receive path that the controller already has. This saves a considerable amount of memory whenever we're able to do that. Typically the thread stacks that we have are about one kilobyte maybe more so that's roughly what you save. If you have an HCI driver that's able to do this or you are the HCI driver utilizes this the native controller HCI driver does it as well. So the host doesn't have its own thread for receiving data. A key part of the Bluetooth stack and the way we process data are network buffers. That's something we share with the networking stack and the IP stack in Zephyr as well and this saves a lot of basically code size. We'd be writing parsers for encoders for protocol data because the network buffer API comes with its own helpers for encoding and decoding different types to the buffers. They also make it possible to easily handle fragmentation so you can have a linked list of buffers and pass those around. So you don't need to have extra handling for that or have one like huge buffer where you put individual fragments but you just change them after each other. And these buffers can be passed around between different threads through different kernel objects you don't need to copy data on and so on. So we achieve almost zero copy operation like this. And they go not just from the bottom of the stack from the controller up to the host but they also go between subsystems. So if you are doing IPv6 over LE the data goes in the same network buffer from the Bluetooth subsystem over to the IP stack or vice versa without having to do any copies of the data. Then a little bit about the basic steps when you want to create your application that uses Bluetooth functionality what you need to do. The first thing that you would typically start off with is looking at your use cases and deciding what exactly are the features that you need. The HEA driver would in practice come from what hardware you have selected. Do you have split Bluetooth controller and Bluetooth host running on different CPUs? Do you have them on the same CPU or not? What is the transport? If you have one of the transports that Zephyr supports currently such as UART or SPY then you can just select one of the existing ones that we have in Zephyr. If you have something more exotic than that then you will need to implement your own HEA driver. Then you can select the exact features that you want. Do you want to do connection based operation? Do you just want to be a beacon? How strong security do you need? Do you want to do signed data when you send it and so on? And also how big is the data that you want to send? How many buffers you need and so on? All these are K-config options in the Zephyr Bluetooth stack. For the maximum number of connections you can go and set it to zero and this will disable all of the connection oriented functionality in Zephyr. It will save a lot of code size and runtime memory as well. For pretty much every single module in the Bluetooth stack we have debug options. Specifically you're able to enable and disable debug logs on a per module basis. So when you go ahead and try to find where an issue is with the stack you can enable the logs exactly for the module that you're interested in. The Linux kernel has something called dynamic debug where you can basically at runtime go ahead and enable and disable. Because of the memory constraints of the device that Zephyr usually runs on we don't have that at runtime but it's instead pretty much the same thing that you get except you need to do it at build time through K-config. Once you've selected the options you want to start writing your application. We have one main initialization API that you start up the Bluetooth stack with. It will go ahead and contact the Bluetooth driver and make sure that the transport there works that the Bluetooth hardware or the radio is responsive to read basic information about what it can do. If you're doing a generic attribute profile based application where you do connections and expose data to devices you would register your services. And once you've registered your services you want to start advertising them to other devices so they can connect to you and discover them. And typically your service would be connected to some physical sensor of sorts. So once you're connected there's a simple PTGOT notify API to send out updates on the value of that sensor. And essentially all of the APIs that we have for the Bluetooth stack in Zephyr we have sample applications in the source tree that you can go ahead and look at which will show exactly how the APIs are used. Those are found under samples Bluetooth. We have some test applications as well. They're not necessarily as good references for somebody starting basically from scratch looking at how to write an application. But there's a test sub director also in Zephyr which you'll be able to find even more code. And pretty much all of those applications that we had will run on most of the boards that Zephyr currently supports. Whether it's a board with a single CPU with a controller there or with split architecture. Then a little bit about what kind of development support we have for doing Bluetooth development. When we got started with Zephyr and implementing a Bluetooth stack for it we didn't actually use any real hardware as such to get quickly started with the development. We were using QML and we were able to take advantage of the support that Linux has to hook that up with Zephyr. And basically have Linux expose its Bluetooth hardware to QML looking like a normal UART based Bluetooth controller and then use that for development. The big advantage with having the data going through Linux is that we can use the tracing tools available there. So there are nice decoders for all traffic going through HCI and we didn't need to implement any of our own for Zephyr instead. We just run the existing tools that are available in Linux. And GDB support is of course something that you get with QML also. Before I go further I just wanted to do a quick demo here. Hopefully it works for how simple it is to use your laptop for example to run a quick Zephyr Bluetooth application. So there are basically just two steps involved. First you ask BlueZ to export your Bluetooth adapter to... Sorry, I can see it perfectly here. It's green and black. So there's a tool called BT Proxy which basically it opens socket to the kernel, creates an exclusive channel to your Bluetooth adapter and then you can choose how to export it further. So by passing minus U it will create a unique socket which then when you ask Zephyr to be running QML it will connect to the unique socket and it will look like a UART device to Zephyr. So you start the BT Proxy. I'll start another terminal here so you can see. So I'll start the HCI Tracing application called BTmon which will show all the HCI data that's going. And then in another terminal I'll run Zephyr. So I'll use the... So if you go to samples Bluetooth you can see that there are lots of very simple applications there. I'll use the peripheral sample which is a simple kind of sensor type application. And all you do is run make QML. And in the other terminal you should see Zephyr starting to talk to the Bluetooth controller once this builds. Yeah, there we go. So here you see that Zephyr has initialized. It has started advertising. Here you can see the data that it's discussing with the Bluetooth adapter on my laptop. So that's basically all that's needed to start using it. Now just for demonstration purposes it's actually using physical hardware. I'll use an app on my phone to look for the device. Of course there are too many here. And then I'll connect it. So I'm now connecting from my phone. You can see the data going through. You can see all the decoding of the data. What's happening there, the attribute protocol and so on. And I'll disconnect like that. So that's pretty much all it takes to get started with Zephyr Bluetooth development even though you don't have any actual hardware except your own PC to run on. Then let's go to actual physical hardware. We wanted to be able to still keep using bluesy decoders like the BTmon that I showed you there. And there's a special option that you can enable in the Zephyr Bluetooth stack which converts your console UART into a binary protocol which we call the Bluetooth monitor protocol. And what it effectively does is that it interleaves the HIA traffic that's going on between the host and the controller in Zephyr with the normal system logs. So you can have print K or print F calls which then get encapsulated into packets which go through this binary protocol. And instead of running, I run BTmon without any parameters here so that it just monitors everything that's happening. What you need to do is you just give minus minus TTY and you give the serial device that you have your physical board connected to. And you'll be able to trace everything that's happening there, the system logs and the HIA traffic that's happening. And at least for the boards that I have, this has been super helpful in debugging is just seeing exactly what's going on there where you typically don't get enough information simply from the normal logs that are put there. Oftentimes if you don't have this kind of functionality you have to put lots and lots of different print Fs around the place to find out what's happening and so on. But with this you see exactly what the raw data is and also the decoding of the raw data that's going there. So until I think late summer last year we only had Bluetooth host support in Zephyr. But something really nice happened during last year. Before 2016 there was pretty much no open source Bluetooth controller implementation that I know of. I've never heard of anything. If somebody knows then please tell me. But in the first half of last year, runtime that had a presentation here just before me they came out with MindUte with a full open source controller implementation supporting Nordic Semiconductor controllers. And shortly thereafter Nordic Semiconductor themselves approached the Zephyr project that they have also controlled implementation. They would like to open source and get included into Zephyr. So we collaborated with Nordic and as a result Zephyr 1.6 has support for Bluetooth controllers. Since it's coming from Nordic it naturally initially only supports Nordic controllers. They have their NRF 51 and NRF 52 based ones. But the way that the implementation is designed it has radio abstraction and we are actually hoping to expand it to support more than just Nordic controllers. The first candidate we have is one from NXP actually. If you think just about the protocol layers in the Bluetooth stack what the controller implements the biggest part of it is called the link layer. And the support or the functionality of the controller that we got into Zephyr is very flexible. Most Bluetooth devices that you have on the market right now they are quite limited in what they can do. What you have on your phones or on your PCs for example they typically can only do one slave connection at the time. They can connect multiple peripherals but they can just be a single, if they want to be in the peripheral role they can just have one connection. However the one we have in Zephyr it can support pretty much not unlimited but it doesn't have any specific limit on the number of connections it can do. It's dependent on the amount of front time memory you have and also what kind of timing constraints you want to do for every single connection. And of course the controller exposes HCI on its highest layer so we were nicely able to hook it up with the host stack in Zephyr. I briefly mentioned about this but you can configure Zephyr in any of these possible combinations of Bluetooth roles where you only run the controller side where you basically have a Zephyr application that's exposing the HCI transport. There's a special raw HCI API that the application hooks onto to be able to expose just HCI at the highest layer. You have the host only option where you have the controller residing on another CPU where you then need an actual HCI driver that does the physical transport or you can run them both in a single controller. All of the Nordic semiconductor boards have just a single CPU where you run both the controller and the host in the same. Some examples of where you could find this. Intel has its QRI-based devices like the Arduino 1-on-1. It has an NR51-based Bluetooth controller and a Quark SC-based application processor. We are running the controller-only mode of Zephyr there on the NR51 side. The carbon board from Linaro has a similar thing except instead of Quark SC it has Cortex-M4 processor but on the NR51 again it's running the controller-only mode of Zephyr. The main difference there is that the Arduino uses UART the carbon uses SPI for the HCI transport. Likewise you would run the host-only configuration on the application processor of these boards. The QMU demonstration I used there, that's also running the host-only configuration with the UART HCI driver because that's how QMU exposes the connection it has to the controller. And then pretty much all of the Nordic boards, they are running both in the same CPU. So in addition to low-energy, we do have basic support for Bluetooth Classic if you want to take advantage of that. We have all the low-level protocols implemented like RFCOM, L2CUP. You have the generic access profile where you're able to discover devices, configure your own discoverability to create connections and so on. They support both for service discovery client and server so you can discover services in another device or you can register your own Bluetooth Classic services and have another device discover them. And we have a couple of sample profiles implemented as well. The main kind of high-level use case that's been in mind here is a headset where you would want to have the advanced audio distribution protocol for stereo audio and hands-free profile for doing calls and call control and then for media control the audio video remote control profile. And I mentioned we are right now working with Bluetooth 5 since the specification with public just end of last year. It's something that's going to continue throughout this year and I hope that, well, server 1.7 won't be having many Bluetooth 5 features but 1.8 should already have many more of them. Bluetooth Mesh is a big thing coming from the Bluetooth SIG soon. But I'll be able to talk more about that once the specification actually gets released to the general public. If you are working for a company that already has is already a Bluetooth SIG member and has access to these specifications please come and talk to me. We can arrange collaboration possibilities on things like Bluetooth Mesh which is not yet public but what we don't want to have is different companies ending up doing duplicate implementations of features just because they can't share it to the public and do collaboration on it. So if you're interested in this and you have access to the specs we can arrange collaboration possibilities before it's actually available to the general public. What we, I mentioned this also, what we want to do is have the controller run on more radios than Nordics. The abstraction is there but we really need to have other radios to see that we've done the right kind of API definition there for the abstraction. There are a couple of features also that we haven't implemented yet such as Linkler privacy which basically lets you push the resolution of private addresses down to the controller instead of having to do this on the host side. That's something we have to do at the moment. Also the standard HCI specification in some aspect it's a little bit limited in what you can do. So what we're going to be working on is an extension to it. It's also called vendor HCI specification. There are things such as being able to set your public address which you cannot do using standard HCI commands. Another example is Nordic controllers. They have in their own special memory location stored a static random address that's supposed to be used as their identity address. In order for us to use this, the standard HCI doesn't provide any kind of mechanism of reading it out from the host side unless the host is running on the same CPU then we can just access the memory directly. So we would have a command that we can read out that address and then program it back to be used as the identity address of the controller. So that's something that we'll be working on as well during this year. Luckily for Zephyr 1.8, we'll already have the specification document for this in the source stream. And yeah, I'd like to encourage anybody who's interested in Bluetooth support and Zephyr to get involved since it's a completely open project. We have an open mailing list. We have a very active IRC channel on FreeNote where we have daily conversations and we have people available there basically around the clock in different time zones. So just come and ask your questions. And same goes for the issue tracking and the source code management, JIRA and Yerit. And that's what I had so far. Any questions? Yeah, I mean, we've been using Linux to do testing of IPv6 over LE. It's still a little bit rough on the edges on the Linux side. It's lacking a proper user space interface which in turn has prevented the creation of proper kind of higher level interfaces in Linux. Currently, to operate this in Linux, you need to use debugFS. You basically echo the address of the Zephyr device to debugFS and Linux connects to it and so on. But basic things are working there. Yeah, so we actually have a sample application for it. I could have shown it. So it's samples Bluetooth IPSP. So that's the one that implements the node role of the IPSP profile. And there's a readme there also that describes basically how to set it up. I think it also goes through exactly what you need to do on the Linux side with debugFS and so on. So this one has an Intel Bluetooth controller. It's the no-field peak controller from Intel. Actually, it's something PCI, it's in USB, of course. That doesn't tell you much, but actually this one says 4.1. There exists the 4.2 firmware, I have seen it. I think they might have rolled back because there was some issues with the latest one. But it should be able to do some 4.2 stuff. No, I don't think you need anything special for that. Engine R, it's a DPU for embedded... Yeah? ...for example, SPC codec or SPC codec? Yeah, so the SPC codec is mandatory for A2DP. So our assumption is actually the way that it's currently designed is that the assumption is that the controller takes care of it. So it's using basically a controller-side codec. At the moment, we don't have plans to have the SPC codec on the separate itself. There are many controllers that have the ability to do that and they do it much more efficiently there on the controller side than instead of us having to do all the encoding or decoding on the separate side. But if you have a use case where you need to do that then feel free to contribute it. I mean, there exists, at least Linux uses. It's a... What's the license of the... Okay, okay, that's one for... Any other questions? Well, feel free to come up and talk to me later if you have something. Thanks.