Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
IdTCPClient on Android: Connecting to non-active network
#7
(04-29-2018, 06:50 AM)BartKindt Wrote: Trying to set the outgoing network using the allocated IP address does not work.

But you haven't shown proof of that yet.

(04-29-2018, 06:50 AM)BartKindt Wrote: - WIFI is enabled, the assigned IP address is 192.168.53.102

Is that the IP address that you are assigning to the BoundIP?  You haven't shown how you are populating your NetwordData object.

(04-29-2018, 06:50 AM)BartKindt Wrote: - My Local Database Server is connected to the WIFI network, and broadcasts its own IP address via the IdUDPServer (which I receive on the phone via the WIFI). Its IP address is 192.168.53.101

Without explicitly binding the TIdTCPClient to a specific local IP/Port, I would expect Android to be smart enough to be able to pick the appropriate network adapter that has a route to reach 192.168.53.101, which would be the WiFi adapter since 192.168.53.102 is on the same subnet as 192.168.53.101.  That is key to any OS's network routing system.

(04-29-2018, 06:50 AM)BartKindt Wrote:
Code:
if NetworkData.LocalIP <> '' then
begin
  BoundIP := NetworkData.LocalIP;
  BoundPort := 8051;
  LocalLog('=== TCPThread.Execute: Connect using BoundIP: '+NetworkData.LocalIP);
end;

Are you SURE that NetworkData.LocalIP is being set to 192.168.53.102?  Is that what is in your log message?  Can you show the code that is populating NetworkData.LocalIP?

On a side note, you don't need to set a value for BoundPort, unless your router/firewall requires it.  Otherwise, I would leave it 0 and let Android pick an available port for you.

(04-29-2018, 06:50 AM)BartKindt Wrote:
Code:
UAndroidPowerManagement.AcquireWakeLock;
Connect;
UAndroidPowerManagement.ReleaseWakeLock;

Make sure to wrap Connect() in a try/finally or try/except block so you release the WakeLock whether Connect() succeeds or fails.

(04-29-2018, 06:50 AM)BartKindt Wrote: The Connect attempt is not going out over the WIFI network.

How do you know that for sure?  Do you have a packet sniffer running that is showing you the network packets being generated by the Android device?

(04-29-2018, 06:50 AM)BartKindt Wrote: It probably goes out over the Mobile network.

Now you are just assuming.  Stop assuming and start debugging.  Find out FOR SURE which network adapter the traffic is actually using.

(04-29-2018, 06:50 AM)BartKindt Wrote: Reading all the documentation on the SetSockOpt() has unfortunately not helped me much, I do not understand much of it.
The Indy SetSockOpt() requires 3 integers.
The Linux doc talks about the SO_BINDTODEVICE; Which I assume is Constant?, which I cannot find anywhere.
"SO_BINDTODEVICE:   Bind this socket to a particular device like "eth0", as specified in the passed interface name."
So where do I enter this string?

You won't be able to use Indy's SetSockOpt() wrapper in this situation (nor did I tell you to do so), as SO_BINDTODEVICE does not pass in integer data as input, per its documentation.  You will have to call the socket API setsockopt() function directly instead.  It takes a pointer and length as input arguments.  You can use those to pass in the adapter name.  Delphi defines Linux's setsockopt() function in the Posix.SysSocket unit, eg (untested):

Code:
uses
 ..., SysUtils, IdStack, Posix.SysSocket;

const
 SO_BINDTODEVICE = 25;

var
 ...
 DeviceName: String;
 M: TMarshaller;
begin
 ...
 DeviceName := ...; // device name of WiFi adapter
 GStack.CheckForSocketError(
    Posix.SysSocket.setsockopt(
      IdTCPClient1.Socket.Binding.Handle,
      Id_SOL_SOCKET,
      SO_BINDTODEVICE,
      M.AsAnsi(DeviceName).ToPointer^,
      Length(DeviceName)+1 // assuming the device name uses ASCII chars only
    )
  );
  ...
end;

(04-29-2018, 06:50 AM)BartKindt Wrote: And unfortunately I have still not been able to find any type of Android string or integer reference linked to a given Network, so that I can supply this to Indy.

Look at Android's NetworkInterface interface, which has getByInetAddress() and getName() methods.

I don't know if getName() returns the same name that SO_BINDTODEVICE expects, though.

Otherwise, since Delphi operates at the native (NDK) level, and thus Indy operates at the Linux level, not at the Android level, you can use Linux APIs to query the adapter information, such as getifaddrs() (which unfortunately Android does not implement, but there is a 3rd party implementation at https://github.com/morristech/android-ifaddrs).

(04-29-2018, 06:50 AM)BartKindt Wrote: The only thing I get is the assigned IP address. (or lots of information about bandwidth, frequencies, etc.)

You are referring to Android's WiFiInfo interface, correct?

(04-29-2018, 06:50 AM)BartKindt Wrote: CORRECTION: I did find this:
"getNetworkId
int getNetworkId ()
Each configured network has a unique small integer ID, used to identify the network when performing operations on the supplicant. This method returns the ID for the currently connected network."

That network ID is not useful in this situation.



PS. on a side note, when posting code snippets to this forum, please use [ code]...[ /code] tags, not {code}...{code} tags like in the Embarcadero forums.  When writing a post in this forum, the full editor has a
.png   code.png (Size: 872 bytes / Downloads: 55)  button for inserting code snippets.

Reply


Messages In This Thread
RE: IdTCPClient on Android: Connecting to non-active network - by rlebeau - 04-30-2018, 06:46 PM

Forum Jump:


Users browsing this thread: 1 Guest(s)