接続したUSBのシリアルポート名を取得するには

参考サイト
https://developer.apple.com/library/archive/samplecode/SerialPortSample/Introduction/Intro.html

キーワード

IOKit, IOServiceMatching, kIOSerialBSDServiceValue,
kIOSerialBSDTypeKey, kIOSerialBSDAllTypes, IOServiceGetMatchingServices,
IOIteratorNext, IORegistryEntryCreateCFProperty

ハマったポイント
サンプル通り、 kIOSerialBSDTypeKey に kIOSerialBSDModemType を指定していると発見できなかった。代わりに kIOSerialBSDAllTypes を指定すれば OK だった。(自分が使いたいデバイスはIORS232SerialStreamとして認識されていたため)

#include <CoreFoundation/CoreFoundation.h>
#include <IOKit/IOKitLib.h>
#include <IOKit/serial/IOSerialKeys.h>
#include <IOKit/serial/ioss.h>
#include <IOKit/IOBSD.h>

int main(int argc, char *argv[]) {
  CFMutableDictionaryRef serialBSDService = IOServiceMatching(kIOSerialBSDServiceValue);
  //CFDictionarySetValue(serialBSDService, CFSTR(kIOSerialBSDTypeKey), CFSTR(kIOSerialBSDModemType));
  CFDictionarySetValue(serialBSDService, CFSTR(kIOSerialBSDTypeKey), CFSTR(kIOSerialBSDAllTypes));
  io_iterator_t serialPortIterator;
  if (IOServiceGetMatchingServices(kIOMasterPortDefault, serialBSDService, &serialPortIterator) != KERN_SUCCESS) {
    fprintf(stderr, "!_!\n");
    return -1;
  }

  io_object_t modemService;
  while ((modemService = IOIteratorNext(serialPortIterator)) != 0) {
#if 0 // DEBUG
    CFMutableDictionaryRef properties = nullptr;
    if (IORegistryEntryCreateCFProperties(modemService, &properties, kCFAllocatorDefault, kNilOptions) == KERN_SUCCESS) {
      CFShow(properties);
    }
#endif

    CFTypeRef bsdPathAsCFString = IORegistryEntryCreateCFProperty(modemService, CFSTR(kIOCalloutDeviceKey), kCFAllocatorDefault, 0);
    if (bsdPathAsCFString) {
      CFShow(bsdPathAsCFString);
    }
  }

  IOObjectRelease(serialPortIterator);

  return 0;
}