24
24
25
25
import java .io .IOException ;
26
26
import java .net .Inet4Address ;
27
+ import java .net .Inet6Address ;
28
+ import java .net .InetAddress ;
29
+ import java .net .NetworkInterface ;
30
+ import java .net .SocketException ;
27
31
import java .util .ArrayList ;
32
+ import java .util .Enumeration ;
33
+ import java .util .HashMap ;
28
34
import java .util .List ;
35
+ import java .util .Map ;
29
36
import java .util .Objects ;
30
37
import java .util .concurrent .ConcurrentHashMap ;
31
38
import java .util .concurrent .CountDownLatch ;
@@ -263,51 +270,134 @@ public void onUnavailable() {
263
270
}
264
271
}
265
272
273
+ // Create networkMap to select correct network via NetworkInterface (fallback)
274
+ Map <String , Network > networkMap = new HashMap <>();
275
+ for (Network network : wifiNetworks ) {
276
+ NetworkCapabilities nc = cm .getNetworkCapabilities (network );
277
+ LinkProperties lp = cm .getLinkProperties (network );
278
+ if (lp != null ) {
279
+ for (LinkAddress address : lp .getLinkAddresses ()) {
280
+ InetAddress inetAddress = address .getAddress ();
281
+ if (inetAddress instanceof Inet4Address || inetAddress instanceof Inet6Address ) {
282
+ networkMap .put (inetAddress .getHostAddress (), network );
283
+ }
284
+ }
285
+ }
286
+ }
287
+
266
288
// Check exist at least one newtwork based on selected transport type
267
289
if (!wifiNetworks .isEmpty ()) {
268
290
boolean networkFound = false ;
269
- for (Network network : wifiNetworks ) {
270
- LinkProperties linkProperties = cm .getLinkProperties (network );
271
- // Ensure linkProperties is not null
272
- if (linkProperties == null )
273
- continue ;
274
-
275
- if (android .os .Build .VERSION .SDK_INT >= android .os .Build .VERSION_CODES .R ) {
276
- Inet4Address foundServerAddress = linkProperties .getDhcpServerAddress ();
277
- if (iotDeviceHost .equals (foundServerAddress .getHostAddress ())) {
278
- // found ioT device network
279
- currentNetwork .setNetwork (network );
280
- cm .bindProcessToNetwork (network );
281
- networkFound = true ;
282
- awaitingNetwork .countDown (); // Stop waiting
283
- break ;
284
- }
285
- } else {
291
+
292
+ if (wifiNetworks .size () == 1 ) {
293
+ // Single network scenario --> // Use that network in any case
294
+ Network network = wifiNetworks .get (0 );
295
+ currentNetwork .setNetwork (network );
296
+ cm .bindProcessToNetwork (network );
297
+ networkFound = true ;
298
+ } else {
299
+ // Multiple network scenario
300
+ for (Network network : wifiNetworks ) {
301
+ LinkProperties linkProperties = cm .getLinkProperties (network );
302
+ // Ensure linkProperties is not null
303
+ if (linkProperties == null )
304
+ continue ;
305
+
286
306
List <LinkAddress > linkAddressList = linkProperties .getLinkAddresses ();
287
- if (linkAddressList != null && !linkAddressList .isEmpty ()) {
288
- for (LinkAddress address : linkAddressList ) {
289
- int lastDotIndex = iotDeviceHost .lastIndexOf ('.' );
290
- String iotSubnetAddress = iotDeviceHost ;
291
- if (lastDotIndex >=0 )
292
- iotSubnetAddress = iotDeviceHost .substring (0 , lastDotIndex );
293
- if (address .getAddress ().getHostAddress ().startsWith (iotSubnetAddress )) {
307
+ if (android .os .Build .VERSION .SDK_INT >= android .os .Build .VERSION_CODES .R ) {
308
+ // Android version >= 11
309
+ Inet4Address foundServerAddress = linkProperties .getDhcpServerAddress ();
310
+ if (foundServerAddress != null ) {
311
+ String foundAddress = foundServerAddress .getHostAddress ();
312
+ if (foundAddress != null && foundAddress .contains (iotDeviceHost )) {
294
313
// found ioT device network
295
314
currentNetwork .setNetwork (network );
296
315
cm .bindProcessToNetwork (network );
297
316
networkFound = true ;
298
- awaitingNetwork .countDown (); // Stop waiting
299
317
break ;
300
318
}
319
+ } else if (linkAddressList != null && !linkAddressList .isEmpty ()) {
320
+ // Fallback to linkAddresses if DHCP server address is null
321
+ for (LinkAddress address : linkAddressList ) {
322
+ int lastDotIndex = iotDeviceHost .lastIndexOf ('.' );
323
+ String iotSubnetAddress = iotDeviceHost ;
324
+ if (lastDotIndex >= 0 )
325
+ iotSubnetAddress = iotDeviceHost .substring (0 , lastDotIndex );
326
+ if (address .getAddress ().getHostAddress ().startsWith (iotSubnetAddress )) {
327
+ // Found IoT device network
328
+ currentNetwork .setNetwork (network );
329
+ cm .bindProcessToNetwork (network );
330
+ networkFound = true ;
331
+ break ;
332
+ }
333
+ }
334
+ }
335
+ } else {
336
+ // Android version < 11
337
+ if (linkAddressList != null && !linkAddressList .isEmpty ()) {
338
+ for (LinkAddress address : linkAddressList ) {
339
+ int lastDotIndex = iotDeviceHost .lastIndexOf ('.' );
340
+ String iotSubnetAddress = iotDeviceHost ;
341
+ if (lastDotIndex >=0 )
342
+ iotSubnetAddress = iotDeviceHost .substring (0 , lastDotIndex );
343
+ if (address .getAddress ().getHostAddress ().startsWith (iotSubnetAddress )) {
344
+ // found ioT device network
345
+ currentNetwork .setNetwork (network );
346
+ cm .bindProcessToNetwork (network );
347
+ networkFound = true ;
348
+ break ;
349
+ }
350
+ }
301
351
}
302
352
}
303
353
}
304
354
}
305
- if (!networkFound ) {
306
- awaitingNetwork .countDown (); // Stop waiting if no network was found
355
+
356
+ // Fallback 1 -> if no matching network is found try selecting via NetworkInterface
357
+ if (!networkFound && wifiNetworks .size () > 1 ) {
358
+ try {
359
+ Enumeration <NetworkInterface > networkInterfaces = NetworkInterface .getNetworkInterfaces ();
360
+ while (networkInterfaces .hasMoreElements ()) {
361
+ NetworkInterface networkInterface = networkInterfaces .nextElement ();
362
+ if (!networkInterface .isUp () || networkInterface .isLoopback ()) continue ;
363
+
364
+ Enumeration <InetAddress > inetAddresses = networkInterface .getInetAddresses ();
365
+ while (inetAddresses .hasMoreElements ()) {
366
+ InetAddress inetAddress = inetAddresses .nextElement ();
367
+ if (inetAddress instanceof Inet4Address ) {
368
+ if (inetAddress != null && iotDeviceHost .equals (inetAddress .getHostAddress ())) {
369
+ // Cerca la rete corrispondente nell'HashMap
370
+ Network matchedNetwork = networkMap .get (inetAddress .getHostAddress ());
371
+ if (matchedNetwork != null ) {
372
+ // Found IoT device network
373
+ currentNetwork .setNetwork (matchedNetwork );
374
+ cm .bindProcessToNetwork (matchedNetwork );
375
+ networkFound = true ;
376
+ break ;
377
+ }
378
+ }
379
+ }
380
+ }
381
+ }
382
+ } catch (SocketException e ) {
383
+ // Fallback 2 -> if no matching network is found try select last wifiNetwork in the list
384
+ if (!networkFound && wifiNetworks .size () > 1 ) {
385
+ Network fallbackNetwork = wifiNetworks .get (wifiNetworks .size () - 1 ); // Get last network from the list
386
+ currentNetwork .setNetwork (fallbackNetwork );
387
+ cm .bindProcessToNetwork (fallbackNetwork );
388
+ }
389
+ }
390
+ }
391
+
392
+ // Fallback 2 -> if no matching network is found try select last wifiNetwork in the list
393
+ if (!networkFound && wifiNetworks .size () > 1 ) {
394
+ Network fallbackNetwork = wifiNetworks .get (wifiNetworks .size () - 1 ); // Get last network from the list
395
+ currentNetwork .setNetwork (fallbackNetwork );
396
+ cm .bindProcessToNetwork (fallbackNetwork );
307
397
}
308
- } else {
309
- awaitingNetwork .countDown (); // Stop waiting
310
398
}
399
+
400
+ awaitingNetwork .countDown (); // Stop waiting
311
401
} else {
312
402
awaitingNetwork .countDown (); // Stop waiting
313
403
}
@@ -327,8 +417,6 @@ public void run() {
327
417
awaitingNetwork .await ();
328
418
}
329
419
330
- // REQUEST NETWORK
331
-
332
420
/**
333
421
* Returns a network given its interface name:
334
422
* "wifi" -> WIFI
0 commit comments