Skip to content

fix: 修复 UAC 麦克风透传在 DWC3 上的播放失败 - #291

Open
arounyf wants to merge 1 commit into
mofeng-git:mainfrom
arounyf:fix/uac-playback-start
Open

fix: 修复 UAC 麦克风透传在 DWC3 上的播放失败#291
arounyf wants to merge 1 commit into
mofeng-git:mainfrom
arounyf:fix/uac-playback-start

Conversation

@arounyf

@arounyf arounyf commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

问题

5963dfa0(完善 OTG UAC 音频支持)将 UAC 播放从 aplay 子进程重写为非阻塞 ALSA 状态机后,DWC3 复合设备上麦克风透传失效,UI 一直卡在「等待目标机」。

两个根本原因

1. ConfigFS link 顺序被打乱 → 等时端点分配到 ep7

recreate_config_links()std::fs::read_dir 遍历 functions/ 目录,按文件系统字母序重建 link。uac1.usb0 字母序排在 hid.usb0~3 之后,导致 UAC 等时端点被分配到 ep7。DWC3 无法在 ep7 上做等时传输,内核报错:

dwc3: request ... was not queued to ep7in

之前成功时 UAC 拿的是低编号端点(ep2),靠 UAC 优先 HID 创建保证。

2. 非阻塞 ALSA 无法启动等时端点

playback.rsPCM::new(..., true)(非阻塞)+ start_threshold 自动启动,但 snd_pcm_start 返回 EPIPE:

Failed to start UAC PCM: snd_pcm_start failed with error 'Broken pipe (32)'

非阻塞模式在 DWC3 上无法激活等时端点。之前 aplay 子进程(阻塞 ALSA)可以。

修复

文件 改动
src/otg/manager.rs recreate_config_linksfunctions Vec 顺序(UAC 优先)重建 link
src/audio/uac/playback.rs 改回 aplay 子进程方案(阻塞 ALSA),保留 UacPlaybackState 状态机接口和前端 UI

同时复现之前 PR #285 的修复:

  • 空闲恢复时强制新 aplay(was_idle 标志)
  • --buffer-size=32768 大缓冲容错
  • 5s 空闲超时
  • try_recv 轮询(避免 blocking_recv 卡死线程)

两个根本修复:

1. recreate_config_links 用 read_dir 字母序重建 ConfigFS link,
   导致 uac1.usb0 排在 hid.* 之后拿到高编号端点 ep7,DWC3 无法
   在该端点上做等时传输(request not queued)。改为按 functions
   Vec 顺序(UAC 优先)重建 link。

2. 非阻塞 ALSA 状态机在 DWC3 上无法启动等时端点
   (snd_pcm_start 返回 EPIPE)。改回 aplay 子进程方案
   (阻塞 ALSA,已验证成功),保留 UacPlaybackState 状态机
   和前端 UI。同时复现之前提交的空闲恢复强制新 aplay、
   大缓冲、5s 空闲超时等修复。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant