go-upnp-master/0000755000175000017500000000000013165312311012354 5ustar freefreego-upnp-master/LICENSE0000644000175000017500000000206313165312311013362 0ustar freefreeThe MIT License (MIT) Copyright (c) 2015 Nebulous Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. go-upnp-master/README.md0000644000175000017500000000564413165312311013644 0ustar freefree## upnp ## package upnp provides a simple and opinionated interface to UPnP-enabled routers, allowing users to forward ports and discover their external IP address. Specific quirks: - When attempting to discover UPnP-enabled routers on the network, only the first such router is returned. If you have multiple routers, this may cause some trouble. - Forwarded ports are always symmetric, e.g. the router's port 9980 will be mapped to the client's port 9980. This will be unacceptable for some purposes, but symmetric mappings are the desired behavior 99% of the time, and they simplify the API. - TCP and UDP protocols are forwarded together. - Ports are forwarded permanently. Some other implementations lease a port mapping for a set duration, and then renew it periodically. This is nice, because it means mappings won't stick around after they've served their purpose. Unfortunately, some routers only support permanent mappings, so this package has chosen to support the lowest common denominator. To un-forward a port, you must use the Clear function (or do it manually). Once you've discovered your router, you can retrieve its address by calling its Location method. This address can be supplied to Load to connect to the router directly, which is much faster than calling Discover. See the [godoc](http://godoc.org/github.com/NebulousLabs/upnp) for full documentation. ## example ## ```go import ( "log" "github.com/NebulousLabs/go-upnp" ) func main() { // connect to router d, err := upnp.Discover() if err != nil { log.Fatal(err) } // discover external IP ip, err := d.ExternalIP() if err != nil { log.Fatal(err) } fmt.Println("Your external IP is:", ip) // forward a port err = d.Forward(9001, "upnp test") if err != nil { log.Fatal(err) } // un-forward a port err = d.Clear(9001) if err != nil { log.Fatal(err) } // record router's location loc := d.Location() // connect to router directly d, err = upnp.Load(loc) if err != nil { log.Fatal(err) } } ``` ## motivation ## Port forwarding and external IP discovery are two of the most common tasks required when creating a P2P network. This requires talking to your local router, usually via the UPnP protocol. There are a number of existing packages that provide this functionality, but I found all of them lacking in some respect. The most robust implementation I found was huin's [goupnp](http://github.com/huin/goupnp), but its interface was clunky and required more boilerplate than I felt was necessary. So this package is really just a wrapper around the goupnp library, specifically tailored to the use cases listed above. This makes the name a bit of a misnomer, I know; UPnP is much broader than port forwarding. But `upnp` is much more search-friendly than `igdman` (Internet Gateway Device Manager). If you think of something better, I'd love to hear it. go-upnp-master/goupnp/0000755000175000017500000000000013165312311013664 5ustar freefreego-upnp-master/goupnp/LICENSE0000644000175000017500000000244413165312311014675 0ustar freefreeCopyright (c) 2013, John Beisley All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. go-upnp-master/goupnp/dcps/0000755000175000017500000000000013165312311014615 5ustar freefreego-upnp-master/goupnp/dcps/internetgateway1/0000755000175000017500000000000013165312311020110 5ustar freefreego-upnp-master/goupnp/dcps/internetgateway1/internetgateway1.go0000644000175000017500000032550213165312311023741 0ustar freefree// Client for UPnP Device Control Protocol Internet Gateway Device v1. // // This DCP is documented in detail at: http://upnp.org/specs/gw/UPnP-gw-InternetGatewayDevice-v1-Device.pdf // // Typically, use one of the New* functions to create clients for services. package internetgateway1 // Generated file - do not edit by hand. See README.md import ( "context" "net/url" "time" "github.com/NebulousLabs/go-upnp/goupnp" "github.com/NebulousLabs/go-upnp/goupnp/soap" ) // Hack to avoid Go complaining if time isn't used. var _ time.Time // Device URNs: const ( URN_LANDevice_1 = "urn:schemas-upnp-org:device:LANDevice:1" URN_WANConnectionDevice_1 = "urn:schemas-upnp-org:device:WANConnectionDevice:1" URN_WANDevice_1 = "urn:schemas-upnp-org:device:WANDevice:1" ) // Service URNs: const ( URN_LANHostConfigManagement_1 = "urn:schemas-upnp-org:service:LANHostConfigManagement:1" URN_Layer3Forwarding_1 = "urn:schemas-upnp-org:service:Layer3Forwarding:1" URN_WANCableLinkConfig_1 = "urn:schemas-upnp-org:service:WANCableLinkConfig:1" URN_WANCommonInterfaceConfig_1 = "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1" URN_WANDSLLinkConfig_1 = "urn:schemas-upnp-org:service:WANDSLLinkConfig:1" URN_WANEthernetLinkConfig_1 = "urn:schemas-upnp-org:service:WANEthernetLinkConfig:1" URN_WANIPConnection_1 = "urn:schemas-upnp-org:service:WANIPConnection:1" URN_WANPOTSLinkConfig_1 = "urn:schemas-upnp-org:service:WANPOTSLinkConfig:1" URN_WANPPPConnection_1 = "urn:schemas-upnp-org:service:WANPPPConnection:1" ) // LANHostConfigManagement1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:LANHostConfigManagement:1". See // goupnp.ServiceClient, which contains RootDevice and Service attributes which // are provided for informational value. type LANHostConfigManagement1 struct { goupnp.ServiceClient } // NewLANHostConfigManagement1Clients 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) { var genericClients []goupnp.ServiceClient if genericClients, errors, err = goupnp.NewServiceClients(URN_LANHostConfigManagement_1); err != nil { return } clients = newLANHostConfigManagement1ClientsFromGenericClients(genericClients) return } // NewLANHostConfigManagement1ClientsByURL 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) if err != nil { return nil, err } return newLANHostConfigManagement1ClientsFromGenericClients(genericClients), nil } // 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 // device. The location parameter is simply assigned to the Location attribute // of the wrapped ServiceClient(s). // // This is a typical entry calling point into this package when reusing an // previously discovered root device. func NewLANHostConfigManagement1ClientsFromRootDevice(rootDevice *goupnp.RootDevice, loc *url.URL) ([]*LANHostConfigManagement1, error) { genericClients, err := goupnp.NewServiceClientsFromRootDevice(rootDevice, loc, URN_LANHostConfigManagement_1) if err != nil { return nil, err } return newLANHostConfigManagement1ClientsFromGenericClients(genericClients), nil } func newLANHostConfigManagement1ClientsFromGenericClients(genericClients []goupnp.ServiceClient) []*LANHostConfigManagement1 { clients := make([]*LANHostConfigManagement1, len(genericClients)) for i := range genericClients { clients[i] = &LANHostConfigManagement1{genericClients[i]} } return clients } func (client *LANHostConfigManagement1) SetDHCPServerConfigurable(NewDHCPServerConfigurable bool) (err error) { // Request structure. request := &struct { NewDHCPServerConfigurable string }{} // BEGIN Marshal arguments into request. if request.NewDHCPServerConfigurable, err = soap.MarshalBoolean(NewDHCPServerConfigurable); err != nil { return } // END Marshal arguments into request. // Response structure. response := interface{}(nil) // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "SetDHCPServerConfigurable", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. // END Unmarshal arguments from response. return } func (client *LANHostConfigManagement1) GetDHCPServerConfigurable() (NewDHCPServerConfigurable bool, err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := &struct { NewDHCPServerConfigurable string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "GetDHCPServerConfigurable", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewDHCPServerConfigurable, err = soap.UnmarshalBoolean(response.NewDHCPServerConfigurable); err != nil { return } // END Unmarshal arguments from response. return } func (client *LANHostConfigManagement1) SetDHCPRelay(NewDHCPRelay bool) (err error) { // Request structure. request := &struct { NewDHCPRelay string }{} // BEGIN Marshal arguments into request. if request.NewDHCPRelay, err = soap.MarshalBoolean(NewDHCPRelay); err != nil { return } // END Marshal arguments into request. // Response structure. response := interface{}(nil) // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "SetDHCPRelay", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. // END Unmarshal arguments from response. return } func (client *LANHostConfigManagement1) GetDHCPRelay() (NewDHCPRelay bool, err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := &struct { NewDHCPRelay string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "GetDHCPRelay", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewDHCPRelay, err = soap.UnmarshalBoolean(response.NewDHCPRelay); err != nil { return } // END Unmarshal arguments from response. return } func (client *LANHostConfigManagement1) SetSubnetMask(NewSubnetMask string) (err error) { // Request structure. request := &struct { NewSubnetMask string }{} // BEGIN Marshal arguments into request. if request.NewSubnetMask, err = soap.MarshalString(NewSubnetMask); err != nil { return } // END Marshal arguments into request. // Response structure. response := interface{}(nil) // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "SetSubnetMask", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. // END Unmarshal arguments from response. return } func (client *LANHostConfigManagement1) GetSubnetMask() (NewSubnetMask string, err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := &struct { NewSubnetMask string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "GetSubnetMask", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewSubnetMask, err = soap.UnmarshalString(response.NewSubnetMask); err != nil { return } // END Unmarshal arguments from response. return } func (client *LANHostConfigManagement1) SetIPRouter(NewIPRouters string) (err error) { // Request structure. request := &struct { NewIPRouters string }{} // BEGIN Marshal arguments into request. if request.NewIPRouters, err = soap.MarshalString(NewIPRouters); err != nil { return } // END Marshal arguments into request. // Response structure. response := interface{}(nil) // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "SetIPRouter", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. // END Unmarshal arguments from response. return } func (client *LANHostConfigManagement1) DeleteIPRouter(NewIPRouters string) (err error) { // Request structure. request := &struct { NewIPRouters string }{} // BEGIN Marshal arguments into request. if request.NewIPRouters, err = soap.MarshalString(NewIPRouters); err != nil { return } // END Marshal arguments into request. // Response structure. response := interface{}(nil) // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "DeleteIPRouter", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. // END Unmarshal arguments from response. return } func (client *LANHostConfigManagement1) GetIPRoutersList() (NewIPRouters string, err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := &struct { NewIPRouters string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "GetIPRoutersList", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewIPRouters, err = soap.UnmarshalString(response.NewIPRouters); err != nil { return } // END Unmarshal arguments from response. return } func (client *LANHostConfigManagement1) SetDomainName(NewDomainName string) (err error) { // Request structure. request := &struct { NewDomainName string }{} // BEGIN Marshal arguments into request. if request.NewDomainName, err = soap.MarshalString(NewDomainName); err != nil { return } // END Marshal arguments into request. // Response structure. response := interface{}(nil) // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "SetDomainName", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. // END Unmarshal arguments from response. return } func (client *LANHostConfigManagement1) GetDomainName() (NewDomainName string, err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := &struct { NewDomainName string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "GetDomainName", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewDomainName, err = soap.UnmarshalString(response.NewDomainName); err != nil { return } // END Unmarshal arguments from response. return } func (client *LANHostConfigManagement1) SetAddressRange(NewMinAddress string, NewMaxAddress string) (err error) { // Request structure. request := &struct { NewMinAddress string NewMaxAddress string }{} // BEGIN Marshal arguments into request. if request.NewMinAddress, err = soap.MarshalString(NewMinAddress); err != nil { return } if request.NewMaxAddress, err = soap.MarshalString(NewMaxAddress); err != nil { return } // END Marshal arguments into request. // Response structure. response := interface{}(nil) // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "SetAddressRange", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. // END Unmarshal arguments from response. return } func (client *LANHostConfigManagement1) GetAddressRange() (NewMinAddress string, NewMaxAddress string, err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := &struct { NewMinAddress string NewMaxAddress string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "GetAddressRange", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewMinAddress, err = soap.UnmarshalString(response.NewMinAddress); err != nil { return } if NewMaxAddress, err = soap.UnmarshalString(response.NewMaxAddress); err != nil { return } // END Unmarshal arguments from response. return } func (client *LANHostConfigManagement1) SetReservedAddress(NewReservedAddresses string) (err error) { // Request structure. request := &struct { NewReservedAddresses string }{} // BEGIN Marshal arguments into request. if request.NewReservedAddresses, err = soap.MarshalString(NewReservedAddresses); err != nil { return } // END Marshal arguments into request. // Response structure. response := interface{}(nil) // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "SetReservedAddress", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. // END Unmarshal arguments from response. return } func (client *LANHostConfigManagement1) DeleteReservedAddress(NewReservedAddresses string) (err error) { // Request structure. request := &struct { NewReservedAddresses string }{} // BEGIN Marshal arguments into request. if request.NewReservedAddresses, err = soap.MarshalString(NewReservedAddresses); err != nil { return } // END Marshal arguments into request. // Response structure. response := interface{}(nil) // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "DeleteReservedAddress", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. // END Unmarshal arguments from response. return } func (client *LANHostConfigManagement1) GetReservedAddresses() (NewReservedAddresses string, err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := &struct { NewReservedAddresses string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "GetReservedAddresses", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewReservedAddresses, err = soap.UnmarshalString(response.NewReservedAddresses); err != nil { return } // END Unmarshal arguments from response. return } func (client *LANHostConfigManagement1) SetDNSServer(NewDNSServers string) (err error) { // Request structure. request := &struct { NewDNSServers string }{} // BEGIN Marshal arguments into request. if request.NewDNSServers, err = soap.MarshalString(NewDNSServers); err != nil { return } // END Marshal arguments into request. // Response structure. response := interface{}(nil) // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "SetDNSServer", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. // END Unmarshal arguments from response. return } func (client *LANHostConfigManagement1) DeleteDNSServer(NewDNSServers string) (err error) { // Request structure. request := &struct { NewDNSServers string }{} // BEGIN Marshal arguments into request. if request.NewDNSServers, err = soap.MarshalString(NewDNSServers); err != nil { return } // END Marshal arguments into request. // Response structure. response := interface{}(nil) // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "DeleteDNSServer", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. // END Unmarshal arguments from response. return } func (client *LANHostConfigManagement1) GetDNSServers() (NewDNSServers string, err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := &struct { NewDNSServers string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "GetDNSServers", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewDNSServers, err = soap.UnmarshalString(response.NewDNSServers); err != nil { return } // END Unmarshal arguments from response. return } // Layer3Forwarding1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:Layer3Forwarding:1". See // goupnp.ServiceClient, which contains RootDevice and Service attributes which // are provided for informational value. type Layer3Forwarding1 struct { goupnp.ServiceClient } // NewLayer3Forwarding1Clients 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) { var genericClients []goupnp.ServiceClient if genericClients, errors, err = goupnp.NewServiceClients(URN_Layer3Forwarding_1); err != nil { return } clients = newLayer3Forwarding1ClientsFromGenericClients(genericClients) return } // NewLayer3Forwarding1ClientsByURL 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) if err != nil { return nil, err } return newLayer3Forwarding1ClientsFromGenericClients(genericClients), nil } // 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 // device. The location parameter is simply assigned to the Location attribute // of the wrapped ServiceClient(s). // // This is a typical entry calling point into this package when reusing an // previously discovered root device. func NewLayer3Forwarding1ClientsFromRootDevice(rootDevice *goupnp.RootDevice, loc *url.URL) ([]*Layer3Forwarding1, error) { genericClients, err := goupnp.NewServiceClientsFromRootDevice(rootDevice, loc, URN_Layer3Forwarding_1) if err != nil { return nil, err } return newLayer3Forwarding1ClientsFromGenericClients(genericClients), nil } func newLayer3Forwarding1ClientsFromGenericClients(genericClients []goupnp.ServiceClient) []*Layer3Forwarding1 { clients := make([]*Layer3Forwarding1, len(genericClients)) for i := range genericClients { clients[i] = &Layer3Forwarding1{genericClients[i]} } return clients } func (client *Layer3Forwarding1) SetDefaultConnectionService(NewDefaultConnectionService string) (err error) { // Request structure. request := &struct { NewDefaultConnectionService string }{} // BEGIN Marshal arguments into request. if request.NewDefaultConnectionService, err = soap.MarshalString(NewDefaultConnectionService); err != nil { return } // END Marshal arguments into request. // Response structure. response := interface{}(nil) // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_Layer3Forwarding_1, "SetDefaultConnectionService", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. // END Unmarshal arguments from response. return } func (client *Layer3Forwarding1) GetDefaultConnectionService() (NewDefaultConnectionService string, err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := &struct { NewDefaultConnectionService string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_Layer3Forwarding_1, "GetDefaultConnectionService", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewDefaultConnectionService, err = soap.UnmarshalString(response.NewDefaultConnectionService); err != nil { return } // END Unmarshal arguments from response. return } // WANCableLinkConfig1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANCableLinkConfig:1". See // goupnp.ServiceClient, which contains RootDevice and Service attributes which // are provided for informational value. type WANCableLinkConfig1 struct { goupnp.ServiceClient } // NewWANCableLinkConfig1Clients 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) { var genericClients []goupnp.ServiceClient if genericClients, errors, err = goupnp.NewServiceClients(URN_WANCableLinkConfig_1); err != nil { return } clients = newWANCableLinkConfig1ClientsFromGenericClients(genericClients) return } // NewWANCableLinkConfig1ClientsByURL 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) if err != nil { return nil, err } return newWANCableLinkConfig1ClientsFromGenericClients(genericClients), nil } // 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 // device. The location parameter is simply assigned to the Location attribute // of the wrapped ServiceClient(s). // // This is a typical entry calling point into this package when reusing an // previously discovered root device. func NewWANCableLinkConfig1ClientsFromRootDevice(rootDevice *goupnp.RootDevice, loc *url.URL) ([]*WANCableLinkConfig1, error) { genericClients, err := goupnp.NewServiceClientsFromRootDevice(rootDevice, loc, URN_WANCableLinkConfig_1) if err != nil { return nil, err } return newWANCableLinkConfig1ClientsFromGenericClients(genericClients), nil } func newWANCableLinkConfig1ClientsFromGenericClients(genericClients []goupnp.ServiceClient) []*WANCableLinkConfig1 { clients := make([]*WANCableLinkConfig1, len(genericClients)) for i := range genericClients { clients[i] = &WANCableLinkConfig1{genericClients[i]} } return clients } // // Return values: // // * NewCableLinkConfigState: allowed values: notReady, dsSyncComplete, usParamAcquired, rangingComplete, ipComplete, todEstablished, paramTransferComplete, registrationComplete, operational, accessDenied // // * NewLinkType: allowed values: Ethernet func (client *WANCableLinkConfig1) GetCableLinkConfigInfo() (NewCableLinkConfigState string, NewLinkType string, err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := &struct { NewCableLinkConfigState string NewLinkType string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetCableLinkConfigInfo", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewCableLinkConfigState, err = soap.UnmarshalString(response.NewCableLinkConfigState); err != nil { return } if NewLinkType, err = soap.UnmarshalString(response.NewLinkType); err != nil { return } // END Unmarshal arguments from response. return } func (client *WANCableLinkConfig1) GetDownstreamFrequency() (NewDownstreamFrequency uint32, err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := &struct { NewDownstreamFrequency string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetDownstreamFrequency", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewDownstreamFrequency, err = soap.UnmarshalUi4(response.NewDownstreamFrequency); err != nil { return } // END Unmarshal arguments from response. return } // // Return values: // // * NewDownstreamModulation: allowed values: 64QAM, 256QAM func (client *WANCableLinkConfig1) GetDownstreamModulation() (NewDownstreamModulation string, err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := &struct { NewDownstreamModulation string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetDownstreamModulation", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewDownstreamModulation, err = soap.UnmarshalString(response.NewDownstreamModulation); err != nil { return } // END Unmarshal arguments from response. return } func (client *WANCableLinkConfig1) GetUpstreamFrequency() (NewUpstreamFrequency uint32, err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := &struct { NewUpstreamFrequency string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetUpstreamFrequency", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewUpstreamFrequency, err = soap.UnmarshalUi4(response.NewUpstreamFrequency); err != nil { return } // END Unmarshal arguments from response. return } // // Return values: // // * NewUpstreamModulation: allowed values: QPSK, 16QAM func (client *WANCableLinkConfig1) GetUpstreamModulation() (NewUpstreamModulation string, err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := &struct { NewUpstreamModulation string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetUpstreamModulation", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewUpstreamModulation, err = soap.UnmarshalString(response.NewUpstreamModulation); err != nil { return } // END Unmarshal arguments from response. return } func (client *WANCableLinkConfig1) GetUpstreamChannelID() (NewUpstreamChannelID uint32, err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := &struct { NewUpstreamChannelID string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetUpstreamChannelID", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewUpstreamChannelID, err = soap.UnmarshalUi4(response.NewUpstreamChannelID); err != nil { return } // END Unmarshal arguments from response. return } func (client *WANCableLinkConfig1) GetUpstreamPowerLevel() (NewUpstreamPowerLevel uint32, err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := &struct { NewUpstreamPowerLevel string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetUpstreamPowerLevel", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewUpstreamPowerLevel, err = soap.UnmarshalUi4(response.NewUpstreamPowerLevel); err != nil { return } // END Unmarshal arguments from response. return } func (client *WANCableLinkConfig1) GetBPIEncryptionEnabled() (NewBPIEncryptionEnabled bool, err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := &struct { NewBPIEncryptionEnabled string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetBPIEncryptionEnabled", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewBPIEncryptionEnabled, err = soap.UnmarshalBoolean(response.NewBPIEncryptionEnabled); err != nil { return } // END Unmarshal arguments from response. return } func (client *WANCableLinkConfig1) GetConfigFile() (NewConfigFile string, err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := &struct { NewConfigFile string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetConfigFile", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewConfigFile, err = soap.UnmarshalString(response.NewConfigFile); err != nil { return } // END Unmarshal arguments from response. return } func (client *WANCableLinkConfig1) GetTFTPServer() (NewTFTPServer string, err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := &struct { NewTFTPServer string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetTFTPServer", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewTFTPServer, err = soap.UnmarshalString(response.NewTFTPServer); err != nil { return } // END Unmarshal arguments from response. return } // WANCommonInterfaceConfig1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1". See // goupnp.ServiceClient, which contains RootDevice and Service attributes which // are provided for informational value. type WANCommonInterfaceConfig1 struct { goupnp.ServiceClient } // NewWANCommonInterfaceConfig1Clients 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) { var genericClients []goupnp.ServiceClient if genericClients, errors, err = goupnp.NewServiceClients(URN_WANCommonInterfaceConfig_1); err != nil { return } clients = newWANCommonInterfaceConfig1ClientsFromGenericClients(genericClients) return } // NewWANCommonInterfaceConfig1ClientsByURL 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) if err != nil { return nil, err } return newWANCommonInterfaceConfig1ClientsFromGenericClients(genericClients), nil } // 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 // device. The location parameter is simply assigned to the Location attribute // of the wrapped ServiceClient(s). // // This is a typical entry calling point into this package when reusing an // previously discovered root device. func NewWANCommonInterfaceConfig1ClientsFromRootDevice(rootDevice *goupnp.RootDevice, loc *url.URL) ([]*WANCommonInterfaceConfig1, error) { genericClients, err := goupnp.NewServiceClientsFromRootDevice(rootDevice, loc, URN_WANCommonInterfaceConfig_1) if err != nil { return nil, err } return newWANCommonInterfaceConfig1ClientsFromGenericClients(genericClients), nil } func newWANCommonInterfaceConfig1ClientsFromGenericClients(genericClients []goupnp.ServiceClient) []*WANCommonInterfaceConfig1 { clients := make([]*WANCommonInterfaceConfig1, len(genericClients)) for i := range genericClients { clients[i] = &WANCommonInterfaceConfig1{genericClients[i]} } return clients } func (client *WANCommonInterfaceConfig1) SetEnabledForInternet(NewEnabledForInternet bool) (err error) { // Request structure. request := &struct { NewEnabledForInternet string }{} // BEGIN Marshal arguments into request. if request.NewEnabledForInternet, err = soap.MarshalBoolean(NewEnabledForInternet); err != nil { return } // END Marshal arguments into request. // Response structure. response := interface{}(nil) // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "SetEnabledForInternet", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. // END Unmarshal arguments from response. return } func (client *WANCommonInterfaceConfig1) GetEnabledForInternet() (NewEnabledForInternet bool, err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := &struct { NewEnabledForInternet string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "GetEnabledForInternet", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewEnabledForInternet, err = soap.UnmarshalBoolean(response.NewEnabledForInternet); err != nil { return } // END Unmarshal arguments from response. return } // // Return values: // // * NewWANAccessType: allowed values: DSL, POTS, Cable, Ethernet // // * NewPhysicalLinkStatus: allowed values: Up, Down func (client *WANCommonInterfaceConfig1) GetCommonLinkProperties() (NewWANAccessType string, NewLayer1UpstreamMaxBitRate uint32, NewLayer1DownstreamMaxBitRate uint32, NewPhysicalLinkStatus string, err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := &struct { NewWANAccessType string NewLayer1UpstreamMaxBitRate string NewLayer1DownstreamMaxBitRate string NewPhysicalLinkStatus string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "GetCommonLinkProperties", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewWANAccessType, err = soap.UnmarshalString(response.NewWANAccessType); err != nil { return } if NewLayer1UpstreamMaxBitRate, err = soap.UnmarshalUi4(response.NewLayer1UpstreamMaxBitRate); err != nil { return } if NewLayer1DownstreamMaxBitRate, err = soap.UnmarshalUi4(response.NewLayer1DownstreamMaxBitRate); err != nil { return } if NewPhysicalLinkStatus, err = soap.UnmarshalString(response.NewPhysicalLinkStatus); err != nil { return } // END Unmarshal arguments from response. return } func (client *WANCommonInterfaceConfig1) GetWANAccessProvider() (NewWANAccessProvider string, err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := &struct { NewWANAccessProvider string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "GetWANAccessProvider", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewWANAccessProvider, err = soap.UnmarshalString(response.NewWANAccessProvider); err != nil { return } // END Unmarshal arguments from response. return } // // Return values: // // * NewMaximumActiveConnections: allowed value range: minimum=1, step=1 func (client *WANCommonInterfaceConfig1) GetMaximumActiveConnections() (NewMaximumActiveConnections uint16, err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := &struct { NewMaximumActiveConnections string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "GetMaximumActiveConnections", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewMaximumActiveConnections, err = soap.UnmarshalUi2(response.NewMaximumActiveConnections); err != nil { return } // END Unmarshal arguments from response. return } func (client *WANCommonInterfaceConfig1) GetTotalBytesSent() (NewTotalBytesSent uint32, err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := &struct { NewTotalBytesSent string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "GetTotalBytesSent", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewTotalBytesSent, err = soap.UnmarshalUi4(response.NewTotalBytesSent); err != nil { return } // END Unmarshal arguments from response. return } func (client *WANCommonInterfaceConfig1) GetTotalBytesReceived() (NewTotalBytesReceived uint32, err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := &struct { NewTotalBytesReceived string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "GetTotalBytesReceived", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewTotalBytesReceived, err = soap.UnmarshalUi4(response.NewTotalBytesReceived); err != nil { return } // END Unmarshal arguments from response. return } func (client *WANCommonInterfaceConfig1) GetTotalPacketsSent() (NewTotalPacketsSent uint32, err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := &struct { NewTotalPacketsSent string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "GetTotalPacketsSent", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewTotalPacketsSent, err = soap.UnmarshalUi4(response.NewTotalPacketsSent); err != nil { return } // END Unmarshal arguments from response. return } func (client *WANCommonInterfaceConfig1) GetTotalPacketsReceived() (NewTotalPacketsReceived uint32, err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := &struct { NewTotalPacketsReceived string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "GetTotalPacketsReceived", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewTotalPacketsReceived, err = soap.UnmarshalUi4(response.NewTotalPacketsReceived); err != nil { return } // END Unmarshal arguments from response. return } func (client *WANCommonInterfaceConfig1) GetActiveConnection(NewActiveConnectionIndex uint16) (NewActiveConnDeviceContainer string, NewActiveConnectionServiceID string, err error) { // Request structure. request := &struct { NewActiveConnectionIndex string }{} // BEGIN Marshal arguments into request. if request.NewActiveConnectionIndex, err = soap.MarshalUi2(NewActiveConnectionIndex); err != nil { return } // END Marshal arguments into request. // Response structure. response := &struct { NewActiveConnDeviceContainer string NewActiveConnectionServiceID string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "GetActiveConnection", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewActiveConnDeviceContainer, err = soap.UnmarshalString(response.NewActiveConnDeviceContainer); err != nil { return } if NewActiveConnectionServiceID, err = soap.UnmarshalString(response.NewActiveConnectionServiceID); err != nil { return } // END Unmarshal arguments from response. return } // WANDSLLinkConfig1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANDSLLinkConfig:1". See // goupnp.ServiceClient, which contains RootDevice and Service attributes which // are provided for informational value. type WANDSLLinkConfig1 struct { goupnp.ServiceClient } // NewWANDSLLinkConfig1Clients 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) { var genericClients []goupnp.ServiceClient if genericClients, errors, err = goupnp.NewServiceClients(URN_WANDSLLinkConfig_1); err != nil { return } clients = newWANDSLLinkConfig1ClientsFromGenericClients(genericClients) return } // NewWANDSLLinkConfig1ClientsByURL 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) if err != nil { return nil, err } return newWANDSLLinkConfig1ClientsFromGenericClients(genericClients), nil } // 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 // device. The location parameter is simply assigned to the Location attribute // of the wrapped ServiceClient(s). // // This is a typical entry calling point into this package when reusing an // previously discovered root device. func NewWANDSLLinkConfig1ClientsFromRootDevice(rootDevice *goupnp.RootDevice, loc *url.URL) ([]*WANDSLLinkConfig1, error) { genericClients, err := goupnp.NewServiceClientsFromRootDevice(rootDevice, loc, URN_WANDSLLinkConfig_1) if err != nil { return nil, err } return newWANDSLLinkConfig1ClientsFromGenericClients(genericClients), nil } func newWANDSLLinkConfig1ClientsFromGenericClients(genericClients []goupnp.ServiceClient) []*WANDSLLinkConfig1 { clients := make([]*WANDSLLinkConfig1, len(genericClients)) for i := range genericClients { clients[i] = &WANDSLLinkConfig1{genericClients[i]} } return clients } func (client *WANDSLLinkConfig1) SetDSLLinkType(NewLinkType string) (err error) { // Request structure. request := &struct { NewLinkType string }{} // BEGIN Marshal arguments into request. if request.NewLinkType, err = soap.MarshalString(NewLinkType); err != nil { return } // END Marshal arguments into request. // Response structure. response := interface{}(nil) // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "SetDSLLinkType", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. // END Unmarshal arguments from response. return } // // Return values: // // * NewLinkStatus: allowed values: Up, Down func (client *WANDSLLinkConfig1) GetDSLLinkInfo() (NewLinkType string, NewLinkStatus string, err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := &struct { NewLinkType string NewLinkStatus string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "GetDSLLinkInfo", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewLinkType, err = soap.UnmarshalString(response.NewLinkType); err != nil { return } if NewLinkStatus, err = soap.UnmarshalString(response.NewLinkStatus); err != nil { return } // END Unmarshal arguments from response. return } func (client *WANDSLLinkConfig1) GetAutoConfig() (NewAutoConfig bool, err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := &struct { NewAutoConfig string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "GetAutoConfig", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewAutoConfig, err = soap.UnmarshalBoolean(response.NewAutoConfig); err != nil { return } // END Unmarshal arguments from response. return } func (client *WANDSLLinkConfig1) GetModulationType() (NewModulationType string, err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := &struct { NewModulationType string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "GetModulationType", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewModulationType, err = soap.UnmarshalString(response.NewModulationType); err != nil { return } // END Unmarshal arguments from response. return } func (client *WANDSLLinkConfig1) SetDestinationAddress(NewDestinationAddress string) (err error) { // Request structure. request := &struct { NewDestinationAddress string }{} // BEGIN Marshal arguments into request. if request.NewDestinationAddress, err = soap.MarshalString(NewDestinationAddress); err != nil { return } // END Marshal arguments into request. // Response structure. response := interface{}(nil) // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "SetDestinationAddress", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. // END Unmarshal arguments from response. return } func (client *WANDSLLinkConfig1) GetDestinationAddress() (NewDestinationAddress string, err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := &struct { NewDestinationAddress string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "GetDestinationAddress", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewDestinationAddress, err = soap.UnmarshalString(response.NewDestinationAddress); err != nil { return } // END Unmarshal arguments from response. return } func (client *WANDSLLinkConfig1) SetATMEncapsulation(NewATMEncapsulation string) (err error) { // Request structure. request := &struct { NewATMEncapsulation string }{} // BEGIN Marshal arguments into request. if request.NewATMEncapsulation, err = soap.MarshalString(NewATMEncapsulation); err != nil { return } // END Marshal arguments into request. // Response structure. response := interface{}(nil) // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "SetATMEncapsulation", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. // END Unmarshal arguments from response. return } func (client *WANDSLLinkConfig1) GetATMEncapsulation() (NewATMEncapsulation string, err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := &struct { NewATMEncapsulation string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "GetATMEncapsulation", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewATMEncapsulation, err = soap.UnmarshalString(response.NewATMEncapsulation); err != nil { return } // END Unmarshal arguments from response. return } func (client *WANDSLLinkConfig1) SetFCSPreserved(NewFCSPreserved bool) (err error) { // Request structure. request := &struct { NewFCSPreserved string }{} // BEGIN Marshal arguments into request. if request.NewFCSPreserved, err = soap.MarshalBoolean(NewFCSPreserved); err != nil { return } // END Marshal arguments into request. // Response structure. response := interface{}(nil) // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "SetFCSPreserved", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. // END Unmarshal arguments from response. return } func (client *WANDSLLinkConfig1) GetFCSPreserved() (NewFCSPreserved bool, err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := &struct { NewFCSPreserved string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "GetFCSPreserved", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewFCSPreserved, err = soap.UnmarshalBoolean(response.NewFCSPreserved); err != nil { return } // END Unmarshal arguments from response. return } // WANEthernetLinkConfig1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANEthernetLinkConfig:1". See // goupnp.ServiceClient, which contains RootDevice and Service attributes which // are provided for informational value. type WANEthernetLinkConfig1 struct { goupnp.ServiceClient } // NewWANEthernetLinkConfig1Clients 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) { var genericClients []goupnp.ServiceClient if genericClients, errors, err = goupnp.NewServiceClients(URN_WANEthernetLinkConfig_1); err != nil { return } clients = newWANEthernetLinkConfig1ClientsFromGenericClients(genericClients) return } // NewWANEthernetLinkConfig1ClientsByURL 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) if err != nil { return nil, err } return newWANEthernetLinkConfig1ClientsFromGenericClients(genericClients), nil } // 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 // device. The location parameter is simply assigned to the Location attribute // of the wrapped ServiceClient(s). // // This is a typical entry calling point into this package when reusing an // previously discovered root device. func NewWANEthernetLinkConfig1ClientsFromRootDevice(rootDevice *goupnp.RootDevice, loc *url.URL) ([]*WANEthernetLinkConfig1, error) { genericClients, err := goupnp.NewServiceClientsFromRootDevice(rootDevice, loc, URN_WANEthernetLinkConfig_1) if err != nil { return nil, err } return newWANEthernetLinkConfig1ClientsFromGenericClients(genericClients), nil } func newWANEthernetLinkConfig1ClientsFromGenericClients(genericClients []goupnp.ServiceClient) []*WANEthernetLinkConfig1 { clients := make([]*WANEthernetLinkConfig1, len(genericClients)) for i := range genericClients { clients[i] = &WANEthernetLinkConfig1{genericClients[i]} } return clients } // // Return values: // // * NewEthernetLinkStatus: allowed values: Up, Down func (client *WANEthernetLinkConfig1) GetEthernetLinkStatus() (NewEthernetLinkStatus string, err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := &struct { NewEthernetLinkStatus string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANEthernetLinkConfig_1, "GetEthernetLinkStatus", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewEthernetLinkStatus, err = soap.UnmarshalString(response.NewEthernetLinkStatus); err != nil { return } // END Unmarshal arguments from response. return } // WANIPConnection1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANIPConnection:1". See // goupnp.ServiceClient, which contains RootDevice and Service attributes which // are provided for informational value. type WANIPConnection1 struct { goupnp.ServiceClient } // NewWANIPConnection1Clients 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(ctx context.Context) (clients []*WANIPConnection1, errors []error, err error) { var genericClients []goupnp.ServiceClient 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 // 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) if err != nil { return nil, err } return newWANIPConnection1ClientsFromGenericClients(genericClients), nil } // 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 // device. The location parameter is simply assigned to the Location attribute // of the wrapped ServiceClient(s). // // This is a typical entry calling point into this package when reusing an // previously discovered root device. func NewWANIPConnection1ClientsFromRootDevice(rootDevice *goupnp.RootDevice, loc *url.URL) ([]*WANIPConnection1, error) { genericClients, err := goupnp.NewServiceClientsFromRootDevice(rootDevice, loc, URN_WANIPConnection_1) if err != nil { return nil, err } return newWANIPConnection1ClientsFromGenericClients(genericClients), nil } func newWANIPConnection1ClientsFromGenericClients(genericClients []goupnp.ServiceClient) []*WANIPConnection1 { clients := make([]*WANIPConnection1, len(genericClients)) for i := range genericClients { clients[i] = &WANIPConnection1{genericClients[i]} } return clients } func (client *WANIPConnection1) SetConnectionType(NewConnectionType string) (err error) { // Request structure. request := &struct { NewConnectionType string }{} // BEGIN Marshal arguments into request. if request.NewConnectionType, err = soap.MarshalString(NewConnectionType); err != nil { return } // END Marshal arguments into request. // Response structure. response := interface{}(nil) // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "SetConnectionType", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. // END Unmarshal arguments from response. return } // // Return values: // // * NewPossibleConnectionTypes: allowed values: Unconfigured, IP_Routed, IP_Bridged func (client *WANIPConnection1) GetConnectionTypeInfo() (NewConnectionType string, NewPossibleConnectionTypes string, err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := &struct { NewConnectionType string NewPossibleConnectionTypes string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "GetConnectionTypeInfo", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewConnectionType, err = soap.UnmarshalString(response.NewConnectionType); err != nil { return } if NewPossibleConnectionTypes, err = soap.UnmarshalString(response.NewPossibleConnectionTypes); err != nil { return } // END Unmarshal arguments from response. return } func (client *WANIPConnection1) RequestConnection() (err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := interface{}(nil) // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "RequestConnection", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. // END Unmarshal arguments from response. return } func (client *WANIPConnection1) RequestTermination() (err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := interface{}(nil) // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "RequestTermination", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. // END Unmarshal arguments from response. return } func (client *WANIPConnection1) ForceTermination() (err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := interface{}(nil) // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "ForceTermination", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. // END Unmarshal arguments from response. return } func (client *WANIPConnection1) SetAutoDisconnectTime(NewAutoDisconnectTime uint32) (err error) { // Request structure. request := &struct { NewAutoDisconnectTime string }{} // BEGIN Marshal arguments into request. if request.NewAutoDisconnectTime, err = soap.MarshalUi4(NewAutoDisconnectTime); err != nil { return } // END Marshal arguments into request. // Response structure. response := interface{}(nil) // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "SetAutoDisconnectTime", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. // END Unmarshal arguments from response. return } func (client *WANIPConnection1) SetIdleDisconnectTime(NewIdleDisconnectTime uint32) (err error) { // Request structure. request := &struct { NewIdleDisconnectTime string }{} // BEGIN Marshal arguments into request. if request.NewIdleDisconnectTime, err = soap.MarshalUi4(NewIdleDisconnectTime); err != nil { return } // END Marshal arguments into request. // Response structure. response := interface{}(nil) // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "SetIdleDisconnectTime", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. // END Unmarshal arguments from response. return } func (client *WANIPConnection1) SetWarnDisconnectDelay(NewWarnDisconnectDelay uint32) (err error) { // Request structure. request := &struct { NewWarnDisconnectDelay string }{} // BEGIN Marshal arguments into request. if request.NewWarnDisconnectDelay, err = soap.MarshalUi4(NewWarnDisconnectDelay); err != nil { return } // END Marshal arguments into request. // Response structure. response := interface{}(nil) // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "SetWarnDisconnectDelay", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. // END Unmarshal arguments from response. return } // // Return values: // // * NewConnectionStatus: allowed values: Unconfigured, Connected, Disconnected // // * NewLastConnectionError: allowed values: ERROR_NONE func (client *WANIPConnection1) GetStatusInfo() (NewConnectionStatus string, NewLastConnectionError string, NewUptime uint32, err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := &struct { NewConnectionStatus string NewLastConnectionError string NewUptime string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "GetStatusInfo", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewConnectionStatus, err = soap.UnmarshalString(response.NewConnectionStatus); err != nil { return } if NewLastConnectionError, err = soap.UnmarshalString(response.NewLastConnectionError); err != nil { return } if NewUptime, err = soap.UnmarshalUi4(response.NewUptime); err != nil { return } // END Unmarshal arguments from response. return } func (client *WANIPConnection1) GetAutoDisconnectTime() (NewAutoDisconnectTime uint32, err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := &struct { NewAutoDisconnectTime string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "GetAutoDisconnectTime", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewAutoDisconnectTime, err = soap.UnmarshalUi4(response.NewAutoDisconnectTime); err != nil { return } // END Unmarshal arguments from response. return } func (client *WANIPConnection1) GetIdleDisconnectTime() (NewIdleDisconnectTime uint32, err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := &struct { NewIdleDisconnectTime string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "GetIdleDisconnectTime", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewIdleDisconnectTime, err = soap.UnmarshalUi4(response.NewIdleDisconnectTime); err != nil { return } // END Unmarshal arguments from response. return } func (client *WANIPConnection1) GetWarnDisconnectDelay() (NewWarnDisconnectDelay uint32, err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := &struct { NewWarnDisconnectDelay string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "GetWarnDisconnectDelay", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewWarnDisconnectDelay, err = soap.UnmarshalUi4(response.NewWarnDisconnectDelay); err != nil { return } // END Unmarshal arguments from response. return } func (client *WANIPConnection1) GetNATRSIPStatus() (NewRSIPAvailable bool, NewNATEnabled bool, err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := &struct { NewRSIPAvailable string NewNATEnabled string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "GetNATRSIPStatus", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewRSIPAvailable, err = soap.UnmarshalBoolean(response.NewRSIPAvailable); err != nil { return } if NewNATEnabled, err = soap.UnmarshalBoolean(response.NewNATEnabled); err != nil { return } // END Unmarshal arguments from response. return } // // Return values: // // * NewProtocol: allowed values: TCP, UDP func (client *WANIPConnection1) GetGenericPortMappingEntry(NewPortMappingIndex uint16) (NewRemoteHost string, NewExternalPort uint16, NewProtocol string, NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32, err error) { // Request structure. request := &struct { NewPortMappingIndex string }{} // BEGIN Marshal arguments into request. if request.NewPortMappingIndex, err = soap.MarshalUi2(NewPortMappingIndex); err != nil { return } // END Marshal arguments into request. // Response structure. response := &struct { NewRemoteHost string NewExternalPort string NewProtocol string NewInternalPort string NewInternalClient string NewEnabled string NewPortMappingDescription string NewLeaseDuration string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "GetGenericPortMappingEntry", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewRemoteHost, err = soap.UnmarshalString(response.NewRemoteHost); err != nil { return } if NewExternalPort, err = soap.UnmarshalUi2(response.NewExternalPort); err != nil { return } if NewProtocol, err = soap.UnmarshalString(response.NewProtocol); err != nil { return } if NewInternalPort, err = soap.UnmarshalUi2(response.NewInternalPort); err != nil { return } if NewInternalClient, err = soap.UnmarshalString(response.NewInternalClient); err != nil { return } if NewEnabled, err = soap.UnmarshalBoolean(response.NewEnabled); err != nil { return } if NewPortMappingDescription, err = soap.UnmarshalString(response.NewPortMappingDescription); err != nil { return } if NewLeaseDuration, err = soap.UnmarshalUi4(response.NewLeaseDuration); err != nil { return } // END Unmarshal arguments from response. return } // // Arguments: // // * NewProtocol: allowed values: TCP, UDP func (client *WANIPConnection1) GetSpecificPortMappingEntry(NewRemoteHost string, NewExternalPort uint16, NewProtocol string) (NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32, err error) { // Request structure. request := &struct { NewRemoteHost string NewExternalPort string NewProtocol string }{} // BEGIN Marshal arguments into request. if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil { return } if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil { return } if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { return } // END Marshal arguments into request. // Response structure. response := &struct { NewInternalPort string NewInternalClient string NewEnabled string NewPortMappingDescription string NewLeaseDuration string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "GetSpecificPortMappingEntry", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewInternalPort, err = soap.UnmarshalUi2(response.NewInternalPort); err != nil { return } if NewInternalClient, err = soap.UnmarshalString(response.NewInternalClient); err != nil { return } if NewEnabled, err = soap.UnmarshalBoolean(response.NewEnabled); err != nil { return } if NewPortMappingDescription, err = soap.UnmarshalString(response.NewPortMappingDescription); err != nil { return } if NewLeaseDuration, err = soap.UnmarshalUi4(response.NewLeaseDuration); err != nil { return } // END Unmarshal arguments from response. return } // // Arguments: // // * NewProtocol: allowed values: TCP, UDP func (client *WANIPConnection1) AddPortMapping(NewRemoteHost string, NewExternalPort uint16, NewProtocol string, NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32) (err error) { // Request structure. request := &struct { NewRemoteHost string NewExternalPort string NewProtocol string NewInternalPort string NewInternalClient string NewEnabled string NewPortMappingDescription string NewLeaseDuration string }{} // BEGIN Marshal arguments into request. if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil { return } if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil { return } if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { return } if request.NewInternalPort, err = soap.MarshalUi2(NewInternalPort); err != nil { return } if request.NewInternalClient, err = soap.MarshalString(NewInternalClient); err != nil { return } if request.NewEnabled, err = soap.MarshalBoolean(NewEnabled); err != nil { return } if request.NewPortMappingDescription, err = soap.MarshalString(NewPortMappingDescription); err != nil { return } if request.NewLeaseDuration, err = soap.MarshalUi4(NewLeaseDuration); err != nil { return } // END Marshal arguments into request. // Response structure. response := interface{}(nil) // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "AddPortMapping", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. // END Unmarshal arguments from response. return } // // Arguments: // // * NewProtocol: allowed values: TCP, UDP func (client *WANIPConnection1) DeletePortMapping(NewRemoteHost string, NewExternalPort uint16, NewProtocol string) (err error) { // Request structure. request := &struct { NewRemoteHost string NewExternalPort string NewProtocol string }{} // BEGIN Marshal arguments into request. if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil { return } if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil { return } if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { return } // END Marshal arguments into request. // Response structure. response := interface{}(nil) // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "DeletePortMapping", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. // END Unmarshal arguments from response. return } func (client *WANIPConnection1) GetExternalIPAddress() (NewExternalIPAddress string, err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := &struct { NewExternalIPAddress string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "GetExternalIPAddress", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewExternalIPAddress, err = soap.UnmarshalString(response.NewExternalIPAddress); err != nil { return } // END Unmarshal arguments from response. return } // WANPOTSLinkConfig1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANPOTSLinkConfig:1". See // goupnp.ServiceClient, which contains RootDevice and Service attributes which // are provided for informational value. type WANPOTSLinkConfig1 struct { goupnp.ServiceClient } // NewWANPOTSLinkConfig1Clients 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) { var genericClients []goupnp.ServiceClient if genericClients, errors, err = goupnp.NewServiceClients(URN_WANPOTSLinkConfig_1); err != nil { return } clients = newWANPOTSLinkConfig1ClientsFromGenericClients(genericClients) return } // NewWANPOTSLinkConfig1ClientsByURL 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) if err != nil { return nil, err } return newWANPOTSLinkConfig1ClientsFromGenericClients(genericClients), nil } // 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 // device. The location parameter is simply assigned to the Location attribute // of the wrapped ServiceClient(s). // // This is a typical entry calling point into this package when reusing an // previously discovered root device. func NewWANPOTSLinkConfig1ClientsFromRootDevice(rootDevice *goupnp.RootDevice, loc *url.URL) ([]*WANPOTSLinkConfig1, error) { genericClients, err := goupnp.NewServiceClientsFromRootDevice(rootDevice, loc, URN_WANPOTSLinkConfig_1) if err != nil { return nil, err } return newWANPOTSLinkConfig1ClientsFromGenericClients(genericClients), nil } func newWANPOTSLinkConfig1ClientsFromGenericClients(genericClients []goupnp.ServiceClient) []*WANPOTSLinkConfig1 { clients := make([]*WANPOTSLinkConfig1, len(genericClients)) for i := range genericClients { clients[i] = &WANPOTSLinkConfig1{genericClients[i]} } return clients } // // Arguments: // // * NewLinkType: allowed values: PPP_Dialup func (client *WANPOTSLinkConfig1) SetISPInfo(NewISPPhoneNumber string, NewISPInfo string, NewLinkType string) (err error) { // Request structure. request := &struct { NewISPPhoneNumber string NewISPInfo string NewLinkType string }{} // BEGIN Marshal arguments into request. if request.NewISPPhoneNumber, err = soap.MarshalString(NewISPPhoneNumber); err != nil { return } if request.NewISPInfo, err = soap.MarshalString(NewISPInfo); err != nil { return } if request.NewLinkType, err = soap.MarshalString(NewLinkType); err != nil { return } // END Marshal arguments into request. // Response structure. response := interface{}(nil) // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANPOTSLinkConfig_1, "SetISPInfo", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. // END Unmarshal arguments from response. return } func (client *WANPOTSLinkConfig1) SetCallRetryInfo(NewNumberOfRetries uint32, NewDelayBetweenRetries uint32) (err error) { // Request structure. request := &struct { NewNumberOfRetries string NewDelayBetweenRetries string }{} // BEGIN Marshal arguments into request. if request.NewNumberOfRetries, err = soap.MarshalUi4(NewNumberOfRetries); err != nil { return } if request.NewDelayBetweenRetries, err = soap.MarshalUi4(NewDelayBetweenRetries); err != nil { return } // END Marshal arguments into request. // Response structure. response := interface{}(nil) // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANPOTSLinkConfig_1, "SetCallRetryInfo", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. // END Unmarshal arguments from response. return } // // Return values: // // * NewLinkType: allowed values: PPP_Dialup func (client *WANPOTSLinkConfig1) GetISPInfo() (NewISPPhoneNumber string, NewISPInfo string, NewLinkType string, err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := &struct { NewISPPhoneNumber string NewISPInfo string NewLinkType string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANPOTSLinkConfig_1, "GetISPInfo", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewISPPhoneNumber, err = soap.UnmarshalString(response.NewISPPhoneNumber); err != nil { return } if NewISPInfo, err = soap.UnmarshalString(response.NewISPInfo); err != nil { return } if NewLinkType, err = soap.UnmarshalString(response.NewLinkType); err != nil { return } // END Unmarshal arguments from response. return } func (client *WANPOTSLinkConfig1) GetCallRetryInfo() (NewNumberOfRetries uint32, NewDelayBetweenRetries uint32, err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := &struct { NewNumberOfRetries string NewDelayBetweenRetries string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANPOTSLinkConfig_1, "GetCallRetryInfo", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewNumberOfRetries, err = soap.UnmarshalUi4(response.NewNumberOfRetries); err != nil { return } if NewDelayBetweenRetries, err = soap.UnmarshalUi4(response.NewDelayBetweenRetries); err != nil { return } // END Unmarshal arguments from response. return } func (client *WANPOTSLinkConfig1) GetFclass() (NewFclass string, err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := &struct { NewFclass string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANPOTSLinkConfig_1, "GetFclass", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewFclass, err = soap.UnmarshalString(response.NewFclass); err != nil { return } // END Unmarshal arguments from response. return } func (client *WANPOTSLinkConfig1) GetDataModulationSupported() (NewDataModulationSupported string, err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := &struct { NewDataModulationSupported string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANPOTSLinkConfig_1, "GetDataModulationSupported", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewDataModulationSupported, err = soap.UnmarshalString(response.NewDataModulationSupported); err != nil { return } // END Unmarshal arguments from response. return } func (client *WANPOTSLinkConfig1) GetDataProtocol() (NewDataProtocol string, err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := &struct { NewDataProtocol string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANPOTSLinkConfig_1, "GetDataProtocol", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewDataProtocol, err = soap.UnmarshalString(response.NewDataProtocol); err != nil { return } // END Unmarshal arguments from response. return } func (client *WANPOTSLinkConfig1) GetDataCompression() (NewDataCompression string, err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := &struct { NewDataCompression string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANPOTSLinkConfig_1, "GetDataCompression", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewDataCompression, err = soap.UnmarshalString(response.NewDataCompression); err != nil { return } // END Unmarshal arguments from response. return } func (client *WANPOTSLinkConfig1) GetPlusVTRCommandSupported() (NewPlusVTRCommandSupported bool, err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := &struct { NewPlusVTRCommandSupported string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANPOTSLinkConfig_1, "GetPlusVTRCommandSupported", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewPlusVTRCommandSupported, err = soap.UnmarshalBoolean(response.NewPlusVTRCommandSupported); err != nil { return } // END Unmarshal arguments from response. return } // WANPPPConnection1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANPPPConnection:1". See // goupnp.ServiceClient, which contains RootDevice and Service attributes which // are provided for informational value. type WANPPPConnection1 struct { goupnp.ServiceClient } // NewWANPPPConnection1Clients 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(ctx context.Context) (clients []*WANPPPConnection1, errors []error, err error) { var genericClients []goupnp.ServiceClient 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 // 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) if err != nil { return nil, err } return newWANPPPConnection1ClientsFromGenericClients(genericClients), nil } // 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 // device. The location parameter is simply assigned to the Location attribute // of the wrapped ServiceClient(s). // // This is a typical entry calling point into this package when reusing an // previously discovered root device. func NewWANPPPConnection1ClientsFromRootDevice(rootDevice *goupnp.RootDevice, loc *url.URL) ([]*WANPPPConnection1, error) { genericClients, err := goupnp.NewServiceClientsFromRootDevice(rootDevice, loc, URN_WANPPPConnection_1) if err != nil { return nil, err } return newWANPPPConnection1ClientsFromGenericClients(genericClients), nil } func newWANPPPConnection1ClientsFromGenericClients(genericClients []goupnp.ServiceClient) []*WANPPPConnection1 { clients := make([]*WANPPPConnection1, len(genericClients)) for i := range genericClients { clients[i] = &WANPPPConnection1{genericClients[i]} } return clients } func (client *WANPPPConnection1) SetConnectionType(NewConnectionType string) (err error) { // Request structure. request := &struct { NewConnectionType string }{} // BEGIN Marshal arguments into request. if request.NewConnectionType, err = soap.MarshalString(NewConnectionType); err != nil { return } // END Marshal arguments into request. // Response structure. response := interface{}(nil) // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "SetConnectionType", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. // END Unmarshal arguments from response. return } // // Return values: // // * NewPossibleConnectionTypes: allowed values: Unconfigured, IP_Routed, DHCP_Spoofed, PPPoE_Bridged, PPTP_Relay, L2TP_Relay, PPPoE_Relay func (client *WANPPPConnection1) GetConnectionTypeInfo() (NewConnectionType string, NewPossibleConnectionTypes string, err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := &struct { NewConnectionType string NewPossibleConnectionTypes string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetConnectionTypeInfo", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewConnectionType, err = soap.UnmarshalString(response.NewConnectionType); err != nil { return } if NewPossibleConnectionTypes, err = soap.UnmarshalString(response.NewPossibleConnectionTypes); err != nil { return } // END Unmarshal arguments from response. return } func (client *WANPPPConnection1) ConfigureConnection(NewUserName string, NewPassword string) (err error) { // Request structure. request := &struct { NewUserName string NewPassword string }{} // BEGIN Marshal arguments into request. if request.NewUserName, err = soap.MarshalString(NewUserName); err != nil { return } if request.NewPassword, err = soap.MarshalString(NewPassword); err != nil { return } // END Marshal arguments into request. // Response structure. response := interface{}(nil) // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "ConfigureConnection", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. // END Unmarshal arguments from response. return } func (client *WANPPPConnection1) RequestConnection() (err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := interface{}(nil) // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "RequestConnection", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. // END Unmarshal arguments from response. return } func (client *WANPPPConnection1) RequestTermination() (err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := interface{}(nil) // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "RequestTermination", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. // END Unmarshal arguments from response. return } func (client *WANPPPConnection1) ForceTermination() (err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := interface{}(nil) // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "ForceTermination", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. // END Unmarshal arguments from response. return } func (client *WANPPPConnection1) SetAutoDisconnectTime(NewAutoDisconnectTime uint32) (err error) { // Request structure. request := &struct { NewAutoDisconnectTime string }{} // BEGIN Marshal arguments into request. if request.NewAutoDisconnectTime, err = soap.MarshalUi4(NewAutoDisconnectTime); err != nil { return } // END Marshal arguments into request. // Response structure. response := interface{}(nil) // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "SetAutoDisconnectTime", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. // END Unmarshal arguments from response. return } func (client *WANPPPConnection1) SetIdleDisconnectTime(NewIdleDisconnectTime uint32) (err error) { // Request structure. request := &struct { NewIdleDisconnectTime string }{} // BEGIN Marshal arguments into request. if request.NewIdleDisconnectTime, err = soap.MarshalUi4(NewIdleDisconnectTime); err != nil { return } // END Marshal arguments into request. // Response structure. response := interface{}(nil) // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "SetIdleDisconnectTime", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. // END Unmarshal arguments from response. return } func (client *WANPPPConnection1) SetWarnDisconnectDelay(NewWarnDisconnectDelay uint32) (err error) { // Request structure. request := &struct { NewWarnDisconnectDelay string }{} // BEGIN Marshal arguments into request. if request.NewWarnDisconnectDelay, err = soap.MarshalUi4(NewWarnDisconnectDelay); err != nil { return } // END Marshal arguments into request. // Response structure. response := interface{}(nil) // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "SetWarnDisconnectDelay", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. // END Unmarshal arguments from response. return } // // Return values: // // * NewConnectionStatus: allowed values: Unconfigured, Connected, Disconnected // // * NewLastConnectionError: allowed values: ERROR_NONE func (client *WANPPPConnection1) GetStatusInfo() (NewConnectionStatus string, NewLastConnectionError string, NewUptime uint32, err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := &struct { NewConnectionStatus string NewLastConnectionError string NewUptime string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetStatusInfo", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewConnectionStatus, err = soap.UnmarshalString(response.NewConnectionStatus); err != nil { return } if NewLastConnectionError, err = soap.UnmarshalString(response.NewLastConnectionError); err != nil { return } if NewUptime, err = soap.UnmarshalUi4(response.NewUptime); err != nil { return } // END Unmarshal arguments from response. return } func (client *WANPPPConnection1) GetLinkLayerMaxBitRates() (NewUpstreamMaxBitRate uint32, NewDownstreamMaxBitRate uint32, err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := &struct { NewUpstreamMaxBitRate string NewDownstreamMaxBitRate string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetLinkLayerMaxBitRates", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewUpstreamMaxBitRate, err = soap.UnmarshalUi4(response.NewUpstreamMaxBitRate); err != nil { return } if NewDownstreamMaxBitRate, err = soap.UnmarshalUi4(response.NewDownstreamMaxBitRate); err != nil { return } // END Unmarshal arguments from response. return } func (client *WANPPPConnection1) GetPPPEncryptionProtocol() (NewPPPEncryptionProtocol string, err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := &struct { NewPPPEncryptionProtocol string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetPPPEncryptionProtocol", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewPPPEncryptionProtocol, err = soap.UnmarshalString(response.NewPPPEncryptionProtocol); err != nil { return } // END Unmarshal arguments from response. return } func (client *WANPPPConnection1) GetPPPCompressionProtocol() (NewPPPCompressionProtocol string, err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := &struct { NewPPPCompressionProtocol string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetPPPCompressionProtocol", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewPPPCompressionProtocol, err = soap.UnmarshalString(response.NewPPPCompressionProtocol); err != nil { return } // END Unmarshal arguments from response. return } func (client *WANPPPConnection1) GetPPPAuthenticationProtocol() (NewPPPAuthenticationProtocol string, err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := &struct { NewPPPAuthenticationProtocol string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetPPPAuthenticationProtocol", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewPPPAuthenticationProtocol, err = soap.UnmarshalString(response.NewPPPAuthenticationProtocol); err != nil { return } // END Unmarshal arguments from response. return } func (client *WANPPPConnection1) GetUserName() (NewUserName string, err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := &struct { NewUserName string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetUserName", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewUserName, err = soap.UnmarshalString(response.NewUserName); err != nil { return } // END Unmarshal arguments from response. return } func (client *WANPPPConnection1) GetPassword() (NewPassword string, err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := &struct { NewPassword string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetPassword", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewPassword, err = soap.UnmarshalString(response.NewPassword); err != nil { return } // END Unmarshal arguments from response. return } func (client *WANPPPConnection1) GetAutoDisconnectTime() (NewAutoDisconnectTime uint32, err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := &struct { NewAutoDisconnectTime string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetAutoDisconnectTime", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewAutoDisconnectTime, err = soap.UnmarshalUi4(response.NewAutoDisconnectTime); err != nil { return } // END Unmarshal arguments from response. return } func (client *WANPPPConnection1) GetIdleDisconnectTime() (NewIdleDisconnectTime uint32, err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := &struct { NewIdleDisconnectTime string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetIdleDisconnectTime", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewIdleDisconnectTime, err = soap.UnmarshalUi4(response.NewIdleDisconnectTime); err != nil { return } // END Unmarshal arguments from response. return } func (client *WANPPPConnection1) GetWarnDisconnectDelay() (NewWarnDisconnectDelay uint32, err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := &struct { NewWarnDisconnectDelay string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetWarnDisconnectDelay", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewWarnDisconnectDelay, err = soap.UnmarshalUi4(response.NewWarnDisconnectDelay); err != nil { return } // END Unmarshal arguments from response. return } func (client *WANPPPConnection1) GetNATRSIPStatus() (NewRSIPAvailable bool, NewNATEnabled bool, err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := &struct { NewRSIPAvailable string NewNATEnabled string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetNATRSIPStatus", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewRSIPAvailable, err = soap.UnmarshalBoolean(response.NewRSIPAvailable); err != nil { return } if NewNATEnabled, err = soap.UnmarshalBoolean(response.NewNATEnabled); err != nil { return } // END Unmarshal arguments from response. return } // // Return values: // // * NewProtocol: allowed values: TCP, UDP func (client *WANPPPConnection1) GetGenericPortMappingEntry(NewPortMappingIndex uint16) (NewRemoteHost string, NewExternalPort uint16, NewProtocol string, NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32, err error) { // Request structure. request := &struct { NewPortMappingIndex string }{} // BEGIN Marshal arguments into request. if request.NewPortMappingIndex, err = soap.MarshalUi2(NewPortMappingIndex); err != nil { return } // END Marshal arguments into request. // Response structure. response := &struct { NewRemoteHost string NewExternalPort string NewProtocol string NewInternalPort string NewInternalClient string NewEnabled string NewPortMappingDescription string NewLeaseDuration string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetGenericPortMappingEntry", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewRemoteHost, err = soap.UnmarshalString(response.NewRemoteHost); err != nil { return } if NewExternalPort, err = soap.UnmarshalUi2(response.NewExternalPort); err != nil { return } if NewProtocol, err = soap.UnmarshalString(response.NewProtocol); err != nil { return } if NewInternalPort, err = soap.UnmarshalUi2(response.NewInternalPort); err != nil { return } if NewInternalClient, err = soap.UnmarshalString(response.NewInternalClient); err != nil { return } if NewEnabled, err = soap.UnmarshalBoolean(response.NewEnabled); err != nil { return } if NewPortMappingDescription, err = soap.UnmarshalString(response.NewPortMappingDescription); err != nil { return } if NewLeaseDuration, err = soap.UnmarshalUi4(response.NewLeaseDuration); err != nil { return } // END Unmarshal arguments from response. return } // // Arguments: // // * NewProtocol: allowed values: TCP, UDP func (client *WANPPPConnection1) GetSpecificPortMappingEntry(NewRemoteHost string, NewExternalPort uint16, NewProtocol string) (NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32, err error) { // Request structure. request := &struct { NewRemoteHost string NewExternalPort string NewProtocol string }{} // BEGIN Marshal arguments into request. if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil { return } if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil { return } if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { return } // END Marshal arguments into request. // Response structure. response := &struct { NewInternalPort string NewInternalClient string NewEnabled string NewPortMappingDescription string NewLeaseDuration string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetSpecificPortMappingEntry", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewInternalPort, err = soap.UnmarshalUi2(response.NewInternalPort); err != nil { return } if NewInternalClient, err = soap.UnmarshalString(response.NewInternalClient); err != nil { return } if NewEnabled, err = soap.UnmarshalBoolean(response.NewEnabled); err != nil { return } if NewPortMappingDescription, err = soap.UnmarshalString(response.NewPortMappingDescription); err != nil { return } if NewLeaseDuration, err = soap.UnmarshalUi4(response.NewLeaseDuration); err != nil { return } // END Unmarshal arguments from response. return } // // Arguments: // // * NewProtocol: allowed values: TCP, UDP func (client *WANPPPConnection1) AddPortMapping(NewRemoteHost string, NewExternalPort uint16, NewProtocol string, NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32) (err error) { // Request structure. request := &struct { NewRemoteHost string NewExternalPort string NewProtocol string NewInternalPort string NewInternalClient string NewEnabled string NewPortMappingDescription string NewLeaseDuration string }{} // BEGIN Marshal arguments into request. if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil { return } if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil { return } if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { return } if request.NewInternalPort, err = soap.MarshalUi2(NewInternalPort); err != nil { return } if request.NewInternalClient, err = soap.MarshalString(NewInternalClient); err != nil { return } if request.NewEnabled, err = soap.MarshalBoolean(NewEnabled); err != nil { return } if request.NewPortMappingDescription, err = soap.MarshalString(NewPortMappingDescription); err != nil { return } if request.NewLeaseDuration, err = soap.MarshalUi4(NewLeaseDuration); err != nil { return } // END Marshal arguments into request. // Response structure. response := interface{}(nil) // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "AddPortMapping", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. // END Unmarshal arguments from response. return } // // Arguments: // // * NewProtocol: allowed values: TCP, UDP func (client *WANPPPConnection1) DeletePortMapping(NewRemoteHost string, NewExternalPort uint16, NewProtocol string) (err error) { // Request structure. request := &struct { NewRemoteHost string NewExternalPort string NewProtocol string }{} // BEGIN Marshal arguments into request. if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil { return } if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil { return } if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { return } // END Marshal arguments into request. // Response structure. response := interface{}(nil) // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "DeletePortMapping", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. // END Unmarshal arguments from response. return } func (client *WANPPPConnection1) GetExternalIPAddress() (NewExternalIPAddress string, err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. // END Marshal arguments into request. // Response structure. response := &struct { NewExternalIPAddress string }{} // Perform the SOAP call. if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetExternalIPAddress", request, response); err != nil { return } // BEGIN Unmarshal arguments from response. if NewExternalIPAddress, err = soap.UnmarshalString(response.NewExternalIPAddress); err != nil { return } // END Unmarshal arguments from response. return } go-upnp-master/goupnp/device.go0000644000175000017500000001236113165312311015455 0ustar freefree// This file contains XML structures for communicating with UPnP devices. package goupnp import ( "encoding/xml" "errors" "fmt" "net/url" "github.com/NebulousLabs/go-upnp/goupnp/scpd" "github.com/NebulousLabs/go-upnp/goupnp/soap" ) const ( DeviceXMLNamespace = "urn:schemas-upnp-org:device-1-0" ) // RootDevice is the device description as described by section 2.3 "Device // description" in // http://upnp.org/specs/arch/UPnP-arch-DeviceArchitecture-v1.1.pdf type RootDevice struct { XMLName xml.Name `xml:"root"` SpecVersion SpecVersion `xml:"specVersion"` URLBase url.URL `xml:"-"` URLBaseStr string `xml:"URLBase"` Device Device `xml:"device"` } // SetURLBase sets the URLBase for the RootDevice and its underlying components. func (root *RootDevice) SetURLBase(urlBase *url.URL) { root.URLBase = *urlBase root.URLBaseStr = urlBase.String() root.Device.SetURLBase(urlBase) } // SpecVersion is part of a RootDevice, describes the version of the // specification that the data adheres to. type SpecVersion struct { Major int32 `xml:"major"` Minor int32 `xml:"minor"` } // Device is a UPnP device. It can have child devices. type Device struct { DeviceType string `xml:"deviceType"` FriendlyName string `xml:"friendlyName"` Manufacturer string `xml:"manufacturer"` ManufacturerURL URLField `xml:"manufacturerURL"` ModelDescription string `xml:"modelDescription"` ModelName string `xml:"modelName"` ModelNumber string `xml:"modelNumber"` ModelURL URLField `xml:"modelURL"` SerialNumber string `xml:"serialNumber"` UDN string `xml:"UDN"` UPC string `xml:"UPC,omitempty"` Icons []Icon `xml:"iconList>icon,omitempty"` Services []Service `xml:"serviceList>service,omitempty"` Devices []Device `xml:"deviceList>device,omitempty"` // Extra observed elements: PresentationURL URLField `xml:"presentationURL"` } // VisitDevices calls visitor for the device, and all its descendent devices. func (device *Device) VisitDevices(visitor func(*Device)) { visitor(device) for i := range device.Devices { device.Devices[i].VisitDevices(visitor) } } // VisitServices calls visitor for all Services under the device and all its // descendent devices. func (device *Device) VisitServices(visitor func(*Service)) { device.VisitDevices(func(d *Device) { for i := range d.Services { visitor(&d.Services[i]) } }) } // FindService finds all (if any) Services under the device and its descendents // that have the given ServiceType. func (device *Device) FindService(serviceType string) []*Service { var services []*Service device.VisitServices(func(s *Service) { if s.ServiceType == serviceType { services = append(services, s) } }) return services } // SetURLBase sets the URLBase for the Device and its underlying components. func (device *Device) SetURLBase(urlBase *url.URL) { device.ManufacturerURL.SetURLBase(urlBase) device.ModelURL.SetURLBase(urlBase) device.PresentationURL.SetURLBase(urlBase) for i := range device.Icons { device.Icons[i].SetURLBase(urlBase) } for i := range device.Services { device.Services[i].SetURLBase(urlBase) } for i := range device.Devices { device.Devices[i].SetURLBase(urlBase) } } func (device *Device) String() string { return fmt.Sprintf("Device ID %s : %s (%s)", device.UDN, device.DeviceType, device.FriendlyName) } // Icon is a representative image that a device might include in its // description. type Icon struct { Mimetype string `xml:"mimetype"` Width int32 `xml:"width"` Height int32 `xml:"height"` Depth int32 `xml:"depth"` URL URLField `xml:"url"` } // SetURLBase sets the URLBase for the Icon. func (icon *Icon) SetURLBase(url *url.URL) { icon.URL.SetURLBase(url) } // Service is a service provided by a UPnP Device. type Service struct { ServiceType string `xml:"serviceType"` ServiceId string `xml:"serviceId"` SCPDURL URLField `xml:"SCPDURL"` ControlURL URLField `xml:"controlURL"` EventSubURL URLField `xml:"eventSubURL"` } // SetURLBase sets the URLBase for the Service. func (srv *Service) SetURLBase(urlBase *url.URL) { srv.SCPDURL.SetURLBase(urlBase) srv.ControlURL.SetURLBase(urlBase) srv.EventSubURL.SetURLBase(urlBase) } func (srv *Service) String() string { return fmt.Sprintf("Service ID %s : %s", srv.ServiceId, srv.ServiceType) } // RequestSCDP requests the SCPD (soap actions and state variables description) // for the service. func (srv *Service) RequestSCDP() (*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 { return nil, err } 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. type URLField struct { URL url.URL `xml:"-"` Ok bool `xml:"-"` Str string `xml:",chardata"` } func (uf *URLField) SetURLBase(urlBase *url.URL) { refUrl, err := url.Parse(uf.Str) if err != nil { uf.URL = url.URL{} uf.Ok = false return } uf.URL = *urlBase.ResolveReference(refUrl) uf.Ok = true } go-upnp-master/goupnp/goupnp.go0000644000175000017500000000776013165312311015535 0ustar freefree// goupnp is an implementation of a client for various UPnP services. // // For most uses, it is recommended to use the code-generated packages under // github.com/huin/goupnp/dcps. Example use is shown at // http://godoc.org/github.com/huin/goupnp/example // // A commonly used client is internetgateway1.WANPPPConnection1: // http://godoc.org/github.com/huin/goupnp/dcps/internetgateway1#WANPPPConnection1 // // Currently only a couple of schemas have code generated for them from the // UPnP example XML specifications. Not all methods will work on these clients, // because the generated stubs contain the full set of specified methods from // the XML specifications, and the discovered services will likely support a // subset of those methods. package goupnp import ( "context" "encoding/xml" "fmt" "net/http" "net/url" "time" "github.com/NebulousLabs/go-upnp/goupnp/httpu" "github.com/NebulousLabs/go-upnp/goupnp/ssdp" "golang.org/x/net/html/charset" ) // ContextError is an error that wraps an error with some context information. type ContextError struct { Context string Err error } func (err ContextError) Error() string { return fmt.Sprintf("%s: %v", err.Context, err.Err) } // MaybeRootDevice contains either a RootDevice or an error. type MaybeRootDevice struct { // Set iff Err == nil. Root *RootDevice // The location the device was discovered at. This can be used with // DeviceByURL, assuming the device is still present. A location represents // the discovery of a device, regardless of if there was an error probing it. Location *url.URL // Any error encountered probing a discovered device. Err error } // DiscoverDevices is deprecated. Use DiscoverDevicesCtx instead. func DiscoverDevices(searchTarget string) ([]MaybeRootDevice, error) { return DiscoverDevicesCtx(context.Background(), searchTarget) } // 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 DiscoverDevicesCtx(ctx context.Context, searchTarget string) ([]MaybeRootDevice, error) { httpu, err := httpu.NewHTTPUClient() if err != nil { return nil, err } defer httpu.Close() responses, err := ssdp.SSDPRawSearchCtx(ctx, httpu, string(searchTarget), 2, 3) if err != nil { return nil, err } results := make([]MaybeRootDevice, len(responses)) for i, response := range responses { maybe := &results[i] loc, err := response.Location() if err != nil { maybe.Err = ContextError{"unexpected bad location from search", err} continue } maybe.Location = loc if root, err := DeviceByURL(loc); err != nil { maybe.Err = err } else { maybe.Root = root } } return results, nil } func DeviceByURL(loc *url.URL) (*RootDevice, error) { locStr := loc.String() root := new(RootDevice) if err := requestXml(locStr, DeviceXMLNamespace, root); err != nil { return nil, ContextError{fmt.Sprintf("error requesting root device details from %q", locStr), err} } var urlBaseStr string if root.URLBaseStr != "" { urlBaseStr = root.URLBaseStr } else { urlBaseStr = locStr } urlBase, err := url.Parse(urlBaseStr) if err != nil { return nil, ContextError{fmt.Sprintf("error parsing location URL %q", locStr), err} } root.SetURLBase(urlBase) return root, nil } func requestXml(url string, defaultSpace string, doc interface{}) error { timeout := time.Duration(3 * time.Second) client := http.Client{ Timeout: timeout, } resp, err := client.Get(url) if err != nil { return err } defer resp.Body.Close() if resp.StatusCode != 200 { return fmt.Errorf("goupnp: got response status %s from %q", resp.Status, url) } decoder := xml.NewDecoder(resp.Body) decoder.DefaultSpace = defaultSpace decoder.CharsetReader = charset.NewReaderLabel return decoder.Decode(doc) } go-upnp-master/goupnp/httpu/0000755000175000017500000000000013165312311015030 5ustar freefreego-upnp-master/goupnp/httpu/httpu.go0000644000175000017500000000634713165312311016535 0ustar freefreepackage httpu import ( "bufio" "bytes" "fmt" "net" "net/http" "sync" "time" ) // HTTPUClient is a client for dealing with HTTPU (HTTP over UDP). Its typical // function is for HTTPMU, and particularly SSDP. type HTTPUClient struct { connLock sync.Mutex // Protects use of conn. conn net.PacketConn } // NewHTTPUClient creates a new HTTPUClient, opening up a new UDP socket for the // purpose. func NewHTTPUClient() (*HTTPUClient, error) { conn, err := net.ListenPacket("udp", ":0") if err != nil { return nil, err } return &HTTPUClient{conn: conn}, nil } // Close shuts down the client. The client will no longer be useful following // this. func (httpu *HTTPUClient) Close() error { httpu.connLock.Lock() defer httpu.connLock.Unlock() return httpu.conn.Close() } // Do performs a request. The timeout is how long to wait for before returning // the responses that were received. An error is only returned for failing to // send the request. Failures in receipt simply do not add to the resulting // responses. // // Note that at present only one concurrent connection will happen per // HTTPUClient. func (httpu *HTTPUClient) Do(req *http.Request, timeout time.Duration, numSends int) ([]*http.Response, error) { httpu.connLock.Lock() defer httpu.connLock.Unlock() // Create the request. This is a subset of what http.Request.Write does // deliberately to avoid creating extra fields which may confuse some // devices. var requestBuf bytes.Buffer method := req.Method if method == "" { method = "GET" } if _, err := fmt.Fprintf(&requestBuf, "%s %s HTTP/1.1\r\n", method, req.URL.RequestURI()); err != nil { return nil, err } if err := req.Header.Write(&requestBuf); err != nil { return nil, err } if _, err := requestBuf.Write([]byte{'\r', '\n'}); err != nil { return nil, err } destAddr, err := net.ResolveUDPAddr("udp", req.Host) if err != nil { return nil, err } if err = httpu.conn.SetDeadline(time.Now().Add(timeout)); err != nil { return nil, err } // Spawn cancellation goroutine done := make(chan struct{}) defer close(done) go func() { select { case <-done: case <-req.Context().Done(): httpu.conn.SetDeadline(time.Unix(1, 0)) } }() // Send request. for i := 0; i < numSends; i++ { if n, err := httpu.conn.WriteTo(requestBuf.Bytes(), destAddr); err != nil { return nil, err } else if n < len(requestBuf.Bytes()) { return nil, fmt.Errorf("httpu: wrote %d bytes rather than full %d in request", n, len(requestBuf.Bytes())) } time.Sleep(5 * time.Millisecond) } // Await responses until timeout. var responses []*http.Response responseBytes := make([]byte, 2048) for { // 2048 bytes should be sufficient for most networks. n, _, err := httpu.conn.ReadFrom(responseBytes) if err != nil { if err, ok := err.(net.Error); ok { if err.Timeout() { break } if err.Temporary() { // Sleep in case this is a persistent error to avoid pegging CPU until deadline. time.Sleep(10 * time.Millisecond) continue } } return nil, err } // Parse response. response, err := http.ReadResponse(bufio.NewReader(bytes.NewBuffer(responseBytes[:n])), req) if err != nil { continue } responses = append(responses, response) } return responses, err } go-upnp-master/goupnp/httpu/serve.go0000644000175000017500000000546213165312311016512 0ustar freefreepackage httpu import ( "bufio" "bytes" "net" "net/http" "regexp" ) const ( DefaultMaxMessageBytes = 2048 ) var ( trailingWhitespaceRx = regexp.MustCompile(" +\r\n") crlf = []byte("\r\n") ) // Handler is the interface by which received HTTPU messages are passed to // handling code. type Handler interface { // ServeMessage is called for each HTTPU message received. peerAddr contains // the address that the message was received from. ServeMessage(r *http.Request) } // HandlerFunc is a function-to-Handler adapter. type HandlerFunc func(r *http.Request) func (f HandlerFunc) ServeMessage(r *http.Request) { f(r) } // A Server defines parameters for running an HTTPU server. type Server struct { Addr string // UDP address to listen on Multicast bool // Should listen for multicast? Interface *net.Interface // Network interface to listen on for multicast, nil for default multicast interface Handler Handler // handler to invoke MaxMessageBytes int // maximum number of bytes to read from a packet, DefaultMaxMessageBytes if 0 } // ListenAndServe listens on the UDP network address srv.Addr. If srv.Multicast // is true, then a multicast UDP listener will be used on srv.Interface (or // default interface if nil). func (srv *Server) ListenAndServe() error { var err error var addr *net.UDPAddr if addr, err = net.ResolveUDPAddr("udp", srv.Addr); err != nil { return err } var conn net.PacketConn if srv.Multicast { if conn, err = net.ListenMulticastUDP("udp", srv.Interface, addr); err != nil { return err } } else { if conn, err = net.ListenUDP("udp", addr); err != nil { return err } } return srv.Serve(conn) } // Serve messages received on the given packet listener to the srv.Handler. func (srv *Server) Serve(l net.PacketConn) error { maxMessageBytes := DefaultMaxMessageBytes if srv.MaxMessageBytes != 0 { maxMessageBytes = srv.MaxMessageBytes } for { buf := make([]byte, maxMessageBytes) n, peerAddr, err := l.ReadFrom(buf) if err != nil { return err } buf = buf[:n] go func(buf []byte, peerAddr net.Addr) { // At least one router's UPnP implementation has added a trailing space // after "HTTP/1.1" - trim it. buf = trailingWhitespaceRx.ReplaceAllLiteral(buf, crlf) req, err := http.ReadRequest(bufio.NewReader(bytes.NewBuffer(buf))) if err != nil { return } req.RemoteAddr = peerAddr.String() srv.Handler.ServeMessage(req) // No need to call req.Body.Close - underlying reader is bytes.Buffer. }(buf, peerAddr) } } // Serve messages received on the given packet listener to the given handler. func Serve(l net.PacketConn, handler Handler) error { srv := Server{ Handler: handler, MaxMessageBytes: DefaultMaxMessageBytes, } return srv.Serve(l) } go-upnp-master/goupnp/scpd/0000755000175000017500000000000013165312311014615 5ustar freefreego-upnp-master/goupnp/scpd/scpd.go0000644000175000017500000001001713165312311016074 0ustar freefreepackage scpd import ( "encoding/xml" "strings" ) const ( SCPDXMLNamespace = "urn:schemas-upnp-org:service-1-0" ) func cleanWhitespace(s *string) { *s = strings.TrimSpace(*s) } // 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"` } // Clean attempts to remove stray whitespace etc. in the structure. It seems // unfortunately common for stray whitespace to be present in SCPD documents, // this method attempts to make it easy to clean them out. func (scpd *SCPD) Clean() { cleanWhitespace(&scpd.ConfigId) for i := range scpd.Actions { scpd.Actions[i].clean() } for i := range scpd.StateVariables { scpd.StateVariables[i].clean() } } func (scpd *SCPD) GetStateVariable(variable string) *StateVariable { for i := range scpd.StateVariables { v := &scpd.StateVariables[i] if v.Name == variable { return v } } return nil } func (scpd *SCPD) GetAction(action string) *Action { for i := range scpd.Actions { a := &scpd.Actions[i] if a.Name == action { return a } } return nil } // SpecVersion is part of a SCPD document, describes the version of the // specification that the data adheres to. type SpecVersion struct { Major int32 `xml:"major"` Minor int32 `xml:"minor"` } type Action struct { Name string `xml:"name"` Arguments []Argument `xml:"argumentList>argument"` } func (action *Action) clean() { cleanWhitespace(&action.Name) for i := range action.Arguments { action.Arguments[i].clean() } } func (action *Action) InputArguments() []*Argument { var result []*Argument for i := range action.Arguments { arg := &action.Arguments[i] if arg.IsInput() { result = append(result, arg) } } return result } func (action *Action) OutputArguments() []*Argument { var result []*Argument for i := range action.Arguments { arg := &action.Arguments[i] if arg.IsOutput() { result = append(result, arg) } } return result } type Argument struct { Name string `xml:"name"` Direction string `xml:"direction"` // in|out RelatedStateVariable string `xml:"relatedStateVariable"` // ? Retval string `xml:"retval"` // ? } func (arg *Argument) clean() { cleanWhitespace(&arg.Name) cleanWhitespace(&arg.Direction) cleanWhitespace(&arg.RelatedStateVariable) cleanWhitespace(&arg.Retval) } func (arg *Argument) IsInput() bool { return arg.Direction == "in" } func (arg *Argument) IsOutput() bool { return arg.Direction == "out" } 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"` AllowedValues []string `xml:"allowedValueList>allowedValue"` } func (v *StateVariable) clean() { cleanWhitespace(&v.Name) cleanWhitespace(&v.SendEvents) cleanWhitespace(&v.Multicast) v.DataType.clean() cleanWhitespace(&v.DefaultValue) if v.AllowedValueRange != nil { v.AllowedValueRange.clean() } for i := range v.AllowedValues { cleanWhitespace(&v.AllowedValues[i]) } } type AllowedValueRange struct { Minimum string `xml:"minimum"` Maximum string `xml:"maximum"` Step string `xml:"step"` } func (r *AllowedValueRange) clean() { cleanWhitespace(&r.Minimum) cleanWhitespace(&r.Maximum) cleanWhitespace(&r.Step) } type DataType struct { Name string `xml:",chardata"` Type string `xml:"type,attr"` } func (dt *DataType) clean() { cleanWhitespace(&dt.Name) cleanWhitespace(&dt.Type) } go-upnp-master/goupnp/service_client.go0000644000175000017500000000612713165312311017217 0ustar freefreepackage goupnp import ( "context" "fmt" "net/url" "github.com/NebulousLabs/go-upnp/goupnp/soap" ) // ServiceClient is a SOAP client, root device and the service for the SOAP // client rolled into one value. The root device, location, and service are // intended to be informational. Location can be used to later recreate a // ServiceClient with NewServiceClientByURL if the service is still present; // bypassing the discovery process. type ServiceClient struct { SOAPClient *soap.SOAPClient RootDevice *RootDevice Location *url.URL Service *Service } // NewServiceClients is deprecated. Use NewServiceClientsCtx instead. func NewServiceClients(searchTarget string) (clients []ServiceClient, errors []error, err error) { return NewServiceClientsCtx(context.Background(), searchTarget) } // 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 NewServiceClientsCtx(ctx context.Context, searchTarget string) (clients []ServiceClient, errors []error, err error) { var maybeRootDevices []MaybeRootDevice if maybeRootDevices, err = DiscoverDevicesCtx(ctx, searchTarget); err != nil { return } clients = make([]ServiceClient, 0, len(maybeRootDevices)) for _, maybeRootDevice := range maybeRootDevices { if maybeRootDevice.Err != nil { errors = append(errors, maybeRootDevice.Err) continue } deviceClients, err := NewServiceClientsFromRootDevice(maybeRootDevice.Root, maybeRootDevice.Location, searchTarget) if err != nil { errors = append(errors, err) continue } clients = append(clients, deviceClients...) } return } // NewServiceClientsByURL 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) if err != nil { return nil, err } return NewServiceClientsFromRootDevice(rootDevice, 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). func NewServiceClientsFromRootDevice(rootDevice *RootDevice, loc *url.URL, searchTarget string) ([]ServiceClient, error) { device := &rootDevice.Device srvs := device.FindService(searchTarget) if len(srvs) == 0 { return nil, fmt.Errorf("goupnp: service %q not found within device %q (UDN=%q)", searchTarget, device.FriendlyName, device.UDN) } clients := make([]ServiceClient, 0, len(srvs)) for _, srv := range srvs { clients = append(clients, ServiceClient{ SOAPClient: srv.NewSOAPClient(), RootDevice: rootDevice, Location: loc, Service: srv, }) } return clients, nil } // GetServiceClient returns the ServiceClient itself. This is provided so that the // service client attributes can be accessed via an interface method on a // wrapping type. func (client *ServiceClient) GetServiceClient() *ServiceClient { return client } go-upnp-master/goupnp/soap/0000755000175000017500000000000013165312311014626 5ustar freefreego-upnp-master/goupnp/soap/soap.go0000644000175000017500000001176513165312311016131 0ustar freefree// Definition for the SOAP structure required for UPnP's SOAP usage. package soap import ( "bytes" "encoding/xml" "fmt" "io/ioutil" "net/http" "net/url" "reflect" ) const ( soapEncodingStyle = "http://schemas.xmlsoap.org/soap/encoding/" soapPrefix = xml.Header + `` soapSuffix = `` ) type SOAPClient struct { EndpointURL url.URL HTTPClient http.Client } func NewSOAPClient(endpointURL url.URL) *SOAPClient { return &SOAPClient{ EndpointURL: endpointURL, } } // PerformSOAPAction makes a SOAP request, with the given action. // inAction and outAction must both be pointers to structs with string fields // only. func (client *SOAPClient) PerformAction(actionNamespace, actionName string, inAction interface{}, outAction interface{}) error { requestBytes, err := encodeRequestAction(actionNamespace, actionName, inAction) if err != nil { return err } response, err := client.HTTPClient.Do(&http.Request{ Method: "POST", URL: &client.EndpointURL, Header: http.Header{ "SOAPACTION": []string{`"` + actionNamespace + "#" + actionName + `"`}, "CONTENT-TYPE": []string{"text/xml; charset=\"utf-8\""}, }, Body: ioutil.NopCloser(bytes.NewBuffer(requestBytes)), // Set ContentLength to avoid chunked encoding - some servers might not support it. ContentLength: int64(len(requestBytes)), }) if err != nil { return fmt.Errorf("goupnp: error performing SOAP HTTP request: %v", err) } defer response.Body.Close() if response.StatusCode != 200 { resp, _ := ioutil.ReadAll(response.Body) return fmt.Errorf("goupnp: SOAP request got HTTP %s: %s", response.Status, resp) } responseEnv := newSOAPEnvelope() decoder := xml.NewDecoder(response.Body) if err := decoder.Decode(responseEnv); err != nil { return fmt.Errorf("goupnp: error decoding response body: %v", err) } if responseEnv.Body.Fault != nil { return responseEnv.Body.Fault } if outAction != nil { if err := xml.Unmarshal(responseEnv.Body.RawAction, outAction); err != nil { return fmt.Errorf("goupnp: error unmarshalling out action: %v, %v", err, responseEnv.Body.RawAction) } } return nil } // newSOAPAction creates a soapEnvelope with the given action and arguments. func newSOAPEnvelope() *soapEnvelope { return &soapEnvelope{ EncodingStyle: soapEncodingStyle, } } // encodeRequestAction is a hacky way to create an encoded SOAP envelope // containing the given action. Experiments with one router have shown that it // 500s for requests where the outer default xmlns is set to the SOAP // namespace, and then reassigning the default namespace within that to the // service namespace. Hand-coding the outer XML to work-around this. func encodeRequestAction(actionNamespace, actionName string, inAction interface{}) ([]byte, error) { requestBuf := new(bytes.Buffer) requestBuf.WriteString(soapPrefix) requestBuf.WriteString(``) if inAction != nil { if err := encodeRequestArgs(requestBuf, inAction); err != nil { return nil, err } } requestBuf.WriteString(``) requestBuf.WriteString(soapSuffix) return requestBuf.Bytes(), nil } func encodeRequestArgs(w *bytes.Buffer, inAction interface{}) error { in := reflect.Indirect(reflect.ValueOf(inAction)) if in.Kind() != reflect.Struct { return fmt.Errorf("goupnp: SOAP inAction is not a struct but of type %v", in.Type()) } enc := xml.NewEncoder(w) nFields := in.NumField() inType := in.Type() for i := 0; i < nFields; i++ { field := inType.Field(i) argName := field.Name if nameOverride := field.Tag.Get("soap"); nameOverride != "" { argName = nameOverride } value := in.Field(i) if value.Kind() != reflect.String { return fmt.Errorf("goupnp: SOAP arg %q is not of type string, but of type %v", argName, value.Type()) } if err := enc.EncodeElement(value.Interface(), xml.StartElement{xml.Name{"", argName}, nil}); err != nil { return fmt.Errorf("goupnp: error encoding SOAP arg %q: %v", argName, err) } } enc.Flush() return nil } type soapEnvelope struct { XMLName xml.Name `xml:"http://schemas.xmlsoap.org/soap/envelope/ Envelope"` EncodingStyle string `xml:"http://schemas.xmlsoap.org/soap/envelope/ encodingStyle,attr"` Body soapBody `xml:"http://schemas.xmlsoap.org/soap/envelope/ Body"` } type soapBody struct { Fault *SOAPFaultError `xml:"Fault"` RawAction []byte `xml:",innerxml"` } // SOAPFaultError implements error, and contains SOAP fault information. type SOAPFaultError struct { FaultCode string `xml:"faultcode"` FaultString string `xml:"faultstring"` Detail string `xml:"detail"` } func (err *SOAPFaultError) Error() string { return fmt.Sprintf("SOAP fault: %s", err.FaultString) } go-upnp-master/goupnp/soap/types.go0000644000175000017500000003143013165312311016322 0ustar freefreepackage soap import ( "encoding/base64" "encoding/hex" "errors" "fmt" "net/url" "regexp" "strconv" "strings" "time" "unicode/utf8" ) var ( // localLoc acts like time.Local for this package, but is faked out by the // unit tests to ensure that things stay constant (especially when running // this test in a place where local time is UTC which might mask bugs). localLoc = time.Local ) func MarshalUi1(v uint8) (string, error) { return strconv.FormatUint(uint64(v), 10), nil } func UnmarshalUi1(s string) (uint8, error) { v, err := strconv.ParseUint(s, 10, 8) return uint8(v), err } func MarshalUi2(v uint16) (string, error) { return strconv.FormatUint(uint64(v), 10), nil } func UnmarshalUi2(s string) (uint16, error) { v, err := strconv.ParseUint(s, 10, 16) return uint16(v), err } func MarshalUi4(v uint32) (string, error) { return strconv.FormatUint(uint64(v), 10), nil } func UnmarshalUi4(s string) (uint32, error) { v, err := strconv.ParseUint(s, 10, 32) return uint32(v), err } func MarshalI1(v int8) (string, error) { return strconv.FormatInt(int64(v), 10), nil } func UnmarshalI1(s string) (int8, error) { v, err := strconv.ParseInt(s, 10, 8) return int8(v), err } func MarshalI2(v int16) (string, error) { return strconv.FormatInt(int64(v), 10), nil } func UnmarshalI2(s string) (int16, error) { v, err := strconv.ParseInt(s, 10, 16) return int16(v), err } func MarshalI4(v int32) (string, error) { return strconv.FormatInt(int64(v), 10), nil } func UnmarshalI4(s string) (int32, error) { v, err := strconv.ParseInt(s, 10, 32) return int32(v), err } func MarshalInt(v int64) (string, error) { return strconv.FormatInt(v, 10), nil } func UnmarshalInt(s string) (int64, error) { return strconv.ParseInt(s, 10, 64) } func MarshalR4(v float32) (string, error) { return strconv.FormatFloat(float64(v), 'G', -1, 32), nil } func UnmarshalR4(s string) (float32, error) { v, err := strconv.ParseFloat(s, 32) return float32(v), err } func MarshalR8(v float64) (string, error) { return strconv.FormatFloat(v, 'G', -1, 64), nil } func UnmarshalR8(s string) (float64, error) { v, err := strconv.ParseFloat(s, 64) return float64(v), err } // MarshalFixed14_4 marshals float64 to SOAP "fixed.14.4" type. func MarshalFixed14_4(v float64) (string, error) { if v >= 1e14 || v <= -1e14 { return "", fmt.Errorf("soap fixed14.4: value %v out of bounds", v) } return strconv.FormatFloat(v, 'f', 4, 64), nil } // UnmarshalFixed14_4 unmarshals float64 from SOAP "fixed.14.4" type. func UnmarshalFixed14_4(s string) (float64, error) { v, err := strconv.ParseFloat(s, 64) if err != nil { return 0, err } if v >= 1e14 || v <= -1e14 { return 0, fmt.Errorf("soap fixed14.4: value %q out of bounds", s) } return v, nil } // MarshalChar marshals rune to SOAP "char" type. func MarshalChar(v rune) (string, error) { if v == 0 { return "", errors.New("soap char: rune 0 is not allowed") } return string(v), nil } // UnmarshalChar unmarshals rune from SOAP "char" type. func UnmarshalChar(s string) (rune, error) { if len(s) == 0 { return 0, errors.New("soap char: got empty string") } r, n := utf8.DecodeRune([]byte(s)) if n != len(s) { return 0, fmt.Errorf("soap char: value %q is not a single rune", s) } return r, nil } func MarshalString(v string) (string, error) { return v, nil } func UnmarshalString(v string) (string, error) { return v, nil } func parseInt(s string, err *error) int { v, parseErr := strconv.ParseInt(s, 10, 64) if parseErr != nil { *err = parseErr } return int(v) } var dateRegexps = []*regexp.Regexp{ // yyyy[-mm[-dd]] regexp.MustCompile(`^(\d{4})(?:-(\d{2})(?:-(\d{2}))?)?$`), // yyyy[mm[dd]] regexp.MustCompile(`^(\d{4})(?:(\d{2})(?:(\d{2}))?)?$`), } func parseDateParts(s string) (year, month, day int, err error) { var parts []string for _, re := range dateRegexps { parts = re.FindStringSubmatch(s) if parts != nil { break } } if parts == nil { err = fmt.Errorf("soap date: value %q is not in a recognized ISO8601 date format", s) return } year = parseInt(parts[1], &err) month = 1 day = 1 if len(parts[2]) != 0 { month = parseInt(parts[2], &err) if len(parts[3]) != 0 { day = parseInt(parts[3], &err) } } if err != nil { err = fmt.Errorf("soap date: %q: %v", s, err) } return } var timeRegexps = []*regexp.Regexp{ // hh[:mm[:ss]] regexp.MustCompile(`^(\d{2})(?::(\d{2})(?::(\d{2}))?)?$`), // hh[mm[ss]] regexp.MustCompile(`^(\d{2})(?:(\d{2})(?:(\d{2}))?)?$`), } func parseTimeParts(s string) (hour, minute, second int, err error) { var parts []string for _, re := range timeRegexps { parts = re.FindStringSubmatch(s) if parts != nil { break } } if parts == nil { err = fmt.Errorf("soap time: value %q is not in ISO8601 time format", s) return } hour = parseInt(parts[1], &err) if len(parts[2]) != 0 { minute = parseInt(parts[2], &err) if len(parts[3]) != 0 { second = parseInt(parts[3], &err) } } if err != nil { err = fmt.Errorf("soap time: %q: %v", s, err) } return } // (+|-)hh[[:]mm] var timezoneRegexp = regexp.MustCompile(`^([+-])(\d{2})(?::?(\d{2}))?$`) func parseTimezone(s string) (offset int, err error) { if s == "Z" { return 0, nil } parts := timezoneRegexp.FindStringSubmatch(s) if parts == nil { err = fmt.Errorf("soap timezone: value %q is not in ISO8601 timezone format", s) return } offset = parseInt(parts[2], &err) * 3600 if len(parts[3]) != 0 { offset += parseInt(parts[3], &err) * 60 } if parts[1] == "-" { offset = -offset } if err != nil { err = fmt.Errorf("soap timezone: %q: %v", s, err) } return } var completeDateTimeZoneRegexp = regexp.MustCompile(`^([^T]+)(?:T([^-+Z]+)(.+)?)?$`) // splitCompleteDateTimeZone splits date, time and timezone apart from an // ISO8601 string. It does not ensure that the contents of each part are // correct, it merely splits on certain delimiters. // e.g "2010-09-08T12:15:10+0700" => "2010-09-08", "12:15:10", "+0700". // Timezone can only be present if time is also present. func splitCompleteDateTimeZone(s string) (dateStr, timeStr, zoneStr string, err error) { parts := completeDateTimeZoneRegexp.FindStringSubmatch(s) if parts == nil { err = fmt.Errorf("soap date/time/zone: value %q is not in ISO8601 datetime format", s) return } dateStr = parts[1] timeStr = parts[2] zoneStr = parts[3] return } // MarshalDate marshals time.Time to SOAP "date" type. Note that this converts // to local time, and discards the time-of-day components. func MarshalDate(v time.Time) (string, error) { return v.In(localLoc).Format("2006-01-02"), nil } var dateFmts = []string{"2006-01-02", "20060102"} // UnmarshalDate unmarshals time.Time from SOAP "date" type. This outputs the // date as midnight in the local time zone. func UnmarshalDate(s string) (time.Time, error) { year, month, day, err := parseDateParts(s) if err != nil { return time.Time{}, err } return time.Date(year, time.Month(month), day, 0, 0, 0, 0, localLoc), nil } // TimeOfDay is used in cases where SOAP "time" or "time.tz" is used. type TimeOfDay struct { // Duration of time since midnight. FromMidnight time.Duration // Set to true if Offset is specified. If false, then the timezone is // unspecified (and by ISO8601 - implies some "local" time). HasOffset bool // Offset is non-zero only if time.tz is used. It is otherwise ignored. If // non-zero, then it is regarded as a UTC offset in seconds. Note that the // sub-minutes is ignored by the marshal function. Offset int } // MarshalTimeOfDay marshals TimeOfDay to the "time" type. func MarshalTimeOfDay(v TimeOfDay) (string, error) { d := int64(v.FromMidnight / time.Second) hour := d / 3600 d = d % 3600 minute := d / 60 second := d % 60 return fmt.Sprintf("%02d:%02d:%02d", hour, minute, second), nil } // UnmarshalTimeOfDay unmarshals TimeOfDay from the "time" type. func UnmarshalTimeOfDay(s string) (TimeOfDay, error) { t, err := UnmarshalTimeOfDayTz(s) if err != nil { return TimeOfDay{}, err } else if t.HasOffset { return TimeOfDay{}, fmt.Errorf("soap time: value %q contains unexpected timezone") } return t, nil } // MarshalTimeOfDayTz marshals TimeOfDay to the "time.tz" type. func MarshalTimeOfDayTz(v TimeOfDay) (string, error) { d := int64(v.FromMidnight / time.Second) hour := d / 3600 d = d % 3600 minute := d / 60 second := d % 60 tz := "" if v.HasOffset { if v.Offset == 0 { tz = "Z" } else { offsetMins := v.Offset / 60 sign := '+' if offsetMins < 1 { offsetMins = -offsetMins sign = '-' } tz = fmt.Sprintf("%c%02d:%02d", sign, offsetMins/60, offsetMins%60) } } return fmt.Sprintf("%02d:%02d:%02d%s", hour, minute, second, tz), nil } // UnmarshalTimeOfDayTz unmarshals TimeOfDay from the "time.tz" type. func UnmarshalTimeOfDayTz(s string) (tod TimeOfDay, err error) { zoneIndex := strings.IndexAny(s, "Z+-") var timePart string var hasOffset bool var offset int if zoneIndex == -1 { hasOffset = false timePart = s } else { hasOffset = true timePart = s[:zoneIndex] if offset, err = parseTimezone(s[zoneIndex:]); err != nil { return } } hour, minute, second, err := parseTimeParts(timePart) if err != nil { return } fromMidnight := time.Duration(hour*3600+minute*60+second) * time.Second // ISO8601 special case - values up to 24:00:00 are allowed, so using // strictly greater-than for the maximum value. if fromMidnight > 24*time.Hour || minute >= 60 || second >= 60 { return TimeOfDay{}, fmt.Errorf("soap time.tz: value %q has value(s) out of range", s) } return TimeOfDay{ FromMidnight: time.Duration(hour*3600+minute*60+second) * time.Second, HasOffset: hasOffset, Offset: offset, }, nil } // MarshalDateTime marshals time.Time to SOAP "dateTime" type. Note that this // converts to local time. func MarshalDateTime(v time.Time) (string, error) { return v.In(localLoc).Format("2006-01-02T15:04:05"), nil } // UnmarshalDateTime unmarshals time.Time from the SOAP "dateTime" type. This // returns a value in the local timezone. func UnmarshalDateTime(s string) (result time.Time, err error) { dateStr, timeStr, zoneStr, err := splitCompleteDateTimeZone(s) if err != nil { return } if len(zoneStr) != 0 { err = fmt.Errorf("soap datetime: unexpected timezone in %q", s) return } year, month, day, err := parseDateParts(dateStr) if err != nil { return } var hour, minute, second int if len(timeStr) != 0 { hour, minute, second, err = parseTimeParts(timeStr) if err != nil { return } } result = time.Date(year, time.Month(month), day, hour, minute, second, 0, localLoc) return } // MarshalDateTimeTz marshals time.Time to SOAP "dateTime.tz" type. func MarshalDateTimeTz(v time.Time) (string, error) { return v.Format("2006-01-02T15:04:05-07:00"), nil } // UnmarshalDateTimeTz unmarshals time.Time from the SOAP "dateTime.tz" type. // This returns a value in the local timezone when the timezone is unspecified. func UnmarshalDateTimeTz(s string) (result time.Time, err error) { dateStr, timeStr, zoneStr, err := splitCompleteDateTimeZone(s) if err != nil { return } year, month, day, err := parseDateParts(dateStr) if err != nil { return } var hour, minute, second int var location *time.Location = localLoc if len(timeStr) != 0 { hour, minute, second, err = parseTimeParts(timeStr) if err != nil { return } if len(zoneStr) != 0 { var offset int offset, err = parseTimezone(zoneStr) if offset == 0 { location = time.UTC } else { location = time.FixedZone("", offset) } } } result = time.Date(year, time.Month(month), day, hour, minute, second, 0, location) return } // MarshalBoolean marshals bool to SOAP "boolean" type. func MarshalBoolean(v bool) (string, error) { if v { return "1", nil } return "0", nil } // UnmarshalBoolean unmarshals bool from the SOAP "boolean" type. func UnmarshalBoolean(s string) (bool, error) { switch s { case "0", "false", "no": return false, nil case "1", "true", "yes": return true, nil } return false, fmt.Errorf("soap boolean: %q is not a valid boolean value", s) } // MarshalBinBase64 marshals []byte to SOAP "bin.base64" type. func MarshalBinBase64(v []byte) (string, error) { return base64.StdEncoding.EncodeToString(v), nil } // UnmarshalBinBase64 unmarshals []byte from the SOAP "bin.base64" type. func UnmarshalBinBase64(s string) ([]byte, error) { return base64.StdEncoding.DecodeString(s) } // MarshalBinHex marshals []byte to SOAP "bin.hex" type. func MarshalBinHex(v []byte) (string, error) { return hex.EncodeToString(v), nil } // UnmarshalBinHex unmarshals []byte from the SOAP "bin.hex" type. func UnmarshalBinHex(s string) ([]byte, error) { return hex.DecodeString(s) } // MarshalURI marshals *url.URL to SOAP "uri" type. func MarshalURI(v *url.URL) (string, error) { return v.String(), nil } // UnmarshalURI unmarshals *url.URL from the SOAP "uri" type. func UnmarshalURI(s string) (*url.URL, error) { return url.Parse(s) } go-upnp-master/goupnp/ssdp/0000755000175000017500000000000013165312311014635 5ustar freefreego-upnp-master/goupnp/ssdp/registry.go0000644000175000017500000001607613165312311017046 0ustar freefreepackage ssdp import ( "fmt" "net/http" "net/url" "regexp" "strconv" "sync" "time" "github.com/NebulousLabs/go-upnp/goupnp/httpu" ) const ( maxExpiryTimeSeconds = 24 * 60 * 60 ) var ( maxAgeRx = regexp.MustCompile("max-age=([0-9]+)") ) const ( EventAlive = EventType(iota) EventUpdate EventByeBye ) type EventType int8 func (et EventType) String() string { switch et { case EventAlive: return "EventAlive" case EventUpdate: return "EventUpdate" case EventByeBye: return "EventByeBye" default: return fmt.Sprintf("EventUnknown(%d)", int8(et)) } } type Update struct { // The USN of the service. USN string // What happened. EventType EventType // The entry, which is nil if the service was not known and // EventType==EventByeBye. The contents of this must not be modified as it is // shared with the registry and other listeners. Once created, the Registry // does not modify the Entry value - any updates are replaced with a new // Entry value. Entry *Entry } type Entry struct { // The address that the entry data was actually received from. RemoteAddr string // Unique Service Name. Identifies a unique instance of a device or service. USN string // Notfication Type. The type of device or service being announced. NT string // Server's self-identifying string. Server string Host string // Location of the UPnP root device description. Location url.URL // Despite BOOTID,CONFIGID being required fields, apparently they are not // always set by devices. Set to -1 if not present. BootID int32 ConfigID int32 SearchPort uint16 // When the last update was received for this entry identified by this USN. LastUpdate time.Time // When the last update's cached values are advised to expire. CacheExpiry time.Time } func newEntryFromRequest(r *http.Request) (*Entry, error) { now := time.Now() expiryDuration, err := parseCacheControlMaxAge(r.Header.Get("CACHE-CONTROL")) if err != nil { return nil, fmt.Errorf("ssdp: error parsing CACHE-CONTROL max age: %v", err) } loc, err := url.Parse(r.Header.Get("LOCATION")) if err != nil { return nil, fmt.Errorf("ssdp: error parsing entry Location URL: %v", err) } bootID, err := parseUpnpIntHeader(r.Header, "BOOTID.UPNP.ORG", -1) if err != nil { return nil, err } configID, err := parseUpnpIntHeader(r.Header, "CONFIGID.UPNP.ORG", -1) if err != nil { return nil, err } searchPort, err := parseUpnpIntHeader(r.Header, "SEARCHPORT.UPNP.ORG", ssdpSearchPort) if err != nil { return nil, err } if searchPort < 1 || searchPort > 65535 { return nil, fmt.Errorf("ssdp: search port %d is out of range", searchPort) } return &Entry{ RemoteAddr: r.RemoteAddr, USN: r.Header.Get("USN"), NT: r.Header.Get("NT"), Server: r.Header.Get("SERVER"), Host: r.Header.Get("HOST"), Location: *loc, BootID: bootID, ConfigID: configID, SearchPort: uint16(searchPort), LastUpdate: now, CacheExpiry: now.Add(expiryDuration), }, nil } func parseCacheControlMaxAge(cc string) (time.Duration, error) { matches := maxAgeRx.FindStringSubmatch(cc) if len(matches) != 2 { return 0, fmt.Errorf("did not find exactly one max-age in cache control header: %q", cc) } expirySeconds, err := strconv.ParseInt(matches[1], 10, 16) if err != nil { return 0, err } if expirySeconds < 1 || expirySeconds > maxExpiryTimeSeconds { return 0, fmt.Errorf("rejecting bad expiry time of %d seconds", expirySeconds) } return time.Duration(expirySeconds) * time.Second, nil } // parseUpnpIntHeader is intended to parse the // {BOOT,CONFIGID,SEARCHPORT}.UPNP.ORG header fields. It returns the def if // the head is empty or missing. func parseUpnpIntHeader(headers http.Header, headerName string, def int32) (int32, error) { s := headers.Get(headerName) if s == "" { return def, nil } v, err := strconv.ParseInt(s, 10, 32) if err != nil { return 0, fmt.Errorf("ssdp: could not parse header %s: %v", headerName, err) } return int32(v), nil } var _ httpu.Handler = new(Registry) // Registry maintains knowledge of discovered devices and services. // // NOTE: the interface for this is experimental and may change, or go away // entirely. type Registry struct { lock sync.Mutex byUSN map[string]*Entry listenersLock sync.RWMutex listeners map[chan<- Update]struct{} } func NewRegistry() *Registry { return &Registry{ byUSN: make(map[string]*Entry), listeners: make(map[chan<- Update]struct{}), } } // NewServerAndRegistry is a convenience function to create a registry, and an // httpu server to pass it messages. Call ListenAndServe on the server for // messages to be processed. func NewServerAndRegistry() (*httpu.Server, *Registry) { reg := NewRegistry() srv := &httpu.Server{ Addr: ssdpUDP4Addr, Multicast: true, Handler: reg, } return srv, reg } func (reg *Registry) AddListener(c chan<- Update) { reg.listenersLock.Lock() defer reg.listenersLock.Unlock() reg.listeners[c] = struct{}{} } func (reg *Registry) RemoveListener(c chan<- Update) { reg.listenersLock.Lock() defer reg.listenersLock.Unlock() delete(reg.listeners, c) } func (reg *Registry) sendUpdate(u Update) { reg.listenersLock.RLock() defer reg.listenersLock.RUnlock() for c := range reg.listeners { c <- u } } // GetService returns known service (or device) entries for the given service // URN. func (reg *Registry) GetService(serviceURN string) []*Entry { // Currently assumes that the map is small, so we do a linear search rather // than indexed to avoid maintaining two maps. var results []*Entry reg.lock.Lock() defer reg.lock.Unlock() for _, entry := range reg.byUSN { if entry.NT == serviceURN { results = append(results, entry) } } return results } // ServeMessage implements httpu.Handler, and uses SSDP NOTIFY requests to // maintain the registry of devices and services. func (reg *Registry) ServeMessage(r *http.Request) { if r.Method != methodNotify { return } nts := r.Header.Get("nts") switch nts { case ntsAlive: reg.handleNTSAlive(r) case ntsUpdate: reg.handleNTSUpdate(r) case ntsByebye: reg.handleNTSByebye(r) } } func (reg *Registry) handleNTSAlive(r *http.Request) error { entry, err := newEntryFromRequest(r) if err != nil { return err } reg.lock.Lock() reg.byUSN[entry.USN] = entry reg.lock.Unlock() reg.sendUpdate(Update{ USN: entry.USN, EventType: EventAlive, Entry: entry, }) return nil } func (reg *Registry) handleNTSUpdate(r *http.Request) error { entry, err := newEntryFromRequest(r) if err != nil { return err } nextBootID, err := parseUpnpIntHeader(r.Header, "NEXTBOOTID.UPNP.ORG", -1) if err != nil { return err } entry.BootID = nextBootID reg.lock.Lock() reg.byUSN[entry.USN] = entry reg.lock.Unlock() reg.sendUpdate(Update{ USN: entry.USN, EventType: EventUpdate, Entry: entry, }) return nil } func (reg *Registry) handleNTSByebye(r *http.Request) error { usn := r.Header.Get("USN") reg.lock.Lock() entry := reg.byUSN[usn] delete(reg.byUSN, usn) reg.lock.Unlock() reg.sendUpdate(Update{ USN: usn, EventType: EventByeBye, Entry: entry, }) return nil } go-upnp-master/goupnp/ssdp/ssdp.go0000644000175000017500000000503513165312311016140 0ustar freefreepackage ssdp import ( "context" "errors" "net/http" "net/url" "strconv" "time" "github.com/NebulousLabs/go-upnp/goupnp/httpu" ) const ( ssdpDiscover = `"ssdp:discover"` ntsAlive = `ssdp:alive` ntsByebye = `ssdp:byebye` ntsUpdate = `ssdp:update` ssdpUDP4Addr = "239.255.255.250:1900" ssdpSearchPort = 1900 methodSearch = "M-SEARCH" methodNotify = "NOTIFY" ) // SSDPRawSearch is deprecated; use SSDPRawSearchCtx instead func SSDPRawSearch(httpu *httpu.HTTPUClient, searchTarget string, maxWaitSeconds int, numSends int) ([]*http.Response, error) { return SSDPRawSearchCtx(context.Background(), httpu, searchTarget, maxWaitSeconds, numSends) } // SSDPRawSearch 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 SSDPRawSearchCtx(ctx context.Context, httpu *httpu.HTTPUClient, searchTarget string, maxWaitSeconds int, numSends int) ([]*http.Response, error) { if maxWaitSeconds < 1 { return nil, errors.New("ssdp: maxWaitSeconds must be >= 1") } seenUsns := make(map[string]bool) var responses []*http.Response req := (&http.Request{ Method: methodSearch, // TODO: Support both IPv4 and IPv6. Host: ssdpUDP4Addr, URL: &url.URL{Opaque: "*"}, Header: http.Header{ // Putting headers in here avoids them being title-cased. // (The UPnP discovery protocol uses case-sensitive headers) "HOST": []string{ssdpUDP4Addr}, "MX": []string{strconv.FormatInt(int64(maxWaitSeconds), 10)}, "MAN": []string{ssdpDiscover}, "ST": []string{searchTarget}, }, }).WithContext(ctx) allResponses, err := httpu.Do(req, time.Duration(maxWaitSeconds)*time.Second+100*time.Millisecond, numSends) if err != nil { return nil, err } for _, response := range allResponses { if response.StatusCode != 200 { continue } if st := response.Header.Get("ST"); st != searchTarget { continue } location, err := response.Location() if err != nil { continue } usn := response.Header.Get("USN") if usn == "" { usn = location.String() } if _, alreadySeen := seenUsns[usn]; !alreadySeen { seenUsns[usn] = true responses = append(responses, response) } } return responses, nil } go-upnp-master/upnp.go0000644000175000017500000001307113165312311013667 0ustar freefree// Package upnp provides a simple and opinionated interface to UPnP-enabled // routers, allowing users to forward ports and discover their external IP // address. Specific quirks: // // - When attempting to discover UPnP-enabled routers on the network, only the // first such router is returned. If you have multiple routers, this may cause // some trouble. But why would you do that? // // - Forwarded ports are always symmetric, e.g. the router's port 9980 will be // mapped to the client's port 9980. This will be unacceptable for some // purposes, but too bad. Symmetric mappings are the desired behavior 99% of // the time, and they save a function argument. // // - TCP and UDP protocols are forwarded together. // // - Ports are forwarded permanently. Some other implementations lease a port // mapping for a set duration, and then renew it periodically. This is nice, // because it means mappings won't stick around after they've served their // purpose. Unfortunately, some routers only support permanent mappings, so this // package has chosen to support the lowest common denominator. To un-forward a // port, you must use the Clear function (or do it manually). // // Once you've discovered your router, you can retrieve its address by calling // its Location method. This address can be supplied to Load to connect to the // router directly, which is much faster than calling Discover. package upnp import ( "context" "errors" "net" "net/url" "time" "github.com/NebulousLabs/fastrand" "github.com/NebulousLabs/go-upnp/goupnp" "github.com/NebulousLabs/go-upnp/goupnp/dcps/internetgateway1" ) // An IGD provides an interface to the most commonly used functions of an // Internet Gateway Device: discovering the external IP, and forwarding ports. type IGD struct { // This interface is satisfied by the internetgateway1.WANIPConnection1 // and internetgateway1.WANPPPConnection1 types. client interface { GetExternalIPAddress() (string, error) AddPortMapping(string, uint16, string, uint16, string, bool, string, uint32) error DeletePortMapping(string, uint16, string) error GetServiceClient() *goupnp.ServiceClient } } // ExternalIP returns the router's external IP. func (d *IGD) ExternalIP() (string, error) { return d.client.GetExternalIPAddress() } // Forward forwards the specified port, and adds its description to the // router's port mapping table. func (d *IGD) Forward(port uint16, desc string) error { ip, err := d.getInternalIP() if err != nil { return err } err = d.client.AddPortMapping("", port, "TCP", port, ip, true, desc, 0) if err != nil { return err } return d.client.AddPortMapping("", port, "UDP", port, ip, true, desc, 0) } // Clear un-forwards a port, removing it from the router's port mapping table. func (d *IGD) Clear(port uint16) error { tcpErr := d.client.DeletePortMapping("", port, "TCP") udpErr := d.client.DeletePortMapping("", port, "UDP") // only return an error if both deletions failed if tcpErr != nil && udpErr != nil { return tcpErr } return nil } // Location returns the URL of the router, for future lookups (see Load). func (d *IGD) Location() string { return d.client.GetServiceClient().Location.String() } // getInternalIP returns the user's local IP. func (d *IGD) getInternalIP() (string, error) { host, _, _ := net.SplitHostPort(d.client.GetServiceClient().RootDevice.URLBase.Host) devIP := net.ParseIP(host) if devIP == nil { return "", errors.New("could not determine router's internal IP") } ifaces, err := net.Interfaces() if err != nil { return "", err } for _, iface := range ifaces { addrs, err := iface.Addrs() if err != nil { return "", err } for _, addr := range addrs { if x, ok := addr.(*net.IPNet); ok && x.Contains(devIP) { return x.IP.String(), nil } } } return "", errors.New("could not determine internal IP") } // Discover is deprecated; use DiscoverCtx instead. func Discover() (*IGD, error) { return DiscoverCtx(context.Background()) } // DiscoverCtx scans the local network for routers and returns the first // UPnP-enabled router it encounters. It will try up to 3 times to find a // router, sleeping a random duration between each attempt. This is to // mitigate a race condition with many callers attempting to discover // simultaneously. func DiscoverCtx(ctx context.Context) (*IGD, error) { // TODO: if more than one client is found, only return those on the same // subnet as the user? maxTries := 3 sleepTime := time.Millisecond * time.Duration(fastrand.Intn(5000)) for try := 0; try < maxTries; try++ { pppclients, _, _ := internetgateway1.NewWANPPPConnection1Clients(ctx) if len(pppclients) > 0 { return &IGD{pppclients[0]}, nil } ipclients, _, _ := internetgateway1.NewWANIPConnection1Clients(ctx) if len(ipclients) > 0 { return &IGD{ipclients[0]}, nil } select { case <-ctx.Done(): return nil, context.Canceled case <-time.After(sleepTime): } sleepTime *= 2 } return nil, errors.New("no UPnP-enabled gateway found") } // Load connects to the router service specified by rawurl. This is much // faster than Discover. Generally, Load should only be called with values // returned by the IGD's Location method. func Load(rawurl string) (*IGD, error) { loc, err := url.Parse(rawurl) if err != nil { return nil, err } pppclients, _ := internetgateway1.NewWANPPPConnection1ClientsByURL(loc) if len(pppclients) > 0 { return &IGD{pppclients[0]}, nil } ipclients, _ := internetgateway1.NewWANIPConnection1ClientsByURL(loc) if len(ipclients) > 0 { return &IGD{ipclients[0]}, nil } return nil, errors.New("no UPnP-enabled gateway found at URL " + rawurl) } go-upnp-master/upnp_test.go0000644000175000017500000000262413165312311014730 0ustar freefreepackage upnp import ( "context" "sync" "testing" "time" ) // TestConcurrentUPNP tests that several threads calling Discover() concurrently // succeed. func TestConcurrentUPNP(t *testing.T) { if testing.Short() { t.SkipNow() } // verify that a router exists ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) defer cancel() _, err := DiscoverCtx(ctx) if err != nil { t.Skip(err) } // now try to concurrently Discover() using 20 threads var wg sync.WaitGroup for i := 0; i < 20; i++ { wg.Add(1) go func() { defer wg.Done() ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) defer cancel() _, err := DiscoverCtx(ctx) if err != nil { t.Error(err) } }() } wg.Wait() } func TestIGD(t *testing.T) { // connect to router ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) defer cancel() d, err := DiscoverCtx(ctx) if err != nil { t.Skip(err) } // discover external IP ip, err := d.ExternalIP() if err != nil { t.Fatal(err) } t.Log("Your external IP is:", ip) // forward a port err = d.Forward(9001, "upnp test") if err != nil { t.Fatal(err) } // un-forward a port err = d.Clear(9001) if err != nil { t.Fatal(err) } // record router's location loc := d.Location() if err != nil { t.Fatal(err) } // connect to router directly d, err = Load(loc) if err != nil { t.Fatal(err) } }