У меня нет полного ответа, но программа, которая достигает того, что вы хотите, - это USB Prober, поставляется с Xcode и расположена по адресу /Developer/Applications/Utilities/USB Prober.app
. Эта программа с открытым исходным кодом, с видимым в браузере репозиторием здесь и всем проектом, включенным в этой загрузки . Я действительно нашел более старую версию более полезной, так как она доступна здесь , особенно BusProbeClass .
Все они опираются на IOKit, для которого документация Apple, похоже, очень не хватает ни по количеству, ни по качеству.
Это тяжелое чтение, но если вы посмотрите + USBProbe
, то увидите, что он получает список текущих USB-устройств, получает IOUSBDeviceInterface
с для каждого в переменной deviceIntf
, а затем отправляет их куда-то, что полезно для остальная часть программы. Если вы отметите + outputDevice: locationID:deviceNumber:
ниже в том же исходном файле, вы увидите, что GetDescriptor
может использоваться на IOUSBDeviceDescriptor
для получения свойств, включая идентификатор поставщика и продукта, комбинация которых гарантированно будет уникальны для форума разработчиков USB.
Используя поставщика и идентификатор продукта, вы можете искать любое конкретное USB-устройство. Из информации о системе моего Mac я могу сказать, что iPhone 4 имеет идентификатор продукта 0x1297 и идентификатор производителя Apple 0x05ac.
Дополнительно: от разбора этого кода, если вы удалите целую кучу проверок, что все работает успешно, и сожмете все это до демонстративного материала, то следующее - это по крайней мере проверка того, подключен ли сейчас iPhone 4 Нужно будет связать со структурой Foundation и IOKit):
#include <stdio.h>
#import <Foundation/Foundation.h>
#import <IOKit/usb/IOUSBLib.h>
#import <IOKit/IOCFPlugIn.h>
#import <mach/mach_port.h>
int main (int argc, const char * argv[])
{
// get the port through which to talk to the kernel
mach_port_t masterDevicePort;
IOMasterPort(MACH_PORT_NULL, &masterDevicePort);
// create a dictionary that describes a search
// for services provided by USB
CFDictionaryRef matchingDictionary = IOServiceMatching(kIOUSBDeviceClassName);
// get an iterator for all devices that match
// the dictionary
io_iterator_t deviceIterator;
IOServiceGetMatchingServices(
masterDevicePort,
matchingDictionary,
&deviceIterator);
// iterate through the iterator...
io_service_t ioDevice;
while((ioDevice = IOIteratorNext(deviceIterator)))
{
IOUSBDeviceInterface **deviceInterface = NULL;
IOCFPlugInInterface **ioPlugin = NULL;
SInt32 score;
// get a pointer to the device, stored to ioPlugin
IOCreatePlugInInterfaceForService(
ioDevice,
kIOUSBDeviceUserClientTypeID,
kIOCFPlugInInterfaceID,
&ioPlugin,
&score);
// ask the device for its interface
(*ioPlugin)->QueryInterface(
ioPlugin,
CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID),
(void *)&deviceInterface);
// make and issue a request to get the device descriptor
IOUSBDeviceDescriptor deviceDescriptor;
IOUSBDevRequest request;
request.bmRequestType = USBmakebmRequestType(kUSBIn, kUSBStandard, kUSBDevice);
request.bRequest = kUSBRqGetDescriptor;
request.wValue = kUSBDeviceDesc << 8;
request.wIndex = 0;
request.wLength = sizeof(deviceDescriptor);
request.pData = &deviceDescriptor;
(*deviceInterface)->DeviceRequest(deviceInterface, &request);
// now we have the device descriptor, do a little cleaning up -
// release the interface and the device
(*deviceInterface)->Release(deviceInterface);
IOObjectRelease(ioDevice);
// ensure that the values returned are in the appropriate
// byte order for this platform
CFSwapInt16LittleToHost(deviceDescriptor.idVendor);
CFSwapInt16LittleToHost(deviceDescriptor.idProduct);
// check whether we have an iPhone 4 attached
if(deviceDescriptor.idVendor == 0x05ac && deviceDescriptor.idProduct == 0x1297)
printf("iPhone 4 is connected!");
}
// clean up by releasing the device iterator
// and returning the communications port
IOObjectRelease(deviceIterator);
mach_port_deallocate(mach_task_self(), masterDevicePort);
return 0;
}
Я еще не понял, как наблюдать за изменениями в подключенных устройствах.