1515def burn (
1616 chip : str = typer .Option (..., "-c" , "--chip" , help = "Chip model name" ),
1717 file : str = typer .Option ("" , "-f" , "--file" , help = "Firmware file (auto-downloads from OpenIPC if omitted)" ),
18- port : str = typer .Option ("/dev/ttyUSB0" , "-p" , "--port" , help = "Serial port" ),
18+ port : str = typer .Option ("/dev/ttyUSB0" , "-p" , "--port" , help = "Serial device (/dev/ttyUSB0), tcp://host: port, rfc2217://host:port, or socket:///path " ),
1919 send_break : bool = typer .Option (False , "-b" , "--break" , help = "Send Ctrl-C after upload" ),
2020 terminal : bool = typer .Option (False , "-t" , "--terminal" , help = "Open serial terminal after upload" ),
2121 power_cycle : bool = typer .Option (False , "--power-cycle" , help = "Auto power-cycle via PoE (needs DEFIB_POE_* env vars)" ),
@@ -441,7 +441,7 @@ def ports(
441441
442442@app .command ()
443443def detect (
444- port : str = typer .Option ("/dev/ttyUSB0" , "-p" , "--port" , help = "Serial port" ),
444+ port : str = typer .Option ("/dev/ttyUSB0" , "-p" , "--port" , help = "Serial device (/dev/ttyUSB0), tcp://host: port, rfc2217://host:port, or socket:///path " ),
445445 output : str = typer .Option ("human" , "--output" , help = "Output mode: human, json" ),
446446 timeout : float = typer .Option (25.0 , "--timeout" , help = "Detection timeout in seconds" ),
447447) -> None :
@@ -508,7 +508,7 @@ async def _detect_async(port: str, output: str, timeout: float) -> None:
508508
509509@app .command ()
510510def capture (
511- port : str = typer .Option (..., "-p" , "--port" , help = "Serial port" ),
511+ port : str = typer .Option (..., "-p" , "--port" , help = "Serial device (/dev/ttyUSB0), tcp://host: port, rfc2217://host:port, or socket:///path " ),
512512 output_file : str = typer .Option (..., "-o" , "--output" , help = "Output .dcap file" ),
513513 chip : str = typer .Option ("" , "-c" , "--chip" , help = "Chip name (metadata only)" ),
514514 duration : float = typer .Option (60.0 , "--duration" , help = "Max capture duration in seconds" ),
@@ -629,7 +629,7 @@ def replay(
629629
630630@app .command ("dump-flash" )
631631def dump_flash_cmd (
632- port : str = typer .Option ("/dev/ttyUSB0" , "-p" , "--port" , help = "Serial port" ),
632+ port : str = typer .Option ("/dev/ttyUSB0" , "-p" , "--port" , help = "Serial device (/dev/ttyUSB0), tcp://host: port, rfc2217://host:port, or socket:///path " ),
633633 output_file : str = typer .Option ("flash_dump.bin" , "-o" , "--output" , help = "Output binary file" ),
634634 size : str = typer .Option ("" , "--size" , help = "Flash size (e.g., 8MB, 16MB) — auto-detect if empty" ),
635635 output : str = typer .Option ("human" , "--output-mode" , help = "Output mode: human, json" ),
@@ -903,7 +903,7 @@ def list_interfaces_cmd(
903903@agent_app .command ("upload" )
904904def agent_upload (
905905 chip : str = typer .Option (..., "-c" , "--chip" , help = "Chip model name" ),
906- port : str = typer .Option ("/dev/ttyUSB0" , "-p" , "--port" , help = "Serial port" ),
906+ port : str = typer .Option ("/dev/ttyUSB0" , "-p" , "--port" , help = "Serial device (/dev/ttyUSB0), tcp://host: port, rfc2217://host:port, or socket:///path " ),
907907 output : str = typer .Option ("human" , "--output" , help = "Output mode: human, json" ),
908908) -> None :
909909 """Upload flash agent to device via boot protocol (requires power-cycle)."""
@@ -921,7 +921,9 @@ async def _agent_upload_async(chip: str, port: str, output: str) -> None:
921921 from defib .profiles .loader import load_profile
922922 from defib .protocol .hisilicon_standard import HiSiliconStandard
923923 from defib .recovery .events import ProgressEvent
924- from defib .transport .serial import SerialTransport
924+ from defib .transport .serial_platform import (
925+ create_transport , normalize_port_name ,
926+ )
925927
926928 console = Console ()
927929
@@ -957,7 +959,7 @@ async def _agent_upload_async(chip: str, port: str, output: str) -> None:
957959 console .print (f"SPL: full U-Boot ({ len (spl_data )} bytes — boundary auto-detected)" )
958960 console .print ("\n [yellow]Power-cycle the camera now![/yellow]\n " )
959961
960- transport = await SerialTransport . create ( port )
962+ transport = await create_transport ( normalize_port_name ( port ) )
961963 protocol = HiSiliconStandard ()
962964 protocol .set_profile (profile )
963965
@@ -996,7 +998,7 @@ def on_progress(e: ProgressEvent) -> None:
996998 import asyncio as aio
997999 await transport .close ()
9981000 await aio .sleep (2 )
999- transport = await SerialTransport . create ( port )
1001+ transport = await create_transport ( normalize_port_name ( port ) )
10001002
10011003 client = FlashAgentClient (transport , chip )
10021004 if await client .connect (timeout = 10.0 ):
@@ -1021,7 +1023,7 @@ def on_progress(e: ProgressEvent) -> None:
10211023def agent_flash (
10221024 chip : str = typer .Option (..., "-c" , "--chip" , help = "Chip model name" ),
10231025 input_file : str = typer .Option (..., "-i" , "--input" , help = "Firmware binary file" ),
1024- port : str = typer .Option ("/dev/ttyUSB0" , "-p" , "--port" , help = "Serial port" ),
1026+ port : str = typer .Option ("/dev/ttyUSB0" , "-p" , "--port" , help = "Serial device (/dev/ttyUSB0), tcp://host: port, rfc2217://host:port, or socket:///path " ),
10251027 verify : bool = typer .Option (True , "--verify/--no-verify" , help = "CRC32 verify after write" ),
10261028 reboot : bool = typer .Option (True , "--reboot/--no-reboot" , help = "Reboot after flash" ),
10271029 output : str = typer .Option ("human" , "--output" , help = "Output mode: human, json" ),
@@ -1052,7 +1054,9 @@ async def _agent_flash_async(
10521054 from defib .profiles .loader import load_profile
10531055 from defib .protocol .hisilicon_standard import HiSiliconStandard
10541056 from defib .recovery .events import ProgressEvent
1055- from defib .transport .serial import SerialTransport
1057+ from defib .transport .serial_platform import (
1058+ create_transport , normalize_port_name ,
1059+ )
10561060
10571061 console = Console ()
10581062 FLASH_MEM = 0x14000000
@@ -1101,7 +1105,7 @@ async def _agent_flash_async(
11011105 console .print ("\n [yellow]Power-cycle the camera now![/yellow]\n " )
11021106
11031107 # --- Phase 1: Upload agent via boot protocol ---
1104- transport = await SerialTransport . create ( port )
1108+ transport = await create_transport ( normalize_port_name ( port ) )
11051109 protocol = HiSiliconStandard ()
11061110 protocol .set_profile (profile )
11071111
@@ -1139,7 +1143,7 @@ def on_boot_progress(e: ProgressEvent) -> None:
11391143 import asyncio as aio
11401144 await transport .close ()
11411145 await aio .sleep (2 )
1142- transport = await SerialTransport . create ( port )
1146+ transport = await create_transport ( normalize_port_name ( port ) )
11431147
11441148 client = FlashAgentClient (transport , chip )
11451149 if not await client .connect (timeout = 10.0 ):
@@ -1242,7 +1246,7 @@ def on_flash_progress(done: int, total: int) -> None:
12421246
12431247@agent_app .command ("info" )
12441248def agent_info (
1245- port : str = typer .Option ("/dev/ttyUSB0" , "-p" , "--port" , help = "Serial port" ),
1249+ port : str = typer .Option ("/dev/ttyUSB0" , "-p" , "--port" , help = "Serial device (/dev/ttyUSB0), tcp://host: port, rfc2217://host:port, or socket:///path " ),
12461250 output : str = typer .Option ("human" , "--output" , help = "Output mode: human, json" ),
12471251) -> None :
12481252 """Query info from a running flash agent."""
@@ -1256,10 +1260,12 @@ async def _agent_info_async(port: str, output: str) -> None:
12561260 from rich .console import Console
12571261
12581262 from defib .agent .client import FlashAgentClient
1259- from defib .transport .serial import SerialTransport
1263+ from defib .transport .serial_platform import (
1264+ create_transport , normalize_port_name ,
1265+ )
12601266
12611267 console = Console ()
1262- transport = await SerialTransport . create ( port )
1268+ transport = await create_transport ( normalize_port_name ( port ) )
12631269 client = FlashAgentClient (transport )
12641270
12651271 if not await client .connect (timeout = 5.0 ):
@@ -1299,7 +1305,7 @@ async def _agent_info_async(port: str, output: str) -> None:
12991305
13001306@agent_app .command ("read" )
13011307def agent_read (
1302- port : str = typer .Option ("/dev/ttyUSB0" , "-p" , "--port" , help = "Serial port" ),
1308+ port : str = typer .Option ("/dev/ttyUSB0" , "-p" , "--port" , help = "Serial device (/dev/ttyUSB0), tcp://host: port, rfc2217://host:port, or socket:///path " ),
13031309 addr : str = typer .Option (None , "-a" , "--addr" , help = "Start address (hex, default: flash base 0x14000000)" ),
13041310 size : str = typer .Option (None , "-s" , "--size" , help = "Size in bytes (or 1KB, 16MB, etc; default: auto-detect)" ),
13051311 output_file : str = typer .Option ("flash_dump.bin" , "-o" , "--output" , help = "Output binary file" ),
@@ -1321,11 +1327,13 @@ async def _agent_read_async(
13211327 from rich .console import Console
13221328
13231329 from defib .agent .client import FlashAgentClient
1324- from defib .transport .serial import SerialTransport
1330+ from defib .transport .serial_platform import (
1331+ create_transport , normalize_port_name ,
1332+ )
13251333
13261334 console = Console ()
13271335
1328- transport = await SerialTransport . create ( port )
1336+ transport = await create_transport ( normalize_port_name ( port ) )
13291337 client = FlashAgentClient (transport )
13301338 if not await client .connect (timeout = 5.0 ):
13311339 console .print ("[red]Agent not responding[/red]" )
@@ -1379,7 +1387,7 @@ async def _agent_read_async(
13791387
13801388@agent_app .command ("write" )
13811389def agent_write (
1382- port : str = typer .Option ("/dev/ttyUSB0" , "-p" , "--port" , help = "Serial port" ),
1390+ port : str = typer .Option ("/dev/ttyUSB0" , "-p" , "--port" , help = "Serial device (/dev/ttyUSB0), tcp://host: port, rfc2217://host:port, or socket:///path " ),
13831391 addr : str = typer .Option ("0x14000000" , "-a" , "--addr" , help = "Start address (hex, default: flash base)" ),
13841392 input_file : str = typer .Option (..., "-i" , "--input" , help = "Input binary file" ),
13851393 verify : bool = typer .Option (True , "--verify/--no-verify" , help = "CRC32 verify after write" ),
@@ -1399,13 +1407,15 @@ async def _agent_write_async(
13991407 from rich .console import Console
14001408
14011409 from defib .agent .client import FlashAgentClient
1402- from defib .transport .serial import SerialTransport
1410+ from defib .transport .serial_platform import (
1411+ create_transport , normalize_port_name ,
1412+ )
14031413
14041414 console = Console ()
14051415 address = int (addr_str , 0 )
14061416 data = open (input_file , "rb" ).read ()
14071417
1408- transport = await SerialTransport . create ( port )
1418+ transport = await create_transport ( normalize_port_name ( port ) )
14091419 client = FlashAgentClient (transport )
14101420 if not await client .connect (timeout = 5.0 ):
14111421 console .print ("[red]Agent not responding[/red]" )
@@ -1449,7 +1459,7 @@ async def _agent_write_async(
14491459
14501460@agent_app .command ("scan" )
14511461def agent_scan (
1452- port : str = typer .Option ("/dev/ttyUSB0" , "-p" , "--port" , help = "Serial port" ),
1462+ port : str = typer .Option ("/dev/ttyUSB0" , "-p" , "--port" , help = "Serial device (/dev/ttyUSB0), tcp://host: port, rfc2217://host:port, or socket:///path " ),
14531463 output_file : str = typer .Option ("" , "-o" , "--output" , help = "Save recoverable data to file (bad sectors filled with 0xFF)" ),
14541464 output : str = typer .Option ("human" , "--output-mode" , help = "Output mode: human, json" ),
14551465) -> None :
@@ -1472,10 +1482,12 @@ async def _agent_scan_async(port: str, output_file: str, output: str) -> None:
14721482 SectorResult ,
14731483 SectorStatus ,
14741484 )
1475- from defib .transport .serial import SerialTransport
1485+ from defib .transport .serial_platform import (
1486+ create_transport , normalize_port_name ,
1487+ )
14761488
14771489 console = Console ()
1478- transport = await SerialTransport . create ( port )
1490+ transport = await create_transport ( normalize_port_name ( port ) )
14791491 client = FlashAgentClient (transport )
14801492
14811493 if not await client .connect (timeout = 5.0 ):
@@ -1658,7 +1670,7 @@ def _parse_size(s: str) -> int:
16581670def install (
16591671 chip : str = typer .Option (..., "-c" , "--chip" , help = "Chip model name" ),
16601672 firmware : str = typer .Option (..., "--firmware" , help = "OpenIPC firmware tarball (.tgz)" ),
1661- port : str = typer .Option ("/dev/ttyUSB0" , "-p" , "--port" , help = "Serial port" ),
1673+ port : str = typer .Option ("/dev/ttyUSB0" , "-p" , "--port" , help = "Serial device (/dev/ttyUSB0), tcp://host: port, rfc2217://host:port, or socket:///path " ),
16621674 power_cycle : bool = typer .Option (False , "--power-cycle" , help = "Auto power-cycle via PoE" ),
16631675 poe_port_override : str = typer .Option ("" , "--poe-port" , help = "Explicit MikroTik ether port (e.g. ether3) — overrides comment-based auto-discovery. Requires --power-cycle." ),
16641676 nic : str = typer .Option ("" , "--nic" , help = "Network interface for TFTP (auto-detect if empty)" ),
@@ -2339,7 +2351,7 @@ async def tftp_and_flash(
23392351def restore (
23402352 chip : str = typer .Option (..., "-c" , "--chip" , help = "Chip model name" ),
23412353 dump : str = typer .Option (..., "-i" , "--input" , help = "Flash dump file or directory of mtdN files" ),
2342- port : str = typer .Option ("/dev/ttyUSB0" , "-p" , "--port" , help = "Serial port" ),
2354+ port : str = typer .Option ("/dev/ttyUSB0" , "-p" , "--port" , help = "Serial device (/dev/ttyUSB0), tcp://host: port, rfc2217://host:port, or socket:///path " ),
23432355 uboot : str = typer .Option ("" , "--uboot" , help = "U-Boot binary to load (auto-downloads if omitted)" ),
23442356 flash_type : str = typer .Option ("auto" , "--flash-type" , help = "Flash type: auto, nor, nand, emmc" ),
23452357 mtdparts : str = typer .Option ("" , "--mtdparts" , help = "NAND partition layout (e.g. hinand:1M(boot),4M(kernel),8M(rootfs),...)" ),
0 commit comments