diff --git a/tnc/codec2.py b/tnc/codec2.py index b6c83b0b..a8c2f441 100644 --- a/tnc/codec2.py +++ b/tnc/codec2.py @@ -240,6 +240,7 @@ class MODEMSTATS(ctypes.Structure): ("fft_buf", (ctypes.c_float * MODEM_STATS_NSPEC * 2)), ] + # Return code flags for freedv_get_rx_status() function api.FREEDV_RX_TRIAL_SYNC = 0x1 # type: ignore # demodulator has trial sync api.FREEDV_RX_SYNC = 0x2 # type: ignore # demodulator has sync diff --git a/tnc/data_handler.py b/tnc/data_handler.py index 0ee6eaef..b07081b1 100644 --- a/tnc/data_handler.py +++ b/tnc/data_handler.py @@ -246,7 +246,7 @@ class DATA: FR_TYPE.CQ.value, FR_TYPE.QRV.value, FR_TYPE.PING.value, - FR_TYPE.BEACON.value + FR_TYPE.BEACON.value, ] ): @@ -272,7 +272,7 @@ class DATA: # BURST ACK elif frametype == FR_TYPE.BURST_ACK.value: - self.log.debug("[TNC] ACK RECEIVED....") + self.log.debug("[TNC] BURST ACK RECEIVED....") self.burst_ack_received(bytes_out[:-2]) # FRAME ACK @@ -366,7 +366,11 @@ class DATA: else: # for debugging purposes to receive all data - self.log.debug("[TNC] Unknown frame received", frame=bytes_out[:-2]) + self.log.debug( + "[TNC] Foreign frame received", + frame=bytes_out[:-2].hex(), + frame_type=FR_TYPE(int.from_bytes(bytes_out[:1], byteorder="big")).name, + ) def enqueue_frame_for_tx( self, @@ -990,7 +994,7 @@ class DATA: ): time.sleep(0.01) - # Once we received a burst ack, reset its state and break the RETRIES loop + # Once we receive a burst ack, reset its state and break the RETRIES loop if self.burst_ack: self.burst_ack = False # reset ack state self.tx_n_retry_of_burst = 0 # reset retries diff --git a/tnc/exceptions.py b/tnc/exceptions.py index 9d49fa66..0b2374bf 100644 --- a/tnc/exceptions.py +++ b/tnc/exceptions.py @@ -2,5 +2,6 @@ Custom exceptions for FreeDATA Python code """ + class NoCallsign(UserWarning): """Raised when a required callsign is not provided""" diff --git a/tnc/helpers.py b/tnc/helpers.py index 21885dc2..c1e36626 100644 --- a/tnc/helpers.py +++ b/tnc/helpers.py @@ -7,8 +7,6 @@ Created on Fri Dec 25 21:25:14 2020 import time import crcengine -import structlog - import static import structlog @@ -29,6 +27,7 @@ def wait(seconds: float) -> bool: time.sleep(0.01) return True + def get_crc_8(data) -> bytes: """Author: DJ2LS @@ -47,6 +46,7 @@ def get_crc_8(data) -> bytes: crc_data = crc_data.to_bytes(1, byteorder="big") return crc_data + def get_crc_16(data) -> bytes: """Author: DJ2LS @@ -65,6 +65,7 @@ def get_crc_16(data) -> bytes: crc_data = crc_data.to_bytes(2, byteorder="big") return crc_data + def get_crc_24(data) -> bytes: """Author: DJ2LS @@ -92,6 +93,7 @@ def get_crc_24(data) -> bytes: crc_data = crc_data.to_bytes(3, byteorder="big") return crc_data + def get_crc_32(data: bytes) -> bytes: """Author: DJ2LS @@ -110,6 +112,7 @@ def get_crc_32(data: bytes) -> bytes: crc_data = crc_data.to_bytes(4, byteorder="big") return crc_data + def add_to_heard_stations(dxcallsign, dxgrid, datatype, snr, offset, frequency): """ @@ -159,11 +162,13 @@ def add_to_heard_stations(dxcallsign, dxgrid, datatype, snr, offset, frequency): ) break + # for idx, item in enumerate(static.HEARD_STATIONS): # if dxcallsign in item: # item = [dxcallsign, int(time.time())] # static.HEARD_STATIONS[idx] = item + def callsign_to_bytes(callsign) -> bytes: """ @@ -287,7 +292,6 @@ def check_callsign(callsign: bytes, crc_to_check: bytes): False """ - # print(callsign) log.debug("[HLP] check_callsign: Checking:", callsign=callsign) try: # We want the callsign without SSID @@ -307,11 +311,12 @@ def check_callsign(callsign: bytes, crc_to_check: bytes): callsign_crc = get_crc_24(call_with_ssid) if callsign_crc == crc_to_check: - print(call_with_ssid) + log.debug("[HLP] check_callsign matched:", call_with_ssid=call_with_ssid) return [True, bytes(call_with_ssid)] return [False, ""] + def encode_grid(grid): """ @author: DB1UJ @@ -375,6 +380,7 @@ def decode_grid(b_code_word: bytes): return grid + def encode_call(call): """ @author: DB1UJ diff --git a/tnc/main.py b/tnc/main.py index c165b7b4..06e2ca46 100755 --- a/tnc/main.py +++ b/tnc/main.py @@ -25,6 +25,7 @@ import structlog log = structlog.get_logger("main") + def signal_handler(sig, frame): """ a signal handler, which closes the network/socket when closing the application @@ -39,6 +40,7 @@ def signal_handler(sig, frame): sock.CLOSE_SIGNAL = True sys.exit(0) + signal.signal(signal.SIGINT, signal_handler) if __name__ == "__main__": diff --git a/tnc/sock.py b/tnc/sock.py index 2769709f..79cc2741 100644 --- a/tnc/sock.py +++ b/tnc/sock.py @@ -48,8 +48,10 @@ class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer): pass + class ThreadedTCPRequestHandler(socketserver.StreamRequestHandler): """ """ + connection_alive = False connection_alive = False @@ -184,6 +186,7 @@ class ThreadedTCPRequestHandler(socketserver.StreamRequestHandler): client=self.request, ) + def process_tnc_commands(data): """ process tnc commands @@ -213,7 +216,9 @@ def process_tnc_commands(data): except Exception as err: command_response("tx_audio_level", False) log.warning( - "[SCK] command execution error", e=err, command=received_json + "[SCK] TX audio command execution error", + e=err, + command=received_json, ) # TRANSMIT TEST FRAME ---------------------------------------------------- @@ -227,7 +232,9 @@ def process_tnc_commands(data): except Exception as err: command_response("send_test_frame", False) log.warning( - "[SCK] command execution error", e=err, command=received_json + "[SCK] Send test frame command execution error", + e=err, + command=received_json, ) # CQ CQ CQ ----------------------------------------------------- @@ -239,7 +246,7 @@ def process_tnc_commands(data): except Exception as err: command_response("cqcqcq", False) log.warning( - "[SCK] command execution error", e=err, command=received_json + "[SCK] CQ command execution error", e=err, command=received_json ) # START_BEACON ----------------------------------------------------- @@ -252,20 +259,24 @@ def process_tnc_commands(data): except Exception as err: command_response("start_beacon", False) log.warning( - "[SCK] command execution error", e=err, command=received_json + "[SCK] Start beacon command execution error", + e=err, + command=received_json, ) # STOP_BEACON ----------------------------------------------------- if received_json["command"] == "stop_beacon": try: - log.warning("[TNC] Stopping beacon!") + log.warning("[SCK] Stopping beacon!") static.BEACON_STATE = False data_handler.DATA_QUEUE_TRANSMIT.put(["BEACON", None, False]) command_response("stop_beacon", True) except Exception as err: command_response("stop_beacon", False) log.warning( - "[SCK] command execution error", e=err, command=received_json + "[SCK] Stop beacon command execution error", + e=err, + command=received_json, ) # PING ---------------------------------------------------------- @@ -290,7 +301,7 @@ def process_tnc_commands(data): except Exception as err: command_response("ping", False) log.warning( - "[SCK] command execution error", e=err, command=received_json + "[SCK] PING command execution error", e=err, command=received_json ) # CONNECT ---------------------------------------------------------- @@ -314,7 +325,9 @@ def process_tnc_commands(data): except Exception as err: command_response("connect", False) log.warning( - "[SCK] command execution error", e=err, command=received_json + "[SCK] Connect command execution error", + e=err, + command=received_json, ) # DISCONNECT ---------------------------------------------------------- @@ -326,7 +339,9 @@ def process_tnc_commands(data): except Exception as err: command_response("disconnect", False) log.warning( - "[SCK] command execution error", e=err, command=received_json + "[SCK] Disconnect command execution error", + e=err, + command=received_json, ) # TRANSMIT RAW DATA ------------------------------------------- @@ -363,18 +378,21 @@ def process_tnc_commands(data): except Exception: arq_uuid = "no-uuid" - if not len(base64data) % 4: - binarydata = base64.b64decode(base64data) - - data_handler.DATA_QUEUE_TRANSMIT.put( - ["ARQ_RAW", binarydata, mode, n_frames, arq_uuid, mycallsign] - ) - else: + if len(base64data) % 4: raise TypeError + + binarydata = base64.b64decode(base64data) + + data_handler.DATA_QUEUE_TRANSMIT.put( + ["ARQ_RAW", binarydata, mode, n_frames, arq_uuid, mycallsign] + ) + except Exception as err: command_response("send_raw", False) log.warning( - "[SCK] command execution error", e=err, command=received_json + "[SCK] Send raw command execution error", + e=err, + command=received_json, ) # STOP TRANSMISSION ---------------------------------------------------------- @@ -385,14 +403,14 @@ def process_tnc_commands(data): try: if static.TNC_STATE == "BUSY" or static.ARQ_STATE: data_handler.DATA_QUEUE_TRANSMIT.put(["STOP"]) - log.warning("[TNC] Stopping transmission!") + log.warning("[SCK] Stopping transmission!") static.TNC_STATE = "IDLE" static.ARQ_STATE = False command_response("stop_transmission", True) except Exception as err: command_response("stop_transmission", False) log.warning( - "[SCK] command execution error", e=err, command=received_json + "[SCK] STOP command execution error", e=err, command=received_json ) if received_json["type"] == "get" and received_json["command"] == "rx_buffer": @@ -424,7 +442,9 @@ def process_tnc_commands(data): except Exception as err: command_response("rx_buffer", False) log.warning( - "[SCK] command execution error", e=err, command=received_json + "[SCK] Send RX buffer command execution error", + e=err, + command=received_json, ) if ( @@ -437,12 +457,14 @@ def process_tnc_commands(data): except Exception as err: command_response("del_rx_buffer", False) log.warning( - "[SCK] command execution error", e=err, command=received_json + "[SCK] Delete RX buffer command execution error", + e=err, + command=received_json, ) # exception, if JSON cant be decoded except Exception as err: - log.error("[TNC] JSON decoding error", e=err) + log.error("[SCK] JSON decoding error", e=err) def send_tnc_state(): @@ -523,9 +545,9 @@ def process_daemon_commands(data): if bytes(callsign, "utf-8") == b"": self.request.sendall(b"INVALID CALLSIGN") log.warning( - "[DMN] SET MYCALL FAILED", + "[SCK] SET MYCALL FAILED", call=static.MYCALLSIGN, - crc=static.MYCALLSIGN_CRC, + crc=static.MYCALLSIGN_CRC.hex(), ) else: static.MYCALLSIGN = bytes(callsign, "utf-8") @@ -533,9 +555,9 @@ def process_daemon_commands(data): command_response("mycallsign", True) log.info( - "[DMN] SET MYCALL", + "[SCK] SET MYCALL", call=static.MYCALLSIGN, - crc=static.MYCALLSIGN_CRC, + crc=static.MYCALLSIGN_CRC.hex(), ) except Exception as err: command_response("mycallsign", False) @@ -547,6 +569,7 @@ def process_daemon_commands(data): if bytes(mygrid, "utf-8") == b"": self.request.sendall(b"INVALID GRID") + command_response("mygrid", False) else: static.MYGRID = bytes(mygrid, "utf-8") log.info("[SCK] SET MYGRID", grid=static.MYGRID) @@ -590,7 +613,7 @@ def process_daemon_commands(data): # print some debugging parameters for item in received_json["parameter"][0]: log.debug( - f"[DMN] TNC Startup Config : {item}", + f"[SCK] TNC Startup Config : {item}", value=received_json["parameter"][0][item], ) @@ -669,7 +692,7 @@ def process_daemon_commands(data): # unregister process from atexit to avoid process zombies atexit.unregister(static.TNCPROCESS.kill) - log.warning("[DMN] Stopping TNC") + log.warning("[SCK] Stopping TNC") static.TNCSTARTED = False command_response("stop_tnc", True) except Exception as err: