How to send only one Byte over a Bluetooth Socket (RFCOMM, SPP) or How to flush a Bluetooth Socket (RFCOMM, SPP)?

6.9k Views Asked by At

I have set up a connection between my PC and a Bluetooth device using a MS Bluetooth socket based on RFCOMM and Serial Port Profile (SPP).

There is no problem to receive data continuously. However, if want to send one byte (which acts as a command), the device does not receive it.

Here are the code snippets (error handling omitted):

SOCKET s = ::socket (AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM); //successful
...
SOCKADDR_BTH btSockAddr;
ZeroMemory(&btSockAddr, sizeof(SOCKADDR_BTH));

btSockAddr.addressFamily = AF_BTH;
btSockAddr.btAddr = DEVICE_ADDRESS;
btSockAddr.serviceClassId = RFCOMM_PROTOCOL_UUID; //SerialPortServiceClass_UUID
btSockAddr.port = BT_PORT_ANY;
...
err = ::connect(s, reinterpret_cast<SOCKADDR*>(&btSockAddr), sizeof(SOCKADDR_BTH)); //successful

char cmd = 'm'; //switch mode
int sentSize = ::send(s, &cmd, 1, 0); //successful, sentSize = 1

...
for(;;)
{
    char out;
    int recvSize = ::recv(s, &out, 1, 0);   //successful, receive byte by byte
    ...
}

Though ::send returns successfully, the device's mode has not changed. So, apparently, the byte given has not been transmitted and still resides in the send buffer (that is my assumption). Is there a way to force sending only one byte, i.e. to send unbuffered?

I can rule out a mistake on device side. Setting up the Bluetooth link manually (Windows Notification Bar / Bluetooth / Add device) und using Putty to establish a serial connection, both receiving and sending are working as expected.

OS: Windows 7 IDE: Visual Studio 2010

2

There are 2 best solutions below

2
On

OK, try number 2! :-)

This line is probably the problem:

btSockAddr.serviceClassId = RFCOMM_PROTOCOL_UUID; //SerialPortServiceClass_UUID 

Why did you change from SerialPortServiceClass_UUID? With RFCOMM_PROTOCOL_UUID that tells the RFCOMM socket to connect to any service in the SDP (service database) that uses protocol RFCOMM. You want instead to have:

btSockAddr.serviceClassId = SerialPortServiceClass_UUID 

(Of course that wouldn't actaully cause the problem you are seeing if the device has only one RFCOMM service in the SD).

1
On

When you use Putty with the virtual COM port do you hit return after entering your single command character?

I suspect so, and thus you need to send CR+LF after the command byte. So pass a buffer of size three to send (i.e. { <command>, 0x0D, 0x0A }). Your device is presumably line based and it waiting for a "line".