diff --git a/internal/audio/embed.go b/internal/audio/embed.go index c6a7a248..9caf199b 100644 --- a/internal/audio/embed.go +++ b/internal/audio/embed.go @@ -15,10 +15,10 @@ var audioOutputBinary []byte var audioInputBinary []byte const ( - audioBinDir = "/userdata/jetkvm/bin" - audioOutputBinPath = audioBinDir + "/jetkvm_audio_output" - audioInputBinPath = audioBinDir + "/jetkvm_audio_input" - binaryFileMode = 0755 // rwxr-xr-x + audioBinDir = "/userdata/jetkvm/bin" + audioOutputBinPath = audioBinDir + "/jetkvm_audio_output" + audioInputBinPath = audioBinDir + "/jetkvm_audio_input" + binaryFileMode = 0755 // rwxr-xr-x ) // ExtractEmbeddedBinaries extracts the embedded C audio binaries to disk @@ -78,13 +78,3 @@ func GetAudioOutputBinaryPath() string { func GetAudioInputBinaryPath() string { return audioInputBinPath } - -// init ensures binaries are extracted when package is imported -func init() { - // Extract binaries on package initialization - // This ensures binaries are available before supervisors start - if err := ExtractEmbeddedBinaries(); err != nil { - // Log error but don't panic - let caller handle initialization failure - fmt.Fprintf(os.Stderr, "Warning: Failed to extract embedded audio binaries: %v\n", err) - } -} diff --git a/internal/audio/ipc.go b/internal/audio/ipc.go index 1807f438..e9b50bb0 100644 --- a/internal/audio/ipc.go +++ b/internal/audio/ipc.go @@ -22,15 +22,15 @@ var writeBufferPool = sync.Pool{ // IPC Protocol constants (matches C implementation in ipc_protocol.h) const ( - ipcMagicOutput = 0x4A4B4F55 // "JKOU" - Output (device → browser) - ipcMagicInput = 0x4A4B4D49 // "JKMI" - Input (browser → device) - ipcHeaderSize = 9 // Reduced from 17 (removed 8-byte timestamp) - ipcMaxFrameSize = 1024 // 128kbps @ 20ms = ~600 bytes worst case with VBR+FEC - ipcMsgTypeOpus = 0 - ipcMsgTypeConfig = 1 - ipcMsgTypeStop = 3 - connectTimeout = 5 * time.Second - readTimeout = 2 * time.Second + ipcMagicOutput = 0x4A4B4F55 // "JKOU" - Output (device → browser) + ipcMagicInput = 0x4A4B4D49 // "JKMI" - Input (browser → device) + ipcHeaderSize = 9 // Reduced from 17 (removed 8-byte timestamp) + ipcMaxFrameSize = 1024 // 128kbps @ 20ms = ~600 bytes worst case with VBR+FEC + ipcMsgTypeOpus = 0 + ipcMsgTypeConfig = 1 + ipcMsgTypeStop = 3 + connectTimeout = 5 * time.Second + readTimeout = 2 * time.Second ) // IPCClient manages Unix socket communication with audio subprocess @@ -109,7 +109,9 @@ func (c *IPCClient) ReadMessage() (uint8, []byte, error) { } // Set read deadline - c.conn.SetReadDeadline(time.Now().Add(readTimeout)) + if err := c.conn.SetReadDeadline(time.Now().Add(readTimeout)); err != nil { + return 0, nil, fmt.Errorf("failed to set read deadline: %w", err) + } // Read 9-byte header var header [ipcHeaderSize]byte diff --git a/internal/audio/supervisor.go b/internal/audio/supervisor.go index b5882c80..3b1ceb93 100644 --- a/internal/audio/supervisor.go +++ b/internal/audio/supervisor.go @@ -21,12 +21,12 @@ type Supervisor struct { socketPath string env []string - cmd *exec.Cmd - ctx context.Context - cancel context.CancelFunc - running atomic.Bool - done chan struct{} // Closed when supervision loop exits - logger zerolog.Logger + cmd *exec.Cmd + ctx context.Context + cancel context.CancelFunc + running atomic.Bool + done chan struct{} // Closed when supervision loop exits + logger zerolog.Logger // Restart state restartCount uint8 @@ -81,7 +81,7 @@ func (s *Supervisor) Stop() { // Kill process if running if s.cmd != nil && s.cmd.Process != nil { - s.cmd.Process.Kill() + _ = s.cmd.Process.Kill() // Ignore error, process may already be dead } // Wait for supervision loop to exit diff --git a/internal/usbgadget/config.go b/internal/usbgadget/config.go index d8bfcf3a..0a9b3caa 100644 --- a/internal/usbgadget/config.go +++ b/internal/usbgadget/config.go @@ -66,14 +66,14 @@ var defaultGadgetConfig = map[string]gadgetConfigItem{ path: []string{"functions", "uac1.usb0"}, configPath: []string{"uac1.usb0"}, attrs: gadgetAttributes{ - "p_chmask": "3", // Playback: stereo (2 channels) - "p_srate": "48000", // Playback: 48kHz sample rate - "p_ssize": "2", // Playback: 16-bit (2 bytes) - "p_volume_present": "0", // Playback: no volume control - "c_chmask": "3", // Capture: stereo (2 channels) - "c_srate": "48000", // Capture: 48kHz sample rate - "c_ssize": "2", // Capture: 16-bit (2 bytes) - "c_volume_present": "0", // Capture: no volume control + "p_chmask": "3", // Playback: stereo (2 channels) + "p_srate": "48000", // Playback: 48kHz sample rate + "p_ssize": "2", // Playback: 16-bit (2 bytes) + "p_volume_present": "0", // Playback: no volume control + "c_chmask": "3", // Capture: stereo (2 channels) + "c_srate": "48000", // Capture: 48kHz sample rate + "c_ssize": "2", // Capture: 16-bit (2 bytes) + "c_volume_present": "0", // Capture: no volume control }, }, }