X-Git-Url: http://sigrok.org/gitweb/?a=blobdiff_plain;f=macosx.c;h=1a2beb06ff64a4bccb448a1bccc7e2132ee2a886;hb=276ef1b92fe0a885c4e2156feeefb29ad67fc0c4;hp=c1c5d9106387c9a595bbc149c292248dc8941637;hpb=e33dcf90a0b0e510eb990c657eab88243d0ac5fd;p=libserialport.git diff --git a/macosx.c b/macosx.c index c1c5d91..1a2beb0 100644 --- a/macosx.c +++ b/macosx.c @@ -21,20 +21,19 @@ #include "libserialport.h" #include "libserialport_internal.h" -enum sp_return get_port_details(struct sp_port *port) +SP_PRIV enum sp_return get_port_details(struct sp_port *port) { /* Description limited to 127 char, anything longer would not be user friendly anyway */ char description[128]; int bus, address, vid, pid = -1; char manufacturer[128], product[128], serial[128]; - char baddr[32]; CFMutableDictionaryRef classes; io_iterator_t iter; - io_object_t ioport; + io_object_t ioport, ioparent; CFTypeRef cf_property, cf_bus, cf_address, cf_vendor, cf_product; Boolean result; - char path[PATH_MAX]; + char path[PATH_MAX], class[16]; DEBUG("Getting serial port list"); if (!(classes = IOServiceMatching(kIOSerialBSDServiceValue))) @@ -58,7 +57,7 @@ enum sp_return get_port_details(struct sp_port *port) IOObjectRelease(ioport); continue; } - DEBUG("Found port %s", path); + DEBUG_FMT("Found port %s", path); IORegistryEntryGetParentEntry(ioport, kIOServicePlane, &ioparent); if ((cf_property=IORegistryEntrySearchCFProperty(ioparent,kIOServicePlane, @@ -87,7 +86,7 @@ enum sp_return get_port_details(struct sp_port *port) CFSTR(kIOTTYDeviceKey), kCFAllocatorDefault, 0))) { if (CFStringGetCString(cf_property, description, sizeof(description), kCFStringEncodingASCII)) { - DEBUG("Found description %s", description); + DEBUG_FMT("Found description %s", description); port->description = strdup(description); } CFRelease(cf_property); @@ -108,7 +107,7 @@ enum sp_return get_port_details(struct sp_port *port) if (cf_bus && cf_address && CFNumberGetValue(cf_bus , kCFNumberIntType, &bus) && CFNumberGetValue(cf_address, kCFNumberIntType, &address)) { - DEBUG("Found matching USB bus:address %03d:%03d", bus, address); + DEBUG_FMT("Found matching USB bus:address %03d:%03d", bus, address); port->usb_bus = bus; port->usb_address = address; } @@ -128,7 +127,7 @@ enum sp_return get_port_details(struct sp_port *port) if (cf_vendor && cf_product && CFNumberGetValue(cf_vendor , kCFNumberIntType, &vid) && CFNumberGetValue(cf_product, kCFNumberIntType, &pid)) { - DEBUG("Found matching USB vid:pid %04X:%04X", vid, pid); + DEBUG_FMT("Found matching USB vid:pid %04X:%04X", vid, pid); port->usb_vid = vid; port->usb_pid = pid; } @@ -140,7 +139,7 @@ enum sp_return get_port_details(struct sp_port *port) kIORegistryIterateRecursively | kIORegistryIterateParents))) { if (CFStringGetCString(cf_property, manufacturer, sizeof(manufacturer), kCFStringEncodingASCII)) { - DEBUG("Found manufacturer %s", manufacturer); + DEBUG_FMT("Found manufacturer %s", manufacturer); port->usb_manufacturer = strdup(manufacturer); } CFRelease(cf_property); @@ -151,7 +150,7 @@ enum sp_return get_port_details(struct sp_port *port) kIORegistryIterateRecursively | kIORegistryIterateParents))) { if (CFStringGetCString(cf_property, product, sizeof(product), kCFStringEncodingASCII)) { - DEBUG("Found product name %s", product); + DEBUG_FMT("Found product name %s", product); port->usb_product = strdup(product); } CFRelease(cf_property); @@ -162,7 +161,7 @@ enum sp_return get_port_details(struct sp_port *port) kIORegistryIterateRecursively | kIORegistryIterateParents))) { if (CFStringGetCString(cf_property, serial, sizeof(serial), kCFStringEncodingASCII)) { - DEBUG("Found serial number %s", serial); + DEBUG_FMT("Found serial number %s", serial); port->usb_serial = strdup(serial); } CFRelease(cf_property); @@ -175,3 +174,52 @@ enum sp_return get_port_details(struct sp_port *port) RETURN_OK(); } + +SP_PRIV enum sp_return list_ports(struct sp_port ***list) +{ + CFMutableDictionaryRef classes; + io_iterator_t iter; + char path[PATH_MAX]; + io_object_t port; + CFTypeRef cf_path; + Boolean result; + int ret = SP_OK; + + DEBUG("Creating matching dictionary"); + if (!(classes = IOServiceMatching(kIOSerialBSDServiceValue))) { + SET_FAIL(ret, "IOServiceMatching() failed"); + goto out_done; + } + + DEBUG("Getting matching services"); + if (IOServiceGetMatchingServices(kIOMasterPortDefault, classes, + &iter) != KERN_SUCCESS) { + SET_FAIL(ret, "IOServiceGetMatchingServices() failed"); + goto out_done; + } + + DEBUG("Iterating over results"); + while ((port = IOIteratorNext(iter))) { + cf_path = IORegistryEntryCreateCFProperty(port, + CFSTR(kIOCalloutDeviceKey), kCFAllocatorDefault, 0); + if (cf_path) { + result = CFStringGetCString(cf_path, path, sizeof(path), + kCFStringEncodingASCII); + CFRelease(cf_path); + if (result) { + DEBUG_FMT("Found port %s", path); + if (!(*list = list_append(*list, path))) { + SET_ERROR(ret, SP_ERR_MEM, "list append failed"); + IOObjectRelease(port); + goto out; + } + } + } + IOObjectRelease(port); + } +out: + IOObjectRelease(iter); +out_done: + + return ret; +}