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

📄 audiogw.cpp

📁 WinCE5.0部分核心源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// This source code is licensed under Microsoft Shared Source License
// Version 1.0 for Windows CE.
// For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.
//

#include "btagpriv.h"
#include "btagnetwork.h"


#ifdef DEBUG

DBGPARAM dpCurSettings = 
{
    TEXT("BTAGSVC"), 
 {
  TEXT("Output"),
  TEXT("Misc"),
  TEXT("Service"),
  TEXT("Parser"),
  TEXT("Handler"),  
  TEXT("Network"),
  TEXT("PhoneUI"),
  TEXT("Undefined"),
  TEXT("Undefined"),
  TEXT("Undefined"),  
  TEXT("Undefined"),
  TEXT("Undefined"),
  TEXT("Undefined"),  
  TEXT("Undefined"),  
  TEXT("Warning"),
  TEXT("Error") 
 },
    0x0000C001
};

#endif


#define MAX_SDP_RECORD_SIZE 0x048


#define SDP_HS_RECORD_SIZE     0x0000003d
BYTE rgbSdpRecordHeadsetHS[] = {
        0x35, 0x3b, 0x09, 0x00, 0x01, 0x35, 0x06, 0x19,
        0x11, 0x12, 0x19, 0x12, 0x03, 0x09, 0x00, 0x04,
        0x35, 0x0c, 0x35, 0x03, 0x19, 0x01, 0x00, 0x35,
        0x05, 0x19, 0x00, 0x03, 0x08, 0x0a, 0x09, 0x00,
        0x09, 0x35, 0x08, 0x35, 0x06, 0x19, 0x11, 0x08,
        0x09, 0x01, 0x00, 0x09, 0x01, 0x00, 0x25, 0x0d,
        0x56, 0x6f, 0x69, 0x63, 0x65, 0x20, 0x47, 0x61,
        0x74, 0x65, 0x77, 0x61, 0x79
};

#define SDP_HS_CHANNEL_OFFSET  29

#define SDP_HF_RECORD_SIZE     0x00000048
BYTE rgbSdpRecordHeadsetHF[] = {
        0x35, 0x46, 0x09, 0x00, 0x01, 0x35, 0x06, 0x19,
        0x11, 0x1f, 0x19, 0x12, 0x03, 0x09, 0x00, 0x04,
        0x35, 0x0c, 0x35, 0x03, 0x19, 0x01, 0x00, 0x35,
        0x05, 0x19, 0x00, 0x03, 0x08, 0x0a, 0x09, 0x00,
        0x09, 0x35, 0x08, 0x35, 0x06, 0x19, 0x11, 0x1e,
        0x09, 0x01, 0x01, 0x09, 0x01, 0x00, 0x25, 0x0d,
        0x56, 0x6f, 0x69, 0x63, 0x65, 0x20, 0x47, 0x61,
        0x74, 0x65, 0x77, 0x61, 0x79, 0x09, 0x03, 0x01,
        0x08, 0x01, 0x09, 0x03, 0x11, 0x09, 0x00, 0x00
};

#define SDP_HF_CHANNEL_OFFSET       29
#define SDP_HF_CAPABILITY_OFFSET    71


CAGService::CAGService()
{
    m_hThread = NULL;
    m_sockServer[0] = INVALID_SOCKET;
    m_sockServer[1] = INVALID_SOCKET;
    m_fShutdown = FALSE;
    m_SDPRecordHS = 0;
    m_SDPRecordHF = 0;
}


// This method initializes the AG
DWORD CAGService::Init(void)
{
    DWORD dwRetVal = ERROR_SUCCESS;
    WSADATA wsd;

    DEBUGMSG(ZONE_OUTPUT, (L"BTAGSVC: Initializing Audio Gateway Service.\n"));

    g_pAGEngine = &m_AGEngine;

    svsutil_Initialize();
    
    dwRetVal = WSAStartup(MAKEWORD(1,0), &wsd);

    return dwRetVal;
}


// This method deinitializes the AG
void CAGService::Deinit(void)
{
    DEBUGMSG(ZONE_OUTPUT, (L"BTAGSVC: Deinitializing Audio Gateway Service.\n"));

    WSACleanup();
    svsutil_DeInitialize();
    
    g_pAGEngine = NULL;
}


// This method starts the AG
DWORD CAGService::Start(void)
{
    DWORD dwRetVal = ERROR_SUCCESS;
    AG_PROPS    AGProps;

    DEBUGMSG(ZONE_OUTPUT, (L"BTAGSVC: Starting Audio Gateway Service.\n"));

    Lock();

    m_fShutdown = FALSE;

    (void) m_ATParser.Init();

    dwRetVal = m_AGEngine.Init(&m_ATParser);
    if (ERROR_SUCCESS != dwRetVal) {
        DEBUGMSG(ZONE_ERROR, (L"BTAGSVC: Error initializing AG engine: %d.\n", dwRetVal));
        goto exit;
    }

    (void) LoadAGState();

    m_hCloseEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
    if (! m_hCloseEvent) {
        dwRetVal = GetLastError();
        DEBUGMSG(ZONE_ERROR, (L"BTAGSVC: Error creating close event: %d.\n", dwRetVal));
        goto exit;
    }

    m_hThread = CreateThread(NULL, 0, ListenThread, this, 0, NULL);
    if (! m_hThread) {
        dwRetVal = GetLastError();
        DEBUGMSG(ZONE_ERROR, (L"BTAGSVC: Error creating ListenThread: %d.\n", dwRetVal));
        goto exit;
    }

    m_AGEngine.GetAGProps(&AGProps);

    m_hScoThread = CreateThread(NULL, 0, SCOListenThread, this, 0, NULL);
    if (! m_hScoThread) {
        dwRetVal = GetLastError();
        DEBUGMSG(ZONE_ERROR, (L"BTAGSVC: Error creating SCOListenThread: %d.\n", dwRetVal));
        goto exit;
    }

    DEBUGMSG(ZONE_OUTPUT, (L"BTAGSVC: Audio Gateway Service started successfully.\n"));

exit:
    Unlock();
    
    if (ERROR_SUCCESS != dwRetVal) {
        Stop();
    }
    
    return dwRetVal;
}


// This method stops the AG
void CAGService::Stop(void)
{
    DEBUGMSG(ZONE_OUTPUT, (L"BTAGSVC: Stopping Audio Gateway Service.\n"));
    
    Lock();

    SaveAGState();
    
    HANDLE h1 = m_hThread;
    HANDLE h2 = m_hScoThread;
    
    m_hThread = NULL;
    m_hScoThread = NULL;
    
    m_fShutdown = TRUE;

    if (INVALID_SOCKET != m_sockServer[0]) {
        closesocket(m_sockServer[0]);
        m_sockServer[0] = INVALID_SOCKET;
    }
    if (INVALID_SOCKET != m_sockServer[1]) {        
        closesocket(m_sockServer[1]);
        m_sockServer[1] = INVALID_SOCKET;
    }

    if (m_hCloseEvent) {
        SetEvent(m_hCloseEvent);
    }

    m_AGEngine.Deinit();
    m_ATParser.Deinit();

    Unlock();

    if (h1) {
        if (h1 != (HANDLE) GetCurrentThreadId()) {
            WaitForSingleObject(h1, INFINITE);
        }

        CloseHandle(h1);
    }

    if (h2) {
        if (h2 != (HANDLE) GetCurrentThreadId()) {
            WaitForSingleObject(h2, INFINITE);
        }

        CloseHandle(h2);
    }

    DEBUGMSG(ZONE_OUTPUT, (L"BTAGSVC: Audio Gateway Service stopped.\n"));
}


// This method opens an audio session on the headset
DWORD CAGService::OpenAudio(void)
{
    DWORD dwRetVal; 

    DEBUGMSG(ZONE_OUTPUT, (L"BTAGSVC: Opening Bluetooth audio connection.\n"));

    Lock();

    dwRetVal = m_AGEngine.OpenAGConnection(TRUE, FALSE);
    if ((ERROR_SUCCESS != dwRetVal) && (ERROR_ALREADY_INITIALIZED != dwRetVal)) {
        DEBUGMSG(ZONE_ERROR, (L"BTAGSVC: Error opening AG Connection: %d.\n", dwRetVal));
        goto exit;
    }

    dwRetVal = ERROR_SUCCESS;

exit:
    Unlock();
    return dwRetVal;
}


// This method closes an audio session on the headset
DWORD CAGService::CloseAudio(void)
{
    DEBUGMSG(ZONE_OUTPUT, (L"BTAGSVC: Closing Bluetooth audio connection.\n"));

    Lock();    
    m_AGEngine.CloseAGConnection(FALSE);
    Unlock();
    
    return ERROR_SUCCESS;
}


// This method opens the control connection
DWORD CAGService::OpenControlConnection(BOOL fFirstOnly)
{
    DWORD dwRetVal; 

    DEBUGMSG(ZONE_OUTPUT, (L"BTAGSVC: Opening Bluetooth control connection.\n"));

    Lock();

    dwRetVal = m_AGEngine.OpenAGConnection(FALSE, fFirstOnly);
    if ((ERROR_SUCCESS != dwRetVal) && (ERROR_ALREADY_INITIALIZED != dwRetVal)) {
        DEBUGMSG(ZONE_ERROR, (L"BTAGSVC: Error opening AG Connection: %d.\n", dwRetVal));
        goto exit;
    }

    dwRetVal = ERROR_SUCCESS;

exit:
    Unlock();
    return dwRetVal;
}


// This method opens the control connection
DWORD CAGService::CloseControlConnection(void)
{
    DEBUGMSG(ZONE_OUTPUT, (L"BTAGSVC: Closing Bluetooth control connection.\n"));

    Lock();    
    m_AGEngine.CloseAGConnection(TRUE);
    Unlock();

    return ERROR_SUCCESS;
}


// This method sets the speaker volume of the peer
DWORD CAGService::SetSpeakerVolume(unsigned short usVolume)
{
    DEBUGMSG(ZONE_OUTPUT, (L"BTAGSVC: Setting Bluetooth audio speaker volume.\n"));
    
    if (usVolume <= 15) {
        Lock();
        m_AGEngine.SetSpeakerVolume(usVolume);
        Unlock();
        return ERROR_SUCCESS;
    }    

    return ERROR_INVALID_PARAMETER;
}


// This method sets the mic volume of the peer
DWORD CAGService::SetMicVolume(unsigned short usVolume)
{
    DEBUGMSG(ZONE_OUTPUT, (L"BTAGSVC: Setting Bluetooth audio microphone volume.\n"));
    
    if (usVolume <= 15) {
        Lock();
        m_AGEngine.SetMicVolume(usVolume);
        Unlock();
        return ERROR_SUCCESS;
    }    

    return ERROR_INVALID_PARAMETER;
}


// This method gets the speaker volume of the peer
DWORD CAGService::GetSpeakerVolume(unsigned short* pusVolume)
{
    AG_PROPS AGProps;

    Lock();
    
    m_AGEngine.GetAGProps(&AGProps);
    *pusVolume = AGProps.usSpeakerVolume;

    Unlock();

    return ERROR_SUCCESS;
}


// This method gets the mic volume of the peer
DWORD CAGService::GetMicVolume(unsigned short* pusVolume)
{
    AG_PROPS AGProps;

    Lock();
    
    m_AGEngine.GetAGProps(&AGProps);
    *pusVolume = AGProps.usMicVolume;

    Unlock();

    return ERROR_SUCCESS;
}

// Get the power-save mode
DWORD CAGService::GetPowerMode(BOOL* pfPowerSave)
{
    AG_PROPS AGProps;

    Lock();
    
    m_AGEngine.GetAGProps(&AGProps);
    *pfPowerSave = AGProps.fPowerSave;

    Unlock();

    return ERROR_SUCCESS;
}

// Get the power-save mode
DWORD CAGService::SetPowerMode(BOOL fPowerSave)
{
    AG_PROPS AGProps;

    Lock();

    m_AGEngine.GetAGProps(&AGProps);

    if (AGProps.fPowerSave != fPowerSave) {
        AGProps.fPowerSave = fPowerSave;
        m_AGEngine.SetAGProps(&AGProps);
        SaveAGState();
    }

    Unlock();

    return ERROR_SUCCESS;
}

// AG server thread
DWORD WINAPI CAGService::ListenThread(LPVOID pv)
{
    CAGService* pInst = (CAGService*)pv;
    pInst->ListenThread_Int();

    return 0;
}


// This method listens for incoming connections to the AG
void CAGService::ListenThread_Int(void)
{
    SOCKADDR_BTH    saServer;
    int             iLen;
    int             on = TRUE;
    AG_PROPS        AGProps;
    BOOL            fStackUp = FALSE;
    BOOL            fHandsfree;

    DEBUGMSG(ZONE_SERVICE, (L"BTAGSVC: ++ListenThread_Int\n"));

    Lock();

    // Make sure BT stack is up
    for (int i = 0 ; i < 100 ; ++i) {
        HANDLE hBthStackInited = OpenEvent (EVENT_ALL_ACCESS, FALSE, BTH_NAMEDEVENT_STACK_INITED);

        if (hBthStackInited) {
            DWORD dwRes = WaitForSingleObject (hBthStackInited, INFINITE);
            CloseHandle (hBthStackInited);
            if (WAIT_OBJECT_0 == dwRes) {
                fStackUp = TRUE;
                break;
            }
        }

        DEBUGMSG(ZONE_WARN, (L"BTAGSVC: BT stack is not ready, waiting...\n"));

        Sleep (1000);
    }

    if (! fStackUp) {
        DEBUGMSG(ZONE_ERROR, (L"BTAGSVC: Bluetooth stack is not up - aborting ListenThread_Int: %d.\n", GetLastError()));
        goto exit;
    }
    
    m_AGEngine.GetAGProps(&AGProps);
    fHandsfree = ! AGProps.fNoHandsfree;

    // Create headset and hands-free sockets
    

⌨️ 快捷键说明

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