Modified and tested IoTMaster for IoTSet in C++; completed IoTMaster and IoTSlave...
authorrtrimana <rtrimana@uci.edu>
Sat, 21 Jan 2017 00:42:19 +0000 (16:42 -0800)
committerrtrimana <rtrimana@uci.edu>
Sat, 21 Jan 2017 00:42:19 +0000 (16:42 -0800)
iotjava/Makefile
iotjava/iotruntime/cpp/iotslave/IoTSlave.cpp
iotjava/iotruntime/cpp/iotslave/IoTSlave.hpp
iotjava/iotruntime/cpp/iotslave/IoTSlave.java
iotjava/iotruntime/cpp/iotslave/Makefile
iotjava/iotruntime/cpp/setrelation/IoTRelation.hpp
iotjava/iotruntime/master/IoTMaster.java
iotjava/iotruntime/messages/IoTCommCode.java
localconfig/iotruntime/IoTMaster.config

index 473dda14d6cf7f96547911b046cae01a132fd57d..2e1b8f92bdf8c37d6b5d9008026c2b1240d6b065 100644 (file)
@@ -45,7 +45,8 @@ PHONY += run-compiler-room
 run-compiler-room:
        cp ../localconfig/iotpolicy/Room/*.pol $(BIN_DIR)/iotpolicy/
        cp ../localconfig/iotpolicy/Room/*.req $(BIN_DIR)/iotpolicy/
-       cd $(BIN_DIR)/iotpolicy; $(JAVA) -cp .:..:../$(PARSERJARS):../$(BIN_DIR) iotpolicy.IoTCompiler room.pol roomsmart.req -java Java
+       #cd $(BIN_DIR)/iotpolicy; $(JAVA) -cp .:..:../$(PARSERJARS):../$(BIN_DIR) iotpolicy.IoTCompiler room.pol roomsmart.req -java Java
+       cd $(BIN_DIR)/iotpolicy; $(JAVA) -cp .:..:../$(PARSERJARS):../$(BIN_DIR) iotpolicy.IoTCompiler room.pol roomsmart.req -cplus C++
 
 PHONY += run-compiler-cam
 run-compiler-cam:
@@ -116,6 +117,7 @@ compile:
        cd $(BIN_DIR)/iotpolicy/output_files/Java; $(JAVAC) -cp .:..:../../../$(BIN_DIR) TestClassCallbacks_Stub.java
        cd $(BIN_DIR)/iotpolicy/output_files/Java; $(JAVAC) -cp .:..:../../../$(BIN_DIR) TestClassInterface*.java
        cd $(BIN_DIR)/iotpolicy/output_files/Java; $(JAVAC) -cp .:..:../../../$(BIN_DIR) CallBackInterface*.java
+       cd $(BIN_DIR)/iotpolicy/output_files/Java; $(JAVAC) -cp .:..:../../../$(BIN_DIR) StubSkeletonMap.java
 #      cd $(BIN_DIR)/iotpolicy/output_files/Java; $(JAVAC) -cp .:..:../../../$(BIN_DIR) TestClassComplete*.java
 #      cd $(BIN_DIR)/iotpolicy/output_files/Java; $(JAVAC) -cp .:..:../../../$(BIN_DIR) CallBackInterface_CallbackSkeleton.java
 #      cd $(BIN_DIR)/iotpolicy/output_files/Java; $(JAVAC) -cp .:..:../../../$(BIN_DIR) CallBackInterfaceWithCallBack_CallbackStub.java
index 2761fb1d8c63891f2085df7f657f3763dd0baa3f..82e53bd08e9d474ca1452c8e53efe305539398e8 100644 (file)
@@ -96,6 +96,27 @@ char* IoTSlave::recvIter(char* recvBuffer, int recvLen) {
 }
 
 
+// Factoring out iteration
+char* IoTSlave::recvFileIter(char* recvBuffer, int recvLen) {
+
+    int bytesReceived = 0;              // Bytes read on each recv()
+    int totalBytesReceived = 0;         // Total bytes read
+
+       while (totalBytesReceived < recvLen) {
+               // Receive up to the buffer size bytes from the sender
+               if ((bytesReceived = (socket->recv(recvBuffer, recvLen))) <= 0) {
+                       string errMsg = "IoTSlave: Unable to read!";
+                       cerr << errMsg << endl;
+                       writeToFile(errMsg);
+                       exit(1);
+               }
+               totalBytesReceived += bytesReceived;     // Keep tally of total bytes
+       }
+
+       return recvBuffer;
+}
+
+
 void IoTSlave::openFile(string fileName) {
 
        log.open(FILEPATH + fileName + FILEEXT);
@@ -169,13 +190,18 @@ void IoTSlave::runInitObject(IoTSlave* iotslave) {
 // Use handler obtained by getObjectHandler() and instantiate object!
 void IoTSlave::instantiateMainObject() {
 
-       // IoTDeviceAddress + other arguments
-       int paramSize = vecIoTSet.size();
+       // IoTSet + IoTRelation objects
+       int paramSize = vecIoTSet.size() + vecIoTRel.size();
        void* params[paramSize];
+       int j = 0;
        for(int i=0; i<vecIoTSet.size(); i++) {
-               params[i] = vecIoTSet[i];       // Just the first object is taken in this case
+               params[j] = vecIoTSet[i]; j++;
        }
        writeToFile("Vector IoTSet size: " + to_string(vecIoTSet.size()));
+       for(int i=0; i<vecIoTRel.size(); i++) {
+               params[j] = vecIoTRel[i]; j++;
+       }
+       writeToFile("Vector IoTRelation size: " + to_string(vecIoTRel.size()));
        objMainCls = create_object(params);
        writeToFile("Object created for " + mainObjectName);
        init_object(objMainCls);
@@ -314,7 +340,7 @@ string IoTSlave::recvString() {
 
        // Get the length of string first
        int strLen = recvInteger();
-       char* recvStr = new char[strLen];               // Normally 4 bytes
+       char* recvStr = new char[strLen];
 
        // Receive and iterate until complete
        recvIter(recvStr, strLen);
@@ -326,6 +352,53 @@ string IoTSlave::recvString() {
 }
 
 
+// Receive file from IoTMaster
+void IoTSlave::transferFile() {
+
+       string fileName = recvFile(); sendAck();
+       //unzipFile(fileName);
+}
+
+
+void IoTSlave::unzipFile(string fileName) {
+
+       // Unzip file (what we are sending is a zipped file)
+       // TODO: perhaps we need to replace this with libzip or zlib later      
+       writeToFile("Unzipping file!");
+       string chmodCmd = FILEPATH + fileName + SHELL;
+       //std::system(chmodCmd.c_str());
+       thread th1 (std::system, chmodCmd.c_str());
+       th1.detach();
+       writeToFile("Finished unzipping file!");
+}
+
+
+string IoTSlave::recvFile() {
+
+       // Get the length of string first
+       string fileName = recvString(); sendAck();
+       int fileLen = recvInteger(); sendAck();
+       writeToFile("Receiving file " + fileName + " with length " + to_string(fileLen) + " bytes...");
+       char* recvFil = new char[fileLen];
+       // Receive and iterate until complete
+       recvFileIter(recvFil, fileLen);
+       // Write into file
+       ofstream fileStream;
+       fileStream.open(FILEPATH + fileName);
+       if (!fileStream) {
+               writeToFile("Error opening file: " + FILEPATH + fileName);
+               exit(1);
+       }
+       fileStream.write(recvFil, fileLen);
+       delete[] recvFil;
+       fileStream.close();
+       // TODO: Experimental
+       //string chmodCmd = FILEPATH + fileName + SHELL;
+       //execv(chmodCmd.c_str(), 0);
+       return fileName;
+}
+
+
 // Create a driver object, e.g. LifxLightBulb
 void IoTSlave::createObject() {
 
@@ -396,32 +469,7 @@ void IoTSlave::getDeviceIoTSetObject() {
 }
 
 
-// Get IoTSet object content reference and put it inside IoTSet object
-// This is basically the stub objects
-void IoTSlave::getIoTSetObject() {
-
-       writeToFile("Getting IoTSet object... ");
-       // Get the IoTDeviceAddress info
-       hostAddress = recvString(); sendAck();
-       writeToFile("=> Host address: " + hostAddress);
-       objectName = recvString(); sendAck();
-       writeToFile("=> Driver object name: " + objectName);
-       objectClassName = recvString(); sendAck();
-       writeToFile("=> Driver object class name: " + objectClassName);
-       objectInterfaceName = recvString(); sendAck();
-       writeToFile("=> Driver object interface name: " + objectInterfaceName);
-       objectStubClass = recvString(); sendAck();
-       writeToFile("=> Driver object stub class name: " + objectStubClass);
-       objectRegPort = recvInteger(); sendAck();
-       writeToFile("=> Driver object registry port: " + to_string(objectRegPort));
-       objectStubPort = recvInteger(); sendAck();
-       writeToFile("=> Driver object stub port: " + to_string(objectStubPort));
-       int numOfPorts = recvInteger(); sendAck();
-       for (int i = 0; i < numOfPorts; i++) {
-               int port = recvInteger(); sendAck();
-               ports.push_back(port);
-               writeToFile("==> Got a new port: " + to_string(port));
-       }
+void IoTSlave::createStub() {
        // Create Stub object
        unordered_map<string,void*>::const_iterator itr = mapObjNameStub.find(objectName);
        if (itr != mapObjNameStub.end()) {      // Stub has been created earlier
@@ -434,6 +482,16 @@ void IoTSlave::getIoTSetObject() {
                mapObjNameStub.insert(make_pair(objectName,objStubCls));
                writeToFile("=> Map has: " + to_string(mapObjNameStub.size()) + " members");
        }
+}
+
+
+// Get IoTSet object content reference and put it inside IoTSet object
+// This is basically the stub objects
+void IoTSlave::getIoTSetObject() {
+
+       writeToFile("Getting IoTSet object... ");
+       getIoTSetRelationObject();
+       createStub();
        // Insert it into isetObject!
        isetObject->insert(objStubCls);
        writeToFile("=> Inserting stub object into set...");
@@ -450,6 +508,7 @@ void IoTSlave::reinitializeIoTSetField() {
        vecIoTSet.push_back(iotsetObject);
 
        // Create object if this is for driver object
+       // Right now we assume that this needs only one object per device
        if (isDriverObject) {
                // Instantiate driver object
                getObjectHandler(objectClassName);
@@ -461,6 +520,78 @@ void IoTSlave::reinitializeIoTSetField() {
 }
 
 
+// Create a new IoTRelation object to hold objects
+void IoTSlave::createNewIoTRelation() {
+
+       objectFieldName = recvString(); sendAck();
+       // Instantiating new IoTSet object
+       irelObject = new unordered_multimap<void*,void*>();
+       writeToFile("Creating new IoTSet for field: " + objectFieldName);
+}
+
+
+// Get IoTRelation object
+void IoTSlave::getIoTSetRelationObject() {
+
+       hostAddress = recvString(); sendAck();
+       writeToFile("=> Host address: " + hostAddress);
+       objectName = recvString(); sendAck();
+       writeToFile("=> Driver object name: " + objectName);
+       objectClassName = recvString(); sendAck();
+       writeToFile("=> Driver object class name: " + objectClassName);
+       objectInterfaceName = recvString(); sendAck();
+       writeToFile("=> Driver object interface name: " + objectInterfaceName);
+       objectStubClass = recvString(); sendAck();
+       writeToFile("=> Driver object stub class name: " + objectStubClass);
+       objectRegPort = recvInteger(); sendAck();
+       writeToFile("=> Driver object registry port: " + to_string(objectRegPort));
+       objectStubPort = recvInteger(); sendAck();
+       writeToFile("=> Driver object stub port: " + to_string(objectStubPort));
+       int numOfPorts = recvInteger(); sendAck();
+       for (int i = 0; i < numOfPorts; i++) {
+               int port = recvInteger(); sendAck();
+               ports.push_back(port);
+               writeToFile("==> Got a new port: " + to_string(port));
+       }
+}
+
+
+// Get the first object of IoTRelation
+void IoTSlave::getIoTRelationFirstObject() {
+
+       writeToFile("Getting IoTRelation first object... ");
+       getIoTSetRelationObject();
+       createStub();
+       // Hold the first object of IoTRelation
+       irelFirstObject = objStubCls;
+       writeToFile("=> Holding first stub object...");
+}
+
+
+// Get the second object of IoTRelation
+void IoTSlave::getIoTRelationSecondObject() {
+
+       writeToFile("Getting IoTRelation second object... ");
+       getIoTSetRelationObject();
+       createStub();
+       // Hold the first object of IoTRelation
+       irelSecondObject = objStubCls;
+       writeToFile("=> Holding second stub object...");
+       pair<void*,void*>* iotrelPair = new pair<void*,void*>(irelFirstObject, irelSecondObject);
+       irelObject->insert(*iotrelPair);
+}
+
+
+// Reinitialize IoTRelation
+void IoTSlave::reinitializeIoTRelationField() {
+
+       writeToFile("Reinitialize IoTRelation field...");
+       iotrelObject = new IoTRelation<void*,void*>(irelObject);
+       // Collect IoTSet field first in a vector
+       vecIoTRel.push_back(iotrelObject);
+}
+
+
 // Invoke init() method in main controller
 void IoTSlave::invokeInitMethod() {
 
@@ -504,8 +635,9 @@ void IoTSlave::commIoTMaster() {
        writeToFile("Starting main loop...");
        // Main iteration/loop
        while(true) {
-               IoTCommCode message = (IoTCommCode) recvInteger(); sendAck();
-               //writeToFile("Message: " + (int) message);
+               IoTCommCode message = (IoTCommCode) recvInteger(); 
+               writeToFile("Message: " + to_string(message));
+               sendAck();
                
                switch(message) {
 
@@ -514,7 +646,7 @@ void IoTSlave::commIoTMaster() {
                                break;
 
                        case TRANSFER_FILE:
-                               //transferFile();
+                               transferFile();
                                break;
 
                        case CREATE_MAIN_OBJECT:
@@ -526,7 +658,7 @@ void IoTSlave::commIoTMaster() {
                                break;
 
                        case CREATE_NEW_IOTRELATION:
-                               //createNewIoTRelation();
+                               createNewIoTRelation();
                                break;
 
                        case GET_IOTSET_OBJECT:
@@ -534,11 +666,11 @@ void IoTSlave::commIoTMaster() {
                                break;
 
                        case GET_IOTRELATION_FIRST_OBJECT:
-                               //getIoTRelationFirstObject();
+                               getIoTRelationFirstObject();
                                break;
 
                        case GET_IOTRELATION_SECOND_OBJECT:
-                               //getIoTRelationSecondObject();
+                               getIoTRelationSecondObject();
                                break;
 
                        case REINITIALIZE_IOTSET_FIELD:
@@ -546,7 +678,7 @@ void IoTSlave::commIoTMaster() {
                                break;
 
                        case REINITIALIZE_IOTRELATION_FIELD:
-                               //reinitializeIoTRelationField();
+                               reinitializeIoTRelationField();
                                break;
 
                        case GET_DEVICE_IOTSET_OBJECT:
@@ -581,19 +713,6 @@ void IoTSlave::commIoTMaster() {
 
 int main(int argc, char *argv[]) {
 
-       /*string serverAddress = "localhost";
-       int serverPort = 12345;
-       IoTSlave *iotSlave = new IoTSlave(serverAddress, serverPort);
-       cout << "Connection established with server!" << endl;
-       int intReceived = iotSlave->recvInteger();
-       cout << "Integer received: " << intReceived << endl;
-       cout << "Integer sent back + 1: " << intReceived++ << endl;
-       iotSlave->sendInteger(intReceived);
-       string strSend = "test sending string";
-       cout << "Sending string: " << strSend << endl;  
-       iotSlave->sendString(strSend);
-       cout << "Received string: " << iotSlave->recvString() << endl;*/
-       
        string serverAddress = argv[1];
        char* servPort = argv[2];
        int serverPort = atoi(servPort);
index 343a2c2ef7e9fcb3535bc693099b5e329e649018..e5ecdfc7e4bf225f94247faa15bf202cdf53a07c 100644 (file)
@@ -5,14 +5,12 @@
 #include <fstream>
 #include <vector>
 #include <thread>
+#include <cstdlib>
 
 #include <dlfcn.h>             // For dlopen, dlsym, etc.
 
-//#include "ObjectFactory.hpp"
-//#include "ISet.hpp"
 #include "IoTSet.hpp"
 #include "IoTDeviceAddress.hpp"
-//#include "IRelation.hpp"
 #include "IoTRelation.hpp"
 #include "Socket.cpp"
 
@@ -71,6 +69,7 @@ class IoTSlave {
                const static string DESTROYFUNCTION;            // The destroy function in class
                const static string INITFUNCTION;                       // The init function in class
                const static string LOCALHOST;                          // String "localhost"
+               const static string SHELL;                                      // String ".sh"
 
                // Class properties
                string serverAddress;
@@ -85,10 +84,16 @@ class IoTSlave {
                int objectRegPort;
                int objectStubPort;
                vector<int> ports;                      // Now used to contain callback ports
-               string objectFieldName;                         // Field name that is going to be initialized with IoTSet or IoTRelation
-               unordered_set<void*>* isetObject;       // Set of object
-               IoTSet<void*>* iotsetObject;            // IoTSet of object
-               vector<IoTSet<void*>*> vecIoTSet;       // IoTSet of object
+               string objectFieldName;                                         // Field name that is going to be initialized with IoTSet or IoTRelation
+               unordered_set<void*>* isetObject;                       // Set of object
+               IoTSet<void*>* iotsetObject;                            // IoTSet of object
+               vector<IoTSet<void*>*> vecIoTSet;                       // IoTSet of object
+               void* irelFirstObject;                                                  // First object of IoTRelation
+               void* irelSecondObject;                                                 // Second object of IoTRelation
+               unordered_multimap<void*,void*>* irelObject;    // Relation of object
+               IoTRelation<void*,void*>* iotrelObject;                 // IoTRelation of objects
+               vector<IoTRelation<void*,void*>*> vecIoTRel;    // IoTRelation of object
+
                TCPSocket* socket;
                ofstream log;                                           // Log the messages
                vector<string> args;                            // Hold the arguments for constructor (in string format)
@@ -115,6 +120,8 @@ class IoTSlave {
                int recvInteger();
                void sendString(string strSend);
                string recvString();
+               string recvFile();
+               void unzipFile(string fileName);
                // Main loop
                void sendAck();
                bool recvEndTransfer();
@@ -122,16 +129,22 @@ class IoTSlave {
                void createObject();            // Create driver object
                void createMainObject();        // Create main object
                void createNewIoTSet();
+               void createNewIoTRelation();
                void getDeviceIoTSetObject();
+               void getIoTRelationFirstObject();
+               void getIoTRelationSecondObject();
                void reinitializeIoTSetField();
+               void reinitializeIoTRelationField();
                void getIoTSetObject();
                void invokeInitMethod();
+               void transferFile();
 
        private:
                // Private helper functions
                int* byteToInt(int* result, char* bytes);
                char* intToByteArray(int i, char* bytes);
                char* recvIter(char* recvBuffer, int recvLen);
+               char* recvFileIter(char* recvBuffer, int recvLen);
                void* getObjectConverted(void* retObj, string object, string objectClass);
                void openFile(string fileName);
                void writeToFile(string logMsg);
@@ -142,6 +155,8 @@ class IoTSlave {
                void instantiateSkelObject();
                void instantiateStubObject();
                void runInitObject(IoTSlave* iotslave);
+               void getIoTSetRelationObject();
+               void createStub();
 };
 
 // Constant initialization
@@ -154,5 +169,6 @@ const string IoTSlave::CREATEFUNCTION = "create";
 const string IoTSlave::DESTROYFUNCTION = "destroy";
 const string IoTSlave::INITFUNCTION = "init";
 const string IoTSlave::LOCALHOST = "localhost";
+const string IoTSlave::SHELL = ".sh";
 
 #endif
index 61a39bc7abfc616a1eabcf85e0405d1c1bb93616..02678c11343a07f84eb4021500d38ff61676c3eb 100644 (file)
@@ -2,6 +2,7 @@ import java.util.*;
 import java.io.*;
 import java.net.*;
 import java.nio.*;
+import static java.lang.Math.toIntExact;
 
 public class IoTSlave {
 
@@ -13,8 +14,7 @@ public class IoTSlave {
        private static final String STR_LOCALHOST = "localhost";
        private static final String STR_IOTSLAVE_CPP = "./IoTSlave.o";
        private static final String STR_IOTSLAVE_PATH = "~/tmp/iot2/iotjava/iotruntime/cpp/iotslave/";
-       private static final String STR_ACK = "ACK";
-       private static final String STR_END = "END";
+
        //private static final String STR_LOG_FILE_PATH = "./";
        private static int INT_SIZE = 4;        // send length in the size of integer (4 bytes)
 
@@ -42,6 +42,51 @@ public class IoTSlave {
        }
 
 
+       /**
+        * A method to send files from IoTMaster
+        *
+        * @param  filesocket File socket object
+        * @param  sFileName  File name
+        * @param  lFLength   File length
+        * @return            void
+        */
+       private void sendFile(Socket filesocket, String sFileName, long lFLength) throws IOException {
+
+               File file = new File(sFileName);
+               byte[] bytFile = new byte[toIntExact(lFLength)];
+               InputStream inFileStream = new FileInputStream(file);
+
+               OutputStream outFileStream = filesocket.getOutputStream();
+               int iCount;
+               while ((iCount = inFileStream.read(bytFile)) > 0) {
+                       outFileStream.write(bytFile, 0, iCount);
+               }
+               filesocket.close();
+       }
+
+
+       private void sendFile(String sFilePath, String sFileName) throws IOException {
+
+               sendCommCode(IoTCommCode.TRANSFER_FILE);
+               // Send file name
+               sendString(sFileName); recvAck();
+               File file = new File(sFilePath + sFileName);
+               int iFileLen = toIntExact(file.length());
+               System.out.println("IoTSlave: Sending file " + sFileName + " with length " + iFileLen + " bytes...");
+               // Send file length
+               sendInteger(iFileLen); recvAck();
+               byte[] bytFile = new byte[iFileLen];
+               InputStream inFileStream = new FileInputStream(file);
+
+               OutputStream outFileStream = socket.getOutputStream();
+               int iCount;
+               while ((iCount = inFileStream.read(bytFile)) > 0) {
+                       outFileStream.write(bytFile, 0, iCount);
+               }
+               System.out.println("IoTSlave: File sent!");
+               recvAck();
+       }
+
        /**
         * sendInteger() sends an integer in bytes
         */
@@ -392,6 +437,12 @@ public class IoTSlave {
                System.out.println("IoTSlave: Connection established with main!");
                // First contact with C++ IoTSlave
                System.out.println("IoTSlave: IoTSlave.o main is ready: " + iotSlaveMain.recvAck());
+               //iotSlaveMain.sendFile("../", "Lifxtest.so");
+               //iotSlaveMain.sendFile("../", "LightBulbTest_Stub.so");
+               //iotSlaveMain.sendFile("../", "Lifxtest.zip");
+               //iotSlaveMain.sendFile("../resources/", "Lifxtest.jar");
+               //iotSlaveMain.sendFile("../", "unzip.zip");
+               
 
                // =========================================
                // Create IoTSlave for driver object!
@@ -408,6 +459,10 @@ public class IoTSlave {
                System.out.println("IoTSlave: Connection established!");
                // First contact with C++ IoTSlave
                System.out.println("IoTSlave: IoTSlave.o is ready: " + iotSlave.recvAck());
+               //iotSlave.sendFile("../", "LifxLightBulb.so");
+               //iotSlave.sendFile("../", "LightBulb_Skeleton.so");
+               //iotSlave.sendFile("../", "LifxLightBulb.zip");
+               //iotSlave.sendFile("../", "unzip2.zip");
                iotSlave.createObjectCpp();
                //iotSlave.createNewIoTSetCpp();
                iotSlave.createNewIoTSetCpp("lb_addresses");
index 48b8955449d7c38c523b564a9a99de5e958268aa..4157921c7f8874fbddf043dfddea22ac72e5d106 100755 (executable)
@@ -4,7 +4,7 @@ include $(BASE)/common.mk
 
 #GCCFLAGS = -Wall -ansi -pedantic -g -std=c++11 -pthread -pg
 GCCFLAGS = -std=c++11 -pthread -pg
-INCLUDE =  -I$(BASE)/iotjava/iotruntime/cpp/socket/ -I$(BASE)/iotjava/iotruntime/cpp/ -I$(BASE)/iotjava/iotruntime/cpp/socket/ -I$(BASE)/iotjava/iotruntime/cpp/setrelation/ -I$(BASE)/iotjava/iotrmi/C++/ -I$(BASE)/benchmarks/virtuals/ -I$(BASE)/benchmarks/drivers/Cpp/LifxLightBulb -I$(BASE)/benchmarks/Cpp/Lifxtest/
+INCLUDE =  -I$(BASE)/iotjava/iotruntime/cpp/socket/ -I$(BASE)/iotjava/iotruntime/cpp/ -I$(BASE)/iotjava/iotruntime/cpp/socket/ -I$(BASE)/iotjava/iotruntime/cpp/setrelation/ -I$(BASE)/iotjava/iotrmi/C++/ -I$(BASE)/benchmarks/virtuals/ -I$(BASE)/benchmarks/drivers/Cpp/LifxLightBulb -I$(BASE)/benchmarks/drivers/Cpp/LabRoom -I$(BASE)/benchmarks/Cpp/Lifxtest/
 CCCLINKERFLAGS = -ldl
 
 all: java cpp
@@ -17,6 +17,11 @@ PHONY += cpp
 cpp:
        $(G++) $(GCCFLAGS) -o IoTSlave.o IoTSlave.cpp $(INCLUDE) $(CCCLINKERFLAGS)
 
+PHONY += cpp-arm
+cpp-arm:
+       $(ARM_G++) $(GCCFLAGS) -o IoTSlave.o IoTSlave.cpp $(INCLUDE) $(CCCLINKERFLAGS)
+       cp IoTSlave.o $(BASE)/bin/iotruntime/slave/
+
 PHONY += run
 run:
        java IoTSlave
@@ -31,5 +36,13 @@ clean:
        rm -rf *.o
        rm -rf *.log
        rm -rf gmon.out
+       rm -rf *.zip
+       rm -rf *.jar
+       #rm -rf *.so
+       pkill IoTSlave
+
+PHONY += kill
+kill:
+       pkill IoTSlave
 
 .PHONY: $(PHONY)
index 673abc42f61422f8525b652cce4748e43f853a35..372f6951327e17dd08f4bc95cd34418ca3630686 100644 (file)
@@ -30,7 +30,7 @@ class IoTRelation {
                        typename unordered_multimap<K,V>::const_iterator> 
                        equal_range(const K& k);                                                                                // Equal range iterator
                int size();                                                                                                                     // Set size
-               unordered_multimap<K,V> values();                                                                       // Return set contents
+               unordered_multimap<K,V>* values();                                                                      // Return set contents
 };
 
 
@@ -119,7 +119,7 @@ int IoTRelation<K,V>::size() {
  * Return a new copy of the set
  */
 template <class K,class V>
-unordered_multimap<K,V> IoTRelation<K,V>::values() {
+unordered_multimap<K,V>* IoTRelation<K,V>::values() {
 
        return new unordered_multimap<K,V>(*rel);
 }
index 5406e478d84fa20c75f44563a268bcbb009f52d2..154f36a5ad9811993c9512bcad92dfe35e8fe3a0 100644 (file)
@@ -19,6 +19,7 @@ import java.io.InputStreamReader;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
+import java.io.OutputStream;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
 import java.io.IOException;
@@ -27,6 +28,7 @@ import java.lang.Class;
 import java.lang.reflect.*;
 import java.net.Socket;
 import java.net.ServerSocket;
+import java.nio.ByteBuffer;
 import java.util.*;
 import static java.lang.Math.toIntExact;
 
@@ -83,11 +85,12 @@ public class IoTMaster {
        private static String STR_IOT_CODE_PATH;
        private static String STR_CONT_PATH;
        private static String STR_RUNTIME_DIR;
+       private static String STR_SLAVE_DIR;
        private static String STR_CLS_PATH;
        private static String STR_RMI_PATH;
        private static String STR_RMI_HOSTNAME;
        private static String STR_LOG_FILE_PATH;
-       private static String STR_SSH_USERNAME;
+       private static String STR_USERNAME;
        private static String STR_ROUTER_ADD;
        private static String STR_MONITORING_HOST;
        private static String STR_ZB_GATEWAY_ADDRESS;
@@ -97,6 +100,8 @@ public class IoTMaster {
        private static String STR_JVM_INIT_HEAP_SIZE;
        private static String STR_JVM_MAX_HEAP_SIZE;
        private static String STR_LANGUAGE;
+       private static String STR_SKEL_CLASS_SUFFIX;
+       private static String STR_STUB_CLASS_SUFFIX;
        private static boolean BOOL_VERBOSE;
 
        /**
@@ -108,6 +113,7 @@ public class IoTMaster {
        private static final String STR_CFG_FILE_EXT = ".config";
        private static final String STR_CLS_FILE_EXT = ".class";
        private static final String STR_JAR_FILE_EXT = ".jar";
+       private static final String STR_SO_FILE_EXT = ".so";
        private static final String STR_ZIP_FILE_EXT = ".zip";
        private static final String STR_TCP_PROTOCOL = "tcp";
        private static final String STR_UDP_PROTOCOL = "udp";
@@ -121,6 +127,11 @@ public class IoTMaster {
        private static final String STR_NO = "No";
        private static final String STR_JAVA = "Java";
        private static final String STR_CPP = "C++";
+       private static final String STR_SSH = "ssh";
+       private static final String STR_SCP = "scp";
+       private static final String STR_IOTSLAVE_CPP = "./IoTSlave.o";
+
+       private static int INT_SIZE = 4;        // send length in the size of integer (4 bytes)
 
        /**
         * Runtime class name constants - not to be configured by users
@@ -165,11 +176,12 @@ public class IoTMaster {
                STR_IOT_CODE_PATH = null;
                STR_CONT_PATH = null;
                STR_RUNTIME_DIR = null;
+               STR_SLAVE_DIR = null;
                STR_CLS_PATH = null;
                STR_RMI_PATH = null;
                STR_RMI_HOSTNAME = null;
                STR_LOG_FILE_PATH = null;
-               STR_SSH_USERNAME = null;
+               STR_USERNAME = null;
                STR_ROUTER_ADD = null;
                STR_MONITORING_HOST = null;
                STR_ZB_GATEWAY_ADDRESS = null;
@@ -223,11 +235,12 @@ public class IoTMaster {
                STR_IOT_CODE_PATH = prop.getProperty("IOT_CODE_PATH");
                STR_CONT_PATH = prop.getProperty("CONTROLLERS_CODE_PATH");
                STR_RUNTIME_DIR = prop.getProperty("RUNTIME_DIR");
+               STR_SLAVE_DIR = prop.getProperty("SLAVE_DIR");
                STR_CLS_PATH = prop.getProperty("CLASS_PATH");
                STR_RMI_PATH = prop.getProperty("RMI_PATH");
                STR_RMI_HOSTNAME = prop.getProperty("RMI_HOSTNAME");
                STR_LOG_FILE_PATH = prop.getProperty("LOG_FILE_PATH");
-               STR_SSH_USERNAME = prop.getProperty("SSH_USERNAME");
+               STR_USERNAME = prop.getProperty("USERNAME");
                STR_ROUTER_ADD = prop.getProperty("ROUTER_ADD");
                STR_MONITORING_HOST = prop.getProperty("MONITORING_HOST");
                STR_ZB_GATEWAY_ADDRESS = prop.getProperty("ZIGBEE_GATEWAY_ADDRESS");
@@ -237,6 +250,8 @@ public class IoTMaster {
                STR_JVM_INIT_HEAP_SIZE = prop.getProperty("JVM_INIT_HEAP_SIZE");
                STR_JVM_MAX_HEAP_SIZE = prop.getProperty("JVM_MAX_HEAP_SIZE");
                STR_LANGUAGE = prop.getProperty("LANGUAGE");
+               STR_SKEL_CLASS_SUFFIX = prop.getProperty("SKEL_CLASS_SUFFIX");
+               STR_STUB_CLASS_SUFFIX = prop.getProperty("STUB_CLASS_SUFFIX");
                if(prop.getProperty("VERBOSE").equals(STR_YES)) {
                        BOOL_VERBOSE = true;
                }
@@ -246,11 +261,12 @@ public class IoTMaster {
                RuntimeOutput.print("STR_IOT_CODE_PATH=" + STR_IOT_CODE_PATH, BOOL_VERBOSE);
                RuntimeOutput.print("STR_CONT_PATH=" + STR_CONT_PATH, BOOL_VERBOSE);
                RuntimeOutput.print("STR_RUNTIME_DIR=" + STR_RUNTIME_DIR, BOOL_VERBOSE);
+               RuntimeOutput.print("STR_SLAVE_DIR=" + STR_SLAVE_DIR, BOOL_VERBOSE);
                RuntimeOutput.print("STR_CLS_PATH=" + STR_CLS_PATH, BOOL_VERBOSE);
                RuntimeOutput.print("STR_RMI_PATH=" + STR_RMI_PATH, BOOL_VERBOSE);
                RuntimeOutput.print("STR_RMI_HOSTNAME=" + STR_RMI_HOSTNAME, BOOL_VERBOSE);
                RuntimeOutput.print("STR_LOG_FILE_PATH=" + STR_LOG_FILE_PATH, BOOL_VERBOSE);
-               RuntimeOutput.print("STR_SSH_USERNAME=" + STR_SSH_USERNAME, BOOL_VERBOSE);
+               RuntimeOutput.print("STR_USERNAME=" + STR_USERNAME, BOOL_VERBOSE);
                RuntimeOutput.print("STR_ROUTER_ADD=" + STR_ROUTER_ADD, BOOL_VERBOSE);
                RuntimeOutput.print("STR_MONITORING_HOST=" + STR_MONITORING_HOST, BOOL_VERBOSE);
                RuntimeOutput.print("STR_ZB_GATEWAY_ADDRESS=" + STR_ZB_GATEWAY_ADDRESS, BOOL_VERBOSE);
@@ -260,6 +276,8 @@ public class IoTMaster {
                RuntimeOutput.print("STR_JVM_INIT_HEAP_SIZE=" + STR_JVM_INIT_HEAP_SIZE, BOOL_VERBOSE);
                RuntimeOutput.print("STR_JVM_MAX_HEAP_SIZE=" + STR_JVM_MAX_HEAP_SIZE, BOOL_VERBOSE);
                RuntimeOutput.print("STR_LANGUAGE=" + STR_LANGUAGE, BOOL_VERBOSE);
+               RuntimeOutput.print("STR_SKEL_CLASS_SUFFIX=" + STR_SKEL_CLASS_SUFFIX, BOOL_VERBOSE);
+               RuntimeOutput.print("STR_STUB_CLASS_SUFFIX=" + STR_STUB_CLASS_SUFFIX, BOOL_VERBOSE);
                RuntimeOutput.print("BOOL_VERBOSE=" + BOOL_VERBOSE, BOOL_VERBOSE);
                RuntimeOutput.print("IoTMaster: Information extracted successfully!", BOOL_VERBOSE);
        }
@@ -340,14 +358,16 @@ public class IoTMaster {
         * @return  void
         */
        private void commMasterToSlave(Message msgSend, String strPurpose,
-               ObjectInputStream inStream, ObjectOutputStream outStream) 
+               InputStream _inStream, OutputStream _outStream)  
                        throws IOException, ClassNotFoundException {
 
                // Send message/command from master
+               ObjectOutputStream outStream = (ObjectOutputStream) _outStream;
                outStream.writeObject(msgSend);
                RuntimeOutput.print("IoTMaster: Send message: " + strPurpose, BOOL_VERBOSE);
 
                // Get reply from slave as acknowledgment
+               ObjectInputStream inStream = (ObjectInputStream) _inStream;
                Message msgReply = (Message) inStream.readObject();
                RuntimeOutput.print("IoTMaster: Reply message: " + msgReply.getMessage(), BOOL_VERBOSE);
        }
@@ -363,7 +383,7 @@ public class IoTMaster {
         * @return  void
         */
        private void instrumentIoTSetDevice(String strFieldIdentifier, String strObjName, String strFieldName, String strIoTSlaveObjectHostAdd,
-               ObjectInputStream inStream, ObjectOutputStream outStream) 
+               InputStream inStream, OutputStream outStream)  
                        throws IOException, ClassNotFoundException, InterruptedException {
 
                // Get information from the set
@@ -373,7 +393,7 @@ public class IoTMaster {
                        Message msgCrtIoTSet = new MessageCreateSetRelation(IoTCommCode.CREATE_NEW_IOTSET, strFieldName);
                        commMasterToSlave(msgCrtIoTSet, "Create new IoTSet for IoTDeviceAddress!", inStream, outStream);
                } else
-                       ;
+                       createNewIoTSetCpp(strFieldName, outStream, inStream);
                int iRows = listObject.size();
                RuntimeOutput.print("IoTMaster: Number of rows for IoTDeviceAddress: " + iRows, BOOL_VERBOSE);
                // Transfer the address
@@ -420,13 +440,14 @@ public class IoTMaster {
                                                strDeviceAddress, commHan.getComPort(strDeviceAddressKey), iDestDeviceDriverPort, bSrcPortWildCard, bDstPortWildCard);
                                commMasterToSlave(msgGetIoTSetObj, "Get IoTSet objects!", inStream, outStream);
                        } else
-                               ;
+                               getDeviceIoTSetObjectCpp(outStream, inStream, strDeviceAddress, commHan.getComPort(strDeviceAddressKey), iDestDeviceDriverPort, 
+                                       bSrcPortWildCard, bDstPortWildCard);
                }
                // Reinitialize IoTSet on device object
                if(STR_LANGUAGE.equals(STR_JAVA))
                        commMasterToSlave(new MessageSimple(IoTCommCode.REINITIALIZE_IOTSET_FIELD), "Reinitialize IoTSet fields!", inStream, outStream);
                else
-                       ;
+                       reinitializeIoTSetFieldCpp(outStream, inStream);
        }
 
 
@@ -441,7 +462,7 @@ public class IoTMaster {
         * @return  void
         */
        private void instrumentIoTSetZBDevice(Map.Entry<String,Object> map, String strObjName, String strFieldName, String strIoTSlaveObjectHostAdd,
-               ObjectInputStream inStream, ObjectOutputStream outStream) 
+               InputStream inStream, OutputStream outStream)  
                        throws IOException, ClassNotFoundException, InterruptedException {
 
                // Get information from the set
@@ -483,7 +504,7 @@ public class IoTMaster {
                        if(STR_LANGUAGE.equals(STR_JAVA)) {
                                Message msgGetIoTSetZBObj = new MessageGetSimpleDeviceObject(IoTCommCode.GET_ZB_DEV_IOTSET_OBJECT, strZBDevAddress);
                                commMasterToSlave(msgGetIoTSetZBObj, "Get IoTSet objects!", inStream, outStream);
-                       } else
+                       } else  // TODO: Implement IoTSet Zigbee for C++
                                ;
                }
                zbConfig.closeConnection();
@@ -502,7 +523,7 @@ public class IoTMaster {
         * @return  void
         */
        private void instrumentIoTSetAddress(String strFieldIdentifier, String strFieldName,
-               ObjectInputStream inStream, ObjectOutputStream outStream) 
+               InputStream inStream, OutputStream outStream)  
                        throws IOException, ClassNotFoundException, InterruptedException {
 
                // Get information from the set
@@ -524,7 +545,7 @@ public class IoTMaster {
                        if(STR_LANGUAGE.equals(STR_JAVA)) {
                                Message msgGetIoTSetAddObj = new MessageGetSimpleDeviceObject(IoTCommCode.GET_ADD_IOTSET_OBJECT, strAddress);
                                commMasterToSlave(msgGetIoTSetAddObj, "Get IoTSet objects!", inStream, outStream);
-                       } else
+                       } else  // TODO: Implement IoTSet Address for C++
                                ;
                }
                // Reinitialize IoTSet on device object
@@ -681,7 +702,6 @@ public class IoTMaster {
                        System.out.println("DEBUG: InstrumentPolicySetDevice: Port number: " + commHan.getComPort(strDeviceAddressKey));
                        System.out.println("DEBUG: InstrumentPolicySetDevice: Device address: " + strDeviceAddressKey + "\n\n");
 
-
                        // Send routing policy to router for device drivers and devices
                        // ROUTING POLICY: RMI communication - RMI registry and stub ports
                        if((iDestDeviceDriverPort == -1) && (!strProtocol.equals(STR_NO_PROTOCOL))) {
@@ -773,8 +793,6 @@ public class IoTMaster {
                }
                // Get the object and the class names
                // Build objects for IoTSet and IoTRelation fields in the device object classes
-//             mapClassNameToCrim.put(strObjClassName + strFieldObjectID, crim);
-//             HashMap<String,Object> hmObjectFieldObjects = crim.getFieldObjects();
                RuntimeOutput.print("IoTMaster: Going to instrument for " + strObjClassName + " with objectID " + 
                        strFieldObjectID, BOOL_VERBOSE);
                for(Map.Entry<String,Object> map : hmObjectFieldObjects.entrySet()) {
@@ -812,13 +830,26 @@ public class IoTMaster {
        /**
         * A private method to send files to a Java slave driver
         *
+        * @params  serverSocket                                ServerSocket
+        * @params  _inStream                                   InputStream
+        * @params  _outStream                                  OutputStream
+        * @params  strObjName                                  String
+        * @params  strObjClassName                             String
+        * @params  strObjClassInterfaceName    String
+        * @params  strObjStubClsIntfaceName    String
+        * @params  strIoTSlaveObjectHostAdd    String
+        * @params  strFieldObjectID                    String
+        * @params  arrFieldValues                              Object[]
+        * @params  arrFieldClasses                             Class[]
         * @return  void
         */
-       private void sendFileToJavaSlaveDriver(ServerSocket serverSocket, ObjectInputStream inStream, ObjectOutputStream outStream,
+       private void sendFileToJavaSlaveDriver(ServerSocket serverSocket, InputStream _inStream, OutputStream _outStream,
                String strObjName, String strObjClassName, String strObjClassInterfaceName, String strObjStubClsIntfaceName,
                String strIoTSlaveObjectHostAdd, String strFieldObjectID, Object[] arrFieldValues, Class[] arrFieldClasses) 
                        throws IOException, ClassNotFoundException {
 
+               ObjectInputStream inStream = (ObjectInputStream) _inStream;
+               ObjectOutputStream outStream = (ObjectOutputStream) _outStream;
                // Create message to transfer file first
                String sFileName = strObjClassName + STR_JAR_FILE_EXT;
                String sPath = STR_IOT_CODE_PATH + strObjClassName + "/" + sFileName;
@@ -838,6 +869,57 @@ public class IoTMaster {
        }
 
 
+       /**
+        * A private method to send files to a Java slave driver
+        *
+        * @return  void
+        */
+       private void sendFileToCppSlaveDriver(String strObjClassName, String strIoTSlaveObjectHostAdd) 
+                       throws IOException, ClassNotFoundException {
+
+               // Create message to transfer file first
+               String sFileName = strObjClassName + STR_ZIP_FILE_EXT;
+               String sFile = STR_IOT_CODE_PATH + strObjClassName + "/" + sFileName;
+               String strCmdSend = STR_SCP + " " + sFile + " " + STR_USERNAME + strIoTSlaveObjectHostAdd + ":" + STR_SLAVE_DIR;
+               runCommand(strCmdSend);
+               RuntimeOutput.print("IoTMaster: Executing: " + strCmdSend, BOOL_VERBOSE);
+               // Unzip file
+               String strCmdUnzip = STR_SSH + " " + STR_USERNAME + strIoTSlaveObjectHostAdd + " cd " +
+                                       STR_SLAVE_DIR + " sudo unzip " + sFileName + ";";
+               runCommand(strCmdUnzip);
+               RuntimeOutput.print("IoTMaster: Executing: " + strCmdUnzip, BOOL_VERBOSE);
+
+       }
+
+
+       /**
+        * Construct command line for Java IoTSlave
+        *
+        * @return       String
+        */
+       private String getCmdJavaDriverIoTSlave(String strIoTMasterHostAdd, String strIoTSlaveObjectHostAdd, String strObjName) {
+
+               return STR_SSH + " " + STR_USERNAME + strIoTSlaveObjectHostAdd + " cd " + STR_RUNTIME_DIR + " sudo java " +
+                       STR_CLS_PATH + " " + STR_RMI_PATH + " " + STR_RMI_HOSTNAME +
+                       strIoTSlaveObjectHostAdd + " " + STR_IOT_SLAVE_CLS + " " + strIoTMasterHostAdd + " " +
+                       commHan.getComPort(strObjName) + " " + commHan.getRMIRegPort(strObjName) + " " +
+                       commHan.getRMIStubPort(strObjName) + " >& " + STR_LOG_FILE_PATH + strObjName + ".log &";
+       }
+
+
+       /**
+        * Construct command line for C++ IoTSlave
+        *
+        * @return       String
+        */
+       private String getCmdCppDriverIoTSlave(String strIoTMasterHostAdd, String strIoTSlaveObjectHostAdd, String strObjName) {
+
+               return STR_SSH + " " + STR_USERNAME + strIoTSlaveObjectHostAdd + " cd " +
+                                       STR_SLAVE_DIR + " sudo " + STR_IOTSLAVE_CPP + " " + strIoTMasterHostAdd + " " +
+                                       commHan.getComPort(strObjName) + " " + strObjName;
+       }
+
+
        /**
         * A private method to create an object on a specific machine
         *
@@ -867,18 +949,29 @@ public class IoTMaster {
                //           -Djava.rmi.server.codebase=file:./*.jar
                //           iotruntime.IoTSlave dw-1.eecs.uci.edu 46151 23829 42874 &
                // The In-Port for IoTMaster is the Out-Port for IoTSlave and vice versa
-               String strSSHCommand = STR_SSH_USERNAME + strIoTSlaveObjectHostAdd + " cd " + STR_RUNTIME_DIR + " sudo java " +
-                       STR_CLS_PATH + " " + STR_RMI_PATH + " " + STR_RMI_HOSTNAME +
-                       strIoTSlaveObjectHostAdd + " " + STR_IOT_SLAVE_CLS + " " + strIoTMasterHostAdd + " " +
-                       commHan.getComPort(strObjName) + " " + commHan.getRMIRegPort(strObjName) + " " +
-                       commHan.getRMIStubPort(strObjName) + " >& " + STR_LOG_FILE_PATH + strObjName + ".log &";
+               String strSSHCommand = null;
+               if(STR_LANGUAGE.equals(STR_JAVA))
+                       strSSHCommand = getCmdJavaDriverIoTSlave(strIoTMasterHostAdd, strIoTSlaveObjectHostAdd, strObjName);
+               else
+                       strSSHCommand = getCmdCppDriverIoTSlave(strIoTMasterHostAdd, strIoTSlaveObjectHostAdd, strObjName);
+
                RuntimeOutput.print(strSSHCommand, BOOL_VERBOSE);
                // Start a new thread to start a new JVM
                createThread(strSSHCommand);
                ServerSocket serverSocket = new ServerSocket(commHan.getComPort(strObjName));
                Socket socket = serverSocket.accept();
-               ObjectInputStream inStream = new ObjectInputStream(socket.getInputStream());
-               ObjectOutputStream outStream = new ObjectOutputStream(socket.getOutputStream());
+               //InputStream inStream = new ObjectInputStream(socket.getInputStream());
+               //OutputStream outStream = new ObjectOutputStream(socket.getOutputStream());
+               InputStream inStream = null;
+               OutputStream outStream = null;
+               if(STR_LANGUAGE.equals(STR_JAVA)) {
+                       inStream = new ObjectInputStream(socket.getInputStream());
+                       outStream = new ObjectOutputStream(socket.getOutputStream());
+               } else {        // At this point the language is certainly C++, otherwise would've complained above
+                       inStream = new BufferedInputStream(socket.getInputStream());
+                       outStream = new BufferedOutputStream(socket.getOutputStream());
+                       recvAck(inStream);
+               }
 
                // PROFILING
                result = System.currentTimeMillis()-start;
@@ -891,8 +984,12 @@ public class IoTMaster {
                        sendFileToJavaSlaveDriver(serverSocket, inStream, outStream, strObjName, 
                                strObjClassName, strObjClassInterfaceName, strObjStubClsIntfaceName,
                                strIoTSlaveObjectHostAdd, strFieldObjectID, arrFieldValues, arrFieldClasses);
-               } else
-                       ;
+               } else {
+                       sendFileToCppSlaveDriver(strObjClassName, strIoTSlaveObjectHostAdd);
+                       createObjectCpp(strObjName, strObjClassName, strObjClassInterfaceName, strIoTSlaveObjectHostAdd,
+                       commHan.getRMIRegPort(strObjName), commHan.getRMIStubPort(strObjName), arrFieldValues, arrFieldClasses,
+                       outStream, inStream);
+               }
 
                // PROFILING
                result = System.currentTimeMillis()-start;
@@ -903,8 +1000,7 @@ public class IoTMaster {
 
                // Instrument the class source code and look for IoTSet for device addresses
                // e.g. @config private IoTSet<IoTDeviceAddress> lb_addresses;
-               RuntimeOutput.print("IoTMaster: Instantiating for " + strObjClassName + " with objectID " + 
-                       strFieldObjectID, BOOL_VERBOSE);
+               RuntimeOutput.print("IoTMaster: Instantiating for " + strObjClassName + " with objectID " + strFieldObjectID, BOOL_VERBOSE);
                // Get the object and the class names
                // Build objects for IoTSet and IoTRelation fields in the device object classes
                Object crimObj = mapClassNameToCrim.get(strObjClassName + strFieldObjectID);
@@ -940,8 +1036,7 @@ public class IoTMaster {
                                                instrumentIoTSetAddress(strFieldIdentifier, strFieldName, inStream, outStream);
                                        }
                                } else {
-                                       String strErrMsg = "IoTMaster: Device driver object" +
-                                                                               " can only have IoTSet<IoTAddress>, IoTSet<IoTDeviceAddress>," +
+                                       String strErrMsg = "IoTMaster: Device driver object can only have IoTSet<IoTAddress>, IoTSet<IoTDeviceAddress>," +
                                                                                " or IoTSet<IoTZigbeeAddress>!";
                                        throw new Error(strErrMsg);
                                }
@@ -953,9 +1048,11 @@ public class IoTMaster {
                // End the session
                // TODO: Change this later
 
-               if(STR_LANGUAGE.equals(STR_JAVA))
-                       outStream.writeObject(new MessageSimple(IoTCommCode.END_SESSION));
-               else
+               if(STR_LANGUAGE.equals(STR_JAVA)) {
+                       ObjectOutputStream oStream = (ObjectOutputStream) outStream;
+                       oStream.writeObject(new MessageSimple(IoTCommCode.END_SESSION));
+               } else  // C++ side for now will be running continuously because it's an infinite loop (not in a separate thread)
+                       //endSessionCpp(outStream);
                        ;
 
                // PROFILING
@@ -1107,7 +1204,7 @@ public class IoTMaster {
         * @params  outStream                 ObjectOutputStream communication
         * @return      void
         */
-       private void initializeSetsAndRelationsJava(ObjectInputStream inStream, ObjectOutputStream outStream) 
+       private void initializeSetsAndRelationsJava(InputStream inStream, OutputStream outStream)  
                throws IOException, ClassNotFoundException {
                // Get list of fields
                List<String> strFields = objInitHand.getListOfFields();
@@ -1166,7 +1263,7 @@ public class IoTMaster {
         * @params  outStream                 ObjectOutputStream communication
         * @return      void
         */
-       private void initializeSetsAndRelationsCpp(ObjectInputStream inStream, ObjectOutputStream outStream) 
+       private void initializeSetsAndRelationsCpp(InputStream inStream, OutputStream outStream)  
                throws IOException, ClassNotFoundException {
                // Get list of fields
                List<String> strFields = objInitHand.getListOfFields();
@@ -1175,45 +1272,39 @@ public class IoTMaster {
                        IoTCommCode iotcommMsg = objInitHand.getFieldMessage(str);
                        if (iotcommMsg == IoTCommCode.CREATE_NEW_IOTSET) {
                                // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO CREATE IOTSET
-                               Message msgCrtIoTSet = new MessageCreateSetRelation(IoTCommCode.CREATE_NEW_IOTSET, str);
-                               commMasterToSlave(msgCrtIoTSet, "Create new IoTSet!", inStream, outStream);
+                               createNewIoTSetCpp(str, outStream, inStream);
                                List<ObjectInitInfo> listObject = objInitHand.getListObjectInitInfo(str);
                                for (ObjectInitInfo objInitInfo : listObject) {
                                        // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO FILL IN IOTSET
-                                       commMasterToSlave(new MessageGetObject(IoTCommCode.GET_IOTSET_OBJECT, objInitInfo.getIoTSlaveObjectHostAdd(),
-                                               objInitInfo.getObjectName(), objInitInfo.getObjectClassName(), objInitInfo.getObjectClassInterfaceName(), 
+                                       getIoTSetRelationObjectCpp(objInitInfo.getIoTSlaveObjectHostAdd(), objInitInfo.getObjectName(), 
+                                               objInitInfo.getObjectClassName(), objInitInfo.getObjectClassInterfaceName(), 
                                                objInitInfo.getObjectStubClassInterfaceName(), objInitInfo.getRMIRegistryPort(), objInitInfo.getRMIStubPort(),
-                                               objInitInfo.getRMICallbackPorts()), "Get IoTSet object!", inStream, outStream);
-
+                                               objInitInfo.getRMICallbackPorts(), outStream, inStream);
                                }
                                // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO REINITIALIZE IOTSET FIELD
-                               commMasterToSlave(new MessageSimple(IoTCommCode.REINITIALIZE_IOTSET_FIELD),
-                                       "Renitialize IoTSet field!", inStream, outStream);
+                               reinitializeIoTSetFieldCpp(outStream, inStream);
                        } else if (iotcommMsg == IoTCommCode.CREATE_NEW_IOTRELATION) {
                                // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO CREATE IOTRELATION
-                               Message msgCrtIoTRel = new MessageCreateSetRelation(IoTCommCode.CREATE_NEW_IOTRELATION, str);
-                               commMasterToSlave(msgCrtIoTRel, "Create new IoTRelation!", inStream, outStream);
+                               // TODO: createNewIoTRelation needs to be created here!
+                               createNewIoTRelationCpp(str, outStream, inStream);
                                List<ObjectInitInfo> listObject = objInitHand.getListObjectInitInfo(str);
                                List<ObjectInitInfo> listSecondObject = objInitHand.getSecondObjectInitInfo(str);
                                Iterator it = listSecondObject.iterator();
                                for (ObjectInitInfo objInitInfo : listObject) {
                                        // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO FILL IN IOTRELATION (FIRST OBJECT)
-                                       commMasterToSlave(new MessageGetObject(IoTCommCode.GET_IOTRELATION_FIRST_OBJECT, 
-                                               objInitInfo.getIoTSlaveObjectHostAdd(), objInitInfo.getObjectName(), objInitInfo.getObjectClassName(),
-                                               objInitInfo.getObjectClassInterfaceName(), objInitInfo.getObjectStubClassInterfaceName(),
-                                               objInitInfo.getRMIRegistryPort(), objInitInfo.getRMIStubPort(), objInitInfo.getRMICallbackPorts()), 
-                                               "Get IoTRelation first object!", inStream, outStream);
+                                       getIoTSetRelationObjectCpp(objInitInfo.getIoTSlaveObjectHostAdd(), objInitInfo.getObjectName(), 
+                                               objInitInfo.getObjectClassName(), objInitInfo.getObjectClassInterfaceName(), 
+                                               objInitInfo.getObjectStubClassInterfaceName(), objInitInfo.getRMIRegistryPort(), objInitInfo.getRMIStubPort(),
+                                               objInitInfo.getRMICallbackPorts(), outStream, inStream);
                                        ObjectInitInfo objSecObj = (ObjectInitInfo) it.next();
                                        // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO FILL IN IOTRELATION (SECOND OBJECT)
-                                       commMasterToSlave(new MessageGetObject(IoTCommCode.GET_IOTRELATION_SECOND_OBJECT,
-                                               objSecObj.getIoTSlaveObjectHostAdd(), objSecObj.getObjectName(), objSecObj.getObjectClassName(),
-                                               objSecObj.getObjectClassInterfaceName(), objSecObj.getObjectStubClassInterfaceName(),
-                                               objSecObj.getRMIRegistryPort(), objSecObj.getRMIStubPort(), objSecObj.getRMICallbackPorts()), 
-                                               "Get IoTRelation second object!", inStream, outStream);
+                                       getIoTSetRelationObjectCpp(objSecObj.getIoTSlaveObjectHostAdd(), objSecObj.getObjectName(), 
+                                               objSecObj.getObjectClassName(), objSecObj.getObjectClassInterfaceName(), 
+                                               objSecObj.getObjectStubClassInterfaceName(), objSecObj.getRMIRegistryPort(), objSecObj.getRMIStubPort(),
+                                               objSecObj.getRMICallbackPorts(), outStream, inStream);
                                }
                                // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO REINITIALIZE IOTRELATION FIELD
-                               commMasterToSlave(new MessageSimple(IoTCommCode.REINITIALIZE_IOTRELATION_FIELD),
-                                       "Renitialize IoTRelation field!", inStream, outStream);
+                               reinitializeIoTRelationFieldCpp(outStream, inStream);
                        }
                }
        }
@@ -1305,14 +1396,21 @@ public class IoTMaster {
                }
        }
 
+
        /**
         * A method to send files to Java IoTSlave
         *
+        * @params  strObjControllerName      String
+        * @params  serverSocket              ServerSocket
+        * @params  inStream                  ObjectInputStream communication
+        * @params  outStream                 ObjectOutputStream communication
         * @return       void
         */     
        private void sendFileToJavaSlave(String strObjControllerName, ServerSocket serverSocket, 
-                       ObjectInputStream inStream, ObjectOutputStream outStream) throws IOException, ClassNotFoundException {
+                       InputStream _inStream, OutputStream _outStream) throws IOException, ClassNotFoundException {
 
+               ObjectInputStream inStream = (ObjectInputStream) _inStream;
+               ObjectOutputStream outStream = (ObjectOutputStream) _outStream;
                // Send .jar file
                String strControllerJarName = strObjControllerName + STR_JAR_FILE_EXT;
                String strControllerJarNamePath = STR_CONT_PATH + strObjControllerName + "/" +
@@ -1343,6 +1441,436 @@ public class IoTMaster {
        }
 
 
+       /**
+        * A method to send files to C++ IoTSlave
+        *
+        * @return       void
+        * TODO: Need to look into this (as of now, file transferred retains the "data" format, 
+        * hence it is unreadable from outside world
+        */
+       private void sendFileToCppSlave(String sFilePath, String sFileName, Socket fileSocket, 
+                       InputStream inStream, OutputStream outStream) throws IOException {
+
+               sendCommCode(IoTCommCode.TRANSFER_FILE, outStream, inStream);
+               // Send file name
+               sendString(sFileName, outStream); recvAck(inStream);
+               File file = new File(sFilePath + sFileName);
+               int iFileLen = toIntExact(file.length());
+               RuntimeOutput.print("IoTSlave: Sending file " + sFileName + " with length " + iFileLen + " bytes...", BOOL_VERBOSE);
+               // Send file length
+               sendInteger(iFileLen, outStream); recvAck(inStream);
+               RuntimeOutput.print("IoTSlave: Sent file size!", BOOL_VERBOSE);
+               byte[] bytFile = new byte[iFileLen];
+               InputStream inFileStream = new FileInputStream(file);
+               RuntimeOutput.print("IoTSlave: Opened file!", BOOL_VERBOSE);
+
+               OutputStream outFileStream = fileSocket.getOutputStream();
+               RuntimeOutput.print("IoTSlave: Got output stream!", BOOL_VERBOSE);
+               int iCount;
+               while ((iCount = inFileStream.read(bytFile)) > 0) {
+                       outFileStream.write(bytFile, 0, iCount);
+               }
+               RuntimeOutput.print("IoTSlave: File sent!", BOOL_VERBOSE);
+               recvAck(inStream);
+       }
+
+
+       /**
+        * A method to send files to C++ IoTSlave (now master using Process() to start 
+        * file transfer using scp)
+        *
+        * @return       void
+        */
+       private void sendFileToCppSlave(String sFilePath, String sFileName) throws IOException {
+
+               // Construct shell command to transfer file     
+               String sFile = sFilePath + sFileName;
+               String strCmdSend = STR_SCP + " " + sFile + " " + STR_USERNAME + strIoTSlaveControllerHostAdd + ":" + STR_SLAVE_DIR;
+               runCommand(strCmdSend);
+               RuntimeOutput.print("IoTMaster: Executing: " + strCmdSend, BOOL_VERBOSE);
+               // Unzip file
+               String strCmdUnzip = STR_SSH + " " + STR_USERNAME + strIoTSlaveControllerHostAdd + " cd " +
+                                       STR_SLAVE_DIR + " sudo unzip " + sFileName + ";";
+               runCommand(strCmdUnzip);
+               RuntimeOutput.print("IoTMaster: Executing: " + strCmdUnzip, BOOL_VERBOSE);
+       }
+
+
+       /**
+        * runCommand() method runs shell command
+        *
+        * @param   strCommand  String that contains command line
+        * @return  void
+        */
+       private void runCommand(String strCommand) {
+
+               try {
+                       Runtime runtime = Runtime.getRuntime();
+                       Process process = runtime.exec(strCommand);
+                       process.waitFor();
+               } catch (IOException ex) {
+                       System.out.println("RouterConfig: IOException: " + ex.getMessage());
+                       ex.printStackTrace();
+               } catch (InterruptedException ex) {
+                       System.out.println("RouterConfig: InterruptException: " + ex.getMessage());
+                       ex.printStackTrace();
+               }
+       }
+
+
+       /**
+        * Construct command line for Java IoTSlave
+        *
+        * @return       String
+        */
+       private String getCmdJavaIoTSlave(String strObjControllerName) {
+
+               return STR_SSH + " " + STR_USERNAME + strIoTSlaveControllerHostAdd + " cd " +
+                                       STR_RUNTIME_DIR + " sudo java " + STR_JVM_INIT_HEAP_SIZE + " " + 
+                                       STR_JVM_MAX_HEAP_SIZE + " " + STR_CLS_PATH + " " +
+                                       STR_RMI_PATH + " " + STR_IOT_SLAVE_CLS + " " + strIoTMasterHostAdd + " " +
+                                       commHan.getComPort(strObjControllerName) + " " +
+                                       commHan.getRMIRegPort(strObjControllerName) + " " +
+                                       commHan.getRMIStubPort(strObjControllerName) + " >& " +
+                                       STR_LOG_FILE_PATH + strObjControllerName + ".log &";
+       }
+
+
+       /**
+        * Construct command line for C++ IoTSlave
+        *
+        * @return       String
+        */
+       private String getCmdCppIoTSlave(String strObjControllerName) {
+
+               return STR_SSH + " " + STR_USERNAME + strIoTSlaveControllerHostAdd + " cd " +
+                                       STR_SLAVE_DIR + " sudo " + STR_IOTSLAVE_CPP + " " + strIoTMasterHostAdd + " " +
+                                       commHan.getComPort(strObjControllerName) + " " + strObjControllerName;
+       }
+
+
+       /**
+        * sendInteger() sends an integer in bytes
+        */
+       public void sendInteger(int intSend, OutputStream outStream) throws IOException {
+
+               BufferedOutputStream output = (BufferedOutputStream) outStream;
+               // Transform integer into bytes
+               ByteBuffer bb = ByteBuffer.allocate(INT_SIZE);
+               bb.putInt(intSend);
+               // Send the byte array
+               output.write(bb.array(), 0, INT_SIZE);
+               output.flush();
+       }
+
+
+       /**
+        * recvInteger() receives integer in bytes
+        */
+       public int recvInteger(InputStream inStream) throws IOException {
+
+               BufferedInputStream input = (BufferedInputStream) inStream;
+               // Wait until input is available
+               while(input.available() == 0);
+               // Read integer - 4 bytes
+               byte[] recvInt = new byte[INT_SIZE];
+               input.read(recvInt, 0, INT_SIZE);
+               int retVal = ByteBuffer.wrap(recvInt).getInt();
+
+               return retVal;
+       }
+
+
+       /**
+        * recvString() receives String in bytes
+        */
+       public String recvString(InputStream inStream) throws IOException {
+
+               BufferedInputStream input = (BufferedInputStream) inStream;
+               int strLen = recvInteger(inStream);
+               // Wait until input is available
+               while(input.available() == 0);
+               // Read String per strLen
+               byte[] recvStr = new byte[strLen];
+               input.read(recvStr, 0, strLen);
+               String retVal = new String(recvStr);
+
+               return retVal;
+       }
+
+
+       /**
+        * sendString() sends a String in bytes
+        */
+       public void sendString(String strSend, OutputStream outStream) throws IOException {
+
+               BufferedOutputStream output = (BufferedOutputStream) outStream;
+               // Transform String into bytes
+               byte[] strSendBytes = strSend.getBytes();
+               int strLen = strSend.length();
+               // Send the string length first
+               sendInteger(strLen, outStream);
+               // Send the byte array
+               output.write(strSendBytes, 0, strLen);
+               output.flush();
+       }
+
+
+       /**
+        * Convert integer to enum
+        */
+       public IoTCommCode getCode(int intCode) throws IOException {
+
+               IoTCommCode[] commCode = IoTCommCode.values();
+               IoTCommCode retCode = commCode[intCode];
+               return retCode;
+
+       }
+
+
+       /**
+        * Receive ACK
+        */
+       public boolean recvAck(InputStream inStream) throws IOException {
+
+               int intAck = recvInteger(inStream);
+               IoTCommCode codeAck = getCode(intAck);
+               if (codeAck == IoTCommCode.ACKNOWLEDGED)
+                       return true;
+               return false;
+
+       }
+
+
+       /**
+        * Send END
+        */
+       public void sendEndTransfer(OutputStream outStream) throws IOException {
+
+               int endCode = IoTCommCode.END_TRANSFER.ordinal();
+               sendInteger(endCode, outStream);
+       }
+
+
+       /**
+        * Send communication code to C++
+        */
+       public void sendCommCode(IoTCommCode inpCommCode, OutputStream outStream, InputStream inStream) throws IOException {
+
+
+               IoTCommCode commCode = inpCommCode;
+               int intCode = commCode.ordinal();
+               // TODO: delete this later
+               System.out.println("DEBUG: Sending " + commCode + " with ordinal: " + intCode);
+               sendInteger(intCode, outStream); recvAck(inStream);
+       }
+
+
+       /**
+        * Create a main controller object for C++
+        */
+       public void createMainObjectCpp(String strObjControllerName, OutputStream outStream, InputStream inStream) throws IOException {
+
+               sendCommCode(IoTCommCode.CREATE_MAIN_OBJECT, outStream, inStream);
+               String strMainObjName = strObjControllerName;
+               sendString(strMainObjName, outStream); recvAck(inStream);
+               RuntimeOutput.print("IoTSlave: Create a main object: " + strMainObjName, BOOL_VERBOSE);
+       }
+
+
+       /**
+        * A helper function that converts Class into String
+        *
+        * @param  strDataType  String MySQL data type
+        * @return              Class
+        */
+       public String getClassConverted(Class<?> cls) {
+
+               if (cls == String.class) {
+                       return "string";
+               } else if (cls == int.class) {
+                       return "int";
+               } else {
+                       return null;
+               }
+       }
+
+
+       /**
+        * A helper function that converts Object into String for transfer to C++ slave
+        *
+        * @param  obj           Object to be converted
+        * @param  strClassType  String Java Class type
+        * @return               Object
+        */
+       public String getObjectConverted(Object obj) {
+
+               if (obj instanceof String) {
+                       return (String) obj;
+               } else if (obj instanceof Integer) {
+                       return Integer.toString((Integer) obj);
+               } else {
+                       return null;
+               }
+       }
+
+
+       /**
+        * Create a driver object for C++
+        */
+       public void createObjectCpp(String strObjName, String strObjClassName, String strObjClassInterfaceName, String strIoTSlaveObjectHostAdd, 
+               Integer iRMIRegistryPort, Integer iRMIStubPort, Object[] arrFieldValues, Class[] arrFieldClasses, 
+               OutputStream outStream, InputStream inStream) throws IOException {
+
+               sendCommCode(IoTCommCode.CREATE_OBJECT, outStream, inStream);
+               RuntimeOutput.print("IoTSlave: Send request to create a driver object... ", BOOL_VERBOSE);
+               RuntimeOutput.print("IoTSlave: Driver object name: " + strObjName, BOOL_VERBOSE);
+               sendString(strObjName, outStream); recvAck(inStream);
+               RuntimeOutput.print("IoTSlave: Driver object class name: " + strObjClassName, BOOL_VERBOSE);
+               sendString(strObjClassName, outStream); recvAck(inStream);
+               RuntimeOutput.print("IoTSlave: Driver object interface name: " + strObjClassInterfaceName, BOOL_VERBOSE);
+               sendString(strObjStubClsIntfaceName, outStream); recvAck(inStream);
+               RuntimeOutput.print("IoTSlave: Driver object skeleton class name: " + strObjClassInterfaceName + STR_SKEL_CLASS_SUFFIX, BOOL_VERBOSE);
+               sendString(strObjClassInterfaceName + STR_SKEL_CLASS_SUFFIX, outStream); recvAck(inStream);
+               RuntimeOutput.print("IoTSlave: Driver object registry port: " + iRMIRegistryPort, BOOL_VERBOSE);
+               sendInteger(iRMIRegistryPort, outStream); recvAck(inStream);
+               RuntimeOutput.print("IoTSlave: Driver object stub port: " + iRMIStubPort, BOOL_VERBOSE);
+               sendInteger(iRMIStubPort, outStream); recvAck(inStream);
+               int numOfArgs = arrFieldValues.length;
+               RuntimeOutput.print("IoTSlave: Send constructor arguments! Number of arguments: " + numOfArgs, BOOL_VERBOSE);
+               sendInteger(numOfArgs, outStream); recvAck(inStream);
+               for(Object obj : arrFieldValues) {
+                       String str = getObjectConverted(obj);
+                       sendString(str, outStream); recvAck(inStream);
+               }
+               RuntimeOutput.print("IoTSlave: Send constructor argument classes!", BOOL_VERBOSE);
+               for(Class cls : arrFieldClasses) {
+                       String str = getClassConverted(cls);
+                       sendString(str, outStream); recvAck(inStream);
+               }
+       }
+
+
+       /**
+        * Create new IoTSet for C++
+        */
+       public void createNewIoTSetCpp(String strObjFieldName, OutputStream outStream, InputStream inStream) throws IOException {
+
+               sendCommCode(IoTCommCode.CREATE_NEW_IOTSET, outStream, inStream);
+               RuntimeOutput.print("IoTSlave: Creating new IoTSet...", BOOL_VERBOSE);
+               RuntimeOutput.print("IoTSlave: Send object field name: " + strObjFieldName, BOOL_VERBOSE);
+               sendString(strObjFieldName, outStream); recvAck(inStream);
+       }
+
+
+       /**
+        * Create new IoTRelation for C++
+        */
+       public void createNewIoTRelationCpp(String strObjFieldName, OutputStream outStream, InputStream inStream) throws IOException {
+
+               sendCommCode(IoTCommCode.CREATE_NEW_IOTRELATION, outStream, inStream);
+               RuntimeOutput.print("IoTSlave: Creating new IoTRelation...", BOOL_VERBOSE);
+               RuntimeOutput.print("IoTSlave: Send object field name: " + strObjFieldName, BOOL_VERBOSE);
+               sendString(strObjFieldName, outStream); recvAck(inStream);
+       }
+
+
+       /**
+        * Get a IoTDeviceAddress object for C++
+        */
+       public void getDeviceIoTSetObjectCpp(OutputStream outStream, InputStream inStream,
+                       String strDeviceAddress, int iSourcePort, int iDestPort, boolean bSourceWildCard, boolean bDestWildCard) throws IOException {
+
+               sendCommCode(IoTCommCode.GET_DEVICE_IOTSET_OBJECT, outStream, inStream);
+               RuntimeOutput.print("IoTSlave: Getting IoTDeviceAddress...", BOOL_VERBOSE);
+               sendString(strDeviceAddress, outStream); recvAck(inStream);
+               sendInteger(iSourcePort, outStream); recvAck(inStream);
+               sendInteger(iDestPort, outStream); recvAck(inStream);
+               int iSourceWildCard = (bSourceWildCard ? 1 : 0);
+               sendInteger(iSourceWildCard, outStream); recvAck(inStream);
+               int iDestWildCard = (bDestWildCard ? 1 : 0);
+               sendInteger(iDestWildCard, outStream); recvAck(inStream);
+               RuntimeOutput.print("IoTSlave: Send device address: " + strDeviceAddress, BOOL_VERBOSE);
+       }
+
+
+       /**
+        * Get a IoTSet content object for C++
+        */
+       public void getIoTSetRelationObjectCpp(String strIoTSlaveHostAddress, String strObjectName, String strObjectClassName, 
+                       String strObjectClassInterfaceName, String strObjectStubClassInterfaceName, int iRMIRegistryPort, int iRMIStubPort, 
+                       Integer[] iCallbackPorts, OutputStream outStream, InputStream inStream) throws IOException {
+
+               sendCommCode(IoTCommCode.GET_IOTSET_OBJECT, outStream, inStream);
+               RuntimeOutput.print("IoTSlave: Getting IoTSet object content...", BOOL_VERBOSE);
+               // Send info
+               RuntimeOutput.print("IoTSlave: Send host address: " + strIoTSlaveHostAddress, BOOL_VERBOSE);
+               sendString(strIoTSlaveHostAddress, outStream); recvAck(inStream);
+               RuntimeOutput.print("IoTSlave: Driver object name: " + strObjectName, BOOL_VERBOSE);
+               sendString(strObjectName, outStream); recvAck(inStream);
+               RuntimeOutput.print("IoTSlave: Driver object class name: " + strObjectClassName, BOOL_VERBOSE);
+               sendString(strObjectClassName, outStream); recvAck(inStream);
+               RuntimeOutput.print("IoTSlave: Driver object interface name: " + strObjectClassInterfaceName, BOOL_VERBOSE);
+               sendString(strObjectClassInterfaceName, outStream); recvAck(inStream);
+               RuntimeOutput.print("IoTSlave: Driver object stub class name: " + strObjectStubClassInterfaceName + STR_STUB_CLASS_SUFFIX, BOOL_VERBOSE);
+               sendString(strObjectStubClassInterfaceName + STR_STUB_CLASS_SUFFIX, outStream); recvAck(inStream);
+               RuntimeOutput.print("IoTSlave: Driver object registry port: " + iRMIRegistryPort, BOOL_VERBOSE);
+               sendInteger(iRMIRegistryPort, outStream); recvAck(inStream);
+               RuntimeOutput.print("IoTSlave: Driver object stub port: " + iRMIStubPort, BOOL_VERBOSE);
+               sendInteger(iRMIStubPort, outStream); recvAck(inStream);
+               sendInteger(iCallbackPorts.length, outStream); recvAck(inStream);
+               for(Integer i : iCallbackPorts) {
+                       sendInteger(i, outStream); recvAck(inStream);
+               }
+       }
+
+
+       /**
+        * Reinitialize IoTRelation field for C++
+        */
+       private void reinitializeIoTRelationFieldCpp(OutputStream outStream, InputStream inStream) throws IOException {
+
+               RuntimeOutput.print("IoTSlave: About to Reinitialize IoTRelation field!", BOOL_VERBOSE);
+               sendCommCode(IoTCommCode.REINITIALIZE_IOTRELATION_FIELD, outStream, inStream);
+               RuntimeOutput.print("IoTSlave: Reinitialize IoTRelation field!", BOOL_VERBOSE);
+       }
+
+
+       /**
+        * Reinitialize IoTSet field for C++
+        */
+       private void reinitializeIoTSetFieldCpp(OutputStream outStream, InputStream inStream) throws IOException {
+
+               RuntimeOutput.print("IoTSlave: About to Reinitialize IoTSet field!", BOOL_VERBOSE);
+               sendCommCode(IoTCommCode.REINITIALIZE_IOTSET_FIELD, outStream, inStream);
+               RuntimeOutput.print("IoTSlave: Reinitialize IoTSet field!", BOOL_VERBOSE);
+       }
+
+
+       /**
+        * Invoke init() for C++
+        */
+       private void invokeInitMethodCpp(OutputStream outStream, InputStream inStream) throws IOException {
+
+               sendCommCode(IoTCommCode.INVOKE_INIT_METHOD, outStream, inStream);
+               RuntimeOutput.print("IoTSlave: Invoke init method!", BOOL_VERBOSE);
+       }
+
+
+       /**
+        * End session for C++
+        */
+       public void endSessionCpp(OutputStream outStream) throws IOException {
+
+               // Send message to end session
+               IoTCommCode endSessionCode = IoTCommCode.END_SESSION;
+               int intCode = endSessionCode.ordinal();
+               sendInteger(intCode, outStream);
+               //RuntimeOutput.print("IoTSlave: Send request to create a main object: " + strObjName, BOOL_VERBOSE);
+               RuntimeOutput.print("IoTSlave: Send request to end session!", BOOL_VERBOSE);
+       }
+
+
        /**
         * A method to assign objects to multiple JVMs, including
         * the controller/device object that uses other objects
@@ -1387,22 +1915,29 @@ public class IoTMaster {
                                        strIoTSlaveControllerHostAdd, STR_TCP_PROTOCOL, commHan.getComPort(strObjControllerName));
 
                                // Construct ssh command line and create a controller thread for e.g. AcmeProximity
-                               String strSSHCommand = STR_SSH_USERNAME + strIoTSlaveControllerHostAdd + " cd " +
-                                       STR_RUNTIME_DIR + " sudo java " + STR_JVM_INIT_HEAP_SIZE + " " + 
-                                       STR_JVM_MAX_HEAP_SIZE + " " + STR_CLS_PATH + " " +
-                                       STR_RMI_PATH + " " + STR_IOT_SLAVE_CLS + " " + strIoTMasterHostAdd + " " +
-                                       commHan.getComPort(strObjControllerName) + " " +
-                                       commHan.getRMIRegPort(strObjControllerName) + " " +
-                                       commHan.getRMIStubPort(strObjControllerName) + " >& " +
-                                       STR_LOG_FILE_PATH + strObjControllerName + ".log &";
+                               String strSSHCommand = null;
+                               if(STR_LANGUAGE.equals(STR_JAVA))
+                                       strSSHCommand = getCmdJavaIoTSlave(strObjControllerName);
+                               else if(STR_LANGUAGE.equals(STR_CPP))
+                                       strSSHCommand = getCmdCppIoTSlave(strObjControllerName);
+                               else
+                                       throw new Error("IoTMaster: Language specification not recognized: " + STR_LANGUAGE);
                                RuntimeOutput.print(strSSHCommand, BOOL_VERBOSE);
                                createThread(strSSHCommand);
                                // Wait for connection
                                // Create a new socket for communication
                                ServerSocket serverSocket = new ServerSocket(commHan.getComPort(strObjControllerName));
                                Socket socket = serverSocket.accept();
-                               ObjectInputStream inStream = new ObjectInputStream(socket.getInputStream());
-                               ObjectOutputStream outStream = new ObjectOutputStream(socket.getOutputStream());
+                               InputStream inStream = null;
+                               OutputStream outStream = null;
+                               if(STR_LANGUAGE.equals(STR_JAVA)) {
+                                       inStream = new ObjectInputStream(socket.getInputStream());
+                                       outStream = new ObjectOutputStream(socket.getOutputStream());
+                               } else {        // At this point the language is certainly C++, otherwise would've complained above
+                                       inStream = new BufferedInputStream(socket.getInputStream());
+                                       outStream = new BufferedOutputStream(socket.getOutputStream());
+                                       recvAck(inStream);
+                               }
                                RuntimeOutput.print("IoTMaster: Communication established!", BOOL_VERBOSE);
 
                                // PROFILING
@@ -1422,10 +1957,12 @@ public class IoTMaster {
                                        // Create main controller/device object
                                        commMasterToSlave(new MessageCreateMainObject(IoTCommCode.CREATE_MAIN_OBJECT, strObjControllerName),
                                                "Create main object!", inStream, outStream);
-                               } else if(STR_LANGUAGE.equals(STR_CPP))
-                                       ;
-                               else
-                                       throw new Error("IoTMaster: Language specification not recognized: " + STR_LANGUAGE);
+                               } else {
+                                       String strControllerZipFile = strObjControllerName + STR_ZIP_FILE_EXT;
+                                       String strControllerFilePath = STR_CONT_PATH + strObjControllerName + "/";
+                                       sendFileToCppSlave(strControllerFilePath, strControllerZipFile);
+                                       createMainObjectCpp(strObjControllerName, outStream, inStream);
+                               }
 
                                // PROFILING
                                result = System.currentTimeMillis()-start;
@@ -1528,7 +2065,7 @@ public class IoTMaster {
                                if(STR_LANGUAGE.equals(STR_JAVA))
                                        initializeSetsAndRelationsJava(inStream, outStream);
                                else
-                                       ;
+                                       initializeSetsAndRelationsCpp(inStream, outStream);;
 
                                // PROFILING
                                result = System.currentTimeMillis()-start;
@@ -1536,15 +2073,15 @@ public class IoTMaster {
 
                                if(STR_LANGUAGE.equals(STR_JAVA))
                                        // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO EXECUTE INIT METHOD
-                                       commMasterToSlave(new MessageSimple(IoTCommCode.INVOKE_INIT_METHOD),
-                                               "Invoke init() method!", inStream, outStream);
+                                       commMasterToSlave(new MessageSimple(IoTCommCode.INVOKE_INIT_METHOD), "Invoke init() method!", inStream, outStream);
                                else
-                                       ;
+                                       invokeInitMethodCpp(outStream, inStream);
                                // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO END PROCESS
-                               if(STR_LANGUAGE.equals(STR_JAVA))
-                                       outStream.writeObject(new MessageSimple(IoTCommCode.END_SESSION));
-                               else
-                                       ;
+                               if(STR_LANGUAGE.equals(STR_JAVA)) {
+                                       ObjectOutputStream oStream = (ObjectOutputStream) outStream;
+                                       oStream.writeObject(new MessageSimple(IoTCommCode.END_SESSION));
+                               } else  // C++ side will wait until the program finishes, it's not generating a separate thread for now
+                                       //endSessionCpp(outStream);
                                outStream.close();
                                inStream.close();
                                socket.close();
index 8548c9592383d6d0500706d7254bbde56439f648..fe97dec0cd00158c693a3ae9336ca51d7a2e1c90 100644 (file)
@@ -16,6 +16,7 @@ public enum IoTCommCode {
        CREATE_MAIN_OBJECT,
        CREATE_NEW_IOTSET,
        CREATE_NEW_IOTRELATION,
+       END_TRANSFER,
        END_SESSION,
        GET_ADD_IOTSET_OBJECT,
        GET_DEVICE_IOTSET_OBJECT,
@@ -27,6 +28,5 @@ public enum IoTCommCode {
        REINITIALIZE_IOTSET_FIELD,
        REINITIALIZE_IOTRELATION_FIELD,
        TRANSFER_FILE,
-
 }
 
index 0a934bdbc7dff7e96b981ec4dcffcb5ac4ed7532..87c9fa12a88f5327b61be77606fc14f760dd72ff 100644 (file)
@@ -4,6 +4,7 @@ MAC_ADDRESS=74:da:38:68:72:8a
 IOT_CODE_PATH=./../iotcode/
 CONTROLLERS_CODE_PATH=../
 RUNTIME_DIR=~/iot2/iotjava/iotruntime;
+SLAVE_DIR=~/iot2/iotjava/iotruntime/slave;
 #CLASS_PATH=-cp .:/usr/share/java/*:./../../iotjava/:./../../iotjava/iotruntime/:./../../iotjava/iotinstaller/:./../../iotjava/iotrmi/
 CLASS_PATH=-cp .:/usr/share/java/*:./../:./../iotruntime/:./../iotinstaller/:./../../iotjava/iotrmi/
 
@@ -13,7 +14,7 @@ CLASS_PATH=-cp .:/usr/share/java/*:./../:./../iotruntime/:./../iotinstaller/:./.
 RMI_PATH=-Djava.rmi.server.codebase=file:.:/usr/share/java/*
 RMI_HOSTNAME=-Djava.rmi.server.hostname=
 LOG_FILE_PATH=log/
-SSH_USERNAME=ssh iotuser@
+USERNAME=iotuser@
 ROUTER_ADD=192.168.2.1
 
 #The only host that SSH is allowed from to the router
@@ -39,3 +40,9 @@ LANGUAGE=Java
 JVM_INIT_HEAP_SIZE=
 JVM_MAX_HEAP_SIZE=
 
+# Skeleton suffix, e.g. _Skeleton for Camera_Skeleton.class
+SKEL_CLASS_SUFFIX=_Skeleton
+
+# Skeleton suffix, e.g. _Stub for CameraSpecial_Stub.class
+STUB_CLASS_SUFFIX=_Stub
+