bluetooth-serial-port icon indicating copy to clipboard operation
bluetooth-serial-port copied to clipboard

wrong data recieved via read

Open Dushistov opened this issue 6 years ago • 7 comments

I want to connect with gps device via bluetooth on linux.

In console I did:

$ sudo rfcomm connect 0 10:C6:FC:FE:6D:D0 &
$ sudo cat /dev/rfcomm0
$GPGSA,A,3,08,27,11,69,14,18,77,32,,,,,2.5,1.6,1.9*35
$GPRMC,161659.5,A,5521.76350,N,03731.92747,E,000.57,058.2,040718,010.2,E,A*35
$GPGGA,161659.5,5521.76350,N,03731.92747,E,1,08,1.6,204.7,M,13.1,M,,*55
$GPVTG,058.2,T,048.0,M,000.57,N,0001.06,K,A*15

as you can see all data is is ascii, this is nmea protocol, it is text based.

Then I modify example.rs:

extern crate bluetooth_serial_port;
extern crate mio;
use bluetooth_serial_port::{BtProtocol, BtSocket};
use std::io::Read;

fn main() {
    // scan for devices
    let devices = bluetooth_serial_port::scan_devices().unwrap();
    if devices.len() == 0 {
        panic!("No devices found");
    }

    let device = devices.iter().position(|x| x.name.contains("GLO")).unwrap();
    let device = &devices[device];
    println!("Connecting to `{}` ({})", device.name, device.addr.to_string());

    // create and connect the RFCOMM socket
    let mut socket = BtSocket::new(BtProtocol::RFCOMM).unwrap();
    socket.connect(device.addr).unwrap();

    loop {
        let mut buffer: [u8; 20] = [0; 20];
        let num_bytes_read = socket.read(&mut buffer[..]).unwrap();
        if num_bytes_read == 0 {
            println!("read nothing, retry");
        }
        let s = &buffer[0..num_bytes_read];
        println!("raw bytes: {:?}", s);
    }
}

and output is:

raw bytes: [192, 1, 22, 0, 3, 1, 0, 37, 1, 10, 1, 128, 0, 232, 3, 232, 3, 184, 207, 4]
raw bytes: [0, 19]
raw bytes: [192, 1, 22, 0, 3, 1, 0, 37, 1, 10, 1, 128, 0, 232, 3, 232, 3, 184, 207, 4]
raw bytes: [0, 19]
raw bytes: [192, 1, 22, 0, 3, 1, 0, 37, 1, 10, 1, 128, 0, 232, 3, 232, 3, 184, 207, 4]
raw bytes: [0, 19]
raw bytes: [192, 1, 22, 0, 3, 1, 0, 37, 1, 10, 1, 128, 0, 232, 3, 232, 3, 184, 207, 4]
raw bytes: [0, 19]
raw bytes: [192, 1, 22, 0, 3, 1, 0, 37, 1, 10, 1, 128, 0, 232, 3, 232, 3, 184, 207, 4]
raw bytes: [0, 19]
raw bytes: [192, 1, 22, 0, 3, 1, 0, 37, 1, 10, 1, 128, 0, 232, 3, 232, 3, 184, 207, 4]
raw bytes: [0, 19]
raw bytes: [192, 1, 22, 0, 3, 1, 0, 37, 1, 10, 1, 128, 0, 232, 3, 232, 3, 184, 207, 4]
raw bytes: [0, 19]
raw bytes: [192, 1, 22, 0, 3, 1, 0, 37, 1, 10, 1, 128, 0, 232, 3, 232, 3, 184, 207, 4]
raw bytes: [0, 19]
raw bytes: [192, 1, 22, 0, 3, 1, 0, 37, 1, 10, 1, 128, 0, 232, 3, 232, 3, 184, 207, 4]
raw bytes: [0, 19]

this looks completly wrong for me, byte with 0 value, bytes with value 1 and so on.

Dushistov avatar Jul 04 '18 16:07 Dushistov

Thank you for your detailed bug report! Your code looks fine to me... Unfortunately I'm not working on bluetooth-serial-port anymore, and I don't see at first glance what the reason for this behavior could be. So I'm sorry to say that you're on your own for this problem. I will leave this issue open, so others can see it.

kaegi avatar Jul 04 '18 19:07 kaegi

Looks like the problem in connection, I replace socket.connect(device.addr).unwrap(); with

    let mut socket = BtSocket::new(BtProtocol::RFCOMM).unwrap();
    let fd = socket.0.stream.into_raw_fd();

    let mut sock_addr = sockaddr_rc {
        rc_family: 31,
        rc_channel: 1,
        rc_bdaddr: bdaddr_t {
            b: [0xD0, 0x6D, 0xFE, 0xFC, 0xC6, 0x10],
        },
    };
    let status = unsafe { libc::connect(fd, mem::transmute(&mut sock_addr), mem::size_of::<sockaddr_rc>() as u32) };
    if status != 0 {
        eprintln!("connect failed");
        return;
    }

and all starts work as expected

Dushistov avatar Jul 04 '18 22:07 Dushistov

@kaegi

I find out the reason, device has 3 rfcomm channels: 1,3,5.

The code in sdp.rs uses the last one 5, and via this channel really comes these strange data, if I force code to use channel 1, I got gps/nmea data.

What is your option about API change in crate should I made to handle this situtaion, here output from this test program:

rfcomm channel: 1 found service record 0x90001 rfcomm channel: 3 found service record 0x90003 rfcomm channel: 5 found service record 0x90005

Dushistov avatar Jul 05 '18 15:07 Dushistov

Probably adding a connect_to_channel to BtSocket. As I'm not interested in maintaining this project, you can have crate and GitHub publishing rights (or fork your own version) if you want to maintain it.

kaegi avatar Jul 06 '18 11:07 kaegi

As I'm not interested in maintaining this project, you can have crate and GitHub publishing rights (or fork your own version) if you want to maintain it

I come back to this work. Therefore, if you are not interested in this project can you give me publish rights for crates.io ?

Dushistov avatar Dec 24 '18 02:12 Dushistov

Should be done now.

kaegi avatar Dec 24 '18 11:12 kaegi

@kaegi Great, thanks!

Dushistov avatar Dec 24 '18 12:12 Dushistov