I have a Bluetooth RFCOMM service running on Linux via the commands:
sdptool add --channel 1 SP
rfcomm watch hci0 1 "$COMMAND" {}
# ^ here
The $COMMAND
will write binary data to the file passed as a parameter. I have tested that it behaves correctly by doing:
FIFO=$(tempfile)
mkfifo "$FIFO"
"$COMMAND" "$FIFO" &
cat "$FIFO" | hexdump -C # <- output is correct
However, when connecting to the service from a different device via SPP/RFCOMM discovery (UUID 00001101-0000-1000-8000-00805F9B34FB
), I see that every instance of 0x0A
(LF
) is replaced by 0x0D
0x0A
(CR
LF
) in the stream. The issue isn't on the receiving end, because I have tried connecting to a hardware serial device that also sends binary data, and there the conversion doesn't happen. It must be the command in the first snippet (above the # ^ here
line) that performs the replacement.
Why does the rfcomm
tool do this replacement and how can I disable it?
It looks like you are being bitten by the line discipline of the TTY (remember that rfcomm
does not create a fifo, but a tty).
You may try changing the TTY to raw mode, that is, without any magic. The easiest way is with stty --file <tty> raw
. I don't know if rfcomm
will admit several commands in its command line but you can do easily with a script:
#!/bin/bash
stty --file "$1" raw
"$COMMAND" "$1"
And then run:
sdptool add --channel 1 SP
rfcomm watch hci0 1 ./command_raw {}
If you have the source of the command to be run, you can also change it easily in 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);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With