1 /** Class IoTRMIObject 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 skeleton part of the RMI
6 * communication. It instatiate an RMI object and activate
7 * a server process that handles RMI requests.
9 * @author Rahmadi Trimananda <rtrimana @ uci.edu>
13 #ifndef _IOTRMIOBJECT_HPP__
14 #define _IOTRMIOBJECT_HPP__
18 #include "IoTRMIUtil.hpp"
19 #include "IoTSocketServer.hpp"
25 IoTRMIObject(int _port, bool* _bResult);
28 void sendReturnObj(void* retObj, string type);
29 void sendReturnObj(void* retObj[], string type[], int numRet);
30 int returnLength(void* retObj[], string retCls[], int numRet);
31 char* returnToBytes(void* retObj[], string retCls[], char* retBytes, int numRet);
32 char* getMethodBytes();
33 int getMethodBytesLen();
34 void setMethodBytes(char* _methodBytes);
36 static int getObjectId(char* methodBytes);
38 static int getMethodId(char* methodBytes);
39 void** getMethodParams(string paramCls[], int numParam, void* paramObj[]);
43 IoTSocketServer *rmiServer;
48 void getMethodIds(const string methodSign[], const int size);
53 IoTRMIObject::IoTRMIObject(int _port, bool* _bResult) {
55 rmiUtil = new IoTRMIUtil();
56 if (rmiUtil == NULL) {
57 perror("IoTRMIObject: IoTRMIUtil isn't initialized!");
63 rmiServer = new IoTSocketServer(_port, _bResult);
64 if (rmiServer == NULL) {
65 perror("IoTRMIObject: IoTSocketServer isn't initialized!");
75 IoTRMIObject::~IoTRMIObject() {
78 if (rmiUtil != NULL) {
83 if (rmiServer != NULL) {
93 // Send return values in bytes to the caller
94 void IoTRMIObject::sendReturnObj(void* retObj, string type) {
96 // Find the length of return object in bytes
97 int retLen = rmiUtil->getTypeSize(type);
99 retLen = rmiUtil->getVarTypeSize(type, retObj);
101 // Need object bytes variable
102 char retObjBytes[retLen];
103 IoTRMIUtil::getObjectBytes(retObjBytes, retObj, type.c_str());
104 rmiServer->sendBytes(retObjBytes, retLen);
108 // Send return values in bytes to the caller (for more than one object - struct)
109 void IoTRMIObject::sendReturnObj(void* retObj[], string type[], int numRet) {
111 // Find the length of return object in bytes
112 int retLen = returnLength(retObj, type, numRet);
113 // Need object bytes variable
114 char retObjBytes[retLen];
115 returnToBytes(retObj, type, retObjBytes, numRet);
116 rmiServer->sendBytes(retObjBytes, retLen);
120 // Get method bytes from the socket
121 char* IoTRMIObject::getMethodBytes() {
123 // Get method in bytes and update method length
125 methodBytes = rmiServer->receiveBytes(methodBytes, &methodLen);
131 // Get method bytes length
132 int IoTRMIObject::getMethodBytesLen() {
138 // Get object Id from bytes
139 int IoTRMIObject::getObjectId() {
141 char objectIdBytes[IoTRMIUtil::OBJECT_ID_LEN];
142 memcpy(objectIdBytes, methodBytes, IoTRMIUtil::OBJECT_ID_LEN);
143 // Get method signature
145 IoTRMIUtil::byteArrayToInt(&objectId, objectIdBytes);
151 // Get object Id from bytes (static version)
152 int IoTRMIObject::getObjectId(char* methodBytes) {
154 char objectIdBytes[IoTRMIUtil::OBJECT_ID_LEN];
155 memcpy(objectIdBytes, methodBytes, IoTRMIUtil::OBJECT_ID_LEN);
156 // Get method signature
158 IoTRMIUtil::byteArrayToInt(&objectId, objectIdBytes);
165 int IoTRMIObject::getMethodId() {
168 char methodIdBytes[IoTRMIUtil::METHOD_ID_LEN];
169 memcpy(methodIdBytes, methodBytes + IoTRMIUtil::OBJECT_ID_LEN, IoTRMIUtil::METHOD_ID_LEN);
170 // Get method signature
172 IoTRMIUtil::byteArrayToInt(&methodId, methodIdBytes);
178 // Get methodId from bytes (static version)
179 int IoTRMIObject::getMethodId(char* methodBytes) {
182 char methodIdBytes[IoTRMIUtil::METHOD_ID_LEN];
183 memcpy(methodIdBytes, methodBytes + IoTRMIUtil::OBJECT_ID_LEN, IoTRMIUtil::METHOD_ID_LEN);
184 // Get method signature
186 IoTRMIUtil::byteArrayToInt(&methodId, methodIdBytes);
192 // Get method parameters and return an array of parameter objects
194 // For primitive objects:
195 // | 32-bit method ID | m-bit actual data (fixed length) |
197 // For string, arrays, and non-primitive objects:
198 // | 32-bit method ID | 32-bit length | n-bit actual data | ...
199 void** IoTRMIObject::getMethodParams(string paramCls[], int numParam, void* paramObj[]) {
201 // Byte scanning position
202 int pos = IoTRMIUtil::OBJECT_ID_LEN + IoTRMIUtil::METHOD_ID_LEN;
203 for (int i = 0; i < numParam; i++) {
204 int paramLen = rmiUtil->getTypeSize(paramCls[i]);
205 // Get the 32-bit field in the byte array to get the actual
206 // length (this is a param with indefinite length)
207 if (paramLen == -1) {
208 char bytPrmLen[IoTRMIUtil::PARAM_LEN];
209 memcpy(bytPrmLen, methodBytes + pos, IoTRMIUtil::PARAM_LEN);
210 pos = pos + IoTRMIUtil::PARAM_LEN;
211 int* prmLenPtr = IoTRMIUtil::byteArrayToInt(¶mLen, bytPrmLen);
212 paramLen = *prmLenPtr;
214 char paramBytes[paramLen];
215 memcpy(paramBytes, methodBytes + pos, paramLen);
216 pos = pos + paramLen;
217 paramObj[i] = IoTRMIUtil::getParamObject(paramObj[i], paramCls[i].c_str(), paramBytes, paramLen);
219 // Delete methodBytes
220 delete[] methodBytes;
226 // Find the bytes length of a return object (struct that has more than 1 member)
227 int IoTRMIObject::returnLength(void* retObj[], string retCls[], int numRet) {
229 // Get byte arrays and calculate return bytes length
231 for (int i = 0; i < numRet; i++) {
232 // Find the return length
233 int retObjLen = rmiUtil->getTypeSize(retCls[i]);
234 if (retObjLen == -1) { // Store the length of the field - indefinite length
235 retObjLen = rmiUtil->getVarTypeSize(retCls[i], retObj[i]);
236 // Some space for return length, i.e. 32 bits for integer
237 returnLen = returnLen + IoTRMIUtil::RETURN_LEN;
239 // Calculate returnLen
240 returnLen = returnLen + retObjLen;
247 // Convert return object (struct members) into bytes
248 char* IoTRMIObject::returnToBytes(void* retObj[], string retCls[], char* retBytes, int numRet) {
251 // Get byte arrays and calculate return bytes length
252 for (int i = 0; i < numRet; i++) {
253 // Find the return length
254 int retObjLen = rmiUtil->getTypeSize(retCls[i]);
255 if (retObjLen == -1) { // Store the length of the field - indefinite length
256 retObjLen = rmiUtil->getVarTypeSize(retCls[i], retObj[i]);
257 // Write the return length
258 char retLenBytes[IoTRMIUtil::RETURN_LEN];
259 IoTRMIUtil::intToByteArray(retObjLen, retLenBytes);
260 memcpy(retBytes + pos, retLenBytes, IoTRMIUtil::RETURN_LEN);
261 pos = pos + IoTRMIUtil::RETURN_LEN;
263 // Get array of bytes and put it in the array of array of bytes
264 char objBytes[retObjLen];
265 IoTRMIUtil::getObjectBytes(objBytes, retObj[i], retCls[i].c_str());
266 memcpy(retBytes + pos, objBytes, retObjLen);
267 pos = pos + retObjLen;