- 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:
305
SCinter.c
305
SCinter.c
@ -2,8 +2,6 @@
|
||||
|
||||
Implementation file for the SICS-interpreter.
|
||||
|
||||
|
||||
|
||||
Mark Koennecke, November 1996
|
||||
|
||||
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
|
||||
Mark Koennecke, August 2001, modified SicsWriteStatus to write motor
|
||||
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 <stdlib.h>
|
||||
@ -61,6 +69,15 @@
|
||||
/* M.Z. */
|
||||
#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)
|
||||
@ -219,22 +236,11 @@
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
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;
|
||||
}
|
||||
}
|
||||
/*------------------------------------------------------------------------*/
|
||||
#define MAXLEN 256
|
||||
#define MAXCOM 50
|
||||
extern char *stptok(char *s, char *tok, unsigned int toklen, char *brk);
|
||||
extern char *SkipSpace(char *pPtr);
|
||||
/*-----------------------------------------------------------------------*/
|
||||
int InterpExecute(SicsInterp *self,SConnection *pCon, char *pText)
|
||||
{
|
||||
int iCount = 0;
|
||||
@ -275,6 +281,7 @@
|
||||
iRet = 1;
|
||||
goto deleteArgv;
|
||||
}
|
||||
|
||||
if(argv[0] == NULL)
|
||||
{
|
||||
SCWrite(pCon,"ERROR: failed to parse command",eError);
|
||||
@ -298,7 +305,13 @@
|
||||
self->eOut = eStatus;
|
||||
Tcl_ResetResult((Tcl_Interp *)self->pTcl);
|
||||
MacroPush(pCon);
|
||||
SCWrite(pCon, "", eStart);
|
||||
pCon->conStatus = 0;
|
||||
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();
|
||||
|
||||
deleteArgv:
|
||||
@ -519,6 +532,74 @@ static void printAll(SicsInterp *pSics, SConnection *pCon)
|
||||
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
|
||||
as specified bi the id given
|
||||
@ -625,9 +706,9 @@ static void printMatch(SicsInterp *pSics, SConnection *pCon, char *mask)
|
||||
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;
|
||||
Tcl_DString txt;
|
||||
@ -644,7 +725,7 @@ static void printType(SicsInterp *pSics, SConnection *pCon, char *type)
|
||||
{
|
||||
if(pCurrent->pData != NULL)
|
||||
{
|
||||
if(iHasType(pCurrent->pData,type))
|
||||
if(iHasType(pCurrent->pData,typeName))
|
||||
{
|
||||
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 argc, char *argv[])
|
||||
{
|
||||
char pType[256];
|
||||
int i;
|
||||
|
||||
if(argc < 2)
|
||||
{
|
||||
@ -701,6 +784,13 @@ static void printType(SicsInterp *pSics, SConnection *pCon, char *type)
|
||||
printType(pSics,pCon,"Motor");
|
||||
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]);
|
||||
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;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
@ -848,3 +965,149 @@ void *FindDrivable(SicsInterp *pSics, char *name){
|
||||
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;
|
||||
}
|
||||
|
@ -87,7 +87,6 @@ typedef struct __SINTER
|
||||
If the command is found, 1 is returned on success, 0 on failure in
|
||||
the command.
|
||||
----------------------------------------------------------------------------*/
|
||||
|
||||
CommandList *FindCommand(SicsInterp *pInterp, char *name);
|
||||
/*
|
||||
Searches the Interpreters pInterp command list for a command
|
||||
|
@ -46,6 +46,9 @@ typedef enum {
|
||||
eInError,
|
||||
eStatus,
|
||||
eValue,
|
||||
eStart,
|
||||
eFinish,
|
||||
eEvent,
|
||||
eWarning,
|
||||
eError
|
||||
} OutCode;
|
||||
|
12
callback.c
12
callback.c
@ -64,6 +64,7 @@
|
||||
void *pUserData;
|
||||
KillFuncIT pKill;
|
||||
int iEvent;
|
||||
commandContext comCon;
|
||||
} CallBackItem, *pCallBackItem;
|
||||
/*------------------------------------------------------------------------*/
|
||||
static int CheckPointer(pICallBack self)
|
||||
@ -140,7 +141,7 @@
|
||||
LLDnodeDataTo(self->iList,&sItem);
|
||||
if(sItem.iEvent == iEvent)
|
||||
{
|
||||
iRet = sItem.pFunc(iEvent, pEventData,sItem.pUserData);
|
||||
iRet = sItem.pFunc(iEvent, pEventData,sItem.pUserData,sItem.comCon);
|
||||
if(!iRet)
|
||||
{
|
||||
iResult = 0;
|
||||
@ -153,7 +154,7 @@
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static long lCount = 1L;
|
||||
|
||||
long RegisterCallback(pICallBack self, int iEvent,
|
||||
long RegisterCallback(pICallBack self, commandContext comCon, int iEvent,
|
||||
SICSCallBack pFunc,
|
||||
void *pUserData, KillFunc pKFunc)
|
||||
{
|
||||
@ -170,6 +171,7 @@
|
||||
sItem.iEvent = iEvent;
|
||||
sItem.pUserData = pUserData;
|
||||
sItem.pKill = pKFunc;
|
||||
sItem.comCon = comCon;
|
||||
|
||||
LLDnodeAppendFrom(self->iList,&sItem);
|
||||
return sItem.iID;
|
||||
@ -244,7 +246,8 @@ static int CallbackWrite(SConnection *pCon,char *message, int outCode)
|
||||
/*-----------------------------------------------------------------------
|
||||
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;
|
||||
Tcl_Interp *pTcl;
|
||||
@ -332,7 +335,8 @@ int CallbackScript(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
return 0;
|
||||
}
|
||||
Arg2Text(argc-4,&argv[4],pBuffer,131);
|
||||
lID = RegisterCallback(pCall,iEvent,ScriptCallback,
|
||||
lID = RegisterCallback(pCall,SCGetContext(pCon),
|
||||
iEvent,ScriptCallback,
|
||||
strdup(pBuffer),free);
|
||||
sprintf(pBuffer,"callback = %ld", lID);
|
||||
SCWrite(pCon,pBuffer,eValue);
|
||||
|
16
commandcontext.h
Normal file
16
commandcontext.h
Normal 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
|
@ -19,8 +19,12 @@
|
||||
|
||||
int ListObjects(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[]);
|
||||
|
||||
/*
|
||||
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
|
||||
|
128
conman.c
128
conman.c
@ -88,7 +88,6 @@ extern pServer pServ;
|
||||
|
||||
/*------------- a number for generating automatic names --------------------*/
|
||||
static int iName = 0;
|
||||
static int SCNormalWrite(SConnection *self, char *buffer, int iOut);
|
||||
static SConnection *freeConnections = NULL;
|
||||
static long lastIdent = 0;
|
||||
/*===========================================================================*/
|
||||
@ -183,6 +182,12 @@ extern pServer pServ;
|
||||
pRes->pFiles[i] = NULL;
|
||||
}
|
||||
|
||||
/* initialise context variables */
|
||||
pRes->iCmdCtr = 0;
|
||||
pRes->conEventType=-1;
|
||||
pRes->conStatus=-1;
|
||||
pRes->contextStack = LLDcreate(sizeof(commandContext));
|
||||
|
||||
/* install command */
|
||||
AddCommand(pSics, ConName(pRes->ident), ConSicsAction, NULL,pRes);
|
||||
return pRes;
|
||||
@ -436,8 +441,11 @@ extern pServer pServ;
|
||||
{
|
||||
DeleteCommandStack(pVictim->pStack);
|
||||
}
|
||||
|
||||
|
||||
pVictim->lMagic=0; /* make a write to a freed connection harmless */
|
||||
/* finally free pVictim*/
|
||||
LLDdelete(pVictim->contextStack);
|
||||
FreeConnection(pVictim);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
@ -531,6 +539,15 @@ extern pServer pServ;
|
||||
}
|
||||
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, ...)
|
||||
{
|
||||
@ -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;
|
||||
char pBueffel[80];
|
||||
@ -686,7 +703,7 @@ static void writeToLogFiles(SConnection *self, char *buffer)
|
||||
return 1;
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static int SCWriteWithOutcode(SConnection *self, char *buffer, int iOut)
|
||||
int SCWriteWithOutcode(SConnection *self, char *buffer, int iOut)
|
||||
{
|
||||
int i, iPtr, iRet, length;
|
||||
char pBueffel[80];
|
||||
@ -1343,7 +1360,14 @@ static void writeToLogFiles(SConnection *self, char *buffer)
|
||||
self->inUse++;
|
||||
self->eInterrupt = eContinue;
|
||||
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);
|
||||
SCPopContext(self);
|
||||
if(self->parameterChange == 1)
|
||||
{
|
||||
/*
|
||||
@ -1658,7 +1682,8 @@ static void writeToLogFiles(SConnection *self, char *buffer)
|
||||
The callback function for connection callbacks. Invokes command
|
||||
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;
|
||||
|
||||
@ -1667,7 +1692,9 @@ static void writeToLogFiles(SConnection *self, char *buffer)
|
||||
|
||||
if(self->pAction)
|
||||
{
|
||||
SCPushContext2(self->pCon,cc);
|
||||
InterpExecute(pServ->pSics,self->pCon,self->pAction);
|
||||
SCPopContext(self->pCon);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@ -1755,7 +1782,7 @@ static void writeToLogFiles(SConnection *self, char *buffer)
|
||||
pCB->pSics = pSics;
|
||||
pCB->pAction = strdup(pBueffel);
|
||||
sItem.pInterface = pInterface;
|
||||
sItem.lID = RegisterCallback(pInterface, iEvent, ConCallBack,
|
||||
sItem.lID = RegisterCallback(pInterface, SCGetContext(pCB->pCon), iEvent, ConCallBack,
|
||||
pCB, CBKill);
|
||||
LLDnodeAppendFrom(self->iList,&sItem);
|
||||
SCSendOK(pCon);
|
||||
@ -1961,6 +1988,48 @@ SConnection *SCLoad(SCStore *con) {
|
||||
}
|
||||
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) {
|
||||
SConnection *next;
|
||||
@ -1970,3 +2039,52 @@ void KillFreeConnections(void) {
|
||||
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;
|
||||
}
|
||||
|
26
conman.h
26
conman.h
@ -23,6 +23,7 @@
|
||||
#include "SCinter.h"
|
||||
#include "network.h"
|
||||
#include "obdes.h"
|
||||
#include "commandcontext.h"
|
||||
|
||||
#define MAXLOGFILES 10
|
||||
|
||||
@ -59,6 +60,16 @@ typedef int (*writeFunc)(struct __SConnection *pCon,
|
||||
int parameterChange;
|
||||
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 */
|
||||
pCosta pStack;
|
||||
|
||||
@ -103,6 +114,8 @@ typedef int (*writeFunc)(struct __SConnection *pCon,
|
||||
int SCOnlySockWrite(SConnection *self, char *buffer, int iOut);
|
||||
int SCFileWrite(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 *********************************** */
|
||||
int SCRegister(SConnection *pCon, SicsInterp *pSics,
|
||||
void *pInter, long lID);
|
||||
@ -158,4 +171,17 @@ SConnection *SCLoad(SCStore *con);
|
||||
|
||||
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
|
||||
|
||||
|
@ -708,7 +708,8 @@
|
||||
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;
|
||||
pMonEvent pMon = NULL;
|
||||
@ -731,7 +732,7 @@
|
||||
*/
|
||||
rights = SCGetRights(pCon);
|
||||
SCSetRights(pCon,usSpy);
|
||||
SCWrite(pCon,pBueffel,eWarning);
|
||||
SCWriteInContext(pCon,pBueffel,eWarning,cc);
|
||||
SCSetRights(pCon,rights);
|
||||
return 1;
|
||||
}
|
||||
@ -896,7 +897,7 @@
|
||||
SCWrite(pCon,pBueffel,eValue);
|
||||
return 1;
|
||||
case 9: /* interest */
|
||||
lID = RegisterCallback(self->pCall, MONITOR, CounterInterest,
|
||||
lID = RegisterCallback(self->pCall, SCGetContext(pCon), MONITOR, CounterInterest,
|
||||
pCon, NULL);
|
||||
SCRegister(pCon,pSics, self->pCall,lID);
|
||||
SCSendOK(pCon);
|
||||
|
8
danu.c
8
danu.c
@ -95,7 +95,8 @@ static int writeDataNumber(pDataNumber self, int iNum)
|
||||
return 1;
|
||||
}
|
||||
/*------------------- 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;
|
||||
SConnection *pCon = NULL;
|
||||
@ -120,7 +121,7 @@ static int writeDataNumber(pDataNumber self, int iNum)
|
||||
if(iNum > 0)
|
||||
{
|
||||
snprintf(pBueffel,131,"sicsdatanumber = %d", iNum);
|
||||
SCWrite(pCon,pBueffel,eValue);
|
||||
SCWriteInContext(pCon,pBueffel,eValue,cc);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@ -330,7 +331,8 @@ int NewThousand(pDataNumber self)
|
||||
}
|
||||
if(strcmp(argv[1],"interest") == 0)
|
||||
{
|
||||
lID = RegisterCallback(self->pCall, VALUECHANGE, InterestCallback,
|
||||
lID = RegisterCallback(self->pCall, SCGetContext(pCon),
|
||||
VALUECHANGE, InterestCallback,
|
||||
pCon, NULL);
|
||||
SCRegister(pCon,pSics, self->pCall,lID);
|
||||
SCSendOK(pCon);
|
||||
|
58
devexec.c
58
devexec.c
@ -62,6 +62,7 @@
|
||||
pObjectDescriptor pDescriptor;
|
||||
float fVal;
|
||||
char *name;
|
||||
commandContext comCon;
|
||||
} DevEntry, *pDevEntry;
|
||||
/*-------------------------------------------------------------------------*/
|
||||
static pDevEntry CreateDevEntry(pObjectDescriptor pDes, void *pData,
|
||||
@ -80,6 +81,7 @@
|
||||
pNew->pData = pData;
|
||||
pNew->name = strdup(name);
|
||||
pNew->fVal = fVal;
|
||||
memset(&pNew->comCon,0,sizeof(commandContext));
|
||||
return pNew;
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
@ -228,6 +230,8 @@
|
||||
SCWrite(pCon,"ERROR: memory exhausted in Device Executor ",eError);
|
||||
return 0;
|
||||
}
|
||||
pNew->comCon = SCGetContext(pCon);
|
||||
strncpy(pNew->comCon.deviceID,name,SCDEVIDLEN);
|
||||
|
||||
/* start it */
|
||||
pDrivInt = pDes->GetInterface(pData,DRIVEID);
|
||||
@ -250,7 +254,12 @@
|
||||
if(iRet == OKOK)
|
||||
{
|
||||
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->iStatus = DEVDONE;
|
||||
/* if no task: start it */
|
||||
@ -263,6 +272,7 @@
|
||||
self,
|
||||
1);
|
||||
self->iEnd = 0;
|
||||
pCon->conStatus = HWBusy;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@ -373,6 +383,9 @@
|
||||
pIDrivable pDrivInt = NULL;
|
||||
int eCode;
|
||||
int isCounting=0, isDriving=0;
|
||||
char pBueffel[512];
|
||||
SConnection *pCon;
|
||||
pCon = self->pOwner;
|
||||
|
||||
assert(self);
|
||||
|
||||
@ -397,6 +410,11 @@
|
||||
LLDnodeDataTo(self->iList,&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);
|
||||
pCountInt = pDev->pDescriptor->GetInterface(pDev->pData,COUNTID);
|
||||
|
||||
@ -423,10 +441,12 @@
|
||||
ExeInterest(self, pDev, "finished");
|
||||
DeleteDevEntry(pDev);
|
||||
LLDnodeDelete(self->iList);
|
||||
SCWrite(pCon, "", eFinish);
|
||||
iRet = LLDnodePtr2Prev(self->iList);
|
||||
if(SCGetInterrupt(self->pOwner) != eContinue)
|
||||
{
|
||||
self->iStatus = DEVINT;
|
||||
SCPopContext(self->pOwner);
|
||||
return -1;
|
||||
}
|
||||
self->iStatus = DEVDONE;
|
||||
@ -435,6 +455,7 @@
|
||||
ExeInterest(self, pDev, "finished with problem");
|
||||
DeleteDevEntry(pDev);
|
||||
pDev = NULL;
|
||||
SCWrite(pCon, "", eFinish);
|
||||
LLDnodeDataTo(self->iList,&pDev);
|
||||
LLDnodeDelete(self->iList);
|
||||
iRet = LLDnodePtr2Prev(self->iList);
|
||||
@ -446,6 +467,7 @@
|
||||
if(SCGetInterrupt(self->pOwner) != eContinue)
|
||||
{
|
||||
self->iStatus = DEVINT;
|
||||
SCPopContext(self->pOwner);
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
@ -455,6 +477,7 @@
|
||||
{
|
||||
SetStatus(eEager);
|
||||
self->iStatus = DEVINT;
|
||||
SCPopContext(self->pOwner);
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
@ -464,6 +487,7 @@
|
||||
{
|
||||
ContinueExecution(self);
|
||||
self->iStatus = DEVINT;
|
||||
SCPopContext(self->pOwner);
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
@ -482,6 +506,7 @@
|
||||
ExeInterest(self, pDev, "finished with problem");
|
||||
DeleteDevEntry(pDev);
|
||||
LLDnodeDelete(self->iList);
|
||||
SCWrite(pCon, "", eFinish);
|
||||
self->iStatus = DEVERROR;
|
||||
if(pDrivInt)
|
||||
{
|
||||
@ -490,10 +515,12 @@
|
||||
if(SCGetInterrupt(self->pOwner) != eContinue)
|
||||
{
|
||||
self->iStatus = DEVINT;
|
||||
SCPopContext(self->pOwner);
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
SCPopContext(self->pOwner);
|
||||
}
|
||||
iRet = LLDnodePtr2Next(self->iList);
|
||||
}
|
||||
@ -641,7 +668,9 @@
|
||||
}
|
||||
iRet = LLDnodePtr2Next(self->iList);
|
||||
}
|
||||
SCPushContext(self->pOwner,0,"system");
|
||||
SCWrite(self->pOwner,"ERROR: Full Stop called!!",eError);
|
||||
SCPopContext(self->pOwner);
|
||||
if(SCGetInterrupt(self->pOwner) > eContinue)
|
||||
{
|
||||
self->iStatus = DEVINT;
|
||||
@ -666,7 +695,7 @@
|
||||
}
|
||||
else if(pCountInt)
|
||||
{
|
||||
pDrivInt->Halt(pDev->pData);
|
||||
pCountInt->Halt(pDev->pData);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@ -699,6 +728,8 @@
|
||||
pDev = (pDevEntry)LLDnodePtr(self->iList);
|
||||
if(pDev)
|
||||
{
|
||||
SCPushContext(self->pOwner, pDev->comCon.transID, pDev->comCon.deviceID);
|
||||
|
||||
pCountInt = pDev->pDescriptor->GetInterface(pDev->pData,COUNTID);
|
||||
if(pCountInt)
|
||||
{
|
||||
@ -710,6 +741,7 @@
|
||||
}
|
||||
|
||||
}
|
||||
SCPopContext(self->pOwner);
|
||||
iRet = LLDnodePtr2Next(self->iList);
|
||||
}
|
||||
SetStatus(ePaused);
|
||||
@ -735,7 +767,6 @@
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
iRet = LLDnodePtr2Next(self->iList);
|
||||
}
|
||||
@ -760,11 +791,13 @@
|
||||
pCountInt = pDev->pDescriptor->GetInterface(pDev->pData,COUNTID);
|
||||
if(pCountInt)
|
||||
{
|
||||
SCPushContext(self->pOwner, pDev->comCon.transID, pDev->comCon.deviceID);
|
||||
iRet = pCountInt->Continue(pDev->pData,self->pOwner);
|
||||
if(!iRet)
|
||||
{
|
||||
iRes = 0;
|
||||
}
|
||||
SCPopContext(self->pOwner);
|
||||
}
|
||||
|
||||
}
|
||||
@ -842,12 +875,15 @@
|
||||
return iRet;
|
||||
}
|
||||
/*------------------- 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(text);
|
||||
|
||||
SCPushContext2(pCon,cc);
|
||||
SCWrite(pCon, text, eValue);
|
||||
SCPopContext(pCon);
|
||||
return 1;
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@ -866,7 +902,8 @@
|
||||
if (argc == 2) {
|
||||
if (strcmp(argv[1], "interest") == 0)
|
||||
{
|
||||
list = RegisterCallback(self->pCall, DRIVSTAT, DrivStatCallback,
|
||||
list = RegisterCallback(self->pCall, SCGetContext(pCon),
|
||||
DRIVSTAT, DrivStatCallback,
|
||||
pCon, NULL);
|
||||
SCRegister(pCon, pSics, self->pCall,list);
|
||||
SCSendOK(pCon);
|
||||
@ -1025,15 +1062,6 @@
|
||||
{
|
||||
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");
|
||||
}
|
||||
#ifdef DEBUG
|
||||
@ -1077,10 +1105,12 @@
|
||||
{
|
||||
if(self->pOwner)
|
||||
{
|
||||
SCPushContext(self->pOwner,0,"system");
|
||||
SCWrite(self->pOwner,
|
||||
"ERROR: Interrupting Current Hardware Operation",
|
||||
eError);
|
||||
SCSetInterrupt(self->pOwner,*iInt);
|
||||
SCPopContext(self->pOwner);
|
||||
}
|
||||
StopExe(self,"all");
|
||||
}
|
||||
|
@ -51,6 +51,8 @@ is set, without the current value is printed.
|
||||
<DT> nvs loss
|
||||
<DD> Starts a loss current measurement on the velocity selector and prints the
|
||||
result.
|
||||
<DT>nvs forbidden
|
||||
<DD>Prints a list of forbidden speed regions for this selector.
|
||||
<DT>nvs status
|
||||
<DD>Prints a status summary of the velocity selector.
|
||||
</DL>
|
||||
|
@ -173,6 +173,16 @@
|
||||
eError);
|
||||
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)
|
||||
{
|
||||
@ -191,6 +201,7 @@
|
||||
/* go to idle when stopped */
|
||||
if(self->iStop)
|
||||
{
|
||||
notifyStatus(self, pCon, HWIdle);
|
||||
return HWIdle;
|
||||
}
|
||||
|
||||
@ -209,16 +220,19 @@
|
||||
case DEVFAULT:
|
||||
sprintf(pBueffel,"ERROR: %s",pError);
|
||||
SCWrite(pCon,pBueffel,eError);
|
||||
notifyStatus(self, pCon, HWFault);
|
||||
return HWFault;
|
||||
case DEVREDO:
|
||||
sprintf(pBueffel,"WARNING: Fixing problem %s",pError);
|
||||
SCWrite(pCon,pBueffel,eWarning);
|
||||
notifyStatus(self, pCon, HWBusy);
|
||||
return HWBusy;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(iRet == -1 ) /* pending */
|
||||
{
|
||||
notifyStatus(self, pCon, HWBusy);
|
||||
return HWBusy;
|
||||
}
|
||||
|
||||
@ -228,6 +242,7 @@
|
||||
self->pName);
|
||||
SCWrite(pCon,pBueffel,eError);
|
||||
self->eMode = EVIdle;
|
||||
notifyStatus(self, pCon, HWFault);
|
||||
return HWFault;
|
||||
}
|
||||
|
||||
@ -254,6 +269,7 @@
|
||||
self->pName);
|
||||
SCWrite(pCon,pBueffel,eError);
|
||||
self->eMode = EVMonitor;
|
||||
notifyStatus(self, pCon, HWIdle);
|
||||
return HWIdle;
|
||||
}
|
||||
tol = ObVal(self->pParam, TOLERANCE);
|
||||
@ -272,13 +288,16 @@
|
||||
self->pName, (self->lastt + tmo - now)*1.0);
|
||||
SCWrite(pCon,pBueffel,eStatus);
|
||||
}
|
||||
notifyStatus(self, pCon, HWBusy);
|
||||
return HWBusy;
|
||||
}
|
||||
if (now > self->lastt + tmo)
|
||||
{
|
||||
self->eMode = EVMonitor;
|
||||
notifyStatus(self, pCon, HWIdle);
|
||||
return HWIdle;
|
||||
}
|
||||
notifyStatus(self, pCon, HWBusy);
|
||||
return HWBusy;
|
||||
}
|
||||
else
|
||||
@ -289,6 +308,7 @@
|
||||
SCWrite(pCon,pBueffel,eStatus);
|
||||
self->lastt -= now;
|
||||
}
|
||||
notifyStatus(self, pCon, HWBusy);
|
||||
return HWBusy;
|
||||
}
|
||||
}
|
||||
@ -1009,7 +1029,8 @@ static void ErrReport(pEVControl self)
|
||||
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;
|
||||
SConnection *pCon = (SConnection *)pUserData;
|
||||
@ -1017,7 +1038,8 @@ static void ErrReport(pEVControl self)
|
||||
|
||||
if(iEvent == VALUECHANGE)
|
||||
{
|
||||
SCWrite(pCon,pBuf,eValue);
|
||||
pCon->conEventType=POSITION;
|
||||
SCWriteInContext(pCon,pBuf,eEvent,cc);
|
||||
return 1;
|
||||
}
|
||||
return 1;
|
||||
@ -1075,7 +1097,8 @@ static void ErrReport(pEVControl self)
|
||||
/* install automatic notification */
|
||||
else if(strcmp(argv[1],"interest") == 0)
|
||||
{
|
||||
lID = RegisterCallback(self->pCall, VALUECHANGE, EVCallBack,
|
||||
lID = RegisterCallback(self->pCall, SCGetContext(pCon),
|
||||
VALUECHANGE, EVCallBack,
|
||||
pCon, NULL);
|
||||
SCRegister(pCon,pSics, self->pCall,lID);
|
||||
SCSendOK(pCon);
|
||||
@ -1414,13 +1437,14 @@ int RemoveEVController(SConnection *pCon, char *name) {
|
||||
SCWrite(pCon,"ERROR: cannot delete while running",eError);
|
||||
return 0;
|
||||
}
|
||||
if (!FindCommandData(pServ->pSics, name, "Environment Controller")) {
|
||||
SCPrintf(pCon,eError,"ERROR: no environment controller %s found",name);
|
||||
EVUnregister(FindEMON(pServ->pSics),name);
|
||||
iRet = RemoveCommand(pServ->pSics,name);
|
||||
if(!iRet)
|
||||
{
|
||||
sprintf(pBueffel,"ERROR: %s not found, NOT deleted",name);
|
||||
SCWrite(pCon,pBueffel,eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
EVUnregister(FindEMON(pServ->pSics),name);
|
||||
RemoveCommand(pServ->pSics,name);
|
||||
return 1;
|
||||
}
|
||||
/*-------------------------------------------------------------------------
|
||||
|
3
event.h
3
event.h
@ -42,7 +42,8 @@
|
||||
#define BATCHAREA 15
|
||||
#define BATCHEND 16
|
||||
#define DRIVSTAT 17
|
||||
|
||||
#define STATUS 18
|
||||
#define POSITION 19 /* Position event for motors - ffr */
|
||||
#line 104 "event.w"
|
||||
|
||||
|
||||
|
18
exeman.c
18
exeman.c
@ -284,25 +284,27 @@ static pExeInfo makeExeInfo(SConnection *pCon, pExeMan self){
|
||||
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;
|
||||
char *name = (char *)pEvent;
|
||||
char pBueffel[132];
|
||||
|
||||
if(iEvent == BATCHSTART){
|
||||
snprintf(pBueffel,131,"BATCHSTART=%s",name);
|
||||
SCWrite(self->pCon,pBueffel,eWarning);
|
||||
SCWriteInContext(self->pCon,pBueffel,eWarning,cc);
|
||||
return 1;
|
||||
}
|
||||
if(iEvent == BATCHEND){
|
||||
snprintf(pBueffel,131,"BATCHEND=%s",name);
|
||||
SCWrite(self->pCon,pBueffel,eWarning);
|
||||
SCWriteInContext(self->pCon,pBueffel,eWarning,cc);
|
||||
return 1;
|
||||
}
|
||||
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;
|
||||
char pBueffel[256];
|
||||
int start, end, lineno;
|
||||
@ -317,7 +319,7 @@ static int LineCallBack(int iEvent, void *pEvent, void *pUser){
|
||||
exeBufRange(buf,&start,&end,&lineno);
|
||||
snprintf(pBueffel,255,"%s.range = %d = %d",exeBufName(buf),
|
||||
start,end);
|
||||
SCWrite(self->pCon,pBueffel,eWarning);
|
||||
SCWriteInContext(self->pCon,pBueffel,eWarning,cc);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
@ -332,13 +334,13 @@ static void registerCallbacks(SConnection *pCon, SicsInterp *pSics,
|
||||
if(info == NULL){
|
||||
return;
|
||||
}
|
||||
lID = RegisterCallback(self->pCall, BATCHSTART, BufferCallback,
|
||||
lID = RegisterCallback(self->pCall, SCGetContext(pCon),BATCHSTART, BufferCallback,
|
||||
info, killExeInfo);
|
||||
SCRegister(pCon,pSics, self->pCall,lID);
|
||||
lID = RegisterCallback(self->pCall, BATCHEND, BufferCallback,
|
||||
lID = RegisterCallback(self->pCall, SCGetContext(pCon),BATCHEND, BufferCallback,
|
||||
info, NULL);
|
||||
SCRegister(pCon,pSics, self->pCall,lID);
|
||||
lID = RegisterCallback(self->pCall, BATCHAREA, LineCallBack,
|
||||
lID = RegisterCallback(self->pCall, SCGetContext(pCon),BATCHAREA, LineCallBack,
|
||||
info, NULL);
|
||||
SCRegister(pCon,pSics, self->pCall,lID);
|
||||
}
|
||||
|
53
fourlib.c
53
fourlib.c
@ -450,6 +450,59 @@ double sign(double a, double b){
|
||||
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,
|
||||
double *omeganb, double *gamma, double *nu){
|
||||
|
@ -122,6 +122,10 @@ void z1FromAngles(double lambda, double stt, double om,
|
||||
*/
|
||||
int bisToNormalBeam(double twotheta, double omega, double chi, double phi,
|
||||
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.
|
||||
|
104
histmem.c
104
histmem.c
@ -439,6 +439,7 @@
|
||||
free(pNew);
|
||||
return NULL;
|
||||
}
|
||||
StringDictAddPair(pNew->pOption,"driver",driver);
|
||||
StringDictAddPair(pNew->pOption,"update","0");
|
||||
|
||||
/* initialise driver */
|
||||
@ -532,6 +533,8 @@
|
||||
return 0;
|
||||
}
|
||||
|
||||
StringDictAddPair(pNew->pOption,"name",argv[1]);
|
||||
|
||||
/* install HM as command */
|
||||
iRet = AddCommand(pSics,argv[1],HistAction,DeleteHistMemory,(void *)pNew);
|
||||
if(!iRet)
|
||||
@ -918,7 +921,8 @@ void HistDirty(pHistMem self)
|
||||
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;
|
||||
char pBueffel[512];
|
||||
@ -927,14 +931,14 @@ void HistDirty(pHistMem self)
|
||||
{
|
||||
pCon = (SConnection *)pUser;
|
||||
assert(pCon);
|
||||
SCWrite(pCon,"HMCOUNTSTART",eWarning);
|
||||
SCWriteInContext(pCon,"HMCOUNTSTART",eWarning,cc);
|
||||
return 1;
|
||||
}
|
||||
else if(iEvent == COUNTEND)
|
||||
{
|
||||
pCon = (SConnection *)pUser;
|
||||
assert(pCon);
|
||||
SCWrite(pCon,"HMCOUNTEND",eWarning);
|
||||
SCWriteInContext(pCon,"HMCOUNTEND",eWarning,cc);
|
||||
return 1;
|
||||
}
|
||||
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 argc, char *argv[])
|
||||
@ -998,10 +1085,12 @@ static int checkHMEnd(pHistMem self, char *text){
|
||||
strtolower(argv[1]);
|
||||
if(strcmp(argv[1],"interest") == 0)
|
||||
{
|
||||
lID = RegisterCallback(self->pCall, COUNTSTART, HMCountInterest,
|
||||
lID = RegisterCallback(self->pCall, SCGetContext(pCon),
|
||||
COUNTSTART, HMCountInterest,
|
||||
pCon, NULL);
|
||||
SCRegister(pCon,pSics, self->pCall,lID);
|
||||
lID = RegisterCallback(self->pCall, COUNTEND, HMCountInterest,
|
||||
lID = RegisterCallback(self->pCall, SCGetContext(pCon),
|
||||
COUNTEND, HMCountInterest,
|
||||
pCon, NULL);
|
||||
SCRegister(pCon,pSics, self->pCall,lID);
|
||||
SCSendOK(pCon);
|
||||
@ -1165,6 +1254,11 @@ static int checkHMEnd(pHistMem self, char *text){
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if(strcmp(argv[1],"list") == 0)
|
||||
{
|
||||
HMListOption(self,pCon);
|
||||
return 1;
|
||||
}
|
||||
/* normal counting*/
|
||||
else if(strcmp(argv[1],"count") == 0)
|
||||
{
|
||||
|
35
hkl.c
35
hkl.c
@ -205,7 +205,8 @@
|
||||
#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;
|
||||
pSelVar pVar = NULL;
|
||||
@ -236,6 +237,7 @@
|
||||
pICallBack pCall = NULL, pCall2 = NULL;
|
||||
pDummy pDum = NULL;
|
||||
float fVal;
|
||||
commandContext comCon;
|
||||
|
||||
assert(pCon);
|
||||
assert(self);
|
||||
@ -264,7 +266,10 @@
|
||||
}
|
||||
|
||||
/* install new callback */
|
||||
comCon.transID = 0;
|
||||
strncpy(comCon.deviceID,"internal",SCDEVIDLEN);
|
||||
self->lID = RegisterCallback(pCall2,
|
||||
comCon,
|
||||
WLCHANGE,
|
||||
HKLCallback,
|
||||
self,
|
||||
@ -673,7 +678,7 @@ static int calculateNormalBeam(MATRIX z1, pHKL self, SConnection *pCon,
|
||||
float fSet[4], double myPsi, int iRetry)
|
||||
{
|
||||
int i, iTest;
|
||||
double stt, om, chi, phi, gamma, nu, psi;
|
||||
double stt, om, chi, phi, gamma, nu, psi, omnb;
|
||||
float currentPhi, currentChi;
|
||||
double ompsi, chipsi, phipsi;
|
||||
MATRIX chim, phim, z4, z3;
|
||||
@ -694,6 +699,7 @@ static int calculateNormalBeam(MATRIX z1, pHKL self, SConnection *pCon,
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
phim = mat_creat(3,3,ZERO_MATRIX);
|
||||
phimat(phim,(double)currentPhi);
|
||||
z4 = mat_mul(phim,z1);
|
||||
@ -703,6 +709,31 @@ static int calculateNormalBeam(MATRIX z1, pHKL self, SConnection *pCon,
|
||||
mat_free(phim);
|
||||
mat_free(chim);
|
||||
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
|
||||
|
22
ifile.c
22
ifile.c
@ -153,6 +153,28 @@
|
||||
{
|
||||
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)
|
||||
|
2
ifile.h
2
ifile.h
@ -25,6 +25,8 @@ typedef struct __IFileE
|
||||
/* returns a value for a name
|
||||
*/
|
||||
IPair *IFAddOption(IPair *pList,char *name, char *value);
|
||||
IPair *IFSetOption(IPair *pList,char *name, char *value);
|
||||
|
||||
int IFSaveOptions(IPair *pList,FILE *fp);
|
||||
void IFDeleteOptions(IPair *pList);
|
||||
|
||||
|
@ -83,6 +83,7 @@ static float EmptyGet(void *self, SConnection *pCon){
|
||||
pRes->SetValue = EmptyValue;
|
||||
pRes->CheckStatus = EmptyStatus;
|
||||
pRes->GetValue = EmptyGet;
|
||||
pRes->drivableStatus=HWIdle;
|
||||
return pRes;
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
33
interface.h
33
interface.h
@ -1,5 +1,5 @@
|
||||
|
||||
#line 365 "interface.w"
|
||||
#line 381 "interface.w"
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
I N T E R F A C E S
|
||||
@ -17,6 +17,7 @@
|
||||
|
||||
#ifndef SICSINTERFACES
|
||||
#define SICSINTERFACES
|
||||
#include "commandcontext.h"
|
||||
|
||||
/* interface ID's used to recognize an interface */
|
||||
#define DRIVEID 513
|
||||
@ -26,7 +27,7 @@
|
||||
|
||||
/* ----------------------- The drivable interface -----------------------*/
|
||||
|
||||
#line 117 "interface.w"
|
||||
#line 121 "interface.w"
|
||||
|
||||
|
||||
typedef struct {
|
||||
@ -39,6 +40,7 @@
|
||||
int (*CheckStatus)(void *self, SConnection *pCon);
|
||||
float (*GetValue)(void *self, SConnection *pCon);
|
||||
int iErrorCount;
|
||||
int drivableStatus;
|
||||
} IDrivable, *pIDrivable;
|
||||
|
||||
pIDrivable GetDrivableInterface(void *pObject);
|
||||
@ -46,14 +48,14 @@
|
||||
float *fPos);
|
||||
|
||||
|
||||
#line 390 "interface.w"
|
||||
#line 407 "interface.w"
|
||||
|
||||
|
||||
pIDrivable CreateDrivableInterface(void);
|
||||
|
||||
/* ------------------------ The countable interface ---------------------*/
|
||||
|
||||
#line 183 "interface.w"
|
||||
#line 188 "interface.w"
|
||||
|
||||
typedef struct {
|
||||
int ID;
|
||||
@ -70,23 +72,23 @@
|
||||
pICountable GetCountableInterface(void *pObject);
|
||||
|
||||
|
||||
#line 395 "interface.w"
|
||||
#line 412 "interface.w"
|
||||
|
||||
|
||||
pICountable CreateCountableInterface(void);
|
||||
|
||||
/* ------------------------- The CallBack Interface --------------------*/
|
||||
|
||||
#line 236 "interface.w"
|
||||
#line 241 "interface.w"
|
||||
|
||||
typedef void (*KillFuncIT)(void *pData);
|
||||
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;
|
||||
|
||||
@ -96,7 +98,8 @@
|
||||
int InvokeCallBack(pICallBack pInterface, int iEvent, void *pEventData);
|
||||
|
||||
/* 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);
|
||||
int RemoveCallback(pICallBack pInterface, long iID);
|
||||
int RemoveCallback2(pICallBack pInterface, void *pUserData);
|
||||
@ -106,11 +109,11 @@
|
||||
|
||||
pICallBack GetCallbackInterface(void *pData);
|
||||
|
||||
#line 401 "interface.w"
|
||||
#line 418 "interface.w"
|
||||
|
||||
/*---------------------- The Environment Interface --------------------*/
|
||||
|
||||
#line 329 "interface.w"
|
||||
#line 335 "interface.w"
|
||||
|
||||
typedef enum { EVIdle, EVDrive, EVMonitor, EVError } EVMode;
|
||||
typedef struct {
|
||||
@ -120,13 +123,13 @@
|
||||
int (*HandleError)(void *self);
|
||||
} EVInterface, *pEVInterface;
|
||||
|
||||
#line 403 "interface.w"
|
||||
#line 420 "interface.w"
|
||||
|
||||
|
||||
#line 355 "interface.w"
|
||||
#line 361 "interface.w"
|
||||
|
||||
pEVInterface CreateEVInterface(void);
|
||||
|
||||
#line 404 "interface.w"
|
||||
#line 421 "interface.w"
|
||||
|
||||
#endif
|
||||
|
@ -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}
|
||||
In order to present themselves to the system SICS objects need to adhere to
|
||||
certyain interfaces. These interfaces are described in this
|
||||
@ -28,7 +38,7 @@ Let's start with the objectdescriptor:
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap1}
|
||||
$\langle$obdes {\footnotesize ?}$\rangle\equiv$
|
||||
$\langle\,$obdes\nobreak\ {\footnotesize \NWtarget{nuweb?}{?}}$\,\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
@ -50,11 +60,15 @@ $\langle$obdes {\footnotesize ?}$\rangle\equiv$
|
||||
\mbox{}\verb@#ifndef SICSDESCRIPTOR@\\
|
||||
\mbox{}\verb@#define SICSDESCRIPTOR@\\
|
||||
\mbox{}\verb@#include <stdio.h>@\\
|
||||
\mbox{}\verb@#include <ifile.h>@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ typedef struct {@\\
|
||||
\mbox{}\verb@ char *name;@\\
|
||||
\mbox{}\verb@ int (*SaveStatus)(void *self, char *name,FILE *fd);@\\
|
||||
\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@@\\
|
||||
\mbox{}\verb@ /*---------------------------------------------------------------------------*/@\\
|
||||
@ -79,12 +93,12 @@ $\langle$obdes {\footnotesize ?}$\rangle\equiv$
|
||||
\mbox{}\verb@ int iHasType(void *pData, char *Type);@\\
|
||||
\mbox{}\verb@ @\\
|
||||
\mbox{}\verb@#endif @\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\mbox{}\verb@@{\NWsep}
|
||||
\end{list}
|
||||
\vspace{-1ex}
|
||||
\footnotesize\addtolength{\baselineskip}{-1ex}
|
||||
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
|
||||
\item Macro referenced in scrap ?.
|
||||
\item \NWtxtMacroRefIn\ \NWlink{nuweb?}{?}.
|
||||
\end{list}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
||||
@ -128,7 +142,7 @@ environment controllers fit this bill as well.
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap2}
|
||||
$\langle$driv {\footnotesize ?}$\rangle\equiv$
|
||||
$\langle\,$driv\nobreak\ {\footnotesize \NWtarget{nuweb?}{?}}$\,\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
@ -143,18 +157,19 @@ $\langle$driv {\footnotesize ?}$\rangle\equiv$
|
||||
\mbox{}\verb@ int (*CheckStatus)(void *self, SConnection *pCon);@\\
|
||||
\mbox{}\verb@ float (*GetValue)(void *self, SConnection *pCon); @\\
|
||||
\mbox{}\verb@ int iErrorCount;@\\
|
||||
\mbox{}\verb@ int drivableStatus;@\\
|
||||
\mbox{}\verb@ } IDrivable, *pIDrivable;@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ pIDrivable GetDrivableInterface(void *pObject); @\\
|
||||
\mbox{}\verb@ int GetDrivablePosition(void *pObject, SConnection *pCon,@\\
|
||||
\mbox{}\verb@ float *fPos);@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\mbox{}\verb@@{\NWsep}
|
||||
\end{list}
|
||||
\vspace{-1ex}
|
||||
\footnotesize\addtolength{\baselineskip}{-1ex}
|
||||
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
|
||||
\item Macro referenced in scrap ?.
|
||||
\item \NWtxtMacroRefIn\ \NWlink{nuweb?}{?}.
|
||||
\end{list}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
||||
@ -207,7 +222,7 @@ This is an interface for interacting with anything which counts.
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap3}
|
||||
$\langle$count {\footnotesize ?}$\rangle\equiv$
|
||||
$\langle\,$count\nobreak\ {\footnotesize \NWtarget{nuweb?}{?}}$\,\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
@ -225,12 +240,12 @@ $\langle$count {\footnotesize ?}$\rangle\equiv$
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ pICountable GetCountableInterface(void *pObject); @\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\mbox{}\verb@@{\NWsep}
|
||||
\end{list}
|
||||
\vspace{-1ex}
|
||||
\footnotesize\addtolength{\baselineskip}{-1ex}
|
||||
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
|
||||
\item Macro referenced in scrap ?.
|
||||
\item \NWtxtMacroRefIn\ \NWlink{nuweb?}{?}.
|
||||
\end{list}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
||||
@ -272,19 +287,19 @@ The first thing to define for such an interface is the type of the callback
|
||||
function:
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap4}
|
||||
$\langle$callfunc {\footnotesize ?}$\rangle\equiv$
|
||||
$\langle\,$callfunc\nobreak\ {\footnotesize \NWtarget{nuweb?}{?}}$\,\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ typedef void (*KillFuncIT)(void *pData);@\\
|
||||
\mbox{}\verb@ typedef int (*SICSCallBack)(int iEvent, void *pEventData, @\\
|
||||
\mbox{}\verb@ void *pUserData);@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\mbox{}\verb@ void *pUserData, commandContext cc);@\\
|
||||
\mbox{}\verb@@{\NWsep}
|
||||
\end{list}
|
||||
\vspace{-1ex}
|
||||
\footnotesize\addtolength{\baselineskip}{-1ex}
|
||||
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
|
||||
\item Macro referenced in scrap ?.
|
||||
\item \NWtxtMacroRefIn\ \NWlink{nuweb?}{?}.
|
||||
\end{list}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
||||
@ -306,7 +321,7 @@ interface:
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap5}
|
||||
$\langle$cifunc {\footnotesize ?}$\rangle\equiv$
|
||||
$\langle\,$cifunc\nobreak\ {\footnotesize \NWtarget{nuweb?}{?}}$\,\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
@ -318,7 +333,8 @@ $\langle$cifunc {\footnotesize ?}$\rangle\equiv$
|
||||
\mbox{}\verb@ int InvokeCallBack(pICallBack pInterface, int iEvent, void *pEventData); @\\
|
||||
\mbox{}\verb@@\\
|
||||
\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@ int RemoveCallback(pICallBack pInterface, long iID);@\\
|
||||
\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@@\\
|
||||
\mbox{}\verb@ pICallBack GetCallbackInterface(void *pData); @\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\mbox{}\verb@@{\NWsep}
|
||||
\end{list}
|
||||
\vspace{-1ex}
|
||||
\footnotesize\addtolength{\baselineskip}{-1ex}
|
||||
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
|
||||
\item Macro referenced in scrap ?.
|
||||
\item \NWtxtMacroRefIn\ \NWlink{nuweb?}{?}.
|
||||
\end{list}
|
||||
\end{minipage}\\[4ex]
|
||||
\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:
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap6}
|
||||
$\langle$envir {\footnotesize ?}$\rangle\equiv$
|
||||
$\langle\,$envir\nobreak\ {\footnotesize \NWtarget{nuweb?}{?}}$\,\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
@ -400,12 +416,12 @@ $\langle$envir {\footnotesize ?}$\rangle\equiv$
|
||||
\mbox{}\verb@ int (*IsInTolerance)(void *self);@\\
|
||||
\mbox{}\verb@ int (*HandleError)(void *self);@\\
|
||||
\mbox{}\verb@ } EVInterface, *pEVInterface;@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\mbox{}\verb@@{\NWsep}
|
||||
\end{list}
|
||||
\vspace{-1ex}
|
||||
\footnotesize\addtolength{\baselineskip}{-1ex}
|
||||
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
|
||||
\item Macro referenced in scrap ?.
|
||||
\item \NWtxtMacroRefIn\ \NWlink{nuweb?}{?}.
|
||||
\end{list}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
||||
@ -428,17 +444,17 @@ in question.
|
||||
The environment interface has just one function associated with it:
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap7}
|
||||
$\langle$envfunc {\footnotesize ?}$\rangle\equiv$
|
||||
$\langle\,$envfunc\nobreak\ {\footnotesize \NWtarget{nuweb?}{?}}$\,\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ pEVInterface CreateEVInterface(void);@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\mbox{}\verb@@{\NWsep}
|
||||
\end{list}
|
||||
\vspace{-1ex}
|
||||
\footnotesize\addtolength{\baselineskip}{-1ex}
|
||||
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
|
||||
\item Macro referenced in scrap ?.
|
||||
\item \NWtxtMacroRefIn\ \NWlink{nuweb?}{?}.
|
||||
\end{list}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
||||
@ -446,19 +462,29 @@ $\langle$envfunc {\footnotesize ?}$\rangle\equiv$
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap8}
|
||||
\verb@"obdes.h"@ {\footnotesize ? }$\equiv$
|
||||
\verb@"obdes.h"@\nobreak\ {\footnotesize \NWtarget{nuweb?}{?} }$\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@@$\langle$obdes {\footnotesize ?}$\rangle$\verb@@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\mbox{}\verb@@\hbox{$\langle\,$obdes\nobreak\ {\footnotesize \NWlink{nuweb?}{?}}$\,\rangle$}\verb@@\\
|
||||
\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}
|
||||
\vspace{-2ex}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap9}
|
||||
\verb@"interface.h"@ {\footnotesize ? }$\equiv$
|
||||
\verb@"interface.h"@\nobreak\ {\footnotesize \NWtarget{nuweb?}{?} }$\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
@ -478,6 +504,7 @@ $\langle$envfunc {\footnotesize ?}$\rangle\equiv$
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@#ifndef SICSINTERFACES@\\
|
||||
\mbox{}\verb@#define SICSINTERFACES@\\
|
||||
\mbox{}\verb@#include "commandcontext.h"@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/* interface ID's used to recognize an interface */@\\
|
||||
\mbox{}\verb@#define DRIVEID 513@\\
|
||||
@ -486,23 +513,23 @@ $\langle$envfunc {\footnotesize ?}$\rangle\equiv$
|
||||
\mbox{}\verb@#define ENVIRINTERFACE 949@\\
|
||||
\mbox{}\verb@@\\
|
||||
\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@ pIDrivable CreateDrivableInterface(void);@\\
|
||||
\mbox{}\verb@@\\
|
||||
\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@ pICountable CreateCountableInterface(void);@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/* ------------------------- The CallBack Interface --------------------*/@\\
|
||||
\mbox{}\verb@@$\langle$callfunc {\footnotesize ?}$\rangle$\verb@@\\
|
||||
\mbox{}\verb@@$\langle$cifunc {\footnotesize ?}$\rangle$\verb@@\\
|
||||
\mbox{}\verb@@\hbox{$\langle\,$callfunc\nobreak\ {\footnotesize \NWlink{nuweb?}{?}}$\,\rangle$}\verb@@\\
|
||||
\mbox{}\verb@@\hbox{$\langle\,$cifunc\nobreak\ {\footnotesize \NWlink{nuweb?}{?}}$\,\rangle$}\verb@@\\
|
||||
\mbox{}\verb@/*---------------------- The Environment Interface --------------------*/@\\
|
||||
\mbox{}\verb@@$\langle$envir {\footnotesize ?}$\rangle$\verb@@\\
|
||||
\mbox{}\verb@@$\langle$envfunc {\footnotesize ?}$\rangle$\verb@@\\
|
||||
\mbox{}\verb@@\hbox{$\langle\,$envir\nobreak\ {\footnotesize \NWlink{nuweb?}{?}}$\,\rangle$}\verb@@\\
|
||||
\mbox{}\verb@@\hbox{$\langle\,$envfunc\nobreak\ {\footnotesize \NWlink{nuweb?}{?}}$\,\rangle$}\verb@@\\
|
||||
\mbox{}\verb@#endif@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\mbox{}\verb@@{\NWsep}
|
||||
\end{list}
|
||||
\vspace{-2ex}
|
||||
\end{minipage}\\[4ex]
|
||||
|
21
interface.w
21
interface.w
@ -45,11 +45,15 @@ Let's start with the objectdescriptor:
|
||||
#ifndef SICSDESCRIPTOR
|
||||
#define SICSDESCRIPTOR
|
||||
#include <stdio.h>
|
||||
#include <ifile.h>
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
int (*SaveStatus)(void *self, char *name,FILE *fd);
|
||||
void *(*GetInterface)(void *self, int iInterfaceID);
|
||||
char *description;
|
||||
char *group;
|
||||
IPair *pKeys;
|
||||
} ObjectDescriptor, *pObjectDescriptor;
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
@ -126,6 +130,7 @@ environment controllers fit this bill as well.
|
||||
int (*CheckStatus)(void *self, SConnection *pCon);
|
||||
float (*GetValue)(void *self, SConnection *pCon);
|
||||
int iErrorCount;
|
||||
int drivableStatus;
|
||||
} IDrivable, *pIDrivable;
|
||||
|
||||
pIDrivable GetDrivableInterface(void *pObject);
|
||||
@ -236,7 +241,7 @@ function:
|
||||
@d callfunc @{
|
||||
typedef void (*KillFuncIT)(void *pData);
|
||||
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.
|
||||
@ -264,7 +269,8 @@ interface:
|
||||
int InvokeCallBack(pICallBack pInterface, int iEvent, void *pEventData);
|
||||
|
||||
/* 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);
|
||||
int RemoveCallback(pICallBack pInterface, long iID);
|
||||
int RemoveCallback2(pICallBack pInterface, void *pUserData);
|
||||
@ -360,6 +366,16 @@ The environment interface has just one function associated with it:
|
||||
|
||||
@o obdes.h -d @{
|
||||
@<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 @{
|
||||
@ -379,6 +395,7 @@ The environment interface has just one function associated with it:
|
||||
|
||||
#ifndef SICSINTERFACES
|
||||
#define SICSINTERFACES
|
||||
#include "commandcontext.h"
|
||||
|
||||
/* interface ID's used to recognize an interface */
|
||||
#define DRIVEID 513
|
||||
|
44
lin2ang.c
44
lin2ang.c
@ -8,6 +8,9 @@
|
||||
copyright: see copyright.h
|
||||
|
||||
Mark Koennecke, February 2000
|
||||
|
||||
added zero point handling for the Jochen
|
||||
Mark Koennecke, December 2005
|
||||
---------------------------------------------------------------------------*/
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
@ -25,12 +28,13 @@
|
||||
pIDrivable pDriv;
|
||||
pMotor lin;
|
||||
float length;
|
||||
float zero;
|
||||
}Lin2Ang, *pLin2Ang;
|
||||
|
||||
/*-------------------------- conversion routines -------------------------*/
|
||||
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)
|
||||
@ -40,7 +44,7 @@
|
||||
assert(self->length > 0.);
|
||||
|
||||
dt = fX/self->length;
|
||||
return RD*asin(dt);
|
||||
return RD*asin(dt) - self->zero;
|
||||
}
|
||||
/*============== functions in the interface ============================*/
|
||||
static void *Lin2AngGetInterface(void *pData, int iID)
|
||||
@ -65,7 +69,8 @@
|
||||
if(!self)
|
||||
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;
|
||||
|
||||
}
|
||||
@ -99,9 +104,7 @@
|
||||
|
||||
self = (pLin2Ang)pData;
|
||||
assert(self);
|
||||
fX = self->lin->pDrivInt->GetValue(self->lin,pCon);
|
||||
MotorGetPar(self->lin,"softzero",&zero);
|
||||
fX -= zero;
|
||||
MotorGetSoftPosition(self->lin,pCon,&fX);
|
||||
return x2ang(self,fX);
|
||||
}
|
||||
/*------------------------------------------------------------------------*/
|
||||
@ -271,6 +274,35 @@
|
||||
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 */
|
||||
if(strstr(argv[1],"lim") != NULL)
|
||||
{
|
||||
|
@ -13,6 +13,7 @@ lin2ang's datastructure is quite simple:
|
||||
pIDrivable pDriv;
|
||||
pMotor lin;
|
||||
float length;
|
||||
float zero;
|
||||
}Lin2Ang;
|
||||
\end{verbatim}
|
||||
The fields are:
|
||||
@ -22,6 +23,7 @@ The fields are:
|
||||
functionality of this object.
|
||||
\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[zero] The angular zero point of this virtual motor.
|
||||
\end{description}
|
||||
|
||||
The interface to this is quite simple, most of the functionality is
|
||||
|
@ -9,4 +9,4 @@
|
||||
|
||||
MFLAGS=-f makefile_linux$(DUMMY)
|
||||
|
||||
HDFROOT=/afs/psi.ch/project/sinq/linux
|
||||
HDFROOT=/usr/local
|
||||
|
13
macro.c
13
macro.c
@ -707,6 +707,15 @@ static int ProtectedExec(ClientData clientData, Tcl_Interp *interp,
|
||||
eOut = eWarning;
|
||||
break;
|
||||
case 7:
|
||||
eOut = eFinish;
|
||||
break;
|
||||
case 8:
|
||||
eOut = eEvent;
|
||||
break;
|
||||
case 9:
|
||||
eOut = eWarning;
|
||||
break;
|
||||
case 10:
|
||||
eOut = eError;
|
||||
break;
|
||||
default:
|
||||
@ -868,7 +877,9 @@ static int ProtectedExec(ClientData clientData, Tcl_Interp *interp,
|
||||
length += 10;
|
||||
pPtr = (char *)malloc(length*sizeof(char));
|
||||
if(pPtr == NULL){
|
||||
SCWrite(pCon,"ERROR: out of memory in TclAction",eError);
|
||||
SCWrite(pCon,
|
||||
"ERROR: out of memory in TclAction",
|
||||
eError);
|
||||
return 0;
|
||||
}
|
||||
memset(pPtr,0,length*sizeof(char));
|
||||
|
3
make_gen
3
make_gen
@ -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 \
|
||||
s_rnge.o sig_die.o gpibcontroller.o $(NIOBJ) mcreader.o mccontrol.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
|
||||
COUNTEROBJ = countdriv.o simcter.o counter.o
|
||||
|
@ -7,14 +7,15 @@
|
||||
#==========================================================================
|
||||
# assign if the National Instrument GPIB driver is available
|
||||
SINQDIR=/afs/psi.ch/project/sinq
|
||||
NI= -DHAVENI
|
||||
NIOBJ= nigpib.o
|
||||
NILIB=$(SINQDIR)/linux/lib/cib.o
|
||||
NI=
|
||||
#NI= -DHAVENI
|
||||
#NIOBJ= nigpib.o
|
||||
#NILIB=$(SINQDIR)/linux/lib/cib.o
|
||||
|
||||
include linux_def
|
||||
|
||||
CC = gcc
|
||||
CFLAGS = -I$(HDFROOT)/include -DHDF4 -DHDF5 $(NI) \
|
||||
CFLAGS = -I$(HDFROOT)/include -DHDF4 -DHDF5 -DNXXML $(NI) \
|
||||
-Ipsi/hardsup -I. \
|
||||
-fwritable-strings -DCYGNUS -DNONINTF -g $(DFORTIFY)
|
||||
|
||||
@ -22,10 +23,10 @@ BINTARGET = bin
|
||||
EXTRA=nintf.o
|
||||
SUBLIBS = psi/libpsi.a psi/hardsup/libhlib.a matrix/libmatrix.a \
|
||||
psi/tecs/libtecsl.a
|
||||
LIBS = -static -L$(HDFROOT)/lib $(SUBLIBS) $(NILIB)\
|
||||
-ltcl8.3 $(HDFROOT)/lib/libhdf5.a \
|
||||
LIBS = -L$(HDFROOT)/lib $(SUBLIBS) $(NILIB)\
|
||||
-ltcl8.4 -lmxml $(HDFROOT)/lib/libhdf5.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
|
||||
|
||||
|
@ -1,3 +1,3 @@
|
||||
106
|
||||
119
|
||||
NEVER, EVER modify or delete this file
|
||||
You'll risk eternal damnation and a reincarnation as a cockroach!|n
|
@ -38,7 +38,8 @@ proc mcstasdump {pid} {
|
||||
error "Trying to dump invalid PID: $pid"
|
||||
}
|
||||
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
|
||||
}
|
||||
#-----------------------------------------------------------------------
|
||||
@ -49,7 +50,9 @@ proc mcstasdump {pid} {
|
||||
# the Unix FAQ this is the best solution......
|
||||
#----------------------------------------------------------------------
|
||||
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]
|
||||
close $f
|
||||
return $pstxt
|
||||
@ -58,11 +61,13 @@ proc readPID {pid} {
|
||||
proc mcstasisrunning {pid} {
|
||||
global runningCount runningLast
|
||||
|
||||
# clientput "Checking McStas PID $pid"
|
||||
if { $pid <= 0} {
|
||||
return 0
|
||||
}
|
||||
set pstxt " "
|
||||
set ret [catch {set pstxt [readPID $pid]} msg]
|
||||
# clientput "pstext = $pstxt"
|
||||
set pslist [split $pstxt "\n"]
|
||||
if { [llength $pslist] < 2} {
|
||||
return 0
|
||||
@ -84,13 +89,17 @@ proc mcstaskill {pid} {
|
||||
error "Trying to kill invalid PID $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}
|
||||
wait 10
|
||||
}
|
||||
#-----------------------------------------------------------------------
|
||||
proc mcinstall {} {
|
||||
allowexec /usr/bin/kill
|
||||
allowexec /bin/kill
|
||||
allowexec /bin/ps
|
||||
Publish mcstasdump User
|
||||
Publish mcstasisrunning User
|
||||
|
@ -1,4 +1,4 @@
|
||||
# --------------------------------------------------------------------------
|
||||
# --------------------------------------------------------------------------
|
||||
# Initialization script for a virtual DMC instrument using a McStas
|
||||
# simulationas a data source
|
||||
#
|
||||
@ -6,12 +6,12 @@
|
||||
#---------------------------------------------------------------------------
|
||||
# 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
|
||||
#ServerOption RedirectFile $home/stdcdmc
|
||||
ServerOption ReadTimeOut 1
|
||||
ServerOption AcceptTimeOut 1
|
||||
ServerOption ReadTimeOut 10
|
||||
ServerOption AcceptTimeOut 10
|
||||
ServerOption ReadUserPasswdTimeout 500000
|
||||
ServerOption LogFileBaseName "$home/vdmclog"
|
||||
ServerOption LogFileDir $home/
|
||||
@ -137,3 +137,13 @@ source $home/vdmccom.tcl
|
||||
#-------------------- configure commandlog
|
||||
commandlog auto
|
||||
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
|
||||
|
@ -6,7 +6,7 @@
|
||||
source $home/mcsupport.tcl
|
||||
|
||||
if { [info exists vdmcinit] == 0 } {
|
||||
set vdmcinit 1
|
||||
set vdmcinit 1f
|
||||
Publish LogBook Spy
|
||||
Publish count User
|
||||
Publish Repeat User
|
||||
@ -187,10 +187,9 @@ proc copydmcdata { } {
|
||||
mcreader insertmon \
|
||||
"/$mcversion/DMC_diff/dmc.xml/PSD_sample/values" \
|
||||
counter 1 [expr 1./350]
|
||||
mcreader insertmon \
|
||||
"/$mcversion/DMC_diff/dmc.xml/Det9/det9.dat/values" \
|
||||
counter 4
|
||||
set hmScale [SplitReply [counter getmonitor 4]]
|
||||
# mcreader insertmon \
|
||||
# "/$mcversion/DMC_diff/dmc.xml/Det9/det9.dat/values" \
|
||||
# counter 4
|
||||
set val [mcreader getfield\
|
||||
"/$mcversion/DMC_diff/dmc.xml/Det9/det9.dat/values"]
|
||||
set l [split $val]
|
||||
@ -212,7 +211,6 @@ proc dmcdump {pid} {
|
||||
#--do nothing: progress is doing it for us
|
||||
}
|
||||
#--------------------------------------------------------------------------
|
||||
#mccontrol configure mcstart rundmcsim
|
||||
mccontrol configure mcstart rundmcoptsim
|
||||
mccontrol configure mccopydata copydmcdata
|
||||
mccontrol configure update 30
|
||||
|
@ -201,13 +201,13 @@ a9 precision 0.010000
|
||||
a9 ignorefault 0.000000
|
||||
a9 AccessCode 2.000000
|
||||
a9 movecount 10.000000
|
||||
title UNKNOWN
|
||||
title D3C
|
||||
title setAccess 2
|
||||
user UNKNOWN
|
||||
user setAccess 2
|
||||
collimation UNKNOWN
|
||||
collimation setAccess 2
|
||||
sampleintern na2ca3al2f14
|
||||
sampleintern D3C
|
||||
sampleintern setAccess 2
|
||||
comment1 UNKNOWN
|
||||
comment1 setAccess 2
|
||||
@ -215,7 +215,7 @@ comment2 UNKNOWN
|
||||
comment2 setAccess 2
|
||||
comment3 UNKNOWN
|
||||
comment3 setAccess 2
|
||||
starttime 2005-10-19 11:11:44
|
||||
starttime 2005-12-20 05:13:05
|
||||
starttime setAccess 2
|
||||
adress UNKNOWN
|
||||
adress setAccess 2
|
||||
|
59
motor.c
59
motor.c
@ -52,6 +52,7 @@
|
||||
#include "splitter.h"
|
||||
#include "status.h"
|
||||
#include "servlog.h"
|
||||
#include "tclmotdriv.h"
|
||||
#include "site.h"
|
||||
/*-------------------------------------------------------------------------
|
||||
some lokal defines
|
||||
@ -385,6 +386,12 @@ static void handleMoveCallback(pMotor self, SConnection *pCon)
|
||||
self = (pMotor)sulf;
|
||||
|
||||
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)
|
||||
{
|
||||
handleMoveCallback(self,pCon);
|
||||
@ -741,7 +748,7 @@ extern void KillPiPiezo(void *pData);
|
||||
iRet = MotorCheckBoundary(self,fNew,&fHard,pBueffel,511);
|
||||
if(!iRet)
|
||||
{
|
||||
SCWrite(pCon,pBueffel,eWarning);
|
||||
SCWrite(pCon,pBueffel,eStatus);
|
||||
SCSetInterrupt(pCon,eAbortOperation);
|
||||
return 0;
|
||||
}
|
||||
@ -1000,6 +1007,21 @@ extern MotorDriver *MakePiPiezo(Tcl_Interp *pTcl, char *pArray);
|
||||
SCWrite(pCon,pBueffel,eError);
|
||||
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
|
||||
{
|
||||
@ -1034,8 +1056,8 @@ extern MotorDriver *MakePiPiezo(Tcl_Interp *pTcl, char *pArray);
|
||||
int i, iLen;
|
||||
|
||||
iLen = ObParLength(self->ParArray);
|
||||
sprintf(pBueffel,"Parameter Listing for motor %s\n",self->name);
|
||||
SCWrite(pCon,pBueffel,eStatus);
|
||||
sprintf(pBueffel,"Parameter Listing for motor %s",self->name);
|
||||
SCWrite(pCon,pBueffel,eValue);
|
||||
snprintf(pBueffel,511,"%s.hardupperlim = %f",self->name,
|
||||
self->pDriver->fUpper);
|
||||
SCWrite(pCon,pBueffel,eValue);
|
||||
@ -1073,6 +1095,7 @@ extern MotorDriver *MakePiPiezo(Tcl_Interp *pTcl, char *pArray);
|
||||
typedef struct {
|
||||
char *pName;
|
||||
SConnection *pCon;
|
||||
float lastValue;
|
||||
} MotInfo, *pMotInfo;
|
||||
/*-----------------------------------------------------------------------*/
|
||||
static void KillInfo(void *pData)
|
||||
@ -1088,7 +1111,8 @@ extern MotorDriver *MakePiPiezo(Tcl_Interp *pTcl, char *pArray);
|
||||
free(self);
|
||||
}
|
||||
/*------------------- 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;
|
||||
char pBueffel[80];
|
||||
@ -1100,8 +1124,12 @@ extern MotorDriver *MakePiPiezo(Tcl_Interp *pTcl, char *pArray);
|
||||
psCall = (MotCallback *)pEvent;
|
||||
pInfo = (MotInfo *)pUser;
|
||||
|
||||
sprintf(pBueffel,"%s.position = %f ", pInfo->pName, psCall->fVal);
|
||||
SCWrite(pInfo->pCon,pBueffel,eValue);
|
||||
if (pInfo->lastValue != psCall->fVal) {
|
||||
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;
|
||||
}
|
||||
/*------------------------------------------------------------------------*/
|
||||
@ -1113,7 +1141,8 @@ extern MotorDriver *MakePiPiezo(Tcl_Interp *pTcl, char *pArray);
|
||||
}
|
||||
}
|
||||
/*------------------------ 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;
|
||||
MotCallback *psCall;
|
||||
@ -1178,7 +1207,7 @@ extern MotorDriver *MakePiPiezo(Tcl_Interp *pTcl, char *pArray);
|
||||
if(!iRet)
|
||||
{
|
||||
sprintf(pBueffel,"Error obtaining position for %s",argv[0]);
|
||||
SCWrite(pCon,pBueffel,eValue);
|
||||
SCWrite(pCon,pBueffel,eError);
|
||||
DeleteTokenList(pList);
|
||||
return 0;
|
||||
}
|
||||
@ -1220,7 +1249,17 @@ extern MotorDriver *MakePiPiezo(Tcl_Interp *pTcl, char *pArray);
|
||||
}
|
||||
pMoti->pName = strdup(argv[0]);
|
||||
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);
|
||||
SCRegister(pCon,pSics, self->pCall,lID);
|
||||
DeleteTokenList(pList);
|
||||
@ -1252,7 +1291,7 @@ extern MotorDriver *MakePiPiezo(Tcl_Interp *pTcl, char *pArray);
|
||||
return 0;
|
||||
}
|
||||
self->endScriptID =
|
||||
RegisterCallback(self->pCall, MOTEND, EndScriptCallback,
|
||||
RegisterCallback(self->pCall, SCGetContext(pCon),MOTEND, EndScriptCallback,
|
||||
strdup(pCurrent->text), KillScript);
|
||||
SCRegister(pCon,pSics, self->pCall,self->endScriptID);
|
||||
DeleteTokenList(pList);
|
||||
|
34
nserver.c
34
nserver.c
@ -6,10 +6,8 @@
|
||||
|
||||
Mark Koennecke, October 1996
|
||||
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, Mark Koennecke, May 2000
|
||||
Define handler in InitServer to ignore SIGPIPE. Paul Hathaway, May 2004
|
||||
|
||||
Copyright: see copyright.h
|
||||
----------------------------------------------------------------------------*/
|
||||
@ -19,6 +17,7 @@
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
#include "sics.h"
|
||||
@ -93,6 +92,8 @@
|
||||
memset(self,0,sizeof(SicsServer));
|
||||
*pServ = self;
|
||||
|
||||
/* define any signal handlers */
|
||||
signal(SIGPIPE,SIG_IGN);
|
||||
|
||||
/* configure fortify */
|
||||
iFortifyScope = Fortify_EnterScope();
|
||||
@ -458,7 +459,7 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
UserWait: the user command for waiting, expects one arg:
|
||||
time to wait in seconds
|
||||
*/
|
||||
---------------------------------------------------------------------------*/
|
||||
int UserWait(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[])
|
||||
{
|
||||
@ -517,7 +518,7 @@
|
||||
}
|
||||
}
|
||||
/*------------------------------------------------------------------------*/
|
||||
int SicsWait(long lTime)
|
||||
int SicsWaitOld(long lTime)
|
||||
{
|
||||
WaitStruct sWait;
|
||||
pTaskMan pTasker = NULL;
|
||||
@ -537,7 +538,28 @@
|
||||
TaskWait(pTasker,lID);
|
||||
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)
|
||||
{
|
||||
|
10
nxupdate.c
10
nxupdate.c
@ -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;
|
||||
SConnection *pCon = NULL;
|
||||
|
||||
@ -257,6 +258,7 @@ int UpdateFactory(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
char pBueffel[256];
|
||||
pNXupdate self = NULL;
|
||||
CommandList *pCom = NULL;
|
||||
commandContext comCon;
|
||||
|
||||
if(argc < 3){
|
||||
SCWrite(pCon,"ERROR: insuffcient number of argument to UpdateFactory",
|
||||
@ -309,9 +311,11 @@ int UpdateFactory(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
/*
|
||||
register callbacks
|
||||
*/
|
||||
RegisterCallback(pCall,COUNTSTART,CountCallback,
|
||||
comCon.transID = 0;
|
||||
strncpy(comCon.deviceID,"internal",SCDEVIDLEN);
|
||||
RegisterCallback(pCall,comCon,COUNTSTART,CountCallback,
|
||||
self,NULL);
|
||||
RegisterCallback(pCall,COUNTEND,CountCallback,
|
||||
RegisterCallback(pCall,comCon,COUNTEND,CountCallback,
|
||||
self,NULL);
|
||||
|
||||
AddCommand(pSics,argv[1],UpdateAction,KillUpdate,self);
|
||||
|
78
obdes.c
78
obdes.c
@ -66,6 +66,9 @@
|
||||
return NULL;
|
||||
}
|
||||
pRes->name = strdup(name);
|
||||
pRes->pKeys = NULL;
|
||||
pRes->description = NULL;
|
||||
pRes->group = NULL;
|
||||
pRes->SaveStatus = DefaultSave;
|
||||
pRes->GetInterface = DefaultGetInterface;
|
||||
return pRes;
|
||||
@ -74,10 +77,10 @@
|
||||
void DeleteDescriptor(pObjectDescriptor self)
|
||||
{
|
||||
assert(self);
|
||||
|
||||
if(self->name)
|
||||
free(self->name);
|
||||
|
||||
if(self->name) free(self->name);
|
||||
if(self->description) free(self->description);
|
||||
if(self->group) free(self->group);
|
||||
if(self->pKeys) IFDeleteOptions(self->pKeys);
|
||||
free(self);
|
||||
|
||||
}
|
||||
@ -134,11 +137,72 @@
|
||||
return 0;
|
||||
}
|
||||
/*------------------------------------------------------------------------*/
|
||||
pObjectDescriptor FindDescriptor(void *pData)
|
||||
{
|
||||
pObjectDescriptor FindDescriptor(void *pData)
|
||||
{
|
||||
pDummy pDum = NULL;
|
||||
|
||||
assert(pData);
|
||||
pDum = (pDummy)pData;
|
||||
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
18
obdes.h
@ -1,5 +1,5 @@
|
||||
|
||||
#line 361 "interface.w"
|
||||
#line 367 "interface.w"
|
||||
|
||||
|
||||
#line 29 "interface.w"
|
||||
@ -22,11 +22,15 @@
|
||||
#ifndef SICSDESCRIPTOR
|
||||
#define SICSDESCRIPTOR
|
||||
#include <stdio.h>
|
||||
#include <ifile.h>
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
int (*SaveStatus)(void *self, char *name,FILE *fd);
|
||||
void *(*GetInterface)(void *self, int iInterfaceID);
|
||||
char *description;
|
||||
char *group;
|
||||
IPair *pKeys;
|
||||
} ObjectDescriptor, *pObjectDescriptor;
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
@ -52,5 +56,15 @@ typedef struct {
|
||||
|
||||
#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
10
ofac.c
@ -114,6 +114,8 @@
|
||||
#include "tasscanub.h"
|
||||
#include "mcreader.h"
|
||||
#include "mccontrol.h"
|
||||
#include "protocol.h"
|
||||
#include "sinfox.h"
|
||||
/*----------------------- Server options creation -------------------------*/
|
||||
static int IFServerOption(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[])
|
||||
@ -237,6 +239,7 @@
|
||||
AddCommand(pInter,"sicsdatafactory",SICSDataFactory,NULL,NULL);
|
||||
AddCommand(pInter,"scriptcallback",CallbackScript,NULL,NULL);
|
||||
AddCommand(pInter,"help",SicsHelp,KillHelp,NULL);
|
||||
AddCommand(pInter,"sicsatt",SicsAtt,NULL,NULL);
|
||||
|
||||
/* commands to do with the executor. Only StopExe carries the
|
||||
DeleteFunction in order to avoid double deletion. All the
|
||||
@ -311,6 +314,10 @@
|
||||
McStasReaderFactory,NULL,NULL);
|
||||
AddCommand(pInter,"MakeMcStasController",
|
||||
McStasControllerFactory,NULL,NULL);
|
||||
AddCommand(pInter,"InstallProtocolHandler",
|
||||
InstallProtocol,NULL,NULL);
|
||||
AddCommand(pInter,"InstallSinfox",
|
||||
InstallSinfox,NULL,NULL);
|
||||
|
||||
/*
|
||||
install site specific commands
|
||||
@ -376,7 +383,8 @@
|
||||
RemoveCommand(pSics,"MakeTasUB");
|
||||
RemoveCommand(pSics,"MakeTasScan");
|
||||
RemoveCommand(pSics,"MakemcStasReader");
|
||||
|
||||
RemoveCommand(pSics,"InstallProtocolHandler");
|
||||
RemoveCommand(pSics,"InstallSinfox");
|
||||
/*
|
||||
remove site specific installation commands
|
||||
*/
|
||||
|
@ -15,8 +15,11 @@
|
||||
"inerror",
|
||||
"status",
|
||||
"value",
|
||||
"start",
|
||||
"finish",
|
||||
"event",
|
||||
"warning",
|
||||
"error",
|
||||
NULL };
|
||||
static int iNoCodes = 7;
|
||||
static int iNoCodes = 10;
|
||||
#endif
|
||||
|
@ -147,7 +147,8 @@
|
||||
return self->fCPS;
|
||||
}
|
||||
/*------------------- 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;
|
||||
SConnection *pCon;
|
||||
@ -160,7 +161,7 @@
|
||||
pCon = (SConnection *)pUser;
|
||||
|
||||
sprintf(pBueffel,"Performance = %f", *fPos);
|
||||
SCWrite(pCon,pBueffel,eValue);
|
||||
SCWriteInContext(pCon,pBueffel,eValue,cc);
|
||||
return 1;
|
||||
}
|
||||
/*----------------------------------------------------------------------------
|
||||
@ -206,7 +207,8 @@
|
||||
|
||||
if(strcmp(argv[1],"interest") == 0)
|
||||
{
|
||||
lID = RegisterCallback(self->pCall, VALUECHANGE, InterestCallback,
|
||||
lID = RegisterCallback(self->pCall, SCGetContext(pCon),
|
||||
VALUECHANGE, InterestCallback,
|
||||
pCon, NULL);
|
||||
SCRegister(pCon,pSics, self->pCall,lID);
|
||||
SCSendOK(pCon);
|
||||
|
616
protocol.c
Normal file
616
protocol.c
Normal 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
34
protocol.h
Normal 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
|
@ -250,6 +250,32 @@ int readRS232TillTerm(prs232 self, void *data, int *datalen){
|
||||
}
|
||||
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)
|
||||
{
|
||||
@ -736,6 +762,31 @@ int RS232Action(SConnection *pCon, SicsInterp *pSics,
|
||||
SCWrite(pCon,pBuffer,eValue);
|
||||
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)
|
||||
{
|
||||
iRet = availableRS232(self);
|
||||
|
@ -56,6 +56,8 @@
|
||||
int writeRS232(prs232 self, void *data, int dataLen);
|
||||
int readRS232(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 availableNetRS232(prs232 self);
|
||||
int transactRS232(prs232 self, void *send, int sendLen,
|
||||
|
43
scan.c
43
scan.c
@ -1236,7 +1236,8 @@ int isScanVarSoft(pScanData self){
|
||||
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;
|
||||
SConnection *pCon = NULL;
|
||||
@ -1253,12 +1254,12 @@ int isScanVarSoft(pScanData self){
|
||||
|
||||
if(iEvent == SCANSTART)
|
||||
{
|
||||
SCWrite(pCon,"NewScan",eWarning);
|
||||
SCWriteInContext(pCon,"NewScan",eWarning,cc);
|
||||
return 1;
|
||||
}
|
||||
else if(iEvent == SCANEND)
|
||||
{
|
||||
SCWrite(pCon,"ScanEnd",eWarning);
|
||||
SCWriteInContext(pCon,"ScanEnd",eWarning,cc);
|
||||
return 1;
|
||||
}
|
||||
else if(iEvent == SCANPOINT)
|
||||
@ -1299,7 +1300,8 @@ int isScanVarSoft(pScanData self){
|
||||
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;
|
||||
SConnection *pCon = NULL;
|
||||
@ -1319,12 +1321,12 @@ int isScanVarSoft(pScanData self){
|
||||
|
||||
if(iEvent == SCANSTART)
|
||||
{
|
||||
SCWrite(pCon,"NewScan",eWarning);
|
||||
SCWriteInContext(pCon,"NewScan",eWarning,cc);
|
||||
return 1;
|
||||
}
|
||||
else if(iEvent == SCANEND)
|
||||
{
|
||||
SCWrite(pCon,"ScanEnd",eWarning);
|
||||
SCWriteInContext(pCon,"ScanEnd",eWarning,cc);
|
||||
return 1;
|
||||
}
|
||||
else if(iEvent == SCANPOINT)
|
||||
@ -1346,12 +1348,13 @@ int isScanVarSoft(pScanData self){
|
||||
}
|
||||
snprintf(pBueffel,255,"%s.scanpoint = {%d %f %ld}",
|
||||
self->objectName,i,fVal,lVal);
|
||||
SCWrite(pCon,pBueffel,eValue);
|
||||
SCWriteInContext(pCon,pBueffel,eValue,cc);
|
||||
}
|
||||
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;
|
||||
SConnection *pCon = NULL;
|
||||
@ -1368,12 +1371,12 @@ int isScanVarSoft(pScanData self){
|
||||
|
||||
if(iEvent == SCANSTART)
|
||||
{
|
||||
SCWrite(pCon,"NewScan",eWarning);
|
||||
SCWriteInContext(pCon,"NewScan",eWarning,cc);
|
||||
return 1;
|
||||
}
|
||||
else if(iEvent == SCANEND)
|
||||
{
|
||||
SCWrite(pCon,"ScanEnd",eWarning);
|
||||
SCWriteInContext(pCon,"ScanEnd",eWarning,cc);
|
||||
return 1;
|
||||
}
|
||||
else if(iEvent == SCANPOINT)
|
||||
@ -1395,7 +1398,9 @@ int isScanVarSoft(pScanData self){
|
||||
{
|
||||
iData[i] = htonl((int)lData[i]);
|
||||
}
|
||||
SCPushContext2(pCon,cc);
|
||||
SCWriteUUencoded(pCon,"ScanData",iData,self->iNP*sizeof(int));
|
||||
SCPopContext(pCon);
|
||||
free(lData);
|
||||
free(iData);
|
||||
return 1;
|
||||
@ -1896,13 +1901,13 @@ static int DumpScan(pScanData self, SConnection *pCon)
|
||||
/*-------- interest */
|
||||
else if(strcmp(argv[1],"interest") == 0)
|
||||
{
|
||||
lID = RegisterCallback(self->pCall, SCANSTART, ScanInterest,
|
||||
lID = RegisterCallback(self->pCall, SCGetContext(pCon),SCANSTART, ScanInterest,
|
||||
pCon, NULL);
|
||||
SCRegister(pCon,pSics, self->pCall,lID);
|
||||
lID = RegisterCallback(self->pCall, SCANEND, ScanInterest,
|
||||
lID = RegisterCallback(self->pCall, SCGetContext(pCon),SCANEND, ScanInterest,
|
||||
pCon, NULL);
|
||||
SCRegister(pCon,pSics, self->pCall,lID);
|
||||
lID = RegisterCallback(self->pCall, SCANPOINT, ScanInterest,
|
||||
lID = RegisterCallback(self->pCall, SCGetContext(pCon),SCANPOINT, ScanInterest,
|
||||
pCon, NULL);
|
||||
SCRegister(pCon,pSics, self->pCall,lID);
|
||||
SCSendOK(pCon);
|
||||
@ -1911,13 +1916,13 @@ static int DumpScan(pScanData self, SConnection *pCon)
|
||||
/*-------- interest */
|
||||
else if(strcmp(argv[1],"dyninterest") == 0)
|
||||
{
|
||||
lID = RegisterCallback(self->pCall, SCANSTART, ScanDynInterest,
|
||||
lID = RegisterCallback(self->pCall, SCGetContext(pCon),SCANSTART, ScanDynInterest,
|
||||
pCon, NULL);
|
||||
SCRegister(pCon,pSics, self->pCall,lID);
|
||||
lID = RegisterCallback(self->pCall, SCANEND, ScanDynInterest,
|
||||
lID = RegisterCallback(self->pCall, SCGetContext(pCon), SCANEND, ScanDynInterest,
|
||||
pCon, NULL);
|
||||
SCRegister(pCon,pSics, self->pCall,lID);
|
||||
lID = RegisterCallback(self->pCall, SCANPOINT, ScanDynInterest,
|
||||
lID = RegisterCallback(self->pCall, SCGetContext(pCon),SCANPOINT, ScanDynInterest,
|
||||
pCon, NULL);
|
||||
SCRegister(pCon,pSics, self->pCall,lID);
|
||||
SCSendOK(pCon);
|
||||
@ -1926,13 +1931,13 @@ static int DumpScan(pScanData self, SConnection *pCon)
|
||||
/*-------- uuinterest */
|
||||
else if(strcmp(argv[1],"uuinterest") == 0)
|
||||
{
|
||||
lID = RegisterCallback(self->pCall, SCANSTART, ScanUUInterest,
|
||||
lID = RegisterCallback(self->pCall, SCGetContext(pCon),SCANSTART, ScanUUInterest,
|
||||
pCon, NULL);
|
||||
SCRegister(pCon,pSics, self->pCall,lID);
|
||||
lID = RegisterCallback(self->pCall, SCANEND, ScanUUInterest,
|
||||
lID = RegisterCallback(self->pCall, SCGetContext(pCon),SCANEND, ScanUUInterest,
|
||||
pCon, NULL);
|
||||
SCRegister(pCon,pSics, self->pCall,lID);
|
||||
lID = RegisterCallback(self->pCall, SCANPOINT, ScanUUInterest,
|
||||
lID = RegisterCallback(self->pCall, SCGetContext(pCon),SCANPOINT, ScanUUInterest,
|
||||
pCon, NULL);
|
||||
SCRegister(pCon,pSics, self->pCall,lID);
|
||||
SCSendOK(pCon);
|
||||
|
11
selvar.c
11
selvar.c
@ -474,7 +474,8 @@
|
||||
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;
|
||||
pSelVar self = NULL;
|
||||
@ -488,7 +489,7 @@
|
||||
|
||||
fVal = GetSelValue(self,pCon);
|
||||
sprintf(pBueffel,"%s.value = %f", self->name, fVal);
|
||||
SCWrite(pCon,pBueffel,eValue);
|
||||
SCWriteInContext(pCon,pBueffel,eValue,cc);
|
||||
return 1;
|
||||
}
|
||||
/*--------------------------------------------------------------------------
|
||||
@ -520,7 +521,8 @@
|
||||
strtolower(argv[1]);
|
||||
if(strcmp(argv[1],"interest") == 0)
|
||||
{
|
||||
lID = RegisterCallback(self->pCall, WLCHANGE, WaveLengthCallBack,
|
||||
lID = RegisterCallback(self->pCall, SCGetContext(pCon),
|
||||
WLCHANGE, WaveLengthCallBack,
|
||||
pCon, NULL);
|
||||
SCRegister(pCon,pSics, self->pCall,lID);
|
||||
SCSendOK(pCon);
|
||||
@ -589,7 +591,8 @@
|
||||
strtolower(argv[1]);
|
||||
if(strcmp(argv[1],"interest") == 0)
|
||||
{
|
||||
lID = RegisterCallback(self->pCall, WLCHANGE, WaveLengthCallBack,
|
||||
lID = RegisterCallback(self->pCall, SCGetContext(pCon),
|
||||
WLCHANGE, WaveLengthCallBack,
|
||||
pCon, NULL);
|
||||
SCRegister(pCon,pSics, self->pCall,lID);
|
||||
SCSendOK(pCon);
|
||||
|
102
servlog.c
102
servlog.c
@ -39,6 +39,13 @@
|
||||
IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
|
||||
NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
|
||||
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 <stdio.h>
|
||||
@ -223,30 +230,17 @@
|
||||
static FILE *fLogFile = NULL;
|
||||
static int iFile = 0;
|
||||
static int iLineCount = 0;
|
||||
static int iLogUsable = 1;
|
||||
|
||||
void SICSLogWrite(char *pText, OutCode eOut)
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int OpenVerifyLogFile()
|
||||
{
|
||||
char pFile[256];
|
||||
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");
|
||||
if(!pChar)
|
||||
{
|
||||
{ /* Try to write to file "server" in*/
|
||||
strcpy(pFile,"server");
|
||||
}
|
||||
else
|
||||
@ -257,44 +251,68 @@
|
||||
fLogFile = fopen(pFile,"w");
|
||||
if(!fLogFile)
|
||||
{
|
||||
printf("ERROR: cannot open logfile %s for writing\n",
|
||||
pFile);
|
||||
fprintf(stderr,"ERROR: Cannot open logfile %s for writing\n",pFile);
|
||||
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);
|
||||
fLogFile = NULL;
|
||||
iFile++;
|
||||
iLineCount = 0;
|
||||
if(iFile >= MAXFILES)
|
||||
{
|
||||
iFile = 0;
|
||||
}
|
||||
pChar = IFindOption(pSICSOptions,"LogFileBaseName");
|
||||
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;
|
||||
iLogUsable = OpenVerifyLogFile();
|
||||
}
|
||||
|
||||
if(1 == iLogUsable)
|
||||
{
|
||||
fprintf(fLogFile,"%s\n",pText);
|
||||
fflush(fLogFile);
|
||||
iLineCount++;
|
||||
@ -310,4 +328,4 @@
|
||||
pCurrent = pCurrent->pNext;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
230
sicsstat.tcl
230
sicsstat.tcl
@ -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
|
||||
|
21
sicvar.c
21
sicvar.c
@ -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;
|
||||
char pBueffel[512];
|
||||
pSicsVariable pVar = NULL;
|
||||
int iVal;
|
||||
int iVal, status;
|
||||
float fVal;
|
||||
char *pText;
|
||||
|
||||
@ -388,18 +389,21 @@
|
||||
|
||||
pVar = (pSicsVariable)pEvent;
|
||||
pCon = (SConnection *)pUser;
|
||||
SCPushContext2(pCon,cc);
|
||||
switch(pVar->eType)
|
||||
{
|
||||
case veInt:
|
||||
VarGetInt(pVar,&iVal);
|
||||
sprintf(pBueffel,"%s = %d",pVar->name,iVal);
|
||||
SCWrite(pCon,pBueffel,eValue);
|
||||
return 1;
|
||||
status = 1;
|
||||
break;
|
||||
case veFloat:
|
||||
VarGetFloat(pVar,&fVal);
|
||||
sprintf(pBueffel,"%s = %f",pVar->name,fVal);
|
||||
SCWrite(pCon,pBueffel,eValue);
|
||||
return 1;
|
||||
status = 1;
|
||||
break;
|
||||
case veText:
|
||||
VarGetText(pVar,&pText);
|
||||
sprintf(pBueffel,"%s = %s", pVar->name,pText);
|
||||
@ -408,9 +412,11 @@
|
||||
{
|
||||
free(pText);
|
||||
}
|
||||
return 1;
|
||||
status = 1;
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
SCPopContext(pCon);
|
||||
return status;
|
||||
}
|
||||
/*----------------------------------------------------------------------*/
|
||||
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 */
|
||||
{
|
||||
lID = RegisterCallback(pVar->pCall, VALUECHANGE, VarInterestCallback,
|
||||
lID = RegisterCallback(pVar->pCall, SCGetContext(pCon),
|
||||
VALUECHANGE, VarInterestCallback,
|
||||
pCon, NULL);
|
||||
SCRegister(pCon,pInterp, pVar->pCall,lID);
|
||||
DeleteTokenList(pList);
|
||||
|
387
sinfo.tcl
Normal file
387
sinfo.tcl
Normal 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"
|
||||
}
|
||||
}
|
115
sinfox.h
Normal file
115
sinfox.h
Normal 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 */
|
8
status.c
8
status.c
@ -181,7 +181,8 @@
|
||||
return 1;
|
||||
}
|
||||
/*------------------- 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;
|
||||
char pBueffel[80];
|
||||
@ -191,7 +192,9 @@
|
||||
pCon = (SConnection *)pUser;
|
||||
|
||||
sprintf(pBueffel,"status = %s", pText[(int)eCode]);
|
||||
SCPushContext2(pCon,cc);
|
||||
SCWrite(pCon,pBueffel,eWarning);
|
||||
SCPopContext(pCon);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -217,7 +220,8 @@
|
||||
strtolower(argv[1]);
|
||||
if(strcmp(argv[1],"interest") == 0)
|
||||
{
|
||||
lID = RegisterCallback(pCall, VALUECHANGE, StatusCallback,
|
||||
lID = RegisterCallback(pCall, SCGetContext(pCon),
|
||||
VALUECHANGE, StatusCallback,
|
||||
pCon, NULL);
|
||||
SCRegister(pCon,pSics, pCall,lID);
|
||||
SCSendOK(pCon);
|
||||
|
18
stptok.h
Normal file
18
stptok.h
Normal 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
91
sycFormat.tcl
Normal 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
219
sycamore.tcl
Normal 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
2
task.c
@ -293,7 +293,7 @@ ente:
|
||||
assert(self);
|
||||
assert(self->iID == TASKERID);
|
||||
|
||||
/* Cycle until back at our selves killed. */
|
||||
/* Cycle until back at ourselves */
|
||||
pEnd = self->pCurrent;
|
||||
pEnd->iStatus = WAITING;
|
||||
IncrTaskPointer(self);
|
||||
|
2
task.h
2
task.h
@ -106,7 +106,7 @@
|
||||
int TaskYield(pTaskMan self);
|
||||
/*
|
||||
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);
|
||||
|
395
tclmotdriv.c
Normal file
395
tclmotdriv.c
Normal 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
41
tclmotdriv.h
Normal 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
193
velo.c
@ -1,4 +1,4 @@
|
||||
/*---------------------------------------------------------------------------
|
||||
/*---------------------------------------------------------------------------
|
||||
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
|
||||
@ -116,6 +116,37 @@
|
||||
/* Success ! */
|
||||
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)
|
||||
{
|
||||
@ -701,7 +732,7 @@
|
||||
return 1;
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
static pEVDriver MakeDummyVel(pVelSel pVel)
|
||||
pEVDriver MakeDummyVel(pVelSel pVel)
|
||||
{
|
||||
pEVDriver pNew = NULL;
|
||||
pVelPrivate ich = NULL;
|
||||
@ -869,51 +900,6 @@
|
||||
EVRegisterController(FindEMON(pSics),pBueffel,pNew->pMonitor,pCon);
|
||||
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 {
|
||||
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;
|
||||
float *fVal = NULL;
|
||||
@ -949,12 +936,12 @@
|
||||
if(iEvent == ROTSTART)
|
||||
{
|
||||
sprintf(pBueffel,"%s Starting",pDat->pName);
|
||||
SCWrite(pDat->pCon,pBueffel,eWarning);
|
||||
SCWriteInContext(pDat->pCon,pBueffel,eWarning,cc);
|
||||
}
|
||||
else if(iEvent == ROTMOVE)
|
||||
{
|
||||
sprintf(pBueffel,"%s.rpm = %f",pDat->pName, *fVal);
|
||||
SCWrite(pDat->pCon,pBueffel,eWarning);
|
||||
SCWriteInContext(pDat->pCon,pBueffel,eWarning,cc);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@ -980,10 +967,6 @@
|
||||
assert(pCon);
|
||||
assert(pSics);
|
||||
|
||||
/* convert to text for parsing */
|
||||
Arg2Text(argc,argv,pCommand, 511);
|
||||
strtolower(pCommand);
|
||||
|
||||
if(argc < 2)
|
||||
{
|
||||
sprintf(pBueffel,"ERROR: %s expects at least one parameter",argv[0]);
|
||||
@ -1026,10 +1009,10 @@
|
||||
}
|
||||
pCB->pCon = pCon;
|
||||
pCB->pName = strdup(argv[0]);
|
||||
lID = RegisterCallback(self->pCall, ROTSTART, RotationInterest,
|
||||
lID = RegisterCallback(self->pCall, SCGetContext(pCon), ROTSTART, RotationInterest,
|
||||
pCB, KillCB);
|
||||
SCRegister(pCon,pSics, self->pCall,lID);
|
||||
lID = RegisterCallback(self->pCall, ROTMOVE, RotationInterest,
|
||||
lID = RegisterCallback(self->pCall, SCGetContext(pCon), ROTMOVE, RotationInterest,
|
||||
pCB, NULL);
|
||||
SCRegister(pCon,pSics, self->pCall,lID);
|
||||
SCSendOK(pCon);
|
||||
@ -1082,6 +1065,13 @@
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* list forbidden regions */
|
||||
if(strcmp(argv[1],"forbidden") == 0)
|
||||
{
|
||||
VSListForbidden(self,pCon);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* status, prints a status message */
|
||||
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 */
|
||||
iRet = VSGetRotation(self,&fRot);
|
||||
if(!iRet)
|
||||
@ -1143,61 +1157,50 @@
|
||||
iRet = MotorGetSoftPosition(self->pTilt,pCon,&fTilt);
|
||||
if(!iRet)
|
||||
{
|
||||
SCWrite(pCon,"ERROR: velocity selector operation aborted",eError);
|
||||
SCWrite(pCon,"ERROR: failed to read tilt angle",eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* search for Tilt */
|
||||
pPtr = strstr(pCommand,"tilt");
|
||||
if(pPtr) /* analyse tilt */
|
||||
{
|
||||
if(strcmp(argv[1],"tilt") == 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;
|
||||
}
|
||||
fTilt = dVal;
|
||||
iDrive = 1;
|
||||
iRet = TTFindNumber(pSics->pTcl,pPtr+strlen("tilt"),&fTilt);
|
||||
if(!iRet)
|
||||
{
|
||||
/* no new value, just print the current one */
|
||||
MotorGetSoftPosition(self->pTilt,pCon,&fTilt);
|
||||
} else {
|
||||
sprintf(pBueffel,"%s tilt = %f",argv[0],fTilt);
|
||||
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 */
|
||||
pPtr = strstr(pCommand,"rot");
|
||||
if(pPtr) /* analyse tilt */
|
||||
{
|
||||
iDrive = 1;
|
||||
iRet = TTFindNumber(pSics->pTcl,pPtr+strlen("rot"),&fVal);
|
||||
if(!iRet)
|
||||
{
|
||||
sprintf(pBueffel,"%s rot = %f",argv[0],fRot);
|
||||
if(strcmp(argv[1],"rot") == 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;
|
||||
}
|
||||
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 */
|
||||
|
1
velo.h
1
velo.h
@ -46,7 +46,6 @@
|
||||
|
||||
#line 264 "velo.w"
|
||||
|
||||
|
||||
#line 164 "velo.w"
|
||||
|
||||
int VSGetLossCurrent(pVelSel self, SConnection *pCon, float *fLoss);
|
||||
|
@ -11,7 +11,7 @@ lappend auto_path /data/koenneck/bin/tcl
|
||||
|
||||
set INI(DefUser) Spy
|
||||
set INI(DefPasswd) 007
|
||||
set INI(ServerPort) 3006
|
||||
set INI(ServerPort) 2911
|
||||
set INI(InterruptPort) 2913
|
||||
set INI(box) localhost
|
||||
set INI(usPasswd) Rosy
|
||||
|
Reference in New Issue
Block a user