添加无线模块

This commit is contained in:
minghanchen
2026-08-19 09:59:36 +08:00
parent 344f662970
commit 52c4dd08f9
33 changed files with 4740 additions and 246 deletions
+143
View File
@@ -0,0 +1,143 @@
from __future__ import annotations
import io
import os
import sys
import tempfile
import unittest
from pathlib import Path
from unittest.mock import Mock, patch
from cognitive_agent.infrastructure.can.gateway import (
ZlgCanBridgeProcess,
ZlgChannelConfig,
)
from cognitive_agent.infrastructure.can.hardware import VehicleCanSettings
from cognitive_agent.infrastructure.can.zlgcan_linux_bridge import (
EXPECTED_ABI_SIZES,
Driver,
_acceptance_filters,
_verified_init,
abi_sizes,
)
REPOSITORY_ROOT = Path(__file__).resolve().parents[2]
class LinuxZlgBridgeTests(unittest.TestCase):
def test_ctypes_layout_matches_vendor_packed_abi(self) -> None:
self.assertEqual(abi_sizes(), EXPECTED_ABI_SIZES)
def test_verified_60mhz_timing_matches_can_dev_baseline(self) -> None:
init = _verified_init(
{
"arbitration_bitrate": 500_000,
"data_bitrate": 2_000_000,
"can_fd_iso": True,
}
)
self.assertEqual(init.clk, 60_000_000)
self.assertEqual(init.mode, 0)
self.assertEqual(
(init.aset.tseg1, init.aset.tseg2, init.aset.sjw, init.aset.brp),
(14, 3, 2, 5),
)
self.assertEqual(
(init.dset.tseg1, init.dset.tseg2, init.dset.sjw, init.dset.brp),
(10, 2, 2, 1),
)
with self.assertRaisesRegex(ValueError, "locked"):
_verified_init(
{"arbitration_bitrate": 1_000_000, "data_bitrate": 4_000_000}
)
def test_passive_state_filter_uses_exact_standard_identifiers(self) -> None:
frame_ids = frozenset({0x342, 0x407, 0x4EB})
filters = _acceptance_filters({"receive_ids": frame_ids})
self.assertEqual(filters.size, 3 * 12)
self.assertEqual(
[
(
filters.table[index].type,
filters.table[index].sid,
filters.table[index].eid,
)
for index in range(3)
],
[(0, 0x342, 0x342), (0, 0x407, 0x407), (0, 0x4EB, 0x4EB)],
)
def test_channel_config_serializes_receive_filter_only_when_requested(self) -> None:
filtered = ZlgChannelConfig(channel=1, receive_ids=(0x342, 0x4EB))
unfiltered = ZlgChannelConfig(channel=1)
self.assertEqual(filtered.public()["receive_ids"], [0x342, 0x4EB])
self.assertNotIn("receive_ids", unfiltered.public())
def test_monitor_only_rejects_send_before_touching_sdk(self) -> None:
driver = object.__new__(Driver)
driver.monitor_only = True
driver.configs = {1: {"channel": 1, "frame_format": "can_fd"}}
driver.sdk = Mock()
with self.assertRaisesRegex(PermissionError, "monitor-only"):
driver.send(
1,
0x123,
bytes.fromhex("0001020304050607"),
is_fd=True,
bitrate_switch=True,
)
driver.sdk.VCI_TransmitFD.assert_not_called()
driver.sdk.VCI_Transmit.assert_not_called()
def test_linux_state_can_be_ready_while_transmit_stays_locked(self) -> None:
with tempfile.TemporaryDirectory() as directory:
library = Path(directory) / "libusbcanfd.so"
library.write_bytes(b"test")
environment = {
"COGNITIVE_AGENT_VEHICLE_CAN_ENABLED": "true",
"COGNITIVE_AGENT_VEHICLE_CAN_BACKEND": "zlgcan-linux",
"COGNITIVE_AGENT_VEHICLE_CAN_CHANNEL": "1",
"COGNITIVE_AGENT_VEHICLE_CAN_REQUIRED_CHANNEL": "1",
"COGNITIVE_AGENT_ZLGCAN_PYTHON": sys.executable,
"COGNITIVE_AGENT_ZLGCAN_LINUX_LIBRARY": str(library),
}
with patch.dict(os.environ, environment, clear=True):
settings = VehicleCanSettings.from_env(REPOSITORY_ROOT)
self.assertEqual(settings.device_type, 33)
self.assertTrue(settings.state_configured)
self.assertFalse(settings.configured)
self.assertTrue(settings.bridge_script.name.endswith("linux_bridge.py"))
self.assertTrue(settings.public_info()["state_configured"])
def test_process_passes_monitor_and_trace_flags_to_bridge(self) -> None:
process = Mock()
process.stdout = io.StringIO('{"ok":true,"event":"ready"}\n')
process.stderr = io.StringIO()
process.stdin = io.StringIO()
process.poll.return_value = 0
with patch(
"cognitive_agent.infrastructure.can.gateway.subprocess.Popen",
return_value=process,
) as popen:
bridge = ZlgCanBridgeProcess(
python_executable=Path(sys.executable),
bridge_script=Path("bridge.py"),
dll_path=Path("libusbcanfd.so"),
device_type=33,
device_index=0,
channels=[ZlgChannelConfig(channel=1, termination_enabled=False)],
monitor_only=True,
trace_all=True,
)
command = popen.call_args.args[0]
self.assertIn("--monitor-only", command)
self.assertIn("--trace-all", command)
bridge.close()
if __name__ == "__main__":
unittest.main()