Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IOS: USB support (OH0, USB_VEN, USB_HID) #4408

Merged
merged 10 commits into from Feb 6, 2017
Merged

Conversation

leoetlino
Copy link
Member

@leoetlino leoetlino commented Oct 30, 2016

This PR implements OH0, USB_VEN and reimplements USB_HID v4 using the new common USB code.

With these devices added, Dolphin's IOS HLE USB support should be virtually complete, apart from HIDv5 (which is not used) and internal IOS devices. Fixes issue 5079, 7856, 9185, 9199, 9426, 9851 and 9852.

Known issues:

  • Isochronous transfers are currently broken on Windows in Your Shape.
  • Your Shape doesn't shut down on STM power-off event. (This is low-priority.)

Tested with the following devices:

  • Wii Speak (057e:0308) in the Wii Speak Channel, Wheel of Fortune, Jeopardy Wii (OH0)
  • SanDisk USB drives (0781:5567, 0781:5572) in libogc homebrew (WiiMC, HBC) which use OH0/VEN
  • Logitech microphone (046d:0a03) in Karaoke Glee (VEN), Karaoke Revolution Presents: American Idol Encore (OH0), Rock Band 3 (OH0), U-Sing (OH0)
  • Your Shape camera (057e:030a) in Your Shape Featuring Jenny McCarthy (VEN)
  • Logitech USB mouse + keyboard receiver (046d:c505) in the Internet Channel (HID v4)
  • Skylanders portals (1430:0150) (HID v4)

@lioncash lioncash added the WIP / do not merge Work in progress (do not merge) label Oct 31, 2016
@lioncash
Copy link
Member

Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb.h, line 134 at r1 (raw file):

constexpr u16 USBHDR(u8 dir, u8 type, u8 recipient, u8 request)
{
  return ((dir << 7 | type << 5 | recipient) << 8) | request;

Note that this should be

return static_cast<int>(((dir << 7 | type << 5 | recipient) << 8) | request);

otherwise this is truncating an int due to how integral promotion works.


Comments from Reviewable

@lioncash
Copy link
Member

Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb.h, line 134 at r1 (raw file):

Previously, lioncash (Mat M.) wrote…

Note that this should be

return static_cast<int>(((dir << 7 | type << 5 | recipient) << 8) | request);

otherwise this is truncating an int due to how integral promotion works.

err...
return static_cast<u16>(((dir << 7 | type << 5 | recipient) << 8) | request);

is what I meant.


Comments from Reviewable

@leoetlino
Copy link
Member Author

Review status: 0 of 52 files reviewed at latest revision, 1 unresolved discussion.


Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb.h, line 134 at r1 (raw file):

Previously, lioncash (Mat M.) wrote…

err...

return static_cast<u16>(((dir << 7 | type << 5 | recipient) << 8) | request);

is what I meant.

Done.

Comments from Reviewable

@JMC47
Copy link
Contributor

JMC47 commented Nov 2, 2016

Using a modified LibUSB, I was able to get Wii Speak working on Windows. i also tested it on linux. It appears oh0 is working properly.

We were unable to get USB/VEN working, which it seems most/all mic games use?

@leoetlino leoetlino changed the title [WIP] Implement USB passthrough for OH0 and USB_VEN [WIP] IPC_HLE: Implement OH0 and USB_VEN Nov 13, 2016
@Warepire
Copy link

Review status: 0 of 77 files reviewed at latest revision, 2 unresolved discussions.


Source/Core/Core/IPC_HLE/USB/LibusbDevice.cpp, line 259 at r4 (raw file):

                                                Version version)
{
  std::vector<u8> buffer(buffer_size);

Is there any possible way that buffer_size can end up being < 12 bytes?
I'd prefer to see some validation of that, or a note somewhere that it's definitely impossible.


Comments from Reviewable

@leoetlino
Copy link
Member Author

Review status: 0 of 77 files reviewed at latest revision, 2 unresolved discussions.


Source/Core/Core/IPC_HLE/USB/LibusbDevice.cpp, line 259 at r4 (raw file):

Previously, Warepire wrote…

Is there any possible way that buffer_size can end up being < 12 bytes?
I'd prefer to see some validation of that, or a note somewhere that it's definitely impossible.

Yes, if GetIOSDescriptors is called with buffer_size < 12 bytes.

Currently, this is used by the USB HID v4 and VEN implementations. HID calls this with a constant size, but VEN relies on the ioctl output buffer size, so it can definitely end up being smaller than what we need.

I'll validate the size in VEN and also add a check here for a minimum usable size.


Comments from Reviewable

@JMC47
Copy link
Contributor

JMC47 commented Feb 4, 2017

@dolphin-emu-bot rebuild

This build was broken somehow so double checking.

return sizer;
}

static bool IsValidHexString(const std::string& string)

This comment was marked as off-topic.

{{0x057e, 0x030a}, "Ubisoft Motion Tracking Camera"},
{{0x0e6f, 0x0129}, "Disney Infinity Reader (Portal Device)"},
{{0x1430, 0x0100}, "Tony Hawk Ride Skateboard"},
{{0x1430, 0x0150}, "Skylanders portals"},

This comment was marked as off-topic.

});
}

static void CopyToBuffer(std::vector<u8>* buffer, const void* data, const size_t size)

This comment was marked as off-topic.

This comment was marked as off-topic.

@Parlane
Copy link
Member

Parlane commented Feb 5, 2017

LGTM

This adds a USB passthrough setting to ConfigManager and everything
needed for the UI to show and manage the whitelist properly.
Allows adding/removing devices from USB passthrough.
This will be useful for the USB devices to disconnect and hide any real
devices when Core::g_want_determinism is true.
This allows us to get back the current active IOS version and expose
only devices which exist/can be used in that version.
The Host class will be used by the OH0, VEN and HID implementations
as the base class for the IOS HLE device. It handles scanning devices,
detecting device changes and everything that will be needed for OH0,
VEN and HID to be implemented, while mostly abstracting libusb away.

The Device class is for actual USB devices. This commit adds a
LibusbDevice which interacts with a real USB device and enables
USB passthrough.
libusb on Windows is limited to only a single context. Trying to open
more than one can cause device enumerations to fail randomly.

libusb is thread-safe and we don't use the manual polling support (with
`poll()`) so this should be safe.
This reimplements the USB HID v4 IOS device using the new common
USB code (to reuse more code and allow emulated HIDs to be added
more easily in the future).

The main difference is that HIDs now have to be whitelisted, like
every other USB device for OH0 and VEN.
The usbdk backend is the only libusb backend that has official support
for isochronous transfers (which are required for Wii Speak,
microphones and cameras). And it's actively developed and maintained.
@ghost
Copy link

ghost commented Feb 7, 2017

uh,but when i start dolphin it appears with a error message "failed to initialize usblib because usbdk is not installed" help!!!

@JMC47
Copy link
Contributor

JMC47 commented Feb 7, 2017

Install the usbdk driver https://github.com/daynix/UsbDk/releases

@mbc07
Copy link
Contributor

mbc07 commented Feb 7, 2017

I noticed I can't use bluetooth passthrough anymore after the merge of this PR. I'm on Windows and I have installed UsbDk, but Dolphin simply hang on a black screen when booting any Wii game (the GUI still responds but you can't stop emulation nor close Dolphin, the only way out is ending Dolphin through Task Manager), even with different BT Adapters that all worked fine on previous versions of Dolphin...

@leoetlino
Copy link
Member Author

@mbc07 could you check Dolphin's log and make sure it is using the correct device for the Bluetooth adapter?

@mbc07
Copy link
Contributor

mbc07 commented Feb 7, 2017

Okay, got it working, seems a Windows issue. Following the wiki instruction (just install UsbDk) makes Dolphin always hang if Bluetooth Passthrough is enabled, regardless of the BT adapter. The only relevant info I found in the log was this line:
29:16:662 IOS\IPC.cpp:712 I[IOS]: Opening /dev/usb/oh1/57e/305 (mode 0, fd 5)
After that, nothing more shows in the log and Dolphin remain stuck at a black screen (the GUI still is fully operational, though).

If I go the Zadig route and install WinUSB driver to the BT adapter, then Dolphin works fine in Bluetooth Passthrough like in previous versions, but if I understood right, Zadig shouldn't be needed anymore after this PR. Maybe the Windows Bluetooth Stack is somehow "locking" the BT Adapter so Dolphin can't access it even though UsbDk is already installed? That or maybe the wiki instructions aren't correct and forcing WinUSB driver with Zadig still is needed regardless of UsbDk being installed?

@leoetlino
Copy link
Member Author

@mbc07 yes, only usbdk should be required now… so I'm not quite sure why it needs a Zadig driver to be installed. I have looked into it and for some reason, libusb gets stuck at opening the Bluetooth adapter, even though the system does not see it anymore (the BT icon disappeared).
I guess we should update the wiki to note that using Zadig is still required for BT passthrough because of a usbdk bug or Windows limitation. :/

@mbc07
Copy link
Contributor

mbc07 commented Feb 8, 2017

I have looked into it and for some reason, libusb gets stuck at opening the Bluetooth adapter, even though the system does not see it anymore (the BT icon disappeared).

Well, I don't even get that far (the BT icon never disappears), and from further testing I'm assuming the Bluetooth Stack is somehow "locking" the BT Adapter, installing libusb with Zadig unloads the BT Stack and then Dolphin can take over the BT Adapter with UsbDk. I even force installed a completely unrelated driver to the BT Adapter (forced a serial port driver), it ended up with an error 10 code saying it couldn't start the device (expected) but it also unloaded the Windows BT Stack and Dolphin worked fine with Bluetooth Passthrough.

TL;DR the Bluetooth Stack locks the adapter somehow, installing any other driver on top of the BT Adapter unloads the BT Stack and then Dolphin can freely control it with UsbDk...

@leoetlino
Copy link
Member Author

leoetlino commented Feb 8, 2017

daynix/UsbDk#35
I have now opened an issue for this.

@@ -443,6 +446,9 @@
<ClInclude Include="Config\PathConfigPane.h">
<Filter>GUI\Config</Filter>
</ClInclude>
<ClCompile Include="Config\AddUSBDeviceDiag.h">

This comment was marked as off-topic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet