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

📄 atcmd.cpp

📁 ril source code for Windows CE
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    if (!fRet)
    {
        delete prtd;
        delete pCmd;
    }
    return fRet;
}

//
//
//
BOOL QueueRsp(CRilHandle* pRilDevice, CResponse*& rpRsp)
{
    FUNCTION_TRACE(QueueRsp);
    BOOL fRet = FALSE;

    // Remember that we're not waiting for AT response anymore
    pRilDevice->StopWaitingForRsp();

    // Queue the command response
    if (!g_pRspQ->Put(rpRsp, INFINITE))
    {
        DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : QueueRsp : Unable to Put CResponse\r\n")));
        goto Error;
    }
    rpRsp = NULL;

    fRet = TRUE;

    Error:
    return fRet;
}

BOOL ParseCLCCNotification(CRilHandle *pRilDevice, CCommand* pCmd, CResponse* pRsp)
{
    FUNCTION_TRACE(ParseCLCCNotification);
    BOOL Found=FALSE;
    LPCSTR szRsp;
    UINT nId;
    UINT nDirection;
    UINT nStatus;
    UINT nType;
    UINT nMultiParty;

    szRsp = pRsp->GetData();

    // Parse "+CLCC: "
    while (MatchStringAnywhere(szRsp,"+CLCC: ",szRsp))
    {
        Found=TRUE;

        // Parse "<id>"
        if (!ParseUInt(szRsp, TRUE, nId, szRsp))
        {
            continue;
        }

        // Parse ",<direction>"
        if (!MatchStringBeginning(szRsp, ",", szRsp) ||
            !ParseUInt(szRsp, TRUE, nDirection, szRsp))
        {
            continue;
        }

        // Parse ",<status>"
        if (!MatchStringBeginning(szRsp, ",", szRsp) ||
            !ParseUInt(szRsp, TRUE, nStatus, szRsp))
        {
            continue;
        }

        // Parse ",<type>"
        if (!MatchStringBeginning(szRsp, ",", szRsp) ||
            !ParseUInt(szRsp, TRUE, nType, szRsp))
        {
            continue;
        }

        // Parse ",<multiparty>"
        if (!MatchStringBeginning(szRsp, ",", szRsp) ||
            !ParseUInt(szRsp, TRUE, nMultiParty, szRsp))
        {
            continue;
        }

        if (nStatus==2)
        {
            RILDIALINFO rdi;
            rdi.cbSize = sizeof(rdi);
            rdi.dwParams = RIL_PARAM_DI_ALL;
            rdi.hrCmdId = pCmd->GetID();
            rdi.dwCallId = nId;
            (void)pRilDevice->BroadcastRealBlobNotification(RIL_NOTIFY_DIAL,
                                                &rdi, sizeof(RILDIALINFO));
            break;
        }
    }

    return Found;
}

//
// Thread responsible for sending commands from the Command Queue to COM port
//
DWORD WINAPI CmdThreadProc(LPVOID lpParameter)
{
    FUNCTION_TRACE(CmdThreadProc);
    DEBUGCHK(lpParameter != NULL);
    CRilHandle* pRilDevice = (CRilHandle*)lpParameter;
    DEBUGMSG(ZONE_TRACE, (TEXT("RILDrv : t : CmdThreadProc : Entering, pRilDevice=0x%x\r\n"),pRilDevice));
    const DWORD dwReturn = pRilDevice->CommandThread();
    DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : CmdThreadProc : THREAD IS EXITING, dwReturn=0x%x\r\n"),dwReturn));
    return dwReturn;
}

//
// Thread responsible for reading responses from COM port into the Response Queue
//
DWORD WINAPI ReadThreadProc(LPVOID lpParameter)
{
    FUNCTION_TRACE(ReadThreadProc);
    DEBUGCHK(lpParameter != NULL);
    CRilHandle* pRilDevice = (CRilHandle*)lpParameter;

    // Switch the thread into higher priority (to guarantee that the module's in buffer doesn't get overflown)
    if (!SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL))
    {
        DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : ReadThreadProc : Unable to raise priority of read thread!!\r\n")));
        return 0;
    }

    DEBUGMSG(ZONE_TRACE, (TEXT("RILDrv : t : ReadThreadProc : Entering, pRilDevice=0x%x\r\n"),pRilDevice));
    const DWORD dwReturn = pRilDevice->ResponseThread();
    DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : ReadThreadProc : THREAD IS EXITING, dwReturn=0x%x\r\n"),dwReturn));
    return dwReturn;
}

DWORD CRilHandle::CommandThread()
{
    FUNCTION_TRACE(CRilHandle::CommandThread);
    CCommand* pCmd = NULL;
    BOOL fBackToCmdMode = FALSE;
    DWORD dwReferenceTime;
    BOOL fDummy;
    HRESULT hr;

    DEBUGCHK(m_pComDevice != NULL);

    // Tell the main thread that we've reached the checkpoint
    GetCheckPoint()->Reached();

    if(g_rppPDDParams->fRadioSignonRequired && !m_pComDevice->WaitForRadioSignon(this))
    {
        DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : CRilHandle::CommandThread : WaitForRadioSignon failed\r\n")));
    }

    while (1)
    {
        // Make sure the module is prepared to handle the command before sending it (except for init commands)
        if (!WaitForCommandOrCancel())
        {
            DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : CRilHandle::CommandThread : Cancel was set\r\n")));
            goto Error;
        }

        // Get the next command from the Queue
        hr = g_pCmdQ->Get(pCmd, INFINITE);
        if (RIL_E_CANCELLED == hr)
        {
            DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : CRilHandle::CommandThread : Get returned RIL_E_CANCELLED\r\n")));
            goto Error;
        }
        DEBUGCHK(FALSE == FAILED(hr));

        // If we failed initialization, ignore any non-init commands in the queue
        if (m_fFailedInit && !pCmd->FInit())
        {
            HRESULT dwError = RIL_E_RADIOFAILEDINIT;
            pCmd->SendResponse(RIL_RESULT_ERROR, &dwError, sizeof(HRESULT));
            continue;
        }

        if (g_dwUnlocked)
        {
            DWORD dwTimeSinceUnlock = GetTickCount() - g_dwUnlocked;
            
// this number was picked by guesswork/experimentation
#define WAIT_FOR_MODULE_TO_SETTLE 500
            if (dwTimeSinceUnlock < WAIT_FOR_MODULE_TO_SETTLE)
            {
                // certain commands like COPS need to wait for the module to
                // "settle" after it's been unlocked.
                Sleep(WAIT_FOR_MODULE_TO_SETTLE - dwTimeSinceUnlock);
            }
            g_dwUnlocked = 0;
        }

        // Send the command to comm port
        if (!m_pComDevice->SendRILCmdHandleRsp(this, pCmd, fDummy, fDummy))
        {
            DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : CRilHandle::CommandThread : SendRILCmdHandleRsp failed\r\n")));
            // Don't give up and exit, just try again
            continue;
        }
        DEBUGCHK(NULL == pCmd);

        // If this command dropped the modem into the data mode, switch to data-mode operation
        if (m_pComDevice->FDataMode())
        {
            fBackToCmdMode = FALSE;
            dwReferenceTime = GetTickCount();
            ResetEvent(m_hDataEvent);

            while (!fBackToCmdMode)
            {
                BOOL fSentCommands = FALSE;

                // Sleep for a timeout
                WaitForSingleObject(m_hDataEvent, GetDataModeCmdDelay());

                // If there is a pending command in the queue, send it through the VSP backdoor
                if (!g_pCmdQ->FEmpty() &&
                    m_pComDevice->SendRILCmdsInDataMode(this, fBackToCmdMode))
                {
                    fSentCommands = TRUE;
                }

                // See if there's a command pending
                if (!fSentCommands &&
                    GetMaxDataModeTimeWithoutCmd() < GetTickCount() - dwReferenceTime)
                {
                    // The command queue is empty and we haven't sent a command for too long -- queue a no-op command
                    (void)QueueCmdIgnoreRsp(APIID_NONE, "AT\r", CMDOPT_NONE, g_TimeoutCmdNoOp,NULL, NULL,0,0,0);

                    (void)m_pComDevice->SendRILCmdsInDataMode(this, fBackToCmdMode);

                    fSentCommands = TRUE;
                }

                if (fSentCommands)
                {
                    // Update the reference time
                    dwReferenceTime = GetTickCount();
                }

                if (fBackToCmdMode || FCancelSet())
                {
                    break;
                }
#ifndef NO_RLSD_SUPPORT
                DWORD dwStatus;
                if (m_pComDevice->VirtGetCommModemStatus(&dwStatus) && !(dwStatus & MS_RLSD_ON))
                {
                    // RLSD is OFF, which means that data connection has been dropped
                    DEBUGMSG(ZONE_INFO, (TEXT("RILDrv : i : CRilHandle::CommandThread : Detected remote disconnect due to loss of RLSD\r\n")));

                    // Exit out of the data mode
                    (void)m_pComDevice->ExitDataMode();

                    if (!SetupCallListEvaluation ())
                    {
                        DEBUGMSG(ZONE_ERROR, (TEXT("CommandThread : E : Error setting up Call List Evaluation\r\n")));
                    }
                    fBackToCmdMode = TRUE;
                }
#endif
            }
        }
    }

    Error:
    delete pCmd;
    RIL_EVENTLOG_MSG((RILLOG_EVENT_COMMANDTHREADEXIT));
    return 0;
}

BOOL CRilHandle::HandleRxData(const char *szData, DWORD dwRead, bool fDataOnNotificationComPort)
{
    LPSTR szAppend = NULL;
    LPSTR szRemainder = NULL;
    UINT cbAppend;
    UINT cbRemainder;
    void* pBlob;
    UINT cbBlob;
    CResponse* pRsp = NULL;
    BOOL bSuccess=FALSE;
    HRESULT hr = E_FAIL;

    // DEBUGMSG(ZONE_INFO, (TEXT("RILDrv : i : ResponseThread read %s\r\n"), TString(PrintableString(szData, dwRead))));

    if (!AppendReadBytes(szData, dwRead, fDataOnNotificationComPort))
    {
        DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : CRilHandle::ResponseThread : AppendReadBytes failed\r\n")));
        goto Exit;
    }

    while (GiveUpReadBytes(szAppend, cbAppend, fDataOnNotificationComPort))
    {
        if (!cbAppend)
        {
            // Free memory occupied by szAppend
            delete[] szAppend;
            szAppend = NULL;
            break;
        }

        if (!pRsp)
        {
            // Allocate a new response, if we need it
            if (FAILED(PDD_GetResponseObject(pRsp)) || !pRsp)
            {
                DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : CRilHandle::ResponseThread : Unable to construct CResponse\r\n")));
                // Critically low on memory
                SignalCriticalError(RILLOG_EVENT_LOWMEMORY, __LINE__, __FILE__);
                goto Exit;
            }
        }

        if (m_fLastCommandTimedOut)
        {
            pRsp->SetPotentialBogusResponseFlag();
            m_fLastCommandTimedOut = FALSE;
        }

        if (!pRsp->AppendString(szAppend, cbAppend, const_cast<LPCSTR&>(szRemainder), cbRemainder, fDataOnNotificationComPort))
        {
            DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : CRilHandle::ResponseThread : AppendString failed\r\n")));
            // Critically low on memory
            SignalCriticalError(RILLOG_EVENT_LOWMEMORY, __LINE__, __FILE__);
            goto Exit;
        }

        // Does this contain a complete response?
        if (!szRemainder)
        {
            // No -- break out of this loop and wait for more data to come

            // Move the data back to the Read Bytes buffer
            if (!InheritReadBytes(pRsp, fDataOnNotificationComPort))
            {
                DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : CRilHandle::ResponseThread : InheritReadBytes failed\r\n")));
                // Critically low on memory
                SignalCriticalError(RILLOG_EVENT_LOWMEMORY, __LINE__, __FILE__);
                goto Exit;
            }

            // Free memory occupied by szAppend
            delete[] szAppend;
            szAppend = NULL;
            cbAppend = 0;
            break;
        }
        else
        {
            // We have complete response. Now is a good time to pass the response on to the logging application if one exists.
            LogATCommand(pRsp->GetData(), pRsp->GetLength(), ATCMD_LOG_RESPONSE);

⌨️ 快捷键说明

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