#include "IoTSlave.hpp"
+#include "Lifxtest.cpp"
+
IoTSlave::IoTSlave(string _serverAddress, int _serverPort, string _objectName) {
+ isDriverObject = false; // Default to false
serverAddress = _serverAddress;
serverPort = _serverPort;
objectName = _objectName;
delete socket;
socket = NULL;
}
+ /*if (objMainCls != NULL) {
+ delete objMainCls;
+ objMainCls = NULL;
+ }
+ if (objSkelCls != NULL) {
+ delete objSkelCls;
+ objSkelCls = NULL;
+ }*/
+ for (IoTSet<void*>* iotset : vecIoTSet) {
+ delete iotset;
+ iotset = NULL;
+ }
closeFile();
}
}
-void IoTSlave::instantiateObject(string objectClassName) {
+void IoTSlave::getObjectHandler(string objectClassName) {
// Object handling
string strObj = FILEPATH + objectClassName + SOEXT;
}
writeToFile("Object handled!");
// Create handler
- create_object = (create_t*) dlsym(handle, CREATEFUNCTION.c_str());
+ string createFunction = CREATEFUNCTION + objectClassName;
+ 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("Object factory created for " + objectClassName);
// Destroy handler
- destroy_object = (destroy_t*) dlsym(handle, DESTROYFUNCTION.c_str());
+ string destroyFunction = DESTROYFUNCTION + objectClassName;
+ destroy_object = (destroy_t*) dlsym(handle, destroyFunction.c_str());
dlsym_error = dlerror();
if (dlsym_error) {
cerr << "Cannot load symbol destroy: " << dlsym_error << '\n';
exit(1);
}
writeToFile("Object destroyer created for " + objectClassName);
+ // Create initializer
+ string initFunction = INITFUNCTION + objectClassName;
+ init_object = (init_t*) dlsym(handle, initFunction.c_str());
+ dlsym_error = dlerror();
+ if (dlsym_error) {
+ cerr << "Cannot load symbol init: " << dlsym_error << '\n';
+ writeToFile("Cannot load symbol init!");
+ exit(1);
+ }
+ writeToFile("Object initializer created for " + objectClassName);
+}
+
+
+// Run init_object function
+void IoTSlave::runInitObject(IoTSlave* iotslave) {
+
+ iotslave->init_object(iotslave->objMainCls);
+}
+
+
+// Instantiate main object!
+// Use handler obtained by getObjectHandler() and instantiate object!
+void IoTSlave::instantiateMainObject() {
+
+ // IoTDeviceAddress + other arguments
+ int paramSize = vecIoTSet.size();
+ void* params[paramSize];
+ for(int i=0; i<vecIoTSet.size(); i++) {
+ params[i] = vecIoTSet[i]; // Just the first object is taken in this case
+ }
+ writeToFile("Vector IoTSet size: " + to_string(vecIoTSet.size()));
+ objMainCls = create_object(params);
+ writeToFile("Object created for " + mainObjectName);
+ init_object(objMainCls);
+ //thread th1 (&IoTSlave::runInitObject, this, this);
+ //th1.detach();
+ //thread th1 (&IoTSlave::runInitObject, this, this);
+ //th1.join();
+ writeToFile("Initialized object " + mainObjectName);
+}
+
+
+// Instantiate driver object!
+// Use handler obtained by getObjectHandler() and instantiate object!
+void IoTSlave::instantiateDriverObject() {
+
+ // IoTDeviceAddress + other arguments
+ int paramSize = vecIoTSet.size() + args.size();
+ void* params[paramSize];
+ for(int i=0; i<vecIoTSet.size(); i++) {
+ params[i] = vecIoTSet[i]; // Just the first object is taken in this case
+ }
+ writeToFile("Vector IoTSet size: " + to_string(vecIoTSet.size()));
+ writeToFile("Arg size: " + to_string(args.size()));
+ int countArg = vecIoTSet.size(); // Start from after the address set
+ // Iterate over arguments
+ for(int i=0; i<args.size(); i++) {
+ params[countArg] = getObjectConverted(params[countArg], args[i], argClasses[i]);
+ countArg++;
+ }
+ objMainCls = create_object(params);
+ // Delete unused object after conversion and instantiation
+ for(int i=1; i<paramSize; i++) {
+ if (argClasses[i-1].compare(STRINGCLASS) == 0) {
+ delete (string*) params[i];
+ } else if (argClasses[i-1].compare(INTCLASS) == 0)
+ delete (int*) params[i];
+ }
+ writeToFile("Object created for " + objectClassName);
+}
+
+
+// Use handler obtained by getObjectHandler() and instantiate skeleton object!
+void IoTSlave::instantiateSkelObject() {
+
+ void* params[SKELPARAMSIZE];
+ params[0] = objMainCls;
+ string callbackAddress = LOCALHOST;
+ params[1] = &callbackAddress;
+ params[2] = &objectStubPort;
+ writeToFile("Skeleton Object " + objectSkelClass + " created for " + objectClassName);
+ // After this, this slave needs to be killed using "pkill IoTSlave" because it's waiting in an infinite while-loop
+ objSkelCls = create_object(params);
+}
+
+
+// Use handler obtained by getObjectHandler() and instantiate stub object!
+void IoTSlave::instantiateStubObject() {
+
+ void* params[STUBPARAMSIZE];
+ params[0] = &objectStubPort;
+ params[1] = &hostAddress;
+ string callbackAddress = LOCALHOST;
+ params[2] = &callbackAddress;
+ int rev = 0;
+ params[3] = &rev;
+ bool result = false;
+ params[4] = &result;
+ params[5] = &ports;
+ writeToFile("Stub Object " + objectStubClass + " created for " + objectClassName);
+ objStubCls = create_object(params);
}
void IoTSlave::createObject() {
writeToFile("Creating a driver object now...");
- sendAck();
// Receiving object info
objectName = recvString(); sendAck();
- writeToFile("Driver object name: " + objectName);
+ writeToFile("=> Driver object name: " + objectName);
objectClassName = recvString(); sendAck();
- writeToFile("Driver object class name: " + objectClassName);
+ writeToFile("=> Driver object class name: " + objectClassName);
objectInterfaceName = recvString(); sendAck();
- writeToFile("Driver object interface name: " + objectInterfaceName);
+ writeToFile("=> Driver object interface name: " + objectInterfaceName);
objectSkelClass = recvString(); sendAck();
- writeToFile("Driver object skeleton class name: " + objectSkelClass);
+ writeToFile("=> Driver object skeleton class name: " + objectSkelClass);
objectRegPort = recvInteger(); sendAck();
- writeToFile("Driver object registry port: " + to_string(objectRegPort));
+ writeToFile("=> Driver object registry port: " + to_string(objectRegPort));
objectStubPort = recvInteger(); sendAck();
- writeToFile("Driver object stub port: " + to_string(objectStubPort));
+ 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);
+ writeToFile("==> Got argument: " + arg);
}
for (int i = 0; i < numOfArgs; i++) {
string argClass = recvString(); sendAck();
- args.push_back(argClass);
- writeToFile("Got argument class: " + argClass);
+ argClasses.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);
}
+// Create a new IoTSet object to hold objects
void IoTSlave::createNewIoTSet() {
-
+ objectFieldName = recvString(); sendAck();
+ // Instantiating new IoTSet object
+ isetObject = new unordered_set<void*>();
+ writeToFile("Creating new IoTSet for field: " + objectFieldName);
}
+// Get IoTDeviceAddress object reference and put it inside IoTSet object
void IoTSlave::getDeviceIoTSetObject() {
+ writeToFile("Getting IoTDeviceAddress... ");
+ // Get the IoTDeviceAddress info
+ hostAddress = recvString(); sendAck();
+ writeToFile("=> Host address: " + hostAddress);
+ int sourcePort = recvInteger(); sendAck();
+ writeToFile("=> Source port: " + to_string(sourcePort));
+ int destPort = recvInteger(); sendAck();
+ writeToFile("=> Destination port: " + to_string(destPort));
+ bool sourcePortWildCard = (bool) recvInteger(); sendAck();
+ writeToFile("=> Is source port wild card? " + to_string(sourcePortWildCard));
+ bool destPortWildCard = (bool) recvInteger(); sendAck();
+ writeToFile("=> Is destination port wild card? " + to_string(destPortWildCard));
+ // Create IoTDeviceAddress
+ IoTDeviceAddress* objDeviceAddress = new IoTDeviceAddress(hostAddress, sourcePort, destPort,
+ sourcePortWildCard, destPortWildCard);
+ // Insert it into isetObject!
+ isetObject->insert(objDeviceAddress);
+ writeToFile("=> Inserting IoTDeviceAddress into set...");
+ writeToFile("==> Now we have " + to_string(isetObject->size()) + " object(s)!");
+ // Set flag to true;
+ isDriverObject = true;
+}
+
+
+// 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));
+ }
+ // Create Stub object
+ unordered_map<string,void*>::const_iterator itr = mapObjNameStub.find(objectName);
+ if (itr != mapObjNameStub.end()) { // Stub has been created earlier
+ writeToFile("=> Stub has been created! Getting back reference...");
+ objStubCls = itr->second;
+ } else { // Instantiate a new stub and map it
+ writeToFile("=> Stub has not been created! Creating a new stub...");
+ getObjectHandler(objectStubClass);
+ instantiateStubObject();
+ mapObjNameStub.insert(make_pair(objectName,objStubCls));
+ writeToFile("=> Map has: " + to_string(mapObjNameStub.size()) + " members");
+ }
+ // Insert it into isetObject!
+ isetObject->insert(objStubCls);
+ writeToFile("=> Inserting stub object into set...");
+ writeToFile("==> Now we have " + to_string(isetObject->size()) + " object(s)!");
+}
+
+
+// Reinitialize IoTSet field!
+void IoTSlave::reinitializeIoTSetField() {
+
+ writeToFile("Reinitialize IoTSet field...");
+ iotsetObject = new IoTSet<void*>(isetObject);
+ // Collect IoTSet field first in a vector
+ vecIoTSet.push_back(iotsetObject);
+
+ // Create object if this is for driver object
+ if (isDriverObject) {
+ // Instantiate driver object
+ getObjectHandler(objectClassName);
+ instantiateDriverObject();
+ // Instantiate skeleton object
+ getObjectHandler(objectSkelClass);
+ instantiateSkelObject();
+ }
+}
+
+
+// Invoke init() method in main controller
+void IoTSlave::invokeInitMethod() {
+
+ writeToFile("Invoke init() method for: " + mainObjectName);
+ // Instantiate main controller object
+ getObjectHandler(mainObjectName);
+ instantiateMainObject();
}
// Create a main object, e.g. Lifxtest
void IoTSlave::createMainObject() {
- writeToFile("Creating main object: " + objectName);
- string mainObject = recvString();
- sendAck();
+ mainObjectName = recvString(); sendAck();
+ writeToFile("Creating main object: " + mainObjectName);
+ // Just receive the name of the class object here
+ // We will instantiate the object after we get the set/relation objects
}
writeToFile("Starting main loop...");
// Main iteration/loop
while(true) {
- IoTCommCode message = (IoTCommCode) recvInteger();
+ IoTCommCode message = (IoTCommCode) recvInteger(); sendAck();
//writeToFile("Message: " + (int) message);
-
+
switch(message) {
case CREATE_OBJECT:
break;
case GET_IOTSET_OBJECT:
- //getIoTSetObject();
+ getIoTSetObject();
break;
case GET_IOTRELATION_FIRST_OBJECT:
break;
case REINITIALIZE_IOTSET_FIELD:
- //reinitializeIoTSetField();
+ reinitializeIoTSetField();
break;
case REINITIALIZE_IOTRELATION_FIELD:
break;
case INVOKE_INIT_METHOD:
- //invokeInitMethod();
+ invokeInitMethod();
break;
case END_SESSION:
int serverPort = atoi(servPort);
string strObjName = argv[3];
IoTSlave *iotSlave = new IoTSlave(serverAddress, serverPort, strObjName);
- //iotSlave->sendInteger(123455);
iotSlave->sendAck();
iotSlave->commIoTMaster();