Skip to content

Commit a3092bd

Browse files
committed
[hal] Fix USB serial port assignment in SerialHelper
Avoid mutating the sorted hub path list when assigning an unclaimed USB serial port. This keeps the second USB device from reusing the first device's mapping, and resets cached hub/resource state before rescanning.
1 parent 7ca35e5 commit a3092bd

File tree

1 file changed

+22
-13
lines changed

1 file changed

+22
-13
lines changed

hal/src/main/native/athena/cpp/SerialHelper.cpp

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -138,10 +138,10 @@ void SerialHelper::SortHubPathVector() {
138138
m_sortedHubPath = m_unsortedHubPath;
139139
std::sort(m_sortedHubPath.begin(), m_sortedHubPath.end(),
140140
[](const wpi::SmallVectorImpl<char>& lhs,
141-
const wpi::SmallVectorImpl<char>& rhs) -> int {
141+
const wpi::SmallVectorImpl<char>& rhs) -> bool {
142142
std::string_view lhsRef(lhs.begin(), lhs.size());
143143
std::string_view rhsRef(rhs.begin(), rhs.size());
144-
return lhsRef.compare(rhsRef);
144+
return lhsRef < rhsRef;
145145
});
146146
}
147147

@@ -162,6 +162,11 @@ void SerialHelper::CoiteratedSort(
162162
}
163163

164164
void SerialHelper::QueryHubPaths(int32_t* status) {
165+
m_unsortedHubPath.clear();
166+
m_visaResource.clear();
167+
m_osResource.clear();
168+
m_sortedHubPath.clear();
169+
165170
// VISA resource matching string
166171
const char* str = "?*";
167172
// Items needed for VISA
@@ -275,12 +280,14 @@ void SerialHelper::QueryHubPaths(int32_t* status) {
275280
continue;
276281
}
277282

283+
std::string_view hubPathComponent = pathSplitVec[hubIndex - 2];
284+
std::string_view osPath =
285+
wpi::split(wpi::split(osName, "(").second, ")").first;
286+
278287
// Add our devices to our list
279-
m_unsortedHubPath.emplace_back(
280-
std::string_view{pathSplitVec[hubIndex - 2]});
288+
m_unsortedHubPath.emplace_back(hubPathComponent);
281289
m_visaResource.emplace_back(desc);
282-
m_osResource.emplace_back(
283-
wpi::split(wpi::split(osName, "(").second, ")").first);
290+
m_osResource.emplace_back(osPath);
284291
break;
285292
}
286293
}
@@ -303,14 +310,16 @@ int32_t SerialHelper::GetIndexForPort(HAL_SerialPort port, int32_t* status) {
303310

304311
// If port has not been assigned, find the one to assign
305312
if (portString.empty()) {
313+
// local copy to avoid modifying original
314+
auto availableHubPaths = m_sortedHubPath;
315+
306316
for (size_t i = 0; i < 2; i++) {
307-
// Remove all used ports
317+
// Remove all used ports from the local copy
308318
auto idx = std::find_if(
309-
m_sortedHubPath.begin(), m_sortedHubPath.end(),
319+
availableHubPaths.begin(), availableHubPaths.end(),
310320
[&](const auto& s) { return wpi::equals(s, m_usbNames[i]); });
311-
if (idx != m_sortedHubPath.end()) {
312-
// found
313-
m_sortedHubPath.erase(idx);
321+
if (idx != availableHubPaths.end()) {
322+
availableHubPaths.erase(idx);
314323
}
315324
if (m_usbNames[i] == "") {
316325
indices.push_back(i);
@@ -330,12 +339,12 @@ int32_t SerialHelper::GetIndexForPort(HAL_SerialPort port, int32_t* status) {
330339
return -1;
331340
}
332341

333-
if (idx >= static_cast<int32_t>(m_sortedHubPath.size())) {
342+
if (idx >= static_cast<int32_t>(availableHubPaths.size())) {
334343
*status = HAL_SERIAL_PORT_NOT_FOUND;
335344
return -1;
336345
}
337346

338-
portString = m_sortedHubPath[idx].str();
347+
portString = availableHubPaths[idx].str();
339348
m_usbNames[port - 2] = portString;
340349
}
341350

0 commit comments

Comments
 (0)