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

Support different USB "modes" (via configuration #5) #205

Closed
EliyahuStern opened this issue Dec 22, 2022 · 5 comments
Closed

Support different USB "modes" (via configuration #5) #205

EliyahuStern opened this issue Dec 22, 2022 · 5 comments

Comments

@EliyahuStern
Copy link

EliyahuStern commented Dec 22, 2022

idevices "hide" a couple of useful USB interfaces when the device is first plugged in. These interface can be revealed by:

  • starting "New Movie Recording" in macOS QuickTime reveals an interface called "Valeria" with Apple's proprietary protocol wrapping an H.265 video/audio stream of the device.
  • activating "Internet Sharing" to the connected device from macOS Settings app reveals CDC NCM interfaces used to establish Ethernet over USB between the host and device.

Under the hood, macOS sends vendor specific control URBs to the device, instructing it to reconnect with a different set of configurations. Both modes add a new configuration (# 5) with both the desired interface (Valeria/CDC NCM) and "Apple USB Multiplexor".

A previous commit (bf2e2ec) was made to support the former ("Valeria") mode. This commit assumes that the extra configuration has 3 interfaces, USBMUX being 3rd, which is not the case for CDC NCM (2nd out of 4).

The latter mode can be considered more valuable on Linux, as it has an out-of-the-box support with the cdc_ncm USB driver module. Once the device is switched to the correct mode and configuration 5 is set, a new Network Interface is added to the system, which can then be easily controlled via UI ("Share this connection ...") or nft/iptables.

To prevent usbmuxd from conflicting with Ethernet/USB, and also to allow users to switch to those modes, I suggest the following changes (which I plan to soon submit a PR for):

  • Add an environment variable to the service (USBMUXD_DEFAULT_DEVICE_MODE) that the user can set to control the desired mode:
    0 ignore mode and connect to USBMUX interface on highest available configuration (usually 4)
    1 if needed, switch to initial mode before connecting to USBMUX interface on highest available configuration (usually 4)
    2 if needed, switch to "Valeria" mode before connecting to USBMUX interface on highest available configuration (usually 5)
    3 if needed, switch to "Ethernet/USB" mode before connecting to USBMUX interface on highest available configuration (usually 5)
  • Factor out most of usb_device_add functionality (that is, the part that finds the suitable configuration/interface/endpoint and adds the device to the "live" list) into usb_device_complete_initialization
  • Instead, usb_device_add will use libusb async APIs to send a vendor-specific control message to the newly connected device, requesting for its current mode.
  • Once the message completes (or fails), the callback function will either call usb_device_complete_initialization, or send another vendor-specific control message to switch to the desired mode.
  • If switching the mode, the device will reconnect, and usb_device_complete_initialization will be called after validating the desired mode.
@EliyahuStern
Copy link
Author

valeria_descriptors.txt
cdc_ncm_descriptors.txt
ipad_cdc_ncm.pcapng.zip

@Karazum
Copy link

Karazum commented Mar 1, 2023

After you commit, I am getting Segmentation fault
Tested on multiple iPhone devices (iOS 16 and iOS 15 versions)


sudo usbmuxd -f -vvv
[11:46:33.138][3] usbmuxd v1.1.1-44-ge55e6e7 starting up
[11:46:33.138][4] Creating socket
[11:46:33.138][4] Listening on /var/run/usbmuxd
[11:46:33.138][5] Initialized config_dir to /var/lib/lockdown
[11:46:33.138][5] client_init
[11:46:33.138][5] device_init
[11:46:33.138][4] Initializing USB
[11:46:33.138][3] Using libusb 1.0.26
[11:46:33.142][4] Registering for libusb hotplug events
[timestamp] [threadID] facility level [function call] <message>
--------------------------------------------------------------------------------
[ 0.003966] [00014b9b] libusb: debug [libusb_hotplug_register_callback] new hotplug cb 0x558fa2815d30 with handle 1
[ 0.003970] [00014b9b] libusb: debug [libusb_get_device_list]  
[ 0.003976] [00014b9b] libusb: debug [libusb_get_device_descriptor]  
[11:46:33.142][4] Found new device with v/p 05ac:12a8 at 3-53
[ 0.003978] [00014b9b] libusb: debug [libusb_open] open 3.53
[ 0.004029] [00014b9b] libusb: debug [usbi_add_event_source] add fd 9 events 4
[11:46:33.142][4] Requesting current mode from device 3-53
[ 0.004034] [00014b9b] libusb: debug [libusb_submit_transfer] transfer 0x558fa2818460
[ 0.004035] [00014b9b] libusb: debug [add_to_flying_list] arm timer for timeout in 1000ms (first in line)
[11:46:33.142][4] 1 device detected
[11:46:33.142][3] Initialization complete
[11:46:33.142][4] Client 10 accepted: /usr/libexec/gvfs-afc-volume-monitor[4349]
[ 0.004116] [00014b9b] libusb: debug [libusb_handle_events_timeout_completed] doing our own event handling
[ 0.004118] [00014b9b] libusb: debug [handle_events] event sources modified, reallocating event data
[ 0.004120] [00014b9b] libusb: debug [usbi_wait_for_events] poll() 3 fds with timeout in 0ms
[ 0.004123] [00014b9b] libusb: debug [usbi_wait_for_events] poll() returned 0
[11:46:33.142][5] Client 10 command len 439 ver 1 msg 8 tag 49
[11:46:33.142][5] Client 10 output buffer got tag 49 msg 8 payload_length 278
[11:46:33.142][5] Client 10 now LISTENING
[ 0.004602] [00014b9b] libusb: debug [libusb_handle_events_timeout_completed] doing our own event handling
[ 0.004605] [00014b9b] libusb: debug [usbi_wait_for_events] poll() 3 fds with timeout in 0ms
[ 0.004606] [00014b9b] libusb: debug [usbi_wait_for_events] poll() returned 1
[ 0.004609] [00014b9b] libusb: debug [reap_for_handle] urb type=2 status=0 transferred=3
[ 0.004611] [00014b9b] libusb: debug [handle_control_completion] handling completion status 0
[ 0.004612] [00014b9b] libusb: debug [arm_timer_for_next_timeout] no timeouts, disarming timer
[ 0.004614] [00014b9b] libusb: debug [usbi_handle_transfer_completion] transfer 0x558fa2818460 has callback 0x558fa207d600
Segmentation fault

@nikias
Copy link
Member

nikias commented Mar 1, 2023

Can you check if it would be fixed with this:
#212

@Karazum
Copy link

Karazum commented Mar 1, 2023

Can you check if it would be fixed with this: #212

Yes, it is fixed

@nikias
Copy link
Member

nikias commented Mar 23, 2023

Great!

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

No branches or pull requests

3 participants