mirror of
https://github.com/DJ2LS/FreeDATA
synced 2024-05-14 08:04:33 +00:00
some more frame porting
This commit is contained in:
parent
ca1257bab7
commit
02062e3e18
|
@ -99,9 +99,9 @@ class DataFrameFactory:
|
|||
}
|
||||
|
||||
def _load_arq_templates(self):
|
||||
|
||||
# same structure for narrow and wide types
|
||||
arq_dc_open_ack = {
|
||||
|
||||
arq_dc_open = {
|
||||
"frame_length": self.LENGTH_SIG0_FRAME,
|
||||
"destination_crc": 3,
|
||||
"origin_crc": 3,
|
||||
|
@ -109,9 +109,22 @@ class DataFrameFactory:
|
|||
"session_id": 1,
|
||||
}
|
||||
# arq connect frames
|
||||
self.template_list[FR_TYPE.ARQ_DC_OPEN_N.value] = arq_dc_open
|
||||
self.template_list[FR_TYPE.ARQ_DC_OPEN_W.value] = arq_dc_open
|
||||
|
||||
# same structure for narrow and wide types
|
||||
arq_dc_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_DC_OPEN_ACK_N.value] = arq_dc_open_ack
|
||||
self.template_list[FR_TYPE.ARQ_DC_OPEN_ACK_W.value] = arq_dc_open_ack
|
||||
|
||||
|
||||
|
||||
# arq burst ack
|
||||
self.template_list[FR_TYPE.BURST_ACK.value] = {
|
||||
"frame_length": self.LENGTH_SIG1_FRAME,
|
||||
|
@ -288,9 +301,36 @@ class DataFrameFactory:
|
|||
"session_id": session_id.to_bytes(1, 'big'),
|
||||
}
|
||||
|
||||
channel_type = FR_TYPE.ARQ_DC_OPEN_W if isWideband else FR_TYPE.ARQ_DC_OPEN_N
|
||||
return self.construct(channel_type, payload)
|
||||
|
||||
def build_arq_connect_ack(self, isWideband, session_id, speed_level,arq_protocol_version):
|
||||
|
||||
#connection_frame = bytearray(self.length_sig0_frame)
|
||||
#connection_frame[:1] = frametype
|
||||
#connection_frame[1:2] = self.session_id
|
||||
#connection_frame[8:9] = bytes([self.speed_level])
|
||||
#connection_frame[13:14] = bytes([self.arq_protocol_version])
|
||||
|
||||
payload = {
|
||||
"session_id": session_id.to_bytes(1, 'big'),
|
||||
"speed_level": bytes([speed_level]),
|
||||
"arq_protocol_version": bytes([arq_protocol_version]),
|
||||
}
|
||||
|
||||
channel_type = FR_TYPE.ARQ_DC_OPEN_ACK_W if isWideband else FR_TYPE.ARQ_DC_OPEN_ACK_N
|
||||
return self.construct(channel_type, payload)
|
||||
|
||||
def build_arq_session_connect(self, isWideband, destination, session_id):
|
||||
|
||||
payload = {
|
||||
"destination_crc": helpers.get_crc_24(destination),
|
||||
"origin_crc": helpers.get_crc_24(self.myfullcall),
|
||||
"origin": helpers.callsign_to_bytes(self.myfullcall),
|
||||
"session_id": session_id.to_bytes(1, 'big'),
|
||||
}
|
||||
return self.construct(FR_TYPE.ARQ_SESSION_OPEN, payload)
|
||||
|
||||
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])
|
||||
|
|
|
@ -329,13 +329,14 @@ class IRS(ARQ):
|
|||
frametype = bytes([FR_TYPE.ARQ_DC_OPEN_ACK_W.value])
|
||||
self.log.debug("[Modem] Responding with high bandwidth mode")
|
||||
|
||||
connection_frame = bytearray(self.length_sig0_frame)
|
||||
connection_frame[:1] = frametype
|
||||
connection_frame[1:2] = self.session_id
|
||||
connection_frame[8:9] = bytes([self.speed_level])
|
||||
connection_frame[13:14] = bytes([self.arq_protocol_version])
|
||||
|
||||
self.enqueue_frame_for_tx([connection_frame], c2_mode=FREEDV_MODE.sig0.value, copies=1, repeat_delay=0)
|
||||
connection_ack_frame = self.frame_factory.build_arq_connect_ack(
|
||||
session_id=self.session_id,
|
||||
speed_level=self.speed_level,
|
||||
arq_protocol_version=self.arq_protocol_version
|
||||
)
|
||||
|
||||
self.enqueue_frame_for_tx([connection_ack_frame], c2_mode=FREEDV_MODE.sig0.value, copies=1, repeat_delay=0)
|
||||
|
||||
self.event_manager.send_custom_event(
|
||||
freedata="modem-message",
|
||||
|
|
|
@ -626,83 +626,6 @@ class ISS(ARQ):
|
|||
)
|
||||
return False
|
||||
|
||||
def open_session(self) -> bool:
|
||||
"""
|
||||
Create and send the frame to request a connection.
|
||||
|
||||
Returns:
|
||||
True if the session was opened successfully
|
||||
False if the session open request failed
|
||||
"""
|
||||
self.IS_ARQ_SESSION_MASTER = True
|
||||
self.states.set("arq_session_state", "connecting")
|
||||
|
||||
# create a random session id
|
||||
self.session_id = np.random.bytes(1)
|
||||
|
||||
connection_frame = bytearray(self.length_sig0_frame)
|
||||
connection_frame[:1] = bytes([FR_TYPE.ARQ_SESSION_OPEN.value])
|
||||
connection_frame[1:2] = self.session_id
|
||||
connection_frame[2:5] = self.dxcallsign_crc
|
||||
connection_frame[5:8] = self.mycallsign_crc
|
||||
connection_frame[8:14] = helpers.callsign_to_bytes(self.mycallsign)
|
||||
|
||||
while not self.states.is_arq_session:
|
||||
threading.Event().wait(0.01)
|
||||
for attempt in range(self.session_connect_max_retries):
|
||||
self.log.info(
|
||||
"[Modem] SESSION ["
|
||||
+ str(self.mycallsign, "UTF-8")
|
||||
+ "]>>?<<["
|
||||
+ str(self.dxcallsign, "UTF-8")
|
||||
+ "]",
|
||||
a=f"{str(attempt + 1)}/{str(self.session_connect_max_retries)}",
|
||||
state=self.states.arq_session_state,
|
||||
)
|
||||
|
||||
self.event_manager.send_custom_event(
|
||||
freedata="modem-message",
|
||||
arq="session",
|
||||
status="connecting",
|
||||
attempt=attempt + 1,
|
||||
maxattempts=self.session_connect_max_retries,
|
||||
mycallsign=str(self.mycallsign, 'UTF-8'),
|
||||
dxcallsign=str(self.dxcallsign, 'UTF-8'),
|
||||
)
|
||||
|
||||
self.enqueue_frame_for_tx([connection_frame], c2_mode=FREEDV_MODE.sig0.value, copies=1, repeat_delay=0)
|
||||
|
||||
# Wait for a time, looking to see if `self.states.is_arq_session`
|
||||
# indicates we've received a positive response from the far station.
|
||||
timeout = time.time() + 3
|
||||
while time.time() < timeout:
|
||||
threading.Event().wait(0.01)
|
||||
# Stop waiting if data channel is opened
|
||||
if self.states.is_arq_session:
|
||||
return True
|
||||
|
||||
# Stop waiting and interrupt if data channel is getting closed while opening
|
||||
if self.states.arq_session_state == "disconnecting":
|
||||
# disabled this session close as its called twice
|
||||
# self.close_session()
|
||||
return False
|
||||
|
||||
# Session connect timeout, send close_session frame to
|
||||
# attempt to clean up the far-side, if it received the
|
||||
# open_session frame and can still hear us.
|
||||
if not self.states.is_arq_session:
|
||||
self.close_session()
|
||||
return False
|
||||
|
||||
# Given the while condition, it will only exit when `self.states.is_arq_session` is True
|
||||
self.event_manager.send_custom_event(
|
||||
freedata="modem-message",
|
||||
arq="session",
|
||||
status="connected",
|
||||
mycallsign=str(self.mycallsign, 'UTF-8'),
|
||||
dxcallsign=str(self.dxcallsign, 'UTF-8'),
|
||||
)
|
||||
return True
|
||||
|
||||
def open_dc_and_transmit(
|
||||
self,
|
||||
|
@ -838,13 +761,11 @@ class ISS(ARQ):
|
|||
frametype = bytes([FR_TYPE.ARQ_DC_OPEN_W.value])
|
||||
self.log.debug("[Modem] Requesting high bandwidth mode")
|
||||
|
||||
connection_frame = bytearray(self.length_sig0_frame)
|
||||
connection_frame[:1] = frametype
|
||||
connection_frame[1:4] = self.dxcallsign_crc
|
||||
connection_frame[4:7] = self.mycallsign_crc
|
||||
connection_frame[7:13] = helpers.callsign_to_bytes(mycallsign)
|
||||
connection_frame[13:14] = self.session_id
|
||||
|
||||
# build connection frame
|
||||
connection_frame = self.frame_factory.build_arq_connect(
|
||||
session_id=self.session_id,
|
||||
destination_crc=self.dxcallsign_crc,
|
||||
)
|
||||
for attempt in range(self.data_channel_max_retries):
|
||||
|
||||
self.event_manager.send_custom_event(
|
||||
|
|
|
@ -169,6 +169,82 @@ class SESSION(ARQ):
|
|||
MODEM_TRANSMIT_QUEUE.put(["morse", 1, 0, self.mycallsign])
|
||||
self.arq_cleanup()
|
||||
|
||||
def open_session(self) -> bool:
|
||||
"""
|
||||
Create and send the frame to request a connection.
|
||||
|
||||
Returns:
|
||||
True if the session was opened successfully
|
||||
False if the session open request failed
|
||||
"""
|
||||
self.IS_ARQ_SESSION_MASTER = True
|
||||
self.states.set("arq_session_state", "connecting")
|
||||
|
||||
# create a random session id
|
||||
self.session_id = np.random.bytes(1)
|
||||
|
||||
# build connection frame
|
||||
connection_frame = self.frame_factory.build_arq_session_connect(
|
||||
session_id=self.session_id,
|
||||
destination_crc=self.dxcallsign_crc,
|
||||
)
|
||||
while not self.states.is_arq_session:
|
||||
threading.Event().wait(0.01)
|
||||
for attempt in range(self.session_connect_max_retries):
|
||||
self.log.info(
|
||||
"[Modem] SESSION ["
|
||||
+ str(self.mycallsign, "UTF-8")
|
||||
+ "]>>?<<["
|
||||
+ str(self.dxcallsign, "UTF-8")
|
||||
+ "]",
|
||||
a=f"{str(attempt + 1)}/{str(self.session_connect_max_retries)}",
|
||||
state=self.states.arq_session_state,
|
||||
)
|
||||
|
||||
self.event_manager.send_custom_event(
|
||||
freedata="modem-message",
|
||||
arq="session",
|
||||
status="connecting",
|
||||
attempt=attempt + 1,
|
||||
maxattempts=self.session_connect_max_retries,
|
||||
mycallsign=str(self.mycallsign, 'UTF-8'),
|
||||
dxcallsign=str(self.dxcallsign, 'UTF-8'),
|
||||
)
|
||||
|
||||
self.enqueue_frame_for_tx([connection_frame], c2_mode=FREEDV_MODE.sig0.value, copies=1, repeat_delay=0)
|
||||
|
||||
# Wait for a time, looking to see if `self.states.is_arq_session`
|
||||
# indicates we've received a positive response from the far station.
|
||||
timeout = time.time() + 3
|
||||
while time.time() < timeout:
|
||||
threading.Event().wait(0.01)
|
||||
# Stop waiting if data channel is opened
|
||||
if self.states.is_arq_session:
|
||||
return True
|
||||
|
||||
# Stop waiting and interrupt if data channel is getting closed while opening
|
||||
if self.states.arq_session_state == "disconnecting":
|
||||
# disabled this session close as its called twice
|
||||
# self.close_session()
|
||||
return False
|
||||
|
||||
# Session connect timeout, send close_session frame to
|
||||
# attempt to clean up the far-side, if it received the
|
||||
# open_session frame and can still hear us.
|
||||
if not self.states.is_arq_session:
|
||||
self.close_session()
|
||||
return False
|
||||
|
||||
# Given the while condition, it will only exit when `self.states.is_arq_session` is True
|
||||
self.event_manager.send_custom_event(
|
||||
freedata="modem-message",
|
||||
arq="session",
|
||||
status="connected",
|
||||
mycallsign=str(self.mycallsign, 'UTF-8'),
|
||||
dxcallsign=str(self.dxcallsign, 'UTF-8'),
|
||||
)
|
||||
return True
|
||||
|
||||
def received_session_opener(self, data_in: bytes, snr) -> None:
|
||||
"""
|
||||
Received a session open request packet.
|
||||
|
|
Loading…
Reference in a new issue