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

Make utility work in the face of 2 issues found on Ubuntu 16.04 #44

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
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
42 changes: 29 additions & 13 deletions ipad_charge.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,31 +33,46 @@ int set_charging_mode(libusb_device *dev, bool enable) {
struct libusb_device_handle *dev_handle;

if ((ret = libusb_open(dev, &dev_handle)) < 0) {
fprintf(stderr, "ipad_charge: unable to open device: error %d\n", ret);
fprintf(stderr, "ipad_charge: %s\n", libusb_strerror(ret));
fprintf(stderr, "ipad_charge: Unable to open device: error %d [%s]\n", ret, libusb_strerror(ret));
return ret;
}

if ((ret = libusb_claim_interface(dev_handle, 0)) < 0) {
fprintf(stderr, "ipad_charge: unable to claim interface: error %d\n", ret);
fprintf(stderr, "ipad_charge: %s\n", libusb_strerror(ret));
goto out_close;
fprintf(stderr, "ipad_charge: Opened device\n");
// Resource Busy issue is caused because kernel is attached to device, so enable auto detach
if ((ret = libusb_set_auto_detach_kernel_driver(dev_handle, 1)) < 0) {
fprintf(stderr, "ipad_charge: Set auto detach failed: error %d [%s]\n", ret, libusb_strerror(ret));
goto out_close;
}
fprintf(stderr, "ipad_charge: Set device to auto detach\n");

int bInterfaceNumber = 0;
// Original code assumes the bInterfaceNumber is always 0, for me it turned out to be 2.
// You can use lsusb to find out which interface numbers are available.
if ((ret = libusb_claim_interface(dev_handle, bInterfaceNumber)) < 0) {
int retFor0 = ret;
bInterfaceNumber = 2;
if ((ret = libusb_claim_interface(dev_handle, 2)) < 0) {
fprintf(stderr, "ipad_charge: Unable to claim interface 0: error %d [%s]\n", retFor0, libusb_strerror(retFor0));
fprintf(stderr, "ipad_charge: Unable to claim interface 2: error %d [%s]\n", ret, libusb_strerror(ret));
goto out_close;
}
}
fprintf(stderr, "ipad_charge: Claimed interface %d\n", bInterfaceNumber);


// the 3rd and 4th numbers are the extra current in mA that the Apple device may draw in suspend state.
// Originally, the 4th was 0x6400, or 25600mA. I believe this was a bug and they meant 0x640, or 1600 mA which would be the max
// for the MFi spec. Also the typical values for the 3nd listed in the MFi spec are 0, 100, 500 so I chose 500 for that.
// And changed it to decimal to be clearer.
if ((ret = libusb_control_transfer(dev_handle, CTRL_OUT, 0x40, 500, enable ? 1600 : 0, NULL, 0, 2000)) < 0) {
fprintf(stderr, "ipad_charge: unable to send command: error %d\n", ret);
fprintf(stderr, "ipad_charge: %s\n", libusb_strerror(ret));
fprintf(stderr, "ipad_charge: Unable to send command: error %d [%s]\n", ret, libusb_strerror(ret));
goto out_release;
}

ret = 0;

out_release:
libusb_release_interface(dev_handle, 0);
libusb_release_interface(dev_handle, bInterfaceNumber);
out_close:
libusb_close(dev_handle);

Expand Down Expand Up @@ -168,7 +183,7 @@ int main(int argc, char *argv[]) {
|| desc.idProduct == PRODUCT_IPHONE_4S
|| desc.idProduct == PRODUCT_IPHONE_5
|| desc.idProduct == PRODUCT_IPAD4)) {

fprintf(stdout, "ipad_charge: Found iPad (bus number= %d, port = %d, address = %d)\n", libusb_get_bus_number(dev), libusb_get_port_number(dev), libusb_get_device_address(dev));
if (set_charging_mode(dev, enable) < 0)
fprintf(stderr, "ipad_charge: error setting charge mode\n");
else
Expand All @@ -180,9 +195,10 @@ int main(int argc, char *argv[]) {
if (count < 1) {
fprintf(stderr, "ipad_charge: no such device or an error occured\n");
ret = 3;
} else
ret = 0;

} else {
fprintf(stderr, "ipad_charge: Charging %d devices\n", count);
ret = 0;
}
libusb_free_device_list(devs, 1);
out_exit:
libusb_exit(NULL);
Expand Down