mirror of
https://github.com/KDE/kdeconnect-android
synced 2025-08-22 18:07:55 +00:00
Better exception handling in LanLinkProvider
Bubble up exceptions instead of using giant, generic try-catch blocks. The UDP and TCP listener loops are now where we catch all the exceptions that might happen handling the incoming packets. Also, the creation of worker threads now happens in the listener loops as well instead of the inner functions. Finally the `broadcastUdpPacket` function has been split in `broadcastUdpIdentityPacket` and `sendUdpIdentityPacket` (the first calls the second).
This commit is contained in:
parent
8eb35028a1
commit
41e296b16d
@ -11,6 +11,9 @@ import android.content.SharedPreferences;
|
|||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import androidx.annotation.WorkerThread;
|
||||||
|
|
||||||
|
import org.json.JSONException;
|
||||||
import org.kde.kdeconnect.Backends.BaseLink;
|
import org.kde.kdeconnect.Backends.BaseLink;
|
||||||
import org.kde.kdeconnect.Backends.BaseLinkProvider;
|
import org.kde.kdeconnect.Backends.BaseLinkProvider;
|
||||||
import org.kde.kdeconnect.Device;
|
import org.kde.kdeconnect.Device;
|
||||||
@ -33,9 +36,11 @@ import java.net.InetSocketAddress;
|
|||||||
import java.net.ServerSocket;
|
import java.net.ServerSocket;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.net.SocketException;
|
import java.net.SocketException;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
import java.security.cert.Certificate;
|
import java.security.cert.Certificate;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import javax.net.SocketFactory;
|
import javax.net.SocketFactory;
|
||||||
import javax.net.ssl.SSLSocket;
|
import javax.net.ssl.SSLSocket;
|
||||||
@ -56,6 +61,8 @@ public class LanLinkProvider extends BaseLinkProvider {
|
|||||||
private final static int MAX_PORT = 1764;
|
private final static int MAX_PORT = 1764;
|
||||||
final static int PAYLOAD_TRANSFER_MIN_PORT = 1739;
|
final static int PAYLOAD_TRANSFER_MIN_PORT = 1739;
|
||||||
|
|
||||||
|
final static int MAX_UDP_PACKET_SIZE = 1024 * 512;
|
||||||
|
|
||||||
private final Context context;
|
private final Context context;
|
||||||
|
|
||||||
private final HashMap<String, LanLink> visibleDevices = new HashMap<>(); //Links by device id
|
private final HashMap<String, LanLink> visibleDevices = new HashMap<>(); //Links by device id
|
||||||
@ -75,7 +82,8 @@ public class LanLinkProvider extends BaseLinkProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//They received my UDP broadcast and are connecting to me. The first thing they send should be their identity packet.
|
//They received my UDP broadcast and are connecting to me. The first thing they send should be their identity packet.
|
||||||
private void tcpPacketReceived(Socket socket) {
|
@WorkerThread
|
||||||
|
private void tcpPacketReceived(Socket socket) throws IOException {
|
||||||
|
|
||||||
NetworkPacket networkPacket;
|
NetworkPacket networkPacket;
|
||||||
try {
|
try {
|
||||||
@ -98,46 +106,39 @@ public class LanLinkProvider extends BaseLinkProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//I've received their broadcast and should connect to their TCP socket and send my identity.
|
//I've received their broadcast and should connect to their TCP socket and send my identity.
|
||||||
private void udpPacketReceived(DatagramPacket packet) {
|
@WorkerThread
|
||||||
|
private void udpPacketReceived(DatagramPacket packet) throws JSONException, IOException {
|
||||||
|
|
||||||
final InetAddress address = packet.getAddress();
|
final InetAddress address = packet.getAddress();
|
||||||
|
|
||||||
try {
|
String message = new String(packet.getData(), Charsets.UTF_8);
|
||||||
|
final NetworkPacket identityPacket = NetworkPacket.unserialize(message);
|
||||||
String message = new String(packet.getData(), Charsets.UTF_8);
|
final String deviceId = identityPacket.getString("deviceId");
|
||||||
final NetworkPacket identityPacket = NetworkPacket.unserialize(message);
|
if (!identityPacket.getType().equals(NetworkPacket.PACKET_TYPE_IDENTITY)) {
|
||||||
final String deviceId = identityPacket.getString("deviceId");
|
Log.e("KDE/LanLinkProvider", "Expecting an UDP identity packet");
|
||||||
if (!identityPacket.getType().equals(NetworkPacket.PACKET_TYPE_IDENTITY)) {
|
return;
|
||||||
Log.e("KDE/LanLinkProvider", "Expecting an UDP identity packet");
|
} else {
|
||||||
|
String myId = DeviceHelper.getDeviceId(context);
|
||||||
|
if (deviceId.equals(myId)) {
|
||||||
|
//Ignore my own broadcast
|
||||||
return;
|
return;
|
||||||
} else {
|
|
||||||
String myId = DeviceHelper.getDeviceId(context);
|
|
||||||
if (deviceId.equals(myId)) {
|
|
||||||
//Ignore my own broadcast
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.i("KDE/LanLinkProvider", "Broadcast identity packet received from " + identityPacket.getString("deviceName"));
|
|
||||||
|
|
||||||
int tcpPort = identityPacket.getInt("tcpPort", MIN_PORT);
|
|
||||||
|
|
||||||
SocketFactory socketFactory = SocketFactory.getDefault();
|
|
||||||
Socket socket = socketFactory.createSocket(address, tcpPort);
|
|
||||||
configureSocket(socket);
|
|
||||||
|
|
||||||
OutputStream out = socket.getOutputStream();
|
|
||||||
NetworkPacket myIdentity = NetworkPacket.createIdentityPacket(context);
|
|
||||||
out.write(myIdentity.serialize().getBytes());
|
|
||||||
out.flush();
|
|
||||||
|
|
||||||
identityPacketReceived(identityPacket, socket, LanLink.ConnectionStarted.Remotely);
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e("KDE/LanLinkProvider", "Cannot connect to " + address, e);
|
|
||||||
// Broadcast our identity packet to see if we get a reverse connection
|
|
||||||
onNetworkChange();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Log.i("KDE/LanLinkProvider", "Broadcast identity packet received from " + identityPacket.getString("deviceName"));
|
||||||
|
|
||||||
|
int tcpPort = identityPacket.getInt("tcpPort", MIN_PORT);
|
||||||
|
|
||||||
|
SocketFactory socketFactory = SocketFactory.getDefault();
|
||||||
|
Socket socket = socketFactory.createSocket(address, tcpPort);
|
||||||
|
configureSocket(socket);
|
||||||
|
|
||||||
|
OutputStream out = socket.getOutputStream();
|
||||||
|
NetworkPacket myIdentity = NetworkPacket.createIdentityPacket(context);
|
||||||
|
out.write(myIdentity.serialize().getBytes());
|
||||||
|
out.flush();
|
||||||
|
|
||||||
|
identityPacketReceived(identityPacket, socket, LanLink.ConnectionStarted.Remotely);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void configureSocket(Socket socket) {
|
private void configureSocket(Socket socket) {
|
||||||
@ -152,6 +153,8 @@ public class LanLinkProvider extends BaseLinkProvider {
|
|||||||
* Called when a new 'identity' packet is received. Those are passed here by
|
* Called when a new 'identity' packet is received. Those are passed here by
|
||||||
* {@link #tcpPacketReceived(Socket)} and {@link #udpPacketReceived(DatagramPacket)}.
|
* {@link #tcpPacketReceived(Socket)} and {@link #udpPacketReceived(DatagramPacket)}.
|
||||||
* <p>
|
* <p>
|
||||||
|
* Should be called on a new thread since it blocks until the handshake is completed.
|
||||||
|
* </p><p>
|
||||||
* If the remote device should be connected, this calls {@link #addLink}.
|
* If the remote device should be connected, this calls {@link #addLink}.
|
||||||
* Otherwise, if there was an Exception, we unpair from that device.
|
* Otherwise, if there was an Exception, we unpair from that device.
|
||||||
* </p>
|
* </p>
|
||||||
@ -160,7 +163,8 @@ public class LanLinkProvider extends BaseLinkProvider {
|
|||||||
* @param socket a new Socket, which should be used to receive packets from the remote device
|
* @param socket a new Socket, which should be used to receive packets from the remote device
|
||||||
* @param connectionStarted which side started this connection
|
* @param connectionStarted which side started this connection
|
||||||
*/
|
*/
|
||||||
private void identityPacketReceived(final NetworkPacket identityPacket, final Socket socket, final LanLink.ConnectionStarted connectionStarted) {
|
@WorkerThread
|
||||||
|
private void identityPacketReceived(final NetworkPacket identityPacket, final Socket socket, final LanLink.ConnectionStarted connectionStarted) throws IOException {
|
||||||
|
|
||||||
String myId = DeviceHelper.getDeviceId(context);
|
String myId = DeviceHelper.getDeviceId(context);
|
||||||
final String deviceId = identityPacket.getString("deviceId");
|
final String deviceId = identityPacket.getString("deviceId");
|
||||||
@ -172,59 +176,43 @@ public class LanLinkProvider extends BaseLinkProvider {
|
|||||||
// If I'm the TCP server I will be the SSL client and viceversa.
|
// If I'm the TCP server I will be the SSL client and viceversa.
|
||||||
final boolean clientMode = (connectionStarted == LanLink.ConnectionStarted.Locally);
|
final boolean clientMode = (connectionStarted == LanLink.ConnectionStarted.Locally);
|
||||||
|
|
||||||
// Do the SSL handshake
|
SharedPreferences preferences = context.getSharedPreferences("trusted_devices", Context.MODE_PRIVATE);
|
||||||
try {
|
boolean isDeviceTrusted = preferences.getBoolean(deviceId, false);
|
||||||
SharedPreferences preferences = context.getSharedPreferences("trusted_devices", Context.MODE_PRIVATE);
|
|
||||||
boolean isDeviceTrusted = preferences.getBoolean(deviceId, false);
|
|
||||||
|
|
||||||
if (isDeviceTrusted && !SslHelper.isCertificateStored(context, deviceId)) {
|
if (isDeviceTrusted && !SslHelper.isCertificateStored(context, deviceId)) {
|
||||||
//Device paired with and old version, we can't use it as we lack the certificate
|
//Device paired with and old version, we can't use it as we lack the certificate
|
||||||
|
Device device = KdeConnect.getInstance().getDevice(deviceId);
|
||||||
|
if (device == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
device.unpair();
|
||||||
|
//Retry as unpaired
|
||||||
|
identityPacketReceived(identityPacket, socket, connectionStarted);
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.i("KDE/LanLinkProvider", "Starting SSL handshake with " + identityPacket.getString("deviceName") + " trusted:" + isDeviceTrusted);
|
||||||
|
|
||||||
|
final SSLSocket sslSocket = SslHelper.convertToSslSocket(context, socket, deviceId, isDeviceTrusted, clientMode);
|
||||||
|
sslSocket.addHandshakeCompletedListener(event -> {
|
||||||
|
String mode = clientMode ? "client" : "server";
|
||||||
|
try {
|
||||||
|
Certificate certificate = event.getPeerCertificates()[0];
|
||||||
|
Log.i("KDE/LanLinkProvider", "Handshake as " + mode + " successful with " + identityPacket.getString("deviceName") + " secured with " + event.getCipherSuite());
|
||||||
|
addLink(deviceId, certificate, identityPacket, sslSocket);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e("KDE/LanLinkProvider", "Handshake as " + mode + " failed with " + identityPacket.getString("deviceName"), e);
|
||||||
Device device = KdeConnect.getInstance().getDevice(deviceId);
|
Device device = KdeConnect.getInstance().getDevice(deviceId);
|
||||||
if (device == null) {
|
if (device == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
device.unpair();
|
device.unpair();
|
||||||
//Retry as unpaired
|
|
||||||
identityPacketReceived(identityPacket, socket, connectionStarted);
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
Log.i("KDE/LanLinkProvider", "Starting SSL handshake with " + identityPacket.getString("deviceName") + " trusted:" + isDeviceTrusted);
|
//Handshake is blocking, so do it on another thread and free this thread to keep receiving new connection
|
||||||
|
Log.d("LanLinkProvider", "Starting handshake");
|
||||||
final SSLSocket sslsocket = SslHelper.convertToSslSocket(context, socket, deviceId, isDeviceTrusted, clientMode);
|
sslSocket.startHandshake();
|
||||||
sslsocket.addHandshakeCompletedListener(event -> {
|
Log.d("LanLinkProvider", "Handshake done");
|
||||||
String mode = clientMode ? "client" : "server";
|
|
||||||
try {
|
|
||||||
Certificate certificate = event.getPeerCertificates()[0];
|
|
||||||
Log.i("KDE/LanLinkProvider", "Handshake as " + mode + " successful with " + identityPacket.getString("deviceName") + " secured with " + event.getCipherSuite());
|
|
||||||
addLink(deviceId, certificate, identityPacket, sslsocket);
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e("KDE/LanLinkProvider", "Handshake as " + mode + " failed with " + identityPacket.getString("deviceName"), e);
|
|
||||||
Device device = KdeConnect.getInstance().getDevice(deviceId);
|
|
||||||
if (device == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
device.unpair();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
//Handshake is blocking, so do it on another thread and free this thread to keep receiving new connection
|
|
||||||
ThreadHelper.execute(() -> {
|
|
||||||
try {
|
|
||||||
synchronized (this) { // FIXME: Why is this needed?
|
|
||||||
sslsocket.startHandshake();
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e("KDE/LanLinkProvider", "Handshake failed with " + identityPacket.getString("deviceName"), e);
|
|
||||||
|
|
||||||
//String[] ciphers = sslsocket.getSupportedCipherSuites();
|
|
||||||
//for (String cipher : ciphers) {
|
|
||||||
// Log.i("SupportedCiphers","cipher: " + cipher);
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e("LanLink", "Exception", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -242,7 +230,6 @@ public class LanLinkProvider extends BaseLinkProvider {
|
|||||||
//Update old link
|
//Update old link
|
||||||
Log.i("KDE/LanLinkProvider", "Reusing same link for device " + deviceId);
|
Log.i("KDE/LanLinkProvider", "Reusing same link for device " + deviceId);
|
||||||
final Socket oldSocket = currentLink.reset(socket);
|
final Socket oldSocket = currentLink.reset(socket);
|
||||||
//Log.e("KDE/LanLinkProvider", "Replacing socket. old: "+ oldSocket.hashCode() + " - new: "+ socket.hashCode());
|
|
||||||
} else {
|
} else {
|
||||||
Log.i("KDE/LanLinkProvider", "Creating a new link for device " + deviceId);
|
Log.i("KDE/LanLinkProvider", "Creating a new link for device " + deviceId);
|
||||||
//Let's create the link
|
//Let's create the link
|
||||||
@ -274,14 +261,19 @@ public class LanLinkProvider extends BaseLinkProvider {
|
|||||||
ThreadHelper.execute(() -> {
|
ThreadHelper.execute(() -> {
|
||||||
Log.i("UdpListener", "Starting UDP listener");
|
Log.i("UdpListener", "Starting UDP listener");
|
||||||
while (listening) {
|
while (listening) {
|
||||||
final int bufferSize = 1024 * 512;
|
|
||||||
byte[] data = new byte[bufferSize];
|
|
||||||
DatagramPacket packet = new DatagramPacket(data, bufferSize);
|
|
||||||
try {
|
try {
|
||||||
|
DatagramPacket packet = new DatagramPacket(new byte[MAX_UDP_PACKET_SIZE], MAX_UDP_PACKET_SIZE);
|
||||||
udpServer.receive(packet);
|
udpServer.receive(packet);
|
||||||
udpPacketReceived(packet);
|
ThreadHelper.execute(() -> {
|
||||||
} catch (Exception e) {
|
try {
|
||||||
|
udpPacketReceived(packet);
|
||||||
|
} catch (JSONException | IOException e) {
|
||||||
|
Log.e("LanLinkProvider", "Exception receiving incoming UDP connection", e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (IOException e) {
|
||||||
Log.e("LanLinkProvider", "UdpReceive exception", e);
|
Log.e("LanLinkProvider", "UdpReceive exception", e);
|
||||||
|
onNetworkChange(); // Trigger a UDP broadcast to try to get them to connect to us instead
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Log.w("UdpListener", "Stopping UDP listener");
|
Log.w("UdpListener", "Stopping UDP listener");
|
||||||
@ -300,7 +292,13 @@ public class LanLinkProvider extends BaseLinkProvider {
|
|||||||
try {
|
try {
|
||||||
Socket socket = tcpServer.accept();
|
Socket socket = tcpServer.accept();
|
||||||
configureSocket(socket);
|
configureSocket(socket);
|
||||||
tcpPacketReceived(socket);
|
ThreadHelper.execute(() -> {
|
||||||
|
try {
|
||||||
|
tcpPacketReceived(socket);
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.e("LanLinkProvider", "Exception receiving incoming TCP connection", e);
|
||||||
|
}
|
||||||
|
});
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.e("LanLinkProvider", "TcpReceive exception", e);
|
Log.e("LanLinkProvider", "TcpReceive exception", e);
|
||||||
}
|
}
|
||||||
@ -329,7 +327,7 @@ public class LanLinkProvider extends BaseLinkProvider {
|
|||||||
throw new RuntimeException("This should not be reachable");
|
throw new RuntimeException("This should not be reachable");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void broadcastUdpPacket() {
|
private void broadcastUdpIdentityPacket() {
|
||||||
if (System.currentTimeMillis() < lastBroadcast + delayBetweenBroadcasts) {
|
if (System.currentTimeMillis() < lastBroadcast + delayBetweenBroadcasts) {
|
||||||
Log.i("LanLinkProvider", "broadcastUdpPacket: relax cowboy");
|
Log.i("LanLinkProvider", "broadcastUdpPacket: relax cowboy");
|
||||||
return;
|
return;
|
||||||
@ -337,57 +335,72 @@ public class LanLinkProvider extends BaseLinkProvider {
|
|||||||
lastBroadcast = System.currentTimeMillis();
|
lastBroadcast = System.currentTimeMillis();
|
||||||
|
|
||||||
ThreadHelper.execute(() -> {
|
ThreadHelper.execute(() -> {
|
||||||
ArrayList<String> iplist = CustomDevicesActivity
|
List<String> ipStringList = CustomDevicesActivity
|
||||||
.getCustomDeviceList(PreferenceManager.getDefaultSharedPreferences(context));
|
.getCustomDeviceList(PreferenceManager.getDefaultSharedPreferences(context));
|
||||||
|
|
||||||
if (TrustedNetworkHelper.isTrustedNetwork(context)) {
|
if (TrustedNetworkHelper.isTrustedNetwork(context)) {
|
||||||
iplist.add("255.255.255.255"); //Default: broadcast.
|
ipStringList.add("255.255.255.255"); //Default: broadcast.
|
||||||
} else {
|
} else {
|
||||||
Log.i("LanLinkProvider", "Current network isn't trusted, not broadcasting");
|
Log.i("LanLinkProvider", "Current network isn't trusted, not broadcasting");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iplist.isEmpty()) {
|
ArrayList<InetAddress> ipList = new ArrayList<>();
|
||||||
return;
|
for (String ip : ipStringList) {
|
||||||
}
|
try {
|
||||||
|
ipList.add(InetAddress.getByName(ip));
|
||||||
NetworkPacket identity = NetworkPacket.createIdentityPacket(context);
|
} catch (UnknownHostException e) {
|
||||||
if (tcpServer == null || !tcpServer.isBound()) {
|
e.printStackTrace();
|
||||||
Log.i("LanLinkProvider", "Won't broadcast UDP packet if TCP socket is not ready yet");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
int port = tcpServer.getLocalPort();
|
|
||||||
identity.set("tcpPort", port);
|
|
||||||
DatagramSocket socket = null;
|
|
||||||
byte[] bytes = null;
|
|
||||||
try {
|
|
||||||
socket = new DatagramSocket();
|
|
||||||
socket.setReuseAddress(true);
|
|
||||||
socket.setBroadcast(true);
|
|
||||||
bytes = identity.serialize().getBytes(Charsets.UTF_8);
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e("KDE/LanLinkProvider", "Failed to create DatagramSocket", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bytes != null) {
|
|
||||||
Log.i("KDE/LanLinkProvider","Sending broadcast to "+iplist.size()+" ips");
|
|
||||||
for (String ipstr : iplist) {
|
|
||||||
try {
|
|
||||||
InetAddress client = InetAddress.getByName(ipstr);
|
|
||||||
socket.send(new DatagramPacket(bytes, bytes.length, client, MIN_PORT));
|
|
||||||
//Log.i("KDE/LanLinkProvider","Udp identity packet sent to address "+client);
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e("KDE/LanLinkProvider", "Sending udp identity packet failed. Invalid address? (" + ipstr + ")", e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (socket != null) {
|
if (ipList.isEmpty()) {
|
||||||
socket.close();
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sendUdpIdentityPacket(ipList);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@WorkerThread
|
||||||
|
public void sendUdpIdentityPacket(List<InetAddress> ipList) {
|
||||||
|
if (tcpServer == null || !tcpServer.isBound()) {
|
||||||
|
Log.i("LanLinkProvider", "Won't broadcast UDP packet if TCP socket is not ready yet");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkPacket identity = NetworkPacket.createIdentityPacket(context);
|
||||||
|
identity.set("tcpPort", tcpServer.getLocalPort());
|
||||||
|
|
||||||
|
byte[] bytes;
|
||||||
|
try {
|
||||||
|
bytes = identity.serialize().getBytes(Charsets.UTF_8);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
Log.e("KDE/LanLinkProvider", "Failed to serialize identity packet", e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DatagramSocket socket;
|
||||||
|
try {
|
||||||
|
socket = new DatagramSocket();
|
||||||
|
socket.setReuseAddress(true);
|
||||||
|
socket.setBroadcast(true);
|
||||||
|
} catch (SocketException e) {
|
||||||
|
Log.e("KDE/LanLinkProvider", "Failed to create DatagramSocket", e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (InetAddress ip : ipList) {
|
||||||
|
try {
|
||||||
|
socket.send(new DatagramPacket(bytes, bytes.length, ip, MIN_PORT));
|
||||||
|
//Log.i("KDE/LanLinkProvider","Udp identity packet sent to address "+client);
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.e("KDE/LanLinkProvider", "Sending udp identity packet failed. Invalid address? (" + ip.toString() + ")", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
socket.close();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onStart() {
|
public void onStart() {
|
||||||
//Log.i("KDE/LanLinkProvider", "onStart");
|
//Log.i("KDE/LanLinkProvider", "onStart");
|
||||||
@ -398,13 +411,13 @@ public class LanLinkProvider extends BaseLinkProvider {
|
|||||||
setupUdpListener();
|
setupUdpListener();
|
||||||
setupTcpListener();
|
setupTcpListener();
|
||||||
|
|
||||||
broadcastUdpPacket();
|
broadcastUdpIdentityPacket();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onNetworkChange() {
|
public void onNetworkChange() {
|
||||||
broadcastUdpPacket();
|
broadcastUdpIdentityPacket();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
Loading…
x
Reference in New Issue
Block a user