AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi SDP Record Stream eins Bluetooth Devices besorgen
Thema durchsuchen
Ansicht
Themen-Optionen

SDP Record Stream eins Bluetooth Devices besorgen

Ein Thema von himitsu · begonnen am 17. Nov 2010 · letzter Beitrag vom 16. Dez 2010
Antwort Antwort
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.051 Beiträge
 
Delphi 12 Athens
 
#1

SDP Record Stream eins Bluetooth Devices besorgen

  Alt 17. Nov 2010, 12:55
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.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
Benutzerbild von Brainstalker
Brainstalker

Registriert seit: 9. Jan 2004
Ort: Berlin
176 Beiträge
 
Delphi 2009 Professional
 
#2

AW: SDP Record Stream eins Bluetooth Devices besorgen

  Alt 16. Dez 2010, 10:19
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
Michael N.
Brainstalker
  Mit Zitat antworten Zitat
Benutzerbild von Brainstalker
Brainstalker

Registriert seit: 9. Jan 2004
Ort: Berlin
176 Beiträge
 
Delphi 2009 Professional
 
#3

AW: SDP Record Stream eins Bluetooth Devices besorgen

  Alt 16. Dez 2010, 19:59
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]));
Michael N.
Brainstalker

Geändert von Brainstalker (16. Dez 2010 um 20:06 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:37 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