From 86d59aecd85e8dc3b4894b8d6fec59763536e1d7 Mon Sep 17 00:00:00 2001 From: sberk42 Date: Sat, 22 Aug 2020 09:04:31 +0200 Subject: [PATCH] added support for calling actions with arguments --- fritzbox_upnp/service.go | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/fritzbox_upnp/service.go b/fritzbox_upnp/service.go index b0a8531..81606d6 100644 --- a/fritzbox_upnp/service.go +++ b/fritzbox_upnp/service.go @@ -18,6 +18,7 @@ package fritzbox_upnp import ( "encoding/xml" "errors" + "bytes" "fmt" "io" "net/http" @@ -96,6 +97,12 @@ type Action struct { ArgumentMap map[string]*Argument // Map of arguments indexed by .Name } +// An InĂ¼ut Argument to pass to an action +type ActionArgument struct { + Name string + Value string +} + // structs to unmarshal SOAP faults type SoapEnvelope struct { XMLName xml.Name `xml:"http://schemas.xmlsoap.org/soap/envelope/ Envelope"` @@ -255,11 +262,19 @@ func (d *Device) fillServices(r *Root) error { const SoapActionXML = `` + `` + - `` + + `%s` + `` -func (a *Action) createCallHttpRequest() (*http.Request, error) { - bodystr := fmt.Sprintf(SoapActionXML, a.Name, a.service.ServiceType) +const SoapActionParamXML = `<%s>%s` + +func (a *Action) createCallHttpRequest(actionArgs []ActionArgument) (*http.Request, error) { + argsString := "" + for _, aa := range actionArgs{ + var buf bytes.Buffer + xml.EscapeText(&buf, []byte(aa.Value)) + argsString += fmt.Sprintf(SoapActionParamXML, aa.Name, buf.String(), aa.Name) + } + bodystr := fmt.Sprintf(SoapActionXML, a.Name, a.service.ServiceType, argsString, a.Name, a.service.ServiceType) url := a.service.Device.root.BaseUrl + a.service.ControlUrl body := strings.NewReader(bodystr) @@ -278,9 +293,12 @@ func (a *Action) createCallHttpRequest() (*http.Request, error) { } // Call an action. -// Currently only actions without input arguments are supported. func (a *Action) Call() (Result, error) { - req, err := a.createCallHttpRequest() + return a.CallWithParams([]ActionArgument{}); +} +// Currently only actions without input arguments are supported. +func (a *Action) CallWithArguments(actionArgs []ActionArgument) (Result, error) { + req, err := a.createCallHttpRequest(actionArgs) if err != nil { return nil, err @@ -304,7 +322,7 @@ func (a *Action) Call() (Result, error) { return nil, err } - req, err = a.createCallHttpRequest() + req, err = a.createCallHttpRequest(actionArgs) if err != nil { return nil, err }