Skip to content

Commit

Permalink
scanner: provide device name (#183)
Browse files Browse the repository at this point in the history
* scan: discover name

* application: remove unused code
  • Loading branch information
holiman authored Mar 19, 2024
1 parent f255229 commit 5494422
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 52 deletions.
10 changes: 0 additions & 10 deletions application/application.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import (
pb "github.com/vishen/go-chromecast/cast/proto"
"github.com/vishen/go-chromecast/playlists"
"github.com/vishen/go-chromecast/storage"
"gopkg.in/ini.v1"
"path/filepath"
)

Expand Down Expand Up @@ -1427,12 +1426,3 @@ func (a *Application) Transcode(contentType string, command string, args ...stri
a.MediaWait()
return nil
}

// plsIterator is an iterator for playlist-files.
// According to https://en.wikipedia.org/wiki/PLS_(file_format),
// The format is case-sensitive and essentially that of an INI file.
// It has entries on the form File1, Title1 etc.
type plsIterator struct {
count int
playlist *ini.Section
}
33 changes: 0 additions & 33 deletions application/application_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,12 @@ import (
"encoding/json"
"testing"

"fmt"
"path/filepath"

"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
"github.com/vishen/go-chromecast/application"
"github.com/vishen/go-chromecast/cast"
mockCast "github.com/vishen/go-chromecast/cast/mocks"
pb "github.com/vishen/go-chromecast/cast/proto"
"github.com/vishen/go-chromecast/playlists"
)

var mockAddr = "foo.bar"
Expand Down Expand Up @@ -46,32 +42,3 @@ func TestApplicationStart(t *testing.T) {
app := application.NewApplication(application.WithConnection(conn))
assertions.NoError(app.Start(mockAddr, mockPort))
}

func TestParsePlaylist(t *testing.T) {
var path string
if abs, err := filepath.Abs(filepath.Join("..", "testdata", "indiepop64.pls")); err != nil {
t.Fatal(err)
} else {
path = fmt.Sprintf("file://%v", abs)
}
it, err := playlists.NewIterator(path)
if err != nil {
t.Fatal(err)
}
var wantUrls = []string{
"https://ice4.somafm.com/indiepop-64-aac",
"https://ice2.somafm.com/indiepop-64-aac",
"https://ice1.somafm.com/indiepop-64-aac",
"https://ice6.somafm.com/indiepop-64-aac",
"https://ice5.somafm.com/indiepop-64-aac",
}
for i, want := range wantUrls {
if !it.HasNext() {
t.Fatal("iterator exhausted")
}
have, _ := it.Next()
if have != want {
t.Fatalf("url %d, have %v want %v", i, have, want)
}
}
}
52 changes: 43 additions & 9 deletions cmd/scan.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,38 @@ import (
"sync"
"time"

"encoding/json"
"github.com/seancfoley/ipaddress-go/ipaddr"
"github.com/spf13/cobra"
"io"
"net/http"
)

type deviceInfo struct {
Name string
}

// getInfo uses the http://<ip>:8008/setup/eureka_endpoint to obtain more
// information about the cast-device.
// OBS: The 8008 seems to be pure http, whereas 8009 is typically the port
// to use for protobuf-communication
func getInfo(ip *ipaddr.IPAddress) (info *deviceInfo, err error) {
resp, err := http.Get(fmt.Sprintf("http://%v:8008/setup/eureka_info", ip))
if err != nil {
return nil, err
}
defer resp.Body.Close()
data, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}
info = new(deviceInfo)
if err := json.Unmarshal(data, info); err != nil {
return nil, err
}
return info, nil
}

// scanCmd triggers a scan
var scanCmd = &cobra.Command{
Use: "scan",
Expand All @@ -33,7 +61,7 @@ var scanCmd = &cobra.Command{
cidrAddr, _ = cmd.Flags().GetString("cidr")
port, _ = cmd.Flags().GetInt("port")
wg sync.WaitGroup
uriCh = make(chan string)
ipCh = make(chan *ipaddr.IPAddress)
logged = time.Unix(0, 0)
start = time.Now()
count int
Expand All @@ -46,15 +74,15 @@ var scanCmd = &cobra.Command{
go func() {
it := ipRange.Iterator()
for it.HasNext() {
uri := fmt.Sprintf("%s:%d", it.Next(), port)
ip := it.Next()
if time.Since(logged) > 8*time.Second {
outputInfo("Scanning... scanned %d, current %v\n", count, uri)
outputInfo("Scanning... scanned %d, current %v\n", count, ip.String())
logged = time.Now()
}
uriCh <- uri
ipCh <- ip
count++
}
close(uriCh)
close(ipCh)
}()
// Use a bunch of goroutines to do connect-attempts.
for i := 0; i < 64; i++ {
Expand All @@ -64,10 +92,16 @@ var scanCmd = &cobra.Command{
dialer := &net.Dialer{
Timeout: 400 * time.Millisecond,
}
for uri := range uriCh {
if conn, err := dialer.Dial("tcp", uri); err == nil {
conn.Close()
outputInfo("Found (potential) chromecast at %v\n", uri)
for ip := range ipCh {
conn, err := dialer.Dial("tcp", fmt.Sprintf("%v:%d", ip, port))
if err != nil {
continue
}
conn.Close()
if info, err := getInfo(ip); err != nil {
outputInfo(" - Device at %v:%d errored during discovery: %v", ip, port, err)
} else {
outputInfo(" - '%v' at %v:%d\n", info.Name, ip, port)
}
}
}()
Expand Down

0 comments on commit 5494422

Please sign in to comment.