mirror of
https://github.com/DJ2LS/FreeDATA
synced 2024-05-14 08:04:33 +00:00
switching to signalling mode as default
necessary for mode gear shifting, ping, cq ...
This commit is contained in:
parent
327f07ed4d
commit
adfb9d3625
9 changed files with 357 additions and 133 deletions
95
README.md
95
README.md
|
@ -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/
|
82
arq.py
82
arq.py
|
@ -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
|
||||
|
||||
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,7 +384,10 @@ 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
|
||||
|
||||
elif static.ARQ_FRAME_ACK_RECEIVED == False and static.ARQ_RX_FRAME_TIMEOUT == True:
|
||||
logging.error("ARQ | TX | NO FRAME ACK RECEIVED")
|
||||
break
|
||||
|
||||
else:
|
||||
|
@ -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
132
hamlib.py
Normal 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()
|
7
main.py
7
main.py
|
@ -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
33
main.spec
Normal 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 )
|
49
modem.py
49
modem.py
|
@ -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()
|
||||
|
@ -138,7 +136,8 @@ 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,9 +160,6 @@ 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))
|
||||
|
@ -314,6 +309,12 @@ class RF():
|
|||
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)
|
||||
|
@ -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)
|
||||
|
|
|
@ -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:
|
||||
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
44
sock.py
|
@ -14,13 +14,24 @@ 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':
|
||||
|
@ -28,7 +39,38 @@ class CMDTCPRequestHandler(socketserver.BaseRequestHandler):
|
|||
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'
|
||||
|
|
16
static.py
16
static.py
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue