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, const string _methodSign[], const int _size);
28 void sendReturnObj(void* retObj, string type);
29 char* getMethodBytes();
30 int getMethodBytesLen();
31 void setMethodBytes(char* _methodBytes);
33 static int getObjectId(char* methodBytes);
34 string getSignature();
35 void** getMethodParams(string paramCls[], int numParam, void* paramObj[]);
38 map<int,string> mapMethodId2Sign;
40 IoTSocketServer *rmiServer;
45 void getMethodIds(const string methodSign[], const int size);
50 IoTRMIObject::IoTRMIObject(int _port, bool* _bResult, const string _methodSign[], const int _size) {
52 rmiUtil = new IoTRMIUtil();
53 if (rmiUtil == NULL) {
54 perror("IoTRMIObject: IoTRMIUtil isn't initialized!");
59 getMethodIds(_methodSign, _size);
61 rmiServer = new IoTSocketServer(_port, _bResult);
62 if (rmiServer == NULL) {
63 perror("IoTRMIObject: IoTSocketServer isn't initialized!");
72 IoTRMIObject::~IoTRMIObject() {
75 if (rmiUtil != NULL) {
80 if (rmiServer != NULL) {
90 // Send return values in bytes to the caller
91 void IoTRMIObject::sendReturnObj(void* retObj, string type) {
93 // Find the length of return object in bytes
94 int retLen = rmiUtil->getTypeSize(type);
96 retLen = rmiUtil->getVarTypeSize(type, retObj);
98 // Need object bytes variable
99 char retObjBytes[retLen];
100 IoTRMIUtil::getObjectBytes(retObjBytes, retObj, type.c_str());
101 rmiServer->sendBytes(retObjBytes, retLen);
105 // Get method bytes from the socket
106 char* IoTRMIObject::getMethodBytes() {
108 // Get method in bytes and update method length
109 cout << "Got into getMethodBytes()" << endl;
111 methodBytes = rmiServer->receiveBytes(methodBytes, &methodLen);
112 cout << "Got into getMethodBytes() 2" << endl;
118 // Get method bytes length
119 int IoTRMIObject::getMethodBytesLen() {
125 // Get object Id from bytes
126 int IoTRMIObject::getObjectId() {
128 char objectIdBytes[IoTRMIUtil::OBJECT_ID_LEN];
129 memcpy(objectIdBytes, methodBytes, IoTRMIUtil::OBJECT_ID_LEN);
130 // Get method signature
132 IoTRMIUtil::byteArrayToInt(&objectId, objectIdBytes);
138 // Get object Id from bytes (static version)
139 int IoTRMIObject::getObjectId(char* methodBytes) {
141 char objectIdBytes[IoTRMIUtil::OBJECT_ID_LEN];
142 memcpy(objectIdBytes, methodBytes, IoTRMIUtil::OBJECT_ID_LEN);
143 // Get method signature
145 IoTRMIUtil::byteArrayToInt(&objectId, objectIdBytes);
152 void IoTRMIObject::setMethodBytes(char* _methodBytes) {
155 methodBytes = _methodBytes;
159 // Get signature from the method-Id-to-method-signature map
160 string IoTRMIObject::getSignature() {
163 char methodIdBytes[IoTRMIUtil::METHOD_ID_LEN];
164 memcpy(methodIdBytes, methodBytes + IoTRMIUtil::OBJECT_ID_LEN, IoTRMIUtil::METHOD_ID_LEN);
165 // Get method signature
167 IoTRMIUtil::byteArrayToInt(&methodId, methodIdBytes);
169 return mapMethodId2Sign.find(methodId)->second;
173 // Get method parameters and return an array of parameter objects
175 // For primitive objects:
176 // | 32-bit method ID | m-bit actual data (fixed length) |
178 // For string, arrays, and non-primitive objects:
179 // | 32-bit method ID | 32-bit length | n-bit actual data | ...
180 void** IoTRMIObject::getMethodParams(string paramCls[], int numParam, void* paramObj[]) {
182 // Byte scanning position
183 int pos = IoTRMIUtil::OBJECT_ID_LEN + IoTRMIUtil::METHOD_ID_LEN;
184 for (int i = 0; i < numParam; i++) {
185 int paramLen = rmiUtil->getTypeSize(paramCls[i]);
186 // Get the 32-bit field in the byte array to get the actual
187 // length (this is a param with indefinite length)
188 if (paramLen == -1) {
189 char bytPrmLen[IoTRMIUtil::PARAM_LEN];
190 memcpy(bytPrmLen, methodBytes + pos, IoTRMIUtil::PARAM_LEN);
191 pos = pos + IoTRMIUtil::PARAM_LEN;
192 int* prmLenPtr = IoTRMIUtil::byteArrayToInt(¶mLen, bytPrmLen);
193 paramLen = *prmLenPtr;
195 char paramBytes[paramLen];
196 memcpy(paramBytes, methodBytes + pos, paramLen);
197 pos = pos + paramLen;
198 paramObj[i] = IoTRMIUtil::getParamObject(paramObj[i], paramCls[i].c_str(), paramBytes, paramLen);
200 // Delete methodBytes
201 delete[] methodBytes;
210 void IoTRMIObject::getMethodIds(const string methodSign[], const int size) {
212 for(int i = 0; i < size; i++) {
213 mapMethodId2Sign[i] = methodSign[i];