package main import ( "fmt" "os" tea "github.com/charmbracelet/bubbletea" "github.com/gorilla/websocket" "golang.org/x/term" "google.golang.org/protobuf/proto" "odroid-tui/pb" ) func startRawTerminal(m *model) tea.Cmd { return func() tea.Msg { fd := int(os.Stdin.Fd()) oldState, err := term.MakeRaw(fd) if err != nil { return err } defer term.Restore(fd, oldState) fmt.Print("\033[2J\033[H") fmt.Printf("\r\n\033[32m--- Terminal Connected (Ctrl+A to exit) ---\033[0m\r\n") u := fmt.Sprintf("ws://%s/ws?token=%s", m.connDetails.IP, m.connDetails.Token) ws, _, err := websocket.DefaultDialer.Dial(u, nil) if err != nil { return err } defer ws.Close() done := make(chan struct{}) sendChan := make(chan []byte, 256) go func() { for d := range sendChan { ws.WriteMessage(websocket.BinaryMessage, d) } }() go func() { for { _, msg, err := ws.ReadMessage() if err != nil { close(done) return } var st pb.StatusMessage if proto.Unmarshal(msg, &st) == nil { if u := st.GetUartData(); u != nil { os.Stdout.Write(u.GetData()) } } else { os.Stdout.Write(msg) } } }() buf := make([]byte, 1024) for { n, err := os.Stdin.Read(buf) if err != nil { close(sendChan) return TerminalFinishedMsg{} } if n > 0 { for i := 0; i < n; i++ { if buf[i] == 1 { ws.Close() return TerminalFinishedMsg{} } } d := make([]byte, n) copy(d, buf[:n]) sendChan <- d } select { case <-done: close(sendChan) return TerminalFinishedMsg{} default: } } } }