📄 opttest.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 <winsock.h>
#include <ws2bth.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 GUID_FORMAT L"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x\n"
#define GUID_ELEMENTS(p) \
&p->Data1, &p->Data2, &p->Data3,\
&p->Data4[0], &p->Data4[1], &p->Data4[2], &p->Data4[3],\
&p->Data4[4], &p->Data4[5], &p->Data4[6], &p->Data4[7]
int GetGUID(WCHAR *psz, GUID *pGUID) {
return (11 == swscanf(psz,GUID_FORMAT,GUID_ELEMENTS(pGUID)));
}
#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);
}
}
static void DumpFeatures (unsigned char *pf) {
wprintf (L"Supported LMP features:\n");
if ((*pf) & 0x01)
wprintf (L"\t3-slot packets\n");
if ((*pf) & 0x02)
wprintf (L"\t5-slot packets\n");
if ((*pf) & 0x04)
wprintf (L"\tencryption\n");
if ((*pf) & 0x08)
wprintf (L"\tslot offset\n");
if ((*pf) & 0x10)
wprintf (L"\ttiming accuracy\n");
if ((*pf) & 0x20)
wprintf (L"\tswitch\n");
if ((*pf) & 0x40)
wprintf (L"\thold\n");
if ((*pf) & 0x80)
wprintf (L"\tsniff\n");
++pf;
if ((*pf) & 0x01)
wprintf (L"\tpark\n");
if ((*pf) & 0x02)
wprintf (L"\tRSSI\n");
if ((*pf) & 0x04)
wprintf (L"\tchannel-quality driven rate\n");
if ((*pf) & 0x08)
wprintf (L"\tSCO\n");
if ((*pf) & 0x10)
wprintf (L"\tHV2\n");
if ((*pf) & 0x20)
wprintf (L"\tHV3\n");
if ((*pf) & 0x40)
wprintf (L"\tu-law log\n");
if ((*pf) & 0x80)
wprintf (L"\ta-law log\n");
++pf;
if ((*pf) & 0x01)
wprintf (L"\tCVSD\n");
if ((*pf) & 0x02)
wprintf (L"\tpaging scheme\n");
if ((*pf) & 0x04)
wprintf (L"\tpower control\n");
if ((*pf) & 0x08)
wprintf (L"\ttransparent SCO data\n");
if ((*pf) & 0x10)
wprintf (L"\tflow lag bit 0\n");
if ((*pf) & 0x20)
wprintf (L"\tflow lag bit 0\n");
if ((*pf) & 0x40)
wprintf (L"\tflow lag bit 0\n");
}
DWORD WINAPI ReadThread (LPVOID lpVoid) {
wprintf (L"Reader thread started for socket 0x%08x\n", lpVoid);
SOCKET s = (SOCKET)lpVoid;
WCHAR szHeader[25];
SOCKADDR_BTH sa;
int size = sizeof(sa);
if (0 == getsockname (s, (SOCKADDR *)&sa, &size)) {
if (size != sizeof(sa)) {
wprintf (L"getsockname returned incorrect size (%d, expected %d)\n", size, sizeof(sa));
wcscpy (szHeader, L">>>>");
} else {
wsprintf (szHeader, L"%04x%08x 0x%02 >", GET_NAP(sa.btAddr),
GET_SAP(sa.btAddr), sa.port);
}
} else {
wprintf (L"getsockname failed. Error = %d\n", WSAGetLastError ());
wcscpy (szHeader, L">>>>");
}
for ( ; ; ) {
char buffer[BUF_MAX];
int len = recv (s, buffer, sizeof(buffer), 0);
if (len <= 0)
break;
DumpBuff (szHeader, (unsigned char *)buffer, len);
}
closesocket (s);
wprintf (L"Reader thread ended for socket 0x%08x\n", lpVoid);
return 0;
}
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");
wprintf (L"\tAUTH\n\tENCRYPT {on, off}\n\tPIN binary data (list of 2 dig hex numbers)\n\tMSC xx xx\n\tRLS xx\n");
wprintf (L"\tXON dec number\n\tXOFF dec number\n\tSENDBUFF dec number\n\tRECVBUFF dec number\n\tGETALL\n\tGETVERSION\n");
wprintf (L"\tHOLD xxxx xxxx\n\tSNIFF xxxx xxxx xxxx xxxx\n\t\n\tUNSNIFF\n\tPARK xxxx xxxx\n\tUNPARK\n");
wprintf (L"\tGETMODE\n\tGETPOLICY\n\tSETPOLICY xxxx\n");
}
DWORD WINAPI WriteThread (LPVOID lpVoid) {
wprintf (L"Writer thread started for socket 0x%08x\n", lpVoid);
Help ();
SOCKET s = (SOCKET)lpVoid;
for ( ; ; ) {
wprintf (L"> ");
WCHAR szCommand[BUF_MAX];
if (! fgetws (szCommand, BUF_MAX, stdin))
break;
WCHAR *szEOL = wcschr (szCommand, L'\n');
if (szEOL)
*szEOL = '\0';
if (wcsicmp (szCommand, L"EXIT") == 0)
break;
if (wcsicmp (szCommand, L"GETALL") == 0) {
union {
int i;
BTH_SOCKOPT_SECURITY bs;
int iarr[2];
};
int iRes;
int ilen = sizeof(bs);
bs.iLength = 16;
bs.btAddr = 0;
iRes = getsockopt (s, SOL_RFCOMM, SO_BTH_GET_LINK, (char *)&bs, &ilen);
if (iRes)
wprintf (L"SO_BTH_GET_LINK : error %d\n", iRes);
else {
unsigned char *arr = bs.caData;
wprintf (L"SO_BTH_GET_LINK : key %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n",
arr[0], arr[1], arr[2], arr[3], arr[4], arr[5], arr[6], arr[7],
arr[8], arr[9], arr[10], arr[11], arr[12], arr[13], arr[14], arr[15]);
}
ilen = sizeof(i);
iRes = getsockopt (s, SOL_RFCOMM, SO_BTH_GET_MTU, (char *)&i, &ilen);
if (iRes)
wprintf (L"SO_BTH_GET_MTU : error %d\n", iRes);
else
wprintf (L"SO_BTH_GET_MTU : mtu %d\n", i);
ilen = sizeof(i);
iRes = getsockopt (s, SOL_RFCOMM, SO_BTH_GET_MTU_MAX, (char *)&i, &ilen);
if (iRes)
wprintf (L"SO_BTH_GET_MTU_MAX : error %d\n", iRes);
else
wprintf (L"SO_BTH_GET_MTU_MAX : max mtu %d\n", i);
ilen = sizeof(i);
iRes = getsockopt (s, SOL_RFCOMM, SO_BTH_GET_MTU_MIN, (char *)&i, &ilen);
if (iRes)
wprintf (L"SO_BTH_GET_MTU_MIN : error %d\n", iRes);
else
wprintf (L"SO_BTH_GET_MTU_MIN : min mtu %d\n", i);
ilen = sizeof(i);
iRes = getsockopt (s, SOL_RFCOMM, SO_BTH_GET_XON_LIM, (char *)&i, &ilen);
if (iRes)
wprintf (L"SO_BTH_GET_XON_LIM : error %d\n", iRes);
else
wprintf (L"SO_BTH_GET_XON_LIM : xon %d\n", i);
ilen = sizeof(i);
iRes = getsockopt (s, SOL_RFCOMM, SO_BTH_GET_XOFF_LIM, (char *)&i, &ilen);
if (iRes)
wprintf (L"SO_BTH_GET_XOFF_LIM : error %d\n", iRes);
else
wprintf (L"SO_BTH_GET_XOFF_LIM : xoff %d\n", i);
ilen = sizeof(i);
iRes = getsockopt (s, SOL_RFCOMM, SO_BTH_GET_SEND_BUFFER, (char *)&i, &ilen);
if (iRes)
wprintf (L"SO_BTH_GET_SEND_BUFFER : error %d\n", iRes);
else
wprintf (L"SO_BTH_GET_SEND_BUFFER : send buf %d\n", i);
ilen = sizeof(i);
iRes = getsockopt (s, SOL_RFCOMM, SO_BTH_GET_RECV_BUFFER, (char *)&i, &ilen);
if (iRes)
wprintf (L"SO_BTH_GET_RECV_BUFFER : error %d\n", iRes);
else
wprintf (L"SO_BTH_GET_RECV_BUFFER : recv buf %d\n", i);
ilen = sizeof(iarr);
iRes = getsockopt (s, SOL_RFCOMM, SO_BTH_GET_V24_BR, (char *)iarr, &ilen);
if (iRes)
wprintf (L"SO_BTH_GET_V24_BR : error %d\n", iRes);
else
wprintf (L"SO_BTH_GET_V24_BR : v24 %d br %d\n", iarr[0], iarr[1]);
ilen = sizeof(i);
iRes = getsockopt (s, SOL_RFCOMM, SO_BTH_GET_RLS, (char *)&i, &ilen);
if (iRes)
wprintf (L"SO_BTH_GET_RLS : error %d\n", iRes);
else
wprintf (L"SO_BTH_GET_RLS : v24 %d\n", i);
ilen = sizeof(i);
iRes = getsockopt (s, SOL_RFCOMM, SO_BTH_GET_FLOW_TYPE, (char *)&i, &ilen);
if (iRes)
wprintf (L"SO_BTH_GET_FLOW_TYPE : error %d\n", iRes);
else
wprintf (L"SO_BTH_GET_FLOW_TYPE : flow %s\n", i == 0 ? L"NOT CREDIT" : ((i == 1) ? L"CREDIT" : L"UNKNOWN"));
continue;
}
if (wcsicmp (szCommand, L"AUTH") == 0) {
int empty = 0;
wprintf (L"setsockopt returns %d\n",
setsockopt (s, SOL_RFCOMM, SO_BTH_AUTHENTICATE, (char *)&empty, sizeof(empty)));
continue;
}
if (wcsicmp (szCommand, L"ENCRYPT ON") == 0) {
int e = TRUE;
wprintf (L"setsockopt returns %d\n",
setsockopt (s, SOL_RFCOMM, SO_BTH_ENCRYPT, (char *)&e, sizeof(e)));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -