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);
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);
36 IoTSocketClient *rmiClient;
41 IoTRMICall::IoTRMICall(int _port, const char* _address, int _rev, bool* _bResult) {
43 rmiUtil = new IoTRMIUtil();
44 if (rmiUtil == NULL) {
45 perror("IoTRMICall: IoTRMIUtil isn't initialized!");
47 rmiClient = new IoTSocketClient(_port, _address, _rev, _bResult);
48 if (rmiClient == NULL) {
49 perror("IoTRMICall: IoTSocketClient isn't initialized!");
55 IoTRMICall::~IoTRMICall() {
58 if (rmiUtil != NULL) {
63 if (rmiClient != NULL) {
73 // Calls a method remotely by passing in parameters and getting a return object
74 void* IoTRMICall::remoteCall(string methodSign, string retType, string paramCls[],
75 void* paramObj[], int numParam, void* retObj) {
77 // Send input parameters
78 int len = methodLength(paramCls, paramObj, numParam);
80 methodToBytes(methodSign, paramCls, paramObj, method, numParam);
83 rmiClient->sendBytes(method, len);
85 // Receive return value and return it to caller
86 if (retType.compare("void") == 0)
87 // Just make it NULL if it's a void return
91 char* retObjBytes = NULL;
92 retObjBytes = rmiClient->receiveBytes(retObjBytes, &retLen);
93 retObj = IoTRMIUtil::getParamObject(retObj, retType.c_str(), retObjBytes, retLen);
100 // Find the bytes length of a method
101 int IoTRMICall::methodLength(string paramCls[], void* paramObj[], int numParam) {
103 // Get byte arrays and calculate method bytes length
104 // Start from the method Id...
105 int methodLen = IoTRMIUtil::METHOD_ID_LEN;
106 for (int i = 0; i < numParam; i++) {
107 // Find the parameter length
108 int paramLen = rmiUtil->getTypeSize(paramCls[i]);
109 if (paramLen == -1) { // Store the length of the field - indefinite length
110 if (paramCls[i].compare("string") == 0) {
111 // Get the length of the string through void* casting to string*
112 paramLen = (*(string*)paramObj[i]).length();
113 } else if (paramCls[i].compare("string[]") == 0) {
114 paramLen = IoTRMIUtil::getByteStringLength(*(vector<string>*) paramObj[i]);
116 string error = "IoTRMICall: Unrecognizable type: " + paramCls[i];
119 // Some space for param length, i.e. 32 bits for integer
120 methodLen = methodLen + IoTRMIUtil::PARAM_LEN;
122 // Calculate methodLen
123 methodLen = methodLen + paramLen;
130 // Convert method and its parameters into bytes
131 char* IoTRMICall::methodToBytes(string methodSign, string paramCls[],
132 void* paramObj[], char* method, int numParam) {
134 // Get method ID in bytes
135 char methodId[IoTRMIUtil::METHOD_ID_LEN];
136 IoTRMIUtil::getHashCodeBytes(methodSign, methodId);
137 memcpy(method, methodId, IoTRMIUtil::METHOD_ID_LEN);
138 int pos = IoTRMIUtil::METHOD_ID_LEN;
139 // Get byte arrays and calculate method bytes length
140 for (int i = 0; i < numParam; i++) {
141 // Find the parameter length
142 int paramLen = rmiUtil->getTypeSize(paramCls[i]);
143 if (paramLen == -1) { // Store the length of the field - indefinite length
144 if (paramCls[i].compare("string") == 0) {
145 // Get the length of the string through void* casting to string*
146 paramLen = (*(string*)paramObj[i]).length();
147 } else if (paramCls[i].compare("string[]") == 0) {
148 paramLen = IoTRMIUtil::getByteStringLength(*(vector<string>*) paramObj[i]);
150 string error = "IoTRMICall: Unrecognizable type: " + paramCls[i];
153 // Write the parameter length
154 char prmLenBytes[IoTRMIUtil::METHOD_ID_LEN];
155 IoTRMIUtil::intToByteArray(paramLen, prmLenBytes);
156 memcpy(method + pos, prmLenBytes, IoTRMIUtil::PARAM_LEN);
157 pos = pos + IoTRMIUtil::PARAM_LEN;
159 // Get array of bytes and put it in the array of array of bytes
160 char objBytes[paramLen];
161 IoTRMIUtil::getObjectBytes(objBytes, paramObj[i], paramCls[i].c_str());
162 memcpy(method + pos, objBytes, paramLen);
163 pos = pos + paramLen;