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__
18 #include "IoTRMIUtil.hpp"
19 #include "IoTSocketClient.hpp"
25 IoTRMICall(int _port, const char* _address, int _rev, bool* _bResult, string _methodSign[], int _size);
28 int methodLength(string paramCls[], void* paramObj[], int numParam);
29 char* methodToBytes(string methodSign, string paramCls[], void* paramObj[],
30 char* method, int numParam);
31 void* remoteCall(string methodSign, string retType, string paramCls[],
32 void* paramObj[], int numParam, void* retObj);
35 map<string,int> mapSign2MethodId;
37 IoTSocketClient *rmiClient;
40 void getMethodIds(string methodSign[], int size);
45 IoTRMICall::IoTRMICall(int _port, const char* _address, int _rev, bool* _bResult, string _methodSign[], int _size) {
47 getMethodIds(_methodSign, _size);
48 rmiUtil = new IoTRMIUtil();
49 if (rmiUtil == NULL) {
50 perror("IoTRMICall: IoTRMIUtil isn't initialized!");
52 rmiClient = new IoTSocketClient(_port, _address, _rev, _bResult);
53 if (rmiClient == NULL) {
54 perror("IoTRMICall: IoTSocketClient isn't initialized!");
60 IoTRMICall::~IoTRMICall() {
63 if (rmiUtil != NULL) {
68 if (rmiClient != NULL) {
78 // Calls a method remotely by passing in parameters and getting a return object
79 void* IoTRMICall::remoteCall(string methodSign, string retType, string paramCls[],
80 void* paramObj[], int numParam, void* retObj) {
82 // Send input parameters
83 int len = methodLength(paramCls, paramObj, numParam);
85 methodToBytes(methodSign, paramCls, paramObj, method, numParam);
88 rmiClient->sendBytes(method, len);
90 // Receive return value and return it to caller
91 if (retType.compare("void") == 0)
92 // Just make it NULL if it's a void return
96 char* retObjBytes = NULL;
97 retObjBytes = rmiClient->receiveBytes(retObjBytes, &retLen);
98 IoTRMIUtil::printBytes(retObjBytes, retLen, false);
99 retObj = IoTRMIUtil::getParamObject(retObj, retType.c_str(), retObjBytes, retLen);
106 // Find the bytes length of a method
107 int IoTRMICall::methodLength(string paramCls[], void* paramObj[], int numParam) {
109 // Get byte arrays and calculate method bytes length
110 // Start from the method Id...
111 int methodLen = IoTRMIUtil::METHOD_ID_LEN;
112 for (int i = 0; i < numParam; i++) {
113 // Find the parameter length
114 int paramLen = rmiUtil->getTypeSize(paramCls[i]);
115 if (paramLen == -1) { // Store the length of the field - indefinite length
116 paramLen = rmiUtil->getVarTypeSize(paramCls[i], paramObj[i]);
117 // Some space for param length, i.e. 32 bits for integer
118 methodLen = methodLen + IoTRMIUtil::PARAM_LEN;
120 // Calculate methodLen
121 methodLen = methodLen + paramLen;
128 // Convert method and its parameters into bytes
129 char* IoTRMICall::methodToBytes(string methodSign, string paramCls[],
130 void* paramObj[], char* method, int numParam) {
132 // Get method ID in bytes
133 char methodId[IoTRMIUtil::METHOD_ID_LEN];
134 int methId = mapSign2MethodId.find(methodSign)->second;
135 IoTRMIUtil::intToByteArray(methId, methodId);
136 memcpy(method, methodId, IoTRMIUtil::METHOD_ID_LEN);
137 int pos = IoTRMIUtil::METHOD_ID_LEN;
138 // Get byte arrays and calculate method bytes length
139 for (int i = 0; i < numParam; i++) {
140 // Find the parameter length
141 int paramLen = rmiUtil->getTypeSize(paramCls[i]);
142 if (paramLen == -1) { // Store the length of the field - indefinite length
143 paramLen = rmiUtil->getVarTypeSize(paramCls[i], paramObj[i]);
144 // Write the parameter length
145 char prmLenBytes[IoTRMIUtil::METHOD_ID_LEN];
146 IoTRMIUtil::intToByteArray(paramLen, prmLenBytes);
147 memcpy(method + pos, prmLenBytes, IoTRMIUtil::PARAM_LEN);
148 pos = pos + IoTRMIUtil::PARAM_LEN;
150 // Get array of bytes and put it in the array of array of bytes
151 char objBytes[paramLen];
152 IoTRMIUtil::getObjectBytes(objBytes, paramObj[i], paramCls[i].c_str());
153 memcpy(method + pos, objBytes, paramLen);
154 pos = pos + paramLen;
164 void IoTRMICall::getMethodIds(string methodSign[], int size) {
166 for(int i = 0; i < size; i++) {
167 mapSign2MethodId[methodSign[i]] = i;