693 lines
25 KiB
C++
Executable File
693 lines
25 KiB
C++
Executable File
#include "cdevServer.h"
|
|
#include "ClientAcceptor.h"
|
|
#include "ClientHandler.h"
|
|
|
|
sig_atomic_t cdevServer::Finished = 0;
|
|
SignalManager cdevServer::SigManager;
|
|
cdevGenericServerTagDef cdevServer::tags;
|
|
|
|
// *****************************************************************************
|
|
// * This function is an interrupt handler that will be executed whenever the
|
|
// * program receives a SIGINT. When called it will set the finished flag to 1
|
|
// * and trigger the termination of the program.
|
|
// *****************************************************************************
|
|
static void SIGINT_handler (int signo)
|
|
{
|
|
cdevServer::Finished = 1;
|
|
signal(signo, SIGINT_handler);
|
|
}
|
|
|
|
|
|
// *****************************************************************************
|
|
// * cdevServer::cdevServer :
|
|
// * This is the constructor for the class. It will post the listening
|
|
// * socket, establish registration with the name server and record all
|
|
// * other pertinent information.
|
|
// *****************************************************************************
|
|
cdevServer::cdevServer (char * DomainName, char * ServerName, unsigned short Port, double Rate)
|
|
: cdevSessionManager(),
|
|
serverName (NULL),
|
|
acceptor (NULL),
|
|
timer (NULL),
|
|
status (UNINITIALIZED),
|
|
serverInfo (NULL)
|
|
{
|
|
// *********************************************************************
|
|
// * Register the import method for the cdevMessage class with the
|
|
// * cdevPacket class.
|
|
// *********************************************************************
|
|
cdevPacket::registerImportMethod(cdevMessage::CDEV_PACKET_VERSION,
|
|
cdevMessage::import);
|
|
|
|
startServer(DomainName, ServerName, Port, Rate, 0);
|
|
}
|
|
|
|
// *****************************************************************************
|
|
// * cdevServer::cdevServer :
|
|
// * This is the do nothing constructor for the class.
|
|
// *****************************************************************************
|
|
cdevServer::cdevServer ( void )
|
|
: cdevSessionManager (),
|
|
serverName (NULL),
|
|
acceptor (NULL),
|
|
timer (NULL),
|
|
status (UNINITIALIZED),
|
|
serverInfo (NULL)
|
|
{
|
|
// *********************************************************************
|
|
// * Register the import method for the cdevMessage class with the
|
|
// * cdevPacket class.
|
|
// *********************************************************************
|
|
cdevPacket::registerImportMethod(cdevMessage::CDEV_PACKET_VERSION,
|
|
cdevMessage::import);
|
|
|
|
}
|
|
|
|
// *****************************************************************************
|
|
// * cdevServer::~cdevServer :
|
|
// * This is the destructor for the object. It will close all listening
|
|
// * sockets and will delete all allocated items.
|
|
// *****************************************************************************
|
|
cdevServer::~cdevServer ( void )
|
|
{
|
|
outputError ( CDEV_SEVERITY_INFO, "CDEV Server",
|
|
"Server %s is Terminating...",
|
|
serverName);
|
|
|
|
Reactor.extractHandler(this);
|
|
|
|
if(timer!=NULL) delete timer;
|
|
if(serverName!=NULL) delete serverName;
|
|
if(acceptor!=NULL) delete acceptor;
|
|
}
|
|
|
|
|
|
// *****************************************************************************
|
|
// * cdevServer::startServer :
|
|
// * This method will initialize a cdevServer within a given name, will
|
|
// * register it within the CDEV Name Server and will commence listening
|
|
// * for connections on the specified port.
|
|
// *****************************************************************************
|
|
int cdevServer::startServer (char * DomainName, char * ServerName, unsigned short Port, double Rate, int searchForPort)
|
|
{
|
|
if(acceptor!=NULL)
|
|
{
|
|
delete acceptor;
|
|
acceptor=NULL;
|
|
}
|
|
if(timer)
|
|
{
|
|
delete timer;
|
|
timer=NULL;
|
|
}
|
|
if(serverName)
|
|
{
|
|
delete serverName;
|
|
serverName = NULL;
|
|
}
|
|
if(serverInfo)
|
|
{
|
|
delete serverInfo;
|
|
serverInfo = NULL;
|
|
}
|
|
|
|
Reactor.extractHandler(this);
|
|
|
|
setTimeoutRate(Rate);
|
|
serverName = strdup(ServerName);
|
|
status = UNINITIALIZED;
|
|
acceptor = new ClientAcceptor(*this);
|
|
|
|
// *********************************************************************
|
|
// * Attempt to open the acceptor to receive new connections.
|
|
// *********************************************************************
|
|
if(searchForPort) Port = 0;
|
|
cdevInetAddr addr(Port);
|
|
int initialized=!(acceptor->open(addr));
|
|
|
|
// *********************************************************************
|
|
// * Call getLocalAddress to retrieve the actual port number that was
|
|
// * opened. This value will differ from the specified port if...
|
|
// * 1) the user specified 0 for the port number -or-
|
|
// * 2) the user set the searchForPort flag to non-zero.
|
|
// *********************************************************************
|
|
if(acceptor->getLocalAddress(addr)==0) Port = addr.getPortNum();
|
|
else Port = (unsigned short)-1;
|
|
|
|
// *********************************************************************
|
|
// * ServerInfo must be created after the port has been searched for
|
|
// * and found. Otherwise, the server will report the original port
|
|
// * number rather than the actual port number.
|
|
// *********************************************************************
|
|
serverInfo = new ServerInfo(DomainName, ServerName, Port);
|
|
|
|
if(initialized)
|
|
{
|
|
// *************************************************************
|
|
// * Register the acceptor with the Reactor.
|
|
// *************************************************************
|
|
if(Reactor.registerHandler(acceptor, READ_MASK)!=-1)
|
|
{
|
|
// *****************************************************
|
|
// * Register this event handler with the Reactor.
|
|
// *****************************************************
|
|
if(Reactor.registerHandler(this, READ_MASK)!=-1)
|
|
{
|
|
// *********************************************
|
|
// * Schedule the periodic timer if it is
|
|
// * greater than 0.
|
|
// *********************************************
|
|
if(Rate <= 0.0 ||
|
|
Reactor.registerTimer(this)!=-1)
|
|
{
|
|
// *************************************
|
|
// * Install a name server timer to
|
|
// * continuously register this server
|
|
// * with the Name Server.
|
|
// *************************************
|
|
timer = new cdevNameServerManager(Reactor, DomainName, ServerName, Port);
|
|
outputError (CDEV_SEVERITY_INFO, "CDEV Server",
|
|
"Server %s is operational and servicing requests...",
|
|
serverName);
|
|
}
|
|
else
|
|
{
|
|
outputError ( CDEV_SEVERITY_SEVERE, "CDEV Server",
|
|
"Server %s - Unable to register server timer with cdevReactor",
|
|
serverName);
|
|
status = CANT_REGISTER_TIMER;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
outputError ( CDEV_SEVERITY_SEVERE, "CDEV Server",
|
|
"Server %s - Unable to register server handler with cdevReactor",
|
|
serverName);
|
|
status = CANT_REGISTER_SERVER;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
outputError (CDEV_SEVERITY_SEVERE, "CDEV Server",
|
|
"Server %s - Unable to register listening service with cdevReactor",
|
|
serverName);
|
|
status = CANT_REGISTER_LISTENER;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
outputError ( CDEV_SEVERITY_SEVERE, "CDEV Server",
|
|
"Server %s - Unable to open listening socket",
|
|
serverName);
|
|
status = CANT_OPEN_SOCKET;
|
|
}
|
|
|
|
switch (status)
|
|
{
|
|
case CANT_REGISTER_TIMER:
|
|
Reactor.extractHandler(this);
|
|
|
|
case CANT_REGISTER_SERVER:
|
|
Reactor.extractHandler(acceptor);
|
|
|
|
case CANT_REGISTER_LISTENER:
|
|
case CANT_OPEN_SOCKET:
|
|
delete acceptor;
|
|
acceptor = NULL;
|
|
break;
|
|
|
|
case SUCCESS:
|
|
default:
|
|
status = SUCCESS;
|
|
break;
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
|
|
// ***************************************************************************
|
|
// * cdevServer::runServer :
|
|
// * This method is called to simultaneously execute all servers that
|
|
// * reside in the system.
|
|
// ***************************************************************************
|
|
void cdevServer::runServer ( void )
|
|
{
|
|
SigManager.installDefaults();
|
|
SigManager.installHandler (SIGINT, SIGINT_handler);
|
|
while (!Finished) Reactor.handleEvents ();
|
|
}
|
|
|
|
|
|
// *****************************************************************************
|
|
// * cdevServer::registerClient :
|
|
// * This is the cdevMessage specific method that is used to send a
|
|
// * "register" message to the server.
|
|
// *****************************************************************************
|
|
void cdevServer::registerClient ( short localID )
|
|
{
|
|
cdevMessage message(localID,0,0,0,0,0,0,0,NULL,"register");
|
|
cdevPacketBinary * packet = new cdevPacketBinary;
|
|
char * binary;
|
|
size_t binaryLen;
|
|
|
|
message.streamOut (&binary, &binaryLen);
|
|
packet->attachData(binary, binaryLen);
|
|
inbound.enqueue (packet);
|
|
}
|
|
|
|
|
|
// *****************************************************************************
|
|
// * cdevServer::unregisterClient :
|
|
// * This is the cdevMessage specific method that is used to send an
|
|
// * "unregister" message to the server.
|
|
// *****************************************************************************
|
|
void cdevServer::unregisterClient ( short localID )
|
|
{
|
|
cdevMessage message(localID,0,0,0,0,0,0,0,NULL,"unregister");
|
|
cdevPacketBinary * packet = new cdevPacketBinary;
|
|
char * binary;
|
|
size_t binaryLen;
|
|
|
|
message.streamOut (&binary, &binaryLen);
|
|
packet->attachData(binary, binaryLen);
|
|
inbound.enqueue (packet);
|
|
trigger.insertEvent();
|
|
}
|
|
|
|
|
|
// *****************************************************************************
|
|
// * cdevServer::newClientSession :
|
|
// * This method allows the caller to create a new ClientSession object. The
|
|
// * ClientSession object functions primarily as a pointer to the queue that
|
|
// * holds packets destined for a specific client, however, the developer
|
|
// * can create a subclass of the ClientSession that may be used to associate
|
|
// * additional, client specific information to the structure.
|
|
// *
|
|
// * The CLIPClientSession class allows the developer to associate a context
|
|
// * with the clientID.
|
|
// *****************************************************************************
|
|
ClientSession * cdevServer::newClientSession ( int SocketID, int ClientID, int LocalID )
|
|
{
|
|
return new CLIPClientSession (SocketID, ClientID, LocalID);
|
|
}
|
|
|
|
|
|
// *****************************************************************************
|
|
// * cdevServer::newSocketSession :
|
|
// * This method allows the caller to create a new SocketSession object. The
|
|
// * SocketSession object functions primarily as a pointer to the queue that
|
|
// * holds packets destined for a specific socket, however, the developer
|
|
// * can create a subclass of the SocketSession that may be used to associate
|
|
// * additional, socket specific information to the structure.
|
|
// *
|
|
// * The CLIPSocketSession class allows the developer to associate a
|
|
// * context map and a tag table with the socket number.
|
|
// *****************************************************************************
|
|
SocketSession * cdevServer::newSocketSession ( int SocketID )
|
|
{
|
|
if(serverInfo) serverInfo->clientCnt++;
|
|
|
|
return new CLIPSocketSession (SocketID);
|
|
}
|
|
|
|
// *****************************************************************************
|
|
// * cdevServer::deleteSocketSession :
|
|
// * This method is called to delete an existing socket session.
|
|
// *****************************************************************************
|
|
void cdevServer::deleteSocketSession ( SocketSession *socket )
|
|
{
|
|
if(socket)
|
|
{
|
|
if(serverInfo)
|
|
{
|
|
if(serverInfo->clientCnt>0) serverInfo->clientCnt--;
|
|
else serverInfo->clientCnt=0;
|
|
}
|
|
|
|
sockets.remove(socket->getSocketID());
|
|
delete socket;
|
|
}
|
|
}
|
|
|
|
// *****************************************************************************
|
|
// * cdevServer::dequeue :
|
|
// * This method provides a mechanism for the cdevServer object to only
|
|
// * dequeue packets that are of the type cdevMessage.
|
|
// *****************************************************************************
|
|
int cdevServer::dequeue ( cdevMessage * &message )
|
|
{
|
|
cdevPacket * packet = NULL;
|
|
|
|
while(packet==NULL && cdevSessionManager::dequeue(packet)==0)
|
|
{
|
|
if(packet->getVersion()!=cdevMessage::CDEV_PACKET_VERSION)
|
|
{
|
|
delete packet;
|
|
packet = NULL;
|
|
}
|
|
else if(((cdevMessage *)packet)->getOperationCode()==CDEV_SERVER_OP)
|
|
{
|
|
processLocal((cdevMessage * &)packet);
|
|
delete packet;
|
|
packet = NULL;
|
|
}
|
|
}
|
|
|
|
message = (cdevMessage *)packet;
|
|
return message==NULL?-1:0;
|
|
}
|
|
|
|
// *****************************************************************************
|
|
// * cdevServer::processLocal :
|
|
// * This method is called to process requests that are being transmitted
|
|
// * directly to the cdev Generic Server Engine to set or retrieve statistics
|
|
// * about the operation of the server or its clients.
|
|
// *****************************************************************************
|
|
void cdevServer::processLocal ( cdevMessage * & message )
|
|
{
|
|
CLIPClientSession * client = NULL;
|
|
CLIPSocketSession * socket = NULL;
|
|
|
|
if((client = (CLIPClientSession *)findLocalClient(message->getClientID()))!=NULL)
|
|
{
|
|
socket = (CLIPSocketSession *)findSocket(client->getSocketID());
|
|
}
|
|
if(!strcmp(message->getMessage(), "set ClientInfo"))
|
|
{
|
|
cdevData * data = message->getData();
|
|
if(data && socket) socket->updateClientInfo(*data);
|
|
}
|
|
else if(!strcmp(message->getMessage(), "get ServerInfo"))
|
|
{
|
|
if(serverInfo)
|
|
{
|
|
message->setOperationCode(CDEV_NORMAL_OP);
|
|
message->setData(&serverInfo->getServerData(), 1);
|
|
}
|
|
else {
|
|
message->setOperationCode(CDEV_NORMAL_OP);
|
|
message->setCompletionCode(-1);
|
|
}
|
|
enqueue(message);
|
|
}
|
|
else if(!strcmp(message->getMessage(), "get ClientInfo"))
|
|
{
|
|
IntHashIterator iter(&sockets);
|
|
ClientHandler * handler = NULL;
|
|
int socketCnt = 0;
|
|
int index = 0;
|
|
cdevData result;
|
|
|
|
iter.first();
|
|
while(iter.data()!=NULL)
|
|
{
|
|
iter++;
|
|
socketCnt++;
|
|
}
|
|
if(socketCnt)
|
|
{
|
|
char ** username = new char *[socketCnt];
|
|
char ** group = new char *[socketCnt];
|
|
unsigned * uid = new unsigned [socketCnt];
|
|
unsigned * gid = new unsigned [socketCnt];
|
|
unsigned * pid = new unsigned [socketCnt];
|
|
char ** program = new char *[socketCnt];
|
|
char ** commandline = new char *[socketCnt];
|
|
unsigned * starttime = new unsigned [socketCnt];
|
|
unsigned * connecttime = new unsigned [socketCnt];
|
|
char ** host = new char *[socketCnt];
|
|
char ** os = new char *[socketCnt];
|
|
char ** osrelease = new char *[socketCnt];
|
|
char ** osversion = new char *[socketCnt];
|
|
char ** machine = new char *[socketCnt];
|
|
char ** shell = new char *[socketCnt];
|
|
unsigned * socketNum = new unsigned[socketCnt];
|
|
unsigned * sendPktCnt = new unsigned[socketCnt];
|
|
unsigned * recvPktCnt = new unsigned[socketCnt];
|
|
|
|
iter.first();
|
|
while(index<socketCnt && (socket = (CLIPSocketSession *)iter.data())!=NULL)
|
|
{
|
|
username[index] = socket->getUsername();
|
|
group[index] = socket->getGroup();
|
|
uid[index] = socket->getUid();
|
|
gid[index] = socket->getGid();
|
|
pid[index] = socket->getPid();
|
|
program[index] = socket->getProgram();
|
|
commandline[index] = socket->getCommandLine();
|
|
starttime[index] = (unsigned)socket->getStartTime();
|
|
connecttime[index] = (unsigned)socket->getConnectTime();
|
|
host[index] = socket->getHost();
|
|
os[index] = socket->getOs();
|
|
osrelease[index] = socket->getOsRelease();
|
|
osversion[index] = socket->getOsVersion();
|
|
machine[index] = socket->getMachine();
|
|
shell[index] = socket->getShell();
|
|
socketNum[index] = socket->getSocketID();
|
|
if(Reactor.getHandler(socketNum[index], (cdevEventHandler *&)handler)==0)
|
|
{
|
|
sendPktCnt[index] = handler->getPacketsSent();
|
|
recvPktCnt[index] = handler->getPacketsRecv();
|
|
}
|
|
else {
|
|
sendPktCnt[index] = 0;
|
|
recvPktCnt[index] = 0;
|
|
}
|
|
index++;
|
|
iter++;
|
|
}
|
|
|
|
result.insert("username", username, socketCnt); delete username;
|
|
result.insert("group", group, socketCnt); delete group;
|
|
result.insert("uid", uid, socketCnt); delete uid;
|
|
result.insert("gid", gid, socketCnt); delete gid;
|
|
result.insert("pid", pid, socketCnt); delete pid;
|
|
result.insert("program", program, socketCnt); delete program;
|
|
result.insert("commandline", commandline, socketCnt); delete commandline;
|
|
result.insert("starttime", starttime, socketCnt); delete starttime;
|
|
result.insert("connecttime", connecttime, socketCnt); delete connecttime;
|
|
result.insert("host", host, socketCnt); delete host;
|
|
result.insert("os", os, socketCnt); delete os;
|
|
result.insert("osrelease", osrelease, socketCnt); delete osrelease;
|
|
result.insert("osversion", osversion, socketCnt); delete osversion;
|
|
result.insert("machine", machine, socketCnt); delete machine;
|
|
result.insert("shell", shell, socketCnt); delete shell;
|
|
result.insert("socket", socketNum, socketCnt); delete socketNum;
|
|
result.insert("sendPktCnt", sendPktCnt, socketCnt); delete sendPktCnt;
|
|
result.insert("recvPktCnt", recvPktCnt, socketCnt); delete recvPktCnt;
|
|
}
|
|
message->setOperationCode(CDEV_NORMAL_OP);
|
|
message->setData(&result, 1);
|
|
enqueue(message);
|
|
}
|
|
}
|
|
|
|
// *****************************************************************************
|
|
// * cdevServer::decodePacket :
|
|
// * This method is used to perform preprocessing on a newly dequeued binary
|
|
// * packet before it is provided to the caller. This method allows the
|
|
// * developer to perform special preparations on the packet before providing
|
|
// * it to the caller.
|
|
// *****************************************************************************
|
|
cdevPacket * cdevServer::decodePacket( cdevPacketBinary * input )
|
|
{
|
|
cdevPacket * packet = NULL;
|
|
|
|
if(input!=NULL)
|
|
{
|
|
short version;
|
|
input->getVersion(version);
|
|
switch (version)
|
|
{
|
|
// *****************************************************
|
|
// * If it is a cdevMessage object, I want to call the
|
|
// * cdevMessage specific decodePacket method.
|
|
// *****************************************************
|
|
case cdevMessage::CDEV_PACKET_VERSION:
|
|
packet = decodePacket ((cdevMessage *)cdevPacket::import(*input));
|
|
break;
|
|
|
|
// *****************************************************
|
|
// * Use the cdevSessionManager::decodePacket method
|
|
// * to handle any other type of packet.
|
|
// *****************************************************
|
|
default:
|
|
packet = cdevSessionManager::decodePacket(input);
|
|
break;
|
|
}
|
|
if(serverInfo) serverInfo->recvPktCnt++;
|
|
}
|
|
return packet;
|
|
}
|
|
|
|
// *****************************************************************************
|
|
// * cdevServer::decodePacket :
|
|
// * This decodePacket method is designed specifically to preprocess the
|
|
// * data associated with a cdevMessage object.
|
|
// *****************************************************************************
|
|
cdevPacket * cdevServer::decodePacket (cdevMessage * message )
|
|
{
|
|
CLIPClientSession * client = NULL;
|
|
CLIPSocketSession * socket = NULL;
|
|
|
|
if(message!=NULL &&
|
|
(client = (CLIPClientSession *)findLocalClient(message->getClientID()))!=NULL &&
|
|
(socket = (CLIPSocketSession *)findSocket(client->getSocketID()))!=NULL)
|
|
{
|
|
// *************************************************************
|
|
// * If a tagMap has been provided... use it to update
|
|
// * the tagMap stored in the SocketSession object.
|
|
// *************************************************************
|
|
if(message->getTagMap()!=NULL)
|
|
{
|
|
socket->TagMap().updateTagMap(*message->getTagMap());
|
|
message->setTagMap(NULL);
|
|
}
|
|
|
|
// *************************************************************
|
|
// * Pass the data and context objects through the tag map to
|
|
// * convert their tags from the remote integers to the local
|
|
// * integers.
|
|
// *************************************************************
|
|
if(message->getData()!=NULL)
|
|
socket->TagMap().remoteToLocal(*message->getData());
|
|
if(message->getContext()!=NULL)
|
|
socket->TagMap().remoteToLocal(*message->getContext());
|
|
|
|
// *************************************************************
|
|
// * If a context has been provided by the client side
|
|
// * of the connection - perform the following steps...
|
|
// *
|
|
// * 1) Add the context to the cdevContextMap for this
|
|
// * socketID if it does not already exist, and
|
|
// * obtain the index that identifies the new
|
|
// * context.
|
|
// *
|
|
// * 2) Delete the context from within the message.
|
|
// *
|
|
// * 3) Set the context within the message to the
|
|
// * current context that is specified in the
|
|
// * ClientSession object.
|
|
// *
|
|
// * 4) Set the saveContext flag in the message to
|
|
// * prevent its inadvertant destruction when the
|
|
// * message is deleted.
|
|
// *************************************************************
|
|
if(message->getContext()!=NULL)
|
|
{
|
|
cdevData * lastContext = client->getContext();
|
|
if(lastContext==NULL || *lastContext!=*message->getContext())
|
|
{
|
|
int contextID = socket->ContextMap().insert(*message->getContext());
|
|
client->setContext(socket->ContextMap().find(contextID));
|
|
}
|
|
}
|
|
message->setContext(client->getContext(), 1);
|
|
|
|
// *************************************************************
|
|
// * Toggle the local and foreign data indices.
|
|
// *************************************************************
|
|
unsigned int index = message->getForeignDataIndex();
|
|
message->setForeignDataIndex(message->getLocalDataIndex());
|
|
message->setLocalDataIndex (index);
|
|
}
|
|
|
|
return message;
|
|
}
|
|
|
|
|
|
// *****************************************************************************
|
|
// * cdevSessionManager::encodePacket :
|
|
// * This method is used to perform postprocessing on a packet that has been
|
|
// * enqueued to be sent to a client. This method allows the developer to
|
|
// * perform special preparations on the packet before providing it to the
|
|
// * client.
|
|
// *****************************************************************************
|
|
cdevPacketBinary * cdevServer::encodePacket ( cdevPacket * input )
|
|
{
|
|
cdevPacketBinary * packet = NULL;
|
|
|
|
if(input!=NULL)
|
|
{
|
|
switch(input->getVersion())
|
|
{
|
|
case cdevMessage::CDEV_PACKET_VERSION:
|
|
packet = encodePacket ((cdevMessage *)input);
|
|
break;
|
|
|
|
default:
|
|
packet = cdevSessionManager::encodePacket(input);
|
|
break;
|
|
}
|
|
if(serverInfo) serverInfo->sendPktCnt++;
|
|
}
|
|
return packet;
|
|
}
|
|
|
|
|
|
// *****************************************************************************
|
|
// * cdevServer::encodePacket :
|
|
// * This encodePacket method is designed specifically to postprocess the
|
|
// * data associated with a cdevMessage object.
|
|
// *****************************************************************************
|
|
cdevPacketBinary * cdevServer::encodePacket (cdevMessage * message )
|
|
{
|
|
cdevPacketBinary * result = NULL;
|
|
CLIPClientSession * client = NULL;
|
|
CLIPSocketSession * socket = NULL;
|
|
|
|
if(message!=NULL &&
|
|
message->getClientID()>0 &&
|
|
message->getTransIndex()>0 &&
|
|
(client = (CLIPClientSession *)findLocalClient(message->getClientID()))!=NULL &&
|
|
(socket = (CLIPSocketSession *)findSocket(client->getSocketID()))!=NULL)
|
|
{
|
|
char * binary = NULL;
|
|
size_t binaryLen = 0;
|
|
static cdevMessage outBound;
|
|
|
|
// *************************************************************
|
|
// * Remap the data to its foreign design.
|
|
// *************************************************************
|
|
if(message->getData()!=NULL)
|
|
socket->TagMap().localToRemote(*message->getData());
|
|
|
|
// *************************************************************
|
|
// * Transfer the critical data items into the class. Note that
|
|
// * we are not returning the deviceList, message, context,
|
|
// * cancelTransIndex, or operationCode with the return packet.
|
|
// *
|
|
// * Also note that the cdevData object is marked as permanent
|
|
// * and is using a pointer to the same cdevData object that is
|
|
// * in the message object.
|
|
// *************************************************************
|
|
outBound.clear();
|
|
outBound.setClientID (client->getClientID()&0xFFFF);
|
|
outBound.setTransIndex (message->getTransIndex());
|
|
outBound.setLocalDataIndex (message->getForeignDataIndex());
|
|
outBound.setForeignDataIndex (message->getLocalDataIndex());
|
|
outBound.setOperationCode (message->getOperationCode());
|
|
outBound.setCompletionCode (message->getCompletionCode());
|
|
outBound.setData (message->getData(), 1);
|
|
|
|
// *************************************************************
|
|
// * Create a binary stream from the cdevMessage object and then
|
|
// * place it into the outbound queue system.
|
|
// *************************************************************
|
|
outBound.streamOut(&binary, &binaryLen);
|
|
outBound.clear ();
|
|
|
|
result = new cdevPacketBinary;
|
|
result->attachData(binary, binaryLen);
|
|
|
|
// *************************************************************
|
|
// * Remap the data to its local design.
|
|
// *************************************************************
|
|
if(message->getData()!=NULL)
|
|
socket->TagMap().remoteToLocal(*message->getData());
|
|
}
|
|
return result;
|
|
}
|
|
|