mirror of
https://github.com/KDE/kdeconnect-android
synced 2025-09-02 15:15:09 +00:00
Move further along with mDNS -- Now able to resolve hostnames and ports
This commit is contained in:
committed by
Albert Vaca Cintora
parent
a63100e5d4
commit
e77978d1d5
@@ -22,10 +22,11 @@
|
|||||||
|
|
||||||
package org.kde.kdeconnect.Backends.MulticastBackend;
|
package org.kde.kdeconnect.Backends.MulticastBackend;
|
||||||
|
|
||||||
import android.annotation.TargetApi;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.net.nsd.NsdManager;
|
import android.net.nsd.NsdManager;
|
||||||
|
import android.net.nsd.NsdManager.RegistrationListener;
|
||||||
|
import android.net.nsd.NsdManager.ResolveListener;
|
||||||
import android.net.nsd.NsdServiceInfo;
|
import android.net.nsd.NsdServiceInfo;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.util.Base64;
|
import android.util.Base64;
|
||||||
@@ -67,8 +68,11 @@ public class MulticastLinkProvider extends BaseLinkProvider implements Multicast
|
|||||||
|
|
||||||
static final String LOG_TAG = "MulticastLink";
|
static final String LOG_TAG = "MulticastLink";
|
||||||
|
|
||||||
|
static final String SERVICE_TYPE = "_kdeconnect._tcp";
|
||||||
|
|
||||||
private NsdManager mNsdManager;
|
private NsdManager mNsdManager;
|
||||||
private NsdManager.RegistrationListener mRegistrationListener;
|
private RegistrationListener mRegistrationListener;
|
||||||
|
private ResolveListener mResolveListener;
|
||||||
private boolean mServiceRegistered = false;
|
private boolean mServiceRegistered = false;
|
||||||
|
|
||||||
private final static int MIN_PORT = 1716;
|
private final static int MIN_PORT = 1716;
|
||||||
@@ -93,7 +97,7 @@ public class MulticastLinkProvider extends BaseLinkProvider implements Multicast
|
|||||||
connectionLost(brokenLink);
|
connectionLost(brokenLink);
|
||||||
}
|
}
|
||||||
|
|
||||||
//They received my UDP broadcast and are connecting to me. The first thing they sned should be their identity.
|
//They received my UDP broadcast and are connecting to me. The first thing they send should be their identity.
|
||||||
private void tcpPacketReceived(Socket socket) {
|
private void tcpPacketReceived(Socket socket) {
|
||||||
|
|
||||||
NetworkPacket networkPacket;
|
NetworkPacket networkPacket;
|
||||||
@@ -116,60 +120,6 @@ public class MulticastLinkProvider extends BaseLinkProvider implements Multicast
|
|||||||
identityPacketReceived(networkPacket, socket, MulticastLink.ConnectionStarted.Locally);
|
identityPacketReceived(networkPacket, socket, MulticastLink.ConnectionStarted.Locally);
|
||||||
}
|
}
|
||||||
|
|
||||||
//I've received their broadcast and should connect to their TCP socket and send my identity.
|
|
||||||
private void udpPacketReceived(DatagramPacket packet) {
|
|
||||||
|
|
||||||
final InetAddress address = packet.getAddress();
|
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
String message = new String(packet.getData(), StringsHelper.UTF8);
|
|
||||||
final NetworkPacket identityPacket = NetworkPacket.unserialize(message);
|
|
||||||
final String deviceId = identityPacket.getString("deviceId");
|
|
||||||
if (!identityPacket.getType().equals(NetworkPacket.PACKET_TYPE_IDENTITY)) {
|
|
||||||
Log.e(LOG_TAG, "Expecting an UDP identity package");
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
String myId = DeviceHelper.getDeviceId(context);
|
|
||||||
if (deviceId.equals(myId)) {
|
|
||||||
//Ignore my own broadcast
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Log.i(LOG_TAG, "Broadcast identity package 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, MulticastLink.ConnectionStarted.Remotely);
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e(LOG_TAG, "Cannot connect to " + address, e);
|
|
||||||
if (!reverseConnectionBlackList.contains(address)) {
|
|
||||||
Log.w(LOG_TAG, "Blacklisting " + address);
|
|
||||||
reverseConnectionBlackList.add(address);
|
|
||||||
new Timer().schedule(new TimerTask() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
reverseConnectionBlackList.remove(address);
|
|
||||||
}
|
|
||||||
}, 5 * 1000);
|
|
||||||
|
|
||||||
// Try to cause a reverse connection
|
|
||||||
onNetworkChange();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void configureSocket(Socket socket) {
|
private void configureSocket(Socket socket) {
|
||||||
try {
|
try {
|
||||||
socket.setKeepAlive(true);
|
socket.setKeepAlive(true);
|
||||||
@@ -334,7 +284,7 @@ public class MulticastLinkProvider extends BaseLinkProvider implements Multicast
|
|||||||
throw new RuntimeException("This should not be reachable");
|
throw new RuntimeException("This should not be reachable");
|
||||||
}
|
}
|
||||||
|
|
||||||
@TargetApi(16)
|
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
|
||||||
public void initializeRegistrationListener() {
|
public void initializeRegistrationListener() {
|
||||||
mRegistrationListener = new NsdManager.RegistrationListener() {
|
mRegistrationListener = new NsdManager.RegistrationListener() {
|
||||||
|
|
||||||
@@ -343,7 +293,7 @@ public class MulticastLinkProvider extends BaseLinkProvider implements Multicast
|
|||||||
// Save the service name. Android may have changed it in order to
|
// Save the service name. Android may have changed it in order to
|
||||||
// resolve a conflict, so update the name you initially requested
|
// resolve a conflict, so update the name you initially requested
|
||||||
// with the name Android actually used.
|
// with the name Android actually used.
|
||||||
Log.w(LOG_TAG, "Registered " + NsdServiceInfo.getServiceName());
|
Log.i(LOG_TAG, "Registered " + NsdServiceInfo.getServiceName());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -368,13 +318,13 @@ public class MulticastLinkProvider extends BaseLinkProvider implements Multicast
|
|||||||
}
|
}
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
|
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
|
||||||
public void initializeNsdManager() {
|
public void initializeNsdManager(RegistrationListener registrationListener) {
|
||||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mNsdManager = (NsdManager) context.getSystemService(Context.NSD_SERVICE);
|
mNsdManager = (NsdManager) context.getSystemService(Context.NSD_SERVICE);
|
||||||
try {
|
try {
|
||||||
mNsdManager.unregisterService(mRegistrationListener);
|
mNsdManager.unregisterService(registrationListener);
|
||||||
} catch (java.lang.IllegalArgumentException e) {
|
} catch (java.lang.IllegalArgumentException e) {
|
||||||
// not yet registered, but it's fine.
|
// not yet registered, but it's fine.
|
||||||
}
|
}
|
||||||
@@ -398,15 +348,75 @@ public class MulticastLinkProvider extends BaseLinkProvider implements Multicast
|
|||||||
// some kind of encoding that is too large for the TXT record
|
// some kind of encoding that is too large for the TXT record
|
||||||
|
|
||||||
serviceInfo.setServiceName("KDE Connect on " + myIdentity.getString("deviceName"));
|
serviceInfo.setServiceName("KDE Connect on " + myIdentity.getString("deviceName"));
|
||||||
serviceInfo.setServiceType("_kdeconnect._tcp");
|
serviceInfo.setServiceType(SERVICE_TYPE);
|
||||||
serviceInfo.setHost(addr);
|
serviceInfo.setHost(addr);
|
||||||
serviceInfo.setPort(port);
|
serviceInfo.setPort(port);
|
||||||
|
|
||||||
//Log.d("KDE/Lan", "service: " + serviceInfo.toString());
|
//Log.d("KDE/Lan", "service: " + serviceInfo.toString());
|
||||||
|
|
||||||
|
mNsdManager.registerService(serviceInfo, NsdManager.PROTOCOL_DNS_SD, registrationListener);
|
||||||
|
}
|
||||||
|
|
||||||
mNsdManager.registerService(
|
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
|
||||||
serviceInfo, NsdManager.PROTOCOL_DNS_SD, mRegistrationListener);
|
public ResolveListener initializeResolveListener() {
|
||||||
|
return new ResolveListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResolveFailed(NsdServiceInfo serviceInfo, int i) {
|
||||||
|
Log.e(LOG_TAG, "Could not resolve service: " + serviceInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onServiceResolved(NsdServiceInfo serviceInfo) {
|
||||||
|
Log.i(LOG_TAG, "Successfully resolved " + serviceInfo);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
|
||||||
|
public void initializeDiscoveryListener() {
|
||||||
|
// Instantiate a new DiscoveryListener
|
||||||
|
NsdManager.DiscoveryListener discoveryListener = new NsdManager.DiscoveryListener() {
|
||||||
|
|
||||||
|
// Called as soon as service discovery begins.
|
||||||
|
@Override
|
||||||
|
public void onDiscoveryStarted(String regType) {
|
||||||
|
Log.d(LOG_TAG, "Service discovery started");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onServiceFound(NsdServiceInfo service) {
|
||||||
|
// A service was found! Do something with it.
|
||||||
|
Log.d(LOG_TAG, "Service discovery success" + service);
|
||||||
|
mNsdManager.resolveService(service, mResolveListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onServiceLost(NsdServiceInfo service) {
|
||||||
|
// When the network service is no longer available.
|
||||||
|
// Internal bookkeeping code goes here.
|
||||||
|
Log.e(LOG_TAG, "service lost: " + service);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDiscoveryStopped(String serviceType) {
|
||||||
|
Log.i(LOG_TAG, "Discovery stopped: " + serviceType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStartDiscoveryFailed(String serviceType, int errorCode) {
|
||||||
|
Log.e(LOG_TAG, "Discovery failed: Error code:" + errorCode);
|
||||||
|
mNsdManager.stopServiceDiscovery(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStopDiscoveryFailed(String serviceType, int errorCode) {
|
||||||
|
Log.e(LOG_TAG, "Discovery failed: Error code:" + errorCode);
|
||||||
|
mNsdManager.stopServiceDiscovery(this);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
mNsdManager.discoverServices(SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, discoveryListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -424,8 +434,11 @@ public class MulticastLinkProvider extends BaseLinkProvider implements Multicast
|
|||||||
setupTcpListener();
|
setupTcpListener();
|
||||||
|
|
||||||
initializeRegistrationListener();
|
initializeRegistrationListener();
|
||||||
|
mResolveListener = initializeResolveListener();
|
||||||
|
|
||||||
initializeNsdManager();
|
initializeNsdManager(mRegistrationListener);
|
||||||
|
|
||||||
|
initializeDiscoveryListener();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -435,12 +448,14 @@ public class MulticastLinkProvider extends BaseLinkProvider implements Multicast
|
|||||||
// This backend does not work on older Android versions
|
// This backend does not work on older Android versions
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (mNsdManager != null) {
|
||||||
|
mNsdManager.unregisterService(mRegistrationListener);
|
||||||
|
}
|
||||||
|
|
||||||
if (NetworkHelper.isOnMobileNetwork(context)) {
|
if (NetworkHelper.isOnMobileNetwork(context)) {
|
||||||
Log.i("LanLinkProvider", "On 3G network, disabling mDNS advertisements.");
|
Log.i("LanLinkProvider", "On 3G network, disabling mDNS advertisements.");
|
||||||
mNsdManager.unregisterService(mRegistrationListener);
|
|
||||||
} else {
|
} else {
|
||||||
this.initializeNsdManager();
|
this.initializeRegistrationListener();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -452,11 +467,7 @@ public class MulticastLinkProvider extends BaseLinkProvider implements Multicast
|
|||||||
}
|
}
|
||||||
|
|
||||||
listening = false;
|
listening = false;
|
||||||
try {
|
mNsdManager.unregisterService(mRegistrationListener);
|
||||||
mNsdManager.unregisterService(mRegistrationListener);
|
|
||||||
} catch(Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
Reference in New Issue
Block a user