⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 comhand.cpp

📁 手机RILGSM实现的源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        fWaitCommEvent = WaitCommEventWithTimeout(g_TimeoutDTRDrop, dwMask);

#ifdef WAVECOM_DRIVER
        DWORD dwStatus;
        if (GetCommModemStatus(m_hDownstream, &dwStatus))
        {

            if (!(dwStatus & MS_DSR_ON))
            {
                // DSR is off, which means that we're in command mode
                DEBUGMSG(ZONE_INFO, (TEXT("RILDrv : i : CComHandle::GetDTRDropResponse : Detected cmd mode due to loss of DSR\r\n")));

                fRet = TRUE;
            }
#ifndef NO_RLSD_SUPPORT
            if (!(dwStatus & MS_RLSD_ON))
            {
                // RLSD is off, which means that data connections has been dropped
                DEBUGMSG(ZONE_INFO, (TEXT("RILDrv : i : CComHandle::GetDTRDropResponse : Detected remote disconnect due to loss of RLSD\r\n")));

                // Notify all clients
                (void)pRilDevice->BroadcastRealBlobNotification(RIL_NOTIFY_CALLSTATECHANGED, NULL, 0);
                fRet = TRUE;
                goto Error;
            }
#endif
        }
#endif

        if (!fWaitCommEvent)
        {
            DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : CComHandle::GetDTRDropResponse : WaitCommEventWithTimeout failed\r\n")));
            goto Error;
        }
        
        DEBUGMSG(ZONE_TRACE, (TEXT("RILDrv : t : CComHandle::GetDTRDropResponse : WaitCommEventWithTimeout returned, dwMask=0x%x\r\n"),dwMask));
        if (dwMask & EV_ERR)
        {
            // Error is detected on the downstream port
            if (ClearCommError(m_hDownstream, &dwErrors, NULL))
            {
                DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : CComHandle::GetDTRDropResponse : Detected comm error: %x\r\n"), dwErrors));
            }
        }

        if (dwMask & EV_BREAK)
        {
            // Break is detected on the downstream port
            if (ClearCommBreak(m_hDownstream))
            {
                DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : CComHandle::GetDTRDropResponse : Detected comm break\r\n")));
            }
        }

        if (dwMask & EV_RXCHAR)
        {
            while (1)
            {
                // Get up to 1K of data
                if (!DOWNST_READFILE(m_hDownstream, szData, 1024, &dwRead))
                {
                    goto Error;
                }

                if (!dwRead)
                {
                    break;
                }
#ifdef DEBUG
                DEBUGMSG(ZONE_TRACE, (TEXT("RILDrv : t : CComHandle::GetDTRDropResponse : Read bytes(3): %s\r\n"), TString(PrintableString(szData, dwRead))));
#endif
                // Append what we got to the temporary buffer
                if (!bufTemp.Append(szData, dwRead))
                {
                    // Critically low on memory
                    SignalCriticalError(RILLOG_EVENT_LOWMEMORY, __LINE__, __FILE__);
                    goto Error;
                }

                // Get the accumulated string
                szTotal = bufTemp.GetData();
                cbTotal = bufTemp.GetLength();
#ifdef DEBUG
                DEBUGMSG(ZONE_TRACE, (TEXT("RILDrv : t : CComHandle::GetDTRDropResponse : Accumulated DTR response has %d chars: %s\r\n"), cbTotal,
                           TString(PrintableString(szTotal, cbTotal))));
#endif
                // Look for the indication of successful DTR drop
                if (MatchBytesAnywhere((BYTE*)szTotal, cbTotal, (BYTE*)"0\r\r\n", 4, pbRemainder))
                {
                    // We found "0\r\r\n", i.e. OK<CR> followed by <CR><LF> (starting an unsolicited notification)
                    DEBUGCHK(NULL != pbRemainder);

                    // Include the terminating <CR><LF> in the remainder
                    pbRemainder -= 2;
                }
                else if (MatchBytesEnd((BYTE*)szTotal, cbTotal, (BYTE*)"0\r", 2, pbRemainder))
                {
                    // We found '0\r" at the very end of the data
                    DEBUGCHK(NULL != pbRemainder);
                }

                if (pbRemainder)
                {
                    szRemainder = (LPCSTR)pbRemainder;
                    // Store any data before OK into the backup buffer
                    cbDataBeforeOK = szRemainder - szTotal - 2;
                    if (cbDataBeforeOK && !m_pBuffer->Append(szTotal, cbDataBeforeOK))
                    {
                        // Critically low on memory
                        SignalCriticalError(RILLOG_EVENT_LOWMEMORY, __LINE__, __FILE__);
                        goto Error;
                    }

                    // Store any data after OK in the response buffer of the read thread
                    cbDataAfterOK = cbTotal - (szRemainder - szTotal);
                    if (cbDataAfterOK && !pRilDevice->AppendReadBytes(szRemainder, cbDataAfterOK, false))
                    {
                        goto Error;
                    }
#ifdef DEBUG
                    DEBUGMSG(ZONE_INFO, (TEXT("RILDrv : i : CComHandle::GetDTRDropResponse : DTR successfuly dropped: %d bytes before, %d bytes after: %s\r\n"),
                               cbDataBeforeOK, cbDataAfterOK, TString(PrintableString(szRemainder,cbDataAfterOK))));
#endif
                    fRet = TRUE;
                    goto Error;
                }
            }
        }
    }

    Error:
    if (!fRet && bufTemp.GetLength())
    {
        // Append any data we've accumulated
        (void)m_pBuffer->Append(bufTemp.GetData(), bufTemp.GetLength());
        DEBUGMSG(ZONE_TRACE, (TEXT("RILDrv : t : CComHandle::GetDTRDropResponse : Stored %d bytes in the buffer\r\n"), bufTemp.GetLength()));
    }
    return fRet;
}


//
// A custom action callback passed to EnterExclusiveUse() below
//
void CComHandle::ResetCommMask(DWORD dwParam)
{
    FUNCTION_TRACE(ResetCommMask);
    DEBUGCHK(NULL != dwParam);

    HANDLE hCom = (HANDLE)dwParam;

    // Release any threads waiting on comm events
    (void)SetCommMask(hCom, 0);
}

HRESULT ParseGetSignalQuality(LPCSTR szRsp, void*& pBlob, UINT& cbBlob);
HRESULT ParseBatteryInfo(LPCSTR szRsp, void*& pBlob, UINT& cbBlob);

#ifdef SUPPRESS_ONLINE_SIGNAL_STRENGTH
extern char gszGetSignalQualityLast[128];
#endif

#ifdef SUPPRESS_ONLINE_BATTERY_INFO
extern char gszGetBatteryInfoLast[128];
#endif

//
// Interrupt other serial operations on the downstream port and send an RIL command
// WARNING: this routine enters Exclusive Use mode, effectively blocking any other virtual
//          serial port operation, so MAKE SURE not to block inside this routine.
//
BOOL CComHandle::SendRILCmdsInDataMode(CRilHandle* const pRilDevice, BOOL& rfBackToCmdMode)
{
    // FUNCTION_TRACE(CComHandle::SendRILCmdsInDataMode);
    DEBUGCHK(FALSE != m_fInited);
    DEBUGCHK(FALSE != m_fPortOpened);
    DEBUGCHK(FALSE != m_fDataMode);
    DEBUGCHK(m_hDownstream != INVALID_HANDLE_VALUE);

    DCB dcbOld; memset(&dcbOld,0,sizeof(dcbOld)); // zero struct
    COMMTIMEOUTS ctOld; memset(&ctOld,0,sizeof(ctOld)); // zero struct
    CCommand* pCmd = NULL;
    CCommand* pCmdPeeked = NULL;
    DWORD dwStartTime;
    UINT nAttempts;
    BOOL fInCmdMode = FALSE;
    HRESULT hr;
    DWORD dwMask;
    DWORD dwTimeAllowedInCmdMode;
    BOOL fEnteredExclusiveUse = FALSE;
    BOOL fPortInitSucceded = FALSE;
    BOOL fATOTimedOut;
    BOOL fDummy;
    BOOL fRet = FALSE;
    DWORD dwStatus;



    rfBackToCmdMode = FALSE;
    if (GetCommModemStatus(m_hDownstream, &dwStatus))
    {
#ifndef NO_RLSD_SUPPORT
        if (!(dwStatus & MS_RLSD_ON))
        {
            // RLSD is off, which means that data connections has been dropped
            DEBUGMSG(ZONE_INFO, (TEXT("RILDrv : i : CComHandle::SendRILCmdsInDataMode : Detected remote disconnect due to loss of RLSD\r\n")));
            fInCmdMode = TRUE;
        }
#endif
#ifdef WAVECOM_DRIVER
        if (!(dwStatus & MS_DSR_ON))
        {
            // DSR is off, which means that we're in cmd mode
            DEBUGMSG(ZONE_INFO, (TEXT("RILDrv : i : CComHandle::SendRILCmdsInDataMode : Detected cmd mode due to loss of DSR\r\n")));
            fInCmdMode = TRUE;
        }
#endif

    }

    // Send out all the no-op commands at the front of the queue without dropping out of data mode
    while (!fInCmdMode && g_pCmdQ->Peek(pCmdPeeked))
    {
        if (pCmdPeeked->FNoOp())
        {
            // Delete whatever was in the command structure
            delete pCmd;
            pCmd = NULL;

            // Get the next command
            hr = g_pCmdQ->Get(pCmd, 0);
            if (FAILED(hr))
            {
                goto Error;
            }

            // Send the command
            if (!SendRILCmdHandleRsp(pRilDevice, pCmd, rfBackToCmdMode, fDummy))
            {
                goto Error;
            }
            DEBUGCHK(NULL == pCmd);
        }
#ifdef SUPPRESS_ONLINE_SIGNAL_STRENGTH
        // Option to avoid getting signal strength while connected (avoids dropping DTR during data calls)
        else if (pCmdPeeked->GetParseFunc()==ParseGetSignalQuality)
        {
            DEBUGMSG(ZONE_INFO, (TEXT("RILDrv : i : CComHandle::SendRILCmdsInDataMode : Faking signal quality\r\n")));
            // Delete whatever was in the command structure
            delete pCmd;
            pCmd = NULL;

            // Get the next command
            hr = g_pCmdQ->Get(pCmd, 0);
            if (FAILED(hr))
            {
                goto Error;
            }

            // Allocate a new response
            CResponse *pRsp = new CResponse;
            if (!pRsp)
            {
                // Critically low on memory
                SignalCriticalError(RILLOG_EVENT_LOWMEMORY, __LINE__, __FILE__);
                goto Error;
            }

            // Create an OK response (since the command was a no-op, it can't fail)
            char *szRemainder;
            UINT cbRemainder;
            if (!pRsp->AppendString(gszGetSignalQualityLast, strlen(gszGetSignalQualityLast), szRemainder, cbRemainder, FALSE))
            {
                goto Error;
            }

            BOOL fHungUp;
            if (!pRilDevice->HandleRsp(pCmd, pRsp, fHungUp, g_bRadioOff))
            {
                goto Error;
            }
            DEBUGCHK(NULL == pCmd);
        }
#endif // SUPPRESS_ONLINE_SIGNAL_STRENGTH
#ifdef SUPPRESS_ONLINE_BATTERY_INFO
        // Option to avoid getting battery strength while connected (avoids dropping DTR during data calls)
        else if (pCmdPeeked->GetParseFunc()==ParseBatteryInfo)
        {
            DEBUGMSG(ZONE_INFO, (TEXT("RILDrv : i : CComHandle::SendRILCmdsInDataMode : Faking battery info\r\n")));
            // Delete whatever was in the command structure
            delete pCmd;
            pCmd = NULL;

            // Get the next command
            hr = g_pCmdQ->Get(pCmd, 0);
            if (FAILED(hr))
            {
                goto Error;
            }

            // Allocate a new response
            CResponse *pRsp = new CResponse;
            if (!pRsp)
            {
                // Critically low on memory
                SignalCriticalError(RILLOG_EVENT_LOWMEMORY, __LINE__, __FILE__);
                goto Error;
            }

            // Create an OK response (since the command was a no-op, it can't fail)
            char *szRemainder;
            UINT cbRemainder;
            if (!pRsp->AppendString(gszGetBatteryInfoLast, strlen(gszGetBatteryInfoLast), szRemainder, cbRemainder, FALSE))
            {
                goto Error;
            }

            BOOL fHungUp;
            if (!pRilDevice->HandleRsp(pCmd, pRsp, fHungUp, g_bRadioOff))
            {
                goto Error;
            }
            DEBUGCHK(NULL == pCmd);
        }
#endif // SUPPRESS_ONLINE_BATTERY_INFO
        else
        {
            break;
        }

    }
    pCmdPeeked = NULL;


    // See how much of the next quantum we can spend in the command mode
    dwTimeAllowedInCmdMode = CalculateCmdModeTime();
    DEBUGMSG(ZONE_TRACE, (TEXT("RILDrv : t : CComHandle::SendRILCmdsInDataMode : Time allowed in cmd mode: %d msec\r\n"), dwTimeAllowedInCmdMode));

    // See if there are any commands in the queue
    if (!g_pCmdQ->Peek(pCmdPeeked))
    {
        goto Error;
    }
    // See if the first command in the queue will take too long
    if (!FEnoughTimeToSendCmd(pCmdPeeked, dwTimeAllowedInCmdMode))
    {
        goto Error;
    }

    pCmdPeeked = NULL;

    // Get the comm mask used now
    (void)GetCommMask(m_hDownstream, &dwMask);

#ifndef DEDICATED_DATA_PORT
    SetEvent(m_hDataModeInterrupted);
#endif

    // Enter exclusive use mode
    if (!EnterExclusiveUse())
    {
        goto Error;
    }
    fEnteredExclusiveUse = TRUE;
    dwStartTime = GetTickCount();

    // Intialize downstream port for RIL use
    if (!InitComPortForRIL(&dcbOld, &ctOld))
    {
        goto Error;
    }
    fPortInitSucceded = TRUE;

    nAttempts = 0;
    while (!fInCmdMode && nAttempts < MAX_DTR_ATTEMPTS)
    {
#ifdef NO_DTR_SUPPORT
        WriteCharsToComPort(pRilDevice, "+++", 3);
#else
        // Drop the DTR
        (void)EscapeCommFunction(m_hDownstream, CLRDTR);
        DEBUGMSG(ZONE_INFO, (TEXT("RILDrv : i : CComHandle::SendRILCmdsInDataMode : Dropping DTR\r\n")));
#endif
        // Verify that we got an "OK" response
        fInCmdMode = GetDTRDropResponse(pRilDevice);
        
        (void)EscapeCommFunction(m_hDownstream, SETDTR);
        ++nAttempts;
    }

    SetTimeoutStatus(!fInCmdMode);

    // If we couldn't drop the DTR for some reason, bail for now
    if (!fInCmdMode)
    {
        DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : CComHandle::SendRILCmdsInDataMode : Could not drop DTR\r\n")));
        goto Error;
    }

    // Temporarily release threads waiting for command mode to operate
    if (!SetEvent(m_hCommandModeEvent))

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -