mirror of
https://github.com/DJ2LS/FreeDATA
synced 2024-05-14 08:04:33 +00:00
and another global has been eliminated..
This commit is contained in:
parent
108851fb78
commit
07e6c33e89
8 changed files with 87 additions and 94 deletions
|
@ -41,13 +41,13 @@ class DATA:
|
||||||
def __init__(self, config, event_queue, states) -> None:
|
def __init__(self, config, event_queue, states) -> None:
|
||||||
self.states = states
|
self.states = states
|
||||||
|
|
||||||
self.stats = stats.stats()
|
self.stats = stats.stats(config, event_queue, states)
|
||||||
self.event_queue = event_queue
|
self.event_queue = event_queue
|
||||||
|
|
||||||
self.mycallsign = config['STATION']['mycall']
|
self.mycallsign = config['STATION']['mycall']
|
||||||
self.ssid_list = config['STATION']['ssid_list']
|
self.ssid_list = config['STATION']['ssid_list']
|
||||||
self.mycallsign_crc = b''
|
self.mycallsign_crc = helpers.get_crc_24(self.mycallsign)
|
||||||
|
|
||||||
self.mygrid = config['STATION']['mygrid']
|
self.mygrid = config['STATION']['mygrid']
|
||||||
self.enable_fsk = config['MODEM']['enable_fsk']
|
self.enable_fsk = config['MODEM']['enable_fsk']
|
||||||
self.respond_to_cq = config['MODEM']['respond_to_cq']
|
self.respond_to_cq = config['MODEM']['respond_to_cq']
|
||||||
|
|
|
@ -11,7 +11,6 @@ import requests
|
||||||
import threading
|
import threading
|
||||||
import ujson as json
|
import ujson as json
|
||||||
import structlog
|
import structlog
|
||||||
from global_instances import HamlibParam, Modem
|
|
||||||
|
|
||||||
log = structlog.get_logger("explorer")
|
log = structlog.get_logger("explorer")
|
||||||
|
|
||||||
|
@ -34,21 +33,21 @@ class explorer():
|
||||||
|
|
||||||
def push(self):
|
def push(self):
|
||||||
|
|
||||||
frequency = 0 if HamlibParam.hamlib_frequency is None else HamlibParam.hamlib_frequency
|
frequency = 0 if self.states.radio_frequency is None else self.states.radio_frequency
|
||||||
band = "USB"
|
band = "USB"
|
||||||
callsign = str(self.config['STATION']['mycall'])
|
callsign = str(self.config['STATION']['mycall'])
|
||||||
gridsquare = str(self.config['STATION']['mygrid'])
|
gridsquare = str(self.config['STATION']['mygrid'])
|
||||||
version = str(Modem.version)
|
version = str(self.states.modem_version)
|
||||||
bandwidth = str(self.config['MODEM']['enable_low_bandwidth_mode'])
|
bandwidth = str(self.config['MODEM']['enable_low_bandwidth_mode'])
|
||||||
beacon = str(self.states.is_beacon_running)
|
beacon = str(self.states.is_beacon_running)
|
||||||
strength = str(HamlibParam.hamlib_strength)
|
strength = str(self.states.radio_strength)
|
||||||
|
|
||||||
log.info("[EXPLORER] publish", frequency=frequency, band=band, callsign=callsign, gridsquare=gridsquare, version=version, bandwidth=bandwidth)
|
log.info("[EXPLORER] publish", frequency=frequency, band=band, callsign=callsign, gridsquare=gridsquare, version=version, bandwidth=bandwidth)
|
||||||
|
|
||||||
headers = {"Content-Type": "application/json"}
|
headers = {"Content-Type": "application/json"}
|
||||||
station_data = {'callsign': callsign, 'gridsquare': gridsquare, 'frequency': frequency, 'strength': strength, 'band': band, 'version': version, 'bandwidth': bandwidth, 'beacon': beacon, "lastheard": []}
|
station_data = {'callsign': callsign, 'gridsquare': gridsquare, 'frequency': frequency, 'strength': strength, 'band': band, 'version': version, 'bandwidth': bandwidth, 'beacon': beacon, "lastheard": []}
|
||||||
|
|
||||||
for i in Modem.heard_stations:
|
for i in self.states.heard_stations:
|
||||||
try:
|
try:
|
||||||
callsign = str(i[0], "UTF-8")
|
callsign = str(i[0], "UTF-8")
|
||||||
grid = str(i[1], "UTF-8")
|
grid = str(i[1], "UTF-8")
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
# global_instances.py
|
|
||||||
|
|
||||||
from deprecated_static import Daemon, ARQ, AudioParam, Beacon, Channel, HamlibParam, ModemParam, Station, Statistics, TCIParam, Modem, MeshParam
|
|
||||||
|
|
||||||
# Initialize instances with appropriate default values
|
|
||||||
|
|
||||||
# Create single instances of each dataclass
|
|
||||||
Daemon = Daemon(modemprocess=None, rigctldprocess=None)
|
|
||||||
ARQ = ARQ()
|
|
||||||
AudioParam = AudioParam()
|
|
||||||
Beacon = Beacon()
|
|
||||||
Channel = Channel()
|
|
||||||
HamlibParam = HamlibParam()
|
|
||||||
ModemParam = ModemParam()
|
|
||||||
Station = Station()
|
|
||||||
Statistics = Statistics()
|
|
||||||
TCIParam = TCIParam()
|
|
||||||
Modem = Modem()
|
|
||||||
MeshParam = MeshParam()
|
|
104
modem/mesh.py
104
modem/mesh.py
|
@ -6,10 +6,10 @@
|
||||||
HF mesh networking prototype and testing module
|
HF mesh networking prototype and testing module
|
||||||
|
|
||||||
import time
|
import time
|
||||||
MeshParam.routing_table = [['AA1AA', 'direct', 0, 1.0, 25, time.time(), ], ['AA1AA', 'AA2BB', 1, 3.1, 10, time.time(), ],
|
self.states.mesh_routing_table = [['AA1AA', 'direct', 0, 1.0, 25, time.time(), ], ['AA1AA', 'AA2BB', 1, 3.1, 10, time.time(), ],
|
||||||
['AA3CC', 'AA2BB', 5, -4.5, -3, time.time(), ]]
|
['AA3CC', 'AA2BB', 5, -4.5, -3, time.time(), ]]
|
||||||
|
|
||||||
print(MeshParam.routing_table)
|
print(self.states.mesh_routing_table)
|
||||||
print("---------------------------------")
|
print("---------------------------------")
|
||||||
|
|
||||||
|
|
||||||
|
@ -51,10 +51,13 @@ import structlog
|
||||||
from queues import MESH_RECEIVED_QUEUE, MESH_QUEUE_TRANSMIT, MESH_SIGNALLING_TABLE
|
from queues import MESH_RECEIVED_QUEUE, MESH_QUEUE_TRANSMIT, MESH_SIGNALLING_TABLE
|
||||||
|
|
||||||
class MeshRouter():
|
class MeshRouter():
|
||||||
def __init__(self):
|
def __init__(self, config, event_queue, states):
|
||||||
|
|
||||||
self.log = structlog.get_logger("RF")
|
self.log = structlog.get_logger("RF")
|
||||||
|
|
||||||
|
self.mycallsign = config['STATION']['mycall']
|
||||||
|
self.mycallsign_crc = helpers.get_crc_24(self.mycallsign)
|
||||||
|
|
||||||
self.transmission_time_list = [
|
self.transmission_time_list = [
|
||||||
60, 90, 120, 180, 180, 180, 180, 180, 180, 360, 360, 360, 360, 360, 360,
|
60, 90, 120, 180, 180, 180, 180, 180, 180, 360, 360, 360, 360, 360, 360,
|
||||||
60, 90, 120, 180, 180, 180, 180, 180, 180, 360, 360, 360, 360, 360, 360,
|
60, 90, 120, 180, 180, 180, 180, 180, 180, 360, 360, 360, 360, 360, 360,
|
||||||
|
@ -113,7 +116,7 @@ class MeshRouter():
|
||||||
heard stations format:
|
heard stations format:
|
||||||
[dxcallsign,dxgrid,int(time.time()),datatype,snr,offset,frequency]
|
[dxcallsign,dxgrid,int(time.time()),datatype,snr,offset,frequency]
|
||||||
|
|
||||||
Modem.heard_stations.append(
|
self.states.heard_stations.append(
|
||||||
[
|
[
|
||||||
dxcallsign,
|
dxcallsign,
|
||||||
dxgrid,
|
dxgrid,
|
||||||
|
@ -134,7 +137,7 @@ class MeshRouter():
|
||||||
frequency_position = 6
|
frequency_position = 6
|
||||||
|
|
||||||
try:
|
try:
|
||||||
for item in Modem.heard_stations:
|
for item in self.states.heard_stations:
|
||||||
#print("-----------")
|
#print("-----------")
|
||||||
#print(item)
|
#print(item)
|
||||||
#print(item[snr_position])
|
#print(item[snr_position])
|
||||||
|
@ -156,21 +159,21 @@ class MeshRouter():
|
||||||
def add_router_to_routing_table(self, new_router):
|
def add_router_to_routing_table(self, new_router):
|
||||||
try:
|
try:
|
||||||
# destination callsign # router callsign # hops # rx snr # route quality # timestamp
|
# destination callsign # router callsign # hops # rx snr # route quality # timestamp
|
||||||
for _, item in enumerate(MeshParam.routing_table):
|
for _, item in enumerate(self.states.mesh_routing_table):
|
||||||
# update routing entry if exists
|
# update routing entry if exists
|
||||||
if new_router[0] in item[0] and new_router[1] in item[1]:
|
if new_router[0] in item[0] and new_router[1] in item[1]:
|
||||||
#print(f"UPDATE {MeshParam.routing_table[_]} >>> {new_router}")
|
#print(f"UPDATE {self.states.mesh_routing_table[_]} >>> {new_router}")
|
||||||
self.log.info(f"[MESH] [ROUTING TABLE] [UPDATE]: {MeshParam.routing_table[_]} >>> ",
|
self.log.info(f"[MESH] [ROUTING TABLE] [UPDATE]: {self.states.mesh_routing_table[_]} >>> ",
|
||||||
update=new_router)
|
update=new_router)
|
||||||
|
|
||||||
MeshParam.routing_table[_] = new_router
|
self.states.mesh_routing_table[_] = new_router
|
||||||
|
|
||||||
# add new routing entry if not exists
|
# add new routing entry if not exists
|
||||||
if new_router not in MeshParam.routing_table:
|
if new_router not in self.states.mesh_routing_table:
|
||||||
#print(f"INSERT {new_router} >>> ROUTING TABLE")
|
#print(f"INSERT {new_router} >>> ROUTING TABLE")
|
||||||
self.log.info("[MESH] [ROUTING TABLE] [INSERT]:", insert=new_router)
|
self.log.info("[MESH] [ROUTING TABLE] [INSERT]:", insert=new_router)
|
||||||
|
|
||||||
MeshParam.routing_table.append(new_router)
|
self.states.mesh_routing_table.append(new_router)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.log.warning("[MESH] error adding data to routing table", e=e, router=new_router)
|
self.log.warning("[MESH] error adding data to routing table", e=e, router=new_router)
|
||||||
|
|
||||||
|
@ -181,7 +184,7 @@ class MeshRouter():
|
||||||
modem.RECEIVE_DATAC4 = True
|
modem.RECEIVE_DATAC4 = True
|
||||||
|
|
||||||
threading.Event().wait(1)
|
threading.Event().wait(1)
|
||||||
if not ARQ.arq_state and not ModemParam.channel_busy:
|
if not self.states.arq_state and not self.states.channel_busy:
|
||||||
try:
|
try:
|
||||||
|
|
||||||
# wait some time until sending routing table
|
# wait some time until sending routing table
|
||||||
|
@ -193,7 +196,7 @@ class MeshRouter():
|
||||||
#[b'DJ2LS-0', 'direct', 0, 9.6, 9.6, 1684912305]
|
#[b'DJ2LS-0', 'direct', 0, 9.6, 9.6, 1684912305]
|
||||||
mesh_broadcast_frame_header = bytearray(4)
|
mesh_broadcast_frame_header = bytearray(4)
|
||||||
mesh_broadcast_frame_header[:1] = bytes([FRAME_TYPE.MESH_BROADCAST.value])
|
mesh_broadcast_frame_header[:1] = bytes([FRAME_TYPE.MESH_BROADCAST.value])
|
||||||
mesh_broadcast_frame_header[1:4] = helpers.get_crc_24(Station.mycallsign)
|
mesh_broadcast_frame_header[1:4] = helpers.get_crc_24(self.mycallsign)
|
||||||
|
|
||||||
# callsign(6), router(6), hops(1), path_score(1) == 14 ==> 14 28 42 ==> 3 mesh routing entries
|
# callsign(6), router(6), hops(1), path_score(1) == 14 ==> 14 28 42 ==> 3 mesh routing entries
|
||||||
# callsign_crc(3), router_crc(3), hops(1), path_score(1) == 8 --> 6
|
# callsign_crc(3), router_crc(3), hops(1), path_score(1) == 8 --> 6
|
||||||
|
@ -204,15 +207,15 @@ class MeshRouter():
|
||||||
|
|
||||||
# Iterate over the route subarrays and add the selected entries to the result bytearray
|
# Iterate over the route subarrays and add the selected entries to the result bytearray
|
||||||
index = 0
|
index = 0
|
||||||
for route_id, route in enumerate(MeshParam.routing_table):
|
for route_id, route in enumerate(self.states.mesh_routing_table):
|
||||||
# the value 5 is the length of crc24 + hops + score
|
# the value 5 is the length of crc24 + hops + score
|
||||||
|
|
||||||
dxcall = MeshParam.routing_table[route_id][0]
|
dxcall = self.states.mesh_routing_table[route_id][0]
|
||||||
# router = MeshParam.routing_table[i][1]
|
# router = self.states.mesh_routing_table[i][1]
|
||||||
hops = MeshParam.routing_table[route_id][2]
|
hops = self.states.mesh_routing_table[route_id][2]
|
||||||
# snr = MeshParam.routing_table[i][3]
|
# snr = self.states.mesh_routing_table[i][3]
|
||||||
route_score = np.clip(MeshParam.routing_table[route_id][4], 0, 254)
|
route_score = np.clip(self.states.mesh_routing_table[route_id][4], 0, 254)
|
||||||
# timestamp = MeshParam.routing_table[i][5]
|
# timestamp = self.states.mesh_routing_table[i][5]
|
||||||
result[index:index + 5] = dxcall + bytes([hops]) + bytes([route_score])
|
result[index:index + 5] = dxcall + bytes([hops]) + bytes([route_score])
|
||||||
index += 5
|
index += 5
|
||||||
|
|
||||||
|
@ -225,13 +228,13 @@ class MeshRouter():
|
||||||
#print(len(_))
|
#print(len(_))
|
||||||
frame_list.append(mesh_broadcast_frame_header + _)
|
frame_list.append(mesh_broadcast_frame_header + _)
|
||||||
|
|
||||||
Modem.transmitting = True
|
self.states.set("is_transmitting", True)
|
||||||
c2_mode = FREEDV_MODE.datac4.value
|
c2_mode = FREEDV_MODE.datac4.value
|
||||||
self.log.info("[MESH] broadcasting routing table", frame_list=frame_list, frames=len(split_result))
|
self.log.info("[MESH] broadcasting routing table", frame_list=frame_list, frames=len(split_result))
|
||||||
modem.MODEM_TRANSMIT_QUEUE.put([c2_mode, 1, 0, frame_list])
|
modem.MODEM_TRANSMIT_QUEUE.put([c2_mode, 1, 0, frame_list])
|
||||||
|
|
||||||
# Wait while transmitting
|
# Wait while transmitting
|
||||||
while Modem.transmitting:
|
while self.states.is_transmitting:
|
||||||
threading.Event().wait(0.01)
|
threading.Event().wait(0.01)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.log.warning("[MESH] broadcasting routing table", e=e)
|
self.log.warning("[MESH] broadcasting routing table", e=e)
|
||||||
|
@ -239,9 +242,12 @@ class MeshRouter():
|
||||||
|
|
||||||
def mesh_rx_dispatcher(self):
|
def mesh_rx_dispatcher(self):
|
||||||
while True:
|
while True:
|
||||||
data_in = MESH_RECEIVED_QUEUE.get()
|
data = MESH_RECEIVED_QUEUE.get()
|
||||||
|
data_in = data[0]
|
||||||
|
snr = data[1]
|
||||||
|
|
||||||
if int.from_bytes(data_in[:1], "big") in [FRAME_TYPE.MESH_BROADCAST.value]:
|
if int.from_bytes(data_in[:1], "big") in [FRAME_TYPE.MESH_BROADCAST.value]:
|
||||||
self.received_routing_table(data_in[:-2])
|
self.received_routing_table(data_in[:-2], snr)
|
||||||
elif int.from_bytes(data_in[:1], "big") in [FRAME_TYPE.MESH_SIGNALLING_PING.value]:
|
elif int.from_bytes(data_in[:1], "big") in [FRAME_TYPE.MESH_SIGNALLING_PING.value]:
|
||||||
self.received_mesh_ping(data_in[:-2])
|
self.received_mesh_ping(data_in[:-2])
|
||||||
elif int.from_bytes(data_in[:1], "big") in [FRAME_TYPE.MESH_SIGNALLING_PING_ACK.value]:
|
elif int.from_bytes(data_in[:1], "big") in [FRAME_TYPE.MESH_SIGNALLING_PING_ACK.value]:
|
||||||
|
@ -273,7 +279,7 @@ class MeshRouter():
|
||||||
threading.Event().wait(1.0)
|
threading.Event().wait(1.0)
|
||||||
for entry in MESH_SIGNALLING_TABLE:
|
for entry in MESH_SIGNALLING_TABLE:
|
||||||
# if in arq state, interrupt dispatcher
|
# if in arq state, interrupt dispatcher
|
||||||
if ARQ.arq_state or ARQ.arq_session:
|
if self.states.arq_state or self.states.arq_session:
|
||||||
break
|
break
|
||||||
|
|
||||||
#print(entry)
|
#print(entry)
|
||||||
|
@ -293,7 +299,7 @@ class MeshRouter():
|
||||||
entry[5] += 1
|
entry[5] += 1
|
||||||
self.log.info("[MESH] [TX] Ping", destination=entry[1], origin=entry[2])
|
self.log.info("[MESH] [TX] Ping", destination=entry[1], origin=entry[2])
|
||||||
channel_busy_timeout = time.time() + 5
|
channel_busy_timeout = time.time() + 5
|
||||||
while ModemParam.channel_busy and time.time() < channel_busy_timeout:
|
while self.states.channel_busy and time.time() < channel_busy_timeout:
|
||||||
threading.Event().wait(0.01)
|
threading.Event().wait(0.01)
|
||||||
self.transmit_mesh_signalling_ping(bytes.fromhex(entry[1]), bytes.fromhex(entry[2]))
|
self.transmit_mesh_signalling_ping(bytes.fromhex(entry[1]), bytes.fromhex(entry[2]))
|
||||||
#print("...")
|
#print("...")
|
||||||
|
@ -306,14 +312,14 @@ class MeshRouter():
|
||||||
entry[5] += 1
|
entry[5] += 1
|
||||||
self.log.info("[MESH] [TX] Ping ACK", destination=entry[1], origin=entry[2])
|
self.log.info("[MESH] [TX] Ping ACK", destination=entry[1], origin=entry[2])
|
||||||
channel_busy_timeout = time.time() + 5
|
channel_busy_timeout = time.time() + 5
|
||||||
while ModemParam.channel_busy and time.time() < channel_busy_timeout:
|
while self.states.channel_busy and time.time() < channel_busy_timeout:
|
||||||
threading.Event().wait(0.01)
|
threading.Event().wait(0.01)
|
||||||
self.transmit_mesh_signalling_ping_ack(bytes.fromhex(entry[1]), bytes.fromhex(entry[2]))
|
self.transmit_mesh_signalling_ping_ack(bytes.fromhex(entry[1]), bytes.fromhex(entry[2]))
|
||||||
else:
|
else:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def received_routing_table(self, data_in):
|
def received_routing_table(self, data_in, snr):
|
||||||
try:
|
try:
|
||||||
print("data received........")
|
print("data received........")
|
||||||
print(data_in)
|
print(data_in)
|
||||||
|
@ -327,7 +333,7 @@ class MeshRouter():
|
||||||
callsign_checksum = payload[i:i + 3] # First 3 bytes of the information (callsign_checksum)
|
callsign_checksum = payload[i:i + 3] # First 3 bytes of the information (callsign_checksum)
|
||||||
hops = int.from_bytes(payload[i+3:i + 4], "big") # Fourth byte of the information (hops)
|
hops = int.from_bytes(payload[i+3:i + 4], "big") # Fourth byte of the information (hops)
|
||||||
score = int.from_bytes(payload[i+4:i + 5], "big") # Fifth byte of the information (score)
|
score = int.from_bytes(payload[i+4:i + 5], "big") # Fifth byte of the information (score)
|
||||||
snr = int(ModemParam.snr)
|
snr = int(snr)
|
||||||
score = self.calculate_new_avg_score(score, self.calculate_score_by_snr(snr))
|
score = self.calculate_new_avg_score(score, self.calculate_score_by_snr(snr))
|
||||||
timestamp = int(time.time())
|
timestamp = int(time.time())
|
||||||
|
|
||||||
|
@ -335,7 +341,7 @@ class MeshRouter():
|
||||||
_use_case1 = callsign_checksum.startswith(b'\x00')
|
_use_case1 = callsign_checksum.startswith(b'\x00')
|
||||||
|
|
||||||
# use case 2: add new router to table only if not own callsign
|
# use case 2: add new router to table only if not own callsign
|
||||||
_use_case2 = callsign_checksum not in [helpers.get_crc_24(Station.mycallsign)]
|
_use_case2 = callsign_checksum not in [helpers.get_crc_24(self.mycallsign)]
|
||||||
|
|
||||||
# use case 3: increment hop if router not direct
|
# use case 3: increment hop if router not direct
|
||||||
if router not in [helpers.get_crc_24(b'direct')] and hops == 0:
|
if router not in [helpers.get_crc_24(b'direct')] and hops == 0:
|
||||||
|
@ -343,9 +349,9 @@ class MeshRouter():
|
||||||
|
|
||||||
# use case 4: if callsign is directly available skip route for only keeping shortest way in db
|
# use case 4: if callsign is directly available skip route for only keeping shortest way in db
|
||||||
_use_case4 = False
|
_use_case4 = False
|
||||||
for _, call in enumerate(MeshParam.routing_table):
|
for _, call in enumerate(self.states.mesh_routing_table):
|
||||||
# check if callsign already in routing table and is direct connection
|
# check if callsign already in routing table and is direct connection
|
||||||
if callsign_checksum in [MeshParam.routing_table[_][0]] and MeshParam.routing_table[_][1] in [helpers.get_crc_24(b'direct')]:
|
if callsign_checksum in [self.states.mesh_routing_table[_][0]] and self.states.mesh_routing_table[_][1] in [helpers.get_crc_24(b'direct')]:
|
||||||
_use_case4 = True
|
_use_case4 = True
|
||||||
|
|
||||||
# use case N: calculate score
|
# use case N: calculate score
|
||||||
|
@ -364,8 +370,8 @@ class MeshRouter():
|
||||||
self.add_router_to_routing_table(new_router)
|
self.add_router_to_routing_table(new_router)
|
||||||
|
|
||||||
print("-------------------------")
|
print("-------------------------")
|
||||||
for _, item in enumerate(MeshParam.routing_table):
|
for _, item in enumerate(self.states.mesh_routing_table):
|
||||||
print(MeshParam.routing_table[_])
|
print(self.states.mesh_routing_table[_])
|
||||||
print("-------------------------")
|
print("-------------------------")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.log.warning("[MESH] error processing received routing broadcast", e=e)
|
self.log.warning("[MESH] error processing received routing broadcast", e=e)
|
||||||
|
@ -388,21 +394,21 @@ class MeshRouter():
|
||||||
def received_mesh_ping(self, data_in):
|
def received_mesh_ping(self, data_in):
|
||||||
destination = data_in[1:4].hex()
|
destination = data_in[1:4].hex()
|
||||||
origin = data_in[4:7].hex()
|
origin = data_in[4:7].hex()
|
||||||
if destination == Station.mycallsign_crc.hex():
|
if destination == self.mycallsign_crc.hex():
|
||||||
self.log.info("[MESH] [RX] [PING] [REQ]", destination=destination, origin=origin, mycall=Station.mycallsign_crc.hex())
|
self.log.info("[MESH] [RX] [PING] [REQ]", destination=destination, origin=origin, mycall=self.mycallsign_crc.hex())
|
||||||
# use case 1: set status to acknowleding if we are the receiver of a PING
|
# use case 1: set status to acknowleding if we are the receiver of a PING
|
||||||
self.add_mesh_ping_to_signalling_table(destination, origin, frametype="PING-ACK", status="acknowledging")
|
self.add_mesh_ping_to_signalling_table(destination, origin, frametype="PING-ACK", status="acknowledging")
|
||||||
|
|
||||||
channel_busy_timeout = time.time() + 5
|
channel_busy_timeout = time.time() + 5
|
||||||
while ModemParam.channel_busy and time.time() < channel_busy_timeout:
|
while self.states.channel_busy and time.time() < channel_busy_timeout:
|
||||||
threading.Event().wait(0.01)
|
threading.Event().wait(0.01)
|
||||||
|
|
||||||
# dxcallsign_crc = Station.mycallsign_crc
|
# dxcallsign_crc = self.mycallsign_crc
|
||||||
self.transmit_mesh_signalling_ping_ack(bytes.fromhex(destination), bytes.fromhex(origin))
|
self.transmit_mesh_signalling_ping_ack(bytes.fromhex(destination), bytes.fromhex(origin))
|
||||||
elif origin == Station.mycallsign_crc.hex():
|
elif origin == self.mycallsign_crc.hex():
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
self.log.info("[MESH] [RX] [PING] [REQ]", destination=destination, origin=origin, mycall=Station.mycallsign_crc.hex())
|
self.log.info("[MESH] [RX] [PING] [REQ]", destination=destination, origin=origin, mycall=self.mycallsign_crc.hex())
|
||||||
# lookup if entry is already in database - if so, udpate and exit
|
# lookup if entry is already in database - if so, udpate and exit
|
||||||
for item in MESH_SIGNALLING_TABLE:
|
for item in MESH_SIGNALLING_TABLE:
|
||||||
if item[1] == destination and item[5] >= self.signalling_max_attempts:
|
if item[1] == destination and item[5] >= self.signalling_max_attempts:
|
||||||
|
@ -429,17 +435,17 @@ class MeshRouter():
|
||||||
attempt = 0
|
attempt = 0
|
||||||
|
|
||||||
|
|
||||||
if destination == Station.mycallsign_crc.hex():
|
if destination == self.mycallsign_crc.hex():
|
||||||
#self.log.info("[MESH] [RX] [PING] [ACK]", destination=destination, origin=origin, mycall=Station.mycallsign_crc.hex())
|
#self.log.info("[MESH] [RX] [PING] [ACK]", destination=destination, origin=origin, mycall=self.mycallsign_crc.hex())
|
||||||
#self.add_mesh_ping_ack_to_signalling_table(destination, origin, status="sending_ack")
|
#self.add_mesh_ping_ack_to_signalling_table(destination, origin, status="sending_ack")
|
||||||
pass
|
pass
|
||||||
elif origin == Station.mycallsign_crc.hex():
|
elif origin == self.mycallsign_crc.hex():
|
||||||
self.log.info("[MESH] [RX] [PING] [ACK]", destination=destination, origin=origin, mycall=Station.mycallsign_crc.hex())
|
self.log.info("[MESH] [RX] [PING] [ACK]", destination=destination, origin=origin, mycall=self.mycallsign_crc.hex())
|
||||||
self.add_mesh_ping_ack_to_signalling_table(destination, origin, status="acknowledged")
|
self.add_mesh_ping_ack_to_signalling_table(destination, origin, status="acknowledged")
|
||||||
else:
|
else:
|
||||||
#status = "forwarding"
|
#status = "forwarding"
|
||||||
#self.add_mesh_ping_ack_to_signalling_table(destination, status)
|
#self.add_mesh_ping_ack_to_signalling_table(destination, status)
|
||||||
self.log.info("[MESH] [RX] [PING] [ACK]", destination=destination, mycall=Station.mycallsign_crc.hex())
|
self.log.info("[MESH] [RX] [PING] [ACK]", destination=destination, mycall=self.mycallsign_crc.hex())
|
||||||
for item in MESH_SIGNALLING_TABLE:
|
for item in MESH_SIGNALLING_TABLE:
|
||||||
if item[1] == destination and item[2] == origin and item[5] >= self.signalling_max_attempts:
|
if item[1] == destination and item[2] == origin and item[5] >= self.signalling_max_attempts:
|
||||||
# use case 2: set status to forwarded if we are not the receiver of a PING and out of retries
|
# use case 2: set status to forwarded if we are not the receiver of a PING and out of retries
|
||||||
|
@ -544,11 +550,11 @@ class MeshRouter():
|
||||||
|
|
||||||
# Set the TRANSMITTING flag before adding an object to the transmit queue
|
# Set the TRANSMITTING flag before adding an object to the transmit queue
|
||||||
# TODO This is not that nice, we could improve this somehow
|
# TODO This is not that nice, we could improve this somehow
|
||||||
Modem.transmitting = True
|
self.states.set("is_transmitting", True)
|
||||||
modem.MODEM_TRANSMIT_QUEUE.put([c2_mode, copies, repeat_delay, frame_to_tx])
|
modem.MODEM_TRANSMIT_QUEUE.put([c2_mode, copies, repeat_delay, frame_to_tx])
|
||||||
|
|
||||||
# Wait while transmitting
|
# Wait while transmitting
|
||||||
while Modem.transmitting:
|
while self.states.is_transmitting:
|
||||||
threading.Event().wait(0.01)
|
threading.Event().wait(0.01)
|
||||||
|
|
||||||
|
|
||||||
|
@ -560,7 +566,7 @@ class MeshRouter():
|
||||||
ping_frame[:1] = frame_type
|
ping_frame[:1] = frame_type
|
||||||
ping_frame[1:4] = destination
|
ping_frame[1:4] = destination
|
||||||
ping_frame[4:7] = origin
|
ping_frame[4:7] = origin
|
||||||
ping_frame[7:13] = helpers.callsign_to_bytes(Station.mycallsign)
|
ping_frame[7:13] = helpers.callsign_to_bytes(self.mycallsign)
|
||||||
|
|
||||||
self.enqueue_frame_for_tx([ping_frame], c2_mode=FREEDV_MODE.sig0.value)
|
self.enqueue_frame_for_tx([ping_frame], c2_mode=FREEDV_MODE.sig0.value)
|
||||||
|
|
||||||
|
@ -573,6 +579,6 @@ class MeshRouter():
|
||||||
ping_frame[:1] = frame_type
|
ping_frame[:1] = frame_type
|
||||||
ping_frame[1:4] = destination
|
ping_frame[1:4] = destination
|
||||||
ping_frame[4:7] = origin
|
ping_frame[4:7] = origin
|
||||||
#ping_frame[7:13] = helpers.callsign_to_bytes(Station.mycallsign)
|
#ping_frame[7:13] = helpers.callsign_to_bytes(self.mycallsign)
|
||||||
|
|
||||||
self.enqueue_frame_for_tx([ping_frame], c2_mode=FREEDV_MODE.sig0.value)
|
self.enqueue_frame_for_tx([ping_frame], c2_mode=FREEDV_MODE.sig0.value)
|
|
@ -27,6 +27,7 @@ from queues import DATA_QUEUE_RECEIVED, MODEM_RECEIVED_QUEUE, MODEM_TRANSMIT_QUE
|
||||||
AUDIO_RECEIVED_QUEUE, AUDIO_TRANSMIT_QUEUE, MESH_RECEIVED_QUEUE
|
AUDIO_RECEIVED_QUEUE, AUDIO_TRANSMIT_QUEUE, MESH_RECEIVED_QUEUE
|
||||||
import audio
|
import audio
|
||||||
import event_manager
|
import event_manager
|
||||||
|
from modem_frametypes import FRAME_TYPE
|
||||||
|
|
||||||
TESTMODE = False
|
TESTMODE = False
|
||||||
RXCHANNEL = ""
|
RXCHANNEL = ""
|
||||||
|
@ -873,7 +874,7 @@ class RF:
|
||||||
self.log.debug(
|
self.log.debug(
|
||||||
"[MDM] [demod_audio] moving data to mesh dispatcher", nbytes=nbytes
|
"[MDM] [demod_audio] moving data to mesh dispatcher", nbytes=nbytes
|
||||||
)
|
)
|
||||||
MESH_RECEIVED_QUEUE.put(bytes(bytes_out))
|
MESH_RECEIVED_QUEUE.put([bytes(bytes_out), snr])
|
||||||
|
|
||||||
else:
|
else:
|
||||||
self.log.debug(
|
self.log.debug(
|
||||||
|
@ -1305,9 +1306,9 @@ class RF:
|
||||||
if self.states.is_transmitting:
|
if self.states.is_transmitting:
|
||||||
self.radio_alc = self.radio.get_alc()
|
self.radio_alc = self.radio.get_alc()
|
||||||
threading.Event().wait(0.1)
|
threading.Event().wait(0.1)
|
||||||
# HamlibParam.hamlib_rf = self.radio.get_level()
|
self.states.set("radio_rf_power", self.radio.get_level())
|
||||||
# threading.Event().wait(0.1)
|
# threading.Event().wait(0.1)
|
||||||
self.states.set("radio_rf_power", self.radio.get_strength())
|
self.states.set("radio_strength", self.radio.get_strength())
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.log.warning(
|
self.log.warning(
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
Hold queues used by more than one module to eliminate cyclic imports.
|
Hold queues used by more than one module to eliminate cyclic imports.
|
||||||
"""
|
"""
|
||||||
import queue
|
import queue
|
||||||
from global_instances import ARQ
|
|
||||||
|
|
||||||
DATA_QUEUE_TRANSMIT = queue.Queue()
|
DATA_QUEUE_TRANSMIT = queue.Queue()
|
||||||
DATA_QUEUE_RECEIVED = queue.Queue()
|
DATA_QUEUE_RECEIVED = queue.Queue()
|
||||||
|
@ -22,7 +21,8 @@ AUDIO_RECEIVED_QUEUE = queue.Queue()
|
||||||
AUDIO_TRANSMIT_QUEUE = queue.Queue()
|
AUDIO_TRANSMIT_QUEUE = queue.Queue()
|
||||||
|
|
||||||
# Initialize FIFO queue to finally store received data
|
# Initialize FIFO queue to finally store received data
|
||||||
RX_BUFFER = queue.Queue(maxsize=ARQ.rx_buffer_size)
|
# TODO Fix rx_buffer_size
|
||||||
|
RX_BUFFER = queue.Queue(maxsize=16)
|
||||||
|
|
||||||
# Commands we want to send to rigctld
|
# Commands we want to send to rigctld
|
||||||
RIGCTLD_COMMAND_QUEUE = queue.Queue()
|
RIGCTLD_COMMAND_QUEUE = queue.Queue()
|
|
@ -3,6 +3,8 @@ import ujson as json
|
||||||
class STATES:
|
class STATES:
|
||||||
def __init__(self, statequeue):
|
def __init__(self, statequeue):
|
||||||
|
|
||||||
|
self.modem_version = 0.0
|
||||||
|
|
||||||
# state related settings
|
# state related settings
|
||||||
self.statequeue = statequeue
|
self.statequeue = statequeue
|
||||||
self.newstate = None
|
self.newstate = None
|
||||||
|
@ -35,10 +37,13 @@ class STATES:
|
||||||
self.arq_speed_list = []
|
self.arq_speed_list = []
|
||||||
self.arq_seconds_until_timeout = 0
|
self.arq_seconds_until_timeout = 0
|
||||||
|
|
||||||
|
self.mesh_routing_table = []
|
||||||
|
|
||||||
self.radio_frequency = 0
|
self.radio_frequency = 0
|
||||||
self.radio_mode = None
|
self.radio_mode = None
|
||||||
self.radio_bandwidth = 0
|
self.radio_bandwidth = 0
|
||||||
self.radio_rf_power = 0
|
self.radio_rf_power = 0
|
||||||
|
self.radio_strength = 0
|
||||||
|
|
||||||
def sendState (self):
|
def sendState (self):
|
||||||
currentState = self.getAsJSON(False)
|
currentState = self.getAsJSON(False)
|
||||||
|
|
|
@ -10,42 +10,43 @@ Created on 05.11.23
|
||||||
import requests
|
import requests
|
||||||
import ujson as json
|
import ujson as json
|
||||||
import structlog
|
import structlog
|
||||||
from global_instances import ARQ, HamlibParam, Station, Modem
|
|
||||||
|
|
||||||
log = structlog.get_logger("stats")
|
log = structlog.get_logger("stats")
|
||||||
|
|
||||||
|
|
||||||
class stats():
|
class stats():
|
||||||
def __init__(self):
|
def __init__(self, config, event_queue, states):
|
||||||
self.explorer_url = "https://api.freedata.app/stats.php"
|
self.explorer_url = "https://api.freedata.app/stats.php"
|
||||||
|
self.states = states
|
||||||
|
|
||||||
|
|
||||||
def push(self, frame_nack_counter, status, duration):
|
def push(self, frame_nack_counter, status, duration):
|
||||||
crcerror = status in ["crc_error", "wrong_crc"]
|
crcerror = status in ["crc_error", "wrong_crc"]
|
||||||
# get avg snr
|
# get avg snr
|
||||||
try:
|
try:
|
||||||
snr_raw = [item["snr"] for item in ARQ.speed_list]
|
snr_raw = [item["snr"] for item in self.states.arq_speed_list]
|
||||||
avg_snr = round(sum(snr_raw) / len(snr_raw), 2 )
|
avg_snr = round(sum(snr_raw) / len(snr_raw), 2 )
|
||||||
except Exception:
|
except Exception:
|
||||||
avg_snr = 0
|
avg_snr = 0
|
||||||
|
|
||||||
headers = {"Content-Type": "application/json"}
|
headers = {"Content-Type": "application/json"}
|
||||||
station_data = {
|
station_data = {
|
||||||
'callsign': str(Station.mycallsign, "utf-8"),
|
'callsign': str(self.states.mycallsign, "utf-8"),
|
||||||
'dxcallsign': str(Station.dxcallsign, "utf-8"),
|
'dxcallsign': str(self.states.dxcallsign, "utf-8"),
|
||||||
'gridsquare': str(Station.mygrid, "utf-8"),
|
'gridsquare': str(self.states.mygrid, "utf-8"),
|
||||||
'dxgridsquare': str(Station.dxgrid, "utf-8"),
|
'dxgridsquare': str(self.states.dxgrid, "utf-8"),
|
||||||
'frequency': 0 if HamlibParam.hamlib_frequency is None else HamlibParam.hamlib_frequency,
|
'frequency': 0 if self.states.radio_frequency is None else self.states.radio_frequency,
|
||||||
'avgstrength': 0,
|
'avgstrength': 0,
|
||||||
'avgsnr': avg_snr,
|
'avgsnr': avg_snr,
|
||||||
'bytesperminute': ARQ.bytes_per_minute,
|
'bytesperminute': self.states.arq_bytes_per_minute,
|
||||||
'filesize': ARQ.total_bytes,
|
'filesize': self.states.arq_total_bytes,
|
||||||
'compressionfactor': ARQ.arq_compression_factor,
|
'compressionfactor': self.states.arq_compression_factor,
|
||||||
'nacks': frame_nack_counter,
|
'nacks': frame_nack_counter,
|
||||||
'crcerror': crcerror,
|
'crcerror': crcerror,
|
||||||
'duration': duration,
|
'duration': duration,
|
||||||
'percentage': ARQ.arq_transmission_percent,
|
'percentage': self.states.arq_transmission_percent,
|
||||||
'status': status,
|
'status': status,
|
||||||
'version': Modem.version
|
'version': self.states.modem_version
|
||||||
}
|
}
|
||||||
|
|
||||||
station_data = json.dumps(station_data)
|
station_data = json.dumps(station_data)
|
||||||
|
|
Loading…
Reference in a new issue