|
@@ -1,6 +1,16 @@
|
|
|
package main
|
|
|
|
|
|
+/*
|
|
|
+ usbkvm.go
|
|
|
+
|
|
|
+ Handles the USB KVM device connections and auxiliary devices
|
|
|
+ running in USB KVM mode. This mode only support 1 USB KVM device
|
|
|
+ at a time.
|
|
|
+
|
|
|
+ For running multiple USB KVM devices, use the ipkvm mode.
|
|
|
+*/
|
|
|
import (
|
|
|
+ "encoding/json"
|
|
|
"log"
|
|
|
"net/http"
|
|
|
"os"
|
|
@@ -8,27 +18,101 @@ import (
|
|
|
"syscall"
|
|
|
|
|
|
"imuslab.com/remdeskvm/remdeskd/mod/remdesaux"
|
|
|
+ "imuslab.com/remdeskvm/remdeskd/mod/remdeshid"
|
|
|
"imuslab.com/remdeskvm/remdeskd/mod/usbcapture"
|
|
|
)
|
|
|
|
|
|
-func startUsbKvmMode() error {
|
|
|
+type UsbKvmConfig struct {
|
|
|
+ ListeningAddress string
|
|
|
+ USBKVMDevicePath string
|
|
|
+ AuxMCUDevicePath string
|
|
|
+ VideoCaptureDevicePath string
|
|
|
+ AudioCaptureDevicePath string
|
|
|
+ CaptureResolutionWidth int
|
|
|
+ CaptureResolutionHeight int
|
|
|
+ CaptureResolutionFPS int
|
|
|
+ USBKVMBaudrate int
|
|
|
+ AuxMCUBaudrate int
|
|
|
+}
|
|
|
+
|
|
|
+var (
|
|
|
+ /* Internal variables for USB-KVM mode only */
|
|
|
+ usbKVM *remdeshid.Controller
|
|
|
+ auxMCU *remdesaux.AuxMcu
|
|
|
+ videoCapture *usbcapture.Instance
|
|
|
+ defaultUsbKvmConfig = &UsbKvmConfig{
|
|
|
+ ListeningAddress: ":9000",
|
|
|
+ USBKVMDevicePath: "/dev/ttyUSB0",
|
|
|
+ AuxMCUDevicePath: "/dev/ttyACM0",
|
|
|
+ VideoCaptureDevicePath: "/dev/video0",
|
|
|
+ AudioCaptureDevicePath: "/dev/snd/pcmC1D0c",
|
|
|
+ CaptureResolutionWidth: 1920,
|
|
|
+ CaptureResolutionHeight: 1080,
|
|
|
+ CaptureResolutionFPS: 25,
|
|
|
+ USBKVMBaudrate: 115200,
|
|
|
+ AuxMCUBaudrate: 115200,
|
|
|
+ }
|
|
|
+)
|
|
|
+
|
|
|
+func loadUsbKvmConfig() (*UsbKvmConfig, error) {
|
|
|
+ if _, err := os.Stat(usbKvmConfigPath); os.IsNotExist(err) {
|
|
|
+ file, err := os.OpenFile(usbKvmConfigPath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0755)
|
|
|
+ if err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+
|
|
|
+ // Save default config as JSON
|
|
|
+ enc := json.NewEncoder(file)
|
|
|
+ enc.SetIndent("", " ")
|
|
|
+ if err := enc.Encode(defaultUsbKvmConfig); err != nil {
|
|
|
+ file.Close()
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ file.Close()
|
|
|
+ return defaultUsbKvmConfig, nil
|
|
|
+ }
|
|
|
+
|
|
|
+ // Load config from file
|
|
|
+ file, err := os.Open(usbKvmConfigPath)
|
|
|
+ if err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+
|
|
|
+ cfg := &UsbKvmConfig{}
|
|
|
+ dec := json.NewDecoder(file)
|
|
|
+ if err := dec.Decode(cfg); err != nil {
|
|
|
+ file.Close()
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ file.Close()
|
|
|
+ return cfg, nil
|
|
|
+}
|
|
|
+
|
|
|
+func startUsbKvmMode(config *UsbKvmConfig) error {
|
|
|
log.Println("Starting in USB KVM mode...")
|
|
|
+ // Initiate the HID controller
|
|
|
+ usbKVM = remdeshid.NewHIDController(&remdeshid.Config{
|
|
|
+ PortName: config.USBKVMDevicePath,
|
|
|
+ BaudRate: config.USBKVMBaudrate,
|
|
|
+ ScrollSensitivity: 0x01, // Set mouse scroll sensitivity
|
|
|
+ })
|
|
|
+
|
|
|
//Start the HID controller
|
|
|
err := usbKVM.Connect()
|
|
|
if err != nil {
|
|
|
- log.Fatal(err)
|
|
|
+ return err
|
|
|
}
|
|
|
|
|
|
//Start auxiliary MCU connections
|
|
|
- auxMCU, err = remdesaux.NewAuxOutbandController(*usbAuxilaryDeviceName, *usbAuxBaudRate)
|
|
|
+ auxMCU, err = remdesaux.NewAuxOutbandController(config.AuxMCUDevicePath, config.AuxMCUBaudrate)
|
|
|
if err != nil {
|
|
|
- log.Fatal(err)
|
|
|
+ return err
|
|
|
}
|
|
|
|
|
|
//Try get the UUID from the auxiliary MCU
|
|
|
uuid, err := auxMCU.GetUUID()
|
|
|
if err != nil {
|
|
|
- log.Println("Get UUID failed:", err)
|
|
|
+ log.Println("Get UUID failed:", err, " - Auxiliary MCU may not be connected.")
|
|
|
} else {
|
|
|
log.Println("Auxiliary MCU found with UUID:", uuid)
|
|
|
|
|
@@ -38,37 +122,34 @@ func startUsbKvmMode() error {
|
|
|
|
|
|
// Initiate the video capture device
|
|
|
videoCapture, err = usbcapture.NewInstance(&usbcapture.Config{
|
|
|
- DeviceName: *captureDeviceName,
|
|
|
+ DeviceName: config.VideoCaptureDevicePath,
|
|
|
AudioConfig: usbcapture.GetDefaultAudioConfig(),
|
|
|
})
|
|
|
|
|
|
if err != nil {
|
|
|
- log.Fatalf("Failed to create video capture instance: %v", err)
|
|
|
+ log.Println("Video capture device init failed:", err, " - Video capture device may not be connected.")
|
|
|
+ return err
|
|
|
}
|
|
|
|
|
|
//Get device information for debug
|
|
|
- usbcapture.PrintV4L2FormatInfo(*captureDeviceName)
|
|
|
+ usbcapture.PrintV4L2FormatInfo(config.VideoCaptureDevicePath)
|
|
|
|
|
|
//Start the video capture device
|
|
|
err = videoCapture.StartVideoCapture(&usbcapture.CaptureResolution{
|
|
|
- Width: 1920,
|
|
|
- Height: 1080,
|
|
|
- FPS: 10,
|
|
|
+ Width: config.CaptureResolutionWidth,
|
|
|
+ Height: config.CaptureResolutionHeight,
|
|
|
+ FPS: config.CaptureResolutionFPS,
|
|
|
})
|
|
|
if err != nil {
|
|
|
- log.Fatal(err)
|
|
|
+ return err
|
|
|
}
|
|
|
|
|
|
// Handle program exit to close the HID controller
|
|
|
-
|
|
|
c := make(chan os.Signal, 1)
|
|
|
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
|
|
|
go func() {
|
|
|
<-c
|
|
|
log.Println("Shutting down usbKVM...")
|
|
|
- if usbKVM != nil {
|
|
|
- //usbKVM.Close()
|
|
|
- }
|
|
|
|
|
|
if auxMCU != nil {
|
|
|
auxMCU.Close()
|
|
@@ -80,11 +161,11 @@ func startUsbKvmMode() error {
|
|
|
os.Exit(0)
|
|
|
}()
|
|
|
|
|
|
- // Register the API routes
|
|
|
+ // Register the rest of the API routes
|
|
|
registerAPIRoutes()
|
|
|
|
|
|
- addr := ":9000"
|
|
|
- log.Printf("Serving on http://localhost%s\n", addr)
|
|
|
+ addr := config.ListeningAddress
|
|
|
+ log.Printf("Serving on%s\n", addr)
|
|
|
err = http.ListenAndServe(addr, nil)
|
|
|
return err
|
|
|
}
|