mirror of
https://git.disroot.org/pranav/pybatmesh.git
synced 2024-12-02 11:40:44 +05:30
Pranav Jerry
25a5bdee30
This will be used to control systemd-networkd via d-bus and runtime configs and make things easier in implementing B.A.T.M.A.N. gateway support
191 lines
6.4 KiB
Python
191 lines
6.4 KiB
Python
# This file is part of naxalnet.
|
|
# Copyright (C) 2021 The naxalnet Authors
|
|
|
|
# This program is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
"""
|
|
scripts.py
|
|
----------
|
|
|
|
The functions in this file is used for reading configs, args
|
|
and doing the things this program is supposed to do.
|
|
This file is named scripts.py because the original developer
|
|
of this program could not think of a better name that suits this file.
|
|
If you want to hack naxalnet, this is the right place to start.
|
|
When run from the commandline, the function main() is called.
|
|
"""
|
|
|
|
import sys
|
|
from pathlib import Path
|
|
from shutil import copy
|
|
from dasbus.error import DBusError
|
|
from systemd.daemon import notify
|
|
from naxalnet import __version__
|
|
from naxalnet.default import REPORT_BUG_INFO
|
|
from naxalnet.log import logger
|
|
from naxalnet.iwd import Adapter, Device, IWD
|
|
from naxalnet.config import args
|
|
from naxalnet.daemon import Daemon
|
|
|
|
|
|
def copy_files():
|
|
"""
|
|
Copy networkd configs to volatile dir.
|
|
The D-Bus API does not support creating new interfaces
|
|
or linking to bridges. So we use config files.
|
|
See man:systemd.network(5)
|
|
"""
|
|
try:
|
|
notify("STATUS=Configuring the network...")
|
|
logger.info("Copying network config files")
|
|
dest = Path(args.networkd_runtime_dir)
|
|
src = Path(args.networkd_config_dir)
|
|
|
|
# Create the volatile directory if it doesn't exist
|
|
dest.mkdir(parents=True, exist_ok=True)
|
|
|
|
# Copy all files in src to dest
|
|
for i in src.iterdir():
|
|
copy(i, dest)
|
|
except PermissionError:
|
|
logger.exception("A PermissionError occured while copying files")
|
|
logger.error(REPORT_BUG_INFO)
|
|
sys.exit(3)
|
|
except:
|
|
logger.exception("An unknown error occured while copying files")
|
|
logger.error(REPORT_BUG_INFO)
|
|
sys.exit(3)
|
|
|
|
|
|
def setup_devices():
|
|
"""
|
|
Setup wifi interfaces using iwd
|
|
This function should be called every time an interface
|
|
is connected or removed.
|
|
"""
|
|
try:
|
|
notify("STATUS=Setting up mesh...")
|
|
iwd = IWD()
|
|
devices = iwd.get_devices()
|
|
adhoc_devices = []
|
|
ap_devices = []
|
|
|
|
# Find devices supporting ad-hoc and ap
|
|
for i in devices:
|
|
# For each device, check if its adapter supports
|
|
# ad-hoc or ap. Many adapters will support both,
|
|
# so we will prioritise ad-hoc over ap.
|
|
device = Device(i)
|
|
logger.debug("Found device %s", device.name)
|
|
adapter = Adapter(device.adapter)
|
|
if adapter.supports_mode("ad-hoc"):
|
|
logger.debug("The device %s can be used for ad-hoc", device.name)
|
|
adhoc_devices.append(i)
|
|
if adapter.supports_mode("ap"):
|
|
logger.debug("The device %s can be used for ap", device.name)
|
|
ap_devices.append(i)
|
|
|
|
if len(adhoc_devices) != 0:
|
|
# Start ad-hoc on first device supporting ad-hoc
|
|
adhoc_device = Device(adhoc_devices.pop())
|
|
# The same device is likely to have ap support too.
|
|
# But we can't start ad-hoc and ap on the same interface.
|
|
# So we will remove adhoc_device from ap_devices if it exists there
|
|
if adhoc_device.name in ap_devices:
|
|
ap_devices.remove(adhoc_device.name)
|
|
|
|
# Turn on adapter if it is off
|
|
# See issue #9
|
|
adhoc_adapter = Adapter(adhoc_device.adapter)
|
|
if not adhoc_adapter.is_powered_on():
|
|
logger.debug("Adapter %s is off. Turning on", adhoc_adapter.name)
|
|
adhoc_adapter.power_on()
|
|
logger.info("Starting mesh on %s", adhoc_device.name)
|
|
adhoc_device.start_adhoc_open(args.adhoc_name)
|
|
# Start Access point if ap_device is not empty,
|
|
# ie, we have more devices
|
|
if len(ap_devices) != 0:
|
|
ap_device = Device(ap_devices.pop())
|
|
logger.info("Starting WiFi Access Point on %s", ap_device.name)
|
|
logger.info("Use naxalnet --print-wifi to get password")
|
|
# Turn on adapter if it is off
|
|
# See issue #9
|
|
ap_adapter = Adapter(ap_device.adapter)
|
|
if not ap_adapter.is_powered_on():
|
|
logger.debug("Adapter %s is off. Turning on", ap_adapter.name)
|
|
ap_adapter.power_on()
|
|
ap_device.start_ap(args.ap_ssid, args.ap_passwd)
|
|
else:
|
|
logger.warning("Not setting up WiFi AP.")
|
|
else:
|
|
logger.warning(
|
|
"No device found to setup mesh. Make sure a WiFi adapter is connected"
|
|
)
|
|
|
|
except DBusError:
|
|
logger.exception("Error while communicating with iwd")
|
|
logger.error(REPORT_BUG_INFO)
|
|
sys.exit(4)
|
|
except:
|
|
logger.exception("An unknown error occured while setting up the mesh")
|
|
logger.error(REPORT_BUG_INFO)
|
|
sys.exit(4)
|
|
|
|
|
|
def print_wifi():
|
|
"""
|
|
Prints the name and password of the adhoc, and ap
|
|
from the arguments
|
|
"""
|
|
print("Mesh name:", args.adhoc_name)
|
|
print("SSID:", args.ap_ssid)
|
|
print("Password:", args.ap_passwd)
|
|
|
|
|
|
def print_version():
|
|
"""Just does what the name suggests"""
|
|
print(__version__)
|
|
|
|
|
|
def main():
|
|
"""
|
|
This is where the magic happens!
|
|
This function is run every time you
|
|
execute naxalnet from the commandline
|
|
"""
|
|
|
|
if args.print_wifi:
|
|
print_wifi()
|
|
sys.exit(0)
|
|
elif args.version:
|
|
print_version()
|
|
sys.exit(0)
|
|
copy_files()
|
|
|
|
setup_devices()
|
|
# Notify systemd that naxalnet is ready.
|
|
# see man:sd_notify(3)
|
|
notify("READY=1")
|
|
|
|
# Start the daemon so that setup_devices() is called every
|
|
# time a device is connected or removed.
|
|
daemon = Daemon()
|
|
daemon.add_callback(setup_devices)
|
|
|
|
notify("STATUS=Waiting for changes")
|
|
daemon.start()
|
|
|
|
# naxalnet prints Bye while exiting.
|
|
logger.info("Bye")
|