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

📄 hcisc.cxx

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

	CloseHandle (hFile);
	CloseHandle (hWriteEvent);
	CloseHandle (hReadEvent);

	hFile = INVALID_HANDLE_VALUE;
	hWriteEvent = hReadEvent = NULL;

#if defined (BT_USE_CELOG)
	if (g_fCeLog) {
		BTH_CELOG_STOP_DATA sd;
		GetLocalTime (&sd.st);

		CELOGDATAFLAGGED(TRUE, CELID_RAW_UCHAR, &sd, sizeof(sd), 0, CELZONE_ALWAYSON, CELOG_FLAG_STOP);

#if defined (SDK_BUILD)
		CELOGSDK_STOP ();
#endif

		g_fCeLog = FALSE;
	}
#endif

	IFDBG(DebugOut (DEBUG_HCI_INIT, L"HCI_CloseConnection - Successful\n"));

	return;
}

//
//	SLIP coding
//

#define SLIP_END		0xc0
#define SLIP_ESC		0xdb
#define SLIP_ESC_END	0xdc
#define SLIP_ESC_ESC	0xdd

static int GetSLIPEncodedLength(const void *pvData, int len) {
	const unsigned char *pData = (unsigned char *)pvData;
	int slip_len = len;

	for (int i = 0; i < len; ++i) {
		if((pData[i] == SLIP_END) || (pData[i] == SLIP_ESC))
			slip_len += 1;
	}

	return slip_len;
}

static void SLIPEncodeIntoBuffer (const void *pvSourceData, int sourceLen, unsigned char *pTargetData) {
	const unsigned char *pSourceData = (unsigned char *)pvSourceData;

	for(int i = 0; i < sourceLen; ++i) {
		unsigned char byte = pSourceData[i];

		switch(byte) {

		case SLIP_END:
			*pTargetData++ = SLIP_ESC;
			*pTargetData++ = SLIP_ESC_END;
			break;

		case SLIP_ESC:
			*pTargetData++ = SLIP_ESC;
			*pTargetData++ = SLIP_ESC_ESC;
			break;

		default:
			*pTargetData++ = pSourceData[i];
			break;

		}
	}
}

/*

This code has been hacked to add a SLIP wrapper around each call
to WriteCommPort. It is assumed that this function is called
only from the HCI_WritePacket function.

We are doing this so the lower lever of the serial driver
can fined the packet boundry.

This driver should be and should be a packet driver not a stream driver. 
Use a monolithic rather than the MDD/PDD model.

*/
BOOL WriteCommPort (unsigned char *pBuffer, unsigned int cSize) {
	DWORD dwFilledSoFar = 0;
	unsigned char *pSlipPacketData = NULL;
	unsigned int slipPacketLength;

	slipPacketLength = GetSLIPEncodedLength ((const void *)pBuffer, cSize);

	pSlipPacketData = (unsigned char *)malloc (slipPacketLength + 2);
	if (pSlipPacketData == NULL)
	{
		IFDBG(DebugOut (DEBUG_ERROR, L"Failed to allocate temporary SLIP packet buffer.\n"));
		return FALSE;
	}

	pSlipPacketData[0] = 0xC0;
	SLIPEncodeIntoBuffer(pBuffer,cSize,&pSlipPacketData[1]);
	pSlipPacketData[slipPacketLength+1] = 0xC0;
	slipPacketLength += 2;

	while ((int)dwFilledSoFar < slipPacketLength) {
		DWORD dwWrit = 0;
#if ! defined (UNDER_CE)
		OVERLAPPED o;
		memset (&o, 0, sizeof(o));
		o.hEvent = hWriteEvent;
		while (! WriteFile (hFile, &(pSlipPacketData[dwFilledSoFar]), slipPacketLength - dwFilledSoFar, &dwWrit, &o)) {
			if ((GetLastError() == ERROR_IO_PENDING) &&
					GetOverlappedResult (hFile, &o, C:\WINCE410\PUBLIC\COMMON\OAK\DRIVERS\BLUETOOTH\TRANSPORTS\SC&dwWrit, TRUE))
				break;

			if (hFile != INVALID_HANDLE_VALUE)
				IFDBG(DebugOut (DEBUG_ERROR, L"Error writing COM port: GetLastError = 0x%08x (%d)\n", GetLastError (), GetLastError ()));

			if (pSlipPacketData) free(pSlipPacketData);

			return FALSE;
		}
#else

		if ((! WriteFile (hFile, &(pSlipPacketData[dwFilledSoFar]), slipPacketLength - dwFilledSoFar, &dwWrit, NULL)) &&
												(dwWrit == 0)) {
#if defined (DEBUG) || defined (_DEBUG) || defined (RETAILLOG)
			if (hFile != INVALID_HANDLE_VALUE)
				IFDBG(DebugOut (DEBUG_ERROR, L"Error writing COM port: GetLastError = 0x%08x (%d)\n", GetLastError (), GetLastError ()));
#endif
			if (pSlipPacketData) free(pSlipPacketData);
			return FALSE;
		}

#endif

#if defined (BT_USE_CELOG)
		if (g_fCeLog && dwWrit) {
			CELOGDATAFLAGGED(TRUE, CELID_RAW_UCHAR, &pSlipPacketData[dwFilledSoFar], (unsigned short)dwWrit, 0, CELZONE_ALWAYSON, CELOG_FLAG_RAW_OUT);
		}
#endif

		dwFilledSoFar += dwWrit;
	}

	if (pSlipPacketData) free(pSlipPacketData);
	return TRUE;
}

BOOL ReadCommPort (unsigned char *pBuffer, DWORD dwLen) {
	IFDBG(DebugOut(DEBUG_HCI_TRANSPORT, L"ReadCommPort attempting to read %d bytes.\n", dwLen));
	DWORD dwFilledSoFar = 0;
	while (dwFilledSoFar < dwLen) {
		OVERLAPPED o;
		memset (&o, 0, sizeof(o));
		o.hEvent = hReadEvent;

		DWORD dwRead = 0;
#if ! defined (UNDER_CE)
		while (! ReadFile (hFile, &pBuffer[dwFilledSoFar], dwLen - dwFilledSoFar, &dwRead, &o)) {
			if ((GetLastError() == ERROR_IO_PENDING) &&
						GetOverlappedResult (hFile, &o, &dwRead, TRUE))
				break;

			if (hFile != INVALID_HANDLE_VALUE)
				IFDBG(DebugOut (DEBUG_ERROR, L"Error reading COM port: GetLastError = 0x%08x (%d)\n", GetLastError (), GetLastError ()));
			return FALSE;
		}
#else
		if ( (! ReadFile (hFile, &pBuffer[dwFilledSoFar], dwLen - dwFilledSoFar, &dwRead, NULL)) &&
			(dwRead == 0)) {
#if defined (DEBUG) || defined (_DEBUG) || defined (RETAILLOG)
			if (hFile != INVALID_HANDLE_VALUE)
				IFDBG(DebugOut (DEBUG_ERROR, L"Error reading COM port: GetLastError = 0x%08x (%d)\n", GetLastError (), GetLastError ()));
#endif
			return FALSE;
		}
#endif
//#if defined (DEBUG) || defined (_DEBUG)
//		IFDBG(DebugOut(DEBUG_HCI_TRANSPORT, L"ReadFile in ReadCommPort read %d bytes. Filled so far=%d\n", dwRead, dwFilledSoFar));
//		DumpBuff (DEBUG_HCI_DUMP, &pBuffer[dwFilledSoFar], dwRead);
//#endif
#if defined (BT_USE_CELOG)
		if (g_fCeLog && dwRead) {
			CELOGDATAFLAGGED(TRUE, CELID_RAW_UCHAR, pBuffer + dwFilledSoFar, (unsigned short)dwRead, 0, CELZONE_ALWAYSON, CELOG_FLAG_RAW_IN);
		}
#endif
		dwFilledSoFar += dwRead;
	}

	return TRUE;
}

int HCI_WritePacket (HCI_TYPE eType, BD_BUFFER *pBuff) {
	IFDBG(DebugOut (DEBUG_HCI_TRANSPORT, L"HCI_WritePacket type 0x%02x len %d\n", eType, BufferTotal (pBuff)));

	IFDBG(DumpBuff (DEBUG_HCI_DUMP, pBuff->pBuffer + pBuff->cStart, BufferTotal (pBuff)));

	if (((int)BufferTotal (pBuff) > PACKET_SIZE_W) || (pBuff->cStart < 4) || (pBuff->cEnd > pBuff->cSize - 1)) {
		IFDBG(DebugOut (DEBUG_ERROR, L"[UART] Packet too big (%d, should be <= %d), or no space for header!\n", BufferTotal (pBuff), PACKET_SIZE_W));
		return FALSE;
	}

	if (hFile == INVALID_HANDLE_VALUE) {
		IFDBG(DebugOut (DEBUG_ERROR, L"HCI_WritePacket - not active\n"));
		return FALSE;
	}

	int iUserSize = BufferTotal (pBuff);

	pBuff->cStart -= 4;
	switch (eType) {
		case COMMAND_PACKET:
			pBuff->pBuffer[pBuff->cStart] = 0x81;
			break;

		case DATA_PACKET_ACL:
			pBuff->pBuffer[pBuff->cStart] = 0x82;
			break;

		case DATA_PACKET_SCO:
			pBuff->pBuffer[pBuff->cStart] = 0x83;
			break;

		default:
			IFDBG(DebugOut (DEBUG_ERROR, L"[UART - NOKIA] WritePacket :: Invalid code!\n"));
			return FALSE;
	}

	pBuff->pBuffer[pBuff->cStart + 1] = 0;
	pBuff->pBuffer[pBuff->cStart + 2] = iUserSize & 0xff;
	pBuff->pBuffer[pBuff->cStart + 3] = (iUserSize >> 8) & 0xff;

	if (BufferTotal (pBuff) & 1)
		pBuff->pBuffer[pBuff->cEnd++] = 0;

	if (! WriteCommPort (pBuff->pBuffer, BufferTotal (pBuff)))
		return FALSE;

	IFDBG(DebugOut (DEBUG_HCI_TRANSPORT, L"HCI_WritePacket : DONE type 0x%02x len %d\n", eType, BufferTotal (pBuff)));
	return TRUE;
}

int HCI_ReadPacket (HCI_TYPE *peType, BD_BUFFER *pBuff) {
	IFDBG(DebugOut (DEBUG_HCI_TRANSPORT, L"HCI_ReadPacket\n"));
	if (hFile == INVALID_HANDLE_VALUE) {
		IFDBG(DebugOut (DEBUG_ERROR, L"HCI_ReadPacket - not active\n"));
		return FALSE;
	}

	pBuff->cEnd = pBuff->cSize;
	pBuff->cStart = 0;

	if (BufferTotal (pBuff) < 257 + 4) {
		IFDBG(DebugOut (DEBUG_ERROR, L"HCI_ReadPacket - failed buffer too small (%d bytes)\n", BufferTotal (pBuff)));
		return FALSE;
	}
	
    for (;;) {
		if (! ReadCommPort (pBuff->pBuffer, 4))
			return FALSE;

		int iRealBytes = pBuff->pBuffer[2] | (pBuff->pBuffer[3] << 8);
		pBuff->cStart = 4;
		pBuff->cEnd = pBuff->cStart + iRealBytes;

		if (iRealBytes & 0x1)
			pBuff->cEnd++;		// Zero fill...

		if (pBuff->cEnd > pBuff->cSize) {
			IFDBG(DebugOut (DEBUG_ERROR, L"HCI_ReadPacket - failed: buffer too small (%d bytes wanted!)\n", BufferTotal (pBuff)));
			return FALSE;
		}

		if (! ReadCommPort (pBuff->pBuffer + pBuff->cStart, BufferTotal (pBuff)))
			return FALSE;

		pBuff->cEnd = pBuff->cStart + iRealBytes;	// Remove trailing 0

		switch (pBuff->pBuffer[0]) {
		case 0x81:			// Command packet
			IFDBG(DebugOut (DEBUG_ERROR, L"HCI_ReadPacket - unexpected packet type (command)\n"));
			IFDBG(DumpBuff (DEBUG_HCI_DUMP, pBuff->pBuffer + pBuff->cStart, iRealBytes));
			return FALSE;

		case 0x82:			// ACL packet
			*peType = DATA_PACKET_ACL;

			IFDBG(DebugOut (DEBUG_HCI_DUMP, L"HCI_ReadPacket: ACL\n"));
			break;

		case 0x83:			// SCO packet
			*peType = DATA_PACKET_SCO;

			IFDBG(DebugOut (DEBUG_HCI_DUMP, L"HCI_ReadPacket: SCO\n"));
			break;

		case 0x84:			// HCI Event
			*peType = EVENT_PACKET;

			IFDBG(DebugOut (DEBUG_HCI_DUMP, L"HCI_ReadPacket: Event\n"));
			break;

		case 0x80:          // TLP_Control
			IFDBG(DebugOut (DEBUG_HCI_DUMP, L"HCI_ReadPacket: TLP_Control (ignoring)\n"));
			IFDBG(DumpBuff (DEBUG_HCI_DUMP, pBuff->pBuffer + pBuff->cStart, iRealBytes));
			continue;
		}

		IFDBG(DumpBuff (DEBUG_HCI_DUMP, pBuff->pBuffer + pBuff->cStart, iRealBytes));
		return TRUE;
	}

	IFDBG(DebugOut (DEBUG_ERROR, L"HCI_ReadPacket - unknown packet type\n"));
	return FALSE;
}

⌨️ 快捷键说明

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