All Downloads are FREE. Search and download functionalities are using the official Maven repository.

eu.hgross.blaubot.ethernet.BlaubotEthernetConnector Maven / Gradle / Ivy

Go to download

An easy to use publish/subscribe middleware to create and communicate through dynamically created adhoc networks.

There is a newer version: 2.0.0-beta.2
Show newest version
package eu.hgross.blaubot.ethernet;

import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.List;

import eu.hgross.blaubot.core.IBlaubotAdapter;
import eu.hgross.blaubot.core.IBlaubotConnection;
import eu.hgross.blaubot.core.IBlaubotDevice;
import eu.hgross.blaubot.core.acceptor.ConnectionMetaDataDTO;
import eu.hgross.blaubot.core.acceptor.IBlaubotIncomingConnectionListener;
import eu.hgross.blaubot.core.acceptor.discovery.BeaconMessage;
import eu.hgross.blaubot.core.acceptor.discovery.IBlaubotBeaconStore;
import eu.hgross.blaubot.core.connector.IBlaubotConnector;
import eu.hgross.blaubot.core.connector.IncompatibleBlaubotDeviceException;
import eu.hgross.blaubot.core.statemachine.BlaubotAdapterHelper;
import eu.hgross.blaubot.util.Log;

/**
 * Connector for ethernet
 * 
 * @author Henning Gross 
 *
 */
public class BlaubotEthernetConnector implements IBlaubotConnector {
	private static final String LOG_TAG = "BlaubotEthernetConnector";
    private static final List SUPPORTED_ACCEPTOR_TYPES = Arrays.asList(EthernetConnectionMetaDataDTO.ACCEPTOR_TYPE);
    private final IBlaubotAdapter adapter;
    private final IBlaubotDevice ownDevice;
    private IBlaubotIncomingConnectionListener incomingConnectionListener;
    private IBlaubotBeaconStore beaconStore;

    public BlaubotEthernetConnector(IBlaubotAdapter blaubotEthernetAdapter, IBlaubotDevice ownDevice) {
        this.ownDevice = ownDevice;
		this.adapter = blaubotEthernetAdapter;
	}

    @Override
    public IBlaubotAdapter getAdapter() {
        return adapter;
    }

    @Override
    public void setBeaconStore(IBlaubotBeaconStore beaconStore) {
        this.beaconStore = beaconStore;
    }

    @Override
	public void setIncomingConnectionListener(IBlaubotIncomingConnectionListener acceptorConnectorListener) {
		this.incomingConnectionListener = acceptorConnectorListener;
	}



	@Override
	public IBlaubotConnection connectToBlaubotDevice(IBlaubotDevice blaubotDevice) {
        final String uniqueDeviceID = blaubotDevice.getUniqueDeviceID();
        final List lastKnownConnectionMetaData = beaconStore.getLastKnownConnectionMetaData(uniqueDeviceID);

        if(lastKnownConnectionMetaData == null) {
            if(Log.logErrorMessages()) {
                Log.e(LOG_TAG, "Could not get connection meta data for unique device id " + uniqueDeviceID);
            }
            return null;
        }

        // take the first supported acceptor, if any
        final List supportedAcceptors = BlaubotAdapterHelper.filterBySupportedAcceptorTypes(lastKnownConnectionMetaData, getSupportedAcceptorTypes());
        if(supportedAcceptors.isEmpty()) {
            if(Log.logErrorMessages()) {
                Log.e(LOG_TAG, "No supported acceptors in meta data to connect to " + uniqueDeviceID + " unfiltered list: " + lastKnownConnectionMetaData);
            }
            throw new IncompatibleBlaubotDeviceException(blaubotDevice + " could not get acceptor meta data for this device.");
        }

        EthernetConnectionMetaDataDTO ethernetConnectionMetaData = new EthernetConnectionMetaDataDTO(supportedAcceptors.get(0));
        if (Log.logDebugMessages()) {
            Log.d(LOG_TAG, "Chosen acceptor to connect to: " + ethernetConnectionMetaData);
            Log.d(LOG_TAG, beaconStore.getLastDiscoveryEvent(uniqueDeviceID)+"");
        }

        return connectToBlaubotDevice(blaubotDevice, ethernetConnectionMetaData);
	}

    /**
     * Connects to the given device using the given connection params.
     * This is a specialized method to bypass some validations to enable the re-use of this connector as a delegate.
     *
     * @param blaubotDevice the device to connect to
     * @param ethernetConnectionMetaData the connection meta data to use for the connection
     * @return the connection or null, if failed
     */
    public IBlaubotConnection connectToBlaubotDevice(IBlaubotDevice blaubotDevice, EthernetConnectionMetaDataDTO ethernetConnectionMetaData) {
        int remoteAcceptorPort = ethernetConnectionMetaData.getAcceptorPort();
        final String ipAddress = ethernetConnectionMetaData.getIpAddress();


        // connect - other side is EthernetAcceptor, see there
        Socket remoteSocket = null;
        try {
            try {
                InetAddress remoteAddress = InetAddress.getByName(ipAddress);
                remoteSocket = new Socket(remoteAddress, remoteAcceptorPort) ;

                BlaubotEthernetUtils.sendOwnUniqueIdThroughSocket(ownDevice, remoteSocket);

                BlaubotEthernetConnection connection = new BlaubotEthernetConnection(blaubotDevice, remoteSocket);

                // send our message
                final BeaconMessage currentBeaconMessage = adapter.getBlaubot().getConnectionStateMachine().getBeaconService().getCurrentBeaconMessage();
                connection.write(currentBeaconMessage.toBytes());

                if(incomingConnectionListener != null) {
                    incomingConnectionListener.onConnectionEstablished(connection);
                }
                return connection;
            } catch (UnknownHostException e) {
                if(Log.logErrorMessages()) {
                    Log.e(LOG_TAG, "Could not extract InetAddress from: " + ipAddress);
                }
                throw e;
            }
        } catch (IOException e) {
            if(Log.logWarningMessages()) {
                Log.w(LOG_TAG, "Could not connect or write to " + ipAddress + ":" + remoteAcceptorPort + " (" + e.getMessage() + ")");
            }
            if(remoteSocket != null) {
                try {
                    remoteSocket.close();
                } catch (IOException e1) {
                }
            }
        }
        if(Log.logWarningMessages()) {
            Log.w(LOG_TAG, "Failed to connect to " + ipAddress + ":" + remoteAcceptorPort );
        }
        return null;
    }

    @Override
    public List getSupportedAcceptorTypes() {
        return SUPPORTED_ACCEPTOR_TYPES;
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy