X-Git-Url: http://sigrok.org/gitweb/?a=blobdiff_plain;ds=inline;f=macosx.c;h=a0df84e6b079d4e5ff9fa969a27020631115bbfe;hb=a06a765515482976bcbd60526bd638b3d10b14e7;hp=71bf0a09cff1a8e4eda92c7750262776b3e0c74f;hpb=235269990bd62a906af871c34839ebb922eecb45;p=libserialport.git
diff --git a/macosx.c b/macosx.c
index 71bf0a0..a0df84e 100644
--- a/macosx.c
+++ b/macosx.c
@@ -18,13 +18,16 @@
* along with this program. If not, see .
*/
+#include
#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 */
+ /*
+ * 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];
@@ -57,9 +60,20 @@ 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,
+ CFSTR("IOClass"), kCFAllocatorDefault,
+ kIORegistryIterateRecursively | kIORegistryIterateParents))) {
+ if (CFStringGetCString(cf_property, class, sizeof(class),
+ kCFStringEncodingASCII) &&
+ strstr(class, "USB")) {
+ DEBUG("Found USB class device");
+ port->transport = SP_TRANSPORT_USB;
+ }
+ CFRelease(cf_property);
+ }
if ((cf_property=IORegistryEntrySearchCFProperty(ioparent,kIOServicePlane,
CFSTR("IOProviderClass"), kCFAllocatorDefault,
kIORegistryIterateRecursively | kIORegistryIterateParents))) {
@@ -86,7 +100,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);
@@ -107,12 +121,14 @@ 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;
}
- if (cf_bus ) CFRelease(cf_bus);
- if (cf_address) CFRelease(cf_address);
+ if (cf_bus)
+ CFRelease(cf_bus);
+ if (cf_address)
+ CFRelease(cf_address);
cf_vendor = IORegistryEntrySearchCFProperty(ioport, kIOServicePlane,
CFSTR("idVendor"),
@@ -127,19 +143,21 @@ 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;
}
- if (cf_vendor ) CFRelease(cf_vendor);
- if (cf_product) CFRelease(cf_product);
+ if (cf_vendor)
+ CFRelease(cf_vendor);
+ if (cf_product)
+ CFRelease(cf_product);
if ((cf_property = IORegistryEntrySearchCFProperty(ioport,kIOServicePlane,
CFSTR("USB Vendor Name"), kCFAllocatorDefault,
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);
@@ -150,7 +168,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);
@@ -161,7 +179,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);
@@ -174,3 +192,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;
+}