diff --git a/wifibroadcast/src/HelperSources/SchedulingHelper.hpp b/wifibroadcast/src/HelperSources/SchedulingHelper.hpp index 9e7600bd..1dabf1c7 100644 --- a/wifibroadcast/src/HelperSources/SchedulingHelper.hpp +++ b/wifibroadcast/src/HelperSources/SchedulingHelper.hpp @@ -15,6 +15,11 @@ namespace SchedulingHelper { +// Only 'low' in comparison to other realtime tasks +static constexpr int PRIORITY_REALTIME_LOW = 30; +static constexpr int PRIORITY_REALTIME_MID = 40; +static constexpr int PRIORITY_REALTIME_HIGH = 50; + // this thread should run as close to realtime as possible // https://youtu.be/NrjXEaTSyrw?t=647 // COMMENT: Please don't ever use 99 for your application, there are some kernel diff --git a/wifibroadcast/src/WBTxRx.cpp b/wifibroadcast/src/WBTxRx.cpp index 880636a9..4f99f187 100644 --- a/wifibroadcast/src/WBTxRx.cpp +++ b/wifibroadcast/src/WBTxRx.cpp @@ -205,6 +205,11 @@ void WBTxRx::tx_inject_packet(const uint8_t stream_index, const uint8_t* data, m_tx_stats.n_injected_bytes_excluding_overhead += data_len; m_tx_stats.n_injected_bytes_including_overhead += packet_size; m_tx_stats.n_injected_packets++; + } else { + m_console->debug("inject error, sleeping ..."); + // m_tx_mutex.unlock(); for now, don't unlock ... therefore we block all + // threads calling inject + std::this_thread::sleep_for(std::chrono::milliseconds(10)); } } @@ -246,16 +251,27 @@ bool WBTxRx::inject_radiotap_packet(int card_index, const uint8_t* packet_buff, if (len_injected != (int)packet_size) { // This basically should never fail - if the tx queue is full, pcap seems to // wait ?! + bool has_fatal_error = false; if (m_options.tx_without_pcap) { m_console->warn( "raw sock - unable to inject packet size:{} ret:{} err:[{}]", packet_size, len_injected, strerror(errno)); + if (errno == ENXIO) { + // See https://man7.org/linux/man-pages/man3/errno.3.html + m_console->warn("Fatal error, no device"); + has_fatal_error = true; + } } else { m_console->warn("pcap -unable to inject packet size:{} ret:{} err:[{}]", packet_size, len_injected, pcap_geterr(m_pcap_handles[card_index].tx)); } m_tx_stats.count_tx_dropped_packets++; + if (has_fatal_error) { + if (m_fatal_error_cb != nullptr) { + m_fatal_error_cb(errno); + } + } return false; } return true; diff --git a/wifibroadcast/src/WBTxRx.h b/wifibroadcast/src/WBTxRx.h index 43ba1cae..c3bac2b1 100644 --- a/wifibroadcast/src/WBTxRx.h +++ b/wifibroadcast/src/WBTxRx.h @@ -182,7 +182,10 @@ class WBTxRx { // register callback that is called each time a valid packet is received (any // multiplexed stream) void rx_register_callback(OUTPUT_DATA_CALLBACK cb); - + // register callback that is called when the wifi card (probably) + // disconneccted + typedef std::function DEVICE_FATAL_ERROR_CALLBACK; + DEVICE_FATAL_ERROR_CALLBACK m_fatal_error_cb = nullptr; /** * Receiving packets happens in the background in another thread. */ diff --git a/wifibroadcast/src/pcap_helper.hpp b/wifibroadcast/src/pcap_helper.hpp index 3769df79..83b06334 100644 --- a/wifibroadcast/src/pcap_helper.hpp +++ b/wifibroadcast/src/pcap_helper.hpp @@ -7,6 +7,7 @@ #include #include +#include #include