1 /** Class IoTRMICommClient implements the client side
4 * @author Rahmadi Trimananda <rtrimana @ uci.edu>
8 #ifndef _IOTRMICOMMCLIENT_HPP__
9 #define _IOTRMICOMMCLIENT_HPP__
18 #include "IoTRMIComm.hpp"
22 mutex clientRemoteCallMutex;
23 mutex clientSendReturnObjMutex;
25 class IoTRMICommClient final : public IoTRMIComm {
27 IoTRMICommClient(int _portSend, int _portRecv, const char* _address, int _rev, bool* _bResult);
30 void sendReturnObj(void* retObj, string type, char* methodBytes);
31 void sendReturnObj(void* retObj[], string type[], int numRet, char* methodBytes);
32 void remoteCall(int objectId, int methodId, string paramCls[], void* paramObj[], int numParam);
35 IoTSocketClient *rmiClientSend;
36 IoTSocketClient *rmiClientRecv;
39 void waitForPackets(IoTRMICommClient* rmiComm);
44 IoTRMICommClient::IoTRMICommClient(int _portSend, int _portRecv, const char* _address, int _rev, bool* _bResult) : IoTRMIComm() {
46 rmiClientRecv = new IoTSocketClient(_portSend, _address, _rev, _bResult);
47 rmiClientSend = new IoTSocketClient(_portRecv, _address, _rev, _bResult);
48 thread th1 (&IoTRMICommClient::waitForPackets, this, this);
54 IoTRMICommClient::~IoTRMICommClient() {
57 if (rmiClientRecv != NULL) {
61 if (rmiClientSend != NULL) {
68 void IoTRMICommClient::waitForPackets(IoTRMICommClient* rmiComm) {
70 char* packetBytes = NULL;
74 packetBytes = rmiClientRecv->receiveBytes(packetBytes, &packetLen);
76 if (packetBytes != NULL) { // If there is method bytes
77 int packetType = getPacketType(packetBytes);
78 if (packetType == IoTRMIUtil::METHOD_TYPE) {
79 rmiComm->methodQueue.enqueue(packetBytes, packetLen);
80 } else if (packetType == IoTRMIUtil::RET_VAL_TYPE) {
81 rmiComm->returnQueue.enqueue(packetBytes, packetLen);
83 // TODO: We need to log error message when we come to running this using IoTSlave
84 // TODO: Beware that using "cout" in the process will kill it (as IoTSlave is loaded at runtime)
85 cerr << "IoTRMICommClient: Packet type is unknown: " << packetType << endl;
95 // Send return values in bytes to the caller
96 void IoTRMICommClient::sendReturnObj(void* retObj, string type, char* methodBytes) {
98 // Critical section that is used by different objects
99 lock_guard<mutex> guard(sendReturnObjMutex);
100 // Find the length of return object in bytes
101 int retLen = rmiUtil->getTypeSize(type);
103 retLen = rmiUtil->getVarTypeSize(type, retObj);
105 // Copy the header and object bytes
106 int objAndMethIdLen = IoTRMIUtil::OBJECT_ID_LEN + IoTRMIUtil::METHOD_ID_LEN;
107 int headerLen = objAndMethIdLen + IoTRMIUtil::PACKET_TYPE_LEN;
108 char retAllObjBytes[headerLen+retLen];
109 // Copy object and method Id first
110 memcpy(retAllObjBytes, methodBytes, objAndMethIdLen);
111 // Copy objectId + methodId + packet type in bytes
112 char packType[IoTRMIUtil::PACKET_TYPE_LEN];
113 IoTRMIUtil::intToByteArray(IoTRMIUtil::RET_VAL_TYPE, packType);
114 memcpy(retAllObjBytes + objAndMethIdLen, packType, IoTRMIUtil::PACKET_TYPE_LEN);
115 // Copy object into byte array
116 char retObjBytes[retLen];
117 IoTRMIUtil::getObjectBytes(retObjBytes, retObj, type.c_str());
118 memcpy(retAllObjBytes + headerLen, retObjBytes, retLen);
120 rmiClientSend->sendBytes(retAllObjBytes, headerLen+retLen);
125 // Send return values in bytes to the caller (for more than one object - struct)
126 void IoTRMICommClient::sendReturnObj(void* retObj[], string type[], int numRet, char* methodBytes) {
128 // Critical section that is used by different objects
129 lock_guard<mutex> guard(sendReturnObjMutex);
130 // Find the length of return object in bytes
131 int retLen = returnLength(retObj, type, numRet);
132 // Copy the header and object bytes
133 int objAndMethIdLen = IoTRMIUtil::OBJECT_ID_LEN + IoTRMIUtil::METHOD_ID_LEN;
134 int headerLen = objAndMethIdLen + IoTRMIUtil::PACKET_TYPE_LEN;
135 char retAllObjBytes[headerLen+retLen];
136 // Copy object and method Id first
137 memcpy(retAllObjBytes, methodBytes, objAndMethIdLen);
138 // Copy objectId + methodId + packet type in bytes
139 char packType[IoTRMIUtil::PACKET_TYPE_LEN];
140 IoTRMIUtil::intToByteArray(IoTRMIUtil::RET_VAL_TYPE, packType);
141 memcpy(retAllObjBytes + objAndMethIdLen, packType, IoTRMIUtil::PACKET_TYPE_LEN);
142 // Copy object into byte array
143 char retObjBytes[retLen];
144 returnToBytes(retObj, type, retObjBytes, numRet);
145 memcpy(retAllObjBytes + headerLen, retObjBytes, retLen);
147 rmiClientSend->sendBytes(retAllObjBytes, headerLen+retLen);
152 // Calls a method remotely by passing in parameters and getting a return object
153 void IoTRMICommClient::remoteCall(int objectId, int methodId, string paramCls[],
154 void* paramObj[], int numParam) {
156 // Critical section that is used by different objects
157 lock_guard<mutex> guard(remoteCallMutex);
158 // Send input parameters
159 int len = methodLength(paramCls, paramObj, numParam);
161 methodToBytes(objectId, methodId, paramCls, paramObj, method, numParam);
164 rmiClientSend->sendBytes(method, len);