Skip to content

Commit

Permalink
Update work in progress files to git
Browse files Browse the repository at this point in the history
Jira-Id: SCDI-43

Signed-off-by: Mika Joenpera <[email protected]>
  • Loading branch information
joenpera committed Oct 13, 2023
1 parent d3b2709 commit 8d90c72
Show file tree
Hide file tree
Showing 8 changed files with 72 additions and 156 deletions.
4 changes: 2 additions & 2 deletions common/scripts/mesh-11s_nats.sh
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ EOF
"mesh")

cat <<EOF >/var/run/wpa_supplicant-11s_"$INDEX"_"$wifidev".conf
ctrl_interface=DIR=/var/run/wpa_supplicant
ctrl_interface=DIR=/var/run/wpa_supplicant_$INDEX
# use 'ap_scan=2' on all devices connected to the network
# this is unnecessary if you only want the network to be created when no other networks..
ap_scan=1
Expand Down Expand Up @@ -321,7 +321,7 @@ EOF
iptables -A FORWARD --in-interface "$batman_iface" -j ACCEPT
iptables --table nat -A POSTROUTING --out-interface "$br_lan_ip" -j MASQUERADE

wpa_supplicant -i "$wifidev" -c /var/run/wpa_supplicant-11s_"$INDEX"_"$wifidev".conf -D nl80211 -C /var/run/wpa_supplicant/ -f /tmp/wpa_supplicant_11s_"$INDEX".log
wpa_supplicant -i "$wifidev" -c /var/run/wpa_supplicant-11s_"$INDEX"_"$wifidev".conf -D nl80211 -C /var/run/wpa_supplicant_"$INDEX"/ -f /tmp/wpa_supplicant_11s_"$INDEX".log
;;
"ap+mesh_mcc")
wait_for_intf "$bridge_name"
Expand Down
2 changes: 1 addition & 1 deletion common/scripts/mesh-helper.sh
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ EOF

generate_br_lan_ip() {
local mesh_if_mac
mesh_if_mac="$(ip -brief link | grep "$id0_MESH_VIF" | awk '{print $3; exit}')"
mesh_if_mac="$(ip -brief link | grep "${id0_MESH_VIF}" | awk '{print $3; exit}')"
local ip_random
ip_random="$(echo "$mesh_if_mac" | cut -b 16-17)"
br_lan_ip="192.168.1."$((16#$ip_random))
Expand Down
80 changes: 22 additions & 58 deletions modules/sc-mesh-secure-deployment/src/nats/comms_nats_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,43 +91,33 @@ def __init__(self, server: str, port: str, interval: int = 1000):
console_handler.setFormatter(log_formatter)
self.main_logger.addHandler(console_handler)

self.comms_status = []
self.c_status = []
#TODO how many radios?
for i in range(0, 3):
self.comms_status.append(comms_status.CommsStatus(self.main_logger.getChild(f"status {str(i)}"), i))
self.c_status.append(comms_status.CommsStatus(self.main_logger.getChild(f"status {str(i)}"), i))

self.settings = comms_settings.CommsSettings(self.comms_status,
self.settings = comms_settings.CommsSettings(self.c_status,
self.main_logger.getChild("settings"))

for cstat in self.comms_status:
cstat.settings(self.settings)
for cstat in self.c_status:
if cstat.index < len(self.settings.mesh_vif):
cstat.wifi_interface = self.settings.mesh_vif[cstat.index]

self.command = comms_command.Command(server, port, self.comms_status,
self.command = comms_command.Command(server, port, self.c_status,
self.main_logger.getChild("command"))
self.telemetry = MeshTelemetry(self.interval, self.main_logger.getChild("telemetry"))

# logger for this module and derived from main logger
self.logger = self.main_logger.getChild("controller")


class CommsCsa: # pylint: disable=too-few-public-methods
"""
Comms CSA class to storage settings for CSA for a state change
"""

def __init__(self):
self.delay = "0"
self.ack_sent = False


# pylint: disable=too-many-arguments, too-many-locals, too-many-statements
async def main(server, port, keyfile=None, certfile=None, interval=1000):
"""
main
"""
cc = CommsController(server, port, interval)
nats_client = NATS()
csac = CommsCsa()

status, _, identity_dict = cc.command.get_identity()

Expand Down Expand Up @@ -178,23 +168,6 @@ async def reconnected_cb():
disconnected_cb=disconnected_cb,
max_reconnect_attempts=-1)

async def handle_settings_csa_post(ret):
if ret == "OK":
ret = "ACK"
elif ret == "TRIGGER":
cmd = json.dumps({"api_version": 1, "cmd": "APPLY"})
cc.command.handle_command(cmd, cc, True, csac.delay)
elif ret == "COUNT":
ret = "COUNT" # not to send ACK/NACK
else:
ret = "NACK"

if ret in ("ACK", "NACK") and csac.ack_sent is False:
response = {'status': ret}
cc.logger.debug("publish response: %s", str(response))
await nats_client.publish("comms.settings_csa",
json.dumps(response).encode("utf-8"))
csac.ack_sent = True

async def message_handler(message):
# reply = message.reply
Expand All @@ -205,39 +178,30 @@ async def message_handler(message):

if subject == f"comms.settings.{identity}":
ret, info = cc.settings.handle_mesh_settings(data)
elif subject == "comms.settings_csa":
ret, info, delay = cc.settings.handle_mesh_settings_csa(data)
csac.delay = delay
csac.ack_sent = "status" in data

elif subject == f"comms.command.{identity}" or subject == "comms.identity":
elif subject in (f"comms.command.{identity}", "comms.identity"):
ret, info, resp = cc.command.handle_command(data, cc)
elif subject == f"comms.status.{identity}":
ret, info = "OK", "Returning current status"

if subject == "comms.settings_csa":
await handle_settings_csa_post(ret)
else:
# Update status info
_ = [item.refresh_status() for item in cc.comms_status]
# Update status info
_ = [item.refresh_status() for item in cc.c_status]

response = {'status': ret, 'info': info,
'mesh_status': [item.mesh_status for item in cc.comms_status],
'mesh_cfg_status': [item.mesh_cfg_status for item in cc.comms_status],
'visualisation_active': [item.is_visualisation_active for item in cc.comms_status],
'mesh_radio_on': [item.is_mesh_radio_on for item in cc.comms_status],
'ap_radio_on': [item.is_ap_radio_on for item in cc.comms_status],
'security_status': [item.security_status for item in cc.comms_status]
}
response = {'status': ret, 'info': info,
'mesh_status': [item.mesh_status for item in cc.c_status],
'mesh_cfg_status': [item.mesh_cfg_status for item in cc.c_status],
'visualisation_active': [item.is_visualisation_active for item in cc.c_status],
'mesh_radio_on': [item.is_mesh_radio_on for item in cc.c_status],
'ap_radio_on': [item.is_ap_radio_on for item in cc.c_status],
'security_status': [item.security_status for item in cc.c_status]
}

if resp != "":
response['data'] = resp
if resp != "":
response['data'] = resp

cc.logger.debug("Sending response: %s", str(response)[:1000])
await message.respond(json.dumps(response).encode("utf-8"))
cc.logger.debug("Sending response: %s", str(response)[:1000])
await message.respond(json.dumps(response).encode("utf-8"))

await nats_client.subscribe(f"comms.settings.{identity}", cb=message_handler)
await nats_client.subscribe("comms.settings_csa", cb=message_handler)
await nats_client.subscribe(f"comms.command.{identity}", cb=message_handler)
await nats_client.subscribe("comms.identity", cb=message_handler)
await nats_client.subscribe(f"comms.status.{identity}", cb=message_handler)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ async def main():
},
{
"radio_index": "1",
"ssid": "test_mesh",
"ssid": "test_mesh2",
"key": "1234567890",
"ap_mac": "00:11:22:33:44:55",
"country": "FI",
Expand All @@ -44,19 +44,19 @@ async def main():
"tx_power": "5",
"mode": "mesh",
"mesh_vif": "wlp1s2",
"phy": "phy1",
"phy": "phy2",
"batman_iface": "bat0",
},
],
"bridge": "br-lan bat0 lan1"
"bridge": "br-lan bat0 eth1 lan1"
}

cmd = json.dumps(cmd_dict)
rep = await nc.request(
f"comms.settings.{config.MODULE_IDENTITY}", cmd.encode(), timeout=2
)
parameters = json.loads(rep.data)
print(parameters)
print(json.dumps(parameters, indent=2))

await nc.close()
exit(0)
Expand Down
19 changes: 4 additions & 15 deletions modules/sc-mesh-secure-deployment/src/nats/src/comms_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
from .comms_common import STATUS, COMMAND
from .comms_status import CommsStatus


class LogFiles: # pylint: disable=too-few-public-methods
"""
LogFiles class
Expand Down Expand Up @@ -59,15 +58,13 @@ def __init__(self, server, port, comms_status: [CommsStatus, ...], logger):
self.interval = 1
self.comms_status = comms_status

def handle_command(self, msg: str, cc, csa=False, delay="0") -> (str, str, str):
def handle_command(self, msg: str, cc) -> (str, str, str):
"""
handler for commands
Args:
msg: JSON formatted data from NATS message.
cc: CommsController class
csa: bool: True if CSA is active
delay: str: delay for channel change in csa case
Returns:
str: OK/FAIL
Expand Down Expand Up @@ -98,7 +95,7 @@ def handle_command(self, msg: str, cc, csa=False, delay="0") -> (str, str, str):
elif self.command == COMMAND.revoke:
ret, info = self.__revoke(cc)
elif self.command == COMMAND.apply:
ret, info = self.__apply_mission_config(csa, delay)
ret, info = self.__apply_mission_config()
elif self.command == COMMAND.wifi_down:
ret, info = self.__radio_down()
elif self.command == COMMAND.wifi_up:
Expand Down Expand Up @@ -172,7 +169,7 @@ def __revoke(self, cc) -> (str, str):

return "OK", "Mesh settings revoked"

def __apply_mission_config(self, csa=False, delay="0") -> (str, str):
def __apply_mission_config(self) -> (str, str):
"""
Replaces active mesh configuration file with previously
stored content and restarts S9011Mesh with new configs.
Expand Down Expand Up @@ -206,18 +203,10 @@ def __apply_mission_config(self, csa=False, delay="0") -> (str, str):
# matches then mission config is applied. Otherwise, default mesh
# is applied. That logic is based on assumption that some
# wireless connectivity needs to be ensured after reboot.
if csa:
processes = ["/opt/S9011sNatsMesh", "/opt/S90APoint"]
else:
processes = ["/opt/S9011sNatsMesh", "/opt/S90APoint", "/opt/S90nats_discovery"]
processes = ["/opt/S9011sNatsMesh", "/opt/S90APoint", "/opt/S90nats_discovery"]

for process in processes:
# delay before restarting mesh using delay
if delay != "0":
ret = subprocess.run(["sleep", delay],
shell=False, check=True,
capture_output=True)

ret = subprocess.run([process, "restart", "id" + self.radio_index],
shell=False, check=True,
capture_output=True)
Expand Down
90 changes: 29 additions & 61 deletions modules/sc-mesh-secure-deployment/src/nats/src/comms_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,10 @@ def __init__(self, comms_status: [cs.CommsStatus, ...], logger):
self.msversion: str = ""
self.delay:str = "" # delay for channel change
self.comms_status = comms_status
self.csa_state: int = 0 # 0: not started, 1: stored, 2: triggered
self.csa_count: int = 0 # number of CSA triggered
self.device_amount: str = "0" # number of devices to trigger CSA from nats message
# TODO: check can we do this
# ret, info = self.__load_settings()
# self.logger.debug("load settings: %s, %s", ret, info)
self.default_mesh = True
ret, info = self.__load_settings()
self.logger.debug("load settings: %s, %s", ret, info)

def validate_mesh_settings(self, index: int) -> (str, str):
"""
Expand Down Expand Up @@ -123,70 +121,36 @@ def validate_mesh_settings(self, index: int) -> (str, str):

return "OK", "Mesh settings OK"

def handle_mesh_settings_csa(self, msg: str, path="/opt",
file="mesh_stored.conf") -> (str, str, str):
"""
Handle mesh settings
"""
# TODO: check implementation
try:
parameters = json.loads(msg)
if "status" in parameters and self.csa_state == 1:
self.csa_count = self.csa_count + 1
if self.csa_count >= int(self.device_amount):
self.csa_state = 2
self.logger.debug(f"Trigger channel switch to {self.frequency}")
return "TRIGGER", "Channel switch triggered", self.delay
return "COUNT", "Channel switch count", self.delay

self.csa_state = 0
ret, info = self.__load_settings()
self.logger.debug("load settings: %s, %s", ret, info)

#self.api_version = int(parameters["api_version"])
self.frequency, self.delay, self.device_amount= map(quote,
(str(parameters["frequency"]),
str(parameters["delay"]),
str(parameters["amount"])))

if validation.validate_delay(self.delay) and validation.validate_frequency(int(self.frequency)):
ret, info = "OK", "CSA settings OK"
else:
ret, info = "FAIL", "Invalid delay or frequency"

self.logger.debug(" settings validation: %s, %s", ret, info)
if ret == "FAIL":
self.comms_status.mesh_cfg_status = \
comms.STATUS.mesh_cfg_not_stored
self.logger.error("save settings failed: %s, %s", ret, info)
else:
ret, info = self.__save_settings(path, file, index)
self.logger.debug("save settings: %s, %s", ret, info)
self.csa_state = 1
self.csa_count = 0

return ret, info, self.delay

except (json.decoder.JSONDecodeError, KeyError,
TypeError, AttributeError) as error:
self.comms_status.mesh_cfg_status = \
comms.STATUS.mesh_cfg_not_stored
ret, info = "FAIL", "JSON format not correct" + str(error)
self.logger.error("csa settings validation: %s, %s", ret, info)

return ret, info, self.delay

def handle_mesh_settings(self, msg: str, path="/opt",
file="mesh_stored.conf") -> (str, str):
"""
Handle mesh settings
"""
try:
parameters_set = json.loads(msg)

self.msversion = "nats"
self.api_version = int(parameters_set["api_version"])
self.role = quote(str(parameters_set["role"]))

if self.default_mesh:
self.radio_index = []
self.ssid = []
self.key = []
self.ap_mac = []
self.country = []
self.frequency = []
self.frequency_mcc = []
self.ip_address = []
self.subnet = []
self.tx_power = []
self.mode = []
self.routing = []
self.priority = []
self.mesh_vif = []
self.phy = []
self.batman_iface = []

for parameters in parameters_set["radios"]:
self.radio_index.append(int(parameters["radio_index"]))
self.ssid.append(quote(str(parameters["ssid"])))
Expand All @@ -207,8 +171,6 @@ def handle_mesh_settings(self, msg: str, path="/opt",

self.bridge = quote(str(parameters_set["bridge"]))

ret, info = "FAIL", "Before validation"

for index in self.radio_index:
self.logger.debug("Mesh settings validation index: %s", str(index))
ret, info = self.validate_mesh_settings(index)
Expand All @@ -222,6 +184,8 @@ def handle_mesh_settings(self, msg: str, path="/opt",
ret, info = self.__save_settings(path, file, index)
self.logger.debug("save settings index %s: %s, %s", str(index), ret, info)

self.default_mesh = False

except (json.decoder.JSONDecodeError, KeyError,
TypeError, AttributeError) as error:
self.comms_status.mesh_cfg_status = \
Expand Down Expand Up @@ -330,16 +294,20 @@ def __load_settings(self) -> (str, str):
for index in range(0, len(self.comms_status)):
file = f"/opt/{str(index)}_mesh.conf"
if os.path.exists(file):
self.default_mesh = False
self.logger.debug("mesh config file %s found", file)
with open(file, "r", encoding="utf-8") as mesh_conf:
mesh_conf_lines = mesh_conf.read()
self.__read_configs(mesh_conf_lines)
else:
self.logger.debug("mesh config file %s not found, loading default", file)
if index == 0:
self.default_mesh = True
self.logger.debug("mesh config file %s not found, loading default", file)
with open(config_file_path, "r", encoding="utf-8") as mesh_conf:
mesh_conf_lines = mesh_conf.read()
self.__read_configs(mesh_conf_lines)
else:
self.logger.debug("index not supported for default: %s", index)
except:
self.logger.error("not able to read mesh config files")
return "FAIL", "not able to read mesh config files"
Expand Down
Loading

0 comments on commit 8d90c72

Please sign in to comment.