improved state and timing

This commit is contained in:
DJ2LS 2021-02-09 14:27:36 +01:00 committed by GitHub
parent 0a8ea24112
commit 91114d0db2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 133 additions and 94 deletions

182
arq.py
View file

@ -22,11 +22,11 @@ modem = modem.RF()
static.ARQ_PAYLOAD_PER_FRAME = static.FREEDV_DATA_PAYLOAD_PER_FRAME - 3 #6?!
static.ARQ_ACK_PAYLOAD_PER_FRAME = 14 - 2#
def arq_ack_timeout():
static.ARQ_ACK_TIMEOUT = 1
#def arq_ack_timeout():
# static.ARQ_ACK_TIMEOUT = 1
def arq_rpt_timeout():
static.ARQ_RPT_TIMEOUT = True
#def arq_rpt_timeout():
# static.ARQ_RPT_TIMEOUT = True
def data_received(data_in):
@ -75,7 +75,9 @@ def data_received(data_in):
for i in range(0,static.ARQ_N_ARQ_FRAMES_PER_DATA_FRAME+1):
static.ARQ_RX_FRAME_BUFFER.insert(i,None)
static.ARQ_RX_FRAME_BUFFER[static.ARQ_RX_N_CURRENT_ARQ_FRAME] = bytes(data_in)
static.ARQ_RX_FRAME_BUFFER[static.ARQ_RX_N_CURRENT_ARQ_FRAME] = bytes(data_in)
static.ARQ_FRAME_BOF_RECEIVED = False
static.ARQ_FRAME_EOF_RECEIVED = False
try:
@ -95,7 +97,6 @@ def data_received(data_in):
# - ------------------------- ARQ BURST CHECKER
# run only if we recieved all ARQ FRAMES per ARQ BURST
#if static.ARQ_N_FRAME == static.ARQ_N_RX_FRAMES_PER_BURSTS and static.ARQ_RX_BURST_BUFFER.count(None) == 1: #if received bursts are equal to burst number in frame
if static.ARQ_RX_BURST_BUFFER.count(None) == 1: #count nones
logging.info("ARQ | TX | BURST ACK")
@ -115,11 +116,11 @@ def data_received(data_in):
# --------------- CHECK WHICH BURST FRAMES WE ARE MISSING -------------------------------------------
missing_frames = b''
for burst in range(1,len(static.ARQ_RX_BURST_BUFFER)):
for burstnumber in range(1,len(static.ARQ_RX_BURST_BUFFER)):
if static.ARQ_RX_BURST_BUFFER[burst] == None:
burst = burst.to_bytes(2, byteorder='big')
missing_frames += burst
if static.ARQ_RX_BURST_BUFFER[burstnumber] == None:
frame_number = burstnumber.to_bytes(2, byteorder='big')
missing_frames += frame_number
logging.info("ARQ | TX | RPT ARQ FRAMES [" + str(missing_frames) + "]")
@ -179,8 +180,9 @@ def data_received(data_in):
ack_frame = b'='+ bytes(static.FRAME_CRC) # < = 61
#TRANSMIT ACK FRAME FOR BURST-----------------------------------------------
time.sleep(0.5) #0.5
logging.info("ARQ | TX | ARQ DATA FRAME ACK [" + str(static.FRAME_CRC.hex()) +"]")
time.sleep(0.5)
modem.transmit_arq_ack(ack_frame)
# clearing buffers and resetting counters
@ -196,43 +198,10 @@ def data_received(data_in):
else:
logging.info("ARQ | RX | DATA FRAME NOT SUCESSFULLY RECEIVED!")
def burst_ack_received():
logging.info("ARQ | RX | BURST ACK RCVD!")
static.ARQ_ACK_TIMEOUT = 1 #Force timer to stop waiting
static.ARQ_ACK_RECEIVED = 1 #Force data loops of TNC to stop and continue with next frame
static.ARQ_RPT_TIMEOUT = True #Force timer to stop waiting
static.ARQ_RPT_RECEIVED = False
static.ARQ_RPT_FRAMES = []
def burst_rpt_received(data_in):
logging.info("ARQ | RX | BURST RPT RCVD!")
static.ARQ_ACK_TIMEOUT = 0 #Force timer to stop waiting
static.ARQ_ACK_RECEIVED = 0 #Force data loops of TNC to stop and continue with next frame
static.ARQ_RPT_RECEIVED = True
static.ARQ_RPT_FRAMES = []
missing_area = bytes(data_in[1:9])
for i in range(0,6,2):
if not missing_area[i:i+2].endswith(b'\x00\x00'):
missing = missing_area[i:i+2]
static.ARQ_RPT_FRAMES.insert(0,missing)
def frame_ack_received():
logging.info("ARQ | RX | FRAME ACK RCVD!")
static.ARQ_ACK_TIMEOUT = 1 #Force timer to stop waiting
static.ARQ_FRAME_ACK_RECEIVED = 1 #Force data loops of TNC to stop and continue with next frame
static.RPT_ACK_RECEIVED = False
static.ARQ_RPT_TIMEOUT = True
def transmit(data_out):
@ -282,7 +251,7 @@ def transmit(data_out):
#--------------------------------------------- N ATTEMPTS TO SEND BURSTS IF ACK RECEPTION FAILS
for static.TX_N_RETRIES in range(static.TX_N_MAX_RETRIES):
if static.ARQ_N_SENT_FRAMES+1 <= static.TX_BUFFER_SIZE:
if static.ARQ_N_SENT_FRAMES + 1 <= static.TX_BUFFER_SIZE:
logging.info("ARQ | TX | F:[" + str(static.ARQ_N_SENT_FRAMES+1) + "-" + str(static.ARQ_N_SENT_FRAMES + static.ARQ_TX_N_FRAMES_PER_BURST) + "] | T:[" + str(static.ARQ_N_SENT_FRAMES) + "/" + str(static.TX_BUFFER_SIZE) + "] [" + str(int(static.ARQ_N_SENT_FRAMES/(static.TX_BUFFER_SIZE)*100)).zfill(3) + "%] | A:[" + str(static.TX_N_RETRIES+1) + "/" + str(static.TX_N_MAX_RETRIES) + "]")
@ -292,84 +261,93 @@ def transmit(data_out):
# lets wait during sending. After sending is finished we will continue
while static.ARQ_STATE == 'SENDING_DATA':
time.sleep(0.05)
print("sending.....")
time.sleep(0.01)
#print("sending.....")
# --------------------------- START TIMER FOR WAITING FOR ACK ---> IF TIMEOUT REACHED, ACK_TIMEOUT = 1
#reset timer and ack state
static.ARQ_FRAME_ACK_RECEIVED = 0
static.ARQ_ACK_RECEIVED = 0
static.ARQ_ACK_TIMEOUT = 0
static.ARQ_FRAME_ACK_RECEIVED = False
static.ARQ_ACK_RECEIVED = False
static.ARQ_RX_ACK_TIMEOUT = False
logging.debug("ARQ | RX | WAITING FOR BURST ACK")
static.ARQ_STATE = 'RECEIVING_ACK'
logging.info("ARQ | RX | WAITING FOR BURST ACK")
static.ARQ_STATE = 'RECEIVING_SIGNALLING'
timer = threading.Timer(static.ARQ_ACK_TIMEOUT_SECONDS, arq_ack_timeout)
timer = threading.Timer(static.ARQ_RX_ACK_TIMEOUT_SECONDS, helpers.arq_ack_timeout)
timer.start()
# --------------------------- WHILE TIMEOUT NOT REACHED AND NO ACK RECEIVED --> LISTEN
while (static.ARQ_ACK_RECEIVED == 0 or static.ARQ_RPT_RECEIVED == False or static.ARQ_FRAME_ACK_RECEIVED == 0) and static.ARQ_TIMEOUT_RECEIVED == 0:
while (static.ARQ_ACK_RECEIVED == False or static.ARQ_RPT_RECEIVED == False or static.ARQ_FRAME_ACK_RECEIVED == False) and static.ARQ_RX_ACK_TIMEOUT == False:
time.sleep(0.01) # lets reduce CPU load a little bit
#print(static.ARQ_STATE)
#--------------------------------------------------------------------------------------------------------------
if static.ARQ_RPT_RECEIVED == True:
logging.info("ARQ | RX | REQUEST FOR REPEATING FRAMES: " + str(static.ARQ_RPT_FRAMES))
logging.info("ARQ | TX | SENDING REQUESTED FRAMES: " + str(static.ARQ_RPT_FRAMES))
TRANSMIT_ARQ_BURST_THREAD = threading.Thread(target=modem.transmit_arq_burst, name="TRANSMIT_ARQ_BURST")
TRANSMIT_ARQ_BURST_THREAD.start()
# lets wait during sending. After sending is finished we will continue
while static.ARQ_STATE == 'SENDING_DATA':
time.sleep(0.05)
time.sleep(0.01)
static.ARQ_FRAME_ACK_RECEIVED = 0
static.ARQ_ACK_RECEIVED = 0
static.ARQ_ACK_TIMEOUT = 0
static.ARQ_RPT_TIMEOUT = False
static.ARQ_FRAME_ACK_RECEIVED = False
static.ARQ_ACK_RECEIVED = False
static.ARQ_RX_ACK_TIMEOUT = False
static.ARQ_RX_RPT_TIMEOUT = False
static.ARQ_STATE = 'RECEIVING_ACK'
static.ARQ_STATE = 'RECEIVING_SIGNALLING'
timer = threading.Timer(static.ARQ_RPT_TIMEOUT_SECONDS, arq_rpt_timeout)
timer = threading.Timer(static.ARQ_RX_RPT_TIMEOUT_SECONDS, helpers.arq_rpt_timeout)
timer.start()
while static.ARQ_ACK_RECEIVED == 0 and static.ARQ_RPT_TIMEOUT == False:
while static.ARQ_ACK_RECEIVED == False and static.ARQ_FRAME_ACK_RECEIVED == False and static.ARQ_RX_RPT_TIMEOUT == False:
time.sleep(0.01) # lets reduce CPU load a little bit
if static.ARQ_ACK_RECEIVED == 1:
if static.ARQ_ACK_RECEIVED == True:
print("ACK WHILE RPT")
logging.info("ARQ | RX | ACK RECEIVED AFTER FRAME REPEAT")
static.ARQ_ACK_TIMEOUT = 1
static.ARQ_RPT_TIMEOUT = True
#break
static.ARQ_RX_ACK_TIMEOUT = True
static.ARQ_RX_RPT_TIMEOUT = True
static.ARQ_RPT_FRAMES = []
if static.ARQ_RX_RPT_TIMEOUT == True and static.ARQ_ACK_RECEIVED == False:
print("Burst lost....")
static.ARQ_RPT_RECEIVED = False
static.ARQ_RPT_FRAMES = []
#--------------------------------------------------------------------------------------------------------------
#if static.ARQ_ACK_RECEIVED == 0 and static.ARQ_ACK_TIMEOUT == 1:
#if static.ARQ_ACK_RECEIVED == 0 and static.ARQ_RX_ACK_TIMEOUT == 1:
# #logging.info("ARQ | RX | ACK TIMEOUT | SENDING ARQ BURST AGAIN")
# pass
#--------------- BREAK LOOP IF ACK HAS BEEN RECEIVED
if static.ARQ_ACK_RECEIVED == 1:
if static.ARQ_ACK_RECEIVED == True:
logging.info("ARQ | RX | ACK RECEIVED")
#-----------IF ACK RECEIVED, INCREMENT ITERATOR FOR MAIN LOOP TO PROCEED WITH NEXT FRAMES/BURST
static.ARQ_N_SENT_FRAMES = static.ARQ_N_SENT_FRAMES + static.ARQ_TX_N_FRAMES_PER_BURST
break
#--------------- BREAK LOOP IF FRAME ACK HAS BEEN RECEIVED EARLIER AS EXPECTED
if static.ARQ_FRAME_ACK_RECEIVED == 1:
if static.ARQ_FRAME_ACK_RECEIVED == True:
logging.info("ARQ | RX | EARLY FRAME ACK RECEIVED - STOPPING TX")
#static.ARQ_N_SENT_FRAMES = #static.TX_BUFFER_SIZE
static.ARQ_N_SENT_FRAMES = static.ARQ_N_SENT_FRAMES + static.ARQ_TX_N_FRAMES_PER_BURST
break
# ----------- if no ACK received and out of retries.....stop frame sending
if static.ARQ_ACK_RECEIVED == 0 and static.ARQ_FRAME_ACK_RECEIVED == 0 and static.ARQ_ACK_TIMEOUT == 1:
if static.ARQ_ACK_RECEIVED == False and static.ARQ_FRAME_ACK_RECEIVED == False and static.ARQ_RX_ACK_TIMEOUT == True:
logging.info("ARQ | TX | NO BURST OR FRAME ACK RECEIVED | DATA SHOULD BE RESEND!")
break
#-------------------------BREAK TX BUFFER LOOP IF ALL PACKETS HAVE BEEN SENT AND WE GOT A FRAME ACK
if static.ARQ_N_SENT_FRAMES == static.TX_BUFFER_SIZE and static.ARQ_FRAME_ACK_RECEIVED == 1:
if static.ARQ_N_SENT_FRAMES == static.TX_BUFFER_SIZE and static.ARQ_FRAME_ACK_RECEIVED == True:
logging.info("ARQ | RX | REGULAR FRAME ACK RECEIVED - DATA TRANSMITTED!")
break
@ -379,9 +357,16 @@ def transmit(data_out):
logging.info("ARQ | TX | BUFFER EMPTY")
# - RESET COUNTERS
static.ARQ_N_SENT_FRAMES = 0
static.ARQ_TX_N_FRAMES_PER_BURST = 0
static.ARQ_ACK_RECEIVED = 0
static.ARQ_FRAME_ACK_RECEIVED = 0
static.ARQ_TX_N_FRAMES_PER_BURST = False
static.ARQ_ACK_RECEIVED = False
static.ARQ_FRAME_ACK_RECEIVED = False
# BURST MACHINE TO DEFINE N BURSTS PER FRAME ---> LATER WE CAN USE CHANNEL MESSUREMENT TO SET FRAMES PER BURST
def get_n_frames_per_burst():
@ -389,3 +374,44 @@ def get_n_frames_per_burst():
#n_frames_per_burst = randrange(1,10)
n_frames_per_burst = 4
return n_frames_per_burst
def burst_ack_received():
#logging.info("ARQ | RX | BURST ACK RCVD!")
static.ARQ_RX_ACK_TIMEOUT = True #Force timer to stop waiting
static.ARQ_ACK_RECEIVED = True #Force data loops of TNC to stop and continue with next frame
static.ARQ_RX_RPT_TIMEOUT = True #Force timer to stop waiting
static.ARQ_RPT_RECEIVED = False
static.ARQ_RPT_FRAMES = []
def frame_ack_received():
#logging.info("ARQ | RX | FRAME ACK RCVD!")
static.ARQ_RX_ACK_TIMEOUT = True #Force timer to stop waiting
static.ARQ_FRAME_ACK_RECEIVED = True #Force data loops of TNC to stop and continue with next frame
static.ARQ_RX_RPT_TIMEOUT = True #Force timer to stop waiting
static.ARQ_RPT_RECEIVED = False
static.ARQ_RPT_FRAMES = []
def burst_rpt_received(data_in):
#logging.info("ARQ | RX | BURST RPT RCVD!")
static.ARQ_RX_ACK_TIMEOUT = False #Force timer to stop waiting
static.ARQ_ACK_RECEIVED = False #Force data loops of TNC to stop and continue with next frame
static.ARQ_RPT_RECEIVED = True
static.ARQ_RPT_FRAMES = []
missing_area = bytes(data_in[1:9])
for i in range(0,6,2):
if not missing_area[i:i+2].endswith(b'\x00\x00'):
missing = missing_area[i:i+2]
static.ARQ_RPT_FRAMES.insert(0,missing)

View file

@ -26,4 +26,14 @@ def get_crc_16(data):
crc_algorithm = crcengine.new('crc16-ccitt-false') #load crc16 library
crc_data = crc_algorithm(data)
crc_data = crc_data.to_bytes(2, byteorder='big')
return crc_data
return crc_data
def arq_ack_timeout():
static.ARQ_RX_ACK_TIMEOUT = True
#print("ARQ_RX_ACK_TIMEOUT")
def arq_rpt_timeout():
static.ARQ_RX_RPT_TIMEOUT = True
#print("ARQ_RX_RPT_TIMEOUT")

View file

@ -156,10 +156,11 @@ class RF():
txbuffer = txbuffer.rstrip(b'\x00') #lets remove unallocated memory because of wrong buffer :-/
elif static.ARQ_RPT_RECEIVED == True:
for n in range(0,len(static.ARQ_RPT_FRAMES)):
missing_frame = int.from_bytes(static.ARQ_RPT_FRAMES[n], "big")
print("MISSING ARQ FRAME: " + str(missing_frame))
#---------------------------BUILD ARQ BURST ---------------------------------------------------------------------
frame_type = 10 + missing_frame #static.ARQ_TX_N_FRAMES_PER_BURST
frame_type = bytes([frame_type])
@ -196,7 +197,8 @@ class RF():
# -------------- transmit audio
self.stream_tx.write(bytes(txbuffer))
static.ARQ_STATE = 'RECEIVING_ACK'
static.ARQ_STATE = 'IDLE'
#static.ARQ_STATE = 'RECEIVING_SIGNALLING'
#--------------------------------------------------------------------------------------------------------
def receive(self,data_mode,signalling_mode):
@ -281,7 +283,8 @@ class RF():
if 50 >= frametype >= 10:
if frame != 3 or force == True:
arq.data_received(bytes(data_bytes_out[:-2])) #send payload data to arq checker without CRC16
arq.data_received(bytes(data_bytes_out[:-2])) #send payload data to arq checker without CRC16
#print("static.ARQ_RX_BURST_BUFFER.count(None) " + str(static.ARQ_RX_BURST_BUFFER.count(None)))
if static.ARQ_RX_BURST_BUFFER.count(None) <= 1:
print("FULL BURST BUFFER ---> UNSYNC")
@ -301,7 +304,7 @@ class RF():
while static.ARQ_STATE == 'IDLE' or static.ARQ_STATE == 'RECEIVING_ACK':
while static.ARQ_STATE == 'IDLE' or static.ARQ_STATE == 'RECEIVING_SIGNALLING':
time.sleep(0.01)
nin = self.c_lib.freedv_nin(freedv_signalling)
@ -318,7 +321,6 @@ class RF():
if nbytes == static.FREEDV_SIGNALLING_BYTES_PER_FRAME:
self.c_lib.freedv_set_sync(freedv_signalling, 0)
frametype = int.from_bytes(bytes(signalling_bytes_out[:1]), "big")
print("SIGNALLING RECEIVED")
# BURST ACK
if frametype == 60:
@ -334,8 +336,8 @@ class RF():
rxstatus = self.c_lib.freedv_get_rx_status(freedv_signalling)
print("ACK")
print(rxstatus)
#print("ACK")
#print(rxstatus)
#if nbytes == static.FREEDV_SIGNALLING_BYTES_PER_FRAME:# or rxstatus == 10:
# self.c_lib.freedv_set_sync(freedv_signalling, 0) #FORCE UNSYNC

View file

@ -82,15 +82,16 @@ ARQ_N_RX_ARQ_FRAMES = 0 # total number of received frames
ARQ_N_RX_FRAMES_PER_BURSTS = 0 # NUMBER OF FRAMES WE ARE WAITING FOR --> GOT DATA FROM RECEIVED FRAME
ARQ_ACK_PAYLOAD_PER_FRAME = 0 # PAYLOAD per ACK frame
ARQ_ACK_RECEIVED = 0 # set to 1 if ACK received
ARQ_FRAME_ACK_RECEIVED = 0 # set to 1 if FRAME ACK received
ARQ_ACK_TIMEOUT = 0 # set to 1 if timeut reached
ARQ_ACK_TIMEOUT_SECONDS = 6.0 #timeout for waiting for ACK frames
ARQ_RPT_TIMEOUT = False
ARQ_RPT_TIMEOUT_SECONDS = 6.0
ARQ_ACK_RECEIVED = False # set to 1 if ACK received
ARQ_FRAME_ACK_RECEIVED = False # set to 1 if FRAME ACK received
ARQ_RX_ACK_TIMEOUT = False # set to 1 if timeut reached
ARQ_RX_ACK_TIMEOUT_SECONDS = 6.0 #timeout for waiting for ACK frames
ARQ_RX_RPT_TIMEOUT = False
ARQ_RX_RPT_TIMEOUT_SECONDS = 6.0
ARQ_RPT_RECEIVED = False #indicate if RPT frame has been received
ARQ_RPT_FRAMES = []
ARQ_RPT_FRAMES = [] #buffer for frames which are requested to repeat
FRAME_CRC = b''
FRAME_BOF = b'\xAA\xAA' #here we define 2 bytes for the BOF
@ -105,7 +106,7 @@ ARQ_N_SENT_FRAMES = 0 #counter for already sent frames
# IDLE
# RECEIVING_DATA
# SENDING_DATA
# RECEIVING_ACK
# RECEIVING_SIGNALLING
# SENDING_ACK
# ACK_RECEIVED
#