From 4381902eb33f6b286f64cb7e9fa0cedecf5c473d Mon Sep 17 00:00:00 2001 From: Sergey Revyakin Date: Thu, 19 Feb 2026 10:18:57 +0700 Subject: [PATCH] =?UTF-8?q?=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D0=BB=20?= =?UTF-8?q?=D1=80=D1=83=D1=87=D0=BA=D0=B8=20=D0=BD=D0=B0=20=D1=87=D1=82?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BC=D0=B0=D0=BA=D0=B0=20=D0=B8=20?= =?UTF-8?q?=D0=B0=D0=B9=D0=BF=D0=B8=20hackrf?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/server_to_master.py | 109 +++++++++++++++++++++++----------------- 1 file changed, 64 insertions(+), 45 deletions(-) diff --git a/src/server_to_master.py b/src/server_to_master.py index d054e73..7793949 100644 --- a/src/server_to_master.py +++ b/src/server_to_master.py @@ -2,44 +2,50 @@ # -*- coding: utf-8 -*- import os import json +import re import httpx import asyncio import requests import websockets +import socket +import uuid from copy import deepcopy from fastapi import FastAPI from common.runtime import load_root_env, validate_env, as_bool, as_float, as_int, as_str from datetime import datetime, timedelta +import logging + +logging.basicConfig(level=logging.INFO) app = FastAPI() ############################################################################ # VARIABLES ############################################################################ -load_root_env(__file__) -validate_env("src/server_to_master.py", { - "lochost": as_str, - "locport": as_int, - "jamhost": as_str, - "jamport": as_int, - "master_server_ip": as_str, - "master_server_port": as_int, - "freqs": as_str, - "num_of_clear_packs": as_int, - "threshold_to_alarm": as_int, - "time_to_jam": as_int, - "time_to_fresh": as_int, - "active_interval_to_send": as_int, - "passive_interval_to_send": as_int, - "jammer_timeout": as_int, - "master_timeout": as_int, - "debug_module_flag": as_bool, - "send_to_module_flag": as_bool, - "send_to_master_flag": as_bool, - "send_to_jammer_flag": as_bool, - "latitude": as_float, - "longitude": as_float, -}) +load_root_env(__file__) +validate_env("src/server_to_master.py", { + "lochost": as_str, + "locport": as_int, + "jamhost": as_str, + "jamport": as_int, + "master_server_ip": as_str, + "master_server_port": as_int, + "freqs": as_str, + "num_of_clear_packs": as_int, + "threshold_to_alarm": as_int, + "time_to_jam": as_int, + "time_to_fresh": as_int, + "active_interval_to_send": as_int, + "passive_interval_to_send": as_int, + "jammer_timeout": as_int, + "master_timeout": as_int, + "debug_module_flag": as_bool, + "send_to_module_flag": as_bool, + "send_to_master_flag": as_bool, + "send_to_jammer_flag": as_bool, + "latitude": as_float, + "longitude": as_float, +}) lochost = os.getenv('lochost') locport = os.getenv('locport') jamhost = os.getenv('jamhost') @@ -138,39 +144,48 @@ freqs_alarm = {freq: 0 for freq in freqs} ############################################################################ # MODULE RIGISTR ############################################################################ +def _normalize_mac(value: str | None): + if not value: + return None + value = value.strip().lower().replace('-', ':') + if not re.fullmatch(r"[0-9a-f]{2}(:[0-9a-f]{2}){5}", value): + return None + return value + + def get_mac_address(interface='enp5s0'): """ - Получить мак текущего устройства, на котором развернут модуль сервер. - :param interface: + Получить MAC текущего устройства. + Приоритет: module_mac из env -> uuid.getnode(). """ + env_mac = _normalize_mac(os.getenv('module_mac')) + if env_mac: + return env_mac + try: - result = os.popen('sudo ifconfig ' + interface).read() - mac_index = result.find('ether') # Индекс начала строки с MAC-адресом - if mac_index != -1: - mac_address = result[mac_index + 6:mac_index + 23] - return mac_address - else: - return None + mac_int = uuid.getnode() + mac = ':'.join(f'{(mac_int >> shift) & 0xff:02x}' for shift in range(40, -1, -8)) + return _normalize_mac(mac) except Exception as e: - print("Ошибка при получении MAC-адреса:" + str(e)) + print('Ошибка при получении MAC-адреса:' + str(e)) return None def get_ip_address(interface='enp5s0'): """ - Получить айпишник текущего устройства, на котором развернут модуль сервер. - :param interface: + Получить IP текущего устройства. + Приоритет: module_ip из env -> исходящий IP до master_server. """ + env_ip = os.getenv('module_ip') + if env_ip: + return env_ip.strip() + try: - result = os.popen('sudo ifconfig ' + interface).read() - ip_index = result.find('inet') # Индекс начала строки с IP-адресом - if ip_index != -1: - ip_address = result[ip_index + 5:ip_index + 19] - return ip_address.strip() - else: - return None + with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock: + sock.connect((master_server_ip, int(master_server_port))) + return sock.getsockname()[0] except Exception as e: - print("Ошибка при получении IP-адреса:" + str(e)) + print('Ошибка при получении IP-адреса:' + str(e)) return None @@ -203,6 +218,10 @@ async def send_to_master(ModuleDataSingleV2, flag): :return: """ mac_address = get_mac_address() + if not mac_address: + print('MAC адрес не определен, отправка на master пропущена') + return + async with httpx.AsyncClient() as client: try: if flag == 0: @@ -341,7 +360,7 @@ async def process_data(data: dict): # Агрегируем N пакетов данных от частот в один общий список, он используется в функции agregate data. # Каждая позиция списка фиксируется за отдельной частотой. - freq = data_dict['freq'] + freq = str(data_dict.get('freq')) for i in range(len(freqs)): if freq == freqs[i]: #Так делаем потому, что сервак является центром принятия решений по триггеру.