Hacker News new | ask | show | jobs
Show HN: OpenBLE, Swagger for Bluetooth (demo.openble.org)
122 points by shardulaeer 987 days ago
OpenBLE is an API specification language and client generator for Bluetooth services built on the generic attribute (GATT) profile.

Bluetooth development is a mess. Too many datasheets, too little documentation and SDK fragmentation across platforms. I built this tool to improve documentation, version control and development speed for BLE programs.

Even though shunned by Apple and Mozilla, Web Bluetooth enjoys wide support and just works. It makes sense to build the frontend for OpenBLE using web Bluetooth. No SDK hell, no installations, wide support albeit experimental. I could ship the spec, SDK, code generator and testing framework in pure JavaScript.

12 comments

As another commenter mentioned, it's common practice to shove all your device's functionality into one characteristic to reduce service discovery time (and, in some cases, memory footprint in firmware). With that in mind, can OpenBLE be used to describe the structure of the bytes being read, written, and indicated by the characteristics?

OpenAPI is useful because it not only generates a frontend for testing an API, it also can be used to generate the skeleton of an API's implementation. Can I generate Zephyr macros using this tool? Can I generate Android or iOS code? A complete tool should be able to generate firmware, Android, and iOS code for both a GATT server and client.

As a professional firmware engineer working in IoT, I'd advise against hanging your hat on Web Bluetooth. Bluetooth is already rife with security problems, and exposing direct control of it to a browser is asking for zero-day nightmares. This is beside the antipattern involved in asking web apps to directly control a peripheral's communication interface.

> I'd advise against hanging your hat on Web Bluetooth. Bluetooth is already rife with security problems, and exposing direct control of it to a browser is asking for zero-day nightmares.

Which is why (quoting OP) Mozilla has 'shunned' it. Apple too perhaps (though the reasoning isn't open afaik, and Safari omits more or adopts more slowly in general than can be ascribed to security/privacy concerns).

Hey, thanks for checking out my project. So the spec is independent of Web Bluetooth; like Swagger is to Swagger UI. I considered electron but it needs installation and wouldn't run on mobiles. Perhaps Web Bluetooth is not ready for devices, but is perfect for dev tools like this one.

As of today it can generate an Arduino GATT server; I'm working to support more platforms, Zephyr, iOS etc.

Great! That's exciting.
> Even though shunned by Apple and Mozilla, Web Bluetooth enjoys wide support and just works.

That’s an interesting way to say Chrome Only feature but you shouldn’t care because Mozilla ran Firefox into 3%/ground and Safari doesn’t matter.

IDK… to the point of the project… I guess that’s cool. But once you have defined and tested your GATTs, it hasn’t been my experience to come back to it a ton of times.

I just wrote unit and systems tests along with a BLE speedtest that also confirms protocol so I could run it where it matters - on different phones.

It was my experience to care more about distance, speed, interval, and MTU on actual hardware than protocol confirmation to a PC.

> But once you have defined and tested your GATTs, it hasn’t been my experience to come back to it a ton of times.

> It was my experience to care more about distance, speed, interval, and MTU on actual hardware than protocol confirmation to a PC.

That's exactly my concern, coupled with a (perceived) small pool of Bluetooth developers. Do you think there's a market for a Postman style commercial cloud product for team collaboration?

What justification is there for not implementing this across all browsers?
because there's still a huge argument about what features from the host system that the web browser should be able to deal with. Lots of people think that webusb, webserial, webbluetooth and similiar things are a security and/or privacy nightmare.
And while some argue that it's enough to put these features behind permission dialogs, browsers already have enough of those that many users will blaze through and approve anything that pops up in order to silence the noisy browser and make the page work as expected, which naturally has major implications.

That's not to say that WebUSB, WebBluetooth, etc shouldn't exist, but clearly putting everything behind dialogs doesn't scale and something better needs to be figured out.

Security.

A lot of hardware devices pretty much implicitly trust the device on the other side of the data connection, because historically anyone able to run software on a machine also has physical access to the device. This resulted in devices accepting firmware updates over Bluetooth, for example, because how else would you update the firmware?

And now with protocols like Web Bluetooth, the only thing standing between between the average user and a random website completely owning their physical hardware devices is a single "I agree" permission popup.

"B...b...b.but the bad guys might use it."

We would never have had PCs with the attitude seen in this thread.

The browser does not need to be an OS.
I really wish WebBluetooth (and WebUSB, etc) was more widely supported. It really opens the door for so many cool applications.
Unfortunately it also opens up the door for so many new exploits.

A lot of hardware has very minimal protection against attacks, because the general idea is that anyone able to run software on a machine could also just trivially physically attack the device itself. The result is that you can often update device firmware over Bluetooth or USB.

Allowing random websites to suddenly have unlimited access to poorly-secured devices is a terrible idea. Google's opinion seems to be that a permission popup is enough, but you get basically identical popups for a website wanting to send you notifications, get your current location, or completely own your physical hardware.

> you get basically identical popups for a website wanting to send you notification

Last I saw, that's not really true - you get asked for BT access in general, but then you have to directly select the device you want the site to connect to once scanning happens (site can specify basic filters to limit devices shown, but little else). Sites can't see what devices are available until you actively select the device from the browser UI, and can't just show you a 'click to give full access to BT with everything'.

> Unfortunately it also opens up the door for so many new exploits.

Put the door behind a permission the user has to explicitly activate, and if you are still concerned, add more friction to the process, or in this case, argue for a better permission system, but please do not argue for "infinite friction" (a.k.a prohibiting, banning, censoring)

If you still think we should not do this because users won't care and will accept any permission anyway, then you are arguing against the freedom of users to have control of their devices and run whatever algorithm they want on them

I use Nordic's app nRF Connect for this - last I used it it was fantastic. Nice to have alternative options though.

I agree WebBluetooth is easily the sanest way to access BLE devices. The iOS API is not too bad either but then you have to deal with Apple. The Android API is terrible, and the Android Bluetooth stack is unreliable and buggy.

>and the Android Bluetooth stack is unreliable and buggy.

It is truly the worst. Up until API level 33 (Android 13 from 2022!!!), all characteristic read/writes were memory unsafe. Now readCharacteristic is async for memory safety, but you're still expected to send a value synchronously with BluetoothGattServer#sendResponse when onCharacteristicWrite gets hit, so sending a value that's derived from any characteristic values is impossible before you fall out of scope. And notifying/indicating is just never reliable -- it just fails to work consistently device to device. And the high level API for the CCCD often doesn't work and requires you to set the 0x2902 descriptor manually.

CoreBluetooth handles BLE so elegantly and Android just botches it. Sad.

Nordic is easily the best way for BLE/ANT+, however now even they are bolting on WiFi (for non-power-limited cases). For standard profiles there's generally an example in the SDKs.
nrfconnect exposes the services, but if they arent registered with the bluetooth SIG then you won't have much more detail than the ids of characteristics and services and their data types. You won't know what the purpose of each service and characteristic is.
You can actually name them, but yeah you can't implement custom encoding/decoding logic. I don't think this thing lets you do that either though.
One thing I’ve wanted to do for end to end testing purposes is to be able to make pretend Bluetooth devices from my Mac. I’ve not seen much to suggest a simple way to do this, does anyone know of anything that I can use to make my Mac Bluetooth look like a heart rate monitor, for example?
My tool of choice for this is LightBlue. It's not fully cross platform, unfortunately, but it works great on Apple devices. (https://apps.apple.com/us/app/lightblue/id557428110)

I've also dabbled with bleno and noble for emulating and/or communicating with peripheral and central devices, respectively. (https://www.npmjs.com/package/@abandonware/bleno)

IIRC, last time I looked at this you needed special permissions to do anything outside the box with bluetooth on Apple.

It's technically straightforward on linux, or using a BBC microbit (there is example code in the Nordic SDK).

BTLE is much simpler than traditional Bluetooth. It’s just a matter of exposing GATT services with well-known IDs. If you search hard enough, you can probably find details for heart rate monitor service definitions. Then you can either programmatically expose services with those IDs or maybe find a helper app to do it for you. I used to use a free app for iPhone that did this but then they decided to start charging a paid subscription, and I can’t remember the name of it anymore.
Great stuff - and it seems you and I are a kindred spirit. For the past few years I've been building iOS and Android BLE apps/SDKs using my own GATT YML spec, and using that to generate working apps+SDKs from custom GATT profiles.

It's like magic when using an LLM to convert the spec to YML to runnable apps.

There absolutely needs to be a general consensus around defining a GATT profile. The challenge is that each company has their own way of using GATT and documenting how it works.

Is there a HID over GATT YAML?

From https://news.ycombinator.com/item?id=37522059 :

> https://github.com/DJm00n/ControllersInfo: HID profiles for Xbox 360, Xbox One, PS4, PS5, Stadia, and Switch

> "HID over GATT Profile (HOGP) 1.0" https://www.bluetooth.org/docman/handlers/downloaddoc.ashx?d...

Not yet but cool idea. Lot of profiles are reused, so it makes sense to write a yaml repository for common profiles.
I don't know about other people, but I've worked for 2 companies now that don't use numerous GATT characteristics to handle numerous operations. They use 1 characteristic with a notify handler and specify numerous operations to go over that characteristic. Discovery time is the reason for doing this. So while this ble swagger type thing might be valuable for simple devices, it might not relevant to more heavy users of ble.
I am of the opinion that a community-backed, portable library of encoders/decoders for a single L2CAP stream or notified characteristic would be far more useful than numerous "standardized" services. I often find the implementation lacking and have to implement something custom, which is nearly always easier over a single characteristic. Something in C++ or Rust would be ubiquitous enough that it could have one counterpart in firmware and another in Android/iOS/WASM. Many GATT characteristics do not handle compression or time-series data well, and there is no shim without going custom over your own characteristics. When I need something optimal, I am probably not using a standard BLE service.
Same here. One company did use a handful of GATT characteristics, but some of them still served a dozen different purposes.
Cool! I have an interesting project but it’s still waiting for Security Level 3 support in Web Bluetooth. Also Peripheral mode would be nice.
There's a lot of FUD about Web Bluetooth in here. The problem with that is Web Bluetooth isn't theoretical. It has been enabled by default since 2017. Where is the flood of predicted exploits? The fears are way overblown.
Seems to be unsupported on any iPhone browsers - I’m assuming it’s WebKit constraint?
The only mainstream browser that supports Web Bluetooth is Chrome. Maybe Apple told Google "no, don't implement that." There are good reasons for that. Web Bluetooth's usefulness is dubious, and the potential for exploits is massive.
> Web Bluetooth's usefulness is dubious,

It is very useful, I use it often. I can't think what security exploits there could be given that the user has to select the device and until they do the API can't access any devices or even scan for them.

> Web Bluetooth's usefulness is dubious

The previous commenter seems to have found a use :)

> Features

> 1. Define your GATT services in YAML.

Uh, nope, thank you.

I'll bite. What other format would you have chosen that's widely supported, easy to read and type by hand, and supports deeply nested data structures?
JSON5
YAML5: https://github.com/quasilyte/yaml5

YAML-LD w/ convenience.jsonld or dollar-convenience.jsonld: https://json-ld.github.io/yaml-ld/spec/

I mean, defining the service in some sort of universal definition format is clearly the way to go. Working with BLE across platforms is incredibly terse and error-prone. The UUIDs should only be in one file -- human eyes aren't going to notice a single-character mistake in those things.

A far-less-error prone and faster approach I've taken recently is just having two busses -- one read/write characteristic for inbound messages to the peripheral, and one r/w/notifying characteristic for inbound messages to the central. Then all messages just get defined as protocol buffers. Adding new characteristics for new functionality is a massive pain. Easier to just add new protos and use the same pipe.

I started with TOML but switched to YAML because people are familiar with OpenAPI. Ultimately everything is parsed to a Javascript object so you can have adapters in your favourite spec language.