service_client.go 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. package goupnp
  2. import (
  3. "fmt"
  4. "net/url"
  5. "github.com/huin/goupnp/soap"
  6. )
  7. // ServiceClient is a SOAP client, root device and the service for the SOAP
  8. // client rolled into one value. The root device, location, and service are
  9. // intended to be informational. Location can be used to later recreate a
  10. // ServiceClient with NewServiceClientByURL if the service is still present;
  11. // bypassing the discovery process.
  12. type ServiceClient struct {
  13. SOAPClient *soap.SOAPClient
  14. RootDevice *RootDevice
  15. Location *url.URL
  16. Service *Service
  17. }
  18. // NewServiceClients discovers services, and returns clients for them. err will
  19. // report any error with the discovery process (blocking any device/service
  20. // discovery), errors reports errors on a per-root-device basis.
  21. func NewServiceClients(searchTarget string) (clients []ServiceClient, errors []error, err error) {
  22. var maybeRootDevices []MaybeRootDevice
  23. if maybeRootDevices, err = DiscoverDevices(searchTarget); err != nil {
  24. return
  25. }
  26. clients = make([]ServiceClient, 0, len(maybeRootDevices))
  27. for _, maybeRootDevice := range maybeRootDevices {
  28. if maybeRootDevice.Err != nil {
  29. errors = append(errors, maybeRootDevice.Err)
  30. continue
  31. }
  32. deviceClients, err := NewServiceClientsFromRootDevice(maybeRootDevice.Root, maybeRootDevice.Location, searchTarget)
  33. if err != nil {
  34. errors = append(errors, err)
  35. continue
  36. }
  37. clients = append(clients, deviceClients...)
  38. }
  39. return
  40. }
  41. // NewServiceClientsByURL creates client(s) for the given service URN, for a
  42. // root device at the given URL.
  43. func NewServiceClientsByURL(loc *url.URL, searchTarget string) ([]ServiceClient, error) {
  44. rootDevice, err := DeviceByURL(loc)
  45. if err != nil {
  46. return nil, err
  47. }
  48. return NewServiceClientsFromRootDevice(rootDevice, loc, searchTarget)
  49. }
  50. // NewServiceClientsFromDevice creates client(s) for the given service URN, in
  51. // a given root device. The loc parameter is simply assigned to the
  52. // Location attribute of the returned ServiceClient(s).
  53. func NewServiceClientsFromRootDevice(rootDevice *RootDevice, loc *url.URL, searchTarget string) ([]ServiceClient, error) {
  54. device := &rootDevice.Device
  55. srvs := device.FindService(searchTarget)
  56. if len(srvs) == 0 {
  57. return nil, fmt.Errorf("goupnp: service %q not found within device %q (UDN=%q)",
  58. searchTarget, device.FriendlyName, device.UDN)
  59. }
  60. clients := make([]ServiceClient, 0, len(srvs))
  61. for _, srv := range srvs {
  62. clients = append(clients, ServiceClient{
  63. SOAPClient: srv.NewSOAPClient(),
  64. RootDevice: rootDevice,
  65. Location: loc,
  66. Service: srv,
  67. })
  68. }
  69. return clients, nil
  70. }
  71. // GetServiceClient returns the ServiceClient itself. This is provided so that the
  72. // service client attributes can be accessed via an interface method on a
  73. // wrapping type.
  74. func (client *ServiceClient) GetServiceClient() *ServiceClient {
  75. return client
  76. }