Separate lower-level API into separate packages.

This commit is contained in:
John Beisley 2013-10-06 13:23:11 +01:00
parent e8e520e578
commit 914072fdd8
7 changed files with 23 additions and 64 deletions

View File

@ -89,7 +89,7 @@ func main() {
} }
} }
srvClient := goupnp.NewSOAPClient(srv.ControlURL.URL) srvClient := srv.NewSOAPClient()
{ {
inAction := GetExternalIPAddressRequest{XMLName: xml.Name{Space: goupnp.ServiceTypeWANPPPConnection, Local: "GetExternalIPAddress"}} inAction := GetExternalIPAddressRequest{XMLName: xml.Name{Space: goupnp.ServiceTypeWANPPPConnection, Local: "GetExternalIPAddress"}}

View File

@ -7,6 +7,9 @@ import (
"errors" "errors"
"fmt" "fmt"
"net/url" "net/url"
"github.com/huin/goupnp/scpd"
"github.com/huin/goupnp/soap"
) )
const ( const (
@ -147,15 +150,19 @@ func (srv *Service) String() string {
// RequestSCDP requests the SCPD (soap actions and state variables description) // RequestSCDP requests the SCPD (soap actions and state variables description)
// for the service. // for the service.
func (srv *Service) RequestSCDP() (*SCPD, error) { func (srv *Service) RequestSCDP() (*scpd.SCPD, error) {
if !srv.SCPDURL.Ok { if !srv.SCPDURL.Ok {
return nil, errors.New("bad/missing SCPD URL, or no URLBase has been set") return nil, errors.New("bad/missing SCPD URL, or no URLBase has been set")
} }
scpd := new(SCPD) s := new(scpd.SCPD)
if err := requestXml(srv.SCPDURL.URL.String(), SCPDXMLNamespace, scpd); err != nil { if err := requestXml(srv.SCPDURL.URL.String(), scpd.SCPDXMLNamespace, s); err != nil {
return nil, err return nil, err
} }
return scpd, nil return s, nil
}
func (srv *Service) NewSOAPClient() *soap.SOAPClient {
return soap.NewSOAPClient(srv.ControlURL.URL)
} }
// URLField is a URL that is part of a device description. // URLField is a URL that is part of a device description.

View File

@ -6,6 +6,9 @@ import (
"fmt" "fmt"
"net/http" "net/http"
"net/url" "net/url"
"github.com/huin/goupnp/httpu"
"github.com/huin/goupnp/ssdp"
) )
// Non-exhaustive set of UPnP service types. // Non-exhaustive set of UPnP service types.
@ -46,12 +49,12 @@ type MaybeRootDevice struct {
// returned for errors while attempting to send the query. An error or // returned for errors while attempting to send the query. An error or
// RootDevice is returned for each discovered service. // RootDevice is returned for each discovered service.
func DiscoverDevices(searchTarget string) ([]MaybeRootDevice, error) { func DiscoverDevices(searchTarget string) ([]MaybeRootDevice, error) {
httpu, err := NewHTTPUClient() httpu, err := httpu.NewHTTPUClient()
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer httpu.Close() defer httpu.Close()
responses, err := SSDPRawSearch(httpu, string(searchTarget), 2, 3) responses, err := ssdp.SSDPRawSearch(httpu, string(searchTarget), 2, 3)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -1,4 +1,4 @@
package goupnp package httpu
import ( import (
"bufio" "bufio"

53
scpd.go
View File

@ -1,53 +0,0 @@
package goupnp
import (
"encoding/xml"
)
const (
SCPDXMLNamespace = "urn:schemas-upnp-org:service-1-0"
)
// SCPD is the service description as described by section 2.5 "Service
// description" in
// http://upnp.org/specs/arch/UPnP-arch-DeviceArchitecture-v1.1.pdf
type SCPD struct {
XMLName xml.Name `xml:"scpd"`
ConfigId string `xml:"configId,attr"`
SpecVersion SpecVersion `xml:"specVersion"`
Actions []Action `xml:"actionList>action"`
StateVariables []StateVariable `xml:"serviceStateTable>stateVariable"`
}
type Action struct {
Name string `xml:"name"`
Arguments []Argument `xml:"argumentList>argument"`
}
type Argument struct {
Name string `xml:"name"`
Direction string `xml:"direction"` // in|out
RelatedStateVariable string `xml:"relatedStateVariable"` // ?
Retval string `xml:"retval"` // ?
}
type StateVariable struct {
Name string `xml:"name"`
SendEvents string `xml:"sendEvents,attr"` // yes|no
Multicast string `xml:"multicast,attr"` // yes|no
DataType DataType `xml:"dataType"`
DefaultValue string `xml:"defaultValue"`
AllowedValueRange AllowedValueRange `xml:"allowedValueRange"`
AllowedValue []string `xml:"allowedValueList>allowedValue"`
}
type AllowedValueRange struct {
Minimum string `xml:"minimum"`
Maximum string `xml:"maximum"`
Step string `xml:"step"`
}
type DataType struct {
Name string `xml:",chardata"`
Type string `xml:"type,attr"`
}

View File

@ -1,6 +1,6 @@
// Definition for the SOAP structure required for UPnP's SOAP usage. // Definition for the SOAP structure required for UPnP's SOAP usage.
package goupnp package soap
import ( import (
"bytes" "bytes"

View File

@ -1,4 +1,4 @@
package goupnp package ssdp
import ( import (
"errors" "errors"
@ -7,6 +7,8 @@ import (
"net/url" "net/url"
"strconv" "strconv"
"time" "time"
"github.com/huin/goupnp/httpu"
) )
const ( const (
@ -22,7 +24,7 @@ const (
// implementation waits an additional 100ms for responses to arrive), 2 is a // 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 // reasonable value for this. numSends is the number of requests to send - 3 is
// a reasonable value for this. // a reasonable value for this.
func SSDPRawSearch(httpu *HTTPUClient, searchTarget string, maxWaitSeconds int, numSends int) ([]*http.Response, error) { func SSDPRawSearch(httpu *httpu.HTTPUClient, searchTarget string, maxWaitSeconds int, numSends int) ([]*http.Response, error) {
if maxWaitSeconds < 1 { if maxWaitSeconds < 1 {
return nil, errors.New("ssdp: maxWaitSeconds must be >= 1") return nil, errors.New("ssdp: maxWaitSeconds must be >= 1")
} }