views:

201

answers:

1

Hi..

I'm developing a dll in visual-c++ for client side application to connect my pc to my android phone via bluetooth. I use this function to find my bluetooth service on the phone(see commented code!):

bool BlueRayXVR::findPairedService(GUID* guid, _SOCKET_ADDRESS* ret){
    this->checkStartup();

    HBLUETOOTH_DEVICE_FIND found_devices;

    BLUETOOTH_DEVICE_INFO device_info;
    device_info.dwSize = sizeof(device_info);

    BLUETOOTH_DEVICE_SEARCH_PARAMS search_criteria;
    search_criteria.dwSize = sizeof(BLUETOOTH_DEVICE_SEARCH_PARAMS);
    search_criteria.fReturnAuthenticated = TRUE;
    search_criteria.fReturnRemembered = FALSE;
    search_criteria.fReturnConnected = FALSE;
    search_criteria.fReturnUnknown = FALSE;
    search_criteria.fIssueInquiry = FALSE;
    search_criteria.cTimeoutMultiplier = 0;

    found_devices = BluetoothFindFirstDevice(&search_criteria, &device_info);

    if (found_devices == NULL)
    {
        _tprintf(TEXT("Error: \n%s\n"), getErrorMessage(WSAGetLastError(), error));
        return false;
    }

    WSAQUERYSET querySet;
    memset(&querySet, 0, sizeof(querySet));
    querySet.dwSize = sizeof(querySet);
    querySet.lpServiceClassId = guid;
    querySet.dwNameSpace = NS_BTH;

    SOCKADDR_BTH sab;
    memset (&sab, 0, sizeof(sab));
    sab.addressFamily  = AF_BTH;

    char addressAsString[1000];
    DWORD addressSize = sizeof(addressAsString);

    bool found = false;

    do
    {
        sab.btAddr = device_info.Address.ullLong;
        if (0 != WSAAddressToString((LPSOCKADDR)&sab, sizeof(sab), NULL, (LPWSTR)addressAsString, &addressSize)){
            _tprintf(TEXT("Error get the mac of the device %s\n.Going to the next device."), device_info.szName);
        }
        else{
            _tprintf(TEXT("Check on device %s%s for the service.\n"), device_info.szName, addressAsString);
            querySet.lpszContext =(LPWSTR) addressAsString;
            HANDLE service_lookup_handle;
            DWORD flags = LUP_FLUSHCACHE |LUP_RETURN_NAME | LUP_RETURN_ADDR | LUP_RETURN_BLOB;

            int result = WSALookupServiceBegin(&querySet, flags, &service_lookup_handle);

            if (0 == result)
            {
                BYTE buffer[2000];
                DWORD bufferLength = sizeof(buffer);
                WSAQUERYSET *pResults = (WSAQUERYSET*)&buffer;
                if(0 == WSALookupServiceNext(service_lookup_handle, flags, &bufferLength, pResults))
                {
                    _tprintf(TEXT("Service : %s\n"), pResults->lpszServiceInstanceName);
                    _tprintf(TEXT("Comment : %s\n"), pResults->lpszComment);
                    *ret = pResults->lpcsaBuffer->RemoteAddr;
                    found = true;

                /*  this->sock = socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);                      
                    if (0 == ::connect(sock, ret->lpSockaddr, ret->iSockaddrLength))
                    {
                        printf("connected");
                        //closesocket (*sock);
                        //return TRUE;
                    }
                    wprintf(L"errore %d: %s", WSAGetLastError(), this->getErrorMessage(WSAGetLastError(), this->error));
                    */
                }
                result = WSALookupServiceEnd(service_lookup_handle);
            }
            else
                _tprintf(TEXT("%s\nGoing to the next device..\n"), getErrorMessage(GetLastError(), error));
        }
    } while (BluetoothFindNextDevice(found_devices, &device_info) && !found);

    if(found_devices)
        BluetoothFindDeviceClose(found_devices);

    _tprintf(TEXT("No more device.\n"));
    return found;
}

And this one to connect to the phone:

bool BlueRayXVR::connect(_SOCKET_ADDRESS* host)
{
    this->sock = socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM); 
    if (this->sock == INVALID_SOCKET)
    {
        _tprintf(TEXT("Failed to get bluetooth socket! %s\n"), getErrorMessage(WSAGetLastError(), error));
        exit(1);
    }

    if (0 == ::connect(sock, host->lpSockaddr, host->iSockaddrLength))
    {
        printf("connected\n");
        return TRUE;
    }
    wprintf(L"errore %d: %s", WSAGetLastError(), this->getErrorMessage(WSAGetLastError(), this->error));
    return FALSE;
}

In my test console app i do:

       _SOCKET_ADDRESS address;
    memset (&address, 0, sizeof(address));
    if(blue->findPairedService(&blue->getDefaultGUID4XVR(), &address)){
        printf("service founded..try to connect..\n");
        if(blue->connect(&address))
            blue->read();
    }

The problem is that if i run my code i always get error 10049.

the strange thing is that if i uncomment the lines of code in findPairedService function and i just do

       _SOCKET_ADDRESS address;
    memset (&address, 0, sizeof(address));
    if(blue->findPairedService(&blue->getDefaultGUID4XVR(), &address)){

it succesfully connect to the phone....

what's wrong??

Thanks!

A: 

According to the docs, WSALookupServiceEnd "terminates the query and cleans up the context." Presumably that includes deleting/overwriting the values in the SOCKADDR struct that it returns, that you later use in the connect call. So just create your own bit of memory to store the struct, copy the returned bytes into it, and all should be fine.

BTW do you realise that doing Windows will automatically do any necessary SDP lookup; when connect() is given a Service Class Id (UUID/Guid) in the SOCKADDR_BTH.serviceClassId field it will do the SDP lookup and find the RFCOMM port number -- and you no longer need to do any of that stuff. :-)

alanjmcf
hi..i read about WSALookupServiceEnd. The weird thing is that if i call connect at the end of findPairedService() it works even if wsalookupserviceend has been already called. I also tried to use SOCKADDR_BTH setting serviceClassId to my UUID but i get error 10022..
hara