21 Commits
Author SHA1 Message Date
cyrilix 11e9df2080 chore: upgrade dependencies 2024-07-31 19:06:38 +02:00
cyrilix 7a4ff9bdbd merge upstream and upgrade go to 1.21 2023-12-03 12:19:53 +01:00
cyrilix e42f04b51d Merge remote-tracking branch 'origin/main' into feat/openhome 2023-12-03 12:13:54 +01:00
Andrew DunhamandHuin 00783e79ec httpu: add context.Context and related interface
This adds a new interface for httpu that supports a Context, and uses
that context to set a deadline/timeout and also cancel the request if
the context is canceled. Additionally, add a new method to the SSDP
package that takes a ClientInterfaceCtx.

Updates #55

Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
2023-08-29 19:12:39 +01:00
jybpandHuin 8ca2329ddb Use errors.As in test 2023-05-10 17:07:24 +01:00
jybpandHuin c99b664f99 Fix test case 2023-05-10 17:07:24 +01:00
jybpandHuin dc178c5d44 Fix faultcode+faultstring and get UPnPError details 2023-05-10 17:07:24 +01:00
John Beisley 15a204aa25 chore: gofmt. 2023-03-09 18:23:30 +00:00
John Beisley e5bb4e5154 Include allowed string values in generated services. 2023-03-09 18:23:18 +00:00
John Beisley 1270e56d5f Fix error naming lint in srvdesc. 2023-03-09 17:08:45 +00:00
John Beisley 51ba21d432 Fix naming of soap/client.HTTPClient. 2023-03-09 16:35:15 +00:00
John Beisley fe0b17f589 Introduce SOAPError type. 2023-03-09 16:34:46 +00:00
John Beisley 8e5cccc9ac Fix trivial lints in goupnp2srvgen. 2023-03-09 15:42:29 +00:00
John Beisley d2cb593349 Include URL to upnpresources.zip in flag help. 2023-03-09 15:40:33 +00:00
Steve HellwegeandHuin 9278656124 Allow http.Client used in discovery to be modified (typically for security reasons)
[why]
The importing application may have some specific security requrirements that necessitate
a change to the http.Client or http.Transport used when fetching the xml from the UPnp server.
For example, the importing application may want to restrict localhost calls which could be
made by an attack server on the local network.

[how]
Create a global HTTPClient which defaults to http.DefaultClient.  This allows the importing
application to modify this global if it wishes to make changes to the http.Client/http.Transport
used when fetching the xml from the UPnP server.
2023-02-12 17:29:00 +00:00
Kz HoandHuin 62bd5c75d8 Add sync.Pool to reuse packet conn buf object 2023-01-18 08:53:09 +00:00
cyrilix 00a824fe48 feat: generate code for openhome 2022-11-01 20:03:30 +01:00
cyrilix 31f6bc38c2 build: upgrade to go 1.19 2022-11-01 20:02:47 +01:00
cyrilix 1a2c6ad5b2 refactor: rename go module 2022-11-01 20:02:13 +01:00
hzyandHuin d8bd5d2d52 More functions support Context 2022-10-02 14:55:49 +01:00
jgouldandHuin 9723a59812 adding ModelType to Device 2022-08-11 22:53:45 +01:00
69 changed files with 17055 additions and 566 deletions
+2 -2
View File
@@ -5,8 +5,8 @@ import (
"fmt"
"log"
"github.com/huin/goupnp"
"github.com/huin/goupnp/ssdp"
"git.cyrilix.bzh/cyrilix/goupnp"
"git.cyrilix.bzh/cyrilix/goupnp/ssdp"
)
func main() {
@@ -4,7 +4,7 @@ import (
"log"
"net/http"
"github.com/huin/goupnp/httpu"
"git.cyrilix.bzh/cyrilix/goupnp/httpu"
)
func main() {
@@ -4,7 +4,7 @@ import (
"fmt"
"log"
"github.com/huin/goupnp/dcps/internetgateway1"
"git.cyrilix.bzh/cyrilix/goupnp/dcps/internetgateway1"
)
func main() {
@@ -3,7 +3,7 @@ package main
import (
"log"
"github.com/huin/goupnp/ssdp"
"git.cyrilix.bzh/cyrilix/goupnp/ssdp"
)
func main() {
+5 -5
View File
@@ -9,9 +9,9 @@ import (
"strings"
"text/template"
"github.com/huin/goupnp"
"github.com/huin/goupnp/scpd"
"github.com/huin/goupnp/soap"
"git.cyrilix.bzh/cyrilix/goupnp"
"git.cyrilix.bzh/cyrilix/goupnp/scpd"
"git.cyrilix.bzh/cyrilix/goupnp/soap"
)
// DCP collects together information about a UPnP Device Control Protocol.
@@ -78,7 +78,7 @@ func (dcp *DCP) processDeviceFile(file *zip.File) error {
}
})
device.VisitServices(func(s *goupnp.Service) {
u, err := extractURNParts(s.ServiceType, serviceURNPrefix)
u, err := extractURNParts(s.ServiceType, dcp.Metadata.ServiceURNPrefix)
if err != nil {
mainErr = err
}
@@ -133,7 +133,7 @@ func (dcp *DCP) processSCPDFile(file *zip.File) error {
return fmt.Errorf("error decoding SCPD XML from file %q: %v", file.Name, err)
}
scpd.Clean()
urnParts, err := urnPartsFromSCPDFilename(file.Name)
urnParts, err := urnPartsFromSCPDFilename(file.Name, dcp.Metadata.ServiceURNPrefix)
if err != nil {
return fmt.Errorf("could not recognize SCPD filename %q: %v", file.Name, err)
}
+2 -2
View File
@@ -80,14 +80,14 @@ func unmarshalXmlFile(file *zip.File, data interface{}) error {
var scpdFilenameRe = regexp.MustCompile(
`.*/([a-zA-Z0-9]+)([0-9]+)\.xml`)
func urnPartsFromSCPDFilename(filename string) (*URNParts, error) {
func urnPartsFromSCPDFilename(filename string, svcURNPrefix string) (*URNParts, error) {
parts := scpdFilenameRe.FindStringSubmatch(filename)
if len(parts) != 3 {
return nil, fmt.Errorf("SCPD filename %q does not have expected number of parts", filename)
}
name, version := parts[1], parts[2]
return &URNParts{
URN: serviceURNPrefix + name + ":" + version,
URN: svcURNPrefix + name + ":" + version,
Name: name,
Version: version,
}, nil
+44 -1
View File
@@ -9,12 +9,51 @@ type DCPMetadata struct {
Name string // What to name the Go DCP package.
OfficialName string // Official name for the DCP.
Src dcpProvider
ServiceURNPrefix string
}
var dcpMetadata = []DCPMetadata{
{
Name: "openhome",
OfficialName: "OpenHome",
ServiceURNPrefix: "urn:av-openhome-org:service:",
Src: upnpdotorg{
DocURL: "http://wiki.openhome.org/wiki/Av:Developer",
XMLSpecURL: "https://github.com/openhome/ohNetGenerated/archive/refs/heads/master.zip",
Hacks: []DCPHackFn{
fixMissingURN(
"urn:av-openhome-org:service:Credentials:1",
"urn:av-openhome-org:service:Debug:1",
"urn:av-openhome-org:service:Exakt:1",
"urn:av-openhome-org:service:Exakt:2",
"urn:av-openhome-org:service:Exakt:3",
"urn:av-openhome-org:service:Info:1",
"urn:av-openhome-org:service:MediaServer:1",
"urn:av-openhome-org:service:NetworkMonitor:1",
"urn:av-openhome-org:service:Pins:1",
"urn:av-openhome-org:service:Playlist:1",
"urn:av-openhome-org:service:PlaylistManager:1",
"urn:av-openhome-org:service:Product:1",
"urn:av-openhome-org:service:Product:2",
"urn:av-openhome-org:service:Radio:1",
"urn:av-openhome-org:service:Receiver:1",
"urn:av-openhome-org:service:Sender:1",
"urn:av-openhome-org:service:Sender:2",
"urn:av-openhome-org:service:SubscriptionLongPoll:1",
"urn:av-openhome-org:service:Time:1",
"urn:av-openhome-org:service:Transport:1",
"urn:av-openhome-org:service:Volume:1",
"urn:av-openhome-org:service:Volume:2",
"urn:av-openhome-org:service:Volume:3",
),
},
},
},
{
Name: "internetgateway1",
OfficialName: "Internet Gateway Device v1",
ServiceURNPrefix: serviceURNPrefix,
Src: upnpdotorg{
DocURL: "http://upnp.org/specs/gw/UPnP-gw-InternetGatewayDevice-v1-Device.pdf",
XMLSpecURL: "http://upnp.org/specs/gw/UPnP-gw-IGD-TestFiles-20010921.zip",
@@ -26,6 +65,7 @@ var dcpMetadata = []DCPMetadata{
{
Name: "internetgateway2",
OfficialName: "Internet Gateway Device v2",
ServiceURNPrefix: serviceURNPrefix,
Src: upnpdotorg{
DocURL: "http://upnp.org/specs/gw/UPnP-gw-InternetGatewayDevice-v2-Device.pdf",
XMLSpecURL: "http://upnp.org/specs/gw/UPnP-gw-IGD-Testfiles-20110224.zip",
@@ -38,6 +78,7 @@ var dcpMetadata = []DCPMetadata{
{
Name: "av1",
OfficialName: "MediaServer v1 and MediaRenderer v1",
ServiceURNPrefix: serviceURNPrefix,
Src: upnpdotorg{
DocURL: "http://upnp.org/specs/av/av1/",
XMLSpecURL: "http://upnp.org/specs/av/UPnP-av-TestFiles-20070927.zip",
@@ -46,6 +87,7 @@ var dcpMetadata = []DCPMetadata{
{
Name: "ocf/internetgateway1",
OfficialName: "Internet Gateway Device v1 - Open Connectivity Foundation",
ServiceURNPrefix: serviceURNPrefix,
Src: openconnectivitydotorg{
SpecsURL: ocfSpecsURL,
DocPath: "*/DeviceProtection_1/UPnP-gw-*v1*.pdf",
@@ -62,6 +104,7 @@ var dcpMetadata = []DCPMetadata{
{
Name: "ocf/internetgateway2",
OfficialName: "Internet Gateway Device v2 - Open Connectivity Foundation",
ServiceURNPrefix: serviceURNPrefix,
Src: openconnectivitydotorg{
SpecsURL: ocfSpecsURL,
DocPath: "*/Internet Gateway_2/UPnP-gw-*.pdf",
@@ -114,7 +157,7 @@ func fixMissingURN(missingURNs ...string) func(dcp *DCP) error {
if _, ok := dcp.ServiceTypes[missingURN]; ok {
continue
}
urnParts, err := extractURNParts(missingURN, serviceURNPrefix)
urnParts, err := extractURNParts(missingURN, dcp.Metadata.ServiceURNPrefix)
if err != nil {
return err
}
+200 -108
View File
@@ -15,8 +15,8 @@ import (
"net/url"
"time"
"github.com/huin/goupnp"
"github.com/huin/goupnp/soap"
"git.cyrilix.bzh/cyrilix/goupnp"
"git.cyrilix.bzh/cyrilix/goupnp/soap"
)
// Hack to avoid Go complaining if time isn't used.
@@ -47,35 +47,47 @@ type AVTransport1 struct {
goupnp.ServiceClient
}
// NewAVTransport1Clients discovers instances of the service on the network,
// NewAVTransport1ClientsCtx discovers instances of the service on the network,
// and returns clients to any that are found. errors will contain an error for
// any devices that replied but which could not be queried, and err will be set
// if the discovery process failed outright.
//
// This is a typical entry calling point into this package.
func NewAVTransport1Clients() (clients []*AVTransport1, errors []error, err error) {
func NewAVTransport1ClientsCtx(ctx context.Context) (clients []*AVTransport1, errors []error, err error) {
var genericClients []goupnp.ServiceClient
if genericClients, errors, err = goupnp.NewServiceClients(URN_AVTransport_1); err != nil {
if genericClients, errors, err = goupnp.NewServiceClientsCtx(ctx, URN_AVTransport_1); err != nil {
return
}
clients = newAVTransport1ClientsFromGenericClients(genericClients)
return
}
// NewAVTransport1ClientsByURL discovers instances of the service at the given
// NewAVTransport1Clients is the legacy version of NewAVTransport1ClientsCtx, but uses
// context.Background() as the context.
func NewAVTransport1Clients() (clients []*AVTransport1, errors []error, err error) {
return NewAVTransport1ClientsCtx(context.Background())
}
// NewAVTransport1ClientsByURLCtx discovers instances of the service at the given
// URL, and returns clients to any that are found. An error is returned if
// there was an error probing the service.
//
// This is a typical entry calling point into this package when reusing an
// previously discovered service URL.
func NewAVTransport1ClientsByURL(loc *url.URL) ([]*AVTransport1, error) {
genericClients, err := goupnp.NewServiceClientsByURL(loc, URN_AVTransport_1)
func NewAVTransport1ClientsByURLCtx(ctx context.Context, loc *url.URL) ([]*AVTransport1, error) {
genericClients, err := goupnp.NewServiceClientsByURLCtx(ctx, loc, URN_AVTransport_1)
if err != nil {
return nil, err
}
return newAVTransport1ClientsFromGenericClients(genericClients), nil
}
// NewAVTransport1ClientsByURL is the legacy version of NewAVTransport1ClientsByURLCtx, but uses
// context.Background() as the context.
func NewAVTransport1ClientsByURL(loc *url.URL) ([]*AVTransport1, error) {
return NewAVTransport1ClientsByURLCtx(context.Background(), loc)
}
// NewAVTransport1ClientsFromRootDevice discovers instances of the service in
// a given root device, and returns clients to any that are found. An error is
// returned if there was not at least one instance of the service within the
@@ -192,7 +204,6 @@ func (client *AVTransport1) GetDeviceCapabilities(InstanceID uint32) (PlayMedia
)
}
//
// Return values:
//
// * NrTracks: allowed value range: minimum=0
@@ -270,7 +281,6 @@ func (client *AVTransport1) GetMediaInfo(InstanceID uint32) (NrTracks uint32, Me
)
}
//
// Return values:
//
// * Track: allowed value range: minimum=0, step=1
@@ -344,7 +354,6 @@ func (client *AVTransport1) GetPositionInfo(InstanceID uint32) (Track uint32, Tr
)
}
//
// Return values:
//
// * CurrentTransportState: allowed values: STOPPED, PLAYING
@@ -402,7 +411,6 @@ func (client *AVTransport1) GetTransportInfo(InstanceID uint32) (CurrentTranspor
)
}
//
// Return values:
//
// * PlayMode: allowed values: NORMAL
@@ -935,35 +943,47 @@ type AVTransport2 struct {
goupnp.ServiceClient
}
// NewAVTransport2Clients discovers instances of the service on the network,
// NewAVTransport2ClientsCtx discovers instances of the service on the network,
// and returns clients to any that are found. errors will contain an error for
// any devices that replied but which could not be queried, and err will be set
// if the discovery process failed outright.
//
// This is a typical entry calling point into this package.
func NewAVTransport2Clients() (clients []*AVTransport2, errors []error, err error) {
func NewAVTransport2ClientsCtx(ctx context.Context) (clients []*AVTransport2, errors []error, err error) {
var genericClients []goupnp.ServiceClient
if genericClients, errors, err = goupnp.NewServiceClients(URN_AVTransport_2); err != nil {
if genericClients, errors, err = goupnp.NewServiceClientsCtx(ctx, URN_AVTransport_2); err != nil {
return
}
clients = newAVTransport2ClientsFromGenericClients(genericClients)
return
}
// NewAVTransport2ClientsByURL discovers instances of the service at the given
// NewAVTransport2Clients is the legacy version of NewAVTransport2ClientsCtx, but uses
// context.Background() as the context.
func NewAVTransport2Clients() (clients []*AVTransport2, errors []error, err error) {
return NewAVTransport2ClientsCtx(context.Background())
}
// NewAVTransport2ClientsByURLCtx discovers instances of the service at the given
// URL, and returns clients to any that are found. An error is returned if
// there was an error probing the service.
//
// This is a typical entry calling point into this package when reusing an
// previously discovered service URL.
func NewAVTransport2ClientsByURL(loc *url.URL) ([]*AVTransport2, error) {
genericClients, err := goupnp.NewServiceClientsByURL(loc, URN_AVTransport_2)
func NewAVTransport2ClientsByURLCtx(ctx context.Context, loc *url.URL) ([]*AVTransport2, error) {
genericClients, err := goupnp.NewServiceClientsByURLCtx(ctx, loc, URN_AVTransport_2)
if err != nil {
return nil, err
}
return newAVTransport2ClientsFromGenericClients(genericClients), nil
}
// NewAVTransport2ClientsByURL is the legacy version of NewAVTransport2ClientsByURLCtx, but uses
// context.Background() as the context.
func NewAVTransport2ClientsByURL(loc *url.URL) ([]*AVTransport2, error) {
return NewAVTransport2ClientsByURLCtx(context.Background(), loc)
}
// NewAVTransport2ClientsFromRootDevice discovers instances of the service in
// a given root device, and returns clients to any that are found. An error is
// returned if there was not at least one instance of the service within the
@@ -1030,7 +1050,6 @@ func (client *AVTransport2) GetCurrentTransportActions(InstanceID uint32) (Actio
)
}
//
// Return values:
//
// * CurrentDRMState: allowed values: OK
@@ -1126,7 +1145,6 @@ func (client *AVTransport2) GetDeviceCapabilities(InstanceID uint32) (PlayMedia
)
}
//
// Return values:
//
// * NrTracks: allowed value range: minimum=0
@@ -1204,7 +1222,6 @@ func (client *AVTransport2) GetMediaInfo(InstanceID uint32) (NrTracks uint32, Me
)
}
//
// Return values:
//
// * CurrentType: allowed values: NO_MEDIA, TRACK_AWARE, TRACK_UNAWARE
@@ -1288,7 +1305,6 @@ func (client *AVTransport2) GetMediaInfo_Ext(InstanceID uint32) (CurrentType str
)
}
//
// Return values:
//
// * Track: allowed value range: minimum=0, step=1
@@ -1410,7 +1426,6 @@ func (client *AVTransport2) GetStateVariables(InstanceID uint32, StateVariableLi
)
}
//
// Return values:
//
// * CurrentTransportState: allowed values: STOPPED, PLAYING
@@ -1468,7 +1483,6 @@ func (client *AVTransport2) GetTransportInfo(InstanceID uint32) (CurrentTranspor
)
}
//
// Return values:
//
// * PlayMode: allowed values: NORMAL
@@ -2067,35 +2081,47 @@ type ConnectionManager1 struct {
goupnp.ServiceClient
}
// NewConnectionManager1Clients discovers instances of the service on the network,
// NewConnectionManager1ClientsCtx discovers instances of the service on the network,
// and returns clients to any that are found. errors will contain an error for
// any devices that replied but which could not be queried, and err will be set
// if the discovery process failed outright.
//
// This is a typical entry calling point into this package.
func NewConnectionManager1Clients() (clients []*ConnectionManager1, errors []error, err error) {
func NewConnectionManager1ClientsCtx(ctx context.Context) (clients []*ConnectionManager1, errors []error, err error) {
var genericClients []goupnp.ServiceClient
if genericClients, errors, err = goupnp.NewServiceClients(URN_ConnectionManager_1); err != nil {
if genericClients, errors, err = goupnp.NewServiceClientsCtx(ctx, URN_ConnectionManager_1); err != nil {
return
}
clients = newConnectionManager1ClientsFromGenericClients(genericClients)
return
}
// NewConnectionManager1ClientsByURL discovers instances of the service at the given
// NewConnectionManager1Clients is the legacy version of NewConnectionManager1ClientsCtx, but uses
// context.Background() as the context.
func NewConnectionManager1Clients() (clients []*ConnectionManager1, errors []error, err error) {
return NewConnectionManager1ClientsCtx(context.Background())
}
// NewConnectionManager1ClientsByURLCtx discovers instances of the service at the given
// URL, and returns clients to any that are found. An error is returned if
// there was an error probing the service.
//
// This is a typical entry calling point into this package when reusing an
// previously discovered service URL.
func NewConnectionManager1ClientsByURL(loc *url.URL) ([]*ConnectionManager1, error) {
genericClients, err := goupnp.NewServiceClientsByURL(loc, URN_ConnectionManager_1)
func NewConnectionManager1ClientsByURLCtx(ctx context.Context, loc *url.URL) ([]*ConnectionManager1, error) {
genericClients, err := goupnp.NewServiceClientsByURLCtx(ctx, loc, URN_ConnectionManager_1)
if err != nil {
return nil, err
}
return newConnectionManager1ClientsFromGenericClients(genericClients), nil
}
// NewConnectionManager1ClientsByURL is the legacy version of NewConnectionManager1ClientsByURLCtx, but uses
// context.Background() as the context.
func NewConnectionManager1ClientsByURL(loc *url.URL) ([]*ConnectionManager1, error) {
return NewConnectionManager1ClientsByURLCtx(context.Background(), loc)
}
// NewConnectionManager1ClientsFromRootDevice discovers instances of the service in
// a given root device, and returns clients to any that are found. An error is
// returned if there was not at least one instance of the service within the
@@ -2191,7 +2217,6 @@ func (client *ConnectionManager1) GetCurrentConnectionIDs() (ConnectionIDs strin
return client.GetCurrentConnectionIDsCtx(context.Background())
}
//
// Return values:
//
// * Direction: allowed values: Input, Output
@@ -2381,35 +2406,47 @@ type ConnectionManager2 struct {
goupnp.ServiceClient
}
// NewConnectionManager2Clients discovers instances of the service on the network,
// NewConnectionManager2ClientsCtx discovers instances of the service on the network,
// and returns clients to any that are found. errors will contain an error for
// any devices that replied but which could not be queried, and err will be set
// if the discovery process failed outright.
//
// This is a typical entry calling point into this package.
func NewConnectionManager2Clients() (clients []*ConnectionManager2, errors []error, err error) {
func NewConnectionManager2ClientsCtx(ctx context.Context) (clients []*ConnectionManager2, errors []error, err error) {
var genericClients []goupnp.ServiceClient
if genericClients, errors, err = goupnp.NewServiceClients(URN_ConnectionManager_2); err != nil {
if genericClients, errors, err = goupnp.NewServiceClientsCtx(ctx, URN_ConnectionManager_2); err != nil {
return
}
clients = newConnectionManager2ClientsFromGenericClients(genericClients)
return
}
// NewConnectionManager2ClientsByURL discovers instances of the service at the given
// NewConnectionManager2Clients is the legacy version of NewConnectionManager2ClientsCtx, but uses
// context.Background() as the context.
func NewConnectionManager2Clients() (clients []*ConnectionManager2, errors []error, err error) {
return NewConnectionManager2ClientsCtx(context.Background())
}
// NewConnectionManager2ClientsByURLCtx discovers instances of the service at the given
// URL, and returns clients to any that are found. An error is returned if
// there was an error probing the service.
//
// This is a typical entry calling point into this package when reusing an
// previously discovered service URL.
func NewConnectionManager2ClientsByURL(loc *url.URL) ([]*ConnectionManager2, error) {
genericClients, err := goupnp.NewServiceClientsByURL(loc, URN_ConnectionManager_2)
func NewConnectionManager2ClientsByURLCtx(ctx context.Context, loc *url.URL) ([]*ConnectionManager2, error) {
genericClients, err := goupnp.NewServiceClientsByURLCtx(ctx, loc, URN_ConnectionManager_2)
if err != nil {
return nil, err
}
return newConnectionManager2ClientsFromGenericClients(genericClients), nil
}
// NewConnectionManager2ClientsByURL is the legacy version of NewConnectionManager2ClientsByURLCtx, but uses
// context.Background() as the context.
func NewConnectionManager2ClientsByURL(loc *url.URL) ([]*ConnectionManager2, error) {
return NewConnectionManager2ClientsByURLCtx(context.Background(), loc)
}
// NewConnectionManager2ClientsFromRootDevice discovers instances of the service in
// a given root device, and returns clients to any that are found. An error is
// returned if there was not at least one instance of the service within the
@@ -2505,7 +2542,6 @@ func (client *ConnectionManager2) GetCurrentConnectionIDs() (ConnectionIDs strin
return client.GetCurrentConnectionIDsCtx(context.Background())
}
//
// Return values:
//
// * Direction: allowed values: Input, Output
@@ -2695,35 +2731,47 @@ type ContentDirectory1 struct {
goupnp.ServiceClient
}
// NewContentDirectory1Clients discovers instances of the service on the network,
// NewContentDirectory1ClientsCtx discovers instances of the service on the network,
// and returns clients to any that are found. errors will contain an error for
// any devices that replied but which could not be queried, and err will be set
// if the discovery process failed outright.
//
// This is a typical entry calling point into this package.
func NewContentDirectory1Clients() (clients []*ContentDirectory1, errors []error, err error) {
func NewContentDirectory1ClientsCtx(ctx context.Context) (clients []*ContentDirectory1, errors []error, err error) {
var genericClients []goupnp.ServiceClient
if genericClients, errors, err = goupnp.NewServiceClients(URN_ContentDirectory_1); err != nil {
if genericClients, errors, err = goupnp.NewServiceClientsCtx(ctx, URN_ContentDirectory_1); err != nil {
return
}
clients = newContentDirectory1ClientsFromGenericClients(genericClients)
return
}
// NewContentDirectory1ClientsByURL discovers instances of the service at the given
// NewContentDirectory1Clients is the legacy version of NewContentDirectory1ClientsCtx, but uses
// context.Background() as the context.
func NewContentDirectory1Clients() (clients []*ContentDirectory1, errors []error, err error) {
return NewContentDirectory1ClientsCtx(context.Background())
}
// NewContentDirectory1ClientsByURLCtx discovers instances of the service at the given
// URL, and returns clients to any that are found. An error is returned if
// there was an error probing the service.
//
// This is a typical entry calling point into this package when reusing an
// previously discovered service URL.
func NewContentDirectory1ClientsByURL(loc *url.URL) ([]*ContentDirectory1, error) {
genericClients, err := goupnp.NewServiceClientsByURL(loc, URN_ContentDirectory_1)
func NewContentDirectory1ClientsByURLCtx(ctx context.Context, loc *url.URL) ([]*ContentDirectory1, error) {
genericClients, err := goupnp.NewServiceClientsByURLCtx(ctx, loc, URN_ContentDirectory_1)
if err != nil {
return nil, err
}
return newContentDirectory1ClientsFromGenericClients(genericClients), nil
}
// NewContentDirectory1ClientsByURL is the legacy version of NewContentDirectory1ClientsByURLCtx, but uses
// context.Background() as the context.
func NewContentDirectory1ClientsByURL(loc *url.URL) ([]*ContentDirectory1, error) {
return NewContentDirectory1ClientsByURLCtx(context.Background(), loc)
}
// NewContentDirectory1ClientsFromRootDevice discovers instances of the service in
// a given root device, and returns clients to any that are found. An error is
// returned if there was not at least one instance of the service within the
@@ -3161,7 +3209,6 @@ func (client *ContentDirectory1) GetSystemUpdateID() (Id uint32, err error) {
return client.GetSystemUpdateIDCtx(context.Background())
}
//
// Return values:
//
// * TransferStatus: allowed values: COMPLETED, ERROR, IN_PROGRESS, STOPPED
@@ -3440,35 +3487,47 @@ type ContentDirectory2 struct {
goupnp.ServiceClient
}
// NewContentDirectory2Clients discovers instances of the service on the network,
// NewContentDirectory2ClientsCtx discovers instances of the service on the network,
// and returns clients to any that are found. errors will contain an error for
// any devices that replied but which could not be queried, and err will be set
// if the discovery process failed outright.
//
// This is a typical entry calling point into this package.
func NewContentDirectory2Clients() (clients []*ContentDirectory2, errors []error, err error) {
func NewContentDirectory2ClientsCtx(ctx context.Context) (clients []*ContentDirectory2, errors []error, err error) {
var genericClients []goupnp.ServiceClient
if genericClients, errors, err = goupnp.NewServiceClients(URN_ContentDirectory_2); err != nil {
if genericClients, errors, err = goupnp.NewServiceClientsCtx(ctx, URN_ContentDirectory_2); err != nil {
return
}
clients = newContentDirectory2ClientsFromGenericClients(genericClients)
return
}
// NewContentDirectory2ClientsByURL discovers instances of the service at the given
// NewContentDirectory2Clients is the legacy version of NewContentDirectory2ClientsCtx, but uses
// context.Background() as the context.
func NewContentDirectory2Clients() (clients []*ContentDirectory2, errors []error, err error) {
return NewContentDirectory2ClientsCtx(context.Background())
}
// NewContentDirectory2ClientsByURLCtx discovers instances of the service at the given
// URL, and returns clients to any that are found. An error is returned if
// there was an error probing the service.
//
// This is a typical entry calling point into this package when reusing an
// previously discovered service URL.
func NewContentDirectory2ClientsByURL(loc *url.URL) ([]*ContentDirectory2, error) {
genericClients, err := goupnp.NewServiceClientsByURL(loc, URN_ContentDirectory_2)
func NewContentDirectory2ClientsByURLCtx(ctx context.Context, loc *url.URL) ([]*ContentDirectory2, error) {
genericClients, err := goupnp.NewServiceClientsByURLCtx(ctx, loc, URN_ContentDirectory_2)
if err != nil {
return nil, err
}
return newContentDirectory2ClientsFromGenericClients(genericClients), nil
}
// NewContentDirectory2ClientsByURL is the legacy version of NewContentDirectory2ClientsByURLCtx, but uses
// context.Background() as the context.
func NewContentDirectory2ClientsByURL(loc *url.URL) ([]*ContentDirectory2, error) {
return NewContentDirectory2ClientsByURLCtx(context.Background(), loc)
}
// NewContentDirectory2ClientsFromRootDevice discovers instances of the service in
// a given root device, and returns clients to any that are found. An error is
// returned if there was not at least one instance of the service within the
@@ -3974,7 +4033,6 @@ func (client *ContentDirectory2) GetSystemUpdateID() (Id uint32, err error) {
return client.GetSystemUpdateIDCtx(context.Background())
}
//
// Return values:
//
// * TransferStatus: allowed values: COMPLETED, ERROR, IN_PROGRESS, STOPPED
@@ -4301,35 +4359,47 @@ type ContentDirectory3 struct {
goupnp.ServiceClient
}
// NewContentDirectory3Clients discovers instances of the service on the network,
// NewContentDirectory3ClientsCtx discovers instances of the service on the network,
// and returns clients to any that are found. errors will contain an error for
// any devices that replied but which could not be queried, and err will be set
// if the discovery process failed outright.
//
// This is a typical entry calling point into this package.
func NewContentDirectory3Clients() (clients []*ContentDirectory3, errors []error, err error) {
func NewContentDirectory3ClientsCtx(ctx context.Context) (clients []*ContentDirectory3, errors []error, err error) {
var genericClients []goupnp.ServiceClient
if genericClients, errors, err = goupnp.NewServiceClients(URN_ContentDirectory_3); err != nil {
if genericClients, errors, err = goupnp.NewServiceClientsCtx(ctx, URN_ContentDirectory_3); err != nil {
return
}
clients = newContentDirectory3ClientsFromGenericClients(genericClients)
return
}
// NewContentDirectory3ClientsByURL discovers instances of the service at the given
// NewContentDirectory3Clients is the legacy version of NewContentDirectory3ClientsCtx, but uses
// context.Background() as the context.
func NewContentDirectory3Clients() (clients []*ContentDirectory3, errors []error, err error) {
return NewContentDirectory3ClientsCtx(context.Background())
}
// NewContentDirectory3ClientsByURLCtx discovers instances of the service at the given
// URL, and returns clients to any that are found. An error is returned if
// there was an error probing the service.
//
// This is a typical entry calling point into this package when reusing an
// previously discovered service URL.
func NewContentDirectory3ClientsByURL(loc *url.URL) ([]*ContentDirectory3, error) {
genericClients, err := goupnp.NewServiceClientsByURL(loc, URN_ContentDirectory_3)
func NewContentDirectory3ClientsByURLCtx(ctx context.Context, loc *url.URL) ([]*ContentDirectory3, error) {
genericClients, err := goupnp.NewServiceClientsByURLCtx(ctx, loc, URN_ContentDirectory_3)
if err != nil {
return nil, err
}
return newContentDirectory3ClientsFromGenericClients(genericClients), nil
}
// NewContentDirectory3ClientsByURL is the legacy version of NewContentDirectory3ClientsByURLCtx, but uses
// context.Background() as the context.
func NewContentDirectory3ClientsByURL(loc *url.URL) ([]*ContentDirectory3, error) {
return NewContentDirectory3ClientsByURLCtx(context.Background(), loc)
}
// NewContentDirectory3ClientsFromRootDevice discovers instances of the service in
// a given root device, and returns clients to any that are found. An error is
// returned if there was not at least one instance of the service within the
@@ -4961,7 +5031,6 @@ func (client *ContentDirectory3) GetSystemUpdateID() (Id uint32, err error) {
return client.GetSystemUpdateIDCtx(context.Background())
}
//
// Return values:
//
// * TransferStatus: allowed values: COMPLETED, ERROR, IN_PROGRESS, STOPPED
@@ -5288,35 +5357,47 @@ type RenderingControl1 struct {
goupnp.ServiceClient
}
// NewRenderingControl1Clients discovers instances of the service on the network,
// NewRenderingControl1ClientsCtx discovers instances of the service on the network,
// and returns clients to any that are found. errors will contain an error for
// any devices that replied but which could not be queried, and err will be set
// if the discovery process failed outright.
//
// This is a typical entry calling point into this package.
func NewRenderingControl1Clients() (clients []*RenderingControl1, errors []error, err error) {
func NewRenderingControl1ClientsCtx(ctx context.Context) (clients []*RenderingControl1, errors []error, err error) {
var genericClients []goupnp.ServiceClient
if genericClients, errors, err = goupnp.NewServiceClients(URN_RenderingControl_1); err != nil {
if genericClients, errors, err = goupnp.NewServiceClientsCtx(ctx, URN_RenderingControl_1); err != nil {
return
}
clients = newRenderingControl1ClientsFromGenericClients(genericClients)
return
}
// NewRenderingControl1ClientsByURL discovers instances of the service at the given
// NewRenderingControl1Clients is the legacy version of NewRenderingControl1ClientsCtx, but uses
// context.Background() as the context.
func NewRenderingControl1Clients() (clients []*RenderingControl1, errors []error, err error) {
return NewRenderingControl1ClientsCtx(context.Background())
}
// NewRenderingControl1ClientsByURLCtx discovers instances of the service at the given
// URL, and returns clients to any that are found. An error is returned if
// there was an error probing the service.
//
// This is a typical entry calling point into this package when reusing an
// previously discovered service URL.
func NewRenderingControl1ClientsByURL(loc *url.URL) ([]*RenderingControl1, error) {
genericClients, err := goupnp.NewServiceClientsByURL(loc, URN_RenderingControl_1)
func NewRenderingControl1ClientsByURLCtx(ctx context.Context, loc *url.URL) ([]*RenderingControl1, error) {
genericClients, err := goupnp.NewServiceClientsByURLCtx(ctx, loc, URN_RenderingControl_1)
if err != nil {
return nil, err
}
return newRenderingControl1ClientsFromGenericClients(genericClients), nil
}
// NewRenderingControl1ClientsByURL is the legacy version of NewRenderingControl1ClientsByURLCtx, but uses
// context.Background() as the context.
func NewRenderingControl1ClientsByURL(loc *url.URL) ([]*RenderingControl1, error) {
return NewRenderingControl1ClientsByURLCtx(context.Background(), loc)
}
// NewRenderingControl1ClientsFromRootDevice discovers instances of the service in
// a given root device, and returns clients to any that are found. An error is
// returned if there was not at least one instance of the service within the
@@ -5341,7 +5422,6 @@ func newRenderingControl1ClientsFromGenericClients(genericClients []goupnp.Servi
return clients
}
//
// Return values:
//
// * CurrentBlueVideoBlackLevel: allowed value range: minimum=0, step=1
@@ -5387,7 +5467,6 @@ func (client *RenderingControl1) GetBlueVideoBlackLevel(InstanceID uint32) (Curr
)
}
//
// Return values:
//
// * CurrentBlueVideoGain: allowed value range: minimum=0, step=1
@@ -5433,7 +5512,6 @@ func (client *RenderingControl1) GetBlueVideoGain(InstanceID uint32) (CurrentBlu
)
}
//
// Return values:
//
// * CurrentBrightness: allowed value range: minimum=0, step=1
@@ -5479,7 +5557,6 @@ func (client *RenderingControl1) GetBrightness(InstanceID uint32) (CurrentBright
)
}
//
// Return values:
//
// * CurrentColorTemperature: allowed value range: minimum=0, step=1
@@ -5525,7 +5602,6 @@ func (client *RenderingControl1) GetColorTemperature(InstanceID uint32) (Current
)
}
//
// Return values:
//
// * CurrentContrast: allowed value range: minimum=0, step=1
@@ -5571,7 +5647,6 @@ func (client *RenderingControl1) GetContrast(InstanceID uint32) (CurrentContrast
)
}
//
// Return values:
//
// * CurrentGreenVideoBlackLevel: allowed value range: minimum=0, step=1
@@ -5617,7 +5692,6 @@ func (client *RenderingControl1) GetGreenVideoBlackLevel(InstanceID uint32) (Cur
)
}
//
// Return values:
//
// * CurrentGreenVideoGain: allowed value range: minimum=0, step=1
@@ -5663,7 +5737,6 @@ func (client *RenderingControl1) GetGreenVideoGain(InstanceID uint32) (CurrentGr
)
}
//
// Return values:
//
// * CurrentHorizontalKeystone: allowed value range: step=1
@@ -5815,7 +5888,6 @@ func (client *RenderingControl1) GetMute(InstanceID uint32, Channel string) (Cur
)
}
//
// Return values:
//
// * CurrentRedVideoBlackLevel: allowed value range: minimum=0, step=1
@@ -5903,7 +5975,6 @@ func (client *RenderingControl1) GetRedVideoGain(InstanceID uint32) (CurrentRedV
)
}
//
// Return values:
//
// * CurrentSharpness: allowed value range: minimum=0, step=1
@@ -5949,7 +6020,6 @@ func (client *RenderingControl1) GetSharpness(InstanceID uint32) (CurrentSharpne
)
}
//
// Return values:
//
// * CurrentVerticalKeystone: allowed value range: step=1
@@ -6000,7 +6070,6 @@ func (client *RenderingControl1) GetVerticalKeystone(InstanceID uint32) (Current
//
// * Channel: allowed values: Master
//
// Return values:
//
// * CurrentVolume: allowed value range: minimum=0, step=1
@@ -7048,35 +7117,47 @@ type RenderingControl2 struct {
goupnp.ServiceClient
}
// NewRenderingControl2Clients discovers instances of the service on the network,
// NewRenderingControl2ClientsCtx discovers instances of the service on the network,
// and returns clients to any that are found. errors will contain an error for
// any devices that replied but which could not be queried, and err will be set
// if the discovery process failed outright.
//
// This is a typical entry calling point into this package.
func NewRenderingControl2Clients() (clients []*RenderingControl2, errors []error, err error) {
func NewRenderingControl2ClientsCtx(ctx context.Context) (clients []*RenderingControl2, errors []error, err error) {
var genericClients []goupnp.ServiceClient
if genericClients, errors, err = goupnp.NewServiceClients(URN_RenderingControl_2); err != nil {
if genericClients, errors, err = goupnp.NewServiceClientsCtx(ctx, URN_RenderingControl_2); err != nil {
return
}
clients = newRenderingControl2ClientsFromGenericClients(genericClients)
return
}
// NewRenderingControl2ClientsByURL discovers instances of the service at the given
// NewRenderingControl2Clients is the legacy version of NewRenderingControl2ClientsCtx, but uses
// context.Background() as the context.
func NewRenderingControl2Clients() (clients []*RenderingControl2, errors []error, err error) {
return NewRenderingControl2ClientsCtx(context.Background())
}
// NewRenderingControl2ClientsByURLCtx discovers instances of the service at the given
// URL, and returns clients to any that are found. An error is returned if
// there was an error probing the service.
//
// This is a typical entry calling point into this package when reusing an
// previously discovered service URL.
func NewRenderingControl2ClientsByURL(loc *url.URL) ([]*RenderingControl2, error) {
genericClients, err := goupnp.NewServiceClientsByURL(loc, URN_RenderingControl_2)
func NewRenderingControl2ClientsByURLCtx(ctx context.Context, loc *url.URL) ([]*RenderingControl2, error) {
genericClients, err := goupnp.NewServiceClientsByURLCtx(ctx, loc, URN_RenderingControl_2)
if err != nil {
return nil, err
}
return newRenderingControl2ClientsFromGenericClients(genericClients), nil
}
// NewRenderingControl2ClientsByURL is the legacy version of NewRenderingControl2ClientsByURLCtx, but uses
// context.Background() as the context.
func NewRenderingControl2ClientsByURL(loc *url.URL) ([]*RenderingControl2, error) {
return NewRenderingControl2ClientsByURLCtx(context.Background(), loc)
}
// NewRenderingControl2ClientsFromRootDevice discovers instances of the service in
// a given root device, and returns clients to any that are found. An error is
// returned if there was not at least one instance of the service within the
@@ -7101,7 +7182,6 @@ func newRenderingControl2ClientsFromGenericClients(genericClients []goupnp.Servi
return clients
}
//
// Return values:
//
// * CurrentBlueVideoBlackLevel: allowed value range: minimum=0, step=1
@@ -7147,7 +7227,6 @@ func (client *RenderingControl2) GetBlueVideoBlackLevel(InstanceID uint32) (Curr
)
}
//
// Return values:
//
// * CurrentBlueVideoGain: allowed value range: minimum=0, step=1
@@ -7193,7 +7272,6 @@ func (client *RenderingControl2) GetBlueVideoGain(InstanceID uint32) (CurrentBlu
)
}
//
// Return values:
//
// * CurrentBrightness: allowed value range: minimum=0, step=1
@@ -7239,7 +7317,6 @@ func (client *RenderingControl2) GetBrightness(InstanceID uint32) (CurrentBright
)
}
//
// Return values:
//
// * CurrentColorTemperature: allowed value range: minimum=0, step=1
@@ -7285,7 +7362,6 @@ func (client *RenderingControl2) GetColorTemperature(InstanceID uint32) (Current
)
}
//
// Return values:
//
// * CurrentContrast: allowed value range: minimum=0, step=1
@@ -7331,7 +7407,6 @@ func (client *RenderingControl2) GetContrast(InstanceID uint32) (CurrentContrast
)
}
//
// Return values:
//
// * CurrentGreenVideoBlackLevel: allowed value range: minimum=0, step=1
@@ -7377,7 +7452,6 @@ func (client *RenderingControl2) GetGreenVideoBlackLevel(InstanceID uint32) (Cur
)
}
//
// Return values:
//
// * CurrentGreenVideoGain: allowed value range: minimum=0, step=1
@@ -7423,7 +7497,6 @@ func (client *RenderingControl2) GetGreenVideoGain(InstanceID uint32) (CurrentGr
)
}
//
// Return values:
//
// * CurrentHorizontalKeystone: allowed value range: step=1
@@ -7575,7 +7648,6 @@ func (client *RenderingControl2) GetMute(InstanceID uint32, Channel string) (Cur
)
}
//
// Return values:
//
// * CurrentRedVideoBlackLevel: allowed value range: minimum=0, step=1
@@ -7621,7 +7693,6 @@ func (client *RenderingControl2) GetRedVideoBlackLevel(InstanceID uint32) (Curre
)
}
//
// Return values:
//
// * CurrentRedVideoGain: allowed value range: minimum=0, step=1
@@ -7667,7 +7738,6 @@ func (client *RenderingControl2) GetRedVideoGain(InstanceID uint32) (CurrentRedV
)
}
//
// Return values:
//
// * CurrentSharpness: allowed value range: minimum=0, step=1
@@ -7761,7 +7831,6 @@ func (client *RenderingControl2) GetStateVariables(InstanceID uint32, StateVaria
)
}
//
// Return values:
//
// * CurrentVerticalKeystone: allowed value range: step=1
@@ -7812,7 +7881,6 @@ func (client *RenderingControl2) GetVerticalKeystone(InstanceID uint32) (Current
//
// * Channel: allowed values: Master
//
// Return values:
//
// * CurrentVolume: allowed value range: minimum=0, step=1
@@ -8931,35 +8999,47 @@ type ScheduledRecording1 struct {
goupnp.ServiceClient
}
// NewScheduledRecording1Clients discovers instances of the service on the network,
// NewScheduledRecording1ClientsCtx discovers instances of the service on the network,
// and returns clients to any that are found. errors will contain an error for
// any devices that replied but which could not be queried, and err will be set
// if the discovery process failed outright.
//
// This is a typical entry calling point into this package.
func NewScheduledRecording1Clients() (clients []*ScheduledRecording1, errors []error, err error) {
func NewScheduledRecording1ClientsCtx(ctx context.Context) (clients []*ScheduledRecording1, errors []error, err error) {
var genericClients []goupnp.ServiceClient
if genericClients, errors, err = goupnp.NewServiceClients(URN_ScheduledRecording_1); err != nil {
if genericClients, errors, err = goupnp.NewServiceClientsCtx(ctx, URN_ScheduledRecording_1); err != nil {
return
}
clients = newScheduledRecording1ClientsFromGenericClients(genericClients)
return
}
// NewScheduledRecording1ClientsByURL discovers instances of the service at the given
// NewScheduledRecording1Clients is the legacy version of NewScheduledRecording1ClientsCtx, but uses
// context.Background() as the context.
func NewScheduledRecording1Clients() (clients []*ScheduledRecording1, errors []error, err error) {
return NewScheduledRecording1ClientsCtx(context.Background())
}
// NewScheduledRecording1ClientsByURLCtx discovers instances of the service at the given
// URL, and returns clients to any that are found. An error is returned if
// there was an error probing the service.
//
// This is a typical entry calling point into this package when reusing an
// previously discovered service URL.
func NewScheduledRecording1ClientsByURL(loc *url.URL) ([]*ScheduledRecording1, error) {
genericClients, err := goupnp.NewServiceClientsByURL(loc, URN_ScheduledRecording_1)
func NewScheduledRecording1ClientsByURLCtx(ctx context.Context, loc *url.URL) ([]*ScheduledRecording1, error) {
genericClients, err := goupnp.NewServiceClientsByURLCtx(ctx, loc, URN_ScheduledRecording_1)
if err != nil {
return nil, err
}
return newScheduledRecording1ClientsFromGenericClients(genericClients), nil
}
// NewScheduledRecording1ClientsByURL is the legacy version of NewScheduledRecording1ClientsByURLCtx, but uses
// context.Background() as the context.
func NewScheduledRecording1ClientsByURL(loc *url.URL) ([]*ScheduledRecording1, error) {
return NewScheduledRecording1ClientsByURLCtx(context.Background(), loc)
}
// NewScheduledRecording1ClientsFromRootDevice discovers instances of the service in
// a given root device, and returns clients to any that are found. An error is
// returned if there was not at least one instance of the service within the
@@ -9818,35 +9898,47 @@ type ScheduledRecording2 struct {
goupnp.ServiceClient
}
// NewScheduledRecording2Clients discovers instances of the service on the network,
// NewScheduledRecording2ClientsCtx discovers instances of the service on the network,
// and returns clients to any that are found. errors will contain an error for
// any devices that replied but which could not be queried, and err will be set
// if the discovery process failed outright.
//
// This is a typical entry calling point into this package.
func NewScheduledRecording2Clients() (clients []*ScheduledRecording2, errors []error, err error) {
func NewScheduledRecording2ClientsCtx(ctx context.Context) (clients []*ScheduledRecording2, errors []error, err error) {
var genericClients []goupnp.ServiceClient
if genericClients, errors, err = goupnp.NewServiceClients(URN_ScheduledRecording_2); err != nil {
if genericClients, errors, err = goupnp.NewServiceClientsCtx(ctx, URN_ScheduledRecording_2); err != nil {
return
}
clients = newScheduledRecording2ClientsFromGenericClients(genericClients)
return
}
// NewScheduledRecording2ClientsByURL discovers instances of the service at the given
// NewScheduledRecording2Clients is the legacy version of NewScheduledRecording2ClientsCtx, but uses
// context.Background() as the context.
func NewScheduledRecording2Clients() (clients []*ScheduledRecording2, errors []error, err error) {
return NewScheduledRecording2ClientsCtx(context.Background())
}
// NewScheduledRecording2ClientsByURLCtx discovers instances of the service at the given
// URL, and returns clients to any that are found. An error is returned if
// there was an error probing the service.
//
// This is a typical entry calling point into this package when reusing an
// previously discovered service URL.
func NewScheduledRecording2ClientsByURL(loc *url.URL) ([]*ScheduledRecording2, error) {
genericClients, err := goupnp.NewServiceClientsByURL(loc, URN_ScheduledRecording_2)
func NewScheduledRecording2ClientsByURLCtx(ctx context.Context, loc *url.URL) ([]*ScheduledRecording2, error) {
genericClients, err := goupnp.NewServiceClientsByURLCtx(ctx, loc, URN_ScheduledRecording_2)
if err != nil {
return nil, err
}
return newScheduledRecording2ClientsFromGenericClients(genericClients), nil
}
// NewScheduledRecording2ClientsByURL is the legacy version of NewScheduledRecording2ClientsByURLCtx, but uses
// context.Background() as the context.
func NewScheduledRecording2ClientsByURL(loc *url.URL) ([]*ScheduledRecording2, error) {
return NewScheduledRecording2ClientsByURLCtx(context.Background(), loc)
}
// NewScheduledRecording2ClientsFromRootDevice discovers instances of the service in
// a given root device, and returns clients to any that are found. An error is
// returned if there was not at least one instance of the service within the
+20 -8
View File
@@ -16,8 +16,8 @@ import (
"net/url"
"time"
"github.com/huin/goupnp"
"github.com/huin/goupnp/soap"
"git.cyrilix.bzh/cyrilix/goupnp"
"git.cyrilix.bzh/cyrilix/goupnp/soap"
)
// Hack to avoid Go complaining if time isn't used.
@@ -44,35 +44,47 @@ type {{$srvIdent}} struct {
goupnp.ServiceClient
}
// New{{$srvIdent}}Clients discovers instances of the service on the network,
// New{{$srvIdent}}ClientsCtx discovers instances of the service on the network,
// and returns clients to any that are found. errors will contain an error for
// any devices that replied but which could not be queried, and err will be set
// if the discovery process failed outright.
//
// This is a typical entry calling point into this package.
func New{{$srvIdent}}Clients() (clients []*{{$srvIdent}}, errors []error, err error) {
func New{{$srvIdent}}ClientsCtx(ctx context.Context) (clients []*{{$srvIdent}}, errors []error, err error) {
var genericClients []goupnp.ServiceClient
if genericClients, errors, err = goupnp.NewServiceClients({{$srv.Const}}); err != nil {
if genericClients, errors, err = goupnp.NewServiceClientsCtx(ctx, {{$srv.Const}}); err != nil {
return
}
clients = new{{$srvIdent}}ClientsFromGenericClients(genericClients)
return
}
// New{{$srvIdent}}ClientsByURL discovers instances of the service at the given
// New{{$srvIdent}}Clients is the legacy version of New{{$srvIdent}}ClientsCtx, but uses
// context.Background() as the context.
func New{{$srvIdent}}Clients() (clients []*{{$srvIdent}}, errors []error, err error) {
return New{{$srvIdent}}ClientsCtx(context.Background())
}
// New{{$srvIdent}}ClientsByURLCtx discovers instances of the service at the given
// URL, and returns clients to any that are found. An error is returned if
// there was an error probing the service.
//
// This is a typical entry calling point into this package when reusing an
// previously discovered service URL.
func New{{$srvIdent}}ClientsByURL(loc *url.URL) ([]*{{$srvIdent}}, error) {
genericClients, err := goupnp.NewServiceClientsByURL(loc, {{$srv.Const}})
func New{{$srvIdent}}ClientsByURLCtx(ctx context.Context, loc *url.URL) ([]*{{$srvIdent}}, error) {
genericClients, err := goupnp.NewServiceClientsByURLCtx(ctx, loc, {{$srv.Const}})
if err != nil {
return nil, err
}
return new{{$srvIdent}}ClientsFromGenericClients(genericClients), nil
}
// New{{$srvIdent}}ClientsByURL is the legacy version of New{{$srvIdent}}ClientsByURLCtx, but uses
// context.Background() as the context.
func New{{$srvIdent}}ClientsByURL(loc *url.URL) ([]*{{$srvIdent}}, error) {
return New{{$srvIdent}}ClientsByURLCtx(context.Background(), loc)
}
// New{{$srvIdent}}ClientsFromRootDevice discovers instances of the service in
// a given root device, and returns clients to any that are found. An error is
// returned if there was not at least one instance of the service within the
+164 -70
View File
@@ -15,8 +15,8 @@ import (
"net/url"
"time"
"github.com/huin/goupnp"
"github.com/huin/goupnp/soap"
"git.cyrilix.bzh/cyrilix/goupnp"
"git.cyrilix.bzh/cyrilix/goupnp/soap"
)
// Hack to avoid Go complaining if time isn't used.
@@ -49,35 +49,47 @@ type LANHostConfigManagement1 struct {
goupnp.ServiceClient
}
// NewLANHostConfigManagement1Clients discovers instances of the service on the network,
// NewLANHostConfigManagement1ClientsCtx discovers instances of the service on the network,
// and returns clients to any that are found. errors will contain an error for
// any devices that replied but which could not be queried, and err will be set
// if the discovery process failed outright.
//
// This is a typical entry calling point into this package.
func NewLANHostConfigManagement1Clients() (clients []*LANHostConfigManagement1, errors []error, err error) {
func NewLANHostConfigManagement1ClientsCtx(ctx context.Context) (clients []*LANHostConfigManagement1, errors []error, err error) {
var genericClients []goupnp.ServiceClient
if genericClients, errors, err = goupnp.NewServiceClients(URN_LANHostConfigManagement_1); err != nil {
if genericClients, errors, err = goupnp.NewServiceClientsCtx(ctx, URN_LANHostConfigManagement_1); err != nil {
return
}
clients = newLANHostConfigManagement1ClientsFromGenericClients(genericClients)
return
}
// NewLANHostConfigManagement1ClientsByURL discovers instances of the service at the given
// NewLANHostConfigManagement1Clients is the legacy version of NewLANHostConfigManagement1ClientsCtx, but uses
// context.Background() as the context.
func NewLANHostConfigManagement1Clients() (clients []*LANHostConfigManagement1, errors []error, err error) {
return NewLANHostConfigManagement1ClientsCtx(context.Background())
}
// NewLANHostConfigManagement1ClientsByURLCtx discovers instances of the service at the given
// URL, and returns clients to any that are found. An error is returned if
// there was an error probing the service.
//
// This is a typical entry calling point into this package when reusing an
// previously discovered service URL.
func NewLANHostConfigManagement1ClientsByURL(loc *url.URL) ([]*LANHostConfigManagement1, error) {
genericClients, err := goupnp.NewServiceClientsByURL(loc, URN_LANHostConfigManagement_1)
func NewLANHostConfigManagement1ClientsByURLCtx(ctx context.Context, loc *url.URL) ([]*LANHostConfigManagement1, error) {
genericClients, err := goupnp.NewServiceClientsByURLCtx(ctx, loc, URN_LANHostConfigManagement_1)
if err != nil {
return nil, err
}
return newLANHostConfigManagement1ClientsFromGenericClients(genericClients), nil
}
// NewLANHostConfigManagement1ClientsByURL is the legacy version of NewLANHostConfigManagement1ClientsByURLCtx, but uses
// context.Background() as the context.
func NewLANHostConfigManagement1ClientsByURL(loc *url.URL) ([]*LANHostConfigManagement1, error) {
return NewLANHostConfigManagement1ClientsByURLCtx(context.Background(), loc)
}
// NewLANHostConfigManagement1ClientsFromRootDevice discovers instances of the service in
// a given root device, and returns clients to any that are found. An error is
// returned if there was not at least one instance of the service within the
@@ -798,35 +810,47 @@ type Layer3Forwarding1 struct {
goupnp.ServiceClient
}
// NewLayer3Forwarding1Clients discovers instances of the service on the network,
// NewLayer3Forwarding1ClientsCtx discovers instances of the service on the network,
// and returns clients to any that are found. errors will contain an error for
// any devices that replied but which could not be queried, and err will be set
// if the discovery process failed outright.
//
// This is a typical entry calling point into this package.
func NewLayer3Forwarding1Clients() (clients []*Layer3Forwarding1, errors []error, err error) {
func NewLayer3Forwarding1ClientsCtx(ctx context.Context) (clients []*Layer3Forwarding1, errors []error, err error) {
var genericClients []goupnp.ServiceClient
if genericClients, errors, err = goupnp.NewServiceClients(URN_Layer3Forwarding_1); err != nil {
if genericClients, errors, err = goupnp.NewServiceClientsCtx(ctx, URN_Layer3Forwarding_1); err != nil {
return
}
clients = newLayer3Forwarding1ClientsFromGenericClients(genericClients)
return
}
// NewLayer3Forwarding1ClientsByURL discovers instances of the service at the given
// NewLayer3Forwarding1Clients is the legacy version of NewLayer3Forwarding1ClientsCtx, but uses
// context.Background() as the context.
func NewLayer3Forwarding1Clients() (clients []*Layer3Forwarding1, errors []error, err error) {
return NewLayer3Forwarding1ClientsCtx(context.Background())
}
// NewLayer3Forwarding1ClientsByURLCtx discovers instances of the service at the given
// URL, and returns clients to any that are found. An error is returned if
// there was an error probing the service.
//
// This is a typical entry calling point into this package when reusing an
// previously discovered service URL.
func NewLayer3Forwarding1ClientsByURL(loc *url.URL) ([]*Layer3Forwarding1, error) {
genericClients, err := goupnp.NewServiceClientsByURL(loc, URN_Layer3Forwarding_1)
func NewLayer3Forwarding1ClientsByURLCtx(ctx context.Context, loc *url.URL) ([]*Layer3Forwarding1, error) {
genericClients, err := goupnp.NewServiceClientsByURLCtx(ctx, loc, URN_Layer3Forwarding_1)
if err != nil {
return nil, err
}
return newLayer3Forwarding1ClientsFromGenericClients(genericClients), nil
}
// NewLayer3Forwarding1ClientsByURL is the legacy version of NewLayer3Forwarding1ClientsByURLCtx, but uses
// context.Background() as the context.
func NewLayer3Forwarding1ClientsByURL(loc *url.URL) ([]*Layer3Forwarding1, error) {
return NewLayer3Forwarding1ClientsByURLCtx(context.Background(), loc)
}
// NewLayer3Forwarding1ClientsFromRootDevice discovers instances of the service in
// a given root device, and returns clients to any that are found. An error is
// returned if there was not at least one instance of the service within the
@@ -929,35 +953,47 @@ type WANCableLinkConfig1 struct {
goupnp.ServiceClient
}
// NewWANCableLinkConfig1Clients discovers instances of the service on the network,
// NewWANCableLinkConfig1ClientsCtx discovers instances of the service on the network,
// and returns clients to any that are found. errors will contain an error for
// any devices that replied but which could not be queried, and err will be set
// if the discovery process failed outright.
//
// This is a typical entry calling point into this package.
func NewWANCableLinkConfig1Clients() (clients []*WANCableLinkConfig1, errors []error, err error) {
func NewWANCableLinkConfig1ClientsCtx(ctx context.Context) (clients []*WANCableLinkConfig1, errors []error, err error) {
var genericClients []goupnp.ServiceClient
if genericClients, errors, err = goupnp.NewServiceClients(URN_WANCableLinkConfig_1); err != nil {
if genericClients, errors, err = goupnp.NewServiceClientsCtx(ctx, URN_WANCableLinkConfig_1); err != nil {
return
}
clients = newWANCableLinkConfig1ClientsFromGenericClients(genericClients)
return
}
// NewWANCableLinkConfig1ClientsByURL discovers instances of the service at the given
// NewWANCableLinkConfig1Clients is the legacy version of NewWANCableLinkConfig1ClientsCtx, but uses
// context.Background() as the context.
func NewWANCableLinkConfig1Clients() (clients []*WANCableLinkConfig1, errors []error, err error) {
return NewWANCableLinkConfig1ClientsCtx(context.Background())
}
// NewWANCableLinkConfig1ClientsByURLCtx discovers instances of the service at the given
// URL, and returns clients to any that are found. An error is returned if
// there was an error probing the service.
//
// This is a typical entry calling point into this package when reusing an
// previously discovered service URL.
func NewWANCableLinkConfig1ClientsByURL(loc *url.URL) ([]*WANCableLinkConfig1, error) {
genericClients, err := goupnp.NewServiceClientsByURL(loc, URN_WANCableLinkConfig_1)
func NewWANCableLinkConfig1ClientsByURLCtx(ctx context.Context, loc *url.URL) ([]*WANCableLinkConfig1, error) {
genericClients, err := goupnp.NewServiceClientsByURLCtx(ctx, loc, URN_WANCableLinkConfig_1)
if err != nil {
return nil, err
}
return newWANCableLinkConfig1ClientsFromGenericClients(genericClients), nil
}
// NewWANCableLinkConfig1ClientsByURL is the legacy version of NewWANCableLinkConfig1ClientsByURLCtx, but uses
// context.Background() as the context.
func NewWANCableLinkConfig1ClientsByURL(loc *url.URL) ([]*WANCableLinkConfig1, error) {
return NewWANCableLinkConfig1ClientsByURLCtx(context.Background(), loc)
}
// NewWANCableLinkConfig1ClientsFromRootDevice discovers instances of the service in
// a given root device, and returns clients to any that are found. An error is
// returned if there was not at least one instance of the service within the
@@ -1016,7 +1052,6 @@ func (client *WANCableLinkConfig1) GetBPIEncryptionEnabled() (NewBPIEncryptionEn
return client.GetBPIEncryptionEnabledCtx(context.Background())
}
//
// Return values:
//
// * NewCableLinkConfigState: allowed values: notReady, dsSyncComplete, usParamAcquired, rangingComplete, ipComplete, todEstablished, paramTransferComplete, registrationComplete, operational, accessDenied
@@ -1128,7 +1163,6 @@ func (client *WANCableLinkConfig1) GetDownstreamFrequency() (NewDownstreamFreque
return client.GetDownstreamFrequencyCtx(context.Background())
}
//
// Return values:
//
// * NewDownstreamModulation: allowed values: 64QAM, 256QAM
@@ -1268,7 +1302,6 @@ func (client *WANCableLinkConfig1) GetUpstreamFrequency() (NewUpstreamFrequency
return client.GetUpstreamFrequencyCtx(context.Background())
}
//
// Return values:
//
// * NewUpstreamModulation: allowed values: QPSK, 16QAM
@@ -1347,35 +1380,47 @@ type WANCommonInterfaceConfig1 struct {
goupnp.ServiceClient
}
// NewWANCommonInterfaceConfig1Clients discovers instances of the service on the network,
// NewWANCommonInterfaceConfig1ClientsCtx discovers instances of the service on the network,
// and returns clients to any that are found. errors will contain an error for
// any devices that replied but which could not be queried, and err will be set
// if the discovery process failed outright.
//
// This is a typical entry calling point into this package.
func NewWANCommonInterfaceConfig1Clients() (clients []*WANCommonInterfaceConfig1, errors []error, err error) {
func NewWANCommonInterfaceConfig1ClientsCtx(ctx context.Context) (clients []*WANCommonInterfaceConfig1, errors []error, err error) {
var genericClients []goupnp.ServiceClient
if genericClients, errors, err = goupnp.NewServiceClients(URN_WANCommonInterfaceConfig_1); err != nil {
if genericClients, errors, err = goupnp.NewServiceClientsCtx(ctx, URN_WANCommonInterfaceConfig_1); err != nil {
return
}
clients = newWANCommonInterfaceConfig1ClientsFromGenericClients(genericClients)
return
}
// NewWANCommonInterfaceConfig1ClientsByURL discovers instances of the service at the given
// NewWANCommonInterfaceConfig1Clients is the legacy version of NewWANCommonInterfaceConfig1ClientsCtx, but uses
// context.Background() as the context.
func NewWANCommonInterfaceConfig1Clients() (clients []*WANCommonInterfaceConfig1, errors []error, err error) {
return NewWANCommonInterfaceConfig1ClientsCtx(context.Background())
}
// NewWANCommonInterfaceConfig1ClientsByURLCtx discovers instances of the service at the given
// URL, and returns clients to any that are found. An error is returned if
// there was an error probing the service.
//
// This is a typical entry calling point into this package when reusing an
// previously discovered service URL.
func NewWANCommonInterfaceConfig1ClientsByURL(loc *url.URL) ([]*WANCommonInterfaceConfig1, error) {
genericClients, err := goupnp.NewServiceClientsByURL(loc, URN_WANCommonInterfaceConfig_1)
func NewWANCommonInterfaceConfig1ClientsByURLCtx(ctx context.Context, loc *url.URL) ([]*WANCommonInterfaceConfig1, error) {
genericClients, err := goupnp.NewServiceClientsByURLCtx(ctx, loc, URN_WANCommonInterfaceConfig_1)
if err != nil {
return nil, err
}
return newWANCommonInterfaceConfig1ClientsFromGenericClients(genericClients), nil
}
// NewWANCommonInterfaceConfig1ClientsByURL is the legacy version of NewWANCommonInterfaceConfig1ClientsByURLCtx, but uses
// context.Background() as the context.
func NewWANCommonInterfaceConfig1ClientsByURL(loc *url.URL) ([]*WANCommonInterfaceConfig1, error) {
return NewWANCommonInterfaceConfig1ClientsByURLCtx(context.Background(), loc)
}
// NewWANCommonInterfaceConfig1ClientsFromRootDevice discovers instances of the service in
// a given root device, and returns clients to any that are found. An error is
// returned if there was not at least one instance of the service within the
@@ -1446,7 +1491,6 @@ func (client *WANCommonInterfaceConfig1) GetActiveConnection(NewActiveConnection
)
}
//
// Return values:
//
// * NewWANAccessType: allowed values: DSL, POTS, Cable, Ethernet
@@ -1532,7 +1576,6 @@ func (client *WANCommonInterfaceConfig1) GetEnabledForInternet() (NewEnabledForI
return client.GetEnabledForInternetCtx(context.Background())
}
//
// Return values:
//
// * NewMaximumActiveConnections: allowed value range: minimum=1, step=1
@@ -1784,35 +1827,47 @@ type WANDSLLinkConfig1 struct {
goupnp.ServiceClient
}
// NewWANDSLLinkConfig1Clients discovers instances of the service on the network,
// NewWANDSLLinkConfig1ClientsCtx discovers instances of the service on the network,
// and returns clients to any that are found. errors will contain an error for
// any devices that replied but which could not be queried, and err will be set
// if the discovery process failed outright.
//
// This is a typical entry calling point into this package.
func NewWANDSLLinkConfig1Clients() (clients []*WANDSLLinkConfig1, errors []error, err error) {
func NewWANDSLLinkConfig1ClientsCtx(ctx context.Context) (clients []*WANDSLLinkConfig1, errors []error, err error) {
var genericClients []goupnp.ServiceClient
if genericClients, errors, err = goupnp.NewServiceClients(URN_WANDSLLinkConfig_1); err != nil {
if genericClients, errors, err = goupnp.NewServiceClientsCtx(ctx, URN_WANDSLLinkConfig_1); err != nil {
return
}
clients = newWANDSLLinkConfig1ClientsFromGenericClients(genericClients)
return
}
// NewWANDSLLinkConfig1ClientsByURL discovers instances of the service at the given
// NewWANDSLLinkConfig1Clients is the legacy version of NewWANDSLLinkConfig1ClientsCtx, but uses
// context.Background() as the context.
func NewWANDSLLinkConfig1Clients() (clients []*WANDSLLinkConfig1, errors []error, err error) {
return NewWANDSLLinkConfig1ClientsCtx(context.Background())
}
// NewWANDSLLinkConfig1ClientsByURLCtx discovers instances of the service at the given
// URL, and returns clients to any that are found. An error is returned if
// there was an error probing the service.
//
// This is a typical entry calling point into this package when reusing an
// previously discovered service URL.
func NewWANDSLLinkConfig1ClientsByURL(loc *url.URL) ([]*WANDSLLinkConfig1, error) {
genericClients, err := goupnp.NewServiceClientsByURL(loc, URN_WANDSLLinkConfig_1)
func NewWANDSLLinkConfig1ClientsByURLCtx(ctx context.Context, loc *url.URL) ([]*WANDSLLinkConfig1, error) {
genericClients, err := goupnp.NewServiceClientsByURLCtx(ctx, loc, URN_WANDSLLinkConfig_1)
if err != nil {
return nil, err
}
return newWANDSLLinkConfig1ClientsFromGenericClients(genericClients), nil
}
// NewWANDSLLinkConfig1ClientsByURL is the legacy version of NewWANDSLLinkConfig1ClientsByURLCtx, but uses
// context.Background() as the context.
func NewWANDSLLinkConfig1ClientsByURL(loc *url.URL) ([]*WANDSLLinkConfig1, error) {
return NewWANDSLLinkConfig1ClientsByURLCtx(context.Background(), loc)
}
// NewWANDSLLinkConfig1ClientsFromRootDevice discovers instances of the service in
// a given root device, and returns clients to any that are found. An error is
// returned if there was not at least one instance of the service within the
@@ -1905,7 +1960,6 @@ func (client *WANDSLLinkConfig1) GetAutoConfig() (NewAutoConfig bool, err error)
return client.GetAutoConfigCtx(context.Background())
}
//
// Return values:
//
// * NewLinkStatus: allowed values: Up, Down
@@ -2204,35 +2258,47 @@ type WANEthernetLinkConfig1 struct {
goupnp.ServiceClient
}
// NewWANEthernetLinkConfig1Clients discovers instances of the service on the network,
// NewWANEthernetLinkConfig1ClientsCtx discovers instances of the service on the network,
// and returns clients to any that are found. errors will contain an error for
// any devices that replied but which could not be queried, and err will be set
// if the discovery process failed outright.
//
// This is a typical entry calling point into this package.
func NewWANEthernetLinkConfig1Clients() (clients []*WANEthernetLinkConfig1, errors []error, err error) {
func NewWANEthernetLinkConfig1ClientsCtx(ctx context.Context) (clients []*WANEthernetLinkConfig1, errors []error, err error) {
var genericClients []goupnp.ServiceClient
if genericClients, errors, err = goupnp.NewServiceClients(URN_WANEthernetLinkConfig_1); err != nil {
if genericClients, errors, err = goupnp.NewServiceClientsCtx(ctx, URN_WANEthernetLinkConfig_1); err != nil {
return
}
clients = newWANEthernetLinkConfig1ClientsFromGenericClients(genericClients)
return
}
// NewWANEthernetLinkConfig1ClientsByURL discovers instances of the service at the given
// NewWANEthernetLinkConfig1Clients is the legacy version of NewWANEthernetLinkConfig1ClientsCtx, but uses
// context.Background() as the context.
func NewWANEthernetLinkConfig1Clients() (clients []*WANEthernetLinkConfig1, errors []error, err error) {
return NewWANEthernetLinkConfig1ClientsCtx(context.Background())
}
// NewWANEthernetLinkConfig1ClientsByURLCtx discovers instances of the service at the given
// URL, and returns clients to any that are found. An error is returned if
// there was an error probing the service.
//
// This is a typical entry calling point into this package when reusing an
// previously discovered service URL.
func NewWANEthernetLinkConfig1ClientsByURL(loc *url.URL) ([]*WANEthernetLinkConfig1, error) {
genericClients, err := goupnp.NewServiceClientsByURL(loc, URN_WANEthernetLinkConfig_1)
func NewWANEthernetLinkConfig1ClientsByURLCtx(ctx context.Context, loc *url.URL) ([]*WANEthernetLinkConfig1, error) {
genericClients, err := goupnp.NewServiceClientsByURLCtx(ctx, loc, URN_WANEthernetLinkConfig_1)
if err != nil {
return nil, err
}
return newWANEthernetLinkConfig1ClientsFromGenericClients(genericClients), nil
}
// NewWANEthernetLinkConfig1ClientsByURL is the legacy version of NewWANEthernetLinkConfig1ClientsByURLCtx, but uses
// context.Background() as the context.
func NewWANEthernetLinkConfig1ClientsByURL(loc *url.URL) ([]*WANEthernetLinkConfig1, error) {
return NewWANEthernetLinkConfig1ClientsByURLCtx(context.Background(), loc)
}
// NewWANEthernetLinkConfig1ClientsFromRootDevice discovers instances of the service in
// a given root device, and returns clients to any that are found. An error is
// returned if there was not at least one instance of the service within the
@@ -2257,7 +2323,6 @@ func newWANEthernetLinkConfig1ClientsFromGenericClients(genericClients []goupnp.
return clients
}
//
// Return values:
//
// * NewEthernetLinkStatus: allowed values: Up, Down
@@ -2302,35 +2367,47 @@ type WANIPConnection1 struct {
goupnp.ServiceClient
}
// NewWANIPConnection1Clients discovers instances of the service on the network,
// NewWANIPConnection1ClientsCtx discovers instances of the service on the network,
// and returns clients to any that are found. errors will contain an error for
// any devices that replied but which could not be queried, and err will be set
// if the discovery process failed outright.
//
// This is a typical entry calling point into this package.
func NewWANIPConnection1Clients() (clients []*WANIPConnection1, errors []error, err error) {
func NewWANIPConnection1ClientsCtx(ctx context.Context) (clients []*WANIPConnection1, errors []error, err error) {
var genericClients []goupnp.ServiceClient
if genericClients, errors, err = goupnp.NewServiceClients(URN_WANIPConnection_1); err != nil {
if genericClients, errors, err = goupnp.NewServiceClientsCtx(ctx, URN_WANIPConnection_1); err != nil {
return
}
clients = newWANIPConnection1ClientsFromGenericClients(genericClients)
return
}
// NewWANIPConnection1ClientsByURL discovers instances of the service at the given
// NewWANIPConnection1Clients is the legacy version of NewWANIPConnection1ClientsCtx, but uses
// context.Background() as the context.
func NewWANIPConnection1Clients() (clients []*WANIPConnection1, errors []error, err error) {
return NewWANIPConnection1ClientsCtx(context.Background())
}
// NewWANIPConnection1ClientsByURLCtx discovers instances of the service at the given
// URL, and returns clients to any that are found. An error is returned if
// there was an error probing the service.
//
// This is a typical entry calling point into this package when reusing an
// previously discovered service URL.
func NewWANIPConnection1ClientsByURL(loc *url.URL) ([]*WANIPConnection1, error) {
genericClients, err := goupnp.NewServiceClientsByURL(loc, URN_WANIPConnection_1)
func NewWANIPConnection1ClientsByURLCtx(ctx context.Context, loc *url.URL) ([]*WANIPConnection1, error) {
genericClients, err := goupnp.NewServiceClientsByURLCtx(ctx, loc, URN_WANIPConnection_1)
if err != nil {
return nil, err
}
return newWANIPConnection1ClientsFromGenericClients(genericClients), nil
}
// NewWANIPConnection1ClientsByURL is the legacy version of NewWANIPConnection1ClientsByURLCtx, but uses
// context.Background() as the context.
func NewWANIPConnection1ClientsByURL(loc *url.URL) ([]*WANIPConnection1, error) {
return NewWANIPConnection1ClientsByURLCtx(context.Background(), loc)
}
// NewWANIPConnection1ClientsFromRootDevice discovers instances of the service in
// a given root device, and returns clients to any that are found. An error is
// returned if there was not at least one instance of the service within the
@@ -2556,7 +2633,6 @@ func (client *WANIPConnection1) GetAutoDisconnectTime() (NewAutoDisconnectTime u
return client.GetAutoDisconnectTimeCtx(context.Background())
}
//
// Return values:
//
// * NewPossibleConnectionTypes: allowed values: Unconfigured, IP_Routed, IP_Bridged
@@ -2632,7 +2708,6 @@ func (client *WANIPConnection1) GetExternalIPAddress() (NewExternalIPAddress str
return client.GetExternalIPAddressCtx(context.Background())
}
//
// Return values:
//
// * NewProtocol: allowed values: TCP, UDP
@@ -2853,7 +2928,6 @@ func (client *WANIPConnection1) GetSpecificPortMappingEntry(NewRemoteHost string
)
}
//
// Return values:
//
// * NewConnectionStatus: allowed values: Unconfigured, Connected, Disconnected
@@ -3148,35 +3222,47 @@ type WANPOTSLinkConfig1 struct {
goupnp.ServiceClient
}
// NewWANPOTSLinkConfig1Clients discovers instances of the service on the network,
// NewWANPOTSLinkConfig1ClientsCtx discovers instances of the service on the network,
// and returns clients to any that are found. errors will contain an error for
// any devices that replied but which could not be queried, and err will be set
// if the discovery process failed outright.
//
// This is a typical entry calling point into this package.
func NewWANPOTSLinkConfig1Clients() (clients []*WANPOTSLinkConfig1, errors []error, err error) {
func NewWANPOTSLinkConfig1ClientsCtx(ctx context.Context) (clients []*WANPOTSLinkConfig1, errors []error, err error) {
var genericClients []goupnp.ServiceClient
if genericClients, errors, err = goupnp.NewServiceClients(URN_WANPOTSLinkConfig_1); err != nil {
if genericClients, errors, err = goupnp.NewServiceClientsCtx(ctx, URN_WANPOTSLinkConfig_1); err != nil {
return
}
clients = newWANPOTSLinkConfig1ClientsFromGenericClients(genericClients)
return
}
// NewWANPOTSLinkConfig1ClientsByURL discovers instances of the service at the given
// NewWANPOTSLinkConfig1Clients is the legacy version of NewWANPOTSLinkConfig1ClientsCtx, but uses
// context.Background() as the context.
func NewWANPOTSLinkConfig1Clients() (clients []*WANPOTSLinkConfig1, errors []error, err error) {
return NewWANPOTSLinkConfig1ClientsCtx(context.Background())
}
// NewWANPOTSLinkConfig1ClientsByURLCtx discovers instances of the service at the given
// URL, and returns clients to any that are found. An error is returned if
// there was an error probing the service.
//
// This is a typical entry calling point into this package when reusing an
// previously discovered service URL.
func NewWANPOTSLinkConfig1ClientsByURL(loc *url.URL) ([]*WANPOTSLinkConfig1, error) {
genericClients, err := goupnp.NewServiceClientsByURL(loc, URN_WANPOTSLinkConfig_1)
func NewWANPOTSLinkConfig1ClientsByURLCtx(ctx context.Context, loc *url.URL) ([]*WANPOTSLinkConfig1, error) {
genericClients, err := goupnp.NewServiceClientsByURLCtx(ctx, loc, URN_WANPOTSLinkConfig_1)
if err != nil {
return nil, err
}
return newWANPOTSLinkConfig1ClientsFromGenericClients(genericClients), nil
}
// NewWANPOTSLinkConfig1ClientsByURL is the legacy version of NewWANPOTSLinkConfig1ClientsByURLCtx, but uses
// context.Background() as the context.
func NewWANPOTSLinkConfig1ClientsByURL(loc *url.URL) ([]*WANPOTSLinkConfig1, error) {
return NewWANPOTSLinkConfig1ClientsByURLCtx(context.Background(), loc)
}
// NewWANPOTSLinkConfig1ClientsFromRootDevice discovers instances of the service in
// a given root device, and returns clients to any that are found. An error is
// returned if there was not at least one instance of the service within the
@@ -3375,7 +3461,6 @@ func (client *WANPOTSLinkConfig1) GetFclass() (NewFclass string, err error) {
return client.GetFclassCtx(context.Background())
}
//
// Return values:
//
// * NewLinkType: allowed values: PPP_Dialup
@@ -3559,35 +3644,47 @@ type WANPPPConnection1 struct {
goupnp.ServiceClient
}
// NewWANPPPConnection1Clients discovers instances of the service on the network,
// NewWANPPPConnection1ClientsCtx discovers instances of the service on the network,
// and returns clients to any that are found. errors will contain an error for
// any devices that replied but which could not be queried, and err will be set
// if the discovery process failed outright.
//
// This is a typical entry calling point into this package.
func NewWANPPPConnection1Clients() (clients []*WANPPPConnection1, errors []error, err error) {
func NewWANPPPConnection1ClientsCtx(ctx context.Context) (clients []*WANPPPConnection1, errors []error, err error) {
var genericClients []goupnp.ServiceClient
if genericClients, errors, err = goupnp.NewServiceClients(URN_WANPPPConnection_1); err != nil {
if genericClients, errors, err = goupnp.NewServiceClientsCtx(ctx, URN_WANPPPConnection_1); err != nil {
return
}
clients = newWANPPPConnection1ClientsFromGenericClients(genericClients)
return
}
// NewWANPPPConnection1ClientsByURL discovers instances of the service at the given
// NewWANPPPConnection1Clients is the legacy version of NewWANPPPConnection1ClientsCtx, but uses
// context.Background() as the context.
func NewWANPPPConnection1Clients() (clients []*WANPPPConnection1, errors []error, err error) {
return NewWANPPPConnection1ClientsCtx(context.Background())
}
// NewWANPPPConnection1ClientsByURLCtx discovers instances of the service at the given
// URL, and returns clients to any that are found. An error is returned if
// there was an error probing the service.
//
// This is a typical entry calling point into this package when reusing an
// previously discovered service URL.
func NewWANPPPConnection1ClientsByURL(loc *url.URL) ([]*WANPPPConnection1, error) {
genericClients, err := goupnp.NewServiceClientsByURL(loc, URN_WANPPPConnection_1)
func NewWANPPPConnection1ClientsByURLCtx(ctx context.Context, loc *url.URL) ([]*WANPPPConnection1, error) {
genericClients, err := goupnp.NewServiceClientsByURLCtx(ctx, loc, URN_WANPPPConnection_1)
if err != nil {
return nil, err
}
return newWANPPPConnection1ClientsFromGenericClients(genericClients), nil
}
// NewWANPPPConnection1ClientsByURL is the legacy version of NewWANPPPConnection1ClientsByURLCtx, but uses
// context.Background() as the context.
func NewWANPPPConnection1ClientsByURL(loc *url.URL) ([]*WANPPPConnection1, error) {
return NewWANPPPConnection1ClientsByURLCtx(context.Background(), loc)
}
// NewWANPPPConnection1ClientsFromRootDevice discovers instances of the service in
// a given root device, and returns clients to any that are found. An error is
// returned if there was not at least one instance of the service within the
@@ -3856,7 +3953,6 @@ func (client *WANPPPConnection1) GetAutoDisconnectTime() (NewAutoDisconnectTime
return client.GetAutoDisconnectTimeCtx(context.Background())
}
//
// Return values:
//
// * NewPossibleConnectionTypes: allowed values: Unconfigured, IP_Routed, DHCP_Spoofed, PPPoE_Bridged, PPTP_Relay, L2TP_Relay, PPPoE_Relay
@@ -3932,7 +4028,6 @@ func (client *WANPPPConnection1) GetExternalIPAddress() (NewExternalIPAddress st
return client.GetExternalIPAddressCtx(context.Background())
}
//
// Return values:
//
// * NewProtocol: allowed values: TCP, UDP
@@ -4327,7 +4422,6 @@ func (client *WANPPPConnection1) GetSpecificPortMappingEntry(NewRemoteHost strin
)
}
//
// Return values:
//
// * NewConnectionStatus: allowed values: Unconfigured, Connected, Disconnected
+218 -90
View File
@@ -15,8 +15,8 @@ import (
"net/url"
"time"
"github.com/huin/goupnp"
"github.com/huin/goupnp/soap"
"git.cyrilix.bzh/cyrilix/goupnp"
"git.cyrilix.bzh/cyrilix/goupnp/soap"
)
// Hack to avoid Go complaining if time isn't used.
@@ -54,35 +54,47 @@ type DeviceProtection1 struct {
goupnp.ServiceClient
}
// NewDeviceProtection1Clients discovers instances of the service on the network,
// NewDeviceProtection1ClientsCtx discovers instances of the service on the network,
// and returns clients to any that are found. errors will contain an error for
// any devices that replied but which could not be queried, and err will be set
// if the discovery process failed outright.
//
// This is a typical entry calling point into this package.
func NewDeviceProtection1Clients() (clients []*DeviceProtection1, errors []error, err error) {
func NewDeviceProtection1ClientsCtx(ctx context.Context) (clients []*DeviceProtection1, errors []error, err error) {
var genericClients []goupnp.ServiceClient
if genericClients, errors, err = goupnp.NewServiceClients(URN_DeviceProtection_1); err != nil {
if genericClients, errors, err = goupnp.NewServiceClientsCtx(ctx, URN_DeviceProtection_1); err != nil {
return
}
clients = newDeviceProtection1ClientsFromGenericClients(genericClients)
return
}
// NewDeviceProtection1ClientsByURL discovers instances of the service at the given
// NewDeviceProtection1Clients is the legacy version of NewDeviceProtection1ClientsCtx, but uses
// context.Background() as the context.
func NewDeviceProtection1Clients() (clients []*DeviceProtection1, errors []error, err error) {
return NewDeviceProtection1ClientsCtx(context.Background())
}
// NewDeviceProtection1ClientsByURLCtx discovers instances of the service at the given
// URL, and returns clients to any that are found. An error is returned if
// there was an error probing the service.
//
// This is a typical entry calling point into this package when reusing an
// previously discovered service URL.
func NewDeviceProtection1ClientsByURL(loc *url.URL) ([]*DeviceProtection1, error) {
genericClients, err := goupnp.NewServiceClientsByURL(loc, URN_DeviceProtection_1)
func NewDeviceProtection1ClientsByURLCtx(ctx context.Context, loc *url.URL) ([]*DeviceProtection1, error) {
genericClients, err := goupnp.NewServiceClientsByURLCtx(ctx, loc, URN_DeviceProtection_1)
if err != nil {
return nil, err
}
return newDeviceProtection1ClientsFromGenericClients(genericClients), nil
}
// NewDeviceProtection1ClientsByURL is the legacy version of NewDeviceProtection1ClientsByURLCtx, but uses
// context.Background() as the context.
func NewDeviceProtection1ClientsByURL(loc *url.URL) ([]*DeviceProtection1, error) {
return NewDeviceProtection1ClientsByURLCtx(context.Background(), loc)
}
// NewDeviceProtection1ClientsFromRootDevice discovers instances of the service in
// a given root device, and returns clients to any that are found. An error is
// returned if there was not at least one instance of the service within the
@@ -672,35 +684,47 @@ type LANHostConfigManagement1 struct {
goupnp.ServiceClient
}
// NewLANHostConfigManagement1Clients discovers instances of the service on the network,
// NewLANHostConfigManagement1ClientsCtx discovers instances of the service on the network,
// and returns clients to any that are found. errors will contain an error for
// any devices that replied but which could not be queried, and err will be set
// if the discovery process failed outright.
//
// This is a typical entry calling point into this package.
func NewLANHostConfigManagement1Clients() (clients []*LANHostConfigManagement1, errors []error, err error) {
func NewLANHostConfigManagement1ClientsCtx(ctx context.Context) (clients []*LANHostConfigManagement1, errors []error, err error) {
var genericClients []goupnp.ServiceClient
if genericClients, errors, err = goupnp.NewServiceClients(URN_LANHostConfigManagement_1); err != nil {
if genericClients, errors, err = goupnp.NewServiceClientsCtx(ctx, URN_LANHostConfigManagement_1); err != nil {
return
}
clients = newLANHostConfigManagement1ClientsFromGenericClients(genericClients)
return
}
// NewLANHostConfigManagement1ClientsByURL discovers instances of the service at the given
// NewLANHostConfigManagement1Clients is the legacy version of NewLANHostConfigManagement1ClientsCtx, but uses
// context.Background() as the context.
func NewLANHostConfigManagement1Clients() (clients []*LANHostConfigManagement1, errors []error, err error) {
return NewLANHostConfigManagement1ClientsCtx(context.Background())
}
// NewLANHostConfigManagement1ClientsByURLCtx discovers instances of the service at the given
// URL, and returns clients to any that are found. An error is returned if
// there was an error probing the service.
//
// This is a typical entry calling point into this package when reusing an
// previously discovered service URL.
func NewLANHostConfigManagement1ClientsByURL(loc *url.URL) ([]*LANHostConfigManagement1, error) {
genericClients, err := goupnp.NewServiceClientsByURL(loc, URN_LANHostConfigManagement_1)
func NewLANHostConfigManagement1ClientsByURLCtx(ctx context.Context, loc *url.URL) ([]*LANHostConfigManagement1, error) {
genericClients, err := goupnp.NewServiceClientsByURLCtx(ctx, loc, URN_LANHostConfigManagement_1)
if err != nil {
return nil, err
}
return newLANHostConfigManagement1ClientsFromGenericClients(genericClients), nil
}
// NewLANHostConfigManagement1ClientsByURL is the legacy version of NewLANHostConfigManagement1ClientsByURLCtx, but uses
// context.Background() as the context.
func NewLANHostConfigManagement1ClientsByURL(loc *url.URL) ([]*LANHostConfigManagement1, error) {
return NewLANHostConfigManagement1ClientsByURLCtx(context.Background(), loc)
}
// NewLANHostConfigManagement1ClientsFromRootDevice discovers instances of the service in
// a given root device, and returns clients to any that are found. An error is
// returned if there was not at least one instance of the service within the
@@ -1421,35 +1445,47 @@ type Layer3Forwarding1 struct {
goupnp.ServiceClient
}
// NewLayer3Forwarding1Clients discovers instances of the service on the network,
// NewLayer3Forwarding1ClientsCtx discovers instances of the service on the network,
// and returns clients to any that are found. errors will contain an error for
// any devices that replied but which could not be queried, and err will be set
// if the discovery process failed outright.
//
// This is a typical entry calling point into this package.
func NewLayer3Forwarding1Clients() (clients []*Layer3Forwarding1, errors []error, err error) {
func NewLayer3Forwarding1ClientsCtx(ctx context.Context) (clients []*Layer3Forwarding1, errors []error, err error) {
var genericClients []goupnp.ServiceClient
if genericClients, errors, err = goupnp.NewServiceClients(URN_Layer3Forwarding_1); err != nil {
if genericClients, errors, err = goupnp.NewServiceClientsCtx(ctx, URN_Layer3Forwarding_1); err != nil {
return
}
clients = newLayer3Forwarding1ClientsFromGenericClients(genericClients)
return
}
// NewLayer3Forwarding1ClientsByURL discovers instances of the service at the given
// NewLayer3Forwarding1Clients is the legacy version of NewLayer3Forwarding1ClientsCtx, but uses
// context.Background() as the context.
func NewLayer3Forwarding1Clients() (clients []*Layer3Forwarding1, errors []error, err error) {
return NewLayer3Forwarding1ClientsCtx(context.Background())
}
// NewLayer3Forwarding1ClientsByURLCtx discovers instances of the service at the given
// URL, and returns clients to any that are found. An error is returned if
// there was an error probing the service.
//
// This is a typical entry calling point into this package when reusing an
// previously discovered service URL.
func NewLayer3Forwarding1ClientsByURL(loc *url.URL) ([]*Layer3Forwarding1, error) {
genericClients, err := goupnp.NewServiceClientsByURL(loc, URN_Layer3Forwarding_1)
func NewLayer3Forwarding1ClientsByURLCtx(ctx context.Context, loc *url.URL) ([]*Layer3Forwarding1, error) {
genericClients, err := goupnp.NewServiceClientsByURLCtx(ctx, loc, URN_Layer3Forwarding_1)
if err != nil {
return nil, err
}
return newLayer3Forwarding1ClientsFromGenericClients(genericClients), nil
}
// NewLayer3Forwarding1ClientsByURL is the legacy version of NewLayer3Forwarding1ClientsByURLCtx, but uses
// context.Background() as the context.
func NewLayer3Forwarding1ClientsByURL(loc *url.URL) ([]*Layer3Forwarding1, error) {
return NewLayer3Forwarding1ClientsByURLCtx(context.Background(), loc)
}
// NewLayer3Forwarding1ClientsFromRootDevice discovers instances of the service in
// a given root device, and returns clients to any that are found. An error is
// returned if there was not at least one instance of the service within the
@@ -1552,35 +1588,47 @@ type WANCableLinkConfig1 struct {
goupnp.ServiceClient
}
// NewWANCableLinkConfig1Clients discovers instances of the service on the network,
// NewWANCableLinkConfig1ClientsCtx discovers instances of the service on the network,
// and returns clients to any that are found. errors will contain an error for
// any devices that replied but which could not be queried, and err will be set
// if the discovery process failed outright.
//
// This is a typical entry calling point into this package.
func NewWANCableLinkConfig1Clients() (clients []*WANCableLinkConfig1, errors []error, err error) {
func NewWANCableLinkConfig1ClientsCtx(ctx context.Context) (clients []*WANCableLinkConfig1, errors []error, err error) {
var genericClients []goupnp.ServiceClient
if genericClients, errors, err = goupnp.NewServiceClients(URN_WANCableLinkConfig_1); err != nil {
if genericClients, errors, err = goupnp.NewServiceClientsCtx(ctx, URN_WANCableLinkConfig_1); err != nil {
return
}
clients = newWANCableLinkConfig1ClientsFromGenericClients(genericClients)
return
}
// NewWANCableLinkConfig1ClientsByURL discovers instances of the service at the given
// NewWANCableLinkConfig1Clients is the legacy version of NewWANCableLinkConfig1ClientsCtx, but uses
// context.Background() as the context.
func NewWANCableLinkConfig1Clients() (clients []*WANCableLinkConfig1, errors []error, err error) {
return NewWANCableLinkConfig1ClientsCtx(context.Background())
}
// NewWANCableLinkConfig1ClientsByURLCtx discovers instances of the service at the given
// URL, and returns clients to any that are found. An error is returned if
// there was an error probing the service.
//
// This is a typical entry calling point into this package when reusing an
// previously discovered service URL.
func NewWANCableLinkConfig1ClientsByURL(loc *url.URL) ([]*WANCableLinkConfig1, error) {
genericClients, err := goupnp.NewServiceClientsByURL(loc, URN_WANCableLinkConfig_1)
func NewWANCableLinkConfig1ClientsByURLCtx(ctx context.Context, loc *url.URL) ([]*WANCableLinkConfig1, error) {
genericClients, err := goupnp.NewServiceClientsByURLCtx(ctx, loc, URN_WANCableLinkConfig_1)
if err != nil {
return nil, err
}
return newWANCableLinkConfig1ClientsFromGenericClients(genericClients), nil
}
// NewWANCableLinkConfig1ClientsByURL is the legacy version of NewWANCableLinkConfig1ClientsByURLCtx, but uses
// context.Background() as the context.
func NewWANCableLinkConfig1ClientsByURL(loc *url.URL) ([]*WANCableLinkConfig1, error) {
return NewWANCableLinkConfig1ClientsByURLCtx(context.Background(), loc)
}
// NewWANCableLinkConfig1ClientsFromRootDevice discovers instances of the service in
// a given root device, and returns clients to any that are found. An error is
// returned if there was not at least one instance of the service within the
@@ -1639,7 +1687,6 @@ func (client *WANCableLinkConfig1) GetBPIEncryptionEnabled() (NewBPIEncryptionEn
return client.GetBPIEncryptionEnabledCtx(context.Background())
}
//
// Return values:
//
// * NewCableLinkConfigState: allowed values: notReady, dsSyncComplete, usParamAcquired, rangingComplete, ipComplete, todEstablished, paramTransferComplete, registrationComplete, operational, accessDenied
@@ -1751,7 +1798,6 @@ func (client *WANCableLinkConfig1) GetDownstreamFrequency() (NewDownstreamFreque
return client.GetDownstreamFrequencyCtx(context.Background())
}
//
// Return values:
//
// * NewDownstreamModulation: allowed values: 64QAM, 256QAM
@@ -1891,7 +1937,6 @@ func (client *WANCableLinkConfig1) GetUpstreamFrequency() (NewUpstreamFrequency
return client.GetUpstreamFrequencyCtx(context.Background())
}
//
// Return values:
//
// * NewUpstreamModulation: allowed values: QPSK, 16QAM
@@ -1970,35 +2015,47 @@ type WANCommonInterfaceConfig1 struct {
goupnp.ServiceClient
}
// NewWANCommonInterfaceConfig1Clients discovers instances of the service on the network,
// NewWANCommonInterfaceConfig1ClientsCtx discovers instances of the service on the network,
// and returns clients to any that are found. errors will contain an error for
// any devices that replied but which could not be queried, and err will be set
// if the discovery process failed outright.
//
// This is a typical entry calling point into this package.
func NewWANCommonInterfaceConfig1Clients() (clients []*WANCommonInterfaceConfig1, errors []error, err error) {
func NewWANCommonInterfaceConfig1ClientsCtx(ctx context.Context) (clients []*WANCommonInterfaceConfig1, errors []error, err error) {
var genericClients []goupnp.ServiceClient
if genericClients, errors, err = goupnp.NewServiceClients(URN_WANCommonInterfaceConfig_1); err != nil {
if genericClients, errors, err = goupnp.NewServiceClientsCtx(ctx, URN_WANCommonInterfaceConfig_1); err != nil {
return
}
clients = newWANCommonInterfaceConfig1ClientsFromGenericClients(genericClients)
return
}
// NewWANCommonInterfaceConfig1ClientsByURL discovers instances of the service at the given
// NewWANCommonInterfaceConfig1Clients is the legacy version of NewWANCommonInterfaceConfig1ClientsCtx, but uses
// context.Background() as the context.
func NewWANCommonInterfaceConfig1Clients() (clients []*WANCommonInterfaceConfig1, errors []error, err error) {
return NewWANCommonInterfaceConfig1ClientsCtx(context.Background())
}
// NewWANCommonInterfaceConfig1ClientsByURLCtx discovers instances of the service at the given
// URL, and returns clients to any that are found. An error is returned if
// there was an error probing the service.
//
// This is a typical entry calling point into this package when reusing an
// previously discovered service URL.
func NewWANCommonInterfaceConfig1ClientsByURL(loc *url.URL) ([]*WANCommonInterfaceConfig1, error) {
genericClients, err := goupnp.NewServiceClientsByURL(loc, URN_WANCommonInterfaceConfig_1)
func NewWANCommonInterfaceConfig1ClientsByURLCtx(ctx context.Context, loc *url.URL) ([]*WANCommonInterfaceConfig1, error) {
genericClients, err := goupnp.NewServiceClientsByURLCtx(ctx, loc, URN_WANCommonInterfaceConfig_1)
if err != nil {
return nil, err
}
return newWANCommonInterfaceConfig1ClientsFromGenericClients(genericClients), nil
}
// NewWANCommonInterfaceConfig1ClientsByURL is the legacy version of NewWANCommonInterfaceConfig1ClientsByURLCtx, but uses
// context.Background() as the context.
func NewWANCommonInterfaceConfig1ClientsByURL(loc *url.URL) ([]*WANCommonInterfaceConfig1, error) {
return NewWANCommonInterfaceConfig1ClientsByURLCtx(context.Background(), loc)
}
// NewWANCommonInterfaceConfig1ClientsFromRootDevice discovers instances of the service in
// a given root device, and returns clients to any that are found. An error is
// returned if there was not at least one instance of the service within the
@@ -2069,7 +2126,6 @@ func (client *WANCommonInterfaceConfig1) GetActiveConnection(NewActiveConnection
)
}
//
// Return values:
//
// * NewWANAccessType: allowed values: DSL, POTS, Cable, Ethernet
@@ -2155,7 +2211,6 @@ func (client *WANCommonInterfaceConfig1) GetEnabledForInternet() (NewEnabledForI
return client.GetEnabledForInternetCtx(context.Background())
}
//
// Return values:
//
// * NewMaximumActiveConnections: allowed value range: minimum=1, step=1
@@ -2407,35 +2462,47 @@ type WANDSLLinkConfig1 struct {
goupnp.ServiceClient
}
// NewWANDSLLinkConfig1Clients discovers instances of the service on the network,
// NewWANDSLLinkConfig1ClientsCtx discovers instances of the service on the network,
// and returns clients to any that are found. errors will contain an error for
// any devices that replied but which could not be queried, and err will be set
// if the discovery process failed outright.
//
// This is a typical entry calling point into this package.
func NewWANDSLLinkConfig1Clients() (clients []*WANDSLLinkConfig1, errors []error, err error) {
func NewWANDSLLinkConfig1ClientsCtx(ctx context.Context) (clients []*WANDSLLinkConfig1, errors []error, err error) {
var genericClients []goupnp.ServiceClient
if genericClients, errors, err = goupnp.NewServiceClients(URN_WANDSLLinkConfig_1); err != nil {
if genericClients, errors, err = goupnp.NewServiceClientsCtx(ctx, URN_WANDSLLinkConfig_1); err != nil {
return
}
clients = newWANDSLLinkConfig1ClientsFromGenericClients(genericClients)
return
}
// NewWANDSLLinkConfig1ClientsByURL discovers instances of the service at the given
// NewWANDSLLinkConfig1Clients is the legacy version of NewWANDSLLinkConfig1ClientsCtx, but uses
// context.Background() as the context.
func NewWANDSLLinkConfig1Clients() (clients []*WANDSLLinkConfig1, errors []error, err error) {
return NewWANDSLLinkConfig1ClientsCtx(context.Background())
}
// NewWANDSLLinkConfig1ClientsByURLCtx discovers instances of the service at the given
// URL, and returns clients to any that are found. An error is returned if
// there was an error probing the service.
//
// This is a typical entry calling point into this package when reusing an
// previously discovered service URL.
func NewWANDSLLinkConfig1ClientsByURL(loc *url.URL) ([]*WANDSLLinkConfig1, error) {
genericClients, err := goupnp.NewServiceClientsByURL(loc, URN_WANDSLLinkConfig_1)
func NewWANDSLLinkConfig1ClientsByURLCtx(ctx context.Context, loc *url.URL) ([]*WANDSLLinkConfig1, error) {
genericClients, err := goupnp.NewServiceClientsByURLCtx(ctx, loc, URN_WANDSLLinkConfig_1)
if err != nil {
return nil, err
}
return newWANDSLLinkConfig1ClientsFromGenericClients(genericClients), nil
}
// NewWANDSLLinkConfig1ClientsByURL is the legacy version of NewWANDSLLinkConfig1ClientsByURLCtx, but uses
// context.Background() as the context.
func NewWANDSLLinkConfig1ClientsByURL(loc *url.URL) ([]*WANDSLLinkConfig1, error) {
return NewWANDSLLinkConfig1ClientsByURLCtx(context.Background(), loc)
}
// NewWANDSLLinkConfig1ClientsFromRootDevice discovers instances of the service in
// a given root device, and returns clients to any that are found. An error is
// returned if there was not at least one instance of the service within the
@@ -2528,7 +2595,6 @@ func (client *WANDSLLinkConfig1) GetAutoConfig() (NewAutoConfig bool, err error)
return client.GetAutoConfigCtx(context.Background())
}
//
// Return values:
//
// * NewLinkStatus: allowed values: Up, Down
@@ -2827,35 +2893,47 @@ type WANEthernetLinkConfig1 struct {
goupnp.ServiceClient
}
// NewWANEthernetLinkConfig1Clients discovers instances of the service on the network,
// NewWANEthernetLinkConfig1ClientsCtx discovers instances of the service on the network,
// and returns clients to any that are found. errors will contain an error for
// any devices that replied but which could not be queried, and err will be set
// if the discovery process failed outright.
//
// This is a typical entry calling point into this package.
func NewWANEthernetLinkConfig1Clients() (clients []*WANEthernetLinkConfig1, errors []error, err error) {
func NewWANEthernetLinkConfig1ClientsCtx(ctx context.Context) (clients []*WANEthernetLinkConfig1, errors []error, err error) {
var genericClients []goupnp.ServiceClient
if genericClients, errors, err = goupnp.NewServiceClients(URN_WANEthernetLinkConfig_1); err != nil {
if genericClients, errors, err = goupnp.NewServiceClientsCtx(ctx, URN_WANEthernetLinkConfig_1); err != nil {
return
}
clients = newWANEthernetLinkConfig1ClientsFromGenericClients(genericClients)
return
}
// NewWANEthernetLinkConfig1ClientsByURL discovers instances of the service at the given
// NewWANEthernetLinkConfig1Clients is the legacy version of NewWANEthernetLinkConfig1ClientsCtx, but uses
// context.Background() as the context.
func NewWANEthernetLinkConfig1Clients() (clients []*WANEthernetLinkConfig1, errors []error, err error) {
return NewWANEthernetLinkConfig1ClientsCtx(context.Background())
}
// NewWANEthernetLinkConfig1ClientsByURLCtx discovers instances of the service at the given
// URL, and returns clients to any that are found. An error is returned if
// there was an error probing the service.
//
// This is a typical entry calling point into this package when reusing an
// previously discovered service URL.
func NewWANEthernetLinkConfig1ClientsByURL(loc *url.URL) ([]*WANEthernetLinkConfig1, error) {
genericClients, err := goupnp.NewServiceClientsByURL(loc, URN_WANEthernetLinkConfig_1)
func NewWANEthernetLinkConfig1ClientsByURLCtx(ctx context.Context, loc *url.URL) ([]*WANEthernetLinkConfig1, error) {
genericClients, err := goupnp.NewServiceClientsByURLCtx(ctx, loc, URN_WANEthernetLinkConfig_1)
if err != nil {
return nil, err
}
return newWANEthernetLinkConfig1ClientsFromGenericClients(genericClients), nil
}
// NewWANEthernetLinkConfig1ClientsByURL is the legacy version of NewWANEthernetLinkConfig1ClientsByURLCtx, but uses
// context.Background() as the context.
func NewWANEthernetLinkConfig1ClientsByURL(loc *url.URL) ([]*WANEthernetLinkConfig1, error) {
return NewWANEthernetLinkConfig1ClientsByURLCtx(context.Background(), loc)
}
// NewWANEthernetLinkConfig1ClientsFromRootDevice discovers instances of the service in
// a given root device, and returns clients to any that are found. An error is
// returned if there was not at least one instance of the service within the
@@ -2880,7 +2958,6 @@ func newWANEthernetLinkConfig1ClientsFromGenericClients(genericClients []goupnp.
return clients
}
//
// Return values:
//
// * NewEthernetLinkStatus: allowed values: Up, Down
@@ -2925,35 +3002,47 @@ type WANIPConnection1 struct {
goupnp.ServiceClient
}
// NewWANIPConnection1Clients discovers instances of the service on the network,
// NewWANIPConnection1ClientsCtx discovers instances of the service on the network,
// and returns clients to any that are found. errors will contain an error for
// any devices that replied but which could not be queried, and err will be set
// if the discovery process failed outright.
//
// This is a typical entry calling point into this package.
func NewWANIPConnection1Clients() (clients []*WANIPConnection1, errors []error, err error) {
func NewWANIPConnection1ClientsCtx(ctx context.Context) (clients []*WANIPConnection1, errors []error, err error) {
var genericClients []goupnp.ServiceClient
if genericClients, errors, err = goupnp.NewServiceClients(URN_WANIPConnection_1); err != nil {
if genericClients, errors, err = goupnp.NewServiceClientsCtx(ctx, URN_WANIPConnection_1); err != nil {
return
}
clients = newWANIPConnection1ClientsFromGenericClients(genericClients)
return
}
// NewWANIPConnection1ClientsByURL discovers instances of the service at the given
// NewWANIPConnection1Clients is the legacy version of NewWANIPConnection1ClientsCtx, but uses
// context.Background() as the context.
func NewWANIPConnection1Clients() (clients []*WANIPConnection1, errors []error, err error) {
return NewWANIPConnection1ClientsCtx(context.Background())
}
// NewWANIPConnection1ClientsByURLCtx discovers instances of the service at the given
// URL, and returns clients to any that are found. An error is returned if
// there was an error probing the service.
//
// This is a typical entry calling point into this package when reusing an
// previously discovered service URL.
func NewWANIPConnection1ClientsByURL(loc *url.URL) ([]*WANIPConnection1, error) {
genericClients, err := goupnp.NewServiceClientsByURL(loc, URN_WANIPConnection_1)
func NewWANIPConnection1ClientsByURLCtx(ctx context.Context, loc *url.URL) ([]*WANIPConnection1, error) {
genericClients, err := goupnp.NewServiceClientsByURLCtx(ctx, loc, URN_WANIPConnection_1)
if err != nil {
return nil, err
}
return newWANIPConnection1ClientsFromGenericClients(genericClients), nil
}
// NewWANIPConnection1ClientsByURL is the legacy version of NewWANIPConnection1ClientsByURLCtx, but uses
// context.Background() as the context.
func NewWANIPConnection1ClientsByURL(loc *url.URL) ([]*WANIPConnection1, error) {
return NewWANIPConnection1ClientsByURLCtx(context.Background(), loc)
}
// NewWANIPConnection1ClientsFromRootDevice discovers instances of the service in
// a given root device, and returns clients to any that are found. An error is
// returned if there was not at least one instance of the service within the
@@ -3179,7 +3268,6 @@ func (client *WANIPConnection1) GetAutoDisconnectTime() (NewAutoDisconnectTime u
return client.GetAutoDisconnectTimeCtx(context.Background())
}
//
// Return values:
//
// * NewPossibleConnectionTypes: allowed values: Unconfigured, IP_Routed, IP_Bridged
@@ -3255,7 +3343,6 @@ func (client *WANIPConnection1) GetExternalIPAddress() (NewExternalIPAddress str
return client.GetExternalIPAddressCtx(context.Background())
}
//
// Return values:
//
// * NewProtocol: allowed values: TCP, UDP
@@ -3476,7 +3563,6 @@ func (client *WANIPConnection1) GetSpecificPortMappingEntry(NewRemoteHost string
)
}
//
// Return values:
//
// * NewConnectionStatus: allowed values: Unconfigured, Connected, Disconnected
@@ -3771,35 +3857,47 @@ type WANIPConnection2 struct {
goupnp.ServiceClient
}
// NewWANIPConnection2Clients discovers instances of the service on the network,
// NewWANIPConnection2ClientsCtx discovers instances of the service on the network,
// and returns clients to any that are found. errors will contain an error for
// any devices that replied but which could not be queried, and err will be set
// if the discovery process failed outright.
//
// This is a typical entry calling point into this package.
func NewWANIPConnection2Clients() (clients []*WANIPConnection2, errors []error, err error) {
func NewWANIPConnection2ClientsCtx(ctx context.Context) (clients []*WANIPConnection2, errors []error, err error) {
var genericClients []goupnp.ServiceClient
if genericClients, errors, err = goupnp.NewServiceClients(URN_WANIPConnection_2); err != nil {
if genericClients, errors, err = goupnp.NewServiceClientsCtx(ctx, URN_WANIPConnection_2); err != nil {
return
}
clients = newWANIPConnection2ClientsFromGenericClients(genericClients)
return
}
// NewWANIPConnection2ClientsByURL discovers instances of the service at the given
// NewWANIPConnection2Clients is the legacy version of NewWANIPConnection2ClientsCtx, but uses
// context.Background() as the context.
func NewWANIPConnection2Clients() (clients []*WANIPConnection2, errors []error, err error) {
return NewWANIPConnection2ClientsCtx(context.Background())
}
// NewWANIPConnection2ClientsByURLCtx discovers instances of the service at the given
// URL, and returns clients to any that are found. An error is returned if
// there was an error probing the service.
//
// This is a typical entry calling point into this package when reusing an
// previously discovered service URL.
func NewWANIPConnection2ClientsByURL(loc *url.URL) ([]*WANIPConnection2, error) {
genericClients, err := goupnp.NewServiceClientsByURL(loc, URN_WANIPConnection_2)
func NewWANIPConnection2ClientsByURLCtx(ctx context.Context, loc *url.URL) ([]*WANIPConnection2, error) {
genericClients, err := goupnp.NewServiceClientsByURLCtx(ctx, loc, URN_WANIPConnection_2)
if err != nil {
return nil, err
}
return newWANIPConnection2ClientsFromGenericClients(genericClients), nil
}
// NewWANIPConnection2ClientsByURL is the legacy version of NewWANIPConnection2ClientsByURLCtx, but uses
// context.Background() as the context.
func NewWANIPConnection2ClientsByURL(loc *url.URL) ([]*WANIPConnection2, error) {
return NewWANIPConnection2ClientsByURLCtx(context.Background(), loc)
}
// NewWANIPConnection2ClientsFromRootDevice discovers instances of the service in
// a given root device, and returns clients to any that are found. An error is
// returned if there was not at least one instance of the service within the
@@ -4246,7 +4344,6 @@ func (client *WANIPConnection2) GetExternalIPAddress() (NewExternalIPAddress str
return client.GetExternalIPAddressCtx(context.Background())
}
//
// Return values:
//
// * NewProtocol: allowed values: TCP, UDP
@@ -4538,7 +4635,6 @@ func (client *WANIPConnection2) GetSpecificPortMappingEntry(NewRemoteHost string
)
}
//
// Return values:
//
// * NewConnectionStatus: allowed values: Unconfigured, Connecting, Connected, PendingDisconnect, Disconnecting, Disconnected
@@ -4833,35 +4929,47 @@ type WANIPv6FirewallControl1 struct {
goupnp.ServiceClient
}
// NewWANIPv6FirewallControl1Clients discovers instances of the service on the network,
// NewWANIPv6FirewallControl1ClientsCtx discovers instances of the service on the network,
// and returns clients to any that are found. errors will contain an error for
// any devices that replied but which could not be queried, and err will be set
// if the discovery process failed outright.
//
// This is a typical entry calling point into this package.
func NewWANIPv6FirewallControl1Clients() (clients []*WANIPv6FirewallControl1, errors []error, err error) {
func NewWANIPv6FirewallControl1ClientsCtx(ctx context.Context) (clients []*WANIPv6FirewallControl1, errors []error, err error) {
var genericClients []goupnp.ServiceClient
if genericClients, errors, err = goupnp.NewServiceClients(URN_WANIPv6FirewallControl_1); err != nil {
if genericClients, errors, err = goupnp.NewServiceClientsCtx(ctx, URN_WANIPv6FirewallControl_1); err != nil {
return
}
clients = newWANIPv6FirewallControl1ClientsFromGenericClients(genericClients)
return
}
// NewWANIPv6FirewallControl1ClientsByURL discovers instances of the service at the given
// NewWANIPv6FirewallControl1Clients is the legacy version of NewWANIPv6FirewallControl1ClientsCtx, but uses
// context.Background() as the context.
func NewWANIPv6FirewallControl1Clients() (clients []*WANIPv6FirewallControl1, errors []error, err error) {
return NewWANIPv6FirewallControl1ClientsCtx(context.Background())
}
// NewWANIPv6FirewallControl1ClientsByURLCtx discovers instances of the service at the given
// URL, and returns clients to any that are found. An error is returned if
// there was an error probing the service.
//
// This is a typical entry calling point into this package when reusing an
// previously discovered service URL.
func NewWANIPv6FirewallControl1ClientsByURL(loc *url.URL) ([]*WANIPv6FirewallControl1, error) {
genericClients, err := goupnp.NewServiceClientsByURL(loc, URN_WANIPv6FirewallControl_1)
func NewWANIPv6FirewallControl1ClientsByURLCtx(ctx context.Context, loc *url.URL) ([]*WANIPv6FirewallControl1, error) {
genericClients, err := goupnp.NewServiceClientsByURLCtx(ctx, loc, URN_WANIPv6FirewallControl_1)
if err != nil {
return nil, err
}
return newWANIPv6FirewallControl1ClientsFromGenericClients(genericClients), nil
}
// NewWANIPv6FirewallControl1ClientsByURL is the legacy version of NewWANIPv6FirewallControl1ClientsByURLCtx, but uses
// context.Background() as the context.
func NewWANIPv6FirewallControl1ClientsByURL(loc *url.URL) ([]*WANIPv6FirewallControl1, error) {
return NewWANIPv6FirewallControl1ClientsByURLCtx(context.Background(), loc)
}
// NewWANIPv6FirewallControl1ClientsFromRootDevice discovers instances of the service in
// a given root device, and returns clients to any that are found. An error is
// returned if there was not at least one instance of the service within the
@@ -5243,35 +5351,47 @@ type WANPOTSLinkConfig1 struct {
goupnp.ServiceClient
}
// NewWANPOTSLinkConfig1Clients discovers instances of the service on the network,
// NewWANPOTSLinkConfig1ClientsCtx discovers instances of the service on the network,
// and returns clients to any that are found. errors will contain an error for
// any devices that replied but which could not be queried, and err will be set
// if the discovery process failed outright.
//
// This is a typical entry calling point into this package.
func NewWANPOTSLinkConfig1Clients() (clients []*WANPOTSLinkConfig1, errors []error, err error) {
func NewWANPOTSLinkConfig1ClientsCtx(ctx context.Context) (clients []*WANPOTSLinkConfig1, errors []error, err error) {
var genericClients []goupnp.ServiceClient
if genericClients, errors, err = goupnp.NewServiceClients(URN_WANPOTSLinkConfig_1); err != nil {
if genericClients, errors, err = goupnp.NewServiceClientsCtx(ctx, URN_WANPOTSLinkConfig_1); err != nil {
return
}
clients = newWANPOTSLinkConfig1ClientsFromGenericClients(genericClients)
return
}
// NewWANPOTSLinkConfig1ClientsByURL discovers instances of the service at the given
// NewWANPOTSLinkConfig1Clients is the legacy version of NewWANPOTSLinkConfig1ClientsCtx, but uses
// context.Background() as the context.
func NewWANPOTSLinkConfig1Clients() (clients []*WANPOTSLinkConfig1, errors []error, err error) {
return NewWANPOTSLinkConfig1ClientsCtx(context.Background())
}
// NewWANPOTSLinkConfig1ClientsByURLCtx discovers instances of the service at the given
// URL, and returns clients to any that are found. An error is returned if
// there was an error probing the service.
//
// This is a typical entry calling point into this package when reusing an
// previously discovered service URL.
func NewWANPOTSLinkConfig1ClientsByURL(loc *url.URL) ([]*WANPOTSLinkConfig1, error) {
genericClients, err := goupnp.NewServiceClientsByURL(loc, URN_WANPOTSLinkConfig_1)
func NewWANPOTSLinkConfig1ClientsByURLCtx(ctx context.Context, loc *url.URL) ([]*WANPOTSLinkConfig1, error) {
genericClients, err := goupnp.NewServiceClientsByURLCtx(ctx, loc, URN_WANPOTSLinkConfig_1)
if err != nil {
return nil, err
}
return newWANPOTSLinkConfig1ClientsFromGenericClients(genericClients), nil
}
// NewWANPOTSLinkConfig1ClientsByURL is the legacy version of NewWANPOTSLinkConfig1ClientsByURLCtx, but uses
// context.Background() as the context.
func NewWANPOTSLinkConfig1ClientsByURL(loc *url.URL) ([]*WANPOTSLinkConfig1, error) {
return NewWANPOTSLinkConfig1ClientsByURLCtx(context.Background(), loc)
}
// NewWANPOTSLinkConfig1ClientsFromRootDevice discovers instances of the service in
// a given root device, and returns clients to any that are found. An error is
// returned if there was not at least one instance of the service within the
@@ -5470,7 +5590,6 @@ func (client *WANPOTSLinkConfig1) GetFclass() (NewFclass string, err error) {
return client.GetFclassCtx(context.Background())
}
//
// Return values:
//
// * NewLinkType: allowed values: PPP_Dialup
@@ -5654,35 +5773,47 @@ type WANPPPConnection1 struct {
goupnp.ServiceClient
}
// NewWANPPPConnection1Clients discovers instances of the service on the network,
// NewWANPPPConnection1ClientsCtx discovers instances of the service on the network,
// and returns clients to any that are found. errors will contain an error for
// any devices that replied but which could not be queried, and err will be set
// if the discovery process failed outright.
//
// This is a typical entry calling point into this package.
func NewWANPPPConnection1Clients() (clients []*WANPPPConnection1, errors []error, err error) {
func NewWANPPPConnection1ClientsCtx(ctx context.Context) (clients []*WANPPPConnection1, errors []error, err error) {
var genericClients []goupnp.ServiceClient
if genericClients, errors, err = goupnp.NewServiceClients(URN_WANPPPConnection_1); err != nil {
if genericClients, errors, err = goupnp.NewServiceClientsCtx(ctx, URN_WANPPPConnection_1); err != nil {
return
}
clients = newWANPPPConnection1ClientsFromGenericClients(genericClients)
return
}
// NewWANPPPConnection1ClientsByURL discovers instances of the service at the given
// NewWANPPPConnection1Clients is the legacy version of NewWANPPPConnection1ClientsCtx, but uses
// context.Background() as the context.
func NewWANPPPConnection1Clients() (clients []*WANPPPConnection1, errors []error, err error) {
return NewWANPPPConnection1ClientsCtx(context.Background())
}
// NewWANPPPConnection1ClientsByURLCtx discovers instances of the service at the given
// URL, and returns clients to any that are found. An error is returned if
// there was an error probing the service.
//
// This is a typical entry calling point into this package when reusing an
// previously discovered service URL.
func NewWANPPPConnection1ClientsByURL(loc *url.URL) ([]*WANPPPConnection1, error) {
genericClients, err := goupnp.NewServiceClientsByURL(loc, URN_WANPPPConnection_1)
func NewWANPPPConnection1ClientsByURLCtx(ctx context.Context, loc *url.URL) ([]*WANPPPConnection1, error) {
genericClients, err := goupnp.NewServiceClientsByURLCtx(ctx, loc, URN_WANPPPConnection_1)
if err != nil {
return nil, err
}
return newWANPPPConnection1ClientsFromGenericClients(genericClients), nil
}
// NewWANPPPConnection1ClientsByURL is the legacy version of NewWANPPPConnection1ClientsByURLCtx, but uses
// context.Background() as the context.
func NewWANPPPConnection1ClientsByURL(loc *url.URL) ([]*WANPPPConnection1, error) {
return NewWANPPPConnection1ClientsByURLCtx(context.Background(), loc)
}
// NewWANPPPConnection1ClientsFromRootDevice discovers instances of the service in
// a given root device, and returns clients to any that are found. An error is
// returned if there was not at least one instance of the service within the
@@ -5951,7 +6082,6 @@ func (client *WANPPPConnection1) GetAutoDisconnectTime() (NewAutoDisconnectTime
return client.GetAutoDisconnectTimeCtx(context.Background())
}
//
// Return values:
//
// * NewPossibleConnectionTypes: allowed values: Unconfigured, IP_Routed, DHCP_Spoofed, PPPoE_Bridged, PPTP_Relay, L2TP_Relay, PPPoE_Relay
@@ -6027,7 +6157,6 @@ func (client *WANPPPConnection1) GetExternalIPAddress() (NewExternalIPAddress st
return client.GetExternalIPAddressCtx(context.Background())
}
//
// Return values:
//
// * NewProtocol: allowed values: TCP, UDP
@@ -6422,7 +6551,6 @@ func (client *WANPPPConnection1) GetSpecificPortMappingEntry(NewRemoteHost strin
)
}
//
// Return values:
//
// * NewConnectionStatus: allowed values: Unconfigured, Connected, Disconnected
+200 -86
View File
@@ -19,8 +19,8 @@ import (
"net/url"
"time"
"github.com/huin/goupnp"
"github.com/huin/goupnp/soap"
"git.cyrilix.bzh/cyrilix/goupnp"
"git.cyrilix.bzh/cyrilix/goupnp/soap"
)
// Hack to avoid Go complaining if time isn't used.
@@ -58,35 +58,47 @@ type LANHostConfigManagement1 struct {
goupnp.ServiceClient
}
// NewLANHostConfigManagement1Clients discovers instances of the service on the network,
// NewLANHostConfigManagement1ClientsCtx discovers instances of the service on the network,
// and returns clients to any that are found. errors will contain an error for
// any devices that replied but which could not be queried, and err will be set
// if the discovery process failed outright.
//
// This is a typical entry calling point into this package.
func NewLANHostConfigManagement1Clients() (clients []*LANHostConfigManagement1, errors []error, err error) {
func NewLANHostConfigManagement1ClientsCtx(ctx context.Context) (clients []*LANHostConfigManagement1, errors []error, err error) {
var genericClients []goupnp.ServiceClient
if genericClients, errors, err = goupnp.NewServiceClients(URN_LANHostConfigManagement_1); err != nil {
if genericClients, errors, err = goupnp.NewServiceClientsCtx(ctx, URN_LANHostConfigManagement_1); err != nil {
return
}
clients = newLANHostConfigManagement1ClientsFromGenericClients(genericClients)
return
}
// NewLANHostConfigManagement1ClientsByURL discovers instances of the service at the given
// NewLANHostConfigManagement1Clients is the legacy version of NewLANHostConfigManagement1ClientsCtx, but uses
// context.Background() as the context.
func NewLANHostConfigManagement1Clients() (clients []*LANHostConfigManagement1, errors []error, err error) {
return NewLANHostConfigManagement1ClientsCtx(context.Background())
}
// NewLANHostConfigManagement1ClientsByURLCtx discovers instances of the service at the given
// URL, and returns clients to any that are found. An error is returned if
// there was an error probing the service.
//
// This is a typical entry calling point into this package when reusing an
// previously discovered service URL.
func NewLANHostConfigManagement1ClientsByURL(loc *url.URL) ([]*LANHostConfigManagement1, error) {
genericClients, err := goupnp.NewServiceClientsByURL(loc, URN_LANHostConfigManagement_1)
func NewLANHostConfigManagement1ClientsByURLCtx(ctx context.Context, loc *url.URL) ([]*LANHostConfigManagement1, error) {
genericClients, err := goupnp.NewServiceClientsByURLCtx(ctx, loc, URN_LANHostConfigManagement_1)
if err != nil {
return nil, err
}
return newLANHostConfigManagement1ClientsFromGenericClients(genericClients), nil
}
// NewLANHostConfigManagement1ClientsByURL is the legacy version of NewLANHostConfigManagement1ClientsByURLCtx, but uses
// context.Background() as the context.
func NewLANHostConfigManagement1ClientsByURL(loc *url.URL) ([]*LANHostConfigManagement1, error) {
return NewLANHostConfigManagement1ClientsByURLCtx(context.Background(), loc)
}
// NewLANHostConfigManagement1ClientsFromRootDevice discovers instances of the service in
// a given root device, and returns clients to any that are found. An error is
// returned if there was not at least one instance of the service within the
@@ -807,35 +819,47 @@ type Layer3Forwarding1 struct {
goupnp.ServiceClient
}
// NewLayer3Forwarding1Clients discovers instances of the service on the network,
// NewLayer3Forwarding1ClientsCtx discovers instances of the service on the network,
// and returns clients to any that are found. errors will contain an error for
// any devices that replied but which could not be queried, and err will be set
// if the discovery process failed outright.
//
// This is a typical entry calling point into this package.
func NewLayer3Forwarding1Clients() (clients []*Layer3Forwarding1, errors []error, err error) {
func NewLayer3Forwarding1ClientsCtx(ctx context.Context) (clients []*Layer3Forwarding1, errors []error, err error) {
var genericClients []goupnp.ServiceClient
if genericClients, errors, err = goupnp.NewServiceClients(URN_Layer3Forwarding_1); err != nil {
if genericClients, errors, err = goupnp.NewServiceClientsCtx(ctx, URN_Layer3Forwarding_1); err != nil {
return
}
clients = newLayer3Forwarding1ClientsFromGenericClients(genericClients)
return
}
// NewLayer3Forwarding1ClientsByURL discovers instances of the service at the given
// NewLayer3Forwarding1Clients is the legacy version of NewLayer3Forwarding1ClientsCtx, but uses
// context.Background() as the context.
func NewLayer3Forwarding1Clients() (clients []*Layer3Forwarding1, errors []error, err error) {
return NewLayer3Forwarding1ClientsCtx(context.Background())
}
// NewLayer3Forwarding1ClientsByURLCtx discovers instances of the service at the given
// URL, and returns clients to any that are found. An error is returned if
// there was an error probing the service.
//
// This is a typical entry calling point into this package when reusing an
// previously discovered service URL.
func NewLayer3Forwarding1ClientsByURL(loc *url.URL) ([]*Layer3Forwarding1, error) {
genericClients, err := goupnp.NewServiceClientsByURL(loc, URN_Layer3Forwarding_1)
func NewLayer3Forwarding1ClientsByURLCtx(ctx context.Context, loc *url.URL) ([]*Layer3Forwarding1, error) {
genericClients, err := goupnp.NewServiceClientsByURLCtx(ctx, loc, URN_Layer3Forwarding_1)
if err != nil {
return nil, err
}
return newLayer3Forwarding1ClientsFromGenericClients(genericClients), nil
}
// NewLayer3Forwarding1ClientsByURL is the legacy version of NewLayer3Forwarding1ClientsByURLCtx, but uses
// context.Background() as the context.
func NewLayer3Forwarding1ClientsByURL(loc *url.URL) ([]*Layer3Forwarding1, error) {
return NewLayer3Forwarding1ClientsByURLCtx(context.Background(), loc)
}
// NewLayer3Forwarding1ClientsFromRootDevice discovers instances of the service in
// a given root device, and returns clients to any that are found. An error is
// returned if there was not at least one instance of the service within the
@@ -938,35 +962,47 @@ type WANCableLinkConfig1 struct {
goupnp.ServiceClient
}
// NewWANCableLinkConfig1Clients discovers instances of the service on the network,
// NewWANCableLinkConfig1ClientsCtx discovers instances of the service on the network,
// and returns clients to any that are found. errors will contain an error for
// any devices that replied but which could not be queried, and err will be set
// if the discovery process failed outright.
//
// This is a typical entry calling point into this package.
func NewWANCableLinkConfig1Clients() (clients []*WANCableLinkConfig1, errors []error, err error) {
func NewWANCableLinkConfig1ClientsCtx(ctx context.Context) (clients []*WANCableLinkConfig1, errors []error, err error) {
var genericClients []goupnp.ServiceClient
if genericClients, errors, err = goupnp.NewServiceClients(URN_WANCableLinkConfig_1); err != nil {
if genericClients, errors, err = goupnp.NewServiceClientsCtx(ctx, URN_WANCableLinkConfig_1); err != nil {
return
}
clients = newWANCableLinkConfig1ClientsFromGenericClients(genericClients)
return
}
// NewWANCableLinkConfig1ClientsByURL discovers instances of the service at the given
// NewWANCableLinkConfig1Clients is the legacy version of NewWANCableLinkConfig1ClientsCtx, but uses
// context.Background() as the context.
func NewWANCableLinkConfig1Clients() (clients []*WANCableLinkConfig1, errors []error, err error) {
return NewWANCableLinkConfig1ClientsCtx(context.Background())
}
// NewWANCableLinkConfig1ClientsByURLCtx discovers instances of the service at the given
// URL, and returns clients to any that are found. An error is returned if
// there was an error probing the service.
//
// This is a typical entry calling point into this package when reusing an
// previously discovered service URL.
func NewWANCableLinkConfig1ClientsByURL(loc *url.URL) ([]*WANCableLinkConfig1, error) {
genericClients, err := goupnp.NewServiceClientsByURL(loc, URN_WANCableLinkConfig_1)
func NewWANCableLinkConfig1ClientsByURLCtx(ctx context.Context, loc *url.URL) ([]*WANCableLinkConfig1, error) {
genericClients, err := goupnp.NewServiceClientsByURLCtx(ctx, loc, URN_WANCableLinkConfig_1)
if err != nil {
return nil, err
}
return newWANCableLinkConfig1ClientsFromGenericClients(genericClients), nil
}
// NewWANCableLinkConfig1ClientsByURL is the legacy version of NewWANCableLinkConfig1ClientsByURLCtx, but uses
// context.Background() as the context.
func NewWANCableLinkConfig1ClientsByURL(loc *url.URL) ([]*WANCableLinkConfig1, error) {
return NewWANCableLinkConfig1ClientsByURLCtx(context.Background(), loc)
}
// NewWANCableLinkConfig1ClientsFromRootDevice discovers instances of the service in
// a given root device, and returns clients to any that are found. An error is
// returned if there was not at least one instance of the service within the
@@ -1025,7 +1061,6 @@ func (client *WANCableLinkConfig1) GetBPIEncryptionEnabled() (NewBPIEncryptionEn
return client.GetBPIEncryptionEnabledCtx(context.Background())
}
//
// Return values:
//
// * NewCableLinkConfigState: allowed values: notReady, dsSyncComplete, usParamAcquired, rangingComplete, ipComplete, todEstablished, paramTransferComplete, registrationComplete, operational, accessDenied
@@ -1137,7 +1172,6 @@ func (client *WANCableLinkConfig1) GetDownstreamFrequency() (NewDownstreamFreque
return client.GetDownstreamFrequencyCtx(context.Background())
}
//
// Return values:
//
// * NewDownstreamModulation: allowed values: 64QAM, 256QAM
@@ -1277,7 +1311,6 @@ func (client *WANCableLinkConfig1) GetUpstreamFrequency() (NewUpstreamFrequency
return client.GetUpstreamFrequencyCtx(context.Background())
}
//
// Return values:
//
// * NewUpstreamModulation: allowed values: QPSK, 16QAM
@@ -1356,35 +1389,47 @@ type WANCommonInterfaceConfig1 struct {
goupnp.ServiceClient
}
// NewWANCommonInterfaceConfig1Clients discovers instances of the service on the network,
// NewWANCommonInterfaceConfig1ClientsCtx discovers instances of the service on the network,
// and returns clients to any that are found. errors will contain an error for
// any devices that replied but which could not be queried, and err will be set
// if the discovery process failed outright.
//
// This is a typical entry calling point into this package.
func NewWANCommonInterfaceConfig1Clients() (clients []*WANCommonInterfaceConfig1, errors []error, err error) {
func NewWANCommonInterfaceConfig1ClientsCtx(ctx context.Context) (clients []*WANCommonInterfaceConfig1, errors []error, err error) {
var genericClients []goupnp.ServiceClient
if genericClients, errors, err = goupnp.NewServiceClients(URN_WANCommonInterfaceConfig_1); err != nil {
if genericClients, errors, err = goupnp.NewServiceClientsCtx(ctx, URN_WANCommonInterfaceConfig_1); err != nil {
return
}
clients = newWANCommonInterfaceConfig1ClientsFromGenericClients(genericClients)
return
}
// NewWANCommonInterfaceConfig1ClientsByURL discovers instances of the service at the given
// NewWANCommonInterfaceConfig1Clients is the legacy version of NewWANCommonInterfaceConfig1ClientsCtx, but uses
// context.Background() as the context.
func NewWANCommonInterfaceConfig1Clients() (clients []*WANCommonInterfaceConfig1, errors []error, err error) {
return NewWANCommonInterfaceConfig1ClientsCtx(context.Background())
}
// NewWANCommonInterfaceConfig1ClientsByURLCtx discovers instances of the service at the given
// URL, and returns clients to any that are found. An error is returned if
// there was an error probing the service.
//
// This is a typical entry calling point into this package when reusing an
// previously discovered service URL.
func NewWANCommonInterfaceConfig1ClientsByURL(loc *url.URL) ([]*WANCommonInterfaceConfig1, error) {
genericClients, err := goupnp.NewServiceClientsByURL(loc, URN_WANCommonInterfaceConfig_1)
func NewWANCommonInterfaceConfig1ClientsByURLCtx(ctx context.Context, loc *url.URL) ([]*WANCommonInterfaceConfig1, error) {
genericClients, err := goupnp.NewServiceClientsByURLCtx(ctx, loc, URN_WANCommonInterfaceConfig_1)
if err != nil {
return nil, err
}
return newWANCommonInterfaceConfig1ClientsFromGenericClients(genericClients), nil
}
// NewWANCommonInterfaceConfig1ClientsByURL is the legacy version of NewWANCommonInterfaceConfig1ClientsByURLCtx, but uses
// context.Background() as the context.
func NewWANCommonInterfaceConfig1ClientsByURL(loc *url.URL) ([]*WANCommonInterfaceConfig1, error) {
return NewWANCommonInterfaceConfig1ClientsByURLCtx(context.Background(), loc)
}
// NewWANCommonInterfaceConfig1ClientsFromRootDevice discovers instances of the service in
// a given root device, and returns clients to any that are found. An error is
// returned if there was not at least one instance of the service within the
@@ -1455,7 +1500,6 @@ func (client *WANCommonInterfaceConfig1) GetActiveConnection(NewActiveConnection
)
}
//
// Return values:
//
// * NewWANAccessType: allowed values: DSL, POTS, Cable, Ethernet
@@ -1541,7 +1585,6 @@ func (client *WANCommonInterfaceConfig1) GetEnabledForInternet() (NewEnabledForI
return client.GetEnabledForInternetCtx(context.Background())
}
//
// Return values:
//
// * NewMaximumActiveConnections: allowed value range: minimum=1, step=1
@@ -1793,35 +1836,47 @@ type WANDSLLinkConfig1 struct {
goupnp.ServiceClient
}
// NewWANDSLLinkConfig1Clients discovers instances of the service on the network,
// NewWANDSLLinkConfig1ClientsCtx discovers instances of the service on the network,
// and returns clients to any that are found. errors will contain an error for
// any devices that replied but which could not be queried, and err will be set
// if the discovery process failed outright.
//
// This is a typical entry calling point into this package.
func NewWANDSLLinkConfig1Clients() (clients []*WANDSLLinkConfig1, errors []error, err error) {
func NewWANDSLLinkConfig1ClientsCtx(ctx context.Context) (clients []*WANDSLLinkConfig1, errors []error, err error) {
var genericClients []goupnp.ServiceClient
if genericClients, errors, err = goupnp.NewServiceClients(URN_WANDSLLinkConfig_1); err != nil {
if genericClients, errors, err = goupnp.NewServiceClientsCtx(ctx, URN_WANDSLLinkConfig_1); err != nil {
return
}
clients = newWANDSLLinkConfig1ClientsFromGenericClients(genericClients)
return
}
// NewWANDSLLinkConfig1ClientsByURL discovers instances of the service at the given
// NewWANDSLLinkConfig1Clients is the legacy version of NewWANDSLLinkConfig1ClientsCtx, but uses
// context.Background() as the context.
func NewWANDSLLinkConfig1Clients() (clients []*WANDSLLinkConfig1, errors []error, err error) {
return NewWANDSLLinkConfig1ClientsCtx(context.Background())
}
// NewWANDSLLinkConfig1ClientsByURLCtx discovers instances of the service at the given
// URL, and returns clients to any that are found. An error is returned if
// there was an error probing the service.
//
// This is a typical entry calling point into this package when reusing an
// previously discovered service URL.
func NewWANDSLLinkConfig1ClientsByURL(loc *url.URL) ([]*WANDSLLinkConfig1, error) {
genericClients, err := goupnp.NewServiceClientsByURL(loc, URN_WANDSLLinkConfig_1)
func NewWANDSLLinkConfig1ClientsByURLCtx(ctx context.Context, loc *url.URL) ([]*WANDSLLinkConfig1, error) {
genericClients, err := goupnp.NewServiceClientsByURLCtx(ctx, loc, URN_WANDSLLinkConfig_1)
if err != nil {
return nil, err
}
return newWANDSLLinkConfig1ClientsFromGenericClients(genericClients), nil
}
// NewWANDSLLinkConfig1ClientsByURL is the legacy version of NewWANDSLLinkConfig1ClientsByURLCtx, but uses
// context.Background() as the context.
func NewWANDSLLinkConfig1ClientsByURL(loc *url.URL) ([]*WANDSLLinkConfig1, error) {
return NewWANDSLLinkConfig1ClientsByURLCtx(context.Background(), loc)
}
// NewWANDSLLinkConfig1ClientsFromRootDevice discovers instances of the service in
// a given root device, and returns clients to any that are found. An error is
// returned if there was not at least one instance of the service within the
@@ -1914,7 +1969,6 @@ func (client *WANDSLLinkConfig1) GetAutoConfig() (NewAutoConfig bool, err error)
return client.GetAutoConfigCtx(context.Background())
}
//
// Return values:
//
// * NewLinkStatus: allowed values: Up, Down
@@ -2213,35 +2267,47 @@ type WANEthernetLinkConfig1 struct {
goupnp.ServiceClient
}
// NewWANEthernetLinkConfig1Clients discovers instances of the service on the network,
// NewWANEthernetLinkConfig1ClientsCtx discovers instances of the service on the network,
// and returns clients to any that are found. errors will contain an error for
// any devices that replied but which could not be queried, and err will be set
// if the discovery process failed outright.
//
// This is a typical entry calling point into this package.
func NewWANEthernetLinkConfig1Clients() (clients []*WANEthernetLinkConfig1, errors []error, err error) {
func NewWANEthernetLinkConfig1ClientsCtx(ctx context.Context) (clients []*WANEthernetLinkConfig1, errors []error, err error) {
var genericClients []goupnp.ServiceClient
if genericClients, errors, err = goupnp.NewServiceClients(URN_WANEthernetLinkConfig_1); err != nil {
if genericClients, errors, err = goupnp.NewServiceClientsCtx(ctx, URN_WANEthernetLinkConfig_1); err != nil {
return
}
clients = newWANEthernetLinkConfig1ClientsFromGenericClients(genericClients)
return
}
// NewWANEthernetLinkConfig1ClientsByURL discovers instances of the service at the given
// NewWANEthernetLinkConfig1Clients is the legacy version of NewWANEthernetLinkConfig1ClientsCtx, but uses
// context.Background() as the context.
func NewWANEthernetLinkConfig1Clients() (clients []*WANEthernetLinkConfig1, errors []error, err error) {
return NewWANEthernetLinkConfig1ClientsCtx(context.Background())
}
// NewWANEthernetLinkConfig1ClientsByURLCtx discovers instances of the service at the given
// URL, and returns clients to any that are found. An error is returned if
// there was an error probing the service.
//
// This is a typical entry calling point into this package when reusing an
// previously discovered service URL.
func NewWANEthernetLinkConfig1ClientsByURL(loc *url.URL) ([]*WANEthernetLinkConfig1, error) {
genericClients, err := goupnp.NewServiceClientsByURL(loc, URN_WANEthernetLinkConfig_1)
func NewWANEthernetLinkConfig1ClientsByURLCtx(ctx context.Context, loc *url.URL) ([]*WANEthernetLinkConfig1, error) {
genericClients, err := goupnp.NewServiceClientsByURLCtx(ctx, loc, URN_WANEthernetLinkConfig_1)
if err != nil {
return nil, err
}
return newWANEthernetLinkConfig1ClientsFromGenericClients(genericClients), nil
}
// NewWANEthernetLinkConfig1ClientsByURL is the legacy version of NewWANEthernetLinkConfig1ClientsByURLCtx, but uses
// context.Background() as the context.
func NewWANEthernetLinkConfig1ClientsByURL(loc *url.URL) ([]*WANEthernetLinkConfig1, error) {
return NewWANEthernetLinkConfig1ClientsByURLCtx(context.Background(), loc)
}
// NewWANEthernetLinkConfig1ClientsFromRootDevice discovers instances of the service in
// a given root device, and returns clients to any that are found. An error is
// returned if there was not at least one instance of the service within the
@@ -2266,7 +2332,6 @@ func newWANEthernetLinkConfig1ClientsFromGenericClients(genericClients []goupnp.
return clients
}
//
// Return values:
//
// * NewEthernetLinkStatus: allowed values: Up, Down
@@ -2311,35 +2376,47 @@ type WANIPConnection1 struct {
goupnp.ServiceClient
}
// NewWANIPConnection1Clients discovers instances of the service on the network,
// NewWANIPConnection1ClientsCtx discovers instances of the service on the network,
// and returns clients to any that are found. errors will contain an error for
// any devices that replied but which could not be queried, and err will be set
// if the discovery process failed outright.
//
// This is a typical entry calling point into this package.
func NewWANIPConnection1Clients() (clients []*WANIPConnection1, errors []error, err error) {
func NewWANIPConnection1ClientsCtx(ctx context.Context) (clients []*WANIPConnection1, errors []error, err error) {
var genericClients []goupnp.ServiceClient
if genericClients, errors, err = goupnp.NewServiceClients(URN_WANIPConnection_1); err != nil {
if genericClients, errors, err = goupnp.NewServiceClientsCtx(ctx, URN_WANIPConnection_1); err != nil {
return
}
clients = newWANIPConnection1ClientsFromGenericClients(genericClients)
return
}
// NewWANIPConnection1ClientsByURL discovers instances of the service at the given
// NewWANIPConnection1Clients is the legacy version of NewWANIPConnection1ClientsCtx, but uses
// context.Background() as the context.
func NewWANIPConnection1Clients() (clients []*WANIPConnection1, errors []error, err error) {
return NewWANIPConnection1ClientsCtx(context.Background())
}
// NewWANIPConnection1ClientsByURLCtx discovers instances of the service at the given
// URL, and returns clients to any that are found. An error is returned if
// there was an error probing the service.
//
// This is a typical entry calling point into this package when reusing an
// previously discovered service URL.
func NewWANIPConnection1ClientsByURL(loc *url.URL) ([]*WANIPConnection1, error) {
genericClients, err := goupnp.NewServiceClientsByURL(loc, URN_WANIPConnection_1)
func NewWANIPConnection1ClientsByURLCtx(ctx context.Context, loc *url.URL) ([]*WANIPConnection1, error) {
genericClients, err := goupnp.NewServiceClientsByURLCtx(ctx, loc, URN_WANIPConnection_1)
if err != nil {
return nil, err
}
return newWANIPConnection1ClientsFromGenericClients(genericClients), nil
}
// NewWANIPConnection1ClientsByURL is the legacy version of NewWANIPConnection1ClientsByURLCtx, but uses
// context.Background() as the context.
func NewWANIPConnection1ClientsByURL(loc *url.URL) ([]*WANIPConnection1, error) {
return NewWANIPConnection1ClientsByURLCtx(context.Background(), loc)
}
// NewWANIPConnection1ClientsFromRootDevice discovers instances of the service in
// a given root device, and returns clients to any that are found. An error is
// returned if there was not at least one instance of the service within the
@@ -2565,7 +2642,6 @@ func (client *WANIPConnection1) GetAutoDisconnectTime() (NewAutoDisconnectTime u
return client.GetAutoDisconnectTimeCtx(context.Background())
}
//
// Return values:
//
// * NewPossibleConnectionTypes: allowed values: Unconfigured, IP_Routed, IP_Bridged
@@ -2641,7 +2717,6 @@ func (client *WANIPConnection1) GetExternalIPAddress() (NewExternalIPAddress str
return client.GetExternalIPAddressCtx(context.Background())
}
//
// Return values:
//
// * NewProtocol: allowed values: TCP, UDP
@@ -2862,7 +2937,6 @@ func (client *WANIPConnection1) GetSpecificPortMappingEntry(NewRemoteHost string
)
}
//
// Return values:
//
// * NewConnectionStatus: allowed values: Unconfigured, Connected, Disconnected
@@ -3157,35 +3231,47 @@ type WANIPConnection2 struct {
goupnp.ServiceClient
}
// NewWANIPConnection2Clients discovers instances of the service on the network,
// NewWANIPConnection2ClientsCtx discovers instances of the service on the network,
// and returns clients to any that are found. errors will contain an error for
// any devices that replied but which could not be queried, and err will be set
// if the discovery process failed outright.
//
// This is a typical entry calling point into this package.
func NewWANIPConnection2Clients() (clients []*WANIPConnection2, errors []error, err error) {
func NewWANIPConnection2ClientsCtx(ctx context.Context) (clients []*WANIPConnection2, errors []error, err error) {
var genericClients []goupnp.ServiceClient
if genericClients, errors, err = goupnp.NewServiceClients(URN_WANIPConnection_2); err != nil {
if genericClients, errors, err = goupnp.NewServiceClientsCtx(ctx, URN_WANIPConnection_2); err != nil {
return
}
clients = newWANIPConnection2ClientsFromGenericClients(genericClients)
return
}
// NewWANIPConnection2ClientsByURL discovers instances of the service at the given
// NewWANIPConnection2Clients is the legacy version of NewWANIPConnection2ClientsCtx, but uses
// context.Background() as the context.
func NewWANIPConnection2Clients() (clients []*WANIPConnection2, errors []error, err error) {
return NewWANIPConnection2ClientsCtx(context.Background())
}
// NewWANIPConnection2ClientsByURLCtx discovers instances of the service at the given
// URL, and returns clients to any that are found. An error is returned if
// there was an error probing the service.
//
// This is a typical entry calling point into this package when reusing an
// previously discovered service URL.
func NewWANIPConnection2ClientsByURL(loc *url.URL) ([]*WANIPConnection2, error) {
genericClients, err := goupnp.NewServiceClientsByURL(loc, URN_WANIPConnection_2)
func NewWANIPConnection2ClientsByURLCtx(ctx context.Context, loc *url.URL) ([]*WANIPConnection2, error) {
genericClients, err := goupnp.NewServiceClientsByURLCtx(ctx, loc, URN_WANIPConnection_2)
if err != nil {
return nil, err
}
return newWANIPConnection2ClientsFromGenericClients(genericClients), nil
}
// NewWANIPConnection2ClientsByURL is the legacy version of NewWANIPConnection2ClientsByURLCtx, but uses
// context.Background() as the context.
func NewWANIPConnection2ClientsByURL(loc *url.URL) ([]*WANIPConnection2, error) {
return NewWANIPConnection2ClientsByURLCtx(context.Background(), loc)
}
// NewWANIPConnection2ClientsFromRootDevice discovers instances of the service in
// a given root device, and returns clients to any that are found. An error is
// returned if there was not at least one instance of the service within the
@@ -3568,7 +3654,6 @@ func (client *WANIPConnection2) GetAutoDisconnectTime() (NewAutoDisconnectTime u
return client.GetAutoDisconnectTimeCtx(context.Background())
}
//
// Return values:
//
// * NewConnectionType: allowed values: Unconfigured, IP_Routed, IP_Bridged
@@ -3644,7 +3729,6 @@ func (client *WANIPConnection2) GetExternalIPAddress() (NewExternalIPAddress str
return client.GetExternalIPAddressCtx(context.Background())
}
//
// Return values:
//
// * NewProtocol: allowed values: TCP, UDP
@@ -3870,7 +3954,6 @@ func (client *WANIPConnection2) GetNATRSIPStatus() (NewRSIPAvailable bool, NewNA
//
// * NewProtocol: allowed values: TCP, UDP
//
// Return values:
//
// * NewInternalPort: allowed value range: minimum=1, maximum=65535
@@ -3946,7 +4029,6 @@ func (client *WANIPConnection2) GetSpecificPortMappingEntry(NewRemoteHost string
)
}
//
// Return values:
//
// * NewConnectionStatus: allowed values: Unconfigured, Connected, Disconnected
@@ -4246,35 +4328,47 @@ type WANIPv6FirewallControl1 struct {
goupnp.ServiceClient
}
// NewWANIPv6FirewallControl1Clients discovers instances of the service on the network,
// NewWANIPv6FirewallControl1ClientsCtx discovers instances of the service on the network,
// and returns clients to any that are found. errors will contain an error for
// any devices that replied but which could not be queried, and err will be set
// if the discovery process failed outright.
//
// This is a typical entry calling point into this package.
func NewWANIPv6FirewallControl1Clients() (clients []*WANIPv6FirewallControl1, errors []error, err error) {
func NewWANIPv6FirewallControl1ClientsCtx(ctx context.Context) (clients []*WANIPv6FirewallControl1, errors []error, err error) {
var genericClients []goupnp.ServiceClient
if genericClients, errors, err = goupnp.NewServiceClients(URN_WANIPv6FirewallControl_1); err != nil {
if genericClients, errors, err = goupnp.NewServiceClientsCtx(ctx, URN_WANIPv6FirewallControl_1); err != nil {
return
}
clients = newWANIPv6FirewallControl1ClientsFromGenericClients(genericClients)
return
}
// NewWANIPv6FirewallControl1ClientsByURL discovers instances of the service at the given
// NewWANIPv6FirewallControl1Clients is the legacy version of NewWANIPv6FirewallControl1ClientsCtx, but uses
// context.Background() as the context.
func NewWANIPv6FirewallControl1Clients() (clients []*WANIPv6FirewallControl1, errors []error, err error) {
return NewWANIPv6FirewallControl1ClientsCtx(context.Background())
}
// NewWANIPv6FirewallControl1ClientsByURLCtx discovers instances of the service at the given
// URL, and returns clients to any that are found. An error is returned if
// there was an error probing the service.
//
// This is a typical entry calling point into this package when reusing an
// previously discovered service URL.
func NewWANIPv6FirewallControl1ClientsByURL(loc *url.URL) ([]*WANIPv6FirewallControl1, error) {
genericClients, err := goupnp.NewServiceClientsByURL(loc, URN_WANIPv6FirewallControl_1)
func NewWANIPv6FirewallControl1ClientsByURLCtx(ctx context.Context, loc *url.URL) ([]*WANIPv6FirewallControl1, error) {
genericClients, err := goupnp.NewServiceClientsByURLCtx(ctx, loc, URN_WANIPv6FirewallControl_1)
if err != nil {
return nil, err
}
return newWANIPv6FirewallControl1ClientsFromGenericClients(genericClients), nil
}
// NewWANIPv6FirewallControl1ClientsByURL is the legacy version of NewWANIPv6FirewallControl1ClientsByURLCtx, but uses
// context.Background() as the context.
func NewWANIPv6FirewallControl1ClientsByURL(loc *url.URL) ([]*WANIPv6FirewallControl1, error) {
return NewWANIPv6FirewallControl1ClientsByURLCtx(context.Background(), loc)
}
// NewWANIPv6FirewallControl1ClientsFromRootDevice discovers instances of the service in
// a given root device, and returns clients to any that are found. An error is
// returned if there was not at least one instance of the service within the
@@ -4656,35 +4750,47 @@ type WANPOTSLinkConfig1 struct {
goupnp.ServiceClient
}
// NewWANPOTSLinkConfig1Clients discovers instances of the service on the network,
// NewWANPOTSLinkConfig1ClientsCtx discovers instances of the service on the network,
// and returns clients to any that are found. errors will contain an error for
// any devices that replied but which could not be queried, and err will be set
// if the discovery process failed outright.
//
// This is a typical entry calling point into this package.
func NewWANPOTSLinkConfig1Clients() (clients []*WANPOTSLinkConfig1, errors []error, err error) {
func NewWANPOTSLinkConfig1ClientsCtx(ctx context.Context) (clients []*WANPOTSLinkConfig1, errors []error, err error) {
var genericClients []goupnp.ServiceClient
if genericClients, errors, err = goupnp.NewServiceClients(URN_WANPOTSLinkConfig_1); err != nil {
if genericClients, errors, err = goupnp.NewServiceClientsCtx(ctx, URN_WANPOTSLinkConfig_1); err != nil {
return
}
clients = newWANPOTSLinkConfig1ClientsFromGenericClients(genericClients)
return
}
// NewWANPOTSLinkConfig1ClientsByURL discovers instances of the service at the given
// NewWANPOTSLinkConfig1Clients is the legacy version of NewWANPOTSLinkConfig1ClientsCtx, but uses
// context.Background() as the context.
func NewWANPOTSLinkConfig1Clients() (clients []*WANPOTSLinkConfig1, errors []error, err error) {
return NewWANPOTSLinkConfig1ClientsCtx(context.Background())
}
// NewWANPOTSLinkConfig1ClientsByURLCtx discovers instances of the service at the given
// URL, and returns clients to any that are found. An error is returned if
// there was an error probing the service.
//
// This is a typical entry calling point into this package when reusing an
// previously discovered service URL.
func NewWANPOTSLinkConfig1ClientsByURL(loc *url.URL) ([]*WANPOTSLinkConfig1, error) {
genericClients, err := goupnp.NewServiceClientsByURL(loc, URN_WANPOTSLinkConfig_1)
func NewWANPOTSLinkConfig1ClientsByURLCtx(ctx context.Context, loc *url.URL) ([]*WANPOTSLinkConfig1, error) {
genericClients, err := goupnp.NewServiceClientsByURLCtx(ctx, loc, URN_WANPOTSLinkConfig_1)
if err != nil {
return nil, err
}
return newWANPOTSLinkConfig1ClientsFromGenericClients(genericClients), nil
}
// NewWANPOTSLinkConfig1ClientsByURL is the legacy version of NewWANPOTSLinkConfig1ClientsByURLCtx, but uses
// context.Background() as the context.
func NewWANPOTSLinkConfig1ClientsByURL(loc *url.URL) ([]*WANPOTSLinkConfig1, error) {
return NewWANPOTSLinkConfig1ClientsByURLCtx(context.Background(), loc)
}
// NewWANPOTSLinkConfig1ClientsFromRootDevice discovers instances of the service in
// a given root device, and returns clients to any that are found. An error is
// returned if there was not at least one instance of the service within the
@@ -4883,7 +4989,6 @@ func (client *WANPOTSLinkConfig1) GetFclass() (NewFclass string, err error) {
return client.GetFclassCtx(context.Background())
}
//
// Return values:
//
// * NewLinkType: allowed values: PPP_Dialup
@@ -5067,35 +5172,47 @@ type WANPPPConnection1 struct {
goupnp.ServiceClient
}
// NewWANPPPConnection1Clients discovers instances of the service on the network,
// NewWANPPPConnection1ClientsCtx discovers instances of the service on the network,
// and returns clients to any that are found. errors will contain an error for
// any devices that replied but which could not be queried, and err will be set
// if the discovery process failed outright.
//
// This is a typical entry calling point into this package.
func NewWANPPPConnection1Clients() (clients []*WANPPPConnection1, errors []error, err error) {
func NewWANPPPConnection1ClientsCtx(ctx context.Context) (clients []*WANPPPConnection1, errors []error, err error) {
var genericClients []goupnp.ServiceClient
if genericClients, errors, err = goupnp.NewServiceClients(URN_WANPPPConnection_1); err != nil {
if genericClients, errors, err = goupnp.NewServiceClientsCtx(ctx, URN_WANPPPConnection_1); err != nil {
return
}
clients = newWANPPPConnection1ClientsFromGenericClients(genericClients)
return
}
// NewWANPPPConnection1ClientsByURL discovers instances of the service at the given
// NewWANPPPConnection1Clients is the legacy version of NewWANPPPConnection1ClientsCtx, but uses
// context.Background() as the context.
func NewWANPPPConnection1Clients() (clients []*WANPPPConnection1, errors []error, err error) {
return NewWANPPPConnection1ClientsCtx(context.Background())
}
// NewWANPPPConnection1ClientsByURLCtx discovers instances of the service at the given
// URL, and returns clients to any that are found. An error is returned if
// there was an error probing the service.
//
// This is a typical entry calling point into this package when reusing an
// previously discovered service URL.
func NewWANPPPConnection1ClientsByURL(loc *url.URL) ([]*WANPPPConnection1, error) {
genericClients, err := goupnp.NewServiceClientsByURL(loc, URN_WANPPPConnection_1)
func NewWANPPPConnection1ClientsByURLCtx(ctx context.Context, loc *url.URL) ([]*WANPPPConnection1, error) {
genericClients, err := goupnp.NewServiceClientsByURLCtx(ctx, loc, URN_WANPPPConnection_1)
if err != nil {
return nil, err
}
return newWANPPPConnection1ClientsFromGenericClients(genericClients), nil
}
// NewWANPPPConnection1ClientsByURL is the legacy version of NewWANPPPConnection1ClientsByURLCtx, but uses
// context.Background() as the context.
func NewWANPPPConnection1ClientsByURL(loc *url.URL) ([]*WANPPPConnection1, error) {
return NewWANPPPConnection1ClientsByURLCtx(context.Background(), loc)
}
// NewWANPPPConnection1ClientsFromRootDevice discovers instances of the service in
// a given root device, and returns clients to any that are found. An error is
// returned if there was not at least one instance of the service within the
@@ -5364,7 +5481,6 @@ func (client *WANPPPConnection1) GetAutoDisconnectTime() (NewAutoDisconnectTime
return client.GetAutoDisconnectTimeCtx(context.Background())
}
//
// Return values:
//
// * NewPossibleConnectionTypes: allowed values: Unconfigured, IP_Routed, DHCP_Spoofed, PPPoE_Bridged, PPTP_Relay, L2TP_Relay, PPPoE_Relay
@@ -5440,7 +5556,6 @@ func (client *WANPPPConnection1) GetExternalIPAddress() (NewExternalIPAddress st
return client.GetExternalIPAddressCtx(context.Background())
}
//
// Return values:
//
// * NewProtocol: allowed values: TCP, UDP
@@ -5835,7 +5950,6 @@ func (client *WANPPPConnection1) GetSpecificPortMappingEntry(NewRemoteHost strin
)
}
//
// Return values:
//
// * NewConnectionStatus: allowed values: Unconfigured, Connected, Disconnected
+2
View File
@@ -0,0 +1,2 @@
//go:generate goupnpdcpgen -dcp_name openhome -code_tmpl_file ../dcps.gotemplate
package openhome
File diff suppressed because it is too large Load Diff
+13 -5
View File
@@ -3,14 +3,15 @@
package goupnp
import (
"context"
"encoding/xml"
"errors"
"fmt"
"net/url"
"strings"
"github.com/huin/goupnp/scpd"
"github.com/huin/goupnp/soap"
"git.cyrilix.bzh/cyrilix/goupnp/scpd"
"git.cyrilix.bzh/cyrilix/goupnp/soap"
)
const (
@@ -51,6 +52,7 @@ type Device struct {
ModelDescription string `xml:"modelDescription"`
ModelName string `xml:"modelName"`
ModelNumber string `xml:"modelNumber"`
ModelType string `xml:"modelType"`
ModelURL URLField `xml:"modelURL"`
SerialNumber string `xml:"serialNumber"`
UDN string `xml:"UDN"`
@@ -148,19 +150,25 @@ func (srv *Service) String() string {
return fmt.Sprintf("Service ID %s : %s", srv.ServiceId, srv.ServiceType)
}
// RequestSCPD requests the SCPD (soap actions and state variables description)
// RequestSCPDCtx requests the SCPD (soap actions and state variables description)
// for the service.
func (srv *Service) RequestSCPD() (*scpd.SCPD, error) {
func (srv *Service) RequestSCPDCtx(ctx context.Context) (*scpd.SCPD, error) {
if !srv.SCPDURL.Ok {
return nil, errors.New("bad/missing SCPD URL, or no URLBase has been set")
}
s := new(scpd.SCPD)
if err := requestXml(srv.SCPDURL.URL.String(), scpd.SCPDXMLNamespace, s); err != nil {
if err := requestXml(ctx, srv.SCPDURL.URL.String(), scpd.SCPDXMLNamespace, s); err != nil {
return nil, err
}
return s, nil
}
// RequestSCPD is the legacy version of RequestSCPDCtx, but uses
// context.Background() as the context.
func (srv *Service) RequestSCPD() (*scpd.SCPD, error) {
return srv.RequestSCPDCtx(context.Background())
}
// RequestSCDP is for compatibility only, prefer RequestSCPD. This was a
// misspelling of RequestSCDP.
func (srv *Service) RequestSCDP() (*scpd.SCPD, error) {
+3 -3
View File
@@ -5,9 +5,9 @@ import (
"net/url"
"os"
"github.com/huin/goupnp"
"github.com/huin/goupnp/dcps/internetgateway1"
"github.com/huin/goupnp/dcps/internetgateway2"
"git.cyrilix.bzh/cyrilix/goupnp"
"git.cyrilix.bzh/cyrilix/goupnp/dcps/internetgateway1"
"git.cyrilix.bzh/cyrilix/goupnp/dcps/internetgateway2"
)
// Use discovered WANPPPConnection1 services to find external IP addresses.
+3 -3
View File
@@ -1,5 +1,5 @@
module github.com/huin/goupnp
module git.cyrilix.bzh/cyrilix/goupnp
go 1.14
go 1.22
require golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
require golang.org/x/sync v0.7.0
+2 -2
View File
@@ -1,2 +1,2 @@
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
+3 -1
View File
@@ -1,4 +1,6 @@
go 1.18
go 1.22
toolchain go1.22.5
use (
.
+6
View File
@@ -0,0 +1,6 @@
golang.org/x/mod v0.6.0 h1:b9gGHsz9/HhJ3HF5DHQytPpuwocVTChQJK3AvoLRD5I=
golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI=
golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/tools v0.2.0 h1:G6AHpWxTMGY1KyEYoAQ5WTtIekUUvDNjan3ugu60JvE=
golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA=
+35 -13
View File
@@ -15,6 +15,7 @@
package goupnp
import (
"context"
"encoding/xml"
"fmt"
"io"
@@ -23,8 +24,8 @@ import (
"net/url"
"time"
"github.com/huin/goupnp/httpu"
"github.com/huin/goupnp/ssdp"
"git.cyrilix.bzh/cyrilix/goupnp/httpu"
"git.cyrilix.bzh/cyrilix/goupnp/ssdp"
)
// ContextError is an error that wraps an error with some context information.
@@ -72,19 +73,22 @@ type MaybeRootDevice struct {
Err error
}
// DiscoverDevices attempts to find targets of the given type. This is
// DiscoverDevicesCtx attempts to find targets of the given type. This is
// typically the entry-point for this package. searchTarget is typically a URN
// in the form "urn:schemas-upnp-org:device:..." or
// "urn:schemas-upnp-org:service:...". A single error is returned for errors
// while attempting to send the query. An error or RootDevice is returned for
// each discovered RootDevice.
func DiscoverDevices(searchTarget string) ([]MaybeRootDevice, error) {
func DiscoverDevicesCtx(ctx context.Context, searchTarget string) ([]MaybeRootDevice, error) {
hc, hcCleanup, err := httpuClient()
if err != nil {
return nil, err
}
defer hcCleanup()
responses, err := ssdp.SSDPRawSearch(hc, string(searchTarget), 2, 3)
searchCtx, cancel := context.WithTimeout(ctx, 2*time.Second)
defer cancel()
responses, err := ssdp.RawSearch(searchCtx, hc, string(searchTarget), 3)
if err != nil {
return nil, err
}
@@ -99,7 +103,7 @@ func DiscoverDevices(searchTarget string) ([]MaybeRootDevice, error) {
continue
}
maybe.Location = loc
if root, err := DeviceByURL(loc); err != nil {
if root, err := DeviceByURLCtx(ctx, loc); err != nil {
maybe.Err = err
} else {
maybe.Root = root
@@ -112,10 +116,16 @@ func DiscoverDevices(searchTarget string) ([]MaybeRootDevice, error) {
return results, nil
}
func DeviceByURL(loc *url.URL) (*RootDevice, error) {
// DiscoverDevices is the legacy version of DiscoverDevicesCtx, but uses
// context.Background() as the context.
func DiscoverDevices(searchTarget string) ([]MaybeRootDevice, error) {
return DiscoverDevicesCtx(context.Background(), searchTarget)
}
func DeviceByURLCtx(ctx context.Context, loc *url.URL) (*RootDevice, error) {
locStr := loc.String()
root := new(RootDevice)
if err := requestXml(locStr, DeviceXMLNamespace, root); err != nil {
if err := requestXml(ctx, locStr, DeviceXMLNamespace, root); err != nil {
return nil, ContextError{fmt.Sprintf("error requesting root device details from %q", locStr), err}
}
var urlBaseStr string
@@ -132,17 +142,29 @@ func DeviceByURL(loc *url.URL) (*RootDevice, error) {
return root, nil
}
func DeviceByURL(loc *url.URL) (*RootDevice, error) {
return DeviceByURLCtx(context.Background(), loc)
}
// CharsetReaderDefault specifies the charset reader used while decoding the output
// from a UPnP server. It can be modified in an init function to allow for non-utf8 encodings,
// but should not be changed after requesting clients.
var CharsetReaderDefault func(charset string, input io.Reader) (io.Reader, error)
func requestXml(url string, defaultSpace string, doc interface{}) error {
timeout := time.Duration(3 * time.Second)
client := http.Client{
Timeout: timeout,
// HTTPClient specifies the http.Client object used when fetching the XML from the UPnP server.
// HTTPClient defaults the http.DefaultClient. This may be overridden by the importing application.
var HTTPClientDefault = http.DefaultClient
func requestXml(ctx context.Context, url string, defaultSpace string, doc interface{}) error {
ctx, cancel := context.WithTimeout(ctx, 3*time.Second)
defer cancel()
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
if err != nil {
return err
}
resp, err := client.Get(url)
resp, err := HTTPClientDefault.Do(req)
if err != nil {
return err
}
+61 -1
View File
@@ -3,6 +3,7 @@ package httpu
import (
"bufio"
"bytes"
"context"
"errors"
"fmt"
"log"
@@ -26,6 +27,27 @@ type ClientInterface interface {
) ([]*http.Response, error)
}
// ClientInterfaceCtx is the equivalent of ClientInterface, except with methods
// taking a context.Context parameter.
type ClientInterfaceCtx interface {
// DoWithContext performs a request. If the input request has a
// deadline, then that value will be used as the timeout for how long
// to wait before returning the responses that were received. If the
// request's context is canceled, this method will return immediately.
//
// If the request's context is never canceled, and does not have a
// deadline, then this function WILL NEVER RETURN. You MUST set an
// appropriate deadline on the context, or otherwise cancel it when you
// want to finish an operation.
//
// An error is only returned for failing to send the request. Failures
// in receipt simply do not add to the resulting responses.
DoWithContext(
req *http.Request,
numSends int,
) ([]*http.Response, error)
}
// HTTPUClient is a client for dealing with HTTPU (HTTP over UDP). Its typical
// function is for HTTPMU, and particularly SSDP.
type HTTPUClient struct {
@@ -34,6 +56,7 @@ type HTTPUClient struct {
}
var _ ClientInterface = &HTTPUClient{}
var _ ClientInterfaceCtx = &HTTPUClient{}
// NewHTTPUClient creates a new HTTPUClient, opening up a new UDP socket for the
// purpose.
@@ -75,6 +98,25 @@ func (httpu *HTTPUClient) Do(
req *http.Request,
timeout time.Duration,
numSends int,
) ([]*http.Response, error) {
ctx := req.Context()
if timeout > 0 {
var cancel func()
ctx, cancel = context.WithTimeout(ctx, timeout)
defer cancel()
req = req.WithContext(ctx)
}
return httpu.DoWithContext(req, numSends)
}
// DoWithContext implements ClientInterfaceCtx.DoWithContext.
//
// Make sure to read the documentation on the ClientInterfaceCtx interface
// regarding cancellation!
func (httpu *HTTPUClient) DoWithContext(
req *http.Request,
numSends int,
) ([]*http.Response, error) {
httpu.connLock.Lock()
defer httpu.connLock.Unlock()
@@ -101,9 +143,27 @@ func (httpu *HTTPUClient) Do(
if err != nil {
return nil, err
}
if err = httpu.conn.SetDeadline(time.Now().Add(timeout)); err != nil {
// Handle context deadline/timeout
ctx := req.Context()
deadline, ok := ctx.Deadline()
if ok {
if err = httpu.conn.SetDeadline(deadline); err != nil {
return nil, err
}
}
// Handle context cancelation
done := make(chan struct{})
defer close(done)
go func() {
select {
case <-ctx.Done():
// if context is cancelled, stop any connections by setting time in the past.
httpu.conn.SetDeadline(time.Now().Add(-time.Second))
case <-done:
}
}()
// Send request.
for i := 0; i < numSends; i++ {
+62
View File
@@ -68,3 +68,65 @@ func (mc *MultiClient) sendRequests(
}
return tasks.Wait()
}
// MultiClientCtx dispatches requests out to all the delegated clients.
type MultiClientCtx struct {
// The HTTPU clients to delegate to.
delegates []ClientInterfaceCtx
}
var _ ClientInterfaceCtx = &MultiClientCtx{}
// NewMultiClient creates a new MultiClient that delegates to all the given
// clients.
func NewMultiClientCtx(delegates []ClientInterfaceCtx) *MultiClientCtx {
return &MultiClientCtx{
delegates: delegates,
}
}
// DoWithContext implements ClientInterfaceCtx.DoWithContext.
func (mc *MultiClientCtx) DoWithContext(
req *http.Request,
numSends int,
) ([]*http.Response, error) {
tasks, ctx := errgroup.WithContext(req.Context())
req = req.WithContext(ctx) // so we cancel if the errgroup errors
results := make(chan []*http.Response)
// For each client, send the request to it and collect results.
tasks.Go(func() error {
defer close(results)
return mc.sendRequestsCtx(results, req, numSends)
})
var responses []*http.Response
tasks.Go(func() error {
for rs := range results {
responses = append(responses, rs...)
}
return nil
})
return responses, tasks.Wait()
}
func (mc *MultiClientCtx) sendRequestsCtx(
results chan<- []*http.Response,
req *http.Request,
numSends int,
) error {
tasks := &errgroup.Group{}
for _, d := range mc.delegates {
d := d // copy for closure
tasks.Go(func() error {
responses, err := d.DoWithContext(req, numSends)
if err != nil {
return err
}
results <- responses
return nil
})
}
return tasks.Wait()
}
+13 -7
View File
@@ -7,6 +7,7 @@ import (
"net"
"net/http"
"regexp"
"sync"
)
const (
@@ -73,20 +74,25 @@ func (srv *Server) Serve(l net.PacketConn) error {
if srv.MaxMessageBytes != 0 {
maxMessageBytes = srv.MaxMessageBytes
}
bufPool := &sync.Pool{
New: func() interface{} {
return make([]byte, maxMessageBytes)
},
}
for {
buf := make([]byte, maxMessageBytes)
buf := bufPool.Get().([]byte)
n, peerAddr, err := l.ReadFrom(buf)
if err != nil {
return err
}
buf = buf[:n]
go func(buf []byte, peerAddr net.Addr) {
go func() {
defer bufPool.Put(buf)
// At least one router's UPnP implementation has added a trailing space
// after "HTTP/1.1" - trim it.
buf = trailingWhitespaceRx.ReplaceAllLiteral(buf, crlf)
reqBuf := trailingWhitespaceRx.ReplaceAllLiteral(buf[:n], crlf)
req, err := http.ReadRequest(bufio.NewReader(bytes.NewBuffer(buf)))
req, err := http.ReadRequest(bufio.NewReader(bytes.NewBuffer(reqBuf)))
if err != nil {
log.Printf("httpu: Failed to parse request: %v", err)
return
@@ -94,7 +100,7 @@ func (srv *Server) Serve(l net.PacketConn) error {
req.RemoteAddr = peerAddr.String()
srv.Handler.ServeMessage(req)
// No need to call req.Body.Close - underlying reader is bytes.Buffer.
}(buf, peerAddr)
}()
}
}
+4 -4
View File
@@ -4,20 +4,20 @@ import (
"io"
"net"
"github.com/huin/goupnp/httpu"
"git.cyrilix.bzh/cyrilix/goupnp/httpu"
)
// httpuClient creates a HTTPU client that multiplexes to all multicast-capable
// IPv4 addresses on the host. Returns a function to clean up once the client is
// no longer required.
func httpuClient() (httpu.ClientInterface, func(), error) {
func httpuClient() (httpu.ClientInterfaceCtx, func(), error) {
addrs, err := localIPv4MCastAddrs()
if err != nil {
return nil, nil, ctxError(err, "requesting host IPv4 addresses")
}
closers := make([]io.Closer, 0, len(addrs))
delegates := make([]httpu.ClientInterface, 0, len(addrs))
delegates := make([]httpu.ClientInterfaceCtx, 0, len(addrs))
for _, addr := range addrs {
c, err := httpu.NewHTTPUClientAddr(addr)
if err != nil {
@@ -34,7 +34,7 @@ func httpuClient() (httpu.ClientInterface, func(), error) {
}
}
return httpu.NewMultiClient(delegates), closer, nil
return httpu.NewMultiClientCtx(delegates), closer, nil
}
// localIPv2MCastAddrs returns the set of IPv4 addresses on multicast-able
+180
View File
@@ -0,0 +1,180 @@
<?xml version="1.0" encoding="utf-8"?>
<scpd xmlns="urn:schemas-upnp-org:service-1-0">
<specVersion>
<major>1</major>
<minor>0</minor>
</specVersion>
<actionList>
<action>
<name>Set</name>
<argumentList>
<argument>
<name>Id</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_String</relatedStateVariable>
</argument>
<argument>
<name>UserName</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_String</relatedStateVariable>
</argument>
<argument>
<name>Password</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_Binary</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>Clear</name>
<argumentList>
<argument>
<name>Id</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_String</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>SetEnabled</name>
<argumentList>
<argument>
<name>Id</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_String</relatedStateVariable>
</argument>
<argument>
<name>Enabled</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_Bool</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>Get</name>
<argumentList>
<argument>
<name>Id</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_String</relatedStateVariable>
</argument>
<argument>
<name>UserName</name>
<direction>out</direction>
<relatedStateVariable>A_ARG_TYPE_String</relatedStateVariable>
</argument>
<argument>
<name>Password</name>
<direction>out</direction>
<relatedStateVariable>A_ARG_TYPE_Binary</relatedStateVariable>
</argument>
<argument>
<name>Enabled</name>
<direction>out</direction>
<relatedStateVariable>A_ARG_TYPE_Bool</relatedStateVariable>
</argument>
<argument>
<name>Status</name>
<direction>out</direction>
<relatedStateVariable>A_ARG_TYPE_String</relatedStateVariable>
</argument>
<argument>
<name>Data</name>
<direction>out</direction>
<relatedStateVariable>A_ARG_TYPE_String</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>Login</name>
<argumentList>
<argument>
<name>Id</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_String</relatedStateVariable>
</argument>
<argument>
<name>Token</name>
<direction>out</direction>
<relatedStateVariable>A_ARG_TYPE_String</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>ReLogin</name>
<argumentList>
<argument>
<name>Id</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_String</relatedStateVariable>
</argument>
<argument>
<name>CurrentToken</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_String</relatedStateVariable>
</argument>
<argument>
<name>NewToken</name>
<direction>out</direction>
<relatedStateVariable>A_ARG_TYPE_String</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>GetIds</name>
<argumentList>
<argument>
<name>Ids</name>
<direction>out</direction>
<relatedStateVariable>Ids</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>GetPublicKey</name>
<argumentList>
<argument>
<name>PublicKey</name>
<direction>out</direction>
<relatedStateVariable>PublicKey</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>GetSequenceNumber</name>
<argumentList>
<argument>
<name>SequenceNumber</name>
<direction>out</direction>
<relatedStateVariable>SequenceNumber</relatedStateVariable>
</argument>
</argumentList>
</action>
</actionList>
<serviceStateTable>
<stateVariable sendEvents="yes">
<name>Ids</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>PublicKey</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>SequenceNumber</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>A_ARG_TYPE_String</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>A_ARG_TYPE_Binary</name>
<dataType>bin.base64</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>A_ARG_TYPE_Bool</name>
<dataType>boolean</dataType>
</stateVariable>
</serviceStateTable>
</scpd>
+35
View File
@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<scpd xmlns="urn:schemas-upnp-org:service-1-0">
<specVersion>
<major>1</major>
<minor>0</minor>
</specVersion>
<actionList>
<action>
<name>GetLog</name>
<argumentList>
<argument>
<name>Log</name>
<direction>out</direction>
<relatedStateVariable>A_ARG_TYPE_String</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>SendLog</name>
<argumentList>
<argument>
<name>Data</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_String</relatedStateVariable>
</argument>
</argumentList>
</action>
</actionList>
<serviceStateTable>
<stateVariable sendEvents="no">
<name>A_ARG_TYPE_String</name>
<dataType>string</dataType>
</stateVariable>
</serviceStateTable>
</scpd>
+160
View File
@@ -0,0 +1,160 @@
<?xml version="1.0" encoding="utf-8"?>
<scpd xmlns="urn:schemas-upnp-org:service-1-0">
<specVersion>
<major>1</major>
<minor>0</minor>
</specVersion>
<actionList>
<action>
<name>DeviceList</name>
<argumentList>
<argument>
<name>List</name>
<direction>out</direction>
<relatedStateVariable>DeviceList</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>DeviceSettings</name>
<argumentList>
<argument>
<name>DeviceId</name>
<direction>in</direction>
<relatedStateVariable>DeviceId</relatedStateVariable>
</argument>
<argument>
<name>Settings</name>
<direction>out</direction>
<relatedStateVariable>DeviceSettings</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>ConnectionStatus</name>
<argumentList>
<argument>
<name>ConnectionStatus</name>
<direction>out</direction>
<relatedStateVariable>ConnectionStatus</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>Set</name>
<argumentList>
<argument>
<name>DeviceId</name>
<direction>in</direction>
<relatedStateVariable>DeviceId</relatedStateVariable>
</argument>
<argument>
<name>BankId</name>
<direction>in</direction>
<relatedStateVariable>BankId</relatedStateVariable>
</argument>
<argument>
<name>FileUri</name>
<direction>in</direction>
<relatedStateVariable>FileUri</relatedStateVariable>
</argument>
<argument>
<name>Mute</name>
<direction>in</direction>
<relatedStateVariable>Mute</relatedStateVariable>
</argument>
<argument>
<name>Persist</name>
<direction>in</direction>
<relatedStateVariable>Persist</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>Reprogram</name>
<argumentList>
<argument>
<name>DeviceId</name>
<direction>in</direction>
<relatedStateVariable>DeviceId</relatedStateVariable>
</argument>
<argument>
<name>FileUri</name>
<direction>in</direction>
<relatedStateVariable>FileUri</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>ReprogramFallback</name>
<argumentList>
<argument>
<name>DeviceId</name>
<direction>in</direction>
<relatedStateVariable>DeviceId</relatedStateVariable>
</argument>
<argument>
<name>FileUri</name>
<direction>in</direction>
<relatedStateVariable>FileUri</relatedStateVariable>
</argument>
</argumentList>
</action>
</actionList>
<serviceStateTable>
<stateVariable sendEvents="yes">
<name>DeviceList</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>DeviceSettings</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>ConnectionStatus</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>DeviceId</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>BankId</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>Persist</name>
<dataType>boolean</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>Mute</name>
<dataType>boolean</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>FileUri</name>
<dataType>uri</dataType>
</stateVariable>
</serviceStateTable>
</scpd>
+176
View File
@@ -0,0 +1,176 @@
<?xml version="1.0" encoding="utf-8"?>
<scpd xmlns="urn:schemas-upnp-org:service-1-0">
<specVersion>
<major>1</major>
<minor>0</minor>
</specVersion>
<actionList>
<action>
<name>DeviceList</name>
<argumentList>
<argument>
<name>List</name>
<direction>out</direction>
<relatedStateVariable>DeviceList</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>DeviceSettings</name>
<argumentList>
<argument>
<name>DeviceId</name>
<direction>in</direction>
<relatedStateVariable>DeviceId</relatedStateVariable>
</argument>
<argument>
<name>Settings</name>
<direction>out</direction>
<relatedStateVariable>DeviceSettings</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>ConnectionStatus</name>
<argumentList>
<argument>
<name>ConnectionStatus</name>
<direction>out</direction>
<relatedStateVariable>ConnectionStatus</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>Set</name>
<argumentList>
<argument>
<name>DeviceId</name>
<direction>in</direction>
<relatedStateVariable>DeviceId</relatedStateVariable>
</argument>
<argument>
<name>BankId</name>
<direction>in</direction>
<relatedStateVariable>BankId</relatedStateVariable>
</argument>
<argument>
<name>FileUri</name>
<direction>in</direction>
<relatedStateVariable>FileUri</relatedStateVariable>
</argument>
<argument>
<name>Mute</name>
<direction>in</direction>
<relatedStateVariable>Mute</relatedStateVariable>
</argument>
<argument>
<name>Persist</name>
<direction>in</direction>
<relatedStateVariable>Persist</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>Reprogram</name>
<argumentList>
<argument>
<name>DeviceId</name>
<direction>in</direction>
<relatedStateVariable>DeviceId</relatedStateVariable>
</argument>
<argument>
<name>FileUri</name>
<direction>in</direction>
<relatedStateVariable>FileUri</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>ReprogramFallback</name>
<argumentList>
<argument>
<name>DeviceId</name>
<direction>in</direction>
<relatedStateVariable>DeviceId</relatedStateVariable>
</argument>
<argument>
<name>FileUri</name>
<direction>in</direction>
<relatedStateVariable>FileUri</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>Version</name>
<argumentList>
<argument>
<name>Version</name>
<direction>out</direction>
<relatedStateVariable>Version</relatedStateVariable>
</argument>
</argumentList>
</action>
</actionList>
<serviceStateTable>
<stateVariable sendEvents="yes">
<name>DeviceList</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>DeviceSettings</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>ConnectionStatus</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>DeviceId</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>BankId</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>Persist</name>
<dataType>boolean</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>Mute</name>
<dataType>boolean</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>FileUri</name>
<dataType>uri</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>Version</name>
<dataType>string</dataType>
</stateVariable>
</serviceStateTable>
</scpd>
+208
View File
@@ -0,0 +1,208 @@
<?xml version="1.0" encoding="utf-8"?>
<scpd xmlns="urn:schemas-upnp-org:service-1-0">
<specVersion>
<major>1</major>
<minor>0</minor>
</specVersion>
<actionList>
<action>
<name>DeviceList</name>
<argumentList>
<argument>
<name>List</name>
<direction>out</direction>
<relatedStateVariable>DeviceList</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>DeviceSettings</name>
<argumentList>
<argument>
<name>DeviceId</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_String</relatedStateVariable>
</argument>
<argument>
<name>Settings</name>
<direction>out</direction>
<relatedStateVariable>A_ARG_TYPE_String</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>ConnectionStatus</name>
<argumentList>
<argument>
<name>ConnectionStatus</name>
<direction>out</direction>
<relatedStateVariable>ConnectionStatus</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>Set</name>
<argumentList>
<argument>
<name>DeviceId</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_String</relatedStateVariable>
</argument>
<argument>
<name>BankId</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_Uint</relatedStateVariable>
</argument>
<argument>
<name>FileUri</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_Uri</relatedStateVariable>
</argument>
<argument>
<name>Mute</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_Bool</relatedStateVariable>
</argument>
<argument>
<name>Persist</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_Bool</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>Reprogram</name>
<argumentList>
<argument>
<name>DeviceId</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_String</relatedStateVariable>
</argument>
<argument>
<name>FileUri</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_Uri</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>ReprogramFallback</name>
<argumentList>
<argument>
<name>DeviceId</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_String</relatedStateVariable>
</argument>
<argument>
<name>FileUri</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_Uri</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>ChannelMap</name>
<argumentList>
<argument>
<name>ChannelMap</name>
<direction>out</direction>
<relatedStateVariable>ChannelMap</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>SetChannelMap</name>
<argumentList>
<argument>
<name>ChannelMap</name>
<direction>in</direction>
<relatedStateVariable>ChannelMap</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>AudioChannels</name>
<argumentList>
<argument>
<name>AudioChannels</name>
<direction>out</direction>
<relatedStateVariable>AudioChannels</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>SetAudioChannels</name>
<argumentList>
<argument>
<name>AudioChannels</name>
<direction>in</direction>
<relatedStateVariable>AudioChannels</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>Version</name>
<argumentList>
<argument>
<name>Version</name>
<direction>out</direction>
<relatedStateVariable>Version</relatedStateVariable>
</argument>
</argumentList>
</action>
</actionList>
<serviceStateTable>
<stateVariable sendEvents="yes">
<name>DeviceList</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>ConnectionStatus</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>ChannelMap</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>AudioChannels</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>Version</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>A_ARG_TYPE_String</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>A_ARG_TYPE_Uint</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>A_ARG_TYPE_Bool</name>
<dataType>boolean</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>A_ARG_TYPE_Uri</name>
<dataType>uri</dataType>
</stateVariable>
</serviceStateTable>
</scpd>
+140
View File
@@ -0,0 +1,140 @@
<?xml version="1.0" encoding="utf-8"?>
<scpd xmlns="urn:schemas-upnp-org:service-1-0">
<specVersion>
<major>1</major>
<minor>0</minor>
</specVersion>
<actionList>
<action>
<name>Counters</name>
<argumentList>
<argument>
<name>TrackCount</name>
<direction>out</direction>
<relatedStateVariable>TrackCount</relatedStateVariable>
</argument>
<argument>
<name>DetailsCount</name>
<direction>out</direction>
<relatedStateVariable>DetailsCount</relatedStateVariable>
</argument>
<argument>
<name>MetatextCount</name>
<direction>out</direction>
<relatedStateVariable>MetatextCount</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>Track</name>
<argumentList>
<argument>
<name>Uri</name>
<direction>out</direction>
<relatedStateVariable>Uri</relatedStateVariable>
</argument>
<argument>
<name>Metadata</name>
<direction>out</direction>
<relatedStateVariable>Metadata</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>Details</name>
<argumentList>
<argument>
<name>Duration</name>
<direction>out</direction>
<relatedStateVariable>Duration</relatedStateVariable>
</argument>
<argument>
<name>BitRate</name>
<direction>out</direction>
<relatedStateVariable>BitRate</relatedStateVariable>
</argument>
<argument>
<name>BitDepth</name>
<direction>out</direction>
<relatedStateVariable>BitDepth</relatedStateVariable>
</argument>
<argument>
<name>SampleRate</name>
<direction>out</direction>
<relatedStateVariable>SampleRate</relatedStateVariable>
</argument>
<argument>
<name>Lossless</name>
<direction>out</direction>
<relatedStateVariable>Lossless</relatedStateVariable>
</argument>
<argument>
<name>CodecName</name>
<direction>out</direction>
<relatedStateVariable>CodecName</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>Metatext</name>
<argumentList>
<argument>
<name>Value</name>
<direction>out</direction>
<relatedStateVariable>Metatext</relatedStateVariable>
</argument>
</argumentList>
</action>
</actionList>
<serviceStateTable>
<stateVariable sendEvents="yes">
<name>TrackCount</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>DetailsCount</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>MetatextCount</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>Uri</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>Metadata</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>Duration</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>BitRate</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>BitDepth</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>SampleRate</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>Lossless</name>
<dataType>boolean</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>CodecName</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>Metatext</name>
<dataType>string</dataType>
</stateVariable>
</serviceStateTable>
</scpd>
+190
View File
@@ -0,0 +1,190 @@
<?xml version="1.0" encoding="utf-8"?>
<scpd xmlns="urn:schemas-upnp-org:service-1-0">
<specVersion>
<major>1</major>
<minor>0</minor>
</specVersion>
<actionList>
<action>
<name>Manufacturer</name>
<argumentList>
<argument>
<name>Name</name>
<direction>out</direction>
<relatedStateVariable>ManufacturerName</relatedStateVariable>
</argument>
<argument>
<name>Info</name>
<direction>out</direction>
<relatedStateVariable>ManufacturerInfo</relatedStateVariable>
</argument>
<argument>
<name>Url</name>
<direction>out</direction>
<relatedStateVariable>ManufacturerUrl</relatedStateVariable>
</argument>
<argument>
<name>ImageUri</name>
<direction>out</direction>
<relatedStateVariable>ManufacturerImageUri</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>Model</name>
<argumentList>
<argument>
<name>Name</name>
<direction>out</direction>
<relatedStateVariable>ModelName</relatedStateVariable>
</argument>
<argument>
<name>Info</name>
<direction>out</direction>
<relatedStateVariable>ModelInfo</relatedStateVariable>
</argument>
<argument>
<name>Url</name>
<direction>out</direction>
<relatedStateVariable>ModelUrl</relatedStateVariable>
</argument>
<argument>
<name>ImageUri</name>
<direction>out</direction>
<relatedStateVariable>ModelImageUri</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>Product</name>
<argumentList>
<argument>
<name>Name</name>
<direction>out</direction>
<relatedStateVariable>ProductName</relatedStateVariable>
</argument>
<argument>
<name>Info</name>
<direction>out</direction>
<relatedStateVariable>ProductInfo</relatedStateVariable>
</argument>
<argument>
<name>Url</name>
<direction>out</direction>
<relatedStateVariable>ProductUrl</relatedStateVariable>
</argument>
<argument>
<name>ImageUri</name>
<direction>out</direction>
<relatedStateVariable>ProductImageUri</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>Attributes</name>
<argumentList>
<argument>
<name>Value</name>
<direction>out</direction>
<relatedStateVariable>Attributes</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>QueryPort</name>
<argumentList>
<argument>
<name>Value</name>
<direction>out</direction>
<relatedStateVariable>QueryPort</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>BrowsePort</name>
<argumentList>
<argument>
<name>Value</name>
<direction>out</direction>
<relatedStateVariable>BrowsePort</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>UpdateCount</name>
<argumentList>
<argument>
<name>Value</name>
<direction>out</direction>
<relatedStateVariable>UpdateCount</relatedStateVariable>
</argument>
</argumentList>
</action>
</actionList>
<serviceStateTable>
<stateVariable sendEvents="yes">
<name>ManufacturerName</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>ManufacturerInfo</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>ManufacturerUrl</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>ManufacturerImageUri</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>ModelName</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>ModelInfo</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>ModelUrl</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>ModelImageUri</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>ProductName</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>ProductInfo</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>ProductUrl</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>ProductImageUri</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>Attributes</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>QueryPort</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>BrowsePort</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>UpdateCount</name>
<dataType>ui4</dataType>
</stateVariable>
</serviceStateTable>
</scpd>
+58
View File
@@ -0,0 +1,58 @@
<?xml version="1.0" encoding="utf-8"?>
<scpd xmlns="urn:schemas-upnp-org:service-1-0">
<specVersion>
<major>1</major>
<minor>0</minor>
</specVersion>
<actionList>
<action>
<name>Name</name>
<argumentList>
<argument>
<name>Name</name>
<direction>out</direction>
<relatedStateVariable>Name</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>Ports</name>
<argumentList>
<argument>
<name>Sender</name>
<direction>out</direction>
<relatedStateVariable>Sender</relatedStateVariable>
</argument>
<argument>
<name>Receiver</name>
<direction>out</direction>
<relatedStateVariable>Receiver</relatedStateVariable>
</argument>
<argument>
<name>Results</name>
<direction>out</direction>
<relatedStateVariable>Results</relatedStateVariable>
</argument>
</argumentList>
</action>
</actionList>
<serviceStateTable>
<stateVariable sendEvents="yes">
<name>Name</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>Sender</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>Receiver</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>Results</name>
<dataType>ui4</dataType>
</stateVariable>
</serviceStateTable>
</scpd>
+224
View File
@@ -0,0 +1,224 @@
<?xml version="1.0" encoding="utf-8"?>
<scpd xmlns="urn:schemas-upnp-org:service-1-0">
<specVersion>
<major>1</major>
<minor>0</minor>
</specVersion>
<actionList>
<action>
<name>GetDeviceAccountMax</name>
<argumentList>
<argument>
<name>DeviceMax</name>
<direction>out</direction>
<relatedStateVariable>DeviceMax</relatedStateVariable>
</argument>
<argument>
<name>AccountMax</name>
<direction>out</direction>
<relatedStateVariable>AccountMax</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>GetModes</name>
<argumentList>
<argument>
<name>Modes</name>
<direction>out</direction>
<relatedStateVariable>Modes</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>GetIdArray</name>
<argumentList>
<argument>
<name>IdArray</name>
<direction>out</direction>
<relatedStateVariable>IdArray</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>ReadList</name>
<argumentList>
<argument>
<name>Ids</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_String</relatedStateVariable>
</argument>
<argument>
<name>List</name>
<direction>out</direction>
<relatedStateVariable>A_ARG_TYPE_String</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>InvokeId</name>
<argumentList>
<argument>
<name>Id</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_Uint</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>InvokeIndex</name>
<argumentList>
<argument>
<name>Index</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_Uint</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>SetDevice</name>
<argumentList>
<argument>
<name>Index</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_Uint</relatedStateVariable>
</argument>
<argument>
<name>Mode</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_String</relatedStateVariable>
</argument>
<argument>
<name>Type</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_String</relatedStateVariable>
</argument>
<argument>
<name>Uri</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_String</relatedStateVariable>
</argument>
<argument>
<name>Title</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_String</relatedStateVariable>
</argument>
<argument>
<name>Description</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_String</relatedStateVariable>
</argument>
<argument>
<name>ArtworkUri</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_String</relatedStateVariable>
</argument>
<argument>
<name>Shuffle</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_Bool</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>SetAccount</name>
<argumentList>
<argument>
<name>Index</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_Uint</relatedStateVariable>
</argument>
<argument>
<name>Mode</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_String</relatedStateVariable>
</argument>
<argument>
<name>Type</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_String</relatedStateVariable>
</argument>
<argument>
<name>Uri</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_String</relatedStateVariable>
</argument>
<argument>
<name>Title</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_String</relatedStateVariable>
</argument>
<argument>
<name>Description</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_String</relatedStateVariable>
</argument>
<argument>
<name>ArtworkUri</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_String</relatedStateVariable>
</argument>
<argument>
<name>Shuffle</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_Bool</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>Clear</name>
<argumentList>
<argument>
<name>Id</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_Uint</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>Swap</name>
<argumentList>
<argument>
<name>Index1</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_Uint</relatedStateVariable>
</argument>
<argument>
<name>Index2</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_Uint</relatedStateVariable>
</argument>
</argumentList>
</action>
</actionList>
<serviceStateTable>
<stateVariable sendEvents="yes">
<name>DeviceMax</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>AccountMax</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>Modes</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>IdArray</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>A_ARG_TYPE_String</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>A_ARG_TYPE_Uint</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>A_ARG_TYPE_Bool</name>
<dataType>boolean</dataType>
</stateVariable>
</serviceStateTable>
</scpd>
+324
View File
@@ -0,0 +1,324 @@
<?xml version="1.0" encoding="utf-8"?>
<scpd xmlns="urn:schemas-upnp-org:service-1-0">
<specVersion>
<major>1</major>
<minor>0</minor>
</specVersion>
<actionList>
<action>
<name>Play</name>
</action>
<action>
<name>Pause</name>
</action>
<action>
<name>Stop</name>
</action>
<action>
<name>Next</name>
</action>
<action>
<name>Previous</name>
</action>
<action>
<name>SetRepeat</name>
<argumentList>
<argument>
<name>Value</name>
<direction>in</direction>
<relatedStateVariable>Repeat</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>Repeat</name>
<argumentList>
<argument>
<name>Value</name>
<direction>out</direction>
<relatedStateVariable>Repeat</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>SetShuffle</name>
<argumentList>
<argument>
<name>Value</name>
<direction>in</direction>
<relatedStateVariable>Shuffle</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>Shuffle</name>
<argumentList>
<argument>
<name>Value</name>
<direction>out</direction>
<relatedStateVariable>Shuffle</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>SeekSecondAbsolute</name>
<argumentList>
<argument>
<name>Value</name>
<direction>in</direction>
<relatedStateVariable>Absolute</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>SeekSecondRelative</name>
<argumentList>
<argument>
<name>Value</name>
<direction>in</direction>
<relatedStateVariable>Relative</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>SeekId</name>
<argumentList>
<argument>
<name>Value</name>
<direction>in</direction>
<relatedStateVariable>Id</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>SeekIndex</name>
<argumentList>
<argument>
<name>Value</name>
<direction>in</direction>
<relatedStateVariable>Index</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>TransportState</name>
<argumentList>
<argument>
<name>Value</name>
<direction>out</direction>
<relatedStateVariable>TransportState</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>Id</name>
<argumentList>
<argument>
<name>Value</name>
<direction>out</direction>
<relatedStateVariable>Id</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>Read</name>
<argumentList>
<argument>
<name>Id</name>
<direction>in</direction>
<relatedStateVariable>Id</relatedStateVariable>
</argument>
<argument>
<name>Uri</name>
<direction>out</direction>
<relatedStateVariable>Uri</relatedStateVariable>
</argument>
<argument>
<name>Metadata</name>
<direction>out</direction>
<relatedStateVariable>Metadata</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>ReadList</name>
<argumentList>
<argument>
<name>IdList</name>
<direction>in</direction>
<relatedStateVariable>IdList</relatedStateVariable>
</argument>
<argument>
<name>TrackList</name>
<direction>out</direction>
<relatedStateVariable>TrackList</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>Insert</name>
<argumentList>
<argument>
<name>AfterId</name>
<direction>in</direction>
<relatedStateVariable>Id</relatedStateVariable>
</argument>
<argument>
<name>Uri</name>
<direction>in</direction>
<relatedStateVariable>Uri</relatedStateVariable>
</argument>
<argument>
<name>Metadata</name>
<direction>in</direction>
<relatedStateVariable>Metadata</relatedStateVariable>
</argument>
<argument>
<name>NewId</name>
<direction>out</direction>
<relatedStateVariable>Id</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>DeleteId</name>
<argumentList>
<argument>
<name>Value</name>
<direction>in</direction>
<relatedStateVariable>Id</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>DeleteAll</name>
</action>
<action>
<name>TracksMax</name>
<argumentList>
<argument>
<name>Value</name>
<direction>out</direction>
<relatedStateVariable>TracksMax</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>IdArray</name>
<argumentList>
<argument>
<name>Token</name>
<direction>out</direction>
<relatedStateVariable>IdArrayToken</relatedStateVariable>
</argument>
<argument>
<name>Array</name>
<direction>out</direction>
<relatedStateVariable>IdArray</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>IdArrayChanged</name>
<argumentList>
<argument>
<name>Token</name>
<direction>in</direction>
<relatedStateVariable>IdArrayToken</relatedStateVariable>
</argument>
<argument>
<name>Value</name>
<direction>out</direction>
<relatedStateVariable>IdArrayChanged</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>ProtocolInfo</name>
<argumentList>
<argument>
<name>Value</name>
<direction>out</direction>
<relatedStateVariable>ProtocolInfo</relatedStateVariable>
</argument>
</argumentList>
</action>
</actionList>
<serviceStateTable>
<stateVariable sendEvents="yes">
<name>TransportState</name>
<dataType>string</dataType>
<allowedValueList>
<allowedValue>Playing</allowedValue>
<allowedValue>Paused</allowedValue>
<allowedValue>Stopped</allowedValue>
<allowedValue>Buffering</allowedValue>
</allowedValueList>
</stateVariable>
<stateVariable sendEvents="yes">
<name>Repeat</name>
<dataType>boolean</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>Shuffle</name>
<dataType>boolean</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>Id</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>IdArray</name>
<dataType>bin.base64</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>TracksMax</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>ProtocolInfo</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>Index</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>Relative</name>
<dataType>i4</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>Absolute</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>IdList</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>TrackList</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>Uri</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>Metadata</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>IdArrayToken</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>IdArrayChanged</name>
<dataType>boolean</dataType>
</stateVariable>
</serviceStateTable>
</scpd>
+402
View File
@@ -0,0 +1,402 @@
<?xml version="1.0" encoding="utf-8"?>
<scpd xmlns="urn:schemas-upnp-org:service-1-0">
<specVersion>
<major>1</major>
<minor>0</minor>
</specVersion>
<actionList>
<action>
<name>Metadata</name>
<argumentList>
<argument>
<name>Metadata</name>
<direction>out</direction>
<relatedStateVariable>Metadata</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>ImagesXml</name>
<argumentList>
<argument>
<name>ImagesXml</name>
<direction>out</direction>
<relatedStateVariable>ImagesXml</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>PlaylistReadArray</name>
<argumentList>
<argument>
<name>Id</name>
<direction>in</direction>
<relatedStateVariable>Id</relatedStateVariable>
</argument>
<argument>
<name>Array</name>
<direction>out</direction>
<relatedStateVariable>IdArray</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>PlaylistReadList</name>
<argumentList>
<argument>
<name>IdList</name>
<direction>in</direction>
<relatedStateVariable>IdList</relatedStateVariable>
</argument>
<argument>
<name>PlaylistList</name>
<direction>out</direction>
<relatedStateVariable>PlaylistList</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>PlaylistRead</name>
<argumentList>
<argument>
<name>Id</name>
<direction>in</direction>
<relatedStateVariable>Id</relatedStateVariable>
</argument>
<argument>
<name>Name</name>
<direction>out</direction>
<relatedStateVariable>Name</relatedStateVariable>
</argument>
<argument>
<name>Description</name>
<direction>out</direction>
<relatedStateVariable>Description</relatedStateVariable>
</argument>
<argument>
<name>ImageId</name>
<direction>out</direction>
<relatedStateVariable>ImageId</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>PlaylistSetName</name>
<argumentList>
<argument>
<name>Id</name>
<direction>in</direction>
<relatedStateVariable>Id</relatedStateVariable>
</argument>
<argument>
<name>Name</name>
<direction>in</direction>
<relatedStateVariable>Name</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>PlaylistSetDescription</name>
<argumentList>
<argument>
<name>Id</name>
<direction>in</direction>
<relatedStateVariable>Id</relatedStateVariable>
</argument>
<argument>
<name>Description</name>
<direction>in</direction>
<relatedStateVariable>Description</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>PlaylistSetImageId</name>
<argumentList>
<argument>
<name>Id</name>
<direction>in</direction>
<relatedStateVariable>Id</relatedStateVariable>
</argument>
<argument>
<name>ImageId</name>
<direction>in</direction>
<relatedStateVariable>ImageId</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>PlaylistInsert</name>
<argumentList>
<argument>
<name>AfterId</name>
<direction>in</direction>
<relatedStateVariable>Id</relatedStateVariable>
</argument>
<argument>
<name>Name</name>
<direction>in</direction>
<relatedStateVariable>Name</relatedStateVariable>
</argument>
<argument>
<name>Description</name>
<direction>in</direction>
<relatedStateVariable>Description</relatedStateVariable>
</argument>
<argument>
<name>ImageId</name>
<direction>in</direction>
<relatedStateVariable>ImageId</relatedStateVariable>
</argument>
<argument>
<name>NewId</name>
<direction>out</direction>
<relatedStateVariable>Id</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>PlaylistDeleteId</name>
<argumentList>
<argument>
<name>Value</name>
<direction>in</direction>
<relatedStateVariable>Id</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>PlaylistMove</name>
<argumentList>
<argument>
<name>Id</name>
<direction>in</direction>
<relatedStateVariable>Id</relatedStateVariable>
</argument>
<argument>
<name>AfterId</name>
<direction>in</direction>
<relatedStateVariable>Id</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>PlaylistsMax</name>
<argumentList>
<argument>
<name>Value</name>
<direction>out</direction>
<relatedStateVariable>PlaylistsMax</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>TracksMax</name>
<argumentList>
<argument>
<name>Value</name>
<direction>out</direction>
<relatedStateVariable>TracksMax</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>PlaylistArrays</name>
<argumentList>
<argument>
<name>Token</name>
<direction>out</direction>
<relatedStateVariable>ArraysToken</relatedStateVariable>
</argument>
<argument>
<name>IdArray</name>
<direction>out</direction>
<relatedStateVariable>IdArray</relatedStateVariable>
</argument>
<argument>
<name>TokenArray</name>
<direction>out</direction>
<relatedStateVariable>TokenArray</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>PlaylistArraysChanged</name>
<argumentList>
<argument>
<name>Token</name>
<direction>in</direction>
<relatedStateVariable>ArraysToken</relatedStateVariable>
</argument>
<argument>
<name>Value</name>
<direction>out</direction>
<relatedStateVariable>IdArrayChanged</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>Read</name>
<argumentList>
<argument>
<name>Id</name>
<direction>in</direction>
<relatedStateVariable>Id</relatedStateVariable>
</argument>
<argument>
<name>TrackId</name>
<direction>in</direction>
<relatedStateVariable>Id</relatedStateVariable>
</argument>
<argument>
<name>Metadata</name>
<direction>out</direction>
<relatedStateVariable>Metadata</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>ReadList</name>
<argumentList>
<argument>
<name>Id</name>
<direction>in</direction>
<relatedStateVariable>Id</relatedStateVariable>
</argument>
<argument>
<name>TrackIdList</name>
<direction>in</direction>
<relatedStateVariable>IdList</relatedStateVariable>
</argument>
<argument>
<name>TrackList</name>
<direction>out</direction>
<relatedStateVariable>TrackList</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>Insert</name>
<argumentList>
<argument>
<name>Id</name>
<direction>in</direction>
<relatedStateVariable>Id</relatedStateVariable>
</argument>
<argument>
<name>AfterTrackId</name>
<direction>in</direction>
<relatedStateVariable>Id</relatedStateVariable>
</argument>
<argument>
<name>Metadata</name>
<direction>in</direction>
<relatedStateVariable>Metadata</relatedStateVariable>
</argument>
<argument>
<name>NewTrackId</name>
<direction>out</direction>
<relatedStateVariable>Id</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>DeleteId</name>
<argumentList>
<argument>
<name>Id</name>
<direction>in</direction>
<relatedStateVariable>Id</relatedStateVariable>
</argument>
<argument>
<name>TrackId</name>
<direction>in</direction>
<relatedStateVariable>Id</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>DeleteAll</name>
<argumentList>
<argument>
<name>Id</name>
<direction>in</direction>
<relatedStateVariable>Id</relatedStateVariable>
</argument>
</argumentList>
</action>
</actionList>
<serviceStateTable>
<stateVariable sendEvents="yes">
<name>Metadata</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>ImagesXml</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>IdArray</name>
<dataType>bin.base64</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>TokenArray</name>
<dataType>bin.base64</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>PlaylistsMax</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>TracksMax</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>PlaylistList</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>Id</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>IdList</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>Name</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>Description</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>ImageId</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>TrackList</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>ArraysToken</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>IdArrayChanged</name>
<dataType>boolean</dataType>
</stateVariable>
</serviceStateTable>
</scpd>
+31
View File
@@ -0,0 +1,31 @@
<ohs>
<domain>av</domain>
<version>1</version>
<group name="Manufacturer" count="1">
<property name="Name" type="String" access="ROC" />
<property name="Info" type="String" access="ROC" />
<property name="Url" type="Uri" access="ROC" />
<property name="ImageUri" type="Uri" access="ROC" />
</group>
<group name="Model" count="1">
<property name="Name" type="String" access="ROC" />
<property name="Info" type="String" access="ROC" />
<property name="Url" type="Uri" access="ROC" />
<property name="ImageUri" type="Uri" access="ROC" />
</group>
<group name="Product" count="1">
<property name="Room" type="String" access="ROC" />
<property name="Name" type="String" access="ROC" />
<property name="Info" type="String" access="ROC" />
<property name="Url" type="Uri" access="ROC" />
<property name="ImageUri" type="Uri" access="ROC" />
</group>
<group name="Source" count="C">
<property name="Name" type="String" access="RW" />
<property name="Type" type="String" access="ROC" />
<property name="Visible" type="Boolean" access="RW" />
</group>
<property name="Attributes" type="String" access="ROC" />
<property name="Standby" type="Boolean" access="RW" />
<property name="SourceIndex" type="Unsigned" access="RW" />
</ohs>
+299
View File
@@ -0,0 +1,299 @@
<?xml version="1.0" encoding="utf-8"?>
<scpd xmlns="urn:schemas-upnp-org:service-1-0">
<specVersion>
<major>1</major>
<minor>0</minor>
</specVersion>
<actionList>
<action>
<name>Manufacturer</name>
<argumentList>
<argument>
<name>Name</name>
<direction>out</direction>
<relatedStateVariable>ManufacturerName</relatedStateVariable>
</argument>
<argument>
<name>Info</name>
<direction>out</direction>
<relatedStateVariable>ManufacturerInfo</relatedStateVariable>
</argument>
<argument>
<name>Url</name>
<direction>out</direction>
<relatedStateVariable>ManufacturerUrl</relatedStateVariable>
</argument>
<argument>
<name>ImageUri</name>
<direction>out</direction>
<relatedStateVariable>ManufacturerImageUri</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>Model</name>
<argumentList>
<argument>
<name>Name</name>
<direction>out</direction>
<relatedStateVariable>ModelName</relatedStateVariable>
</argument>
<argument>
<name>Info</name>
<direction>out</direction>
<relatedStateVariable>ModelInfo</relatedStateVariable>
</argument>
<argument>
<name>Url</name>
<direction>out</direction>
<relatedStateVariable>ModelUrl</relatedStateVariable>
</argument>
<argument>
<name>ImageUri</name>
<direction>out</direction>
<relatedStateVariable>ModelImageUri</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>Product</name>
<argumentList>
<argument>
<name>Room</name>
<direction>out</direction>
<relatedStateVariable>ProductRoom</relatedStateVariable>
</argument>
<argument>
<name>Name</name>
<direction>out</direction>
<relatedStateVariable>ProductName</relatedStateVariable>
</argument>
<argument>
<name>Info</name>
<direction>out</direction>
<relatedStateVariable>ProductInfo</relatedStateVariable>
</argument>
<argument>
<name>Url</name>
<direction>out</direction>
<relatedStateVariable>ProductUrl</relatedStateVariable>
</argument>
<argument>
<name>ImageUri</name>
<direction>out</direction>
<relatedStateVariable>ProductImageUri</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>Standby</name>
<argumentList>
<argument>
<name>Value</name>
<direction>out</direction>
<relatedStateVariable>Standby</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>SetStandby</name>
<argumentList>
<argument>
<name>Value</name>
<direction>in</direction>
<relatedStateVariable>Standby</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>SourceCount</name>
<argumentList>
<argument>
<name>Value</name>
<direction>out</direction>
<relatedStateVariable>SourceCount</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>SourceXml</name>
<argumentList>
<argument>
<name>Value</name>
<direction>out</direction>
<relatedStateVariable>SourceXml</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>SourceIndex</name>
<argumentList>
<argument>
<name>Value</name>
<direction>out</direction>
<relatedStateVariable>SourceIndex</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>SetSourceIndex</name>
<argumentList>
<argument>
<name>Value</name>
<direction>in</direction>
<relatedStateVariable>SourceIndex</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>SetSourceIndexByName</name>
<argumentList>
<argument>
<name>Value</name>
<direction>in</direction>
<relatedStateVariable>SourceName</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>Source</name>
<argumentList>
<argument>
<name>Index</name>
<direction>in</direction>
<relatedStateVariable>SourceIndex</relatedStateVariable>
</argument>
<argument>
<name>SystemName</name>
<direction>out</direction>
<relatedStateVariable>SourceName</relatedStateVariable>
</argument>
<argument>
<name>Type</name>
<direction>out</direction>
<relatedStateVariable>SourceType</relatedStateVariable>
</argument>
<argument>
<name>Name</name>
<direction>out</direction>
<relatedStateVariable>SourceName</relatedStateVariable>
</argument>
<argument>
<name>Visible</name>
<direction>out</direction>
<relatedStateVariable>SourceVisible</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>Attributes</name>
<argumentList>
<argument>
<name>Value</name>
<direction>out</direction>
<relatedStateVariable>Attributes</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>SourceXmlChangeCount</name>
<argumentList>
<argument>
<name>Value</name>
<direction>out</direction>
<relatedStateVariable>SourceXmlChangeCount</relatedStateVariable>
</argument>
</argumentList>
</action>
</actionList>
<serviceStateTable>
<stateVariable sendEvents="yes">
<name>ManufacturerName</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>ManufacturerInfo</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>ManufacturerUrl</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>ManufacturerImageUri</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>ModelName</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>ModelInfo</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>ModelUrl</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>ModelImageUri</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>ProductRoom</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>ProductName</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>ProductInfo</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>ProductUrl</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>ProductImageUri</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>Standby</name>
<dataType>boolean</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>SourceIndex</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>SourceCount</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>SourceXml</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>Attributes</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>SourceXmlChangeCount</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>SourceType</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>SourceName</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>SourceVisible</name>
<dataType>boolean</dataType>
</stateVariable>
</serviceStateTable>
</scpd>
+313
View File
@@ -0,0 +1,313 @@
<?xml version="1.0" encoding="utf-8"?>
<scpd xmlns="urn:schemas-upnp-org:service-1-0">
<specVersion>
<major>1</major>
<minor>0</minor>
</specVersion>
<actionList>
<action>
<name>Manufacturer</name>
<argumentList>
<argument>
<name>Name</name>
<direction>out</direction>
<relatedStateVariable>ManufacturerName</relatedStateVariable>
</argument>
<argument>
<name>Info</name>
<direction>out</direction>
<relatedStateVariable>ManufacturerInfo</relatedStateVariable>
</argument>
<argument>
<name>Url</name>
<direction>out</direction>
<relatedStateVariable>ManufacturerUrl</relatedStateVariable>
</argument>
<argument>
<name>ImageUri</name>
<direction>out</direction>
<relatedStateVariable>ManufacturerImageUri</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>Model</name>
<argumentList>
<argument>
<name>Name</name>
<direction>out</direction>
<relatedStateVariable>ModelName</relatedStateVariable>
</argument>
<argument>
<name>Info</name>
<direction>out</direction>
<relatedStateVariable>ModelInfo</relatedStateVariable>
</argument>
<argument>
<name>Url</name>
<direction>out</direction>
<relatedStateVariable>ModelUrl</relatedStateVariable>
</argument>
<argument>
<name>ImageUri</name>
<direction>out</direction>
<relatedStateVariable>ModelImageUri</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>Product</name>
<argumentList>
<argument>
<name>Room</name>
<direction>out</direction>
<relatedStateVariable>ProductRoom</relatedStateVariable>
</argument>
<argument>
<name>Name</name>
<direction>out</direction>
<relatedStateVariable>ProductName</relatedStateVariable>
</argument>
<argument>
<name>Info</name>
<direction>out</direction>
<relatedStateVariable>ProductInfo</relatedStateVariable>
</argument>
<argument>
<name>Url</name>
<direction>out</direction>
<relatedStateVariable>ProductUrl</relatedStateVariable>
</argument>
<argument>
<name>ImageUri</name>
<direction>out</direction>
<relatedStateVariable>ProductImageUri</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>Standby</name>
<argumentList>
<argument>
<name>Value</name>
<direction>out</direction>
<relatedStateVariable>Standby</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>SetStandby</name>
<argumentList>
<argument>
<name>Value</name>
<direction>in</direction>
<relatedStateVariable>Standby</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>SourceCount</name>
<argumentList>
<argument>
<name>Value</name>
<direction>out</direction>
<relatedStateVariable>SourceCount</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>SourceXml</name>
<argumentList>
<argument>
<name>Value</name>
<direction>out</direction>
<relatedStateVariable>SourceXml</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>SourceIndex</name>
<argumentList>
<argument>
<name>Value</name>
<direction>out</direction>
<relatedStateVariable>SourceIndex</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>SetSourceIndex</name>
<argumentList>
<argument>
<name>Value</name>
<direction>in</direction>
<relatedStateVariable>SourceIndex</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>SetSourceIndexByName</name>
<argumentList>
<argument>
<name>Value</name>
<direction>in</direction>
<relatedStateVariable>SourceName</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>SetSourceBySystemName</name>
<argumentList>
<argument>
<name>Value</name>
<direction>in</direction>
<relatedStateVariable>SourceSystemName</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>Source</name>
<argumentList>
<argument>
<name>Index</name>
<direction>in</direction>
<relatedStateVariable>SourceIndex</relatedStateVariable>
</argument>
<argument>
<name>SystemName</name>
<direction>out</direction>
<relatedStateVariable>SourceName</relatedStateVariable>
</argument>
<argument>
<name>Type</name>
<direction>out</direction>
<relatedStateVariable>SourceType</relatedStateVariable>
</argument>
<argument>
<name>Name</name>
<direction>out</direction>
<relatedStateVariable>SourceName</relatedStateVariable>
</argument>
<argument>
<name>Visible</name>
<direction>out</direction>
<relatedStateVariable>SourceVisible</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>Attributes</name>
<argumentList>
<argument>
<name>Value</name>
<direction>out</direction>
<relatedStateVariable>Attributes</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>SourceXmlChangeCount</name>
<argumentList>
<argument>
<name>Value</name>
<direction>out</direction>
<relatedStateVariable>SourceXmlChangeCount</relatedStateVariable>
</argument>
</argumentList>
</action>
</actionList>
<serviceStateTable>
<stateVariable sendEvents="yes">
<name>ManufacturerName</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>ManufacturerInfo</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>ManufacturerUrl</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>ManufacturerImageUri</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>ModelName</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>ModelInfo</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>ModelUrl</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>ModelImageUri</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>ProductRoom</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>ProductName</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>ProductInfo</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>ProductUrl</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>ProductImageUri</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>Standby</name>
<dataType>boolean</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>SourceIndex</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>SourceCount</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>SourceXml</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>Attributes</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>SourceXmlChangeCount</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>SourceType</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>SourceName</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>SourceSystemName</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>SourceVisible</name>
<dataType>boolean</dataType>
</stateVariable>
</serviceStateTable>
</scpd>
+244
View File
@@ -0,0 +1,244 @@
<?xml version="1.0"?>
<scpd xmlns="urn:schemas-upnp-org:service-1-0">
<specVersion>
<major>1</major>
<minor>0</minor>
</specVersion>
<actionList>
<action>
<name>Play</name>
</action>
<action>
<name>Pause</name>
</action>
<action>
<name>Stop</name>
</action>
<action>
<name>SeekSecondAbsolute</name>
<argumentList>
<argument>
<name>Value</name>
<direction>in</direction>
<relatedStateVariable>Absolute</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>SeekSecondRelative</name>
<argumentList>
<argument>
<name>Value</name>
<direction>in</direction>
<relatedStateVariable>Relative</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>Channel</name>
<argumentList>
<argument>
<name>Uri</name>
<direction>out</direction>
<relatedStateVariable>Uri</relatedStateVariable>
</argument>
<argument>
<name>Metadata</name>
<direction>out</direction>
<relatedStateVariable>Metadata</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>SetChannel</name>
<argumentList>
<argument>
<name>Uri</name>
<direction>in</direction>
<relatedStateVariable>Uri</relatedStateVariable>
</argument>
<argument>
<name>Metadata</name>
<direction>in</direction>
<relatedStateVariable>Metadata</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>TransportState</name>
<argumentList>
<argument>
<name>Value</name>
<direction>out</direction>
<relatedStateVariable>TransportState</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>Id</name>
<argumentList>
<argument>
<name>Value</name>
<direction>out</direction>
<relatedStateVariable>Id</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>SetId</name>
<argumentList>
<argument>
<name>Value</name>
<direction>in</direction>
<relatedStateVariable>Id</relatedStateVariable>
</argument>
<argument>
<name>Uri</name>
<direction>in</direction>
<relatedStateVariable>Uri</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>Read</name>
<argumentList>
<argument>
<name>Id</name>
<direction>in</direction>
<relatedStateVariable>Id</relatedStateVariable>
</argument>
<argument>
<name>Metadata</name>
<direction>out</direction>
<relatedStateVariable>Metadata</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>ReadList</name>
<argumentList>
<argument>
<name>IdList</name>
<direction>in</direction>
<relatedStateVariable>IdList</relatedStateVariable>
</argument>
<argument>
<name>ChannelList</name>
<direction>out</direction>
<relatedStateVariable>ChannelList</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>IdArray</name>
<argumentList>
<argument>
<name>Token</name>
<direction>out</direction>
<relatedStateVariable>IdArrayToken</relatedStateVariable>
</argument>
<argument>
<name>Array</name>
<direction>out</direction>
<relatedStateVariable>IdArray</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>IdArrayChanged</name>
<argumentList>
<argument>
<name>Token</name>
<direction>in</direction>
<relatedStateVariable>IdArrayToken</relatedStateVariable>
</argument>
<argument>
<name>Value</name>
<direction>out</direction>
<relatedStateVariable>IdArrayChanged</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>ChannelsMax</name>
<argumentList>
<argument>
<name>Value</name>
<direction>out</direction>
<relatedStateVariable>ChannelsMax</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>ProtocolInfo</name>
<argumentList>
<argument>
<name>Value</name>
<direction>out</direction>
<relatedStateVariable>ProtocolInfo</relatedStateVariable>
</argument>
</argumentList>
</action>
</actionList>
<serviceStateTable>
<stateVariable sendEvents="yes">
<name>Uri</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>Metadata</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>TransportState</name>
<dataType>string</dataType>
<allowedValueList>
<allowedValue>Stopped</allowedValue>
<allowedValue>Playing</allowedValue>
<allowedValue>Paused</allowedValue>
<allowedValue>Buffering</allowedValue>
</allowedValueList>
</stateVariable>
<stateVariable sendEvents="yes">
<name>Id</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>IdArray</name>
<dataType>bin.base64</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>ChannelsMax</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>ProtocolInfo</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>Relative</name>
<dataType>i4</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>Absolute</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>IdArrayToken</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>IdArrayChanged</name>
<dataType>boolean</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>IdList</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>ChannelList</name>
<dataType>string</dataType>
</stateVariable>
</serviceStateTable>
</scpd>
+90
View File
@@ -0,0 +1,90 @@
<?xml version="1.0"?>
<scpd xmlns="urn:schemas-upnp-org:service-1-0">
<specVersion>
<major>1</major>
<minor>0</minor>
</specVersion>
<actionList>
<action>
<name>Play</name>
</action>
<action>
<name>Stop</name>
</action>
<action>
<name>SetSender</name>
<argumentList>
<argument>
<name>Uri</name>
<direction>in</direction>
<relatedStateVariable>Uri</relatedStateVariable>
</argument>
<argument>
<name>Metadata</name>
<direction>in</direction>
<relatedStateVariable>Metadata</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>Sender</name>
<argumentList>
<argument>
<name>Uri</name>
<direction>out</direction>
<relatedStateVariable>Uri</relatedStateVariable>
</argument>
<argument>
<name>Metadata</name>
<direction>out</direction>
<relatedStateVariable>Metadata</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>ProtocolInfo</name>
<argumentList>
<argument>
<name>Value</name>
<direction>out</direction>
<relatedStateVariable>ProtocolInfo</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>TransportState</name>
<argumentList>
<argument>
<name>Value</name>
<direction>out</direction>
<relatedStateVariable>TransportState</relatedStateVariable>
</argument>
</argumentList>
</action>
</actionList>
<serviceStateTable>
<stateVariable sendEvents="yes">
<name>Uri</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>Metadata</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>TransportState</name>
<dataType>string</dataType>
<allowedValueList>
<allowedValue>Stopped</allowedValue>
<allowedValue>Playing</allowedValue>
<allowedValue>Waiting</allowedValue>
<allowedValue>Buffering</allowedValue>
</allowedValueList>
</stateVariable>
<stateVariable sendEvents="yes">
<name>ProtocolInfo</name>
<dataType>string</dataType>
</stateVariable>
</serviceStateTable>
</scpd>
+88
View File
@@ -0,0 +1,88 @@
<?xml version="1.0"?>
<scpd xmlns="urn:schemas-upnp-org:service-1-0">
<specVersion>
<major>1</major>
<minor>0</minor>
</specVersion>
<actionList>
<action>
<name>PresentationUrl</name>
<argumentList>
<argument>
<name>Value</name>
<direction>out</direction>
<relatedStateVariable>PresentationUrl</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>Metadata</name>
<argumentList>
<argument>
<name>Value</name>
<direction>out</direction>
<relatedStateVariable>Metadata</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>Audio</name>
<argumentList>
<argument>
<name>Value</name>
<direction>out</direction>
<relatedStateVariable>Audio</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>Status</name>
<argumentList>
<argument>
<name>Value</name>
<direction>out</direction>
<relatedStateVariable>Status</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>Attributes</name>
<argumentList>
<argument>
<name>Value</name>
<direction>out</direction>
<relatedStateVariable>Attributes</relatedStateVariable>
</argument>
</argumentList>
</action>
</actionList>
<serviceStateTable>
<stateVariable sendEvents="yes">
<name>PresentationUrl</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>Metadata</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>Audio</name>
<dataType>boolean</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>Status</name>
<dataType>string</dataType>
<allowedValueList>
<allowedValue>Enabled</allowedValue>
<allowedValue>Disabled</allowedValue>
<allowedValue>Blocked</allowedValue>
</allowedValueList>
</stateVariable>
<stateVariable sendEvents="yes">
<name>Attributes</name>
<dataType>string</dataType>
</stateVariable>
</serviceStateTable>
</scpd>
+123
View File
@@ -0,0 +1,123 @@
<?xml version="1.0"?>
<scpd xmlns="urn:schemas-upnp-org:service-1-0">
<specVersion>
<major>1</major>
<minor>0</minor>
</specVersion>
<actionList>
<action>
<name>PresentationUrl</name>
<argumentList>
<argument>
<name>Value</name>
<direction>out</direction>
<relatedStateVariable>PresentationUrl</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>Metadata</name>
<argumentList>
<argument>
<name>Value</name>
<direction>out</direction>
<relatedStateVariable>Metadata</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>Audio</name>
<argumentList>
<argument>
<name>Value</name>
<direction>out</direction>
<relatedStateVariable>Audio</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>Status</name>
<argumentList>
<argument>
<name>Value</name>
<direction>out</direction>
<relatedStateVariable>Status</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>Status2</name>
<argumentList>
<argument>
<name>Value</name>
<direction>out</direction>
<relatedStateVariable>Status2</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>Enabled</name>
<argumentList>
<argument>
<name>Value</name>
<direction>out</direction>
<relatedStateVariable>Enabled</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>Attributes</name>
<argumentList>
<argument>
<name>Value</name>
<direction>out</direction>
<relatedStateVariable>Attributes</relatedStateVariable>
</argument>
</argumentList>
</action>
</actionList>
<serviceStateTable>
<stateVariable sendEvents="yes">
<name>PresentationUrl</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>Metadata</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>Audio</name>
<dataType>boolean</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>Status</name>
<dataType>string</dataType>
<allowedValueList>
<allowedValue>Enabled</allowedValue>
<allowedValue>Disabled</allowedValue>
<allowedValue>Blocked</allowedValue>
</allowedValueList>
</stateVariable>
<stateVariable sendEvents="yes">
<name>Status2</name>
<dataType>string</dataType>
<allowedValueList>
<allowedValue>Sending</allowedValue>
<allowedValue>Ready</allowedValue>
<allowedValue>Blocked</allowedValue>
<allowedValue>Inactive</allowedValue>
<allowedValue>Disabled</allowedValue>
</allowedValueList>
</stateVariable>
<stateVariable sendEvents="yes">
<name>Enabled</name>
<dataType>boolean</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>Attributes</name>
<dataType>string</dataType>
</stateVariable>
</serviceStateTable>
</scpd>
+120
View File
@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<scpd xmlns="urn:schemas-upnp-org:service-1-0">
<specVersion>
<major>1</major>
<minor>0</minor>
</specVersion>
<actionList>
<action>
<name>Subscribe</name>
<argumentList>
<argument>
<name>ClientId</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_ClientId</relatedStateVariable>
</argument>
<argument>
<name>Udn</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_Udn</relatedStateVariable>
</argument>
<argument>
<name>Service</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_Service</relatedStateVariable>
</argument>
<argument>
<name>RequestedDuration</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_RequestedDuration</relatedStateVariable>
</argument>
<argument>
<name>Sid</name>
<direction>out</direction>
<relatedStateVariable>A_ARG_TYPE_Sid</relatedStateVariable>
</argument>
<argument>
<name>Duration</name>
<direction>out</direction>
<relatedStateVariable>A_ARG_TYPE_Duration</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>Unsubscribe</name>
<argumentList>
<argument>
<name>Sid</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_Sid</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>Renew</name>
<argumentList>
<argument>
<name>Sid</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_Sid</relatedStateVariable>
</argument>
<argument>
<name>RequestedDuration</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_RequestedDuration</relatedStateVariable>
</argument>
<argument>
<name>Duration</name>
<direction>out</direction>
<relatedStateVariable>A_ARG_TYPE_Duration</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>GetPropertyUpdates</name>
<argumentList>
<argument>
<name>ClientId</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_ClientId</relatedStateVariable>
</argument>
<argument>
<name>Updates</name>
<direction>out</direction>
<relatedStateVariable>A_ARG_TYPE_PropertyUpdates</relatedStateVariable>
</argument>
</argumentList>
</action>
</actionList>
<serviceStateTable>
<stateVariable sendEvents="no">
<name>A_ARG_TYPE_ClientId</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>A_ARG_TYPE_Udn</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>A_ARG_TYPE_Service</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>A_ARG_TYPE_RequestedDuration</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>A_ARG_TYPE_Sid</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>A_ARG_TYPE_Duration</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>A_ARG_TYPE_PropertyUpdates</name>
<dataType>string</dataType>
</stateVariable>
</serviceStateTable>
</scpd>
+44
View File
@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<scpd xmlns="urn:schemas-upnp-org:service-1-0">
<specVersion>
<major>1</major>
<minor>0</minor>
</specVersion>
<actionList>
<action>
<name>Time</name>
<argumentList>
<argument>
<name>TrackCount</name>
<direction>out</direction>
<relatedStateVariable>TrackCount</relatedStateVariable>
</argument>
<argument>
<name>Duration</name>
<direction>out</direction>
<relatedStateVariable>Duration</relatedStateVariable>
</argument>
<argument>
<name>Seconds</name>
<direction>out</direction>
<relatedStateVariable>Seconds</relatedStateVariable>
</argument>
</argumentList>
</action>
</actionList>
<serviceStateTable>
<stateVariable sendEvents="yes">
<name>TrackCount</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>Duration</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>Seconds</name>
<dataType>ui4</dataType>
</stateVariable>
</serviceStateTable>
</scpd>
+249
View File
@@ -0,0 +1,249 @@
<?xml version="1.0" encoding="utf-8"?>
<scpd xmlns="urn:schemas-upnp-org:service-1-0">
<specVersion>
<major>1</major>
<minor>0</minor>
</specVersion>
<actionList>
<action>
<name>PlayAs</name>
<argumentList>
<argument>
<name>Mode</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_string</relatedStateVariable>
</argument>
<argument>
<name>Command</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_string</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>Play</name>
</action>
<action>
<name>Pause</name>
</action>
<action>
<name>Stop</name>
</action>
<action>
<name>SkipNext</name>
</action>
<action>
<name>SkipPrevious</name>
</action>
<action>
<name>SetRepeat</name>
<argumentList>
<argument>
<name>Repeat</name>
<direction>in</direction>
<relatedStateVariable>Repeat</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>SetShuffle</name>
<argumentList>
<argument>
<name>Shuffle</name>
<direction>in</direction>
<relatedStateVariable>Shuffle</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>SeekSecondAbsolute</name>
<argumentList>
<argument>
<name>StreamId</name>
<direction>in</direction>
<relatedStateVariable>StreamId</relatedStateVariable>
</argument>
<argument>
<name>SecondAbsolute</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_uint</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>SeekSecondRelative</name>
<argumentList>
<argument>
<name>StreamId</name>
<direction>in</direction>
<relatedStateVariable>StreamId</relatedStateVariable>
</argument>
<argument>
<name>SecondRelative</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_int</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>TransportState</name>
<argumentList>
<argument>
<name>State</name>
<direction>out</direction>
<relatedStateVariable>TransportState</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>Modes</name>
<argumentList>
<argument>
<name>Modes</name>
<direction>out</direction>
<relatedStateVariable>Modes</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>ModeInfo</name>
<argumentList>
<argument>
<name>CanSkipNext</name>
<direction>out</direction>
<relatedStateVariable>CanSkipNext</relatedStateVariable>
</argument>
<argument>
<name>CanSkipPrevious</name>
<direction>out</direction>
<relatedStateVariable>CanSkipPrevious</relatedStateVariable>
</argument>
<argument>
<name>CanRepeat</name>
<direction>out</direction>
<relatedStateVariable>CanRepeat</relatedStateVariable>
</argument>
<argument>
<name>CanShuffle</name>
<direction>out</direction>
<relatedStateVariable>CanShuffle</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>StreamInfo</name>
<argumentList>
<argument>
<name>StreamId</name>
<direction>out</direction>
<relatedStateVariable>StreamId</relatedStateVariable>
</argument>
<argument>
<name>CanSeek</name>
<direction>out</direction>
<relatedStateVariable>CanSeek</relatedStateVariable>
</argument>
<argument>
<name>CanPause</name>
<direction>out</direction>
<relatedStateVariable>CanPause</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>StreamId</name>
<argumentList>
<argument>
<name>StreamId</name>
<direction>out</direction>
<relatedStateVariable>StreamId</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>Repeat</name>
<argumentList>
<argument>
<name>Repeat</name>
<direction>out</direction>
<relatedStateVariable>Repeat</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>Shuffle</name>
<argumentList>
<argument>
<name>Shuffle</name>
<direction>out</direction>
<relatedStateVariable>Shuffle</relatedStateVariable>
</argument>
</argumentList>
</action>
</actionList>
<serviceStateTable>
<stateVariable sendEvents="yes">
<name>Modes</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>CanSkipNext</name>
<dataType>boolean</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>CanSkipPrevious</name>
<dataType>boolean</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>CanRepeat</name>
<dataType>boolean</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>CanShuffle</name>
<dataType>boolean</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>StreamId</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>CanSeek</name>
<dataType>boolean</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>CanPause</name>
<dataType>boolean</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>TransportState</name>
<dataType>string</dataType>
<allowedValueList>
<allowedValue>Playing</allowedValue>
<allowedValue>Paused</allowedValue>
<allowedValue>Stopped</allowedValue>
<allowedValue>Buffering</allowedValue>
<allowedValue>Waiting</allowedValue>
</allowedValueList>
</stateVariable>
<stateVariable sendEvents="yes">
<name>Repeat</name>
<dataType>boolean</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>Shuffle</name>
<dataType>boolean</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>A_ARG_TYPE_uint</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>A_ARG_TYPE_int</name>
<dataType>i4</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>A_ARG_TYPE_string</name>
<dataType>string</dataType>
</stateVariable>
</serviceStateTable>
</scpd>
+200
View File
@@ -0,0 +1,200 @@
<?xml version="1.0" encoding="utf-8"?>
<scpd xmlns="urn:schemas-upnp-org:service-1-0">
<specVersion>
<major>1</major>
<minor>0</minor>
</specVersion>
<actionList>
<action>
<name>Characteristics</name>
<argumentList>
<argument>
<name>VolumeMax</name>
<direction>out</direction>
<relatedStateVariable>VolumeMax</relatedStateVariable>
</argument>
<argument>
<name>VolumeUnity</name>
<direction>out</direction>
<relatedStateVariable>VolumeUnity</relatedStateVariable>
</argument>
<argument>
<name>VolumeSteps</name>
<direction>out</direction>
<relatedStateVariable>VolumeSteps</relatedStateVariable>
</argument>
<argument>
<name>VolumeMilliDbPerStep</name>
<direction>out</direction>
<relatedStateVariable>VolumeMilliDbPerStep</relatedStateVariable>
</argument>
<argument>
<name>BalanceMax</name>
<direction>out</direction>
<relatedStateVariable>BalanceMax</relatedStateVariable>
</argument>
<argument>
<name>FadeMax</name>
<direction>out</direction>
<relatedStateVariable>FadeMax</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>SetVolume</name>
<argumentList>
<argument>
<name>Value</name>
<direction>in</direction>
<relatedStateVariable>Volume</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>VolumeInc</name>
</action>
<action>
<name>VolumeDec</name>
</action>
<action>
<name>Volume</name>
<argumentList>
<argument>
<name>Value</name>
<direction>out</direction>
<relatedStateVariable>Volume</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>SetBalance</name>
<argumentList>
<argument>
<name>Value</name>
<direction>in</direction>
<relatedStateVariable>Balance</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>BalanceInc</name>
</action>
<action>
<name>BalanceDec</name>
</action>
<action>
<name>Balance</name>
<argumentList>
<argument>
<name>Value</name>
<direction>out</direction>
<relatedStateVariable>Balance</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>SetFade</name>
<argumentList>
<argument>
<name>Value</name>
<direction>in</direction>
<relatedStateVariable>Fade</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>FadeInc</name>
</action>
<action>
<name>FadeDec</name>
</action>
<action>
<name>Fade</name>
<argumentList>
<argument>
<name>Value</name>
<direction>out</direction>
<relatedStateVariable>Fade</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>SetMute</name>
<argumentList>
<argument>
<name>Value</name>
<direction>in</direction>
<relatedStateVariable>Mute</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>Mute</name>
<argumentList>
<argument>
<name>Value</name>
<direction>out</direction>
<relatedStateVariable>Mute</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>VolumeLimit</name>
<argumentList>
<argument>
<name>Value</name>
<direction>out</direction>
<relatedStateVariable>VolumeLimit</relatedStateVariable>
</argument>
</argumentList>
</action>
</actionList>
<serviceStateTable>
<stateVariable sendEvents="yes">
<name>Volume</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>Mute</name>
<dataType>boolean</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>Balance</name>
<dataType>i4</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>Fade</name>
<dataType>i4</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>VolumeLimit</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>VolumeMax</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>VolumeUnity</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>VolumeSteps</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>VolumeMilliDbPerStep</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>BalanceMax</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>FadeMax</name>
<dataType>ui4</dataType>
</stateVariable>
</serviceStateTable>
</scpd>
+214
View File
@@ -0,0 +1,214 @@
<?xml version="1.0" encoding="utf-8"?>
<scpd xmlns="urn:schemas-upnp-org:service-1-0">
<specVersion>
<major>1</major>
<minor>0</minor>
</specVersion>
<actionList>
<action>
<name>Characteristics</name>
<argumentList>
<argument>
<name>VolumeMax</name>
<direction>out</direction>
<relatedStateVariable>VolumeMax</relatedStateVariable>
</argument>
<argument>
<name>VolumeUnity</name>
<direction>out</direction>
<relatedStateVariable>VolumeUnity</relatedStateVariable>
</argument>
<argument>
<name>VolumeSteps</name>
<direction>out</direction>
<relatedStateVariable>VolumeSteps</relatedStateVariable>
</argument>
<argument>
<name>VolumeMilliDbPerStep</name>
<direction>out</direction>
<relatedStateVariable>VolumeMilliDbPerStep</relatedStateVariable>
</argument>
<argument>
<name>BalanceMax</name>
<direction>out</direction>
<relatedStateVariable>BalanceMax</relatedStateVariable>
</argument>
<argument>
<name>FadeMax</name>
<direction>out</direction>
<relatedStateVariable>FadeMax</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>SetVolume</name>
<argumentList>
<argument>
<name>Value</name>
<direction>in</direction>
<relatedStateVariable>Volume</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>VolumeInc</name>
</action>
<action>
<name>VolumeDec</name>
</action>
<action>
<name>Volume</name>
<argumentList>
<argument>
<name>Value</name>
<direction>out</direction>
<relatedStateVariable>Volume</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>SetBalance</name>
<argumentList>
<argument>
<name>Value</name>
<direction>in</direction>
<relatedStateVariable>Balance</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>BalanceInc</name>
</action>
<action>
<name>BalanceDec</name>
</action>
<action>
<name>Balance</name>
<argumentList>
<argument>
<name>Value</name>
<direction>out</direction>
<relatedStateVariable>Balance</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>SetFade</name>
<argumentList>
<argument>
<name>Value</name>
<direction>in</direction>
<relatedStateVariable>Fade</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>FadeInc</name>
</action>
<action>
<name>FadeDec</name>
</action>
<action>
<name>Fade</name>
<argumentList>
<argument>
<name>Value</name>
<direction>out</direction>
<relatedStateVariable>Fade</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>SetMute</name>
<argumentList>
<argument>
<name>Value</name>
<direction>in</direction>
<relatedStateVariable>Mute</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>Mute</name>
<argumentList>
<argument>
<name>Value</name>
<direction>out</direction>
<relatedStateVariable>Mute</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>VolumeLimit</name>
<argumentList>
<argument>
<name>Value</name>
<direction>out</direction>
<relatedStateVariable>VolumeLimit</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>UnityGain</name>
<argumentList>
<argument>
<name>Value</name>
<direction>out</direction>
<relatedStateVariable>UnityGain</relatedStateVariable>
</argument>
</argumentList>
</action>
</actionList>
<serviceStateTable>
<stateVariable sendEvents="yes">
<name>Volume</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>Mute</name>
<dataType>boolean</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>Balance</name>
<dataType>i4</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>Fade</name>
<dataType>i4</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>VolumeLimit</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>VolumeMax</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>VolumeUnity</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>VolumeSteps</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>VolumeMilliDbPerStep</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>BalanceMax</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>FadeMax</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>UnityGain</name>
<dataType>boolean</dataType>
</stateVariable>
</serviceStateTable>
</scpd>
+297
View File
@@ -0,0 +1,297 @@
<?xml version="1.0" encoding="utf-8"?>
<scpd xmlns="urn:schemas-upnp-org:service-1-0">
<specVersion>
<major>1</major>
<minor>0</minor>
</specVersion>
<actionList>
<action>
<name>Characteristics</name>
<argumentList>
<argument>
<name>VolumeMax</name>
<direction>out</direction>
<relatedStateVariable>VolumeMax</relatedStateVariable>
</argument>
<argument>
<name>VolumeUnity</name>
<direction>out</direction>
<relatedStateVariable>VolumeUnity</relatedStateVariable>
</argument>
<argument>
<name>VolumeSteps</name>
<direction>out</direction>
<relatedStateVariable>VolumeSteps</relatedStateVariable>
</argument>
<argument>
<name>VolumeMilliDbPerStep</name>
<direction>out</direction>
<relatedStateVariable>VolumeMilliDbPerStep</relatedStateVariable>
</argument>
<argument>
<name>BalanceMax</name>
<direction>out</direction>
<relatedStateVariable>BalanceMax</relatedStateVariable>
</argument>
<argument>
<name>FadeMax</name>
<direction>out</direction>
<relatedStateVariable>FadeMax</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>SetVolume</name>
<argumentList>
<argument>
<name>Value</name>
<direction>in</direction>
<relatedStateVariable>Volume</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>VolumeInc</name>
</action>
<action>
<name>VolumeDec</name>
</action>
<action>
<name>Volume</name>
<argumentList>
<argument>
<name>Value</name>
<direction>out</direction>
<relatedStateVariable>Volume</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>SetBalance</name>
<argumentList>
<argument>
<name>Value</name>
<direction>in</direction>
<relatedStateVariable>Balance</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>BalanceInc</name>
</action>
<action>
<name>BalanceDec</name>
</action>
<action>
<name>Balance</name>
<argumentList>
<argument>
<name>Value</name>
<direction>out</direction>
<relatedStateVariable>Balance</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>SetFade</name>
<argumentList>
<argument>
<name>Value</name>
<direction>in</direction>
<relatedStateVariable>Fade</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>FadeInc</name>
</action>
<action>
<name>FadeDec</name>
</action>
<action>
<name>Fade</name>
<argumentList>
<argument>
<name>Value</name>
<direction>out</direction>
<relatedStateVariable>Fade</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>SetMute</name>
<argumentList>
<argument>
<name>Value</name>
<direction>in</direction>
<relatedStateVariable>Mute</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>Mute</name>
<argumentList>
<argument>
<name>Value</name>
<direction>out</direction>
<relatedStateVariable>Mute</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>VolumeLimit</name>
<argumentList>
<argument>
<name>Value</name>
<direction>out</direction>
<relatedStateVariable>VolumeLimit</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>UnityGain</name>
<argumentList>
<argument>
<name>Value</name>
<direction>out</direction>
<relatedStateVariable>UnityGain</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>VolumeOffset</name>
<argumentList>
<argument>
<name>Channel</name>
<direction>in</direction>
<relatedStateVariable>Channel</relatedStateVariable>
</argument>
<argument>
<name>VolumeOffsetBinaryMilliDb</name>
<direction>out</direction>
<relatedStateVariable>VolumeOffsetBinaryMilliDb</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>SetVolumeOffset</name>
<argumentList>
<argument>
<name>Channel</name>
<direction>in</direction>
<relatedStateVariable>Channel</relatedStateVariable>
</argument>
<argument>
<name>VolumeOffsetBinaryMilliDb</name>
<direction>in</direction>
<relatedStateVariable>VolumeOffsetBinaryMilliDb</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>Trim</name>
<argumentList>
<argument>
<name>Channel</name>
<direction>in</direction>
<relatedStateVariable>Channel</relatedStateVariable>
</argument>
<argument>
<name>TrimBinaryMilliDb</name>
<direction>out</direction>
<relatedStateVariable>TrimBinaryMilliDb</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>SetTrim</name>
<argumentList>
<argument>
<name>Channel</name>
<direction>in</direction>
<relatedStateVariable>Channel</relatedStateVariable>
</argument>
<argument>
<name>TrimBinaryMilliDb</name>
<direction>in</direction>
<relatedStateVariable>TrimBinaryMilliDb</relatedStateVariable>
</argument>
</argumentList>
</action>
</actionList>
<serviceStateTable>
<stateVariable sendEvents="yes">
<name>Volume</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>Mute</name>
<dataType>boolean</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>Balance</name>
<dataType>i4</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>Fade</name>
<dataType>i4</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>VolumeLimit</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>VolumeMax</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>VolumeUnity</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>VolumeSteps</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>VolumeMilliDbPerStep</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>BalanceMax</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>FadeMax</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>UnityGain</name>
<dataType>boolean</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>Channel</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>VolumeOffsetBinaryMilliDb</name>
<dataType>i4</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>VolumeOffsets</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>VolumeOffsetMax</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>TrimBinaryMilliDb</name>
<dataType>i4</dataType>
</stateVariable>
<stateVariable sendEvents="yes">
<name>Trim</name>
<dataType>string</dataType>
</stateVariable>
</serviceStateTable>
</scpd>
+20 -7
View File
@@ -1,11 +1,12 @@
package goupnp
import (
"context"
"fmt"
"net"
"net/url"
"github.com/huin/goupnp/soap"
"git.cyrilix.bzh/cyrilix/goupnp/soap"
)
// ServiceClient is a SOAP client, root device and the service for the SOAP
@@ -21,12 +22,12 @@ type ServiceClient struct {
localAddr net.IP
}
// NewServiceClients discovers services, and returns clients for them. err will
// NewServiceClientsCtx discovers services, and returns clients for them. err will
// report any error with the discovery process (blocking any device/service
// discovery), errors reports errors on a per-root-device basis.
func NewServiceClients(searchTarget string) (clients []ServiceClient, errors []error, err error) {
func NewServiceClientsCtx(ctx context.Context, searchTarget string) (clients []ServiceClient, errors []error, err error) {
var maybeRootDevices []MaybeRootDevice
if maybeRootDevices, err = DiscoverDevices(searchTarget); err != nil {
if maybeRootDevices, err = DiscoverDevicesCtx(ctx, searchTarget); err != nil {
return
}
@@ -49,16 +50,28 @@ func NewServiceClients(searchTarget string) (clients []ServiceClient, errors []e
return
}
// NewServiceClientsByURL creates client(s) for the given service URN, for a
// NewServiceClients is the legacy version of NewServiceClientsCtx, but uses
// context.Background() as the context.
func NewServiceClients(searchTarget string) (clients []ServiceClient, errors []error, err error) {
return NewServiceClientsCtx(context.Background(), searchTarget)
}
// NewServiceClientsByURLCtx creates client(s) for the given service URN, for a
// root device at the given URL.
func NewServiceClientsByURL(loc *url.URL, searchTarget string) ([]ServiceClient, error) {
rootDevice, err := DeviceByURL(loc)
func NewServiceClientsByURLCtx(ctx context.Context, loc *url.URL, searchTarget string) ([]ServiceClient, error) {
rootDevice, err := DeviceByURLCtx(ctx, loc)
if err != nil {
return nil, err
}
return NewServiceClientsFromRootDevice(rootDevice, loc, searchTarget)
}
// NewServiceClientsByURL is the legacy version of NewServiceClientsByURLCtx, but uses
// context.Background() as the context.
func NewServiceClientsByURL(loc *url.URL, searchTarget string) ([]ServiceClient, error) {
return NewServiceClientsByURLCtx(context.Background(), loc, searchTarget)
}
// NewServiceClientsFromDevice creates client(s) for the given service URN, in
// a given root device. The loc parameter is simply assigned to the
// Location attribute of the returned ServiceClient(s).
+6 -2
View File
@@ -194,9 +194,13 @@ type soapBody struct {
// SOAPFaultError implements error, and contains SOAP fault information.
type SOAPFaultError struct {
FaultCode string `xml:"faultCode"`
FaultString string `xml:"faultString"`
FaultCode string `xml:"faultcode"`
FaultString string `xml:"faultstring"`
Detail struct {
UPnPError struct {
Errorcode int `xml:"errorCode"`
ErrorDescription string `xml:"errorDescription"`
} `xml:"UPnPError"`
Raw []byte `xml:",innerxml"`
} `xml:"detail"`
}
+71
View File
@@ -2,10 +2,12 @@ package soap
import (
"bytes"
"errors"
"io/ioutil"
"net/http"
"net/url"
"reflect"
"strings"
"testing"
)
@@ -87,6 +89,75 @@ func TestActionInputs(t *testing.T) {
}
}
func TestUPnPError(t *testing.T) {
t.Parallel()
url, err := url.Parse("http://example.com/soap")
if err != nil {
t.Fatal(err)
}
body := `
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<s:Body>
<s:Fault>
<faultcode>s:Client</faultcode>
<faultstring>UPnPError</faultstring>
<detail>
<UPnPError xmlns="urn:schemas-upnp-org:control-1-0">
<errorCode>725</errorCode>
<errorDescription>OnlyPermanentLeasesSupported</errorDescription>
</UPnPError>
</detail>
</s:Fault>
</s:Body>
</s:Envelope>`
rt := &capturingRoundTripper{
resp: &http.Response{
StatusCode: 500,
ContentLength: int64(len(body)),
Body: ioutil.NopCloser(bytes.NewBufferString(body)),
},
}
client := SOAPClient{
EndpointURL: *url,
HTTPClient: http.Client{
Transport: rt,
},
}
err = client.PerformAction("mynamespace", "myaction", nil, nil)
if err == nil {
t.Fatal("expected error, got nil")
}
if testing.Verbose() {
t.Logf("%+v\n", err)
}
soapErr := &SOAPFaultError{}
if ok := errors.As(err, &soapErr); !ok {
t.Fatal("expected *SOAPFaultError")
}
if soapErr.FaultCode != "s:Client" {
t.Fatalf("unexpected FaultCode: %s", soapErr.FaultCode)
}
if soapErr.FaultString != "UPnPError" {
t.Fatalf("unexpected FaultString: %s", soapErr.FaultString)
}
if soapErr.Detail.UPnPError.Errorcode != 725 {
t.Fatalf("unexpected UPnPError Errorcode: %d", soapErr.Detail.UPnPError.Errorcode)
}
if soapErr.Detail.UPnPError.ErrorDescription != "OnlyPermanentLeasesSupported" {
t.Fatalf("unexpected UPnPError ErrorDescription: %s",
soapErr.Detail.UPnPError.ErrorDescription)
}
if !strings.EqualFold(string(soapErr.Detail.Raw), `
<UPnPError xmlns="urn:schemas-upnp-org:control-1-0">
<errorCode>725</errorCode>
<errorDescription>OnlyPermanentLeasesSupported</errorDescription>
</UPnPError>
`) {
t.Fatalf("unexpected Detail.Raw, got:\n%s", string(soapErr.Detail.Raw))
}
}
func TestEscapeXMLText(t *testing.T) {
t.Parallel()
+1 -1
View File
@@ -10,7 +10,7 @@ import (
"sync"
"time"
"github.com/huin/goupnp/httpu"
"git.cyrilix.bzh/cyrilix/goupnp/httpu"
)
const (
+84 -9
View File
@@ -1,6 +1,7 @@
package ssdp
import (
"context"
"errors"
"log"
"net/http"
@@ -34,24 +35,90 @@ type HTTPUClient interface {
) ([]*http.Response, error)
}
// SSDPRawSearch performs a fairly raw SSDP search request, and returns the
// HTTPUClientCtx is an optional interface that will be used to perform
// HTTP-over-UDP requests if the client implements it.
type HTTPUClientCtx interface {
DoWithContext(
req *http.Request,
numSends int,
) ([]*http.Response, error)
}
// SSDPRawSearchCtx performs a fairly raw SSDP search request, and returns the
// unique response(s) that it receives. Each response has the requested
// searchTarget, a USN, and a valid location. maxWaitSeconds states how long to
// wait for responses in seconds, and must be a minimum of 1 (the
// implementation waits an additional 100ms for responses to arrive), 2 is a
// reasonable value for this. numSends is the number of requests to send - 3 is
// a reasonable value for this.
func SSDPRawSearch(
func SSDPRawSearchCtx(
ctx context.Context,
httpu HTTPUClient,
searchTarget string,
maxWaitSeconds int,
numSends int,
) ([]*http.Response, error) {
if maxWaitSeconds < 1 {
return nil, errors.New("ssdp: maxWaitSeconds must be >= 1")
req, err := prepareRequest(ctx, searchTarget, maxWaitSeconds)
if err != nil {
return nil, err
}
req := http.Request{
allResponses, err := httpu.Do(req, time.Duration(maxWaitSeconds)*time.Second+100*time.Millisecond, numSends)
if err != nil {
return nil, err
}
return processSSDPResponses(searchTarget, allResponses)
}
// RawSearch performs a fairly raw SSDP search request, and returns the
// unique response(s) that it receives. Each response has the requested
// searchTarget, a USN, and a valid location. If the provided context times out
// or is canceled, the search will be aborted. numSends is the number of
// requests to send - 3 is a reasonable value for this.
//
// The provided context should have a deadline, since the SSDP protocol
// requires the max wait time be included in search requests. If the context
// has no deadline, then a default deadline of 3 seconds will be applied.
func RawSearch(
ctx context.Context,
httpu HTTPUClientCtx,
searchTarget string,
numSends int,
) ([]*http.Response, error) {
// We need a timeout value to include in the SSDP request; get it by
// checking the deadline on the context.
var maxWaitSeconds int
if deadline, ok := ctx.Deadline(); ok {
maxWaitSeconds = int(deadline.Sub(time.Now()) / time.Second)
} else {
// Pick a default timeout of 3 seconds if none was provided.
maxWaitSeconds = 3
var cancel func()
ctx, cancel = context.WithTimeout(ctx, time.Duration(maxWaitSeconds)*time.Second)
defer cancel()
}
req, err := prepareRequest(ctx, searchTarget, maxWaitSeconds)
if err != nil {
return nil, err
}
allResponses, err := httpu.DoWithContext(req, numSends)
if err != nil {
return nil, err
}
return processSSDPResponses(searchTarget, allResponses)
}
// prepareRequest checks the provided parameters and constructs a SSDP search
// request to be sent.
func prepareRequest(ctx context.Context, searchTarget string, maxWaitSeconds int) (*http.Request, error) {
if maxWaitSeconds < 1 {
return nil, errors.New("ssdp: request timeout must be at least 1s")
}
req := (&http.Request{
Method: methodSearch,
// TODO: Support both IPv4 and IPv6.
Host: ssdpUDP4Addr,
@@ -64,12 +131,14 @@ func SSDPRawSearch(
"MAN": []string{ssdpDiscover},
"ST": []string{searchTarget},
},
}
allResponses, err := httpu.Do(&req, time.Duration(maxWaitSeconds)*time.Second+100*time.Millisecond, numSends)
if err != nil {
return nil, err
}).WithContext(ctx)
return req, nil
}
func processSSDPResponses(
searchTarget string,
allResponses []*http.Response,
) ([]*http.Response, error) {
isExactSearch := searchTarget != SSDPAll && searchTarget != UPNPRootDevice
seenIDs := make(map[string]bool)
@@ -97,3 +166,9 @@ func SSDPRawSearch(
return responses, nil
}
// SSDPRawSearch is the legacy version of SSDPRawSearchCtx, but uses
// context.Background() as the context.
func SSDPRawSearch(httpu HTTPUClient, searchTarget string, maxWaitSeconds int, numSends int) ([]*http.Response, error) {
return SSDPRawSearchCtx(context.Background(), httpu, searchTarget, maxWaitSeconds, numSends)
}
+88 -41
View File
@@ -23,7 +23,9 @@ import (
"github.com/huin/goupnp/v2alpha/description/typedesc"
"github.com/huin/goupnp/v2alpha/description/xmlsrvdesc"
"github.com/huin/goupnp/v2alpha/soap"
"github.com/huin/goupnp/v2alpha/soap/types"
"golang.org/x/exp/maps"
soaptypes "github.com/huin/goupnp/v2alpha/soap/types"
)
var (
@@ -31,7 +33,9 @@ var (
outputDir = flag.String("output_dir", "", "Path to directory to write output in.")
srvManifests = flag.String("srv_manifests", "", "Path to srvmanifests.toml")
srvTemplate = flag.String("srv_template", "", "Path to srv.gotemplate.")
upnpresourcesZip = flag.String("upnpresources_zip", "", "Path to upnpresources.zip.")
upnpresourcesZip = flag.String("upnpresources_zip", "",
"Path to upnpresources.zip, downloaded from "+
"https://openconnectivity.org/upnp-specs/upnpresources.zip.")
)
const soapActionInterface = "SOAPActionInterface"
@@ -50,14 +54,14 @@ func run() error {
}
if *outputDir == "" {
return errors.New("-output_dir is a required flag.")
return errors.New("-output_dir is a required flag")
}
if err := os.MkdirAll(*outputDir, 0); err != nil {
return fmt.Errorf("creating output_dir %q: %w", *outputDir, err)
}
if *srvManifests == "" {
return errors.New("-srv_manifests is a required flag.")
return errors.New("-srv_manifests is a required flag")
}
var manifests DCPSpecManifests
_, err := toml.DecodeFile(*srvManifests, &manifests)
@@ -66,7 +70,7 @@ func run() error {
}
if *srvTemplate == "" {
return errors.New("-srv_template is a required flag.")
return errors.New("-srv_template is a required flag")
}
tmpl, err := template.New(filepath.Base(*srvTemplate)).Funcs(template.FuncMap{
"args": tmplfuncs.Args,
@@ -77,7 +81,7 @@ func run() error {
}
if *upnpresourcesZip == "" {
return errors.New("-upnpresources_zip is a required flag.")
return errors.New("-upnpresources_zip is a required flag")
}
f, err := os.Open(*upnpresourcesZip)
if err != nil {
@@ -91,7 +95,7 @@ func run() error {
// Use default type map for now. Addtional types could be use instead or
// as well as necessary for extended types.
typeMap := types.TypeMap().Clone()
typeMap := soaptypes.TypeMap().Clone()
typeMap[soapActionInterface] = typedesc.TypeDesc{
GoType: reflect.TypeOf((*soap.Action)(nil)).Elem(),
}
@@ -158,7 +162,8 @@ func processService(
return fmt.Errorf("transforming service description: %w", err)
}
imps, err := accumulateImports(sd, typeMap)
imps := newImports()
types, err := accumulateTypes(sd, typeMap, imps)
if err != nil {
return err
}
@@ -167,6 +172,7 @@ func processService(
err = tmpl.ExecuteTemplate(buf, "service", tmplArgs{
Manifest: srvManifest,
Imps: imps,
Types: types,
SCPD: sd,
})
if err != nil {
@@ -219,14 +225,44 @@ type ServiceManifest struct {
type tmplArgs struct {
Manifest *ServiceManifest
Imps *imports
Types *types
SCPD *srvdesc.SCPD
}
type imports struct {
// Maps from a type name like "ui4" to the `alias.name` for the import.
TypeByName map[string]typeDesc
// Each required import line, ordered by path.
ImportLines []importItem
// aliasByPath maps from import path to its imported alias.
aliasByPath map[string]string
// nextAlias is the number for the next import alias.
nextAlias int
}
func newImports() *imports {
return &imports{
aliasByPath: make(map[string]string),
nextAlias: 1,
}
}
func (imps *imports) getAliasForPath(path string) string {
if alias, ok := imps.aliasByPath[path]; ok {
return alias
}
alias := fmt.Sprintf("pkg%d", imps.nextAlias)
imps.nextAlias++
imps.ImportLines = append(imps.ImportLines, importItem{
Alias: alias,
Path: path,
})
imps.aliasByPath[path] = alias
return alias
}
type types struct {
// Maps from a type name like "ui4" to the `alias.name` for the import.
TypeByName map[string]typeDesc
StringVarDefs []stringVarDef
}
type typeDesc struct {
@@ -239,17 +275,41 @@ type typeDesc struct {
Name string
}
type stringVarDef struct {
Name string
AllowedValues []string
}
type importItem struct {
Alias string
Path string
}
func accumulateImports(srvDesc *srvdesc.SCPD, typeMap typedesc.TypeMap) (*imports, error) {
typeNames := make(map[string]bool)
typeNames[soapActionInterface] = true
// accumulateTypes creates type information, and adds any required imports for
// them.
func accumulateTypes(
srvDesc *srvdesc.SCPD,
typeMap typedesc.TypeMap,
imps *imports,
) (*types, error) {
typeNames := make(map[string]struct{})
typeNames[soapActionInterface] = struct{}{}
err := visitTypesSCPD(srvDesc, func(typeName string) {
typeNames[typeName] = true
var stringVarDefs []stringVarDef
sortedVarNames := maps.Keys(srvDesc.VariableByName)
sort.Strings(sortedVarNames)
for _, svName := range sortedVarNames {
sv := srvDesc.VariableByName[svName]
if sv.DataType == "string" && len(sv.AllowedValues) > 0 {
stringVarDefs = append(stringVarDefs, stringVarDef{
Name: svName,
AllowedValues: srvDesc.VariableByName[svName].AllowedValues,
})
}
}
err := visitTypesSCPD(srvDesc, func(sv *srvdesc.StateVariable) {
typeNames[sv.DataType] = struct{}{}
})
if err != nil {
return nil, err
@@ -257,7 +317,7 @@ func accumulateImports(srvDesc *srvdesc.SCPD, typeMap typedesc.TypeMap) (*import
// Have sorted list of import package paths. Partly for aesthetics of generated code, but also
// to have stable-generated aliases.
paths := make(map[string]bool)
paths := make(map[string]struct{})
for typeName := range typeNames {
t, ok := typeMap[typeName]
if !ok {
@@ -265,29 +325,17 @@ func accumulateImports(srvDesc *srvdesc.SCPD, typeMap typedesc.TypeMap) (*import
}
pkgPath := t.GoType.PkgPath()
if pkgPath == "" {
// Builtin type, ignore.
// Builtin type, no import needed.
continue
}
paths[pkgPath] = true
}
sortedPaths := make([]string, 0, len(paths))
for path := range paths {
sortedPaths = append(sortedPaths, path)
paths[pkgPath] = struct{}{}
}
sortedPaths := maps.Keys(paths)
sort.Strings(sortedPaths)
// Generate import aliases.
index := 1
aliasByPath := make(map[string]string, len(paths))
importLines := make([]importItem, 0, len(paths))
// Generate import aliases in deterministic order.
for _, path := range sortedPaths {
alias := fmt.Sprintf("pkg%d", index)
index++
importLines = append(importLines, importItem{
Alias: alias,
Path: path,
})
aliasByPath[path] = alias
imps.getAliasForPath(path)
}
// Populate typeByName.
@@ -295,28 +343,27 @@ func accumulateImports(srvDesc *srvdesc.SCPD, typeMap typedesc.TypeMap) (*import
for typeName := range typeNames {
goType := typeMap[typeName]
pkgPath := goType.GoType.PkgPath()
alias := aliasByPath[pkgPath]
td := typeDesc{
Name: goType.GoType.Name(),
}
if alias == "" {
if pkgPath == "" {
// Builtin type.
td.AbsRef = td.Name
td.Ref = td.Name
} else {
td.AbsRef = strconv.Quote(pkgPath) + "." + td.Name
td.Ref = alias + "." + td.Name
td.Ref = imps.getAliasForPath(pkgPath) + "." + td.Name
}
typeByName[typeName] = td
}
return &imports{
return &types{
TypeByName: typeByName,
ImportLines: importLines,
StringVarDefs: stringVarDefs,
}, nil
}
type typeVisitor func(typeName string)
type typeVisitor func(sv *srvdesc.StateVariable)
// visitTypesSCPD calls `visitor` with each data type name (e.g. "ui4") referenced
// by action arguments.`
@@ -335,14 +382,14 @@ func visitTypesAction(action *srvdesc.Action, visitor typeVisitor) error {
if err != nil {
return err
}
visitor(sv.DataType)
visitor(sv)
}
for _, arg := range action.OutArgs {
sv, err := arg.RelatedStateVariable()
if err != nil {
return err
}
visitor(sv.DataType)
visitor(sv)
}
return nil
}
+19 -12
View File
@@ -10,9 +10,9 @@ import (
)
var (
BadDescriptionError = errors.New("bad XML description")
MissingDefinitionError = errors.New("missing definition")
UnsupportedDescriptionError = errors.New("unsupported XML description")
ErrBadDescription = errors.New("bad XML description")
ErrMissingDefinition = errors.New("missing definition")
ErrUnsupportedDescription = errors.New("unsupported XML description")
)
// SCPD is the top level service description.
@@ -37,7 +37,7 @@ func FromXML(xmlDesc *xmlsrvdesc.SCPD) (*SCPD, error) {
}
if _, exists := stateVariables[sv.Name]; exists {
return nil, fmt.Errorf("%w: multiple state variables with name %q",
BadDescriptionError, sv.Name)
ErrBadDescription, sv.Name)
}
stateVariables[sv.Name] = sv
}
@@ -49,7 +49,7 @@ func FromXML(xmlDesc *xmlsrvdesc.SCPD) (*SCPD, error) {
}
if _, exists := actions[action.Name]; exists {
return nil, fmt.Errorf("%w: multiple actions with name %q",
BadDescriptionError, action.Name)
ErrBadDescription, action.Name)
}
actions[action.Name] = action
}
@@ -79,7 +79,7 @@ type Action struct {
// actionFromXML creates an Action from the given XML description.
func actionFromXML(xmlAction *xmlsrvdesc.Action, scpd *SCPD) (*Action, error) {
if xmlAction.Name == "" {
return nil, fmt.Errorf("%w: empty action name", BadDescriptionError)
return nil, fmt.Errorf("%w: empty action name", ErrBadDescription)
}
action := &Action{
SCPD: scpd,
@@ -99,7 +99,7 @@ func actionFromXML(xmlAction *xmlsrvdesc.Action, scpd *SCPD) (*Action, error) {
outArgs = append(outArgs, arg)
default:
return nil, fmt.Errorf("%w: argument %q has invalid direction %q",
BadDescriptionError, xmlArg.Name, xmlArg.Direction)
ErrBadDescription, xmlArg.Name, xmlArg.Direction)
}
}
action.InArgs = inArgs
@@ -117,10 +117,10 @@ type Argument struct {
// argumentFromXML creates an Argument from the XML description.
func argumentFromXML(xmlArg *xmlsrvdesc.Argument, action *Action) (*Argument, error) {
if xmlArg.Name == "" {
return nil, fmt.Errorf("%w: empty argument name", BadDescriptionError)
return nil, fmt.Errorf("%w: empty argument name", ErrBadDescription)
}
if xmlArg.RelatedStateVariable == "" {
return nil, fmt.Errorf("%w: empty related state variable", BadDescriptionError)
return nil, fmt.Errorf("%w: empty related state variable", ErrBadDescription)
}
return &Argument{
Action: action,
@@ -133,25 +133,32 @@ func (arg *Argument) RelatedStateVariable() (*StateVariable, error) {
if v, ok := arg.Action.SCPD.VariableByName[arg.RelatedStateVariableName]; ok {
return v, nil
}
return nil, fmt.Errorf("%w: state variable %q", MissingDefinitionError, arg.RelatedStateVariableName)
return nil, fmt.Errorf("%w: state variable %q", ErrMissingDefinition, arg.RelatedStateVariableName)
}
// StateVariable description data.
type StateVariable struct {
Name string
DataType string
AllowedValues []string
}
func stateVariableFromXML(xmlSV *xmlsrvdesc.StateVariable) (*StateVariable, error) {
if xmlSV.Name == "" {
return nil, fmt.Errorf("%w: empty state variable name", BadDescriptionError)
return nil, fmt.Errorf("%w: empty state variable name", ErrBadDescription)
}
if xmlSV.DataType.Type != "" {
return nil, fmt.Errorf("%w: unsupported data type %q",
UnsupportedDescriptionError, xmlSV.DataType.Type)
ErrUnsupportedDescription, xmlSV.DataType.Type)
}
if xmlSV.DataType.Name != "string" && len(xmlSV.AllowedValues) > 0 {
return nil, fmt.Errorf("%w: allowedValueList is currently unsupported for type %q",
ErrUnsupportedDescription, xmlSV.DataType.Name)
}
return &StateVariable{
Name: xmlSV.Name,
DataType: xmlSV.DataType.Name,
AllowedValues: xmlSV.AllowedValues,
}, nil
}
+3 -1
View File
@@ -2,6 +2,8 @@ module github.com/huin/goupnp/v2alpha
go 1.18
require github.com/google/go-cmp v0.5.7
require github.com/google/go-cmp v0.5.8
require github.com/BurntSushi/toml v1.1.0
require golang.org/x/exp v0.0.0-20230307190834-24139beb5833 // indirect
+4
View File
@@ -2,5 +2,9 @@ github.com/BurntSushi/toml v1.1.0 h1:ksErzDEI1khOiGPgpwuI7x2ebx/uXQNw7xJpn9Eq1+I
github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o=
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
golang.org/x/exp v0.0.0-20230307190834-24139beb5833 h1:SChBja7BCQewoTAU7IgvucQKMIXrEpFxNMs0spT3/5s=
golang.org/x/exp v0.0.0-20230307190834-24139beb5833/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+68 -19
View File
@@ -8,15 +8,52 @@ import (
"fmt"
"io"
"net/http"
"strings"
"github.com/huin/goupnp/v2alpha/soap"
"github.com/huin/goupnp/v2alpha/soap/envelope"
)
var _ HttpClient = &http.Client{}
var (
// ErrSOAP can be used with errors.Is.
ErrSOAP = errors.New("SOAP error")
)
// HttpClient defines the interface required of an HTTP client. It is a subset of *http.Client.
type HttpClient interface {
// SOAPError describes an error from this package, potentially including a
// lower-level cause.
type SOAPError struct {
// description describes the error from the SOAP perspective.
description string
// cause may be nil.
cause error
}
func (se *SOAPError) Error() string {
b := &strings.Builder{}
b.WriteString("SOAP error")
if se.description != "" {
b.WriteString(": ")
b.WriteString(se.description)
}
if se.cause != nil {
b.WriteString(": ")
b.WriteString(se.cause.Error())
}
return b.String()
}
func (se *SOAPError) Is(target error) bool {
return target == ErrSOAP
}
func (se *SOAPError) Unwrap() error {
return se.cause
}
var _ HTTPClient = &http.Client{}
// HTTPClient defines the interface required of an HTTP client. It is a subset of *http.Client.
type HTTPClient interface {
Do(req *http.Request) (*http.Response, error)
}
@@ -25,22 +62,21 @@ type Option func(*options)
// WithHTTPClient specifies an *http.Client to use instead of
// http.DefaultClient.
func WithHTTPClient(httpClient HttpClient) Option {
func WithHTTPClient(httpClient HTTPClient) Option {
return func(o *options) {
o.httpClient = httpClient
}
}
type options struct {
httpClient HttpClient
httpClient HTTPClient
}
// Client is a SOAP client, attached to a specific SOAP endpoint.
// the zero value is not usable, use NewClient() to create an instance.
type Client struct {
httpClient HttpClient
httpClient HTTPClient
endpointURL string
maxErrorResponseBytes int
}
// New creates a new SOAP client, which will POST its requests to the
@@ -79,8 +115,10 @@ func (c *Client) Do(
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("SOAP request got HTTP %s (%d)",
resp.Status, resp.StatusCode)
return &SOAPError{
description: fmt.Sprintf("SOAP request got HTTP %s (%d)",
resp.Status, resp.StatusCode),
}
}
return ParseResponseAction(resp, actionOut)
@@ -110,7 +148,10 @@ func SetRequestAction(
buf := &bytes.Buffer{}
err := envelope.Write(buf, actionIn)
if err != nil {
return fmt.Errorf("encoding envelope: %w", err)
return &SOAPError{
description: "encoding envelope",
cause: err,
}
}
req.Body = io.NopCloser(buf)
@@ -131,31 +172,39 @@ func ParseResponseAction(
actionOut *envelope.Action,
) error {
if resp.Body == nil {
return errors.New("missing response body")
return &SOAPError{description: "missing HTTP response body"}
}
buf := &bytes.Buffer{}
if _, err := io.Copy(buf, resp.Body); err != nil {
return fmt.Errorf("reading response body: %w", err)
return &SOAPError{
description: "reading HTTP response body",
cause: err,
}
}
if err := envelope.Read(buf, actionOut); err != nil {
if _, ok := err.(*envelope.Fault); ok {
if errors.Is(err, envelope.ErrFault) {
// Parsed cleanly, got SOAP fault.
return err
return &SOAPError{
description: "SOAP fault",
cause: err,
}
}
// Parsing problem, provide some information for context.
dispLen := buf.Len()
truncMessage := ""
if dispLen > 1024 {
dispLen = 1024
truncMessage = fmt.Sprintf("first %d bytes: ", dispLen)
truncMessage = fmt.Sprintf("first %d bytes (total %d bytes): ", dispLen, buf.Len())
}
return fmt.Errorf(
"parsing response body (%s%q): %w",
return &SOAPError{
description: fmt.Sprintf(
"parsing SOAP response from HTTP body (%s%q)",
truncMessage, buf.Bytes()[:dispLen],
err,
)
),
cause: err,
}
}
return nil
+6 -6
View File
@@ -321,9 +321,9 @@ var _ SOAPValue = &Fixed14_4{}
// Fixed14_4FromParts creates a Fixed14_4 from components.
// Bounds:
// * Both intPart and fracPart must have the same sign.
// * -1e14 < intPart < 1e14
// * -1e4 < fracPart < 1e4
// - Both intPart and fracPart must have the same sign.
// - -1e14 < intPart < 1e14
// - -1e4 < fracPart < 1e4
func Fixed14_4FromParts(intPart int64, fracPart int16) (Fixed14_4, error) {
var v Fixed14_4
err := v.SetParts(intPart, fracPart)
@@ -332,9 +332,9 @@ func Fixed14_4FromParts(intPart int64, fracPart int16) (Fixed14_4, error) {
// SetFromParts sets the value based on the integer component and the fractional component.
// Bounds:
// * Both intPart and fracPart must have the same sign.
// * -1e14 < intPart < 1e14
// * -1e4 < fracPart < 1e4
// - Both intPart and fracPart must have the same sign.
// - -1e14 < intPart < 1e14
// - -1e4 < fracPart < 1e4
func (v *Fixed14_4) SetParts(intPart int64, fracPart int16) error {
if (intPart < 0) != (fracPart < 0) {
return fmt.Errorf("want intPart and fracPart with same sign, got %d and %d",
@@ -34,6 +34,7 @@ func (a *DeleteDNSServer) RefResponse() any { return &a.Response }
// DeleteDNSServerRequest contains the "in" args for the "DeleteDNSServer" action.
type DeleteDNSServerRequest struct {
// NewDNSServers relates to state variable DNSServers.
NewDNSServers string
}
@@ -64,6 +65,7 @@ func (a *DeleteIPRouter) RefResponse() any { return &a.Response }
// DeleteIPRouterRequest contains the "in" args for the "DeleteIPRouter" action.
type DeleteIPRouterRequest struct {
// NewIPRouters relates to state variable IPRouters.
NewIPRouters string
}
@@ -94,6 +96,7 @@ func (a *DeleteReservedAddress) RefResponse() any { return &a.Response }
// DeleteReservedAddressRequest contains the "in" args for the "DeleteReservedAddress" action.
type DeleteReservedAddressRequest struct {
// NewReservedAddresses relates to state variable ReservedAddresses.
NewReservedAddresses string
}
@@ -127,7 +130,9 @@ type GetAddressRangeRequest struct{}
// GetAddressRangeResponse contains the "out" args for the "GetAddressRange" action.
type GetAddressRangeResponse struct {
// NewMinAddress relates to state variable MinAddress.
NewMinAddress string
// NewMaxAddress relates to state variable MaxAddress.
NewMaxAddress string
}
@@ -158,6 +163,7 @@ type GetDHCPRelayRequest struct{}
// GetDHCPRelayResponse contains the "out" args for the "GetDHCPRelay" action.
type GetDHCPRelayResponse struct {
// NewDHCPRelay relates to state variable DHCPRelay.
NewDHCPRelay pkg2.Boolean
}
@@ -188,6 +194,7 @@ type GetDHCPServerConfigurableRequest struct{}
// GetDHCPServerConfigurableResponse contains the "out" args for the "GetDHCPServerConfigurable" action.
type GetDHCPServerConfigurableResponse struct {
// NewDHCPServerConfigurable relates to state variable DHCPServerConfigurable.
NewDHCPServerConfigurable pkg2.Boolean
}
@@ -218,6 +225,7 @@ type GetDNSServersRequest struct{}
// GetDNSServersResponse contains the "out" args for the "GetDNSServers" action.
type GetDNSServersResponse struct {
// NewDNSServers relates to state variable DNSServers.
NewDNSServers string
}
@@ -248,6 +256,7 @@ type GetDomainNameRequest struct{}
// GetDomainNameResponse contains the "out" args for the "GetDomainName" action.
type GetDomainNameResponse struct {
// NewDomainName relates to state variable DomainName.
NewDomainName string
}
@@ -278,6 +287,7 @@ type GetIPRoutersListRequest struct{}
// GetIPRoutersListResponse contains the "out" args for the "GetIPRoutersList" action.
type GetIPRoutersListResponse struct {
// NewIPRouters relates to state variable IPRouters.
NewIPRouters string
}
@@ -308,6 +318,7 @@ type GetReservedAddressesRequest struct{}
// GetReservedAddressesResponse contains the "out" args for the "GetReservedAddresses" action.
type GetReservedAddressesResponse struct {
// NewReservedAddresses relates to state variable ReservedAddresses.
NewReservedAddresses string
}
@@ -338,6 +349,7 @@ type GetSubnetMaskRequest struct{}
// GetSubnetMaskResponse contains the "out" args for the "GetSubnetMask" action.
type GetSubnetMaskResponse struct {
// NewSubnetMask relates to state variable SubnetMask.
NewSubnetMask string
}
@@ -365,7 +377,9 @@ func (a *SetAddressRange) RefResponse() any { return &a.Response }
// SetAddressRangeRequest contains the "in" args for the "SetAddressRange" action.
type SetAddressRangeRequest struct {
// NewMinAddress relates to state variable MinAddress.
NewMinAddress string
// NewMaxAddress relates to state variable MaxAddress.
NewMaxAddress string
}
@@ -396,6 +410,7 @@ func (a *SetDHCPRelay) RefResponse() any { return &a.Response }
// SetDHCPRelayRequest contains the "in" args for the "SetDHCPRelay" action.
type SetDHCPRelayRequest struct {
// NewDHCPRelay relates to state variable DHCPRelay.
NewDHCPRelay pkg2.Boolean
}
@@ -426,6 +441,7 @@ func (a *SetDHCPServerConfigurable) RefResponse() any { return &a.Response }
// SetDHCPServerConfigurableRequest contains the "in" args for the "SetDHCPServerConfigurable" action.
type SetDHCPServerConfigurableRequest struct {
// NewDHCPServerConfigurable relates to state variable DHCPServerConfigurable.
NewDHCPServerConfigurable pkg2.Boolean
}
@@ -456,6 +472,7 @@ func (a *SetDNSServer) RefResponse() any { return &a.Response }
// SetDNSServerRequest contains the "in" args for the "SetDNSServer" action.
type SetDNSServerRequest struct {
// NewDNSServers relates to state variable DNSServers.
NewDNSServers string
}
@@ -486,6 +503,7 @@ func (a *SetDomainName) RefResponse() any { return &a.Response }
// SetDomainNameRequest contains the "in" args for the "SetDomainName" action.
type SetDomainNameRequest struct {
// NewDomainName relates to state variable DomainName.
NewDomainName string
}
@@ -516,6 +534,7 @@ func (a *SetIPRouter) RefResponse() any { return &a.Response }
// SetIPRouterRequest contains the "in" args for the "SetIPRouter" action.
type SetIPRouterRequest struct {
// NewIPRouters relates to state variable IPRouters.
NewIPRouters string
}
@@ -546,6 +565,7 @@ func (a *SetReservedAddress) RefResponse() any { return &a.Response }
// SetReservedAddressRequest contains the "in" args for the "SetReservedAddress" action.
type SetReservedAddressRequest struct {
// NewReservedAddresses relates to state variable ReservedAddresses.
NewReservedAddresses string
}
@@ -576,6 +596,7 @@ func (a *SetSubnetMask) RefResponse() any { return &a.Response }
// SetSubnetMaskRequest contains the "in" args for the "SetSubnetMask" action.
type SetSubnetMaskRequest struct {
// NewSubnetMask relates to state variable SubnetMask.
NewSubnetMask string
}
@@ -8,6 +8,35 @@ import (
pkg2 "github.com/huin/goupnp/v2alpha/soap/types"
)
// Allowed values for state variable ConnectionStatus.
const (
ConnectionStatus_Unconfigured = "Unconfigured"
ConnectionStatus_Connected = "Connected"
ConnectionStatus_Disconnected = "Disconnected"
)
// Allowed values for state variable LastConnectionError.
const (
LastConnectionError_ERROR_NONE = "ERROR_NONE"
)
// Allowed values for state variable PortMappingProtocol.
const (
PortMappingProtocol_TCP = "TCP"
PortMappingProtocol_UDP = "UDP"
)
// Allowed values for state variable PossibleConnectionTypes.
const (
PossibleConnectionTypes_Unconfigured = "Unconfigured"
PossibleConnectionTypes_IP_Routed = "IP_Routed"
PossibleConnectionTypes_DHCP_Spoofed = "DHCP_Spoofed"
PossibleConnectionTypes_PPPoE_Bridged = "PPPoE_Bridged"
PossibleConnectionTypes_PPTP_Relay = "PPTP_Relay"
PossibleConnectionTypes_L2TP_Relay = "L2TP_Relay"
PossibleConnectionTypes_PPPoE_Relay = "PPPoE_Relay"
)
const ServiceType = "urn:schemas-upnp-org:service:WANPPPConnection:1"
// AddPortMapping provides request and response for the action.
@@ -34,13 +63,21 @@ func (a *AddPortMapping) RefResponse() any { return &a.Response }
// AddPortMappingRequest contains the "in" args for the "AddPortMapping" action.
type AddPortMappingRequest struct {
// NewRemoteHost relates to state variable RemoteHost.
NewRemoteHost string
// NewExternalPort relates to state variable ExternalPort.
NewExternalPort pkg2.UI2
// NewProtocol relates to state variable PortMappingProtocol (2 standard allowed values).
NewProtocol string
// NewInternalPort relates to state variable InternalPort.
NewInternalPort pkg2.UI2
// NewInternalClient relates to state variable InternalClient.
NewInternalClient string
// NewEnabled relates to state variable PortMappingEnabled.
NewEnabled pkg2.Boolean
// NewPortMappingDescription relates to state variable PortMappingDescription.
NewPortMappingDescription string
// NewLeaseDuration relates to state variable PortMappingLeaseDuration.
NewLeaseDuration pkg2.UI4
}
@@ -71,7 +108,9 @@ func (a *ConfigureConnection) RefResponse() any { return &a.Response }
// ConfigureConnectionRequest contains the "in" args for the "ConfigureConnection" action.
type ConfigureConnectionRequest struct {
// NewUserName relates to state variable UserName.
NewUserName string
// NewPassword relates to state variable Password.
NewPassword string
}
@@ -102,8 +141,11 @@ func (a *DeletePortMapping) RefResponse() any { return &a.Response }
// DeletePortMappingRequest contains the "in" args for the "DeletePortMapping" action.
type DeletePortMappingRequest struct {
// NewRemoteHost relates to state variable RemoteHost.
NewRemoteHost string
// NewExternalPort relates to state variable ExternalPort.
NewExternalPort pkg2.UI2
// NewProtocol relates to state variable PortMappingProtocol (2 standard allowed values).
NewProtocol string
}
@@ -165,6 +207,7 @@ type GetAutoDisconnectTimeRequest struct{}
// GetAutoDisconnectTimeResponse contains the "out" args for the "GetAutoDisconnectTime" action.
type GetAutoDisconnectTimeResponse struct {
// NewAutoDisconnectTime relates to state variable AutoDisconnectTime.
NewAutoDisconnectTime pkg2.UI4
}
@@ -195,7 +238,9 @@ type GetConnectionTypeInfoRequest struct{}
// GetConnectionTypeInfoResponse contains the "out" args for the "GetConnectionTypeInfo" action.
type GetConnectionTypeInfoResponse struct {
// NewConnectionType relates to state variable ConnectionType.
NewConnectionType string
// NewPossibleConnectionTypes relates to state variable PossibleConnectionTypes (7 standard allowed values).
NewPossibleConnectionTypes string
}
@@ -226,6 +271,7 @@ type GetExternalIPAddressRequest struct{}
// GetExternalIPAddressResponse contains the "out" args for the "GetExternalIPAddress" action.
type GetExternalIPAddressResponse struct {
// NewExternalIPAddress relates to state variable ExternalIPAddress.
NewExternalIPAddress string
}
@@ -253,18 +299,27 @@ func (a *GetGenericPortMappingEntry) RefResponse() any { return &a.Response }
// GetGenericPortMappingEntryRequest contains the "in" args for the "GetGenericPortMappingEntry" action.
type GetGenericPortMappingEntryRequest struct {
// NewPortMappingIndex relates to state variable PortMappingNumberOfEntries.
NewPortMappingIndex pkg2.UI2
}
// GetGenericPortMappingEntryResponse contains the "out" args for the "GetGenericPortMappingEntry" action.
type GetGenericPortMappingEntryResponse struct {
// NewRemoteHost relates to state variable RemoteHost.
NewRemoteHost string
// NewExternalPort relates to state variable ExternalPort.
NewExternalPort pkg2.UI2
// NewProtocol relates to state variable PortMappingProtocol (2 standard allowed values).
NewProtocol string
// NewInternalPort relates to state variable InternalPort.
NewInternalPort pkg2.UI2
// NewInternalClient relates to state variable InternalClient.
NewInternalClient string
// NewEnabled relates to state variable PortMappingEnabled.
NewEnabled pkg2.Boolean
// NewPortMappingDescription relates to state variable PortMappingDescription.
NewPortMappingDescription string
// NewLeaseDuration relates to state variable PortMappingLeaseDuration.
NewLeaseDuration pkg2.UI4
}
@@ -295,6 +350,7 @@ type GetIdleDisconnectTimeRequest struct{}
// GetIdleDisconnectTimeResponse contains the "out" args for the "GetIdleDisconnectTime" action.
type GetIdleDisconnectTimeResponse struct {
// NewIdleDisconnectTime relates to state variable IdleDisconnectTime.
NewIdleDisconnectTime pkg2.UI4
}
@@ -325,7 +381,9 @@ type GetLinkLayerMaxBitRatesRequest struct{}
// GetLinkLayerMaxBitRatesResponse contains the "out" args for the "GetLinkLayerMaxBitRates" action.
type GetLinkLayerMaxBitRatesResponse struct {
// NewUpstreamMaxBitRate relates to state variable UpstreamMaxBitRate.
NewUpstreamMaxBitRate pkg2.UI4
// NewDownstreamMaxBitRate relates to state variable DownstreamMaxBitRate.
NewDownstreamMaxBitRate pkg2.UI4
}
@@ -356,7 +414,9 @@ type GetNATRSIPStatusRequest struct{}
// GetNATRSIPStatusResponse contains the "out" args for the "GetNATRSIPStatus" action.
type GetNATRSIPStatusResponse struct {
// NewRSIPAvailable relates to state variable RSIPAvailable.
NewRSIPAvailable pkg2.Boolean
// NewNATEnabled relates to state variable NATEnabled.
NewNATEnabled pkg2.Boolean
}
@@ -387,6 +447,7 @@ type GetPPPAuthenticationProtocolRequest struct{}
// GetPPPAuthenticationProtocolResponse contains the "out" args for the "GetPPPAuthenticationProtocol" action.
type GetPPPAuthenticationProtocolResponse struct {
// NewPPPAuthenticationProtocol relates to state variable PPPAuthenticationProtocol.
NewPPPAuthenticationProtocol string
}
@@ -417,6 +478,7 @@ type GetPPPCompressionProtocolRequest struct{}
// GetPPPCompressionProtocolResponse contains the "out" args for the "GetPPPCompressionProtocol" action.
type GetPPPCompressionProtocolResponse struct {
// NewPPPCompressionProtocol relates to state variable PPPCompressionProtocol.
NewPPPCompressionProtocol string
}
@@ -447,6 +509,7 @@ type GetPPPEncryptionProtocolRequest struct{}
// GetPPPEncryptionProtocolResponse contains the "out" args for the "GetPPPEncryptionProtocol" action.
type GetPPPEncryptionProtocolResponse struct {
// NewPPPEncryptionProtocol relates to state variable PPPEncryptionProtocol.
NewPPPEncryptionProtocol string
}
@@ -477,6 +540,7 @@ type GetPasswordRequest struct{}
// GetPasswordResponse contains the "out" args for the "GetPassword" action.
type GetPasswordResponse struct {
// NewPassword relates to state variable Password.
NewPassword string
}
@@ -504,17 +568,25 @@ func (a *GetSpecificPortMappingEntry) RefResponse() any { return &a.Response }
// GetSpecificPortMappingEntryRequest contains the "in" args for the "GetSpecificPortMappingEntry" action.
type GetSpecificPortMappingEntryRequest struct {
// NewRemoteHost relates to state variable RemoteHost.
NewRemoteHost string
// NewExternalPort relates to state variable ExternalPort.
NewExternalPort pkg2.UI2
// NewProtocol relates to state variable PortMappingProtocol (2 standard allowed values).
NewProtocol string
}
// GetSpecificPortMappingEntryResponse contains the "out" args for the "GetSpecificPortMappingEntry" action.
type GetSpecificPortMappingEntryResponse struct {
// NewInternalPort relates to state variable InternalPort.
NewInternalPort pkg2.UI2
// NewInternalClient relates to state variable InternalClient.
NewInternalClient string
// NewEnabled relates to state variable PortMappingEnabled.
NewEnabled pkg2.Boolean
// NewPortMappingDescription relates to state variable PortMappingDescription.
NewPortMappingDescription string
// NewLeaseDuration relates to state variable PortMappingLeaseDuration.
NewLeaseDuration pkg2.UI4
}
@@ -545,8 +617,11 @@ type GetStatusInfoRequest struct{}
// GetStatusInfoResponse contains the "out" args for the "GetStatusInfo" action.
type GetStatusInfoResponse struct {
// NewConnectionStatus relates to state variable ConnectionStatus (3 standard allowed values).
NewConnectionStatus string
// NewLastConnectionError relates to state variable LastConnectionError (1 standard allowed values).
NewLastConnectionError string
// NewUptime relates to state variable Uptime.
NewUptime pkg2.UI4
}
@@ -577,6 +652,7 @@ type GetUserNameRequest struct{}
// GetUserNameResponse contains the "out" args for the "GetUserName" action.
type GetUserNameResponse struct {
// NewUserName relates to state variable UserName.
NewUserName string
}
@@ -607,6 +683,7 @@ type GetWarnDisconnectDelayRequest struct{}
// GetWarnDisconnectDelayResponse contains the "out" args for the "GetWarnDisconnectDelay" action.
type GetWarnDisconnectDelayResponse struct {
// NewWarnDisconnectDelay relates to state variable WarnDisconnectDelay.
NewWarnDisconnectDelay pkg2.UI4
}
@@ -690,6 +767,7 @@ func (a *SetAutoDisconnectTime) RefResponse() any { return &a.Response }
// SetAutoDisconnectTimeRequest contains the "in" args for the "SetAutoDisconnectTime" action.
type SetAutoDisconnectTimeRequest struct {
// NewAutoDisconnectTime relates to state variable AutoDisconnectTime.
NewAutoDisconnectTime pkg2.UI4
}
@@ -720,6 +798,7 @@ func (a *SetConnectionType) RefResponse() any { return &a.Response }
// SetConnectionTypeRequest contains the "in" args for the "SetConnectionType" action.
type SetConnectionTypeRequest struct {
// NewConnectionType relates to state variable ConnectionType.
NewConnectionType string
}
@@ -750,6 +829,7 @@ func (a *SetIdleDisconnectTime) RefResponse() any { return &a.Response }
// SetIdleDisconnectTimeRequest contains the "in" args for the "SetIdleDisconnectTime" action.
type SetIdleDisconnectTimeRequest struct {
// NewIdleDisconnectTime relates to state variable IdleDisconnectTime.
NewIdleDisconnectTime pkg2.UI4
}
@@ -780,6 +860,7 @@ func (a *SetWarnDisconnectDelay) RefResponse() any { return &a.Response }
// SetWarnDisconnectDelayRequest contains the "in" args for the "SetWarnDisconnectDelay" action.
type SetWarnDisconnectDelayRequest struct {
// NewWarnDisconnectDelay relates to state variable WarnDisconnectDelay.
NewWarnDisconnectDelay pkg2.UI4
}
+24 -5
View File
@@ -1,5 +1,6 @@
{{define "service"}}
{{- $Imps := .Imps -}}
{{- $Types := .Types -}}
// Package {{.Manifest.Package}} provides types for the {{quote .Manifest.ServiceType}} service.
{{- with .Manifest.DocumentURL}}
//
@@ -13,15 +14,28 @@ import (
{{- end}}
)
{{range .Types.StringVarDefs}}
{{- $Name := .Name}}
{{- with .AllowedValues}}
// Allowed values for state variable {{$Name}}.
const (
{{- range .}}
{{$Name}}_{{.}} = "{{.}}"
{{- end}}
)
{{- end}}
{{- end}}
const ServiceType = {{quote .Manifest.ServiceType}}
{{range .SCPD.SortedActions}}
{{- template "action" args "Action" . "Imps" $Imps}}
{{- template "action" args "Action" . "Imps" $Imps "Types" $Types}}
{{end}}
{{- end}}
{{define "action"}}
{{- $Imps := .Imps}}
{{- $soapActionType := index $Imps.TypeByName "SOAPActionInterface"}}
{{- $Types := .Types}}
{{- $soapActionType := index $Types.TypeByName "SOAPActionInterface"}}
// {{.Action.Name}} provides request and response for the action.
//
// ServiceType implements {{$soapActionType.AbsRef}}, self-describing the SOAP action.
@@ -43,18 +57,23 @@ func (a *{{.Action.Name}}) RefResponse() any { return &a.Response }
// {{.Action.Name}}Request contains the "in" args for the {{quote .Action.Name}} action.
type {{.Action.Name}}Request struct
{{- template "args" args "Args" .Action.InArgs "Imps" $Imps}}
{{- template "args" args "Args" .Action.InArgs "Imps" $Imps "Types" $Types}}
// {{.Action.Name}}Response contains the "out" args for the {{quote .Action.Name}} action.
type {{.Action.Name}}Response struct
{{- template "args" args "Args" .Action.OutArgs "Imps" $Imps}}
{{- template "args" args "Args" .Action.OutArgs "Imps" $Imps "Types" $Types}}
{{- end}}
{{define "args"}}
{{- $Imps := .Imps -}}
{{- $Types := .Types -}}
{ {{- with .Args}}
{{- range .}}
{{- $fieldType := index $Imps.TypeByName .RelatedStateVariable.DataType}}
{{- $fieldType := index $Types.TypeByName .RelatedStateVariable.DataType}}
// {{.Name}} relates to state variable {{.RelatedStateVariable.Name}}
{{- with .RelatedStateVariable.AllowedValues}}
{{- ""}} ({{len .}} standard allowed values)
{{- end }}.
{{.Name}} {{$fieldType.Ref}}
{{- end}}
{{end -}} }
+27
View File
@@ -0,0 +1,27 @@
Copyright (c) 2009 The Go Authors. 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.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
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
OWNER 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.
+22
View File
@@ -0,0 +1,22 @@
Additional IP Rights Grant (Patents)
"This implementation" means the copyrightable works distributed by
Google as part of the Go project.
Google hereby grants to You a perpetual, worldwide, non-exclusive,
no-charge, royalty-free, irrevocable (except as stated in this section)
patent license to make, have made, use, offer to sell, sell, import,
transfer and otherwise run, modify and propagate the contents of this
implementation of Go, where such license applies only to those patent
claims, both currently owned or controlled by Google and acquired in
the future, licensable by Google that are necessarily infringed by this
implementation of Go. This grant does not include claims that would be
infringed only as a consequence of further modification of this
implementation. If you or your agent or exclusive licensee institute or
order or agree to the institution of patent litigation against any
entity (including a cross-claim or counterclaim in a lawsuit) alleging
that this implementation of Go or any code incorporated within this
implementation of Go constitutes direct or contributory patent
infringement, or inducement of patent infringement, then any patent
rights granted to you under this License for this implementation of Go
shall terminate as of the date such litigation is filed.
+132
View File
@@ -0,0 +1,132 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package errgroup provides synchronization, error propagation, and Context
// cancelation for groups of goroutines working on subtasks of a common task.
package errgroup
import (
"context"
"fmt"
"sync"
)
type token struct{}
// A Group is a collection of goroutines working on subtasks that are part of
// the same overall task.
//
// A zero Group is valid, has no limit on the number of active goroutines,
// and does not cancel on error.
type Group struct {
cancel func(error)
wg sync.WaitGroup
sem chan token
errOnce sync.Once
err error
}
func (g *Group) done() {
if g.sem != nil {
<-g.sem
}
g.wg.Done()
}
// WithContext returns a new Group and an associated Context derived from ctx.
//
// The derived Context is canceled the first time a function passed to Go
// returns a non-nil error or the first time Wait returns, whichever occurs
// first.
func WithContext(ctx context.Context) (*Group, context.Context) {
ctx, cancel := withCancelCause(ctx)
return &Group{cancel: cancel}, ctx
}
// Wait blocks until all function calls from the Go method have returned, then
// returns the first non-nil error (if any) from them.
func (g *Group) Wait() error {
g.wg.Wait()
if g.cancel != nil {
g.cancel(g.err)
}
return g.err
}
// Go calls the given function in a new goroutine.
// It blocks until the new goroutine can be added without the number of
// active goroutines in the group exceeding the configured limit.
//
// The first call to return a non-nil error cancels the group's context, if the
// group was created by calling WithContext. The error will be returned by Wait.
func (g *Group) Go(f func() error) {
if g.sem != nil {
g.sem <- token{}
}
g.wg.Add(1)
go func() {
defer g.done()
if err := f(); err != nil {
g.errOnce.Do(func() {
g.err = err
if g.cancel != nil {
g.cancel(g.err)
}
})
}
}()
}
// TryGo calls the given function in a new goroutine only if the number of
// active goroutines in the group is currently below the configured limit.
//
// The return value reports whether the goroutine was started.
func (g *Group) TryGo(f func() error) bool {
if g.sem != nil {
select {
case g.sem <- token{}:
// Note: this allows barging iff channels in general allow barging.
default:
return false
}
}
g.wg.Add(1)
go func() {
defer g.done()
if err := f(); err != nil {
g.errOnce.Do(func() {
g.err = err
if g.cancel != nil {
g.cancel(g.err)
}
})
}
}()
return true
}
// SetLimit limits the number of active goroutines in this group to at most n.
// A negative value indicates no limit.
//
// Any subsequent call to the Go method will block until it can add an active
// goroutine without exceeding the configured limit.
//
// The limit must not be modified while any goroutines in the group are active.
func (g *Group) SetLimit(n int) {
if n < 0 {
g.sem = nil
return
}
if len(g.sem) != 0 {
panic(fmt.Errorf("errgroup: modify limit while %v goroutines in the group are still active", len(g.sem)))
}
g.sem = make(chan token, n)
}
+13
View File
@@ -0,0 +1,13 @@
// Copyright 2023 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build go1.20
package errgroup
import "context"
func withCancelCause(parent context.Context) (context.Context, func(error)) {
return context.WithCancelCause(parent)
}
+14
View File
@@ -0,0 +1,14 @@
// Copyright 2023 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build !go1.20
package errgroup
import "context"
func withCancelCause(parent context.Context) (context.Context, func(error)) {
ctx, cancel := context.WithCancel(parent)
return ctx, func(error) { cancel() }
}
+3
View File
@@ -0,0 +1,3 @@
# golang.org/x/sync v0.5.0
## explicit; go 1.18
golang.org/x/sync/errgroup