File: properties_service.go

package info (click to toggle)
golang-github-muka-go-bluetooth 5.60-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 2,688 kB
  • sloc: makefile: 92; sh: 2
file content (101 lines) | stat: -rw-r--r-- 2,672 bytes parent folder | download
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
package api

import (
	"github.com/fatih/structs"
	"github.com/godbus/dbus/v5"
	"github.com/godbus/dbus/v5/introspect"
	"github.com/godbus/dbus/v5/prop"
	"github.com/muka/go-bluetooth/bluez"
	"github.com/muka/go-bluetooth/bluez/profile"
	"github.com/muka/go-bluetooth/props"
	log "github.com/sirupsen/logrus"
)

// NewDBusProperties create a new instance
func NewDBusProperties(conn *dbus.Conn) (*DBusProperties, error) {

	o := &DBusProperties{
		conn:        conn,
		props:       make(map[string]bluez.Properties),
		propsConfig: make(map[string]map[string]*props.PropInfo),
	}

	err := o.parseProperties()
	return o, err
}

// DBus Properties interface implementation
type DBusProperties struct {
	conn        *dbus.Conn
	props       map[string]bluez.Properties
	propsConfig map[string]map[string]*props.PropInfo
	instance    *prop.Properties
}

func (p *DBusProperties) parseProperties() error {
	for iface, ifaceVal := range p.props {
		if _, ok := p.propsConfig[iface]; !ok {
			p.propsConfig[iface] = make(map[string]*props.PropInfo)
		}
		p.propsConfig[iface] = props.ParseProperties(ifaceVal)
	}
	return nil
}

func (p *DBusProperties) onChange(ev *prop.Change) *dbus.Error {
	if _, ok := p.propsConfig[ev.Iface]; ok {
		if conf, ok := p.propsConfig[ev.Iface][ev.Name]; ok {
			if conf.Writable {
				log.Debugf("Set %s.%s", ev.Iface, ev.Name)
				prop := p.props[ev.Iface]
				s := structs.New(prop)
				err := s.Field(ev.Name).Set(ev.Value)
				if err != nil {
					log.Errorf("Failed to set %s.%s: %s", ev.Iface, ev.Name, err.Error())
					return &profile.ErrRejected
				}
			}
		}
	}
	return nil
}

//Instance return the props instance
func (p *DBusProperties) Instance() *prop.Properties {
	return p.instance
}

//Introspection return the props instance
func (p *DBusProperties) Introspection(iface string) []introspect.Property {
	res := p.instance.Introspection(iface)
	// log.Debug("Introspect", res)
	return res
}

//Expose expose the properties interface
func (p *DBusProperties) Expose(path dbus.ObjectPath) {
	propsConfig := make(map[string]map[string]*prop.Prop)
	for iface1, props1 := range p.propsConfig {
		propsConfig[iface1] = make(map[string]*prop.Prop)
		for k, v := range props1 {
			if v.Skip {
				continue
			}
			propsConfig[iface1][k] = &v.Prop
		}
	}

	p.instance = prop.New(p.conn, path, propsConfig)
}

//AddProperties add a property set
func (p *DBusProperties) AddProperties(iface string, props bluez.Properties) error {
	p.props[iface] = props
	return p.parseProperties()
}

//RemoveProperties remove a property set
func (p *DBusProperties) RemoveProperties(iface string) {
	delete(p.props, iface)
	delete(p.propsConfig, iface)
}