Skip to content

Commit 4284f91

Browse files
smartmedevnicpaola
andauthored
feat: Added compatibility for concurrenct connections for Android 15 (#206)
Co-authored-by: Nicola Paola <[email protected]>
1 parent f33522e commit 4284f91

File tree

1 file changed

+119
-31
lines changed

1 file changed

+119
-31
lines changed

android/src/main/java/com/asterinet/react/tcpsocket/TcpSocketModule.java

+119-31
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,15 @@
2424

2525
import java.io.IOException;
2626
import java.net.Inet4Address;
27+
import java.net.Inet6Address;
28+
import java.net.InetAddress;
29+
import java.net.NetworkInterface;
30+
import java.net.SocketException;
2731
import java.util.ArrayList;
32+
import java.util.Enumeration;
33+
import java.util.HashMap;
2834
import java.util.List;
35+
import java.util.Map;
2936
import java.util.Objects;
3037
import java.util.concurrent.ConcurrentHashMap;
3138
import java.util.concurrent.CountDownLatch;
@@ -263,51 +270,134 @@ public void onUnavailable() {
263270
}
264271
}
265272

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+
266288
// Check exist at least one newtwork based on selected transport type
267289
if (!wifiNetworks.isEmpty()) {
268290
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+
286306
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)) {
294313
// found ioT device network
295314
currentNetwork.setNetwork(network);
296315
cm.bindProcessToNetwork(network);
297316
networkFound = true;
298-
awaitingNetwork.countDown(); // Stop waiting
299317
break;
300318
}
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+
}
301351
}
302352
}
303353
}
304354
}
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);
307397
}
308-
} else {
309-
awaitingNetwork.countDown(); // Stop waiting
310398
}
399+
400+
awaitingNetwork.countDown(); // Stop waiting
311401
} else {
312402
awaitingNetwork.countDown(); // Stop waiting
313403
}
@@ -327,8 +417,6 @@ public void run() {
327417
awaitingNetwork.await();
328418
}
329419

330-
// REQUEST NETWORK
331-
332420
/**
333421
* Returns a network given its interface name:
334422
* "wifi" -> WIFI

0 commit comments

Comments
 (0)