Skip to content

Commit

Permalink
simplify tx inject error counting
Browse files Browse the repository at this point in the history
  • Loading branch information
Consti10 committed Aug 24, 2023
1 parent ab8a3a7 commit 771be21
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 31 deletions.
48 changes: 23 additions & 25 deletions src/WBTxRx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,43 +161,41 @@ void WBTxRx::tx_inject_packet(const uint8_t stream_index,const uint8_t* data, in
// we allocate the right size in the beginning, but check if ciphertext_len is actually matching what we calculated
// (the documentation says 'write up to n bytes' but they probably mean (write exactly n bytes unless an error occurs)
assert(data_len+crypto_aead_chacha20poly1305_ABYTES == ciphertext_len);
const auto before_injection = std::chrono::steady_clock::now();
// we inject the packet on whatever card has the highest rx rssi right now
const auto len_injected= inject_radiotap_packet(m_curr_tx_card.load(),packet_buff,packet_size);
const auto delta_inject=std::chrono::steady_clock::now()-before_injection;
if(delta_inject>=MAX_SANE_INJECTION_TIME){
m_tx_stats.count_tx_injections_error_hint++;
}
if(m_options.debug_tx_injection_time){
m_tx_inject_time.add(delta_inject);
if(m_tx_inject_time.get_delta_since_last_reset()>std::chrono::seconds(2)){
m_console->debug("packet injection time: {}",m_tx_inject_time.getAvgReadable());
m_tx_inject_time.reset();
}
if(delta_inject>MAX_SANE_INJECTION_TIME){
m_console->debug("Injected packet ret:{} took:{}",len_injected,MyTimeHelper::R(delta_inject));
}
}
if (len_injected != (int) packet_size) {
m_tx_stats.count_tx_errors++;
}else{
const bool success= inject_radiotap_packet(m_curr_tx_card.load(),packet_buff,packet_size);
if(success){
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++;
}
announce_session_key_if_needed();
}

int WBTxRx::inject_radiotap_packet(int card_index,const uint8_t* packet_buff, int packet_size) {
bool WBTxRx::inject_radiotap_packet(int card_index,const uint8_t* packet_buff, int packet_size) {
// inject via pcap
int len_injected=0;
// we inject the packet on whatever card has the highest rx rssi right now
const auto before_inject=std::chrono::steady_clock::now();
if(m_options.tx_without_pcap){
len_injected=(int)write(m_pcap_handles[card_index].tx_sockfd,packet_buff,packet_size);
}else{
len_injected=pcap_inject(m_pcap_handles[card_index].tx, packet_buff, packet_size);
//const auto len_injected=write(m_receive_pollfds[card_index].fd,packet_buff,packet_size);
}
const auto delta_inject=std::chrono::steady_clock::now()-before_inject;
if(delta_inject>=MAX_SANE_INJECTION_TIME){
m_tx_stats.count_tx_injections_error_hint++;
}
if(m_options.debug_tx_injection_time){
m_tx_inject_time.add(delta_inject);
if(m_tx_inject_time.get_delta_since_last_reset()>std::chrono::seconds(2)){
m_console->debug("packet injection time: {}",m_tx_inject_time.getAvgReadable());
m_tx_inject_time.reset();
}
if(delta_inject>MAX_SANE_INJECTION_TIME){
m_console->debug("Injected packet ret:{} took:{}",len_injected,MyTimeHelper::R(delta_inject));
}
}
if (len_injected != (int) packet_size) {
// This basically should never fail - if the tx queue is full, pcap seems to wait ?!
if(m_options.tx_without_pcap){
Expand All @@ -206,8 +204,10 @@ int WBTxRx::inject_radiotap_packet(int card_index,const uint8_t* packet_buff, in
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_errors++;
return false;
}
return len_injected;
return true;
}

void WBTxRx::rx_register_callback(WBTxRx::OUTPUT_DATA_CALLBACK cb) {
Expand Down Expand Up @@ -693,10 +693,8 @@ void WBTxRx::send_session_key() {
const int packet_size=(int)packet.size();
// NOTE: Session key is always sent via card 0 since otherwise we might pick up the session key intended for the ground unit
// from the air unit !
const auto len_injected= inject_radiotap_packet(0,packet.data(),packet_size);
if (len_injected != (int) packet_size) {
m_tx_stats.count_tx_errors++;
}else{
const bool success = inject_radiotap_packet(0,packet.data(),packet_size);
if(success){
// These bytes only count as "including overhead"
m_tx_stats.n_injected_bytes_including_overhead +=packet_size;
m_tx_stats.n_injected_packets++;
Expand Down
13 changes: 7 additions & 6 deletions src/WBTxRx.h
Original file line number Diff line number Diff line change
Expand Up @@ -322,11 +322,8 @@ class WBTxRx {
OUTPUT_DATA_CALLBACK m_output_cb= nullptr;
RxStats m_rx_stats{};
TxStats m_tx_stats{};
// a tx error is thrown if injecting the packet takes longer than MAX_SANE_INJECTION_TIME,
// which hints at an overflowing tx queue (unfortunately I don't know a way to directly get the tx queue yet)
// However, this hint can be misleading - for example, during testing (MCS set to 3) and with about 5MBit/s video after FEC
// I get about 5 tx error(s) per second with my atheros, but it works fine. This workaround also seems to not work at all
// with the RTL8812au.
// a tx error hint is thrown if injecting the packet takes longer than MAX_SANE_INJECTION_TIME,
// which hints at too much data being fed to the wifi driver.
static constexpr std::chrono::nanoseconds MAX_SANE_INJECTION_TIME=std::chrono::milliseconds(5);
std::vector<RxStatsPerCard> m_rx_stats_per_card;
std::map<int,std::shared_ptr<StreamRxHandler>> m_rx_handlers;
Expand All @@ -347,7 +344,11 @@ class WBTxRx {
AvgCalculator m_packet_decrypt_time;
AvgCalculator m_tx_inject_time;
private:
int inject_radiotap_packet(int card_index,const uint8_t* packet_buff,int packet_size);
// For OpenHD rate control, this method should block until the driver accepted the packet
// returns true if packet is now in driver hands, false otherwise.
// on failure, m_tx_stats.count_tx_errors is increased by one
// if injection takes "really long", tx error hint is increase
bool inject_radiotap_packet(int card_index,const uint8_t* packet_buff,int packet_size);
// we announce the session key in regular intervals if data is currently being injected (tx_ is called)
void announce_session_key_if_needed();
// send out the session key
Expand Down

0 comments on commit 771be21

Please sign in to comment.