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)) +