ошибка bluetooth winsock 10049 при подключении () - PullRequest
2 голосов
/ 18 мая 2010

Я разрабатываю dll на Visual C ++ для клиентского приложения, чтобы подключить мой компьютер к моему телефону Android через Bluetooth. Я использую эту функцию, чтобы найти мою службу bluetooth на телефоне (см. Закомментированный код!):

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;
}

А этот для подключения к телефону:

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;
}

В моем тестовом консольном приложении я делаю:

       _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();
    }

Проблема в том, что если я запускаю свой код, я всегда получаю ошибку 10049.

Странно то, что если я раскомментирую строки кода в функции findPairedService, и я просто делаю

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

это успешно подключиться к телефону ....

что не так ??

Спасибо!

1 Ответ

0 голосов
/ 20 мая 2010

Согласно документам, WSALookupServiceEnd "завершает запрос и очищает контекст". Предположительно, это включает в себя удаление / перезапись значений в структуре SOCKADDR, которую он возвращает, которую вы позже используете при вызове соединения. Так что просто создайте свой собственный бит памяти для хранения структуры, скопируйте в нее возвращенные байты, и все будет хорошо.

Кстати, понимаете ли вы, что Windows будет автоматически выполнять любой необходимый поиск SDP; когда connect() присваивается идентификатор класса обслуживания (UUID / Guid) в поле SOCKADDR_BTH.serviceClassId, он выполнит поиск SDP и найдет номер порта RFCOMM - и вам больше не нужно ничего делать. : -)

...