From: rtrimana <rtrimana@uci.edu> Date: Fri, 13 Jan 2017 23:33:42 +0000 (-0800) Subject: Adding stub and skeleton for Lifxtest and LifxLightBulb; Creating build flow for... X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=db205c86272ade784240295eb0e4c8d160f02717;p=iot2.git Adding stub and skeleton for Lifxtest and LifxLightBulb; Creating build flow for shared-objects; Developing IoTSlave for C++ --- diff --git a/benchmarks/Cpp/Lifxtest/LightBulbTest_Stub.cpp b/benchmarks/Cpp/Lifxtest/LightBulbTest_Stub.cpp new file mode 100644 index 0000000..4a046bc --- /dev/null +++ b/benchmarks/Cpp/Lifxtest/LightBulbTest_Stub.cpp @@ -0,0 +1,11 @@ +#include <iostream> +#include "LightBulbTest_Stub.hpp" + +// External creator/destroyer +/*extern "C" LightBulbTest_Stub* create(int _port, const char* _skeletonAddress, string _callbackAddress, int _rev, bool* _bResult, vector<int> _ports) { + return new LightBulbTest_Stub(_port, _skeletonAddress, _callbackAddress, _rev, _bResult, _ports); +} + +extern "C" void destroy(LightBulbTest_Stub* t) { + delete t; +}*/ diff --git a/benchmarks/Cpp/Lifxtest/LightBulbTest_Stub.hpp b/benchmarks/Cpp/Lifxtest/LightBulbTest_Stub.hpp index ccc3fe6..5d0c9b0 100644 --- a/benchmarks/Cpp/Lifxtest/LightBulbTest_Stub.hpp +++ b/benchmarks/Cpp/Lifxtest/LightBulbTest_Stub.hpp @@ -144,4 +144,7 @@ class LightBulbTest_Stub : public LightBulbTest } }; + +//typedef LightBulbTest_Stub* create_t(int _port, const char* _skeletonAddress, string _callbackAddress, int _rev, bool* _bResult, vector<int> _ports); +//typedef void destroy_t(LightBulbTest_Stub*); #endif diff --git a/benchmarks/Cpp/Lifxtest/Makefile b/benchmarks/Cpp/Lifxtest/Makefile index 3dd8e5c..5f82d06 100755 --- a/benchmarks/Cpp/Lifxtest/Makefile +++ b/benchmarks/Cpp/Lifxtest/Makefile @@ -4,9 +4,21 @@ include $(BASE)/common.mk all: lifxtest +ARGS = -shared -fpic + PHONY += lifxtest lifxtest: $(G++) ./Lifxtest.cpp $(BASE)/iotjava/iotruntime/cpp/socket/Socket.cpp -o $(BIN_DIR)/Lifxtest/Lifxtest.o --std=c++11 -pthread -pg -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/ cp ./Lifxtest.config $(BIN_DIR)/Lifxtest +PHONY += so-lifxtest +so-lifxtest: + $(G++) $(ARGS) ./Lifxtest.cpp $(BASE)/iotjava/iotruntime/cpp/socket/Socket.cpp -o $(BIN_DIR)/Lifxtest/Lifxtest.so --std=c++11 -pthread -pg -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/ + cp ./Lifxtest.config $(BIN_DIR)/Lifxtest + +PHONY += so-lightstub +so-lightstub: + $(G++) $(ARGS) ./LightBulbTest_Stub.cpp $(BASE)/iotjava/iotruntime/cpp/socket/Socket.cpp -o $(BIN_DIR)/Lifxtest/LightBulbTest_Stub.so --std=c++11 -pthread -pg -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/ + cp ./Lifxtest.config $(BIN_DIR)/Lifxtest + .PHONY: $(PHONY) diff --git a/benchmarks/drivers/Cpp/LifxLightBulb/DeviceStateLocation.hpp~ b/benchmarks/drivers/Cpp/LifxLightBulb/DeviceStateLocation.hpp~ deleted file mode 100644 index b898319..0000000 --- a/benchmarks/drivers/Cpp/LifxLightBulb/DeviceStateLocation.hpp~ +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef _DEVICESTATELOCATION_HPP__ -#define _DEVICESTATELOCATION_HPP__ -#include <iostream> -#include <string> - -class DeviceStateLocation { - private: - char location[16]; - string label; - int64_t updatedAt; - - public: - - DeviceStateLocation(char _location[16], String _label, long _updatedAt) { - - strcpy(location, _location); - label = _label; - updatedAt = _updatedAt; - } - - - ~DeviceStateLocation() { - } - - - char* getLocation() { - return location; - } - - - string getLabel() { - return label; - } - - - int64_t getUpdatedAt() { - return updatedAt; - } -}; -#endif diff --git a/benchmarks/drivers/Cpp/LifxLightBulb/LifxLightBulb.cpp b/benchmarks/drivers/Cpp/LifxLightBulb/LifxLightBulb.cpp index 3f2cea8..af7b892 100644 --- a/benchmarks/drivers/Cpp/LifxLightBulb/LifxLightBulb.cpp +++ b/benchmarks/drivers/Cpp/LifxLightBulb/LifxLightBulb.cpp @@ -10,6 +10,14 @@ using namespace std; +// External creator/destroyer +/*extern "C" LifxLightBulb* create(IoTSet<IoTDeviceAddress*>* _devAddress, string macAddress) { + return new LifxLightBulb(_devAddress, macAddress); +} + +extern "C" void destroy(LifxLightBulb* t) { + delete t; +}*/ // Constructor LifxLightBulb::LifxLightBulb() { diff --git a/benchmarks/drivers/Cpp/LifxLightBulb/LifxLightBulb.hpp b/benchmarks/drivers/Cpp/LifxLightBulb/LifxLightBulb.hpp index e422a72..7d23c22 100644 --- a/benchmarks/drivers/Cpp/LifxLightBulb/LifxLightBulb.hpp +++ b/benchmarks/drivers/Cpp/LifxLightBulb/LifxLightBulb.hpp @@ -164,4 +164,7 @@ class LifxLightBulb : public LightBulb void handleStateVersionMessageReceived(char* payloadData); void handleLightStateMessageReceived(char* payloadData); }; + +//typedef LifxLightBulb* create_t(IoTSet<IoTDeviceAddress*>* _devAddress, string macAddress); +//typedef void destroy_t(LifxLightBulb*); #endif diff --git a/benchmarks/drivers/Cpp/LifxLightBulb/LightBulb_Skeleton.cpp b/benchmarks/drivers/Cpp/LifxLightBulb/LightBulb_Skeleton.cpp new file mode 100644 index 0000000..aab1ac8 --- /dev/null +++ b/benchmarks/drivers/Cpp/LifxLightBulb/LightBulb_Skeleton.cpp @@ -0,0 +1,11 @@ +#include <iostream> +#include "LightBulb_Skeleton.hpp" + +// External creator/destroyer +/*extern "C" LightBulb_Skeleton* create(LightBulb *_mainObj, string _callbackAddress, int _port) { + return new LightBulb_Skeleton(_mainObj, _callbackAddress, _port); +} + +extern "C" void destroy(LightBulb_Skeleton* t) { + delete t; +}*/ diff --git a/benchmarks/drivers/Cpp/LifxLightBulb/LightBulb_Skeleton.hpp b/benchmarks/drivers/Cpp/LifxLightBulb/LightBulb_Skeleton.hpp index 5b7aaaa..b70b21d 100644 --- a/benchmarks/drivers/Cpp/LifxLightBulb/LightBulb_Skeleton.hpp +++ b/benchmarks/drivers/Cpp/LifxLightBulb/LightBulb_Skeleton.hpp @@ -329,4 +329,7 @@ class LightBulb_Skeleton : public LightBulb }; set<int> LightBulb_Skeleton::set0Allowed { 2, 10, 1, 3, 11, 8, 12, 7, 13, 9, 6, 16, 17, 4, 0, 14, 15, 5 }; + +//typedef LightBulb_Skeleton* create_t(LightBulb *_mainObj, string _callbackAddress, int _port); +//typedef void destroy_t(LightBulb_Skeleton*); #endif diff --git a/benchmarks/drivers/Cpp/Makefile b/benchmarks/drivers/Cpp/Makefile index a14df94..74221bc 100644 --- a/benchmarks/drivers/Cpp/Makefile +++ b/benchmarks/drivers/Cpp/Makefile @@ -4,6 +4,8 @@ include $(BASE)/common.mk all: light +ARGS = -shared -fpic + # Compile # PHONY += light @@ -11,4 +13,14 @@ light: cd LifxLightBulb/; $(G++) ./LifxLightBulb.cpp $(BASE)/../iotjava/iotruntime/cpp/socket/Socket.cpp -o ../$(BIN_DIR)/iotcode/LifxLightBulb/LifxLightBulb.o --std=c++11 -pthread -pg -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/ cp LifxLightBulb/LifxLightBulb.config $(BIN_DIR)/iotcode/LifxLightBulb +PHONY += so-light +so-light: + cd LifxLightBulb/; $(G++) $(ARGS) ./LifxLightBulb.cpp $(BASE)/../iotjava/iotruntime/cpp/socket/Socket.cpp -o ../$(BIN_DIR)/iotcode/LifxLightBulb/LifxLightBulb.so --std=c++11 -pthread -pg -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/ + cp LifxLightBulb/LifxLightBulb.config $(BIN_DIR)/iotcode/LifxLightBulb + +PHONY += so-lightskel +so-lightskel: + cd LifxLightBulb/; $(G++) $(ARGS) ./LightBulb_Skeleton.cpp $(BASE)/../iotjava/iotruntime/cpp/socket/Socket.cpp -o ../$(BIN_DIR)/iotcode/LifxLightBulb/LightBulb_Skeleton.so --std=c++11 -pthread -pg -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/ + cp LifxLightBulb/LifxLightBulb.config $(BIN_DIR)/iotcode/LifxLightBulb + .PHONY: $(PHONY) diff --git a/iotjava/iotruntime/cpp/iotslave/IoTCommCode.java b/iotjava/iotruntime/cpp/iotslave/IoTCommCode.java new file mode 100644 index 0000000..3c456cb --- /dev/null +++ b/iotjava/iotruntime/cpp/iotslave/IoTCommCode.java @@ -0,0 +1,30 @@ +/** Class IoTCommCode is a place to keep all the necessary + * enumerations for communication + * + * @author Rahmadi Trimananda <rahmadi.trimananda @ uci.edu> + * @version 1.0 + * @since 2016-02-19 + */ + +// Enumeration of master-slave communication codes +public enum IoTCommCode { + + ACKNOWLEDGED, + CREATE_OBJECT, + CREATE_MAIN_OBJECT, + CREATE_NEW_IOTSET, + CREATE_NEW_IOTRELATION, + END_TRANSFER, + END_SESSION, + GET_ADD_IOTSET_OBJECT, + GET_DEVICE_IOTSET_OBJECT, + GET_IOTSET_OBJECT, + GET_IOTRELATION_FIRST_OBJECT, + GET_IOTRELATION_SECOND_OBJECT, + GET_ZB_DEV_IOTSET_OBJECT, + INVOKE_INIT_METHOD, + REINITIALIZE_IOTSET_FIELD, + REINITIALIZE_IOTRELATION_FIELD, + TRANSFER_FILE, +} + diff --git a/iotjava/iotruntime/cpp/iotslave/IoTSlave.cpp b/iotjava/iotruntime/cpp/iotslave/IoTSlave.cpp new file mode 100644 index 0000000..d950a03 --- /dev/null +++ b/iotjava/iotruntime/cpp/iotslave/IoTSlave.cpp @@ -0,0 +1,389 @@ +#include <iostream> +#include <fstream> + +#include "IoTSlave.hpp" + +IoTSlave::IoTSlave(string _serverAddress, int _serverPort, string _objectName) { + + serverAddress = _serverAddress; + serverPort = _serverPort; + objectName = _objectName; + socket = new TCPSocket(serverAddress, serverPort); + openFile(objectName); + writeToFile("IoTSlave object created! Connection established!"); +} + + +IoTSlave::~IoTSlave() { + + if (socket != NULL) { + delete socket; + socket = NULL; + } + closeFile(); +} + + +// Private helper functions +int* IoTSlave::byteToInt(int* result, char* bytes) { + + int i = 0; + memcpy(&i, bytes, sizeof(int)); + *result = be32toh(i); + + return result; +} + + +char* IoTSlave::intToByteArray(int i, char* bytes) { + + int iInvert = htobe32(i); + memcpy(bytes, &iInvert, sizeof(int)); + + return bytes; +} + + +void* IoTSlave::getObjectConverted(void* retObj, string object, string objectClass) { + + // Returning new objects in heap - so we need to delete them afterwards + if (objectClass.compare(STRINGCLASS) == 0) { + string* retStr = new string(object); + retObj = retStr; + } else if (objectClass.compare(INTCLASS) == 0) { + int* retInt = new int(atoi(object.c_str())); + retObj = retInt; + } else // return NULL if class is not identifiable + return NULL; + + return retObj; +} + + +// Factoring out iteration +char* IoTSlave::recvIter(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, RCVBUFSIZE))) <= 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); +} + + +void IoTSlave::writeToFile(string logMsg) { + + log << "IoTSlave: " << logMsg << endl; +} + + +void IoTSlave::closeFile() { + + log.close(); +} + + +void IoTSlave::instantiateObject(string objectClassName) { + + // Object handling + string strObj = FILEPATH + objectClassName + SOEXT; + void* handle = dlopen (strObj.c_str(), RTLD_LAZY); + if (!handle) { + fputs (dlerror(), stderr); + writeToFile("Error handling object!"); + exit(1); + } + writeToFile("Object handled!"); + // Create handler + create_object = (create_t*) dlsym(handle, CREATEFUNCTION.c_str()); + const char* dlsym_error = dlerror(); + if (dlsym_error) { + cerr << "Cannot load symbol create: " << dlsym_error << '\n'; + writeToFile("Cannot load symbol create!"); + exit(1); + } + writeToFile("Object factory created for " + objectClassName); + // Destroy handler + destroy_object = (destroy_t*) dlsym(handle, DESTROYFUNCTION.c_str()); + dlsym_error = dlerror(); + if (dlsym_error) { + cerr << "Cannot load symbol destroy: " << dlsym_error << '\n'; + writeToFile("Cannot load symbol destroy!"); + exit(1); + } + writeToFile("Object destroyer created for " + objectClassName); +} + + +// Public methods +string IoTSlave::getServerAddress() { + + return serverAddress; +} + + +int IoTSlave::getServerPort() { + + return serverPort; +} + + +string IoTSlave::getObjectName() { + + return objectName; +} + + +void IoTSlave::sendInteger(int intSend) { + + char charInt[sizeof(int)]; + // Convert int to byte array and fix endianness + intToByteArray(intSend, charInt); + // Send the length first + void* toSend = charInt; + socket->send(toSend, sizeof(int)); +} + + +int IoTSlave::recvInteger() { + + int toBeReceived = sizeof(int); + char recvInt[sizeof(int)]; // Normally 4 bytes + + // Receive and iterate until complete + recvIter(recvInt, toBeReceived); + + int retVal = 0; + byteToInt(&retVal, recvInt); + + return retVal; +} + + +void IoTSlave::sendString(string strSend) { + + // Send the length first + int strLen = strSend.length(); + sendInteger(strLen); + + // Send the string + char* chStrSend = new char[strLen]; + strcpy(chStrSend, strSend.c_str()); + void* toSend = chStrSend; + socket->send(toSend, strLen); + // Avoid memory leak + delete[] chStrSend; +} + + +string IoTSlave::recvString() { + + // Get the length of string first + int strLen = recvInteger(); + char* recvStr = new char[strLen]; // Normally 4 bytes + + // Receive and iterate until complete + recvIter(recvStr, strLen); + + string retVal(recvStr, strLen); + delete[] recvStr; + + return retVal; +} + + +// Create a driver object, e.g. LifxLightBulb +void IoTSlave::createObject() { + + writeToFile("Creating a driver object now..."); + sendAck(); + // Receiving object info + 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); + objectSkelClass = recvString(); sendAck(); + writeToFile("Driver object skeleton class name: " + objectSkelClass); + objectRegPort = recvInteger(); sendAck(); + writeToFile("Driver object registry port: " + to_string(objectRegPort)); + objectStubPort = recvInteger(); sendAck(); + writeToFile("Driver object stub port: " + to_string(objectStubPort)); + int numOfArgs = recvInteger(); sendAck(); + for (int i = 0; i < numOfArgs; i++) { + string arg = recvString(); sendAck(); + args.push_back(arg); + writeToFile("Got argument: " + arg); + } + for (int i = 0; i < numOfArgs; i++) { + string argClass = recvString(); sendAck(); + args.push_back(argClass); + writeToFile("Got argument class: " + argClass); + } + // We are just receiving object information here + // Instantiation will be done when IoTDeviceAddress has been sent + //instantiateObject(objectClassName); +} + + +void IoTSlave::createNewIoTSet() { + + +} + + +void IoTSlave::getDeviceIoTSetObject() { + + +} + + +// Create a main object, e.g. Lifxtest +void IoTSlave::createMainObject() { + + writeToFile("Creating main object: " + objectName); + string mainObject = recvString(); + sendAck(); +} + + +void IoTSlave::sendAck() { + + int codeAck = (int) ACKNOWLEDGED; + sendInteger(codeAck); +} + + +bool IoTSlave::recvEndTransfer() { + + int codeEndTransfer = (int) END_TRANSFER; + int recvCode = recvInteger(); + if (recvCode == codeEndTransfer) + return true; + return false; +} + + +void IoTSlave::commIoTMaster() { + + writeToFile("Starting main loop..."); + // Main iteration/loop + while(true) { + IoTCommCode message = (IoTCommCode) recvInteger(); + //writeToFile("Message: " + (int) message); + + switch(message) { + + case CREATE_OBJECT: + createObject(); + break; + + case TRANSFER_FILE: + //transferFile(); + break; + + case CREATE_MAIN_OBJECT: + createMainObject(); + break; + + case CREATE_NEW_IOTSET: + createNewIoTSet(); + break; + + case CREATE_NEW_IOTRELATION: + //createNewIoTRelation(); + break; + + case GET_IOTSET_OBJECT: + //getIoTSetObject(); + break; + + case GET_IOTRELATION_FIRST_OBJECT: + //getIoTRelationFirstObject(); + break; + + case GET_IOTRELATION_SECOND_OBJECT: + //getIoTRelationSecondObject(); + break; + + case REINITIALIZE_IOTSET_FIELD: + //reinitializeIoTSetField(); + break; + + case REINITIALIZE_IOTRELATION_FIELD: + //reinitializeIoTRelationField(); + break; + + case GET_DEVICE_IOTSET_OBJECT: + getDeviceIoTSetObject(); + break; + + case GET_ZB_DEV_IOTSET_OBJECT: + //getZBDevIoTSetObject(); + break; + + case GET_ADD_IOTSET_OBJECT: + //getAddIoTSetObject(); + break; + + case INVOKE_INIT_METHOD: + //invokeInitMethod(); + break; + + case END_SESSION: + // END of session + goto ENDLOOP; + break; + + default: + break; + } + } + ENDLOOP: + writeToFile("End of loop!"); +} + + +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); + string strObjName = argv[3]; + IoTSlave *iotSlave = new IoTSlave(serverAddress, serverPort, strObjName); + //iotSlave->sendInteger(123455); + iotSlave->sendAck(); + iotSlave->commIoTMaster(); + + return 0; +} diff --git a/iotjava/iotruntime/cpp/iotslave/IoTSlave.hpp b/iotjava/iotruntime/cpp/iotslave/IoTSlave.hpp new file mode 100644 index 0000000..f998a09 --- /dev/null +++ b/iotjava/iotruntime/cpp/iotslave/IoTSlave.hpp @@ -0,0 +1,122 @@ +#ifndef _IOTSLAVE_HPP__ +#define _IOTSLAVE_HPP__ + +#include <iostream> +#include <fstream> +#include <vector> + +#include <dlfcn.h> // For dlopen, dlsym, etc. + +#include "ObjectFactory.hpp" +#include "ISet.hpp" +#include "IoTSet.hpp" +#include "IRelation.hpp" +#include "IoTRelation.hpp" +#include "Socket.cpp" + +/** Class IoTSlave is a communication class + * that interacts with IoTSlave.java to set up C++ + * objects in Sentinel. + * + * @author Rahmadi Trimananda <rtrimana @ uci.edu> + * @version 1.0 + * @since 2017-01-12 + */ +// Enumeration of master-slave communication codes +enum IoTCommCode { + + ACKNOWLEDGED, + CREATE_OBJECT, + CREATE_MAIN_OBJECT, + CREATE_NEW_IOTSET, + CREATE_NEW_IOTRELATION, + END_TRANSFER, + END_SESSION, + GET_ADD_IOTSET_OBJECT, + GET_DEVICE_IOTSET_OBJECT, + GET_IOTSET_OBJECT, + GET_IOTRELATION_FIRST_OBJECT, + GET_IOTRELATION_SECOND_OBJECT, + GET_ZB_DEV_IOTSET_OBJECT, + INVOKE_INIT_METHOD, + REINITIALIZE_IOTSET_FIELD, + REINITIALIZE_IOTRELATION_FIELD, + TRANSFER_FILE, + +}; + +class IoTSlave { + + private: + // Constants + const static int RCVBUFSIZE = 1024; // Size of receive buffer + const static string FILEPATH; // File path + const static string FILEEXT; // File extension + const static string SOEXT; // Shared object (.so) extension + const static string STRINGCLASS; // String class + const static string INTCLASS; // Int class + const static string CREATEFUNCTION; // The create function in class + const static string DESTROYFUNCTION; // The destroy function in class + + // Class properties + string serverAddress; + int serverPort; + string objectName; + string objectClassName; + string objectInterfaceName; + string objectSkelClass; // Need to send from Java IoTSlave: sMessage.getObjectInterfaceName() + SKEL_CLASS_SUFFIX + int objectRegPort; + int objectStubPort; + + void* object; // Handler of object + TCPSocket* socket; + ofstream log; // Log the messages + vector<string> args; // Hold the arguments for constructor (in string format) + vector<string> argClasses; // Hold the argument classes + // Object handlers + create_t* create_object; + destroy_t* destroy_object; + + public: + // Constructors + IoTSlave(string _serverAddress, int _serverPort, string _objectName); + ~IoTSlave(); + // Class methods + string getServerAddress(); + int getServerPort(); + string getObjectName(); + void sendInteger(int intSend); + int recvInteger(); + void sendString(string strSend); + string recvString(); + // Main loop + void sendAck(); + bool recvEndTransfer(); + void commIoTMaster(); + void createObject(); // Create driver object + void createMainObject(); // Create main object + void createNewIoTSet(); + void getDeviceIoTSetObject(); + + private: + // Private helper functions + int* byteToInt(int* result, char* bytes); + char* intToByteArray(int i, char* bytes); + char* recvIter(char* recvBuffer, int recvLen); + void* getObjectConverted(void* retObj, string object, string objectClass); + void openFile(string fileName); + void writeToFile(string logMsg); + void closeFile(); + void instantiateObject(string objectClassName); +}; + +// Constant initialization +const string IoTSlave::FILEPATH = "./"; +const string IoTSlave::FILEEXT = "_cpp.log"; +const string IoTSlave::SOEXT = ".so"; +const string IoTSlave::STRINGCLASS = "string"; +const string IoTSlave::INTCLASS = "int"; +const string IoTSlave::CREATEFUNCTION = "create"; +const string IoTSlave::DESTROYFUNCTION = "destroy"; + +#endif diff --git a/iotjava/iotruntime/cpp/iotslave/IoTSlave.java b/iotjava/iotruntime/cpp/iotslave/IoTSlave.java new file mode 100644 index 0000000..98aa828 --- /dev/null +++ b/iotjava/iotruntime/cpp/iotslave/IoTSlave.java @@ -0,0 +1,313 @@ +import java.util.*; +import java.io.*; +import java.net.*; +import java.nio.*; + +public class IoTSlave { + + private ServerSocket serverSocket; + private Socket socket; + private BufferedInputStream input; + private BufferedOutputStream output; + + private static final String STR_LOCALHOST = "localhost"; + private static final String STR_IOTSLAVE_CPP = "./IoTSlave.o"; + 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) + + + public IoTSlave() { + + serverSocket = null; + socket = null; + input = null; + output = null; + } + + + /** + * Prepare server socket connection with C++ IoTSlave + */ + public void setServerSocketCpp(int iPort) { + + try { + serverSocket = new ServerSocket(iPort); + } + catch ( IOException e ) { + e.printStackTrace(); + } + } + + + /** + * sendInteger() sends an integer in bytes + */ + public void sendInteger(int intSend) throws IOException { + + // 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() throws IOException { + + // 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() throws IOException { + + int strLen = recvInteger(); + // 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) throws IOException { + + // Transform String into bytes + byte[] strSendBytes = strSend.getBytes(); + int strLen = strSend.length(); + // Send the string length first + sendInteger(strLen); + // Send the byte array + output.write(strSendBytes, 0, strLen); + output.flush(); + } + + + /** + * Establish connection with C++ IoTSlave + */ + public void connectCpp() throws IOException { + + socket = serverSocket.accept(); + input = new BufferedInputStream(socket.getInputStream()); + output = new BufferedOutputStream(socket.getOutputStream()); + } + + + /** + * Construct a SSH command to run C++ program + */ + public static String constructCommand(String serverAddress, int serverPort, String strObjName) { + + String strCommand = STR_IOTSLAVE_CPP + " " + serverAddress + " " + serverPort + " " + strObjName; + return strCommand; + } + + + /** + * Create a new thread to start a new C++ process + */ + public static void createCppThread(String strCmd) { + + Thread thread = new Thread(new Runnable() { + public void run() { + try { + Runtime runtime = Runtime.getRuntime(); + Process process = runtime.exec(strCmd); + } catch(IOException ex) { + ex.printStackTrace(); + } + } + }); + thread.start(); + //RuntimeOutput.print("IoTSlave: Executing: " + strCmd, BOOL_VERBOSE); + System.out.println("IoTSlave: Executing: " + strCmd); + } + + + /** + * 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() throws IOException { + + int intAck = recvInteger(); + IoTCommCode codeAck = getCode(intAck); + if (codeAck == IoTCommCode.ACKNOWLEDGED) + return true; + return false; + + } + + + /** + * Send END + */ + public void sendEndTransfer() throws IOException { + + int endCode = IoTCommCode.END_TRANSFER.ordinal(); + sendInteger(endCode); + } + + + /** + * Create a driver object for C++ + */ + public void createObjectCpp() throws IOException { + + IoTCommCode commCode = null; + int intCode = 0; + commCode = IoTCommCode.CREATE_OBJECT; + intCode = commCode.ordinal(); + sendInteger(intCode); recvAck(); + String strDrvObjName = "LifxLightBulbLB2"; + String strDrvObjClsName = "LifxLightBulb"; + String strDrvObjIntfaceClsName = "LightBulb"; + String strDrvObjSkelClsName = "LightBulb_Skeleton"; + int iRegPort = 30313; + int iStubPort = 55179; + // TODO: On the actual slave we need to do conversion back to string before we send everything to C++ IoTSlave + // TODO: Make it as array of string + String[] arrCppArgs = { "D073D5128E300000" }; + String[] arrCppArgClasses = { "string" }; + System.out.println("IoTSlave: Send request to create a driver object... "); + System.out.println("IoTSlave: Driver object name: " + strDrvObjName); + sendString(strDrvObjName); recvAck(); + System.out.println("IoTSlave: Driver object class name: " + strDrvObjClsName); + sendString(strDrvObjClsName); recvAck(); + System.out.println("IoTSlave: Driver object interface name: " + strDrvObjIntfaceClsName); + sendString(strDrvObjIntfaceClsName); recvAck(); + System.out.println("IoTSlave: Driver object skeleton class name: " + strDrvObjSkelClsName); + sendString(strDrvObjSkelClsName); recvAck(); + System.out.println("IoTSlave: Driver object registry port: " + iRegPort); + sendInteger(iRegPort); recvAck(); + System.out.println("IoTSlave: Driver object stub port: " + iStubPort); + sendInteger(iStubPort); recvAck(); + int numOfArgs = arrCppArgs.length; + System.out.println("IoTSlave: Send constructor arguments! Number of arguments: " + numOfArgs); + sendInteger(numOfArgs); recvAck(); + for(String str : arrCppArgs) { + sendString(str); recvAck(); + } + System.out.println("IoTSlave: Send constructor argument classes!"); + for(String str : arrCppArgClasses) { + sendString(str); recvAck(); + } + } + + + /** + * Send object fields + */ + private void sendFieldsCpp() throws IOException { + + + } + + + /** + * Send object field types + */ + private void sendFieldTypesCpp() throws IOException { + + + } + + + /** + * End session for C++ + */ + public void endSessionCpp() throws IOException { + + // Send message to end session + IoTCommCode endSessionCode = IoTCommCode.END_SESSION; + int intCode = endSessionCode.ordinal(); + sendInteger(intCode); + //RuntimeOutput.print("IoTSlave: Send request to create a main object: " + strObjName, BOOL_VERBOSE); + System.out.println("IoTSlave: Send request to end session!"); + } + + + public static void main(String[] args) throws IOException, InterruptedException { + + /*int iPort = 12345; + IoTSlave iotSlave = new IoTSlave(); + iotSlave.setServerSocketCpp(iPort); + iotSlave.connectCpp(); + System.out.println("Connection established with client!"); + iotSlave.sendInteger(1234); + System.out.println("Integer sent!"); + System.out.println("Integer received: " + iotSlave.recvInteger()); + String strRecv = iotSlave.recvString(); + System.out.println("Received string: " + strRecv); + strRecv = strRecv + " - ACKNOWLEDGED!"; + System.out.println("Sending back string: " + strRecv); + iotSlave.sendString(strRecv);*/ + + int iPort =12345; + String strAddress = "localhost"; + String strObjName = "Lifxtest"; + + IoTSlave iotSlave = new IoTSlave(); + iotSlave.setServerSocketCpp(iPort); + + // Run thread to spawn C++ IoTSlave + String strCmd = IoTSlave.constructCommand(strAddress, 12345, strObjName); + IoTSlave.createCppThread(strCmd); + iotSlave.connectCpp(); + //RuntimeOutput.print("IoTSlave: Connection established!", BOOL_VERBOSE); + System.out.println("IoTSlave: Connection established!"); + // First contact with C++ IoTSlave + System.out.println("IoTSlave: IoTSlave.o is ready: " + iotSlave.recvAck()); + + iotSlave.createObjectCpp(); + + + iotSlave.endSessionCpp(); + + + // Send message to create a main object + /*commCode = IoTCommCode.CREATE_MAIN_OBJECT; + intCode = commCode.ordinal(); + iotSlave.sendInteger(intCode); + //RuntimeOutput.print("IoTSlave: Send request to create a main object: " + strObjName, BOOL_VERBOSE); + System.out.println("IoTSlave: Send request to create a main object: " + strObjName); + //RuntimeOutput.print("IoTSlave: IoTSlave.o is ready: " + strAck, BOOL_VERBOSE); + System.out.println("IoTSlave: IoTSlave.o is ready: " + strAck);*/ + + //Thread.sleep(1000); + + } +} diff --git a/iotjava/iotruntime/cpp/iotslave/LifxLightBulb.so b/iotjava/iotruntime/cpp/iotslave/LifxLightBulb.so new file mode 100755 index 0000000..8c4657d Binary files /dev/null and b/iotjava/iotruntime/cpp/iotslave/LifxLightBulb.so differ diff --git a/iotjava/iotruntime/cpp/iotslave/Lifxtest.so b/iotjava/iotruntime/cpp/iotslave/Lifxtest.so new file mode 100755 index 0000000..9bf27d6 Binary files /dev/null and b/iotjava/iotruntime/cpp/iotslave/Lifxtest.so differ diff --git a/iotjava/iotruntime/cpp/iotslave/LightBulbTest_Stub.so b/iotjava/iotruntime/cpp/iotslave/LightBulbTest_Stub.so new file mode 100755 index 0000000..452ce36 Binary files /dev/null and b/iotjava/iotruntime/cpp/iotslave/LightBulbTest_Stub.so differ diff --git a/iotjava/iotruntime/cpp/iotslave/LightBulb_Skeleton.so b/iotjava/iotruntime/cpp/iotslave/LightBulb_Skeleton.so new file mode 100755 index 0000000..0f0e895 Binary files /dev/null and b/iotjava/iotruntime/cpp/iotslave/LightBulb_Skeleton.so differ diff --git a/iotjava/iotruntime/cpp/iotslave/Makefile b/iotjava/iotruntime/cpp/iotslave/Makefile new file mode 100755 index 0000000..a42bda5 --- /dev/null +++ b/iotjava/iotruntime/cpp/iotslave/Makefile @@ -0,0 +1,31 @@ +BASE = ../../../.. + +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/ +CCCLINKERFLAGS = -ldl + +all: java cpp + +PHONY += java +java: + javac *.java + +PHONY += cpp +cpp: + $(G++) $(GCCFLAGS) -o IoTSlave.o IoTSlave.cpp $(INCLUDE) $(CCCLINKERFLAGS) + +PHONY += run +run: + java IoTSlave + +PHONY += clean +clean: + rm -rf *.class + rm -rf *.o + rm -rf *.log + rm -rf gmon.out + +.PHONY: $(PHONY) diff --git a/iotjava/iotruntime/cpp/iotslave/ObjectFactory.hpp b/iotjava/iotruntime/cpp/iotslave/ObjectFactory.hpp new file mode 100644 index 0000000..ee54758 --- /dev/null +++ b/iotjava/iotruntime/cpp/iotslave/ObjectFactory.hpp @@ -0,0 +1,85 @@ +#include "LifxLightBulb.cpp" +#include "LightBulb_Skeleton.cpp" +#include "LightBulbTest_Stub.cpp" + + +typedef void* create_t(string className, void** params); +typedef void destroy_t(void*); + +// External creator/destroyer +extern "C" void* create(string className, void** params) { + + if (className.compare("LifxLightBulb") == 0) { + // Arguments: IoTSet<IoTDeviceAddress*>* _devAddress, string macAddress + // We pass in a pointer to string and then we pass in just the value for the class + return new LifxLightBulb((IoTSet<IoTDeviceAddress*>*) params[0], *((string*) params[1])); + } else if (className.compare("LightBulb_Skeleton") == 0) { + // Arguments: LightBulb *_mainObj, string _callbackAddress, int _port + // We pass in pointers to string and integer, and read the values again + return new LightBulb_Skeleton((LightBulb*) params[0], *((string*) params[1]), *((int*) params[2])); + } else if (className.compare("LightBulbTest_Stub") == 0) { + // int _port, const char* _skeletonAddress, string _callbackAddress, int _rev, bool* _bResult, vector<int> _ports + // We pass in pointers to string and integer, and read the values again + return new LightBulbTest_Stub(*((int*) params[0]), (const char*) params[1], *((string*) params[2]), *((int*) params[3]), + (bool*) params[4], *((vector<int>*) params[5])); + } else { // Class is not recognized + cerr << "ObjectFactory: Class is not recognized: " << className << endl; + exit(1); + } +} + +extern "C" void destroy(string className, void* ob) { + + if (ob != NULL) { // Check that this pointer is not NULL + + if (className.compare("LifxLightBulb") == 0) { + LifxLightBulb* obj = (LifxLightBulb*) ob; + delete obj; + } else if (className.compare("LightBulb_Skeleton") == 0) { + LightBulb_Skeleton* obj = (LightBulb_Skeleton*) ob; + delete obj; + } else if (className.compare("LightBulbTest_Stub") == 0) { + LightBulbTest_Stub* obj = (LightBulbTest_Stub*) ob; + delete obj; + } else { // Class is not recognized + cerr << "ObjectFactory: Class is not recognized: " << className << endl; + exit(1); + } + } +} + +/*typedef LifxLightBulb* create_t(IoTSet<IoTDeviceAddress*>* _devAddress, string macAddress); +typedef void destroy_t(LifxLightBulb*); + +// External creator/destroyer +extern "C" LifxLightBulb* create(IoTSet<IoTDeviceAddress*>* _devAddress, string macAddress) { + return new LifxLightBulb(_devAddress, macAddress); +} + +extern "C" void destroy(LifxLightBulb* t) { + delete t; +}*/ + +//typedef LightBulb_Skeleton* create_t(LightBulb *_mainObj, string _callbackAddress, int _port); +//typedef void destroy_t(LightBulb_Skeleton*); + +/*extern "C" LightBulb_Skeleton* create(LightBulb *_mainObj, string _callbackAddress, int _port) { + return new LightBulb_Skeleton(_mainObj, _callbackAddress, _port); +} + +extern "C" void destroy(LightBulb_Skeleton* t) { + delete t; +}*/ + +//typedef LightBulbTest_Stub* create_t(int _port, const char* _skeletonAddress, string _callbackAddress, int _rev, bool* _bResult, vector<int> _ports); +//typedef void destroy_t(LightBulbTest_Stub*); + +/*extern "C" LightBulbTest_Stub* create(int _port, const char* _skeletonAddress, string _callbackAddress, int _rev, bool* _bResult, vector<int> _ports) { + return new LightBulbTest_Stub(_port, _skeletonAddress, _callbackAddress, _rev, _bResult, _ports); +} + +extern "C" void destroy(LightBulbTest_Stub* t) { + delete t; +}*/ + + diff --git a/iotjava/iotruntime/cpp/setrelation/IRelation.hpp b/iotjava/iotruntime/cpp/setrelation/IRelation.hpp new file mode 100644 index 0000000..5261c30 --- /dev/null +++ b/iotjava/iotruntime/cpp/setrelation/IRelation.hpp @@ -0,0 +1,142 @@ +#ifndef _IRELATION_HPP__ +#define _IRELATION_HPP__ +#include <iostream> +#include <string> +#include <unordered_map> + +using namespace std; + +/** This is the IoTRelation implementation for C++ + * + * @author Rahmadi Trimananda <rahmadi.trimananda @ uci.edu> + * @version 1.0 + * @since 2016-09-06 + */ +template <class K,class V> +class IRelation { + private: + unordered_multimap<K,V>* rel; + public: + IRelation(); + IRelation(unordered_multimap<K,V> const* r); + ~IRelation(); + public: + typename unordered_multimap<K,V>::const_iterator find(const K& k); // Find the object based on key + typename unordered_multimap<K,V>::const_iterator insert(const pair<K,V>& val); // Insert the object pair + bool empty(); // Test is empty? + typename unordered_multimap<K,V>::const_iterator begin(); // Iterator + typename unordered_multimap<K,V>::const_iterator end(); // Iterator + std::pair<typename unordered_multimap<K,V>::const_iterator, + 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 +}; + + +/** + * Default constructor + */ +template <class K,class V> +IRelation<K,V>::IRelation() { + + rel = new unordered_multimap<K,V>(); +} + + +/** + * Useful constructor + */ +template <class K,class V> +IRelation<K,V>::IRelation(const unordered_multimap<K,V>* r) { + + rel = r; +} + + +/** + * Default destructor + */ +template <class K,class V> +IRelation<K,V>::~IRelation() { + + if (rel != NULL) + delete rel; +} + + +/** + * Find the object k in the set + */ +template <class K,class V> +typename unordered_multimap<K,V>::const_iterator IRelation<K,V>::find(const K& k) { + + return rel->find(k); +} + + +/** + * Insert object k into the set + */ +template <class K,class V> +typename unordered_multimap<K,V>::const_iterator IRelation<K,V>::insert(const pair<K,V>& val) { + + return rel->insert(val); +} + + +/** + * Return the "begin" iterator + */ +template <class K,class V> +typename unordered_multimap<K,V>::const_iterator IRelation<K,V>::begin() { + + return rel->begin(); +} + + +/** + * Return the "end" iterator + */ +template <class K,class V> +typename unordered_multimap<K,V>::const_iterator IRelation<K,V>::end() { + + return rel->end(); +} + + +/** + * Return the "equal_range" iterator + */ +template <class K,class V> +std::pair<typename unordered_multimap<K,V>::const_iterator, + typename unordered_multimap<K,V>::const_iterator> + IRelation<K,V>::equal_range(const K& k) { + + return rel->equal_range(k); +} + + +/** + * Return the size of the set + */ +template <class K,class V> +int IRelation<K,V>::size() { + + return rel->size(); +} + + +/** + * Return a new copy of the set + */ +template <class K,class V> +unordered_multimap<K,V> IRelation<K,V>::values() { + + return rel; +} +#endif + + + + diff --git a/iotjava/iotruntime/cpp/setrelation/ISet.hpp b/iotjava/iotruntime/cpp/setrelation/ISet.hpp new file mode 100644 index 0000000..667b8ce --- /dev/null +++ b/iotjava/iotruntime/cpp/setrelation/ISet.hpp @@ -0,0 +1,124 @@ +#ifndef _ISET_HPP__ +#define _ISET_HPP__ +#include <iostream> +#include <string> +#include <unordered_set> + +using namespace std; + +/** This is the IoTSet implementation for C++ + * + * @author Rahmadi Trimananda <rahmadi.trimananda @ uci.edu> + * @version 1.0 + * @since 2016-09-06 + */ +template <class T> +class ISet { + private: + unordered_set<T>* set; + public: + ISet(); + ISet(unordered_set<T> const* s); + ~ISet(); + public: + typename unordered_set<T>::const_iterator find(const T& k); // Find the object + typename unordered_set<T>::const_iterator insert(const T& k); // Insert the object + bool empty(); // Test is empty? + typename unordered_set<T>::const_iterator begin(); // Iterator + typename unordered_set<T>::const_iterator end(); // Iterator + int size(); // Set size + unordered_set<T>* values(); // Return set contents +}; + + +/** + * Default constructor + */ +template <class T> +ISet<T>::ISet() { + + set = new unordered_set<T>(); +} + + +/** + * Useful constructor + */ +template <class T> +ISet<T>::ISet(const unordered_set<T>* s) { + + set = s; +} + + +/** + * Default destructor + */ +template <class T> +ISet<T>::~ISet() { + + if (set != NULL) + delete set; +} + + +/** + * Find the object k in the set + */ +template <class T> +typename unordered_set<T>::const_iterator ISet<T>::find(const T& k) { + + return set->find(k); +} + + +/** + * Insert object k into the set + */ +template <class T> +typename unordered_set<T>::const_iterator ISet<T>::insert(const T& k) { + + return set->insert(k); +} + + +/** + * Return the "begin" iterator + */ +template <class T> +typename unordered_set<T>::const_iterator ISet<T>::begin() { + + return set->begin(); +} + + +/** + * Return the "end" iterator + */ +template <class T> +typename unordered_set<T>::const_iterator ISet<T>::end() { + + return set->end(); +} + + +/** + * Return the size of the set + */ +template <class T> +int ISet<T>::size() { + + return set->size(); +} + + +/** + * Return a new copy of the set + */ +template <class T> +unordered_set<T>* ISet<T>::values() { + + return set; +} +#endif + diff --git a/iotjava/iotruntime/cpp/setrelation/IoTRelation.hpp b/iotjava/iotruntime/cpp/setrelation/IoTRelation.hpp index c2315f9..77c8ff4 100644 --- a/iotjava/iotruntime/cpp/setrelation/IoTRelation.hpp +++ b/iotjava/iotruntime/cpp/setrelation/IoTRelation.hpp @@ -58,7 +58,6 @@ IoTRelation<K,V>::IoTRelation(const unordered_multimap<K,V>& r) { template <class K,class V> IoTRelation<K,V>::~IoTRelation() { - //free(&set); } diff --git a/iotjava/iotruntime/cpp/setrelation/IoTSet.hpp b/iotjava/iotruntime/cpp/setrelation/IoTSet.hpp index f5ba84a..78d8c63 100644 --- a/iotjava/iotruntime/cpp/setrelation/IoTSet.hpp +++ b/iotjava/iotruntime/cpp/setrelation/IoTSet.hpp @@ -55,7 +55,6 @@ IoTSet<T>::IoTSet(const unordered_set<T>& s) { template <class T> IoTSet<T>::~IoTSet() { - //free(&set); }