📄 btcp.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 <windev.h>
#include <stdio.h>
#include <winsock2.h>
#include <bt_api.h>
#include <bthapi.h>
#include <initguid.h>
#include <bt_sdp.h>
#include <service.h>
#include "resource.h"
#include <svsutil.hxx>
#include <bt_buffer.h>
#include <bt_ddi.h>
#define APPNAME L"BluetoothCP"
HINSTANCE ghInst;
HWND ghWnd;
int gExit = FALSE;
unsigned int gCod, gPage, gScan, gAuth;
int gStopped;
#if defined (DO_DEVICE_CONTROL)
#if defined (SDK_BUILD)
#include <aygshell.h>
typedef void (*tSHInputDialog)(HWND hwnd, UINT uMsg, WPARAM wParam);
tSHInputDialog gpSHInputDialog = NULL;
#endif
HANDLE ghEvent;
HWND ghWndHidden;
#endif
#if defined (DO_DEVICE_CONTROL)
struct pin_request {
BT_ADDR bt;
HWND hWnd;
};
DWORD WINAPI GetName (LPVOID pArg) {
pin_request *p = (pin_request *)pArg;
BT_ADDR bt = p->bt;
HWND hWnd = p->hWnd;
WCHAR szName[MAX_PATH];
unsigned int c = 0;
if (ERROR_SUCCESS == BthRemoteNameQuery (&bt, MAX_PATH, &c, szName))
SetWindowText (GetDlgItem (hWnd, IDC_CONNECT_STRING), szName);
return 0;
}
static BOOL CALLBACK DlgProc2 (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
#if defined (SDK_BUILD)
if (gpSHInputDialog)
gpSHInputDialog (hWnd, uMsg, wParam);
#endif
switch (uMsg) {
case WM_INITDIALOG:
{
SetForegroundWindow (hWnd);
SetWindowText (GetDlgItem (hWnd, IDC_PIN), L"");
SetFocus (GetDlgItem (hWnd, IDC_PIN));
SetWindowLong (hWnd, DWL_USER, lParam);
pin_request *p = (pin_request *)lParam;
p->hWnd = hWnd;
WCHAR szString[256];
wsprintf (szString, L"%04x%08x", GET_NAP(p->bt), GET_SAP(p->bt));
SetWindowText (GetDlgItem (hWnd, IDC_CONNECT_STRING), szString);
// CloseHandle (CreateThread (NULL, 0, GetName, p, 0, NULL));
}
return 0;
case WM_COMMAND:
{
int wID = LOWORD(wParam);
switch (wID)
{
case IDOK:
{
WCHAR szPin[64];
WCHAR *pszPIN = szPin;
GetWindowText (GetDlgItem (hWnd, IDC_PIN), szPin, 64);
pin_request *p = (pin_request *)GetWindowLong (hWnd, DWL_USER);
unsigned char pin[16];
int cPin = 0;
while ((*pszPIN) && (cPin < 16))
pin[cPin++] = (unsigned char)*(pszPIN++);
if (cPin)
BthSetPIN (&p->bt, cPin, pin);
EndDialog (hWnd, 0);
}
return 0;
case IDCANCEL:
{
pin_request *p = (pin_request *)GetWindowLong (hWnd, DWL_USER);
BthRefusePINRequest (&p->bt);
EndDialog (hWnd, 0);
}
return 0;
}
}
break;
}
return 0;
}
#endif
void SetUnloadedState (void) {
SetWindowText (GetDlgItem (ghWnd, IDC_DESCR), L"Card Not Present");
SetWindowText (GetDlgItem (ghWnd, IDC_PAGE), L"");
SetWindowText (GetDlgItem (ghWnd, IDC_COD), L"");
SendMessage (GetDlgItem (ghWnd, IDC_DISCOVERABLE), BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
SendMessage (GetDlgItem (ghWnd, IDC_CONNECTABLE), BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
SendMessage (GetDlgItem (ghWnd, IDC_SECURE_ONLY), BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
SendMessage (GetDlgItem (ghWnd, IDC_DESCR), LB_RESETCONTENT, 0, 0);
SetWindowText (GetDlgItem (ghWnd, IDC_STARTSTOP), L"START");
gCod = 0;
gScan = 0;
gPage = 0;
gAuth = 0;
gStopped = TRUE;
}
#if defined (DO_DEVICE_CONTROL)
void FillFromRegistry (void) {
HKEY hk;
if (ERROR_SUCCESS == RegOpenKeyEx (HKEY_LOCAL_MACHINE, L"software\\microsoft\\bluetooth\\btcp", 0, KEY_WRITE, &hk)) {
DWORD dwType = 0;
DWORD dwSize = sizeof(gAuth);
if (ERROR_SUCCESS == RegQueryValueEx (hk, L"authentication", NULL, &dwType, (LPBYTE)&gAuth, &dwSize))
BthWriteAuthenticationEnable (gAuth);
dwSize = sizeof(gScan);
if (ERROR_SUCCESS == RegQueryValueEx (hk, L"scan", NULL, &dwType, (LPBYTE)&gScan, &dwSize))
BthWriteScanEnableMask (gScan);
dwSize = sizeof(gPage);
if (ERROR_SUCCESS == RegQueryValueEx (hk, L"page", NULL, &dwType, (LPBYTE)&gPage, &dwSize))
BthWritePageTimeout (gPage);
RegCloseKey (hk);
}
}
#endif
DWORD WINAPI FillParameters (LPVOID pArg) {
WCHAR szLine[MAX_PATH];
SetUnloadedState ();
SetWindowText (GetDlgItem (ghWnd, IDC_DESCR), L"Loading...");
BT_ADDR bt;
if (BthReadLocalAddr (&bt) != ERROR_SUCCESS) {
SetUnloadedState ();
return 0;
}
wsprintf (szLine, L"Address: %04x%08x", GET_NAP(bt), GET_SAP(bt));
SendMessage (GetDlgItem (ghWnd, IDC_DESCR), LB_ADDSTRING, 0, (LPARAM)szLine);
unsigned char mask;
if (gExit)
return 0;
if (BthReadScanEnableMask (&mask) != ERROR_SUCCESS) {
SetUnloadedState ();
return 0;
}
gScan = mask;
wsprintf (szLine, L"Inquiry Scan: %s", (mask & 1) ? L"enabled" : L"disabled");
SendMessage (GetDlgItem (ghWnd, IDC_DESCR), LB_ADDSTRING, 0, (LPARAM)szLine);
wsprintf (szLine, L"Page Scan: %s", (mask & 2) ? L"enabled" : L"disabled");
SendMessage (GetDlgItem (ghWnd, IDC_DESCR), LB_ADDSTRING, 0, (LPARAM)szLine);
SendMessage (GetDlgItem (ghWnd, IDC_DISCOVERABLE), BM_SETCHECK, (WPARAM) ((mask & 1) ? BST_CHECKED : BST_UNCHECKED), 0);
SendMessage (GetDlgItem (ghWnd, IDC_CONNECTABLE), BM_SETCHECK, (WPARAM) ((mask & 2) ? BST_CHECKED : BST_UNCHECKED), 0);
unsigned char authn = 0;
if (BthReadAuthenticationEnable (&authn) != ERROR_SUCCESS) {
SetUnloadedState ();
return 0;
}
gAuth = authn;
SendMessage (GetDlgItem (ghWnd, IDC_SECURE_ONLY), BM_SETCHECK, (WPARAM) (authn ? BST_CHECKED : BST_UNCHECKED), 0);
unsigned short page;
if (gExit)
return 0;
if (BthReadPageTimeout (&page) != ERROR_SUCCESS) {
SetUnloadedState ();
return 0;
}
gPage = page;
wsprintf (szLine, L"%d", page);
SetWindowText (GetDlgItem (ghWnd, IDC_PAGE), szLine);
unsigned int cod;
if (gExit)
return 0;
if (BthReadCOD (&cod) != ERROR_SUCCESS) {
SetUnloadedState ();
return 0;
}
gCod = cod;
wsprintf (szLine, L"0x%06x", cod);
SetWindowText (GetDlgItem (ghWnd, IDC_COD), szLine);
#if defined (DO_DEVICE_CONTROL)
HKEY hk = NULL;
DWORD dwDisp = 0;
if (ERROR_SUCCESS == RegCreateKeyEx (HKEY_LOCAL_MACHINE, L"software\\microsoft\\bluetooth\\btcp", 0, NULL, 0, KEY_WRITE, NULL, &hk, &dwDisp)) {
RegSetValueEx (hk, L"authentication", NULL, REG_DWORD, (LPBYTE)&gAuth, sizeof(gAuth));
RegSetValueEx (hk, L"scan", NULL, REG_DWORD, (LPBYTE)&gScan, sizeof(gScan));
RegSetValueEx (hk, L"page", NULL, REG_DWORD, (LPBYTE)&gPage, sizeof(gPage));
RegCloseKey (hk);
}
#endif
if (gExit)
return 0;
unsigned short hci_subversion, lmp_subversion, manufacturer;
unsigned char hci_version, lmp_version, lmp_features[8];
if (BthReadLocalVersion (&hci_version, &hci_subversion, &lmp_version, &lmp_subversion, &manufacturer, lmp_features) != ERROR_SUCCESS) {
SetUnloadedState ();
return 0;
}
unsigned char *pf = lmp_features;
wsprintf (szLine, L"HCI Version : %d", hci_version);
SendMessage (GetDlgItem (ghWnd, IDC_DESCR), LB_ADDSTRING, 0, (LPARAM)szLine);
wsprintf (szLine, L"HCI Subversion : %d", hci_subversion);
SendMessage (GetDlgItem (ghWnd, IDC_DESCR), LB_ADDSTRING, 0, (LPARAM)szLine);
wsprintf (szLine, L"LMP Version : %d", lmp_version);
SendMessage (GetDlgItem (ghWnd, IDC_DESCR), LB_ADDSTRING, 0, (LPARAM)szLine);
wsprintf (szLine, L"LMP Subversion : %d", lmp_subversion);
SendMessage (GetDlgItem (ghWnd, IDC_DESCR), LB_ADDSTRING, 0, (LPARAM)szLine);
switch (manufacturer) {
case 0:
wsprintf (szLine, L"OEM: Ericsson");
break;
case 1:
wsprintf (szLine, L"OEM: Nokia");
break;
case 2:
wsprintf (szLine, L"OEM: Intel");
break;
case 3:
wsprintf (szLine, L"OEM: IBM");
break;
case 4:
wsprintf (szLine, L"OEM: Toshiba");
break;
case 5:
wsprintf (szLine, L"OEM: 3COM");
break;
case 6:
wsprintf (szLine, L"OEM: Microsoft");
break;
case 7:
wsprintf (szLine, L"OEM: Lucent");
break;
case 8:
wsprintf (szLine, L"OEM: Motorola");
break;
case 9:
wsprintf (szLine, L"OEM: Infineon");
break;
case 10:
wsprintf (szLine, L"OEM: CSR");
break;
case 11:
wsprintf (szLine, L"OEM: Silicon Wave");
break;
case 12:
wsprintf (szLine, L"OEM: Digianswer");
break;
default:
wsprintf (szLine, L"OEM: Unknown, code %d", manufacturer);
break;
}
SendMessage (GetDlgItem (ghWnd, IDC_DESCR), LB_ADDSTRING, 0, (LPARAM)szLine);
wsprintf (szLine, L"Supported LMP features:");
SendMessage (GetDlgItem (ghWnd, IDC_DESCR), LB_ADDSTRING, 0, (LPARAM)szLine);
if ((*pf) & 0x01) {
wsprintf (szLine, L" 3-slot packets");
SendMessage (GetDlgItem (ghWnd, IDC_DESCR), LB_ADDSTRING, 0, (LPARAM)szLine);
}
if ((*pf) & 0x02) {
wsprintf (szLine, L" 5-slot packets");
SendMessage (GetDlgItem (ghWnd, IDC_DESCR), LB_ADDSTRING, 0, (LPARAM)szLine);
}
if ((*pf) & 0x04) {
wsprintf (szLine, L" encryption");
SendMessage (GetDlgItem (ghWnd, IDC_DESCR), LB_ADDSTRING, 0, (LPARAM)szLine);
}
if ((*pf) & 0x08) {
wsprintf (szLine, L" slot offset");
SendMessage (GetDlgItem (ghWnd, IDC_DESCR), LB_ADDSTRING, 0, (LPARAM)szLine);
}
if ((*pf) & 0x10) {
wsprintf (szLine, L" timing accuracy");
SendMessage (GetDlgItem (ghWnd, IDC_DESCR), LB_ADDSTRING, 0, (LPARAM)szLine);
}
if ((*pf) & 0x20) {
wsprintf (szLine, L" switch");
SendMessage (GetDlgItem (ghWnd, IDC_DESCR), LB_ADDSTRING, 0, (LPARAM)szLine);
}
if ((*pf) & 0x40) {
wsprintf (szLine, L" hold");
SendMessage (GetDlgItem (ghWnd, IDC_DESCR), LB_ADDSTRING, 0, (LPARAM)szLine);
}
if ((*pf) & 0x80) {
wsprintf (szLine, L" sniff");
SendMessage (GetDlgItem (ghWnd, IDC_DESCR), LB_ADDSTRING, 0, (LPARAM)szLine);
}
++pf;
if ((*pf) & 0x01) {
wsprintf (szLine, L" park");
SendMessage (GetDlgItem (ghWnd, IDC_DESCR), LB_ADDSTRING, 0, (LPARAM)szLine);
}
if ((*pf) & 0x02) {
wsprintf (szLine, L" RSSI");
SendMessage (GetDlgItem (ghWnd, IDC_DESCR), LB_ADDSTRING, 0, (LPARAM)szLine);
}
if ((*pf) & 0x04) {
wsprintf (szLine, L" channel-quality driven rate");
SendMessage (GetDlgItem (ghWnd, IDC_DESCR), LB_ADDSTRING, 0, (LPARAM)szLine);
}
if ((*pf) & 0x08) {
wsprintf (szLine, L" SCO");
SendMessage (GetDlgItem (ghWnd, IDC_DESCR), LB_ADDSTRING, 0, (LPARAM)szLine);
}
if ((*pf) & 0x10) {
wsprintf (szLine, L" HV2");
SendMessage (GetDlgItem (ghWnd, IDC_DESCR), LB_ADDSTRING, 0, (LPARAM)szLine);
}
if ((*pf) & 0x20) {
wsprintf (szLine, L" HV3");
SendMessage (GetDlgItem (ghWnd, IDC_DESCR), LB_ADDSTRING, 0, (LPARAM)szLine);
}
if ((*pf) & 0x40) {
wsprintf (szLine, L" u-law log");
SendMessage (GetDlgItem (ghWnd, IDC_DESCR), LB_ADDSTRING, 0, (LPARAM)szLine);
}
if ((*pf) & 0x80) {
wsprintf (szLine, L" a-law log");
SendMessage (GetDlgItem (ghWnd, IDC_DESCR), LB_ADDSTRING, 0, (LPARAM)szLine);
}
++pf;
if ((*pf) & 0x01) {
wsprintf (szLine, L" CVSD");
SendMessage (GetDlgItem (ghWnd, IDC_DESCR), LB_ADDSTRING, 0, (LPARAM)szLine);
}
if ((*pf) & 0x02) {
wsprintf (szLine, L" paging scheme");
SendMessage (GetDlgItem (ghWnd, IDC_DESCR), LB_ADDSTRING, 0, (LPARAM)szLine);
}
if ((*pf) & 0x04) {
wsprintf (szLine, L" power control");
SendMessage (GetDlgItem (ghWnd, IDC_DESCR), LB_ADDSTRING, 0, (LPARAM)szLine);
}
if ((*pf) & 0x08) {
wsprintf (szLine, L" transparent SCO data");
SendMessage (GetDlgItem (ghWnd, IDC_DESCR), LB_ADDSTRING, 0, (LPARAM)szLine);
}
if ((*pf) & 0x10) {
wsprintf (szLine, L" flow lag bit 0");
SendMessage (GetDlgItem (ghWnd, IDC_DESCR), LB_ADDSTRING, 0, (LPARAM)szLine);
}
if ((*pf) & 0x20) {
wsprintf (szLine, L" flow lag bit 0");
SendMessage (GetDlgItem (ghWnd, IDC_DESCR), LB_ADDSTRING, 0, (LPARAM)szLine);
}
if ((*pf) & 0x40) {
wsprintf (szLine, L" flow lag bit 0");
SendMessage (GetDlgItem (ghWnd, IDC_DESCR), LB_ADDSTRING, 0, (LPARAM)szLine);
}
SetWindowText (GetDlgItem (ghWnd, IDC_STARTSTOP), L"STOP");
gStopped = FALSE;
return 0;
}
void StartStop (void) {
DWORD ictl = 0;
if (gStopped)
ictl = IOCTL_SERVICE_START;
else
ictl = IOCTL_SERVICE_STOP;
HANDLE hDev = CreateFile (L"BTD0:", GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, 0, NULL);
if (hDev == INVALID_HANDLE_VALUE)
return;
WCHAR *argPtr = L"card";
DeviceIoControl (hDev, ictl, argPtr, sizeof(WCHAR) * (wcslen (argPtr) + 1), NULL, NULL, NULL, NULL);
CloseHandle (hDev);
Sleep (3000);
#if defined (DO_DEVICE_CONTROL)
if (ictl == IOCTL_SERVICE_START)
FillFromRegistry ();
#endif
FillParameters (NULL);
}
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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -