This commit is contained in:
parent 06a5a758a3
commit 58fa7d1ee6
19 changed files with 567 additions and 377 deletions

View file

@ -10,8 +10,8 @@ from pywifi import Profile
from models.wifi import WifiAccessPoint, WifiScanResult
logging.basicConfig(
level=logging.DEBUG, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
)
level=logging.DEBUG,
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s")
logger = logging.getLogger(__name__)
@ -38,7 +38,7 @@ class WifiService:
for iface in interfaces:
iface_name = iface.name()
if (
"p2p" in iface_name.lower()
"p2p" in iface_name.lower()
): # Исключаю сетевые интерфейсы типа p2p из выбора, возможно сделать решение получше нежели исключать интерфейсы
logger.debug(f"Пропущен интерфейс {iface_name} (P2P)")
continue
@ -67,14 +67,14 @@ class WifiService:
return self.mac_lookup.lookup(mac)
except Exception as e:
logger.warning(
f"Не удалось определить производителя для MAC {mac}: {str(e)}"
)
f"Не удалось определить производителя для MAC {mac}: {str(e)}")
return "Unknown"
def _get_encryption_from_iw(self, ap_info: Dict) -> str:
"""Определяет шифрование из данных iw"""
security = ap_info.get("security", "")
logger.debug(f"Шифрование для BSSID {ap_info.get('bssid')}: {security}")
logger.debug(
f"Шифрование для BSSID {ap_info.get('bssid')}: {security}")
if "WPA3" in security:
return "WPA3"
elif "WPA2" in security or "RSN" in security:
@ -127,12 +127,16 @@ class WifiService:
return []
cmd = ["sudo", "iw", "dev", self.interface.name(), "scan"]
logger.debug(f"Выполняем команду: {' '.join(cmd)}")
result = subprocess.run(cmd, capture_output=True, text=True, timeout=10)
result = subprocess.run(cmd,
capture_output=True,
text=True,
timeout=10)
if result.returncode != 0:
logger.error(f"Ошибка iw scan: {result.stderr}")
return []
output = result.stdout
logger.debug(f"Вывод iw scan (первые 500 символов): {output[:500]}...")
logger.debug(
f"Вывод iw scan (первые 500 символов): {output[:500]}...")
aps = []
current_ap = None
@ -149,12 +153,15 @@ class WifiService:
if bssid_match := bssid_pattern.match(line):
if current_ap:
aps.append(current_ap)
current_ap = {"bssid": bssid_match.group(1).lower(), "security": ""}
current_ap = {
"bssid": bssid_match.group(1).lower(),
"security": ""
}
elif current_ap:
if ssid_match := ssid_pattern.match(line):
current_ap["ssid"] = (
ssid_match.group(1) if ssid_match.group(1).strip() else ""
)
current_ap["ssid"] = (ssid_match.group(1)
if ssid_match.group(1).strip()
else "")
elif freq_match := freq_pattern.match(line):
current_ap["frequency"] = int(freq_match.group(1))
elif signal_match := signal_pattern.match(line):
@ -163,8 +170,10 @@ class WifiService:
current_ap["security"] += "RSN;"
elif wpa_pattern.match(line):
current_ap["security"] += "WPA;"
elif security_type_match := security_type_pattern.search(line):
current_ap["security"] += security_type_match.group(1) + ";"
elif security_type_match := security_type_pattern.search(
line):
current_ap["security"] += security_type_match.group(
1) + ";"
if current_ap:
aps.append(current_ap)
@ -206,7 +215,10 @@ class WifiService:
logger.debug(f"Найдено {len(py_results)} точек через pywifi")
iw_results = self._get_iw_scan_data()
iw_by_bssid = {ap["bssid"]: ap for ap in iw_results if ap.get("bssid")}
iw_by_bssid = {
ap["bssid"]: ap
for ap in iw_results if ap.get("bssid")
}
best_aps_by_ssid: Dict[str, WifiAccessPoint] = (
{}
@ -243,18 +255,15 @@ class WifiService:
)
if ssid not in best_aps_by_ssid or (
current_ap.signal
and best_aps_by_ssid[ssid].signal
and current_ap.signal > best_aps_by_ssid[ssid].signal
):
current_ap.signal and best_aps_by_ssid[ssid].signal
and current_ap.signal > best_aps_by_ssid[ssid].signal):
best_aps_by_ssid[ssid] = current_ap
aps = list(best_aps_by_ssid.values())
logger.info(
f"Сканирование Wi-Fi завершено за {time.time() - start_time:.2f} секунд, "
f"найдено {len(aps)} уникальных сетей"
)
f"найдено {len(aps)} уникальных сетей")
return WifiScanResult(access_points=aps)
except Exception as e: