Ver Fonte

fix(device-locating): got help receiving udp packets from roku devices

Thanks to stevet goRoku now can process the responces from roku devices, which can now in turn be properly displayed and used to select a different IP to control that roku device.

closes #1
Apollo há 3 anos atrás
pai
commit
5b4ee973ae
3 ficheiros alterados com 101 adições e 13 exclusões
  1. 24 8
      poster.go
  2. 61 0
      roku1.go
  3. 16 5
      webserver.go

+ 24 - 8
poster.go

@@ -4,10 +4,8 @@ import (
 	"fmt"
 	"io"
 	"log"
-	"net"
 	"net/http"
-	"os"
-	"time"
+	"strings"
 
 	"github.com/beanzilla/glom"
 	"github.com/beego/x2j"
@@ -52,6 +50,7 @@ func Post(where string) *http.Response {
 	}
 }*/
 
+/*
 func PostFind() {
 	file, err := os.ReadFile("finder.txt")
 	if err != nil {
@@ -100,6 +99,7 @@ func GetFind(data *[]string) {
 	}
 	*data = list
 }
+*/
 
 func Get(where string) *http.Response {
 	resp, err := http.Get(where)
@@ -189,12 +189,28 @@ func GetDeviceInfo(ip string) map[string]interface{} {
 	return dev
 }
 
-func GetDevices() *[]string {
+func GetDevices(wake_on_lan map[string]string) (*[]string, map[string]string) {
 	var str []string
-	go GetFind(&str)
-	go PostFind()
-	//fmt.Print(str)
-	return &str
+	resp := strings.Split(PostFind(), "\n")
+	//fmt.Printf("Processing %d lines\n", len(resp))
+	ip := ""
+	for _, line := range resp {
+		if strings.Contains(line, "LOCATION") {
+			st := strings.ReplaceAll(line, "LOCATION: http://", "")
+			st = strings.ReplaceAll(st, ":8060/", "")
+			st = strings.ReplaceAll(st, "\r", "")
+			//fmt.Printf("IP='%s'", st)
+			str = append(str, st)
+			ip = st
+		} else if strings.Contains(line, "WAKEUP") {
+			st := strings.ReplaceAll(line, "WAKEUP: MAC=", "")
+			st = strings.ReplaceAll(st, ";Timeout=10", "")
+			st = strings.ReplaceAll(st, "\r", "")
+			//fmt.Printf("IP='%s' MAC='%s'", ip, st)
+			wake_on_lan[ip] = st
+		}
+	}
+	return &str, wake_on_lan
 }
 
 func DebugInfo(ip string) string {

+ 61 - 0
roku1.go

@@ -0,0 +1,61 @@
+package main
+
+import (
+	"fmt"
+	"log"
+	"net"
+	"os"
+	"time"
+)
+
+func PostFind() string {
+	file, err := os.ReadFile("finder.txt")
+	if err != nil {
+		log.Print(err)
+	}
+	addr, err := net.ResolveUDPAddr("udp", "239.255.255.250:1900")
+	if err != nil {
+		log.Print(err)
+	}
+	laddr, err := net.ResolveUDPAddr("udp", ":0") // "192.168.254.13:9000")
+	if err != nil {
+		log.Print(err)
+	}
+	// "192.168.254.13:9000")
+
+	// conn, err := net.DialUDP("udp", laddr, addr)
+	/*
+		ListenUDP -- to SEND?  WAT?
+		https://github.com/golang/go/issues/13391
+		Ok, maybe you don't want to read it -- the developers are cranky when
+		asked why Listen would be able to SEND.
+	*/
+	conn, err := net.ListenUDP("udp", laddr)
+	if err != nil {
+		log.Print(err)
+	}
+	defer conn.Close()
+
+	conn.WriteTo(file, addr)
+	// conn.Write(file)
+	log.Println("Posted Request for devices")
+
+	// future: Handle multiple devices
+	conn.SetReadDeadline(time.Now().Add(time.Second * time.Duration(5)))
+	buffer := make([]byte, 512)
+	n, fromaddr, err := conn.ReadFrom(buffer) //  Read(buffer)
+	fmt.Printf("%d, %#v, %#v\n", n, fromaddr, err)
+
+	var output string = string(buffer[0:n])
+	//fmt.Printf("GOT: [%s]\n", output)
+	// log.Printf("Read: %#v\n", buffer)
+	return output
+}
+
+/*
+func main() {
+	fmt.Println("Start:")
+	PostFind()
+	fmt.Println("Done!")
+}
+*/

+ 16 - 5
webserver.go

@@ -15,6 +15,7 @@ type WebServer struct {
 	Host        string
 	At          string
 	Device_list []string
+	WakeOnLan   map[string]string
 	Power       bool
 }
 
@@ -22,6 +23,7 @@ func (w *WebServer) Init(tv, host, port string) {
 	w.Tv_ip = tv
 	w.Host = host
 	w.Port = port
+	w.WakeOnLan = make(map[string]string)
 }
 
 func (w *WebServer) homepage(c echo.Context) error {
@@ -57,11 +59,20 @@ func (w *WebServer) connector(c echo.Context) error {
 
 func (w *WebServer) con_refresh(c echo.Context) error {
 	log.Printf("Recieved Connection Refresh")
-	var list *[]string = GetDevices()
-	//w.Device_list = append(w.Device_list, *list...)
-	w.Device_list = *list
-	log.Printf("Found %d devices", len(w.Device_list))
-	return c.Redirect(http.StatusOK, "/connect")
+	var list *[]string
+	list, w.WakeOnLan = GetDevices(w.WakeOnLan)
+	log.Printf("Found %d devices", len(*list))
+	log.Printf("Obtained %d WOLs", len(w.WakeOnLan))
+	for ip, mac := range w.WakeOnLan {
+		fmt.Printf("IP='%v' MAC='%v'\n", ip, mac)
+	}
+	for _, ip := range *list {
+		if ip != w.Tv_ip {
+			w.Device_list = append(w.Device_list, ip)
+		}
+	}
+	//w.Device_list = *list
+	return c.Redirect(http.StatusTemporaryRedirect, "/connect")
 }
 
 func (w *WebServer) tvcmd(c echo.Context) error {