1 /** Class IoTRMICall provides methods that the upper
2 * layers can use to transport and invoke methods
3 * when using IoTSocket, IoTSocketClient and IoTSocketServer.
5 * This class serves in the stub part of the RMI
6 * communication. It bridges and creates RMI requests to be
7 * transferred into the RMI object.
9 * @author Rahmadi Trimananda <rtrimana @ uci.edu>
13 #ifndef _IOTRMICALL_HPP__
14 #define _IOTRMICALL_HPP__
19 #include "IoTRMIUtil.hpp"
20 #include "IoTSocketClient.hpp"
28 IoTRMICall(int _port, const char* _address, int _rev, bool* _bResult,
29 const string _methodSign[], const int _size);
32 int methodLength(string paramCls[], void* paramObj[], int numParam);
33 char* methodToBytes(int objectId, string methodSign, string paramCls[], void* paramObj[],
34 char* method, int numParam);
35 void* remoteCall(int objectId, string methodSign, string retType, string paramCls[],
36 void* paramObj[], int numParam, void* retObj);
39 map<string,int> mapSign2MethodId;
41 IoTSocketClient *rmiClient;
44 void getMethodIds(const string methodSign[], const int size);
49 IoTRMICall::IoTRMICall(int _port, const char* _address, int _rev, bool* _bResult, const string _methodSign[], const int _size) {
51 getMethodIds(_methodSign, _size);
52 rmiUtil = new IoTRMIUtil();
53 if (rmiUtil == NULL) {
54 perror("IoTRMICall: IoTRMIUtil isn't initialized!");
56 rmiClient = new IoTSocketClient(_port, _address, _rev, _bResult);
57 if (rmiClient == NULL) {
58 perror("IoTRMICall: IoTSocketClient isn't initialized!");
64 IoTRMICall::~IoTRMICall() {
67 if (rmiUtil != NULL) {
72 if (rmiClient != NULL) {
82 // Calls a method remotely by passing in parameters and getting a return object
83 void* IoTRMICall::remoteCall(int objectId, string methodSign, string retType, string paramCls[],
84 void* paramObj[], int numParam, void* retObj) {
86 // Critical section that is used by different objects
87 lock_guard<mutex> guard(mtx);
88 // Send input parameters
89 int len = methodLength(paramCls, paramObj, numParam);
91 cout << "Got in remoteCall!" << endl;
92 methodToBytes(objectId, methodSign, paramCls, paramObj, method, numParam);
93 cout << "Executed methodToBytes in remoteCall!" << endl;
94 IoTRMIUtil::printBytes(method, len, false);
97 rmiClient->sendBytes(method, len);
99 cout << "Got in remoteCall! 2" << endl;
100 // Receive return value and return it to caller
101 if (retType.compare("void") == 0)
102 // Just make it NULL if it's a void return
106 char* retObjBytes = NULL;
107 retObjBytes = rmiClient->receiveBytes(retObjBytes, &retLen);
108 IoTRMIUtil::printBytes(retObjBytes, retLen, false);
109 retObj = IoTRMIUtil::getParamObject(retObj, retType.c_str(), retObjBytes, retLen);
116 // Find the bytes length of a method
117 int IoTRMICall::methodLength(string paramCls[], void* paramObj[], int numParam) {
119 // Get byte arrays and calculate method bytes length
120 // Start from the object Id + method Id...
121 int methodLen = IoTRMIUtil::OBJECT_ID_LEN + IoTRMIUtil::METHOD_ID_LEN;
122 for (int i = 0; i < numParam; i++) {
123 // Find the parameter length
124 int paramLen = rmiUtil->getTypeSize(paramCls[i]);
125 if (paramLen == -1) { // Store the length of the field - indefinite length
126 paramLen = rmiUtil->getVarTypeSize(paramCls[i], paramObj[i]);
127 // Some space for param length, i.e. 32 bits for integer
128 methodLen = methodLen + IoTRMIUtil::PARAM_LEN;
130 // Calculate methodLen
131 methodLen = methodLen + paramLen;
138 // Convert method and its parameters into bytes
139 char* IoTRMICall::methodToBytes(int objectId, string methodSign, string paramCls[],
140 void* paramObj[], char* method, int numParam) {
142 // Get object Id in bytes
143 char objId[IoTRMIUtil::OBJECT_ID_LEN];
144 IoTRMIUtil::intToByteArray(objectId, objId);
145 memcpy(method, objId, IoTRMIUtil::OBJECT_ID_LEN);
146 int pos = IoTRMIUtil::OBJECT_ID_LEN;
147 // Get method Id in bytes
148 char methodId[IoTRMIUtil::METHOD_ID_LEN];
149 int methId = mapSign2MethodId.find(methodSign)->second;
150 IoTRMIUtil::intToByteArray(methId, methodId);
151 memcpy(method + pos, methodId, IoTRMIUtil::METHOD_ID_LEN);
152 pos = pos + IoTRMIUtil::METHOD_ID_LEN;
153 // Get byte arrays and calculate method bytes length
154 for (int i = 0; i < numParam; i++) {
155 // Find the parameter length
156 int paramLen = rmiUtil->getTypeSize(paramCls[i]);
157 if (paramLen == -1) { // Store the length of the field - indefinite length
158 paramLen = rmiUtil->getVarTypeSize(paramCls[i], paramObj[i]);
159 // Write the parameter length
160 char prmLenBytes[IoTRMIUtil::METHOD_ID_LEN];
161 IoTRMIUtil::intToByteArray(paramLen, prmLenBytes);
162 memcpy(method + pos, prmLenBytes, IoTRMIUtil::PARAM_LEN);
163 pos = pos + IoTRMIUtil::PARAM_LEN;
165 // Get array of bytes and put it in the array of array of bytes
166 char objBytes[paramLen];
167 IoTRMIUtil::getObjectBytes(objBytes, paramObj[i], paramCls[i].c_str());
168 memcpy(method + pos, objBytes, paramLen);
169 pos = pos + paramLen;
179 void IoTRMICall::getMethodIds(const string methodSign[], const int size) {
181 for(int i = 0; i < size; i++) {
182 mapSign2MethodId[methodSign[i]] = i;