C++ 如何获取远程设备的串行端口配置文件SDP记录

C++ 如何获取远程设备的串行端口配置文件SDP记录,c++,windows-ce,C++,Windows Ce,我正在尝试编写一个应用程序,将远程蓝牙设备与Windows Mobile/CE掌上电脑配对,并获得该设备的服务 我注意到,当您手动配对设备并通过系统设置服务时(例如,转到设置->蓝牙->添加设备),它会在以下注册表中生成一个sdprecord值 HKLM/Software/Microsoft/Bluetooth/Device/{deviceAddress}/{*Service_UUID*} 我基本上是想在我的程序中实现这一点 我遵循了以下文件: 然后将SDPrecord转换为二进制并将其写入注

我正在尝试编写一个应用程序,将远程蓝牙设备与Windows Mobile/CE掌上电脑配对,并获得该设备的服务

我注意到,当您手动配对设备并通过系统设置服务时(例如,转到设置->蓝牙->添加设备),它会在以下注册表中生成一个sdprecord值

HKLM/Software/Microsoft/Bluetooth/Device/{deviceAddress}/{*Service_UUID*}

我基本上是想在我的程序中实现这一点

我遵循了以下文件:

然后将SDPrecord转换为二进制并将其写入注册表:

RegSetValueEx(hSerialPortKey,_T("sdprecord"),0,REG_BINARY,(BYTE*)&pRecord,sizeof(pRecord)*2+1);
结果与我手动配对设备时得到的结果不同

我做错了什么?如何检索SDP记录?先谢谢你

下面是我的代码

BTHNS_RESTRICTIONBLOB RBlob;
memset(&RBlob,0,sizeof(BTHNS_RESTRICTIONBLOB));
RBlob.type = SDP_SERVICE_SEARCH_ATTRIBUTE_REQUEST;
RBlob.numRange = 1;
RBlob.uuids[0].uuidType= SDP_ST_UUID16;//SDP_ST_UUID128;
RBlob.uuids[0].u.uuid16= SerialPortServiceClassID_UUID16;
RBlob.pRange[0].minAttribute =SDP_ATTRIB_PROTOCOL_DESCRIPTOR_LIST;
RBlob.pRange[0].maxAttribute = SDP_ATTRIB_PROTOCOL_DESCRIPTOR_LIST;

SOCKADDR_BTH sa;
memset (&sa, 0, sizeof(SOCKADDR_BTH));
BTH_ADDR *pDeviceAddr = &devAddress;
*(BTH_ADDR *)(&sa.btAddr) = *pDeviceAddr;
sa.addressFamily = AF_BTH;

CSADDR_INFO csai;
memset(&csai,0,sizeof(CSADDR_INFO));
csai.RemoteAddr.lpSockaddr = (sockaddr*)&sa;
csai.RemoteAddr.iSockaddrLength = sizeof(sa);

BLOB blob;
blob.cbSize = sizeof(BTHNS_RESTRICTIONBLOB);
blob.pBlobData = (BYTE *)&RBlob;

WSAQUERYSET wsaq;
memset(&wsaq,0,sizeof(WSAQUERYSET));
wsaq.dwSize = sizeof(WSAQUERYSET);
wsaq.dwNumberOfCsAddrs = 1;
wsaq.dwNameSpace = NS_BTH;
wsaq.lpBlob = &blob;
wsaq.lpcsaBuffer = &csai;
wsaq.lpServiceClassId = &serialPortUUID;

//Initialising winsock
    WSADATA data;
    int result = WSAStartup(MAKEWORD(2, 2), &data);//initializing winsock
    if (hLib == NULL)
    {
        return S_FALSE;
    }
    result =  WSALookupServiceBegin (&wsaq,0, &hLookup);
    while (result ==ERROR_SUCCESS )
    {
        BYTE sdpBuffer[4096];
        memset(sdpBuffer,0,sizeof(sdpBuffer));
        LPWSAQUERYSET pResult = (LPWSAQUERYSET)&sdpBuffer;
        dwSize = sizeof(sdpBuffer);
        pResult->dwSize = sizeof(WSAQUERYSET);
        pResult->dwNameSpace = NS_BTH;
        pResult->lpBlob = NULL;
        pResult->lpServiceClassId = &serialPortUUID;
        result = WSALookupServiceNext(hLookup,0,&dwSize,pResult);
        if(result == -1 )
        {
            int error;
            error = WSAGetLastError();
            if (error == WSA_E_NO_MORE)
                break;
        }
        else
        {
            //Get SDP record
            if (pResult != NULL)
            {
                if (ERROR_SUCCESS != ServiceAndAttributeSearchParse(pResult->lpBlob->pBlobData,pResult->lpBlob->cbSize,&pRecordArg,&ulRecords)) { //error handling}
                ULONG recordIndex;
                for (recordIndex = 0; recordIndex < ulRecords; recordIndex++) {
                    pRecord = pRecordArg[recordIndex];}
BTHNS_限制blob RBlob;
memset(&RBlob,0,sizeof(BTHNS_RESTRICTIONBLOB));
RBlob.type=SDP\服务\搜索\属性\请求;
RBlob.numRange=1;
RBlob.uuids[0].uuidType=SDP_ST_UUID16//SDP_ST_UUID128;
RBlob.uuids[0].u.uuid16=SerialPortServiceClassID\u uuid16;
RBlob.pRange[0].minAttribute=SDP\u ATTRIB\u PROTOCOL\u DESCRIPTOR\u LIST;
RBlob.pRange[0].maxAttribute=SDP\u ATTRIB\u PROTOCOL\u DESCRIPTOR\u LIST;
SOCKADDR_BTH sa;
memset(&sa,0,sizeof(SOCKADDR_BTH));
BTH_ADDR*pDeviceAddr=&devAddress;
*(BTH_ADDR*)(&sa.btAddr)=*pDeviceAddr;
sa.addressFamily=AF_BTH;
CSADDR_信息csai;
memset(&csai,0,sizeof(CSADDR_INFO));
csai.RemoteAddr.lpSockaddr=(sockaddr*)&sa;
csai.RemoteAddr.iSockaddrLength=sizeof(sa);
一团一团;
blob.cbSize=sizeof(BTHNS_RESTRICTIONBLOB);
blob.pBlobData=(字节*)&RBlob;
WSAQUERYSET-wsaq;
memset(&wsaq,0,sizeof(WSAQUERYSET));
wsaq.dwSize=sizeof(WSAQUERYSET);
wsaq.dwNumberOfCsAddrs=1;
wsaq.dwNameSpace=NS_BTH;
wsaq.lpBlob=&blob;
wsaq.lpcsaBuffer=&csai;
wsaq.lpServiceClassId=&serialPortUUID;
//初始化winsock
WSADATA数据;
int result=WSAStartup(MAKEWORD(2,2)和data)//初始化winsock
if(hLib==NULL)
{
返回S_FALSE;
}
结果=WSALookupServiceBegin(&wsaq,0,&hLookup);
while(结果==错误\成功)
{
字节sdpBuffer[4096];
memset(sdpBuffer,0,sizeof(sdpBuffer));
LPWSAQUERYSET PRESLT=(LPWSAQUERYSET)和sdpBuffer;
dwSize=sizeof(sdpBuffer);
pResult->dwSize=sizeof(WSAQUERYSET);
pResult->dwNameSpace=NS\u BTH;
pResult->lpBlob=NULL;
预设->lpServiceClassId=&serialPortUUID;
结果=WSALookupServiceNext(hLookup,0,&dwSize,pResult);
如果(结果==-1)
{
整数误差;
错误=WSAGetLastError();
如果(错误==WSA\u E\u无更多)
打破
}
其他的
{
//获取SDP记录
如果(预设值!=NULL)
{
if(ERROR_SUCCESS!=ServiceAndAttributeSearchParse(pResult->lpBlob->pBlobData,pResult->lpBlob->cbSize,&pRecordArg,&ulRecords)){//ERROR handling}
乌龙指数;
对于(recordIndex=0;recordIndex
我想代码应该没问题。这是我的代码

int FindRFCOMMChannel (unsigned char *pStream, int cStream, unsigned char *pChann) 
{ 
    ISdpRecord **pRecordArg; 
    int cRecordArg = 0; 

    *pChann = 0; 

    int hr = ServiceAndAttributeSearch(pStream, cStream, &pRecordArg, (ULONG *)&cRecordArg); 

    if (hr != ERROR_SUCCESS)
    {
        BT_ERROR( CBTRFCOMMMgr, PerformServiceSearch, "ServiceAndAttributeSearch ERROR %d\n");    
        return hr; 
    }

    for (int i = 0; (! *pChann) && (i < cRecordArg); i++) 
    { 
        ISdpRecord *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; 
        int cProtocols = 0; 
        NodeData protocolDescriptor; // information about a specific protocol (i.e. L2CAP, RFCOMM, ...) 

        pRecordContainer->GetNodeCount((DWORD *)&cProtocols); 
        for (int j = 0; (! *pChann) && (j < cProtocols); j++) { 
            pRecordContainer->GetNode(j,&protocolDescriptor); 

            if (protocolDescriptor.type != SDP_TYPE_CONTAINER) 
                continue; 

            ISdpNodeContainer *pProtocolContainer = protocolDescriptor.u.container; 
            int cProtocolAtoms = 0; 
            pProtocolContainer->GetNodeCount((DWORD *)&cProtocolAtoms); 

            for (int k = 0; (! *pChann) && (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); 

                    *pChann = (unsigned char)GetChannel(&channelID); 
                    break; // formatting error 
                } 
            } 
        } 
    } 

    for (i = 0; i < cRecordArg; i++)  
        pRecordArg[i]->Release(); 

    CoTaskMemFree(pRecordArg); 

    return (*pChann != 0) ? 1:0; 
} 

int 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; 
} 

int GetChannel (NodeData *pChannelNode) { 
if (pChannelNode->specificType == SDP_ST_UINT8) 
    return pChannelNode->u.uint8; 
else if (pChannelNode->specificType == SDP_ST_INT8) 
    return pChannelNode->u.int8; 
else if (pChannelNode->specificType == SDP_ST_UINT16) 
    return pChannelNode->u.uint16; 
else if (pChannelNode->specificType == SDP_ST_INT16) 
    return pChannelNode->u.int16; 
else if (pChannelNode->specificType == SDP_ST_UINT32) 
    return pChannelNode->u.uint32; 
else if (pChannelNode->specificType == SDP_ST_INT32) 
    return pChannelNode->u.int32; 

return 0; 
} 
int FindRFCOMMChannel(无符号字符*pStream,int cStream,无符号字符*pChann)
{ 
ISDProcord**pRecordArg;
int-cRecordArg=0;
*pChann=0;
int hr=服务和属性搜索(pStream、cStream和pRecordArg、(ULONG*)和cRecordArg);
如果(hr!=错误\u成功)
{
BT_错误(CBTRFCommgr,PerformServiceSearch,“服务和属性搜索错误%d\n”);
返回人力资源;
}
对于(int i=0;(!*pChann)和&(iGetAttribute(SDP_ATTRIB_PROTOCOL_DESCRIPTOR_LIST,&protocolList)|
(protocolList.type!=SDP_类型_容器))
继续;
ISdpNodeContainer*pRecordContainer=protocolList.u.container;
int cProtocols=0;
NodeData protocolDescriptor;//有关特定协议的信息(即L2CAP、RFCOMM等)
pRecordContainer->GetNodeCount((DWORD*)和cProtocols);
对于(intj=0;(!*pChann)&&(jGetNode(j和protocolDescriptor);
if(protocolDescriptor.type!=SDP\u type\u容器)
继续;
ISdpNodeContainer*pProtocolContainer=protocolDescriptor.u.container;
int cProtocolAtoms=0;
pProtocolContainer->GetNodeCount((DWORD*)和cProtocolAtoms);
对于(intk=0;(!*pChann)&&(kGetNode(k和nodeAtom);
if(IsRfcommUuid(&nodeAtom)){
如果(k+1==cProtocolAtoms){
//响应格式错误。通道ID应跟随RFCOMM uuid
打破
} 
沟形节足动物;
pProtocolContainer->GetNode(k+1和channelID);
*pChann=(无符号字符)GetChannel(&channelID);
break;//格式错误
} 
} 
} 
} 
对于(i=0;iRelease();
CoTaskMemFree(pRecordArg);
返回(*pChann!=0)?1:0;
} 
int IsRfcommUuid(NodeData*pNode){
如果(pNode->type!=SDP\U type\U UUID)
返回FALSE;
如果(pNode->specificType==SDP\u ST\u UUID16)
返回(pNode->u.uuid16==RFCOMM_协议_uuid16);
else if(pNode->specificType==SDP\u ST\u UUID32)
返回(pNode->u.uuid32==R