mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-08-01 19:18:28 -04:00
bluetooth: add soft rfkill unblock, wait for adapter to become available
instead of forfeiting subscription fixes #2922 fixes #1537
This commit is contained in:
@@ -43,10 +43,10 @@ func NewManager() (*Manager, error) {
|
|||||||
broker := NewSubscriptionBroker(m.broadcastPairingPrompt)
|
broker := NewSubscriptionBroker(m.broadcastPairingPrompt)
|
||||||
m.promptBroker = broker
|
m.promptBroker = broker
|
||||||
|
|
||||||
adapter, err := m.findAdapter()
|
adapter, err := findAdapter(conn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
conn.Close()
|
conn.Close()
|
||||||
return nil, fmt.Errorf("no bluetooth adapter found: %w", err)
|
return nil, err
|
||||||
}
|
}
|
||||||
m.adapterPath = adapter
|
m.adapterPath = adapter
|
||||||
|
|
||||||
@@ -74,12 +74,12 @@ func NewManager() (*Manager, error) {
|
|||||||
return m, nil
|
return m, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Manager) findAdapter() (dbus.ObjectPath, error) {
|
func findAdapter(conn *dbus.Conn) (dbus.ObjectPath, error) {
|
||||||
obj := m.dbusConn.Object(bluezService, dbus.ObjectPath("/"))
|
obj := conn.Object(bluezService, dbus.ObjectPath("/"))
|
||||||
var objects map[dbus.ObjectPath]map[string]map[string]dbus.Variant
|
var objects map[dbus.ObjectPath]map[string]map[string]dbus.Variant
|
||||||
|
|
||||||
if err := obj.Call(objectMgrIface+".GetManagedObjects", 0).Store(&objects); err != nil {
|
if err := obj.Call(objectMgrIface+".GetManagedObjects", 0).Store(&objects); err != nil {
|
||||||
return "", err
|
return "", fmt.Errorf("%w: %v", ErrNoAdapter, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for path, interfaces := range objects {
|
for path, interfaces := range objects {
|
||||||
@@ -89,7 +89,7 @@ func (m *Manager) findAdapter() (dbus.ObjectPath, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return "", fmt.Errorf("no adapter found")
|
return "", ErrNoAdapter
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Manager) initialize() error {
|
func (m *Manager) initialize() error {
|
||||||
@@ -487,6 +487,11 @@ func (m *Manager) StopDiscovery() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *Manager) SetPowered(powered bool) error {
|
func (m *Manager) SetPowered(powered bool) error {
|
||||||
|
if powered {
|
||||||
|
if err := rfkillUnblockBluetooth(); err != nil {
|
||||||
|
log.Debugf("[BluezManager] rfkill unblock failed: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
obj := m.dbusConn.Object(bluezService, m.adapterPath)
|
obj := m.dbusConn.Object(bluezService, m.adapterPath)
|
||||||
return obj.Call(propertiesIface+".Set", 0, adapter1Iface, "Powered", dbus.MakeVariant(powered)).Err
|
return obj.Call(propertiesIface+".Set", 0, adapter1Iface, "Powered", dbus.MakeVariant(powered)).Err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package bluez
|
||||||
|
|
||||||
|
func rfkillUnblockBluetooth() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package bluez
|
||||||
|
|
||||||
|
import "os"
|
||||||
|
|
||||||
|
// linux/rfkill.h: struct rfkill_event { __u32 idx; __u8 type; __u8 op; __u8 soft; __u8 hard; },
|
||||||
|
// RFKILL_TYPE_BLUETOOTH=2, RFKILL_OP_CHANGE_ALL=3
|
||||||
|
func rfkillUnblockBluetooth() error {
|
||||||
|
f, err := os.OpenFile("/dev/rfkill", os.O_WRONLY, 0)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
var event [8]byte
|
||||||
|
event[4] = 2
|
||||||
|
event[5] = 3
|
||||||
|
_, err = f.Write(event[:])
|
||||||
|
return err
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
package bluez
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/godbus/dbus/v5"
|
||||||
|
)
|
||||||
|
|
||||||
|
var ErrNoAdapter = errors.New("no bluetooth adapter found")
|
||||||
|
|
||||||
|
func WaitForAdapter() error {
|
||||||
|
conn, err := dbus.ConnectSystemBus()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer conn.Close()
|
||||||
|
|
||||||
|
if err := conn.AddMatchSignal(
|
||||||
|
dbus.WithMatchInterface(objectMgrIface),
|
||||||
|
dbus.WithMatchMember("InterfacesAdded"),
|
||||||
|
); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
signals := make(chan *dbus.Signal, 64)
|
||||||
|
conn.Signal(signals)
|
||||||
|
|
||||||
|
if _, err := findAdapter(conn); err == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
for sig := range signals {
|
||||||
|
if sig == nil || sig.Name != objectMgrIface+".InterfacesAdded" || len(sig.Body) < 2 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
ifaces, ok := sig.Body[1].(map[string]map[string]dbus.Variant)
|
||||||
|
if !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if _, ok := ifaces[adapter1Iface]; ok {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fmt.Errorf("dbus signal stream closed")
|
||||||
|
}
|
||||||
@@ -1668,10 +1668,21 @@ func (s *Server) Serve(printDocs bool) error {
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
if err := InitializeBluezManager(); err != nil {
|
for {
|
||||||
log.Warnf("Bluez manager unavailable: %v", err)
|
err := InitializeBluezManager()
|
||||||
} else {
|
if err == nil {
|
||||||
notifyCapabilityChange()
|
notifyCapabilityChange()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
log.Warnf("Bluez manager unavailable: %v", err)
|
||||||
|
if !errors.Is(err, bluez.ErrNoAdapter) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := bluez.WaitForAdapter(); err != nil {
|
||||||
|
log.Warnf("Bluetooth adapter watch failed: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
log.Info("Bluetooth adapter appeared, initializing bluez manager")
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
|||||||
@@ -335,6 +335,7 @@ Singleton {
|
|||||||
const data = response.result.data;
|
const data = response.result.data;
|
||||||
|
|
||||||
if (service === "server") {
|
if (service === "server") {
|
||||||
|
const prevCapabilities = capabilities;
|
||||||
apiVersion = data.apiVersion || 0;
|
apiVersion = data.apiVersion || 0;
|
||||||
cliVersion = data.cliVersion || "";
|
cliVersion = data.cliVersion || "";
|
||||||
capabilities = data.capabilities || [];
|
capabilities = data.capabilities || [];
|
||||||
@@ -346,6 +347,12 @@ Singleton {
|
|||||||
}
|
}
|
||||||
|
|
||||||
capabilitiesReceived();
|
capabilitiesReceived();
|
||||||
|
|
||||||
|
const capabilitiesChanged = prevCapabilities.length !== capabilities.length || capabilities.some(c => !prevCapabilities.includes(c));
|
||||||
|
if (prevCapabilities.length > 0 && capabilitiesChanged) {
|
||||||
|
log.info("Capabilities changed, resubscribing");
|
||||||
|
subscribe(activeSubscriptions);
|
||||||
|
}
|
||||||
} else if (service === "network") {
|
} else if (service === "network") {
|
||||||
networkStateUpdate(data);
|
networkStateUpdate(data);
|
||||||
} else if (service === "network.credentials") {
|
} else if (service === "network.credentials") {
|
||||||
|
|||||||
Reference in New Issue
Block a user