Tested C++ RPS/RMI libraries for arbitrary objects and arbitrary remote calls
[iot2.git] / iotjava / iotrmi / C++ / basics / TestClassComplete_Stub.cpp
1 #include <iostream>
2 #include <string>
3 #include "TestClassComplete_Stub.hpp"
4 #include "CallBack.hpp"
5
6 #include "CallBackInterface_Skeleton.cpp"
7
8 using namespace std;
9
10
11 TestClassComplete_Stub::TestClassComplete_Stub(int _portSend, int _portRecv, const char* _skeletonAddress, int _rev, bool* _bResult) {
12         rmiComm = new IoTRMICommClient(_portSend, _portRecv, _skeletonAddress, _rev, _bResult);
13         rmiComm->registerStub(objectId, 0, &retValueReceived0);
14         rmiComm->registerStub(objectId, 2, &retValueReceived2);
15         IoTRMIUtil::mapStub->insert(make_pair(objectId, this));
16 }
17
18 TestClassComplete_Stub::TestClassComplete_Stub(IoTRMIComm* _rmiComm, int _objectId) {
19         rmiComm = _rmiComm;
20         objectId = _objectId;
21         rmiComm->registerStub(objectId, 0, &retValueReceived0);
22         rmiComm->registerStub(objectId, 2, &retValueReceived2);
23 }
24
25 TestClassComplete_Stub::~TestClassComplete_Stub() {
26         if (rmiComm != NULL) {
27                 delete rmiComm;
28                 rmiComm = NULL;
29         }
30         for(CallBackInterface* cb : vecCallbackObj) {
31                 delete cb;
32                 cb = NULL;
33         }
34 }
35
36 mutex mtxMethodExec1;   // TODO: We probably need to correlate this always with class name, e.g. methodExecCallBackInterfaceWithCallBack
37 void TestClassComplete_Stub::registerCallback(CallBackInterface* _cb) { 
38         lock_guard<mutex> guard(mtxMethodExec1);
39         int objIdSent = 0;
40         auto it = IoTRMIUtil::mapSkel->find(_cb);
41         if (it == IoTRMIUtil::mapSkel->end()) { // Not in the map, so new object
42                 objIdSent = rmiComm->getObjectIdCounter();
43                 rmiComm->decrementObjectIdCounter();
44                 CallBackInterface_Skeleton* skel0 = new CallBackInterface_Skeleton(_cb, rmiComm, objIdSent);
45                 vecCallbackObj.push_back(skel0);
46                 IoTRMIUtil::mapSkel->insert(make_pair(_cb, skel0));
47                 IoTRMIUtil::mapSkelId->insert(make_pair(_cb, objIdSent));
48                 cout << "Create new skeleton for TestClass! ID=" << objIdSent << endl;
49                 //thread th0 (&CallBackInterface_Skeleton::___waitRequestInvokeMethod, std::ref(skel0));
50                 thread th0 (&CallBackInterface_Skeleton::___waitRequestInvokeMethod, std::ref(skel0), std::ref(skel0));  
51                 th0.detach();
52                 //while(!didAlreadyInitWaitInvoke);
53                 while(!skel0->didInitWaitInvoke());
54         } else {
55                 auto itId = IoTRMIUtil::mapSkelId->find(_cb);
56                 objIdSent = itId->second;
57                 cout << "Skeleton exists for TestClass! ID=" << objIdSent << endl;
58         }
59
60         //int ___paramCB0 = 1;
61         int ___paramCB0 = objIdSent;
62         int methodId = 1;
63         string retType = "void";
64         int numParam = 1;
65         string paramCls[] = { "int" };
66         void* paramObj[] = { &___paramCB0 };
67         void* retObj = NULL;
68         rmiComm->remoteCall(objectId, methodId, paramCls, paramObj, numParam);
69 }
70
71 mutex mtxMethodExec0;   // TODO: We probably need to correlate this always with class name, e.g. methodExecCallBackInterfaceWithCallBack
72 short TestClassComplete_Stub::getShort(short in) {
73         lock_guard<mutex> guard(mtxMethodExec0);
74         cout << "getShort() is called!!!" << endl << endl;
75         int methodId = 0;
76         string retType = "short";
77         int numParam = 1;
78         string paramCls[] = { "short" };
79         void* paramObj[] = { &in };
80         short retVal = 0;
81         void* retObj = &retVal;
82         cout << "Calling remote call!" << endl;
83         rmiComm->remoteCall(objectId, methodId, paramCls, paramObj, numParam);
84         cout << "Finished calling remote call!" << endl;
85         // Waiting for return value
86         while(!retValueReceived0);
87         rmiComm->getReturnValue(retType, retObj);
88         //retValueReceived0.exchange(false);
89         retValueReceived0 = false;
90         didGetReturnBytes.exchange(true);
91         cout << "Getting return value for getShort(): " << retVal << endl;
92
93         return retVal;
94 }
95
96 mutex mtxMethodExec2;   // TODO: We probably need to correlate this always with class name, e.g. methodExecCallBackInterfaceWithCallBack
97 int TestClassComplete_Stub::callBack() {
98         lock_guard<mutex> guard(mtxMethodExec2);
99         int methodId = 2;
100         string retType = "int";
101         int numParam = 0;
102         string paramCls[] = {  };
103         void* paramObj[] = {  };
104         int retVal = 0;
105         void* retObj = &retVal;
106         rmiComm->remoteCall(objectId, methodId, paramCls, paramObj, numParam);
107         // Waiting for return value
108         while(!retValueReceived2);
109         rmiComm->getReturnValue(retType, retObj);
110         //retValueReceived2.exchange(false);
111         retValueReceived2 = false;
112         didGetReturnBytes.exchange(true);
113
114         cout << "Getting return value for callback(): " << retVal << endl;
115
116         return retVal;
117 }
118
119
120 int main(int argc, char *argv[])
121 {
122
123         int portSend = 5000;
124         int portRecv = 6000;
125         const char* address = "localhost";
126         //const char* address = "192.168.2.191";        // RPi2
127         //const char* skeletonAddress = "128.195.136.170";      // dc-9.calit2.uci.edu
128         const char* skeletonAddress = "128.195.204.132";
129         const char* callbackAddress = "128.195.204.132";        // dw-2.eecs.uci.edu (this machine)
130         //const char* skeletonAddress = "192.168.2.108";        // RPi1
131         //const char* callbackAddress = "192.168.2.191";        // RPi2
132         int rev = 0;
133         bool bResult = false;
134         //vector<int> ports;
135         //ports.push_back(12345);
136         //ports.push_back(22346);
137         //ports.push_back(32344);
138         //ports.push_back(43212);
139
140         TestClassComplete *tcStub = new TestClassComplete_Stub(portSend, portRecv, skeletonAddress, rev, &bResult);
141         //cout << "Getting return value from getShort(): " << tcStub->getShort(1234) << endl;
142         //cout << "Getting return value from getShort(): " << tcStub->getShort(4321) << endl;
143         //cout << "Getting return value from getShort(): " << tcStub->getShort(5678) << endl;
144         cout << "==== CALLBACK ====" << endl;
145         CallBackInterface *cbSingle = new CallBack(2354);
146         tcStub->registerCallback(cbSingle);
147         //tcStub->registerCallback(cbSingle);
148         CallBackInterface *cbSingle1 = new CallBack(2646);
149         tcStub->registerCallback(cbSingle1);
150         CallBackInterface *cbSingle2 = new CallBack(2000);
151         tcStub->registerCallback(cbSingle2);
152         cout << "Return value from callback: " << tcStub->callBack() << endl;
153         //cout << "Return value from callback: " << tcStub->callBack() << endl;
154
155         // TODO: we need this while loop at the end to keep the threads running
156         while(true);
157
158         return 0;
159 }