Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi Bluetooth Server Win32 API (https://www.delphipraxis.net/154412-bluetooth-server-win32-api.html)

Brainstalker 9. Sep 2010 20:30

Bluetooth Server Win32 API
 
Hallo,

ich versuche mich gerade daran einen kleinen Server zu erstellen, der Bluetoothverbindungen entgegennimmt. Er soll also das entgegennehmen, was ein Bluetoothgerät an ihn sendet. Das können zum Beispiel Strings sein oder binäre Rohdaten.
Mein Problem ist jetzt das mir anscheinend das Verständnis für den ersten Schritt fehlt. Wie erstelle ich denn mit den bereitgestellten Funktionen der Win32API einen solchen Server. Muss ich da irgendwie über Sockets gehen oder wie? Welche Funktionen muss ich da verwenden.

Ich hab schon nach Radios gescannt und bekomme auch die Namen der Bluetoothgeräte. Schön und gut, aber wie gehts weiter?

Ach ich benutze übrigens die Jedi Bluetooth API Header.


[EDIT]
Ach ja das Gerät ist übrigens ein Android Smartphone. Von dem möchte ich Daten an meinen PC schicken. Ich habe auf meinem Smartphone einen Service, der auch von Windows erkannt wird. Allerdings bekomme ich da immer die Fehlermeldung das der Treiber nicht installiert werden kann. Ist ja auch klar, woher soll Windows den Service kennen.

Brainstalker 9. Sep 2010 22:53

AW: Bluetooth Server Win32 API
 
Ich hab jetzt selber nochmal ein bisschen die Microsoft Bluetooth API und die JEDI Header durchsucht. Ist es richtig, das ich über die Funktion
Delphi-Quellcode:
function BluetoothEnableIncomingConnections(hRadio: THandle; fEnabled: BOOL): BOOL; stdcall;
eine Verbindung mit dem Gerät aufbaue? Wie sieht es umgekehrt aus, wie gehe ich vor wenn ich eine Verbindung vom Gerät aufbauen möchte?

Wenn ich eine Verbindung haben sollte, kann ich dann über die SDP-Funktionen Daten empfangen? Was müsste ich dabei beachten?

mkinzler 10. Sep 2010 06:41

AW: Bluetooth Server Win32 API
 
Ist zawr nicht umsonst, aber vielleicht ein Blick wert:
http://www.tinyapps.info/

Brainstalker 13. Sep 2010 05:51

AW: Bluetooth Server Win32 API
 
Ja ich werd mir das noch mal genauer anschauen. Aber ich wollte eigentlich kein Geld ausgeben und da ich jetzt schon angefangen habe auch weiter selbst ein bisschen probieren. Außerdem lerne ich dadurch auch ein bisschen mehr über die Win API programmierung, mit der ich mich bisher sehr wenig beschäftigt habe.

Bin jetzt schon soweit, das ich die Bluetooth Radios und Devices auflisten kann. Habe auch schon Funktionen implementiert um die Hersteller und Geräteklassen zu dekodieren.
Im Moment ist halt noch das große Problem, das ich keine Verbindung vom Smartphone zum PC bekomme. Ich hab den Bluetooth Empfänger zwar auf AcceptConnection gesetzt aber irgendwas läuft noch schief. Liegt das vielleicht an der Übertragung? Der Service auf dem Smartphone liefert ein SDP Paket für den Service an den Empfänger aus (Wird auch von Windows erkannt, aber die Verbindung läuft über ein Socket.
Die Server/Client Software auf dem Smartphone ist in Java für Android gescherieben und nicht zu 100% von mir. Hab noch nicht viel Java gemacht.
Muss ich jetzt zwingend eine Socketverbindung auf dem PC erstellen damit die Verbindung funktioniert? Dann müsste ich mich auch noch in Sockets einlesen, aber wär ja auch nicht so schlimm.

Beschäftigt sich hier sonst niemand weiter mit Bluetooth ohne Komponenten? Soll ja erstmal nur den Microsoft Stack zum Teil implementieren. Will ja erstmal nur Strings zu Server schicken.

Brainstalker 13. Sep 2010 09:41

AW: Bluetooth Server Win32 API
 
So ich hab jetzt mal wieder ein bisschen in der Bluetooth API geschaut und ich denke der Socket Ansatz ist der richtige. Das Androidprogramm in Java benutzt auch einen Socket, also müsste das dann ja so hinhauen. Läuft dann über RFComm.

Hab mal jetzt ein bisschen was aus der API zusammen kopiert und halbwegs nach Delphi portiert. Können noch Fehler drin sein oder Pseudocode enthalten sein. Hab jetzt auch gerade keine Möglichkeit das zu testen, weil ich auf Arbeit bin. Aber vielleicht können ja die Socket Experten mal nen Blick drüber werfen.

Delphi-Quellcode:
var
  wsaD: TWsaData;
  iResult: integer;
  ListenSocket: TSocket;
  name: SOCKADDR_BTH;

begin

//----------------------
// Initialize Winsock

  iResult := WSAStartup(WINSOCK_VERSION, @wsaD);
  if (iResult <> NO_ERROR)
    ShowMessage('Error at WSAStartup()');

//----------------------
// Create a SOCKET for listening for
// incoming connection requests.

  // Parameters for Bluetooth Socket
  ListenSocket := socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
  if (ListenSocket = INVALID_SOCKET) then
  begin
    ShowMessage('Error at socket(): ' + WSAGetLastError());
    WSACleanup();
    exit;
  end;

//----------------------
// The sockaddr_in structure specifies the address family,
// IP address, and port for the socket that is being bound.

  name.addressFamily := AF_BTH;
  name.btAddr := 0;
  name.serviceClassId := NULL_GUID;
  name.port := BT_PORT_ANY;


  if (bind(ListenSocket, TSockAddr(@name), sizeof(name)) = SOCKET_ERROR) then
  begin
    ShowMessage('bind() failed.');
    closesocket(ListenSocket);
    exit;
  end;

//----------------------
// Listen for incoming connection requests
// on the created socket

  if (listen(ListenSocket, SOMAXCONN) = SOCKET_ERROR) then
    ShowMessage('Error listening on socket.');

  ShowMessage('Listening on socket...');
  WSACleanup();
  exit;

end;

Astat 13. Sep 2010 13:59

AW: Bluetooth Server Win32 API
 
Zitat:

Zitat von Brainstalker (Beitrag 1049184)
..mal nen Blick drüber werfen.

Hi Brainstalker, als Minimum Sample sollte noch folgendes implementiert werden.

Delphi-Quellcode:
var
  ...
  name: SOCKADDR_BTH;
  addrlen: integer;
  ClientSocket: TSocket;
begin
  iResult := WSAStartup($0020, @wsaD);
.....

//----------------------
// Listen for incoming connection requests
// on the created socket

  if (listen(ListenSocket, SOMAXCONN) = SOCKET_ERROR) then
    ShowMessage('Error listening on socket.');

  addrlen := SizeOf(name);
  while ServerRunning do begin
    ClientSocket := Accept(ListenSocket, @name, @addrlen);
    if (ClientSocket <> INVALID_SOCKET) then begin
      cbRcv := Recv(ClientSocket, szBuf[0], WSOCK_READ_BUFFER_SIZE, 0);
      if (cbRcv = 0) or (cbRcv = SOCKET_ERROR) then EXIT;
      .... loop
      ret := ioctlsocket(ClientSocket, FIONREAD, cbRead);
      result := Send(ASocket, sSendData[1], Length(sSendData), 0);
      done....
    end;
  end;

  ShowMessage('Listening on socket...');
  WSACleanup();
  exit;

end;

lg. Astat

Brainstalker 13. Sep 2010 17:48

AW: Bluetooth Server Win32 API
 
Hey danke Astat,

das mit dem Accept hab ich auch noch gefunden. Das Programm wartet auch auf eine Connection vom Client. Mein Problem ist jetzt bloß noch, das mein Client auf dem Smartphone immer noch nicht connecten will. Ich weiß nicht was ich im Moment noch für einen Fehler drin habe. Falls sich jemand mit der Android programmierung auskennt, mit:
Code:
private final BluetoothDevice mmDevice;
tmp = mmDevice.createRfcommSocketToServiceRecord(MY_UUID);
will ich eine Verbindung herstellen. Allerdigs bekomm ich damit keine Connection.


[EDIT]
Hab gerade rausgefunden, das ich den Service mit der Funktion WSASetService promoten soll. Allerdings scheint das bei mir nicht so richtig zu funktionieren.
Als Fehler bekomme ich immer (Nummer: 11004):
Zitat:

Der angeforderte Name ist gültig, es wurden jedoch keine Daten des angeforderten Typs gefunden
Weiß jemand was da schief läuft?

Brainstalker 14. Sep 2010 07:35

AW: Bluetooth Server Win32 API
 
Der ganze Thread hier ist zwar eher ein Selbstgespräch, aber vielleicht bringt es ja auch anderen Benutzern etwas wenn ich hier meine Gedanken und Fortschritte aufschreibe.

Ich stehe jetzt (hoffentlich) kurz vor einer funktionierenden Verbindung meines Android Handys und dem PC. Ich werde nachher zwei Dinge ausprobieren, ich habe zum einen im Internet noch ein bisschen Source zur Funktion WSASetService gefunden:
Code:
int size = sizeof(SOCKADDR_BTH);

if (0 != getsockname(s, pAddr, &size))
{
printf("%s\n", GetLastErrorMessage(GetLastError()));
}

WSAQUERYSET service;

memset(&service, 0, sizeof(service));

service.dwSize = sizeof(service);

service.lpszServiceInstanceName = "My Service";
service.lpszComment = "My comment";

GUID serviceID = OBEXFileTransferServiceClass_UUID;

service.lpServiceClassId = &serviceID;

service.dwNumberOfCsAddrs = 1;
service.dwNameSpace = NS_BTH;

CSADDR_INFO csAddr;

memset(&csAddr, 0, sizeof(csAddr));

csAddr.LocalAddr.iSockaddrLength = sizeof(SOCKADDR_BTH);
csAddr.LocalAddr.lpSockaddr = pAddr;

csAddr.iSocketType = SOCK_STREAM;
csAddr.iProtocol = BTHPROTO_RFCOMM;

service.lpcsaBuffer = &csAddr;

if (0 != WSASetService(&service, RNRSERVICE_REGISTER, 0))
{
printf("%s\n", GetLastErrorMessage(GetLastError()));
}
und zum anderen liegt es vielleicht daran, das mein Androidprogramm einfach nur eine andere GUID für den Service benutzen muss.
Code:
RFCOMM_PROTOCOL_UUID: TGUID = '{00000003-0000-1000-8000-00805F9B34FB}';

Brainstalker 17. Sep 2010 15:43

AW: Bluetooth Server Win32 API
 
Ich bin leider noch nicht viel weiter gekommen. Allerdings ist mir jetzt was aufgefallen.

In der Datei "ws2bth.h" ist die Konstante BT_PORT_ANY als -1 deklariert.
Im Struct SOCKADDR_BTH ist die Variable port als ULONG deklariert.

Es ist doch gar nicht möglich den Wert zuzuweisen oder? Der Compiler meckert ja zurecht das die untere Grenze verletzt wird.

Delphi-Quellcode:
const
  BT_PORT_ANY = -1;

var
  name: SOCKADDR_BTH;

...

name.port := BT_PORT_ANY;
Wie kann ich denn den Wert zuweisen? Scheint ein Fehler zu sein in meinem Code, denn z.Z. benutze ich 0 als Port. In der msdn steht aber man soll BT_PORT_ANY benutzen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:20 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