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

📄 sdpbase.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 SDP Layer
// 
// 
// Module Name:
// 
//      sdpbase.cxx
// 
// Abstract:
// 
//      This file implements SDP layer.
// 
// 
//------------------------------------------------------------------------------


#include "common.h"
#include <svsutil.hxx>
#include <bt_debug.h>


#define CALL_SDP_SERVICE_SEARCH             0x0001
#define CALL_SDP_ATTRIBUTE_SEARCH           0x0002
#define CALL_SDP_SERVICE_ATTRIBUTE_SEARCH   0x0004
#define CALL_SDP_ACCEPT                     0x0008
#define CALL_SDP_CONNECT                    0x0010
#define CALL_SDP_DISCONNECT                 0x0020
#define CALL_SDP_SERVER_WORKER              0x0040

#define CALL_SDP_SEARCH                    (CALL_SDP_SERVICE_SEARCH | CALL_SDP_ATTRIBUTE_SEARCH | CALL_SDP_SERVICE_ATTRIBUTE_SEARCH)
#define CALL_SDP_ACCEPT_CONNECT            (CALL_SDP_ACCEPT | CALL_SDP_CONNECT)
#define CALL_SDP_ACCEPT_SEARCH             (CALL_SDP_SEARCH | CALL_SDP_ACCEPT)
#define CALL_SDP_SEARCH_WORKER             (CALL_SDP_SEARCH | CALL_SDP_SERVER_WORKER)

#define	NONE			0x00
#define CONNECTED		0x01
#define CONFIG_REQ_DONE 0x02
#define CONFIG_IND_DONE 0x04
#define UP              0x07
#define LINK_ERROR		0x80

#define DEFAULT_IN_MTU_SIZE   0x1000
#define MAX_MTU_SIZE          0xFFFF

#define SDP_SCALE		                10

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

#if 0
// Currently no registry settings are available for SDP.
#define SDP_DEFAULT_LINK_TIMEOUT_MS     10000

static const WCHAR g_SdpBaseRegKey[] = L"software\\Microsoft\\bluetooth\\l2cap";
static const WCHAR g_SdpLinkIdle[]   = L"SdpLinkIdle";
#endif

struct SDP_CONTEXT : public SVSAllocClass, public SVSRefObj {
	SDP_CONTEXT	           *pNext;
	SDP_CALLBACKS	       c;
	SDP_EVENT_INDICATION   ei;

	void *pUserContext;

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

struct Call;
struct CallQueue { 
	struct CallQueue  *pNext;
	Call              *pCall;
};

struct Link : public SVSAllocClass, public SVSRefObj {
	Link			*pNext;

	BD_ADDR			b;
	unsigned short	psm;
	unsigned short	cid;

	unsigned int	fStage;

	unsigned int	fIncoming : 1;
	unsigned int    fCallCanceled : 1;

	unsigned short	inMTU;
	unsigned short	outMTU;

	CallQueue       *pCallQueue;
};

struct Call : public SVSAllocClass {
	Call			*pNext;
	Link            *pLink;

	unsigned int	fWhat			: 8;

	SDP_CONTEXT     *pOwner;
	void            *pCallContext;
	SdpConnection   *pSdpConnection;
};

static int sdp_ConfigInd(void *pUserContext, unsigned char id, unsigned short cid, unsigned short usOutMTU, unsigned short usInFlushTO, struct btFLOWSPEC *pInFlow, int cOptNum, struct btCONFIGEXTENSION **ppExtendedOptions);
static int sdp_ConnectInd(void *pUserContext, BD_ADDR *pba, unsigned short cid, unsigned char id, unsigned short psm);
static int sdp_DataUpInd(void *pUserContext, unsigned short cid, BD_BUFFER *pBuffer);
static int sdp_DisconnectInd(void *pUserContext, unsigned short cid, int iErr);
static int sdp_lStackEvent(void *pUserContext, int iEvent, void *pEventContext);

static int sdp_lCallAborted(void *pCallContext, int iError);
static int sdp_ConfigReq_Out(void *pCallContext, unsigned short usResult, unsigned short usInMTU, unsigned short usOutFlushTO, struct btFLOWSPEC *pOutFlow, int cOptNum, struct btCONFIGEXTENSION **ppExtendedOptions);
static int sdp_ConfigResponse_Out(void *pCallContext, unsigned short result);
static int sdp_ConnectReq_Out(void *pCallContext, unsigned short cid, unsigned short result, unsigned short status);
static int sdp_ConnectResponse_Out(void *pCallContext, unsigned short result);
static int sdp_DataDown_Out(void *pCallContext, unsigned short result);
static int sdp_Disconnect_Out(void *pCallContext, unsigned short result);

static int sdp_InquiryComplete(void *pUserContext, void *pCallContext, unsigned char status, unsigned char num_responses);
static int sdp_InquiryResult(void *pUserContext, void *pCallContext, BD_ADDR *pba, unsigned char page_scan_repetition_mode_list, unsigned char page_scan_period_mode, unsigned char page_scan_mode, unsigned int class_of_device, unsigned short clock_offset);
static int sdp_RemoteNameDone(void *pUserContext, void *pCallContext, unsigned char status, BD_ADDR *pba, unsigned char utf_name[248]);
static int sdp_hStackEvent(void *pUserContext, int iEvent, void *pEventContext);

static int sdp_hCallAborted(void *pCallContext, int iError);
static int sdp_LocalNameDone(void *pCallContext, unsigned char status);
static int sdp_Inquiry_Out(void *pCallContext, unsigned char status);
static int sdp_BDADDR_Out(void *pCallContext, unsigned char status, BD_ADDR *pba);
static int sdp_RemoteName_Out(void *pCallContext, unsigned char status);
static int sdp_WriteScan_Out(void *pCallContext, unsigned char status);

static int SdpDisconnect(Link *pLink, Call *pCall);
static void DeleteCall (Call *pCall);

static int MapStatusToErrorCode(int status);

class SDP : public SVSSynch, public SVSRefObj {
public:
	Link			*pLinks;
	Call			*pCalls;
	SDP_CONTEXT     *pContexts;
	
	HANDLE			hL2CAP;
	L2CAP_INTERFACE	l2cap_if;

	FixedMemDescr	*pfmdLinks;
	FixedMemDescr	*pfmdCalls;
	FixedMemDescr   *pfmdSdpConnections;
	FixedMemDescr   *pfmdCallQueue;
	FixedMemDescr   *pfmdBuffers;

//	DWORD           dwSdpIdle;

	SDP_STAGE       eStage;
	BD_ADDR			b;

	int             cDataHeaders;
	int             cDataTrailers;

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

		eStage       = JustCreated;

		hL2CAP       = NULL;
		memset(&l2cap_if, 0, sizeof(l2cap_if));

		pfmdLinks          = NULL;
		pfmdCalls          = NULL;
		pfmdSdpConnections = NULL;
		pfmdCallQueue      = NULL;
		pfmdBuffers        = NULL;

		memset (&b, 0, sizeof(b));
		cDataHeaders = cDataTrailers = 0;
	}

	SDP(void) {
		ReInit();
	}

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

SDP           *gpSDP           = NULL;
SdpDatabase   *pSdpDB          = NULL;
unsigned char *gpSdpReadBuffer = NULL;



//******************************************************************
// Link/call/notification helper functions.
//******************************************************************

static SDP_CONTEXT * VerifyContext(SDP_CONTEXT *pContext) {
	SVSUTIL_ASSERT(gpSDP->IsLocked());

	SDP_CONTEXT *pTrav = gpSDP->pContexts;
	while (pTrav &&(pTrav != pContext))
		pTrav = pTrav->pNext;

	return pTrav;
}

static SDP *CreateNewSDP(void) {
	return new SDP;
}

static SdpDatabase *CreateNewSdpDatabase(void) {
	return new SdpDatabase;
}

static Call *VerifyCall(Call *pCall, unsigned char fWhat=0) {
	Call *p = gpSDP->pCalls;
	while (p && (p != pCall))
		p = p->pNext;

	// Make sure call type is appropriate for given context.
	if (p && fWhat && ! (p->fWhat & fWhat))  {
		SVSUTIL_ASSERT(0);
		return NULL;
	}

	return p;
}

static Link *VerifyLink(Link *pLink) {
	Link *p = gpSDP->pLinks;
	while (p && (p != pLink))
		p = p->pNext;

	return p;
}

static Call *AllocCall(int fWhat, Link *pLink, SDP_CONTEXT *pOwner, void *pCallContext) {
	Call *pCall = (Call *)svsutil_GetFixed(gpSDP->pfmdCalls);
	if (!pCall)
		return NULL;

	memset(pCall, 0, sizeof(*pCall));

	pCall->pNext = gpSDP->pCalls;
	gpSDP->pCalls = pCall;

	pCall->pLink         = pLink;
	pCall->fWhat         = fWhat;
	pCall->pOwner        = pOwner;
	pCall->pCallContext  = pCallContext;

	return pCall;
}

static Link* AllocLink(void)  {
	Link *pLink = (Link *)svsutil_GetFixed(gpSDP->pfmdLinks);
	if (!pLink)
		return NULL;

	memset(pLink, 0, sizeof(*pLink));

	pLink->AddRef();
	pLink->psm = PSM_SDP;
	return pLink;
}

static SdpConnection* AllocSdpConnection(Call *pCall)  {
	SdpConnection *pSdpConn = (SdpConnection*) svsutil_GetFixed(gpSDP->pfmdSdpConnections);
	if (!pSdpConn)
		return NULL;

	memset(pSdpConn ,0,sizeof(*pSdpConn));
	pSdpConn->pCallContext = (void *) pCall;
	if (pCall)  {
		pCall->pSdpConnection = pSdpConn;
		pCall->pSdpConnection->outMtu = pCall->pLink->outMTU;
		pCall->pSdpConnection->inMtu  = pCall->pLink->inMTU;
	}
	return pSdpConn;
}

static CallQueue *AddItemToCallQueue(Link *pLink, Call *pCall)  {
	CallQueue *pNew  = (CallQueue *) svsutil_GetFixed(gpSDP->pfmdCallQueue);
	if (!pNew)
		return NULL;

	pNew->pNext = NULL;
	pNew->pCall = pCall;

	if (!pLink->pCallQueue)
		pLink->pCallQueue = pNew;
	else {
		CallQueue *pTrav = pLink->pCallQueue;
		while (pTrav->pNext)
			pTrav = pTrav->pNext;

		pTrav->pNext = pNew;
	}

	return pNew;
}

// need a connection struct for local requests, alloc once when first needed.
static SdpConnection *gpSpdConnectionLocal = NULL;

static SdpConnection* GetLocalSDPConn() {
	if (gpSpdConnectionLocal) {
		memset((void*)gpSpdConnectionLocal,0,sizeof(*gpSpdConnectionLocal));
		return gpSpdConnectionLocal;
	}

	gpSpdConnectionLocal = AllocSdpConnection(NULL);
	return gpSpdConnectionLocal;
}

static void RemoveCallFromSendQueue(Link *pLink, Call *pCall)  {
	IFDBG(DebugOut(DEBUG_SDP_TRACE,L"RemoveCallFromSendQueue (0x%08x)\r\n",pLink));

	SVSUTIL_ASSERT(gpSDP->IsLocked());
	SVSUTIL_ASSERT(VerifyLink(pLink));

	CallQueue *pTrav   = pLink->pCallQueue;
	CallQueue *pFollow = NULL;
	
	while (pTrav && (pTrav->pCall != pCall)) { 
		pFollow = pTrav;
		pTrav =   pTrav->pNext;
	}
	if (!pTrav)
		return;

	if (pFollow)
		pFollow->pNext = pTrav->pNext;
	else  {
		SVSUTIL_ASSERT(pLink->pCallQueue->pCall == pCall);
		pLink->pCallQueue = pTrav->pNext;
	}

	svsutil_FreeFixed(pTrav, gpSDP->pfmdCallQueue);
}

void NotifyConnect(SDP_CONTEXT *pOwner, void *pContext, unsigned long status, unsigned short cid)  {
	SVSUTIL_ASSERT (VerifyContext(pOwner));

	SDP_Connect_Out pCallback = pOwner->c.sdp_Connect_Out;
	IFDBG(DebugOut(DEBUG_SDP_CALLBACK,L"About to enter sdp_Connect_Out, pContext=0x%08x,status=0x%08x, cid=0x%04x\r\n",pContext,status,cid));

	pOwner->AddRef();
	gpSDP->Unlock();
	__try {
		pCallback(pContext,status,cid);
	}
	__except (1) {
		IFDBG(DebugOut(DEBUG_ERROR,L"sdp_Connect_Out excepted, exception code = 0x%08x\r\n",GetExceptionCode()));
	}
	gpSDP->Lock();
	pOwner->DelRef();
	
	IFDBG(DebugOut(DEBUG_SDP_CALLBACK,L"Finished with sdp_Connect_Out\r\n"));
}

void NotifyDisconnect(SDP_CONTEXT *pOwner, void *pContext, unsigned long status) {
	SVSUTIL_ASSERT (VerifyContext(pOwner));

	SDP_Disonnect_Out pCallback = pOwner->c.sdp_Disconnect_Out;

	IFDBG(DebugOut(DEBUG_SDP_CALLBACK,L"About to enter sdp_Disconnect_Out, pContext=0x%08x, status=0x%08x\r\n",pContext,status));

	pOwner->AddRef();
	gpSDP->Unlock();
	__try {
		pCallback(pContext,status);
	}
	__except (1) {
		IFDBG(DebugOut(DEBUG_ERROR,L"sdp_Disconnect_Out excepted, exception code = 0x%08x\r\n",GetExceptionCode()));
	}
	gpSDP->Lock();
	pOwner->DelRef();

	IFDBG(DebugOut(DEBUG_SDP_CALLBACK,L"Finished with sdp_Disconnect_Out\r\n"));
}

void NotifyServiceSearch(SDP_CONTEXT *pOwner, void *pContext, unsigned long status, unsigned short cReturnedHandles, unsigned char *pClientBuf)  {
	SVSUTIL_ASSERT (VerifyContext(pOwner));
	SDP_ServiceSearch_Out pCallback = pOwner->c.sdp_ServiceSearch_Out;
	unsigned long *pHandles = NULL;

	if (status == ERROR_SUCCESS)
		pHandles = (unsigned long *) pClientBuf;

	pOwner->AddRef();
	gpSDP->Unlock();
	IFDBG(DebugOut(DEBUG_SDP_CALLBACK,L"About to enter sdp_ServiceSearch_Out, pContext=0x%08x\r\n",pContext));
	__try {
		pCallback(pContext,status,cReturnedHandles,pHandles);
	}
	__except (1) {
		IFDBG(DebugOut(DEBUG_ERROR,L"sdp_ServiceSearch_Out excepted, exception code = 0x%08x\r\n",GetExceptionCode()));
	}
	gpSDP->Lock();
	pOwner->DelRef();
	IFDBG(DebugOut(DEBUG_SDP_CALLBACK,L"Finished with sdp_ServiceSearch_Out\r\n"));
}

void NotifyAttributeSearch(SDP_CONTEXT *pOwner, void *pContext, unsigned long status, unsigned char *pClientBuf, unsigned long ulClientBuf)  {
	SVSUTIL_ASSERT (VerifyContext(pOwner));
	SDP_AttributeSearch_Out pCallback = pOwner->c.sdp_AttributeSearch_Out;

⌨️ 快捷键说明

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