From 2b708f8453fda5161bac86fdbaf7b90560872906 Mon Sep 17 00:00:00 2001 From: DJ2LS <75909252+DJ2LS@users.noreply.github.com> Date: Tue, 16 Feb 2021 19:39:08 +0100 Subject: [PATCH 1/7] new socket handler --- README.md | 19 ++-------- arq.py | 6 ++-- main.py | 25 +++++++++---- readfromsocket.py | 35 ++++++++++++++++++ sock.py | 92 +++++++++++------------------------------------ socketclient.py | 9 +++-- 6 files changed, 87 insertions(+), 99 deletions(-) create mode 100644 readfromsocket.py diff --git a/README.md b/README.md index e2517ed9..f5e928c2 100644 --- a/README.md +++ b/README.md @@ -7,25 +7,12 @@ My first attempt to learn more about FreeDV and how to create a TNC which gets d David Rowe and the FreeDV team for developing the modem and libraries FreeDV Codec 2 : https://github.com/drowe67/codec2 + + This software has been heavily inspired by https://github.com/xssfox/freedv-tnc/ -## ToDo -- [x] ARQ: Stop-And-Wait -- [x] ARQ: Go-Back-N -- [x] ARQ: Selective repeating of lost arq frames -- [x] ARQ: Dynamic number of frames per burst -- [ ] ARQ: Set frames per burst automatically by channel quality -- [ ] SETTING: Callsign with selective receiveing -- [ ] SETTING: Own grid locator -- [ ] SOCKET: Set settings & commands via command socket -- [ ] SOCKET: Receive data via data socket -- [ ] TRX: Control radio via hamlib -- [ ] MODE: Beacon -- [ ] MODE: Broadcast -- [ ] MODE: ARQ AX25 -- [ ] MODE: Gear shifting ARQ -- [ ] TNC: CLI GUI for basic settings + ## Setup diff --git a/arq.py b/arq.py index 74bb96c8..0be4b045 100644 --- a/arq.py +++ b/arq.py @@ -323,7 +323,7 @@ def transmit(data_out): #--------------- BREAK LOOP IF FRAME ACK HAS BEEN RECEIVED EARLIER AS EXPECTED elif static.ARQ_FRAME_ACK_RECEIVED == True: - logging.info("----------------------------------------------------------") + logging.info("ARQ | RX | EARLY FRAME ACK RECEIVED") #static.ARQ_N_SENT_FRAMES = #static.TX_BUFFER_SIZE @@ -363,11 +363,13 @@ def transmit(data_out): # ----------- if no ACK received and out of retries.....stop frame sending if static.ARQ_ACK_RECEIVED == False and static.ARQ_FRAME_ACK_RECEIVED == False and static.ARQ_RX_ACK_TIMEOUT == True: logging.error("ARQ | TX | NO BURST OR FRAME ACK RECEIVED | DATA SHOULD BE RESEND!") + logging.error("----------------------------------------------------------") break #-------------------------BREAK TX BUFFER LOOP IF ALL PACKETS HAVE BEEN SENT AND WE GOT A FRAME ACK elif static.ARQ_N_SENT_FRAMES == static.TX_BUFFER_SIZE and static.ARQ_FRAME_ACK_RECEIVED == True: logging.log(25,"ARQ | RX | FRAME ACK RECEIVED - DATA TRANSMITTED! :-)") + logging.log(25,"----------------------------------------------------------") break else: @@ -394,7 +396,7 @@ def transmit(data_out): # 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(): #n_frames_per_burst = randrange(1,10) - n_frames_per_burst = 2 + n_frames_per_burst = 5 return n_frames_per_burst diff --git a/main.py b/main.py index b6b19c85..12116a2e 100644 --- a/main.py +++ b/main.py @@ -12,8 +12,18 @@ import argparse import logging import threading +import socket + + import static import helpers + +def client(ip, port, message): + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: + sock.connect((ip, port)) + sock.sendall(bytes(message, 'ascii')) + response = str(sock.recv(1024), 'ascii') + print("Received: {}".format(response)) if __name__ == '__main__': @@ -58,11 +68,12 @@ if __name__ == '__main__': import sock # we need to wait until we got all parameters from argparse - cmd_server_thread = threading.Thread(target=sock.start_cmd_socket, name="cmd server") - cmd_server_thread.start() - - data_server_thread = threading.Thread(target=sock.start_data_socket, name="data server") - data_server_thread.start() - - + HOST,PORT = static.HOST, static.PORT + server = sock.ThreadedTCPServer((HOST,PORT), sock.ThreadedTCPRequestHandler) + + server_thread = threading.Thread(target=server.serve_forever, name="CMD-SRV:" + str(static.PORT)) + # Exit the server thread when the main thread terminates + server_thread.daemon = True + server_thread.start() + logging.info("SRV | STARTING TCP/IP SOCKET FOR CMD ON PORT: " + str(static.PORT)) diff --git a/readfromsocket.py b/readfromsocket.py new file mode 100644 index 00000000..ca8b525b --- /dev/null +++ b/readfromsocket.py @@ -0,0 +1,35 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Created on Fri Dec 11 21:53:35 2020 + +@author: parallels +""" + +import socket +import sys +import argparse +import time + + + + +#--------------------------------------------GET PARAMETER INPUTS +parser = argparse.ArgumentParser(description='Simons TEST TNC') +parser.add_argument('--port', dest="socket_port", default=3000, help="Set the port, the socket is listening on.", type=int) +parser.add_argument('--data', dest="data", default=False, help="data", type=str) + +args = parser.parse_args() + +ip, port = "localhost", args.socket_port +message = args.data + + + +with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: + print(ip) + print(port) + sock.connect((ip, port)) + sock.sendall(bytes(message, 'utf-8')) + response = str(sock.recv(1024), 'utf-8') + print("Received: {}".format(response)) diff --git a/sock.py b/sock.py index ebbc18f0..6e6b5d7e 100644 --- a/sock.py +++ b/sock.py @@ -9,89 +9,39 @@ Created on Fri Dec 25 21:25:14 2020 import socketserver import threading import logging - +import time import static import arq -class DATATCPRequestHandler(socketserver.BaseRequestHandler): + +class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler): def handle(self): - - self.data = bytes() - while True: - chunk = self.request.recv(8192)#.strip() - self.data += chunk - if chunk.endswith(b'\n'): - break + data = str(self.request.recv(1024), 'utf-8') + #cur_thread = threading.current_thread() + #response = bytes("{}: {}".format(cur_thread.name, data), 'ascii') + #self.request.sendall(response) + #print(threading.enumerate()) - # SEND AN ARQ FRAME ------------------------- - if self.data.startswith(b'ARQ:'): + if data == 'SOCKETTEST': + response = bytes("WELL DONE! YOU ARE ABLE TO COMMUNICATE WITH THE TNC", 'utf-8') + self.request.sendall(response) + + # TRANSMIT ARQ MESSAGE + if data.startswith('ARQ:'): + logging.info("CMD | NEW ARQ DATA") + + data = data.split('ARQ:') + data_out = bytes(data[1], 'utf-8') - data = self.data.split(b'ARQ:') - data_out = data[1] - TRANSMIT_ARQ = threading.Thread(target=arq.transmit, args=[data_out], name="TRANSMIT_ARQ") TRANSMIT_ARQ.start() - - - -class CMDTCPRequestHandler(socketserver.BaseRequestHandler): - - def handle(self): - - self.data = bytes() - while True: - chunk = self.request.recv(8192)#.strip() - self.data += chunk - if chunk.endswith(b'\n'): - break - - - - # self.request is the TCP socket connected to the client - #self.data = self.request.recv(1024).strip() -### self.data = self.request.recv(1000000).strip() - - # interrupt listening loop "while true" by setting MODEM_RECEIVE to False - #if len(self.data) > 0: - # static.MODEM_RECEIVE = False - - - ####print("{} wrote:".format(self.client_address[0])) - ####print(self.data) - - # just send back the same data, but upper-cased - #####self.request.sendall(self.data.upper()) - - #if self.data == b'TEST': - #logging.info("DER TEST KLAPPT! HIER KOMMT DER COMMAND PARSER HIN!") - if self.data.startswith(b'SHOWBUFFERSIZE'): - self.request.sendall(bytes(static.RX_BUFFER[-1])) - print(static.RX_BUFFER_SIZE) +class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer): + socketserver.TCPServer.allow_reuse_address = True + pass -def start_cmd_socket(): - try: - logging.info("SRV | STARTING TCP/IP SOCKET FOR CMD ON PORT: " + str(static.PORT)) - socketserver.TCPServer.allow_reuse_address = True #https://stackoverflow.com/a/16641793 - cmdserver = socketserver.TCPServer((static.HOST, static.PORT), CMDTCPRequestHandler) - cmdserver.serve_forever() - - finally: - cmdserver.server_close() - - -def start_data_socket(): - - try: - logging.info("SRV | STARTING TCP/IP SOCKET FOR DATA ON PORT: " + str(static.PORT + 1)) - socketserver.TCPServer.allow_reuse_address = True #https://stackoverflow.com/a/16641793 - dataserver = socketserver.TCPServer((static.HOST, static.PORT + 1), DATATCPRequestHandler) - dataserver.serve_forever() - - finally: - dataserver.server_close() diff --git a/socketclient.py b/socketclient.py index 37141c73..6316c6d0 100644 --- a/socketclient.py +++ b/socketclient.py @@ -23,6 +23,7 @@ def create_string(length): # Keep appending random characters using chr(x) random_string += (chr(random_integer)) print("STR:" + str(random_string)) + return random_string @@ -42,9 +43,11 @@ args = parser.parse_args() data = create_string(args.datalength) -data = bytes("ACK:" + "!!!--" + data + "--!!!" + "\n", "utf-8") +data = bytes("ARQ:" + "" + data + "" + "\n", "utf-8") -print(data) + + +#print(data) HOST, PORT = "localhost", args.socket_port @@ -60,6 +63,6 @@ with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: received = str(sock.recv(1024), "utf-8") print("Sent: {}".format(data)) -print("Received: {}".format(received)) + From 533d797be3259461be390caff9bf20a8c29ff1ae Mon Sep 17 00:00:00 2001 From: DJ2LS <75909252+DJ2LS@users.noreply.github.com> Date: Tue, 16 Feb 2021 20:49:02 +0100 Subject: [PATCH 2/7] new commands --- sock.py | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/sock.py b/sock.py index 6e6b5d7e..707b1489 100644 --- a/sock.py +++ b/sock.py @@ -13,11 +13,15 @@ import time import static import arq +import helpers class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler): def handle(self): + + encoding = 'utf-8' + data = str(self.request.recv(1024), 'utf-8') #cur_thread = threading.current_thread() #response = bytes("{}: {}".format(cur_thread.name, data), 'ascii') @@ -37,7 +41,73 @@ class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler): TRANSMIT_ARQ = threading.Thread(target=arq.transmit, args=[data_out], name="TRANSMIT_ARQ") TRANSMIT_ARQ.start() + + + + # SETTINGS AND STATUS + if data.startswith('SET:MYCALLSIGN:'): + data = data.split('SET:MYCALLSIGN:') + static.MYCALLSIGN = bytes(data[1], encoding) + static.MYCALLSIGN_CRC8 = helpers.get_crc_8(static.MYCALLSIGN) + #self.request.sendall(bytes(static.MYCALLSIGN, encoding)) + self.request.sendall(static.MYCALLSIGN) + logging.info("CMD | MYCALLSIGN: " + str(static.MYCALLSIGN)) + + + if data == 'GET:MYCALLSIGN': + self.request.sendall(bytes(static.MYCALLSIGN, encoding)) + + if data == 'GET:MYCALLSIGN_CRC8': + self.request.sendall(bytes(static.MYCALLSIGN_CRC8, encoding)) + + if data == 'GET:DXCALLSIGN': + self.request.sendall(bytes(static.DXCALLSIGN, encoding)) + + # ARQ + if data == 'GET:ARQ_STATE': + self.request.sendall(bytes(static.ARQ_STATE, encoding)) + + if data == 'GET:TX_N_MAX_RETRIES': + self.request.sendall(bytes([static.TX_N_MAX_RETRIES], encoding)) + + if data == 'GET:TX_N_RETRIES': + self.request.sendall(bytes([static.TX_N_RETRIES], encoding)) + + if data == 'GET:ARQ_TX_N_FRAMES_PER_BURST': + self.request.sendall(bytes([static.ARQ_TX_N_FRAMES_PER_BURST], encoding)) + + if data == 'GET:ARQ_TX_N_BURSTS': + self.request.sendall(bytes([static.ARQ_TX_N_BURSTS], encoding)) + + if data == 'GET:ARQ_TX_N_CURRENT_ARQ_FRAME': + self.request.sendall(bytes([static.ARQ_TX_N_CURRENT_ARQ_FRAME], encoding)) + + if data == 'GET:ARQ_TX_N_TOTAL_ARQ_FRAMES': + self.request.sendall(bytes([static.ARQ_TX_N_TOTAL_ARQ_FRAMES], encoding)) + + if data == 'GET:ARQ_RX_FRAME_N_BURSTS': + self.request.sendall(bytes([static.ARQ_RX_FRAME_N_BURSTS], encoding)) + + if data == 'GET:ARQ_RX_N_CURRENT_ARQ_FRAME': + self.request.sendall(bytes([static.ARQ_RX_N_CURRENT_ARQ_FRAME], encoding)) + + if data == 'GET:ARQ_N_ARQ_FRAMES_PER_DATA_FRAME': + self.request.sendall(bytes([static.ARQ_N_ARQ_FRAMES_PER_DATA_FRAME], encoding)) + + if data == 'GET:RX_BUFFER_LENGTH': + self.request.sendall(bytes(str(len(static.RX_BUFFER)),encoding)) + if data.startswith('GET:RX_BUFFER:'): + + data = data.split('GET:RX_BUFFER:') + bufferposition = data[1] + + if bufferposition == 0: + if len(static.RX_BUFFER) > 0: + self.request.sendall(static.RX_BUFFER[-1]) + else: + if len(static.RX_BUFFER) > 0: + self.request.sendall(static.RX_BUFFER[bufferposition]) class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer): From a36b85aca3bea38f97fc8604d6955ef406e27e6d Mon Sep 17 00:00:00 2001 From: DJ2LS <75909252+DJ2LS@users.noreply.github.com> Date: Tue, 16 Feb 2021 22:41:06 +0100 Subject: [PATCH 3/7] updated callsin and buffer readings --- main.py | 20 +++++++------------- sock.py | 25 ++++++++++++++++++------- static.py | 8 ++++---- 3 files changed, 29 insertions(+), 24 deletions(-) diff --git a/main.py b/main.py index 12116a2e..289680c3 100644 --- a/main.py +++ b/main.py @@ -12,8 +12,6 @@ import argparse import logging import threading -import socket - import static import helpers @@ -33,20 +31,13 @@ if __name__ == '__main__': # list audio devices helpers.list_audio_devices() - - + - static.MYCALLSIGN = b'DJ2LS' - static.MYCALLSIGN_CRC8 = helpers.get_crc_8(static.MYCALLSIGN) + #static.MYCALLSIGN = b'DJ2LS' + #static.MYCALLSIGN_CRC8 = helpers.get_crc_8(static.MYCALLSIGN) static.DXCALLSIGN = b'DH3WO' - static.DXCALLSIGN_CRC8 = helpers.get_crc_8(static.DXCALLSIGN) - - print("MYCALLSIGN " + str(static.MYCALLSIGN)) - print("MYCALLSIGN_CRC8 " + str(static.MYCALLSIGN_CRC8)) - - print("DXCALLSIGN " + str(static.DXCALLSIGN)) - print("DXCALLSIGN_CRC8 " + str(static.DXCALLSIGN_CRC8)) + static.DXCALLSIGN_CRC8 = helpers.get_crc_8(static.DXCALLSIGN) @@ -77,3 +68,6 @@ if __name__ == '__main__': server_thread.start() logging.info("SRV | STARTING TCP/IP SOCKET FOR CMD ON PORT: " + str(static.PORT)) + + + diff --git a/sock.py b/sock.py index 707b1489..8e223752 100644 --- a/sock.py +++ b/sock.py @@ -29,15 +29,17 @@ class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler): #print(threading.enumerate()) if data == 'SOCKETTEST': - response = bytes("WELL DONE! YOU ARE ABLE TO COMMUNICATE WITH THE TNC", 'utf-8') + cur_thread = threading.current_thread() + response = bytes("WELL DONE! YOU ARE ABLE TO COMMUNICATE WITH THE TNC ---THREAD: " + str(cur_thread), 'utf-8') + self.request.sendall(response) # TRANSMIT ARQ MESSAGE if data.startswith('ARQ:'): logging.info("CMD | NEW ARQ DATA") - data = data.split('ARQ:') - data_out = bytes(data[1], 'utf-8') + arqdata = data.split('ARQ:') + data_out = bytes(arqdata[1], 'utf-8') TRANSMIT_ARQ = threading.Thread(target=arq.transmit, args=[data_out], name="TRANSMIT_ARQ") TRANSMIT_ARQ.start() @@ -100,15 +102,24 @@ class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler): if data.startswith('GET:RX_BUFFER:'): data = data.split('GET:RX_BUFFER:') - bufferposition = data[1] - - if bufferposition == 0: + bufferposition = int(data[1]) + print(static.RX_BUFFER) + if bufferposition == -1: if len(static.RX_BUFFER) > 0: self.request.sendall(static.RX_BUFFER[-1]) else: - if len(static.RX_BUFFER) > 0: + if bufferposition >= len(static.RX_BUFFER) > 0: + #print(static.RX_BUFFER[0]) + #print(static.RX_BUFFER[1]) + #print(static.RX_BUFFER[2]) + #print(type(bufferposition)) + #print(bufferposition) self.request.sendall(static.RX_BUFFER[bufferposition]) + #quit() + + #self.request.close() + #cur_thread.close() class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer): socketserver.TCPServer.allow_reuse_address = True diff --git a/static.py b/static.py index f1613d74..38350b70 100644 --- a/static.py +++ b/static.py @@ -7,11 +7,11 @@ Created on Wed Dec 23 11:13:57 2020 """ # Operator Defaults -MYCALLSIGN = b'' -MYCALLSIGN_CRC8 = b'' +MYCALLSIGN = b'AA0AA' +MYCALLSIGN_CRC8 = b'A' -DXCALLSIGN = b'' -DXCALLSIGN_CRC8 = b'' +DXCALLSIGN = b'AA0AA' +DXCALLSIGN_CRC8 = b'A' MYGRID = b'' #--------------------------------- From 171dc0e5a0c5e839c03be7392739cab5c5201054 Mon Sep 17 00:00:00 2001 From: DJ2LS <75909252+DJ2LS@users.noreply.github.com> Date: Thu, 18 Feb 2021 11:14:47 +0100 Subject: [PATCH 4/7] single threading instead of multithreading per req --- main.py | 13 ++++--------- sock.py | 36 +++++++++++++++++++++--------------- 2 files changed, 25 insertions(+), 24 deletions(-) diff --git a/main.py b/main.py index 289680c3..aa5aeac6 100644 --- a/main.py +++ b/main.py @@ -58,15 +58,10 @@ if __name__ == '__main__': static.PORT = args.socket_port import sock # we need to wait until we got all parameters from argparse - - HOST,PORT = static.HOST, static.PORT - server = sock.ThreadedTCPServer((HOST,PORT), sock.ThreadedTCPRequestHandler) - - server_thread = threading.Thread(target=server.serve_forever, name="CMD-SRV:" + str(static.PORT)) - # Exit the server thread when the main thread terminates - server_thread.daemon = True - server_thread.start() - logging.info("SRV | STARTING TCP/IP SOCKET FOR CMD ON PORT: " + str(static.PORT)) + + cmd_server_thread = threading.Thread(target=sock.start_cmd_socket, name="cmd server") + cmd_server_thread.start() + diff --git a/sock.py b/sock.py index 8e223752..415fbfe9 100644 --- a/sock.py +++ b/sock.py @@ -15,8 +15,7 @@ import static import arq import helpers - -class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler): +class CMDTCPRequestHandler(socketserver.BaseRequestHandler): def handle(self): @@ -102,27 +101,34 @@ class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler): if data.startswith('GET:RX_BUFFER:'): data = data.split('GET:RX_BUFFER:') - bufferposition = int(data[1]) + bufferposition = int(data[1])-1 print(static.RX_BUFFER) if bufferposition == -1: if len(static.RX_BUFFER) > 0: self.request.sendall(static.RX_BUFFER[-1]) - else: - if bufferposition >= len(static.RX_BUFFER) > 0: + + if bufferposition <= len(static.RX_BUFFER) > 0: #print(static.RX_BUFFER[0]) #print(static.RX_BUFFER[1]) #print(static.RX_BUFFER[2]) #print(type(bufferposition)) #print(bufferposition) - self.request.sendall(static.RX_BUFFER[bufferposition]) - - #quit() - - #self.request.close() - #cur_thread.close() - -class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer): - socketserver.TCPServer.allow_reuse_address = True - pass + self.request.sendall(bytes(static.RX_BUFFER[bufferposition])) + + + + + + +def start_cmd_socket(): + + try: + logging.info("SRV | STARTING TCP/IP SOCKET FOR CMD ON PORT: " + str(static.PORT)) + socketserver.TCPServer.allow_reuse_address = True #https://stackoverflow.com/a/16641793 + cmdserver = socketserver.TCPServer((static.HOST, static.PORT), CMDTCPRequestHandler) + cmdserver.serve_forever() + + finally: + cmdserver.server_close() From 1f1234254ac73f1cec2314eea90c59d34812b519 Mon Sep 17 00:00:00 2001 From: DJ2LS <75909252+DJ2LS@users.noreply.github.com> Date: Thu, 18 Feb 2021 15:11:37 +0100 Subject: [PATCH 5/7] add del rx_buffer via sock --- main.py | 15 ++------------- sock.py | 32 ++++++++++++-------------------- 2 files changed, 14 insertions(+), 33 deletions(-) diff --git a/main.py b/main.py index aa5aeac6..c81c5dbe 100644 --- a/main.py +++ b/main.py @@ -31,14 +31,6 @@ if __name__ == '__main__': # list audio devices helpers.list_audio_devices() - - - #static.MYCALLSIGN = b'DJ2LS' - #static.MYCALLSIGN_CRC8 = helpers.get_crc_8(static.MYCALLSIGN) - - static.DXCALLSIGN = b'DH3WO' - static.DXCALLSIGN_CRC8 = helpers.get_crc_8(static.DXCALLSIGN) - #--------------------------------------------GET PARAMETER INPUTS @@ -50,13 +42,12 @@ if __name__ == '__main__': args = parser.parse_args() - - #--------------------------------------------START CMD & DATA SERVER static.FREEDV_DATA_MODE = args.freedv_data_mode static.AUDIO_INPUT_DEVICE = args.audio_input_device static.AUDIO_OUTPUT_DEVICE = args.audio_output_device static.PORT = args.socket_port - + + #--------------------------------------------START CMD SERVER import sock # we need to wait until we got all parameters from argparse cmd_server_thread = threading.Thread(target=sock.start_cmd_socket, name="cmd server") @@ -64,5 +55,3 @@ if __name__ == '__main__': - - diff --git a/sock.py b/sock.py index 415fbfe9..d1189de8 100644 --- a/sock.py +++ b/sock.py @@ -19,18 +19,13 @@ class CMDTCPRequestHandler(socketserver.BaseRequestHandler): def handle(self): - encoding = 'utf-8' - + encoding = 'utf-8' data = str(self.request.recv(1024), 'utf-8') - #cur_thread = threading.current_thread() - #response = bytes("{}: {}".format(cur_thread.name, data), 'ascii') - #self.request.sendall(response) - #print(threading.enumerate()) + # SOCKETTEST if data == 'SOCKETTEST': cur_thread = threading.current_thread() - response = bytes("WELL DONE! YOU ARE ABLE TO COMMUNICATE WITH THE TNC ---THREAD: " + str(cur_thread), 'utf-8') - + response = bytes("WELL DONE! YOU ARE ABLE TO COMMUNICATE WITH THE TNC", encoding) self.request.sendall(response) # TRANSMIT ARQ MESSAGE @@ -48,11 +43,13 @@ class CMDTCPRequestHandler(socketserver.BaseRequestHandler): # SETTINGS AND STATUS if data.startswith('SET:MYCALLSIGN:'): data = data.split('SET:MYCALLSIGN:') - static.MYCALLSIGN = bytes(data[1], encoding) - static.MYCALLSIGN_CRC8 = helpers.get_crc_8(static.MYCALLSIGN) - #self.request.sendall(bytes(static.MYCALLSIGN, encoding)) - self.request.sendall(static.MYCALLSIGN) - logging.info("CMD | MYCALLSIGN: " + str(static.MYCALLSIGN)) + if bytes(data[1], encoding) == b'': + self.request.sendall(b'INVALID CALLSIGN') + else: + static.MYCALLSIGN = bytes(data[1], encoding) + static.MYCALLSIGN_CRC8 = helpers.get_crc_8(static.MYCALLSIGN) + self.request.sendall(static.MYCALLSIGN) + logging.info("CMD | MYCALLSIGN: " + str(static.MYCALLSIGN)) if data == 'GET:MYCALLSIGN': @@ -102,21 +99,16 @@ class CMDTCPRequestHandler(socketserver.BaseRequestHandler): data = data.split('GET:RX_BUFFER:') bufferposition = int(data[1])-1 - print(static.RX_BUFFER) if bufferposition == -1: if len(static.RX_BUFFER) > 0: self.request.sendall(static.RX_BUFFER[-1]) if bufferposition <= len(static.RX_BUFFER) > 0: - #print(static.RX_BUFFER[0]) - #print(static.RX_BUFFER[1]) - #print(static.RX_BUFFER[2]) - #print(type(bufferposition)) - #print(bufferposition) self.request.sendall(bytes(static.RX_BUFFER[bufferposition])) - + if data == 'DEL:RX_BUFFER': + static.RX_BUFFER = [] From 4bd8119b2578b47b1e663efaec88736987c19dad Mon Sep 17 00:00:00 2001 From: DJ2LS <75909252+DJ2LS@users.noreply.github.com> Date: Thu, 18 Feb 2021 15:27:55 +0100 Subject: [PATCH 6/7] Update README.md --- README.md | 97 ++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 78 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index f5e928c2..ffb15db1 100644 --- a/README.md +++ b/README.md @@ -2,18 +2,21 @@ ## FreeDV- Just Another TNC Experiment My first attempt to learn more about FreeDV and how to create a TNC which gets data from a TCP/IP socket +## ToDo -## Credits - -David Rowe and the FreeDV team for developing the modem and libraries -FreeDV Codec 2 : https://github.com/drowe67/codec2 - - -This software has been heavily inspired by https://github.com/xssfox/freedv-tnc/ - - - - +- [x] ARQ: Stop-And-Wait +- [x] ARQ: Go-Back-N +- [x] ARQ: Selective repeating of lost arq frames +- [x] ARQ: Dynamic number of frames per burst +- [ ] ARQ: Set frames per burst automatically by channel quality +- [ ] SOCKET: Run commands via TCP/IP socket +- [ ] TRX: Control radio via hamlib +- [ ] MODE: Beacon +- [ ] MODE: Broadcast +- [ ] MODE: ARQ AX25 +- [ ] MODE: Gear shifting ARQ +- [ ] TNC: CLI GUI for basic settings +- [ ] TNC: Multicore support ## Setup Install FreeDV-Socket-TNC directly to home folder and compile codec2 automatically @@ -26,26 +29,73 @@ chmod +x ~/install_socket_tnc.sh ## Usage main program ``` -./main.py --port 3000 --tx 1 --rx 1 +./main.py --port 3000 --tx 1 --rx 1 --mode 12 ``` -## Usage testclient +## Usage TCP/IP socket client ``` -./socketclient.py --port 3000 --data "BC: hello" +python3 readfromsocket.py --port 3000 --data "GET:RX_BUFFER:0 ``` - ## Socket Commands -Send a simple broadcast +#### SOCKETTEST +Message for testing purposes which repeats: ``` -BC: +SOCKETTEST ``` -Send an ARQ like frame which will ask the receiver for acknowledgement +"WELL DONE! YOU ARE ABLE TO COMMUNICATE WITH THE TNC" + + +#### TRANSMIT ARQ MESSAGE 'HELLO!' ``` -ACK: +ARQ:HELLO! ``` +#### SET NEW CALLSIGN +``` +SET:MYCALLSIGN:AA1AA +``` + +#### GET CALLSIGN +``` +GET:MYCALLSIGN +``` + +#### GET CALLSIGN CRC8 +``` +GET:MYCALLSIGN_CRC8 +``` + +#### GET DX CALLSIGN +``` +GET:DXCALLSIGN +``` + +#### GET ARQ STATE +``` +GET:ARQ_STATE +``` + +#### GET RX BUFFER LENGTH / SIZE +``` +GET:RX_BUFFER_LENGTH +``` + +#### GET RX BUFFER +``` +GET:RX_BUFFER:POSITION +``` +Position = 0 --> Latest Data +Position 1-N --> Buffer positions + +#### DELETE RX BUFFER +``` +DEL:RX_BUFFER +``` + + + ## Other stuff @@ -63,3 +113,12 @@ sudo modprobe snd-aloop index=1,2 enable=1,1 pcm_substreams=1,1 id=CHAT1,CHAT2 ./main.py --port 3001 --tx 2 --rx 2 ``` + +## Credits + +David Rowe and the FreeDV team for developing the modem and libraries +FreeDV Codec 2 : https://github.com/drowe67/codec2 + + +This software has been inspired by https://github.com/xssfox/freedv-tnc/ + From f310a1b92561446b991fa6a30950c8695c8cec40 Mon Sep 17 00:00:00 2001 From: DJ2LS <75909252+DJ2LS@users.noreply.github.com> Date: Thu, 18 Feb 2021 16:26:51 +0100 Subject: [PATCH 7/7] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ffb15db1..2c691230 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ My first attempt to learn more about FreeDV and how to create a TNC which gets d - [x] ARQ: Selective repeating of lost arq frames - [x] ARQ: Dynamic number of frames per burst - [ ] ARQ: Set frames per burst automatically by channel quality -- [ ] SOCKET: Run commands via TCP/IP socket +- [x] SOCKET: Run commands via TCP/IP socket - [ ] TRX: Control radio via hamlib - [ ] MODE: Beacon - [ ] MODE: Broadcast @@ -17,6 +17,7 @@ My first attempt to learn more about FreeDV and how to create a TNC which gets d - [ ] MODE: Gear shifting ARQ - [ ] TNC: CLI GUI for basic settings - [ ] TNC: Multicore support +- [ ] MODEM: Sample rate conversion ## Setup Install FreeDV-Socket-TNC directly to home folder and compile codec2 automatically