Initial revision
This commit is contained in:
792
sps.c
Normal file
792
sps.c
Normal file
@@ -0,0 +1,792 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
S P S
|
||||
|
||||
Implementation file for the SICS module handling Siemens SPS controllers
|
||||
at SinQ.
|
||||
|
||||
copyright: see copyright.h
|
||||
I cannot imagine that somebody wants this. It is highly special for SINQ.
|
||||
It handles a protocoll tailor made by Siemens for Sinq. I cannot imagine
|
||||
that somebody wants something from Siemens anyway.
|
||||
|
||||
|
||||
Mark Koennnecke, Juli 1998
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <tcl.h>
|
||||
#include "fortify.h"
|
||||
#include "hardsup/serialsinq.h"
|
||||
#include "sics.h"
|
||||
#include "lld.h"
|
||||
#include "bit.h"
|
||||
#include "sps.i"
|
||||
#include "sps.h"
|
||||
|
||||
/*--------------------- some internal defines ----------------------------*/
|
||||
#define SPSOFFLINE -10
|
||||
#define COMMDEAD -11
|
||||
#define COMMRECONNECT -12
|
||||
#define COMMTMO -13
|
||||
/*-------------------------------------------------------------------------*/
|
||||
static float SimRandom(void)
|
||||
{
|
||||
float fVal;
|
||||
|
||||
fVal = ( (float) rand() / (float)RAND_MAX) * 100.0;
|
||||
return fVal;
|
||||
}
|
||||
/*--------------------- static functions ---------------------------------*/
|
||||
static int init(pSPS self)
|
||||
{
|
||||
int iRet;
|
||||
|
||||
assert(self);
|
||||
assert(self->pHost);
|
||||
|
||||
/* check if in simulation mode */
|
||||
if(self->iMode)
|
||||
return 1;
|
||||
|
||||
/* open the port */
|
||||
iRet = SerialOpen(&self->pData, self->pHost, self->iPort, self->iChannel);
|
||||
if((iRet != 1) || (self->pData == NULL) )
|
||||
{
|
||||
self->iLastError = COMMDEAD;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* configure terminators */
|
||||
SerialATerm(&self->pData, "1\r\n");
|
||||
SerialSendTerm(&self->pData,"\r\n");
|
||||
|
||||
return 1;
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
static int SPSCommand(pSPS self, char *pCommand, char *pReply,
|
||||
int iReplyLen)
|
||||
{
|
||||
int iRet, i;
|
||||
|
||||
assert(self);
|
||||
assert(pCommand);
|
||||
assert(pReply);
|
||||
|
||||
/* Send command. If failure try to reconnect and try again. If
|
||||
still in trouble then, give up
|
||||
*/
|
||||
iRet = SerialWriteRead(&self->pData,pCommand,pReply,iReplyLen);
|
||||
if(iRet != 1)
|
||||
{
|
||||
switch(iRet)
|
||||
{
|
||||
case TIMEOUT:
|
||||
self->iLastError = COMMTMO;
|
||||
return 0;
|
||||
break;
|
||||
default:
|
||||
self->iLastError = iRet;
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* now we may still have a TMO or OFL message */
|
||||
if(strstr(pReply,"?TMO") != NULL)
|
||||
{
|
||||
self->iLastError = COMMTMO;
|
||||
return 0;
|
||||
}
|
||||
if(strstr(pReply,"?OFL") != NULL)
|
||||
{
|
||||
self->iLastError = SPSOFFLINE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int SPSSetButton(pSPS self, SConnection *pCon, int iByte, int iBit)
|
||||
{
|
||||
Permission perm;
|
||||
char pCommand[30];
|
||||
char pBueffel[256];
|
||||
int iRet, iTest,i;
|
||||
|
||||
assert(self);
|
||||
assert(pCon);
|
||||
|
||||
|
||||
/* first check permissions */
|
||||
iRet = LLDnodePtr2First(self->lPermissions);
|
||||
iTest = 0;
|
||||
while(iRet != 0)
|
||||
{
|
||||
LLDnodeDataTo(self->lPermissions,&perm);
|
||||
if(perm.iByte == iByte)
|
||||
{
|
||||
if(perm.iBit == iBit)
|
||||
{
|
||||
iTest = SCMatchRights(pCon,perm.iPrivilege);
|
||||
break;
|
||||
}
|
||||
}
|
||||
iRet = LLDnodePtr2Next(self->lPermissions);
|
||||
}
|
||||
if(!iTest)
|
||||
{
|
||||
sprintf(pBueffel,"ERROR: you have no permission to flip %d.%d",
|
||||
iByte,iBit);
|
||||
SCWrite(pCon,pBueffel,eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* if in sim mode, return true */
|
||||
if(self->iMode)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* format command and send a command to set a bit through the
|
||||
drain in order to simulate a button press
|
||||
*/
|
||||
sprintf(pCommand,"S%3.3d%1.1d",iByte,iBit);
|
||||
iRet = SPSCommand(self,pCommand,pBueffel,255);
|
||||
if(!iRet)
|
||||
{
|
||||
SCWrite(pCon,pBueffel,eError);
|
||||
SCWrite(pCon,"ERROR: Sending flip command failed",eError);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int SPSGetStatus(pSPS self, int iStatus, int *iSet)
|
||||
{
|
||||
int iRet, i, i2, iVal;
|
||||
unsigned char pByte[16];
|
||||
char pBueffel[256], pNum[10];
|
||||
char *pPtr;
|
||||
unsigned char cBit, cMask;
|
||||
|
||||
assert(self);
|
||||
|
||||
if((iStatus < 0) || (iStatus >= 128) )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* if in simulation mode, return a random number */
|
||||
if(self->iMode)
|
||||
{
|
||||
if(SimRandom() >= 50.)
|
||||
{
|
||||
*iSet = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
*iSet = 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* send an R command down to the SPS */
|
||||
iRet = SPSCommand(self,"R",pBueffel,255);
|
||||
if(!iRet)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* decode the reply into the Byte array */
|
||||
pPtr = pBueffel;
|
||||
if(*pPtr != 'R')
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
pPtr++;
|
||||
for(i = 0; i < 16; i++)
|
||||
{
|
||||
/* skip the whitespace */
|
||||
pPtr++;
|
||||
pNum[0] = *pPtr;
|
||||
pPtr++;
|
||||
pNum[1] = *pPtr;
|
||||
pPtr++;
|
||||
pNum[2] = *pPtr;
|
||||
pPtr++;
|
||||
pNum[3] = '\0';
|
||||
pByte[i] = atoi(pNum);
|
||||
}
|
||||
|
||||
/* test the bit */
|
||||
i = iStatus / 8;
|
||||
cBit = pByte[i];
|
||||
i2 = iStatus % 8;
|
||||
cMask = 1 << i2;
|
||||
|
||||
/*
|
||||
printf("Byte %d, Value %d, Bit %d, Value: %d\n", i,cBit, i2, (cBit & cMask));
|
||||
*/
|
||||
|
||||
if((cBit & cMask) > 0 )
|
||||
{
|
||||
*iSet = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
*iSet = 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/*-------------------------------------------------------------------------
|
||||
This is a special feature for SANS at SINQ. SANS has a collimator and
|
||||
the length of the collimator can only be deduced from the SPS status
|
||||
message by checking each of nine segments separately. For efficiency
|
||||
this is coded into a special function for SANS. This also needs a special
|
||||
function for testing bits.
|
||||
|
||||
Mark Koennecke, April 1999
|
||||
*/
|
||||
static int TestBit(unsigned char cByte, int iBit)
|
||||
{
|
||||
unsigned char cMask;
|
||||
|
||||
assert(iBit >= 0);
|
||||
assert(iBit < 8);
|
||||
|
||||
cMask = 1 << iBit;
|
||||
if( (cMask & cByte) > 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------------------*/
|
||||
int SPSGetSANS(pSPS self, float *fLength)
|
||||
{
|
||||
int iRet, i, i2, iVal;
|
||||
unsigned char pByte[16];
|
||||
char pBueffel[256], pNum[10];
|
||||
char *pPtr;
|
||||
unsigned char cBit, cMask;
|
||||
float fLang;
|
||||
|
||||
assert(self);
|
||||
|
||||
/* if in simulation mode, return a random number */
|
||||
if(self->iMode)
|
||||
{
|
||||
*fLength = SimRandom();
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* send an R command down to the SPS */
|
||||
iRet = SPSCommand(self,"R",pBueffel,255);
|
||||
if(!iRet)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* decode the reply into the Byte array */
|
||||
pPtr = pBueffel;
|
||||
if(*pPtr != 'R')
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
pPtr++;
|
||||
for(i = 0; i < 16; i++)
|
||||
{
|
||||
/* skip the whitespace */
|
||||
pPtr++;
|
||||
pNum[0] = *pPtr;
|
||||
pPtr++;
|
||||
pNum[1] = *pPtr;
|
||||
pPtr++;
|
||||
pNum[2] = *pPtr;
|
||||
pPtr++;
|
||||
pNum[3] = '\0';
|
||||
pByte[i] = atoi(pNum);
|
||||
}
|
||||
|
||||
fLang = 189.;
|
||||
if(TestBit(pByte[0],1) > 0)
|
||||
{
|
||||
fLang = 18.;
|
||||
}
|
||||
/* coll 1 15m */
|
||||
if(TestBit(pByte[0],3) > 0)
|
||||
{
|
||||
fLang = 15.;
|
||||
}
|
||||
/* coll 2 11 m*/
|
||||
if(TestBit(pByte[0],7) > 0)
|
||||
{
|
||||
fLang = 11.;
|
||||
}
|
||||
/* coll 3 8 m*/
|
||||
if(TestBit(pByte[1],3) > 0)
|
||||
{
|
||||
fLang -= 3.;
|
||||
}
|
||||
/* coll 4 6m */
|
||||
if(TestBit(pByte[1],7) > 0)
|
||||
{
|
||||
fLang -= 2.;
|
||||
}
|
||||
/* coll 5 4.5 m */
|
||||
if(TestBit(pByte[2],3) > 0)
|
||||
{
|
||||
fLang -= 1.5;
|
||||
}
|
||||
/* coll 6 3 m*/
|
||||
if(TestBit(pByte[2],7) > 0)
|
||||
{
|
||||
fLang -= 1.5;
|
||||
}
|
||||
/* coll 7 */
|
||||
if(TestBit(pByte[3],3) > 0)
|
||||
{
|
||||
fLang -= 1.;
|
||||
}
|
||||
/* coll 8 */
|
||||
if(TestBit(pByte[3],6) > 0)
|
||||
{
|
||||
fLang -= 1.;
|
||||
}
|
||||
if(TestBit(pByte[3],7) > 0)
|
||||
{
|
||||
fLang -= 0.6;
|
||||
}
|
||||
*fLength = fLang;
|
||||
return 1;
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int SPSGetADC(pSPS self, int iWhich, int *iValue)
|
||||
{
|
||||
int iADC[8];
|
||||
int i, iRet;
|
||||
char *pPtr, pBueffel[256], pNum[10];
|
||||
|
||||
assert(self);
|
||||
|
||||
/* check iWhich */
|
||||
if( (iWhich < 0) || (iWhich > 7) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* give a random number in simulation mode */
|
||||
if(self->iMode)
|
||||
{
|
||||
*iValue = (int)SimRandom();
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* send an A command to the box */
|
||||
iRet = SPSCommand(self,"A",pBueffel,255);
|
||||
if(!iRet)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* decode the result */
|
||||
pPtr = pBueffel;
|
||||
if(*pPtr != 'A') /* a silly answer was returned */
|
||||
{
|
||||
SICSLogWrite("SPS: Silly answer in SPSGetADC",eError);
|
||||
return 0;
|
||||
}
|
||||
pPtr++;
|
||||
for(i = 0; i < 8; i++)
|
||||
{
|
||||
pPtr++; /* skip whitespace */
|
||||
strncpy(pNum,pPtr,5);
|
||||
pNum[5] = '\0';
|
||||
pPtr += 5;
|
||||
iADC[i] = atoi(pNum);
|
||||
}
|
||||
|
||||
/* now give the value */
|
||||
*iValue = iADC[iWhich];
|
||||
return 1;
|
||||
}
|
||||
/*-----------------------------------------------------------------------*/
|
||||
void SPSAddPermission(pSPS self, int iByte, int iBit, int iRights)
|
||||
{
|
||||
Permission perm;
|
||||
|
||||
assert(self);
|
||||
|
||||
perm.iByte = iByte;
|
||||
perm.iBit = iBit;
|
||||
perm.iPrivilege = iRights;
|
||||
|
||||
LLDnodeAppendFrom(self->lPermissions,&perm);
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
void RemoveSPS(void *pData)
|
||||
{
|
||||
pSPS self = NULL;
|
||||
|
||||
self = (pSPS)pData;
|
||||
|
||||
if(!self)
|
||||
return;
|
||||
|
||||
if(self->pHost)
|
||||
{
|
||||
free(self->pHost);
|
||||
}
|
||||
|
||||
SerialClose(&self->pData);
|
||||
if(self->pDes)
|
||||
{
|
||||
DeleteDescriptor(self->pDes);
|
||||
}
|
||||
LLDdelete(self->lPermissions);
|
||||
free(self);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int SPSFactory(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[])
|
||||
{
|
||||
int iRet, iVal;
|
||||
pSPS pNew = NULL;
|
||||
char pBueffel[256];
|
||||
|
||||
assert(pCon);
|
||||
assert(pSics);
|
||||
|
||||
/* we need at least two extra arguments: name and either host or sim */
|
||||
if(argc < 3)
|
||||
{
|
||||
SCWrite(pCon,
|
||||
"ERROR: Insufficient number of arguments for installing SPS",
|
||||
eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* allocate a new SPS */
|
||||
pNew = (pSPS)malloc(sizeof(SPS));
|
||||
if(!pNew)
|
||||
{
|
||||
SCWrite(pCon,"ERROR: no memory to allocate SPS",eError);
|
||||
return 0;
|
||||
}
|
||||
memset(pNew,0,sizeof(SPS));
|
||||
pNew->pDes = CreateDescriptor("SPS");
|
||||
pNew->lPermissions = LLDcreate(sizeof(Permission));
|
||||
if( (!pNew->pDes) || (pNew->lPermissions < 0) )
|
||||
{
|
||||
SCWrite(pCon,"ERROR: no memory to allocate SPS",eError);
|
||||
return 0;
|
||||
}
|
||||
pNew->pHost = strdup(argv[2]);
|
||||
|
||||
/* check if we go for sim */
|
||||
strtolower(argv[2]);
|
||||
if(strcmp(argv[2],"sim") == 0)
|
||||
{
|
||||
pNew->iMode = 1;
|
||||
}
|
||||
else /* we are installing a real one and need tons more arguments */
|
||||
{
|
||||
if(argc < 5)
|
||||
{
|
||||
SCWrite(pCon,
|
||||
"ERROR: Insufficient number of arguments for installing SPS",
|
||||
eError);
|
||||
RemoveSPS(pNew);
|
||||
return 0;
|
||||
}
|
||||
/* get port number */
|
||||
iRet = Tcl_GetInt(pSics->pTcl,argv[3],&iVal);
|
||||
if(iRet != TCL_OK)
|
||||
{
|
||||
sprintf(pBueffel,"ERROR: expected integer argument for port, got %s",
|
||||
argv[3]);
|
||||
SCWrite(pCon,pBueffel,eError);
|
||||
RemoveSPS(pNew);
|
||||
return 0;
|
||||
}
|
||||
pNew->iPort = iVal;
|
||||
|
||||
/* get channel number */
|
||||
iRet = Tcl_GetInt(pSics->pTcl,argv[4],&iVal);
|
||||
if(iRet != TCL_OK)
|
||||
{
|
||||
sprintf(pBueffel,"ERROR: expected integer argument for channel, got %s",
|
||||
argv[4]);
|
||||
SCWrite(pCon,pBueffel,eError);
|
||||
RemoveSPS(pNew);
|
||||
return 0;
|
||||
}
|
||||
pNew->iChannel = iVal;
|
||||
}
|
||||
|
||||
/* initialise */
|
||||
iRet = init(pNew);
|
||||
if(!iRet)
|
||||
{
|
||||
SCWrite(pCon,"ERROR: Failure to initialise SPS controller",eError);
|
||||
RemoveSPS(pNew);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* install command */
|
||||
iRet = AddCommand(pSics, argv[1],SPSAction,RemoveSPS,pNew);
|
||||
if(!iRet)
|
||||
{
|
||||
sprintf(pBueffel,"ERROR: duplicate SPS command %s NOT created",
|
||||
argv[1]);
|
||||
SCWrite(pCon,pBueffel,eError);
|
||||
RemoveSPS(pNew);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
#include "access.c"
|
||||
/*-------------------------------------------------------------------------*/
|
||||
int SPSAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[])
|
||||
{
|
||||
pSPS self = NULL;
|
||||
char pBueffel[256];
|
||||
int iByte, iBit, iSet;
|
||||
int iRet, i;
|
||||
float fLang;
|
||||
|
||||
self = (pSPS)pData;
|
||||
assert(self);
|
||||
|
||||
/* we need at least 3 arguments */
|
||||
if(argc < 2)
|
||||
{
|
||||
sprintf(pBueffel,"ERROR: need at least two arguments to %s",
|
||||
argv[0]);
|
||||
SCWrite(pCon,pBueffel,eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* do something according to key word */
|
||||
strtolower(argv[1]);
|
||||
if(strcmp(argv[1],"push") == 0) /* operate a button */
|
||||
{
|
||||
/* four arguments needed */
|
||||
if(argc < 4)
|
||||
{
|
||||
sprintf(pBueffel,"ERROR: need at least two arguments to %s push",
|
||||
argv[0]);
|
||||
SCWrite(pCon,pBueffel,eError);
|
||||
return 0;
|
||||
}
|
||||
/* convert arguments */
|
||||
iRet = Tcl_GetInt(pSics->pTcl,argv[2],&iByte);
|
||||
if(iRet != TCL_OK)
|
||||
{
|
||||
sprintf(pBueffel,"ERROR: expected integer argument for byte, got %s",
|
||||
argv[2]);
|
||||
SCWrite(pCon,pBueffel,eError);
|
||||
return 0;
|
||||
}
|
||||
iRet = Tcl_GetInt(pSics->pTcl,argv[3],&iBit);
|
||||
if(iRet != TCL_OK)
|
||||
{
|
||||
sprintf(pBueffel,"ERROR: expected integer argument for bit, got %s",
|
||||
argv[3]);
|
||||
SCWrite(pCon,pBueffel,eError);
|
||||
return 0;
|
||||
}
|
||||
/* try it */
|
||||
iRet = SPSSetButton(self,pCon,iByte,iBit);
|
||||
if(!iRet)
|
||||
{
|
||||
SCWrite(pCon,"ERROR: Pushing button failed",eError);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else if(strcmp(argv[1],"status") == 0) /* status bits */
|
||||
{
|
||||
/* which bit ? */
|
||||
if(argc < 3)
|
||||
{
|
||||
sprintf(pBueffel,"ERROR: need at least two arguments to %s push",
|
||||
argv[0]);
|
||||
SCWrite(pCon,pBueffel,eError);
|
||||
return 0;
|
||||
}
|
||||
iRet = Tcl_GetInt(pSics->pTcl,argv[2],&iByte);
|
||||
if(iRet != TCL_OK)
|
||||
{
|
||||
sprintf(pBueffel,"ERROR: expected integer argument for bit, got %s",
|
||||
argv[2]);
|
||||
SCWrite(pCon,pBueffel,eError);
|
||||
return 0;
|
||||
}
|
||||
iRet = SPSGetStatus(self,iByte,&iSet);
|
||||
if(iRet <= 0)
|
||||
{
|
||||
sprintf(pBueffel,"ERROR: failed to read status bit %d",
|
||||
iByte);
|
||||
SCWrite(pCon,pBueffel,eError);
|
||||
return 0;
|
||||
}
|
||||
sprintf(pBueffel,"%s.status.%3.3d = %d",argv[0],iByte,iSet);
|
||||
SCWrite(pCon,pBueffel,eValue);
|
||||
return 1;
|
||||
}
|
||||
else if(strcmp(argv[1],"stat2") == 0) /* status bits */
|
||||
{
|
||||
if(argc < 4)
|
||||
{
|
||||
sprintf(pBueffel,"ERROR: need at least two arguments to %s stat2",
|
||||
argv[0]);
|
||||
SCWrite(pCon,pBueffel,eError);
|
||||
return 0;
|
||||
}
|
||||
/* which bit ? */
|
||||
iRet = Tcl_GetInt(pSics->pTcl,argv[2],&iByte);
|
||||
if(iRet != TCL_OK)
|
||||
{
|
||||
sprintf(pBueffel,"ERROR: expected integer argument for bit, got %s",
|
||||
argv[2]);
|
||||
SCWrite(pCon,pBueffel,eError);
|
||||
return 0;
|
||||
}
|
||||
iRet = Tcl_GetInt(pSics->pTcl,argv[3],&iBit);
|
||||
if(iRet != TCL_OK)
|
||||
{
|
||||
sprintf(pBueffel,"ERROR: expected integer argument for bit, got %s",
|
||||
argv[3]);
|
||||
SCWrite(pCon,pBueffel,eError);
|
||||
return 0;
|
||||
}
|
||||
if( (iByte <= 0) || (iBit < 0) || (iBit > 7) )
|
||||
{
|
||||
SCWrite(pCon,"ERROR: arguments out of range for stat2",eError);
|
||||
return 0;
|
||||
}
|
||||
iRet = SPSGetStatus(self,((iByte-1)*8 + iBit),&iSet);
|
||||
if(iRet <= 0)
|
||||
{
|
||||
sprintf(pBueffel,"ERROR: failed to read status bit %d",
|
||||
iByte);
|
||||
SCWrite(pCon,pBueffel,eError);
|
||||
return 0;
|
||||
}
|
||||
sprintf(pBueffel,"%s.status.%3.3d.%1.1d = %d",argv[0],iByte,iBit,iSet);
|
||||
SCWrite(pCon,pBueffel,eValue);
|
||||
return 1;
|
||||
}
|
||||
else if(strcmp(argv[1],"adc") == 0) /* ADC values */
|
||||
{
|
||||
/* which ADC ? */
|
||||
iRet = Tcl_GetInt(pSics->pTcl,argv[2],&iByte);
|
||||
if(iRet != TCL_OK)
|
||||
{
|
||||
sprintf(pBueffel,"ERROR: expected integer argument for ADC, got %s",
|
||||
argv[2]);
|
||||
SCWrite(pCon,pBueffel,eError);
|
||||
return 0;
|
||||
}
|
||||
iRet = SPSGetADC(self,iByte,&iSet);
|
||||
if(!iRet)
|
||||
{
|
||||
sprintf(pBueffel,"ERROR: failed to read ADC %d",
|
||||
iByte);
|
||||
SCWrite(pCon,pBueffel,eError);
|
||||
return 0;
|
||||
}
|
||||
sprintf(pBueffel,"%s.ADC.%1.1d = %d",argv[0],iByte,iSet);
|
||||
SCWrite(pCon,pBueffel,eValue);
|
||||
return 1;
|
||||
}
|
||||
else if(strcmp(argv[1],"perm") == 0)
|
||||
{
|
||||
/* only managers may set permissions */
|
||||
if(!SCMatchRights(pCon,usMugger))
|
||||
{
|
||||
SCWrite(pCon,"ERROR: Security: Only mangagers may configure SPS buttons",
|
||||
eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* we need lots of parameters */
|
||||
if(argc < 5)
|
||||
{
|
||||
sprintf(pBueffel,"ERROR: need at least three arguments to %s perm",
|
||||
argv[0]);
|
||||
SCWrite(pCon,pBueffel,eError);
|
||||
return 0;
|
||||
}
|
||||
/* convert arguments */
|
||||
iRet = Tcl_GetInt(pSics->pTcl,argv[2],&iByte);
|
||||
if(iRet != TCL_OK)
|
||||
{
|
||||
sprintf(pBueffel,"ERROR: expected integer argument for byte, got %s",
|
||||
argv[2]);
|
||||
SCWrite(pCon,pBueffel,eError);
|
||||
return 0;
|
||||
}
|
||||
iRet = Tcl_GetInt(pSics->pTcl,argv[3],&iBit);
|
||||
if(iRet != TCL_OK)
|
||||
{
|
||||
sprintf(pBueffel,"ERROR: expected integer argument for bit, got %s",
|
||||
argv[3]);
|
||||
SCWrite(pCon,pBueffel,eError);
|
||||
return 0;
|
||||
}
|
||||
/* try to convert user code */
|
||||
strtolower(argv[4]);
|
||||
iSet = -10;
|
||||
i = 0;
|
||||
while(aCode[i] != NULL)
|
||||
{
|
||||
if(strcmp(aCode[i],argv[4]) == 0)
|
||||
{
|
||||
iSet = i;
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if(iSet < 0)
|
||||
{
|
||||
sprintf(pBueffel,"ERROR: %s is not valid user code",argv[4]);
|
||||
SCWrite(pCon,pBueffel,eError);
|
||||
return 0;
|
||||
}
|
||||
/* do it, finally */
|
||||
SPSAddPermission(self,iByte,iBit,iSet);
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
}
|
||||
/* -------- sans collimator */
|
||||
else if(strcmp(argv[1],"colli") == 0)
|
||||
{
|
||||
iRet = SPSGetSANS(self,&fLang);
|
||||
if(!iRet)
|
||||
{
|
||||
SCWrite(pCon,"ERROR: cannot read SANS collimator",eError);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(pBueffel,"SANS.collimator = %f",fLang);
|
||||
SCWrite(pCon,pBueffel,eValue);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
sprintf(pBueffel,"ERROR: %s does not not understand subcommand %s",
|
||||
argv[0], argv[1]);
|
||||
SCWrite(pCon,pBueffel,eError);
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user