Einzelnen Beitrag anzeigen

philipp.hofmann

Registriert seit: 21. Mär 2012
Ort: Hannover
859 Beiträge
 
Delphi 10.4 Sydney
 
#1

Status: Tethering - noch Probleme mit MacOS und iOS

  Alt 28. Mai 2021, 16:48
Status: Tethering

Da das Thema deutlich aufwändiger ist, als erwartet, hier mal mein aktueller Status mit ein paar Handlungsempfehlungen.
In meinem Fall habe ich eine Haupt-App und eine Fernsteuerung. Die Fernsteuerung sucht und verbindet sich mit der Hauptapp und beide können jetzt der jeweils anderen Daten und somit Handlungs-/Anzeige-Anweisungen schicken.

- die Windows-App kann sowohl andere Manager und Profiles im Netzwerk suchen und finden (discover) als auch gefunden werden und dann zwischen beiden Apps Daten austauschen
- hier ist wichtig, dass das eigene WLAN als "Privat" und nicht als "Öffentlich" gekennzeichnet wird, teilweise muss man die App auch in der Firewall nochmals bewusst erlauben.

- die Android-App kann sowohl andere Manager und Profiles im Netzwerk suchen und finden (discover) als auch gefunden werden und dann zwischen beiden Apps Daten austauschen
- Permission Internet muss auf "true" gesetzt sein

- die MacOS-App kann andere Manager und Profiles im Netzwerk suchen und finden (discover), diesem auch Daten schicken und Antworten empfangen, kann aber nicht gefunden werden.
Ursache: DoOnReceiveData wird nie errreicht

Folgende Entitlements wurden gesetzt (Entitlement.TemplateOSX.xml):
<key>com.apple.security.network.client</key>
<true/>
<key>com.apple.security.network.server</key>
<true/>

- die iOS-App kann beides nicht, weder suchen und finden (discover) noch gefunden werden.
Ursache: Beim BroadcastData wird die Exception "Socket-Fehler # 65Keine Route zum Host." bzw. "Socket-Fehler # 9Falsche Dateinummer." geworfen

Ich frage mich jetzt:
a) Welche Capabitlities müssen für den Identifier auf developer.apple.com für iOS gesetzt werden?
b) Welche Capabitlities müssen für den Identifier auf developer.apple.com für MacOS gesetzt werden?
c) Welche Entitlements müssen für iOS gesetzt werden (Entitlement.TemplateiOS.xml)?
d) Welche Entitlements müssen für MacOS gesetzt werden (Entitlement.TemplateOSX.xml)?
e) Welche Properties müssen für iOS gesetzt werden (info.plist.TemplateiOS.xml)?
Muss hier z.B. com.apple.developer.networking.multicast gesetzt werden, wo man vorab auch per "Multicast Networking Entitlement Request" nachfragen muss
(und dort schon eine AppStore-URL angeben muss, obwohl die App noch gar nicht mit iOS funktioniert)
f) Welche Properties müssen für MacOS gesetzt werden (info.plist.TemplateOSX.xml)?

Tipp 1: Formulardesigner: das Profile auf Enabled setzen und den Manager aus Disabled und dem Profile keinen Manager zuweisen.
Im Programm-Code den Manager auf Enabled setzen und direkt davor dem Profile den Manager zuweisen.
Sonst wird schon sehr viel initialisert (z.B. der Netzwerk-Adapter) bevor man erstmalig Zugriff im Code auf die Komponenten hat.

Delphi-Quellcode:
  CommandApp.Manager := CommandManager;
  CommandManager.Enabled := True;
Tipp 2: IP-Adresse des eigenen Adapters nicht automatisch setzen lassen, sondern selbst per Indy auswählen:

[DELPHI]
uses IdStack, IdGlobal;

function getIPv4Address():String;
var
AAddresses: TIdStackLocalAddressList;
LAddr: TIdStackLocalAddress;
I: Integer;
prefNetwork,IP: String;
begin
AAddresses:=TIdStackLocalAddressList.Create();
prefNetwork:='192.';//can be set also outside this functionality before the manager is enabled or the manager-attribute of the profile is set
Result:='';
try
GStack.GetLocalAddressList(AAddresses);
for I := 0 to AAddresses.Count-1 do
begin
LAddr:=AAddresses[I];
IP:=LAddr.IPAddress;
if ((IP<>'127.0.0.1') and ((Result='') or ((prefNetwork>'') and (pos(prefNetwork,IP)=1) and (pos(prefNetwork,Result)<>1)))) then
begin
case LAddr.IPVersion of
Id_IPv4:
begin
mlog.info('Found IP-address*: '+IP);
Result:=IP;
end;
Id_IPv6:
begin
mlog.info('Found IP-address: '+IP);
end;
end;
end else
mlog.info('Found IP-address: '+IP);
end;
finally
AAddresses.Free;
end;
end;
[DELPHI]

Dies passiert an zwei Stellen:

System.Tether.Manager.pas
Delphi-Quellcode:
constructor TTetheringAdapter.Create;
var ip:String;
begin
  inherited;
  FRemoteManagers := TTetheringManagerInfoList.Create;
  ip:=getIPv4Address();
  if (ip>'') then
    FAdapterConnectionString := ip
  else
    FAdapterConnectionString := TTetheringManagerCommunicationThread.EMPTYTOKEN;
end;
System.Tether.NetworkAdapter.pas
Delphi-Quellcode:
procedure TTetheringNetworkManagerCommunicationThread.Execute;
...
        if not LListening then
          raise ETetheringException.Create(SManagerNetworkCreation);

        var ip:String;
        ip:=TStringUtils.getIPv4Address();
        if (ip>'') then
          LRemoteConnectionString := ip + TetheringConnectionSeparator + FTarget
        else
          LRemoteConnectionString := EMPTYTOKEN + TetheringConnectionSeparator + FTarget;
Zur Sicherheit habe ich es noch hier eingebaut, da wird es aber höchstwahrscheinlich nicht gebraucht:

System.Tether.NetworkAdapter.pas
Delphi-Quellcode:
procedure TTetheringNetworkAdapterCommon.DoDiscoverManagers(Timeout: Cardinal;
  const ATargetList: TTetheringTargetHosts; const AProfileGroups, AProfileTexts: TArray<string>);
...
    LCommand := TTetheringManagerCommand.Create(TTetheringNetworkManagerCommunicationThread.TetheringDiscoverManagers,
      FAdapterConnectionString, Manager.Version, [FCommunicationThread.FTarget, LGroups, LTexts]);
  end else begin
    if (pos(TTetheringNetworkManagerCommunicationThread.EMPTYTOKEN,FAdapterConnectionString)>0) then
    begin
      var ip:String;
      ip:=TStringUtils.getIPv4Address();
      if (ip>'') then
        FAdapterConnectionString:=StringReplace(FAdapterConnectionString,TTetheringNetworkManagerCommunicationThread.EMPTYTOKEN,ip,[]);
    end;
  Mit Zitat antworten Zitat