Merge branch 'main' into ls-hamlib-test

This commit is contained in:
DJ2LS 2022-01-05 11:54:31 +01:00 committed by GitHub
commit 71be19ecc4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 603 additions and 619 deletions

View file

@ -128,6 +128,18 @@ add_test(NAME highsnr_virtual5_P_P_multi_callback_outside
./test_virtual4b.sh") ./test_virtual4b.sh")
set_tests_properties(highsnr_virtual5_P_P_multi_callback_outside PROPERTIES PASS_REGULAR_EXPRESSION "DATAC0: 2/4 DATAC1: 2/4 DATAC3: 2/4") set_tests_properties(highsnr_virtual5_P_P_multi_callback_outside PROPERTIES PASS_REGULAR_EXPRESSION "DATAC0: 2/4 DATAC1: 2/4 DATAC3: 2/4")
# ARQ test short
add_test(NAME highsnr_ARQ_short
COMMAND sh -c "export LD_LIBRARY_PATH=${CODEC2_BUILD_DIR}/src;
PATH=$PATH:${CODEC2_BUILD_DIR}/src;
cd ${CMAKE_CURRENT_SOURCE_DIR}/test;
python3 test_arq_short.py")
set_tests_properties(highsnr_ARQ_short PROPERTIES PASS_REGULAR_EXPRESSION "ARQ | TX | DATA TRANSMITTED!")
endif() endif()

Binary file not shown.

View file

@ -648,11 +648,11 @@ ipcRenderer.on('action-update-tnc-state', (event, arg) => {
} }
// ARQ STATE // ARQ STATE
if (arg.arq_state == 'DATA') { if (arg.arq_state == 'True') {
document.getElementById("arq_state").className = "btn btn-warning"; document.getElementById("arq_state").className = "btn btn-warning";
document.getElementById("startTransmission").disabled = true document.getElementById("startTransmission").disabled = true
document.getElementById("stopTransmission").disabled = false document.getElementById("stopTransmission").disabled = false
} else if (arg.arq_state == 'IDLE') { } else if (arg.arq_state == 'False') {
document.getElementById("arq_state").className = "btn btn-secondary"; document.getElementById("arq_state").className = "btn btn-secondary";
document.getElementById("startTransmission").disabled = false document.getElementById("startTransmission").disabled = false
document.getElementById("stopTransmission").disabled = true document.getElementById("stopTransmission").disabled = true
@ -701,6 +701,15 @@ ipcRenderer.on('action-update-tnc-state', (event, arg) => {
} }
document.getElementById("bytes_per_min").innerHTML = arq_bytes_per_minute document.getElementById("bytes_per_min").innerHTML = arq_bytes_per_minute
// SET BYTES PER MINUTE COMPRESSED
if (typeof(arg.arq_bytes_per_minute) == 'undefined') {
var arq_bytes_per_minute_compressed = 0
} else {
var arq_bytes_per_minute_compressed = Math.round(arg.arq_bytes_per_minute * arg.arq_compression_factor)
}
document.getElementById("bytes_per_min_compressed").innerHTML = arq_bytes_per_minute_compressed
// SET TOTAL BYTES // SET TOTAL BYTES
if (typeof(arg.total_bytes) == 'undefined') { if (typeof(arg.total_bytes) == 'undefined') {
var total_bytes = 0 var total_bytes = 0

View file

@ -152,6 +152,7 @@ client.on('data', function(data) {
arq_rx_n_current_arq_frame: data['ARQ_RX_N_CURRENT_ARQ_FRAME'], arq_rx_n_current_arq_frame: data['ARQ_RX_N_CURRENT_ARQ_FRAME'],
arq_n_arq_frames_per_data_frame: data['ARQ_N_ARQ_FRAMES_PER_DATA_FRAME'], arq_n_arq_frames_per_data_frame: data['ARQ_N_ARQ_FRAMES_PER_DATA_FRAME'],
arq_bytes_per_minute: data['ARQ_BYTES_PER_MINUTE'], arq_bytes_per_minute: data['ARQ_BYTES_PER_MINUTE'],
arq_compression_factor: data['ARQ_COMPRESSION_FACTOR'],
total_bytes: data['TOTAL_BYTES'], total_bytes: data['TOTAL_BYTES'],
arq_transmission_percent: data['ARQ_TRANSMISSION_PERCENT'], arq_transmission_percent: data['ARQ_TRANSMISSION_PERCENT'],
stations: data['STATIONS'], stations: data['STATIONS'],

View file

@ -897,7 +897,8 @@
<div class="input-group input-group-sm"> <span class="input-group-text" id="basic-addon1">Mode</span> <div class="input-group input-group-sm"> <span class="input-group-text" id="basic-addon1">Mode</span>
<select class="form-select form-select-sm" aria-label=".form-select-sm" id="datamode"> <select class="form-select form-select-sm" aria-label=".form-select-sm" id="datamode">
<!--<option value="14">low SNR (DC0)</option>--> <!--<option value="14">low SNR (DC0)</option>-->
<option selected value="10">HIGH SNR (DC1)</option> <option selected value="255">AUTO</option>
<option value="10">HIGH SNR (DC1)</option>
<option value="12">MED SNR (DC3)</option> <option value="12">MED SNR (DC3)</option>
</select> </select>
</div> </div>
@ -951,7 +952,7 @@
<!---------------------------------------------------------------------- FOOTER AREA ------------------------------------------------------------> <!---------------------------------------------------------------------- FOOTER AREA ------------------------------------------------------------>
<nav class="navbar fixed-bottom navbar-light bg-light"> <nav class="navbar fixed-bottom navbar-light bg-light">
<div class="container-fluid"> <div class="container-fluid">
<div class="btn-toolbar" style="width:20%" role="toolbar"> <div class="btn-toolbar" role="toolbar">
<div class="btn-group btn-group-sm me-2" role="group"> <div class="btn-group btn-group-sm me-2" role="group">
<button class="btn btn-secondary" id="ptt_state" type="button" data-bs-placement="top" data-bs-toggle="tooltip" data-bs-html="true" title="PTT state:<strong class='text-success'>RECEIVING</strong> / <strong class='text-danger'>TRANSMITTING</strong>"> <button class="btn btn-secondary" id="ptt_state" type="button" data-bs-placement="top" data-bs-toggle="tooltip" data-bs-html="true" title="PTT state:<strong class='text-success'>RECEIVING</strong> / <strong class='text-danger'>TRANSMITTING</strong>">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-broadcast-pin" viewBox="0 0 16 16"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-broadcast-pin" viewBox="0 0 16 16">
@ -975,21 +976,31 @@
</div> </div>
</div> </div>
<div class="container-fluid" style="width:30%">
<div class="container-fluid p-0" style="width:15rem">
<div class="input-group input-group-sm"> <div class="input-group input-group-sm">
<!--<span class="input-group-text" id="basic-addon1"><strong>Freq</strong></span>--> <span class="input-group-text" id="frequency">---</span> <!--<span class="input-group-text" id="basic-addon1"><strong>Freq</strong></span>--> <span class="input-group-text" id="frequency">---</span>
<!--<span class="input-group-text" id="basic-addon1"><strong>Mode</strong></span>--> <span class="input-group-text" id="mode">---</span> <!--<span class="input-group-text" id="basic-addon1"><strong>Mode</strong></span>--> <span class="input-group-text" id="mode">---</span>
<!--<span class="input-group-text" id="basic-addon1"><strong>BW</strong></span>--> <span class="input-group-text" id="bandwith">---</span> <!--<span class="input-group-text" id="basic-addon1"><strong>BW</strong></span>--> <span class="input-group-text" id="bandwith">---</span>
</div> </div>
</div> </div>
<div class="container-fluid" style="width:30%">
<div class="container-fluid p-0" style="width:12rem">
<div class="input-group input-group-sm"> <span class="input-group-text" id="basic-addon1"><strong>B/min</strong></span> <div class="input-group input-group-sm"> <span class="input-group-text" id="basic-addon1"><strong>B/min</strong></span>
<span class="input-group-text" id="bytes_per_min">---</span> <span class="input-group-text" id="bytes_per_min" data-bs-placement="bottom" data-bs-toggle="tooltip" data-bs-html="false" title="raw data rate modem in bytes per minute">---</span>
<span class="input-group-text" id="basic-addon1"><strong>Total</strong></span> <span class="input-group-text" id="bytes_per_min_compressed" data-bs-placement="bottom" data-bs-toggle="tooltip" data-bs-html="false" title="data rate including file compression in bytes per minute">---</span>
</div>
</div>
<div class="container-fluid p-0" style="width:10rem">
<div class="input-group input-group-sm"> <span class="input-group-text" id="basic-addon1"><strong>kBytes</strong></span>
<span class="input-group-text" id="total_bytes">---</span> <span class="input-group-text" id="total_bytes">---</span>
</div> </div>
</div> </div>
<div class="container-fluid" style="width:20%"> <div class="container-fluid p-0" style="width:15rem">
<div class="progress" style="height: 30px;"> <div class="progress" style="height: 30px;">
<div class="progress-bar progress-bar-striped bg-primary" id="transmission_progress" role="progressbar" style="width: 0%" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div> <div class="progress-bar progress-bar-striped bg-primary" id="transmission_progress" role="progressbar" style="width: 0%" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div>
<!--<p class="justify-content-center d-flex position-absolute w-100">PROGRESS</p>--> <!--<p class="justify-content-center d-flex position-absolute w-100">PROGRESS</p>-->

View file

@ -1,3 +1,34 @@
# Instructions
1. Install:
```
cd FreeDATA
mkdir build
cd build
cmake -DCODEC2_BUILD_DIR=$HOME/codec2/build_linux ..
```
2. List available tests:
```
ctest -N
Test project /home/david/FreeDATA/build
Test #1: 000_audio_tests
Test #2: 001_highsnr_stdio_audio
Total Tests: 2
```
3. Run tests:
```
ctest --output-on-failure
```
4. Run tests verbosely:
```
ctest -V
```
# 001_HIGHSNR_STDIO_AUDIO TEST SUITE # 001_HIGHSNR_STDIO_AUDIO TEST SUITE
1. Install 1. Install

28
test/test_arq_short.py Normal file
View file

@ -0,0 +1,28 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Wed Dec 23 07:04:24 2020
@author: DJ2LS
"""
import sys
sys.path.insert(0,'..')
sys.path.insert(0,'../tnc')
import data_handler
import argparse
import codec2
parser = argparse.ArgumentParser(description='ARQ TEST')
parser.add_argument('--mode', dest="FREEDV_MODE", type=str, choices=['datac0', 'datac1', 'datac3'])
parser.add_argument('--framesperburst', dest="N_FRAMES_PER_BURST", default=1, type=int)
args = parser.parse_args()
bytes_out = b'{"dt":"f","fn":"zeit.txt","ft":"text\\/plain","d":"data:text\\/plain;base64,MyBtb2Rlcywgb2huZSBjbGFzcwowLjAwMDk2OTQ4MTE4MDk5MTg0MTcKCjIgbW9kZXMsIG9obmUgY2xhc3MKMC4wMDA5NjY1NDUxODkxMjI1Mzk0CgoxIG1vZGUsIG9obmUgY2xhc3MKMC4wMDA5NjY5NzY1NTU4Nzc4MjA5CgMyBtb2Rlcywgb2huZSBjbGFzcwowLjAwMDk2OTQ4MTE4MDk5MTg0MTcKCjIgbW9kZXMsIG9obmUgY2xhc3MKMC4wMDA5NjY1NDUxODkxMjI1Mzk0CgoxIG1vZGUsIG9obmUgY2xhc3MKMC4wMDA5NjY5NzY1NTU4Nzc4MjA5Cg=MyBtb2Rlcywgb2huZSBjbGFzcwowLjAwMDk2OTQ4MTE4MDk5MTg0MTcKCjIgbW9kZXMsIG9obmUgY2xhc3MKMC4wMDA5NjY1NDUxODkxMjI1Mzk0CgoxIG1vZGUsIG9obmUgY2xhc3MKMC4wMDA5NjY5NzY1NTU4Nzc4MjA5CgMyBtb2Rlcywgb2huZSBjbGFzcwowLjAwMDk2OTQ4MTE4MDk5MTg0MTcKCjIgbW9kZXMsIG9obmUgY2xhc3MKMC4wMDA5NjY1NDUxODkxMjI1Mzk0CgoxIG1vZGUsIG9obmUgY2xhc3MKMC4wMDA5NjY5NzY1NTU4Nzc4MjA5CgMyBtb2Rlcywgb2huZSBjbGFzcwowLjAwMDk2OTQ4MTE4MDk5MTg0MTcKCjIgbW9kZXMsIG9obmUgY2xhc3MKMC4wMDA5NjY1NDUxODkxMjI1Mzk0CgoxIG1vZGUsIG9obmUgY2xhc3MKMC4wMDA5NjY5NzY1NTU4Nzc4MjA5Cg=","crc":"123123123"}'
mode = codec2.freedv_get_mode(args.FREEDV_MODE)
n_frames_per_burst = args.N_FRAMES_PER_BURST
data_handler.TESTMODE = True
data_handler.open_dc_and_transmit(bytes_out, mode, n_frames_per_burst)

View file

@ -1,22 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Wed Dec 23 07:04:24 2020
@author: DJ2LS
"""
import sys
sys.path.insert(0,'..')
sys.path.insert(0,'../tnc')
import data_handler
teststring = b'HELLO WORLD'
data_handler.arq_transmit(teststring, 10, 1)

File diff suppressed because it is too large Load diff

View file

@ -18,6 +18,7 @@ import numpy as np
import helpers import helpers
import static import static
import data_handler import data_handler
import re import re
import queue import queue
import codec2 import codec2
@ -240,17 +241,17 @@ class RF():
mod_out_postamble = create_string_buffer(n_tx_postamble_modem_samples * 2) mod_out_postamble = create_string_buffer(n_tx_postamble_modem_samples * 2)
# add empty data to handle ptt toggle time # add empty data to handle ptt toggle time
data_delay_seconds = 250 data_delay_mseconds = 0 #miliseconds
data_delay = int(self.MODEM_SAMPLE_RATE*(data_delay_seconds/1000)) data_delay = int(self.MODEM_SAMPLE_RATE*(data_delay_mseconds/1000))
mod_out_silence = create_string_buffer(data_delay*2) mod_out_silence = create_string_buffer(data_delay*2)
txbuffer = bytes(mod_out_silence) txbuffer = bytes(mod_out_silence)
for i in range(1,repeats+1): for i in range(1,repeats+1):
# write preamble to txbuffer # write preamble to txbuffer
codec2.api.freedv_rawdatapreambletx(freedv, mod_out_preamble) codec2.api.freedv_rawdatapreambletx(freedv, mod_out_preamble)
time.sleep(0.01) time.sleep(0.05)
txbuffer += bytes(mod_out_preamble) txbuffer += bytes(mod_out_preamble)
# create modulaton for n frames in list # create modulaton for n frames in list
for n in range(0,len(frames)): for n in range(0,len(frames)):
@ -267,19 +268,19 @@ class RF():
data = (ctypes.c_ubyte * bytes_per_frame).from_buffer_copy(buffer) data = (ctypes.c_ubyte * bytes_per_frame).from_buffer_copy(buffer)
codec2.api.freedv_rawdatatx(freedv,mod_out,data) # modulate DATA and save it into mod_out pointer codec2.api.freedv_rawdatatx(freedv,mod_out,data) # modulate DATA and save it into mod_out pointer
time.sleep(0.01) time.sleep(0.05)
txbuffer += bytes(mod_out) txbuffer += bytes(mod_out)
# append postamble to txbuffer # append postamble to txbuffer
codec2.api.freedv_rawdatapostambletx(freedv, mod_out_postamble) codec2.api.freedv_rawdatapostambletx(freedv, mod_out_postamble)
txbuffer += bytes(mod_out_postamble) txbuffer += bytes(mod_out_postamble)
time.sleep(0.01) time.sleep(0.05)
# add delay to end of frames # add delay to end of frames
samples_delay = int(self.MODEM_SAMPLE_RATE*(repeat_delay/1000)) samples_delay = int(self.MODEM_SAMPLE_RATE*(repeat_delay/1000))
mod_out_silence = create_string_buffer(samples_delay*2) mod_out_silence = create_string_buffer(samples_delay*2)
txbuffer += bytes(mod_out_silence) txbuffer += bytes(mod_out_silence)
time.sleep(0.01) #time.sleep(0.05)
# resample up to 48k (resampler works on np.int16) # resample up to 48k (resampler works on np.int16)
x = np.frombuffer(txbuffer, dtype=np.int16) x = np.frombuffer(txbuffer, dtype=np.int16)
@ -294,7 +295,9 @@ class RF():
# if data is shorter than the expcected audio frames per buffer we need to append 0 # if data is shorter than the expcected audio frames per buffer we need to append 0
# to prevent the callback from stucking/crashing # to prevent the callback from stucking/crashing
if len(c) < self.AUDIO_FRAMES_PER_BUFFER_RX*2: if len(c) < self.AUDIO_FRAMES_PER_BUFFER_RX*2:
c += bytes(self.AUDIO_FRAMES_PER_BUFFER_RX*2 - len(c)) delta = bytes(self.AUDIO_FRAMES_PER_BUFFER_RX*2 - len(c))
c += delta
structlog.get_logger("structlog").debug("[TNC] mod out shorter than audio buffer", delta=len(delta))
self.modoutqueue.put(c) self.modoutqueue.put(c)
# maybe we need to toggle PTT before craeting modulation because of queue processing # maybe we need to toggle PTT before craeting modulation because of queue processing
@ -302,21 +305,21 @@ class RF():
while not self.modoutqueue.empty(): while not self.modoutqueue.empty():
pass pass
static.PTT_STATE = self.hamlib.set_ptt(False) static.PTT_STATE = self.hamlib.set_ptt(False)
self.c_lib.freedv_close(freedv) self.c_lib.freedv_close(freedv)
return True return True
def audio(self): def audio(self):
try: try:
print(f"starting pyaudio callback", file=sys.stderr) structlog.get_logger("structlog").debug("[TNC] starting pyaudio callback")
self.audio_stream.start_stream() self.audio_stream.start_stream()
except Exception as e: except Exception as e:
print(f"pyAudio error: {e}", file=sys.stderr) structlog.get_logger("structlog").error("[TNC] starting pyaudio callback failed", e=e)
while self.audio_stream.is_active(): while self.audio_stream.is_active():
while self.datac0_buffer.nbuffer >= self.datac0_nin: while self.datac0_buffer.nbuffer >= self.datac0_nin:
# demodulate audio # demodulate audio
nbytes = codec2.api.freedv_rawdatarx(self.datac0_freedv, self.datac0_bytes_out, self.datac0_buffer.buffer.ctypes) nbytes = codec2.api.freedv_rawdatarx(self.datac0_freedv, self.datac0_bytes_out, self.datac0_buffer.buffer.ctypes)
self.datac0_buffer.pop(self.datac0_nin) self.datac0_buffer.pop(self.datac0_nin)
@ -327,6 +330,7 @@ class RF():
self.calculate_snr(self.datac0_freedv) self.calculate_snr(self.datac0_freedv)
while self.datac1_buffer.nbuffer >= self.datac1_nin: while self.datac1_buffer.nbuffer >= self.datac1_nin:
# demodulate audio # demodulate audio
nbytes = codec2.api.freedv_rawdatarx(self.datac1_freedv, self.datac1_bytes_out, self.datac1_buffer.buffer.ctypes) nbytes = codec2.api.freedv_rawdatarx(self.datac1_freedv, self.datac1_bytes_out, self.datac1_buffer.buffer.ctypes)
self.datac1_buffer.pop(self.datac1_nin) self.datac1_buffer.pop(self.datac1_nin)
@ -337,6 +341,7 @@ class RF():
self.calculate_snr(self.datac1_freedv) self.calculate_snr(self.datac1_freedv)
while self.datac3_buffer.nbuffer >= self.datac3_nin: while self.datac3_buffer.nbuffer >= self.datac3_nin:
# demodulate audio # demodulate audio
nbytes = codec2.api.freedv_rawdatarx(self.datac3_freedv, self.datac3_bytes_out, self.datac3_buffer.buffer.ctypes) nbytes = codec2.api.freedv_rawdatarx(self.datac3_freedv, self.datac3_bytes_out, self.datac3_buffer.buffer.ctypes)
self.datac3_buffer.pop(self.datac3_nin) self.datac3_buffer.pop(self.datac3_nin)
@ -344,8 +349,9 @@ class RF():
if nbytes == self.datac3_bytes_per_frame: if nbytes == self.datac3_bytes_per_frame:
self.dataqueue.put([self.datac3_bytes_out, self.datac3_freedv ,self.datac3_bytes_per_frame]) self.dataqueue.put([self.datac3_bytes_out, self.datac3_freedv ,self.datac3_bytes_per_frame])
self.get_scatter(self.datac3_freedv) self.get_scatter(self.datac3_freedv)
self.calculate_snr(self.datac3_freedv) self.calculate_snr(self.datac3_freedv)
@ -353,8 +359,11 @@ class RF():
# worker for FIFO queue for processing received frames # worker for FIFO queue for processing received frames
def worker(self): def worker(self):
while True: while True:
time.sleep(0.1) time.sleep(0.01)
data = self.dataqueue.get() data = self.dataqueue.get()
# data[0] = bytes_out
# data[1] = freedv session
# data[2] = bytes_per_frame
self.process_data(data[0], data[1], data[2]) self.process_data(data[0], data[1], data[2])
self.dataqueue.task_done() self.dataqueue.task_done()
@ -366,7 +375,7 @@ class RF():
# we could also create an own function, which returns True. # we could also create an own function, which returns True.
def process_data(self, bytes_out, freedv, bytes_per_frame): def process_data(self, bytes_out, freedv, bytes_per_frame):
if bytes(bytes_out[1:2]) == static.MYCALLSIGN_CRC8 or bytes(bytes_out[6:7]) == static.MYCALLSIGN_CRC8 or bytes(bytes_out[1:2]) == b'\x01': if bytes(bytes_out[1:2]) == static.MYCALLSIGN_CRC8 or bytes(bytes_out[3:4]) == static.MYCALLSIGN_CRC8 or bytes(bytes_out[1:2]) == b'\x01':
# CHECK IF FRAMETYPE IS BETWEEN 10 and 50 ------------------------ # CHECK IF FRAMETYPE IS BETWEEN 10 and 50 ------------------------
frametype = int.from_bytes(bytes(bytes_out[:1]), "big") frametype = int.from_bytes(bytes(bytes_out[:1]), "big")
@ -378,39 +387,47 @@ class RF():
#print("Freq-Offset: " + str(frequency_offset)) #print("Freq-Offset: " + str(frequency_offset))
if 50 >= frametype >= 10: if 50 >= frametype >= 10:
# get snr of received data
snr = self.calculate_snr(freedv)
structlog.get_logger("structlog").debug("[TNC] RX SNR", snr=snr)
# send payload data to arq checker without CRC16 # send payload data to arq checker without CRC16
data_handler.arq_data_received(bytes(bytes_out[:-2]), bytes_per_frame) data_handler.arq_data_received(bytes(bytes_out[:-2]), bytes_per_frame, snr, freedv)
#print("static.ARQ_RX_BURST_BUFFER.count(None) " + str(static.ARQ_RX_BURST_BUFFER.count(None))) # if we received the last frame of a burst or the last remaining rpt frame, do a modem unsync
if static.RX_BURST_BUFFER.count(None) <= 1: if static.RX_BURST_BUFFER.count(None) <= 1 or (frame+1) == n_frames_per_burst:
logging.debug("FULL BURST BUFFER ---> UNSYNC") structlog.get_logger("structlog").debug(f"LAST FRAME OF BURST --> UNSYNC {frame+1}/{n_frames_per_burst}")
self.c_lib.freedv_set_sync(freedv, 0) self.c_lib.freedv_set_sync(freedv, 0)
# BURST ACK # BURST ACK
elif frametype == 60: elif frametype == 60:
logging.debug("ACK RECEIVED....") structlog.get_logger("structlog").debug("ACK RECEIVED....")
data_handler.burst_ack_received()
data_handler.burst_ack_received(bytes_out[:-2])
# FRAME ACK # FRAME ACK
elif frametype == 61: elif frametype == 61:
logging.debug("FRAME ACK RECEIVED....") structlog.get_logger("structlog").debug("FRAME ACK RECEIVED....")
data_handler.frame_ack_received() data_handler.frame_ack_received()
# FRAME RPT # FRAME RPT
elif frametype == 62: elif frametype == 62:
logging.debug("REPEAT REQUEST RECEIVED....") structlog.get_logger("structlog").debug("REPEAT REQUEST RECEIVED....")
data_handler.burst_rpt_received(bytes_out[:-2]) data_handler.burst_rpt_received(bytes_out[:-2])
# FRAME NACK
elif frametype == 63:
structlog.get_logger("structlog").debug("FRAME NOT ACK RECEIVED....")
data_handler.frame_nack_received(bytes_out[:-2])
# CQ FRAME # CQ FRAME
elif frametype == 200: elif frametype == 200:
logging.debug("CQ RECEIVED....") structlog.get_logger("structlog").debug("CQ RECEIVED....")
data_handler.received_cq(bytes_out[:-2]) data_handler.received_cq(bytes_out[:-2])
# PING FRAME # PING FRAME
elif frametype == 210: elif frametype == 210:
logging.debug("PING RECEIVED....") structlog.get_logger("structlog").debug("PING RECEIVED....")
frequency_offset = self.get_frequency_offset(freedv) frequency_offset = self.get_frequency_offset(freedv)
#print("Freq-Offset: " + str(frequency_offset)) #print("Freq-Offset: " + str(frequency_offset))
data_handler.received_ping(bytes_out[:-2], frequency_offset) data_handler.received_ping(bytes_out[:-2], frequency_offset)
@ -418,7 +435,7 @@ class RF():
# PING ACK # PING ACK
elif frametype == 211: elif frametype == 211:
logging.debug("PING ACK RECEIVED....") structlog.get_logger("structlog").debug("PING ACK RECEIVED....")
# early detection of frequency offset # early detection of frequency offset
#frequency_offset = int.from_bytes(bytes(bytes_out[9:11]), "big", signed=True) #frequency_offset = int.from_bytes(bytes(bytes_out[9:11]), "big", signed=True)
#print("Freq-Offset: " + str(frequency_offset)) #print("Freq-Offset: " + str(frequency_offset))
@ -433,19 +450,21 @@ class RF():
# ARQ FILE TRANSFER RECEIVED! # ARQ FILE TRANSFER RECEIVED!
elif frametype == 225: elif frametype == 225:
logging.debug("ARQ arq_received_data_channel_opener") structlog.get_logger("structlog").debug("ARQ arq_received_data_channel_opener")
data_handler.arq_received_data_channel_opener(bytes_out[:-2]) data_handler.arq_received_data_channel_opener(bytes_out[:-2])
# ARQ CHANNEL IS OPENED # ARQ CHANNEL IS OPENED
elif frametype == 226: elif frametype == 226:
logging.debug("ARQ arq_received_channel_is_open") structlog.get_logger("structlog").debug("ARQ arq_received_channel_is_open")
data_handler.arq_received_channel_is_open(bytes_out[:-2]) data_handler.arq_received_channel_is_open(bytes_out[:-2])
# ARQ CONNECT ACK / KEEP ALIVE # ARQ CONNECT ACK / KEEP ALIVE
# this is outdated and we may remove it
elif frametype == 230: elif frametype == 230:
logging.debug("BEACON RECEIVED") structlog.get_logger("structlog").debug("BEACON RECEIVED")
data_handler.received_beacon(bytes_out[:-2]) data_handler.received_beacon(bytes_out[:-2])
# TESTFRAMES
elif frametype == 255: elif frametype == 255:
structlog.get_logger("structlog").debug("TESTFRAME RECEIVED", frame=bytes_out[:]) structlog.get_logger("structlog").debug("TESTFRAME RECEIVED", frame=bytes_out[:])
@ -455,6 +474,7 @@ class RF():
# DO UNSYNC AFTER LAST BURST by checking the frame nums against the total frames per burst # DO UNSYNC AFTER LAST BURST by checking the frame nums against the total frames per burst
# this should be changed to a timeout based unsync
if frame == n_frames_per_burst: if frame == n_frames_per_burst:
logging.info("LAST FRAME ---> UNSYNC") logging.info("LAST FRAME ---> UNSYNC")
self.c_lib.freedv_set_sync(freedv, 0) # FORCE UNSYNC self.c_lib.freedv_set_sync(freedv, 0) # FORCE UNSYNC
@ -508,11 +528,13 @@ class RF():
self.c_lib.freedv_get_modem_stats(freedv, byref( self.c_lib.freedv_get_modem_stats(freedv, byref(
modem_stats_sync), byref(modem_stats_snr)) modem_stats_sync), byref(modem_stats_snr))
modem_stats_snr = modem_stats_snr.value modem_stats_snr = modem_stats_snr.value
try: try:
static.SNR = round(modem_stats_snr, 1) static.SNR = round(modem_stats_snr, 1)
return static.SNR
except: except:
static.SNR = 0 static.SNR = 0
return static.SNR
def update_rig_data(self): def update_rig_data(self):
while True: while True:
@ -553,3 +575,13 @@ class RF():
static.FFT = [0] * 320 static.FFT = [0] * 320
else: else:
pass pass
def get_bytes_per_frame(self, mode):
freedv = cast(codec2.api.freedv_open(mode), c_void_p)
# get number of bytes per frame for mode
return int(codec2.api.freedv_get_bits_per_modem_frame(freedv)/8)
def set_frames_per_burst(self, n_frames_per_burst):
codec2.api.freedv_set_frames_per_burst(self.datac1_freedv,n_frames_per_burst)
codec2.api.freedv_set_frames_per_burst(self.datac3_freedv,n_frames_per_burst)

View file

@ -31,6 +31,7 @@ import time
import static import static
import data_handler import data_handler
import helpers import helpers
import sys import sys
@ -121,7 +122,7 @@ class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):
PING_THREAD = threading.Thread(target=data_handler.transmit_ping, args=[dxcallsign], name="PING") PING_THREAD = threading.Thread(target=data_handler.transmit_ping, args=[dxcallsign], name="PING")
PING_THREAD.start() PING_THREAD.start()
# and static.ARQ_READY_FOR_DATA == True: # and static.ARQ_STATE == 'CONNECTED' :
if received_json["type"] == 'ARQ' and received_json["command"] == "sendFile": if received_json["type"] == 'ARQ' and received_json["command"] == "sendFile":
static.TNC_STATE = 'BUSY' static.TNC_STATE = 'BUSY'
@ -191,7 +192,7 @@ class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):
print(" >>> STOPPING TRANSMISSION <<<") print(" >>> STOPPING TRANSMISSION <<<")
structlog.get_logger("structlog").warning("[TNC] Stopping transmission!") structlog.get_logger("structlog").warning("[TNC] Stopping transmission!")
static.TNC_STATE = 'IDLE' static.TNC_STATE = 'IDLE'
static.ARQ_STATE = 'IDLE' static.ARQ_STATE = False
# SETTINGS AND STATUS --------------------------------------------- # SETTINGS AND STATUS ---------------------------------------------
@ -248,6 +249,7 @@ class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):
"RX_MSG_BUFFER_LENGTH": str(len(static.RX_MSG_BUFFER)), "RX_MSG_BUFFER_LENGTH": str(len(static.RX_MSG_BUFFER)),
"ARQ_BYTES_PER_MINUTE": str(static.ARQ_BYTES_PER_MINUTE), "ARQ_BYTES_PER_MINUTE": str(static.ARQ_BYTES_PER_MINUTE),
"ARQ_BYTES_PER_MINUTE_BURST": str(static.ARQ_BYTES_PER_MINUTE_BURST), "ARQ_BYTES_PER_MINUTE_BURST": str(static.ARQ_BYTES_PER_MINUTE_BURST),
"ARQ_COMPRESSION_FACTOR": str(static.ARQ_COMPRESSION_FACTOR),
"ARQ_TRANSMISSION_PERCENT": str(static.ARQ_TRANSMISSION_PERCENT), "ARQ_TRANSMISSION_PERCENT": str(static.ARQ_TRANSMISSION_PERCENT),
"TOTAL_BYTES": str(static.TOTAL_BYTES), "TOTAL_BYTES": str(static.TOTAL_BYTES),
"INFO" : static.INFO, "INFO" : static.INFO,
@ -322,8 +324,7 @@ class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):
print(exc_type, fname, exc_tb.tb_lineno) print(exc_type, fname, exc_tb.tb_lineno)
print("############ END OF ERROR #######################") print("############ END OF ERROR #######################")
print("reset of connection...") structlog.get_logger("structlog").warning("[TNC] reset of tcp/ip connection...")
structlog.get_logger("structlog").warning("[TNC] Stopping transmission!")
#socketTimeout = 0 #socketTimeout = 0
structlog.get_logger("structlog").error("[TNC] Network error", e = sys.exc_info()[0]) structlog.get_logger("structlog").error("[TNC] Network error", e = sys.exc_info()[0])

View file

@ -72,12 +72,14 @@ ARQ_BYTES_PER_MINUTE_BURST = 0
ARQ_BYTES_PER_MINUTE = 0 ARQ_BYTES_PER_MINUTE = 0
ARQ_BITS_PER_SECOND_BURST = 0 ARQ_BITS_PER_SECOND_BURST = 0
ARQ_BITS_PER_SECOND = 0 ARQ_BITS_PER_SECOND = 0
ARQ_COMPRESSION_FACTOR = 0
ARQ_TRANSMISSION_PERCENT = 0 ARQ_TRANSMISSION_PERCENT = 0
TOTAL_BYTES = 0 TOTAL_BYTES = 0
#CHANNEL_STATE = 'RECEIVING_SIGNALLING' #CHANNEL_STATE = 'RECEIVING_SIGNALLING'
TNC_STATE = 'IDLE' TNC_STATE = 'IDLE'
ARQ_STATE = 'IDLE' ARQ_STATE = False
# BEACON STATE # BEACON STATE
BEACON_STATE = False BEACON_STATE = False
@ -86,7 +88,7 @@ BEACON_STATE = False
RX_BUFFER = [] RX_BUFFER = []
RX_MSG_BUFFER = [] RX_MSG_BUFFER = []
RX_BURST_BUFFER = [] RX_BURST_BUFFER = []
RX_FRAME_BUFFER = [] RX_FRAME_BUFFER = b''
#RX_BUFFER_SIZE = 0 #RX_BUFFER_SIZE = 0
# ------- HEARD STATIOS BUFFER # ------- HEARD STATIOS BUFFER