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 final : 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 rmiServerRecv->connect();
78 void IoTRMICommServer::waitForConnectionOnServerSend() {
80 rmiServerSend->connect();
84 void IoTRMICommServer::waitForPackets(IoTRMICommServer* rmiComm) {
86 char* packetBytes = NULL;
90 packetBytes = rmiComm->rmiServerRecv->receiveBytes(packetBytes, &packetLen);
92 if (packetBytes != NULL) { // If there is method bytes
93 int packetType = IoTRMIComm::getPacketType(packetBytes);
94 if (packetType == IoTRMIUtil::METHOD_TYPE) {
95 rmiComm->methodQueue.enqueue(packetBytes, packetLen);
96 } else if (packetType == IoTRMIUtil::RET_VAL_TYPE) {
97 rmiComm->returnQueue.enqueue(packetBytes, packetLen);
99 // TODO: We need to log error message when we come to running this using IoTSlave
100 // TODO: Beware that using "cout" in the process will kill it (as IoTSlave is loaded at runtime)
101 cerr << "IoTRMICommServer: Packet type is unknown: " << packetType << endl;
111 // Send return values in bytes to the caller
112 void IoTRMICommServer::sendReturnObj(void* retObj, string type, char* methodBytes) {
114 // Critical section that is used by different objects
115 lock_guard<mutex> guard(sendReturnObjMutex);
116 // Find the length of return object in bytes
117 int retLen = rmiUtil->getTypeSize(type);
119 retLen = rmiUtil->getVarTypeSize(type, retObj);
121 // Copy the header and object bytes
122 int objAndMethIdLen = IoTRMIUtil::OBJECT_ID_LEN + IoTRMIUtil::METHOD_ID_LEN;
123 int headerLen = objAndMethIdLen + IoTRMIUtil::PACKET_TYPE_LEN;
124 char retAllObjBytes[headerLen+retLen];
125 // Copy object and method Id first
126 memcpy(retAllObjBytes, methodBytes, objAndMethIdLen);
127 // Copy objectId + methodId + packet type in bytes
128 char packType[IoTRMIUtil::PACKET_TYPE_LEN];
129 IoTRMIUtil::intToByteArray(IoTRMIUtil::RET_VAL_TYPE, packType);
130 memcpy(retAllObjBytes + objAndMethIdLen, packType, IoTRMIUtil::PACKET_TYPE_LEN);
131 // Copy object into byte array
132 char retObjBytes[retLen];
133 IoTRMIUtil::getObjectBytes(retObjBytes, retObj, type.c_str());
134 memcpy(retAllObjBytes + headerLen, retObjBytes, retLen);
136 rmiServerSend->sendBytes(retAllObjBytes, headerLen+retLen);
141 // Send return values in bytes to the caller (for more than one object - struct)
142 void IoTRMICommServer::sendReturnObj(void* retObj[], string type[], int numRet, char* methodBytes) {
144 // Critical section that is used by different objects
145 lock_guard<mutex> guard(sendReturnObjMutex);
146 // Find the length of return object in bytes
147 int retLen = returnLength(retObj, type, numRet);
148 // Copy the header and object bytes
149 int objAndMethIdLen = IoTRMIUtil::OBJECT_ID_LEN + IoTRMIUtil::METHOD_ID_LEN;
150 int headerLen = objAndMethIdLen + IoTRMIUtil::PACKET_TYPE_LEN;
151 char retAllObjBytes[headerLen+retLen];
152 // Copy object and method Id first
153 memcpy(retAllObjBytes, methodBytes, objAndMethIdLen);
154 // Copy objectId + methodId + packet type in bytes
155 char packType[IoTRMIUtil::PACKET_TYPE_LEN];
156 IoTRMIUtil::intToByteArray(IoTRMIUtil::RET_VAL_TYPE, packType);
157 memcpy(retAllObjBytes + objAndMethIdLen, packType, IoTRMIUtil::PACKET_TYPE_LEN);
158 // Copy object into byte array
159 char retObjBytes[retLen];
160 returnToBytes(retObj, type, retObjBytes, numRet);
161 memcpy(retAllObjBytes + headerLen, retObjBytes, retLen);
163 rmiServerSend->sendBytes(retAllObjBytes, headerLen+retLen);
168 // Calls a method remotely by passing in parameters and getting a return object
169 void IoTRMICommServer::remoteCall(int objectId, int methodId, string paramCls[],
170 void* paramObj[], int numParam) {
172 // Critical section that is used by different objects
173 lock_guard<mutex> guard(remoteCallMutex);
174 // Send input parameters
175 int len = methodLength(paramCls, paramObj, numParam);
177 methodToBytes(objectId, methodId, paramCls, paramObj, method, numParam);
180 rmiServerSend->sendBytes(method, len);