Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions packages/usbmuxd/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ TERMUX_PKG_MAINTAINER="@termux"
_COMMIT=523f7004dce885fe38b4f80e34a8f76dc8ea98b5
_COMMIT_DATE=20250201
TERMUX_PKG_VERSION=1.1.1-p${_COMMIT_DATE}
TERMUX_PKG_REVISION=2
TERMUX_PKG_REVISION=3
TERMUX_PKG_SRCURL=git+https://github.com/libimobiledevice/usbmuxd
TERMUX_PKG_SHA256=7943adb00031c05a6db3b7e822b5147e32988c9b79d29fd4656a2e1f733181de
TERMUX_PKG_GIT_BRANCH=master
TERMUX_PKG_AUTO_UPDATE=true
TERMUX_PKG_DEPENDS="libimobiledevice-glue, libplist, libusb"
TERMUX_PKG_DEPENDS="libimobiledevice, libplist, libusb, termux-api, jq"
TERMUX_PKG_EXTRA_CONFIGURE_ARGS="
--without-preflight
--without-systemd
Expand All @@ -37,3 +37,9 @@ termux_step_post_get_source() {
termux_step_pre_configure() {
autoreconf -fi
}

termux_step_post_make_install() {
mv "$TERMUX_PREFIX/bin/usbmuxd" "$TERMUX_PREFIX/bin/usbmuxd-bin"
$CC $CFLAGS $CPPFLAGS $LDFLAGS $TERMUX_PKG_BUILDER_DIR/usbmuxd-helper/usbmuxd-helper.c -lusb-1.0 -o "$TERMUX_PREFIX/libexec/usbmuxd-helper"
install -Dm755 "$TERMUX_PKG_BUILDER_DIR/usbmuxd-helper/usbmuxd" -t "$TERMUX_PREFIX/bin"
}
103 changes: 103 additions & 0 deletions packages/usbmuxd/usbmuxd-helper/usbmuxd
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
#!/data/data/com.termux/files/usr/bin/bash
set -euo pipefail
handle_sigint() {
echo -e "\nShutting down usbmuxd"
usbmuxd-bin -X
exit 130 # SIGINT
}
trap handle_sigint SIGINT
loop_refresh_usb_fd() {
local cmd_once="$1"
local cmd_repeat="$2"
[[ -z $cmd_once || -z $cmd_repeat ]] && {
printf 'Usage: loop_refresh_usb_fd "cmd_once" "cmd_repeat" \n' >&2
return 2
}
if ! eval "$cmd_once" &> /dev/null; then
echo "Failed to start usbmuxd..retrying"
return
fi
sleep 3 # Give it some time to boot up
# First time checks to see if it really launched
if ! eval "$cmd_repeat" &> /dev/null; then
if ! eval pgrep -x usbmuxd-bin &> /dev/null; then
# Should never happen unless it somehow took too long to start or got killed
# We supress log output so have the user troubleshoot it by manually starting
echo "usbmuxd failed to run. Please try running it manually using \'termux-api-start && $cmd_once\'"
usbmuxd-bin -X
exit 1
else
# Possibly remove this and just swap out the repeat command with idevicepair pair.

# Imitates what happens on desktop, requesting trust as soon as plugged in. Some
# programs that rely on usbmuxd don't handle when a device is not paired (LOCKDOWN_E_INVALID_HOST_ID)
# so it is best to pair them upon connection.
echo "Can't connect to iDevice. Assuming unpaired. Please press \"trust\" on the iDevice."
idevicepair pair &> /dev/null || true
echo "Press any key after trusting to continue starting usbmuxd"
read -r -n1
idevicepair pair &> /dev/null || true
fi
fi
echo "USB device connected! usbmuxd running. Ctrl+c to stop"
while true; do
if ! eval "$cmd_repeat" &> /dev/null; then
echo "USB device disconnected!"
break
fi
sleep 0.5
done
}
# Make sure Termux:API is accessable first
echo "Notice: We can currently only interact with one device at a time due to termux-usb limitations"
echo "Starting Termux:API for requesting USB access, please make sure your iDevice is plugged in and unlocked and the Termux:API plugin app is installed."
termux-api-start >/dev/null || exit_code=$?
exit_code=${exit_code:-0}
if [[ $exit_code != 0 ]]; then
echo "Failed to start Termux:API service. Is companion app installed?"
exit "$exit_code"
fi

while true; do
# TODO: Adapt to https://github.com/termux/termux-api/pull/759
# Rewrite the script to target vendorId when requesting permission once the PR is merged so we target only iDevices.
while true; do
readarray -t deviceArray < <(
termux-api-start &> /dev/null || :
termux-usb -l | jq -r '.[]'
)
if [ "${#deviceArray[@]}" -eq 0 ]; then
echo -ne "\033[2K\rNo USB devices found. Please make sure the iDevice is the USB host."
sleep 0.5
else
echo -ne "\033[2K\r${#deviceArray[@]} USB device(s) found! Starting usbmuxd... \n"
break
fi
done
for dev in "${deviceArray[@]}"; do
echo "Requesting USB permission. If prompted for the iDevice, please allow... "
exit_code=0
usb_info=$(termux-usb -r -e "$PREFIX"/libexec/usbmuxd-helper "$dev") || exit_code=$?
if [[ $exit_code != 0 ]]; then
echo "Permission denied. Continuing to next device."
continue
fi
read -r vid pid product manufacturer <<<"$usb_info"
if [[ $vid == "05ac" ]]; then # Apple's vendorId
usbmuxd-bin -X # Kill any running usbmuxd's
sleep 0.5 # Give it some time to die
loop_refresh_usb_fd "termux-usb -r -E -e usbmuxd-bin $dev" "idevicename"
rescan=true # Rescan devices upon disconnect
continue
else
echo "Not an iDevice:" "$vid":"$pid" "$product" "$manufacturer"". Continuing to the next device."
continue
fi
done
if [[ $rescan == "true" ]]; then
rescan=false
continue
fi
echo "No more devices found. Either no iDevice was found or it was not given permission. Run \"usbmuxd\" again to retry"
exit 2
done
36 changes: 36 additions & 0 deletions packages/usbmuxd/usbmuxd-helper/usbmuxd-helper.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#include <libusb-1.0/libusb.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
if (argc != 2) {
fprintf(stderr, "Usage: %s <usb_fd>\n", argv[0]);
return 1;
}
int fd = atoi(argv[1]);
libusb_device_handle *handle;
libusb_set_option(NULL, LIBUSB_OPTION_NO_DEVICE_DISCOVERY);
libusb_init(NULL);
if (libusb_wrap_sys_device(NULL, (intptr_t)fd, &handle)) {
fprintf(stderr, "Failed to wrap fd\n");
return 1;
}
libusb_device *dev = libusb_get_device(handle);
struct libusb_device_descriptor desc;
if (libusb_get_device_descriptor(dev, &desc) != 0) {
fprintf(stderr, "Failed to get device descriptor\n");
return 1;
}
unsigned char manufacturer[256] = {0};
unsigned char product[256] = {0};
if (desc.iManufacturer)
libusb_get_string_descriptor_ascii(handle, desc.iManufacturer, manufacturer,
sizeof(manufacturer));
if (desc.iProduct)
libusb_get_string_descriptor_ascii(handle, desc.iProduct, product,
sizeof(product));
printf("%04x %04x \"%s\" \"%s\"\n", desc.idVendor, desc.idProduct, product,
manufacturer);

libusb_exit(NULL);
return 0;
}
Loading