#include #include #include #include #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; iReactor.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