I was just saying that I had purchased an OTG adapter, but could take a look into something for Apple.You would need a lightning cable.
Implying, I usually find good deals.
I was just saying that I had purchased an OTG adapter, but could take a look into something for Apple.You would need a lightning cable.
//
// USB.mm
// iOUSB
//
// Created by Brandon on 2018-05-26.
// Copyright © 2018 XIO. All rights reserved.
//
#import "USB.h"
#import <IOKit/IOKitLib.h>
#import <IOKit/usb/IOUSBLib.h>
#import <IOKit/IOCFPlugIn.h>
#define kNintendoSwitchVendorID 0x0955
#define kNintendoSwitchProductID 0x7321
@implementation USB
- (NSArray<NSString *> *)getUSBDevices {
NSMutableArray *strings = [[NSMutableArray alloc] init];
CFMutableDictionaryRef matchingDict;
io_iterator_t iter;
kern_return_t kr;
io_service_t device;
matchingDict = IOServiceMatching("IOUSBHostDevice"); //kIOUSBDeviceClassName for OSX but "IOUSBHostDevice" for iOS..
if (matchingDict == NULL)
{
return nil;
}
//Add Nintendo Switch
long usbVendor = kNintendoSwitchVendorID;
long usbProduct = kNintendoSwitchProductID;
CFNumberRef numberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &usbVendor);
CFDictionarySetValue(matchingDict, CFSTR(kUSBVendorID), numberRef);
CFRelease(numberRef);
// Create a CFNumber for the idProduct and set the value in the dictionary
numberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &usbProduct);
CFDictionarySetValue(matchingDict, CFSTR(kUSBProductID), numberRef);
CFRelease(numberRef);
numberRef = NULL;
kr = IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDict, &iter);
if (kr != KERN_SUCCESS)
{
return nil;
}
while ((device = IOIteratorNext(iter)))
{
io_name_t devName;
io_name_t className;
io_string_t pathName;
io_string_t planeName;
IORegistryEntryGetName(device, devName);
IOObjectGetClass(device, className);
IORegistryEntryGetPath(device, kIOServicePlane, pathName);
IORegistryEntryGetPath(device, kIOUSBPlane, planeName);
[strings addObject:[NSString stringWithFormat:@"Device Name: %s", devName]];
[strings addObject:[NSString stringWithFormat:@"Device Class: %s", className]];
[strings addObject:[NSString stringWithFormat:@"Device Plane: %s", pathName]];
[strings addObject:[NSString stringWithFormat:@"Device Path: %s", planeName]];
[strings addObject:@"\n"];
if ([[NSString stringWithUTF8String:devName] isEqualToString:@"APX"]) {
int vendorId = [self getDeviceVendorId:device];
int productId = [self getDeviceProductId:device];
NSString *serialNumber = [self getDeviceSerialNumber:device];
NSString *manufacturer = [self getDeviceManufacturer:device];
[strings addObject:[NSString stringWithFormat:@"VendorID: %04X", vendorId]];
[strings addObject:[NSString stringWithFormat:@"ProductID: %04X", productId]];
[strings addObject:[NSString stringWithFormat:@"Device Serial Number: %@", serialNumber]];
[strings addObject:[NSString stringWithFormat:@"Device Manufacturer: %@", manufacturer]];
}
IOObjectRelease(device);
}
IOObjectRelease(iter);
return strings;
}
- (int)getDeviceVendorId:(io_service_t)device {
return [self getUSBProperty:device propertyName:@"idVendor"];
}
- (int)getDeviceProductId:(io_service_t)device {
return [self getUSBProperty:device propertyName:@"idProduct"];
}
- (NSString *)getDeviceSerialNumber:(io_service_t)device {
IOUSBDeviceInterface182 **deviceInterface = [self getDeviceInterface:device];
if (deviceInterface) {
UInt8 index;
(*deviceInterface)->USBGetSerialNumberStringIndex(deviceInterface, &index);
return [self getDeviceStringDescriptor:deviceInterface index:index];
}
return nil;
}
- (NSString *)getDeviceManufacturer:(io_service_t)device {
IOUSBDeviceInterface182 **deviceInterface = [self getDeviceInterface:device];
if (deviceInterface) {
UInt8 index;
(*deviceInterface)->USBGetManufacturerStringIndex(deviceInterface, &index);
return [self getDeviceStringDescriptor:deviceInterface index:index];
}
return nil;
}
/// MARK: -
- (int)getUSBProperty:(io_service_t)device propertyName:(NSString *)propertyName {
CFNumberRef number = (CFNumberRef)IORegistryEntryCreateCFProperty(device, (__bridge CFStringRef)(propertyName), kCFAllocatorDefault, 0);
int value = 0;
CFNumberGetValue(number, kCFNumberSInt32Type, &value);
CFRelease(number);
return value;
}
- (IOUSBDeviceInterface182 **)getDeviceInterface:(io_service_t)device {
kern_return_t result;
SInt32 score;
IOCFPlugInInterface **plugin = nil;
result = IOCreatePlugInInterfaceForService(device, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &plugin, &score);
if (result != KERN_SUCCESS)
{
return nil;
}
IOUSBDeviceInterface182 **deviceInterface = nil;
result = (*plugin)->QueryInterface(plugin, CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID182), (void **)&deviceInterface);
if (result != KERN_SUCCESS)
{
IODestroyPlugInInterface(plugin);
return nil;
}
IODestroyPlugInInterface(plugin);
return deviceInterface;
}
- (NSString *)getDeviceStringDescriptor:(IOUSBDeviceInterface182 **)deviceInterface index:(uint8_t)index {
UInt8 requestBuffer[256];
IOUSBDevRequest request = {
.bmRequestType = USBmakebmRequestType(kUSBIn, kUSBStandard, kUSBDevice),
.bRequest = kUSBRqGetDescriptor,
.wValue = (kUSBStringDesc << 8) | index,
.wIndex = 0x409, //English
.wLength = sizeof(requestBuffer),
.pData = requestBuffer
};
kern_return_t result;
result = (*deviceInterface)->DeviceRequest(deviceInterface, &request);
if (result != KERN_SUCCESS)
{
return nil;
}
int strLength = requestBuffer[0] - 2;
CFStringRef serialNumberString = CFStringCreateWithBytes(kCFAllocatorDefault, &requestBuffer[2], strLength, kCFStringEncodingUTF16LE, false);
return (__bridge NSString *)serialNumberString;
}
@end
https://imgur.com/a/joYfxgA
I am able to talk to the device interface.. What I can't figure out is how to keep it connected long enough so I can upload a payload.. Notice from the above link I have a screenshot of the terminal where I had to run the same command like 5 times before it showed up again.. It shows up, then disconnects, then shows up, then disconnects (seems to stay connected for about 3 seconds.. possibly my cord but I doubt it).
However, I am able to get the Switch USB port access on the device itself intermittently.. When I actually get access to it, I can upload files to the switch (possibly before it disconnects again).
Seems a hell of a lot harder than Android.. that's for sure.. but it's not impossible. Just takes time.
The new code looks like (uses IOKit.framework which ships with iOS and OSX):
Code:// // USB.mm // iOUSB // // Created by Brandon on 2018-05-26. // Copyright © 2018 XIO. All rights reserved. // #import "USB.h" #import <IOKit/IOKitLib.h> #import <IOKit/usb/IOUSBLib.h> #import <IOKit/IOCFPlugIn.h> #define kNintendoSwitchVendorID 0x0955 #define kNintendoSwitchProductID 0x7321 @implementation USB - (NSArray<NSString *> *)getUSBDevices { NSMutableArray *strings = [[NSMutableArray alloc] init]; CFMutableDictionaryRef matchingDict; io_iterator_t iter; kern_return_t kr; io_service_t device; matchingDict = IOServiceMatching("IOUSBHostDevice"); //kIOUSBDeviceClassName for OSX but "IOUSBHostDevice" for iOS.. if (matchingDict == NULL) { return nil; } //Add Nintendo Switch long usbVendor = kNintendoSwitchVendorID; long usbProduct = kNintendoSwitchProductID; CFNumberRef numberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &usbVendor); CFDictionarySetValue(matchingDict, CFSTR(kUSBVendorID), numberRef); CFRelease(numberRef); // Create a CFNumber for the idProduct and set the value in the dictionary numberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &usbProduct); CFDictionarySetValue(matchingDict, CFSTR(kUSBProductID), numberRef); CFRelease(numberRef); numberRef = NULL; kr = IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDict, &iter); if (kr != KERN_SUCCESS) { return nil; } while ((device = IOIteratorNext(iter))) { io_name_t devName; io_name_t className; io_string_t pathName; io_string_t planeName; IORegistryEntryGetName(device, devName); IOObjectGetClass(device, className); IORegistryEntryGetPath(device, kIOServicePlane, pathName); IORegistryEntryGetPath(device, kIOUSBPlane, planeName); [strings addObject:[NSString stringWithFormat:@"Device Name: %s", devName]]; [strings addObject:[NSString stringWithFormat:@"Device Class: %s", className]]; [strings addObject:[NSString stringWithFormat:@"Device Plane: %s", pathName]]; [strings addObject:[NSString stringWithFormat:@"Device Path: %s", planeName]]; [strings addObject:@"\n"]; if ([[NSString stringWithUTF8String:devName] isEqualToString:@"APX"]) { int vendorId = [self getDeviceVendorId:device]; int productId = [self getDeviceProductId:device]; NSString *serialNumber = [self getDeviceSerialNumber:device]; NSString *manufacturer = [self getDeviceManufacturer:device]; [strings addObject:[NSString stringWithFormat:@"VendorID: %04X", vendorId]]; [strings addObject:[NSString stringWithFormat:@"ProductID: %04X", productId]]; [strings addObject:[NSString stringWithFormat:@"Device Serial Number: %@", serialNumber]]; [strings addObject:[NSString stringWithFormat:@"Device Manufacturer: %@", manufacturer]]; } IOObjectRelease(device); } IOObjectRelease(iter); return strings; } - (int)getDeviceVendorId:(io_service_t)device { return [self getUSBProperty:device propertyName:@"idVendor"]; } - (int)getDeviceProductId:(io_service_t)device { return [self getUSBProperty:device propertyName:@"idProduct"]; } - (NSString *)getDeviceSerialNumber:(io_service_t)device { IOUSBDeviceInterface182 **deviceInterface = [self getDeviceInterface:device]; if (deviceInterface) { UInt8 index; (*deviceInterface)->USBGetSerialNumberStringIndex(deviceInterface, &index); return [self getDeviceStringDescriptor:deviceInterface index:index]; } return nil; } - (NSString *)getDeviceManufacturer:(io_service_t)device { IOUSBDeviceInterface182 **deviceInterface = [self getDeviceInterface:device]; if (deviceInterface) { UInt8 index; (*deviceInterface)->USBGetManufacturerStringIndex(deviceInterface, &index); return [self getDeviceStringDescriptor:deviceInterface index:index]; } return nil; } /// MARK: - - (int)getUSBProperty:(io_service_t)device propertyName:(NSString *)propertyName { CFNumberRef number = (CFNumberRef)IORegistryEntryCreateCFProperty(device, (__bridge CFStringRef)(propertyName), kCFAllocatorDefault, 0); int value = 0; CFNumberGetValue(number, kCFNumberSInt32Type, &value); CFRelease(number); return value; } - (IOUSBDeviceInterface182 **)getDeviceInterface:(io_service_t)device { kern_return_t result; SInt32 score; IOCFPlugInInterface **plugin = nil; result = IOCreatePlugInInterfaceForService(device, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &plugin, &score); if (result != KERN_SUCCESS) { return nil; } IOUSBDeviceInterface182 **deviceInterface = nil; result = (*plugin)->QueryInterface(plugin, CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID182), (void **)&deviceInterface); if (result != KERN_SUCCESS) { IODestroyPlugInInterface(plugin); return nil; } IODestroyPlugInInterface(plugin); return deviceInterface; } - (NSString *)getDeviceStringDescriptor:(IOUSBDeviceInterface182 **)deviceInterface index:(uint8_t)index { UInt8 requestBuffer[256]; IOUSBDevRequest request = { .bmRequestType = USBmakebmRequestType(kUSBIn, kUSBStandard, kUSBDevice), .bRequest = kUSBRqGetDescriptor, .wValue = (kUSBStringDesc << 8) | index, .wIndex = 0x409, //English .wLength = sizeof(requestBuffer), .pData = requestBuffer }; kern_return_t result; result = (*deviceInterface)->DeviceRequest(deviceInterface, &request); if (result != KERN_SUCCESS) { return nil; } int strLength = requestBuffer[0] - 2; CFStringRef serialNumberString = CFStringCreateWithBytes(kCFAllocatorDefault, &requestBuffer[2], strLength, kCFStringEncodingUTF16LE, false); return (__bridge NSString *)serialNumberString; } @end
So yeah.. I have access to the USB port and can talk to it on iOS (tested on 10.3.3).. but I dunno where to go from there or how to get the device to stop disconnecting.. Perhaps I have to "open" the device to keep it connected.. Not sure yet.
Cydia Impactor signs IPAs as part of the install process. It's all very seamless. You just use an Apple ID and an app password. no need for dev accounts UDIDs or Jailbreaks.Unless you are Jailbroken the IPA file has to be signed by a certificate associated with a provisioning profile that has your device's UDID. These developer certificates are handed out by Apple.
Try setting up a quick thing where it just says "Online" and constantly updates it and changes it to Offline accordingly, just to eliminate the idea of maybe a command is shutting it offhttps://imgur.com/a/joYfxgA
I am able to talk to the device interface.. What I can't figure out is how to keep it connected long enough so I can upload a payload.. Notice from the above link I have a screenshot of the terminal where I had to run the same command like 5 times before it showed up again.. It shows up, then disconnects, then shows up, then disconnects (seems to stay connected for about 3 seconds.. possibly my cord but I doubt it).
However, I am able to get the Switch USB port access on the device itself intermittently.. When I actually get access to it, I can upload files to the switch (possibly before it disconnects again).
Seems a hell of a lot harder than Android.. that's for sure.. but it's not impossible. Just takes time.
The new code looks like (uses IOKit.framework which ships with iOS and OSX):
Code:// // USB.mm // iOUSB // // Created by Brandon on 2018-05-26. // Copyright © 2018 XIO. All rights reserved. // #import "USB.h" #import <IOKit/IOKitLib.h> #import <IOKit/usb/IOUSBLib.h> #import <IOKit/IOCFPlugIn.h> #define kNintendoSwitchVendorID 0x0955 #define kNintendoSwitchProductID 0x7321 @implementation USB - (NSArray<NSString *> *)getUSBDevices { NSMutableArray *strings = [[NSMutableArray alloc] init]; CFMutableDictionaryRef matchingDict; io_iterator_t iter; kern_return_t kr; io_service_t device; matchingDict = IOServiceMatching("IOUSBHostDevice"); //kIOUSBDeviceClassName for OSX but "IOUSBHostDevice" for iOS.. if (matchingDict == NULL) { return nil; } //Add Nintendo Switch long usbVendor = kNintendoSwitchVendorID; long usbProduct = kNintendoSwitchProductID; CFNumberRef numberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &usbVendor); CFDictionarySetValue(matchingDict, CFSTR(kUSBVendorID), numberRef); CFRelease(numberRef); // Create a CFNumber for the idProduct and set the value in the dictionary numberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &usbProduct); CFDictionarySetValue(matchingDict, CFSTR(kUSBProductID), numberRef); CFRelease(numberRef); numberRef = NULL; kr = IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDict, &iter); if (kr != KERN_SUCCESS) { return nil; } while ((device = IOIteratorNext(iter))) { io_name_t devName; io_name_t className; io_string_t pathName; io_string_t planeName; IORegistryEntryGetName(device, devName); IOObjectGetClass(device, className); IORegistryEntryGetPath(device, kIOServicePlane, pathName); IORegistryEntryGetPath(device, kIOUSBPlane, planeName); [strings addObject:[NSString stringWithFormat:@"Device Name: %s", devName]]; [strings addObject:[NSString stringWithFormat:@"Device Class: %s", className]]; [strings addObject:[NSString stringWithFormat:@"Device Plane: %s", pathName]]; [strings addObject:[NSString stringWithFormat:@"Device Path: %s", planeName]]; [strings addObject:@"\n"]; if ([[NSString stringWithUTF8String:devName] isEqualToString:@"APX"]) { int vendorId = [self getDeviceVendorId:device]; int productId = [self getDeviceProductId:device]; NSString *serialNumber = [self getDeviceSerialNumber:device]; NSString *manufacturer = [self getDeviceManufacturer:device]; [strings addObject:[NSString stringWithFormat:@"VendorID: %04X", vendorId]]; [strings addObject:[NSString stringWithFormat:@"ProductID: %04X", productId]]; [strings addObject:[NSString stringWithFormat:@"Device Serial Number: %@", serialNumber]]; [strings addObject:[NSString stringWithFormat:@"Device Manufacturer: %@", manufacturer]]; } IOObjectRelease(device); } IOObjectRelease(iter); return strings; } - (int)getDeviceVendorId:(io_service_t)device { return [self getUSBProperty:device propertyName:@"idVendor"]; } - (int)getDeviceProductId:(io_service_t)device { return [self getUSBProperty:device propertyName:@"idProduct"]; } - (NSString *)getDeviceSerialNumber:(io_service_t)device { IOUSBDeviceInterface182 **deviceInterface = [self getDeviceInterface:device]; if (deviceInterface) { UInt8 index; (*deviceInterface)->USBGetSerialNumberStringIndex(deviceInterface, &index); return [self getDeviceStringDescriptor:deviceInterface index:index]; } return nil; } - (NSString *)getDeviceManufacturer:(io_service_t)device { IOUSBDeviceInterface182 **deviceInterface = [self getDeviceInterface:device]; if (deviceInterface) { UInt8 index; (*deviceInterface)->USBGetManufacturerStringIndex(deviceInterface, &index); return [self getDeviceStringDescriptor:deviceInterface index:index]; } return nil; } /// MARK: - - (int)getUSBProperty:(io_service_t)device propertyName:(NSString *)propertyName { CFNumberRef number = (CFNumberRef)IORegistryEntryCreateCFProperty(device, (__bridge CFStringRef)(propertyName), kCFAllocatorDefault, 0); int value = 0; CFNumberGetValue(number, kCFNumberSInt32Type, &value); CFRelease(number); return value; } - (IOUSBDeviceInterface182 **)getDeviceInterface:(io_service_t)device { kern_return_t result; SInt32 score; IOCFPlugInInterface **plugin = nil; result = IOCreatePlugInInterfaceForService(device, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &plugin, &score); if (result != KERN_SUCCESS) { return nil; } IOUSBDeviceInterface182 **deviceInterface = nil; result = (*plugin)->QueryInterface(plugin, CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID182), (void **)&deviceInterface); if (result != KERN_SUCCESS) { IODestroyPlugInInterface(plugin); return nil; } IODestroyPlugInInterface(plugin); return deviceInterface; } - (NSString *)getDeviceStringDescriptor:(IOUSBDeviceInterface182 **)deviceInterface index:(uint8_t)index { UInt8 requestBuffer[256]; IOUSBDevRequest request = { .bmRequestType = USBmakebmRequestType(kUSBIn, kUSBStandard, kUSBDevice), .bRequest = kUSBRqGetDescriptor, .wValue = (kUSBStringDesc << 8) | index, .wIndex = 0x409, //English .wLength = sizeof(requestBuffer), .pData = requestBuffer }; kern_return_t result; result = (*deviceInterface)->DeviceRequest(deviceInterface, &request); if (result != KERN_SUCCESS) { return nil; } int strLength = requestBuffer[0] - 2; CFStringRef serialNumberString = CFStringCreateWithBytes(kCFAllocatorDefault, &requestBuffer[2], strLength, kCFStringEncodingUTF16LE, false); return (__bridge NSString *)serialNumberString; } @end
So yeah.. I have access to the USB port and can talk to it on iOS (tested on 10.3.3).. but I dunno where to go from there or how to get the device to stop disconnecting.. Perhaps I have to "open" the device to keep it connected.. Not sure yet.
ill have to see if theres any official or otherwise libraries to access usb devices, even if it would only work on jailbroken devices, thats better than nothing
weve already discussed that side loading isn't an issue, because of Cydia impactor. We're just waiting for someone to make the program. Hopefully @JustBrandonT can put something togetherStock iOS does support interfacing with USB devices. There are existing, officially supported frameworks for reading and writing to USB storage. It would probably need some tweaks to allow streaming executable data the way RCM requires, but nothing too grueling. You would definitely need a firm understanding of how existing implementations work, but it has to be doable.
It's not so much a matter of whether or not the hardware can do it. It's more just that Apple would never allow it on the App Store, and you don't have a lot of options for sideloading apps on iOS.
I think that cable should be good enough, but idkGot an iPhone X jailbroken on 11.1.2 would love to see this made. Regarding some of the earlier posts, would I need to cop an OTG adapter? I have the official 2m USB-C lightning cable from Apple
iPhone master race btw
I think that cable should be good enough, but idk
https://imgur.com/a/joYfxgA
I am able to talk to the device interface.. What I can't figure out is how to keep it connected long enough so I can upload a payload.. Notice from the above link I have a screenshot of the terminal where I had to run the same command like 5 times before it showed up again.. It shows up, then disconnects, then shows up, then disconnects (seems to stay connected for about 3 seconds.. possibly my cord but I doubt it).
However, I am able to get the Switch USB port access on the device itself intermittently.. When I actually get access to it, I can upload files to the switch (possibly before it disconnects again).
Seems a hell of a lot harder than Android.. that's for sure.. but it's not impossible. Just takes time.
The new code looks like (uses IOKit.framework which ships with iOS and OSX):
-- snip --
So yeah.. I have access to the USB port and can talk to it on iOS (tested on 10.3.3).. but I dunno where to go from there or how to get the device to stop disconnecting.. Perhaps I have to "open" the device to keep it connected.. Not sure yet.
Just upgrade to an Android, or use Windows. Best methods.
Don't be so hostile bro. >w>Are you going to buy us all new phones and new Windows computers? Take your advice and stick it where the Sun don't shine otherwise.
I actually have an Intel Edison single board computer and a RPi Zero I can run fusee gelee on, but I work as an iPhone developer, so I'm interested in getting this working just because. So shut it.
Don't be so hostile bro. >w>
I just don't see why people would waste their time trying to make closed hardware and software do shit it was never intended to do, when people usually have old Android phones laying around in drawers, not being used that would be perfect for this stuff.
I am not a expert on IOS devices so don't quote me on this, but in terms of HW the lighting port does support XHCI. In terms of software though, I don't believe IOS offers the necessary control, perhaps a jailbroken device, but I doubt stock IOS would allow it.
Thats exactly my problem? autoRCM is letting anyone soft-brick their switch like its a good thing.
So yeah.. I have access to the USB port and can talk to it on iOS (tested on 10.3.3).. but I dunno where to go from there or how to get the device to stop disconnecting.. Perhaps I have to "open" the device to keep it connected.. Not sure yet.
but it only lasts a week and then you have to reinstall?! there was a huge hook to cydia impactor that I cannot remember.Cydia Impactor signs IPAs as part of the install process. It's all very seamless. You just use an Apple ID and an app password. no need for dev accounts UDIDs or Jailbreaks.
but it only lasts a week and then you have to reinstall?! there was a huge hook to cydia impactor that I cannot remember.
As iPhone user, not possible unless it is jailbroken, so jailbreaking is getting more painful and difficult nowadays, damn to Apple. I do like iPhone but not fan of Apple's action.