📄 mybtutil.cpp
字号:
//======================================================================
// MyBtUtil - Handy Bluetooth routines
//
// Written for the book Programming Windows CE
// Copyright (C) 2007 Douglas Boling
//======================================================================
#include <windows.h>
#include <winsock2.h>
#include <ws2bth.h>
#include <bthapi.h>
#include "MyBtUtil.h"
// Returns number of elements
#define dim(x) (sizeof(x) / sizeof(x[0]))
#define MYBUFFSIZE 16384
//----------------------------------------------------------------------
// FindDevices - Find devices in range.
//
int FindDevices (PMYBTDEVICE pbtDev, int *pnDevs) {
DWORD dwFlags, dwLen;
HANDLE hLookup;
int i, rc, nMax = *pnDevs;
*pnDevs = 0;
// Create inquiry blob to limit time of search
BTHNS_INQUIRYBLOB inqblob;
memset (&inqblob, 0, sizeof (inqblob));
inqblob.LAP = BT_ADDR_GIAC; // Default GIAC
inqblob.length = 4; // 4 * 1.28 = 5 seconds
inqblob.num_responses = nMax;
// Create blob to point to inquiry blob
BLOB blob;
blob.cbSize = sizeof (BTHNS_INQUIRYBLOB);
blob.pBlobData = (PBYTE)&inqblob;
// Init query
WSAQUERYSET QuerySet;
memset(&QuerySet,0,sizeof(WSAQUERYSET));
QuerySet.dwSize = sizeof(WSAQUERYSET);
QuerySet.dwNameSpace = NS_BTH;
QuerySet.lpBlob = &blob;
// Start query for devices
rc = WSALookupServiceBegin (&QuerySet, LUP_CONTAINERS, &hLookup);
if (rc) return rc;
PBYTE pOut = (PBYTE)LocalAlloc (LPTR, MYBUFFSIZE);
if (!pOut) return -1;
WSAQUERYSET *pQueryResult = (WSAQUERYSET *)pOut;
for (i = 0; i < nMax; i++) {
dwLen = MYBUFFSIZE;
dwFlags = LUP_RETURN_NAME | LUP_RETURN_ADDR;
rc = WSALookupServiceNext (hLookup, dwFlags, &dwLen, pQueryResult);
if (rc == SOCKET_ERROR) {
rc = GetLastError();
break;
}
// Copy device name
if (pQueryResult->lpszServiceInstanceName)
StringCchCopy (pbtDev[i].szName, dim (pbtDev[i].szName),
pQueryResult->lpszServiceInstanceName);
else
pbtDev[i].szName[0] = TEXT('\0');
// Copy bluetooth device address
SOCKADDR_BTH *pbta;
pbta = (SOCKADDR_BTH *)pQueryResult->lpcsaBuffer->RemoteAddr.lpSockaddr;
pbtDev[i].btaddr = pbta->btAddr;
}
if (rc == WSA_E_NO_MORE) rc = 0;
*pnDevs = i;
WSALookupServiceEnd (hLookup);
LocalFree (pOut);
return rc;
}
//----------------------------------------------------------------------
// PublishRecord - Helper routine that actually does the registering
// of the SDP record.
//
int PublishRecord (PBYTE pSDPRec, int nRecSize, ULONG *pRecord) {
BTHNS_SETBLOB *pSetBlob;
ULONG ulSdpVersion = BTH_SDP_VERSION;
int rc;
// Zero out the record handle that will be returned by the call
*pRecord = 0;
// Allocate and init the SetBlob
pSetBlob = (BTHNS_SETBLOB *)LocalAlloc (LPTR,
sizeof (BTHNS_SETBLOB) + nRecSize-1);
if (!pSetBlob) return -1;
pSetBlob->pRecordHandle = pRecord;
pSetBlob->pSdpVersion = &ulSdpVersion;
pSetBlob->fSecurity = 0;
pSetBlob->fOptions = 0;
pSetBlob->ulRecordLength = nRecSize;
memcpy (pSetBlob->pRecord, pSDPRec, nRecSize);
// Init the container blob
BLOB blob;
blob.cbSize = sizeof(BTHNS_SETBLOB) + nRecSize - 1;
blob.pBlobData = (PBYTE) pSetBlob;
// Init the WSAQuerySet struct
WSAQUERYSET Service;
memset (&Service, 0, sizeof(Service));
Service.dwSize = sizeof(Service);
Service.lpBlob = &blob;
Service.dwNameSpace = NS_BTH;
// Publish the service
rc = WSASetService(&Service, RNRSERVICE_REGISTER, 0);
if (rc == SOCKET_ERROR)
rc = GetLastError();
// Clean up
LocalFree ((PBYTE)pSetBlob);
return rc;
}
//----------------------------------------------------------------------
// UnregisterBtService - Remove service from SDP database
//
int UnregisterBtService (HWND hWnd, ULONG hRecord) {
ULONG ulSdpVersion = BTH_SDP_VERSION;
int rc;
BTHNS_SETBLOB SetBlob;
memset (&SetBlob, 0, sizeof (SetBlob));
SetBlob.pRecordHandle = &hRecord;
SetBlob.pSdpVersion = &ulSdpVersion;
// Init the container blob
BLOB blob;
blob.cbSize = sizeof(BTHNS_SETBLOB);
blob.pBlobData = (PBYTE) &SetBlob;
// Init the WSAQuerySet struct
WSAQUERYSET Service;
memset (&Service, 0, sizeof(Service));
Service.dwSize = sizeof(Service);
Service.lpBlob = &blob;
Service.dwNameSpace = NS_BTH;
// Unpublish the service
rc = WSASetService(&Service, RNRSERVICE_DELETE, 0);
if (rc == SOCKET_ERROR)
rc = GetLastError();
return rc;
}
//----------------------------------------------------------------------
// RegisterBtService - Registers a service with a guid and RFChannel
//
int RegisterBtService (GUID *pguid, byte bChannel, ULONG *pRecord) {
// SDP dummy record
// GUID goes at offset 8
// Channel goes in last byte of record.
static BYTE bSDPRecord[] = {
0x35, 0x27, 0x09, 0x00, 0x01, 0x35, 0x11, 0x1C, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x09, 0x00, 0x04, 0x35, 0x0C, 0x35, 0x03, 0x19, 0x01,
0x00, 0x35, 0x05, 0x19, 0x00, 0x03, 0x08, 0x00};
// Update the SDP record
// Translate guid into net byte order for SDP record
GUID *p = (GUID *)&bSDPRecord[8];
p->Data1 = htonl (pguid->Data1);
p->Data2 = htons (pguid->Data2);
p->Data3 = htons (pguid->Data3);
memcpy (p->Data4, pguid->Data4, sizeof (pguid->Data4));
// Copy channel value into record
bSDPRecord[sizeof (bSDPRecord)-1] = bChannel;
return PublishRecord (bSDPRecord, sizeof (bSDPRecord), pRecord);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -