Current section
Files
Jump to
Current section
Files
blue_heron
README.md
README.md
# BlueHeron[](https://hex.pm/packages/blue_heron)[](https://hexdocs.pm/blue_heron/BlueHeron.html)[](https://circleci.com/gh/nerves-project/nerves/tree/main)BlueHeron is a new Elixir Bluetooth LE Library that communicates directly withBluetooth modules via HCI. It is VERY much under construction, and we expect theuser API to change completely.On the plus side, BlueHeron has no dependencies on Linux's `bluez` stack so ifyou either can't use `bluez`, don't want to, or have a simple BLE use case,please join us in building this out! We gather on the [Elixir Langslack](https://elixir-slackin.herokuapp.com/) in the `#nerves-bluetooth`channel.## GoalsBlueHeron development was started since SmartRent had a need for a very simpleBLE interface on one of its Nerves devices.The existing Elixir BLE library, [Harald](https://github.com/verypossible-labs/harald),didn't have enough functionality and we made so many modifications that it nolonger felt like the library followed the spirit of what Harald wanted to be.Our goals here are to make a one-stop BLE library with support for thefollowing:* Scan for and connect to BLE peripheral devices (BlueHeron takes on the central role like a smartphone)* GATT client support* Work with USB and UART-based Bluetooth modules* Support BLE beacons* BLE peripheral and GATT server supportThe current focus is on filling out the central role. The API is quite unstableat the moment, but we're aiming for a high level API so that most users don'tneed to become Bluetooth experts. Currently, the raw API is helping us learn andiron out quirks quickly. See [Rationale](#Rationale) for more about why we'redoing building this library.If you are interested in adding support for the other roles, please let us knoweither here or on Slack. While we're very interested in part of this library forwork, we're also having fun with BLE and figure that we might as well see if wecan hit some Nerves use cases too.## Hardware compatibilityWe have only tested BlueHeron with a limited number of Bluetooth adapters.Here's what's known:| Bluetooth module or chipset | Connection | Works? | Firmware | Notes| -------------------------------------- | ---------- | ------ | ---------------------- | -----| Realtek WiFi/BT combo (EDUP EP-AC1681) | USB | Yes | rtl_bt/rtl8822b_fw.bin | BlueHeron doesn't need to load the firmware for this one to work.| Cypress CYW43438 (RPi0W and RPi 3B) | UART | Yes | ? | BlueHeron doesn't need to load the firmware for this one to work.| Cypress CYW43455 (RPi 3A+ and 3B+) | UART | No | ? | Retry when #21 is fixed## Getting startedSee the [examples](https://github.com/blue-heron/blue_heron/examples) for the time being.## TransportsBlueHeron interacts with Bluetooth modules via transports. Transportimplementations are not part of this library since they are hardware-specific.See[BlueHeronTransportUART](https://github.com/blue-heron/blue_heron_transport_uart)and[BlueHeronTransportUSB](https://github.com/blue-heron/blue_heron_transport_usb)for examples.## HCI LoggingThis project includes a Logger backend to dump PKTLOG format. This is the same formatthat Android, IOS, btstack, hcidump, and bluez use.Add the backend to debug all data to/from the HCI transport:```elixiriex> Logger.add_backend(BlueHeron.HCIDump.Logger)BlueHeron.HCIDump.Logger```This will produce a file `/tmp/hcidump.pklg` that can be loaded into Wireshark.**NOTE** This project configures logger so it is always enabled by default.However, this can be disabled by setting `config :blue_heron, log_hci_dump_file:false`The `BlueHeron.HCIDump.Logger` module implements a superset of Elixir's builtin logger andall non-HCI data is forwarded directly to Elixir's Logger.```elixiriex> require BlueHeron.HCIDump.Logger, as: LoggerBlueHeron.HCIDump.Loggeriex> Logger.debug("sample data")16:43:46.496 [debug] sample dataiex>```## Helpful docs* [Bluetooth Core Specification v5.2](https://www.bluetooth.org/docman/handlers/downloaddoc.ashx?doc_id=478726)## RationaleThis library will likely feel like a whole lot of reinvention of the wheel foranyone familiar with Bluetooth stacks in embedded Linux. It took around threeyears for one of us to get to this point of starting a new library, so it'sworth sketching out why.The obvious approach is to use Linux's `bluez` stack. It certainly worked, butwas complicated for most people to set up when using Nerves. Consequently, itwas hard to debug and a thankless task for anyone attempting to support Nervesusers. It was far easier to use `bluez` on a batteries-included OS distributionlike Raspbian.The next approach was to use a smart Bluetooth module like an Adafruit Bluefruitmodule or a Roving Networks (now Microchip) Bluetooth module. These have an `AT`style command set for doing common Bluetooth things (for example,see[here](https://learn.adafruit.com/introducing-adafruit-ble-bluetooth-low-energy-friend/command-mode)),and are fairly easy to use once you got used to the interface. Not everyonewanted to use these for various reasons (cost being a big one).A good alternative was to use a C Bluetooth stack that talks directly to aBluetooth module via UART or USB using the HCI protocol. These aretypically marketed towards microcontroller users, but can be made to work onminimal Linux configurations too. Some of the options have good documentationand are commercially supported.Integrating the C stack still required work, and since our needs were so simple,we simultaneously looked at an Elixir implementation. Elixir has a way of makingdull work surprisingly enjoyable, and it's especially suited to communicationprotocols. When the proof-of-concept started working in not much time, wedecided that we'd much rather spend our time in Elixir than anywhere else.Will this library have more features than `bluez`? Not even close. Will it dowhat we need? Yes. Will it have fewer bugs, be more robust, etc.? Don't know,but its small size and few parts is easier to get our heads around and debugwhen issues come up. Is it fun to work on? Yes, so we got permission toopen-source it, so we could use it for hobby projects too.## SupportWe provide best-effort support via the [Elixir Forum](https://elixirforum.com/)and the [#nerves-bluetooth channel on the ElixirSlack](https://elixir-slackin.herokuapp.com/). If you need more immediatesupport or feature additions, commercial support is provided by [BinaryNoggin](https://binarynoggin.com).## LicenseThe source code is released under Apache License 2.0.Check [NOTICE](NOTICE) and [LICENSE](LICENSE) files for more information.