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

📄 atcmd.cpp

📁 ril source code for Windows CE
💻 CPP
📖 第 1 页 / 共 4 页
字号:
                    }
                    else if (RIL_NOTIFY_REGSTATUSCHANGED == pRsp->GetNotifyCode() && g_fSignalQualityReceived)
                    {
                        // Throw up a signal quality notification for good measure.
                        BroadcastRealBlobNotification(RIL_NOTIFY_SIGNALQUALITY, &g_rsq, sizeof(g_rsq));
                    }
                }
                delete pRsp;
                pRsp = NULL;
            }

            // Throw up a location update notification if required.
            if (g_fLocationInfoReceived)
            {
                BroadcastRealBlobNotification(RIL_NOTIFY_LOCATIONUPDATE, &g_rliLocationInfo, sizeof(g_rliLocationInfo));
                g_fLocationInfoReceived = FALSE;
            }

            // perform external calltype determination processing
            if (g_rfExternalCalltypeDetermination)
            {
                // Throw up a ring notification if required.  This is only required after a +CLIP notification is the first
                // notification to provide a reliable calltype after an initial CRING notification has been suppressed.
                // This is perfromed here to to stay consistent with the way the RIL handles other secondary or
                // after-the-fact notifications (e.g. SIM Toolkit notifications) that are sent along with primary notifications.
                EnterCriticalSection(&g_csRingingCallData);
                if (g_rcdRingingCallData.fForceRingNotification)
                {
                    DEBUGMSG(ZONE_INFO, (TEXT("RILDrv : E : CRilHandle::ResponseThread : Throwing delayed ring notification.\r\n")));
                    RILRINGINFO rri; memset(&rri,0,sizeof(rri));
                    rri.cbSize = sizeof(RILRINGINFO);
                    rri.dwParams |= RIL_PARAM_RI_CALLTYPE;
                    rri.dwCallType = g_rcdRingingCallData.dwCalltype;
                    g_rcdRingingCallData.fForceRingNotification = FALSE;
                    LeaveCriticalSection(&g_csRingingCallData);
                    BroadcastRealBlobNotification(RIL_NOTIFY_RING, &rri, sizeof(rri));
                }
                else
                {
                    LeaveCriticalSection(&g_csRingingCallData);
                }
            }

            if (g_fSystemChanged)
            {
                // Notify that the system and its capability are changed
                DEBUGMSG(ZONE_INFO, (TEXT("RILDrv : i : CRilHandle::ResponseThread : Sending RIL_NOTIFY_SYSTEMCHANGED and RIL_NOTIFY_SYSTEMCAPSCHANGED\r\n")));
                (void)BroadcastDWORDBlobNotification(RIL_NOTIFY_SYSTEMCHANGED, g_dwSystemType);
                (void)BroadcastDWORDBlobNotification(RIL_NOTIFY_SYSTEMCAPSCHANGED, g_dwSystemCaps);
                g_fSystemChanged = FALSE;
            }

            // Append the remaining data to the read bytes buffer
            if (cbRemainder && !AppendReadBytes(szRemainder, cbRemainder, fDataOnNotificationComPort))
            {
                DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : CRilHandle::ResponseThread : cbRemainder and AppendReadBytes failed\r\n")));
                goto Exit;
            }
        }

        // Free memory occupied by szAppend
        delete[] szAppend;
        szAppend = NULL;
        szRemainder = NULL;
        cbAppend = 0;
    }

    bSuccess=TRUE;
Exit:
    delete pRsp;
    return bSuccess;
}

#define RESP_DATA_BUF 1024
DWORD CRilHandle::ResponseThread()
{
    FUNCTION_TRACE(CRilHandle::ResponseThread);
    char szData[RESP_DATA_BUF];
    DWORD dwMask;
    DWORD dwRead;
    DWORD dwErrors;
    char szData2[RESP_DATA_BUF];
    DWORD dwRead2;

    DEBUGCHK(m_pComDevice != NULL);

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

    while (1)
    {
        // See if the thread needs to terminate
        if (FCancelSet())
        {
            break;
        }

        // Wait for more data
        if ( (!m_pComDevice->VirtWaitCommEvent(&dwMask)) || (!dwMask) )
        {
            // Due to the way the comm handle is passed around, we could have a race condition such that the event mask gets reset
            // just before or while we're waiting. To handle this case, we just check to see if the mask was reset out from
            // under us, and if it was, we just try again after resetting to a valid state.
            // This should never happen though
            DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : CRilHandle::ResponseThread : VirtWaitCommEvent failed\r\n")));
            DWORD dwCommMask=0;
            if (!m_pComDevice->VirtGetCommMask(&dwCommMask) || (dwCommMask!=g_rppPDDParams->dwDefaultCOMMask))
            {
                DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : CRilHandle::ResponseThread : VirtWaitCommEvent failed, CommMask was 0x%x\r\n"),dwCommMask));
                m_pComDevice->VirtSetCommMask( g_rppPDDParams->dwDefaultCOMMask );
            }
            continue;
        }

        if (dwMask & EV_ERR)
        {
            DEBUGMSG(ZONE_INFO, (TEXT("RILDrv : i : CRilHandle::ResponseThread : VirtWaitCommEvent returned EV_ERR\r\n")));

            // Error is detected on the downstream port
            if (m_pComDevice->VirtClearCommError(&dwErrors, NULL))
            {
                DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : CRilHandle::ResponseThread : Detected comm error: %x\r\n"), dwErrors));
            }
        }

        if (dwMask & EV_BREAK)
        {
            DEBUGMSG(ZONE_INFO, (TEXT("RILDrv : i : CRilHandle::ResponseThread : VirtWaitCommEvent returned EV_BREAK\r\n")));

            // Break is detected on the downstream port
            if (m_pComDevice->VirtClearCommBreak())
            {
                DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : CRilHandle::ResponseThread : Detected comm break\r\n")));
            }
        }

        if (dwMask & EV_RXCHAR)
        {
            // DEBUGMSG(ZONE_INFO, (TEXT("RILDrv : i : CRilHandle::ResponseThread : VirtWaitCommEvent returned EV_RXCHAR\r\n")));

            do
            {
                if (!m_pComDevice->Read(szData, RESP_DATA_BUF, dwRead))
                {
                    DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : CRilHandle::ResponseThread : Read failed\r\n")));
                    break;
                }

                if (!dwRead)
                {
                    DEBUGMSG(ZONE_INFO, (TEXT("RILDrv : i : CRilHandle::ResponseThread no data?!\r\n")));
                    break;
                }

#ifdef SIMULATE_HUNG_RADIO
                if (g_fSimulateHungRadio == TRUE)
                {
                    DEBUGMSG(ZONE_INFO, (TEXT("RILDrv : i : CRilHandle::ResponseThread Simulating hung radio, discarding data\r\n")));
                    dwRead = 0;
                    break;
                }
#endif

                if (!HandleRxData(szData,dwRead,false))
                {
                    DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : CRilHandle::ResponseThread: HandleRxData failed?!\r\n")));
                    break;
                }
            } while (dwRead==RESP_DATA_BUF);
        }

        if (dwMask & EV_EVENT2)
        {
            // DEBUGMSG(ZONE_INFO, (TEXT("RILDrv : i : CRilHandle::ResponseThread : VirtWaitCommEvent returned EV_RXCHAR\r\n")));

            do
            {
                if (!m_pComDevice->Read2(szData2, RESP_DATA_BUF, dwRead2))
                {
                    DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : CRilHandle::ResponseThread : Read failed\r\n")));
                    break;
                }

                if (!dwRead2)
                {
                    DEBUGMSG(ZONE_INFO, (TEXT("RILDrv : i : CRilHandle::ResponseThread no data?!\r\n")));
                    break;
                }

#ifdef SIMULATE_HUNG_RADIO
                if (g_fSimulateHungRadio == TRUE)
                {
                    DEBUGMSG(ZONE_INFO, (TEXT("RILDrv : i : CRilHandle::ResponseThread Simulating hung radio, discarding data\r\n")));
                    dwRead2 = 0;
                    break;
                }
#endif

                if (!HandleRxData(szData2,dwRead2,true))
                {
                    DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : CRilHandle::ResponseThread: HandleRxData failed?!\r\n")));
                    break;
                }
            } while (dwRead2==RESP_DATA_BUF);
        }
    }

    return 0;
}

/**********************************************************************/

ATCmd::ATCmd()
{
    InitializeCriticalSection( &m_cs );
    m_hEvent = NULL;
    m_hr = E_NOTIMPL;
    m_fInProgress = FALSE;
}

ATCmd::~ATCmd()
{
    if ( m_hEvent != NULL )
    {
        CloseHandle( m_hEvent );
        m_hEvent = NULL;
    }
    DeleteCriticalSection( &m_cs );
}

void
ATCmd::Dump() const
{
#ifdef DEBUG
    SYNCBLOCK( m_cs );
    DEBUGMSG(ZONE_TRACE,(TEXT("RILDrv : i : event       [%08x]"), m_hEvent));
    DEBUGMSG(ZONE_TRACE,(TEXT("RILDrv : i : hr          [%08x]"), m_hr));
    DEBUGMSG(ZONE_TRACE,(TEXT("RILDrv : i : in progress [%d]"), (int)m_fInProgress));
#endif
}

HRESULT
ATCmd::Execute( const char *cmd, DWORD dwOptions, DWORD dwTimeout)
{
    HRESULT hr = E_INVALIDARG;

    if ( cmd != NULL )
    {
        SYNCBLOCK( m_cs );

        hr = E_FAIL;

        if ( 0 == dwTimeout )
        {
            dwTimeout = 20L * 1000L;
        }

        HRESULT hr2 = Initialize();
        if ( SUCCEEDED( hr2 ) && !m_fInProgress )
        {
            if ( QueueCmdIgnoreRspWithData(APIID_NONE,              // appiid
                                            cmd,                    // szCmd
                                            dwOptions | CMDOPT_FORCEPARSE,      // dwOptions
                                            dwTimeout,                  // dwTimeout
                                            NULL,                   // Parse fn
                                            NULL,                   // Ptr to notification data
                                            0,                      // dwRetries
                                            0,                      // dwRetriesOnError
                                            0,                      // dwRetryOnErrorDelay
                                            &ATCmd::s_ParseFunc,    // parse fn with data
                                            this) )                 // Data
            {
                m_fInProgress = TRUE;

                {
                    UNSYNCBLOCK( m_cs );

                    /* wait till the result comes back */
                    DWORD dwWaitResult = WaitForSingleObject( m_hEvent, INFINITE );
                }

                /* return the result of the parsing */
                hr = m_hr;
            }
        }
    }

    return hr;
}

HRESULT
ATCmd::Initialize()
{
    HRESULT hr = E_OUTOFMEMORY;
    {
        SYNCBLOCK( m_cs );

        if ( m_hEvent == NULL )
        {
            m_hEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
        }

        if ( m_hEvent != NULL )
        {
            hr = S_OK;
        }
    }
    return hr;
}

HRESULT
ATCmd::s_ParseFunc( LPCSTR szRsp, void*& pBlob, UINT& cbBlob, PVOID& pfnParseData )
{
    HRESULT hr = E_INVALIDARG;

    pBlob  = NULL;
    cbBlob = 0;

    if ( pfnParseData != NULL )
    {
        ATCmd *pATCmd = reinterpret_cast<ATCmd*>( pfnParseData );
        if ( pATCmd != NULL )
        {
            hr = pATCmd->ParseFunc( szRsp );
        }
        else
        {
            hr = E_NOTIMPL;
        }
        pATCmd = NULL;
    }

    return hr;
}

HRESULT
ATCmd::ParseFunc( LPCSTR szRsp )
{
    HRESULT hr = Parse( szRsp );
    {
        SYNCBLOCK( m_cs );

        /* store the result of the parsing */
        m_hr = hr;

        m_fInProgress = FALSE;
    }

    /* notify */
    SetEvent( m_hEvent );

    hr = S_OK;
    return hr;
}

⌨️ 快捷键说明

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