bluetooth/adapter_linux.go

71 lines
1.9 KiB
Go
Raw Permalink Normal View History

//go:build !baremetal
// Some documentation for the BlueZ D-Bus interface:
// https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc
package bluetooth
import (
2021-11-02 01:35:48 +03:00
"errors"
linux: rewrite everything to use DBus directly This is a big rewrite to use DBus calls directly instead of going through go-bluetooth first. This is a big change, but I believe it is an improvement. While the go-bluetooth works for many cases, it's a layer in between that I believe hurts more than it helps. Without it, we can just program directly against the BlueZ D-Bus API. The end result is about 10% more code. With this rewrite, I fixed the following issues: * All MapToStruct warnings are gone, like in https://github.com/tinygo-org/bluetooth/issues/193. * Advertisements can be restarted after they were stopped. Previously this resulted in a panic. * Looking at the source code of go-bluetooth, it appears that it includes devices from a different Bluetooth adapter than the one that's currently scanning. This is fixed with the rewrite. * Fix a bug in Adapter.AddService where it would only allow adding a single service. Multiple services can now be added. This was actually the motivating bug that led me down to rewrite the whole thing because I couldn't figure out where the bug was in go-bluetooth (it's many layers deep). * The `WriteEvent` callback in a characteristic now also gets the 'offset' parameter which wasn't provided by go-bluetooth. This rewrite also avoids go-bluetooth specific workarounds like https://github.com/tinygo-org/bluetooth/pull/74 and https://github.com/tinygo-org/bluetooth/pull/121. I have tested all examples in the smoketest-linux Makefile target. They all still work with this rewrite.
2024-01-02 14:51:05 +03:00
"fmt"
2021-11-02 01:35:48 +03:00
linux: rewrite everything to use DBus directly This is a big rewrite to use DBus calls directly instead of going through go-bluetooth first. This is a big change, but I believe it is an improvement. While the go-bluetooth works for many cases, it's a layer in between that I believe hurts more than it helps. Without it, we can just program directly against the BlueZ D-Bus API. The end result is about 10% more code. With this rewrite, I fixed the following issues: * All MapToStruct warnings are gone, like in https://github.com/tinygo-org/bluetooth/issues/193. * Advertisements can be restarted after they were stopped. Previously this resulted in a panic. * Looking at the source code of go-bluetooth, it appears that it includes devices from a different Bluetooth adapter than the one that's currently scanning. This is fixed with the rewrite. * Fix a bug in Adapter.AddService where it would only allow adding a single service. Multiple services can now be added. This was actually the motivating bug that led me down to rewrite the whole thing because I couldn't figure out where the bug was in go-bluetooth (it's many layers deep). * The `WriteEvent` callback in a characteristic now also gets the 'offset' parameter which wasn't provided by go-bluetooth. This rewrite also avoids go-bluetooth specific workarounds like https://github.com/tinygo-org/bluetooth/pull/74 and https://github.com/tinygo-org/bluetooth/pull/121. I have tested all examples in the smoketest-linux Makefile target. They all still work with this rewrite.
2024-01-02 14:51:05 +03:00
"github.com/godbus/dbus/v5"
)
linux: rewrite everything to use DBus directly This is a big rewrite to use DBus calls directly instead of going through go-bluetooth first. This is a big change, but I believe it is an improvement. While the go-bluetooth works for many cases, it's a layer in between that I believe hurts more than it helps. Without it, we can just program directly against the BlueZ D-Bus API. The end result is about 10% more code. With this rewrite, I fixed the following issues: * All MapToStruct warnings are gone, like in https://github.com/tinygo-org/bluetooth/issues/193. * Advertisements can be restarted after they were stopped. Previously this resulted in a panic. * Looking at the source code of go-bluetooth, it appears that it includes devices from a different Bluetooth adapter than the one that's currently scanning. This is fixed with the rewrite. * Fix a bug in Adapter.AddService where it would only allow adding a single service. Multiple services can now be added. This was actually the motivating bug that led me down to rewrite the whole thing because I couldn't figure out where the bug was in go-bluetooth (it's many layers deep). * The `WriteEvent` callback in a characteristic now also gets the 'offset' parameter which wasn't provided by go-bluetooth. This rewrite also avoids go-bluetooth specific workarounds like https://github.com/tinygo-org/bluetooth/pull/74 and https://github.com/tinygo-org/bluetooth/pull/121. I have tested all examples in the smoketest-linux Makefile target. They all still work with this rewrite.
2024-01-02 14:51:05 +03:00
const defaultAdapter = "hci0"
type Adapter struct {
id string
linux: rewrite everything to use DBus directly This is a big rewrite to use DBus calls directly instead of going through go-bluetooth first. This is a big change, but I believe it is an improvement. While the go-bluetooth works for many cases, it's a layer in between that I believe hurts more than it helps. Without it, we can just program directly against the BlueZ D-Bus API. The end result is about 10% more code. With this rewrite, I fixed the following issues: * All MapToStruct warnings are gone, like in https://github.com/tinygo-org/bluetooth/issues/193. * Advertisements can be restarted after they were stopped. Previously this resulted in a panic. * Looking at the source code of go-bluetooth, it appears that it includes devices from a different Bluetooth adapter than the one that's currently scanning. This is fixed with the rewrite. * Fix a bug in Adapter.AddService where it would only allow adding a single service. Multiple services can now be added. This was actually the motivating bug that led me down to rewrite the whole thing because I couldn't figure out where the bug was in go-bluetooth (it's many layers deep). * The `WriteEvent` callback in a characteristic now also gets the 'offset' parameter which wasn't provided by go-bluetooth. This rewrite also avoids go-bluetooth specific workarounds like https://github.com/tinygo-org/bluetooth/pull/74 and https://github.com/tinygo-org/bluetooth/pull/121. I have tested all examples in the smoketest-linux Makefile target. They all still work with this rewrite.
2024-01-02 14:51:05 +03:00
scanCancelChan chan struct{}
bus *dbus.Conn
bluez dbus.BusObject // object at /
adapter dbus.BusObject // object at /org/bluez/hciX
address string
defaultAdvertisement *Advertisement
connectHandler func(device Device, connected bool)
}
// DefaultAdapter is the default adapter on the system. On Linux, it is the
// first adapter available.
//
// Make sure to call Enable() before using it to initialize the adapter.
var DefaultAdapter = &Adapter{
linux: rewrite everything to use DBus directly This is a big rewrite to use DBus calls directly instead of going through go-bluetooth first. This is a big change, but I believe it is an improvement. While the go-bluetooth works for many cases, it's a layer in between that I believe hurts more than it helps. Without it, we can just program directly against the BlueZ D-Bus API. The end result is about 10% more code. With this rewrite, I fixed the following issues: * All MapToStruct warnings are gone, like in https://github.com/tinygo-org/bluetooth/issues/193. * Advertisements can be restarted after they were stopped. Previously this resulted in a panic. * Looking at the source code of go-bluetooth, it appears that it includes devices from a different Bluetooth adapter than the one that's currently scanning. This is fixed with the rewrite. * Fix a bug in Adapter.AddService where it would only allow adding a single service. Multiple services can now be added. This was actually the motivating bug that led me down to rewrite the whole thing because I couldn't figure out where the bug was in go-bluetooth (it's many layers deep). * The `WriteEvent` callback in a characteristic now also gets the 'offset' parameter which wasn't provided by go-bluetooth. This rewrite also avoids go-bluetooth specific workarounds like https://github.com/tinygo-org/bluetooth/pull/74 and https://github.com/tinygo-org/bluetooth/pull/121. I have tested all examples in the smoketest-linux Makefile target. They all still work with this rewrite.
2024-01-02 14:51:05 +03:00
id: defaultAdapter,
connectHandler: func(device Device, connected bool) {
},
}
// Enable configures the BLE stack. It must be called before any
// Bluetooth-related calls (unless otherwise indicated).
func (a *Adapter) Enable() (err error) {
linux: rewrite everything to use DBus directly This is a big rewrite to use DBus calls directly instead of going through go-bluetooth first. This is a big change, but I believe it is an improvement. While the go-bluetooth works for many cases, it's a layer in between that I believe hurts more than it helps. Without it, we can just program directly against the BlueZ D-Bus API. The end result is about 10% more code. With this rewrite, I fixed the following issues: * All MapToStruct warnings are gone, like in https://github.com/tinygo-org/bluetooth/issues/193. * Advertisements can be restarted after they were stopped. Previously this resulted in a panic. * Looking at the source code of go-bluetooth, it appears that it includes devices from a different Bluetooth adapter than the one that's currently scanning. This is fixed with the rewrite. * Fix a bug in Adapter.AddService where it would only allow adding a single service. Multiple services can now be added. This was actually the motivating bug that led me down to rewrite the whole thing because I couldn't figure out where the bug was in go-bluetooth (it's many layers deep). * The `WriteEvent` callback in a characteristic now also gets the 'offset' parameter which wasn't provided by go-bluetooth. This rewrite also avoids go-bluetooth specific workarounds like https://github.com/tinygo-org/bluetooth/pull/74 and https://github.com/tinygo-org/bluetooth/pull/121. I have tested all examples in the smoketest-linux Makefile target. They all still work with this rewrite.
2024-01-02 14:51:05 +03:00
bus, err := dbus.SystemBus()
if err != nil {
return err
}
a.bus = bus
a.bluez = a.bus.Object("org.bluez", dbus.ObjectPath("/"))
a.adapter = a.bus.Object("org.bluez", dbus.ObjectPath("/org/bluez/"+a.id))
addr, err := a.adapter.GetProperty("org.bluez.Adapter1.Address")
if err != nil {
if err, ok := err.(dbus.Error); ok && err.Name == "org.freedesktop.DBus.Error.UnknownObject" {
return fmt.Errorf("bluetooth: adapter %s does not exist", a.adapter.Path())
}
linux: rewrite everything to use DBus directly This is a big rewrite to use DBus calls directly instead of going through go-bluetooth first. This is a big change, but I believe it is an improvement. While the go-bluetooth works for many cases, it's a layer in between that I believe hurts more than it helps. Without it, we can just program directly against the BlueZ D-Bus API. The end result is about 10% more code. With this rewrite, I fixed the following issues: * All MapToStruct warnings are gone, like in https://github.com/tinygo-org/bluetooth/issues/193. * Advertisements can be restarted after they were stopped. Previously this resulted in a panic. * Looking at the source code of go-bluetooth, it appears that it includes devices from a different Bluetooth adapter than the one that's currently scanning. This is fixed with the rewrite. * Fix a bug in Adapter.AddService where it would only allow adding a single service. Multiple services can now be added. This was actually the motivating bug that led me down to rewrite the whole thing because I couldn't figure out where the bug was in go-bluetooth (it's many layers deep). * The `WriteEvent` callback in a characteristic now also gets the 'offset' parameter which wasn't provided by go-bluetooth. This rewrite also avoids go-bluetooth specific workarounds like https://github.com/tinygo-org/bluetooth/pull/74 and https://github.com/tinygo-org/bluetooth/pull/121. I have tested all examples in the smoketest-linux Makefile target. They all still work with this rewrite.
2024-01-02 14:51:05 +03:00
return fmt.Errorf("could not activate BlueZ adapter: %w", err)
}
linux: rewrite everything to use DBus directly This is a big rewrite to use DBus calls directly instead of going through go-bluetooth first. This is a big change, but I believe it is an improvement. While the go-bluetooth works for many cases, it's a layer in between that I believe hurts more than it helps. Without it, we can just program directly against the BlueZ D-Bus API. The end result is about 10% more code. With this rewrite, I fixed the following issues: * All MapToStruct warnings are gone, like in https://github.com/tinygo-org/bluetooth/issues/193. * Advertisements can be restarted after they were stopped. Previously this resulted in a panic. * Looking at the source code of go-bluetooth, it appears that it includes devices from a different Bluetooth adapter than the one that's currently scanning. This is fixed with the rewrite. * Fix a bug in Adapter.AddService where it would only allow adding a single service. Multiple services can now be added. This was actually the motivating bug that led me down to rewrite the whole thing because I couldn't figure out where the bug was in go-bluetooth (it's many layers deep). * The `WriteEvent` callback in a characteristic now also gets the 'offset' parameter which wasn't provided by go-bluetooth. This rewrite also avoids go-bluetooth specific workarounds like https://github.com/tinygo-org/bluetooth/pull/74 and https://github.com/tinygo-org/bluetooth/pull/121. I have tested all examples in the smoketest-linux Makefile target. They all still work with this rewrite.
2024-01-02 14:51:05 +03:00
addr.Store(&a.address)
return nil
}
2021-11-02 01:35:48 +03:00
func (a *Adapter) Address() (MACAddress, error) {
linux: rewrite everything to use DBus directly This is a big rewrite to use DBus calls directly instead of going through go-bluetooth first. This is a big change, but I believe it is an improvement. While the go-bluetooth works for many cases, it's a layer in between that I believe hurts more than it helps. Without it, we can just program directly against the BlueZ D-Bus API. The end result is about 10% more code. With this rewrite, I fixed the following issues: * All MapToStruct warnings are gone, like in https://github.com/tinygo-org/bluetooth/issues/193. * Advertisements can be restarted after they were stopped. Previously this resulted in a panic. * Looking at the source code of go-bluetooth, it appears that it includes devices from a different Bluetooth adapter than the one that's currently scanning. This is fixed with the rewrite. * Fix a bug in Adapter.AddService where it would only allow adding a single service. Multiple services can now be added. This was actually the motivating bug that led me down to rewrite the whole thing because I couldn't figure out where the bug was in go-bluetooth (it's many layers deep). * The `WriteEvent` callback in a characteristic now also gets the 'offset' parameter which wasn't provided by go-bluetooth. This rewrite also avoids go-bluetooth specific workarounds like https://github.com/tinygo-org/bluetooth/pull/74 and https://github.com/tinygo-org/bluetooth/pull/121. I have tested all examples in the smoketest-linux Makefile target. They all still work with this rewrite.
2024-01-02 14:51:05 +03:00
if a.address == "" {
2021-11-02 01:35:48 +03:00
return MACAddress{}, errors.New("adapter not enabled")
}
linux: rewrite everything to use DBus directly This is a big rewrite to use DBus calls directly instead of going through go-bluetooth first. This is a big change, but I believe it is an improvement. While the go-bluetooth works for many cases, it's a layer in between that I believe hurts more than it helps. Without it, we can just program directly against the BlueZ D-Bus API. The end result is about 10% more code. With this rewrite, I fixed the following issues: * All MapToStruct warnings are gone, like in https://github.com/tinygo-org/bluetooth/issues/193. * Advertisements can be restarted after they were stopped. Previously this resulted in a panic. * Looking at the source code of go-bluetooth, it appears that it includes devices from a different Bluetooth adapter than the one that's currently scanning. This is fixed with the rewrite. * Fix a bug in Adapter.AddService where it would only allow adding a single service. Multiple services can now be added. This was actually the motivating bug that led me down to rewrite the whole thing because I couldn't figure out where the bug was in go-bluetooth (it's many layers deep). * The `WriteEvent` callback in a characteristic now also gets the 'offset' parameter which wasn't provided by go-bluetooth. This rewrite also avoids go-bluetooth specific workarounds like https://github.com/tinygo-org/bluetooth/pull/74 and https://github.com/tinygo-org/bluetooth/pull/121. I have tested all examples in the smoketest-linux Makefile target. They all still work with this rewrite.
2024-01-02 14:51:05 +03:00
mac, err := ParseMAC(a.address)
2021-11-02 01:35:48 +03:00
if err != nil {
return MACAddress{}, err
}
return MACAddress{MAC: mac}, nil
}