MCPcopy Create free account
hub / github.com/aethersdr/AetherSDR / open

Method open

src/core/HidEncoderManager.cpp:423–560  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

421}
422
423bool HidEncoderManager::open(uint16_t vid, uint16_t pid)
424{
425 if (m_device) close();
426
427 // Block if more than one RC-28-compatible device is connected — interleaved
428 // events from two encoders would produce unpredictable tuning behaviour.
429 // macOS reports each HID usage collection as a separate enumeration entry, so
430 // counting raw entries would over-count a single device. We group by a stable
431 // physical-device key: the USB serial number when present, otherwise the
432 // hidapi path. The RC-28 exposes no serial, but all usage-collection entries
433 // of one physical interface share the same path, while two separate devices
434 // get distinct paths — so the path fallback distinguishes them correctly.
435 if (isRC28CompatibleId(vid, pid)) {
436 bool multiplePhysical = false;
437 QString firstKey;
438 bool firstSeen = false;
439 if (auto* info = hid_enumerate(vid, pid)) {
440 for (auto* cur = info; cur; cur = cur->next) {
441 const QString key = (cur->serial_number && cur->serial_number[0] != L'\0')
442 ? QStringLiteral("sn:") + QString::fromWCharArray(cur->serial_number)
443 : QStringLiteral("path:") + QString::fromLatin1(cur->path ? cur->path : "");
444 if (!firstSeen) {
445 firstKey = key;
446 firstSeen = true;
447 } else if (key != firstKey) {
448 multiplePhysical = true;
449 break;
450 }
451 }
452 hid_free_enumeration(info);
453 }
454 if (multiplePhysical) {
455 const auto* devices = HidDeviceParser::supportedDevices();
456 int count = HidDeviceParser::supportedDeviceCount();
457 QString name;
458 for (int i = 0; i < count; ++i) {
459 if (devices[i].vid == vid && devices[i].pid == pid) {
460 name = devices[i].name;
461 break;
462 }
463 }
464 // open() is retried every hotplug tick while two devices remain, so
465 // warn + emit only on the transition into the blocked state.
466 if (!m_multipleDetected.load(std::memory_order_acquire)) {
467 // Write the name before the release store so the main thread
468 // sees a valid QString when it reads m_multipleDetected as true.
469 m_blockedDeviceName = name;
470 m_multipleDetected.store(true, std::memory_order_release);
471 qCWarning(lcDevices) << "HidEncoderManager: multiple" << name
472 << "devices detected — blocking until only one is present";
473 emit multipleDevicesDetected(name);
474 }
475 return false;
476 }
477 m_blockedDeviceName.clear();
478 m_multipleDetected.store(false, std::memory_order_release);
479 }
480

Callers

nothing calls this directly

Calls 6

tmate2SegFunction · 0.85
loadMethod · 0.45
clearMethod · 0.45
stopMethod · 0.45
startMethod · 0.45
valueMethod · 0.45

Tested by

no test coverage detected