diff --git a/lib/linux-list.test.ts b/lib/linux-list.test.ts index 0274188f..5ef9aa5f 100644 --- a/lib/linux-list.test.ts +++ b/lib/linux-list.test.ts @@ -64,7 +64,7 @@ N: ttyMFD0 E: DEVNAME=/dev/ttyMFD0 E: ID_VENDOR_ID=0x2343 E: ID_MODEL_ID=0043 -E: ID_MODEL_ENC=some device made by someone +E: ID_MODEL=some device made by someone P: /devices/unknown N: rfcomm4 @@ -84,6 +84,7 @@ const portOutput = [ { path: '/dev/ttyACM0', manufacturer: 'Arduino (www.arduino.cc)', + product: '0043', serialNumber: '752303138333518011C1', productId: '0043', vendorId: '2341', @@ -95,6 +96,7 @@ const portOutput = [ }, { path: '/dev/ttyMFD0', + product: 'some device made by someone', vendorId: '2343', productId: '0043', }, diff --git a/lib/linux-list.ts b/lib/linux-list.ts index 3d3c9800..471394f1 100644 --- a/lib/linux-list.ts +++ b/lib/linux-list.ts @@ -11,6 +11,7 @@ function propName(name: string) { return { DEVNAME: 'path', ID_VENDOR_ENC: 'manufacturer', + ID_MODEL: 'product', ID_SERIAL_SHORT: 'serialNumber', ID_VENDOR_ID: 'vendorId', ID_MODEL_ID: 'productId', @@ -20,6 +21,7 @@ function propName(name: string) { * see https://github.com/serialport/bindings-cpp/issues/115 */ ID_USB_VENDOR_ENC: 'manufacturer', + ID_USB_MODEL: 'product', ID_USB_SERIAL_SHORT: 'serialNumber', ID_USB_VENDOR_ID: 'vendorId', ID_USB_MODEL_ID: 'productId', @@ -56,6 +58,7 @@ export function linuxList(spawnCmd: typeof spawn = spawn) { let port: PortInfo = { path: '', manufacturer: undefined, + product: undefined, serialNumber: undefined, pnpId: undefined, locationId: undefined, @@ -71,6 +74,7 @@ export function linuxList(spawnCmd: typeof spawn = spawn) { port = { path: '', manufacturer: undefined, + product: undefined, serialNumber: undefined, pnpId: undefined, locationId: undefined, diff --git a/src/darwin_list.cpp b/src/darwin_list.cpp index c39f7bec..ba072224 100644 --- a/src/darwin_list.cpp +++ b/src/darwin_list.cpp @@ -162,6 +162,7 @@ static stDeviceListItem* GetSerialDevices() { memset(serialDevice->vendorId, 0, sizeof(serialDevice->vendorId)); memset(serialDevice->productId, 0, sizeof(serialDevice->productId)); serialDevice->manufacturer[0] = '\0'; + serialDevice->product[0] = '\0'; serialDevice->serialNumber[0] = '\0'; deviceListItem->next = NULL; deviceListItem->length = &length; @@ -205,6 +206,28 @@ static stDeviceListItem* GetSerialDevices() { CFRelease(manufacturerAsCFString); } + CFStringRef productAsCFString = (CFStringRef) IORegistryEntryCreateCFProperty(device, + CFSTR(kUSBProductString), + kCFAllocatorDefault, + 0); + + if (productAsCFString) { + Boolean result; + char product[MAXPATHLEN]; + + // Convert from a CFString to a C (NUL-terminated) + result = CFStringGetCString(productAsCFString, + product, + sizeof(product), + kCFStringEncodingUTF8); + + if (result) { + snprintf(serialDevice->product, sizeof(serialDevice->product), "%s", product); + } + + CFRelease(productAsCFString); + } + CFStringRef serialNumberAsCFString = (CFStringRef) IORegistryEntrySearchCFProperty(device, kIOServicePlane, CFSTR(kUSBSerialNumberString), @@ -300,6 +323,9 @@ void ListBaton::Execute() { if (*device.manufacturer) { resultItem->manufacturer = device.manufacturer; } + if (*device.product) { + resultItem->product = device.product; + } if (*device.serialNumber) { resultItem->serialNumber = device.serialNumber; } diff --git a/src/darwin_list.h b/src/darwin_list.h index 8eef0b7d..fb59b110 100644 --- a/src/darwin_list.h +++ b/src/darwin_list.h @@ -14,6 +14,7 @@ void setIfNotEmpty(Napi::Object item, std::string key, const char *value); struct ListResultItem { std::string path; std::string manufacturer; + std::string product; std::string serialNumber; std::string pnpId; std::string locationId; @@ -22,7 +23,7 @@ struct ListResultItem { }; struct ListBaton : public Napi::AsyncWorker { - ListBaton(Napi::Function& callback) : Napi::AsyncWorker(callback, "node-serialport:ListBaton"), + ListBaton(Napi::Function& callback) : Napi::AsyncWorker(callback, "node-serialport:ListBaton"), errorString() {} std::list results; char errorString[ERROR_STRING_SIZE]; @@ -38,6 +39,7 @@ struct ListBaton : public Napi::AsyncWorker { setIfNotEmpty(item, "path", (*it)->path.c_str()); setIfNotEmpty(item, "manufacturer", (*it)->manufacturer.c_str()); + setIfNotEmpty(item, "product", (*it)->product.c_str()); setIfNotEmpty(item, "serialNumber", (*it)->serialNumber.c_str()); setIfNotEmpty(item, "pnpId", (*it)->pnpId.c_str()); setIfNotEmpty(item, "locationId", (*it)->locationId.c_str()); @@ -56,6 +58,7 @@ typedef struct SerialDevice { char vendorId[MAXPATHLEN]; char productId[MAXPATHLEN]; char manufacturer[MAXPATHLEN]; + char product[MAXPATHLEN]; char serialNumber[MAXPATHLEN]; } stSerialDevice;