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):
|
def _load_arq_templates(self):
|
||||||
|
|
||||||
# same structure for narrow and wide types
|
# same structure for narrow and wide types
|
||||||
arq_dc_open_ack = {
|
|
||||||
|
arq_dc_open = {
|
||||||
"frame_length": self.LENGTH_SIG0_FRAME,
|
"frame_length": self.LENGTH_SIG0_FRAME,
|
||||||
"destination_crc": 3,
|
"destination_crc": 3,
|
||||||
"origin_crc": 3,
|
"origin_crc": 3,
|
||||||
|
@ -109,9 +109,22 @@ class DataFrameFactory:
|
||||||
"session_id": 1,
|
"session_id": 1,
|
||||||
}
|
}
|
||||||
# arq connect frames
|
# 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_N.value] = arq_dc_open_ack
|
||||||
self.template_list[FR_TYPE.ARQ_DC_OPEN_ACK_W.value] = arq_dc_open_ack
|
self.template_list[FR_TYPE.ARQ_DC_OPEN_ACK_W.value] = arq_dc_open_ack
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# arq burst ack
|
# arq burst ack
|
||||||
self.template_list[FR_TYPE.BURST_ACK.value] = {
|
self.template_list[FR_TYPE.BURST_ACK.value] = {
|
||||||
"frame_length": self.LENGTH_SIG1_FRAME,
|
"frame_length": self.LENGTH_SIG1_FRAME,
|
||||||
|
@ -288,9 +301,36 @@ class DataFrameFactory:
|
||||||
"session_id": session_id.to_bytes(1, 'big'),
|
"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
|
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)
|
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):
|
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 = bytearray(self.length_sig1_frame)
|
||||||
# ack_frame[:1] = bytes([FR_TYPE.BURST_ACK.value])
|
# 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])
|
frametype = bytes([FR_TYPE.ARQ_DC_OPEN_ACK_W.value])
|
||||||
self.log.debug("[Modem] Responding with high bandwidth mode")
|
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(
|
self.event_manager.send_custom_event(
|
||||||
freedata="modem-message",
|
freedata="modem-message",
|
||||||
|
|
|
@ -626,83 +626,6 @@ class ISS(ARQ):
|
||||||
)
|
)
|
||||||
return False
|
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(
|
def open_dc_and_transmit(
|
||||||
self,
|
self,
|
||||||
|
@ -838,13 +761,11 @@ class ISS(ARQ):
|
||||||
frametype = bytes([FR_TYPE.ARQ_DC_OPEN_W.value])
|
frametype = bytes([FR_TYPE.ARQ_DC_OPEN_W.value])
|
||||||
self.log.debug("[Modem] Requesting high bandwidth mode")
|
self.log.debug("[Modem] Requesting high bandwidth mode")
|
||||||
|
|
||||||
connection_frame = bytearray(self.length_sig0_frame)
|
# build connection frame
|
||||||
connection_frame[:1] = frametype
|
connection_frame = self.frame_factory.build_arq_connect(
|
||||||
connection_frame[1:4] = self.dxcallsign_crc
|
session_id=self.session_id,
|
||||||
connection_frame[4:7] = self.mycallsign_crc
|
destination_crc=self.dxcallsign_crc,
|
||||||
connection_frame[7:13] = helpers.callsign_to_bytes(mycallsign)
|
)
|
||||||
connection_frame[13:14] = self.session_id
|
|
||||||
|
|
||||||
for attempt in range(self.data_channel_max_retries):
|
for attempt in range(self.data_channel_max_retries):
|
||||||
|
|
||||||
self.event_manager.send_custom_event(
|
self.event_manager.send_custom_event(
|
||||||
|
|
|
@ -169,6 +169,82 @@ class SESSION(ARQ):
|
||||||
MODEM_TRANSMIT_QUEUE.put(["morse", 1, 0, self.mycallsign])
|
MODEM_TRANSMIT_QUEUE.put(["morse", 1, 0, self.mycallsign])
|
||||||
self.arq_cleanup()
|
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:
|
def received_session_opener(self, data_in: bytes, snr) -> None:
|
||||||
"""
|
"""
|
||||||
Received a session open request packet.
|
Received a session open request packet.
|
||||||
|
|
Loading…
Reference in a new issue