views:

220

answers:

2

hi

I need to create a custom bluetooth service and I have to develop it using c++. I read a lot of examples but I didn't success in publishing a new service with a custom UUID. I need to specify a UUID in order to be able to connect to the service from an android app. This is what i wrote:

GUID service_UUID = { /* 00000003-0000-1000-8000-00805F9B34FB */
    0x00000003,
    0x0000,
    0x1000,
    {0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB}
};
    SOCKET s, s2;
SOCKADDR_BTH sab
if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0)
    return 1;
printf("installing a new service\n");

s = socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
if (s == INVALID_SOCKET)
{
    printf ("Socket creation failed, error %d\n", WSAGetLastError());
    return 1;
}

memset (&sab, 0, sizeof(sab));
sab.addressFamily  = AF_BTH;
sab.port = BT_PORT_ANY;
sab.serviceClassId = service_UUID;


if (0 != bind(s, (SOCKADDR *) &sab, sizeof(sab)))
{
    printf ("bind() failed with error code %d\n", WSAGetLastError());
    closesocket (s);
    return 1;
}
int result=sizeof(sab);
getsockname(s,(SOCKADDR *) &sab, &result );
printSOCKADDR_BTH(sab);

if(listen (s, 5) == 0)
    printf("listen() is OK! Listening for connection... :)\n");
else
    printf("listen() failed with error code %d\n", WSAGetLastError());

printf("waiting connection");

for ( ; ; )
{
    int ilen = sizeof(sab2);
    s2 = accept (s, (SOCKADDR *)&sab2, &ilen);
    printf ("accepted");
}
if(closesocket(s) == 0)
    printf("closesocket() pretty fine!\n");
if(WSACleanup () == 0)
    printf("WSACleanup() is OK!\n");
return 0;

When i print the SOCKADDR_BTH structure retrieved with get getsockname i get an UUID that is not the mine. Furthermore if i use the UUID read from getsockname to connect the Android application the connection fails with this exception:

java.io.IOException: Service discovery failed

Could you help me??

Thanks!

A: 

"Discovery Failed" Means the phone sent out a broadcast message asking for a connection with the specified bluetooth MAC address, but nobody with that address responded.

Double check the Bluetooth MAC address of the remote device.

Brad Hein
if i'm not wrong this is the only way i can establish a bluetooth connection through android http://developer.android.com/reference/android/bluetooth/BluetoothDevice.html#createRfcommSocketToServiceRecord%28java.util.UUID%29 How could I use MAC address?
hara
BTDevice = BTAdapter.getRemoteDevice(PeerMAC); BTSocket = BTDevice.createRfcommSocketToServiceRecord(UUID);
Brad Hein
this is what i do..but UUID is not a mac address..if i'm not wrong..
hara
Your statement doesn't make sense. Of course the UUID is not a MAC address. If that is what you're already doing then you need to double check the bluetooth MAC that you are using. You cannot make a bluetooth connection without knowing the peer device's MAC, as shown in my code snippet above.
Brad Hein
sorry..i didn't realize the first statement!i will try that.Thanks!
hara
+1  A: 

You have to create the SDP record and publish it with WSASetService before bind and wait for connections. Follow this tutorial, and you'll be able to receive connections.

albtraum
Hi..yes..i saw that tutorial but(QUOTE):"The format of the SDP information that’s published is so complex that Windows CE provides a special COM control to construct and deconstruct SDP records...As a shortcut, many Bluetooth applications compose a generic record, either hand-assembling the record or using an example tool named BthNsCreate (available in the Windows CE SDK) that’s provided in the Platform Builder." I have already asked about BthNsCreate http://stackoverflow.com/questions/2763966/how-to-get-an-sdp-record-for-bluetooth-service Any suggestions?
hara
You are using BT_PORT_ANY in the structure, so that's why you get a UUID different from yours, I think.
albtraum
The documentation of SOCKADDR_BTH structure says that the serviceClassId is ignored if you're using bind. In my application(server), I set the channel(the port parameter) to 0 and the last byte of SDP to 0; At the offset 8 of the record you have the UUID of your service and the last byte, the channel. Publishing the record, the UUID and channel are binded, and you can look for the channel in the client using your UUID.In the client app, I don't set the channel, only the UUID of the service, and the client make the SDP search to find the channel.
albtraum