Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add tx dropped frames stat, only consider card that are currently receiving for tx switching #31

Merged
merged 4 commits into from
Aug 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/WBStreamTx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ bool WBStreamTx::try_enqueue_block(std::vector<std::shared_ptr<std::vector<uint8
const bool res= m_block_queue->try_enqueue(item);
if(!res){
m_n_dropped_packets+=fragments.size();
m_n_dropped_frames++;
//m_curr_seq_nr+=fragments.size();
}
return res;
Expand All @@ -107,12 +108,12 @@ WBStreamTx::Statistics WBStreamTx::get_latest_stats() {
m_bitrate_calculator_data_provided.get_last_or_recalculate(
m_count_bytes_data_provided,std::chrono::seconds(2));
ret.n_dropped_packets=m_n_dropped_packets;
ret.n_dropped_frames=m_n_dropped_frames;
ret.current_injected_packets_per_second=m_packets_per_second_calculator.get_last_or_recalculate(
m_n_injected_packets,std::chrono::seconds(2));
return ret;
}


void WBStreamTx::loop_process_data() {
if(options.dequeue_thread_max_realtime){
SchedulingHelper::setThreadParamsMaxRealtime();
Expand Down
3 changes: 3 additions & 0 deletions src/WBStreamTx.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,9 @@ class WBStreamTx {
// Sending a lot of small packets for example should be avoided
uint64_t current_injected_packets_per_second;
// N of dropped packets, increases when both the internal driver queue and the extra 124 packets queue of the tx fill up
// In FEC mode (video), every time a frame is dropped this is increased by the n of fragments in this frame
uint64_t n_dropped_packets;
int32_t n_dropped_frames;
};
Statistics get_latest_stats();
// only valid when actually doing FEC
Expand Down Expand Up @@ -130,6 +132,7 @@ class WBStreamTx {
std::unique_ptr<std::thread> m_process_data_thread;
bool m_process_data_thread_run=true;
uint64_t m_n_dropped_packets=0;
int32_t m_n_dropped_frames=0;
// Time fragments / blocks spend in the non-blocking atomic queue.
AvgCalculator m_queue_time_calculator;
AvgCalculator m_block_until_tx_time;
Expand Down
16 changes: 11 additions & 5 deletions src/WBTxRx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ WBTxRx::WBTxRx(std::vector<WifiCard> wifi_cards1,Options options1)
assert(false);
}
m_receive_pollfds.resize(m_wifi_cards.size());
m_active_tx_card_data.resize(m_wifi_cards.size());
for(int i=0;i<m_wifi_cards.size();i++){
RxStatsPerCard tmp{};
tmp.card_index=i;
Expand Down Expand Up @@ -560,7 +561,6 @@ void WBTxRx::on_new_packet(const uint8_t wlan_idx,const uint8_t *pkt,const int p
}

void WBTxRx::switch_tx_card_if_needed() {
// Adjustment of which card is used for injecting packets in case there are multiple RX card(s)
if(m_wifi_cards.size()>1 && m_options.enable_auto_switch_tx_card){
const auto elapsed=std::chrono::steady_clock::now()-m_last_highest_rssi_adjustment_tp;
if(elapsed>=HIGHEST_RSSI_ADJUSTMENT_INTERVAL){
Expand All @@ -569,10 +569,16 @@ void WBTxRx::switch_tx_card_if_needed() {
int highest_dbm=INT32_MIN;
for(int i=0;i< m_wifi_cards.size();i++){
RxStatsPerCard& this_card_stats=m_rx_stats_per_card.at(i);
const auto dbm_average=this_card_stats.card_dbm;
if(dbm_average>highest_dbm){
idx_card_highest_rssi=i;
highest_dbm=(int)dbm_average;
// Check if this card is behaving "okay", aka receiving packets at the time
const auto delta_valid_packets=this_card_stats.count_p_valid-m_active_tx_card_data[i].last_received_n_valid_packets;
m_active_tx_card_data[i].last_received_n_valid_packets=this_card_stats.count_p_valid;
if(delta_valid_packets!=0){
// Some valid packets on this card, or reset
const auto dbm_average=this_card_stats.card_dbm;
if(dbm_average>highest_dbm){
idx_card_highest_rssi=i;
highest_dbm=static_cast<int>(dbm_average); // NOLINT(cert-str34-c)
}
}
//m_console->debug("Card {} dbm_average:{}",i,dbm_average);
}
Expand Down
11 changes: 10 additions & 1 deletion src/WBTxRx.h
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,10 @@ class WBTxRx {
int curr_bits_per_second_including_overhead=-1;
// tx error hint, first sign the tx can't keep up with the provided bitrate
int32_t count_tx_injections_error_hint=0;
// actual tx errors
// actual tx errors - e.g. packets dropped during injection.
// Usually, this shouldn't increase, since "injecting a frame" should be a blocking operation
// (until there is space available in the tx queue, aka either linux network or driver packet queue)
// and openhd does automatic bitrate adjust at the tx.
int32_t count_tx_errors=0;
};
struct RxStats{
Expand Down Expand Up @@ -285,6 +288,10 @@ class WBTxRx {
uint64_t m_nonce=0;
// For multiple RX cards the card with the highest rx rssi is used to inject packets on
std::atomic<int> m_curr_tx_card=0;
struct ActiveCardCalculationData{
int64_t last_received_n_valid_packets=0;
};
std::vector<ActiveCardCalculationData> m_active_tx_card_data;
SessionKeyPacket m_tx_sess_key_packet;
std::unique_ptr<wb::Encryptor> m_encryptor;
std::unique_ptr<wb::Decryptor> m_decryptor;
Expand Down Expand Up @@ -358,6 +365,8 @@ class WBTxRx {
// called avery time we have successfully decrypted a packet
void on_valid_packet(uint64_t nonce,int wlan_index,uint8_t stream_index,const uint8_t *data,int data_len);
static std::string options_to_string(const std::vector<std::string>& wifi_cards,const Options& options);
// Adjustment of which card is used for injecting packets in case there are multiple RX card(s)
// (Of all cards currently receiving data, find the one with the highest reported dBm)
void switch_tx_card_if_needed();
private:
// These are 'extra' for calculating some channel pollution value
Expand Down