function callback(uAttribId: LongWord; pValueStream: PByte; cbStreamSize: LongWord; Param: Pointer): LongBool;
stdcall;
var
element: SDP_ELEMENT_DATA;
begin
TMemo(Param).Lines.Add(Format('
Callback uAttribId: %d', [uAttribId]));
TMemo(Param).Lines.Add(Format('
Callback pValueStream: %d', [pValueStream]));
TMemo(Param).Lines.Add(Format('
Callback cbStreamSize: %d', [cbStreamSize]));
if BluetoothSdpGetElementData(pValueStream, cbStreamSize, @element) = ERROR_SUCCESS
then begin
Result := TRUE;
end else begin
TMemo(Param).Lines.Add(Format('
BluetoothSdpGetElementData failed with error code %d: %s',
[WSAGetLastError, SysErrorMessage(WSAGetLastError)]));
Result := FALSE;
end
end;
var
m_data: WSADATA;
s: TSocket;
protocolInfo: WSAPROTOCOL_INFO;
protocolInfoSize, i, i2: Integer;
querySet, querySet2: WSAQUERYSET;
pResults: lpWSAQUERYSET;
hLookup, hLookup2: THandle;
buffer:
Array[0..999]
of Byte;
buffer1:
Array[0..1999]
of Byte;
bufferLength, flags, addressSize, bufferLength1: LongWord;
pCSAddr: pCSADDR_INFO;
pDeviceInfo: pBTH_DEVICE_INFO;
addressAsString:
Array[0..1999]
of Char;
pBlob: JwaWinsock2.pBLOB;
protocol: TGUID;
// Load the winsock2 library
if WSAStartup($0202, m_data) = 0
then begin
try
// Create a blutooth socket
s := socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
if s = INVALID_SOCKET
then begin
Memo2.Lines.Add(Format('
Failed to get bluetooth socket with error code %d: %s',
[WSAGetLastError, SysErrorMessage(WSAGetLastError)]));
Exit;
end;
// Get the bluetooth device info using getsockopt
protocolInfoSize := SizeOf(protocolInfo);
if getsockopt(s, SOL_SOCKET, SO_PROTOCOL_INFO, @protocolInfo, protocolInfoSize) <> 0
then begin
Memo2.Lines.Add(Format('
getsockopt failed with error code %d: %s',
[WSAGetLastError, SysErrorMessage(WSAGetLastError)]));
Exit;
end;
// Query set criteria
ZeroMemory(@querySet, SizeOf(querySet));
querySet.dwSize := SizeOf(querySet);
querySet.dwNameSpace := NS_BTH;
// Set the flags for query
flags := LUP_RETURN_NAME
or LUP_CONTAINERS
or LUP_RETURN_ADDR
or LUP_FLUSHCACHE
or
LUP_RETURN_TYPE
or LUP_RETURN_BLOB
or LUP_RES_SERVICE;
// Start a device in range query...
if WSALookupServiceBegin(@querySet, flags, hLookup) = 0
then begin
i := 0;
while true
do begin
bufferLength := SizeOf(buffer);
pResults := @buffer;
if WSALookupServiceNext(hLookup, flags, bufferLength, @pResults) = 0
then begin
// Get the device info, name, address etc
Memo2.Lines.Add(Format('
The service instance name is %s', [pResults.lpszServiceInstanceName]));
pCSAddr := pCSADDR_INFO(pResults.lpcsaBuffer);
pDeviceInfo := pBTH_DEVICE_INFO(pResults.lpBlob);
ZeroMemory(@querySet2, SizeOf(querySet2));
querySet2.dwSize := SizeOf(querySet2);
protocol := L2CAP_PROTOCOL_UUID;
querySet2.lpServiceClassId := @protocol;
querySet2.dwNameSpace := NS_BTH;
// Print the local bluetooth device address...
addressSize := SizeOf(addressAsString);
if WSAAddressToString(pCSAddr.LocalAddr.lpSockaddr, pCSAddr.LocalAddr.iSockaddrLength,
@protocolInfo, @addressAsString, addressSize) = 0
then begin
Memo2.Lines.Add(Format('
The local address: %s', [addressAsString]));
end else
Memo2.Lines.Add(Format('
WSAAddressToString for local address failed with error code %s', [WSAGetLastError]));
// Print the remote bluetooth device address...
addressSize := SizeOf(addressAsString);
if WSAAddressToString(pCSAddr.RemoteAddr.lpSockaddr, pCSAddr.RemoteAddr.iSockaddrLength,
@protocolInfo, @addressAsString, addressSize) = 0
then begin
Memo2.Lines.Add(Format('
The remote device address: %s', [addressAsString]));
end else
Memo2.Lines.Add(Format('
WSAAddressToString for remote address failed with error code %d: %s',
[WSAGetLastError, SysErrorMessage(WSAGetLastError)]));
// Prepare for service query set
querySet2.lpszContext := @addressAsString;
flags := LUP_FLUSHCACHE
or LUP_RETURN_NAME
or LUP_RETURN_TYPE
or
LUP_RETURN_ADDR
or LUP_RETURN_BLOB
or LUP_RETURN_COMMENT;
// Start service query
if WSALookupServiceBegin(@querySet2, flags, hLookup2) = 0
then begin
try
while true
do begin
bufferLength1 := SizeOf(buffer1);
pResults := lpWSAQUERYSET(@buffer1);
// Next service query
if WSALookupServiceNext(hLookup2, flags, bufferLength1, pResults) = 0
then begin
// Populate the service info
Memo2.Lines.Add(Format('
WSALookupServiceNext - service instance name: %s', [pResults.lpszServiceInstanceName]));
Memo2.Lines.Add(Format('
WSALookupServiceNext - comment (if any): %s', [pResults.lpszComment]));
pCSAddr := pCSADDR_INFO(@pResults.lpcsaBuffer);
// Extract the sdp info
if Assigned(pResults.lpBlob)
then begin
pBlob := pResults.lpBlob;
if BluetoothSdpEnumAttributes(pBlob.pBlobData, pBlob.cbSize, callback, Pointer(Memo2))
then begin
Inc(i);
Memo2.Lines.Add(Format('
BluetoothSdpEnumAttributes #%d is OK!', [i]));
end else
Memo2.Lines.Add(Format('
BluetoothSdpEnumAttributes failed with error code %d: %s',
[WSAGetLastError, SysErrorMessage(WSAGetLastError)]));
end;
end else begin
if WSAGetLastError <> WSA_E_NO_MORE
then
Memo2.Lines.Add(Format('
WSALookupServiceNext failed with error code %d: %s',
[WSAGetLastError, SysErrorMessage(WSAGetLastError)]));
Break;
end;
end;
finally
if WSALookupServiceEnd(hLookup2) <> 0
then
Memo2.Lines.Add(Format('
WSALookupServiceEnd failed with error code %d: %s',
[WSAGetLastError, SysErrorMessage(WSAGetLastError)]))
end;
end else
Memo2.Lines.Add(Format('
WSALookupServiceBegin failed with error code %d: %s',
[WSAGetLastError, SysErrorMessage(WSAGetLastError)]));
end else
Memo2.Lines.Add(Format('
WSALookupServiceNext failed with error code %d: %s',
[WSAGetLastError, SysErrorMessage(WSAGetLastError)]));
end;
if WSALookupServiceEnd(hLookup) <> 0
then
Memo2.Lines.Add(Format('
WSALookupServiceEnd failed with error code %d: %s',
[WSAGetLastError, SysErrorMessage(WSAGetLastError)]));
end else
Memo2.Lines.Add(Format('
WSALookupServiceBegin failed with error code %d: %s',
[WSAGetLastError, SysErrorMessage(WSAGetLastError)]));
finally
if WSACleanup <> 0
then
Memo2.Lines.Add(Format('
WSACleanup failed with error code %d: %s',
[WSAGetLastError, SysErrorMessage(WSAGetLastError)]));
end;
end else
Memo2.Lines.Add('
WSAStartup failed');