Files
sics/counter.c
koennecke fd5451e8fd Enhanced comments in asynnet
Changed required privilege for chnaging the threshold from manager to user in counter.c
Changed an output code in macro.c
2016-10-25 17:03:21 +02:00

1210 lines
33 KiB
C

/*-------------------------------------------------------------------------
C O U N T E R
The SICS Interface to a single detector and his associated
monitors.
Mark Koennecke, January 1997
Copyright:
Labor fuer Neutronenstreuung
Paul Scherrer Institut
CH-5423 Villigen-PSI
The authors hereby grant permission to use, copy, modify, distribute,
and license this software and its documentation for any purpose, provided
that existing copyright notices are retained in all copies and that this
notice is included verbatim in any distributions. No written agreement,
license, or royalty fee is required for any of the authorized uses.
Modifications to this software may be copyrighted by their authors
and need not follow the licensing terms described here, provided that
the new terms are clearly indicated on the first page of each file where
they apply.
IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE
IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
MODIFICATIONS.
----------------------------------------------------------------------------*/
#include <stdlib.h>
#include <assert.h>
#include <math.h>
#include <time.h>
#include "fortify.h"
#include <string.h>
#include "sics.h"
#include "countdriv.h"
#include "counter.h"
#include "fupa.h"
#include "status.h"
#include "splitter.h"
#include "site.h"
/*-------------------------------------------------------------------------*/
/*
The monitor callback data structure
*/
typedef struct {
float fPreset;
float fCurrent;
char *pName;
} MonEvent, *pMonEvent;
/*-----------------------------------------------------------------------------*/
static int Halt(void *pData)
{
pCounter self = NULL;
assert(pData);
self = (pCounter) pData;
return self->pDriv->Halt(self->pDriv);
}
/*-------------------------------------------------------------------------*/
static void SetCounterError(void *pData, char *text)
{
pCounter self = NULL;
assert(pData);
self = (pCounter) pData;
if(self->error != NULL){
free(self->error);
}
self->error = strdup(text);
}
/*--------------------------------------------------------------------------*/
static void SetCountParameters(void *pData, float fPreset,
CounterMode eMode)
{
pCounter self = NULL;
assert(pData);
self = (pCounter) pData;
SetCounterPreset(self, fPreset);
SetCounterMode(self, eMode);
}
/*-----------------------------------------------------------------------*/
static int StartCount(void *pData, SConnection * pCon)
{
pCounter self;
char pBueffel[132];
char pError[80];
int iRet;
int i;
int iErr;
time_t tX;
self = (pCounter) pData;
assert(self);
if (!GetCountLock(self->pCountInt, pCon)) {
return 0;
}
SetCounterError(pData,"None");
/* try at least three times to do it */
for (i = 0; i < 3; i++) {
iRet = self->pDriv->Start(self->pDriv);
if (iRet == OKOK) {
self->isUpToDate = 0;
self->badStatusCount = 0;
self->tStart = time(&tX);
InvokeCallBack(self->pCall, COUNTSTART, pCon);
return iRet;
} else {
iRet = self->pDriv->GetError(self->pDriv, &iErr, pError, 79);
sprintf(pBueffel, "WARNING: %s ", pError);
SCWrite(pCon, pBueffel, eLog);
iRet = self->pDriv->TryAndFixIt(self->pDriv, iErr);
if (iRet == COTERM) {
SCWrite(pCon, "ERROR: Cannot fix counter problem, aborting",
eError);
SCSetInterrupt(pCon, eAbortBatch);
ReleaseCountLock(self->pCountInt);
SetCounterError(pData,pError);
return HWFault;
}
}
}
SCWrite(pCon, "ERROR: Cannot fix counter problem, aborting", eError);
SCSetInterrupt(pCon, eAbortBatch);
ReleaseCountLock(self->pCountInt);
return HWFault;
}
/*-----------------------------------------------------------------------*/
static int PauseCount(void *pData, SConnection * pCon)
{
pCounter self;
char pBueffel[132];
char pError[80];
int iRet;
int i;
int iErr;
self = (pCounter) pData;
assert(self);
/* try at least three times to do it */
for (i = 0; i < 3; i++) {
iRet = self->pDriv->Pause(self->pDriv);
if (iRet == OKOK) {
self->isUpToDate = 0;
return iRet;
} else {
iRet = self->pDriv->GetError(self->pDriv, &iErr, pError, 79);
sprintf(pBueffel, "WARNING: %s ", pError);
SCWrite(pCon, pBueffel, eError);
iRet = self->pDriv->TryAndFixIt(self->pDriv, iErr);
if (iRet == COTERM) {
SCWrite(pCon, "ERROR: Cannot fix counter problem, aborting",
eError);
SCSetInterrupt(pCon, eAbortBatch);
return HWFault;
}
}
}
SCWrite(pCon, "ERROR: Cannot fix counter problem, aborting", eError);
SCSetInterrupt(pCon, eAbortBatch);
return HWFault;
}
/*-----------------------------------------------------------------------*/
static int ContinueCount(void *pData, SConnection * pCon)
{
pCounter self;
char pBueffel[132];
char pError[80];
int iRet;
int i;
int iErr;
self = (pCounter) pData;
assert(self);
/* try at least three times to do it */
for (i = 0; i < 3; i++) {
iRet = self->pDriv->Continue(self->pDriv);
if (iRet == OKOK) {
self->isUpToDate = 0;
return iRet;
} else {
iRet = self->pDriv->GetError(self->pDriv, &iErr, pError, 79);
sprintf(pBueffel, "WARNING: %s ", pError);
SCWrite(pCon, pBueffel, eError);
iRet = self->pDriv->TryAndFixIt(self->pDriv, iErr);
if (iRet == COTERM) {
SCWrite(pCon, "ERROR: Cannot fix counter problem, aborting",
eError);
SCSetInterrupt(pCon, eAbortBatch);
return HWFault;
}
}
}
SCWrite(pCon, "ERROR: Cannot fix counter problem, aborting", eError);
SCSetInterrupt(pCon, eAbortBatch);
return HWFault;
}
/*------------------------------------------------------------------------*/
static int TransferData(void *pData, SConnection * pCon)
{
pCounter self = NULL;
int i, iRet;
char pError[80];
char pBueffel[132];
int iCode;
self = (pCounter) pData;
assert(self);
assert(pCon);
/* try three times */
for (i = 0; i < 3; i++) {
iRet = self->pDriv->ReadValues(self->pDriv);
if (iRet == OKOK) {
self->isUpToDate = 1;
return OKOK;
} else {
self->pDriv->GetError(self->pDriv, &iCode, pError, 79);
sprintf(pBueffel, "WARNING: %s", pError);
SCWrite(pCon, pBueffel, eError);
iRet = self->pDriv->TryAndFixIt(self->pDriv, iCode);
if (iRet == COTERM) {
SCWrite(pCon, "ERROR: Cannot fix counter problem, aborting",
eError);
SCSetInterrupt(pCon, eAbortBatch);
SetCounterError(pData,pError);
return HWFault;
}
}
}
SCWrite(pCon, "ERROR: Cannot fix counter problem, aborting", eError);
SCSetInterrupt(pCon, eAbortBatch);
return HWFault;
}
/*--------------------------------------------------------------------------*/
static int CheckCountStatus(void *pData, SConnection * pCon)
{
pCounter self = NULL;
int i, iRet;
int eCt;
char pError[80], pBueffel[132];
int iErr;
float fControl = .0, rate;
MonEvent sMon;
self = (pCounter) pData;
assert(self);
assert(pCon);
eCt = self->pDriv->GetStatus(self->pDriv, &fControl);
if (eCt == HWFault) {
self->badStatusCount++;
iRet = self->pDriv->GetError(self->pDriv, &iErr, pError, 79);
sprintf(pBueffel, "WARNING: %s ", pError);
SCWrite(pCon, pBueffel, eLog);
iRet = self->pDriv->TryAndFixIt(self->pDriv, iErr);
if (iRet == COTERM || self->badStatusCount > 3) {
SCWrite(pCon, "ERROR: Cannot fix counter problem, aborting", eError);
SCSetInterrupt(pCon, eAbortBatch);
InvokeCallBack(self->pCall, COUNTEND, NULL);
ReleaseCountLock(self->pCountInt);
SetCounterError(pData,pError);
return eCt;
} else {
return HWBusy;
}
}
/* if(self->pDriv->fTime > .0){ */
/* rate = (float)(self->pDriv->lCounts[1])/self->pDriv->fTime; */
/* if(rate > 10000){ */
/* SCWrite(pCon,"WARNING: Your control monitor is running into dead time", */
/* eLogError); */
/* } */
/* } */
/*
handle count parameters and notify listeners on progress
*/
sMon.fCurrent = fControl;
sMon.fPreset = self->pDriv->fPreset;
sMon.pName = self->name;
self->badStatusCount = 0; /* clear: we managed to read OK */
if (self->iCallbackCounter > 20) {
InvokeCallBack(self->pCall, MONITOR, &sMon);
tracePar(self->name,"control:%f", fControl);
self->iCallbackCounter = 0;
} else {
self->iCallbackCounter++;
}
self->pDriv->fLastCurrent = fControl;
/*
notification on finish
*/
if (eCt == HWIdle) {
self->isUpToDate = 0;
TransferData(self,pCon);
InvokeCallBack(self->pCall, COUNTEND, NULL);
ReleaseCountLock(self->pCountInt);
}
return eCt;
}
/*------------------------------------------------------------------------*/
static int SaveCounterStatus(void *pData, char *name, FILE * fd)
{
pCounter self = NULL;
assert(pData);
assert(fd);
self = (pCounter) pData;
fprintf(fd, "# Counter %s\n", name);
fprintf(fd, "%s SetPreset %f\n", name, self->pDriv->fPreset);
if (self->pDriv->eMode == eTimer) {
fprintf(fd, "%s SetMode Timer\n", name);
} else {
fprintf(fd, "%s SetMode Monitor\n", name);
}
return 1;
}
/*------------------------------------------------------------------------*/
static void *CounterGetInterface(void *pData, int iID)
{
pCounter self = NULL;
self = (pCounter) pData;
assert(self);
if (iID == COUNTID) {
return self->pCountInt;
} else if (iID == CALLBACKINTERFACE) {
return self->pCall;
}
return NULL;
}
/*---------------------------------------------------------------------------*/
void DeleteCounter(void *pData)
{
pCounter self = NULL;
assert(pData);
self = (pCounter) pData;
if (self->pDes) {
DeleteDescriptor(self->pDes);
}
if (self->pCountInt) {
free(self->pCountInt);
}
if (self->pCall) {
DeleteCallBackInterface(self->pCall);
}
if (self->name) {
free(self->name);
}
if (self->pDriv) {
DeleteCounterDriver(self->pDriv);
}
free(self);
}
/*-------------------------------------------------------------------------*/
int DoCount(pCounter self, float fPreset, SConnection * pCon, int iBlock)
{
int iRet, level;
char pBueffel[132];
Status eOld;
assert(self);
/* check authorisation */
if (!SCMatchRights(pCon, usUser)) {
sprintf(pBueffel, "ERROR: you are not authorised to count");
SCWrite(pCon, pBueffel, eError);
return 0;
}
/* set Preset */
SetCounterPreset(self, fPreset);
if (iBlock == 0) {
level = RUNRUN;
} else {
level = RUNDRIVE;
}
iRet = StartDevice(GetExecutor(), self->name, self->pDes, self, pCon,
level, fPreset);
if (!iRet) {
SCWrite(pCon, "Counting aborted", eError);
return 0;
}
/* continue only if in blocking mode, or from tas scan (iBlock == 2) */
if (iBlock != 1) {
return 1;
}
/* wait forever until done or interrupted */
iRet = Wait4Success(GetExecutor());
if (iRet == DEVINT) {
SCWrite(pCon, "Counting aborted due to Interrupt", eError);
} else if (iRet == DEVERROR) {
SCWrite(pCon, "Counting finished with Problems", eError);
iRet = 1;
} else {
SCWrite(pCon, "Counting finished", eValue);
iRet = 1;
}
return iRet;
}
/*-------------------------------------------------------------------------*/
int MakeCounter(SConnection * pCon, SicsInterp * pSics, void *pData,
int argc, char *argv[])
{
pCounter pNew = NULL;
pCounterDriver pDriv = NULL;
float fFail = -1;
int iRet;
char pBueffel[256];
pSite site = NULL;
assert(pCon);
assert(pSics);
if (argc < 3) {
SCWrite(pCon, "ERROR: insuficient number of arguments to MakeCounter",
eError);
return 0;
}
strtolower(argv[1]);
strtolower(argv[2]);
site = getSite();
if (site != NULL) {
pDriv = site->CreateCounterDriver(pCon, argc, argv);
}
/*
test for simulation driver, which is for everybody
*/
if (strcmp(argv[2], "sim") == 0) {
if (argc > 3) {
fFail = atof(argv[3]);
pDriv = NewSIMCounter(argv[1], fFail);
}
}
/*
* test for regression testing counter
*/
if (strcmp(argv[2], "regress") == 0) {
pDriv = NewRegressCounter(argv[1]);
}
/*
* test for McStas simulation counter driver
*/
if (strcmp(argv[2], "mcstas") == 0) {
pDriv = NewMcStasCounter(argv[1]);
}
if (!pDriv) {
snprintf(pBueffel,255, "ERROR: cannot create requested driver %s", argv[2]);
SCWrite(pCon, pBueffel, eError);
return 0;
}
/* create Counter and command */
pNew = CreateCounter(argv[1], pDriv);
if (!pNew) {
snprintf(pBueffel, 255,"ERROR: cannot create counter %s", argv[1]);
SCWrite(pCon, pBueffel, eError);
return 0;
}
iRet =
AddCommand(pSics, argv[1], CountAction, DeleteCounter,
(void *) pNew);
if (!iRet) {
snprintf(pBueffel,255, "ERROR: duplicate command %s not created", argv[1]);
SCWrite(pCon, pBueffel, eError);
return 0;
}
return 1;
}
/* --------------------------------------------------------------------------*/
int SetCounterMode(pCounter self, CounterMode eNew)
{
return self->setMode(self,eNew);
}
/*---------------------------------------------------------------------------*/
static int SetCounterModeImpl(pCounter self, CounterMode eNew)
{
int i;
assert(self);
if (eNew == self->pDriv->eMode) {
return 1;
}
if (eNew == eTimer) {
for (i = 0; i < self->iExponent; i++) {
self->pDriv->fPreset /= 10.;
}
tracePar(self->name,"mode:timer");
}
if (eNew == ePreset) {
for (i = 0; i < self->iExponent; i++) {
self->pDriv->fPreset *= 10.;
}
tracePar(self->name,"mode:monitor");
}
self->pDriv->eMode = eNew;
return 1;
}
/*-------------------------------------------------------------------------*/
CounterMode GetCounterMode(pCounter self)
{
return self->getMode(self);
}
/*--------------------------------------------------------------------------*/
static CounterMode GetCounterModeImpl(pCounter self)
{
assert(self);
return self->pDriv->eMode;
}
/*------------------------------------------------------------------------*/
int GetNMonitor(pCounter self)
{
return self->getNMonitor(self);
}
/*------------------------------------------------------------------------*/
static int GetNMonitorImpl(pCounter self)
{
assert(self);
return self->pDriv->iNoOfMonitors;
}
int GetControlMonitor(pCounter self)
{
return self->pDriv->iControlMonitor;
}
int SetControlMonitor(pCounter self, int channel)
{
int maxchan = self->pDriv->iNoOfMonitors - 1;
if (channel < 0 || channel > maxchan) {
return 0;
}
self->pDriv->iControlMonitor = channel;
return 1;
}
#ifdef NONINTF
extern float nintf(float f);
#endif
/*------------------------------------------------------------------------*/
int SetCounterPreset(pCounter self, float fVal)
{
return self->setPreset(self,fVal);
}
/*------------------------------------------------------------------------*/
static int SetCounterPresetImpl(pCounter self, float fVal)
{
int i;
assert(self);
if (fVal < .0) {
return 0;
}
if (GetCounterMode(self) == ePreset) {
for (i = 0; i < self->iExponent; i++) {
fVal *= 10.;
}
fVal = nintf(fVal);
}
self->pDriv->fPreset = fVal;
tracePar(self->name,"preset:%f", fVal);
return 1;
}
/*------------------------------------------------------------------------*/
float GetCounterPreset(pCounter self)
{
return self->getPreset(self);
}
/*------------------------------------------------------------------------*/
float GetControlValue(pCounter self)
{
return self->getControlValue(self);
}
/*------------------------------------------------------------------------*/
static float GetControlValueImpl(pCounter self)
{
return self->pDriv->fLastCurrent;
}
/*------------------------------------------------------------------------*/
static float GetCounterPresetImpl(pCounter self)
{
int i;
float fVal;
assert(self);
fVal = self->pDriv->fPreset;
if (self->pDriv->eMode == ePreset) {
for (i = 0; i < self->iExponent; i++) {
fVal /= 10.;
}
}
return fVal;
}
/*-----------------------------------------------------------------------*/
long GetCounts(pCounter self, SConnection * pCon)
{
return self->getCounts(self, pCon);
}
/*-----------------------------------------------------------------------*/
static long GetCountsImpl(pCounter self, SConnection * pCon)
{
assert(self);
if (!self->isUpToDate) {
self->pCountInt->TransferData(self, pCon);
}
return self->pDriv->lCounts[self->pDriv->iControlMonitor];
}
/*------------------------------------------------------------------------*/
long GetMonitor(pCounter self, int iNum, SConnection * pCon)
{
return self->getMonitor(self, iNum, pCon);
}
/*------------------------------------------------------------------------*/
static long GetMonitorImpl(pCounter self, int iNum, SConnection * pCon)
{
assert(self);
if (!self->isUpToDate) {
self->pCountInt->TransferData(self, pCon);
}
if ((iNum < 0) || (iNum >= self->pDriv->iNoOfMonitors)) {
return -1L;
} else {
return self->pDriv->lCounts[iNum];
}
}
/*-----------------------------------------------------------------------*/
void SetMonitorValue(pCounter self, int index, long value)
{
return self->setMonitor(self, index, value);
}
/*-----------------------------------------------------------------------*/
static void SetMonitorValueImpl(pCounter self, int index, long value)
{
assert(self);
if (index >= 0 && index < self->pDriv->iNoOfMonitors) {
self->pDriv->lCounts[index] = value;
}
}
/*------------------------------------------------------------------------*/
float GetCountTime(pCounter self, SConnection * pCon)
{
return self->getTime(self, pCon);
}
/*------------------------------------------------------------------------*/
static float GetCountTimeImpl(pCounter self, SConnection * pCon)
{
assert(self);
if (!self->isUpToDate) {
self->pCountInt->TransferData(self, pCon);
}
return self->pDriv->fTime;
}
/*----------------------------------------------------------------------*/
static int isAuthorised(SConnection * pCon, int iCode)
{
char pBueffel[132];
if (!SCMatchRights(pCon, iCode)) {
sprintf(pBueffel, "ERROR: you are not authorised to count");
SCWrite(pCon, pBueffel, eError);
return 0;
}
return 1;
}
/*-----------------------------------------------------------------------*/
int CounterInterest(int iEvent, void *pEvent, void *pUser)
{
SConnection *pCon = NULL;
pMonEvent pMon = NULL;
char pBueffel[512];
int rights;
pCon = (SConnection *) pUser;
pMon = (pMonEvent) pEvent;
if (pCon == NULL || !SCisConnected(pCon)) {
return -1;
}
if (iEvent != MONITOR || pCon == NULL) {
return 0;
}
snprintf(pBueffel,511, "%s.CountStatus = %f %d", pMon->pName, pMon->fPreset,
(int) nintf(pMon->fCurrent));
/**
* prevent this to be written to log files
*/
SCSetRights(pCon, usSpy);
SCWrite(pCon, pBueffel, eEvent);
return 1;
}
/*------------------------------------------------------------------------*/
pCounter CreateCounter(char *name, pCounterDriver pDriv)
{
pCounter pRes = NULL;
assert(pDriv);
pRes = (pCounter) malloc(sizeof(Counter));
if (!pRes) {
return NULL;
}
pRes->pDes = CreateDescriptor("SingleCounter");
if (!pRes->pDes) {
free(pRes);
return NULL;
}
/* initialize Descriptor functions */
pRes->pDes->GetInterface = CounterGetInterface;
pRes->pDes->SaveStatus = SaveCounterStatus;
/* initialise countable interface */
pRes->pCountInt = CreateCountableInterface();
if (!pRes->pCountInt) {
DeleteDescriptor(pRes->pDes);
free(pRes);
return NULL;
}
pRes->pCountInt->SetCountParameters = SetCountParameters;
pRes->pCountInt->StartCount = StartCount;
pRes->pCountInt->CheckCountStatus = CheckCountStatus;
pRes->pCountInt->TransferData = TransferData;
pRes->pCountInt->Halt = Halt;
pRes->pCountInt->Pause = PauseCount;
pRes->pCountInt->Continue = ContinueCount;
pRes->iCallbackCounter = 20;
pRes->setMode = SetCounterModeImpl;
pRes->getMode = GetCounterModeImpl;
pRes->getNMonitor = GetNMonitorImpl;
pRes->setPreset = SetCounterPresetImpl;
pRes->getPreset = GetCounterPresetImpl;
pRes->getControlValue = GetControlValueImpl;
pRes->getCounts = GetCountsImpl;
pRes->getMonitor = GetMonitorImpl;
pRes->setMonitor = SetMonitorValueImpl;
pRes->getTime = GetCountTimeImpl;
pRes->pCall = CreateCallBackInterface();
pRes->pDriv = pDriv;
pRes->isUpToDate = 1;
pRes->iExponent = 0;
pRes->name = strdup(name);
pRes->error = strdup("None");
return pRes;
}
/*-----------------------------------------------------------------------*/
int CountAction(SConnection * pCon, SicsInterp * pSics, void *pData,
int argc, char *argv[])
{
pCounter self = NULL;
int iRet, iRet2, i;
FuPaResult PaRes;
char pBueffel[256], pError[80];
char **argx;
float fVal;
long lVal;
long lID;
CounterMode eMode;
FuncTemplate ActionTemplate[] = {
{"count", 1, {FUPAFLOAT}},
{"getpreset", 0, {0.0}},
{"setpreset", 1, {FUPAFLOAT}},
{"getmode", 0, {0, 0}},
{"setmode", 1, {FUPATEXT}},
{"getcounts", 0, {0, 0}},
{"getmonitor", 1, {FUPAINT, 0}},
{"setexponent", 1, {FUPAINT, 0}},
{"getexponent", 0, {0, 0}},
{"interest", 0, {0, 0}},
{"uninterest", 0, {0, 0}},
{"status", 0, {0, 0}},
{"gettime", 0, {0, 0}},
{"countnb", 1, {FUPAFLOAT}},
{"getthreshold", 1, {FUPAINT}},
{"setthreshold", 2, {FUPAINT, FUPAFLOAT}},
{"stop", 0, {0, 0}},
{"mode", 1, {FUPAOPT}},
{"preset", 1, {FUPAOPT}},
{"send", 0, {0, 0}},
{"setpar", 3, {FUPATEXT, FUPAINT, FUPAFLOAT}},
{"getpar", 2, {FUPATEXT, FUPAOPT}},
{"getnmon", 0, {0, 0}},
{"state", 0, {0, 0}},
{"error", 0, {0, 0}},
{"getchannel",0,{0}},
{"setchannel",1,{FUPAINT}},
{"countstatus", 0, {0, 0}}
};
char *pMode[] = {
"timer",
"monitor",
NULL
};
self = (pCounter) pData;
assert(self);
assert(pCon);
assert(pSics);
/* parse function args */
argtolower(argc, argv);
argx = &argv[1];
iRet =
EvaluateFuPa((pFuncTemplate) & ActionTemplate, 28, argc - 1, argx,
&PaRes);
if (iRet < 0) {
snprintf(pBueffel, 255,"%s", PaRes.pError);
SCWrite(pCon, pBueffel, eError);
return 0;
}
/* do something! */
switch (iRet) {
case 0: /* Count */
return DoCount(self, PaRes.Arg[0].fVal, pCon, 1);
break;
case 1: /* GetPreset */
fVal = GetCounterPreset(self);
sprintf(pBueffel, "%s.Preset = %f", argv[0], fVal);
SCWrite(pCon, pBueffel, eValue);
return 1;
break;
case 2: /* Set Preset */
if (isRunning(self->pCountInt)) {
SCWrite(pCon, "ERROR: cannot change preset while counting", eError);
return 0;
}
if (isAuthorised(pCon, usUser)) {
iRet2 = SetCounterPreset(self, PaRes.Arg[0].fVal);
SCparChange(pCon);
if (iRet2)
SCSendOK(pCon);
return iRet2;
} else {
return 0;
}
break;
case 3: /* GetMode */
eMode = GetCounterMode(self);
if (eMode == eTimer) {
sprintf(pBueffel, "%s.Mode = Timer", argv[0]);
} else {
sprintf(pBueffel, "%s.Mode = Monitor", argv[0]);
}
SCWrite(pCon, pBueffel, eValue);
return 1;
break;
case 4: /* Set Mode */
if (isRunning(self->pCountInt)) {
SCWrite(pCon, "ERROR: cannot change mode while counting", eError);
return 0;
}
if (isAuthorised(pCon, usUser)) {
if (strcmp(PaRes.Arg[0].text, "timer") == 0) {
SetCounterMode(self, eTimer);
SCparChange(pCon);
SCSendOK(pCon);
return 1;
} else if (strcmp(PaRes.Arg[0].text, "monitor") == 0) {
SetCounterMode(self, ePreset);
SCparChange(pCon);
SCSendOK(pCon);
return 1;
} else {
snprintf(pBueffel,255, "ERROR: %s not recognized as valid counter mode",
PaRes.Arg[0].text);
SCWrite(pCon, pBueffel, eError);
return 0;
}
} else {
return 0;
}
case 5: /* GetCounts */
lVal = GetCounts(self, pCon);
sprintf(pBueffel, "%s.Counts = %ld", argv[0], lVal);
SCWrite(pCon, pBueffel, eValue);
return 1;
case 6: /* GetMonitor */
lVal = GetMonitor(self, PaRes.Arg[0].iVal, pCon);
if (lVal < 0) {
sprintf(pBueffel, "ERROR: %d out of range for monitors",
PaRes.Arg[0].iVal);
SCWrite(pCon, pBueffel, eError);
return 0;
}
sprintf(pBueffel, "%s.Monitor %d = %ld", argv[0], PaRes.Arg[0].iVal,
lVal);
SCWrite(pCon, pBueffel, eValue);
return 1;
case 7: /* SetExponent */
if (!SCMatchRights(pCon, usMugger)) {
return 0;
}
self->iExponent = PaRes.Arg[0].iVal;
SCparChange(pCon);
SCSendOK(pCon);
return 1;
case 8: /* GetExponent */
sprintf(pBueffel, "%s.Exponent = %d", argv[0], self->iExponent);
SCWrite(pCon, pBueffel, eValue);
return 1;
case 9: /* interest */
lID = RegisterCallback(self->pCall, MONITOR, CounterInterest,
SCCopyConnection(pCon), SCDeleteConnection);
SCSendOK(pCon);
return 1;
case 10: /* uninterest */
RemoveCallbackCon(self->pCall, pCon);
SCSendOK(pCon);
return 1;
case 11: /* status */
case 27:
self->pCountInt->TransferData(self, pCon);
if (GetCounterMode(self) == ePreset) {
lVal = GetCounterPreset(self);
for(i = 0; i < self->iExponent; i++){
lVal *= 10;
}
sprintf(pBueffel, "%s.CountStatus = %d %d Beam: %ld E6",
argv[0],
(int) nintf(lVal),
(int) nintf(GetControlValue(self)),
GetMonitor(self, 4, pCon) / 100000);
} else {
sprintf(pBueffel, "%s.CountStatus = %8.2f %8.2f Beam %ld E6",
argv[0],
self->pDriv->fPreset,
self->pDriv->fLastCurrent,
GetMonitor(self, 4, pCon) / 100000);
}
SCWrite(pCon, pBueffel, eValue);
return 1;
case 12: /* gettime */
fVal = GetCountTime(self, pCon);
sprintf(pBueffel, "%s.CountTime = %f", argv[0], fVal);
SCWrite(pCon, pBueffel, eValue);
return 1;
case 13:
/* countnb, non blocking count */
return DoCount(self, PaRes.Arg[0].fVal, pCon, 0);
break;
case 14:
/* get threshold value */
iRet = self->pDriv->Get(self->pDriv, "threshold",
PaRes.Arg[0].iVal, &fVal);
if (iRet <= 0) {
self->pDriv->GetError(self->pDriv, &iRet, pError, 79);
sprintf(pBueffel, "ERROR: %s", pError);
SCWrite(pCon, pBueffel, eError);
return 0;
} else {
sprintf(pBueffel, "%s.threshold%1.1d = %f",
argv[0], PaRes.Arg[0].iVal, fVal);
SCWrite(pCon, pBueffel, eValue);
return 1;
}
break;
case 15:
if (!SCMatchRights(pCon, usUser)) {
SCWrite(pCon,
"ERROR: Insufficient privilege to set threshold", eError);
return 0;
}
if (isRunning(self->pCountInt)) {
SCWrite(pCon,
"ERROR: cannot change threshold while counting",
eError);
return 0;
}
/* set threshold value */
iRet = self->pDriv->Set(self->pDriv, "threshold",
PaRes.Arg[0].iVal, PaRes.Arg[1].fVal);
if (iRet <= 0) {
self->pDriv->GetError(self->pDriv, &iRet, pError, 79);
sprintf(pBueffel, "ERROR: %s", pError);
SCWrite(pCon, pBueffel, eError);
return 0;
} else {
SCparChange(pCon);
SCSendOK(pCon);
return 1;
}
break;
case 16:
/* stop */
if (!SCMatchRights(pCon, usUser)) {
return 0;
}
self->pCountInt->Halt(self);
SCSendOK(pCon);
return 1;
case 17:
/* mode */
if (PaRes.Arg[0].iVal) { /* set case */
if (isRunning(self->pCountInt)) {
SCWrite(pCon, "ERROR: cannot change mode while counting", eError);
return 0;
}
if (isAuthorised(pCon, usUser)) {
if (strcmp(PaRes.Arg[0].text, "timer") == 0) {
SetCounterMode(self, eTimer);
SCparChange(pCon);
SCSendOK(pCon);
return 1;
} else if (strcmp(PaRes.Arg[0].text, "monitor") == 0) {
SetCounterMode(self, ePreset);
SCparChange(pCon);
SCSendOK(pCon);
return 1;
} else {
snprintf(pBueffel,255,
"ERROR: %s not recognized as valid counter mode",
PaRes.Arg[0].text);
SCWrite(pCon, pBueffel, eError);
return 0;
}
}
} else { /* get case */
eMode = GetCounterMode(self);
if (eMode == eTimer) {
sprintf(pBueffel, "%s.Mode = Timer", argv[0]);
} else {
sprintf(pBueffel, "%s.Mode = Monitor", argv[0]);
}
SCWrite(pCon, pBueffel, eValue);
return 1;
break;
}
break;
case 18: /* preset */
if (PaRes.Arg[0].iVal) { /* set case */
if (isRunning(self->pCountInt)) {
SCWrite(pCon, "ERROR: cannot set preset while counting", eError);
return 0;
}
if (isAuthorised(pCon, usUser)) {
iRet2 = SetCounterPreset(self, PaRes.Arg[0].fVal);
if (iRet2)
SCSendOK(pCon);
SCparChange(pCon);
return iRet2;
} else {
return 0;
}
} else { /* read case */
fVal = GetCounterPreset(self);
sprintf(pBueffel, "%s.Preset = %f", argv[0], fVal);
SCWrite(pCon, pBueffel, eValue);
return 1;
}
break;
case 19: /* send */
/* only manager may use this */
if (!SCMatchRights(pCon, usMugger)) {
return 0;
}
Arg2Text(argc - 2, &argv[2], pError, 79);
iRet = self->pDriv->Send(self->pDriv, pError, pBueffel, 255);
if (iRet == 1) {
SCWrite(pCon, pBueffel, eValue);
return 1;
} else {
self->pDriv->GetError(self->pDriv, &iRet, pError, 79);
SCWrite(pCon, pError, eError);
return 0;
}
break;
case 20: /* setpar */
if (isRunning(self->pCountInt)) {
SCWrite(pCon, "ERROR: cannot change parameters while counting",
eError);
return 0;
}
if (!SCMatchRights(pCon, usMugger)) {
return 0;
}
iRet = self->pDriv->Set(self->pDriv, PaRes.Arg[0].text,
PaRes.Arg[1].iVal, PaRes.Arg[2].fVal);
if (iRet == 1) {
SCparChange(pCon);
SCSendOK(pCon);
return 1;
} else {
self->pDriv->GetError(self->pDriv, &iRet, pError, 79);
SCWrite(pCon, pError, eError);
return 0;
}
break;
case 21: /* getpar */
if (!SCMatchRights(pCon, usMugger)) {
return 0;
}
iRet = self->pDriv->Get(self->pDriv, PaRes.Arg[0].text,
PaRes.Arg[1].iVal, &fVal);
if (iRet == 1) {
snprintf(pBueffel,255, "%s.%s %s = %f", argv[0], PaRes.Arg[0].text,
PaRes.Arg[1].text, fVal);
SCWrite(pCon, pBueffel, eValue);
return 1;
} else {
self->pDriv->GetError(self->pDriv, &iRet, pError, 79);
SCWrite(pCon, pError, eError);
return 0;
}
break;
case 22: /* getnmon */
snprintf(pBueffel, 131, "%s.getnmon = %d", argv[0], GetNMonitor(self));
SCWrite(pCon, pBueffel, eValue);
break;
case 23: /* state */
if(isRunning(self->pCountInt)){
snprintf(pBueffel, 131, "%s.state = run", argv[0]);
} else {
snprintf(pBueffel, 131, "%s.state = idle", argv[0]);
}
SCWrite(pCon, pBueffel, eValue);
return 1;
break;
case 24: /* error */
snprintf(pBueffel, 131, "%s.error = %s", argv[0],self->error);
SCWrite(pCon, pBueffel, eValue);
return 1;
break;
case 25: /* getchannel */
snprintf(pBueffel,131,"%s.getchannel = %d", argv[0], GetControlMonitor(self));
SCWrite(pCon,pBueffel,eValue);
return 1;
break;
case 26: /* setchannel */
if (SetControlMonitor(self, PaRes.Arg[0].iVal)) {
return 1;
} else {
SCWrite(pCon,"ERROR: Invalid channel id",eError);
return 0;
}
break;
default:
assert(0); /* internal error */
}
return 0;
}