sistemata la comunicazione via json, da sistemare quella mediante comando semplice tgtset/tgtinit
This commit is contained in:
parent
fc1722d8eb
commit
3213d61e5b
@ -17,7 +17,7 @@
|
|||||||
},
|
},
|
||||||
"sfp": {
|
"sfp": {
|
||||||
"ip": "127.0.0.1",
|
"ip": "127.0.0.1",
|
||||||
"port": 60001,
|
"port": 60003,
|
||||||
"local_port": 60002,
|
"local_port": 60002,
|
||||||
"use_json_protocol": true
|
"use_json_protocol": true
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,6 +19,7 @@ from target_simulator.utils.logger import get_logger
|
|||||||
from target_simulator.gui.payload_router import DebugPayloadRouter
|
from target_simulator.gui.payload_router import DebugPayloadRouter
|
||||||
from target_simulator.analysis.simulation_state_hub import SimulationStateHub
|
from target_simulator.analysis.simulation_state_hub import SimulationStateHub
|
||||||
from target_simulator.config import DEBUG_CONFIG
|
from target_simulator.config import DEBUG_CONFIG
|
||||||
|
import json
|
||||||
|
|
||||||
|
|
||||||
class SFPCommunicator(CommunicatorInterface):
|
class SFPCommunicator(CommunicatorInterface):
|
||||||
@ -219,6 +220,8 @@ class SFPCommunicator(CommunicatorInterface):
|
|||||||
# --- JSON Protocol Logic for scenario initialization ---
|
# --- JSON Protocol Logic for scenario initialization ---
|
||||||
self.logger.debug("Using JSON protocol for scenario initialization.")
|
self.logger.debug("Using JSON protocol for scenario initialization.")
|
||||||
json_command = command_builder.build_json_update(scenario.get_all_targets())
|
json_command = command_builder.build_json_update(scenario.get_all_targets())
|
||||||
|
# Compact the JSON payload to a single-line string before saving/sending
|
||||||
|
json_command = self._compact_json_if_needed(json_command)
|
||||||
self._save_json_payload_to_temp(json_command, "sfp_scenario_init")
|
self._save_json_payload_to_temp(json_command, "sfp_scenario_init")
|
||||||
|
|
||||||
if not self._send_single_command(json_command):
|
if not self._send_single_command(json_command):
|
||||||
@ -262,6 +265,8 @@ class SFPCommunicator(CommunicatorInterface):
|
|||||||
|
|
||||||
# Expect a single command string which is the JSON payload
|
# Expect a single command string which is the JSON payload
|
||||||
json_payload = commands[0]
|
json_payload = commands[0]
|
||||||
|
# Compact JSON for live updates before saving/sending
|
||||||
|
json_payload = self._compact_json_if_needed(json_payload)
|
||||||
self._save_json_payload_to_temp(json_payload, "sfp_live_update")
|
self._save_json_payload_to_temp(json_payload, "sfp_live_update")
|
||||||
return self._send_single_command(json_payload)
|
return self._send_single_command(json_payload)
|
||||||
else:
|
else:
|
||||||
@ -275,8 +280,41 @@ class SFPCommunicator(CommunicatorInterface):
|
|||||||
def _send_single_command(self, command: str) -> bool:
|
def _send_single_command(self, command: str) -> bool:
|
||||||
if not self.transport or not self._destination:
|
if not self.transport or not self._destination:
|
||||||
return False
|
return False
|
||||||
|
# As a final safeguard, compact JSON payloads here as well
|
||||||
|
try:
|
||||||
|
command = self._compact_json_if_needed(command)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
return self.transport.send_script_command(command, self._destination)
|
return self.transport.send_script_command(command, self._destination)
|
||||||
|
|
||||||
|
def _compact_json_if_needed(self, command: str) -> str:
|
||||||
|
"""If the command is a JSON document (starts with { or [), return a compact
|
||||||
|
single-line JSON string (no unnecessary spaces/newlines) with a trailing newline.
|
||||||
|
Otherwise return the original command unchanged.
|
||||||
|
"""
|
||||||
|
if not isinstance(command, str):
|
||||||
|
try:
|
||||||
|
command = str(command)
|
||||||
|
except Exception:
|
||||||
|
return command
|
||||||
|
|
||||||
|
s = command.strip()
|
||||||
|
if not s:
|
||||||
|
return command
|
||||||
|
|
||||||
|
if not (s.startswith("{") or s.startswith("[")):
|
||||||
|
return command
|
||||||
|
|
||||||
|
try:
|
||||||
|
obj = json.loads(s)
|
||||||
|
compact = json.dumps(obj, separators=(',', ':'))
|
||||||
|
if not compact.endswith("\n"):
|
||||||
|
compact += "\n"
|
||||||
|
return compact
|
||||||
|
except Exception:
|
||||||
|
# If parsing fails, return original command (avoid changing it)
|
||||||
|
return command
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def test_connection(config: Dict[str, Any]) -> bool:
|
def test_connection(config: Dict[str, Any]) -> bool:
|
||||||
local_port = config.get("local_port")
|
local_port = config.get("local_port")
|
||||||
|
|||||||
@ -64,7 +64,7 @@ class ConnectionSettingsWindow(tk.Toplevel):
|
|||||||
target_cfg.get("serial", {}).get("baudrate", 9600)
|
target_cfg.get("serial", {}).get("baudrate", 9600)
|
||||||
)
|
)
|
||||||
self.target_vars["sfp_ip"].set(target_sfp_cfg.get("ip", "127.0.0.1"))
|
self.target_vars["sfp_ip"].set(target_sfp_cfg.get("ip", "127.0.0.1"))
|
||||||
self.target_vars["sfp_port"].set(target_sfp_cfg.get("port", 60001))
|
self.target_vars["sfp_port"].set(target_sfp_cfg.get("port", 60003))
|
||||||
self.target_vars["sfp_local_port"].set(target_sfp_cfg.get("local_port", 60002))
|
self.target_vars["sfp_local_port"].set(target_sfp_cfg.get("local_port", 60002))
|
||||||
self.target_vars["sfp_use_json"].set(
|
self.target_vars["sfp_use_json"].set(
|
||||||
target_sfp_cfg.get("use_json_protocol", False)
|
target_sfp_cfg.get("use_json_protocol", False)
|
||||||
@ -93,7 +93,7 @@ class ConnectionSettingsWindow(tk.Toplevel):
|
|||||||
lru_cfg.get("serial", {}).get("baudrate", 9600)
|
lru_cfg.get("serial", {}).get("baudrate", 9600)
|
||||||
)
|
)
|
||||||
self.lru_vars["sfp_ip"].set(lru_sfp_cfg.get("ip", "127.0.0.1"))
|
self.lru_vars["sfp_ip"].set(lru_sfp_cfg.get("ip", "127.0.0.1"))
|
||||||
self.lru_vars["sfp_port"].set(lru_sfp_cfg.get("port", 60001))
|
self.lru_vars["sfp_port"].set(lru_sfp_cfg.get("port", 60003))
|
||||||
self.lru_vars["sfp_local_port"].set(lru_sfp_cfg.get("local_port", 60002))
|
self.lru_vars["sfp_local_port"].set(lru_sfp_cfg.get("local_port", 60002))
|
||||||
self.lru_vars["sfp_use_json"].set(lru_sfp_cfg.get("use_json_protocol", False))
|
self.lru_vars["sfp_use_json"].set(lru_sfp_cfg.get("use_json_protocol", False))
|
||||||
# Select the correct notebook tab for lru
|
# Select the correct notebook tab for lru
|
||||||
|
|||||||
@ -76,7 +76,7 @@ class SfpDebugWindow(tk.Toplevel):
|
|||||||
self.image_area_size = 150
|
self.image_area_size = 150
|
||||||
self.ip_var = tk.StringVar(value="127.0.0.1")
|
self.ip_var = tk.StringVar(value="127.0.0.1")
|
||||||
self.local_port_var = tk.StringVar(value="60002")
|
self.local_port_var = tk.StringVar(value="60002")
|
||||||
self.server_port_var = tk.StringVar(value="60001")
|
self.server_port_var = tk.StringVar(value="60003")
|
||||||
self.script_var = tk.StringVar(value="print('hello from client')")
|
self.script_var = tk.StringVar(value="print('hello from client')")
|
||||||
self.tgt_id_var = tk.IntVar(value=DEF_TEST_ID)
|
self.tgt_id_var = tk.IntVar(value=DEF_TEST_ID)
|
||||||
self.tgt_range_var = tk.DoubleVar(value=DEF_TEST_RANGE)
|
self.tgt_range_var = tk.DoubleVar(value=DEF_TEST_RANGE)
|
||||||
@ -677,9 +677,10 @@ class SfpDebugWindow(tk.Toplevel):
|
|||||||
command_str = command_builder.build_tgtset_from_target_state(
|
command_str = command_builder.build_tgtset_from_target_state(
|
||||||
temp_target, include_flags=True
|
temp_target, include_flags=True
|
||||||
)
|
)
|
||||||
command_str = command_str.strip()
|
# Normalize/prefix legacy textual commands so the server receives the
|
||||||
if not command_str.endswith("\n"):
|
# expected leading '$' and a trailing newline. Also log the final
|
||||||
command_str += "\n"
|
# payload shown exactly as sent.
|
||||||
|
command_str = self._ensure_legacy_prefixed(command_str)
|
||||||
self._log_to_widget(f"Built command: {command_str!r}", "INFO")
|
self._log_to_widget(f"Built command: {command_str!r}", "INFO")
|
||||||
|
|
||||||
success = self.shared_communicator._send_single_command(command_str)
|
success = self.shared_communicator._send_single_command(command_str)
|
||||||
@ -818,6 +819,8 @@ class SfpDebugWindow(tk.Toplevel):
|
|||||||
return
|
return
|
||||||
try:
|
try:
|
||||||
command_str = self.script_var.get()
|
command_str = self.script_var.get()
|
||||||
|
# Ensure legacy/textual script commands are prefixed with '$' as expected by server
|
||||||
|
command_str = self._ensure_legacy_prefixed(command_str)
|
||||||
self.shared_communicator._send_single_command(command_str)
|
self.shared_communicator._send_single_command(command_str)
|
||||||
except (ValueError, tk.TclError) as e:
|
except (ValueError, tk.TclError) as e:
|
||||||
self._log_to_widget(
|
self._log_to_widget(
|
||||||
@ -833,6 +836,8 @@ class SfpDebugWindow(tk.Toplevel):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
# Normalize legacy textual commands (prefix with $) before sending.
|
||||||
|
command_str = self._ensure_legacy_prefixed(command_str)
|
||||||
success = self.shared_communicator._send_single_command(command_str)
|
success = self.shared_communicator._send_single_command(command_str)
|
||||||
if success:
|
if success:
|
||||||
self._log_to_widget(f"Successfully sent command: {command_str}", "INFO")
|
self._log_to_widget(f"Successfully sent command: {command_str}", "INFO")
|
||||||
@ -908,9 +913,7 @@ class SfpDebugWindow(tk.Toplevel):
|
|||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
command_str = command_builder.build_tgtset_selective(target_id, updates)
|
command_str = command_builder.build_tgtset_selective(target_id, updates)
|
||||||
command_str = command_str.strip()
|
# _on_send_simple_command will normalize/prefix as needed
|
||||||
if command_str and not command_str.endswith("\n"):
|
|
||||||
command_str = command_str + "\n"
|
|
||||||
return self._on_send_simple_command(command_str)
|
return self._on_send_simple_command(command_str)
|
||||||
except (ValueError, tk.TclError) as e:
|
except (ValueError, tk.TclError) as e:
|
||||||
self._log_to_widget(f"ERROR: Invalid input for tgtset: {e}", "ERROR")
|
self._log_to_widget(f"ERROR: Invalid input for tgtset: {e}", "ERROR")
|
||||||
@ -1329,6 +1332,33 @@ class SfpDebugWindow(tk.Toplevel):
|
|||||||
self.log_tab.config(state=tk.DISABLED)
|
self.log_tab.config(state=tk.DISABLED)
|
||||||
self.log_tab.see(tk.END)
|
self.log_tab.see(tk.END)
|
||||||
|
|
||||||
|
def _ensure_legacy_prefixed(self, command: str) -> str:
|
||||||
|
"""Normalize textual/legacy commands: ensure they end with a newline.
|
||||||
|
|
||||||
|
If the string looks like JSON (starts with '{' or '['), do not alter it
|
||||||
|
other than ensuring a trailing newline. Bytes are decoded as UTF-8.
|
||||||
|
Former behavior prefixed '$' to legacy commands; that has been removed
|
||||||
|
because the DSP expects plain 'tgtset' commands.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
if isinstance(command, (bytes, bytearray)):
|
||||||
|
s = command.decode("utf-8")
|
||||||
|
else:
|
||||||
|
s = str(command)
|
||||||
|
except Exception:
|
||||||
|
s = str(command)
|
||||||
|
|
||||||
|
s = s.strip()
|
||||||
|
if not s:
|
||||||
|
return s
|
||||||
|
|
||||||
|
# If it looks like JSON (starts with { or [), leave structure intact
|
||||||
|
# but ensure a trailing newline. For legacy textual commands, do not
|
||||||
|
# add any special prefix — just ensure newline.
|
||||||
|
if not s.endswith("\n"):
|
||||||
|
s = s + "\n"
|
||||||
|
return s
|
||||||
|
|
||||||
def _on_save_ris_csv(self):
|
def _on_save_ris_csv(self):
|
||||||
try:
|
try:
|
||||||
import csv
|
import csv
|
||||||
|
|||||||
@ -10,7 +10,7 @@ import os
|
|||||||
from target_simulator.core.sfp_transport import SfpTransport
|
from target_simulator.core.sfp_transport import SfpTransport
|
||||||
|
|
||||||
LISTEN_IP = "127.0.0.1"
|
LISTEN_IP = "127.0.0.1"
|
||||||
LISTEN_PORT = 60001
|
LISTEN_PORT = 60003
|
||||||
CLIENT_BIND_PORT = 60002
|
CLIENT_BIND_PORT = 60002
|
||||||
|
|
||||||
received = []
|
received = []
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user