Preparing Makefiles, stub, skeleton, config files, etc. for porting LifxLightBulb...
[iot2.git] / iotjava / iotruntime / slave / IoTSlave.java
1 package iotruntime.slave;
2
3 import iotruntime.*;
4 import iotruntime.zigbee.*;
5 import iotruntime.messages.*;
6 import iotruntime.master.RuntimeOutput;
7
8 // Java packages
9 import java.io.File;
10 import java.io.FileInputStream;
11 import java.io.FileOutputStream;
12 import java.io.ObjectInputStream;
13 import java.io.ObjectOutputStream;
14 import java.io.InputStream;
15 import java.io.OutputStream;
16 import java.io.IOException;
17 import java.io.FileNotFoundException;
18 import java.lang.ClassNotFoundException;
19 import java.lang.Class;
20 import java.lang.reflect.*;
21 import java.lang.ClassLoader;
22 import java.net.Socket;
23 import java.net.UnknownHostException;
24 import java.net.URL;
25 import java.net.URLClassLoader;
26 import java.rmi.registry.LocateRegistry;
27 import java.rmi.registry.Registry;
28 import java.rmi.Remote;
29 import java.rmi.RemoteException;
30 import java.rmi.AlreadyBoundException;
31 import java.rmi.NotBoundException;
32 import java.rmi.server.UnicastRemoteObject;
33 import java.util.Properties;
34
35 // Zip/Unzip utility
36 import net.lingala.zip4j.exception.ZipException;
37 import net.lingala.zip4j.core.ZipFile;
38
39 /** Class IoTSlave is run by IoTMaster on a different JVM's.
40  *  It needs to respond to IoTMaster's commands
41  *
42  * @author      Rahmadi Trimananda <rahmadi.trimananda @ uci.edu>
43  * @version     1.0
44  * @since       2016-06-16
45  */
46 public class IoTSlave {
47
48         /**
49          * IoTSlave class properties
50          */
51         private Message sIoTMasterMsg;
52         private String sIoTMasterHostAdd;
53         private int iComPort;
54         private int iRMIRegPort;
55         private int iRMIStubPort;
56         private String strFieldName;
57         private Class<?> clsMain;
58         private Object objMainCls;
59         private Object iRelFirstObject;
60         private Object iRelSecondObject;
61         private Socket socket;
62         private ObjectOutputStream outStream;
63         private ObjectInputStream inStream;
64         /**
65          * IoTSet object, e.g. IoTSet<ProximitySensor> proximity_sensors;
66          * IoTRelation object, e.g. IoTRelation<ProximitySensor, LightBulb> ps_lb_relation;
67          */
68         private ISet<Object> isetObject;
69         private IoTSet<Object> iotsetObject;
70         private IRelation<Object,Object> irelObject;
71         private IoTRelation<Object,Object> iotrelObject;
72
73         // Constants that are to be extracted from config file
74         private static String STR_JAR_FILE_PATH;
75         private static String STR_OBJ_CLS_PFX;
76         private static String STR_INTERFACE_PFX;
77         private static boolean BOOL_VERBOSE;
78
79         /**
80          * IoTSlave class constants - not to be changed by users
81          */
82         private static final String STR_IOT_SLAVE_NAME = "IoTSlave";
83         private static final String STR_CFG_FILE_EXT = ".config";
84         private static final String STR_CLS_FILE_EXT = ".class";
85         private static final String STR_JAR_FILE_EXT = ".jar";
86         private static final String STR_ZIP_FILE_EXT = ".zip";
87         private static final String STR_UNZIP_DIR = "./";
88         private static final Class<?>[] STR_URL_PARAM = new Class[] {URL.class };
89         private static final String STR_YES = "Yes";
90         private static final String STR_NO = "No";
91
92         /**
93          * Class constructor
94          *
95          */
96         public IoTSlave(String[] argInp) {
97
98                 sIoTMasterMsg = null;
99                 sIoTMasterHostAdd = argInp[0];
100                 iComPort = Integer.parseInt(argInp[1]);
101                 iRMIRegPort = Integer.parseInt(argInp[2]);
102                 iRMIStubPort = Integer.parseInt(argInp[3]);
103                 strFieldName = null;
104                 clsMain = null;
105                 objMainCls = null;
106                 isetObject = null;
107                 iotsetObject = null;
108                 irelObject = null;
109                 iotrelObject = null;
110                 iRelFirstObject = null;
111                 iRelSecondObject = null;
112                 socket = null;
113                 outStream = null;
114                 inStream = null;
115
116                 STR_JAR_FILE_PATH = null;
117                 STR_OBJ_CLS_PFX = null;
118                 STR_INTERFACE_PFX = null;
119                 BOOL_VERBOSE = false;
120         }
121
122         /**
123          * A method to initialize constants from config file
124          *
125          * @return void
126          */
127         private void parseIoTSlaveConfigFile() {
128                 // Parse configuration file
129                 Properties prop = new Properties();
130                 String strCfgFileName = STR_IOT_SLAVE_NAME + STR_CFG_FILE_EXT;
131                 File file = new File(strCfgFileName);
132                 try {
133                         FileInputStream fis = new FileInputStream(file);
134                         prop.load(fis);
135                 } catch (IOException ex) {
136                         System.out.println("IoTMaster: Error reading config file: " + strCfgFileName);
137                         ex.printStackTrace();
138                 }
139                 System.out.println("IoTMaster: Extracting information from config file: " + strCfgFileName);
140                 // Initialize constants from config file
141                 STR_JAR_FILE_PATH = prop.getProperty("JAR_FILE_PATH");
142                 STR_OBJ_CLS_PFX = prop.getProperty("OBJECT_CLASS_PREFIX");
143                 STR_INTERFACE_PFX = prop.getProperty("INTERFACE_PREFIX");
144                 STR_INTERFACE_PFX = prop.getProperty("INTERFACE_PREFIX");
145                 if (prop.getProperty("VERBOSE").equals(STR_YES)) {
146                         BOOL_VERBOSE = true;
147                 }
148
149                 System.out.println("JAR_FILE_PATH=" + STR_JAR_FILE_PATH);
150                 System.out.println("OBJECT_CLASS_PREFIX=" + STR_OBJ_CLS_PFX);
151                 System.out.println("INTERFACE_PREFIX=" + STR_INTERFACE_PFX);
152                 System.out.println("IoTMaster: Information extracted successfully!");
153         }
154
155         /**
156          * Adds the content pointed by the URL to the classpath dynamically at runtime (hack!!!)
157          *
158          * @param  url         the URL pointing to the content to be added
159          * @throws IOException
160          * @see    <a href="http://stackoverflow.com/questions/60764/how-should-i-load-jars-dynamically-at-runtime</a>
161          */
162         private static void addURL(URL url) throws IOException {
163
164                 URLClassLoader sysloader = (URLClassLoader)ClassLoader.getSystemClassLoader();
165                 Class<?> sysclass = URLClassLoader.class;
166
167                 try {
168
169                         Method method = sysclass.getDeclaredMethod("addURL", STR_URL_PARAM);
170                         method.setAccessible(true);
171                         method.invoke(sysloader,new Object[] { url });
172
173                 } catch (Throwable t) {
174
175                         t.printStackTrace();
176                         throw new IOException("IoTSlave: Could not add URL to system classloader!");
177                 }
178         }
179
180         /**
181          * A private method to create object
182          *
183          * @return  void
184          */
185         private void createObject() throws IOException,
186                 ClassNotFoundException, NoSuchMethodException, InstantiationException,
187                         RemoteException, AlreadyBoundException, IllegalAccessException,
188                                 InvocationTargetException {
189
190                 // Translating into the actual Message class
191                 MessageCreateObject sMessage = (MessageCreateObject) sIoTMasterMsg;
192
193                 // Instantiate object using reflection
194                 String strObjClassName = STR_OBJ_CLS_PFX + "." + sMessage.getObjectClass() +
195                                                                                                                  "." + sMessage.getObjectClass();
196                 File file = new File(STR_JAR_FILE_PATH + sMessage.getObjectClass() + STR_JAR_FILE_EXT);
197                 RuntimeOutput.print("IoTSlave: DEBUG print path: " + STR_JAR_FILE_PATH +
198                                                                                          sMessage.getObjectClass() + STR_JAR_FILE_EXT, BOOL_VERBOSE);
199                 addURL(file.toURI().toURL());
200                 clsMain = Class.forName(strObjClassName);
201
202                 Class[] clsParams = sMessage.getObjectFldCls();
203                 Constructor<?> ct = clsMain.getDeclaredConstructor(clsParams);
204                 Object objParams[] = sMessage.getObjectFields();
205                 objMainCls = ct.newInstance(objParams);
206                 RuntimeOutput.print("IoTSlave: Create object!", BOOL_VERBOSE);
207
208                 // Register object to RMI - there are 2 ports: RMI registry port and RMI stub port
209                 Object objStub = (Object)
210                         UnicastRemoteObject.exportObject((Remote) objMainCls, iRMIStubPort);
211                 Registry registry = LocateRegistry.createRegistry(iRMIRegPort);
212                 registry.bind(sMessage.getObjectName(), (Remote) objStub);
213                 outStream.writeObject(new MessageSimple(IoTCommCode.ACKNOWLEDGED));
214                 RuntimeOutput.print("IoTSlave: Registering object via RMI!", BOOL_VERBOSE);
215
216         }
217
218         
219         /**
220          * A private method to transfer file
221          *
222          * @return  void
223          */
224         private void transferFile() throws IOException,
225                 UnknownHostException, FileNotFoundException {
226
227                 // Translating into the actual Message class
228                 MessageSendFile sMessage = (MessageSendFile) sIoTMasterMsg;
229
230                 // Send back the received message as acknowledgement
231                 outStream.writeObject(new MessageSimple(IoTCommCode.ACKNOWLEDGED));
232
233                 // Write file to the current location
234                 Socket filesocket = new Socket(sIoTMasterHostAdd, iComPort);
235                 InputStream inFileStream = filesocket.getInputStream();
236                 OutputStream outFileStream = new FileOutputStream(sMessage.getFileName());
237                 byte[] bytFile = new byte[Math.toIntExact(sMessage.getFileSize())];
238
239                 int iCount = 0;
240                 while ((iCount = inFileStream.read(bytFile)) > 0) {
241                         outFileStream.write(bytFile, 0, iCount);
242                 }
243                 // Unzip if this is a zipped file
244                 if (sMessage.getFileName().contains(STR_ZIP_FILE_EXT)) {
245                         RuntimeOutput.print("IoTSlave: Unzipping file: " + sMessage.getFileName(), BOOL_VERBOSE);
246                         try {
247                                 ZipFile zipFile = new ZipFile(sMessage.getFileName());
248                                 zipFile.extractAll(STR_UNZIP_DIR);
249                         } catch (ZipException ex) {
250                                 System.out.println("IoTSlave: Error in unzipping file!");
251                                 ex.printStackTrace();
252                         }
253                 }
254                 outStream.writeObject(new MessageSimple(IoTCommCode.ACKNOWLEDGED));
255                 RuntimeOutput.print("IoTSlave: Receiving file transfer!", BOOL_VERBOSE);
256         }
257
258         /**
259          * A private method to create a main object
260          *
261          * @return  void
262          */
263         private void createMainObject() throws IOException,
264                 ClassNotFoundException, InstantiationException, IllegalAccessException,
265                         InvocationTargetException {
266
267                 // Translating into the actual Message class
268                 MessageCreateMainObject sMessage = (MessageCreateMainObject) sIoTMasterMsg;
269
270                 // Getting controller class
271                 File file = new File(STR_JAR_FILE_PATH + sMessage.getObjectName() + STR_JAR_FILE_EXT);
272                 RuntimeOutput.print("IoTSlave: DEBUG print path: " + STR_JAR_FILE_PATH +
273                                                                                          sMessage.getObjectName() + STR_JAR_FILE_EXT, BOOL_VERBOSE);
274                 addURL(file.toURI().toURL());
275                 // We will always have a package name <object name>.<object name>
276                 // e.g. SmartLightsController.SmartLightsController
277                 clsMain = Class.forName(sMessage.getObjectName() + "." + sMessage.getObjectName());
278                 objMainCls = clsMain.newInstance();
279
280                 // Send back the received message as acknowledgement
281                 outStream.writeObject(new MessageSimple(IoTCommCode.ACKNOWLEDGED));
282                 RuntimeOutput.print("IoTSlave: Instantiating main controller/device class "
283                                                                                          + sMessage.getObjectName(), BOOL_VERBOSE);
284
285         }
286
287         /**
288          * A private method to create a new IoTSet
289          *
290          * @return  void
291          */
292         private void createNewIoTSet() throws IOException {
293
294                 // Translating into the actual Message class
295                 MessageCreateSetRelation sMessage = (MessageCreateSetRelation) sIoTMasterMsg;
296
297                 // Initialize field name
298                 strFieldName = sMessage.getObjectFieldName();
299                 RuntimeOutput.print("IoTSlave: Setting up field " + strFieldName, BOOL_VERBOSE);
300
301                 // Creating a new IoTSet object
302                 isetObject = new ISet<Object>();
303
304                 // Send back the received message as acknowledgement
305                 outStream.writeObject(new MessageSimple(IoTCommCode.ACKNOWLEDGED));
306                 RuntimeOutput.print("IoTSlave: Creating a new IoTSet object!", BOOL_VERBOSE);
307
308         }
309
310         /**
311          * A private method to create a new IoTRelation
312          *
313          * @return  void
314          */
315         private void createNewIoTRelation() throws IOException {
316
317                 // Translating into the actual Message class
318                 MessageCreateSetRelation sMessage = (MessageCreateSetRelation) sIoTMasterMsg;
319
320                 // Initialize field name
321                 strFieldName = sMessage.getObjectFieldName();
322                 RuntimeOutput.print("IoTSlave: Setting up field " + strFieldName, BOOL_VERBOSE);
323
324                 // Creating a new IoTRelation object
325                 irelObject = new IRelation<Object,Object>();
326
327                 // Send back the received message as acknowledgement
328                 outStream.writeObject(new MessageSimple(IoTCommCode.ACKNOWLEDGED));
329                 RuntimeOutput.print("IoTSlave: Creating a new IoTRelation object!", BOOL_VERBOSE);
330
331         }
332
333         /**
334          * A private method to get an object from the registry
335          *
336          * @return  Object
337          */
338         private Object getObjectFromRegistry() throws RemoteException,
339                         ClassNotFoundException, NotBoundException {
340
341                 // Translating into the actual Message class
342                 MessageGetObject sMessage = (MessageGetObject) sIoTMasterMsg;
343
344                 // Locate RMI registry and add object into IoTSet
345                 Registry registry =
346                         LocateRegistry.getRegistry(sMessage.getHostAddress(), sMessage.getRMIRegPort());
347                 RuntimeOutput.print("IoTSlave: Looking for RMI registry: " +
348                         sMessage.getHostAddress() + ":" + sMessage.getRMIRegPort() +
349                         " with RMI stub port: " + sMessage.getRMIStubPort(), BOOL_VERBOSE);
350                 Object stubObj = registry.lookup(sMessage.getObjectName());
351                 RuntimeOutput.print("IoTSlave: Looking for object name: " + sMessage.getObjectName(), BOOL_VERBOSE);
352
353                 // Class conversion to interface class of this class,
354                 // e.g. ProximitySensorImpl has ProximitySensor interface
355                 String strObjClassInterfaceName = STR_OBJ_CLS_PFX + "." + STR_INTERFACE_PFX + "." +
356                         sMessage.getObjectInterfaceName();
357                 Class<?> clsInf = Class.forName(strObjClassInterfaceName);
358                 Object stubObjConv = clsInf.cast(stubObj);
359
360                 return stubObjConv;
361         }
362
363         /**
364          * A private method to get an IoTSet object
365          *
366          * @return  void
367          */
368         private void getIoTSetObject() throws IOException,
369                 ClassNotFoundException, RemoteException, NotBoundException {
370
371                 Object objRegistry = getObjectFromRegistry();
372                 isetObject.add(objRegistry);
373                 RuntimeOutput.print("IoTSlave: This IoTSet now has: " + isetObject.size() + " entry(s)", BOOL_VERBOSE);
374
375                 // Send back the received message as acknowledgement
376                 outStream.writeObject(new MessageSimple(IoTCommCode.ACKNOWLEDGED));
377                 RuntimeOutput.print("IoTSlave: Getting an object for IoTSet!", BOOL_VERBOSE);
378
379         }
380
381         /**
382          * A private method to get an IoTRelation first object
383          *
384          * @return  void
385          */
386         private void getIoTRelationFirstObject() throws IOException,
387                 ClassNotFoundException, RemoteException, NotBoundException {
388
389                 Object objRegistry = getObjectFromRegistry();
390                 iRelFirstObject = objRegistry;
391
392                 // Send back the received message as acknowledgement
393                 outStream.writeObject(new MessageSimple(IoTCommCode.ACKNOWLEDGED));
394                 RuntimeOutput.print("IoTSlave: Getting a first object for IoTRelation!", BOOL_VERBOSE);
395
396         }
397
398         /**
399          * A private method to get an IoTRelation second object
400          *
401          * @return  void
402          */
403         private void getIoTRelationSecondObject() throws IOException,
404                 ClassNotFoundException, RemoteException, NotBoundException {
405
406                 Object objRegistry = getObjectFromRegistry();
407                 iRelSecondObject = objRegistry;
408
409                 // Now add the first and the second object into IoTRelation
410                 irelObject.put(iRelFirstObject, iRelSecondObject);
411                 RuntimeOutput.print("IoTSlave: This IoTRelation now has: " + irelObject.size() + " entry(s)", BOOL_VERBOSE);
412
413                 // Send back the received message as acknowledgement
414                 outStream.writeObject(new MessageSimple(IoTCommCode.ACKNOWLEDGED));
415                 RuntimeOutput.print("IoTSlave: Getting a second object for IoTRelation!", BOOL_VERBOSE);
416
417         }
418
419         /**
420          * A private method to reinitialize IoTSet field
421          *
422          * @return  void
423          */
424         private void reinitializeIoTSetField() throws IOException,
425                 IllegalAccessException, NoSuchFieldException {
426
427                 // Reinitialize IoTSet field after getting all the objects
428                 iotsetObject = new IoTSet<Object>(isetObject.values());
429
430                 // Private fields need getDeclaredField(), while public fields use getField()
431                 Field fld = clsMain.getDeclaredField(strFieldName);
432                 boolean bAccess = fld.isAccessible();
433                 fld.setAccessible(true);
434                 fld.set(objMainCls, iotsetObject);
435                 fld.setAccessible(bAccess);
436                 RuntimeOutput.print("IoTSlave: Reinitializing field " + strFieldName, BOOL_VERBOSE);
437
438                 // Send back the received message as acknowledgement
439                 outStream.writeObject(new MessageSimple(IoTCommCode.ACKNOWLEDGED));
440                 RuntimeOutput.print("IoTSlave: Reinitializing IoTSet field!", BOOL_VERBOSE);
441
442         }
443
444         /**
445          * A private method to reinitialize IoTRelation field
446          *
447          * @return  void
448          */
449         private void reinitializeIoTRelationField() throws IOException,
450                 IllegalAccessException, NoSuchFieldException {
451
452                 // Reinitialize IoTSet field after getting all the objects
453                 iotrelObject = new IoTRelation<Object,Object>(irelObject.relationMap(), irelObject.size());
454
455                 // Private fields need getDeclaredField(), while public fields use getField()
456                 Field fld = clsMain.getDeclaredField(strFieldName);
457                 boolean bAccess = fld.isAccessible();
458                 fld.setAccessible(true);
459                 fld.set(objMainCls, iotrelObject);
460                 fld.setAccessible(bAccess);
461                 RuntimeOutput.print("IoTSlave: Reinitializing field " + strFieldName, BOOL_VERBOSE);
462
463                 // Send back the received message as acknowledgement
464                 outStream.writeObject(new MessageSimple(IoTCommCode.ACKNOWLEDGED));
465                 RuntimeOutput.print("IoTSlave: Reinitializing IoTRelation field!", BOOL_VERBOSE);
466
467         }
468
469         /**
470          * A private method to get the device driver object's IoTSet
471          * <p>
472          * This is to handle device driver's IoTSet that contains IP addresses
473          *
474          * @return  void
475          */
476         private void getDeviceIoTSetObject() throws IOException {
477
478                 // Translating into the actual Message class
479                 MessageGetDeviceObject sMessage = (MessageGetDeviceObject) sIoTMasterMsg;
480
481                 // Get IoTSet objects for IP address set on device driver/controller
482                 IoTDeviceAddress objDeviceAddress = new IoTDeviceAddress(sMessage.getHostAddress(),
483                         sMessage.getSourceDeviceDriverPort(),
484                         sMessage.getDestinationDeviceDriverPort(),
485                         sMessage.isSourcePortWildCard(),
486                         sMessage.isDestinationPortWildCard());
487                 RuntimeOutput.print("IoTSlave: Device address transferred: " + sMessage.getHostAddress(), BOOL_VERBOSE);
488                 isetObject.add(objDeviceAddress);
489                 RuntimeOutput.print("IoTSlave: This IoTSet now has: " + isetObject.size() + " entry(s)", BOOL_VERBOSE);
490
491                 // Send back the received message as acknowledgement
492                 outStream.writeObject(new MessageSimple(IoTCommCode.ACKNOWLEDGED));
493                 RuntimeOutput.print("IoTSlave: Getting an object for IoTSet!", BOOL_VERBOSE);
494
495         }
496
497         /**
498          * A private method to get the device driver object's IoTSet for IoTZigbeeAddress
499          * <p>
500          * This is to handle device driver's IoTSet that contains Zigbee addresses
501          *
502          * @return  void
503          */
504         private void getZBDevIoTSetObject() throws IOException {
505
506                 // Translating into the actual Message class
507                 MessageGetSimpleDeviceObject sMessage = (MessageGetSimpleDeviceObject) sIoTMasterMsg;
508
509                 // Get IoTSet objects for IP address set on device driver/controller
510                 IoTZigbeeAddress objZBDevAddress = new IoTZigbeeAddress(sMessage.getHostAddress());
511                 RuntimeOutput.print("IoTSlave: Device address transferred: " + sMessage.getHostAddress(), BOOL_VERBOSE);
512                 isetObject.add(objZBDevAddress);
513                 RuntimeOutput.print("IoTSlave: This IoTSet now has: " + isetObject.size() + " entry(s)", BOOL_VERBOSE);
514
515                 // Send back the received message as acknowledgement
516                 outStream.writeObject(new MessageSimple(IoTCommCode.ACKNOWLEDGED));
517                 RuntimeOutput.print("IoTSlave: Getting an object for IoTSet!", BOOL_VERBOSE);
518
519         }
520
521         
522         /**
523          * A private method to get IoTAddress objects for IoTSet
524          *
525          * @return  void
526          */
527         private void getAddIoTSetObject() throws IOException {
528
529                 // Translating into the actual Message class
530                 MessageGetSimpleDeviceObject sMessage = (MessageGetSimpleDeviceObject) sIoTMasterMsg;
531
532                 // Get IoTSet objects for IP address set on device driver/controller
533                 IoTAddress objAddress = new IoTAddress(sMessage.getHostAddress());
534                 RuntimeOutput.print("IoTSlave: Address transferred: " + sMessage.getHostAddress(), BOOL_VERBOSE);
535                 isetObject.add(objAddress);
536                 RuntimeOutput.print("IoTSlave: This IoTSet now has: " + isetObject.size() + " entry(s)", BOOL_VERBOSE);
537                 // Send back the received message as acknowledgement
538                 outStream.writeObject(new MessageSimple(IoTCommCode.ACKNOWLEDGED));
539                 RuntimeOutput.print("IoTSlave: Getting an object for IoTSet!", BOOL_VERBOSE);
540
541         }
542         
543         /**
544          * A private method to invoke init() method in the controller object
545          *
546          * @return  void
547          */
548         private void invokeInitMethod() throws IOException {
549
550                 new Thread() {
551                         public void run() {
552                                 try {
553                                         Class<?> noparams[] = {};
554                                         Method method = clsMain.getDeclaredMethod("init", noparams);
555                                         method.invoke(objMainCls);
556                                 } catch (NoSuchMethodException  |
557                                                  IllegalAccessException |
558                                                  InvocationTargetException ex) {
559                                         System.out.println("IoTSlave: Exception: "
560                                                  + ex.getMessage());
561                                         ex.printStackTrace();
562                                 }
563                         }
564                 }.start();
565
566                 // Start a new thread to invoke the init function
567                 RuntimeOutput.print("IoTSlave: Invoke init method! Job done!", BOOL_VERBOSE);
568
569                 // Send back the received message as acknowledgement
570                 outStream.writeObject(new MessageSimple(IoTCommCode.ACKNOWLEDGED));
571
572         }
573
574         /**
575          * A public method to do communication with IoTMaster
576          *
577          * @params  iIndex  Integer index
578          * @return  void
579          */
580         public void commIoTMaster() {
581
582                 try {
583
584                         // Loop, receive and process commands from IoTMaster
585                         socket = new Socket(sIoTMasterHostAdd, iComPort);
586                         outStream = new ObjectOutputStream(socket.getOutputStream());
587                         inStream = new ObjectInputStream(socket.getInputStream());
588
589                         LOOP:
590                         while(true) {
591                                 // Get the first payload
592                                 RuntimeOutput.print("IoTSlave: Slave waiting...", BOOL_VERBOSE);
593                                 sIoTMasterMsg = (Message) inStream.readObject();
594
595                                 // Check payload message from IoTMaster and make a decision
596                                 switch (sIoTMasterMsg.getMessage()) {
597
598                                 case CREATE_OBJECT:
599                                         createObject();
600                                         break;
601
602                                 case TRANSFER_FILE:
603                                         transferFile();
604                                         break;
605
606                                 case CREATE_MAIN_OBJECT:
607                                         createMainObject();
608                                         break;
609
610                                 case CREATE_NEW_IOTSET:
611                                         createNewIoTSet();
612                                         break;
613
614                                 case CREATE_NEW_IOTRELATION:
615                                         createNewIoTRelation();
616                                         break;
617
618                                 case GET_IOTSET_OBJECT:
619                                         getIoTSetObject();
620                                         break;
621
622                                 case GET_IOTRELATION_FIRST_OBJECT:
623                                         getIoTRelationFirstObject();
624                                         break;
625
626                                 case GET_IOTRELATION_SECOND_OBJECT:
627                                         getIoTRelationSecondObject();
628                                         break;
629
630                                 case REINITIALIZE_IOTSET_FIELD:
631                                         reinitializeIoTSetField();
632                                         break;
633
634                                 case REINITIALIZE_IOTRELATION_FIELD:
635                                         reinitializeIoTRelationField();
636                                         break;
637
638                                 case GET_DEVICE_IOTSET_OBJECT:
639                                         getDeviceIoTSetObject();
640                                         break;
641
642                                 case GET_ZB_DEV_IOTSET_OBJECT:
643                                         getZBDevIoTSetObject();
644                                         break;
645
646                                 case GET_ADD_IOTSET_OBJECT:
647                                         getAddIoTSetObject();
648                                         break;
649
650                                 case INVOKE_INIT_METHOD:
651                                         invokeInitMethod();
652                                         break;
653
654                                 case END_SESSION:
655                                         // END of session
656                                         break LOOP;
657
658                                 default:
659                                         break;
660                                 }
661                         }
662                         RuntimeOutput.print("IoTSlave: Session ends!", BOOL_VERBOSE);
663
664                         // Closing streams and end session
665                         outStream.close();
666                         inStream.close();
667                         socket.close();
668                         RuntimeOutput.print("IoTSlave: Closing!", BOOL_VERBOSE);
669
670                 } catch (IOException               |
671                                  ClassNotFoundException    |
672                                  NoSuchMethodException     |
673                                  InstantiationException    |
674                                  AlreadyBoundException     |
675                                  IllegalAccessException    |
676                                  InvocationTargetException |
677                                  NotBoundException         |
678                                  NoSuchFieldException ex) {
679                         System.out.println("IoTSlave: Exception: "
680                                  + ex.getMessage());
681                         ex.printStackTrace();
682                 }
683         }
684
685         public static void main(String args[]) {
686                 IoTSlave iotSlave = new IoTSlave(args);
687                 iotSlave.parseIoTSlaveConfigFile();
688                 iotSlave.commIoTMaster();
689         }
690 }