mirror of
https://github.com/DJ2LS/FreeDATA
synced 2024-05-14 08:04:33 +00:00
added ARQ like behavior
send via socket "ACK:<DATA TX requests a ACK from RX. RX then sends an ACK to TX. ACK will be requested 3 times, else timeout. Todo: Frame ID, Code cleanup,...... and much much more
This commit is contained in:
parent
ae9a4b49cf
commit
4435ef602e
3 changed files with 103 additions and 13 deletions
43
modem.py
43
modem.py
|
@ -116,7 +116,7 @@ class RF():
|
||||||
sys.stdout.flush() # flushing stdout
|
sys.stdout.flush() # flushing stdout
|
||||||
|
|
||||||
if self.data_output == "audio":
|
if self.data_output == "audio":
|
||||||
|
print(self.audio_channels)
|
||||||
stream_tx = self.p.open(format=self.format,
|
stream_tx = self.p.open(format=self.format,
|
||||||
channels=self.audio_channels,
|
channels=self.audio_channels,
|
||||||
rate=self.audio_sample_rate,
|
rate=self.audio_sample_rate,
|
||||||
|
@ -146,25 +146,52 @@ class RF():
|
||||||
|
|
||||||
|
|
||||||
while static.MODEM_RECEIVE == True: # Listne to audio until data arrives
|
while static.MODEM_RECEIVE == True: # Listne to audio until data arrives
|
||||||
#while True: # Listne to audio until data arrives
|
|
||||||
|
|
||||||
|
|
||||||
if self.data_input == "stdin":
|
#if self.data_input == "stdin":
|
||||||
samples = self.c_lib.freedv_nin(self.freedv)*2 ### MIT DER *2 funktioniert das irgendwie recht zuverlässig bei mode 5! Bei Mode 12 auch
|
# samples = self.c_lib.freedv_nin(self.freedv)*2 ### MIT DER *2 funktioniert das irgendwie recht zuverlässig bei mode 5! Bei Mode 12 auch
|
||||||
data_in = sys.stdin.buffer.read(samples)
|
# data_in = sys.stdin.buffer.read(samples)
|
||||||
if self.data_input == "audio":
|
if self.data_input == "audio":
|
||||||
|
|
||||||
data_in = stream_rx.read(self.c_lib.freedv_nin(self.freedv), exception_on_overflow = False)
|
data_in = stream_rx.read(self.c_lib.freedv_nin(self.freedv), exception_on_overflow = False)
|
||||||
#print(bytes(data_in))
|
#print(bytes(data_in))
|
||||||
|
buffer = bytearray(self.n_max_modem_samples*2) # N MAX SAMPLES * 2
|
||||||
|
buffer[:len(data_in)] = data_in # copy across what we have
|
||||||
|
|
||||||
|
|
||||||
|
self.ModulationIn()() #Create new ModulationIn Object
|
||||||
|
modulation = self.ModulationIn()# get an empty modulation array
|
||||||
|
modulation = modulation.from_buffer_copy(buffer) # copy buffer across and get a pointer to it.
|
||||||
|
|
||||||
bytes_out = self.FrameBytes()() # initilize a pointer to where bytes will be outputed
|
bytes_out = self.FrameBytes()() # initilize a pointer to where bytes will be outputed
|
||||||
|
|
||||||
nbytes = self.c_lib.freedv_rawdatarx(self.freedv, bytes_out, data_in) # Demodulated data and get number of demodulated bytes
|
nbytes = self.c_lib.freedv_rawdatarx(self.freedv, bytes_out, data_in) # Demodulated data and get number of demodulated bytes
|
||||||
|
|
||||||
#if nbytes > 0:
|
|
||||||
if nbytes == self.bytes_per_frame: # make sure, we receive a full frame
|
if nbytes == self.bytes_per_frame: # make sure, we receive a full frame
|
||||||
|
|
||||||
|
|
||||||
print(bytes(bytes_out[:-2]))
|
print(bytes(bytes_out[:-2]))
|
||||||
#stream_rx.close()
|
self.c_lib.freedv_set_sync(self.freedv, 0)
|
||||||
|
|
||||||
|
#print(bytes(bytes_out))
|
||||||
|
|
||||||
|
# CHECK IF FRAME CONTAINS ACK------------------------
|
||||||
|
if bytes(bytes_out[:6]) == b'REQACK':
|
||||||
|
print("REQACK FRAME ERKANNT!!!!")
|
||||||
|
print("ADD TO SEND BUFFER")
|
||||||
|
time.sleep(5)
|
||||||
|
print("SEND ACK FRAME")
|
||||||
|
self.Transmit(b'ACK')
|
||||||
|
#----------------------------------------------------
|
||||||
|
|
||||||
|
# CHECK IF FRAME CONTAINS ACK------------------------
|
||||||
|
if bytes(bytes_out[:3]) == b'ACK':
|
||||||
|
print("ACK FRAME ERKANNT!!!!")
|
||||||
|
static.ACK_TIMEOUT = 1
|
||||||
|
static.ACK_RECEIVED = 1
|
||||||
|
static.ACK_RETRY = 3
|
||||||
|
#----------------------------------------------------
|
||||||
|
|
||||||
#return bytes(bytes_out[:-2])
|
#return bytes(bytes_out[:-2])
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -28,3 +28,10 @@ AUDIO_SAMPLE_RATE = 8000
|
||||||
MODEM_SAMPLE_RATE = 8000
|
MODEM_SAMPLE_RATE = 8000
|
||||||
AUDIO_FRAMES_PER_BUFFER = 1024
|
AUDIO_FRAMES_PER_BUFFER = 1024
|
||||||
AUDIO_CHANNELS = 1
|
AUDIO_CHANNELS = 1
|
||||||
|
|
||||||
|
|
||||||
|
#TNC DEFAULTS
|
||||||
|
TX_RETRIES = 3
|
||||||
|
ACK_RECEIVED = 0
|
||||||
|
ACK_TIMEOUT = 0
|
||||||
|
ACK_RETRY = 3
|
66
tnc.py
66
tnc.py
|
@ -7,7 +7,8 @@ import threading
|
||||||
|
|
||||||
import modem
|
import modem
|
||||||
import static
|
import static
|
||||||
|
#from other import *
|
||||||
|
import other
|
||||||
modem = modem.RF()
|
modem = modem.RF()
|
||||||
|
|
||||||
|
|
||||||
|
@ -20,8 +21,8 @@ class TCPRequestHandler(socketserver.BaseRequestHandler):
|
||||||
|
|
||||||
|
|
||||||
# interrupt listening loop "while true" by setting MODEM_RECEIVE to False
|
# interrupt listening loop "while true" by setting MODEM_RECEIVE to False
|
||||||
if len(self.data) > 0:
|
#if len(self.data) > 0:
|
||||||
static.MODEM_RECEIVE = False
|
# static.MODEM_RECEIVE = False
|
||||||
|
|
||||||
|
|
||||||
print("{} wrote:".format(self.client_address[0]))
|
print("{} wrote:".format(self.client_address[0]))
|
||||||
|
@ -36,11 +37,66 @@ class TCPRequestHandler(socketserver.BaseRequestHandler):
|
||||||
# BROADCAST PARSER -----------------------------------------------------------
|
# BROADCAST PARSER -----------------------------------------------------------
|
||||||
|
|
||||||
if self.data.startswith(b'BC:'):
|
if self.data.startswith(b'BC:'):
|
||||||
static.MODEM_RECEIVE = False
|
static.MODEM_RECEIVE = True ####### FALSE....
|
||||||
print(static.MODEM_RECEIVE)
|
print(static.MODEM_RECEIVE)
|
||||||
|
|
||||||
data = self.data.split(b'BC:')
|
data = self.data.split(b'BC:')
|
||||||
daten = modem.Transmit(data[1])
|
daten = modem.Transmit(data[1])
|
||||||
|
|
||||||
static.MODEM_RECEIVE = True
|
static.MODEM_RECEIVE = True
|
||||||
print(static.MODEM_RECEIVE)
|
print(static.MODEM_RECEIVE)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# ACKNOWLEDGE PARSER -----------------------------------------------------------
|
||||||
|
|
||||||
|
if self.data.startswith(b'ACK:'):
|
||||||
|
static.MODEM_RECEIVE = True ############## FALSE
|
||||||
|
print(static.MODEM_RECEIVE)
|
||||||
|
|
||||||
|
data = self.data.split(b'ACK:')
|
||||||
|
data_out = data[1]
|
||||||
|
|
||||||
|
|
||||||
|
TXbuffer = [data_out[i:i+24] for i in range(0, len(data_out), 24)] # split incomming bytes to size of 30bytes, create a list and loop through it
|
||||||
|
TXbuffer_length = len(TXbuffer)
|
||||||
|
for i in range(TXbuffer_length): # LOOP THROUGH DATA LIST
|
||||||
|
|
||||||
|
#--------------------------------------------- BUILD DATA PACKET
|
||||||
|
ack = b'REQACK'
|
||||||
|
data_to_transmit = ack + TXbuffer[i]
|
||||||
|
|
||||||
|
|
||||||
|
print(len(data_to_transmit))
|
||||||
|
print(data_to_transmit)
|
||||||
|
#---------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
static.ACK_RETRY = 1
|
||||||
|
for static.ACK_RETRY in range(static.TX_RETRIES):
|
||||||
|
print("RETRY: " + str(static.ACK_RETRY))
|
||||||
|
print("SENDING")
|
||||||
|
static.ACK_RECEIVED = 0
|
||||||
|
daten = modem.Transmit(data_to_transmit)
|
||||||
|
|
||||||
|
# --------------------------- START TIMER
|
||||||
|
static.ACK_TIMEOUT = 0
|
||||||
|
timer = threading.Timer(10.0, other.timeout)
|
||||||
|
timer.start()
|
||||||
|
|
||||||
|
# --------------------------- WHILE TIMEOUT NOT REACHED LISTEN
|
||||||
|
print("WAITING FOR ACK")
|
||||||
|
while static.ACK_TIMEOUT == 0 and static.ACK_RECEIVED == 0:
|
||||||
|
static.MODEM_RECEIVE = True
|
||||||
|
|
||||||
|
if static.ACK_RECEIVED == 1:
|
||||||
|
static.ACK_RETRY = 3
|
||||||
|
break
|
||||||
|
|
||||||
|
if static.ACK_RECEIVED ==1:
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
print("GESCHAFFT!")
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue