#include <cdevPlatforms.h>
#include <cdevSystem.h>
#include <cdevRequestObject.h>
#include <cdevDevice.h>
#include <cdevGroup.h>
#include <cdevCommon.h>

int lastHitReceived = 0;
int callbackCount   = 0;
double totalPeriod  = 0.0;

void myCallback1 (int status, void *, cdevRequestObject &, cdevData &)
	{
	if(status==CDEV_SUCCESS) callbackCount++;
	}

void myCallback2 (int status, void *, cdevRequestObject &, cdevData &)
	{
	if(status==CDEV_SUCCESS)
		{
		callbackCount++;
		lastHitReceived++;
		}		 
	}

#define POSTCOUNT 1
#define REPEATCOUNT 2

int main(void)
{
struct timeval first, second, lapsed;
cdevCallback cb1(myCallback1, NULL);
cdevCallback cb2(myCallback2, NULL);

cdevDevice * device[3];

device[0] = cdevDevice::attachPtr("device1");
device[1] = cdevDevice::attachPtr("device2");
device[2] = cdevDevice::attachPtr("device3");
cdevData data;
cdevData context;
int      i,j,k;
int      done = -2;
double   deviceValue[3][3];
char     message[255];

context.insert("value", 3);
for(i=0; i<3; i++)
	{
	for(j=0; j<3; j++)
		{
		sprintf(message, "get attrib%i", j+1);
		device[i]->send(message, NULL, data);
		deviceValue[i][j] = (double)data;
		}
	}		

while(done<0)
	{
	fprintf(stdout, "Posting %i monitors\n", POSTCOUNT*9);
	for(i=0; i<3; i++)
		{
		device[i]->setContext(context);
		for(j=0; j<3; j++)
			{
			sprintf(message, "monitorOn attrib%i", j+1);
			for(k=0; k<POSTCOUNT-1; k++)
				{
				device[i]->sendCallback(message, NULL, cb1);
				}
			device[i]->sendCallback(message, NULL, cb2);
			}
		}

	for(k=0; k<REPEATCOUNT; k++)
		{
		gettimeofday(&first);
		while(lastHitReceived<3) cdevSystem::defaultSystem().pend();
		lastHitReceived = 0;
		gettimeofday(&second);	

		if (first.tv_usec > second.tv_usec) 
			{
			second.tv_usec += 1000000;
			second.tv_sec--;
			}
		lapsed.tv_usec = second.tv_usec - first.tv_usec;
		lapsed.tv_sec = second.tv_sec - first.tv_sec;
		double period = (double)lapsed.tv_sec+(double)lapsed.tv_usec/1000000.00;
		totalPeriod  += period;
		fprintf(stdout, "%i Callbacks in %f seconds (%i pkts/sec - %i pkts/sec cum)\n", 
		        POSTCOUNT*9, period, (int)((double)POSTCOUNT*9.0/period), (int)((double)callbackCount/totalPeriod));

		for(i=0; i<3; i++)
			{
			for(j=0; j<3; j++)
				{
				deviceValue[i][j]+=1.0;
				data.insert("value", deviceValue[i][j]);
				if(k<REPEATCOUNT-1)
					{
					sprintf(message, "set attrib%i", j+1);
					device[i]->sendNoBlock(message, data, NULL);
					}
				}
			}
		}

	fprintf(stdout, "Removing %i monitors\n", POSTCOUNT*9);
	for(i=0; i<3; i++)
		{
		for(j=0; j<3; j++)
			{
			sprintf(message, "monitorOff attrib%i", j+1);
			device[i]->sendCallback(message, NULL, cb1);
			device[i]->sendCallback(message, NULL, cb2);
			}
		}
	done++;
	}
cdevSystem::defaultSystem().poll();

return 0;
}
