Browse Source

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 3 years ago
parent
commit
5b4ee973ae
3 changed files with 101 additions and 13 deletions
  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"
 	"fmt"
 	"io"
 	"io"
 	"log"
 	"log"
-	"net"
 	"net/http"
 	"net/http"
-	"os"
-	"time"
+	"strings"
 
 
 	"github.com/beanzilla/glom"
 	"github.com/beanzilla/glom"
 	"github.com/beego/x2j"
 	"github.com/beego/x2j"
@@ -52,6 +50,7 @@ func Post(where string) *http.Response {
 	}
 	}
 }*/
 }*/
 
 
+/*
 func PostFind() {
 func PostFind() {
 	file, err := os.ReadFile("finder.txt")
 	file, err := os.ReadFile("finder.txt")
 	if err != nil {
 	if err != nil {
@@ -100,6 +99,7 @@ func GetFind(data *[]string) {
 	}
 	}
 	*data = list
 	*data = list
 }
 }
+*/
 
 
 func Get(where string) *http.Response {
 func Get(where string) *http.Response {
 	resp, err := http.Get(where)
 	resp, err := http.Get(where)
@@ -189,12 +189,28 @@ func GetDeviceInfo(ip string) map[string]interface{} {
 	return dev
 	return dev
 }
 }
 
 
-func GetDevices() *[]string {
+func GetDevices(wake_on_lan map[string]string) (*[]string, map[string]string) {
 	var str []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 {
 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
 	Host        string
 	At          string
 	At          string
 	Device_list []string
 	Device_list []string
+	WakeOnLan   map[string]string
 	Power       bool
 	Power       bool
 }
 }
 
 
@@ -22,6 +23,7 @@ func (w *WebServer) Init(tv, host, port string) {
 	w.Tv_ip = tv
 	w.Tv_ip = tv
 	w.Host = host
 	w.Host = host
 	w.Port = port
 	w.Port = port
+	w.WakeOnLan = make(map[string]string)
 }
 }
 
 
 func (w *WebServer) homepage(c echo.Context) error {
 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 {
 func (w *WebServer) con_refresh(c echo.Context) error {
 	log.Printf("Recieved Connection Refresh")
 	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 {
 func (w *WebServer) tvcmd(c echo.Context) error {