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

📄 handler.cpp

📁 WinCE5.0部分核心源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        m_AGProps.fUseHFAudio = TRUE; // Indicate call is answered from HF

        AddRef();
        Unlock();
        
        DWORD dwErr = BthAGNetworkAnswerCall();
        
        Lock();
        DelRef();
      
        if (ERROR_SUCCESS == dwErr) {
            SendATCommand(AT_OK, sizeof(AT_OK)-1);
        }
        else {
            DEBUGMSG(ZONE_ERROR, (L"BTAGSVC: Error answering call: %d\n", dwErr));
            SendATCommand(AT_ERROR, sizeof(AT_ERROR)-1);
            m_AGProps.fUseHFAudio = FALSE;
        }
    }
    else {
        SendATCommand(AT_ERROR, sizeof(AT_ERROR)-1);
    }

    Unlock();
}


// This method is called by the peer device to hang-up or reject an incoming call
void CAGEngine::OnHangupCall(LPSTR pszParam, int cchParam)
{
    DEBUGMSG(ZONE_HANDLER, (L"BTAGSVC: Calling AGEngine::OnHangupCall\n"));

    Lock();
    
    if (((m_AGProps.state == AG_STATE_RINGING) || 
        (m_AGProps.state == AG_STATE_RINGING_AUDIO_UP)) && 
        (!(m_AGProps.usHFCapability & AG_CAP_REJECT_CALL)))
    {
        // Do not support rejecting incoming calls
        SendATCommand(AT_ERROR, sizeof(AT_ERROR)-1);
    }
    else {
        AddRef();
        Unlock();
        
        DWORD dwErr = BthAGNetworkDropCall(NETWORK_FLAGS_DROP_ACTIVE);
        
        Lock();
        DelRef();

        if (ERROR_SUCCESS == dwErr) {    
            SendATCommand(AT_OK, sizeof(AT_OK)-1);
        }
        else {
            DEBUGMSG(ZONE_ERROR, (L"BTAGSVC: Error dropping call: %d\n", dwErr));
            SendATCommand(AT_ERROR, sizeof(AT_ERROR)-1);            
        }
    }
    
    Unlock();
}


// This method is called by the peer to transmit DTMF codes
void CAGEngine::OnDTMF(LPSTR pszParams, int cchParam)
{
    WCHAR wszDTMF[MAX_SEND_BUF];
    
    DEBUGMSG(ZONE_HANDLER, (L"BTAGSVC: Calling AGEngine::OnDTMF\n"));

    Lock();

    ASSERT(m_AGProps.state >= AG_STATE_CONNECTED);

    if (m_AGProps.fInCall) {
        SendATCommand(AT_OK, sizeof(AT_OK)-1);

        AddRef();
        Unlock();
        
        if (0 < MultiByteToWideChar(CP_ACP, 0, pszParams, -1, wszDTMF, ARRAY_SIZE(wszDTMF))) {
            BthAGNetworkTransmitDTMF(wszDTMF);
        }
        else {
            ASSERT(0);
        }               
        
        Lock();
        DelRef();
    }
    else {
        SendATCommand(AT_ERROR, sizeof(AT_ERROR)-1);
    }

    Unlock();
}


// This method is called by the peer to place a call on hold or enable
// a multi-party call.
void CAGEngine::OnCallHold(LPSTR pszParams, int cchParam)
{
    DEBUGMSG(ZONE_HANDLER, (L"BTAGSVC: Calling AGEngine::OnCallHold\n"));

    Lock();

    ASSERT(m_AGProps.state >= AG_STATE_CONNECTED);

    DWORD dwErr;
    BOOL fSuccess = FALSE;
    BOOL fServiceConnectionUp = FALSE;
    BOOL fCallSetup = FALSE;

    if (m_AGProps.usHFCapability & AG_CAP_3WAY_CALL) {
        if (cchParam < 1) {
            // Bad parameters, do nothing to send error
        }
        else if (pszParams[0] == '?') {
            // Test command for supported call-waiting features            
            SendATCommand("\r\n+CHLD:(0,1,2)\r\n", 17);
            SendATCommand(AT_OK, sizeof(AT_OK)-1);
            fServiceConnectionUp = TRUE;
            fSuccess = TRUE;
        }
        else if (pszParams[0] == '0') {
            // Release all calls
            AddRef();
            Unlock();

            dwErr = BthAGNetworkDropCall(NETWORK_FLAGS_DROP_ALL);

            Lock();
            DelRef();
            
            if (ERROR_SUCCESS == dwErr) {
                fSuccess = TRUE;
                SendATCommand(AT_OK, sizeof(AT_OK)-1);
            }
        }
        else if (pszParams[0] == '1') {
            // Release active calls, transfer held calls
            m_AGProps.fUseHFAudio = TRUE;

            AddRef();
            Unlock();

            dwErr = BthAGNetworkDropCall(NETWORK_FLAGS_DROP_ACTIVE);

            Lock();
            DelRef();
            
            if (ERROR_SUCCESS == dwErr) {
                m_AGProps.fUseHFAudio = TRUE;

                AddRef();
                Unlock();

                dwErr = BthAGNetworkUnholdCall();

                Lock();
                DelRef();
                
                if (ERROR_SUCCESS == dwErr) {
                    fSuccess = TRUE;
                    SendATCommand(AT_OK, sizeof(AT_OK)-1);
                }
            }
        }
        else if (pszParams[0] == '2') {
            // Swap calls
            m_AGProps.fUseHFAudio = TRUE;

            AddRef();
            Unlock();

            dwErr = BthAGNetworkSwapCall();

            Lock();
            DelRef();
            
            if (ERROR_SUCCESS == dwErr) {
                fSuccess = TRUE;
                SendATCommand(AT_OK, sizeof(AT_OK)-1);
            }
        }
        else if ((pszParams[0] == '3') || (pszParams[0] == '4')) {
            // We don't support these parameters, do nothing to send error
        }
    }

    if (! fSuccess) {
        SendATCommand(AT_ERROR, sizeof(AT_ERROR)-1);
        m_AGProps.fUseHFAudio = TRUE;
    }

    if (fServiceConnectionUp) {
        ServiceConnectionUp();
    }

    Unlock();
}


PFN_BthAGOnVoiceTag CAGEngine::GetVoiceTagHandler()
{
    return m_pParser ? m_pParser->GetVoiceTagHandler() : NULL;
}


// This method is called by the peer to start voice recognition
void CAGEngine::OnVoiceRecognition(LPSTR pszParams, int cchParam)
{
    DEBUGMSG(ZONE_HANDLER, (L"BTAGSVC: Calling AGEngine::OnVoiceRecognition\n"));

    Lock();

    ASSERT(m_AGProps.state >= AG_STATE_CONNECTED);

    if (m_AGProps.usHFCapability & AG_CAP_VOICE_RECOG) {
        if (cchParam != 1) {
            SendATCommand(AT_ERROR, sizeof(AT_ERROR)-1);
        }
        else if (pszParams[0] == '0') {
            SendATCommand(AT_OK, sizeof(AT_OK)-1);
            
            AddRef();
            Unlock();
            
            BthAGPhoneExtEvent(AG_PHONE_EVENT_VOICE_RECOG, 0, (void*)GetVoiceTagHandler());

            Lock();
            DelRef();
        }
        else if (pszParams[0] == '1') {
            SendATCommand(AT_OK, sizeof(AT_OK)-1);
            DWORD dwErr = OpenAudioChannel();
            if ((ERROR_SUCCESS != dwErr) && (ERROR_ALREADY_INITIALIZED != dwErr)) {
                DEBUGMSG(ZONE_WARN, (L"BTAGSVC: Call to open audio channel failed.  Can't do voice recognition.\n"));
            }        

            AddRef();
            Unlock();
            
            BthAGPhoneExtEvent(AG_PHONE_EVENT_VOICE_RECOG, 1, (void*)GetVoiceTagHandler());

            Lock();
            DelRef();            
        }    
    }
    else {
        SendATCommand(AT_ERROR, sizeof(AT_ERROR)-1);        
    }
    
    Unlock();
}


// This method is called by the peer to query supported features of the AG
void CAGEngine::OnSupportedFeatures(LPSTR pszParams, int cchParam)
{
    DEBUGMSG(ZONE_HANDLER, (L"BTAGSVC: Calling AGEngine::OnSupportedFeatures\n"));

    Lock();

    ASSERT(m_AGProps.state >= AG_STATE_CONNECTING);

    LPSTR pTmp;    
    m_AGProps.usRemoteFeatures = (USHORT) strtol(pszParams, &pTmp, 10);
    if (pTmp != (pszParams + strlen(pszParams))) {
        DEBUGMSG(ZONE_HANDLER, (L"BTAGSVC: AT+BRSF Command was poorly formatted.\n"));
        SendATCommand(AT_ERROR, sizeof(AT_ERROR)-1);
    }
    else {
        CHAR pszCommand[MAX_SEND_BUF];
        
        m_AGProps.fHandsfree = TRUE;
        
        int cchCommand = _snprintf(pszCommand, MAX_SEND_BUF-1, "\r\n+BRSF:%d\r\n", m_AGProps.usHFCapability);
        pszCommand[MAX_SEND_BUF-1]='\0';
        if (cchCommand > 0) {
            SendATCommand(pszCommand, cchCommand);
            SendATCommand(AT_OK, sizeof(AT_OK)-1);
        }
        else {
            SendATCommand(AT_ERROR, sizeof(AT_ERROR)-1);
        }
    }       

    Unlock();
}


// This method is called by the peer to get a list of supported indicators
void CAGEngine::OnTestIndicators(LPSTR pszParams, int cchParam)
{
    DEBUGMSG(ZONE_HANDLER, (L"BTAGSVC: Calling AGEngine::OnTestIndicators\n"));

    CHAR pszCommand[MAX_SEND_BUF];

    Lock();

    ASSERT(m_AGProps.state >= AG_STATE_CONNECTING);

    m_AGProps.fHandsfree = TRUE;

    int cchCommand = _snprintf(pszCommand, MAX_SEND_BUF-1, "\r\n+CIND: (\"service\",(0,1)),(\"call\",(0,1)),(\"callsetup\",(0-3))\r\n");
    pszCommand[MAX_SEND_BUF-1]='\0';
    if (cchCommand > 0) {
        SendATCommand(pszCommand, cchCommand);
        SendATCommand(AT_OK, sizeof(AT_OK)-1);
    }
    else {
        SendATCommand(AT_ERROR, sizeof(AT_ERROR)-1);
    }

    Unlock();
}


// This method is called by the peer to read the supported indicators
void CAGEngine::OnReadIndicators(LPSTR pszParams, int cchParam)
{
    CHAR pszCommand[MAX_SEND_BUF];
    
    DEBUGMSG(ZONE_HANDLER, (L"BTAGSVC: Calling AGEngine::OnReadIndicators\n"));

    Lock();

    ASSERT(m_AGProps.state >= AG_STATE_CONNECTING);

    m_AGProps.fHandsfree = TRUE;

    BOOL fService = (m_AGProps.fHaveService?1:0);
    BOOL fCall = ((m_AGProps.fInCall)?1:0);

    // Send status of all indicators
    int cchCommand = _snprintf(pszCommand, MAX_SEND_BUF-1, "\r\n+CIND: %d,%d,%d\r\n", fService, fCall, m_AGProps.usCallSetup);
    pszCommand[MAX_SEND_BUF-1]='\0';
    if (cchCommand > 0) {
        SendATCommand(pszCommand, cchCommand);
        SendATCommand(AT_OK, sizeof(AT_OK)-1);
    }
    else {
        SendATCommand(AT_ERROR, sizeof(AT_ERROR)-1);
    }

    Unlock();
}


// This method is called by the peer to register for indicator updates.
void CAGEngine::OnRegisterIndicatorUpdates(LPSTR pszParams, int cchParam)
{
    DEBUGMSG(ZONE_HANDLER, (L"BTAGSVC: Calling AGEngine::OnRegisterIndicatorUpdates\n"));

    //
    // Format of the string we are parsing: "a,b,c,d\n".
    // We care about a and d.
    //

    Lock();

    ASSERT(m_AGProps.state >= AG_STATE_CONNECTING);

    DWORD cParam = 0;
    BOOL fSendOk = FALSE;

    while (*pszParams != '\0') {
        if (*pszParams == ',') {
            cParam++;
        }
        else if (cParam == 0 && (*pszParams != ' ')) {
            // If first param is not 3 we don't care about this command
            if (*pszParams != '3') {
                break;
            }
        }
        else if ((cParam == 3) && (*pszParams != ' ')) {
            // Fourth param is indicator update flag
            if (*pszParams == '1') {            
                DEBUGMSG(ZONE_HANDLER, (L"BTAGSVC: Enabling Indicator Updates.\n"));
                m_AGProps.fIndicatorUpdates = TRUE;
            }
            else {            
                DEBUGMSG(ZONE_HANDLER, (L"BTAGSVC: Disabling Indicator Updates.\n"));
                m_AGProps.fIndicatorUpdates = FALSE;
            }

            m_AGProps.fHandsfree = TRUE;

            fSendOk = TRUE;
            break;
        }

        pszParams++;
    }

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

    if ((m_AGProps.usHFCapability & AG_CAP_3WAY_CALL) && 
        (m_AGProps.usRemoteFeatures & HF_CAP_3WAY_CALL)) {
        // If we mutually support 3-way call, service level connection
        // is not up until after AT+CHLD=?
    }
    else {
        ServiceConnectionUp();
    }
    
    Unlock();

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


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

    Lock();

    ASSERT(m_AGProps.state >= AG_STATE_CONNECTING);

    BOOL fSendOk = FALSE;

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

⌨️ 快捷键说明

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