mirror of
https://github.com/KDE/kdeconnect-android
synced 2025-08-22 18:07:55 +00:00
Dynamic tcp port change when bind fails
This commit is contained in:
parent
ec7333dc9a
commit
27f7e54c7f
@ -238,6 +238,7 @@ public class BackgroundService extends Service {
|
|||||||
@Override
|
@Override
|
||||||
public void onDestroy() {
|
public void onDestroy() {
|
||||||
Log.i("BackgroundService", "Destroying");
|
Log.i("BackgroundService", "Destroying");
|
||||||
|
stopDiscovery();
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,6 +25,11 @@ public class NioSessionComputerLink extends BaseComputerLink {
|
|||||||
|
|
||||||
private IoSession session = null;
|
private IoSession session = null;
|
||||||
|
|
||||||
|
public void disconnect() {
|
||||||
|
Log.e("NioSessionComputerLink","Disconnect: "+session.getRemoteAddress().toString());
|
||||||
|
session.close(true);
|
||||||
|
}
|
||||||
|
|
||||||
public NioSessionComputerLink(IoSession session, String deviceId, BaseLinkProvider linkProvider) {
|
public NioSessionComputerLink(IoSession session, String deviceId, BaseLinkProvider linkProvider) {
|
||||||
super(deviceId, linkProvider);
|
super(deviceId, linkProvider);
|
||||||
this.session = session;
|
this.session = session;
|
||||||
|
@ -64,6 +64,10 @@ public class BroadcastTcpLinkProvider extends BaseLinkProvider {
|
|||||||
NioSessionComputerLink prevLink = nioSessions.get(session.getId());
|
NioSessionComputerLink prevLink = nioSessions.get(session.getId());
|
||||||
|
|
||||||
if (np.getType().equals(NetworkPackage.PACKAGE_TYPE_IDENTITY)) {
|
if (np.getType().equals(NetworkPackage.PACKAGE_TYPE_IDENTITY)) {
|
||||||
|
String myId = NetworkPackage.createIdentityPackage(context).getString("deviceId");
|
||||||
|
if (np.getString("deviceId").equals(myId)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
NioSessionComputerLink link = new NioSessionComputerLink(session, np.getString("deviceId"), BroadcastTcpLinkProvider.this);
|
NioSessionComputerLink link = new NioSessionComputerLink(session, np.getString("deviceId"), BroadcastTcpLinkProvider.this);
|
||||||
nioSessions.put(session.getId(),link);
|
nioSessions.put(session.getId(),link);
|
||||||
addLink(np, link);
|
addLink(np, link);
|
||||||
@ -78,50 +82,7 @@ public class BroadcastTcpLinkProvider extends BaseLinkProvider {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private void addLink(NetworkPackage identityPackage, NioSessionComputerLink link) {
|
private IoHandler udpHandler = new IoHandlerAdapter() {
|
||||||
Log.e("BroadcastTcpLinkProvider","addLink to "+identityPackage.getString("deviceName"));
|
|
||||||
String deviceId = identityPackage.getString("deviceId");
|
|
||||||
BaseComputerLink oldLink = visibleComputers.get(deviceId);
|
|
||||||
if (oldLink != null) {
|
|
||||||
Log.e("BroadcastTcpLinkProvider","Removing old connection to same device");
|
|
||||||
connectionLost(oldLink);
|
|
||||||
}
|
|
||||||
visibleComputers.put(deviceId, link);
|
|
||||||
connectionAccepted(identityPackage, link);
|
|
||||||
}
|
|
||||||
|
|
||||||
public BroadcastTcpLinkProvider(Context context) {
|
|
||||||
|
|
||||||
this.context = context;
|
|
||||||
|
|
||||||
//This handles the case when I'm the new device in the network and somebody answers my introduction package
|
|
||||||
tcpAcceptor = new NioSocketAcceptor();
|
|
||||||
tcpAcceptor.setHandler(tcpHandler);
|
|
||||||
tcpAcceptor.getSessionConfig().setKeepAlive(true);
|
|
||||||
//TextLineCodecFactory will split incoming data delimited by the given string
|
|
||||||
tcpAcceptor.getFilterChain().addLast("codec",
|
|
||||||
new ProtocolCodecFilter(
|
|
||||||
new TextLineCodecFactory(Charset.defaultCharset(), LineDelimiter.UNIX, LineDelimiter.UNIX)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
try {
|
|
||||||
tcpAcceptor.getSessionConfig().setReuseAddress(true);
|
|
||||||
tcpAcceptor.bind(new InetSocketAddress(port));
|
|
||||||
} catch(Exception e) {
|
|
||||||
Log.e("BroadcastTcpLinkProvider", "Error: Could not bind tcp socket");
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStart() {
|
|
||||||
|
|
||||||
//This handles the case when I'm the existing device in the network and receive a "hello" UDP package
|
|
||||||
udpAcceptor = new NioDatagramAcceptor();
|
|
||||||
udpAcceptor.getSessionConfig().setReuseAddress(true); //Share port if existing
|
|
||||||
udpAcceptor.setHandler(new IoHandlerAdapter() {
|
|
||||||
@Override
|
@Override
|
||||||
public void messageReceived(IoSession udpSession, Object message) throws Exception {
|
public void messageReceived(IoSession udpSession, Object message) throws Exception {
|
||||||
super.messageReceived(udpSession, message);
|
super.messageReceived(udpSession, message);
|
||||||
@ -147,13 +108,14 @@ public class BroadcastTcpLinkProvider extends BaseLinkProvider {
|
|||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
String myId = NetworkPackage.createIdentityPackage(context).getString("deviceId");
|
String myId = NetworkPackage.createIdentityPackage(context).getString("deviceId");
|
||||||
if (np.getType().equals(myId)) {
|
if (np.getString("deviceId").equals(myId)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.e("BroadcastTcpLinkProvider", "It is an identity package, creating link");
|
Log.e("BroadcastTcpLinkProvider", "It is an identity package, creating link");
|
||||||
|
|
||||||
|
try {
|
||||||
final InetSocketAddress address = (InetSocketAddress) udpSession.getRemoteAddress();
|
final InetSocketAddress address = (InetSocketAddress) udpSession.getRemoteAddress();
|
||||||
|
|
||||||
final NioSocketConnector connector = new NioSocketConnector();
|
final NioSocketConnector connector = new NioSocketConnector();
|
||||||
@ -166,7 +128,8 @@ public class BroadcastTcpLinkProvider extends BaseLinkProvider {
|
|||||||
);
|
);
|
||||||
connector.getSessionConfig().setKeepAlive(true);
|
connector.getSessionConfig().setKeepAlive(true);
|
||||||
|
|
||||||
ConnectFuture future = connector.connect(new InetSocketAddress(address.getAddress(), port));
|
int tcpPort = np.getInt("tcpPort",port);
|
||||||
|
ConnectFuture future = connector.connect(new InetSocketAddress(address.getAddress(), tcpPort));
|
||||||
future.addListener(new IoFutureListener<IoFuture>() {
|
future.addListener(new IoFutureListener<IoFuture>() {
|
||||||
@Override
|
@Override
|
||||||
public void operationComplete(IoFuture ioFuture) {
|
public void operationComplete(IoFuture ioFuture) {
|
||||||
@ -184,16 +147,63 @@ public class BroadcastTcpLinkProvider extends BaseLinkProvider {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
} catch (Exception e) {
|
||||||
|
Log.e("BroadcastTcpLinkProvider","Exception!!");
|
||||||
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private void addLink(NetworkPackage identityPackage, NioSessionComputerLink link) {
|
||||||
|
Log.e("BroadcastTcpLinkProvider","addLink to "+identityPackage.getString("deviceName"));
|
||||||
|
String deviceId = identityPackage.getString("deviceId");
|
||||||
|
BaseComputerLink oldLink = visibleComputers.get(deviceId);
|
||||||
|
if (oldLink != null) {
|
||||||
|
Log.e("BroadcastTcpLinkProvider","Removing old connection to same device");
|
||||||
|
connectionLost(oldLink);
|
||||||
|
}
|
||||||
|
visibleComputers.put(deviceId, link);
|
||||||
|
connectionAccepted(identityPackage, link);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BroadcastTcpLinkProvider(Context context) {
|
||||||
|
|
||||||
|
this.context = context;
|
||||||
|
|
||||||
|
//This handles the case when I'm the new device in the network and somebody answers my introduction package
|
||||||
|
tcpAcceptor = new NioSocketAcceptor();
|
||||||
|
tcpAcceptor.setHandler(tcpHandler);
|
||||||
|
tcpAcceptor.getSessionConfig().setKeepAlive(true);
|
||||||
|
tcpAcceptor.getSessionConfig().setReuseAddress(true);
|
||||||
|
tcpAcceptor.setCloseOnDeactivation(false);
|
||||||
|
//TextLineCodecFactory will split incoming data delimited by the given string
|
||||||
|
tcpAcceptor.getFilterChain().addLast("codec",
|
||||||
|
new ProtocolCodecFilter(
|
||||||
|
new TextLineCodecFactory(Charset.defaultCharset(), LineDelimiter.UNIX, LineDelimiter.UNIX)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
udpAcceptor = new NioDatagramAcceptor();
|
||||||
|
udpAcceptor.getSessionConfig().setReuseAddress(true); //Share port if existing
|
||||||
//TextLineCodecFactory will split incoming data delimited by the given string
|
//TextLineCodecFactory will split incoming data delimited by the given string
|
||||||
udpAcceptor.getFilterChain().addLast("codec",
|
udpAcceptor.getFilterChain().addLast("codec",
|
||||||
new ProtocolCodecFilter(
|
new ProtocolCodecFilter(
|
||||||
new TextLineCodecFactory(Charset.defaultCharset(), LineDelimiter.UNIX, LineDelimiter.UNIX)
|
new TextLineCodecFactory(Charset.defaultCharset(), LineDelimiter.UNIX, LineDelimiter.UNIX)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStart() {
|
||||||
|
|
||||||
|
//This handles the case when I'm the existing device in the network and receive a "hello" UDP package
|
||||||
|
|
||||||
|
udpAcceptor.setHandler(udpHandler);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
udpAcceptor.bind(new InetSocketAddress(port));
|
udpAcceptor.bind(new InetSocketAddress(port));
|
||||||
} catch(Exception e) {
|
} catch(Exception e) {
|
||||||
@ -201,25 +211,29 @@ public class BroadcastTcpLinkProvider extends BaseLinkProvider {
|
|||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
onNetworkChange();
|
boolean success = false;
|
||||||
|
int tcpPort = port;
|
||||||
|
while(!success) {
|
||||||
|
try {
|
||||||
|
tcpAcceptor.bind(new InetSocketAddress(tcpPort));
|
||||||
|
success = true;
|
||||||
|
} catch(Exception e) {
|
||||||
|
tcpPort++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
Log.e("BroadcastTcpLinkProvider","Using tcpPort "+tcpPort);
|
||||||
public void onNetworkChange() {
|
|
||||||
|
|
||||||
Log.e("BroadcastTcpLinkProvider","OnNetworkChange: " + (udpAcceptor != null));
|
|
||||||
|
|
||||||
if (udpAcceptor == null) return;
|
|
||||||
|
|
||||||
//I'm on a new network, let's be polite and introduce myself
|
//I'm on a new network, let's be polite and introduce myself
|
||||||
|
final int finalTcpPort = tcpPort;
|
||||||
new AsyncTask<Void,Void,Void>() {
|
new AsyncTask<Void,Void,Void>() {
|
||||||
@Override
|
@Override
|
||||||
protected Void doInBackground(Void... voids) {
|
protected Void doInBackground(Void... voids) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String s = NetworkPackage.createIdentityPackage(context).serialize();
|
NetworkPackage identity = NetworkPackage.createIdentityPackage(context);
|
||||||
byte[] b = s.getBytes("UTF-8");
|
identity.set("tcpPort",finalTcpPort);
|
||||||
|
byte[] b = identity.serialize().getBytes("UTF-8");
|
||||||
DatagramPacket packet = new DatagramPacket(b, b.length, InetAddress.getByAddress(new byte[]{-1,-1,-1,-1}), port);
|
DatagramPacket packet = new DatagramPacket(b, b.length, InetAddress.getByAddress(new byte[]{-1,-1,-1,-1}), port);
|
||||||
DatagramSocket socket = new DatagramSocket();
|
DatagramSocket socket = new DatagramSocket();
|
||||||
socket.setReuseAddress(true);
|
socket.setReuseAddress(true);
|
||||||
@ -232,18 +246,28 @@ public class BroadcastTcpLinkProvider extends BaseLinkProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}.execute();
|
}.execute();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNetworkChange() {
|
||||||
|
|
||||||
|
Log.e("BroadcastTcpLinkProvider","OnNetworkChange: " + (udpAcceptor != null));
|
||||||
|
|
||||||
|
onStop();
|
||||||
|
onStart();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onStop() {
|
public void onStop() {
|
||||||
|
|
||||||
if (udpAcceptor != null) {
|
|
||||||
udpAcceptor.unbind();
|
udpAcceptor.unbind();
|
||||||
udpAcceptor = null;
|
tcpAcceptor.unbind();
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user