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

📄 l2capdev.cxx

📁 Windows CE操作系统中适用的蓝牙驱动程序
💻 CXX
📖 第 1 页 / 共 4 页
字号:
}

int L2CAPCloseCID (unsigned short usCID) {
	if (! gpState)
		return ERROR_SERVICE_NOT_ACTIVE;

	gpState->Lock ();
	if (! gpState->fIsRunning) {
		gpState->Unlock ();

		return ERROR_SERVICE_NOT_ACTIVE;
	}

	Link *pLink = FindLink (usCID);
	if (! pLink) {
		gpState->Unlock ();

		return ERROR_NOT_FOUND;
	}

	unsigned short cid = pLink->cid;
	DeleteLink (pLink);
	HANDLE hL2CAP = gpState->hL2CAP;
	L2CA_Disconnect_In pCallback = gpState->l2cap_if.l2ca_Disconnect_In;

	gpState->Unlock ();

	__try {
		pCallback (hL2CAP, NULL, cid);
	} __except (1) {
	}

	return ERROR_SUCCESS;
}

int L2CAPRead
(
unsigned short usCID,
unsigned int cBuffer,
unsigned int *pRequired,
unsigned char *pBuffer
) {
	if (! gpState)
		return ERROR_SERVICE_NOT_ACTIVE;

	gpState->Lock ();
	if (! gpState->fIsRunning) {
		gpState->Unlock ();

		return ERROR_SERVICE_NOT_ACTIVE;
	}

	Link *pLink = FindLink (usCID);
	if (! pLink) {
		gpState->Unlock ();

		return ERROR_NOT_FOUND;
	}

	if (pLink->fStage & LINK_ERROR) {
		gpState->Unlock ();

		return ERROR_CONNECTION_UNAVAIL;
	}

	SCall *pCall = gpState->pCalls;
	while (pCall && ((pCall->pLink != pLink) || (pCall->fWhat != CALL_L2CAP_DATA_READ) || (! pCall->fAutoClean)))
		pCall = pCall->pNext;

	for (int i = 0 ; ; ++i) {
		if (pCall) {
			SVSUTIL_ASSERT (pCall->fComplete);
			int iRes = pCall->iResult;
			if (iRes == ERROR_SUCCESS) {
				SVSUTIL_ASSERT (pCall->pBuffer);

				unsigned int cSize = BufferTotal (pCall->pBuffer);
				*pRequired = cSize;
				if (cSize <= cBuffer) {
					BufferGetChunk (pCall->pBuffer, cSize, pBuffer);
					DeleteCall (pCall);
				}
			}
			gpState->Unlock ();
			return iRes;
		}

		if (i == 1) {
			gpState->Unlock ();
			return ERROR_CANCELLED;
		}

		if (pLink->fStage != UP) {
			gpState->Unlock ();
			return ERROR_CONNECTION_UNAVAIL;
		}

		pCall = AllocCall (CALL_L2CAP_DATA_READ, pLink, GetOwnerProcess ());
		if (! pCall) {
			gpState->Unlock ();
			return ERROR_OUTOFMEMORY;
		}
		
		HANDLE hEvent = pCall->hEvent;
		gpState->Unlock ();
		WaitForSingleObject (hEvent, INFINITE);
		if (! gpState)
			return ERROR_CANCELLED;

		gpState->Lock ();
		if (! gpState->fIsRunning) {
			gpState->Unlock ();
			return ERROR_CANCELLED;
		}

		pCall = VerifyCall (pCall);
	}
}

int L2CAPWrite
(
unsigned short usCID,
unsigned int cBuffer,
unsigned char *pBuffer
) {
	if (! gpState)
		return ERROR_SERVICE_NOT_ACTIVE;

	gpState->Lock ();
	if (! gpState->fIsRunning) {
		gpState->Unlock ();

		return ERROR_SERVICE_NOT_ACTIVE;
	}

	Link *pLink = FindLink (usCID);
	if ((! pLink) || (pLink->fStage != UP)) {
		gpState->Unlock ();

		return ERROR_NOT_FOUND;
	}

	BD_BUFFER *pB = L2CAP_BufferAlloc (cBuffer + gpState->cHeaders + gpState->cTrailers);
	pB->cStart = gpState->cHeaders;
	pB->cEnd = pB->cSize - gpState->cTrailers;
	memcpy (pB->pBuffer + pB->cStart, pBuffer, cBuffer);

	SCall *pCall = AllocCall (CALL_L2CAP_DATA_WRITE, pLink, GetOwnerProcess ());
	if (! pCall) {
		gpState->Unlock ();
		return ERROR_OUTOFMEMORY;
	}

	HANDLE hEvent = pCall->hEvent;
	HANDLE hL2CAP = gpState->hL2CAP;
	L2CA_DataDown_In pCallback = gpState->l2cap_if.l2ca_DataDown_In;

	gpState->Unlock ();

	int iRes = ERROR_INTERNAL_ERROR;
	__try {
		iRes = pCallback (hL2CAP, pCall, usCID, pB);
	} __except (1) {
	}

	if (iRes == ERROR_SUCCESS)
		WaitForSingleObject (hEvent, INFINITE);

	if (! gpState)
		return ERROR_SERVICE_NOT_ACTIVE;

	gpState->Lock ();

	SVSUTIL_ASSERT ((iRes != ERROR_SUCCESS) || pCall->fComplete);
	if (iRes == ERROR_SUCCESS)
		iRes = pCall->iResult;
	else
		L2CAP_BufferFree (pB);

	DeleteCall (pCall);

	gpState->Unlock ();
	return iRes;
}

int L2CAPPing
(
BT_ADDR	*pbt,
unsigned int cBufferIn,
unsigned char *pBufferIn,
unsigned int *pcBufferOut,
unsigned char *pBufferOut
) {
	BD_ADDR ba = *(BD_ADDR *)pbt;
	unsigned int cBuffer = *pcBufferOut;
	*pcBufferOut = 0;

	if (! gpState)
		return ERROR_SERVICE_NOT_ACTIVE;

	gpState->Lock ();
	if (! gpState->fIsRunning) {
		gpState->Unlock ();

		return ERROR_SERVICE_NOT_ACTIVE;
	}

	SCall *pCall = AllocCall (CALL_L2CAP_PING, NULL, GetOwnerProcess ());
	if (! pCall) {
		gpState->Unlock ();
		return ERROR_OUTOFMEMORY;
	}

	HANDLE hEvent = pCall->hEvent;
	HANDLE hL2CAP = gpState->hL2CAP;
	L2CA_Ping_In pCallback = gpState->l2cap_if.l2ca_Ping_In;

	gpState->Unlock ();

	int iRes = ERROR_INTERNAL_ERROR;
	__try {
		iRes = pCallback (hL2CAP, pCall, &ba, pBufferIn, cBufferIn);
	} __except (1) {
	}

	if (iRes == ERROR_SUCCESS)
		WaitForSingleObject (hEvent, INFINITE);

	if (! gpState)
		return ERROR_SERVICE_NOT_ACTIVE;

	gpState->Lock ();

	SVSUTIL_ASSERT ((iRes != ERROR_SUCCESS) || pCall->fComplete);
	if (iRes == ERROR_SUCCESS) {
		iRes = pCall->iResult;
		if ((iRes == ERROR_SUCCESS) && (pCall->pBuffer)) {
			unsigned int cSize = BufferTotal (pCall->pBuffer);
			*pcBufferOut = cSize;
			if (cSize <= cBuffer)
				BufferGetChunk (pCall->pBuffer, cSize, pBufferOut);
		}
	}

	DeleteCall (pCall);

	gpState->Unlock ();
	return iRes;
}

#if defined (UNDER_CE)
//
//	Driver service funcs...
//
extern "C" BOOL WINAPI DllMain( HANDLE hInstDll, DWORD fdwReason, LPVOID lpvReserved) {
	switch(fdwReason) {
		case DLL_PROCESS_ATTACH:
			DisableThreadLibraryCalls ((HMODULE)hInstDll);
			svsutil_Initialize ();
			break;

		case DLL_PROCESS_DETACH:
			svsutil_DeInitialize ();
			break;
	}
	return TRUE;
}

//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//		EXECUTION THREAD: Client-application!
//			These functions are only executed on the caller's thread
// 			i.e. the thread belongs to the client application
//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//	@func PVOID | L2C_Init | Device initialization routine
//  @parm DWORD | dwInfo | Info passed to RegisterDevice
//  @rdesc	Returns a DWORD which will be passed to Open & Deinit or NULL if
//			unable to initialize the device.
//	@remark	Routine exported by a device driver.  "PRF" is the string passed
//			in as lpszType in RegisterDevice
extern "C" DWORD L2C_Init (DWORD Index) {
	DebugInit();

	return (DWORD)(l2capdev_CreateDriverInstance () == ERROR_SUCCESS);
}

//	@func PVOID | L2C_Deinit | Device deinitialization routine
//  @parm DWORD | dwData | value returned from L2C_Init call
//  @rdesc	Returns TRUE for success, FALSE for failure.
//	@remark	Routine exported by a device driver.  "PRF" is the string
//			passed in as lpszType in RegisterDevice
extern "C" BOOL L2C_Deinit(DWORD dwData) {
	l2capdev_CloseDriverInstance ();

	DebugDeInit();

	return TRUE;
}

//	@func PVOID | L2C_Open		| Device open routine
//  @parm DWORD | dwData		| value returned from L2C_Init call
//  @parm DWORD | dwAccess		| requested access (combination of GENERIC_READ
//								  and GENERIC_WRITE)
//  @parm DWORD | dwShareMode	| requested share mode (combination of
//								  FILE_SHARE_READ and FILE_SHARE_WRITE)
//  @rdesc	Returns a DWORD which will be passed to Read, Write, etc or NULL if
//			unable to open device.
//	@remark	Routine exported by a device driver.  "PRF" is the string passed
//			in as lpszType in RegisterDevice
extern "C" DWORD L2C_Open (DWORD dwData, DWORD dwAccess, DWORD dwShareMode) {
	HANDLE *ph = (HANDLE *)g_funcAlloc (sizeof(HANDLE), g_pvAllocData);

	ph[0] = NULL;

	return (DWORD)ph;
}

//	@func BOOL | L2C_Close | Device close routine
//  @parm DWORD | dwOpenData | value returned from L2C_Open call
//  @rdesc	Returns TRUE for success, FALSE for failure
//	@remark	Routine exported by a device driver.  "PRF" is the string passed
//			in as lpszType in RegisterDevice
extern "C" BOOL L2C_Close (DWORD dwData)  {
	HANDLE *ph = (HANDLE *)dwData;

	if (ph && ph[0])
		ProcessExited (ph[0]);

	if (ph)
		g_funcFree (ph, g_pvFreeData);

	return TRUE;
}

//	@func DWORD | L2C_Write | Device write routine
//  @parm DWORD | dwOpenData | value returned from L2C_Open call
//  @parm LPCVOID | pBuf | buffer containing data
//  @parm DWORD | len | maximum length to write [IN BYTES, NOT WORDS!!!]
//  @rdesc	Returns -1 for error, otherwise the number of bytes written.  The
//			length returned is guaranteed to be the length requested unless an
//			error condition occurs.
//	@remark	Routine exported by a device driver.  "PRF" is the string passed
//			in as lpszType in RegisterDevice
//
extern "C" DWORD L2C_Write (DWORD dwData, LPCVOID pInBuf, DWORD dwInLen) {
	return -1;
}

//	@func DWORD | L2C_Read | Device read routine
//  @parm DWORD | dwOpenData | value returned from L2C_Open call
//  @parm LPVOID | pBuf | buffer to receive data
//  @parm DWORD | len | maximum length to read [IN BYTES, not WORDS!!]
//  @rdesc	Returns 0 for end of file, -1 for error, otherwise the number of
//			bytes read.  The length returned is guaranteed to be the length
//			requested unless end of file or an error condition occurs.
//	@remark	Routine exported by a device driver.  "PRF" is the string passed
//			in as lpszType in RegisterDevice
//
extern "C" DWORD L2C_Read (DWORD dwData, LPVOID pBuf, DWORD Len) {
	return -1;
}

//	@func DWORD | L2C_Seek | Device seek routine
//  @parm DWORD | dwOpenData | value returned from L2C_Open call
//  @parm long | pos | position to seek to (relative to type)
//  @parm DWORD | type | FILE_BEGIN, FILE_CURRENT, or FILE_END
//  @rdesc	Returns current position relative to start of file, or -1 on error
//	@remark	Routine exported by a device driver.  "PRF" is the string passed
//		 in as lpszType in RegisterDevice

extern "C" DWORD L2C_Seek (DWORD dwData, long pos, DWORD type) {
	return (DWORD)-1;
}

//	@func void | L2C_PowerUp | Device powerup routine
//	@comm	Called to restore device from suspend mode.  You cannot call any
//			routines aside from those in your dll in this call.
extern "C" void L2C_PowerUp (void) {
	return;
}
//	@func void | L2C_PowerDown | Device powerdown routine
//	@comm	Called to suspend device.  You cannot call any routines aside from
//			those in your dll in this call.
extern "C" void L2C_PowerDown (void) {
	return;
}

//	@func BOOL | L2C_IOControl | Device IO control routine
//  @parm DWORD | dwOpenData | value returned from L2C_Open call
//  @parm DWORD | dwCode | io control code to be performed
//  @parm PBYTE | pBufIn | input data to the device
//  @parm DWORD | dwLenIn | number of bytes being passed in
//  @parm PBYTE | pBufOut | output data from the device
//  @parm DWORD | dwLenOut |maximum number of bytes to receive from device
//  @parm PDWORD | pdwActualOut | actual number of bytes received from device
//  @rdesc	Returns TRUE for success, FALSE for failure
//	@remark	Routine exported by a device driver.  "PRF" is the string passed
//		in as lpszType in RegisterDevice
extern "C" BOOL L2C_IOControl(DWORD dwData, DWORD dwCode, PBYTE pBufIn,
			  DWORD dwLenIn, PBYTE pBufOut, DWORD dwLenOut,
			  PDWORD pdwActualOut)
{
#if ! defined (SDK_BUILD)
	if (dwCode == IOCTL_PSL_NOTIFY) {
		PDEVICE_PSL_NOTIFY pPslPacket = (PDEVICE_PSL_NOTIFY)pBufIn;
		if ((pPslPacket->dwSize == sizeof(DEVICE_PSL_NOTIFY)) && (pPslPacket->dwFlags == DLL_PROCESS_EXITING)){
			SVSUTIL_ASSERT (*(HANDLE *)dwData == pPslPacket->hProc);
			ProcessExited ((HANDLE)pPslPacket->hProc);
		}

		return TRUE;
	}
#endif

	HANDLE *ph = (HANDLE *)dwData;
	SVSUTIL_ASSERT (ph);

	if (! ph[0])
		ph[0] = GetCallerProcess ();

	SVSUTIL_ASSERT (ph[0] == GetCallerProcess());

	int iError = ERROR_SUCCESS;

	L2CAPDEVAPICALL *pbapi = (L2CAPDEVAPICALL *)pBufIn;
	if (dwLenIn != sizeof(L2CAPDEVAPICALL)) {
		SetLastError(ERROR_INVALID_PARAMETER);
		return FALSE;
	}

	switch (dwCode) {
	case L2CAPDEV_IOCTL_L2CAPConnect:
		iError = L2CAPConnect (&pbapi->L2CAPConnect_p.ba,
			pbapi->L2CAPConnect_p.usPSM,
			pbapi->L2CAPConnect_p.usInMTU,
			&pbapi->L2CAPConnect_p.usCID,
			&pbapi->L2CAPConnect_p.usOutMTU);
		break;

	case L2CAPDEV_IOCTL_L2CAPListen:
		iError = L2CAPListen (pbapi->L2CAPListen_p.usPSM, pbapi->L2CAPListen_p.usInMTU);
		break;

	case L2CAPDEV_IOCTL_L2CAPAccept:
		iError = L2CAPAccept (pbapi->L2CAPAccept_p.usPSM,
			&pbapi->L2CAPAccept_p.ba,
			&pbapi->L2CAPAccept_p.usCID,
			&pbapi->L2CAPAccept_p.usOutMTU);
		break;

	case L2CAPDEV_IOCTL_L2CAPWrite:
		iError = L2CAPWrite (pbapi->L2CAPReadWrite_p.usCID,
			pbapi->L2CAPReadWrite_p.cBuffer,
			(unsigned char *)MapCallerPtr (pbapi->L2CAPReadWrite_p.pBuffer, pbapi->L2CAPReadWrite_p.cBuffer));
		break;

	case L2CAPDEV_IOCTL_L2CAPRead:
		iError = L2CAPRead (pbapi->L2CAPReadWrite_p.usCID,
			pbapi->L2CAPReadWrite_p.cBuffer,
			&pbapi->L2CAPReadWrite_p.cRequired,
			(unsigned char *)MapCallerPtr (pbapi->L2CAPReadWrite_p.pBuffer, pbapi->L2CAPReadWrite_p.cBuffer));
		break;

	case L2CAPDEV_IOCTL_L2CAPCloseCID:
		iError = L2CAPCloseCID (pbapi->L2CAPClose_p.us);
		break;

	case L2CAPDEV_IOCTL_L2CAPClosePSM:
		iError = L2CAPClosePSM (pbapi->L2CAPClose_p.us);
		break;

	case L2CAPDEV_IOCTL_L2CAPPing:
		iError = L2CAPPing (&pbapi->L2CAPPing_p.ba, pbapi->L2CAPPing_p.cBufferIn,
				(unsigned char *)MapCallerPtr (pbapi->L2CAPPing_p.pBufferIn, pbapi->L2CAPPing_p.cBufferIn),
				&pbapi->L2CAPPing_p.cBufferOut, 
				(unsigned char *)MapCallerPtr (pbapi->L2CAPPing_p.pBufferOut, pbapi->L2CAPPing_p.cBufferOut));
		break;

	default:
		IFDBG(DebugOut (DEBUG_WARN, L"Unknown control code %d\n", dwCode));
		iError = ERROR_CALL_NOT_IMPLEMENTED;
	}

	if (iError != ERROR_SUCCESS) {
		SetLastError(iError);
		return FALSE;
	}

	return TRUE;
}

#if defined(UNDER_CE) && CE_MAJOR_VER < 0x0003
extern "C" int _isctype(int c, int mask) {
	if ((c < 0) || (c > 0xff))
		return 0;
	return iswctype((wchar_t)c,(wctype_t)mask);
}
#endif //defined(UNDER_CE) && CE_MAJOR_VER < 0x0003

#endif	// UNDER_CE

⌨️ 快捷键说明

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