mirror of
https://github.com/DJ2LS/FreeDATA
synced 2024-05-14 08:04:33 +00:00
195 lines
6.4 KiB
Python
195 lines
6.4 KiB
Python
import time
|
|
from modem_frametypes import FRAME_TYPE as FR_TYPE
|
|
from codec2 import FREEDV_MODE
|
|
import helpers
|
|
import uuid
|
|
import structlog
|
|
|
|
class PING:
|
|
def __init__(self, config, event_queue, states):
|
|
self.log = structlog.get_logger("DHPING")
|
|
self.states = states
|
|
self.event_queue = event_queue
|
|
self.config = config
|
|
|
|
# ---------- PING
|
|
def transmit_ping(self, mycallsign: bytes, dxcallsign: bytes) -> None:
|
|
"""
|
|
Funktion for controlling pings
|
|
Args:
|
|
mycallsign:bytes:
|
|
dxcallsign:bytes:
|
|
|
|
"""
|
|
# check if specific callsign is set with different SSID than the Modem is initialized
|
|
try:
|
|
mycallsign = helpers.callsign_to_bytes(mycallsign)
|
|
mycallsign = helpers.bytes_to_callsign(mycallsign)
|
|
except Exception:
|
|
mycallsign = self.mycallsign
|
|
|
|
if not str(dxcallsign).strip():
|
|
self.log.warning("[Modem] Missing required callsign", dxcallsign=dxcallsign)
|
|
return
|
|
|
|
# additional step for being sure our callsign is correctly
|
|
# in case we are not getting a station ssid
|
|
# then we are forcing a station ssid = 0
|
|
dxcallsign = helpers.callsign_to_bytes(dxcallsign)
|
|
dxcallsign = helpers.bytes_to_callsign(dxcallsign)
|
|
|
|
self.dxcallsign = dxcallsign
|
|
self.dxcallsign_crc = helpers.get_crc_24(self.dxcallsign)
|
|
self.send_data_to_socket_queue(
|
|
freedata="modem-message",
|
|
ping="transmitting",
|
|
dxcallsign=str(dxcallsign, "UTF-8"),
|
|
)
|
|
self.log.info(
|
|
"[Modem] PING REQ ["
|
|
+ mycallsign
|
|
+ "] >>> ["
|
|
+ str(dxcallsign, "UTF-8")
|
|
+ "]"
|
|
)
|
|
|
|
ping_frame = bytearray(self.length_sig0_frame)
|
|
ping_frame[:1] = bytes([FR_TYPE.PING.value])
|
|
ping_frame[1:4] = self.dxcallsign_crc
|
|
ping_frame[4:7] = helpers.get_crc_24(mycallsign)
|
|
ping_frame[7:13] = helpers.callsign_to_bytes(mycallsign)
|
|
|
|
if self.enable_fsk:
|
|
self.log.info("[Modem] ENABLE FSK", state=self.enable_fsk)
|
|
self.enqueue_frame_for_tx([ping_frame], c2_mode=FREEDV_MODE.fsk_ldpc_0.value)
|
|
else:
|
|
self.enqueue_frame_for_tx([ping_frame], c2_mode=FREEDV_MODE.sig0.value)
|
|
|
|
def received_ping(self, data_in: bytes, snr) -> None:
|
|
"""
|
|
Called if we received a ping
|
|
|
|
Args:
|
|
data_in:bytes:
|
|
|
|
"""
|
|
dxcallsign_crc = bytes(data_in[4:7])
|
|
dxcallsign = helpers.bytes_to_callsign(bytes(data_in[7:13]))
|
|
|
|
# check if callsign ssid override
|
|
valid, mycallsign = helpers.check_callsign(self.mycallsign, data_in[1:4], self.ssid_list)
|
|
if not valid:
|
|
# PING packet not for me.
|
|
self.log.debug("[Modem] received_ping: ping not for this station.")
|
|
return
|
|
|
|
self.dxcallsign_crc = dxcallsign_crc
|
|
self.dxcallsign = dxcallsign
|
|
self.log.info(
|
|
"[Modem] PING REQ ["
|
|
+ str(mycallsign, "UTF-8")
|
|
+ "] <<< ["
|
|
+ str(dxcallsign, "UTF-8")
|
|
+ "]",
|
|
snr=snr,
|
|
)
|
|
|
|
self.dxgrid = b'------'
|
|
helpers.add_to_heard_stations(
|
|
dxcallsign,
|
|
self.dxgrid,
|
|
"PING",
|
|
snr,
|
|
self.modem_frequency_offset,
|
|
self.states.radio_frequency,
|
|
self.states.heard_stations
|
|
)
|
|
|
|
self.send_data_to_socket_queue(
|
|
freedata="modem-message",
|
|
ping="received",
|
|
uuid=str(uuid.uuid4()),
|
|
timestamp=int(time.time()),
|
|
dxgrid=str(self.dxgrid, "UTF-8"),
|
|
dxcallsign=str(dxcallsign, "UTF-8"),
|
|
mycallsign=str(mycallsign, "UTF-8"),
|
|
snr=str(snr),
|
|
)
|
|
if self.respond_to_call:
|
|
self.transmit_ping_ack(snr)
|
|
|
|
def transmit_ping_ack(self, snr):
|
|
"""
|
|
|
|
transmit a ping ack frame
|
|
called by def received_ping
|
|
"""
|
|
ping_frame = bytearray(self.length_sig0_frame)
|
|
ping_frame[:1] = bytes([FR_TYPE.PING_ACK.value])
|
|
ping_frame[1:4] = self.dxcallsign_crc
|
|
ping_frame[4:7] = self.mycallsign_crc
|
|
ping_frame[7:11] = helpers.encode_grid(self.mygrid)
|
|
ping_frame[13:14] = helpers.snr_to_bytes(snr)
|
|
|
|
if self.enable_fsk:
|
|
self.enqueue_frame_for_tx([ping_frame], c2_mode=FREEDV_MODE.fsk_ldpc_0.value)
|
|
else:
|
|
self.enqueue_frame_for_tx([ping_frame], c2_mode=FREEDV_MODE.sig0.value)
|
|
|
|
def received_ping_ack(self, data_in: bytes, snr) -> None:
|
|
"""
|
|
Called if a PING ack has been received
|
|
Args:
|
|
data_in:bytes:
|
|
|
|
"""
|
|
|
|
# check if we received correct ping
|
|
# check if callsign ssid override
|
|
_valid, mycallsign = helpers.check_callsign(self.mycallsign, data_in[1:4], self.ssid_list)
|
|
if _valid:
|
|
|
|
self.dxgrid = bytes(helpers.decode_grid(data_in[7:11]), "UTF-8")
|
|
dxsnr = helpers.snr_from_bytes(data_in[13:14])
|
|
self.send_data_to_socket_queue(
|
|
freedata="modem-message",
|
|
ping="acknowledge",
|
|
uuid=str(uuid.uuid4()),
|
|
timestamp=int(time.time()),
|
|
dxgrid=str(self.dxgrid, "UTF-8"),
|
|
dxcallsign=str(self.dxcallsign, "UTF-8"),
|
|
mycallsign=str(mycallsign, "UTF-8"),
|
|
snr=str(snr),
|
|
dxsnr=str(dxsnr)
|
|
)
|
|
# combined_snr = own rx snr / snr on dx side
|
|
combined_snr = f"{snr}/{dxsnr}"
|
|
helpers.add_to_heard_stations(
|
|
self.dxcallsign,
|
|
self.dxgrid,
|
|
"PING-ACK",
|
|
combined_snr,
|
|
self.modem_frequency_offset,
|
|
self.states.radio_frequency,
|
|
self.states.heard_stations
|
|
)
|
|
|
|
self.log.info(
|
|
"[Modem] PING ACK ["
|
|
+ str(mycallsign, "UTF-8")
|
|
+ "] >|< ["
|
|
+ str(self.dxcallsign, "UTF-8")
|
|
+ "]",
|
|
snr=snr,
|
|
dxsnr=dxsnr,
|
|
)
|
|
self.states.set("is_modem_busy", False)
|
|
else:
|
|
self.log.info(
|
|
"[Modem] FOREIGN PING ACK ["
|
|
+ str(self.mycallsign, "UTF-8")
|
|
+ "] ??? ["
|
|
+ str(bytes(data_in[4:7]), "UTF-8")
|
|
+ "]",
|
|
snr=snr,
|
|
)
|