📄 sdpsearch.cpp
字号:
//
// 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
Demonstrates using the COM apis in SDP user to traverse an SDP service attribute
response buffer.
This particular example shows parsing an RFCOMM channel ID out of a query.
**/
#include <windows.h>
#include <bthapi.h>
#include <initguid.h>
#include <bt_sdp.h>
#include "..\sdpcommon\sdpcommon.h"
// Sample of what a service attribute response looks like in raw form.
UCHAR szBuf[] = {0x35, 0x43, 0x35, 0x41, 0x09, 0x00, 0x01, 0x35, 0x03, 0x19, 0x11, 0x06, 0x09, 0x00, 0x04, 0x35, 0x11,
0x35, 0x03, 0x19, 0x01, 0x00, 0x35, 0x05, 0x19, 0x00, 0x03, 0x08, 0x0A, 0x35, 0x03, 0x19, 0x00, 0x08,
0x09, 0x00, 0x06, 0x35, 0x09, 0x09, 0x65, 0x6E, 0x09, 0x00, 0x6A, 0x09, 0x01, 0x00, 0x09, 0x00, 0x09,
0x35, 0x08, 0x35, 0x06, 0x19, 0x11, 0x06, 0x09, 0x01, 0x00, 0x09, 0x01, 0x00, 0x25, 0x03, 0x46, 0x54, 0x50};
BOOL IsRfcommUuid(NodeData *pNode) {
if (pNode->type != SDP_TYPE_UUID)
return FALSE;
if (pNode->specificType == SDP_ST_UUID16)
return (pNode->u.uuid16 == RFCOMM_PROTOCOL_UUID16);
else if (pNode->specificType == SDP_ST_UUID32)
return (pNode->u.uuid32 == RFCOMM_PROTOCOL_UUID16);
else if (pNode->specificType == SDP_ST_UUID128)
return (0 == memcmp(&RFCOMM_PROTOCOL_UUID,&pNode->u.uuid128,sizeof(GUID)));
return FALSE;
}
BOOL GetChannel (NodeData *pChannelNode, ULONG *pulChannel) {
if (pChannelNode->specificType == SDP_ST_UINT8)
*pulChannel = pChannelNode->u.uint8;
else if (pChannelNode->specificType == SDP_ST_INT8)
*pulChannel = pChannelNode->u.int8;
else if (pChannelNode->specificType == SDP_ST_UINT16)
*pulChannel = pChannelNode->u.uint16;
else if (pChannelNode->specificType == SDP_ST_INT16)
*pulChannel = pChannelNode->u.int16;
else if (pChannelNode->specificType == SDP_ST_UINT32)
*pulChannel = pChannelNode->u.uint32;
else if (pChannelNode->specificType == SDP_ST_INT32)
*pulChannel = pChannelNode->u.int32;
else
return FALSE; // misformatted response.
return TRUE;
}
int
WINAPI
WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
#ifdef UNDER_NT
LPSTR lpCmdLine,
#else
LPWSTR lpCmdLine,
#endif
int nCmdShow)
{
ISdpRecord **pRecordArg;
ISdpRecord *pRecord = NULL;
ULONG ulRecords = 0;
ULONG i,j,k;
ULONG ulChannelId = 0;
BOOL fSuccess = FALSE;
CoInitializeEx(NULL,COINIT_MULTITHREADED);
// Note: in real scenarios szBuf will be results from BthNsLookupServiceNext() after
// performing a ServiweAttribute search.
if (ERROR_SUCCESS != ServiceAndAttributeSearchParse(szBuf,sizeof(szBuf),&pRecordArg,&ulRecords))
goto done;
for (i = 0; i < ulRecords; i++) {
pRecord = pRecordArg[i]; // particular record to examine in this loop
CNodeDataFreeString protocolList; // contains SDP_ATTRIB_PROTOCOL_DESCRIPTOR_LIST data, if available
if (ERROR_SUCCESS != pRecord->GetAttribute(SDP_ATTRIB_PROTOCOL_DESCRIPTOR_LIST,&protocolList) ||
(protocolList.type != SDP_TYPE_CONTAINER))
{
continue;
}
ISdpNodeContainer *pRecordContainer = protocolList.u.container;
DWORD cProtocols = 0;
NodeData protocolDescriptor; // information about a specific protocol (i.e. L2CAP, RFCOMM, ...)
pRecordContainer->GetNodeCount(&cProtocols);
for (j = 0; j < cProtocols; j++) {
pRecordContainer->GetNode(j,&protocolDescriptor);
if (protocolDescriptor.type != SDP_TYPE_CONTAINER)
continue;
ISdpNodeContainer *pProtocolContainer = protocolDescriptor.u.container;
DWORD cProtocolAtoms;
pProtocolContainer->GetNodeCount(&cProtocolAtoms);
for (k = 0; k < cProtocolAtoms; k++) {
NodeData nodeAtom; // individual data element, such as what protocol this is or RFCOMM channel id.
pProtocolContainer->GetNode(k,&nodeAtom);
if (IsRfcommUuid(&nodeAtom)) {
if (k+1 == cProtocolAtoms) {
// misformatted response. Channel ID should follow RFCOMM uuid
break;
}
NodeData channelID;
pProtocolContainer->GetNode(k+1,&channelID);
if (GetChannel(&channelID,&ulChannelId)) {
fSuccess = TRUE;
goto done;
}
break; // formatting error
}
}
}
}
done:
for (i = 0; i < ulRecords; i++)
pRecordArg[i]->Release();
CoTaskMemFree(pRecordArg);
CoUninitialize();
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -