- Currently disabled attempts at logging commands

- Added a warning for excessive data rates on monitors
- Added statistics to devser and thus to scriptcontext
- Added byte concatenation to dynstring
- Added aborting for reflection generation to fourmess.c
- Added data checksum testing to hipadaba, use for update tests
- Fixed interrupt discovery in network.c, caused invalid interrupt
  codes which in turn confused sicscron which had to be fixed too.
- Renamed ubcalc into ubcalcint in order to reclaim the ubcalc for Jurg
- Added an a3offset to tasub in order to fix what I perceive an IS problem
- Added support for the newer version of the Siemens SPS, the S7
- Added a not yet fully working sinqhttpopt driver which talks to
  http HM without libghttp


SKIPPED:
	psi/delcam.c
	psi/make_gen
	psi/psi.c
	psi/sinq.c
	psi/sinq.h
	psi/sinqhttpopt.c
	psi/slsvme.c
	psi/spss7.c
This commit is contained in:
koennecke
2010-12-20 10:18:01 +00:00
parent 3e89d559ef
commit 045029dfd3
45 changed files with 732 additions and 202 deletions

View File

@ -79,6 +79,7 @@
#include "obdes.h" #include "obdes.h"
#include "lld.h" #include "lld.h"
#include "dynstring.h" #include "dynstring.h"
#include "commandlog.h"
/* M.Z. */ /* M.Z. */
#include "definealias.h" #include "definealias.h"
@ -354,6 +355,14 @@ int InterpExecute(SicsInterp * self, SConnection * pCon, char *pText)
} }
MacroPop(); MacroPop();
/*
* log in history if succesfull
*/
if(iRet == 1){
WriteCommandHistory(pText);
}
deleteArgv: deleteArgv:
if (argv) { if (argv) {
/* delete argv */ /* delete argv */

14
ascon.c
View File

@ -218,17 +218,24 @@ int AsconConnectSuccess(int fd)
FD_SET(fd, &rmask); FD_SET(fd, &rmask);
ret = uselect(fd + 1, &rmask, &wmask, NULL, &tmo); ret = uselect(fd + 1, &rmask, &wmask, NULL, &tmo);
if (ret > 0) { if (ret > 0) {
assert(FD_ISSET(fd, &wmask)); /**
* This assertion triggered for some reason: as writing is only done later
* I moved the test for ISSET(wmask) down there
* assert(FD_ISSET(fd, &wmask));
*/
if (FD_ISSET(fd, &rmask)) { /* there may already be data for read */ if (FD_ISSET(fd, &rmask)) { /* there may already be data for read */
if (recv(fd, NULL, 0, 0) < 0) { /* zero length, check only return value */ if (recv(fd, NULL, 0, 0) < 0) { /* zero length, check only return value */
ret = ASCON_RECV_ERROR; /* first recv failed */ ret = ASCON_RECV_ERROR; /* first recv failed */
} }
} else { } else {
if(FD_ISSET(fd,&wmask)){
if (send(fd, NULL, 0, 0) < 0) { /* zero length, check only return value */ if (send(fd, NULL, 0, 0) < 0) { /* zero length, check only return value */
ret = ASCON_SEND_ERROR; /* first send failed */ ret = ASCON_SEND_ERROR; /* first send failed */
} }
} }
} }
}
fcntl(fd, F_SETFL, oldopts & ~O_NONBLOCK); /* reset to blocking mode */ fcntl(fd, F_SETFL, oldopts & ~O_NONBLOCK); /* reset to blocking mode */
return ret; return ret;
} }
@ -698,3 +705,8 @@ char *AsconGetError(Ascon *a)
{ {
return GetCharArray(a->errmsg); return GetCharArray(a->errmsg);
} }
int AsconLastState(Ascon *a)
{
return (int)a->state;
}

View File

@ -94,4 +94,10 @@ char *ConcatArgs(int argc, char *argv[]);
*/ */
void AsconError(Ascon *a, char *msg, int errorno); void AsconError(Ascon *a, char *msg, int errorno);
/**
* \brief return the last ascon state. Only used for statistics
* \param a The Adcon to query
* \return the AsconState as an integer.
*/
int AsconLastState(Ascon *a);
#endif #endif

View File

@ -43,7 +43,7 @@
#define DATASOCKET 1 #define DATASOCKET 1
#define MAXCONNECTIONS 1024 #define MAXCONNECTIONS 1024
#define RBUFFERSIZE 262144 /* 256kb */ #define RBUFFERSIZE 262144 /* 256kb */
#define WBUFFERSIZE 4*262144 /* 512kb */ #define WBUFFERSIZE 10*262144 /* 512kb */
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
typedef struct { typedef struct {
int socket; int socket;

View File

@ -42,6 +42,7 @@
* port or data is ready. * port or data is ready.
* \param handle The handle of the new network connection * \param handle The handle of the new network connection
* \return 1 if the new connection can be accepted or 0 if not. * \return 1 if the new connection can be accepted or 0 if not.
* Same for data.
*/ */
typedef int (*ANETcallback) (int handle, void *userData); typedef int (*ANETcallback) (int handle, void *userData);
/** /**

View File

@ -16,6 +16,10 @@
- timestamps look different and are omitted if no other text is written - timestamps look different and are omitted if no other text is written
- socket number information is written on the timestamp line - socket number information is written on the timestamp line
Added command history logging. Due to problems this is currently disabled by
writeHistory = 0 and code in SetWriteHistory
Mark Koennecke, July 2010
--------------------------------------------------------------------------*/ --------------------------------------------------------------------------*/
#include <stdlib.h> #include <stdlib.h>
#include <assert.h> #include <assert.h>
@ -28,7 +32,7 @@
#include "scaldate.h" #include "scaldate.h"
#include "network.h" #include "network.h"
#include "circular.h" #include "circular.h"
#include "stptok.h"
/* in conman.c */ /* in conman.c */
int TelnetWrite(mkChannel * pSock, char *pText); int TelnetWrite(mkChannel * pSock, char *pText);
@ -36,6 +40,9 @@ int TelnetWrite(mkChannel * pSock, char *pText);
static FILE *fd = NULL; static FILE *fd = NULL;
static FILE *fauto = NULL; static FILE *fauto = NULL;
static char pFile[256]; static char pFile[256];
/*------------------------- command history logging --------------------*/
static char pHistoryFilter[1024] = "";
static int writeHistory = 0;
/*-------------------- the tail buffer ---------------------------------*/ /*-------------------- the tail buffer ---------------------------------*/
static pCircular pTail = NULL; static pCircular pTail = NULL;
#define MAXTAIL 1000 #define MAXTAIL 1000
@ -484,6 +491,31 @@ int CommandLog(SConnection * pCon, SicsInterp * pSics, void *pData,
} }
SCPrintf(pCon, eValue, "%s.intervall [min] = %d", argv[0], iIntervall); SCPrintf(pCon, eValue, "%s.intervall [min] = %d", argv[0], iIntervall);
return 1; return 1;
} else if (strcmp(argv[1], "history") == 0) {
if (argc > 2) {
iRet = Tcl_GetInt(pSics->pTcl, argv[2], &iVal);
if (iRet != TCL_OK) {
SCWrite(pCon, "ERROR: failed to convert new history to number",
eError);
return 0;
}
writeHistory = iVal;
}
SCPrintf(pCon, eValue, "%s.writeHistory = %d", argv[0], writeHistory);
return 1;
} else if (strcmp(argv[1], "historyfilter") == 0) {
if (argc > 2) {
if(strlen(argv[2]) < 1024){
strcpy(pHistoryFilter,argv[2]);
} else {
SCWrite(pCon,"ERROR: history filter to long", eError);
return 0;
}
SCSendOK(pCon);
return 1;
}
SCPrintf(pCon, eValue, "%s.historyFilter = %s", argv[0], pHistoryFilter);
return 1;
} else if (strcmp(argv[1], "compact") == 0) { } else if (strcmp(argv[1], "compact") == 0) {
if (argc > 2) { if (argc > 2) {
iCompact = atoi(argv[2]); iCompact = atoi(argv[2]);
@ -554,13 +586,51 @@ static int openHistoryLog()
return 1; return 1;
} }
} }
/*---------------------------------------------------------------------------
* This is to suppress certain stuff from the history log in order to stop it
* from filling with garbage
-----------------------------------------------------------------------------*/
static int historyFilter(char *command)
{
static char *toRemove[] = {"sct", "hupdate","contextdo","transact", NULL};
char token[50];
char *pPtr = NULL;
int i = 0;
while(toRemove[i] != NULL){
if(strstr(command,toRemove[i]) != NULL){
return 0;
}
i++;
}
pPtr = pHistoryFilter;
while((pPtr = stptok(pPtr,token,50,":")) != NULL){
if(strstr(command,token) != NULL){
return 0;
}
}
return 1;
}
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
void WriteCommandHistory(char *txt) void WriteCommandHistory(char *txt)
{ {
if(writeHistory == 0){
return;
}
if(comHistory == NULL){ if(comHistory == NULL){
openHistoryLog(); openHistoryLog();
} }
if(comHistory != NULL){ if(comHistory != NULL){
if(historyFilter(txt)){
fprintf(comHistory,"%s\n", txt); fprintf(comHistory,"%s\n", txt);
} }
}
}
/*-----------------------------------------------------------------------*/
void SetWriteHistory(int i)
{
/* writeHistory = i;*/
writeHistory = 0;
} }

View File

@ -18,4 +18,5 @@ int CommandLog(SConnection * pCon, SicsInterp * pSics, void *pData,
void CommandLogClose(void *pData); void CommandLogClose(void *pData);
void WriteCommandHistory(char *txt); void WriteCommandHistory(char *txt);
void SetWriteHistory(int i);
#endif #endif

View File

@ -1416,12 +1416,6 @@ int SCInvoke(SConnection * self, SicsInterp * pInter, char *pCommand)
SCDeleteConnection(pCopy); SCDeleteConnection(pCopy);
StatusFileTask(NULL); /* save changed parameters */ StatusFileTask(NULL); /* save changed parameters */
/*
* log successful commands for later evaluation
*/
if(iRet == 1){
WriteCommandHistory(pCommand);
}
self->inUse--; self->inUse--;
return iRet; return iRet;
} }

View File

@ -214,7 +214,7 @@ static int CheckCountStatus(void *pData, SConnection * pCon)
int eCt; int eCt;
char pError[80], pBueffel[132]; char pError[80], pBueffel[132];
int iErr; int iErr;
float fControl; float fControl, rate;
MonEvent sMon; MonEvent sMon;
self = (pCounter) pData; self = (pCounter) pData;
@ -239,6 +239,13 @@ static int CheckCountStatus(void *pData, SConnection * pCon)
} }
} }
if(self->pDriv->fTime > .0){
rate = (float)(self->pDriv->lCounts[1])/self->pDriv->fTime;
if(rate > 5000){
SCWrite(pCon,"WARNING: Your control monitor is running into dead time",
eWarning);
}
}
/* /*
handle count parameters and notify listeners on progress handle count parameters and notify listeners on progress
*/ */

View File

@ -68,6 +68,8 @@ static int SecStartCount(void *pData, SConnection *pCon)
self->tStart = time(NULL); self->tStart = time(NULL);
node = GetHipadabaNode(self->pDes->parNode, "status"); node = GetHipadabaNode(self->pDes->parNode, "status");
UpdateHipadabaPar(node,MakeHdbText("run"), pCon); UpdateHipadabaPar(node,MakeHdbText("run"), pCon);
node = GetHipadabaNode(self->pDes->parNode, "control");
UpdateHipadabaPar(node,MakeHdbFloat(.0), pCon);
SetHdbProperty(node,"geterror", NULL); SetHdbProperty(node,"geterror", NULL);
/* /*
* set time to 0. Otherwise, if there is a delay, * set time to 0. Otherwise, if there is a delay,
@ -145,14 +147,6 @@ static int SecCtrCheckStatus(void *pData, SConnection *pCon)
} }
ReleaseHdbValue(&v); ReleaseHdbValue(&v);
/*
* check for overrun timers
*/
if(self->getMode(self) == eTimer &&
time(NULL) > (self->tStart + (int)self->getPreset(self)) && self->haltFixFlag == 0){
SecCtrHalt(self);
self->haltFixFlag = 1;
}
node = GetHipadabaNode(self->pDes->parNode,"control"); node = GetHipadabaNode(self->pDes->parNode,"control");
assert(node != NULL); assert(node != NULL);
@ -167,6 +161,20 @@ static int SecCtrCheckStatus(void *pData, SConnection *pCon)
sMon.fPreset = fPreset; sMon.fPreset = fPreset;
sMon.pName = self->name; sMon.pName = self->name;
self->badStatusCount = 0; self->badStatusCount = 0;
/*
* check for overrun counter boxes
*/
if(self->getMode(self) == eTimer &&
(sMon.fCurrent > sMon.fPreset +1)
&& self->haltFixFlag == 0){
SecCtrHalt(self);
self->haltFixFlag = 1;
}
/*
* invoke notifiactions, if necessary
*/
if (self->iCallbackCounter > 20) { if (self->iCallbackCounter > 20) {
InvokeCallBack(self->pCall, MONITOR, &sMon); InvokeCallBack(self->pCall, MONITOR, &sMon);
self->iCallbackCounter = 0; self->iCallbackCounter = 0;

101
devser.c
View File

@ -22,6 +22,18 @@ struct DevSer {
DevAction *actions; /* the action queue */ DevAction *actions; /* the action queue */
DevAction *toKill; /* list of actions to be killed */ DevAction *toKill; /* list of actions to be killed */
int steps; int steps;
double startTime; /* fields for statistics */
double comCount;
long nComCount;
double comMax;
long errorCount;
int inError;
double asconStart;
double asconSum;
double asconMax;
long asconCount;
int asconState, asconMaxState;
int maxCount;
}; };
static char *devPrio[NumberOfPRIO] = { static char *devPrio[NumberOfPRIO] = {
@ -133,6 +145,80 @@ static DevAction *DevNextAction(DevSer * devser)
} }
return NULL; return NULL;
} }
static void LogStart(DevSer *self)
{
if(self->startTime > 0){
printf("DEVSER: there is something fucked up in LogStart. Investigate!\n");
}
self->startTime = DoubleTime();
}
static void LogResponse(DevSer *self, int error)
{
double responseTime;
if(self->startTime < 0){
printf("DEVSER: there is something fucked up in LogResponse, Investigate!\n");
self->startTime = -1;
return;
}
responseTime = DoubleTime() - self->startTime;
self->comCount += responseTime;
if(responseTime > self->comMax){
self->comMax = responseTime;
}
self->nComCount++;
if(error == 1 && self->inError == 0){
self->errorCount++;
self->inError = 1;
} else if(error == 0){
self->inError = 0;
}
self->startTime = -1;
}
static void StartAscon(DevSer *self)
{
self->asconStart = DoubleTime();
self->asconState = AsconLastState(self->ascon);
}
static void AsconLog(DevSer *self)
{
double used;
used = DoubleTime() - self->asconStart;
self->asconSum += used;
self->asconCount++;
if(used > self->asconMax){
self->asconMax = used;
self->asconMaxState = self->asconState;
}
if(used > self->asconMax/2.){
self->maxCount++;
}
}
void DevStatistics(DevSer *devser, double *avg, double *max,
long *errCount, int *errState)
{
if(devser->nComCount > 0){
*avg = devser->comCount/devser->nComCount;
} else {
*avg = 0; /* no data!*/
}
*max = devser->comMax;
*errCount = devser->errorCount;
*errState = devser->inError;
}
void DevAsconStatistics(DevSer *self, double *avg, \
double *max, int *maxState, int *longCount)
{
if(self->asconCount > 0){
*avg = self->asconSum/self->asconCount;
} else {
*avg = .0;
}
*max = self->asconMax;
*maxState = self->asconMaxState;
*longCount = self->maxCount;
}
static int DevQueueTask(void *ds) static int DevQueueTask(void *ds)
{ {
@ -155,11 +241,24 @@ static int DevQueueTask(void *ds)
} }
while (action != NULL) { while (action != NULL) {
StartAscon(devser);
status = AsconTask(devser->ascon); status = AsconTask(devser->ascon);
AsconLog(devser);
if (status == AsconFailure) { if (status == AsconFailure) {
replyData = AsconGetError(devser->ascon); replyData = AsconGetError(devser->ascon);
/**
* TODO: this may be a place to record the end time
*/
if(devser->startTime > 0){
LogResponse(devser,1);
} else {
/* This is a follow up error and should not go into statistics */
}
} else if (status == AsconReady) { } else if (status == AsconReady) {
replyData = AsconRead(devser->ascon); replyData = AsconRead(devser->ascon);
if(replyData != NULL){
LogResponse(devser,0);
}
} else { } else {
return 1; return 1;
} }
@ -169,6 +268,7 @@ static int DevQueueTask(void *ds)
sendData = action->hdl(action->data, replyData, (status == AsconFailure)); sendData = action->hdl(action->data, replyData, (status == AsconFailure));
if (sendData != NULL) { if (sendData != NULL) {
AsconWrite(devser->ascon, sendData, 0); AsconWrite(devser->ascon, sendData, 0);
LogStart(devser);
return 1; return 1;
} }
if (devser->killCurrent) { if (devser->killCurrent) {
@ -200,6 +300,7 @@ DevSer *DevMake(SConnection * con, int argc, char *argv[])
devser->actions = NULL; devser->actions = NULL;
devser->toKill = NULL; devser->toKill = NULL;
devser->steps = -1; /* no debugging by default */ devser->steps = -1; /* no debugging by default */
devser->startTime = -1;
TaskRegister(pServ->pTasker, DevQueueTask, NULL, NULL, devser, 0); TaskRegister(pServ->pTasker, DevQueueTask, NULL, NULL, devser, 0);
return devser; return devser;
} }

View File

@ -162,4 +162,23 @@ DevPrio DevText2Prio(char *text);
*/ */
char * DevList(DevSer * devser); char * DevList(DevSer * devser);
/**
* \brief Get statistics
* \param devser The device serializer
* \param avg The average response time
* \param max The maximum response time
* \param errCount The count of communication errors detected so far.
* \param errFlag A flag if the device is in an error state or not
*/
void DevStatistics(DevSer *devser, double *avg, double *max,
long *errCount, int *errFlag);
/**
* \brief Get Ascon invocation statistics. This can help to stop
* blocking behaviour in protocol handlers.
* \param devser The device serializer to query
* \param avg The avgerage time spent in AsconTask invocations
* \param max The maximum time spent in a AsconTask call.
*/
void DevAsconStatistics(DevSer *self, double *avg,
double *max, int *maxState, int *longCount);
#endif #endif

View File

@ -174,7 +174,27 @@ int DynStringConcatChar(pDynString self, char c)
self->iTextLen++; self->iTextLen++;
return 1; return 1;
} }
/*---------------------------------------------------------------------------*/
int DynStringConcatBytes(pDynString self, char *data, int datalen)
{
int iRequested, iRet;
assert(self);
assert(self->iMAGIC == DYNMAGIC);
iRequested = self->iTextLen + datalen;
if (iRequested >= self->iBufferSize) {
iRet = Resize(self, iRequested);
if (!iRet) {
return 0;
}
}
memcpy(self->pBuffer + self->iTextLen,data,datalen);
self->iTextLen += datalen;
return 1;
}
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
int DynStringInsert(pDynString self, char *pText, int iPos) int DynStringInsert(pDynString self, char *pText, int iPos)
{ {

View File

@ -54,7 +54,10 @@ int DynStringConcatChar(pDynString self, char c);
/* /*
adds one character at the end of the string adds one character at the end of the string
*/ */
int DynStringConcatBytes(pDynString self, char *data, int datalen);
/*
* adds datalen bytes from data to the buffer
*/
int DynStringInsert(pDynString self, char *pText, int iPos); int DynStringInsert(pDynString self, char *pText, int iPos);
/* /*

View File

@ -217,7 +217,6 @@ int exeBufProcess(pExeBuf self, SicsInterp * pSics,
/* print only SICS commands */ /* print only SICS commands */
SCPrintf(pCon, eLog, "%s:%d>> %s", self->name, self->lineno, SCPrintf(pCon, eLog, "%s:%d>> %s", self->name, self->lineno,
cmd); cmd);
WriteCommandHistory(cmd);
} else { } else {
/* debugging */ /* debugging */
/* SCPrintf(pCon, eValue, "%s:%d>> %s",self->name,self->lineno,cmd); */ /* SCPrintf(pCon, eValue, "%s:%d>> %s",self->name,self->lineno,cmd); */

View File

@ -729,6 +729,10 @@ static int GenIndex(pSICSOBJ self, SConnection * pCon, pHdb commandNode,
AddRefIdx(priv->messList, hkl); AddRefIdx(priv->messList, hkl);
count++; count++;
} }
if(SCGetInterrupt(pCon) != eContinue){
SCWrite(pCon,"ERROR: reflection generation aborted", eError);
return 0;
}
} }
} }
} }
@ -768,6 +772,10 @@ static int GenInconsumerate(pSICSOBJ self, SConnection * pCon,
hkl[j] -= qvec[j]; hkl[j] -= qvec[j];
} }
AddRefIdx(priv->messList, hkl); AddRefIdx(priv->messList, hkl);
if(SCGetInterrupt(pCon) != eContinue){
SCWrite(pCon,"ERROR: generating incommensurate reflections aborted", eError);
return 0;
}
} }
SCPrintf(pCon, eValue, SCPrintf(pCon, eValue,
"%d additional inconsumerate reflections generated", "%d additional inconsumerate reflections generated",

154
genbinprot.c Normal file
View File

@ -0,0 +1,154 @@
/*
* genbinprot.c
*
* This is a generic binary protocol handler for scriptcontext. It expects a
* command of the form:
*
* writepointer:writecount:readpointer:readcount
*
* And will writecount bytes from the data area writepointer and
* read readcount bytes into the memory area under readpointer.
* If writecount is 0, the nothing will be written. This can
* be used to read a binary message in parts. Both writepointer and
* readpointer are memory addresses in hexadecimal.
*
* This is a workaround for the essential weakness of devser not being
* able to work with binary protocols.
*
* Created on: Jul 7, 2010
* Author: koennecke
*/
#include <errno.h>
#include <stdio.h>
#include <sics.h>
#include <ascon.h>
#include <ascon.i>
#include <stptok.h>
/*-----------------------------------------------------------------*/
typedef struct {
char *writePointer;
unsigned int toWrite;
char *readPointer;
unsigned int readCount;
unsigned int toRead;
}GenBin, *pGenBin;
/*------------------------------------------------------------------*/
static void initGenBin(Ascon *a)
{
pGenBin self = (pGenBin)a->private;
char *pPtr = NULL, pToken[60];
long lval;
pPtr = GetCharArray(a->wrBuffer);
pPtr = stptok(pPtr,pToken,60,":");
sscanf(pToken,"%lx",&lval);
self->writePointer = (char *)lval;
pPtr = stptok(pPtr,pToken,60,":");
sscanf(pToken,"%d",&self->toWrite);
pPtr = stptok(pPtr,pToken,60,":");
sscanf(pToken,"%lx",&lval);
self->readPointer = (char *)lval;
pPtr = stptok(pPtr,pToken,60,":");
sscanf(pToken,"%d",&self->toRead);
a->wrPos = 0;
self->readCount = 0;
}
/*------------------------------------------------------------------*/
static int GenBinHandler(Ascon *a)
{
pGenBin self = (pGenBin)a->private;
unsigned int toWrite;
int ret;
char chr;
switch(a->state){
case AsconWriteStart:
AsconReadGarbage(a->fd);
initGenBin(a);
a->state = AsconWriting;
break;
case AsconWriting:
toWrite = self->toWrite - a->wrPos;
if(toWrite == 0){
a->state = AsconWriteDone;
} else {
ret = AsconWriteChars(a->fd, self->writePointer+a->wrPos, toWrite);
if (ret < 0) {
if (errno != EINTR && errno != EAGAIN) {
AsconError(a, "send failed:", errno);
}
} else {
a->wrPos += ret;
if(a->wrPos >= self->toWrite){
a->state = AsconWriteDone;
}
}
}
break;
case AsconReading:
if(self->readCount >= self->toRead){
a->state = AsconReadDone;
DynStringCopy(a->rdBuffer,"OK");
} else {
ret = AsconReadChar(a->fd, &chr);
if (ret < 0) {
/* EINTR means we must retry */
if (errno != EINTR && errno != EAGAIN) {
AsconError(a, "AsconReadChar failed:", errno);
}
return 1;
} else if (ret > 0) {
a->start = DoubleTime();
self->readPointer[self->readCount] = chr;
self->readCount++;
} else if (ret == 0) {
if (a->timeout > 0) {
if (DoubleTime() - a->start > a->timeout) {
AsconError(a, "read timeout", 0);
a->state = AsconTimeout;
}
}
}
}
break;
default:
return AsconStdHandler(a);
}
return 1;
}
/*------------------------------------------------------------------------*/
static int GenBinInit(Ascon * a, SConnection * con, int argc, char *argv[])
{
pGenBin priv = NULL;
priv = calloc(sizeof(GenBin), 1);
a->fd = -1;
a->state = AsconConnectStart;
a->reconnectInterval = 10;
a->hostport = strdup(argv[1]);
if (argc > 2) {
a->timeout = atof(argv[2]);
} else {
a->timeout = 2.0; /* sec */
}
a->private = priv;
a->killPrivate = free;
return 1;
}
/*------------------------------------------------------------------------*/
void AddGenBinProtocoll()
{
AsconProtocol *prot = NULL;
prot = calloc(sizeof(AsconProtocol), 1);
prot->name = strdup("genbin");
prot->init = GenBinInit;
prot->handler = GenBinHandler;
AsconInsertProtocol(prot);
}

View File

@ -448,7 +448,81 @@ void ReleaseHdbValue(hdbValue * v)
break; break;
} }
} }
/*-----------------------------------------------------------------------------*/
static unsigned short fletcher16( char *data, size_t len)
{
unsigned short sum1 = 0xff, sum2 = 0xff, result;
unsigned char checkA, checkB;
if(data == NULL){
return 0;
}
while (len) {
size_t tlen = len > 21 ? 21 : len;
len -= tlen;
do {
sum1 += *data++;
sum2 += sum1;
} while (--tlen);
sum1 = (sum1 & 0xff) + (sum1 >> 8);
sum2 = (sum2 & 0xff) + (sum2 >> 8);
}
/* Second reduction step to reduce sums to 8 bits */
sum1 = (sum1 & 0xff) + (sum1 >> 8);
sum2 = (sum2 & 0xff) + (sum2 >> 8);
checkA = (unsigned char)sum1;
checkB = (unsigned char)sum2;
result = checkA;
result = result << 8 | checkB;
return result ;
}
/*------------------------------------------------------------------------*/
unsigned short getHdbCheckSum(hdbValue *val)
{
char *data;
size_t len;
len = getHdbValueLength(*val);
switch (val->dataType) {
case HIPNONE:
return 0;
break;
case HIPINT:
data = (char *)&val->v.intValue;
return fletcher16(data,len);
break;
case HIPFLOAT:
data = (char *)&val->v.doubleValue;
return fletcher16(data,len);
break;
case HIPTEXT:
data = val->v.text;
return fletcher16(data,len);
break;
case HIPINTAR:
case HIPINTVARAR:
data = (char *)val->v.intArray;
return fletcher16(data,len);
break;
case HIPFLOATAR:
case HIPFLOATVARAR:
data = (char *)val->v.floatArray;
return fletcher16(data,len);
break;
case HIPOBJ:
data = (char *)val->v.obj;
return fletcher16(data,len);
break;
case HIPFUNC:
data = (char *)val->v.func;
return fletcher16(data,len);
break;
default:
assert(0);
break;
}
return 0;
}
/*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
int compareHdbValue(hdbValue v1, hdbValue v2) int compareHdbValue(hdbValue v1, hdbValue v2)
{ {
@ -457,6 +531,12 @@ int compareHdbValue(hdbValue v1, hdbValue v2)
if (v1.dataType != v2.dataType) { if (v1.dataType != v2.dataType) {
return 0; return 0;
} }
if((v1.doNotFree == 1 && v1.v.obj == NULL)
|| (v2.doNotFree == 1 && v2.v.obj == NULL)){
return 0;
}
switch (v1.dataType) { switch (v1.dataType) {
case HIPNONE: case HIPNONE:
return 0; return 0;
@ -971,12 +1051,17 @@ int NotifyHipadabaPar(pHdb node, void *callData)
int GetHipadabaPar(pHdb node, hdbValue *v, void *callData) int GetHipadabaPar(pHdb node, hdbValue *v, void *callData)
{ {
int status; int status;
unsigned short checksum;
memset(v,0,sizeof(hdbValue)); memset(v,0,sizeof(hdbValue));
v->dataType = node->value.dataType; v->dataType = node->value.dataType;
checksum = getHdbCheckSum(&node->value);
status = SendDataMessage(node, get, v, callData); status = SendDataMessage(node, get, v, callData);
copyHdbValue(&node->value, v); copyHdbValue(&node->value, v);
if(getHdbCheckSum(&node->value) != checksum){
NotifyHipadabaPar(node, callData);
}
if (status != 1) { if (status != 1) {
return status; return status;
} }

View File

@ -253,6 +253,12 @@ int cloneHdbValue(hdbValue * source, hdbValue * clone);
* @return the number of data bytes * @return the number of data bytes
*/ */
int getHdbValueLength(hdbValue v); int getHdbValueLength(hdbValue v);
/**
* calculate a checksum of the data in val
* @param val The hdbValue to calcululate the checksum for
* @return The checksum
*/
unsigned short getHdbCheckSum(hdbValue *val);
/*========================== function protoypes: Nodes =======================*/ /*========================== function protoypes: Nodes =======================*/
/** /**
* make a new hipadaba node * make a new hipadaba node

View File

@ -227,7 +227,9 @@ int LoggerWrite0(Logger * log, time_t now, int period, char *value)
} }
assert(log->old); assert(log->old);
assert(l < log->oldsize); assert(l < log->oldsize);
if(log->old != value){
strcpy(log->old, value); strcpy(log->old, value);
}
assert(log->old[l] == '\0'); assert(log->old[l] == '\0');
log->last = now; log->last = now;
return 1; return 1;

44
macro.c
View File

@ -118,33 +118,6 @@ int MacroPop(void)
} }
return 1; return 1;
} }
/*---------------------------------------------------------------------------
* This is to suppress certain stuff from the history log in order to stop it
* from filling with garbage
-----------------------------------------------------------------------------*/
static int historyFilter(pDummy pDum, char *command, char *fullCommand)
{
static char *toRemove[] = {"sct", "hupdate",NULL};
static char *typeRemove[] = {"ScriptContext",NULL};
int i = 0;
while(toRemove[i] != NULL){
if(strcmp(command,toRemove[i]) == 0){
return 0;
}
i++;
}
i = 0;
while(typeRemove[i] != NULL){
if(strcmp(pDum->pDescriptor->name, typeRemove[i]) == 0) {
return 0;
}
i++;
}
return 1;
}
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static int SicsUnknownProc(ClientData pData, Tcl_Interp * pInter, static int SicsUnknownProc(ClientData pData, Tcl_Interp * pInter,
int argc, char *argv[]) int argc, char *argv[])
@ -155,7 +128,7 @@ static int SicsUnknownProc(ClientData pData, Tcl_Interp * pInter,
SicsInterp *pSinter = NULL; SicsInterp *pSinter = NULL;
SConnection *pCon = NULL; SConnection *pCon = NULL;
CommandList *pCommand = NULL; CommandList *pCommand = NULL;
char *lastCommand = NULL, comBuffer[132], comHistory[256]; char *lastCommand = NULL, comBuffer[132];
int iRet = 0, i; int iRet = 0, i;
int iMacro; int iMacro;
Statistics *old; Statistics *old;
@ -216,18 +189,6 @@ static int SicsUnknownProc(ClientData pData, Tcl_Interp * pInter,
StatisticsEnd(old); StatisticsEnd(old);
SCsetMacro(pCon, iMacro); SCsetMacro(pCon, iMacro);
if(iRet == 1){
/*
* this is OK because comBuffer is length restricted
*/
strcpy(comHistory,"SICSUNKNOWN: ");
strcat(comHistory,comBuffer);
/* This gives just to many unwanted entries.... TODO: Filter better
if(historyFilter(pCommand->pData, myarg[0], comBuffer) == 1){
WriteCommandHistory(comHistory);
}
*/
}
/* /*
lastUnkown gets deeply stacked with each SICS command exec'd. lastUnkown gets deeply stacked with each SICS command exec'd.
This is not reflected in code. However, lastUnknown has already This is not reflected in code. However, lastUnknown has already
@ -240,6 +201,7 @@ static int SicsUnknownProc(ClientData pData, Tcl_Interp * pInter,
/* finish */ /* finish */
if (iRet == 1) { if (iRet == 1) {
WriteCommandHistory(comBuffer);
return TCL_OK; return TCL_OK;
} else { } else {
Tcl_SetVar(pInter, SICSERROR, "yes", TCL_GLOBAL_ONLY); Tcl_SetVar(pInter, SICSERROR, "yes", TCL_GLOBAL_ONLY);
@ -989,7 +951,9 @@ static int TclAction(SConnection * pCon, SicsInterp * pSics, void *pData,
return 0; return 0;
} }
Tcl_ResetResult(pTcl); Tcl_ResetResult(pTcl);
SetWriteHistory(0);
iRet = Tcl_Eval(pTcl, pCommand); iRet = Tcl_Eval(pTcl, pCommand);
SetWriteHistory(1);
if (iRet == TCL_OK) { if (iRet == TCL_OK) {
if (strlen(pTcl->result) > 0) { if (strlen(pTcl->result) > 0) {
SCPrintf(pCon, eValue, "%s", pTcl->result); SCPrintf(pCon, eValue, "%s", pTcl->result);

View File

@ -41,7 +41,7 @@ SOBJ = network.o ifile.o conman.o SCinter.o splitter.o passwd.o \
sgclib.o sgfind.o sgio.o sgsi.o sghkl.o singlediff.o singlebi.o \ sgclib.o sgfind.o sgio.o sgsi.o sghkl.o singlediff.o singlebi.o \
singlenb.o simindex.o simidx.o uselect.o singletas.o motorsec.o \ singlenb.o simindex.o simidx.o uselect.o singletas.o motorsec.o \
rwpuffer.o asynnet.o background.o countersec.o hdbtable.o velosec.o \ rwpuffer.o asynnet.o background.o countersec.o hdbtable.o velosec.o \
histmemsec.o sansbc.o sicsutil.o strlutil.o histmemsec.o sansbc.o sicsutil.o strlutil.o genbinprot.o
MOTOROBJ = motor.o simdriv.o MOTOROBJ = motor.o simdriv.o
COUNTEROBJ = countdriv.o simcter.o counter.o COUNTEROBJ = countdriv.o simcter.o counter.o

View File

@ -96,16 +96,26 @@ static long SecMotorRun(void *sulf, SConnection * pCon, float fNew)
{ {
pMotor self = (pMotor) sulf; pMotor self = (pMotor) sulf;
hdbValue v; hdbValue v;
int accesscode; int accesscode, status;
pHdb node = NULL;
assert(SICSHdbGetPar(self, NULL, "accesscode", &v) == 1); assert(SICSHdbGetPar(self, NULL, "accesscode", &v) == 1);
accesscode = (int)v.v.doubleValue; accesscode = (int)v.v.doubleValue;
if(!SCMatchRights(pCon, accesscode)){ if(!SCMatchRights(pCon, accesscode)){
return 0; return 0;
} }
self->stopped = 0;
v = MakeHdbFloat(fNew); v = MakeHdbFloat(fNew);
return SetHipadabaPar(self->pDescriptor->parNode, v, pCon); status = SetHipadabaPar(self->pDescriptor->parNode, v, pCon);
node = GetHipadabaNode(self->pDescriptor->parNode, "status");
if(node != NULL){
v = MakeHdbText(strdup("run"));
UpdateHipadabaPar(node,v,pCon);
ReleaseHdbValue(&v);
}
return status;
} }
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
@ -299,7 +309,9 @@ static int SecMotorStatus(void *sulf, SConnection * pCon)
if (SCGetInterrupt(pCon) < (int) interrupt) { if (SCGetInterrupt(pCon) < (int) interrupt) {
SCSetInterrupt(pCon, (int) interrupt); SCSetInterrupt(pCon, (int) interrupt);
} }
if(self->stopped == 0) {
self->errorCount++; self->errorCount++;
}
break; break;
case HWIdle: case HWIdle:
self->posCount = 10000; self->posCount = 10000;

View File

@ -626,7 +626,9 @@ int NETReadTillTerm(mkChannel * self, long timeout,
} }
} }
} else { } else {
/* this is for accepting a terminator consisting of multiple characters, pTerm[0] is & */ /* this is for accepting a terminator consisting of multiple characters, pTerm[0] is &
* There is evidence that this code is broken. M.K.
*/
if (matchIndex == 1 && c == pTerm[1]) { if (matchIndex == 1 && c == pTerm[1]) {
matchIndex++; matchIndex++;
} else { } else {

View File

@ -1007,13 +1007,13 @@ static void killCommandCBData(void *data)
/*----------------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------------*/
static int testAndInvokeInterrupt(pCommandCBData self, int handle) static int testAndInvokeInterrupt(pCommandCBData self, int handle)
{ {
char *pPtr; char *pPtr, *pInt;
char buffer[512]; char buffer[512];
int iInt; int iInt;
pPtr = GetCharArray(self->command); pPtr = GetCharArray(self->command);
if (strstr(pPtr, "INT1712") != NULL) { if ((pInt = strstr(pPtr, "INT1712")) != NULL) {
sscanf(pPtr, "%s %d", buffer, &iInt); sscanf(pInt, "%s %d", buffer, &iInt);
if (SCMatchRights(self->pCon, usUser)) { if (SCMatchRights(self->pCon, usUser)) {
TaskSignal(pServ->pTasker, SICSINT, &iInt); TaskSignal(pServ->pTasker, SICSINT, &iInt);
snprintf(buffer, 512, "INTERRUPT %d issued on sock %d", snprintf(buffer, 512, "INTERRUPT %d issued on sock %d",

View File

@ -37,6 +37,7 @@
#include "tcldrivable.h" #include "tcldrivable.h"
#include "nserver.h" #include "nserver.h"
#include "sicshipadaba.h" #include "sicshipadaba.h"
#include "commandlog.h"
int ServerSetupInterrupt(int iPort, pNetRead pNet, pTaskMan pTasker); int ServerSetupInterrupt(int iPort, pNetRead pNet, pTaskMan pTasker);
/* /*
@ -122,6 +123,7 @@ int InitServer(char *file, pServer * pServ)
NetWatchInit(); NetWatchInit();
/* initialise the server from script */ /* initialise the server from script */
SetWriteHistory(0);
if (file == NULL) { if (file == NULL) {
iRet = InitObjectCommands(self, DEFAULTINIFILE); iRet = InitObjectCommands(self, DEFAULTINIFILE);
} else { } else {
@ -259,6 +261,7 @@ int InitServer(char *file, pServer * pServ)
strcpy(pBueffel, "restore"); strcpy(pBueffel, "restore");
SCInvoke(self->dummyCon, self->pSics, pBueffel); SCInvoke(self->dummyCon, self->pSics, pBueffel);
} }
SetWriteHistory(1);
INIT(StatusFileInit); INIT(StatusFileInit);

1
ofac.c
View File

@ -40,6 +40,7 @@ static void InitGeneral(void)
INIT(UdpInit); INIT(UdpInit);
INIT(HelpInit); INIT(HelpInit);
INIT(AddTestProt); INIT(AddTestProt);
INIT(AddGenBinProtocoll);
INIT(SiteInit); /* site specific initializations */ INIT(SiteInit); /* site specific initializations */
} }

View File

@ -28,19 +28,16 @@ static int timeDue(struct __POLLDRIV *self, time_t now, SConnection * pCon)
/*------------------ HDB Driver -----------------------------------------*/ /*------------------ HDB Driver -----------------------------------------*/
static int pollHdb(struct __POLLDRIV *self, SConnection * pCon) static int pollHdb(struct __POLLDRIV *self, SConnection * pCon)
{ {
hdbValue old, newVal; hdbValue newVal;
pHdb node = NULL; pHdb node = NULL;
memset(&old, 0, sizeof(hdbValue));
memset(&newVal, 0, sizeof(hdbValue)); memset(&newVal, 0, sizeof(hdbValue));
node = (pHdb) self->objPointer; node = (pHdb) self->objPointer;
assert(node != NULL); assert(node != NULL);
old = node->value;
self->nextPoll = time(NULL) + self->pollIntervall; self->nextPoll = time(NULL) + self->pollIntervall;
if (GetHipadabaPar(node, &newVal, pCon) == 1) { if (GetHipadabaPar(node, &newVal, pCon) == 1) {
if (!compareHdbValue(old, newVal)) {
UpdateHipadabaPar(node, newVal, pCon);
}
ReleaseHdbValue(&newVal); ReleaseHdbValue(&newVal);
return 1; return 1;
} else { } else {

View File

@ -366,6 +366,9 @@ static char *SctActionHandler(void *actionData, char *lastReply,
if (!commError && controller->verbose && lastReply != NULL if (!commError && controller->verbose && lastReply != NULL
&& *lastReply != '\0') { && *lastReply != '\0') {
SCPrintf(con, eLog, "%6.3f reply : %s\n", secondsOfMinute(), lastReply); SCPrintf(con, eLog, "%6.3f reply : %s\n", secondsOfMinute(), lastReply);
/**
* TODO: This is the end place of any communication for statistics measurement
*/
} }
/* /*
@ -413,17 +416,20 @@ static char *SctActionHandler(void *actionData, char *lastReply,
/* /*
* an error occurred in the script: store error message in * an error occurred in the script: store error message in
* a property, and write the error message the first time it * a property, and write the error message the first time it
* occurs * occurs.
*
* Replaced <> by - because it messed up XML for Gumtree
* Mark Koennecke
*/ */
snprintf(eprop, sizeof eprop, "error_during_%s", data->name); snprintf(eprop, sizeof eprop, "error_during_%s", data->name);
emsg = GetHdbProp(node, eprop); emsg = GetHdbProp(node, eprop);
if (emsg == NULL || con != controller->conn) { if (emsg == NULL || con != controller->conn) {
GetHdbPath(node, path, sizeof path); GetHdbPath(node, path, sizeof path);
SCPrintf(con, eError, SCPrintf(con, eError,
"ERROR: action <%s> in {%s} node %s:\nERROR: %s", "ERROR: action - %s - in {%s} node %s:\nERROR: %s",
data->name, origScript, path, result); data->name, origScript, path, result);
} }
snprintf(msg, sizeof msg, "<%s> %s", origScript, result); snprintf(msg, sizeof msg, "- %s - %s", origScript, result);
if (strcasecmp(data->name, "read") == 0) { if (strcasecmp(data->name, "read") == 0) {
SetHdbProperty(node, "geterror", result); SetHdbProperty(node, "geterror", result);
} }
@ -476,7 +482,7 @@ static char *SctActionHandler(void *actionData, char *lastReply,
if (emsg != NULL) { if (emsg != NULL) {
GetHdbPath(node, path, sizeof path); GetHdbPath(node, path, sizeof path);
SCPrintf(con, eError, SCPrintf(con, eError,
"action <%s>: success after error message (%s)\n %s", "action - %s -: success after error message (%s)\n %s",
data->name, path, emsg); data->name, path, emsg);
SetHdbProperty(node, eprop, NULL); SetHdbProperty(node, eprop, NULL);
} }
@ -504,6 +510,9 @@ static char *SctActionHandler(void *actionData, char *lastReply,
if (controller->verbose) { if (controller->verbose) {
SCPrintf(con, eLog, "%6.3f send : %s", secondsOfMinute(), send); SCPrintf(con, eLog, "%6.3f send : %s", secondsOfMinute(), send);
} }
/**
* TODO: this is another point where to introduce statistics, this is the start
*/
return send; return send;
} }
} }
@ -1071,6 +1080,7 @@ static int SctQueueCmd(pSICSOBJ ccmd, SConnection * con,
typedef struct SctTransact { typedef struct SctTransact {
char *command; char *command;
char *reply;
int sent; int sent;
SConnection *con; SConnection *con;
SctController *controller; SctController *controller;
@ -1085,6 +1095,9 @@ static void KillSctTransact(void *data)
if (self->command) { if (self->command) {
free(self->command); free(self->command);
} }
if (self->reply) {
free(self->reply);
}
if (self->con) { if (self->con) {
SCDeleteConnection(self->con); SCDeleteConnection(self->con);
} }
@ -1107,7 +1120,9 @@ static char *TransactionHandler(void *actionData, char *lastReply,
if (st->controller->verbose) { if (st->controller->verbose) {
SCPrintf(st->con, eLog, "%6.3f reply : %s", secondsOfMinute(), lastReply); SCPrintf(st->con, eLog, "%6.3f reply : %s", secondsOfMinute(), lastReply);
} }
SCWrite(st->con, lastReply, eValue); /* printf("Transact: %s got %s\n", st->command, lastReply); */
st->reply = strdup(lastReply);
return NULL; return NULL;
} }
} }
@ -1141,6 +1156,11 @@ static int SctTransactCmd(pSICSOBJ ccmd, SConnection * con,
break; break;
} }
} }
if(st->reply != NULL){
SCWrite(con,st->reply,eValue);
} else {
SCWrite(con,"ERROR: no reply!",eError);
}
KillSctTransact(st); KillSctTransact(st);
return 1; return 1;
} }
@ -1207,6 +1227,31 @@ static int SctListActions(pSICSOBJ ccmd, SConnection * con,
return 1; return 1;
} }
static int SctStatistics(pSICSOBJ ccmd, SConnection * con,
Hdb * cmdNode, Hdb * par[], int nPar)
{
SctController *c;
double avg, max;
long errCount;
int errState, maxState, maxCount;
char state[16];
c = (SctController *) ccmd->pPrivate;
DevStatistics(c->devser,&avg, &max, &errCount, &errState);
if(errState == 1){
strcpy(state,"in error");
} else {
strcpy(state,"good");
}
SCPrintf(con,eValue,"Average roundtrip time: %lf, maximum roundtrip time %lf, com error count: %ld, com state: %s",
avg, max, errCount, state);
DevAsconStatistics(c->devser,&avg, &max, &maxState, &maxCount);
SCPrintf(con,eValue,"Average time in AsconTask: %lf, maximum time spent in AsconTask %lf, state of Ascon on max %d, count > max/2 %d",
avg, max, maxState, maxCount);
return 1;
}
static hdbCallbackReturn SctDebugCallback(Hdb * node, void *userData, static hdbCallbackReturn SctDebugCallback(Hdb * node, void *userData,
hdbMessage * msg) hdbMessage * msg)
{ {
@ -1369,6 +1414,9 @@ static int SctMakeController(SConnection * con, SicsInterp * sics,
cmd = AddSICSHdbPar(controller->node, cmd = AddSICSHdbPar(controller->node,
"actions", usUser, MakeSICSFunc(SctListActions)); "actions", usUser, MakeSICSFunc(SctListActions));
cmd = AddSICSHdbPar(controller->node,
"statistics", usSpy, MakeSICSFunc(SctStatistics));
cb = MakeHipadabaCallback(SctDebugCallback, controller, NULL); cb = MakeHipadabaCallback(SctDebugCallback, controller, NULL);
if (cb) if (cb)
AppendHipadabaCallback(par, cb); AppendHipadabaCallback(par, cb);

View File

@ -7,6 +7,8 @@
copyright: see copyright.h copyright: see copyright.h
Mark Koennecke, November 1999 Mark Koennecke, November 1999
modified to give more error output: Mark Koennecke, December 2010
------------------------------------------------------------------------*/ ------------------------------------------------------------------------*/
#include <stdlib.h> #include <stdlib.h>
#include <assert.h> #include <assert.h>
@ -16,7 +18,7 @@
#include "sics.h" #include "sics.h"
#include "splitter.h" #include "splitter.h"
#include "sicscron.h" #include "sicscron.h"
#include "commandlog.h"
typedef struct { typedef struct {
int iInterval; int iInterval;
@ -61,6 +63,8 @@ static int CronTask(void *pData)
int iRet; int iRet;
Tcl_Interp *pTcl = pServ->pSics->pTcl; Tcl_Interp *pTcl = pServ->pSics->pTcl;
time_t now; time_t now;
struct tm *nowtm;
char buffer[1024];
if (!self) { if (!self) {
return 0; return 0;
@ -75,14 +79,16 @@ static int CronTask(void *pData)
MacroPop(); MacroPop();
if (iRet != TCL_OK) { if (iRet != TCL_OK) {
if (strcmp(pTcl->result, "stop") == 0) { if (strcmp(pTcl->result, "stop") == 0) {
SCPrintf(self->pCon, eLogError, "sicscron script '%s' stopped", snprintf(buffer,1024,"sicscron script '%s' stopped with %s",
self->pCommand); self->pCommand, pTcl->result);
SCPrintf(self->pCon, eLogError, buffer);
WriteToCommandLog("SICSCRON:", buffer);
self->iEnd = 0; self->iEnd = 0;
return 0; return 0;
} }
SCPrintf(self->pCon, eLogError, snprintf(buffer,1024,"ERROR in sicscron script '%s': %s", self->pCommand, pTcl->result);
"ERROR in sicscron script '%s':", self->pCommand); SCPrintf(self->pCon, eLogError,buffer);
SCPrintf(self->pCon, eLogError, "ERROR: %s", pTcl->result); WriteToCommandLog("SICSCRON:", buffer);
} }
if (self->iEnd == 2) { /* dolater command */ if (self->iEnd == 2) { /* dolater command */
self->iEnd = 0; self->iEnd = 0;
@ -92,6 +98,11 @@ static int CronTask(void *pData)
if (now > self->tNext) if (now > self->tNext)
self->tNext = now + 1; self->tNext = now + 1;
} }
/* printf("CronTask return: %d\n", self->iEnd > 0);*/
if(self->iEnd <= 0){
snprintf(buffer,1024,"crontask terminating at %s on %d", ctime(&now), self->iEnd);
WriteToCommandLog("SICSCRON", buffer);
}
return self->iEnd > 0; return self->iEnd > 0;
} }
@ -106,7 +117,7 @@ static void CronSignal(void *pData, int iID, void *pSigData)
if (iID == SICSINT) { if (iID == SICSINT) {
iInt = (int *) pSigData; iInt = (int *) pSigData;
if (*iInt >= eEndServer) { if (*iInt == eEndServer) {
self->iEnd = 0; self->iEnd = 0;
} }
} }

View File

@ -337,7 +337,6 @@ static long totalSum(int *data, int length)
/*----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/
typedef struct { typedef struct {
pHistMem pHM; pHistMem pHM;
long oldSum;
} HMAdapter, *pHMAdapter; } HMAdapter, *pHMAdapter;
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
static hdbCallbackReturn HMDataGetCallback(pHdb currentNode, static hdbCallbackReturn HMDataGetCallback(pHdb currentNode,
@ -360,13 +359,6 @@ static hdbCallbackReturn HMDataGetCallback(pHdb currentNode,
currentNode->value.arrayLength = GetHistLength(pHMA->pHM); currentNode->value.arrayLength = GetHistLength(pHMA->pHM);
currentNode->value.v.intArray = currentNode->value.v.intArray =
(int *) GetHistogramPointer(pHMA->pHM, pCon); (int *) GetHistogramPointer(pHMA->pHM, pCon);
sum1 =
totalSum(currentNode->value.v.intArray,
currentNode->value.arrayLength);
if (sum1 != pHMA->oldSum) {
UpdateHipadabaPar(currentNode, currentNode->value, NULL);
pHMA->oldSum = sum1;
}
return hdbContinue; return hdbContinue;
} }
@ -377,14 +369,14 @@ static pHdb MakeHMDataNode(pHistMem pHM, char *name)
pHdbCallback pCall = NULL; pHdbCallback pCall = NULL;
pHMAdapter pHMA = NULL; pHMAdapter pHMA = NULL;
node = MakeHipadabaNode(name, HIPINTVARAR, 2); node = MakeHipadabaNode(name, HIPINTVARAR, GetHistLength(pHM));
pHMA = malloc(sizeof(HMAdapter)); pHMA = malloc(sizeof(HMAdapter));
if (node == NULL || pHMA == NULL) { if (node == NULL || pHMA == NULL) {
return NULL; return NULL;
} }
pHMA->pHM = pHM; pHMA->pHM = pHM;
pHMA->oldSum = 0;
node->value.doNotFree = 1; node->value.doNotFree = 1;
node->value.v.intArray = (int *)GetHistogramPointer(pHM, pServ->dummyCon);
pCall = MakeHipadabaCallback(HMDataGetCallback, pHMA, free); pCall = MakeHipadabaCallback(HMDataGetCallback, pHMA, free);
if (pCall == NULL) { if (pCall == NULL) {
return NULL; return NULL;

View File

@ -34,6 +34,7 @@
#include <splitter.h> #include <splitter.h>
#include "sicsobj.h" #include "sicsobj.h"
#include <macro.h> #include <macro.h>
#include "commandlog.h"
#define MAX_HDB_PATH 1024 #define MAX_HDB_PATH 1024
@ -828,7 +829,9 @@ static hdbCallbackReturn SICSScriptReadCallback(pHdb node, void *userData,
if (pCon != NULL) { if (pCon != NULL) {
MacroPush(pCon); MacroPush(pCon);
} }
SetWriteHistory(0);
status = Tcl_Eval(InterpGetTcl(pServ->pSics), command); status = Tcl_Eval(InterpGetTcl(pServ->pSics), command);
SetWriteHistory(1);
if (pCon != NULL) { if (pCon != NULL) {
MacroPop(); MacroPop();
} }

View File

@ -1,60 +1,13 @@
exe batchpath ./ exe batchpath ./
exe syspath ./ exe syspath ./
sample
sample setAccess 2 #--- BEGIN (commands producing errors on last restore)
title #--- END (commands producing errors on last restore)
title setAccess 2
user
user setAccess 2
email unknown
email setAccess 2
address unknown
address setAccess 2
fax unknown
fax setAccess 2
phone unknown
phone setAccess 2
# Motor som
som sign 1.000000
som SoftZero 0.000000
som SoftLowerLim -180.000000
som SoftUpperLim 180.000000
som Fixed -1.000000
som InterruptMode 0.000000
som precision 0.010000
som ignorefault 0.000000
som AccessCode 2.000000
som failafter 3.000000
som maxretry 3.000000
som movecount 10.000000
# Motor stt
stt sign 1.000000
stt SoftZero 0.000000
stt SoftLowerLim 0.000000
stt SoftUpperLim 120.000000
stt Fixed -1.000000
stt InterruptMode 0.000000
stt precision 0.010000
stt ignorefault 0.000000
stt AccessCode 2.000000
stt failafter 3.000000
stt maxretry 3.000000
stt movecount 10.000000
# Motor dth
dth sign 1.000000
dth SoftZero 0.000000
dth SoftLowerLim 0.000000
dth SoftUpperLim 200.000000
dth Fixed -1.000000
dth InterruptMode 0.000000
dth precision 0.010000
dth ignorefault 0.000000
dth AccessCode 2.000000
dth failafter 3.000000
dth maxretry 3.000000
dth movecount 10.000000
# Counter counter # Counter counter
counter SetPreset 1000.000000 counter SetPreset 7.000000
counter SetMode Timer counter SetMode Timer
hm CountMode timer hm preset 7
hm preset 3.000000 hm mode monitor
title UNKNOWN
title setAccess 2

View File

@ -48,7 +48,7 @@ static int calculateTASSettings(pSingleDiff self,
return 0; return 0;
} }
status = calcTasQAngles(self->UB, mn, 1, qe, &angles); status = calcTasQAngles(self->UB, mn, 1,0, qe, &angles);
if (status < 0) { if (status < 0) {
status = 0; status = 0;
} else { } else {

View File

@ -665,7 +665,7 @@ int MakeSingleX(SConnection * pCon, SicsInterp * pSics,
if (AddCommand(pSics, "singlex", SingleXAction, KillSICSOBJ, pNew)) { if (AddCommand(pSics, "singlex", SingleXAction, KillSICSOBJ, pNew)) {
HKLFactory(pCon, pSics, data, argc, argv); HKLFactory(pCon, pSics, data, argc, argv);
HKLMotInstall(pCon, pSics, data, argc, argv); HKLMotInstall(pCon, pSics, data, argc, argv);
CreateUBCalc(pCon, pSics, "ubcalc", "hkl"); CreateUBCalc(pCon, pSics, "ubcalcint", "hkl");
InstallFourMess(pCon, pSics); InstallFourMess(pCon, pSics);
MakeCone(pCon, pSics, data, argc, argv); MakeCone(pCon, pSics, data, argc, argv);
InitSimpleIndex(pCon, pSics); InitSimpleIndex(pCon, pSics);

View File

@ -524,7 +524,7 @@ int WriteScanPoints(pScanData self, int iPoint)
DynarGet(self->pScanVar, i2, &pPtr); DynarGet(self->pScanVar, i2, &pPtr);
pVar = (pVarEntry) pPtr; pVar = (pVarEntry) pPtr;
if (pVar) { if (pVar) {
snprintf(pItem,sizeof(pItem)-1, "%-9.3f ", GetScanVarPos(pVar, i)); snprintf(pItem,sizeof(pItem)-1, "%-9.4f ", GetScanVarPos(pVar, i));
strlcat(pLine, pItem,1024); strlcat(pLine, pItem,1024);
} }
} }

View File

@ -258,6 +258,7 @@ static int startTASMotor(pMotor mot, SConnection * pCon, char *name,
SCWrite(pCon, buffer, eWarning); SCWrite(pCon, buffer, eWarning);
return OKOK; return OKOK;
} }
mot->stopped = 0;
if (ABS(val - target) > MOTPREC) { if (ABS(val - target) > MOTPREC) {
status = mot->pDrivInt->SetValue(mot, pCon, (float) target); status = mot->pDrivInt->SetValue(mot, pCon, (float) target);
if (status != OKOK) { if (status != OKOK) {
@ -524,7 +525,7 @@ static int checkMotors(ptasMot self, SConnection * pCon)
for (i = 0; i < length; i++) { for (i = 0; i < length; i++) {
mask[i] = 1; mask[i] = 1;
} }
if (self->math->outOfPlaneAllowed != 0) { if (self->math->outOfPlaneAllowed == 0) {
mask[SGU] = 0; mask[SGU] = 0;
mask[SGL] = 0; mask[SGL] = 0;
} }

24
tasub.c
View File

@ -1857,7 +1857,7 @@ int TasUBWrapper(SConnection * pCon, SicsInterp * pSics, void *pData,
ptasUB self = NULL; ptasUB self = NULL;
char pBueffel[131]; char pBueffel[131];
int status, newSS; int status, newSS;
double misalign = .0; double misalign = .0, a3offset;
self = (ptasUB) pData; self = (ptasUB) pData;
assert(self != NULL); assert(self != NULL);
@ -2039,6 +2039,28 @@ int TasUBWrapper(SConnection * pCon, SicsInterp * pSics, void *pData,
SCWrite(pCon, pBueffel, eValue); SCWrite(pCon, pBueffel, eValue);
return 1; return 1;
} }
} else if (strcmp(argv[1], "a3offset") == 0) {
if (argc > 2) {
strtolower(argv[2]);
if (!SCMatchRights(pCon, usMugger)) {
return 0;
}
status = Tcl_GetDouble(InterpGetTcl(pSics), argv[2], &a3offset);
if (status != TCL_OK) {
SCWrite(pCon, "ERROR: failed to convert argument to number",
eError);
return 0;
}
self->machine.a3offset = a3offset;
invokeUpdate(self,pCon,"main");
SCSendOK(pCon);
return 1;
} else {
snprintf(pBueffel, 131, "%s.a3offset = %lf", argv[0],
self->machine.a3offset);
SCWrite(pCon, pBueffel, eValue);
return 1;
}
} else if (strcmp(argv[1], "silent") == 0) { } else if (strcmp(argv[1], "silent") == 0) {
if (argc > 2) { if (argc > 2) {
strtolower(argv[2]); strtolower(argv[2]);

View File

@ -540,8 +540,8 @@ int calcTasMisalignment(ptasMachine machine, tasQEPosition qe, double *misalign
} }
/*-------------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------------*/
int calcTasQAngles(MATRIX UB, MATRIX planeNormal, int ss, tasQEPosition qe, int calcTasQAngles(MATRIX UB, MATRIX planeNormal, int ss, double a3offset,
ptasAngles angles) tasQEPosition qe, ptasAngles angles)
{ {
MATRIX R, QC; MATRIX R, QC;
double om, q, theta, cos2t; double om, q, theta, cos2t;
@ -596,14 +596,14 @@ int calcTasQAngles(MATRIX UB, MATRIX planeNormal, int ss, tasQEPosition qe,
theta = calcTheta(qe.ki, qe.kf, angles->sample_two_theta); theta = calcTheta(qe.ki, qe.kf, angles->sample_two_theta);
angles->a3 = om + theta; angles->a3 = om + theta + a3offset;
/* /*
put a3 into -180, 180 properly. We can always turn by 180 because the put a3 into -180, 180 properly. We can always turn by 180 because the
scattering geometry is symmetric in this respect. It is like looking at scattering geometry is symmetric in this respect. It is like looking at
the scattering plane from the other side the scattering plane from the other side
*/ */
angles->a3 -= 180.; angles->a3 -= 180.;
if (angles->a3 < -180.) { if (angles->a3 < -180 - a3offset) {
angles->a3 += 360.; angles->a3 += 360.;
} }
@ -680,7 +680,8 @@ int calcAllTasAngles(ptasMachine machine, tasQEPosition qe,
} }
status = calcTasQAngles(machine->UB, machine->planeNormal, status = calcTasQAngles(machine->UB, machine->planeNormal,
machine->ss_sample, qe, angles); machine->ss_sample,
machine->a3offset, qe, angles);
if (status != 1) { if (status != 1) {
return status; return status;
} }

View File

@ -53,6 +53,7 @@ typedef struct {
MATRIX UB; MATRIX UB;
MATRIX planeNormal; MATRIX planeNormal;
int ss_sample; /* scattering sense sample */ int ss_sample; /* scattering sense sample */
double a3offset;
} tasMachine, *ptasMachine; } tasMachine, *ptasMachine;
/** /**
* a position in Q - Energy space * a position in Q - Energy space
@ -178,12 +179,14 @@ MATRIX calcPlaneNormal(tasReflection r1, tasReflection r2);
* @param UB The UB matrix to use * @param UB The UB matrix to use
* @param planeNormal The normal to the scattering plane to use * @param planeNormal The normal to the scattering plane to use
* @param ss The scattering sense at the sample * @param ss The scattering sense at the sample
* @param The Mark Laver offset to a3. 0 is always a good value for this
* @param qe The desired Q Energy position * @param qe The desired Q Energy position
* @param angles The resulting angles. * @param angles The resulting angles.
* @return 1 on success, a negative error code when errors are encountered * @return 1 on success, a negative error code when errors are encountered
*/ */
int calcTasQAngles(MATRIX UB, MATRIX planeNormal, int calcTasQAngles(MATRIX UB, MATRIX planeNormal,
int ss, tasQEPosition qe, ptasAngles angles); int ss, double a3offset,
tasQEPosition qe, ptasAngles angles);
/** /**
* calculate QH, QK, QL from the angles given * calculate QH, QK, QL from the angles given
* @param UB The UB matrix to use * @param UB The UB matrix to use

View File

@ -13,6 +13,11 @@
# copyright: see file COPYRIGHT # copyright: see file COPYRIGHT
# #
# Mark Koennecke, May 2009 # Mark Koennecke, May 2009
#
# You will need to override hmhttpevalstatus to implement
# an update of the detector data
#
# Mark Koennecke, April 2010
#--------------------------------------------------------- #---------------------------------------------------------
proc hmhttpsend {url} { proc hmhttpsend {url} {
sct send $url sct send $url
@ -127,7 +132,7 @@ proc hmhttpevalstatus {name} {
#--------------------------------------------------------- #---------------------------------------------------------
proc MakeHTTPHM {name rank host initscript {tof NULL} } { proc MakeHTTPHM {name rank host initscript {tof NULL} } {
sicsdatafactory new ${name}transfer sicsdatafactory new ${name}transfer
makesctcontroller ${name}sct sinqhttp $host ${name}transfer 600 spy 007 makesctcontroller ${name}sct sinqhttpopt $host ${name}transfer 600 spy 007
MakeSecHM $name $rank $tof MakeSecHM $name $rank $tof
hsetprop /sics/${name}/control write hmhttpcontrol hsetprop /sics/${name}/control write hmhttpcontrol
hsetprop /sics/${name}/control hmhttpreply hmhttpreply hsetprop /sics/${name}/control hmhttpreply hmhttpreply

View File

@ -1,3 +1,3 @@
294 302
NEVER, EVER modify or delete this file NEVER, EVER modify or delete this file
You'll risk eternal damnation and a reincarnation as a cockroach! You'll risk eternal damnation and a reincarnation as a cockroach!

View File

@ -234,9 +234,9 @@ singlex peaksearch/chimin 90
singlex peaksearch/chimax 180 singlex peaksearch/chimax 180
#HKL Settings #HKL Settings
hkl scantolerance 2.500000 hkl scantolerance 2.500000
ubcalc difftheta 0.300000 ubcalcint difftheta 0.300000
ubcalc maxindex 5 ubcalcint maxindex 5
ubcalc maxlist 10 ubcalcint maxlist 10
fmesstable clear fmesstable clear
messref anglesheader stt,om,chi,phi messref anglesheader stt,om,chi,phi
messref clear messref clear
@ -251,5 +251,7 @@ cone qscale 1
cone center unknown cone center unknown
simidx sttlim 0.2 simidx sttlim 0.2
simidx anglim 0.5 simidx anglim 0.5
apple preset 0
apple mode monitor
simi preset 0 simi preset 0
simi mode monitor simi mode monitor

View File

@ -528,7 +528,7 @@ amorhmsct poll /sics/amorhm/collapse 20
#source ../sim/mars/julcho.tcl #source ../sim/mars/julcho.tcl
MakeSinq MakeSinqRedirect lnsl15 10500
MakeSingleX MakeSingleX
singlex configure stt a4 singlex configure stt a4
@ -636,13 +636,13 @@ proc tofappleinit {} {
set hmhttp 0 set hmhttp 0
if {$hmhttp == 1} { if {$hmhttp == 1} {
source ../tcl/sinqhttp.tcl source ../tcl/sinqhttp.tcl
MakeHTTPHM apple 1 hm02 appleinit # MakeHTTPHM apple 1 hm01 appleinit
# MakeHTTPHM apple 1 localhost:8080 appleinit # MakeHTTPHM apple 1 localhost:8080 appleinit
apple dim 16384 # apple dim 16384
#---------- for TOF #---------- for TOF
# MakeHTTPHM apple 2 hm02 tofappleinit tof MakeHTTPHM apple 2 hm01 tofappleinit tof
# apple dim 16384 10 apple dim 16384 10
# apple genbin 10 20 100 apple genbin 10 20 100
applesct debug 0 applesct debug 0
apple init apple init
} }
@ -752,3 +752,6 @@ zugsct debug 0
source ../tcl/stddrive.tcl source ../tcl/stddrive.tcl
source ../sim/poldi_sics/zug.tcl source ../sim/poldi_sics/zug.tcl
} }
#MakeSPSS7 s7 203 251 129.129.195.55:2005
#MakeSPSS7 s7 203 251 localhost:8090

View File

@ -1,19 +1,21 @@
sample La Cu2 O4+x 1/3 1/3 2 map 5K, CuCrO2
2 1 0 0 23. 5. 4 1 .5 0 2 1 0 0 45 3 4 1 .5 0
0 2.3167 0 1.178
1 0.0 1 0.0 1 0.0 0 0.0 0 .0 0 .0 0 .0
1 5.32 1 5.40 1 13.18 0 90 0 90 0 90 0 2.9667 0 2.9667 0 17.3977 0 90 0 90 0 120
-2 0 0 51.30 28.02 131.50 17.44 1773 1.0000 1.0000 0.0000 46.742 23.322 182.960 178.382
0 0 2 20.58 13.91 182.04 289.68 1780 -1.0000 2.0000 0.0000 46.740 23.244 182.601 238.437
0 -2 0 51.23 25.61 140.29 197.69 1784 0.0000 0.0000 6.0000 23.867 11.737 92.919 77.023
-2 -2 0 75.59 38.04 95.27 221.22 1787 0.0000 -2.0000 1.0000 54.687 27.298 173.003 28.437
-2 -2 2 79.32 40.26 108.56 272.88 1791 0.0000 1.0000 1.0000 26.807 13.375 175.101 208.398
-2 0 4 68.20 34.42 144.68 323.66 1819 1.0000 0.0000 2.0000 27.727 13.848 165.785 149.054
1 -1 3 48.02 24.08 185.50 236.97 1801 0.0000 -1.0000 5.0000 33.282 16.614 140.921 28.625
-2 2 0 75.82 37.79 174.43 15.78 1804 1.0000 0.0000 5.0000 33.270 16.627 145.492 150.046
1 -1 1 37.50 18.65 185.79 211.98 1809 -1.0000 1.0000 8.0000 41.915 20.725 131.535 265.171
0 0 6 64.07 31.95 181.88 285.97 1812 1.0000 0.0000 8.0000 41.915 20.978 132.105 151.023
0 0 8 89.90 42.93 181.81 284.09 1816 0.0000 2.0000 2.0000 55.172 27.515 174.425 208.367
1 0 0 -2.0000 0.0000 2.0000 55.177 27.515 170.078 328.031
0 1 0 3.0000 0.0000 0.0000 86.800 43.319 181.531 148.375
1 0 0 0.0000 3.0000 0.0000 86.802 43.319 182.796 208.429
-1