diff --git a/arq.py b/arq.py index 01a3ba22..c67bf888 100644 --- a/arq.py +++ b/arq.py @@ -27,17 +27,17 @@ def arq_ack_timeout(): def data_received(data_in): - ARQ_N_RX_BURSTS = int.from_bytes(bytes(data_in[:1]), "big") - 10 #get number of bursts from received frame + static.ARQ_N_RX_FRAMES_PER_BURSTS = int.from_bytes(bytes(data_in[:1]), "big") - 10 #get number of bursts from received frame static.ARQ_RX_BURST_BUFFER.append(data_in) #append data to RX BUFFER - print("WAITING FOR BURSTS: " + str(ARQ_N_RX_BURSTS)) + print("WAITING FOR FRAMS_PER_BURST: " + str(static.ARQ_N_RX_FRAMES_PER_BURSTS)) print("ARQ_RX_BURST_BUFFER: " + str(len(static.ARQ_RX_BURST_BUFFER))) burst_total_payload = bytearray() #while static.ACK_RX_TIMEOUT == 0: #define timeout where data has to be received untl error occurs - if len(static.ARQ_RX_BURST_BUFFER) == ARQ_N_RX_BURSTS: #if received bursts are equal to burst number in frame + if len(static.ARQ_RX_BURST_BUFFER) == static.ARQ_N_RX_FRAMES_PER_BURSTS: #if received bursts are equal to burst number in frame for n_raw_frame in range(0,len(static.ARQ_RX_BURST_BUFFER)): @@ -71,8 +71,9 @@ def data_received(data_in): #TRANSMIT ACK FRAME ----------------------------------------------- logging.info("TX | SENDING ARQ BURST ACK [" + str(data_in[1:3]) +"]") + time.sleep(4.5) modem.transmit_arq_ack(ack_buffer) - print(ack_buffer) + #print(ack_buffer) # ------------------------------------------------------------ frametype = int.from_bytes(bytes(ack_buffer[:1]), "big") @@ -83,9 +84,8 @@ def data_received(data_in): static.ARQ_RX_BURST_BUFFER = [] # CLEAR RX BURST BUFFER else: #IF burst payload crc and input crc are NOT equal - print("CRC NOT EQUAL!!!!!") - print(data_in[1:3]) - static.ARQ_RX_BURST_BUFFER = [] + print("CRC NOT EQUAL!!!!![" + str(data_in[1:3]) + "]") + static.ARQ_RX_BURST_BUFFER = [] #erase ARQ RX Burst buffer # LOOP THOUGH FRAME BUFFER AND STICK EVERYTHING TOGETHER @@ -94,12 +94,12 @@ def data_received(data_in): print(static.ARQ_RX_FRAME_BUFFER) for frame in range(len(static.ARQ_RX_FRAME_BUFFER)): complete_frame = complete_frame + static.ARQ_RX_FRAME_BUFFER[frame] - print(complete_frame) - print(complete_frame[4:6]) + #print(complete_frame) + #print(complete_frame[4:6]) # -------- DETECT IF WE ALREADY RECEIVED A FRAME HEADER THEN SAVE DATA TO GLOBALS #if burst_total_payload[4:6].startswith(b'\xAA\xAA'): - if complete_frame[4:6].startswith(b'\xAA\xAA') or burst_total_payload[4:6].startswith(b'\xAA\xAA'): + if complete_frame[4:6].startswith(static.FRAME_BOF) or burst_total_payload[4:6].startswith(static.FRAME_BOF): print("FRAME HEADER RECEIVED!") #print("FRAME BURSTS = " + str(complete_frame[:2])) #print("FRAME CRC = " + str(complete_frame[2:4])) @@ -107,10 +107,10 @@ def data_received(data_in): static.ARQ_RX_FRAME_N_BURSTS = int.from_bytes(bytes(complete_frame[:2]), "big") # -------- DETECT IF WE HAVE ALREADY RECEIVED THE LAST FRAME - if burst_total_payload.rstrip(b'\x00').endswith(b'\xFF\xFF'): - print("DAS IST DER LETZTE BURST MIT EOF!!!") + if burst_total_payload.rstrip(b'\x00').endswith(static.FRAME_EOF): + print("EOF RECEIVED") - print("WEITER GEHTS...") + print("LET'S CONTINUE...") # NOW WE TRY TO SEPARATE THE FRAME CRC FOR A CRC CALCULATION frame_payload = complete_frame.rstrip(b'\x00') #REMOVE x00 frame_payload = frame_payload[6:-2] #THIS IS THE FRAME PAYLOAD @@ -134,8 +134,8 @@ def data_received(data_in): def ack_received(): logging.info("RX | ACK RCVD!") - static.ACK_TIMEOUT = 1 #Force timer to stop waiting - static.ACK_RECEIVED = 1 #Force data loops of TNC to stop and continue with next frame + 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_ACK_WAITING_FOR_ID def transmit(data_out): @@ -220,6 +220,7 @@ def transmit(data_out): # lets sleep a while during sending. After this we will continue while static.ARQ_STATE == 'SENDING_DATA': time.sleep(0.05) + #print("WAIT WHILE SENDIN") # --------------------------- START TIMER FOR WAITING FOR ACK ---> IF TIMEOUT REACHED, ACK_TIMEOUT = 1 logging.info("TX | WAITING FOR ACK") @@ -256,7 +257,11 @@ def transmit(data_out): # IF TX BUFFER IS EMPTY / ALL FRAMES HAVE BEEN SENT --> HERE WE COULD ADD AN static.VAR for IDLE STATE logging.info("TX | BUFFER EMPTY") - + print(static.ARQ_N_SENT_FRAMES) + print(static.ARQ_TX_N_FRAMES_PER_BURST) + # - RESET COUNTERS + static.ARQ_N_SENT_FRAMES = 0 + static.ARQ_TX_N_FRAMES_PER_BURST = 0 # 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(): diff --git a/modem.py b/modem.py index be116cc4..8352d2c8 100644 --- a/modem.py +++ b/modem.py @@ -105,6 +105,7 @@ class RF(): txbuffer = bytearray() txbuffer += bytes(mod_out_preamble) txbuffer += bytes(mod_out) + #txbuffer = txbuffer.rstrip(b'\x00') # -------------- audio sample rate conversion audio = audioop.ratecv(txbuffer,2,1,static.MODEM_SAMPLE_RATE, static.AUDIO_SAMPLE_RATE_TX, static.TX_SAMPLE_STATE) @@ -114,6 +115,9 @@ class RF(): #-------------------------------------------------------------------------------------------------------- def transmit_arq_ack(self,ack_buffer): + + static.ARQ_STATE = 'SENDING_ACK' + self.c_lib.freedv_open.restype = ctypes.POINTER(ctypes.c_ubyte) freedv = self.c_lib.freedv_open(static.FREEDV_SIGNALLING_MODE) bytes_per_frame = int(self.c_lib.freedv_get_bits_per_modem_frame(freedv)/8) @@ -141,23 +145,26 @@ class RF(): # WE NEED TO ADJUST IT FOR SINGLE TRANSMISSION if static.FREEDV_SIGNALLING_MODE == 7: modulation = bytes(mod_out) - txbuffer = modulation[:len(modulation)] + modulation # double transmission in one audio burst + txbuffer = modulation[:len(modulation)] + modulation # pseudo preamble and double transmission in one audio burst else: txbuffer = bytearray() #txbuffer += bytes(mod_out_preamble) txbuffer += bytes(mod_out) - + #txbuffer = txbuffer.rstrip(b'\x00') # -------------- audio sample rate conversion audio = audioop.ratecv(txbuffer,2,1,static.MODEM_SAMPLE_RATE, static.AUDIO_SAMPLE_RATE_TX, static.TX_SAMPLE_STATE) - # -------------- transmit audio + # -------------- transmit audio twice + self.stream_tx.write(audio[0]) self.stream_tx.write(audio[0]) - + + static.ARQ_STATE = 'RECEIVING_DATA' #-------------------------------------------------------------------------------------------------------- # GET ARQ BURST FRAME VOM BUFFER AND MODULATE IT def transmit_arq_burst(self): - static.ARQ_STATE = 'SENDING_ACK' + static.ARQ_STATE = 'SENDING_DATA' + self.c_lib.freedv_open.restype = ctypes.POINTER(ctypes.c_ubyte) freedv = self.c_lib.freedv_open(static.FREEDV_DATA_MODE) @@ -177,13 +184,17 @@ class RF(): self.c_lib.freedv_rawdatapreambletx(freedv, mod_out_preamble); txbuffer = bytearray() txbuffer += bytes(mod_out_preamble) - + + time_start = time.time() for n in range(0,static.ARQ_TX_N_FRAMES_PER_BURST): #---------------------------BUILD ARQ BURST --------------------------------------------------------------------- frame_type = 10 + static.ARQ_TX_N_FRAMES_PER_BURST frame_type = bytes([frame_type]) - + print(frame_type) + print("static.ARQ_N_SENT_FRAMES: " + str(static.ARQ_N_SENT_FRAMES)) + print("static.ARQ_TX_N_FRAMES_PER_BURST: " + str(static.ARQ_TX_N_FRAMES_PER_BURST)) + payload_data = bytes(static.TX_BUFFER[static.ARQ_N_SENT_FRAMES + n]) arqframe = frame_type + static.ARQ_BURST_PAYLOAD_CRC + payload_data @@ -202,14 +213,24 @@ class RF(): data = (ctypes.c_ubyte * static.FREEDV_DATA_BYTES_PER_FRAME).from_buffer_copy(buffer) self.c_lib.freedv_rawdatatx(freedv,mod_out,data) # modulate DATA and safe it into mod_out pointer txbuffer += bytes(mod_out) - - # -------------- audio sample rate conversion - audio = audioop.ratecv(txbuffer,2,1,static.MODEM_SAMPLE_RATE, static.AUDIO_SAMPLE_RATE_TX, static.TX_SAMPLE_STATE) - # -------------- transmit audio + #print(len(txbuffer)) + #txbuffer = txbuffer.strip(b'\x00\x00') + #print(len(txbuffer)) + # -------------- audio sample rate conversion + print("MODULATION TIME: " + str(time.time() - time_start)) + time_start = time.time() + audio = audioop.ratecv(txbuffer,2,1,static.MODEM_SAMPLE_RATE, static.AUDIO_SAMPLE_RATE_TX, static.TX_SAMPLE_STATE) + # -------------- transmit audio + time_start = time.time() self.stream_tx.write(audio[0]) - static.ARQ_STATE = 'IDLE' + print("AUDIO TIME: " + str(time.time() - time_start)) + + + + static.ARQ_STATE = 'RECEIVING_ACK' + #-------------------------------------------------------------------------------------------------------- def receive(self,data_mode,signalling_mode): @@ -245,26 +266,48 @@ class RF(): data_in = self.stream_rx.read(nin, exception_on_overflow = False) data_in = audioop.ratecv(data_in,2,1,static.AUDIO_SAMPLE_RATE_RX, static.MODEM_SAMPLE_RATE, None) data_in = data_in[0].rstrip(b'\x00') - + + #print(data_in) + self.c_lib.freedv_rawdatarx.argtype = [ctypes.POINTER(ctypes.c_ubyte), data_bytes_out, data_in] # check if really neccessary nbytes = self.c_lib.freedv_rawdatarx(freedv_data, data_bytes_out, data_in) # demodulate audio + print(self.c_lib.freedv_get_rx_status(freedv_data)) + + modem_stats_snr = c_float() + modem_stats_sync = c_int() + + #self.c_lib.freedv_get_modem_stats(freedv_data,byref(modem_stats_sync), byref(modem_stats_snr)) + #modem_stats_snr = modem_stats_snr.value + #print(modem_stats_snr) + + if nbytes == static.FREEDV_DATA_BYTES_PER_FRAME: - - + # CHECK IF FRAMETYPE IS BETWEEN 10 and 50 ------------------------ frametype = int.from_bytes(bytes(data_bytes_out[:1]), "big") if 50 >= frametype >= 10 and len(data_bytes_out) > 30: # --> The length check filters out random strings without CRC print("MODE: " + str(data_mode) + " DATA: " + str(bytes(data_bytes_out[:-2]))) arq.data_received(bytes(data_bytes_out[:-2])) #send payload data to arq checker without CRC16 - self.c_lib.freedv_set_sync(freedv_data, 0) #FORCE UNSYNC + + + #self.c_lib.freedv_set_sync(freedv_data, 0) #FORCE UNSYNC else: print("MODE: " + str(data_mode) + " DATA: " + str(bytes(data_bytes_out))) + + + # NEEDS TO BE OPTIMIZED + # DO UNSYNC IF LAST FRAME PER BURST SENT + if len(static.ARQ_RX_BURST_BUFFER) == static.ARQ_N_RX_FRAMES_PER_BURSTS and len(static.ARQ_RX_BURST_BUFFER) != 0: + print("DOING UNSYNC") + self.c_lib.freedv_set_sync(freedv_data, 0) #FORCE UNSYNC + + while static.ARQ_STATE == 'IDLE' or static.ARQ_STATE == 'RECEIVING_ACK': time.sleep(0.01) - + nin = self.c_lib.freedv_nin(freedv_signalling) nin = int(nin*(static.AUDIO_SAMPLE_RATE_RX/static.MODEM_SAMPLE_RATE)) @@ -279,16 +322,17 @@ class RF(): # CHECK IF FRAME CONTAINS ACK------------------------ --> 700D / 7 frametype = int.from_bytes(bytes(signalling_bytes_out[:1]), "big") - if frametype == 60 and len(signalling_bytes_out) == 14: - print("ACK FRAME RECEIVED!!!!!!!!!!") + if frametype == 60 and len(signalling_bytes_out) == static.FREEDV_SIGNALLING_BYTES_PER_FRAME: + arq.ack_received() + # print("ACK FRAME RECEIVED!!!!!!!!!!") #if bytes(bytes_out[:1]) == b'<': #b'\7': < = 60 # CHECK CRC 8 OF ACK FRAME - print(signalling_bytes_out[:1]) - print(signalling_bytes_out[3:14]) + # print(signalling_bytes_out[:1]) + # print(signalling_bytes_out[3:14]) - if bytes(signalling_bytes_out[:2]) == helpers.get_crc_8(bytes(signalling_bytes_out[3:14])): - print("MODE: " + str(signalling_mode) + " DATA: " + str(bytes(signalling_bytes_out))) - arq.ack_received() + # if bytes(signalling_bytes_out[:2]) == helpers.get_crc_8(bytes(signalling_bytes_out[3:14])): + # print("MODE: " + str(signalling_mode) + " DATA: " + str(bytes(signalling_bytes_out))) + # arq.ack_received() diff --git a/static.py b/static.py index 9f8a76f6..c369179b 100644 --- a/static.py +++ b/static.py @@ -5,7 +5,12 @@ Created on Wed Dec 23 11:13:57 2020 @author: DJ2LS """ +# ADDITION MESSUREMENT: +#AUDIO TIME: 7.451462268829346 #12 # 1 FRAME + PREAMBLE +#MODULATION TIME: 0.002051115036010742 #12 # 1 FRAME + PREAMBLE +#MODULATION TIME: 0.004580974578857422 #12 # 2 FRAME + PREAMBLE +#AUDIO TIME: 14.750595331192017 #12 # 2 FRAME + PREAMBLE # FreeDV Defaults @@ -50,6 +55,7 @@ ARQ_ACK_WAITING_FOR_ID = 0 ARQ_RX_BURST_BUFFER = [] ARQ_RX_FRAME_BUFFER = [] ARQ_RX_FRAME_N_BURSTS = 0 +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 ARQ_ACK_RECEIVED = 0 ARQ_ACK_TIMEOUT = 0