mirror of
https://github.com/DJ2LS/FreeDATA
synced 2024-05-14 08:04:33 +00:00
new socket handler
This commit is contained in:
parent
093fa3acfc
commit
2b708f8453
6 changed files with 87 additions and 99 deletions
19
README.md
19
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
|
||||
|
|
6
arq.py
6
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
|
||||
|
||||
|
||||
|
|
23
main.py
23
main.py
|
@ -12,9 +12,19 @@ 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))
|
||||
|
||||
|
|
35
readfromsocket.py
Normal file
35
readfromsocket.py
Normal file
|
@ -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))
|
88
sock.py
88
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):
|
||||
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())
|
||||
|
||||
self.data = bytes()
|
||||
while True:
|
||||
chunk = self.request.recv(8192)#.strip()
|
||||
self.data += chunk
|
||||
if chunk.endswith(b'\n'):
|
||||
break
|
||||
if data == 'SOCKETTEST':
|
||||
response = bytes("WELL DONE! YOU ARE ABLE TO COMMUNICATE WITH THE TNC", 'utf-8')
|
||||
self.request.sendall(response)
|
||||
|
||||
# SEND AN ARQ FRAME -------------------------
|
||||
if self.data.startswith(b'ARQ:'):
|
||||
# TRANSMIT ARQ MESSAGE
|
||||
if data.startswith('ARQ:'):
|
||||
logging.info("CMD | NEW ARQ DATA")
|
||||
|
||||
data = self.data.split(b'ARQ:')
|
||||
data_out = data[1]
|
||||
data = data.split('ARQ:')
|
||||
data_out = bytes(data[1], 'utf-8')
|
||||
|
||||
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
|
||||
class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
|
||||
socketserver.TCPServer.allow_reuse_address = True
|
||||
pass
|
||||
|
||||
|
||||
|
||||
# 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)
|
||||
|
||||
|
||||
|
||||
|
||||
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()
|
||||
|
|
|
@ -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))
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue