Skip to content

Commit

Permalink
all: add ApplicationOption's and a way to get cast dns by name
Browse files Browse the repository at this point in the history
Added ApplicationOption's which can be used to configure the
application.

Changed to use a variable for 'connectionRetries' instead of the
hardcoded 5. Can also be configured with the ApplicationOption.

New method in 'dns' to quickly and easily get a cast dns entry by name.
  • Loading branch information
vishen committed May 10, 2020
1 parent 3d6aea8 commit ba871fd
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 18 deletions.
65 changes: 50 additions & 15 deletions application/application.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,25 +90,56 @@ type Application struct {
playedItems map[string]PlayedItem
cacheDisabled bool
cache *storage.Storage

// Number of connection retries to try before returning
// and error.
connectionRetries int
}

type ApplicationOption func(*Application)

func WithIface(iface *net.Interface) ApplicationOption {
return func(a *Application) {
a.iface = iface
}
}

func NewApplication(iface *net.Interface, debug, cacheDisabled bool) *Application {
// TODO(vishen): make cast.Connection an interface, most likely will just need
// the Send method
// Channel to receive messages from the cast connecttion. 5 is a randomly
// chosen number.
func WithDebug(debug bool) ApplicationOption {
return func(a *Application) {
a.debug = debug
a.conn.SetDebug(debug)
}
}

func WithCacheDisabled(cacheDisabled bool) ApplicationOption {
return func(a *Application) {
a.cacheDisabled = cacheDisabled
}
}

func WithConnectionRetries(connectionRetries int) ApplicationOption {
return func(a *Application) {
a.connectionRetries = connectionRetries
}
}

func NewApplication(opts ...ApplicationOption) *Application {
recvMsgChan := make(chan *pb.CastMessage, 5)
a := &Application{
recvMsgChan: recvMsgChan,
resultChanMap: map[int]chan *pb.CastMessage{},
messageChan: make(chan *pb.CastMessage),
conn: cast.NewConnection(recvMsgChan, debug),
debug: debug,
cacheDisabled: cacheDisabled,
playedItems: map[string]PlayedItem{},
cache: storage.NewStorage(),
iface: iface,
recvMsgChan: recvMsgChan,
resultChanMap: map[int]chan *pb.CastMessage{},
messageChan: make(chan *pb.CastMessage),
conn: cast.NewConnection(recvMsgChan),
playedItems: map[string]PlayedItem{},
cache: storage.NewStorage(),
connectionRetries: 5,
}

// Apply options
for _, o := range opts {
o(a)
}

// Kick off the listener for asynchronous messages received from the
// cast connection.
go a.recvMessages()
Expand All @@ -119,6 +150,7 @@ func NewApplication(iface *net.Interface, debug, cacheDisabled bool) *Applicatio

func (a *Application) Application() *cast.Application { return a.application }
func (a *Application) Media() *cast.Media { return a.media }
func (a *Application) Volume() *cast.Volume { return a.volumeReceiver }

func (a *Application) AddMessageFunc(f CastMessageFunc) {
a.messageMu.Lock()
Expand Down Expand Up @@ -236,7 +268,10 @@ func (a *Application) Update() error {
var err error
// Simple retry. We need this for when the device isn't currently
// available, but it is likely that it will come up soon.
for i := 0; i < 5; i++ {
// TODO: This seems to happen when changing media on the cast device,
// not sure how to fix but there might be some way of knowing from the
// payload?
for i := 0; i < a.connectionRetries; i++ {
recvStatus, err = a.getReceiverStatus()
if err == nil {
break
Expand Down
3 changes: 1 addition & 2 deletions cast/connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,9 @@ type Connection struct {
connected bool
}

func NewConnection(recvMsgChan chan *pb.CastMessage, debug bool) *Connection {
func NewConnection(recvMsgChan chan *pb.CastMessage) *Connection {
c := &Connection{
recvMsgChan: recvMsgChan,
debug: debug,
connected: false,
}
return c
Expand Down
8 changes: 7 additions & 1 deletion cmd/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@ func castApplication(cmd *cobra.Command, args []string) (*application.Applicatio
dnsTimeoutSeconds, _ := cmd.Flags().GetInt("dns-timeout")
useFirstDevice, _ := cmd.Flags().GetBool("first")

applicationOptions := []application.ApplicationOption{
application.WithDebug(debug),
application.WithCacheDisabled(disableCache),
}

// If we need to look on a specific network interface for mdns or
// for finding a network ip to host from, ensure that the network
// interface exists.
Expand All @@ -74,6 +79,7 @@ func castApplication(cmd *cobra.Command, args []string) (*application.Applicatio
if iface, err = net.InterfaceByName(ifaceName); err != nil {
return nil, errors.Wrap(err, fmt.Sprintf("unable to find interface %q", ifaceName))
}
applicationOptions = append(applicationOptions, application.WithIface(iface))
}

var entry castdns.CastDNSEntry
Expand Down Expand Up @@ -116,7 +122,7 @@ func castApplication(cmd *cobra.Command, args []string) (*application.Applicatio
Port: p,
}
}
app := application.NewApplication(iface, debug, disableCache)
app := application.NewApplication(applicationOptions...)
if err := app.Start(entry); err != nil {
// NOTE: currently we delete the dns cache every time we get
// an error, this is to make sure that if the device gets a new
Expand Down
16 changes: 16 additions & 0 deletions dns/dns.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,22 @@ func (e CastEntry) GetPort() int {
return e.Port
}

// DiscoverCastDNSEntryByName returns the first cast dns device
// found that matches the name.
func DiscoverCastDNSEntryByName(ctx context.Context, iface *net.Interface, name string) (CastEntry, error) {
castEntryChan, err := DiscoverCastDNSEntries(ctx, iface)
if err != nil {
return CastEntry{}, err
}

for d := range castEntryChan {
if d.DeviceName == name {
return d, nil
}
}
return CastEntry{}, fmt.Errorf("No cast device found with name %q", name)
}

// DiscoverCastDNSEntries will return a channel with any cast dns entries
// found.
func DiscoverCastDNSEntries(ctx context.Context, iface *net.Interface) (<-chan CastEntry, error) {
Expand Down

0 comments on commit ba871fd

Please sign in to comment.