Newer
Older
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
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;
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;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
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
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;
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";
public Antifurto(Automa automa) throws JSONException, IOException, MqttException {
this.automa = automa;
JSONObject jsonObject = new JSONObject(Helper.leggiFile(CONF_FILE));
brokerUrl = jsonObject.getString("protocol") + "://" + jsonObject.getString("broker") + ":" + jsonObject.getInt("port");
mqttDomain = jsonObject.getString("mqttDomain");
mqttSubdomain = jsonObject.getString("mqttSubdomain");
// Su questo topic ricevero' un messaggio del tipo {request:description}
// Su questo topic ricevero' le richieste di inviare il mio stato attuale
topicsSub.add("rpc/"+getMqttTree()+"/antifurto");
jsonObject = new JSONObject(Helper.leggiFile(CONF_ZONA));
interruttore = jsonObject.getString("interruttore");
topicsSub.add("from/"+getMqttTree()+"/gpio/" + interruttore); // Sottoscrivo i messaggi che notificano il cambiamento di stato dell'interruttore
// Per ogni sensore di movimento, sottoscrivo i messaggi che notificano il loro cambiamento di stato
sensori = jsonObject.getJSONArray("sensoriMovimento");
topicsSub.add("from/"+getMqttTree()+"/gpio/" + sensori.get(i));
nomeOutputAntifurto = jsonObject.getString("nomeOutputAntifurto");
topicsSub.add("from/"+getMqttTree()+"/gpio/" + nomeOutputAntifurto);
interruttoreOutputSuono = jsonObject.getString("outputSuono");
topicsSub.add("from/"+getMqttTree()+"/gpio/" + interruttoreOutputSuono); // Sottoscrivo i messaggi che notificano il cambiamento di stato dell'interruttore
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");
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");
this.mqttClient = new MqttClient(brokerUrl, clientId, new MemoryPersistence());
public void startClient(Esecutore esec, Publisher publisher) throws MqttException, JSONException {
String caFilePath = "";
String clientCrtFilePath = "";
String clientKeyFilePath = "";
MqttConnectOptions options = new MqttConnectOptions();
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";
options.setUserName("gruppo2");
options.setPassword("funziona".toCharArray());
}
System.out.println("Unknown broken url " + brokerUrl);
System.exit(1);
}
options.setMqttVersion(MqttConnectOptions.MQTT_VERSION_3_1);
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);
subCall.sendOutAntifurto();
// sottoscrive il topic passato come parametro
public void addTopicToSubscribe(String topic) throws MqttException {
public void publishMethod(String topic, String msg) throws MqttException {
final MqttTopic msgTopic = mqttClient.getTopic(topic);
msgTopic.publish(new MqttMessage(msg.getBytes()));
}
public static void main(String args[]) throws JSONException, IOException {
exc = false;
}
catch(MqttException e) {
System.out.println("Error: "+ e.getMessage() + "\nRestarting system...");
e.printStackTrace();
exc = true;
}
}
}
private static void startSystem() throws JSONException, IOException, MqttException {
MyQueue<Integer> codaVal = new MyQueue<Integer>();
MyQueue<Pair> codaMsg = new MyQueue<Pair>();
Automa automa = new Automa();
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);
antifurto.startClient(esec, publisher);
publisher.start();
esec.start();
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 getNomeOutputSuono() {
return interruttoreOutputSuono;
}
public void setNomeInterruttoreAntifurto(String nuovoNome) {
if(nuovoNome.startsWith("IN"))
this.interruttore = nuovoNome;
}
public void setNomeOutputAntifurto(String nuovoNome) {
public void setNomeOutputSuono(String nuovoNome) {
this.interruttoreOutputSuono = nuovoNome;
}
public void unsubscribeTopic(String topic) throws MqttException {
mqttClient.unsubscribe(topic);
}
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);
}
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
// 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();
}