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

📄 audiogw.cpp

📁 WinCE5.0部分核心源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    m_sockServer[0] = socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
    if (INVALID_SOCKET == m_sockServer[0]) {
        DEBUGMSG(ZONE_ERROR, (L"BTAGSVC: Error opening socket: %d.\n", GetLastError()));
        goto exit;
    }

    if (fHandsfree) {
        m_sockServer[1] = socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
        if (INVALID_SOCKET == m_sockServer[1]) {
            DEBUGMSG(ZONE_ERROR, (L"BTAGSVC: Error opening socket: %d.\n", GetLastError()));
            goto exit;
        }
    }

    // Bind headset socket and add SDP record

    memset(&saServer, 0, sizeof(saServer));
    saServer.addressFamily = AF_BTH;
   
    if (0 != bind(m_sockServer[0], (SOCKADDR*)&saServer, sizeof(saServer))) {
        DEBUGMSG(ZONE_ERROR, (L"BTAGSVC: Error calling bind: %d.\n", GetLastError()));
        goto exit;
    }

    iLen = sizeof(saServer);
    if (SOCKET_ERROR == getsockname(m_sockServer[0], (SOCKADDR*)&saServer, &iLen)) {
        DEBUGMSG(ZONE_ERROR, (L"BTAGSVC: Error calling getsockname: %d.\n", GetLastError()));
        goto exit;
    }    

    if (ERROR_SUCCESS != AddSDPRecord(rgbSdpRecordHeadsetHS, SDP_HS_RECORD_SIZE, SDP_HS_CHANNEL_OFFSET, saServer.port, &m_SDPRecordHS)) {
        DEBUGMSG(ZONE_ERROR, (L"BTAGSVC: Error adding headset SDP record.\n"));
        goto exit;
    }

    // Bind hands-free socket and add SDP record

    if (fHandsfree) {
        memset(&saServer, 0, sizeof(saServer));
        saServer.addressFamily = AF_BTH;
        
        if (0 != bind(m_sockServer[1], (SOCKADDR*)&saServer, sizeof(saServer))) {
            DEBUGMSG(ZONE_ERROR, (L"BTAGSVC: Error calling bind: %d.\n", GetLastError()));
            goto exit;
        }    

        iLen = sizeof(saServer);
        if (SOCKET_ERROR == getsockname(m_sockServer[1], (SOCKADDR*)&saServer, &iLen)) {
            DEBUGMSG(ZONE_ERROR, (L"BTAGSVC: Error calling getsockname: %d.\n", GetLastError()));
            goto exit;
        }

        rgbSdpRecordHeadsetHF[SDP_HF_CAPABILITY_OFFSET] = (BYTE) AGProps.usHFCapability;

        if (ERROR_SUCCESS != AddSDPRecord(rgbSdpRecordHeadsetHF, SDP_HF_RECORD_SIZE, SDP_HF_CHANNEL_OFFSET, saServer.port, &m_SDPRecordHF)) {
            DEBUGMSG(ZONE_ERROR, (L"BTAGSVC: Error adding hands-free SDP record.\n"));    
            goto exit;
        }
    }

    // Continue setting up sockets

    listen(m_sockServer[0], 2);
    if (fHandsfree) {
        listen(m_sockServer[1], 2);
    }

    m_AGEngine.GetAGProps(&AGProps);

    if (AGProps.fAuth) {
        DEBUGMSG(ZONE_SERVICE, (L"BTAGSVC: Setting SO_BTH_AUTHENTICATE on server socket.\n"));
        setsockopt(m_sockServer[0], SOL_RFCOMM, SO_BTH_AUTHENTICATE, (char *)&on, sizeof(on));
        if (fHandsfree) {
            setsockopt(m_sockServer[1], SOL_RFCOMM, SO_BTH_AUTHENTICATE, (char *)&on, sizeof(on));
        }
    }
    if (AGProps.fEncrypt) {
        DEBUGMSG(ZONE_SERVICE, (L"BTAGSVC: Setting SO_BTH_ENCRYPT on server socket.\n"));
        setsockopt(m_sockServer[0], SOL_RFCOMM, SO_BTH_ENCRYPT, (char *)&on, sizeof(on));
        if (fHandsfree) {
            setsockopt(m_sockServer[1], SOL_RFCOMM, SO_BTH_ENCRYPT, (char *)&on, sizeof(on));
        }
    }

    while (1) {
        SOCKADDR_BTH    saClient;
        SOCKET          sockClient;
        BOOL            fHFSupport = FALSE;

        fd_set sockSet;
        
        FD_ZERO(&sockSet);
        FD_SET(m_sockServer[0], &sockSet);
        if (fHandsfree) {
            FD_SET(m_sockServer[1], &sockSet);
        }

        Unlock();
        int iSockets = select(0,&sockSet,NULL,NULL,NULL);
        Lock();

        if (m_fShutdown || (0 == iSockets) || (SOCKET_ERROR == iSockets)) {
            DEBUGMSG(ZONE_ERROR, (L"BTAGSVC: Error in call to select: %d\n", GetLastError()));
            goto exit;
        }

        SOCKET s = sockSet.fd_array[iSockets - 1];
        if (fHandsfree && (s == m_sockServer[1])) {
            // Peer device supports HFP
            fHFSupport = TRUE;
        }

        iLen = sizeof(saClient);
        sockClient = accept(s, (SOCKADDR*)&saClient, &iLen);
        if (INVALID_SOCKET == sockClient) {
            DEBUGMSG(ZONE_ERROR, (L"BTAGSVC: Error in call to accept, breaking... - error:%d\n", GetLastError()));
            goto exit;
        }

        DEBUGMSG(ZONE_SERVICE, (L"BTAGSVC: A Bluetooth peer device has connected to the Audio Gateway.\n"));

        if (!m_AGEngine.FindBTAddrInList(saClient.btAddr)) {
            DEBUGMSG(ZONE_WARN, (L"BTAGSVC: The peer device was not accepted since the user has never confirmed it as a device to be used.\n"));
            closesocket(sockClient);
            continue;            
        }

        m_AGEngine.GetAGProps(&AGProps);
        if (AGProps.btAddrClient && (AGProps.btAddrClient != saClient.btAddr)) {
            DEBUGMSG(ZONE_WARN, (L"BTAGSVC: The peer device was not accepted since we already have an active connection.\n"));
            closesocket(sockClient);
            continue;            
        }

        (void) m_AGEngine.SetBTAddrList(saClient.btAddr, fHFSupport); // ignore return value in this case

        if (ERROR_SUCCESS != m_AGEngine.NotifyConnect(sockClient, fHFSupport)) {
            DEBUGMSG(ZONE_WARN, (L"BTAGSVC: The AG Engine did not accept the connection to the device.\n"));
            closesocket(sockClient);
            continue;
        }
    }

exit:
    if (m_SDPRecordHF) {
        RemoveSDPRecord(&m_SDPRecordHF);
    }
    if (m_SDPRecordHS) {
        RemoveSDPRecord(&m_SDPRecordHS);
    }

    g_dwState = SERVICE_STATE_OFF;
   
    Unlock();

    if (! m_fShutdown) {
        Stop();
    } 

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


// AG SCO Server Thread
DWORD WINAPI CAGService::SCOListenThread(LPVOID pv)
{
    CAGService* pInst = (CAGService*)pv;
    pInst->SCOListenThread_Int();

    return 0;
}


// This method listens for incoming SCO connections to the AG
void CAGService::SCOListenThread_Int(void)
{
    DWORD dwErr = ERROR_SUCCESS;
    AG_PROPS AGProps;

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

    Lock();

    m_AGEngine.GetAGProps(&AGProps);
    
    if (AGProps.fPCMMode) {
        dwErr = BthAcceptSCOConnections(TRUE);
    }
    
    if (ERROR_SUCCESS == dwErr) {
        HANDLE hBTConnect = OpenEvent(EVENT_ALL_ACCESS, FALSE, L"system/events/bluetooth/ConnectionsChange");
        if (hBTConnect) {
            HANDLE h[2];            
            DWORD dwWait;

            h[0] = hBTConnect;
            h[1] = m_hCloseEvent;
            
            while (1) {            
                Unlock();                
                dwWait = WaitForMultipleObjects(2, h, FALSE, INFINITE);
                Lock();
                
                if (dwWait != WAIT_OBJECT_0) {
                    break;
                }

                DEBUGMSG(ZONE_SERVICE, (L"BTAGSVC: SCOListenThread_Int - Connection Event.\n"));

                m_AGEngine.ConnectionEvent();
            }
        }
        else {
            DEBUGMSG(ZONE_ERROR, (L"BTAGSVC: SCOListenThread_Int: Error opening named event: %d\n", dwErr));
        }

        if (AGProps.fPCMMode) {
            BthAcceptSCOConnections(FALSE);
        }
    }
    else {
        DEBUGMSG(ZONE_ERROR, (L"BTAGSVC: SCOListenThread_Int: Error accepting SCO connections: %d\n", dwErr));
    }

    Unlock();

    DEBUGMSG(ZONE_SERVICE, (L"BTAGSVC: --SCOListenThread_Int\n"));
}


// This method loads AG settings
DWORD CAGService::LoadAGState(void)
{
    DWORD       dwRetVal    = ERROR_SUCCESS;
    DWORD       cdwBytes    = 0;
    DWORD       dwData      = 0;
    HKEY        hk          = NULL;
    AG_PROPS    AGProps;

    m_AGEngine.GetAGProps(&AGProps);
    
    dwRetVal = RegOpenKeyEx(HKEY_LOCAL_MACHINE, RK_AUDIO_GATEWAY, 0, 0, &hk);
    if (dwRetVal != ERROR_SUCCESS) {
        goto exit;
    }

    cdwBytes = sizeof(dwData);
    if (ERROR_SUCCESS == RegQueryValueEx(hk, _T("MapAudioToPcmMode"), 0, NULL, (PBYTE)&dwData, &cdwBytes)) {
        AGProps.fPCMMode = dwData;
    }

    cdwBytes = sizeof(dwData);
    if (ERROR_SUCCESS == RegQueryValueEx(hk, _T("MicVolume"), 0, NULL, (PBYTE)&dwData, &cdwBytes)) {
        AGProps.usMicVolume = (USHORT) dwData;
    }

    cdwBytes = sizeof(dwData);
    if (ERROR_SUCCESS == RegQueryValueEx(hk, _T("SpkVolume"), 0, NULL, (PBYTE)&dwData, &cdwBytes)) {
        AGProps.usSpeakerVolume = (USHORT) dwData;
    }

    cdwBytes = sizeof(dwData);
    if (ERROR_SUCCESS == RegQueryValueEx(hk, _T("Authenticate"), 0, NULL, (PBYTE)&dwData, &cdwBytes)) {
        AGProps.fAuth = dwData;
    }

    cdwBytes = sizeof(dwData);
    if (ERROR_SUCCESS == RegQueryValueEx(hk, _T("Enrypt"), 0, NULL, (PBYTE)&dwData, &cdwBytes)) {
        AGProps.fEncrypt = dwData;
    }

    cdwBytes = sizeof(dwData);
    if (ERROR_SUCCESS == RegQueryValueEx(hk, _T("NoHandsfree"), 0, NULL, (PBYTE)&dwData, &cdwBytes)) {
        AGProps.fNoHandsfree = dwData;
    }

    cdwBytes = sizeof(dwData);
    if (ERROR_SUCCESS == RegQueryValueEx(hk, _T("PowerSave"), 0, NULL, (PBYTE)&dwData, &cdwBytes)) {
        AGProps.fPowerSave = dwData;
    }

    cdwBytes = sizeof(dwData);
    if (ERROR_SUCCESS == RegQueryValueEx(hk, _T("Capability"), 0, NULL, (PBYTE)&dwData, &cdwBytes)) {
        AGProps.usHFCapability = (USHORT) dwData;
    }

    cdwBytes = sizeof(dwData);
    if (ERROR_SUCCESS == RegQueryValueEx(hk, _T("PageTimeout"), 0, NULL, (PBYTE)&dwData, &cdwBytes)) {
        AGProps.usPageTimeout = (USHORT) dwData;
    }

    cdwBytes = sizeof(dwData);
    if (ERROR_SUCCESS == RegQueryValueEx(hk, _T("SniffDelay"), 0, NULL, (PBYTE)&dwData, &cdwBytes)) {
        AGProps.ulSniffDelay = (ULONG) dwData;
    }

    cdwBytes = sizeof(dwData);
    if (ERROR_SUCCESS == RegQueryValueEx(hk, _T("SniffMax"), 0, NULL, (PBYTE)&dwData, &cdwBytes)) {
        AGProps.usSniffMax = (USHORT) dwData;
    }

    cdwBytes = sizeof(dwData);
    if (ERROR_SUCCESS == RegQueryValueEx(hk, _T("SniffMin"), 0, NULL, (PBYTE)&dwData, &cdwBytes)) {
        AGProps.usSniffMin = (USHORT) dwData;
    }

    cdwBytes = sizeof(dwData);
    if (ERROR_SUCCESS == RegQueryValueEx(hk, _T("SniffAttempt"), 0, NULL, (PBYTE)&dwData, &cdwBytes)) {
        AGProps.usSniffAttempt = (USHORT) dwData;
    }

    cdwBytes = sizeof(dwData);
    if (ERROR_SUCCESS == RegQueryValueEx(hk, _T("SniffTimeout"), 0, NULL, (PBYTE)&dwData, &cdwBytes)) {
        AGProps.usSniffTimeout = (USHORT) dwData;
    }

    RegCloseKey(hk);
    
    m_AGEngine.SetAGProps(&AGProps);
    
exit:    
    return dwRetVal;
}


// This method saves AG settings
DWORD CAGService::SaveAGState(void)
{
    DWORD       dwRetVal    = ERROR_SUCCESS;
    DWORD       dwDisp      = 0;
    DWORD       dwData      = 0;
    HKEY        hk          = NULL;
    AG_PROPS    AGProps;

    dwRetVal = RegCreateKeyEx(HKEY_LOCAL_MACHINE, RK_AUDIO_GATEWAY, 0, NULL, 0, NULL, NULL, &hk, &dwDisp);
    if (ERROR_SUCCESS != dwRetVal) {
        goto exit;
    }

    m_AGEngine.GetAGProps(&AGProps);

    dwData = AGProps.usMicVolume;
    dwRetVal = RegSetValueEx(hk, _T("MicVolume"), 0, REG_DWORD, (PBYTE)&dwData, sizeof(dwData));
    if (ERROR_SUCCESS != dwRetVal) {
        goto exit;
    }

    dwData = AGProps.usSpeakerVolume;
    dwRetVal = RegSetValueEx(hk, _T("SpkVolume"), 0, REG_DWORD, (PBYTE)&dwData, sizeof(dwData));
    if (ERROR_SUCCESS != dwRetVal) {
        goto exit;
    }

    dwData = AGProps.fPowerSave;
    dwRetVal = RegSetValueEx(hk, _T("PowerSave"), 0, REG_DWORD, (PBYTE)&dwData, sizeof(dwData));
    if (ERROR_SUCCESS != dwRetVal) {
        goto exit;
    }    

exit:
    if (hk) {
        RegCloseKey(hk);
    }
    
    return dwRetVal;
}


// This method adds an SDP record
DWORD CAGService::AddSDPRecord(PBYTE rbgSdpRecord, DWORD cbSdpRecord, DWORD dwChannelOffset, unsigned long ulPort, unsigned long* pSdpRecord)
{
    DWORD dwRetVal  = ERROR_SUCCESS;
    DWORD dwSizeOut = 0;

    struct {
        BTHNS_SETBLOB   b;
        unsigned char   uca[MAX_SDP_RECORD_SIZE];
    } bigBlob;

    ULONG ulSdpVersion = BTH_SDP_VERSION;
    *pSdpRecord = 0;

    bigBlob.b.pRecordHandle   = pSdpRecord;
    bigBlob.b.pSdpVersion     = &ulSdpVersion;
    bigBlob.b.fSecurity       = 0;
    bigBlob.b.fOptions        = 0;
    bigBlob.b.ulRecordLength  = cbSdpRecord;

    memcpy(bigBlob.b.pRecord, rbgSdpRecord, cbSdpRecord);

    bigBlob.b.pRecord[dwChannelOffset] = (unsigned char)ulPort;

    BLOB blob;
    blob.cbSize    = sizeof(BTHNS_SETBLOB) + cbSdpRecord - 1;
    blob.pBlobData = (PBYTE) &bigBlob;

    WSAQUERYSET Service;
    memset(&Service, 0, sizeof(Service));
    Service.dwSize = sizeof(Service);
    Service.lpBlob = &blob;
    Service.dwNameSpace = NS_BTH;

    dwRetVal = WSASetService(&Service, RNRSERVICE_REGISTER, 0);
    if (ERROR_SUCCESS != dwRetVal) {
        DEBUGMSG(ZONE_ERROR, (L"BTAGSVC: Error adding SDP record.\n"));
        goto exit;
    }

    DEBUGMSG(ZONE_SERVICE, (L"BTAGSVC: Successfully added SDP record.\n"));
    
exit:
    return dwRetVal;
}


// This method removes an SDP record
DWORD CAGService::RemoveSDPRecord(unsigned long* pSdpRecord)
{
    DWORD dwRetVal      = ERROR_SUCCESS;
    ULONG ulSdpVersion  = BTH_SDP_VERSION;

    BTHNS_SETBLOB delBlob;
    memset(&delBlob, 0, sizeof(delBlob));
    delBlob.pRecordHandle   = pSdpRecord;
    delBlob.pSdpVersion     = &ulSdpVersion;

    BLOB blob;
    blob.cbSize    = sizeof(BTHNS_SETBLOB);
    blob.pBlobData = (PBYTE) &delBlob;

    WSAQUERYSET Service;
    memset(&Service, 0, sizeof(Service));
    Service.dwSize = sizeof(Service);
    Service.lpBlob = &blob;
    Service.dwNameSpace = NS_BTH;

    dwRetVal = WSASetService(&Service, RNRSERVICE_DELETE, 0);

    *pSdpRecord = 0;

#ifdef DEBUG
    if (ERROR_SUCCESS == dwRetVal) {
        DEBUGMSG(ZONE_SERVICE, (L"BTAGSVC: Successfully removed SDP record.\n"));
    }
#endif // DEBUG

    return dwRetVal;
}


⌨️ 快捷键说明

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