comhand.cpp

来自「ril source code for Windows CE」· C++ 代码 · 共 2,022 行 · 第 1/5 页

CPP
2,022
字号
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.

Module Name:

comhand.cpp

Abstract:


Notes:


--*/


#include "precomp.h"
#ifdef RIL_LAST_ERROR
#include "ccoreutl.h"
#endif

// Initialize radio off to true, since this is how we boot up.
BOOL g_bRadioOff = TRUE;
BOOL g_bSettingMinimumEquipmentState = FALSE;
#ifdef RIL_LAST_ERROR
extern DWORD g_dwLastError;
#endif

extern DWORD g_dwPrintSIMPINInfo;
extern BOOL SetupCallListEvaluation (void);

//
// Virtual serial device handle ctor
//
CComHandle::CComHandle()
: m_hDownstream(INVALID_HANDLE_VALUE),
m_hDownstream2(INVALID_HANDLE_VALUE),
m_hCommandModeEvent(NULL),
m_hCancelEvent(NULL),
#ifndef DEDICATED_DATA_PORT
m_hDataModeInterrupted(NULL),
#endif
#ifdef DEDICATED_DATA_PORT
m_hDataModeEvent(NULL),
#endif
m_pBuffer(NULL),
m_dwDownstreamBaudRate(115200),
m_dwStatQuantum(500),
m_pOwner(NULL),
m_fInited(FALSE),
m_fPortOpened(FALSE),
m_fDataMode(FALSE),
m_fCancelledDial(FALSE),
m_dwNumTimeouts(0),
m_dwMaxTimeouts(3)
{
    // FUNCTION_TRACE(CComHandle::CComHandle);
    DWORD dwTemp;

    InitializeCriticalSection(&m_csDataMode);
    InitializeCriticalSection(&m_csOwner);
    InitializeCriticalSection(&m_csStats);

    // Read the baud rate for the downstream modem
    if (GetRegistryDWORD(HKEY_LOCAL_MACHINE, g_tszRegKeyRIL, TEXT("BaudRate"), &dwTemp))
    {
        m_dwDownstreamBaudRate = dwTemp;
    }

    // Read the data mode interruption time
    if (GetRegistryDWORD(HKEY_LOCAL_MACHINE, g_tszRegKeyRIL, TEXT("DataModeInteruptionQuantum"), &dwTemp))
    {
        m_dwStatQuantum = dwTemp;
    }

    // Read the data mode interruption time
    if (GetRegistryDWORD(HKEY_LOCAL_MACHINE, g_tszRegKeyRIL, TEXT("MaxTimeouts"), &dwTemp))
    {
        m_dwMaxTimeouts = dwTemp;
    }

    // Intialize read and write data bickets to 0
    memset(m_rgdwReadStatBits,  0x00, STAT_BUCKETS * sizeof(DWORD));
    memset(m_rgdwWriteStatBits, 0x00, STAT_BUCKETS * sizeof(DWORD));

    // Set the initial timestamps for com activity stats
    m_dwReadStatTimestamp = GetTickCount();
    m_dwWriteStatTimestamp = m_dwReadStatTimestamp;
}


//
// Virtual serial device handle dtor
//
CComHandle::~CComHandle()
{
    // FUNCTION_TRACE(CComHandle::~CComHandle);
    if (m_fPortOpened)
    {
        (void)CloseDownstreamPort();
        m_fPortOpened = FALSE;
    }

    if (m_hCommandModeEvent)
    {
        CloseHandle(m_hCommandModeEvent);
        m_hCommandModeEvent = NULL;
    }

    if (m_hCancelEvent)
    {
        CloseHandle(m_hCancelEvent);
        m_hCancelEvent = NULL;
    }

#ifndef DEDICATED_DATA_PORT
    if (m_hDataModeInterrupted)
    {
        CloseHandle(m_hDataModeInterrupted);
        m_hDataModeInterrupted = NULL;
    }
#endif

#ifdef DEDICATED_DATA_PORT
    if (m_hDataModeEvent)
    {
        CloseHandle(m_hDataModeEvent);
        m_hDataModeEvent = NULL;
    }
#endif

    delete m_pBuffer;
    m_pBuffer = NULL;

    DeleteCriticalSection(&m_csDataMode);
    DeleteCriticalSection(&m_csOwner);
    DeleteCriticalSection(&m_csStats);
    m_fInited = FALSE;
}


//
// Virtual serial device handle initialization
//
BOOL CComHandle::Init()
{
    // FUNCTION_TRACE(CComHandle::Init);
    if (m_fInited)
    {
        goto Error;
    }

    // Create command-mode event
    m_hCommandModeEvent = CreateEvent(NULL, TRUE, TRUE, NULL);
    if (!m_hCommandModeEvent)
    {
        goto Error;
    }

    // Create cancel event
    m_hCancelEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    if (!m_hCancelEvent)
    {
        goto Error;
    }

#ifndef DEDICATED_DATA_PORT
    // Create data mode interrupt event
    m_hDataModeInterrupted = CreateEvent(NULL, TRUE, FALSE, NULL);
    if (!m_hDataModeInterrupted)
    {
        goto Error;
    }
#endif

#if DEDICATED_DATA_PORT

    // Create event to signal data mode to data port
    m_hDataModeEvent = CreateEvent(NULL, TRUE, FALSE, RILDRIVERDATAMODE_EVENT);
    if (!m_hDataModeEvent)
    {
        goto Error;
    }

#endif

    // Create backup buffer
    m_pBuffer = new CBuffer;
    if (!m_pBuffer)
    {
        goto Error;
    }

    // Initialize the shared resource underneath
    m_fInited = CSharedResource::Init(m_hCancelEvent);

    Error:
    return m_fInited;
}

// Causes a reboot if more than some number of commands in a row fail
void CComHandle::SetTimeoutStatus(BOOL bTimedOut)
{
    // FUNCTION_TRACE(CComHandle::SetTimeoutStatus);
    if (bTimedOut)
    {
        m_dwNumTimeouts++;
        if (m_dwNumTimeouts>=m_dwMaxTimeouts)
        {
            DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : CComHandle::SetTimeoutStatus : Too many timeouts, rebooting via CPM\r\n")));
            SignalCriticalError(RILLOG_EVENT_TOOMANYTIMEOUTS, __LINE__, __FILE__);
        }
    }
    else
    {
        m_dwNumTimeouts=0;
    }
}

//
// Open downstream port
//
BOOL CComHandle::OpenDownstreamPort()
{
    // FUNCTION_TRACE(CComHandle::OpenDownstreamPort);

#ifdef UNDER_CE
    DWORD dwFlags = 0;
#else   // UNDER_CE
    DWORD dwFlags = FILE_FLAG_OVERLAPPED;
#endif // UNDER_CE

    TCHAR tszComName[6];
    DWORD dwTimeout;
    DWORD nAttempts = 0;
    DWORD nMaxAttempts;
    BOOL fRet = FALSE;

    // Get the COM port name
    if (!GetRegistrySZ(HKEY_LOCAL_MACHINE, g_tszRegKeyRIL, TEXT("ComPort"), tszComName, 6))
    {
        _tcsncpyz(tszComName, TEXT("COM2:"), 6);
    }

    DEBUGMSG(ZONE_TRACE, (TEXT("RILDrv : t : CComHandle::OpenDownstreamPort : Connecting to COM port: %s\r\n"), tszComName));

    TCHAR tszComNameNotifications[6];
    // Get the Notification COM port name

    tszComNameNotifications[0] = L'\0';
    if (g_rppPDDParams->fNotificationPortSupported) {
        if (!GetRegistrySZ(HKEY_LOCAL_MACHINE, g_tszRegKeyRIL, TEXT("ComPortNotifications"), tszComNameNotifications, 6)) {
            _tcsncpyz(tszComName, TEXT("COM2:"), 6);
            }
        DEBUGMSG(ZONE_TRACE, (TEXT("RILDrv : t : CComHandle::OpenDownstreamPort : Connecting to Notifications COM port: %s\r\n"), tszComNameNotifications));
        }

    // Get the max number of times we should try to open the COM port
    if (!GetRegistryDWORD(HKEY_LOCAL_MACHINE, g_tszRegKeyRIL, TEXT("MaxOpenAttempts"), &nMaxAttempts))
    {
        nMaxAttempts = 3;
    }

    // Get the amount of time we should sleep between attempts
    if (!GetRegistryDWORD(HKEY_LOCAL_MACHINE, g_tszRegKeyRIL, TEXT("OpenTimeout"), &dwTimeout))
    {
        dwTimeout = 1000;
    }

    // Open the COM port
    while (1)
    {
        // Try to open the COM port
        m_hDownstream = CreateFile(tszComName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, dwFlags, NULL);

        // If we succeeded or exhausted the number of attempts, quit looping
        nAttempts++;
        if (m_hDownstream != INVALID_HANDLE_VALUE || nAttempts >= nMaxAttempts)
        {
            break;
        }

        // Sleep the required amount of time and try again
        Sleep(dwTimeout);
    }

    if (g_rppPDDParams->fNotificationPortSupported) {
            nAttempts = 0;
            // Open the Notifications COM port
            while (1)
            {
                // Try to open the COM port
                m_hDownstream2 = CreateFile(tszComNameNotifications, GENERIC_READ, 0, NULL, OPEN_EXISTING, dwFlags, NULL);

                // If we succeeded or exhausted the number of attempts, quit looping
                nAttempts++;
                if (m_hDownstream2 != INVALID_HANDLE_VALUE || nAttempts >= nMaxAttempts)
                {
                    break;
                }

                // Sleep the required amount of time and try again
                Sleep(dwTimeout);
            }

            if (INVALID_HANDLE_VALUE == m_hDownstream2)
            {
                DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : CComHandle::OpenDownstreamPort : Couldn't open downstream port 2\r\n")));
                goto Error;
            }
        }
    
    if (INVALID_HANDLE_VALUE == m_hDownstream)
    {
        DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : CComHandle::OpenDownstreamPort : Couldn't open downstream port\r\n")));
        goto Error;
    }

    if (!InitCommState(NULL))
    {
        DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : CComHandle::OpenDownstreamPort : Couldn't Init comm state\r\n")));
        goto Error;
    }

    m_fPortOpened = TRUE;
    fRet = TRUE;

    Error:
    if (!fRet)
    {
        if (INVALID_HANDLE_VALUE != m_hDownstream)
        {
            (void)CloseHandle(m_hDownstream);
        }
        
        if (g_rppPDDParams->fNotificationPortSupported) {
                if (INVALID_HANDLE_VALUE != m_hDownstream2)
                {
                    (void)CloseHandle(m_hDownstream2);
                }
            }
    }
    return fRet;
}


//
// Close downstream port
//
BOOL CComHandle::CloseDownstreamPort()
{
    // FUNCTION_TRACE(CComHandle::CloseDownstreamPort);
    BOOL fRet = FALSE;

    if (!m_fInited || !m_fPortOpened || INVALID_HANDLE_VALUE == m_hDownstream)
    {
        goto Error;
    }

    if (g_rppPDDParams->fNotificationPortSupported) {
            if (INVALID_HANDLE_VALUE == m_hDownstream2)
            {
                goto Error;
            }
        }
    
    // Release all the waiting operations
    (void)SetEvent(m_hCancelEvent);

    // Close the downstream port
    (void)CloseHandle(m_hDownstream);
    m_hDownstream = INVALID_HANDLE_VALUE;
    
    if (g_rppPDDParams->fNotificationPortSupported) {
            // Close the downstream notifications port
            (void)CloseHandle(m_hDownstream2);
            m_hDownstream2 = INVALID_HANDLE_VALUE;
        }

    fRet = TRUE;

    Error:
    return fRet;
}


//
// Serial read
//
BOOL CComHandle::Read(void* pBuf, const UINT cb, DWORD& rdwRead) const

⌨️ 快捷键说明

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