- Added Sycamore protocol and command context to SICS

- Added sinfo to SICS
- Added driver for TCP/IP Astrium velocity selector
- Added driver for TCP/IP Astrium chopper controller


SKIPPED:
	psi/amor2t.c
	psi/amorstat.c
	psi/dornier2.c
	psi/ecb.c
	psi/el734hp.c
	psi/fowrite.c
	psi/libpsi.a
	psi/make_gen
	psi/nextrics.c
	psi/pardef.c
	psi/pimotor.c
	psi/pipiezo.c
	psi/polterwrite.c
	psi/psi.c
	psi/scontroller.c
	psi/serial.c
	psi/tasinit.c
	psi/tasscan.c
	psi/tcpdocho.c
	psi/tcpdornier.c
	psi/tricssupport.c
	psi/velodornier.c
This commit is contained in:
koennecke
2005-12-22 22:16:10 +00:00
parent 603a4fc14b
commit b3138f1197
67 changed files with 4650 additions and 682 deletions

305
SCinter.c
View File

@ -2,8 +2,6 @@
Implementation file for the SICS-interpreter. Implementation file for the SICS-interpreter.
Mark Koennecke, November 1996 Mark Koennecke, November 1996
Made ListObjects more intelligent: list objects according to interface etc. Made ListObjects more intelligent: list objects according to interface etc.
@ -42,6 +40,16 @@
M. Zolliker, Sept 2000, introduced formal aliases, modifications marked M.Z M. Zolliker, Sept 2000, introduced formal aliases, modifications marked M.Z
Mark Koennecke, August 2001, modified SicsWriteStatus to write motor Mark Koennecke, August 2001, modified SicsWriteStatus to write motor
positions on demand. positions on demand.
Made ListObjects moe intelligent: list objects according to interface etc.
Mark Koennecke, December 2003
Extended 'dir' command (function ListObjects) to list via typename from
object descriptor. For completeness, added function PrintAllTypes.
Paul Hathaway, May 2004
Modified printXXX functions to fix duplicate write of last buffer line.
Paul Hathaway, May 2004
---------------------------------------------------------------------------*/ ---------------------------------------------------------------------------*/
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -61,6 +69,15 @@
/* M.Z. */ /* M.Z. */
#include "definealias.h" #include "definealias.h"
/* pvh */
#include "lld_str.h"
static void printList(SConnection *pCon, int listID);
static void freeList(int listID);
int compareStringNode(void *pStr1, void **ppStr2);
#define MAXLEN 256
#define MAXPAR 100
#define MAXBUF 128
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
SicsInterp *InitInterp(void) SicsInterp *InitInterp(void)
@ -219,22 +236,11 @@
return 1; return 1;
} }
#define MAXLEN 256
/*------------------------------------------------------------------------*/ #define MAXCOM 50
void RemoveStartupCommands(void) extern char *stptok(char *s, char *tok, unsigned int toklen, char *brk);
{ extern char *SkipSpace(char *pPtr);
CommandList *pCurrent, *pNext; /*-----------------------------------------------------------------------*/
pCurrent = pServ->pSics->pCList;
while(pCurrent)
{
pNext = pCurrent->pNext;
if (pCurrent->startupOnly) {
RemoveCommand(pServ->pSics, pCurrent->pName);
}
pCurrent = pNext;
}
}
/*------------------------------------------------------------------------*/
int InterpExecute(SicsInterp *self,SConnection *pCon, char *pText) int InterpExecute(SicsInterp *self,SConnection *pCon, char *pText)
{ {
int iCount = 0; int iCount = 0;
@ -275,6 +281,7 @@
iRet = 1; iRet = 1;
goto deleteArgv; goto deleteArgv;
} }
if(argv[0] == NULL) if(argv[0] == NULL)
{ {
SCWrite(pCon,"ERROR: failed to parse command",eError); SCWrite(pCon,"ERROR: failed to parse command",eError);
@ -298,7 +305,13 @@
self->eOut = eStatus; self->eOut = eStatus;
Tcl_ResetResult((Tcl_Interp *)self->pTcl); Tcl_ResetResult((Tcl_Interp *)self->pTcl);
MacroPush(pCon); MacroPush(pCon);
SCWrite(pCon, "", eStart);
pCon->conStatus = 0;
iRet = pCommand->OFunc(pCon, self, pCommand->pData, argc, argv); iRet = pCommand->OFunc(pCon, self, pCommand->pData, argc, argv);
/* If a task is registered with the dev exec then conStatus is HWBusy*/
if (pCon->conStatus != HWBusy) {
SCWrite(pCon,"",eFinish);
}
MacroPop(); MacroPop();
deleteArgv: deleteArgv:
@ -519,6 +532,74 @@ static void printAll(SicsInterp *pSics, SConnection *pCon)
SCWrite(pCon,pBueffel,eStatus); SCWrite(pCon,pBueffel,eStatus);
} }
} }
/*------------------------------------------------------------------------
printAllTypes prints the list of types of objects instantiated on the
CommandList.
iFiltered=0 gives all objects including interpreter command objects
iFiltered=1 gives types where object name is not the same as its type
-------------------------------------------------------------------------*/
static void printAllTypes(SicsInterp *pSics, SConnection *pCon, int iFiltered)
{
CommandList *pCurrent = NULL;
char pBueffel[256];
char pName_lc[256];
char pType_lc[256];
char *pType;
Dummy *pTest;
int typeListID;
assert(pSics);
assert(pCon);
pBueffel[0] = '\0';
typeListID = LLDstringCreate();
if(-1==typeListID)
{
strcpy(pBueffel,"ERROR: Cannot generate list of object types\r\n");
SCWrite(pCon,pBueffel,eStatus);
return;
}
pCurrent = pSics->pCList;
while(pCurrent)
{
if(NULL != pCurrent->pData)
{
pTest = (pDummy)pCurrent->pData;
if(NULL != pTest->pDescriptor)
{
pType = pTest->pDescriptor->name;
strcpy(pType_lc,pType);
strtolower(pType_lc);
LLDnodePtr2First(typeListID);
/* int LLDnodeFind( int List, CompFunPtr Compare, void * DataPtr ); */
/* */
/* Find *DataPtr in the List using the *Compare function. */
/* Returns the return value of *Compare. */
/* 0 == equal == found. */
/* non-zero == not found. Current node is set to found node. */
/* Returns 2 for an empty list. */
/* NB: First checked node is current node, then search to end of list*/
if(0!=LLDnodeFind(typeListID,compareStringNode,(void *)pType))
{ /* empty list or 'typename' not found */
strcpy(pName_lc, pCurrent->pName);
strtolower(pName_lc);
if((0==iFiltered)||((1==iFiltered)&&(0!=strcmp(pType_lc,pName_lc))))
{ /*ie Add if unfiltered or pass filter(name!=typename) */
LLDstringAdd(typeListID,pType);
}
}
}
}
pCurrent = pCurrent->pNext;
}
printList(pCon,typeListID);
freeList(typeListID);
}
/*----------------------------------------------------------------------- /*-----------------------------------------------------------------------
printInterface prints only those objects which implement an interface printInterface prints only those objects which implement an interface
as specified bi the id given as specified bi the id given
@ -625,9 +706,9 @@ static void printMatch(SicsInterp *pSics, SConnection *pCon, char *mask)
SCWrite(pCon,pBueffel,eStatus); SCWrite(pCon,pBueffel,eStatus);
} }
/*----------------------------------------------------------------------- /*-----------------------------------------------------------------------
printType prints only those objects which match the type given printType prints only those objects whose descriptor match the type given
-------------------------------------------------------------------------*/ -------------------------------------------------------------------------*/
static void printType(SicsInterp *pSics, SConnection *pCon, char *type) static void printType(SicsInterp *pSics, SConnection *pCon, char *typeName)
{ {
CommandList *pCurrent; CommandList *pCurrent;
Tcl_DString txt; Tcl_DString txt;
@ -644,7 +725,7 @@ static void printType(SicsInterp *pSics, SConnection *pCon, char *type)
{ {
if(pCurrent->pData != NULL) if(pCurrent->pData != NULL)
{ {
if(iHasType(pCurrent->pData,type)) if(iHasType(pCurrent->pData,typeName))
{ {
if(iNum == 0) if(iNum == 0)
{ {
@ -680,6 +761,8 @@ static void printType(SicsInterp *pSics, SConnection *pCon, char *type)
int ListObjects(SConnection *pCon, SicsInterp *pSics, void *pData, int ListObjects(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]) int argc, char *argv[])
{ {
char pType[256];
int i;
if(argc < 2) if(argc < 2)
{ {
@ -701,6 +784,13 @@ static void printType(SicsInterp *pSics, SConnection *pCon, char *type)
printType(pSics,pCon,"Motor"); printType(pSics,pCon,"Motor");
return 1; return 1;
} }
/* Start Mod by Paul Hathaway May 2004 */
if(0 == strcmp(argv[1],"types"))
{
printAllTypes(pSics,pCon,1);
return 1;
}
/* End Mod by Paul Hathaway May 2004*/
/* /*
@ -745,6 +835,33 @@ static void printType(SicsInterp *pSics, SConnection *pCon, char *type)
printMatch(pSics,pCon,argv[2]); printMatch(pSics,pCon,argv[2]);
return 1; return 1;
} }
/* Start Mod by Paul Hathaway May 2004 */
/*
* type-based dir
*/
if(0 == strcmp(argv[1],"type"))
{
if(0==strcmp(argv[2],"*"))
{
printAllTypes(pSics,pCon,0);
return 1;
}
strcpy(pType,argv[2]);
/* Cater for multi-word types eg 'Environment Monitor' */
if(argc > 3)
{
for(i=3;i<argc;i++)
{
strcat(pType," ");
strcat(pType,argv[i]);
}
}
printType(pSics,pCon,pType);
return 1;
}
/* End Mod by Paul Hathaway May 2004*/
return 1; return 1;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
@ -848,3 +965,149 @@ void *FindDrivable(SicsInterp *pSics, char *name){
return NULL; return NULL;
} }
/*------------------------------------------------------------------------*/
/* printList: Print contents of an LLDstring list
* Envisaged to be used by other extensions/refactoring utilising dynamic
* linked list module. May extend toallow different output formats
* (eg multi/single column) via switches
*/
static void printList(SConnection *pCon, int listID)
{
char pBueffel[MAXBUF];
int retCode;
if(0!=LLDnodePtr2First(listID))
{
do
{
retCode = LLDstringData(listID,NULL);
if ((MAXBUF-3) > retCode) {
retCode = LLDstringData(listID,pBueffel);
strcat(pBueffel,"\r\n");
SCWrite(pCon,pBueffel,eStatus);
}
} while(0!=LLDnodePtr2Next(listID));
}
}
/*------------------------------------------------------------------------*/
static void freeList(int listID)
{
do {
LLDstringDelete(listID);
} while(0!=LLDnodePtr2First(listID));
LLDdelete(listID);
}
/*------------------------------------------------------------------------*/
/* compareStringNode wraps strcmp for use in findNode(LLD module) calls */
int compareStringNode(void *pStr1, void **ppStr2)
{
return strcmp((char *)pStr1,(char *)(*ppStr2));
}
/*------------------------------------------------------------------------*/
void RemoveStartupCommands(void)
{
CommandList *pCurrent, *pNext;
pCurrent = pServ->pSics->pCList;
while(pCurrent)
{
pNext = pCurrent->pNext;
if (pCurrent->startupOnly) {
RemoveCommand(pServ->pSics, pCurrent->pName);
}
pCurrent = pNext;
}
}
/*----------------------------------------------------------------------*/
static int handleGet(SConnection *pCon,SicsInterp *pSics, int argc,
char *argv[]){
CommandList *obj = NULL;
pDummy pDum = NULL;
char pBueffel[512];
char *pPtr = NULL;
if(argc < 4){
SCWrite(pCon,"ERROR: Insufficient number of arguments to SicsAtt get",
eError);
return 0;
}
obj = FindCommand(pSics,argv[2]);
if(obj == NULL){
snprintf(pBueffel,511,"ERROR: object %s not found",argv[2]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
pDum = obj->pData;
if(pDum == NULL){
snprintf(pBueffel,511,"%s has no data, is command", argv[2]);
SCWrite(pCon,pBueffel,eValue);
return 1;
}
strtolower(argv[3]);
if(strcmp(argv[3],"type") == 0){
snprintf(pBueffel,511, "%s.type = %s", argv[2], pDum->pDescriptor->name);
SCWrite(pCon,pBueffel,eValue);
return 1;
} else {
pPtr = GetDescriptorKey(pDum->pDescriptor, argv[3]);
if(pPtr == NULL){
snprintf(pBueffel,511,"%s.%s = Undefined", argv[0], argv[3]);
} else {
snprintf(pBueffel,511,"%s.%s = %s", argv[0], argv[3], pPtr);
}
SCWrite(pCon,pBueffel,eValue);
return 1;
}
}
/*----------------------------------------------------------------------*/
static int handleSet(SConnection *pCon,SicsInterp *pSics, int argc,
char *argv[]){
CommandList *obj = NULL;
pDummy pDum = NULL;
char pBueffel[512];
char *pPtr = NULL;
if(argc < 5){
SCWrite(pCon,"ERROR: Insufficient number of arguments to SicsAtt set",
eError);
return 0;
}
obj = FindCommand(pSics,argv[2]);
if(obj == NULL){
snprintf(pBueffel,511,"ERROR: object %s not found",argv[2]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
pDum = obj->pData;
if(pDum == NULL){
snprintf(pBueffel,511,"%s has no data, is command", argv[2]);
SCWrite(pCon,pBueffel,eValue);
return 1;
}
strtolower(argv[3]);
pDum->pDescriptor->pKeys = IFSetOption(pDum->pDescriptor->pKeys, argv[3], argv[4]);
SCSendOK(pCon);
return 1;
}
/*-----------------------------------------------------------------------*/
int SicsAtt(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]){
CommandList *current = NULL;
pDummy pDum = NULL;
if(argc < 2){
SCWrite(pCon,"ERROR: insufficient number of argumens to SicsAtt",eError);
return 0;
}
strtolower(argv[1]);
if(strcmp(argv[1],"get") == 0) {
return handleGet(pCon, pSics, argc, argv);
} else if(strcmp(argv[1],"set") == 0){
return handleSet(pCon,pSics,argc, argv);
}
return 0;
}

View File

@ -87,7 +87,6 @@ typedef struct __SINTER
If the command is found, 1 is returned on success, 0 on failure in If the command is found, 1 is returned on success, 0 on failure in
the command. the command.
----------------------------------------------------------------------------*/ ----------------------------------------------------------------------------*/
CommandList *FindCommand(SicsInterp *pInterp, char *name); CommandList *FindCommand(SicsInterp *pInterp, char *name);
/* /*
Searches the Interpreters pInterp command list for a command Searches the Interpreters pInterp command list for a command

View File

@ -46,6 +46,9 @@ typedef enum {
eInError, eInError,
eStatus, eStatus,
eValue, eValue,
eStart,
eFinish,
eEvent,
eWarning, eWarning,
eError eError
} OutCode; } OutCode;

View File

@ -64,6 +64,7 @@
void *pUserData; void *pUserData;
KillFuncIT pKill; KillFuncIT pKill;
int iEvent; int iEvent;
commandContext comCon;
} CallBackItem, *pCallBackItem; } CallBackItem, *pCallBackItem;
/*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
static int CheckPointer(pICallBack self) static int CheckPointer(pICallBack self)
@ -140,7 +141,7 @@
LLDnodeDataTo(self->iList,&sItem); LLDnodeDataTo(self->iList,&sItem);
if(sItem.iEvent == iEvent) if(sItem.iEvent == iEvent)
{ {
iRet = sItem.pFunc(iEvent, pEventData,sItem.pUserData); iRet = sItem.pFunc(iEvent, pEventData,sItem.pUserData,sItem.comCon);
if(!iRet) if(!iRet)
{ {
iResult = 0; iResult = 0;
@ -153,7 +154,7 @@
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
static long lCount = 1L; static long lCount = 1L;
long RegisterCallback(pICallBack self, int iEvent, long RegisterCallback(pICallBack self, commandContext comCon, int iEvent,
SICSCallBack pFunc, SICSCallBack pFunc,
void *pUserData, KillFunc pKFunc) void *pUserData, KillFunc pKFunc)
{ {
@ -170,6 +171,7 @@
sItem.iEvent = iEvent; sItem.iEvent = iEvent;
sItem.pUserData = pUserData; sItem.pUserData = pUserData;
sItem.pKill = pKFunc; sItem.pKill = pKFunc;
sItem.comCon = comCon;
LLDnodeAppendFrom(self->iList,&sItem); LLDnodeAppendFrom(self->iList,&sItem);
return sItem.iID; return sItem.iID;
@ -244,7 +246,8 @@ static int CallbackWrite(SConnection *pCon,char *message, int outCode)
/*----------------------------------------------------------------------- /*-----------------------------------------------------------------------
the actual callback function invoking the script the actual callback function invoking the script
------------------------------------------------------------------------*/ ------------------------------------------------------------------------*/
static int ScriptCallback(int iEvent, void *pEventData, void *pUserData) static int ScriptCallback(int iEvent, void *pEventData, void *pUserData,
commandContext cc)
{ {
SConnection *pCon = NULL; SConnection *pCon = NULL;
Tcl_Interp *pTcl; Tcl_Interp *pTcl;
@ -332,7 +335,8 @@ int CallbackScript(SConnection *pCon, SicsInterp *pSics, void *pData,
return 0; return 0;
} }
Arg2Text(argc-4,&argv[4],pBuffer,131); Arg2Text(argc-4,&argv[4],pBuffer,131);
lID = RegisterCallback(pCall,iEvent,ScriptCallback, lID = RegisterCallback(pCall,SCGetContext(pCon),
iEvent,ScriptCallback,
strdup(pBuffer),free); strdup(pBuffer),free);
sprintf(pBuffer,"callback = %ld", lID); sprintf(pBuffer,"callback = %ld", lID);
SCWrite(pCon,pBuffer,eValue); SCWrite(pCon,pBuffer,eValue);

16
commandcontext.h Normal file
View File

@ -0,0 +1,16 @@
/*-------------------------------------------------
This file holds the command context structure which
is needed to make the sycamore protocol work.
Mark Koennecke, December 2005
-------------------------------------------------*/
#ifndef SICSCOMCONTEXT
#define SICSCOMCONTEXT
typedef struct{
int transID;
char deviceID[256];
}commandContext, *pCommandContext;
#define SCDEVIDLEN 256
#endif

View File

@ -19,8 +19,12 @@
int ListObjects(SConnection *pCon, SicsInterp *pSics, void *pData, int ListObjects(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]); int argc, char *argv[]);
/* /*
lists all avialable objects. Realised in Scinter.c lists all avialable objects. Realised in Scinter.c
*/ */
int SicsAtt(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]);
/*
handling of SICS object attributes. In SCinter.c
*/
#endif #endif

128
conman.c
View File

@ -88,7 +88,6 @@ extern pServer pServ;
/*------------- a number for generating automatic names --------------------*/ /*------------- a number for generating automatic names --------------------*/
static int iName = 0; static int iName = 0;
static int SCNormalWrite(SConnection *self, char *buffer, int iOut);
static SConnection *freeConnections = NULL; static SConnection *freeConnections = NULL;
static long lastIdent = 0; static long lastIdent = 0;
/*===========================================================================*/ /*===========================================================================*/
@ -183,6 +182,12 @@ extern pServer pServ;
pRes->pFiles[i] = NULL; pRes->pFiles[i] = NULL;
} }
/* initialise context variables */
pRes->iCmdCtr = 0;
pRes->conEventType=-1;
pRes->conStatus=-1;
pRes->contextStack = LLDcreate(sizeof(commandContext));
/* install command */ /* install command */
AddCommand(pSics, ConName(pRes->ident), ConSicsAction, NULL,pRes); AddCommand(pSics, ConName(pRes->ident), ConSicsAction, NULL,pRes);
return pRes; return pRes;
@ -436,8 +441,11 @@ extern pServer pServ;
{ {
DeleteCommandStack(pVictim->pStack); DeleteCommandStack(pVictim->pStack);
} }
pVictim->lMagic=0; /* make a write to a freed connection harmless */ pVictim->lMagic=0; /* make a write to a freed connection harmless */
/* finally free pVictim*/ /* finally free pVictim*/
LLDdelete(pVictim->contextStack);
FreeConnection(pVictim); FreeConnection(pVictim);
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
@ -531,6 +539,15 @@ extern pServer pServ;
} }
return self->write(self,pBuffer,iOut); return self->write(self,pBuffer,iOut);
} }
/*-----------------------------------------------------------------------*/
int SCWriteInContext(SConnection *pCon, char *pBuffer, int out, commandContext cc)
{
int status;
SCPushContext2(pCon,cc);
status = SCWrite(pCon,pBuffer,out);
SCPopContext(pCon);
return status;
}
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
int SCPrintf(SConnection *self, int iOut, char *fmt, ...) int SCPrintf(SConnection *self, int iOut, char *fmt, ...)
{ {
@ -632,7 +649,7 @@ static void writeToLogFiles(SConnection *self, char *buffer)
} }
} }
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
static int SCNormalWrite(SConnection *self, char *buffer, int iOut) int SCNormalWrite(SConnection *self, char *buffer, int iOut)
{ {
int i, iPtr, iRet; int i, iPtr, iRet;
char pBueffel[80]; char pBueffel[80];
@ -686,7 +703,7 @@ static void writeToLogFiles(SConnection *self, char *buffer)
return 1; return 1;
} }
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
static int SCWriteWithOutcode(SConnection *self, char *buffer, int iOut) int SCWriteWithOutcode(SConnection *self, char *buffer, int iOut)
{ {
int i, iPtr, iRet, length; int i, iPtr, iRet, length;
char pBueffel[80]; char pBueffel[80];
@ -1343,7 +1360,14 @@ static void writeToLogFiles(SConnection *self, char *buffer)
self->inUse++; self->inUse++;
self->eInterrupt = eContinue; self->eInterrupt = eContinue;
self->parameterChange = 0; self->parameterChange = 0;
/*
get first word of command
*/
memset(pBueffel,0,80);
stptok(trim(pCommand),pBueffel,79," ");
SCAdvanceContext(self,pBueffel);
iRet = InterpExecute(pInter,self,pCommand); iRet = InterpExecute(pInter,self,pCommand);
SCPopContext(self);
if(self->parameterChange == 1) if(self->parameterChange == 1)
{ {
/* /*
@ -1658,7 +1682,8 @@ static void writeToLogFiles(SConnection *self, char *buffer)
The callback function for connection callbacks. Invokes command The callback function for connection callbacks. Invokes command
given at registration time. given at registration time.
*/ */
static int ConCallBack(int iEvent, void *pEventData, void *pUserData) static int ConCallBack(int iEvent, void *pEventData, void *pUserData,
commandContext cc)
{ {
pCBAction self = NULL; pCBAction self = NULL;
@ -1667,7 +1692,9 @@ static void writeToLogFiles(SConnection *self, char *buffer)
if(self->pAction) if(self->pAction)
{ {
SCPushContext2(self->pCon,cc);
InterpExecute(pServ->pSics,self->pCon,self->pAction); InterpExecute(pServ->pSics,self->pCon,self->pAction);
SCPopContext(self->pCon);
} }
return 1; return 1;
} }
@ -1755,7 +1782,7 @@ static void writeToLogFiles(SConnection *self, char *buffer)
pCB->pSics = pSics; pCB->pSics = pSics;
pCB->pAction = strdup(pBueffel); pCB->pAction = strdup(pBueffel);
sItem.pInterface = pInterface; sItem.pInterface = pInterface;
sItem.lID = RegisterCallback(pInterface, iEvent, ConCallBack, sItem.lID = RegisterCallback(pInterface, SCGetContext(pCB->pCon), iEvent, ConCallBack,
pCB, CBKill); pCB, CBKill);
LLDnodeAppendFrom(self->iList,&sItem); LLDnodeAppendFrom(self->iList,&sItem);
SCSendOK(pCon); SCSendOK(pCon);
@ -1961,6 +1988,48 @@ SConnection *SCLoad(SCStore *con) {
} }
return pCon; return pCon;
} }
/* --------------------------------------------------------------------------*/
long SCTagContext(SConnection *self, char *tagName)
{
commandContext a;
if(NULL==self) return -1;
/*
return SCSetContext(self,self->iCmdID,tagName);
*/
a = SCGetContext(self);
strncpy(a.deviceID,tagName,SCDEVIDLEN);
/*
SCGetContext will already have advanced the stack pointer to the
last position
*/
LLDnodeDataTo(self->contextStack, &a);
}
/* --------------------------------------------------------------------------*/
long SCAdvanceContext(SConnection *self, char *tagName)
{
if(NULL==self) return -1;
self->iCmdCtr++;
if(999999<self->iCmdCtr)
{
self->iCmdCtr = 0;
}
return SCPushContext(self, self->iCmdCtr, tagName);
}
/*------------------------------------------------------------------------*/
int SCVerifyConnection(SConnection *self)
{
return VerifyConnection(self);
}
/*------------------------------------------------------------------------*/
void SCWriteToLogFiles(SConnection *self, char *buffer)
{
writeToLogFiles(self,buffer);
}
/*------------------------------------------------------------------------*/
int SCDoSockWrite(SConnection *self, char *buffer)
{
return doSockWrite(self,buffer);
}
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
void KillFreeConnections(void) { void KillFreeConnections(void) {
SConnection *next; SConnection *next;
@ -1970,3 +2039,52 @@ void KillFreeConnections(void) {
freeConnections = next; freeConnections = next;
} }
} }
/*-------------------------------------------------------------------------*/
int SCPushContext(SConnection *self, int ID, char *deviceID)
{
commandContext neu;
if(!VerifyConnection(self))
{
return 0;
}
neu.transID = ID;
strncpy(neu.deviceID,deviceID,SCDEVIDLEN);
LLDnodeAppendFrom(self->contextStack,&neu);
return 1;
}
/*------------------------------------------------------*/
int SCPushContext2(SConnection *self, commandContext cc)
{
return SCPushContext(self,cc.transID, cc.deviceID);
}
/*------------------------------------------------------*/
commandContext SCGetContext(SConnection *pCon)
{
commandContext neu;
neu.transID = 0;
strcpy(neu.deviceID,"Undefined");
if(!VerifyConnection(pCon))
{
return neu;
}
if(LLDnodePtr2Last(pCon->contextStack) == 1){
LLDnodeDataTo(pCon->contextStack, &neu);
}
return neu;
}
/*-----------------------------------------------------*/
int SCPopContext(SConnection *pCon)
{
if(!VerifyConnection(pCon))
{
return 0;
}
if(LLDnodePtr2Last(pCon->contextStack) != 0)
{
LLDnodeDelete(pCon->contextStack);
}
return 1;
}

View File

@ -23,6 +23,7 @@
#include "SCinter.h" #include "SCinter.h"
#include "network.h" #include "network.h"
#include "obdes.h" #include "obdes.h"
#include "commandcontext.h"
#define MAXLOGFILES 10 #define MAXLOGFILES 10
@ -59,6 +60,16 @@ typedef int (*writeFunc)(struct __SConnection *pCon,
int parameterChange; int parameterChange;
int sicsError; int sicsError;
/*
stuff supporting the sycamore protocol and a
command context
*/
long iCmdCtr;
int conEventType;
int conStatus; /* should use status enum ffr */
int iProtocolID;
int contextStack;
/* a FIFO */ /* a FIFO */
pCosta pStack; pCosta pStack;
@ -103,6 +114,8 @@ typedef int (*writeFunc)(struct __SConnection *pCon,
int SCOnlySockWrite(SConnection *self, char *buffer, int iOut); int SCOnlySockWrite(SConnection *self, char *buffer, int iOut);
int SCFileWrite(SConnection *self, char *buffer, int iOut); int SCFileWrite(SConnection *self, char *buffer, int iOut);
int SCNotWrite(SConnection *self, char *buffer, int iOut); int SCNotWrite(SConnection *self, char *buffer, int iOut);
int SCNormalWrite(SConnection *self, char *buffer, int iOut);
int SCWriteWithOutcode(SConnection *self, char *buffer, int iOut);
/************************* CallBack *********************************** */ /************************* CallBack *********************************** */
int SCRegister(SConnection *pCon, SicsInterp *pSics, int SCRegister(SConnection *pCon, SicsInterp *pSics,
void *pInter, long lID); void *pInter, long lID);
@ -158,4 +171,17 @@ SConnection *SCLoad(SCStore *con);
void KillFreeConnections(void); void KillFreeConnections(void);
/*------------------------------------------------------------------------*/
int SCVerifyConnection(SConnection *self);
void SCWriteToLogFiles(SConnection *self, char *buffer);
int SCDoSockWrite(SConnection *self, char *buffer);
int SCWriteInContext(SConnection *pCon, char *buffer, int code, commandContext cc);
long SCTagContext(SConnection *self, char *tagName);
long SCAdvanceContext(SConnection *self, char *tagName);
int SCPushContext(SConnection *pCon, int ID, char *deviceID);
int SCPushContext2(SConnection *pCon, commandContext cc);
int SCPopContext(SConnection *pCon);
commandContext SCGetContext(SConnection *pCon);
#endif #endif

View File

@ -708,7 +708,8 @@
return 1; return 1;
} }
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
static int CounterInterest(int iEvent, void *pEvent, void *pUser) static int CounterInterest(int iEvent, void *pEvent, void *pUser,
commandContext cc)
{ {
SConnection *pCon = NULL; SConnection *pCon = NULL;
pMonEvent pMon = NULL; pMonEvent pMon = NULL;
@ -731,7 +732,7 @@
*/ */
rights = SCGetRights(pCon); rights = SCGetRights(pCon);
SCSetRights(pCon,usSpy); SCSetRights(pCon,usSpy);
SCWrite(pCon,pBueffel,eWarning); SCWriteInContext(pCon,pBueffel,eWarning,cc);
SCSetRights(pCon,rights); SCSetRights(pCon,rights);
return 1; return 1;
} }
@ -896,7 +897,7 @@
SCWrite(pCon,pBueffel,eValue); SCWrite(pCon,pBueffel,eValue);
return 1; return 1;
case 9: /* interest */ case 9: /* interest */
lID = RegisterCallback(self->pCall, MONITOR, CounterInterest, lID = RegisterCallback(self->pCall, SCGetContext(pCon), MONITOR, CounterInterest,
pCon, NULL); pCon, NULL);
SCRegister(pCon,pSics, self->pCall,lID); SCRegister(pCon,pSics, self->pCall,lID);
SCSendOK(pCon); SCSendOK(pCon);

8
danu.c
View File

@ -95,7 +95,8 @@ static int writeDataNumber(pDataNumber self, int iNum)
return 1; return 1;
} }
/*------------------- The CallBack function for interest ------------------*/ /*------------------- The CallBack function for interest ------------------*/
static int InterestCallback(int iEvent, void *pEvent, void *pUser) static int InterestCallback(int iEvent, void *pEvent, void *pUser,
commandContext cc)
{ {
pDataNumber self = NULL; pDataNumber self = NULL;
SConnection *pCon = NULL; SConnection *pCon = NULL;
@ -120,7 +121,7 @@ static int writeDataNumber(pDataNumber self, int iNum)
if(iNum > 0) if(iNum > 0)
{ {
snprintf(pBueffel,131,"sicsdatanumber = %d", iNum); snprintf(pBueffel,131,"sicsdatanumber = %d", iNum);
SCWrite(pCon,pBueffel,eValue); SCWriteInContext(pCon,pBueffel,eValue,cc);
} }
return 1; return 1;
} }
@ -330,7 +331,8 @@ int NewThousand(pDataNumber self)
} }
if(strcmp(argv[1],"interest") == 0) if(strcmp(argv[1],"interest") == 0)
{ {
lID = RegisterCallback(self->pCall, VALUECHANGE, InterestCallback, lID = RegisterCallback(self->pCall, SCGetContext(pCon),
VALUECHANGE, InterestCallback,
pCon, NULL); pCon, NULL);
SCRegister(pCon,pSics, self->pCall,lID); SCRegister(pCon,pSics, self->pCall,lID);
SCSendOK(pCon); SCSendOK(pCon);

View File

@ -62,6 +62,7 @@
pObjectDescriptor pDescriptor; pObjectDescriptor pDescriptor;
float fVal; float fVal;
char *name; char *name;
commandContext comCon;
} DevEntry, *pDevEntry; } DevEntry, *pDevEntry;
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
static pDevEntry CreateDevEntry(pObjectDescriptor pDes, void *pData, static pDevEntry CreateDevEntry(pObjectDescriptor pDes, void *pData,
@ -80,6 +81,7 @@
pNew->pData = pData; pNew->pData = pData;
pNew->name = strdup(name); pNew->name = strdup(name);
pNew->fVal = fVal; pNew->fVal = fVal;
memset(&pNew->comCon,0,sizeof(commandContext));
return pNew; return pNew;
} }
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
@ -228,6 +230,8 @@
SCWrite(pCon,"ERROR: memory exhausted in Device Executor ",eError); SCWrite(pCon,"ERROR: memory exhausted in Device Executor ",eError);
return 0; return 0;
} }
pNew->comCon = SCGetContext(pCon);
strncpy(pNew->comCon.deviceID,name,SCDEVIDLEN);
/* start it */ /* start it */
pDrivInt = pDes->GetInterface(pData,DRIVEID); pDrivInt = pDes->GetInterface(pData,DRIVEID);
@ -250,7 +254,12 @@
if(iRet == OKOK) if(iRet == OKOK)
{ {
LLDnodeAppendFrom(self->iList,&pNew); LLDnodeAppendFrom(self->iList,&pNew);
ExeInterest(self, pNew, "started"); sprintf(pBueffel,"started");
if(NULL!=pNew->comCon.deviceID)
{
snprintf(pBueffel,130,"started (%s)",pNew->comCon.deviceID);
}
ExeInterest(self, pNew, pBueffel);
self->iRun = 1; self->iRun = 1;
self->iStatus = DEVDONE; self->iStatus = DEVDONE;
/* if no task: start it */ /* if no task: start it */
@ -263,6 +272,7 @@
self, self,
1); 1);
self->iEnd = 0; self->iEnd = 0;
pCon->conStatus = HWBusy;
} }
return 1; return 1;
} }
@ -373,6 +383,9 @@
pIDrivable pDrivInt = NULL; pIDrivable pDrivInt = NULL;
int eCode; int eCode;
int isCounting=0, isDriving=0; int isCounting=0, isDriving=0;
char pBueffel[512];
SConnection *pCon;
pCon = self->pOwner;
assert(self); assert(self);
@ -397,6 +410,11 @@
LLDnodeDataTo(self->iList,&pDev); LLDnodeDataTo(self->iList,&pDev);
if(pDev) if(pDev)
{ {
/*
SCSetContext(self->pOwner,pDev->cmdID,pDev->name);
*/
SCPushContext(self->pOwner, pDev->comCon.transID, pDev->comCon.deviceID);
pDrivInt = pDev->pDescriptor->GetInterface(pDev->pData,DRIVEID); pDrivInt = pDev->pDescriptor->GetInterface(pDev->pData,DRIVEID);
pCountInt = pDev->pDescriptor->GetInterface(pDev->pData,COUNTID); pCountInt = pDev->pDescriptor->GetInterface(pDev->pData,COUNTID);
@ -423,10 +441,12 @@
ExeInterest(self, pDev, "finished"); ExeInterest(self, pDev, "finished");
DeleteDevEntry(pDev); DeleteDevEntry(pDev);
LLDnodeDelete(self->iList); LLDnodeDelete(self->iList);
SCWrite(pCon, "", eFinish);
iRet = LLDnodePtr2Prev(self->iList); iRet = LLDnodePtr2Prev(self->iList);
if(SCGetInterrupt(self->pOwner) != eContinue) if(SCGetInterrupt(self->pOwner) != eContinue)
{ {
self->iStatus = DEVINT; self->iStatus = DEVINT;
SCPopContext(self->pOwner);
return -1; return -1;
} }
self->iStatus = DEVDONE; self->iStatus = DEVDONE;
@ -435,6 +455,7 @@
ExeInterest(self, pDev, "finished with problem"); ExeInterest(self, pDev, "finished with problem");
DeleteDevEntry(pDev); DeleteDevEntry(pDev);
pDev = NULL; pDev = NULL;
SCWrite(pCon, "", eFinish);
LLDnodeDataTo(self->iList,&pDev); LLDnodeDataTo(self->iList,&pDev);
LLDnodeDelete(self->iList); LLDnodeDelete(self->iList);
iRet = LLDnodePtr2Prev(self->iList); iRet = LLDnodePtr2Prev(self->iList);
@ -446,6 +467,7 @@
if(SCGetInterrupt(self->pOwner) != eContinue) if(SCGetInterrupt(self->pOwner) != eContinue)
{ {
self->iStatus = DEVINT; self->iStatus = DEVINT;
SCPopContext(self->pOwner);
return -1; return -1;
} }
break; break;
@ -455,6 +477,7 @@
{ {
SetStatus(eEager); SetStatus(eEager);
self->iStatus = DEVINT; self->iStatus = DEVINT;
SCPopContext(self->pOwner);
return -1; return -1;
} }
break; break;
@ -464,6 +487,7 @@
{ {
ContinueExecution(self); ContinueExecution(self);
self->iStatus = DEVINT; self->iStatus = DEVINT;
SCPopContext(self->pOwner);
return -1; return -1;
} }
break; break;
@ -482,6 +506,7 @@
ExeInterest(self, pDev, "finished with problem"); ExeInterest(self, pDev, "finished with problem");
DeleteDevEntry(pDev); DeleteDevEntry(pDev);
LLDnodeDelete(self->iList); LLDnodeDelete(self->iList);
SCWrite(pCon, "", eFinish);
self->iStatus = DEVERROR; self->iStatus = DEVERROR;
if(pDrivInt) if(pDrivInt)
{ {
@ -490,10 +515,12 @@
if(SCGetInterrupt(self->pOwner) != eContinue) if(SCGetInterrupt(self->pOwner) != eContinue)
{ {
self->iStatus = DEVINT; self->iStatus = DEVINT;
SCPopContext(self->pOwner);
return -1; return -1;
} }
break; break;
} }
SCPopContext(self->pOwner);
} }
iRet = LLDnodePtr2Next(self->iList); iRet = LLDnodePtr2Next(self->iList);
} }
@ -641,7 +668,9 @@
} }
iRet = LLDnodePtr2Next(self->iList); iRet = LLDnodePtr2Next(self->iList);
} }
SCPushContext(self->pOwner,0,"system");
SCWrite(self->pOwner,"ERROR: Full Stop called!!",eError); SCWrite(self->pOwner,"ERROR: Full Stop called!!",eError);
SCPopContext(self->pOwner);
if(SCGetInterrupt(self->pOwner) > eContinue) if(SCGetInterrupt(self->pOwner) > eContinue)
{ {
self->iStatus = DEVINT; self->iStatus = DEVINT;
@ -666,7 +695,7 @@
} }
else if(pCountInt) else if(pCountInt)
{ {
pDrivInt->Halt(pDev->pData); pCountInt->Halt(pDev->pData);
} }
return 1; return 1;
} }
@ -699,6 +728,8 @@
pDev = (pDevEntry)LLDnodePtr(self->iList); pDev = (pDevEntry)LLDnodePtr(self->iList);
if(pDev) if(pDev)
{ {
SCPushContext(self->pOwner, pDev->comCon.transID, pDev->comCon.deviceID);
pCountInt = pDev->pDescriptor->GetInterface(pDev->pData,COUNTID); pCountInt = pDev->pDescriptor->GetInterface(pDev->pData,COUNTID);
if(pCountInt) if(pCountInt)
{ {
@ -710,6 +741,7 @@
} }
} }
SCPopContext(self->pOwner);
iRet = LLDnodePtr2Next(self->iList); iRet = LLDnodePtr2Next(self->iList);
} }
SetStatus(ePaused); SetStatus(ePaused);
@ -735,7 +767,6 @@
{ {
return 1; return 1;
} }
} }
iRet = LLDnodePtr2Next(self->iList); iRet = LLDnodePtr2Next(self->iList);
} }
@ -760,11 +791,13 @@
pCountInt = pDev->pDescriptor->GetInterface(pDev->pData,COUNTID); pCountInt = pDev->pDescriptor->GetInterface(pDev->pData,COUNTID);
if(pCountInt) if(pCountInt)
{ {
SCPushContext(self->pOwner, pDev->comCon.transID, pDev->comCon.deviceID);
iRet = pCountInt->Continue(pDev->pData,self->pOwner); iRet = pCountInt->Continue(pDev->pData,self->pOwner);
if(!iRet) if(!iRet)
{ {
iRes = 0; iRes = 0;
} }
SCPopContext(self->pOwner);
} }
} }
@ -842,12 +875,15 @@
return iRet; return iRet;
} }
/*------------------- The CallBack function for interest ------------------*/ /*------------------- The CallBack function for interest ------------------*/
static int DrivStatCallback(int iEvent, void *text, void *pCon) static int DrivStatCallback(int iEvent, void *text, void *pCon,
commandContext cc)
{ {
assert(pCon); assert(pCon);
assert(text); assert(text);
SCPushContext2(pCon,cc);
SCWrite(pCon, text, eValue); SCWrite(pCon, text, eValue);
SCPopContext(pCon);
return 1; return 1;
} }
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
@ -866,7 +902,8 @@
if (argc == 2) { if (argc == 2) {
if (strcmp(argv[1], "interest") == 0) if (strcmp(argv[1], "interest") == 0)
{ {
list = RegisterCallback(self->pCall, DRIVSTAT, DrivStatCallback, list = RegisterCallback(self->pCall, SCGetContext(pCon),
DRIVSTAT, DrivStatCallback,
pCon, NULL); pCon, NULL);
SCRegister(pCon, pSics, self->pCall,list); SCRegister(pCon, pSics, self->pCall,list);
SCSendOK(pCon); SCSendOK(pCon);
@ -1025,15 +1062,6 @@
{ {
if(iInterrupt > 1) if(iInterrupt > 1)
{ {
/* M.Z: it seems that this warning is redundant
a) because it was erroenous
b) it would be emitted for every driveable obj to be stopped
Interrupt2Text(iInterrupt,pInterrupt,79);
snprintf(pBueffel,131,"ERROR: interrupt %s triggered",
pInterrupt);
SCWrite(self->pOwner,pBueffel, eError);
*/
StopExe(self,"all"); StopExe(self,"all");
} }
#ifdef DEBUG #ifdef DEBUG
@ -1077,10 +1105,12 @@
{ {
if(self->pOwner) if(self->pOwner)
{ {
SCPushContext(self->pOwner,0,"system");
SCWrite(self->pOwner, SCWrite(self->pOwner,
"ERROR: Interrupting Current Hardware Operation", "ERROR: Interrupting Current Hardware Operation",
eError); eError);
SCSetInterrupt(self->pOwner,*iInt); SCSetInterrupt(self->pOwner,*iInt);
SCPopContext(self->pOwner);
} }
StopExe(self,"all"); StopExe(self,"all");
} }

View File

@ -51,6 +51,8 @@ is set, without the current value is printed.
<DT> nvs loss <DT> nvs loss
<DD> Starts a loss current measurement on the velocity selector and prints the <DD> Starts a loss current measurement on the velocity selector and prints the
result. result.
<DT>nvs forbidden
<DD>Prints a list of forbidden speed regions for this selector.
<DT>nvs status <DT>nvs status
<DD>Prints a status summary of the velocity selector. <DD>Prints a status summary of the velocity selector.
</DL> </DL>

View File

@ -173,6 +173,16 @@
eError); eError);
return -999.; return -999.;
} }
static void notifyStatus(pEVControl self, SConnection *pCon, int status) {
if (self->pDrivInt->drivableStatus!=status) {
((SConnection *)pCon)->conEventType=STATUS;
((SConnection *)pCon)->conStatus=status;
SCWrite(pCon, "", eEvent);
self->pDrivInt->drivableStatus=status;
}
}
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static int EVIStatus(void *pData, SConnection *pCon) static int EVIStatus(void *pData, SConnection *pCon)
{ {
@ -191,6 +201,7 @@
/* go to idle when stopped */ /* go to idle when stopped */
if(self->iStop) if(self->iStop)
{ {
notifyStatus(self, pCon, HWIdle);
return HWIdle; return HWIdle;
} }
@ -209,16 +220,19 @@
case DEVFAULT: case DEVFAULT:
sprintf(pBueffel,"ERROR: %s",pError); sprintf(pBueffel,"ERROR: %s",pError);
SCWrite(pCon,pBueffel,eError); SCWrite(pCon,pBueffel,eError);
notifyStatus(self, pCon, HWFault);
return HWFault; return HWFault;
case DEVREDO: case DEVREDO:
sprintf(pBueffel,"WARNING: Fixing problem %s",pError); sprintf(pBueffel,"WARNING: Fixing problem %s",pError);
SCWrite(pCon,pBueffel,eWarning); SCWrite(pCon,pBueffel,eWarning);
notifyStatus(self, pCon, HWBusy);
return HWBusy; return HWBusy;
break; break;
} }
} }
else if(iRet == -1 ) /* pending */ else if(iRet == -1 ) /* pending */
{ {
notifyStatus(self, pCon, HWBusy);
return HWBusy; return HWBusy;
} }
@ -228,6 +242,7 @@
self->pName); self->pName);
SCWrite(pCon,pBueffel,eError); SCWrite(pCon,pBueffel,eError);
self->eMode = EVIdle; self->eMode = EVIdle;
notifyStatus(self, pCon, HWFault);
return HWFault; return HWFault;
} }
@ -254,6 +269,7 @@
self->pName); self->pName);
SCWrite(pCon,pBueffel,eError); SCWrite(pCon,pBueffel,eError);
self->eMode = EVMonitor; self->eMode = EVMonitor;
notifyStatus(self, pCon, HWIdle);
return HWIdle; return HWIdle;
} }
tol = ObVal(self->pParam, TOLERANCE); tol = ObVal(self->pParam, TOLERANCE);
@ -272,13 +288,16 @@
self->pName, (self->lastt + tmo - now)*1.0); self->pName, (self->lastt + tmo - now)*1.0);
SCWrite(pCon,pBueffel,eStatus); SCWrite(pCon,pBueffel,eStatus);
} }
notifyStatus(self, pCon, HWBusy);
return HWBusy; return HWBusy;
} }
if (now > self->lastt + tmo) if (now > self->lastt + tmo)
{ {
self->eMode = EVMonitor; self->eMode = EVMonitor;
notifyStatus(self, pCon, HWIdle);
return HWIdle; return HWIdle;
} }
notifyStatus(self, pCon, HWBusy);
return HWBusy; return HWBusy;
} }
else else
@ -289,6 +308,7 @@
SCWrite(pCon,pBueffel,eStatus); SCWrite(pCon,pBueffel,eStatus);
self->lastt -= now; self->lastt -= now;
} }
notifyStatus(self, pCon, HWBusy);
return HWBusy; return HWBusy;
} }
} }
@ -1009,7 +1029,8 @@ static void ErrReport(pEVControl self)
return 1; return 1;
} }
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
static int EVCallBack(int iEvent, void *pEventData, void *pUserData) static int EVCallBack(int iEvent, void *pEventData, void *pUserData,
commandContext cc)
{ {
char *pBuf = (char *)pEventData; char *pBuf = (char *)pEventData;
SConnection *pCon = (SConnection *)pUserData; SConnection *pCon = (SConnection *)pUserData;
@ -1017,7 +1038,8 @@ static void ErrReport(pEVControl self)
if(iEvent == VALUECHANGE) if(iEvent == VALUECHANGE)
{ {
SCWrite(pCon,pBuf,eValue); pCon->conEventType=POSITION;
SCWriteInContext(pCon,pBuf,eEvent,cc);
return 1; return 1;
} }
return 1; return 1;
@ -1075,7 +1097,8 @@ static void ErrReport(pEVControl self)
/* install automatic notification */ /* install automatic notification */
else if(strcmp(argv[1],"interest") == 0) else if(strcmp(argv[1],"interest") == 0)
{ {
lID = RegisterCallback(self->pCall, VALUECHANGE, EVCallBack, lID = RegisterCallback(self->pCall, SCGetContext(pCon),
VALUECHANGE, EVCallBack,
pCon, NULL); pCon, NULL);
SCRegister(pCon,pSics, self->pCall,lID); SCRegister(pCon,pSics, self->pCall,lID);
SCSendOK(pCon); SCSendOK(pCon);
@ -1414,13 +1437,14 @@ int RemoveEVController(SConnection *pCon, char *name) {
SCWrite(pCon,"ERROR: cannot delete while running",eError); SCWrite(pCon,"ERROR: cannot delete while running",eError);
return 0; return 0;
} }
if (!FindCommandData(pServ->pSics, name, "Environment Controller")) { EVUnregister(FindEMON(pServ->pSics),name);
SCPrintf(pCon,eError,"ERROR: no environment controller %s found",name); iRet = RemoveCommand(pServ->pSics,name);
if(!iRet)
{
sprintf(pBueffel,"ERROR: %s not found, NOT deleted",name);
SCWrite(pCon,pBueffel,eError);
return 0; return 0;
} }
EVUnregister(FindEMON(pServ->pSics),name);
RemoveCommand(pServ->pSics,name);
return 1; return 1;
} }
/*------------------------------------------------------------------------- /*-------------------------------------------------------------------------

View File

@ -42,7 +42,8 @@
#define BATCHAREA 15 #define BATCHAREA 15
#define BATCHEND 16 #define BATCHEND 16
#define DRIVSTAT 17 #define DRIVSTAT 17
#define STATUS 18
#define POSITION 19 /* Position event for motors - ffr */
#line 104 "event.w" #line 104 "event.w"

View File

@ -284,25 +284,27 @@ static pExeInfo makeExeInfo(SConnection *pCon, pExeMan self){
return pNew; return pNew;
} }
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
static int BufferCallback(int iEvent, void *pEvent, void *pUser){ static int BufferCallback(int iEvent, void *pEvent, void *pUser,
commandContext cc){
pExeInfo self = (pExeInfo)pUser; pExeInfo self = (pExeInfo)pUser;
char *name = (char *)pEvent; char *name = (char *)pEvent;
char pBueffel[132]; char pBueffel[132];
if(iEvent == BATCHSTART){ if(iEvent == BATCHSTART){
snprintf(pBueffel,131,"BATCHSTART=%s",name); snprintf(pBueffel,131,"BATCHSTART=%s",name);
SCWrite(self->pCon,pBueffel,eWarning); SCWriteInContext(self->pCon,pBueffel,eWarning,cc);
return 1; return 1;
} }
if(iEvent == BATCHEND){ if(iEvent == BATCHEND){
snprintf(pBueffel,131,"BATCHEND=%s",name); snprintf(pBueffel,131,"BATCHEND=%s",name);
SCWrite(self->pCon,pBueffel,eWarning); SCWriteInContext(self->pCon,pBueffel,eWarning,cc);
return 1; return 1;
} }
return 0; return 0;
} }
/*-------------------------------------------------------------------*/ /*-------------------------------------------------------------------*/
static int LineCallBack(int iEvent, void *pEvent, void *pUser){ static int LineCallBack(int iEvent, void *pEvent, void *pUser,
commandContext cc){
pExeInfo self = (pExeInfo)pUser; pExeInfo self = (pExeInfo)pUser;
char pBueffel[256]; char pBueffel[256];
int start, end, lineno; int start, end, lineno;
@ -317,7 +319,7 @@ static int LineCallBack(int iEvent, void *pEvent, void *pUser){
exeBufRange(buf,&start,&end,&lineno); exeBufRange(buf,&start,&end,&lineno);
snprintf(pBueffel,255,"%s.range = %d = %d",exeBufName(buf), snprintf(pBueffel,255,"%s.range = %d = %d",exeBufName(buf),
start,end); start,end);
SCWrite(self->pCon,pBueffel,eWarning); SCWriteInContext(self->pCon,pBueffel,eWarning,cc);
return 1; return 1;
} }
return 0; return 0;
@ -332,13 +334,13 @@ static void registerCallbacks(SConnection *pCon, SicsInterp *pSics,
if(info == NULL){ if(info == NULL){
return; return;
} }
lID = RegisterCallback(self->pCall, BATCHSTART, BufferCallback, lID = RegisterCallback(self->pCall, SCGetContext(pCon),BATCHSTART, BufferCallback,
info, killExeInfo); info, killExeInfo);
SCRegister(pCon,pSics, self->pCall,lID); SCRegister(pCon,pSics, self->pCall,lID);
lID = RegisterCallback(self->pCall, BATCHEND, BufferCallback, lID = RegisterCallback(self->pCall, SCGetContext(pCon),BATCHEND, BufferCallback,
info, NULL); info, NULL);
SCRegister(pCon,pSics, self->pCall,lID); SCRegister(pCon,pSics, self->pCall,lID);
lID = RegisterCallback(self->pCall, BATCHAREA, LineCallBack, lID = RegisterCallback(self->pCall, SCGetContext(pCon),BATCHAREA, LineCallBack,
info, NULL); info, NULL);
SCRegister(pCon,pSics, self->pCall,lID); SCRegister(pCon,pSics, self->pCall,lID);
} }

View File

@ -450,6 +450,59 @@ double sign(double a, double b){
return -ABS(a); return -ABS(a);
} }
} }
/*--------------------------------------------------------------------*/
static void makeNull(double *gamma, double *om, double *nu){
*gamma = .0;
*om = .0;
*nu = .0;
}
/*---------------------------------------------------------------------*/
int z1mToNormalBeam(double lambda, MATRIX z1m, double *gamma, double *om, double *nu){
MATRIX dum, znew;
double d, a, b, sint, theta, omdeg;
int status;
status = calcTheta(lambda,z1m,&d,&theta);
if(!status){
makeNull(gamma,om,nu);
return status;
}
/* Everything on omega axis is blind: test for this */
a = sqrt(z1m[0][0] * z1m[0][0] + z1m[1][0] * z1m[1][0]);
if(ABS(a) < .0001) {
makeNull(gamma,om,nu);
return 0;
}
sint = sin(theta/RD);
b = 2.*sint*sint/(lambda*a);
if(b >= 1.) {
makeNull(gamma,om,nu);
return 0;
}
a = -atan2(z1m[1][0], -z1m[0][0]);
b = -asin(b);
*om = a + b;
omdeg = *om*RD;
dum = mat_creat(3,3,ZERO_MATRIX);
phimat(dum,omdeg);
znew = mat_mul(dum,z1m);
if(znew[0][0] < 0) {
*om = *om -2.*atan2(-znew[0][0], -znew[2][0]);
omdeg = *om * RD;
}
b = (sign(180.,omdeg)+ omdeg)/360.;
/* omdeg = omdeg - 360. * floor(b); */
*nu = asin(lambda*z1m[2][0]);
*gamma = acos(cos(2.*(theta/RD)))/cos(*nu);
*om = omdeg;
*nu = *nu * RD;
*gamma = *gamma * RD;
mat_free(dum);
mat_free(znew);
return 1;
}
/*----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/
int bisToNormalBeam(double twotheta, double omega, double chi, double phi, int bisToNormalBeam(double twotheta, double omega, double chi, double phi,
double *omeganb, double *gamma, double *nu){ double *omeganb, double *gamma, double *nu){

View File

@ -122,6 +122,10 @@ void z1FromAngles(double lambda, double stt, double om,
*/ */
int bisToNormalBeam(double twotheta, double omega, double chi, double phi, int bisToNormalBeam(double twotheta, double omega, double chi, double phi,
double *omeganb, double *gamma, double *nu); double *omeganb, double *gamma, double *nu);
/**
* calculate normal beam angles from z1
*/
int z1mToNormalBeam(double lambda, MATRIX z1, double *gamma, double *om, double *nu);
/** /**
* calculate the vector z1 from the normal beam angles omega, gamma and nu. * calculate the vector z1 from the normal beam angles omega, gamma and nu.

104
histmem.c
View File

@ -439,6 +439,7 @@
free(pNew); free(pNew);
return NULL; return NULL;
} }
StringDictAddPair(pNew->pOption,"driver",driver);
StringDictAddPair(pNew->pOption,"update","0"); StringDictAddPair(pNew->pOption,"update","0");
/* initialise driver */ /* initialise driver */
@ -532,6 +533,8 @@
return 0; return 0;
} }
StringDictAddPair(pNew->pOption,"name",argv[1]);
/* install HM as command */ /* install HM as command */
iRet = AddCommand(pSics,argv[1],HistAction,DeleteHistMemory,(void *)pNew); iRet = AddCommand(pSics,argv[1],HistAction,DeleteHistMemory,(void *)pNew);
if(!iRet) if(!iRet)
@ -918,7 +921,8 @@ void HistDirty(pHistMem self)
return 0; return 0;
} }
/*----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/
static int HMCountInterest(int iEvent, void *pEvent, void *pUser) static int HMCountInterest(int iEvent, void *pEvent, void *pUser,
commandContext cc)
{ {
SConnection *pCon = NULL; SConnection *pCon = NULL;
char pBueffel[512]; char pBueffel[512];
@ -927,14 +931,14 @@ void HistDirty(pHistMem self)
{ {
pCon = (SConnection *)pUser; pCon = (SConnection *)pUser;
assert(pCon); assert(pCon);
SCWrite(pCon,"HMCOUNTSTART",eWarning); SCWriteInContext(pCon,"HMCOUNTSTART",eWarning,cc);
return 1; return 1;
} }
else if(iEvent == COUNTEND) else if(iEvent == COUNTEND)
{ {
pCon = (SConnection *)pUser; pCon = (SConnection *)pUser;
assert(pCon); assert(pCon);
SCWrite(pCon,"HMCOUNTEND",eWarning); SCWriteInContext(pCon,"HMCOUNTEND",eWarning,cc);
return 1; return 1;
} }
return 0; return 0;
@ -955,6 +959,89 @@ static int checkHMEnd(pHistMem self, char *text){
} }
} }
} }
/*--------------------------------------------------------------------------*/
void HMListOption(pHistMem self, SConnection *pCon)
{
char pBuffer[512];
char name[20];
char pValue[128];
const char *pKey;
int i,iRet,iLen,iRank,iDiscard,tofMode;
float fVal;
char *pMode[] = {"timer","monitor",NULL};
memset(pBuffer, 0, sizeof(pBuffer));
memset(pValue, 0, sizeof(pValue));
memset(name, 0, sizeof(name));
iRet = StringDictGet(self->pOption,"name",name,19);
if(0==iRet) {
strcpy(name,"*");
}
iRet = StringDictGet(self->pOption,"driver",pValue,sizeof(pValue)-1);
if(0<iRet) {
sprintf(pBuffer,"%s.driver = %s",name,pValue);
SCWrite(pCon,pBuffer,eStatus);
}
iRet = StringDictGetAsNumber(self->pOption,"update",&fVal);
if(0<iRet) {
sprintf(pBuffer,"%s.update = %d",name,(int)rint(fVal));
} else {
sprintf(pBuffer,"%s.update = 0 (no buffering)",name);
}
SCWrite(pCon,pBuffer,eStatus);
iRet = StringDictGetAsNumber(self->pOption,"rank",&fVal);
if(0<iRet) {
iRank = (int)rint(fVal);
sprintf(pBuffer,"%s.rank = %d",name,iRank);
SCWrite(pCon,pBuffer,eStatus);
} else {
iRank = 0;
}
for(i=0; i<iRank; i++){
sprintf(pValue,"dim%1.1d",i);
iRet = StringDictGetAsNumber(self->pOption,pValue,&fVal);
if(0<iRet){
sprintf(pBuffer,"%s.dim%1.1d = %d",name,i,(int)rint(fVal));
SCWrite(pCon,pBuffer,eStatus);
}
}
pKey = StringDictGetNext(self->pOption,pValue,sizeof(pValue)-1);
while(pKey != NULL) {
iDiscard=0;
if(0==strcmp("name",pKey)) iDiscard=1;
if(0==strcmp("driver",pKey)) iDiscard=1;
if(0==strcmp("update",pKey)) iDiscard=1;
if(0==strcmp("rank",pKey)) iDiscard=1;
if(NULL!=strstr(pKey,"dim")) iDiscard=1;
if(0==iDiscard) {
sprintf(pBuffer,"%s.%s = %s",name,pKey,pValue,sizeof(pValue)-1);
SCWrite(pCon,pBuffer,eStatus);
}
pKey = StringDictGetNext(self->pOption,pValue,sizeof(pValue)-1);
}
/* Display Count Mode */
sprintf(pBuffer,"%s.CountMode = %s",name,pMode[self->pDriv->eCount]);
SCWrite(pCon,pBuffer,eStatus);
/* Display Preset */
sprintf(pBuffer,"%s.preset = %f",name,self->pDriv->fCountPreset);
SCWrite(pCon,pBuffer,eStatus);
if(self->pDriv->data->nTimeChan > 2) {
tofMode = 1;
} else {
tofMode = 0;
}
sprintf(pBuffer,"%s.tofMode = %d",name,tofMode);
SCWrite(pCon,pBuffer,eStatus);
}
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
int HistAction(SConnection *pCon, SicsInterp *pSics, void *pData, int HistAction(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]) int argc, char *argv[])
@ -998,10 +1085,12 @@ static int checkHMEnd(pHistMem self, char *text){
strtolower(argv[1]); strtolower(argv[1]);
if(strcmp(argv[1],"interest") == 0) if(strcmp(argv[1],"interest") == 0)
{ {
lID = RegisterCallback(self->pCall, COUNTSTART, HMCountInterest, lID = RegisterCallback(self->pCall, SCGetContext(pCon),
COUNTSTART, HMCountInterest,
pCon, NULL); pCon, NULL);
SCRegister(pCon,pSics, self->pCall,lID); SCRegister(pCon,pSics, self->pCall,lID);
lID = RegisterCallback(self->pCall, COUNTEND, HMCountInterest, lID = RegisterCallback(self->pCall, SCGetContext(pCon),
COUNTEND, HMCountInterest,
pCon, NULL); pCon, NULL);
SCRegister(pCon,pSics, self->pCall,lID); SCRegister(pCon,pSics, self->pCall,lID);
SCSendOK(pCon); SCSendOK(pCon);
@ -1165,6 +1254,11 @@ static int checkHMEnd(pHistMem self, char *text){
return 0; return 0;
} }
} }
else if(strcmp(argv[1],"list") == 0)
{
HMListOption(self,pCon);
return 1;
}
/* normal counting*/ /* normal counting*/
else if(strcmp(argv[1],"count") == 0) else if(strcmp(argv[1],"count") == 0)
{ {

35
hkl.c
View File

@ -205,7 +205,8 @@
#include "selvar.i" #include "selvar.i"
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static int HKLCallback(int iEvent, void *pEvent, void *pUser) static int HKLCallback(int iEvent, void *pEvent, void *pUser,
commandContext cc)
{ {
pHKL self = NULL; pHKL self = NULL;
pSelVar pVar = NULL; pSelVar pVar = NULL;
@ -236,6 +237,7 @@
pICallBack pCall = NULL, pCall2 = NULL; pICallBack pCall = NULL, pCall2 = NULL;
pDummy pDum = NULL; pDummy pDum = NULL;
float fVal; float fVal;
commandContext comCon;
assert(pCon); assert(pCon);
assert(self); assert(self);
@ -264,7 +266,10 @@
} }
/* install new callback */ /* install new callback */
comCon.transID = 0;
strncpy(comCon.deviceID,"internal",SCDEVIDLEN);
self->lID = RegisterCallback(pCall2, self->lID = RegisterCallback(pCall2,
comCon,
WLCHANGE, WLCHANGE,
HKLCallback, HKLCallback,
self, self,
@ -673,7 +678,7 @@ static int calculateNormalBeam(MATRIX z1, pHKL self, SConnection *pCon,
float fSet[4], double myPsi, int iRetry) float fSet[4], double myPsi, int iRetry)
{ {
int i, iTest; int i, iTest;
double stt, om, chi, phi, gamma, nu, psi; double stt, om, chi, phi, gamma, nu, psi, omnb;
float currentPhi, currentChi; float currentPhi, currentChi;
double ompsi, chipsi, phipsi; double ompsi, chipsi, phipsi;
MATRIX chim, phim, z4, z3; MATRIX chim, phim, z4, z3;
@ -694,6 +699,7 @@ static int calculateNormalBeam(MATRIX z1, pHKL self, SConnection *pCon,
{ {
return 0; return 0;
} }
/*
phim = mat_creat(3,3,ZERO_MATRIX); phim = mat_creat(3,3,ZERO_MATRIX);
phimat(phim,(double)currentPhi); phimat(phim,(double)currentPhi);
z4 = mat_mul(phim,z1); z4 = mat_mul(phim,z1);
@ -703,6 +709,31 @@ static int calculateNormalBeam(MATRIX z1, pHKL self, SConnection *pCon,
mat_free(phim); mat_free(phim);
mat_free(chim); mat_free(chim);
mat_free(z4); mat_free(z4);
*/
if(!z1mToNormalBeam(self->fLambda, z1, &gamma, &omnb, &nu)){
return 0;
}
if(checkNormalBeam(omnb, &gamma, nu,fSet,pCon,self)){
return 1;
} else {
return 0;
}
if(!z1mToBisecting(self->fLambda,z1,&stt,&om,&chi,&phi))
{
return 0;
}
if(bisToNormalBeam(stt,om,chi,phi,
&omnb, &gamma, &nu))
{
/* om = -om + 180.; */
if(checkNormalBeam(omnb, &gamma, nu,fSet,pCon,self))
{
return 1;
}
}
return 0;
/* /*
do the bisecting angles first do the bisecting angles first

22
ifile.c
View File

@ -153,6 +153,28 @@
{ {
return CreateNewEntry(name,value,pList); return CreateNewEntry(name,value,pList);
} }
/*--------------------------------------------------------------------------*/
IPair *IFSetOption(IPair *pList,char *name, char *value)
{
IPair *pCurrent;
if(NULL!=pList)
{
pCurrent = pList;
while((NULL!=pCurrent) && (0!=strcmp(name,pCurrent->name)))
{
pCurrent = pCurrent->pNext;
}
if(NULL!=pCurrent)
{ /* replace value */
free(pCurrent->value);
pCurrent->value = strdup(value);
return pCurrent;
}
}
return CreateNewEntry(name,value,pList);
}
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
int IFSaveOptions(IPair *pList,FILE *fd) int IFSaveOptions(IPair *pList,FILE *fd)

View File

@ -25,6 +25,8 @@ typedef struct __IFileE
/* returns a value for a name /* returns a value for a name
*/ */
IPair *IFAddOption(IPair *pList,char *name, char *value); IPair *IFAddOption(IPair *pList,char *name, char *value);
IPair *IFSetOption(IPair *pList,char *name, char *value);
int IFSaveOptions(IPair *pList,FILE *fp); int IFSaveOptions(IPair *pList,FILE *fp);
void IFDeleteOptions(IPair *pList); void IFDeleteOptions(IPair *pList);

View File

@ -83,6 +83,7 @@ static float EmptyGet(void *self, SConnection *pCon){
pRes->SetValue = EmptyValue; pRes->SetValue = EmptyValue;
pRes->CheckStatus = EmptyStatus; pRes->CheckStatus = EmptyStatus;
pRes->GetValue = EmptyGet; pRes->GetValue = EmptyGet;
pRes->drivableStatus=HWIdle;
return pRes; return pRes;
} }
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/

View File

@ -1,5 +1,5 @@
#line 365 "interface.w" #line 381 "interface.w"
/*--------------------------------------------------------------------------- /*---------------------------------------------------------------------------
I N T E R F A C E S I N T E R F A C E S
@ -17,6 +17,7 @@
#ifndef SICSINTERFACES #ifndef SICSINTERFACES
#define SICSINTERFACES #define SICSINTERFACES
#include "commandcontext.h"
/* interface ID's used to recognize an interface */ /* interface ID's used to recognize an interface */
#define DRIVEID 513 #define DRIVEID 513
@ -26,7 +27,7 @@
/* ----------------------- The drivable interface -----------------------*/ /* ----------------------- The drivable interface -----------------------*/
#line 117 "interface.w" #line 121 "interface.w"
typedef struct { typedef struct {
@ -39,6 +40,7 @@
int (*CheckStatus)(void *self, SConnection *pCon); int (*CheckStatus)(void *self, SConnection *pCon);
float (*GetValue)(void *self, SConnection *pCon); float (*GetValue)(void *self, SConnection *pCon);
int iErrorCount; int iErrorCount;
int drivableStatus;
} IDrivable, *pIDrivable; } IDrivable, *pIDrivable;
pIDrivable GetDrivableInterface(void *pObject); pIDrivable GetDrivableInterface(void *pObject);
@ -46,14 +48,14 @@
float *fPos); float *fPos);
#line 390 "interface.w" #line 407 "interface.w"
pIDrivable CreateDrivableInterface(void); pIDrivable CreateDrivableInterface(void);
/* ------------------------ The countable interface ---------------------*/ /* ------------------------ The countable interface ---------------------*/
#line 183 "interface.w" #line 188 "interface.w"
typedef struct { typedef struct {
int ID; int ID;
@ -70,23 +72,23 @@
pICountable GetCountableInterface(void *pObject); pICountable GetCountableInterface(void *pObject);
#line 395 "interface.w" #line 412 "interface.w"
pICountable CreateCountableInterface(void); pICountable CreateCountableInterface(void);
/* ------------------------- The CallBack Interface --------------------*/ /* ------------------------- The CallBack Interface --------------------*/
#line 236 "interface.w" #line 241 "interface.w"
typedef void (*KillFuncIT)(void *pData); typedef void (*KillFuncIT)(void *pData);
typedef int (*SICSCallBack)(int iEvent, void *pEventData, typedef int (*SICSCallBack)(int iEvent, void *pEventData,
void *pUserData); void *pUserData, commandContext cc);
#line 400 "interface.w" #line 417 "interface.w"
#line 258 "interface.w" #line 263 "interface.w"
typedef struct __ICallBack *pICallBack; typedef struct __ICallBack *pICallBack;
@ -96,7 +98,8 @@
int InvokeCallBack(pICallBack pInterface, int iEvent, void *pEventData); int InvokeCallBack(pICallBack pInterface, int iEvent, void *pEventData);
/* callback client side */ /* callback client side */
long RegisterCallback(pICallBack pInterface, int iEvent, SICSCallBack pFunc, long RegisterCallback(pICallBack pInterface, commandContext comCon,
int iEvent, SICSCallBack pFunc,
void *pUserData, KillFuncIT pKill); void *pUserData, KillFuncIT pKill);
int RemoveCallback(pICallBack pInterface, long iID); int RemoveCallback(pICallBack pInterface, long iID);
int RemoveCallback2(pICallBack pInterface, void *pUserData); int RemoveCallback2(pICallBack pInterface, void *pUserData);
@ -106,11 +109,11 @@
pICallBack GetCallbackInterface(void *pData); pICallBack GetCallbackInterface(void *pData);
#line 401 "interface.w" #line 418 "interface.w"
/*---------------------- The Environment Interface --------------------*/ /*---------------------- The Environment Interface --------------------*/
#line 329 "interface.w" #line 335 "interface.w"
typedef enum { EVIdle, EVDrive, EVMonitor, EVError } EVMode; typedef enum { EVIdle, EVDrive, EVMonitor, EVError } EVMode;
typedef struct { typedef struct {
@ -120,13 +123,13 @@
int (*HandleError)(void *self); int (*HandleError)(void *self);
} EVInterface, *pEVInterface; } EVInterface, *pEVInterface;
#line 403 "interface.w" #line 420 "interface.w"
#line 355 "interface.w" #line 361 "interface.w"
pEVInterface CreateEVInterface(void); pEVInterface CreateEVInterface(void);
#line 404 "interface.w" #line 421 "interface.w"
#endif #endif

View File

@ -1,3 +1,13 @@
\newcommand{\NWtarget}[2]{#2}
\newcommand{\NWlink}[2]{#2}
\newcommand{\NWtxtMacroDefBy}{Macro defined by}
\newcommand{\NWtxtMacroRefIn}{Macro referenced in}
\newcommand{\NWtxtMacroNoRef}{Macro never referenced}
\newcommand{\NWtxtDefBy}{Defined by}
\newcommand{\NWtxtRefIn}{Referenced in}
\newcommand{\NWtxtNoRef}{Not referenced}
\newcommand{\NWtxtFileDefBy}{File defined by}
\newcommand{\NWsep}{${\diamond}$}
\subsection{Object interfaces}\label{inter} \subsection{Object interfaces}\label{inter}
In order to present themselves to the system SICS objects need to adhere to In order to present themselves to the system SICS objects need to adhere to
certyain interfaces. These interfaces are described in this certyain interfaces. These interfaces are described in this
@ -28,7 +38,7 @@ Let's start with the objectdescriptor:
\begin{flushleft} \small \begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap1} \begin{minipage}{\linewidth} \label{scrap1}
$\langle$obdes {\footnotesize ?}$\rangle\equiv$ $\langle\,$obdes\nobreak\ {\footnotesize \NWtarget{nuweb?}{?}}$\,\rangle\equiv$
\vspace{-1ex} \vspace{-1ex}
\begin{list}{}{} \item \begin{list}{}{} \item
\mbox{}\verb@@\\ \mbox{}\verb@@\\
@ -50,11 +60,15 @@ $\langle$obdes {\footnotesize ?}$\rangle\equiv$
\mbox{}\verb@#ifndef SICSDESCRIPTOR@\\ \mbox{}\verb@#ifndef SICSDESCRIPTOR@\\
\mbox{}\verb@#define SICSDESCRIPTOR@\\ \mbox{}\verb@#define SICSDESCRIPTOR@\\
\mbox{}\verb@#include <stdio.h>@\\ \mbox{}\verb@#include <stdio.h>@\\
\mbox{}\verb@#include <ifile.h>@\\
\mbox{}\verb@@\\ \mbox{}\verb@@\\
\mbox{}\verb@ typedef struct {@\\ \mbox{}\verb@ typedef struct {@\\
\mbox{}\verb@ char *name;@\\ \mbox{}\verb@ char *name;@\\
\mbox{}\verb@ int (*SaveStatus)(void *self, char *name,FILE *fd);@\\ \mbox{}\verb@ int (*SaveStatus)(void *self, char *name,FILE *fd);@\\
\mbox{}\verb@ void *(*GetInterface)(void *self, int iInterfaceID);@\\ \mbox{}\verb@ void *(*GetInterface)(void *self, int iInterfaceID);@\\
\mbox{}\verb@ char *description;@\\
\mbox{}\verb@ char *group;@\\
\mbox{}\verb@ IPair *pKeys;@\\
\mbox{}\verb@ } ObjectDescriptor, *pObjectDescriptor;@\\ \mbox{}\verb@ } ObjectDescriptor, *pObjectDescriptor;@\\
\mbox{}\verb@@\\ \mbox{}\verb@@\\
\mbox{}\verb@ /*---------------------------------------------------------------------------*/@\\ \mbox{}\verb@ /*---------------------------------------------------------------------------*/@\\
@ -79,12 +93,12 @@ $\langle$obdes {\footnotesize ?}$\rangle\equiv$
\mbox{}\verb@ int iHasType(void *pData, char *Type);@\\ \mbox{}\verb@ int iHasType(void *pData, char *Type);@\\
\mbox{}\verb@ @\\ \mbox{}\verb@ @\\
\mbox{}\verb@#endif @\\ \mbox{}\verb@#endif @\\
\mbox{}\verb@@$\diamond$ \mbox{}\verb@@{\NWsep}
\end{list} \end{list}
\vspace{-1ex} \vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex} \footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} \begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?. \item \NWtxtMacroRefIn\ \NWlink{nuweb?}{?}.
\end{list} \end{list}
\end{minipage}\\[4ex] \end{minipage}\\[4ex]
\end{flushleft} \end{flushleft}
@ -128,7 +142,7 @@ environment controllers fit this bill as well.
\begin{flushleft} \small \begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap2} \begin{minipage}{\linewidth} \label{scrap2}
$\langle$driv {\footnotesize ?}$\rangle\equiv$ $\langle\,$driv\nobreak\ {\footnotesize \NWtarget{nuweb?}{?}}$\,\rangle\equiv$
\vspace{-1ex} \vspace{-1ex}
\begin{list}{}{} \item \begin{list}{}{} \item
\mbox{}\verb@@\\ \mbox{}\verb@@\\
@ -143,18 +157,19 @@ $\langle$driv {\footnotesize ?}$\rangle\equiv$
\mbox{}\verb@ int (*CheckStatus)(void *self, SConnection *pCon);@\\ \mbox{}\verb@ int (*CheckStatus)(void *self, SConnection *pCon);@\\
\mbox{}\verb@ float (*GetValue)(void *self, SConnection *pCon); @\\ \mbox{}\verb@ float (*GetValue)(void *self, SConnection *pCon); @\\
\mbox{}\verb@ int iErrorCount;@\\ \mbox{}\verb@ int iErrorCount;@\\
\mbox{}\verb@ int drivableStatus;@\\
\mbox{}\verb@ } IDrivable, *pIDrivable;@\\ \mbox{}\verb@ } IDrivable, *pIDrivable;@\\
\mbox{}\verb@@\\ \mbox{}\verb@@\\
\mbox{}\verb@ pIDrivable GetDrivableInterface(void *pObject); @\\ \mbox{}\verb@ pIDrivable GetDrivableInterface(void *pObject); @\\
\mbox{}\verb@ int GetDrivablePosition(void *pObject, SConnection *pCon,@\\ \mbox{}\verb@ int GetDrivablePosition(void *pObject, SConnection *pCon,@\\
\mbox{}\verb@ float *fPos);@\\ \mbox{}\verb@ float *fPos);@\\
\mbox{}\verb@@\\ \mbox{}\verb@@\\
\mbox{}\verb@@$\diamond$ \mbox{}\verb@@{\NWsep}
\end{list} \end{list}
\vspace{-1ex} \vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex} \footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} \begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?. \item \NWtxtMacroRefIn\ \NWlink{nuweb?}{?}.
\end{list} \end{list}
\end{minipage}\\[4ex] \end{minipage}\\[4ex]
\end{flushleft} \end{flushleft}
@ -207,7 +222,7 @@ This is an interface for interacting with anything which counts.
\begin{flushleft} \small \begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap3} \begin{minipage}{\linewidth} \label{scrap3}
$\langle$count {\footnotesize ?}$\rangle\equiv$ $\langle\,$count\nobreak\ {\footnotesize \NWtarget{nuweb?}{?}}$\,\rangle\equiv$
\vspace{-1ex} \vspace{-1ex}
\begin{list}{}{} \item \begin{list}{}{} \item
\mbox{}\verb@@\\ \mbox{}\verb@@\\
@ -225,12 +240,12 @@ $\langle$count {\footnotesize ?}$\rangle\equiv$
\mbox{}\verb@@\\ \mbox{}\verb@@\\
\mbox{}\verb@ pICountable GetCountableInterface(void *pObject); @\\ \mbox{}\verb@ pICountable GetCountableInterface(void *pObject); @\\
\mbox{}\verb@@\\ \mbox{}\verb@@\\
\mbox{}\verb@@$\diamond$ \mbox{}\verb@@{\NWsep}
\end{list} \end{list}
\vspace{-1ex} \vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex} \footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} \begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?. \item \NWtxtMacroRefIn\ \NWlink{nuweb?}{?}.
\end{list} \end{list}
\end{minipage}\\[4ex] \end{minipage}\\[4ex]
\end{flushleft} \end{flushleft}
@ -272,19 +287,19 @@ The first thing to define for such an interface is the type of the callback
function: function:
\begin{flushleft} \small \begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap4} \begin{minipage}{\linewidth} \label{scrap4}
$\langle$callfunc {\footnotesize ?}$\rangle\equiv$ $\langle\,$callfunc\nobreak\ {\footnotesize \NWtarget{nuweb?}{?}}$\,\rangle\equiv$
\vspace{-1ex} \vspace{-1ex}
\begin{list}{}{} \item \begin{list}{}{} \item
\mbox{}\verb@@\\ \mbox{}\verb@@\\
\mbox{}\verb@ typedef void (*KillFuncIT)(void *pData);@\\ \mbox{}\verb@ typedef void (*KillFuncIT)(void *pData);@\\
\mbox{}\verb@ typedef int (*SICSCallBack)(int iEvent, void *pEventData, @\\ \mbox{}\verb@ typedef int (*SICSCallBack)(int iEvent, void *pEventData, @\\
\mbox{}\verb@ void *pUserData);@\\ \mbox{}\verb@ void *pUserData, commandContext cc);@\\
\mbox{}\verb@@$\diamond$ \mbox{}\verb@@{\NWsep}
\end{list} \end{list}
\vspace{-1ex} \vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex} \footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} \begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?. \item \NWtxtMacroRefIn\ \NWlink{nuweb?}{?}.
\end{list} \end{list}
\end{minipage}\\[4ex] \end{minipage}\\[4ex]
\end{flushleft} \end{flushleft}
@ -306,7 +321,7 @@ interface:
\begin{flushleft} \small \begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap5} \begin{minipage}{\linewidth} \label{scrap5}
$\langle$cifunc {\footnotesize ?}$\rangle\equiv$ $\langle\,$cifunc\nobreak\ {\footnotesize \NWtarget{nuweb?}{?}}$\,\rangle\equiv$
\vspace{-1ex} \vspace{-1ex}
\begin{list}{}{} \item \begin{list}{}{} \item
\mbox{}\verb@@\\ \mbox{}\verb@@\\
@ -318,7 +333,8 @@ $\langle$cifunc {\footnotesize ?}$\rangle\equiv$
\mbox{}\verb@ int InvokeCallBack(pICallBack pInterface, int iEvent, void *pEventData); @\\ \mbox{}\verb@ int InvokeCallBack(pICallBack pInterface, int iEvent, void *pEventData); @\\
\mbox{}\verb@@\\ \mbox{}\verb@@\\
\mbox{}\verb@ /* callback client side */@\\ \mbox{}\verb@ /* callback client side */@\\
\mbox{}\verb@ long RegisterCallback(pICallBack pInterface, int iEvent, SICSCallBack pFunc,@\\ \mbox{}\verb@ long RegisterCallback(pICallBack pInterface, commandContext comCon, @\\
\mbox{}\verb@ int iEvent, SICSCallBack pFunc,@\\
\mbox{}\verb@ void *pUserData, KillFuncIT pKill);@\\ \mbox{}\verb@ void *pUserData, KillFuncIT pKill);@\\
\mbox{}\verb@ int RemoveCallback(pICallBack pInterface, long iID);@\\ \mbox{}\verb@ int RemoveCallback(pICallBack pInterface, long iID);@\\
\mbox{}\verb@ int RemoveCallback2(pICallBack pInterface, void *pUserData);@\\ \mbox{}\verb@ int RemoveCallback2(pICallBack pInterface, void *pUserData);@\\
@ -327,12 +343,12 @@ $\langle$cifunc {\footnotesize ?}$\rangle\equiv$
\mbox{}\verb@ int argc, char *argv[]); @\\ \mbox{}\verb@ int argc, char *argv[]); @\\
\mbox{}\verb@@\\ \mbox{}\verb@@\\
\mbox{}\verb@ pICallBack GetCallbackInterface(void *pData); @\\ \mbox{}\verb@ pICallBack GetCallbackInterface(void *pData); @\\
\mbox{}\verb@@$\diamond$ \mbox{}\verb@@{\NWsep}
\end{list} \end{list}
\vspace{-1ex} \vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex} \footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} \begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?. \item \NWtxtMacroRefIn\ \NWlink{nuweb?}{?}.
\end{list} \end{list}
\end{minipage}\\[4ex] \end{minipage}\\[4ex]
\end{flushleft} \end{flushleft}
@ -389,7 +405,7 @@ This interface is used by the environment monitor in order to monitor
the status of a environment controller. The interface looks like this: the status of a environment controller. The interface looks like this:
\begin{flushleft} \small \begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap6} \begin{minipage}{\linewidth} \label{scrap6}
$\langle$envir {\footnotesize ?}$\rangle\equiv$ $\langle\,$envir\nobreak\ {\footnotesize \NWtarget{nuweb?}{?}}$\,\rangle\equiv$
\vspace{-1ex} \vspace{-1ex}
\begin{list}{}{} \item \begin{list}{}{} \item
\mbox{}\verb@@\\ \mbox{}\verb@@\\
@ -400,12 +416,12 @@ $\langle$envir {\footnotesize ?}$\rangle\equiv$
\mbox{}\verb@ int (*IsInTolerance)(void *self);@\\ \mbox{}\verb@ int (*IsInTolerance)(void *self);@\\
\mbox{}\verb@ int (*HandleError)(void *self);@\\ \mbox{}\verb@ int (*HandleError)(void *self);@\\
\mbox{}\verb@ } EVInterface, *pEVInterface;@\\ \mbox{}\verb@ } EVInterface, *pEVInterface;@\\
\mbox{}\verb@@$\diamond$ \mbox{}\verb@@{\NWsep}
\end{list} \end{list}
\vspace{-1ex} \vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex} \footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} \begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?. \item \NWtxtMacroRefIn\ \NWlink{nuweb?}{?}.
\end{list} \end{list}
\end{minipage}\\[4ex] \end{minipage}\\[4ex]
\end{flushleft} \end{flushleft}
@ -428,17 +444,17 @@ in question.
The environment interface has just one function associated with it: The environment interface has just one function associated with it:
\begin{flushleft} \small \begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap7} \begin{minipage}{\linewidth} \label{scrap7}
$\langle$envfunc {\footnotesize ?}$\rangle\equiv$ $\langle\,$envfunc\nobreak\ {\footnotesize \NWtarget{nuweb?}{?}}$\,\rangle\equiv$
\vspace{-1ex} \vspace{-1ex}
\begin{list}{}{} \item \begin{list}{}{} \item
\mbox{}\verb@@\\ \mbox{}\verb@@\\
\mbox{}\verb@ pEVInterface CreateEVInterface(void);@\\ \mbox{}\verb@ pEVInterface CreateEVInterface(void);@\\
\mbox{}\verb@@$\diamond$ \mbox{}\verb@@{\NWsep}
\end{list} \end{list}
\vspace{-1ex} \vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex} \footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} \begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?. \item \NWtxtMacroRefIn\ \NWlink{nuweb?}{?}.
\end{list} \end{list}
\end{minipage}\\[4ex] \end{minipage}\\[4ex]
\end{flushleft} \end{flushleft}
@ -446,19 +462,29 @@ $\langle$envfunc {\footnotesize ?}$\rangle\equiv$
\begin{flushleft} \small \begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap8} \begin{minipage}{\linewidth} \label{scrap8}
\verb@"obdes.h"@ {\footnotesize ? }$\equiv$ \verb@"obdes.h"@\nobreak\ {\footnotesize \NWtarget{nuweb?}{?} }$\equiv$
\vspace{-1ex} \vspace{-1ex}
\begin{list}{}{} \item \begin{list}{}{} \item
\mbox{}\verb@@\\ \mbox{}\verb@@\\
\mbox{}\verb@@$\langle$obdes {\footnotesize ?}$\rangle$\verb@@\\ \mbox{}\verb@@\hbox{$\langle\,$obdes\nobreak\ {\footnotesize \NWlink{nuweb?}{?}}$\,\rangle$}\verb@@\\
\mbox{}\verb@@$\diamond$ \mbox{}\verb@/*--------------------------------------------------------------------------*/@\\
\mbox{}\verb@/* Additional properties used by the ANSTO site to provide more information@\\
\mbox{}\verb@ * about each object instance, especially devices.@\\
\mbox{}\verb@ */@\\
\mbox{}\verb@ void SetDescriptorKey(pObjectDescriptor self, char *keyName, char *value);@\\
\mbox{}\verb@ void SetDescriptorGroup(pObjectDescriptor self, char *group);@\\
\mbox{}\verb@ void SetDescriptorDescription(pObjectDescriptor self, char *description);@\\
\mbox{}\verb@ char * GetDescriptorKey(pObjectDescriptor self, char *keyName);@\\
\mbox{}\verb@ char * GetDescriptorGroup(pObjectDescriptor self);@\\
\mbox{}\verb@ char * GetDescriptorDescription(pObjectDescriptor self);@\\
\mbox{}\verb@@{\NWsep}
\end{list} \end{list}
\vspace{-2ex} \vspace{-2ex}
\end{minipage}\\[4ex] \end{minipage}\\[4ex]
\end{flushleft} \end{flushleft}
\begin{flushleft} \small \begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap9} \begin{minipage}{\linewidth} \label{scrap9}
\verb@"interface.h"@ {\footnotesize ? }$\equiv$ \verb@"interface.h"@\nobreak\ {\footnotesize \NWtarget{nuweb?}{?} }$\equiv$
\vspace{-1ex} \vspace{-1ex}
\begin{list}{}{} \item \begin{list}{}{} \item
\mbox{}\verb@@\\ \mbox{}\verb@@\\
@ -478,6 +504,7 @@ $\langle$envfunc {\footnotesize ?}$\rangle\equiv$
\mbox{}\verb@@\\ \mbox{}\verb@@\\
\mbox{}\verb@#ifndef SICSINTERFACES@\\ \mbox{}\verb@#ifndef SICSINTERFACES@\\
\mbox{}\verb@#define SICSINTERFACES@\\ \mbox{}\verb@#define SICSINTERFACES@\\
\mbox{}\verb@#include "commandcontext.h"@\\
\mbox{}\verb@@\\ \mbox{}\verb@@\\
\mbox{}\verb@/* interface ID's used to recognize an interface */@\\ \mbox{}\verb@/* interface ID's used to recognize an interface */@\\
\mbox{}\verb@#define DRIVEID 513@\\ \mbox{}\verb@#define DRIVEID 513@\\
@ -486,23 +513,23 @@ $\langle$envfunc {\footnotesize ?}$\rangle\equiv$
\mbox{}\verb@#define ENVIRINTERFACE 949@\\ \mbox{}\verb@#define ENVIRINTERFACE 949@\\
\mbox{}\verb@@\\ \mbox{}\verb@@\\
\mbox{}\verb@/* ----------------------- The drivable interface -----------------------*/@\\ \mbox{}\verb@/* ----------------------- The drivable interface -----------------------*/@\\
\mbox{}\verb@@$\langle$driv {\footnotesize ?}$\rangle$\verb@@\\ \mbox{}\verb@@\hbox{$\langle\,$driv\nobreak\ {\footnotesize \NWlink{nuweb?}{?}}$\,\rangle$}\verb@@\\
\mbox{}\verb@@\\ \mbox{}\verb@@\\
\mbox{}\verb@ pIDrivable CreateDrivableInterface(void);@\\ \mbox{}\verb@ pIDrivable CreateDrivableInterface(void);@\\
\mbox{}\verb@@\\ \mbox{}\verb@@\\
\mbox{}\verb@/* ------------------------ The countable interface ---------------------*/@\\ \mbox{}\verb@/* ------------------------ The countable interface ---------------------*/@\\
\mbox{}\verb@@$\langle$count {\footnotesize ?}$\rangle$\verb@@\\ \mbox{}\verb@@\hbox{$\langle\,$count\nobreak\ {\footnotesize \NWlink{nuweb?}{?}}$\,\rangle$}\verb@@\\
\mbox{}\verb@@\\ \mbox{}\verb@@\\
\mbox{}\verb@ pICountable CreateCountableInterface(void);@\\ \mbox{}\verb@ pICountable CreateCountableInterface(void);@\\
\mbox{}\verb@@\\ \mbox{}\verb@@\\
\mbox{}\verb@/* ------------------------- The CallBack Interface --------------------*/@\\ \mbox{}\verb@/* ------------------------- The CallBack Interface --------------------*/@\\
\mbox{}\verb@@$\langle$callfunc {\footnotesize ?}$\rangle$\verb@@\\ \mbox{}\verb@@\hbox{$\langle\,$callfunc\nobreak\ {\footnotesize \NWlink{nuweb?}{?}}$\,\rangle$}\verb@@\\
\mbox{}\verb@@$\langle$cifunc {\footnotesize ?}$\rangle$\verb@@\\ \mbox{}\verb@@\hbox{$\langle\,$cifunc\nobreak\ {\footnotesize \NWlink{nuweb?}{?}}$\,\rangle$}\verb@@\\
\mbox{}\verb@/*---------------------- The Environment Interface --------------------*/@\\ \mbox{}\verb@/*---------------------- The Environment Interface --------------------*/@\\
\mbox{}\verb@@$\langle$envir {\footnotesize ?}$\rangle$\verb@@\\ \mbox{}\verb@@\hbox{$\langle\,$envir\nobreak\ {\footnotesize \NWlink{nuweb?}{?}}$\,\rangle$}\verb@@\\
\mbox{}\verb@@$\langle$envfunc {\footnotesize ?}$\rangle$\verb@@\\ \mbox{}\verb@@\hbox{$\langle\,$envfunc\nobreak\ {\footnotesize \NWlink{nuweb?}{?}}$\,\rangle$}\verb@@\\
\mbox{}\verb@#endif@\\ \mbox{}\verb@#endif@\\
\mbox{}\verb@@$\diamond$ \mbox{}\verb@@{\NWsep}
\end{list} \end{list}
\vspace{-2ex} \vspace{-2ex}
\end{minipage}\\[4ex] \end{minipage}\\[4ex]

View File

@ -45,11 +45,15 @@ Let's start with the objectdescriptor:
#ifndef SICSDESCRIPTOR #ifndef SICSDESCRIPTOR
#define SICSDESCRIPTOR #define SICSDESCRIPTOR
#include <stdio.h> #include <stdio.h>
#include <ifile.h>
typedef struct { typedef struct {
char *name; char *name;
int (*SaveStatus)(void *self, char *name,FILE *fd); int (*SaveStatus)(void *self, char *name,FILE *fd);
void *(*GetInterface)(void *self, int iInterfaceID); void *(*GetInterface)(void *self, int iInterfaceID);
char *description;
char *group;
IPair *pKeys;
} ObjectDescriptor, *pObjectDescriptor; } ObjectDescriptor, *pObjectDescriptor;
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
@ -126,6 +130,7 @@ environment controllers fit this bill as well.
int (*CheckStatus)(void *self, SConnection *pCon); int (*CheckStatus)(void *self, SConnection *pCon);
float (*GetValue)(void *self, SConnection *pCon); float (*GetValue)(void *self, SConnection *pCon);
int iErrorCount; int iErrorCount;
int drivableStatus;
} IDrivable, *pIDrivable; } IDrivable, *pIDrivable;
pIDrivable GetDrivableInterface(void *pObject); pIDrivable GetDrivableInterface(void *pObject);
@ -236,7 +241,7 @@ function:
@d callfunc @{ @d callfunc @{
typedef void (*KillFuncIT)(void *pData); typedef void (*KillFuncIT)(void *pData);
typedef int (*SICSCallBack)(int iEvent, void *pEventData, typedef int (*SICSCallBack)(int iEvent, void *pEventData,
void *pUserData); void *pUserData, commandContext cc);
@} @}
The callback function is meant to return 0 for failure or 1 for success. The callback function is meant to return 0 for failure or 1 for success.
@ -264,7 +269,8 @@ interface:
int InvokeCallBack(pICallBack pInterface, int iEvent, void *pEventData); int InvokeCallBack(pICallBack pInterface, int iEvent, void *pEventData);
/* callback client side */ /* callback client side */
long RegisterCallback(pICallBack pInterface, int iEvent, SICSCallBack pFunc, long RegisterCallback(pICallBack pInterface, commandContext comCon,
int iEvent, SICSCallBack pFunc,
void *pUserData, KillFuncIT pKill); void *pUserData, KillFuncIT pKill);
int RemoveCallback(pICallBack pInterface, long iID); int RemoveCallback(pICallBack pInterface, long iID);
int RemoveCallback2(pICallBack pInterface, void *pUserData); int RemoveCallback2(pICallBack pInterface, void *pUserData);
@ -360,6 +366,16 @@ The environment interface has just one function associated with it:
@o obdes.h -d @{ @o obdes.h -d @{
@<obdes@> @<obdes@>
/*--------------------------------------------------------------------------*/
/* Additional properties used by the ANSTO site to provide more information
* about each object instance, especially devices.
*/
void SetDescriptorKey(pObjectDescriptor self, char *keyName, char *value);
void SetDescriptorGroup(pObjectDescriptor self, char *group);
void SetDescriptorDescription(pObjectDescriptor self, char *description);
char * GetDescriptorKey(pObjectDescriptor self, char *keyName);
char * GetDescriptorGroup(pObjectDescriptor self);
char * GetDescriptorDescription(pObjectDescriptor self);
@} @}
@o interface.h -d @{ @o interface.h -d @{
@ -379,6 +395,7 @@ The environment interface has just one function associated with it:
#ifndef SICSINTERFACES #ifndef SICSINTERFACES
#define SICSINTERFACES #define SICSINTERFACES
#include "commandcontext.h"
/* interface ID's used to recognize an interface */ /* interface ID's used to recognize an interface */
#define DRIVEID 513 #define DRIVEID 513

View File

@ -8,6 +8,9 @@
copyright: see copyright.h copyright: see copyright.h
Mark Koennecke, February 2000 Mark Koennecke, February 2000
added zero point handling for the Jochen
Mark Koennecke, December 2005
---------------------------------------------------------------------------*/ ---------------------------------------------------------------------------*/
#include <stdlib.h> #include <stdlib.h>
#include <math.h> #include <math.h>
@ -25,12 +28,13 @@
pIDrivable pDriv; pIDrivable pDriv;
pMotor lin; pMotor lin;
float length; float length;
float zero;
}Lin2Ang, *pLin2Ang; }Lin2Ang, *pLin2Ang;
/*-------------------------- conversion routines -------------------------*/ /*-------------------------- conversion routines -------------------------*/
static float ang2x(pLin2Ang self, float fAngle) static float ang2x(pLin2Ang self, float fAngle)
{ {
return self->length*sin(fAngle/RD); return self->length*sin((fAngle+self->zero)/RD);
} }
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
static float x2ang(pLin2Ang self, float fX) static float x2ang(pLin2Ang self, float fX)
@ -40,7 +44,7 @@
assert(self->length > 0.); assert(self->length > 0.);
dt = fX/self->length; dt = fX/self->length;
return RD*asin(dt); return RD*asin(dt) - self->zero;
} }
/*============== functions in the interface ============================*/ /*============== functions in the interface ============================*/
static void *Lin2AngGetInterface(void *pData, int iID) static void *Lin2AngGetInterface(void *pData, int iID)
@ -65,7 +69,8 @@
if(!self) if(!self)
return 0; return 0;
fprintf(fd,"%s.length %f\n",name, self->length); fprintf(fd,"%s length %f\n",name, self->length);
fprintf(fd,"%s zero %f\n",name, self->zero);
return 1; return 1;
} }
@ -99,9 +104,7 @@
self = (pLin2Ang)pData; self = (pLin2Ang)pData;
assert(self); assert(self);
fX = self->lin->pDrivInt->GetValue(self->lin,pCon); MotorGetSoftPosition(self->lin,pCon,&fX);
MotorGetPar(self->lin,"softzero",&zero);
fX -= zero;
return x2ang(self,fX); return x2ang(self,fX);
} }
/*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
@ -271,6 +274,35 @@
return 1; return 1;
} }
} }
/* zero point */
if(strcmp(argv[1],"zero") == 0)
{
if(argc >= 3)
{
iRet = Tcl_GetDouble(pSics->pTcl,argv[2],&dVal);
if(iRet != TCL_OK)
{
SCWrite(pCon,"ERROR: zero parameter not recognised as number",
eError);
return 0;
}
if(!SCMatchRights(pCon,usUser))
{
SCWrite(pCon,"ERROR: Insufficient privilege to change zero point",
eError);
return 0;
}
self->zero = dVal;
SCSendOK(pCon);
return 1;
}
else
{
sprintf(pBueffel,"%s.zero = %f",argv[0],self->zero);
SCWrite(pCon,pBueffel,eValue);
return 1;
}
}
/* limits */ /* limits */
if(strstr(argv[1],"lim") != NULL) if(strstr(argv[1],"lim") != NULL)
{ {

View File

@ -13,6 +13,7 @@ lin2ang's datastructure is quite simple:
pIDrivable pDriv; pIDrivable pDriv;
pMotor lin; pMotor lin;
float length; float length;
float zero;
}Lin2Ang; }Lin2Ang;
\end{verbatim} \end{verbatim}
The fields are: The fields are:
@ -22,6 +23,7 @@ The fields are:
functionality of this object. functionality of this object.
\item[lin] The translation table motor to use for driving the angle. \item[lin] The translation table motor to use for driving the angle.
\item[length] The length of the arm around which the angle pivots. \item[length] The length of the arm around which the angle pivots.
\item[zero] The angular zero point of this virtual motor.
\end{description} \end{description}
The interface to this is quite simple, most of the functionality is The interface to this is quite simple, most of the functionality is

View File

@ -9,4 +9,4 @@
MFLAGS=-f makefile_linux$(DUMMY) MFLAGS=-f makefile_linux$(DUMMY)
HDFROOT=/afs/psi.ch/project/sinq/linux HDFROOT=/usr/local

13
macro.c
View File

@ -707,6 +707,15 @@ static int ProtectedExec(ClientData clientData, Tcl_Interp *interp,
eOut = eWarning; eOut = eWarning;
break; break;
case 7: case 7:
eOut = eFinish;
break;
case 8:
eOut = eEvent;
break;
case 9:
eOut = eWarning;
break;
case 10:
eOut = eError; eOut = eError;
break; break;
default: default:
@ -868,7 +877,9 @@ static int ProtectedExec(ClientData clientData, Tcl_Interp *interp,
length += 10; length += 10;
pPtr = (char *)malloc(length*sizeof(char)); pPtr = (char *)malloc(length*sizeof(char));
if(pPtr == NULL){ if(pPtr == NULL){
SCWrite(pCon,"ERROR: out of memory in TclAction",eError); SCWrite(pCon,
"ERROR: out of memory in TclAction",
eError);
return 0; return 0;
} }
memset(pPtr,0,length*sizeof(char)); memset(pPtr,0,length*sizeof(char));

View File

@ -29,7 +29,8 @@ SOBJ = network.o ifile.o conman.o SCinter.o splitter.o passwd.o \
fourlib.o motreg.o motreglist.o anticollider.o nxdataset.o \ fourlib.o motreg.o motreglist.o anticollider.o nxdataset.o \
s_rnge.o sig_die.o gpibcontroller.o $(NIOBJ) mcreader.o mccontrol.o\ s_rnge.o sig_die.o gpibcontroller.o $(NIOBJ) mcreader.o mccontrol.o\
hmdata.o nxscript.o tclintimpl.o sicsdata.o mcstascounter.o \ hmdata.o nxscript.o tclintimpl.o sicsdata.o mcstascounter.o \
mcstashm.o initializer.o remob.o mcstashm.o initializer.o remob.o tclmotdriv.o protocol.o \
sinfox.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

@ -7,14 +7,15 @@
#========================================================================== #==========================================================================
# assign if the National Instrument GPIB driver is available # assign if the National Instrument GPIB driver is available
SINQDIR=/afs/psi.ch/project/sinq SINQDIR=/afs/psi.ch/project/sinq
NI= -DHAVENI NI=
NIOBJ= nigpib.o #NI= -DHAVENI
NILIB=$(SINQDIR)/linux/lib/cib.o #NIOBJ= nigpib.o
#NILIB=$(SINQDIR)/linux/lib/cib.o
include linux_def include linux_def
CC = gcc CC = gcc
CFLAGS = -I$(HDFROOT)/include -DHDF4 -DHDF5 $(NI) \ CFLAGS = -I$(HDFROOT)/include -DHDF4 -DHDF5 -DNXXML $(NI) \
-Ipsi/hardsup -I. \ -Ipsi/hardsup -I. \
-fwritable-strings -DCYGNUS -DNONINTF -g $(DFORTIFY) -fwritable-strings -DCYGNUS -DNONINTF -g $(DFORTIFY)
@ -22,10 +23,10 @@ BINTARGET = bin
EXTRA=nintf.o EXTRA=nintf.o
SUBLIBS = psi/libpsi.a psi/hardsup/libhlib.a matrix/libmatrix.a \ SUBLIBS = psi/libpsi.a psi/hardsup/libhlib.a matrix/libmatrix.a \
psi/tecs/libtecsl.a psi/tecs/libtecsl.a
LIBS = -static -L$(HDFROOT)/lib $(SUBLIBS) $(NILIB)\ LIBS = -L$(HDFROOT)/lib $(SUBLIBS) $(NILIB)\
-ltcl8.3 $(HDFROOT)/lib/libhdf5.a \ -ltcl8.4 -lmxml $(HDFROOT)/lib/libhdf5.a \
$(HDFROOT)/lib/libmfhdf.a $(HDFROOT)/lib/libdf.a \ $(HDFROOT)/lib/libmfhdf.a $(HDFROOT)/lib/libdf.a \
$(HDFROOT)/lib/libjpeg.a -ldl -lz -lm -lc -ljpeg -ldl -lz -lm -lc
include make_gen include make_gen

View File

@ -1,3 +1,3 @@
106 119
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!|n You'll risk eternal damnation and a reincarnation as a cockroach!|n

View File

@ -38,7 +38,8 @@ proc mcstasdump {pid} {
error "Trying to dump invalid PID: $pid" error "Trying to dump invalid PID: $pid"
} }
clientput "Dumping ..." clientput "Dumping ..."
catch {eval exec /usr/bin/kill -USR2 $pid} # catch {eval exec /usr/bin/kill -USR2 $pid}
catch {eval exec /bin/kill -USR2 $pid}
wait $mcwaittime wait $mcwaittime
} }
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
@ -49,7 +50,9 @@ proc mcstasdump {pid} {
# the Unix FAQ this is the best solution...... # the Unix FAQ this is the best solution......
#---------------------------------------------------------------------- #----------------------------------------------------------------------
proc readPID {pid} { proc readPID {pid} {
set f [ open "| /bin/ps -up $pid" r] # set f [ open "| /bin/ps -up $pid" r]
# This is system dependent. The above works for SL, below for Suse
set f [ open "| /bin/ps up $pid" r]
set pstxt [read $f] set pstxt [read $f]
close $f close $f
return $pstxt return $pstxt
@ -58,11 +61,13 @@ proc readPID {pid} {
proc mcstasisrunning {pid} { proc mcstasisrunning {pid} {
global runningCount runningLast global runningCount runningLast
# clientput "Checking McStas PID $pid"
if { $pid <= 0} { if { $pid <= 0} {
return 0 return 0
} }
set pstxt " " set pstxt " "
set ret [catch {set pstxt [readPID $pid]} msg] set ret [catch {set pstxt [readPID $pid]} msg]
# clientput "pstext = $pstxt"
set pslist [split $pstxt "\n"] set pslist [split $pstxt "\n"]
if { [llength $pslist] < 2} { if { [llength $pslist] < 2} {
return 0 return 0
@ -84,13 +89,17 @@ proc mcstaskill {pid} {
error "Trying to kill invalid PID $pid" error "Trying to kill invalid PID $pid"
} }
clientput "Killing $pid" clientput "Killing $pid"
catch {eval exec /usr/bin/kill -TERM $pid} # catch {eval exec /usr/bin/kill -TERM $pid} msg
# On Suse kill is /bin/kill, on others it is /usr/bin/kill
catch {eval exec /bin/kill -TERM $pid} msg
clientput "Kill message $msg"
# catch {mccontrol finish} # catch {mccontrol finish}
wait 10 wait 10
} }
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
proc mcinstall {} { proc mcinstall {} {
allowexec /usr/bin/kill allowexec /usr/bin/kill
allowexec /bin/kill
allowexec /bin/ps allowexec /bin/ps
Publish mcstasdump User Publish mcstasdump User
Publish mcstasisrunning User Publish mcstasisrunning User

View File

@ -1,4 +1,4 @@
# -------------------------------------------------------------------------- # --------------------------------------------------------------------------
# Initialization script for a virtual DMC instrument using a McStas # Initialization script for a virtual DMC instrument using a McStas
# simulationas a data source # simulationas a data source
# #
@ -6,12 +6,12 @@
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
# O P T I O N S # O P T I O N S
set home $env(HOME)/src/workspace/sics/mcstas/dmc set home $env(HOME)/psi/sics/mcstas/dmc
#--------------------------------- first all the server options are set #--------------------------------- first all the server options are set
#ServerOption RedirectFile $home/stdcdmc #ServerOption RedirectFile $home/stdcdmc
ServerOption ReadTimeOut 1 ServerOption ReadTimeOut 10
ServerOption AcceptTimeOut 1 ServerOption AcceptTimeOut 10
ServerOption ReadUserPasswdTimeout 500000 ServerOption ReadUserPasswdTimeout 500000
ServerOption LogFileBaseName "$home/vdmclog" ServerOption LogFileBaseName "$home/vdmclog"
ServerOption LogFileDir $home/ ServerOption LogFileDir $home/
@ -137,3 +137,13 @@ source $home/vdmccom.tcl
#-------------------- configure commandlog #-------------------- configure commandlog
commandlog auto commandlog auto
commandlog intervall 5 commandlog intervall 5
#----------- enable sycamore
InstallProtocolHandler
InstallSinfox
source sycFormat.tcl
source /usr/lib/tcllib1.6.1/stooop/stooop.tcl
namespace import stooop::*
source sinfo.tcl
source sycamore.tcl
Publish sinfo Spy

View File

@ -6,7 +6,7 @@
source $home/mcsupport.tcl source $home/mcsupport.tcl
if { [info exists vdmcinit] == 0 } { if { [info exists vdmcinit] == 0 } {
set vdmcinit 1 set vdmcinit 1f
Publish LogBook Spy Publish LogBook Spy
Publish count User Publish count User
Publish Repeat User Publish Repeat User
@ -187,10 +187,9 @@ proc copydmcdata { } {
mcreader insertmon \ mcreader insertmon \
"/$mcversion/DMC_diff/dmc.xml/PSD_sample/values" \ "/$mcversion/DMC_diff/dmc.xml/PSD_sample/values" \
counter 1 [expr 1./350] counter 1 [expr 1./350]
mcreader insertmon \ # mcreader insertmon \
"/$mcversion/DMC_diff/dmc.xml/Det9/det9.dat/values" \ # "/$mcversion/DMC_diff/dmc.xml/Det9/det9.dat/values" \
counter 4 # counter 4
set hmScale [SplitReply [counter getmonitor 4]]
set val [mcreader getfield\ set val [mcreader getfield\
"/$mcversion/DMC_diff/dmc.xml/Det9/det9.dat/values"] "/$mcversion/DMC_diff/dmc.xml/Det9/det9.dat/values"]
set l [split $val] set l [split $val]
@ -212,7 +211,6 @@ proc dmcdump {pid} {
#--do nothing: progress is doing it for us #--do nothing: progress is doing it for us
} }
#-------------------------------------------------------------------------- #--------------------------------------------------------------------------
#mccontrol configure mcstart rundmcsim
mccontrol configure mcstart rundmcoptsim mccontrol configure mcstart rundmcoptsim
mccontrol configure mccopydata copydmcdata mccontrol configure mccopydata copydmcdata
mccontrol configure update 30 mccontrol configure update 30

View File

@ -201,13 +201,13 @@ a9 precision 0.010000
a9 ignorefault 0.000000 a9 ignorefault 0.000000
a9 AccessCode 2.000000 a9 AccessCode 2.000000
a9 movecount 10.000000 a9 movecount 10.000000
title UNKNOWN title D3C
title setAccess 2 title setAccess 2
user UNKNOWN user UNKNOWN
user setAccess 2 user setAccess 2
collimation UNKNOWN collimation UNKNOWN
collimation setAccess 2 collimation setAccess 2
sampleintern na2ca3al2f14 sampleintern D3C
sampleintern setAccess 2 sampleintern setAccess 2
comment1 UNKNOWN comment1 UNKNOWN
comment1 setAccess 2 comment1 setAccess 2
@ -215,7 +215,7 @@ comment2 UNKNOWN
comment2 setAccess 2 comment2 setAccess 2
comment3 UNKNOWN comment3 UNKNOWN
comment3 setAccess 2 comment3 setAccess 2
starttime 2005-10-19 11:11:44 starttime 2005-12-20 05:13:05
starttime setAccess 2 starttime setAccess 2
adress UNKNOWN adress UNKNOWN
adress setAccess 2 adress setAccess 2

59
motor.c
View File

@ -52,6 +52,7 @@
#include "splitter.h" #include "splitter.h"
#include "status.h" #include "status.h"
#include "servlog.h" #include "servlog.h"
#include "tclmotdriv.h"
#include "site.h" #include "site.h"
/*------------------------------------------------------------------------- /*-------------------------------------------------------------------------
some lokal defines some lokal defines
@ -385,6 +386,12 @@ static void handleMoveCallback(pMotor self, SConnection *pCon)
self = (pMotor)sulf; self = (pMotor)sulf;
status = evaluateStatus(self,pCon); status = evaluateStatus(self,pCon);
if (self->pDrivInt->drivableStatus!=status) {
((SConnection *)pCon)->conEventType=STATUS;
((SConnection *)pCon)->conStatus=status;
SCWrite(pCon, "", eEvent);
self->pDrivInt->drivableStatus=status;
}
if(status == HWBusy) if(status == HWBusy)
{ {
handleMoveCallback(self,pCon); handleMoveCallback(self,pCon);
@ -741,7 +748,7 @@ extern void KillPiPiezo(void *pData);
iRet = MotorCheckBoundary(self,fNew,&fHard,pBueffel,511); iRet = MotorCheckBoundary(self,fNew,&fHard,pBueffel,511);
if(!iRet) if(!iRet)
{ {
SCWrite(pCon,pBueffel,eWarning); SCWrite(pCon,pBueffel,eStatus);
SCSetInterrupt(pCon,eAbortOperation); SCSetInterrupt(pCon,eAbortOperation);
return 0; return 0;
} }
@ -1000,6 +1007,21 @@ extern MotorDriver *MakePiPiezo(Tcl_Interp *pTcl, char *pArray);
SCWrite(pCon,pBueffel,eError); SCWrite(pCon,pBueffel,eError);
return 0; return 0;
} }
}else if (strcmp(argv[2],"tclmot") == 0)
{
pDriver = CreateTclMotDriv(pCon,argc,argv);
if(!pDriver)
{
return 0;
}
/* create the motor */
pNew = MotorInit("TCLMOT",argv[1],pDriver);
if(!pNew)
{
sprintf(pBueffel,"Failure to create motor %s",argv[1]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
} }
else else
{ {
@ -1034,8 +1056,8 @@ extern MotorDriver *MakePiPiezo(Tcl_Interp *pTcl, char *pArray);
int i, iLen; int i, iLen;
iLen = ObParLength(self->ParArray); iLen = ObParLength(self->ParArray);
sprintf(pBueffel,"Parameter Listing for motor %s\n",self->name); sprintf(pBueffel,"Parameter Listing for motor %s",self->name);
SCWrite(pCon,pBueffel,eStatus); SCWrite(pCon,pBueffel,eValue);
snprintf(pBueffel,511,"%s.hardupperlim = %f",self->name, snprintf(pBueffel,511,"%s.hardupperlim = %f",self->name,
self->pDriver->fUpper); self->pDriver->fUpper);
SCWrite(pCon,pBueffel,eValue); SCWrite(pCon,pBueffel,eValue);
@ -1073,6 +1095,7 @@ extern MotorDriver *MakePiPiezo(Tcl_Interp *pTcl, char *pArray);
typedef struct { typedef struct {
char *pName; char *pName;
SConnection *pCon; SConnection *pCon;
float lastValue;
} MotInfo, *pMotInfo; } MotInfo, *pMotInfo;
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
static void KillInfo(void *pData) static void KillInfo(void *pData)
@ -1088,7 +1111,8 @@ extern MotorDriver *MakePiPiezo(Tcl_Interp *pTcl, char *pArray);
free(self); free(self);
} }
/*------------------- The CallBack function for interest ------------------*/ /*------------------- The CallBack function for interest ------------------*/
static int InterestCallback(int iEvent, void *pEvent, void *pUser) static int InterestCallback(int iEvent, void *pEvent, void *pUser,
commandContext cc)
{ {
pMotInfo pInfo = NULL; pMotInfo pInfo = NULL;
char pBueffel[80]; char pBueffel[80];
@ -1100,8 +1124,12 @@ extern MotorDriver *MakePiPiezo(Tcl_Interp *pTcl, char *pArray);
psCall = (MotCallback *)pEvent; psCall = (MotCallback *)pEvent;
pInfo = (MotInfo *)pUser; pInfo = (MotInfo *)pUser;
sprintf(pBueffel,"%s.position = %f ", pInfo->pName, psCall->fVal); if (pInfo->lastValue != psCall->fVal) {
SCWrite(pInfo->pCon,pBueffel,eValue); pInfo->lastValue = psCall->fVal;
(pInfo->pCon)->conEventType=POSITION;
sprintf(pBueffel,"%s.position = %f ", pInfo->pName, pInfo->lastValue);
SCWriteInContext(pInfo->pCon,pBueffel,eEvent,cc);
}
return 1; return 1;
} }
/*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
@ -1113,7 +1141,8 @@ extern MotorDriver *MakePiPiezo(Tcl_Interp *pTcl, char *pArray);
} }
} }
/*------------------------ The endscript callback function ----------------*/ /*------------------------ The endscript callback function ----------------*/
static int EndScriptCallback(int iEvent, void *pEvent, void *pUser) static int EndScriptCallback(int iEvent, void *pEvent, void *pUser,
commandContext cc)
{ {
char *pScript = NULL; char *pScript = NULL;
MotCallback *psCall; MotCallback *psCall;
@ -1178,7 +1207,7 @@ extern MotorDriver *MakePiPiezo(Tcl_Interp *pTcl, char *pArray);
if(!iRet) if(!iRet)
{ {
sprintf(pBueffel,"Error obtaining position for %s",argv[0]); sprintf(pBueffel,"Error obtaining position for %s",argv[0]);
SCWrite(pCon,pBueffel,eValue); SCWrite(pCon,pBueffel,eError);
DeleteTokenList(pList); DeleteTokenList(pList);
return 0; return 0;
} }
@ -1220,7 +1249,17 @@ extern MotorDriver *MakePiPiezo(Tcl_Interp *pTcl, char *pArray);
} }
pMoti->pName = strdup(argv[0]); pMoti->pName = strdup(argv[0]);
pMoti->pCon = pCon; pMoti->pCon = pCon;
lID = RegisterCallback(self->pCall, MOTDRIVE, InterestCallback, iRet = MotorGetSoftPosition(self,pCon,&fValue);
if(!iRet)
{
sprintf(pBueffel,"Failed to register interest, Reason:Error obtaining current position for %s",argv[0]);
SCWrite(pCon,pBueffel,eError);
DeleteTokenList(pList);
return 0;
}
pMoti->lastValue = fValue;
lID = RegisterCallback(self->pCall, SCGetContext(pCon),MOTDRIVE, InterestCallback,
pMoti, KillInfo); pMoti, KillInfo);
SCRegister(pCon,pSics, self->pCall,lID); SCRegister(pCon,pSics, self->pCall,lID);
DeleteTokenList(pList); DeleteTokenList(pList);
@ -1252,7 +1291,7 @@ extern MotorDriver *MakePiPiezo(Tcl_Interp *pTcl, char *pArray);
return 0; return 0;
} }
self->endScriptID = self->endScriptID =
RegisterCallback(self->pCall, MOTEND, EndScriptCallback, RegisterCallback(self->pCall, SCGetContext(pCon),MOTEND, EndScriptCallback,
strdup(pCurrent->text), KillScript); strdup(pCurrent->text), KillScript);
SCRegister(pCon,pSics, self->pCall,self->endScriptID); SCRegister(pCon,pSics, self->pCall,self->endScriptID);
DeleteTokenList(pList); DeleteTokenList(pList);

View File

@ -6,10 +6,8 @@
Mark Koennecke, October 1996 Mark Koennecke, October 1996
Revised for use with tasker: Mark Koennecke, September 1997 Revised for use with tasker: Mark Koennecke, September 1997
Added code to redirect stdout/sterr to file, Mark Koennecke, May 2000
Added code to redirect stdout/sterr to file. Define handler in InitServer to ignore SIGPIPE. Paul Hathaway, May 2004
Mark Koennecke, May 2000
Copyright: see copyright.h Copyright: see copyright.h
----------------------------------------------------------------------------*/ ----------------------------------------------------------------------------*/
@ -19,6 +17,7 @@
#include <assert.h> #include <assert.h>
#include <stdio.h> #include <stdio.h>
#include <sys/types.h> #include <sys/types.h>
#include <signal.h>
#include <unistd.h> #include <unistd.h>
#include <time.h> #include <time.h>
#include "sics.h" #include "sics.h"
@ -93,6 +92,8 @@
memset(self,0,sizeof(SicsServer)); memset(self,0,sizeof(SicsServer));
*pServ = self; *pServ = self;
/* define any signal handlers */
signal(SIGPIPE,SIG_IGN);
/* configure fortify */ /* configure fortify */
iFortifyScope = Fortify_EnterScope(); iFortifyScope = Fortify_EnterScope();
@ -458,7 +459,7 @@
/*-------------------------------------------------------------------------- /*--------------------------------------------------------------------------
UserWait: the user command for waiting, expects one arg: UserWait: the user command for waiting, expects one arg:
time to wait in seconds time to wait in seconds
*/ ---------------------------------------------------------------------------*/
int UserWait(SConnection *pCon, SicsInterp *pSics, void *pData, int UserWait(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]) int argc, char *argv[])
{ {
@ -517,7 +518,7 @@
} }
} }
/*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
int SicsWait(long lTime) int SicsWaitOld(long lTime)
{ {
WaitStruct sWait; WaitStruct sWait;
pTaskMan pTasker = NULL; pTaskMan pTasker = NULL;
@ -537,7 +538,28 @@
TaskWait(pTasker,lID); TaskWait(pTasker,lID);
return 1; return 1;
} }
/*------------------------------------------------------------------------
The new SicsWait is still on probation. It prevents commands to be
executed on the same task on which the Sicswait is acting.
M.K. December 2005
-------------------------------------------------------------------------*/
int SicsWait(long lTime)
{
pTaskMan pTasker = NULL;
time_t endTime;
if(pServ->simMode)
{
return 1;
}
pTasker = GetTasker();
endTime = time(NULL) + lTime;
while(time(NULL) < endTime)
{
TaskYield(pTasker);
}
return 1;
}
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
void ServerWriteGlobal(char *pMessage,int iOut) void ServerWriteGlobal(char *pMessage,int iOut)
{ {

View File

@ -46,7 +46,8 @@ static int UpdateTask(void *pData){
} }
} }
/*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/
static int CountCallback(int iEvent, void *pEventData, void *pUser){ static int CountCallback(int iEvent, void *pEventData, void *pUser,
commandContext cc){
pNXupdate self = NULL; pNXupdate self = NULL;
SConnection *pCon = NULL; SConnection *pCon = NULL;
@ -257,6 +258,7 @@ int UpdateFactory(SConnection *pCon, SicsInterp *pSics, void *pData,
char pBueffel[256]; char pBueffel[256];
pNXupdate self = NULL; pNXupdate self = NULL;
CommandList *pCom = NULL; CommandList *pCom = NULL;
commandContext comCon;
if(argc < 3){ if(argc < 3){
SCWrite(pCon,"ERROR: insuffcient number of argument to UpdateFactory", SCWrite(pCon,"ERROR: insuffcient number of argument to UpdateFactory",
@ -309,9 +311,11 @@ int UpdateFactory(SConnection *pCon, SicsInterp *pSics, void *pData,
/* /*
register callbacks register callbacks
*/ */
RegisterCallback(pCall,COUNTSTART,CountCallback, comCon.transID = 0;
strncpy(comCon.deviceID,"internal",SCDEVIDLEN);
RegisterCallback(pCall,comCon,COUNTSTART,CountCallback,
self,NULL); self,NULL);
RegisterCallback(pCall,COUNTEND,CountCallback, RegisterCallback(pCall,comCon,COUNTEND,CountCallback,
self,NULL); self,NULL);
AddCommand(pSics,argv[1],UpdateAction,KillUpdate,self); AddCommand(pSics,argv[1],UpdateAction,KillUpdate,self);

78
obdes.c
View File

@ -66,6 +66,9 @@
return NULL; return NULL;
} }
pRes->name = strdup(name); pRes->name = strdup(name);
pRes->pKeys = NULL;
pRes->description = NULL;
pRes->group = NULL;
pRes->SaveStatus = DefaultSave; pRes->SaveStatus = DefaultSave;
pRes->GetInterface = DefaultGetInterface; pRes->GetInterface = DefaultGetInterface;
return pRes; return pRes;
@ -74,10 +77,10 @@
void DeleteDescriptor(pObjectDescriptor self) void DeleteDescriptor(pObjectDescriptor self)
{ {
assert(self); assert(self);
if(self->name) free(self->name);
if(self->name) if(self->description) free(self->description);
free(self->name); if(self->group) free(self->group);
if(self->pKeys) IFDeleteOptions(self->pKeys);
free(self); free(self);
} }
@ -134,11 +137,72 @@
return 0; return 0;
} }
/*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
pObjectDescriptor FindDescriptor(void *pData) pObjectDescriptor FindDescriptor(void *pData)
{ {
pDummy pDum = NULL; pDummy pDum = NULL;
assert(pData); assert(pData);
pDum = (pDummy)pData; pDum = (pDummy)pData;
return pDum->pDescriptor; return pDum->pDescriptor;
} }
/*--------------------------------------------------------------------------*/
void SetDescriptorKey(pObjectDescriptor self, char *keyName, char *eltValue)
{
if(NULL!=self)
{
IFSetOption(self->pKeys,keyName,eltValue);
}
}
/*--------------------------------------------------------------------------*/
void SetDescriptorGroup(pObjectDescriptor self, char *group)
{
if(NULL==self)
{
return;
}
if(NULL != self->group)
{
free(self->group);
}
self->group = strdup(group);
}
/*--------------------------------------------------------------------------*/
void SetDescriptorDescription(pObjectDescriptor self, char *description)
{
if(NULL==self)
{
return;
}
if(NULL != self->description)
{
free(self->description);
}
self->description = strdup(description);
}
/*--------------------------------------------------------------------------*/
char * GetDescriptorKey(pObjectDescriptor self, char *keyName)
{
if(NULL==self)
{
return NULL;
}
return IFindOption(self->pKeys,keyName);
}
/*--------------------------------------------------------------------------*/
char * GetDescriptorGroup(pObjectDescriptor self)
{
if(NULL==self)
{
return NULL;
}
return self->group;
}
/*--------------------------------------------------------------------------*/
char * GetDescriptorDescription(pObjectDescriptor self)
{
if(NULL==self)
{
return NULL;
}
return self->description;
}

18
obdes.h
View File

@ -1,5 +1,5 @@
#line 361 "interface.w" #line 367 "interface.w"
#line 29 "interface.w" #line 29 "interface.w"
@ -22,11 +22,15 @@
#ifndef SICSDESCRIPTOR #ifndef SICSDESCRIPTOR
#define SICSDESCRIPTOR #define SICSDESCRIPTOR
#include <stdio.h> #include <stdio.h>
#include <ifile.h>
typedef struct { typedef struct {
char *name; char *name;
int (*SaveStatus)(void *self, char *name,FILE *fd); int (*SaveStatus)(void *self, char *name,FILE *fd);
void *(*GetInterface)(void *self, int iInterfaceID); void *(*GetInterface)(void *self, int iInterfaceID);
char *description;
char *group;
IPair *pKeys;
} ObjectDescriptor, *pObjectDescriptor; } ObjectDescriptor, *pObjectDescriptor;
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
@ -52,5 +56,15 @@ typedef struct {
#endif #endif
#line 362 "interface.w" #line 368 "interface.w"
/*--------------------------------------------------------------------------*/
/* Additional properties used by the ANSTO site to provide more information
* about each object instance, especially devices.
*/
void SetDescriptorKey(pObjectDescriptor self, char *keyName, char *value);
void SetDescriptorGroup(pObjectDescriptor self, char *group);
void SetDescriptorDescription(pObjectDescriptor self, char *description);
char * GetDescriptorKey(pObjectDescriptor self, char *keyName);
char * GetDescriptorGroup(pObjectDescriptor self);
char * GetDescriptorDescription(pObjectDescriptor self);

10
ofac.c
View File

@ -114,6 +114,8 @@
#include "tasscanub.h" #include "tasscanub.h"
#include "mcreader.h" #include "mcreader.h"
#include "mccontrol.h" #include "mccontrol.h"
#include "protocol.h"
#include "sinfox.h"
/*----------------------- Server options creation -------------------------*/ /*----------------------- Server options creation -------------------------*/
static int IFServerOption(SConnection *pCon, SicsInterp *pSics, void *pData, static int IFServerOption(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]) int argc, char *argv[])
@ -237,6 +239,7 @@
AddCommand(pInter,"sicsdatafactory",SICSDataFactory,NULL,NULL); AddCommand(pInter,"sicsdatafactory",SICSDataFactory,NULL,NULL);
AddCommand(pInter,"scriptcallback",CallbackScript,NULL,NULL); AddCommand(pInter,"scriptcallback",CallbackScript,NULL,NULL);
AddCommand(pInter,"help",SicsHelp,KillHelp,NULL); AddCommand(pInter,"help",SicsHelp,KillHelp,NULL);
AddCommand(pInter,"sicsatt",SicsAtt,NULL,NULL);
/* commands to do with the executor. Only StopExe carries the /* commands to do with the executor. Only StopExe carries the
DeleteFunction in order to avoid double deletion. All the DeleteFunction in order to avoid double deletion. All the
@ -311,6 +314,10 @@
McStasReaderFactory,NULL,NULL); McStasReaderFactory,NULL,NULL);
AddCommand(pInter,"MakeMcStasController", AddCommand(pInter,"MakeMcStasController",
McStasControllerFactory,NULL,NULL); McStasControllerFactory,NULL,NULL);
AddCommand(pInter,"InstallProtocolHandler",
InstallProtocol,NULL,NULL);
AddCommand(pInter,"InstallSinfox",
InstallSinfox,NULL,NULL);
/* /*
install site specific commands install site specific commands
@ -376,7 +383,8 @@
RemoveCommand(pSics,"MakeTasUB"); RemoveCommand(pSics,"MakeTasUB");
RemoveCommand(pSics,"MakeTasScan"); RemoveCommand(pSics,"MakeTasScan");
RemoveCommand(pSics,"MakemcStasReader"); RemoveCommand(pSics,"MakemcStasReader");
RemoveCommand(pSics,"InstallProtocolHandler");
RemoveCommand(pSics,"InstallSinfox");
/* /*
remove site specific installation commands remove site specific installation commands
*/ */

View File

@ -15,8 +15,11 @@
"inerror", "inerror",
"status", "status",
"value", "value",
"start",
"finish",
"event",
"warning", "warning",
"error", "error",
NULL }; NULL };
static int iNoCodes = 7; static int iNoCodes = 10;
#endif #endif

View File

@ -147,7 +147,8 @@
return self->fCPS; return self->fCPS;
} }
/*------------------- The CallBack function for interest ------------------*/ /*------------------- The CallBack function for interest ------------------*/
static int InterestCallback(int iEvent, void *pEvent, void *pUser) static int InterestCallback(int iEvent, void *pEvent, void *pUser,
commandContext cc)
{ {
float *fPos; float *fPos;
SConnection *pCon; SConnection *pCon;
@ -160,7 +161,7 @@
pCon = (SConnection *)pUser; pCon = (SConnection *)pUser;
sprintf(pBueffel,"Performance = %f", *fPos); sprintf(pBueffel,"Performance = %f", *fPos);
SCWrite(pCon,pBueffel,eValue); SCWriteInContext(pCon,pBueffel,eValue,cc);
return 1; return 1;
} }
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
@ -206,7 +207,8 @@
if(strcmp(argv[1],"interest") == 0) if(strcmp(argv[1],"interest") == 0)
{ {
lID = RegisterCallback(self->pCall, VALUECHANGE, InterestCallback, lID = RegisterCallback(self->pCall, SCGetContext(pCon),
VALUECHANGE, InterestCallback,
pCon, NULL); pCon, NULL);
SCRegister(pCon,pSics, self->pCall,lID); SCRegister(pCon,pSics, self->pCall,lID);
SCSendOK(pCon); SCSendOK(pCon);

616
protocol.c Normal file
View File

@ -0,0 +1,616 @@
/*--------------------------------------------------------------------------
ANSTO Protocol Command Object
Paul Hathaway, November, 2004
Copyright: See copyright.txt
----------------------------------------------------------------------------*/
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <conman.h>
#include <obdes.h>
#include <sics.h>
#include <conman.h>
#include <fupa.h>
#include <splitter.h>
#include <outcode.c>
#include <dynstring.h>
#include "protocol.h"
#define MAXMSG 1024
#define INIT_STR_SIZE 256
#define STR_RESIZE_LENGTH 256
typedef struct __Protocol {
pObjectDescriptor pDes; /* required as first field */
char *name; /* protocol handler name */
char *version; /* protocol version string */
int iNumPros; /* number of valid protocols? */
writeFunc defaultWriter; /* default write function */
int isDefaultSet;
char *pProList[5]; /* list of valid protocols? */
} Protocol;
char *pEventType[]={
"VALUECHANGE", /* 0 */
"MOTDRIVE", /* 1 */
"MONITOR", /* 2 */
"ROTSTART", /* 3 */
"ROTMOVE", /* 4 */
"SCANEND", /* 5 */
"SCANSTART", /* 6 */
"SCANPOINT", /* 7 */
"WLCHANGE", /* 8 */
"REFLECTIONDONE", /* 9 */
"COUNTSTART", /* 10 */
"COUNTEND", /* 11 */
"FILELOADED", /* 12 */
"MOTEND", /* 13 */
"BATCHSTART", /* 14 */
"BATCHAREA", /* 15 */
"BATCHEND", /* 16 */
"DRIVSTAT", /* 17 */
"STATUS", /* 18 */
"POSITION" /* 19 Motor position events, ffr */
};
char *pStatus[]={
"UNSET",
"OKOK", /* 1 */
"HWIdle", /* 2 */
"HWBusy", /* 3 */
"HWFault", /* 4 */
"HWPosFault", /* 5 */
"HWCrash", /* 6 */
"NOMEMORY", /* 7 */
"HWNoBeam", /* 8 */
"HWPause", /* 9 */
"HWWarn", /* 10 */
"HWRedo", /* 11 */
};
typedef struct __Protocol *pProtocol;
/* alternate implementation of protocol list if data hiding in
* Protocol struct via CreateProtocol does not work
* static char *pPros[] = {
* "default",
* "outcodes",
* "sycamore"
* NULL };
* static int iNumPros = 3
*/
pProtocol CreateProtocol(void);
static int ProtocolOptions(SConnection* pCon, pProtocol pPro);
static int ProtocolHelp(SConnection* pCon, Protocol* pPro);
static int ProtocolSet(SConnection* pCon, Protocol* pPro, char *pProName);
static int ProtocolGet(SConnection* pCon, Protocol* pPro, char *pProName,
int *pIndex);
static int ProtocolList(SConnection* pCon, Protocol* pPro);
int ProtocolAction(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]);
static int EnumChoice(char *pList[], int iLength, char *pInput);
static int InitDefaultProtocol(SConnection* pCon, Protocol *pPro);
/* Signatures for protocol writers implemented in this file */
int SCWriteSycamore(SConnection *pCon, char *pBuffer, int iOut);
/*--------------------------------------------------------------------------*/
pProtocol CreateProtocol(void)
{
int i, iNumPros = 4;
char *pPros[5] = {"default",
"normal",
"withcode",
"sycamore",
NULL
};
pProtocol pNew = NULL;
pNew = (pProtocol)malloc(sizeof(Protocol));
if(!pNew)
{
return NULL;
}
pNew->pDes = CreateDescriptor("Protocol");
if(!pNew->pDes)
{
free(pNew);
return NULL;
}
pNew->name = strdup("protocol");
pNew->version = strdup("1.0");
pNew->iNumPros = iNumPros;
// pNew->pProList = (char *)malloc(sizeof(pPros));
for(i=0;i<iNumPros;i++)
{
pNew->pProList[i] = strdup(pPros[i]);
}
pNew->pProList[i] = NULL;
pNew->isDefaultSet = 0;
return pNew;
}
/*-------------------------------------------------------------------------*/
void DeleteProtocol(void *self)
{
int i;
pProtocol pOld = (pProtocol)self;
if(NULL==pOld)
{
return;
}
if(pOld->name)
{
free(pOld->name);
}
if(pOld->pDes)
{
DeleteDescriptor(pOld->pDes);
}
if(pOld->version)
{
free(pOld->version);
}
if(pOld->pProList)
{
i = 0;
while(NULL!=pOld->pProList[i])
{
free(pOld->pProList[i]);
i++;
}
}
free(pOld);
}
/*------------------------------------------------------------------*/
static int ContextDo(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]){
commandContext comCon;
char command[1024];
int status;
if(argc < 3){
SCWrite(pCon,"ERROR: insufficient arguments to contextdo",eError);
return 0;
}
status = Tcl_GetInt(pSics->pTcl,argv[1],&comCon.transID);
if(status != TCL_OK){
snprintf(command,1023,"ERROR: failed to convert %s to transaction ID", argv[1]);
SCWrite(pCon,command,eError);
return 0;
}
strncpy(comCon.deviceID,argv[2],SCDEVIDLEN);
memset(command,0,1024*sizeof(char));
Arg2Text(argc-2,&argv[2],command,1023);
SCPushContext2(pCon,comCon);
status = InterpExecute(pSics,pCon,command);
SCPopContext(pCon);
return status;
}
/*--------------------------------------------------------------------------*/
int InstallProtocol(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[])
{
pProtocol pNew = NULL;
pNew = CreateProtocol();
if(NULL==pNew)
{
SCWrite(pCon,"No memory to create Protocol",eError);
return 0;
}
AddCommand(pSics,"Protocol",ProtocolAction,DeleteProtocol,pNew);
AddCommand(pSics,"contextdo",ContextDo,NULL,NULL);
SCSendOK(pCon);
return 1;
}
/*------------------------------------------------------------------------*/
static int ProtocolOptions(SConnection* pCon, pProtocol pPro)
{
int i;
char pBuffer[80];
for(i=0;i<pPro->iNumPros;i++)
{
sprintf(pBuffer,"Protocol[%d] = %s",i,pPro->pProList[i]);
SCWrite(pCon,pBuffer,eStatus);
}
return 1;
}
/*------------------------------------------------------------------------*/
static int ProtocolHelp(SConnection* pCon, Protocol* pPro)
{
SCWrite(pCon,
"Usage: protocol {help|list|options|reset} | set protocolName",
eStatus);
return 1;
}
/*------------------------------------------------------------------------*/
static int ProtocolSet(SConnection* pCon, Protocol* pPro, char *pProName)
{
int proID;
if(!SCVerifyConnection(pCon))
{
return 0;
}
/* lazy initialisation of defaultWriter since connection is verified */
InitDefaultProtocol(pCon,pPro);
/* Do not die if no data */
if(NULL == pProName)
{
return 0;
}
/* check list of protocols for valid name and assign functions based */
/* on match of pProName */
proID = EnumChoice(pPro->pProList,pPro->iNumPros,pProName);
switch(proID)
{
case -1: /* invalid */
return 0;
break;
case 1: /* normal (connection start default) */
SCSetWriteFunc(pCon,SCNormalWrite);
break;
case 2: /* outcodes */
SCSetWriteFunc(pCon,SCWriteWithOutcode);
break;
case 3: /* sycamore */
SCSetWriteFunc(pCon,SCWriteSycamore);
break;
case 0: /* default = psi_sics */
default:
SCSetWriteFunc(pCon,pPro->defaultWriter);
break;
}
pCon->iProtocolID = proID;
SCSendOK(pCon);
return 1;
}
/*------------------------------------------------------------------------*/
static int ProtocolGet(SConnection* pCon, Protocol* pPro, char *pProName,
int *pIndex)
{
if(!SCVerifyConnection(pCon))
{
return 0;
}
/* lazy initialisation of defaultWriter since connection is verified */
if(0==pPro->isDefaultSet)
{
pPro->defaultWriter = SCGetWriteFunc(pCon);
pPro->isDefaultSet = 1;
pCon->iProtocolID = 0;
}
*pIndex = (int)malloc(sizeof(int));
*pIndex = pCon->iProtocolID;
/* check list of protocols for valid name */
switch(*pIndex)
{
case 0: /* default = psi_sics */
case 1: /* normal (connection start default) */
case 2: /* outcodes */
case 3: /* sycamore */
pProName = strdup(pPro->pProList[*pIndex]);
return 1;
break;
default:
return 0;
break;
}
}
/*------------------------------------------------------------------------*/
static int ProtocolList(SConnection* pCon, Protocol* pPro)
{
SCWrite(pCon,
"Usage: protocol {help|list|options|reset} | set protocolName",
eStatus);
return 1;
}
/*-------------------------------------------------------------------------*/
int ProtocolAction(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[])
{
int iRet;
char **argx;
FuPaResult PaRes;
pProtocol pPro = NULL;
const int iNumCmds = 5;
FuncTemplate CommandTemplate[] = {
{"help",0,{0,0}},
{"list",0,{0,0}},
{"options",0,{0,0}},
{"set",1,{FUPATEXT}},
{"reset",0,{0,0}},
NULL
};
assert(pCon);
assert(pSics);
pPro = (pProtocol)pData;
assert(pPro);
/* You need to have User level access rights to use this facility */
if(!SCMatchRights(pCon,usUser))
{
return 0;
}
/* parse function args */
argtolower(argc,argv);
argx = &argv[1];
iRet = EvaluateFuPa((pFuncTemplate)&CommandTemplate,iNumCmds,argc-1,argx,&PaRes);
/* if invalid (iRet < 0) then default to "help" command */
switch(iRet)
{
case 1: /* list */
iRet = ProtocolList(pCon,pPro);
break;
case 2: /* options */
iRet = ProtocolOptions(pCon,pPro);
break;
case 3: /* set */
iRet = ProtocolSet(pCon,pPro,PaRes.Arg[0].text);
break;
case 4: /* reset */
iRet = ProtocolSet(pCon,pPro,"default");
break;
case 0: /* help */
default:
iRet = ProtocolHelp(pCon,pPro);
break;
}
return iRet;
}
/*-------------------------------------------------------------------------*/
static int EnumChoice(char *pList[], int iLength, char *pInput)
{
int i;
int iRet = -1;
for(i=0;i<iLength;i++)
{
if(0==strcmp(pInput,pList[i]))
{
iRet = i;
break;
}
}
return iRet;
}
/*----------------------------------*/
static int InitDefaultProtocol(SConnection* pCon, Protocol *pPro)
{
if(NULL==pCon)
{
return 0;
}
/* lazy initialisation of defaultWriter since connection is verified */
if(0==pPro->isDefaultSet)
{
pPro->defaultWriter = SCGetWriteFunc(pCon);
pPro->isDefaultSet = 1;
pCon->iProtocolID = 0;
}
return pPro->isDefaultSet;
}
/*---------------------------------------------------------------------*/
int SCWriteSycamore(SConnection *pCon, char *pBuffer, int iOut)
{
int i, iPtr, iRet;
int bDevIDdone = 0;
int bFlagDone = 0;
char pBueffel[MAXMSG];
long taskID = 0;
/* char pPrefix[40];*/
pDynString pMsg = NULL;
pDynString pMsgOut = NULL;
pDynString parseCmd = NULL;
SicsInterp *pSics;
TokenList *pList = NULL;
TokenList *pCurrent;
commandContext comCon;
char *savedTclResult = NULL;
/* For calling sycParse from interpreter */
char **argv = NULL;
int argc;
char *parser = "sycformat ";
char batchName[50];
strcpy(batchName,"::ansto::batch::next");
CommandList *pCommand = NULL;
if(!SCVerifyConnection(pCon))
{
DeleteDynString(parseCmd);
return 0;
}
comCon = SCGetContext(pCon);
if (strcmp(comCon.deviceID, batchName) == 0) {
DeleteDynString(parseCmd);
return 1;
}
/* Return 0 without dying if no message data */
if(pBuffer == NULL)
{
DeleteDynString(parseCmd);
return 0;
}
/*
build the Tcl-command to execute for formatting the
data into a sycamore string
*/
pSics = GetInterpreter();
taskID = comCon.transID;
taskID = taskID % 1000000;
pMsg = CreateDynString(INIT_STR_SIZE, STR_RESIZE_LENGTH);
pBueffel[0] = '\0';
sprintf(pBueffel,"con%4.4d",pCon->ident); /* field 1: connID */
DynStringConcat(pMsg,pBueffel);
sprintf(pBueffel," t%6.6d",taskID); /* field 2: taskID */
DynStringConcat(pMsg,pBueffel);
DynStringConcatChar(pMsg,' ');
/* deviceID */
DynStringConcat(pMsg,comCon.deviceID);
DynStringConcatChar(pMsg,' ');
/* msgFlag */
switch(iOut) {
case 5: /* eValue */
DynStringConcat(pMsg,"out");
break;
default:
DynStringConcat(pMsg,pCode[iOut]);
break;
}
DynStringConcatChar(pMsg,' ');
DynStringConcat(pMsg, " { ");
DynStringConcat(pMsg, comCon.deviceID);
DynStringConcat(pMsg, " } {");
if (iOut == eStart){
DynStringConcat(pMsg, comCon.deviceID);
}
parseCmd = CreateDynString(INIT_STR_SIZE, STR_RESIZE_LENGTH);
DynStringCopy(parseCmd, parser);
DynStringConcat(parseCmd,GetCharArray(pMsg));
DynStringConcat(parseCmd,pBuffer);
if (iOut == eEvent) {
DynStringConcat(parseCmd, " type.");
DynStringConcat(parseCmd, pEventType[pCon->conEventType]);
DynStringConcat(parseCmd, " status.");
DynStringConcat(parseCmd, pStatus[pCon->conStatus]);
}
DynStringConcatChar(parseCmd, '}');
savedTclResult = strdup(Tcl_GetStringResult(pSics->pTcl));
Tcl_Eval(pSics->pTcl, GetCharArray(parseCmd));
pMsgOut = CreateDynString(INIT_STR_SIZE, STR_RESIZE_LENGTH);
DynStringCopy(pMsgOut, (char *)Tcl_GetStringResult(pSics->pTcl));
if(savedTclResult != NULL){
Tcl_SetResult(pSics->pTcl,savedTclResult,TCL_VOLATILE);
free(savedTclResult);
}
/* log it for any case */
if(pCon->pSock)
{
iRet = pCon->pSock->sockid;
}
else
{
iRet = 0;
}
sprintf(pBueffel,"Next line intended for socket: %d",iRet);
SICSLogWrite(pBueffel,eInternal);
SICSLogWrite(GetCharArray(pMsgOut),iOut);
/* write to commandlog if user or manager privilege */
if(SCGetRights(pCon) <= usUser)
{
sprintf(pBueffel,"To sock %d :",iRet);
WriteToCommandLog(pBueffel,GetCharArray(pMsgOut));
}
/* put it into the interpreter if present */
if(SCinMacro(pCon))
{
InterpWrite(pSics,pBuffer);
iRet = SCDoSockWrite(pCon,GetCharArray(pMsgOut));
}
else /* not in interpreter, normal logic */
{
/* is this really to be printed ? */
if(iOut < pCon->iOutput)
{
DeleteDynString(parseCmd);
DeleteDynString(pMsg);
DeleteDynString(pMsgOut);
return 0;
}
/* first the socket */
/*strcat(pMsg, pBueffel);*/
iRet = SCDoSockWrite(pCon,GetCharArray(pMsgOut));
SCWriteToLogFiles(pCon,GetCharArray(pMsgOut));
}
if(pMsgOut != NULL){
DeleteDynString(pMsgOut);
}
DeleteDynString(parseCmd);
DeleteDynString(pMsg);
return 1;
}
/*------------------------------------------------------------------------*/
/* Protocol API */
char * GetProtocolName(SConnection* pCon)
{
pProtocol pPro;
pSicsInterp pSics;
if(!SCVerifyConnection(pCon))
{
return NULL;
}
pSics = GetInterpreter();
if(!pSics) return NULL;
pPro = FindCommandData(pSics,"protocol","Protocol");
if(!pPro) return NULL;
InitDefaultProtocol(pCon,pPro);
/* check list of protocols for valid name */
switch(pCon->iProtocolID)
{
case 0: /* default = psi_sics */
case 1: /* normal (connection start default) */
case 2: /* outcodes */
case 3: /* sycamore */
return strdup(pPro->pProList[pCon->iProtocolID]);
break;
default:
return strdup("invalid");
break;
}
}
/*----------------------------------*/
int GetProtocolID(SConnection* pCon)
{
if(NULL!=pCon)
{
return pCon->iProtocolID;
}
return -1;
}

34
protocol.h Normal file
View File

@ -0,0 +1,34 @@
/*---------------------------------------------------------------------------
----------------------------------------------------------------------------*/
#ifndef ANSTO_PROTOCOL
#define ANSTO_PROTOCOL
#include <sics.h>
#include <conman.h>
static const int iNumProTags = 2;
static char *pProTags[3] = {
"start",
"finish",
NULL
};
#define esStart -1
#define esFinish -2
/*--------------------- lifecycle -------------------------------------- */
int InstallProtocol(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]);
void DeleteProtocol(void *pSelf);
/*--------------------- operations --------------------------------------*/
int ProtocolAction(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]);
/*--------------------- implement protocol sycamore ---------------------*/
int SCWriteSycamore(SConnection *pCon, char *pBuffer, int iOut);
/*--------------------- implement protocol API -----------------------*/
char * GetProtocolName(SConnection *pCon);
int GetProtocolID(SConnection *pCon);
/*-----------------------------------------------------------------------*/
#endif

View File

@ -250,6 +250,32 @@ int readRS232TillTerm(prs232 self, void *data, int *datalen){
} }
return 1; return 1;
} }
/*----------------------------------------------------------------------*/
int readRS232UntilWord(prs232 self,
char *buffer, int buflen, char *word){
time_t endTime;
int status;
int bytesRead = 0;
endTime = time(NULL) + self->timeout;
memset(buffer,0,buflen);
while(time(NULL) < endTime){
if(availableRS232(self)){
bytesRead = recv(self->pSock->sockid,buffer + bytesRead,
buflen - bytesRead - 1,0);
if(bytesRead < 0){
return BADREAD;
}
if(strstr(buffer,word) != NULL) {
return 1;
}
} else {
SicsWait(1);
}
}
return 0;
}
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
int availableRS232(prs232 self) int availableRS232(prs232 self)
{ {
@ -736,6 +762,31 @@ int RS232Action(SConnection *pCon, SicsInterp *pSics,
SCWrite(pCon,pBuffer,eValue); SCWrite(pCon,pBuffer,eValue);
return 1; return 1;
} }
else if(strcmp(argv[1],"readchar") == 0){
if(argc < 3){
SCWrite(pCon,"ERROR: need number of chars to read",eError);
return 0;
}
iRet = Tcl_GetInt(pSics->pTcl,argv[2],&iRead);
if(iRet != TCL_OK){
SCWrite(pCon,"ERROR: failed to convert argument to number",eError);
return 0;
}
if(!availableRS232(self))
{
SCWrite(pCon,"Nothing to read!",eError);
return 1;
}
iRet = readRS232(self,pBuffer,&iRead);
if(iRet < 0)
{
getRS232Error(iRet,pError,255);
SCWrite(pCon,pError,eError);
return 0;
}
SCWrite(pCon,pBuffer,eValue);
return 1;
}
else if(strcmp(argv[1],"available") == 0) else if(strcmp(argv[1],"available") == 0)
{ {
iRet = availableRS232(self); iRet = availableRS232(self);

View File

@ -56,6 +56,8 @@
int writeRS232(prs232 self, void *data, int dataLen); int writeRS232(prs232 self, void *data, int dataLen);
int readRS232(prs232 self, void *data, int *dataLen); int readRS232(prs232 self, void *data, int *dataLen);
int readRS232TillTerm(prs232 self, void *data, int *datalen); int readRS232TillTerm(prs232 self, void *data, int *datalen);
int readRS232UntilWord(prs232 self,
char *buffer, int buflen, char *word);
int availableRS232(prs232 self); int availableRS232(prs232 self);
int availableNetRS232(prs232 self); int availableNetRS232(prs232 self);
int transactRS232(prs232 self, void *send, int sendLen, int transactRS232(prs232 self, void *send, int sendLen,

43
scan.c
View File

@ -1236,7 +1236,8 @@ int isScanVarSoft(pScanData self){
return 1; return 1;
} }
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
static int ScanInterest(int iEvent, void *pEventData, void *pUser) static int ScanInterest(int iEvent, void *pEventData, void *pUser,
commandContext cc)
{ {
pScanData self = NULL; pScanData self = NULL;
SConnection *pCon = NULL; SConnection *pCon = NULL;
@ -1253,12 +1254,12 @@ int isScanVarSoft(pScanData self){
if(iEvent == SCANSTART) if(iEvent == SCANSTART)
{ {
SCWrite(pCon,"NewScan",eWarning); SCWriteInContext(pCon,"NewScan",eWarning,cc);
return 1; return 1;
} }
else if(iEvent == SCANEND) else if(iEvent == SCANEND)
{ {
SCWrite(pCon,"ScanEnd",eWarning); SCWriteInContext(pCon,"ScanEnd",eWarning,cc);
return 1; return 1;
} }
else if(iEvent == SCANPOINT) else if(iEvent == SCANPOINT)
@ -1299,7 +1300,8 @@ int isScanVarSoft(pScanData self){
return 1; return 1;
} }
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
static int ScanDynInterest(int iEvent, void *pEventData, void *pUser) static int ScanDynInterest(int iEvent, void *pEventData, void *pUser,
commandContext cc)
{ {
pScanData self = NULL; pScanData self = NULL;
SConnection *pCon = NULL; SConnection *pCon = NULL;
@ -1319,12 +1321,12 @@ int isScanVarSoft(pScanData self){
if(iEvent == SCANSTART) if(iEvent == SCANSTART)
{ {
SCWrite(pCon,"NewScan",eWarning); SCWriteInContext(pCon,"NewScan",eWarning,cc);
return 1; return 1;
} }
else if(iEvent == SCANEND) else if(iEvent == SCANEND)
{ {
SCWrite(pCon,"ScanEnd",eWarning); SCWriteInContext(pCon,"ScanEnd",eWarning,cc);
return 1; return 1;
} }
else if(iEvent == SCANPOINT) else if(iEvent == SCANPOINT)
@ -1346,12 +1348,13 @@ int isScanVarSoft(pScanData self){
} }
snprintf(pBueffel,255,"%s.scanpoint = {%d %f %ld}", snprintf(pBueffel,255,"%s.scanpoint = {%d %f %ld}",
self->objectName,i,fVal,lVal); self->objectName,i,fVal,lVal);
SCWrite(pCon,pBueffel,eValue); SCWriteInContext(pCon,pBueffel,eValue,cc);
} }
return 1; return 1;
} }
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
static int ScanUUInterest(int iEvent, void *pEventData, void *pUser) static int ScanUUInterest(int iEvent, void *pEventData, void *pUser,
commandContext cc)
{ {
pScanData self = NULL; pScanData self = NULL;
SConnection *pCon = NULL; SConnection *pCon = NULL;
@ -1368,12 +1371,12 @@ int isScanVarSoft(pScanData self){
if(iEvent == SCANSTART) if(iEvent == SCANSTART)
{ {
SCWrite(pCon,"NewScan",eWarning); SCWriteInContext(pCon,"NewScan",eWarning,cc);
return 1; return 1;
} }
else if(iEvent == SCANEND) else if(iEvent == SCANEND)
{ {
SCWrite(pCon,"ScanEnd",eWarning); SCWriteInContext(pCon,"ScanEnd",eWarning,cc);
return 1; return 1;
} }
else if(iEvent == SCANPOINT) else if(iEvent == SCANPOINT)
@ -1395,7 +1398,9 @@ int isScanVarSoft(pScanData self){
{ {
iData[i] = htonl((int)lData[i]); iData[i] = htonl((int)lData[i]);
} }
SCPushContext2(pCon,cc);
SCWriteUUencoded(pCon,"ScanData",iData,self->iNP*sizeof(int)); SCWriteUUencoded(pCon,"ScanData",iData,self->iNP*sizeof(int));
SCPopContext(pCon);
free(lData); free(lData);
free(iData); free(iData);
return 1; return 1;
@ -1896,13 +1901,13 @@ static int DumpScan(pScanData self, SConnection *pCon)
/*-------- interest */ /*-------- interest */
else if(strcmp(argv[1],"interest") == 0) else if(strcmp(argv[1],"interest") == 0)
{ {
lID = RegisterCallback(self->pCall, SCANSTART, ScanInterest, lID = RegisterCallback(self->pCall, SCGetContext(pCon),SCANSTART, ScanInterest,
pCon, NULL); pCon, NULL);
SCRegister(pCon,pSics, self->pCall,lID); SCRegister(pCon,pSics, self->pCall,lID);
lID = RegisterCallback(self->pCall, SCANEND, ScanInterest, lID = RegisterCallback(self->pCall, SCGetContext(pCon),SCANEND, ScanInterest,
pCon, NULL); pCon, NULL);
SCRegister(pCon,pSics, self->pCall,lID); SCRegister(pCon,pSics, self->pCall,lID);
lID = RegisterCallback(self->pCall, SCANPOINT, ScanInterest, lID = RegisterCallback(self->pCall, SCGetContext(pCon),SCANPOINT, ScanInterest,
pCon, NULL); pCon, NULL);
SCRegister(pCon,pSics, self->pCall,lID); SCRegister(pCon,pSics, self->pCall,lID);
SCSendOK(pCon); SCSendOK(pCon);
@ -1911,13 +1916,13 @@ static int DumpScan(pScanData self, SConnection *pCon)
/*-------- interest */ /*-------- interest */
else if(strcmp(argv[1],"dyninterest") == 0) else if(strcmp(argv[1],"dyninterest") == 0)
{ {
lID = RegisterCallback(self->pCall, SCANSTART, ScanDynInterest, lID = RegisterCallback(self->pCall, SCGetContext(pCon),SCANSTART, ScanDynInterest,
pCon, NULL); pCon, NULL);
SCRegister(pCon,pSics, self->pCall,lID); SCRegister(pCon,pSics, self->pCall,lID);
lID = RegisterCallback(self->pCall, SCANEND, ScanDynInterest, lID = RegisterCallback(self->pCall, SCGetContext(pCon), SCANEND, ScanDynInterest,
pCon, NULL); pCon, NULL);
SCRegister(pCon,pSics, self->pCall,lID); SCRegister(pCon,pSics, self->pCall,lID);
lID = RegisterCallback(self->pCall, SCANPOINT, ScanDynInterest, lID = RegisterCallback(self->pCall, SCGetContext(pCon),SCANPOINT, ScanDynInterest,
pCon, NULL); pCon, NULL);
SCRegister(pCon,pSics, self->pCall,lID); SCRegister(pCon,pSics, self->pCall,lID);
SCSendOK(pCon); SCSendOK(pCon);
@ -1926,13 +1931,13 @@ static int DumpScan(pScanData self, SConnection *pCon)
/*-------- uuinterest */ /*-------- uuinterest */
else if(strcmp(argv[1],"uuinterest") == 0) else if(strcmp(argv[1],"uuinterest") == 0)
{ {
lID = RegisterCallback(self->pCall, SCANSTART, ScanUUInterest, lID = RegisterCallback(self->pCall, SCGetContext(pCon),SCANSTART, ScanUUInterest,
pCon, NULL); pCon, NULL);
SCRegister(pCon,pSics, self->pCall,lID); SCRegister(pCon,pSics, self->pCall,lID);
lID = RegisterCallback(self->pCall, SCANEND, ScanUUInterest, lID = RegisterCallback(self->pCall, SCGetContext(pCon),SCANEND, ScanUUInterest,
pCon, NULL); pCon, NULL);
SCRegister(pCon,pSics, self->pCall,lID); SCRegister(pCon,pSics, self->pCall,lID);
lID = RegisterCallback(self->pCall, SCANPOINT, ScanUUInterest, lID = RegisterCallback(self->pCall, SCGetContext(pCon),SCANPOINT, ScanUUInterest,
pCon, NULL); pCon, NULL);
SCRegister(pCon,pSics, self->pCall,lID); SCRegister(pCon,pSics, self->pCall,lID);
SCSendOK(pCon); SCSendOK(pCon);

View File

@ -474,7 +474,8 @@
return 1; return 1;
} }
/*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
static int WaveLengthCallBack(int iEvent, void *pEvent, void *pUser) static int WaveLengthCallBack(int iEvent, void *pEvent, void *pUser,
commandContext cc)
{ {
SConnection *pCon = NULL; SConnection *pCon = NULL;
pSelVar self = NULL; pSelVar self = NULL;
@ -488,7 +489,7 @@
fVal = GetSelValue(self,pCon); fVal = GetSelValue(self,pCon);
sprintf(pBueffel,"%s.value = %f", self->name, fVal); sprintf(pBueffel,"%s.value = %f", self->name, fVal);
SCWrite(pCon,pBueffel,eValue); SCWriteInContext(pCon,pBueffel,eValue,cc);
return 1; return 1;
} }
/*-------------------------------------------------------------------------- /*--------------------------------------------------------------------------
@ -520,7 +521,8 @@
strtolower(argv[1]); strtolower(argv[1]);
if(strcmp(argv[1],"interest") == 0) if(strcmp(argv[1],"interest") == 0)
{ {
lID = RegisterCallback(self->pCall, WLCHANGE, WaveLengthCallBack, lID = RegisterCallback(self->pCall, SCGetContext(pCon),
WLCHANGE, WaveLengthCallBack,
pCon, NULL); pCon, NULL);
SCRegister(pCon,pSics, self->pCall,lID); SCRegister(pCon,pSics, self->pCall,lID);
SCSendOK(pCon); SCSendOK(pCon);
@ -589,7 +591,8 @@
strtolower(argv[1]); strtolower(argv[1]);
if(strcmp(argv[1],"interest") == 0) if(strcmp(argv[1],"interest") == 0)
{ {
lID = RegisterCallback(self->pCall, WLCHANGE, WaveLengthCallBack, lID = RegisterCallback(self->pCall, SCGetContext(pCon),
WLCHANGE, WaveLengthCallBack,
pCon, NULL); pCon, NULL);
SCRegister(pCon,pSics, self->pCall,lID); SCRegister(pCon,pSics, self->pCall,lID);
SCSendOK(pCon); SCSendOK(pCon);

102
servlog.c
View File

@ -39,6 +39,13 @@
IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
MODIFICATIONS. MODIFICATIONS.
Modified: Paul Hathaway, June 2004
SICSLogWrite
- no longer asserts existence of the log file, writing
to stderr and skipping further file writes.
- NETWrites log message (if enabled) before attempt to write to file
- uses OpenVerifyLogFile helper function (removed duplicate code)
-----------------------------------------------------------------------------*/ -----------------------------------------------------------------------------*/
#include "fortify.h" #include "fortify.h"
#include <stdio.h> #include <stdio.h>
@ -223,30 +230,17 @@
static FILE *fLogFile = NULL; static FILE *fLogFile = NULL;
static int iFile = 0; static int iFile = 0;
static int iLineCount = 0; static int iLineCount = 0;
static int iLogUsable = 1;
void SICSLogWrite(char *pText, OutCode eOut) /*---------------------------------------------------------------------------*/
int OpenVerifyLogFile()
{ {
char pFile[256]; char pFile[256];
char *pChar = NULL; char *pChar = NULL;
pCaptureEntry pCurrent;
char pBueffel[256];
#ifdef NOLOG
return ;
#endif
if(fLogFile == NULL) /* first time of */
{
/* no options: startup or serious trouble, print to stdout*/
if(!pSICSOptions)
{
printf(" %s \n",pText);
return;
}
/* get the filename */
pChar = IFindOption(pSICSOptions,"LogFileBaseName"); pChar = IFindOption(pSICSOptions,"LogFileBaseName");
if(!pChar) if(!pChar)
{ { /* Try to write to file "server" in*/
strcpy(pFile,"server"); strcpy(pFile,"server");
} }
else else
@ -257,44 +251,68 @@
fLogFile = fopen(pFile,"w"); fLogFile = fopen(pFile,"w");
if(!fLogFile) if(!fLogFile)
{ {
printf("ERROR: cannot open logfile %s for writing\n", fprintf(stderr,"ERROR: Cannot open logfile %s for writing\n",pFile);
pFile);
fLogFile = NULL; fLogFile = NULL;
return; return 0;
}
else
{
return 1;
} }
} }
/* switch file if to many lines */ /*---------------------------------------------------------------------------*/
if(iLineCount == MAXLOG) void SICSLogWrite(char *pText, OutCode eOut)
{
char pFile[256];
char *pChar = NULL;
pCaptureEntry pCurrent;
char pBueffel[256];
#ifdef NOLOG
return ;
#endif
/* do all captured */
pCurrent = pCapture;
while(pCurrent)
{
if( (pCurrent->iOut == eOut) || (pCurrent->iAllFlag == 1) )
{
NETWrite(pCurrent->pCon->pSock,pText,strlen(pText));
}
pCurrent = pCurrent->pNext;
}
if(0 == iLogUsable) return;
if(fLogFile == NULL) /* first time of use*/
{
/* no options: startup or serious trouble, print to stdout*/
if(!pSICSOptions)
{
printf("WARNING: Cannot log(%s)\n",pText);
return;
}
iLogUsable = OpenVerifyLogFile();
}
/* switch file if too many lines */
if(iLineCount >= MAXLOG)
{ {
fclose(fLogFile); fclose(fLogFile);
fLogFile = NULL; fLogFile = NULL;
iFile++; iFile++;
iLineCount = 0;
if(iFile >= MAXFILES) if(iFile >= MAXFILES)
{ {
iFile = 0; iFile = 0;
} }
pChar = IFindOption(pSICSOptions,"LogFileBaseName"); iLogUsable = OpenVerifyLogFile();
if(!pChar)
{
strcpy(pFile,"server");
}
else
{
strcpy(pFile,pChar);
}
sprintf(pFile,"%s%1d.log",pFile, iFile);
fLogFile = fopen(pFile,"w");
if(!fLogFile)
{
printf("ERROR: cannot open logfile %s for writing\n",
pFile);
fLogFile = NULL;
return;
}
iLineCount = 0;
} }
if(1 == iLogUsable)
{
fprintf(fLogFile,"%s\n",pText); fprintf(fLogFile,"%s\n",pText);
fflush(fLogFile); fflush(fLogFile);
iLineCount++; iLineCount++;
@ -310,4 +328,4 @@
pCurrent = pCurrent->pNext; pCurrent = pCurrent->pNext;
} }
} }
}

View File

@ -1,230 +0,0 @@
exe batchpath ./
exe syspath ./
#---- tasUB module tasub
tasub mono dd 3.350000
tasub mono hb1 1.000000
tasub mono hb2 1.000000
tasub mono vb1 1.000000
tasub mono vb2 1.000000
tasub mono ss 1
tasub ana dd 3.350000
tasub ana hb1 1.000000
tasub ana hb2 1.000000
tasub ana vb1 1.000000
tasub ana vb2 1.000000
tasub ana ss 1
tasub cell 1.000000 1.000000 1.000000 90.000000 90.000000 90.000000
tasub clear
tasub const ki
tasub ss 1
tasub setub 1.000000 0.000000 0.000000 0.000000 1.000000 0.000000 0.000000 0.000000 1.000000
tasub setnormal 0.000000 0.000000 0.000000
tasub settarget 0.000000 0.000000 0.000000 0.000000 0.000000
tasub update
scaninfo 0,Unknown,1.0,.1
scaninfo setAccess 0
polfile UNKNOWN
polfile setAccess 2
local UNKNOWN
local setAccess 2
output UNKNOWN
output setAccess 2
lastcommand UNKNOWN
lastcommand setAccess 2
user Albert von Villigen
user setAccess 2
title UNKNOWN
title setAccess 2
# Counter counter
counter SetPreset 10.000000
counter SetMode Timer
# Motor agl
agl sign 1.000000
agl SoftZero 0.000000
agl SoftLowerLim -10.000000
agl SoftUpperLim 10.000000
agl Fixed -1.000000
agl InterruptMode 0.000000
agl precision 0.010000
agl AccessCode 2.000000
agl movecount 10.000000
# Motor sgu
sgu sign 1.000000
sgu SoftZero 0.000000
sgu SoftLowerLim -16.000000
sgu SoftUpperLim 16.000000
sgu Fixed -1.000000
sgu InterruptMode 0.000000
sgu precision 0.010000
sgu AccessCode 2.000000
sgu movecount 10.000000
# Motor sgl
sgl sign 1.000000
sgl SoftZero 0.000000
sgl SoftLowerLim -16.000000
sgl SoftUpperLim 16.000000
sgl Fixed -1.000000
sgl InterruptMode 0.000000
sgl precision 0.010000
sgl AccessCode 2.000000
sgl movecount 10.000000
# Motor mgl
mgl sign 1.000000
mgl SoftZero 0.000000
mgl SoftLowerLim -10.000000
mgl SoftUpperLim 10.000000
mgl Fixed -1.000000
mgl InterruptMode 0.000000
mgl precision 0.010000
mgl AccessCode 2.000000
mgl movecount 10.000000
# Motor atu
atu sign 1.000000
atu SoftZero 0.000000
atu SoftLowerLim -17.000000
atu SoftUpperLim 16.879999
atu Fixed -1.000000
atu InterruptMode 0.000000
atu precision 0.010000
atu AccessCode 2.000000
atu movecount 10.000000
# Motor atl
atl sign 1.000000
atl SoftZero 0.000000
atl SoftLowerLim -17.000000
atl SoftUpperLim 17.000000
atl Fixed -1.000000
atl InterruptMode 0.000000
atl precision 0.010000
atl AccessCode 2.000000
atl movecount 10.000000
# Motor stu
stu sign 1.000000
stu SoftZero 0.000000
stu SoftLowerLim -30.000000
stu SoftUpperLim 30.000000
stu Fixed -1.000000
stu InterruptMode 0.000000
stu precision 0.010000
stu AccessCode 2.000000
stu movecount 10.000000
# Motor stl
stl sign 1.000000
stl SoftZero 0.000000
stl SoftLowerLim -30.000000
stl SoftUpperLim 30.000000
stl Fixed -1.000000
stl InterruptMode 0.000000
stl precision 0.010000
stl AccessCode 2.000000
stl movecount 10.000000
# Motor mtu
mtu sign 1.000000
mtu SoftZero 0.000000
mtu SoftLowerLim -17.000000
mtu SoftUpperLim 17.000000
mtu Fixed -1.000000
mtu InterruptMode 0.000000
mtu precision 0.010000
mtu AccessCode 2.000000
mtu movecount 10.000000
# Motor mtl
mtl sign 1.000000
mtl SoftZero 0.000000
mtl SoftLowerLim -17.000000
mtl SoftUpperLim 17.000000
mtl Fixed -1.000000
mtl InterruptMode 0.000000
mtl precision 0.010000
mtl AccessCode 2.000000
mtl movecount 10.000000
# Motor ach
ach sign 1.000000
ach SoftZero 0.000000
ach SoftLowerLim -0.500000
ach SoftUpperLim 11.500000
ach Fixed -1.000000
ach InterruptMode 0.000000
ach precision 0.010000
ach AccessCode 2.000000
ach movecount 10.000000
# Motor sro
sro sign 1.000000
sro SoftZero 0.000000
sro SoftLowerLim 0.000000
sro SoftUpperLim 351.000000
sro Fixed -1.000000
sro InterruptMode 0.000000
sro precision 0.010000
sro AccessCode 2.000000
sro movecount 10.000000
# Motor mcv
mcv sign 1.000000
mcv SoftZero 0.000000
mcv SoftLowerLim -9.000000
mcv SoftUpperLim 124.000000
mcv Fixed -1.000000
mcv InterruptMode 0.000000
mcv precision 0.010000
mcv AccessCode 2.000000
mcv movecount 10.000000
# Motor a6
a6 sign 1.000000
a6 SoftZero 0.000000
a6 SoftLowerLim -116.000000
a6 SoftUpperLim 166.000000
a6 Fixed -1.000000
a6 InterruptMode 0.000000
a6 precision 0.010000
a6 AccessCode 2.000000
a6 movecount 10.000000
# Motor a5
a5 sign 1.000000
a5 SoftZero 0.000000
a5 SoftLowerLim -200.000000
a5 SoftUpperLim 200.000000
a5 Fixed -1.000000
a5 InterruptMode 0.000000
a5 precision 0.010000
a5 AccessCode 2.000000
a5 movecount 10.000000
# Motor a4
a4 sign 1.000000
a4 SoftZero 0.000000
a4 SoftLowerLim -135.100006
a4 SoftUpperLim 123.400002
a4 Fixed -1.000000
a4 InterruptMode 0.000000
a4 precision 0.010000
a4 AccessCode 2.000000
a4 movecount 10.000000
# Motor a3
a3 sign 1.000000
a3 SoftZero 0.000000
a3 SoftLowerLim -177.300003
a3 SoftUpperLim 177.300003
a3 Fixed -1.000000
a3 InterruptMode 0.000000
a3 precision 0.010000
a3 AccessCode 2.000000
a3 movecount 10.000000
# Motor a2
a2 sign 1.000000
a2 SoftZero 0.000000
a2 SoftLowerLim -129.100006
a2 SoftUpperLim -22.000000
a2 Fixed -1.000000
a2 InterruptMode 0.000000
a2 precision 0.010000
a2 AccessCode 2.000000
a2 movecount 10.000000
# Motor a1
a1 sign 1.000000
a1 SoftZero 0.000000
a1 SoftLowerLim -87.000000
a1 SoftUpperLim 6.100000
a1 Fixed -1.000000
a1 InterruptMode 0.000000
a1 precision 0.010000
a1 AccessCode 2.000000
a1 movecount 10.000000

View File

@ -374,12 +374,13 @@
} }
} }
/*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/
static int VarInterestCallback(int iEvent, void *pEvent, void *pUser) static int VarInterestCallback(int iEvent, void *pEvent, void *pUser,
commandContext cc)
{ {
SConnection *pCon; SConnection *pCon;
char pBueffel[512]; char pBueffel[512];
pSicsVariable pVar = NULL; pSicsVariable pVar = NULL;
int iVal; int iVal, status;
float fVal; float fVal;
char *pText; char *pText;
@ -388,18 +389,21 @@
pVar = (pSicsVariable)pEvent; pVar = (pSicsVariable)pEvent;
pCon = (SConnection *)pUser; pCon = (SConnection *)pUser;
SCPushContext2(pCon,cc);
switch(pVar->eType) switch(pVar->eType)
{ {
case veInt: case veInt:
VarGetInt(pVar,&iVal); VarGetInt(pVar,&iVal);
sprintf(pBueffel,"%s = %d",pVar->name,iVal); sprintf(pBueffel,"%s = %d",pVar->name,iVal);
SCWrite(pCon,pBueffel,eValue); SCWrite(pCon,pBueffel,eValue);
return 1; status = 1;
break;
case veFloat: case veFloat:
VarGetFloat(pVar,&fVal); VarGetFloat(pVar,&fVal);
sprintf(pBueffel,"%s = %f",pVar->name,fVal); sprintf(pBueffel,"%s = %f",pVar->name,fVal);
SCWrite(pCon,pBueffel,eValue); SCWrite(pCon,pBueffel,eValue);
return 1; status = 1;
break;
case veText: case veText:
VarGetText(pVar,&pText); VarGetText(pVar,&pText);
sprintf(pBueffel,"%s = %s", pVar->name,pText); sprintf(pBueffel,"%s = %s", pVar->name,pText);
@ -408,9 +412,11 @@
{ {
free(pText); free(pText);
} }
return 1; status = 1;
break;
} }
return 1; SCPopContext(pCon);
return status;
} }
/*----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/
static int VarSetFromText(pSicsVariable self, SConnection *pCon, char *text) static int VarSetFromText(pSicsVariable self, SConnection *pCon, char *text)
@ -559,7 +565,8 @@ static int VarSetFromText(pSicsVariable self, SConnection *pCon, char *text)
} }
else if(strcmp(pCurrent->text,"interest") == 0) /* interest */ else if(strcmp(pCurrent->text,"interest") == 0) /* interest */
{ {
lID = RegisterCallback(pVar->pCall, VALUECHANGE, VarInterestCallback, lID = RegisterCallback(pVar->pCall, SCGetContext(pCon),
VALUECHANGE, VarInterestCallback,
pCon, NULL); pCon, NULL);
SCRegister(pCon,pInterp, pVar->pCall,lID); SCRegister(pCon,pInterp, pVar->pCall,lID);
DeleteTokenList(pList); DeleteTokenList(pList);

387
sinfo.tcl Normal file
View File

@ -0,0 +1,387 @@
# requires stooop package from tcllib
# loaded from sycamore.tcl
proc arga argStr {
set args [ split $argStr ]
set argc [llength $args]
# syc::debug "arga.argc = %s" $argc
set objName ""
set key ""
set name ""
set val ""
set bObj [expr $argc > 0]
set bKey [expr $argc > 1]
set bName [expr $argc > 2]
set bVal [expr $argc > 3]
if $bObj {
set objName [string tolower [lindex $args 0]]
#syc::debug "arga.objName = %s" $objName
}
if $bKey {
set key [string tolower [lindex $args 1]]
#syc::debug "arga.key = %s" $key
}
if $bName {
set name [string tolower [lindex $args 2]]
}
if $bVal {
set val [string tolower [lindex $args 3]]
}
# ? cannot get 'array set' to work in the form:
# array set argv {
# argc $argc
# objName $objName
# ... etcetera
# }
set argv(argc) $argc
set argv(bObj) $bObj
set argv(bKey) $bKey
set argv(bName) $bName
set argv(bVal) $bVal
set argv(objName) $objName
set argv(key) $key
set argv(name) $name
set argv(val) $val
# would like to return associative array
# for now, settle for list
# syc::debug "arga.argv = { %s }" [array get argv]
return [array get argv]
}
# -----------------------------------------------------------------------------
class sinfo { ;# base class definition
proc sinfo {this} { ;# base class constructor
# non-static data member initialisation
set ($this,objectID) $this
}
proc ~sinfo {this} {} ;# base class destructor
proc id {this} {
return [format "sin.objectID = \{ %s \}" $($this,objectID)]
}
# static data member variables
# set File default.dat
set delimiter ", "
set debug 0
set init 0
set name "sinfo"
set usage {sinfo init|diag|config|server|device|command [parameter]}
set version 0.6
class server {
proc server {this name} {
set ($this,name) $name
proc name {this} {
return [format "server.name = \{ %s \}" $($this,name)]
}
}
proc ~server {this} {}
}
class sinfot {
proc sinfot {this} {}
proc ~sinfot {this} {}
}
proc helpMsgStr args {
return [formatMsg $sinfo::name "usage" $sinfo::usage]
}
proc debug args {
if {$sinfo::debug < 1} {
return
}
set l [llength $args]
set dMsg "Script code event"
set dVal " "
if {$l > 0} {
set dMsg [lindex $args 0]
if {$l > 1} {
set dVal [lindex $args 1]
}
}
sinWrite [format "sinfo::debug: %s" [format $dMsg $dVal]] "value"
}
proc diag args {
set flag [lindex $args 0]
set msg [format "diag=%s" $flag]
switch $flag {
"on" {
set sinfo::debug 1
}
"off" {
set sinfo::debug 0
}
default {
if {1 == $sinfo::debug} {
set msg "diag=on"
} else {
set msg "diag=off"
}
}
}
return [format "sinfo.diag = \{ %s \}" $msg]
}
proc formatMsg {objName parName msg} {
# return [format "%s.%s = \{ %s \}" $objName $parName $msg]
# set msgStr [format "%s.%s = %s " $objName $parName $msg]
#sinWrite "DEBUG formatMsg: msg = $msg" "value"
return "$objName.$parName=$msg"
}
proc writeObjPar {objName parName} {
return [format "%s.%s = \{ %s \}" \
$objName $parName [set ::$objName::$parName]]
}
proc writeError {objName msg} {
# return [format "%s.error = \{ %s \}" $objName $msg]
set msg [format "%s.error = \{ %s \}" $objName $msg]
sinWrite $msg "error"
return $msg
}
proc writeNspPar {objName parName} {
set result ::
append result $objName :: $parName
# return [format "%s.%s = \{ %s \}" $objName $parName [set $result]]
sinWrite [format "%s" [set $result]] "value"
}
proc writeList {objName parName parList} {
# return [format "%s.%s = %s " $objName $parName \
# [join $parList $sinfo::delimiter]]
set msg [format "%s" [join $parList $sinfo::delimiter]]
sinWrite $msg "value"
#return $msg
}
proc writeNamespaceChildren {obj key nsp} {
set chList {}
set nameList {}
set chList [namespace children $nsp]
set l [llength $chList]
for {set i 0} {$i < $l} {incr i} {
lappend nameList [namespace tail [lindex $chList $i]]
}
writeList $obj $key $nameList
}
proc writeNamespaceList {obj key nsp} {
set nameList {}
foreach v [info vars ${nsp}::*] {
lappend nameList [namespace tail $v]
}
writeList $obj $key $nameList
}
}
proc sinfo::server args {
array set argv [arga $args]
debug "sinfo::server, server.argv = { %s }" [array get argv]
set parSet {}
set parNames {}
if {$argv(bKey)} {
set key $argv(key)
debug "sinfo::server, key = $key"
switch $key {
"connection" -
"experiment" -
"help" -
"key" -
"list"
{
debug "sinfo::server, in switch $key, sinfox list server $key"
set nameList [sinfox list server $key]
sinfo::writeList "server" $key $nameList
}
"command" -
"device" -
"devicetype" -
"group" -
"interface"
{
if {$argv(bName)} {
set name $argv(name)
debug "sinfo::server, using name $name"
#sinWrite [format "DEBUG: if bname, key = %s, name = %s" $key $name] "value"
set nameList [sinfox list server $key $name]
sinfo::writeList "server" $name $nameList
#todo: improve response for unknown name
# eg server.error={device=foo}
} else {
set nameList [sinfox list server $key]
debug "sinfo::server, key=$key, nameList = $nameList"
sinfo::writeList "server" $key $nameList
}
}
"gtdevice"
{
if {$argv(bName)} {
set name $argv(name)
if [info exists ::server::gtDeviceList::$name] {
sinfo::writeNspPar server::gtDeviceList $name
} else {
set msg [format "key=%s.%s" "server" $key]
return [sinfo::writeList "server" error $msg]
}
} else {
writeList "server" $key [gumtree::gtDeviceList]
# sinfo::writeNamespaceList "server" $key \
# [ ::server::gtDeviceList
}
}
default {
puts default
if [info exists ::server::$key] {
sinfo::writeNspPar server $key
} else {
set msg [format "key=%s.%s" "server" $key]
return [sinfo::writeList "server" error $msg]
}
}
}
} else {
# writeNamespaceList $objName
set nameList [sinfox list server list]
writeList "server" "list" $nameList
}
}
proc sinfo::checkType {objName} {
if { [string compare -nocase $objName server] == 0 } then {
set return "server"
} elseif { [string compare -nocase $objName sequencer] == 0 } then {
set return "sequencer"
} else {
switch [SICSType $objName] {
COUNT -
DRIV { return "device" }
COM { return "command" }
TEXT { return "object" }
default { return "unknown" }
}
}
}
proc sinfo::list args {
array set argv [arga $args]
debug "sinfo.argv = { %s }" [array get argv]
set argc [llength $args]
set objName $argv(objName)
set key $argv(key)
set name $argv(name)
sinfo::debug "sinfo.numargs = %s" $argc
if {$argc < 1} {
sinWrite [sinfo::helpMsgStr] "value"
return
}
sinfo::debug "object = %s" $argv(objName)
if $argv(bKey) {
sinfo::debug "key = %s" $argv(key)
}
if $argv(bName) {
sinfo::debug "name = %s" $argv(name)
}
set parList {}
set numPars 0
set objType [checkType $objName]
sinfo::debug "sinfo.objectType = %s" $objType
switch $objType {
device
{
set nameList [sinfox list $objName $key $name]
writeList $objName $key $nameList
}
command
{
debug "sinfo.message = { %s is command objectType}" $objName
}
server
{
set cmd [format "sinfo::server %s %s %s %s" \
$objName $key $argv(name) $argv(val)]
return [eval $cmd]
}
sequencer
{
debug "sinfo.message = { %s is sequencer objectType}" $objName
if {$argv(bKey)} {
set key $argv(key)
switch $key {
"command"
{
if $bName {
set target [format "::sequencer::%s" $name]
sinfo::writeNamespaceList $objName $name $target
} else {
sinfo::writeNamespaceChildren $objName \
$key ::sequencer
}
}
default
{
}
}
} else {
sinfo::writeNamespaceList "sequencer" "list" "::sequencer"
}
}
object
{
# todo: test for interface name
switch $objName {
default {
writeError "sinfo" \
[format "'%s' is invalid object" $objName]
}
}
}
unknown -
default {
writeError "sinfo" [format "'%s' has invalid object type" $objName]
}
}
}
# -----------------------------------------------------------------------------
# wrapper procs for sinfo class
proc sinfo args {
set l [llength $args]
if {$l < 1} {
sinWrite [sinfo::helpMsgStr] "value"
return
}
set arglist [ split $args ]
set objName [lindex $arglist 0]
set cmd [format "sinfo::%s $args" $objName]
#sinWrite "DEBUG: $cmd" "value"
# set cmd $args
#set cmd "sinfo::list $args"
#FIXME the command should provide the output code for sinWrite
#sinWrite [eval $cmd] "value"
eval $cmd
}
proc sin args {
set argc [llength $args]
if {$argc < 1} {
set msg \
"sin.usage = \
{ sin \[server|sequencer|device|command\] \[parameter\] }"
sinWrite $msg "value"
} else {
sinWrite [sinfo::list $args] "value"
}
}

1221
sinfox.c Normal file

File diff suppressed because it is too large Load Diff

115
sinfox.h Normal file
View File

@ -0,0 +1,115 @@
/*---------------------------------------------------------------------------
----------------------------------------------------------------------------*/
#ifndef ANSTO_SINFOX
#define ANSTO_SINFOX
#include <sics.h>
#include <conman.h>
typedef struct __Sinfox {
pObjectDescriptor pDes; /* required as first field */
const char *buildVersion;
const char *configName;
const char *configVersion;
const char *description;
const char *instrument;
const char *schemaVersion;
Tcl_Interp *tTcl;
} Sinfox;
typedef struct __Sinfox *pSinfox;
#ifndef SICSSITE /* Avoid duplicate declaration in site_ansto.c */
const int iNumInfoKeys = 6;
char *pInfoKeys[7] = {
"buildVersion",
"configName",
"configVersion",
"description",
"instrument",
"schemaVersion",
NULL
};
const int iNumCommandKeys = 3;
char *pCommandKeys[4] = {
"argument",
"device",
"interface",
NULL
};
const int iNumDeviceKeys = 3;
char *pDeviceKeys[4] = {
"attribute",
"command",
"interface",
NULL
};
const int iNumDeviceTypes = 24;
char *pDeviceTypes[25] = {
"4-circle-calculus",
"anticollider",
"chopper",
"chopperadaptor",
"connection",
"crystalselector",
"environment monitor",
"environment controller",
"gpib",
"hklscan",
"hmcontrol",
"lin2ang",
"local maximum detector",
"maximizer",
"mesure",
"motor",
"mulmot",
"omega2theta",
"rs232 controller",
"scanobject",
"sicsvariable",
"singlecounter",
"velocityselector",
"xytable",
NULL
};
const int iNumIFaces = 4;
char *pIFaces[5] = {
"callback",
"countable",
"drivable",
"environment",
NULL
};
const int iNumServerKeys = 10;
char *pServerKeys[11] = {
"help",
"list",
"command",
"connection",
"device",
"devicetype",
"experiment",
"group",
"interface",
"key",
NULL
};
#endif /* SICSSITE */
/*--------------------- lifecycle -------------------------------------- */
int InstallSinfox(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]);
void DeleteSinfox(void *pSelf);
/*--------------------- operations --------------------------------------*/
int SinfoxAction(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]);
/*-----------------------------------------------------------------------*/
#endif /* ANSTO_SINFOX */

View File

@ -181,7 +181,8 @@
return 1; return 1;
} }
/*------------------- The CallBack function for interest ------------------*/ /*------------------- The CallBack function for interest ------------------*/
static int StatusCallback(int iEvent, void *pEvent, void *pUser) static int StatusCallback(int iEvent, void *pEvent, void *pUser,
commandContext cc)
{ {
SConnection *pCon; SConnection *pCon;
char pBueffel[80]; char pBueffel[80];
@ -191,7 +192,9 @@
pCon = (SConnection *)pUser; pCon = (SConnection *)pUser;
sprintf(pBueffel,"status = %s", pText[(int)eCode]); sprintf(pBueffel,"status = %s", pText[(int)eCode]);
SCPushContext2(pCon,cc);
SCWrite(pCon,pBueffel,eWarning); SCWrite(pCon,pBueffel,eWarning);
SCPopContext(pCon);
return 1; return 1;
} }
@ -217,7 +220,8 @@
strtolower(argv[1]); strtolower(argv[1]);
if(strcmp(argv[1],"interest") == 0) if(strcmp(argv[1],"interest") == 0)
{ {
lID = RegisterCallback(pCall, VALUECHANGE, StatusCallback, lID = RegisterCallback(pCall, SCGetContext(pCon),
VALUECHANGE, StatusCallback,
pCon, NULL); pCon, NULL);
SCRegister(pCon,pSics, pCall,lID); SCRegister(pCon,pSics, pCall,lID);
SCSendOK(pCon); SCSendOK(pCon);

18
stptok.h Normal file
View File

@ -0,0 +1,18 @@
/*
** stptok() -- public domain by Ray Gardner, modified by Bob Stout
**
** You pass this function a string to parse, a buffer to receive the
** "token" that gets scanned, the length of the buffer, and a string of
** "break" characters that stop the scan. It will copy the string into
** the buffer up to any of the break characters, or until the buffer is
** full, and will always leave the buffer null-terminated. It will
** return a pointer to the first non-breaking character after the one
** that stopped the scan.
*/
#ifndef STPSTPTOK
#define STPSTPTOK
char *stptok(const char *s, char *tok, size_t toklen, char *brk);
#endif

91
sycFormat.tcl Normal file
View File

@ -0,0 +1,91 @@
#----------------------------------------------------------------------------
# Implements sycFormat which is needed by the sycamore protocol.
# Deobjectified version of the ANSTO original
#
# Original Implementor: Paul Hathaway, Ferdi Francescini
#
# More bugs introduced by: Mark Koennecke
#-------------------------------------------------------------------------
if { [info exists sycinit] == 0 } {
set sycinit 1
Publish sycformat Spy
}
array set statusMap [ list OKOK "ok" \
HWIdle "idle" \
HWBusy "running" \
HWFault "fault" \
HWPosFault "posfault" \
HWCrash "crash" \
NOMEMORY "nomemory" \
HWNoBeam "nobeam" \
HWPause "pause" \
HWWarn "warn" \
HWRedo "redo" ]
# 'tag' and 'msgString' parameters must be passed within braces
# eg sycFormat con0004 t000005 s1 event {s1} {type.position status.HWBusy}
proc sycformat {connID transID devID msgFlag tag msgString} {
global statusMap cache
set fullmatch ""; set msg ""; set eventType ""; set status ""
set position ""
proc _prefix {flag} {
upvar connID cID transID tID devID dID
return "\[$cID:$tID:$dID:$flag\]"
}
regexp {<(.*)>} $msgString match msg
regexp {type\.(\w*)} $msgString match eventType
regexp {status\.(\w*)} $msgString match status
# Skip useless messages
if {[string first "Parameter Listing for motor" $msgString] > -1} {
return ""
}
switch $msgFlag {
"start" {
set output "[_prefix start] $msgString"
}
"event" {
switch $eventType {
"POSITION" {
regexp {(\w+)\.position *= *(\d+(?:\.\d+)?)} $msgString match device position
set output "[_prefix event] $tag={type=$eventType,$devID.position=$position}"
}
default {
# Error
}
}
}
"out" {
# Concatenate multiple messages into a comma separated list
if [info exists cache($transID)] {
append msg ", " $msgString
eval "lappend cache($transID) $msg"
} else {
eval "lappend cache($transID) $msgString"
}
set output ""
}
"finish" {
if [info exists cache($transID)] {
set output "[_prefix out] $tag=\{$cache($transID)\}"
append output "\n[_prefix finish]"
unset cache($transID)
} else {
set output "[_prefix finish]"
}
}
default {
set output "[_prefix $msgFlag] $msgString"
}
}
return $output
}

219
sycamore.tcl Normal file
View File

@ -0,0 +1,219 @@
#source $sychome/stooop/mkpkgidx.tcl
#source stooop.tcl
#set tcl_pkgPath $sychome
# ClientPut $tcl_pkgPath "value"
# package require stooop 4 ;# load stooop package
# namespace forget stooop::* ;# remove if previously loaded
# namespace import stooop::*
# -----------------------------------------------------------------------------
# source $sychome/ns_site.tcl
# source $sychome/ns_sequencer.tcl
# source $sychome/ns_server.tcl
set STACKTRACE 0
proc stackTrace args {
set level [ info level ]
ClientPut "====================" "value"
for {set i 1} {$i < $level} {incr i} {
ClientPut [info level $i] "value"
ClientPut " " "value"
}
ClientPut "====================" "value"
}
# -----------------------------------------------------------------------------
# testing stubs when SICS modules not available
# proc sinfox args
# proc ClientPut {msg oCode}
# proc SICSType {objName}
# source stubs.tcl
# -----------------------------------------------------------------------------
# Sycamore Utilities: tcl procedures required by sycamore implementation
proc sinWrite {msg oCode} {
# simplest processing of format for now
global STACKTRACE
if {$STACKTRACE} {
stackTrace
}
ClientPut $msg $oCode
}
proc varexist {nsp var} {
return [expr [string compare $nsp$var [namespace which -variable $nsp$var]]==0]
}
#proc sycFormat {connID transID devID msgFlag args} {
# return "\[$connID:$transID:$devID:$msgFlag\] $args"
#}
#source $sychome/sycFormat.tcl
#publish sycFormat spy
proc arga argStr {
set args [ split $argStr ]
set argc [llength $args]
# syc::debug "arga.argc = %s" $argc
set objName ""
set key ""
set name ""
set val ""
set bObj [expr $argc > 0]
set bKey [expr $argc > 1]
set bName [expr $argc > 2]
set bVal [expr $argc > 3]
if $bObj {
set objName [string tolower [lindex $args 0]]
#syc::debug "arga.objName = %s" $objName
}
if $bKey {
set key [string tolower [lindex $args 1]]
#syc::debug "arga.key = %s" $key
}
if $bName {
set name [string tolower [lindex $args 2]]
}
if $bVal {
set val [string tolower [lindex $args 3]]
}
# ? cannot get 'array set' to work in the form:
# array set argv {
# argc $argc
# objName $objName
# ... etcetera
# }
set argv(argc) $argc
set argv(bObj) $bObj
set argv(bKey) $bKey
set argv(bName) $bName
set argv(bVal) $bVal
set argv(objName) $objName
set argv(key) $key
set argv(name) $name
set argv(val) $val
# would like to return associative array
# for now, settle for list
# syc::debug "arga.argv = { %s }" [array get argv]
return [array get argv]
}
# alternative solution for passing arguments around
#class argv {
# proc argv {this args} {
# set ($this,argc) [llength $args]
# set ($this,objName) ""
# set ($this,key) ""
# set ($this,name) ""
# set ($this,val) ""
# set ($this,bObj) [expr $l > 0]
# set ($this,bKey) [expr $l > 0]
# set ($this,bName) [expr $l > 1]
# set ($this,bVal) [expr $l > 2]
# if $($this,bObj) {
# set ($this,objName) [lindex $args 0]
# }
# if $($this,bKey) {
# set ($this,key) [lindex $args 0]
# }
# if $($this,bName) {
# set ($this,name) [lindex $args 1]
# }
# if $($this,bVal) {
# set ($this,val) [lindex $args 2]
# }
# }
# proc ~argv {this} {}
#}
#
## -----------------------------------------------------------------------------
# working idea for making diagnostic class global
class diagnostic {
proc diagnostic {this} {
set ($this,id) $this
set ($this,debug) 0
}
proc ~diagnostic {this} {}
proc diag {this flag} {
set msg [format "diag=%s" $flag]
switch $flag {
"on" {
set ($this,debug) 1
}
"off" {
set ($this,debug) 0
}
default {}
}
if {1 == ($this,debug)} {
set msg "diag=on"
} else {
set msg "diag=off"
}
return [format "%s.diag = \{ %s \}" $this $msg]
}
proc debug {this dMsg dVal} {
if {1 > ($this,debug)} {
return
}
sinWrite [format "%s::debug: %s" $this [format $dMsg $dVal]] "value"
}
}
## -----------------------------------------------------------------------------
# Class for module static variables and methods
class syc {
# class lifecycle methods
proc syc {this} {}
proc ~syc {this} {}
# static data members
set debug 0
# static methods
proc debug args {
if {$syc::debug < 1} {
return
}
set l [llength $args]
set dMsg "Script code event"
set dVal " "
if {$l > 0} {
set dMsg [lindex $args 0]
if {$l > 1} {
set dVal [lindex $args 1]
}
}
sinWrite [format "syc::debug: %s" [format $dMsg $dVal]] "value"
}
proc diag args {
set flag [lindex $args 0]
set msg [format "diag=%s" $flag]
switch $flag {
"on" {
set syc::debug 1
}
"off" {
set syc::debug 0
}
default {
if {1 == $syc::debug} {
set msg "diag=on"
} else {
set msg "diag=off"
}
}
}
return [format "syc.diag = \{ %s \}" $msg]
}
}
## -----------------------------------------------------------------------------
sinWrite "Loading sinfo" "value"
#source $sychome/sinfo.tcl
#publish sinfo spy
# source $sychome/sequencer.tcl

2
task.c
View File

@ -293,7 +293,7 @@ ente:
assert(self); assert(self);
assert(self->iID == TASKERID); assert(self->iID == TASKERID);
/* Cycle until back at our selves killed. */ /* Cycle until back at ourselves */
pEnd = self->pCurrent; pEnd = self->pCurrent;
pEnd->iStatus = WAITING; pEnd->iStatus = WAITING;
IncrTaskPointer(self); IncrTaskPointer(self);

2
task.h
View File

@ -106,7 +106,7 @@
int TaskYield(pTaskMan self); int TaskYield(pTaskMan self);
/* /*
does one cycle of the task loop and returns to the caller.This call allows does one cycle of the task loop and returns to the caller.This call allows
other tasks to execute while a task executeds a lengthy calculation. other tasks to execute while a task executes a lengthy calculation.
*/ */
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
int TaskSignal(pTaskMan self, int iSignal, void *pSigData); int TaskSignal(pTaskMan self, int iSignal, void *pSigData);

395
tclmotdriv.c Normal file
View File

@ -0,0 +1,395 @@
/*---------------------------------------------------------------------------
This is a motor driver which is implemented in Tcl. This means
this code is only a wrapper which calls Tcl functions to do the
actual work.
The Tcl functions to implement the interface are called with the name
of the motor as first parameter followed by any additional parameters
such as the position to run to for run. Functions have to return the proper
SICS return codes for a motor driver as integer numbers.
The Tcl function list is initialized from a Tcl-array which holds function
names for the entries:
- getpos
- run
- status
- geterror
- fixit
This Tcl-array is passed as parameter on creating the motor. In order to
facilitate error handling, a motor parameter errorcode is available to
store errors between invocations.
copyright: see file COPYRIGHT
Mark Koennecke, December 2005
--------------------------------------------------------------------------*/
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <time.h>
#include "sics.h"
#include "modriv.h"
#include "tclmotdriv.h"
#define FUNCNOTFOUND -11000
#define TCLERROR -11001
#define NOTCLRESULT -11002
/*----------------------------------------------------------------------------*/
static int buildStandardCommandPart(TCLDriv *pDriv, char *command,
char *tclCommand, int commandLen){
char tclFunc[132];
int status;
status = StringDictGet(pDriv->mappings,command,tclFunc,131);
if(status != 1) {
return 0;
}
snprintf(tclCommand,commandLen,"%s %s ", tclFunc, pDriv->motName);
return 1;
}
/*----------------------------------------------------------------------------*/
static int GetTclPos(void *self, float *fPos){
TCLDriv *pDriv;
char tclCommand[1024];
int status;
const char *result = NULL;
assert(self);
pDriv = (TCLDriv *)self;
pDriv->errorCode = 0;
if(!buildStandardCommandPart(pDriv,"getpos",tclCommand,1023)){
pDriv->errorCode = FUNCNOTFOUND;
return HWFault;
}
status = Tcl_Eval(pServ->pSics->pTcl,tclCommand);
result = Tcl_GetStringResult(pServ->pSics->pTcl);
if(result == NULL){
pDriv->errorCode = NOTCLRESULT;
return HWFault;
}
if(status != TCL_OK){
pDriv->errorCode = TCLERROR;
strncpy(pDriv->tclError,result,1023);
return HWFault;
}
sscanf(result,"%f",fPos);
return OKOK;
}
/*----------------------------------------------------------------------------*/
static int TclRun(void *self, float fVal) {
TCLDriv *pDriv;
char tclCommand[1024];
char num[80];
int status;
const char *result = NULL;
assert(self);
pDriv = (TCLDriv *)self;
pDriv->errorCode = 0;
if(!buildStandardCommandPart(pDriv,"run",tclCommand,1023)){
pDriv->errorCode = FUNCNOTFOUND;
return HWFault;
}
snprintf(num,79,"%f",fVal);
strncat(tclCommand,num,1023-strlen(tclCommand));
status = Tcl_Eval(pServ->pSics->pTcl,tclCommand);
result = Tcl_GetStringResult(pServ->pSics->pTcl);
if(result == NULL) {
pDriv->errorCode = NOTCLRESULT;
return HWFault;
}
if(status != TCL_OK){
pDriv->errorCode = TCLERROR;
strncpy(pDriv->tclError,result,1023);
return HWFault;
}
sscanf(result,"%d%",&status);
return status;
}
/*-------------------------------------------------------------------------*/
static int evaluateInternalErrors(TCLDriv *pDriv, int *iCode,
char *error, int iErrLen){
switch(pDriv->errorCode){
case FUNCNOTFOUND:
strncpy(error,"Config Error: Tcl function for driver not found",iErrLen);
*iCode = pDriv->errorCode;
return 1;
break;
case TCLERROR:
strncpy(error,pDriv->tclError,iErrLen);
*iCode = pDriv->errorCode;
return 1;
break;
case NOTCLRESULT:
strncpy(error,"Tcl function did not return result",iErrLen);
*iCode = pDriv->errorCode;
return 1;
break;
default:
return 0;
break;
}
return 0;
}
/*--------------------------------------------------------------------------*/
static void TclError(void *self, int *iCode, char *error, int iErrLen){
TCLDriv *pDriv;
char tclCommand[1024];
int status = 1;
const char *result = NULL;
assert(self);
pDriv = (TCLDriv *)self;
if(evaluateInternalErrors(pDriv,iCode,error,iErrLen) == 1) {
return;
}
if(!buildStandardCommandPart(pDriv,"geterror",tclCommand,1023)){
pDriv->errorCode = FUNCNOTFOUND;
status = 0;
}
if(status != 0){
status = Tcl_Eval(pServ->pSics->pTcl,tclCommand);
result = Tcl_GetStringResult(pServ->pSics->pTcl);
if(result == NULL) {
pDriv->errorCode = NOTCLRESULT;
}
if(status != TCL_OK && result != NULL){
pDriv->errorCode = TCLERROR;
strncpy(pDriv->tclError,result,1023);
}
}
if(evaluateInternalErrors(pDriv,iCode,error,iErrLen) == 1) {
return;
}
strncpy(error,result,iErrLen);
}
/*---------------------------------------------------------------------------*/
static int TclFix(void *self, int iError, float fNew){
TCLDriv *pDriv;
char tclCommand[1024];
char num[80];
int status;
const char *result = NULL;
assert(self);
pDriv = (TCLDriv *)self;
pDriv->errorCode = 0;
if(!buildStandardCommandPart(pDriv,"fixit",tclCommand,1023)){
pDriv->errorCode = FUNCNOTFOUND;
return HWFault;
}
snprintf(num,79,"%f",fNew);
strncat(tclCommand,num,1023-strlen(tclCommand));
status = Tcl_Eval(pServ->pSics->pTcl,tclCommand);
result = Tcl_GetStringResult(pServ->pSics->pTcl);
if(result == NULL) {
pDriv->errorCode = NOTCLRESULT;
return HWFault;
}
if(status != TCL_OK){
pDriv->errorCode = TCLERROR;
strncpy(pDriv->tclError,result,1023);
return HWFault;
}
sscanf(result,"%d%",&status);
return status;
}
/*--------------------------------------------------------------------------*/
static int TclHalt(void *self)
{
TCLDriv *pDriv;
char tclCommand[1024];
int status;
const char *result = NULL;
assert(self);
pDriv = (TCLDriv *)self;
pDriv->errorCode = 0;
if(!buildStandardCommandPart(pDriv,"halt",tclCommand,1023)){
pDriv->errorCode = FUNCNOTFOUND;
return HWFault;
}
status = Tcl_Eval(pServ->pSics->pTcl,tclCommand);
result = Tcl_GetStringResult(pServ->pSics->pTcl);
if(result == NULL){
pDriv->errorCode = NOTCLRESULT;
return HWFault;
}
if(status != TCL_OK){
pDriv->errorCode = TCLERROR;
strncpy(pDriv->tclError,result,1023);
return HWFault;
}
return OKOK;
}
/*--------------------------------------------------------------------------*/
static int TclStat(void *self)
{
TCLDriv *pDriv;
char tclCommand[1024];
int status;
const char *result = NULL;
assert(self);
pDriv = (TCLDriv *)self;
pDriv->errorCode = 0;
if(!buildStandardCommandPart(pDriv,"status",tclCommand,1023)){
pDriv->errorCode = FUNCNOTFOUND;
return HWFault;
}
status = Tcl_Eval(pServ->pSics->pTcl,tclCommand);
result = Tcl_GetStringResult(pServ->pSics->pTcl);
if(result == NULL){
pDriv->errorCode = NOTCLRESULT;
return HWFault;
}
if(status != TCL_OK){
pDriv->errorCode = TCLERROR;
strncpy(pDriv->tclError,result,1023);
return HWFault;
}
sscanf(result,"%d%",&status);
return status;
}
/*-----------------------------------------------------------------------*/
static int TclSetPar(void *self, SConnection *pCon, char *name, float newValue){
TCLDriv *pDriv = (TCLDriv *) self;
assert(self);
assert(pCon);
if(strcmp(name,"hardupperlim") == 0)
{
pDriv->fUpper = newValue;
return 1;
}
if(strcmp(name,"hardlowerlim") == 0)
{
pDriv->fLower = newValue;
return 1;
}
if(strcmp(name,"errorcode") == 0)
{
pDriv->errorCode = (int)newValue;
return 1;
}
return 0;
}
/*-----------------------------------------------------------------------*/
static int TclGetPar(void *self, char *name, float *value){
TCLDriv *pDriv = (TCLDriv *) self;
assert(self);
if(strcmp(name,"errorcode") == 0)
{
*value = (float)pDriv->errorCode;
return 1;
}
return 0;
}
/*---------------------------------------------------------------------------*/
void KillTCL(void *pData)
{
TCLDriv *pDriv = (TCLDriv *) pData;
if(pDriv != NULL){
DeleteStringDict(pDriv->mappings);
}
return;
}
/*-------------------------------------------------------------------------*/
static int assignMappings(TCLDriv *pDriv, SConnection *pCon, char *arrayName){
const char *funcName = NULL;
char *funcText[] = {"getpos",
"run",
"status",
"halt",
"geterror",
"fixit",
NULL};
char error[256];
int count = 0;
while(funcText[count] != NULL) {
funcName = Tcl_GetVar2(pServ->pSics->pTcl,arrayName,funcText[count],TCL_GLOBAL_ONLY);
if(funcName == NULL) {
snprintf(error,255,"ERROR: entry for %s not found in tcl-array %s",
funcText[count], arrayName);
SCWrite(pCon,error,eError);
return 0;
}
StringDictAddPair(pDriv->mappings,funcText[count],(char *)funcName);
count++;
}
return 1;
}
/*--------------------------------------------------------------------------*/
MotorDriver *CreateTclMotDriv(SConnection *pCon, int argc, char *argv[])
{
TCLDriv *pDriv = NULL;
assert(pCon);
if(argc < 4) {
SCWrite(pCon,"ERROR: not enough arguments to initilaize Tcl-driver",eError);
return NULL;
}
pDriv = (TCLDriv *)malloc(sizeof(TCLDriv));
if(!pDriv){
SCWrite(pCon,"Error allocating memory in TclMotor",eError);
return NULL;
}
memset(pDriv,0,sizeof(TCLDriv));
pDriv->mappings = CreateStringDict();
if(pDriv->mappings == NULL){
SCWrite(pCon,"Error allocating memory in TclMotor",eError);
free(pDriv);
return NULL;
}
if(assignMappings(pDriv,pCon,argv[3]) != 1){
DeleteStringDict(pDriv->mappings);
free(pDriv);
return NULL;
}
pDriv->name = strdup("Tcl-Driver");
strncpy(pDriv->motName, argv[1], 131);
pDriv->GetPosition = GetTclPos;
pDriv->RunTo = TclRun;
pDriv->GetStatus = TclStat;
pDriv->GetError = TclError;
pDriv->TryAndFixIt = TclFix;
pDriv->SetDriverPar = TclSetPar;
pDriv->GetDriverPar = TclGetPar;
pDriv->Halt = TclHalt;
pDriv->KillPrivate = KillTCL;
return (MotorDriver *)pDriv;
}

41
tclmotdriv.h Normal file
View File

@ -0,0 +1,41 @@
/*---------------------------------------------------------------------------
This is a motor driver which is implemented in Tcl. This means
this code is only a wrapper which calls Tcl functions to do the
actual work.
copyright: see file COPYRIGHT
Mark Koennecke, December 2005
--------------------------------------------------------------------------*/
#ifndef TCLMOTDRIV
#define TCLMOTDRIV
#include "stringdict.h"
typedef struct ___TclDriv {
/* general motor driver interface
fields. REQUIRED!
*/
float fUpper; /* upper limit */
float fLower; /* lower limit */
char *name;
int (*GetPosition)(void *self,float *fPos);
int (*RunTo)(void *self, float fNewVal);
int (*GetStatus)(void *self);
void (*GetError)(void *self, int *iCode, char *buffer, int iBufLen);
int (*TryAndFixIt)(void *self,int iError, float fNew);
int (*Halt)(void *self);
int (*GetDriverPar)(void *self, char *name,
float *value);
int (*SetDriverPar)(void *self,SConnection *pCon,
char *name, float newValue);
void (*ListDriverPar)(void *self, char *motorName,
SConnection *pCon);
void (*KillPrivate)(void *self);
/* Tcl specific fields */
pStringDict mappings;
int errorCode;
char tclError[1024];
char motName[132];
} TCLDriv;
#endif

193
velo.c
View File

@ -1,4 +1,4 @@
/*--------------------------------------------------------------------------- /*---------------------------------------------------------------------------
V E L O C I T Y S E L E C T O R V E L O C I T Y S E L E C T O R
The velocity selector module for SICS. For documentation see velo.w The velocity selector module for SICS. For documentation see velo.w
@ -116,6 +116,37 @@
/* Success ! */ /* Success ! */
return 1; return 1;
} }
/*-----------------------------------------------------------------------*/
static void VSListForbidden(pVelSel self, SConnection *pCon){
Tcl_DString message;
int status;
Verbot Alcatraz;
char pBueffel[256];
Tcl_DStringInit(&message);
/*
The first entry in the forbidden region thing is meant to
contain the overall range: skip it!
*/
status = LLDnodePtr2First(self->iForbidden);
LLDnodeDataTo(self->iForbidden,&Alcatraz);
if(status == 1){
snprintf(pBueffel,255,"%s.forbidden = {%f -inf", self->pName, Alcatraz.fMax);
Tcl_DStringAppend(&message,pBueffel,strlen(pBueffel));
}
/* now search the forbidden regions */
status = LLDnodePtr2Next(self->iForbidden);
while(status != 0){
LLDnodeDataTo(self->iForbidden,&Alcatraz);
snprintf(pBueffel,255,", %f - %f", Alcatraz.fMin, Alcatraz.fMax);
Tcl_DStringAppend(&message,pBueffel,strlen(pBueffel));
status = LLDnodePtr2Next(self->iForbidden);
}
Tcl_DStringAppend(&message,"}",1);
SCWrite(pCon,Tcl_DStringValue(&message),eValue);
Tcl_DStringFree(&message);
}
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
static long VSSetValue(void *pData,SConnection *pCon, float fVal) static long VSSetValue(void *pData,SConnection *pCon, float fVal)
{ {
@ -701,7 +732,7 @@
return 1; return 1;
} }
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
static pEVDriver MakeDummyVel(pVelSel pVel) pEVDriver MakeDummyVel(pVelSel pVel)
{ {
pEVDriver pNew = NULL; pEVDriver pNew = NULL;
pVelPrivate ich = NULL; pVelPrivate ich = NULL;
@ -869,51 +900,6 @@
EVRegisterController(FindEMON(pSics),pBueffel,pNew->pMonitor,pCon); EVRegisterController(FindEMON(pSics),pBueffel,pNew->pMonitor,pCon);
return iRet; return iRet;
} }
/*------------------------------------------------------------------------*/
static int TTFindNumber(Tcl_Interp *pTcl,char *pPtr, float *fVal)
{
int iRet;
char *pEnd;
char *pMark;
double dVal;
pEnd = pPtr + strlen(pPtr);
/* advance to first non blank or non = character */
while( (isspace(*pPtr)) || (*pPtr == '=') )
{
pPtr++;
if(pPtr >= pEnd)
{
return 0;
}
}
/* find end of string */
pMark = pPtr;
while( (!isspace(*pMark)))
{
pMark++;
if(pMark >= pEnd)
{
return 0;
}
}
/* replace pMark temporarily by \0 */
*pMark = '\0';
/* now read number from pPtr */
iRet = Tcl_GetDouble(pTcl,pPtr,&dVal);
if(iRet != TCL_OK)
{
return 0;
}
/* fix back and return */
*pMark = ' ';
*fVal = (float)dVal;
return 1;
}
/*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
typedef struct { typedef struct {
SConnection *pCon; SConnection *pCon;
@ -935,7 +921,8 @@
} }
} }
/*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
static int RotationInterest(int iEvent, void *pData, void *pUser) static int RotationInterest(int iEvent, void *pData, void *pUser,
commandContext cc)
{ {
CBData *pDat = NULL; CBData *pDat = NULL;
float *fVal = NULL; float *fVal = NULL;
@ -949,12 +936,12 @@
if(iEvent == ROTSTART) if(iEvent == ROTSTART)
{ {
sprintf(pBueffel,"%s Starting",pDat->pName); sprintf(pBueffel,"%s Starting",pDat->pName);
SCWrite(pDat->pCon,pBueffel,eWarning); SCWriteInContext(pDat->pCon,pBueffel,eWarning,cc);
} }
else if(iEvent == ROTMOVE) else if(iEvent == ROTMOVE)
{ {
sprintf(pBueffel,"%s.rpm = %f",pDat->pName, *fVal); sprintf(pBueffel,"%s.rpm = %f",pDat->pName, *fVal);
SCWrite(pDat->pCon,pBueffel,eWarning); SCWriteInContext(pDat->pCon,pBueffel,eWarning,cc);
} }
return 1; return 1;
} }
@ -980,10 +967,6 @@
assert(pCon); assert(pCon);
assert(pSics); assert(pSics);
/* convert to text for parsing */
Arg2Text(argc,argv,pCommand, 511);
strtolower(pCommand);
if(argc < 2) if(argc < 2)
{ {
sprintf(pBueffel,"ERROR: %s expects at least one parameter",argv[0]); sprintf(pBueffel,"ERROR: %s expects at least one parameter",argv[0]);
@ -1026,10 +1009,10 @@
} }
pCB->pCon = pCon; pCB->pCon = pCon;
pCB->pName = strdup(argv[0]); pCB->pName = strdup(argv[0]);
lID = RegisterCallback(self->pCall, ROTSTART, RotationInterest, lID = RegisterCallback(self->pCall, SCGetContext(pCon), ROTSTART, RotationInterest,
pCB, KillCB); pCB, KillCB);
SCRegister(pCon,pSics, self->pCall,lID); SCRegister(pCon,pSics, self->pCall,lID);
lID = RegisterCallback(self->pCall, ROTMOVE, RotationInterest, lID = RegisterCallback(self->pCall, SCGetContext(pCon), ROTMOVE, RotationInterest,
pCB, NULL); pCB, NULL);
SCRegister(pCon,pSics, self->pCall,lID); SCRegister(pCon,pSics, self->pCall,lID);
SCSendOK(pCon); SCSendOK(pCon);
@ -1082,6 +1065,13 @@
return 1; return 1;
} }
/* list forbidden regions */
if(strcmp(argv[1],"forbidden") == 0)
{
VSListForbidden(self,pCon);
return 1;
}
/* status, prints a status message */ /* status, prints a status message */
if(strcmp(argv[1],"status") == 0) if(strcmp(argv[1],"status") == 0)
{ {
@ -1133,6 +1123,30 @@
} }
} }
if(strcmp(argv[1],"rottolerance") == 0){
if(argc > 2){
/* set case */
iRet = Tcl_GetDouble(pSics->pTcl,argv[2],&dVal);
if(iRet != TCL_OK){
sprintf(pBueffel,"ERROR: %s not recognized as numeric value for fMax",
argv[2]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
if(!SCMatchRights(pCon,usUser)){
return 0;
}
self->pDriv->fTolerance = dVal;
SCSendOK(pCon);
return 1;
} else {
sprintf(pBueffel,"%s.rottolerance = %f",
argv[0],self->pDriv->fTolerance);
SCWrite(pCon,pBueffel,eError);
return 1;
}
}
/* initialise the tilt and rot to current values */ /* initialise the tilt and rot to current values */
iRet = VSGetRotation(self,&fRot); iRet = VSGetRotation(self,&fRot);
if(!iRet) if(!iRet)
@ -1143,61 +1157,50 @@
iRet = MotorGetSoftPosition(self->pTilt,pCon,&fTilt); iRet = MotorGetSoftPosition(self->pTilt,pCon,&fTilt);
if(!iRet) if(!iRet)
{ {
SCWrite(pCon,"ERROR: velocity selector operation aborted",eError); SCWrite(pCon,"ERROR: failed to read tilt angle",eError);
return 0; return 0;
} }
/* search for Tilt */ /* search for Tilt */
pPtr = strstr(pCommand,"tilt"); if(strcmp(argv[1],"tilt") == 0){
if(pPtr) /* analyse tilt */ if(argc > 2){
{ /* set case */
iRet = Tcl_GetDouble(pSics->pTcl,argv[2],&dVal);
if(iRet != TCL_OK){
sprintf(pBueffel,"ERROR: %s not recognized as numeric value for fMax",
argv[2]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
fTilt = dVal;
iDrive = 1; iDrive = 1;
iRet = TTFindNumber(pSics->pTcl,pPtr+strlen("tilt"),&fTilt); } else {
if(!iRet)
{
/* no new value, just print the current one */
MotorGetSoftPosition(self->pTilt,pCon,&fTilt);
sprintf(pBueffel,"%s tilt = %f",argv[0],fTilt); sprintf(pBueffel,"%s tilt = %f",argv[0],fTilt);
SCWrite(pCon,pBueffel,eError); SCWrite(pCon,pBueffel,eError);
return 0; return 1;
} }
} }
/* serch for rottolerance */
pPtr = strstr(pCommand,"rottolerance");
if(pPtr) /* analyse rottolerance */
{
iDrive = 1;
iRet = TTFindNumber(pSics->pTcl,pPtr+strlen("rottolerance"),&fTol);
if(!iRet)
{
sprintf(pBueffel,"%s.rottolerance = %f",
argv[0],self->pDriv->fTolerance);
SCWrite(pCon,pBueffel,eError);
return 1;
}
else
{
self->pDriv->fTolerance = fTol;
SCSendOK(pCon);
return 1;
}
}
/* same for rot */ /* same for rot */
pPtr = strstr(pCommand,"rot"); if(strcmp(argv[1],"rot") == 0){
if(pPtr) /* analyse tilt */ if(argc > 2){
{ /* set case */
iDrive = 1; iRet = Tcl_GetDouble(pSics->pTcl,argv[2],&dVal);
iRet = TTFindNumber(pSics->pTcl,pPtr+strlen("rot"),&fVal); if(iRet != TCL_OK){
if(!iRet) sprintf(pBueffel,"ERROR: %s not recognized as numeric value for fMax",
{ argv[2]);
sprintf(pBueffel,"%s rot = %f",argv[0],fRot);
SCWrite(pCon,pBueffel,eError); SCWrite(pCon,pBueffel,eError);
return 0; return 0;
} }
fRot = fVal; fRot = dVal;
iDrive = 1;
} else {
sprintf(pBueffel,"%s rot = %f",argv[0],fRot);
SCWrite(pCon,pBueffel,eError);
return 1;
}
} }
/* do drive if we really need to */ /* do drive if we really need to */

1
velo.h
View File

@ -46,7 +46,6 @@
#line 264 "velo.w" #line 264 "velo.w"
#line 164 "velo.w" #line 164 "velo.w"
int VSGetLossCurrent(pVelSel self, SConnection *pCon, float *fLoss); int VSGetLossCurrent(pVelSel self, SConnection *pCon, float *fLoss);

View File

@ -11,7 +11,7 @@ lappend auto_path /data/koenneck/bin/tcl
set INI(DefUser) Spy set INI(DefUser) Spy
set INI(DefPasswd) 007 set INI(DefPasswd) 007
set INI(ServerPort) 3006 set INI(ServerPort) 2911
set INI(InterruptPort) 2913 set INI(InterruptPort) 2913
set INI(box) localhost set INI(box) localhost
set INI(usPasswd) Rosy set INI(usPasswd) Rosy