switching to signalling mode as default

necessary for mode gear shifting, ping, cq ...
This commit is contained in:
DJ2LS 2021-02-24 14:16:29 +01:00 committed by GitHub
parent 327f07ed4d
commit adfb9d3625
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 357 additions and 133 deletions

View file

@ -2,22 +2,18 @@
## 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
- [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
- [x] 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
- [ ] MODEM: Sample rate conversion
## 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/
## Setup
Install FreeDV-Socket-TNC directly to home folder and compile codec2 automatically
@ -30,73 +26,26 @@ chmod +x ~/install_socket_tnc.sh
## Usage main program
```
./main.py --port 3000 --tx 1 --rx 1 --mode 12
./main.py --port 3000 --tx 1 --rx 1
```
## Usage TCP/IP socket client
## Usage testclient
```
python3 readfromsocket.py --port 3000 --data "GET:RX_BUFFER:0
./socketclient.py --port 3000 --data "BC: hello"
```
## Socket Commands
#### SOCKETTEST
Message for testing purposes which repeats:
Send a simple broadcast
```
SOCKETTEST
BC:<DATA>
```
"WELL DONE! YOU ARE ABLE TO COMMUNICATE WITH THE TNC"
#### TRANSMIT ARQ MESSAGE 'HELLO!'
Send an ARQ like frame which will ask the receiver for acknowledgement
```
ARQ:HELLO!
ACK:<DATA>
```
#### 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
@ -114,9 +63,3 @@ 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/

94
arq.py
View file

@ -39,7 +39,7 @@ def data_received(data_in):
arq_percent_burst = int((static.ARQ_N_FRAME / static.ARQ_N_RX_FRAMES_PER_BURSTS)*100)
arq_percent_frame = int(((static.ARQ_RX_N_CURRENT_ARQ_FRAME)/static.ARQ_N_ARQ_FRAMES_PER_DATA_FRAME)*100)
logging.log(24, "ARQ | RX | ARQ FRAME [" + str(static.ARQ_N_FRAME) + "/" + str(static.ARQ_N_RX_FRAMES_PER_BURSTS) + "] [" + str(arq_percent_burst).zfill(3) + "%] --- TOTAL [" + str(static.ARQ_RX_N_CURRENT_ARQ_FRAME) + "/" + str(static.ARQ_N_ARQ_FRAMES_PER_DATA_FRAME) + "] [" + str(arq_percent_frame).zfill(3) + "%]" )
logging.log(24, "ARQ | RX | F:[" + str(static.ARQ_N_FRAME) + "/" + str(static.ARQ_N_RX_FRAMES_PER_BURSTS) + "] [" + str(arq_percent_burst).zfill(3) + "%] --- T:[" + str(static.ARQ_RX_N_CURRENT_ARQ_FRAME) + "/" + str(static.ARQ_N_ARQ_FRAMES_PER_DATA_FRAME) + "] [" + str(arq_percent_frame).zfill(3) + "%]" )
@ -81,11 +81,15 @@ def data_received(data_in):
logging.info("ARQ | TX | BURST ACK")
#BUILDING ACK FRAME FOR BURST -----------------------------------------------
ack_payload = b'BURST_ACK'
ack_payload = b'ACK'
ack_frame = b'<' + ack_payload # < = 60
#TRANSMIT ACK FRAME FOR BURST-----------------------------------------------
modem.transmit_arq_ack(ack_frame)
modem.transmit_signalling(ack_frame)
#TRANSMIT_ARQ_ACK_THREAD = threading.Thread(target=modem.transmit_arq_ack, args=[ack_frame], name="TRANSMIT_ARQ_BURST")
#TRANSMIT_ARQ_ACK_THREAD.start()
#while static.ARQ_STATE == 'SENDING_ACK':
# pass
#clear burst buffer
static.ARQ_RX_BURST_BUFFER = []
@ -111,10 +115,10 @@ def data_received(data_in):
#BUILDING RPT FRAME FOR BURST -----------------------------------------------
rpt_payload = missing_frames
rpt_frame = b'>' + rpt_payload #> = 63
rpt_frame = b'>' + rpt_payload #> = 63 --> 62?!?!?!?!
#TRANSMIT RPT FRAME FOR BURST-----------------------------------------------
modem.transmit_arq_ack(rpt_frame)
modem.transmit_signalling(rpt_frame)
@ -123,7 +127,7 @@ def data_received(data_in):
complete_data_frame = bytearray()
#print("static.ARQ_RX_FRAME_BUFFER.count(None)" + str(static.ARQ_RX_FRAME_BUFFER.count(None)))
if static.ARQ_RX_FRAME_BUFFER.count(None) == 1: ## 1 because position 0 of list will alaways be None in our case
#print("DECODING FRAME!")
logging.debug("DECODING FRAME!")
for frame in range(1,len(static.ARQ_RX_FRAME_BUFFER)):
raw_arq_frame = static.ARQ_RX_FRAME_BUFFER[frame]
arq_frame_payload = raw_arq_frame[8:]
@ -135,18 +139,23 @@ def data_received(data_in):
arq_frame_payload = arq_frame_payload.split(static.FRAME_BOF)
arq_frame_payload = arq_frame_payload[1]
logging.debug("BOF")
# -------- DETECT IF WE RECEIVED A FRAME FOOTER THEN SAVE DATA TO GLOBALS
if arq_frame_payload.rstrip(b'\x00').endswith(static.FRAME_EOF):
# we need to check for at least one xFF. Sometimes we have only one xFF, because the second one is in the next frame
if arq_frame_payload.rstrip(b'\x00').endswith(static.FRAME_EOF) or arq_frame_payload.rstrip(b'\x00').endswith(static.FRAME_EOF[:-1]):
static.ARQ_FRAME_EOF_RECEIVED = True
arq_frame_payload = arq_frame_payload.split(static.FRAME_EOF)
arq_frame_payload = arq_frame_payload[0]
if arq_frame_payload.rstrip(b'\x00').endswith(static.FRAME_EOF[:-1]):
arq_frame_payload = arq_frame_payload.split(static.FRAME_EOF[:-1])
arq_frame_payload = arq_frame_payload[0]
else:
arq_frame_payload = arq_frame_payload.split(static.FRAME_EOF)
arq_frame_payload = arq_frame_payload[0]
logging.debug("EOF")
# --------- AFTER WE SEPARATED BOF AND EOF, STICK EVERYTHING TOGETHER
complete_data_frame = complete_data_frame + arq_frame_payload
logging.debug(complete_data_frame)
#check if Begin of Frame BOF and End of Frame EOF are received, then start calculating CRC and sticking everything together
if static.ARQ_FRAME_BOF_RECEIVED == True and static.ARQ_FRAME_EOF_RECEIVED == True:
@ -167,9 +176,9 @@ def data_received(data_in):
#TRANSMIT ACK FRAME FOR BURST-----------------------------------------------
time.sleep(1) #0.5
logging.info("ARQ | TX | ARQ DATA FRAME ACK [" + str(static.FRAME_CRC.hex()) +"]")
logging.info("ARQ | TX | ARQ DATA FRAME ACK [" + str(static.FRAME_CRC.hex()) +"] BER: ["+str(static.UNCODED_BER)+"]")
modem.transmit_arq_ack(ack_frame)
modem.transmit_signalling(ack_frame)
# clearing buffers and resetting counters
static.ARQ_RX_BURST_BUFFER = []
@ -367,7 +376,7 @@ 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("ARQ | TX | NO ACK RECEIVED | DATA SHOULD BE RESEND!")
logging.error("------------------------------------------------------")
break
@ -375,8 +384,11 @@ def transmit(data_out):
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
break
elif static.ARQ_FRAME_ACK_RECEIVED == False and static.ARQ_RX_FRAME_TIMEOUT == True:
logging.error("ARQ | TX | NO FRAME ACK RECEIVED")
break
else:
logging.debug("NO MATCHING RULE AT THE END")
@ -401,8 +413,8 @@ 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 = 5
n_frames_per_burst = randrange(1,10)
#n_frames_per_burst = 1
return n_frames_per_burst
@ -428,3 +440,43 @@ def burst_rpt_received(data_in):
missing = missing_area[i:i+2]
static.ARQ_RPT_FRAMES.insert(0,missing)
def transmit_ping(callsign):
static.DXCALLSIGN = bytes(callsign, 'utf-8')
logging.info("PING ["+ str(static.MYCALLSIGN, 'utf-8') + "] > ["+ callsign + "]")
frame_type = bytes([2])
ping_payload = b'PING'
ping_frame = frame_type + ping_payload
TRANSMIT_PING_THREAD = threading.Thread(target=modem.transmit_signalling, args=[ping_frame], name="TRANSMIT_ARQ")
TRANSMIT_PING_THREAD.start()
def received_ping(data_in):
logging.info("TX PING ACK")
frame_type = bytes([3])
ping_payload = b'PING_ACK'
ping_frame = frame_type + ping_payload
TRANSMIT_PING_THREAD = threading.Thread(target=modem.transmit_signalling, args=[ping_frame], name="TRANSMIT_ARQ")
TRANSMIT_PING_THREAD.start()
def received_ping_ack(data_in):
logging.info("PING ACK")
def transmit_cq():
logging.info("CQ CQ CQ")
frame_type = bytes([1])
print(frame_type)
cq_frame = frame_type + static.MYCALLSIGN
modem.transmit_signalling(cq_frame)

132
hamlib.py Normal file
View file

@ -0,0 +1,132 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sys
# Change this path to match your "make install" path
sys.path.append('/usr/local/lib/python3.8/site-packages')
## Uncomment to run this script from an in-tree build (or adjust to the
## build directory) without installing the bindings.
#sys.path.append ('.')
#sys.path.append ('.libs')
import Hamlib
def StartUp():
"""Simple script to test the Hamlib.py module with Python3."""
print("%s: Python %s; %s\n" \
% (sys.argv[0], sys.version.split()[0], Hamlib.cvar.hamlib_version))
Hamlib.rig_set_debug(Hamlib.RIG_DEBUG_NONE)
# Init RIG_MODEL_DUMMY
my_rig = Hamlib.Rig(Hamlib.RIG_MODEL_DUMMY)
my_rig.set_conf("rig_pathname", "/dev/Rig")
my_rig.set_conf("retry", "5")
my_rig.open ()
print("SET PTT------------------------------------------")
#Supported types are RIG (CAT command), DTR, RTS, PARALLEL, NONE, overriding PTT type defined in the rig's backend.
#Some side effects of this command are that when type is set to DTR, read PTT state comes from the Hamlib frontend, not read from the radio. When set to NONE, PTT state cannot be read or set even if rig backend supports reading/setting PTT status from the rig.
my_rig.set_ptt(Hamlib.RIG_PTT_SERIAL_DTR,1)
print(my_rig.get_ptt())
rpath = my_rig.get_conf("rig_pathname")
retry = my_rig.get_conf("retry")
print("status(str):\t\t%s" % Hamlib.rigerror(my_rig.error_status))
print("get_conf:\t\tpath = %s, retry = %s" \
% (rpath, retry))
my_rig.set_freq(Hamlib.RIG_VFO_B, 5700000000)
my_rig.set_vfo(Hamlib.RIG_VFO_B)
print("freq:\t\t\t%s" % my_rig.get_freq())
my_rig.set_freq(Hamlib.RIG_VFO_A, 145550000)
(mode, width) = my_rig.get_mode()
print("mode:\t\t\t%s\nbandwidth:\t\t%s" % (Hamlib.rig_strrmode(mode), width))
my_rig.set_mode(Hamlib.RIG_MODE_CW)
(mode, width) = my_rig.get_mode()
print("mode:\t\t\t%s\nbandwidth:\t\t%s" % (Hamlib.rig_strrmode(mode), width))
print("Backend copyright:\t%s" % my_rig.caps.copyright)
print("Model:\t\t\t%s" % my_rig.caps.model_name)
print("Manufacturer:\t\t%s" % my_rig.caps.mfg_name)
print("Backend version:\t%s" % my_rig.caps.version)
print("Backend status:\t\t%s" % Hamlib.rig_strstatus(my_rig.caps.status))
print("Rig info:\t\t%s" % my_rig.get_info())
my_rig.set_level("VOXDELAY", 1)
print("VOX delay:\t\t%s" % my_rig.get_level_i("VOXDELAY"))
my_rig.set_level(Hamlib.RIG_LEVEL_VOXDELAY, 5)
print("VOX delay:\t\t%s" % my_rig.get_level_i(Hamlib.RIG_LEVEL_VOXDELAY))
af = 12.34
print("Setting AF to %0.2f...." % (af))
my_rig.set_level("AF", af)
print("status:\t\t\t%s - %s" % (my_rig.error_status,
Hamlib.rigerror(my_rig.error_status)))
print("AF level:\t\t%0.2f" % my_rig.get_level_f(Hamlib.RIG_LEVEL_AF))
print("strength:\t\t%s" % my_rig.get_level_i(Hamlib.RIG_LEVEL_STRENGTH))
print("status:\t\t\t%s" % my_rig.error_status)
print("status(str):\t\t%s" % Hamlib.rigerror(my_rig.error_status))
chan = Hamlib.channel(Hamlib.RIG_VFO_B)
my_rig.get_channel(chan,1)
print("get_channel status:\t%s" % my_rig.error_status)
print("VFO:\t\t\t%s, %s" % (Hamlib.rig_strvfo(chan.vfo), chan.freq))
print("Attenuators:\t\t%s" % my_rig.caps.attenuator)
print("\nSending Morse, '73'")
my_rig.send_morse(Hamlib.RIG_VFO_A, "73")
my_rig.close()
print("\nSome static functions:")
err, lon1, lat1 = Hamlib.locator2longlat("IN98XC")
err, lon2, lat2 = Hamlib.locator2longlat("DM33DX")
err, loc1 = Hamlib.longlat2locator(lon1, lat1, 3)
err, loc2 = Hamlib.longlat2locator(lon2, lat2, 3)
print("Loc1:\t\tIN98XC -> %9.4f, %9.4f -> %s" % (lon1, lat1, loc1))
print("Loc2:\t\tDM33DX -> %9.4f, %9.4f -> %s" % (lon2, lat2, loc2))
err, dist, az = Hamlib.qrb(lon1, lat1, lon2, lat2)
longpath = Hamlib.distance_long_path(dist)
print("Distance:\t%.3f km, azimuth %.2f, long path:\t%.3f km" \
% (dist, az, longpath))
# dec2dms expects values from 180 to -180
# sw is 1 when deg is negative (west or south) as 0 cannot be signed
err, deg1, mins1, sec1, sw1 = Hamlib.dec2dms(lon1)
err, deg2, mins2, sec2, sw2 = Hamlib.dec2dms(lat1)
lon3 = Hamlib.dms2dec(deg1, mins1, sec1, sw1)
lat3 = Hamlib.dms2dec(deg2, mins2, sec2, sw2)
print('Longitude:\t%4.4f, %4d° %2d\' %2d" %1s\trecoded: %9.4f' \
% (lon1, deg1, mins1, sec1, ('W' if sw1 else 'E'), lon3))
print('Latitude:\t%4.4f, %4d° %2d\' %2d" %1s\trecoded: %9.4f' \
% (lat1, deg2, mins2, sec2, ('S' if sw2 else 'N'), lat3))
if __name__ == '__main__':
StartUp()

View file

@ -16,12 +16,7 @@ import threading
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__':

33
main.spec Normal file
View file

@ -0,0 +1,33 @@
# -*- mode: python ; coding: utf-8 -*-
block_cipher = None
a = Analysis(['main.py'],
pathex=['/home/parallels/FreeDV-JATE'],
binaries=[],
datas=[],
hiddenimports=[],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
[],
name='main',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=True )

View file

@ -93,9 +93,10 @@ class RF():
self.my_rig.set_ptt(self.hamlib_ptt_type,0)
#--------------------------------------------------------------------------------------------------------
def transmit_arq_ack(self,ack_buffer):
def transmit_signalling(self,ack_buffer):
#print(ack_buffer)
static.ARQ_STATE = 'SENDING_ACK'
#static.ARQ_STATE = 'SENDING_ACK'
static.ARQ_STATE = 'SENDING_SIGNALLING'
static.PTT_STATE = True
self.my_rig.set_ptt(self.hamlib_ptt_type,1)
@ -121,9 +122,6 @@ class RF():
data = (ctypes.c_ubyte * bytes_per_frame).from_buffer_copy(buffer)
preamble_bytes = self.c_lib.freedv_rawdatapreambletx(freedv, mod_out_preamble)
#print(n_tx_modem_samples)
#print(preamble_bytes)
#print(len(mod_out_preamble))
self.c_lib.freedv_rawdatatx(freedv,mod_out,data) # modulate DATA and safe it into mod_out pointer
txbuffer = bytearray()
@ -137,8 +135,9 @@ class RF():
self.my_rig.set_ptt(self.hamlib_ptt_type,0)
static.PTT_STATE = False
static.ARQ_STATE = 'RECEIVING_DATA'
static.ARQ_STATE = 'RECEIVING_SIGNALLING'
#static.ARQ_STATE = 'RECEIVING_DATA'
#--------------------------------------------------------------------------------------------------------
# GET ARQ BURST FRAME VOM BUFFER AND MODULATE IT
def transmit_arq_burst(self):
@ -161,10 +160,7 @@ class RF():
mod_out_preamble = mod_out_preamble()
preamble = self.c_lib.freedv_rawdatapreambletx(freedv, mod_out_preamble);
#print(n_tx_modem_samples)
#print(preamble)
#print(len(mod_out_preamble))
txbuffer = bytearray()
txbuffer += bytes(mod_out_preamble)
@ -246,8 +242,8 @@ class RF():
# -------------- transmit audio
self.stream_tx.write(bytes(txbuffer))
static.ARQ_STATE = 'IDLE'
#static.ARQ_STATE = 'RECEIVING_SIGNALLING'
#static.ARQ_STATE = 'IDLE'
static.ARQ_STATE = 'RECEIVING_SIGNALLING'
static.PTT_STATE = False
self.my_rig.set_ptt(self.hamlib_ptt_type,0)
#--------------------------------------------------------------------------------------------------------
@ -290,7 +286,6 @@ class RF():
data_in = self.stream_rx.read(nin, exception_on_overflow = False)
#print(audioop.rms(data_in, 2))
#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
logging.debug(self.c_lib.freedv_get_rx_status(freedv_data))
@ -313,8 +308,14 @@ class RF():
stuck_in_sync_counter = 0
stuck_in_sync_10_counter = 0
#-----------------------------------
# get bit errors
Tbits = self.c_lib.freedv_get_total_bits(freedv_data)
Terrs = self.c_lib.freedv_get_total_bit_errors(freedv_data)
if Tbits != 0:
static.UNCODED_BER = Terrs/Tbits
if nbytes == static.FREEDV_DATA_BYTES_PER_FRAME:
rxstatus = self.c_lib.freedv_get_rx_status(freedv_data)
logging.debug("DATA-" + str(rxstatus))
@ -333,6 +334,7 @@ class RF():
if 50 >= frametype >= 10:
if frame != 3 or force == True:
arq.data_received(bytes(data_bytes_out[:-2])) #send payload data to arq checker without CRC16
#print("static.ARQ_RX_BURST_BUFFER.count(None) " + str(static.ARQ_RX_BURST_BUFFER.count(None)))
@ -349,6 +351,12 @@ class RF():
# DO UNSYNC AFTER LAST BURST by checking the frame numbers agains the total frames per burst
if frame == n_frames_per_burst:
#reset bit error counters
self.c_lib.freedv_set_total_bit_errors(freedv_data,0)
self.c_lib.freedv_set_total_bits(freedv_data,0)
logging.debug("LAST FRAME ---> UNSYNC")
self.c_lib.freedv_set_sync(freedv_data, 0) #FORCE UNSYNC
@ -386,8 +394,23 @@ class RF():
logging.debug("REPEAT REQUEST RECEIVED....")
arq.burst_rpt_received(signalling_bytes_out[:-2])
# CQ FRAME
elif frametype == 1:
logging.info("CQ RECEIVED....")
# PING FRAME
elif frametype == 2:
logging.debug("PING RECEIVED....")
arq.received_ping(signalling_bytes_out[:-2])
# PING ACK
elif frametype == 3:
logging.debug("PING ACK RECEIVED....")
arq.received_ping_ack(signalling_bytes_out[:-2])
else:
logging.debug("OTHER FRAME: " + str(signalling_bytes_out[:-2]))
logging.info("OTHER FRAME: " + str(signalling_bytes_out[:-2]))
print(frametype)
rxstatus = self.c_lib.freedv_get_rx_status(freedv_signalling)

View file

@ -24,12 +24,14 @@ args = parser.parse_args()
ip, port = "localhost", args.socket_port
message = args.data
print(len(b'\n'))
while True:
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
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'))
sock.sendall(bytes(message, 'utf-8') + b'\n')
response = str(sock.recv(1024), 'utf-8')
print("Received: {}".format(response))
print("CMD: {}".format(response))
False
break

44
sock.py
View file

@ -14,21 +14,63 @@ import time
import static
import arq
import helpers
import fec
class CMDTCPRequestHandler(socketserver.BaseRequestHandler):
def handle(self):
encoding = 'utf-8'
data = str(self.request.recv(1024), 'utf-8')
#data = str(self.request.recv(1024), 'utf-8')
data = bytes()
while True:
chunk = self.request.recv(8192)#.strip()
data += chunk
if chunk.endswith(b'\n'):
break
data = data[:-1] # remove b'\n'
data = str(data, 'utf-8')
# SOCKETTEST
if data == 'SOCKETTEST':
cur_thread = threading.current_thread()
response = bytes("WELL DONE! YOU ARE ABLE TO COMMUNICATE WITH THE TNC", encoding)
self.request.sendall(response)
# CQ CQ CQ
if data == 'CQCQCQ':
for i in range(0,3):
arq.transmit_cq()
while static.ARQ_STATE == 'SENDING_SIGNALLING':
time.sleep(0.1)
pass
# PING
if data.startswith('PING:'):
#send ping frame and wait for ACK
pingcommand = data.split('PING:')
dxcallsign = pingcommand[1]
arq.transmit_ping(dxcallsign)
# ARQ CONNECT TO CALLSIGN
if data.startswith('ARQ:CONNECT:'):
if static.TNC_STATE == b'CONNECTED':
# here we should disconnect
pass
if static.TNC_STATE == b'IDLE':
# here we send an "CONNECT FRAME
pass
# TRANSMIT ARQ MESSAGE
# wen need to change the TNC_STATE to "CONNECTE" and need to make sure we have a valid callsign and callsign crc8 of the DX station
if data.startswith('ARQ:') and static.TNC_STATE == b'IDLE':
logging.info("CMD | NEW ARQ DATA")
static.TNC_STATE = b'BUSY'

View file

@ -18,7 +18,7 @@ MYGRID = b''
TNC_STATE = b'IDLE'
PTT_STATE = False
#---------------------------------
@ -51,7 +51,7 @@ PORT = 3000
#PTT control through CM108 GPIO pin
HAMLIB_PTT_TYPE = 'RIG_PTT_NONE'
PTT_STATE = False
@ -69,6 +69,8 @@ FREEDV_DATA_BYTES_PER_FRAME = 0
FREEDV_DATA_PAYLOAD_PER_FRAME = 0
FREEDV_SIGNALLING_BYTES_PER_FRAME = 0
FREEDV_SIGNALLING_PAYLOAD_PER_FRAME = 0
UNCODED_BER = 1
#---------------------------------
#Audio Defaults
@ -85,7 +87,7 @@ AUDIO_CHANNELS = 1
#---------------------------------
#ARQ DEFAULTS
TX_N_MAX_RETRIES = 10
TX_N_MAX_RETRIES = 5
TX_N_RETRIES = 0
ARQ_TX_N_FRAMES_PER_BURST = 0
@ -141,10 +143,10 @@ ARQ_N_SENT_FRAMES = 0 #counter for already sent frames
# RECEIVING_SIGNALLING
# SENDING_ACK
# ACK_RECEIVED
#
#
#
ARQ_STATE = 'RECEIVING_DATA'
# CONNECTED
# DISCONNECTED
# DISCONNECTING
ARQ_STATE = 'RECEIVING_SIGNALLING'
# ------- TX BUFFER
TX_BUFFER_SIZE = 0