Skip to content

Commit

Permalink
Set BW, GI, STBC and MCS index in runtime for each stream separately.
Browse files Browse the repository at this point in the history
  • Loading branch information
svpcom committed Dec 23, 2018
1 parent 5fd2dea commit 576ff26
Show file tree
Hide file tree
Showing 5 changed files with 129 additions and 13 deletions.
65 changes: 62 additions & 3 deletions src/tx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -282,9 +282,15 @@ int main(int argc, char * const *argv)
int opt;
uint8_t k=8, n=12, radio_port=1;
int udp_port=5600;

int bandwidth = 40;
int short_gi = 1;
int stbc = 1;
int mcs_index = 1;

string keypair = "tx.key";

while ((opt = getopt(argc, argv, "K:k:n:u:r:p:")) != -1) {
while ((opt = getopt(argc, argv, "K:k:n:u:r:p:B:G:S:M:")) != -1) {
switch (opt) {
case 'K':
keypair = optarg;
Expand All @@ -301,11 +307,24 @@ int main(int argc, char * const *argv)
case 'p':
radio_port = atoi(optarg);
break;
case 'B':
bandwidth = atoi(optarg);
break;
case 'G':
short_gi = (optarg[0] == 's' || optarg[0] == 'S') ? 1 : 0;
break;
case 'S':
stbc = atoi(optarg);
break;
case 'M':
mcs_index = atoi(optarg);
break;
default: /* '?' */
show_usage:
fprintf(stderr, "Usage: %s [-K tx_key] [-k RS_K] [-n RS_N] [-u udp_port] [-p radio_port] interface1 [interface2] ...\n",
fprintf(stderr, "Usage: %s [-K tx_key] [-k RS_K] [-n RS_N] [-u udp_port] [-p radio_port] [-B bandwidth] [-G guard_interval] [-S stbc] [-M mcs_index] interface1 [interface2] ...\n",
argv[0]);
fprintf(stderr, "Default: K='%s', k=%d, n=%d, udp_port=%d, radio_port=%d\n", keypair.c_str(), k, n, udp_port, radio_port);
fprintf(stderr, "Default: K='%s', k=%d, n=%d, udp_port=%d, radio_port=%d bandwidth=%d guard_interval=%s stbc=%d mcs_index=%d\n",
keypair.c_str(), k, n, udp_port, radio_port, bandwidth, short_gi ? "short" : "long", stbc, mcs_index);
fprintf(stderr, "Radio MTU: %lu\n", (unsigned long)MAX_PAYLOAD_SIZE);
fprintf(stderr, "WFB version " WFB_VERSION "\n");
exit(1);
Expand All @@ -316,6 +335,46 @@ int main(int argc, char * const *argv)
goto show_usage;
}

// Set flags in radiotap header
{
uint8_t flags = 0;
switch(bandwidth) {
case 20:
flags |= IEEE80211_RADIOTAP_MCS_BW_20;
break;
case 40:
flags |= IEEE80211_RADIOTAP_MCS_BW_40;
break;
default:
fprintf(stderr, "Unsupported bandwidth: %d\n", bandwidth);
exit(1);
}

if(short_gi)
{
flags |= IEEE80211_RADIOTAP_MCS_SGI;
}

switch(stbc) {
case 0:
break;
case 1:
flags |= (IEEE80211_RADIOTAP_MCS_STBC_1 << IEEE80211_RADIOTAP_MCS_STBC_SHIFT);
break;
case 2:
flags |= (IEEE80211_RADIOTAP_MCS_STBC_2 << IEEE80211_RADIOTAP_MCS_STBC_SHIFT);
break;
case 3:
flags |= (IEEE80211_RADIOTAP_MCS_STBC_3 << IEEE80211_RADIOTAP_MCS_STBC_SHIFT);
break;
default:
fprintf(stderr, "Unsupported STBC type: %d\n", stbc);
exit(1);
}

radiotap_header[MCS_FLAGS_OFF] = flags;
radiotap_header[MCS_IDX_OFF] = mcs_index;
}
try
{
vector<int> tx_fd;
Expand Down
12 changes: 9 additions & 3 deletions src/wifibroadcast.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,16 +65,22 @@ extern string string_format(const char *format, ...);
#define IEEE80211_RADIOTAP_MCS_STBC_SHIFT 5

#define MCS_KNOWN (IEEE80211_RADIOTAP_MCS_HAVE_MCS | IEEE80211_RADIOTAP_MCS_HAVE_BW | IEEE80211_RADIOTAP_MCS_HAVE_GI | IEEE80211_RADIOTAP_MCS_HAVE_STBC) // | IEEE80211_RADIOTAP_MCS_HAVE_FMT)
#define MCS_FLAGS (IEEE80211_RADIOTAP_MCS_BW_40 | IEEE80211_RADIOTAP_MCS_SGI | (IEEE80211_RADIOTAP_MCS_STBC_1 << IEEE80211_RADIOTAP_MCS_STBC_SHIFT) ) // | IEEE80211_RADIOTAP_MCS_FMT_GF)

static const uint8_t radiotap_header[] __attribute__((unused)) = {
// Default is MCS#1 -- QPSK 1/2 40MHz SGI -- 30 Mbit/s
// MCS_FLAGS = (IEEE80211_RADIOTAP_MCS_BW_40 | IEEE80211_RADIOTAP_MCS_SGI | (IEEE80211_RADIOTAP_MCS_STBC_1 << IEEE80211_RADIOTAP_MCS_STBC_SHIFT) ) // | IEEE80211_RADIOTAP_MCS_FMT_GF)

static uint8_t radiotap_header[] __attribute__((unused)) = {
0x00, 0x00, // <-- radiotap version
0x0d, 0x00, // <- radiotap header length
0x00, 0x80, 0x08, 0x00, // <-- radiotap present flags: RADIOTAP_TX_FLAGS + RADIOTAP_MCS
0x08, 0x00, // RADIOTAP_F_TX_NOACK
MCS_KNOWN , MCS_FLAGS, 0x01 // MCS default is #1 -- QPSK 1/2 40MHz SGI -- 30 Mbit/s
MCS_KNOWN , 0x00, 0x00 // bitmap, flags, mcs_index
};

// offset of MCS_FLAGS and MCS index
#define MCS_FLAGS_OFF 11
#define MCS_IDX_OFF 12

//the last byte of the mac address is recycled as a port number
#define SRC_MAC_LASTBYTE 15
#define DST_MAC_LASTBYTE 21
Expand Down
18 changes: 18 additions & 0 deletions telemetry/conf/local.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,21 @@ bin_dir = '.'

[common]
#debug=True

# [drone_video]
# bandwidth = 20 # bandwidth 20 or 40 MHz
# short_gi = False # use short GI or not
# stbc = 1 # stbc streams: 1, 2, 3 or 0 if unused
# mcs_index = 1 # mcs index

# [drone_mavlink]
# bandwidth = 20 # bandwidth 20 or 40 MHz
# short_gi = False # use short GI or not
# stbc = 1 # stbc streams: 1, 2, 3 or 0 if unused
# mcs_index = 1 # mcs index

# [gs_mavlink]
# bandwidth = 20 # bandwidth 20 or 40 MHz
# short_gi = False # use short GI or not
# stbc = 1 # stbc streams: 1, 2, 3 or 0 if unused
# mcs_index = 1 # mcs index
17 changes: 16 additions & 1 deletion telemetry/conf/master.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ port_tx = 14601 # udp port range (from port_tx to port_tx + number of wlans)
listen = None # udp port for incoming connection, conflicts with 'connect'
connect = 14550 # udp port for outgoing connection, conflicts with 'listen'
inject_rssi = True # inject RADIO_STATUS packets
# Radiotap flags for TX:
bandwidth = 40 # bandwidth 20 or 40 MHz
short_gi = True # use short GI or not
stbc = 1 # stbc streams: 1, 2, 3 or 0 if unused
mcs_index = 1 # mcs index

[gs_video]
keypair = 'gs.key' # keypair generated by wfb-keygen
Expand All @@ -40,10 +45,20 @@ port_tx = 14701
listen = None
connect = 14560
inject_rssi = True # inject RADIO_STATUS packets
# Radiotap flags for TX:
bandwidth = 40 # bandwidth 20 or 40 MHz
short_gi = True # use short GI or not
stbc = 1 # stbc streams: 1, 2, 3 or 0 if unused
mcs_index = 1 # mcs index

[drone_video]
keypair = 'drone.key'
stats_port = None
stream = 3
listen = 5602
connect = None
connect = None
# Radiotap flags for TX:
bandwidth = 40 # bandwidth 20 or 40 MHz
short_gi = True # use short GI or not
stbc = 1 # stbc streams: 1, 2, 3 or 0 if unused
mcs_index = 1 # mcs index
30 changes: 24 additions & 6 deletions telemetry/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,8 @@ def processEnded(self, status):
self.df.errback(status)

def start(self):
df = defer.maybeDeferred(reactor.spawnProcess, self, self.cmd[0], self.cmd, env=None, childFDs={0: "w", 1: "r", 2: "r"})
df = defer.maybeDeferred(reactor.spawnProcess, self, self.cmd[0], self.cmd, env=None,
childFDs={0: "w", 1: "r", 2: "r"})
return df.addCallback(lambda _: self.df)


Expand All @@ -249,8 +250,15 @@ def init(profile, wlans):

def init_mavlink(profile, wlans):
cfg = getattr(settings, '%s_mavlink' % (profile,))
cmd_rx = ('%s -p %d -u %d -K %s' % (os.path.join(settings.path.bin_dir, 'wfb_rx'), cfg.stream_rx, cfg.port_rx, os.path.join(settings.path.conf_dir, cfg.keypair))).split() + wlans
cmd_tx = ('%s -p %d -u %d -K %s' % (os.path.join(settings.path.bin_dir, 'wfb_tx'), cfg.stream_tx, cfg.port_tx, os.path.join(settings.path.conf_dir, cfg.keypair))).split() + wlans

cmd_rx = ('%s -p %d -u %d -K %s' % \
(os.path.join(settings.path.bin_dir, 'wfb_rx'), cfg.stream_rx,
cfg.port_rx, os.path.join(settings.path.conf_dir, cfg.keypair))).split() + wlans

cmd_tx = ('%s -p %d -u %d -K %s -B %d -G %s -S %d -M %d' % \
(os.path.join(settings.path.bin_dir, 'wfb_tx'),
cfg.stream_tx, cfg.port_tx, os.path.join(settings.path.conf_dir, cfg.keypair),
cfg.bandwidth, "short" if cfg.short_gi else "long", cfg.stbc, cfg.mcs_index)).split() + wlans

if cfg.listen:
connect = None
Expand All @@ -259,7 +267,8 @@ def init_mavlink(profile, wlans):
connect = ('127.0.0.1', cfg.connect)
listen = 0

p_in = UDPProxyProtocol(connect, agg_max_size=settings.common.radio_mtu, agg_timeout=settings.common.mavlink_agg_timeout, inject_rssi=cfg.inject_rssi)
p_in = UDPProxyProtocol(connect, agg_max_size=settings.common.radio_mtu,
agg_timeout=settings.common.mavlink_agg_timeout, inject_rssi=cfg.inject_rssi)
p_tx_l = [UDPProxyProtocol(('127.0.0.1', cfg.port_tx + i)) for i, _ in enumerate(wlans)]
p_rx = UDPProxyProtocol()
p_rx.peer = p_in
Expand Down Expand Up @@ -289,13 +298,22 @@ def init_video(profile, wlans):

if cfg.listen:
# We don't use TX diversity for video streaming due to only one transmitter on the vehichle
cmd = ('%s -p %d -u %d -K %s %s' % (os.path.join(settings.path.bin_dir, 'wfb_tx'), cfg.stream, cfg.listen, os.path.join(settings.path.conf_dir, cfg.keypair), wlans[0])).split()
cmd = ('%s -p %d -u %d -K %s -B %d -G %s -S %d -M %d %s' % \
(os.path.join(settings.path.bin_dir, 'wfb_tx'), cfg.stream,
cfg.listen, os.path.join(settings.path.conf_dir, cfg.keypair),
cfg.bandwidth, "short" if cfg.short_gi else "long", cfg.stbc, cfg.mcs_index,
wlans[0])).split()

df = TXProtocol(cmd, 'video tx').start()
else:
ant_f = AntennaFactory(None, None)
if cfg.stats_port:
reactor.listenTCP(cfg.stats_port, ant_f)
cmd = ('%s -p %d -u %d -K %s' % (os.path.join(settings.path.bin_dir, 'wfb_rx'), cfg.stream, cfg.connect, os.path.join(settings.path.conf_dir, cfg.keypair))).split() + wlans

cmd = ('%s -p %d -u %d -K %s' % \
(os.path.join(settings.path.bin_dir, 'wfb_rx'), cfg.stream, cfg.connect,
os.path.join(settings.path.conf_dir, cfg.keypair))).split() + wlans

df = RXProtocol(ant_f, cmd, 'video rx').start()

log.msg('Video: %s' % (' '.join(cmd),))
Expand Down

0 comments on commit 576ff26

Please sign in to comment.