Commit a129731f authored by David Helkowski's avatar David Helkowski
Browse files

Initial version

Working detection of IOS device connect and disconnect.

There is also support for sending the magic usb command that enables streaming video through USB, but it is not enabled because it is not useful in and of itself without additional libraries to read out the h264 data.
parent cfd23144
.DS_Store
project.xcworkspace/
xcuserdata/
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 50;
objects = {
/* Begin PBXBuildFile section */
6D3B3CBA2328522B000AE6D8 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D3B3CB92328522B000AE6D8 /* main.cpp */; };
6D3B3CC223285FA3000AE6D8 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D3B3CC123285FA3000AE6D8 /* IOKit.framework */; };
6D3B3CC423285FA9000AE6D8 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D3B3CC323285FA9000AE6D8 /* CoreFoundation.framework */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
6D3B3CB42328522B000AE6D8 /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = /usr/share/man/man1/;
dstSubfolderSpec = 0;
files = (
);
runOnlyForDeploymentPostprocessing = 1;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
6D3B3CB62328522B000AE6D8 /* osx_ios_device_trigger */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = osx_ios_device_trigger; sourceTree = BUILT_PRODUCTS_DIR; };
6D3B3CB92328522B000AE6D8 /* main.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; };
6D3B3CC123285FA3000AE6D8 /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; };
6D3B3CC323285FA9000AE6D8 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
6D3B3CB32328522B000AE6D8 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
6D3B3CC423285FA9000AE6D8 /* CoreFoundation.framework in Frameworks */,
6D3B3CC223285FA3000AE6D8 /* IOKit.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
6D3B3CAD2328522B000AE6D8 = {
isa = PBXGroup;
children = (
6D3B3CB82328522B000AE6D8 /* osx_ios_device_trigger */,
6D3B3CB72328522B000AE6D8 /* Products */,
6D3B3CC023285FA3000AE6D8 /* Frameworks */,
);
sourceTree = "<group>";
};
6D3B3CB72328522B000AE6D8 /* Products */ = {
isa = PBXGroup;
children = (
6D3B3CB62328522B000AE6D8 /* osx_ios_device_trigger */,
);
name = Products;
sourceTree = "<group>";
};
6D3B3CB82328522B000AE6D8 /* osx_ios_device_trigger */ = {
isa = PBXGroup;
children = (
6D3B3CB92328522B000AE6D8 /* main.cpp */,
);
path = osx_ios_device_trigger;
sourceTree = "<group>";
};
6D3B3CC023285FA3000AE6D8 /* Frameworks */ = {
isa = PBXGroup;
children = (
6D3B3CC323285FA9000AE6D8 /* CoreFoundation.framework */,
6D3B3CC123285FA3000AE6D8 /* IOKit.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
6D3B3CB52328522B000AE6D8 /* osx_ios_device_trigger */ = {
isa = PBXNativeTarget;
buildConfigurationList = 6D3B3CBD2328522B000AE6D8 /* Build configuration list for PBXNativeTarget "osx_ios_device_trigger" */;
buildPhases = (
6D3B3CB22328522B000AE6D8 /* Sources */,
6D3B3CB32328522B000AE6D8 /* Frameworks */,
6D3B3CB42328522B000AE6D8 /* CopyFiles */,
);
buildRules = (
);
dependencies = (
);
name = osx_ios_device_trigger;
productName = osx_ios_device_trigger;
productReference = 6D3B3CB62328522B000AE6D8 /* osx_ios_device_trigger */;
productType = "com.apple.product-type.tool";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
6D3B3CAE2328522B000AE6D8 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1030;
ORGANIZATIONNAME = "David Helkowski";
TargetAttributes = {
6D3B3CB52328522B000AE6D8 = {
CreatedOnToolsVersion = 10.3;
};
};
};
buildConfigurationList = 6D3B3CB12328522B000AE6D8 /* Build configuration list for PBXProject "osx_ios_device_trigger" */;
compatibilityVersion = "Xcode 9.3";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
);
mainGroup = 6D3B3CAD2328522B000AE6D8;
productRefGroup = 6D3B3CB72328522B000AE6D8 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
6D3B3CB52328522B000AE6D8 /* osx_ios_device_trigger */,
);
};
/* End PBXProject section */
/* Begin PBXSourcesBuildPhase section */
6D3B3CB22328522B000AE6D8 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
6D3B3CBA2328522B000AE6D8 /* main.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
6D3B3CBB2328522B000AE6D8 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "Mac Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.14;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
};
name = Debug;
};
6D3B3CBC2328522B000AE6D8 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "Mac Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.14;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
SDKROOT = macosx;
};
name = Release;
};
6D3B3CBE2328522B000AE6D8 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = QNYBTNP38J;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Debug;
};
6D3B3CBF2328522B000AE6D8 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = QNYBTNP38J;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
6D3B3CB12328522B000AE6D8 /* Build configuration list for PBXProject "osx_ios_device_trigger" */ = {
isa = XCConfigurationList;
buildConfigurations = (
6D3B3CBB2328522B000AE6D8 /* Debug */,
6D3B3CBC2328522B000AE6D8 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
6D3B3CBD2328522B000AE6D8 /* Build configuration list for PBXNativeTarget "osx_ios_device_trigger" */ = {
isa = XCConfigurationList;
buildConfigurations = (
6D3B3CBE2328522B000AE6D8 /* Debug */,
6D3B3CBF2328522B000AE6D8 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 6D3B3CAE2328522B000AE6D8 /* Project object */;
}
#include <CoreFoundation/CoreFoundation.h>
#include <IOKit/IOKitLib.h>
#include <IOKit/IOMessage.h>
#include <IOKit/IOCFPlugIn.h>
#include <IOKit/usb/IOUSBLib.h>
#include<set>
std::set<UInt16> prodIds = {
0x1290,0x1292,0x1294,0x1297,0x129a,0x129c,
0x129f,0x12a0,0x12a2,0x12a3,0x12a4,0x12a5,
0x12a6,0x12a8,0x12a9,0x12ab
};
#include<map>
const std::map<UInt16,const char *> prodMap = {
{0x1290,"iPhone"},
{0x1292,"iPhone 3G"},
{0x1294,"iPhone 3GS"},
{0x1297,"iPhone 4"},
{0x129a,"iPad"},
{0x129c,"iPhone 4 CDMA"},
{0x129f,"iPad 2"},
{0x12a0,"iPhone 4S"},
{0x12a2,"iPad 2 3G"},
{0x12a3,"iPad 2 CDMA"},
{0x12a4,"iPad 3 wifi"},
{0x12a5,"iPad 3 CDMA"},
{0x12a6,"iPad 3 3G"},
{0x12a8,"iPhone 5-8/X"},
{0x12a9,"iPad 2"},
{0x12ab,"iPad 4 Mini"}
};
typedef struct USBDeviceInfo {
io_object_t notification;
IOUSBDeviceInterface942 **interface;
IOUSBInterfaceInterface942 **iface2; // interface squared
CFStringRef name;
UInt32 locationID;
} USBDeviceInfo;
static IONotificationPortRef globalDevicePort;
static IONotificationPortRef globalInterfacePort;
static io_iterator_t globalDeviceIter;
static io_iterator_t globalInterfaceIter;
static bool gdone = false;
// Recieves kIOGeneralInterest notifications
void DeviceNotification(void *voidDevInfo, io_service_t service, natural_t messageType, void *messageArgument) {
//kern_return_t kres;
USBDeviceInfo *devInfo = (USBDeviceInfo *) voidDevInfo;
if( messageType == kIOMessageServiceIsTerminated ) { // See IOMessage.h for other types
fprintf(stderr, "Device removed\n");
fprintf(stderr, " Name: "); CFShow( devInfo->name );
fprintf(stderr, " LocationID: 0x%lx.\n\n", (unsigned long) devInfo->locationID);
// Cleanup
CFRelease( devInfo->name );
if( devInfo->interface ) /*kr = */(*devInfo->interface)->Release( devInfo->interface );
/*kres = */IOObjectRelease( devInfo->notification );
free(devInfo);
}
}
IOUSBDevRequest * magicControlRequest() {
IOUSBDevRequest *req = (IOUSBDevRequest *) malloc( sizeof( IOUSBDevRequest ) );
req->bmRequestType = 0x40;
req->bRequest = 82;
req->wValue = 0x0;
req->wIndex = 0x2;
req->wLength = 0x0;
req->wLenDone = 0x0;
req->pData = 0x00;
return req;
}
void InterfaceAdded(void *refCon, io_iterator_t iterator) {
kern_return_t kres;
io_service_t usbInterface;
while( ( usbInterface = IOIteratorNext( iterator ) ) ) {
//printf("Interface added\n");
IOCFPlugInInterface **plugin = NULL;
{ // Get plugin interface to communicate to kernel
SInt32 score;
kres = IOCreatePlugInInterfaceForService( usbInterface, kIOUSBInterfaceUserClientTypeID, kIOCFPlugInInterfaceID, &plugin, &score );
if( ( kIOReturnSuccess != kres ) || !plugin ) {
//fprintf( stderr, "IOCreatePlugInInterfaceForService returned 0x%08x.\n", kres );
continue;
}
}
//printf(" Got plugin\n");
IOUSBInterfaceInterface942 **iface2; // interface squared
{
kres = (*plugin)->QueryInterface( plugin, CFUUIDGetUUIDBytes(kIOUSBInterfaceInterfaceID), (LPVOID *)&iface2 );
if( KERN_SUCCESS != kres ) { fprintf( stderr, "iface2 failed 0x%08x.\n", kres ); }
else { /*printf(" Got iface2\n");*/ }
}
IOReturn kr;
UInt16 devVendor = 0x0000;
UInt16 devProduct = 0x0000;
UInt8 intfClass = 0x00;
UInt8 intfSubClass = 0x00;
kr = (*iface2)->GetInterfaceClass(iface2, &intfClass);
kr = (*iface2)->GetInterfaceSubClass(iface2, &intfSubClass);
kr = (*iface2)->GetDeviceVendor(iface2, &devVendor);
kr = (*iface2)->GetDeviceProduct(iface2, &devProduct);
if( devVendor != 0x5ac || !prodIds.count( devProduct ) ) {
(*plugin)->Release(plugin);
continue;
}
printf("Interface added\n");
printf(" class: %02x\n", intfClass);
printf(" subclass: %02x\n", intfSubClass);
printf(" Vendor: %04x\n", devVendor);
printf(" Product: %04x\n", devProduct);
if( !gdone && intfClass == 0x0a && intfSubClass == 0x00 ) {
gdone = 1;
if( KERN_SUCCESS != kres ) { fprintf( stderr, "open interface failed: 0x%08x.\n", kres ); }
else {
/*IOUSBDevRequest *req = magicControlRequest();
(*iface2)->ControlRequest( iface2, 0x00, req );
if( KERN_SUCCESS != kres ) { fprintf( stderr, "control request failed: 0x%08x.\n", kres ); }
else {
printf(" Sent control request\n");
io_service_t USBdevice = 0;
IOCFPlugInInterface **plugin;
IOUSBDeviceInterface942 **dev;
SInt32 score;
kr = (*iface2)->GetDevice(iface2, &USBdevice);
if( KERN_SUCCESS != kres ) { fprintf( stderr, "get usbdevice failed: 0x%08x.\n", kres ); }
kr = IOCreatePlugInInterfaceForService(USBdevice,
kIOUSBDeviceUserClientTypeID,
kIOCFPlugInInterfaceID,
&plugin,
&score);
if( KERN_SUCCESS != kres ) { fprintf( stderr, "get plugin failed: 0x%08x.\n", kres ); }
kr = (*plugin)->QueryInterface(plugin,
CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID942 ),
(LPVOID *) &dev);
if( KERN_SUCCESS != kres ) { fprintf( stderr, "get device interface failed: 0x%08x.\n", kres ); }
(*plugin)->Release(plugin);
{ // Set configuration 5
UInt8 numConfig;
kres = (*dev)->GetNumberOfConfigurations( dev, &numConfig );
fprintf(stderr," Number of configs: %d\n", numConfig );
if( numConfig >= 5 ) {
IOUSBConfigurationDescriptorPtr configDesc;
kres = (*dev)->GetConfigurationDescriptorPtr(dev, 5, &configDesc);
kres = (*dev)->SetConfiguration(dev, configDesc->bConfigurationValue);
}
}
(*dev)->Release(dev);
}
free( req->pData );
free( req );*/
}
}
// Release pluginInterface
(*plugin)->Release(plugin);
}
}
// Callback from IOServiceAddMatchingNotification
void DeviceAdded(void *refCon, io_iterator_t iterator) {
kern_return_t kres;
io_service_t usbDevice;
while( ( usbDevice = IOIteratorNext( iterator ) ) ) {
// Create a blank device info struct
USBDeviceInfo *devInfo = (USBDeviceInfo *) malloc( sizeof( USBDeviceInfo ) );
bzero( devInfo, sizeof( USBDeviceInfo ) );
IOCFPlugInInterface **plugin = NULL;
{ // Get plugin interface to communicate to kernel
SInt32 score;
kres = IOCreatePlugInInterfaceForService( usbDevice, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &plugin, &score );
if( ( kIOReturnSuccess != kres ) || !plugin ) {
//fprintf( stderr, "IOCreatePlugInInterfaceForService returned 0x%08x.\n", kres );
continue;
}
}
// Get device interface; Can call routines in IOUSBLib.h against this
HRESULT res = (*plugin)->QueryInterface( plugin, CFUUIDGetUUIDBytes( kIOUSBDeviceInterfaceID942 ), (LPVOID*) &devInfo->interface );
IOUSBDeviceInterface942 **iface = devInfo->interface;
IOReturn kr;
UInt16 devVendor = 0x0000;
UInt16 devProduct = 0x0000;
UInt8 snsi = 0x00;
kr = (*iface)->GetDeviceVendor(iface, &devVendor);
kr = (*iface)->GetDeviceProduct(iface, &devProduct);
if( devVendor != 0x5ac || !prodIds.count( devProduct ) ) {
(*plugin)->Release(plugin);
continue;
}
printf("Device added\n");
{ // Get deviceName
io_name_t deviceName;
kres = IORegistryEntryGetName( usbDevice, deviceName );
if( KERN_SUCCESS != kres ) deviceName[0] = '\0';
CFStringRef deviceNameStr = CFStringCreateWithCString( kCFAllocatorDefault, deviceName, kCFStringEncodingASCII );
fprintf(stderr, " Name: "); CFShow( deviceNameStr );
devInfo->name = deviceNameStr;
}
{ // Get USB serial number
kr = (*iface)->USBGetSerialNumberStringIndex( iface, &snsi );
if( kr != kIOReturnSuccess ) {
fprintf( stderr, "Get Serial index 0x%08x.\n", kr );
}
else {
IOUSBDevRequest req;
UInt16 buffer[256];
char serial[256];
req.bmRequestType = USBmakebmRequestType(kUSBIn, kUSBStandard, kUSBDevice);
req.bRequest = kUSBRqGetDescriptor;
req.wValue = (kUSBStringDesc << 8) | snsi;
req.wIndex = 0x0409; //language ID (en-us) for serial number string
req.pData = buffer;
req.wLength = 256;//sizeof(buffer);
kr = (*iface)->DeviceRequest(iface, &req);
if( kr == kIOReturnSuccess && req.wLenDone > 0 ) {
int i, count;
// skip first word, and copy the rest to the serial string, changing shorts to bytes.
count = (req.wLenDone - 1) / 2;
for (i = 0; i < count; i++)
serial[i] = buffer[i + 1];
serial[i] = 0;
fprintf(stderr, " Serial: %s\n", serial);
}
}
}
// Release pluginInterface
(*plugin)->Release(plugin);
auto item = prodMap.find( devProduct );
const char *product = item->second;
fprintf(stderr, " Product: %s\n", product );
if( res || devInfo->interface == NULL ) { fprintf(stderr, "Failed to get device interface; res = %d.\n", (int) res); continue; }
{ // Fetch the locationID ( identifies the device )
UInt32 locationID;
kres = (*devInfo->interface)->GetLocationID( devInfo->interface, &locationID );
if( KERN_SUCCESS != kres ) { fprintf( stderr, "GetLocationID returned 0x%08x.\n", kres ); continue; }
else fprintf( stderr, " LocationID: 0x%lx\n\n", (unsigned long) locationID );
devInfo->locationID = locationID;
}
// Subscribe to kIOGeneralInterest notifications, calling back DeviceNotification; Pass along devInfo
kres = IOServiceAddInterestNotification(
globalDevicePort, // notifyPort
usbDevice, // notificationType
kIOGeneralInterest, // matching
DeviceNotification, // callback
devInfo, // callback data
&(devInfo->notification) // notification
);
if( KERN_SUCCESS != kres ) printf( "IOServiceAddInterestNotification returned 0x%08x.\n", kres );
// Release iterator
/*kres = */IOObjectRelease( usbDevice );
}
}
void SignalHandler(int sigraised) { exit(0); }
int main( int argc, const char *argv[] ) {
//long usbVendor = 0x0000;