From b4f15c87c5200b78a292243cbfb271c48d9d6c5e Mon Sep 17 00:00:00 2001 From: rtrimana Date: Fri, 4 Nov 2016 17:05:52 -0700 Subject: [PATCH] Adding callback for C++ (still has bug for return values); adding struct as method argument; still missing struct as return value; clean up needed later --- iotjava/iotrmi/C++/IoTRMICall.hpp | 9 ++ iotjava/iotrmi/C++/IoTRMIObject.hpp | 3 + iotjava/iotrmi/C++/IoTSocket.hpp | 2 +- iotjava/iotrmi/C++/sample/CallBack.hpp | 4 + .../iotrmi/C++/sample/CallBackInterface.hpp | 5 + .../iotrmi/C++/sample/CallBack_CBSkeleton.hpp | 67 ++++++---- iotjava/iotrmi/C++/sample/CallBack_CBStub.hpp | 6 + .../iotrmi/C++/sample/CallBack_Skeleton.hpp | 4 + iotjava/iotrmi/C++/sample/CallBack_Stub.hpp | 5 +- iotjava/iotrmi/C++/sample/StructC.cpp | 33 +++++ iotjava/iotrmi/C++/sample/StructC.hpp | 13 ++ iotjava/iotrmi/C++/sample/Test.cpp | 32 +++++ iotjava/iotrmi/C++/sample/Test2.cpp | 25 ++++ iotjava/iotrmi/C++/sample/TestClass.cpp | 1 + iotjava/iotrmi/C++/sample/TestClass.hpp | 31 ++++- .../iotrmi/C++/sample/TestClassInterface.hpp | 10 +- .../iotrmi/C++/sample/TestClass_Skeleton.cpp | 5 +- .../iotrmi/C++/sample/TestClass_Skeleton.hpp | 116 ++++++++++++++-- iotjava/iotrmi/C++/sample/TestClass_Stub.cpp | 36 ++++- iotjava/iotrmi/C++/sample/TestClass_Stub.hpp | 126 +++++++++++++++++- iotjava/iotrmi/Java/sample/StructJ.java | 8 ++ iotjava/iotrmi/Java/sample/StructMain.java | 17 +++ iotjava/iotrmi/Java/sample/TestClass.java | 17 ++- .../Java/sample/TestClassInterface.java | 1 + .../Java/sample/TestClass_CBSkeleton.java | 8 +- .../iotrmi/Java/sample/TestClass_CBStub.java | 7 +- .../Java/sample/TestClass_Skeleton.java | 45 ++++++- .../iotrmi/Java/sample/TestClass_Stub.java | 57 +++++++- 28 files changed, 630 insertions(+), 63 deletions(-) create mode 100644 iotjava/iotrmi/C++/sample/StructC.cpp create mode 100644 iotjava/iotrmi/C++/sample/StructC.hpp create mode 100644 iotjava/iotrmi/C++/sample/Test.cpp create mode 100644 iotjava/iotrmi/C++/sample/Test2.cpp create mode 100644 iotjava/iotrmi/Java/sample/StructJ.java create mode 100644 iotjava/iotrmi/Java/sample/StructMain.java diff --git a/iotjava/iotrmi/C++/IoTRMICall.hpp b/iotjava/iotrmi/C++/IoTRMICall.hpp index f498758..c749b02 100644 --- a/iotjava/iotrmi/C++/IoTRMICall.hpp +++ b/iotjava/iotrmi/C++/IoTRMICall.hpp @@ -15,11 +15,14 @@ #include #include +#include #include "IoTRMIUtil.hpp" #include "IoTSocketClient.hpp" using namespace std; +mutex mtx; + class IoTRMICall { public: IoTRMICall(int _port, const char* _address, int _rev, bool* _bResult, @@ -80,14 +83,20 @@ IoTRMICall::~IoTRMICall() { void* IoTRMICall::remoteCall(int objectId, string methodSign, string retType, string paramCls[], void* paramObj[], int numParam, void* retObj) { + // Critical section that is used by different objects + lock_guard guard(mtx); // Send input parameters int len = methodLength(paramCls, paramObj, numParam); char method[len]; + cout << "Got in remoteCall!" << endl; methodToBytes(objectId, methodSign, paramCls, paramObj, method, numParam); + cout << "Executed methodToBytes in remoteCall!" << endl; + IoTRMIUtil::printBytes(method, len, false); // Send bytes fflush(NULL); rmiClient->sendBytes(method, len); fflush(NULL); + cout << "Got in remoteCall! 2" << endl; // Receive return value and return it to caller if (retType.compare("void") == 0) // Just make it NULL if it's a void return diff --git a/iotjava/iotrmi/C++/IoTRMIObject.hpp b/iotjava/iotrmi/C++/IoTRMIObject.hpp index 366c6ef..084fb7b 100644 --- a/iotjava/iotrmi/C++/IoTRMIObject.hpp +++ b/iotjava/iotrmi/C++/IoTRMIObject.hpp @@ -106,7 +106,10 @@ void IoTRMIObject::sendReturnObj(void* retObj, string type) { char* IoTRMIObject::getMethodBytes() { // Get method in bytes and update method length + cout << "Got into getMethodBytes()" << endl; + //fflush(NULL); methodBytes = rmiServer->receiveBytes(methodBytes, &methodLen); + cout << "Got into getMethodBytes() 2" << endl; fflush(NULL); return methodBytes; } diff --git a/iotjava/iotrmi/C++/IoTSocket.hpp b/iotjava/iotrmi/C++/IoTSocket.hpp index 46685f7..54f0234 100644 --- a/iotjava/iotrmi/C++/IoTSocket.hpp +++ b/iotjava/iotrmi/C++/IoTSocket.hpp @@ -159,7 +159,7 @@ char* IoTSocket::receiveBytes(char* pVals, int* len) if (!receiveAck()) return NULL; #endif - + cout << "Socket 6!" << endl; return pVals; } diff --git a/iotjava/iotrmi/C++/sample/CallBack.hpp b/iotjava/iotrmi/C++/sample/CallBack.hpp index a4b9db4..7774d76 100644 --- a/iotjava/iotrmi/C++/sample/CallBack.hpp +++ b/iotjava/iotrmi/C++/sample/CallBack.hpp @@ -1,3 +1,6 @@ +#ifndef _CALLBACK_HPP__ +#define _CALLBACK_HPP__ + #include #include "CallBackInterface.hpp" @@ -36,4 +39,5 @@ void CallBack::setInt(int _i) { intA = _i; } +#endif diff --git a/iotjava/iotrmi/C++/sample/CallBackInterface.hpp b/iotjava/iotrmi/C++/sample/CallBackInterface.hpp index 9864d6f..7364f8d 100644 --- a/iotjava/iotrmi/C++/sample/CallBackInterface.hpp +++ b/iotjava/iotrmi/C++/sample/CallBackInterface.hpp @@ -1,3 +1,6 @@ +#ifndef _CALLBACKINTERFACE_HPP__ +#define _CALLBACKINTERFACE_HPP__ + #include using namespace std; @@ -8,3 +11,5 @@ class CallBackInterface { virtual void setInt(int _i) = 0; }; +#endif + diff --git a/iotjava/iotrmi/C++/sample/CallBack_CBSkeleton.hpp b/iotjava/iotrmi/C++/sample/CallBack_CBSkeleton.hpp index b2f56a2..7ed5f04 100644 --- a/iotjava/iotrmi/C++/sample/CallBack_CBSkeleton.hpp +++ b/iotjava/iotrmi/C++/sample/CallBack_CBSkeleton.hpp @@ -1,6 +1,10 @@ +#ifndef _CALLBACK_CBSKELETON_HPP__ +#define _CALLBACK_CBSKELETON_HPP__ + #include +#include "CallBackInterface.hpp" #include "../IoTRMIObject.hpp" -#include "CallBack.hpp" + using namespace std; @@ -9,7 +13,7 @@ class CallBack_CBSkeleton : public CallBackInterface { CallBack_CBSkeleton(CallBackInterface* _cb, int _objectId); ~CallBack_CBSkeleton(); - void invokeMethod(IoTRMIObject* rmiObj); + void* invokeMethod(IoTRMIObject* rmiObj, string *type); int printInt(); void setInt(int _i); @@ -43,35 +47,41 @@ CallBack_CBSkeleton::~CallBack_CBSkeleton() { } -void CallBack_CBSkeleton::invokeMethod(IoTRMIObject* rmiObj) { +void* CallBack_CBSkeleton::invokeMethod(IoTRMIObject* rmiObj, string *type) { // Loop continuously waiting for incoming bytes - while (true) { - - rmiObj->getMethodBytes(); - string methodSign = rmiObj->getSignature(); - cout << "Method sign: " << methodSign << endl; - - if (methodSign.compare("intprintInt()") == 0) { - string paramCls[] = { }; - int numParam = 0; - void* paramObj[] = { }; - rmiObj->getMethodParams(paramCls, numParam, paramObj); - int retVal = printInt(); - void* retObj = &retVal; - rmiObj->sendReturnObj(retObj, "int"); - } else if (methodSign.compare("voidsetInt(int)") == 0) { - string paramCls[] = { "int" }; - int numParam = 1; - int param1 = 1; - void* paramObj[] = { ¶m1 }; - rmiObj->getMethodParams(paramCls, numParam, paramObj); - setInt(param1); - } else { - string error = "Signature not recognized: " + string(methodSign); - throw error; - } + void* retObj = NULL; + cout << "Get inside invoke method!" << endl; + + //rmiObj->getMethodBytes(); + cout << "Get inside invoke 2!" << endl; + string methodSign = rmiObj->getSignature(); + cout << "Get inside invoke 3!" << endl; + cout << "Method sign: " << methodSign << endl; + + if (methodSign.compare("intprintInt()") == 0) { + string paramCls[] = { }; + int numParam = 0; + void* paramObj[] = { }; + rmiObj->getMethodParams(paramCls, numParam, paramObj); + int retVal = printInt(); + retObj = &retVal; + *type = "int"; + rmiObj->sendReturnObj(retObj, "int"); + } else if (methodSign.compare("voidsetInt(int)") == 0) { + string paramCls[] = { "int" }; + int numParam = 1; + int param1 = 1; + void* paramObj[] = { ¶m1 }; + rmiObj->getMethodParams(paramCls, numParam, paramObj); + setInt(param1); + *type = "void"; + } else { + string error = "Signature not recognized: " + string(methodSign); + throw error; } + + return retObj; } @@ -86,4 +96,5 @@ void CallBack_CBSkeleton::setInt(int _i) { cb->setInt(_i); } +#endif diff --git a/iotjava/iotrmi/C++/sample/CallBack_CBStub.hpp b/iotjava/iotrmi/C++/sample/CallBack_CBStub.hpp index 07b5b3c..090b2c4 100644 --- a/iotjava/iotrmi/C++/sample/CallBack_CBStub.hpp +++ b/iotjava/iotrmi/C++/sample/CallBack_CBStub.hpp @@ -1,3 +1,6 @@ +#ifndef _CALLBACK_CBSTUB_HPP__ +#define _CALLBACK_CBSTUB_HPP__ + #include #include "CallBackInterface.hpp" #include "../IoTRMICall.hpp" @@ -55,6 +58,7 @@ CallBack_CBStub::~CallBack_CBStub() { int CallBack_CBStub::printInt() { + cout << "Got here in printInt()" << endl; int numParam = 0; string sign = "intprintInt()"; string retType = "int"; @@ -63,6 +67,7 @@ int CallBack_CBStub::printInt() { int retVal = 0; void* retObj = &retVal; rmiCall->remoteCall(objectId, sign, retType, paramCls, paramObj, numParam, retObj); + cout << "Return value from printInt(): " << retVal << endl; return retVal; } @@ -78,4 +83,5 @@ void CallBack_CBStub::setInt(int _i) { rmiCall->remoteCall(objectId, sign, retType, paramCls, paramObj, numParam, retObj); } +#endif diff --git a/iotjava/iotrmi/C++/sample/CallBack_Skeleton.hpp b/iotjava/iotrmi/C++/sample/CallBack_Skeleton.hpp index 36477ac..b087046 100644 --- a/iotjava/iotrmi/C++/sample/CallBack_Skeleton.hpp +++ b/iotjava/iotrmi/C++/sample/CallBack_Skeleton.hpp @@ -1,3 +1,6 @@ +#ifndef _CALLBACK_SKELETON_HPP__ +#define _CALLBACK_SKELETON_HPP__ + #include #include "../IoTRMIObject.hpp" #include "CallBack.hpp" @@ -91,4 +94,5 @@ void CallBack_Skeleton::setInt(int _i) { cb->setInt(_i); } +#endif diff --git a/iotjava/iotrmi/C++/sample/CallBack_Stub.hpp b/iotjava/iotrmi/C++/sample/CallBack_Stub.hpp index b1fa580..42f1059 100644 --- a/iotjava/iotrmi/C++/sample/CallBack_Stub.hpp +++ b/iotjava/iotrmi/C++/sample/CallBack_Stub.hpp @@ -1,3 +1,6 @@ +#ifndef _CALLBACK_STUB_HPP__ +#define _CALLBACK_STUB_HPP__ + #include #include "CallBackInterface.hpp" #include "../IoTRMICall.hpp" @@ -80,4 +83,4 @@ void CallBack_Stub::setInt(int _i) { rmiCall->remoteCall(objectId, sign, retType, paramCls, paramObj, numParam, retObj); } - +#endif diff --git a/iotjava/iotrmi/C++/sample/StructC.cpp b/iotjava/iotrmi/C++/sample/StructC.cpp new file mode 100644 index 0000000..060d255 --- /dev/null +++ b/iotjava/iotrmi/C++/sample/StructC.cpp @@ -0,0 +1,33 @@ +#include +#include +#include "StructC.hpp" + +int main(int argc, char *argv[]) { + + data testdata; + testdata.name = "Rahmadi"; + testdata.value = 0.123; + testdata.year = 2016; + + /*cout << "Name: " << testdata.name << endl; + cout << "Value: " << testdata.value << endl; + cout << "Year: " << testdata.year << endl;*/ + + vector dataset; + data testdata2; + testdata2.name = "Trimananda"; + testdata2.value = 0.223; + testdata2.year = 2017; + + dataset.push_back(testdata); + dataset.push_back(testdata2); + + for (data dat : dataset) { + + cout << "Name: " << dat.name << endl; + cout << "Value: " << dat.value << endl; + cout << "Year: " << dat.year << endl; + } + + return 0; +} diff --git a/iotjava/iotrmi/C++/sample/StructC.hpp b/iotjava/iotrmi/C++/sample/StructC.hpp new file mode 100644 index 0000000..b762f5e --- /dev/null +++ b/iotjava/iotrmi/C++/sample/StructC.hpp @@ -0,0 +1,13 @@ +#ifndef _STRUCTC_HPP__ +#define _STRUCTC_HPP__ + +using namespace std; + +struct data { + string name; + float value; + int year; +}; + +#endif + diff --git a/iotjava/iotrmi/C++/sample/Test.cpp b/iotjava/iotrmi/C++/sample/Test.cpp new file mode 100644 index 0000000..8d1771e --- /dev/null +++ b/iotjava/iotrmi/C++/sample/Test.cpp @@ -0,0 +1,32 @@ +#include +#include +#include +#include +#include +#include + +std::map g_pages; +std::mutex g_pages_mutex; + +void save_page(const std::string &url) +{ + // simulate a long page fetch + std::this_thread::sleep_for(std::chrono::seconds(2)); + std::string result = "fake content"; + + std::lock_guard guard(g_pages_mutex); + g_pages[url] = result; +} + +int main() +{ + std::thread t1(save_page, "http://foo"); + std::thread t2(save_page, "http://bar"); + t1.join(); + t2.join(); + + // safe to access g_pages without lock now, as the threads are joined + for (const auto &pair : g_pages) { + std::cout << pair.first << " => " << pair.second << '\n'; + } +} \ No newline at end of file diff --git a/iotjava/iotrmi/C++/sample/Test2.cpp b/iotjava/iotrmi/C++/sample/Test2.cpp new file mode 100644 index 0000000..3996381 --- /dev/null +++ b/iotjava/iotrmi/C++/sample/Test2.cpp @@ -0,0 +1,25 @@ +// mutex example +#include // std::cout +#include // std::thread +#include // std::mutex + +std::mutex mtx; // mutex for critical section + +void print_block (int n, char c) { + // critical section (exclusive access to std::cout signaled by locking mtx): + mtx.lock(); + for (int i=0; i #include #include "TestClass.hpp" +#include "CallBack.hpp" using namespace std; diff --git a/iotjava/iotrmi/C++/sample/TestClass.hpp b/iotjava/iotrmi/C++/sample/TestClass.hpp index efa4f2a..61dd2e3 100644 --- a/iotjava/iotrmi/C++/sample/TestClass.hpp +++ b/iotjava/iotrmi/C++/sample/TestClass.hpp @@ -1,5 +1,9 @@ +#ifndef _TESTCLASS_HPP__ +#define _TESTCLASS_HPP__ + #include #include "TestClassInterface.hpp" +#include "StructC.hpp" using namespace std; @@ -19,6 +23,7 @@ class TestClass : public TestClassInterface { void registerCallback(CallBackInterface* _cb); void registerCallback(vector _cb); int callBack(); + void handleStruct(vector vecData); private: int intA; @@ -120,6 +125,17 @@ void TestClass::registerCallback(vector _cb) { } +void TestClass::handleStruct(vector vecData) { + + for (data dat : vecData) { + + cout << "Name: " << dat.name << endl; + cout << "Value: " << dat.value << endl; + cout << "Year: " << dat.year << endl; + } +} + + //int TestClass::callBack() { // return cb.printInt(); //} @@ -129,7 +145,20 @@ int TestClass::callBack() { int sum = 0; for (CallBackInterface* cb : cbvec) { - sum = sum + cb->printInt(); + //cout << "Sum: " << sum << endl; + //sum = sum + cb->printInt(); + cb->setInt(sum++); } + //CallBackInterface* cb = cbvec[0]; + //sum = cb->printInt(); + //sum = sum + cb->printInt(); + //cb->printInt(); + //CallBackInterface* cb1 = cbvec[0]; + //cb1->printInt(); + + + return sum; } +#endif + diff --git a/iotjava/iotrmi/C++/sample/TestClassInterface.hpp b/iotjava/iotrmi/C++/sample/TestClassInterface.hpp index 0dd0845..ed73f1e 100644 --- a/iotjava/iotrmi/C++/sample/TestClassInterface.hpp +++ b/iotjava/iotrmi/C++/sample/TestClassInterface.hpp @@ -1,7 +1,10 @@ +#ifndef _TESTCLASSINTERFACE_HPP__ +#define _TESTCLASSINTERFACE_HPP__ + #include #include -#include "CallBack_CBSkeleton.hpp" -//#include "CallBack.hpp" +#include "CallBackInterface.hpp" +#include "StructC.hpp" using namespace std; @@ -17,5 +20,8 @@ class TestClassInterface { virtual void registerCallback(CallBackInterface* _cb) = 0; virtual void registerCallback(vector _cb) = 0; virtual int callBack() = 0; + virtual void handleStruct(vector vecData) = 0; }; +#endif + diff --git a/iotjava/iotrmi/C++/sample/TestClass_Skeleton.cpp b/iotjava/iotrmi/C++/sample/TestClass_Skeleton.cpp index 23079c8..665bd16 100644 --- a/iotjava/iotrmi/C++/sample/TestClass_Skeleton.cpp +++ b/iotjava/iotrmi/C++/sample/TestClass_Skeleton.cpp @@ -1,16 +1,17 @@ #include #include #include "TestClass_Skeleton.hpp" +#include "TestClass.hpp" using namespace std; int main(int argc, char *argv[]) { - int port = 5010; + int port = 5011; TestClassInterface *tc = new TestClass(3, 5.0, "7911"); TestClass_Skeleton *tcSkel = new TestClass_Skeleton(tc, port); - tcSkel->waitRequestInvokeMethod(); + //tcSkel->waitRequestInvokeMethod(); delete tc; delete tcSkel; diff --git a/iotjava/iotrmi/C++/sample/TestClass_Skeleton.hpp b/iotjava/iotrmi/C++/sample/TestClass_Skeleton.hpp index 8786e0e..b5452c0 100644 --- a/iotjava/iotrmi/C++/sample/TestClass_Skeleton.hpp +++ b/iotjava/iotrmi/C++/sample/TestClass_Skeleton.hpp @@ -1,6 +1,11 @@ +#ifndef _TESTCLASS_SKELETON_HPP__ +#define _TESTCLASS_SKELETON_HPP__ + #include #include "../IoTRMIObject.hpp" -#include "TestClass.hpp" +#include "../IoTRMICall.hpp" +#include "CallBack_CBStub.hpp" +#include "TestClassInterface.hpp" using namespace std; @@ -20,13 +25,17 @@ class TestClass_Skeleton : public TestClassInterface { void registerCallback(CallBackInterface* _cb); void registerCallback(vector _cb); int callBack(); + void handleStruct(vector vecData); - const static int size = 9; + const static int size = 12; const static string methodSignatures[size]; private: - TestClassInterface *tc; - IoTRMIObject *rmiObj; + TestClassInterface *tc; + IoTRMIObject *rmiObj; + IoTRMICall *rmiCall; + static int objIdCnt; + vector vecCBObj; //CallBackInterface cbstub; }; @@ -41,15 +50,24 @@ const string TestClass_Skeleton::methodSignatures[TestClass_Skeleton::size] = { "intsetACAndGetA(string,int)", "intcallBack()", "voidregisterCallBack(CallBackInterface)", - "voidregisterCallBack(CallBackInterface[])" + "voidregisterCallBack(CallBackInterface[])", + "registercallback", + "handleStruct(StructJ[])", + "structsize" }; +int TestClass_Skeleton::objIdCnt = 0; + + TestClass_Skeleton::TestClass_Skeleton(TestClassInterface* _tc, int _port) { bool _bResult = false; tc = _tc; + cout << "Reached here 1!" << endl; rmiObj = new IoTRMIObject(_port, &_bResult, methodSignatures, size); + cout << "Reached here 2!" << endl; + waitRequestInvokeMethod(); } @@ -59,11 +77,20 @@ TestClass_Skeleton::~TestClass_Skeleton() { delete rmiObj; rmiObj = NULL; } + if (rmiCall != NULL) { + delete rmiCall; + rmiCall = NULL; + } + for(CallBackInterface* cb : vecCBObj) { + delete cb; + cb = NULL; + } } void TestClass_Skeleton::waitRequestInvokeMethod() { + int structsize1 = 0; // Loop continuously waiting for incoming bytes while (true) { @@ -130,11 +157,77 @@ void TestClass_Skeleton::waitRequestInvokeMethod() { void* retObj = &retVal; rmiObj->sendReturnObj(retObj, "int"); /*} else if (methodSign.compare("voidregisterCallBack(CallBackInterface)") == 0) { - // - } else if (methodSign.compare("intcallBack()") == 0) { //*/ + } else if (methodSign.compare("voidregisterCallBack(CallBackInterface[])") == 0) { + string paramCls[] = { "int" }; + int numParam = 1; + int numStubs = 0; + void* paramObj[] = { &numStubs }; + rmiObj->getMethodParams(paramCls, numParam, paramObj); + vector stub; + for (int objId = 0; objId < numStubs; objId++) { + CallBackInterface* cb = new CallBack_CBStub(rmiCall, objIdCnt); + stub.push_back(cb); + vecCBObj.push_back(cb); + objIdCnt++; + } + registerCallback(stub); + } else if (methodSign.compare("registercallback") == 0) { + string paramCls[] = { "int", "string", "int" }; + int numParam = 3; + int param1 = 0; + string param2 = ""; + int param3 = 0; + void* paramObj[] = { ¶m1, ¶m2, ¶m3 }; + cout << "Get here! Registering callback!" << endl; + rmiObj->getMethodParams(paramCls, numParam, paramObj); + // Instantiate IoTRMICall object + bool bResult = false; + rmiCall = new IoTRMICall(param1, param2.c_str(), param3, &bResult, + CallBack_CBStub::methodSignatures, CallBack_CBStub::size); + } else if (methodSign.compare("intcallBack()") == 0) { + cout << "Get here inside callback!!!" << endl; + int retVal = callBack(); + cout << "Return value in TestClass_Skeleton: " << retVal << endl; + void* retObj = &retVal; + rmiObj->sendReturnObj(retObj, "int"); + // Handle struct + } else if (methodSign.compare("structsize") == 0) { + string paramCls[] = { "int" }; + int numParam = 1; + int param1 = 0; + void* paramObj[] = { ¶m1 }; + rmiObj->getMethodParams(paramCls, numParam, paramObj); + structsize1 = param1; + cout << "Struct size: " << structsize1 << endl; + } else if (methodSign.compare("handleStruct(StructJ[])") == 0) { + string paramCls[3*structsize1]; + void* paramObj[3*structsize1]; + int numParam = 3*structsize1; + // define array of everything + string param1[structsize1]; + float param2[structsize1]; + int param3[structsize1]; + int pos = 0; + for(int i=0; i < structsize1; i++) { + paramCls[pos] = "string"; + paramObj[pos++] = ¶m1[i]; + paramCls[pos] = "float"; + paramObj[pos++] = ¶m2[i]; + paramCls[pos] = "int"; + paramObj[pos++] = ¶m3[i]; + } + rmiObj->getMethodParams(paramCls, numParam, paramObj); + vector dat(structsize1); + pos = 0; + for (int i=0; i < structsize1; i++) { + dat[i].name = param1[i]; + dat[i].value = param2[i]; + dat[i].year = param3[i]; + } + handleStruct(dat); } else { - string error = "Signature unreqcognized: " + string(methodSign); + string error = "Signature unrecognized: " + string(methodSign); throw error; } } @@ -201,3 +294,10 @@ int TestClass_Skeleton::callBack() { } +void TestClass_Skeleton::handleStruct(vector vecData) { + + tc->handleStruct(vecData); +} + +#endif + diff --git a/iotjava/iotrmi/C++/sample/TestClass_Stub.cpp b/iotjava/iotrmi/C++/sample/TestClass_Stub.cpp index 12f47b3..d56d39d 100644 --- a/iotjava/iotrmi/C++/sample/TestClass_Stub.cpp +++ b/iotjava/iotrmi/C++/sample/TestClass_Stub.cpp @@ -1,18 +1,19 @@ #include #include #include "TestClass_Stub.hpp" +#include "CallBack.hpp" using namespace std; int main(int argc, char *argv[]) { - int port = 5010; + int port = 5011; const char* address = "localhost"; int rev = 0; bool bResult = false; vector ports; - ports.push_back(12345); + ports.push_back(12346); //ports.push_back(13234); TestClassInterface *tcStub = new TestClass_Stub(port, address, rev, &bResult, ports); @@ -28,8 +29,39 @@ int main(int argc, char *argv[]) input.push_back(987);*/ cout << "Return value: " << tcStub->sumArray(input) << endl; + + /*CallBackInterface *cb1 = new CallBack(23); + CallBackInterface *cb2 = new CallBack(33); + CallBackInterface *cb3 = new CallBack(43); + vector cb; + cb.push_back(cb1); + cb.push_back(cb2); + cb.push_back(cb3); + tcStub->registerCallback(cb); + cout << "Return value from callback: " << tcStub->callBack() << endl; delete tcStub; + delete cb1; + delete cb2; + delete cb3;*/ + vector dataset; + + data testdata; + testdata.name = "Rahmadi"; + testdata.value = 0.123; + testdata.year = 2016; + + data testdata2; + testdata2.name = "Trimananda"; + testdata2.value = 0.223; + testdata2.year = 2017; + + dataset.push_back(testdata); + dataset.push_back(testdata2); + + tcStub->handleStruct(dataset); + + delete tcStub; return 0; } diff --git a/iotjava/iotrmi/C++/sample/TestClass_Stub.hpp b/iotjava/iotrmi/C++/sample/TestClass_Stub.hpp index 1749a59..39ede87 100644 --- a/iotjava/iotrmi/C++/sample/TestClass_Stub.hpp +++ b/iotjava/iotrmi/C++/sample/TestClass_Stub.hpp @@ -1,7 +1,13 @@ +#ifndef _TESTCLASS_STUB_HPP__ +#define _TESTCLASS_STUB_HPP__ + #include +#include #include "../IoTRMICall.hpp" #include "../IoTRMIObject.hpp" #include "TestClassInterface.hpp" +#include "CallBack_CBSkeleton.hpp" +#include "StructC.hpp" using namespace std; @@ -21,9 +27,11 @@ class TestClass_Stub : public TestClassInterface { void registerCallback(CallBackInterface* _cb); void registerCallback(vector_cb); int callBack(); - void init_CallBack(); + void handleStruct(vector vecData); + void ____init_CallBack(); // thread + void ____registerCallBack(); // tell the other side that we are ready - const static int size = 9; + const static int size = 12; const static string methodSignatures[size]; private: @@ -35,12 +43,16 @@ class TestClass_Stub : public TestClassInterface { IoTRMIObject *rmiObj; string address; vector ports; - map mapCBObj; + vector vecCBObj; int objectId = 0; // Default value is 0 + static int objIdCnt; }; +int TestClass_Stub::objIdCnt = 0; + + const string TestClass_Stub::methodSignatures[TestClass_Stub::size] = { "voidsetA(int)", "voidsetB(float)", @@ -51,7 +63,10 @@ const string TestClass_Stub::methodSignatures[TestClass_Stub::size] = { "intsetACAndGetA(string,int)", "intcallBack()", "voidregisterCallBack(CallBackInterface)", - "voidregisterCallBack(CallBackInterface[])" + "voidregisterCallBack(CallBackInterface[])", + "registercallback", + "handleStruct(StructJ[])", + "structsize" }; @@ -67,6 +82,13 @@ TestClass_Stub::TestClass_Stub(int _port, const char* _address, int _rev, bool* address = _address; rmiCall = new IoTRMICall(_port, _address, _rev, _bResult, methodSignatures, size); ports = _ports; + // Start thread + cout << "Reached here 1!" << endl; +// thread th1 (&TestClass_Stub::____init_CallBack, this); +// th1.detach(); + //th1.join(); + cout << "Reached here 2!" << endl; +// ____registerCallBack(); } @@ -76,21 +98,66 @@ TestClass_Stub::~TestClass_Stub() { delete rmiCall; rmiCall = NULL; } + if (rmiObj != NULL) { + delete rmiObj; + rmiObj = NULL; + } + for(CallBackInterface* cb : vecCBObj) { + delete cb; + cb = NULL; + } } // Callback handler thread -void TestClass_Stub::init_CallBack() { +void TestClass_Stub::____init_CallBack() { bool bResult = false; + cout << "Reach here init!" << endl; rmiObj = new IoTRMIObject(ports[0], &bResult, CallBack_CBSkeleton::methodSignatures, CallBack_CBSkeleton::size); + cout << "Reach here init 2!" << endl; while (true) { char* method = rmiObj->getMethodBytes(); - + cout << "Get method bytes here: " << endl; + IoTRMIUtil::printBytes(method, rmiObj->getMethodBytesLen(), false); + int objId = IoTRMIObject::getObjectId(method); + if (objId < vecCBObj.size()) { // Check if still within range + CallBack_CBSkeleton* skel = + dynamic_cast (vecCBObj.at(objId)); + cout << "Dynamic cast done!" << endl; + //rmiObj->setMethodBytes(method); + string type = ""; + cout << "About to execute invoke method!" << endl; + void* retObj = skel->invokeMethod(rmiObj, &type); + cout << "Executed invoke method!" << endl; + if (type != "void") { + rmiObj->sendReturnObj(retObj, type); + cout << "Sent return object!" << endl; + } + } else { + string error = "TestClass_Stub: Illegal object Id: " + to_string(objId); + throw error; + } } } +// Notify that callback thread is ready +void TestClass_Stub::____registerCallBack() { + + int numParam = 3; + string sign = "registercallback"; + string retType = "void"; + string paramCls[] = { "int", "string", "int" }; + int rev = 0; + void* paramObj[] = { &ports[0], &address, &rev }; + void* retObj = NULL; + cout << "Get here! 1" << endl; + rmiCall->remoteCall(objectId, sign, retType, paramCls, paramObj, numParam, retObj); + cout << "Get here! 2" << endl; +} + + void TestClass_Stub::setA(int _int) { int numParam = 1; @@ -192,7 +259,19 @@ void TestClass_Stub::registerCallback(CallBackInterface* _cb) { void TestClass_Stub::registerCallback(vector _cb) { - //Should implement the callback here for multiple callback objects + for (CallBackInterface* cb: _cb) { + CallBack_CBSkeleton* skel = new CallBack_CBSkeleton(cb, objIdCnt++); + vecCBObj.push_back(skel); + } + + int numParam = 1; + string sign = "voidregisterCallBack(CallBackInterface[])"; + string retType = "void"; + string paramCls[] = { "int" }; + int param1 = _cb.size(); + void* paramObj[] = { ¶m1 }; + void* retObj = NULL; + rmiCall->remoteCall(objectId, sign, retType, paramCls, paramObj, numParam, retObj); } @@ -209,3 +288,36 @@ int TestClass_Stub::callBack() { return retVal; } + +void TestClass_Stub::handleStruct(vector vecData) { + + int numParam = 1; + string sign = "structsize"; + string retType = "void"; + string paramCls[] = { "int" }; + int structsize = vecData.size(); + void* paramObj[] = { &structsize }; + void* retObj = NULL; + rmiCall->remoteCall(objectId, sign, retType, paramCls, paramObj, numParam, retObj); + + int numParam2 = 3*vecData.size(); + string sign2 = "handleStruct(StructJ[])"; + string retType2 = "void"; + string paramCls2[numParam2]; + void* paramObj2[numParam2]; + int pos = 0; + for(int i = 0; i < vecData.size(); i++) { + paramCls2[pos] = "string"; + paramObj2[pos] = &vecData[i].name; pos++; + paramCls2[pos] = "float"; + paramObj2[pos] = &vecData[i].value; pos++; + paramCls2[pos] = "int"; + paramObj2[pos] = &vecData[i].year; pos++; + } + void* retObj2 = NULL; + cout << "In handle struct 3!" << endl; + rmiCall->remoteCall(objectId, sign2, retType2, paramCls2, paramObj2, numParam2, retObj2); +} + + +#endif diff --git a/iotjava/iotrmi/Java/sample/StructJ.java b/iotjava/iotrmi/Java/sample/StructJ.java new file mode 100644 index 0000000..b1a0354 --- /dev/null +++ b/iotjava/iotrmi/Java/sample/StructJ.java @@ -0,0 +1,8 @@ +package iotrmi.Java.sample; + +public class StructJ { + + public static String name; + public static float value; + public static int year; +} diff --git a/iotjava/iotrmi/Java/sample/StructMain.java b/iotjava/iotrmi/Java/sample/StructMain.java new file mode 100644 index 0000000..3f4456c --- /dev/null +++ b/iotjava/iotrmi/Java/sample/StructMain.java @@ -0,0 +1,17 @@ +package iotrmi.Java.sample; + +public class StructMain { + + public static void main (String[] args) { + + StructJ data = new StructJ(); + data.name = "Rahmadi"; + data.value = 0.123f; + data.year = 2016; + + System.out.println("Name: " + data.name); + System.out.println("Value: " + data.value); + System.out.println("Year: " + data.year); + } +} + diff --git a/iotjava/iotrmi/Java/sample/TestClass.java b/iotjava/iotrmi/Java/sample/TestClass.java index 1c95b3a..a59518a 100644 --- a/iotjava/iotrmi/Java/sample/TestClass.java +++ b/iotjava/iotrmi/Java/sample/TestClass.java @@ -145,13 +145,22 @@ public class TestClass implements TestClassInterface { return sum; } + public void handleStruct(StructJ[] data) { + + for (StructJ str : data) { + System.out.println("Name: " + str.name); + System.out.println("Value: " + str.value); + System.out.println("Year: " + str.year); + } + } + public static void main(String[] args) { - TestClass tc = new TestClass(); - CallBack cb = new CallBack(3); + //TestClass tc = new TestClass(); + //CallBack cb = new CallBack(3); - tc.registerCallback(cb); - System.out.println("Return value: " + tc.callBack()); + //tc.registerCallback(cb); + //System.out.println("Return value: " + tc.callBack()); } } diff --git a/iotjava/iotrmi/Java/sample/TestClassInterface.java b/iotjava/iotrmi/Java/sample/TestClassInterface.java index b9c563a..9d46df5 100644 --- a/iotjava/iotrmi/Java/sample/TestClassInterface.java +++ b/iotjava/iotrmi/Java/sample/TestClassInterface.java @@ -13,4 +13,5 @@ public interface TestClassInterface { public void registerCallback(CallBackInterface _cb); public void registerCallback(CallBackInterface[] _cb); public int callBack(); + public void handleStruct(StructJ[] data); } diff --git a/iotjava/iotrmi/Java/sample/TestClass_CBSkeleton.java b/iotjava/iotrmi/Java/sample/TestClass_CBSkeleton.java index 10f136d..3435959 100644 --- a/iotjava/iotrmi/Java/sample/TestClass_CBSkeleton.java +++ b/iotjava/iotrmi/Java/sample/TestClass_CBSkeleton.java @@ -27,7 +27,8 @@ public class TestClass_CBSkeleton implements TestClassInterface { "intcallBack()", "voidregisterCallBack(CallBackInterface)", "voidregisterCallBack(CallBackInterface[])", - "registercallback" + "registercallback", + "handleStruct(StructJ)" }; private TestClassInterface tc; @@ -169,6 +170,11 @@ public class TestClass_CBSkeleton implements TestClassInterface { return tc.callBack(); } + public void handleStruct(StructJ[] data) { + + tc.handleStruct(data); + } + public static void main(String[] args) throws Exception { diff --git a/iotjava/iotrmi/Java/sample/TestClass_CBStub.java b/iotjava/iotrmi/Java/sample/TestClass_CBStub.java index 65550c7..a3d80fd 100644 --- a/iotjava/iotrmi/Java/sample/TestClass_CBStub.java +++ b/iotjava/iotrmi/Java/sample/TestClass_CBStub.java @@ -38,7 +38,8 @@ public class TestClass_CBStub implements TestClassInterface { "intcallBack()", "voidregisterCallBack(CallBackInterface)", "voidregisterCallBack(CallBackInterface[])", - "registercallback" + "registercallback", + "handleStruct(StructJ)" }; /** @@ -236,6 +237,10 @@ public class TestClass_CBStub implements TestClassInterface { } + public void handleStruct(StructJ[] data) { + + } + public static void main(String[] args) throws Exception { diff --git a/iotjava/iotrmi/Java/sample/TestClass_Skeleton.java b/iotjava/iotrmi/Java/sample/TestClass_Skeleton.java index acab4ac..a115615 100644 --- a/iotjava/iotrmi/Java/sample/TestClass_Skeleton.java +++ b/iotjava/iotrmi/Java/sample/TestClass_Skeleton.java @@ -27,7 +27,9 @@ public class TestClass_Skeleton implements TestClassInterface { "intcallBack()", "voidregisterCallBack(CallBackInterface)", "voidregisterCallBack(CallBackInterface[])", - "registercallback" + "registercallback", + "handleStruct(StructJ[])", + "structsize" }; private TestClassInterface tc; @@ -53,6 +55,8 @@ public class TestClass_Skeleton implements TestClassInterface { public void waitRequestInvokeMethod() throws IOException { + // Struct size + int structsize1 = 0; // Loop continuously waiting for incoming bytes while (true) { @@ -114,6 +118,40 @@ public class TestClass_Skeleton implements TestClassInterface { String[] methodSignatures = CallBack_CBStub.getMethodSignatures(); rmiCall = new IoTRMICall((int) paramObj[0], (String) paramObj[1], (int) paramObj[2], methodSignatures); System.out.println("Creating a new IoTRMICall object"); + // Struct handling (3 is the size of the struct) + } else if (methodSign.equals("structsize")) { + paramObj = rmiObj.getMethodParams(new Class[] { int.class }, + new Class[] { null }, new Class[] { null }); + structsize1 = (int) paramObj[0]; + } else if (methodSign.equals("handleStruct(StructJ[])")) { + Class[] paramCls = new Class[3*structsize1]; + Class[] paramClsTyp1 = new Class[3*structsize1]; + Class[] paramClsTyp2 = new Class[3*structsize1]; + int pos = 0; + for(int i=0; i < structsize1; i++) { + paramCls[pos] = String.class; + paramClsTyp1[pos] = null; + paramClsTyp2[pos++] = null; + paramCls[pos] = float.class; + paramClsTyp1[pos] = null; + paramClsTyp2[pos++] = null; + paramCls[pos] = int.class; + paramClsTyp1[pos] = null; + paramClsTyp2[pos++] = null; + } + paramObj = rmiObj.getMethodParams(paramCls, + paramClsTyp1, paramClsTyp2); + StructJ[] data = new StructJ[structsize1]; + for (int i=0; i < structsize1; i++) { + data[i] = new StructJ(); + } + pos = 0; + for(int i=0; i < structsize1; i++) { + data[i].name = (String) paramObj[pos++]; + data[i].value = (float) paramObj[pos++]; + data[i].year = (int) paramObj[pos++]; + } + tc.handleStruct(data); } else throw new Error("Signature not recognized!"); @@ -184,6 +222,11 @@ public class TestClass_Skeleton implements TestClassInterface { return tc.callBack(); } + public void handleStruct(StructJ[] data) { + + tc.handleStruct(data); + } + public static void main(String[] args) throws Exception { diff --git a/iotjava/iotrmi/Java/sample/TestClass_Stub.java b/iotjava/iotrmi/Java/sample/TestClass_Stub.java index 90e2264..43fcaf0 100644 --- a/iotjava/iotrmi/Java/sample/TestClass_Stub.java +++ b/iotjava/iotrmi/Java/sample/TestClass_Stub.java @@ -38,7 +38,9 @@ public class TestClass_Stub implements TestClassInterface { "intcallBack()", "voidregisterCallBack(CallBackInterface)", "voidregisterCallBack(CallBackInterface[])", - "registercallback" + "registercallback", + "handleStruct(StructJ[])", + "structsize" }; /** @@ -101,7 +103,7 @@ public class TestClass_Stub implements TestClassInterface { String sign = "registercallback"; // can be any string Class retType = void.class; - // port, address, rev, and number of objects + // port, address, rev Class[] paramCls = new Class[] { int.class, String.class, int.class }; Object[] paramObj = new Object[] { ports[0], address, 0 }; rmiCall.remoteCall(objectId, sign, retType, null, null, paramCls, paramObj); @@ -230,6 +232,34 @@ public class TestClass_Stub implements TestClassInterface { } + public void handleStruct(StructJ[] data) { + + String sign = "structsize"; + Class retType = void.class; + Class[] paramCls = new Class[] { int.class }; + Object[] paramObj = new Object[] { data.length }; + rmiCall.remoteCall(objectId, sign, retType, null, null, paramCls, paramObj); + + String sign2 = "handleStruct(StructJ[])"; + Class retType2 = void.class; + // Calculate the size of the array + Class[] paramCls2 = new Class[3*data.length]; + Object[] paramObj2 = new Object[3*data.length]; + // Handle with for loop + int pos = 0; + for(int i = 0; i < data.length; i++) { + paramCls2[pos] = String.class; + paramObj2[pos++] = data[i].name; + paramCls2[pos] = float.class; + paramObj2[pos++] = data[i].value; + paramCls2[pos] = int.class; + paramObj2[pos++] = data[i].year; + } + System.out.println(Arrays.toString(paramObj2)); + rmiCall.remoteCall(objectId, sign2, retType2, null, null, paramCls2, paramObj2); + } + + public static void main(String[] args) throws Exception { CommunicationHandler comHan = new CommunicationHandler(true); @@ -247,7 +277,7 @@ public class TestClass_Stub implements TestClassInterface { System.out.println("Return value: " + tcstub.setACAndGetA("string", 123)); System.out.println("Return value: " + tcstub.sumArray(new String[] { "123", "456", "987" })); - CallBackInterface cb1 = new CallBack(23); + /*CallBackInterface cb1 = new CallBack(23); CallBackInterface cb2 = new CallBack(33); CallBackInterface cb3 = new CallBack(43); CallBackInterface[] cb = { cb1, cb2, cb3 }; @@ -258,7 +288,26 @@ public class TestClass_Stub implements TestClassInterface { CallBackInterface cb6 = new CallBack(12); CallBackInterface[] cbt = { cb4, cb5, cb6 }; tcstub.registerCallback(cbt); - System.out.println("Return value from callback: " + tcstub.callBack()); + System.out.println("Return value from callback: " + tcstub.callBack());*/ + + StructJ[] data = new StructJ[2]; + for (int i=0; i<2; i++) { + data[i] = new StructJ(); + } + data[0].name = "Rahmadi"; + data[0].value = 0.123f; + data[0].year = 2016; + //data[1].name = "Trimananda"; + //data[1].value = 0.223f; + //data[1].year = 2017; + + for (StructJ str : data) { + System.out.println("Name: " + str.name); + System.out.println("Value: " + str.value); + System.out.println("Year: " + str.year); + } + + tcstub.handleStruct(data); } } -- 2.34.1