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

📄 comhand.cpp

📁 windows mobile RIL软件
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//    NKDbgPrintfW(TEXT("SendRILCmdHandleRsp\r\n"));
//    NKDbgPrintfW(TEXT("RILDrv : t : Executing command with ID: 0x%08x\r\n"), rpCmd->GetID());
#ifdef GPRS_CONTEXT_CACHING
    if (APIID_SETGPRSCONTEXT == rpCmd->GetAPIID())
    {
        szCmd = rpCmd->GetCmd();
        if (IsGPRSContextCommandCached(szCmd))
        {
            // This exact set GPRS context command has already been sent down.
            // some radios don't like this to be sent down again, and anyway, there's
            // no point, so just NOOP
            rpCmd->SetCmdOpt(CMDOPT_NOOP);
        }
    }
#endif // GPRS_CONTEXT_CACHING

    // If this is a deactivate command and a CRING has been detected just before this
    // we are likely in the scenario where a ATCI or non-S/R data call is being deactivated
    // before processing the incoming voice call (Connection Manager functionality). Class
    // B GPRS radios cannot process a GPRS deactivate request when a incoming call is
    // not processed yet, so we fake a response to this deactivate request without sending
    // it to the radio. Note that we depend on celltsp to deactivate the GPRS context after
    // the voice call is hung up because there is a mismatch between celltsp's picture (deactivated)
    // and the radio's picture of the context (activated) and celltsp forces its state on the radio.

    if (rpCmd->CmdOptIsSet(CMDOPT_DEACT)) {
        EnterCriticalSection(&g_csDeactCringLock); 
        if (TRUE == IncomingCallInProgress()) {
            rpCmd->SetCmdOpt(CMDOPT_NOOP);
            }
        LeaveCriticalSection(&g_csDeactCringLock);             
        }
            
    if (rpCmd->FNoOp())
    {
        // This command is a no-op, so we can avoid sending it

        // Allocate a new response
        pRsp = new CResponse(pRilDevice);
        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)
        pRsp->MakeOK();

        // We can't possibly fail a no-op
        hr = S_OK;
    }
    else if (g_bRadioOff && !rpCmd->FInit() && !rpCmd->CmdOptIsSet(CMDOPT_IGNORERADIOOFF))
    {
        // The radio is off and the current command is not acceptable
        // while the radio is in this state.
        //
        // Note: These conditions should really be handled in the radio with
        // a CME error, but the radio corresponding to the OEM1_DRIVER does
        // not behave well when some commands are sent when the radio is in
        // the minimum power mode. We keep this logic for the Wavecom driver
        // for consistency and testing purposes.
        //

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

        // Create an error response to indicate that the radio is off.
        if (!pRsp->MakeError(RIL_E_RADIOOFF))
            goto Error;
    }
    else
    {
        int NumRetries = rpCmd->GetRetries();
        while (NumRetries-->=0)
        {
            delete pRsp;
            pRsp = NULL;

            // This command wasn't a no-op, so we need to send it
            szCmd = rpCmd->GetCmd();
            DEBUGCHK(NULL != szCmd);

            // Let RIL know we're waiting for AT response
            pRilDevice->StartWaitingForRsp(rpCmd);

            // We want the response that follows the command we are about to send.
            // Discard any responses that have accidentally queued up.
            while (!g_pRspQ->FEmpty())
            {
                hr = g_pRspQ->Get(pRsp, 0);
                if (SUCCEEDED(hr))
                {
#ifdef DEBUG
                    DEBUGMSG(ZONE_INFO, (TEXT("RILDrv : i : CComHandle::SendRILCmdHandleRsp : Discarding extra queued response: %s\r\n"),
                               VerboseString(TString(pRsp->GetData()))));
#endif // DEBUG
                    delete pRsp;
                    pRsp = NULL;
                }
            }

#ifdef OEM2_DRIVER
            // On OEM2 we need to reset the CPINN event in case one has happened previously.
            if (rpCmd->CmdOptIsSet(CMDOPT_SETRADIOON) && (NULL != g_hCPINNEvent))
            {
                ResetEvent(g_hCPINNEvent);
            }
                                
#endif

#if defined(OEM1_GPRS_DEACT) || defined(EMP_DRIVER)
            if (rpCmd->CmdOptIsSet(CMDOPT_DEACT)) {
                EnterCriticalSection(&g_csGPRSDeactLock); 
                // In case the previous deactivation attempt did not result in a expected ME DEACT notification
                // after a response was received, we want to be sure to not confuse the response for that
                // transaction with that for this new transaction, so we clear it
                g_fDeactResponseRcvd = FALSE;
                LeaveCriticalSection(&g_csGPRSDeactLock);                 
                }
#endif

            bool fSendingSecondPart = false;
            // Write the command out to the com port
            UINT iCmdLen = strlen(szCmd);
            if (!WriteCmdsToComPort(pRilDevice, szCmd, iCmdLen))
            {
//#ifdef DEBUG
                DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : CComHandle::SendRILCmdHandleRsp : Error writing command: %s\r\n"), VerboseString(TString(szCmd))));
//#endif // DEBUG

                // Ignore the error. Even if we know that there was a problem writing to the com port,
                // we don't know what exactly was written nor whether we should expect a response.
                // It's best at this point to wait normally for a response. If no response is generated
                // due to the error, then we'll time out and continue as usual.
            }
            else
            {
                DWORD dwZone = rpCmd->CmdOptIsSet(CMDOPT_POLLING) ?
                    RILLOG_ZONE_CMD_POLLING : RILLOG_ZONE_CMD;
                if (!rpCmd->CmdOptIsSet(CMDOPT_SUPPRESSLOGGING))
                {
                    g_RilLog.LogEvent(dwZone, RILLOG_EVENT_SENDINGCMD, PrintableString(szCmd, iCmdLen));
                }
                else
                {
                    g_RilLog.LogEvent(dwZone, RILLOG_EVENT_SENDINGCMDSUPPRESSED, rpCmd->GetAPIID());
                }
#ifdef RIL_WATSON_REPORT
                // Store last command in info cache.
                EnterCriticalSection(&g_csRilInfoCache);
                strncpy(g_RilInfoCache.szLastCmd, szCmd, MAXLENGTH_CMD);
                g_RilInfoCache.fLastCmdSuppress = rpCmd->CmdOptIsSet(CMDOPT_SUPPRESSLOGGING);
                LeaveCriticalSection(&g_csRilInfoCache);
#endif //RIL_WATSON_REPORT
            }

            // If we've just sent a dial or answer command, prepare to handle a hangup command before getting a response
            if (rpCmd->FDial() || rpCmd->FAnswer())
            {
                // Launch a thread to wait for a hangup
                HANDLE hThread = NULL;
                hQuitEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
                if (hQuitEvent)
                {
                    HANGUP_THREAD_DATA* phtd = new HANGUP_THREAD_DATA;
                    if (phtd)
                    {
                        (void)memset(phtd, 0x00, sizeof(HANGUP_THREAD_DATA));
                        phtd->hQuitEvent = hQuitEvent;
                        phtd->pComDevice = this;
                        phtd->pRilDevice = pRilDevice;

                        hThread = CreateThread(NULL, 0, HangupThreadProc, (LPVOID)phtd, 0, NULL);
                    }

                    if (hThread)
                    {
                        // We created the thread
                        // Don't need a handle to the thread...
                        CloseHandle(hThread);
                        // The thread takes care of freeing pthd and closing the event handle
                        // Therefore, don't touch phtd after this point
                    }
                    else
                    {
                        // If we didn't create the thread, clean up and soldier on...
                        delete phtd;
                        phtd=NULL;
                        CloseHandle(hQuitEvent);
                        hQuitEvent=NULL;
                    }
                }
            }

            // Get the response out of the Response Queue
            hr = g_pRspQ->Get(pRsp, rpCmd->GetTimeout());
			DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : CComHandle::SendRILCmdHandleRsp : Got the response(Timeout=%d)\r\n"),rpCmd->GetTimeout()));
            if (SUCCEEDED(hr) && (rpCmd->CmdOptIsSet(CMDOPT_INTERMEDIATERESPONSE)) && (RIL_RESULT_OK == pRsp->GetNotifyCode()))
            {
                szCmd = rpCmd->GetCmdPart2();
                if (NULL != szCmd)
                {
                    // if there is a secondary command, send it out now.  This is primarily to handle SMS send commands
                    // that need an intermediary prompt.
                    pRilDevice->StopWaitingForRsp();
                    pRilDevice->StartWaitingForRsp(rpCmd);
                    fSendingSecondPart = true;
                    iCmdLen = strlen(szCmd);
                    if (!WriteCmdsToComPort(pRilDevice, szCmd, iCmdLen))
                    {
#ifdef DEBUG
                        DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : CComHandle::SendRILCmdHandleRsp : Error writing command: %s\r\n"), VerboseString(TString(szCmd))));
#endif // DEBUG
        
                        // Ignore the error. Even if we know that there was a problem writing to the com port,
                        // we don't know what exactly was written nor whether we should expect a response.
                        // It's best at this point to wait normally for a response. If no response is generated
                        // due to the error, then we'll time out and continue as usual.
                    }
                    else
                    {
                        DWORD dwZone = rpCmd->CmdOptIsSet(CMDOPT_POLLING) ?
                            RILLOG_ZONE_CMD_POLLING : RILLOG_ZONE_CMD;
                        if (!rpCmd->CmdOptIsSet(CMDOPT_SUPPRESSLOGGING))
                        {
                            g_RilLog.LogEvent(dwZone, RILLOG_EVENT_SENDINGCMD, PrintableString(szCmd, iCmdLen));
                        }
                        else
                        {
                            g_RilLog.LogEvent(dwZone, RILLOG_EVENT_SENDINGCMDSUPPRESSED, rpCmd->GetAPIID());
                        }
#ifdef RIL_WATSON_REPORT
                        // Store last command in info cache.
                        EnterCriticalSection(&g_csRilInfoCache);
                        strncpy(g_RilInfoCache.szLastCmd, szCmd, MAXLENGTH_CMD);
                        g_RilInfoCache.fLastCmdSuppress = rpCmd->CmdOptIsSet(CMDOPT_SUPPRESSLOGGING);
                        LeaveCriticalSection(&g_csRilInfoCache);
#endif //RIL_WATSON_REPORT
                    }
                }
                // Now wait for the secondary response which will be the real deal.
                delete pRsp;                
                hr = g_pRspQ->Get(pRsp, rpCmd->GetTimeout());
            }
            

            if (RIL_E_TIMEDOUT == hr)
            {
                // If we timed out, just print out a warning and (maybe) try again
                DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : CComHandle::SendRILCmdHandleRsp : Cmd timed out? (Before StopWaitingForRsp)\r\n")));
#ifdef RIL_LAST_ERROR
                g_dwLastError = MAKELONG(0, RADIO_TIMEOUTERROR);
#endif
                if (rpCmd->CmdOptIsSet(CMDOPT_SUPPRESSLOGGING))
                {
                    g_RilLog.LogEvent(RILLOG_ZONE_CMD, RILLOG_EVENT_CMDTIMEDOUTSUPPRESSED, rpCmd->GetAPIID());
                }
                else
                {
                    g_RilLog.LogEvent(RILLOG_ZONE_CMD, RILLOG_EVENT_CMDTIMEDOUT, PrintableString(szCmd, iCmdLen));
                }

#ifndef OEM2_DRIVER
                // Bug 29018 Send an extra AT\r to try to kick the modem out of its stupor!
                if (fSendingSecondPart)
                {
                    WriteCharsToComPort(pRilDevice, "\x1b\r", 2);
                    g_RilLog.LogEvent(RILLOG_ZONE_CMD, RILLOG_EVENT_SENDINGCMD, PrintableString("<esc>\r", 6));
                }
                else
                {
                    WriteCharsToComPort(pRilDevice, "AT\r", 3);
                    g_RilLog.LogEvent(RILLOG_ZONE_CMD, RILLOG_EVENT_SENDINGCMD, PrintableString("AT\r", 3));
                }
                HRESULT hrTmp;
                CResponse* pRspTmp = NULL;
                hrTmp = g_pRspQ->Get(pRspTmp, 500); // Wait 1/2 second for a response
                delete pRspTmp;
#endif // ! OEM2_DRIVER
            }

            // Let RIL know we're not waiting for AT response anymore
            pRilDevice->StopWaitingForRsp();

            // If we lauched a thread to wait for hangup, kill it
            if (hQuitEvent)
            {
                (void)SetEvent(hQuitEvent);
                hQuitEvent = NULL;
            }

            if (SUCCEEDED(hr))
            {
                // There is a remote chance that while waiting for a connect code
                // to go back into data mode, that we pick up some other rogue
                // response. We don't want RIL to go into data mode until we're
                // sure there is a connect. So, if we don't get a connect result,
                // try the command again.
                // If the command generates its own error response, then we will be
                // repeating this command/error for NUM_TIMEOUT_INIT_ATTEMPTS.
                // The last error response will be returned to the caller.
                if (rpCmd->FRequireConnectRsp() &&
                    RIL_NOTIFY_CONNECT != pRsp->GetNotifyCode())
                {
                    continue;
                }

                // If we cancelled the last dial command, turn the OK response into a NOCARRIER
                if (m_fCancelledDial)
                {
                    if (rpCmd->FDial() || rpCmd->FAnswer())
                    {
                        pRsp->SetCallAborted();
                    }
                    m_fCancelledDial = FALSE;
                }
                else if (rpCmd->FDial() && RIL_RESULT_ERROR == pRsp->GetNotifyCode() &&
                         rpCmd->CmdOptIsSet(CMDOPT_LONGDIALSTRING))
                {
                    pRsp->MakeError(RIL_E_DIALSTRINGTOOLONG);
                }
                break;
            }
            // See if we couldn't get the response for some reason
            else if (RIL_E_TIMEDOUT == hr)
            {
                // If we timed out, just print out a warning and (maybe) try again
                DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : CComHandle::SendRILCmdHandleRsp : Cmd timed out?\r\n")));

                // Send a hint to the response thread that we could have
                // bad data in the response buffer.
                pRilDevice->SetLastCommandTimedOut();
            }
            else
            {
                DEBUGCHK(RIL_E_CANCELLED == hr);
                goto Error;
            }
        } // for (i = 0; i < MaxRetries; i++)

        // Did we time out??
        if (RIL_E_TIMEDOUT == hr)
        {
#ifdef DEBUG
            DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : CComHandle::SendRILCmdHandleRsp : Command has timed out: %s\r\n"), VerboseString(TString(szCmd))));
#endif
            DEBUGCHK(NULL == pRsp);

            rfTimedOut = TRUE;

            // Additional operations may be requred to cancel timed out dial commands, so we need to return a different error
            if (rpCmd->FDial())
            {
                hr = RIL_E_NORESPONSETODIAL;
            }

            // We fail timed out commands
            pRsp = new CResponse(pRilDevice);
            if (!pRsp || !pRsp->MakeError(hr))
            {
                goto Error;
            }
        }
        else if (RIL_E_TIMEDOUT == pRsp->GetError())
        {
#ifdef DEBUG
            DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : CComHandle::SendRILCmdHandleRsp : Radio indicated timeout for command: %s\r\n"), VerboseString(TString(szCmd))));
#endif
            rfTimedOut = TRUE;
        }

        SetTimeoutStatus(rfTimedOut);
    } // else

    // If we issued a successful hangup command, exit out of the data mode
    if (rpCmd->FHangup() &&
        (RIL_RESULT_NOCARRIER == pRsp->GetNotifyCode() || RIL_RESULT_OK == pRsp->GetNotifyCode()))
    {
        (void)ExitDataMode();
    }

    // If we tried to get a connect response but failed,
    // then we've timed out.
    if (rpCmd->FRequireConnectRsp() &&
        (RIL_NOTIFY_CONNECT != pRsp->GetNotifyCode() &&
         RIL_RESULT_NOCARRIER != pRsp->GetNotifyCode()))
    {
        rfTimedOut = TRUE;
    }

#if defined (OEM1_DRIVER) || defined(OEM2_DRIVER) || defined(PHILIP_DRIVER)
    if (APIID_SETEQUIPMENTSTATE == rpCmd->GetAPIID() &&
     

⌨️ 快捷键说明

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