2021-07-21 15:36:11 +05:30
|
|
|
#!/usr/bin/env python3
|
|
|
|
|
|
|
|
# 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/>.
|
|
|
|
|
|
|
|
"""
|
2021-08-14 22:00:07 +05:30
|
|
|
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 here_be_dragons() is called.
|
2021-07-21 15:36:11 +05:30
|
|
|
"""
|
|
|
|
|
|
|
|
import sys
|
2021-09-06 14:57:54 +05:30
|
|
|
import logging
|
2021-07-21 15:36:11 +05:30
|
|
|
from pathlib import Path
|
|
|
|
from shutil import copy
|
2021-08-09 12:54:41 +05:30
|
|
|
from dasbus.error import DBusError
|
2021-09-06 14:57:54 +05:30
|
|
|
from systemd import journal
|
2021-08-14 22:00:07 +05:30
|
|
|
from naxalnet import __version__
|
|
|
|
from naxalnet.iwd import Adapter, Device, IWD
|
2021-08-13 10:35:13 +05:30
|
|
|
from naxalnet.config import parse_args
|
2021-09-06 14:57:54 +05:30
|
|
|
|
|
|
|
# from naxalnet.log import logger
|
|
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
2021-07-21 15:36:11 +05:30
|
|
|
|
|
|
|
|
2021-08-13 10:35:13 +05:30
|
|
|
def copy_files(args):
|
2021-07-25 14:06:17 +05:30
|
|
|
"""
|
|
|
|
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)
|
|
|
|
"""
|
2021-07-21 15:36:11 +05:30
|
|
|
|
2021-08-25 15:52:46 +05:30
|
|
|
logger.info("Copying network config files")
|
2021-08-13 10:35:13 +05:30
|
|
|
dest = Path(args.networkd_runtime_dir)
|
|
|
|
src = Path(args.networkd_config_dir)
|
2021-07-25 14:06:17 +05:30
|
|
|
|
|
|
|
# Create the volatile directory if it doesn't exist
|
|
|
|
dest.mkdir(parents=True, exist_ok=True)
|
2021-07-21 15:36:11 +05:30
|
|
|
|
2021-07-25 14:06:17 +05:30
|
|
|
# Copy all files in src to dest
|
|
|
|
for i in src.iterdir():
|
|
|
|
copy(i, dest)
|
2021-07-21 15:36:11 +05:30
|
|
|
|
2021-07-25 14:06:17 +05:30
|
|
|
|
2021-08-05 12:11:31 +05:30
|
|
|
def setup_devices(args):
|
2021-08-09 12:54:41 +05:30
|
|
|
"""
|
|
|
|
Setup wifi interfaces using iwd
|
|
|
|
This function should be called every time an interface
|
2021-08-14 22:00:07 +05:30
|
|
|
is connected or removed.
|
|
|
|
args should be what parse_args() returns
|
2021-08-09 12:54:41 +05:30
|
|
|
"""
|
2021-08-05 12:11:31 +05:30
|
|
|
iwd = IWD()
|
|
|
|
devices = iwd.get_devices()
|
|
|
|
adhoc_devices = []
|
|
|
|
ap_devices = []
|
|
|
|
|
|
|
|
# Find devices supporting ad-hoc and ap
|
|
|
|
for i in devices:
|
2021-08-14 22:00:07 +05:30
|
|
|
# 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.
|
2021-08-05 12:11:31 +05:30
|
|
|
device = Device(i)
|
2021-08-25 15:52:46 +05:30
|
|
|
logger.debug("Found device %s", device.name)
|
2021-08-05 12:11:31 +05:30
|
|
|
adapter = Adapter(device.adapter)
|
|
|
|
if adapter.supports_mode("ad-hoc"):
|
2021-08-25 15:52:46 +05:30
|
|
|
logger.debug("The device %s can be used for ad-hoc", device.name)
|
2021-08-05 12:11:31 +05:30
|
|
|
adhoc_devices.append(i)
|
|
|
|
if adapter.supports_mode("ap"):
|
2021-08-25 15:52:46 +05:30
|
|
|
logger.debug("The device %s can be used for ap", device.name)
|
2021-08-05 12:11:31 +05:30
|
|
|
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.
|
2021-08-14 22:00:07 +05:30
|
|
|
# So we will remove adhoc_device from ap_devices if it exists there
|
2021-08-05 12:11:31 +05:30
|
|
|
if adhoc_device.name in ap_devices:
|
|
|
|
ap_devices.remove(adhoc_device.name)
|
2021-08-25 15:52:46 +05:30
|
|
|
logger.info("Starting mesh on %s", adhoc_device.name)
|
2021-08-05 12:11:31 +05:30
|
|
|
# Turn on adapter if it is off
|
|
|
|
# See issue #9
|
|
|
|
adhoc_adapter = Adapter(adhoc_device.adapter)
|
|
|
|
if not adhoc_adapter.is_powered_on():
|
2021-08-25 15:52:46 +05:30
|
|
|
logger.debug("Adapter %s is off. Turning on", adhoc_adapter.name)
|
2021-08-05 12:11:31 +05:30
|
|
|
adhoc_adapter.power_on()
|
|
|
|
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())
|
2021-08-25 15:52:46 +05:30
|
|
|
logger.info("Starting WiFi Access Point on %s", ap_device.name)
|
|
|
|
logger.info("Use naxalnet --print-wifi to get password")
|
2021-08-05 12:11:31 +05:30
|
|
|
# Turn on adapter if it is off
|
|
|
|
# See issue #9
|
|
|
|
ap_adapter = Adapter(ap_device.adapter)
|
|
|
|
if not ap_adapter.is_powered_on():
|
2021-08-25 15:52:46 +05:30
|
|
|
logger.debug("Adapter %s is off. Turning on", ap_adapter.name)
|
2021-08-05 12:11:31 +05:30
|
|
|
ap_adapter.power_on()
|
|
|
|
ap_device.start_ap(args.ap_ssid, args.ap_passwd)
|
2021-09-06 12:23:07 +05:30
|
|
|
else:
|
|
|
|
logger.info("Not setting up WiFi AP.")
|
|
|
|
else:
|
|
|
|
logger.warning(
|
|
|
|
"No device found to setup mesh. Make sure a WiFi adapter is connected"
|
|
|
|
)
|
2021-09-04 14:24:53 +05:30
|
|
|
|
2021-08-05 12:11:31 +05:30
|
|
|
|
2021-08-13 12:30:30 +05:30
|
|
|
def print_wifi(args):
|
2021-08-14 22:00:07 +05:30
|
|
|
"""
|
|
|
|
Prints the name and password of the adhoc, and ap
|
|
|
|
from the arguments
|
|
|
|
"""
|
2021-08-13 12:30:30 +05:30
|
|
|
print("Mesh name:", args.adhoc_name)
|
|
|
|
print("SSID:", args.ap_ssid)
|
|
|
|
print("Password:", args.ap_passwd)
|
|
|
|
|
|
|
|
|
2021-08-14 22:00:07 +05:30
|
|
|
def print_version():
|
|
|
|
"""Just does what the name suggests"""
|
|
|
|
print(__version__)
|
|
|
|
|
|
|
|
|
2021-07-25 14:06:17 +05:30
|
|
|
def here_be_dragons():
|
|
|
|
"""
|
2021-08-14 22:00:07 +05:30
|
|
|
This is where the magic happens!
|
2021-07-25 14:06:17 +05:30
|
|
|
This function is run every time you
|
2021-08-14 22:00:07 +05:30
|
|
|
execute naxalnet from the commandline
|
2021-07-25 14:06:17 +05:30
|
|
|
"""
|
2021-07-30 17:56:33 +05:30
|
|
|
args = parse_args()
|
2021-08-13 10:35:13 +05:30
|
|
|
|
2021-09-06 14:57:54 +05:30
|
|
|
# --verbose
|
|
|
|
if args.verbose >= 2:
|
|
|
|
loglevel = logging.DEBUG
|
|
|
|
elif args.verbose == 1:
|
|
|
|
loglevel = logging.INFO
|
|
|
|
else:
|
|
|
|
loglevel = logging.WARNING
|
|
|
|
|
|
|
|
# if --systemd is given, log to systemd journal
|
|
|
|
if args.systemd:
|
|
|
|
logger.setLevel(level=logging.DEBUG)
|
|
|
|
logger.addHandler(journal.JournalHandler())
|
|
|
|
else:
|
|
|
|
logging.basicConfig(level=loglevel)
|
|
|
|
|
2021-08-13 12:30:30 +05:30
|
|
|
if args.print_wifi:
|
|
|
|
print_wifi(args)
|
|
|
|
sys.exit(0)
|
2021-08-14 22:00:07 +05:30
|
|
|
elif args.version:
|
|
|
|
print_version()
|
|
|
|
sys.exit(0)
|
2021-08-13 12:30:30 +05:30
|
|
|
|
2021-07-25 14:06:17 +05:30
|
|
|
try:
|
2021-08-13 10:35:13 +05:30
|
|
|
copy_files(args)
|
2021-07-21 15:36:11 +05:30
|
|
|
except PermissionError as error:
|
2021-08-25 15:52:46 +05:30
|
|
|
logger.error("Cannot copy file: %s", error)
|
|
|
|
sys.exit(3)
|
2021-07-21 15:36:11 +05:30
|
|
|
|
|
|
|
try:
|
2021-08-05 12:11:31 +05:30
|
|
|
setup_devices(args)
|
2021-08-25 15:52:46 +05:30
|
|
|
except DBusError:
|
|
|
|
logger.exception("Error while communicating with iwd")
|
|
|
|
sys.exit(4)
|
2021-09-06 12:23:07 +05:30
|
|
|
# naxalnet prints Bye if no errors occured
|
|
|
|
logger.info("Bye")
|