【问题标题】:Sending binary data over Bluetooth/RFCOMM/SPP converts 0x0A to 0x0D 0x0A通过蓝牙/RFCOMM/SPP 发送二进制数据将 0x0A 转换为 0x0D 0x0A
【发布时间】:2013-02-22 16:37:55
【问题描述】:

我有一个通过命令在 Linux 上运行的蓝牙 RFCOMM 服务:

sdptool add --channel 1 SP
rfcomm watch hci0 1 "$COMMAND" {}
# ^ here

$COMMAND 会将二进制数据写入作为参数传递的文件。我已经通过以下方式测试了它的行为是否正确:

FIFO=$(tempfile)
mkfifo "$FIFO"
"$COMMAND" "$FIFO" &
cat "$FIFO" | hexdump -C # <- output is correct

但是,当通过 SPP/RFCOMM 发现 (UUID 00001101-0000-1000-8000-00805F9B34FB) 从不同设备连接到服务时,我看到 0x0A (LF) 的每个实例都被 0x0D 0x0A ( CRLF) 在流中。问题不在接收端,因为我尝试连接到也发送二进制数据的硬件串行设备,但没有发生转换。执行替换的必须是第一个 sn-p(# ^ here 行上方)中的命令。

为什么rfcomm 工具会进行此替换,如何禁用它?

【问题讨论】:

    标签: linux bluetooth serial-port newline


    【解决方案1】:

    您似乎被 TTY 的线路规则所困扰(请记住,rfcomm 不会创建 fifo,而是创建 tty)。

    您可以尝试将 TTY 更改为 raw 模式,也就是说,不要使用任何魔法。最简单的方法是使用stty --file &lt;tty&gt; raw。我不知道rfcomm 是否会在其命令行中接受多个命令,但您可以使用脚本轻松完成:

    command_raw

    #!/bin/bash
    stty --file "$1" raw
    "$COMMAND" "$1"
    

    然后运行:

    sdptool add --channel 1 SP
    rfcomm watch hci0 1 ./command_raw {}
    

    如果你有要运行的命令的源代码,你也可以在 C: 中轻松更改它:

     #include <termios.h>
     #include <unistd.h>
    
     //WARNING: error checking left as an exercise to the reader!
     void make_raw(int fd)
     {
         struct termios ios;
    
         //Not a TTY: nothing to do
         if (!isatty(fd))
             return; 
    
         tcgetattr(fd, &ios);
         cfmakeraw(&ios);
         tcsetattr(fd, TCSANOW, &ios);
     }
    

    【讨论】:

    • 我没有意识到 rfcomm 设备是一个 TTY。 C 代码当然可以完美运行。
    猜你喜欢
    • 2021-05-20
    • 2016-01-17
    • 2011-12-13
    • 2016-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-08
    相关资源
    最近更新 更多