package main import ( "fmt" "log" "strings" "time" "fyne.io/fyne/v2" "fyne.io/fyne/v2/app" "fyne.io/fyne/v2/container" "fyne.io/fyne/v2/dialog" "fyne.io/fyne/v2/widget" "go.bug.st/serial" "go.bug.st/serial/enumerator" ) type Packet struct { Id string Type string Data string } var serialPort serial.Port var isAuthenticated bool = false var application = app.New() var window = application.NewWindow("Securitas") var authBtn = widget.NewButton("Authenticate", func() { go sendPacket("fingerprint", "auth", "-") }) var loadPasswordsBtn = widget.NewButton("Load Passwords", func() { go sendPacket("passwords", "available", "-") }) var addPasswordBtn = widget.NewButton("Add password", func() { nameEntry := widget.NewEntry() passwordEntry := widget.NewEntry() var items = []*widget.FormItem{ {Text: "Name", Widget: nameEntry}, {Text: "Password", Widget: passwordEntry}, } go dialog.ShowForm("New Password", "Create", "Cancel", items, func(status bool) { if !status { return } sendPacket("new_password", nameEntry.Text, passwordEntry.Text) time.Sleep(time.Millisecond * 750) newPasswordsArray := append(passwordSelector.Options, nameEntry.Text) newPasswords := strings.Join(newPasswordsArray[:], "-") sendPacket("passwords", "new_available", newPasswords) time.Sleep(time.Millisecond * 750) go sendPacket("passwords", "available", "-") }, window) }) var enrollBtn = widget.NewButton("Enroll", func() { go sendPacket("fingerprint", "enroll", "1") }) var passwordSelector = widget.NewSelect([]string{}, func(value string) { log.Println("Select set to", value) }) var getPasswordBtn = widget.NewButton("Get", func() { go sendPacket("passwords", "load", passwordSelector.Selected) }) func main() { window.Resize(fyne.NewSize(600, 400)) window.CenterOnScreen() window.SetFixedSize(true) titleText := widget.NewLabel("Password manager") titleText.TextStyle.Bold = true txtResults := widget.NewTextGrid() txtResults.ShowLineNumbers = true loadPasswordsBtn.Disable() addPasswordBtn.Disable() enrollBtn.Disable() cntButtons := container.NewGridWithColumns(4, authBtn, loadPasswordsBtn, addPasswordBtn, enrollBtn) cntSelection := container.NewGridWithColumns(2, passwordSelector, getPasswordBtn) cntContent := container.NewGridWithRows(3, titleText, cntSelection, cntButtons) window.SetContent(cntContent) go handleSerial() window.ShowAndRun() } func handleSerial() { ports, err := enumerator.GetDetailedPortsList() if err != nil { log.Fatal(err) } if len(ports) == 0 { fmt.Println("No serial ports found!") return } for _, port := range ports { fmt.Printf("Found port: %s\n", port.Name) if port.IsUSB { fmt.Printf(" USB ID %s:%s\n", port.VID, port.PID) fmt.Printf(" USB serial %s\n", port.SerialNumber) } } fmt.Println("") for { var device string = "/dev/ttyUSB0" fmt.Println("Trying to connect to: ", device) mode := &serial.Mode{ BaudRate: 9600, } port, err := serial.Open(device, mode) if err != nil { log.Fatal(err) time.Sleep(time.Second * 2) } serialPort = port fmt.Println("Connected to: ", device) fmt.Println("") reading := false for { data := "" buffer := make([]byte, 512) for { n, err := port.Read(buffer) if err != nil { fmt.Printf("Error occured: %v", err.Error()) time.Sleep(time.Second * 2) break } if n == 0 { fmt.Println("\nEOF") break } if strings.Contains(string(buffer[:n]), "!***!") { reading = true data = "" buffer = make([]byte, 1024) } if !reading { break } data += string(buffer[:n]) if strings.Contains(string(buffer[:n]), "\n") { fmt.Printf("%#v\n", data) break } } if !reading { continue } data = strings.ReplaceAll(data, "\x00", "") data = strings.ReplaceAll(data, "\xb4", "") data = strings.ReplaceAll(data, "\xc3", "") data = strings.ReplaceAll(data, "\r\n", "") pieces := strings.Split(data, "\xc4") var packet Packet packet.Id = pieces[0] packet.Type = pieces[1] packet.Data = pieces[2] go handlePacket(&packet) // fmt.Printf("%#v\n", data) } // var newPacket Packet // err = json.Unmarshal([]byte(`{\"id\":\"fingerprint_init\",\"type\":""\"found\",\"data\":\"true\",\"overflow\""":false}`), &newPacket) // if err != nil { // fmt.Println(err) // } } } func sendPacket(pId string, pType string, pData string) { n, err := serialPort.Write([]byte("\xb4" + pId + "\xc4" + pType + "\xc4" + pData + "\xc3\r\n")) if err != nil { log.Fatal(err) } fmt.Println("-------- Send Packet --------") fmt.Println("ID: ", pId) fmt.Println("Type: ", pType) fmt.Println("Data: ", pData) fmt.Printf("Send %v bytes\n", n) } func handlePacket(packet *Packet) { fmt.Println("-------- New Packet --------") fmt.Printf("ID: %#v\n", packet.Id) fmt.Printf("Type: %#v\n", packet.Type) fmt.Printf("Data: %#v\n", packet.Data) if packet.Id == "fingerprint" { if packet.Type == "enroll_status" { } if packet.Type == "auth_status" { if packet.Data == "valid" { isAuthenticated = true authBtn.Disable() loadPasswordsBtn.Enable() addPasswordBtn.Enable() enrollBtn.Enable() } else { isAuthenticated = false } } } if packet.Id == "passwords" { if packet.Type == "available_passwords" { if len(packet.Data) >= 1 { passwordSelector.Options = strings.Split(packet.Data, "-") } else { var empty [0]string passwordSelector.Options = empty[:] } loadPasswordsBtn.Disable() } if packet.Type == "password" { dialog.ShowInformation("Password", "Password: "+packet.Data, window) } } }