4 #include "IoTSlave.hpp"
6 IoTSlave::IoTSlave(string _serverAddress, int _serverPort, string _objectName) {
8 serverAddress = _serverAddress;
9 serverPort = _serverPort;
10 objectName = _objectName;
11 socket = new TCPSocket(serverAddress, serverPort);
13 writeToFile("IoTSlave object created! Connection established!");
17 IoTSlave::~IoTSlave() {
27 // Private helper functions
28 int* IoTSlave::byteToInt(int* result, char* bytes) {
31 memcpy(&i, bytes, sizeof(int));
38 char* IoTSlave::intToByteArray(int i, char* bytes) {
40 int iInvert = htobe32(i);
41 memcpy(bytes, &iInvert, sizeof(int));
47 void* IoTSlave::getObjectConverted(void* retObj, string object, string objectClass) {
49 // Returning new objects in heap - so we need to delete them afterwards
50 if (objectClass.compare(STRINGCLASS) == 0) {
51 string* retStr = new string(object);
53 } else if (objectClass.compare(INTCLASS) == 0) {
54 int* retInt = new int(atoi(object.c_str()));
56 } else // return NULL if class is not identifiable
63 // Factoring out iteration
64 char* IoTSlave::recvIter(char* recvBuffer, int recvLen) {
66 int bytesReceived = 0; // Bytes read on each recv()
67 int totalBytesReceived = 0; // Total bytes read
69 while (totalBytesReceived < recvLen) {
70 // Receive up to the buffer size bytes from the sender
71 if ((bytesReceived = (socket->recv(recvBuffer, RCVBUFSIZE))) <= 0) {
72 string errMsg = "IoTSlave: Unable to read!";
73 cerr << errMsg << endl;
77 totalBytesReceived += bytesReceived; // Keep tally of total bytes
84 void IoTSlave::openFile(string fileName) {
86 log.open(FILEPATH + fileName + FILEEXT);
90 void IoTSlave::writeToFile(string logMsg) {
92 log << "IoTSlave: " << logMsg << endl;
96 void IoTSlave::closeFile() {
102 void IoTSlave::instantiateObject(string objectClassName) {
105 string strObj = FILEPATH + objectClassName + SOEXT;
106 void* handle = dlopen (strObj.c_str(), RTLD_LAZY);
108 fputs (dlerror(), stderr);
109 writeToFile("Error handling object!");
112 writeToFile("Object handled!");
114 create_object = (create_t*) dlsym(handle, CREATEFUNCTION.c_str());
115 const char* dlsym_error = dlerror();
117 cerr << "Cannot load symbol create: " << dlsym_error << '\n';
118 writeToFile("Cannot load symbol create!");
121 writeToFile("Object factory created for " + objectClassName);
123 destroy_object = (destroy_t*) dlsym(handle, DESTROYFUNCTION.c_str());
124 dlsym_error = dlerror();
126 cerr << "Cannot load symbol destroy: " << dlsym_error << '\n';
127 writeToFile("Cannot load symbol destroy!");
130 writeToFile("Object destroyer created for " + objectClassName);
135 string IoTSlave::getServerAddress() {
137 return serverAddress;
141 int IoTSlave::getServerPort() {
147 string IoTSlave::getObjectName() {
153 void IoTSlave::sendInteger(int intSend) {
155 char charInt[sizeof(int)];
156 // Convert int to byte array and fix endianness
157 intToByteArray(intSend, charInt);
158 // Send the length first
159 void* toSend = charInt;
160 socket->send(toSend, sizeof(int));
164 int IoTSlave::recvInteger() {
166 int toBeReceived = sizeof(int);
167 char recvInt[sizeof(int)]; // Normally 4 bytes
169 // Receive and iterate until complete
170 recvIter(recvInt, toBeReceived);
173 byteToInt(&retVal, recvInt);
179 void IoTSlave::sendString(string strSend) {
181 // Send the length first
182 int strLen = strSend.length();
186 char* chStrSend = new char[strLen];
187 strcpy(chStrSend, strSend.c_str());
188 void* toSend = chStrSend;
189 socket->send(toSend, strLen);
195 string IoTSlave::recvString() {
197 // Get the length of string first
198 int strLen = recvInteger();
199 char* recvStr = new char[strLen]; // Normally 4 bytes
201 // Receive and iterate until complete
202 recvIter(recvStr, strLen);
204 string retVal(recvStr, strLen);
211 // Create a driver object, e.g. LifxLightBulb
212 void IoTSlave::createObject() {
214 writeToFile("Creating a driver object now...");
216 // Receiving object info
217 objectName = recvString(); sendAck();
218 writeToFile("Driver object name: " + objectName);
219 objectClassName = recvString(); sendAck();
220 writeToFile("Driver object class name: " + objectClassName);
221 objectInterfaceName = recvString(); sendAck();
222 writeToFile("Driver object interface name: " + objectInterfaceName);
223 objectSkelClass = recvString(); sendAck();
224 writeToFile("Driver object skeleton class name: " + objectSkelClass);
225 objectRegPort = recvInteger(); sendAck();
226 writeToFile("Driver object registry port: " + to_string(objectRegPort));
227 objectStubPort = recvInteger(); sendAck();
228 writeToFile("Driver object stub port: " + to_string(objectStubPort));
229 int numOfArgs = recvInteger(); sendAck();
230 for (int i = 0; i < numOfArgs; i++) {
231 string arg = recvString(); sendAck();
233 writeToFile("Got argument: " + arg);
235 for (int i = 0; i < numOfArgs; i++) {
236 string argClass = recvString(); sendAck();
237 args.push_back(argClass);
238 writeToFile("Got argument class: " + argClass);
240 // We are just receiving object information here
241 // Instantiation will be done when IoTDeviceAddress has been sent
242 //instantiateObject(objectClassName);
246 void IoTSlave::createNewIoTSet() {
252 void IoTSlave::getDeviceIoTSetObject() {
258 // Create a main object, e.g. Lifxtest
259 void IoTSlave::createMainObject() {
261 writeToFile("Creating main object: " + objectName);
262 string mainObject = recvString();
267 void IoTSlave::sendAck() {
269 int codeAck = (int) ACKNOWLEDGED;
270 sendInteger(codeAck);
274 bool IoTSlave::recvEndTransfer() {
276 int codeEndTransfer = (int) END_TRANSFER;
277 int recvCode = recvInteger();
278 if (recvCode == codeEndTransfer)
284 void IoTSlave::commIoTMaster() {
286 writeToFile("Starting main loop...");
287 // Main iteration/loop
289 IoTCommCode message = (IoTCommCode) recvInteger();
290 //writeToFile("Message: " + (int) message);
302 case CREATE_MAIN_OBJECT:
306 case CREATE_NEW_IOTSET:
310 case CREATE_NEW_IOTRELATION:
311 //createNewIoTRelation();
314 case GET_IOTSET_OBJECT:
318 case GET_IOTRELATION_FIRST_OBJECT:
319 //getIoTRelationFirstObject();
322 case GET_IOTRELATION_SECOND_OBJECT:
323 //getIoTRelationSecondObject();
326 case REINITIALIZE_IOTSET_FIELD:
327 //reinitializeIoTSetField();
330 case REINITIALIZE_IOTRELATION_FIELD:
331 //reinitializeIoTRelationField();
334 case GET_DEVICE_IOTSET_OBJECT:
335 getDeviceIoTSetObject();
338 case GET_ZB_DEV_IOTSET_OBJECT:
339 //getZBDevIoTSetObject();
342 case GET_ADD_IOTSET_OBJECT:
343 //getAddIoTSetObject();
346 case INVOKE_INIT_METHOD:
347 //invokeInitMethod();
360 writeToFile("End of loop!");
364 int main(int argc, char *argv[]) {
366 /*string serverAddress = "localhost";
367 int serverPort = 12345;
368 IoTSlave *iotSlave = new IoTSlave(serverAddress, serverPort);
369 cout << "Connection established with server!" << endl;
370 int intReceived = iotSlave->recvInteger();
371 cout << "Integer received: " << intReceived << endl;
372 cout << "Integer sent back + 1: " << intReceived++ << endl;
373 iotSlave->sendInteger(intReceived);
374 string strSend = "test sending string";
375 cout << "Sending string: " << strSend << endl;
376 iotSlave->sendString(strSend);
377 cout << "Received string: " << iotSlave->recvString() << endl;*/
379 string serverAddress = argv[1];
380 char* servPort = argv[2];
381 int serverPort = atoi(servPort);
382 string strObjName = argv[3];
383 IoTSlave *iotSlave = new IoTSlave(serverAddress, serverPort, strObjName);
384 //iotSlave->sendInteger(123455);
386 iotSlave->commIoTMaster();