mirror of
https://github.com/DJ2LS/FreeDATA
synced 2024-05-14 08:04:33 +00:00
ARQ WIP - introduced flags
This commit is contained in:
parent
674dd2e383
commit
0fffe86f05
|
@ -25,15 +25,6 @@ class ARQSession():
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
"""
|
|
||||||
helpers.set_flag(byte, 'DATA-ACK-NACK', True, FLAG_POSITIONS)
|
|
||||||
helpers.get_flag(byte, 'DATA-ACK-NACK', FLAG_POSITIONS)
|
|
||||||
"""
|
|
||||||
FLAG_POSITIONS = {
|
|
||||||
'DATA-ACK-NACK': 0, # Bit position for DATA-ACK-NACK
|
|
||||||
}
|
|
||||||
|
|
||||||
def __init__(self, config: dict, modem, dxcall: str):
|
def __init__(self, config: dict, modem, dxcall: str):
|
||||||
self.logger = structlog.get_logger(type(self).__name__)
|
self.logger = structlog.get_logger(type(self).__name__)
|
||||||
self.config = config
|
self.config = config
|
||||||
|
|
|
@ -144,11 +144,12 @@ class ARQSessionIRS(arq_session.ARQSession):
|
||||||
def receive_data(self, burst_frame):
|
def receive_data(self, burst_frame):
|
||||||
self.process_incoming_data(burst_frame)
|
self.process_incoming_data(burst_frame)
|
||||||
self.calibrate_speed_settings()
|
self.calibrate_speed_settings()
|
||||||
ack = self.frame_factory.build_arq_burst_ack(
|
|
||||||
self.id, self.received_bytes,
|
|
||||||
self.speed_level, self.frames_per_burst, self.snr[0])
|
|
||||||
|
|
||||||
if not self.all_data_received():
|
if not self.all_data_received():
|
||||||
|
ack = self.frame_factory.build_arq_burst_ack(
|
||||||
|
self.id, self.received_bytes,
|
||||||
|
self.speed_level, self.frames_per_burst, self.snr[0])
|
||||||
|
|
||||||
# increase ack counter
|
# increase ack counter
|
||||||
self.transmitted_acks += 1
|
self.transmitted_acks += 1
|
||||||
self.set_state(IRS_State.BURST_REPLY_SENT)
|
self.set_state(IRS_State.BURST_REPLY_SENT)
|
||||||
|
@ -157,6 +158,13 @@ class ARQSessionIRS(arq_session.ARQSession):
|
||||||
|
|
||||||
if self.final_crc_matches():
|
if self.final_crc_matches():
|
||||||
self.log("All data received successfully!")
|
self.log("All data received successfully!")
|
||||||
|
ack = self.frame_factory.build_arq_burst_ack(self.id,
|
||||||
|
self.received_bytes,
|
||||||
|
self.speed_level,
|
||||||
|
self.frames_per_burst,
|
||||||
|
self.snr[0],
|
||||||
|
flag_final=True,
|
||||||
|
flag_checksum=True)
|
||||||
self.transmit_frame(ack, mode=FREEDV_MODE.signalling)
|
self.transmit_frame(ack, mode=FREEDV_MODE.signalling)
|
||||||
self.log("ACK sent")
|
self.log("ACK sent")
|
||||||
self.set_state(IRS_State.ENDED)
|
self.set_state(IRS_State.ENDED)
|
||||||
|
@ -164,6 +172,15 @@ class ARQSessionIRS(arq_session.ARQSession):
|
||||||
False, self.id, self.dxcall, self.total_length, True)
|
False, self.id, self.dxcall, self.total_length, True)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
|
||||||
|
ack = self.frame_factory.build_arq_burst_ack(self.id,
|
||||||
|
self.received_bytes,
|
||||||
|
self.speed_level,
|
||||||
|
self.frames_per_burst,
|
||||||
|
self.snr[0],
|
||||||
|
flag_final=True,
|
||||||
|
flag_checksum=False)
|
||||||
|
self.transmit_frame(ack, mode=FREEDV_MODE.signalling)
|
||||||
self.log("CRC fail at the end of transmission!")
|
self.log("CRC fail at the end of transmission!")
|
||||||
self.set_state(IRS_State.FAILED)
|
self.set_state(IRS_State.FAILED)
|
||||||
self.event_manager.send_arq_session_finished(
|
self.event_manager.send_arq_session_finished(
|
||||||
|
|
|
@ -102,11 +102,12 @@ class ARQSessionISS(arq_session.ARQSession):
|
||||||
self.event_manager.send_arq_session_progress(
|
self.event_manager.send_arq_session_progress(
|
||||||
True, self.id, self.dxcall, self.confirmed_bytes, len(self.data))
|
True, self.id, self.dxcall, self.confirmed_bytes, len(self.data))
|
||||||
|
|
||||||
if self.confirmed_bytes == len(self.data):
|
if self.confirmed_bytes == len(self.data) and irs_frame["flag"]["FINAL"]:
|
||||||
self.set_state(ISS_State.ENDED)
|
self.set_state(ISS_State.ENDED)
|
||||||
self.log("All data transfered!")
|
self.log("All data transfered!")
|
||||||
self.event_manager.send_arq_session_finished(True, self.id, self.dxcall, len(self.data), True)
|
self.event_manager.send_arq_session_finished(True, self.id, self.dxcall, len(self.data), irs_frame["flag"]["CHECKSUM"])
|
||||||
return
|
return
|
||||||
|
|
||||||
payload_size = self.get_data_payload_size()
|
payload_size = self.get_data_payload_size()
|
||||||
burst = []
|
burst = []
|
||||||
for f in range(0, self.frames_per_burst):
|
for f in range(0, self.frames_per_burst):
|
||||||
|
|
|
@ -7,6 +7,16 @@ class DataFrameFactory:
|
||||||
LENGTH_SIG0_FRAME = 14
|
LENGTH_SIG0_FRAME = 14
|
||||||
LENGTH_SIG1_FRAME = 14
|
LENGTH_SIG1_FRAME = 14
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
helpers.set_flag(byte, 'DATA-ACK-NACK', True, FLAG_POSITIONS)
|
||||||
|
helpers.get_flag(byte, 'DATA-ACK-NACK', FLAG_POSITIONS)
|
||||||
|
"""
|
||||||
|
ARQ_FLAGS = {
|
||||||
|
'FINAL': 0, # Bit position for indicating the FINAL state
|
||||||
|
'CHECKSUM': 1, # Bit position for indicating the CHECKSUM is correct or not
|
||||||
|
}
|
||||||
|
|
||||||
def __init__(self, config):
|
def __init__(self, config):
|
||||||
self.myfullcall = f"{config['STATION']['mycall']}-{config['STATION']['myssid']}"
|
self.myfullcall = f"{config['STATION']['mycall']}-{config['STATION']['myssid']}"
|
||||||
self.mygrid = config['STATION']['mygrid']
|
self.mygrid = config['STATION']['mygrid']
|
||||||
|
@ -132,6 +142,7 @@ class DataFrameFactory:
|
||||||
"speed_level": 1,
|
"speed_level": 1,
|
||||||
"frames_per_burst": 1,
|
"frames_per_burst": 1,
|
||||||
"snr": 1,
|
"snr": 1,
|
||||||
|
"flag": 1,
|
||||||
}
|
}
|
||||||
|
|
||||||
# arq burst nack
|
# arq burst nack
|
||||||
|
@ -171,7 +182,6 @@ class DataFrameFactory:
|
||||||
item_length = len(content[key])
|
item_length = len(content[key])
|
||||||
if buffer_position + item_length > frame_length:
|
if buffer_position + item_length > frame_length:
|
||||||
raise OverflowError("Frame data overflow!")
|
raise OverflowError("Frame data overflow!")
|
||||||
|
|
||||||
frame[buffer_position: buffer_position + item_length] = content[key]
|
frame[buffer_position: buffer_position + item_length] = content[key]
|
||||||
buffer_position += item_length
|
buffer_position += item_length
|
||||||
return frame
|
return frame
|
||||||
|
@ -214,6 +224,16 @@ class DataFrameFactory:
|
||||||
"snr", "offset", "total_length", "state"]:
|
"snr", "offset", "total_length", "state"]:
|
||||||
extracted_data[key] = int.from_bytes(data, 'big')
|
extracted_data[key] = int.from_bytes(data, 'big')
|
||||||
|
|
||||||
|
elif key == "flag":
|
||||||
|
|
||||||
|
data = int.from_bytes(data, "big")
|
||||||
|
extracted_data[key] = {}
|
||||||
|
if frametype == FR_TYPE.ARQ_BURST_ACK.value:
|
||||||
|
flag_dict = self.ARQ_FLAGS
|
||||||
|
for flag in flag_dict:
|
||||||
|
# Update extracted_data with the status of each flag
|
||||||
|
# get_flag returns True or False based on the bit value at the flag's position
|
||||||
|
extracted_data[key][flag] = helpers.get_flag(data, flag, flag_dict)
|
||||||
else:
|
else:
|
||||||
extracted_data[key] = data
|
extracted_data[key] = data
|
||||||
|
|
||||||
|
@ -315,13 +335,13 @@ class DataFrameFactory:
|
||||||
return self.construct(FR_TYPE.ARQ_SESSION_OPEN, payload)
|
return self.construct(FR_TYPE.ARQ_SESSION_OPEN, payload)
|
||||||
|
|
||||||
def build_arq_session_open_ack(self, session_id, destination, version, snr):
|
def build_arq_session_open_ack(self, session_id, destination, version, snr):
|
||||||
|
|
||||||
payload = {
|
payload = {
|
||||||
"session_id": session_id.to_bytes(1, 'big'),
|
"session_id": session_id.to_bytes(1, 'big'),
|
||||||
"origin": helpers.callsign_to_bytes(self.myfullcall),
|
"origin": helpers.callsign_to_bytes(self.myfullcall),
|
||||||
"destination_crc": helpers.get_crc_24(destination),
|
"destination_crc": helpers.get_crc_24(destination),
|
||||||
"version": bytes([version]),
|
"version": bytes([version]),
|
||||||
"snr": snr.to_bytes(1, 'big'),
|
"snr": snr.to_bytes(1, 'big'), }
|
||||||
}
|
|
||||||
return self.construct(FR_TYPE.ARQ_SESSION_OPEN_ACK, payload)
|
return self.construct(FR_TYPE.ARQ_SESSION_OPEN_ACK, payload)
|
||||||
|
|
||||||
def build_arq_session_info(self, session_id: int, total_length: int, total_crc: bytes, snr):
|
def build_arq_session_info(self, session_id: int, total_length: int, total_crc: bytes, snr):
|
||||||
|
@ -354,13 +374,21 @@ class DataFrameFactory:
|
||||||
return frame
|
return frame
|
||||||
|
|
||||||
def build_arq_burst_ack(self, session_id: bytes, offset, speed_level: int,
|
def build_arq_burst_ack(self, session_id: bytes, offset, speed_level: int,
|
||||||
frames_per_burst: int, snr: int):
|
frames_per_burst: int, snr: int, flag_final=False, flag_checksum=False):
|
||||||
|
flag = 0b00000000
|
||||||
|
if flag_final:
|
||||||
|
flag = helpers.set_flag(flag, 'FINAL', True, self.ARQ_FLAGS)
|
||||||
|
|
||||||
|
if flag_checksum:
|
||||||
|
flag = helpers.set_flag(flag, 'CHECKSUM', True, self.ARQ_FLAGS)
|
||||||
|
|
||||||
payload = {
|
payload = {
|
||||||
"session_id": session_id.to_bytes(1, 'big'),
|
"session_id": session_id.to_bytes(1, 'big'),
|
||||||
"offset": offset.to_bytes(4, 'big'),
|
"offset": offset.to_bytes(4, 'big'),
|
||||||
"speed_level": speed_level.to_bytes(1, 'big'),
|
"speed_level": speed_level.to_bytes(1, 'big'),
|
||||||
"frames_per_burst": frames_per_burst.to_bytes(1, 'big'),
|
"frames_per_burst": frames_per_burst.to_bytes(1, 'big'),
|
||||||
"snr": helpers.snr_to_bytes(snr),
|
"snr": helpers.snr_to_bytes(snr),
|
||||||
|
"flag": flag.to_bytes(1, 'big'),
|
||||||
}
|
}
|
||||||
return self.construct(FR_TYPE.ARQ_BURST_ACK, payload)
|
return self.construct(FR_TYPE.ARQ_BURST_ACK, payload)
|
||||||
|
|
||||||
|
|
|
@ -98,7 +98,7 @@ class TestARQSession(unittest.TestCase):
|
||||||
|
|
||||||
def testARQSessionSmallPayload(self):
|
def testARQSessionSmallPayload(self):
|
||||||
# set Packet Error Rate (PER) / frame loss probability
|
# set Packet Error Rate (PER) / frame loss probability
|
||||||
self.loss_probability = 30
|
self.loss_probability = 0
|
||||||
|
|
||||||
self.establishChannels()
|
self.establishChannels()
|
||||||
params = {
|
params = {
|
||||||
|
@ -111,7 +111,7 @@ class TestARQSession(unittest.TestCase):
|
||||||
|
|
||||||
def testARQSessionLargePayload(self):
|
def testARQSessionLargePayload(self):
|
||||||
# set Packet Error Rate (PER) / frame loss probability
|
# set Packet Error Rate (PER) / frame loss probability
|
||||||
self.loss_probability = 50
|
self.loss_probability = 0
|
||||||
|
|
||||||
self.establishChannels()
|
self.establishChannels()
|
||||||
params = {
|
params = {
|
||||||
|
|
Loading…
Reference in a new issue