cert renew

This commit is contained in:
kaedwen
2023-07-18 19:43:19 +02:00
parent 3a6fae5bf2
commit 18a99b3715
40 changed files with 122 additions and 8296 deletions
+1 -1
View File
@@ -1,2 +1,2 @@
service*
cert
renew.local.env
+1 -1
View File
@@ -12,7 +12,7 @@
"program": "${workspaceFolder}/main.go",
"env": {
"HTTP_STATIC": "${workspaceFolder}/static/dist",
"VIDEO_OUT_DEVICE": "/dev/video4",
//"VIDEO_OUT_DEVICE": "/dev/video4",
"AUDIO_OUT_DEVICE": "plughw:0,1,0",
"INPUT_DEVICE": "/dev/input/event5",
"JINGLE_PATH": "${workspaceFolder}/audio",
+1
View File
@@ -3,6 +3,7 @@ build:
build-static:
npm --prefix static ci && npm --prefix static run build
cp -r audio static/dist/audio
build-armhf:
GOARCH=arm \
+5
View File
@@ -0,0 +1,5 @@
HTTPREQ_ENDPOINT=<your httpreq endpoint>
ACME_KID=<your acme kid>
ACME_HMAC=<your acme hmac>
ACME_DOMAINS=<your domain>
ACME_EMAIL=<your email>
+10
View File
@@ -0,0 +1,10 @@
[Unit]
Description=Renew certificate
[Service]
Type=simple
EnvironmentFile=/etc/ring/renew.env
ExecStart=/usr/local/bin/renew.sh
[Install]
WantedBy=multi-user.target
+13
View File
@@ -0,0 +1,13 @@
#!/bin/sh
set +x
lego --path "/etc/ldap/cert" --email "${ACME_EMAIL}" --server "https://acme.zerossl.com/v2/DV90" --accept-tos --eab \
--kid "${ACME_KID}" \
--hmac "${ACME_HMAC}" \
--key-type "rsa4096" \
--dns "httpreq" \
--domains "${ACME_DOMAINS}" \
--pem \
renew \
--renew-hook="systemctl restart ring"
+10
View File
@@ -0,0 +1,10 @@
[Unit]
Description=Renew certificate
[Timer]
Persistent=true
OnCalendar=*-*-* 3:35
RandomizedDelaySec=1h
[Install]
WantedBy=timers.target
+1 -3
View File
@@ -5,12 +5,11 @@ go 1.20
require (
github.com/alexflint/go-arg v1.4.3
github.com/gin-gonic/gin v1.9.1
github.com/google/uuid v1.3.0
github.com/hashicorp/mdns v1.0.5
github.com/holoplot/go-evdev v0.0.0-20230626094006-70c9462cc0f2
github.com/ianr0bkny/go-sonos v0.0.0-20171025003233-056585059953
github.com/pion/rtcp v1.2.10
github.com/pion/webrtc/v3 v3.2.10
github.com/szatmary/sonos v0.0.0-20191204204454-000c9219ff0e
github.com/tinyzimmer/go-glib v0.0.25
github.com/tinyzimmer/go-gst v0.2.33
go.uber.org/zap v1.24.0
@@ -28,7 +27,6 @@ require (
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.14.1 // indirect
github.com/goccy/go-json v0.10.2 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/compress v1.10.3 // indirect
github.com/klauspost/cpuid/v2 v2.2.5 // indirect
-4
View File
@@ -68,8 +68,6 @@ github.com/hashicorp/mdns v1.0.5/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/
github.com/holoplot/go-evdev v0.0.0-20230626094006-70c9462cc0f2 h1:bxudnRpvfq2PMYEYN7VGj03+MXG4EobVUmONigCx1yA=
github.com/holoplot/go-evdev v0.0.0-20230626094006-70c9462cc0f2/go.mod h1:iHAf8OIncO2gcQ8XOjS7CMJ2aPbX2Bs0wl5pZyanEqk=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/ianr0bkny/go-sonos v0.0.0-20171025003233-056585059953 h1:n9vfPPfv66b56toxNZk/w7VPSZ5eK/NxVrtRs1uptzo=
github.com/ianr0bkny/go-sonos v0.0.0-20171025003233-056585059953/go.mod h1:uvzy1yuMP2e76h67o5rpaXPDPq4e/cUGU4RYkm9a0Js=
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
@@ -168,8 +166,6 @@ github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/szatmary/sonos v0.0.0-20191204204454-000c9219ff0e h1:beo21nzzdqCVGe6EdG3Lo3UbU7meQN4JjAAeyZccH94=
github.com/szatmary/sonos v0.0.0-20191204204454-000c9219ff0e/go.mod h1:F5m1XEgf251EShYE9r+2Rl45NPLGovXttfuAjBb93bY=
github.com/tinyzimmer/go-glib v0.0.25 h1:2GpumtkxA0wpXhCXP6D3ksb5pGMfo9WbhgLvEw8njK4=
github.com/tinyzimmer/go-glib v0.0.25/go.mod h1:ltV0gO6xNFzZhsIRbFXv8RTq9NGoNT2dmAER4YmZfaM=
github.com/tinyzimmer/go-gst v0.2.33 h1:wdwUYoN7dkWGUTrZIgB9Mp5LMRr/Sld5PVGRsE7/O9s=
+13 -11
View File
@@ -27,12 +27,12 @@ type ConfigLogging struct {
}
type ConfigRing struct {
Device string `arg:"--input-device,env:INPUT_DEVICE" default:"/dev/input/by-path/platform-gpio-keys-user-event"`
Key string `arg:"--ring-key" default:"KEY_F1"`
JingleName string `arg:"--jingle-name,env:JINGLE_NAME" default:"ding-dong.wav"`
JinglePath *string `arg:"--jingle-path,env:JINGLE_PATH"`
SonosTarget string `arg:"--sonos-target,env:SONOS_TARGET" default:"-"`
SonosVolume int `arg:"--sonos-volume,env:SONOS_VOLUME" default:"50"`
Device *string `arg:"--input-device,env:INPUT_DEVICE"`
Key string `arg:"--ring-key" default:"KEY_F1"`
JingleBaseUri *string `arg:"--jingle-base-uri,env:JINGLE_BASE_URI"`
JinglePath string `arg:"--jingle-path,env:JINGLE_PATH" default:"audio/ding-dong.wav"`
SonosTarget string `arg:"--sonos-target,env:SONOS_TARGET" default:"-"`
SonosVolume int `arg:"--sonos-volume,env:SONOS_VOLUME" default:"50"`
}
type ConfigHTTP struct {
@@ -47,11 +47,12 @@ type ConfigHTTP struct {
}
type ConfigVideoOutputStream struct {
Source string `arg:"--video-out-src,env:VIDEO_OUT_SRC" default:"v4l2src"`
Device string `arg:"--video-out-device,env:VIDEO_OUT_DEVICE" default:"/dev/video0"`
Codec string `arg:"--video-out-codec,env:VIDEO_OUT_CODEC" default:"vp8"`
Height uint `arg:"--video-out-height,env:VIDEO_OUT_HEIGHT" default:"480"`
Width uint `arg:"--video-out-width,env:VIDEO_OUT_WIDTH" default:"640"`
Source string `arg:"--video-out-src,env:VIDEO_OUT_SRC" default:"v4l2src"`
Device string `arg:"--video-out-device,env:VIDEO_OUT_DEVICE" default:"/dev/video0"`
Codec string `arg:"--video-out-codec,env:VIDEO_OUT_CODEC" default:"vp8"`
Height uint `arg:"--video-out-height,env:VIDEO_OUT_HEIGHT" default:"480"`
Width uint `arg:"--video-out-width,env:VIDEO_OUT_WIDTH" default:"640"`
USE_QUEUE bool `arg:"--video-out-queue,env:VIDEO_OUT_QUEUE" default:"false"`
}
type ConfigAudioOutputStream struct {
@@ -60,6 +61,7 @@ type ConfigAudioOutputStream struct {
Device *string `arg:"--audio-out-device,env:AUDIO_OUT_DEVICE"`
Codec string `arg:"--audio-out-codec,env:AUDIO_OUT_CODEC" default:"opus"`
Channels uint `arg:"--audio-out-channels,env:AUDIO_OUT_CHANNELS" default:"1"`
USE_QUEUE bool `arg:"--audio-out-queue,env:AUDIO_OUT_QUEUE" default:"false"`
}
type ConfigAudioInputStream struct {
+15 -5
View File
@@ -32,13 +32,23 @@ func NewRingHandler(lg *zap.Logger, cfg *common.ConfigRing) (*RingHandler, error
}
func (h *RingHandler) Watch(ctx context.Context) error {
if h.cfg.Device == nil {
h.lg.Warn("nothing to watch for key press")
return nil
}
if h.cfg.JingleBaseUri == nil {
h.lg.Warn("missing jingle base uri, nothing to play")
return nil
}
for _, p := range h.playHandlers {
if err := p.Watch(ctx); err != nil {
return err
}
}
d, err := evdev.Open(h.cfg.Device)
d, err := evdev.Open(*h.cfg.Device)
if err != nil {
return err
}
@@ -48,9 +58,9 @@ func (h *RingHandler) Watch(ctx context.Context) error {
key := evdev.KEYFromString[h.cfg.Key]
bu := url.URL{
Scheme: "http",
Host: "192.168.60.141:9099",
bu, err := url.Parse(*h.cfg.JingleBaseUri)
if err != nil {
return err
}
go func() {
@@ -62,7 +72,7 @@ func (h *RingHandler) Watch(ctx context.Context) error {
for {
e, err := d.ReadOne()
if err == nil && e.Code == key && e.Value == 0 {
tu := bu.JoinPath(h.cfg.JingleName)
tu := bu.JoinPath(h.cfg.JinglePath)
for _, p := range h.playHandlers {
if err := p.Play(tu); err != nil {
h.lg.Error("failed to play", zap.Error(err))
+3
View File
@@ -43,6 +43,7 @@ type sonosInfo struct {
type sonosAudioClip struct {
Name string `json:"name"`
AppId string `json:"appId"`
ClipType string `json:"clipType,omitempty"`
StreamUrl string `json:"streamUrl"`
Volume int `json:"volume"`
}
@@ -108,6 +109,7 @@ func (p *SonosPlayer) Play(uri *url.URL, volume int) error {
sab := sonosAudioClip{
Name: "Pull Bell",
AppId: "com.acme.app",
ClipType: "CHIME",
StreamUrl: uri.String(),
Volume: volume,
}
@@ -181,6 +183,7 @@ func (h *SonosHandler) Watch(ctx context.Context) error {
func (h *SonosHandler) Play(uri *url.URL) error {
for _, p := range h.players {
h.lg.Info("playing clip", zap.String("target", p.address.String()), zap.String("clip", uri.String()))
if err := p.Play(uri, h.cfg.SonosVolume); err != nil {
h.lg.Error("failed to play", zap.String("address", p.address.String()), zap.Error(err))
}
+18
View File
@@ -71,6 +71,15 @@ func CreateVideoPipelineSink(s StreamElement) (*gst.Pipeline, <-chan media.Sampl
}
elems = append(elems, conv)
if s.Queue {
// add a queue
queue, err := gst.NewElement("queue")
if err != nil {
return nil, nil, err
}
elems = append(elems, queue)
}
// Create the enc
enc, err := gst.NewElement("vp8enc")
if err != nil {
@@ -140,6 +149,15 @@ func CreateAudioPipelineSink(s StreamElement) (*gst.Pipeline, <-chan media.Sampl
}
elems = append(elems, conv)
if s.Queue {
// add a queue
queue, err := gst.NewElement("queue")
if err != nil {
return nil, nil, err
}
elems = append(elems, queue)
}
// Create the enc
enc, err := gst.NewElement("opusenc")
if err != nil {
+1
View File
@@ -30,6 +30,7 @@ type StreamElement struct {
Kind string
Properties map[string]interface{}
Caps *StreamElementCaps
Queue bool
}
func (se StreamElement) ToGstCaps() *gst.Caps {
+30 -6
View File
@@ -2,6 +2,8 @@ package webrtc
import (
"context"
"errors"
"io"
"sync"
"time"
@@ -121,6 +123,7 @@ func (wh *WebrtcHandler) handleAudioSamples(ctx context.Context, cfg *common.Con
Channels: cfg.Channels,
Rate: 48000,
},
Queue: cfg.USE_QUEUE,
}
var err error
@@ -164,6 +167,7 @@ func (wh *WebrtcHandler) handleVideoSamples(ctx context.Context, cfg *common.Con
Width: cfg.Width,
Height: cfg.Height,
},
Queue: cfg.USE_QUEUE,
}
var err error
@@ -195,7 +199,7 @@ func (wh *WebrtcHandler) handleVideoSamples(ctx context.Context, cfg *common.Con
return nil
}
func (wh *WebrtcHandler) createPeerHandle(ctx context.Context, sh *server.SignalingHandle) error {
func (wh *WebrtcHandler) createPeerHandle(rctx context.Context, sh *server.SignalingHandle) error {
wh.mu.Lock()
defer wh.mu.Unlock()
@@ -210,6 +214,9 @@ func (wh *WebrtcHandler) createPeerHandle(ctx context.Context, sh *server.Signal
return err
}
// create a context for this handle
hctx, hcancel := context.WithCancel(rctx)
// Set a handler for when a new remote track starts, this handler creates a gstreamer pipeline
// for the given codec
peerConnection.OnTrack(func(track *webrtc.TrackRemote, receiver *webrtc.RTPReceiver) {
@@ -227,9 +234,13 @@ func (wh *WebrtcHandler) createPeerHandle(ctx context.Context, sh *server.Signal
select {
case <-ticker.C:
if err := peerConnection.WriteRTCP([]rtcp.Packet{&rtcp.PictureLossIndication{MediaSSRC: uint32(track.SSRC())}}); err != nil {
if errors.Is(err, io.ErrClosedPipe) {
return
}
wh.lg.Error("failed to send PLI", zap.Error(err))
}
case <-ctx.Done():
case <-hctx.Done():
return
}
}
@@ -240,18 +251,24 @@ func (wh *WebrtcHandler) createPeerHandle(ctx context.Context, sh *server.Signal
})
if err != nil {
wh.lg.Error("failed to create src pipeline", zap.Error(err))
return
}
pipeline.Start()
buf := make([]byte, 1400)
for {
i, _, readErr := track.Read(buf)
n, _, readErr := track.Read(buf)
if readErr != nil {
if errors.Is(readErr, io.EOF) {
return
}
wh.lg.Error("read failed", zap.Error(err))
continue
}
if i > 0 {
pipeline.Push(buf[:i])
if n > 0 {
err := pipeline.Push(buf[:n])
if err != nil {
wh.lg.Error("push failed", zap.Error(err))
}
@@ -266,10 +283,17 @@ func (wh *WebrtcHandler) createPeerHandle(ctx context.Context, sh *server.Signal
if connectionState == webrtc.ICEConnectionStateDisconnected {
peerConnection.Close()
hcancel()
// remove this handle
wh.mu.Lock()
delete(wh.peerHandles, sh.Id)
if len(wh.peerHandles) == 0 {
wh.stopPipelines()
}
wh.mu.Unlock()
}
})
@@ -354,7 +378,7 @@ func (wh *WebrtcHandler) createPeerHandle(ctx context.Context, sh *server.Signal
if err != nil {
wh.lg.Error("failed to handle offer", zap.Error(err))
}
case <-ctx.Done():
case <-hctx.Done():
return
}
}
-6
View File
@@ -39,12 +39,6 @@ func (s staticDiskSource) Open(p string) (common.StaticSourceFile, error) {
}
func SetupHandler(e *gin.Engine, cfg *common.Config) {
if cfg.Ring.JinglePath != nil {
e.GET(cfg.Ring.JingleName, func(c *gin.Context) {
c.File(path.Join(*cfg.Ring.JinglePath, cfg.Ring.JingleName))
})
}
if cfg.Http.StaticPath != nil {
handler := common.NewStaticHandler(staticDiskSource{*cfg.Http.StaticPath}, "index.html")
e.NoRoute(func(c *gin.Context) {
-6
View File
@@ -42,12 +42,6 @@ func (s staticSource) Open(p string) (common.StaticSourceFile, error) {
}
func SetupHandler(e *gin.Engine, cfg *common.Config) {
if cfg.Ring.JinglePath != nil {
e.GET(cfg.Ring.JingleName, func(c *gin.Context) {
c.File(path.Join(*cfg.Ring.JinglePath, cfg.Ring.JingleName))
})
}
handler := common.NewStaticHandler(staticSource{"dist"}, "index.html")
e.NoRoute(func(c *gin.Context) {
encoding := c.Request.Header.Get("Accept-Encoding")
-28
View File
@@ -1,28 +0,0 @@
go-sonos
========
Copyright (c) 2012, Ian T. Richards <ianr@panix.com>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-942
View File
@@ -1,942 +0,0 @@
//
// go-sonos
// ========
//
// Copyright (c) 2012, Ian T. Richards <ianr@panix.com>
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//
// A client implementation of the SSDP protocol.
//
// mgr := ssdp.MakeManager()
// mgr.Discover("eth0", "13104", false)
// qry := ssdp.ServiceQueryTerms{
// ssdp.ServiceKey("schemas-upnp-org-MusicServices"): -1,
// }
// result := mgr.QueryServices(qry)
// if device_list, has := result["schemas-upnp-org-MusicServices"]; has {
// for _, device := range device_list {
// ...
// }
// }
// mgr.Close()
//
package ssdp
import (
"bufio"
"bytes"
"errors"
"fmt"
"io"
"log"
"net"
"net/textproto"
"regexp"
"strconv"
"strings"
"time"
)
var ssdpHNAPRegex *regexp.Regexp
var ssdpOtherDeviceRegex *regexp.Regexp
var ssdpOtherDeviceUUIDRegex *regexp.Regexp
var ssdpOtherServiceRegex *regexp.Regexp
var ssdpOtherServiceUUIDRegex *regexp.Regexp
var ssdpResponseStartLineRegexp *regexp.Regexp
var ssdpServerStringRegexp *regexp.Regexp
var ssdpRootDeviceUUIDRegex *regexp.Regexp
var ssdpUPnPBareUUIDRegex *regexp.Regexp
var ssdpUPnPDeviceRegex *regexp.Regexp
var ssdpUPnPDeviceUUIDRegex *regexp.Regexp
var ssdpUPnPServiceRegex *regexp.Regexp
var ssdpUPnPServiceUUIDRegex *regexp.Regexp
var ssdpUPnPUIDRegex *regexp.Regexp
func init() {
ssdpHNAPRegex = regexp.MustCompile("^hnap:(.+)$")
ssdpOtherDeviceRegex = regexp.MustCompile("^urn:([^:]+):device:([^:]+)(:(.+))?$")
ssdpOtherDeviceUUIDRegex = regexp.MustCompile("^uuid:([^:]+)::urn:([^:]+):device:([^:]+)(:(.+))?$")
ssdpOtherServiceRegex = regexp.MustCompile("^urn:([^:]+):service:([^:]+)(:(.+))?$")
ssdpOtherServiceUUIDRegex = regexp.MustCompile("^uuid:([^:]+)::urn:([^:]+):service:([^:]+)(:(.+))?$")
ssdpResponseStartLineRegexp = regexp.MustCompile("^HTTP/([0-9\\.]+)$")
ssdpServerStringRegexp = regexp.MustCompile("^([^ /,]+)(/([^ ,]+))?,?\\s+[Uu][Pp][Nn][Pp](/([^ ,]+))?,?\\s+([^/]+)(/(.+))?$")
ssdpRootDeviceUUIDRegex = regexp.MustCompile("^uuid:([^:]+)::upnp:rootdevice$")
ssdpUPnPBareUUIDRegex = regexp.MustCompile("^uuid:([^:]+)$")
ssdpUPnPDeviceRegex = regexp.MustCompile("^urn:schemas-upnp-org:device:([^:]+)(:(.+))?$")
ssdpUPnPDeviceUUIDRegex = regexp.MustCompile("uuid:([^:]+)::urn:schemas-upnp-org:device:([^:]+)(:(.+))?$")
ssdpUPnPServiceRegex = regexp.MustCompile("^urn:schemas-upnp-org:service:([^:]+)(:(.+))?$")
ssdpUPnPServiceUUIDRegex = regexp.MustCompile("uuid:([^:]+)::urn:schemas-upnp-org:service:([^:]+)(:(.+))?$")
ssdpUPnPUIDRegex = regexp.MustCompile("^uuid:(.+)$")
}
const (
ssdpBroadcastGroup = "239.255.255.250:1900"
ssdpBroadcastVersion = "udp"
)
// Type protection for a device URI
type Location string
// Type protection for a SSDP service key
type ServiceKey string
// Type protection for a Universally Unique ID
type UUID string
type ssdpServerDescription struct {
os string
os_version string
upnp_version string
product string
productVersion string
}
type ssdpResourceBase struct {
ssdpServerDescription
location Location
uuid UUID
}
// An abstraction of an SSDP service
type Service interface {
// The version of the service
Version() int64
}
type ssdpService struct {
ssdpResourceBase
name string
version int64
uri string
}
func (this *ssdpService) Version() int64 {
return this.version
}
type ssdpServiceSet map[ServiceKey]Service
// An abstraction of an SSDP leaf device
type Device interface {
// The product name (e.g. "Sonos")
Product() string
// The product version (e.g. "28.1-83040 (BR100)")
ProductVersion() string
// The device name (e.h. "ZonePlayer")
Name() string
// A URI that can be queried for device capabilities
Location() Location
// The device's Universally Unique ID
UUID() UUID
// Search for a service in the device's capabilities; same
// return semantics as querying a map
Service(key ServiceKey) (service Service, has bool)
// Return a list of services implemented by this device
Services() []ServiceKey
}
type ssdpDevice struct {
ssdpResourceBase
name string
version int64
uri string
services ssdpServiceSet
}
func (this *ssdpDevice) Product() string {
return this.product
}
func (this *ssdpDevice) ProductVersion() string {
return this.productVersion
}
func (this *ssdpDevice) Name() string {
return this.name
}
func (this *ssdpDevice) Location() Location {
return this.location
}
func (this *ssdpDevice) UUID() UUID {
return this.uuid
}
func (this *ssdpDevice) Service(key ServiceKey) (service Service, has bool) {
service, has = this.services[key]
return
}
func (this *ssdpDevice) Services() []ServiceKey {
i := 0
keys := make([]ServiceKey, len(this.services))
for key, _ := range this.services {
keys[i] = key
i += 1
}
return keys
}
// Indexes leaf devices by UUID
type DeviceMap map[UUID]Device
type ssdpRootDevice struct {
ssdpResourceBase
Devices DeviceMap
}
type ssdpRootDeviceMap map[Location]*ssdpRootDevice
// Discovered devices sorted by supported service
type ServiceMap map[ServiceKey]DeviceMap
type ssdpResourceType int
const (
ssdpTypessdpRootDevice ssdpResourceType = iota
ssdpTypeService
ssdpTypeDevice
ssdpTypeHNAP
ssdpTypeUUID
ssdpTypeUnknown
)
type ssdpResource struct {
ssdpServerDescription
ssdptype ssdpResourceType
uuid UUID
name string
version int64
uri string
location Location
children []*ssdpResource
}
type ssdpMessageType int
const (
ssdpSearch ssdpMessageType = iota
ssdpNotify
ssdpResponse
ssdpInvalid
)
type ssdpRawMessage struct {
msgtype ssdpMessageType
httpver string
header map[string]string
}
type ssdpNotifyMessage struct {
_01_nls string
cache_control string
host string
location Location
nts string
nt string
opt string
server string
usn string
x_rincon_bootseq string
x_rincon_household string
x_user_agent string
}
type ssdpNotifyQueue chan *ssdpNotifyMessage
type ssdpResponseMessage struct {
ssdpServerDescription
_01_nls string
al string
cache_control string
date string
ext string
location Location
opt string
st string
usn string
x_rincon_bootseq string
x_rincon_household string
x_rincon_variant string
x_rincon_wifimode string
x_user_agent string
content_length string
bootid_upnp_org string
configid_upnp_org string
household_smartspeaker_audio string
x_av_server_info string
}
type ssdpResponseQueue chan *ssdpResponseMessage
type ssdpConnection struct {
conn *net.UDPConn
addr *net.UDPAddr
}
// A map of service key to minimum required version
type ServiceQueryTerms map[ServiceKey]int64
// Encapsulates SSDP discovery, handles updates, and stores results
type Manager interface {
// Initiates SSDP discovery, where ifiname names a network device
// to query, port gives a free port on that network device to listen
// for responses, and the subscribe flag (currrently unimplemented)
// determines whether to listen to asynchronous updates after the
// initial query is complete.
Discover(ifiname, port string, subscribe bool) error
// After discovery is complete searches for devices implementing
// the services specified in query.
QueryServices(query ServiceQueryTerms) ServiceMap
// Return the list of devices that were found during discovery
Devices() DeviceMap
// Shuts down asynchronous subscriptions to device state
Close() error
}
type ssdpDefaultManager struct {
responseQueue ssdpResponseQueue
notifyQueue ssdpNotifyQueue
unicast ssdpConnection
multicast ssdpConnection
rootDeviceMap ssdpRootDeviceMap
deviceMap DeviceMap
serviceMap ServiceMap
readyChan chan int
closeChan chan int
}
// Returns an empty manager ready for SSDP discovery
func MakeManager() Manager {
mgr := &ssdpDefaultManager{}
mgr.responseQueue = make(ssdpResponseQueue)
mgr.notifyQueue = make(ssdpNotifyQueue)
mgr.unicast = ssdpConnection{}
mgr.multicast = ssdpConnection{}
mgr.rootDeviceMap = make(ssdpRootDeviceMap)
mgr.deviceMap = make(DeviceMap)
mgr.serviceMap = make(ServiceMap)
mgr.readyChan = make(chan int)
mgr.closeChan = make(chan int)
return mgr
}
func (this *ssdpDefaultManager) Discover(ifiname, port string, subscribe bool) (err error) {
this.ssdpDiscoverImpl(ifiname, port, subscribe)
return
}
func (this *ssdpDefaultManager) QueryServices(query ServiceQueryTerms) (results ServiceMap) {
results = make(ServiceMap)
for name, minver := range query {
results[name] = make(DeviceMap)
if dlist, has := this.serviceMap[name]; has {
for uuid, _ := range dlist {
de := this.deviceMap[uuid]
if svc, has := de.Service(name); has {
if minver <= svc.Version() {
results[name][de.UUID()] = de
}
}
}
}
}
return
}
func (this *ssdpDefaultManager) Devices() DeviceMap {
return this.deviceMap
}
func (this *ssdpDefaultManager) Close() (err error) {
if nil != this.unicast.conn {
this.unicast.conn.Close()
<-this.closeChan
}
if nil != this.multicast.conn {
this.multicast.conn.Close()
<-this.closeChan
}
return
}
func ssdpNewDevice(res *ssdpResource) (de *ssdpDevice) {
de = new(ssdpDevice)
de.ssdpServerDescription = res.ssdpServerDescription
de.uuid = res.uuid
de.location = res.location
de.name = res.name
de.version = res.version
de.uri = res.uri
de.services = make(ssdpServiceSet)
return
}
func ssdpNewssdpRootDevice(res *ssdpResource) (rd *ssdpRootDevice) {
rd = new(ssdpRootDevice)
rd.ssdpServerDescription = res.ssdpServerDescription
rd.uuid = res.uuid
rd.location = res.location
rd.Devices = make(DeviceMap)
return
}
func (rd *ssdpRootDevice) ssdpRequireEmbeddedDevice(de *ssdpDevice) {
if _, has := rd.Devices[de.UUID()]; !has {
rd.Devices[de.UUID()] = de
}
}
func ssdpNewRawMessage() *ssdpRawMessage {
return &ssdpRawMessage{ssdpInvalid, "1.1", make(map[string]string)}
}
func ssdpNewResource(uuid UUID) (res *ssdpResource) {
res = new(ssdpResource)
res.ssdptype = ssdpTypeUnknown
res.uuid = uuid
return
}
func ssdpNewService(res *ssdpResource) (sv *ssdpService) {
sv = new(ssdpService)
sv.ssdpServerDescription = res.ssdpServerDescription
sv.uuid = res.uuid
sv.location = res.location
sv.name = res.name
sv.version = res.version
sv.uri = res.uri
return
}
func (this *ssdpDefaultManager) ssdpParseStartLineFields(raw *ssdpRawMessage, fields []string) {
if "M-SEARCH" == fields[0] {
raw.msgtype = ssdpSearch
} else if "NOTIFY" == fields[0] {
raw.msgtype = ssdpNotify
} else if m := ssdpResponseStartLineRegexp.FindStringSubmatch(fields[0]); 0 < len(m) {
raw.msgtype = ssdpResponse
raw.httpver = m[1]
} else {
panic(fmt.Sprintf("Invalid start line `%s'", fields[0]))
}
}
func (this *ssdpDefaultManager) ssdpParseStartLine(raw *ssdpRawMessage, line []byte) {
fields := strings.Fields(string(line))
if 3 != len(fields) {
panic("Invalid start line")
} else {
this.ssdpParseStartLineFields(raw, fields)
}
}
func (this *ssdpDefaultManager) ssdpParseHeaderLine(raw *ssdpRawMessage, line []byte) {
i := strings.Index(string(line), ":")
if -1 == i {
panic("Invalid header")
}
field := textproto.CanonicalMIMEHeaderKey(strings.TrimSpace(string(line[0:i])))
value := strings.TrimSpace(string(line[i+1:]))
if _, has := raw.header[field]; has {
panic("Header field redefined")
} else {
raw.header[field] = value
}
}
func (this *ssdpDefaultManager) ssdpParseInputLine(raw *ssdpRawMessage, line []byte, lineno int) {
if 1 < lineno {
this.ssdpParseHeaderLine(raw, line)
} else {
this.ssdpParseStartLine(raw, line)
}
}
func (this *ssdpDefaultManager) ssdpParseInput(msg []byte) (raw *ssdpRawMessage) {
raw = ssdpNewRawMessage()
bin := bufio.NewReader(bytes.NewReader(msg))
var line []byte
lineno := 0
for {
if fragment, is_prefix, err := bin.ReadLine(); nil == err {
line = append(line, fragment...)
if !is_prefix {
lineno += 1
if 1 < lineno && 0 == len(line) {
break
}
this.ssdpParseInputLine(raw, line, lineno)
line = nil
}
} else if io.EOF == err {
panic("Premature end of header")
} else {
panic(err)
}
}
return
}
func (this *ssdpDefaultManager) ssdpHandleNotify(raw *ssdpRawMessage) *ssdpNotifyMessage {
msg := new(ssdpNotifyMessage) /*asynchronous reply from multicast*/
for key, value := range raw.header {
switch key {
case "Location":
msg.location = Location(value)
case "Server":
msg.server = value
case "Host":
msg.host = value
case "Usn":
msg.usn = value
case "Cache-Control":
msg.cache_control = value
case "X-User-Agent":
msg.x_user_agent = value
case "X-Rincon-Bootseq":
msg.x_rincon_bootseq = value
case "X-Rincon-Household":
msg.x_rincon_household = value
case "Nts":
msg.nts = value
case "Nt":
msg.nt = value
case "Opt":
msg.opt = value
case "01-Nls":
msg._01_nls = value
default:
log.Printf("No support for field `%s' (value `%s')", key, value)
}
}
return msg
}
func (this *ssdpDefaultManager) ssdpHandleResponse(raw *ssdpRawMessage) *ssdpResponseMessage {
msg := new(ssdpResponseMessage) /*synchronous reply from unicast*/
for key, value := range raw.header {
switch key {
case "Location":
msg.location = Location(value)
case "St":
msg.st = value
case "Server":
m := ssdpServerStringRegexp.FindStringSubmatch(value)
if 0 < len(m) {
msg.os = m[1]
msg.os_version = m[3]
msg.upnp_version = m[5]
msg.product = m[6]
msg.productVersion = m[8]
} else {
log.Printf("Invalid server description `%s'", value)
}
case "Opt":
msg.opt = value
case "Usn":
msg.usn = value
case "Ext":
msg.ext = value
case "Date":
msg.date = value
case "Cache-Control":
msg.cache_control = value
case "X-User-Agent":
msg.x_user_agent = value
case "X-Rincon-Bootseq":
msg.x_rincon_bootseq = value
case "X-Rincon-Household":
msg.x_rincon_household = value
case "X-Rincon-Variant":
msg.x_rincon_variant = value
case "X-Rincon-Wifimode":
msg.x_rincon_wifimode = value
case "Al":
msg.al = value
case "01-Nls":
msg._01_nls = value
case "Content-Length":
msg.content_length = value
case "Bootid.upnp.org":
msg.bootid_upnp_org = value
case "Configid.upnp.org":
msg.configid_upnp_org = value
case "Household.smartspeaker.audio":
msg.household_smartspeaker_audio = value
case "X-Av-Server-Info":
msg.x_av_server_info = value
default:
log.Printf("No support for field `%s' (value `%s')", key, value)
log.Printf("%v", raw)
}
}
return msg
}
func (this *ssdpDefaultManager) ssdpHandleMessage(raw *ssdpRawMessage) {
switch raw.msgtype {
case ssdpSearch: /*ignore*/
case ssdpResponse:
this.responseQueue <- this.ssdpHandleResponse(raw)
case ssdpNotify:
this.notifyQueue <- this.ssdpHandleNotify(raw)
}
}
func (this *ssdpDefaultManager) ssdpDiscoverLoop(conn net.Conn) {
this.readyChan <- 1
msg := make([]byte, 65536) /*max size of a single UDP packet*/
defer func() {
recover()
this.closeChan <- 1
}()
for {
if n, err := conn.Read(msg); nil != err {
panic(err)
} else if raw := this.ssdpParseInput(msg[:n]); nil != raw {
this.ssdpHandleMessage(raw)
}
}
}
func (this *ssdpDefaultManager) ssdpUnicastDiscoverImpl(ifi *net.Interface, port string) (err error) {
addrs, err := ifi.Addrs()
if nil != err {
return
} else if 0 == len(addrs) {
err = errors.New(fmt.Sprintf("No addresses found for interface %s", ifi.Name))
return
}
var lip net.IP
for _, addr := range addrs {
if nil != addr.(*net.IPNet).IP.DefaultMask() {
lip = addr.(*net.IPNet).IP
break;
}
}
laddr, err := net.ResolveUDPAddr(ssdpBroadcastVersion, net.JoinHostPort(lip.String(), port))
if nil != err {
return
}
uc, err := net.ListenUDP(ssdpBroadcastVersion, laddr)
if nil != err {
return
}
this.unicast.addr = laddr
this.unicast.conn = uc
go this.ssdpDiscoverLoop(uc)
<-this.readyChan
return
}
func (this *ssdpDefaultManager) ssdpMulticastDiscoverImpl(ifi *net.Interface, subscribe bool) (err error) {
maddr, err := net.ResolveUDPAddr(ssdpBroadcastVersion, ssdpBroadcastGroup)
if nil != err {
return
}
this.multicast.addr = maddr
var mc *net.UDPConn
if subscribe {
mc, err = net.ListenMulticastUDP(ssdpBroadcastVersion, ifi, maddr)
if nil != err {
return
}
this.multicast.conn = mc
go this.ssdpDiscoverLoop(mc)
<-this.readyChan
}
return
}
func (this *ssdpDefaultManager) ssdpQueryMessage(timeout int) (msg *bytes.Buffer) {
msg = new(bytes.Buffer)
msg.WriteString("M-SEARCH * HTTP/1.1\r\n")
msg.WriteString("HosT: 239.255.255.250:1900\r\n")
msg.WriteString("MAN: \"ssdp:discover\"\r\n")
msg.WriteString(fmt.Sprintf("MX: %d\r\n", timeout))
msg.WriteString("ST: ssdp:all\r\n")
msg.WriteString("USER-AGENT: unix/5.1 UPnP/1.1 crash/1.0\r\n")
msg.WriteString("\r\n")
return
}
func (this *ssdpDefaultManager) ssdpRequiressdpRootDevice(res *ssdpResource) (rd *ssdpRootDevice) {
var has bool
if rd, has = this.rootDeviceMap[res.location]; !has {
rd = ssdpNewssdpRootDevice(res)
this.rootDeviceMap[rd.location] = rd
}
return
}
func (this *ssdpDefaultManager) ssdpRequireDevice(res *ssdpResource) (de *ssdpDevice) {
if raw, has := this.deviceMap[res.uuid]; !has {
de = ssdpNewDevice(res)
this.deviceMap[res.uuid] = de
} else {
de = raw.(*ssdpDevice)
}
return
}
func (this *ssdpDefaultManager) ssdpNotifyssdpRootDevice(res *ssdpResource) {
this.ssdpRequiressdpRootDevice(res)
this.ssdpRequireDevice(res)
}
func (this *ssdpDefaultManager) ssdpNotifyDevice(res *ssdpResource) {
rd := this.ssdpRequiressdpRootDevice(res)
de := this.ssdpRequireDevice(res)
rd.ssdpRequireEmbeddedDevice(de)
}
func (this *ssdpDefaultManager) ssdpGetServiceKey(sv *ssdpService) (key ServiceKey) {
uri := sv.uri
if 0 >= len(uri) {
uri = "schemas-upnp-org"
}
key = ServiceKey(fmt.Sprintf("%s-%s", uri, sv.name))
return
}
func (this *ssdpDefaultManager) ssdpRequireService(de *ssdpDevice, sv *ssdpService) {
key := this.ssdpGetServiceKey(sv)
if _, has := de.services[key]; !has {
de.services[key] = sv
if _, has := this.serviceMap[key]; !has {
this.serviceMap[key] = make(DeviceMap)
}
this.serviceMap[key][de.UUID()] = de
}
}
func (this *ssdpDefaultManager) ssdpNotifyService(res *ssdpResource) {
de := this.ssdpRequireDevice(res)
sv := ssdpNewService(res)
this.ssdpRequireService(de, sv)
}
func (this *ssdpDefaultManager) ssdpNotifyResource(res *ssdpResource) {
switch res.ssdptype {
case ssdpTypessdpRootDevice:
this.ssdpNotifyssdpRootDevice(res)
case ssdpTypeDevice:
this.ssdpNotifyDevice(res)
case ssdpTypeService:
this.ssdpNotifyService(res)
case ssdpTypeHNAP:
/*TODO*/
case ssdpTypeUUID:
/*TODO ... not sure what to do*/
default:
log.Fatalf("Unhandled ssdptype %d", res.ssdptype)
}
}
func (this *ssdpDefaultManager) ssdpIncludessdpRootDevice(ssdpsm *ssdpResponseMessage) {
if n := ssdpRootDeviceUUIDRegex.FindStringSubmatch(ssdpsm.usn); 0 < len(n) {
uuid := UUID(n[1])
res := ssdpNewResource(uuid)
res.ssdpServerDescription = ssdpsm.ssdpServerDescription
res.uuid = uuid
res.location = ssdpsm.location
res.ssdptype = ssdpTypessdpRootDevice
this.ssdpNotifyResource(res)
} else {
log.Printf("Invalid Unique Service Name for upnp:rootdevice: `%s'", ssdpsm.usn)
}
}
func (this *ssdpDefaultManager) ssdpIncludeService(ssdpsm *ssdpResponseMessage) {
if n := ssdpUPnPServiceUUIDRegex.FindStringSubmatch(ssdpsm.usn); 0 < len(n) {
uuid := UUID(n[1])
res := ssdpNewResource(uuid)
res.ssdpServerDescription = ssdpsm.ssdpServerDescription
res.location = ssdpsm.location
res.ssdptype = ssdpTypeService
res.name = n[2]
var err error
if res.version, err = strconv.ParseInt(n[4], 10, 4); nil != err {
log.Printf("Error in parsing service version `%s'", n[4])
}
this.ssdpNotifyResource(res)
} else {
log.Printf("Invalid Unique Service Name for UPnP service: `%s'", ssdpsm.usn)
}
}
func (this *ssdpDefaultManager) ssdpIncludeDevice(ssdpsm *ssdpResponseMessage) {
if n := ssdpUPnPDeviceUUIDRegex.FindStringSubmatch(ssdpsm.usn); 0 < len(n) {
uuid := UUID(n[1])
res := ssdpNewResource(uuid)
res.ssdpServerDescription = ssdpsm.ssdpServerDescription
res.location = ssdpsm.location
res.ssdptype = ssdpTypeDevice
res.name = n[2]
var err error
if res.version, err = strconv.ParseInt(n[4], 10, 4); nil != err {
log.Printf("Error in parsing device version `%s'", n[4])
}
this.ssdpNotifyResource(res)
} else {
log.Printf("Invalid Unique Service Name for UPnP device: `%s'", ssdpsm.usn)
}
}
func (this *ssdpDefaultManager) ssdpIncludeUUID(ssdpsm *ssdpResponseMessage) {
if n := ssdpUPnPBareUUIDRegex.FindStringSubmatch(ssdpsm.usn); 0 < len(n) {
uuid := UUID(n[1])
res := ssdpNewResource(uuid)
res.ssdpServerDescription = ssdpsm.ssdpServerDescription
res.location = ssdpsm.location
res.ssdptype = ssdpTypeUUID
this.ssdpNotifyResource(res)
} else {
log.Printf("Invalid Unique Service Name: `%s'", ssdpsm.usn)
}
}
func (this *ssdpDefaultManager) ssdpIncludeHNAP(ssdpsm *ssdpResponseMessage, name string) {
if n := ssdpUPnPBareUUIDRegex.FindStringSubmatch(ssdpsm.usn); 0 < len(n) {
uuid := UUID(n[1])
res := ssdpNewResource(uuid)
res.ssdpServerDescription = ssdpsm.ssdpServerDescription
res.location = ssdpsm.location
res.ssdptype = ssdpTypeHNAP
res.name = name
this.ssdpNotifyResource(res)
} else {
log.Printf("Invalid Unique Service Name for HNAP: `%s'", ssdpsm.usn)
}
}
func (this *ssdpDefaultManager) ssdpIncludeOtherService(ssdpsm *ssdpResponseMessage) {
if n := ssdpOtherServiceUUIDRegex.FindStringSubmatch(ssdpsm.usn); 0 < len(n) {
uuid := UUID(n[1])
res := ssdpNewResource(uuid)
res.ssdpServerDescription = ssdpsm.ssdpServerDescription
res.location = ssdpsm.location
res.ssdptype = ssdpTypeService
res.uri = n[2]
res.name = n[3]
var err error
if res.version, err = strconv.ParseInt(n[5], 10, 4); nil != err {
log.Printf("Error in parsing service version `%s'", n[4])
}
this.ssdpNotifyResource(res)
} else {
log.Printf("Invalid Unique Service Name for third-party service: `%s'", ssdpsm.usn)
}
}
func (this *ssdpDefaultManager) ssdpIncludeOtherDevice(ssdpsm *ssdpResponseMessage) {
if n := ssdpOtherDeviceUUIDRegex.FindStringSubmatch(ssdpsm.usn); 0 < len(n) {
uuid := UUID(n[1])
res := ssdpNewResource(uuid)
res.ssdpServerDescription = ssdpsm.ssdpServerDescription
res.location = ssdpsm.location
res.ssdptype = ssdpTypeDevice
res.uri = n[2]
res.name = n[3]
var err error
if res.version, err = strconv.ParseInt(n[5], 10, 4); nil != err {
log.Printf("Error in parsing device version `%s'", n[4])
}
this.ssdpNotifyResource(res)
} else {
log.Printf("Invalid Unique Service Name for third-party device: `%s'", ssdpsm.usn)
}
}
func (this *ssdpDefaultManager) ssdpIncludeResponse(msg *ssdpResponseMessage) {
if "upnp:rootdevice" == msg.st {
this.ssdpIncludessdpRootDevice(msg)
} else if m := ssdpUPnPServiceRegex.FindStringSubmatch(msg.st); 0 < len(m) {
this.ssdpIncludeService(msg)
} else if m := ssdpUPnPDeviceRegex.FindStringSubmatch(msg.st); 0 < len(m) {
this.ssdpIncludeDevice(msg)
} else if m := ssdpUPnPUIDRegex.FindStringSubmatch(msg.st); 0 < len(m) {
this.ssdpIncludeUUID(msg)
} else if m := ssdpHNAPRegex.FindStringSubmatch(msg.st); 0 < len(m) {
this.ssdpIncludeHNAP(msg, m[1])
} else if m := ssdpOtherServiceRegex.FindStringSubmatch(msg.st); 0 < len(m) {
this.ssdpIncludeOtherService(msg)
} else if m := ssdpOtherDeviceRegex.FindStringSubmatch(msg.st); 0 < len(m) {
this.ssdpIncludeOtherDevice(msg)
} else {
log.Printf("Unsupported search term [ST] `%s'", msg.st)
}
}
func (this *ssdpDefaultManager) ssdpIncludeNotification(msg *ssdpNotifyMessage) {
/*TODO*/
}
func (this *ssdpDefaultManager) ssdpSendQuery(timeout int) (err error) {
msg := this.ssdpQueryMessage(timeout)
if _, err = this.unicast.conn.WriteTo(msg.Bytes(), this.multicast.addr); nil != err {
return
} else {
timeout := time.NewTimer(time.Duration(timeout) * time.Second)
done := false
for !done {
select {
case m := <-this.responseQueue:
this.ssdpIncludeResponse(m)
case raw := <-this.notifyQueue:
this.ssdpIncludeNotification(raw)
case <-timeout.C:
done = true
}
}
}
return
}
func (this *ssdpDefaultManager) ssdpQueryLoop() (err error) {
for i := 0; i < 2; i++ {
if err = this.ssdpSendQuery(3 /*timeout seconds*/); nil != err {
return
}
}
return
}
func (this *ssdpDefaultManager) ssdpDiscoverImpl(ifiname, port string, subscribe bool) {
ifi, err := net.InterfaceByName(ifiname)
if nil != err {
panic(err)
} else if err = this.ssdpUnicastDiscoverImpl(ifi, port); nil != err {
panic(err)
} else if err = this.ssdpMulticastDiscoverImpl(ifi, subscribe); nil != err {
panic(err)
} else if err = this.ssdpQueryLoop(); nil != err {
panic(err)
}
}
-12
View File
@@ -1,12 +0,0 @@
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib
# Test binary, build with `go test -c`
*.test
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
File diff suppressed because it is too large Load Diff
-593
View File
@@ -1,593 +0,0 @@
package alarmclock
import (
"bytes"
"encoding/xml"
"errors"
"io/ioutil"
"net/http"
"net/url"
)
const (
_ServiceURN = "urn:schemas-upnp-org:service:AlarmClock:1"
_EncodingSchema = "http://schemas.xmlsoap.org/soap/encoding/"
_EnvelopeSchema = "http://schemas.xmlsoap.org/soap/envelope/"
)
type Service struct {
ControlEndpoint *url.URL
EventEndpoint *url.URL
}
func NewService(deviceUrl *url.URL) *Service {
c, err := url.Parse(`/AlarmClock/Control`)
if nil != err {
panic(err)
}
e, err := url.Parse(`/AlarmClock/Event`)
if nil != err {
panic(err)
}
return &Service{
ControlEndpoint: deviceUrl.ResolveReference(c),
EventEndpoint: deviceUrl.ResolveReference(e),
}
}
type Envelope struct {
XMLName xml.Name `xml:"s:Envelope"`
Xmlns string `xml:"xmlns:s,attr"`
EncodingStyle string `xml:"s:encodingStyle,attr"`
Body Body `xml:"s:Body"`
}
type Body struct {
XMLName xml.Name `xml:"s:Body"`
SetFormat *SetFormatArgs `xml:"u:SetFormat,omitempty"`
GetFormat *GetFormatArgs `xml:"u:GetFormat,omitempty"`
SetTimeZone *SetTimeZoneArgs `xml:"u:SetTimeZone,omitempty"`
GetTimeZone *GetTimeZoneArgs `xml:"u:GetTimeZone,omitempty"`
GetTimeZoneAndRule *GetTimeZoneAndRuleArgs `xml:"u:GetTimeZoneAndRule,omitempty"`
GetTimeZoneRule *GetTimeZoneRuleArgs `xml:"u:GetTimeZoneRule,omitempty"`
SetTimeServer *SetTimeServerArgs `xml:"u:SetTimeServer,omitempty"`
GetTimeServer *GetTimeServerArgs `xml:"u:GetTimeServer,omitempty"`
SetTimeNow *SetTimeNowArgs `xml:"u:SetTimeNow,omitempty"`
GetHouseholdTimeAtStamp *GetHouseholdTimeAtStampArgs `xml:"u:GetHouseholdTimeAtStamp,omitempty"`
GetTimeNow *GetTimeNowArgs `xml:"u:GetTimeNow,omitempty"`
CreateAlarm *CreateAlarmArgs `xml:"u:CreateAlarm,omitempty"`
UpdateAlarm *UpdateAlarmArgs `xml:"u:UpdateAlarm,omitempty"`
DestroyAlarm *DestroyAlarmArgs `xml:"u:DestroyAlarm,omitempty"`
ListAlarms *ListAlarmsArgs `xml:"u:ListAlarms,omitempty"`
SetDailyIndexRefreshTime *SetDailyIndexRefreshTimeArgs `xml:"u:SetDailyIndexRefreshTime,omitempty"`
GetDailyIndexRefreshTime *GetDailyIndexRefreshTimeArgs `xml:"u:GetDailyIndexRefreshTime,omitempty"`
}
type EnvelopeResponse struct {
XMLName xml.Name `xml:"Envelope"`
Xmlns string `xml:"xmlns:s,attr"`
EncodingStyle string `xml:"encodingStyle,attr"`
Body BodyResponse `xml:"Body"`
}
type BodyResponse struct {
XMLName xml.Name `xml:"Body"`
SetFormat *SetFormatResponse `xml:"SetFormatResponse,omitempty"`
GetFormat *GetFormatResponse `xml:"GetFormatResponse,omitempty"`
SetTimeZone *SetTimeZoneResponse `xml:"SetTimeZoneResponse,omitempty"`
GetTimeZone *GetTimeZoneResponse `xml:"GetTimeZoneResponse,omitempty"`
GetTimeZoneAndRule *GetTimeZoneAndRuleResponse `xml:"GetTimeZoneAndRuleResponse,omitempty"`
GetTimeZoneRule *GetTimeZoneRuleResponse `xml:"GetTimeZoneRuleResponse,omitempty"`
SetTimeServer *SetTimeServerResponse `xml:"SetTimeServerResponse,omitempty"`
GetTimeServer *GetTimeServerResponse `xml:"GetTimeServerResponse,omitempty"`
SetTimeNow *SetTimeNowResponse `xml:"SetTimeNowResponse,omitempty"`
GetHouseholdTimeAtStamp *GetHouseholdTimeAtStampResponse `xml:"GetHouseholdTimeAtStampResponse,omitempty"`
GetTimeNow *GetTimeNowResponse `xml:"GetTimeNowResponse,omitempty"`
CreateAlarm *CreateAlarmResponse `xml:"CreateAlarmResponse,omitempty"`
UpdateAlarm *UpdateAlarmResponse `xml:"UpdateAlarmResponse,omitempty"`
DestroyAlarm *DestroyAlarmResponse `xml:"DestroyAlarmResponse,omitempty"`
ListAlarms *ListAlarmsResponse `xml:"ListAlarmsResponse,omitempty"`
SetDailyIndexRefreshTime *SetDailyIndexRefreshTimeResponse `xml:"SetDailyIndexRefreshTimeResponse,omitempty"`
GetDailyIndexRefreshTime *GetDailyIndexRefreshTimeResponse `xml:"GetDailyIndexRefreshTimeResponse,omitempty"`
}
func (s *Service) exec(actionName string, httpClient *http.Client, envelope *Envelope) (*EnvelopeResponse, error) {
marshaled, err := xml.Marshal(envelope)
if err != nil {
return nil, err
}
postBody := []byte(`<?xml version="1.0"?>`)
postBody = append(postBody, marshaled...)
req, err := http.NewRequest(`POST`, s.ControlEndpoint.String(), bytes.NewBuffer(postBody))
if err != nil {
return nil, err
}
req.Header.Set(`Content-Type`, `text/xml; charset="utf-8"`)
req.Header.Set(`SOAPAction`, _ServiceURN+`#`+actionName)
res, err := httpClient.Do(req)
if err != nil {
return nil, err
}
defer res.Body.Close()
responseBody, err := ioutil.ReadAll(res.Body)
if err != nil {
return nil, err
}
var envelopeResponse EnvelopeResponse
err = xml.Unmarshal(responseBody, &envelopeResponse)
if err != nil {
return nil, err
}
return &envelopeResponse, nil
}
type SetFormatArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
DesiredTimeFormat string `xml:"DesiredTimeFormat"`
DesiredDateFormat string `xml:"DesiredDateFormat"`
}
type SetFormatResponse struct {
}
func (s *Service) SetFormat(httpClient *http.Client, args *SetFormatArgs) (*SetFormatResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`SetFormat`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{SetFormat: args},
})
if err != nil {
return nil, err
}
if r.Body.SetFormat == nil {
return nil, errors.New(`unexpected respose from service calling alarmclock.SetFormat()`)
}
return r.Body.SetFormat, nil
}
type GetFormatArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
}
type GetFormatResponse struct {
CurrentTimeFormat string `xml:"CurrentTimeFormat"`
CurrentDateFormat string `xml:"CurrentDateFormat"`
}
func (s *Service) GetFormat(httpClient *http.Client, args *GetFormatArgs) (*GetFormatResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`GetFormat`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{GetFormat: args},
})
if err != nil {
return nil, err
}
if r.Body.GetFormat == nil {
return nil, errors.New(`unexpected respose from service calling alarmclock.GetFormat()`)
}
return r.Body.GetFormat, nil
}
type SetTimeZoneArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
Index int32 `xml:"Index"`
AutoAdjustDst bool `xml:"AutoAdjustDst"`
}
type SetTimeZoneResponse struct {
}
func (s *Service) SetTimeZone(httpClient *http.Client, args *SetTimeZoneArgs) (*SetTimeZoneResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`SetTimeZone`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{SetTimeZone: args},
})
if err != nil {
return nil, err
}
if r.Body.SetTimeZone == nil {
return nil, errors.New(`unexpected respose from service calling alarmclock.SetTimeZone()`)
}
return r.Body.SetTimeZone, nil
}
type GetTimeZoneArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
}
type GetTimeZoneResponse struct {
Index int32 `xml:"Index"`
AutoAdjustDst bool `xml:"AutoAdjustDst"`
}
func (s *Service) GetTimeZone(httpClient *http.Client, args *GetTimeZoneArgs) (*GetTimeZoneResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`GetTimeZone`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{GetTimeZone: args},
})
if err != nil {
return nil, err
}
if r.Body.GetTimeZone == nil {
return nil, errors.New(`unexpected respose from service calling alarmclock.GetTimeZone()`)
}
return r.Body.GetTimeZone, nil
}
type GetTimeZoneAndRuleArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
}
type GetTimeZoneAndRuleResponse struct {
Index int32 `xml:"Index"`
AutoAdjustDst bool `xml:"AutoAdjustDst"`
CurrentTimeZone string `xml:"CurrentTimeZone"`
}
func (s *Service) GetTimeZoneAndRule(httpClient *http.Client, args *GetTimeZoneAndRuleArgs) (*GetTimeZoneAndRuleResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`GetTimeZoneAndRule`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{GetTimeZoneAndRule: args},
})
if err != nil {
return nil, err
}
if r.Body.GetTimeZoneAndRule == nil {
return nil, errors.New(`unexpected respose from service calling alarmclock.GetTimeZoneAndRule()`)
}
return r.Body.GetTimeZoneAndRule, nil
}
type GetTimeZoneRuleArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
Index int32 `xml:"Index"`
}
type GetTimeZoneRuleResponse struct {
TimeZone string `xml:"TimeZone"`
}
func (s *Service) GetTimeZoneRule(httpClient *http.Client, args *GetTimeZoneRuleArgs) (*GetTimeZoneRuleResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`GetTimeZoneRule`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{GetTimeZoneRule: args},
})
if err != nil {
return nil, err
}
if r.Body.GetTimeZoneRule == nil {
return nil, errors.New(`unexpected respose from service calling alarmclock.GetTimeZoneRule()`)
}
return r.Body.GetTimeZoneRule, nil
}
type SetTimeServerArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
DesiredTimeServer string `xml:"DesiredTimeServer"`
}
type SetTimeServerResponse struct {
}
func (s *Service) SetTimeServer(httpClient *http.Client, args *SetTimeServerArgs) (*SetTimeServerResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`SetTimeServer`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{SetTimeServer: args},
})
if err != nil {
return nil, err
}
if r.Body.SetTimeServer == nil {
return nil, errors.New(`unexpected respose from service calling alarmclock.SetTimeServer()`)
}
return r.Body.SetTimeServer, nil
}
type GetTimeServerArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
}
type GetTimeServerResponse struct {
CurrentTimeServer string `xml:"CurrentTimeServer"`
}
func (s *Service) GetTimeServer(httpClient *http.Client, args *GetTimeServerArgs) (*GetTimeServerResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`GetTimeServer`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{GetTimeServer: args},
})
if err != nil {
return nil, err
}
if r.Body.GetTimeServer == nil {
return nil, errors.New(`unexpected respose from service calling alarmclock.GetTimeServer()`)
}
return r.Body.GetTimeServer, nil
}
type SetTimeNowArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
DesiredTime string `xml:"DesiredTime"`
TimeZoneForDesiredTime string `xml:"TimeZoneForDesiredTime"`
}
type SetTimeNowResponse struct {
}
func (s *Service) SetTimeNow(httpClient *http.Client, args *SetTimeNowArgs) (*SetTimeNowResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`SetTimeNow`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{SetTimeNow: args},
})
if err != nil {
return nil, err
}
if r.Body.SetTimeNow == nil {
return nil, errors.New(`unexpected respose from service calling alarmclock.SetTimeNow()`)
}
return r.Body.SetTimeNow, nil
}
type GetHouseholdTimeAtStampArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
TimeStamp string `xml:"TimeStamp"`
}
type GetHouseholdTimeAtStampResponse struct {
HouseholdUTCTime string `xml:"HouseholdUTCTime"`
}
func (s *Service) GetHouseholdTimeAtStamp(httpClient *http.Client, args *GetHouseholdTimeAtStampArgs) (*GetHouseholdTimeAtStampResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`GetHouseholdTimeAtStamp`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{GetHouseholdTimeAtStamp: args},
})
if err != nil {
return nil, err
}
if r.Body.GetHouseholdTimeAtStamp == nil {
return nil, errors.New(`unexpected respose from service calling alarmclock.GetHouseholdTimeAtStamp()`)
}
return r.Body.GetHouseholdTimeAtStamp, nil
}
type GetTimeNowArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
}
type GetTimeNowResponse struct {
CurrentUTCTime string `xml:"CurrentUTCTime"`
CurrentLocalTime string `xml:"CurrentLocalTime"`
CurrentTimeZone string `xml:"CurrentTimeZone"`
CurrentTimeGeneration uint32 `xml:"CurrentTimeGeneration"`
}
func (s *Service) GetTimeNow(httpClient *http.Client, args *GetTimeNowArgs) (*GetTimeNowResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`GetTimeNow`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{GetTimeNow: args},
})
if err != nil {
return nil, err
}
if r.Body.GetTimeNow == nil {
return nil, errors.New(`unexpected respose from service calling alarmclock.GetTimeNow()`)
}
return r.Body.GetTimeNow, nil
}
type CreateAlarmArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
StartLocalTime string `xml:"StartLocalTime"`
Duration string `xml:"Duration"`
// Allowed Value: ONCE
// Allowed Value: WEEKDAYS
// Allowed Value: WEEKENDS
// Allowed Value: DAILY
Recurrence string `xml:"Recurrence"`
Enabled bool `xml:"Enabled"`
RoomUUID string `xml:"RoomUUID"`
ProgramURI string `xml:"ProgramURI"`
ProgramMetaData string `xml:"ProgramMetaData"`
// Allowed Value: NORMAL
// Allowed Value: REPEAT_ALL
// Allowed Value: SHUFFLE_NOREPEAT
// Allowed Value: SHUFFLE
PlayMode string `xml:"PlayMode"`
Volume uint16 `xml:"Volume"`
IncludeLinkedZones bool `xml:"IncludeLinkedZones"`
}
type CreateAlarmResponse struct {
AssignedID uint32 `xml:"AssignedID"`
}
func (s *Service) CreateAlarm(httpClient *http.Client, args *CreateAlarmArgs) (*CreateAlarmResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`CreateAlarm`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{CreateAlarm: args},
})
if err != nil {
return nil, err
}
if r.Body.CreateAlarm == nil {
return nil, errors.New(`unexpected respose from service calling alarmclock.CreateAlarm()`)
}
return r.Body.CreateAlarm, nil
}
type UpdateAlarmArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
ID uint32 `xml:"ID"`
StartLocalTime string `xml:"StartLocalTime"`
Duration string `xml:"Duration"`
// Allowed Value: ONCE
// Allowed Value: WEEKDAYS
// Allowed Value: WEEKENDS
// Allowed Value: DAILY
Recurrence string `xml:"Recurrence"`
Enabled bool `xml:"Enabled"`
RoomUUID string `xml:"RoomUUID"`
ProgramURI string `xml:"ProgramURI"`
ProgramMetaData string `xml:"ProgramMetaData"`
// Allowed Value: NORMAL
// Allowed Value: REPEAT_ALL
// Allowed Value: SHUFFLE_NOREPEAT
// Allowed Value: SHUFFLE
PlayMode string `xml:"PlayMode"`
Volume uint16 `xml:"Volume"`
IncludeLinkedZones bool `xml:"IncludeLinkedZones"`
}
type UpdateAlarmResponse struct {
}
func (s *Service) UpdateAlarm(httpClient *http.Client, args *UpdateAlarmArgs) (*UpdateAlarmResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`UpdateAlarm`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{UpdateAlarm: args},
})
if err != nil {
return nil, err
}
if r.Body.UpdateAlarm == nil {
return nil, errors.New(`unexpected respose from service calling alarmclock.UpdateAlarm()`)
}
return r.Body.UpdateAlarm, nil
}
type DestroyAlarmArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
ID uint32 `xml:"ID"`
}
type DestroyAlarmResponse struct {
}
func (s *Service) DestroyAlarm(httpClient *http.Client, args *DestroyAlarmArgs) (*DestroyAlarmResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`DestroyAlarm`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{DestroyAlarm: args},
})
if err != nil {
return nil, err
}
if r.Body.DestroyAlarm == nil {
return nil, errors.New(`unexpected respose from service calling alarmclock.DestroyAlarm()`)
}
return r.Body.DestroyAlarm, nil
}
type ListAlarmsArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
}
type ListAlarmsResponse struct {
CurrentAlarmList string `xml:"CurrentAlarmList"`
CurrentAlarmListVersion string `xml:"CurrentAlarmListVersion"`
}
func (s *Service) ListAlarms(httpClient *http.Client, args *ListAlarmsArgs) (*ListAlarmsResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`ListAlarms`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{ListAlarms: args},
})
if err != nil {
return nil, err
}
if r.Body.ListAlarms == nil {
return nil, errors.New(`unexpected respose from service calling alarmclock.ListAlarms()`)
}
return r.Body.ListAlarms, nil
}
type SetDailyIndexRefreshTimeArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
DesiredDailyIndexRefreshTime string `xml:"DesiredDailyIndexRefreshTime"`
}
type SetDailyIndexRefreshTimeResponse struct {
}
func (s *Service) SetDailyIndexRefreshTime(httpClient *http.Client, args *SetDailyIndexRefreshTimeArgs) (*SetDailyIndexRefreshTimeResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`SetDailyIndexRefreshTime`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{SetDailyIndexRefreshTime: args},
})
if err != nil {
return nil, err
}
if r.Body.SetDailyIndexRefreshTime == nil {
return nil, errors.New(`unexpected respose from service calling alarmclock.SetDailyIndexRefreshTime()`)
}
return r.Body.SetDailyIndexRefreshTime, nil
}
type GetDailyIndexRefreshTimeArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
}
type GetDailyIndexRefreshTimeResponse struct {
CurrentDailyIndexRefreshTime string `xml:"CurrentDailyIndexRefreshTime"`
}
func (s *Service) GetDailyIndexRefreshTime(httpClient *http.Client, args *GetDailyIndexRefreshTimeArgs) (*GetDailyIndexRefreshTimeResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`GetDailyIndexRefreshTime`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{GetDailyIndexRefreshTime: args},
})
if err != nil {
return nil, err
}
if r.Body.GetDailyIndexRefreshTime == nil {
return nil, errors.New(`unexpected respose from service calling alarmclock.GetDailyIndexRefreshTime()`)
}
return r.Body.GetDailyIndexRefreshTime, nil
}
-174
View File
@@ -1,174 +0,0 @@
package connectionmanager
import (
"bytes"
"encoding/xml"
"errors"
"io/ioutil"
"net/http"
"net/url"
)
const (
_ServiceURN = "urn:schemas-upnp-org:service:ConnectionManager:1"
_EncodingSchema = "http://schemas.xmlsoap.org/soap/encoding/"
_EnvelopeSchema = "http://schemas.xmlsoap.org/soap/envelope/"
)
type Service struct {
ControlEndpoint *url.URL
EventEndpoint *url.URL
}
func NewService(deviceUrl *url.URL) *Service {
c, err := url.Parse(`/MediaServer/ConnectionManager/Control`)
if nil != err {
panic(err)
}
e, err := url.Parse(`/MediaServer/ConnectionManager/Event`)
if nil != err {
panic(err)
}
return &Service{
ControlEndpoint: deviceUrl.ResolveReference(c),
EventEndpoint: deviceUrl.ResolveReference(e),
}
}
type Envelope struct {
XMLName xml.Name `xml:"s:Envelope"`
Xmlns string `xml:"xmlns:s,attr"`
EncodingStyle string `xml:"s:encodingStyle,attr"`
Body Body `xml:"s:Body"`
}
type Body struct {
XMLName xml.Name `xml:"s:Body"`
GetProtocolInfo *GetProtocolInfoArgs `xml:"u:GetProtocolInfo,omitempty"`
GetCurrentConnectionIDs *GetCurrentConnectionIDsArgs `xml:"u:GetCurrentConnectionIDs,omitempty"`
GetCurrentConnectionInfo *GetCurrentConnectionInfoArgs `xml:"u:GetCurrentConnectionInfo,omitempty"`
}
type EnvelopeResponse struct {
XMLName xml.Name `xml:"Envelope"`
Xmlns string `xml:"xmlns:s,attr"`
EncodingStyle string `xml:"encodingStyle,attr"`
Body BodyResponse `xml:"Body"`
}
type BodyResponse struct {
XMLName xml.Name `xml:"Body"`
GetProtocolInfo *GetProtocolInfoResponse `xml:"GetProtocolInfoResponse,omitempty"`
GetCurrentConnectionIDs *GetCurrentConnectionIDsResponse `xml:"GetCurrentConnectionIDsResponse,omitempty"`
GetCurrentConnectionInfo *GetCurrentConnectionInfoResponse `xml:"GetCurrentConnectionInfoResponse,omitempty"`
}
func (s *Service) exec(actionName string, httpClient *http.Client, envelope *Envelope) (*EnvelopeResponse, error) {
marshaled, err := xml.Marshal(envelope)
if err != nil {
return nil, err
}
postBody := []byte(`<?xml version="1.0"?>`)
postBody = append(postBody, marshaled...)
req, err := http.NewRequest(`POST`, s.ControlEndpoint.String(), bytes.NewBuffer(postBody))
if err != nil {
return nil, err
}
req.Header.Set(`Content-Type`, `text/xml; charset="utf-8"`)
req.Header.Set(`SOAPAction`, _ServiceURN+`#`+actionName)
res, err := httpClient.Do(req)
if err != nil {
return nil, err
}
defer res.Body.Close()
responseBody, err := ioutil.ReadAll(res.Body)
if err != nil {
return nil, err
}
var envelopeResponse EnvelopeResponse
err = xml.Unmarshal(responseBody, &envelopeResponse)
if err != nil {
return nil, err
}
return &envelopeResponse, nil
}
type GetProtocolInfoArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
}
type GetProtocolInfoResponse struct {
Source string `xml:"Source"`
Sink string `xml:"Sink"`
}
func (s *Service) GetProtocolInfo(httpClient *http.Client, args *GetProtocolInfoArgs) (*GetProtocolInfoResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`GetProtocolInfo`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{GetProtocolInfo: args},
})
if err != nil {
return nil, err
}
if r.Body.GetProtocolInfo == nil {
return nil, errors.New(`unexpected respose from service calling connectionmanager.GetProtocolInfo()`)
}
return r.Body.GetProtocolInfo, nil
}
type GetCurrentConnectionIDsArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
}
type GetCurrentConnectionIDsResponse struct {
ConnectionIDs string `xml:"ConnectionIDs"`
}
func (s *Service) GetCurrentConnectionIDs(httpClient *http.Client, args *GetCurrentConnectionIDsArgs) (*GetCurrentConnectionIDsResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`GetCurrentConnectionIDs`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{GetCurrentConnectionIDs: args},
})
if err != nil {
return nil, err
}
if r.Body.GetCurrentConnectionIDs == nil {
return nil, errors.New(`unexpected respose from service calling connectionmanager.GetCurrentConnectionIDs()`)
}
return r.Body.GetCurrentConnectionIDs, nil
}
type GetCurrentConnectionInfoArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
ConnectionID int32 `xml:"ConnectionID"`
}
type GetCurrentConnectionInfoResponse struct {
RcsID int32 `xml:"RcsID"`
AVTransportID int32 `xml:"AVTransportID"`
ProtocolInfo string `xml:"ProtocolInfo"`
PeerConnectionManager string `xml:"PeerConnectionManager"`
PeerConnectionID int32 `xml:"PeerConnectionID"`
Direction string `xml:"Direction"`
Status string `xml:"Status"`
}
func (s *Service) GetCurrentConnectionInfo(httpClient *http.Client, args *GetCurrentConnectionInfoArgs) (*GetCurrentConnectionInfoResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`GetCurrentConnectionInfo`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{GetCurrentConnectionInfo: args},
})
if err != nil {
return nil, err
}
if r.Body.GetCurrentConnectionInfo == nil {
return nil, errors.New(`unexpected respose from service calling connectionmanager.GetCurrentConnectionInfo()`)
}
return r.Body.GetCurrentConnectionInfo, nil
}
-539
View File
@@ -1,539 +0,0 @@
package contentdirectory
import (
"bytes"
"encoding/xml"
"errors"
"io/ioutil"
"net/http"
"net/url"
)
const (
_ServiceURN = "urn:schemas-upnp-org:service:ContentDirectory:1"
_EncodingSchema = "http://schemas.xmlsoap.org/soap/encoding/"
_EnvelopeSchema = "http://schemas.xmlsoap.org/soap/envelope/"
)
type Service struct {
ControlEndpoint *url.URL
EventEndpoint *url.URL
}
func NewService(deviceUrl *url.URL) *Service {
c, err := url.Parse(`/MediaServer/ContentDirectory/Control`)
if nil != err {
panic(err)
}
e, err := url.Parse(`/MediaServer/ContentDirectory/Event`)
if nil != err {
panic(err)
}
return &Service{
ControlEndpoint: deviceUrl.ResolveReference(c),
EventEndpoint: deviceUrl.ResolveReference(e),
}
}
type Envelope struct {
XMLName xml.Name `xml:"s:Envelope"`
Xmlns string `xml:"xmlns:s,attr"`
EncodingStyle string `xml:"s:encodingStyle,attr"`
Body Body `xml:"s:Body"`
}
type Body struct {
XMLName xml.Name `xml:"s:Body"`
GetSearchCapabilities *GetSearchCapabilitiesArgs `xml:"u:GetSearchCapabilities,omitempty"`
GetSortCapabilities *GetSortCapabilitiesArgs `xml:"u:GetSortCapabilities,omitempty"`
GetSystemUpdateID *GetSystemUpdateIDArgs `xml:"u:GetSystemUpdateID,omitempty"`
GetAlbumArtistDisplayOption *GetAlbumArtistDisplayOptionArgs `xml:"u:GetAlbumArtistDisplayOption,omitempty"`
GetLastIndexChange *GetLastIndexChangeArgs `xml:"u:GetLastIndexChange,omitempty"`
Browse *BrowseArgs `xml:"u:Browse,omitempty"`
FindPrefix *FindPrefixArgs `xml:"u:FindPrefix,omitempty"`
GetAllPrefixLocations *GetAllPrefixLocationsArgs `xml:"u:GetAllPrefixLocations,omitempty"`
CreateObject *CreateObjectArgs `xml:"u:CreateObject,omitempty"`
UpdateObject *UpdateObjectArgs `xml:"u:UpdateObject,omitempty"`
DestroyObject *DestroyObjectArgs `xml:"u:DestroyObject,omitempty"`
RefreshShareIndex *RefreshShareIndexArgs `xml:"u:RefreshShareIndex,omitempty"`
RequestResort *RequestResortArgs `xml:"u:RequestResort,omitempty"`
GetShareIndexInProgress *GetShareIndexInProgressArgs `xml:"u:GetShareIndexInProgress,omitempty"`
GetBrowseable *GetBrowseableArgs `xml:"u:GetBrowseable,omitempty"`
SetBrowseable *SetBrowseableArgs `xml:"u:SetBrowseable,omitempty"`
}
type EnvelopeResponse struct {
XMLName xml.Name `xml:"Envelope"`
Xmlns string `xml:"xmlns:s,attr"`
EncodingStyle string `xml:"encodingStyle,attr"`
Body BodyResponse `xml:"Body"`
}
type BodyResponse struct {
XMLName xml.Name `xml:"Body"`
GetSearchCapabilities *GetSearchCapabilitiesResponse `xml:"GetSearchCapabilitiesResponse,omitempty"`
GetSortCapabilities *GetSortCapabilitiesResponse `xml:"GetSortCapabilitiesResponse,omitempty"`
GetSystemUpdateID *GetSystemUpdateIDResponse `xml:"GetSystemUpdateIDResponse,omitempty"`
GetAlbumArtistDisplayOption *GetAlbumArtistDisplayOptionResponse `xml:"GetAlbumArtistDisplayOptionResponse,omitempty"`
GetLastIndexChange *GetLastIndexChangeResponse `xml:"GetLastIndexChangeResponse,omitempty"`
Browse *BrowseResponse `xml:"BrowseResponse,omitempty"`
FindPrefix *FindPrefixResponse `xml:"FindPrefixResponse,omitempty"`
GetAllPrefixLocations *GetAllPrefixLocationsResponse `xml:"GetAllPrefixLocationsResponse,omitempty"`
CreateObject *CreateObjectResponse `xml:"CreateObjectResponse,omitempty"`
UpdateObject *UpdateObjectResponse `xml:"UpdateObjectResponse,omitempty"`
DestroyObject *DestroyObjectResponse `xml:"DestroyObjectResponse,omitempty"`
RefreshShareIndex *RefreshShareIndexResponse `xml:"RefreshShareIndexResponse,omitempty"`
RequestResort *RequestResortResponse `xml:"RequestResortResponse,omitempty"`
GetShareIndexInProgress *GetShareIndexInProgressResponse `xml:"GetShareIndexInProgressResponse,omitempty"`
GetBrowseable *GetBrowseableResponse `xml:"GetBrowseableResponse,omitempty"`
SetBrowseable *SetBrowseableResponse `xml:"SetBrowseableResponse,omitempty"`
}
func (s *Service) exec(actionName string, httpClient *http.Client, envelope *Envelope) (*EnvelopeResponse, error) {
marshaled, err := xml.Marshal(envelope)
if err != nil {
return nil, err
}
postBody := []byte(`<?xml version="1.0"?>`)
postBody = append(postBody, marshaled...)
req, err := http.NewRequest(`POST`, s.ControlEndpoint.String(), bytes.NewBuffer(postBody))
if err != nil {
return nil, err
}
req.Header.Set(`Content-Type`, `text/xml; charset="utf-8"`)
req.Header.Set(`SOAPAction`, _ServiceURN+`#`+actionName)
res, err := httpClient.Do(req)
if err != nil {
return nil, err
}
defer res.Body.Close()
responseBody, err := ioutil.ReadAll(res.Body)
if err != nil {
return nil, err
}
var envelopeResponse EnvelopeResponse
err = xml.Unmarshal(responseBody, &envelopeResponse)
if err != nil {
return nil, err
}
return &envelopeResponse, nil
}
type GetSearchCapabilitiesArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
}
type GetSearchCapabilitiesResponse struct {
SearchCaps string `xml:"SearchCaps"`
}
func (s *Service) GetSearchCapabilities(httpClient *http.Client, args *GetSearchCapabilitiesArgs) (*GetSearchCapabilitiesResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`GetSearchCapabilities`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{GetSearchCapabilities: args},
})
if err != nil {
return nil, err
}
if r.Body.GetSearchCapabilities == nil {
return nil, errors.New(`unexpected respose from service calling contentdirectory.GetSearchCapabilities()`)
}
return r.Body.GetSearchCapabilities, nil
}
type GetSortCapabilitiesArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
}
type GetSortCapabilitiesResponse struct {
SortCaps string `xml:"SortCaps"`
}
func (s *Service) GetSortCapabilities(httpClient *http.Client, args *GetSortCapabilitiesArgs) (*GetSortCapabilitiesResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`GetSortCapabilities`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{GetSortCapabilities: args},
})
if err != nil {
return nil, err
}
if r.Body.GetSortCapabilities == nil {
return nil, errors.New(`unexpected respose from service calling contentdirectory.GetSortCapabilities()`)
}
return r.Body.GetSortCapabilities, nil
}
type GetSystemUpdateIDArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
}
type GetSystemUpdateIDResponse struct {
Id uint32 `xml:"Id"`
}
func (s *Service) GetSystemUpdateID(httpClient *http.Client, args *GetSystemUpdateIDArgs) (*GetSystemUpdateIDResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`GetSystemUpdateID`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{GetSystemUpdateID: args},
})
if err != nil {
return nil, err
}
if r.Body.GetSystemUpdateID == nil {
return nil, errors.New(`unexpected respose from service calling contentdirectory.GetSystemUpdateID()`)
}
return r.Body.GetSystemUpdateID, nil
}
type GetAlbumArtistDisplayOptionArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
}
type GetAlbumArtistDisplayOptionResponse struct {
AlbumArtistDisplayOption string `xml:"AlbumArtistDisplayOption"`
}
func (s *Service) GetAlbumArtistDisplayOption(httpClient *http.Client, args *GetAlbumArtistDisplayOptionArgs) (*GetAlbumArtistDisplayOptionResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`GetAlbumArtistDisplayOption`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{GetAlbumArtistDisplayOption: args},
})
if err != nil {
return nil, err
}
if r.Body.GetAlbumArtistDisplayOption == nil {
return nil, errors.New(`unexpected respose from service calling contentdirectory.GetAlbumArtistDisplayOption()`)
}
return r.Body.GetAlbumArtistDisplayOption, nil
}
type GetLastIndexChangeArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
}
type GetLastIndexChangeResponse struct {
LastIndexChange string `xml:"LastIndexChange"`
}
func (s *Service) GetLastIndexChange(httpClient *http.Client, args *GetLastIndexChangeArgs) (*GetLastIndexChangeResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`GetLastIndexChange`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{GetLastIndexChange: args},
})
if err != nil {
return nil, err
}
if r.Body.GetLastIndexChange == nil {
return nil, errors.New(`unexpected respose from service calling contentdirectory.GetLastIndexChange()`)
}
return r.Body.GetLastIndexChange, nil
}
type BrowseArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
ObjectID string `xml:"ObjectID"`
// Allowed Value: BrowseMetadata
// Allowed Value: BrowseDirectChildren
BrowseFlag string `xml:"BrowseFlag"`
Filter string `xml:"Filter"`
StartingIndex uint32 `xml:"StartingIndex"`
RequestedCount uint32 `xml:"RequestedCount"`
SortCriteria string `xml:"SortCriteria"`
}
type BrowseResponse struct {
Result string `xml:"Result"`
NumberReturned uint32 `xml:"NumberReturned"`
TotalMatches uint32 `xml:"TotalMatches"`
UpdateID uint32 `xml:"UpdateID"`
}
func (s *Service) Browse(httpClient *http.Client, args *BrowseArgs) (*BrowseResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`Browse`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{Browse: args},
})
if err != nil {
return nil, err
}
if r.Body.Browse == nil {
return nil, errors.New(`unexpected respose from service calling contentdirectory.Browse()`)
}
return r.Body.Browse, nil
}
type FindPrefixArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
ObjectID string `xml:"ObjectID"`
Prefix string `xml:"Prefix"`
}
type FindPrefixResponse struct {
StartingIndex uint32 `xml:"StartingIndex"`
UpdateID uint32 `xml:"UpdateID"`
}
func (s *Service) FindPrefix(httpClient *http.Client, args *FindPrefixArgs) (*FindPrefixResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`FindPrefix`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{FindPrefix: args},
})
if err != nil {
return nil, err
}
if r.Body.FindPrefix == nil {
return nil, errors.New(`unexpected respose from service calling contentdirectory.FindPrefix()`)
}
return r.Body.FindPrefix, nil
}
type GetAllPrefixLocationsArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
ObjectID string `xml:"ObjectID"`
}
type GetAllPrefixLocationsResponse struct {
TotalPrefixes uint32 `xml:"TotalPrefixes"`
PrefixAndIndexCSV string `xml:"PrefixAndIndexCSV"`
UpdateID uint32 `xml:"UpdateID"`
}
func (s *Service) GetAllPrefixLocations(httpClient *http.Client, args *GetAllPrefixLocationsArgs) (*GetAllPrefixLocationsResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`GetAllPrefixLocations`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{GetAllPrefixLocations: args},
})
if err != nil {
return nil, err
}
if r.Body.GetAllPrefixLocations == nil {
return nil, errors.New(`unexpected respose from service calling contentdirectory.GetAllPrefixLocations()`)
}
return r.Body.GetAllPrefixLocations, nil
}
type CreateObjectArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
ContainerID string `xml:"ContainerID"`
Elements string `xml:"Elements"`
}
type CreateObjectResponse struct {
ObjectID string `xml:"ObjectID"`
Result string `xml:"Result"`
}
func (s *Service) CreateObject(httpClient *http.Client, args *CreateObjectArgs) (*CreateObjectResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`CreateObject`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{CreateObject: args},
})
if err != nil {
return nil, err
}
if r.Body.CreateObject == nil {
return nil, errors.New(`unexpected respose from service calling contentdirectory.CreateObject()`)
}
return r.Body.CreateObject, nil
}
type UpdateObjectArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
ObjectID string `xml:"ObjectID"`
CurrentTagValue string `xml:"CurrentTagValue"`
NewTagValue string `xml:"NewTagValue"`
}
type UpdateObjectResponse struct {
}
func (s *Service) UpdateObject(httpClient *http.Client, args *UpdateObjectArgs) (*UpdateObjectResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`UpdateObject`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{UpdateObject: args},
})
if err != nil {
return nil, err
}
if r.Body.UpdateObject == nil {
return nil, errors.New(`unexpected respose from service calling contentdirectory.UpdateObject()`)
}
return r.Body.UpdateObject, nil
}
type DestroyObjectArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
ObjectID string `xml:"ObjectID"`
}
type DestroyObjectResponse struct {
}
func (s *Service) DestroyObject(httpClient *http.Client, args *DestroyObjectArgs) (*DestroyObjectResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`DestroyObject`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{DestroyObject: args},
})
if err != nil {
return nil, err
}
if r.Body.DestroyObject == nil {
return nil, errors.New(`unexpected respose from service calling contentdirectory.DestroyObject()`)
}
return r.Body.DestroyObject, nil
}
type RefreshShareIndexArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
AlbumArtistDisplayOption string `xml:"AlbumArtistDisplayOption"`
}
type RefreshShareIndexResponse struct {
}
func (s *Service) RefreshShareIndex(httpClient *http.Client, args *RefreshShareIndexArgs) (*RefreshShareIndexResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`RefreshShareIndex`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{RefreshShareIndex: args},
})
if err != nil {
return nil, err
}
if r.Body.RefreshShareIndex == nil {
return nil, errors.New(`unexpected respose from service calling contentdirectory.RefreshShareIndex()`)
}
return r.Body.RefreshShareIndex, nil
}
type RequestResortArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
SortOrder string `xml:"SortOrder"`
}
type RequestResortResponse struct {
}
func (s *Service) RequestResort(httpClient *http.Client, args *RequestResortArgs) (*RequestResortResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`RequestResort`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{RequestResort: args},
})
if err != nil {
return nil, err
}
if r.Body.RequestResort == nil {
return nil, errors.New(`unexpected respose from service calling contentdirectory.RequestResort()`)
}
return r.Body.RequestResort, nil
}
type GetShareIndexInProgressArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
}
type GetShareIndexInProgressResponse struct {
IsIndexing bool `xml:"IsIndexing"`
}
func (s *Service) GetShareIndexInProgress(httpClient *http.Client, args *GetShareIndexInProgressArgs) (*GetShareIndexInProgressResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`GetShareIndexInProgress`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{GetShareIndexInProgress: args},
})
if err != nil {
return nil, err
}
if r.Body.GetShareIndexInProgress == nil {
return nil, errors.New(`unexpected respose from service calling contentdirectory.GetShareIndexInProgress()`)
}
return r.Body.GetShareIndexInProgress, nil
}
type GetBrowseableArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
}
type GetBrowseableResponse struct {
IsBrowseable bool `xml:"IsBrowseable"`
}
func (s *Service) GetBrowseable(httpClient *http.Client, args *GetBrowseableArgs) (*GetBrowseableResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`GetBrowseable`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{GetBrowseable: args},
})
if err != nil {
return nil, err
}
if r.Body.GetBrowseable == nil {
return nil, errors.New(`unexpected respose from service calling contentdirectory.GetBrowseable()`)
}
return r.Body.GetBrowseable, nil
}
type SetBrowseableArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
Browseable bool `xml:"Browseable"`
}
type SetBrowseableResponse struct {
}
func (s *Service) SetBrowseable(httpClient *http.Client, args *SetBrowseableArgs) (*SetBrowseableResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`SetBrowseable`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{SetBrowseable: args},
})
if err != nil {
return nil, err
}
if r.Body.SetBrowseable == nil {
return nil, errors.New(`unexpected respose from service calling contentdirectory.SetBrowseable()`)
}
return r.Body.SetBrowseable, nil
}
-789
View File
@@ -1,789 +0,0 @@
package deviceproperties
import (
"bytes"
"encoding/xml"
"errors"
"io/ioutil"
"net/http"
"net/url"
)
const (
_ServiceURN = "urn:schemas-upnp-org:service:DeviceProperties:1"
_EncodingSchema = "http://schemas.xmlsoap.org/soap/encoding/"
_EnvelopeSchema = "http://schemas.xmlsoap.org/soap/envelope/"
)
type Service struct {
ControlEndpoint *url.URL
EventEndpoint *url.URL
}
func NewService(deviceUrl *url.URL) *Service {
c, err := url.Parse(`/DeviceProperties/Control`)
if nil != err {
panic(err)
}
e, err := url.Parse(`/DeviceProperties/Event`)
if nil != err {
panic(err)
}
return &Service{
ControlEndpoint: deviceUrl.ResolveReference(c),
EventEndpoint: deviceUrl.ResolveReference(e),
}
}
type Envelope struct {
XMLName xml.Name `xml:"s:Envelope"`
Xmlns string `xml:"xmlns:s,attr"`
EncodingStyle string `xml:"s:encodingStyle,attr"`
Body Body `xml:"s:Body"`
}
type Body struct {
XMLName xml.Name `xml:"s:Body"`
SetLEDState *SetLEDStateArgs `xml:"u:SetLEDState,omitempty"`
GetLEDState *GetLEDStateArgs `xml:"u:GetLEDState,omitempty"`
AddBondedZones *AddBondedZonesArgs `xml:"u:AddBondedZones,omitempty"`
RemoveBondedZones *RemoveBondedZonesArgs `xml:"u:RemoveBondedZones,omitempty"`
CreateStereoPair *CreateStereoPairArgs `xml:"u:CreateStereoPair,omitempty"`
SeparateStereoPair *SeparateStereoPairArgs `xml:"u:SeparateStereoPair,omitempty"`
SetZoneAttributes *SetZoneAttributesArgs `xml:"u:SetZoneAttributes,omitempty"`
GetZoneAttributes *GetZoneAttributesArgs `xml:"u:GetZoneAttributes,omitempty"`
GetHouseholdID *GetHouseholdIDArgs `xml:"u:GetHouseholdID,omitempty"`
GetZoneInfo *GetZoneInfoArgs `xml:"u:GetZoneInfo,omitempty"`
SetAutoplayLinkedZones *SetAutoplayLinkedZonesArgs `xml:"u:SetAutoplayLinkedZones,omitempty"`
GetAutoplayLinkedZones *GetAutoplayLinkedZonesArgs `xml:"u:GetAutoplayLinkedZones,omitempty"`
SetAutoplayRoomUUID *SetAutoplayRoomUUIDArgs `xml:"u:SetAutoplayRoomUUID,omitempty"`
GetAutoplayRoomUUID *GetAutoplayRoomUUIDArgs `xml:"u:GetAutoplayRoomUUID,omitempty"`
SetAutoplayVolume *SetAutoplayVolumeArgs `xml:"u:SetAutoplayVolume,omitempty"`
GetAutoplayVolume *GetAutoplayVolumeArgs `xml:"u:GetAutoplayVolume,omitempty"`
SetUseAutoplayVolume *SetUseAutoplayVolumeArgs `xml:"u:SetUseAutoplayVolume,omitempty"`
GetUseAutoplayVolume *GetUseAutoplayVolumeArgs `xml:"u:GetUseAutoplayVolume,omitempty"`
AddHTSatellite *AddHTSatelliteArgs `xml:"u:AddHTSatellite,omitempty"`
RemoveHTSatellite *RemoveHTSatelliteArgs `xml:"u:RemoveHTSatellite,omitempty"`
EnterConfigMode *EnterConfigModeArgs `xml:"u:EnterConfigMode,omitempty"`
ExitConfigMode *ExitConfigModeArgs `xml:"u:ExitConfigMode,omitempty"`
GetButtonState *GetButtonStateArgs `xml:"u:GetButtonState,omitempty"`
SetButtonLockState *SetButtonLockStateArgs `xml:"u:SetButtonLockState,omitempty"`
GetButtonLockState *GetButtonLockStateArgs `xml:"u:GetButtonLockState,omitempty"`
}
type EnvelopeResponse struct {
XMLName xml.Name `xml:"Envelope"`
Xmlns string `xml:"xmlns:s,attr"`
EncodingStyle string `xml:"encodingStyle,attr"`
Body BodyResponse `xml:"Body"`
}
type BodyResponse struct {
XMLName xml.Name `xml:"Body"`
SetLEDState *SetLEDStateResponse `xml:"SetLEDStateResponse,omitempty"`
GetLEDState *GetLEDStateResponse `xml:"GetLEDStateResponse,omitempty"`
AddBondedZones *AddBondedZonesResponse `xml:"AddBondedZonesResponse,omitempty"`
RemoveBondedZones *RemoveBondedZonesResponse `xml:"RemoveBondedZonesResponse,omitempty"`
CreateStereoPair *CreateStereoPairResponse `xml:"CreateStereoPairResponse,omitempty"`
SeparateStereoPair *SeparateStereoPairResponse `xml:"SeparateStereoPairResponse,omitempty"`
SetZoneAttributes *SetZoneAttributesResponse `xml:"SetZoneAttributesResponse,omitempty"`
GetZoneAttributes *GetZoneAttributesResponse `xml:"GetZoneAttributesResponse,omitempty"`
GetHouseholdID *GetHouseholdIDResponse `xml:"GetHouseholdIDResponse,omitempty"`
GetZoneInfo *GetZoneInfoResponse `xml:"GetZoneInfoResponse,omitempty"`
SetAutoplayLinkedZones *SetAutoplayLinkedZonesResponse `xml:"SetAutoplayLinkedZonesResponse,omitempty"`
GetAutoplayLinkedZones *GetAutoplayLinkedZonesResponse `xml:"GetAutoplayLinkedZonesResponse,omitempty"`
SetAutoplayRoomUUID *SetAutoplayRoomUUIDResponse `xml:"SetAutoplayRoomUUIDResponse,omitempty"`
GetAutoplayRoomUUID *GetAutoplayRoomUUIDResponse `xml:"GetAutoplayRoomUUIDResponse,omitempty"`
SetAutoplayVolume *SetAutoplayVolumeResponse `xml:"SetAutoplayVolumeResponse,omitempty"`
GetAutoplayVolume *GetAutoplayVolumeResponse `xml:"GetAutoplayVolumeResponse,omitempty"`
SetUseAutoplayVolume *SetUseAutoplayVolumeResponse `xml:"SetUseAutoplayVolumeResponse,omitempty"`
GetUseAutoplayVolume *GetUseAutoplayVolumeResponse `xml:"GetUseAutoplayVolumeResponse,omitempty"`
AddHTSatellite *AddHTSatelliteResponse `xml:"AddHTSatelliteResponse,omitempty"`
RemoveHTSatellite *RemoveHTSatelliteResponse `xml:"RemoveHTSatelliteResponse,omitempty"`
EnterConfigMode *EnterConfigModeResponse `xml:"EnterConfigModeResponse,omitempty"`
ExitConfigMode *ExitConfigModeResponse `xml:"ExitConfigModeResponse,omitempty"`
GetButtonState *GetButtonStateResponse `xml:"GetButtonStateResponse,omitempty"`
SetButtonLockState *SetButtonLockStateResponse `xml:"SetButtonLockStateResponse,omitempty"`
GetButtonLockState *GetButtonLockStateResponse `xml:"GetButtonLockStateResponse,omitempty"`
}
func (s *Service) exec(actionName string, httpClient *http.Client, envelope *Envelope) (*EnvelopeResponse, error) {
marshaled, err := xml.Marshal(envelope)
if err != nil {
return nil, err
}
postBody := []byte(`<?xml version="1.0"?>`)
postBody = append(postBody, marshaled...)
req, err := http.NewRequest(`POST`, s.ControlEndpoint.String(), bytes.NewBuffer(postBody))
if err != nil {
return nil, err
}
req.Header.Set(`Content-Type`, `text/xml; charset="utf-8"`)
req.Header.Set(`SOAPAction`, _ServiceURN+`#`+actionName)
res, err := httpClient.Do(req)
if err != nil {
return nil, err
}
defer res.Body.Close()
responseBody, err := ioutil.ReadAll(res.Body)
if err != nil {
return nil, err
}
var envelopeResponse EnvelopeResponse
err = xml.Unmarshal(responseBody, &envelopeResponse)
if err != nil {
return nil, err
}
return &envelopeResponse, nil
}
type SetLEDStateArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
// Allowed Value: On
// Allowed Value: Off
DesiredLEDState string `xml:"DesiredLEDState"`
}
type SetLEDStateResponse struct {
}
func (s *Service) SetLEDState(httpClient *http.Client, args *SetLEDStateArgs) (*SetLEDStateResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`SetLEDState`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{SetLEDState: args},
})
if err != nil {
return nil, err
}
if r.Body.SetLEDState == nil {
return nil, errors.New(`unexpected respose from service calling deviceproperties.SetLEDState()`)
}
return r.Body.SetLEDState, nil
}
type GetLEDStateArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
}
type GetLEDStateResponse struct {
CurrentLEDState string `xml:"CurrentLEDState"`
}
func (s *Service) GetLEDState(httpClient *http.Client, args *GetLEDStateArgs) (*GetLEDStateResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`GetLEDState`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{GetLEDState: args},
})
if err != nil {
return nil, err
}
if r.Body.GetLEDState == nil {
return nil, errors.New(`unexpected respose from service calling deviceproperties.GetLEDState()`)
}
return r.Body.GetLEDState, nil
}
type AddBondedZonesArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
ChannelMapSet string `xml:"ChannelMapSet"`
}
type AddBondedZonesResponse struct {
}
func (s *Service) AddBondedZones(httpClient *http.Client, args *AddBondedZonesArgs) (*AddBondedZonesResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`AddBondedZones`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{AddBondedZones: args},
})
if err != nil {
return nil, err
}
if r.Body.AddBondedZones == nil {
return nil, errors.New(`unexpected respose from service calling deviceproperties.AddBondedZones()`)
}
return r.Body.AddBondedZones, nil
}
type RemoveBondedZonesArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
ChannelMapSet string `xml:"ChannelMapSet"`
KeepGrouped bool `xml:"KeepGrouped"`
}
type RemoveBondedZonesResponse struct {
}
func (s *Service) RemoveBondedZones(httpClient *http.Client, args *RemoveBondedZonesArgs) (*RemoveBondedZonesResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`RemoveBondedZones`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{RemoveBondedZones: args},
})
if err != nil {
return nil, err
}
if r.Body.RemoveBondedZones == nil {
return nil, errors.New(`unexpected respose from service calling deviceproperties.RemoveBondedZones()`)
}
return r.Body.RemoveBondedZones, nil
}
type CreateStereoPairArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
ChannelMapSet string `xml:"ChannelMapSet"`
}
type CreateStereoPairResponse struct {
}
func (s *Service) CreateStereoPair(httpClient *http.Client, args *CreateStereoPairArgs) (*CreateStereoPairResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`CreateStereoPair`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{CreateStereoPair: args},
})
if err != nil {
return nil, err
}
if r.Body.CreateStereoPair == nil {
return nil, errors.New(`unexpected respose from service calling deviceproperties.CreateStereoPair()`)
}
return r.Body.CreateStereoPair, nil
}
type SeparateStereoPairArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
ChannelMapSet string `xml:"ChannelMapSet"`
}
type SeparateStereoPairResponse struct {
}
func (s *Service) SeparateStereoPair(httpClient *http.Client, args *SeparateStereoPairArgs) (*SeparateStereoPairResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`SeparateStereoPair`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{SeparateStereoPair: args},
})
if err != nil {
return nil, err
}
if r.Body.SeparateStereoPair == nil {
return nil, errors.New(`unexpected respose from service calling deviceproperties.SeparateStereoPair()`)
}
return r.Body.SeparateStereoPair, nil
}
type SetZoneAttributesArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
DesiredZoneName string `xml:"DesiredZoneName"`
DesiredIcon string `xml:"DesiredIcon"`
DesiredConfiguration string `xml:"DesiredConfiguration"`
}
type SetZoneAttributesResponse struct {
}
func (s *Service) SetZoneAttributes(httpClient *http.Client, args *SetZoneAttributesArgs) (*SetZoneAttributesResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`SetZoneAttributes`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{SetZoneAttributes: args},
})
if err != nil {
return nil, err
}
if r.Body.SetZoneAttributes == nil {
return nil, errors.New(`unexpected respose from service calling deviceproperties.SetZoneAttributes()`)
}
return r.Body.SetZoneAttributes, nil
}
type GetZoneAttributesArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
}
type GetZoneAttributesResponse struct {
CurrentZoneName string `xml:"CurrentZoneName"`
CurrentIcon string `xml:"CurrentIcon"`
CurrentConfiguration string `xml:"CurrentConfiguration"`
}
func (s *Service) GetZoneAttributes(httpClient *http.Client, args *GetZoneAttributesArgs) (*GetZoneAttributesResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`GetZoneAttributes`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{GetZoneAttributes: args},
})
if err != nil {
return nil, err
}
if r.Body.GetZoneAttributes == nil {
return nil, errors.New(`unexpected respose from service calling deviceproperties.GetZoneAttributes()`)
}
return r.Body.GetZoneAttributes, nil
}
type GetHouseholdIDArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
}
type GetHouseholdIDResponse struct {
CurrentHouseholdID string `xml:"CurrentHouseholdID"`
}
func (s *Service) GetHouseholdID(httpClient *http.Client, args *GetHouseholdIDArgs) (*GetHouseholdIDResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`GetHouseholdID`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{GetHouseholdID: args},
})
if err != nil {
return nil, err
}
if r.Body.GetHouseholdID == nil {
return nil, errors.New(`unexpected respose from service calling deviceproperties.GetHouseholdID()`)
}
return r.Body.GetHouseholdID, nil
}
type GetZoneInfoArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
}
type GetZoneInfoResponse struct {
SerialNumber string `xml:"SerialNumber"`
SoftwareVersion string `xml:"SoftwareVersion"`
DisplaySoftwareVersion string `xml:"DisplaySoftwareVersion"`
HardwareVersion string `xml:"HardwareVersion"`
IPAddress string `xml:"IPAddress"`
MACAddress string `xml:"MACAddress"`
CopyrightInfo string `xml:"CopyrightInfo"`
ExtraInfo string `xml:"ExtraInfo"`
HTAudioIn uint32 `xml:"HTAudioIn"`
Flags uint32 `xml:"Flags"`
}
func (s *Service) GetZoneInfo(httpClient *http.Client, args *GetZoneInfoArgs) (*GetZoneInfoResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`GetZoneInfo`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{GetZoneInfo: args},
})
if err != nil {
return nil, err
}
if r.Body.GetZoneInfo == nil {
return nil, errors.New(`unexpected respose from service calling deviceproperties.GetZoneInfo()`)
}
return r.Body.GetZoneInfo, nil
}
type SetAutoplayLinkedZonesArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
IncludeLinkedZones bool `xml:"IncludeLinkedZones"`
Source string `xml:"Source"`
}
type SetAutoplayLinkedZonesResponse struct {
}
func (s *Service) SetAutoplayLinkedZones(httpClient *http.Client, args *SetAutoplayLinkedZonesArgs) (*SetAutoplayLinkedZonesResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`SetAutoplayLinkedZones`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{SetAutoplayLinkedZones: args},
})
if err != nil {
return nil, err
}
if r.Body.SetAutoplayLinkedZones == nil {
return nil, errors.New(`unexpected respose from service calling deviceproperties.SetAutoplayLinkedZones()`)
}
return r.Body.SetAutoplayLinkedZones, nil
}
type GetAutoplayLinkedZonesArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
Source string `xml:"Source"`
}
type GetAutoplayLinkedZonesResponse struct {
IncludeLinkedZones bool `xml:"IncludeLinkedZones"`
}
func (s *Service) GetAutoplayLinkedZones(httpClient *http.Client, args *GetAutoplayLinkedZonesArgs) (*GetAutoplayLinkedZonesResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`GetAutoplayLinkedZones`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{GetAutoplayLinkedZones: args},
})
if err != nil {
return nil, err
}
if r.Body.GetAutoplayLinkedZones == nil {
return nil, errors.New(`unexpected respose from service calling deviceproperties.GetAutoplayLinkedZones()`)
}
return r.Body.GetAutoplayLinkedZones, nil
}
type SetAutoplayRoomUUIDArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
RoomUUID string `xml:"RoomUUID"`
Source string `xml:"Source"`
}
type SetAutoplayRoomUUIDResponse struct {
}
func (s *Service) SetAutoplayRoomUUID(httpClient *http.Client, args *SetAutoplayRoomUUIDArgs) (*SetAutoplayRoomUUIDResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`SetAutoplayRoomUUID`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{SetAutoplayRoomUUID: args},
})
if err != nil {
return nil, err
}
if r.Body.SetAutoplayRoomUUID == nil {
return nil, errors.New(`unexpected respose from service calling deviceproperties.SetAutoplayRoomUUID()`)
}
return r.Body.SetAutoplayRoomUUID, nil
}
type GetAutoplayRoomUUIDArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
Source string `xml:"Source"`
}
type GetAutoplayRoomUUIDResponse struct {
RoomUUID string `xml:"RoomUUID"`
}
func (s *Service) GetAutoplayRoomUUID(httpClient *http.Client, args *GetAutoplayRoomUUIDArgs) (*GetAutoplayRoomUUIDResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`GetAutoplayRoomUUID`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{GetAutoplayRoomUUID: args},
})
if err != nil {
return nil, err
}
if r.Body.GetAutoplayRoomUUID == nil {
return nil, errors.New(`unexpected respose from service calling deviceproperties.GetAutoplayRoomUUID()`)
}
return r.Body.GetAutoplayRoomUUID, nil
}
type SetAutoplayVolumeArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
// Allowed Range: 0 -> 100 step: 1
Volume uint16 `xml:"Volume"`
Source string `xml:"Source"`
}
type SetAutoplayVolumeResponse struct {
}
func (s *Service) SetAutoplayVolume(httpClient *http.Client, args *SetAutoplayVolumeArgs) (*SetAutoplayVolumeResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`SetAutoplayVolume`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{SetAutoplayVolume: args},
})
if err != nil {
return nil, err
}
if r.Body.SetAutoplayVolume == nil {
return nil, errors.New(`unexpected respose from service calling deviceproperties.SetAutoplayVolume()`)
}
return r.Body.SetAutoplayVolume, nil
}
type GetAutoplayVolumeArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
Source string `xml:"Source"`
}
type GetAutoplayVolumeResponse struct {
CurrentVolume uint16 `xml:"CurrentVolume"`
}
func (s *Service) GetAutoplayVolume(httpClient *http.Client, args *GetAutoplayVolumeArgs) (*GetAutoplayVolumeResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`GetAutoplayVolume`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{GetAutoplayVolume: args},
})
if err != nil {
return nil, err
}
if r.Body.GetAutoplayVolume == nil {
return nil, errors.New(`unexpected respose from service calling deviceproperties.GetAutoplayVolume()`)
}
return r.Body.GetAutoplayVolume, nil
}
type SetUseAutoplayVolumeArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
UseVolume bool `xml:"UseVolume"`
Source string `xml:"Source"`
}
type SetUseAutoplayVolumeResponse struct {
}
func (s *Service) SetUseAutoplayVolume(httpClient *http.Client, args *SetUseAutoplayVolumeArgs) (*SetUseAutoplayVolumeResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`SetUseAutoplayVolume`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{SetUseAutoplayVolume: args},
})
if err != nil {
return nil, err
}
if r.Body.SetUseAutoplayVolume == nil {
return nil, errors.New(`unexpected respose from service calling deviceproperties.SetUseAutoplayVolume()`)
}
return r.Body.SetUseAutoplayVolume, nil
}
type GetUseAutoplayVolumeArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
Source string `xml:"Source"`
}
type GetUseAutoplayVolumeResponse struct {
UseVolume bool `xml:"UseVolume"`
}
func (s *Service) GetUseAutoplayVolume(httpClient *http.Client, args *GetUseAutoplayVolumeArgs) (*GetUseAutoplayVolumeResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`GetUseAutoplayVolume`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{GetUseAutoplayVolume: args},
})
if err != nil {
return nil, err
}
if r.Body.GetUseAutoplayVolume == nil {
return nil, errors.New(`unexpected respose from service calling deviceproperties.GetUseAutoplayVolume()`)
}
return r.Body.GetUseAutoplayVolume, nil
}
type AddHTSatelliteArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
HTSatChanMapSet string `xml:"HTSatChanMapSet"`
}
type AddHTSatelliteResponse struct {
}
func (s *Service) AddHTSatellite(httpClient *http.Client, args *AddHTSatelliteArgs) (*AddHTSatelliteResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`AddHTSatellite`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{AddHTSatellite: args},
})
if err != nil {
return nil, err
}
if r.Body.AddHTSatellite == nil {
return nil, errors.New(`unexpected respose from service calling deviceproperties.AddHTSatellite()`)
}
return r.Body.AddHTSatellite, nil
}
type RemoveHTSatelliteArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
SatRoomUUID string `xml:"SatRoomUUID"`
}
type RemoveHTSatelliteResponse struct {
}
func (s *Service) RemoveHTSatellite(httpClient *http.Client, args *RemoveHTSatelliteArgs) (*RemoveHTSatelliteResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`RemoveHTSatellite`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{RemoveHTSatellite: args},
})
if err != nil {
return nil, err
}
if r.Body.RemoveHTSatellite == nil {
return nil, errors.New(`unexpected respose from service calling deviceproperties.RemoveHTSatellite()`)
}
return r.Body.RemoveHTSatellite, nil
}
type EnterConfigModeArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
Mode string `xml:"Mode"`
Options string `xml:"Options"`
}
type EnterConfigModeResponse struct {
State string `xml:"State"`
}
func (s *Service) EnterConfigMode(httpClient *http.Client, args *EnterConfigModeArgs) (*EnterConfigModeResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`EnterConfigMode`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{EnterConfigMode: args},
})
if err != nil {
return nil, err
}
if r.Body.EnterConfigMode == nil {
return nil, errors.New(`unexpected respose from service calling deviceproperties.EnterConfigMode()`)
}
return r.Body.EnterConfigMode, nil
}
type ExitConfigModeArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
Options string `xml:"Options"`
}
type ExitConfigModeResponse struct {
}
func (s *Service) ExitConfigMode(httpClient *http.Client, args *ExitConfigModeArgs) (*ExitConfigModeResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`ExitConfigMode`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{ExitConfigMode: args},
})
if err != nil {
return nil, err
}
if r.Body.ExitConfigMode == nil {
return nil, errors.New(`unexpected respose from service calling deviceproperties.ExitConfigMode()`)
}
return r.Body.ExitConfigMode, nil
}
type GetButtonStateArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
}
type GetButtonStateResponse struct {
State string `xml:"State"`
}
func (s *Service) GetButtonState(httpClient *http.Client, args *GetButtonStateArgs) (*GetButtonStateResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`GetButtonState`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{GetButtonState: args},
})
if err != nil {
return nil, err
}
if r.Body.GetButtonState == nil {
return nil, errors.New(`unexpected respose from service calling deviceproperties.GetButtonState()`)
}
return r.Body.GetButtonState, nil
}
type SetButtonLockStateArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
// Allowed Value: On
// Allowed Value: Off
DesiredButtonLockState string `xml:"DesiredButtonLockState"`
}
type SetButtonLockStateResponse struct {
}
func (s *Service) SetButtonLockState(httpClient *http.Client, args *SetButtonLockStateArgs) (*SetButtonLockStateResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`SetButtonLockState`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{SetButtonLockState: args},
})
if err != nil {
return nil, err
}
if r.Body.SetButtonLockState == nil {
return nil, errors.New(`unexpected respose from service calling deviceproperties.SetButtonLockState()`)
}
return r.Body.SetButtonLockState, nil
}
type GetButtonLockStateArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
}
type GetButtonLockStateResponse struct {
CurrentButtonLockState string `xml:"CurrentButtonLockState"`
}
func (s *Service) GetButtonLockState(httpClient *http.Client, args *GetButtonLockStateArgs) (*GetButtonLockStateResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`GetButtonLockState`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{GetButtonLockState: args},
})
if err != nil {
return nil, err
}
if r.Body.GetButtonLockState == nil {
return nil, errors.New(`unexpected respose from service calling deviceproperties.GetButtonLockState()`)
}
return r.Body.GetButtonLockState, nil
}
-200
View File
@@ -1,200 +0,0 @@
package groupmanagement
import (
"bytes"
"encoding/xml"
"errors"
"io/ioutil"
"net/http"
"net/url"
)
const (
_ServiceURN = "urn:schemas-upnp-org:service:GroupManagement:1"
_EncodingSchema = "http://schemas.xmlsoap.org/soap/encoding/"
_EnvelopeSchema = "http://schemas.xmlsoap.org/soap/envelope/"
)
type Service struct {
ControlEndpoint *url.URL
EventEndpoint *url.URL
}
func NewService(deviceUrl *url.URL) *Service {
c, err := url.Parse(`/GroupManagement/Control`)
if nil != err {
panic(err)
}
e, err := url.Parse(`/GroupManagement/Event`)
if nil != err {
panic(err)
}
return &Service{
ControlEndpoint: deviceUrl.ResolveReference(c),
EventEndpoint: deviceUrl.ResolveReference(e),
}
}
type Envelope struct {
XMLName xml.Name `xml:"s:Envelope"`
Xmlns string `xml:"xmlns:s,attr"`
EncodingStyle string `xml:"s:encodingStyle,attr"`
Body Body `xml:"s:Body"`
}
type Body struct {
XMLName xml.Name `xml:"s:Body"`
AddMember *AddMemberArgs `xml:"u:AddMember,omitempty"`
RemoveMember *RemoveMemberArgs `xml:"u:RemoveMember,omitempty"`
ReportTrackBufferingResult *ReportTrackBufferingResultArgs `xml:"u:ReportTrackBufferingResult,omitempty"`
SetSourceAreaIds *SetSourceAreaIdsArgs `xml:"u:SetSourceAreaIds,omitempty"`
}
type EnvelopeResponse struct {
XMLName xml.Name `xml:"Envelope"`
Xmlns string `xml:"xmlns:s,attr"`
EncodingStyle string `xml:"encodingStyle,attr"`
Body BodyResponse `xml:"Body"`
}
type BodyResponse struct {
XMLName xml.Name `xml:"Body"`
AddMember *AddMemberResponse `xml:"AddMemberResponse,omitempty"`
RemoveMember *RemoveMemberResponse `xml:"RemoveMemberResponse,omitempty"`
ReportTrackBufferingResult *ReportTrackBufferingResultResponse `xml:"ReportTrackBufferingResultResponse,omitempty"`
SetSourceAreaIds *SetSourceAreaIdsResponse `xml:"SetSourceAreaIdsResponse,omitempty"`
}
func (s *Service) exec(actionName string, httpClient *http.Client, envelope *Envelope) (*EnvelopeResponse, error) {
marshaled, err := xml.Marshal(envelope)
if err != nil {
return nil, err
}
postBody := []byte(`<?xml version="1.0"?>`)
postBody = append(postBody, marshaled...)
req, err := http.NewRequest(`POST`, s.ControlEndpoint.String(), bytes.NewBuffer(postBody))
if err != nil {
return nil, err
}
req.Header.Set(`Content-Type`, `text/xml; charset="utf-8"`)
req.Header.Set(`SOAPAction`, _ServiceURN+`#`+actionName)
res, err := httpClient.Do(req)
if err != nil {
return nil, err
}
defer res.Body.Close()
responseBody, err := ioutil.ReadAll(res.Body)
if err != nil {
return nil, err
}
var envelopeResponse EnvelopeResponse
err = xml.Unmarshal(responseBody, &envelopeResponse)
if err != nil {
return nil, err
}
return &envelopeResponse, nil
}
type AddMemberArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
MemberID string `xml:"MemberID"`
BootSeq uint32 `xml:"BootSeq"`
}
type AddMemberResponse struct {
CurrentTransportSettings string `xml:"CurrentTransportSettings"`
CurrentURI string `xml:"CurrentURI"`
GroupUUIDJoined string `xml:"GroupUUIDJoined"`
ResetVolumeAfter bool `xml:"ResetVolumeAfter"`
VolumeAVTransportURI string `xml:"VolumeAVTransportURI"`
}
func (s *Service) AddMember(httpClient *http.Client, args *AddMemberArgs) (*AddMemberResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`AddMember`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{AddMember: args},
})
if err != nil {
return nil, err
}
if r.Body.AddMember == nil {
return nil, errors.New(`unexpected respose from service calling groupmanagement.AddMember()`)
}
return r.Body.AddMember, nil
}
type RemoveMemberArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
MemberID string `xml:"MemberID"`
}
type RemoveMemberResponse struct {
}
func (s *Service) RemoveMember(httpClient *http.Client, args *RemoveMemberArgs) (*RemoveMemberResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`RemoveMember`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{RemoveMember: args},
})
if err != nil {
return nil, err
}
if r.Body.RemoveMember == nil {
return nil, errors.New(`unexpected respose from service calling groupmanagement.RemoveMember()`)
}
return r.Body.RemoveMember, nil
}
type ReportTrackBufferingResultArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
MemberID string `xml:"MemberID"`
ResultCode int32 `xml:"ResultCode"`
}
type ReportTrackBufferingResultResponse struct {
}
func (s *Service) ReportTrackBufferingResult(httpClient *http.Client, args *ReportTrackBufferingResultArgs) (*ReportTrackBufferingResultResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`ReportTrackBufferingResult`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{ReportTrackBufferingResult: args},
})
if err != nil {
return nil, err
}
if r.Body.ReportTrackBufferingResult == nil {
return nil, errors.New(`unexpected respose from service calling groupmanagement.ReportTrackBufferingResult()`)
}
return r.Body.ReportTrackBufferingResult, nil
}
type SetSourceAreaIdsArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
DesiredSourceAreaIds string `xml:"DesiredSourceAreaIds"`
}
type SetSourceAreaIdsResponse struct {
}
func (s *Service) SetSourceAreaIds(httpClient *http.Client, args *SetSourceAreaIdsArgs) (*SetSourceAreaIdsResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`SetSourceAreaIds`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{SetSourceAreaIds: args},
})
if err != nil {
return nil, err
}
if r.Body.SetSourceAreaIds == nil {
return nil, errors.New(`unexpected respose from service calling groupmanagement.SetSourceAreaIds()`)
}
return r.Body.SetSourceAreaIds, nil
}
@@ -1,254 +0,0 @@
package grouprenderingcontrol
import (
"bytes"
"encoding/xml"
"errors"
"io/ioutil"
"net/http"
"net/url"
)
const (
_ServiceURN = "urn:schemas-upnp-org:service:GroupRenderingControl:1"
_EncodingSchema = "http://schemas.xmlsoap.org/soap/encoding/"
_EnvelopeSchema = "http://schemas.xmlsoap.org/soap/envelope/"
)
type Service struct {
ControlEndpoint *url.URL
EventEndpoint *url.URL
}
func NewService(deviceUrl *url.URL) *Service {
c, err := url.Parse(`/MediaRenderer/GroupRenderingControl/Control`)
if nil != err {
panic(err)
}
e, err := url.Parse(`/MediaRenderer/GroupRenderingControl/Event`)
if nil != err {
panic(err)
}
return &Service{
ControlEndpoint: deviceUrl.ResolveReference(c),
EventEndpoint: deviceUrl.ResolveReference(e),
}
}
type Envelope struct {
XMLName xml.Name `xml:"s:Envelope"`
Xmlns string `xml:"xmlns:s,attr"`
EncodingStyle string `xml:"s:encodingStyle,attr"`
Body Body `xml:"s:Body"`
}
type Body struct {
XMLName xml.Name `xml:"s:Body"`
GetGroupMute *GetGroupMuteArgs `xml:"u:GetGroupMute,omitempty"`
SetGroupMute *SetGroupMuteArgs `xml:"u:SetGroupMute,omitempty"`
GetGroupVolume *GetGroupVolumeArgs `xml:"u:GetGroupVolume,omitempty"`
SetGroupVolume *SetGroupVolumeArgs `xml:"u:SetGroupVolume,omitempty"`
SetRelativeGroupVolume *SetRelativeGroupVolumeArgs `xml:"u:SetRelativeGroupVolume,omitempty"`
SnapshotGroupVolume *SnapshotGroupVolumeArgs `xml:"u:SnapshotGroupVolume,omitempty"`
}
type EnvelopeResponse struct {
XMLName xml.Name `xml:"Envelope"`
Xmlns string `xml:"xmlns:s,attr"`
EncodingStyle string `xml:"encodingStyle,attr"`
Body BodyResponse `xml:"Body"`
}
type BodyResponse struct {
XMLName xml.Name `xml:"Body"`
GetGroupMute *GetGroupMuteResponse `xml:"GetGroupMuteResponse,omitempty"`
SetGroupMute *SetGroupMuteResponse `xml:"SetGroupMuteResponse,omitempty"`
GetGroupVolume *GetGroupVolumeResponse `xml:"GetGroupVolumeResponse,omitempty"`
SetGroupVolume *SetGroupVolumeResponse `xml:"SetGroupVolumeResponse,omitempty"`
SetRelativeGroupVolume *SetRelativeGroupVolumeResponse `xml:"SetRelativeGroupVolumeResponse,omitempty"`
SnapshotGroupVolume *SnapshotGroupVolumeResponse `xml:"SnapshotGroupVolumeResponse,omitempty"`
}
func (s *Service) exec(actionName string, httpClient *http.Client, envelope *Envelope) (*EnvelopeResponse, error) {
marshaled, err := xml.Marshal(envelope)
if err != nil {
return nil, err
}
postBody := []byte(`<?xml version="1.0"?>`)
postBody = append(postBody, marshaled...)
req, err := http.NewRequest(`POST`, s.ControlEndpoint.String(), bytes.NewBuffer(postBody))
if err != nil {
return nil, err
}
req.Header.Set(`Content-Type`, `text/xml; charset="utf-8"`)
req.Header.Set(`SOAPAction`, _ServiceURN+`#`+actionName)
res, err := httpClient.Do(req)
if err != nil {
return nil, err
}
defer res.Body.Close()
responseBody, err := ioutil.ReadAll(res.Body)
if err != nil {
return nil, err
}
var envelopeResponse EnvelopeResponse
err = xml.Unmarshal(responseBody, &envelopeResponse)
if err != nil {
return nil, err
}
return &envelopeResponse, nil
}
type GetGroupMuteArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
InstanceID uint32 `xml:"InstanceID"`
}
type GetGroupMuteResponse struct {
CurrentMute bool `xml:"CurrentMute"`
}
func (s *Service) GetGroupMute(httpClient *http.Client, args *GetGroupMuteArgs) (*GetGroupMuteResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`GetGroupMute`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{GetGroupMute: args},
})
if err != nil {
return nil, err
}
if r.Body.GetGroupMute == nil {
return nil, errors.New(`unexpected respose from service calling grouprenderingcontrol.GetGroupMute()`)
}
return r.Body.GetGroupMute, nil
}
type SetGroupMuteArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
InstanceID uint32 `xml:"InstanceID"`
DesiredMute bool `xml:"DesiredMute"`
}
type SetGroupMuteResponse struct {
}
func (s *Service) SetGroupMute(httpClient *http.Client, args *SetGroupMuteArgs) (*SetGroupMuteResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`SetGroupMute`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{SetGroupMute: args},
})
if err != nil {
return nil, err
}
if r.Body.SetGroupMute == nil {
return nil, errors.New(`unexpected respose from service calling grouprenderingcontrol.SetGroupMute()`)
}
return r.Body.SetGroupMute, nil
}
type GetGroupVolumeArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
InstanceID uint32 `xml:"InstanceID"`
}
type GetGroupVolumeResponse struct {
CurrentVolume uint16 `xml:"CurrentVolume"`
}
func (s *Service) GetGroupVolume(httpClient *http.Client, args *GetGroupVolumeArgs) (*GetGroupVolumeResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`GetGroupVolume`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{GetGroupVolume: args},
})
if err != nil {
return nil, err
}
if r.Body.GetGroupVolume == nil {
return nil, errors.New(`unexpected respose from service calling grouprenderingcontrol.GetGroupVolume()`)
}
return r.Body.GetGroupVolume, nil
}
type SetGroupVolumeArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
InstanceID uint32 `xml:"InstanceID"`
// Allowed Range: 0 -> 100 step: 1
DesiredVolume uint16 `xml:"DesiredVolume"`
}
type SetGroupVolumeResponse struct {
}
func (s *Service) SetGroupVolume(httpClient *http.Client, args *SetGroupVolumeArgs) (*SetGroupVolumeResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`SetGroupVolume`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{SetGroupVolume: args},
})
if err != nil {
return nil, err
}
if r.Body.SetGroupVolume == nil {
return nil, errors.New(`unexpected respose from service calling grouprenderingcontrol.SetGroupVolume()`)
}
return r.Body.SetGroupVolume, nil
}
type SetRelativeGroupVolumeArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
InstanceID uint32 `xml:"InstanceID"`
Adjustment int32 `xml:"Adjustment"`
}
type SetRelativeGroupVolumeResponse struct {
NewVolume uint16 `xml:"NewVolume"`
}
func (s *Service) SetRelativeGroupVolume(httpClient *http.Client, args *SetRelativeGroupVolumeArgs) (*SetRelativeGroupVolumeResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`SetRelativeGroupVolume`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{SetRelativeGroupVolume: args},
})
if err != nil {
return nil, err
}
if r.Body.SetRelativeGroupVolume == nil {
return nil, errors.New(`unexpected respose from service calling grouprenderingcontrol.SetRelativeGroupVolume()`)
}
return r.Body.SetRelativeGroupVolume, nil
}
type SnapshotGroupVolumeArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
InstanceID uint32 `xml:"InstanceID"`
}
type SnapshotGroupVolumeResponse struct {
}
func (s *Service) SnapshotGroupVolume(httpClient *http.Client, args *SnapshotGroupVolumeArgs) (*SnapshotGroupVolumeResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`SnapshotGroupVolume`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{SnapshotGroupVolume: args},
})
if err != nil {
return nil, err
}
if r.Body.SnapshotGroupVolume == nil {
return nil, errors.New(`unexpected respose from service calling grouprenderingcontrol.SnapshotGroupVolume()`)
}
return r.Body.SnapshotGroupVolume, nil
}
-21
View File
@@ -1,21 +0,0 @@
MIT License
Copyright (c) 2019 Matthew Szatmary
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
-169
View File
@@ -1,169 +0,0 @@
package musicservices
import (
"bytes"
"encoding/xml"
"errors"
"io/ioutil"
"net/http"
"net/url"
)
const (
_ServiceURN = "urn:schemas-upnp-org:service:MusicServices:1"
_EncodingSchema = "http://schemas.xmlsoap.org/soap/encoding/"
_EnvelopeSchema = "http://schemas.xmlsoap.org/soap/envelope/"
)
type Service struct {
ControlEndpoint *url.URL
EventEndpoint *url.URL
}
func NewService(deviceUrl *url.URL) *Service {
c, err := url.Parse(`/MusicServices/Control`)
if nil != err {
panic(err)
}
e, err := url.Parse(`/MusicServices/Event`)
if nil != err {
panic(err)
}
return &Service{
ControlEndpoint: deviceUrl.ResolveReference(c),
EventEndpoint: deviceUrl.ResolveReference(e),
}
}
type Envelope struct {
XMLName xml.Name `xml:"s:Envelope"`
Xmlns string `xml:"xmlns:s,attr"`
EncodingStyle string `xml:"s:encodingStyle,attr"`
Body Body `xml:"s:Body"`
}
type Body struct {
XMLName xml.Name `xml:"s:Body"`
GetSessionId *GetSessionIdArgs `xml:"u:GetSessionId,omitempty"`
ListAvailableServices *ListAvailableServicesArgs `xml:"u:ListAvailableServices,omitempty"`
UpdateAvailableServices *UpdateAvailableServicesArgs `xml:"u:UpdateAvailableServices,omitempty"`
}
type EnvelopeResponse struct {
XMLName xml.Name `xml:"Envelope"`
Xmlns string `xml:"xmlns:s,attr"`
EncodingStyle string `xml:"encodingStyle,attr"`
Body BodyResponse `xml:"Body"`
}
type BodyResponse struct {
XMLName xml.Name `xml:"Body"`
GetSessionId *GetSessionIdResponse `xml:"GetSessionIdResponse,omitempty"`
ListAvailableServices *ListAvailableServicesResponse `xml:"ListAvailableServicesResponse,omitempty"`
UpdateAvailableServices *UpdateAvailableServicesResponse `xml:"UpdateAvailableServicesResponse,omitempty"`
}
func (s *Service) exec(actionName string, httpClient *http.Client, envelope *Envelope) (*EnvelopeResponse, error) {
marshaled, err := xml.Marshal(envelope)
if err != nil {
return nil, err
}
postBody := []byte(`<?xml version="1.0"?>`)
postBody = append(postBody, marshaled...)
req, err := http.NewRequest(`POST`, s.ControlEndpoint.String(), bytes.NewBuffer(postBody))
if err != nil {
return nil, err
}
req.Header.Set(`Content-Type`, `text/xml; charset="utf-8"`)
req.Header.Set(`SOAPAction`, _ServiceURN+`#`+actionName)
res, err := httpClient.Do(req)
if err != nil {
return nil, err
}
defer res.Body.Close()
responseBody, err := ioutil.ReadAll(res.Body)
if err != nil {
return nil, err
}
var envelopeResponse EnvelopeResponse
err = xml.Unmarshal(responseBody, &envelopeResponse)
if err != nil {
return nil, err
}
return &envelopeResponse, nil
}
type GetSessionIdArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
ServiceId uint32 `xml:"ServiceId"`
Username string `xml:"Username"`
}
type GetSessionIdResponse struct {
SessionId string `xml:"SessionId"`
}
func (s *Service) GetSessionId(httpClient *http.Client, args *GetSessionIdArgs) (*GetSessionIdResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`GetSessionId`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{GetSessionId: args},
})
if err != nil {
return nil, err
}
if r.Body.GetSessionId == nil {
return nil, errors.New(`unexpected respose from service calling musicservices.GetSessionId()`)
}
return r.Body.GetSessionId, nil
}
type ListAvailableServicesArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
}
type ListAvailableServicesResponse struct {
AvailableServiceDescriptorList string `xml:"AvailableServiceDescriptorList"`
AvailableServiceTypeList string `xml:"AvailableServiceTypeList"`
AvailableServiceListVersion string `xml:"AvailableServiceListVersion"`
}
func (s *Service) ListAvailableServices(httpClient *http.Client, args *ListAvailableServicesArgs) (*ListAvailableServicesResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`ListAvailableServices`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{ListAvailableServices: args},
})
if err != nil {
return nil, err
}
if r.Body.ListAvailableServices == nil {
return nil, errors.New(`unexpected respose from service calling musicservices.ListAvailableServices()`)
}
return r.Body.ListAvailableServices, nil
}
type UpdateAvailableServicesArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
}
type UpdateAvailableServicesResponse struct {
}
func (s *Service) UpdateAvailableServices(httpClient *http.Client, args *UpdateAvailableServicesArgs) (*UpdateAvailableServicesResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`UpdateAvailableServices`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{UpdateAvailableServices: args},
})
if err != nil {
return nil, err
}
if r.Body.UpdateAvailableServices == nil {
return nil, errors.New(`unexpected respose from service calling musicservices.UpdateAvailableServices()`)
}
return r.Body.UpdateAvailableServices, nil
}
-115
View File
@@ -1,115 +0,0 @@
package qplay
import (
"bytes"
"encoding/xml"
"errors"
"io/ioutil"
"net/http"
"net/url"
)
const (
_ServiceURN = "urn:schemas-upnp-org:service:QPlay:1"
_EncodingSchema = "http://schemas.xmlsoap.org/soap/encoding/"
_EnvelopeSchema = "http://schemas.xmlsoap.org/soap/envelope/"
)
type Service struct {
ControlEndpoint *url.URL
EventEndpoint *url.URL
}
func NewService(deviceUrl *url.URL) *Service {
c, err := url.Parse(`/QPlay/Control`)
if nil != err {
panic(err)
}
e, err := url.Parse(`/QPlay/Event`)
if nil != err {
panic(err)
}
return &Service{
ControlEndpoint: deviceUrl.ResolveReference(c),
EventEndpoint: deviceUrl.ResolveReference(e),
}
}
type Envelope struct {
XMLName xml.Name `xml:"s:Envelope"`
Xmlns string `xml:"xmlns:s,attr"`
EncodingStyle string `xml:"s:encodingStyle,attr"`
Body Body `xml:"s:Body"`
}
type Body struct {
XMLName xml.Name `xml:"s:Body"`
QPlayAuth *QPlayAuthArgs `xml:"u:QPlayAuth,omitempty"`
}
type EnvelopeResponse struct {
XMLName xml.Name `xml:"Envelope"`
Xmlns string `xml:"xmlns:s,attr"`
EncodingStyle string `xml:"encodingStyle,attr"`
Body BodyResponse `xml:"Body"`
}
type BodyResponse struct {
XMLName xml.Name `xml:"Body"`
QPlayAuth *QPlayAuthResponse `xml:"QPlayAuthResponse,omitempty"`
}
func (s *Service) exec(actionName string, httpClient *http.Client, envelope *Envelope) (*EnvelopeResponse, error) {
marshaled, err := xml.Marshal(envelope)
if err != nil {
return nil, err
}
postBody := []byte(`<?xml version="1.0"?>`)
postBody = append(postBody, marshaled...)
req, err := http.NewRequest(`POST`, s.ControlEndpoint.String(), bytes.NewBuffer(postBody))
if err != nil {
return nil, err
}
req.Header.Set(`Content-Type`, `text/xml; charset="utf-8"`)
req.Header.Set(`SOAPAction`, _ServiceURN+`#`+actionName)
res, err := httpClient.Do(req)
if err != nil {
return nil, err
}
defer res.Body.Close()
responseBody, err := ioutil.ReadAll(res.Body)
if err != nil {
return nil, err
}
var envelopeResponse EnvelopeResponse
err = xml.Unmarshal(responseBody, &envelopeResponse)
if err != nil {
return nil, err
}
return &envelopeResponse, nil
}
type QPlayAuthArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
Seed string `xml:"Seed"`
}
type QPlayAuthResponse struct {
Code string `xml:"Code"`
MID string `xml:"MID"`
DID string `xml:"DID"`
}
func (s *Service) QPlayAuth(httpClient *http.Client, args *QPlayAuthArgs) (*QPlayAuthResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`QPlayAuth`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{QPlayAuth: args},
})
if err != nil {
return nil, err
}
if r.Body.QPlayAuth == nil {
return nil, errors.New(`unexpected respose from service calling qplay.QPlayAuth()`)
}
return r.Body.QPlayAuth, nil
}
-435
View File
@@ -1,435 +0,0 @@
package queue
import (
"bytes"
"encoding/xml"
"errors"
"io/ioutil"
"net/http"
"net/url"
)
const (
_ServiceURN = "urn:schemas-upnp-org:service:Queue:1"
_EncodingSchema = "http://schemas.xmlsoap.org/soap/encoding/"
_EnvelopeSchema = "http://schemas.xmlsoap.org/soap/envelope/"
)
type Service struct {
ControlEndpoint *url.URL
EventEndpoint *url.URL
}
func NewService(deviceUrl *url.URL) *Service {
c, err := url.Parse(`/MediaRenderer/Queue/Control`)
if nil != err {
panic(err)
}
e, err := url.Parse(`/MediaRenderer/Queue/Event`)
if nil != err {
panic(err)
}
return &Service{
ControlEndpoint: deviceUrl.ResolveReference(c),
EventEndpoint: deviceUrl.ResolveReference(e),
}
}
type Envelope struct {
XMLName xml.Name `xml:"s:Envelope"`
Xmlns string `xml:"xmlns:s,attr"`
EncodingStyle string `xml:"s:encodingStyle,attr"`
Body Body `xml:"s:Body"`
}
type Body struct {
XMLName xml.Name `xml:"s:Body"`
AddURI *AddURIArgs `xml:"u:AddURI,omitempty"`
AddMultipleURIs *AddMultipleURIsArgs `xml:"u:AddMultipleURIs,omitempty"`
AttachQueue *AttachQueueArgs `xml:"u:AttachQueue,omitempty"`
Backup *BackupArgs `xml:"u:Backup,omitempty"`
Browse *BrowseArgs `xml:"u:Browse,omitempty"`
CreateQueue *CreateQueueArgs `xml:"u:CreateQueue,omitempty"`
RemoveAllTracks *RemoveAllTracksArgs `xml:"u:RemoveAllTracks,omitempty"`
RemoveTrackRange *RemoveTrackRangeArgs `xml:"u:RemoveTrackRange,omitempty"`
ReorderTracks *ReorderTracksArgs `xml:"u:ReorderTracks,omitempty"`
ReplaceAllTracks *ReplaceAllTracksArgs `xml:"u:ReplaceAllTracks,omitempty"`
SaveAsSonosPlaylist *SaveAsSonosPlaylistArgs `xml:"u:SaveAsSonosPlaylist,omitempty"`
}
type EnvelopeResponse struct {
XMLName xml.Name `xml:"Envelope"`
Xmlns string `xml:"xmlns:s,attr"`
EncodingStyle string `xml:"encodingStyle,attr"`
Body BodyResponse `xml:"Body"`
}
type BodyResponse struct {
XMLName xml.Name `xml:"Body"`
AddURI *AddURIResponse `xml:"AddURIResponse,omitempty"`
AddMultipleURIs *AddMultipleURIsResponse `xml:"AddMultipleURIsResponse,omitempty"`
AttachQueue *AttachQueueResponse `xml:"AttachQueueResponse,omitempty"`
Backup *BackupResponse `xml:"BackupResponse,omitempty"`
Browse *BrowseResponse `xml:"BrowseResponse,omitempty"`
CreateQueue *CreateQueueResponse `xml:"CreateQueueResponse,omitempty"`
RemoveAllTracks *RemoveAllTracksResponse `xml:"RemoveAllTracksResponse,omitempty"`
RemoveTrackRange *RemoveTrackRangeResponse `xml:"RemoveTrackRangeResponse,omitempty"`
ReorderTracks *ReorderTracksResponse `xml:"ReorderTracksResponse,omitempty"`
ReplaceAllTracks *ReplaceAllTracksResponse `xml:"ReplaceAllTracksResponse,omitempty"`
SaveAsSonosPlaylist *SaveAsSonosPlaylistResponse `xml:"SaveAsSonosPlaylistResponse,omitempty"`
}
func (s *Service) exec(actionName string, httpClient *http.Client, envelope *Envelope) (*EnvelopeResponse, error) {
marshaled, err := xml.Marshal(envelope)
if err != nil {
return nil, err
}
postBody := []byte(`<?xml version="1.0"?>`)
postBody = append(postBody, marshaled...)
req, err := http.NewRequest(`POST`, s.ControlEndpoint.String(), bytes.NewBuffer(postBody))
if err != nil {
return nil, err
}
req.Header.Set(`Content-Type`, `text/xml; charset="utf-8"`)
req.Header.Set(`SOAPAction`, _ServiceURN+`#`+actionName)
res, err := httpClient.Do(req)
if err != nil {
return nil, err
}
defer res.Body.Close()
responseBody, err := ioutil.ReadAll(res.Body)
if err != nil {
return nil, err
}
var envelopeResponse EnvelopeResponse
err = xml.Unmarshal(responseBody, &envelopeResponse)
if err != nil {
return nil, err
}
return &envelopeResponse, nil
}
type AddURIArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
QueueID uint32 `xml:"QueueID"`
UpdateID uint32 `xml:"UpdateID"`
EnqueuedURI string `xml:"EnqueuedURI"`
EnqueuedURIMetaData string `xml:"EnqueuedURIMetaData"`
DesiredFirstTrackNumberEnqueued uint32 `xml:"DesiredFirstTrackNumberEnqueued"`
EnqueueAsNext bool `xml:"EnqueueAsNext"`
}
type AddURIResponse struct {
FirstTrackNumberEnqueued uint32 `xml:"FirstTrackNumberEnqueued"`
NumTracksAdded uint32 `xml:"NumTracksAdded"`
NewQueueLength uint32 `xml:"NewQueueLength"`
NewUpdateID uint32 `xml:"NewUpdateID"`
}
func (s *Service) AddURI(httpClient *http.Client, args *AddURIArgs) (*AddURIResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`AddURI`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{AddURI: args},
})
if err != nil {
return nil, err
}
if r.Body.AddURI == nil {
return nil, errors.New(`unexpected respose from service calling queue.AddURI()`)
}
return r.Body.AddURI, nil
}
type AddMultipleURIsArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
QueueID uint32 `xml:"QueueID"`
UpdateID uint32 `xml:"UpdateID"`
ContainerURI string `xml:"ContainerURI"`
ContainerMetaData string `xml:"ContainerMetaData"`
DesiredFirstTrackNumberEnqueued uint32 `xml:"DesiredFirstTrackNumberEnqueued"`
EnqueueAsNext bool `xml:"EnqueueAsNext"`
NumberOfURIs uint32 `xml:"NumberOfURIs"`
EnqueuedURIsAndMetaData string `xml:"EnqueuedURIsAndMetaData"`
}
type AddMultipleURIsResponse struct {
FirstTrackNumberEnqueued uint32 `xml:"FirstTrackNumberEnqueued"`
NumTracksAdded uint32 `xml:"NumTracksAdded"`
NewQueueLength uint32 `xml:"NewQueueLength"`
NewUpdateID uint32 `xml:"NewUpdateID"`
}
func (s *Service) AddMultipleURIs(httpClient *http.Client, args *AddMultipleURIsArgs) (*AddMultipleURIsResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`AddMultipleURIs`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{AddMultipleURIs: args},
})
if err != nil {
return nil, err
}
if r.Body.AddMultipleURIs == nil {
return nil, errors.New(`unexpected respose from service calling queue.AddMultipleURIs()`)
}
return r.Body.AddMultipleURIs, nil
}
type AttachQueueArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
QueueOwnerID string `xml:"QueueOwnerID"`
}
type AttachQueueResponse struct {
QueueID uint32 `xml:"QueueID"`
QueueOwnerContext string `xml:"QueueOwnerContext"`
}
func (s *Service) AttachQueue(httpClient *http.Client, args *AttachQueueArgs) (*AttachQueueResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`AttachQueue`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{AttachQueue: args},
})
if err != nil {
return nil, err
}
if r.Body.AttachQueue == nil {
return nil, errors.New(`unexpected respose from service calling queue.AttachQueue()`)
}
return r.Body.AttachQueue, nil
}
type BackupArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
}
type BackupResponse struct {
}
func (s *Service) Backup(httpClient *http.Client, args *BackupArgs) (*BackupResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`Backup`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{Backup: args},
})
if err != nil {
return nil, err
}
if r.Body.Backup == nil {
return nil, errors.New(`unexpected respose from service calling queue.Backup()`)
}
return r.Body.Backup, nil
}
type BrowseArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
QueueID uint32 `xml:"QueueID"`
StartingIndex uint32 `xml:"StartingIndex"`
RequestedCount uint32 `xml:"RequestedCount"`
}
type BrowseResponse struct {
Result string `xml:"Result"`
NumberReturned uint32 `xml:"NumberReturned"`
TotalMatches uint32 `xml:"TotalMatches"`
UpdateID uint32 `xml:"UpdateID"`
}
func (s *Service) Browse(httpClient *http.Client, args *BrowseArgs) (*BrowseResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`Browse`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{Browse: args},
})
if err != nil {
return nil, err
}
if r.Body.Browse == nil {
return nil, errors.New(`unexpected respose from service calling queue.Browse()`)
}
return r.Body.Browse, nil
}
type CreateQueueArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
QueueOwnerID string `xml:"QueueOwnerID"`
QueueOwnerContext string `xml:"QueueOwnerContext"`
QueuePolicy string `xml:"QueuePolicy"`
}
type CreateQueueResponse struct {
QueueID uint32 `xml:"QueueID"`
}
func (s *Service) CreateQueue(httpClient *http.Client, args *CreateQueueArgs) (*CreateQueueResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`CreateQueue`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{CreateQueue: args},
})
if err != nil {
return nil, err
}
if r.Body.CreateQueue == nil {
return nil, errors.New(`unexpected respose from service calling queue.CreateQueue()`)
}
return r.Body.CreateQueue, nil
}
type RemoveAllTracksArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
QueueID uint32 `xml:"QueueID"`
UpdateID uint32 `xml:"UpdateID"`
}
type RemoveAllTracksResponse struct {
NewUpdateID uint32 `xml:"NewUpdateID"`
}
func (s *Service) RemoveAllTracks(httpClient *http.Client, args *RemoveAllTracksArgs) (*RemoveAllTracksResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`RemoveAllTracks`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{RemoveAllTracks: args},
})
if err != nil {
return nil, err
}
if r.Body.RemoveAllTracks == nil {
return nil, errors.New(`unexpected respose from service calling queue.RemoveAllTracks()`)
}
return r.Body.RemoveAllTracks, nil
}
type RemoveTrackRangeArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
QueueID uint32 `xml:"QueueID"`
UpdateID uint32 `xml:"UpdateID"`
StartingIndex uint32 `xml:"StartingIndex"`
NumberOfTracks uint32 `xml:"NumberOfTracks"`
}
type RemoveTrackRangeResponse struct {
NewUpdateID uint32 `xml:"NewUpdateID"`
}
func (s *Service) RemoveTrackRange(httpClient *http.Client, args *RemoveTrackRangeArgs) (*RemoveTrackRangeResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`RemoveTrackRange`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{RemoveTrackRange: args},
})
if err != nil {
return nil, err
}
if r.Body.RemoveTrackRange == nil {
return nil, errors.New(`unexpected respose from service calling queue.RemoveTrackRange()`)
}
return r.Body.RemoveTrackRange, nil
}
type ReorderTracksArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
QueueID uint32 `xml:"QueueID"`
StartingIndex uint32 `xml:"StartingIndex"`
NumberOfTracks uint32 `xml:"NumberOfTracks"`
InsertBefore uint32 `xml:"InsertBefore"`
UpdateID uint32 `xml:"UpdateID"`
}
type ReorderTracksResponse struct {
NewUpdateID uint32 `xml:"NewUpdateID"`
}
func (s *Service) ReorderTracks(httpClient *http.Client, args *ReorderTracksArgs) (*ReorderTracksResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`ReorderTracks`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{ReorderTracks: args},
})
if err != nil {
return nil, err
}
if r.Body.ReorderTracks == nil {
return nil, errors.New(`unexpected respose from service calling queue.ReorderTracks()`)
}
return r.Body.ReorderTracks, nil
}
type ReplaceAllTracksArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
QueueID uint32 `xml:"QueueID"`
UpdateID uint32 `xml:"UpdateID"`
ContainerURI string `xml:"ContainerURI"`
ContainerMetaData string `xml:"ContainerMetaData"`
CurrentTrackIndex uint32 `xml:"CurrentTrackIndex"`
NewCurrentTrackIndices string `xml:"NewCurrentTrackIndices"`
NumberOfURIs uint32 `xml:"NumberOfURIs"`
EnqueuedURIsAndMetaData string `xml:"EnqueuedURIsAndMetaData"`
}
type ReplaceAllTracksResponse struct {
NewQueueLength uint32 `xml:"NewQueueLength"`
NewUpdateID uint32 `xml:"NewUpdateID"`
}
func (s *Service) ReplaceAllTracks(httpClient *http.Client, args *ReplaceAllTracksArgs) (*ReplaceAllTracksResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`ReplaceAllTracks`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{ReplaceAllTracks: args},
})
if err != nil {
return nil, err
}
if r.Body.ReplaceAllTracks == nil {
return nil, errors.New(`unexpected respose from service calling queue.ReplaceAllTracks()`)
}
return r.Body.ReplaceAllTracks, nil
}
type SaveAsSonosPlaylistArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
QueueID uint32 `xml:"QueueID"`
Title string `xml:"Title"`
ObjectID string `xml:"ObjectID"`
}
type SaveAsSonosPlaylistResponse struct {
AssignedObjectID string `xml:"AssignedObjectID"`
}
func (s *Service) SaveAsSonosPlaylist(httpClient *http.Client, args *SaveAsSonosPlaylistArgs) (*SaveAsSonosPlaylistResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`SaveAsSonosPlaylist`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{SaveAsSonosPlaylist: args},
})
if err != nil {
return nil, err
}
if r.Body.SaveAsSonosPlaylist == nil {
return nil, errors.New(`unexpected respose from service calling queue.SaveAsSonosPlaylist()`)
}
return r.Body.SaveAsSonosPlaylist, nil
}
View File
-940
View File
@@ -1,940 +0,0 @@
package renderingcontrol
import (
"bytes"
"encoding/xml"
"errors"
"io/ioutil"
"net/http"
"net/url"
)
const (
_ServiceURN = "urn:schemas-upnp-org:service:RenderingControl:1"
_EncodingSchema = "http://schemas.xmlsoap.org/soap/encoding/"
_EnvelopeSchema = "http://schemas.xmlsoap.org/soap/envelope/"
)
type Service struct {
ControlEndpoint *url.URL
EventEndpoint *url.URL
}
func NewService(deviceUrl *url.URL) *Service {
c, err := url.Parse(`/MediaRenderer/RenderingControl/Control`)
if nil != err {
panic(err)
}
e, err := url.Parse(`/MediaRenderer/RenderingControl/Event`)
if nil != err {
panic(err)
}
return &Service{
ControlEndpoint: deviceUrl.ResolveReference(c),
EventEndpoint: deviceUrl.ResolveReference(e),
}
}
type Envelope struct {
XMLName xml.Name `xml:"s:Envelope"`
Xmlns string `xml:"xmlns:s,attr"`
EncodingStyle string `xml:"s:encodingStyle,attr"`
Body Body `xml:"s:Body"`
}
type Body struct {
XMLName xml.Name `xml:"s:Body"`
GetMute *GetMuteArgs `xml:"u:GetMute,omitempty"`
SetMute *SetMuteArgs `xml:"u:SetMute,omitempty"`
ResetBasicEQ *ResetBasicEQArgs `xml:"u:ResetBasicEQ,omitempty"`
ResetExtEQ *ResetExtEQArgs `xml:"u:ResetExtEQ,omitempty"`
GetVolume *GetVolumeArgs `xml:"u:GetVolume,omitempty"`
SetVolume *SetVolumeArgs `xml:"u:SetVolume,omitempty"`
SetRelativeVolume *SetRelativeVolumeArgs `xml:"u:SetRelativeVolume,omitempty"`
GetVolumeDB *GetVolumeDBArgs `xml:"u:GetVolumeDB,omitempty"`
SetVolumeDB *SetVolumeDBArgs `xml:"u:SetVolumeDB,omitempty"`
GetVolumeDBRange *GetVolumeDBRangeArgs `xml:"u:GetVolumeDBRange,omitempty"`
GetBass *GetBassArgs `xml:"u:GetBass,omitempty"`
SetBass *SetBassArgs `xml:"u:SetBass,omitempty"`
GetTreble *GetTrebleArgs `xml:"u:GetTreble,omitempty"`
SetTreble *SetTrebleArgs `xml:"u:SetTreble,omitempty"`
GetEQ *GetEQArgs `xml:"u:GetEQ,omitempty"`
SetEQ *SetEQArgs `xml:"u:SetEQ,omitempty"`
GetLoudness *GetLoudnessArgs `xml:"u:GetLoudness,omitempty"`
SetLoudness *SetLoudnessArgs `xml:"u:SetLoudness,omitempty"`
GetSupportsOutputFixed *GetSupportsOutputFixedArgs `xml:"u:GetSupportsOutputFixed,omitempty"`
GetOutputFixed *GetOutputFixedArgs `xml:"u:GetOutputFixed,omitempty"`
SetOutputFixed *SetOutputFixedArgs `xml:"u:SetOutputFixed,omitempty"`
GetHeadphoneConnected *GetHeadphoneConnectedArgs `xml:"u:GetHeadphoneConnected,omitempty"`
RampToVolume *RampToVolumeArgs `xml:"u:RampToVolume,omitempty"`
RestoreVolumePriorToRamp *RestoreVolumePriorToRampArgs `xml:"u:RestoreVolumePriorToRamp,omitempty"`
SetChannelMap *SetChannelMapArgs `xml:"u:SetChannelMap,omitempty"`
SetRoomCalibrationX *SetRoomCalibrationXArgs `xml:"u:SetRoomCalibrationX,omitempty"`
GetRoomCalibrationStatus *GetRoomCalibrationStatusArgs `xml:"u:GetRoomCalibrationStatus,omitempty"`
SetRoomCalibrationStatus *SetRoomCalibrationStatusArgs `xml:"u:SetRoomCalibrationStatus,omitempty"`
}
type EnvelopeResponse struct {
XMLName xml.Name `xml:"Envelope"`
Xmlns string `xml:"xmlns:s,attr"`
EncodingStyle string `xml:"encodingStyle,attr"`
Body BodyResponse `xml:"Body"`
}
type BodyResponse struct {
XMLName xml.Name `xml:"Body"`
GetMute *GetMuteResponse `xml:"GetMuteResponse,omitempty"`
SetMute *SetMuteResponse `xml:"SetMuteResponse,omitempty"`
ResetBasicEQ *ResetBasicEQResponse `xml:"ResetBasicEQResponse,omitempty"`
ResetExtEQ *ResetExtEQResponse `xml:"ResetExtEQResponse,omitempty"`
GetVolume *GetVolumeResponse `xml:"GetVolumeResponse,omitempty"`
SetVolume *SetVolumeResponse `xml:"SetVolumeResponse,omitempty"`
SetRelativeVolume *SetRelativeVolumeResponse `xml:"SetRelativeVolumeResponse,omitempty"`
GetVolumeDB *GetVolumeDBResponse `xml:"GetVolumeDBResponse,omitempty"`
SetVolumeDB *SetVolumeDBResponse `xml:"SetVolumeDBResponse,omitempty"`
GetVolumeDBRange *GetVolumeDBRangeResponse `xml:"GetVolumeDBRangeResponse,omitempty"`
GetBass *GetBassResponse `xml:"GetBassResponse,omitempty"`
SetBass *SetBassResponse `xml:"SetBassResponse,omitempty"`
GetTreble *GetTrebleResponse `xml:"GetTrebleResponse,omitempty"`
SetTreble *SetTrebleResponse `xml:"SetTrebleResponse,omitempty"`
GetEQ *GetEQResponse `xml:"GetEQResponse,omitempty"`
SetEQ *SetEQResponse `xml:"SetEQResponse,omitempty"`
GetLoudness *GetLoudnessResponse `xml:"GetLoudnessResponse,omitempty"`
SetLoudness *SetLoudnessResponse `xml:"SetLoudnessResponse,omitempty"`
GetSupportsOutputFixed *GetSupportsOutputFixedResponse `xml:"GetSupportsOutputFixedResponse,omitempty"`
GetOutputFixed *GetOutputFixedResponse `xml:"GetOutputFixedResponse,omitempty"`
SetOutputFixed *SetOutputFixedResponse `xml:"SetOutputFixedResponse,omitempty"`
GetHeadphoneConnected *GetHeadphoneConnectedResponse `xml:"GetHeadphoneConnectedResponse,omitempty"`
RampToVolume *RampToVolumeResponse `xml:"RampToVolumeResponse,omitempty"`
RestoreVolumePriorToRamp *RestoreVolumePriorToRampResponse `xml:"RestoreVolumePriorToRampResponse,omitempty"`
SetChannelMap *SetChannelMapResponse `xml:"SetChannelMapResponse,omitempty"`
SetRoomCalibrationX *SetRoomCalibrationXResponse `xml:"SetRoomCalibrationXResponse,omitempty"`
GetRoomCalibrationStatus *GetRoomCalibrationStatusResponse `xml:"GetRoomCalibrationStatusResponse,omitempty"`
SetRoomCalibrationStatus *SetRoomCalibrationStatusResponse `xml:"SetRoomCalibrationStatusResponse,omitempty"`
}
func (s *Service) exec(actionName string, httpClient *http.Client, envelope *Envelope) (*EnvelopeResponse, error) {
marshaled, err := xml.Marshal(envelope)
if err != nil {
return nil, err
}
postBody := []byte(`<?xml version="1.0"?>`)
postBody = append(postBody, marshaled...)
req, err := http.NewRequest(`POST`, s.ControlEndpoint.String(), bytes.NewBuffer(postBody))
if err != nil {
return nil, err
}
req.Header.Set(`Content-Type`, `text/xml; charset="utf-8"`)
req.Header.Set(`SOAPAction`, _ServiceURN+`#`+actionName)
res, err := httpClient.Do(req)
if err != nil {
return nil, err
}
defer res.Body.Close()
responseBody, err := ioutil.ReadAll(res.Body)
if err != nil {
return nil, err
}
var envelopeResponse EnvelopeResponse
err = xml.Unmarshal(responseBody, &envelopeResponse)
if err != nil {
return nil, err
}
return &envelopeResponse, nil
}
type GetMuteArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
InstanceID uint32 `xml:"InstanceID"`
// Allowed Value: Master
// Allowed Value: LF
// Allowed Value: RF
// Allowed Value: SpeakerOnly
Channel string `xml:"Channel"`
}
type GetMuteResponse struct {
CurrentMute bool `xml:"CurrentMute"`
}
func (s *Service) GetMute(httpClient *http.Client, args *GetMuteArgs) (*GetMuteResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`GetMute`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{GetMute: args},
})
if err != nil {
return nil, err
}
if r.Body.GetMute == nil {
return nil, errors.New(`unexpected respose from service calling renderingcontrol.GetMute()`)
}
return r.Body.GetMute, nil
}
type SetMuteArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
InstanceID uint32 `xml:"InstanceID"`
// Allowed Value: Master
// Allowed Value: LF
// Allowed Value: RF
// Allowed Value: SpeakerOnly
Channel string `xml:"Channel"`
DesiredMute bool `xml:"DesiredMute"`
}
type SetMuteResponse struct {
}
func (s *Service) SetMute(httpClient *http.Client, args *SetMuteArgs) (*SetMuteResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`SetMute`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{SetMute: args},
})
if err != nil {
return nil, err
}
if r.Body.SetMute == nil {
return nil, errors.New(`unexpected respose from service calling renderingcontrol.SetMute()`)
}
return r.Body.SetMute, nil
}
type ResetBasicEQArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
InstanceID uint32 `xml:"InstanceID"`
}
type ResetBasicEQResponse struct {
Bass int16 `xml:"Bass"`
Treble int16 `xml:"Treble"`
Loudness bool `xml:"Loudness"`
LeftVolume uint16 `xml:"LeftVolume"`
RightVolume uint16 `xml:"RightVolume"`
}
func (s *Service) ResetBasicEQ(httpClient *http.Client, args *ResetBasicEQArgs) (*ResetBasicEQResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`ResetBasicEQ`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{ResetBasicEQ: args},
})
if err != nil {
return nil, err
}
if r.Body.ResetBasicEQ == nil {
return nil, errors.New(`unexpected respose from service calling renderingcontrol.ResetBasicEQ()`)
}
return r.Body.ResetBasicEQ, nil
}
type ResetExtEQArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
InstanceID uint32 `xml:"InstanceID"`
EQType string `xml:"EQType"`
}
type ResetExtEQResponse struct {
}
func (s *Service) ResetExtEQ(httpClient *http.Client, args *ResetExtEQArgs) (*ResetExtEQResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`ResetExtEQ`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{ResetExtEQ: args},
})
if err != nil {
return nil, err
}
if r.Body.ResetExtEQ == nil {
return nil, errors.New(`unexpected respose from service calling renderingcontrol.ResetExtEQ()`)
}
return r.Body.ResetExtEQ, nil
}
type GetVolumeArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
InstanceID uint32 `xml:"InstanceID"`
// Allowed Value: Master
// Allowed Value: LF
// Allowed Value: RF
Channel string `xml:"Channel"`
}
type GetVolumeResponse struct {
CurrentVolume uint16 `xml:"CurrentVolume"`
}
func (s *Service) GetVolume(httpClient *http.Client, args *GetVolumeArgs) (*GetVolumeResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`GetVolume`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{GetVolume: args},
})
if err != nil {
return nil, err
}
if r.Body.GetVolume == nil {
return nil, errors.New(`unexpected respose from service calling renderingcontrol.GetVolume()`)
}
return r.Body.GetVolume, nil
}
type SetVolumeArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
InstanceID uint32 `xml:"InstanceID"`
// Allowed Value: Master
// Allowed Value: LF
// Allowed Value: RF
Channel string `xml:"Channel"`
// Allowed Range: 0 -> 100 step: 1
DesiredVolume uint16 `xml:"DesiredVolume"`
}
type SetVolumeResponse struct {
}
func (s *Service) SetVolume(httpClient *http.Client, args *SetVolumeArgs) (*SetVolumeResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`SetVolume`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{SetVolume: args},
})
if err != nil {
return nil, err
}
if r.Body.SetVolume == nil {
return nil, errors.New(`unexpected respose from service calling renderingcontrol.SetVolume()`)
}
return r.Body.SetVolume, nil
}
type SetRelativeVolumeArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
InstanceID uint32 `xml:"InstanceID"`
// Allowed Value: Master
// Allowed Value: LF
// Allowed Value: RF
Channel string `xml:"Channel"`
Adjustment int32 `xml:"Adjustment"`
}
type SetRelativeVolumeResponse struct {
NewVolume uint16 `xml:"NewVolume"`
}
func (s *Service) SetRelativeVolume(httpClient *http.Client, args *SetRelativeVolumeArgs) (*SetRelativeVolumeResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`SetRelativeVolume`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{SetRelativeVolume: args},
})
if err != nil {
return nil, err
}
if r.Body.SetRelativeVolume == nil {
return nil, errors.New(`unexpected respose from service calling renderingcontrol.SetRelativeVolume()`)
}
return r.Body.SetRelativeVolume, nil
}
type GetVolumeDBArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
InstanceID uint32 `xml:"InstanceID"`
// Allowed Value: Master
// Allowed Value: LF
// Allowed Value: RF
Channel string `xml:"Channel"`
}
type GetVolumeDBResponse struct {
CurrentVolume int16 `xml:"CurrentVolume"`
}
func (s *Service) GetVolumeDB(httpClient *http.Client, args *GetVolumeDBArgs) (*GetVolumeDBResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`GetVolumeDB`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{GetVolumeDB: args},
})
if err != nil {
return nil, err
}
if r.Body.GetVolumeDB == nil {
return nil, errors.New(`unexpected respose from service calling renderingcontrol.GetVolumeDB()`)
}
return r.Body.GetVolumeDB, nil
}
type SetVolumeDBArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
InstanceID uint32 `xml:"InstanceID"`
// Allowed Value: Master
// Allowed Value: LF
// Allowed Value: RF
Channel string `xml:"Channel"`
DesiredVolume int16 `xml:"DesiredVolume"`
}
type SetVolumeDBResponse struct {
}
func (s *Service) SetVolumeDB(httpClient *http.Client, args *SetVolumeDBArgs) (*SetVolumeDBResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`SetVolumeDB`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{SetVolumeDB: args},
})
if err != nil {
return nil, err
}
if r.Body.SetVolumeDB == nil {
return nil, errors.New(`unexpected respose from service calling renderingcontrol.SetVolumeDB()`)
}
return r.Body.SetVolumeDB, nil
}
type GetVolumeDBRangeArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
InstanceID uint32 `xml:"InstanceID"`
// Allowed Value: Master
// Allowed Value: LF
// Allowed Value: RF
Channel string `xml:"Channel"`
}
type GetVolumeDBRangeResponse struct {
MinValue int16 `xml:"MinValue"`
MaxValue int16 `xml:"MaxValue"`
}
func (s *Service) GetVolumeDBRange(httpClient *http.Client, args *GetVolumeDBRangeArgs) (*GetVolumeDBRangeResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`GetVolumeDBRange`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{GetVolumeDBRange: args},
})
if err != nil {
return nil, err
}
if r.Body.GetVolumeDBRange == nil {
return nil, errors.New(`unexpected respose from service calling renderingcontrol.GetVolumeDBRange()`)
}
return r.Body.GetVolumeDBRange, nil
}
type GetBassArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
InstanceID uint32 `xml:"InstanceID"`
}
type GetBassResponse struct {
CurrentBass int16 `xml:"CurrentBass"`
}
func (s *Service) GetBass(httpClient *http.Client, args *GetBassArgs) (*GetBassResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`GetBass`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{GetBass: args},
})
if err != nil {
return nil, err
}
if r.Body.GetBass == nil {
return nil, errors.New(`unexpected respose from service calling renderingcontrol.GetBass()`)
}
return r.Body.GetBass, nil
}
type SetBassArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
InstanceID uint32 `xml:"InstanceID"`
// Allowed Range: -10 -> 10 step: 1
DesiredBass int16 `xml:"DesiredBass"`
}
type SetBassResponse struct {
}
func (s *Service) SetBass(httpClient *http.Client, args *SetBassArgs) (*SetBassResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`SetBass`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{SetBass: args},
})
if err != nil {
return nil, err
}
if r.Body.SetBass == nil {
return nil, errors.New(`unexpected respose from service calling renderingcontrol.SetBass()`)
}
return r.Body.SetBass, nil
}
type GetTrebleArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
InstanceID uint32 `xml:"InstanceID"`
}
type GetTrebleResponse struct {
CurrentTreble int16 `xml:"CurrentTreble"`
}
func (s *Service) GetTreble(httpClient *http.Client, args *GetTrebleArgs) (*GetTrebleResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`GetTreble`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{GetTreble: args},
})
if err != nil {
return nil, err
}
if r.Body.GetTreble == nil {
return nil, errors.New(`unexpected respose from service calling renderingcontrol.GetTreble()`)
}
return r.Body.GetTreble, nil
}
type SetTrebleArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
InstanceID uint32 `xml:"InstanceID"`
// Allowed Range: -10 -> 10 step: 1
DesiredTreble int16 `xml:"DesiredTreble"`
}
type SetTrebleResponse struct {
}
func (s *Service) SetTreble(httpClient *http.Client, args *SetTrebleArgs) (*SetTrebleResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`SetTreble`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{SetTreble: args},
})
if err != nil {
return nil, err
}
if r.Body.SetTreble == nil {
return nil, errors.New(`unexpected respose from service calling renderingcontrol.SetTreble()`)
}
return r.Body.SetTreble, nil
}
type GetEQArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
InstanceID uint32 `xml:"InstanceID"`
EQType string `xml:"EQType"`
}
type GetEQResponse struct {
CurrentValue int16 `xml:"CurrentValue"`
}
func (s *Service) GetEQ(httpClient *http.Client, args *GetEQArgs) (*GetEQResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`GetEQ`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{GetEQ: args},
})
if err != nil {
return nil, err
}
if r.Body.GetEQ == nil {
return nil, errors.New(`unexpected respose from service calling renderingcontrol.GetEQ()`)
}
return r.Body.GetEQ, nil
}
type SetEQArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
InstanceID uint32 `xml:"InstanceID"`
EQType string `xml:"EQType"`
DesiredValue int16 `xml:"DesiredValue"`
}
type SetEQResponse struct {
}
func (s *Service) SetEQ(httpClient *http.Client, args *SetEQArgs) (*SetEQResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`SetEQ`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{SetEQ: args},
})
if err != nil {
return nil, err
}
if r.Body.SetEQ == nil {
return nil, errors.New(`unexpected respose from service calling renderingcontrol.SetEQ()`)
}
return r.Body.SetEQ, nil
}
type GetLoudnessArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
InstanceID uint32 `xml:"InstanceID"`
// Allowed Value: Master
// Allowed Value: LF
// Allowed Value: RF
Channel string `xml:"Channel"`
}
type GetLoudnessResponse struct {
CurrentLoudness bool `xml:"CurrentLoudness"`
}
func (s *Service) GetLoudness(httpClient *http.Client, args *GetLoudnessArgs) (*GetLoudnessResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`GetLoudness`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{GetLoudness: args},
})
if err != nil {
return nil, err
}
if r.Body.GetLoudness == nil {
return nil, errors.New(`unexpected respose from service calling renderingcontrol.GetLoudness()`)
}
return r.Body.GetLoudness, nil
}
type SetLoudnessArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
InstanceID uint32 `xml:"InstanceID"`
// Allowed Value: Master
// Allowed Value: LF
// Allowed Value: RF
Channel string `xml:"Channel"`
DesiredLoudness bool `xml:"DesiredLoudness"`
}
type SetLoudnessResponse struct {
}
func (s *Service) SetLoudness(httpClient *http.Client, args *SetLoudnessArgs) (*SetLoudnessResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`SetLoudness`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{SetLoudness: args},
})
if err != nil {
return nil, err
}
if r.Body.SetLoudness == nil {
return nil, errors.New(`unexpected respose from service calling renderingcontrol.SetLoudness()`)
}
return r.Body.SetLoudness, nil
}
type GetSupportsOutputFixedArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
InstanceID uint32 `xml:"InstanceID"`
}
type GetSupportsOutputFixedResponse struct {
CurrentSupportsFixed bool `xml:"CurrentSupportsFixed"`
}
func (s *Service) GetSupportsOutputFixed(httpClient *http.Client, args *GetSupportsOutputFixedArgs) (*GetSupportsOutputFixedResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`GetSupportsOutputFixed`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{GetSupportsOutputFixed: args},
})
if err != nil {
return nil, err
}
if r.Body.GetSupportsOutputFixed == nil {
return nil, errors.New(`unexpected respose from service calling renderingcontrol.GetSupportsOutputFixed()`)
}
return r.Body.GetSupportsOutputFixed, nil
}
type GetOutputFixedArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
InstanceID uint32 `xml:"InstanceID"`
}
type GetOutputFixedResponse struct {
CurrentFixed bool `xml:"CurrentFixed"`
}
func (s *Service) GetOutputFixed(httpClient *http.Client, args *GetOutputFixedArgs) (*GetOutputFixedResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`GetOutputFixed`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{GetOutputFixed: args},
})
if err != nil {
return nil, err
}
if r.Body.GetOutputFixed == nil {
return nil, errors.New(`unexpected respose from service calling renderingcontrol.GetOutputFixed()`)
}
return r.Body.GetOutputFixed, nil
}
type SetOutputFixedArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
InstanceID uint32 `xml:"InstanceID"`
DesiredFixed bool `xml:"DesiredFixed"`
}
type SetOutputFixedResponse struct {
}
func (s *Service) SetOutputFixed(httpClient *http.Client, args *SetOutputFixedArgs) (*SetOutputFixedResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`SetOutputFixed`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{SetOutputFixed: args},
})
if err != nil {
return nil, err
}
if r.Body.SetOutputFixed == nil {
return nil, errors.New(`unexpected respose from service calling renderingcontrol.SetOutputFixed()`)
}
return r.Body.SetOutputFixed, nil
}
type GetHeadphoneConnectedArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
InstanceID uint32 `xml:"InstanceID"`
}
type GetHeadphoneConnectedResponse struct {
CurrentHeadphoneConnected bool `xml:"CurrentHeadphoneConnected"`
}
func (s *Service) GetHeadphoneConnected(httpClient *http.Client, args *GetHeadphoneConnectedArgs) (*GetHeadphoneConnectedResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`GetHeadphoneConnected`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{GetHeadphoneConnected: args},
})
if err != nil {
return nil, err
}
if r.Body.GetHeadphoneConnected == nil {
return nil, errors.New(`unexpected respose from service calling renderingcontrol.GetHeadphoneConnected()`)
}
return r.Body.GetHeadphoneConnected, nil
}
type RampToVolumeArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
InstanceID uint32 `xml:"InstanceID"`
// Allowed Value: Master
// Allowed Value: LF
// Allowed Value: RF
Channel string `xml:"Channel"`
// Allowed Value: SLEEP_TIMER_RAMP_TYPE
// Allowed Value: ALARM_RAMP_TYPE
// Allowed Value: AUTOPLAY_RAMP_TYPE
RampType string `xml:"RampType"`
// Allowed Range: 0 -> 100 step: 1
DesiredVolume uint16 `xml:"DesiredVolume"`
ResetVolumeAfter bool `xml:"ResetVolumeAfter"`
ProgramURI string `xml:"ProgramURI"`
}
type RampToVolumeResponse struct {
RampTime uint32 `xml:"RampTime"`
}
func (s *Service) RampToVolume(httpClient *http.Client, args *RampToVolumeArgs) (*RampToVolumeResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`RampToVolume`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{RampToVolume: args},
})
if err != nil {
return nil, err
}
if r.Body.RampToVolume == nil {
return nil, errors.New(`unexpected respose from service calling renderingcontrol.RampToVolume()`)
}
return r.Body.RampToVolume, nil
}
type RestoreVolumePriorToRampArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
InstanceID uint32 `xml:"InstanceID"`
// Allowed Value: Master
// Allowed Value: LF
// Allowed Value: RF
Channel string `xml:"Channel"`
}
type RestoreVolumePriorToRampResponse struct {
}
func (s *Service) RestoreVolumePriorToRamp(httpClient *http.Client, args *RestoreVolumePriorToRampArgs) (*RestoreVolumePriorToRampResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`RestoreVolumePriorToRamp`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{RestoreVolumePriorToRamp: args},
})
if err != nil {
return nil, err
}
if r.Body.RestoreVolumePriorToRamp == nil {
return nil, errors.New(`unexpected respose from service calling renderingcontrol.RestoreVolumePriorToRamp()`)
}
return r.Body.RestoreVolumePriorToRamp, nil
}
type SetChannelMapArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
InstanceID uint32 `xml:"InstanceID"`
ChannelMap string `xml:"ChannelMap"`
}
type SetChannelMapResponse struct {
}
func (s *Service) SetChannelMap(httpClient *http.Client, args *SetChannelMapArgs) (*SetChannelMapResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`SetChannelMap`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{SetChannelMap: args},
})
if err != nil {
return nil, err
}
if r.Body.SetChannelMap == nil {
return nil, errors.New(`unexpected respose from service calling renderingcontrol.SetChannelMap()`)
}
return r.Body.SetChannelMap, nil
}
type SetRoomCalibrationXArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
InstanceID uint32 `xml:"InstanceID"`
CalibrationID string `xml:"CalibrationID"`
Coefficients string `xml:"Coefficients"`
CalibrationMode string `xml:"CalibrationMode"`
}
type SetRoomCalibrationXResponse struct {
}
func (s *Service) SetRoomCalibrationX(httpClient *http.Client, args *SetRoomCalibrationXArgs) (*SetRoomCalibrationXResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`SetRoomCalibrationX`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{SetRoomCalibrationX: args},
})
if err != nil {
return nil, err
}
if r.Body.SetRoomCalibrationX == nil {
return nil, errors.New(`unexpected respose from service calling renderingcontrol.SetRoomCalibrationX()`)
}
return r.Body.SetRoomCalibrationX, nil
}
type GetRoomCalibrationStatusArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
InstanceID uint32 `xml:"InstanceID"`
}
type GetRoomCalibrationStatusResponse struct {
RoomCalibrationEnabled bool `xml:"RoomCalibrationEnabled"`
RoomCalibrationAvailable bool `xml:"RoomCalibrationAvailable"`
}
func (s *Service) GetRoomCalibrationStatus(httpClient *http.Client, args *GetRoomCalibrationStatusArgs) (*GetRoomCalibrationStatusResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`GetRoomCalibrationStatus`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{GetRoomCalibrationStatus: args},
})
if err != nil {
return nil, err
}
if r.Body.GetRoomCalibrationStatus == nil {
return nil, errors.New(`unexpected respose from service calling renderingcontrol.GetRoomCalibrationStatus()`)
}
return r.Body.GetRoomCalibrationStatus, nil
}
type SetRoomCalibrationStatusArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
InstanceID uint32 `xml:"InstanceID"`
RoomCalibrationEnabled bool `xml:"RoomCalibrationEnabled"`
}
type SetRoomCalibrationStatusResponse struct {
}
func (s *Service) SetRoomCalibrationStatus(httpClient *http.Client, args *SetRoomCalibrationStatusArgs) (*SetRoomCalibrationStatusResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`SetRoomCalibrationStatus`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{SetRoomCalibrationStatus: args},
})
if err != nil {
return nil, err
}
if r.Body.SetRoomCalibrationStatus == nil {
return nil, errors.New(`unexpected respose from service calling renderingcontrol.SetRoomCalibrationStatus()`)
}
return r.Body.SetRoomCalibrationStatus, nil
}
-576
View File
@@ -1,576 +0,0 @@
package systemproperties
import (
"bytes"
"encoding/xml"
"errors"
"io/ioutil"
"net/http"
"net/url"
)
const (
_ServiceURN = "urn:schemas-upnp-org:service:SystemProperties:1"
_EncodingSchema = "http://schemas.xmlsoap.org/soap/encoding/"
_EnvelopeSchema = "http://schemas.xmlsoap.org/soap/envelope/"
)
type Service struct {
ControlEndpoint *url.URL
EventEndpoint *url.URL
}
func NewService(deviceUrl *url.URL) *Service {
c, err := url.Parse(`/SystemProperties/Control`)
if nil != err {
panic(err)
}
e, err := url.Parse(`/SystemProperties/Event`)
if nil != err {
panic(err)
}
return &Service{
ControlEndpoint: deviceUrl.ResolveReference(c),
EventEndpoint: deviceUrl.ResolveReference(e),
}
}
type Envelope struct {
XMLName xml.Name `xml:"s:Envelope"`
Xmlns string `xml:"xmlns:s,attr"`
EncodingStyle string `xml:"s:encodingStyle,attr"`
Body Body `xml:"s:Body"`
}
type Body struct {
XMLName xml.Name `xml:"s:Body"`
SetString *SetStringArgs `xml:"u:SetString,omitempty"`
GetString *GetStringArgs `xml:"u:GetString,omitempty"`
Remove *RemoveArgs `xml:"u:Remove,omitempty"`
GetWebCode *GetWebCodeArgs `xml:"u:GetWebCode,omitempty"`
ProvisionCredentialedTrialAccountX *ProvisionCredentialedTrialAccountXArgs `xml:"u:ProvisionCredentialedTrialAccountX,omitempty"`
AddAccountX *AddAccountXArgs `xml:"u:AddAccountX,omitempty"`
AddOAuthAccountX *AddOAuthAccountXArgs `xml:"u:AddOAuthAccountX,omitempty"`
RemoveAccount *RemoveAccountArgs `xml:"u:RemoveAccount,omitempty"`
EditAccountPasswordX *EditAccountPasswordXArgs `xml:"u:EditAccountPasswordX,omitempty"`
SetAccountNicknameX *SetAccountNicknameXArgs `xml:"u:SetAccountNicknameX,omitempty"`
RefreshAccountCredentialsX *RefreshAccountCredentialsXArgs `xml:"u:RefreshAccountCredentialsX,omitempty"`
EditAccountMd *EditAccountMdArgs `xml:"u:EditAccountMd,omitempty"`
DoPostUpdateTasks *DoPostUpdateTasksArgs `xml:"u:DoPostUpdateTasks,omitempty"`
ResetThirdPartyCredentials *ResetThirdPartyCredentialsArgs `xml:"u:ResetThirdPartyCredentials,omitempty"`
EnableRDM *EnableRDMArgs `xml:"u:EnableRDM,omitempty"`
GetRDM *GetRDMArgs `xml:"u:GetRDM,omitempty"`
ReplaceAccountX *ReplaceAccountXArgs `xml:"u:ReplaceAccountX,omitempty"`
}
type EnvelopeResponse struct {
XMLName xml.Name `xml:"Envelope"`
Xmlns string `xml:"xmlns:s,attr"`
EncodingStyle string `xml:"encodingStyle,attr"`
Body BodyResponse `xml:"Body"`
}
type BodyResponse struct {
XMLName xml.Name `xml:"Body"`
SetString *SetStringResponse `xml:"SetStringResponse,omitempty"`
GetString *GetStringResponse `xml:"GetStringResponse,omitempty"`
Remove *RemoveResponse `xml:"RemoveResponse,omitempty"`
GetWebCode *GetWebCodeResponse `xml:"GetWebCodeResponse,omitempty"`
ProvisionCredentialedTrialAccountX *ProvisionCredentialedTrialAccountXResponse `xml:"ProvisionCredentialedTrialAccountXResponse,omitempty"`
AddAccountX *AddAccountXResponse `xml:"AddAccountXResponse,omitempty"`
AddOAuthAccountX *AddOAuthAccountXResponse `xml:"AddOAuthAccountXResponse,omitempty"`
RemoveAccount *RemoveAccountResponse `xml:"RemoveAccountResponse,omitempty"`
EditAccountPasswordX *EditAccountPasswordXResponse `xml:"EditAccountPasswordXResponse,omitempty"`
SetAccountNicknameX *SetAccountNicknameXResponse `xml:"SetAccountNicknameXResponse,omitempty"`
RefreshAccountCredentialsX *RefreshAccountCredentialsXResponse `xml:"RefreshAccountCredentialsXResponse,omitempty"`
EditAccountMd *EditAccountMdResponse `xml:"EditAccountMdResponse,omitempty"`
DoPostUpdateTasks *DoPostUpdateTasksResponse `xml:"DoPostUpdateTasksResponse,omitempty"`
ResetThirdPartyCredentials *ResetThirdPartyCredentialsResponse `xml:"ResetThirdPartyCredentialsResponse,omitempty"`
EnableRDM *EnableRDMResponse `xml:"EnableRDMResponse,omitempty"`
GetRDM *GetRDMResponse `xml:"GetRDMResponse,omitempty"`
ReplaceAccountX *ReplaceAccountXResponse `xml:"ReplaceAccountXResponse,omitempty"`
}
func (s *Service) exec(actionName string, httpClient *http.Client, envelope *Envelope) (*EnvelopeResponse, error) {
marshaled, err := xml.Marshal(envelope)
if err != nil {
return nil, err
}
postBody := []byte(`<?xml version="1.0"?>`)
postBody = append(postBody, marshaled...)
req, err := http.NewRequest(`POST`, s.ControlEndpoint.String(), bytes.NewBuffer(postBody))
if err != nil {
return nil, err
}
req.Header.Set(`Content-Type`, `text/xml; charset="utf-8"`)
req.Header.Set(`SOAPAction`, _ServiceURN+`#`+actionName)
res, err := httpClient.Do(req)
if err != nil {
return nil, err
}
defer res.Body.Close()
responseBody, err := ioutil.ReadAll(res.Body)
if err != nil {
return nil, err
}
var envelopeResponse EnvelopeResponse
err = xml.Unmarshal(responseBody, &envelopeResponse)
if err != nil {
return nil, err
}
return &envelopeResponse, nil
}
type SetStringArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
VariableName string `xml:"VariableName"`
StringValue string `xml:"StringValue"`
}
type SetStringResponse struct {
}
func (s *Service) SetString(httpClient *http.Client, args *SetStringArgs) (*SetStringResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`SetString`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{SetString: args},
})
if err != nil {
return nil, err
}
if r.Body.SetString == nil {
return nil, errors.New(`unexpected respose from service calling systemproperties.SetString()`)
}
return r.Body.SetString, nil
}
type GetStringArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
VariableName string `xml:"VariableName"`
}
type GetStringResponse struct {
StringValue string `xml:"StringValue"`
}
func (s *Service) GetString(httpClient *http.Client, args *GetStringArgs) (*GetStringResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`GetString`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{GetString: args},
})
if err != nil {
return nil, err
}
if r.Body.GetString == nil {
return nil, errors.New(`unexpected respose from service calling systemproperties.GetString()`)
}
return r.Body.GetString, nil
}
type RemoveArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
VariableName string `xml:"VariableName"`
}
type RemoveResponse struct {
}
func (s *Service) Remove(httpClient *http.Client, args *RemoveArgs) (*RemoveResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`Remove`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{Remove: args},
})
if err != nil {
return nil, err
}
if r.Body.Remove == nil {
return nil, errors.New(`unexpected respose from service calling systemproperties.Remove()`)
}
return r.Body.Remove, nil
}
type GetWebCodeArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
AccountType uint32 `xml:"AccountType"`
}
type GetWebCodeResponse struct {
WebCode string `xml:"WebCode"`
}
func (s *Service) GetWebCode(httpClient *http.Client, args *GetWebCodeArgs) (*GetWebCodeResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`GetWebCode`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{GetWebCode: args},
})
if err != nil {
return nil, err
}
if r.Body.GetWebCode == nil {
return nil, errors.New(`unexpected respose from service calling systemproperties.GetWebCode()`)
}
return r.Body.GetWebCode, nil
}
type ProvisionCredentialedTrialAccountXArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
AccountType uint32 `xml:"AccountType"`
AccountID string `xml:"AccountID"`
AccountPassword string `xml:"AccountPassword"`
}
type ProvisionCredentialedTrialAccountXResponse struct {
IsExpired bool `xml:"IsExpired"`
AccountUDN string `xml:"AccountUDN"`
}
func (s *Service) ProvisionCredentialedTrialAccountX(httpClient *http.Client, args *ProvisionCredentialedTrialAccountXArgs) (*ProvisionCredentialedTrialAccountXResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`ProvisionCredentialedTrialAccountX`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{ProvisionCredentialedTrialAccountX: args},
})
if err != nil {
return nil, err
}
if r.Body.ProvisionCredentialedTrialAccountX == nil {
return nil, errors.New(`unexpected respose from service calling systemproperties.ProvisionCredentialedTrialAccountX()`)
}
return r.Body.ProvisionCredentialedTrialAccountX, nil
}
type AddAccountXArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
AccountType uint32 `xml:"AccountType"`
AccountID string `xml:"AccountID"`
AccountPassword string `xml:"AccountPassword"`
}
type AddAccountXResponse struct {
AccountUDN string `xml:"AccountUDN"`
}
func (s *Service) AddAccountX(httpClient *http.Client, args *AddAccountXArgs) (*AddAccountXResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`AddAccountX`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{AddAccountX: args},
})
if err != nil {
return nil, err
}
if r.Body.AddAccountX == nil {
return nil, errors.New(`unexpected respose from service calling systemproperties.AddAccountX()`)
}
return r.Body.AddAccountX, nil
}
type AddOAuthAccountXArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
AccountType uint32 `xml:"AccountType"`
AccountToken string `xml:"AccountToken"`
AccountKey string `xml:"AccountKey"`
OAuthDeviceID string `xml:"OAuthDeviceID"`
AuthorizationCode string `xml:"AuthorizationCode"`
RedirectURI string `xml:"RedirectURI"`
UserIdHashCode string `xml:"UserIdHashCode"`
AccountTier uint32 `xml:"AccountTier"`
}
type AddOAuthAccountXResponse struct {
AccountUDN string `xml:"AccountUDN"`
AccountNickname string `xml:"AccountNickname"`
}
func (s *Service) AddOAuthAccountX(httpClient *http.Client, args *AddOAuthAccountXArgs) (*AddOAuthAccountXResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`AddOAuthAccountX`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{AddOAuthAccountX: args},
})
if err != nil {
return nil, err
}
if r.Body.AddOAuthAccountX == nil {
return nil, errors.New(`unexpected respose from service calling systemproperties.AddOAuthAccountX()`)
}
return r.Body.AddOAuthAccountX, nil
}
type RemoveAccountArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
AccountType uint32 `xml:"AccountType"`
AccountID string `xml:"AccountID"`
}
type RemoveAccountResponse struct {
}
func (s *Service) RemoveAccount(httpClient *http.Client, args *RemoveAccountArgs) (*RemoveAccountResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`RemoveAccount`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{RemoveAccount: args},
})
if err != nil {
return nil, err
}
if r.Body.RemoveAccount == nil {
return nil, errors.New(`unexpected respose from service calling systemproperties.RemoveAccount()`)
}
return r.Body.RemoveAccount, nil
}
type EditAccountPasswordXArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
AccountType uint32 `xml:"AccountType"`
AccountID string `xml:"AccountID"`
NewAccountPassword string `xml:"NewAccountPassword"`
}
type EditAccountPasswordXResponse struct {
}
func (s *Service) EditAccountPasswordX(httpClient *http.Client, args *EditAccountPasswordXArgs) (*EditAccountPasswordXResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`EditAccountPasswordX`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{EditAccountPasswordX: args},
})
if err != nil {
return nil, err
}
if r.Body.EditAccountPasswordX == nil {
return nil, errors.New(`unexpected respose from service calling systemproperties.EditAccountPasswordX()`)
}
return r.Body.EditAccountPasswordX, nil
}
type SetAccountNicknameXArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
AccountUDN string `xml:"AccountUDN"`
AccountNickname string `xml:"AccountNickname"`
}
type SetAccountNicknameXResponse struct {
}
func (s *Service) SetAccountNicknameX(httpClient *http.Client, args *SetAccountNicknameXArgs) (*SetAccountNicknameXResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`SetAccountNicknameX`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{SetAccountNicknameX: args},
})
if err != nil {
return nil, err
}
if r.Body.SetAccountNicknameX == nil {
return nil, errors.New(`unexpected respose from service calling systemproperties.SetAccountNicknameX()`)
}
return r.Body.SetAccountNicknameX, nil
}
type RefreshAccountCredentialsXArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
AccountType uint32 `xml:"AccountType"`
AccountUID uint32 `xml:"AccountUID"`
AccountToken string `xml:"AccountToken"`
AccountKey string `xml:"AccountKey"`
}
type RefreshAccountCredentialsXResponse struct {
}
func (s *Service) RefreshAccountCredentialsX(httpClient *http.Client, args *RefreshAccountCredentialsXArgs) (*RefreshAccountCredentialsXResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`RefreshAccountCredentialsX`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{RefreshAccountCredentialsX: args},
})
if err != nil {
return nil, err
}
if r.Body.RefreshAccountCredentialsX == nil {
return nil, errors.New(`unexpected respose from service calling systemproperties.RefreshAccountCredentialsX()`)
}
return r.Body.RefreshAccountCredentialsX, nil
}
type EditAccountMdArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
AccountType uint32 `xml:"AccountType"`
AccountID string `xml:"AccountID"`
NewAccountMd string `xml:"NewAccountMd"`
}
type EditAccountMdResponse struct {
}
func (s *Service) EditAccountMd(httpClient *http.Client, args *EditAccountMdArgs) (*EditAccountMdResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`EditAccountMd`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{EditAccountMd: args},
})
if err != nil {
return nil, err
}
if r.Body.EditAccountMd == nil {
return nil, errors.New(`unexpected respose from service calling systemproperties.EditAccountMd()`)
}
return r.Body.EditAccountMd, nil
}
type DoPostUpdateTasksArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
}
type DoPostUpdateTasksResponse struct {
}
func (s *Service) DoPostUpdateTasks(httpClient *http.Client, args *DoPostUpdateTasksArgs) (*DoPostUpdateTasksResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`DoPostUpdateTasks`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{DoPostUpdateTasks: args},
})
if err != nil {
return nil, err
}
if r.Body.DoPostUpdateTasks == nil {
return nil, errors.New(`unexpected respose from service calling systemproperties.DoPostUpdateTasks()`)
}
return r.Body.DoPostUpdateTasks, nil
}
type ResetThirdPartyCredentialsArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
}
type ResetThirdPartyCredentialsResponse struct {
}
func (s *Service) ResetThirdPartyCredentials(httpClient *http.Client, args *ResetThirdPartyCredentialsArgs) (*ResetThirdPartyCredentialsResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`ResetThirdPartyCredentials`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{ResetThirdPartyCredentials: args},
})
if err != nil {
return nil, err
}
if r.Body.ResetThirdPartyCredentials == nil {
return nil, errors.New(`unexpected respose from service calling systemproperties.ResetThirdPartyCredentials()`)
}
return r.Body.ResetThirdPartyCredentials, nil
}
type EnableRDMArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
RDMValue bool `xml:"RDMValue"`
}
type EnableRDMResponse struct {
}
func (s *Service) EnableRDM(httpClient *http.Client, args *EnableRDMArgs) (*EnableRDMResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`EnableRDM`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{EnableRDM: args},
})
if err != nil {
return nil, err
}
if r.Body.EnableRDM == nil {
return nil, errors.New(`unexpected respose from service calling systemproperties.EnableRDM()`)
}
return r.Body.EnableRDM, nil
}
type GetRDMArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
}
type GetRDMResponse struct {
RDMValue bool `xml:"RDMValue"`
}
func (s *Service) GetRDM(httpClient *http.Client, args *GetRDMArgs) (*GetRDMResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`GetRDM`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{GetRDM: args},
})
if err != nil {
return nil, err
}
if r.Body.GetRDM == nil {
return nil, errors.New(`unexpected respose from service calling systemproperties.GetRDM()`)
}
return r.Body.GetRDM, nil
}
type ReplaceAccountXArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
AccountUDN string `xml:"AccountUDN"`
NewAccountID string `xml:"NewAccountID"`
NewAccountPassword string `xml:"NewAccountPassword"`
AccountToken string `xml:"AccountToken"`
AccountKey string `xml:"AccountKey"`
OAuthDeviceID string `xml:"OAuthDeviceID"`
}
type ReplaceAccountXResponse struct {
NewAccountUDN string `xml:"NewAccountUDN"`
}
func (s *Service) ReplaceAccountX(httpClient *http.Client, args *ReplaceAccountXArgs) (*ReplaceAccountXResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`ReplaceAccountX`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{ReplaceAccountX: args},
})
if err != nil {
return nil, err
}
if r.Body.ReplaceAccountX == nil {
return nil, errors.New(`unexpected respose from service calling systemproperties.ReplaceAccountX()`)
}
return r.Body.ReplaceAccountX, nil
}
-306
View File
@@ -1,306 +0,0 @@
package virtuallinein
import (
"bytes"
"encoding/xml"
"errors"
"io/ioutil"
"net/http"
"net/url"
)
const (
_ServiceURN = "urn:schemas-upnp-org:service:VirtualLineIn:1"
_EncodingSchema = "http://schemas.xmlsoap.org/soap/encoding/"
_EnvelopeSchema = "http://schemas.xmlsoap.org/soap/envelope/"
)
type Service struct {
ControlEndpoint *url.URL
EventEndpoint *url.URL
}
func NewService(deviceUrl *url.URL) *Service {
c, err := url.Parse(`/MediaRenderer/VirtualLineIn/Control`)
if nil != err {
panic(err)
}
e, err := url.Parse(`/MediaRenderer/VirtualLineIn/Event`)
if nil != err {
panic(err)
}
return &Service{
ControlEndpoint: deviceUrl.ResolveReference(c),
EventEndpoint: deviceUrl.ResolveReference(e),
}
}
type Envelope struct {
XMLName xml.Name `xml:"s:Envelope"`
Xmlns string `xml:"xmlns:s,attr"`
EncodingStyle string `xml:"s:encodingStyle,attr"`
Body Body `xml:"s:Body"`
}
type Body struct {
XMLName xml.Name `xml:"s:Body"`
StartTransmission *StartTransmissionArgs `xml:"u:StartTransmission,omitempty"`
StopTransmission *StopTransmissionArgs `xml:"u:StopTransmission,omitempty"`
Play *PlayArgs `xml:"u:Play,omitempty"`
Pause *PauseArgs `xml:"u:Pause,omitempty"`
Next *NextArgs `xml:"u:Next,omitempty"`
Previous *PreviousArgs `xml:"u:Previous,omitempty"`
Stop *StopArgs `xml:"u:Stop,omitempty"`
SetVolume *SetVolumeArgs `xml:"u:SetVolume,omitempty"`
}
type EnvelopeResponse struct {
XMLName xml.Name `xml:"Envelope"`
Xmlns string `xml:"xmlns:s,attr"`
EncodingStyle string `xml:"encodingStyle,attr"`
Body BodyResponse `xml:"Body"`
}
type BodyResponse struct {
XMLName xml.Name `xml:"Body"`
StartTransmission *StartTransmissionResponse `xml:"StartTransmissionResponse,omitempty"`
StopTransmission *StopTransmissionResponse `xml:"StopTransmissionResponse,omitempty"`
Play *PlayResponse `xml:"PlayResponse,omitempty"`
Pause *PauseResponse `xml:"PauseResponse,omitempty"`
Next *NextResponse `xml:"NextResponse,omitempty"`
Previous *PreviousResponse `xml:"PreviousResponse,omitempty"`
Stop *StopResponse `xml:"StopResponse,omitempty"`
SetVolume *SetVolumeResponse `xml:"SetVolumeResponse,omitempty"`
}
func (s *Service) exec(actionName string, httpClient *http.Client, envelope *Envelope) (*EnvelopeResponse, error) {
marshaled, err := xml.Marshal(envelope)
if err != nil {
return nil, err
}
postBody := []byte(`<?xml version="1.0"?>`)
postBody = append(postBody, marshaled...)
req, err := http.NewRequest(`POST`, s.ControlEndpoint.String(), bytes.NewBuffer(postBody))
if err != nil {
return nil, err
}
req.Header.Set(`Content-Type`, `text/xml; charset="utf-8"`)
req.Header.Set(`SOAPAction`, _ServiceURN+`#`+actionName)
res, err := httpClient.Do(req)
if err != nil {
return nil, err
}
defer res.Body.Close()
responseBody, err := ioutil.ReadAll(res.Body)
if err != nil {
return nil, err
}
var envelopeResponse EnvelopeResponse
err = xml.Unmarshal(responseBody, &envelopeResponse)
if err != nil {
return nil, err
}
return &envelopeResponse, nil
}
type StartTransmissionArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
InstanceID uint32 `xml:"InstanceID"`
CoordinatorID string `xml:"CoordinatorID"`
}
type StartTransmissionResponse struct {
CurrentTransportSettings string `xml:"CurrentTransportSettings"`
}
func (s *Service) StartTransmission(httpClient *http.Client, args *StartTransmissionArgs) (*StartTransmissionResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`StartTransmission`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{StartTransmission: args},
})
if err != nil {
return nil, err
}
if r.Body.StartTransmission == nil {
return nil, errors.New(`unexpected respose from service calling virtuallinein.StartTransmission()`)
}
return r.Body.StartTransmission, nil
}
type StopTransmissionArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
InstanceID uint32 `xml:"InstanceID"`
CoordinatorID string `xml:"CoordinatorID"`
}
type StopTransmissionResponse struct {
}
func (s *Service) StopTransmission(httpClient *http.Client, args *StopTransmissionArgs) (*StopTransmissionResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`StopTransmission`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{StopTransmission: args},
})
if err != nil {
return nil, err
}
if r.Body.StopTransmission == nil {
return nil, errors.New(`unexpected respose from service calling virtuallinein.StopTransmission()`)
}
return r.Body.StopTransmission, nil
}
type PlayArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
InstanceID uint32 `xml:"InstanceID"`
Speed string `xml:"Speed"`
}
type PlayResponse struct {
}
func (s *Service) Play(httpClient *http.Client, args *PlayArgs) (*PlayResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`Play`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{Play: args},
})
if err != nil {
return nil, err
}
if r.Body.Play == nil {
return nil, errors.New(`unexpected respose from service calling virtuallinein.Play()`)
}
return r.Body.Play, nil
}
type PauseArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
InstanceID uint32 `xml:"InstanceID"`
}
type PauseResponse struct {
}
func (s *Service) Pause(httpClient *http.Client, args *PauseArgs) (*PauseResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`Pause`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{Pause: args},
})
if err != nil {
return nil, err
}
if r.Body.Pause == nil {
return nil, errors.New(`unexpected respose from service calling virtuallinein.Pause()`)
}
return r.Body.Pause, nil
}
type NextArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
InstanceID uint32 `xml:"InstanceID"`
}
type NextResponse struct {
}
func (s *Service) Next(httpClient *http.Client, args *NextArgs) (*NextResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`Next`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{Next: args},
})
if err != nil {
return nil, err
}
if r.Body.Next == nil {
return nil, errors.New(`unexpected respose from service calling virtuallinein.Next()`)
}
return r.Body.Next, nil
}
type PreviousArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
InstanceID uint32 `xml:"InstanceID"`
}
type PreviousResponse struct {
}
func (s *Service) Previous(httpClient *http.Client, args *PreviousArgs) (*PreviousResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`Previous`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{Previous: args},
})
if err != nil {
return nil, err
}
if r.Body.Previous == nil {
return nil, errors.New(`unexpected respose from service calling virtuallinein.Previous()`)
}
return r.Body.Previous, nil
}
type StopArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
InstanceID uint32 `xml:"InstanceID"`
}
type StopResponse struct {
}
func (s *Service) Stop(httpClient *http.Client, args *StopArgs) (*StopResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`Stop`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{Stop: args},
})
if err != nil {
return nil, err
}
if r.Body.Stop == nil {
return nil, errors.New(`unexpected respose from service calling virtuallinein.Stop()`)
}
return r.Body.Stop, nil
}
type SetVolumeArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
InstanceID uint32 `xml:"InstanceID"`
DesiredVolume uint16 `xml:"DesiredVolume"`
}
type SetVolumeResponse struct {
}
func (s *Service) SetVolume(httpClient *http.Client, args *SetVolumeArgs) (*SetVolumeResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`SetVolume`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{SetVolume: args},
})
if err != nil {
return nil, err
}
if r.Body.SetVolume == nil {
return nil, errors.New(`unexpected respose from service calling virtuallinein.SetVolume()`)
}
return r.Body.SetVolume, nil
}
-318
View File
@@ -1,318 +0,0 @@
package zonegrouptopology
import (
"bytes"
"encoding/xml"
"errors"
"io/ioutil"
"net/http"
"net/url"
)
const (
_ServiceURN = "urn:schemas-upnp-org:service:ZoneGroupTopology:1"
_EncodingSchema = "http://schemas.xmlsoap.org/soap/encoding/"
_EnvelopeSchema = "http://schemas.xmlsoap.org/soap/envelope/"
)
type Service struct {
ControlEndpoint *url.URL
EventEndpoint *url.URL
}
func NewService(deviceUrl *url.URL) *Service {
c, err := url.Parse(`/ZoneGroupTopology/Control`)
if nil != err {
panic(err)
}
e, err := url.Parse(`/ZoneGroupTopology/Event`)
if nil != err {
panic(err)
}
return &Service{
ControlEndpoint: deviceUrl.ResolveReference(c),
EventEndpoint: deviceUrl.ResolveReference(e),
}
}
type Envelope struct {
XMLName xml.Name `xml:"s:Envelope"`
Xmlns string `xml:"xmlns:s,attr"`
EncodingStyle string `xml:"s:encodingStyle,attr"`
Body Body `xml:"s:Body"`
}
type Body struct {
XMLName xml.Name `xml:"s:Body"`
CheckForUpdate *CheckForUpdateArgs `xml:"u:CheckForUpdate,omitempty"`
BeginSoftwareUpdate *BeginSoftwareUpdateArgs `xml:"u:BeginSoftwareUpdate,omitempty"`
ReportUnresponsiveDevice *ReportUnresponsiveDeviceArgs `xml:"u:ReportUnresponsiveDevice,omitempty"`
ReportAlarmStartedRunning *ReportAlarmStartedRunningArgs `xml:"u:ReportAlarmStartedRunning,omitempty"`
SubmitDiagnostics *SubmitDiagnosticsArgs `xml:"u:SubmitDiagnostics,omitempty"`
RegisterMobileDevice *RegisterMobileDeviceArgs `xml:"u:RegisterMobileDevice,omitempty"`
GetZoneGroupAttributes *GetZoneGroupAttributesArgs `xml:"u:GetZoneGroupAttributes,omitempty"`
GetZoneGroupState *GetZoneGroupStateArgs `xml:"u:GetZoneGroupState,omitempty"`
}
type EnvelopeResponse struct {
XMLName xml.Name `xml:"Envelope"`
Xmlns string `xml:"xmlns:s,attr"`
EncodingStyle string `xml:"encodingStyle,attr"`
Body BodyResponse `xml:"Body"`
}
type BodyResponse struct {
XMLName xml.Name `xml:"Body"`
CheckForUpdate *CheckForUpdateResponse `xml:"CheckForUpdateResponse,omitempty"`
BeginSoftwareUpdate *BeginSoftwareUpdateResponse `xml:"BeginSoftwareUpdateResponse,omitempty"`
ReportUnresponsiveDevice *ReportUnresponsiveDeviceResponse `xml:"ReportUnresponsiveDeviceResponse,omitempty"`
ReportAlarmStartedRunning *ReportAlarmStartedRunningResponse `xml:"ReportAlarmStartedRunningResponse,omitempty"`
SubmitDiagnostics *SubmitDiagnosticsResponse `xml:"SubmitDiagnosticsResponse,omitempty"`
RegisterMobileDevice *RegisterMobileDeviceResponse `xml:"RegisterMobileDeviceResponse,omitempty"`
GetZoneGroupAttributes *GetZoneGroupAttributesResponse `xml:"GetZoneGroupAttributesResponse,omitempty"`
GetZoneGroupState *GetZoneGroupStateResponse `xml:"GetZoneGroupStateResponse,omitempty"`
}
func (s *Service) exec(actionName string, httpClient *http.Client, envelope *Envelope) (*EnvelopeResponse, error) {
marshaled, err := xml.Marshal(envelope)
if err != nil {
return nil, err
}
postBody := []byte(`<?xml version="1.0"?>`)
postBody = append(postBody, marshaled...)
req, err := http.NewRequest(`POST`, s.ControlEndpoint.String(), bytes.NewBuffer(postBody))
if err != nil {
return nil, err
}
req.Header.Set(`Content-Type`, `text/xml; charset="utf-8"`)
req.Header.Set(`SOAPAction`, _ServiceURN+`#`+actionName)
res, err := httpClient.Do(req)
if err != nil {
return nil, err
}
defer res.Body.Close()
responseBody, err := ioutil.ReadAll(res.Body)
if err != nil {
return nil, err
}
var envelopeResponse EnvelopeResponse
err = xml.Unmarshal(responseBody, &envelopeResponse)
if err != nil {
return nil, err
}
return &envelopeResponse, nil
}
type CheckForUpdateArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
// Allowed Value: All
// Allowed Value: Software
UpdateType string `xml:"UpdateType"`
CachedOnly bool `xml:"CachedOnly"`
Version string `xml:"Version"`
}
type CheckForUpdateResponse struct {
UpdateItem string `xml:"UpdateItem"`
}
func (s *Service) CheckForUpdate(httpClient *http.Client, args *CheckForUpdateArgs) (*CheckForUpdateResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`CheckForUpdate`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{CheckForUpdate: args},
})
if err != nil {
return nil, err
}
if r.Body.CheckForUpdate == nil {
return nil, errors.New(`unexpected respose from service calling zonegrouptopology.CheckForUpdate()`)
}
return r.Body.CheckForUpdate, nil
}
type BeginSoftwareUpdateArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
UpdateURL string `xml:"UpdateURL"`
Flags uint32 `xml:"Flags"`
ExtraOptions string `xml:"ExtraOptions"`
}
type BeginSoftwareUpdateResponse struct {
}
func (s *Service) BeginSoftwareUpdate(httpClient *http.Client, args *BeginSoftwareUpdateArgs) (*BeginSoftwareUpdateResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`BeginSoftwareUpdate`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{BeginSoftwareUpdate: args},
})
if err != nil {
return nil, err
}
if r.Body.BeginSoftwareUpdate == nil {
return nil, errors.New(`unexpected respose from service calling zonegrouptopology.BeginSoftwareUpdate()`)
}
return r.Body.BeginSoftwareUpdate, nil
}
type ReportUnresponsiveDeviceArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
DeviceUUID string `xml:"DeviceUUID"`
// Allowed Value: Remove
// Allowed Value: TopologyMonitorProbe
// Allowed Value: VerifyThenRemoveSystemwide
DesiredAction string `xml:"DesiredAction"`
}
type ReportUnresponsiveDeviceResponse struct {
}
func (s *Service) ReportUnresponsiveDevice(httpClient *http.Client, args *ReportUnresponsiveDeviceArgs) (*ReportUnresponsiveDeviceResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`ReportUnresponsiveDevice`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{ReportUnresponsiveDevice: args},
})
if err != nil {
return nil, err
}
if r.Body.ReportUnresponsiveDevice == nil {
return nil, errors.New(`unexpected respose from service calling zonegrouptopology.ReportUnresponsiveDevice()`)
}
return r.Body.ReportUnresponsiveDevice, nil
}
type ReportAlarmStartedRunningArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
}
type ReportAlarmStartedRunningResponse struct {
}
func (s *Service) ReportAlarmStartedRunning(httpClient *http.Client, args *ReportAlarmStartedRunningArgs) (*ReportAlarmStartedRunningResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`ReportAlarmStartedRunning`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{ReportAlarmStartedRunning: args},
})
if err != nil {
return nil, err
}
if r.Body.ReportAlarmStartedRunning == nil {
return nil, errors.New(`unexpected respose from service calling zonegrouptopology.ReportAlarmStartedRunning()`)
}
return r.Body.ReportAlarmStartedRunning, nil
}
type SubmitDiagnosticsArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
IncludeControllers bool `xml:"IncludeControllers"`
Type string `xml:"Type"`
}
type SubmitDiagnosticsResponse struct {
DiagnosticID uint32 `xml:"DiagnosticID"`
}
func (s *Service) SubmitDiagnostics(httpClient *http.Client, args *SubmitDiagnosticsArgs) (*SubmitDiagnosticsResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`SubmitDiagnostics`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{SubmitDiagnostics: args},
})
if err != nil {
return nil, err
}
if r.Body.SubmitDiagnostics == nil {
return nil, errors.New(`unexpected respose from service calling zonegrouptopology.SubmitDiagnostics()`)
}
return r.Body.SubmitDiagnostics, nil
}
type RegisterMobileDeviceArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
MobileDeviceName string `xml:"MobileDeviceName"`
MobileDeviceUDN string `xml:"MobileDeviceUDN"`
MobileIPAndPort string `xml:"MobileIPAndPort"`
}
type RegisterMobileDeviceResponse struct {
}
func (s *Service) RegisterMobileDevice(httpClient *http.Client, args *RegisterMobileDeviceArgs) (*RegisterMobileDeviceResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`RegisterMobileDevice`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{RegisterMobileDevice: args},
})
if err != nil {
return nil, err
}
if r.Body.RegisterMobileDevice == nil {
return nil, errors.New(`unexpected respose from service calling zonegrouptopology.RegisterMobileDevice()`)
}
return r.Body.RegisterMobileDevice, nil
}
type GetZoneGroupAttributesArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
}
type GetZoneGroupAttributesResponse struct {
CurrentZoneGroupName string `xml:"CurrentZoneGroupName"`
CurrentZoneGroupID string `xml:"CurrentZoneGroupID"`
CurrentZonePlayerUUIDsInGroup string `xml:"CurrentZonePlayerUUIDsInGroup"`
CurrentMuseHouseholdId string `xml:"CurrentMuseHouseholdId"`
}
func (s *Service) GetZoneGroupAttributes(httpClient *http.Client, args *GetZoneGroupAttributesArgs) (*GetZoneGroupAttributesResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`GetZoneGroupAttributes`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{GetZoneGroupAttributes: args},
})
if err != nil {
return nil, err
}
if r.Body.GetZoneGroupAttributes == nil {
return nil, errors.New(`unexpected respose from service calling zonegrouptopology.GetZoneGroupAttributes()`)
}
return r.Body.GetZoneGroupAttributes, nil
}
type GetZoneGroupStateArgs struct {
Xmlns string `xml:"xmlns:u,attr"`
}
type GetZoneGroupStateResponse struct {
ZoneGroupState string `xml:"ZoneGroupState"`
}
func (s *Service) GetZoneGroupState(httpClient *http.Client, args *GetZoneGroupStateArgs) (*GetZoneGroupStateResponse, error) {
args.Xmlns = _ServiceURN
r, err := s.exec(`GetZoneGroupState`, httpClient,
&Envelope{
EncodingStyle: _EncodingSchema,
Xmlns: _EnvelopeSchema,
Body: Body{GetZoneGroupState: args},
})
if err != nil {
return nil, err
}
if r.Body.GetZoneGroupState == nil {
return nil, errors.New(`unexpected respose from service calling zonegrouptopology.GetZoneGroupState()`)
}
return r.Body.GetZoneGroupState, nil
}
-100
View File
@@ -1,100 +0,0 @@
package sonos
import (
"bufio"
"errors"
"fmt"
"net"
"net/http"
"net/url"
"time"
)
const (
mx = 5
st = "urn:schemas-upnp-org:device:ZonePlayer:1"
bcastaddr = "239.255.255.250:1900"
)
type Sonos struct {
// Context Context
listenSocket *net.UDPConn
udpReader *bufio.Reader
found chan *ZonePlayer
}
func NewSonos() (*Sonos, error) {
conn, err := net.ListenUDP("udp", &net.UDPAddr{IP: []byte{0, 0, 0, 0}, Port: 0, Zone: ""})
if err != nil {
return nil, err
}
s := Sonos{
listenSocket: conn,
udpReader: bufio.NewReader(conn),
found: make(chan *ZonePlayer),
}
return &s, nil
}
func (s *Sonos) Close() {
s.listenSocket.Close()
}
func (s *Sonos) Search() (chan *ZonePlayer, error) {
go func() {
for {
response, err := http.ReadResponse(s.udpReader, nil)
if err != nil {
continue
}
location, err := url.Parse(response.Header.Get("Location"))
if err != nil {
continue
}
zp, err := NewZonePlayer(location)
if err != nil {
continue
}
if zp.IsCoordinator() {
s.found <- zp
}
}
}()
// MX should be set to use timeout value in integer seconds
pkt := []byte(fmt.Sprintf("M-SEARCH * HTTP/1.1\r\nHOST: %s\r\nMAN: \"ssdp:discover\"\r\nMX: %d\r\nST: %s\r\n\r\n", bcastaddr, mx, st))
bcast, err := net.ResolveUDPAddr("udp", bcastaddr)
if err != nil {
return nil, err
}
_, err = s.listenSocket.WriteTo(pkt, bcast)
if err != nil {
return nil, err
}
return s.found, nil
}
func FindRoom(room string, timeout time.Duration) (*ZonePlayer, error) {
son, err := NewSonos()
if err != nil {
return nil, err
}
defer son.Close()
found, _ := son.Search()
to := time.After(timeout)
for {
select {
case <-to:
return nil, errors.New("timeout")
case zp := <-found:
if zp.RoomName() == room {
return zp, nil
}
}
}
}
-107
View File
@@ -1,107 +0,0 @@
package sonos
import "encoding/xml"
type VanishedDevice struct {
XMLName xml.Name `xml:"VanishedDevice"`
UUID string `xml:"UUID"`
Location string `xml:"Location"`
ZoneName string `xml:"ZoneName"`
Icon string `xml:"Icon"`
Configuration string `xml:"Configuration"`
SoftwareVersion string `xml:"SoftwareVersion"`
SWGen string `xml:"SWGen"`
MinCompatibleVersion string `xml:"MinCompatibleVersion"`
LegacyCompatibleVersion string `xml:"LegacyCompatibleVersion"`
BootSeq string `xml:"BootSeq"`
TVConfigurationError string `xml:"TVConfigurationError"`
HdmiCecAvailable string `xml:"HdmiCecAvailable"`
WirelessMode string `xml:"WirelessMode"`
WirelessLeafOnly string `xml:"WirelessLeafOnly"`
HasConfiguredSSID string `xml:"HasConfiguredSSID"`
ChannelFreq string `xml:"ChannelFreq"`
BehindWifiExtender string `xml:"BehindWifiExtender"`
WifiEnabled string `xml:"WifiEnabled"`
Orientation string `xml:"Orientation"`
RoomCalibrationState string `xml:"RoomCalibrationState"`
SecureRegState string `xml:"SecureRegState"`
VoiceConfigState string `xml:"VoiceConfigState"`
MicEnabled string `xml:"MicEnabled"`
AirPlayEnabled string `xml:"AirPlayEnabled"`
IdleState string `xml:"IdleState"`
MoreInfo string `xml:"MoreInfo"`
}
type Satellite struct {
XMLName xml.Name `xml:"Satellite"`
UUID string `xml:"UUID"`
Location string `xml:"Location"`
ZoneName string `xml:"ZoneName"`
Icon string `xml:"Icon"`
Configuration string `xml:"Configuration"`
SoftwareVersion string `xml:"SoftwareVersion"`
SWGen string `xml:"SWGen"`
MinCompatibleVersion string `xml:"MinCompatibleVersion"`
LegacyCompatibleVersion string `xml:"LegacyCompatibleVersion"`
BootSeq string `xml:"BootSeq"`
TVConfigurationError string `xml:"TVConfigurationError"`
HdmiCecAvailable string `xml:"HdmiCecAvailable"`
WirelessMode string `xml:"WirelessMode"`
WirelessLeafOnly string `xml:"WirelessLeafOnly"`
HasConfiguredSSID string `xml:"HasConfiguredSSID"`
ChannelFreq string `xml:"ChannelFreq"`
BehindWifiExtender string `xml:"BehindWifiExtender"`
WifiEnabled string `xml:"WifiEnabled"`
Orientation string `xml:"Orientation"`
RoomCalibrationState string `xml:"RoomCalibrationState"`
SecureRegState string `xml:"SecureRegState"`
VoiceConfigState string `xml:"VoiceConfigState"`
MicEnabled string `xml:"MicEnabled"`
AirPlayEnabled string `xml:"AirPlayEnabled"`
IdleState string `xml:"IdleState"`
MoreInfo string `xml:"MoreInfo"`
}
type ZoneGroupMember struct {
XMLName xml.Name `xml:"ZoneGroupMember"`
UUID string `xml:"UUID"`
Location string `xml:"Location"`
ZoneName string `xml:"ZoneName"`
Icon string `xml:"Icon"`
Configuration string `xml:"Configuration"`
SoftwareVersion string `xml:"SoftwareVersion"`
SWGen string `xml:"SWGen"`
MinCompatibleVersion string `xml:"MinCompatibleVersion"`
LegacyCompatibleVersion string `xml:"LegacyCompatibleVersion"`
BootSeq string `xml:"BootSeq"`
TVConfigurationError string `xml:"TVConfigurationError"`
HdmiCecAvailable string `xml:"HdmiCecAvailable"`
WirelessMode string `xml:"WirelessMode"`
WirelessLeafOnly string `xml:"WirelessLeafOnly"`
HasConfiguredSSID string `xml:"HasConfiguredSSID"`
ChannelFreq string `xml:"ChannelFreq"`
BehindWifiExtender string `xml:"BehindWifiExtender"`
WifiEnabled string `xml:"WifiEnabled"`
Orientation string `xml:"Orientation"`
RoomCalibrationState string `xml:"RoomCalibrationState"`
SecureRegState string `xml:"SecureRegState"`
VoiceConfigState string `xml:"VoiceConfigState"`
MicEnabled string `xml:"MicEnabled"`
AirPlayEnabled string `xml:"AirPlayEnabled"`
IdleState string `xml:"IdleState"`
MoreInfo string `xml:"MoreInfo"`
Satellite []Satellite `xml:"Satellite>Satellite"`
VanishedDevice []VanishedDevice `xml:"VanishedDevices>VanishedDevice"`
}
type ZoneGroup struct {
XMLName xml.Name `xml:"ZoneGroup"`
Coordinator string `xml:"Coordinator,attr"`
ID string `xml:"ID,attr"`
ZoneGroupMember []ZoneGroupMember `xml:"ZoneGroupMember"`
}
type ZoneGroupState struct {
XMLName xml.Name `xml:"ZoneGroupState"`
ZoneGroups []ZoneGroup `xml:"ZoneGroups>ZoneGroup"`
}
-236
View File
@@ -1,236 +0,0 @@
package sonos
import (
"encoding/xml"
"io/ioutil"
"net/http"
"net/url"
avt "github.com/szatmary/sonos/AVTransport"
clk "github.com/szatmary/sonos/AlarmClock"
con "github.com/szatmary/sonos/ConnectionManager"
dir "github.com/szatmary/sonos/ContentDirectory"
dev "github.com/szatmary/sonos/DeviceProperties"
gmn "github.com/szatmary/sonos/GroupManagement"
rcg "github.com/szatmary/sonos/GroupRenderingControl"
mus "github.com/szatmary/sonos/MusicServices"
ply "github.com/szatmary/sonos/QPlay"
que "github.com/szatmary/sonos/Queue"
ren "github.com/szatmary/sonos/RenderingControl"
sys "github.com/szatmary/sonos/SystemProperties"
vli "github.com/szatmary/sonos/VirtualLineIn"
zgt "github.com/szatmary/sonos/ZoneGroupTopology"
)
type SpecVersion struct {
XMLName xml.Name `xml:"specVersion"`
Major int `xml:"major"`
Minor int `xml:"minor"`
}
type Service struct {
XMLName xml.Name `xml:"service"`
ServiceType string `xml:"serviceType"`
ServiceId string `xml:"serviceId"`
ControlURL string `xml:"controlURL"`
EventSubURL string `xml:"eventSubURL"`
SCPDURL string `xml:"SCPDURL"`
}
type Icon struct {
XMLName xml.Name `xml:"icon"`
Id string `xml:"id"`
Mimetype string `xml:"mimetype"`
Width int `xml:"width"`
Height int `xml:"height"`
Depth int `xml:"depth"`
Url url.URL `xml:"url"`
}
type Device struct {
XMLName xml.Name `xml:"device"`
DeviceType string `xml:"deviceType"`
FriendlyName string `xml:"friendlyName"`
Manufacturer string `xml:"manufacturer"`
ManufacturerURL string `xml:"manufacturerURL"`
ModelNumber string `xml:"modelNumber"`
ModelDescription string `xml:"modelDescription"`
ModelName string `xml:"modelName"`
ModelURL string `xml:"modelURL"`
SoftwareVersion string `xml:"softwareVersion"`
SwGen string `xml:"swGen"`
HardwareVersion string `xml:"hardwareVersion"`
SerialNum string `xml:"serialNum"`
MACAddress string `xml:"MACAddress"`
UDN string `xml:"UDN"`
Icons []Icon `xml:"iconList>icon"`
MinCompatibleVersion string `xml:"minCompatibleVersion"`
LegacyCompatibleVersion string `xml:"legacyCompatibleVersion"`
ApiVersion string `xml:"apiVersion"`
MinApiVersion string `xml:"minApiVersion"`
DisplayVersion string `xml:"displayVersion"`
ExtraVersion string `xml:"extraVersion"`
RoomName string `xml:"roomName"`
DisplayName string `xml:"displayName"`
ZoneType int `xml:"zoneType"`
Feature1 string `xml:"feature1"`
Feature2 string `xml:"feature2"`
Feature3 string `xml:"feature3"`
Seriesid string `xml:"seriesid"`
Variant int `xml:"variant"`
InternalSpeakerSize float32 `xml:"internalSpeakerSize"`
BassExtension float32 `xml:"bassExtension"`
SatGainOffset float32 `xml:"satGainOffset"`
Memory int `xml:"memory"`
Flash int `xml:"flash"`
FlashRepartitioned int `xml:"flashRepartitioned"`
AmpOnTime int `xml:"ampOnTime"`
RetailMode int `xml:"retailMode"`
Services []Service `xml:"serviceList>service"`
Devices []Device `xml:"deviceList>device"`
}
type Root struct {
XMLName xml.Name `xml:"root"`
Xmlns string `xml:"xmlns,attr"`
SpecVersion SpecVersion `xml:"specVersion"`
Device Device `xml:"device"`
}
type ZonePlayer struct {
Root *Root
HttpClient *http.Client
DeviceDescriptionURL *url.URL
// services
AlarmClock *clk.Service
AVTransport *avt.Service
ConnectionManager *con.Service
ContentDirectory *dir.Service
DeviceProperties *dev.Service
GroupManagement *gmn.Service
GroupRenderingControl *rcg.Service
MusicServices *mus.Service
QPlay *ply.Service
Queue *que.Service
RenderingControl *ren.Service
SystemProperties *sys.Service
VirtualLineIn *vli.Service
ZoneGroupTopology *zgt.Service
}
func NewZonePlayer(deviceDescriptionURL *url.URL) (*ZonePlayer, error) {
zp := ZonePlayer{
Root: &Root{},
HttpClient: &http.Client{},
DeviceDescriptionURL: deviceDescriptionURL,
AlarmClock: clk.NewService(deviceDescriptionURL),
AVTransport: avt.NewService(deviceDescriptionURL),
ConnectionManager: con.NewService(deviceDescriptionURL),
ContentDirectory: dir.NewService(deviceDescriptionURL),
DeviceProperties: dev.NewService(deviceDescriptionURL),
GroupManagement: gmn.NewService(deviceDescriptionURL),
GroupRenderingControl: rcg.NewService(deviceDescriptionURL),
MusicServices: mus.NewService(deviceDescriptionURL),
QPlay: ply.NewService(deviceDescriptionURL),
Queue: que.NewService(deviceDescriptionURL),
RenderingControl: ren.NewService(deviceDescriptionURL),
SystemProperties: sys.NewService(deviceDescriptionURL),
VirtualLineIn: vli.NewService(deviceDescriptionURL),
ZoneGroupTopology: zgt.NewService(deviceDescriptionURL),
}
resp, err := zp.HttpClient.Get(zp.DeviceDescriptionURL.String())
if err != nil {
return nil, err
}
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
defer resp.Body.Close()
err = xml.Unmarshal(body, zp.Root)
if err != nil {
return nil, err
}
return &zp, nil
}
func (z *ZonePlayer) RoomName() string {
return z.Root.Device.RoomName
}
func (z *ZonePlayer) ModelName() string {
return z.Root.Device.ModelName
}
func (z *ZonePlayer) HardwareVersion() string {
return z.Root.Device.HardwareVersion
}
func (z *ZonePlayer) SerialNum() string {
return z.Root.Device.SerialNum
}
func (z *ZonePlayer) IsCoordinator() bool {
zoneGroupState, err := z.GetZoneGroupState()
if err != nil {
return false
}
for _, group := range zoneGroupState.ZoneGroups {
if "uuid:"+group.Coordinator == z.Root.Device.UDN {
return true
}
}
return false
}
// Convience functions
func (z *ZonePlayer) GetZoneGroupState() (*ZoneGroupState, error) {
zoneGroupStateResponse, err := z.ZoneGroupTopology.GetZoneGroupState(z.HttpClient, &zgt.GetZoneGroupStateArgs{})
if err != nil {
return nil, err
}
var zoneGroupState ZoneGroupState
err = xml.Unmarshal([]byte(zoneGroupStateResponse.ZoneGroupState), &zoneGroupState)
if err != nil {
return nil, err
}
return &zoneGroupState, nil
}
func (z *ZonePlayer) GetVolume() (int, error) {
res, err := z.RenderingControl.GetVolume(z.HttpClient, &ren.GetVolumeArgs{Channel: "Master"})
if err != nil {
return 0, err
}
return int(res.CurrentVolume), err
}
func (z *ZonePlayer) SetVolume(desiredVolume int) error {
_, err := z.RenderingControl.SetVolume(z.HttpClient, &ren.SetVolumeArgs{
Channel: "Master",
DesiredVolume: uint16(desiredVolume),
})
return err
}
func (z *ZonePlayer) Play() error {
_, err := z.AVTransport.Play(z.HttpClient, &avt.PlayArgs{
Speed: "1.0",
})
return err
}
func (z *ZonePlayer) SetAVTransportURI(url string) error {
_, err := z.AVTransport.SetAVTransportURI(z.HttpClient, &avt.SetAVTransportURIArgs{
CurrentURI: url,
})
return err
}
-20
View File
@@ -79,9 +79,6 @@ github.com/hashicorp/mdns
# github.com/holoplot/go-evdev v0.0.0-20230626094006-70c9462cc0f2
## explicit; go 1.18
github.com/holoplot/go-evdev
# github.com/ianr0bkny/go-sonos v0.0.0-20171025003233-056585059953
## explicit
github.com/ianr0bkny/go-sonos/ssdp
# github.com/json-iterator/go v1.1.12
## explicit; go 1.12
github.com/json-iterator/go
@@ -217,23 +214,6 @@ github.com/pmezard/go-difflib/difflib
## explicit; go 1.20
github.com/stretchr/testify/assert
github.com/stretchr/testify/require
# github.com/szatmary/sonos v0.0.0-20191204204454-000c9219ff0e
## explicit
github.com/szatmary/sonos
github.com/szatmary/sonos/AVTransport
github.com/szatmary/sonos/AlarmClock
github.com/szatmary/sonos/ConnectionManager
github.com/szatmary/sonos/ContentDirectory
github.com/szatmary/sonos/DeviceProperties
github.com/szatmary/sonos/GroupManagement
github.com/szatmary/sonos/GroupRenderingControl
github.com/szatmary/sonos/MusicServices
github.com/szatmary/sonos/QPlay
github.com/szatmary/sonos/Queue
github.com/szatmary/sonos/RenderingControl
github.com/szatmary/sonos/SystemProperties
github.com/szatmary/sonos/VirtualLineIn
github.com/szatmary/sonos/ZoneGroupTopology
# github.com/tinyzimmer/go-glib v0.0.25
## explicit; go 1.16
github.com/tinyzimmer/go-glib/glib