249 lines
8.1 KiB
C++
Executable File
249 lines
8.1 KiB
C++
Executable File
#include <cdevDevice.h>
|
|
#include <cdevRequestObject.h>
|
|
#include <cdevCollection.h>
|
|
#include <cdevCollectionRequest.h>
|
|
|
|
#include "cdevGateway.h"
|
|
|
|
GatewayServer *gatewayServer;
|
|
|
|
// *****************************************************************************
|
|
// * GatewayServer::GatewayServer :
|
|
// * This is the constructor for the gateway server. It initializes the
|
|
// * underlying cdevServer object and sets the nextCollectionInt variable
|
|
// * to zero.
|
|
// *
|
|
// * The constructor will also extract all of the file descriptors from the
|
|
// * cdevSystem object and will create a GatewayHandler for each of them...
|
|
// * The fdChangedCallback method will be register with the cdevSystem to
|
|
// * ensure that these GatewayHandlers will be regularly updated/removed
|
|
// * as they become connected and disconnected.
|
|
// *****************************************************************************
|
|
GatewayServer::GatewayServer ( char * domain, char * server, unsigned short port, double pulse )
|
|
: cdevServer(domain, server, port, pulse), nextCollectionInt(0)
|
|
{
|
|
int fdBufSize = 256;
|
|
int * fdBuf = NULL;
|
|
|
|
// *********************************************************************
|
|
// * Get the list of all file descriptors that are in use by the
|
|
// * cdevSystem class.
|
|
// *********************************************************************
|
|
do {
|
|
fdBuf = new int[fdBufSize];
|
|
if(cdevSystem::defaultSystem().getFd(fdBuf, fdBufSize)!=CDEV_SUCCESS)
|
|
{
|
|
delete fdBuf;
|
|
fdBufSize *= 2;
|
|
fdBuf = NULL;
|
|
}
|
|
} while (fdBuf==NULL);
|
|
|
|
// *********************************************************************
|
|
// * Create a GatewayHandler to manage each of the file descriptors
|
|
// * that was provided by the cdevSystem class, and register them with
|
|
// * the Reactor.
|
|
// *********************************************************************
|
|
for(int i=0; i<fdBufSize; i++)
|
|
{
|
|
GatewayHandler * hdlr;
|
|
hdlr = new GatewayHandler(cdevSystem::defaultSystem(), fdBuf[i]);
|
|
Reactor.registerHandler(hdlr, cdevEventHandler::READ_MASK);
|
|
}
|
|
|
|
// *********************************************************************
|
|
// * Install the static fdChangedCallback method to be called each time
|
|
// * one of the cdevSystem's file descriptors is added or deleted.
|
|
// *********************************************************************
|
|
cdevSystem::defaultSystem().addFdChangedCallback(fdChangedCallback, this);
|
|
|
|
// *********************************************************************
|
|
// * Delete the temporary file descriptor buffer before returning.
|
|
// *********************************************************************
|
|
delete fdBuf;
|
|
}
|
|
|
|
// *****************************************************************************
|
|
// * GatewayServer::~GatewayServer :
|
|
// * This is the virtual destructor for the cdevGateway class. It does
|
|
// * nothing except serve as a placeholder to ensure that the delete
|
|
// * mechanism calls the most senior object.
|
|
// *****************************************************************************
|
|
GatewayServer::~GatewayServer ( void )
|
|
{
|
|
}
|
|
|
|
|
|
// *****************************************************************************
|
|
// * GatewayServer::fdChangedCallback :
|
|
// * This method will be called by CDEV anytime one of the file descriptors
|
|
// * associated with the cdevSystem is added or deleted. This method may
|
|
// * then add or delete the file descriptor from the Reactor object.
|
|
// *****************************************************************************
|
|
void GatewayServer::fdChangedCallback (int fd, int opened, void * arg )
|
|
{
|
|
GatewayServer * server = (GatewayServer *)arg;
|
|
|
|
if(opened)
|
|
{
|
|
GatewayHandler * hdlr;
|
|
hdlr = new GatewayHandler(cdevSystem::defaultSystem(), fd);
|
|
server->Reactor.registerHandler(hdlr, cdevEventHandler::READ_MASK);
|
|
}
|
|
else server->Reactor.removeHandler(fd);
|
|
}
|
|
|
|
|
|
// *****************************************************************************
|
|
// * GatewayServer::handleTimeout :
|
|
// * This is the handleTimeout method. It is called by the cdevReactor
|
|
// * periodically to make sure that all events are being handled.
|
|
// *****************************************************************************
|
|
int GatewayServer::handleTimeout ( void )
|
|
{
|
|
cdevSystem::defaultSystem().pend(0.001);
|
|
return 0;
|
|
}
|
|
|
|
// *****************************************************************************
|
|
// * GatewayServer::processMessages :
|
|
// * This is the processMessages method. It receives the inbound requests
|
|
// * from the clients and then calls CDEV to process the requests.
|
|
// *****************************************************************************
|
|
void GatewayServer::processMessages ( void )
|
|
{
|
|
int data_handled = 0;
|
|
cdevMessage * request;
|
|
while(dequeue(request)==0)
|
|
{
|
|
if(!strcmp(request->getMessage(), "register") ||
|
|
!strcmp(request->getMessage(), "unregister"))
|
|
{
|
|
enqueue(request);
|
|
delete (request);
|
|
}
|
|
else
|
|
{
|
|
int result (CDEV_SUCCESS);
|
|
cdevCallback cb (gatewayCallback, request);
|
|
int deviceCount (request->getDeviceCount());
|
|
char ** deviceList = request->getDeviceList();
|
|
char * message = request->getMessage();
|
|
cdevData * context = request->getContext();
|
|
cdevData * dataOut = request->getData();
|
|
cdevRequestObject * req = NULL;
|
|
|
|
if(deviceCount<=0 || deviceList==NULL || message==NULL)
|
|
{
|
|
result = CDEV_ERROR;
|
|
}
|
|
else
|
|
{
|
|
if(deviceCount==1)
|
|
{
|
|
req = cdevRequestObject::attachPtr(deviceList[0], message);
|
|
}
|
|
else {
|
|
char name[32];
|
|
sprintf(name, "~Collection%i", nextCollectionInt++);
|
|
cdevCollection *col = cdevCollection::attachPtr(name);
|
|
col->add(deviceCount, deviceList);
|
|
req = col->getRequestObject(message);
|
|
}
|
|
if(context) req->setContext(*context);
|
|
result = req->sendCallback(dataOut, cb);
|
|
if(result==CDEV_SUCCESS) data_handled++;
|
|
}
|
|
|
|
if(result != CDEV_SUCCESS)
|
|
{
|
|
request->setCompletionCode(result);
|
|
enqueue(request);
|
|
delete request;
|
|
}
|
|
}
|
|
|
|
// *********************************************************************
|
|
// * Note: The developer MUST do a pend at this point in order to
|
|
// * have the file descriptors updated... However, the wait time can be
|
|
// * very, very short.
|
|
// *********************************************************************
|
|
if(data_handled) cdevSystem::defaultSystem().pend(0.000001);
|
|
}
|
|
}
|
|
|
|
// *****************************************************************************
|
|
// * GatewayServer::gatewayCallback :
|
|
// * This is the callback function that is called each time a request has
|
|
// * been processed by CDEV. The cdevMessage that was used to make the
|
|
// * request is stored in the userarg parameter and this method will pass
|
|
// * the result to the cdevGateway for processing.
|
|
// *
|
|
// * When the isTransactionDone flag is set to TRUE, this method will
|
|
// * delete the cdevMessage object.
|
|
// *****************************************************************************
|
|
void GatewayServer::gatewayCallback ( int status, void *userarg, cdevRequestObject &, cdevData &data)
|
|
{
|
|
cdevMessage * message = (cdevMessage *)userarg;
|
|
|
|
|
|
message->setCompletionCode(status);
|
|
message->setData(&data, 1);
|
|
message->setOperationCode(cdevCallback::isTransactionDone()?1:0);
|
|
gatewayServer->enqueue(message);
|
|
message->setData(NULL);
|
|
|
|
if(cdevCallback::isTransactionDone()) delete message;
|
|
}
|
|
|
|
|
|
int main(int argc, char ** argv)
|
|
{
|
|
char serverName[255];
|
|
int serverPort = 9573;
|
|
int mismatch = 0;
|
|
|
|
strcpy(serverName, "Gateway1");
|
|
|
|
for(int i=1; i<argc && !mismatch; i++)
|
|
{
|
|
char * ptr;
|
|
switch(*argv[i])
|
|
{
|
|
case 's':
|
|
if((ptr = strchr(argv[i], '='))!=NULL && *(++ptr))
|
|
{
|
|
strcpy(serverName, ptr);
|
|
}
|
|
else mismatch = 1;
|
|
break;
|
|
|
|
case 'p':
|
|
if((ptr = strchr(argv[i], '='))!=NULL && *(++ptr))
|
|
{
|
|
if((serverPort = atoi(ptr))==0)
|
|
{
|
|
mismatch = 1;
|
|
}
|
|
}
|
|
else mismatch = 1;
|
|
break;
|
|
|
|
default:
|
|
mismatch = 1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(mismatch)
|
|
{
|
|
fprintf(stderr, "%s <s=server name> <p=server port>\\n", argv[0]);
|
|
}
|
|
else
|
|
{
|
|
gatewayServer = new GatewayServer("GATEWAY", serverName, serverPort, 60);
|
|
gatewayServer->runServer();
|
|
}
|
|
return mismatch?-1:0;
|
|
}
|