From 643bcdc95248e97d9549aa576467ec47f9829090 Mon Sep 17 00:00:00 2001 From: Arda Aydin Date: Fri, 11 Sep 2026 23:48:10 +0300 Subject: [PATCH] Add Trace DASP preference to print protocol transactions to terminal New checkbox in Preferences (default off). When enabled, every DASP send (>>>) and receive (<<<) prints message type, seq/ack numbers, payload size, and remote address to stdout. Co-Authored-By: Claude Opus 4.6 --- app_state.py | 11 +++++++---- dasp.py | 20 ++++++++++++++++++++ main.py | 18 +++++++++++++++--- 3 files changed, 42 insertions(+), 7 deletions(-) diff --git a/app_state.py b/app_state.py index a1abdcd..08d795f 100644 --- a/app_state.py +++ b/app_state.py @@ -8,7 +8,7 @@ so later rebinding would only ever be seen by the module that did it. import configparser import os -VERSION = "0.0.0.075" +VERSION = "0.0.0.076" PROPERTIES_FILE = os.path.join(os.path.dirname(os.path.abspath(__file__)), "editor.properties") DEFAULT_GRID_SIZE = 10 DEFAULT_ADD_TIMESTAMP = True @@ -111,6 +111,7 @@ def load_preferences(): box_width = DEFAULT_BOX_WIDTH left_pane_width = DEFAULT_LEFT_PANE_WIDTH sedona_home = "" + trace_dasp = False if os.path.exists(PROPERTIES_FILE): try: @@ -122,6 +123,7 @@ def load_preferences(): "Editor", "left_pane_width", fallback=DEFAULT_LEFT_PANE_WIDTH ) sedona_home = config.get("Editor", "sedona.home", fallback="").strip() + trace_dasp = config.getboolean("Editor", "trace_dasp", fallback=False) except Exception: pass else: @@ -142,7 +144,7 @@ def load_preferences(): left_pane_width = max( MIN_ALLOWED_LEFT_PANE_WIDTH, min(MAX_ALLOWED_LEFT_PANE_WIDTH, left_pane_width) ) - return sedona_home, grid_size, add_timestamp, box_width, left_pane_width + return sedona_home, grid_size, add_timestamp, box_width, left_pane_width, trace_dasp def save_preferences(): @@ -153,7 +155,8 @@ def save_preferences(): "grid_size": str(GRID_SIZE), "add_timestamp": str(ADD_TIMESTAMP), "box_width": str(BOX_WIDTH), - "left_pane_width": str(LEFT_PANE_WIDTH) + "left_pane_width": str(LEFT_PANE_WIDTH), + "trace_dasp": str(TRACE_DASP), } with open(PROPERTIES_FILE, "w") as configfile: config.write(configfile) @@ -217,4 +220,4 @@ def base_window_title_live(): return f"Sedona Live Editor [v{VERSION}] — {device_host}:{device_port}" -SEDONA_HOME, GRID_SIZE, ADD_TIMESTAMP, BOX_WIDTH, LEFT_PANE_WIDTH = load_preferences() +SEDONA_HOME, GRID_SIZE, ADD_TIMESTAMP, BOX_WIDTH, LEFT_PANE_WIDTH, TRACE_DASP = load_preferences() diff --git a/dasp.py b/dasp.py index 7f8c540..75db4af 100644 --- a/dasp.py +++ b/dasp.py @@ -78,6 +78,24 @@ ERR_TIMEOUT = 0xE5 DEFAULT_PORT = 1876 +_MSG_TYPE_NAMES = { + DISCOVER: "DISCOVER", HELLO: "HELLO", CHALLENGE: "CHALLENGE", + AUTHENTICATE: "AUTHENTICATE", WELCOME: "WELCOME", KEEPALIVE: "KEEPALIVE", + DATAGRAM: "DATAGRAM", CLOSE: "CLOSE", +} + + +def _trace(direction, msg, addr=None): + import app_state + if not app_state.TRACE_DASP: + return + name = _MSG_TYPE_NAMES.get(msg.msg_type, f"?{msg.msg_type}") + seq = f" seq={msg.seq_num}" if msg.seq_num >= 0 else "" + ack = f" ack={msg.ack}" if msg.ack >= 0 else "" + plen = len(msg.payload) if msg.payload else 0 + dest = f" {addr[0]}:{addr[1]}" if addr else "" + print(f"[DASP] {direction}{dest} {name}{seq}{ack} payload={plen}") + class DaspException(Exception): def __init__(self, msg, error_code=-1): @@ -898,6 +916,7 @@ class DaspSocket: # ── Network I/O ───────────────────────────────────────────── def _send_msg(self, session, msg): + _trace(">>>", msg, (session.host, session.port)) data = msg.encode() with self._send_lock: try: @@ -922,6 +941,7 @@ class DaspSocket: break def _dispatch(self, msg, addr): + _trace("<<<", msg, addr) session_id = msg.session_id with self._sessions_lock: session = self._sessions.get(session_id) diff --git a/main.py b/main.py index de7ad10..ecb3587 100644 --- a/main.py +++ b/main.py @@ -1661,7 +1661,7 @@ def open_preferences_dialog(): dialog = tk.Toplevel(window) dialog.title("Preferences") - dialog.geometry("470x290") + dialog.geometry("470x330") dialog.resizable(False, False) dialog.transient(window) dialog.grab_set() @@ -1724,7 +1724,18 @@ def open_preferences_dialog(): text="Yes", variable=var_timestamp ) - chk_timestamp.grid(row=4, column=1, sticky="w", pady=(0, 15)) + chk_timestamp.grid(row=4, column=1, sticky="w", pady=(0, 10)) + + lbl_trace = ttk.Label(frame_padded, text="Trace DASP to terminal?", anchor="w") + lbl_trace.grid(row=5, column=0, sticky="w", pady=(0, 15), padx=(0, 10)) + + var_trace_dasp = tk.BooleanVar(value=app_state.TRACE_DASP) + chk_trace_dasp = ttk.Checkbutton( + frame_padded, + text="Yes", + variable=var_trace_dasp + ) + chk_trace_dasp.grid(row=5, column=1, sticky="w", pady=(0, 15)) def apply_preferences(): try: @@ -1781,6 +1792,7 @@ def open_preferences_dialog(): app_state.LEFT_PANE_WIDTH = pane_width app_state.GRID_SIZE = val app_state.ADD_TIMESTAMP = var_timestamp.get() + app_state.TRACE_DASP = var_trace_dasp.get() app_state.SEDONA_HOME = entry_home.get().strip() app_state.save_preferences() @@ -1799,7 +1811,7 @@ def open_preferences_dialog(): messagebox.showerror("Invalid Input", message, parent=dialog) btn_save_pref = ttk.Button(frame_padded, text="Apply Changes", command=apply_preferences) - btn_save_pref.grid(row=5, column=1, sticky="e") + btn_save_pref.grid(row=6, column=1, sticky="e") if not app_state.SEDONA_HOME: entry_home.focus_set()