Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Bluethooth auf Android - recvmsg stuck (https://www.delphipraxis.net/204510-bluethooth-auf-android-recvmsg-stuck.html)

Geri 2. Jun 2020 18:52

Bluethooth auf Android - recvmsg stuck
 
Hallo zusammen

Ich hoffe, bei euch ist alles bestens!

Ich habe hier eine Android-App (android 7.0), welche ich mit Delphi 10.3.3 community edition
erstellt habe. Über Bluetooth werden mit einem HC-05-6 Bluetooth-Modul
zyklisch Daten ausgetauscht.
Nach ein paar Minuten Laufzeit friert die App ein. Wenn ich den Debugger
stoppe, dann bleibt er in recvmsg "stecken"

Unter
MS-Windows - HC-05-6 läuft die Anwendung einwandfrei
Android-app mit einem ESP32-Bluetooth-Modul einwandfrei.

Anbei die Sende-Empfangsroutine.
Ich meine, das Problem entsteht in ReceiveBuffer := LSocket.ReceiveData(10);

Vielen Dank für eure Tipps

Geri

Delphi-Quellcode:
function TDROController.SendReceive(Cmd, DataLen:Word; Data:Array of Byte; ExpectedLength:DWord; var ReceiveLength:DWord; var InData:Array of Byte; Timeout:Word):Integer;
var
  LBuffer:TBytes;
  i :integer;
  CRC: Byte;
  ReceiveBuffer:TBytes;
  CurrentIdx:LongWord;
begin
  CRC:=$EF;                            // just fill it with dummy byte
  SetLength(LBuffer,4+ DataLen);
  LBuffer[0]:= $24;                    // Start identifier
  LBuffer[1] := Cmd;                   // command
  LBuffer[2]:= DataLen;                // DataLen
  if DataLen > 0 then
    move(Data,LBuffer[3],DataLen);         // Data
  move(CRC,LBuffer[3+DataLen],sizeof(CRC)); // CRC-Byte
  SetLength(ReceiveBuffer,0);
  result:=-1; // mark as error
  if Assigned(LSocket) then
  begin
    if LSocket.Connected then
    begin
      try
        LSocket.SendData(LBuffer);
        CurrentIdx:=0;
        for i := 0 to TimeOut div 10 do
        begin
          ReceiveBuffer := LSocket.ReceiveData(10);
          if length(ReceiveBuffer) > 0 then
          begin
            move(ReceiveBuffer[0],InData[CurrentIdx],length(ReceiveBuffer));
            CurrentIdx := CurrentIdx + length(ReceiveBuffer);
            SetLength(ReceiveBuffer,0);
            if CurrentIdx >= (ExpectedLength + 4) then
            begin
              result:=0;
              Setlength(LBuffer,0);
              exit;
            end;
          end;
        End;
        ReceiveLength:= CurrentIdx;
        Setlength(LBuffer,0);
      except
        on e: exception do
          AddDebug('Sendreceive Exception ' + E.Message );
      end;
    End;
  end;
  Disconnect();
end;

Rollo62 3. Jun 2020 08:35

AW: Bluethooth auf Android - recvmsg stuck
 
Mit BT-Classic mache ich eigentlich nichts, weil iOS damit selten funktioniert.

Kan es sein dass das Phone einfach einschläft, und dann abstürzt ?
Hast Du mal mit WakeLock versucht wach zu halten ?

Geri 3. Jun 2020 21:51

AW: Bluethooth auf Android - recvmsg stuck
 
Hallo Rollo

Danke für deine Tipps!

Wakelock kannte ich noch nicht.

Habe heute noch einiges versucht. U.a. Timeouts beim Lesen zu verlängern - immer noch selbiges Problem

Gibt es vielleicht eine gute alternative open source Bluethooth-Komponente?

Beste Grüße
Geri

Moombas 4. Jun 2020 07:47

AW: Bluethooth auf Android - recvmsg stuck
 
Ist auf dem Gerät der Doze-Mode (Akkuoptimierung) eingeschaltet? Teste es ggf. mal ohne.

Geri 4. Jun 2020 11:35

AW: Bluethooth auf Android - recvmsg stuck
 
Hallo Moombas

Vielen Dank für die Hilfe!

Ich habe unter Android die Überwachung der App ausgeschaltet. Das Problem bestand aber noch.

Ich denke, es hängt aber schon irgendwie damit zusammen, dass die App in eine Art Ruhezustand geht. Zeitlichen Zusammenhang konnte ich aber noch nicht feststellen.

Ich habe nun aber in die oben gezeigte SendReceive-Methode eine Protokollierug hinzugefügt. Nun läuft die App bereits eine halbe Stunde einwandfrei. AddComDebug fügt Text in ein TMemo hinzu - obwohl sich das TMemo-Feld nicht in einer anderen Tab befindet und nicht sichtbar ist.

Delphi-Quellcode:

        LSocket.SendData(LBuffer);
        CurrentIdx:=0;
        for i := 0 to TimeOut div 25 do
        begin
          AddComDebug('Rcv start ');
          ReceiveBuffer := LSocket.ReceiveData(25);
          AddComDebug('Received bytes ' + IntToStr(length(ReceiveBuffer)));
          if length(ReceiveBuffer) > 0 then
          begin
            move(ReceiveBuffer[0],InData[CurrentIdx],length(ReceiveBuffer));
            CurrentIdx := CurrentIdx + length(ReceiveBuffer);
            SetLength(ReceiveBuffer,0);
            if CurrentIdx >= (ExpectedLength + 4) then
            begin
              result:=0;
              Setlength(LBuffer,0);
              ReceiveLength:= CurrentIdx;
              AddComDebug('End send receive - OK ' + IntToStr(ReceiveLength));
              exit;
            end;
          end;
        End;
...snip
Beste Grüße
Geri

idontknow 5. Jun 2020 15:56

AW: Bluethooth auf Android - recvmsg stuck
 
Wo wird denn die Länge vom Array InData festgelegt?

Geri 5. Jun 2020 20:44

AW: Bluethooth auf Android - recvmsg stuck
 
Hallo Oliver

Das sieht bei mir so aus.

Delphi-Quellcode:
function TDROController.ReadControllerInfo(Sender: TObject):Integer;
var ExpectedLen:DWord;
    ReceiveLen:DWord;
    InData, OutData:Array[0..100] of Byte;
begin
  Result:=-1;
  ExpectedLen:=sizeof(ControllerInfo);
  if SendReceive(DRO_GET_CONTROLLER_INFO,0,OutData,ExpectedLen,ReceiveLen,InData,stdBTIO_TIMEOUT) = 0 Then
  begin
    move(InData[3],ControllerInfo,sizeof(ControllerInfo));
    Result:=0;
  End
end;
Ich habe gestern begonen den Datenaustausch zu protokollieren. Bei jedem Transfer wurden genau 12 Byte ausgetauscht. Dazu wurde die Routine Receivedata vier mal aufgerufen. Zuerst wurden meist 0 Byte empfangen, dann 5 Byte, dann wieder 0 and zuletzt 7 Byte.

Unter MS-Windows läuft das Programm mehrere Stunden einwandfrei.


Beste Grüße

Geri

Geri 7. Jun 2020 16:40

AW: Bluethooth auf Android - recvmsg stuck
 
Inzwischen habe ich Wakelock eingebaut, ich konnte (gefühlt) eine Besserung feststellen. Den Code fand ich im Internet. Nach einiger Zeit friert die App aber immer noch ein. Das kann nach einmal nach 5 Minuten, ein anderes mal nach 1 Stunde sein.

Delphi-Quellcode:
function GetPowerManager: JPowerManager;
var PowerServiceNative: JObject;
begin
  PowerServiceNative := TAndroidHelper.Context.getSystemService(TJContext.JavaClass.POWER_SERVICE);
  if not Assigned(PowerServiceNative) then
    raise Exception.Create('Could not locate Power Service');
  Result := TJPowerManager.Wrap((PowerServiceNative as ILocalObject).GetObjectID);
  if not Assigned(Result) then
    raise Exception.Create('Could not access Power Manager');
end;

var WakeLock: JPowerManager_WakeLock = nil;

function AcquireWakeLock(): Boolean;
var
  PowerManager: JPowerManager;
begin
  Result := Assigned(WakeLock);
  if not Result then
  begin
    PowerManager := GetPowerManager;
      WakeLock := PowerManager.newWakeLock(TJPowerManager.JavaClass.SCREEN_BRIGHT_WAKE_LOCK,
StringToJString('Delphi'));
    Result := Assigned(WakeLock);
  end;
  if Result then
  begin
    if not WakeLock.isHeld then
    begin
      WakeLock.acquire;
      Result := WakeLock.isHeld
    end;
  end;
end;

procedure ReleaseWakeLock;
begin
  if Assigned(WakeLock) then
  begin
    WakeLock.release;
    WakeLock := nil
  end;
end;
Im Debugger sehe ich, dass AcquireWakeLock true zurückliefert. Habe mit diversen Levels probiert.

https://stuff.mit.edu/afs/sipb/proje...FULL_WAKE_LOCK

Beste Grüße

Geri

Geri 9. Jun 2020 14:38

AW: Bluethooth auf Android - recvmsg stuck
 
Hallo zusammen

Inzwischen bin ich ein wenig weitergekommen.

Habe auf drei verschiedenen Smartphones die App mehrere Stunden getestet:

Samsung, GT-I9195, Android 4.4.2 => funktioniert einwandfrei
Samsung, SM-G361F, Android 5.1.1 => funktioniert einwandfrei
Samsung Galaxy S6, Android 7.0 => funktioniert nicht

Folgendes habe ich gemacht:
  1. Energieüberwachung für die App ausgeschaltet
  2. Wakelock auf höchsten Level eingestellt
  3. Cache der App gelöscht

Gibt es evtl. noch eine Einstellung, die auf die App Einfluss haben könnte?

Beste Grüße
Geri


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