mirror of
https://github.com/svpcom/wfb-ng.git
synced 2025-03-14 10:33:58 -03:00
Add support for rx-only cards
This commit is contained in:
parent
340e699c71
commit
b9ba1b69d8
@ -126,7 +126,7 @@ ip link set {{ wlan }} down
|
||||
iw dev {{ wlan }} set monitor otherbss
|
||||
ip link set {{ wlan }} up
|
||||
iw dev {{ wlan }} set channel {{ channel[wlan] }} {{ ht_mode }}
|
||||
{% if txpower[wlan] != None %}
|
||||
{% if txpower[wlan] not in (None, 'off') %}
|
||||
iw dev {{ wlan }} set txpower fixed {{ txpower[wlan] }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
@ -37,10 +37,11 @@ wifi_channel = 165 # radio channel @5825 MHz, range: 5815-5835 MHz, width
|
||||
|
||||
wifi_region = 'BO' # Set CRDA region
|
||||
wifi_txpower = None # Leave None to use default power settings from driver.
|
||||
# There is a special value 'off' for RX only cards.
|
||||
# For 8812au set to -dBm * 100. I.e for 30dBm set to -3000
|
||||
# For 8812eu set to dBm * 100. I.e for 30dBm set to 3000
|
||||
# Also you can set own txpower for each wifi card, for example:
|
||||
# {'wlan0': -100, 'wlan1': 100}
|
||||
# {'wlan0': -100, 'wlan1': 100, 'wlan2': 'off'}
|
||||
|
||||
|
||||
temp_measurement_interval = 10 # [s] (8812eu only) Internal RF path temp measurement.
|
||||
|
@ -112,8 +112,9 @@ class StatsAndSelectorFactory(Factory):
|
||||
Aggregate RX stats and select TX antenna
|
||||
"""
|
||||
|
||||
def __init__(self, logger, cli_title=None, rf_temp_meter=None, is_cluster=False):
|
||||
def __init__(self, logger, cli_title=None, rf_temp_meter=None, is_cluster=False, rx_only_wlan_ids=None):
|
||||
self.is_cluster = is_cluster
|
||||
self.rx_only_wlan_ids = rx_only_wlan_ids or set()
|
||||
self.ant_sel_cb_list = []
|
||||
self.rssi_cb_l = []
|
||||
self.cur_stats = {}
|
||||
@ -188,6 +189,10 @@ class StatsAndSelectorFactory(Factory):
|
||||
snr_min, snr_avg, snr_max) in stats_agg.items()),
|
||||
lambda x: x[0]):
|
||||
|
||||
# Skip RX only cards in TX voting
|
||||
if wlan_id in self.rx_only_wlan_ids:
|
||||
continue
|
||||
|
||||
grp = list(grp)
|
||||
# Use max average rssi [dBm] from all wlan's antennas
|
||||
# Use max packet counter per antenna from all wlan's antennas
|
||||
|
@ -22,6 +22,7 @@ import sys
|
||||
import msgpack
|
||||
import os
|
||||
import time
|
||||
import socket
|
||||
import struct
|
||||
import gzip
|
||||
import argparse
|
||||
@ -88,13 +89,13 @@ def init_wlans(max_bw, wlans):
|
||||
|
||||
yield call_and_check_rc('iw', 'dev', wlan, 'set', 'channel', str(channel), ht_mode)
|
||||
|
||||
# You can set own tx power for each card
|
||||
if isinstance(settings.common.wifi_txpower, dict):
|
||||
txpower = settings.common.wifi_txpower[wlan]
|
||||
else:
|
||||
txpower = settings.common.wifi_txpower
|
||||
txpower = settings.common.wifi_txpower
|
||||
|
||||
if txpower is not None:
|
||||
# You can set own tx power for each card
|
||||
if isinstance(txpower, dict):
|
||||
txpower = txpower[wlan]
|
||||
|
||||
if txpower not in (None, 'off'):
|
||||
yield call_and_check_rc('iw', 'dev', wlan, 'set', 'txpower', 'fixed', str(txpower))
|
||||
|
||||
except ExecError as v:
|
||||
@ -119,8 +120,21 @@ def init(profiles, wlans, cluster_mode):
|
||||
def _ssh_exited(x, node):
|
||||
raise Exception('Connection to %s closed, aborting' % (node,))
|
||||
|
||||
rx_only_wlan_ids = set()
|
||||
|
||||
if is_cluster:
|
||||
services, cluster_nodes = parse_cluster_services(profiles)
|
||||
for node in cluster_nodes:
|
||||
node_ipv4_addr = struct.unpack("!L", socket.inet_aton(node))[0]
|
||||
txpower = search_attr('wifi_txpower',
|
||||
settings.cluster.nodes[node],
|
||||
settings.common.__dict__)
|
||||
|
||||
for idx, wlan in enumerate(settings.cluster.nodes[node]['wlans']):
|
||||
if (txpower[wlan] if isinstance(txpower, dict) else txpower) == 'off':
|
||||
rx_only_wlan_ids.add((node_ipv4_addr << 24) | idx)
|
||||
|
||||
|
||||
if cluster_mode == 'ssh':
|
||||
for node, setup_script in gen_cluster_scripts(cluster_nodes, ssh_mode=True).items():
|
||||
ssh_user = search_attr('ssh_user',
|
||||
@ -153,6 +167,13 @@ def init(profiles, wlans, cluster_mode):
|
||||
max_bw = max(cfg.bandwidth for _, tmp in services for _, _, cfg in tmp)
|
||||
yield init_wlans(max_bw, wlans)
|
||||
|
||||
txpower = settings.common.wifi_txpower
|
||||
|
||||
for idx, wlan in enumerate(wlans):
|
||||
if (txpower[wlan] if isinstance(txpower, dict) else txpower) == 'off':
|
||||
rx_only_wlan_ids.add(idx)
|
||||
|
||||
|
||||
sockets = []
|
||||
cleanup_l = []
|
||||
|
||||
@ -171,6 +192,9 @@ def init(profiles, wlans, cluster_mode):
|
||||
else:
|
||||
rf_temp_meter = None
|
||||
|
||||
if rx_only_wlan_ids:
|
||||
log.msg('RX-only wlan ids: %s' % (', '.join(map(hex, rx_only_wlan_ids))))
|
||||
|
||||
for profile, service_list in services:
|
||||
# Domain wide antenna selector
|
||||
profile_cfg = getattr(settings, profile)
|
||||
@ -192,7 +216,7 @@ def init(profiles, wlans, cluster_mode):
|
||||
'cluster' if is_cluster else ', '.join(wlans),
|
||||
profile_cfg.link_domain)
|
||||
|
||||
ant_sel_f = StatsAndSelectorFactory(logger, cli_title, rf_temp_meter, is_cluster)
|
||||
ant_sel_f = StatsAndSelectorFactory(logger, cli_title, rf_temp_meter, is_cluster, rx_only_wlan_ids)
|
||||
cleanup_l.append(ant_sel_f)
|
||||
|
||||
link_id = hash_link_domain(profile_cfg.link_domain)
|
||||
@ -204,7 +228,7 @@ def init(profiles, wlans, cluster_mode):
|
||||
log.msg('Starting %s/%s@%s' % (profile, service_name, profile_cfg.link_domain))
|
||||
dl.append(defer.maybeDeferred(type_map[service_type], service_name, srv_cfg,
|
||||
srv_cfg.udp_peers_auto if is_cluster else wlans,
|
||||
link_id, ant_sel_f, is_cluster))
|
||||
link_id, ant_sel_f, is_cluster, rx_only_wlan_ids))
|
||||
|
||||
yield defer.gatherResults(dl, consumeErrors=True).addBoth(_cleanup).addErrback(lambda f: f.trap(defer.FirstError) and f.value.subFailure)
|
||||
|
||||
|
@ -74,12 +74,12 @@ def parse_services(profile_name, udp_port_allocator):
|
||||
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def init_udp_direct_tx(service_name, cfg, wlans, link_id, ant_sel_f, is_cluster):
|
||||
def init_udp_direct_tx(service_name, cfg, wlans, link_id, ant_sel_f, is_cluster, rx_only_wlan_ids):
|
||||
# Direct udp doesn't support TX diversity - only first card will be used.
|
||||
# But if mirror mode is enabled it will use all cards.
|
||||
|
||||
if not cfg.mirror and (len(wlans) > 1 or ',' in wlans[0]):
|
||||
raise Exception("udp_direct_tx doesn't supports diversity but multiple cards selected. Use udp_proxy for such case.")
|
||||
if not cfg.mirror and (len(wlans) > 1 or ',' in wlans[0] or rx_only_wlan_ids):
|
||||
raise Exception("udp_direct_tx doesn't supports diversity and/or rx-only wlans. Use udp_proxy for such case.")
|
||||
|
||||
if not listen_re.match(cfg.peer):
|
||||
raise Exception('%s: unsupported peer address: %s' % (service_name, cfg.peer))
|
||||
@ -130,7 +130,7 @@ def init_udp_direct_tx(service_name, cfg, wlans, link_id, ant_sel_f, is_cluster)
|
||||
yield df
|
||||
|
||||
|
||||
def init_udp_direct_rx(service_name, cfg, wlans, link_id, ant_sel_f, is_cluster):
|
||||
def init_udp_direct_rx(service_name, cfg, wlans, link_id, ant_sel_f, is_cluster, rx_only_wlan_ids):
|
||||
if not connect_re.match(cfg.peer):
|
||||
raise Exception('%s: unsupported peer address: %s' % (service_name, cfg.peer))
|
||||
|
||||
@ -156,7 +156,7 @@ def init_udp_direct_rx(service_name, cfg, wlans, link_id, ant_sel_f, is_cluster)
|
||||
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def init_mavlink(service_name, cfg, wlans, link_id, ant_sel_f, is_cluster):
|
||||
def init_mavlink(service_name, cfg, wlans, link_id, ant_sel_f, is_cluster, rx_only_wlan_ids):
|
||||
listen = None
|
||||
connect = None
|
||||
serial = None
|
||||
@ -281,7 +281,7 @@ def init_mavlink(service_name, cfg, wlans, link_id, ant_sel_f, is_cluster):
|
||||
|
||||
log.msg('%s use wfb_tx ports %s, control_port %d' % (service_name, tx_ports, control_port))
|
||||
|
||||
p_tx_map = dict((wlan_id, UDPProxyProtocol(('127.0.0.1', port))) for wlan_id, port in tx_ports.items())
|
||||
p_tx_map = dict((wlan_id, UDPProxyProtocol(('127.0.0.1', port))) for wlan_id, port in tx_ports.items() if wlan_id not in rx_only_wlan_ids)
|
||||
|
||||
if serial:
|
||||
serial_port = SerialPort(p_in, os.path.join('/dev', serial[0]), reactor, baudrate=serial[1])
|
||||
@ -298,7 +298,8 @@ def init_mavlink(service_name, cfg, wlans, link_id, ant_sel_f, is_cluster):
|
||||
if wlan_id is not None \
|
||||
else list(p_tx_map.values())[0]
|
||||
|
||||
ant_sel_f.add_ant_sel_cb(ant_sel_cb)
|
||||
if p_tx_map:
|
||||
ant_sel_f.add_ant_sel_cb(ant_sel_cb)
|
||||
|
||||
# Report RSSI to OSD
|
||||
ant_sel_f.add_rssi_cb(p_in.send_rssi)
|
||||
@ -320,7 +321,7 @@ def init_mavlink(service_name, cfg, wlans, link_id, ant_sel_f, is_cluster):
|
||||
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def init_tunnel(service_name, cfg, wlans, link_id, ant_sel_f, is_cluster):
|
||||
def init_tunnel(service_name, cfg, wlans, link_id, ant_sel_f, is_cluster, rx_only_wlan_ids):
|
||||
p_in = TUNTAPProtocol(mtu=settings.common.radio_mtu,
|
||||
agg_timeout=settings.common.tunnel_agg_timeout)
|
||||
|
||||
@ -383,7 +384,7 @@ def init_tunnel(service_name, cfg, wlans, link_id, ant_sel_f, is_cluster):
|
||||
control_port = yield control_port_df
|
||||
|
||||
log.msg('%s use wfb_tx ports %s, control_port %d' % (service_name, tx_ports, control_port))
|
||||
p_tx_map = dict((wlan_id, UDPProxyProtocol(('127.0.0.1', port))) for wlan_id, port in tx_ports.items())
|
||||
p_tx_map = dict((wlan_id, UDPProxyProtocol(('127.0.0.1', port))) for wlan_id, port in tx_ports.items() if wlan_id not in rx_only_wlan_ids)
|
||||
|
||||
tun_ep = TUNTAPTransport(reactor, p_in, cfg.ifname, cfg.ifaddr, mtu=settings.common.radio_mtu, default_route=cfg.default_route)
|
||||
sockets += [ reactor.listenUDP(0, p_tx) for p_tx in p_tx_map.values() ]
|
||||
@ -402,7 +403,8 @@ def init_tunnel(service_name, cfg, wlans, link_id, ant_sel_f, is_cluster):
|
||||
else:
|
||||
p_in.all_peers = list(p_tx_map.values())
|
||||
|
||||
ant_sel_f.add_ant_sel_cb(ant_sel_cb)
|
||||
if p_tx_map:
|
||||
ant_sel_f.add_ant_sel_cb(ant_sel_cb)
|
||||
|
||||
dl.append(RXProtocol(ant_sel_f, cmd_rx, '%s rx' % (service_name,)).start())
|
||||
|
||||
@ -417,7 +419,7 @@ def init_tunnel(service_name, cfg, wlans, link_id, ant_sel_f, is_cluster):
|
||||
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def init_udp_proxy(service_name, cfg, wlans, link_id, ant_sel_f, is_cluster):
|
||||
def init_udp_proxy(service_name, cfg, wlans, link_id, ant_sel_f, is_cluster, rx_only_wlan_ids):
|
||||
listen = None
|
||||
connect = None
|
||||
|
||||
@ -500,7 +502,7 @@ def init_udp_proxy(service_name, cfg, wlans, link_id, ant_sel_f, is_cluster):
|
||||
|
||||
log.msg('%s use wfb_tx ports %s, control_port %d' % (service_name, tx_ports, control_port))
|
||||
|
||||
p_tx_map = dict((wlan_id, UDPProxyProtocol(('127.0.0.1', port))) for wlan_id, port in tx_ports.items())
|
||||
p_tx_map = dict((wlan_id, UDPProxyProtocol(('127.0.0.1', port))) for wlan_id, port in tx_ports.items() if wlan_id not in rx_only_wlan_ids)
|
||||
sockets += [ reactor.listenUDP(0, p_tx) for p_tx in p_tx_map.values() ]
|
||||
|
||||
def ant_sel_cb(wlan_id):
|
||||
@ -508,7 +510,8 @@ def init_udp_proxy(service_name, cfg, wlans, link_id, ant_sel_f, is_cluster):
|
||||
if wlan_id is not None \
|
||||
else list(p_tx_map.values())[0]
|
||||
|
||||
ant_sel_f.add_ant_sel_cb(ant_sel_cb)
|
||||
if p_tx_map:
|
||||
ant_sel_f.add_ant_sel_cb(ant_sel_cb)
|
||||
|
||||
def _cleanup(x):
|
||||
for s in sockets:
|
||||
|
Loading…
Reference in New Issue
Block a user