diff options
Diffstat (limited to 'libaltos/libaltos_darwin.c')
| -rw-r--r-- | libaltos/libaltos_darwin.c | 82 | 
1 files changed, 72 insertions, 10 deletions
diff --git a/libaltos/libaltos_darwin.c b/libaltos/libaltos_darwin.c index bf3cf094..04194d9a 100644 --- a/libaltos/libaltos_darwin.c +++ b/libaltos/libaltos_darwin.c @@ -20,6 +20,9 @@  #include <IOKitLib.h>  #include <IOKit/usb/USBspec.h> +#include <IOKit/serial/IOSerialKeys.h> +#include <usb/IOUSBLib.h> +#include <usb/USBSpec.h>  #include <sys/param.h>  #include <paths.h>  #include <CFNumber.h> @@ -45,11 +48,23 @@ struct altos_list {  	int ftdi;  }; +static char * +get_cfstring(CFTypeRef string, char result[512]) +{ +	Boolean		got_string; + +	got_string = CFStringGetCString(string, result, 512, kCFStringEncodingASCII); +	if (!got_string) +		strcpy(result, "CFStringGetCString failed"); +	return result; +} +  static int  get_string(io_object_t object, CFStringRef entry, char *result, int result_len)  {  	CFTypeRef entry_as_string;  	Boolean got_string; +	char entry_string[512];  	entry_as_string = IORegistryEntrySearchCFProperty (object,  							   kIOServicePlane, @@ -62,8 +77,9 @@ get_string(io_object_t object, CFStringRef entry, char *result, int result_len)  						kCFStringEncodingASCII);  		CFRelease(entry_as_string); -		if (got_string) +		if (got_string) {  			return 1; +		}  	}  	return 0;  } @@ -73,6 +89,7 @@ get_number(io_object_t object, CFStringRef entry, int *result)  {  	CFTypeRef entry_as_number;  	Boolean got_number; +	char entry_string[512];  	entry_as_number = IORegistryEntrySearchCFProperty (object,  							   kIOServicePlane, @@ -83,8 +100,9 @@ get_number(io_object_t object, CFStringRef entry, int *result)  		got_number = CFNumberGetValue(entry_as_number,  					      kCFNumberIntType,  					      result); -		if (got_number) +		if (got_number) {  			return 1; +		}  	}  	return 0;  } @@ -93,12 +111,19 @@ PUBLIC struct altos_list *  altos_list_start(void)  {  	struct altos_list *list = calloc (sizeof (struct altos_list), 1); -	CFMutableDictionaryRef matching_dictionary = IOServiceMatching("IOUSBDevice"); +	CFMutableDictionaryRef matching_dictionary;  	io_iterator_t tdIterator;  	io_object_t tdObject;  	kern_return_t ret;  	int i; +	matching_dictionary = IOServiceMatching(kIOSerialBSDServiceValue); +	if (matching_dictionary) { +		CFDictionarySetValue(matching_dictionary, +				     CFSTR(kIOSerialBSDTypeKey), +				     CFSTR(kIOSerialBSDAllTypes)); +	} +  	ret = IOServiceGetMatchingServices(kIOMasterPortDefault, matching_dictionary, &list->iterator);  	if (ret != kIOReturnSuccess) {  		free(list); @@ -118,26 +143,63 @@ altos_ftdi_list_start(void)  	return list;  } +static io_service_t get_usb_object(io_object_t serial_device) +{ +	io_iterator_t iterator; +	io_service_t usb_device; +	io_service_t service; +	IOReturn status; + +	status = IORegistryEntryCreateIterator(serial_device, +				      kIOServicePlane, +				      kIORegistryIterateParents | kIORegistryIterateRecursively, +				      &iterator); + +	if (status != kIOReturnSuccess) +		return 0; + +	while((service = IOIteratorNext(iterator))) { +		io_name_t servicename; +		status = IORegistryEntryGetNameInPlane(service, kIOServicePlane, servicename); + +		if (status == kIOReturnSuccess && IOObjectConformsTo(service, kIOUSBDeviceClassName)) { +			IOObjectRelease(iterator); +			return service; +		} +		IOObjectRelease(service); +	} +	IOObjectRelease(iterator); +	return 0; +} +  PUBLIC int  altos_list_next(struct altos_list *list, struct altos_device *device)  { +  	io_object_t object; +	io_service_t usb_device;  	char serial_string[128];  	for (;;) {  		object = IOIteratorNext(list->iterator); -		if (!object) +		if (!object) {  			return 0; +		} + +		usb_device = get_usb_object(object); -		if (!get_number (object, CFSTR(kUSBVendorID), &device->vendor) || -		    !get_number (object, CFSTR(kUSBProductID), &device->product)) -			continue; -		if (get_string (object, CFSTR("IOCalloutDevice"), device->path, sizeof (device->path)) && -		    get_string (object, CFSTR("USB Product Name"), device->name, sizeof (device->name)) && -		    get_string (object, CFSTR("USB Serial Number"), serial_string, sizeof (serial_string))) { +		if (get_number (usb_device, CFSTR(kUSBVendorID), &device->vendor) && +		    get_number (usb_device, CFSTR(kUSBProductID), &device->product) && +		    get_string (object, CFSTR(kIOCalloutDeviceKey), device->path, sizeof (device->path)) && +		    get_string (usb_device, CFSTR(kUSBProductString), device->name, sizeof (device->name)) && +		    get_string (usb_device, CFSTR(kUSBSerialNumberString), serial_string, sizeof (serial_string))) {  			device->serial = atoi(serial_string); +			IOObjectRelease(object); +			IOObjectRelease(usb_device);  			return 1;  		} +		IOObjectRelease(object); +		IOObjectRelease(usb_device);  	}  }  | 
