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

📄 l2cap.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 L2CAP Layer
// 
// 
// Module Name:
// 
//      l2cap.cxx
// 
// Abstract:
// 
//      This file implements Bluetooth L2CAP Layer
// 
// 
//------------------------------------------------------------------------------
#include <windows.h>
#include <svsutil.hxx>

#if ! defined (UNDER_CE)
#include <stddef.h>
#endif

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

#include <service.h>
#include <winsock2.h>

#include <bt_api.h>


#define L2CAP_TO		5000
#define L2CAP_LINK_TO	1000
#define L2CAP_SCALE		10

#define L2CAP_FIRST_CID	0x0040
#define L2CAP_FIRST_PSM	0x1001
#define L2CAP_LAST_PSM	0x1001

#define L2CAP_RTX		60
#define L2CAP_ERTX		300
#define L2CAP_PHYSIDLE	10
#define L2CAP_CONNIDLE	10
#define L2CAP_CONFIGTO	120

#define L2CAP_RECONNECT	3
#define L2CAP_MAXBAD	3

#define L2CAP_COMMAND_COMMAND_REJECT		0x01
#define L2CAP_COMMAND_CONNECTION_REQUEST	0x02
#define L2CAP_COMMAND_CONNECTION_RESPONSE	0x03
#define L2CAP_COMMAND_CONFIG_REQUEST		0x04
#define L2CAP_COMMAND_CONFIG_RESPONSE		0x05
#define L2CAP_COMMAND_DISCONNECT_REQUEST	0x06
#define L2CAP_COMMAND_DISCONNECT_RESPONSE	0x07
#define L2CAP_COMMAND_ECHO_REQUEST			0x08
#define L2CAP_COMMAND_ECHO_RESPONSE			0x09
#define L2CAP_COMMAND_INFO_REQUEST			0x0a
#define L2CAP_COMMAND_INFO_RESPONSE			0x0b

#define L2CAP_V_MAJ	1
#define L2CAP_V_MIN	1

enum CONNECTION_STAGE {
	STARTING_PHYS,			// Waiting physical link
	STARTING,				// Waiting response
	STARTING_REQUEST,
	CONFIG,
	CONFIG_LOCAL_DONE,
	CONFIG_REMOTE_DONE,
	UP,
	DISCONNECTED
};

enum CALL_OP {
	CALL_HCI_READSCAN,
	CALL_HCI_WRITESCAN,
	CALL_PHYS_CONNECT,
	CALL_PHYS_ACCEPT,
	CALL_PHYS_DISCONNECT,
	CALL_PHYS_DROP_IDLE,
	CALL_PHYS_PING,
	CALL_LOG_CONNECT_REQ,
	CALL_LOG_CONNECT_RESP,
	CALL_LOG_CONFIG_REQ,
	CALL_LOG_CONFIG_RESP,
	CALL_LOG_DISCONNECT_REQ,
	CALL_USERDATA,
};

enum CALL_CONTEXT_TYPE {
	CALL_CTX_UNINITIALIZED	= 0,
	CALL_CTX_EVENT,
	CALL_CTX_CALLBACK,
	CALL_CTX_CALLOWNER,
	CALL_CTX_INTERNAL
};

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

class PhysLink;
class LogLink;
class CallContext;
class L2CAP_CONTEXT;
class L2CAP;

class PSMContext {
public:
	PSMContext		*pNext;
	unsigned short	usPSM;

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

class L2CAP_CONTEXT : public SVSAllocClass, public SVSRefObj {
public:
	L2CAP_CONTEXT	*pNext;

	L2CAP_EVENT_INDICATION	ei;
	L2CAP_CALLBACKS			c;

	void			        *pUserContext;
	PSMContext				*pReservedPorts;

	int						fDefaultServer;

	unsigned short			usPacketType;

	L2CAP_CONTEXT (void) {
		pNext = NULL;
		memset (&ei, 0, sizeof(ei));
		memset (&c, 0, sizeof(c));

		pUserContext   = NULL;
		pReservedPorts = NULL;

		fDefaultServer = FALSE;
		usPacketType   = 0;
	}
};

class PhysLink {
public:
	PhysLink			*pNext;
	DWORD				dwTimeOutCookie;

	BD_ADDR				b;
	unsigned short		h;

	unsigned char		mode;

	CONNECTION_STAGE	eStage;

	LogLink				*pLogLinks;

	unsigned int		iConnectionAttempts;
	unsigned int		iTransmissionProblems;
	unsigned int		iPingsSent;

	unsigned short		usPacketType;

	int					iLockCnt;

	PhysLink (void) {
		memset (this, 0, sizeof(PhysLink));
		eStage = STARTING;
		h      = BT_HCI_INVALID_HANDLE;
	}

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

class LogLink {
public:
	LogLink				*pNext;
	DWORD				dwTimeOutCookie;

	PhysLink			*pPhysLink;

	unsigned short		psm;

	unsigned short		cid;
	unsigned short		cid_remote;

	CONNECTION_STAGE	eStage;

	L2CAP_CONTEXT		*pOwner;

	LogLink (PhysLink *pPhys, L2CAP_CONTEXT *a_pOwner) {
		pNext = pPhys->pLogLinks;
		pPhys->pLogLinks = this;

		dwTimeOutCookie = 0;

		pPhysLink = pPhys;

		psm = 0;

		cid = INVALID_CID;
		cid_remote = INVALID_CID;

		eStage = pPhys->eStage == UP ? STARTING : STARTING_PHYS;

		pOwner = a_pOwner;

	}

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

typedef int (*ContextCallback) (CallContext *pContext, int iErr);

class CallContext {
public:
	CallContext			*pNext;
	DWORD				dwTimeOutCookie;

	CALL_OP				eWhat;

	union {
		void			*pLink;
		LogLink			*pLogLink;
		PhysLink		*pPhysLink;
	} u;

	unsigned int		id : 8;

	unsigned int		fForeignId : 1;
	unsigned int		fComplete : 1;
	unsigned int		fKeepOnAbort : 1;
	unsigned int		fRespPending : 1;

	unsigned int		iResult;

	L2CAP_CONTEXT		*pOwner;
	void				*pContext;

	CALL_CONTEXT_TYPE	eType;

	union {
		HANDLE			hEvent;
		ContextCallback	pCallback;
	};

	int					cData;
	void				*pData;

	union {
		unsigned char	ucresult[8];
		unsigned short	usresult[4];
		unsigned int	uiresult[2];
	} r;

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

class L2CAP : public SVSAllocClass, public SVSSynch, public SVSRefObj {
public:
	PhysLink			*pPhysLinks;
	L2CAP_CONTEXT		*pContexts;
	CallContext			*pCalls;

	L2CAP_STAGE			eStage;

	FixedMemDescr		*pfmdPhysLinks;
	FixedMemDescr		*pfmdLogLinks;
	FixedMemDescr		*pfmdCallContexts;
	FixedMemDescr		*pfmdPSM;

	HCI_INTERFACE		hci_if;
	HANDLE				hHCI;

	int					cHCIHeader;
	int					cHCITrailer;

	int					iEchoes;

	unsigned short		usCurrentPSM;
	unsigned short		usCurrentCID;
	unsigned char		ucCurrentID;

	//	Configurable parameters
	unsigned char		bRole;
	unsigned short		usLinkPolicy;
	unsigned short		usPacketType;

	unsigned int		RTX;
	unsigned int		ERTX;

	DWORD				dwPhysIdle;
	DWORD				dwConnectIdle;
	DWORD				dwConfigTO;

	unsigned int		fPicoCapable : 1;
	unsigned int		fScanModeControl : 1;

	void ReInit (void) {
		pPhysLinks		 = NULL;
		pContexts		 = NULL;
		pCalls           = NULL;

		eStage			 = JustCreated;

		pfmdPhysLinks    = NULL;
		pfmdLogLinks     = NULL;
		pfmdCallContexts = NULL;
		pfmdPSM          = NULL;

		memset (&hci_if, 0, sizeof(hci_if));

		hHCI             = NULL;

		cHCIHeader       = 0;
		cHCITrailer      = 0;

		iEchoes          = 0;

		usCurrentPSM     = L2CAP_FIRST_PSM;
		usCurrentCID     = L2CAP_FIRST_CID;
		ucCurrentID      = 0;

		bRole            = 0;
		usLinkPolicy     = 0xffff;
		usPacketType     = 0;

		RTX              = 0;
		ERTX             = 0;

		dwPhysIdle       = 0;
		dwConnectIdle    = 0;
		dwConfigTO       = 0;

		fPicoCapable     = FALSE;
		fScanModeControl = TRUE;
	}

	L2CAP (void) {
		ReInit ();
	}

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

struct CONFIG_OPT {
	unsigned char	type;
	unsigned char	length;
	union {
		unsigned short	MTU;
		unsigned short	FlushTimeout;
		unsigned char	QoS[22];
	} u;
};

struct SignallingPacket {
	struct {
		unsigned char		code;
		unsigned char		id;
		unsigned short		length;
	} h;

	union {
		struct {
			unsigned short	reason;
			unsigned char	ucOptionalData[4];
		} COMMAND_REJECT;
		struct {
			unsigned short  psm;
			unsigned short  source_cid;
		} CONNECTION_REQUEST;
		struct {
			unsigned short	dest_cid;
			unsigned short  source_cid;
			unsigned short	result;
			unsigned short	status;
		} CONNECTION_RESPONSE;
		struct {
			unsigned short	dest_cid;
			unsigned short	flags;
			unsigned char	optbuf[sizeof(CONFIG_OPT) * 3];
		} CONFIG_REQUEST;
		struct {
			unsigned short  source_cid;
			unsigned short  flags;
			unsigned short  result;
			unsigned char	optbuf[sizeof(CONFIG_OPT) * 3];
		} CONFIG_RESPONSE;
		struct {
			unsigned short	dest_cid;
			unsigned short	source_cid;
		} DISCONNECT_REQUEST, DISCONNECT_RESPONSE;
		struct {
			unsigned char	ucData[256];
		} ECHO_REQUEST, ECHO_RESPONSE;
		struct {
			unsigned short  info_type;
		} INFO_REQUEST;
		struct {
			unsigned short  info_type;
			unsigned short  result;
			unsigned char   ucData[1];
		} INFO_RESPONSE;
	} u;
};

struct Signal {
	unsigned short		length;
	unsigned short		cid;
	SignallingPacket	packet;
};

static inline int SIGNAL_LENGTH(Signal &s) {
	return (offsetof (Signal, packet) + s.length);
}

static L2CAP *gpL2CAP = NULL;

static CallContext *AllocCallContext (CALL_CONTEXT_TYPE eType, CALL_OP eOp, void *pLink, L2CAP_CONTEXT *pOwner, void *pCallContext);
static void ResetCallContext (CallContext *pContext);
static void DeleteCallContext (CallContext *pContext);

static int CancelCall (CallContext *pCall, int iError);

static void DisconnectLogicalLink (LogLink *pLink, int iErr, int fSendDisconnect);
static int DisconnectPhysicalLink (PhysLink *pPhysLink, int fReconnect, int iErr, CallContext *pCallContext);

#if defined (DEBUG) || defined (_DEBUG)
static void DumpBuff (unsigned int cMask, BD_BUFFER *pBuff) {
	DumpBuff (cMask, pBuff->pBuffer + pBuff->cStart, BufferTotal (pBuff));
}
#else
static void DumpBuff (unsigned int cMask, BD_BUFFER *pB) {}
#endif

static void AbortCall (CallContext *pCall, int iErr);

static PhysLink *FindPhys (unsigned short h) {
	PhysLink *pP = gpL2CAP->pPhysLinks;
	while (pP && (pP->h != h))
		pP = pP->pNext;

⌨️ 快捷键说明

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