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

📄 hcibcsp.cpp

📁 Windows CE操作系统中适用的蓝牙驱动程序
💻 CPP
📖 第 1 页 / 共 4 页
字号:
#endif
		CloseHandle (hFile);
	}

	hFile = INVALID_HANDLE_VALUE;
}

//
//	SLIP coding
//
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;

		}
	}
}

static int SLIPReadBytes(void *pvData, int len, BOOL* pfSlipError) {
	unsigned char *pData = (unsigned char *)pvData;
	unsigned char slipBuffer[SLIP_BUFFER_SIZE];
	int unslippedByte = 0;

	*pfSlipError = FALSE;
	
	while (unslippedByte < len) {
		int bytesRead = len - unslippedByte;

		if (bytesRead > SLIP_BUFFER_SIZE)
			bytesRead = SLIP_BUFFER_SIZE;
		
		if (! ReadCommPort(slipBuffer, bytesRead)) {
			IFDBG(DebugOut(DEBUG_ERROR, L"[BCSP] SLIPReadBytes failed.\n"));

			return FALSE;
		}

		int slipBufferPos = 0;

		while (slipBufferPos < bytesRead) {
			unsigned char byte = slipBuffer[slipBufferPos++];
			if(byte == SLIP_ESC) {
				if(slipBufferPos == bytesRead) {
					if (! ReadCommPort (&byte, 1)) {
						IFDBG(DebugOut(DEBUG_ERROR, L"[BCSP] SLIPReadBytes failed.\n"));

						return FALSE;
					}
				} else
					byte = slipBuffer[slipBufferPos++];

				pData[unslippedByte++] = (byte == SLIP_ESC_ESC) ? SLIP_ESC : SLIP_END;
			} else if (byte == SLIP_END) {
				*pfSlipError = TRUE;
				IFDBG(DebugOut(DEBUG_WARN, L"[BCSP] SLIPReadBytes failed with SLIP error.\n"));
				PushBackData(&slipBuffer[slipBufferPos], bytesRead-slipBufferPos);
				return FALSE;
			} else
				pData[unslippedByte++] = byte;	

			ASSERT (unslippedByte <= len);
		}
	}
	
	return TRUE;
}

static int ReadFromCOMPort(BCSPHeader *pHeader, unsigned char *pPayloadData) {
  	BOOL fDone = FALSE;

	while (!fDone) {
		// locate the start of a new packet
		unsigned char byte = 0;
		int fReadOK = TRUE;
		BOOL fSlipError = FALSE;

		while ((fReadOK = ReadCommPort (&byte, 1)) && (byte != SLIP_END))
			IFDBG(DebugOut (DEBUG_HCI_TRANSPORT, L"[BCSP] PACKET IN : skip <%02x>\n", byte));

		if (! fReadOK) {
			IFDBG(DebugOut(DEBUG_ERROR, L"[BCSP] ReadFromCOMPort failed.\n"));
			return FALSE;
		}

		while ((byte == SLIP_END) && (fReadOK = ReadCommPort (&byte, 1)))
			IFDBG(DebugOut (DEBUG_HCI_TRANSPORT, L"[BCSP] PACKET IN : skip <SLIP_END>\n"));

		if (! fReadOK) {
			IFDBG(DebugOut(DEBUG_ERROR, L"[BCSP] ReadFromCOMPort failed.\n"));
			return FALSE;
		}

		
		// now byte holds the first byte of the header structure
		// put it in there and read the rest of the header

		if(byte == SLIP_ESC) {
			if (! ReadCommPort (&byte, 1))
				return FALSE;

			pHeader->flags = (byte == SLIP_ESC_END) ? SLIP_END : SLIP_ESC;	
		} else pHeader->flags = byte;

		if (! SLIPReadBytes (((unsigned char *)pHeader) + 1, sizeof(*pHeader) - 1, &fSlipError)) {
			if (fSlipError)
				continue;

			IFDBG(DebugOut(DEBUG_ERROR, L"[BCSP] ReadFromCOMPort failed.\n"));
			return FALSE;
		}

#if defined (FULL_BCSP_DUMP)
		IFDBG(DebugOut (DEBUG_HCI_TRANSPORT, L"[BCSP] PACKET IN: seq      = %d\n", pHeader->seq));
		IFDBG(DebugOut (DEBUG_HCI_TRANSPORT, L"[BCSP] PACKET IN: ack      = %d\n", pHeader->ack));
		IFDBG(DebugOut (DEBUG_HCI_TRANSPORT, L"[BCSP] PACKET IN: crc      = %s\n", pHeader->crcPresent ? L"yes" : L"no"));
		IFDBG(DebugOut (DEBUG_HCI_TRANSPORT, L"[BCSP] PACKET IN: protocol = %d\n", pHeader->protocolType));
		IFDBG(DebugOut (DEBUG_HCI_TRANSPORT, L"[BCSP] PACKET IN: prot. id = %d\n", pHeader->protocolID));
		IFDBG(DebugOut (DEBUG_HCI_TRANSPORT, L"[BCSP] PACKET IN: payload  = %d bytes\n", pHeader->payloadLength));
#endif

		if ((pHeader->payloadLength > 0) && (! SLIPReadBytes(pPayloadData, pHeader->payloadLength, &fSlipError))) {
			if (fSlipError)
				continue;

			IFDBG(DebugOut(DEBUG_ERROR, L"[BCSP] ReadFromCOMPort failed.\n"));
			return FALSE;
		}

#if defined (FULL_BCSP_DUMP)
		IFDBG(DebugOut (DEBUG_HCI_TRANSPORT, L"[BCSP] PACKET IN: HEX HEADER\n"));
		IFDBG(for (int i = 0 ; i < sizeof (*pHeader) ; ++i) DebugOut (DEBUG_OUTPUT, L"%02x ", ((unsigned char *)pHeader)[i]););
		IFDBG(DebugOut (DEBUG_OUTPUT, L"\n"));

		if (pHeader->payloadLength > 0) {
			IFDBG(DebugOut (DEBUG_HCI_TRANSPORT, L"[BCSP] PACKET IN: PAYLOAD\n", pHeader->payloadLength));
			IFDBG(DumpBuff (DEBUG_HCI_TRANSPORT, pPayloadData, pHeader->payloadLength));
		}
#endif

		unsigned short crc;

		if(pHeader->crcPresent) {
			SLIPReadBytes (&crc, sizeof(crc), &fSlipError);
#if defined (FULL_BCSP_DUMP)
			IFDBG(DebugOut (DEBUG_HCI_TRANSPORT, L"[BCSP] PACKET IN: <crc:%02x>\n", crc));
#endif
		}

		fReadOK = ReadCommPort (&byte, 1);	
		if (! fReadOK) {
			IFDBG(DebugOut(DEBUG_ERROR, L"[BCSP] ReadFromCOMPort failed.\n"));
			return FALSE;
		}

		if (byte != SLIP_END)
			continue;

		fDone = TRUE;
	}

	return TRUE;
}

//
//	Misc class support functions
//
//
//	BCSPPacket
//

unsigned char* g_pWriteBuff;

int BCSPPacket::WriteToCOMPort (int fUnlock) {
	header.SetChecksum ();

	// first SLIP-encode header into packet data
	int slipHeaderLength = GetSLIPEncodedLength (&header, sizeof(header));

	ASSERT (slipHeaderLength <= 9);

	SLIPEncodeIntoBuffer (&header, sizeof(header), &pPacketData[9 - slipHeaderLength]);

	// write SLIP_END bytes
	pPacketData[8 - slipHeaderLength] = pPacketData[slipPayloadLength + 10 - 1] = SLIP_END;

#if defined (FULL_BCSP_DUMP)
	IFDBG(DebugOut (DEBUG_HCI_TRANSPORT, L"[BCSP] PACKET OUT: seq      = %d\n", header.seq));
	IFDBG(DebugOut (DEBUG_HCI_TRANSPORT, L"[BCSP] PACKET OUT: ack      = %d\n", header.ack));
	IFDBG(DebugOut (DEBUG_HCI_TRANSPORT, L"[BCSP] PACKET OUT: crc      = %s\n", header.crcPresent ? L"yes" : L"no"));
	IFDBG(DebugOut (DEBUG_HCI_TRANSPORT, L"[BCSP] PACKET OUT: protocol = %d\n", header.protocolType));
	IFDBG(DebugOut (DEBUG_HCI_TRANSPORT, L"[BCSP] PACKET OUT: prot. id = %d\n", header.protocolID));
	IFDBG(DebugOut (DEBUG_HCI_TRANSPORT, L"[BCSP] PACKET OUT: payload  = %d bytes\n", header.payloadLength));

	IFDBG(DebugOut(DEBUG_HCI_TRANSPORT, L"[BCSP] PACKET OUT: CODED PAYLOAD\n"));
	IFDBG(DumpBuff(DEBUG_HCI_TRANSPORT, &pPacketData[8 - slipHeaderLength], slipPayloadLength + slipHeaderLength + 2));
#endif

	int cBuffer = slipPayloadLength + slipHeaderLength + 2;

	ASSERT (cBuffer < MAX_BUFFER_SIZE);
	ASSERT (g_pWriteBuff);
	
	memcpy (g_pWriteBuff, &pPacketData[8 - slipHeaderLength], cBuffer);

	if (fUnlock)
		LeaveCriticalSection (&g_csBCSP);

	int iRes = WriteCommPort(g_pWriteBuff, cBuffer);

	if (fUnlock)
		EnterCriticalSection (&g_csBCSP);

	if (! iRes) {
		IFDBG(DebugOut(DEBUG_ERROR, L"[BCSP] BCSPPacket::WriteToCOMPort failed.\n"));
	}

	return iRes;
}

void BCSPPacket::SetData (const void *pvData, int len) {
	if(pPacketData)
		free(pPacketData);

	pPacketData = 0;
	
	header.payloadLength = len;
	slipPayloadLength = GetSLIPEncodedLength (pvData, len);

	pPacketData = (unsigned char *)malloc (slipPayloadLength + 10);
	if (pPacketData) {
		SLIPEncodeIntoBuffer (pvData, len, &pPacketData[9]);
	}
}

//
//	BCSPPacketListNode
//
static int GetListSize (void) {
	BCSPPacketListNode *pPacket = g_pTransmitPackets;
	
	int size = 0;
	while(pPacket) {
		++size;
		pPacket = pPacket->next;
	}

	return size;
}

static int GetSCOListSize (void) {
	BCSPPacketListNode *pPacket = g_pSCOTransmitPackets;
	
	int size = 0;
	while(pPacket) {
		++size;
		pPacket = pPacket->next;
	}

	return size;
}

static void AddToList(BCSPPacketListNode* pNewPacket) {
	BCSPPacketListNode* pPacket;
	
	ASSERT (pNewPacket->next == 0);

	if (pNewPacket->packet.header.protocolID == IO_DATA_PROTOCOL_HCI_SCO) {
		if(! g_pSCOTransmitPackets) {
			g_pSCOTransmitPackets = pNewPacket;
			return;
		}
		pPacket = g_pSCOTransmitPackets;
	}
	else {
		if(! g_pTransmitPackets) {
			g_pTransmitPackets = pNewPacket;
			return;
		}
		pPacket = g_pTransmitPackets;
	}

	while(pPacket->next) pPacket = pPacket->next;
	pPacket->next = pNewPacket;
}

static BCSPPacketListNode *GetFirstPacketForSend (void) {
	BCSPPacketListNode *pPacket = g_pTransmitPackets;
	while(pPacket && (! pPacket->packet.fResendPacket) && (! pPacket->packet.fNewPacket))
		pPacket = pPacket->next;

	return pPacket;
}

static BCSPPacketListNode *GetNextSCOPacket (void) {
	BCSPPacketListNode *pPacket = g_pSCOTransmitPackets;
	if (g_pSCOTransmitPackets) {
		g_pSCOTransmitPackets = g_pSCOTransmitPackets->next;
	}
	
	return pPacket;
}

//
//	Protocol procedures : Link establishment
//
//			HANDLE handles[2] = { hLinkEstablishmentThreadDie, hLinkEstablishmentSyncReceived };
static DWORD WINAPI BCSPLinkEstablishmentThread (LPVOID phandles) {
	IFDBG(DebugOut (DEBUG_HCI_TRANSPORT, L"[BCSP] BCSPLinkEstablishmentThread started...\n"));

	const unsigned char syncPayload[] = { 0xDA, 0xDC, 0xED, 0xED };

	BCSPPacket syncPacket;
	syncPacket.SetData(syncPayload, 4);
	syncPacket.header.ack = 0;
	syncPacket.header.seq = 0;
	syncPacket.header.crcPresent = 0;
	syncPacket.header.payloadLength = 4;
	syncPacket.header.protocolID = 1;
	syncPacket.header.protocolType = 0;

	const unsigned char syncRespPayload[] = { 0xAC, 0xAF, 0xEF, 0xEE };

	BCSPPacket syncRespPacket;
	syncRespPacket.SetData(syncRespPayload, 4);
	syncRespPacket.header.ack = 0;
	syncRespPacket.header.seq = 0;
	syncRespPacket.header.crcPresent = 0;
	syncRespPacket.header.payloadLength = 4;
	syncRespPacket.header.protocolID = 1;
	syncRespPacket.header.protocolType = 0;

	const unsigned char confPayload[] = { 0xAD, 0xEF, 0xAC, 0xED };

	BCSPPacket confPacket;
	confPacket.SetData(confPayload, 4);
	confPacket.header.ack = 0;
	confPacket.header.seq = 0;
	confPacket.header.crcPresent = 0;
	confPacket.header.payloadLength = 4;
	confPacket.header.protocolID = 1;
	confPacket.header.protocolType = 0;

	IFDBG(DebugOut (DEBUG_HCI_TRANSPORT, L"[BCSP] BCSPLinkEstablishmentThread : SYNC\n"));

	if (syncPacket.WriteToCOMPort (FALSE)) {
		int iCount = 0;

		while (iCount < BCSP_RETRY_LIMIT) {
			DWORD ret = WaitForMultipleObjects (2, (HANDLE *)phandles, FALSE, BCSP_PASSIVE_TIMEOUT);

			if(WAIT_OBJECT_0 == ret) {
				IFDBG(DebugOut (DEBUG_HCI_TRANSPORT, L"[BCSP] BCSPLinkEstablishmentThread : got SYNC-RESP, sending CONF and returning\n"));
				return confPacket.WriteToCOMPort (FALSE);
			} else if (WAIT_OBJECT_0 + 1 == ret) {
				IFDBG(DebugOut (DEBUG_HCI_TRANSPORT, L"[BCSP] BCSPLinkEstablishmentThread : got SYNC, send SYNC-RESP\n"));

				if (! syncRespPacket.WriteToCOMPort (FALSE))
					break;
			} else {
				ASSERT (ret == WAIT_TIMEOUT);
				IFDBG(DebugOut (DEBUG_HCI_TRANSPORT, L"[BCSP] BCSPLinkEstablishmentThread : timeout, resending SYNC\n"));

				if (! syncPacket.WriteToCOMPort (FALSE))
					break;

				++iCount;
			}
		}
	}

	IFDBG(DebugOut (DEBUG_ERROR, L"[BCSP] BCSPLinkEstablishmentThread : closing port and dying\n"));
	CloseCommPort ();

	return FALSE;
}

static int BCSPLinkEstablishment (void) {
#ifndef BCSP_NO_LINK_ESTABLISHMENT
	unsigned char payload[PACKET_SIZE_R];
	BCSPHeader syncHeader;

	const unsigned char syncPayload[] = { 0xDA, 0xDC, 0xED, 0xED };
	const unsigned char syncRespPayload[] = { 0xAC, 0xAF, 0xEF, 0xEE };

	payload[0] = 0;

	HANDLE hLinkEstablishmentThreadDie    = CreateEvent (NULL, TRUE, FALSE, NULL);
	HANDLE hLinkEstablishmentSyncReceived = CreateEvent (NULL, FALSE, FALSE, NULL);

	HANDLE handles[2] = { hLinkEstablishmentThreadDie, hLinkEstablishmentSyncReceived };

	HANDLE hThread = CreateThread(NULL, 0, BCSPLinkEstablishmentThread, handles, 0, NULL);

	int iRes = FALSE;

	while (TRUE) {
		if (! ReadFromCOMPort(&syncHeader, payload))
			break;

		if (syncHeader.payloadLength != 4)
			continue;

		if (0 == memcmp(syncPayload, payload, 4))
			SetEvent(hLinkEstablishmentSyncReceived);
		else if (0 == memcmp(syncRespPayload, payload, 4)) {
			iRes = TRUE;
			break;
		}
	}

⌨️ 快捷键说明

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