📄 btclient.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 <stdio.h>
#include <bt_api.h>
#include "../l2capapi/l2capapi.hxx"
#include "btdc.h"
#if defined (USE_RPC)
extern "C" handle_t bluetooth_IfHandle;
extern "C" void __RPC_FAR * __RPC_API midl_user_allocate (size_t len) {
return malloc(len);
}
extern "C" void __RPC_API midl_user_free (void * __RPC_FAR ptr) {
free (ptr);
}
#endif
const unsigned char crctable[256] = { //reversed, 8-bit, poly=0x07
0x00, 0x91, 0xE3, 0x72, 0x07, 0x96, 0xE4, 0x75, 0x0E, 0x9F, 0xED, 0x7C, 0x09, 0x98, 0xEA, 0x7B,
0x1C, 0x8D, 0xFF, 0x6E, 0x1B, 0x8A, 0xF8, 0x69, 0x12, 0x83, 0xF1, 0x60, 0x15, 0x84, 0xF6, 0x67,
0x38, 0xA9, 0xDB, 0x4A, 0x3F, 0xAE, 0xDC, 0x4D, 0x36, 0xA7, 0xD5, 0x44, 0x31, 0xA0, 0xD2, 0x43,
0x24, 0xB5, 0xC7, 0x56, 0x23, 0xB2, 0xC0, 0x51, 0x2A, 0xBB, 0xC9, 0x58, 0x2D, 0xBC, 0xCE, 0x5F,
0x70, 0xE1, 0x93, 0x02, 0x77, 0xE6, 0x94, 0x05, 0x7E, 0xEF, 0x9D, 0x0C, 0x79, 0xE8, 0x9A, 0x0B,
0x6C, 0xFD, 0x8F, 0x1E, 0x6B, 0xFA, 0x88, 0x19, 0x62, 0xF3, 0x81, 0x10, 0x65, 0xF4, 0x86, 0x17,
0x48, 0xD9, 0xAB, 0x3A, 0x4F, 0xDE, 0xAC, 0x3D, 0x46, 0xD7, 0xA5, 0x34, 0x41, 0xD0, 0xA2, 0x33,
0x54, 0xC5, 0xB7, 0x26, 0x53, 0xC2, 0xB0, 0x21, 0x5A, 0xCB, 0xB9, 0x28, 0x5D, 0xCC, 0xBE, 0x2F,
0xE0, 0x71, 0x03, 0x92, 0xE7, 0x76, 0x04, 0x95, 0xEE, 0x7F, 0x0D, 0x9C, 0xE9, 0x78, 0x0A, 0x9B,
0xFC, 0x6D, 0x1F, 0x8E, 0xFB, 0x6A, 0x18, 0x89, 0xF2, 0x63, 0x11, 0x80, 0xF5, 0x64, 0x16, 0x87,
0xD8, 0x49, 0x3B, 0xAA, 0xDF, 0x4E, 0x3C, 0xAD, 0xD6, 0x47, 0x35, 0xA4, 0xD1, 0x40, 0x32, 0xA3,
0xC4, 0x55, 0x27, 0xB6, 0xC3, 0x52, 0x20, 0xB1, 0xCA, 0x5B, 0x29, 0xB8, 0xCD, 0x5C, 0x2E, 0xBF,
0x90, 0x01, 0x73, 0xE2, 0x97, 0x06, 0x74, 0xE5, 0x9E, 0x0F, 0x7D, 0xEC, 0x99, 0x08, 0x7A, 0xEB,
0x8C, 0x1D, 0x6F, 0xFE, 0x8B, 0x1A, 0x68, 0xF9, 0x82, 0x13, 0x61, 0xF0, 0x85, 0x14, 0x66, 0xF7,
0xA8, 0x39, 0x4B, 0xDA, 0xAF, 0x3E, 0x4C, 0xDD, 0xA6, 0x37, 0x45, 0xD4, 0xA1, 0x30, 0x42, 0xD3,
0xB4, 0x25, 0x57, 0xC6, 0xB3, 0x22, 0x50, 0xC1, 0xBA, 0x2B, 0x59, 0xC8, 0xBD, 0x2C, 0x5E, 0xCF
};
unsigned char MakeFCS (int len, unsigned char *p) {
unsigned char FCS=0xFF;
while (len--)
FCS=crctable[FCS^*p++];
return 0xFF - FCS;
}
int CheckFCS (int len, unsigned char *p, unsigned char code) {
unsigned char FCS=0xFF;
while (len--)
FCS=crctable[FCS^*p++];
FCS = crctable[FCS^code];
return (FCS==0xCF);
}
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 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;
}
int GetBytes (WCHAR **pp, unsigned char *pbuf, int *piLen) {
int iBufSize = *piLen;
*piLen = 0;
while (**pp == ' ')
++*pp;
int iRes = 0;
int iDig = 0;
int i = 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 == 2) {
if (i >= iBufSize)
return FALSE;
pbuf[i++] = iRes;
iRes = 0;
iDig = 0;
}
}
if (iDig == 1)
return FALSE;
*piLen = i;
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
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);
}
}
DWORD WINAPI ReadThread (LPVOID lpVoid) {
unsigned short cid = (unsigned short)lpVoid;
wprintf (L"Read thread created for connection 0x%04x\n", cid);
int cCount = 0;
FILE *fp = NULL;
unsigned char *ucbuffer = (unsigned char *)malloc(0xffff);
for ( ; ; ) {
int cSize = 0;
int iErr = L2CAPRead (cid, 0xffff, (unsigned int *)&cSize, ucbuffer);
if (iErr != ERROR_SUCCESS) {
wprintf (L"Error 0x%08x (%d)\n", iErr, iErr);
L2CAPCloseCID (cid);
break;
}
if (cSize >= 16) {
int cSig = *(int *)ucbuffer;
if ((cSig == 'NAME') || (cSig == 'DATA') || (cSig == 'DONE')) {
int crc = *(int *)(ucbuffer + 4);
int c = *(int *)(ucbuffer + 8);
int ct = *(int *)(ucbuffer + 12);
if ((crc <= 0xff) && ((c + 16) == cSize) && (ct == cCount)) {
wprintf (L".");
if ((cSig == 'DONE') && (crc == 0) && (c == 0) && fp) {
wprintf (L"\nFile transfer complete\n");
fclose (fp);
fp = NULL;
cCount = 0;
continue;
} else if ((cSig == 'NAME') && (ct == 0)) {
if (fp) {
wprintf (L"\nFile transfer aborted!\n");
fclose (fp);
fp = NULL;
cCount = 0;
}
fp = _wfopen ((WCHAR *)(ucbuffer + 16), L"wb");
if (! fp)
wprintf (L"Cannot open the file %s\n", (WCHAR*) (ucbuffer + 16));
else {
wprintf (L"\nStarted transfer of %s\n", (WCHAR*) (ucbuffer + 16));
++cCount;
continue;
}
} else if ((cSig == 'DATA') && fp && (c > 0) && CheckFCS (c, ucbuffer + 16, crc & 0xff)) {
int cc = fwrite (ucbuffer + 16, 1, c, fp);
if (cc != c) {
wprintf (L"\nWrite aborted!\n");
fclose (fp);
fp = NULL;
cCount = 0;
} else {
++cCount;
continue;
}
}
}
}
}
if (fp) {
wprintf (L"\nFile transfer aborted!\n");
fclose (fp);
fp = NULL;
cCount = 0;
}
WCHAR *p = (WCHAR *)ucbuffer;
int c = cSize / 2;
if (((c * 2) == cSize) && (c > 0) && (p[c - 1] == '\0')) {
for (int i = 0 ; i < c - 1 ; ++i) {
if (! iswprint (p[i]))
break;
}
if (i == c - 1)
wprintf (L"%04x> %s\n", cid, (WCHAR*) ucbuffer);
else
DumpBuff (NULL, ucbuffer, cSize);
} else
DumpBuff (NULL, ucbuffer, cSize);
}
free (ucbuffer);
return 0;
}
static struct {
HANDLE hDevice;
HANDLE hFile;
int fActivated;
} g_ports[10];
static int g_fPortsInit = FALSE;
DWORD WINAPI RFCOMMReadThread (LPVOID lpVoid) {
WCHAR szComPort[30];
int index = (int)lpVoid;
if ((index < 0) || (index > 9))
return 0;
wsprintf (szComPort, L"COM%d:", index);
HANDLE hCommPort = rfCreateFile (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 ());
return 0;
}
wprintf (L"Opened %s, handle 0x%08x\n", szComPort, hCommPort);
g_ports[index].hFile = hCommPort;
unsigned char buffer[10];
DWORD dwRead;
while (rfReadFile (hCommPort, buffer, sizeof(buffer), &dwRead, NULL))
DumpBuff (szComPort, buffer, dwRead);
rfCloseHandle (hCommPort);
g_ports[index].hFile = INVALID_HANDLE_VALUE;
wprintf (L"Exiting thread for port %s\n", szComPort);
return 0;
}
BOOL WriteCommPort (HANDLE hFile, unsigned char *pBuffer, unsigned int cSize) {
DWORD dwFilledSoFar = 0;
while ((int)dwFilledSoFar < cSize) {
DWORD dwWrit = 0;
#if ! defined (UNDER_CE)
static HANDLE hWriteEvent = NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -