Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi SDP Record Stream eins Bluetooth Devices besorgen (https://www.delphipraxis.net/156030-sdp-record-stream-eins-bluetooth-devices-besorgen.html)

himitsu 17. Nov 2010 12:55

SDP Record Stream eins Bluetooth Devices besorgen
 
Mahlzeit.

Also, ich lass' mir über BluetoothFindFirstDevice die vorhandenen Bluetooth Devices auflisten,
aber um detailiertere Informationen zu den gefundenen Devices bekommen zu können, benötige ich diesen besagten SDP Record Stream.
Und genau da liegt mein Problem, denn ich finde einfach nicht raus, wie man da (einfach) rankommt. :?

Gefunden hab ich nur diese Funktionen http://msdn.microsoft.com/en-us/library/aa362927.aspx ,
wobei alle BluetoothSdp*-Funktionen diesen Stream verlangen, aber keine der anderen Funktionen liefert mir soeinen (falls ich es nicht übersehn hab).


OK, auf der Suche nach einer Lösung bin ich auch auf folgene Seiten gestoßen, wo entsprechende BluetoothSdp*-Funktionen genutzt werden.
http://www.lenholgate.com/archives/000102.html
http://social.msdn.microsoft.com/for...6-c7a134ea449d
http://www.winsocketdotnetworkprogra...rotocol4l.html

Letzeres hatte ich mir erstmal übersetzt, es compiliert auch, aber beim Aufruf von WSALookupServiceNext kommt es nach ein paar Sekunden zu einer Zugriffsverletzung und der Codepointer liegt irgendwo rum.
In der Assembleransicht des Debuggers sieht man, daß die Codeverarbeitung sich wohl irgendwann verläuft, vermutlich an eine falsche Stelle springt und es dann natürlich zu Problemen kommt.

Mein Übersetzungsergebnis:
Delphi-Quellcode:
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');
Wie gesagt, eigentlich würde ich eh auf diesen riesigen Code verzichten, wenn es eine (einfache) Lösung gibt, um z.B. direkt über eine BLUETOOTH_DEVICE_INFO auf diesen Stream zu kommen.

Brainstalker 16. Dez 2010 10:19

AW: SDP Record Stream eins Bluetooth Devices besorgen
 
Hey,

ist zwar jetzt leider keine Antwort auf deine Frage, aber ich beschäftige mich auch ein bisschen mit der Win Bluetooth API.
Ich hab jetzt länger nicht mehr weitergearbeitet, wollte aber wieder ansetzen. Vielleicht können wir da ja zu zweit ein bisschen mehr auf die Reihe bekommen.

Ich schau mir noch mal meinen Code an und falls ich wegen dem SDP was funktionierendes habe dann poste ich es.

Mein Post

Brainstalker 16. Dez 2010 19:59

AW: SDP Record Stream eins Bluetooth Devices besorgen
 
Ich habe deinen Fehler gefunden:
Code:
if WSALookupServiceNext(hLookup, flags, bufferLength, @pResults) = 0 then begin
da muss das @ weg vor pResults.

Dann sollte es eigentlich gehen.



EDIT:

Und in deiner callback Funktion fehlt noch ein ^ hinter pValueStream:
Code:
TMemo(Param).Lines.Add(Format('Callback pValueStream: %d', [pValueStream]));


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:40 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz