1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
|
package api
import (
"errors"
"github.com/godbus/dbus/v5"
"github.com/muka/go-bluetooth/bluez"
"github.com/muka/go-bluetooth/bluez/profile"
log "github.com/sirupsen/logrus"
)
// NewDBusObjectManager create a new instance
func NewDBusObjectManager(conn *dbus.Conn) (*DBusObjectManager, error) {
o := &DBusObjectManager{
conn: conn,
objects: make(map[dbus.ObjectPath]map[string]bluez.Properties),
}
return o, nil
}
// DBusObjectManager interface implementation
type DBusObjectManager struct {
conn *dbus.Conn
objects map[dbus.ObjectPath]map[string]bluez.Properties
}
// SignalAdded notify of interfaces being added
func (o *DBusObjectManager) SignalAdded(path dbus.ObjectPath) error {
props, err := o.GetManagedObject(path)
if err != nil {
return err
}
return o.conn.Emit(path, bluez.InterfacesAdded, props)
}
// SignalRemoved notify of interfaces being removed
func (o *DBusObjectManager) SignalRemoved(path dbus.ObjectPath, ifaces []string) error {
if ifaces == nil {
ifaces = make([]string, 0)
}
return o.conn.Emit(path, bluez.InterfacesRemoved, ifaces)
}
// GetManagedObject return an up to date view of a single object state
func (o *DBusObjectManager) GetManagedObject(objpath dbus.ObjectPath) (map[string]map[string]dbus.Variant, error) {
props, err := o.GetManagedObjects()
if err != nil {
return nil, err
}
if p, ok := props[objpath]; ok {
return p, nil
}
return nil, errors.New("Object not found")
}
// GetManagedObjects return an up to date view of the object state
func (o *DBusObjectManager) GetManagedObjects() (map[dbus.ObjectPath]map[string]map[string]dbus.Variant, *dbus.Error) {
props := make(map[dbus.ObjectPath]map[string]map[string]dbus.Variant)
for path, ifs := range o.objects {
if _, ok := props[path]; !ok {
props[path] = make(map[string]map[string]dbus.Variant)
}
for i, m := range ifs {
if _, ok := props[path][i]; !ok {
props[path][i] = make(map[string]dbus.Variant)
}
l, err := m.ToMap()
if err != nil {
log.Errorf("Failed to serialize properties: %s", err.Error())
return nil, &profile.ErrInvalidArguments
}
for k, v := range l {
vrt := dbus.MakeVariant(v)
props[path][i][k] = vrt
}
}
}
log.Tracef("ObjectManager.GetManagedObjects \n %v", props)
return props, nil
}
//AddObject add an object to the list
func (o *DBusObjectManager) AddObject(path dbus.ObjectPath, val map[string]bluez.Properties) error {
log.Tracef("ObjectManager.AddObject: %s", path)
o.objects[path] = val
return o.SignalAdded(path)
}
//RemoveObject remove an object from the list
func (o *DBusObjectManager) RemoveObject(path dbus.ObjectPath) error {
log.Tracef("ObjectManager.RemoveObject: %s", path)
if s, ok := o.objects[path]; ok {
delete(o.objects, path)
ifaces := make([]string, len(s))
for i := range s {
ifaces = append(ifaces, i)
}
return o.SignalRemoved(path, ifaces)
}
return nil
}
|