From d992fd8dc0de83c81cc4405e80f87016cd3c1759 Mon Sep 17 00:00:00 2001 From: DJ2LS <75909252+DJ2LS@users.noreply.github.com> Date: Mon, 23 May 2022 13:11:16 +0200 Subject: [PATCH] Second run reducing number of problems --- tnc/helpers.py | 37 +++++++----- tnc/main.py | 7 ++- tnc/modem.py | 150 +++++++++++++++++++++++++++++-------------------- tnc/rig.py | 12 ++-- tnc/rigctl.py | 8 +-- tnc/rigctld.py | 4 +- tnc/sock.py | 141 +++++++++++++++++++++++++--------------------- tnc/static.py | 14 ++--- 8 files changed, 211 insertions(+), 162 deletions(-) diff --git a/tnc/helpers.py b/tnc/helpers.py index 57697f8a..c29ab467 100644 --- a/tnc/helpers.py +++ b/tnc/helpers.py @@ -80,9 +80,13 @@ def get_crc_24(data) -> bytes: Returns: CRC-24 (OpenPGP) of the provided data as bytes """ - crc_algorithm = crcengine.create(0x864cfb, 24, 0xb704ce, ref_in=False, - ref_out=False, xor_out=0, - name='crc-24-openpgp') + crc_algorithm = crcengine.create(0x864cfb, + 24, + 0xb704ce, + ref_in=False, + ref_out=False, + xor_out=0, + name='crc-24-openpgp') crc_data = crc_algorithm(data) crc_data = crc_data.to_bytes(3, byteorder='big') return crc_data @@ -136,6 +140,7 @@ def add_to_heard_stations(dxcallsign, dxgrid, datatype, snr, offset, frequency): static.HEARD_STATIONS.append([dxcallsign, dxgrid, int(time.time()), datatype, snr, offset, frequency]) break + # for idx, item in enumerate(static.HEARD_STATIONS): # if dxcallsign in item: # item = [dxcallsign, int(time.time())] @@ -174,7 +179,6 @@ def callsign_to_bytes(callsign) -> bytes: callsign = bytes(callsign, 'utf-8') except TypeError as e: structlog.get_logger("structlog").debug("[HLP] callsign_to_bytes: Exception converting callsign to bytes:", e=e) - pass # Need this step to reduce the needed payload by the callsign (stripping "-" out of the callsign) callsign = callsign.split(b'-') @@ -195,6 +199,7 @@ def callsign_to_bytes(callsign) -> bytes: return encode_call(callsign + ssid) # return bytes(bytestring) + def bytes_to_callsign(bytestring: bytes) -> bytes: """ Convert our callsign, received by a frame to a callsign in a human readable format @@ -242,7 +247,7 @@ def bytes_to_callsign(bytestring: bytes) -> bytes: return bytes(f"{callsign}-{ssid}", "utf-8") -def check_callsign(callsign:bytes, crc_to_check:bytes): +def check_callsign(callsign: bytes, crc_to_check: bytes): """ Funktion to check a crc against a callsign to calculate the ssid by generating crc until we got it @@ -288,30 +293,31 @@ def encode_grid(grid): """ out_code_word = 0 - grid = grid.upper() # upper case to be save + grid = grid.upper() # upper case to be save int_first = ord(grid[0]) - 65 # -65 offset for 'A' become zero, utf8 table int_sec = ord(grid[1]) - 65 # -65 offset for 'A' become zero, utf8 table - int_val = (int_first * 18) + int_sec # encode for modulo devision, 2 numbers in 1 + int_val = (int_first * 18) + int_sec # encode for modulo devision, 2 numbers in 1 - out_code_word = (int_val & 0b111111111) # only 9 bit LSB A - R * A - R is needed + out_code_word = (int_val & 0b111111111) # only 9 bit LSB A - R * A - R is needed out_code_word <<= 9 # shift 9 bit left having space next bits, letter A-R * A-R int_val = int(grid[2:4]) # number string to number int, highest value 99 - out_code_word |= (int_val & 0b1111111) # using bit OR to add new value + out_code_word |= (int_val & 0b1111111) # using bit OR to add new value out_code_word <<= 7 # shift 7 bit left having space next bits, letter A-X int_val = ord(grid[4]) - 65 # -65 offset for 'A' become zero, utf8 table - out_code_word |= (int_val & 0b11111) # using bit OR to add new value + out_code_word |= (int_val & 0b11111) # using bit OR to add new value out_code_word <<= 5 # shift 5 bit left having space next bits, letter A-X int_val = ord(grid[5]) - 65 # -65 offset for 'A' become zero, utf8 table - out_code_word |= (int_val & 0b11111) # using bit OR to add new value + out_code_word |= (int_val & 0b11111) # using bit OR to add new value return out_code_word.to_bytes(length=4, byteorder='big') -def decode_grid(b_code_word:bytes): + +def decode_grid(b_code_word: bytes): """ @author: DB1UJ Args: @@ -340,6 +346,7 @@ def decode_grid(b_code_word:bytes): return grid + def encode_call(call): """ @author: DB1UJ @@ -351,7 +358,7 @@ def encode_call(call): """ out_code_word = 0 - call = call.upper() # upper case to be save + call = call.upper() # upper case to be save for x in call: int_val = ord(x) - 48 # -48 reduce bits, begin with first number utf8 table @@ -364,7 +371,7 @@ def encode_call(call): return out_code_word.to_bytes(length=6, byteorder='big') -def decode_call(b_code_word:bytes): +def decode_call(b_code_word: bytes): """ @author: DB1UJ Args: @@ -378,7 +385,7 @@ def decode_call(b_code_word:bytes): call = str() while code_word != 0: - call = chr((code_word & 0b111111)+48) + call + call = chr((code_word & 0b111111) + 48) + call code_word >>= 6 call = call[:-1] + ssid # remove the last char from call and replace with SSID diff --git a/tnc/main.py b/tnc/main.py index 6e08dfbd..f7ceb795 100755 --- a/tnc/main.py +++ b/tnc/main.py @@ -24,7 +24,7 @@ import log_handler import modem import static -# signal handler for closing aplication + def signal_handler(sig, frame): """ a signal handler, which closes the network/socket when closing the application @@ -39,15 +39,16 @@ def signal_handler(sig, frame): sock.CLOSE_SIGNAL = True sys.exit(0) + signal.signal(signal.SIGINT, signal_handler) if __name__ == '__main__': - # we need to run this on windows for multiprocessing support + # we need to run this on Windows for multiprocessing support multiprocessing.freeze_support() # --------------------------------------------GET PARAMETER INPUTS PARSER = argparse.ArgumentParser(description='FreeDATA TNC') PARSER.add_argument('--mycall', dest="mycall", default="AA0AA", help="My callsign", type=str) - PARSER.add_argument('--ssid', dest="ssid_list", nargs='*', default=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15], help="SSID list we are responding to", type=str) + PARSER.add_argument('--ssid', dest="ssid_list", nargs='*', default=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ,11 ,12 ,13 ,14 ,15 ], help="SSID list we are responding to", type=str) PARSER.add_argument('--mygrid', dest="mygrid", default="JN12AA", help="My gridsquare", type=str) PARSER.add_argument('--rx', dest="audio_input_device", default=0, help="listening sound card", type=int) PARSER.add_argument('--tx', dest="audio_output_device", default=0, help="transmitting sound card", type=int) diff --git a/tnc/modem.py b/tnc/modem.py index 5a44d8fa..15d58e82 100644 --- a/tnc/modem.py +++ b/tnc/modem.py @@ -10,11 +10,8 @@ Created on Wed Dec 23 07:04:24 2020 import atexit import ctypes -import logging import os -import pathlib import queue -import re import sys import threading import time @@ -25,11 +22,9 @@ import sounddevice as sd import structlog import ujson as json -import audio +# import audio import codec2 import data_handler -import helpers -import log_handler import sock import static @@ -47,8 +42,10 @@ RECEIVE_DATAC1 = False RECEIVE_DATAC3 = False RECEIVE_FSK_LDPC_1 = False -class RF(): + +class RF: """ """ + def __init__(self): self.sampler_avg = 0 @@ -86,41 +83,51 @@ class RF(): # Open codec2 instances self.datac0_freedv = ctypes.cast(codec2.api.freedv_open(codec2.api.FREEDV_MODE_DATAC0), ctypes.c_void_p) - self.c_lib.freedv_set_tuning_range(self.datac0_freedv, ctypes.c_float(static.TUNING_RANGE_FMIN), ctypes.c_float(static.TUNING_RANGE_FMAX)) + self.c_lib.freedv_set_tuning_range(self.datac0_freedv, ctypes.c_float(static.TUNING_RANGE_FMIN), + ctypes.c_float(static.TUNING_RANGE_FMAX)) self.datac0_bytes_per_frame = int(codec2.api.freedv_get_bits_per_modem_frame(self.datac0_freedv) / 8) self.datac0_payload_per_frame = self.datac0_bytes_per_frame - 2 self.datac0_n_nom_modem_samples = self.c_lib.freedv_get_n_nom_modem_samples(self.datac0_freedv) self.datac0_n_tx_modem_samples = self.c_lib.freedv_get_n_tx_modem_samples(self.datac0_freedv) self.datac0_n_tx_preamble_modem_samples = self.c_lib.freedv_get_n_tx_preamble_modem_samples(self.datac0_freedv) - self.datac0_n_tx_postamble_modem_samples = self.c_lib.freedv_get_n_tx_postamble_modem_samples(self.datac0_freedv) + self.datac0_n_tx_postamble_modem_samples = self.c_lib.freedv_get_n_tx_postamble_modem_samples( + self.datac0_freedv) self.datac0_bytes_out = ctypes.create_string_buffer(self.datac0_bytes_per_frame) codec2.api.freedv_set_frames_per_burst(self.datac0_freedv, 1) - self.datac0_buffer = codec2.audio_buffer(2*self.AUDIO_FRAMES_PER_BUFFER_RX) + self.datac0_buffer = codec2.audio_buffer(2 * self.AUDIO_FRAMES_PER_BUFFER_RX) self.datac1_freedv = ctypes.cast(codec2.api.freedv_open(codec2.api.FREEDV_MODE_DATAC1), ctypes.c_void_p) - self.c_lib.freedv_set_tuning_range(self.datac1_freedv, ctypes.c_float(static.TUNING_RANGE_FMIN), ctypes.c_float(static.TUNING_RANGE_FMAX)) + self.c_lib.freedv_set_tuning_range(self.datac1_freedv, ctypes.c_float(static.TUNING_RANGE_FMIN), + ctypes.c_float(static.TUNING_RANGE_FMAX)) self.datac1_bytes_per_frame = int(codec2.api.freedv_get_bits_per_modem_frame(self.datac1_freedv) / 8) self.datac1_bytes_out = ctypes.create_string_buffer(self.datac1_bytes_per_frame) codec2.api.freedv_set_frames_per_burst(self.datac1_freedv, 1) - self.datac1_buffer = codec2.audio_buffer(2*self.AUDIO_FRAMES_PER_BUFFER_RX) + self.datac1_buffer = codec2.audio_buffer(2 * self.AUDIO_FRAMES_PER_BUFFER_RX) self.datac3_freedv = ctypes.cast(codec2.api.freedv_open(codec2.api.FREEDV_MODE_DATAC3), ctypes.c_void_p) - self.c_lib.freedv_set_tuning_range(self.datac3_freedv, ctypes.c_float(static.TUNING_RANGE_FMIN), ctypes.c_float(static.TUNING_RANGE_FMAX)) + self.c_lib.freedv_set_tuning_range(self.datac3_freedv, ctypes.c_float(static.TUNING_RANGE_FMIN), + ctypes.c_float(static.TUNING_RANGE_FMAX)) self.datac3_bytes_per_frame = int(codec2.api.freedv_get_bits_per_modem_frame(self.datac3_freedv) / 8) self.datac3_bytes_out = ctypes.create_string_buffer(self.datac3_bytes_per_frame) codec2.api.freedv_set_frames_per_burst(self.datac3_freedv, 1) - self.datac3_buffer = codec2.audio_buffer(2*self.AUDIO_FRAMES_PER_BUFFER_RX) + self.datac3_buffer = codec2.audio_buffer(2 * self.AUDIO_FRAMES_PER_BUFFER_RX) - self.fsk_ldpc_freedv_0 = ctypes.cast(codec2.api.freedv_open_advanced(codec2.api.FREEDV_MODE_FSK_LDPC, ctypes.byref(codec2.api.FREEDV_MODE_FSK_LDPC_0_ADV)), ctypes.c_void_p) + self.fsk_ldpc_freedv_0 = ctypes.cast(codec2.api.freedv_open_advanced(codec2.api.FREEDV_MODE_FSK_LDPC, + ctypes.byref( + codec2.api.FREEDV_MODE_FSK_LDPC_0_ADV)), + ctypes.c_void_p) self.fsk_ldpc_bytes_per_frame_0 = int(codec2.api.freedv_get_bits_per_modem_frame(self.fsk_ldpc_freedv_0) / 8) self.fsk_ldpc_bytes_out_0 = ctypes.create_string_buffer(self.fsk_ldpc_bytes_per_frame_0) - #codec2.api.freedv_set_frames_per_burst(self.fsk_ldpc_freedv_0, 1) + # codec2.api.freedv_set_frames_per_burst(self.fsk_ldpc_freedv_0, 1) self.fsk_ldpc_buffer_0 = codec2.audio_buffer(self.AUDIO_FRAMES_PER_BUFFER_RX) - self.fsk_ldpc_freedv_1 = ctypes.cast(codec2.api.freedv_open_advanced(codec2.api.FREEDV_MODE_FSK_LDPC, ctypes.byref(codec2.api.FREEDV_MODE_FSK_LDPC_1_ADV)), ctypes.c_void_p) + self.fsk_ldpc_freedv_1 = ctypes.cast(codec2.api.freedv_open_advanced(codec2.api.FREEDV_MODE_FSK_LDPC, + ctypes.byref( + codec2.api.FREEDV_MODE_FSK_LDPC_1_ADV)), + ctypes.c_void_p) self.fsk_ldpc_bytes_per_frame_1 = int(codec2.api.freedv_get_bits_per_modem_frame(self.fsk_ldpc_freedv_1) / 8) self.fsk_ldpc_bytes_out_1 = ctypes.create_string_buffer(self.fsk_ldpc_bytes_per_frame_1) - #codec2.api.freedv_set_frames_per_burst(self.fsk_ldpc_freedv_0, 1) + # codec2.api.freedv_set_frames_per_burst(self.fsk_ldpc_freedv_0, 1) self.fsk_ldpc_buffer_1 = codec2.audio_buffer(self.AUDIO_FRAMES_PER_BUFFER_RX) # initial nin values @@ -132,7 +139,9 @@ class RF(): # --------------------------------------------CREATE PYAUDIO INSTANCE if not TESTMODE: try: - self.stream = sd.RawStream(channels=1, dtype='int16', callback=self.callback, device=(static.AUDIO_INPUT_DEVICE, static.AUDIO_OUTPUT_DEVICE), samplerate = self.AUDIO_SAMPLE_RATE_RX, blocksize=4800) + self.stream = sd.RawStream(channels=1, dtype='int16', callback=self.callback, + device=(static.AUDIO_INPUT_DEVICE, static.AUDIO_OUTPUT_DEVICE), + samplerate=self.AUDIO_SAMPLE_RATE_RX, blocksize=4800) atexit.register(self.stream.stop) structlog.get_logger("structlog").info("[MDM] init: opened audio devices") @@ -142,7 +151,7 @@ class RF(): try: structlog.get_logger("structlog").debug("[MDM] init: starting pyaudio callback") - #self.audio_stream.start_stream() + # self.audio_stream.start_stream() self.stream.start() except Exception as e: @@ -152,6 +161,7 @@ class RF(): # create a stream object for simulating audio stream class Object(object): pass + self.stream = Object() self.stream.active = True @@ -161,12 +171,13 @@ class RF(): os.mkfifo(TXCHANNEL) except Exception as e: structlog.get_logger("structlog").error(f"[MDM] init:mkfifo: Exception: {e}") - pass - mkfifo_write_callback_thread = threading.Thread(target=self.mkfifo_write_callback, name="MKFIFO WRITE CALLBACK THREAD",daemon=True) + mkfifo_write_callback_thread = threading.Thread(target=self.mkfifo_write_callback, + name="MKFIFO WRITE CALLBACK THREAD", daemon=True) mkfifo_write_callback_thread.start() - mkfifo_read_callback_thread = threading.Thread(target=self.mkfifo_read_callback, name="MKFIFO READ CALLBACK THREAD",daemon=True) + mkfifo_read_callback_thread = threading.Thread(target=self.mkfifo_read_callback, + name="MKFIFO READ CALLBACK THREAD", daemon=True) mkfifo_read_callback_thread.start() # --------------------------------------------INIT AND OPEN HAMLIB @@ -183,7 +194,11 @@ class RF(): import rigdummy as rig self.hamlib = rig.radio() - self.hamlib.open_rig(devicename=static.HAMLIB_DEVICE_NAME, deviceport=static.HAMLIB_DEVICE_PORT, hamlib_ptt_type=static.HAMLIB_PTT_TYPE, serialspeed=static.HAMLIB_SERIAL_SPEED, pttport=static.HAMLIB_PTT_PORT, data_bits=static.HAMLIB_DATA_BITS, stop_bits=static.HAMLIB_STOP_BITS, handshake=static.HAMLIB_HANDSHAKE, rigctld_ip = static.HAMLIB_RIGCTLD_IP, rigctld_port = static.HAMLIB_RIGCTLD_PORT) + self.hamlib.open_rig(devicename=static.HAMLIB_DEVICE_NAME, deviceport=static.HAMLIB_DEVICE_PORT, + hamlib_ptt_type=static.HAMLIB_PTT_TYPE, serialspeed=static.HAMLIB_SERIAL_SPEED, + pttport=static.HAMLIB_PTT_PORT, data_bits=static.HAMLIB_DATA_BITS, + stop_bits=static.HAMLIB_STOP_BITS, handshake=static.HAMLIB_HANDSHAKE, + rigctld_ip=static.HAMLIB_RIGCTLD_IP, rigctld_port=static.HAMLIB_RIGCTLD_PORT) # --------------------------------------------START DECODER THREAD if static.ENABLE_FFT: @@ -200,10 +215,12 @@ class RF(): audio_thread_datac3.start() if static.ENABLE_FSK: - audio_thread_fsk_ldpc0 = threading.Thread(target=self.audio_fsk_ldpc_0, name="AUDIO_THREAD FSK LDPC0", daemon=True) + audio_thread_fsk_ldpc0 = threading.Thread(target=self.audio_fsk_ldpc_0, name="AUDIO_THREAD FSK LDPC0", + daemon=True) audio_thread_fsk_ldpc0.start() - audio_thread_fsk_ldpc1 = threading.Thread(target=self.audio_fsk_ldpc_1, name="AUDIO_THREAD FSK LDPC1", daemon=True) + audio_thread_fsk_ldpc1 = threading.Thread(target=self.audio_fsk_ldpc_1, name="AUDIO_THREAD FSK LDPC1", + daemon=True) audio_thread_fsk_ldpc1.start() hamlib_thread = threading.Thread(target=self.update_rig_data, name="HAMLIB_THREAD", daemon=True) @@ -235,10 +252,10 @@ class RF(): self.datac0_buffer.push(x) if not self.datac1_buffer.nbuffer + length_x > self.datac1_buffer.size and RECEIVE_DATAC1: - self.datac1_buffer.push(x) + self.datac1_buffer.push(x) if not self.datac3_buffer.nbuffer + length_x > self.datac3_buffer.size and RECEIVE_DATAC3: - self.datac3_buffer.push(x) + self.datac3_buffer.push(x) def mkfifo_write_callback(self): while 1: @@ -246,12 +263,11 @@ class RF(): # -----write if len(self.modoutqueue) <= 0 or self.mod_out_locked: - #data_out48k = np.zeros(self.AUDIO_FRAMES_PER_BUFFER_RX, dtype=np.int16) + # data_out48k = np.zeros(self.AUDIO_FRAMES_PER_BUFFER_RX, dtype=np.int16) pass else: data_out48k = self.modoutqueue.popleft() - #print(len(data_out48k)) fifo_write = open(TXCHANNEL, 'wb') fifo_write.write(data_out48k) @@ -312,7 +328,7 @@ class RF(): static.BUFFER_OVERFLOW_COUNTER[4] += 1 if len(self.modoutqueue) <= 0 or self.mod_out_locked: - # if not self.modoutqueue or self.mod_out_locked: + data_out48k = np.zeros(frames, dtype=np.int16) self.fft_data = x else: @@ -343,7 +359,7 @@ class RF(): static.TRANSMITTING = True # Toggle ptt early to save some time and send ptt state via socket static.PTT_STATE = self.hamlib.set_ptt(True) - jsondata = {"ptt":"True"} + jsondata = {"ptt": "True"} data_out = json.dumps(jsondata) sock.SOCKET_QUEUE.put(data_out) @@ -390,12 +406,13 @@ class RF(): # Create crc for data frame - we are using the crc function shipped with codec2 to avoid # CRC algorithm incompatibilities - crc = ctypes.c_ushort(codec2.api.freedv_gen_crc16(bytes(buffer), payload_bytes_per_frame)) # Generate CRC16 + crc = ctypes.c_ushort( + codec2.api.freedv_gen_crc16(bytes(buffer), payload_bytes_per_frame)) # Generate CRC16 crc = crc.value.to_bytes(2, byteorder='big') # Convert crc to 2 byte hex string buffer += crc # Append crc16 to 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 txbuffer += bytes(mod_out) # codec2 fsk postamble may be broken - at least it sounds like that so we are disabling it for testing @@ -421,14 +438,14 @@ class RF(): self.mod_out_locked = False # ------------------------------- - chunk_length = self.AUDIO_FRAMES_PER_BUFFER_TX #4800 - chunk = [txbuffer_48k[i:i+chunk_length] for i in range(0, len(txbuffer_48k), chunk_length)] + chunk_length = self.AUDIO_FRAMES_PER_BUFFER_TX # 4800 + chunk = [txbuffer_48k[i:i + chunk_length] for i in range(0, len(txbuffer_48k), chunk_length)] for c in chunk: if len(c) < chunk_length: delta = chunk_length - len(c) delta_zeros = np.zeros(delta, dtype=np.int16) c = np.append(c, delta_zeros) - #structlog.get_logger("structlog").debug("[MDM] mod out shorter than audio buffer", delta=delta) + # structlog.get_logger("structlog").debug("[MDM] mod out shorter than audio buffer", delta=delta) self.modoutqueue.append(c) @@ -441,7 +458,7 @@ class RF(): static.PTT_STATE = self.hamlib.set_ptt(False) # Push ptt state to socket stream - jsondata = {"ptt":"False"} + jsondata = {"ptt": "False"} data_out = json.dumps(jsondata) sock.SOCKET_QUEUE.put(data_out) @@ -460,12 +477,14 @@ class RF(): threading.Event().wait(0.01) while self.datac0_buffer.nbuffer >= self.datac0_nin: # demodulate audio - nbytes_datac0 = codec2.api.freedv_rawdatarx(self.datac0_freedv, self.datac0_bytes_out, self.datac0_buffer.buffer.ctypes) + nbytes_datac0 = 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_nin = codec2.api.freedv_nin(self.datac0_freedv) if nbytes_datac0 == self.datac0_bytes_per_frame: - self.modem_received_queue.put([self.datac0_bytes_out, self.datac0_freedv, self.datac0_bytes_per_frame]) - #self.get_scatter(self.datac0_freedv) + self.modem_received_queue.put( + [self.datac0_bytes_out, self.datac0_freedv, self.datac0_bytes_per_frame]) + # self.get_scatter(self.datac0_freedv) self.calculate_snr(self.datac0_freedv) def audio_datac1(self): @@ -475,12 +494,14 @@ class RF(): threading.Event().wait(0.01) while self.datac1_buffer.nbuffer >= self.datac1_nin: # demodulate audio - nbytes_datac1 = codec2.api.freedv_rawdatarx(self.datac1_freedv, self.datac1_bytes_out, self.datac1_buffer.buffer.ctypes) + nbytes_datac1 = 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_nin = codec2.api.freedv_nin(self.datac1_freedv) if nbytes_datac1 == self.datac1_bytes_per_frame: - self.modem_received_queue.put([self.datac1_bytes_out, self.datac1_freedv, self.datac1_bytes_per_frame]) - #self.get_scatter(self.datac1_freedv) + self.modem_received_queue.put( + [self.datac1_bytes_out, self.datac1_freedv, self.datac1_bytes_per_frame]) + # self.get_scatter(self.datac1_freedv) self.calculate_snr(self.datac1_freedv) def audio_datac3(self): @@ -490,12 +511,14 @@ class RF(): threading.Event().wait(0.01) while self.datac3_buffer.nbuffer >= self.datac3_nin: # demodulate audio - nbytes_datac3 = codec2.api.freedv_rawdatarx(self.datac3_freedv, self.datac3_bytes_out, self.datac3_buffer.buffer.ctypes) + nbytes_datac3 = 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_nin = codec2.api.freedv_nin(self.datac3_freedv) if nbytes_datac3 == self.datac3_bytes_per_frame: - self.modem_received_queue.put([self.datac3_bytes_out, self.datac3_freedv, self.datac3_bytes_per_frame]) - #self.get_scatter(self.datac3_freedv) + self.modem_received_queue.put( + [self.datac3_bytes_out, self.datac3_freedv, self.datac3_bytes_per_frame]) + # self.get_scatter(self.datac3_freedv) self.calculate_snr(self.datac3_freedv) def audio_fsk_ldpc_0(self): @@ -505,12 +528,14 @@ class RF(): threading.Event().wait(0.01) while self.fsk_ldpc_buffer_0.nbuffer >= self.fsk_ldpc_nin_0: # demodulate audio - nbytes_fsk_ldpc_0 = codec2.api.freedv_rawdatarx(self.fsk_ldpc_freedv_0, self.fsk_ldpc_bytes_out_0, self.fsk_ldpc_buffer_0.buffer.ctypes) + nbytes_fsk_ldpc_0 = codec2.api.freedv_rawdatarx(self.fsk_ldpc_freedv_0, self.fsk_ldpc_bytes_out_0, + self.fsk_ldpc_buffer_0.buffer.ctypes) self.fsk_ldpc_buffer_0.pop(self.fsk_ldpc_nin_0) self.fsk_ldpc_nin_0 = codec2.api.freedv_nin(self.fsk_ldpc_freedv_0) if nbytes_fsk_ldpc_0 == self.fsk_ldpc_bytes_per_frame_0: - self.modem_received_queue.put([self.fsk_ldpc_bytes_out_0, self.fsk_ldpc_freedv_0, self.fsk_ldpc_bytes_per_frame_0]) - #self.get_scatter(self.fsk_ldpc_freedv_0) + self.modem_received_queue.put( + [self.fsk_ldpc_bytes_out_0, self.fsk_ldpc_freedv_0, self.fsk_ldpc_bytes_per_frame_0]) + # self.get_scatter(self.fsk_ldpc_freedv_0) self.calculate_snr(self.fsk_ldpc_freedv_0) def audio_fsk_ldpc_1(self): @@ -520,12 +545,14 @@ class RF(): threading.Event().wait(0.01) while self.fsk_ldpc_buffer_1.nbuffer >= self.fsk_ldpc_nin_1: # demodulate audio - nbytes_fsk_ldpc_1 = codec2.api.freedv_rawdatarx(self.fsk_ldpc_freedv_1, self.fsk_ldpc_bytes_out_1, self.fsk_ldpc_buffer_1.buffer.ctypes) + nbytes_fsk_ldpc_1 = codec2.api.freedv_rawdatarx(self.fsk_ldpc_freedv_1, self.fsk_ldpc_bytes_out_1, + self.fsk_ldpc_buffer_1.buffer.ctypes) self.fsk_ldpc_buffer_1.pop(self.fsk_ldpc_nin_1) self.fsk_ldpc_nin_1 = codec2.api.freedv_nin(self.fsk_ldpc_freedv_1) if nbytes_fsk_ldpc_1 == self.fsk_ldpc_bytes_per_frame_1: - self.modem_received_queue.put([self.fsk_ldpc_bytes_out_1, self.fsk_ldpc_freedv_1, self.fsk_ldpc_bytes_per_frame_1]) - #self.get_scatter(self.fsk_ldpc_freedv_1) + self.modem_received_queue.put( + [self.fsk_ldpc_bytes_out_1, self.fsk_ldpc_freedv_1, self.fsk_ldpc_bytes_per_frame_1]) + # self.get_scatter(self.fsk_ldpc_freedv_1) self.calculate_snr(self.fsk_ldpc_freedv_1) # worker for FIFO queue for processing received frames @@ -536,7 +563,7 @@ class RF(): structlog.get_logger("structlog").debug("[MDM] worker_transmit", mode=data[0]) self.transmit(mode=data[0], repeats=data[1], repeat_delay=data[2], frames=data[3]) - #self.modem_transmit_queue.task_done() + # self.modem_transmit_queue.task_done() # worker for FIFO queue for processing received frames def worker_received(self): @@ -644,7 +671,7 @@ class RF(): channel_busy_delay = 0 while True: - #time.sleep(0.01) + # time.sleep(0.01) threading.Event().wait(0.01) # WE NEED TO OPTIMIZE THIS! @@ -657,7 +684,7 @@ class RF(): # set value 0 to 1 to avoid division by zero fftarray[fftarray == 0] = 1 - dfft = 10.*np.log10(abs(fftarray)) + dfft = 10. * np.log10(abs(fftarray)) # get average of dfft avg = np.mean(dfft) @@ -666,7 +693,7 @@ class RF(): # Data higher than the average must be a signal. Therefore we are setting it to 100 so it will be highlighted # Have to do this when we are not transmitting so our own sending data will not affect this too much if not static.TRANSMITTING: - dfft[dfft>avg+10] = 100 + dfft[dfft > avg + 10] = 100 # Calculate audio max value # static.AUDIO_RMS = np.amax(self.fft_data) @@ -688,7 +715,7 @@ class RF(): dfft = np.around(dfft, 0) dfftlist = dfft.tolist() - static.FFT = dfftlist[:320] #320 --> bandwidth 3000 + static.FFT = dfftlist[:320] # 320 --> bandwidth 3000 except Exception as e: structlog.get_logger("structlog").error(f"[MDM] calculate_fft: Exception: {e}") structlog.get_logger("structlog").debug("[MDM] Setting fft=0") @@ -708,15 +735,18 @@ class RF(): codec2.api.freedv_set_frames_per_burst(self.datac3_freedv, n_frames_per_burst) codec2.api.freedv_set_frames_per_burst(self.fsk_ldpc_freedv_0, n_frames_per_burst) + def open_codec2_instance(mode): """ Return a codec2 instance """ if mode in ['FSK_LDPC_0', 200]: return ctypes.cast(codec2.api.freedv_open_advanced(codec2.api.FREEDV_MODE_FSK_LDPC, - ctypes.byref(codec2.api.FREEDV_MODE_FSK_LDPC_0_ADV)), ctypes.c_void_p) + ctypes.byref(codec2.api.FREEDV_MODE_FSK_LDPC_0_ADV)), + ctypes.c_void_p) if mode in ['FSK_LDPC_1', 201]: return ctypes.cast(codec2.api.freedv_open_advanced(codec2.api.FREEDV_MODE_FSK_LDPC, - ctypes.byref(codec2.api.FREEDV_MODE_FSK_LDPC_1_ADV)), ctypes.c_void_p) + ctypes.byref(codec2.api.FREEDV_MODE_FSK_LDPC_1_ADV)), + ctypes.c_void_p) return ctypes.cast(codec2.api.freedv_open(mode), ctypes.c_void_p) diff --git a/tnc/rig.py b/tnc/rig.py index cdbf879f..cbc960f3 100644 --- a/tnc/rig.py +++ b/tnc/rig.py @@ -23,13 +23,13 @@ try: python_version = str(sys.version_info[0]) + "." + str(sys.version_info[1]) # installation path for Ubuntu 20.04 LTS python modules - #sys.path.append('/usr/local/lib/python'+ python_version +'/site-packages') + # sys.path.append('/usr/local/lib/python'+ python_version +'/site-packages') # installation path for Ubuntu 20.10 + sys.path.append('/usr/local/lib/') # installation path for Suse - sys.path.append('/usr/local/lib64/python'+ python_version +'/site-packages') + sys.path.append('/usr/local/lib64/python' + python_version + '/site-packages') # everything else... not nice, but an attempt to see how its running within app bundle # this is not needed as python will be shipped with app bundle @@ -55,7 +55,7 @@ except Exception as e: structlog.get_logger("structlog").warning("[RIG] Python Hamlib binding not found", error=e) try: structlog.get_logger("structlog").warning("[RIG] Trying to open rigctl") - rigctl = subprocess.Popen("rigctl -V",shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, text=True) + rigctl = subprocess.Popen("rigctl -V", shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, text=True) hamlib_version = rigctl.stdout.readline() hamlib_version = hamlib_version.split(' ') @@ -166,7 +166,7 @@ class radio: elif self.hamlib_ptt_type == 'RIG_PTT_NONE': self.hamlib_ptt_type = Hamlib.RIG_PTT_NONE - else: #self.hamlib_ptt_type == 'RIG_PTT_NONE': + else: # self.hamlib_ptt_type == 'RIG_PTT_NONE': self.hamlib_ptt_type = Hamlib.RIG_PTT_NONE structlog.get_logger("structlog").info("[RIG] Opening...", device=self.devicenumber, path=self.my_rig.get_conf("rig_pathname"), serial_speed=self.my_rig.get_conf("serial_speed"), serial_handshake=self.my_rig.get_conf("serial_handshake"), stop_bits=self.my_rig.get_conf("stop_bits"), data_bits=self.my_rig.get_conf("data_bits"), ptt_pathname=self.my_rig.get_conf("ptt_pathname")) @@ -192,7 +192,7 @@ class radio: # set rig mode to USB # temporarly outcommented because of possible problems. - #self.my_rig.set_mode(Hamlib.RIG_MODE_USB) + # self.my_rig.set_mode(Hamlib.RIG_MODE_USB) # self.my_rig.set_mode(Hamlib.RIG_MODE_PKTUSB) return True @@ -215,7 +215,7 @@ class radio: return bandwith # not needed yet beacuse of some possible problems - #def set_mode(self, mode): + # def set_mode(self, mode): # return 0 def get_ptt(self): diff --git a/tnc/rigctl.py b/tnc/rigctl.py index 319d511a..8115d3e7 100644 --- a/tnc/rigctl.py +++ b/tnc/rigctl.py @@ -54,14 +54,14 @@ class radio: """ self.devicename = devicename self.deviceport = deviceport - self.serialspeed = str(serialspeed) # we need to ensure this is a str, otherwise set_conf functions are crashing + self.serialspeed = str(serialspeed) # we need to ensure this is a str, otherwise set_conf functions are crashing self.hamlib_ptt_type = hamlib_ptt_type self.pttport = pttport self.data_bits = data_bits self.stop_bits = stop_bits self.handshake = handshake - # check if we are running in a pyinstaller environment + # check if we are running in a pyinstaller environment if hasattr(sys, "_MEIPASS"): sys.path.append(getattr(sys, "_MEIPASS")) else: @@ -75,7 +75,7 @@ class radio: if int(self.devicename): self.devicenumber = int(self.devicename) else: - self.devicenumber = 6 #dummy + self.devicenumber = 6 # dummy structlog.get_logger("structlog").warning("[RIGCTL] Radio not found. Using DUMMY!", error=e) # set deviceport to dummy port, if we selected dummy model @@ -179,5 +179,5 @@ class radio: def close_rig(self): """ """ - #self.my_rig.close() + # self.my_rig.close() return diff --git a/tnc/rigctld.py b/tnc/rigctld.py index 422a6e95..0b9e4f43 100644 --- a/tnc/rigctld.py +++ b/tnc/rigctld.py @@ -24,7 +24,7 @@ class radio(): def __init__(self, hostname="localhost", port=4532, poll_rate=5, timeout=5): """ Open a connection to rotctld, and test it for validity """ self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - #self.sock.settimeout(timeout) + # self.sock.settimeout(timeout) self.connected = False self.hostname = hostname @@ -63,7 +63,7 @@ class radio(): """Connect to rigctld instance""" if not self.connected: try: - self.connection = socket.create_connection((self.hostname,self.port)) + self.connection = socket.create_connection((self.hostname, self.port)) self.connected = True structlog.get_logger("structlog").info("[RIGCTLD] Connected to rigctld!", ip=self.hostname, port=self.port) return True diff --git a/tnc/sock.py b/tnc/sock.py index 6b6179b0..f3493785 100644 --- a/tnc/sock.py +++ b/tnc/sock.py @@ -21,22 +21,19 @@ Created on Fri Dec 25 21:25:14 2020 """ import atexit import base64 -import logging -import os + import queue import socketserver import sys import threading import time -import psutil import structlog import ujson as json -import audio import data_handler import helpers -import log_handler + import static SOCKET_QUEUE = queue.Queue() @@ -81,10 +78,10 @@ class ThreadedTCPRequestHandler(socketserver.StreamRequestHandler): while not SOCKET_QUEUE.empty(): data = SOCKET_QUEUE.get() sock_data = bytes(data, 'utf-8') - sock_data += b'\n' # append line limiter + sock_data += b'\n' # append line limiter # send data to all clients - #try: + # try: for client in CONNECTED_CLIENTS: try: client.send(sock_data) @@ -97,7 +94,7 @@ class ThreadedTCPRequestHandler(socketserver.StreamRequestHandler): static.SCATTER = [] # we want to display INFO messages only once static.INFO = [] - #self.request.sendall(sock_data) + # self.request.sendall(sock_data) time.sleep(0.15) def receive_from_client(self): @@ -112,7 +109,7 @@ class ThreadedTCPRequestHandler(socketserver.StreamRequestHandler): data += chunk if chunk == b'': - #print("connection broken. Closing...") + # print("connection broken. Closing...") self.connection_alive = False if data.startswith(b'{') and data.endswith(b'}\n'): @@ -138,7 +135,8 @@ class ThreadedTCPRequestHandler(socketserver.StreamRequestHandler): # finally delete our rx buffer to be ready for new commands data = bytes() except Exception as e: - structlog.get_logger("structlog").info("[SCK] Connection closed", ip=self.client_address[0], port=self.client_address[1], e=e) + structlog.get_logger("structlog").info("[SCK] Connection closed", ip=self.client_address[0], + port=self.client_address[1], e=e) self.connection_alive = False def handle(self): @@ -147,11 +145,12 @@ class ThreadedTCPRequestHandler(socketserver.StreamRequestHandler): """ CONNECTED_CLIENTS.add(self.request) - structlog.get_logger("structlog").debug("[SCK] Client connected", ip=self.client_address[0], port=self.client_address[1]) + structlog.get_logger("structlog").debug("[SCK] Client connected", ip=self.client_address[0], + port=self.client_address[1]) self.connection_alive = True - self.sendThread = threading.Thread(target=self.send_to_client, args=[],daemon=True).start() - self.receiveThread = threading.Thread(target=self.receive_from_client, args=[],daemon=True).start() + self.sendThread = threading.Thread(target=self.send_to_client, args=[], daemon=True).start() + self.receiveThread = threading.Thread(target=self.receive_from_client, args=[], daemon=True).start() # keep connection alive until we close it while self.connection_alive and not CLOSE_SIGNAL: @@ -159,11 +158,14 @@ class ThreadedTCPRequestHandler(socketserver.StreamRequestHandler): def finish(self): """ """ - structlog.get_logger("structlog").warning("[SCK] Closing client socket", ip=self.client_address[0], port=self.client_address[1]) + structlog.get_logger("structlog").warning("[SCK] Closing client socket", ip=self.client_address[0], + port=self.client_address[1]) try: CONNECTED_CLIENTS.remove(self.request) except: - structlog.get_logger("structlog").warning("[SCK] client connection already removed from client list", client=self.request) + structlog.get_logger("structlog").warning("[SCK] client connection already removed from client list", + client=self.request) + def process_tnc_commands(data): """ @@ -346,13 +348,15 @@ def process_tnc_commands(data): } for i in range(len(static.RX_BUFFER)): - #print(static.RX_BUFFER[i][4]) - #rawdata = json.loads(static.RX_BUFFER[i][4]) + # print(static.RX_BUFFER[i][4]) + # rawdata = json.loads(static.RX_BUFFER[i][4]) base64_data = static.RX_BUFFER[i][4] - output["data-array"].append({"uuid": static.RX_BUFFER[i][0],"timestamp": static.RX_BUFFER[i][1], "dxcallsign": str(static.RX_BUFFER[i][2], 'utf-8'), "dxgrid": str(static.RX_BUFFER[i][3], 'utf-8'), "data": base64_data}) + output["data-array"].append({"uuid": static.RX_BUFFER[i][0], "timestamp": static.RX_BUFFER[i][1], + "dxcallsign": str(static.RX_BUFFER[i][2], 'utf-8'), + "dxgrid": str(static.RX_BUFFER[i][3], 'utf-8'), "data": base64_data}) jsondata = json.dumps(output) - #self.request.sendall(bytes(jsondata, encoding)) + # self.request.sendall(bytes(jsondata, encoding)) SOCKET_QUEUE.put(jsondata) command_response("rx_buffer", True) @@ -368,10 +372,11 @@ def process_tnc_commands(data): command_response("del_rx_buffer", False) structlog.get_logger("structlog").warning("[SCK] command execution error", e=e, command=received_json) - # exception, if JSON cant be decoded + # exception, if JSON can't be decoded except Exception as e: structlog.get_logger("structlog").error("[TNC] JSON decoding error", e=e) + def send_tnc_state(): """ send the tnc state to network @@ -401,8 +406,8 @@ def send_tnc_state(): "arq_compression_factor": str(static.ARQ_COMPRESSION_FACTOR), "arq_transmission_percent": str(static.ARQ_TRANSMISSION_PERCENT), "total_bytes": str(static.TOTAL_BYTES), - "info" : static.INFO, - "beacon_state" : str(static.BEACON_STATE), + "info": static.INFO, + "beacon_state": str(static.BEACON_STATE), "stations": [], "mycallsign": str(static.MYCALLSIGN, encoding), "dxcallsign": str(static.DXCALLSIGN, encoding), @@ -422,6 +427,7 @@ def send_tnc_state(): return json.dumps(output) + def process_daemon_commands(data): """ process daemon commands @@ -441,13 +447,15 @@ def process_daemon_commands(data): if bytes(callsign, 'utf-8') == b'': self.request.sendall(b'INVALID CALLSIGN') - structlog.get_logger("structlog").warning("[DMN] SET MYCALL FAILED", call=static.MYCALLSIGN, crc=static.MYCALLSIGN_CRC) + structlog.get_logger("structlog").warning("[DMN] SET MYCALL FAILED", call=static.MYCALLSIGN, + crc=static.MYCALLSIGN_CRC) else: static.MYCALLSIGN = bytes(callsign, 'utf-8') static.MYCALLSIGN_CRC = helpers.get_crc_24(static.MYCALLSIGN) command_response("mycallsign", True) - structlog.get_logger("structlog").info("[DMN] SET MYCALL", call=static.MYCALLSIGN, crc=static.MYCALLSIGN_CRC) + structlog.get_logger("structlog").info("[DMN] SET MYCALL", call=static.MYCALLSIGN, + crc=static.MYCALLSIGN_CRC) except Exception as e: command_response("mycallsign", False) structlog.get_logger("structlog").warning("[SCK] command execution error", e=e, command=received_json) @@ -494,33 +502,34 @@ def process_daemon_commands(data): # print some debugging parameters for item in received_json["parameter"][0]: - structlog.get_logger("structlog").debug("[DMN] TNC Startup Config : " + item, value=received_json["parameter"][0][item]) + structlog.get_logger("structlog").debug("[DMN] TNC Startup Config : " + item, + value=received_json["parameter"][0][item]) DAEMON_QUEUE.put(['STARTTNC', - mycall, - mygrid, - rx_audio, - tx_audio, - devicename, - deviceport, - serialspeed, - pttprotocol, - pttport, - data_bits, - stop_bits, - handshake, - radiocontrol, - rigctld_ip, - rigctld_port, - enable_scatter, - enable_fft, - low_bandwith_mode, - tuning_range_fmin, - tuning_range_fmax, - enable_fsk, - tx_audio_level, - respond_to_cq, - ]) + mycall, + mygrid, + rx_audio, + tx_audio, + devicename, + deviceport, + serialspeed, + pttprotocol, + pttport, + data_bits, + stop_bits, + handshake, + radiocontrol, + rigctld_ip, + rigctld_port, + enable_scatter, + enable_fft, + low_bandwith_mode, + tuning_range_fmin, + tuning_range_fmax, + enable_fsk, + tx_audio_level, + respond_to_cq, + ]) command_response("start_tnc", True) except Exception as e: @@ -542,18 +551,18 @@ def process_daemon_commands(data): rigctld_port = str(received_json["parameter"][0]["rigctld_port"]) DAEMON_QUEUE.put(['TEST_HAMLIB', - devicename, - deviceport, - serialspeed, - pttprotocol, - pttport, - data_bits, - stop_bits, - handshake, - radiocontrol, - rigctld_ip, - rigctld_port, - ]) + devicename, + deviceport, + serialspeed, + pttprotocol, + pttport, + data_bits, + stop_bits, + handshake, + radiocontrol, + rigctld_ip, + rigctld_port, + ]) command_response("test_hamlib", True) except Exception as e: command_response("test_hamlib", False) @@ -572,6 +581,7 @@ def process_daemon_commands(data): command_response("stop_tnc", False) structlog.get_logger("structlog").warning("[SCK] command execution error", e=e, command=received_json) + def send_daemon_state(): """ send the daemon state to network @@ -587,10 +597,10 @@ def send_daemon_state(): 'input_devices': static.AUDIO_INPUT_DEVICES, 'output_devices': static.AUDIO_OUTPUT_DEVICES, 'serial_devices': static.SERIAL_DEVICES, - #'cpu': str(psutil.cpu_percent()), - #'ram': str(psutil.virtual_memory().percent), + # 'cpu': str(psutil.cpu_percent()), + # 'ram': str(psutil.virtual_memory().percent), 'version': '0.1' - } + } if static.TNCSTARTED: output["daemon_state"].append({"status": "running"}) @@ -604,8 +614,9 @@ def send_daemon_state(): structlog.get_logger("structlog").warning("[SCK] error", e=e) return None + def command_response(command, status): s_status = "OK" if status else "Failed" - jsondata = {"command_response": command, "status" : s_status} + jsondata = {"command_response": command, "status": s_status} data_out = json.dumps(jsondata) SOCKET_QUEUE.put(data_out) diff --git a/tnc/static.py b/tnc/static.py index 2922520c..9b2e311a 100644 --- a/tnc/static.py +++ b/tnc/static.py @@ -25,7 +25,7 @@ DXCALLSIGN_CRC = b'A' MYGRID = b'' DXGRID = b'' -SSID_LIST = [] # ssid list we are responding to +SSID_LIST = [] # ssid list we are responding to LOW_BANDWITH_MODE = False # --------------------------------- @@ -33,7 +33,7 @@ LOW_BANDWITH_MODE = False # Server Defaults HOST = "0.0.0.0" PORT = 3000 -SOCKET_TIMEOUT = 1 # seconds +SOCKET_TIMEOUT = 1 # seconds # --------------------------------- SERIAL_DEVICES = [] # --------------------------------- @@ -74,7 +74,7 @@ AUDIO_INPUT_DEVICES = [] AUDIO_OUTPUT_DEVICES = [] AUDIO_INPUT_DEVICE = -2 AUDIO_OUTPUT_DEVICE = -2 -BUFFER_OVERFLOW_COUNTER = [0,0,0,0,0] +BUFFER_OVERFLOW_COUNTER = [0, 0, 0, 0, 0] AUDIO_RMS = 0 FFT = [0] @@ -94,11 +94,11 @@ ARQ_TRANSMISSION_PERCENT = 0 ARQ_SPEED_LEVEL = 0 TOTAL_BYTES = 0 -#CHANNEL_STATE = 'RECEIVING_SIGNALLING' +# CHANNEL_STATE = 'RECEIVING_SIGNALLING' TNC_STATE = 'IDLE' ARQ_STATE = False ARQ_SESSION = False -ARQ_SESSION_STATE = 'disconnected' # disconnected, connecting, connected, disconnecting, failed +ARQ_SESSION_STATE = 'disconnected' # disconnected, connecting, connected, disconnecting, failed # BEACON STATE BEACON_STATE = False @@ -109,9 +109,9 @@ RX_BUFFER = [] RX_MSG_BUFFER = [] RX_BURST_BUFFER = [] RX_FRAME_BUFFER = b'' -#RX_BUFFER_SIZE = 0 +# RX_BUFFER_SIZE = 0 -# ------- HEARD STATIOS BUFFER +# ------- HEARD STATIONS BUFFER HEARD_STATIONS = [] # ------- INFO MESSAGE BUFFER