diff --git a/rx.cpp b/rx.cpp index 43e210e..0d85336 100644 --- a/rx.cpp +++ b/rx.cpp @@ -117,13 +117,19 @@ void Receiver::loop_iter(void) int pktlen = hdr.caplen; // int pkt_rate = 0 - uint8_t antenna = 0; - int8_t rssi = SCHAR_MIN; + int ant_idx = 0; + uint8_t antenna[RX_ANT_MAX]; + int8_t rssi[RX_ANT_MAX]; uint8_t flags = 0; struct ieee80211_radiotap_iterator iterator; int ret = ieee80211_radiotap_iterator_init(&iterator, (ieee80211_radiotap_header*)pkt, pktlen, NULL); - while (ret == 0) { + // Fill all antenna slots with 0xff (unused) + memset(antenna, 0xff, sizeof(antenna)); + // Fill all rssi slots with minimum value + memset(rssi, SCHAR_MIN, sizeof(rssi)); + + while (ret == 0 && ant_idx < RX_ANT_MAX) { ret = ieee80211_radiotap_iterator_next(&iterator); if (ret) @@ -150,12 +156,13 @@ void Receiver::loop_iter(void) case IEEE80211_RADIOTAP_ANTENNA: // FIXME // In case of multiple antenna stats in one packet this index will be irrelivant - antenna = *(uint8_t*)(iterator.this_arg); + antenna[ant_idx] = *(uint8_t*)(iterator.this_arg); + ant_idx += 1; break; case IEEE80211_RADIOTAP_DBM_ANTSIGNAL: // Some cards can provide rssi for multiple antennas in one packet, so we should select maximum value - rssi = max(rssi, *(int8_t*)(iterator.this_arg)); + rssi[ant_idx] = *(int8_t*)(iterator.this_arg); break; case IEEE80211_RADIOTAP_FLAGS: @@ -167,7 +174,7 @@ void Receiver::loop_iter(void) } } /* while more rt headers */ - if (ret != -ENOENT){ + if (ret != -ENOENT && ant_idx < RX_ANT_MAX){ fprintf(stderr, "Error parsing radiotap header!\n"); continue; } @@ -253,11 +260,12 @@ Forwarder::Forwarder(const string &client_addr, int client_port) } -void Forwarder::process_packet(const uint8_t *buf, size_t size, uint8_t wlan_idx, uint8_t antenna, int8_t rssi, sockaddr_in *sockaddr) +void Forwarder::process_packet(const uint8_t *buf, size_t size, uint8_t wlan_idx, const uint8_t *antenna, const int8_t *rssi, sockaddr_in *sockaddr) { - wrxfwd_t fwd_hdr = { .wlan_idx = wlan_idx, - .antenna = antenna, - .rssi = rssi }; + wrxfwd_t fwd_hdr = { .wlan_idx = wlan_idx }; + + memcpy(fwd_hdr.antenna, antenna, RX_ANT_MAX * sizeof(uint8_t)); + memcpy(fwd_hdr.rssi, rssi, RX_ANT_MAX * sizeof(int8_t)); struct iovec iov[2] = {{ .iov_base = (void*)&fwd_hdr, .iov_len = sizeof(fwd_hdr)}, @@ -362,22 +370,25 @@ void Aggregator::dump_stats(FILE *fp) } -void Aggregator::log_rssi(const sockaddr_in *sockaddr, uint8_t wlan_idx, uint8_t ant, int8_t rssi) +void Aggregator::log_rssi(const sockaddr_in *sockaddr, uint8_t wlan_idx, const uint8_t *ant, const int8_t *rssi) { - // key: addr + port + wlan_idx + ant - uint64_t key = 0; - if (sockaddr != NULL && sockaddr->sin_family == AF_INET) + for(int i = 0; i < RX_ANT_MAX && ant[i] != 0xff; i++) { - key = ((uint64_t)ntohl(sockaddr->sin_addr.s_addr) << 32 | (uint64_t)ntohs(sockaddr->sin_port) << 16); + // key: addr + port + wlan_idx + ant + uint64_t key = 0; + if (sockaddr != NULL && sockaddr->sin_family == AF_INET) + { + key = ((uint64_t)ntohl(sockaddr->sin_addr.s_addr) << 32 | (uint64_t)ntohs(sockaddr->sin_port) << 16); + } + + key |= ((uint64_t)wlan_idx << 8 | (uint64_t)ant[i]); + + antenna_stat[key].log_rssi(rssi[i]); } - - key |= ((uint64_t)wlan_idx << 8 | (uint64_t)ant); - - antenna_stat[key].log_rssi(rssi); } -void Aggregator::process_packet(const uint8_t *buf, size_t size, uint8_t wlan_idx, uint8_t antenna, int8_t rssi, sockaddr_in *sockaddr) +void Aggregator::process_packet(const uint8_t *buf, size_t size, uint8_t wlan_idx, const uint8_t *antenna, const int8_t *rssi, sockaddr_in *sockaddr) { uint8_t new_session_key[sizeof(session_key)]; count_p_all += 1; diff --git a/rx.hpp b/rx.hpp index 8809019..54b034e 100644 --- a/rx.hpp +++ b/rx.hpp @@ -28,7 +28,7 @@ typedef enum { class BaseAggregator { public: - virtual void process_packet(const uint8_t *buf, size_t size, uint8_t wlan_idx, uint8_t antenna, int8_t rssi, sockaddr_in *sockaddr) = 0; + virtual void process_packet(const uint8_t *buf, size_t size, uint8_t wlan_idx, const uint8_t *antenna, const int8_t *rssi, sockaddr_in *sockaddr) = 0; virtual void dump_stats(FILE *fp) = 0; protected: int open_udp_socket_for_tx(const string &client_addr, int client_port) @@ -56,7 +56,7 @@ class Forwarder : public BaseAggregator public: Forwarder(const string &client_addr, int client_port); ~Forwarder(); - virtual void process_packet(const uint8_t *buf, size_t size, uint8_t wlan_idx, uint8_t antenna, int8_t rssi, sockaddr_in *sockaddr); + virtual void process_packet(const uint8_t *buf, size_t size, uint8_t wlan_idx, const uint8_t *antenna, const int8_t *rssi, sockaddr_in *sockaddr); virtual void dump_stats(FILE *fp) {} private: int sockfd; @@ -109,12 +109,12 @@ class Aggregator : public BaseAggregator public: Aggregator(const string &client_addr, int client_port, int k, int n, const string &keypair); ~Aggregator(); - virtual void process_packet(const uint8_t *buf, size_t size, uint8_t wlan_idx, uint8_t antenna, int8_t rssi, sockaddr_in *sockaddr); + virtual void process_packet(const uint8_t *buf, size_t size, uint8_t wlan_idx, const uint8_t *antenna, const int8_t *rssi, sockaddr_in *sockaddr); virtual void dump_stats(FILE *fp); private: void send_packet(int ring_idx, int fragment_idx); void apply_fec(int ring_idx); - void log_rssi(const sockaddr_in *sockaddr, uint8_t wlan_idx, uint8_t ant, int8_t rssi); + void log_rssi(const sockaddr_in *sockaddr, uint8_t wlan_idx, const uint8_t *ant, const int8_t *rssi); int get_block_ring_idx(uint64_t block_idx); int rx_ring_push(void); fec_t* fec_p; diff --git a/telemetry/server.py b/telemetry/server.py index 11a936b..4d1979e 100644 --- a/telemetry/server.py +++ b/telemetry/server.py @@ -121,12 +121,28 @@ class AntennaProtocol(LineReceiver): p_all, p_dec_err, p_dec_ok, p_fec_rec, p_lost, p_bad = map(int, cols[2].split(':')) if not self.count_all: - self.count_all = (p_all, p_dec_err, p_dec_ok, p_fec_rec, p_lost, p_bad) + self.count_all = (p_all, p_dec_ok, p_fec_rec, p_lost, p_dec_err, p_bad) else: - self.count_all = tuple((a + b) for a, b in zip((p_all, p_dec_err, p_dec_ok, p_fec_rec, p_lost, p_bad), self.count_all)) + self.count_all = tuple((a + b) for a, b in zip((p_all, p_dec_ok, p_fec_rec, p_lost, p_dec_err, p_bad), self.count_all)) + + self.window.addstr(0, 0, 'PKT: recv %d d_ok %d fec_r %d lost %d d_err %d bad %d\n' % self.count_all) + + msg_l = (('PKT/s: recv %d d_ok %d ' % (p_all, p_dec_ok), 0), + ('fec_r %d' % p_fec_rec, curses.A_REVERSE if p_fec_rec else 0), + (' ', 0), + ('lost %d' % p_lost, curses.A_REVERSE if p_lost else 0), + (' ', 0), + ('d_err %d' % p_dec_err, curses.A_REVERSE if p_dec_err else 0), + (' ', 0), + ('bad %d\n' % p_bad, curses.A_REVERSE if p_bad else 0)) + + x = 0 + xmax = self.window.getmaxyx()[1] + for msg, attr in msg_l: + if x < xmax: + self.window.addstr(1, x, msg, attr) + x += len(msg) - self.window.addstr(0, 0, 'PKT: %d recv, %d d_err, %d d_ok, %d fec_r, %d lost, %d bad\n' % self.count_all) - self.window.addstr(1, 0, 'PKT/s: %d recv, %d d_err, %d d_ok, %d fec_r, %d lost, %d bad\n' % (p_all, p_dec_err, p_dec_ok, p_fec_rec, p_lost, p_bad)) mav_rssi = [] flags = 0 @@ -134,7 +150,7 @@ class AntennaProtocol(LineReceiver): for i, (k, v) in enumerate(sorted(self.ant.iteritems())): pkt_s, rssi_min, rssi_avg, rssi_max = v mav_rssi.append(rssi_avg) - self.window.addstr(i + 3, 0, '%s: %d pkt/s, rssi %d < %d < %d\n' % (k, pkt_s, rssi_min, rssi_avg, rssi_max)) + self.window.addstr(i + 3, 0, '%04x: %d pkt/s, rssi %d < %d < %d\n' % (int(k, 16), pkt_s, rssi_min, rssi_avg, rssi_max)) rssi = (max(mav_rssi) if mav_rssi else -128) % 256 diff --git a/tx.hpp b/tx.hpp index eec9b69..27f3b87 100644 --- a/tx.hpp +++ b/tx.hpp @@ -85,9 +85,13 @@ public: private: virtual void inject_packet(const uint8_t *buf, size_t size) { - wrxfwd_t fwd_hdr = { .wlan_idx = (uint8_t)(rand() % 2), - .antenna = (uint8_t)(rand() % 2), - .rssi = (int8_t)(rand() & 0xff) }; + wrxfwd_t fwd_hdr = { .wlan_idx = (uint8_t)(rand() % 2) }; + + memset(fwd_hdr.antenna, 0xff, sizeof(fwd_hdr.antenna)); + memset(fwd_hdr.rssi, SCHAR_MIN, sizeof(fwd_hdr.rssi)); + + fwd_hdr.antenna[0] = (uint8_t)(rand() % 2); + fwd_hdr.rssi[0] = (int8_t)(rand() & 0xff); struct iovec iov[2] = {{ .iov_base = (void*)&fwd_hdr, .iov_len = sizeof(fwd_hdr)}, diff --git a/wifibroadcast.hpp b/wifibroadcast.hpp index 8a89871..fda32d5 100644 --- a/wifibroadcast.hpp +++ b/wifibroadcast.hpp @@ -112,11 +112,13 @@ static uint8_t ieee80211_header[] = { #define WFB_PACKET_KEY 0x2 #define SESSION_KEY_ANNOUNCE_MSEC 1000 +#define RX_ANT_MAX 4 +// Header for forwarding raw packets from RX host to Aggregator in UDP packets typedef struct { uint8_t wlan_idx; - uint8_t antenna; //RADIOTAP_ANTENNA - int8_t rssi; //RADIOTAP_DBM_ANTSIGNAL + uint8_t antenna[RX_ANT_MAX]; //RADIOTAP_ANTENNA, list of antenna idx, 0xff for unused slot + int8_t rssi[RX_ANT_MAX]; //RADIOTAP_DBM_ANTSIGNAL, list of rssi for corresponding antenna idx } __attribute__ ((packed)) wrxfwd_t; // Network packet headers. All numbers are in network (big endian) format