gnuradio branch bug
Tested your GNURadio branch, and I have to say, it's significantly ahead of the others in terms of performance. Reception and detection are spot on, but I identified an issue in multi-range handling.
If multiple ranges are set per stick (e.g., 143-145, 145-147) or if a single wide range is used (e.g., 143-147), the system fails to initiate recording.
thank you for your work!
I’ve got the same problem here. Fresh Ubuntu install and using docker. I added a very small range 153 to 154 sample rate 2400000. And I was able to get a recording but when expanding to 140 to 160 samples are taken but no recordings. The only other thing I changed setting the transmission group size to 1000. Other than that amazing software I’m finding frequencies around my small town I never knew were there.
Same problem here with gnuradio branch - no recordings if multiple ranges defined in config. Haven't yet tested wider single range.
Take the following with the grain of salt - yet it may point to the possible root cause for described symptom:
The bug appears to be in the multiple frequency ranges handling logic. When there are multiple frequency ranges, the code is waiting on m_notification.wait() which is a blocking call.
In the Notification<T> class implementation in notification.h:
T wait() {
std::unique_lock<std::mutex> lock(m_mutex);
m_cv.wait(lock, [this]() { return m_value.has_value(); });
T value = std::move(m_value.value());
m_value = std::nullopt;
return value;
}
The wait() method blocks until a notification is received. When scanning multiple frequency ranges, if no transmission is detected in the current range, the thread will be stuck waiting for a notification that might never come before it's time to move to the next range. The fix would be to modify the Notification class to support a timed wait or implement a non-blocking check in the scanner loop.
Potential solution:
- Add a timed wait method to the Notification class
template <typename T>
std::optional<T> wait_for(std::chrono::milliseconds timeout) {
std::unique_lock<std::mutex> lock(m_mutex);
if (m_cv.wait_for(lock, timeout, [this]() { return m_value.has_value(); })) {
T value = std::move(m_value.value());
m_value = std::nullopt;
return value;
}
return std::nullopt;
}
- Modify the Scanner::worker() method to use a timed wait
void Scanner::worker() {
Logger::info(LABEL, "thread started");
if (m_ranges.empty()) {
Logger::warn(LABEL, "empty scanned ranges");
} else if (m_ranges.size() == 1) {
m_device.setFrequencyRange(m_ranges.front());
while (m_isRunning) {
m_device.updateRecordings(m_notification.wait());
}
} else {
while (m_isRunning) {
for (const auto& range : m_ranges) {
m_device.setFrequencyRange(range);
const auto startScanningTime = getTime();
bool isRecording = false;
while ((getTime() <= startScanningTime + RANGE_SCANNING_TIME || isRecording) && m_isRunning) {
// Wait with timeout instead of blocking indefinitely
auto result = m_notification.wait_for(std::chrono::milliseconds(100));
if (result) {
// We got a notification
const auto& notification = *result;
isRecording = !notification.empty();
m_device.updateRecordings(notification);
} else {
// Timeout - no transmission detected in this interval
m_device.updateRecordings({});
}
}
if (!m_isRunning) {
break;
}
}
}
}
Logger::info(LABEL, "thread stopped");
}
Take the following with the grain of salt - yet it may point to the possible root cause for described symptom:
The bug appears to be in the multiple frequency ranges handling logic. When there are multiple frequency ranges, the code is waiting on m_notification.wait() which is a blocking call.
In the Notification class implementation in notification.h:
T wait() { std::unique_lockstd::mutex lock(m_mutex); m_cv.wait(lock, this { return m_value.has_value(); }); T value = std::move(m_value.value()); m_value = std::nullopt; return value; }
The wait() method blocks until a notification is received. When scanning multiple frequency ranges, if no transmission is detected in the current range, the thread will be stuck waiting for a notification that might never come before it's time to move to the next range. The fix would be to modify the Notification class to support a timed wait or implement a non-blocking check in the scanner loop.
Potential solution:
1. Add a timed wait method to the Notification classtemplate <typename T> std::optional<T> wait_for(std::chrono::milliseconds timeout) { std::unique_lockstd::mutex lock(m_mutex); if (m_cv.wait_for(lock, timeout, this { return m_value.has_value(); })) { T value = std::move(m_value.value()); m_value = std::nullopt; return value; } return std::nullopt; }
2. Modify the Scanner::worker() method to use a timed waitvoid Scanner::worker() { Logger::info(LABEL, "thread started"); if (m_ranges.empty()) { Logger::warn(LABEL, "empty scanned ranges"); } else if (m_ranges.size() == 1) { m_device.setFrequencyRange(m_ranges.front()); while (m_isRunning) { m_device.updateRecordings(m_notification.wait()); } } else { while (m_isRunning) { for (const auto& range : m_ranges) { m_device.setFrequencyRange(range);
const auto startScanningTime = getTime(); bool isRecording = false; while ((getTime() <= startScanningTime + RANGE_SCANNING_TIME || isRecording) && m_isRunning) { // Wait with timeout instead of blocking indefinitely auto result = m_notification.wait_for(std::chrono::milliseconds(100)); if (result) { // We got a notification const auto& notification = *result; isRecording = !notification.empty(); m_device.updateRecordings(notification); } else { // Timeout - no transmission detected in this interval m_device.updateRecordings({}); } } if (!m_isRunning) { break; } } }} Logger::info(LABEL, "thread stopped"); }
could you please describe in which files the changes are made? all in notification.h? Thank you very much!
I have no cpp knownĺedge - just quessing that AI proposed solution was related to notification class (notification.h) and scanner worker implementation (scanner.cpp).
Problem with no recordings with single wide freq range could be related to frequency range splitting - ie when range is splitted, recording problem cause is similar to multiple ranges problem.
Check out the new release https://github.com/shajen/sdr-hub it's much simpler!