19#include <radio_tool/radio/ailunce_radio.hpp>
20#include <radio_tool/fw/ailunce_fw.hpp>
31#ifdef COMPORT_DI_LOOKUP
32#pragma comment(lib, "Setupapi.lib")
46 return "== Ailunce USB Serial Cable ==";
57 device.SetInterfaceAttribs(B57600, 0);
58 auto fd = device.GetFD();
61 WriteFile((HANDLE)fd,
"1", (DWORD)1, NULL, NULL);
65 std::this_thread::sleep_for(std::chrono::milliseconds(100));
67 auto r = fw.GetDataSegments()[0];
71auto AilunceRadio::SupportsDevice(
const std::string &port) ->
bool
78 auto ids = GetComPortUSBIds(port);
79 return (ids.first == VID && ids.second == PID) ||
true;
82auto AilunceRadio::GetComPortUSBIds(
const std::string &port) -> std::pair<uint16_t, uint16_t>
84#if defined(_WIN32) && defined(COMPORT_DI_LOOKUP)
85 auto handle = SetupDiGetClassDevs(NULL,
"USB", NULL, DIGCF_ALLCLASSES | DIGCF_PRESENT);
86 if (handle ==
nullptr)
88 throw std::runtime_error(
"Failed to open device info");
93 SP_DEVINFO_DATA deviceInfo = {};
94 deviceInfo.cbSize =
sizeof(SP_DEVINFO_DATA);
96 DWORD idx = 0, outSize = 0;
97 while (SetupDiEnumDeviceInfo(handle, idx++, &deviceInfo))
99 if (SetupDiGetDeviceRegistryPropertyA(handle, &deviceInfo, SPDRP_HARDWAREID, &propType, (PBYTE)&hwIds,
sizeof(hwIds), &outSize))
101 std::cerr << hwIds << std::endl;
104 if ((regKey = SetupDiOpenDevRegKey(handle, &deviceInfo, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ)) == INVALID_HANDLE_VALUE)
106 std::cerr <<
"Failed to find reg key for device: " << (
char *)hwIds << std::endl;
110 constexpr auto BufferLen = 256;
112 DWORD portNameSize = BufferLen;
113 BYTE portName[BufferLen];
114 if (RegQueryValueExA(regKey,
"PortName", NULL, &dwType, (LPBYTE)&portName, &portNameSize) == ERROR_SUCCESS)
117 std::cerr << portName << std::endl;
122 SetupDiDestroyDeviceInfoList(handle);
124 HKEY comKey =
nullptr;
125 auto openResult = RegOpenKeyExA(HKEY_LOCAL_MACHINE, (LPSTR)
"SYSTEM\\CurrentControlSet\\Control\\COM Name Arbiter\\Devices", 0, KEY_READ | KEY_WOW64_64KEY, &comKey);
126 if (openResult != ERROR_SUCCESS)
128 throw std::runtime_error(
"Failed to get serial port info from registry");
131 constexpr auto BufferSize = 256L;
132 BYTE value[BufferSize];
133 DWORD valueSize = BufferSize;
135 auto readResult = RegQueryValueExA(comKey, port.c_str(), NULL, NULL, (LPBYTE)&value, &valueSize);
136 if (readResult == ERROR_SUCCESS)
139 if (std::regex_match((
char *)value, match, std::regex(
"^.*#vid_([\\w+]{4})\\+pid_([\\w+]{4}).*$")))
141 auto vid = std::stoi(match[1],
nullptr, 16);
142 auto pid = std::stoi(match[2],
nullptr, 16);
143 return std::make_pair(vid, pid);
148 throw std::runtime_error(
"Error reading registory key values");
155 return std::make_pair(0, 0);