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

📄 handler.cpp

📁 WinCE5.0部分核心源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                m_AGProps.fNotifyCallWait = FALSE;
            }

            fSendOk = TRUE;
            break;
        }
        pszParams++;
    }

    if (fSendOk) {
        SendATCommand(AT_OK, sizeof(AT_OK)-1);
    }
    else {
        SendATCommand(AT_ERROR, sizeof(AT_ERROR)-1);
    }

    Unlock();

    DEBUGMSG(ZONE_HANDLER, (L"BTAGSVC: --AGEngine::OnEnableCallWaiting\n"));
}


// This method is called by the peer to enable "call line identification".
void CAGEngine::OnEnableCLI(LPSTR pszParams, int cchParam)
{
    DEBUGMSG(ZONE_HANDLER, (L"BTAGSVC: Calling AGEngine::OnEnableCLI\n"));

    BOOL fSendOk = FALSE;

    Lock();

    ASSERT(m_AGProps.state >= AG_STATE_CONNECTING);

    while (*pszParams != '\0') {
        if (*pszParams != ' ') {
            if (*pszParams == '1') {
                DEBUGMSG(ZONE_HANDLER, (L"BTAGSVC: Enabling CLI.\n"));
                m_AGProps.fNotifyCLI = TRUE;
            }
            else {
                DEBUGMSG(ZONE_HANDLER, (L"BTAGSVC: Disabling CLI.\n"));
                m_AGProps.fNotifyCLI = FALSE;
            }

            fSendOk = TRUE;
            break;
        }
        pszParams++;
    }

    if (fSendOk) {
        SendATCommand(AT_OK, sizeof(AT_OK)-1);
    }
    else {
        SendATCommand(AT_ERROR, sizeof(AT_ERROR)-1);
    }

    Unlock();
}


// This method is called when the parser receives an unknown command
void CAGEngine::OnUnknownCommand(void)
{
    DEBUGMSG(ZONE_HANDLER, (L"BTAGSVC: Calling AGEngine::OnUnknownCommand\n"));

    Lock();

    ASSERT(m_AGProps.state >= AG_STATE_CONNECTING);
    
    if (m_AGProps.state >= AG_STATE_CONNECTING) {
        SendATCommand(AT_ERROR, sizeof(AT_ERROR)-1);
    }
    
    Unlock();
}


// This method is called when the peer device responds with OK
void CAGEngine::OnOK(void)
{
    DEBUGMSG(ZONE_HANDLER, (L"BTAGSVC: Got OK response from peer.\n"));
}


// This method is called when the peer devices responds with ERROR
void CAGEngine::OnError(void)
{
    DEBUGMSG(ZONE_WARN, (L"BTAGSVC: Got ERROR response from peer.\n"));
}


// This method is called when service goes up or down
void CAGEngine::OnServiceCallback(BOOL fHaveService)
{
    DEBUGMSG(ZONE_HANDLER, (L"BTAGSVC: OnServiceCallback: %d\n", fHaveService));

    if (m_AGProps.fHaveService != fHaveService) {
        Lock();
        
        m_AGProps.fHaveService = fHaveService;
        if (m_AGProps.fIndicatorUpdates) {
            CHAR szCommand[MAX_SEND_BUF];            
            int cbCommand = _snprintf(szCommand, MAX_SEND_BUF-1, "\r\n+CIEV:1,%d\r\n", (fHaveService?1:0));
            szCommand[MAX_SEND_BUF-1]='\0';
            if (cbCommand > 0) {
                SendATCommand(szCommand, cbCommand);
            }
        }

        Unlock();
    }
}


// This method is called by the Network when an event has occured
void CAGEngine::OnNetworkEvent(DWORD dwEvent, LPVOID lpvParam, DWORD cbParam)
{
    switch (dwEvent) {
        case NETWORK_EVENT_CALL_IN:
            OnNetworkCallIn((LPSTR)lpvParam);
            break;
        case NETWORK_EVENT_CALL_OUT:
            OnNetworkCallOut();
            break;
        case NETWORK_EVENT_CALL_CONNECT:
            OnNetworkAnswerCall();
            break;
        case NETWORK_EVENT_CALL_BUSY:
        case NETWORK_EVENT_CALL_DISCONNECT:
            if (sizeof(DWORD) > cbParam) {
                DEBUGMSG(ZONE_ERROR, (L"BTAGSVC: Received error event from network component with invalid param size.\n"));
                ASSERT(0);                    
            }
            else {
                OnNetworkHangupCall((DWORD)lpvParam, (NETWORK_EVENT_CALL_BUSY == dwEvent) ? HANGUP_DELAY_BUSY_MS : HANGUP_DELAY_MS);
            }
            break;
        case NETWORK_EVENT_CALL_REJECT:        
            OnNetworkRejectCall();
            break;
        case NETWORK_EVENT_RING:
            OnNetworkRing();
            break;
        case NETWORK_EVENT_CALL_INFO:
            OnNetworkInfo((LPSTR)lpvParam);
            break;
        case NETWORK_EVENT_FAILED:
            if (sizeof(NetworkCallFailedInfo) > cbParam) {
                DEBUGMSG(ZONE_ERROR, (L"BTAGSVC: Received error event from network component with invalid param size.\n"));
                ASSERT(0);                    
            }
            else {
                OnNetworkCallFailed(((NetworkCallFailedInfo*)lpvParam)->usCallType, ((NetworkCallFailedInfo*)lpvParam)->dwStatus);
            }            
            break;            
        default:
            DEBUGMSG(ZONE_WARN, (L"BTAGSVC: Unknown network event: %d\n", dwEvent));
            ASSERT(0);
    }
}


// This method is called by the Network when a call is answered
void CAGEngine::OnNetworkAnswerCall(void)
{
    DEBUGMSG(ZONE_HANDLER, (L"BTAGSVC: Calling AGEngine::OnNetworkAnswerCall\n"));

    Lock();
    
    if ((m_AGProps.state >= AG_STATE_CONNECTED) && m_AGProps.fIndicatorUpdates) {
        SendATCommand("\r\n+CIEV:2,1\r\n", 13); // Call is active
        SendATCommand("\r\n+CIEV:3,0\r\n", 13); // Call Setup is completed
    }
    m_AGProps.usCallSetup = 0;
    m_AGProps.fInCall = TRUE;

    if ((m_AGProps.state >= AG_STATE_CONNECTED) && m_AGProps.fUseHFAudio) {
		if (m_AGProps.usCallType == AG_CALL_TYPE_IN) {
	        DWORD dwErr = OpenAudioChannel();
	        if ((ERROR_SUCCESS != dwErr) && (ERROR_ALREADY_INITIALIZED != dwErr)) {
	            DEBUGMSG(ZONE_ERROR, (L"BTAGSVC: Error opening audio connection: %d\n", dwErr));
	        }
		}
    }
    else if (m_AGProps.fPowerSave || !m_AGProps.fHandsfree) {
        // Call was answered in the handset close connection in power-save mode
        CloseControlChannel();
    }

    m_AGProps.fUseHFAudio = FALSE;

    Unlock();
}


// This method is called by the Network when a call is disconnected (or busy)
void CAGEngine::OnNetworkHangupCall(DWORD dwRemainingConnections, DWORD dwHangUpDelayMS)
{
    DEBUGMSG(ZONE_HANDLER, (L"BTAGSVC: Calling AGEngine::OnNetworkHangupCall\n"));

    Lock();

    if (dwRemainingConnections == 0) {
        if (m_AGProps.state >= AG_STATE_CONNECTED) {
            if (m_AGProps.fIndicatorUpdates && m_AGProps.fInCall) {
                // For hangup call, send call indicator as inactive
                SendATCommand("\r\n+CIEV:2,0\r\n", 13); 
            }
            else if (m_AGProps.fIndicatorUpdates) {
                // For rejected call, send callsetup indicator as inactive
                SendATCommand("\r\n+CIEV:3,0\r\n", 13); 
            }

            wcscpy(m_wszCLI, L"");

            m_fCancelCloseConnection = FALSE;
            m_CloseCookie = m_pTP->ScheduleEvent(TimeoutConnection, (LPVOID)this, HANGUP_DELAY_MS);
        }
        
        m_AGProps.usCallSetup = 0;
        m_AGProps.fInCall = FALSE;
    }   
    else {
        DWORD dwState = 0;
        DWORD dwErr = BthAGNetworkGetCallState(&dwState);

        // We have a call connected, if it is not active or on hold,
        // we need to do some clean up
        
        if ((ERROR_SUCCESS == dwErr) &&
            !(dwState & NETWORK_FLAGS_STATE_HOLD) && 
            !(dwState & NETWORK_FLAGS_STATE_ACTIVE)) {            
            if (m_AGProps.fIndicatorUpdates && m_AGProps.fInCall) {
                // For hangup call, send call indicator as inactive
                SendATCommand("\r\n+CIEV:2,0\r\n", 13); 
            }

            wcscpy(m_wszCLI, L"");
            m_AGProps.fInCall = FALSE;
        }        
    }

    Unlock();
}


// This method is called by the Network when a call is rejected
void CAGEngine::OnNetworkRejectCall(void)
{
    DEBUGMSG(ZONE_HANDLER, (L"BTAGSVC: Calling AGEngine::OnNetworkRejectCall\n"));

    Lock();

    m_AGProps.usCallSetup = 0;
    m_AGProps.fInCall = FALSE;

    if (m_AGProps.state >= AG_STATE_CONNECTED) {
        if (m_AGProps.fIndicatorUpdates) {
            SendATCommand("\r\n+CIEV:3,0\r\n", 13); // Call Setup is complete
        }

        wcscpy(m_wszCLI, L"");

        CloseAudioChannel();
        if (m_AGProps.fPowerSave || !m_AGProps.fHandsfree) {
            CloseControlChannel();
        }
    }
    
    Unlock();
}


// This method is called by the Network when an incoming call is placed
void CAGEngine::OnNetworkCallIn(LPSTR pszNumber)
{
    DEBUGMSG(ZONE_HANDLER, (L"BTAGSVC: Calling AGEngine::OnNetworkCallIn\n"));

    Lock();

    if (m_AGProps.fInCall) {
        // Already in a call, send call-wait signal but do not accept call.
        if (m_AGProps.fNotifyCallWait) {
            CHAR szCommand[MAX_SEND_BUF];
            int cbCommand;
            
            if (pszNumber[0] == 0) {
                cbCommand = _snprintf(szCommand, MAX_SEND_BUF-1, "\r\n+CCWA:\"0\",0,1\r\n");
            }
            else {
                cbCommand = _snprintf(szCommand, MAX_SEND_BUF-1, "\r\n+CCWA:\"%s\",0,1\r\n", pszNumber);
            }
            szCommand[MAX_SEND_BUF-1]='\0';
            if (cbCommand > 0) {
                SendATCommand(szCommand, cbCommand);
            }

            SendATCommand("\r\n+CIEV:3,1\r\n", 13);
        }
    }
    else {
        m_AGProps.usCallType = AG_CALL_TYPE_IN;
        m_AGProps.fMuteRings = FALSE;        
        
        DWORD dwErr = OpenControlChannel(FALSE);
        if ((ERROR_SUCCESS != dwErr) && (ERROR_ALREADY_INITIALIZED != dwErr)) {
            DEBUGMSG(ZONE_ERROR, (L"BTAGSVC: Error opening AG Connection: %d.\n", dwErr));
        }
        else {
            if (! m_hUIThread) {
                m_hUIThread = CreateThread(NULL, 0, AGUIThread, this, 0, NULL);
            }

            if (m_hUIThread) {
                if (m_AGProps.fHandsfree) {
                    if (m_AGProps.usHFCapability & AG_CAP_INBAND_RING) {
                        if (m_AGProps.state >= AG_STATE_AUDIO_UP) {
                            DEBUGMSG(ZONE_HANDLER, (L"BTAGSVC: Incoming call is using in-band ring tone.\n"));
                            SendATCommand("\r\n+BSIR:1\r\n", 11); // In-band ring tone on
                        }
                        else if (m_AGProps.state >= AG_STATE_CONNECTED) {
                            SendATCommand("\r\n+BSIR:0\r\n", 11); // In-band ring tone off
                        }
                    }
    
                    if (m_AGProps.fIndicatorUpdates) {
                        SendATCommand("\r\n+CIEV:3,1\r\n", 13); // Call Setup is ongoing
                    }
                    m_AGProps.usCallSetup = 1;

                    if (pszNumber[0] != 0) {
                        WCHAR wszNumber[MAX_PHONE_NUMBER];

                        ASSERT(ARRAY_SIZE(wszNumber) == ARRAY_SIZE(m_wszCLI));
                    
                        if (0 < MultiByteToWideChar(CP_ACP, 0, pszNumber, -1, wszNumber, ARRAY_SIZE(wszNumber))) {
                            if (m_AGProps.fNotifyCLI) {
                                if (FALSE == BthAGGetNameByPhoneNumber(pszNumber, m_wszCLI)) {
                                    wcscpy(m_wszCLI, wszNumber);    
                                }               
                            }
                            else {
                                wcscpy(m_wszCLI, wszNumber);
                            }
                        }
                        else {
                            ASSERT(0);
                        }
                    }
                }
            }
            else {
                DEBUGMSG(ZONE_ERROR, (L"BTAGSVC: Out of resources.\n"));
            }
        }
    }
    
    Unlock();
}


// This method is called by the Network when an outgoing call is placed
void CAGEngine::OnNetworkCallOut(void)
{
    DEBUGMSG(ZONE_HANDLER, (L"BTAGSVC: Calling AGEngine::OnNetworkCallOut\n"));

    Lock();

    m_AGProps.usCallType = AG_CALL_TYPE_OUT;
    m_AGProps.fUseHFAudio = TRUE; // By default outgoing calls will connect HF audio

    m_fAudioConnect = TRUE;
    DWORD dwErr = OpenControlChannel(FALSE);
    if ((ERROR_SUCCESS != dwErr) && (ERROR_ALREADY_INITIALIZED != dwErr)) {
        DEBUGMSG(ZONE_ERROR, (L"BTAGSVC: Error opened AG Connection: %d.\n", dwErr));
    }
    else {
        if (! m_hUIThread) {
            m_hUIThread = CreateThread(NULL, 0, AGUIThread, this, 0, NULL);
        }
        
        if (m_hUIThread) {
            if (m_AGProps.fHandsfree) {
                if (m_AGProps.fIndicatorUpdates) {
                    SendATCommand("\r\n+CIEV:3,3\r\n", 13); // Call Setup is alerting remote party
                }
                m_AGProps.usCallSetup = 3;
            }
        }
        else {
            DEBUGMSG(ZONE_ERROR, (L"BTAGSVC: Out of resources.\n"));
        }                
    }

    Unlock();
}


// This method is called by the Network when a caller id notification is delayed
void CAGEngine::OnNetworkInfo(LPSTR pszNumber)
{
    DEBUGMSG(ZONE_HANDLER, (L"BTAGSVC: Calling AGEngine::OnNetworkInfo number:%hs\n", pszNumber));
    
    Lock();
    
    if (pszNumber[0] != 0) {
        WCHAR wszNumber[MAX_PHONE_NUMBER];

        ASSERT(ARRAY_SIZE(wszNumber) == ARRAY_SIZE(m_wszCLI));
        
        if (0 < MultiByteToWideChar(CP_ACP, 0, pszNumber, -1, wszNumber, ARRAY_SIZE(wszNumber))) {
            if (m_AGProps.fNotifyCLI) {
                if (FALSE == BthAGGetNameByPhoneNumber(pszNumber, m_wszCLI)) {
                    wcscpy(m_wszCLI, wszNumber);    
                }               
            }
            else {
                wcscpy(m_wszCLI, wszNumber);
            }
        }
        else {
            ASSERT(0);
        }
    }
    
    Unlock();
}


// This method is called by the Network when a RING is received
void CAGEngine::OnNetworkRing(void)
{
    DEBUGMSG(ZONE_HANDLER, (L"BTAGSVC: Calling AGEngine::OnNetworkRing\n"));

    Lock();
    
 

⌨️ 快捷键说明

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