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

📄 handler.cpp

📁 WinCE5.0部分核心源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    // TODO: See if we have a built-in audio driver and do switching.

    waveOutMessage(0, WODM_BT_SCO_AUDIO_CONTROL, 0, TRUE);

    m_AGProps.state = AG_STATE_AUDIO_UP;

    AddRef();
    Unlock();

    BthAGPhoneExtEvent(AG_PHONE_EVENT_BT_AUDIO, 1, NULL);

    Lock();
    DelRef();
    
exit:
    return dwRetVal;
}


// This private method closes the audio connection to the peer
DWORD CAGEngine::CloseAudioChannel(void)
{
    DWORD dwRetVal = ERROR_SUCCESS;

    DEBUGMSG(ZONE_HANDLER, (L"BTAGSVC: ++CloseAudioChannel\n"));

    ASSERT(IsLocked());
    
    if (m_AGProps.state >= AG_STATE_AUDIO_UP) {
        DEBUGMSG(ZONE_HANDLER, (L"BTAGSVC: CloseAudioChannel - audio is up, closing connection\n"));

        waveOutMessage(0, WODM_BT_SCO_AUDIO_CONTROL, 0, FALSE);

        // TODO: See if we have a built-in audio driver and do switching.

        if (m_AGProps.fPCMMode) {
            DEBUGMSG(ZONE_HANDLER, (L"BTAGSVC: CloseAudioChannel - Need to close SCO connection in PCM mode\n"));
            
            dwRetVal = BthCloseConnection (m_hSco);
            if (dwRetVal != ERROR_SUCCESS) {
                DEBUGMSG(ZONE_WARN, (_T("BTAGSVC: Error closing SCO connection: %d\n"), dwRetVal));
            }

            m_hSco = 0; 
        }
        
        AddRef();
        Unlock();
        
        BthAGPhoneExtEvent(AG_PHONE_EVENT_BT_AUDIO, 0, NULL);

        Lock();
        DelRef();           

        m_AGProps.state = AG_STATE_CONNECTED;

        // If we have not already scheduled sniff thread and sniff mode is enabled and we
        // are connected to a HF device and are persisting HF connections, schedule the
        // sniff thread.
        if ((! m_SniffCookie) && m_AGProps.ulSniffDelay && m_AGProps.fHandsfree && !m_AGProps.fPowerSave) {
            m_SniffCookie = m_pTP->ScheduleEvent(EnterSniffModeThread, (LPVOID)this, m_AGProps.ulSniffDelay);        
        }
    }

    DEBUGMSG(ZONE_HANDLER, (L"BTAGSVC: --CloseAudioChannel\n"));
    
    return dwRetVal;
}


// This method sets the speaker volume for the peer device
void CAGEngine::SetSpeakerVolume(unsigned short usVolume)
{
    CHAR szBuf[MAX_SEND_BUF];
    
    DEBUGMSG(ZONE_HANDLER, (L"BTAGSVC: Setting the speaker volume to %d\n", usVolume));

    ASSERT(usVolume <= 15);

    Lock();

    m_AGProps.usSpeakerVolume = usVolume;
    if (m_AGProps.state >= AG_STATE_CONNECTING) {
        int cbBuf = _snprintf(szBuf, MAX_SEND_BUF-1, AT_VGS, usVolume);
        szBuf[MAX_SEND_BUF-1]='\0';
        if (cbBuf > 0) {
            SendATCommand(szBuf, cbBuf);    
        }
    }
    
    Unlock();
}


// This method sets the mic volume for the peer device
void CAGEngine::SetMicVolume(unsigned short usVolume)
{
    CHAR szBuf[MAX_SEND_BUF];

    DEBUGMSG(ZONE_HANDLER, (L"BTAGSVC: Setting the microphone volume to %d\n", usVolume));

    ASSERT(usVolume <= 15);

    Lock();

    m_AGProps.usMicVolume = usVolume;
    int cbBuf = _snprintf(szBuf, MAX_SEND_BUF-1, AT_VGM, usVolume);
    szBuf[MAX_SEND_BUF-1]='\0';
    if (cbBuf > 0) {
        if (m_AGProps.state >= AG_STATE_CONNECTING) {
            SendATCommand(szBuf, cbBuf);
        }
    }

    Unlock();
}


// This method is called when the headset button is pressed
void CAGEngine::OnHeadsetButton(LPSTR pszParams, int cchParam)
{
    DWORD dwErr = ERROR_SUCCESS;
    
    DEBUGMSG(ZONE_HANDLER, (L"BTAGSVC: Calling AGEngine::OnHeadsetButton\n"));

    Lock();

    ASSERT(m_AGProps.state >= AG_STATE_CONNECTED);

    SendATCommand(AT_OK, sizeof(AT_OK) - 1);

    if ((AG_STATE_RINGING == m_AGProps.state) || (AG_STATE_RINGING_AUDIO_UP == m_AGProps.state)) {
        DEBUGMSG(ZONE_HANDLER, (L"BTAGSVC: Calling AGEngine::OnHeadsetButton - In ringing state, answer call.\n"));

        m_AGProps.fUseHFAudio = TRUE;
        
        AddRef();
        Unlock();
        
        dwErr = BthAGNetworkAnswerCall();
        
        Lock();
        DelRef();

        m_fExpectHeadsetButton = FALSE;

        if (ERROR_SUCCESS != dwErr) {
            DEBUGMSG(ZONE_ERROR, (L"BTAGSVC: Error answering call: %d\n", dwErr));
            m_AGProps.fUseHFAudio = FALSE;
        }
    }
    else if (! m_fExpectHeadsetButton) {
        DEBUGMSG(ZONE_HANDLER, (L"BTAGSVC: Calling AGEngine::OnHeadsetButton - Not expecting headset button, drop/swap call.\n"));

        AddRef();
        Unlock();

        DWORD dwState = 0;
        BthAGNetworkGetCallState(&dwState);

        if ((dwState & NETWORK_FLAGS_STATE_HOLD)    ||   // If bitmask indicates we have calls on hold, do a swap
            ((dwState & NETWORK_FLAGS_STATE_ACTIVE) && 
            (dwState & NETWORK_FLAGS_STATE_OFFERING))    // If we have active call and offering call, do a swap
            ) {
            m_AGProps.fUseHFAudio = TRUE;
            dwErr = BthAGNetworkSwapCall();
        }
        else {                
            BthAGNetworkDropCall(NETWORK_FLAGS_DROP_ACTIVE);
        }
        
        Lock();
        DelRef();

        if (ERROR_SUCCESS != dwErr) {
            DEBUGMSG(ZONE_ERROR, (L"BTAGSVC: Error swapping call: %d\n", dwErr));
            m_AGProps.fUseHFAudio = FALSE;
        }
    }
    else {
        // After headset-initiated connection, the HeadsetButton command
        // is expected once.
        DEBUGMSG(ZONE_HANDLER, (L"BTAGSVC: Calling AGEngine::OnHeadsetButton - Expecting headset button after connect, do nothing.\n"));
        m_fExpectHeadsetButton = FALSE;
    }

    Unlock();
}


// This method is called when the speaker volume on the device changes
void CAGEngine::OnSpeakerVol(LPSTR pszParams, int cchParam)
{
    DEBUGMSG(ZONE_HANDLER, (L"BTAGSVC: Calling AGEngine::OnSpkVol\n"));

    Lock();

    ASSERT(m_AGProps.state >= AG_STATE_CONNECTING);

    LPSTR pTmp;    
    unsigned short usVolume = (USHORT) strtol(pszParams, &pTmp, 10);
    if (pTmp != (pszParams + strlen(pszParams))) {
        DEBUGMSG(ZONE_HANDLER, (L"BTAGSVC: Speaker volume AT Command was poorly formatted.\n"));
        SendATCommand(AT_ERROR, sizeof(AT_ERROR)-1);
    }
    else if (usVolume > 15) {
        DEBUGMSG(ZONE_HANDLER, (L"BTAGSVC: Received speaker volume indication of %d - returning ERROR (out of range).\n", usVolume));
        SendATCommand(AT_ERROR, sizeof(AT_ERROR)-1);
    }
    else {
        m_AGProps.usSpeakerVolume = usVolume;
        SendATCommand(AT_OK, sizeof(AT_OK)-1);     
        
        AddRef();
        Unlock();        
        
        BthAGPhoneExtEvent(AG_PHONE_EVENT_SPEAKER_VOLUME, (DWORD)usVolume, NULL);        
        
        Lock();
        DelRef();
    }

    Unlock();
}


// This method is called when the mic volume on the device changes
void CAGEngine::OnMicVol(LPSTR pszParams, int cchParam)
{
    DEBUGMSG(ZONE_HANDLER, (L"BTAGSVC: Calling AGEngine::OnMicVol\n"));

    Lock();

    ASSERT(m_AGProps.state >= AG_STATE_CONNECTING);

    LPSTR pTmp;    
    unsigned short usVolume = (USHORT) strtol(pszParams, &pTmp, 10);
    if (pTmp != (pszParams + strlen(pszParams))) {
        DEBUGMSG(ZONE_HANDLER, (L"BTAGSVC: Mic volume AT Command was poorly formatted.\n"));
        SendATCommand(AT_ERROR, sizeof(AT_ERROR)-1);
    }
    else if (usVolume > 15) {
        DEBUGMSG(ZONE_HANDLER, (L"BTAGSVC: Received microphone volume indication of %d - returning ERROR (out of range).\n", usVolume));
        SendATCommand(AT_ERROR, sizeof(AT_ERROR)-1);
    }
    else {
        m_AGProps.usMicVolume = usVolume;
        SendATCommand(AT_OK, sizeof(AT_OK)-1);
        
        AddRef();
        Unlock();
        
        BthAGPhoneExtEvent(AG_PHONE_EVENT_MIC_VOLUME, (DWORD)usVolume, NULL); 
        
        Lock();
        DelRef();        
    }

    Unlock();
}


// This method is called when the peer device dials a number
void CAGEngine::OnDial(LPSTR pszParams, int cchParam)
{
    WCHAR wszNumber[MAX_PHONE_NUMBER];
    DWORD dwErr;

    DEBUGMSG(ZONE_HANDLER, (L"BTAGSVC: Calling AGEngine::OnDial\n"));

    Lock();

    ASSERT(m_AGProps.state >= AG_STATE_CONNECTED);
    
    SendATCommand(AT_OK, sizeof(AT_OK)-1);

    if (pszParams[cchParam-1] == ';') {
        pszParams[cchParam-1] = '\0';
    }

    if (m_AGProps.fIndicatorUpdates) {
        SendATCommand("\r\n+CIEV:3,2\r\n", 13); // Call Setup is ongoing
    }
    m_AGProps.usCallSetup = 2;

    m_AGProps.fUseHFAudio = TRUE; // Indicate call is initiated from HF

    AddRef();
    Unlock();
    
    if (0 < MultiByteToWideChar(CP_ACP, 0, pszParams, -1, wszNumber, ARRAY_SIZE(wszNumber))) {
        dwErr = BthAGNetworkDialNumber(wszNumber);
    }
    else {
        ASSERT(0);
        dwErr = GetLastError();
    }
    
    Lock();
    DelRef();

    if (ERROR_SUCCESS != dwErr) {
        DEBUGMSG(ZONE_ERROR, (L"BTAGSVC: Error dialing number: %d\n", dwErr));

        if (m_AGProps.fIndicatorUpdates) {
            SendATCommand("\r\n+CIEV:3,0\r\n", 13); // Call Setup is done
        }
        m_AGProps.usCallSetup = 0;
        m_AGProps.fUseHFAudio = FALSE;
    }

    Unlock();
}


// This method is called when the peer device wants to dial the last dialed number
void CAGEngine::OnDialLast(LPSTR pszParams, int cchParam)
{
    DEBUGMSG(ZONE_HANDLER, (L"BTAGSVC: Calling AGEngine::OnDialLast\n"));
    WCHAR wszNumber[MAX_PHONE_NUMBER];

    Lock();

    ASSERT(m_AGProps.state >= AG_STATE_CONNECTED);

    SendATCommand(AT_OK, sizeof(AT_OK)-1);

    AddRef();
    Unlock();
    
    BOOL fDialed = BthAGGetLastDialed(wszNumber);
    
    Lock();
    DelRef();

    if (fDialed) {        
        if (m_AGProps.fIndicatorUpdates) {
            SendATCommand("\r\n+CIEV:3,2\r\n", 13); // Call Setup is ongoing
        }
        m_AGProps.usCallSetup = 2;

        m_AGProps.fUseHFAudio = TRUE; // Indicate call is initiated from HF

        AddRef();
        Unlock();        
        
        DWORD dwErr = BthAGNetworkDialNumber(wszNumber);
        
        Lock();
        DelRef();

        if (ERROR_SUCCESS != dwErr) {
            DEBUGMSG(ZONE_ERROR, (L"BTAGSVC: Error dialing number: %d\n", dwErr));
            if (m_AGProps.fIndicatorUpdates) {
                SendATCommand("\r\n+CIEV:3,0\r\n", 13); // Call Setup is done
            }
            m_AGProps.usCallSetup = 0;
            m_AGProps.fUseHFAudio = FALSE;
        }
    }

    Unlock();
}


// This method is called when the peer device wants to dial a number in memory
void CAGEngine::OnDialMemory(LPSTR pszParams, int cchParam)
{
    DEBUGMSG(ZONE_HANDLER, (L"BTAGSVC: Calling AGEngine::OnDialMemory\n"));
        
    if (pszParams[cchParam-1] == ';') {
        pszParams[cchParam-1] = '\0';
    }

    Lock();

    ASSERT(m_AGProps.state >= AG_STATE_CONNECTED);

    LPSTR pTmp; 
    unsigned short usIndex = (USHORT) strtol(pszParams, &pTmp, 10);
    if (pTmp != (pszParams + strlen(pszParams))) {
        DEBUGMSG(ZONE_HANDLER, (L"BTAGSVC: ATD> Command was poorly formatted.\n"));
        SendATCommand(AT_ERROR, sizeof(AT_ERROR)-1);
    }
    else {
        WCHAR wszNumber[MAX_PHONE_NUMBER];
            
        SendATCommand(AT_OK, sizeof(AT_OK)-1);

        AddRef();
        Unlock();

        BOOL fDialed = BthAGGetSpeedDial(usIndex, wszNumber);

        Lock();
        DelRef();
       
        if (fDialed) {
            if (m_AGProps.fIndicatorUpdates) {
                SendATCommand("\r\n+CIEV:3,2\r\n", 13); // Call Setup is ongoing
            }
            m_AGProps.usCallSetup = 2;

            m_AGProps.fUseHFAudio = TRUE; // Indicate call is initiated from HF

            AddRef();
            Unlock();
            
            DWORD dwErr = BthAGNetworkDialNumber(wszNumber);            
            
            Lock();
            DelRef();

            if (ERROR_SUCCESS != dwErr) {                
                DEBUGMSG(ZONE_ERROR, (L"BTAGSVC: Error dialing number: %d\n", dwErr));
                if (m_AGProps.fIndicatorUpdates) {
                    SendATCommand("\r\n+CIEV:3,0\r\n", 13); // Call Setup is done
                }
                m_AGProps.usCallSetup = 0;
                m_AGProps.fUseHFAudio = FALSE;
            }
        }
    }

    Unlock();
}


// This method is called when the peer device to answer an incoming call
void CAGEngine::OnAnswerCall(LPSTR pszParams, int cchParam)
{
    DEBUGMSG(ZONE_HANDLER, (L"BTAGSVC: Calling AGEngine::OnAnswerCall\n"));

    Lock();

    if (m_AGProps.state >= AG_STATE_RINGING) {
        m_AGProps.fMuteRings = TRUE;

⌨️ 快捷键说明

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