WIP adding arq data frame

This commit is contained in:
DJ2LS 2023-12-08 11:42:38 +01:00
parent 71ad71d0bf
commit 5842519e2a
3 changed files with 59 additions and 23 deletions

View file

@ -74,17 +74,21 @@ class ARQSessionISS(arq_session.ARQSession):
# Sends the full payload in multiple frames
def send_data(self):
# Todo make this n frames per burst stuff part of the protocol again
# hard coding n frames per burst to 1 for now.
n_frames_per_burst = 1
n_frame = 1
offset = 0
while offset < len(self.data):
max_size = self.get_payload_size(self.speed_level)
end_offset = min(len(self.data), max_size)
frame_payload = self.data[offset:end_offset]
# TODO build_arq_session_connect is wrong frame. It seems we need to create the correct function for this
#data_frame = self.frame_factory.build_arq_session_connect(self.speed_level, self.dxcall, frame_payload)
#self.set_state(self.STATE_SENDING)
#if not self.send_arq(data_frame):
# return False
#offset = end_offset + 1
data_frame = self.frame_factory.build_arq_data_frame(self.id, n_frames_per_burst, max_size, n_frame, frame_payload)
self.set_state(self.STATE_SENDING)
if not self.send_arq(data_frame):
return False
offset = end_offset + 1
# Send part of the payload using ARQ
def send_arq(self, frame):

View file

@ -101,7 +101,7 @@ class DataFrameFactory:
def _load_arq_templates(self):
# same structure for narrow and wide types
arq_dc_open = {
arq_session_open = {
"frame_length": self.LENGTH_SIG0_FRAME,
"destination_crc": 3,
"origin_crc": 3,
@ -109,22 +109,32 @@ class DataFrameFactory:
"session_id": 1,
}
# arq connect frames
self.template_list[FR_TYPE.ARQ_SESSION_OPEN_N.value] = arq_dc_open
self.template_list[FR_TYPE.ARQ_SESSION_OPEN_W.value] = arq_dc_open
self.template_list[FR_TYPE.ARQ_SESSION_OPEN_N.value] = arq_session_open
self.template_list[FR_TYPE.ARQ_SESSION_OPEN_W.value] = arq_session_open
# same structure for narrow and wide types
arq_dc_open_ack = {
arq_session_open_ack = {
"frame_length": self.LENGTH_SIG0_FRAME,
"session_id": 1,
"speed_level": 1,
"arq_protocol_version": 1
}
# arq connect ack frames
self.template_list[FR_TYPE.ARQ_SESSION_OPEN_ACK_N.value] = arq_dc_open_ack
self.template_list[FR_TYPE.ARQ_SESSION_OPEN_ACK_W.value] = arq_dc_open_ack
self.template_list[FR_TYPE.ARQ_SESSION_OPEN_ACK_N.value] = arq_session_open_ack
self.template_list[FR_TYPE.ARQ_SESSION_OPEN_ACK_W.value] = arq_session_open_ack
# arq data frame
# register n frames
for n_frame in range(0,50):
self.template_list[FR_TYPE.BURST_01.value + n_frame] = {
"frame_length": "dynamic",
"n_frames_per_burst": 1,
"session_id": 1,
"payload": "dynamic",
}
# arq burst ack
self.template_list[FR_TYPE.BURST_ACK.value] = {
"frame_length": self.LENGTH_SIG1_FRAME,
@ -163,10 +173,20 @@ class DataFrameFactory:
}
def construct(self, frametype, content):
frame_template = self.template_list[frametype.value]
frame_length = frame_template["frame_length"]
frame = bytearray(frame_length)
def construct(self, frametype, content, frame_length=LENGTH_SIG1_FRAME):
# frame_length: can be set manually for data frames, whose length can be dynamic regarding corresponding mode
# data bursts have a frame type range of 01-50
if frametype in range(1, 50):
frame_template = self.template_list[frametype.value]
frame = bytearray(frame_length)
# override "dynamic" value of payload length
self.template_list[frame_template].payload = frame_length - 3
else:
frame_template = self.template_list[frametype.value]
frame_length = frame_template["frame_length"]
frame = bytearray(frame_length)
buffer_position = 1
for key, item_length in frame_template.items():
@ -222,9 +242,11 @@ class DataFrameFactory:
:rtype: int
"""
freedv = codec2.open_instance(mode)
# TODO add close session
# get number of bytes per frame for mode
return int(codec2.api.freedv_get_bits_per_modem_frame(freedv) / 8)
bytes_per_frame = int(codec2.api.freedv_get_bits_per_modem_frame(freedv) / 8)
# TODO add close session
return bytes_per_frame
def build_ping(self, destination):
payload = {
@ -326,6 +348,16 @@ class DataFrameFactory:
channel_type = FR_TYPE.ARQ_SESSION_OPEN_ACK_W if isWideband else FR_TYPE.ARQ_SESSION_OPEN_ACK_N
return self.construct(channel_type, payload)
def build_arq_data_frame(self, session_id: bytes, n_frames_per_burst: int, max_size: int, n_frame: int, frame_payload: bytes):
payload = {
"n_frames_per_burst": bytes([n_frames_per_burst]),
"session_id": session_id,
"data": frame_payload
}
return self.construct(FR_TYPE.FR_TYPE.BURST_01.value + n_frame, payload, frame_length=max_size)
def build_arq_burst_ack(self, session_id: bytes, snr: int, speed_level: int, len_arq_rx_frame_buffer: int):
# ack_frame = bytearray(self.length_sig1_frame)
# ack_frame[:1] = bytes([FR_TYPE.BURST_ACK.value])

View file

@ -7,12 +7,12 @@ from enum import Enum
class FRAME_TYPE(Enum):
"""Lookup for frame types"""
BURST_01 = 10
BURST_02 = 11
BURST_03 = 12
BURST_04 = 13
BURST_01 = 1
BURST_02 = 2
BURST_03 = 3
BURST_04 = 4
# ...
BURST_51 = 50
BURST_50 = 50
BURST_ACK = 60
FR_ACK = 61
FR_REPEAT = 62