my BlueUSB

After first sucessfully trying the USBHostShell of Peter Barrett, I continued with the BlueUSB which, according to what he hooked up to it was very powerfull.

The good

The library is light weight and indeed it did not have problems with any of my three BT radios. Also the inquiry discovered all devices I was interested in. This makes it a good starting point to build applications from.

The bad

The stack is very bare bone, it provides core functionality (L2CAP) but not the desirable SDP and especially RFCOMM. The program, as provided, was designed to be used for HID, especially the wiimote. For my purposes I need RFCOMM so I started the development of an RFCOMM layer. Everything I needed was on the Internet, specifications (bluetooth.org and ETSI) and examples (google code and open_bt). How hard can it be to add a few bytes to every packet? Well a lot harder than I initially thought.

The ugly

Lean as BlueUSB is, it lacks quite a few features. Most notably there is no support for fragmentation and recombination or control flow. The L2CAP works in basic mode so fragmentation and flow control are not required but the HCI should support recombination. Nowhere are packet sizes checked against the actual mtu's or buffer sizes. The structure of the library is a mixture of object-oriented concepts and flat C-code. The programmer needs to be aware of object sizes and alignment. The HCI layer appears to be both above and beneath the L2CAP layer which makes understanding the code a bit confusing. Also the state-machine of the L2CAP was incomplete so connections sometimes failed.

My contribution

Originally I just wanted to bolt an RFCOMM layer right on top of the L2CAP layer with minimal changes to the existing code. Meanwhile I have an RFCOMM layer and a simple SDP client running but it required quite a few changes to the existing code. To make things worse, it didn't make the code more understandable. A complete refactoring of the code, using more object oriented concepts would be a good idea but will take quite some time. For the time being however I will not try to improve the code any further unless the need arises.

Update 15.04.2011

I have done a lot of work on SDP. It should handlemultiple simultaneous connections now (as a client) and also the server is working. Windows Vista can query the services and reports it as a serial device. The next step is to make MBED accept incoming RFCOMM connections.

Update 4-5-2011

Finally have the RFCOMM server working (reasonably). It responds to SABM, PN, DISC, DM, MSC and RPN commands. Credit based data-flow works OK. Other data-flow is not implemented. The published demo allows a terminal like Putty to connect/disconnect and echo anything typed. Characters are buffered until CR or LF or buffer-full. I'm still struggling with a nasty bug in USBHost. Sometimes the bulk endpoint just blocks and nothing comes out of it anymore. I've traced the problem to something in the ISR, ProcessDoneQueue or Transfer. The problem is not random but always occurs in the same place in my program (after authentication when setting up an rfcomm connection with mbed as server, last thing to happen is change of encryption). I found out that enabling a LOG statement in ProcessDoneQueue cured the problem which made me think that it was timing related. Replacing the LOG with wait_us() also worked, even with delays a short as 0us or 1us, which make me think it is interrupt related. Somewhere in the program is a kind of race or deadlock condition but I cannot find it. I already sacrificed two weeks of my life to it and have decided to use the work-around as long as it works. If anyone has ideas please let me know. A good starting point is ftp://ftp.compaq.com/pub/supportinformation/papers/hcir1_0a.pdf the OHCI specification. I also looked at the USBLite stack from NXP but could not find anything like ProcessDoneQueue, in any case it does not run as part of the ISR. For those who want to improve the BT stack: The BT Core specification is almost mandatory reading (I used v2.0) and so is the additional specification for RFCOMM (both available from the BT SIG website). Very helpful is also the ETSI TS07.10 specification (ETSI TS 101369 v7.2.0), but a bit harder to get. A good introduction to RFCOMM is in 'Connect without cables' Bray/Thurman, Chapter 10 about RFCOMM can be found on the Internet. Some information about dlci's and the D and C/R bits is confusing and you should really read the real spec.


12 comments on my BlueUSB:

04 Apr 2011

Excellent work. I was hoping someone had already done the RFCOMM SPP layer. If I understand correctly this means we'd be able to use the cheap $2.00 BT USB modules to give our MBED bluetooth serial right??

Thanks for your contributions!!!

04 Apr 2011

Yes, The RFCOMM layer follows the pattern of the other layers so the interface is as defined in Socket.h.

int Socket_Open(SOCKET_RFCOM, &s.hdr, cb, this); where s is L2CAPAddr (hci.h) containing the BT address and rfcomm channel (in psm), cb is the callback where the received data goes: void cb(int socket, SocketState state, const unsigned char *data, int len, void *userData); and 'this' is the userData pointer to the object receiving the data. Socket_Open returns the socket just opened.

Socket_Close(socket); closes the socket Socket_Send(int socket, const unsigned char *data, int len); sends a block of data of length 'len' to the peer device. True Serial compatibility would need an aditional adaptation which defines putc, getc, readable, writable and preferably some buffering.

04 Apr 2011

Fantastic job implementing RFCOMM, well done!

04 May 2011

good job :)

11 Jun 2011

I am trying to receive ASCII strings from a Bluetooth GPS. Although i am reading about RFCOMM, Bluetooth protocols and connecting WII Remote i still don't understand how to receive the ASCII strings from the BT GPS.

After installing my BlueUSB on the mbed i see the following results in CoolTerm

HCI_EV_REMOTE_NAME 16: 07 FF 00 1B A4 8C 1B 08 00 42 54 20 47 50 53 00
.[33m00:08:1B:8C:A4:1B = BT GPS
.[0mReady to open ports
0 ft BT devices have been found
Passively opening socket 1 for type 3, invoking 'Listen' on 10000544 (=RFCOMMManager SocketHandler)
RFCOMM listener socket 1 for ch 1 (dlci 0x02) is assigned to slot 0

So i think that the connection is established and RFCOMM is waiting? But how to retrieve the Data? I have checked the function of the BT GPS. This transfers the Data correctly to a BT serial program running on a second computer.

So anyone can give me a tip how to carry on? Thanks.

11 Jun 2011

Hi,

thanks for using blueusb :). No the connection is not established yet, the devices see each other and there is a socket on the mbed listening. What you need to know is who will initiate the connection. Right now the mbed expects the GPS to initiate the connection and is waiting on channel 1, which is mostly the correct channel. If you want the mbed to initiate the connection you need Socket_Open i.o. Socket_listen. When you are using the btserial class you need to take the other constructor (the one with the bluetooth address (of the GPS)). Have a look at this thread as well: http://mbed.org/forum/mbed/topic/2269/?page=1#comment-11562

happy to answer further questions

11 Jun 2011

Wow thanks for that fast answer. But i still don'tt understand the way of how to communicate with the GPS. I would prefer to use the btserial class as the GPS is answering with strings. And changing to other BT GPS modules would mean that i'll have to compile the source again. Is there any source skeleton of how to realise this ?

11 Jun 2011

Well I use it for a different purpose (the ft devices). But using the btserial class should be easy (but it is very poorly tested because I don't use it myself, it was intended as an example). Many devices work with Request/Response sequences, A device (usually the initiator) sends a request and waits for the response. GPS may be different, my GPS (serial, not USB) just spits out data in a format defined through its LCD screen. In that case look how it connects to your PC. When you create virtual comports for BT devices you van choose whether it should be for incoming or outgoing trafic (Note: both are bidirectional, it is just a matter of initiative). So if your PC uses an outgoing port (with a specific BT address) then for the mbed you also choose the constructor with the BT address. One way or the other, after the connection is established, you call readable or getc to read the incoming data and hope that there is some. Please look at the code that Rob wrote in the link I sent you.

11 Jun 2011

After changing to the btserial class with the Address of the BT GPS this is my result. I have modified the Address in Robs code. Still no data from BT GPS.

HCI_EV_REMOTE_NAME 16: 07 FF 00 1B A4 8C 1B 08 00 42 54 20 47 50 53 00
.[33m00:08:1B:8C:A4:1B = BT GPS
.[0mB ready to connect
Opening socket 1 for type 3, invoking 'Open' on 10000544 (=RFCOMMManager SocketHandler)
Need to open L2CAP channel first before opening RFCOMM channel 0
Opening socket 2 for type 2, invoking 'Open' on 10000610 (=HCI SocketHandler)
Can't open l2cap 3 on 1B:A4:8C:1B:08:00
Successfully opened L2CAP channel on socket -300
11 Jun 2011

-300 is the device not found error. During the inquiry the mbed builds a list of devices, the device you want to connect to must be in this list. Please look higher in the log for entries like "Inquiry Result:", I think you have the address backwards.

11 Jun 2011

oops. The address was really backwards. After correcting this is the result.

RFCOMM: EA=1, C/R=1, D=0, ch=2; control=1F (P/F=1); length=0
payload: 0:
Received DM IND (1F) for dlci 4
Socket 1 has been freed
.[0mACL Read pending..

Seems it is connected now. How to get an answer from the BT GPS ?

11 Jun 2011

No it is not connected. The GPS sent you a DM indication (Disconnected Mode). This typically means that there was something in the connection setup that it didn't like. Sometimes this can be solved by looking at the proposed parameters and the replies. Typically look at PN and MSC commands, there are other commands like RPN and FCOn/FCOff that the mbed does nothing or very little with. Please send me a private message with the entire log file and I'll try to find out what happened.

Please log in to post comments.