1 /** Class IoTRMICommServer implements the server side
4 * @author Rahmadi Trimananda <rtrimana @ uci.edu>
8 #ifndef _IOTRMICOMMSERVER_HPP__
9 #define _IOTRMICOMMSERVER_HPP__
18 #include "IoTRMIComm.hpp"
23 class IoTRMICommServer : public IoTRMIComm {
25 IoTRMICommServer(int _portSend, int _portRecv, bool* _bResult);
28 void sendReturnObj(void* retObj, string type, char* methodBytes);
29 void sendReturnObj(void* retObj[], string type[], int numRet, char* methodBytes);
30 void remoteCall(int objectId, int methodId, string paramCls[], void* paramObj[], int numParam);
33 IoTSocketServer *rmiServerSend;
34 IoTSocketServer *rmiServerRecv;
37 void waitForConnectionOnServerRecv();
38 void waitForConnectionOnServerSend();
39 void waitForPackets(IoTRMICommServer* rmiComm);
44 IoTRMICommServer::IoTRMICommServer(int _portSend, int _portRecv, bool* _bResult) : IoTRMIComm() {
46 rmiServerSend = new IoTSocketServer(_portSend, _bResult);
47 rmiServerRecv = new IoTSocketServer(_portRecv, _bResult);
48 thread th1 (&IoTRMICommServer::waitForConnectionOnServerSend, this);
49 thread th2 (&IoTRMICommServer::waitForConnectionOnServerRecv, this);
52 thread th3 (&IoTRMICommServer::waitForPackets, this, this);
58 IoTRMICommServer::~IoTRMICommServer() {
61 if (rmiServerSend != NULL) {
65 if (rmiServerRecv != NULL) {
72 void IoTRMICommServer::waitForConnectionOnServerRecv() {
74 cout << "Wait on connection ServerRecv!" << endl;
75 rmiServerRecv->connect();
76 cout << "Connected on connection ServerRecv!" << endl;
80 void IoTRMICommServer::waitForConnectionOnServerSend() {
82 cout << "Wait on connection ServerSend!" << endl;
83 rmiServerSend->connect();
84 cout << "Connected on connection ServerSend!" << endl;
88 void IoTRMICommServer::waitForPackets(IoTRMICommServer* rmiComm) {
90 char* packetBytes = NULL;
92 //cout << "Starting waitForPacketsOnServer()" << endl;
95 packetBytes = rmiComm->rmiServerRecv->receiveBytes(packetBytes, &packetLen);
97 if (packetBytes != NULL) { // If there is method bytes
98 //IoTRMIUtil::printBytes(packetBytes, packetLen, false);
99 int packetType = IoTRMIComm::getPacketType(packetBytes);
100 if (packetType == IoTRMIUtil::METHOD_TYPE) {
101 rmiComm->methodQueue.enqueue(packetBytes, packetLen);
102 } else if (packetType == IoTRMIUtil::RET_VAL_TYPE) {
103 rmiComm->returnQueue.enqueue(packetBytes, packetLen);
105 // TODO: We need to log error message when we come to running this using IoTSlave
106 // TODO: Beware that using "cout" in the process will kill it (as IoTSlave is loaded in Sentinel)
107 cerr << "IoTRMICommServer: Packet type is unknown: " << packetType << endl;
117 // Send return values in bytes to the caller
118 void IoTRMICommServer::sendReturnObj(void* retObj, string type, char* methodBytes) {
120 // Critical section that is used by different objects
121 lock_guard<mutex> guard(sendReturnObjMutex);
122 // Find the length of return object in bytes
123 int retLen = rmiUtil->getTypeSize(type);
125 retLen = rmiUtil->getVarTypeSize(type, retObj);
127 // Copy the header and object bytes
128 int objAndMethIdLen = IoTRMIUtil::OBJECT_ID_LEN + IoTRMIUtil::METHOD_ID_LEN;
129 int headerLen = objAndMethIdLen + IoTRMIUtil::PACKET_TYPE_LEN;
130 char retAllObjBytes[headerLen+retLen];
131 // Copy object and method Id first
132 memcpy(retAllObjBytes, methodBytes, objAndMethIdLen);
133 // Copy objectId + methodId + packet type in bytes
134 char packType[IoTRMIUtil::PACKET_TYPE_LEN];
135 IoTRMIUtil::intToByteArray(IoTRMIUtil::RET_VAL_TYPE, packType);
136 memcpy(retAllObjBytes + objAndMethIdLen, packType, IoTRMIUtil::PACKET_TYPE_LEN);
137 // Copy object into byte array
138 char retObjBytes[retLen];
139 IoTRMIUtil::getObjectBytes(retObjBytes, retObj, type.c_str());
140 memcpy(retAllObjBytes + headerLen, retObjBytes, retLen);
142 IoTRMIUtil::printBytes(retAllObjBytes, headerLen+retLen, false);
143 rmiServerSend->sendBytes(retAllObjBytes, headerLen+retLen);
148 // Send return values in bytes to the caller (for more than one object - struct)
149 void IoTRMICommServer::sendReturnObj(void* retObj[], string type[], int numRet, char* methodBytes) {
151 // Critical section that is used by different objects
152 lock_guard<mutex> guard(sendReturnObjMutex);
153 // Find the length of return object in bytes
154 int retLen = returnLength(retObj, type, numRet);
155 // Copy the header and object bytes
156 int objAndMethIdLen = IoTRMIUtil::OBJECT_ID_LEN + IoTRMIUtil::METHOD_ID_LEN;
157 int headerLen = objAndMethIdLen + IoTRMIUtil::PACKET_TYPE_LEN;
158 char retAllObjBytes[headerLen+retLen];
159 // Copy object and method Id first
160 memcpy(retAllObjBytes, methodBytes, objAndMethIdLen);
161 // Copy objectId + methodId + packet type in bytes
162 char packType[IoTRMIUtil::PACKET_TYPE_LEN];
163 IoTRMIUtil::intToByteArray(IoTRMIUtil::RET_VAL_TYPE, packType);
164 memcpy(retAllObjBytes + objAndMethIdLen, packType, IoTRMIUtil::PACKET_TYPE_LEN);
165 // Copy object into byte array
166 char retObjBytes[retLen];
167 returnToBytes(retObj, type, retObjBytes, numRet);
168 memcpy(retAllObjBytes + headerLen, retObjBytes, retLen);
170 rmiServerSend->sendBytes(retAllObjBytes, headerLen+retLen);
175 // Calls a method remotely by passing in parameters and getting a return object
176 void IoTRMICommServer::remoteCall(int objectId, int methodId, string paramCls[],
177 void* paramObj[], int numParam) {
179 // Critical section that is used by different objects
180 lock_guard<mutex> guard(remoteCallMutex);
181 // Send input parameters
182 int len = methodLength(paramCls, paramObj, numParam);
184 methodToBytes(objectId, methodId, paramCls, paramObj, method, numParam);
187 rmiServerSend->sendBytes(method, len);