|
#ifndef _VIRTUAL_ATTRIB_H_
#define _VIRTUAL_ATTRIB_H_ 1
#include <cdevData.h>
#include <VirtualServer.h>
// *****************************************************************************
// * class VirtualAttrib:
// * This class maintains a list of items that make-up a Virtual Attrib. And
// * access mechanisms.
// *****************************************************************************
class VirtualAttrib
{
private:
char * device;
char * attrib;
cdevMonitorNode * monitors;
double value;
char status [255];
char severity[255];
char units [255];
double alarmHigh;
double alarmLow;
double warningHigh;
double warningLow;
double controlHigh;
double controlLow;
int resultCode;
public:
VirtualAttrib (char * Device, char * Attrib);
~VirtualAttrib ( void );
int setFromData ( cdevData * data );
void getToData ( cdevData * data, cdevData * context = NULL );
void getAllToData ( cdevData * data );
int setValue ( double Value );
int setStatus ( char * Status );
int setSeverity ( char * Severity );
int setUnits ( char * Units );
int setAlarmHigh ( double AlarmHigh );
int setAlarmLow ( double AlarmLow );
int setWarningHigh ( double WarningHigh );
int setWarningLow ( double WarningLow );
int setControlHigh ( double ControlHigh );
int setControlLow ( double ControlLow );
void checkAlarms ( void );
double getValue ( void ) { return value; }
char * getStatus ( void ) { return status; }
char * getSeverity ( void ) { return severity; }
char * getUnits ( void ) { return units; }
double getAlarmHigh ( void ) { return alarmHigh; }
double getAlarmLow ( void ) { return alarmLow; }
double getWarningHigh ( void ) { return warningHigh; }
double getWarningLow ( void ) { return warningLow; }
double getControlHigh ( void ) { return controlHigh; }
double getControlLow ( void ) { return controlLow; }
int getResultCode ( void ) { return resultCode; }
void insertMonitor ( cdevMonitorTable * table, cdevMessage * message );
void removeMonitor ( cdevMonitorTable * table, cdevMessage * message );
};
#endif
VirtualAttrib.cc
|
This is the source file that defines the implementation details of the VirtualDevice class. The methods below are used to
insert and retrieve properties associated with the device/attribute pairs that are represented by each VirtualDevice object.
|
#include <VirtualAttrib.h>
static int VALUE_TAG = -1;
|
These static integers will be populated with the associated tag identifiers
that are used in the cdevData object. By using the tag identifier integer
rather than the associated character string, performance is greatly
improved when accessing properties stored in the cdevData object.
|
|
static int STATUS_TAG = -1;
static int SEVERITY_TAG = -1;
static int UNITS_TAG = -1;
static int ALARMHIGH_TAG = -1;
static int ALARMLOW_TAG = -1;
static int WARNINGHIGH_TAG = -1;
static int WARNINGLOW_TAG = -1;
static int CONTROLHIGH_TAG = -1;
static int CONTROLLOW_TAG = -1;
// *****************************************************************************
// * VirtualAttrib::VirtualAttrib :
// * This is the constructor for the VirtualAttrib class. It initializes the
// * internal mechanisms to 0.
// *****************************************************************************
VirtualAttrib::VirtualAttrib ( char * Device, char * Attrib )
: device(strdup(Device)),
|
The constructor for the VirtualAttrib object makes a copy of the name of
the device and attribute and then initializes all of its internal properties.
Note that if the 'high' and 'low' values for a range specification (such as
alarm) are equal, then that range specification is disabled.
|
|
attrib(strdup(Attrib)),
monitors(NULL),
value(0.0),
alarmHigh(0.0),
alarmLow(0.0),
warningHigh(0.0),
warningLow(0.0),
controlHigh(0.0),
controlLow(0.0)
{
*severity = 0;
*units = 0;
strcpy(status, "NORMAL");
}
// *****************************************************************************
// * VirtualAttrib::~VirtualAttrib :
// * This is the destructor for the VirtualAttrib class. It must free the
// * memory associated with the device and attribute names.
// *****************************************************************************
VirtualAttrib::~VirtualAttrib ( void
)
|
The destructor for a VirtualAttrib object only needs to delete the device
and attrib strings that were duplicated when the object was created.
|
|
{
delete device;
delete attrib;
}
// *****************************************************************************
// * VirtualAttrib::setFromData :
// * This method will populate the VirtualAttrib object with the data contained in
// * the cdevData object.
// *****************************************************************************
int VirtualAttrib::setFromData ( cdevData * data )
|
When a "set" cdevMessage
object is received in the
processMessages method of
the VirtualServer, it contains a
cdevData object that has a list
of properties and values. For
each property that is specified
this method will call the set
method with the new value. If
the value is different than the
previous value and the
property is monitored, then the
callback will be fired at that
time.
The result of this operation is
indicated by success in setting
the value property.
|
|
{
double val;
int result;
if(data!=NULL)
{
result = CDEV_SUCCESS;
data->get(UNITS_TAG, units, 255);
if(data->get(CONTROLLOW_TAG, &val)==CDEV_SUCCESS) setControlLow(val);
if(data->get(CONTROLHIGH_TAG, &val)==CDEV_SUCCESS) setControlHigh(val);
if(data->get(ALARMLOW_TAG, &val)==CDEV_SUCCESS) setAlarmLow(val);
if(data->get(ALARMHIGH_TAG, &val)==CDEV_SUCCESS) setAlarmHigh(val);
if(data->get(WARNINGLOW_TAG, &val)==CDEV_SUCCESS) setWarningLow(val);
if(data->get(WARNINGHIGH_TAG, &val)==CDEV_SUCCESS) setWarningHigh(val);
if(data->get(VALUE_TAG, &val)==CDEV_SUCCESS)
{
result=setValue(val);
}
}
else result = CDEV_ERROR;
checkAlarms();
return result;
}
// *****************************************************************************
// * VirtualAttrib::getToData :
// * This method will populate the VirtualAttrib object with the data contained in
// * the cdevData object.
// *****************************************************************************
void VirtualAttrib::getToData ( cdevData * data, cdevData * context )
|
When a "get" cdevMessage object is received in the
processMessages method of the VirtualServer, it
contains a context that indicates the properties that the
caller desires to be returned. This method walks through
the context object and copies each property that is
specified in the context into the cdevData object pointed
to by the data parameter. Once populated, this object will
be returned to the caller.
If the context is empty, then the "value", "status", and
"severity" properties are returned by default.
|
|
{
if(data!=NULL)
{
data->remove();
if(context!=NULL)
{
if(context->getType(VALUE_TAG)!=CDEV_INVALID)
data->insert(VALUE_TAG, getValue());
if(context->getType(STATUS_TAG)!=CDEV_INVALID)
data->insert(STATUS_TAG, getStatus());
if(context->getType(SEVERITY_TAG)!=CDEV_INVALID)
data->insert(SEVERITY_TAG, getSeverity());
if(context->getType(UNITS_TAG)!=CDEV_INVALID)
data->insert(UNITS_TAG, getUnits());
if(context->getType(CONTROLLOW_TAG)!=CDEV_INVALID)
data->insert(CONTROLLOW_TAG, getControlLow());
if(context->getType(CONTROLHIGH_TAG)!=CDEV_INVALID)
data->insert(CONTROLHIGH_TAG, getControlHigh());
if(context->getType(ALARMLOW_TAG)!=CDEV_INVALID)
data->insert(ALARMLOW_TAG, getAlarmLow());
if(context->getType(ALARMHIGH_TAG)!=CDEV_INVALID)
data->insert(ALARMHIGH_TAG, getAlarmHigh());
if(context->getType(WARNINGLOW_TAG)!=CDEV_INVALID)
data->insert(WARNINGLOW_TAG, getWarningLow());
if(context->getType(WARNINGHIGH_TAG)!=CDEV_INVALID)
data->insert(WARNINGHIGH_TAG, getWarningHigh());
}
else
{
data->insert(VALUE_TAG, getValue());
data->insert(STATUS_TAG, getStatus());
data->insert(SEVERITY_TAG, getSeverity());
}
}
}
// *****************************************************************************
// * VirtualAttrib::getAllToData :
// * This method will populate the VirtualAttrib object with the data contained in
// * the cdevData object.
// *****************************************************************************
void VirtualAttrib::getAllToData ( cdevData * data )
|
Unlike the getToData method, this method will populate
the cdevData object will all properties that are currently
contained in the VirtualAttrib object.
|
|
{
if(data!=NULL)
{
data->remove();
data->insert(VALUE_TAG, getValue());
data->insert(STATUS_TAG, getStatus());
data->insert(SEVERITY_TAG, getSeverity());
data->insert(UNITS_TAG, getUnits());
data->insert(CONTROLLOW_TAG, getControlLow());
data->insert(CONTROLHIGH_TAG, getControlHigh());
data->insert(ALARMLOW_TAG, getAlarmLow());
data->insert(ALARMHIGH_TAG, getAlarmHigh());
data->insert(WARNINGLOW_TAG, getWarningLow());
data->insert(WARNINGHIGH_TAG, getWarningHigh());
}
}
// *****************************************************************************
// * VirtualAttrib::setValue :
// * This method allows the caller to set the value of the Virtual Attrib.
// * This call will fail if the specified value is outside of the legal
// * range.
// *****************************************************************************
int VirtualAttrib::setValue ( double Value )
|
The setValue method is used to set the value property within the VirtualAttrib
object. Since the overall range may be specified using the controlHigh and
controlLow properties, this method will ensure that the new value conforms to the
range (if specified) and will fail if the value is too high or too low.
|
|
{
resultCode = CDEV_SUCCESS;
if(controlHigh>controlLow &&
(Value<controlLow || Value>controlHigh))
{
resultCode = CDEV_OUTOFRANGE;
}
else if(value != Value)
{
value = Value;
checkAlarms();
|
The checkAlarms method is called after the value has been set. The
checkAlarms method determines if the new value places the VirtualAttrib
in a warning or alarm state based on the confines that are specified in the
alarmHigh/Low and warningHigh/Low properties.
If the VirtualAttrib is monitored, then all properties will be copied into a
cdevData object and the list of monitors for the value property will be fired.
|
|
if(monitors && monitors->isMonitored())
{
cdevData data;
getAllToData(&data);
monitors->fireMonitor(VALUE_TAG, &data);
}
}
return resultCode;
}
// *****************************************************************************
// * VirtualAttrib::setStatus :
// * This method allows the caller to set the status of the device.
// *****************************************************************************
int VirtualAttrib::setStatus ( char * Status )
|
Sets the status property and fires any monitors that may be associated
with that value.
|
|
{
if(strcmp(status, Status))
{
strncpy(status, Status, 255);
status[254] = 0;
if(monitors && monitors->isMonitored())
{
cdevData data;
getAllToData(&data);
monitors->fireMonitor(STATUS_TAG, &data);
}
}
return CDEV_SUCCESS;
}
// *****************************************************************************
// * VirtualAttrib::setSeverity :
// * This method allows the caller to set the severity flag for the device.
// *****************************************************************************
int VirtualAttrib::setSeverity ( char * Severity )
|
Sets the severity property and fires any monitors that may be associated
with that value.
|
|
{
if(strcmp(severity, Severity))
{
strncpy(severity, Severity, 255);
severity[254] = 0;
if(monitors && monitors->isMonitored())
{
cdevData data;
getAllToData(&data);
monitors->fireMonitor(SEVERITY_TAG, &data);
}
}
return CDEV_SUCCESS;
}
// *****************************************************************************
// * VirtualAttrib::setUnits :
// * This method allows the caller to set the units for the device.
// *****************************************************************************
int VirtualAttrib::setUnits ( char * Units )
|
Sets the units property and fires any monitors that may be associated with
that value.
|
|
{
if(strcmp(units, Units))
{
strncpy(units, Units, 255);
units[254] = 0;
if(monitors && monitors->isMonitored())
{
cdevData data;
getAllToData(&data);
monitors->fireMonitor(UNITS_TAG, &data);
}
}
return CDEV_SUCCESS;
}
// *****************************************************************************
// * VirtualAttrib::setAlarmHigh :
// * This method allows the caller to set the high alarm value of the device.
// *****************************************************************************
int VirtualAttrib::setAlarmHigh ( double AlarmHigh )
|
Sets the alarmHigh property and calls checkAlarms to determine if a
change in this value will trigger a change in the device alarm status.
Dispatches any monitors that are associated with the property.
|
|
{
if(alarmHigh!=AlarmHigh)
{
alarmHigh = AlarmHigh;
checkAlarms();
if(monitors && monitors->isMonitored())
{
cdevData data;
getAllToData(&data);
monitors->fireMonitor(ALARMHIGH_TAG, &data);
}
}
return CDEV_SUCCESS;
}
// *****************************************************************************
// * VirtualAttrib::setAlarmLow :
// * This method allows the caller to set the low alarm value of the device.
// *****************************************************************************
int VirtualAttrib::setAlarmLow ( double AlarmLow )
|
Sets the alarmLow property and calls checkAlarms to determine if a
change in this value will trigger a change in the device alarm status.
Dispatches any monitors that are associated with the property.
|
|
{
if(alarmLow!=AlarmLow)
{
alarmLow = AlarmLow;
checkAlarms();
if(monitors && monitors->isMonitored())
{
cdevData data;
getAllToData(&data);
monitors->fireMonitor(ALARMLOW_TAG, &data);
}
}
return CDEV_SUCCESS;
}
// *****************************************************************************
// * VirtualAttrib::setWarningHigh :
// * This method allows the caller to set the high warning value of a device.
// *****************************************************************************
int VirtualAttrib::setWarningHigh ( double WarningHigh
)
|
Sets the warningHigh property and calls checkAlarms to determine if a
change in this value will trigger a change in the device warning status.
Dispatches any monitors that are associated with the property.
|
|
{
if(warningHigh!=WarningHigh)
{
warningHigh = WarningHigh;
checkAlarms();
if(monitors && monitors->isMonitored())
{
cdevData data;
getAllToData(&data);
monitors->fireMonitor(WARNINGHIGH_TAG, &data);
}
}
return CDEV_SUCCESS;
}
// *****************************************************************************
// * VirtualAttrib::setWarningLow :
// * This method allows the caller to set the low warning value of a device.
// *****************************************************************************
int VirtualAttrib::setWarningLow ( double WarningLow )
|
Sets the warningLow property and calls checkAlarms to determine if a
change in this value will trigger a change in the device warning status.
Dispatches any monitors that are associated with the property.
|
|
{
if(warningLow != WarningLow)
{
warningLow = WarningLow;
checkAlarms();
if(monitors && monitors->isMonitored())
{
cdevData data;
getAllToData(&data);
monitors->fireMonitor(WARNINGLOW_TAG, &data);
}
}
return CDEV_SUCCESS;
}
// *****************************************************************************
// * VirtualAttrib::setControlHigh :
// * This method allows the caller to set the maximum value for a device.
// *****************************************************************************
int VirtualAttrib::setControlHigh ( double ControlHigh )
|
Sets the controlHigh property and calls checkAlarms to determine if a
change in this value will trigger a change in the device status.
Dispatches any monitors that are associated with the property.
|
|
{
if(controlHigh != ControlHigh)
{
controlHigh = ControlHigh;
checkAlarms();
if(monitors && monitors->isMonitored())
{
cdevData data;
getAllToData(&data);
monitors->fireMonitor(CONTROLHIGH_TAG, &data);
}
}
return CDEV_SUCCESS;
}
// *****************************************************************************
// * VirtualAttrib::setControlLow :
// * This method allows the caller to set the minimum value of a device.
// *****************************************************************************
int VirtualAttrib::setControlLow ( double ControlLow )
|
Sets the controlLow property and calls checkAlarms to determine if a
change in this value will trigger a change in the device status.
Dispatches any monitors that are associated with the property.
|
|
{
if(controlLow != ControlLow)
{
controlLow = ControlLow;
checkAlarms();
if(monitors && monitors->isMonitored())
{
cdevData data;
getAllToData(&data);
monitors->fireMonitor(CONTROLLOW_TAG, &data);
}
}
return CDEV_SUCCESS;
}
// *****************************************************************************
// * VirtualAttrib::checkAlarms :
// * This method allows the caller to read the value in comparison with all
// * of its limits and set the status and severity tag appropriately.
// *****************************************************************************
void VirtualAttrib::checkAlarms ( void )
|
This method tests the value property against the ranges that may be
specified in the warningHigh/Low, alarmHigh/Low and controlHigh/Low
properties. If the value is outside of any of these ranges, then the status
and severity variables will be set to a corresponding value: "WARNING",
"ALARM", or "ERROR"
|
|
{
int done = 0;
if(controlHigh>controlLow)
{
{
setStatus("OUT OF RANGE LOW");
setSeverity("ERROR");
done = 1;
}
else if (value>controlHigh)
{
setStatus("OUT OF RANGE HIGH");
setSeverity("ERROR");
done = 1;
}
}
if(!done && alarmHigh>alarmLow)
{
{
setStatus("ALARM LOW");
setSeverity("ALARM");
done = 1;
}
else if (value>alarmHigh)
{
setStatus("ALARM HIGH");
setSeverity("ALARM");
done = 1;
}
}
if(!done && warningHigh>warningLow)
{
{
setStatus("WARNING LOW");
setSeverity("WARNING");
done = 1;
}
else if (value>warningHigh)
{
setStatus("WARNING HIGH");
setSeverity("WARNING");
done = 1;
}
}
if(!done)
{
setStatus("NORMAL");
setSeverity("\\0");
}
}
// *****************************************************************************
// * VirtualAttrib::insertMonitor :
// * This message adds a monitor to the cdevMonitorTable for this device/
// * attribute pair. The message parameter becomes the property of the
// * monitorTable and should not be accessed again by the caller.
// *****************************************************************************
void VirtualAttrib::insertMonitor ( cdevMonitorTable * table, cdevMessage * message )
{
|
The processMessages method of the VirtualServer class
calls this method when it receives a "monitorOn" message.
This method collects all of the current property values into a
cdevData object and then submits the cdevMessage object
and the data to the insertMonitor method of the
cdevMonitorTable object. The method will then call
findMonitor to locate its node in the cdevMonitorTable for later
access.
Note that the cdevMessage object becomes the property of
the cdevMonitorTable object and should not be accessed
again.
|
|
if(table!=NULL && message!=NULL)
{
cdevData data;
getAllToData(&data);
table->insertMonitor(message, &data);
monitors = table->findMonitor(device, attrib);
if(monitors && !monitors->isMonitored()) monitors = NULL;
}
else if(message!=NULL) delete message;
}
// *****************************************************************************
// * VirtualAttrib::removeMonitor:
// * This method uses the cancelTransIdx to locate and delete a monitor
// * that was previously posted using that transaction index.
// *****************************************************************************
void VirtualAttrib::removeMonitor (cdevMonitorTable * table, cdevMessage * message )
{
|
The processMessages method of the VirtualServer class
calls this method when it receives a "monitorOff" message.
The method will call the removeMonitor method of the
cdevMonitorTable to remove the monitor.
If all monitors have been removed that are associated with
this VirtualAttrib object, then the monitors pointer will be set
to NULL.
|
|
if(table!=NULL && message!=NULL)
{
table->removeMonitor(message);
if(monitors && !monitors->isMonitored()) monitors = NULL;
}
}
VirtualServer.h
|
The following header file defines the structure of the VirtualServer class. The VirtualServer class inherits its functionality from
the cdevServer object and consequently has to do very little initialization. When created it calls the populateTable method to
generate a list of VirtualAttrib objects that it will support, the service may then manipulate any of the devices that the server
has created using the commands "get", "set", "monitorOn", and "monitorOff".
|
#include <cdevServer.h>
#include <StringHash.h>
#include <cdevMonitorTable.h>
// *****************************************************************************
// * class VirtualServer :
// * This is the server class for the VirtualDevice. It simply receives
// * messages from a client and immediately returns them.
// *
// * The constructor passes the domain, server, port and rate to the
// * underlying cdevServer class to be processed. The cdevServer constructor
// * will add this server to the Name Server and will begin processing
// * messages when the cdevServer::runServer() method is executed.
// *
// * The processMessages method is the servers interface to the world... Each
// * time a complete message is received or the time specified in rate
// * expires, that method will be called.
// *****************************************************************************
class VirtualServer : public cdevServer, public cdevMonitorTable
{
private:
StringHash attribHash;
public:
VirtualServer ( char * domain, char * server, unsigned int port, double rate )
: cdevServer(domain, server, port, rate), attribHash()
{
populateTable();
}
virtual ~VirtualServer ( void );
virtual void processMessages ( void );
void populateTable ( void );
virtual int fireCallback ( cdevMessage * message );
};
VirtualServer.cc
|
This source file implements the classes that are defined in the VirtualServer.h header file. The methods that are contained in
this file define the functionality for the VirtualServer that is different from what is provided by default by the cdevServer class.
|
#include <VirtualServer.h>
#include <VirtualAttrib.h>
VirtualServer::~VirtualServer ( void )
|
This is the destructor for the VirtualServer object. It is responsible for
walking through the list of VirtualAttrib objects that were created and
deleting each of them from the list prior to terminating.
|
|
{
StringHashIterator iter(&attribHash);
VirtualAttrib * attrib = NULL;
char * key = NULL;
iter.first();
while((key=iter.key())!=NULL)
{
attrib = (VirtualAttrib *)iter.data();
iter++;
attribHash.remove(key);
if(attrib!=NULL) delete attrib;
}
}
void VirtualServer::populateTable ( void )
|
The populateTable method is used to generate a collection of device
names and their associated attributes that will be used to create a hash
table of VirtualAttrib objects. The device names are "device0" through
"device9", and each device has attributes "attrib0" through "attrib9".
The client may use the "get", "set", "monitorOn" or "monitorOff" methods
to manipulate the properties associated with any of these VirtualAttrib
objects.
|
|
{
char device[10];
char attrib[10];
char key[20];
{
{
sprintf(device, "device%i", i);
sprintf(attrib, "attrib%i", j);
sprintf(key, "device%i attrib%i", i, j);
attribHash.insert(key, new VirtualAttrib(device, attrib));
}
}
}
void VirtualServer::processMessages ( void )
|
The processMessages method will be called whenever data is waiting to
be processed in the inbound queue. When called, this method should
process all of the messages that it has available and then return 0.
To process a cdevMessage the method must dequeue it, process it,
enqueue the result and then delete the original cdevMessage object.
|
|
{
char key[255];
int saveMessageFlag;
int sendMessageFlag;
cdevMessage * message;
VirtualAttrib * attrib;
cdevData output;
while(dequeue(message)==0)
{
// *************************************************************
// * Note at this point a cdevTagMap has already been received
// * from the client. This tag map will have initialized all
// * of the tags that are required by the service.
// *************************************************************
if(!strcmp(message->getMessage(), "unregister"))
{
sendMessageFlag = 0;
removeClientMonitors(message->getClientID());
}
if(!strncmp(message->getMessage(), "get ", 4))
{
output.remove();
saveMessageFlag = 0;
sendMessageFlag = 1;
sprintf(key, "%s %s",
message->getDeviceList()[0],
&message->getMessage()[4]);
if((attrib = (VirtualAttrib *)attribHash.find(key))!=NULL)
{
attrib->getToData(&output, message->getContext());
output.insert("resultCode", CDEV_SUCCESS);
|
The resultCode property is set to CDEV_SUCCESS
to indicate that the call completed successfully.
|
|
}
else output.insert("resultCode", CDEV_NOTFOUND);
}
else if(!strncmp(message->getMessage(), "set ", 4))
{
output.remove();
saveMessageFlag = 0;
sendMessageFlag = 1;
sprintf(key, "%s %s",
message->getDeviceList()[0],
&message->getMessage()[4]);
if((attrib = (VirtualAttrib *)attribHash.find(key))!=NULL)
{
output.insert("resultCode",
attrib->setFromData(message->getData()));
}
else output.insert("resultCode", CDEV_NOTFOUND);
}
else if(!strncmp(message->getMessage(), "monitorOn ", 10))
{
saveMessageFlag = 1;
sendMessageFlag = 0;
sprintf(key, "%s %s",
message->getDeviceList()[0],
&message->getMessage()[10]);
if((attrib = (VirtualAttrib *)attribHash.find(key))!=NULL)
{
attrib->insertMonitor(this, message);
}
}
else if(!strncmp(message->getMessage(), "monitorOff ", 11))
{
saveMessageFlag = 0;
sendMessageFlag = 1;
sprintf(key, "%s %s",
message->getDeviceList()[0],
&message->getMessage()[11]);
if((attrib = (VirtualAttrib *)attribHash.find(key))!=NULL)
{
attrib->removeMonitor(this, message);
}
}
else
{
saveMessageFlag = 0;
sendMessageFlag = 1;
output.insert("resultCode", CDEV_NOTFOUND);
}
if(sendMessageFlag)
|
The sendMessageFlag indicates whether a return message should be provided to the
caller. If the message was a monitorOn request, then the return message has already
been automatically dispatched by the cdevMonitorTable object.
|
|
{
message->setData(&output, 1);
enqueue(message);
}
if(!saveMessageFlag) delete message;
|
If the cdevMessage object was not provided to the cdevMonitorTable to install a monitor,
then it should be deleted.
|
|
}
}
int VirtualServer::fireCallback ( cdevMessage * message )
|
This method is called by the cdevMonitorTable portion of the class
whenever a monitored value has changed. It is only required to enqueue
the cdevMessage object so that it can be returned to the client with the
new value.
|
|
{
int result = CDEV_SUCCESS;
cdevData * data = NULL;
if(message && (data = message->getData())!=NULL)
{
data->insert("resultCode", CDEV_SUCCESS);
result = enqueue(message);
}
return result;
}
void main()
|
The main function creates an instance of the VirtualServer class named
"TestServerX", which will have the Name Server domain "VIRTUAL" and
will listen for incoming requests on port 9120. The processMessages
method will be called automatically at least every 60 seconds.
|
|
{
VirtualServer server("VIRTUAL", "TestServerX", 9120, 60);
cdevServer::runServer();
}
VirtualService.h
|
The VirtualService.h header file describes the structure of the VirtualService that will be loaded by the cdevSystem in order
to accomodate requests made to the VirtualServer.
|
#include <cdevClientService.h>
// *****************************************************************************
// * newVirtualService :
// * This function will be called by the cdevSystem object to create an
// * initial instance of the VirtualService.
// *****************************************************************************
extern "C" cdevService * newVirtualService ( char * name, cdevSystem * system );
|
The newVirtualService function will
create the initial instance of the
VirtualService class.
|
|
// *****************************************************************************
// * class VirtualService :
// * This class simply inherits from the cdevClientService and must define
// * only a constructor and destructor.
// *****************************************************************************
class VirtualService : public cdevClientService
|
The VirtualService class inherits
almost all of its functionality from the
cdevClientService class.
|
|
{
public:
VirtualService ( char * name, cdevSystem & system =
cdevSystem::defaultSystem());
protected:
int RESULT_CODE_TAG;
virtual ~VirtualService ( void ) {};
virtual void fireCallback ( int status, cdevTranObj &xobj, cdevData *resultData );
|
The fireCallback method has been
overloaded in order to allow the
service to copy the resultCode
property from the returned
cdevData object into the
completion status for the
cdevCallback function.
|
|
};
VirtualService.cc
|
This source file implements the classes that are defined in the VirtualService.h header file. The methods that are contained
in this file define the functionality for the VirtualService that is different from what is provided by default by the
cdevClientService class.
|
#include <VirtualService.h>
// *****************************************************************************
// * newVirtualService:
// * This function will be called by the cdevSystem object to create an
// * initial instance of the VirtualService.
// *****************************************************************************
extern "C" cdevService * newVirtualService (char * name, cdevSystem * system)
|
The newVirtualService is called by the
cdevSystem to create an instance of
the VirtualService object.
|
|
{
return new VirtualService(name, *system);
}
// *****************************************************************************
// * VirtualService::VirtualService :
// * This is teh constructor for the VirtualService. It initializes the
// * underlying cdevClientService by specifying that it is in the domain of
// * VIRTUAL.
// *****************************************************************************
VirtualService::VirtualService ( char * name, cdevSystem & system)
|
The constructor for the class will
initialize the underlying
cdevClientService object with the
name of the Name Server domain and
the service name and cdevSystem
parameters.
Additionally the constructor must
declare any tags that it will be using for
communications.
|
|
: cdevClientService("VIRTUAL", name, system)
{
// *********************************************************************
// * Install the RESULT_CODE_TAG at a location of 30 or higher if it
// * does not already exist.
// *********************************************************************
RESULT_CODE_TAG = 0;
cdevData::tagC2I("resultCode", &RESULT_CODE_TAG);
{
cdevData::insertTag(i, "resultCode");
cdevData::tagC2I("resultCode", &RESULT_CODE_TAG);
}
system.reportError(CDEV_SEVERITY_INFO, "VirtualService", NULL,
|
Once initialized the VirtualService will
declare its presence using the
reportError mechanism.
|
|
"Constructing a new VirtualService");
}
// *****************************************************************************
// * VirtualService::fireCallback :
// * This is the method that will be called to dispatch the callback methods
// * that are associated with the calls to the Virtual Server. If the
// * message has been processed successfully, then the method will remove
// * the resultCode from the outbound data and use that as the status.
// *****************************************************************************
void VirtualService::fireCallback ( int status, cdevTranObj &xobj, cdevData *resultData )
{
// *********************************************************************
// * If the message was transmitted successfully, get the result code
// * from the data that was returned and use that as the status.
// *********************************************************************
if(status==CDEV_SUCCESS && resultData!=NULL)
|
Before calling the user defined
callback, this method will copy the
resultCode property of the returned
cdevData object into the status integer
that is provided to the callback
function.
|
|
{
resultData->get(RESULT_CODE_TAG, &status);
resultData->remove(RESULT_CODE_TAG);
}
cdevClientService::fireCallback(status, xobj, resultData);
}
Virtual.ddl
|
This is the device definition file that is used to map the CDEV requests to the VirtualService for transmission to the
VirtualServer.
|
service Virtual
{
tags {server}
}
class Virtuals
{
verbs {get, set, monitorOn, monitorOff}
attributes
{
default Virtual;
servers Virtual;
attrib0 Virtual {server=TestServerX};
attrib1 Virtual {server=TestServerX};
attrib2 Virtual {server=TestServerX};
attrib3 Virtual {server=TestServerX};
attrib4 Virtual {server=TestServerX};
attrib5 Virtual {server=TestServerX};
attrib6 Virtual {server=TestServerX};
attrib7 Virtual {server=TestServerX};
attrib8 Virtual {server=TestServerX};
attrib9 Virtual {server=TestServerX};
}
messages
{
disconnect Virtual;
}
}
Virtuals :
device0, device1, device2, device3, device4,
device5, device6, device7, device8, device9;
|