package org.deviceconnect.android.deviceplugin.awsiot.udt; import android.util.Log; import com.barchart.udt.net.NetServerSocketUDT; import java.io.IOException; import java.net.InetSocketAddress; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.Executors; public class RelayServer { private static final boolean DEBUG = true; private static final String TAG = "UDT"; private NetServerSocketUDT mAcceptorSocket; private List<SocketTask> mSockets = new ArrayList<>(); private boolean mCloseFlag; private OnRelayServerListener mListener; public RelayServer() { } public void setOnRelayServerListener(final OnRelayServerListener listener) { mListener = listener; } public void open() throws IOException { if (mAcceptorSocket != null) { return; } StunClient client = new StunClient(); if (client.bindingRequest()) { String address = client.getMappedAddress(); int port = client.getMappedPort(); if (mListener != null) { mListener.onRetrievedAddress(address, port); } mAcceptorSocket = new NetServerSocketUDT(); mAcceptorSocket.bind(new InetSocketAddress("0.0.0.0", port), 256); mCloseFlag = false; while (!mCloseFlag) { final SocketTask task = new SocketTask(mAcceptorSocket.accept()); task.setOnSocketTaskListener(mListener); mSockets.add(task); Executors.newSingleThreadExecutor().submit(new Callable<Boolean>() { @Override public Boolean call() { try { return task.execute(); } finally { mSockets.remove(task); } } }); } } else { throw new IOException("Failed to retrieved address from STUN server."); } } public void sendData(final byte[] data) throws IOException { for (SocketTask task : mSockets) { task.sendData(data); } } public void sendData(final byte[] data,final int length) throws IOException { for (SocketTask task : mSockets) { task.sendData(data, length); } } public void sendData(final byte[] data, final int offset, final int length) throws IOException { for (SocketTask task : mSockets) { task.sendData(data, offset, length); } } public void close() throws IOException { if (DEBUG) { Log.i(TAG, "RelayServer#close()"); } mCloseFlag = true; for (SocketTask task : mSockets) { try { task.close(); } catch (IOException e) { if (DEBUG) { Log.w(TAG, "RelayServer#close", e); } } } if (mAcceptorSocket != null) { mAcceptorSocket.close(); } mAcceptorSocket = null; mListener = null; } public interface OnRelayServerListener extends SocketTask.OnSocketTaskListener { void onRetrievedAddress(String address, int port); } }