mutex mtx;
-class IoTRMICall {
+class IoTRMICall final {
public:
- IoTRMICall(int _port, const char* _address, int _rev, bool* _bResult,
- const string _methodSign[], const int _size);
+ IoTRMICall(int _port, const char* _address, int _rev, bool* _bResult);
~IoTRMICall();
// Public methods
int methodLength(string paramCls[], void* paramObj[], int numParam);
- char* methodToBytes(int objectId, string methodSign, string paramCls[], void* paramObj[],
+ char* methodToBytes(int objectId, int methId, string paramCls[], void* paramObj[],
char* method, int numParam);
- void* remoteCall(int objectId, string methodSign, string retType, string paramCls[],
+ void* remoteCall(int objectId, int methodId, string retType, string paramCls[],
void* paramObj[], int numParam, void* retObj);
+ void** getStructObjects(string retType[], int numRet, void* retObj[]);
+ void** getReturnObjects(char* retBytes, string retCls[], int numRet, void* retObj[]);
private:
- map<string,int> mapSign2MethodId;
IoTRMIUtil *rmiUtil;
IoTSocketClient *rmiClient;
// Constructor
-IoTRMICall::IoTRMICall(int _port, const char* _address, int _rev, bool* _bResult, const string _methodSign[], const int _size) {
+IoTRMICall::IoTRMICall(int _port, const char* _address, int _rev, bool* _bResult) {
- getMethodIds(_methodSign, _size);
rmiUtil = new IoTRMIUtil();
if (rmiUtil == NULL) {
perror("IoTRMICall: IoTRMIUtil isn't initialized!");
// Calls a method remotely by passing in parameters and getting a return object
-void* IoTRMICall::remoteCall(int objectId, string methodSign, string retType, string paramCls[],
+void* IoTRMICall::remoteCall(int objectId, int methodId, string retType, string paramCls[],
void* paramObj[], int numParam, void* retObj) {
// Critical section that is used by different objects
// Send input parameters
int len = methodLength(paramCls, paramObj, numParam);
char method[len];
- cout << "Got in remoteCall!" << endl;
- methodToBytes(objectId, methodSign, paramCls, paramObj, method, numParam);
- cout << "Executed methodToBytes in remoteCall!" << endl;
- IoTRMIUtil::printBytes(method, len, false);
+ methodToBytes(objectId, methodId, paramCls, paramObj, method, numParam);
// Send bytes
fflush(NULL);
rmiClient->sendBytes(method, len);
fflush(NULL);
- cout << "Got in remoteCall! 2" << endl;
// Receive return value and return it to caller
if (retType.compare("void") == 0)
// Just make it NULL if it's a void return
int retLen = 0;
char* retObjBytes = NULL;
retObjBytes = rmiClient->receiveBytes(retObjBytes, &retLen);
- IoTRMIUtil::printBytes(retObjBytes, retLen, false);
retObj = IoTRMIUtil::getParamObject(retObj, retType.c_str(), retObjBytes, retLen);
+ // Delete received bytes object
+ delete[] retObjBytes;
}
return retObj;
}
+// Get a set of return objects (struct)
+void** IoTRMICall::getStructObjects(string retType[], int numRet, void* retObj[]) {
+
+ // Critical section that is used by different objects
+ lock_guard<mutex> guard(mtx);
+ // Receive struct return value and return it to caller
+ int retLen = 0;
+ char* retObjBytes = NULL;
+ // Return size of array of struct
+ retObjBytes = rmiClient->receiveBytes(retObjBytes, &retLen);
+ retObj = getReturnObjects(retObjBytes, retType, numRet, retObj);
+ // Delete received bytes object
+ delete[] retObjBytes;
+
+ return retObj;
+}
+
+
// Find the bytes length of a method
int IoTRMICall::methodLength(string paramCls[], void* paramObj[], int numParam) {
// Calculate methodLen
methodLen = methodLen + paramLen;
}
-
return methodLen;
}
// Convert method and its parameters into bytes
-char* IoTRMICall::methodToBytes(int objectId, string methodSign, string paramCls[],
+char* IoTRMICall::methodToBytes(int objectId, int methId, string paramCls[],
void* paramObj[], char* method, int numParam) {
// Get object Id in bytes
int pos = IoTRMIUtil::OBJECT_ID_LEN;
// Get method Id in bytes
char methodId[IoTRMIUtil::METHOD_ID_LEN];
- int methId = mapSign2MethodId.find(methodSign)->second;
IoTRMIUtil::intToByteArray(methId, methodId);
memcpy(method + pos, methodId, IoTRMIUtil::METHOD_ID_LEN);
pos = pos + IoTRMIUtil::METHOD_ID_LEN;
if (paramLen == -1) { // Store the length of the field - indefinite length
paramLen = rmiUtil->getVarTypeSize(paramCls[i], paramObj[i]);
// Write the parameter length
- char prmLenBytes[IoTRMIUtil::METHOD_ID_LEN];
+ char prmLenBytes[IoTRMIUtil::PARAM_LEN];
IoTRMIUtil::intToByteArray(paramLen, prmLenBytes);
memcpy(method + pos, prmLenBytes, IoTRMIUtil::PARAM_LEN);
pos = pos + IoTRMIUtil::PARAM_LEN;
}
-// *************
-// Helpers
-// *************
-void IoTRMICall::getMethodIds(const string methodSign[], const int size) {
-
- for(int i = 0; i < size; i++) {
- mapSign2MethodId[methodSign[i]] = i;
+void** IoTRMICall::getReturnObjects(char* retBytes, string retCls[], int numRet, void* retObj[]) {
+
+ // Byte scanning position
+ int pos = 0;
+ for (int i = 0; i < numRet; i++) {
+ int retLen = rmiUtil->getTypeSize(retCls[i]);
+ // Get the 32-bit field in the byte array to get the actual
+ // length (this is a param with indefinite length)
+ if (retLen == -1) {
+ char bytRetLen[IoTRMIUtil::RETURN_LEN];
+ memcpy(bytRetLen, retBytes + pos, IoTRMIUtil::RETURN_LEN);
+ pos = pos + IoTRMIUtil::RETURN_LEN;
+ int* retLenPtr = IoTRMIUtil::byteArrayToInt(&retLen, bytRetLen);
+ retLen = *retLenPtr;
+ }
+ char retObjBytes[retLen];
+ memcpy(retObjBytes, retBytes + pos, retLen);
+ pos = pos + retLen;
+ retObj[i] = IoTRMIUtil::getParamObject(retObj[i], retCls[i].c_str(), retObjBytes, retLen);
}
-}
+ return retObj;
+}
#endif