Skip to content

Commit ba871fd

Browse files
committed
all: add ApplicationOption's and a way to get cast dns by name
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.
1 parent 3d6aea8 commit ba871fd

File tree

4 files changed

+74
-18
lines changed

4 files changed

+74
-18
lines changed

application/application.go

Lines changed: 50 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -90,25 +90,56 @@ type Application struct {
9090
playedItems map[string]PlayedItem
9191
cacheDisabled bool
9292
cache *storage.Storage
93+
94+
// Number of connection retries to try before returning
95+
// and error.
96+
connectionRetries int
97+
}
98+
99+
type ApplicationOption func(*Application)
100+
101+
func WithIface(iface *net.Interface) ApplicationOption {
102+
return func(a *Application) {
103+
a.iface = iface
104+
}
93105
}
94106

95-
func NewApplication(iface *net.Interface, debug, cacheDisabled bool) *Application {
96-
// TODO(vishen): make cast.Connection an interface, most likely will just need
97-
// the Send method
98-
// Channel to receive messages from the cast connecttion. 5 is a randomly
99-
// chosen number.
107+
func WithDebug(debug bool) ApplicationOption {
108+
return func(a *Application) {
109+
a.debug = debug
110+
a.conn.SetDebug(debug)
111+
}
112+
}
113+
114+
func WithCacheDisabled(cacheDisabled bool) ApplicationOption {
115+
return func(a *Application) {
116+
a.cacheDisabled = cacheDisabled
117+
}
118+
}
119+
120+
func WithConnectionRetries(connectionRetries int) ApplicationOption {
121+
return func(a *Application) {
122+
a.connectionRetries = connectionRetries
123+
}
124+
}
125+
126+
func NewApplication(opts ...ApplicationOption) *Application {
100127
recvMsgChan := make(chan *pb.CastMessage, 5)
101128
a := &Application{
102-
recvMsgChan: recvMsgChan,
103-
resultChanMap: map[int]chan *pb.CastMessage{},
104-
messageChan: make(chan *pb.CastMessage),
105-
conn: cast.NewConnection(recvMsgChan, debug),
106-
debug: debug,
107-
cacheDisabled: cacheDisabled,
108-
playedItems: map[string]PlayedItem{},
109-
cache: storage.NewStorage(),
110-
iface: iface,
129+
recvMsgChan: recvMsgChan,
130+
resultChanMap: map[int]chan *pb.CastMessage{},
131+
messageChan: make(chan *pb.CastMessage),
132+
conn: cast.NewConnection(recvMsgChan),
133+
playedItems: map[string]PlayedItem{},
134+
cache: storage.NewStorage(),
135+
connectionRetries: 5,
136+
}
137+
138+
// Apply options
139+
for _, o := range opts {
140+
o(a)
111141
}
142+
112143
// Kick off the listener for asynchronous messages received from the
113144
// cast connection.
114145
go a.recvMessages()
@@ -119,6 +150,7 @@ func NewApplication(iface *net.Interface, debug, cacheDisabled bool) *Applicatio
119150

120151
func (a *Application) Application() *cast.Application { return a.application }
121152
func (a *Application) Media() *cast.Media { return a.media }
153+
func (a *Application) Volume() *cast.Volume { return a.volumeReceiver }
122154

123155
func (a *Application) AddMessageFunc(f CastMessageFunc) {
124156
a.messageMu.Lock()
@@ -236,7 +268,10 @@ func (a *Application) Update() error {
236268
var err error
237269
// Simple retry. We need this for when the device isn't currently
238270
// available, but it is likely that it will come up soon.
239-
for i := 0; i < 5; i++ {
271+
// TODO: This seems to happen when changing media on the cast device,
272+
// not sure how to fix but there might be some way of knowing from the
273+
// payload?
274+
for i := 0; i < a.connectionRetries; i++ {
240275
recvStatus, err = a.getReceiverStatus()
241276
if err == nil {
242277
break

cast/connection.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,9 @@ type Connection struct {
3232
connected bool
3333
}
3434

35-
func NewConnection(recvMsgChan chan *pb.CastMessage, debug bool) *Connection {
35+
func NewConnection(recvMsgChan chan *pb.CastMessage) *Connection {
3636
c := &Connection{
3737
recvMsgChan: recvMsgChan,
38-
debug: debug,
3938
connected: false,
4039
}
4140
return c

cmd/utils.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,11 @@ func castApplication(cmd *cobra.Command, args []string) (*application.Applicatio
6565
dnsTimeoutSeconds, _ := cmd.Flags().GetInt("dns-timeout")
6666
useFirstDevice, _ := cmd.Flags().GetBool("first")
6767

68+
applicationOptions := []application.ApplicationOption{
69+
application.WithDebug(debug),
70+
application.WithCacheDisabled(disableCache),
71+
}
72+
6873
// If we need to look on a specific network interface for mdns or
6974
// for finding a network ip to host from, ensure that the network
7075
// interface exists.
@@ -74,6 +79,7 @@ func castApplication(cmd *cobra.Command, args []string) (*application.Applicatio
7479
if iface, err = net.InterfaceByName(ifaceName); err != nil {
7580
return nil, errors.Wrap(err, fmt.Sprintf("unable to find interface %q", ifaceName))
7681
}
82+
applicationOptions = append(applicationOptions, application.WithIface(iface))
7783
}
7884

7985
var entry castdns.CastDNSEntry
@@ -116,7 +122,7 @@ func castApplication(cmd *cobra.Command, args []string) (*application.Applicatio
116122
Port: p,
117123
}
118124
}
119-
app := application.NewApplication(iface, debug, disableCache)
125+
app := application.NewApplication(applicationOptions...)
120126
if err := app.Start(entry); err != nil {
121127
// NOTE: currently we delete the dns cache every time we get
122128
// an error, this is to make sure that if the device gets a new

dns/dns.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,22 @@ func (e CastEntry) GetPort() int {
5454
return e.Port
5555
}
5656

57+
// DiscoverCastDNSEntryByName returns the first cast dns device
58+
// found that matches the name.
59+
func DiscoverCastDNSEntryByName(ctx context.Context, iface *net.Interface, name string) (CastEntry, error) {
60+
castEntryChan, err := DiscoverCastDNSEntries(ctx, iface)
61+
if err != nil {
62+
return CastEntry{}, err
63+
}
64+
65+
for d := range castEntryChan {
66+
if d.DeviceName == name {
67+
return d, nil
68+
}
69+
}
70+
return CastEntry{}, fmt.Errorf("No cast device found with name %q", name)
71+
}
72+
5773
// DiscoverCastDNSEntries will return a channel with any cast dns entries
5874
// found.
5975
func DiscoverCastDNSEntries(ctx context.Context, iface *net.Interface) (<-chan CastEntry, error) {

0 commit comments

Comments
 (0)