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

📄 sca.cxx

📁 蓝牙wince测试demo Windows CE Bluetooth application sample
💻 CXX
字号:
//
// 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.
//
/**
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED 
WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.


Abstract:
	Windows CE Bluetooth application sample

**/
#include <windows.h>
#include <bt_api.h>

#define BUF_MAX 256

int GetDI (WCHAR **pp, unsigned int *pi) {
	while (**pp == ' ')
		++*pp;

	int iDig = 0;
	*pi = 0;
	while (iswdigit (**pp)) {
		int c = **pp;

		c = c - '0';

		if ((c < 0) || (c > 9))
			return FALSE;

		*pi = *pi * 10 + c;

		++*pp;

		++iDig;
	}

	if ((iDig <= 0) || (iDig > 10))
		return FALSE;

	return TRUE;
}

int GetBA (WCHAR **pp, BT_ADDR *pba) {
	while (**pp == ' ')
		++*pp;

	for (int i = 0 ; i < 4 ; ++i, ++*pp) {
		if (! iswxdigit (**pp))
			return FALSE;

		int c = **pp;
		if (c >= 'a')
			c = c - 'a' + 0xa;
		else if (c >= 'A')
			c = c - 'A' + 0xa;
		else c = c - '0';

		if ((c < 0) || (c > 16))
			return FALSE;

		*pba = *pba * 16 + c;
	}

	for (i = 0 ; i < 8 ; ++i, ++*pp) {
		if (! iswxdigit (**pp))
			return FALSE;

		int c = **pp;
		if (c >= 'a')
			c = c - 'a' + 0xa;
		else if (c >= 'A')
			c = c - 'A' + 0xa;
		else c = c - '0';

		if ((c < 0) || (c > 16))
			return FALSE;

		*pba = *pba * 16 + c;
	}

	if ((**pp != ' ') && (**pp != '\0'))
		return FALSE;

	return TRUE;
}

#define BPR		8

int GetUx (WCHAR **pp, void *pRes, int nDigs) {
	while (**pp == ' ')
		++*pp;
	if (**pp != '0')
		return FALSE;
	++*pp;
	if (**pp != 'x')
		return FALSE;

	++*pp;

	int iDig = 0;
	int iRes = 0;
	while (iswxdigit (**pp)) {
		int c = **pp;
		if (c >= 'a')
			c = c - 'a' + 0xa;
		else if (c >= 'A')
			c = c - 'A' + 0xa;
		else c = c - '0';

		if ((c < 0) || (c > 16))
			return FALSE;

		iRes = iRes * 16 + c;

		++*pp;

		++iDig;
	}

	if (iDig > nDigs)
		return FALSE;

	switch (nDigs) {
	case 2:
		*(unsigned char *)pRes = (unsigned char)iRes;
		break;
	case 4:
		*(unsigned short *)pRes = (unsigned short)iRes;
		break;
	case 8:
		*(unsigned int *)pRes = (unsigned int)iRes;
		break;
	}

	return TRUE;
}

void DumpBuff (WCHAR *szLineHeader, unsigned char *lpBuffer, unsigned int cBuffer) {
	WCHAR szLine[5 + 7 + 2 + 4 * BPR];

	for (int i = 0 ; i < (int)cBuffer ; i += BPR) {
		int bpr = cBuffer - i;
		if (bpr > BPR)
			bpr = BPR;

		wsprintf (szLine, L"%04x ", i);
		WCHAR *p = szLine + wcslen (szLine);

		for (int j = 0 ; j < bpr ; ++j) {
			WCHAR c = (lpBuffer[i + j] >> 4) & 0xf;
			if (c > 9) c += L'a' - 10; else c += L'0';
			*p++ = c;
			c = lpBuffer[i + j] & 0xf;
			if (c > 9) c += L'a' - 10; else c += L'0';
			*p++ = c;
			*p++ = L' ';
		}

		for ( ; j < BPR ; ++j) {
			*p++ = L' ';
			*p++ = L' ';
			*p++ = L' ';
		}

		*p++ = L' ';
		*p++ = L' ';
		*p++ = L' ';
		*p++ = L'|';
		*p++ = L' ';
		*p++ = L' ';
		*p++ = L' ';

		for (j = 0 ; j < bpr ; ++j) {
			WCHAR c = lpBuffer[i + j];
			if ((c < L' ') || (c >= 127))
				c = L'.';

			*p++ = c;
		}

		for ( ; j < BPR ; ++j) {
			*p++ = L' ';
		}

		*p++ = L'\n';
		*p++ = L'\0';

		wprintf (L"%s %s", szLineHeader ? szLineHeader : L"", szLine);
	}
}

void DisplayModem (HANDLE hFile) {
	DWORD dwModem = 0;
	GetCommModemStatus (hFile, &dwModem);
	wprintf (L": ");
	if (dwModem & MS_CTS_ON)
		wprintf (L"MS_CTS_ON ");
	if (dwModem & MS_DSR_ON)
		wprintf (L"MS_DSR_ON ");
	if (dwModem & MS_RING_ON)
		wprintf (L"MS_RING_ON ");
	if (dwModem & MS_RLSD_ON)
		wprintf (L"MS_RLSD_ON ");
	wprintf (L"\n");
}

void GetAndPrintDCB (HANDLE hFile) {
	DCB dcb;
	memset (&dcb, 0, sizeof(dcb));
	dcb.DCBlength = sizeof(dcb);
	if (GetCommState (hFile, &dcb)) {
		wprintf (L"Baud rate:           %d\n", dcb.BaudRate);
		wprintf (L"Binary:              %s\n", dcb.fBinary ? L"yes" : L"no");
		wprintf (L"Parity:              %s\n", dcb.fParity ? L"yes" : L"no");
		wprintf (L"fOutxCtsFlow         %s\n", dcb.fOutxCtsFlow ? L"yes" : L"no");
		wprintf (L"fOutxDsrFlow         %s\n", dcb.fOutxDsrFlow ? L"yes" : L"no");
		wprintf (L"fDtrControl          %s\n", dcb.fDtrControl == DTR_CONTROL_DISABLE ? L"DTR_CONTROL_DISABLE" : (dcb.fDtrControl == DTR_CONTROL_ENABLE ? L"DTR_CONTROL_ENABLE" : (dcb.fDtrControl == DTR_CONTROL_HANDSHAKE ? L"DTR_CONTROL_HANDSHAKE" : L"unknown")));
		wprintf (L"fDsrSensitivity      %s\n", dcb.fDsrSensitivity ? L"yes" : L"no");
		wprintf (L"fTXContinueOnXoff    %s\n", dcb.fTXContinueOnXoff ? L"yes" : L"no");
		wprintf (L"fOutX                %s\n", dcb.fOutX ? L"yes" : L"no");
		wprintf (L"fInX                 %s\n", dcb.fInX ? L"yes" : L"no");
		wprintf (L"fErrorChar           %s\n", dcb.fErrorChar ? L"yes" : L"no");
		wprintf (L"fNull                %s\n", dcb.fNull ? L"yes" : L"no");
		wprintf (L"fRtsControl          %s\n", dcb.fRtsControl == RTS_CONTROL_DISABLE ? L"RTS_CONTROL_DISABLE" : (dcb.fRtsControl == RTS_CONTROL_ENABLE ? L"RTS_CONTROL_ENABLE" : (dcb.fRtsControl == RTS_CONTROL_HANDSHAKE ? L"RTS_CONTROL_HANDSHAKE" : L"unknown")));
		wprintf (L"fAbortOnError        %s\n", dcb.fAbortOnError ? L"yes" : L"no");
		wprintf (L"XonLim               %d\n", dcb.XonLim);
		wprintf (L"XoffLim              %d\n", dcb.XoffLim);
		wprintf (L"ByteSize             %d\n", dcb.ByteSize);
		wprintf (L"Parity               %s\n", dcb.Parity == NOPARITY ? L"NOPARITY" : (dcb.Parity == ODDPARITY ? L"ODDPARITY" : (dcb.Parity == EVENPARITY ? L"EVENPARITY" : (dcb.Parity == MARKPARITY ? L"MARKPARITY" : dcb.Parity == SPACEPARITY ? L"SPACEPARITY" : L"UNKNOWN"))));
		wprintf (L"StopBits             %s\n", dcb.StopBits == ONESTOPBIT ? L"ONESTOPBIT" : (dcb.StopBits == ONE5STOPBITS ? L"ONE5STOPBITS" : (dcb.StopBits == TWOSTOPBITS ? L"TWOSTOPBITS" : L"UNKNOWN")));
		wprintf (L"XonChar              0x%02x\n", dcb.XonChar);
		wprintf (L"XoffChar             0x%02x\n", dcb.XoffChar);
		wprintf (L"ErrorChar            0x%02x\n", dcb.ErrorChar);
		wprintf (L"EofChar              0x%02x\n", dcb.EofChar);
		wprintf (L"EvtChar              0x%02x\n", dcb.EvtChar);
	} else
		wprintf (L"GetCommState fails, error %d\n", GetLastError ());
}

DWORD WINAPI ReadThread (LPVOID lpVoid) {
	HANDLE hFile = (HANDLE)lpVoid;
	WCHAR szHeader[25];
	wsprintf (szHeader, L"0x%08x > ", hFile);

	SetCommMask (hFile, EV_RXCHAR | EV_CTS | EV_DSR | EV_RLSD | EV_ERR | EV_RING | EV_EVENT1);

	for ( ; ; ) {
		DWORD ModemState;

		if (! WaitCommEvent (hFile, &ModemState, NULL))
			break;

		wprintf (L"Read thread woke up, ModemState = 0x%08x!\n", ModemState);

		if (ModemState & EV_RXCHAR) {
			char buffer[BUF_MAX];
			DWORD dwRead = 0;
			if (! ReadFile (hFile, buffer, sizeof(buffer), &dwRead, NULL))
				break;

			DumpBuff (szHeader, (unsigned char *)buffer, dwRead);
		}

		if (ModemState & EV_ERR)
			wprintf (L"COMM: Error signalled!\n");

		int fDisplayModem = FALSE;

		if (ModemState & EV_CTS) {
			wprintf (L"EV_CTS ");
			fDisplayModem = TRUE;
		}

		if (ModemState & EV_DSR) {
			wprintf (L"EV_DSR ");
			fDisplayModem = TRUE;
		}

		if (ModemState & EV_RLSD) {
			wprintf (L"EV_RLSD ");
			fDisplayModem = TRUE;
		}

		if (ModemState & EV_RING) {
			wprintf (L"EV_RING ");
			fDisplayModem = TRUE;
		}

		if (fDisplayModem)
			DisplayModem (hFile);

		if (ModemState & EV_EVENT1) {
			wprintf (L"DCB arrived\n");
			GetAndPrintDCB (hFile);
		}
	}

	CloseHandle (hFile);

	return 0;
}

int UserGetDCB (HANDLE hFile, DCB *pdcb) {
	wprintf (L"Setting DCB.\n");
	memset (pdcb, 0, sizeof (*pdcb));
	pdcb->DCBlength = sizeof(*pdcb);

	if (! GetCommState (hFile, pdcb)) {
		wprintf (L"Cound not get comm state\n");
		return FALSE;
	}

	int iDatum;

	wprintf (L"Baud> ");
	scanf ("%d", &iDatum);
	pdcb->BaudRate = iDatum;

	wprintf (L"DATABITS, 5-8\nByte Size> ");
	scanf ("%d", &iDatum);
	pdcb->ByteSize = iDatum;

	wprintf (L"ONESTOPBIT=0, ONE5STOPBITS=1\nStop Bits> ");
	scanf ("%d", &iDatum);
	pdcb->StopBits = iDatum;

	wprintf (L"NOPARITY = 0, ODDPARITY=1, EVENPARITY=2, MARKPARITY=3, SPACEPARITY=4\nParity> ");
	scanf ("%d", &iDatum);
	pdcb->Parity = iDatum;
	if (pdcb->Parity != 0)
		pdcb->fParity = TRUE;

	return TRUE;
}

static void Help (void) {
	wprintf (L"Use one of:\n\tEXIT\n\tSEND file\n\tTEXT string\n\tBIN binary data (list of 2 dig hex numbers)\n\tSETDCB\n\tGETDCB\n");
}

DWORD WINAPI WriteThread (LPVOID lpVoid) {
	Help ();

	HANDLE hFile = (HANDLE)lpVoid;

	for ( ; ; ) {
		wprintf (L"> ");
		WCHAR szCommand[BUF_MAX];
		if (! fgetws (szCommand, BUF_MAX, stdin))
			break;

		WCHAR *p = wcschr (szCommand, L'\n');
		if (p)
			*p = '\0';

		if (wcsicmp (szCommand, L"EXIT") == 0)
			break;

		if (wcsicmp (szCommand, L"SETDCB") == 0) {
			DCB dcb;
			if (UserGetDCB (hFile, &dcb)) {
				if (! SetCommState (hFile, &dcb))
					wprintf (L"SetCommState: error %d\n", GetLastError ());
			}
			continue;
		}

		if (wcsicmp (szCommand, L"GETDCB") == 0) {
			GetAndPrintDCB (hFile);
			continue;
		}

		if (wcsnicmp (szCommand, L"SEND ", 5) == 0) {
			WCHAR *szName = szCommand + 5;
			WCHAR *szEOL = wcschr (szName, L'\n');
			if (szEOL)
				*szEOL = '\0';

			FILE *fp = _wfopen (szName, L"r");
			if (fp) {
				unsigned char b[BUF_MAX];
				for ( ; ; ) {
					int c = fread (b, 1, sizeof(b), fp);
					if (c <= 0)
						break;

					DWORD dwWritten = 0;
					if (! WriteFile (hFile, (char *)b, c, &dwWritten, NULL)) {
						wprintf (L"WriteFile returns %d bytes written, Error = %d\n", dwWritten, GetLastError ());
						break;
					}

					if ((int)dwWritten != c)
						wprintf (L"Written %d out of requested %d\n", dwWritten, c);
				}

				fclose (fp);
			} else
				wprintf (L"Cannot open %s\n", szCommand);

			continue;
		}

		if (wcsnicmp (szCommand, L"TEXT ", 5) == 0) {
			WCHAR *szString = szCommand + 5;
			WCHAR *szEOL = wcschr (szString, L'\n');
			if (szEOL)
				*szEOL = '\0';
			int c = (wcslen (szString) + 1) * sizeof(WCHAR);
			if (c > sizeof (WCHAR)) {
				DWORD dwWritten = 0;
				if (! WriteFile (hFile, (char *)szString, c, &dwWritten, NULL)) {
					wprintf (L"WriteFile returns %d bytes written, Error = %d\n", dwWritten, GetLastError ());
				} else {
					if ((int)dwWritten != c)
						wprintf (L"Written %d out of requested %d\n", dwWritten, c);
				}
			} else
				wprintf (L"Empty string!\n");

			continue;
		}

		if (wcsnicmp (szCommand, L"BIN ", 4) == 0) {
			WCHAR *szData = szCommand + 4;
			WCHAR *szEOL = wcschr (szData, L'\n');
			if (szEOL)
				*szEOL = '\0';

			int c = 0;
			unsigned char *b = (unsigned char *)szCommand;

			for ( ; ; ) {
				if (! GetUx (&szData, b + c, 2))
					break;

				++c;
			}

			if (c > 0) {
				DWORD dwWritten = 0;
				if (! WriteFile (hFile, (char *)b, c, &dwWritten, NULL)) {
					wprintf (L"WriteFile returns %d bytes written, Error = %d\n", dwWritten, GetLastError ());
				} else {
					if ((int)dwWritten != c)
						wprintf (L"Written %d out of requested %d\n", dwWritten, c);
				}
			} else
				wprintf (L"Empty string!\n");

			continue;
		}

	}

	CloseHandle (hFile);
	return 0;
}

int wmain (int argc, WCHAR **argv) {
	WCHAR *arg2 = argv[2];
	WCHAR *arg3 = argv[3];
	WCHAR *arg4 = argv[4];
	int channel = 0;
	int index = 0;

	PORTEMUPortParams pp;
	memset (&pp, 0, sizeof(pp));

	if ((argc == 5) && (wcsicmp (argv[1], L"client") == 0) && GetBA(&arg2, &pp.device) && GetDI(&arg3, (unsigned int *)&channel) && GetDI(&arg4, (unsigned int *)&index)) {
		pp.channel = channel & 0xff;
		pp.uiportflags = RFCOMM_PORT_FLAGS_REMOTE_DCB;
	} else if ((argc == 4) && (wcsicmp (argv[1], L"server") == 0) && GetDI(&arg2, (unsigned int *)&channel) && GetDI(&arg3, (unsigned int *)&index)) {
		pp.flocal = TRUE;
		pp.channel = channel & 0xff;
	} else {
		wprintf (L"Usage: %s {server | client <target bt_addr>} channel port_index\n", argv[0]);
		return 1;
	}

	HANDLE h = RegisterDevice (L"COM", index, L"btd.dll", (DWORD)&pp);
	wprintf (L"handle = 0x%08x\n", h);

	if (h == NULL) {
		wprintf (L"GetLastError = %d\n", GetLastError ());
		return 0;
	}

	WCHAR szComPort[30];
	wsprintf (szComPort, L"COM%d:", index);
	HANDLE hCommPort = CreateFile (szComPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
	if (hCommPort == INVALID_HANDLE_VALUE) {
		wprintf (L"Failed to open %s. Error = %d\n", szComPort, GetLastError ());
		DeregisterDevice (h);
		return 0;
	}

	CloseHandle (CreateThread(NULL, 0, ReadThread, (LPVOID)hCommPort, 0, NULL));
	WriteThread ((LPVOID)hCommPort);

	DeregisterDevice (h);

	return 0;
}

⌨️ 快捷键说明

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