使用socat拦截物理串口上的通信

使用socat拦截物理串口上的通信

我不是 Linux 专家,所以请放轻松;)。

好的,情况是我有一台运行 Debian Wheezy 的单板计算机。我知道它旧/有风险等等,但它实际上不是“我的”设备,因此我无法控制它。

上面运行着一些软件,用 C# 编写并通过 Mono 运行。再说一遍,这不是我的软件,我对它的控制权为零,也没有更改代码的能力。

该软件通过物理串行端口 ( /dev/ttyS1) 将 AT 命令发送到调制解调器,调制解调器返回对命令的适当响应。

调制解调器不再可用,因此我需要开发一些替代方案。因此,我认为我可以在 SBC 上运行一个简单的 python 脚本,该脚本将“拦截”AT 命令,将适当的响应发送回 c# 软件,然后我可以使用 python 脚本与另一个设备进行通信,但我需要这样做。

有了一个很好的“谷歌”,socat似乎是做到这一点的最佳选择。然而,我尝试过,但不知道有多少种组合,无法让它按照我需要的方式工作。

物理设置是,我目前已将串行端口插入我的笔记本电脑,这样我就可以看到来自管道的 AT 命令(在 ttyS1 上),然后我通过 ssh 进入 SBC 并启动 minicom 以查看由socat

现有设置

C# <-> ttyS1 <-> 旧调制解调器

所需设置

C# <-> socat <-> python -> 新调制解调器

以下只是我尝试过的两种变体:

socat -x /dev/ttyS1,raw,echo=0,crnl PTY,link=/dev/ttyV1,raw,echo=0,crnl

...还尝试了相反的方式,以防我误解...

socat -x PTY,link=/dev/ttyV1,raw,echo=0,crnl /dev/ttyS1,raw,echo=0,crnl

我也尝试过许多不同的变体,推送到文件,“teeing”到文件,不同的命令开关,使用 stty 等配置端口等

每次我遇到同样的问题时,我实际上看不到正在发送的 AT 命令C# 软件?!

我可以在 SBC 上输入 minicom 并看到笔记本电脑上串行端口读取器上出现的输出,同样我可以在笔记本电脑上输入串行端口读取器并查看 SBC 上 minicom 中的输入,但是我看不到什么拦截的是从 C# 软件发送的实际 AT 命令,即使该软件配置为使用 ttyS1。

我对软件的唯一控制是它使用哪个端口与调制解调器通信。因此,我还尝试将其更改为虚拟端口,例如,/dev/ttyV1并在启动期间和 c# 程序启动之前运行socat创建虚拟端口,以便虚拟端口实际上可用。我再次遇到完全相同的问题,我仍然看不到 C# 软件发送的 AT 命令。

希望有人能提供帮助,因为我已经呆了整整两天了,但无法让它发挥作用。我很确定 socat 是一个可以使用的工具,希望我只是从根本上误解了它的工作原理。

答案1

可能缺少一个强制性部分:串行端口速率。

socat一旦我在选项中设置了串行端口速率,就可以尝试类似的实验:

socat -x PTY,link=/dev/ttyV1,raw,echo=0,crnl /dev/ttyS1,b115200,raw,echo=0,crnl

这里我使用了 115200 波特率b115200socat的男人告诉使用此命令来查看所有可能的b...选项:

socat -hh |grep 'b[1-9]'

(并且:

注意:在某些操作系统上,这些选项可能不可用。请改用 ispeed 或 ospeed。

用作测试应用程序(是的,screen可以处理串行端口):

screen /dev/ttyV1 115200

代替

screen /dev/ttyS1 115200

我能够像往常一样登录配置为通过串行端口具有控制台的其他系统(screen的 115200 参数变得无用,但这表明这不应中断应用程序)。

发送或接收的所有内容均以十六进制显示-x


我想我已经回答了你的问题。您的目标似乎是改变流量,这是一项更大的任务,但您询问如何读取通过串行端口的流量。

您需要一个专用工具来改变流量,特别是当字符没有缓冲时(使得sed在管道中间使用 & 类似可能更加困难)。

socat通常,第一半部分 (PTY)会有第一个命令,它会调用一个可执行文件来改变流量(可以是 shell 脚本或者 python 或其他什么,并且必须管理两侧,可能使用最多 4 个不同的 FD),它会调用第二半部分 (ttyS1) 的EXEC:第二个命令。socat

答案2

HardwareW - /dev/ttyUSB0 <---> socat/logging <---> ~/myserial <---> Python 串行脚本

  1. 插入您的ttyUSB0设备,并让您的用户可以ttyUSB0使用:

    sudo chown youruser.youruser -R /dev/ttyUSB0
    
  2. 启动Socat

    socat -d -d -x /dev/ttyUSB0,b9600,rawer  PTY,link=$HOME/myserial,rawer,echo=0 2>log3
    
  3. 向 RS232 设备发送数据/请求。

    python myserial-client.py '*IDN?'
    

    请注意,设备通常需要特定的字符序列,例如。*IDN?,并且不会响应 Minicom 终端,该终端逐字符发送数据 *, I, D, N, ?

    例子myserial-client.py

    import sys
    import serial
    DEFAULT_ADDR = '/home/krzys/myserial'
    DEFAULT_CMD = 'R5'
    args = len(sys.argv) - 1
    if args == 0:
        addr, cmd = DEFAULT_ADDR, DEFAULT_CMD
    elif args == 1:
        addr, cmd = DEFAULT_ADDR, sys.argv[1]
    else:
        addr, cmd = sys.argv[1:3]
    
    cmd += '\r\n'
    s = serial.Serial("/home/krzys/myserial",9600,timeout=0.5)
    s.write(cmd.encode())
    print(s.readline())
    
  4. 最好通过编写虚拟myserver.py脚本来检查您的脚本,您可以在其中测试+验证发送和接收帧。

请检查这个要点,关于如何在linux虚拟Python模拟器中设置,以及客户端来测试串行通信。

相关内容