diff --git a/KdeConnect/KdeConnect.iml b/KdeConnect/KdeConnect.iml
index e79ec377..ef070ffd 100644
--- a/KdeConnect/KdeConnect.iml
+++ b/KdeConnect/KdeConnect.iml
@@ -68,6 +68,8 @@
+
+
diff --git a/KdeConnect/build.gradle b/KdeConnect/build.gradle
index e3d81fa5..725bc903 100644
--- a/KdeConnect/build.gradle
+++ b/KdeConnect/build.gradle
@@ -10,6 +10,8 @@ apply plugin: 'android'
dependencies {
compile files('libs/android-support-v4.jar')
+ compile files('libs/mina-core-2.0.7.jar')
+ compile files('libs/slf4j-api-1.6.6.jar')
}
android {
diff --git a/KdeConnect/libs/mina-core-2.0.7.jar b/KdeConnect/libs/mina-core-2.0.7.jar
new file mode 100644
index 00000000..5ec135bb
Binary files /dev/null and b/KdeConnect/libs/mina-core-2.0.7.jar differ
diff --git a/KdeConnect/libs/slf4j-api-1.6.6.jar b/KdeConnect/libs/slf4j-api-1.6.6.jar
new file mode 100644
index 00000000..4c03fa6b
Binary files /dev/null and b/KdeConnect/libs/slf4j-api-1.6.6.jar differ
diff --git a/KdeConnect/src/main/java/org/kde/connect/BackgroundService.java b/KdeConnect/src/main/java/org/kde/connect/BackgroundService.java
index 42183581..621aa88d 100644
--- a/KdeConnect/src/main/java/org/kde/connect/BackgroundService.java
+++ b/KdeConnect/src/main/java/org/kde/connect/BackgroundService.java
@@ -31,25 +31,22 @@ public class BackgroundService extends Service {
PingPackageInterface pingEmitter;
- private void registerEmitters() {
- if (settings.getBoolean("emit_call", true)) {
+ private void registerPackageInterfaces() {
+ if (settings.getBoolean("call_interface", true)) {
emitters.add(new CallPackageInterface(getApplicationContext()));
}
- if (settings.getBoolean("emit_ping", true)) {
+ if (settings.getBoolean("ping_interface", true)) {
emitters.add(pingEmitter);
}
- if (settings.getBoolean("emit_clipboard", true)) {
+ if (settings.getBoolean("clipboard_interface", true)) {
emitters.add(new ClipboardPackageInterface(getApplicationContext()));
}
}
- public void registerAnnouncers() {
- /*if (settings.getBoolean("announce_avahi", true)) {
- locators.add(new AvahiLinkProvider(this));
- }*/
- if (settings.getBoolean("announce_avahi_tcp", true)) {
+ public void registerLinkProviders() {
+ if (settings.getBoolean("avahitcp_link", true)) {
locators.add(new AvahiTcpLinkProvider(this));
}
}
@@ -65,7 +62,7 @@ public class BackgroundService extends Service {
//This will be called for each intent launch, even if the service is already started and is reused
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
- Log.e("BackgroundService","Running callbacks waiting service to be ready");
+ Log.i("BackgroundService","onStartCommand");
for (InstanceCallback c : callbacks) {
c.onServiceStart(this);
}
@@ -74,19 +71,18 @@ public class BackgroundService extends Service {
}
private void startDiscovery() {
- Log.e("StartDiscovery","Registering connection receivers");
+ Log.i("StartDiscovery","Registering connection receivers");
for (BaseLinkProvider a : locators) {
- Log.e("Registerign", a.toString());
a.reachComputers(new BaseLinkProvider.ConnectionReceiver() {
@Override
public void onConnectionAccepted(String deviceId, String name, BaseComputerLink link) {
- Log.e("BackgroundService", "Connection accepted!");
+ Log.i("BackgroundService", "Connection accepted!");
if (devices.containsKey(deviceId)) {
- Log.e("BackgroundService", "known device");
+ Log.i("BackgroundService", "known device");
devices.get(deviceId).addLink(link);
} else {
- Log.e("BackgroundService", "unknown device");
+ Log.i("BackgroundService", "unknown device");
Device device = new Device(deviceId, name, link);
devices.put(deviceId, device);
for (BasePackageInterface pe : emitters) {
@@ -119,14 +115,14 @@ public class BackgroundService extends Service {
public void onCreate() {
super.onCreate();
- Log.e("BackgroundService","Service not started yet, initializing...");
+ Log.i("BackgroundService","Service not started yet, initializing...");
settings = getSharedPreferences("KdeConnect", 0);
pingEmitter = new PingPackageInterface(getApplicationContext());
- registerEmitters();
- registerAnnouncers();
+ registerPackageInterfaces();
+ registerLinkProviders();
startDiscovery();
}
@@ -138,7 +134,7 @@ public class BackgroundService extends Service {
@Override
public void onDestroy() {
- Log.e("BackgroundService", "Destroying");
+ Log.i("BackgroundService", "Destroying");
super.onDestroy();
}
diff --git a/KdeConnect/src/main/java/org/kde/connect/ComputerLinks/TcpComputerLink.java b/KdeConnect/src/main/java/org/kde/connect/ComputerLinks/TcpComputerLink.java
index 91885fad..53b1f07b 100644
--- a/KdeConnect/src/main/java/org/kde/connect/ComputerLinks/TcpComputerLink.java
+++ b/KdeConnect/src/main/java/org/kde/connect/ComputerLinks/TcpComputerLink.java
@@ -3,142 +3,82 @@ package org.kde.connect.ComputerLinks;
import android.os.AsyncTask;
import android.util.Log;
+import org.apache.mina.core.buffer.SimpleBufferAllocator;
+import org.apache.mina.core.filterchain.IoFilter;
+import org.apache.mina.core.future.ConnectFuture;
+import org.apache.mina.core.service.IoHandlerAdapter;
+import org.apache.mina.core.session.IoSession;
+import org.apache.mina.filter.codec.ProtocolCodecFilter;
+import org.apache.mina.filter.codec.textline.LineDelimiter;
+import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
+import org.apache.mina.filter.keepalive.KeepAliveFilter;
+import org.apache.mina.transport.socket.nio.NioSocketConnector;
import org.kde.connect.LinkProviders.BaseLinkProvider;
import org.kde.connect.NetworkPackage;
import java.net.InetAddress;
import java.net.InetSocketAddress;
-import java.nio.ByteBuffer;
-import java.nio.CharBuffer;
-import java.nio.channels.SelectionKey;
-import java.nio.channels.Selector;
-import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
-import java.nio.charset.CharsetEncoder;
-import java.util.Iterator;
public class TcpComputerLink extends BaseComputerLink {
- private boolean listenign = false;
- private SocketChannel sChannel;
- private Charset charset = Charset.forName("US-ASCII");
+ private IoSession session = null;
- public TcpComputerLink(BaseLinkProvider linkProvider, InetAddress ip, int port) throws java.io.IOException {
+ public TcpComputerLink(BaseLinkProvider linkProvider) {
super(linkProvider);
+ }
- sChannel = SocketChannel.open();
- sChannel.socket().setSoTimeout(0);
- sChannel.socket().setKeepAlive(true);
- sChannel.configureBlocking(false);
- sChannel.connect(new InetSocketAddress(ip, port));
+ public void connect(final InetAddress ip, final int port) {
+
+ final NioSocketConnector connector = new NioSocketConnector();
+ connector.setHandler(new IoHandlerAdapter() {
+ @Override
+ public void messageReceived(IoSession session, Object message) throws Exception {
+ super.messageReceived(session, message);
+ Log.e("TcpComputerLink","messageReceived (" + message.getClass() + ") " + message.toString());
+ try {
+ String theMessage = (String) message;
+ NetworkPackage np = NetworkPackage.unserialize(theMessage);
+ packageReceived(np);
+ } catch (Exception e) {
+ e.printStackTrace();
+ Log.e("TcpComputerLink","Could not unserialize package");
+ }
+ }
+ });
+
+ //TextLineCodecFactory will split incoming data delimited by the given string
+ connector.getFilterChain().addLast("codec",
+ new ProtocolCodecFilter(
+ new TextLineCodecFactory(Charset.forName("UTF-8"), LineDelimiter.UNIX, LineDelimiter.UNIX)
+ )
+ );
+ connector.getSessionConfig().setKeepAlive(true);
+
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ ConnectFuture future = connector.connect(new InetSocketAddress(ip, port));
+ //Wait unit it is connected (this call makes it blocking, but we are on a thread anyway)
+ future.awaitUninterruptibly();
+ if (!future.isConnected()) Log.e("TcpComputerLink","Could not connect");
+ Log.e("TcpComputerLink","connected");
+ session = future.getSession();
+ }
+ }).run();
}
@Override
public boolean sendPackage(NetworkPackage np) {
- Log.e("TcpComputerLink","sendPackage");
- try {
- String s = np.serialize();
- Log.e("SendPackage",s);
-
- CharsetEncoder enc = charset.newEncoder();
- ByteBuffer bytes = enc.encode(CharBuffer.wrap(s));
- Log.e("asdads",""+bytes.array().length);
- int written = sChannel.write(bytes);
-
- Log.e("SendPackage","sent "+written+" bytes");
- } catch(Exception e) {
- Log.e("TcpComputerLink","Exception");
- e.printStackTrace();
+ Log.e("TcpComputerLink", "sendPackage");
+ if (session == null) {
+ Log.e("TcpComputerLink","not yet connected");
+ return false;
+ } else {
+ session.write(np.serialize());
+ return true;
}
- return true;
}
- public void startReceivingPackages() {
- if (listenign) return;
-
- listenign = true;
-
- try {
-
- /*
- Log.e("TcpComputerLink","start receiving packages");
- InputStreamReader reader = new InputStreamReader(socket.getInputStream());
- Log.e("TcpComputerLink","Entering loop");
-
- while (socket.isConnected()) {
- if (serverMessage == null) {
- //wait(100);
- continue;
- }
- NetworkPackage np = NetworkPackage.unserialize(serverMessage);
- Log.e("TcpComputerLink",serverMessage);
- packageReceived(np);
- }*/
-
-
- final Selector selector = Selector.open();
- sChannel.register(selector, SelectionKey.OP_CONNECT + SelectionKey.OP_READ);
-
- new Thread(new Runnable() {
- @Override
- public void run() {
- while (true) {
- try {
- selector.select(); //blocking
- Iterator it = selector.selectedKeys().iterator();
- // Process each key at a time
- while (it.hasNext()) {
- // Get the selection key
- SelectionKey selKey = (SelectionKey)it.next();
-
- // Remove it from the list to indicate that it is being processed
- it.remove();
-
- if (selKey.isValid() && selKey.isConnectable()) {
- // Get channel with connection request
- SocketChannel sChannel = (SocketChannel)selKey.channel();
-
- boolean success = sChannel.finishConnect();
- if (!success) {
- // An error occurred; handle it
-
- // Unregister the channel with this selector
- selKey.cancel();
- }
- }
- if (selKey.isValid() && selKey.isReadable()) {
- // Get channel with bytes to read
-
- SocketChannel sChannel = (SocketChannel)selKey.channel();
-
- ByteBuffer buffer = ByteBuffer.allocate(4096);
- int read = sChannel.read(buffer);
- //TODO: Check if there is more to read (or otherwise if we have read more than one package)
- String s = new String( buffer.array(), 0, read, charset );
- Log.e("readable","Read "+read+" bytes: "+s);
-
- NetworkPackage np = NetworkPackage.unserialize(s);
- packageReceived(np);
-
- }
- }
- } catch (Exception e) {
- Log.e("TcpComputerLink","Inner loop exception");
- e.printStackTrace();
- listenign = false;
- break;
- }
- }
- Log.e("TcpComputerLink","Exiting loop");
- }
- }).run();
-
- } catch (Exception e) {
- Log.e("TcpComputerLink","Exception");
- listenign = false;
- e.printStackTrace();
- }
-
- }
}
diff --git a/KdeConnect/src/main/java/org/kde/connect/ComputerLinks/UdpComputerLink.java b/KdeConnect/src/main/java/org/kde/connect/ComputerLinks/UdpComputerLink.java
deleted file mode 100644
index 27f28202..00000000
--- a/KdeConnect/src/main/java/org/kde/connect/ComputerLinks/UdpComputerLink.java
+++ /dev/null
@@ -1,74 +0,0 @@
-package org.kde.connect.ComputerLinks;
-
-import android.os.AsyncTask;
-import android.util.Log;
-
-import org.kde.connect.LinkProviders.AvahiLinkProvider;
-import org.kde.connect.NetworkPackage;
-
-import java.io.IOException;
-import java.net.DatagramPacket;
-import java.net.DatagramSocket;
-import java.net.InetAddress;
-
-public class UdpComputerLink extends BaseComputerLink {
-
- DatagramSocket socket = null;
- int UDP_PORT;
- InetAddress IP;
-
- final int BUFFER_SIZE = 5*1024;
-
- public UdpComputerLink(AvahiLinkProvider linkProvider, InetAddress ip, int port) throws IOException {
- super(linkProvider);
- UDP_PORT = port;
- IP = ip;
- }
-
- @Override
- public boolean sendPackage(NetworkPackage np) {
- if (socket == null) startReceivingPackages();
- Log.e("UdpComputerLink","sendPackage");
- final String messageStr = np.serialize();
- Log.e("UdpComputerLink", "aboutToSend");
- int msg_length = messageStr.length();
- byte[] message = messageStr.getBytes();
- DatagramPacket p = new DatagramPacket(message, msg_length, IP, UDP_PORT);
- Log.e("UdpComputerLink", "aboutToSend " + IP + ":" + UDP_PORT);
- try {
- socket.send(p);
- } catch (Exception e) {
- Log.e("UdpComputerLink", "Exception!");
- }
- Log.e("UdpComputerLink", "sent");
- return true;
- }
-
- public void startReceivingPackages() {
- try {
- socket = new DatagramSocket(UDP_PORT);
- }catch(Exception e) {
- Log.e("UdpComputerLink","Exception");
- e.printStackTrace();
- }
- Log.e("UdpComputerLink","" + IP + ":" + UDP_PORT);
- new Thread(new Runnable() {
- @Override
- public void run() {
- try {
- Log.e("UdpComputerLink","Waiting for udp datagrams");
- byte[] buffer = new byte[BUFFER_SIZE];
- while(true){
- DatagramPacket packet = new DatagramPacket(buffer, buffer.length );
- socket.receive(packet);
- String s = new String(packet.getData(), 0, packet.getLength());
- packageReceived(NetworkPackage.unserialize(s));
- }
- } catch (java.io.IOException e) {
- Log.e("UdpComputerLink","Exception");
- e.printStackTrace();
- }
- }
- }).run();
- }
-}
diff --git a/KdeConnect/src/main/java/org/kde/connect/LinkProviders/AvahiLinkProvider.java b/KdeConnect/src/main/java/org/kde/connect/LinkProviders/AvahiLinkProvider.java
deleted file mode 100644
index 22f3fd17..00000000
--- a/KdeConnect/src/main/java/org/kde/connect/LinkProviders/AvahiLinkProvider.java
+++ /dev/null
@@ -1,147 +0,0 @@
-package org.kde.connect.LinkProviders;
-
-import android.content.Context;
-import android.net.nsd.NsdManager;
-import android.net.nsd.NsdServiceInfo;
-import android.util.Log;
-
-import org.kde.connect.ComputerLinks.BaseComputerLink;
-import org.kde.connect.ComputerLinks.UdpComputerLink;
-import org.kde.connect.Device;
-import org.kde.connect.NetworkPackage;
-
-import java.lang.Override;
-import java.util.ArrayList;
-
-public class AvahiLinkProvider implements BaseLinkProvider {
-
- String serviceType = "_kdeconnect._udp";
-
- NsdManager mNsdManager;
-
- ArrayList visibleComputers = new ArrayList();
-
- Context ctx;
-
- private NsdManager.DiscoveryListener oldListener = null;
-
- public AvahiLinkProvider(Context context) {
- mNsdManager = (NsdManager)context.getSystemService(Context.NSD_SERVICE);
- ctx = context;
- }
-
- @Override
- public void reachComputers(final ConnectionReceiver cr) {
-
- visibleComputers.clear();
-
- if (oldListener != null) mNsdManager.stopServiceDiscovery(oldListener);
-
- Log.e("AvahiLinkProvider", "Discovering computers...");
-
- final NsdManager.ResolveListener mResolveListener = new NsdManager.ResolveListener() {
-
- @Override
- public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) {
- Log.e("AvahiLinkProvider", "Resolve failed: " + errorCode);
- }
-
- @Override
- public void onServiceResolved(final NsdServiceInfo serviceInfo) {
- Log.e("AvahiLinkProvider", "Resolve Succeeded: " + serviceInfo);
-
- //Handshake link
- try {
- UdpComputerLink link = new UdpComputerLink(AvahiLinkProvider.this,serviceInfo.getHost(),serviceInfo.getPort());
- link.addPackageReceiver(new BaseComputerLink.PackageReceiver() {
- @Override
- public void onPackageReceived(NetworkPackage np) {
- Log.e("AvahiLinkProvider","Received reply");
- if (np.getType().equals(NetworkPackage.PACKAGE_TYPE_IDENTITY)) {
- String id = np.getString("deviceId");
- String name = np.getString("deviceName");
- //Real data link
- try {
- UdpComputerLink link2 = new UdpComputerLink(AvahiLinkProvider.this,serviceInfo.getHost(),10603);
- visibleComputers.add(link2);
- cr.onConnectionAccepted(id, name, link2);
- } catch (Exception e) {
-
- }
- } else {
- Log.e("AvahiLinkProvider","Received non-identity package");
- }
- }
- });
- link.startReceivingPackages();
- Log.e("AvahiLinkProvider","Sending identity package");
- NetworkPackage np = NetworkPackage.createIdentityPackage(ctx);
- link.sendPackage(np);
- } catch (Exception e) {
-
- }
- }
-
- };
-
- NsdManager.DiscoveryListener mDiscoveryListener = new NsdManager.DiscoveryListener() {
-
- @Override
- public void onDiscoveryStarted(String regType) {
- Log.e("AvahiLinkProvider", "Service discovery started");
- }
-
- @Override
- public void onServiceFound(NsdServiceInfo service) {
- Log.e("AvahiLinkProvider", "Service discovery success" + service);
-
- if (!service.getServiceType().startsWith(serviceType)) {
- Log.e("AvahiLinkProvider", "Unknown Service Type: " + service.getServiceType());
- } else {
- Log.e("AvahiLinkProvider", "Computer found, resolving...");
- mNsdManager.resolveService(service, mResolveListener);
- }
-
- }
-
- @Override
- public void onServiceLost(NsdServiceInfo service) {
- Log.e("AvahiLinkProvider", "Service lost: " + service);
- }
-
- @Override
- public void onDiscoveryStopped(String serviceType) {
- Log.e("AvahiLinkProvider", "Discovery stopped: " + serviceType);
- }
-
- @Override
- public void onStartDiscoveryFailed(String serviceType, int errorCode) {
- Log.e("AvahiLinkProvider", "Discovery failed: Error code:" + errorCode);
- mNsdManager.stopServiceDiscovery(this);
- }
-
- @Override
- public void onStopDiscoveryFailed(String serviceType, int errorCode) {
- Log.e("AvahiLinkProvider", "Discovery failed: Error code:" + errorCode);
- mNsdManager.stopServiceDiscovery(this);
- }
- };
-
- oldListener = mDiscoveryListener;
- mNsdManager.discoverServices(serviceType, NsdManager.PROTOCOL_DNS_SD, mDiscoveryListener);
-
- }
-
-
- @Override
- public int getPriority() {
- return 100;
- }
-
-
- @Override
- public String getName() {
- return "AvahiUdpLinkProvider";
- }
-
-}
diff --git a/KdeConnect/src/main/java/org/kde/connect/LinkProviders/AvahiTcpLinkProvider.java b/KdeConnect/src/main/java/org/kde/connect/LinkProviders/AvahiTcpLinkProvider.java
index 360e6325..e5677374 100644
--- a/KdeConnect/src/main/java/org/kde/connect/LinkProviders/AvahiTcpLinkProvider.java
+++ b/KdeConnect/src/main/java/org/kde/connect/LinkProviders/AvahiTcpLinkProvider.java
@@ -54,11 +54,10 @@ public class AvahiTcpLinkProvider implements BaseLinkProvider {
Log.e("AvahiTcpLinkProvider", "Resolve Succeeded. " + serviceInfo);
try {
- Log.e("AvahiTcpLinkProvider", "Creating link");
+ Log.e("AvahiTcpLinkProvider", "Connecting and waiting identity package");
final InetAddress host = serviceInfo.getHost();
final int port = serviceInfo.getPort();
- final TcpComputerLink link = new TcpComputerLink(AvahiTcpLinkProvider.this,host,port);
- Log.e("AvahiTcpLinkProvider", "Waiting identity package");
+ final TcpComputerLink link = new TcpComputerLink(AvahiTcpLinkProvider.this);
link.addPackageReceiver(new BaseComputerLink.PackageReceiver() {
@Override
public void onPackageReceived(NetworkPackage np) {
@@ -77,12 +76,13 @@ public class AvahiTcpLinkProvider implements BaseLinkProvider {
}
visibleComputers.put(host,link);
cr.onConnectionAccepted(id,name,link);
+ link.removePackageReceiver(this);
}
}
});
- link.startReceivingPackages();
+ link.connect(host,port);
} catch (Exception e) {
Log.e("AvahiTcpLinkProvider","Exception");
e.printStackTrace();
diff --git a/KdeConnect/src/main/res/layout/activity_main.xml b/KdeConnect/src/main/res/layout/activity_main.xml
index 0afd3477..dcc73874 100644
--- a/KdeConnect/src/main/res/layout/activity_main.xml
+++ b/KdeConnect/src/main/res/layout/activity_main.xml
@@ -20,12 +20,4 @@
android:id="@+id/listView1"
android:layout_weight="1"/>
-
-
diff --git a/build.gradle b/build.gradle
index 495c5038..f82180e3 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1 +1,2 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
+