2022-01-28 17:02:50 +01:00

105 lines
2.9 KiB
Go

package ssdp
/* ***** BEGIN GPL LICENSE BLOCK *****
*
* Original Code Copyright (C) 2022 Blender Foundation.
*
* This file is part of Flamenco.
*
* Flamenco is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* Flamenco is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* Flamenco. If not, see <https://www.gnu.org/licenses/>.
*
* ***** END GPL LICENSE BLOCK ***** */
import (
"net/url"
"github.com/rs/zerolog/log"
"gitlab.com/blender-institute/gossdp"
)
// Finder is a uses UPnP/SSDP to find a Flamenco Manager on the local network.
type Finder struct {
overrideURL *url.URL
}
type ssdpClient struct {
response chan interface{}
}
// NewManagerFinder returns a default SSDP/UPnP based finder.
func NewManagerFinder(managerURL *url.URL) Finder {
return Finder{
overrideURL: managerURL,
}
}
func (b *ssdpClient) NotifyAlive(message gossdp.AliveMessage) {
log.Info().Interface("message", message).Msg("UPnP/SSDP NotifyAlive")
}
func (b *ssdpClient) NotifyBye(message gossdp.ByeMessage) {
log.Info().Interface("message", message).Msg("UPnP/SSDP NotifyBye")
}
func (b *ssdpClient) Response(message gossdp.ResponseMessage) {
log.Debug().Interface("message", message).Msg("UPnP/SSDP response")
url, err := url.Parse(message.Location)
if err != nil {
b.response <- err
return
}
b.response <- url
}
// FindFlamencoManager tries to find a Manager, sending its URL to the returned channel.
func (f Finder) FindFlamencoManager() <-chan *url.URL {
reporter := make(chan *url.URL)
go func() {
defer close(reporter)
if f.overrideURL != nil {
log.Debug().Str("url", f.overrideURL.String()).Msg("Using configured Flamenco Manager URL")
reporter <- f.overrideURL
return
}
log.Info().Msg("finding Flamenco Manager via UPnP/SSDP")
b := ssdpClient{make(chan interface{})}
client, err := gossdp.NewSsdpClientWithLogger(&b, ZeroLogWrapper{})
if err != nil {
log.Fatal().Err(err).Msg("Unable to create UPnP/SSDP client")
return
}
log.Debug().Msg("Starting UPnP/SSDP client")
go client.Start()
defer client.Stop()
if err := client.ListenFor("urn:flamenco:manager:0"); err != nil {
log.Error().Err(err).Msg("unable to find Manager")
return
}
log.Debug().Msg("Waiting for UPnP/SSDP answer")
urlOrErr := <-b.response
switch v := urlOrErr.(type) {
case *url.URL:
reporter <- v
case error:
log.Fatal().Err(v).Msg("Error waiting for UPnP/SSDP response from Manager")
}
}()
return reporter
}