Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MacOS: When extracting buslocation Unique ID is expected to be exactly 18 chars long #62

Open
naali opened this issue Jan 24, 2023 · 0 comments
Labels

Comments

@naali
Copy link

naali commented Jan 24, 2023

Not sure if it's just me and my luck, but at least for me MacOS 13.1 (Ventura) seems to give Unique IDs with a length of 17 chars... This causes buslocation detection to fail so devices can't be recognized from each other if you happen to have multiple similar cameras connected.

I made a quick & dirty patch to platformcontext.mm that extracts buslocation from 17 char Unique IDs and it seems to work. Maybe the Unique ID should be handled by dropping pid & vid and then using the rest of it as the buslocation? That way the Unique ID lenght woudln't matter...

Other solution that might work (if the id is < 18 chars) is to zeropad the beginning till it is long enough. It will get converted from string to uint32_t so trailing zeros wouldn't matter.

I assume that the Unique ID is stored as an actual number value at some point and the leading zeros are cut off when converting it to string. At least on my case this could be the reason:

ioreg -p IOUSB -l -w 0 | grep Global | grep class
      +-o Global Shutter Camera@02140000  <class IOUSBHostDevice, id 0x1001f0d11, registered, matched, active, busy 0 (18 ms), retain 35>
      +-o Global Shutter Camera@02110000  <class IOUSBHostDevice, id 0x1001f0d2a, registered, matched, active, busy 0 (19 ms), retain 35>

Enough with the speculations, here's the quick & dirty patch :)

        } else if (device.uniqueID.length == 17) {
            std::string locStdStr = std::string(device.uniqueID.UTF8String);

            // sanity check for PID and VID to make sure the unique ID is indeed
            // in the format we expect..
            char pidStr[5];
            char vidStr[5];
            snprintf(pidStr, sizeof(pidStr), "%04x", deviceInfo->m_pid);
            snprintf(vidStr, sizeof(vidStr), "%04x", deviceInfo->m_vid);

            if ((locStdStr.substr(9,4) == std::string(vidStr)) &&
                (locStdStr.substr(13,4) == std::string(pidStr)))
            {
                // format seems to be correct
                NSString *hexString = [device.uniqueID substringWithRange:NSMakeRange(2,7)];
                NSScanner *scanner = [NSScanner scannerWithString:hexString];
                [scanner scanHexInt:&(deviceInfo->m_busLocation)];

                LOG(LOG_DEBUG, "Location : %08X\n", deviceInfo->m_busLocation);
                [scanner dealloc];
                [hexString dealloc];
            }
            else
            {
                LOG(LOG_DEBUG, "VID/PID mismatch!\n");
                LOG(LOG_DEBUG, "Extracted VID %s\n", locStdStr.substr(10,4).c_str());
                LOG(LOG_DEBUG, "Extracted PID %s\n", locStdStr.substr(14,4).c_str());
            }
        }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants