Tested C++ RPS/RMI libraries for arbitrary objects and arbitrary remote calls
[iot2.git] / iotjava / iotrmi / C++ / basics / TestClassInterface_Skeleton.cpp
index 0ad75869f1436ca13846c5badae0fca7c810ab0b..65524f76eb52e7152c8ffd7f0ae0dc7abe2e7862 100644 (file)
@@ -7,32 +7,30 @@
 
 using namespace std;
 
-TestClassInterface_Skeleton::TestClassInterface_Skeleton(TestClassInterface *_mainObj, string _callbackAddress, int _port) {
+TestClassInterface_Skeleton::TestClassInterface_Skeleton(TestClassInterface *_mainObj, int _portSend, int _portRecv) {
        bool _bResult = false;
        mainObj = _mainObj;
-       callbackAddress = _callbackAddress;
-       rmiObj = new IoTRMIObject(_port, &_bResult);
-       set0Allowed.insert(-9999);
-       ___waitRequestInvokeMethod();
+       rmiComm = new IoTRMICommServer(_portSend, _portRecv, &_bResult);
+       IoTRMIUtil::mapSkel->insert(make_pair(_mainObj, this));
+       IoTRMIUtil::mapSkelId->insert(make_pair(_mainObj, objectId));
+       rmiComm->registerSkeleton(objectId, &methodReceived);
+       thread th1 (&TestClassInterface_Skeleton::___waitRequestInvokeMethod, this, this);
+//     th1.detach();
+       th1.join();
 }
 
-TestClassInterface_Skeleton::TestClassInterface_Skeleton(TestClassInterface *_mainObj, int _objIdCnt, string _callbackAddress) {
+TestClassInterface_Skeleton::TestClassInterface_Skeleton(TestClassInterface *_mainObj, IoTRMIComm *_rmiComm, int _objectId) {
        bool _bResult = false;
        mainObj = _mainObj;
-       objIdCnt = _objIdCnt;
-       callbackAddress = _callbackAddress;
-       set0Allowed.insert(-9999);
-       ___waitRequestInvokeMethod();
+       rmiComm = _rmiComm;
+       objectId = _objectId;
+       rmiComm->registerSkeleton(objectId, &methodReceived);
 }
 
 TestClassInterface_Skeleton::~TestClassInterface_Skeleton() {
-       if (rmiObj != NULL) {
-               delete rmiObj;
-               rmiObj = NULL;
-       }
-       if (rmiCall != NULL) {
-               delete rmiCall;
-               rmiCall = NULL;
+       if (rmiComm != NULL) {
+               delete rmiComm;
+               rmiComm = NULL;
        }
        for(CallBackInterfaceWithCallBack* cb : vecCallbackObj) {
                delete cb;
@@ -40,6 +38,11 @@ TestClassInterface_Skeleton::~TestClassInterface_Skeleton() {
        }
 }
 
+bool TestClassInterface_Skeleton::didInitWaitInvoke() {
+
+       return didAlreadyInitWaitInvoke;
+}
+
 short TestClassInterface_Skeleton::getShort(short in) {
        return mainObj->getShort(in);
 }
@@ -48,84 +51,112 @@ void TestClassInterface_Skeleton::registerCallback(CallBackInterfaceWithCallBack
        mainObj->registerCallback(_cb);
 }
 
-void TestClassInterface_Skeleton::___regCB() {
-       int numParam = 3;
-       vector<int> param1;
-       string param2 = "";
-       int param3 = 0;
-       string paramCls[] = { "int*", "String", "int" };
-       void* paramObj[] = { &param1, &param2, &param3 };
-       rmiObj->getMethodParams(paramCls, numParam, paramObj);
-       bool bResult = false;
-       rmiCall = new IoTRMICall(param1[1], param2.c_str(), param3, &bResult);
-}
-
 int TestClassInterface_Skeleton::callBack() {
        return mainObj->callBack();
 }
 
-void TestClassInterface_Skeleton::___getShort() {
+void TestClassInterface_Skeleton::___getShort(TestClassInterface_Skeleton* skel) {
+       char* localMethodBytes = new char[methodLen];
+       memcpy(localMethodBytes, skel->methodBytes, methodLen);
+       //cout << "Bytes inside getShort: " << endl;
+       //IoTRMIUtil::printBytes(localMethodBytes, methodLen, false);
+       didGetMethodBytes.exchange(true);
        string paramCls[] = { "short" };
        int numParam = 1;
        short in;
        void* paramObj[] = { &in };
-       rmiObj->getMethodParams(paramCls, numParam, paramObj);
+       skel->rmiComm->getMethodParams(paramCls, numParam, paramObj, localMethodBytes);
        short retVal = getShort(in);
+       cout << "Getting return value getShort(): " << retVal << endl;
        void* retObj = &retVal;
-       rmiObj->sendReturnObj(retObj, "short");
+       skel->rmiComm->sendReturnObj(retObj, "short", localMethodBytes);
+       cout << "Sent return value for getShort()" << endl;
+       delete[] localMethodBytes;
 }
 
-void TestClassInterface_Skeleton::___registerCallback() {
+void TestClassInterface_Skeleton::___registerCallback(TestClassInterface_Skeleton* skel) {
+       char* localMethodBytes = new char[methodLen];
+       memcpy(localMethodBytes, skel->methodBytes, methodLen);
+       didGetMethodBytes.exchange(true);
        string paramCls[] = { "int" };
        int numParam = 1;
        int numStubs0 = 0;
        void* paramObj[] = { &numStubs0 };
-       rmiObj->getMethodParams(paramCls, numParam, paramObj);
-       //CallBackInterfaceWithCallBack* stub0 = new CallBackInterfaceWithCallBack_CallbackStub(rmiCall, callbackAddress, objIdCnt, ports);
-       CallBackInterfaceWithCallBack* stub0 = new CallBackInterfaceWithCallBack_Stub(rmiCall, callbackAddress, objIdCnt, ports);
-       vecCallbackObj.push_back(stub0);
-       objIdCnt++;
-       registerCallback(stub0);
+       skel->rmiComm->getMethodParams(paramCls, numParam, paramObj, localMethodBytes);
+       // Choosing the right stub
+       int objIdRecv = numStubs0;
+       CallBackInterfaceWithCallBack* stub0 = NULL;
+       auto it = IoTRMIUtil::mapStub->find(objIdRecv);
+       if (it == IoTRMIUtil::mapStub->end()) { // Not in the map, so new object
+               stub0 = new CallBackInterfaceWithCallBack_Stub(rmiComm, objIdRecv);
+               IoTRMIUtil::mapStub->insert(make_pair(objIdRecv, stub0));
+               cout << "Create new stub for Callback! ID=" << objIdRecv << endl;
+               rmiComm->setObjectIdCounter(objIdRecv);
+               rmiComm->decrementObjectIdCounter();
+       } else {
+               stub0 = (CallBackInterfaceWithCallBack_Stub*) it->second;
+               cout << "Stub exists for Callback! ID=" << objIdRecv << endl;
+       }
+       skel->vecCallbackObj.push_back(stub0);
+       skel->registerCallback(stub0);
+       delete[] localMethodBytes;
 }
 
-void TestClassInterface_Skeleton::___callBack() {
+void TestClassInterface_Skeleton::___callBack(TestClassInterface_Skeleton* skel) {
+       char* localMethodBytes = new char[methodLen];
+       memcpy(localMethodBytes, skel->methodBytes, methodLen);
+       didGetMethodBytes.exchange(true);
        string paramCls[] = {  };
        int numParam = 0;
        void* paramObj[] = {  };
-       rmiObj->getMethodParams(paramCls, numParam, paramObj);
+       skel->rmiComm->getMethodParams(paramCls, numParam, paramObj, localMethodBytes);
        int retVal = callBack();
        void* retObj = &retVal;
-       rmiObj->sendReturnObj(retObj, "int");
+       skel->rmiComm->sendReturnObj(retObj, "int", localMethodBytes);
+       delete[] localMethodBytes;
 }
 
-void TestClassInterface_Skeleton::___waitRequestInvokeMethod() {
+void TestClassInterface_Skeleton::___waitRequestInvokeMethod(TestClassInterface_Skeleton* skel) {
+       cout << "Running loop!" << endl;
+       //didAlreadyInitWaitInvoke.exchange(true);
+       skel->didAlreadyInitWaitInvoke = true;
        while (true) {
-               rmiObj->getMethodBytes();
-               int _objectId = rmiObj->getObjectId();
-               int methodId = rmiObj->getMethodId();
-               if (_objectId == object0Id) {
-                       if (set0Allowed.find(methodId) == set0Allowed.end()) {
+               if (!methodReceived)
+                       continue;
+               skel->methodBytes = skel->rmiComm->getMethodBytes();
+               skel->methodLen = skel->rmiComm->getMethodLength();
+               cout << endl;
+               // TODO: Get method length as well!!!
+               //methodReceived.exchange(false);
+               methodReceived = false;
+               int _objectId = skel->rmiComm->getObjectId(skel->methodBytes);
+               int methodId = skel->rmiComm->getMethodId(skel->methodBytes);
+               if (_objectId == objectId) {
+                       if (skel->set0Allowed.find(methodId) == skel->set0Allowed.end()) {
                                cerr << "Object with object Id: " << _objectId << "  is not allowed to access method: " << methodId << endl;
                                return;
                        }
                }
-               else {
-                       cerr << "Object Id: " << _objectId << " not recognized!" << endl;
-                       return;
-               }
+               else
+                       continue;
                switch (methodId) {
-                       case 0: ___getShort(); break;
-                       case 1: ___registerCallback(); break;
-                       case 2: ___callBack(); break;
-                       case -9999: ___regCB(); break;
+                       case 0: { thread th0 (&TestClassInterface_Skeleton::___getShort, std::ref(skel), skel); th0.detach(); break; }
+                                       //___getShort(skel); break;
+                       case 1: { thread th1 (&TestClassInterface_Skeleton::___registerCallback, std::ref(skel), skel); th1.detach(); break; }
+                                       //___registerCallback(skel); break;
+                       case 2: { thread th2 (&TestClassInterface_Skeleton::___callBack, std::ref(skel), skel); th2.detach(); break; }
+                                       //___callBack(skel); break;
                        default: 
                        cerr << "Method Id " << methodId << " not recognized!" << endl;
-                       throw exception();
+                       //throw exception();
+                       return;
                }
+               cout << "Out of switch statement!" << endl;
        }
 }
 
 
+
 int main(int argc, char *argv[])
 {
        // First argument is port number
@@ -139,10 +170,11 @@ int main(int argc, char *argv[])
        cout << argv3 << endl;
        cout << argv4 << endl;*/
 
-       int port = 5010;
+       int portSend = 5000;
+       int portRecv = 6000;
        //TestClassInterface *tc = new TestClass(argv2, argv3, argv4);
        TestClassInterface *tc = new TestClass(123, 2.345, "test");
-       TestClassInterface_Skeleton *tcSkel = new TestClassInterface_Skeleton(tc, "localhost", port);
+       TestClassInterface_Skeleton *tcSkel = new TestClassInterface_Skeleton(tc, portSend, portRecv);
 
        //delete tc;
        //delete tcSkel;