FreeDATA/modem/arq_session.py

91 lines
2.7 KiB
Python
Raw Normal View History

2023-12-05 17:50:39 +00:00
import queue, threading
2023-12-06 10:59:35 +00:00
import codec2
2023-12-05 17:50:39 +00:00
import data_frame_factory
2023-12-05 18:12:21 +00:00
import structlog
2023-12-14 16:29:04 +00:00
from modem_frametypes import FRAME_TYPE
2023-12-05 17:50:39 +00:00
class ARQSession():
2023-12-14 21:53:32 +00:00
SPEED_LEVEL_DICT = {
0: {
'mode': codec2.FREEDV_MODE.datac4,
'min_snr': -10,
'duration_per_frame': 5.17,
},
1: {
'mode': codec2.FREEDV_MODE.datac3,
'min_snr': 0,
'duration_per_frame': 3.19,
},
2: {
'mode': codec2.FREEDV_MODE.datac1,
'min_snr': 3,
'duration_per_frame': 4.18,
},
}
2023-12-05 17:50:39 +00:00
def __init__(self, config: dict, tx_frame_queue: queue.Queue, dxcall: str):
2023-12-05 18:12:21 +00:00
self.logger = structlog.get_logger(type(self).__name__)
2023-12-05 17:50:39 +00:00
self.config = config
2023-12-14 16:29:04 +00:00
self.snr = []
2023-12-05 17:50:39 +00:00
self.dxcall = dxcall
2023-12-14 16:29:04 +00:00
self.dx_snr = []
2023-12-05 17:50:39 +00:00
self.tx_frame_queue = tx_frame_queue
self.speed_level = 0
2023-12-14 16:29:04 +00:00
self.frames_per_burst = 1
2023-12-05 17:50:39 +00:00
self.frame_factory = data_frame_factory.DataFrameFactory(self.config)
2023-12-14 16:29:04 +00:00
self.event_frame_received = threading.Event()
2023-12-05 17:50:39 +00:00
self.id = None
2023-12-11 18:02:50 +00:00
def log(self, message, isWarning = False):
msg = f"[{type(self).__name__}]: {message}"
logger = self.logger.warn if isWarning else self.logger.info
logger(msg)
2023-12-10 08:59:02 +00:00
2023-12-05 17:50:39 +00:00
def get_mode_by_speed_level(self, speed_level):
2023-12-14 21:53:32 +00:00
return self.SPEED_LEVEL_DICT[speed_level]["mode"]
2023-12-05 17:50:39 +00:00
2023-12-15 13:41:11 +00:00
def transmit_frame(self, frame: bytearray, mode = False):
2023-12-11 18:02:50 +00:00
self.log("Transmitting frame")
2023-12-15 13:41:11 +00:00
if not mode:
self.get_mode_by_speed_level(self.speed_level)
2023-12-05 18:01:48 +00:00
modem_queue_item = {
2023-12-15 13:41:11 +00:00
'mode': mode,
2023-12-05 18:01:48 +00:00
'repeat': 1,
'repeat_delay': 1,
'frame': frame,
}
self.tx_frame_queue.put(modem_queue_item)
2023-12-13 13:33:09 +00:00
def set_state(self, state):
self.log(f"{type(self).__name__} state change from {self.state} to {state}")
2023-12-05 18:12:21 +00:00
self.state = state
2023-12-06 10:59:35 +00:00
2023-12-14 16:29:04 +00:00
def get_data_payload_size(self):
return self.frame_factory.get_available_data_payload_for_mode(
FRAME_TYPE.ARQ_BURST_FRAME,
2023-12-14 21:53:32 +00:00
self.SPEED_LEVEL_DICT[self.speed_level]["mode"]
2023-12-14 16:29:04 +00:00
)
2023-12-12 21:33:17 +00:00
def set_details(self, snr, frequency_offset):
2023-12-14 16:29:04 +00:00
self.snr.append(snr)
2023-12-12 21:33:17 +00:00
self.frequency_offset = frequency_offset
2023-12-14 16:29:04 +00:00
def on_frame_received(self, frame):
self.event_frame_received.set()
frame_type = frame['frame_type_int']
if self.state in self.STATE_TRANSITION:
if frame_type in self.STATE_TRANSITION[self.state]:
action_name = self.STATE_TRANSITION[self.state][frame_type]
getattr(self, action_name)(frame)
return
self.log(f"Ignoring unknow transition from state {self.state} with frame {frame['frame_type']}")