--- /dev/null
+#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;
+}*/
}
};
+
+//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
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)
+++ /dev/null
-#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
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() {
void handleStateVersionMessageReceived(char* payloadData);
void handleLightStateMessageReceived(char* payloadData);
};
+
+//typedef LifxLightBulb* create_t(IoTSet<IoTDeviceAddress*>* _devAddress, string macAddress);
+//typedef void destroy_t(LifxLightBulb*);
#endif
--- /dev/null
+#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;
+}*/
};
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
all: light
+ARGS = -shared -fpic
+
# Compile
#
PHONY += 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)
--- /dev/null
+/** 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,
+}
+
--- /dev/null
+#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;
+}
--- /dev/null
+#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
--- /dev/null
+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);
+
+ }
+}
--- /dev/null
+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)
--- /dev/null
+#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;
+}*/
+
+
--- /dev/null
+#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
+
+
+
+
--- /dev/null
+#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
+
template <class K,class V>
IoTRelation<K,V>::~IoTRelation() {
- //free(&set);
}
template <class T>
IoTSet<T>::~IoTSet() {
- //free(&set);
}