Skip to content
Snippets Groups Projects
Antifurto.java 10.3 KiB
Newer Older
  • Learn to ignore specific revisions
  • Elisa Giglio's avatar
    Elisa Giglio committed
    package code;
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.Date;
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    import java.io.BufferedInputStream;
    import java.io.FileInputStream;
    import java.io.FileReader;
    
    import java.security.KeyPair;
    import java.security.KeyStore;
    import java.security.Security;
    import java.security.cert.CertificateFactory;
    import java.security.cert.X509Certificate;
    import javax.net.ssl.KeyManagerFactory;
    import javax.net.ssl.SSLContext;
    import javax.net.ssl.SSLSocketFactory;
    import javax.net.ssl.TrustManagerFactory;
    import org.bouncycastle.jce.provider.BouncyCastleProvider;
    import org.bouncycastle.openssl.PEMDecryptorProvider;
    import org.bouncycastle.openssl.PEMEncryptedKeyPair;
    import org.bouncycastle.openssl.PEMKeyPair;
    import org.bouncycastle.openssl.PEMParser;
    import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
    import org.bouncycastle.openssl.jcajce.JcePEMDecryptorProviderBuilder;
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    
    import org.eclipse.paho.client.mqttv3.MqttClient;
    import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
    import org.eclipse.paho.client.mqttv3.MqttException;
    import org.eclipse.paho.client.mqttv3.MqttMessage;
    import org.eclipse.paho.client.mqttv3.MqttTopic;
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    import org.json.JSONArray;
    import org.json.JSONException;
    import org.json.JSONObject;
    
    public class Antifurto {
    
    	private static String brokerUrl;
    	private String interruttore;
    	private String interruttoreOutputSuono;
    
    	private String nomeOutputAntifurto;
    	private static JSONArray sensori;  // sensori di movimento
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    	private static ArrayList<String> topicsSub;
    	private Date date = new Date();
    	private String clientId = Long.toString(date.getTime()) + "-sub-pub"; // unique client id
    	private Automa automa;
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    	private MqttClient mqttClient;
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    	private static String mqttDomain;
    	private static String mqttSubdomain;
    
    	public static final String PATH_BB = "/home/debian/CONFIG/antifurto";
    	
    	private final String CONF_FILE = PATH_BB + "/res/CONF/conf.json";
    	public static final String CONF_ZONA = PATH_BB + "/res/CONF/zona.json";
    	
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    	public Antifurto(Automa automa) throws JSONException, IOException, MqttException {
    		this.automa = automa;
    
    		JSONObject jsonObject = new JSONObject(Helper.leggiFile(CONF_FILE));
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    		brokerUrl = jsonObject.getString("protocol") + "://" + jsonObject.getString("broker") + ":" + jsonObject.getInt("port");
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    		mqttDomain = jsonObject.getString("mqttDomain");
    		mqttSubdomain = jsonObject.getString("mqttSubdomain");
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    		topicsSub = new ArrayList<String>();
    
    Alfredo Chissotti's avatar
    Alfredo Chissotti committed
    
    		// Su questo topic ricevero' un messaggio del tipo {request:description}
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    		// Dovro' quindi mandare la mia descrizione json
    
    Alfredo Chissotti's avatar
    Alfredo Chissotti committed
    		topicsSub.add("to/all");
    
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    		// Su questo topic ricevero' le richieste di inviare il mio stato attuale
    
    		topicsSub.add("rpc/"+getMqttTree()+"/antifurto");
    
    		jsonObject = new JSONObject(Helper.leggiFile(CONF_ZONA));
    
    Alfredo Chissotti's avatar
    Alfredo Chissotti committed
    		interruttore = jsonObject.getString("interruttore");
    
    
    		topicsSub.add("from/"+getMqttTree()+"/gpio/" + interruttore); // Sottoscrivo i messaggi che notificano il cambiamento di stato dell'interruttore
    
    Alfredo Chissotti's avatar
    Alfredo Chissotti committed
    
    		// Per ogni sensore di movimento, sottoscrivo i messaggi che notificano il loro cambiamento di stato
    
    		sensori = jsonObject.getJSONArray("sensoriMovimento");
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    		for(int i=0; i<sensori.length(); i++) {
    
    Alfredo Chissotti's avatar
    Alfredo Chissotti committed
    			topicsSub.add("from/"+getMqttTree()+"/gpio/" + sensori.get(i));
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    		}
    
    		nomeOutputAntifurto = jsonObject.getString("nomeOutputAntifurto");
    		topicsSub.add("from/"+getMqttTree()+"/gpio/" + nomeOutputAntifurto);
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    		interruttoreOutputSuono = jsonObject.getString("outputSuono");
    
    		topicsSub.add("from/"+getMqttTree()+"/gpio/" + interruttoreOutputSuono); // Sottoscrivo i messaggi che notificano il cambiamento di stato dell'interruttore
    
    Alfredo Chissotti's avatar
    Alfredo Chissotti committed
    		topicsSub.add("conf/"+getMqttTree()+"/antifurto/soglia"); // Su questo topic mi arrivera' un messaggio {"soglia": 30} e dovro' impostare la soglia di conseguenza
    
    		topicsSub.add("conf/"+getMqttTree()+"/antifurto");
    
    Alfredo Chissotti's avatar
    Alfredo Chissotti committed
    		topicsSub.add("conf/"+getMqttTree()+"/antifurto/sensore"); // Su questo topic mi arrivera' un messaggio per l'aggiunta di un sensore di movimento.
    																   // Ad esempio se mi arriva il messaggio {"in": "IN3", "delta":33 } devo aggiungere il sensore di movimento che si
    
    																   // chiama IN3, il cui valore di delta e' 33 (devo quindi aggiornare il file deltaSensoriMovimento.json
    
    		topicsSub.add("to/"+getMqttTree()+"/antifurto/luceAntifurto");
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    		this.mqttClient = new MqttClient(brokerUrl, clientId, new MemoryPersistence());
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    	}
    
    	public void startClient(Esecutore esec, Publisher publisher) throws MqttException, JSONException {
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    		String caFilePath = "";
    		String clientCrtFilePath = "";
    		String clientKeyFilePath = "";
    
    Alfredo Chissotti's avatar
    Alfredo Chissotti committed
    
    		MqttConnectOptions options = new MqttConnectOptions();
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    		options.setCleanSession(false);
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    		if(brokerUrl.contains("luci.local")) {  // devo connettermi al mosquitto della beaglebone
    
    			caFilePath = PATH_BB + "/certificates/beaglebone/caGruppo2.crt";
    			clientCrtFilePath = PATH_BB + "/certificates/beaglebone/clientGruppo2.crt";
    			clientKeyFilePath = PATH_BB + "/certificates/beaglebone/clientGruppo2.key";
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    			options.setUserName("gruppo2");
    			options.setPassword("funziona".toCharArray());
    		}
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    		else {
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    			System.out.println("Unknown broken url " + brokerUrl);
    			System.exit(1);
    		}
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    		options.setMqttVersion(MqttConnectOptions.MQTT_VERSION_3_1);
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    		SSLSocketFactory socketFactory;
    		try {
    			socketFactory = getSocketFactory(caFilePath, clientCrtFilePath, clientKeyFilePath, "");
    			options.setSocketFactory(socketFactory);
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    
    		SubscribeCallback subCall = new SubscribeCallback(this, publisher, esec, automa);
    		mqttClient.setCallback(subCall);
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    		
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    		mqttClient.connect(options);
    
    Alfredo Chissotti's avatar
    Alfredo Chissotti committed
    
    		for(String t: topicsSub)
    
    			addTopicToSubscribe(t);
    
    		subCall.sendOutAntifurto();
    
    	// sottoscrive il topic passato come parametro
    	public void addTopicToSubscribe(String topic) throws MqttException {
    
    Alfredo Chissotti's avatar
    Alfredo Chissotti committed
    		mqttClient.subscribe(topic);
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    	}
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    	public void publishMethod(String topic, String msg) throws MqttException {
    		final MqttTopic msgTopic = mqttClient.getTopic(topic);
    		msgTopic.publish(new MqttMessage(msg.getBytes()));
    	}
    
    Alfredo Chissotti's avatar
    Alfredo Chissotti committed
    	public static void main(String args[]) throws JSONException, IOException {
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    		boolean exc = true;
    
    Alfredo Chissotti's avatar
    Alfredo Chissotti committed
    		System.out.println("antifurto started");
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    		while(true) {
    			if(exc) {
    				try {
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    					startSystem();
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    					exc = false;
    				}
    				catch(MqttException e) {
    					System.out.println("Error: "+ e.getMessage() + "\nRestarting system...");
    					e.printStackTrace();
    					exc = true;
    				}
    			}
    		}
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    	}
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    	private static void startSystem() throws JSONException, IOException, MqttException {
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    		MyQueue<Integer> codaVal = new MyQueue<Integer>();
    		MyQueue<Pair> codaMsg = new MyQueue<Pair>();
    		Automa automa = new Automa();
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    		Antifurto antifurto = new Antifurto(automa);
    		Publisher publisher = new Publisher(codaMsg, antifurto);
    
    		Esecutore esec = new Esecutore(publisher, codaVal, automa, antifurto);
    
    		Timer timer = new Timer(6000,-1,esec,automa);
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    		antifurto.startClient(esec, publisher);
    		publisher.start();
    		esec.start();
    
    Alfredo Chissotti's avatar
    Alfredo Chissotti committed
    		timer.start();
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    	}
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    	public static String getMqttTree() {
    		return mqttDomain+"/"+mqttSubdomain;
    	}
    
    
    	public static JSONArray getSensori() {
    		return sensori;
    	}
    
    	public static void addSensore(String newSensore) { // aggiunge un sensore di movimento
    		sensori.put(newSensore);
    	}
    
    	public String getNomeInterruttoreAntifurto() {
    		return interruttore;
    	}
    
    	public String getNomeOutputAntifurto() {
    
    Alfredo Chissotti's avatar
    Alfredo Chissotti committed
    		return nomeOutputAntifurto;
    
    	public String getNomeOutputSuono() {
    		return interruttoreOutputSuono;
    	}
    
    	public void setNomeInterruttoreAntifurto(String nuovoNome) {
    		if(nuovoNome.startsWith("IN"))
    			this.interruttore = nuovoNome;
    	}
    
    	public void setNomeOutputAntifurto(String nuovoNome) {
    
    Alfredo Chissotti's avatar
    Alfredo Chissotti committed
    		if(nuovoNome.startsWith("OUT"))
    
    			this.nomeOutputAntifurto = nuovoNome;
    	}
    
    	public void setNomeOutputSuono(String nuovoNome) {
    
    Alfredo Chissotti's avatar
    Alfredo Chissotti committed
    		if(nuovoNome.startsWith("OUT"))
    
    			this.interruttoreOutputSuono = nuovoNome;
    	}
    
    	public void unsubscribeTopic(String topic) throws MqttException {
    		mqttClient.unsubscribe(topic);
    	}
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    	private static SSLSocketFactory getSocketFactory(final String caCrtFile,
    			final String crtFile, final String keyFile, final String password)
    			throws Exception {
    		Security.addProvider(new BouncyCastleProvider());
    
    		// load CA certificate
    		X509Certificate caCert = null;
    
    		FileInputStream fis = new FileInputStream(caCrtFile);
    		BufferedInputStream bis = new BufferedInputStream(fis);
    		CertificateFactory cf = CertificateFactory.getInstance("X.509");
    
    		while (bis.available() > 0) {
    			caCert = (X509Certificate) cf.generateCertificate(bis);
    		}
    
    		// load client certificate
    		bis = new BufferedInputStream(new FileInputStream(crtFile));
    		X509Certificate cert = null;
    		while (bis.available() > 0) {
    			cert = (X509Certificate) cf.generateCertificate(bis);
    		}
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    		// load client private key
    		PEMParser pemParser = new PEMParser(new FileReader(keyFile));
    		Object object = pemParser.readObject();
    		PEMDecryptorProvider decProv = new JcePEMDecryptorProviderBuilder()
    				.build(password.toCharArray());
    		JcaPEMKeyConverter converter = new JcaPEMKeyConverter()
    				.setProvider("BC");
    		KeyPair key;
    		if (object instanceof PEMEncryptedKeyPair) {
    			//System.out.println("Encrypted key - we will use provided password");
    			key = converter.getKeyPair(((PEMEncryptedKeyPair) object)
    					.decryptKeyPair(decProv));
    		} else {
    			//System.out.println("Unencrypted key - no password needed");
    			key = converter.getKeyPair((PEMKeyPair) object);
    		}
    		pemParser.close();
    
    		// CA certificate is used to authenticate server
    		KeyStore caKs = KeyStore.getInstance(KeyStore.getDefaultType());
    		caKs.load(null, null);
    		caKs.setCertificateEntry("ca-certificate", caCert);
    		TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");
    		tmf.init(caKs);
    
    		// client key and certificates are sent to server so it can authenticate
    		// us
    		KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
    		ks.load(null, null);
    		ks.setCertificateEntry("certificate", cert);
    		ks.setKeyEntry("private-key", key.getPrivate(), password.toCharArray(),
    				new java.security.cert.Certificate[] { cert });
    		KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory
    				.getDefaultAlgorithm());
    		kmf.init(ks, password.toCharArray());
    
    		// finally, create SSL socket factory
    		SSLContext context = SSLContext.getInstance("TLSv1.2");
    		context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
    
    		return context.getSocketFactory();
    	}