main.go 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. package main
  2. import (
  3. "embed"
  4. "flag"
  5. "io/fs"
  6. "log"
  7. "net/http"
  8. "os"
  9. "os/signal"
  10. "syscall"
  11. "time"
  12. "imuslab.com/remdeskvm/remdeskd/mod/remdesaux"
  13. "imuslab.com/remdeskvm/remdeskd/mod/remdeshid"
  14. "imuslab.com/remdeskvm/remdeskd/mod/usbcapture"
  15. )
  16. const defaultDevMode = true
  17. var (
  18. developent = flag.Bool("dev", defaultDevMode, "Enable development mode with local static files")
  19. mode = flag.String("mode", "usbkvm", "Mode of operation: kvm or capture")
  20. usbKVMDeviceName = flag.String("usbhid", "/dev/ttyUSB0", "USB KVM device file path")
  21. usbAuxilaryDeviceName = flag.String("auxmcu", "/dev/ttyACM0", "USB Auxiliary MCU device file path")
  22. usbKVMBaudRate = flag.Int("baudrate", 115200, "USB KVM baud rate")
  23. usbAuxBaudRate = flag.Int("auxbaudrate", 115200, "USB Auxiliary MCU baud rate")
  24. captureDeviceName = flag.String("capture", "/dev/video0", "Video capture device file path")
  25. /* Internal Modules */
  26. usbKVM *remdeshid.Controller
  27. auxMCU *remdesaux.AuxMcu
  28. videoCapture *usbcapture.Instance
  29. )
  30. /* Web Server Static Files */
  31. //go:embed www
  32. var embeddedFiles embed.FS
  33. var webfs http.FileSystem
  34. func init() {
  35. // Initiate the web server static files
  36. if *developent {
  37. webfs = http.Dir("./www")
  38. } else {
  39. // Embed the ./www folder and trim the prefix
  40. subFS, err := fs.Sub(embeddedFiles, "www")
  41. if err != nil {
  42. log.Fatal(err)
  43. }
  44. webfs = http.FS(subFS)
  45. }
  46. }
  47. func main() {
  48. flag.Parse()
  49. // Initiate the HID controller
  50. usbKVM = remdeshid.NewHIDController(&remdeshid.Config{
  51. PortName: *usbKVMDeviceName,
  52. BaudRate: *usbKVMBaudRate,
  53. ScrollSensitivity: 0x01, // Set mouse scroll sensitivity
  54. })
  55. switch *mode {
  56. case "cfgchip":
  57. //Start the HID controller
  58. err := usbKVM.Connect()
  59. if err != nil {
  60. log.Fatal(err)
  61. }
  62. time.Sleep(1 * time.Second) // Wait for the controller to initialize
  63. log.Println("Updating chip baudrate to 115200...")
  64. //Configure the HID controller
  65. err = usbKVM.ConfigureChipTo115200()
  66. if err != nil {
  67. log.Fatalf("Failed to configure chip baudrate: %v", err)
  68. return
  69. }
  70. time.Sleep(1 * time.Second)
  71. log.Println("Setting chip USB device properties...")
  72. time.Sleep(2 * time.Second) // Wait for the controller to initialize
  73. _, err = usbKVM.WriteChipProperties()
  74. if err != nil {
  75. log.Fatalf("Failed to write chip properties: %v", err)
  76. return
  77. }
  78. log.Println("Configuration command sent. Unplug the device and plug it back in to apply the changes.")
  79. case "usbkvm":
  80. log.Println("Starting in USB KVM mode...")
  81. //Start the HID controller
  82. err := usbKVM.Connect()
  83. if err != nil {
  84. log.Fatal(err)
  85. }
  86. //Start auxiliary MCU connections
  87. auxMCU, err = remdesaux.NewAuxOutbandController(*usbAuxilaryDeviceName, *usbAuxBaudRate)
  88. if err != nil {
  89. log.Fatal(err)
  90. }
  91. //Try get the UUID from the auxiliary MCU
  92. uuid, err := auxMCU.GetUUID()
  93. if err != nil {
  94. log.Println("Get UUID failed:", err)
  95. } else {
  96. log.Println("Auxiliary MCU UUID:", uuid)
  97. }
  98. // Initiate the video capture device
  99. videoCapture, err = usbcapture.NewInstance(&usbcapture.Config{
  100. DeviceName: *captureDeviceName,
  101. AudioConfig: usbcapture.GetDefaultAudioConfig(),
  102. })
  103. if err != nil {
  104. log.Fatalf("Failed to create video capture instance: %v", err)
  105. }
  106. //Get device information for debug
  107. usbcapture.PrintV4L2FormatInfo(*captureDeviceName)
  108. //Start the video capture device
  109. err = videoCapture.StartVideoCapture(&usbcapture.CaptureResolution{
  110. Width: 1920,
  111. Height: 1080,
  112. FPS: 10,
  113. })
  114. if err != nil {
  115. log.Fatal(err)
  116. }
  117. // Handle program exit to close the HID controller
  118. c := make(chan os.Signal, 1)
  119. signal.Notify(c, os.Interrupt, syscall.SIGTERM)
  120. go func() {
  121. <-c
  122. log.Println("Shutting down usbKVM...")
  123. if usbKVM != nil {
  124. //usbKVM.Close()
  125. }
  126. if auxMCU != nil {
  127. auxMCU.Close()
  128. }
  129. log.Println("Shutting down capture device...")
  130. if videoCapture != nil {
  131. videoCapture.Close()
  132. }
  133. os.Exit(0)
  134. }()
  135. // Start the web server
  136. http.Handle("/", http.FileServer(webfs))
  137. http.HandleFunc("/hid", usbKVM.HIDWebSocketHandler)
  138. http.HandleFunc("/audio", videoCapture.AudioStreamingHandler)
  139. http.HandleFunc("/stream", videoCapture.ServeVideoStream)
  140. http.HandleFunc("/aux/switchusbkvm", auxMCU.HandleSwitchUSBToKVM)
  141. http.HandleFunc("/aux/switchusbremote", auxMCU.HandleSwitchUSBToRemote)
  142. http.HandleFunc("/aux/presspower", auxMCU.HandlePressPowerButton)
  143. http.HandleFunc("/aux/releasepower", auxMCU.HandleReleasePowerButton)
  144. http.HandleFunc("/aux/pressreset", auxMCU.HandlePressResetButton)
  145. http.HandleFunc("/aux/releasereset", auxMCU.HandleReleaseResetButton)
  146. http.HandleFunc("/aux/getuuid", auxMCU.HandleGetUUID)
  147. addr := ":9000"
  148. log.Printf("Serving on http://localhost%s\n", addr)
  149. log.Fatal(http.ListenAndServe(addr, nil))
  150. case "list-audio-devices":
  151. log.Println("Starting in List Audio Devices mode...")
  152. //Get the audio devices
  153. path, err := usbcapture.FindHDMICapturePCMPath()
  154. if err != nil {
  155. log.Fatalf("Failed to find HDMI capture PCM path: %v", err)
  156. }
  157. log.Printf("Found HDMI capture PCM path: %s\n", path)
  158. //List all audio capture devices
  159. captureDevs, err := usbcapture.ListCaptureDevices()
  160. if err != nil {
  161. log.Fatalf("Failed to list capture devices: %v", err)
  162. }
  163. log.Println("Available audio capture devices:")
  164. for _, dev := range captureDevs {
  165. log.Printf(" - %s\n", dev)
  166. }
  167. default:
  168. log.Fatalf("Unknown mode: %s. Supported modes are: usbkvm, capture", *mode)
  169. }
  170. }