Show rssi from all antennas separately

Fix ncurses interface
This commit is contained in:
Vasily Evseenko 2018-11-13 18:08:17 +03:00
parent 4c78d2a672
commit 85a72243bc
5 changed files with 67 additions and 34 deletions

51
rx.cpp
View File

@ -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;

8
rx.hpp
View File

@ -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;

View File

@ -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

10
tx.hpp
View File

@ -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)},

View File

@ -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