Как получить запись SDP профиля последовательного порта для удаленного устройства

Я пытаюсь написать приложение, которое связывает удаленное устройство Bluetooth с карманным компьютером с Windows Mobile / CE и получает обслуживание устройства.

Я заметил, что когда вы вручную подключаете устройство и настраиваете службу через систему (например, зайдите в настройки-> Bluetooth-> добавить устройство), оно генерирует sdprecord значение в следующем реестре

HKLM / Software / Microsoft / Bluetooth / Device /{} DeviceAddress/ * {Service_UUID *}.

Я в основном пытаюсь реализовать это в моей программе.

Я следовал следующим документам:
http://msdn.microsoft.com/en-us/library/ms883458.aspx
http://msdn.microsoft.com/en-us/library/ms883398.aspx

а затем преобразовать 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];}

1

Решение

Я думаю, что код должен быть в порядке. Вот мой код

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

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]