File indexing completed on 2024-05-19 05:35:37
0001 # SPDX-License-Identifier: GPL-3.0-or-later 0002 # SPDX-FileCopyrightText: 2021 Anupam Basak <anupam.basak27@gmail.com> 0003 0004 import os 0005 import re 0006 0007 from PySide2.QtCore import QUrl, Slot, Signal, Property, QObject, QProcess 0008 from PySide2.QtQml import qmlRegisterType 0009 0010 from PicoWizard.module import Module 0011 from PicoWizard.modules.wifi.wifimodel import WifiModel 0012 from PicoWizard.utils.logger import Logger 0013 0014 0015 class Wifi(Module): 0016 log = Logger.getLogger(__name__) 0017 0018 def __init__(self, parent=None): 0019 super().__init__(__file__, parent) 0020 0021 self._wifiModel = WifiModel(parent) 0022 0023 self.listWifi() 0024 0025 @staticmethod 0026 def registerTypes() -> None: 0027 qmlRegisterType(Wifi, 'PicoWizard', 1, 0, 'WifiModule') 0028 0029 @staticmethod 0030 def qmlPath() -> QUrl: 0031 return QUrl(os.path.join(os.path.dirname(os.path.realpath(__file__)), "Wifi.qml")) 0032 0033 @Slot(None, result=str) 0034 def moduleName(self) -> str: 0035 return self.tr("Wifi") 0036 0037 @Signal 0038 def modelChanged(self): 0039 pass 0040 0041 @Property(QObject, notify=modelChanged) 0042 def model(self): 0043 return self._wifiModel 0044 0045 def listWifi(self): 0046 self.log.info('Fetching list of wifi') 0047 0048 args = [ 0049 '/usr/bin/nmcli', 0050 '-c', 0051 'no', 0052 '-f', 0053 'BSSID,SSID,SIGNAL,SECURITY', 0054 '-t', 0055 'dev', 0056 'wifi', 0057 'list', 0058 '--rescan', 0059 'yes' 0060 ] 0061 0062 process = QProcess(self) 0063 process.start('/usr/bin/pkexec', args) 0064 0065 process.finished.connect(lambda exitCode, exitStatus: self.listWifiProcessFinished(process, exitCode, exitStatus)) 0066 process.errorOccurred.connect(lambda err: self.listWifiProcessError(process, err)) 0067 0068 def listWifiProcessFinished(self, process, exitCode, exitStatus): 0069 self.log.debug(f'List Wifi process status : {exitStatus}[CODE {exitCode}]') 0070 self.log.info('Listing Wifi') 0071 0072 output = process.readAll().data().decode() 0073 0074 if exitCode != 0 or "Error:" in output: 0075 self.log.error(f'Failed to get wifi list : {exitStatus}') 0076 self.errorOccurred.emit("Error listing wifi connections") 0077 else: 0078 self.log.debug('Parsing wifi data') 0079 self.generateWifiList(output) 0080 0081 def listWifiProcessError(self, process, err): 0082 self.log.error(f'Failed to get wifi list : {err}') 0083 0084 def generateWifiList(self, output): 0085 self._wifiModel.reset() 0086 wifiItemRegex = '(.*):(.*):(.*):(.*)' 0087 matches = re.findall(wifiItemRegex, output) 0088 0089 for match in matches: 0090 if match[1]: 0091 wifiItem = { 0092 'bssid': match[0].replace('\\', ''), 0093 'ssid': match[1], 0094 'signal': match[2], 0095 'security': match[3] if match[3] else 'Open', 0096 'isSecured': True if match[3] else False 0097 } 0098 0099 self._wifiModel.layoutAboutToBeChanged.emit() 0100 self._wifiModel.addWifiItem(wifiItem) 0101 self._wifiModel.layoutChanged.emit() 0102 0103 self.log.info('Generated Wifi List') 0104 self.log.debug(self._wifiModel.getWifiList()) 0105 0106 @Slot(int, str, result=None) 0107 def setWifi(self, wifiIndex, password): 0108 bssid = self._wifiModel.data(self._wifiModel.index(wifiIndex, 0), WifiModel.BssidRole) 0109 ssid = self._wifiModel.data(self._wifiModel.index(wifiIndex, 0), WifiModel.SsidRole) 0110 self.log.debug(f'Selected SSID : {ssid}') 0111 0112 process = QProcess(self) 0113 args = [ 0114 '/usr/bin/nmcli', 0115 'dev', 0116 'wifi', 0117 'connect', 0118 f'{ssid}', 0119 'password', 0120 f'{password}', 0121 'bssid', 0122 f'{bssid}' 0123 ] 0124 0125 process.start('/usr/bin/pkexec', args) 0126 0127 process.finished.connect(lambda exitCode, exitStatus: self.setWifiCmdSuccess(process, exitCode, exitStatus, ssid)) 0128 process.error.connect(lambda err: self.setWifiCmdFailed(process, err)) 0129 0130 def setWifiCmdSuccess(self, process, exitCode, exitStatus, ssid): 0131 self.log.debug(f'Connect Wifi process status : {exitStatus} [CODE {exitCode}]') 0132 0133 output = process.readAll().data().decode() 0134 0135 if exitCode != 0 or "Error:" in output: 0136 self.log.error(f'Failed to connect to wifi : {output} [{exitStatus}]') 0137 self.errorOccurred.emit("Failed to connect to wifi. Recheck the password and try again.") 0138 self.connectWifiFailed.emit() 0139 else: 0140 self.log.info("Successfully connected to wifi") 0141 Module.__ENV__.insert('PICOWIZARD_WIFI', ssid) 0142 self.connectWifiSuccess.emit() 0143 0144 def setWifiCmdFailed(self, process, err): 0145 self.log.error(f'Failed to connect to wifi : {err}') 0146 self.errorOccurred.emit("Failed to connect to wifi") 0147 self.connectWifiFailed.emit() 0148 0149 @Signal 0150 def connectWifiSuccess(self): 0151 pass 0152 0153 @Signal 0154 def connectWifiFailed(self): 0155 pass