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

📄 hci.cxx

📁 三星2440原版bsp
💻 CXX
📖 第 1 页 / 共 5 页
字号:
//
// 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.
//
//------------------------------------------------------------------------------
// 
//      Bluetooth HCI layer
// 
// 
// Module Name:
// 
//      hci.cxx
// 
// Abstract:
// 
//      This file implements Bluetooth HCI layer
// 
// 
//------------------------------------------------------------------------------
#include <windows.h>
#include <svsutil.hxx>

#include <bt_debug.h>
#include <bt_os.h>
#include <bt_buffer.h>
#include <bt_hcip.h>
#include <bt_ddi.h>

static void ConnectTransport (void);
static void ShutdownTransport (void);
int hci_disconnect_transport (int fFinalShutdown);

BD_BUFFER *AllocBuffer (int size);
BD_BUFFER *CopyBuffer (BD_BUFFER *pSource);
BD_BUFFER *FreeBuffer (BD_BUFFER *pBuffer);

#define HCI_BUFFER			(256 + 3)
#define HCI_MEM_SCALE		10
#define HCI_TIMER_SCALE		20000

#define DEFAULT_WORKER_THREAD_PRIORITY	132

struct HCI_CONTEXT : public SVSAllocClass {
	HCI_CONTEXT				*pNext;

	HCI_EVENT_INDICATION	ei;
	HCI_CALLBACKS			c;

	unsigned int			uiControl;

	BD_ADDR					ba;
	unsigned int			class_of_device;
	unsigned char			link_type;

	void			        *pUserContext;

	HCI_CONTEXT (void) {
		memset (this, 0, sizeof(*this));
	}
};

struct BasebandConnection {
	BasebandConnection			*pNext;

	unsigned short				connection_handle;
	BD_ADDR						ba;

	unsigned int				remote_cod;

	unsigned char				link_type;

	unsigned int				fEncrypted     : 1;
	unsigned int				fAuthenticated : 1;
	unsigned int                fMode          : 3;

	HCI_CONTEXT					*pOwner;

	int							cAclDataPacketsPending;
	int							cScoDataPacketsPending;

	BD_BUFFER					*pAclPacket;
	int							cAclBytesComplete;

	DWORD						dwNextScoSyncTime;
	DWORD						dwScoPendingPacketCount;

	~BasebandConnection (void) {
		if (pAclPacket && pAclPacket->pFree)
			pAclPacket->pFree (pAclPacket);
	}

	void *operator new (size_t iSize);
	void operator delete(void *ptr);
};

struct HCIPacket {
	HCIPacket		*pNext;

	HCI_TYPE		ePacketType;

	union {
		struct {
			unsigned short	hConnection;
			int				cTotal;
			int				cSubsPending;

			int				cCompleted;
		} DataPacketAcl;

		struct {
			unsigned short	hConnection;
			int				cTotal;
			int				cSubsPending;
		} DataPacketSco;

		struct {
			unsigned short  hConnection;
			int				cTotal;
			int				cSubsPending;
		} DataPacketU;

		struct {
			unsigned short      opCode;
			HCI_EVENT_CODE		eEvent;
			PacketMarker		m;

			int					iEventRef;
		} CommandPacket;
	} uPacket;

	HCI_CONTEXT		*pOwner;
	void			*pCallContext;

	BD_BUFFER		*pContents;

	HCIPacket (HCI_TYPE a_eType, HCI_CONTEXT *a_pOwner, void *a_pCallContext, unsigned int a_cSize) {
		IFDBG(DebugOut (DEBUG_HCI_PACKETS, L"PACKET TRACK :: Created packet 0x%08x\n", this));
		memset (this, 0, sizeof(*this));
		ePacketType  = a_eType;
		pOwner       = a_pOwner;
		pCallContext = a_pCallContext;

		uPacket.CommandPacket.m.fMarker = BTH_MARKER_NONE;

		if (a_cSize)
			pContents = BufferAlloc (a_cSize);
		else
			pContents = NULL;
	}

	HCIPacket (HCI_TYPE a_eType, HCI_CONTEXT *a_pOwner, void *a_pCallContext, unsigned int a_cSize, BD_ADDR *pba) {
		SVSUTIL_ASSERT (a_eType == COMMAND_PACKET);

		HCIPacket::HCIPacket (a_eType, a_pOwner, a_pCallContext, a_cSize);
		uPacket.CommandPacket.m.fMarker = BTH_MARKER_ADDRESS;
		uPacket.CommandPacket.m.ba = *pba;
	}

	HCIPacket (HCI_TYPE a_eType, HCI_CONTEXT *a_pOwner, void *a_pCallContext, unsigned int a_cSize, unsigned short connection_handle) {
		SVSUTIL_ASSERT (a_eType == COMMAND_PACKET);

		HCIPacket::HCIPacket (a_eType, a_pOwner, a_pCallContext, a_cSize);
		uPacket.CommandPacket.m.fMarker = BTH_MARKER_CONNECTION;
		uPacket.CommandPacket.m.connection_handle  = connection_handle;
	}

	~HCIPacket (void) {
		IFDBG(DebugOut (DEBUG_HCI_PACKETS, L"PACKET TRACK :: Destroyed packet 0x%08x\n", this));
		if (pContents)
			pContents->pFree (pContents);
	}

	void *operator new (size_t iSize);
	void operator delete(void *ptr);
};

enum HCI_LIFE_STAGE {
	JustCreated			= 0,
	Initializing,
	AlmostRunning,
	Connected,
	Disconnected,
	ShuttingDown,
	Error
};

struct InquiryResultList {
	InquiryResultList		*pNext;
	InquiryResultBuffer		irb;

	void *operator new (size_t iSize);
	void operator delete(void *ptr);
};

struct ConnReqData {
	ConnReqData		*pNext;
	BD_ADDR			ba;
	unsigned int	cod;

	void *operator new (size_t iSize);
	void operator delete(void *ptr);
};

int RetireCall (HCIPacket *pPacket, HCI_CONTEXT *pDeviceContext, void *pCallContext, int iError);

struct HCI : public SVSSynch {
	HCI_LIFE_STAGE		eStage;

	FixedMemDescr		*pfmdPackets;
	FixedMemDescr		*pfmdConnections;
	FixedMemDescr		*pfmdInquiryResults;
	FixedMemDescr		*pfmdConnReqData;

	HCIPacket			*pPackets;
	HCIPacket			*pPacketsSent;
	HCIPacket			*pPacketsPending;
	BasebandConnection	*pConnections;
	HCI_CONTEXT			*pContexts;

	HCI_CONTEXT			*pPeriodicInquiryOwner;

	InquiryResultList	*pInquiryResults;

	ConnReqData			*pConnReqData;

	HANDLE				hQueue;
	HANDLE              hWriterThread;
	HANDLE              hReaderThread;

	int                 iCallRefCount;

	int					cCommandPacketsAllowed;
	DWORD				dwCommandPacketTimeout;

	int					cTotalAclDataPacketsPending;	// Total num of ACL packets pending on all connections
	int					cTotalScoDataPacketsPending;	// Total num of SCO packets pending on all connections

	int					fHostFlow  : 1;
	int					fLoopback  : 1;
	int					fUnderTest : 1;
	int					fScoFlow   : 1;

	HCI_Buffer_Size		sHostBuffer;
	HCI_Buffer_Size		sDeviceBuffer;

	unsigned  __int64	llEventMask;

	int					iHardwareErrors;
	int					iReportedErrors;

	HCI_PARAMETERS		transport;

	HANDLE				hInitEvent;

	void ReInit (void) {
		eStage			= JustCreated;
		pfmdPackets		= NULL;
		pfmdConnections = NULL;

		pfmdInquiryResults = NULL;

		pPackets		= NULL;
		pPacketsSent    = NULL;
		pPacketsPending = NULL;
		pConnections    = NULL;
		pContexts       = NULL;

		pPeriodicInquiryOwner = NULL;

		pInquiryResults = NULL;

		pConnReqData 	= NULL;

		hQueue          = NULL;

		hWriterThread   = hReaderThread = NULL;

		iCallRefCount   = 0;

		cCommandPacketsAllowed = 1;
		dwCommandPacketTimeout = 0;

		memset (&sDeviceBuffer, 0, sizeof(sDeviceBuffer));
		memset (&sHostBuffer, 0, sizeof(sHostBuffer));
		memset (&transport, 0, sizeof(transport));

		fHostFlow  = FALSE;
		fLoopback  = FALSE;
		fUnderTest = FALSE;
		fScoFlow   = FALSE;

		llEventMask = 0;

		iHardwareErrors = 0;
		iReportedErrors = 0;

		cTotalAclDataPacketsPending = 0;
		cTotalScoDataPacketsPending = 0;			

		hInitEvent = NULL;
	}

	HCI (void) {
		ReInit();
	}

	void AddRef (void) {
		++iCallRefCount;
	}

	void Release (void) {
		--iCallRefCount;
		SVSUTIL_ASSERT (iCallRefCount >= 0);
	}

	int InCall (void) {
		return iCallRefCount;
	}

	int IsStackRunning (void) {
		return (eStage == AlmostRunning) || (eStage == Connected) || (eStage == Disconnected) || (eStage == Error);
	}

	void Reset (void) {
		memset (&sHostBuffer, 0, sizeof(sHostBuffer));

		fHostFlow   = FALSE;
		fLoopback   = FALSE;
		fUnderTest  = FALSE;
		fScoFlow    = FALSE;
		llEventMask = 0;

		iHardwareErrors = 0;
		iReportedErrors = 0;

		while (pConnections) {
			BasebandConnection *pNext = pConnections->pNext;
			delete pConnections;
			pConnections = pNext;
		}

		while (pInquiryResults) {
			InquiryResultList *pNext = pInquiryResults->pNext;
			delete pInquiryResults;
			pInquiryResults = pNext;
		}

		while (pConnReqData) {
			ConnReqData *pNext = pConnReqData->pNext;
			delete pConnReqData;
			pConnReqData = pNext;
		}

		pPeriodicInquiryOwner = NULL;

		HCIPacket *pX = pPacketsPending;
		pPacketsPending = NULL;

		while (pX && (eStage == IsStackRunning ())) {
			HCIPacket *pNext = pX->pNext;
			RetireCall (pX, pX->pOwner, pX->pCallContext, ERROR_BUS_RESET);
			pX = pNext;
		}

		pX = pPacketsSent;
		pPacketsSent = NULL;

		while (pX && (eStage == IsStackRunning ())) {
			HCIPacket *pNext = pX->pNext;
			RetireCall (pX, pX->pOwner, pX->pCallContext, ERROR_BUS_RESET);
			pX = pNext;
		}
	}
};

static HCI *gpHCI = NULL;

struct InternalCommand {
	HANDLE			hEvent;
	int				fCompleted;
	unsigned char	status;
};

static void IncrHWErr (void) {
	IFDBG(DebugOut (DEBUG_WARN, L"[HCI] IncrHWErr : to %d\n", gpHCI->iHardwareErrors + 1));

	if ((++gpHCI->iHardwareErrors) > HCI_MAX_ERR) {
		IFDBG(DebugOut (DEBUG_ERROR, L"[HCI] Shutting closed because of hardware errors (%d total)\n",
			gpHCI->iHardwareErrors));

		ShutdownTransport ();
	}
}

static int InitTrackReset (void *pCallContext, unsigned char status) {
	IFDBG(DebugOut (DEBUG_HCI_INIT, L"InitTrackReset:: status %02x\n", status));

	InternalCommand *pArgs = (InternalCommand *)pCallContext;
	pArgs->status     = status;
	pArgs->fCompleted = TRUE;
	SetEvent (pArgs->hEvent);

	return TRUE;
}

static int InitTrackReadBufferSize (void *pCallContext, unsigned char status,
						 unsigned short hci_acl_data_packet_length,
						 unsigned char hci_sco_data_packet_length,
						 unsigned short hci_total_num_acl_data_packet,
						 unsigned short hci_total_num_sco_data_packets) {
	IFDBG(DebugOut (DEBUG_HCI_INIT, L"InitTrackBufferRead:: status %02x acl len: %d packets %d sco len %d packets %d\n",
				status, hci_acl_data_packet_length, hci_total_num_acl_data_packet, hci_sco_data_packet_length,
				hci_total_num_sco_data_packets));

	if (status == 0) {
		SVSUTIL_ASSERT (gpHCI->sDeviceBuffer.ACL_Data_Packet_Length == hci_acl_data_packet_length);
		SVSUTIL_ASSERT (gpHCI->sDeviceBuffer.SCO_Data_Packet_Length == hci_sco_data_packet_length);
		SVSUTIL_ASSERT (gpHCI->sDeviceBuffer.Total_Num_ACL_Data_Packets == hci_total_num_acl_data_packet);
		SVSUTIL_ASSERT (gpHCI->sDeviceBuffer.Total_Num_SCO_Data_Packets == hci_total_num_sco_data_packets);
	}

	InternalCommand *pArgs = (InternalCommand *)pCallContext;
	pArgs->status     = status;
	pArgs->fCompleted = TRUE;
	SetEvent (pArgs->hEvent);

	return TRUE;
}

static int InitTrackReadLSP (void *pCallContext, unsigned char status, unsigned char features_mask[8]) {
	IFDBG(DebugOut (DEBUG_HCI_INIT, L"InitTrackReadLSP:: status %02x\n", status));

⌨️ 快捷键说明

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