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

📄 btaudiogw.cpp

📁 The following file describes how to use the Bluetooth Headset Audio Gateway.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
//

#include <windows.h>
#include "svsutil.hxx"
#include <bt_api.h>
#include "device.h"
#include "btagw_dbg.h"
#include "btagw_reg.h"

#define MAX_VOL			15
#define MIN_VOL			0
#define RING_TIMEOUT	3000

// Global Data
CRITICAL_SECTION		g_csData;
USHORT					g_usSpkVol;
USHORT					g_usMicVol;
DWORD					g_dwAGState;
HANDLE					g_hHeadset;
HANDLE					g_hRingStopEvent;
HANDLE					g_hCloseEvent;
HANDLE					g_hSpkVolEvent;
HANDLE					g_hMicVolEvent;
HANDLE					g_hRingAnswerEvent;
PFN_BTH_ATCMD_CALLBACK	g_pfnATCmdCallback;
BOOL					g_fPcmMode;
BT_ADDR					g_btaddr;
unsigned short			g_hSco;


#ifdef DEBUG

DBGPARAM dpCurSettings = 
{
    TEXT("BTAUDIOGW"), 
 {
  TEXT("Output"),
  TEXT("Events"),
  TEXT("Packets"),  
  TEXT("Undefined"),
  TEXT("Undefined"),
  TEXT("Undefined"),
  TEXT("Undefined"),
  TEXT("Undefined"),
  TEXT("Undefined"),
  TEXT("Undefined"),  
  TEXT("Undefined"),
  TEXT("Undefined"),
  TEXT("Undefined"),  
  TEXT("Undefined"),  
  TEXT("Warning"),
  TEXT("Error") 
 },
 
    0x0000C000
};

#endif


DWORD LoadAGState(void);
DWORD SaveAGState(void);
DWORD InitSco(void);
DWORD DeinitSco(void);
DWORD GetBDAddr(void);



// Dll Entry point
extern "C" BOOL WINAPI DllMain(HANDLE hInstDll, DWORD dwReason, LPVOID lpvReserved)
{
	if (dwReason == DLL_PROCESS_ATTACH) {
		DEBUGREGISTER((HINSTANCE)hInstDll);
		InitializeCriticalSection(&g_csData);
	}
	else if (dwReason == DLL_PROCESS_DETACH) {
		DeleteCriticalSection(&g_csData);
	}
	
	return TRUE;
}



// Initialize the Audio Gateway
extern "C" DWORD BthInitializeAudioGateway(void)
{
	DWORD dwRetVal = ERROR_SUCCESS;

	EnterCriticalSection(&g_csData);

	if (g_dwAGState != AG_UNINITIALIZED) {
		dwRetVal = ERROR_ALREADY_INITIALIZED;
		SetLastError(dwRetVal);
		DEBUGMSG(ZONE_ERROR, (_T("BTAUDIOGW: The audio gateway has already been initialized")));
		goto exit;
	}

	g_hRingStopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
	if (! g_hRingStopEvent) {
		dwRetVal = GetLastError();
		DEBUGMSG(ZONE_ERROR, (_T("BTAUDIOGW: Error creating stop event for ring thread: %d"), dwRetVal));		
		goto exit;
	}
	
	g_hRingAnswerEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
	if (! g_hRingAnswerEvent) {
		dwRetVal = GetLastError();
		DEBUGMSG(ZONE_ERROR, (_T("BTAUDIOGW: Error creating ring answer event: %d"), dwRetVal));
		goto exit;
	}
	
	if (LoadAGState() != ERROR_SUCCESS) {
		DEBUGMSG(ZONE_WARN, (_T("BTAUDIOGW: Warning - could not load state of Audio Gateway on start up")));
	}

	dwRetVal = InitializeDevice();
	if (dwRetVal != ERROR_SUCCESS) {
		DEBUGMSG(ZONE_ERROR, (_T("BTAUDIOGW: Error initializing device: %d"), dwRetVal));
		goto exit;
	}

	if (g_fPcmMode) {
		dwRetVal = GetBDAddr();
		if (dwRetVal != ERROR_SUCCESS) {
			goto exit;
		}
		
		dwRetVal = RegisterBthDevice(g_btaddr, &g_hHeadset);
		if (dwRetVal != ERROR_SUCCESS) {
			goto exit;
		}
	}
	
	g_dwAGState = AG_DISCONNECTED;

exit:
	if (dwRetVal != ERROR_SUCCESS) {
		DeInitializeDevice();
		if (g_hRingAnswerEvent) {
			CloseHandle(g_hRingAnswerEvent);
			g_hRingAnswerEvent = NULL;
		}
		if (g_hRingStopEvent) {
			CloseHandle(g_hRingStopEvent);
			g_hRingStopEvent = NULL;
		}
	}

	LeaveCriticalSection(&g_csData);

	return dwRetVal;
}



// Uninitialize the Audio Gateway
extern "C" DWORD BthUninitializeAudioGateway(void)
{
	DWORD dwRetVal = ERROR_SUCCESS;

	EnterCriticalSection(&g_csData);
	
	if (g_dwAGState == AG_UNINITIALIZED) {
		dwRetVal = ERROR_NOT_READY;
		SetLastError(dwRetVal);
		DEBUGMSG(ZONE_ERROR, (_T("BTAUDIOGW: The audio gateway has not yet been initialized")));
		goto exit;
	}
	
	if (SaveAGState() != ERROR_SUCCESS) {
		DEBUGMSG(ZONE_WARN, (_T("BTAUDIOGW: Warning - could not save state of the Audio Gateway on shutdown")));
	}

	dwRetVal = DeregisterBthDevice(g_hHeadset);
	if (dwRetVal != ERROR_SUCCESS) {
		DEBUGMSG(ZONE_WARN, (_T("BTAUDIOGW: Warning - could not deregister device")));
	}
	g_hHeadset = NULL;
	
	DeInitializeDevice();
	CloseHandle(g_hRingStopEvent);
	CloseHandle(g_hRingAnswerEvent);

	g_dwAGState = AG_UNINITIALIZED;

exit:
	LeaveCriticalSection(&g_csData);
	return TRUE;
}



// Create a connection for the paired device.
extern "C" DWORD BthCreateHeadsetConnection(PFN_BTH_ATCMD_CALLBACK pfnCallback)
{
	DWORD dwRetVal;

	EnterCriticalSection(&g_csData);
	
	if (g_dwAGState == AG_UNINITIALIZED) {
		DEBUGMSG(ZONE_ERROR, (_T("BTAUDIOGW: The audio gateway has not been initialized yet")));
		dwRetVal = ERROR_NOT_READY;
		SetLastError(dwRetVal);
	}
	else if (g_dwAGState == AG_CONNECTED) {
		DEBUGMSG(ZONE_ERROR, (_T("BTAUDIOGW: Already connected to the headset")));
		dwRetVal = ERROR_ALREADY_INITIALIZED;
		SetLastError(dwRetVal);
	}
	else if (g_dwAGState == AG_DISCONNECTED) {
		dwRetVal = StartDevice();
		if (dwRetVal != ERROR_SUCCESS) {
			goto exit;
		}
		
		g_pfnATCmdCallback = pfnCallback;
		g_dwAGState = AG_CONNECTED;
	}

exit:
	LeaveCriticalSection(&g_csData);
	return dwRetVal;
}



// Close the current connection.
extern "C" DWORD BthCloseHeadsetConnection(void)
{
	DWORD dwRetVal;

	EnterCriticalSection(&g_csData);

	if (g_dwAGState == AG_CONNECTED) {
		if (g_fPcmMode) {
			DeinitSco();
		}
		dwRetVal = StopDevice();
		if (dwRetVal == ERROR_SUCCESS) {
			g_dwAGState = AG_DISCONNECTED;
			g_pfnATCmdCallback = NULL;
		}
	}
	else {
		dwRetVal = ERROR_NOT_CONNECTED;
		SetLastError(dwRetVal);
	}

	LeaveCriticalSection(&g_csData);
	
	return dwRetVal;
}



// Ring the headset until it is answered or preempted by StopRingingHeadset
extern "C" DWORD BthRingHeadset(void)
{
	DWORD 	dwRetVal = ERROR_SUCCESS;
	HANDLE	hEvents[2];

	EnterCriticalSection(&g_csData);

	if (g_dwAGState != AG_CONNECTED) {
		DEBUGMSG(ZONE_ERROR, (_T("BTAUDIOGW: Cannot call StartHeadset before establishing an ACL connection")));
		dwRetVal = ERROR_NOT_CONNECTED;
		SetLastError(dwRetVal);
		goto exit;
	}

	ResetEvent(g_hRingAnswerEvent);
	SetRingingState(TRUE);

	hEvents[0] = g_hRingAnswerEvent;
	hEvents[1] = g_hRingStopEvent;

	// Send RING commands
	do {
		dwRetVal = SendATCommand(AT_RING, 8);
		if (dwRetVal != ERROR_SUCCESS) {
			DEBUGMSG(ZONE_ERROR, (_T("BTAUDIOGW: SendATCommand failed with error %d"), dwRetVal));
			break;
		}
		LeaveCriticalSection(&g_csData);
		dwRetVal = WaitForMultipleObjects(2, hEvents, FALSE, RING_TIMEOUT);
		EnterCriticalSection(&g_csData);
		if (g_dwAGState != AG_CONNECTED)
			break;
	} while (dwRetVal == WAIT_TIMEOUT);
	
	SetRingingState(FALSE);

	// Set proper return value;
	if (dwRetVal == WAIT_OBJECT_0) {
		dwRetVal = ERROR_SUCCESS;
		if (g_fPcmMode) {
			dwRetVal = InitSco();
			if (dwRetVal != ERROR_SUCCESS) {
				DEBUGMSG(ZONE_ERROR, (_T("BTAUDIOGW: Unable to initialize SCO connection - ACL connection closed")));
				goto exit;
			}
		}
	}
	else {
		DEBUGMSG(ZONE_OUTPUT, (_T("BTAUDIOGW: Ring was not answered by headset and exiting")));
		dwRetVal = ERROR_OPERATION_ABORTED;
		SetLastError(dwRetVal);
	}

exit:
	LeaveCriticalSection(&g_csData);
	return dwRetVal;
}



// Stops the headset ringing.
extern "C" DWORD BthStopRingingHeadset(void)
{
	DWORD dwRetVal = ERROR_SUCCESS;

	EnterCriticalSection(&g_csData);

	if (g_dwAGState != AG_CONNECTED) {
		DEBUGMSG(ZONE_ERROR, (_T("BTAUDIOGW: Cannot call StopHeadset before establishing an ACL connection")));
		dwRetVal = ERROR_NOT_CONNECTED;
		SetLastError(dwRetVal);
		goto exit;
	}

	SetEvent(g_hRingStopEvent);

exit:
	LeaveCriticalSection(&g_csData);
	return dwRetVal;
}



// Send a custom AT command to the headset
extern "C" DWORD BthSendHeadsetCommand(char* pszCommand, DWORD cdwBuf)
{
	DWORD dwRetVal = ERROR_SUCCESS;

	if (! pszCommand) {
		dwRetVal = ERROR_INVALID_PARAMETER;
		goto exit;

⌨️ 快捷键说明

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