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

📄 btdriverstreamwrite.cpp

📁 Windows CE操作系统中适用的蓝牙驱动程序
💻 CPP
字号:
//
// 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 "BTDriverStream.h"

//////////////////////////////////////////////////////////////////////
// BTWSSWrite: Write to TxFIFO until there's no more to write.
// Before writing data, we check how much space there are left in TxFIFO
//////////////////////////////////////////////////////////////////////

static DWORD
BTWSSWrite(PWSSBTCLIENT_CONTEXT ptrcc, PVOID buf,DWORD length)
{
	DWORD amountWritten = 0;	
	PWSSBTCLIENT_CONTEXT  extension = (PWSSBTCLIENT_CONTEXT)ptrcc;

	for (int i = 0 ; i < 2 ; ++i) {
		if((extension->currentTxBuffer == FIRST_TX_BUFFER && extension->firstTxBufferFull)
			|| (extension->currentTxBuffer == SECOND_TX_BUFFER && extension->secondTxBufferFull)
			|| (length == 0))
		{
			break;
		}

		DWORD thisWrite=0;
		if(length > TXBUFFERSIZE) thisWrite = TXBUFFERSIZE;
		else thisWrite = length;

		//Write the first buffer
		if(extension->currentTxBuffer == FIRST_TX_BUFFER)
		{
			WRITE_PORT_UCHAR(extension->ioBase + FIRST_TX_BUFFER_LENGTH_OFFSET,(BYTE)thisWrite);
			for(DWORD j=0;j<thisWrite;j++)
			{
				WRITE_PORT_UCHAR(extension->ioBase + FIRST_TX_BUFFER_DATA_OFFSET + j,*((BYTE *)buf + j));
			}

			extension->currentTxBuffer = SECOND_TX_BUFFER;
			extension->firstTxBufferFull = TRUE;

			//Give the buffer to the FPGA
			WRITE_PORT_UCHAR(extension->ioBase + CMD_REGISTER_OFFSET,START_FIRST_TX_BUFFER);
			// DEBUGMSG(ZONE_INTERRUPT, (L"WCESTREAMBT:::::::::::::::::::TX1 %d bytes\n", thisWrite));
		}
		else
		{
			WRITE_PORT_UCHAR(extension->ioBase + SECOND_TX_BUFFER_LENGTH_OFFSET,(BYTE)thisWrite);
			for(DWORD j=0;j<thisWrite;j++)
			{
				WRITE_PORT_UCHAR(extension->ioBase + SECOND_TX_BUFFER_DATA_OFFSET + j,*((BYTE *)buf + j));
			}

			extension->currentTxBuffer = FIRST_TX_BUFFER;
			extension->secondTxBufferFull = TRUE;

			//Give the buffer to the FPGA
			WRITE_PORT_UCHAR(extension->ioBase + CMD_REGISTER_OFFSET,START_SECOND_TX_BUFFER);
			// DEBUGMSG(ZONE_INTERRUPT, (L"WCESTREAMBT:::::::::::::::::::TX2 %d bytes\n", thisWrite));
		}

		buf = (BYTE *)buf + thisWrite;
		length -= thisWrite;
		amountWritten += thisWrite;
	}

	return amountWritten;
}

////////////////////////////////////////////////////////////
// BTWSSWrite: A user application wants to write data to us.
// Check if we can complete the request immediately, queue
// it otherwise
///////////////////////////////////////////////////////////

DWORD WBT_Write(DWORD dwOpenContext, LPCVOID pBuffer, DWORD dwNumBytes)
{
	DEBUGMSG(ZONE_TRACE, (L"WceStreamBT: WBT_Write %d bytes\r\n", dwNumBytes));

	PWSSBTCLIENT_CONTEXT  pcc = (PWSSBTCLIENT_CONTEXT)dwOpenContext;

	DWORD		written = 0;

	EnterCriticalSection (&g_CS);

	int iTimeout = 0;

	if ((pcc == g_pCC) && pcc->fDriverStarted)
	{
		if (pcc->fWriting)
		{
			DEBUGMSG(ZONE_ERROR, (L"WceStreamBT: another thread already writing\r\n"));

			LeaveCriticalSection (&g_CS);
			return 0xffffffff;
		}

		pcc->fWriting = TRUE;

		iTimeout = pcc->CommTimeOuts.WriteTotalTimeoutConstant;
		if (pcc->CommTimeOuts.WriteTotalTimeoutMultiplier != MAXDWORD)
			iTimeout += pcc->CommTimeOuts.WriteTotalTimeoutMultiplier * dwNumBytes;

		ASSERT (pcc->sendBuffer->DataAvailable() == 0);

		DWORD empty = pcc->sendBuffer->GetEmptySpace();
		if (empty < dwNumBytes)
		{
			// Overflow...
			DEBUGMSG(ZONE_ERROR, (L"WceStreamBT: packet too big for TX buffer\r\n"));

			LeaveCriticalSection (&g_CS);
			return 0xffffffff;
		}

		pcc->sendBuffer->WriteData((BYTE *)pBuffer, dwNumBytes);

		DEBUGMSG(ZONE_WRITE, (L"WceStreamBT: Write iteration: initiating content transfer\r\n"));
		BTWSSWriteFromSendBuffer (pcc);
	}

	DWORD dwRes = WAIT_OBJECT_0;

	for ( ; ; )
	{
		if ((pcc != g_pCC) || pcc->fOverflow || (! pcc->fDriverStarted))
		{
			DEBUGMSG(ZONE_ERROR, (L"WceStreamBT: Overflow detected or card removed. Failing the write.\r\n"));
			dwNumBytes = 0xffffffff;
			break;
		}

		if (pcc->sendBuffer->DataAvailable() == 0)
			break;

		if (dwRes == WAIT_TIMEOUT)
		{
			dwNumBytes -= pcc->sendBuffer->DataAvailable();
			pcc->sendBuffer->Flush ();
			break;
		}

		DEBUGMSG(ZONE_WRITE, (L"WceStreamBT: Write blocking for %d ms...\r\n", iTimeout));

		HANDLE h = pcc->hWriteEvent;

		pcc->iRefCnt++;

		LeaveCriticalSection (&g_CS);
		dwRes = WaitForSingleObject (h, iTimeout);
		EnterCriticalSection (&g_CS);

		if (pcc == g_pCC)
			--pcc->iRefCnt;
	}

	if (pcc == g_pCC)
	{
		pcc->fWriting = FALSE;
	}

	LeaveCriticalSection (&g_CS);

	DEBUGMSG(ZONE_WRITE, (L"WceStreamBT: Completing a write with %d bytes\r\n", dwNumBytes));

	return dwNumBytes;
}


//////////////////////////////////////////////////////////////////////
// BTWSSWriteFromSendBuffer: Try writing from our sendBuffer
/////////////////////////////////////////////////////////////////////// 

void
BTWSSWriteFromSendBuffer(PWSSBTCLIENT_CONTEXT ptrcc)
{
	DWORD dataLeft = ptrcc->sendBuffer->DataAvailable();
	if (! dataLeft)
	{
		ptrcc->sendBuffer->Flush();
		SetEvent (ptrcc->hWriteEvent);

		return;
	}

	BYTE *data = ptrcc->sendBuffer->c_ptr(0,dataLeft);

	if(data == NULL)
	{
		// Error...
		ptrcc->fOverflow = TRUE;
		SetEvent (ptrcc->hWriteEvent);
		SetEvent (ptrcc->hReadEvent);
		return;
	}

	DWORD written = BTWSSWrite(ptrcc,data,dataLeft);

	ptrcc->sendBuffer->DropData(written);

	dataLeft = ptrcc->sendBuffer->DataAvailable();

	if(dataLeft == 0)
	{
		ptrcc->sendBuffer->Flush();
		SetEvent (ptrcc->hWriteEvent);
	}
}

⌨️ 快捷键说明

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