123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173 |
- package remdeshid
- import (
- "fmt"
- "log"
- "time"
- "github.com/tarm/serial"
- )
- func NewHIDController(config *Config) *Controller {
- // Initialize the HID state with default values
- defaultHidState := HIDState{
- Modkey: 0x00,
- KeyboardButtons: [6]uint8{0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- Leds: 0x00,
- MouseButtons: 0x00, // No mouse buttons pressed
- MouseX: 0,
- MouseY: 0,
- }
- return &Controller{
- Config: config,
- serialRunning: false,
- hidState: defaultHidState,
- writeQueue: make(chan []byte, 32),
- incomgDataQueue: make(chan []byte, 1024),
- }
- }
- // Connect opens the serial port and starts reading from it
- func (c *Controller) Connect() error {
- // Open the serial port
- config := &serial.Config{
- Name: c.Config.PortName,
- Baud: c.Config.BaudRate,
- Size: 8,
- Parity: serial.ParityNone,
- }
- port, err := serial.OpenPort(config)
- if err != nil {
- return err
- }
- c.serialPort = port
- //Start reading from the serial port
- go func() {
- buf := make([]byte, 1024)
- for {
- n, err := port.Read(buf)
- if err != nil {
- log.Println(err.Error())
- return
- }
- if n > 0 {
- c.incomgDataQueue <- buf[:n]
- //fmt.Print("Received bytes: ")
- //for i := 0; i < n; i++ {
- // fmt.Printf("0x%02X ", buf[i])
- //}
- fmt.Println()
- }
- }
- }()
- //Create a loop to write to the serial port
- c.serialRunning = true
- go func() {
- for {
- data := <-c.writeQueue
- _, err := port.Write(data)
- if err != nil {
- log.Println(err.Error())
- return
- }
- }
- }()
- //Send over an opr queue reset signal
- err = c.Send([]byte{0xFF})
- if err != nil {
- return err
- }
- return nil
- }
- func (c *Controller) Send(data []byte) error {
- if !c.serialRunning {
- return fmt.Errorf("serial port is not running")
- }
- select {
- case c.writeQueue <- data:
- return nil
- case <-time.After(30 * time.Millisecond):
- return fmt.Errorf("timeout waiting to send data")
- }
- }
- func (c *Controller) ClearReadQueue() {
- // Clear the incoming data queue
- for len(c.incomgDataQueue) > 0 {
- <-c.incomgDataQueue
- }
- }
- func (c *Controller) WaitForReply(cmdByte byte) ([]byte, error) {
- // Wait for a reply from the device
- succReplyByte := cmdByte | 0x80
- errorReplyByte := cmdByte | 0xC0
- timeout := make(chan bool, 1)
- go func() {
- // Timeout after 500ms
- time.Sleep(500 * time.Millisecond)
- timeout <- true
- }()
- var reply []byte
- for {
- select {
- case data := <-c.incomgDataQueue:
- reply = append(reply, data...)
- // Check if we have received enough bytes for a complete packet
- if len(reply) >= 7 {
- // Validate header
- if reply[0] == 0x57 && reply[1] == 0xAB {
- // Extract fields
- //address := reply[2]
- replyByte := reply[3]
- dataLength := reply[4]
- expectedLength := 5 + int(dataLength) + 1 // Header + address + replyByte + dataLength + data + checksum
- // Check if the full packet is received
- if len(reply) >= expectedLength {
- data := reply[5 : 5+dataLength]
- checksum := reply[5+dataLength]
- // Calculate checksum
- sum := byte(0)
- for _, b := range reply[:5+dataLength] {
- sum += b
- }
- // Validate checksum
- if sum == checksum {
- // Check reply byte for success or error
- switch replyByte {
- case succReplyByte:
- return data, nil
- case errorReplyByte:
- return nil, fmt.Errorf("device returned error reply")
- }
- } else {
- return nil, fmt.Errorf("checksum validation failed")
- }
- }
- } else {
- // Invalid header, discard data
- reply = nil
- }
- }
- case <-timeout:
- return nil, fmt.Errorf("timeout waiting for reply")
- }
- }
- }
- func (c *Controller) Close() {
- if c.serialPort != nil {
- c.serialPort.Close()
- }
- }
|