diff --git a/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h b/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h index 00d6df141..b82b2201d 100644 --- a/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h +++ b/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h @@ -9,7 +9,7 @@ #include "receiver_defs.h" class MySocketTCP; -class ClientInterface; +class ServerInterface; class slsReceiverImplementation; @@ -363,5 +363,5 @@ protected: MySocketTCP* mySock; /** client interface */ - ClientInterface* interface; + ServerInterface* interface; }; diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index 9d7a8acda..833006a46 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -6,7 +6,7 @@ #include "slsReceiverTCPIPInterface.h" #include "slsReceiverImplementation.h" #include "MySocketTCP.h" -#include "ClientInterface.h" +#include "ServerInterface.h" #include "gitInfoReceiver.h" #include "slsReceiverUsers.h" #include "slsReceiver.h" @@ -60,7 +60,7 @@ slsReceiverTCPIPInterface::slsReceiverTCPIPInterface(int pn): portNumber = (pn > 0 ? pn : DEFAULT_PORTNO + 2); MySocketTCP* m = new MySocketTCP(portNumber); mySock = m; - interface = new ClientInterface(mySock, -1, "Receiver"); + interface = new ServerInterface(mySock, -1, "Receiver"); //initialize variables strcpy(mySock->lastClientIP,"none"); diff --git a/slsSupportLib/CMakeLists.txt b/slsSupportLib/CMakeLists.txt index d495d381f..be39ec9b4 100644 --- a/slsSupportLib/CMakeLists.txt +++ b/slsSupportLib/CMakeLists.txt @@ -6,6 +6,7 @@ set(SOURCES src/ClientSocket.cpp src/DataSocket.cpp src/ServerSocket.cpp + src/ServerInterface.cpp ) set(HEADERS @@ -28,6 +29,7 @@ set(PUBLICHEADERS include/ClientSocket.h include/DataSocket.h include/ServerSocket.h + include/ServerInterface.h ) add_library(slsSupportLib SHARED diff --git a/slsSupportLib/include/ServerInterface.h b/slsSupportLib/include/ServerInterface.h new file mode 100644 index 000000000..223efa3a2 --- /dev/null +++ b/slsSupportLib/include/ServerInterface.h @@ -0,0 +1,152 @@ +#pragma once + + +#include "sls_detector_defs.h" +#include "MySocketTCP.h" + + +/** + * @short the ServerInterface class is the interface between the client and the server + */ +// Do not overload to make it easier for manual comparison between client and server functions + +class ServerInterface: public virtual slsDetectorDefs{ + +public: + + /** + * (default) constructor + * @param socket tcp socket between client and receiver + * @param n for debugging purposes (useful only for client side) + * @param t string to identify type (Detector, Receiver) for printouts (useful only for client side) + */ + ServerInterface(MySocketTCP *socket, int n=-1, std::string t=""); + + /** + * destructor + */ + virtual ~ServerInterface() = default; + + /** + * Set the datasocket + * @param socket the data socket + */ + void SetSocket(MySocketTCP *socket); + + /** + * Receive ret, mess or retval from Server + * @param ret result of operation + * @param mess pointer to message + * @param retval pointer to retval + * @param sizeOfRetval size of retval + */ + void Client_Receive(int& ret, char* mess, void* retval, int sizeOfRetval); + + /** + * Send Arguments to server and receives result back + * @param fnum function enum to determine what parameter + * @param args pointer to arguments + * @param sizeOfArgs argument size + * @param retval pointer to return value + * @param sizeOfRetval return value size + * @param mess pointer to message if message required externally + * @returns success of operation + */ + int Client_Send(int fnum, + void* args, int sizeOfArgs, + void* retval, int sizeOfRetval, + char* mess = 0); + + + /** only Receiver + * Server sends result to client (also set ret to force_update if different clients) + * @param update true if one must update if different clients, else false + * @param ret success of operation + * @param retval pointer to result + * @param retvalSize size of result + * @param mess message + * @returns success of operation + */ + int Server_SendResult(bool update, int ret, void* retval, int retvalSize, char* mess = 0); + + /** only Receiver + * Server receives arguments and checks if base object is null (if checkbase is true) + * checking base object is null (for receiver only when it has not been configured yet) + * @param ret pointer to success of operation + * @param mess message + * @param arg pointer to argument + * @param sizeofArg size of argument + * @param checkbase if true, checks if base object is null and sets ret and mess accordingly + * @param base pointer to base object + * @returns fail if socket crashes while reading arguments, else fail + */ + int Server_ReceiveArg(int& ret, char* mess, void* arg, int sizeofArg,bool checkbase=false, void* base=NULL); + + /** only Receiver + * Server verifies if it is unlocked, + * sets and prints appropriate message if it is locked and different clients + * @param ret pointer to success + * @param mess message + * @param lockstatus status of lock + * @returns success of operaton + */ + int Server_VerifyLock(int& ret, char* mess, int lockstatus); + + /** only Receiver + * Server verifies if it is unlocked and idle, + * sets and prints appropriate message if it is locked and different clients + * @param ret pointer to success + * @param mess message + * @param lockstatus status of lock + * @param status status of server + * @param fnum function number for error message + * @returns success of operaton + */ + int Server_VerifyLockAndIdle(int& ret, char* mess, int lockstatus, slsDetectorDefs::runStatus status, int fnum); + + /** only Receiver + * Server sets and prints error message for null object error (receiver only) + * @param ret pointer to success that will be set to FAIL + * @param mess message + */ + void Server_NullObjectError(int& ret, char* mess); + + /** only Receiver + * Servers prints error message for socket crash when reading + * @returns always FAIL + */ + int Server_SocketCrash(); + + /** only Receiver + * Servers sets and prints error message for locked server + * @param ret pointer to success that will be set to FAIL + * @param mess message + * @returns success of operaton + */ + int Server_LockedError(int& ret, char* mess); + + /** only Receiver + * Servers sets and prints error message for server not being idle + * @param ret pointer to success that will be set to FAIL + * @param mess message + * @param fnum function number for error message + * @returns success of operaton + */ + int Server_NotIdleError(int& ret, char* mess, int fnum); + +private: + + /** + * socket for data acquisition + */ + MySocketTCP *mySocket; + + /** index for client debugging purposes */ + int index; + + /** string for type to differentiate between Detector & Receiver in printouts */ + std::string type; + +}; + + diff --git a/slsSupportLib/src/ServerInterface.cpp b/slsSupportLib/src/ServerInterface.cpp new file mode 100644 index 000000000..6be49a37e --- /dev/null +++ b/slsSupportLib/src/ServerInterface.cpp @@ -0,0 +1,143 @@ +#include "ServerInterface.h" + +ServerInterface::ServerInterface(MySocketTCP *socket, int n, std::string t): mySocket(socket), + index(n), + type(t){} + +void ServerInterface::SetSocket(MySocketTCP *socket) { + mySocket = socket; +} + + +void ServerInterface::Client_Receive(int& ret, char* mess, void* retval, int sizeOfRetval) { + // get result of operation + mySocket->ReceiveDataOnly(&ret,sizeof(ret)); + + bool unrecognizedFunction = false; + if (ret == FAIL) { + bool created = false; + // allocate mess if null + if (!mess){ + created = true; + mess = new char[MAX_STR_LENGTH]; + memset(mess, 0, MAX_STR_LENGTH); + } + // get error message + mySocket->ReceiveDataOnly(mess,MAX_STR_LENGTH); + cprintf(RED, "%s %d returned error: %s", type.c_str(), index, mess); + + // unrecognized function, do not ask for retval + if(strstr(mess,"Unrecognized Function") != nullptr) + unrecognizedFunction = true; + // delete allocated mess + if (created) + delete [] mess; + } + // get retval + if (!unrecognizedFunction) + mySocket->ReceiveDataOnly(retval, sizeOfRetval); +} + + +int ServerInterface::Client_Send(int fnum, + void* args, int sizeOfArgs, + void* retval, int sizeOfRetval, + char* mess) { + int ret = FAIL; + mySocket->SendDataOnly(&fnum,sizeof(fnum)); + mySocket->SendDataOnly(args, sizeOfArgs); + Client_Receive(ret, mess, retval, sizeOfRetval); + return ret; +} + + +int ServerInterface::Server_SendResult(bool update, int ret, + void* retval, int retvalSize, char* mess) { + + // update if different clients + if (update && ret == OK && mySocket->differentClients) + ret = FORCE_UPDATE; + + // send success of operation + mySocket->SendDataOnly(&ret,sizeof(ret)); + if(ret == FAIL) { + // send error message + if (mess) + mySocket->SendDataOnly(mess, MAX_STR_LENGTH); + // debugging feature. should not happen. + else + FILE_LOG(logERROR) << "No error message provided for this failure. Will mess up TCP\n"; + } + // send return value + mySocket->SendDataOnly(retval, retvalSize); + + return ret; +} + + +int ServerInterface::Server_ReceiveArg(int& ret, char* mess, void* arg, int sizeofArg, bool checkbase, void* base) { + // client socket crash, cannot receive arguments + if (sizeofArg && mySocket->ReceiveDataOnly(arg, sizeofArg) < 0) + return Server_SocketCrash(); + + // check if server object created + if (checkbase && base == nullptr) + Server_NullObjectError(ret, mess); + + // no crash + return OK; +} + + +int ServerInterface::Server_VerifyLock(int& ret, char* mess, int lockstatus) { + // server locked + if (mySocket->differentClients && lockstatus) + return Server_LockedError(ret, mess); + return ret; +} + + +int ServerInterface::Server_VerifyLockAndIdle(int& ret, char* mess, int lockstatus, slsDetectorDefs::runStatus status, int fnum) { + // server locked + if (mySocket->differentClients && lockstatus) + return Server_LockedError(ret, mess); + + // server not idle for this command + if (status != slsDetectorDefs::IDLE) + return Server_NotIdleError(ret, mess, fnum); + return ret; +} + + +void ServerInterface::Server_NullObjectError(int& ret, char* mess) { + ret=FAIL; + strcpy(mess,"Receiver not set up. Please use rx_hostname first.\n"); + FILE_LOG(logERROR) << mess; +} + + +int ServerInterface::Server_SocketCrash() { + FILE_LOG(logERROR) << "Reading from socket failed. Possible socket crash"; + return FAIL; +} + + +int ServerInterface::Server_LockedError(int& ret, char* mess) { + ret = FAIL; + sprintf(mess,"Receiver locked by %s\n", mySocket->lastClientIP); + FILE_LOG(logERROR) << mess; + return ret; +} + + +int ServerInterface::Server_NotIdleError(int& ret, char* mess, int fnum) { + ret = FAIL; + sprintf(mess,"Can not execute %s when receiver is not idle\n", + getFunctionNameFromEnum((enum detFuncs)fnum)); + FILE_LOG(logERROR) << mess; + return ret; +} + + + +