mirror of
https://github.com/markqvist/Reticulum.git
synced 2024-11-25 07:00:17 +00:00
Compare commits
10 Commits
6c26e8b1b1
...
e4ab81d95a
Author | SHA1 | Date | |
---|---|---|---|
|
e4ab81d95a | ||
|
760ab981d0 | ||
|
7b43ff0cef | ||
|
996161e2f4 | ||
|
bf633bba5d | ||
|
8337a5945d | ||
|
a736b3adfc | ||
|
25127cd3c9 | ||
|
ebf084cff0 | ||
|
cd8fe95d91 |
@ -59,6 +59,7 @@ class AX25():
|
|||||||
class AX25KISSInterface(Interface):
|
class AX25KISSInterface(Interface):
|
||||||
MAX_CHUNK = 32768
|
MAX_CHUNK = 32768
|
||||||
BITRATE_GUESS = 1200
|
BITRATE_GUESS = 1200
|
||||||
|
DEFAULT_IFAC_SIZE = 8
|
||||||
|
|
||||||
owner = None
|
owner = None
|
||||||
port = None
|
port = None
|
||||||
@ -68,7 +69,7 @@ class AX25KISSInterface(Interface):
|
|||||||
stopbits = None
|
stopbits = None
|
||||||
serial = None
|
serial = None
|
||||||
|
|
||||||
def __init__(self, owner, name, callsign, ssid, port, speed, databits, parity, stopbits, preamble, txtail, persistence, slottime, flow_control):
|
def __init__(self, owner, configuration):
|
||||||
import importlib
|
import importlib
|
||||||
if importlib.util.find_spec('serial') != None:
|
if importlib.util.find_spec('serial') != None:
|
||||||
import serial
|
import serial
|
||||||
@ -79,6 +80,25 @@ class AX25KISSInterface(Interface):
|
|||||||
|
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
|
c = configuration
|
||||||
|
name = c["name"]
|
||||||
|
preamble = int(c["preamble"]) if "preamble" in c else None
|
||||||
|
txtail = int(c["txtail"]) if "txtail" in c else None
|
||||||
|
persistence = int(c["persistence"]) if "persistence" in c else None
|
||||||
|
slottime = int(c["slottime"]) if "slottime" in c else None
|
||||||
|
flow_control = c.as_bool("flow_control") if "flow_control" in c else False
|
||||||
|
port = c["port"] if "port" in c else None
|
||||||
|
speed = int(c["speed"]) if "speed" in c else 9600
|
||||||
|
databits = int(c["databits"]) if "databits" in c else 8
|
||||||
|
parity = c["parity"] if "parity" in c else "N"
|
||||||
|
stopbits = int(c["stopbits"]) if "stopbits" in c else 1
|
||||||
|
|
||||||
|
callsign = c["callsign"] if "callsign" in c else ""
|
||||||
|
ssid = int(c["ssid"]) if "ssid" in c else -1
|
||||||
|
|
||||||
|
if port == None:
|
||||||
|
raise ValueError("No port specified for serial interface")
|
||||||
|
|
||||||
self.HW_MTU = 564
|
self.HW_MTU = 564
|
||||||
|
|
||||||
self.pyserial = serial
|
self.pyserial = serial
|
||||||
|
@ -52,6 +52,7 @@ class KISS():
|
|||||||
class KISSInterface(Interface):
|
class KISSInterface(Interface):
|
||||||
MAX_CHUNK = 32768
|
MAX_CHUNK = 32768
|
||||||
BITRATE_GUESS = 1200
|
BITRATE_GUESS = 1200
|
||||||
|
DEFAULT_IFAC_SIZE = 8
|
||||||
|
|
||||||
owner = None
|
owner = None
|
||||||
port = None
|
port = None
|
||||||
@ -61,7 +62,7 @@ class KISSInterface(Interface):
|
|||||||
stopbits = None
|
stopbits = None
|
||||||
serial = None
|
serial = None
|
||||||
|
|
||||||
def __init__(self, owner, name, port, speed, databits, parity, stopbits, preamble, txtail, persistence, slottime, flow_control, beacon_interval, beacon_data):
|
def __init__(self, owner, configuration):
|
||||||
import importlib
|
import importlib
|
||||||
if RNS.vendor.platformutils.is_android():
|
if RNS.vendor.platformutils.is_android():
|
||||||
self.on_android = True
|
self.on_android = True
|
||||||
@ -84,6 +85,21 @@ class KISSInterface(Interface):
|
|||||||
|
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
|
c = configuration
|
||||||
|
name = c["name"]
|
||||||
|
preamble = int(c["preamble"]) if "preamble" in c else None
|
||||||
|
txtail = int(c["txtail"]) if "txtail" in c else None
|
||||||
|
persistence = int(c["persistence"]) if "persistence" in c else None
|
||||||
|
slottime = int(c["slottime"]) if "slottime" in c else None
|
||||||
|
flow_control = c.as_bool("flow_control") if "flow_control" in c else False
|
||||||
|
port = c["port"] if "port" in c else None
|
||||||
|
speed = int(c["speed"]) if "speed" in c else 9600
|
||||||
|
databits = int(c["databits"]) if "databits" in c else 8
|
||||||
|
parity = c["parity"] if "parity" in c else "N"
|
||||||
|
stopbits = int(c["stopbits"]) if "stopbits" in c else 1
|
||||||
|
beacon_interval = int(c["beacon_interval"]) if "beacon_interval" in c else None
|
||||||
|
beacon_data = c["beacon_data"] if "beacon_data" in c else None
|
||||||
|
|
||||||
self.HW_MTU = 564
|
self.HW_MTU = 564
|
||||||
|
|
||||||
if beacon_data == None:
|
if beacon_data == None:
|
||||||
|
@ -238,6 +238,7 @@ class AndroidBluetoothManager():
|
|||||||
|
|
||||||
class RNodeInterface(Interface):
|
class RNodeInterface(Interface):
|
||||||
MAX_CHUNK = 32768
|
MAX_CHUNK = 32768
|
||||||
|
DEFAULT_IFAC_SIZE = 8
|
||||||
|
|
||||||
FREQ_MIN = 137000000
|
FREQ_MIN = 137000000
|
||||||
FREQ_MAX = 1020000000
|
FREQ_MAX = 1020000000
|
||||||
@ -341,12 +342,27 @@ class RNodeInterface(Interface):
|
|||||||
serial.close()
|
serial.close()
|
||||||
|
|
||||||
|
|
||||||
def __init__(
|
def __init__(self, owner, configuration):
|
||||||
self, owner, name, port, frequency = None, bandwidth = None, txpower = None,
|
c = configuration
|
||||||
sf = None, cr = None, flow_control = False, id_interval = None,
|
name = c["name"]
|
||||||
allow_bluetooth = False, target_device_name = None,
|
allow_bluetooth = c["allow_bluetooth"]
|
||||||
target_device_address = None, id_callsign = None, st_alock = None, lt_alock = None,
|
target_device_name = c["target_device_name"]
|
||||||
ble_addr = None, ble_name = None, force_ble=False):
|
target_device_address = c["target_device_address"]
|
||||||
|
ble_name = c["ble_name"]
|
||||||
|
ble_addr = c["ble_addr"]
|
||||||
|
force_ble = c["force_ble"]
|
||||||
|
frequency = int(c["frequency"]) if "frequency" in c else None
|
||||||
|
bandwidth = int(c["bandwidth"]) if "bandwidth" in c else None
|
||||||
|
txpower = int(c["txpower"]) if "txpower" in c else None
|
||||||
|
sf = int(c["spreadingfactor"]) if "spreadingfactor" in c else None
|
||||||
|
cr = int(c["codingrate"]) if "codingrate" in c else None
|
||||||
|
flow_control = c.as_bool("flow_control") if "flow_control" in c else False
|
||||||
|
id_interval = int(c["id_interval"]) if "id_interval" in c else None
|
||||||
|
id_callsign = c["id_callsign"] if "id_callsign" in c else None
|
||||||
|
st_alock = float(c["airtime_limit_short"]) if "airtime_limit_short" in c else None
|
||||||
|
lt_alock = float(c["airtime_limit_long"]) if "airtime_limit_long" in c else None
|
||||||
|
port = c["port"] if "port" in c else None
|
||||||
|
|
||||||
import importlib
|
import importlib
|
||||||
if RNS.vendor.platformutils.is_android():
|
if RNS.vendor.platformutils.is_android():
|
||||||
self.on_android = True
|
self.on_android = True
|
||||||
|
@ -42,6 +42,7 @@ class HDLC():
|
|||||||
|
|
||||||
class SerialInterface(Interface):
|
class SerialInterface(Interface):
|
||||||
MAX_CHUNK = 32768
|
MAX_CHUNK = 32768
|
||||||
|
DEFAULT_IFAC_SIZE = 8
|
||||||
|
|
||||||
owner = None
|
owner = None
|
||||||
port = None
|
port = None
|
||||||
@ -51,7 +52,7 @@ class SerialInterface(Interface):
|
|||||||
stopbits = None
|
stopbits = None
|
||||||
serial = None
|
serial = None
|
||||||
|
|
||||||
def __init__(self, owner, name, port, speed, databits, parity, stopbits):
|
def __init__(self, owner, configuration):
|
||||||
import importlib
|
import importlib
|
||||||
if RNS.vendor.platformutils.is_android():
|
if RNS.vendor.platformutils.is_android():
|
||||||
self.on_android = True
|
self.on_android = True
|
||||||
@ -74,6 +75,17 @@ class SerialInterface(Interface):
|
|||||||
|
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
|
c = configuration
|
||||||
|
name = c["name"]
|
||||||
|
port = c["port"] if "port" in c else None
|
||||||
|
speed = int(c["speed"]) if "speed" in c else 9600
|
||||||
|
databits = int(c["databits"]) if "databits" in c else 8
|
||||||
|
parity = c["parity"] if "parity" in c else "N"
|
||||||
|
stopbits = int(c["stopbits"]) if "stopbits" in c else 1
|
||||||
|
|
||||||
|
if port == None:
|
||||||
|
raise ValueError("No port specified for serial interface")
|
||||||
|
|
||||||
self.HW_MTU = 564
|
self.HW_MTU = 564
|
||||||
|
|
||||||
self.pyserial = serial
|
self.pyserial = serial
|
||||||
|
@ -829,10 +829,20 @@ class I2PInterfacePeer(Interface):
|
|||||||
|
|
||||||
class I2PInterface(Interface):
|
class I2PInterface(Interface):
|
||||||
BITRATE_GUESS = 256*1000
|
BITRATE_GUESS = 256*1000
|
||||||
|
DEFAULT_IFAC_SIZE = 16
|
||||||
|
|
||||||
def __init__(self, owner, name, rns_storagepath, peers, connectable = False, ifac_size = 16, ifac_netname = None, ifac_netkey = None):
|
def __init__(self, owner, configuration):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
|
c = configuration
|
||||||
|
name = c["name"]
|
||||||
|
rns_storagepath = c["storagepath"]
|
||||||
|
peers = c.as_list("peers") if "peers" in c else None
|
||||||
|
connectable = c.as_bool("connectable") if "connectable" in c else False
|
||||||
|
ifac_size = c["ifac_size"]
|
||||||
|
ifac_netname = c["ifac_netname"]
|
||||||
|
ifac_netkey = c["ifac_netkey"]
|
||||||
|
|
||||||
self.HW_MTU = 1064
|
self.HW_MTU = 1064
|
||||||
|
|
||||||
self.online = False
|
self.online = False
|
||||||
|
@ -52,6 +52,7 @@ class KISS():
|
|||||||
class KISSInterface(Interface):
|
class KISSInterface(Interface):
|
||||||
MAX_CHUNK = 32768
|
MAX_CHUNK = 32768
|
||||||
BITRATE_GUESS = 1200
|
BITRATE_GUESS = 1200
|
||||||
|
DEFAULT_IFAC_SIZE = 8
|
||||||
|
|
||||||
owner = None
|
owner = None
|
||||||
port = None
|
port = None
|
||||||
@ -61,7 +62,7 @@ class KISSInterface(Interface):
|
|||||||
stopbits = None
|
stopbits = None
|
||||||
serial = None
|
serial = None
|
||||||
|
|
||||||
def __init__(self, owner, name, port, speed, databits, parity, stopbits, preamble, txtail, persistence, slottime, flow_control, beacon_interval, beacon_data):
|
def __init__(self, owner, configuration):
|
||||||
import importlib
|
import importlib
|
||||||
if importlib.util.find_spec('serial') != None:
|
if importlib.util.find_spec('serial') != None:
|
||||||
import serial
|
import serial
|
||||||
@ -72,6 +73,24 @@ class KISSInterface(Interface):
|
|||||||
|
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
|
c = configuration
|
||||||
|
name = c["name"]
|
||||||
|
preamble = int(c["preamble"]) if "preamble" in c else None
|
||||||
|
txtail = int(c["txtail"]) if "txtail" in c else None
|
||||||
|
persistence = int(c["persistence"]) if "persistence" in c else None
|
||||||
|
slottime = int(c["slottime"]) if "slottime" in c else None
|
||||||
|
flow_control = c.as_bool("flow_control") if "flow_control" in c else False
|
||||||
|
port = c["port"] if "port" in c else None
|
||||||
|
speed = int(c["speed"]) if "speed" in c else 9600
|
||||||
|
databits = int(c["databits"]) if "databits" in c else 8
|
||||||
|
parity = c["parity"] if "parity" in c else "N"
|
||||||
|
stopbits = int(c["stopbits"]) if "stopbits" in c else 1
|
||||||
|
beacon_interval = int(c["id_interval"]) if "id_interval" in c else None
|
||||||
|
beacon_data = c["id_callsign"] if "id_callsign" in c else None
|
||||||
|
|
||||||
|
if port == None:
|
||||||
|
raise ValueError("No port specified for serial interface")
|
||||||
|
|
||||||
self.HW_MTU = 564
|
self.HW_MTU = 564
|
||||||
|
|
||||||
if beacon_data == None:
|
if beacon_data == None:
|
||||||
|
@ -46,16 +46,25 @@ class HDLC():
|
|||||||
class PipeInterface(Interface):
|
class PipeInterface(Interface):
|
||||||
MAX_CHUNK = 32768
|
MAX_CHUNK = 32768
|
||||||
BITRATE_GUESS = 1*1000*1000
|
BITRATE_GUESS = 1*1000*1000
|
||||||
|
DEFAULT_IFAC_SIZE = 8
|
||||||
|
|
||||||
owner = None
|
owner = None
|
||||||
command = None
|
command = None
|
||||||
|
|
||||||
def __init__(self, owner, name, command, respawn_delay):
|
def __init__(self, owner, configuration):
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
|
c = configuration
|
||||||
|
name = c["name"]
|
||||||
|
command = c["command"] if "command" in c else None
|
||||||
|
respawn_delay = c.as_float("respawn_delay") if "respawn_delay" in c else None
|
||||||
|
|
||||||
|
if command == None:
|
||||||
|
raise ValueError("No command specified for PipeInterface")
|
||||||
|
|
||||||
if respawn_delay == None:
|
if respawn_delay == None:
|
||||||
respawn_delay = 5
|
respawn_delay = 5
|
||||||
|
|
||||||
super().__init__()
|
|
||||||
|
|
||||||
self.HW_MTU = 1064
|
self.HW_MTU = 1064
|
||||||
|
|
||||||
self.owner = owner
|
self.owner = owner
|
||||||
|
@ -95,6 +95,7 @@ class KISS():
|
|||||||
|
|
||||||
class RNodeInterface(Interface):
|
class RNodeInterface(Interface):
|
||||||
MAX_CHUNK = 32768
|
MAX_CHUNK = 32768
|
||||||
|
DEFAULT_IFAC_SIZE = 8
|
||||||
|
|
||||||
FREQ_MIN = 137000000
|
FREQ_MIN = 137000000
|
||||||
FREQ_MAX = 3000000000
|
FREQ_MAX = 3000000000
|
||||||
@ -117,7 +118,7 @@ class RNodeInterface(Interface):
|
|||||||
BATTERY_STATE_CHARGING = 0x02
|
BATTERY_STATE_CHARGING = 0x02
|
||||||
BATTERY_STATE_CHARGED = 0x03
|
BATTERY_STATE_CHARGED = 0x03
|
||||||
|
|
||||||
def __init__(self, owner, name, port, frequency = None, bandwidth = None, txpower = None, sf = None, cr = None, flow_control = False, id_interval = None, id_callsign = None, st_alock = None, lt_alock = None, ble_addr = None, ble_name = None, force_ble=False):
|
def __init__(self, owner, configuration):
|
||||||
if RNS.vendor.platformutils.is_android():
|
if RNS.vendor.platformutils.is_android():
|
||||||
raise SystemError("Invalid interface type. The Android-specific RNode interface must be used on Android")
|
raise SystemError("Invalid interface type. The Android-specific RNode interface must be used on Android")
|
||||||
|
|
||||||
@ -131,6 +132,41 @@ class RNodeInterface(Interface):
|
|||||||
|
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
|
c = configuration
|
||||||
|
name = c["name"]
|
||||||
|
frequency = int(c["frequency"]) if "frequency" in c else None
|
||||||
|
bandwidth = int(c["bandwidth"]) if "bandwidth" in c else None
|
||||||
|
txpower = int(c["txpower"]) if "txpower" in c else None
|
||||||
|
sf = int(c["spreadingfactor"]) if "spreadingfactor" in c else None
|
||||||
|
cr = int(c["codingrate"]) if "codingrate" in c else None
|
||||||
|
flow_control = c.as_bool("flow_control") if "flow_control" in c else False
|
||||||
|
id_interval = int(c["id_interval"]) if "id_interval" in c else None
|
||||||
|
id_callsign = c["id_callsign"] if "id_callsign" in c else None
|
||||||
|
st_alock = float(c["airtime_limit_short"]) if "airtime_limit_short" in c else None
|
||||||
|
lt_alock = float(c["airtime_limit_long"]) if "airtime_limit_long" in c else None
|
||||||
|
|
||||||
|
force_ble = False
|
||||||
|
ble_name = None
|
||||||
|
ble_addr = None
|
||||||
|
|
||||||
|
port = c["port"] if "port" in c else None
|
||||||
|
|
||||||
|
if port == None:
|
||||||
|
raise ValueError("No port specified for RNode interface")
|
||||||
|
|
||||||
|
if port != None:
|
||||||
|
ble_uri_scheme = "ble://"
|
||||||
|
if port.lower().startswith(ble_uri_scheme):
|
||||||
|
force_ble = True
|
||||||
|
ble_string = port[len(ble_uri_scheme):]
|
||||||
|
port = None
|
||||||
|
if len(ble_string) == 0:
|
||||||
|
pass
|
||||||
|
elif len(ble_string.split(":")) == 6 and len(ble_string) == 17:
|
||||||
|
ble_addr = ble_string
|
||||||
|
else:
|
||||||
|
ble_name = ble_string
|
||||||
|
|
||||||
self.HW_MTU = 508
|
self.HW_MTU = 508
|
||||||
|
|
||||||
self.pyserial = serial
|
self.pyserial = serial
|
||||||
|
@ -163,6 +163,7 @@ class KISS():
|
|||||||
|
|
||||||
class RNodeMultiInterface(Interface):
|
class RNodeMultiInterface(Interface):
|
||||||
MAX_CHUNK = 32768
|
MAX_CHUNK = 32768
|
||||||
|
DEFAULT_IFAC_SIZE = 8
|
||||||
|
|
||||||
CALLSIGN_MAX_LEN = 32
|
CALLSIGN_MAX_LEN = 32
|
||||||
|
|
||||||
@ -173,7 +174,7 @@ class RNodeMultiInterface(Interface):
|
|||||||
|
|
||||||
MAX_SUBINTERFACES = 11
|
MAX_SUBINTERFACES = 11
|
||||||
|
|
||||||
def __init__(self, owner, name, port, subint_config, id_interval = None, id_callsign = None):
|
def __init__(self, owner, configuration):
|
||||||
if RNS.vendor.platformutils.is_android():
|
if RNS.vendor.platformutils.is_android():
|
||||||
raise SystemError("Invalid interface type. The Android-specific RNode interface must be used on Android")
|
raise SystemError("Invalid interface type. The Android-specific RNode interface must be used on Android")
|
||||||
|
|
||||||
@ -187,6 +188,77 @@ class RNodeMultiInterface(Interface):
|
|||||||
|
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
|
c = configuration
|
||||||
|
name = c["name"]
|
||||||
|
|
||||||
|
count = 0
|
||||||
|
enabled_count = 0
|
||||||
|
|
||||||
|
# Count how many interfaces are in the file
|
||||||
|
for subinterface in c:
|
||||||
|
# if the retrieved entry is not a string, it must be a dictionary, which is what we want
|
||||||
|
if not isinstance(c[subinterface], str):
|
||||||
|
count += 1
|
||||||
|
|
||||||
|
# Count how many interfaces are enabled to allow for appropriate matrix sizing
|
||||||
|
for subinterface in c:
|
||||||
|
# if the retrieved entry is not a string, it must be a dictionary, which is what we want
|
||||||
|
if not isinstance(c[subinterface], str):
|
||||||
|
subinterface_config = self.config["interfaces"][name][subinterface]
|
||||||
|
if (("interface_enabled" in subinterface_config) and subinterface_config.as_bool("interface_enabled") == True) or (("enabled" in c) and c.as_bool("enabled") == True):
|
||||||
|
enabled_count += 1
|
||||||
|
|
||||||
|
# Create an array with a row for each subinterface
|
||||||
|
subint_config = [[0 for x in range(11)] for y in range(enabled_count)]
|
||||||
|
subint_index = 0
|
||||||
|
|
||||||
|
for subinterface in c:
|
||||||
|
# If the retrieved entry is not a string, it must be a dictionary, which is what we want
|
||||||
|
if not isinstance(c[subinterface], str):
|
||||||
|
subinterface_config = self.config["interfaces"][name][subinterface]
|
||||||
|
if (("interface_enabled" in subinterface_config) and subinterface_config.as_bool("interface_enabled") == True) or (("enabled" in c) and c.as_bool("enabled") == True):
|
||||||
|
subint_config[subint_index][0] = subinterface
|
||||||
|
|
||||||
|
subint_vport = subinterface_config["vport"] if "vport" in subinterface_config else None
|
||||||
|
subint_config[subint_index][1] = subint_vport
|
||||||
|
|
||||||
|
frequency = int(subinterface_config["frequency"]) if "frequency" in subinterface_config else None
|
||||||
|
subint_config[subint_index][2] = frequency
|
||||||
|
bandwidth = int(subinterface_config["bandwidth"]) if "bandwidth" in subinterface_config else None
|
||||||
|
subint_config[subint_index][3] = bandwidth
|
||||||
|
txpower = int(subinterface_config["txpower"]) if "txpower" in subinterface_config else None
|
||||||
|
subint_config[subint_index][4] = txpower
|
||||||
|
spreadingfactor = int(subinterface_config["spreadingfactor"]) if "spreadingfactor" in subinterface_config else None
|
||||||
|
subint_config[subint_index][5] = spreadingfactor
|
||||||
|
codingrate = int(subinterface_config["codingrate"]) if "codingrate" in subinterface_config else None
|
||||||
|
subint_config[subint_index][6] = codingrate
|
||||||
|
flow_control = subinterface_config.as_bool("flow_control") if "flow_control" in subinterface_config else False
|
||||||
|
subint_config[subint_index][7] = flow_control
|
||||||
|
st_alock = float(subinterface_config["airtime_limit_short"]) if "airtime_limit_short" in subinterface_config else None
|
||||||
|
subint_config[subint_index][8] = st_alock
|
||||||
|
lt_alock = float(subinterface_config["airtime_limit_long"]) if "airtime_limit_long" in subinterface_config else None
|
||||||
|
subint_config[subint_index][9] = lt_alock
|
||||||
|
|
||||||
|
if "outgoing" in subinterface_config and subinterface_config.as_bool("outgoing") == False:
|
||||||
|
subint_config[subint_index][10] = False
|
||||||
|
else:
|
||||||
|
subint_config[subint_index][10] = True
|
||||||
|
subint_index += 1
|
||||||
|
|
||||||
|
# if no subinterfaces are defined
|
||||||
|
if count == 0:
|
||||||
|
raise ValueError("No subinterfaces configured for "+name)
|
||||||
|
# if no subinterfaces are enabled
|
||||||
|
elif enabled_count == 0:
|
||||||
|
raise ValueError("No subinterfaces enabled for "+name)
|
||||||
|
|
||||||
|
id_interval = int(c["id_interval"]) if "id_interval" in c else None
|
||||||
|
id_callsign = c["id_callsign"] if "id_callsign" in c else None
|
||||||
|
port = c["port"] if "port" in c else None
|
||||||
|
|
||||||
|
if port == None:
|
||||||
|
raise ValueError("No port specified for "+name)
|
||||||
|
|
||||||
self.HW_MTU = 508
|
self.HW_MTU = 508
|
||||||
|
|
||||||
self.clients = 0
|
self.clients = 0
|
||||||
|
@ -42,6 +42,7 @@ class HDLC():
|
|||||||
|
|
||||||
class SerialInterface(Interface):
|
class SerialInterface(Interface):
|
||||||
MAX_CHUNK = 32768
|
MAX_CHUNK = 32768
|
||||||
|
DEFAULT_IFAC_SIZE = 8
|
||||||
|
|
||||||
owner = None
|
owner = None
|
||||||
port = None
|
port = None
|
||||||
@ -51,7 +52,7 @@ class SerialInterface(Interface):
|
|||||||
stopbits = None
|
stopbits = None
|
||||||
serial = None
|
serial = None
|
||||||
|
|
||||||
def __init__(self, owner, name, port, speed, databits, parity, stopbits):
|
def __init__(self, owner, configuration):
|
||||||
import importlib
|
import importlib
|
||||||
if importlib.util.find_spec('serial') != None:
|
if importlib.util.find_spec('serial') != None:
|
||||||
import serial
|
import serial
|
||||||
@ -62,6 +63,17 @@ class SerialInterface(Interface):
|
|||||||
|
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
|
c = configuration
|
||||||
|
name = c["name"]
|
||||||
|
port = c["port"] if "port" in c else None
|
||||||
|
speed = int(c["speed"]) if "speed" in c else 9600
|
||||||
|
databits = int(c["databits"]) if "databits" in c else 8
|
||||||
|
parity = c["parity"] if "parity" in c else "N"
|
||||||
|
stopbits = int(c["stopbits"]) if "stopbits" in c else 1
|
||||||
|
|
||||||
|
if port == None:
|
||||||
|
raise ValueError("No port specified for serial interface")
|
||||||
|
|
||||||
self.HW_MTU = 564
|
self.HW_MTU = 564
|
||||||
|
|
||||||
self.pyserial = serial
|
self.pyserial = serial
|
||||||
|
364
RNS/Reticulum.py
364
RNS/Reticulum.py
@ -446,14 +446,7 @@ class Reticulum:
|
|||||||
if "interfaces" in self.config:
|
if "interfaces" in self.config:
|
||||||
for name in self.config["interfaces"]:
|
for name in self.config["interfaces"]:
|
||||||
if not name in interface_names:
|
if not name in interface_names:
|
||||||
# TODO: We really need to generalise this way of instantiating
|
|
||||||
# and configuring interfaces. Ideally, interfaces should just
|
|
||||||
# have a conrfig dict passed to their init method, and return
|
|
||||||
# a ready interface, onto which this routine can configure any
|
|
||||||
# generic or extra parameters.
|
|
||||||
|
|
||||||
c = self.config["interfaces"][name]
|
c = self.config["interfaces"][name]
|
||||||
|
|
||||||
interface_mode = Interface.Interface.MODE_FULL
|
interface_mode = Interface.Interface.MODE_FULL
|
||||||
|
|
||||||
if "interface_mode" in c:
|
if "interface_mode" in c:
|
||||||
@ -602,360 +595,41 @@ class Reticulum:
|
|||||||
interface_post_init(interface)
|
interface_post_init(interface)
|
||||||
|
|
||||||
if c["type"] == "I2PInterface":
|
if c["type"] == "I2PInterface":
|
||||||
i2p_peers = c.as_list("peers") if "peers" in c else None
|
|
||||||
connectable = c.as_bool("connectable") if "connectable" in c else False
|
|
||||||
|
|
||||||
if ifac_size == None:
|
|
||||||
ifac_size = 16
|
|
||||||
|
|
||||||
interface = I2PInterface.I2PInterface(
|
|
||||||
RNS.Transport,
|
|
||||||
name,
|
|
||||||
Reticulum.storagepath,
|
|
||||||
i2p_peers,
|
|
||||||
connectable = connectable,
|
|
||||||
ifac_size = ifac_size,
|
|
||||||
ifac_netname = ifac_netname,
|
|
||||||
ifac_netkey = ifac_netkey,
|
|
||||||
)
|
|
||||||
|
|
||||||
if "outgoing" in c and c.as_bool("outgoing") == False:
|
|
||||||
interface.OUT = False
|
|
||||||
else:
|
|
||||||
interface.OUT = True
|
|
||||||
|
|
||||||
if interface_mode == Interface.Interface.MODE_ACCESS_POINT:
|
if interface_mode == Interface.Interface.MODE_ACCESS_POINT:
|
||||||
RNS.log(str(interface)+" does not support Access Point mode, reverting to default mode: Full", RNS.LOG_WARNING)
|
RNS.log(str(interface)+" does not support Access Point mode, reverting to default mode: Full", RNS.LOG_WARNING)
|
||||||
interface_mode = Interface.Interface.MODE_FULL
|
interface_mode = Interface.Interface.MODE_FULL
|
||||||
|
|
||||||
interface.mode = interface_mode
|
interface_config["storagepath"] = Reticulum.storagepath
|
||||||
|
interface_config["ifac_netname"] = ifac_netname
|
||||||
|
interface_config["ifac_netkey"] = ifac_netkey
|
||||||
|
interface_config["ifac_size"] = ifac_size
|
||||||
|
|
||||||
interface.announce_cap = announce_cap
|
interface = I2PInterface.I2PInterface(RNS.Transport, interface_config)
|
||||||
if configured_bitrate:
|
interface_post_init(interface)
|
||||||
interface.bitrate = configured_bitrate
|
|
||||||
|
|
||||||
if c["type"] == "SerialInterface":
|
if c["type"] == "SerialInterface":
|
||||||
port = c["port"] if "port" in c else None
|
interface = SerialInterface.SerialInterface(RNS.Transport, interface_config)
|
||||||
speed = int(c["speed"]) if "speed" in c else 9600
|
interface_post_init(interface)
|
||||||
databits = int(c["databits"]) if "databits" in c else 8
|
|
||||||
parity = c["parity"] if "parity" in c else "N"
|
|
||||||
stopbits = int(c["stopbits"]) if "stopbits" in c else 1
|
|
||||||
|
|
||||||
if port == None:
|
|
||||||
raise ValueError("No port specified for serial interface")
|
|
||||||
|
|
||||||
interface = SerialInterface.SerialInterface(
|
|
||||||
RNS.Transport,
|
|
||||||
name,
|
|
||||||
port,
|
|
||||||
speed,
|
|
||||||
databits,
|
|
||||||
parity,
|
|
||||||
stopbits
|
|
||||||
)
|
|
||||||
|
|
||||||
if "outgoing" in c and c.as_bool("outgoing") == False:
|
|
||||||
interface.OUT = False
|
|
||||||
else:
|
|
||||||
interface.OUT = True
|
|
||||||
|
|
||||||
interface.mode = interface_mode
|
|
||||||
|
|
||||||
interface.announce_cap = announce_cap
|
|
||||||
if configured_bitrate:
|
|
||||||
interface.bitrate = configured_bitrate
|
|
||||||
if ifac_size != None:
|
|
||||||
interface.ifac_size = ifac_size
|
|
||||||
else:
|
|
||||||
interface.ifac_size = 8
|
|
||||||
|
|
||||||
if c["type"] == "PipeInterface":
|
if c["type"] == "PipeInterface":
|
||||||
command = c["command"] if "command" in c else None
|
interface = PipeInterface.PipeInterface(RNS.Transport, interface_config)
|
||||||
respawn_delay = c.as_float("respawn_delay") if "respawn_delay" in c else None
|
interface_post_init(interface)
|
||||||
|
|
||||||
if command == None:
|
|
||||||
raise ValueError("No command specified for PipeInterface")
|
|
||||||
|
|
||||||
interface = PipeInterface.PipeInterface(
|
|
||||||
RNS.Transport,
|
|
||||||
name,
|
|
||||||
command,
|
|
||||||
respawn_delay,
|
|
||||||
)
|
|
||||||
|
|
||||||
if "outgoing" in c and c.as_bool("outgoing") == False:
|
|
||||||
interface.OUT = False
|
|
||||||
else:
|
|
||||||
interface.OUT = True
|
|
||||||
|
|
||||||
interface.mode = interface_mode
|
|
||||||
|
|
||||||
interface.announce_cap = announce_cap
|
|
||||||
if configured_bitrate:
|
|
||||||
interface.bitrate = configured_bitrate
|
|
||||||
if ifac_size != None:
|
|
||||||
interface.ifac_size = ifac_size
|
|
||||||
else:
|
|
||||||
interface.ifac_size = 8
|
|
||||||
|
|
||||||
if c["type"] == "KISSInterface":
|
if c["type"] == "KISSInterface":
|
||||||
preamble = int(c["preamble"]) if "preamble" in c else None
|
interface = KISSInterface.KISSInterface(RNS.Transport, interface_config)
|
||||||
txtail = int(c["txtail"]) if "txtail" in c else None
|
interface_post_init(interface)
|
||||||
persistence = int(c["persistence"]) if "persistence" in c else None
|
|
||||||
slottime = int(c["slottime"]) if "slottime" in c else None
|
|
||||||
flow_control = c.as_bool("flow_control") if "flow_control" in c else False
|
|
||||||
port = c["port"] if "port" in c else None
|
|
||||||
speed = int(c["speed"]) if "speed" in c else 9600
|
|
||||||
databits = int(c["databits"]) if "databits" in c else 8
|
|
||||||
parity = c["parity"] if "parity" in c else "N"
|
|
||||||
stopbits = int(c["stopbits"]) if "stopbits" in c else 1
|
|
||||||
beacon_interval = int(c["id_interval"]) if "id_interval" in c else None
|
|
||||||
beacon_data = c["id_callsign"] if "id_callsign" in c else None
|
|
||||||
|
|
||||||
if port == None:
|
|
||||||
raise ValueError("No port specified for serial interface")
|
|
||||||
|
|
||||||
interface = KISSInterface.KISSInterface(
|
|
||||||
RNS.Transport,
|
|
||||||
name,
|
|
||||||
port,
|
|
||||||
speed,
|
|
||||||
databits,
|
|
||||||
parity,
|
|
||||||
stopbits,
|
|
||||||
preamble,
|
|
||||||
txtail,
|
|
||||||
persistence,
|
|
||||||
slottime,
|
|
||||||
flow_control,
|
|
||||||
beacon_interval,
|
|
||||||
beacon_data
|
|
||||||
)
|
|
||||||
|
|
||||||
if "outgoing" in c and c.as_bool("outgoing") == False:
|
|
||||||
interface.OUT = False
|
|
||||||
else:
|
|
||||||
interface.OUT = True
|
|
||||||
|
|
||||||
interface.mode = interface_mode
|
|
||||||
|
|
||||||
interface.announce_cap = announce_cap
|
|
||||||
if configured_bitrate:
|
|
||||||
interface.bitrate = configured_bitrate
|
|
||||||
if ifac_size != None:
|
|
||||||
interface.ifac_size = ifac_size
|
|
||||||
else:
|
|
||||||
interface.ifac_size = 8
|
|
||||||
|
|
||||||
if c["type"] == "AX25KISSInterface":
|
if c["type"] == "AX25KISSInterface":
|
||||||
preamble = int(c["preamble"]) if "preamble" in c else None
|
interface = AX25KISSInterface.AX25KISSInterface(RNS.Transport, interface_config)
|
||||||
txtail = int(c["txtail"]) if "txtail" in c else None
|
interface_post_init(interface)
|
||||||
persistence = int(c["persistence"]) if "persistence" in c else None
|
|
||||||
slottime = int(c["slottime"]) if "slottime" in c else None
|
|
||||||
flow_control = c.as_bool("flow_control") if "flow_control" in c else False
|
|
||||||
port = c["port"] if "port" in c else None
|
|
||||||
speed = int(c["speed"]) if "speed" in c else 9600
|
|
||||||
databits = int(c["databits"]) if "databits" in c else 8
|
|
||||||
parity = c["parity"] if "parity" in c else "N"
|
|
||||||
stopbits = int(c["stopbits"]) if "stopbits" in c else 1
|
|
||||||
|
|
||||||
callsign = c["callsign"] if "callsign" in c else ""
|
|
||||||
ssid = int(c["ssid"]) if "ssid" in c else -1
|
|
||||||
|
|
||||||
if port == None:
|
|
||||||
raise ValueError("No port specified for serial interface")
|
|
||||||
|
|
||||||
interface = AX25KISSInterface.AX25KISSInterface(
|
|
||||||
RNS.Transport,
|
|
||||||
name,
|
|
||||||
callsign,
|
|
||||||
ssid,
|
|
||||||
port,
|
|
||||||
speed,
|
|
||||||
databits,
|
|
||||||
parity,
|
|
||||||
stopbits,
|
|
||||||
preamble,
|
|
||||||
txtail,
|
|
||||||
persistence,
|
|
||||||
slottime,
|
|
||||||
flow_control
|
|
||||||
)
|
|
||||||
|
|
||||||
if "outgoing" in c and c.as_bool("outgoing") == False:
|
|
||||||
interface.OUT = False
|
|
||||||
else:
|
|
||||||
interface.OUT = True
|
|
||||||
|
|
||||||
interface.mode = interface_mode
|
|
||||||
|
|
||||||
interface.announce_cap = announce_cap
|
|
||||||
if configured_bitrate:
|
|
||||||
interface.bitrate = configured_bitrate
|
|
||||||
if ifac_size != None:
|
|
||||||
interface.ifac_size = ifac_size
|
|
||||||
else:
|
|
||||||
interface.ifac_size = 8
|
|
||||||
|
|
||||||
if c["type"] == "RNodeInterface":
|
if c["type"] == "RNodeInterface":
|
||||||
frequency = int(c["frequency"]) if "frequency" in c else None
|
interface = RNodeInterface.RNodeInterface(RNS.Transport, interface_config)
|
||||||
bandwidth = int(c["bandwidth"]) if "bandwidth" in c else None
|
interface_post_init(interface)
|
||||||
txpower = int(c["txpower"]) if "txpower" in c else None
|
|
||||||
spreadingfactor = int(c["spreadingfactor"]) if "spreadingfactor" in c else None
|
|
||||||
codingrate = int(c["codingrate"]) if "codingrate" in c else None
|
|
||||||
flow_control = c.as_bool("flow_control") if "flow_control" in c else False
|
|
||||||
id_interval = int(c["id_interval"]) if "id_interval" in c else None
|
|
||||||
id_callsign = c["id_callsign"] if "id_callsign" in c else None
|
|
||||||
st_alock = float(c["airtime_limit_short"]) if "airtime_limit_short" in c else None
|
|
||||||
lt_alock = float(c["airtime_limit_long"]) if "airtime_limit_long" in c else None
|
|
||||||
|
|
||||||
force_ble = False
|
|
||||||
ble_name = None
|
|
||||||
ble_addr = None
|
|
||||||
|
|
||||||
port = c["port"] if "port" in c else None
|
|
||||||
|
|
||||||
if port == None:
|
|
||||||
raise ValueError("No port specified for RNode interface")
|
|
||||||
|
|
||||||
if port != None:
|
|
||||||
ble_uri_scheme = "ble://"
|
|
||||||
if port.lower().startswith(ble_uri_scheme):
|
|
||||||
force_ble = True
|
|
||||||
ble_string = port[len(ble_uri_scheme):]
|
|
||||||
port = None
|
|
||||||
if len(ble_string) == 0:
|
|
||||||
pass
|
|
||||||
elif len(ble_string.split(":")) == 6 and len(ble_string) == 17:
|
|
||||||
ble_addr = ble_string
|
|
||||||
else:
|
|
||||||
ble_name = ble_string
|
|
||||||
|
|
||||||
interface = RNodeInterface.RNodeInterface(
|
|
||||||
RNS.Transport,
|
|
||||||
name,
|
|
||||||
port,
|
|
||||||
frequency = frequency,
|
|
||||||
bandwidth = bandwidth,
|
|
||||||
txpower = txpower,
|
|
||||||
sf = spreadingfactor,
|
|
||||||
cr = codingrate,
|
|
||||||
flow_control = flow_control,
|
|
||||||
id_interval = id_interval,
|
|
||||||
id_callsign = id_callsign,
|
|
||||||
st_alock = st_alock,
|
|
||||||
lt_alock = lt_alock,
|
|
||||||
ble_addr = ble_addr,
|
|
||||||
ble_name = ble_name,
|
|
||||||
force_ble = force_ble,
|
|
||||||
)
|
|
||||||
|
|
||||||
if "outgoing" in c and c.as_bool("outgoing") == False:
|
|
||||||
interface.OUT = False
|
|
||||||
else:
|
|
||||||
interface.OUT = True
|
|
||||||
|
|
||||||
interface.mode = interface_mode
|
|
||||||
|
|
||||||
interface.announce_cap = announce_cap
|
|
||||||
if configured_bitrate:
|
|
||||||
interface.bitrate = configured_bitrate
|
|
||||||
if ifac_size != None:
|
|
||||||
interface.ifac_size = ifac_size
|
|
||||||
else:
|
|
||||||
interface.ifac_size = 8
|
|
||||||
|
|
||||||
if c["type"] == "RNodeMultiInterface":
|
if c["type"] == "RNodeMultiInterface":
|
||||||
count = 0
|
interface = RNodeMultiInterface.RNodeMultiInterface(RNS.Transport, interface_config)
|
||||||
enabled_count = 0
|
interface_post_init(interface)
|
||||||
|
|
||||||
# Count how many interfaces are in the file
|
|
||||||
for subinterface in c:
|
|
||||||
# if the retrieved entry is not a string, it must be a dictionary, which is what we want
|
|
||||||
if not isinstance(c[subinterface], str):
|
|
||||||
count += 1
|
|
||||||
|
|
||||||
# Count how many interfaces are enabled to allow for appropriate matrix sizing
|
|
||||||
for subinterface in c:
|
|
||||||
# if the retrieved entry is not a string, it must be a dictionary, which is what we want
|
|
||||||
if not isinstance(c[subinterface], str):
|
|
||||||
subinterface_config = self.config["interfaces"][name][subinterface]
|
|
||||||
if (("interface_enabled" in subinterface_config) and subinterface_config.as_bool("interface_enabled") == True) or (("enabled" in c) and c.as_bool("enabled") == True):
|
|
||||||
enabled_count += 1
|
|
||||||
|
|
||||||
# Create an array with a row for each subinterface
|
|
||||||
subint_config = [[0 for x in range(11)] for y in range(enabled_count)]
|
|
||||||
subint_index = 0
|
|
||||||
|
|
||||||
for subinterface in c:
|
|
||||||
# If the retrieved entry is not a string, it must be a dictionary, which is what we want
|
|
||||||
if not isinstance(c[subinterface], str):
|
|
||||||
subinterface_config = self.config["interfaces"][name][subinterface]
|
|
||||||
if (("interface_enabled" in subinterface_config) and subinterface_config.as_bool("interface_enabled") == True) or (("enabled" in c) and c.as_bool("enabled") == True):
|
|
||||||
subint_config[subint_index][0] = subinterface
|
|
||||||
|
|
||||||
subint_vport = subinterface_config["vport"] if "vport" in subinterface_config else None
|
|
||||||
subint_config[subint_index][1] = subint_vport
|
|
||||||
|
|
||||||
frequency = int(subinterface_config["frequency"]) if "frequency" in subinterface_config else None
|
|
||||||
subint_config[subint_index][2] = frequency
|
|
||||||
bandwidth = int(subinterface_config["bandwidth"]) if "bandwidth" in subinterface_config else None
|
|
||||||
subint_config[subint_index][3] = bandwidth
|
|
||||||
txpower = int(subinterface_config["txpower"]) if "txpower" in subinterface_config else None
|
|
||||||
subint_config[subint_index][4] = txpower
|
|
||||||
spreadingfactor = int(subinterface_config["spreadingfactor"]) if "spreadingfactor" in subinterface_config else None
|
|
||||||
subint_config[subint_index][5] = spreadingfactor
|
|
||||||
codingrate = int(subinterface_config["codingrate"]) if "codingrate" in subinterface_config else None
|
|
||||||
subint_config[subint_index][6] = codingrate
|
|
||||||
flow_control = subinterface_config.as_bool("flow_control") if "flow_control" in subinterface_config else False
|
|
||||||
subint_config[subint_index][7] = flow_control
|
|
||||||
st_alock = float(subinterface_config["airtime_limit_short"]) if "airtime_limit_short" in subinterface_config else None
|
|
||||||
subint_config[subint_index][8] = st_alock
|
|
||||||
lt_alock = float(subinterface_config["airtime_limit_long"]) if "airtime_limit_long" in subinterface_config else None
|
|
||||||
subint_config[subint_index][9] = lt_alock
|
|
||||||
|
|
||||||
if "outgoing" in subinterface_config and subinterface_config.as_bool("outgoing") == False:
|
|
||||||
subint_config[subint_index][10] = False
|
|
||||||
else:
|
|
||||||
subint_config[subint_index][10] = True
|
|
||||||
subint_index += 1
|
|
||||||
|
|
||||||
# if no subinterfaces are defined
|
|
||||||
if count == 0:
|
|
||||||
raise ValueError("No subinterfaces configured for "+name)
|
|
||||||
# if no subinterfaces are enabled
|
|
||||||
elif enabled_count == 0:
|
|
||||||
raise ValueError("No subinterfaces enabled for "+name)
|
|
||||||
|
|
||||||
id_interval = int(c["id_interval"]) if "id_interval" in c else None
|
|
||||||
id_callsign = c["id_callsign"] if "id_callsign" in c else None
|
|
||||||
port = c["port"] if "port" in c else None
|
|
||||||
|
|
||||||
if port == None:
|
|
||||||
raise ValueError("No port specified for "+name)
|
|
||||||
|
|
||||||
interface = RNodeMultiInterface.RNodeMultiInterface(
|
|
||||||
RNS.Transport,
|
|
||||||
name,
|
|
||||||
port,
|
|
||||||
subint_config,
|
|
||||||
id_interval = id_interval,
|
|
||||||
id_callsign = id_callsign
|
|
||||||
)
|
|
||||||
|
|
||||||
interface.IN = False
|
|
||||||
interface.OUT = False
|
|
||||||
|
|
||||||
interface.mode = interface_mode
|
|
||||||
|
|
||||||
interface.announce_cap = announce_cap
|
|
||||||
if configured_bitrate:
|
|
||||||
interface.bitrate = configured_bitrate
|
|
||||||
if ifac_size != None:
|
|
||||||
interface.ifac_size = ifac_size
|
|
||||||
else:
|
|
||||||
interface.ifac_size = 8
|
|
||||||
|
|
||||||
|
|
||||||
if interface != None:
|
if interface != None:
|
||||||
interface.announce_rate_target = announce_rate_target
|
interface.announce_rate_target = announce_rate_target
|
||||||
@ -1011,7 +685,7 @@ class Reticulum:
|
|||||||
|
|
||||||
RNS.log("System interfaces are ready", RNS.LOG_VERBOSE)
|
RNS.log("System interfaces are ready", RNS.LOG_VERBOSE)
|
||||||
|
|
||||||
def _add_interface(self,interface, mode = None, configured_bitrate=None, ifac_size=None, ifac_netname=None, ifac_netkey=None, announce_cap=None, announce_rate_target=None, announce_rate_grace=None, announce_rate_penalty=None):
|
def _add_interface(self, interface, mode = None, configured_bitrate=None, ifac_size=None, ifac_netname=None, ifac_netkey=None, announce_cap=None, announce_rate_target=None, announce_rate_grace=None, announce_rate_penalty=None):
|
||||||
if not self.is_connected_to_shared_instance:
|
if not self.is_connected_to_shared_instance:
|
||||||
if interface != None and issubclass(type(interface), RNS.Interfaces.Interface.Interface):
|
if interface != None and issubclass(type(interface), RNS.Interfaces.Interface.Interface):
|
||||||
|
|
||||||
|
@ -493,7 +493,7 @@ Multi interface can be used to configure sub-interfaces individually.
|
|||||||
# id_interval = 600
|
# id_interval = 600
|
||||||
|
|
||||||
# A subinterface
|
# A subinterface
|
||||||
[[[HIGHDATARATE]]]
|
[[[High Datarate]]]
|
||||||
# Subinterfaces can be enabled and disabled in of themselves
|
# Subinterfaces can be enabled and disabled in of themselves
|
||||||
interface_enabled = True
|
interface_enabled = True
|
||||||
|
|
||||||
@ -535,7 +535,7 @@ Multi interface can be used to configure sub-interfaces individually.
|
|||||||
# airtime_limit_long = 100
|
# airtime_limit_long = 100
|
||||||
# airtime_limit_short = 100
|
# airtime_limit_short = 100
|
||||||
|
|
||||||
[[[LOWDATARATE]]]
|
[[[Low Datarate]]]
|
||||||
# Subinterfaces can be enabled and disabled in of themselves
|
# Subinterfaces can be enabled and disabled in of themselves
|
||||||
interface_enabled = True
|
interface_enabled = True
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user