Add PingFrameHandler

This commit is contained in:
Pedro 2023-11-30 00:15:16 +01:00
parent f4b00ce68a
commit 63273b7f02
4 changed files with 121 additions and 19 deletions

View file

@ -68,6 +68,15 @@ class DataFrameFactory:
"origin": 6
}
# ping ack
self.template_list[FR_TYPE.PING_ACK.value] = {
"frame_length": self.LENGTH_SIG0_FRAME,
"destination_crc": 3,
"origin_crc": 3,
"gridsquare": 4,
"snr": 1,
}
def _load_fec_templates(self):
# fec wakeup frame
self.template_list[FR_TYPE.FEC_WAKEUP.value] = {
@ -207,7 +216,16 @@ class DataFrameFactory:
"origin": helpers.callsign_to_bytes(self.myfullcall),
}
return self.construct(FR_TYPE.PING, payload)
def build_ping_ack(self, destination, snr):
payload = {
"destination_crc": helpers.get_crc_24(destination),
"origin_crc": helpers.get_crc_24(self.myfullcall),
"gridsquare": helpers.encode_grid(self.mygrid),
"snr": helpers.snr_to_bytes(snr)
}
return self.construct(FR_TYPE.PING_ACK, payload)
def build_cq(self):
payload = {
"origin": helpers.callsign_to_bytes(self.myfullcall),

View file

@ -21,6 +21,7 @@ from protocol_arq import ARQ
from protocol_arq_session import SESSION
from frame_handler import FrameHandler
from frame_handler_ping import PingFrameHandler
class DISPATCHER():
@ -41,7 +42,7 @@ class DISPATCHER():
FR_TYPE.FR_NACK.value: {"class": FrameHandler, "name": "FRAME NACK"},
FR_TYPE.FR_REPEAT.value: {"class": FrameHandler, "name": "REPEAT REQUEST"},
FR_TYPE.PING_ACK.value: {"class": FrameHandler, "name": "PING ACK"},
FR_TYPE.PING.value: {"class": FrameHandler, "name": "PING"},
FR_TYPE.PING.value: {"class": PingFrameHandler, "name": "PING"},
FR_TYPE.QRV.value: {"class": FrameHandler, "name": "QRV"},
FR_TYPE.IS_WRITING.value: {"class": FrameHandler, "name": "IS_WRITING"},
FR_TYPE.FEC.value: {"class": FrameHandler, "name": "FEC"},
@ -169,6 +170,7 @@ class DISPATCHER():
# instantiate handler
handler_class = self.FRAME_HANDLER[frametype]['class']
handler = handler_class(self.FRAME_HANDLER[frametype]['name'],
self.config,
self.states,
self.event_manager,
MODEM_TRANSMIT_QUEUE,

View file

@ -3,41 +3,75 @@ from event_manager import EventManager
from state_manager import StateManager
from queue import Queue
import structlog
import time, uuid
from codec2 import FREEDV_MODE
class FrameHandler():
def __init__(self, name: str, states: StateManager, event_manager: EventManager,
def __init__(self, name: str, config, states: StateManager, event_manager: EventManager,
tx_frame_queue: Queue,
arq_sessions: list) -> None:
self.name = name
self.config = config
self.states = states
self.event_manager = event_manager
self.tx_trame_queue = tx_frame_queue
self.tx_frame_queue = tx_frame_queue
self.arq_sessions = arq_sessions
self.logger = structlog.get_logger("Frame Handler")
def add_to_heard_stations(self):
pass
def make_event(self, frame):
return {
"freedata": "generic frame handler",
"frame": frame,
self.details = {
'frame' : None,
'snr' : 0,
'freq_offset': 0,
'freedv_inst': None,
'bytes_per_frame': 0
}
def emit_event(self, frame):
event_data = self.make_event(frame)
def add_to_heard_stations(self):
frame = self.details['frame']
dxgrid = frame['gridsquare'] if 'gridsquare' in frame else "------"
helpers.add_to_heard_stations(
frame['origin'],
dxgrid,
self.name,
self.details['snr'],
self.details['freq_offset'],
self.states.radio_frequency,
self.states.heard_stations,
)
def make_event(self):
event = {
"freedata": "modem-message",
"uuid": str(uuid.uuid4()),
"timestamp": int(time.time()),
"mycallsign": self.config['STATION']['mycall'],
"snr": str(self.details['snr']),
}
if 'origin' in self.details['frame']:
event['dxcallsign'] = self.details['frame']['origin']
return event
def emit_event(self):
event_data = self.make_event()
self.event_manager.broadcast(event_data)
def make_modem_queue_item(self, mode, repeat, repeat_delay, frame):
return {
'mode': self.get_tx_mode(),
'repeat': 1,
'repeat_delay': 0,
'repeat': repeat,
'repeat_delay': repeat_delay,
'frame': frame,
}
def get_tx_mode(self):
return (
FREEDV_MODE.fsk_ldpc_0.value
if self.config['MODEM']['enable_fsk']
else FREEDV_MODE.sig0.value
)
def transmit(self, frame):
tx_queue_item = self.make_modem_queue_item(self.get_tx_mode(), 1, 0, frame)
self.tx_frame_queue.put(tx_queue_item)
@ -45,12 +79,18 @@ class FrameHandler():
def follow_protocol(self):
pass
def log(self, frame):
self.logger.info(f"[Frame Handler] Handling frame {frame}")
def log(self):
self.logger.info(f"[Frame Handler] Handling frame {self.details['frame']}")
pass
def handle(self, frame, snr, freq_offset, freedv_inst, bytes_per_frame):
self.log(frame)
self.details['frame'] = frame
self.details['snr'] = snr
self.details['freq_offset'] = freq_offset
self.details['freedv_inst'] = freedv_inst
self.details['bytes_per_frame'] = bytes_per_frame
self.log()
self.add_to_heard_stations()
self.emit_event(frame)
self.emit_event()
self.follow_protocol()

View file

@ -0,0 +1,42 @@
import frame_handler
import helpers
import data_frame_factory
class PingFrameHandler(frame_handler.FrameHandler):
def make_event(self):
event = super().make_event()
event['ping'] = "received"
return event
def follow_protocol(self):
deconstructed_frame = self.details['frame']
origin = deconstructed_frame["origin"]
# check if callsign ssid override
valid, mycallsign = helpers.check_callsign(
self.config['STATION']['mycall'],
deconstructed_frame["destination_crc"],
self.config['STATION']['ssid_list'])
if not valid:
# PING packet not for me.
self.logger.debug("[Modem] received_ping: ping not for this station.")
return
self.dxcallsign_crc = deconstructed_frame["origin_crc"]
self.dxcallsign = origin
self.logger.info(
f"[Modem] PING REQ from [{origin}] to [{mycallsign}]",
snr=self.details['snr'],
)
self.send_ack()
def send_ack(self):
factory = data_frame_factory.DataFrameFactory(self.config)
ping_ack_frame = factory.build_ping_ack(
self.details['frame']['origin_crc'],
self.details['snr']
)
self.transmit(ping_ack_frame)