attempt fixing some callsign related stuff...aaargh

This commit is contained in:
DJ2LS 2023-11-19 14:03:48 +01:00
parent 225af9e8b5
commit 442a041952
6 changed files with 153 additions and 50 deletions

View file

@ -68,6 +68,15 @@ export function sendModemPing(dxcall) {
return apiPost("/modem/ping_ping", { dxcall: dxcall }); return apiPost("/modem/ping_ping", { dxcall: dxcall });
} }
export function sendModemARQRaw(mycall, dxcall, data, uuid) {
return apiPost("/modem/send_arq_raw", {
mycallsign: mycall,
dxcallsign: dxcall,
data: data,
uuid: uuid
});
}
export function sendModemTestFrame() { export function sendModemTestFrame() {
return apiPost("/modem/send_test_frame"); return apiPost("/modem/send_test_frame");
} }

View file

@ -20,6 +20,11 @@ import { displayToast } from "./popupHandler.js";
//const FD = require("./src/js/freedata.js"); //const FD = require("./src/js/freedata.js");
import { btoa_FD, sortByProperty } from "./freedata.js"; import { btoa_FD, sortByProperty } from "./freedata.js";
import { sendModemARQRaw } from "../js/api.js";
const split_char = "0;1;";
// define default message object // define default message object
interface Attachment { interface Attachment {
content_type: string; content_type: string;
@ -1074,3 +1079,43 @@ async function checkForWaitingMessages(dxcall) {
console.log(err); console.log(err);
}); });
} }
export function sendMessage(obj) {
let dxcallsign = obj.dxcallsign;
let checksum = obj.checksum;
let uuid = obj.uuid;
let command = obj.command;
let filename = Object.keys(obj._attachments)[0];
//let filetype = filename.split(".")[1]
let filetype = obj._attachments[filename].content_type;
let file = obj._attachments[filename].data;
let data_with_attachment =
obj.timestamp +
split_char +
obj.msg +
split_char +
filename +
split_char +
filetype +
split_char +
file;
let data = btoa_FD(
"m" +
split_char +
command +
split_char +
checksum +
split_char +
uuid +
split_char +
data_with_attachment,
);
let mycallsign = settings.remote.STATION.mycall + '-' + settings.remote.STATION.myssid;
sendModemARQRaw(mycallsign, dxcallsign, data, uuid)
}

View file

@ -44,11 +44,14 @@ class DATA:
self.stats = stats.stats(config, event_queue, states) self.stats = stats.stats(config, event_queue, states)
self.event_queue = event_queue self.event_queue = event_queue
# Functions here expect mycallsign to be in callxx-# format; so cheat a little bit here:
self.mycallsign = config['STATION']['mycall'] self.mycallsign = config['STATION']['mycall']
self.myssid = config['STATION']['myssid'] self.myssid = config['STATION']['myssid']
# Functions here expect mycallsign to be in callxx-# format; so cheat a little bit here:
self.mycallsign += "-" + str(self.myssid) self.mycallsign += "-" + str(self.myssid)
encoded_call = helpers.callsign_to_bytes(self.mycallsign)
self.mycallsign = helpers.bytes_to_callsign(encoded_call)
self.ssid_list = config['STATION']['ssid_list'] self.ssid_list = config['STATION']['ssid_list']
self.mycallsign_crc = helpers.get_crc_24(self.mycallsign) self.mycallsign_crc = helpers.get_crc_24(self.mycallsign)
@ -102,7 +105,7 @@ class DATA:
self.IS_ARQ_SESSION_MASTER = False self.IS_ARQ_SESSION_MASTER = False
self.arq_session_last_received = 0 self.arq_session_last_received = 0
self.arq_session_timeout = 30 self.arq_session_timeout = 30
self.session_connect_max_retries = 15 self.session_connect_max_retries = 10
self.irs_buffer_position = 0 self.irs_buffer_position = 0
self.arq_compression_factor = 0 self.arq_compression_factor = 0
@ -151,7 +154,6 @@ class DATA:
# event for checking arq_state_event # event for checking arq_state_event
self.arq_state_event = threading.Event() self.arq_state_event = threading.Event()
# -------------- AVAILABLE MODES START----------- # -------------- AVAILABLE MODES START-----------
# IMPORTANT: LISTS MUST BE OF EQUAL LENGTH # IMPORTANT: LISTS MUST BE OF EQUAL LENGTH
@ -314,6 +316,8 @@ class DATA:
"""Dispatch incoming UI instructions for transmitting operations""" """Dispatch incoming UI instructions for transmitting operations"""
while True: while True:
data = self.data_queue_transmit.get() data = self.data_queue_transmit.get()
# if we are already in ARQ_STATE, or we're receiving codec2 traffic # if we are already in ARQ_STATE, or we're receiving codec2 traffic
# let's wait with processing data # let's wait with processing data
@ -349,8 +353,7 @@ class DATA:
elif data[0] == "CONNECT": elif data[0] == "CONNECT":
# [1] mycallsign # [1] mycallsign
# [2] dxcallsign # [2] dxcallsign
# [3] attempts self.arq_session_handler(data[1], data[2])
self.arq_session_handler(data[1], data[2], data[3])
elif data[0] == "PING": elif data[0] == "PING":
# [1] mycallsign # [1] mycallsign
@ -370,11 +373,9 @@ class DATA:
elif data[0] == "ARQ_RAW": elif data[0] == "ARQ_RAW":
# [1] DATA_OUT bytes # [1] DATA_OUT bytes
# [2] self.transmission_uuid str # [2] self.transmission_uuid str
# [3] mycallsign with ssid # [3] mycallsign with ssid str
# [4] dxcallsign with ssid # [4] dxcallsign with ssid str
# [5] attempts self.open_dc_and_transmit(data[1], data[2], data[3], data[4])
# [6] hmac salt hash
self.open_dc_and_transmit(data[1], data[2], data[3], data[4], data[5], data[6])
elif data[0] == "FEC_IS_WRITING": elif data[0] == "FEC_IS_WRITING":
@ -549,12 +550,12 @@ class DATA:
# add mycallsign and dxcallsign to network message if they not exist # add mycallsign and dxcallsign to network message if they not exist
# and make sure we are not overwrite them if they exist # and make sure we are not overwrite them if they exist
try: try:
if "mycallsign" not in jsondata: if "mycallsign" not in jsondata:
jsondata["mycallsign"] = self.mycallsign jsondata["mycallsign"] = str(self.mycallsign, "UTF-8")
if "dxcallsign" not in jsondata: if "dxcallsign" not in jsondata:
print(self.dxcallsign) jsondata["dxcallsign"] = str(self.dxcallsign, "UTF-8")
jsondata["dxcallsign"] = self.dxcallsign
except Exception as e: except Exception as e:
self.log.debug("[Modem] error adding callsigns to network message", e=e) self.log.debug("[Modem] error adding callsigns to network message", e=e)
@ -1709,7 +1710,7 @@ class DATA:
############################################################################################################ ############################################################################################################
# ARQ SESSION HANDLER # ARQ SESSION HANDLER
############################################################################################################ ############################################################################################################
def arq_session_handler(self, mycallsign, dxcallsign, attempts) -> bool: def arq_session_handler(self, mycallsign, dxcallsign) -> bool:
""" """
Create a session with `self.dxcallsign` and wait until the session is open. Create a session with `self.dxcallsign` and wait until the session is open.
@ -1717,20 +1718,21 @@ class DATA:
True if the session was opened successfully True if the session was opened successfully
False if the session open request failed False if the session open request failed
""" """
# override connection attempts
self.session_connect_max_retries = attempts
self.mycallsign = mycallsign encoded_call = helpers.callsign_to_bytes(mycallsign)
self.dxcallsign = dxcallsign mycallsign = helpers.bytes_to_callsign(encoded_call)
self.states.set("dxcallsign", self.dxcallsign) encoded_call = helpers.callsign_to_bytes(dxcallsign)
self.dxcallsign_crc = helpers.get_crc_24(self.dxcallsign) dxcallsign = helpers.bytes_to_callsign(encoded_call)
self.states.set("dxcallsign", dxcallsign)
dxcallsign_crc = helpers.get_crc_24(dxcallsign)
self.log.info( self.log.info(
"[Modem] SESSION [" "[Modem] SESSION ["
+ str(self.mycallsign, "UTF-8") + str(mycallsign, "UTF-8")
+ "]>> <<[" + "]>> <<["
+ str(self.dxcallsign, "UTF-8") + str(dxcallsign, "UTF-8")
+ "]", + "]",
self.states.arq_session_state, self.states.arq_session_state,
) )
@ -1749,8 +1751,8 @@ class DATA:
freedata="modem-message", freedata="modem-message",
arq="session", arq="session",
status="connecting", status="connecting",
mycallsign=str(self.mycallsign, 'UTF-8'), mycallsign=str(mycallsign, 'UTF-8'),
dxcallsign=str(self.dxcallsign, 'UTF-8'), dxcallsign=str(dxcallsign, 'UTF-8'),
) )
if self.states.is_arq_session and self.states.arq_session_state == "connected": if self.states.is_arq_session and self.states.arq_session_state == "connected":
# self.states.set("arq_session_state", "connected") # self.states.set("arq_session_state", "connected")
@ -1758,16 +1760,16 @@ class DATA:
freedata="modem-message", freedata="modem-message",
arq="session", arq="session",
status="connected", status="connected",
mycallsign=str(self.mycallsign, 'UTF-8'), mycallsign=str(mycallsign, 'UTF-8'),
dxcallsign=str(self.dxcallsign, 'UTF-8'), dxcallsign=str(dxcallsign, 'UTF-8'),
) )
return True return True
self.log.warning( self.log.warning(
"[Modem] SESSION FAILED [" "[Modem] SESSION FAILED ["
+ str(self.mycallsign, "UTF-8") + str(mycallsign, "UTF-8")
+ "]>>X<<[" + "]>>X<<["
+ str(self.dxcallsign, "UTF-8") + str(dxcallsign, "UTF-8")
+ "]", + "]",
attempts=self.session_connect_max_retries, # Adjust for 0-based for user display attempts=self.session_connect_max_retries, # Adjust for 0-based for user display
reason="maximum connection attempts reached", reason="maximum connection attempts reached",
@ -1779,8 +1781,8 @@ class DATA:
arq="session", arq="session",
status="failed", status="failed",
reason="timeout", reason="timeout",
mycallsign=str(self.mycallsign, 'UTF-8'), mycallsign=str(mycallsign, 'UTF-8'),
dxcallsign=str(self.dxcallsign, 'UTF-8'), dxcallsign=str(dxcallsign, 'UTF-8'),
) )
return False return False
@ -1986,7 +1988,7 @@ class DATA:
) )
self.log.info( self.log.info(
"[Modem] SESSION [" "[Modem] SESSION ["
+ str(mycallsign, "UTF-8") + str(self.mycallsign, "UTF-8")
+ "]<<X>>[" + "]<<X>>["
+ str(self.dxcallsign, "UTF-8") + str(self.dxcallsign, "UTF-8")
+ "]", + "]",
@ -1997,7 +1999,7 @@ class DATA:
freedata="modem-message", freedata="modem-message",
arq="session", arq="session",
status="close", status="close",
mycallsign=str(mycallsign, 'UTF-8'), mycallsign=str(self.mycallsign, 'UTF-8'),
dxcallsign=str(self.dxcallsign, 'UTF-8'), dxcallsign=str(self.dxcallsign, 'UTF-8'),
) )
@ -2089,8 +2091,6 @@ class DATA:
transmission_uuid: str, transmission_uuid: str,
mycallsign, mycallsign,
dxcallsign, dxcallsign,
attempts: int,
hmac_salt: str
) -> bool: ) -> bool:
""" """
Open data channel and transmit data Open data channel and transmit data
@ -2099,22 +2099,37 @@ class DATA:
data_out:bytes: data_out:bytes:
transmission_uuid:str: transmission_uuid:str:
mycallsign:bytes: mycallsign:bytes:
attempts:int: Overriding number of attempts initiating a connection
Returns: Returns:
True if the data session was opened and the data was sent True if the data session was opened and the data was sent
False if the data session was not opened False if the data session was not opened
""" """
# overwrite mycallsign in case of different SSID
self.mycallsign = mycallsign self.mycallsign = mycallsign
self.dxcallsign = dxcallsign
# 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
if not self.states.is_arq_session:
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.dxcallsign_crc = helpers.get_crc_24(self.dxcallsign)
# override session connection attempts # check if hmac hash is provided
self.data_channel_max_retries = attempts try:
self.log.info("[SCK] [HMAC] Looking for salt/token", local=mycallsign, remote=dxcallsign)
hmac_salt = helpers.get_hmac_salt(dxcallsign, mycallsign)
self.log.info("[SCK] [HMAC] Salt info", local=mycallsign, remote=dxcallsign, salt=hmac_salt)
except Exception:
self.log.warning("[SCK] [HMAC] No salt/token found")
hmac_salt = ''
self.states.set("is_modem_busy", True) self.states.set("is_modem_busy", True)
self.arq_file_transfer = True self.arq_file_transfer = True
self.beacon_paused = True
self.transmission_uuid = transmission_uuid self.transmission_uuid = transmission_uuid
@ -2130,7 +2145,7 @@ class DATA:
self.arq_open_data_channel(mycallsign) self.arq_open_data_channel(mycallsign)
# if data channel is open, return true else false # if data channel is open, return true else false
if self.states.is_arq_state_event.is_set(): if self.arq_state_event.is_set():
# start arq transmission # start arq transmission
self.arq_transmit(data_out, hmac_salt) self.arq_transmit(data_out, hmac_salt)
return True return True
@ -2168,6 +2183,9 @@ class DATA:
# open_session frame and can still hear us. # open_session frame and can still hear us.
self.close_session() self.close_session()
# release beacon pause
self.beacon_paused = False
# otherwise return false # otherwise return false
return False return False
@ -2216,14 +2234,14 @@ class DATA:
freedata="modem-message", freedata="modem-message",
arq="transmission", arq="transmission",
status="opening", status="opening",
mycallsign=str(mycallsign, 'UTF-8'), mycallsign=mycallsign,
dxcallsign=str(self.dxcallsign, 'UTF-8'), dxcallsign=str(self.dxcallsign, 'UTF-8'),
irs=helpers.bool_to_string(self.is_IRS) irs=helpers.bool_to_string(self.is_IRS)
) )
self.log.info( self.log.info(
"[Modem] ARQ | DATA | TX | [" "[Modem] ARQ | DATA | TX | ["
+ str(mycallsign, "UTF-8") + mycallsign
+ "]>> <<[" + "]>> <<["
+ str(self.dxcallsign, "UTF-8") + str(self.dxcallsign, "UTF-8")
+ "]", + "]",
@ -2235,7 +2253,7 @@ class DATA:
self.channel_busy_handler() self.channel_busy_handler()
# if channel free, enqueue frame for tx # if channel free, enqueue frame for tx
if not self.states.is_arq_state_event.is_set(): if not self.arq_state_event.is_set():
self.enqueue_frame_for_tx([connection_frame], c2_mode=FREEDV_MODE.sig0.value, copies=1, repeat_delay=0) self.enqueue_frame_for_tx([connection_frame], c2_mode=FREEDV_MODE.sig0.value, copies=1, repeat_delay=0)
# wait until timeout or event set # wait until timeout or event set
@ -2243,7 +2261,7 @@ class DATA:
random_wait_time = randrange(int(self.duration_sig1_frame * 10), int(self.datachannel_opening_interval * 10), 1) / 10 random_wait_time = randrange(int(self.duration_sig1_frame * 10), int(self.datachannel_opening_interval * 10), 1) / 10
self.arq_state_event.wait(timeout=random_wait_time) self.arq_state_event.wait(timeout=random_wait_time)
if self.states.is_arq_state_event.is_set(): if self.arq_state_event.is_set():
return True return True
if not self.states.is_modem_busy: if not self.states.is_modem_busy:
return False return False
@ -2281,7 +2299,7 @@ class DATA:
# Station B already tries connecting to Station A. # Station B already tries connecting to Station A.
# For avoiding ignoring repeated connect request in case of packet loss # For avoiding ignoring repeated connect request in case of packet loss
# we are only ignoring packets in case we are ISS # we are only ignoring packets in case we are ISS
if self.states.is_arq_state_event.is_set() and not self.is_IRS: if self.arq_state_event.is_set() and not self.is_IRS:
return False return False
self.is_IRS = True self.is_IRS = True
@ -2855,7 +2873,7 @@ class DATA:
self.send_data_to_socket_queue( self.send_data_to_socket_queue(
freedata="modem-message", freedata="modem-message",
cq="transmitting", cq="transmitting",
mycallsign=self.mycallsign, mycallsign=str(self.mycallsign, "UTF-8"),
dxcallsign="None", dxcallsign="None",
) )
cq_frame = bytearray(self.length_sig0_frame) cq_frame = bytearray(self.length_sig0_frame)
@ -2888,7 +2906,7 @@ class DATA:
self.send_data_to_socket_queue( self.send_data_to_socket_queue(
freedata="modem-message", freedata="modem-message",
cq="received", cq="received",
mycallsign=self.mycallsign, mycallsign=str(self.mycallsign, "UTF-8"),
dxcallsign=str(dxcallsign, "UTF-8"), dxcallsign=str(dxcallsign, "UTF-8"),
dxgrid=str(self.dxgrid, "UTF-8"), dxgrid=str(self.dxgrid, "UTF-8"),
) )
@ -2937,7 +2955,7 @@ class DATA:
dxcallsign=str(dxcallsign, "UTF-8"), dxcallsign=str(dxcallsign, "UTF-8"),
) )
self.log.info("[Modem] Sending QRV!") self.log.info("[Modem] Sending QRV!")
print(self.mycallsign)
qrv_frame = bytearray(self.length_sig0_frame) qrv_frame = bytearray(self.length_sig0_frame)
qrv_frame[:1] = bytes([FR_TYPE.QRV.value]) qrv_frame[:1] = bytes([FR_TYPE.QRV.value])
qrv_frame[1:7] = helpers.callsign_to_bytes(self.mycallsign) qrv_frame[1:7] = helpers.callsign_to_bytes(self.mycallsign)

View file

@ -212,7 +212,7 @@ def callsign_to_bytes(callsign: str) -> bytes:
# log.debug("[HLP] callsign_to_bytes: Error converting callsign to bytes:", e=err) # log.debug("[HLP] callsign_to_bytes: Error converting callsign to bytes:", e=err)
pass pass
except Exception as err: except Exception as err:
log.debug("[HLP] callsign_to_bytes: Error converting callsign to bytes:", e=err) log.debug("[HLP] callsign_to_bytes: Error converting callsign to bytes:", e=err, data=callsign)
# Need this step to reduce the needed payload by the callsign # Need this step to reduce the needed payload by the callsign
# (stripping "-" out of the callsign) # (stripping "-" out of the callsign)

View file

@ -167,6 +167,12 @@ def post_modem_stop():
def get_modem_version(): def get_modem_version():
return api_response({"version": 0}) return api_response({"version": 0})
@app.route('/modem/send_arq_raw', methods=['POST'])
def post_modem_send_raw():
if request.method not in ['POST']:
return api_response({"info": "endpoint for SENDING RAW DATA via POST"})
server_commands.modem_arq_send_raw(request.json)
return api_response(request.json)
# @app.route('/modem/arq_connect', methods=['POST']) # @app.route('/modem/arq_connect', methods=['POST'])
# @app.route('/modem/arq_disconnect', methods=['POST']) # @app.route('/modem/arq_disconnect', methods=['POST'])

View file

@ -1,6 +1,8 @@
from queues import DATA_QUEUE_TRANSMIT from queues import DATA_QUEUE_TRANSMIT
import base64 import base64
import structlog import structlog
import threading
from random import randrange
log = structlog.get_logger("COMMANDS") log = structlog.get_logger("COMMANDS")
def cqcqcq(data): def cqcqcq(data):
@ -38,6 +40,29 @@ def modem_send_test_frame():
"[CMD] Send test frame" "[CMD] Send test frame"
) )
DATA_QUEUE_TRANSMIT.put(["SEND_TEST_FRAME"]) DATA_QUEUE_TRANSMIT.put(["SEND_TEST_FRAME"])
def modem_arq_send_raw(data):
# wait some random time
threading.Event().wait(randrange(5, 25, 5) / 10.0)
base64data = data["data"]
# check if transmission uuid provided else set no-uuid
try:
arq_uuid = data["uuid"]
except Exception:
arq_uuid = "no-uuid"
if len(base64data) % 4:
raise TypeError
binarydata = base64.b64decode(base64data)
DATA_QUEUE_TRANSMIT.put(
["ARQ_RAW", binarydata, arq_uuid, data["mycallsign"], data["dxcallsign"]]
)
def modem_fec_transmit(data): def modem_fec_transmit(data):
log.info( log.info(