Files
pmomusic/upnp/serviceinstance.go
2025-09-06 17:45:28 +02:00

122 lines
2.8 KiB
Go

package upnp
import (
"fmt"
"net/http"
"gargoton.petite-maison-orange.fr/eric/pmomusic/upnp/devices/services/actions"
"gargoton.petite-maison-orange.fr/eric/pmomusic/upnp/devices/services/statevariables"
"github.com/beevik/etree"
log "github.com/sirupsen/logrus"
)
type ServiceInstance struct {
name string
identifier string
version int
device *DeviceInstance
statevariables statevariables.StateVarInstanceSet
actions actions.ActionInstanceSet
}
func (si *ServiceInstance) Name() string {
return si.name
}
func (svc *ServiceInstance) TypeID() string {
return "ServiceInstance"
}
func (si *ServiceInstance) Identifier() string {
return si.identifier
}
func (svc *ServiceInstance) ServiceType() string {
return fmt.Sprintf("urn:schemas-upnp-org:service:%s:%d", svc.name, svc.version)
}
func (svc *ServiceInstance) ServiceId() string {
return fmt.Sprintf("urn:upnp-org:serviceId:%s", svc.identifier)
}
func (svc *ServiceInstance) BaseRoute() string {
return fmt.Sprintf("%s/service/%s", svc.device.BaseRoute(), svc.Name())
}
func (svc *ServiceInstance) ControlURL() string {
return fmt.Sprintf("%s/control", svc.BaseRoute())
}
func (svc *ServiceInstance) EventSubURL() string {
return fmt.Sprintf("%s/event", svc.BaseRoute())
}
func (svc *ServiceInstance) SCPDURL() string {
return fmt.Sprintf("%s/desc.xml", svc.BaseRoute())
}
func (svc *ServiceInstance) RegisterURLs() error {
mux, ok := svc.device.server.httpSrv.Handler.(*http.ServeMux)
if mux == nil || !ok {
return fmt.Errorf("❌ Device %s the server handler is not correctly defined", svc.Name())
}
mux.HandleFunc(
svc.SCPDURL(),
svc.device.server.ServeXML(svc.SPCDElement),
)
log.Infof(
"✅ Service description for %s:%s available at : %s%s",
svc.device.Name(),
svc.Name(),
svc.device.server.BaseURL(),
svc.SCPDURL(),
)
return nil
}
func (svc *ServiceInstance) SPCDElement() *etree.Element {
elem := etree.NewElement("scpd")
elem.CreateAttr("xmlns", "urn:schemas-upnp-org:service-1-0")
spec := elem.CreateElement("specVersion")
spec.CreateElement("major").SetText("1")
spec.CreateElement("minor").SetText("0")
if len(svc.actions) > 0 {
elem.AddChild(svc.actions.ToXMLElement())
}
if len(svc.statevariables) > 0 {
elem.AddChild(svc.statevariables.ToXMLElement())
}
return elem
}
func (svc *ServiceInstance) ToXMLElement() *etree.Element {
elem := etree.NewElement("service")
st := elem.CreateElement("serviceType")
st.SetText(svc.ServiceType())
sid := elem.CreateElement("serviceId")
sid.SetText(svc.ServiceId())
spcd := elem.CreateElement("SCPDURL")
spcd.SetText(svc.SCPDURL())
ctrl := elem.CreateElement("controlURL")
ctrl.SetText(svc.ControlURL())
event := elem.CreateElement("eventSubURL")
event.SetText(svc.EventSubURL())
return elem
}