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 : 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);
33 //void waitForPackets();
34 //void waitForPackets(IoTRMICommClient* rmiComm);
37 IoTSocketClient *rmiClientSend;
38 IoTSocketClient *rmiClientRecv;
41 void waitForPackets(IoTRMICommClient* rmiComm);
46 IoTRMICommClient::IoTRMICommClient(int _portSend, int _portRecv, const char* _address, int _rev, bool* _bResult) : IoTRMIComm() {
48 rmiClientRecv = new IoTSocketClient(_portSend, _address, _rev, _bResult);
49 rmiClientSend = new IoTSocketClient(_portRecv, _address, _rev, _bResult);
50 thread th1 (&IoTRMICommClient::waitForPackets, this, this);
57 IoTRMICommClient::~IoTRMICommClient() {
60 if (rmiClientRecv != NULL) {
64 if (rmiClientSend != NULL) {
71 void IoTRMICommClient::waitForPackets(IoTRMICommClient* rmiComm) {
73 char* packetBytes = NULL;
77 packetBytes = rmiClientRecv->receiveBytes(packetBytes, &packetLen);
79 if (packetBytes != NULL) { // If there is method bytes
80 //IoTRMIUtil::printBytes(packetBytes, packetLen, false);
81 //packetBytesPtr = &packetBytes;
82 int packetType = getPacketType(packetBytes);
83 if (packetType == IoTRMIUtil::METHOD_TYPE) {
84 rmiComm->methodQueue.enqueue(packetBytes, packetLen);
85 } else if (packetType == IoTRMIUtil::RET_VAL_TYPE) {
86 rmiComm->returnQueue.enqueue(packetBytes, packetLen);
88 // TODO: We need to log error message when we come to running this using IoTSlave
89 // TODO: Beware that using "cout" in the process will kill it (as IoTSlave is loaded in Sentinel)
90 cerr << "IoTRMICommClient: Packet type is unknown: " << packetType << endl;
100 // Send return values in bytes to the caller
101 void IoTRMICommClient::sendReturnObj(void* retObj, string type, char* methodBytes) {
103 // Critical section that is used by different objects
104 lock_guard<mutex> guard(sendReturnObjMutex);
105 // Find the length of return object in bytes
106 int retLen = rmiUtil->getTypeSize(type);
108 retLen = rmiUtil->getVarTypeSize(type, retObj);
110 // Copy the header and object bytes
111 int objAndMethIdLen = IoTRMIUtil::OBJECT_ID_LEN + IoTRMIUtil::METHOD_ID_LEN;
112 int headerLen = objAndMethIdLen + IoTRMIUtil::PACKET_TYPE_LEN;
113 char retAllObjBytes[headerLen+retLen];
114 // Copy object and method Id first
115 memcpy(retAllObjBytes, methodBytes, objAndMethIdLen);
116 // Copy objectId + methodId + packet type in bytes
117 char packType[IoTRMIUtil::PACKET_TYPE_LEN];
118 IoTRMIUtil::intToByteArray(IoTRMIUtil::RET_VAL_TYPE, packType);
119 memcpy(retAllObjBytes + objAndMethIdLen, packType, IoTRMIUtil::PACKET_TYPE_LEN);
120 // Copy object into byte array
121 char retObjBytes[retLen];
122 IoTRMIUtil::getObjectBytes(retObjBytes, retObj, type.c_str());
123 memcpy(retAllObjBytes + headerLen, retObjBytes, retLen);
125 rmiClientSend->sendBytes(retAllObjBytes, headerLen+retLen);
130 // Send return values in bytes to the caller (for more than one object - struct)
131 void IoTRMICommClient::sendReturnObj(void* retObj[], string type[], int numRet, char* methodBytes) {
133 // Critical section that is used by different objects
134 lock_guard<mutex> guard(sendReturnObjMutex);
135 // Find the length of return object in bytes
136 int retLen = returnLength(retObj, type, numRet);
137 // Copy the header and object bytes
138 int objAndMethIdLen = IoTRMIUtil::OBJECT_ID_LEN + IoTRMIUtil::METHOD_ID_LEN;
139 int headerLen = objAndMethIdLen + IoTRMIUtil::PACKET_TYPE_LEN;
140 char retAllObjBytes[headerLen+retLen];
141 // Copy object and method Id first
142 memcpy(retAllObjBytes, methodBytes, objAndMethIdLen);
143 // Copy objectId + methodId + packet type in bytes
144 char packType[IoTRMIUtil::PACKET_TYPE_LEN];
145 IoTRMIUtil::intToByteArray(IoTRMIUtil::RET_VAL_TYPE, packType);
146 memcpy(retAllObjBytes + objAndMethIdLen, packType, IoTRMIUtil::PACKET_TYPE_LEN);
147 // Copy object into byte array
148 char retObjBytes[retLen];
149 returnToBytes(retObj, type, retObjBytes, numRet);
150 memcpy(retAllObjBytes + headerLen, retObjBytes, retLen);
152 rmiClientSend->sendBytes(retAllObjBytes, headerLen+retLen);
157 // Calls a method remotely by passing in parameters and getting a return object
158 void IoTRMICommClient::remoteCall(int objectId, int methodId, string paramCls[],
159 void* paramObj[], int numParam) {
161 // Critical section that is used by different objects
162 lock_guard<mutex> guard(remoteCallMutex);
163 // Send input parameters
164 int len = methodLength(paramCls, paramObj, numParam);
166 methodToBytes(objectId, methodId, paramCls, paramObj, method, numParam);
169 rmiClientSend->sendBytes(method, len);