2022-02-22 13:04:20 +03:00
|
|
|
//go:build !baremetal
|
2019-11-09 17:55:38 +03:00
|
|
|
|
2020-06-11 16:51:24 +03:00
|
|
|
// Some documentation for the BlueZ D-Bus interface:
|
|
|
|
// https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc
|
|
|
|
|
2019-11-09 17:55:38 +03:00
|
|
|
package bluetooth
|
|
|
|
|
|
|
|
import (
|
2021-11-02 01:35:48 +03:00
|
|
|
"errors"
|
2024-01-02 14:51:05 +03:00
|
|
|
"fmt"
|
2021-11-02 01:35:48 +03:00
|
|
|
|
2024-01-02 14:51:05 +03:00
|
|
|
"github.com/godbus/dbus/v5"
|
2019-11-09 17:55:38 +03:00
|
|
|
)
|
|
|
|
|
2024-01-02 14:51:05 +03:00
|
|
|
const defaultAdapter = "hci0"
|
|
|
|
|
2019-11-09 17:55:38 +03:00
|
|
|
type Adapter struct {
|
2020-06-01 19:04:03 +03:00
|
|
|
id string
|
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
|
2020-06-01 19:04:03 +03:00
|
|
|
defaultAdvertisement *Advertisement
|
2020-09-10 18:17:45 +03:00
|
|
|
|
2023-04-25 03:12:05 +03:00
|
|
|
connectHandler func(device Address, connected bool)
|
2019-11-09 17:55:38 +03:00
|
|
|
}
|
|
|
|
|
2020-06-01 14:26:45 +03:00
|
|
|
// 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.
|
2020-09-10 18:17:45 +03:00
|
|
|
var DefaultAdapter = &Adapter{
|
2024-01-02 14:51:05 +03:00
|
|
|
id: defaultAdapter,
|
2023-04-25 03:12:05 +03:00
|
|
|
connectHandler: func(device Address, connected bool) {
|
2020-09-10 18:17:45 +03:00
|
|
|
},
|
|
|
|
}
|
2019-11-09 17:55:38 +03:00
|
|
|
|
|
|
|
// Enable configures the BLE stack. It must be called before any
|
|
|
|
// Bluetooth-related calls (unless otherwise indicated).
|
2020-06-01 14:26:45 +03:00
|
|
|
func (a *Adapter) Enable() (err error) {
|
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())
|
2020-06-01 14:26:45 +03:00
|
|
|
}
|
2024-01-02 14:51:05 +03:00
|
|
|
return fmt.Errorf("could not activate BlueZ adapter: %w", err)
|
2020-06-01 14:26:45 +03:00
|
|
|
}
|
2024-01-02 14:51:05 +03:00
|
|
|
addr.Store(&a.address)
|
|
|
|
|
2019-11-09 17:55:38 +03:00
|
|
|
return nil
|
|
|
|
}
|
2021-11-02 01:35:48 +03:00
|
|
|
|
|
|
|
func (a *Adapter) Address() (MACAddress, error) {
|
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")
|
|
|
|
}
|
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
|
|
|
|
}
|