iOS设备USB重置问题:录制中断后代码模拟重连失败求助
iOS USB录屏管道停滞问题排查与修复
错误原因分析
(iokit/usb) pipe has stalled错误本质是USB传输管道因设备端视频传输中断后的残留异常进入停滞状态,必须先清除该状态才能继续与设备通信,直接执行DeviceRequest会因管道未恢复而失败。
具体修复步骤与代码调整
1. 先重置USB设备清除停滞状态
在获取设备接口后,先执行设备重置操作,这是模拟物理插拔的核心逻辑,能直接刷新设备的USB状态:
result = (*iodev)->QueryInterface( iodev, CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID245), (LPVOID)&dev); IODestroyPlugInInterface(iodev); if (result || !dev) { fprintf(stderr, "could not get device interface: %08x\n", (int)result); continue; } // 新增:重置USB设备,清除管道停滞状态 IOReturn reset_err = (*dev)->USBDeviceReset(dev); if (reset_err != kIOReturnSuccess) { printf("Failed to reset USB device: %s\n", mach_error_string(reset_err)); // 重置失败时释放接口后重试 (*dev)->Release(dev); dev = NULL; continue; }
2. 修正DeviceRequest的缓冲区处理逻辑
原代码中固定大小的缓冲区可能因不足以容纳序列号字符串描述符导致传输异常,建议先查询描述符实际长度再分配对应缓冲区:
// 获取序列号索引 IOReturn err = (*dev)->USBGetSerialNumberStringIndex(dev, &serial_index); if (err != kIOReturnSuccess) { printf("Could not get serial number string index (error: %x)\n", err); (*dev)->Release(dev); dev = NULL; return; } // 第一步:查询描述符实际长度 IOUSBDevRequest request = {0}; request.bmRequestType = USBmakebmRequestType(kUSBIn, kUSBStandard, kUSBDevice); request.bRequest = kUSBRqGetDescriptor; request.wValue = (kUSBStringDesc << 8) | serial_index; request.wIndex = 0x409; request.wLength = 0; // 发送长度为0的请求获取实际描述符长度 err = (*dev)->DeviceRequest(dev, &request); if (err != kIOReturnSuccess) { printf("Failed to get descriptor length: %s\n", mach_error_string(err)); (*dev)->Release(dev); dev = NULL; return; } // 第二步:分配对应大小的缓冲区并获取完整描述符 uint8_t* buffer = malloc(request.wLength); if (!buffer) { printf("Failed to allocate buffer for descriptor\n"); (*dev)->Release(dev); dev = NULL; return; } bzero(buffer, request.wLength); request.wLength = request.wLength; request.pData = buffer; err = (*dev)->DeviceRequest(dev, &request); if (err != kIOReturnSuccess) { char *err_str = mach_error_string(err); printf("Could not request usb device %s\n", err_str); free(buffer); (*dev)->Release(dev); dev = NULL; return; } // 此处添加序列号处理逻辑... // 清理资源 free(buffer); (*dev)->Release(dev); dev = NULL;
3. 确保资源正确释放
每次操作完成或失败后,必须释放IOUSBDeviceInterface接口,避免资源泄漏导致后续操作出现管道异常。
额外注意事项
- 执行设备重置后,idb的录屏会话需要重新初始化,建议重置后重启idb的设备连接会话。
- 如果问题仍存在,检查USB线缆是否损坏,或尝试更换USB端口(优先使用USB 3.0端口)。
内容的提问来源于stack exchange,提问作者Solid Soft
相关产品推荐
相关产品推荐

