- Added a protocol driver for the munich sputter machine

- Added a multicountsersec to teplace hmcontrol and multicounter
- Fixed a case sensitivity bug in haddcheck
- Made oscillate work with second generation motors for POLDI
- Added a time stamper to trace. Now there will be time stamps in trace files which allow
  to correlate things from the master log with the trace.
- Updated polterwrite.
- Updated testprot to work with the behave test


SKIPPED:
	psi/make_gen
	psi/polterwrite.c
	psi/psi.c
	psi/sputterprot.c
This commit is contained in:
koennecke
2013-11-04 12:55:15 +00:00
parent 8ecf2f37a5
commit ad241bd99e
15 changed files with 829 additions and 190 deletions

View File

@ -1543,6 +1543,55 @@ int SCPrompt(SConnection * pCon, char *pPrompt, char *pResult, int iLen)
CostaLock(master->pStack); CostaLock(master->pStack);
return 0; return 0;
} }
/*----------------------------------------------------------------------------*/
int SCPromptTMO(SConnection * pCon, char *pPrompt, char *pResult, int iLen, int timeout)
{
int iRet, i;
char *pPtr = NULL;
char pFrom[50];
Status eOld;
int oldMode;
SConnection *master = NULL;
if (!VerifyConnection(pCon)) {
return 0;
}
SCWrite(pCon, pPrompt, eWarning);
master = SCfindMaster(pCon);
eOld = GetStatus();
SetStatus(eInput);
CostaUnlock(master->pStack);
for(i = 0; i < timeout; i++) {
/*
wait a second. We want to wait even in a simulation, otherwise
we go into an endless loop. This is why there is the hack with
oldMode and pServ->simMode.
*/
oldMode = pServ->simMode;
pServ->simMode = 0;
SicsWait(1);
pServ->simMode = oldMode;
/* is there an interrupt pending ? */
if (SCGetInterrupt(pCon) != eContinue) {
break;
}
/* do we have data ? */
iRet = CostaPop(master->pStack, &pPtr);
if (iRet == 1) {
SetStatus(eOld);
CostaLock(master->pStack);
strlcpy(pResult, pPtr, iLen);
WriteToCommandLogId(" prompted>", pCon->sockHandle, pPtr);
return 1;
}
}
SetStatus(eOld);
CostaLock(master->pStack);
return 0;
}
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
int SCGetRights(SConnection * self) int SCGetRights(SConnection * self)

View File

@ -95,6 +95,7 @@ int SCWrite(SConnection * self, char *pBuffer, int iOut);
int SCPrintf(SConnection * self, int iOut, char *fmt, ...); int SCPrintf(SConnection * self, int iOut, char *fmt, ...);
int SCRead(SConnection * self, char *pBuffer, int iBufLen); int SCRead(SConnection * self, char *pBuffer, int iBufLen);
int SCPrompt(SConnection * pCon, char *pPrompt, char *pResult, int iLen); int SCPrompt(SConnection * pCon, char *pPrompt, char *pResult, int iLen);
int SCPromptTMO(SConnection * pCon, char *pPrompt, char *pResult, int iLen, int timeout);
int SCSendOK(SConnection * self); int SCSendOK(SConnection * self);
int SCnoSock(SConnection * pCon); int SCnoSock(SConnection * pCon);
int SCWriteUUencoded(SConnection * pCon, char *pName, void *iData, int SCWriteUUencoded(SConnection * pCon, char *pName, void *iData,

View File

@ -121,96 +121,96 @@ static int SecContinue(void *pData, SConnection *pCon)
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
static int SecCtrCheckStatus(void *pData, SConnection *pCon) static int SecCtrCheckStatus(void *pData, SConnection *pCon)
{ {
pCounter self = (pCounter)pData; pCounter self = (pCounter)pData;
pHdb node = NULL, control = NULL; pHdb node = NULL, control = NULL;
hdbValue v; hdbValue v;
int status; int status;
MonEvent sMon; MonEvent sMon;
float fControl, fPreset; float fControl, fPreset;
char error[132]; char error[132];
assert(self != NULL); assert(self != NULL);
node = GetHipadabaNode(self->pDes->parNode,"status"); node = GetHipadabaNode(self->pDes->parNode,"status");
assert(node != NULL); assert(node != NULL);
status = GetHipadabaPar(node,&v,pCon); status = GetHipadabaPar(node,&v,pCon);
if(status != 1){ if(status != 1){
ReleaseCountLock(self->pCountInt); ReleaseCountLock(self->pCountInt);
return HWFault; return HWFault;
} }
if(v.v.text == NULL){ if(v.v.text == NULL){
return HWBusy; return HWBusy;
} }
if (strstr(v.v.text, "idle") != NULL) { if (strstr(v.v.text, "idle") != NULL) {
InvokeCallBack(self->pCall, COUNTEND, NULL); InvokeCallBack(self->pCall, COUNTEND, NULL);
ReleaseCountLock(self->pCountInt); ReleaseCountLock(self->pCountInt);
status = HWIdle; status = HWIdle;
} else if (strstr(v.v.text, "run") != NULL) { } else if (strstr(v.v.text, "run") != NULL) {
status = HWBusy; status = HWBusy;
} else if (strstr(v.v.text, "nobeam") != NULL) { } else if (strstr(v.v.text, "nobeam") != NULL) {
status = HWNoBeam; status = HWNoBeam;
} else if (strstr(v.v.text, "pause") != NULL) { } else if (strstr(v.v.text, "pause") != NULL) {
status = HWPause; status = HWPause;
} else if (strstr(v.v.text, "restart") != NULL) { } else if (strstr(v.v.text, "restart") != NULL) {
SecStartCount(self, pCon); SecStartCount(self, pCon);
return HWBusy; return HWBusy;
} else if (strstr(v.v.text, "error") != NULL) { } else if (strstr(v.v.text, "error") != NULL) {
InvokeCallBack(self->pCall, COUNTEND, NULL); InvokeCallBack(self->pCall, COUNTEND, NULL);
ReleaseCountLock(self->pCountInt); ReleaseCountLock(self->pCountInt);
if(GetHdbProperty(node,"geterror",error,sizeof(error)) == 1){ if(GetHdbProperty(node,"geterror",error,sizeof(error)) == 1){
SCPrintf(pCon,eError,"ERROR: %s", error); SCPrintf(pCon,eError,"ERROR: %s", error);
SecCounterSetError(self,error); SecCounterSetError(self,error);
} else { } else {
SecCounterSetError(self,"Undefined counter error: set status geterror"); SecCounterSetError(self,"Undefined counter error: set status geterror");
SCPrintf(pCon,eError,"ERROR: Unknown counter status error: set status geterror property"); SCPrintf(pCon,eError,"ERROR: Unknown counter status error: set status geterror property");
} }
status = HWFault; status = HWFault;
} else { } else {
SCPrintf(pCon, eError, "ERROR: unknown counter status %s found", SCPrintf(pCon, eError, "ERROR: unknown counter status %s found",
v.v.text); v.v.text);
ReleaseCountLock(self->pCountInt); ReleaseCountLock(self->pCountInt);
status = HWFault; status = HWFault;
} }
ReleaseHdbValue(&v); ReleaseHdbValue(&v);
node = GetHipadabaNode(self->pDes->parNode,"control"); node = GetHipadabaNode(self->pDes->parNode,"control");
assert(node != NULL); assert(node != NULL);
GetHipadabaPar(node,&v,pCon); GetHipadabaPar(node,&v,pCon);
fControl = v.v.doubleValue; fControl = v.v.doubleValue;
node = GetHipadabaNode(self->pDes->parNode,"preset"); node = GetHipadabaNode(self->pDes->parNode,"preset");
assert(node != NULL); assert(node != NULL);
GetHipadabaPar(node,&v,pCon); GetHipadabaPar(node,&v,pCon);
fPreset = v.v.doubleValue; fPreset = v.v.doubleValue;
sMon.fCurrent = fControl; sMon.fCurrent = fControl;
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 * check for overrun counter boxes
*/ */
if(self->getMode(self) == eTimer && if(self->getMode(self) == eTimer &&
(sMon.fCurrent > sMon.fPreset +1) (sMon.fCurrent > sMon.fPreset +1)
&& self->haltFixFlag == 0){ && self->haltFixFlag == 0){
SecCtrHalt(self); SecCtrHalt(self);
self->haltFixFlag = 1; self->haltFixFlag = 1;
} }
/* /*
* invoke notifiactions, if necessary * 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;
} else { } else {
self->iCallbackCounter++; self->iCallbackCounter++;
} }
return status; return status;
} }
/*--------------------------------------------------------------------------- /*---------------------------------------------------------------------------
* Here is an issue: this ought to wait until data has arrived. Callers * Here is an issue: this ought to wait until data has arrived. Callers
@ -221,6 +221,12 @@ static int SecCtrCheckStatus(void *pData, SConnection *pCon)
* - add an update callback which deletes the property when done. * - add an update callback which deletes the property when done.
* - Check that property or the geterror property here in a loop * - Check that property or the geterror property here in a loop
* until done or we timeout. * until done or we timeout.
*
* Nope! Update October 2013:
* How it is normally done is to read the data through scripcontext when
* counting is finished and not to finish with counting until this has
* been done. The code below is only usefule for non scriptcontext
* drivers.
* -----------------------------------------------------------------------*/ * -----------------------------------------------------------------------*/
static int SecCtrTransferData(void *pData, SConnection *pCon) static int SecCtrTransferData(void *pData, SConnection *pCon)
{ {
@ -551,6 +557,9 @@ pCounter CreateSecCounter(SConnection *pCon, char *type, char *name, int length)
return NULL; return NULL;
} }
SetHdbProperty(child, "__save", "true"); SetHdbProperty(child, "__save", "true");
SetHdbProperty(child, "values", "timer,monitor");
PrependHipadabaCallback(child,MakeHipadabaCallback(SICSValueCheckCallback,
NULL,NULL));
AddHipadabaChild(node, child, NULL); AddHipadabaChild(node, child, NULL);
child = MakeSICSHdbPar("status", usInternal, MakeHdbText("idle")); child = MakeSICSHdbPar("status", usInternal, MakeHdbText("idle"));

16
danu.c
View File

@ -75,7 +75,7 @@ static int readDataNumber(pDataNumber self)
} }
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
static int writeDataNumber(pDataNumber self, int iNum) static int writeDataNumber(pDataNumber self, int iNum)
{ {
FILE *fd = NULL; FILE *fd = NULL;
@ -126,7 +126,18 @@ static int InterestCallback(int iEvent, void *pEvent, void *pUser)
} }
return 1; return 1;
} }
/*-------------------------------------------------------------------------*/
static void *GetDanuInterface(void *data, int interfaceID)
{
pDataNumber self = (pDataNumber)data;
if(self == NULL){
return NULL;
}
if(interfaceID == CALLBACKINTERFACE){
return self->pCall;
}
return NULL;
}
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
pDataNumber CreateDataNumber(char *pFileName) pDataNumber CreateDataNumber(char *pFileName)
{ {
@ -140,6 +151,7 @@ pDataNumber CreateDataNumber(char *pFileName)
memset(pNew, 0, sizeof(DataNumber)); memset(pNew, 0, sizeof(DataNumber));
pNew->pDes = CreateDescriptor("DataNumber"); pNew->pDes = CreateDescriptor("DataNumber");
pNew->pDes->GetInterface = GetDanuInterface;
pNew->pCall = CreateCallBackInterface(); pNew->pCall = CreateCallBackInterface();
if (!pNew->pDes || !pNew->pCall) { if (!pNew->pDes || !pNew->pCall) {
free(pNew); free(pNew);

View File

@ -376,6 +376,8 @@ static int CountTaskFunc(void *data)
return 1; return 1;
} }
taskData->pCount->TransferData(taskData->obj, taskData->pCon);
if(status == HWFault){ if(status == HWFault){
SetDevexecStatus(pServ->pExecutor,DEVERROR); SetDevexecStatus(pServ->pExecutor,DEVERROR);
} }

View File

@ -44,7 +44,7 @@ SOBJ = network.o ifile.o conman.o SCinter.o splitter.o passwd.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 genbinprot.o trace.o\ histmemsec.o sansbc.o sicsutil.o strlutil.o genbinprot.o trace.o\
singlebinb.o taskobj.o sctcomtask.o tasmono.o singlebinb.o taskobj.o sctcomtask.o tasmono.o multicountersec.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

520
multicountersec.c Normal file
View File

@ -0,0 +1,520 @@
/**
* This is a second generation multicounter. It coordinates counting multiple
* HM/CCD with the counter box. It also allows to override transfer such that
* such a counter can be used in a scan. As with the ordinary multicounter.
* This one is supposed to become the standard multicounter replacing the old
* multicounter and the hmcontrol module. The other difference is that the task
* mechanism will be used to keep track of counters.
*
* copyright: see file COPYRIGHT
*
* Mark Koennecke, October 2013
*/
#include <time.h>
#include <sics.h>
#include <counter.h>
#include <stptok.h>
#include <macro.h>
#include "sicshipadaba.h"
/*-------------------------------------------------------------------------*/
static void SecCounterSetError(pCounter self, char *text)
{
hdbValue v;
pHdb node;
node = GetHipadabaNode(self->pDes->parNode, "error");
if(node != NULL){
v = MakeHdbText(strdup(text));
UpdateHipadabaPar(node,v,NULL);
ReleaseHdbValue(&v);
}
}
/*---------------------------------------------------------------------------------*/
static void doCountCommand(pHdb self, SConnection *pCon, int command)
{
pHdb master = NULL, slaves = NULL;
char *pPtr, name[80];
pICountable pCount = NULL;
void *data;
master = GetHipadabaNode(self,"master");
slaves = GetHipadabaNode(self,"slaves");
assert(master != NULL);
assert(slaves != NULL);
/*
treat master
*/
data = FindCommandData(pServ->pSics,master->value.v.text,NULL);
if(data != NULL){
pCount = GetCountableInterface(data);
if(pCount != NULL){
switch(command){
case 1001: /* stop */
pCount->Halt(data);
break;
case 1002: /*pause */
pCount->Pause(data,pCon);
break;
case 1003: /* continue */
pCount->Continue(data,pCon);
break;
case 1011:
break;
default:
assert(0);
}
}
}
/*
treat slaves
*/
pPtr = slaves->value.v.text;
while((pPtr = stptok(pPtr,name,sizeof(name),",")) != NULL){
data = FindCommandData(pServ->pSics,name,NULL);
if(data != NULL){
pCount = GetCountableInterface(data);
if(pCount != NULL){
switch(command){
case 1001: /* stop */
case 1011:
pCount->Halt(data);
break;
case 1002: /*pause */
pCount->Pause(data,pCon);
break;
case 1003: /* continue */
pCount->Continue(data,pCon);
break;
default:
assert(0);
}
}
}
if(data == NULL || pCount == NULL){
SCPrintf(pCon,eLogError,"ERROR: slave counter %s NOT found or unusable", name);
}
}
}
/*---------------------------------------------------------------------------------*/
static void startMultiCounting(pHdb self, SConnection *pCon)
{
pHdb mode = NULL, preset = NULL, master = NULL, slaves = NULL;
pHdb sID, mID;
char *pPtr, name[80];
pICountable pCount = NULL;
void *data;
long slaveID, masterID;
CounterMode eMode;
hdbValue v;
mode = GetHipadabaNode(self,"mode");
preset = GetHipadabaNode(self,"preset");
master = GetHipadabaNode(self,"master");
slaves = GetHipadabaNode(self,"slaves");
sID = GetHipadabaNode(self,"slaveID");
mID = GetHipadabaNode(self,"masterID");
assert(mode != NULL);
assert(preset != NULL);
assert(master != NULL);
assert(slaves != NULL);
assert(sID != NULL);
assert(mID != NULL);
if(strcmp(mode->value.v.text,"timer") == 0) {
eMode = eTimer;
} else {
eMode = ePreset;
}
/*
start slaves
*/
slaveID = GetTaskGroupID(pServ->pTasker);
pPtr = slaves->value.v.text;
while((pPtr = stptok(pPtr,name,sizeof(name),",")) != NULL){
data = FindCommandData(pServ->pSics,name,NULL);
if(data != NULL){
pCount = GetCountableInterface(data);
if(pCount != NULL){
pCount->SetCountParameters(data,preset->value.v.doubleValue,
eMode);
masterID = StartCountTask(data,pCon,name);
if(masterID < 0) {
SCPrintf(pCon,eLogError,"ERROR: failed to start slave %s, aborting", name);
doCountCommand(self,pCon,1001);
return;
} else {
AddTaskToGroup(pServ->pTasker,masterID, slaveID);
}
}
}
if(data == NULL || pCount == NULL){
SCPrintf(pCon,eLogError,"ERROR: slave counter %s NOT found or unusable", name);
}
}
/*
start master
*/
data = FindCommandData(pServ->pSics,master->value.v.text,NULL);
if(data != NULL){
pCount = GetCountableInterface(data);
if(pCount != NULL){
pCount->SetCountParameters(data,preset->value.v.doubleValue,
eMode);
masterID = StartCountTask(data,pCon,master->value.v.text);
}
}
v = MakeHdbInt(masterID);
UpdateHipadabaPar(mID,v,pCon);
v = MakeHdbInt(slaveID);
UpdateHipadabaPar(sID,v,pCon);
}
/*---------------------------------------------------------------------------------*/
static hdbCallbackReturn MultiSecControllCallback(pHdb node,
void *userData,
pHdbMessage message)
{
pHdbDataMessage mm = NULL;
pHdb self = NULL;
int code;
SConnection *pCon = NULL;
mm = GetHdbSetMessage(message);
if(mm == NULL){
return hdbContinue;
}
code = (int)mm->v->v.doubleValue;
pCon = (SConnection *)mm->callData;
self = node->mama;
assert(self != NULL);
switch(code){
case 1000: /* start */
startMultiCounting(self, pCon);
break;
case 1001: /* stop */
doCountCommand(self,pCon,code);
break;
case 1002: /*pause */
doCountCommand(self,pCon,code);
break;
case 1003: /* continue */
doCountCommand(self,pCon,code);
break;
default:
if(pCon != NULL){
SCPrintf(pCon,eLogError,"ERROR: control code %d not recognised", code);
return hdbAbort;
}
}
return hdbContinue;
}
/*-------------------------------------------------------------------------------------*/
static int isMultiMasterRunning(pCounter self, SConnection *pCon, int *status)
{
pHdb mID, master, myStatus, control, ccd, stopTime;
hdbValue v;
long mlID;
void *data;
pICountable pCount;
float controlVal;
mID = GetHipadabaNode(self->objectNode,"masterID");
master = GetHipadabaNode(self->objectNode,"master");
myStatus = GetHipadabaNode(self->objectNode,"status");
control = GetHipadabaNode(self->objectNode,"control");
ccd = GetHipadabaNode(self->objectNode,"ccd");
stopTime = GetHipadabaNode(self->objectNode,"stopTime");
assert(mID != NULL);
assert(master != NULL);
assert(myStatus != NULL);
assert(control != NULL);
assert(ccd != NULL);
assert(stopTime != NULL);
mlID = mID->value.v.intValue;
if(mlID == 0) {
return 0;
}
data = FindCommandData(pServ->pSics,master->value.v.text,NULL);
assert(data != NULL);
pCount = GetCountableInterface(data);
assert(pCount != NULL);
if(isTaskIDRunning(pServ->pTasker,mlID)) {
*status = pCount->CheckCountStatus(data,pCon);
controlVal = GetControlValue((pCounter)data);
UpdateHipadabaPar(control,MakeHdbFloat(controlVal),pCon);
SecCounterSetError(self,"None");
switch(*status){
case HWFault:
UpdateHipadabaPar(myStatus,MakeHdbText("error"),pCon);
UpdateHipadabaPar(stopTime,MakeHdbInt(time(NULL)),pCon);
SecCounterSetError(self,"Master counter errror");
*status = HWBusy;
break;
case HWPause:
UpdateHipadabaPar(myStatus,MakeHdbText("paused"),pCon);
break;
case HWNoBeam:
UpdateHipadabaPar(myStatus,MakeHdbText("nobeam"),pCon);
break;
default:
*status = HWBusy;
UpdateHipadabaPar(myStatus,MakeHdbText("run"),pCon);
break;
}
} else {
/*
we recently stopped. Mark it so and stop slaves.
*/
mID->value.v.intValue = 0;
*status = HWBusy;
UpdateHipadabaPar(myStatus,MakeHdbText("run"),pCon);
UpdateHipadabaPar(stopTime,MakeHdbInt(time(NULL)),pCon);
if(ccd->value.v.intValue != 1) {
doCountCommand(self->objectNode,pCon,1011);
}
}
return 1;
}
/*-------------------------------------------------------------------------------------*/
static int areSlavesRunning(pCounter self, SConnection *pCon, int *status)
{
pHdb slaveID, myStatus, stopTime, ccd;
int i;
slaveID = GetHipadabaNode(self->objectNode,"slaveID");
myStatus = GetHipadabaNode(self->objectNode,"status");
stopTime = GetHipadabaNode(self->objectNode,"stopTime");
ccd = GetHipadabaNode(self->objectNode,"ccd");
assert(slaveID != NULL);
assert(myStatus != NULL);
assert(stopTime != NULL);
assert(ccd != NULL);
if(isTaskGroupRunning(pServ->pTasker,slaveID->value.v.intValue)){
if(ccd->value.v.intValue == 1 && time(NULL) > stopTime->value.v.intValue + 100) {
SCWrite(pCon,"WARNING: CCD overrun, restarting counting...", eLogError);
self->pCountInt->Halt(self);
ReleaseCountLock(self->pCountInt);
for(i = 0; i < 100; i++){
SicsWait(1);
if(!isTaskGroupRunning(pServ->pTasker,slaveID->value.v.intValue)){
self->pCountInt->StartCount(self,pCon);
UpdateHipadabaPar(myStatus,MakeHdbText("run"),pCon);
UpdateHipadabaPar(stopTime,MakeHdbInt(time(NULL)),pCon);
*status = HWBusy;
return 1;
}
}
SCWrite(pCon,"ERROR: failed to stop overrun CCD",eLogError);
*status = HWFault;
return 0;
} else {
*status = HWBusy;
UpdateHipadabaPar(myStatus,MakeHdbText("run"),pCon);
return 1;
}
} else {
*status = HWIdle;
UpdateHipadabaPar(myStatus,MakeHdbText("idle"),pCon);
return 0;
}
return 1;
}
/*------------------------------------------------------------------------------------*/
static void multiEndCounting(pCounter self, SConnection *pCon)
{
InvokeCallBack(self->pCall, COUNTEND, NULL);
ReleaseCountLock(self->pCountInt);
}
/*-------------------------------------------------------------------------------------*/
static int MultiSecStatus(void *pData, SConnection * pCon)
{
int status;
void *data;
pICountable pCount = NULL;
pHdb mID = NULL, sID = NULL, master;
pCounter self = (pCounter)pData;
if(isMultiMasterRunning(self,pCon, &status)){
return status;
}
if(areSlavesRunning(self,pCon, &status)){
return status;
}
multiEndCounting(self,pCon);
return HWIdle;
}
/*--------------------------------------------------------------------------*/
static int MultiSecTransfer(void *pData, SConnection * pCon)
{
int i, retVal = OKOK, tclStatus;
char pBueffel[132];
pCounter pCount = NULL;
pHdb transfer;
pCount = (pCounter) pData;
transfer = GetHipadabaNode(pCount->objectNode,"transfer");
if(transfer != NULL){
MacroPush(pCon);
tclStatus = Tcl_Eval(InterpGetTcl(pServ->pSics), transfer->value.v.text);
if (tclStatus != TCL_OK) {
snprintf(pBueffel, 131, "ERROR: TransferScript returned: %s",
Tcl_GetStringResult(InterpGetTcl(pServ->pSics)));
SCWrite(pCon, pBueffel, eError);
MacroPop();
return HWFault;
}
MacroPop();
}
return retVal;
}
/*---------------------------------------------------------------------------
Forward unknown commands to the master counter
-----------------------------------------------------------------------------*/
static int MultiInvokeSICSOBJ(SConnection * pCon, SicsInterp * pSics, void *pData,
int argc, char *argv[])
{
int status;
char buffer[132];
pHdb master = NULL;
pCounter self = (pCounter)pData;
void *data = NULL;
CommandList *pCom;
status = InvokeSICSOBJ(pCon, pSics, pData, argc, argv);
if (status == -1) {
master = GetHipadabaNode(self->objectNode,"master");
assert(master != NULL);
pCom = FindCommand(pSics,master->value.v.text);
if(pCom != NULL){
status = pCom->OFunc(pCon,pSics,pCom->pData,argc,argv);
}
status = 0;
}
return status;
}
/*-------------------------------------------------------------------------------------*/
int MakeMultiSec(SConnection * pCon, SicsInterp * pSics, void *pData,
int argc, char *argv[])
{
pCounter pRes = NULL;
int status, length;
pHdb node, child;
if(argc < 3) {
SCWrite(pCon,"ERROR: need at least a name and length to create a counter",
eError);
return 0;
}
length = atoi(argv[2]);
pRes = CreateSecCounter(pCon,"SingleCounter", argv[1], length);
if(pRes == NULL){
return 0;
}
pRes->pCountInt->CheckCountStatus = MultiSecStatus;
pRes->pCountInt->TransferData = MultiSecTransfer;
node = pRes->objectNode;
child = GetHipadabaNode(node,"control");
AppendHipadabaCallback(child,MakeHipadabaCallback(MultiSecControllCallback,NULL,NULL));
child = MakeSICSHdbPar("master", usMugger, MakeHdbText(""));
if (child == NULL) {
SCWrite(pCon,"ERROR: out of memory in MakeMultiCounterSec",eError);
return 0;
} else {
SetHdbProperty(child, "__save", "true");
AddHipadabaChild(node, child, NULL);
}
child = MakeSICSHdbPar("transfer", usMugger, MakeHdbText(""));
if (child == NULL) {
SCWrite(pCon,"ERROR: out of memory in MakeMultiCounterSec",eError);
return 0;
} else {
SetHdbProperty(child, "__save", "true");
AddHipadabaChild(node, child, NULL);
}
child = MakeSICSHdbPar("error", usMugger, MakeHdbText("None"));
if (child == NULL) {
SCWrite(pCon,"ERROR: out of memory in MakeMultiCounterSec",eError);
return 0;
} else {
AddHipadabaChild(node, child, NULL);
}
child = MakeSICSHdbPar("slaves", usMugger, MakeHdbText(""));
if (child == NULL) {
SCWrite(pCon,"ERROR: out of memory in MakeMultiCounterSec",eError);
return 0;
} else {
SetHdbProperty(child, "__save", "true");
AddHipadabaChild(node, child, NULL);
}
child = MakeSICSHdbPar("ccd", usMugger, MakeHdbInt(0));
if (child == NULL) {
SCWrite(pCon,"ERROR: out of memory in MakeMultiCounterSec",eError);
return 0;
} else {
SetHdbProperty(child, "__save", "true");
AddHipadabaChild(node, child, NULL);
}
child = MakeSICSHdbPar("stopTime", usInternal, MakeHdbInt(0));
if (child == NULL) {
SCWrite(pCon,"ERROR: out of memory in MakeMultiCounterSec",eError);
return 0;
} else {
AddHipadabaChild(node, child, NULL);
}
child = MakeSICSHdbPar("masterID", usInternal, MakeHdbInt(0));
if (child == NULL) {
SCWrite(pCon,"ERROR: out of memory in MakeMultiCounterSec",eError);
return 0;
} else {
AddHipadabaChild(node, child, NULL);
}
child = MakeSICSHdbPar("slaveID", usInternal, MakeHdbInt(0));
if (child == NULL) {
SCWrite(pCon,"ERROR: out of memory in MakeMultiCounterSec",eError);
return 0;
} else {
AddHipadabaChild(node, child, NULL);
}
status =
AddCommand(pSics, argv[1], MultiInvokeSICSOBJ, DeleteCounter,
(void *) pRes);
if (status != 1) {
SCPrintf(pCon,eError, "ERROR: duplicate command %s not created", argv[1]);
return 0;
}
return 1;
}

1
ofac.c
View File

@ -145,6 +145,7 @@ static void InitIniCommands(SicsInterp * pInter)
SCMD("MakeMcStasReader", McStasReaderFactory); SCMD("MakeMcStasReader", McStasReaderFactory);
SCMD("MakeMono", MonoInit); SCMD("MakeMono", MonoInit);
SCMD("MakeMultiCounter", MakeMultiCounter); SCMD("MakeMultiCounter", MakeMultiCounter);
SCMD("MakeMultiSec", MakeMultiSec);
SCMD("MakeNXScript", MakeNXScript); SCMD("MakeNXScript", MakeNXScript);
SCMD("MakeO2T", CreateO2T); SCMD("MakeO2T", CreateO2T);
SCMD("MakeOscillator", MakeOscillator); SCMD("MakeOscillator", MakeOscillator);

View File

@ -4,6 +4,10 @@
copyright: see file COPYRIGHT copyright: see file COPYRIGHT
Mark Koennecke, November 2004 Mark Koennecke, November 2004
Fixed to work with second generation motors too
Mark Koennecke, September 2013
------------------------------------------------------------------------*/ ------------------------------------------------------------------------*/
#include <stdio.h> #include <stdio.h>
#include <assert.h> #include <assert.h>
@ -21,7 +25,7 @@ static void StopOscillation(pOscillator self)
{ {
assert(self != NULL); assert(self != NULL);
if (self->taskID > 0) { if (self->taskID > 0) {
self->pMot->pDriver->Halt(self->pMot->pDriver); self->pMot->pDrivInt->Halt(self->pMot);
self->stopFlag = 1; self->stopFlag = 1;
self->taskID = -1; self->taskID = -1;
} }
@ -71,27 +75,20 @@ static int OscillationTask(void *data)
return 0; return 0;
} }
status = self->pMot->pDriver->GetStatus(self->pMot->pDriver); status = self->pMot->pDrivInt->CheckStatus(self->pMot,pServ->dummyCon);
switch (status) { switch (status) {
case HWFault: case HWFault:
case HWPosFault: case HWPosFault:
self->pMot->pDriver->GetError(self->pMot->pDriver, &code, error, 255); WriteToCommandLog("oscillator>> ",
WriteToCommandLog("oscillator>> ", error); "ERROR occurred in oscialltion, try running motor manually to find out more");
pos = getCurrentTarget(self); WriteToCommandLog("oscillator>> ",
errStatus = "Trying to run other direction");
self->pMot->pDriver->TryAndFixIt(self->pMot->pDriver, code, pos); pos = getNextPos(self);
self->errorCount++; status = MotorRun(self->pMot, self->pCon, pos);
if (errStatus == MOTFAIL) { if (self->debug > 0) {
/* snprintf(message, 131, "Started oscillation to %f, ret code = %d",
try driving the other way on a serious error pos, status);
*/ WriteToCommandLog("oscillator>>", message);
pos = getNextPos(self);
status = MotorRun(self->pMot, self->pCon, pos);
if (self->debug > 0) {
snprintf(message, 131, "Started oscillation to %f, ret code = %d",
pos, status);
WriteToCommandLog("oscillator>>", message);
}
} }
break; break;
case HWWarn: case HWWarn:

View File

@ -243,12 +243,12 @@ pHdbCallback MakeReadOnlyCallback()
return MakeHipadabaCallback(SICSReadOnlyCallback, NULL, NULL); return MakeHipadabaCallback(SICSReadOnlyCallback, NULL, NULL);
} }
/*------------------------------------------------------------------------------------*/ /*------------------------------------------------------------------------------------*/
static hdbCallbackReturn SICSValueCheckCallback(pHdb node, void *userData, hdbCallbackReturn SICSValueCheckCallback(pHdb node, void *userData,
pHdbMessage message) pHdbMessage message)
{ {
SConnection *pCon = NULL; SConnection *pCon = NULL;
pHdbDataMessage mm = NULL; pHdbDataMessage mm = NULL;
char values[1024], *pPtr, pToken[80]; char values[1024], *pPtr, pToken[80], *pVal;
int status; int status;
hdbValue v; hdbValue v;
@ -273,11 +273,15 @@ static hdbCallbackReturn SICSValueCheckCallback(pHdb node, void *userData,
} }
pPtr = values; pPtr = values;
pVal = strdup(v.v.text);
strtolower(pVal);
while((pPtr = stptok(pPtr,pToken,sizeof(pToken),",")) != NULL){ while((pPtr = stptok(pPtr,pToken,sizeof(pToken),",")) != NULL){
if(strcmp(pToken,v.v.text) == 0) { if(strcmp(pToken,pVal) == 0) {
free(pVal);
return hdbContinue; return hdbContinue;
} }
} }
free(pVal);
if(pCon != NULL){ if(pCon != NULL){
SCPrintf(pCon,eLogError,"ERROR: %s not allowed as value for %s, allowed are: %s", SCPrintf(pCon,eLogError,"ERROR: %s not allowed as value for %s, allowed are: %s",
@ -3958,7 +3962,7 @@ int InstallSICSHipadaba(SConnection * pCon, SicsInterp * pSics,
AddCommand(pSics, "hnotify", AutoNotifyHdbNode, NULL, NULL); AddCommand(pSics, "hnotify", AutoNotifyHdbNode, NULL, NULL);
AddCommand(pSics, "hdelcb", RemoveHdbCallback, NULL, NULL); AddCommand(pSics, "hdelcb", RemoveHdbCallback, NULL, NULL);
AddCommand(pSics, "hinfo", HdbNodeInfo, NULL, NULL); AddCommand(pSics, "hinfo", HdbNodeInfo, NULL, NULL);
AddCommand(pSics, "hval", HdbNodeVal, NULL, NULL); /* AddCommand(pSics, "hval", HdbNodeVal, NULL, NULL);*/
AddCommand(pSics, "hchain", ChainHdbNode, NULL, NULL); AddCommand(pSics, "hchain", ChainHdbNode, NULL, NULL);
AddCommand(pSics, "harray", HdbArrayNode, NULL, NULL); AddCommand(pSics, "harray", HdbArrayNode, NULL, NULL);
AddCommand(pSics, "hsetprop", SetSICSHdbProperty, NULL, NULL); AddCommand(pSics, "hsetprop", SetSICSHdbProperty, NULL, NULL);

View File

@ -149,6 +149,14 @@ pHdbCallback MakeTreeChangeCallback(SConnection * pCon, int id);
* make a clalback to invoke a function node * make a clalback to invoke a function node
*/ */
pHdbCallback MakeSICSFuncCallback(void *obj); pHdbCallback MakeSICSFuncCallback(void *obj);
/**
* callback for checking node values against the values property
* @param node The node to for which this callback has been called
* @param userData userData associated with this callback. NULL expected
* @param message The message sent to the node
*/
hdbCallbackReturn SICSValueCheckCallback(pHdb node, void *userData,
pHdbMessage message);
/*======================== parameter creation ===================================*/ /*======================== parameter creation ===================================*/
/** /**

View File

@ -272,7 +272,6 @@ static float getMotorValue(pMotor mot, SConnection * pCon)
} }
/*--------------------- In devexec.c --------------------------------------*/ /*--------------------- In devexec.c --------------------------------------*/
void InvokeNewTarget(pExeList self, char *name, float target); void InvokeNewTarget(pExeList self, char *name, float target);
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
static int startTASMotor(pMotor mot, SConnection * pCon, char *name, static int startTASMotor(pMotor mot, SConnection * pCon, char *name,
double target, int silent, int stopFixed) double target, int silent, int stopFixed)
@ -312,7 +311,31 @@ static int startTASMotor(pMotor mot, SConnection * pCon, char *name,
} }
return status; return status;
} }
/*-------------------------------------------------------------------------*/
static int StartTASA3(pMotor mot, SConnection *pCon, char *name,
double target, int silent, int stopFixed)
{
float val;
int status;
char buffer[80];
val = getMotorValue(mot,pCon);
if(ABS(target-val) > 190) {
SCPrintf(pCon,eLog,"WARNING: driving a3 more then 190 degree: %f, please confirm with y",
ABS(target-val));
status = SCPromptTMO(pCon,NULL,buffer,sizeof(buffer),120);
if(status == 1){
if(buffer[0] == 'y'){
return startTASMotor(mot,pCon,name,target,silent,stopFixed);
}
}
SCWrite(pCon,"ERROR: no or wrong reply, aborting scan",eLogError);
SCSetInterrupt(pCon,eAbortScan);
return HWFault;
} else {
return startTASMotor(mot,pCon,name,target,silent,stopFixed);
}
}
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static int startMotors(ptasMot self, tasAngles angles, static int startMotors(ptasMot self, tasAngles angles,
SConnection * pCon, int driveQ, int driveTilt) SConnection * pCon, int driveQ, int driveTilt)
@ -326,38 +349,6 @@ static int startMotors(ptasMot self, tasAngles angles,
/* /*
monochromator monochromator
*/ */
/* status = startTASMotor(self->math->motors[A1], pCon, "a1", */
/* angles.monochromator_two_theta / 2., silent, stopFixed); */
/* if (status != OKOK) { */
/* return status; */
/* } */
/* status = startTASMotor(self->math->motors[A2], pCon, "a2", */
/* angles.monochromator_two_theta, silent,stopFixed); */
/* if (status != OKOK) { */
/* return status; */
/* } */
/* if (self->math->motors[MCV] != NULL) { */
/* curve = maCalcVerticalCurvature(self->math->machine.monochromator, */
/* angles.monochromator_two_theta); */
/* status = startTASMotor(self->math->motors[MCV], pCon, "mcv", */
/* curve, silent,stopFixed); */
/* if (status != OKOK) { */
/* SCWrite(pCon,"WARNING: monochromator vertical curvature motor failed to start", eLog); */
/* SCSetInterrupt(pCon,eContinue); */
/* } */
/* } */
/* if (self->math->motors[MCH] != NULL) { */
/* curve = maCalcHorizontalCurvature(self->math->machine.monochromator, */
/* angles.monochromator_two_theta); */
/* status = startTASMotor(self->math->motors[MCH], pCon, "mch", */
/* curve, silent,stopFixed); */
/* if (status != OKOK) { */
/* SCWrite(pCon,"WARNING: monochromator horizontal curvature motor failed to start", eLog); */
/* SCSetInterrupt(pCon,eContinue); */
/* } */
/* } */
status = self->math->mono->SetValue(self->math->monoData, status = self->math->mono->SetValue(self->math->monoData,
pCon,angles.monochromator_two_theta); pCon,angles.monochromator_two_theta);
if(status != OKOK){ if(status != OKOK){
@ -408,7 +399,7 @@ static int startMotors(ptasMot self, tasAngles angles,
/* /*
crystal crystal
*/ */
status = startTASMotor(self->math->motors[A3], pCon, "a3", status = StartTASA3(self->math->motors[A3], pCon, "a3",
angles.a3, silent,stopFixed); angles.a3, silent,stopFixed);
if (status != OKOK) { if (status != OKOK) {
return status; return status;

View File

@ -577,7 +577,7 @@ amorhmsct poll /sics/amorhm/collapse 20
#source ../sim/mars/julcho.tcl #source ../sim/mars/julcho.tcl
MakeSinqRedirect lnsl15 10500 #MakeSinqRedirect lnsl15 10500
MakeSingleX MakeSingleX
singlex configure stt a4 singlex configure stt a4
@ -847,4 +847,12 @@ if {$zwickroll == 1} {
# makesctcontroller zwro std pc8977:50370 \r\n 5 \r\n # makesctcontroller zwro std pc8977:50370 \r\n 5 \r\n
makesctcontroller zwro std localhost:8080 \r\n 5 \n makesctcontroller zwro std localhost:8080 \r\n 5 \n
zwickroll::makezwickroll zwro zwickroll::makezwickroll zwro
} }
set sputter 1
if {$sputter == 1} {
source ../sim/sicscommon/stddrive.tcl
source ../sim/amor_sics/sputter.tcl
SputterInit
}

View File

@ -103,13 +103,18 @@ static void findResponse(Ascon *a)
dict = (pStringDict)a->private; dict = (pStringDict)a->private;
status = StringDictGet(dict,GetCharArray(a->wrBuffer),response, sizeof(response)); status = StringDictGet(dict,GetCharArray(a->wrBuffer),response, sizeof(response));
if(status != 1){ if(status != 1){
if(StringDictGet(dict,"echofail",response,sizeof(response)) == 1) {
DynStringConcat(a->rdBuffer,GetCharArray(a->wrBuffer));
return;
} else {
a->state = AsconFailed; a->state = AsconFailed;
DynStringConcat(a->errmsg,"ERROR: no response found in dictionary for "); DynStringConcat(a->errmsg,"ERROR: no response found in dictionary for ");
DynStringConcat(a->errmsg,GetCharArray(a->wrBuffer)); DynStringConcat(a->errmsg,GetCharArray(a->wrBuffer));
return; return;
}
} }
/** /**
Tclescape is an escape string/character which idetifies a response as a tcl invocation. Tclescape is an escape string/character which identifies a response as a tcl invocation.
Thus the algorithm runs: Thus the algorithm runs:
* Find out if there is a Tcl escape * Find out if there is a Tcl escape
* If so: * If so:

126
trace.c
View File

@ -17,23 +17,30 @@
* *
* Created on: Apr 27, 2011 * Created on: Apr 27, 2011
* Author: koennecke * Author: koennecke
*
* Enhanced to write time stamps any ten minutes.
*
* Mark Koennecke, October 2013
*/ */
#include <time.h>
#include <math.h>
#include <trace.h> #include <trace.h>
#include <stdio.h> #include <stdio.h>
#include <sics.h> #include <sics.h>
#include <sicshipadaba.h> #include <sicshipadaba.h>
#include <sicsobj.h> #include <sicsobj.h>
static FILE *log = NULL; static FILE *logFD = NULL;
static char *logfile = NULL; static char *logfile = NULL;
static int hdbInit = 0; static int hdbInit = 0;
static int filterProv = 0; static int filterProv = 0;
static int debug = 0; static int debug = 0;
static int lastTen = -10;
/*----------------------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------------------*/
int traceActive() int traceActive()
{ {
if (log == NULL){ if (logFD == NULL){
return 0; return 0;
} else { } else {
return 1; return 1;
@ -201,14 +208,14 @@ void traceprint(char *sub, char *id, char *data)
{ {
char *mysub, *myid, *mydata; char *mysub, *myid, *mydata;
if(log != NULL && filter(sub,id)){ if(logFD != NULL && filter(sub,id)){
mysub = strdup(sub); mysub = strdup(sub);
myid = strdup(id); myid = strdup(id);
mydata = strdup(data); mydata = strdup(data);
strrepc(mydata,'\n',':'); strrepc(mydata,'\n',':');
strrepc(mysub,':','@'); strrepc(mysub,':','@');
strrepc(myid,':','@'); strrepc(myid,':','@');
fprintf(log,"%s:%s:%lf:%s\n",mysub,myid,DoubleTime(),mydata); fprintf(logFD,"%s:%s:%lf:%s\n",mysub,myid,DoubleTime(),mydata);
free(mysub); free(mysub);
free(myid); free(myid);
free(mydata); free(mydata);
@ -221,7 +228,7 @@ void traceIO(char *id, char *format, ...)
char buffer[1024], *buf = NULL; char buffer[1024], *buf = NULL;
int len; int len;
if(log != NULL && filter("io","id")){ if(logFD != NULL && filter("io","id")){
va_start(argptr,format); va_start(argptr,format);
len = vsnprintf(buffer, sizeof(buffer),format,argptr); len = vsnprintf(buffer, sizeof(buffer),format,argptr);
va_end(argptr); va_end(argptr);
@ -247,7 +254,7 @@ void traceDevice(char *id, char *format, ...)
char buffer[1024], *buf = NULL; char buffer[1024], *buf = NULL;
int len; int len;
if(log != NULL && filter("dev","id")){ if(logFD != NULL && filter("dev","id")){
va_start(argptr,format); va_start(argptr,format);
len = vsnprintf(buffer, sizeof(buffer),format,argptr); len = vsnprintf(buffer, sizeof(buffer),format,argptr);
va_end(argptr); va_end(argptr);
@ -272,7 +279,7 @@ void traceCommand(char *id, char *format, ...)
char buffer[1024], *buf = NULL; char buffer[1024], *buf = NULL;
int len; int len;
if(log != NULL && filter("com","id")){ if(logFD != NULL && filter("com","id")){
va_start(argptr,format); va_start(argptr,format);
len = vsnprintf(buffer, sizeof(buffer),format,argptr); len = vsnprintf(buffer, sizeof(buffer),format,argptr);
va_end(argptr); va_end(argptr);
@ -297,7 +304,7 @@ void tracePar(char *id, char *format, ...)
char buffer[1024], *buf = NULL; char buffer[1024], *buf = NULL;
int len; int len;
if(log != NULL && filter("par","id")){ if(logFD != NULL && filter("par","id")){
va_start(argptr,format); va_start(argptr,format);
len = vsnprintf(buffer, sizeof(buffer),format,argptr); len = vsnprintf(buffer, sizeof(buffer),format,argptr);
va_end(argptr); va_end(argptr);
@ -322,7 +329,7 @@ void traceSys(char *id, char *format, ...)
char buffer[1024], *buf = NULL; char buffer[1024], *buf = NULL;
int len; int len;
if(log != NULL && filter("sys","id")){ if(logFD != NULL && filter("sys","id")){
va_start(argptr,format); va_start(argptr,format);
len = vsnprintf(buffer, sizeof(buffer),format,argptr); len = vsnprintf(buffer, sizeof(buffer),format,argptr);
va_end(argptr); va_end(argptr);
@ -347,7 +354,7 @@ void traceDebug(char *id, char *format, ...)
char buffer[1024], *buf = NULL; char buffer[1024], *buf = NULL;
int len; int len;
if(log != NULL && debug == 1){ if(logFD != NULL && debug == 1){
va_start(argptr,format); va_start(argptr,format);
len = vsnprintf(buffer, sizeof(buffer),format,argptr); len = vsnprintf(buffer, sizeof(buffer),format,argptr);
va_end(argptr); va_end(argptr);
@ -374,7 +381,7 @@ static void saveInitialParameters()
float value; float value;
pDummy pDum = NULL; pDummy pDum = NULL;
if(log == NULL){ if(logFD == NULL){
return; return;
} }
@ -387,58 +394,83 @@ static void saveInitialParameters()
snprintf(prefix,sizeof(prefix),"par:start:%s", pCom->pName); snprintf(prefix,sizeof(prefix),"par:start:%s", pCom->pName);
pDum = (pDummy)pCom->pData; pDum = (pDummy)pCom->pData;
if(pDum != NULL){ if(pDum != NULL){
pDum->pDescriptor->SaveStatus(pCom->pData,prefix, log); pDum->pDescriptor->SaveStatus(pCom->pData,prefix, logFD);
pDriv = pDum->pDescriptor->GetInterface(pCom->pData, DRIVEID); pDriv = pDum->pDescriptor->GetInterface(pCom->pData, DRIVEID);
if(pDriv != NULL){ if(pDriv != NULL){
value = pDriv->GetValue(pCom->pData,pServ->dummyCon); value = pDriv->GetValue(pCom->pData,pServ->dummyCon);
fprintf(log,"%s:%f\n", prefix,value); fprintf(logFD,"%s:%f\n", prefix,value);
} }
} }
pCom = pCom->pNext; pCom = pCom->pNext;
} }
fprintf(log,"par:start:EOF\n"); fprintf(logFD,"par:start:EOF\n");
}
/*----------------------------------------------------------------*/
static int TraceLogTask(void *data)
{
time_t iDate;
struct tm *psTime;
char pBuffer[132];
int tenmin;
if(logFD == NULL){
return 0;
}
iDate = time(NULL);
psTime = localtime(&iDate);
tenmin = (int)floor(1.0*psTime->tm_min/10.);
if(tenmin != lastTen){
memset(pBuffer, 0, sizeof(pBuffer));
strftime(pBuffer, sizeof(pBuffer)-1, "%Y-%m-%d@%H-%M-%S", psTime);
lastTen = tenmin;
traceSys("TIMESTAMP",pBuffer);
}
return 1;
} }
/*----------------------------------------------------------------*/ /*----------------------------------------------------------------*/
static int TraceLog(pSICSOBJ ccmd, SConnection * con, static int TraceLog(pSICSOBJ ccmd, SConnection * con,
Hdb * cmdNode, Hdb * par[], int nPar) Hdb * cmdNode, Hdb * par[], int nPar)
{ {
char *filename = NULL; char *filename = NULL;
if(nPar < 1) { if(nPar < 1) {
if(log != NULL){ if(logFD != NULL){
SCPrintf(con,eValue,"Tracing to %s", logfile); SCPrintf(con,eValue,"Tracing to %s", logfile);
} else { } else {
SCWrite(con,"Tracing is off", eValue); SCWrite(con,"Tracing is off", eValue);
} }
return 1; return 1;
} }
filename = par[0]->value.v.text; filename = par[0]->value.v.text;
if(strcmp(filename,"close") == 0 ){ if(strcmp(filename,"close") == 0 ){
if(log != NULL){ if(logFD != NULL){
fclose(log); fclose(logFD);
log = NULL; logFD = NULL;
SCPrintf(con,eValue,"Tracing to %s closed", logfile); SCPrintf(con,eValue,"Tracing to %s closed", logfile);
free(logfile); free(logfile);
} }
} else { } else {
if(log != NULL){ if(logFD != NULL){
fclose(log); fclose(logFD);
free(logfile); free(logfile);
} }
log = fopen(filename,"w"); logFD = fopen(filename,"w");
if(log == NULL){ if(logFD == NULL){
SCPrintf(con,eError,"ERROR: failed to open %s for logging", filename); SCPrintf(con,eError,"ERROR: failed to open %s for logging", filename);
return 0; return 0;
} else { } else {
logfile = strdup(filename); logfile = strdup(filename);
saveInitialParameters(); saveInitialParameters();
SCPrintf(con,eValue,"Logging to %s", filename); SCPrintf(con,eValue,"Logging to %s", filename);
if(hdbInit == 0){ if(hdbInit == 0){
TraceObjects(); TraceObjects();
hdbInit = 1; hdbInit = 1;
} }
} TaskRegisterN(pServ->pTasker,"tracestamper",
TraceLogTask, NULL, NULL, NULL, 1);
}
} }
return 1; return 1;
} }
@ -465,10 +497,10 @@ static int TraceFilter(pSICSOBJ ccmd, SConnection * con,
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
static void KillTrace(void *data) static void KillTrace(void *data)
{ {
if(log != NULL){ if(logFD != NULL){
fclose(log); fclose(logFD);
free(logfile); free(logfile);
log = NULL; logFD = NULL;
logfile = NULL; logfile = NULL;
} }
} }