- Reworked the connection object and the IO system

- Reworked the support for TRICS
- Added a second generation motor
This commit is contained in:
koennecke
2009-02-03 08:05:39 +00:00
parent f6d595665e
commit 361ee9ebea
119 changed files with 16455 additions and 3674 deletions

View File

@ -270,10 +270,10 @@ extern char *SkipSpace(char *pPtr);
assert(pCon);
/* write info to Log */
if(pCon->pSock)
if(pCon->sockHandle >= 0)
{
sprintf(pBueffel,"Executing -> %s <- from socket %d",pText,
pCon->pSock->sockid);
pCon->sockHandle);
SICSLogWrite(pBueffel,eCommand);
}
else
@ -282,6 +282,7 @@ extern char *SkipSpace(char *pPtr);
SICSLogWrite(pBueffel,eCommand);
}
/* convert to argc, argv */
argc = 0;
argv = NULL;
@ -315,7 +316,7 @@ extern char *SkipSpace(char *pPtr);
/* invoke the command */
self->eOut = eStatus;
self->eOut = eValue;
Tcl_ResetResult((Tcl_Interp *)self->pTcl);
MacroPush(pCon);
pCon->conStatus = 0;
@ -324,8 +325,8 @@ extern char *SkipSpace(char *pPtr);
StatisticsEnd(old);
/* If a task is registered with the dev exec then conStatus is HWBusy*/
if (pCon->conStatus != HWBusy) {
comCon = SCGetContext(pCon);
if (0 != strcmp("contextdo",comCon.deviceID))
/*comCon = SCGetContext(pCon);*/
if (0 != strcmp("contextdo",pCon->deviceID))
SCWrite(pCon,"",eFinish);
}
MacroPop();
@ -552,7 +553,7 @@ static void printAll(SicsInterp *pSics, SConnection *pCon)
strcat(pBueffel," ");
strcat(pBueffel,pCurrent->pName);
strcat(pBueffel,"\r\n");
SCWrite(pCon,pBueffel,eStatus);
SCWrite(pCon,pBueffel,eValue);
iNum = 0;
pBueffel[0]='\0';
}
@ -563,7 +564,7 @@ static void printAll(SicsInterp *pSics, SConnection *pCon)
if(strlen(pBueffel) > 2)
{
strcat(pBueffel,"\r\n");
SCWrite(pCon,pBueffel,eStatus);
SCWrite(pCon,pBueffel,eValue);
}
}
/*------------------------------------------------------------------------*/
@ -597,7 +598,7 @@ static void printAllTypes(SicsInterp *pSics, SConnection *pCon, int iFiltered)
if(-1==typeListID)
{
strcpy(pBueffel,"ERROR: Cannot generate list of object types\r\n");
SCWrite(pCon,pBueffel,eStatus);
SCWrite(pCon,pBueffel,eValue);
return;
}
@ -679,7 +680,7 @@ static void printInterface(SicsInterp *pSics, SConnection *pCon, int id)
strcat(pBueffel," ");
strcat(pBueffel,pCurrent->pName);
strcat(pBueffel,"\r\n");
SCWrite(pCon,pBueffel,eStatus);
SCWrite(pCon,pBueffel,eValue);
iNum = 0;
pBueffel[0]='\0';
}
@ -690,7 +691,7 @@ static void printInterface(SicsInterp *pSics, SConnection *pCon, int id)
/* write final entries */
strcat(pBueffel,"\r\n");
SCWrite(pCon,pBueffel,eStatus);
SCWrite(pCon,pBueffel,eValue);
}
/*-----------------------------------------------------------------------
printMatch prints only those objects which match the wildcard string given
@ -732,7 +733,7 @@ static void printMatch(SicsInterp *pSics, SConnection *pCon, char *mask)
strcat(pBueffel," ");
strcat(pBueffel,pCurrent->pName);
strcat(pBueffel,"\r\n");
SCWrite(pCon,pBueffel,eStatus);
SCWrite(pCon,pBueffel,eValue);
pBueffel[0]='\0';
iNum = 0;
}
@ -743,7 +744,7 @@ static void printMatch(SicsInterp *pSics, SConnection *pCon, char *mask)
/* write final entries */
strcat(pBueffel,"\r\n");
SCWrite(pCon,pBueffel,eStatus);
SCWrite(pCon,pBueffel,eValue);
}
/*-----------------------------------------------------------------------
printType prints only those objects whose descriptor match the type given
@ -794,7 +795,7 @@ static void printType(SicsInterp *pSics, SConnection *pCon, char *typeName)
/* write final entries */
strcat(pBueffel,"\r\n");
SCWrite(pCon,Tcl_DStringValue(&txt),eStatus);
SCWrite(pCon,Tcl_DStringValue(&txt),eValue);
Tcl_DStringFree(&txt);
}
/*--------------------------------------------------------------------------*/
@ -1042,7 +1043,7 @@ static void printList(SConnection *pCon, int listID)
if ((MAXBUF-3) > retCode) {
retCode = LLDstringData(listID,pBueffel);
strcat(pBueffel,"\r\n");
SCWrite(pCon,pBueffel,eStatus);
SCWrite(pCon,pBueffel,eValue);
}
} while(0!=LLDnodePtr2Next(listID));
}

View File

@ -40,19 +40,21 @@
/* this enum defines the output types in SICS */
typedef enum {
eInternal,
eCommand,
eHWError,
eInError,
eStatus,
eValue,
eStart,
eFinish,
eEvent,
eWarning,
eError,
eHdbValue,
eHdbEvent
eInternal, /* internal */
eCommand, /* reserved, not used */
eHWError, /* reserved, used only for SICSLog */
eInError, /* reserved, used as a mark in the handling of output codes */
eStatus, /* reserved, deprecated */
eValue, /* value reponse: copied into Tcl */
eStart, /* start message */
eFinish, /* finish message */
eEvent, /* some callback messages */
eWarning, /* warnings */
eError, /* error: copied into Tcl */
eHdbValue, /* hipadaba value chnage */
eHdbEvent, /* Hipadaba event */
eLog, /* log message: is always written to client */
eLogError /* error message to log: is always written to client */
} OutCode;
#include "interrupt.h"

14
ascon.c
View File

@ -305,7 +305,9 @@ int AsconStdHandler(Ascon *a) {
l = GetDynStringLength(a->wrBuffer) - a->wrPos;
ret = AsconWriteChars(a->fd, GetCharArray(a->wrBuffer) + a->wrPos, l);
if (ret < 0) {
if(errno != EINTR && errno != EAGAIN){
AsconError(a, "send failed:", errno);
}
/*
* Ooops: which state shall we go to after a write fail?
* This seems to retry.
@ -352,7 +354,10 @@ int AsconStdHandler(Ascon *a) {
ret = AsconReadChar(a->fd, &chr);
}
if (ret < 0) {
/* EINTR means we shall retry */
if(errno != EINTR && errno != EAGAIN){
AsconError(a, "AsconReadChar failed:", errno);
}
return 1;
}
if (a->state == AsconReadDone) {
@ -453,6 +458,13 @@ void AsconKill(Ascon *a) {
}
free(a);
}
void AsconDisconnect(Ascon *a){
if(a->fd > 0){
close(a->fd);
}
a->fd = -1;
a->state = AsconConnectStart;
}
AsconStatus AsconTask(Ascon *a) {
double now;
@ -491,6 +503,8 @@ AsconStatus AsconTask(Ascon *a) {
if (now > a->lastReconnect + a->reconnectInterval) {
a->lastReconnect = now;
close(a->fd);
/* allow the system to cleanup the socket, otherwise a reconnect will fail*/
sleep(1);
a->fd = -1;
a->state = AsconConnectStart;
}

View File

@ -36,6 +36,10 @@ Ascon *AsconMake(SConnection *con, int argc, char *argv[]);
* \param a the connection to be killed
*/
void AsconKill(Ascon *a);
/** \brief Disconnect function
* \param a the connection to disconnect
*/
void AsconDisconnect(Ascon *a);
/** \brief the task handler. To be called repeatedly.
* \param a the connection

View File

@ -648,7 +648,7 @@ int AsyncQueueAction(SConnection *pCon, SicsInterp *pSics,
}
else {
snprintf(line, 132, "%s.delay = %d", argv[0], self->iDelay);
SCWrite(pCon, line, eStatus);
SCWrite(pCon, line, eValue);
return OKOK;
}
return OKOK;
@ -675,7 +675,7 @@ int AsyncQueueAction(SConnection *pCon, SicsInterp *pSics,
}
else {
snprintf(line, 132, "%s.timeout = %d", argv[0], self->timeout);
SCWrite(pCon, line, eStatus);
SCWrite(pCon, line, eValue);
return OKOK;
}
return OKOK;
@ -702,7 +702,7 @@ int AsyncQueueAction(SConnection *pCon, SicsInterp *pSics,
}
else {
snprintf(line, 132, "%s.retries = %d", argv[0], self->retries);
SCWrite(pCon, line, eStatus);
SCWrite(pCon, line, eValue);
return OKOK;
}
return OKOK;

87
background.c Normal file
View File

@ -0,0 +1,87 @@
/**
* This is for backgrounding operations in SICS. They run in an own
* task.
*
* copyright: see file COPYRIGHT
*
* Mark Koennecke, February 2009
*/
#include <sics.h>
#include "splitter.h"
#include "background.h"
/*---------------------------------------------------------------------------*/
typedef struct {
SConnection *con;
char *command;
} BckTask, *pBckTask;
/*---------------------------------------------------------------------------*/
static void KillBckTask(void *data){
pBckTask self = (pBckTask)data;
if(self == NULL){
return;
}
if(self->con){
SCDeleteConnection(self->con);
}
if(self->command){
free(self->command);
}
}
/*---------------------------------------------------------------------------*/
static int BackgroundTask(void *data){
pBckTask self = (pBckTask)data;
assert(self != NULL);
InterpExecute(pServ->pSics,self->con,self->command);
return 0;
}
/*----------------------------------------------------------------------------*/
int BackgroundCommand(SConnection *pCon, char *command){
pBckTask self = NULL;
self = calloc(1,sizeof(BckTask));
if(self == NULL){
return 0;
}
self->con = SCCopyConnection(pCon);
self->command = strdup(command);
if(self->con == NULL || self->command == NULL){
free(self);
return 0;
}
TaskRegister(pServ->pTasker,
BackgroundTask,
NULL,
KillBckTask,
self,
1);
return 1;
}
/*------------------------------------------------------------------------*/
int BackgroundAction(SConnection *pCon, SicsInterp *pSics,
void *pData, int argc, char *argv[]){
int status;
char command[1024];
memset(command,0,1024);
Arg2Text(argc-1,&argv[1], command, 1024);
status = BackgroundCommand(pCon,command);
if(status == 0){
SCWrite(pCon,"ERROR: out of memory starting task", eError);
return 0;
}
SCSendOK(pCon);
return 1;
}
/*--------------------------------------------------------------------------*/
void InstallBackground(SicsInterp *pSics){
AddCommand(pSics,
"bg",
BackgroundAction,
NULL,
NULL);
}

26
background.h Normal file
View File

@ -0,0 +1,26 @@
/**
* This is for backgrounding operations in SICS. They run in an own
* task.
*
* copyright: see file COPYRIGHT
*
* Mark Koennecke, February 2009
*/
#ifndef BACKGROUND_H_
#define BACKGROUND_H_
/**
* interpreter inteface
*/
int BackgroundAction(SConnection *pCon, SicsInterp *pSics,
void *pData, int argc, char *argv[]);
/*
* actual function which does the backgrounding
*/
int BackgroundCommand(SConnection *pCon, char *command);
/*
* used only once for installing Background
*/
void InstallBackground(SicsInterp *pSics);
#endif /*BACKGROUND_H_*/

View File

@ -50,22 +50,24 @@
#include "splitter.h"
#define CALLBACK 17777
/*--------------------- The interface datastructure ---------------------*/
typedef struct __ICallBack {
int iID;
int iList;
} ICallBack;
static int debug = 0;
/*-------------- The data stored for a single callback ------------------*/
typedef struct {
typedef struct __CBItem{
long iID;
SICSCallBack pFunc;
void *pUserData;
KillFuncIT pKill;
int iEvent;
commandContext comCon;
int killFlag;
struct __CBItem *next;
} CallBackItem, *pCallBackItem;
/*--------------------- The interface datastructure ---------------------*/
typedef struct __ICallBack {
int iID;
pCallBackItem head;
} ICallBack;
/*------------------------------------------------------------------------*/
static int CheckPointer(pICallBack self)
{
@ -89,19 +91,14 @@
}
pNew->iID = CALLBACK;
pNew->iList = LLDcreate(sizeof(CallBackItem));
if(pNew->iList < 0)
{
free(pNew);
return NULL;
}
pNew->head = NULL;
return pNew;
}
/*--------------------------------------------------------------------------*/
void DeleteCallBackInterface(pICallBack self)
{
int iRet;
CallBackItem sItem;
pCallBackItem pItem, pTmp;
if(!CheckPointer(self))
{
@ -109,73 +106,160 @@
}
/* kill all userdata associated with callbacks */
iRet = LLDnodePtr2First(self->iList);
while(iRet != 0)
pItem = self->head;
while(pItem != NULL)
{
LLDnodeDataTo(self->iList,&sItem);
if(sItem.pKill != NULL)
pTmp = pItem->next;
if(pItem->pKill != NULL)
{
sItem.pKill(sItem.pUserData);
pItem->pKill(pItem->pUserData);
}
iRet = LLDnodePtr2Next(self->iList);
free(pItem);
pItem = pTmp;
}
LLDdelete(self->iList);
free(self);
}
/*--------------------------------------------------------------------------*/
static void markUserdata4Kill(pICallBack self, void *pData)
{
pCallBackItem pItem = NULL;
pItem = self->head;
while(pItem != NULL){
if(pData != NULL && pItem->pUserData == pData)
{
pItem->killFlag = 1;
}
pItem = pItem->next;
}
}
/*-------------------------------------------------------------------------*/
static void cleanCallbackList(pICallBack self)
{
pCallBackItem toKill, current;
/*
* killing at the head
*/
while(self->head != NULL && self->head->killFlag == 0){
toKill = self->head;
self->head = toKill->next;
if(toKill->pKill != NULL){
toKill->pKill(toKill->pUserData);
}
free(toKill);
}
if(self->head == NULL){
return;
}
/*
* killing in the middle and the end
*/
current = self->head;
while(current->next != NULL){
if(current->next->killFlag == 1){
toKill = current->next;
current->next = toKill->next;
if(toKill->pKill != NULL){
toKill->pKill(toKill->pUserData);
}
free(toKill);
} else {
current = current->next;
}
}
}
/*--------------------------------------------------------------------------*/
int InvokeCallBack(pICallBack self, int iEvent, void *pEventData)
{
CallBackItem sItem;
pCallBackItem pItem;
int iCurrent, iRet;
int iResult = 1;
int iResult = 1, iKill = 0;;
if(!CheckPointer(self))
{
return 0;
}
iCurrent = LLDnodePtr2First(self->iList);
while(iCurrent != 0)
pItem = self->head;
while(pItem != NULL)
{
LLDnodeDataTo(self->iList,&sItem);
if(sItem.iEvent == iEvent)
if(pItem->iEvent == iEvent && pItem->killFlag == 0)
{
iRet = sItem.pFunc(iEvent, pEventData,sItem.pUserData,sItem.comCon);
if(!iRet)
iRet = pItem->pFunc(iEvent, pEventData,pItem->pUserData);
if(iRet < 0)
{
pItem->killFlag = 1;
if(pItem->pUserData != NULL)
{
markUserdata4Kill(self, pItem->pUserData);
iKill = 1;
}
}
else if(iRet != 1)
{
iResult = 0;
}
}
iCurrent = LLDnodePtr2Next(self->iList);
pItem = pItem->next;
}
/* kill run */
if(iKill == 1){
cleanCallbackList(self);
}
return iResult;
}
/*--------------------------------------------------------------------------*/
static long lCount = 1L;
long RegisterCallback(pICallBack self, commandContext comCon, int iEvent,
long RegisterCallback(pICallBack self, int iEvent,
SICSCallBack pFunc,
void *pUserData, KillFunc pKFunc)
{
CallBackItem sItem;
pCallBackItem pItem = NULL;
if(!CheckPointer(self))
{
return 0;
}
sItem.iID = lCount++;
assert(pFunc);
sItem.pFunc = pFunc;
sItem.iEvent = iEvent;
sItem.pUserData = pUserData;
sItem.pKill = pKFunc;
sItem.comCon = comCon;
LLDnodeAppendFrom(self->iList,&sItem);
return sItem.iID;
pItem = calloc(1,sizeof(CallBackItem));
if(pItem == NULL){
return -1;
}
pItem->iID = lCount++;
assert(pFunc);
pItem->pFunc = pFunc;
pItem->iEvent = iEvent;
pItem->pUserData = pUserData;
pItem->pKill = pKFunc;
pItem->killFlag = 0;
pItem->next = self->head;
self->head = pItem;
if(debug){
printf("Registered callback at %p\n",self);
}
return pItem->iID;
}
/*------------------------------------------------------------------------*/
static void markById(pICallBack self, int lID)
{
pCallBackItem pItem = NULL;
pItem = self->head;
while(pItem != NULL)
{
if(pItem->iID == lID)
{
pItem->killFlag = 1;
}
pItem = pItem->next;
}
}
/*-------------------------------------------------------------------------*/
int RemoveCallback(pICallBack self, long lID)
{
@ -186,22 +270,8 @@
{
return 0;
}
iCurrent = LLDnodePtr2First(self->iList);
while(iCurrent != 0)
{
LLDnodeDataTo(self->iList,&sItem);
if(sItem.iID == lID)
{
if(sItem.pKill != NULL)
{
sItem.pKill(sItem.pUserData);
}
LLDnodeDelete(self->iList);
return 1;
}
iCurrent = LLDnodePtr2Next(self->iList);
}
markById(self,lID);
cleanCallbackList(self);
return 0;
}
/*--------------------------------------------------------------------------*/
@ -214,21 +284,35 @@
{
return 0;
}
markUserdata4Kill(self,pUserData);
cleanCallbackList(self);
return 1;
}
/*--------------------------------------------------------------------------*/
int RemoveCallbackCon(pICallBack self, SConnection *con)
{
pCallBackItem pItem;
SConnection *tst = NULL;
iCurrent = LLDnodePtr2First(self->iList);
while(iCurrent != 0)
if(!CheckPointer(self))
{
LLDnodeDataTo(self->iList,&sItem);
if(sItem.pUserData == pUserData)
return 0;
}
pItem = self->head;
while(pItem != NULL)
{
if(sItem.pKill != NULL)
tst = (SConnection *)pItem->pUserData;
if(VerifyConnection(tst) && tst->ident == con->ident)
{
sItem.pKill(sItem.pUserData);
if(debug){
printf("Killing callback on connection.ident = %ld\n", con->ident);
}
LLDnodeDelete(self->iList);
pItem->killFlag = 1;
}
iCurrent = LLDnodePtr2Next(self->iList);
pItem = pItem->next;
}
cleanCallbackList(self);
return 1;
}
/*-------------------------------------------------------------------
@ -246,8 +330,7 @@ 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,
commandContext cc)
static int ScriptCallback(int iEvent, void *pEventData, void *pUserData)
{
SConnection *pCon = NULL;
Tcl_Interp *pTcl;
@ -264,18 +347,6 @@ static int ScriptCallback(int iEvent, void *pEventData, void *pUserData,
fprintf(stdout,"ERROR: ScriptCallback: no script to execute\n");
return 0;
}
/*
SCSetWriteFunc(pCon,CallbackWrite);
MacroPush(pCon);
pTcl = InterpGetTcl(pServ->pSics);
status = Tcl_Eval(pTcl,(char *)pUserData);
if(status != TCL_OK)
{
fprintf(stdout,"ERROR: in CallbackScript: %s\n",(char *)pUserData);
fprintf(stdout,"Tcl-error: %s\n",pTcl->result);
}
MacroPop();
*/
SCSetRights(pCon,usInternal);
status = InterpExecute(pServ->pSics,pCon,(char *)pUserData);
@ -335,7 +406,7 @@ int CallbackScript(SConnection *pCon, SicsInterp *pSics, void *pData,
return 0;
}
Arg2Text(argc-4,&argv[4],pBuffer,131);
lID = RegisterCallback(pCall,SCGetContext(pCon),
lID = RegisterCallback(pCall,
iEvent,ScriptCallback,
strdup(pBuffer),free);
sprintf(pBuffer,"callback = %ld", lID);

276
cone.c
View File

@ -5,6 +5,10 @@
COPYRIGHT: see file COPYRIGHT
Mark Koennecke, March 2006
Reworked for new four circle infrastructure.
Mark Koennecke, August 2008
------------------------------------------------------------------------*/
#include <stdio.h>
#include <assert.h>
@ -12,11 +16,15 @@
#include "hkl.i"
#include "vector.h"
#include "fourlib.h"
#include "singlex.h"
#include "sicsobj.h"
#include "sicshipadaba.h"
/*=================== Object Descriptor Interface ===================================================*/
static void *ConeGetInterface(void *pData, int iID){
pConeData self = NULL;
pSICSOBJ obj = (pSICSOBJ)pData;
self = (pConeData)pData;
self = (pConeData)obj->pPrivate;
if(self == NULL){
return NULL;
}
@ -25,28 +33,15 @@ static void *ConeGetInterface(void *pData, int iID){
}
return NULL;
}
/*---------------------------------------------------------------------------------------------------*/
static void ConeSaveStatus(void *data, char *name, FILE *fd){
pConeData self = (pConeData)data;
if(self == NULL){
return;
}
fprintf(fd,"%s center %d\n", name,self->center);
fprintf(fd,"%s target %f %f %f\n", name, self->target.h,
self->target.k, self->target.l);
fprintf(fd,"%s qscale %f \n", name, self->qScale);
}
/*=================== Drivable Interface ============================================================*/
static int ConeHalt(void *pData){
pSICSOBJ obj = pData;
pConeData self = NULL;
self = (pConeData)pData;
self = (pConeData)obj->pPrivate;
assert(self != NULL);
self->pHkl->pTheta->pDrivInt->Halt(self->pHkl->pTheta);
self->pHkl->pOmega->pDrivInt->Halt(self->pHkl->pOmega);
self->pHkl->pChi->pDrivInt->Halt(self->pHkl->pChi);
self->pHkl->pPhi->pDrivInt->Halt(self->pHkl->pPhi);
stopHKLMotors(self->pHkl);
return 1;
}
/*-----------------------------------------------------------------------------------------------------*/
@ -88,37 +83,71 @@ static MATRIX makeCsToPsiMatrix(reflection center, double lambda){
* me a lot of trouble keeping track of parameter changes in UBCALC etc.
* ---------------------------------------------------------------------------*/
static long ConeSetValue(void *pData, SConnection *pCon, float fVal){
pSICSOBJ obj = pData, refList;
pConeData self = NULL;
float fSet[4];
double fSet[4];
float ffSet[4];
double openingAngle, length;
MATRIX csToPsi = NULL, B = NULL, newScat = NULL;
int status;
reflection center;
int status, i;
reflection center, target;
char buffer[131];
const double *cell;
double hkl[3], ang[4];
lattice direct;
hdbValue v;
if(!SCMatchRights(pCon,usUser)){
return 0;
}
self = (pConeData)pData;
self = (pConeData)obj->pPrivate;
assert(self != NULL);
/*
* calculate opening angle
*/
B = mat_creat(3,3,UNIT_MATRIX);
status = calculateBMatrix(self->ubi->direct,B);
cell = SXGetCell();
direct.a = cell[0];
direct.b = cell[1];
direct.c = cell[2];
direct.alpha = cell[3];
direct.beta = cell[4];
direct.gamma = cell[5];
status = calculateBMatrix(direct,B);
if(status < 0){
SCWrite(pCon,"ERROR: cell has no volume",eError);
return 0;
}
center = getReflection(self->ubi,self->center);
openingAngle = angleBetweenReflections(B,center,self->target);
/*
* get center from the main reflection list
*/
refList = SXGetReflectionList();
SICSHdbGetPar(obj,pCon,"center", &v);
if(!GetRefIndexID(refList,v.v.text,hkl)){
SCPrintf(pCon,eError,"ERROR: cannot find reflection with ID: %s", v.v.text);
return 0;
}
center.h = hkl[0];
center.k = hkl[1];
center.l = hkl[2];
GetRefAnglesID(refList,v.v.text,ang);
center.s2t = ang[0];
center.om = ang[1];
center.chi = ang[2];
center.phi = ang[3];
SICSHdbGetPar(obj,pCon,"target",&v);
target.h = v.v.floatArray[0];
target.k = v.v.floatArray[1];
target.l = v.v.floatArray[2];
openingAngle = angleBetweenReflections(B,center,target);
/*
* calculate conversion matrix from cone system to PSI system
*/
csToPsi = makeCsToPsiMatrix(center,self->ubi->hkl->fLambda);
csToPsi = makeCsToPsiMatrix(center,SXGetLambda());
if(csToPsi == NULL){
SCWrite(pCon,"ERROR: bad parameters: failed to generate conversion matrix",
eError);
@ -129,7 +158,16 @@ static long ConeSetValue(void *pData, SConnection *pCon, float fVal){
* calculate scattering vector on cone and make its length
* match the length of the apropriate scattering vector
*/
length = scatteringVectorLength(B,self->target) * self->qScale;
SICSHdbGetPar(obj,pCon,"target",&v);
target.h = v.v.floatArray[0];
target.k = v.v.floatArray[1];
target.l = v.v.floatArray[2];
SICSHdbGetPar(obj,pCon,"qscale",&v);
/*
* calculate scattering vector on cone and make its length
* match the length of the apropriate scattering vector
*/
length = scatteringVectorLength(B,target) * v.v.doubleValue;
newScat = calcConeVector(openingAngle, fVal, length, csToPsi);
if(newScat == NULL){
SCWrite(pCon,"ERROR: fails to calculate cone vector",eError);
@ -139,7 +177,7 @@ static long ConeSetValue(void *pData, SConnection *pCon, float fVal){
/*
* try to find setting angles for this vector
*/
status = findAllowedBisecting(self->pHkl->fLambda,newScat, fSet,
status = findAllowedBisecting(SXGetLambda(),newScat, fSet,
hklInRange, self->pHkl);
/*
* clean up matrices
@ -157,201 +195,119 @@ static long ConeSetValue(void *pData, SConnection *pCon, float fVal){
/*
* start motors
*/
return startHKLMotors(self->pHkl, pCon,fSet);
for(i = 0; i < 4; i++){
ffSet[i] = fSet[i];
}
return startHKLMotors(self->pHkl, pCon,ffSet);
}
/*---------------------------------------------------------------------------------------------------*/
static int checkMotors(pConeData self, SConnection *pCon){
int status;
int status, i;
pMotor pMot = NULL;
MotorFunction mots[] = {TwoTheta, Omega, Chi, Phi};
status = self->pHkl->pTheta->pDrivInt->CheckStatus(self->pHkl->pTheta, pCon);
for(i = 0; i < 4; i++){
pMot = SXGetMotor(mots[i]);
if(pMot != NULL){
status = pMot->pDrivInt->CheckStatus(pMot, pCon);
if(status != HWIdle && status != OKOK){
return status;
}
status = self->pHkl->pOmega->pDrivInt->CheckStatus(self->pHkl->pOmega, pCon);
if(status != HWIdle && status != OKOK){
return status;
}
status = self->pHkl->pChi->pDrivInt->CheckStatus(self->pHkl->pChi, pCon);
if(status != HWIdle && status != OKOK){
return status;
}
status = self->pHkl->pPhi->pDrivInt->CheckStatus(self->pHkl->pPhi, pCon);
if(status != HWIdle && status != OKOK){
return status;
}
return HWIdle;
}
/*-----------------------------------------------------------------------------------------------------*/
static int ConeCheckStatus(void *pData, SConnection *pCon){
pSICSOBJ obj = pData;
pConeData self = NULL;
int status;
self = (pConeData)pData;
self = (pConeData)obj->pPrivate;
assert(self != NULL);
return checkMotors(self,pCon);
}
/*-----------------------------------------------------------------------------------------------------*/
static float ConeGetValue(void *pData, SConnection *pCon){
pSICSOBJ obj = pData;
pConeData self = NULL;
float fVal[3];
int status;
self = (pConeData)pData;
self = (pConeData)obj->pPrivate;
assert(self != NULL);
return self->lastConeAngle;
}
/*=============================== Live and Death ====================================*/
static pConeData MakeConeMot(pUBCALC u){
static pConeData MakeConeMot(){
pConeData self = NULL;
assert(u != NULL);
self = (pConeData)malloc(sizeof(coneData));
if(self == NULL){
return NULL;
}
memset(self,0,sizeof(coneData));
self->pDes = CreateDescriptor("Cone");
self->pDriv = CreateDrivableInterface();
if(self->pDes == NULL || self->pDriv == NULL){
if(self->pDriv == NULL){
free(self);
return NULL;
}
self->pDes->GetInterface = ConeGetInterface;
self->pDriv->Halt = ConeHalt;
self->pDriv->CheckLimits = ConeCheckLimits;
self->pDriv->SetValue = ConeSetValue;
self->pDriv->CheckStatus = ConeCheckStatus;
self->pDriv->GetValue = ConeGetValue;
self->ubi = u;
self->pHkl = u->hkl;
self->qScale = 1.0;
return self;
}
/*----------------------------------------------------------------------------------*/
static void KillConeMot(void *pData){
pConeData self = NULL;
self = (pConeData)pData;
if(self == NULL){
return;
}
if(self->pDes != NULL){
DeleteDescriptor(self->pDes);
}
if(self->pDriv){
free(self->pDriv);
}
free(self);
}
/*=============================== Interpreter Interface ============================*/
int ConeAction(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]){
pConeData self = NULL;
float value;
int id;
char pBuffer[132];
self = (pConeData)pData;
assert(self != NULL);
if(argc > 1) {
strtolower(argv[1]);
if(strcmp(argv[1],"center") == 0){
if(argc > 2){
if(!SCMatchRights(pCon,usUser)){
return 0;
}
id = atoi(argv[2]);
if(id < 0 || id > 2 ){
SCWrite(pCon,"ERROR: id must be between 0 - 3",eError);
return 0;
}
self->center = id;
SCSendOK(pCon);
return 1;
} else {
snprintf(pBuffer,131,"%s.center = %d", argv[0], self->center);
SCWrite(pCon,pBuffer,eValue);
return 1;
}
} else if(strcmp(argv[1],"qscale") == 0){
if(argc > 2){
if(!SCMatchRights(pCon,usUser)){
return 0;
}
self->qScale = atof(argv[2]);
SCSendOK(pCon);
return 1;
} else {
snprintf(pBuffer,131,"%s.qscale = %f", argv[0], self->qScale);
SCWrite(pCon,pBuffer,eValue);
return 1;
}
} else if (strcmp(argv[1],"target") == 0){
if(argc >= 5){
if(!SCMatchRights(pCon,usUser)){
return 0;
}
self->target.h = atof(argv[2]);
self->target.k = atof(argv[3]);
self->target.l = atof(argv[4]);
self->qScale = 1.;
SCSendOK(pCon);
return 1;
} else {
snprintf(pBuffer,131,"%s.target = %f %f %f", argv[0],
self->target.h, self->target.k, self->target.l);
SCWrite(pCon,pBuffer,eValue);
return 1;
}
} else {
SCWrite(pCon,"ERROR: subcommand to cone not known",eError);
return 0;
}
}
/*
* default: print value
*/
value = self->pDriv->GetValue(self,pCon);
if(value < -9000.){
snprintf(pBuffer,131,"ERROR: failed to read %s",argv[0]);
SCWrite(pCon,pBuffer,eError);
return 0;
}
snprintf(pBuffer,131,"%s = %f", argv[0], value);
SCWrite(pCon,pBuffer,eValue);
return 1;
}
/*------------------------------------------------------------------------------------------*/
int MakeCone(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]){
pUBCALC ubi = NULL;
pSICSOBJ pNew = NULL;
pConeData pMot = NULL;
char pBuffer[131];
char pBuffer[131], pName[80];
int status;
pHdb cmd;
if(argc < 3){
SCWrite(pCon,"ERROR: insuffient number of arguments to MakeCone",eError);
if(argc > 1){
strcpy(pName,argv[1]);
} else {
strcpy(pName,"cone");
}
pNew = MakeSICSOBJ(pName,"Cone");
pMot = MakeConeMot();
if(pNew == NULL || pMot == NULL){
SCWrite(pCon,"ERROR: out of memory creating cone virtual motor",eError);
return 0;
}
ubi = FindCommandData(pSics,argv[2],"UBcalc");
if(ubi == NULL){
snprintf(pBuffer,131,"ERROR: %s is no UBcalc object" , argv[2]);
pNew->pDes->GetInterface = ConeGetInterface;
pNew->pPrivate = pMot;
pNew->KillPrivate = DefaultFree;
cmd = AddSICSHdbPar(pNew->objectNode,"target", usUser, makeHdbValue(HIPFLOATAR,3));
SetHdbProperty(cmd,"__save", "true");
cmd = AddSICSHdbPar(pNew->objectNode,"qscale", usUser, MakeHdbFloat(1.));
SetHdbProperty(cmd,"__save", "true");
cmd = AddSICSHdbPar(pNew->objectNode,"center", usUser, MakeHdbText("unknown"));
SetHdbProperty(cmd,"__save", "true");
if(argc > 2){
pMot->pHkl = FindCommandData(pSics,argv[2],"4-Circle-Calculus");
} else {
pMot->pHkl = FindCommandData(pSics,"hkl","4-Circle-Calculus");
}
if(pMot->pHkl == NULL){
snprintf(pBuffer,131,"ERROR: %s is no hkl object" , argv[2]);
SCWrite(pCon,pBuffer,eError);
return 0;
}
pMot = MakeConeMot(ubi);
if(pMot == NULL){
SCWrite(pCon,"ERROR: out of memory creating cone virtual motor",eError);
return 0;
}
status = AddCommand(pSics,argv[1],ConeAction,KillConeMot,pMot);
status = AddCommand(pSics,pName,InterInvokeSICSOBJ,KillSICSOBJ,pNew);
if(status != 1){
SCWrite(pCon,"ERROR: failed to create duplicate cone motor",eError);
}
return status;
}

9
cone.h
View File

@ -13,21 +13,12 @@
#include "ubcalc.h"
/*-----------------------------------------------------------------------*/
typedef struct {
pObjectDescriptor pDes;
pIDrivable pDriv;
reflection target;
float lastConeAngle;
float qScale;
pUBCALC ubi;
int center;
pHKL pHkl;
} coneData, *pConeData;
/*----------------------------------------------------------------------*/
int MakeCone(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]);
int ConeAction(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]);
#endif

View File

@ -241,15 +241,19 @@ static int ConfCheckLimits(void *pData, float fVal, char *error, int errLen){
{
free(self->pName);
}
if(self->pCon)
{
SCDeleteConnection(self->pCon);
}
free(self);
}
/*------------------- The CallBack function for interest ------------------
* iEvent: Event ID, see event.h for SICS events
* pEvent: May contain data from event generating object
* pUser: Data available when registering interest, see RegisteredInfo struct
* defined above for available info */
static int InterestCallback(int iEvent, void *pEvent, void *pUser,
commandContext cc)
* defined above for available info
--------------------------------------------------------------------------*/
static int InterestCallback(int iEvent, void *pEvent, void *pUser)
{
pRegisteredInfo pInfo = NULL;
char pBueffel[80];
@ -258,6 +262,10 @@ static int ConfCheckLimits(void *pData, float fVal, char *error, int errLen){
assert(pEvent);
assert(pUser);
if(!SCisConnected(pInfo->pCon)){
return -1;
}
pEventData = (EventInfo *)pEvent;
pInfo = (RegisteredInfo *)pUser;
@ -265,7 +273,7 @@ static int ConfCheckLimits(void *pData, float fVal, char *error, int errLen){
pInfo->lastValue = pEventData->fVal;
(pInfo->pCon)->conEventType=POSITION;
sprintf(pBueffel,"%s.position = %f ", pInfo->pName, pInfo->lastValue);
SCWriteInContext(pInfo->pCon,pBueffel,eEvent,cc);
SCWrite(pInfo->pCon,pBueffel,eEvent);
}
return 1;
}
@ -552,7 +560,7 @@ int ConfigurableVirtualMotorAction(SConnection *pCon, SicsInterp *pSics,
return 0;
}
pRegInfo->pName = strdup(argv[0]);
pRegInfo->pCon = pCon;
pRegInfo->pCon = SCCopyConnection(pCon);
value = ConfGetValue(self,pCon);
if(!iRet)
{
@ -562,8 +570,8 @@ int ConfigurableVirtualMotorAction(SConnection *pCon, SicsInterp *pSics,
}
pRegInfo->lastValue = value;
lID = RegisterCallback(self->pCall, SCGetContext(pCon),MOTDRIVE, InterestCallback, pRegInfo, KillInfo);
SCRegister(pCon,pSics, self->pCall,lID);
lID = RegisterCallback(self->pCall, MOTDRIVE,
InterestCallback, pRegInfo, KillInfo);
SCSendOK(pCon);
return 1;
} else {

889
conman.c

File diff suppressed because it is too large Load Diff

164
conman.h
View File

@ -1,4 +1,3 @@
/*--------------------------------------------------------------------------
C O N N E C T I O N O B J E C T
@ -15,6 +14,10 @@
Mark Koennecke, December 2004
copyright: see copyright.h
substantially for the new asynchronous I/O system
Mark Koennecke, January 2009
----------------------------------------------------------------------------*/
#ifndef SICSCONNECT
#define SICSCONNECT
@ -22,6 +25,7 @@
#include "costa.h"
#include "SCinter.h"
#include "network.h"
#include "asynnet.h"
#include "obdes.h"
#include "commandcontext.h"
#include "dynstring.h"
@ -32,80 +36,57 @@ typedef int (*writeFunc)(struct __SConnection *pCon,
char *pMessage, int iCode);
typedef struct __SConnection {
/* object basics */
pObjectDescriptor pDes;
long lMagic;
long ident;
struct __SConnection *next;
/* I/O control */
/* our socket */
mkChannel *pSock;
/* per connection log files */
FILE *pFiles[MAXLOGFILES];
int iFiles;
int iMacro; /* suppress I/O in macro*/
/* Copy Object Fields*/
pObjectDescriptor pDes; /* must be here */
long lMagic; /* connection object ID */
long ident; /* connection idetification */
struct __SConnection *next; /* pointer for freeConnection managenment */
int sockHandle; /* socket handle */
int iTelnet; /* telnet flag */
int iOutput;
writeFunc write; /* function doing
writing */
int listening; /* for listening to commandlog or other data */
/* execution context */
int eInterrupt;
int iUserRights;
int inUse;
int iGrab; /* grab flag for token*/
int sicsError;
/*
* for I/O Buffering
*/
pDynString data;
writeFunc oldWriteFunc;
/*
stuff supporting the sycamore protocol and a
command context
*/
long iCmdCtr;
int conEventType;
int iMacro; /* suppress I/O in macro */
writeFunc write; /* function doing writing */
int sicsError; /* Tcl interpreter requirement */
pDynString data; /* for I/O buffering */
writeFunc oldWriteFunc; /* saved write function used in I/O buffering */
long iCmdCtr; /* sycamore protocol used */
int conEventType; /* sycamore protocol support */
int conStatus; /* should use status enum ffr */
int iProtocolID;
int contextStack;
int transID; /* transaction ID */
char deviceID[256]; /* transaction device ID */
int iUserRights; /* user rights of the connection */
/* a FIFO */
pCosta pStack;
/* callback registry */
int iList;
/* Tasking Stuff */
int iEnd;
/* for keeping track of the login
process on a non telnet connection.
Should only be used in SCTaskFunction
*/
int iLogin;
time_t conStart;
/* master connection object fields */
int iList; /* callback registry, may go? */
int iEnd; /* flag to end connection task */
int iLogin; /* flag for successful login process */
time_t conStart; /* time when connection was built: used during login */
int iOutput; /* output filter flag */
int listening; /* for listening to commandlog or other data */
int eInterrupt; /* interrupts */
int inUse; /* usage counter for the connection */
int iGrab; /* grab flag for token*/
int iProtocolID; /* ID of the protocol on this connection */
pCosta pStack; /* stack of pending commands */
int contextStack; /* context stack: may go? */
mkChannel *pSock; /* for temporary backwards compatability */
} SConnection;
#include "nserver.h"
/*------------------------------ live & death ----------------------------*/
SConnection *SCreateConnection(SicsInterp *pSics, mkChannel *pSock,
SConnection *SCreateConnection(SicsInterp *pSics, int sockHandle,
int iUserRights);
SConnection *SCCreateDummyConnection(SicsInterp *pSics);
void SCDeleteConnection(void *pVictim);
SConnection *SCCopyConnection(SConnection *pCon);
SConnection *SCfindMaster(SConnection *pCon);
int SCisConnected(SConnection *pCon);
int VerifyConnection(SConnection *pCon);
int SCVerifyConnection(SConnection *self);
/*------------------------------- tasking --------------------------------*/
int SCTaskFunction(void *pCon);
void SCSignalFunction(void *pCon, int iSignal, void *pSigData);
/* ***************************** I/O ************************************** */
int SCAddLogFile(SConnection *self, char *name);
int SCDelLogFile(SConnection *pCon, int iFile);
void SCSetOutputClass(SConnection *self, int iClass);
int SCWrite(SConnection *self, char *pBuffer, int iOut);
int SCPrintf(SConnection *self, int iOut, char *fmt, ...);
@ -126,21 +107,6 @@ typedef int (*writeFunc)(struct __SConnection *pCon,
/*********************** I/O Buffering ***********************************/
int SCStartBuffering(SConnection *pCon);
pDynString SCEndBuffering(SConnection *pCon);
/************************* CallBack *********************************** */
int SCRegister(SConnection *pCon, SicsInterp *pSics,
void *pInter, long lID);
int SCUnregister(SConnection *pCon, void *pInter);
/**
* delete a callback with the given ID
*/
int SCUnregisterID(SConnection *pCon, long ID);
/**
* retrieve the ID of a callback on the callback interface
* given in pData. This, together with SCUnregisterID allows to
* ceanly remove all callbacks on a connection
* returns -1 if no ID can be found.
*/
long SCgetCallbackID(SConnection *pCon, void *pData);
/******************************* Error **************************************/
void SCSetInterrupt(SConnection *self, int eCode);
int SCGetInterrupt(SConnection *self);
@ -156,9 +122,6 @@ typedef int (*writeFunc)(struct __SConnection *pCon,
int SCGetOutClass(SConnection *self);
int SCGetGrab(SConnection *pCon);
int SCActive(SConnection *pCon);
/********************* simulation mode ************************************/
void SCSetSimMode(SConnection *pCon, int value);
int SCinSimMode(SConnection *pCon);
/* **************************** Invocation ******************************** */
int SCInvoke(SConnection *self,SicsInterp *pInter,char *pCommand);
@ -167,6 +130,23 @@ typedef int (*writeFunc)(struct __SConnection *pCon,
int argc, char *argv[]);
int ConSicsAction(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]);
/*------------------------------------------------------------------------*/
int SCDoSockWrite(SConnection *self, char *buffer);
int SCWriteInContext(SConnection *pCon, char *buffer, int code, commandContext cc);
/* ================== =====================================================
* These routines are obsolete and may not even work anymore.
* Mark Koennecke, January 2009
* ==========================================================================*/
void SCWriteToLogFiles(SConnection *self, char *buffer);
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);
/******************************** Store ************************************/
typedef struct SCStore SCStore;
@ -189,18 +169,20 @@ void SCStoreFree(SCStore *conStore);
/* free an SCStore */
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);
/************************* CallBack *********************************** */
int SCRegister(SConnection *pCon, SicsInterp *pSics,
void *pInter, long lID);
int SCUnregister(SConnection *pCon, void *pInter);
/**
* delete a callback with the given ID
*/
int SCUnregisterID(SConnection *pCon, long ID);
/**
* retrieve the ID of a callback on the callback interface
* given in pData. This, together with SCUnregisterID allows to
* ceanly remove all callbacks on a connection
* returns -1 if no ID can be found.
*/
long SCgetCallbackID(SConnection *pCon, void *pData);
#endif

View File

@ -96,6 +96,10 @@
self = (pCounter)pData;
assert(self);
if(!GetCountLock(self->pCountInt, pCon)){
return 0;
}
/* try at least three times to do it */
for(i = 0; i < 3; i++)
{
@ -118,12 +122,14 @@
{
SCWrite(pCon,"ERROR: Cannot fix counter problem, aborting",eError);
SCSetInterrupt(pCon,eAbortBatch);
ReleaseCountLock(self->pCountInt);
return HWFault;
}
}
}
SCWrite(pCon,"ERROR: Cannot fix counter problem, aborting",eError);
SCSetInterrupt(pCon,eAbortBatch);
ReleaseCountLock(self->pCountInt);
return HWFault;
}
/*-----------------------------------------------------------------------*/
@ -235,6 +241,7 @@
SCWrite(pCon,"ERROR: Cannot fix counter problem, aborting",eError);
SCSetInterrupt(pCon,eAbortBatch);
InvokeCallBack(self->pCall,COUNTEND,NULL);
ReleaseCountLock(self->pCountInt);
return eCt;
}
else
@ -267,6 +274,7 @@
if(eCt == HWIdle)
{
InvokeCallBack(self->pCall,COUNTEND,NULL);
ReleaseCountLock(self->pCountInt);
}
return eCt;
}
@ -462,7 +470,7 @@
if(!iRet)
{
SetStatus(eOld);
SCWrite(pCon,"Counting aborted",eStatus);
SCWrite(pCon,"Counting aborted",eError);
return 0;
}
@ -476,16 +484,16 @@
iRet = Wait4Success(GetExecutor());
if(iRet == DEVINT)
{
SCWrite(pCon,"Counting aborted due to Interrupt",eStatus);
SCWrite(pCon,"Counting aborted due to Interrupt",eError);
}
else if(iRet == DEVERROR)
{
SCWrite(pCon,"Counting finished with Problems",eStatus);
SCWrite(pCon,"Counting finished with Problems",eError);
iRet = 1;
}
else
{
SCWrite(pCon,"Counting finished",eStatus);
SCWrite(pCon,"Counting finished",eValue);
iRet = 1;
}
SetStatus(eOld);
@ -715,15 +723,18 @@
return 1;
}
/*-----------------------------------------------------------------------*/
static int CounterInterest(int iEvent, void *pEvent, void *pUser,
commandContext cc)
static int CounterInterest(int iEvent, void *pEvent, void *pUser)
{
SConnection *pCon = NULL;
pMonEvent pMon = NULL;
char pBueffel[512];
int rights;
if(iEvent != MONITOR)
if(pCon == NULL || !SCisConnected(pCon)){
return -1;
}
if(iEvent != MONITOR || pCon == NULL)
{
return 0;
}
@ -737,10 +748,8 @@
/**
* prevent this to be written to log files
*/
rights = SCGetRights(pCon);
SCSetRights(pCon,usSpy);
SCWriteInContext(pCon,pBueffel,eWarning,cc);
SCSetRights(pCon,rights);
SCWrite(pCon,pBueffel,eWarning);
return 1;
}
/*-----------------------------------------------------------------------*/
@ -817,6 +826,10 @@
return 1;
break;
case 2: /* Set Preset */
if(isRunning(self->pCountInt)){
SCWrite(pCon,"ERROR: cannot change preset while counting", eError);
return 0;
}
if(isAuthorised(pCon,usUser))
{
iRet2 = SetCounterPreset(self,PaRes.Arg[0].fVal);
@ -844,6 +857,10 @@
return 1;
break;
case 4: /* Set Mode */
if(isRunning(self->pCountInt)){
SCWrite(pCon,"ERROR: cannot change mode while counting", eError);
return 0;
}
if(isAuthorised(pCon,usUser))
{
if(strcmp(PaRes.Arg[0].text,"timer") == 0)
@ -905,13 +922,13 @@
SCWrite(pCon,pBueffel,eValue);
return 1;
case 9: /* interest */
lID = RegisterCallback(self->pCall, SCGetContext(pCon), MONITOR, CounterInterest,
pCon, NULL);
SCRegister(pCon,pSics, self->pCall,lID);
lID = RegisterCallback(self->pCall, MONITOR, CounterInterest,
SCCopyConnection(pCon),
SCDeleteConnection);
SCSendOK(pCon);
return 1;
case 10: /* uninterest */
RemoveCallback2(self->pCall,pCon);
RemoveCallbackCon(self->pCall,pCon);
SCSendOK(pCon);
return 1;
case 11: /* status */
@ -1008,6 +1025,10 @@
/* mode */
if(PaRes.Arg[0].iVal) /* set case */
{
if(isRunning(self->pCountInt)){
SCWrite(pCon,"ERROR: cannot change mode while counting",eError);
return 0;
}
if(isAuthorised(pCon,usUser))
{
if(strcmp(PaRes.Arg[0].text,"timer") == 0)
@ -1053,6 +1074,10 @@
case 18: /* preset */
if(PaRes.Arg[0].iVal) /* set case */
{
if(isRunning(self->pCountInt)){
SCWrite(pCon,"ERROR: cannot set preset while counting", eError);
return 0;
}
if(isAuthorised(pCon,usUser))
{
iRet2 = SetCounterPreset(self,PaRes.Arg[0].fVal);
@ -1095,6 +1120,10 @@
}
break;
case 20: /* setpar*/
if(isRunning(self->pCountInt)){
SCWrite(pCon,"ERROR: cannot change parameters while counting", eError);
return 0;
}
if(!SCMatchRights(pCon,usMugger))
{
return 0;

20
danu.c
View File

@ -95,14 +95,19 @@ static int writeDataNumber(pDataNumber self, int iNum)
return 1;
}
/*------------------- The CallBack function for interest ------------------*/
static int InterestCallback(int iEvent, void *pEvent, void *pUser,
commandContext cc)
static int InterestCallback(int iEvent, void *pEvent, void *pUser)
{
pDataNumber self = NULL;
SConnection *pCon = NULL;
char pBueffel[132];
int iNum;
pCon = (SConnection *)pUser;
if(pCon == NULL || !SCisConnected(pCon))
{
return -1;
}
if(iEvent != VALUECHANGE)
{
return 1;
@ -111,7 +116,6 @@ static int writeDataNumber(pDataNumber self, int iNum)
assert(pEvent);
assert(pUser);
pCon = (SConnection *)pUser;
self = (pDataNumber)pEvent;
/*
@ -121,7 +125,7 @@ static int writeDataNumber(pDataNumber self, int iNum)
if(iNum > 0)
{
snprintf(pBueffel,131,"sicsdatanumber = %d", iNum);
SCWriteInContext(pCon,pBueffel,eValue,cc);
SCWrite(pCon,pBueffel,eValue);
}
return 1;
}
@ -331,16 +335,16 @@ int NewThousand(pDataNumber self)
}
if(strcmp(argv[1],"interest") == 0)
{
lID = RegisterCallback(self->pCall, SCGetContext(pCon),
lID = RegisterCallback(self->pCall,
VALUECHANGE, InterestCallback,
pCon, NULL);
SCRegister(pCon,pSics, self->pCall,lID);
SCCopyConnection(pCon),
SCDeleteConnection);
SCSendOK(pCon);
return 1;
}
if(strcmp(argv[1],"uninterest") == 0)
{
RemoveCallback2(self->pCall,pCon);
RemoveCallbackCon(self->pCall,pCon);
SCSendOK(pCon);
}

282
devexec.c
View File

@ -12,6 +12,9 @@
Refactored and instrumentation for instrument staticstics added.
Mark Koennecke, July 2006
Reworked to use copied connection objects instead of context pushes.
Mark Koennecke, January 2009
Copyright:
Labor fuer Neutronenstreuung
@ -113,7 +116,7 @@ void DevexecLog(char *operation, char *device) {
pObjectDescriptor pDescriptor;
float fVal;
char *name;
commandContext comCon;
SConnection *pCon;
} DevEntry, *pDevEntry;
/*------------------------------------------------------------------------*/
typedef struct {
@ -123,7 +126,8 @@ typedef struct {
pIDrivable pDrivInt;
}checkContext, *pCheckContext;
/*-------------------------------------------------------------------------*/
static pDevEntry CreateDevEntry(pObjectDescriptor pDes, void *pData,
static pDevEntry CreateDevEntry(pObjectDescriptor pDes, SConnection *pCon,
void *pData,
float fVal, char *name)
{
pDevEntry pNew = NULL;
@ -139,7 +143,7 @@ typedef struct {
pNew->pData = pData;
pNew->name = strdup(name);
pNew->fVal = fVal;
memset(&pNew->comCon,0,sizeof(commandContext));
pNew->pCon = SCCopyConnection(pCon);
return pNew;
}
/*-------------------------------------------------------------------------*/
@ -151,9 +155,11 @@ typedef struct {
{
free(self->name);
}
if(self->pCon){
SCDeleteConnection(self->pCon);
}
free(self);
}
/* ----------------- The Executor himself ---------------------------------*/
typedef struct __EXELIST{
pObjectDescriptor pDes;
@ -242,6 +248,11 @@ typedef struct {
if(self->pCall)
DeleteCallBackInterface(self->pCall);
if(self->pOwner){
SCDeleteConnection(self->pOwner);
self->pOwner = NULL;
}
free(self);
pServ->pExecutor = NULL;
if(devLog != NULL){
@ -279,7 +290,7 @@ typedef struct {
/* may we? */
if(self->pOwner != NULL)
{
if(pCon != self->pOwner)
if(pCon->ident != self->pOwner->ident)
{
/* this hack helps on rita2, when using the sendsics script
which opens a client for every command */
@ -288,7 +299,8 @@ typedef struct {
overwriteOwner = overwriteOption && *overwriteOption != '0';
}
if (overwriteOwner) {
self->pOwner = pCon;
SCDeleteConnection(self->pOwner);
self->pOwner = SCCopyConnection(pCon);
} else {
SCWrite(pCon,
"ERROR: somebody else is still driving, Request rejected",eError);
@ -298,7 +310,7 @@ typedef struct {
}
else
{
self->pOwner = pCon;
self->pOwner = SCCopyConnection(pCon);
}
if(self->iLock == 1)
{
@ -308,14 +320,12 @@ typedef struct {
/* well create a new entry */
self->iStop = 0;
pNew = CreateDevEntry(pDes,pData,fNew,name);
pNew = CreateDevEntry(pDes,pCon,pData,fNew,name);
if(!pNew)
{
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);
@ -328,7 +338,7 @@ typedef struct {
oldVal = pDrivInt->GetValue(pData,pCon);
snprintf(pBueffel,131,"Driving %s from %8.3f to %8.3f",
name, oldVal, fNew);
SCWrite(pCon,pBueffel,eWarning);
SCWrite(pCon,pBueffel,eValue);
}
}
else if(pCountInt)
@ -346,9 +356,9 @@ typedef struct {
{
LLDnodeAppendFrom(self->iList,&pNew);
sprintf(pBueffel,"started");
if(NULL!=pNew->comCon.deviceID)
if(NULL!=pNew->pCon->deviceID)
{
snprintf(pBueffel,130,"started (%s)",pNew->comCon.deviceID);
snprintf(pBueffel,130,"started (%s)",pNew->pCon->deviceID);
}
ExeInterest(self, pNew, pBueffel);
self->iRun = 1;
@ -375,13 +385,15 @@ typedef struct {
DeleteDevEntry(pNew);
if(LLDcheck(self->iList) >= LIST_EMPTY)
{
if(self->pOwner != NULL){
SCDeleteConnection(self->pOwner);
}
self->pOwner = NULL;
}
return 0;
}
return 0;
}
/*-----------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
int StartMotor(pExeList self, SicsInterp *pSics, SConnection *pCon,
char *name, float fVal)
@ -467,183 +479,10 @@ typedef struct {
return StartDevice(self,name,pCter->pDes,(void *)pCter,
pCon,pCter->pDriv->fPreset);
}
/*--------------------------------------------------------------------------*/
int CheckExeListOld(pExeList self)
{
int iRet;
pDevEntry pDev = NULL;
pICountable pCountInt = NULL;
pIDrivable pDrivInt = NULL;
int eCode;
int isCounting=0, isDriving=0;
char pBueffel[512];
SConnection *pCon;
pCon = self->pOwner;
assert(self);
/* Sometimes this gets called, though nothing is running. There are
cases where this is feasible for maintainance, but in some cases it
is pure rubbish, because nothing runs. This will be checked here.
*/
if((self->pOwner == NULL) || (LLDcheck(self->iList) == LIST_EMPTY))
{
self->iRun = 0;
self->iEnd = 1;
self->iStop = 0;
return 1;
}
/*
check the status of all registered devices. Remove when finished
*/
iRet = LLDnodePtr2First(self->iList);
while(iRet != 0)
{
LLDnodeDataTo(self->iList,&pDev);
if(pDev)
{
SCPushContext(self->pOwner, pDev->comCon.transID, pDev->comCon.deviceID);
pDrivInt = pDev->pDescriptor->GetInterface(pDev->pData,DRIVEID);
pCountInt = pDev->pDescriptor->GetInterface(pDev->pData,COUNTID);
if(pDrivInt)
{
eCode = pDrivInt->CheckStatus(pDev->pData,self->pOwner);
}
else if(pCountInt)
{
eCode = pCountInt->CheckCountStatus(pDev->pData,self->pOwner);
}
switch(eCode)
{
case HWIdle:
case OKOK:
if(pCountInt)
{
pCountInt->TransferData(pDev->pData,self->pOwner);
}
else if(pDrivInt)
{
pDrivInt->iErrorCount = 0;
}
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;
break;
case HWFault: /* real HW error: burning, no net etc.. */
ExeInterest(self, pDev, "finished with problem");
DeleteDevEntry(pDev);
pDev = NULL;
SCWrite(pCon, "", eFinish);
LLDnodeDataTo(self->iList,&pDev);
LLDnodeDelete(self->iList);
iRet = LLDnodePtr2Prev(self->iList);
self->iStatus = DEVERROR;
if(pDrivInt)
{
pDrivInt->iErrorCount++;
}
if(SCGetInterrupt(self->pOwner) != eContinue)
{
self->iStatus = DEVINT;
SCPopContext(self->pOwner);
return -1;
}
break;
case HWNoBeam:
SetStatus(eOutOfBeam);
if(SCGetInterrupt(self->pOwner) != eContinue)
{
SetStatus(eEager);
self->iStatus = DEVINT;
SCPopContext(self->pOwner);
return -1;
}
break;
case HWPause:
SetStatus(ePaused);
if(SCGetInterrupt(self->pOwner) != eContinue)
{
ContinueExecution(self);
self->iStatus = DEVINT;
SCPopContext(self->pOwner);
return -1;
}
break;
case HWBusy:
if(pDrivInt != NULL)
{
isDriving = 1;
}
else if(pCountInt != NULL)
{
isCounting = 1;
}
self->iStatus = DEVBUSY;
break;
case HWPosFault: /* cannot get somewhere... */
ExeInterest(self, pDev, "finished with problem");
DeleteDevEntry(pDev);
LLDnodeDelete(self->iList);
SCWrite(pCon, "", eFinish);
self->iStatus = DEVERROR;
if(pDrivInt)
{
pDrivInt->iErrorCount++;
}
if(SCGetInterrupt(self->pOwner) != eContinue)
{
self->iStatus = DEVINT;
SCPopContext(self->pOwner);
return -1;
}
break;
}
SCPopContext(self->pOwner);
}
iRet = LLDnodePtr2Next(self->iList);
}
if (isCounting) {
if (isDriving) {
SetStatus(eCountDrive);
} else {
SetStatus(eCounting);
}
} else if (isDriving) {
SetStatus(eDriving);
}
iRet = LLDnodePtr2First(self->iList);
if(LLDcheck(self->iList) == LIST_EMPTY)
{
self->pOwner = NULL;
self->iEnd = 1;
self->iRun = 0;
self->lTask = -1;
return 1;
}
else
{
return 0;
}
}
/*-------------------------------------------------------------------------*/
static int checkInterrupt(pCheckContext pCheck, int targetStatus){
if(SCGetInterrupt(pCheck->self->pOwner) != eContinue) {
pCheck->self->iStatus = DEVINT;
SCPopContext(pCheck->self->pOwner);
SetStatus(eEager);
return -1;
} else {
@ -654,15 +493,13 @@ static int checkInterrupt(pCheckContext pCheck, int targetStatus){
static int initializeCheck(pCheckContext pCheck, pDevEntry pDev){
int eCode = HWFault;
SCPushContext(pCheck->self->pOwner,
pDev->comCon.transID, pDev->comCon.deviceID);
pCheck->pDev = pDev;
pCheck->pDrivInt = pDev->pDescriptor->GetInterface(pDev->pData,DRIVEID);
pCheck->pCountInt = pDev->pDescriptor->GetInterface(pDev->pData,COUNTID);
if(pCheck->pDrivInt != NULL){
eCode = pCheck->pDrivInt->CheckStatus(pDev->pData,pCheck->self->pOwner);
eCode = pCheck->pDrivInt->CheckStatus(pDev->pData,pDev->pCon);
} else if(pCheck->pCountInt != NULL) {
eCode = pCheck->pCountInt->CheckCountStatus(pDev->pData,pCheck->self->pOwner);
eCode = pCheck->pCountInt->CheckCountStatus(pDev->pData,pDev->pCon);
}
return eCode;
}
@ -671,7 +508,7 @@ static int finishDevice(pCheckContext pCheck){
int status;
if(pCheck->pCountInt != NULL) {
pCheck->pCountInt->TransferData(pCheck->pDev->pData,pCheck->self->pOwner);
pCheck->pCountInt->TransferData(pCheck->pDev->pData,pCheck->pDev->pCon);
} else if(pCheck->pDrivInt != NULL) {
pCheck->pDrivInt->iErrorCount = 0;
}
@ -704,6 +541,9 @@ static int errorDevice(pCheckContext pCheck){
/*-------------------------------------------------------------------------*/
static int testFinish(pExeList self){
if((self->pOwner == NULL) || (LLDcheck(self->iList) == LIST_EMPTY)) {
if(self->pOwner != NULL){
SCDeleteConnection(self->pOwner);
}
self->pOwner = NULL;
self->iRun = 0;
self->iEnd = 1;
@ -725,8 +565,6 @@ static int testFinish(pExeList self){
int eCode;
int isCounting=0, isDriving=0;
char pBueffel[512];
SConnection *pCon;
pCon = self->pOwner;
assert(self);
@ -812,7 +650,6 @@ static int testFinish(pExeList self){
}
break;
}
SCPopContext(self->pOwner);
}
status = LLDnodePtr2Next(self->iList);
}
@ -866,12 +703,12 @@ static int testFinish(pExeList self){
iRet = CheckExeList(self);
if(iRet == 1) /* nothing to do! */
{
SCWrite(pCon,"Machine idle",eStatus);
SCWrite(pCon,"Machine idle",eValue);
return 1;
}
else if(iRet == -1)
{
SCWrite(pCon,"Handling Interrupt",eStatus);
SCWrite(pCon,"Handling Interrupt",eError);
return 0;
}
@ -884,7 +721,7 @@ static int testFinish(pExeList self){
if(pDev)
{
sprintf(pBueffel,"\t%s %f",pDev->name,pDev->fVal);
SCWrite(pCon,pBueffel,eStatus);
SCWrite(pCon,pBueffel,eValue);
}
iRet = LLDnodePtr2Next(self->iList);
}
@ -949,9 +786,7 @@ static int testFinish(pExeList self){
}
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;
@ -1009,12 +844,10 @@ static int testFinish(pExeList self){
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)
{
iRet = pCountInt->Pause(pDev->pData,self->pOwner);
iRet = pCountInt->Pause(pDev->pData,pDev->pCon);
if(!iRet)
{
iRes = 0;
@ -1022,7 +855,6 @@ static int testFinish(pExeList self){
}
}
SCPopContext(self->pOwner);
iRet = LLDnodePtr2Next(self->iList);
}
SetStatus(ePaused);
@ -1072,13 +904,11 @@ static int testFinish(pExeList self){
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);
iRet = pCountInt->Continue(pDev->pData,pDev->pCon);
if(!iRet)
{
iRes = 0;
}
SCPopContext(self->pOwner);
}
}
@ -1113,6 +943,7 @@ static int testFinish(pExeList self){
{
self->iStatus = DEVINT;
}
SCDeleteConnection(self->pOwner);
}
self->pOwner = NULL;
self->iEnd = 1;
@ -1156,15 +987,17 @@ static int testFinish(pExeList self){
return iRet;
}
/*------------------- The CallBack function for interest ------------------*/
static int DrivStatCallback(int iEvent, void *text, void *pCon,
commandContext cc)
static int DrivStatCallback(int iEvent, void *text, void *pCon)
{
assert(pCon);
assert(text);
SConnection *con = (SConnection *)pCon;
SCPushContext2(pCon,cc);
SCWrite(pCon, text, eValue);
SCPopContext(pCon);
if(con == NULL || !SCisConnected(con))
{
return -1;
}
SCWrite(pCon, text, eLog);
return 1;
}
/*--------------------------------------------------------------------------*/
@ -1183,17 +1016,15 @@ static int testFinish(pExeList self){
if (argc == 2) {
if (strcmp(argv[1], "interest") == 0)
{
list = RegisterCallback(self->pCall, SCGetContext(pCon),
list = RegisterCallback(self->pCall,
DRIVSTAT, DrivStatCallback,
pCon, NULL);
SCRegister(pCon, pSics, self->pCall,list);
SCCopyConnection(pCon), NULL);
SCSendOK(pCon);
return 1;
}
if (strcmp(argv[1], "uninterest") == 0)
{
RemoveCallback2(self->pCall, pCon);
SCUnregister(pCon, self->pCall);
RemoveCallbackCon(self->pCall,pCon);
SCSendOK(pCon);
return 1;
}
@ -1240,12 +1071,12 @@ static int testFinish(pExeList self){
}
else if(iRet == DEVDONE)
{
SCWrite(pCon,"All done",eStatus);
SCWrite(pCon,"All done",eValue);
iRet = 1;
}
else if(iRet == DEVERROR)
{
SCWrite(pCon,"Finished with Problems",eStatus);
SCWrite(pCon,"Finished with Problems",eValue);
iRet = 1;
}
SetStatus(eEager);
@ -1422,6 +1253,7 @@ static int testFinish(pExeList self){
{
int *iInt;
pExeList self = NULL;
SConnection *pCon = NULL;
self = (pExeList)pEL;
assert(self);
@ -1433,12 +1265,16 @@ static int testFinish(pExeList self){
{
if(self->pOwner)
{
SCPushContext(self->pOwner,0,"system");
SCWrite(self->pOwner,
pCon = SCCopyConnection(self->pOwner);
if(pCon != NULL){
pCon->transID = 0;
strcpy(pCon->deviceID,"system");
SCWrite(pCon,
"ERROR: Interrupting Current Hardware Operation",
eError);
SCSetInterrupt(self->pOwner,*iInt);
SCPopContext(self->pOwner);
SCSetInterrupt(pCon,*iInt);
SCDeleteConnection(pCon);
}
}
StopExe(self,"all");
}

View File

@ -217,7 +217,13 @@ void DevKill(DevSer *devser) {
}
}
void DevQueue(DevSer *devser, void *actionData, DevPrio prio,
void DevDisconnect(DevSer *devser){
if(devser->asyncConn){
AsconDisconnect(devser->asyncConn);
}
}
int DevQueue(DevSer *devser, void *actionData, DevPrio prio,
DevActionHandler hdl, DevActionMatch *matchFunc,
DevKillActionData *killFunc) {
DevAction *action, **ptr2Last;
@ -228,13 +234,14 @@ void DevQueue(DevSer *devser, void *actionData, DevPrio prio,
ptr2Last = &devser->actions;
for (action = devser->actions; action != NULL && action->prio >= prio; action = action->next) {
if (action->hdl == hdl && matchFunc(actionData, action->data)) {
return; /* there is already an identical action */
return 0; /* there is already an identical action */
}
ptr2Last = &action->next;
}
new = DevNewAction(actionData, hdl, killFunc, prio);
new->next = action;
*ptr2Last = new;
return 1;
}
int DevUnschedule(DevSer *devser, void *actionData,

View File

@ -54,6 +54,10 @@ void DevDebugMode(DevSer *devser, int steps);
* \param devser the device serializer
*/
void DevKill(DevSer *devser);
/** \brief Disconnect
* \param devser The device serializer to disconnect
*/
void DevDisconnect(DevSer *devser);
/** \brief Queue an action
*
@ -67,8 +71,10 @@ void DevKill(DevSer *devser);
* \param killFunc the action data kill function (called from DevKill and
* after the action has finished, i.e. when hdl returned NULL)
* or NULL if no kill function is needed.
* \return 0 when not queued because a similar action is already on the queue,
* 1 on success.
*/
void DevQueue(DevSer *devser, void *actionData, DevPrio prio,
int DevQueue(DevSer *devser, void *actionData, DevPrio prio,
DevActionHandler hdl, DevActionMatch *matchFunc,
DevKillActionData *killFunc) ;

View File

@ -312,7 +312,7 @@ static int DiffScanTask(void *pData){
if(data->Monitors[self->scaleMonitor -1] -
self->last.Monitors[self->scaleMonitor-1] < 5) {
SCWrite(self->scanObject->pCon,
"WARNING: low count rate",eWarning);
"WARNING: low count rate",eLog);
}
rawCount = data->lCount;
rawMon = data->Monitors[self->scaleMonitor-1];
@ -329,7 +329,7 @@ static int DiffScanTask(void *pData){
self->scanObject->iCounts -1,
fPos, countValue, rawCount,
rawMon);
SCWrite(self->scanObject->pCon,pBueffel,eWarning);
SCWrite(self->scanObject->pCon,pBueffel,eLog);
InvokeCallBack(self->scanObject->pCall,SCANPOINT,self->scanObject);
/*

View File

@ -131,21 +131,21 @@
{
SCSetInterrupt(pCon,eContinue);
sprintf(pBueffel,"Driving %s aborted at %9.3f",name, fPos);
SCWrite(pCon,pBueffel,eStatus);
SCWrite(pCon,pBueffel,eError);
}
return 0;
}
else if(iRet == DEVDONE)
{
sprintf(pBueffel,"Driving %s to %9.3f done", name, fPos);
SCWrite(pCon,pBueffel,eStatus);
SCWrite(pCon,pBueffel,eValue);
return 1;
}
else
{
sprintf(pBueffel,
"Driving %s finished with problems, position: %9.3f",name,fPos);
SCWrite(pCon,pBueffel,eStatus);
SCWrite(pCon,pBueffel,eValue);
return 1;
}
}
@ -393,7 +393,7 @@
SetStatus(eOld);
return 0;
}
SCWrite(pCon,"Driving finished sucessfully",eStatus);
SCWrite(pCon,"Driving finished sucessfully",eValue);
SetStatus(eOld);
return 1;
}

View File

@ -254,6 +254,19 @@
return self->iTextLen;
}
/*---------------------------------------------------------------------------*/
int DynStringBackspace(pDynString self)
{
assert(self);
assert(self->iMAGIC == DYNMAGIC);
if(self->iTextLen > 0)
{
self->pBuffer[self->iTextLen - 1] = '\0';
self->iTextLen--;
}
return 1;
}

View File

@ -87,6 +87,10 @@
int DynStringClear(pDynString self);
/*
removes all old dat from the dynstring
removes all old data from the dynstring
*/
int DynStringBackspace(pDynString self);
/*
removes one character at the end from the dynstring
*/
#endif

View File

@ -100,7 +100,14 @@
self->start = time(NULL);
self->lastt = 0;
self->iWarned = 0;
self->conn = SCSave(pCon, self->conn);
if(self->conn != NULL){
SCDeleteConnection(self->conn);
}
self->conn = SCCopyConnection(pCon);
if(self->conn == NULL){
SCWrite(pCon,"ERROR: out of memory in EVIDrive", eError);
return 0;
}
/* try at least three times to do it */
for(i = 0; i < 3; i++)
@ -302,7 +309,7 @@
{
sprintf(pBueffel,"%s inside tolerance, wait %.2f sec to settle",
self->pName, (self->lastt + tmo - now)*1.0);
SCWrite(pCon,pBueffel,eWarning);
SCWrite(pCon,pBueffel,eLog);
}
notifyStatus(self, pCon, HWBusy);
return HWBusy;
@ -322,7 +329,7 @@
if (tmo > 0) {
sprintf(pBueffel,"%s outside tolerance, settling time suspended",
self->pName);
SCWrite(pCon,pBueffel,eWarning);
SCWrite(pCon,pBueffel,eLog);
}
self->lastt -= now;
}
@ -376,7 +383,7 @@
}
/*---------------------------- Error Handlers --------------------------------*/
static void ErrWrite(char *txt, SCStore *conn)
static void ErrWrite(char *txt, SConnection *conn)
{
pExeList pExe;
SConnection *pCon = NULL;
@ -386,13 +393,11 @@ static void ErrWrite(char *txt, SCStore *conn)
if (pCon)
{
SCWrite(pCon,txt,eWarning);
SCWrite(pCon,txt,eLog);
}
else
{
pCon = SCStorePush(conn);
SCWrite(pCon, txt, eWarning);
SCStorePop(conn);
SCWrite(conn, txt, eLog);
}
}
/*-----------------------------------------------------------------------*/
@ -436,7 +441,7 @@ static void ErrReport(pEVControl self)
pExe = GetExecutor();
if(IsCounting(pExe))
{
SCWrite(GetExeOwner(pExe),"Pausing till OK",eError);
SCWrite(GetExeOwner(pExe),"Pausing till OK",eLogError);
PauseExecution(pExe);
/* wait till OK */
@ -796,7 +801,10 @@ static void ErrReport(pEVControl self)
pRes->pName = strdup(pName);
pRes->eMode = EVIdle;
pRes->iWarned = 0;
if(pRes->conn != NULL){
SCDeleteConnection(pRes->conn);
pRes->conn = NULL;
}
/* a terminal error gives a -1 in iRet */
if(iRet < 0)
@ -871,7 +879,7 @@ static void ErrReport(pEVControl self)
}
if (self->conn != NULL)
{
SCStoreFree(self->conn);
SCDeleteConnection(self->conn);
}
free(self);
}
@ -1064,17 +1072,21 @@ static void ErrReport(pEVControl self)
return 1;
}
/*-------------------------------------------------------------------------*/
static int EVCallBack(int iEvent, void *pEventData, void *pUserData,
commandContext cc)
static int EVCallBack(int iEvent, void *pEventData, void *pUserData)
{
char *pBuf = (char *)pEventData;
SConnection *pCon = (SConnection *)pUserData;
char pBueffel[132];
if(iEvent == VALUECHANGE)
if(pCon == NULL || !SCisConnected(pCon))
{
return -1;
}
if(iEvent == VALUECHANGE && pCon != NULL)
{
pCon->conEventType=POSITION;
SCWriteInContext(pCon,pBuf,eEvent,cc);
SCWrite(pCon,pBuf,eEvent);
return 1;
}
return 1;
@ -1135,16 +1147,15 @@ static void ErrReport(pEVControl self)
/* install automatic notification */
else if(strcmp(argv[1],"interest") == 0)
{
lID = RegisterCallback(self->pCall, SCGetContext(pCon),
lID = RegisterCallback(self->pCall,
VALUECHANGE, EVCallBack,
pCon, NULL);
SCRegister(pCon,pSics, self->pCall,lID);
SCCopyConnection(pCon), SCDeleteConnection);
SCSendOK(pCon);
return 1;
}
else if(strcmp(argv[1],"uninterest") == 0)
{
RemoveCallback2(self->pCall,pCon);
RemoveCallbackCon(self->pCall,pCon);
SCSendOK(pCon);
return 1;
}

View File

@ -41,7 +41,7 @@
int iWarned;
int iTcl;
int iStop;
SCStore *conn;
SConnection *conn;
char *creationArgs;
char *runScript;
void *pPrivate;

View File

@ -52,7 +52,7 @@ $\langle$evdata {\footnotesize ?}$\rangle\equiv$
\mbox{}\verb@ int iWarned;@\\
\mbox{}\verb@ int iTcl;@\\
\mbox{}\verb@ int iStop;@\\
\mbox{}\verb@ SCStore *conn;@\\
\mbox{}\verb@ SConnection *conn;@\\
\mbox{}\verb@ char *creationArgs;@\\
\mbox{}\verb@ char *runScript;@\\
\mbox{}\verb@ void *pPrivate;@\\

View File

@ -47,7 +47,7 @@ used by EVControl:
int iWarned;
int iTcl;
int iStop;
SCStore *conn;
SConnection *conn;
char *creationArgs;
char *runScript;
void *pPrivate;

1
exe.w
View File

@ -159,6 +159,7 @@ typedef struct __EXEMAN{
int runList;
pExeBuf uploadBuffer;
int echo;
SConnection *runCon;
}ExeMan, *pExeMan;
@}
The fields:

View File

@ -197,7 +197,10 @@ int exeBufProcess(pExeBuf self, SicsInterp *pSics,
cmdName[l] = '\0';
if (FindCommand(pSics, cmdName) != NULL) {
/* print only SICS commands */
SCPrintf(pCon, eValue, "%s:%d>> %s",self->name,self->lineno,cmd);
SCPrintf(pCon, eLog, "%s:%d>> %s",self->name,self->lineno,cmd);
} else {
/* debugging */
/* SCPrintf(pCon, eValue, "%s:%d>> %s",self->name,self->lineno,cmd); */
}
}
}
@ -209,11 +212,11 @@ int exeBufProcess(pExeBuf self, SicsInterp *pSics,
Tcl Error
*/
if(strlen(pTcl->result) >= 2){
SCWrite(pCon,pTcl->result,eError);
SCPrintf(pCon,eLogError,"ERROR: Tcl reported: %s", pTcl->result);
}
SCWrite(pCon,"ERROR: Tcl error in block:",eError);
SCWrite(pCon,"ERROR: Tcl error in block:",eLogError);
SCWrite(pCon,GetCharArray(command),eError);
SCWrite(pCon,"ERROR: end of Tcl error block",eError);
SCWrite(pCon,"ERROR: end of Tcl error block",eLogError);
} else {
/*
SICS error: has already been reported

View File

@ -1,5 +1,5 @@
#line 226 "exe.w"
#line 227 "exe.w"
/**
* Buffer handling code for the Exe Buffer batch file processing
@ -102,7 +102,7 @@
*/
char *exeBufName(pExeBuf self);
#line 239 "exe.w"
#line 240 "exe.w"
#endif

View File

@ -1,5 +1,5 @@
#line 217 "exe.w"
#line 218 "exe.w"
/*--------------------------------------------------------------------
Internal header file for the exe buffer module. Do not edit. This is
@ -16,6 +16,6 @@ typedef struct __EXEBUF{
int lineno;
} ExeBuf;
#line 222 "exe.w"
#line 223 "exe.w"

View File

@ -1,3 +1,4 @@
/**
* Implementation file for the exe buffer buffer manager.
*
@ -225,6 +226,12 @@ static int runBatchBuffer(pExeMan self, SConnection *pCon,
if(!SCMatchRights(pCon,usUser)) {
return 0;
}
if(self->runCon != NULL && self->runCon != pCon){
SCWrite(pCon,"ERROR: another batch buffer is already runnig", eError);
return 0;
}
filePath = locateBatchBuffer(self,name);
if(filePath == NULL){
snprintf(pBueffel,255,"ERROR: batch buffer %s not found in path",
@ -320,8 +327,7 @@ int exeHdbNode(pHdb exeNode, SConnection *pCon){
pExeBuf buffer = NULL;
hdbValue v;
int status;
commandContext cc;
writeFunc oldWrite;
SConnection *conCon = NULL;
/*
* clear log buffer
@ -337,8 +343,12 @@ int exeHdbNode(pHdb exeNode, SConnection *pCon){
* prepare context
*/
name = GetHipadabaPath(log);
cc = SCGetContext(pCon);
strncpy(cc.deviceID, name,255);
conCon = SCCopyConnection(pCon);
if(conCon == NULL){
SCWrite(pCon,"ERROR: out of memory in exehdbNode", eError);
return 0;
}
strncpy(conCon->deviceID, name,255);
strncpy(bufferNode,name,511);
/*
@ -365,12 +375,9 @@ int exeHdbNode(pHdb exeNode, SConnection *pCon){
exeBufAppend(buffer,v.v.text);
strncpy(bufferNode,name,511);
oldWrite = SCGetWriteFunc(pCon);
SCSetWriteFunc(pCon,SCHdbWrite);
SCPushContext2(pCon,cc);
status = exeBufProcess(buffer,pServ->pSics,pCon,NULL,0);
SCSetWriteFunc(pCon,oldWrite);
SCPopContext(pCon);
SCSetWriteFunc(conCon,SCHdbWrite);
status = exeBufProcess(buffer,pServ->pSics,conCon,NULL,0);
SCDeleteConnection(conCon);
exeBufDelete(buffer);
free(name);
if(strlen(log->value.v.text) < 2){
@ -388,13 +395,16 @@ static int runHdbBuffer(pExeMan self, SConnection *pCon,
pHdb node = NULL;
hdbValue v;
int status;
commandContext cc;
writeFunc oldWrite;
SConnection *conCon = NULL;
if(!SCMatchRights(pCon,usUser)) {
return 0;
}
if(self->runCon != NULL && self->runCon != pCon){
SCWrite(pCon,"ERROR: another bacth buffer is still running", eError);
return 0;
}
/*
* clear log buffer
*/
@ -409,8 +419,8 @@ static int runHdbBuffer(pExeMan self, SConnection *pCon,
/*
* prepare context
*/
cc = SCGetContext(pCon);
strcpy(cc.deviceID, pBueffel);
conCon = SCCopyConnection(pCon);
strcpy(conCon->deviceID, pBueffel);
/*
* load commands into buffer
@ -437,15 +447,14 @@ static int runHdbBuffer(pExeMan self, SConnection *pCon,
exeBufAppend(buffer,v.v.text);
strncpy(bufferNode,name,511);
oldWrite = SCGetWriteFunc(pCon);
SCSetWriteFunc(pCon,SCHdbWrite);
SCPushContext2(pCon,cc);
SCSetWriteFunc(conCon,SCHdbWrite);
self->exeStackPtr++;
self->runCon = conCon;
DynarPut(self->exeStack,self->exeStackPtr,buffer);
status = exeBufProcess(buffer,pSics,pCon,self->pCall,self->echo);
status = exeBufProcess(buffer,pSics,conCon,self->pCall,self->echo);
self->exeStackPtr--;
SCSetWriteFunc(pCon,oldWrite);
SCPopContext(pCon);
self->runCon = NULL;
SCDeleteConnection(conCon);
return status;
}
/*--------------------------------------------------------------------*/
@ -519,6 +528,9 @@ typedef struct {
/*------------------------------------------------------------------*/
static void killExeInfo(void *pData){
pExeInfo self = (pExeInfo)pData;
if(self->pCon != NULL){
SCDeleteConnection(self->pCon);
}
if(self != NULL){
free(self);
}
@ -533,32 +545,41 @@ static pExeInfo makeExeInfo(SConnection *pCon, pExeMan self){
eError);
return NULL;
}
pNew->pCon = pCon;
memset(pNew,0,sizeof(exeInfo));
pNew->pCon = SCCopyConnection(pCon);
if(pNew->pCon == NULL){
SCWrite(pCon,
"ERROR: failed to allocate info structure for registering callbacks",
eError);
return NULL;
}
pNew->exe = self;
return pNew;
}
/*------------------------------------------------------------------*/
static int BufferCallback(int iEvent, void *pEvent, void *pUser,
commandContext cc){
static int BufferCallback(int iEvent, void *pEvent, void *pUser){
pExeInfo self = (pExeInfo)pUser;
char *name = (char *)pEvent;
char pBueffel[132];
if(!SCisConnected(self->pCon)){
return -1;
}
if(iEvent == BATCHSTART){
snprintf(pBueffel,131,"BATCHSTART=%s",name);
SCWriteInContext(self->pCon,pBueffel,eWarning,cc);
SCWrite(self->pCon,pBueffel,eLog);
return 1;
}
if(iEvent == BATCHEND){
snprintf(pBueffel,131,"BATCHEND=%s",name);
SCWriteInContext(self->pCon,pBueffel,eWarning,cc);
SCWrite(self->pCon,pBueffel,eLog);
return 1;
}
return 0;
}
/*-------------------------------------------------------------------*/
static int LineCallBack(int iEvent, void *pEvent, void *pUser,
commandContext cc){
static int LineCallBack(int iEvent, void *pEvent, void *pUser){
pExeInfo self = (pExeInfo)pUser;
char pBueffel[256];
int start, end, lineno;
@ -566,6 +587,11 @@ static int LineCallBack(int iEvent, void *pEvent, void *pUser,
pExeBuf buf = NULL;
assert(self);
if(!SCisConnected(self->pCon)){
return -1;
}
if(iEvent == BATCHAREA){
DynarGet(self->exe->exeStack,self->exe->exeStackPtr,&pPtr);
buf = (pExeBuf)pPtr;
@ -573,7 +599,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);
SCWriteInContext(self->pCon,pBueffel,eWarning,cc);
SCWrite(self->pCon,pBueffel,eLog);
return 1;
}
return 0;
@ -588,15 +614,12 @@ static void registerCallbacks(SConnection *pCon, SicsInterp *pSics,
if(info == NULL){
return;
}
lID = RegisterCallback(self->pCall, SCGetContext(pCon),BATCHSTART, BufferCallback,
lID = RegisterCallback(self->pCall,BATCHSTART, BufferCallback,
info, killExeInfo);
SCRegister(pCon,pSics, self->pCall,lID);
lID = RegisterCallback(self->pCall, SCGetContext(pCon),BATCHEND, BufferCallback,
lID = RegisterCallback(self->pCall, BATCHEND, BufferCallback,
info, NULL);
SCRegister(pCon,pSics, self->pCall,lID);
lID = RegisterCallback(self->pCall, SCGetContext(pCon),BATCHAREA, LineCallBack,
lID = RegisterCallback(self->pCall, BATCHAREA, LineCallBack,
info, NULL);
SCRegister(pCon,pSics, self->pCall,lID);
}
/*--------------------------------------------------------------------*/
static void unregisterCallbacks(SConnection *pCon, pExeMan self){
@ -607,7 +630,6 @@ static void unregisterCallbacks(SConnection *pCon, pExeMan self){
lID = SCgetCallbackID(pCon,self->pCall);
if(lID >= 0){
RemoveCallback(self->pCall,lID);
SCUnregisterID(pCon,lID);
}
}
}
@ -1148,7 +1170,7 @@ static int execQueue(pExeMan self, SConnection *pCon, SicsInterp *pSics){
pExeBuf buf = NULL;
int status;
if(self->exeStackPtr >= 0){
if(self->exeStackPtr >= 0 || (self->runCon != NULL && self->runCon != pCon) ){
SCWrite(pCon,
"ERROR: cannot start queue while batch buffers are still running",eError);
return 0;
@ -1157,6 +1179,7 @@ static int execQueue(pExeMan self, SConnection *pCon, SicsInterp *pSics){
return 0;
}
self->runCon = pCon;
while(LLDnodePtr2First(self->runList) != 0){
LLDnodeDataTo(self->runList,&buf);
LLDnodeDelete(self->runList);
@ -1164,6 +1187,7 @@ static int execQueue(pExeMan self, SConnection *pCon, SicsInterp *pSics){
if(buf == NULL){
SCWrite(pCon,
"ERROR: serious trouble, buffer not in queue, inform programmer",eError);
self->runCon = NULL;
return 0;
}
DynarPut(self->exeStack,self->exeStackPtr,buf);
@ -1171,9 +1195,11 @@ static int execQueue(pExeMan self, SConnection *pCon, SicsInterp *pSics){
self->exeStackPtr--;
if(SCGetInterrupt(pCon) >= eAbortBatch){
SCWrite(pCon,"ERROR: queue processing interrupted",eError);
self->runCon = NULL;
return 0;
}
}
self->runCon = 0;
return 1;
}
/*========================== interpreter action =======================*/

View File

@ -1,5 +1,5 @@
#line 195 "exe.w"
#line 196 "exe.w"
/*-------------------------------------------------------------------
Internal header file for the exe manager module. Do not edit. This
@ -18,7 +18,8 @@ typedef struct __EXEMAN{
int runList;
pExeBuf uploadBuffer;
int echo;
SConnection *runCon;
}ExeMan, *pExeMan;
#line 200 "exe.w"
#line 201 "exe.w"

View File

@ -322,12 +322,12 @@
if(SCGetInterrupt(pCon) == eAbortOperation)
{
SCSetInterrupt(pCon,eContinue);
SCWrite(pCon,"Driving Aborted",eStatus);
SCWrite(pCon,"Driving Aborted",eError);
}
return 0;
break;
case DEVDONE:
SCWrite(pCon,"Driving to center done",eStatus);
SCWrite(pCon,"Driving to center done",eValue);
break;
default:
SCWrite(pCon,

View File

@ -608,11 +608,11 @@ void z1FromAllAngles(double lambda, double omega , double gamma,
mat_free(z3);
}
/*-----------------------------------------------------------------------*/
int findAllowedBisecting(double lambda, MATRIX z1, float fSet[4],
int findAllowedBisecting(double lambda, MATRIX z1, double *fSet,
inRange testFunc, void *userData){
int status, i, mask[4];
double stt, om, chi, phi, psi, ompsi, chipsi, phipsi;
float fTest[4];
double fTest[4];
status = z1mToBisecting(lambda,z1, &stt, &om, &chi, &phi);
chi = circlify(chi);

View File

@ -187,8 +187,8 @@ int calcTheta(double lambda, MATRIX z1, double *d, double *theta);
* in testing the range.
* @return 0 on failure, 1 on success.
*/
typedef int (*inRange)(void *userData, float dSet[4], int mask[4]);
int findAllowedBisecting(double lambda, MATRIX z1, float fSet[4],
typedef int (*inRange)(void *userData, double dSet[4], int mask[4]);
int findAllowedBisecting(double lambda, MATRIX z1, double fSet[4],
inRange testFunc, void *userData);
#endif

778
fourmess.c Normal file
View File

@ -0,0 +1,778 @@
/**
* This is a new version of the four circle reflection measurement module. Its task is
* to provide functionality required for measuring a list of reflections. This is done
* with the help of some scripts binding things together. This module provides:
* - a table of scan parameters for measuring reflections at different angles.
* - the functions required to produce the scan data files for single detector
* mode.
* - a list of reflections to measure.
*
* In contrast to the old mesure module, this only provides some help to
* scripts. Thus, through scripts, a more flexible measurement is possible.
*
* copyright: see file COPYRIGHT
*
* Mark Koennecke, July 2008
*/
#include <stdio.h>
#include <assert.h>
#include "singlex.h"
#include "sicsobj.h"
#include "fourtable.h"
#include "sicshipadaba.h"
#include "sicsvar.h"
#include <sics.h>
#include "scan.h"
#include "stdscan.h"
#include "evcontroller.h"
#include "integrate.h"
#include "sginfo.h"
#include "matrix/matrix.h"
#include "cell.h"
#include "fourlib.h"
extern void SNXFormatTime(char *pBueffel, int iLen);
/*---------------------------------------------------------------------------*/
typedef struct {
FILE *profFile; /* file with reflection profiles, ccl */
FILE *hklFile; /* file with integrated intensities */
int stepTable; /* table with the scan parameters */
char *currentFileRoot;
pSICSOBJ messList;
pHdb currentRefl; /* the current reflection being measured */
int count;
pScanData pScanner;
int masterCount; /* the number of master reflection as craeted by indgen */
}FourMess, *pFourMess;
/*---------------------------------------------------------------------------*/
static void KillFourMess(void *data){
pFourMess priv = (pFourMess)data;
if(priv == NULL){
return;
}
if(priv->profFile != NULL){
fclose(priv->profFile);
}
if(priv->hklFile != NULL){
fclose(priv->hklFile);
}
if(priv->currentFileRoot != NULL){
free(priv->currentFileRoot);
}
if(priv->stepTable >= 0){
DeleteFourCircleTable(priv->stepTable);
}
free(priv);
}
/*----------------------------------------------------------------------------*/
static int FourMessAction(SConnection *pCon, SicsInterp *pSics,
void *data, int argc, char *argv[]){
pFourMess priv = NULL;
pSICSOBJ self = (pSICSOBJ)data;
int err, status;
assert(self != NULL);
priv = self->pPrivate;
assert(priv != NULL);
if(argc < 2){
SCWrite(pCon,"ERROR: insufficient number of arguments to fmess",
eError);
return 0;
}
if(strcmp(argv[1],"table") == 0){
return HandleFourCircleCommands(&priv->stepTable,pCon,
argc,argv,&err);
}
status = InvokeSICSOBJ(pCon,pSics,data,argc,argv);
if(status < 0){
SCPrintf(pCon,eError, "ERROR: %s no subcommand or parameter",
argv[1]);
return 0;
}
return status;
}
/*-----------------------------------------------------------------------------*/
static int FourMessClose(pSICSOBJ self, SConnection *pCon, pHdb commandNode,
pHdb par[], int nPar){
pFourMess priv = NULL;
priv = self->pPrivate;
if(priv->hklFile != NULL){
fclose(priv->hklFile);
priv->hklFile = NULL;
}
if(priv->profFile != NULL){
fclose(priv->profFile);
priv->profFile = NULL;
}
return 1;
}
/*-----------------------------------------------------------------------------*/
static int FourMessStart(pSICSOBJ self, SConnection *pCon, pHdb commandNode,
pHdb par[], int nPar){
pFourMess priv = NULL;
char pFilename[512], pRoot[512];
char pBueffel[1024];
double lambda;
const double *dUB;
pSicsVariable pVar = NULL;
char *pFile = NULL, *pPtr;
FILE *temp = NULL;
pHdb node;
hdbValue v;
assert(self);
assert(pCon);
priv = self->pPrivate;
if(nPar < 1){
SCWrite(pCon,"ERROR: need file name parameter to start",eError);
return 0;
}
/* close open files if so */
if(priv->hklFile != NULL){
FourMessClose(self,pCon,commandNode,par,nPar);
}
/* create filename root */
GetHipadabaPar(par[0],&v, pCon);
pFile = strdup(v.v.text);
pPtr = strrchr(pFile,(int)'.');
pPtr++;
*pPtr = '\0';
if(priv->currentFileRoot != NULL){
free(priv->currentFileRoot);
}
priv->currentFileRoot = strdup(pFile);
free(pFile);
strncpy(pRoot,priv->currentFileRoot,511);
/* open the reflection file */
sprintf(pBueffel,"Writing to %s.ccl, .rfl",pRoot);
SCWrite(pCon,pBueffel,eValue);
strcpy(pFilename,pRoot);
strcat(pFilename,"ccl");
priv->profFile = fopen(pFilename,"w");
if(!priv->profFile){
sprintf(pBueffel,"ERROR: SERIOUS TROUBLE: cannot open %s!",
pFilename);
SCWrite(pCon,pBueffel,eError);
SCSetInterrupt(pCon,eAbortBatch);
return 0;
}
node = GetHipadabaNode(self->objectNode,"template");
assert(node != NULL);
GetHipadabaPar(node,&v,pCon);
temp = fopen(v.v.text,"r");
if(temp == NULL)
{
SCWrite(pCon,"ERROR: failed to open header template",eError);
}
if(temp != NULL )
{
WriteTemplate(priv->profFile, temp, pFilename, NULL,
pCon, pServ->pSics);
fclose(temp);
}
/* open hkl-data file */
strcpy(pFilename,pRoot);
strcat(pFilename,"rfl");
priv->hklFile = fopen(pFilename,"w");
if(!priv->hklFile){
sprintf(pBueffel,"ERROR: SERIOUS TROUBLE: cannot open %s!",
pFilename);
SCWrite(pCon,pBueffel,eError);
SCSetInterrupt(pCon,eAbortBatch);
return 0;
}
fputs(pFilename,priv->hklFile);
fputs("\n",priv->hklFile);
/* write some header data */
SNXFormatTime(pBueffel,1024);
fprintf(priv->hklFile,"filetime = %s\n",pBueffel);
lambda = SXGetLambda();
fprintf(priv->hklFile,"lambda = %f Angstroem\n",lambda);
dUB = SXGetUB();
fprintf(priv->hklFile,
"UB = %7.6f %7.6f %7.6f %7.6f %7.6f %7.6f %7.6f %7.6f %7.6f\n",
dUB[0], dUB[1],dUB[2],dUB[3],dUB[4],dUB[5],dUB[6],dUB[7],dUB[8]);
/* write sample & user info */
strcpy(pBueffel,"CCL, Instr=TRICS, ");
pVar = FindVariable(pServ->pSics,"sample");
if(pVar){
fprintf(priv->hklFile,"sample = %s\n",pVar->text);
}
pVar = FindVariable(pServ->pSics,"user");
if(pVar){
fprintf(priv->hklFile,"user = %s \n",pVar->text);
}
priv->count = 0;
return 1;
}
/*----------------------------------------------------------------------------*/
static int FourMessScanPar(pSICSOBJ self, SConnection *pCon, pHdb commandNode,
pHdb par[], int nPar){
pFourMess priv = self->pPrivate;
char *scanvar;
double stt, dVal;
int np, preset;
pDynString data;
assert(priv != NULL);
if(nPar < 1){
SCWrite(pCon,"ERROR: need two theta parameter to scanpar", eError);
return 0;
}
stt = par[0]->value.v.doubleValue;
scanvar = GetFourCircleScanVar(priv->stepTable,stt);
dVal = GetFourCircleStep(priv->stepTable,stt);
np = GetFourCircleScanNP(priv->stepTable,stt);
preset = GetFourCirclePreset(priv->stepTable,stt);
if(strcmp(scanvar,"NOT FOUND") == 0){
SCPrintf(pCon,eValue,"%s,%f,%d,%d","om", dVal,np,preset);
} else {
SCPrintf(pCon,eValue,"%s,%f,%d,%d",scanvar,dVal,np,preset);
}
return 1;
}
/*----------------------------------------------------------------------------*/
static hdbCallbackReturn SetScannerCB(pHdb node, void *userData,
pHdbMessage mm){
pHdbDataMessage set = NULL;
pFourMess priv = (pFourMess)userData;
SConnection *pCon = NULL;
pScanData old;
if((set = GetHdbSetMessage(mm)) != NULL){
old = priv->pScanner;
priv->pScanner = FindCommandData(pServ->pSics,set->v->v.text,"ScanObject");
if(priv->pScanner == NULL){
priv->pScanner = old;
pCon = set->callData;
if(pCon != NULL){
SCWrite(pCon,"ERROR: scan object not found", eError);
}
return hdbAbort;
}
}
return hdbContinue;
}
/*---------------------------------------------------------------------------*/
static double getProtonAverage(pFourMess self){
int np, i;
long *lData = NULL, lSum = 0;
np = GetScanNP(self->pScanner);
lData = (long *)malloc((np+1)*sizeof(long));
if(lData == NULL || np == 0){
return 0.;
}
memset(lData,0,(np+1)*sizeof(long));
GetScanMonitor(self->pScanner,2,lData, np);
for(i = 0; i < np; i++){
lSum += lData[i];
}
free(lData);
return (double)lSum/(double)np;
}
/*---------------------------------------------------------------------------*/
static int FourMessStoreIntern(pSICSOBJ self, SConnection *pCon,
double fHkl[3], double fPosition[4]){
pFourMess priv = self->pPrivate;
float fSum, fSigma, fTemp, fStep, fPreset;
int i, iLF, iRet, iNP,ii;
long *lCounts = NULL;
pEVControl pEva = NULL;
pDummy pPtr = NULL;
pIDrivable pDriv = NULL;
char pBueffel[512], pTime[512], pNum[10];
double prot;
if(priv->pScanner == NULL){
SCWrite(pCon,"ERROR: store: scan not configured", eLogError);
return 0;
}
if(priv->hklFile == NULL){
SCWrite(pCon,"ERROR: store: no files open", eLogError);
return 0;
}
/* get necessary data */
fSum = 0.;
fSigma = 0.;
iRet = ScanIntegrate(priv->pScanner,&fSum, &fSigma);
if(iRet != 1){
switch(iRet){
case INTEGLEFT:
sprintf(pBueffel,
"WARNING: integration failed --> no left side to: %f %f %f",
fHkl[0], fHkl[1],fHkl[2]);
break;
case INTEGRIGHT:
sprintf(pBueffel,
"WARNING: integration failed -->no right side to: %f %f %f",
fHkl[0], fHkl[1],fHkl[2]);
break;
case INTEGNOPEAK:
sprintf(pBueffel,
"WARNING: integration failed -->no peak found: %f %f %f",
fHkl[0], fHkl[1],fHkl[2]);
break;
case INTEGFUNNYBACK:
sprintf(pBueffel,
"WARNING: integration problem, asymmetric background: %f %f %f",
fHkl[0], fHkl[1],fHkl[2]);
break;
}
SCWrite(pCon,pBueffel,eLog);
}
iNP = GetScanNP(priv->pScanner);
lCounts = malloc(iNP*sizeof(long));
if(lCounts == NULL){
SCWrite(pCon,"ERROR: out of memory in store", eLogError);
return 0;
}
GetScanCounts(priv->pScanner,lCounts,iNP);
/* write it */
if(priv->profFile){
fprintf(priv->profFile,"%4d %7.3f %7.3f %7.3f %7.2f %7.2f %7.2f %7.2f %7.0f %7.2f\n",
priv->count, fHkl[0],fHkl[1],fHkl[2],
fPosition[0], fPosition[1],
fPosition[2], fPosition[3],
fSum,fSigma);
}
if(priv->hklFile){
fprintf(priv->hklFile,"%5d %6.2f %6.2f %6.2f %7.2f %7.2f %7.2f %7.2f %7.0f %7.2f\n",
priv->count, fHkl[0],fHkl[1],fHkl[2],
fPosition[0], fPosition[1],
fPosition[2],fPosition[3],
fSum,fSigma);
}
sprintf(pBueffel,"%5d %6.2f %6.2f %6.2f %7.2f %7.2f %7.2f %7.2f %7.0f %7.2f\n",
priv->count, fHkl[0],fHkl[1],fHkl[2],
fPosition[0], fPosition[1],
fPosition[2], fPosition[3],
fSum,fSigma);
SCWrite(pCon,pBueffel,eLog);
/* get temperature */
fTemp = -777.77;
pEva = (pEVControl)FindCommandData(pServ->pSics,"temperature",
"Environment Controller");
if(pEva == NULL){
pPtr = (pDummy)FindCommandData(pServ->pSics,"temperature",
"RemObject");
if(pPtr != NULL){
pDriv = pPtr->pDescriptor->GetInterface(pPtr,DRIVEID);
if(pDriv != NULL){
fTemp = pDriv->GetValue(pPtr,pCon);
}
}
} else {
iRet = EVCGetPos(pEva, pCon,&fTemp);
}
/* write profile */
if(priv->profFile){
/* collect data */
SNXFormatTime(pBueffel,512);
GetScanVarStep(priv->pScanner,0,&fStep);
fPreset = GetScanPreset(priv->pScanner);
prot = getProtonAverage(priv);
fprintf(priv->profFile,"%3d %7.4f %9.0f %7.3f %12f %s\n",iNP,fStep,
fPreset,fTemp,prot, pBueffel);
for(i = 0; i < iNP; i++){
for(ii = 0; ii < 10 && i < iNP; ii++){
fprintf(priv->profFile," %7ld",lCounts[i]);
iLF = 1;
i++;
}
fprintf(priv->profFile,"\n");
i--;
iLF = 0;
}
if(iLF){
fprintf(priv->profFile,"\n");
}
fflush(priv->profFile);
}
strcpy(pTime,pBueffel);
sprintf(pBueffel,"%3d%8.4f%10.0f%8.3f %s\n",iNP,fStep,
fPreset,fTemp,pTime);
SCWrite(pCon,pBueffel,eLog);
pBueffel[0] = '\0';
for(i = 0; i < iNP; i++){
for(ii = 0; ii < 10 && i < iNP; ii++){
sprintf(pNum," %6ld",lCounts[i]);
strcat(pBueffel,pNum);
iLF = 1;
i++;
}
SCWrite(pCon,pBueffel,eLog);
pBueffel[0] = '\0';
i--;
iLF = 0;
}
if(iLF){
SCWrite(pCon,pBueffel,eLog);
}
free(lCounts);
return 1;
}
/*----------------------------------------------------------------------------*/
static int FourMessStore(pSICSOBJ self, SConnection *pCon, pHdb commandNode,
pHdb par[], int nPar){
double fHkl[3], fPosition[4];
int i;
if(nPar < 7) {
SCWrite(pCon,"ERROR: not enough arguments for store",eError);
return 0;
}
/* load hkl */
for(i = 0; i < 3; i++){
fHkl[i] = par[i]->value.v.doubleValue;
}
/* load positions */
for(i = 0; i < 4; i++){
fPosition[i] = par[i+3]->value.v.doubleValue;
}
return FourMessStoreIntern(self, pCon,fHkl, fPosition);
}
/*------------------------------------------------------------------*/
static int weakScan(pSICSOBJ self, SConnection *pCon){
int i, np;
long low = 99999, high = -99999, *lCounts = NULL;
pFourMess priv = self->pPrivate;
hdbValue v;
/*
the scan is always OK if we do not test for weak conditions or we are in psd mode
*/
SICSHdbGetPar(self,pCon,"weak",&v);
if(v.v.intValue == 0){
return 0;
}
np = GetScanNP(priv->pScanner);
lCounts = malloc(np*sizeof(long));
if(lCounts == NULL){
SCWrite(pCon,"ERROR: out of memory in weakScan test", eLogError);
return 0;
}
GetScanCounts(priv->pScanner,lCounts,np);
for(i = 0; i < np; i++){
if(lCounts[i] < low){
low = lCounts[i];
}
if(lCounts[i] > high){
high = lCounts[i];
}
}
/*
I am using the weakest point here as a rough estimate of
the background
*/
SICSHdbGetPar(self,pCon,"weakthreshold",&v);
if(high - 2 * low > v.v.intValue){
return 0;
} else {
return 1;
}
}
/*----------------------------------------------------------------------------*/
static int FourMessWeak(pSICSOBJ self, SConnection *pCon, pHdb commandNode,
pHdb par[], int nPar){
int weak;
weak = weakScan(self,pCon);
SCPrintf(pCon,eLog,"weak = %d", weak);
return 1;
}
/*----------------------------------------------------------------------------*/
static int GenIndex(pSICSOBJ self, SConnection *pCon, pHdb commandNode,
pHdb par[], int nPar){
double lambda = SXGetLambda(), d, om, hkl[3];
int h, k, l, minh, mink, minl, suppress;
hdbValue hkllim, sttlim;
T_SgInfo *sginfo = SXGetSpaceGroup();
pFourMess priv = self->pPrivate;
int count = 0;
MATRIX B, H, Z1;
const double *cell;
lattice direct;
if(nPar < 1) {
SCWrite(pCon,"ERROR: need a suppression flag for indgen",
eError);
return 0;
}
SICSHdbGetPar(self,pCon,"hkllim",&hkllim);
SICSHdbGetPar(self,pCon,"sttlim",&sttlim);
suppress = par[0]->value.v.intValue;
minh = hkllim.v.intArray[3];
mink = hkllim.v.intArray[4];
minl = hkllim.v.intArray[5];
SetListMin_hkl(sginfo,hkllim.v.intArray[1], hkllim.v.intArray[2],
&minh, &mink, &minl);
ClearReflectionList(priv->messList);
cell = SXGetCell();
direct.a = cell[0];
direct.b = cell[1];
direct.c = cell[2];
direct.alpha = cell[3];
direct.beta = cell[4];
direct.gamma = cell[5];
B = mat_creat(3,3,UNIT_MATRIX);
if(!calculateBMatrix(direct,B)){
SCWrite(pCon,"ERROR: invalid cell", eError);
return 0;
}
H = mat_creat(3,1,ZERO_MATRIX);
for(h = hkllim.v.intArray[0]; h < hkllim.v.intArray[3]; h++){
for(k = hkllim.v.intArray[1]; k < hkllim.v.intArray[4]; k++){
for(l = hkllim.v.intArray[2]; l < hkllim.v.intArray[5]; l++){
/* first test: extinct */
if(IsSysAbsent_hkl(sginfo,h,k,l,NULL) != 0 ){
continue;
}
/* second test: a symmetrically equivalent already seen */
if((suppress != 0) && IsSuppressed_hkl(sginfo,minh,mink,minl,
hkllim.v.intArray[1],hkllim.v.intArray[2],h,k,l ) != 0){
continue;
}
/* third test: within stt limits */
H[0][0] = (double)h;
H[1][0] = (double)k;
H[2][0] = (double)l;
Z1 = mat_mul(B,H);
calcTheta(lambda,Z1,&d,&om);
om *= 2.;
mat_free(Z1);
if(om > sttlim.v.floatArray[0] && om < sttlim.v.floatArray[1]){
hkl[0] = (double)h;
hkl[1] = (double)k;
hkl[2] = (double)l;
AddRefIdx(priv->messList,hkl);
count++;
}
}
}
}
mat_free(B);
mat_free(H);
priv->masterCount = count;
SCPrintf(pCon,eValue,"%d reflections generated", count);
return 1;
}
/*-----------------------------------------------------------------------------*/
static int GenInconsumerate(pSICSOBJ self, SConnection *pCon, pHdb commandNode,
pHdb par[], int nPar){
double hkl[3], qvec[3];
pFourMess priv = self->pPrivate;
int i, j;
if(nPar < 3) {
SCWrite(pCon,
"ERROR: need q displacement vector with three compononts",
eError);
return 0;
}
qvec[0] = par[0]->value.v.doubleValue;
qvec[1] = par[1]->value.v.doubleValue;
qvec[2] = par[2]->value.v.doubleValue;
for(i = 0; i < priv->masterCount; i++){
GetRefIndex(priv->messList,i,hkl);
for(j = 0; j < 3; j++){
hkl[j] += qvec[j];
}
AddRefIdx(priv->messList, hkl);
}
SCPrintf(pCon,eValue,"%d additional inconsumerate reflections generated",
priv->masterCount);
return 1;
}
/*----------------------------------------------------------------------------*/
static int hklCompare(const void *h1, const void *h2){
const double *hkl1 = h1, *hkl2 = h2;
if(hkl1[3] < hkl2[3]){
return -1;
} else if (hkl1[3] == hkl2[3]) {
return 0;
} else {
return 1;
}
}
/*----------------------------------------------------------------------------*/
static int SortRef(pSICSOBJ self, SConnection *pCon, pHdb commandNode,
pHdb par[], int nPar){
double *sortlist, d, lambda, om, hkl[4], ang[4];
const double *cell;
int nRefl, i, j;
MATRIX B, H, Z1;
lattice direct;
pFourMess priv = self->pPrivate;
lambda = SXGetLambda();
cell = SXGetCell();
direct.a = cell[0];
direct.b = cell[1];
direct.c = cell[2];
direct.alpha = cell[3];
direct.beta = cell[4];
direct.gamma = cell[5];
B = mat_creat(3,3,UNIT_MATRIX);
if(!calculateBMatrix(direct,B)){
SCWrite(pCon,"ERROR: invalid cell", eError);
return 0;
}
H = mat_creat(3,1,ZERO_MATRIX);
nRefl = ReflectionListCount(priv->messList);
sortlist = malloc(nRefl*4*sizeof(double));
if(sortlist == NULL){
SCWrite(pCon,"ERROR: out of memory in SortRef",eError);
return 0;
}
/*
* I am using hkl[3] for storing the theta value to sort for! */
for(i = 0; i < nRefl; i++){
GetRefIndex(priv->messList,i,hkl);
for(j = 0; j < 3; j++){
H[j][0] = hkl[j];
}
Z1 = mat_mul(B,H);
calcTheta(lambda,Z1,&d, &om);
mat_free(Z1);
hkl[3] = om;
memcpy(sortlist + i*4, hkl, 4*sizeof(double));
}
qsort(sortlist,nRefl,4*sizeof(double),hklCompare);
ClearReflectionList(priv->messList);
for(i = 0; i < nRefl; i++){
ang[1] = sortlist[i*4+3];
ang[0] = 2.*ang[1];
ang[2] = .0;
ang[3] = .0;
/* AddRefIdxAng(priv->messList, sortlist+i*4,ang); */
AddRefIdx(priv->messList, sortlist+i*4);
}
free(sortlist);
mat_free(B);
mat_free(H);
SCSendOK(pCon);
return 1;
}
/*----------------------------------------------------------------------------*/
static int FourMessSave(void *data, char *name, FILE *fd){
pSICSOBJ self = data;
pFourMess priv = self->pPrivate;
SaveSICSOBJ(data,name,fd);
SaveFourCircleTable(priv->stepTable, name, fd);
return 1;
}
/*----------------------------------------------------------------------------*/
void InstallFourMess(SConnection *pCon, SicsInterp *pSics){
pFourMess priv = NULL;
pSICSOBJ pNew = NULL;
pHdb cmd = NULL;
int hkl[] = {-10,-10,10,10,10,10};
double sttlim[] = {5.0, 180};
pNew = MakeSICSOBJ("fmess","FourMess");
priv = calloc(1,sizeof(FourMess));
if(pNew == NULL || priv == NULL){
SCWrite(pCon,"ERROR: out of memory creating fourmess", eError);
}
pNew->pDes->SaveStatus = FourMessSave;
pNew->pPrivate = priv;
pNew->KillPrivate = KillFourMess;
priv->stepTable = MakeFourCircleTable();
priv->messList = CreateReflectionList(pCon,pSics,"messref");
if(priv->stepTable < 0 || priv->messList == NULL){
SCWrite(pCon,"ERROR: out of memory creating fourmess", eError);
}
cmd = AddSICSHdbPar(pNew->objectNode,"weak", usUser, MakeHdbInt(0));
SetHdbProperty(cmd,"__save","true");
cmd = AddSICSHdbPar(pNew->objectNode,"weakthreshold", usUser,
MakeHdbInt(20));
SetHdbProperty(cmd,"__save","true");
cmd = AddSICSHdbPar(pNew->objectNode,"mode", usUser, MakeHdbText("Monitor"));
cmd = AddSICSHdbPar(pNew->objectNode,"hkllim", usUser, MakeHdbIntArray(6,hkl));
SetHdbProperty(cmd,"__save","true");
cmd = AddSICSHdbPar(pNew->objectNode,"sttlim", usUser, MakeHdbFloatArray(2,sttlim));
SetHdbProperty(cmd,"__save","true");
cmd = AddSICSHdbPar(pNew->objectNode,"start", usUser, MakeSICSFunc(FourMessStart));
cmd = AddSICSHdbPar(cmd,"filename", usUser, MakeHdbText("Unknown"));
cmd = AddSICSHdbPar(pNew->objectNode,"close", usUser, MakeSICSFunc(FourMessClose));
cmd = AddSICSHdbPar(pNew->objectNode,"scanpar", usUser, MakeSICSFunc(FourMessScanPar));
cmd = AddSICSHdbPar(cmd,"twotheta", usUser, MakeHdbFloat(.0));
cmd = AddSICSHdbPar(pNew->objectNode,"store", usUser, MakeSICSFunc(FourMessStore));
AddSICSHdbPar(cmd,"h", usUser, MakeHdbFloat(.0));
AddSICSHdbPar(cmd,"k", usUser, MakeHdbFloat(.0));
AddSICSHdbPar(cmd,"l", usUser, MakeHdbFloat(.0));
AddSICSHdbPar(cmd,"stt", usUser, MakeHdbFloat(.0));
AddSICSHdbPar(cmd,"om", usUser, MakeHdbFloat(.0));
AddSICSHdbPar(cmd,"chi", usUser, MakeHdbFloat(.0));
AddSICSHdbPar(cmd,"phi", usUser, MakeHdbFloat(.0));
cmd = AddSICSHdbPar(pNew->objectNode,"weak", usUser, MakeSICSFunc(FourMessWeak));
cmd = AddSICSHdbPar(pNew->objectNode,"indgen", usUser, MakeSICSFunc(GenIndex));
AddSICSHdbPar(cmd,"sup", usUser, MakeHdbInt(1));
cmd = AddSICSHdbPar(pNew->objectNode,"genw", usUser, MakeSICSFunc(GenInconsumerate));
AddSICSHdbPar(cmd,"hw", usUser, MakeHdbFloat(.0));
AddSICSHdbPar(cmd,"kw", usUser, MakeHdbFloat(.0));
AddSICSHdbPar(cmd,"lw", usUser, MakeHdbFloat(.0));
cmd = AddSICSHdbPar(pNew->objectNode,"indsort", usUser, MakeSICSFunc(SortRef));
cmd = AddSICSHdbPar(pNew->objectNode,"template", usMugger, MakeHdbText("Unknown"));
cmd = AddSICSHdbPar(pNew->objectNode,"scanobj", usMugger, MakeHdbText("xxxscan"));
PrependHipadabaCallback(cmd,
MakeHipadabaCallback(SetScannerCB, priv,NULL));
priv->pScanner = FindCommandData(pSics,"xxxscan","ScanObject");
AddCommand(pSics,
"fmess",
FourMessAction,
KillSICSOBJ,
pNew);
}

25
fourmess.h Normal file
View File

@ -0,0 +1,25 @@
/**
* This is a new version of the four circle reflection measurement module. Its task is
* to provide functionality required for measuring a list of reflections. This is done
* with the help of some scripts bind things together. This module provides:
* - a table of scan parameters for measuring reflections at different angles.
* - the functions required to produce the scan data files for single detector
* mode.
* - a list of reflections to measure.
*
* In contrast to the old mesure module, this module is more flexible and
* allows for reflection list processing in all modes and for all detectors.
*
* copyright: see file COPYRIGHT
*
* Mark Koennecke, July 2008
*/
#ifndef _FOURMESS
#define _FOURMESS
#include <sics.h>
void InstallFourMess(SConnection *pCon, SicsInterp *pSics);
#endif

View File

@ -125,7 +125,7 @@ static int addToList(int handle, SConnection *pCon, int argc, char *argv[]){
}
strncpy(entry.scanVar,argv[4],29);
strtolower(entry.scanVar);
if(strcmp(entry.scanVar,"om") != 0 && strcmp(entry.scanVar,"o2t") != 0){
if(strcmp(entry.scanVar,"om") != 0 && strstr(entry.scanVar,"o2t") == NULL){
SCWrite(pCon,"ERROR: Invalied scan variable specified, only om, o2t allowed",eError);
return 0;
}

View File

@ -236,7 +236,6 @@ static int MakeGenPar(pSICSOBJ self, SConnection *pCon,
pGenController priv;
pAsyncUnit assi;
pAsyncTxn trans;
commandContext comCon;
char replyCommand[2048];
} GenContext, *pGenContext;
/*--------------------------------------------------------------------------
@ -266,13 +265,10 @@ static int MakeGenPar(pSICSOBJ self, SConnection *pCon,
break;
}
if(genCon->pCon != NULL){
SCPushContext2(genCon->pCon, genCon->comCon);
}
genCon->priv->replyCallback(genCon->obj, genCon->pCon,
genCon->node, genCon->replyCommand, reply, strlen(reply));
if(genCon->pCon != NULL){
SCPopContext(genCon->pCon);
SCDeleteConnection(genCon->pCon);
}
free(genCon);
@ -362,9 +358,8 @@ static pGenContext PrepareToEnque(pSICSOBJ self, SConnection *pCon, pHdb node){
result->node = node;
result->priv = priv;
result->obj = self;
result->pCon = pCon;
result->pCon = SCCopyConnection(pCon);
priv->comError = GCOK;
result->comCon = SCGetContext(pCon);
free(command);
return result;

View File

@ -167,6 +167,10 @@ extern pHistDriver MakeHMSlaveHM(pStringDict pOpt);
self = (pHistMem)pData;
assert(self);
if(!GetCountLock(self->pCountInt, pCon)){
return HWFault;
}
if(!self->iInit)
{
SCWrite(pCon,"ERROR: histogram memory not initialised",eError);
@ -195,6 +199,7 @@ extern pHistDriver MakeHMSlaveHM(pStringDict pOpt);
SCWrite(pCon,"ERROR: failed to fix histogram memory problem",
eError);
SCSetInterrupt(pCon,eAbortBatch);
ReleaseCountLock(self->pCountInt);
return HWFault;
}
}
@ -321,6 +326,7 @@ extern pHistDriver MakeHMSlaveHM(pStringDict pOpt);
SCWrite(pCon,"ERROR: failed to fix histogram memory problem",eError);
SCSetInterrupt(pCon,eAbortBatch);
InvokeCallBack(self->pCall,COUNTEND,NULL);
ReleaseCountLock(self->pCountInt);
return eCt;
}
else
@ -339,6 +345,7 @@ extern pHistDriver MakeHMSlaveHM(pStringDict pOpt);
*/
updateHMData(self->pDriv->data);
InvokeCallBack(self->pCall,COUNTEND,NULL);
ReleaseCountLock(self->pCountInt);
}
return eCt;
@ -595,6 +602,11 @@ extern pHistDriver MakeHMSlaveHM(pStringDict pOpt);
assert(self);
assert(pCon);
if(isRunning(self->pCountInt)){
SCWrite(pCon,"ERROR: cannot configure histogram memory while counting", eError);
return 0;
}
iRet = HistDriverConfig(self->pDriv,self->pDriv->pOption,pCon);
if(!iRet)
{
@ -766,16 +778,16 @@ void HistDirty(pHistMem self)
iRet = Wait4Success(GetExecutor());
if(iRet == DEVINT)
{
SCWrite(pCon,"Counting aborted due to Interrupt",eStatus);
SCWrite(pCon,"Counting aborted due to Interrupt",eError);
}
else if(iRet == DEVERROR)
{
SCWrite(pCon,"Counting finished with Problems",eStatus);
SCWrite(pCon,"Counting finished with Problems",eValue);
iRet = 1;
}
else
{
SCWrite(pCon,"Counting finished",eStatus);
SCWrite(pCon,"Counting finished",eValue);
iRet = 1;
}
@ -934,24 +946,29 @@ void HistDirty(pHistMem self)
return 0;
}
/*----------------------------------------------------------------------*/
static int HMCountInterest(int iEvent, void *pEvent, void *pUser,
commandContext cc)
static int HMCountInterest(int iEvent, void *pEvent, void *pUser)
{
SConnection *pCon = NULL;
char pBueffel[512];
if(iEvent == COUNTSTART)
pCon = (SConnection *)pUser;
if(pCon == NULL || !SCisConnected(pCon))
{
return -1;
}
if(iEvent == COUNTSTART && pUser != NULL)
{
pCon = (SConnection *)pUser;
assert(pCon);
SCWriteInContext(pCon,"HMCOUNTSTART",eWarning,cc);
SCWrite(pCon,"HMCOUNTSTART",eWarning);
return 1;
}
else if(iEvent == COUNTEND)
{
pCon = (SConnection *)pUser;
assert(pCon);
SCWriteInContext(pCon,"HMCOUNTEND",eWarning,cc);
SCWrite(pCon,"HMCOUNTEND",eWarning);
return 1;
}
return 0;
@ -982,11 +999,13 @@ static int checkHMEnd(pHistMem self, char *text){
int i,iRet,iLen,iRank,iDiscard,tofMode;
float fVal;
char *pMode[] = {"timer","monitor",NULL};
pDynString buf = NULL;
memset(pBuffer, 0, sizeof(pBuffer));
memset(pValue, 0, sizeof(pValue));
memset(name, 0, sizeof(name));
SCStartBuffering(pCon);
iRet = StringDictGet(self->pDriv->pOption,"name",name,19);
if(0==iRet) {
strcpy(name,"*");
@ -994,7 +1013,7 @@ static int checkHMEnd(pHistMem self, char *text){
iRet = StringDictGet(self->pDriv->pOption,"driver",pValue,sizeof(pValue)-1);
if(0<iRet) {
sprintf(pBuffer,"%s.driver = %s",name,pValue);
SCWrite(pCon,pBuffer,eStatus);
SCWrite(pCon,pBuffer,eValue);
}
iRet = StringDictGetAsNumber(self->pDriv->pOption,"update",&fVal);
@ -1003,13 +1022,13 @@ static int checkHMEnd(pHistMem self, char *text){
} else {
sprintf(pBuffer,"%s.update = 0 (no buffering)",name);
}
SCWrite(pCon,pBuffer,eStatus);
SCWrite(pCon,pBuffer,eValue);
iRet = StringDictGetAsNumber(self->pDriv->pOption,"rank",&fVal);
if(0<iRet) {
iRank = (int)rint(fVal);
sprintf(pBuffer,"%s.rank = %d",name,iRank);
SCWrite(pCon,pBuffer,eStatus);
SCWrite(pCon,pBuffer,eValue);
} else {
iRank = 0;
}
@ -1018,7 +1037,7 @@ static int checkHMEnd(pHistMem self, char *text){
iRet = StringDictGetAsNumber(self->pDriv->pOption,pValue,&fVal);
if(0<iRet){
sprintf(pBuffer,"%s.dim%1.1d = %d",name,i,(int)rint(fVal));
SCWrite(pCon,pBuffer,eStatus);
SCWrite(pCon,pBuffer,eValue);
}
}
@ -1032,18 +1051,18 @@ static int checkHMEnd(pHistMem self, char *text){
if(NULL!=strstr(pKey,"dim")) iDiscard=1;
if(0==iDiscard) {
snprintf(pBuffer,511,"%s.%s = %s",name,pKey,pValue);
SCWrite(pCon,pBuffer,eStatus);
SCWrite(pCon,pBuffer,eValue);
}
pKey = StringDictGetNext(self->pDriv->pOption,pValue,sizeof(pValue)-1);
}
/* Display Count Mode */
sprintf(pBuffer,"%s.CountMode = %s",name,pMode[self->pDriv->eCount]);
SCWrite(pCon,pBuffer,eStatus);
SCWrite(pCon,pBuffer,eValue);
/* Display Preset */
sprintf(pBuffer,"%s.preset = %f",name,self->pDriv->fCountPreset);
SCWrite(pCon,pBuffer,eStatus);
SCWrite(pCon,pBuffer,eValue);
if(self->pDriv->data->nTimeChan > 2) {
tofMode = 1;
@ -1051,7 +1070,11 @@ static int checkHMEnd(pHistMem self, char *text){
tofMode = 0;
}
sprintf(pBuffer,"%s.tofMode = %d",name,tofMode);
SCWrite(pCon,pBuffer,eStatus);
SCWrite(pCon,pBuffer,eValue);
buf = SCEndBuffering(pCon);
if(buf != NULL){
SCWrite(pCon,GetCharArray(buf), eValue);
}
}
/*--------------------------------------------------------------------------*/
@ -1098,14 +1121,12 @@ static int checkHMEnd(pHistMem self, char *text){
strtolower(argv[1]);
if(strcmp(argv[1],"interest") == 0)
{
lID = RegisterCallback(self->pCall, SCGetContext(pCon),
lID = RegisterCallback(self->pCall,
COUNTSTART, HMCountInterest,
pCon, NULL);
SCRegister(pCon,pSics, self->pCall,lID);
lID = RegisterCallback(self->pCall, SCGetContext(pCon),
SCCopyConnection(pCon), SCDeleteConnection);
lID = RegisterCallback(self->pCall,
COUNTEND, HMCountInterest,
pCon, NULL);
SCRegister(pCon,pSics, self->pCall,lID);
SCCopyConnection(pCon), SCDeleteConnection);
SCSendOK(pCon);
return 1;
}
@ -1178,6 +1199,10 @@ static int checkHMEnd(pHistMem self, char *text){
}
else /* set case */
{
if(isRunning(self->pCountInt)){
SCWrite(pCon,"ERROR: cannot change preset while counting", eError);
return 0;
}
fVal = atof(argv[2]);
if(!SCMatchRights(pCon,self->iAccess))
{
@ -1221,6 +1246,10 @@ static int checkHMEnd(pHistMem self, char *text){
else /* set case */
{
strtolower(argv[2]);
if(isRunning(self->pCountInt)){
SCWrite(pCon,"ERROR: cannot change countmode while counting", eError);
return 0;
}
if(!SCMatchRights(pCon,self->iAccess))
{
return 0;
@ -1638,14 +1667,12 @@ static int checkHMEnd(pHistMem self, char *text){
/* generate time binning */
else if(strcmp(argv[1],"genbin") == 0)
{
if(!SCMatchRights(pCon,usMugger))
{
if(isRunning(self->pCountInt)){
SCWrite(pCon,"ERROR: cannot change time binning while counting", eError);
return 0;
}
if(GetStatus() == eCounting)
if(!SCMatchRights(pCon,usMugger))
{
SCWrite(pCon,"ERROR: cannot modify timebinning while counting",
eError);
return 0;
}
if(argc < 5)
@ -1695,6 +1722,10 @@ static int checkHMEnd(pHistMem self, char *text){
/* set a time bin */
else if(strcmp(argv[1],"setbin") == 0)
{
if(isRunning(self->pCountInt)){
SCWrite(pCon,"ERROR: cannot change time binning while counting", eError);
return 0;
}
if(!SCMatchRights(pCon,usMugger))
{
return 0;
@ -1732,6 +1763,10 @@ static int checkHMEnd(pHistMem self, char *text){
/* clear time bin info */
else if(strcmp(argv[1],"clearbin") == 0)
{
if(isRunning(self->pCountInt)){
SCWrite(pCon,"ERROR: cannot change time binning while counting", eError);
return 0;
}
clearTimeBinning(self->pDriv->data);
SCSendOK(pCon);
return 1;

1198
hkl.c

File diff suppressed because it is too large Load Diff

8
hkl.h
View File

@ -19,15 +19,12 @@
typedef struct __HKL *pHKL;
/*-------------------------------------------------------------------------*/
pHKL CreateHKL(pMotor pTheta, pMotor pOmega,
pMotor pChi, pMotor pPhi, pMotor pNu);
pHKL CreateHKL();
void DeleteHKL(void *pData);
int HKLFactory(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]);
/*------------------------------------------------------------------------*/
int SetWavelengthVariable(SConnection *pCon, pHKL self, pSelVar pVar);
int SetWavelengthManual(pHKL self, float fVal);
void SetHKLScanTolerance(pHKL self, float value);
int SetUB(pHKL self, float fUB[9]);
int GetUB(pHKL self, float fUB[9]);
@ -48,7 +45,8 @@
int HKLAction(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]);
int hklInRange(void *data, float fSet[4], int mask[4]);
int hklInRange(void *data, double fSet[4], int mask[4]);
int startHKLMotors(pHKL self, SConnection *pCon, float fSet[4]);
void stopHKLMotors(pHKL self);
#endif

9
hkl.i
View File

@ -9,24 +9,17 @@
typedef struct __HKL {
pObjectDescriptor pDes;
double fUB[9];
MATRIX UBinv;
double fLambda;
int iManual;
double fLastHKL[5];
int iNOR;
int iQuad;
int iHM;
pMotor pTheta;
pMotor pOmega;
pMotor pChi;
pMotor pPhi;
pMotor pNu;
pSelVar pMono;
long lID;
float scanTolerance;
float targetHKL[3];
int targetDirty;
pIDrivable pMotDriv;
} HKL;

38
hkl.tex
View File

@ -20,26 +20,19 @@ $\langle$hkldat {\footnotesize ?}$\rangle\equiv$
\mbox{}\verb@@\\
\mbox{}\verb@ typedef struct __HKL {@\\
\mbox{}\verb@ pObjectDescriptor pDes;@\\
\mbox{}\verb@ double fUB[9];@\\
\mbox{}\verb@ MATRIX UBinv;@\\
\mbox{}\verb@ double fLambda;@\\
\mbox{}\verb@ int iManual;@\\
\mbox{}\verb@ double fLastHKL[5];@\\
\mbox{}\verb@ int iNOR;@\\
\mbox{}\verb@ int iQuad;@\\
\mbox{}\verb@ int iHM;@\\
\mbox{}\verb@ pMotor pTheta;@\\
\mbox{}\verb@ pMotor pOmega;@\\
\mbox{}\verb@ pMotor pChi;@\\
\mbox{}\verb@ pMotor pPhi;@\\
\mbox{}\verb@ pMotor pNu;@\\
\mbox{}\verb@ pSelVar pMono;@\\
\mbox{}\verb@ long lID;@\\
\mbox{}\verb@ float scanTolerance;@\\
\mbox{}\verb@ float targetHKL[3];@\\
\mbox{}\verb@ int targetDirty;@\\
\mbox{}\verb@ pIDrivable pMotDriv;@\\
\mbox{}\verb@ } HKL;@\\
\mbox{}\verb@@$\diamond$
\mbox{}\verb@@$\Diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
@ -51,23 +44,12 @@ $\langle$hkldat {\footnotesize ?}$\rangle\equiv$
The fields are more or less self explaining:
\begin{description}
\item[pDes] The standard object descriptor.
\item[fUB] The UB matrix.
\item[iUB] is a flag which spcifies if a UB is specified.
\item[fLambda] The wavelength of the neutrons.
\item[iManual] A flag which defines if the wavelength has been set manually
or is updated automatically from a wavelength variable.
\item[fLastHKL] the HKL of the last reflection calculated.
\item[iNor] a flag for normal beam calculation mode.
\item[iHM] a flag for histogram memory mode. In this mode two theta
limits are checked alos for detector 2 and 3.
\item[pTheta] The two theta motor. All motor are needed for boundary
checking.
\item[pOmega] The omega axis motor.
\item[pChi] The chi axis motor.
\item[pPhi] the phi axis motor.
\item[pNu] the nu axis motor for normal beam geometry.
This is detector tilt.
\item[pMono] The selector variable doing the wavelength.
\item[scanTolerance] The hkl module refuses to position a reflection if it is
to close to omega limits for scanning. This is the tolerance to use.
\item[targetHKL] The target HKL values to support the H, K, L virtual motors
@ -95,15 +77,12 @@ $\langle$hklint {\footnotesize ?}$\rangle\equiv$
\mbox{}\verb@@\\
\mbox{}\verb@ typedef struct __HKL *pHKL;@\\
\mbox{}\verb@/*-------------------------------------------------------------------------*/@\\
\mbox{}\verb@ pHKL CreateHKL(pMotor pTheta, pMotor pOmega, @\\
\mbox{}\verb@ pMotor pChi, pMotor pPhi, pMotor pNu);@\\
\mbox{}\verb@ pHKL CreateHKL();@\\
\mbox{}\verb@ void DeleteHKL(void *pData);@\\
\mbox{}\verb@ @\\
\mbox{}\verb@ int HKLFactory(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
\mbox{}\verb@ int argc, char *argv[]);@\\
\mbox{}\verb@/*------------------------------------------------------------------------*/@\\
\mbox{}\verb@ int SetWavelengthVariable(SConnection *pCon, pHKL self, pSelVar pVar);@\\
\mbox{}\verb@ int SetWavelengthManual(pHKL self, float fVal);@\\
\mbox{}\verb@ void SetHKLScanTolerance(pHKL self, float value);@\\
\mbox{}\verb@ int SetUB(pHKL self, float fUB[9]);@\\
\mbox{}\verb@ int GetUB(pHKL self, float fUB[9]);@\\
@ -126,7 +105,8 @@ $\langle$hklint {\footnotesize ?}$\rangle\equiv$
\mbox{}\verb@ int argc, char *argv[]); @\\
\mbox{}\verb@ int hklInRange(void *data, float fSet[4], int mask[4]);@\\
\mbox{}\verb@ int startHKLMotors(pHKL self, SConnection *pCon, float fSet[4]);@\\
\mbox{}\verb@@$\diamond$
\mbox{}\verb@ void stopHKLMotors(pHKL self);@\\
\mbox{}\verb@@$\Diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
@ -197,7 +177,7 @@ drive properly.
\mbox{}\verb@----------------------------------------------------------------------------*/@\\
\mbox{}\verb@@$\langle$hkldat {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@@\\
\mbox{}\verb@@$\diamond$
\mbox{}\verb@@$\Diamond$
\end{list}
\vspace{-2ex}
\end{minipage}\\[4ex]
@ -227,7 +207,7 @@ drive properly.
\mbox{}\verb@#include "selvar.h"@\\
\mbox{}\verb@@$\langle$hklint {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@#endif @\\
\mbox{}\verb@@$\diamond$
\mbox{}\verb@@$\Diamond$
\end{list}
\vspace{-2ex}
\end{minipage}\\[4ex]
@ -257,7 +237,7 @@ $\langle$hklmotdat {\footnotesize ?}$\rangle\equiv$
\mbox{}\verb@ pIDrivable pDriv;@\\
\mbox{}\verb@ int index;@\\
\mbox{}\verb@ }HKLMot, *pHKLMot;@\\
\mbox{}\verb@@$\diamond$
\mbox{}\verb@@$\Diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
@ -303,7 +283,7 @@ functions. The interpreter interface is minimal: only a value request is support
\mbox{}\verb@#endif@\\
\mbox{}\verb@@\\
\mbox{}\verb@ @\\
\mbox{}\verb@@$\diamond$
\mbox{}\verb@@$\Diamond$
\end{list}
\vspace{-2ex}
\end{minipage}\\[4ex]

26
hkl.w
View File

@ -15,47 +15,29 @@ The object uses the following object data structure:
@d hkldat @{
typedef struct __HKL {
pObjectDescriptor pDes;
double fUB[9];
MATRIX UBinv;
double fLambda;
int iManual;
double fLastHKL[5];
int iNOR;
int iQuad;
int iHM;
pMotor pTheta;
pMotor pOmega;
pMotor pChi;
pMotor pPhi;
pMotor pNu;
pSelVar pMono;
long lID;
float scanTolerance;
float targetHKL[3];
int targetDirty;
pIDrivable pMotDriv;
} HKL;
@}
The fields are more or less self explaining:
\begin{description}
\item[pDes] The standard object descriptor.
\item[fUB] The UB matrix.
\item[iUB] is a flag which spcifies if a UB is specified.
\item[fLambda] The wavelength of the neutrons.
\item[iManual] A flag which defines if the wavelength has been set manually
or is updated automatically from a wavelength variable.
\item[fLastHKL] the HKL of the last reflection calculated.
\item[iNor] a flag for normal beam calculation mode.
\item[iHM] a flag for histogram memory mode. In this mode two theta
limits are checked alos for detector 2 and 3.
\item[pTheta] The two theta motor. All motor are needed for boundary
checking.
\item[pOmega] The omega axis motor.
\item[pChi] The chi axis motor.
\item[pPhi] the phi axis motor.
\item[pNu] the nu axis motor for normal beam geometry.
This is detector tilt.
\item[pMono] The selector variable doing the wavelength.
\item[scanTolerance] The hkl module refuses to position a reflection if it is
to close to omega limits for scanning. This is the tolerance to use.
\item[targetHKL] The target HKL values to support the H, K, L virtual motors
@ -78,15 +60,12 @@ module:
@d hklint @{
typedef struct __HKL *pHKL;
/*-------------------------------------------------------------------------*/
pHKL CreateHKL(pMotor pTheta, pMotor pOmega,
pMotor pChi, pMotor pPhi, pMotor pNu);
pHKL CreateHKL();
void DeleteHKL(void *pData);
int HKLFactory(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]);
/*------------------------------------------------------------------------*/
int SetWavelengthVariable(SConnection *pCon, pHKL self, pSelVar pVar);
int SetWavelengthManual(pHKL self, float fVal);
void SetHKLScanTolerance(pHKL self, float value);
int SetUB(pHKL self, float fUB[9]);
int GetUB(pHKL self, float fUB[9]);
@ -109,6 +88,7 @@ module:
int argc, char *argv[]);
int hklInRange(void *data, float fSet[4], int mask[4]);
int startHKLMotors(pHKL self, SConnection *pCon, float fSet[4]);
void stopHKLMotors(pHKL self);
@}
All functions return 0 on failure, 1 on success if not stated otherwise.
Most functions take a pointer to a HKL data structure as first parameter.

View File

@ -15,6 +15,7 @@
#include "hkl.h"
#include "hkl.i"
#include "hklmot.h"
#include "singlex.h"
/*=================== Object Descriptor Interface ===================================================*/
static void *HKLGetInterface(void *pData, int iID){
pHKLMot self = NULL;
@ -28,21 +29,15 @@ static void *HKLGetInterface(void *pData, int iID){
}
return NULL;
}
/*--------------------------------------------------------------------------------------------------*/
extern void stopHKLMotors(pHKL hkl);
/*=================== Drivable Interface ============================================================*/
static int HKLHalt(void *pData){
pHKLMot self = NULL;
self = (pHKLMot)pData;
assert(self != NULL);
self->pHkl->pTheta->pDrivInt->Halt(self->pHkl->pTheta);
self->pHkl->pOmega->pDrivInt->Halt(self->pHkl->pOmega);
if(self->pHkl->iNOR == 1){
self->pHkl->pNu->pDrivInt->Halt(self->pHkl->pNu);
} else {
self->pHkl->pChi->pDrivInt->Halt(self->pHkl->pChi);
self->pHkl->pPhi->pDrivInt->Halt(self->pHkl->pPhi);
}
stopHKLMotors(self->pHkl);
return 1;
}
/*-----------------------------------------------------------------------------------------------------*/
@ -72,26 +67,52 @@ static long HKLSetValue(void *pData, SConnection *pCon, float fVal){
/*---------------------------------------------------------------------------------------------------*/
static int checkMotors(pHKLMot self, SConnection *pCon){
int status;
pMotor pTheta, pOmega, pChi, pPhi, pNu;
status = self->pHkl->pTheta->pDrivInt->CheckStatus(self->pHkl->pTheta, pCon);
pTheta = SXGetMotor(TwoTheta);
pOmega = SXGetMotor(Omega);
pChi = SXGetMotor(Chi);
pPhi = SXGetMotor(Phi);
if(pTheta == NULL || pOmega == NULL){
SCWrite(pCon,"ERROR: configuration problem, stt,om motors not found,",
eError);
return HWFault;
}
status = pTheta->pDrivInt->CheckStatus(pTheta, pCon);
if(status != HWIdle && status != OKOK){
return status;
}
status = self->pHkl->pOmega->pDrivInt->CheckStatus(self->pHkl->pOmega, pCon);
status = pOmega->pDrivInt->CheckStatus(pOmega, pCon);
if(status != HWIdle && status != OKOK){
return status;
}
if(self->pHkl->iNOR == 1){
status = self->pHkl->pNu->pDrivInt->CheckStatus(self->pHkl->pNu, pCon);
if(SXGetMode() == NB){
pNu = SXGetMotor(Nu);
if(pNu == NULL){
SCWrite(pCon,"ERROR: configuration problem, nu motor not found,",
eError);
return HWFault;
}
status = pNu->pDrivInt->CheckStatus(pNu, pCon);
if(status != HWIdle && status != OKOK){
return status;
}
} else {
status = self->pHkl->pChi->pDrivInt->CheckStatus(self->pHkl->pChi, pCon);
pChi = SXGetMotor(Chi);
pPhi = SXGetMotor(Phi);
if(pTheta == NULL || pOmega == NULL){
SCWrite(pCon,"ERROR: configuration problem, chi, phi motors not found,",
eError);
return HWFault;
}
status = pChi->pDrivInt->CheckStatus(pChi, pCon);
if(status != HWIdle && status != OKOK){
return status;
}
status = self->pHkl->pPhi->pDrivInt->CheckStatus(self->pHkl->pPhi, pCon);
status = pPhi->pDrivInt->CheckStatus(pPhi, pCon);
if(status != HWIdle && status != OKOK){
return status;
}
@ -204,11 +225,11 @@ int HKLMotInstall(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, c
char pBuffer[131];
if(argc < 2){
SCWrite(pCon,"ERROR: Insifficient number of arguments to HKLMotInstall",eError);
return 0;
}
pHkl = (pHKL)FindCommandData(pSics,"hkl","4-Circle-Calculus");
} else {
strtolower(argv[1]);
pHkl = (pHKL)FindCommandData(pSics,argv[1],"4-Circle-Calculus");
}
if(pHkl == NULL){
snprintf(pBuffer,131,"ERROR: %s is not present or no HKL object",argv[1]);
SCWrite(pCon,pBuffer,eError);

View File

@ -45,9 +45,11 @@ static int HMCHalt(void *pData)
for(i = 0; i < self->nSlaves; i++)
{
status = self->slaves[i]->Halt(self->slaveData[i]);
ReleaseCountLock(self->slaves[i]);
if(status != OKOK)
retVal = status;
}
ReleaseCountLock(self->pCount);
return retVal;
}
/*-----------------------------------------------------------------------*/
@ -59,8 +61,13 @@ static int HMCStart(void *pData, SConnection *pCon)
self = (pHMcontrol)pData;
assert(self);
if(!GetCountLock(self->pCount, pCon)){
return HWFault;
}
for(i = 0; i < self->nSlaves; i++)
{
ReleaseCountLock(self->slaves[i]);
status = self->slaves[i]->StartCount(self->slaveData[i],pCon);
if(status != OKOK)
{

View File

@ -92,9 +92,9 @@ static int DriverList(SConnection *con, SicsInterp *sics,
if (argc < 2 || strcasecmp(argv[1], "list") == 0) {
for (p = list; p != NULL; p = p->next) {
if (argc < 3) {
SCPrintf(con, eStatus, "%s %s %s", p->type, p->name, p->desc);
SCPrintf(con, eValue, "%s %s %s", p->type, p->name, p->desc);
} else if (strcasecmp(argv[2], p->type) == 0) {
SCPrintf(con, eStatus, "%s %s", p->name, p->desc);
SCPrintf(con, eValue, "%s %s", p->name, p->desc);
}
}
} else {

View File

@ -167,6 +167,30 @@ int GetDrivablePosition(void *pObject, SConnection *pCon, float *fPos)
{
return (pICountable)FindInterface(pObject,COUNTID);
}
/*--------------------------------------------------------------------------*/
int GetCountLock(pICountable self, SConnection *pCon)
{
if(self->running == 1)
{
SCWrite(pCon,"ERROR: someone else is already counting!", eError);
return 0;
}
else
{
self->running = 1;
return 1;
}
}
/*--------------------------------------------------------------------------*/
void ReleaseCountLock(pICountable self)
{
self->running = 0;
}
/*--------------------------------------------------------------------------*/
int isRunning(pICountable self)
{
return self->running;
}
/*--------------------------------------------------------------------------*/
pICallBack GetCallbackInterface(void *pObject)
{

View File

@ -1,5 +1,5 @@
#line 379 "interface.w"
#line 399 "interface.w"
/*---------------------------------------------------------------------------
I N T E R F A C E S
@ -27,7 +27,7 @@
/* ----------------------- The drivable interface -----------------------*/
#line 119 "interface.w"
#line 121 "interface.w"
typedef struct {
@ -48,17 +48,18 @@
float *fPos);
#line 405 "interface.w"
#line 425 "interface.w"
pIDrivable CreateDrivableInterface(void);
/* ------------------------ The countable interface ---------------------*/
#line 186 "interface.w"
#line 188 "interface.w"
typedef struct {
int ID;
int running;
int (*Halt)(void *self);
void (*SetCountParameters)(void *self, float fPreset,
CounterMode eMode);\
@ -70,25 +71,27 @@
} ICountable, *pICountable;
pICountable GetCountableInterface(void *pObject);
int GetCountLock(pICountable self, SConnection *pCon);
void ReleaseCountLock(pICountable self);
int isRunning(pICountable self);
#line 410 "interface.w"
#line 430 "interface.w"
pICountable CreateCountableInterface(void);
/* ------------------------- The CallBack Interface --------------------*/
#line 239 "interface.w"
#line 253 "interface.w"
typedef void (*KillFuncIT)(void *pData);
typedef int (*SICSCallBack)(int iEvent, void *pEventData,
void *pUserData, commandContext cc);
void *pUserData);
#line 415 "interface.w"
#line 435 "interface.w"
#line 261 "interface.w"
#line 275 "interface.w"
typedef struct __ICallBack *pICallBack;
@ -98,22 +101,23 @@
int InvokeCallBack(pICallBack pInterface, int iEvent, void *pEventData);
/* callback client side */
long RegisterCallback(pICallBack pInterface, commandContext comCon,
long RegisterCallback(pICallBack pInterface,
int iEvent, SICSCallBack pFunc,
void *pUserData, KillFuncIT pKill);
int RemoveCallback(pICallBack pInterface, long iID);
int RemoveCallback2(pICallBack pInterface, void *pUserData);
int RemoveCallbackCon(pICallBack pInterface, SConnection *pCon);
int CallbackScript(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]);
pICallBack GetCallbackInterface(void *pData);
#line 416 "interface.w"
#line 436 "interface.w"
/*---------------------- The Environment Interface --------------------*/
#line 333 "interface.w"
#line 353 "interface.w"
typedef enum { EVIdle, EVDrive, EVMonitor, EVError } EVMode;
typedef struct {
@ -123,13 +127,13 @@
int (*HandleError)(void *self);
} EVInterface, *pEVInterface;
#line 418 "interface.w"
#line 438 "interface.w"
#line 359 "interface.w"
#line 379 "interface.w"
pEVInterface CreateEVInterface(void);
#line 419 "interface.w"
#line 439 "interface.w"
#endif

View File

@ -51,12 +51,14 @@ $\langle$obdes {\footnotesize ?}$\rangle\equiv$
\mbox{}\verb@#define SICSDESCRIPTOR@\\
\mbox{}\verb@#include <stdio.h>@\\
\mbox{}\verb@#include <ifile.h>@\\
\mbox{}\verb@#include <hipadaba.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@ IPair *pKeys;@\\
\mbox{}\verb@ pHdb parNode;@\\
\mbox{}\verb@ } ObjectDescriptor, *pObjectDescriptor;@\\
\mbox{}\verb@@\\
\mbox{}\verb@ /*---------------------------------------------------------------------------*/@\\
@ -81,7 +83,7 @@ $\langle$obdes {\footnotesize ?}$\rangle\equiv$
\mbox{}\verb@ int iHasType(void *pData, char *Type);@\\
\mbox{}\verb@ @\\
\mbox{}\verb@#endif @\\
\mbox{}\verb@@$\diamond$
\mbox{}\verb@@$\Diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
@ -152,7 +154,7 @@ $\langle$driv {\footnotesize ?}$\rangle\equiv$
\mbox{}\verb@ int GetDrivablePosition(void *pObject, SConnection *pCon,@\\
\mbox{}\verb@ float *fPos);@\\
\mbox{}\verb@@\\
\mbox{}\verb@@$\diamond$
\mbox{}\verb@@$\Diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
@ -216,6 +218,7 @@ $\langle$count {\footnotesize ?}$\rangle\equiv$
\mbox{}\verb@@\\
\mbox{}\verb@ typedef struct {@\\
\mbox{}\verb@ int ID;@\\
\mbox{}\verb@ int running;@\\
\mbox{}\verb@ int (*Halt)(void *self);@\\
\mbox{}\verb@ void (*SetCountParameters)(void *self, float fPreset,@\\
\mbox{}\verb@ CounterMode eMode);\@\\
@ -227,8 +230,10 @@ $\langle$count {\footnotesize ?}$\rangle\equiv$
\mbox{}\verb@ } ICountable, *pICountable;@\\
\mbox{}\verb@@\\
\mbox{}\verb@ pICountable GetCountableInterface(void *pObject); @\\
\mbox{}\verb@@\\
\mbox{}\verb@@$\diamond$
\mbox{}\verb@ int GetCountLock(pICountable self, SConnection *pCon);@\\
\mbox{}\verb@ void ReleaseCountLock(pICountable self);@\\
\mbox{}\verb@ int isRunning(pICountable self);@\\
\mbox{}\verb@@$\Diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
@ -237,6 +242,8 @@ $\langle$count {\footnotesize ?}$\rangle\equiv$
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
{\bf running } Is a flag which says if the counter is operating or not.
{\bf Halt and StartCount} are self explaining, they just do what they say. Please
note, that counting configuration must have happened before usage of this
interface.
@ -260,6 +267,13 @@ the existence of a countable interface. If it exists a pointer to it will be
returned. NEVER free this pointer. If no countable interface exists, NULL
will be returned.
{\bf GetCountLock} will try to set the running flag. If it is already running, an error
is printed to pCon and 0 is returned.
{\bf ReleaseCountLock} release the count lock.
{\bf isRunning} returns the running flag.
\subsubsection{The Callback Interface}
The Callback Interface is SICS suport for component behaviour for objects.
Consider objects A and B. A now is able to generate certain events when it's
@ -281,8 +295,8 @@ $\langle$callfunc {\footnotesize ?}$\rangle\equiv$
\mbox{}\verb@@\\
\mbox{}\verb@ typedef void (*KillFuncIT)(void *pData);@\\
\mbox{}\verb@ typedef int (*SICSCallBack)(int iEvent, void *pEventData, @\\
\mbox{}\verb@ void *pUserData, commandContext cc);@\\
\mbox{}\verb@@$\diamond$
\mbox{}\verb@ void *pUserData);@\\
\mbox{}\verb@@$\Diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
@ -321,17 +335,18 @@ $\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, commandContext comCon, @\\
\mbox{}\verb@ long RegisterCallback(pICallBack pInterface, @\\
\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);@\\
\mbox{}\verb@ int RemoveCallbackCon(pICallBack pInterface, SConnection *pCon);@\\
\mbox{}\verb@@\\
\mbox{}\verb@ int CallbackScript(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
\mbox{}\verb@ int argc, char *argv[]); @\\
\mbox{}\verb@@\\
\mbox{}\verb@ pICallBack GetCallbackInterface(void *pData); @\\
\mbox{}\verb@@$\diamond$
\mbox{}\verb@@$\Diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
@ -378,6 +393,11 @@ RegisterCallBack.
search key for deletion is the pointer to user data. All callbacks related
to this user data in the interface specified will be removed.
{\bf RemoveCallbackCon} is another variant for removing callbacks. This time the
search key for deletion is the pointer to user data which must be a connection object.
All callbacks related to this connection in the interface specified will be removed. This is
a convenience function for removing interest callbacks in SICS.
{\bf CallbackScript} allows to connect callbacks to scripts. Please
note, that those scripts will have a dummy connection to clients only
and will not be able to write to clients. All output occurring in
@ -404,7 +424,7 @@ $\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@@$\Diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
@ -437,7 +457,7 @@ $\langle$envfunc {\footnotesize ?}$\rangle\equiv$
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@ pEVInterface CreateEVInterface(void);@\\
\mbox{}\verb@@$\diamond$
\mbox{}\verb@@$\Diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
@ -465,7 +485,7 @@ $\langle$envfunc {\footnotesize ?}$\rangle\equiv$
\mbox{}\verb@ char * GetDescriptorKey(pObjectDescriptor self, char *keyName);@\\
\mbox{}\verb@ char * GetDescriptorGroup(pObjectDescriptor self);@\\
\mbox{}\verb@ char * GetDescriptorDescription(pObjectDescriptor self);@\\
\mbox{}\verb@@$\diamond$
\mbox{}\verb@@$\Diamond$
\end{list}
\vspace{-2ex}
\end{minipage}\\[4ex]
@ -517,7 +537,7 @@ $\langle$envfunc {\footnotesize ?}$\rangle\equiv$
\mbox{}\verb@@$\langle$envir {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@@$\langle$envfunc {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@#endif@\\
\mbox{}\verb@@$\diamond$
\mbox{}\verb@@$\Diamond$
\end{list}
\vspace{-2ex}
\end{minipage}\\[4ex]

View File

@ -46,12 +46,14 @@ Let's start with the objectdescriptor:
#define SICSDESCRIPTOR
#include <stdio.h>
#include <ifile.h>
#include <hipadaba.h>
typedef struct {
char *name;
int (*SaveStatus)(void *self, char *name,FILE *fd);
void *(*GetInterface)(void *self, int iInterfaceID);
IPair *pKeys;
pHdb parNode;
} ObjectDescriptor, *pObjectDescriptor;
/*---------------------------------------------------------------------------*/
@ -186,6 +188,7 @@ This is an interface for interacting with anything which counts.
@d count @{
typedef struct {
int ID;
int running;
int (*Halt)(void *self);
void (*SetCountParameters)(void *self, float fPreset,
CounterMode eMode);\
@ -197,9 +200,13 @@ This is an interface for interacting with anything which counts.
} ICountable, *pICountable;
pICountable GetCountableInterface(void *pObject);
int GetCountLock(pICountable self, SConnection *pCon);
void ReleaseCountLock(pICountable self);
int isRunning(pICountable self);
@}
{\bf running } Is a flag which says if the counter is operating or not.
{\bf Halt and StartCount} are self explaining, they just do what they say. Please
note, that counting configuration must have happened before usage of this
interface.
@ -223,6 +230,13 @@ the existence of a countable interface. If it exists a pointer to it will be
returned. NEVER free this pointer. If no countable interface exists, NULL
will be returned.
{\bf GetCountLock} will try to set the running flag. If it is already running, an error
is printed to pCon and 0 is returned.
{\bf ReleaseCountLock} release the count lock.
{\bf isRunning} returns the running flag.
\subsubsection{The Callback Interface}
The Callback Interface is SICS suport for component behaviour for objects.
Consider objects A and B. A now is able to generate certain events when it's
@ -239,7 +253,7 @@ function:
@d callfunc @{
typedef void (*KillFuncIT)(void *pData);
typedef int (*SICSCallBack)(int iEvent, void *pEventData,
void *pUserData, commandContext cc);
void *pUserData);
@}
The callback function is meant to return 0 for failure or 1 for success.
@ -267,11 +281,12 @@ interface:
int InvokeCallBack(pICallBack pInterface, int iEvent, void *pEventData);
/* callback client side */
long RegisterCallback(pICallBack pInterface, commandContext comCon,
long RegisterCallback(pICallBack pInterface,
int iEvent, SICSCallBack pFunc,
void *pUserData, KillFuncIT pKill);
int RemoveCallback(pICallBack pInterface, long iID);
int RemoveCallback2(pICallBack pInterface, void *pUserData);
int RemoveCallbackCon(pICallBack pInterface, SConnection *pCon);
int CallbackScript(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]);
@ -317,6 +332,11 @@ RegisterCallBack.
search key for deletion is the pointer to user data. All callbacks related
to this user data in the interface specified will be removed.
{\bf RemoveCallbackCon} is another variant for removing callbacks. This time the
search key for deletion is the pointer to user data which must be a connection object.
All callbacks related to this connection in the interface specified will be removed. This is
a convenience function for removing interest callbacks in SICS.
{\bf CallbackScript} allows to connect callbacks to scripts. Please
note, that those scripts will have a dummy connection to clients only
and will not be able to write to clients. All output occurring in

86
macro.c
View File

@ -529,7 +529,7 @@ extern int Nxinter_SafeInit(Tcl_Interp *pTcl); /* from Swig NeXus Tcl interface
if(FindCommand(pInter,pBueffel) != NULL)
{
sprintf(pBueffel,"%s:%d>> %s",pFile,iLine,pCom);
SCWrite(pCon,pBueffel,eValue);
SCWrite(pCon,pBueffel,eLog);
if(pWhere != NULL)
{
free(pWhere);
@ -627,21 +627,6 @@ extern int Nxinter_SafeInit(Tcl_Interp *pTcl); /* from Swig NeXus Tcl interface
}
SCnoSock(pIntern);
/* configure the log file */
pFil = strdup(argv[1]);
pExt = strrchr(pFil,(int)'.');
if(!pExt)
{
SCWrite(pCon,"ERROR: no extension found in InternalFileEval",
eError);
return 0;
}
else
{
strcpy(pExt,".log");
SCAddLogFile(pIntern,pFil);
free(pFil);
}
/* invoke the fileeval */
MacroPush(pIntern);
@ -664,9 +649,8 @@ extern int Nxinter_SafeInit(Tcl_Interp *pTcl); /* from Swig NeXus Tcl interface
int ClientPut(SConnection *pCon, SicsInterp *pInter, void *pData,
int argc, char *argv[])
{
OutCode eOut = eWarning;
OutCode eOut = eLog;
int i = 0, iCode, iLen;
int iMacro;
char *ppCode;
char *pMessage = NULL;
@ -701,7 +685,7 @@ extern int Nxinter_SafeInit(Tcl_Interp *pTcl); /* from Swig NeXus Tcl interface
}
else
{
i = 10;
i = eLog;
iCode = argc;
}
@ -740,8 +724,14 @@ extern int Nxinter_SafeInit(Tcl_Interp *pTcl); /* from Swig NeXus Tcl interface
case 10:
eOut = eError;
break;
case 11:
eOut = eLog;
break;
case 12:
eOut = eLogError;
break;
default:
eOut = eWarning;
eOut = eLog;
iCode = argc;
break;
}
@ -756,19 +746,13 @@ extern int Nxinter_SafeInit(Tcl_Interp *pTcl); /* from Swig NeXus Tcl interface
pMessage = (char *)malloc((iLen+100)*sizeof(char));
if(!pMessage)
{
SCWrite(pCon,"ERROR: out of memory in clientput",eError);
SCWrite(pCon,"ERROR: out of memory in clientput",eLogError);
return 0;
}
memset(pMessage,0,(iLen+100)*sizeof(char));
Arg2Text(iCode-1,&argv[1],pMessage,(iLen+100)*sizeof(char));
/* now write, thereby tunneling macro flag in order to get proper
write to client and not into interpreter
*/
iMacro = SCinMacro(pCon);
SCsetMacro(pCon,0);
SCWrite(pCon,pMessage,eOut);
SCsetMacro(pCon,iMacro);
if(pMessage)
{
free(pMessage);
@ -784,14 +768,14 @@ extern int Nxinter_SafeInit(Tcl_Interp *pTcl); /* from Swig NeXus Tcl interface
int iMacro;
char *ppCode;
char *pMessage = NULL;
commandContext cc;
SConnection *conCon = NULL;
assert(pCon);
assert(pInter);
if(argc < 2)
{
SCWrite(pCon,"Insufficient arguments to ClientPut",eError);
SCWrite(pCon,"Insufficient arguments to ClientPut",eLogError);
return 0;
}
@ -856,8 +840,14 @@ extern int Nxinter_SafeInit(Tcl_Interp *pTcl); /* from Swig NeXus Tcl interface
case 10:
eOut = eError;
break;
case 11:
eOut = eLog;
break;
case 12:
eOut = eLogError;
break;
default:
eOut = eWarning;
eOut = eLog;
iCode = argc;
break;
}
@ -882,14 +872,13 @@ extern int Nxinter_SafeInit(Tcl_Interp *pTcl); /* from Swig NeXus Tcl interface
write to client and not into interpreter. We also make sure that the device
is gumput
*/
iMacro = SCinMacro(pCon);
SCsetMacro(pCon,0);
cc = SCGetContext(pCon);
strcpy(cc.deviceID,"gumput");
SCPushContext2(pCon,cc);
SCWrite(pCon,pMessage,eOut);
SCPopContext(pCon);
SCsetMacro(pCon,iMacro);
conCon = SCCopyConnection(pCon);
if(conCon == NULL){
SCWrite(pCon,"ERROR: out of memory in gumput", eError);
}
strcpy(conCon->deviceID,"gumput");
SCWrite(conCon,pMessage,eOut);
SCDeleteConnection(conCon);
if(pMessage)
{
free(pMessage);
@ -908,7 +897,7 @@ extern int Nxinter_SafeInit(Tcl_Interp *pTcl); /* from Swig NeXus Tcl interface
if(argc < 2)
{
SCWrite(pCon,"Insufficient arguments to Broadcast",eError);
SCWrite(pCon,"Insufficient arguments to Broadcast",eLog);
return 0;
}
@ -917,10 +906,7 @@ extern int Nxinter_SafeInit(Tcl_Interp *pTcl); /* from Swig NeXus Tcl interface
write to client and not into interpreter
*/
Arg2Text(argc-1, &argv[1],pBueffel,255);
iMacro = SCinMacro(pCon);
SCsetMacro(pCon,0);
ServerWriteGlobal(pBueffel,eWarning);
SCsetMacro(pCon,iMacro);
ServerWriteGlobal(pBueffel,eLog);
return 1;
}
/*---------------------------------------------------------------------------
@ -1013,13 +999,14 @@ extern int Nxinter_SafeInit(Tcl_Interp *pTcl); /* from Swig NeXus Tcl interface
SCWrite(pCon, "ERROR: no more memory", eError);
return 0;
}
Tcl_ResetResult(pTcl);
iRet = Tcl_Eval(pTcl,pCommand);
if (pCommand != pBueffel) free(pCommand);
if(iRet == TCL_OK)
{
if(strlen(pTcl->result) > 0){
SCPrintf(pCon, eStatus, "%s", pTcl->result);
SCPrintf(pCon, eValue, "%s", pTcl->result);
}
if (pCommand != pBueffel) free(pCommand);
return 1;
}
else
@ -1028,7 +1015,10 @@ extern int Nxinter_SafeInit(Tcl_Interp *pTcl); /* from Swig NeXus Tcl interface
{
Tcl_UnsetVar(pTcl,SICSERROR,TCL_GLOBAL_ONLY);
}
SCPrintf(pCon,eError,"%s",pTcl->result);
if(strlen(pTcl->result) > 0){
SCPrintf(pCon,eError,"ERROR: Tcl reported %s in %s",pTcl->result, pCommand);
}
if (pCommand != pBueffel) free(pCommand);
return 0;
}
return 1; /* not reached */
@ -1117,11 +1107,11 @@ extern int Nxinter_SafeInit(Tcl_Interp *pTcl); /* from Swig NeXus Tcl interface
}
strtolower(argv[0]);
if(strcmp(argv[0],"fulltransact") == 0){
SCPrintf(pCon,eError, "TRANSACTIONSTART %s",pCommand);
SCPrintf(pCon,eLog, "TRANSACTIONSTART %s",pCommand);
}
iRet = InterpExecute(pSics,pCon,pCommand);
if (pCommand != pBuffer) free(pCommand);
SCWrite(pCon,"TRANSACTIONFINISHED",eError);
SCWrite(pCon,"TRANSACTIONFINISHED",eLog);
return iRet;
}

View File

@ -21,7 +21,7 @@ SOBJ = network.o ifile.o conman.o SCinter.o splitter.o passwd.o \
mesure.o uubuffer.o commandlog.o udpquieck.o fourtable.o\
rmtrail.o help.o nxupdate.o confvirtualmot.o vector.o\
simchop.o choco.o chadapter.o trim.o scaldate.o tasub.o\
hklscan.o xytable.o exebuf.o exeman.o ubfour.o ubcalc.o\
xytable.o exebuf.o exeman.o ubfour.o ubcalc.o\
circular.o maximize.o sicscron.o scanvar.o tasublib.o\
d_sign.o d_mod.o tcldrivable.o stdscan.o diffscan.o nxxml.o\
synchronize.o definealias.o oscillate.o tasdrive.o \
@ -37,7 +37,10 @@ SOBJ = network.o ifile.o conman.o SCinter.o splitter.o passwd.o \
sicshdbadapter.o polldriv.o sicspoll.o statemon.o hmslave.o \
nwatch.o asyncqueue.o asyncprotocol.o sicsobj.o \
nxcopy.o nxinterhelper.o nxinter_wrap.o genericcontroller.o nxstack.o \
sctdriveadapter.o sctdriveobj.o uselect.o
sctdriveadapter.o sctdriveobj.o reflist.o singlex.o fourmess.o \
sgclib.o sgfind.o sgio.o sgsi.o sghkl.o singlediff.o singlebi.o \
singlenb.o simindex.o simidx.o uselect.o singletas.o motorsec.o \
rwpuffer.o asynnet.o background.o
MOTOROBJ = motor.o simdriv.o
COUNTEROBJ = countdriv.o simcter.o counter.o
@ -60,7 +63,7 @@ full: purge all
SICServer: $(SOBJ) $(MOTOROBJ) $(COUNTEROBJ) \
$(VELOOBJ) $(DIFIL) $(EXTRA) \
$(SUBLIBS)
$(CC) -g -pg -o SICServer \
$(CC) -g -o SICServer \
$(SOBJ) $(MOTOROBJ) $(COUNTEROBJ) \
$(VELOOBJ) $(DIFOBJ) $(EXTRA) $(LIBS)

View File

@ -50,7 +50,7 @@
#include "motor.h"
#define MAXPTS 100
#define DEBUG 1
#define DEBUG 0
typedef struct __MAXIMIZE {
pObjectDescriptor pDes;
@ -382,8 +382,14 @@
fCent = x[i] +(fDisc -y[i])/fS;
}
/* finished ! */
for(i = 0; i < iTop-1; i++){
if(fCent >= x[i] && fCent < x[i+1] ){
lCts = y[i];
break;
}
}
maxDrive(pVar,pVarName,fCent,pCon);
sprintf(pBueffel,"Found peak center at %8.2f", fCent);
sprintf(pBueffel,"Found peak center at %8.2f, Count = %ld", fCent, lCts);
SCWrite(pCon,pBueffel,eValue);
return 1;
}

View File

@ -671,7 +671,7 @@ static int ScanReflection(pMesure self, float twoTheta, SConnection *pCon)
AddScanVar(self->pScanner, pServ->pSics,pCon,self->pCOmega,
fStart, stepWidth);
snprintf(pBueffel,131,"Scanning om from %f with step %f", fStart, stepWidth);
SCWrite(pCon,pBueffel,eValue);
SCWrite(pCon,pBueffel,eLog);
/*
Oksana does not want o2t scans to be tightly coupled, this is why we
cannot use the normal o2t scan variable. Instead we calculate new limits and
@ -688,7 +688,7 @@ static int ScanReflection(pMesure self, float twoTheta, SConnection *pCon)
AddScanVar(self->pScanner, pServ->pSics,pCon,self->pC2Theta,
fStart, stepWidth);
snprintf(pBueffel,131,"Scanning 2theta from %f with step %f", fStart, stepWidth);
SCWrite(pCon,pBueffel,eValue);
SCWrite(pCon,pBueffel,eLog);
}
/*
@ -744,7 +744,7 @@ static int ScanReflection(pMesure self, float twoTheta, SConnection *pCon)
/*
redo scan with preset * 5
*/
SCWrite(pCon,"Remeasuring weak reflection",eWarning);
SCWrite(pCon,"Remeasuring weak reflection",eLog);
iRet = SilentScan(self->pScanner,np,self->CountMode,
fPreset*5.,pServ->pSics,pCon);
@ -811,7 +811,9 @@ static int ScanReflection(pMesure self, float twoTheta, SConnection *pCon)
/* do the logfile */
strcpy(pFilename,pRoot);
strcat(pFilename,"log");
/* TODO
self->iLogFile = SCAddLogFile(pCon,pFilename);
*/
self->pCon = pCon;
/*
@ -916,7 +918,9 @@ static int ScanReflection(pMesure self, float twoTheta, SConnection *pCon)
strcat(pFile,"/");
strcat(pFile,fileroot);
strcat(pFile,".log");
/* TODO:
self->iLogFile = SCAddLogFile(pCon,pFile);
*/
self->pCon = pCon;
/*
@ -960,7 +964,9 @@ static int ScanReflection(pMesure self, float twoTheta, SConnection *pCon)
{
assert(self);
SCDelLogFile(self->pCon,self->iLogFile);
/* TODO
* SCDelLogFile(self->pCon,self->iLogFile);
*/
if(self->psd == 1)
{
self->pCon = NULL;
@ -1094,7 +1100,7 @@ static double getProtonAverage(pMesure self){
self->fPosition[0], self->fPosition[1],
self->fPosition[2],self->fPosition[3],
fSum,fSigma);
SCWrite(pCon,pBueffel,eStatus);
SCWrite(pCon,pBueffel,eLog);
/* get temperature */
fTemp = -777.77;
@ -1218,7 +1224,7 @@ static double getProtonAverage(pMesure self){
/* make a mark */
SNXFormatTime(pTime,131);
sprintf(pBueffel,"Starting at list %s at %s",pFile,pTime);
SCWrite(pCon,pBueffel,eStatus);
SCWrite(pCon,pBueffel,eLog);
/* skippy! */
for(i = 0; i < iSkip; i++)
@ -1272,7 +1278,7 @@ static double getProtonAverage(pMesure self){
/* we are done */
SNXFormatTime(pTime,131);
sprintf(pBueffel,"Finishing list %s at %s",pFile,pTime);
SCWrite(pCon,pBueffel,eStatus);
SCWrite(pCon,pBueffel,eLog);
fclose(fd);
return 1;
@ -1366,7 +1372,7 @@ static double getProtonAverage(pMesure self){
/* make a mark */
SNXFormatTime(pTime,131);
sprintf(pBueffel,"Starting at list %s at %s",pFile,pTime);
SCWrite(pCon,pBueffel,eStatus);
SCWrite(pCon,pBueffel,eLog);
/* skippy! */
for(i = 0; i < iSkip; i++)
@ -1409,7 +1415,7 @@ static double getProtonAverage(pMesure self){
/* we are done */
SNXFormatTime(pTime,131);
sprintf(pBueffel,"Finishing list %s at %s",pFile,pTime);
SCWrite(pCon,pBueffel,eStatus);
SCWrite(pCon,pBueffel,eLog);
fclose(fd);
return 1;

View File

@ -200,6 +200,12 @@ static int RGSetDriverPar(void *data, SConnection *pCon,
} else if (strcmp(name,"recover") == 0){
self->recover = (int)value;
return 1;
} else if(strcmp(name,"hardupperlim") == 0) {
self->fUpper = value;
return 1;
} else if(strcmp(name,"hardlowerlim") == 0){
self->fLower = value;
return 1;
}
return 0;
}

625
motor.c
View File

@ -10,6 +10,10 @@
endscript facility added: Mark Koennecke, August 2002
Modified to support driver parameters, Mark Koennecke, January 2003
Reworked to allow for multiple implementations of motors on the same
interface in preparation for second generation motors.
Mark Koennecke, December 2008
Copyright:
Labor fuer Neutronenstreuung
@ -115,7 +119,71 @@
self->stopped = 1;
return self->pDriver->Halt((void *)self->pDriver);
}
/*---------------------------------------------------------------------------
MotorCheckBoundary checks for violation of boundary conditions and
transforms from SoftCoordinates to hard coordinates.
*/
static int MotorCheckBoundaryImpl(pMotor self, float fVal, float *fNew,
char *pError, int iErrLen)
{
float fHard;
float fZero;
char pBueffel[512];
assert(self);
/* check for fixed */
if(ObVal(self->ParArray,FIX) >= 0)
{
sprintf(pBueffel,"Motor %s is Fixed",self->name);
strncpy(pError,pBueffel,iErrLen);
return 0; /* is this an error? */
}
/* check against software boundaries */
if(fVal > ObVal(self->ParArray,SUPP))
{
sprintf(pBueffel,"%f violates upper software limit %f on %s",
fVal, ObVal(self->ParArray,SUPP),self->name);
strncpy(pError,pBueffel,iErrLen);
return 0;
}
if(fVal < ObVal(self->ParArray,SLOW))
{
sprintf(pBueffel,"%f violates lower software limit %f on %s",
fVal,ObVal(self->ParArray,SLOW),self->name );
strncpy(pError,pBueffel,iErrLen);
return 0;
}
/* correct for zero point */
fZero = ObVal(self->ParArray,SZERO);
fZero = -fZero;
fHard = fVal - fZero;
/* apply sign */
fHard = fHard*ObVal(self->ParArray,SIGN);
/* check for hardware limits */
if(fHard > self->pDriver->fUpper)
{
sprintf(pBueffel,"%f violates upper hardware limit %f on %s",
fVal,self->pDriver->fUpper,self->name);
strncpy(pError,pBueffel,iErrLen);
return 0;
}
if(fHard < self->pDriver->fLower)
{
sprintf(pBueffel,"%f violates lower hardware limit %f on %s",
fVal,self->pDriver->fLower,self->name);
strncpy(pError,pBueffel,iErrLen);
return 0;
}
*fNew = fHard;
return 1;
}
/*--------------------------------------------------------------------------*/
static int MotorLimits(void *sulf, float fVal, char *error, int iErrLen)
{
@ -126,7 +194,41 @@
self = (pMotor)sulf;
return MotorCheckBoundary(self,fVal,&fHard,error,iErrLen);
return MotorCheckBoundaryImpl(self,fVal,&fHard,error,iErrLen);
}
/* ------------------------------------------------------------------------*/
static int MotorGetSoftPositionImpl(pMotor self, SConnection *pCon, float *fVal)
{
int iRet;
float fValue;
assert(self);
assert(pCon);
/* get the hard position */
iRet = MotorGetHardPosition(self,pCon,&fValue);
if(!iRet)
{
*fVal = fValue;
return 0;
}
/* apply zeropoint */
if(ObVal(self->ParArray,SIGN) < 0.)
{
fValue += ObVal(self->ParArray,SZERO);
}
else
{
fValue -= ObVal(self->ParArray,SZERO);
}
*fVal = fValue;
/* apply sign */
/* *fVal = MotorHardToSoftPosition(self,fValue); */
*fVal = fValue*ObVal(self->ParArray,SIGN);
return 1;
}
/*---------------------------------------------------------------------------*/
static float MotorGetValue(void *pData, SConnection *pCon)
@ -135,7 +237,7 @@
float fVal = 0.;
assert(pData);
iRet = MotorGetSoftPosition((pMotor)pData,pCon,&fVal);
iRet = MotorGetSoftPositionImpl((pMotor)pData,pCon,&fVal);
if(iRet != OKOK)
{
fVal = -9999999.99;
@ -397,143 +499,22 @@ static void handleMoveCallback(pMotor self, SConnection *pCon)
return status;
}
/*---------------------------------------------------------------------------*/
pMotor MotorInit(char *drivername, char *name, MotorDriver *pDriv)
{
pMotor pM = NULL;
assert(drivername);
assert(pDriv);
assert(name);
/* get memory */
pM = (pMotor)malloc(sizeof(Motor));
if(!pM)
{
return NULL;
}
/* create and initialize parameters */
pM->ParArray = ObParCreate(MOTOBPARLENGTH);
if(!pM->ParArray)
{
free(pM);
return NULL;
}
ObParInit(pM->ParArray,SLOW,"softlowerlim",pDriv->fLower,usUser);
ObParInit(pM->ParArray,SUPP,"softupperlim",pDriv->fUpper,usUser);
ObParInit(pM->ParArray,SZERO,"softzero",ZEROINACTIVE,usUser);
ObParInit(pM->ParArray,FIX,"fixed",-1,usUser);
ObParInit(pM->ParArray,INT,"interruptmode",INTCONT,usMugger);
ObParInit(pM->ParArray,PREC,"precision",0.01,usMugger);
ObParInit(pM->ParArray,USRIGHTS,"accesscode",(float)usUser,usMugger);
ObParInit(pM->ParArray,SIGN,"sign",1.0,usMugger);
ObParInit(pM->ParArray,ECOUNT,"failafter",3.0,usMugger);
ObParInit(pM->ParArray,POSCOUNT,"maxretry",3.0,usMugger);
ObParInit(pM->ParArray,IGNOREFAULT,"ignorefault",0.0,usMugger);
ObParInit(pM->ParArray,MOVECOUNT,"movecount",10.0,usMugger);
pDriv->GetPosition(pDriv,&(pM->fPosition));
pM->fTarget = pM->fPosition;
pM->endScriptID = 0;
/* copy arguments */
pM->pDriver = pDriv;
pM->drivername = strdup(drivername);
pM->name = strdup(name);
/* initialise object descriptor */
pM->pDescriptor = CreateDescriptor("Motor");
if(!pM->pDescriptor)
{
ObParDelete(pM->ParArray);
free(pM);
return NULL;
}
pM->pDescriptor->GetInterface = MotorGetInterface;
pM->pDescriptor->SaveStatus = MotorSaveStatus;
/* initialise Drivable interface */
pM->pDrivInt = CreateDrivableInterface();
if(!pM->pDrivInt)
{
DeleteDescriptor(pM->pDescriptor);
ObParDelete(pM->ParArray);
free(pM);
return NULL;
}
pM->pDrivInt->SetValue = MotorRun;
pM->pDrivInt->CheckLimits = MotorLimits;
pM->pDrivInt->CheckStatus = MotorStatus;
pM->pDrivInt->GetValue = MotorGetValue;
pM->pDrivInt->Halt = MotorHalt;
/* initialise callback interface */
pM->pCall = CreateCallBackInterface();
if(!pM->pCall)
{
MotorKill(pM);
return NULL;
}
/* done */
return pM;
}
int MotorGetPar(pMotor self, char *name, float *fVal)
{
return self->MotorGetPar(self,name,fVal);
}
/*---------------------------------------------------------------------------*/
int MotorSetPar(pMotor self, SConnection *pCon, char *name, float fVal)
{
return self->MotorSetPar(self,pCon,name,fVal);
}
/*---------------------------------------------------------------------------*/
int MotorGetHardPosition(pMotor self,SConnection *pCon, float *fVal)
{
return self->MotorGetHardPosition(self, pCon, fVal);
}
/*--------------------------------------------------------------------------*/
extern void KillPiPiezo(void *pData);
void MotorKill(void *self)
{
pMotor pM;
assert(self);
pM = (pMotor)self;
/* MotorHalt(pM); */
if(pM->name)
free(pM->name);
if(pM->pDrivInt)
{
free(pM->pDrivInt);
}
if(pM->pCall)
{
DeleteCallBackInterface(pM->pCall);
}
/* kill driver */
if(pM->drivername)
{
if(pM->pDriver->KillPrivate != NULL)
{
pM->pDriver->KillPrivate(pM->pDriver);
if(pM->pDriver->name != NULL)
{
free(pM->pDriver->name);
}
free(pM->pDriver);
}
free(pM->drivername);
}
/* get rid of parameter space */
if(pM->ParArray)
{
ObParDelete(pM->ParArray);
}
/* kill Descriptor */
DeleteDescriptor(pM->pDescriptor);
free(pM);
}
/*--------------------------------------------------------------------------*/
int MotorGetPar(pMotor self, char *name, float *fVal)
static int MotorGetParImpl(pMotor self, char *name, float *fVal)
{
ObPar *pPar = NULL;
assert(self);
@ -585,7 +566,7 @@ extern void KillPiPiezo(void *pData);
}
}
/*---------------------------------------------------------------------------*/
int MotorSetPar(pMotor self, SConnection *pCon, char *name, float fVal)
static int MotorSetParImpl(pMotor self, SConnection *pCon, char *name, float fVal)
{
ObPar *pPar = NULL;
char pBueffel[512];
@ -657,73 +638,61 @@ extern void KillPiPiezo(void *pData);
return iRet;
}
/*---------------------------------------------------------------------------
MotorCheckBoundary checks for violation of boundary conditions and
transforms from SoftCoordinates to hard coordinates.
*/
int MotorCheckBoundary(pMotor self, float fVal, float *fNew,
char *pError, int iErrLen)
/*------------------------------------------------------------------------*/
static int MotorGetHardPositionImpl(pMotor self,SConnection *pCon, float *fHard)
{
float fHard;
float fZero;
char pBueffel[512];
int iRet, iCode;
float fVal;
char pBueffel[512],pError[256];
assert(self);
assert(pCon);
/* check for fixed */
if(ObVal(self->ParArray,FIX) >= 0)
iRet = self->pDriver->GetPosition(self->pDriver,&fVal);
if(iRet == OKOK) /* all went well, the exception */
{
sprintf(pBueffel,"Motor %s is Fixed",self->name);
strncpy(pError,pBueffel,iErrLen);
return 0; /* is this an error? */
}
/* check against software boundaries */
if(fVal > ObVal(self->ParArray,SUPP))
{
sprintf(pBueffel,"%f violates upper software limit %f on %s",
fVal, ObVal(self->ParArray,SUPP),self->name);
strncpy(pError,pBueffel,iErrLen);
return 0;
}
if(fVal < ObVal(self->ParArray,SLOW))
{
sprintf(pBueffel,"%f violates lower software limit %f on %s",
fVal,ObVal(self->ParArray,SLOW),self->name );
strncpy(pError,pBueffel,iErrLen);
return 0;
}
/* correct for zero point */
fZero = ObVal(self->ParArray,SZERO);
fZero = -fZero;
fHard = fVal - fZero;
/* apply sign */
fHard = fHard*ObVal(self->ParArray,SIGN);
/* check for hardware limits */
if(fHard > self->pDriver->fUpper)
{
sprintf(pBueffel,"%f violates upper hardware limit %f on %s",
fVal,self->pDriver->fUpper,self->name);
strncpy(pError,pBueffel,iErrLen);
return 0;
}
if(fHard < self->pDriver->fLower)
{
sprintf(pBueffel,"%f violates lower hardware limit %f on %s",
fVal,self->pDriver->fLower,self->name);
strncpy(pError,pBueffel,iErrLen);
return 0;
}
*fNew = fHard;
*fHard = fVal;
return 1;
}
else /* a problem, the usual case: try fix the problem */
{ /* no point in trying this three times */
self->pDriver->GetError(self->pDriver,&iCode, pError,255);
iRet = self->pDriver->TryAndFixIt(self->pDriver,iCode, fVal);
sprintf(pBueffel,"WARNING: Trying to fix %s",pError);
SCWrite(pCon,pBueffel,eWarning);
switch(iRet)
{
case MOTFAIL:
sprintf(pBueffel,"ERROR: cannot fix motor %s",
self->name);
SCWrite(pCon,pBueffel,eError);
SCSetInterrupt(pCon,(int)ObVal(self->ParArray,INT));
*fHard = fVal;
return 0;
case MOTOK:
case MOTREDO:
iRet = self->pDriver->GetPosition(self->pDriver,&fVal);
if(iRet)
{
*fHard = fVal*ObVal(self->ParArray,SIGN);
return 1;
}
else
{
sprintf(pBueffel,"ERROR: cannot fix motor %s",
self->name);
SCSetInterrupt(pCon,(int)ObVal(self->ParArray,INT));
SCWrite(pCon,pBueffel,eError);
*fHard = fVal;
return 0;
}
}
}
*fHard = fVal*ObVal(self->ParArray,SIGN);
return 0;
}
/*---------------------------------------------------------------------------*/
long MotorRun(void *sulf, SConnection *pCon, float fNew)
static long MotorRunImpl(void *sulf, SConnection *pCon, float fNew)
{
float fHard;
int i, iRet, iCode;
@ -748,7 +717,7 @@ extern void KillPiPiezo(void *pData);
}
/* check boundaries first */
iRet = MotorCheckBoundary(self,fNew,&fHard,pError,131);
iRet = MotorCheckBoundaryImpl(self,fNew,&fHard,pError,131);
if(!iRet)
{
snprintf(pBueffel,511,"ERROR: %s",pError);
@ -824,58 +793,170 @@ extern void KillPiPiezo(void *pData);
}
return OKOK;
}
/*------------------------------------------------------------------------*/
int MotorGetHardPosition(pMotor self,SConnection *pCon, float *fHard)
/*---------------------------------------------------------------------------*/
pMotor MotorInit(char *drivername, char *name, MotorDriver *pDriv)
{
int iRet, iCode;
float fVal;
char pBueffel[512],pError[256];
pMotor pM = NULL;
assert(drivername);
assert(pDriv);
assert(name);
/* get memory */
pM = (pMotor)malloc(sizeof(Motor));
if(!pM)
{
return NULL;
}
/* create and initialize parameters */
pM->ParArray = ObParCreate(MOTOBPARLENGTH);
if(!pM->ParArray)
{
free(pM);
return NULL;
}
ObParInit(pM->ParArray,SLOW,"softlowerlim",pDriv->fLower,usUser);
ObParInit(pM->ParArray,SUPP,"softupperlim",pDriv->fUpper,usUser);
ObParInit(pM->ParArray,SZERO,"softzero",ZEROINACTIVE,usUser);
ObParInit(pM->ParArray,FIX,"fixed",-1,usUser);
ObParInit(pM->ParArray,INT,"interruptmode",INTCONT,usMugger);
ObParInit(pM->ParArray,PREC,"precision",0.01,usMugger);
ObParInit(pM->ParArray,USRIGHTS,"accesscode",(float)usUser,usMugger);
ObParInit(pM->ParArray,SIGN,"sign",1.0,usMugger);
ObParInit(pM->ParArray,ECOUNT,"failafter",3.0,usMugger);
ObParInit(pM->ParArray,POSCOUNT,"maxretry",3.0,usMugger);
ObParInit(pM->ParArray,IGNOREFAULT,"ignorefault",0.0,usMugger);
ObParInit(pM->ParArray,MOVECOUNT,"movecount",10.0,usMugger);
pDriv->GetPosition(pDriv,&(pM->fPosition));
pM->fTarget = pM->fPosition;
pM->endScriptID = 0;
/* copy arguments */
pM->pDriver = pDriv;
pM->drivername = strdup(drivername);
pM->name = strdup(name);
/* initialise object descriptor */
pM->pDescriptor = CreateDescriptor("Motor");
if(!pM->pDescriptor)
{
ObParDelete(pM->ParArray);
free(pM);
return NULL;
}
pM->pDescriptor->GetInterface = MotorGetInterface;
pM->pDescriptor->SaveStatus = MotorSaveStatus;
/* initialise Drivable interface */
pM->pDrivInt = CreateDrivableInterface();
if(!pM->pDrivInt)
{
DeleteDescriptor(pM->pDescriptor);
ObParDelete(pM->ParArray);
free(pM);
return NULL;
}
pM->pDrivInt->SetValue = MotorRunImpl;
pM->pDrivInt->CheckLimits = MotorLimits;
pM->pDrivInt->CheckStatus = MotorStatus;
pM->pDrivInt->GetValue = MotorGetValue;
pM->pDrivInt->Halt = MotorHalt;
/* initialize function pointers */
pM->MotorGetPar = MotorGetParImpl;
pM->MotorSetPar = MotorSetParImpl;
pM->MotorGetHardPosition = MotorGetHardPositionImpl;
/* initialise callback interface */
pM->pCall = CreateCallBackInterface();
if(!pM->pCall)
{
MotorKill(pM);
return NULL;
}
/* done */
return pM;
}
/*--------------------------------------------------------------------------*/
long MotorRun(void *data, SConnection *pCon, float fNew)
{
pMotor self = (pMotor)data;
return self->pDrivInt->SetValue(data,pCon,fNew);
}
/*--------------------------------------------------------------------------*/
int MotorCheckBoundary(pMotor self, float fVal, float *fHard,
char *error, int iErrLen)
{
return self->pDrivInt->CheckLimits(self,fVal,error,iErrLen);
}
/*--------------------------------------------------------------------------*/
int MotorGetSoftPosition(pMotor self,SConnection *pCon, float *fVal)
{
float myVal;
myVal = self->pDrivInt->GetValue(self,pCon);
*fVal = myVal;
if(myVal <= -9999999.99){
return 0;
} else {
return 1;
}
}
/*--------------------------------------------------------------------------*/
extern void KillPiPiezo(void *pData);
void MotorKill(void *self)
{
pMotor pM;
assert(self);
assert(pCon);
iRet = self->pDriver->GetPosition(self->pDriver,&fVal);
if(iRet == OKOK) /* all went well, the exception */
pM = (pMotor)self;
/* MotorHalt(pM); */
if(pM->name)
free(pM->name);
if(pM->pDrivInt)
{
*fHard = fVal;
return 1;
free(pM->pDrivInt);
}
else /* a problem, the usual case: try fix the problem */
{ /* no point in trying this three times */
self->pDriver->GetError(self->pDriver,&iCode, pError,255);
iRet = self->pDriver->TryAndFixIt(self->pDriver,iCode, fVal);
sprintf(pBueffel,"WARNING: Trying to fix %s",pError);
SCWrite(pCon,pBueffel,eWarning);
switch(iRet)
if(pM->pCall)
{
case MOTFAIL:
sprintf(pBueffel,"ERROR: cannot fix motor %s",
self->name);
SCWrite(pCon,pBueffel,eError);
SCSetInterrupt(pCon,(int)ObVal(self->ParArray,INT));
*fHard = fVal;
return 0;
case MOTOK:
case MOTREDO:
iRet = self->pDriver->GetPosition(self->pDriver,&fVal);
if(iRet)
DeleteCallBackInterface(pM->pCall);
}
/* kill driver */
if(pM->drivername)
{
*fHard = fVal*ObVal(self->ParArray,SIGN);
return 1;
}
else
if(pM->pDriver->KillPrivate != NULL)
{
sprintf(pBueffel,"ERROR: cannot fix motor %s",
self->name);
SCSetInterrupt(pCon,(int)ObVal(self->ParArray,INT));
SCWrite(pCon,pBueffel,eError);
*fHard = fVal;
return 0;
pM->pDriver->KillPrivate(pM->pDriver);
if(pM->pDriver->name != NULL)
{
free(pM->pDriver->name);
}
free(pM->pDriver);
}
free(pM->drivername);
}
*fHard = fVal*ObVal(self->ParArray,SIGN);
return 0;
/* get rid of parameter space */
if(pM->ParArray)
{
ObParDelete(pM->ParArray);
}
/* kill Descriptor */
DeleteDescriptor(pM->pDescriptor);
free(pM);
}
/*------------------------------------------------------------------------*/
float MotorHardToSoftPosition(pMotor self, float fValue)
@ -892,40 +973,6 @@ extern void KillPiPiezo(void *pData);
/* apply sign */
return fValue*ObVal(self->ParArray,SIGN);
}
/* ------------------------------------------------------------------------*/
int MotorGetSoftPosition(pMotor self, SConnection *pCon, float *fVal)
{
int iRet;
float fValue;
assert(self);
assert(pCon);
/* get the hard position */
iRet = MotorGetHardPosition(self,pCon,&fValue);
if(!iRet)
{
*fVal = fValue;
return 0;
}
/* apply zeropoint */
if(ObVal(self->ParArray,SIGN) < 0.)
{
fValue += ObVal(self->ParArray,SZERO);
}
else
{
fValue -= ObVal(self->ParArray,SZERO);
}
*fVal = fValue;
/* apply sign */
/* *fVal = MotorHardToSoftPosition(self,fValue); */
*fVal = fValue*ObVal(self->ParArray,SIGN);
return 1;
}
/*---------------------------------------------------------------------------*/
int MotorCheckPosition(void *sulf, SConnection *pCon)
{
@ -1079,9 +1126,9 @@ extern MotorDriver *MakePiPiezo(Tcl_Interp *pTcl, char *pArray);
sprintf(pBueffel,"Parameter Listing for motor %s",self->name);
SCWrite(pCon,pBueffel,eValue);
sprintf(pBueffel,"%s.Position = %f\n", self->name,self->fPosition);
SCWrite(pCon,pBueffel,eStatus);
SCWrite(pCon,pBueffel,eValue);
sprintf(pBueffel,"%s.TargetPosition = %f\n", self->name,self->fTarget);
SCWrite(pCon,pBueffel,eStatus);
SCWrite(pCon,pBueffel,eValue);
snprintf(pBueffel,511,"%s.hardlowerlim = %f",self->name,
self->pDriver->fLower);
@ -1093,7 +1140,7 @@ extern MotorDriver *MakePiPiezo(Tcl_Interp *pTcl, char *pArray);
{
sprintf(pBueffel,"%s.%s = %f\n",self->name,
self->ParArray[i].name,self->ParArray[i].fVal);
SCWrite(pCon,pBueffel,eStatus);
SCWrite(pCon,pBueffel,eValue);
}
/*
@ -1129,11 +1176,14 @@ extern MotorDriver *MakePiPiezo(Tcl_Interp *pTcl, char *pArray);
{
free(self->pName);
}
if(self->pCon != NULL)
{
SCDeleteConnection(self->pCon);
}
free(self);
}
/*------------------- The CallBack function for interest ------------------*/
static int InterestCallback(int iEvent, void *pEvent, void *pUser,
commandContext cc)
static int InterestCallback(int iEvent, void *pEvent, void *pUser)
{
pMotInfo pInfo = NULL;
char pBueffel[80];
@ -1145,11 +1195,15 @@ extern MotorDriver *MakePiPiezo(Tcl_Interp *pTcl, char *pArray);
psCall = (MotCallback *)pEvent;
pInfo = (MotInfo *)pUser;
if(!SCisConnected(pInfo->pCon)){
return -1;
}
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);
SCWrite(pInfo->pCon,pBueffel,eEvent);
}
return 1;
}
@ -1162,8 +1216,7 @@ extern MotorDriver *MakePiPiezo(Tcl_Interp *pTcl, char *pArray);
}
}
/*------------------------ The endscript callback function ----------------*/
static int EndScriptCallback(int iEvent, void *pEvent, void *pUser,
commandContext cc)
static int EndScriptCallback(int iEvent, void *pEvent, void *pUser)
{
char *pScript = NULL;
MotCallback *psCall;
@ -1269,7 +1322,7 @@ extern MotorDriver *MakePiPiezo(Tcl_Interp *pTcl, char *pArray);
return 0;
}
pMoti->pName = strdup(argv[0]);
pMoti->pCon = pCon;
pMoti->pCon = SCCopyConnection(pCon);
iRet = MotorGetSoftPosition(self,pCon,&fValue);
if(!iRet)
{
@ -1280,16 +1333,15 @@ extern MotorDriver *MakePiPiezo(Tcl_Interp *pTcl, char *pArray);
}
pMoti->lastValue = fValue;
lID = RegisterCallback(self->pCall, SCGetContext(pCon),MOTDRIVE, InterestCallback,
lID = RegisterCallback(self->pCall, MOTDRIVE, InterestCallback,
pMoti, KillInfo);
SCRegister(pCon,pSics, self->pCall,lID);
DeleteTokenList(pList);
SCSendOK(pCon);
return 1;
}
else if(strcmp(pCurrent->text,"uninterest") == 0)
{
RemoveCallback2(self->pCall,pCon);
RemoveCallbackCon(self->pCall,pCon);
SCSendOK(pCon);
DeleteTokenList(pList);
return 1;
@ -1312,9 +1364,8 @@ extern MotorDriver *MakePiPiezo(Tcl_Interp *pTcl, char *pArray);
return 0;
}
self->endScriptID =
RegisterCallback(self->pCall, SCGetContext(pCon),MOTEND, EndScriptCallback,
RegisterCallback(self->pCall, MOTEND, EndScriptCallback,
strdup(pCurrent->text), KillScript);
SCRegister(pCon,pSics, self->pCall,self->endScriptID);
DeleteTokenList(pList);
SCSendOK(pCon);
return 1;

12
motor.h
View File

@ -13,13 +13,17 @@
#include "modriv.h"
#include "obdes.h"
#include "interface.h"
#include "hipadaba.h"
#define MOTOBPARLENGTH 12
typedef struct __Motor {
pObjectDescriptor pDescriptor;
ObPar *ParArray;
pHdb objectNode;
pIDrivable pDrivInt;
pICallBack pCall;
int (*MotorSetPar)(struct __Motor *self, SConnection *pCon, char *name, float fVal);
int (*MotorGetPar)(struct __Motor *self, char *name, float *fVal);
int (*MotorGetHardPosition)(struct __Motor *self, SConnection *pCon, float *fVal);
char *drivername;
char *name;
MotorDriver *pDriver;
@ -31,6 +35,10 @@
int retryCount; /* for retries in status */
int posFaultCount;
int stopped;
int errorCount;
ObPar *ParArray;
void *pPrivate;
void (*KillPrivate)(void *);
} Motor;
typedef Motor *pMotor;
/*------------------------------------------------------------------------
@ -50,12 +58,10 @@ typedef struct {
long MotorRun(void *self, SConnection *pCon, float fNew);
int MotorCheckBoundary(pMotor self, float fVal, float *fHard,
char *error, int iErrLen);
int MotorCheckPosition(void *self, SConnection *pCon);
/* Where are we ? */
int MotorGetSoftPosition(pMotor self,SConnection *pCon, float *fVal);
int MotorGetHardPosition(pMotor self,SConnection *pCon, float *fVal);
float MotorHardToSoftPosition(pMotor self, float fHard);
/* creation */
int MotorCreate(SConnection *pCon, SicsInterp *pSics, void *pData,

749
motorsec.c Normal file
View File

@ -0,0 +1,749 @@
/**
* This is the implementation of a second generation motor. A second
* generation motor differs in various aspects from a first generation
* motor though it is functionally equivalent and even adheres to the
* same interface. The differing aspects are:
* - The second generation motor deos not use the ObPar array for parameter storage
* but the Hipadaba parameter system rooted in self->pDes->objectNode.
* - The second generation motor does not use the driver. The second generation motor
* implements some functionality but is largely a shell. Scripts are supposed to add
* more parameters and link to a corresponding ScriptContext object which takes care
* of actual talking to the hardware.
* - The old callback system is also not implemented: third parties which are interested
* to be notified of changes to the motor position shall register a callback.
*
* This also means that many of the fields in the motor data structure are not used in
* this module but are present to support first generation motors. This must be so as we cannot
* replace all existing driver with new ones quickly. Here a list of fields which have no use:
* - pDriver
* - ParArray
*
* We need three different position parameters to keep this under control:
* - the physical value which is the main motor node
* - the targetposition which is is the hardware target where the motor is supposed
* to be
* - The hardposition which is the actual hardware position. This is also the
* one which is responsible for talking to the motor.
*
* Then we need a status parameter which is some text which says what the motor
* is up to.
*
* A less obvious use of a callback is the HardUpdateCallback. It automatically
* updates the physical motor position, too.
*
* copyright: see file COPYRIGHT
*
* Mark Koennecke, December 2008
*/
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <math.h>
#include "sics.h"
#include "sicshipadaba.h"
#include "sicsobj.h"
#include "motor.h"
#include "splitter.h"
#define ABS(x) (x < 0 ? -(x) : (x))
/*--------------------------------------------------------------------------*/
static int SecMotorGetPar(pMotor self, char *name, float *fVal){
char pBueffel[512];
hdbValue value;;
int status;
snprintf(pBueffel,511,"%s ", name);
status = SICSHdbGetPar(self,NULL,pBueffel, &value);
*fVal = (float)value.v.doubleValue;
return status;
}
/*---------------------------------------------------------------------------*/
static int SecMotorSetPar(pMotor self, SConnection *pCon, char *name, float fVal){
int status;
hdbValue value;
value = MakeHdbFloat(fVal);
status = SICSHdbSetPar(self,
pCon,name,value);
if(status == 1){
SCparChange(pCon);
return 1;
} else {
return 0;
}
}
/*-------------------------------------------------------------------------*/
static void *MotorGetInterfaceSec(void *pData, int iID){
pMotor self = NULL;
self = (pMotor)pData;
assert(self);
if(iID == DRIVEID){
return self->pDrivInt;
} else if(iID == CALLBACKINTERFACE) {
return self->pCall;
}
return NULL;
}
/*---------------------------------------------------------------------------*/
static long SecMotorRun(void *sulf, SConnection *pCon, float fNew){
pMotor self = (pMotor)sulf;
hdbValue v;
v = MakeHdbFloat(fNew);
return SetHipadabaPar(self->pDescriptor->parNode,v,pCon);
}
/*--------------------------------------------------------------------------*/
static int SecMotorCheckBoundary(pMotor self, float fVal, float *fTarget,
char *pError, int iErrLen){
double fZero, fixed, lowerlim, upperlim, sign;
float fHard, hupper, hlower;
char pBueffel[512];
hdbValue v;
assert(self);
assert(SICSHdbGetPar(self,NULL,
"fixed",&v) == 1);
fixed = v.v.doubleValue;
assert(SICSHdbGetPar(self,NULL,
"softzero",&v) == 1);
fZero = v.v.doubleValue;
assert(SICSHdbGetPar(self,NULL,
"softlowerlim",&v) == 1);
lowerlim = v.v.doubleValue;
assert(SICSHdbGetPar(self,NULL,
"softupperlim",&v) == 1);
upperlim = v.v.doubleValue;
assert(SICSHdbGetPar(self,NULL,
"sign",&v) == 1);
sign = v.v.doubleValue;
*fTarget = fVal;
/* check for fixed */
if(fixed >= 0){
sprintf(pBueffel,"Motor %s is Fixed",self->name);
strncpy(pError,pBueffel,iErrLen);
return 0; /* is this an error? */
}
/* check against software boundaries */
if(fVal > upperlim){
sprintf(pBueffel,"%f violates upper software limit %f on %s",
fVal, upperlim,self->name);
strncpy(pError,pBueffel,iErrLen);
return 0;
}
if(fVal < lowerlim){
sprintf(pBueffel,"%f violates lower software limit %f on %s",
fVal,lowerlim,self->name );
strncpy(pError,pBueffel,iErrLen);
return 0;
}
/* correct for zero point */
fZero = -fZero;
fHard = fVal - fZero;
/* apply sign */
fHard = fHard*sign;
/* check for hardware limits */
SecMotorGetPar(self,"hardlowerlim",&hlower);
SecMotorGetPar(self,"hardupperlim",&hupper);
if(fHard > hupper){
sprintf(pBueffel,"%f violates upper hardware limit %f on %s",
fVal,hupper,self->name);
strncpy(pError,pBueffel,iErrLen);
return 0;
}
if(fHard < hlower){
sprintf(pBueffel,"%f violates lower hardware limit %f on %s",
fVal,hlower,self->name);
strncpy(pError,pBueffel,iErrLen);
return 0;
}
*fTarget = fHard;
return 1;
}
/*--------------------------------------------------------------------------*/
static int SecMotorLimits(void *sulf, float fVal, char *error, int iErrLen){
float fHard;
pMotor self;
assert(sulf);
self = (pMotor)sulf;
return SecMotorCheckBoundary(self,fVal,&fHard,error,iErrLen);
}
/*-----------------------------------------------------------------------*/
static int checkPosition(pMotor self, SConnection *pCon){
float precision, hard, target, maxretry;
pHdb node = NULL;
if(SCGetInterrupt(pCon) != eContinue){
return HWFault;
}
if(self->stopped){
SCPrintf(pCon,eWarning,"WARNING: %s stopped", self->name);
return HWFault;
}
SecMotorGetPar(self,"hardposition",&hard);
SecMotorGetPar(self,"targetposition",&target);
SecMotorGetPar(self,"precision",&precision);
SecMotorGetPar(self,"maxretry",&maxretry);
if(ABS(target-hard) > precision){
if(self->retryCount >= (int)maxretry){
SCPrintf(pCon,eError,
"ERROR: Aborting %s after %d retries, off position by %f",
self->name, (int)maxretry, target - hard);
return HWFault;
}
self->retryCount++;
SCPrintf(pCon,eWarning,"WARNING: %s off position by %f, restarting",
self->name, target-hard);
node = GetHipadabaNode(self->pDescriptor->parNode,"status");
assert(node != NULL);
UpdateHipadabaPar(node,MakeHdbText("run"), pCon);
node = GetHipadabaNode(self->pDescriptor->parNode,"hardposition");
assert(node != NULL);
SetHipadabaPar(node,MakeHdbFloat(target), pCon);
return HWBusy;
}
return HWIdle;
}
/*-----------------------------------------------------------------------*/
static void handleMoveCallback(pMotor self, SConnection *pCon){
float movecount;
pHdb node = NULL;
hdbValue v;
SecMotorGetPar(self,"movecount",&movecount);
self->posCount++;
if(self->posCount > (int)movecount){
node = GetHipadabaNode(self->pDescriptor->parNode,"hardposition");
GetHipadabaPar(node,&v,pCon);
UpdateHipadabaPar(node,v,pCon);
self->posCount = 0;
}
}
/*-----------------------------------------------------------------------*/
static int SecMotorStatus(void *sulf, SConnection *pCon){
pMotor self = NULL;
int status;
pHdb node = NULL;
hdbValue v;
float interrupt;
assert(sulf);
self = (pMotor)sulf;
node = GetHipadabaNode(self->pDescriptor->parNode,"status");
assert(node != NULL);
status = GetHipadabaPar(node,&v,pCon);
if(status != 1){
return HWFault;
}
if(v.v.text == NULL){
return HWBusy;
}
if(strstr(v.v.text,"idle") != NULL){
status = checkPosition(self,pCon);
} else if(strstr(v.v.text,"run") != NULL){
handleMoveCallback(self,pCon);
status = HWBusy;
} else if(strstr(v.v.text,"poserror") != NULL){
status = checkPosition(self,pCon);
} else if(strstr(v.v.text,"error") != NULL){
status = HWFault;
} else {
SCPrintf(pCon,eError,"ERROR: unknown motor status %s found", v.v.text);
status = HWFault;
}
/*
* when terminating: force an update of the position.
*/
switch(status){
case HWFault:
self->posCount = 10000;
handleMoveCallback(self,pCon);
SecMotorGetPar(self,"interrupt",&interrupt);
if(SCGetInterrupt(pCon) < (int)interrupt){
SCSetInterrupt(pCon,(int)interrupt);
}
self->errorCount++;
break;
case HWIdle:
self->posCount = 10000;
handleMoveCallback(self,pCon);
self->errorCount = 0;
break;
}
return status;
}
/*---------------------------------------------------------------------------*/
static float SecMotorGetValue(void *pData, SConnection *pCon){
int status;
pMotor self = (pMotor)pData;
hdbValue v;
assert(pData);
status = GetHipadabaPar(self->pDescriptor->parNode, &v,pCon);
if(status != 1){
return -9999999.99;
} else {
return (float)v.v.doubleValue;
}
}
/*------------------------------------------------------------------------*/
static int SecMotorHalt(void *sulf){
pMotor self;
pHdb node = NULL, par[0];
SICSOBJFunc haltFunc = NULL;
int status;
assert(sulf);
self = (pMotor)sulf;
node = GetHipadabaNode(self->pDescriptor->parNode,"halt");
assert(node != NULL);
haltFunc = (SICSOBJFunc)node->value.v.func;
assert(haltFunc != NULL);
self->stopped = 1;
return haltFunc((pSICSOBJ)self,pServ->dummyCon,node,par,0);
}
/*--------------------------------------------------------------------------*/
static int SecMotorGetHardPosition(struct __Motor *self,
SConnection *pCon, float *fVal){
hdbValue v;
int status;
pHdb node = NULL;
node = GetHipadabaNode(self->pDescriptor->parNode,"hardposition");
assert(node != NULL);
status = GetHipadabaPar(node,&v,pCon);
*fVal = (float)v.v.doubleValue;
return status;
}
/*---------------------------------------------------------------------------*/
static void AddMotorPar(pHdb node, int priv, char *name){
pHdb child = NULL;
child = MakeSICSHdbPar(name,priv,MakeHdbFloat(.0));
if(child != NULL){
SetHdbProperty(child,"__save", "true");
AddHipadabaChild(node,child,NULL);
}
}
/*---------------------------------------------------------------------------*/
static float hardToSoftPosition(pMotor self, float hard){
float sign, zero, fVal;
SecMotorGetPar(self,"sign", &sign);
SecMotorGetPar(self,"softzero", &zero);
fVal = hard;
if(sign < 0){
fVal += zero;
} else {
fVal -= zero;
}
fVal *= sign;
return fVal;
}
/*---------------------------------------------------------------------------*/
static hdbCallbackReturn SecMotorCallback(pHdb node, void *userData,
pHdbMessage message){
SConnection *pCon = NULL;
pHdbDataMessage mm = NULL;
hdbValue v;
pHdb child = NULL;
pMotor self = NULL;
float fHard, fVal, sign, zero;
char pBueffel[512], pError[132];
int status;
self = (pMotor)userData;
assert(self != NULL);
mm = GetHdbSetMessage(message);
if(mm != NULL){
pCon = (SConnection *)mm->callData;
v = *(mm->v);
/*
* check permission
*/
SecMotorGetPar(self,"accesscode",&fVal);
if(!SCMatchRights(pCon,(int)fVal)){
sprintf(pBueffel,"ERROR: You are not authorised to move motor %s",
self->name);
SCWrite(pCon,pBueffel,eError);
SCSetInterrupt(pCon,eAbortBatch);
return hdbAbort;
}
/*
* check limits
*/
status = SecMotorCheckBoundary(self,(float)v.v.doubleValue,
&fHard,pError,131);
if(status != 1){
snprintf(pBueffel,511,"ERROR: %s",pError);
SCWrite(pCon,pBueffel,eWarning);
SCSetInterrupt(pCon,eAbortOperation);
return hdbAbort;
}
/*
* check the motor bad flag
*/
SecMotorGetPar(self,"ignorefault",&fVal);
if((int)fVal > 0){
snprintf(pBueffel,511,"WARNING: motor %s is unreliable",
self->name);
SCWrite(pCon,pBueffel,eWarning);
self->errorCount = 0;
}
/*
* check for alarm condition
*/
SecMotorGetPar(self,"failafter",&fVal);
if(self->errorCount > (int)fVal){
/* big alarm */
ServerWriteGlobal("ERROR: !!! MOTOR ALARM !!! MOTOR ALARM !!!",eError);
sprintf(pBueffel,
"ERROR: too many position errors counted at motor %s",
self->name);
ServerWriteGlobal(pBueffel,eError);
SCSetInterrupt(pCon,eAbortBatch);
self->errorCount = 0;
return hdbAbort;
}
self->posFaultCount = 0;
self->retryCount = 0;
self->stopped = 0;
self->posCount = 0;
child = GetHipadabaNode(self->pDescriptor->parNode,"targetposition");
UpdateHipadabaPar(child,MakeHdbFloat(fHard),pCon);
child = GetHipadabaNode(self->pDescriptor->parNode,"status");
UpdateHipadabaPar(child,MakeHdbText("run"), pCon);
child = GetHipadabaNode(self->pDescriptor->parNode,"hardposition");
SetHipadabaPar(child,MakeHdbFloat(fHard), pCon);
return hdbContinue;
}
mm = GetHdbGetMessage(message);
if(mm != NULL){
pCon = (SConnection *)mm->callData;
SecMotorGetPar(self,"hardposition", &fVal);
fVal = hardToSoftPosition(self,fVal);
node->value.v.doubleValue = fVal;
mm->v->v.doubleValue = fVal;
return hdbContinue;
}
return hdbContinue;
}
/*--------------------------------------------------------------------------*/
static hdbCallbackReturn HardUpdateCallback(pHdb node, void *userData,
pHdbMessage message){
pHdbDataMessage mm = NULL;
pMotor self = (pMotor)userData;
float fVal;
hdbValue v;
assert(self != NULL);
mm = GetHdbUpdateMessage(message);
if(mm != NULL){
v = *mm->v;
fVal = hardToSoftPosition(self,(float)v.v.doubleValue);
v.v.doubleValue = fVal;
UpdateHipadabaPar(self->pDescriptor->parNode, v, mm->callData);
return hdbContinue;
}
return hdbContinue;
}
/*--------------------------------------------------------------------------*/
static hdbCallbackReturn SecMotorSignCallback(pHdb node, void *userData,
pHdbMessage message){
pMotor self = NULL;
SConnection *pCon = NULL;
pHdb zero = NULL;
double value;
pHdbDataMessage mm = NULL;
float limit;
hdbValue v;
self = (pMotor)userData;
mm = GetHdbSetMessage(message);
if(mm != NULL){
pCon = (SConnection *)mm->callData;
if(!SCMatchRights(pCon,usMugger)){
return hdbAbort;
}
v = *mm->v;
if(ABS(v.v.doubleValue) - 1. > .01){
if(pCon!= NULL){
SCWrite(pCon,"ERROR: invalid sign value",eError);
return hdbAbort;
}
}
SecMotorGetPar(self,"softlowerlim",&limit);
limit *= v.v.doubleValue;
SecMotorSetPar(self,pCon,"softlowerlim",limit);
SecMotorGetPar(self,"softupperlim",&limit);
limit *= v.v.doubleValue;
SecMotorSetPar(self,pCon,"softupperlim",limit);
SecMotorSetPar(self,pCon,"softzero",.0);
UpdateHipadabaPar(node,v,pCon);
return hdbContinue;
}
return hdbContinue;
}
/*---------------------------------------------------------------------------*/
static hdbCallbackReturn SecMotorZeroCallback(pHdb node, void *userData,
pHdbMessage message){
pMotor self = NULL;
float limit, oldZero, diff;
SConnection *pCon = NULL;
pHdbDataMessage mm = NULL;
hdbValue v;
self = (pMotor)userData;
assert(self != NULL);
mm = GetHdbSetMessage(message);
if(mm != NULL){
pCon = (SConnection *)mm->callData;
if(!SCMatchRights(pCon,usUser)){
return hdbAbort;
}
v = *mm->v;
SecMotorGetPar(self,"softzero", &oldZero);
diff = v.v.doubleValue - oldZero;
SecMotorGetPar(self,"softupperlim",&limit);
limit -= diff;
SecMotorSetPar(self,pCon,"softupperlim",limit);
SecMotorGetPar(self,"softlowerlim",&limit);
limit -= diff;
SecMotorSetPar(self,pCon,"softlowerlim",limit);
UpdateHipadabaPar(node,v,pCon);
return hdbContinue;
}
return hdbContinue;
}
/*---------------------------------------------------------------------------*/
pMotor SecMotorInit(char *name){
pMotor pM = NULL;
pHdb node = NULL, child = NULL;
hdbValue v;
assert(name);
/* get memory */
pM = (pMotor)malloc(sizeof(Motor));
if(!pM){
return NULL;
}
memset(pM,0,sizeof(Motor));
/* initialise object descriptor */
pM->pDescriptor = CreateDescriptor("Motor");
if(!pM->pDescriptor){
free(pM);
return NULL;
}
pM->pDescriptor->GetInterface = MotorGetInterfaceSec;
pM->pDescriptor->SaveStatus = SaveSICSOBJ;
pM->pDescriptor->parNode = MakeSICSHdbPar(name,usSpy,MakeHdbFloat(.0));
if(pM->pDescriptor->parNode == NULL){
free(pM);
return NULL;
}
node = pM->pDescriptor->parNode;
pM->objectNode = node;
AppendHipadabaCallback(pM->pDescriptor->parNode,
MakeHipadabaCallback(SecMotorCallback,pM,NULL));
/* copy arguments */
pM->name = strdup(name);
/*
* install parameters
*/
child = MakeSICSHdbPar("targetposition",usInternal,MakeHdbFloat(.0));
if(child == NULL){
return(NULL);
}
SetHdbProperty(child,"__save", "true");
AddHipadabaChild(node,child,NULL);
child = MakeHipadabaNode("hardposition",HIPFLOAT,1);
if(child == NULL){
return(NULL);
}
AddHipadabaChild(node,child,NULL);
SetHdbProperty(child,"motname", name);
AppendHipadabaCallback(child,
MakeHipadabaCallback(HardUpdateCallback,pM,NULL));
child = MakeHipadabaNode("sign",HIPFLOAT, 1);
SetHdbProperty(child,"__save", "true");
AddHipadabaChild(node,child,NULL);
AppendHipadabaCallback(child,
MakeHipadabaCallback(SecMotorSignCallback,pM,NULL));
UpdateHipadabaPar(child,MakeHdbFloat(1.),NULL);
child = MakeHipadabaNode("softzero",HIPFLOAT, 1);
SetHdbProperty(child,"__save", "true");
AddHipadabaChild(node,child,NULL);
AppendHipadabaCallback(child,
MakeHipadabaCallback(SecMotorZeroCallback,pM,NULL));
child = MakeHipadabaNode("hardlowerlim",HIPFLOAT, 1);
AddHipadabaChild(node,child,NULL);
child = MakeHipadabaNode("hardupperlim",HIPFLOAT, 1);
AddHipadabaChild(node,child,NULL);
child = MakeSICSHdbPar("softlowerlim",usUser,
MakeHdbFloat(.0));
SetHdbProperty(child,"__save", "true");
AddHipadabaChild(node,child,NULL);
child = MakeSICSHdbPar("softupperlim",usUser,
MakeHdbFloat(.0));
SetHdbProperty(child,"__save", "true");
AddHipadabaChild(node,child,NULL);
child = MakeSICSHdbPar("fixed",usUser,
MakeHdbFloat(-1.));
SetHdbProperty(child,"__save", "true");
AddHipadabaChild(node,child,NULL);
child = MakeSICSHdbPar("interruptmode",usMugger,
MakeHdbFloat(.0));
SetHdbProperty(child,"__save", "true");
AddHipadabaChild(node,child,NULL);
child = MakeSICSHdbPar("precision",usMugger,
MakeHdbFloat(.1));
SetHdbProperty(child,"__save", "true");
AddHipadabaChild(node,child,NULL);
child = MakeSICSHdbPar("accesscode",usMugger,
MakeHdbFloat((double)usUser));
SetHdbProperty(child,"__save", "true");
AddHipadabaChild(node,child,NULL);
child = MakeSICSHdbPar("failafter",usMugger,
MakeHdbFloat((double)3.0));
SetHdbProperty(child,"__save", "true");
AddHipadabaChild(node,child,NULL);
child = MakeSICSHdbPar("maxretry",usMugger,
MakeHdbFloat((double)3.0));
SetHdbProperty(child,"__save", "true");
AddHipadabaChild(node,child,NULL);
child = MakeSICSHdbPar("ignorefault",usMugger,
MakeHdbFloat((double).0));
SetHdbProperty(child,"__save", "true");
AddHipadabaChild(node,child,NULL);
child = MakeSICSHdbPar("movecount",usMugger,
MakeHdbFloat((double)10.0));
SetHdbProperty(child,"__save", "true");
AddHipadabaChild(node,child,NULL);
child = MakeHipadabaNode("status",HIPTEXT,1);
SetHdbProperty(child,"motname", name);
AddHipadabaChild(node,child,NULL);
pM->endScriptID = 0;
/* initialise Drivable interface */
pM->pDrivInt = CreateDrivableInterface();
if(!pM->pDrivInt){
DeleteDescriptor(pM->pDescriptor);
free(pM);
return NULL;
}
pM->pDrivInt->SetValue = SecMotorRun;
pM->pDrivInt->CheckLimits = SecMotorLimits;
pM->pDrivInt->CheckStatus = SecMotorStatus;
pM->pDrivInt->GetValue = SecMotorGetValue;
pM->pDrivInt->Halt = SecMotorHalt;
/*
* initialize motor function pointers
*/
pM->MotorGetPar = SecMotorGetPar;
pM->MotorSetPar = SecMotorSetPar;
pM->MotorGetHardPosition = SecMotorGetHardPosition;
/* initialise callback interface */
pM->pCall = CreateCallBackInterface();
if(!pM->pCall){
MotorKill(pM);
return NULL;
}
/* done */
return pM;
}
/*--------------------------------------------------------------------------*/
static void SecMotorKill(void *data){
pMotor self = (pMotor)data;
if(self == NULL){
return;
}
if(self->name)
free(self->name);
if(self->pDrivInt){
free(self->pDrivInt);
}
if(self->pCall){
DeleteCallBackInterface(self->pCall);
}
/* kill Descriptor */
DeleteDescriptor(self->pDescriptor);
free(self);
}
/*--------------------------------------------------------------------------*/
int SecMotorFactory(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]){
pMotor pNew = NULL;
if(argc < 2){
SCWrite(pCon,"ERROR: need name for new motor", eError);
return 0;
}
pNew = SecMotorInit(argv[1]);
if(pNew == NULL){
SCWrite(pCon,"ERROR: out of memory creating motor", eError);
return 0;
}
return AddCommand(pSics,argv[1],InterInvokeSICSOBJ,
SecMotorKill,pNew);
}

14
motorsec.h Normal file
View File

@ -0,0 +1,14 @@
/**
* This is the header file for the second generation motor object.
* More details in the header of the implementation file.
*
* copyright: see file COPYRIGHT
*
* Mark Koennecke, December 2008
*/
#ifndef MOTORSEC_H_
#define MOTORSEC_H_
int SecMotorFactory(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]);
#endif /*MOTORSEC_H_*/

View File

@ -59,9 +59,11 @@ static int MMCCHalt(void *pData){
for(i = 0; i < self->nSlaves; i++){
status = self->slaves[i]->Halt(self->slaveData[i]);
ReleaseCountLock(self->slaves[i]);
if(status != OKOK)
retVal = status;
}
ReleaseCountLock(pCount->pCountInt);
return retVal;
}
/*-------------------------------------------------------------------------*/
@ -77,9 +79,14 @@ static int MMCCStart(void *pData, SConnection *pCon)
}
assert(self);
if(!GetCountLock(pCount->pCountInt, pCon)){
return HWFault;
}
for(i = 0; i < self->nSlaves; i++){
self->slaves[i]->SetCountParameters(self->slaveData[i],
pCount->pDriv->fPreset, pCount->pDriv->eMode);
ReleaseCountLock(self->slaves[i]);
status = self->slaves[i]->StartCount(self->slaveData[i],pCon);
if(status != OKOK){
MMCCHalt(pData);

21
nintf.c
View File

@ -3,6 +3,8 @@
is an implementation.
Mark Koennecke, February 2000
Added double version, Mark Koennecke, August 2008
---------------------------------------------------------------------------*/
#include <math.h>
@ -24,3 +26,22 @@
}
return (float) ip;
}
/*-------------------------------------------------------------------*/
double nintd(double f)
{
double ip, rm, dVal;
double fRes;
dVal = (double)f;
rm = modf(dVal,&ip);
if(rm < .0)rm = -rm;
if(rm > .5)
{
if(ip < .0)
ip -= 1.;
else
ip += 1.;
}
return (double) ip;
}

390
nread.c
View File

@ -10,7 +10,7 @@
Telnet Functionality added: Mark Koennecke, January 1998
Revamped login to non telnet connection.
Mark Koennecke, October 20000
Mark Koennecke, October 2000
-----------------------------------------------------------------------------*/
#include <stdlib.h>
@ -67,6 +67,7 @@ extern int VerifyChannel(mkChannel *self); /* defined in network.c */
int iReadTimeout;
int iEnd;
long lMagic;
pDynString conList;
} NetReader;
/*---------------------------------------------------------------------------
The structure used for an item in the Net Reader list of connections
@ -97,7 +98,8 @@ extern int VerifyChannel(mkChannel *self); /* defined in network.c */
memset(pNew,0,sizeof(NetReader));
pNew->iList = LLDcreate(sizeof(NetItem));
if(pNew->iList < 0)
pNew->conList = CreateDynString(1024,1024);
if(pNew->iList < 0 || pNew->conList == NULL)
{
free(pNew);
return NULL;
@ -121,6 +123,10 @@ extern int VerifyChannel(mkChannel *self); /* defined in network.c */
}
LLDdelete(self->iList);
if(self->conList != NULL)
{
DeleteDynString(self->conList);
}
free(self);
}
/*--------------------------------------------------------------------------*/
@ -208,7 +214,9 @@ extern int VerifyChannel(mkChannel *self); /* defined in network.c */
if(pNew)
{
/* create connection object */
/* TODO
pRes = SCreateConnection(self->pMain->pSics,pNew,3);
*/
if(!pRes)
{
SICSLogWrite("Failure to allocate new Connection",eInternal);
@ -370,7 +378,9 @@ extern int VerifyChannel(mkChannel *self); /* defined in network.c */
if(pNew)
{
/* create connection object */
/* TODO
pRes = SCreateConnection(self->pMain->pSics,pNew,usSpy);
*/
if(!pRes)
{
SICSLogWrite("Failure to allocate new Connection",eInternal);
@ -706,9 +716,6 @@ extern int VerifyChannel(mkChannel *self); /* defined in network.c */
int conCount = 0;
char num[50];
IPair *options = NULL;
char buffer[1024];
int bufferLen;
static int bufferFull=0;
self = (pNetRead)pData;
assert(self);
@ -723,12 +730,13 @@ extern int VerifyChannel(mkChannel *self); /* defined in network.c */
return 0;
}
ANETprocess();
/* build the select mask */
FD_ZERO(&lMask);
iRet = LLDnodePtr2First(self->iList);
iCount = 0;
buffer[0] = '\0';
bufferLen = 0;
DynStringClear(self->conList);
while(iRet != 0)
{
LLDnodeDataTo(self->iList,&NItem);
@ -736,14 +744,10 @@ extern int VerifyChannel(mkChannel *self); /* defined in network.c */
{
break;
}
snprintf(num,sizeof num, "%d, type %d:", NItem.pSock->sockid, NItem.eType);
if (bufferLen + strlen(num) < sizeof buffer) {
strcpy(buffer + bufferLen, num);
bufferLen += strlen(num);
} else {
if (bufferFull == 0) {
bufferFull = 1;
}
sprintf(num,"%d, type %d:", NItem.pSock->sockid, NItem.eType);
if(conCount < 100){
DynStringConcat(self->conList,num);
}
FD_SET(NItem.pSock->sockid,&lMask);
if(NItem.pSock->sockid > iCount)
@ -751,17 +755,20 @@ extern int VerifyChannel(mkChannel *self); /* defined in network.c */
iCount = NItem.pSock->sockid;
}
conCount++;
if(conCount > 100){
WriteToCommandLog("WAYTOMANYCONNECTIONS> ", GetCharArray(self->conList));
}
iRet = LLDnodePtr2Next(self->iList);
}
if(conCount > 100){
WriteToCommandLog("WAYTOMANYCONNECTIONS> ", GetCharArray(self->conList));
}
snprintf(num,sizeof num,"%d", conCount);
IFSetOption(pSICSOptions,"ConnectionCount",num);
IFSetOption(pSICSOptions,"ConMask",buffer);
IFSetOption(pSICSOptions,"ConMask",GetCharArray(self->conList));
if (bufferFull == 1) {
bufferFull = 2;
WriteToCommandLog("BUFFERFULL>",buffer);
}
/* the select itself */
tmo.tv_usec = self->iReadTimeout;
@ -1072,5 +1079,348 @@ extern int VerifyChannel(mkChannel *self); /* defined in network.c */
}
return 0;
}
/*===================================================================================
* new code to support the ANET network stuff
* =================================================================================*/
typedef struct {
pDynString command;
int state;
SConnection *pCon;
}CommandCBData, *pCommandCBData;
/*----------------------------------------------------------------------------------*/
static void killCommandCBData(void *data){
pCommandCBData self = (pCommandCBData)data;
if(self == NULL){
return;
}
if(self->command != NULL){
DeleteDynString(self->command);
}
free(self);
}
/*----------------------------------------------------------------------------------*/
static int testAndInvokeInterrupt(pCommandCBData self, int handle){
char *pPtr;
char buffer[512];
int iInt;
pPtr = GetCharArray(self->command);
if(strstr(pPtr,"INT1712") != NULL){
sscanf(pPtr, "%s %d",buffer, &iInt);
if(SCMatchRights(self->pCon,usUser)) {
TaskSignal(pServ->pTasker, SICSINT, &iInt);
snprintf(buffer,512, "INTERRUPT %d issued on sock %d",
iInt,handle);
WriteToCommandLog("SYS>", buffer);
if(iInt == eEndServer){
TaskStop(pServ->pTasker);
}
} else {
SCWrite(self->pCon,
"ERROR: insufficient privilege to invoke Interrupt",
eError);
}
return 1;
}
return 0;
}
/*----------------------------------------------------------------------------------*/
static int CommandDataCB(int handle, void *userData){
pCommandCBData self = (pCommandCBData)userData;
int i, length, status;
char *pPtr = NULL;
assert(self != NULL);
pPtr = ANETreadPtr(handle,&length);
if(pPtr == NULL){
return 1;
}
for(i = 0; i < length; i++){
switch(self->state){
case COLLECT:
if(pPtr[i] == '\r' || pPtr[i] == '\n'){
self->state = SKIPTERM;
if(!testAndInvokeInterrupt(self,handle)){
status = CostaTop(self->pCon->pStack, GetCharArray(self->command));
if(!status){
SCWrite(self->pCon,"ERROR: Busy", eError);
}
}
DynStringClear(self->command);
} else {
if(pPtr[i] != '\0'){
DynStringConcatChar(self->command, pPtr[i]);
}
}
break;
case SKIPTERM:
if(pPtr[i] != '\r' && pPtr[i] != '\n' && pPtr[i] != '\0'){
DynStringConcatChar(self->command, pPtr[i]);
self->state = COLLECT;
}
break;
}
}
ANETreadConsume(handle, length);
return 1;
}
/*----------------------------------------------------------------------------------*/
static int CommandAcceptCB(int handle, void *userData){
SConnection *pCon = NULL;
pCommandCBData usData = NULL;
pCon = SCreateConnection(pServ->pSics, handle, 3);
usData = malloc(sizeof(CommandCBData));
if(pCon == NULL || usData == NULL){
SICSLogWrite("Failure to allocate new Connection",eInternal);
return 0;
}
usData->command = CreateDynString(256,256);
if(usData->command == NULL){
SICSLogWrite("Failure to allocate new Connection",eInternal);
return 0;
}
usData->pCon = pCon;
usData->state = COLLECT;
TaskRegister(pServ->pTasker,
SCTaskFunction,
SCSignalFunction,
SCDeleteConnection,
pCon,
1);
ANETsetReadCallback(handle, CommandDataCB,
usData, killCommandCBData);
SCSendOK(pCon);
return 1;
}
/*-----------------------------------------------------------------------*/
static int ANETTelnetReply(int sockHandle, char code, char cChar)
{
char pReply[3];
pReply[0] = IAC;
pReply[1] = code;
pReply[2] = cChar;
ANETwrite(sockHandle,pReply,3);
return 1;
}
/*-----------------------------------------------------------------------*/
static int ANETTelnetProcess(int handle, void *usData){
pCommandCBData self = NULL;
int length, status, i;
int cChar;
char *pPtr = NULL;
char pError[256];
self = (pCommandCBData)usData;
assert(self != NULL);
pPtr = ANETreadPtr(handle,&length);
/* do telnet analysis of the data buffer */
for(i = 0; i < length; i++){
cChar = (int)pPtr[i];
#ifdef TELNETDEBUG
if( (cChar > 48) && (cChar < 128) ){
printf("char: %c\n",cChar);
} else {
printf("Control: %d\n",cChar);
}
#endif
/* Telnet status switching */
switch(self->state){
case tData:
switch(cChar){
case IAC:
self->state = tIAC;
break;
case '\r':
case '\n':
if(!testAndInvokeInterrupt(self,handle)){
status = CostaTop(self->pCon->pStack, GetCharArray(self->command));
if(!status){
SCWrite(self->pCon,"ERROR: Busy", eError);
}
}
self->state = tCR;
DynStringClear(self->command);
break;
case (char)8: /* backspace */
DynStringBackspace(self->command);
break;
case (char)0:/* ignore 0 character sent as end of text */
break;
default:
DynStringConcatChar(self->command,(char)cChar);
break;
} /* end of tData case */
break;
case tCR:
if(cChar == '\r' || cChar == '\n' || cChar == '\0'){
continue;
} else {
self->state = tData;
DynStringConcatChar(self->command,(char)cChar);
}
break;
case tIAC:
switch(cChar)
{
case IAC:
self->state = tData;
break;
case WILL:
self->state = tWill;
break;
case WONT:
self->state = tWont;
break;
case DONT:
self->state = tDont;
break;
case DO:
self->state = tDo;
break;
case EOR:
self->state = tData;
break;
case SB:
self->state = tSB;
break;
case EC:
DynStringBackspace(self->command);
self->state = tData;
break;
case EL:
DynStringClear(self->command);
self->state = tData;
break;
case IP:
SCSetInterrupt(self->pCon,eAbortBatch);
self->state = tData;
break;
default:
self->state = tData;
break;
} /* end of tIAC */
break;
case tWill: /* we do not do options! */
ANETTelnetReply(handle,DONT,cChar);
self->state = tData;
break;
case tWont: /* we do not do options! A Wont is sent by the client
if it cannot do a option we requested it to have. As
we do not try to force options, this should not happen
*/
self->state = tData;
break;
case tDo: /* we do not do options! */
ANETTelnetReply(handle,WONT,cChar);
self->state = tData;
break;
case tDont: /* we do not do options! A Dont is sent by the client
if it cannot do a option we requested it to have. As
we do not try to force options, this should not happen
*/
self->state = tData;
break;
case tSB: /* as we do not have options, we cannot have suboption
negotaitions. Something is seriously wrong when
we are here. It is a protocoll error. However, we
ignore it silently. tSB marks the start of the
subnegotiation. The current character must be the
option code we are dealing with.
*/
self->state = tSE;
break;
case tSE:
/* now we are in the suboption parameter. Normally data
should be copied to a suboption string buffer here
until SE.
*/
switch(cChar)
{
case IAC:
break;
case SE:
self->state = tData;
/* suboption interpretation would go here */
break;
default:
/* copy data to suboption buffer */
break;
}
break;
default:
/* There is something wrong here! */
sprintf(pError,"ERROR: bad telnet code %d", cChar);
SICSLogWrite(pError,eInternal);
self->state = tData;
break;
} /* end master swicth */
} /* end for loop */
ANETreadConsume(handle,length);
return 1;
}
/*----------------------------------------------------------------------------------*/
static int TelnetAcceptCB(int handle, void *userData){
SConnection *pCon = NULL;
pCommandCBData usData = NULL;
pTelTask pTel = NULL;
pCon = SCreateConnection(pServ->pSics, handle, 3);
usData = malloc(sizeof(CommandCBData));
if(pCon == NULL || usData == NULL){
SICSLogWrite("Failure to allocate new Connection",eInternal);
return 0;
}
usData->command = CreateDynString(256,256);
if(usData->command == NULL){
SICSLogWrite("Failure to allocate new Connection",eInternal);
return 0;
}
usData->pCon = pCon;
usData->state = tData;
/* Create a task object for the telnet connection */
pTel = CreateTelnet(pCon);
if(!pTel){
SICSLogWrite("Failure to allocate new Telnet Task Object",
eInternal);
SCDeleteConnection(pCon);
return 0;
}
/* register connection and task */
pCon->iTelnet = 1;
TaskRegister(pServ->pTasker,
TelnetTask,
TelnetSignal,
DeleteTelnet,
pTel,
1);
ANETsetReadCallback(handle, ANETTelnetProcess,
usData, killCommandCBData);
SCSendOK(pCon);
return 1;
}
/*------------------------------------------------------------------------------------*/
static void NREADlog(int level, char *txt, void *userData){
puts(txt);
}
/*------------------------------------------------------------------------------------*/
int NetReadInstallANETPort(pNetRead self, eNRType eType, int iPort){
ANETsetLog(NREADlog,NULL);
switch(eType){
case naccept:
return ANETopenServerPort(iPort,CommandAcceptCB,NULL);
break;
case taccept:
return ANETopenServerPort(iPort,TelnetAcceptCB,NULL);
break;
}
return 0;
}

View File

@ -32,5 +32,7 @@
int NetReadWait4Data(pNetRead self, int iSocket);
int NetReadReadable(pNetRead self, int iSocket);
int NetReadResetUser(pNetRead self, int iSocket);
/*--------------------------------------------------------------------------*/
int NetReadInstallANETPort(pNetRead self, eNRType eType, int iPort);
#endif

View File

@ -11,11 +11,11 @@ through a command channel
A prior
version of SICS had a select system call for each of these cases. It was
found, that the code spent most of its time in the select system call
thus intrdoducing a major performance problem.
thus introducing a major performance problem.
The select system call can handle more then one file descriptor in one call.
This is exactly what this module handles. It does a global select on
all open sockets and forwards any pending data to approriate handlers.
all open sockets and forwards any pending data to appropriate handlers.
This scheme brought a drastic
performance improvement.
@ -25,13 +25,13 @@ differently:
A connection request will be validated, a new connection object will be
created and a new task for this connection object will be started.
A command will be placed in the apropriate command stack for the task
A command will be placed in the appropriate command stack for the task
belonging to this connection to work on in a later stage. The netreader will
also take care that all commands are complete, this is the terminator
\verb+\n+ or \verb+\r+ has been sent.
Both forms of interrupt will be interpreted and a suitable signal
will be sent to all runing tasks if the interrupt request is valid.
will be sent to all running tasks if the interrupt request is valid.
In order to perform his tasks the network reader needs to maintain a list of
all open sockets and their types. Additionally it needs to know about the
@ -61,6 +61,11 @@ come in on a user socket. This function is problematic with dynamically
creates and deleted objects such as environment device objects. Its use is
therefore no longer recommended.
In January 2009 a new asynchronous I/O structure was devised. This makes most of
NetReader obsolete. However, it was decided to keep the old structure for the
time being. A new function, NetReadInstallANETPort was added to install server
ports for the new system.
Thus the interface looks like this:
\begin{flushleft} \small
@ -88,7 +93,9 @@ $\langle$nrint {\footnotesize ?}$\rangle\equiv$
\mbox{}\verb@ int NetReadWait4Data(pNetRead self, int iSocket);@\\
\mbox{}\verb@ int NetReadReadable(pNetRead self, int iSocket);@\\
\mbox{}\verb@ int NetReadResetUser(pNetRead self, int iSocket);@\\
\mbox{}\verb@@$\diamond$
\mbox{}\verb@/*--------------------------------------------------------------------------*/@\\
\mbox{}\verb@ int NetReadInstallANETPort(pNetRead self, eNRType eType, int iPort); @\\
\mbox{}\verb@@$\Diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
@ -153,7 +160,7 @@ if not.
\mbox{}\verb@#define SICSNETREADER@\\
\mbox{}\verb@@$\langle$nrint {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@#endif@\\
\mbox{}\verb@@$\diamond$
\mbox{}\verb@@$\Diamond$
\end{list}
\vspace{-2ex}
\end{minipage}\\[4ex]

15
nread.w
View File

@ -11,11 +11,11 @@ through a command channel
A prior
version of SICS had a select system call for each of these cases. It was
found, that the code spent most of its time in the select system call
thus intrdoducing a major performance problem.
thus introducing a major performance problem.
The select system call can handle more then one file descriptor in one call.
This is exactly what this module handles. It does a global select on
all open sockets and forwards any pending data to approriate handlers.
all open sockets and forwards any pending data to appropriate handlers.
This scheme brought a drastic
performance improvement.
@ -25,13 +25,13 @@ differently:
A connection request will be validated, a new connection object will be
created and a new task for this connection object will be started.
A command will be placed in the apropriate command stack for the task
A command will be placed in the appropriate command stack for the task
belonging to this connection to work on in a later stage. The netreader will
also take care that all commands are complete, this is the terminator
\verb+\n+ or \verb+\r+ has been sent.
Both forms of interrupt will be interpreted and a suitable signal
will be sent to all runing tasks if the interrupt request is valid.
will be sent to all running tasks if the interrupt request is valid.
In order to perform his tasks the network reader needs to maintain a list of
all open sockets and their types. Additionally it needs to know about the
@ -61,6 +61,11 @@ come in on a user socket. This function is problematic with dynamically
creates and deleted objects such as environment device objects. Its use is
therefore no longer recommended.
In January 2009 a new asynchronous I/O structure was devised. This makes most of
NetReader obsolete. However, it was decided to keep the old structure for the
time being. A new function, NetReadInstallANETPort was added to install server
ports for the new system.
Thus the interface looks like this:
@d nrint @{
@ -83,6 +88,8 @@ Thus the interface looks like this:
int NetReadWait4Data(pNetRead self, int iSocket);
int NetReadReadable(pNetRead self, int iSocket);
int NetReadResetUser(pNetRead self, int iSocket);
/*--------------------------------------------------------------------------*/
int NetReadInstallANETPort(pNetRead self, eNRType eType, int iPort);
@}
This starts off with the definition of a data type for the net reader and an

View File

@ -213,6 +213,7 @@
IFDeleteOptions(pSICSOptions);
return 0;
}
/*
self->pServerPort = NETOpenPort(iPort);
if(!self->pServerPort)
{
@ -222,6 +223,8 @@
return 0;
}
NetReadRegister(pReader, self->pServerPort, naccept, NULL);
*/
NetReadInstallANETPort(pReader,naccept, iPort);
/* the device executor */
openDevexecLog();

View File

@ -8,6 +8,7 @@
Mark Koennecke, February 2003
Mark Koennecke, January 2004
added putHdb and putHdbSlab, Mark Koennecke, December 2008
------------------------------------------------------------------------*/
#include <stdlib.h>
#include <assert.h>
@ -30,6 +31,7 @@
#include "nxdict.h"
#include "nxscript.h"
#include "sicsdata.h"
#include "sicshipadaba.h"
extern char *trim(char *str);
@ -96,7 +98,7 @@ char *makeFilename(SicsInterp *pSics, SConnection *pCon) {
if(dir == NULL){
mkdir(pRes,S_IRWXU | S_IRGRP | S_IXGRP);
snprintf(pBueffel,255,"Creating dir: %s", pRes);
SCWrite(pCon,pBueffel,eWarning);
SCWrite(pCon,pBueffel,eLog);
} else {
closedir(dir);
}
@ -126,6 +128,28 @@ void changeExtension(char *filename, char *newExtension){
assert(strlen(pPtr) >= strlen(newExtension));
strcpy(pPtr,newExtension);
}
/*----------------------------------------------------------------------*/
static int listToArray(SicsInterp *pSics, char *list,
int intar[NX_MAXRANK]){
int argc, status, i, val;
CONST char **argv;
Tcl_Interp *pTcl = InterpGetTcl(pSics);
status = Tcl_SplitList(pTcl, list, &argc, &argv);
if(status != TCL_OK){
return status;
}
for(i = 0; i < argc; i++){
status = Tcl_GetInt(pTcl,argv[i],&val);
if(status != TCL_OK){
return status;
}
intar[i] = val;
}
Tcl_Free((char *)argv);
return TCL_OK;
}
/*======================== Action =======================================*/
static int handleFileOperations(SConnection *pCon, pNXScript self,
int argc, char *argv[]){
@ -209,7 +233,7 @@ static void putMotor(SConnection *pCon, SicsInterp *pSics, pNXScript self,
if(argc < 4){
SCWrite(pCon,"ERROR: insufficient number of arguments to putmotor",
eError);
eLogError);
return;
}
@ -219,7 +243,7 @@ static void putMotor(SConnection *pCon, SicsInterp *pSics, pNXScript self,
brumm = (pMotor)FindCommandData(pSics,argv[3],"Motor");
if(!brumm){
sprintf(buffer,"ERROR: motor %s not found!", argv[3]);
SCWrite(pCon,buffer,eError);
SCWrite(pCon,buffer,eLogError);
return;
}
@ -229,14 +253,14 @@ static void putMotor(SConnection *pCon, SicsInterp *pSics, pNXScript self,
status = MotorGetSoftPosition(brumm, pCon,&fVal);
if(!status){
sprintf(buffer,"ERROR: failed to read position of %s", argv[3]);
SCWrite(pCon,buffer,eError);
SCWrite(pCon,buffer,eLogError);
return;
}
status = NXDputalias(self->fileHandle,self->dictHandle,argv[2],&fVal);
if(status != NX_OK){
sprintf(buffer,"ERROR: failed to write %s with alias %s",
argv[3],argv[2]);
SCWrite(pCon,buffer,eError);
SCWrite(pCon,buffer,eLogError);
return;
}
@ -251,7 +275,7 @@ static void putMotor(SConnection *pCon, SicsInterp *pSics, pNXScript self,
if(status != NX_OK){
sprintf(buffer,"ERROR: failed to write %s zero with alias %s",
argv[3],argv[2]);
SCWrite(pCon,buffer,eError);
SCWrite(pCon,buffer,eLogError);
return;
}
}
@ -268,7 +292,7 @@ static void putCounter(SConnection *pCon, SicsInterp *pSics, pNXScript self,
if(argc < 4){
SCWrite(pCon,"ERROR: insufficient number of arguments to putcounter",
eError);
eLogError);
return;
}
memset(dummy,0,80*sizeof(char));
@ -279,7 +303,7 @@ static void putCounter(SConnection *pCon, SicsInterp *pSics, pNXScript self,
cter = (pCounter)FindCommandData(pSics,argv[3],"SingleCounter");
if(!cter){
sprintf(buffer,"ERROR: counter %s not found!", argv[3]);
SCWrite(pCon,buffer,eError);
SCWrite(pCon,buffer,eLogError);
return;
}
@ -292,7 +316,7 @@ static void putCounter(SConnection *pCon, SicsInterp *pSics, pNXScript self,
status = NXDputalias(self->fileHandle,self->dictHandle,newAlias,&fVal);
if(status != NX_OK){
sprintf(buffer,"ERROR: failed to write preset to %s", newAlias);
SCWrite(pCon,buffer,eError);
SCWrite(pCon,buffer,eLogError);
}
/*
@ -309,7 +333,7 @@ static void putCounter(SConnection *pCon, SicsInterp *pSics, pNXScript self,
status = NXDputalias(self->fileHandle,self->dictHandle,newAlias,dummy);
if(status != NX_OK){
sprintf(buffer,"ERROR: failed to write counter mode to %s", newAlias);
SCWrite(pCon,buffer,eError);
SCWrite(pCon,buffer,eLogError);
}
/*
@ -322,7 +346,7 @@ static void putCounter(SConnection *pCon, SicsInterp *pSics, pNXScript self,
status = NXDputalias(self->fileHandle,self->dictHandle,newAlias,&fVal);
if(status != NX_OK){
sprintf(buffer,"ERROR: failed to write count time to %s", newAlias);
SCWrite(pCon,buffer,eError);
SCWrite(pCon,buffer,eLogError);
}
}
@ -352,7 +376,7 @@ static void putSicsData(SConnection *pCon, SicsInterp *pSics,
if(argc < 4){
SCWrite(pCon,"ERROR: insufficient number of arguments to putSicsData",
eError);
eLogError);
return;
}
@ -362,14 +386,14 @@ static void putSicsData(SConnection *pCon, SicsInterp *pSics,
data = (pSICSData)FindCommandData(pSics,argv[3],"SICSData");
if(data == NULL){
snprintf(buffer,255,"ERROR: sicsdata %s not found!", argv[3]);
SCWrite(pCon,buffer,eError);
SCWrite(pCon,buffer,eLogError);
return;
}
status = NXDputalias(self->fileHandle,self->dictHandle,argv[2],data->data);
if(status != NX_OK){
sprintf(buffer,"ERROR: failed to write sicsdata to %s", argv[2]);
SCWrite(pCon,buffer,eError);
SCWrite(pCon,buffer,eLogError);
}
}
/*----------------------------------------------------------------------*/
@ -380,25 +404,177 @@ static void putAttribute(SConnection *pCon, SicsInterp *pSics,
if(argc < 5){
SCWrite(pCon,"ERROR: insufficient number of arguments to putAttribute",
eError);
eLogError);
return;
}
status = NXDopenalias(self->fileHandle,self->dictHandle,argv[2]);
if(status != NX_OK){
sprintf(buffer,"ERROR: failed to open alias %s", argv[2]);
SCWrite(pCon,buffer,eError);
SCWrite(pCon,buffer,eLogError);
return;
}
status = NXputattr(self->fileHandle,argv[3],(void *)argv[4],
strlen(argv[4])+1, type);
if(status != NX_OK){
sprintf(buffer,"ERROR: failed to write attribute %s", argv[3]);
SCWrite(pCon,buffer,eError);
SCWrite(pCon,buffer,eLogError);
}
NXopenpath(self->fileHandle,"/");
}
/*----------------------------------------------------------------------*/
static void putHdb(SConnection *pCon, SicsInterp *pSics, pNXScript self,
int argc, char *argv[]){
pHdb node = NULL;
char alias[512];
hdbValue v;
float fVal, *floatAr = NULL;
int i;
if(argc < 3){
SCWrite(pCon,"ERROR: putHdb needs at least node name",
eLogError);
return;
}
node = FindHdbNode(NULL,argv[2], pCon);
if(node == NULL){
SCPrintf(pCon,eLogError,"ERROR: node %s not found", argv[2]);
return;
}
memset(alias,0,512*sizeof(char));
if(!GetHdbProperty(node,"nxalias", alias, 512)){
if(argc < 4) {
SCPrintf(pCon,eLogError,"ERROR: neither nxalias property nor alias on command line found for %s",
argv[2]);
return;
} else {
strncpy(alias, argv[3],512);
}
}
GetHipadabaPar(node,&v,pCon);
switch(v.dataType){
case HIPNONE:
return;
break;
case HIPINT:
NXDputalias(self->fileHandle, self->dictHandle, alias,
&v.v.intValue);
break;
case HIPFLOAT:
fVal = v.v.doubleValue;
NXDputalias(self->fileHandle, self->dictHandle, alias,
&fVal);
break;
case HIPTEXT:
NXDputalias(self->fileHandle, self->dictHandle, alias,
v.v.text);
break;
case HIPINTAR:
case HIPINTVARAR:
NXDputalias(self->fileHandle, self->dictHandle, alias,
v.v.intArray);
break;
case HIPFLOATAR:
case HIPFLOATVARAR:
floatAr = malloc(v.arrayLength*sizeof(float));
if(floatAr == NULL){
SCPrintf(pCon,eLogError,"ERROR: out of memory writing %s", node->name);
return;
}
for(i = 0; i < v.arrayLength; i++){
floatAr[i] = v.v.floatArray[i];
}
NXDputalias(self->fileHandle, self->dictHandle, alias,
floatAr);
free(floatAr);
break;
}
ReleaseHdbValue(&v);
}
/*----------------------------------------------------------------------*/
static void putHdbSlab(SConnection *pCon, SicsInterp *pSics, pNXScript self,
int argc, char *argv[]){
pHdb node = NULL;
char alias[512];
hdbValue v;
float fVal, *floatAr = NULL;
int start[NX_MAXRANK], size[NX_MAXRANK];
int i, status;
if(argc < 5){
SCWrite(pCon,"ERROR: putHdbSlab needs at least node name start, size",
eLogError);
return;
}
node = FindHdbNode(NULL,argv[2], pCon);
if(node == NULL){
SCPrintf(pCon,eLogError,"ERROR: node %s not found", argv[2]);
return;
}
memset(alias,0,512*sizeof(char));
if(!GetHdbProperty(node,"nxalias", alias, 512)){
SCPrintf(pCon,eLogError,
"ERROR: nxalias property not found for %s",
argv[2]);
return;
}
status = NXDopenalias(self->fileHandle, self->dictHandle,alias);
if(status != NX_OK){
SCPrintf(pCon,eLogError,"ERROR: failed to open alias for %s", argv[2]);
return;
}
status = listToArray(pSics,argv[3],start);
if(status != TCL_OK){
SCWrite(pCon,"ERROR: failed to convert start value list", eLogError);
return;
}
status = listToArray(pSics,argv[4],size);
if(status != TCL_OK){
SCWrite(pCon,"ERROR: failed to convert size value list", eLogError);
return;
}
GetHipadabaPar(node,&v,pCon);
switch(v.dataType){
case HIPNONE:
return;
break;
case HIPINT:
status = NXputslab(self->fileHandle, &v.v.intValue, start,size);
break;
case HIPFLOAT:
fVal = v.v.doubleValue;
status = NXputslab(self->fileHandle, &fVal, start,size);
break;
case HIPTEXT:
status = NXputslab(self->fileHandle, v.v.text, start,size);
break;
case HIPINTAR:
case HIPINTVARAR:
status = NXputslab(self->fileHandle, v.v.intArray, start,size);
break;
case HIPFLOATAR:
case HIPFLOATVARAR:
floatAr = malloc(v.arrayLength*sizeof(float));
if(floatAr == NULL){
SCPrintf(pCon,eLogError,"ERROR: out of memory writing %s", node->name);
return;
}
for(i = 0; i < v.arrayLength; i++){
floatAr[i] = v.v.floatArray[i];
}
status = NXputslab(self->fileHandle, floatAr, start,size);
free(floatAr);
break;
}
if(status != NX_OK){
SCPrintf(pCon,eLogError,"ERROR: failed to write slab for node %s", argv[2]);
}
ReleaseHdbValue(&v);
}
/*----------------------------------------------------------------------*/
static void updateHMDim(NXScript *self, pHistMem mem){
int iDim[MAXDIM];
int i, rank, timeLength, status;
@ -444,7 +620,7 @@ static void putHistogramMemory(SConnection *pCon, SicsInterp *pSics,
if(argc < 4){
SCWrite(pCon,"ERROR: insufficient number of arguments to puthm",
eError);
eLogError);
return;
}
@ -454,7 +630,7 @@ static void putHistogramMemory(SConnection *pCon, SicsInterp *pSics,
mem = (pHistMem)FindCommandData(pSics,argv[3],"HistMem");
if(!mem){
sprintf(buffer,"ERROR: HistMem %s not found!", argv[3]);
SCWrite(pCon,buffer,eError);
SCWrite(pCon,buffer,eLogError);
return;
}
@ -475,14 +651,14 @@ static void putHistogramMemory(SConnection *pCon, SicsInterp *pSics,
if(status != TCL_OK){
sprintf(buffer,"ERROR: failed to convert %s to integer",
argv[4]);
SCWrite(pCon,buffer,eError);
SCWrite(pCon,buffer,eLogError);
return;
}
status = Tcl_GetInt(InterpGetTcl(pSics),argv[5],&length);
if(status != TCL_OK){
sprintf(buffer,"ERROR: failed to convert %s to integer",
argv[5]);
SCWrite(pCon,buffer,eError);
SCWrite(pCon,buffer,eLogError);
return;
}
}
@ -495,7 +671,7 @@ static void putHistogramMemory(SConnection *pCon, SicsInterp *pSics,
if(status != TCL_OK){
sprintf(buffer,"ERROR: failed to convert %s to integer",
argv[6]);
SCWrite(pCon,buffer,eError);
SCWrite(pCon,buffer,eLogError);
return;
}
}
@ -507,7 +683,7 @@ static void putHistogramMemory(SConnection *pCon, SicsInterp *pSics,
iData = (HistInt *)malloc(length*sizeof(HistInt));
if(!iData){
SCWrite(pCon,"ERROR: out of memory for reading histogram memory",
eError);
eLogError);
return;
}
memset(iData,0,length*sizeof(HistInt));
@ -526,7 +702,7 @@ static void putHistogramMemory(SConnection *pCon, SicsInterp *pSics,
}
}
if(!status){
SCWrite(pCon,"ERROR: failed to read histogram memory",eError);
SCWrite(pCon,"ERROR: failed to read histogram memory",eLogError);
if(subset){
free(iData);
}
@ -539,7 +715,7 @@ static void putHistogramMemory(SConnection *pCon, SicsInterp *pSics,
status = NXDputalias(self->fileHandle, self->dictHandle,argv[2],iData);
if(status != NX_OK){
sprintf(buffer,"ERROR: failed to write histogram memory data");
SCWrite(pCon,buffer,eError);
SCWrite(pCon,buffer,eLogError);
}
if(subset){
@ -563,7 +739,7 @@ static void putHistogramMemoryChunked(SConnection *pCon, SicsInterp *pSics,
if(argc < 5){
SCWrite(pCon,"ERROR: insufficient number of arguments to puthmchunked",
eError);
eLogError);
return;
}
@ -573,7 +749,7 @@ static void putHistogramMemoryChunked(SConnection *pCon, SicsInterp *pSics,
mem = (pHistMem)FindCommandData(pSics,argv[3],"HistMem");
if(!mem){
sprintf(buffer,"ERROR: HistMem %s not found!", argv[3]);
SCWrite(pCon,buffer,eError);
SCWrite(pCon,buffer,eLogError);
return;
}
@ -592,7 +768,7 @@ static void putHistogramMemoryChunked(SConnection *pCon, SicsInterp *pSics,
if(status != TCL_OK){
sprintf(buffer,"ERROR: failed to convert %s to integer",
argv[4]);
SCWrite(pCon,buffer,eError);
SCWrite(pCon,buffer,eLogError);
return;
}
@ -603,7 +779,7 @@ static void putHistogramMemoryChunked(SConnection *pCon, SicsInterp *pSics,
iData = (HistInt *)malloc(length*sizeof(HistInt));
if(!iData){
SCWrite(pCon,"ERROR: out of memory for reading histogram memory",
eError);
eLogError);
return;
}
memset(iData,0,length*sizeof(HistInt));
@ -622,7 +798,7 @@ static void putHistogramMemoryChunked(SConnection *pCon, SicsInterp *pSics,
}
}
if(!status){
SCWrite(pCon,"ERROR: failed to read histogram memory",eError);
SCWrite(pCon,"ERROR: failed to read histogram memory",eLogError);
if(subset){
free(iData);
}
@ -635,7 +811,7 @@ static void putHistogramMemoryChunked(SConnection *pCon, SicsInterp *pSics,
status = NXDputalias(self->fileHandle, self->dictHandle,argv[2],iData);
if(status != NX_OK){
sprintf(buffer,"ERROR: failed to write histogram memory data");
SCWrite(pCon,buffer,eError);
SCWrite(pCon,buffer,eLogError);
}
if(subset){
@ -646,28 +822,6 @@ static void putHistogramMemoryChunked(SConnection *pCon, SicsInterp *pSics,
return;
}
/*----------------------------------------------------------------------*/
static int listToArray(SicsInterp *pSics, char *list,
int intar[NX_MAXRANK]){
int argc, status, i, val;
CONST char **argv;
Tcl_Interp *pTcl = InterpGetTcl(pSics);
status = Tcl_SplitList(pTcl, list, &argc, &argv);
if(status != TCL_OK){
return status;
}
for(i = 0; i < argc; i++){
status = Tcl_GetInt(pTcl,argv[i],&val);
if(status != TCL_OK){
return status;
}
intar[i] = val;
}
Tcl_Free((char *)argv);
return TCL_OK;
}
/*----------------------------------------------------------------------*/
static void putSlab(SConnection *pCon, SicsInterp *pSics, pNXScript self,
int argc, char *argv[]){
int start[NX_MAXRANK], size[NX_MAXRANK];
@ -678,25 +832,25 @@ static void putSlab(SConnection *pCon, SicsInterp *pSics, pNXScript self,
if(argc < 6){
SCWrite(pCon,"ERROR: insufficient number of arguments to putslab",
eError);
eLogError);
return;
}
status = NXDopenalias(self->fileHandle, self->dictHandle,argv[2]);
if(status != NX_OK){
SCPrintf(pCon,eError,"ERROR: failed to open alias %s", argv[2]);
SCPrintf(pCon,eLogError,"ERROR: failed to open alias %s", argv[2]);
return;
}
status = listToArray(pSics,argv[3],start);
if(status != TCL_OK){
SCWrite(pCon,"ERROR: failed to convert start value list", eError);
SCWrite(pCon,"ERROR: failed to convert start value list", eLogError);
return;
}
status = listToArray(pSics,argv[4],size);
if(status != TCL_OK){
SCWrite(pCon,"ERROR: failed to convert size value list", eError);
SCWrite(pCon,"ERROR: failed to convert size value list", eLogError);
return;
}
@ -731,7 +885,7 @@ static void putSlab(SConnection *pCon, SicsInterp *pSics, pNXScript self,
if(written == 0){
SCWrite(pCon,"ERROR: failed to write data, data not recognised",
eError);
eLogError);
}
}
/*-------------------------------------------------------------------*/
@ -746,7 +900,7 @@ static void putTimeBinning(SConnection *pCon, SicsInterp *pSics,
if(argc < 4){
SCWrite(pCon,"ERROR: insufficient number of arguments to puttimebinning",
eError);
eLogError);
return;
}
@ -756,7 +910,7 @@ static void putTimeBinning(SConnection *pCon, SicsInterp *pSics,
mem = (pHistMem)FindCommandData(pSics,argv[3],"HistMem");
if(!mem){
sprintf(buffer,"ERROR: HistMem %s not found!", argv[3]);
SCWrite(pCon,buffer,eError);
SCWrite(pCon,buffer,eLogError);
return;
}
@ -768,7 +922,7 @@ static void putTimeBinning(SConnection *pCon, SicsInterp *pSics,
if(!status){
sprintf(buffer,"ERROR: alias %s for time binning not found",
argv[2]);
SCWrite(pCon,buffer,eError);
SCWrite(pCon,buffer,eLogError);
return;
}
timeBin = GetHistTimeBin(mem,&timeLength);
@ -780,7 +934,7 @@ static void putTimeBinning(SConnection *pCon, SicsInterp *pSics,
if(self->timeDivisor != 1){
timeCopy = (float *)malloc(timeLength*sizeof(float));
if(timeCopy == NULL){
SCWrite(pCon,"ERROR: out of memory writing time binning",eError);
SCWrite(pCon,"ERROR: out of memory writing time binning",eLogError);
return;
}
for(i = 0; i < timeLength; i++){
@ -796,7 +950,7 @@ static void putTimeBinning(SConnection *pCon, SicsInterp *pSics,
if(status != NX_OK){
sprintf(buffer,"ERROR: failed to write time binning");
SCWrite(pCon,buffer,eError);
SCWrite(pCon,buffer,eLogError);
}
SCSendOK(pCon);
return;
@ -814,7 +968,7 @@ static void putArray(SConnection *pCon, SicsInterp *pSics,
if(argc < 5){
SCWrite(pCon,"ERROR: insufficient number of arguments to array",
eError);
eLogError);
return;
}
tcl = InterpGetTcl(pSics);
@ -825,8 +979,8 @@ static void putArray(SConnection *pCon, SicsInterp *pSics,
*/
status = Tcl_GetInt(tcl,argv[4],&length);
if(status != TCL_OK){
sprintf(buffer,"ERROR: failed to convert %s to integer",argv[4]);
SCWrite(pCon,buffer,eError);
sprintf(buffer,"ERROR: failed to convert %s to integer in putarray",argv[4]);
SCWrite(pCon,buffer,eLogError);
return;
}
@ -838,9 +992,9 @@ static void putArray(SConnection *pCon, SicsInterp *pSics,
}
if(data == NULL){
snprintf(buffer,255,
"ERROR: out of memory or invalid length at %s, length = %s",
"ERROR: out of memory or invalid length in putarray at %s, length = %s",
argv[2],argv[4]);
SCWrite(pCon,buffer,eError);
SCWrite(pCon,buffer,eLogError);
return;
}
memset(data,0,length*sizeof(float));
@ -854,14 +1008,14 @@ static void putArray(SConnection *pCon, SicsInterp *pSics,
if(varData != NULL){
status = Tcl_GetDouble(tcl,varData,&dVal);
if(status != TCL_OK){
sprintf(buffer,"ERROR: failed to convert %s to double",
sprintf(buffer,"ERROR: failed to convert %s to double in putarray",
varData);
SCWrite(pCon,buffer,eError);
SCWrite(pCon,buffer,eLogError);
}
data[i] = (float)dVal;
} else {
snprintf(buffer,254,"WARNING: failed to find array element %d", i);
SCWrite(pCon,buffer,eError);
snprintf(buffer,254,"WARNING: failed to find array element %d in putarray", i);
SCWrite(pCon,buffer,eLogError);
}
}
@ -870,9 +1024,9 @@ static void putArray(SConnection *pCon, SicsInterp *pSics,
*/
status = NXDdefget(self->dictHandle,argv[2],buffer,254);
if(!status){
sprintf(buffer,"ERROR: alias %s for array not found",
sprintf(buffer,"ERROR: alias %s for array not found in putarray",
argv[2]);
SCWrite(pCon,buffer,eError);
SCWrite(pCon,buffer,eLogError);
free(data);
return;
}
@ -883,8 +1037,8 @@ static void putArray(SConnection *pCon, SicsInterp *pSics,
*/
status = NXDputdef(self->fileHandle,self->dictHandle,defString,data);
if(status != NX_OK){
sprintf(buffer,"ERROR: failed to write array");
SCWrite(pCon,buffer,eError);
sprintf(buffer,"ERROR: failed to write array in putarray");
SCWrite(pCon,buffer,eLogError);
}
free(data);
SCSendOK(pCon);
@ -902,7 +1056,7 @@ static void putIntArray(SConnection *pCon, SicsInterp *pSics,
if(argc < 5){
SCWrite(pCon,"ERROR: insufficient number of arguments to array",
eError);
eLogError);
return;
}
tcl = InterpGetTcl(pSics);
@ -914,7 +1068,7 @@ static void putIntArray(SConnection *pCon, SicsInterp *pSics,
status = Tcl_GetInt(tcl,argv[4],&length);
if(status != TCL_OK){
sprintf(buffer,"ERROR: failed to convert %s to integer",argv[4]);
SCWrite(pCon,buffer,eError);
SCWrite(pCon,buffer,eLogError);
return;
}
@ -925,7 +1079,7 @@ static void putIntArray(SConnection *pCon, SicsInterp *pSics,
data = (int *)malloc(length*sizeof(int));
}
if(data == NULL){
SCWrite(pCon,"ERROR: out of memory or invalid length",eError);
SCWrite(pCon,"ERROR: out of memory or invalid length",eLogError);
return;
}
memset(data,0,length*sizeof(int));
@ -941,12 +1095,12 @@ static void putIntArray(SConnection *pCon, SicsInterp *pSics,
if(status != TCL_OK){
sprintf(buffer,"ERROR: failed to convert %s to int",
varData);
SCWrite(pCon,buffer,eError);
SCWrite(pCon,buffer,eLogError);
}
data[i] = iVal;
} else {
snprintf(buffer,254,"WARNING: failed to find array element %d", i);
SCWrite(pCon,buffer,eError);
SCWrite(pCon,buffer,eLogError);
}
}
@ -957,7 +1111,7 @@ static void putIntArray(SConnection *pCon, SicsInterp *pSics,
if(!status){
sprintf(buffer,"ERROR: alias %s for array not found",
argv[2]);
SCWrite(pCon,buffer,eError);
SCWrite(pCon,buffer,eLogError);
free(data);
return;
}
@ -969,7 +1123,7 @@ static void putIntArray(SConnection *pCon, SicsInterp *pSics,
status = NXDputdef(self->fileHandle,self->dictHandle,defString,data);
if(status != NX_OK){
sprintf(buffer,"ERROR: failed to write array");
SCWrite(pCon,buffer,eError);
SCWrite(pCon,buffer,eLogError);
}
free(data);
SCSendOK(pCon);
@ -983,7 +1137,7 @@ static void putGlobal(SConnection *pCon, SicsInterp *pSics,
if(argc < 4){
SCWrite(pCon,"ERROR: insufficient number of arguments to putglobal",
eError);
eLogError);
return;
}
@ -991,7 +1145,7 @@ static void putGlobal(SConnection *pCon, SicsInterp *pSics,
status = NXputattr(self->fileHandle,argv[2],value,strlen(value),
NX_CHAR);
if(status != NX_OK){
SCWrite(pCon,"ERROR: failed to write attribute",eError);
SCWrite(pCon,"ERROR: failed to write attribute",eLogError);
}
SCSendOK(pCon);
}
@ -1007,14 +1161,14 @@ static int handlePut(SConnection *pCon, SicsInterp *pSics, pNXScript self,
if(strcmp(argv[1],"putfloat") == 0){
if(argc < 4){
SCWrite(pCon,"ERROR: insufficient number of arguments to putfloat",
eError);
eLogError);
return 1;
}
status = Tcl_GetDouble(InterpGetTcl(pSics),argv[3],&dVal);
if(status != TCL_OK){
sprintf(buffer,"ERROR: failed to convert %s to float",
argv[3]);
SCWrite(pCon,buffer,eError);
SCWrite(pCon,buffer,eLogError);
return 1;
}
fVal = (float)dVal;
@ -1023,20 +1177,20 @@ static int handlePut(SConnection *pCon, SicsInterp *pSics, pNXScript self,
if(status != NX_OK){
sprintf(buffer,"ERROR: failed to write %f to alias %s",
fVal, argv[2]);
SCWrite(pCon,buffer,eError);
SCWrite(pCon,buffer,eLogError);
}
return 1;
} else if(strcmp(argv[1],"putint") == 0){
if(argc < 4){
SCWrite(pCon,"ERROR: insufficient number of arguments to putint",
eError);
eLogError);
return 1;
}
status = Tcl_GetInt(InterpGetTcl(pSics),argv[3],&iVal);
if(status != TCL_OK){
sprintf(buffer,"ERROR: failed to convert %s to int",
argv[3]);
SCWrite(pCon,buffer,eError);
SCWrite(pCon,buffer,eLogError);
return 1;
}
status = NXDputalias(self->fileHandle, self->dictHandle,
@ -1044,14 +1198,14 @@ static int handlePut(SConnection *pCon, SicsInterp *pSics, pNXScript self,
if(status != NX_OK){
sprintf(buffer,"ERROR: failed to write %d to alias %s",
iVal, argv[2]);
SCWrite(pCon,buffer,eError);
SCWrite(pCon,buffer,eLogError);
}
return 1;
} else if (strcmp(argv[1],"puttext") == 0){
/*====================*/
if(argc < 4){
SCWrite(pCon,"ERROR: insufficient number of arguments to puttext",
eError);
eLogError);
return 1;
}
Arg2Text(argc-3,&argv[3],buffer,1023);
@ -1060,7 +1214,7 @@ static int handlePut(SConnection *pCon, SicsInterp *pSics, pNXScript self,
if(status != NX_OK){
sprintf(buffer,"ERROR: alias %s not found in puttext",
argv[2]);
SCWrite(pCon,buffer,eError);
SCWrite(pCon,buffer,eLogError);
return 1;
}
if(strlen(defString) < 900){
@ -1070,7 +1224,7 @@ static int handlePut(SConnection *pCon, SicsInterp *pSics, pNXScript self,
strcat(defString," }");
} else {
SCWrite(pCon,"ERROR: out of definition string space in puttext",
eError);
eLogError);
return 1;
}
status = NXDputdef(self->fileHandle,self->dictHandle,
@ -1078,7 +1232,7 @@ static int handlePut(SConnection *pCon, SicsInterp *pSics, pNXScript self,
if(status != NX_OK){
sprintf(buffer,"ERROR: failed to write alias %s",
argv[2]);
SCWrite(pCon,buffer,eError);
SCWrite(pCon,buffer,eLogError);
}
return 1;
} else if(strcmp(argv[1],"putmot") == 0){
@ -1089,6 +1243,14 @@ static int handlePut(SConnection *pCon, SicsInterp *pSics, pNXScript self,
/* ================*/
putCounter(pCon,pSics,self, argc,argv);
return 1;
} else if(strcmp(argv[1],"puthdb") == 0){
/* ================*/
putHdb(pCon,pSics,self, argc,argv);
return 1;
} else if(strcmp(argv[1],"puthdbslab") == 0){
/* ================*/
putHdbSlab(pCon,pSics,self, argc,argv);
return 1;
}else if(strcmp(argv[1],"puthm") == 0){
/*=================*/
putHistogramMemory(pCon,pSics,self,argc, argv);
@ -1115,7 +1277,7 @@ static int handlePut(SConnection *pCon, SicsInterp *pSics, pNXScript self,
/*===============*/
putSlab(pCon,pSics,self,argc,argv);
} else {
SCWrite(pCon,"ERROR: put command not recognised",eError);
SCWrite(pCon,"ERROR: put command not recognised",eLogError);
}
return 1;
}
@ -1128,7 +1290,7 @@ static void makeLink(SConnection *pCon, SicsInterp *pSics,
if(argc < 4){
SCWrite(pCon,"ERROR: insufficient number of arguments to makelink",
eError);
eLogError);
return;
}
@ -1137,7 +1299,7 @@ static void makeLink(SConnection *pCon, SicsInterp *pSics,
if(status != NX_OK){
snprintf(pBueffel,255,"ERROR: linking %s against %s failed",
argv[2], argv[3]);
SCWrite(pCon,pBueffel,eError);
SCWrite(pCon,pBueffel,eLogError);
return;
}
@ -1150,12 +1312,12 @@ static void updateDictVar(SConnection *pCon, pNXScript self, int argc,
if(self->dictHandle == NULL){
SCWrite(pCon,"ERROR: cannot update variable, dictionary not open",
eError);
eLogError);
return;
}
if(argc < 4){
SCWrite(pCon,"ERROR: insufficient number of arguments to updateDictVar",
eError);
eLogError);
return;
}
NXDupdate(self->dictHandle,argv[2],argv[3]);
@ -1176,7 +1338,7 @@ int NXScriptAction(SConnection *pCon, SicsInterp *pSics, void *pData,
return 1;
}
if(argc < 2){
SCWrite(pCon,"ERROR: no keyword found",eError);
SCWrite(pCon,"ERROR: no keyword found",eLogError);
return 1;
}
strtolower(argv[1]);
@ -1193,7 +1355,7 @@ int NXScriptAction(SConnection *pCon, SicsInterp *pSics, void *pData,
}
} else if(strcmp(argv[1],"divisor") == 0){
if(argc < 3) {
SCWrite(pCon,"ERROR: no diviso found",eError);
SCWrite(pCon,"ERROR: no divisor found",eLogError);
return 1;
}
if(!SCMatchRights(pCon,usMugger)){
@ -1216,7 +1378,7 @@ int NXScriptAction(SConnection *pCon, SicsInterp *pSics, void *pData,
if we are here, we can only continue if files are open
*/
if(self->fileHandle == NULL || self->dictHandle == NULL){
SCWrite(pCon,"ERROR: cannot write, files not open",eError);
SCWrite(pCon,"ERROR: cannot write, files not open",eLogError);
return 1;
}
@ -1232,7 +1394,7 @@ int NXScriptAction(SConnection *pCon, SicsInterp *pSics, void *pData,
if(strcmp(argv[1],"isalias") == 0) {
if(argc < 3) {
SCWrite(pCon,"ERROR: need alias to test",eError);
SCWrite(pCon,"ERROR: need alias to test",eLogError);
return 1;
}
if(NXDget(self->dictHandle,argv[2],buffer,131) == NX_OK){

View File

@ -46,8 +46,7 @@ static int UpdateTask(void *pData){
}
}
/*--------------------------------------------------------------------*/
static int CountCallback(int iEvent, void *pEventData, void *pUser,
commandContext cc){
static int CountCallback(int iEvent, void *pEventData, void *pUser){
pNXupdate self = NULL;
SConnection *pCon = NULL;
@ -258,7 +257,6 @@ 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",
@ -311,11 +309,9 @@ int UpdateFactory(SConnection *pCon, SicsInterp *pSics, void *pData,
/*
register callbacks
*/
comCon.transID = 0;
strncpy(comCon.deviceID,"internal",SCDEVIDLEN);
RegisterCallback(pCall,comCon,COUNTSTART,CountCallback,
RegisterCallback(pCall,COUNTSTART,CountCallback,
self,NULL);
RegisterCallback(pCall,comCon,COUNTEND,CountCallback,
RegisterCallback(pCall,COUNTEND,CountCallback,
self,NULL);
AddCommand(pSics,argv[1],UpdateAction,KillUpdate,self);

View File

@ -1,5 +1,5 @@
#line 365 "interface.w"
#line 385 "interface.w"
#line 29 "interface.w"
@ -56,7 +56,7 @@ typedef struct {
#endif
#line 366 "interface.w"
#line 386 "interface.w"
/*--------------------------------------------------------------------------*/
/* Additional properties used by the ANSTO site to provide more information

22
ofac.c
View File

@ -85,7 +85,6 @@
#include "udpquieck.h"
#include "choco.h"
#include "chadapter.h"
#include "hklscan.h"
#include "xytable.h"
#include "maximize.h"
#include "difrac.h"
@ -129,6 +128,10 @@
#include "hdbqueue.h"
#include "genericcontroller.h"
#include "proxy.h"
#include "reflist.h"
#include "singlex.h"
#include "motorsec.h"
#include "background.h"
/*----------------------- Server options creation -------------------------*/
static int IFServerOption(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[])
@ -257,6 +260,7 @@
AddCommand(pInter,"list",SicsList,NULL,NULL);
AddCommand(pInter,"InstallHdb",InstallSICSHipadaba,NULL,NULL);
MakeProtocol(pInter);
InstallBackground(pInter);
/* commands to do with the executor. Only StopExe carries the
DeleteFunction in order to avoid double deletion. All the
@ -296,7 +300,6 @@
AddCommand(pInter,"kill_command",SICSKill,NULL,NULL);
AddCommand(pInter,"MakeChopper",ChocoFactory,NULL,NULL);
AddCommand(pInter,"ChopperAdapter",CHAdapterFactory,NULL,NULL);
AddCommand(pInter,"MakeHklscan",HklscanFactory,NULL,NULL);
AddCommand(pInter,"MakeXYTable",XYFactory,NULL,NULL);
AddCommand(pInter,"MakeMaximize",MaximizeFactory,NULL,NULL);
AddCommand(pInter,"MakeLin2Ang",MakeLin2Ang,NULL,NULL);
@ -350,6 +353,9 @@
AddCommand(pInter,"MakeGenController",GenControllerFactory,NULL,NULL);
AddCommand(pInter,"genconfigure",GenControllerConfigure,NULL,NULL);
AddCommand(pInter,"MakeProxy",ProxyFactory,NULL,NULL);
AddCommand(pInter,"MakeRefList",MakeReflectionList,NULL,NULL);
AddCommand(pInter,"MakeSingleX",MakeSingleX,NULL,NULL);
AddCommand(pInter,"MakeSecMotor",SecMotorFactory,NULL,NULL);
/*
install site specific commands
@ -425,6 +431,9 @@
RemoveCommand(pSics,"MakeGenController");
RemoveCommand(pSics,"genconfigure");
RemoveCommand(pSics,"MakeProxy");
RemoveCommand(pSics,"MakeRefList");
RemoveCommand(pSics,"MakeSingleX");
RemoveCommand(pSics,"MakeSecMotor");
/*
remove site specific installation commands
*/
@ -475,21 +484,12 @@
InitIniCommands(pSics,pServ->pTasker);
InstallBckRestore(pCon,pSics);
pCon->iFiles = 0;
/* evaluate the file */
sprintf(pBueffel,"fileeval %s",file);
iRet = InterpExecute(pSics,pCon,pBueffel);
if(!iRet)
{
KillIniCommands(pSics);
RemoveStartupCommands();
SCDeleteConnection(pCon);
return 0;
}
/* done */
pCon->iFiles = 0;
SCDeleteConnection(pCon);
KillIniCommands(pSics);
RemoveStartupCommands();

View File

@ -347,7 +347,7 @@
return 0;
}
sprintf(pBueffel,"Trying hard to optimise variable %s",pOvar->pName);
SCWrite(pCon,pBueffel,eWarning);
SCWrite(pCon,pBueffel,eLog);
iRet = SilentScan(self->pScanner,pOvar->iStep,self->eCount,
self->fPreset,pServ->pSics,pCon);
if(!iRet)
@ -397,11 +397,11 @@
strcat(pBueffel,cData);
break;
}
SCWrite(pCon,pBueffel,eWarning);
SCWrite(pCon,pBueffel,eLog);
if(fMax < self->fThreshold)
{
SCWrite(pCon,"Peak may be lost, increasing scan range",eWarning);
SCWrite(pCon,"Peak may be lost, increasing scan range",eLog);
pOvar->iLost++;
if(pOvar->iLost > 2)
{
@ -435,11 +435,11 @@
{
pOvar->fShift = ABS(pOvar->fCenter - fNewCenter);
sprintf(pBueffel,"%s shifted by %8.2f ",pOvar->pName,pOvar->fShift);
SCWrite(pCon,pBueffel,eWarning);
SCWrite(pCon,pBueffel,eLog);
pOvar->fPrecision = 3*fStdDev;
sprintf(pBueffel,"%s precision set to 3*StdDev = %8.3f",
pOvar->pName, 3*fStdDev);
SCWrite(pCon,pBueffel,eWarning);
SCWrite(pCon,pBueffel,eLog);
pOvar->fCenter = fNewCenter;
}
/* drive to the new center */
@ -627,7 +627,7 @@ static int findDirection(pOptimise self, pOVarEntry pOvar, SConnection *pCon)
}
snprintf(buffer,255,"Climbing %s, value = %f, count = %ld",
pOvar->pName, varValue, currentCount);
SCWrite(pCon,buffer,eWarning);
SCWrite(pCon,buffer,eLog);
if(currentCount <= lastCount)
{
@ -695,7 +695,7 @@ static int findDirection(pOptimise self, pOVarEntry pOvar, SConnection *pCon)
for(iCycle = 0; iCycle < self->iMaxCycles; iCycle++)
{
sprintf(pBueffel,"Optimiser cycle %d of %d started",iCycle, self->iMaxCycles);
SCWrite(pCon,pBueffel,eStatus);
SCWrite(pCon,pBueffel,eLog);
for(i = iRedoVar; i < self->iVar; i++)
{
iRet = CenterVariable(self,pCon,i);
@ -740,7 +740,7 @@ static int findDirection(pOptimise self, pOVarEntry pOvar, SConnection *pCon)
for(iCycle = 0; iCycle < self->iMaxCycles; iCycle++)
{
sprintf(pBueffel,"Optimiser cycle %d of %d started",iCycle, self->iMaxCycles);
SCWrite(pCon,pBueffel,eStatus);
SCWrite(pCon,pBueffel,eLog);
for(i = iRedoVar; i < self->iVar; i++)
{
iRet = ClimbVariable(self,pCon,i);

View File

@ -22,6 +22,8 @@
"error",
"hdbvalue",
"hdbevent",
"log",
"logerror",
NULL };
static int iNoCodes = 13;
#endif

View File

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

View File

@ -173,7 +173,7 @@ void DeleteProtocol(void *self)
/*------------------------------------------------------------------*/
static int ContextDo(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]){
commandContext comCon;
SConnection *comCon = NULL;
char buffer[1024];
char *command;
int status;
@ -183,23 +183,27 @@ static int ContextDo(SConnection *pCon, SicsInterp *pSics, void *pData,
return 0;
}
status = Tcl_GetInt(pSics->pTcl,argv[1],&comCon.transID);
comCon = SCCopyConnection(pCon);
if(comCon == NULL){
SCWrite(pCon,"EROOR: out of memory in contextdo", eError);
return 0;
}
status = Tcl_GetInt(pSics->pTcl,argv[1],&comCon->transID);
if(status != TCL_OK){
snprintf(buffer,1023,"ERROR: failed to convert %s to transaction ID", argv[1]);
SCWrite(pCon,buffer,eError);
return 0;
}
strncpy(comCon.deviceID,argv[2],SCDEVIDLEN);
strncpy(comCon->deviceID,argv[2],SCDEVIDLEN);
memset(buffer,0,sizeof(buffer));
command = Arg2Tcl(argc-2,&argv[2],buffer,sizeof buffer);
if (!command) {
SCWrite(pCon,"ERROR: no more memory",eError);
return 0;
}
SCPushContext2(pCon,comCon);
status = InterpExecute(pSics,pCon,command);
status = InterpExecute(pSics,comCon,command);
if (command != buffer) free(command);
SCPopContext(pCon);
SCDeleteConnection(comCon);
return status;
}
/*--------------------------------------------------------------------------*/
@ -236,7 +240,7 @@ static int ProtocolOptions(SConnection* pCon, pProtocol pPro)
for(i=0;i<pPro->iNumPros;i++)
{
sprintf(pBuffer,"Protocol[%d] = %s",i,pPro->pProList[i]);
SCWrite(pCon,pBuffer,eStatus);
SCWrite(pCon,pBuffer,eValue);
}
return 1;
}
@ -246,18 +250,22 @@ static int ProtocolHelp(SConnection* pCon, Protocol* pPro)
{
SCWrite(pCon,
"Usage: protocol {help|list|options|reset} | set protocolName",
eStatus);
eValue);
return 1;
}
/*------------------------------------------------------------------------*/
static int ProtocolSet(SConnection* pCon, Protocol* pPro, char *pProName)
{
SConnection *pMaster = NULL;
int proID;
if(!SCVerifyConnection(pCon))
{
return 0;
}
pMaster = SCfindMaster(pCon);
assert(pMaster != NULL);
/* lazy initialisation of defaultWriter since connection is verified */
InitDefaultProtocol(pCon,pPro);
@ -278,28 +286,35 @@ static int ProtocolSet(SConnection* pCon, Protocol* pPro, char *pProName)
break;
case 1: /* normal (connection start default) */
SCSetWriteFunc(pMaster,SCNormalWrite);
SCSetWriteFunc(pCon,SCNormalWrite);
break;
case 2: /* outcodes */
SCSetWriteFunc(pMaster,SCWriteWithOutcode);
SCSetWriteFunc(pCon,SCWriteWithOutcode);
break;
case 3: /* sycamore */
SCSetWriteFunc(pMaster,SCWriteSycamore);
SCSetWriteFunc(pCon,SCWriteSycamore);
break;
case 4: /* json */
SCSetWriteFunc(pCon,SCWriteJSON_String);
SCSetWriteFunc(pMaster,SCWriteJSON_String);
break;
case 5:
SCSetWriteFunc(pMaster,SCACTWrite);
SCSetWriteFunc(pCon,SCACTWrite);
break;
case 0: /* default = psi_sics */
default:
SCSetWriteFunc(pMaster,pPro->defaultWriter);
SCSetWriteFunc(pCon,pPro->defaultWriter);
break;
}
pCon->iProtocolID = proID;
pMaster->iProtocolID = proID;
SCSendOK(pCon);
return 1;
}
@ -356,7 +371,7 @@ static int ProtocolList(SConnection* pCon, Protocol* pPro)
{
SCWrite(pCon,
"Usage: protocol {help|list|options|reset} | set protocolName",
eStatus);
eValue);
return 1;
}
@ -589,7 +604,6 @@ int SCWriteSycamore(SConnection *pCon, char *pBuffer, int iOut)
/* first the socket */
/*strcat(pMsg, pBueffel);*/
iRet = SCDoSockWrite(pCon,GetCharArray(pMsg));
SCWriteToLogFiles(pCon,GetCharArray(pMsg));
}
if (pMsg != NULL)
DeleteDynString(pMsg);
@ -742,7 +756,6 @@ int SCWriteJSON_String(SConnection *pCon, char *pBuffer, int iOut)
iRet = 0;
} else {
iRet = SCDoSockWrite(pCon,json_object_to_json_string(my_object));
SCWriteToLogFiles(pCon,pBuffer);
}
}
if (tmp_json != NULL && !is_error(tmp_json))

47
remob.c
View File

@ -45,7 +45,7 @@ typedef struct RemServer {
int taskActive;
int interestActive;
int forwardMessages;
SCStore *conn;
SConnection *conn;
} RemServer;
struct Remob {
@ -156,7 +156,7 @@ static int RemHandle(RemServer *remserver) {
/*-------------------------------------------------------------------------*/
static void RemCopy(RemChannel *rc, SConnection *pCon) {
if (pCon != NULL && rc->line[0] != '\0') {
SCPrintf(pCon, eStatus, " %s", rc->line);
SCPrintf(pCon, eLog, " %s", rc->line);
}
}
/*-------------------------------------------------------------------------*/
@ -260,10 +260,8 @@ static int RemServerTask(void *data) {
if (remserver->forwardMessages) {
/* forward all other messages */
if (SCStoreConnected(remserver->conn)) {
pCon = SCStorePush(remserver->conn);
RemCopy(rc, pCon);
SCStorePop(remserver->conn);
if (SCisConnected(remserver->conn)) {
RemCopy(rc, remserver->conn);
}
}
}
@ -406,7 +404,10 @@ static float RemobGetValue(void *pData, SConnection *pCon) {
assert(remob);
remserver->conn = SCSave(pCon, remserver->conn);
if(remserver->conn != NULL){
SCDeleteConnection(remserver->conn);
}
remserver->conn = SCCopyConnection(pCon);
none = -1.25e6;
value= none;
snprintf(buf, sizeof(buf), "<%s", remob->name);
@ -457,7 +458,10 @@ static int RemobStatus(void *pData, SConnection *pCon) {
assert(remob);
remob->server->conn = SCSave(pCon, remob->server->conn);
if(remob->server->conn != NULL){
SCDeleteConnection(remob->server->conn);
}
remob->server->conn = SCCopyConnection(pCon);
return remob->status;
}
/*---------------------------------------------------------------------------*/
@ -475,11 +479,15 @@ static long RemobRun(void *self, SConnection *pCon, float fNew) {
RemChannel *rc;
int nChan;
remserver = remob->server;
remserver->conn = SCSave(pCon, remserver->conn);
assert(remob);
assert(pCon);
remserver = remob->server;
if(remserver->conn != NULL){
SCDeleteConnection(remserver->conn);
}
remserver->conn = SCCopyConnection(pCon);
rights = SCGetRights(pCon);
nChan = rights <= usUser;
rc = &remserver->rc[nChan];
@ -526,6 +534,9 @@ static void KillInfo(void *pData) {
if (self->pName) {
free(self->pName);
}
if(self->pCon){
SCDeleteConnection(self->pCon);
}
free(self);
}
/*------------------- The CallBack function for interest ------------------*/
@ -572,7 +583,10 @@ int RemobAction(SConnection *pCon, SicsInterp *pSics, void *pData,
nChan = (rights <= usUser);
rc = &remserver->rc[nChan];
if (rights >= usUser) {
remserver->conn = SCSave(pCon, remserver->conn);
if(remserver->conn != NULL){
SCDeleteConnection(remserver->conn);
}
remserver->conn = SCCopyConnection(pCon);
}
if (argc == 1) {
iRet = RemTransact(remserver, nChan, pCon, remob->name, ">", NULL);
@ -664,7 +678,10 @@ int RemServerAction(SConnection *pCon, SicsInterp *pSics, void *pData,
nChan = (rights <= usUser);
rc = &remserver->rc[nChan];
if (nChan) {
remserver->conn = SCSave(pCon, remserver->conn);
if(remserver->conn != NULL){
SCDeleteConnection(remserver->conn);
}
remserver->conn = SCCopyConnection(pCon);
}
if (argc == 1) {
serverport = IFindOption(pSICSOptions,"ServerPort");
@ -680,7 +697,7 @@ int RemServerAction(SConnection *pCon, SicsInterp *pSics, void *pData,
}
}
if (thishostname == NULL) thishostname = "undef";
SCPrintf(pCon, eStatus, "%s = %s:%d %s:%s",
SCPrintf(pCon, eValue, "%s = %s:%d %s:%s",
argv[0], remserver->host, remserver->port, thishostname, serverport);
} else if (argc>2 && strcasecmp(argv[1],"nowait") == 0) {
RemConnect(remserver, nChan);
@ -737,7 +754,9 @@ static void RemServerKill(void *self) {
DeleteDescriptor(remserver->desc);
if (remserver->name) free(remserver->name);
if (remserver->host) free(remserver->host);
SCStoreFree(remserver->conn);
if(remserver->conn != NULL){
SCDeleteConnection(remserver->conn);
}
free(remserver);
}
/*-----------------------------------------------------------------------*/

View File

@ -237,7 +237,7 @@ int readRS232TillTerm(prs232 self, void *data, int *datalen){
}
else if(iRet == -1)
{
printf("Incomplete read: %s\n", (char *)data);
printf("Incomplete read: %s, errno = %d\n", (char *)data, errno);
return INCOMPLETE;
}
else if (iRet < 0)
@ -374,7 +374,7 @@ int transactRS232(prs232 self, void *send, int sendLen,
}
else
{
printf("RS232 IN/TRANS/INCOMPLETE: %s",(char *)reply);
printf("RS232 IN/TRANS/INCOMPLETE: %s, errno = %d",(char *)reply, errno);
}
}
if(iRet == 0)

132
scan.c
View File

@ -395,7 +395,7 @@ int StoreScanCounts(pScanData self, char *data)
if(data == NULL)
{
SCWrite(self->pCon,"WARNING: StoreScanCounts called without data",
eWarning);
eLog);
return 1;
}
InitCountEntry(&sCount);
@ -409,9 +409,9 @@ int StoreScanCounts(pScanData self, char *data)
}
else
{
SCWrite(self->pCon,"WARNING: No data in StoreScanCounts",eWarning);
SCWrite(self->pCon,"WARNING: No data in StoreScanCounts",eLog);
snprintf(pBueffel,255,"Received: %s", data);
SCWrite(self->pCon,pBueffel,eWarning);
SCWrite(self->pCon,pBueffel,eLog);
return 1;
}
pPtr = stptok(pPtr,pNumber,29," \t");
@ -431,7 +431,7 @@ int StoreScanCounts(pScanData self, char *data)
{
SCWrite(self->pCon,
"ERROR: I have only space for 10 Monitors in count structure",
eError);
eLogError);
return 0;
}
}
@ -484,7 +484,7 @@ CountEntry CollectCounterData(pScanData self)
iRet = Tcl_Eval(pTcl,self->pCommand);
if(iRet != TCL_OK)
{
SCWrite(self->pCon,pTcl->result,eError);
SCWrite(self->pCon,pTcl->result,eLogError);
return sCount;
}
/* interprete the Tcl result as a list of counts
@ -495,7 +495,7 @@ CountEntry CollectCounterData(pScanData self)
pPtr = strtok(pAns," ");
if(!pPtr)
{
SCWrite(self->pCon,"ERROR: no counts found in Tcl-result",eError);
SCWrite(self->pCon,"ERROR: no counts found in Tcl-result",eLogError);
}
sscanf(pPtr,"%f",&fVal);
sCount.lCount = (long)fVal;
@ -559,11 +559,11 @@ CountEntry CollectCounterData(pScanData self)
SCSetInterrupt(self->pCon,eContinue);
SCWrite(self->pCon,
"WARNING: skipped scan point due to motor failure",
eWarning);
eLog);
continue;
break;
case eAbortScan:
SCWrite(self->pCon,"ERROR: Scan aborted",eError);
SCWrite(self->pCon,"ERROR: Scan aborted",eLogError);
/* eat the interrupt, the requested op has been
done
*/
@ -571,14 +571,14 @@ CountEntry CollectCounterData(pScanData self)
return 0;
break;
default: /* all others */
SCWrite(self->pCon,"ERROR: Scan aborted",eError);
SCWrite(self->pCon,"ERROR: Scan aborted",eLogError);
return 0;
break;
}
if(!iRet)
{
SCWrite(self->pCon,"WARNING: skipped scan point after drive failure",
eWarning);
eLog);
continue;
}
@ -596,7 +596,7 @@ CountEntry CollectCounterData(pScanData self)
continue;
break;
case eAbortScan:
SCWrite(self->pCon,"ERROR: Scan aborted",eError);
SCWrite(self->pCon,"ERROR: Scan aborted",eLogError);
/* eat the interrupt, the requested op has been
done
*/
@ -604,14 +604,14 @@ CountEntry CollectCounterData(pScanData self)
return 0;
break;
default: /* all others */
SCWrite(self->pCon,"ERROR: Scan aborted",eError);
SCWrite(self->pCon,"ERROR: Scan aborted",eLogError);
return 0;
break;
}
if(!iRet)
{
SCWrite(self->pCon,"WARNING: skipped scan point after count failure",
eWarning);
eLog);
continue;
}
@ -1264,8 +1264,7 @@ CountEntry CollectCounterData(pScanData self)
return 1;
}
/*--------------------------------------------------------------------------*/
static int ScanInterest(int iEvent, void *pEventData, void *pUser,
commandContext cc)
static int ScanInterest(int iEvent, void *pEventData, void *pUser)
{
pScanData self = NULL;
SConnection *pCon = NULL;
@ -1280,14 +1279,18 @@ CountEntry CollectCounterData(pScanData self)
assert(self);
assert(pCon);
if(!SCisConnected(pCon)){
return -1;
}
if(iEvent == SCANSTART)
{
SCWriteInContext(pCon,"NewScan",eWarning,cc);
SCWrite(pCon,"NewScan",eLog);
return 1;
}
else if(iEvent == SCANEND)
{
SCWriteInContext(pCon,"ScanEnd",eWarning,cc);
SCWrite(pCon,"ScanEnd",eLog);
return 1;
}
else if(iEvent == SCANPOINT)
@ -1319,7 +1322,7 @@ CountEntry CollectCounterData(pScanData self)
strcat(pPtr,"}");
oldWrite = SCGetWriteFunc(pCon);
SCSetWriteFunc(pCon,SCOnlySockWrite);
SCWrite(pCon,pPtr,eWarning);
SCWrite(pCon,pPtr,eLog);
SCSetWriteFunc(pCon,oldWrite);
free(lData);
free(pPtr);
@ -1328,8 +1331,7 @@ CountEntry CollectCounterData(pScanData self)
return 1;
}
/*--------------------------------------------------------------------------*/
static int ScanDynInterest(int iEvent, void *pEventData, void *pUser,
commandContext cc)
static int ScanDynInterest(int iEvent, void *pEventData, void *pUser)
{
pScanData self = NULL;
SConnection *pCon = NULL;
@ -1347,14 +1349,19 @@ CountEntry CollectCounterData(pScanData self)
assert(self);
assert(pCon);
if(!SCisConnected(pCon))
{
return -1;
}
if(iEvent == SCANSTART)
{
SCWriteInContext(pCon,"NewScan",eWarning,cc);
SCWrite(pCon,"NewScan",eLog);
return 1;
}
else if(iEvent == SCANEND)
{
SCWriteInContext(pCon,"ScanEnd",eWarning,cc);
SCWrite(pCon,"ScanEnd",eLog);
return 1;
}
else if(iEvent == SCANPOINT)
@ -1376,16 +1383,15 @@ CountEntry CollectCounterData(pScanData self)
}
snprintf(pBueffel,255,"%s.scanpoint = {%d %f %ld}",
self->objectName,i,fVal,lVal);
SCWriteInContext(pCon,pBueffel,eValue,cc);
SCWrite(pCon,pBueffel,eLog);
}
return 1;
}
/*--------------------------------------------------------------------------*/
static int ScanUUInterest(int iEvent, void *pEventData, void *pUser,
commandContext cc)
static int ScanUUInterest(int iEvent, void *pEventData, void *pUser)
{
pScanData self = NULL;
SConnection *pCon = NULL;
SConnection *pCon = NULL, *comCon = NULL;
char pItem[20];
long *lData = NULL;
int *iData = NULL;
@ -1396,15 +1402,21 @@ CountEntry CollectCounterData(pScanData self)
assert(self);
assert(pCon);
/*
printf("ScanUUInterest called for pCon = %p handle %d\n", pCon, pCon->sockHandle);
*/
if(!SCisConnected(pCon)){
return -1;
}
if(iEvent == SCANSTART)
{
SCWriteInContext(pCon,"NewScan",eWarning,cc);
SCWrite(pCon,"NewScan",eLog);
return 1;
}
else if(iEvent == SCANEND)
{
SCWriteInContext(pCon,"ScanEnd",eWarning,cc);
SCWrite(pCon,"ScanEnd",eLog);
return 1;
}
else if(iEvent == SCANPOINT)
@ -1426,9 +1438,7 @@ CountEntry CollectCounterData(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;
@ -1929,53 +1939,53 @@ static int DumpScan(pScanData self, SConnection *pCon)
/*-------- interest */
else if(strcmp(argv[1],"interest") == 0)
{
lID = RegisterCallback(self->pCall, SCGetContext(pCon),SCANSTART, ScanInterest,
pCon, NULL);
SCRegister(pCon,pSics, self->pCall,lID);
lID = RegisterCallback(self->pCall, SCGetContext(pCon),SCANEND, ScanInterest,
pCon, NULL);
SCRegister(pCon,pSics, self->pCall,lID);
lID = RegisterCallback(self->pCall, SCGetContext(pCon),SCANPOINT, ScanInterest,
pCon, NULL);
SCRegister(pCon,pSics, self->pCall,lID);
/*
printf("Registering scan callbacks on handle %d\n", pCon->sockHandle);
*/
lID = RegisterCallback(self->pCall, SCANSTART, ScanInterest,
SCCopyConnection(pCon), SCDeleteConnection);
lID = RegisterCallback(self->pCall, SCANEND, ScanInterest,
SCCopyConnection(pCon),SCDeleteConnection);
lID = RegisterCallback(self->pCall, SCANPOINT, ScanInterest,
SCCopyConnection(pCon), SCDeleteConnection);
SCSendOK(pCon);
return 1;
}
/*-------- interest */
else if(strcmp(argv[1],"dyninterest") == 0)
{
lID = RegisterCallback(self->pCall, SCGetContext(pCon),SCANSTART, ScanDynInterest,
pCon, NULL);
SCRegister(pCon,pSics, self->pCall,lID);
lID = RegisterCallback(self->pCall, SCGetContext(pCon), SCANEND, ScanDynInterest,
pCon, NULL);
SCRegister(pCon,pSics, self->pCall,lID);
lID = RegisterCallback(self->pCall, SCGetContext(pCon),SCANPOINT, ScanDynInterest,
pCon, NULL);
SCRegister(pCon,pSics, self->pCall,lID);
/*
printf("Registering scanDyn callbacks on handle %d\n", pCon->sockHandle);
*/
lID = RegisterCallback(self->pCall, SCANSTART, ScanDynInterest,
SCCopyConnection(pCon), SCDeleteConnection);
lID = RegisterCallback(self->pCall,SCANEND, ScanDynInterest,
SCCopyConnection(pCon), SCDeleteConnection);
lID = RegisterCallback(self->pCall, SCANPOINT, ScanDynInterest,
SCCopyConnection(pCon), SCDeleteConnection);
SCSendOK(pCon);
return 1;
}
/*-------- uuinterest */
else if(strcmp(argv[1],"uuinterest") == 0)
{
lID = RegisterCallback(self->pCall, SCGetContext(pCon),SCANSTART, ScanUUInterest,
pCon, NULL);
SCRegister(pCon,pSics, self->pCall,lID);
lID = RegisterCallback(self->pCall, SCGetContext(pCon),SCANEND, ScanUUInterest,
pCon, NULL);
SCRegister(pCon,pSics, self->pCall,lID);
lID = RegisterCallback(self->pCall, SCGetContext(pCon),SCANPOINT, ScanUUInterest,
pCon, NULL);
SCRegister(pCon,pSics, self->pCall,lID);
/*
printf("Registering scanUU callbacks on handle %d, con = %p\n",
conSave->sockHandle, conSave);
*/
lID = RegisterCallback(self->pCall, SCANSTART, ScanUUInterest,
SCCopyConnection(pCon), SCDeleteConnection);
lID = RegisterCallback(self->pCall, SCANEND, ScanUUInterest,
SCCopyConnection(pCon),SCDeleteConnection);
lID = RegisterCallback(self->pCall, SCANPOINT, ScanUUInterest,
SCCopyConnection(pCon), SCDeleteConnection);
SCSendOK(pCon);
return 1;
}
/* ------- uninterest */
else if(strcmp(argv[1],"uninterest") == 0)
{
RemoveCallback2(self->pCall,pCon);
SCUnregister(pCon,self->pCall);
RemoveCallbackCon(self->pCall,pCon);
SCSendOK(pCon);
return 1;
}
@ -2134,7 +2144,7 @@ static int DumpScan(pScanData self, SConnection *pCon)
iRet = Tcl_GetInt(InterpGetTcl(pSics),argv[2],&lNP);
if(iRet != TCL_OK)
{
sprintf(pBueffel,"ERROR: expected number, got %s",argv[3]);
sprintf(pBueffel,"ERROR: expected number, got %s",argv[2]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
@ -2187,7 +2197,7 @@ static int DumpScan(pScanData self, SConnection *pCon)
iRet = Tcl_GetInt(InterpGetTcl(pSics),argv[2],&lNP);
if(iRet != TCL_OK)
{
sprintf(pBueffel,"ERROR: expected number, got %s",argv[3]);
sprintf(pBueffel,"ERROR: expected number, got %s",argv[2]);
SCWrite(pCon,pBueffel,eError);
return 0;
}

View File

@ -79,12 +79,12 @@
if(pOwner)
{
Interrupt2Text(SCGetInterrupt(pOwner),pBueffel,131);
SCWrite(pCon,pBueffel,eStatus);
SCWrite(pCon,pBueffel,eValue);
}
else
{
Interrupt2Text(SCGetInterrupt(pCon),pBueffel,131);
SCWrite(pCon,pBueffel,eStatus);
SCWrite(pCon,pBueffel,eValue);
}
return 1;
}

View File

@ -33,7 +33,7 @@ typedef struct ScriptContext {
struct SctController {
DevSer *devser;
Hdb *node; /* the controller node */
SCStore *conn;
SConnection*conn;
int verbose;
};
@ -41,13 +41,13 @@ struct SctController {
typedef struct SctData {
char *name;
SctController *controller;
SCStore *conCtx;
SConnection*conCtx;
int answered;
Hdb *node;
} SctData;
static ScriptContext *sct = NULL;
static SCStore *currentCon = NULL;
static SConnection *currentCon = NULL;
static struct {
char *name;
@ -184,6 +184,14 @@ int SctCommand(SConnection *con, SicsInterp *sics, void *object,
return 1;
}
/**
* controller
*/
if(strcmp(argv[1],"controller") == 0){
SCWrite(con,cNode->name, eValue);
return 1;
}
/*
* time stamping
*/
@ -271,9 +279,9 @@ static char *SctActionHandler(void *actionData, char *lastReply) {
char timeKey[50], timeVal[50];
if (currentCon) {
con = SCStorePush(currentCon);
con = currentCon;
} else {
con = SCStorePush(controller->conn);
con = controller->conn;
}
SetProp(node, controller->node, "result", lastReply);
if (controller->verbose && lastReply != NULL && *lastReply != '\0') {
@ -310,26 +318,16 @@ static char *SctActionHandler(void *actionData, char *lastReply) {
send = GetProp(node, controller->node, "send");
if (send != NULL && send[0] != '\0') {
if (controller->verbose) {
SCPrintf(con, eWarning, "send : %s", send);
}
if (currentCon) {
SCStorePop(currentCon);
} else {
SCStorePop(controller->conn);
SCPrintf(con, eLog, "send : %s", send);
}
return send;
}
}
SCPrintf(con, eError, "ERROR: too many quick scripts chained");
SCPrintf(con, eLogError, "ERROR: too many quick scripts chained");
finish:
SetProp(node, controller->node, "state", "idle");
if (currentCon) {
SCStorePop(currentCon);
} else {
SCStorePop(controller->conn);
}
if (data->conCtx != NULL) {
SCStoreFree(data->conCtx);
SCDeleteConnection(data->conCtx);
data->conCtx = NULL;
}
return send;
@ -337,7 +335,7 @@ finish:
static char *SctWriteHandler(void *actionData, char *lastReply) {
SctData *data = actionData;
SCStore *old;
SConnection*old;
char *result;
old = currentCon;
@ -470,14 +468,12 @@ static hdbCallbackReturn SctActionCallback(Hdb *node, void *userData,
}
if (data->conCtx != NULL) {
con2 = SCStorePush(data->conCtx);
GetHdbPath(node, path, sizeof path);
SCPrintf(con2, eValue, "%s target changed to %s before completion",
SCPrintf(data->conCtx, eLog, "%s target changed to %s before completion",
path, GetCharArray(text));
SCStorePop(data->conCtx);
}
DeleteDynString(text);
data->conCtx = SCSave(con, data->conCtx);
data->conCtx = SCCopyConnection(con);
data->answered = 0;
DevQueue(data->controller->devser, data, prio,
SctWriteHandler, SctMatch, NULL);
@ -490,12 +486,12 @@ static hdbCallbackReturn SctActionCallback(Hdb *node, void *userData,
if (currentCon) { /* update called from a write action */
data->answered = 1;
GetHdbPath(node, path, sizeof path);
con = SCStorePush(currentCon);
con = currentCon;
text = formatValue(*(mm->v), node);
SCPrintf(con, eStatus, "%s = %s", path,
/* Markus: who is receiving this message? */
SCPrintf(con, eLog, "%s = %s", path,
GetCharArray(text));
DeleteDynString(text);
SCStorePop(currentCon);
}
return hdbContinue;
}
@ -537,7 +533,7 @@ static void SctKillData(void *d) {
SctData *data = d;
if (data->name) free(data->name);
if (data->conCtx) SCStoreFree(data->conCtx);
if (data->conCtx) SCDeleteConnection(data->conCtx);
free(data);
}
@ -564,7 +560,7 @@ int SctAddPollNode(SctController *controller, Hdb *node, double interval,
assert(data);
data->controller = controller;
data->node = node;
data->conCtx = NULL;
data->conCtx = NULL; /* we might need a dummy connection here */
data->name = strdup(action);
return DevSchedule(controller->devser, data, prio, interval,
@ -755,10 +751,16 @@ void SctQueueNode(SctController *controller, Hdb *node,
data->name = strdup(action);
data->conCtx = NULL;
DevQueue(data->controller->devser, data, prio,
SctWriteHandler, SctMatch, SctKillData);
if(!DevQueue(data->controller->devser, data, prio,
SctWriteHandler, SctMatch, SctKillData)){
if(data->name != NULL){
free(data->name);
}
free(data);
} else {
if (con != NULL) {
data->conCtx = SCSave(con, NULL);
data->conCtx = SCCopyConnection(con);
}
}
return;
}
@ -813,6 +815,9 @@ static void KillSctTransact(void *data){
if(self->command){
free(self->command);
}
if(self->con){
SCDeleteConnection(self->con);
}
free(self);
}
@ -844,7 +849,7 @@ static int SctTransactCmd(pSICSOBJ ccmd, SConnection *con,
SCWrite(con,"ERROR: out of memory in SctTransactCommand", eError);
return 0;
}
st->con = con;
st->con = SCCopyConnection(con);
st->command = strdup(par[0]->value.v.text);
DevQueue(c->devser, st, WritePRIO,
@ -863,6 +868,8 @@ static int SctSendCmd(pSICSOBJ ccmd, SConnection *con,
Hdb *cmdNode, Hdb *par[], int nPar) {
pSctTransact st = NULL;
SctController *c;
char *prioText = NULL;
int prio;
c = (SctController *)ccmd->pPrivate;
@ -871,14 +878,28 @@ static int SctSendCmd(pSICSOBJ ccmd, SConnection *con,
SCWrite(con,"ERROR: out of memory in SctSendCmd", eError);
return 0;
}
st->con = con;
st->con = SCCopyConnection(con);
st->command = strdup(par[0]->value.v.text);
DevQueue(c->devser, st, WritePRIO,
prioText = ParText(cmdNode, "prio", nPar, "write");
prio = DevText2Prio(prioText);
if(prio == NullPRIO){
prio = WritePRIO;
}
DevQueue(c->devser, st, prio,
TransactionHandler, SctTransactMatch, KillSctTransact);
return 1;
}
static int SctDisconnect(pSICSOBJ ccmd, SConnection *con,
Hdb *cmdNode, Hdb *par[], int nPar) {
SctController *c;
c = (SctController *)ccmd->pPrivate;
DevDisconnect(c->devser);
return 1;
}
static hdbCallbackReturn SctDebugCallback(Hdb *node, void *userData,
hdbMessage *msg) {
@ -911,9 +932,7 @@ static void SctKillController(void *c) {
CleanStack(controller->node);
RemoveSICSInternalCallback(controller);
if (controller->conn) {
con = SCLoad(controller->conn);
SCDeleteConnection(con);
SCStoreFree(controller->conn);
SCDeleteConnection(controller->conn);
}
DevKill(controller->devser);
free(controller);
@ -943,7 +962,7 @@ static int SctMakeController(SConnection *con, SicsInterp *sics,
ccmd = MakeSICSOBJv(nodeName, "SctController", HIPNONE, usSpy);
controller->node = ccmd->objectNode;
controller->conn = SCSave(SCCreateDummyConnection(pServ->pSics), NULL);
controller->conn = SCCreateDummyConnection(pServ->pSics);
assert(ccmd);
assert(controller->node->mama == NULL);
@ -992,7 +1011,10 @@ static int SctMakeController(SConnection *con, SicsInterp *sics,
cmd = AddSICSHdbPar(controller->node,
"send", usMugger, MakeSICSFunc(SctSendCmd));
AddSICSHdbPar(cmd, "data", usMugger, MakeHdbText(""));
AddSICSHdbPar(cmd, "prio", usMugger, MakeHdbText(""));
cmd = AddSICSHdbPar(controller->node,
"disconnect", usMugger, MakeSICSFunc(SctDisconnect));
par = AddSICSHdbPar(controller->node, "debug", usUser, MakeHdbInt(-1));

View File

@ -356,28 +356,28 @@ end:
/* print known parameters */
iLen = ObParLength(self->pParams);
sprintf(pBueffel,"Parameter Listing for %s\n",self->name);
SCWrite(pCon,pBueffel,eStatus);
SCWrite(pCon,pBueffel,eValue);
for(i = 0; i < iLen; i++)
{
sprintf(pBueffel,"%s.%s = %f\n",self->name,
self->pParams[i].name,self->pParams[i].fVal);
SCWrite(pCon,pBueffel,eStatus);
SCWrite(pCon,pBueffel,eValue);
}
/* print motornames as well */
sprintf(pBueffel,"%s.ThetaMotor = %s\n",self->name,self->pTheta->name);
SCWrite(pCon,pBueffel,eStatus);
SCWrite(pCon,pBueffel,eValue);
sprintf(pBueffel,"%s.TwoThetaMotor = %s\n",self->name,self->pTwoTheta->name);
SCWrite(pCon,pBueffel,eStatus);
SCWrite(pCon,pBueffel,eValue);
if(self->pBend1)
{
sprintf(pBueffel,"%s.VerticalBenderMotor = %s\n",self->name,self->pBend1->name);
SCWrite(pCon,pBueffel,eStatus);
SCWrite(pCon,pBueffel,eValue);
}
if(self->pBend2)
{
sprintf(pBueffel,"%s.HorizontalBenderMotor = %s\n",self->name,self->pBend2->name);
SCWrite(pCon,pBueffel,eStatus);
SCWrite(pCon,pBueffel,eValue);
}
}
/*-----------------------------------------------------------------------------
@ -790,7 +790,7 @@ end:
{
sprintf(pBueffel,"WARNING: monochromator %s out of sync by %f\n",
self->name,fVal);
SCWrite(pCon,pBueffel,eStatus);
SCWrite(pCon,pBueffel,eWarning);
}
/* calculate wavelength from angles */

View File

@ -480,8 +480,7 @@
return 1;
}
/*------------------------------------------------------------------------*/
static int WaveLengthCallBack(int iEvent, void *pEvent, void *pUser,
commandContext cc)
static int WaveLengthCallBack(int iEvent, void *pEvent, void *pUser)
{
SConnection *pCon = NULL;
pSelVar self = NULL;
@ -493,9 +492,14 @@
assert(pCon);
assert(self);
if(pCon == NULL || !SCisConnected(pCon))
{
return -1;
}
fVal = GetSelValue(self,pCon);
sprintf(pBueffel,"%s.value = %f", self->name, fVal);
SCWriteInContext(pCon,pBueffel,eValue,cc);
SCWrite(pCon,pBueffel,eValue);
return 1;
}
/*--------------------------------------------------------------------------
@ -527,10 +531,9 @@
strtolower(argv[1]);
if(strcmp(argv[1],"interest") == 0)
{
lID = RegisterCallback(self->pCall, SCGetContext(pCon),
lID = RegisterCallback(self->pCall,
WLCHANGE, WaveLengthCallBack,
pCon, NULL);
SCRegister(pCon,pSics, self->pCall,lID);
SCCopyConnection(pCon), SCDeleteConnection);
SCSendOK(pCon);
return 1;
}
@ -570,7 +573,7 @@
{
fWave = GetMonoPosition(self->pSel,pCon);
sprintf(pBueffel,"%s = %f",argv[0],fWave);
SCWrite(pCon,pBueffel,eStatus);
SCWrite(pCon,pBueffel,eValue);
return 1;
}
return 0;
@ -597,10 +600,9 @@
strtolower(argv[1]);
if(strcmp(argv[1],"interest") == 0)
{
lID = RegisterCallback(self->pCall, SCGetContext(pCon),
lID = RegisterCallback(self->pCall,
WLCHANGE, WaveLengthCallBack,
pCon, NULL);
SCRegister(pCon,pSics, self->pCall,lID);
SCSendOK(pCon);
return 1;
}
@ -644,7 +646,7 @@
fWave = 777.77;
}
sprintf(pBueffel,"%s = %f",argv[0],fWave);
SCWrite(pCon,pBueffel,eStatus);
SCWrite(pCon,pBueffel,eValue);
return 1;
}
return 0;

View File

@ -284,8 +284,8 @@
{
if( (pCurrent->iOut == eOut) || (pCurrent->iAllFlag == 1) )
{
NETWrite(pCurrent->pCon->pSock,pText,strlen(pText));
NETWrite(pCurrent->pCon->pSock,"\n",1);
ANETwrite(pCurrent->pCon->sockHandle,pText,strlen(pText));
ANETwrite(pCurrent->pCon->sockHandle,"\n",1);
}
pCurrent = pCurrent->pNext;
}

2505
sgclib.c Normal file

File diff suppressed because it is too large Load Diff

1174
sgfind.c Normal file

File diff suppressed because it is too large Load Diff

280
sghkl.c Normal file
View File

@ -0,0 +1,280 @@
/*
Space Group Info's (c) 1994-96 Ralf W. Grosse-Kunstleve
*/
#include <stdio.h>
#include <stdlib.h>
#include "sginfo.h"
static const char *IErr_Inc_SymMx =
"Internal Error: Inconsistent symmetry matrices";
int IsSysAbsent_hkl(const T_SgInfo *SgInfo,
int h, int k, int l, int *TH_Restriction)
{
int iTrV, nTrV;
const int *TrV;
int iList, mh, mk, ml, hm, km, lm;
int TH, THr, FlagMismatch;
const T_RTMx *lsmx;
mh = -h;
mk = -k;
ml = -l;
/* check list of symmetry operations
take care of lattice type and "centric" flag */
THr = -1;
if (TH_Restriction != NULL) *TH_Restriction = THr;
FlagMismatch = 0;
nTrV = SgInfo->LatticeInfo->nTrVector;
lsmx = SgInfo->ListSeitzMx;
for (iList = 0; iList < SgInfo->nList; iList++, lsmx++)
{
hm = lsmx->s.R[0] * h + lsmx->s.R[3] * k + lsmx->s.R[6] * l;
km = lsmx->s.R[1] * h + lsmx->s.R[4] * k + lsmx->s.R[7] * l;
lm = lsmx->s.R[2] * h + lsmx->s.R[5] * k + lsmx->s.R[8] * l;
TrV = SgInfo->LatticeInfo->TrVector;
for (iTrV = 0; iTrV < nTrV; iTrV++)
{
TH = (lsmx->s.T[0] + *TrV++) * h;
TH += (lsmx->s.T[1] + *TrV++) * k;
TH += (lsmx->s.T[2] + *TrV++) * l;
TH %= STBF; if (TH < 0) TH += STBF;
if (mh == hm && mk == km && ml == lm)
{
if (TH != 0 && SgInfo->Centric == -1)
return -(iList + 1 + iTrV * SgInfo->nList);
if (THr < 0)
THr = TH;
else if (THr != TH)
FlagMismatch = 1; /* must be systematic absent */
/* will check later ... */
}
else if ( h == hm && k == km && l == lm)
{
if (TH != 0)
return (iList + 1 + iTrV * SgInfo->nList);
}
else
break;
}
}
if (THr >= 0 && FlagMismatch) /* ... consistency check */
SetSgError(IErr_Inc_SymMx);
if (TH_Restriction != NULL)
{
if (SgInfo->Centric == -1) *TH_Restriction = 0;
else *TH_Restriction = THr;
}
return 0;
}
int BuildEq_hkl(const T_SgInfo *SgInfo, T_Eq_hkl *Eq_hkl, int h, int k, int l)
{
int iList, hm, km, lm, i;
T_RTMx *lsmx;
T_Eq_hkl BufEq_hkl;
if (Eq_hkl == NULL)
Eq_hkl = &BufEq_hkl;
Eq_hkl->M = 1;
Eq_hkl->N = 1;
Eq_hkl->h[0] = h;
Eq_hkl->k[0] = k;
Eq_hkl->l[0] = l;
Eq_hkl->TH[0] = 0;
if (! (h || k || l))
return Eq_hkl->M; /* this is 000 */
Eq_hkl->M++;
/* check list of symmetry operations */
lsmx = &SgInfo->ListSeitzMx[1]; /* skip first = identity matrix */
for (iList = 1; iList < SgInfo->nList; iList++, lsmx++)
{
hm = lsmx->s.R[0] * h + lsmx->s.R[3] * k + lsmx->s.R[6] * l;
km = lsmx->s.R[1] * h + lsmx->s.R[4] * k + lsmx->s.R[7] * l;
lm = lsmx->s.R[2] * h + lsmx->s.R[5] * k + lsmx->s.R[8] * l;
for (i = 0; i < Eq_hkl->N; i++)
{
if ( ( hm == Eq_hkl->h[i] && km == Eq_hkl->k[i] && lm == Eq_hkl->l[i])
|| (-hm == Eq_hkl->h[i] && -km == Eq_hkl->k[i] && -lm == Eq_hkl->l[i]))
break;
}
if (i == Eq_hkl->N)
{
if (Eq_hkl->N >= 24) {
SetSgError(IErr_Inc_SymMx);
return 0;
}
Eq_hkl->h[i] = hm;
Eq_hkl->k[i] = km;
Eq_hkl->l[i] = lm;
Eq_hkl->TH[i] = ( lsmx->s.T[0] * h
+ lsmx->s.T[1] * k
+ lsmx->s.T[2] * l) % STBF;
if (Eq_hkl->TH[i] < 0)
Eq_hkl->TH[i] += STBF;
Eq_hkl->M += 2;
Eq_hkl->N++;
}
}
if (SgInfo->nList % Eq_hkl->N) /* another error trap */ {
SetSgError(IErr_Inc_SymMx);
return 0;
}
return Eq_hkl->M;
}
int AreSymEquivalent_hkl(const T_SgInfo *SgInfo, int h1, int k1, int l1,
int h2, int k2, int l2)
{
int iList, mh2, mk2, ml2, hm, km, lm;
T_RTMx *lsmx;
mh2 = -h2;
mk2 = -k2;
ml2 = -l2;
/* check list of symmetry operations */
lsmx = SgInfo->ListSeitzMx;
for (iList = 0; iList < SgInfo->nList; iList++, lsmx++)
{
hm = lsmx->s.R[0] * h1 + lsmx->s.R[3] * k1 + lsmx->s.R[6] * l1;
km = lsmx->s.R[1] * h1 + lsmx->s.R[4] * k1 + lsmx->s.R[7] * l1;
lm = lsmx->s.R[2] * h1 + lsmx->s.R[5] * k1 + lsmx->s.R[8] * l1;
if ( h2 == hm && k2 == km && l2 == lm)
return (iList + 1);
else if (mh2 == hm && mk2 == km && ml2 == lm)
return -(iList + 1);
}
return 0;
}
void SetListMin_hkl(const T_SgInfo *SgInfo, int Maxk, int Maxl,
int *Minh, int *Mink, int *Minl)
{
*Minh = 0;
switch(SgInfo->XtalSystem)
{
case XS_Triclinic:
*Mink = -Maxk;
*Minl = -Maxl;
break;
case XS_Monoclinic:
if (SgInfo->UniqueRefAxis == 'z')
{
*Mink = -Maxk;
*Minl = 0;
}
else
{
*Mink = 0;
*Minl = -Maxl;
}
break;
default:
if (SgInfo->XtalSystem == XS_Trigonal && SgInfo->UniqueDirCode == '*')
*Mink = -Maxk;
else
*Mink = 0;
*Minl = 0;
break;
}
}
int IsSuppressed_hkl(const T_SgInfo *SgInfo, int Minh, int Mink, int Minl,
int Maxk, int Maxl,
int h, int k, int l)
{
int iList, mate, hm, km, lm;
T_RTMx *lsmx;
/* check for Friedel mate first */
hm = -h, km = -k, lm = -l;
if ( (Minh <= hm && hm <= h)
&& (Mink <= km && km <= Maxk)
&& (Minl <= lm && lm <= Maxl)){
if (hm < h) return -1;
else /* if (h == 0) */
if (km < k) return -1;
else if (k == 0)
if (lm < l) return -1;
}
lsmx = &SgInfo->ListSeitzMx[1]; /* skip first = identity matrix */
for (iList = 1; iList < SgInfo->nList; iList++, lsmx++)
{
/* check if equivalent hm, km, lm are inside loop range ... */
hm = lsmx->s.R[0] * h + lsmx->s.R[3] * k + lsmx->s.R[6] * l;
km = lsmx->s.R[1] * h + lsmx->s.R[4] * k + lsmx->s.R[7] * l;
lm = lsmx->s.R[2] * h + lsmx->s.R[5] * k + lsmx->s.R[8] * l;
for (mate = 0; mate < 2; mate++)
{
if (mate) hm = -hm, km = -km, lm = -lm; /* ... or friedel mate */
if ( Minh <= hm && hm <= h
&& Mink <= km && km <= Maxk
&& Minl <= lm && lm <= Maxl)
{
/* ... and were processed before */
if (hm < h)
return (mate ? -(iList + 1) : iList + 1);
else /* if (hm == h) */
if (km < k)
return (mate ? -(iList + 1) : iList + 1);
else if (km == k)
if (lm < l)
return (mate ? -(iList + 1) : iList + 1);
}
}
}
return 0;
}

1966
sginfo.c Normal file

File diff suppressed because it is too large Load Diff

1789
sginfo.h Normal file

File diff suppressed because it is too large Load Diff

1790
sgio.c Normal file

File diff suppressed because it is too large Load Diff

445
sgsi.c Normal file
View File

@ -0,0 +1,445 @@
/*
Space Group Info's (c) 1994-96 Ralf W. Grosse-Kunstleve
*/
#include <stdio.h>
#include <stdlib.h>
#ifdef APP_INCLUDE
#include APP_INCLUDE
#endif
#ifndef AppMalloc
#define AppMalloc(ptr, n) (ptr) = malloc((n) * sizeof (*(ptr)))
#endif
#ifndef AppFree
#define AppFree(ptr, n) free(ptr)
#endif
#include "sginfo.h"
/* Non elegant way to get s.i. vectors and moduli:
1. Build field with legal reference points marked (TestField)
2. Go through list of possible s.i. vects and mods:
Verify with TestField
*/
void MarkLegalOrigins(const T_SgInfo *SgInfo, int *TestField)
{
int O[3], V[3], lx, ly, lz, mx, my, mz, i;
int IsFine, iList, iLoopInv, nLoopInv;
int BufMx[9];
const T_RTMx *lsmx;
int nTrV, iTrV;
const int *TrV;
nLoopInv = Sg_nLoopInv(SgInfo);
nTrV = SgInfo->LatticeInfo->nTrVector;
switch (SgInfo->LatticeInfo->Code)
{
default:
case 'P': lx = ly = lz = 12; break;
case 'A': lx = ly = 12; lz = 6; break;
case 'B': ly = lz = 12; lx = 6; break;
case 'C': lz = lx = 12; ly = 6; break;
case 'I': lx = ly = 12; lz = 6; break;
case 'R': lx = ly = 12; lz = 4; break;
case 'S': lz = lx = 12; ly = 4; break;
case 'T': ly = lz = 12; lx = 4; break;
case 'F': lx = 12; ly = lz = 6; break;
}
for (O[0] = 0; O[0] < 12; O[0]++)
for (O[1] = 0; O[1] < 12; O[1]++)
for (O[2] = 0; O[2] < 12; O[2]++)
{
IsFine = 1;
for (iList = 0; IsFine && iList < SgInfo->nList; iList++)
{
lsmx = &SgInfo->ListSeitzMx[iList];
for (iLoopInv = 0; IsFine && iLoopInv < nLoopInv; iLoopInv++)
{
if (iLoopInv == 0)
for (i = 0; i < 9; i++)
{
if (i % 4) BufMx[i] = lsmx->s.R[i];
else BufMx[i] = lsmx->s.R[i] - 1;
}
else
for (i = 0; i < 9; i++)
{
if (i % 4) BufMx[i] = -lsmx->s.R[i];
else BufMx[i] = -lsmx->s.R[i] - 1;
}
RotMx_t_Vector(V, BufMx, O, 12);
TrV = SgInfo->LatticeInfo->TrVector;
for (iTrV = 0; iTrV < nTrV; iTrV++)
{
mx = (V[0] * (STBF / 12) + *TrV++) % STBF;
my = (V[1] * (STBF / 12) + *TrV++) % STBF;
mz = (V[2] * (STBF / 12) + *TrV++) % STBF;
if (mx == 0 && my == 0 && mz == 0)
break;
}
if (iTrV == nTrV) IsFine = 0;
}
}
if (! (O[0] < lx && O[1] < ly && O[2] < lz))
IsFine = -IsFine;
*TestField++ = IsFine;
#if DEBUG_MarkLegalOrigins
if (IsFine == 1) putc(' ', stdout);
else if (IsFine == -1) putc('#', stdout);
if (IsFine != 0)
fprintf(stdout, " %2d %2d %2d\n", O[0], O[1], O[2]);
#endif
}
}
#define IsArbitraryShift(iShift) \
( (iShift) == 1 || (iShift) == 5 \
|| (iShift) == 7 || (iShift) == 11)
int Verify_si(int h, int k, int l, const int *TestField)
{
int O[3], TH;
for (O[0] = 0; O[0] < 12; O[0]++)
for (O[1] = 0; O[1] < 12; O[1]++)
for (O[2] = 0; O[2] < 12; O[2]++)
{
if (*TestField++)
{
TH = h * O[0] + k * O[1] + l * O[2];
TH %= 12;
if (TH) return 0;
if (IsArbitraryShift(O[0])) TH += h;
if (IsArbitraryShift(O[1])) TH += k;
if (IsArbitraryShift(O[2])) TH += l;
if (TH) return 0;
}
}
return 1;
}
int Is_si(const T_SgInfo *SgInfo, int h, int k, int l)
{
int i_si_v, u;
const int *si_v, *si_m;
si_v = SgInfo->si_Vector;
si_m = SgInfo->si_Modulus;
for (i_si_v = 0; i_si_v < SgInfo->n_si_Vector; i_si_v++)
{
u = *si_v++ * h;
u += *si_v++ * k;
u += *si_v++ * l;
if (*si_m) {
if (u % (*si_m)) return 0; }
else {
if (u) return 0; }
si_m++;
}
return 1;
}
int Set_si(T_SgInfo *SgInfo)
{
static const int TabTrial_si[] =
{
0,
1, 0, 2, -1, 4, /* I -4 */
1, 2, -1, 0, 4,
1, -1, 0, 2, 4,
1, 2, 4, 3, 6, /* P 3 2 */
1, 4, 3, 2, 6,
1, 3, 2, 4, 6,
1, 1, 1, 1, 4,
1, 1, 1, 1, 2,
1, 1, 1, 1, 0,
1, 0, 0, 1, 2,
1, 0, 1, 0, 2,
1, 1, 0, 0, 2,
1, 0, 0, 1, 0,
1, 0, 1, 0, 0,
1, 1, 0, 0, 0,
2, 1, -1, 0, 3,
0, 0, 1, 0,
2, -1, 0, 1, 3,
0, 1, 0, 0,
2, 0, 1, -1, 3,
1, 0, 0, 0,
2, 0, 1, 1, 4, /* F 2x */
1, 0, 0, 0,
2, 1, 0, 1, 4, /* F 2y */
0, 1, 0, 0,
2, 1, 1, 0, 4, /* F 2z */
0, 0, 1, 0,
2, 1, 0, 0, 2,
0, 0, 1, 2,
2, 0, 1, 0, 2,
0, 0, 1, 2,
2, 1, 0, 0, 2,
0, 1, 0, 2,
2, 1, 1, 0, 2,
0, 0, 1, 2,
2, 1, 0, 1, 2,
0, 1, 0, 2,
2, 0, 1, 1, 2,
1, 0, 0, 2,
2, 1, 0, 0, 2,
0, 0, 1, 0,
2, 0, 1, 0, 2,
0, 0, 1, 0,
2, 1, 0, 0, 2,
0, 1, 0, 0,
2, 1, 0, 0, 0,
0, 0, 1, 2,
2, 0, 1, 0, 0,
0, 0, 1, 2,
2, 1, 0, 0, 0,
0, 1, 0, 2,
2, 1, 1, 0, 2,
0, 0, 1, 0,
2, 1, 0, 1, 2,
0, 1, 0, 0,
2, 0, 1, 1, 2,
1, 0, 0, 0,
2, 1, 0, 0, 0,
0, 0, 1, 0,
2, 0, 1, 0, 0,
0, 0, 1, 0,
2, 1, 0, 0, 0,
0, 1, 0, 0,
3, 1, 0, 0, 2,
0, 1, 0, 2,
0, 0, 1, 2,
3, 1, 0, 0, 0,
0, 1, 0, 2,
0, 0, 1, 2,
3, 1, 0, 0, 2,
0, 1, 0, 0,
0, 0, 1, 2,
3, 1, 0, 0, 2,
0, 1, 0, 2,
0, 0, 1, 0,
3, 1, 0, 0, 2,
0, 1, 0, 0,
0, 0, 1, 0,
3, 1, 0, 0, 0,
0, 1, 0, 2,
0, 0, 1, 0,
3, 1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 2,
3, 1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
3, -1, 0, 0, 2, /* -A 1 */
0, -1, 1, 4,
0, 1, 1, 4,
3, -1, 0, 1, 4, /* -B 1 */
0, -1, 0, 2,
1, 0, 1, 4,
3, 1, 1, 0, 4, /* -C 1 */
1, -1, 0, 4,
0, 0, -1, 2,
3, -1, 1, 1, 4, /* -I 1 */
1, -1, 1, 4,
1, 1, -1, 4,
3, 0, 1, 1, 4, /* -F 1 */
1, 0, 1, 4,
1, 1, 0, 4,
3, -1, 0, 0, 0, /* A 2x */
0, -1, 1, 4,
0, 1, 1, 4,
3, -1, 0, 1, 4, /* B 2y */
0, -1, 0, 0,
1, 0, 1, 4,
3, 1, 1, 0, 4, /* C 2z */
1, -1, 0, 4,
0, 0, -1, 0,
-1
};
int h, k, l, iList;
int Maxh, Maxk, Maxl;
int Minh, Mink, Minl;
int nTestField, *TestField;
int nProperty, *Property, *pp;
int IsFine, would_be, is;
int i_si, *si_v;
const int *trial_si;
SgInfo->n_si_Vector = -1;
nTestField = 12 * 12 * 12;
AppMalloc(TestField, nTestField);
if (TestField == NULL) {
SetSgError("Not enough core");
return -1;
}
MarkLegalOrigins(SgInfo, TestField);
Maxh = Maxk = Maxl = 7;
SetListMin_hkl(SgInfo, Maxk, Maxl, &Minh, &Mink, &Minl);
nProperty = (Maxh - Minh + 1)
* (Maxk - Mink + 1)
* (Maxl - Minl + 1);
AppMalloc(Property, nProperty);
if (Property == NULL) {
SetSgError("Not enough core");
AppFree(TestField, nTestField);
return -1;
}
pp = Property;
for (h = Minh; h <= Maxh; h++)
for (k = Mink; k <= Maxk; k++)
for (l = Minl; l <= Maxl; l++)
{
iList = IsSysAbsent_hkl(SgInfo, h, k, l, NULL);
if (SgError != NULL)
{
AppFree(Property, nProperty);
AppFree(TestField, nTestField);
return -1;
}
if (iList == 0)
*pp++ = Verify_si(h, k, l, TestField);
else
*pp++ = -1;
}
trial_si = TabTrial_si;
while (*trial_si >= 0)
{
SgInfo->n_si_Vector = *trial_si++;
si_v = SgInfo->si_Vector;
for (i_si = 0; i_si < SgInfo->n_si_Vector; i_si++)
{
*si_v++ = *trial_si++;
*si_v++ = *trial_si++;
*si_v++ = *trial_si++;
SgInfo->si_Modulus[i_si] = *trial_si++;
}
IsFine = 1;
pp = Property;
for (h = Minh; IsFine && h <= Maxh; h++)
for (k = Mink; IsFine && k <= Maxk; k++)
for (l = Minl; IsFine && l <= Maxl; l++)
{
is = *pp++;
if (is >= 0)
{
would_be = Is_si(SgInfo, h, k, l);
if (is != would_be)
IsFine = 0;
}
}
if (IsFine)
{
AppFree(Property, nProperty);
AppFree(TestField, nTestField);
return 0;
}
}
SgInfo->n_si_Vector = -1;
SetSgError("Internal Error: Can't determine s.i. vectors and moduli");
AppFree(Property, nProperty);
AppFree(TestField, nTestField);
return -1;
}
void Set_uvw(const T_SgInfo *SgInfo, int h, int k, int l, int *uvw)
{
int i_si_v, u;
const int *si_v, *si_m;
si_v = SgInfo->si_Vector;
si_m = SgInfo->si_Modulus;
for (i_si_v = 0; i_si_v < SgInfo->n_si_Vector; i_si_v++)
{
u = *si_v++ * h;
u += *si_v++ * k;
u += *si_v++ * l;
if (*si_m) u %= (*si_m);
si_m++;
uvw[i_si_v] = u;
}
}

View File

@ -78,7 +78,7 @@
StatisticsEnd(old);
MacroPop();
if (iRet != TCL_OK) {
SCPrintf(self->pCon, eStatus,
SCPrintf(self->pCon, eLogError,
"ERROR in sicscron script: %s", pTcl->result);
self->iEnd = 0;
return 0;
@ -114,12 +114,12 @@
if (self->iEnd == 2 && data->dolater) {
tm = *localtime(&self->tNext);
strftime(datim, sizeof datim, "%Y-%m-%d %T", &tm);
SCPrintf(data->pCon, eStatus, "%s %s", datim,
SCPrintf(data->pCon, eLog, "%s %s", datim,
self->pCommand);
} else if (self->iEnd == 1 && !data->dolater) {
tm = *localtime(&self->tNext);
strftime(datim, sizeof datim, "%Y-%m-%d %T", &tm);
SCPrintf(data->pCon, eStatus, "%s %8d %s", datim,
SCPrintf(data->pCon, eLog, "%s %8d %s", datim,
self->iInterval, self->pCommand);
}
}

View File

@ -53,8 +53,7 @@ static void AddPrivProperty(pHdb node, int priv){
SetHdbProperty(node,PRIVNAM,pPriv);
}
/*=================== motor code =======================================*/
static int MoveCallback(int iEvent, void *eventData, void *userData,
commandContext cc){
static int MoveCallback(int iEvent, void *eventData, void *userData){
MotCallback *motData = (MotCallback *)eventData;
pHdb motor = (pHdb)userData;
pHdb pos = NULL;
@ -71,8 +70,7 @@ static int MoveCallback(int iEvent, void *eventData, void *userData,
return 1;
}
/*---------------------------------------------------------------------*/
static int MotorValueCallback(int iEvent, void *eventData, void *userData,
commandContext cc){
static int MotorValueCallback(int iEvent, void *eventData, void *userData){
pHdb motor = (pHdb)userData;
pMotor pMot = (pMotor)eventData;
pHdb current = NULL;
@ -280,9 +278,9 @@ static pHdb CreateMotorAdapter(char *name, pMotor pMot){
*/
strncpy(comCom.deviceID,name,255);
comCom.transID = -77;
RegisterCallback(pMot->pCall,comCom, MOTDRIVE, MoveCallback,
RegisterCallback(pMot->pCall,MOTDRIVE, MoveCallback,
result,NULL);
RegisterCallback(pMot->pCall,comCom, HDBVAL, MotorValueCallback,
RegisterCallback(pMot->pCall,HDBVAL, MotorValueCallback,
result,NULL);
if(!AddStdMotorPar(result,pMot)){
@ -396,8 +394,7 @@ static hdbCallbackReturn SicsVarSetCallback(pHdb currentNode, void *userData,
return hdbContinue;
}
/*----------------------------------------------------------------------*/
static int ValueCallback(int iEvent, void *eventData, void *userData,
commandContext cc){
static int ValueCallback(int iEvent, void *eventData, void *userData){
pSicsVariable pVar = (pSicsVariable)eventData;
pHdb node = (pHdb)userData;
hdbValue v;
@ -451,10 +448,8 @@ static pHdb MakeSicsVarNode(pSicsVariable pVar, char *name){
if(pCall == NULL){
return NULL;
}
strncpy(comCom.deviceID,name,255);
comCom.transID = -77;
AppendHipadabaCallback(node,pCall);
RegisterCallback(pVar->pCall,comCom, VALUECHANGE, ValueCallback,
RegisterCallback(pVar->pCall,VALUECHANGE, ValueCallback,
node,NULL);
snprintf(command,1023,"%s ", pVar->name);
SetHdbProperty(node,"sicscommand",command);
@ -503,8 +498,7 @@ static void updateCountList(){
SCDeleteConnection(pDummy);
}
/*---------------------------------------------------------------------------*/
static int CounterCallback(int iEvent, void *eventData, void *userData,
commandContext cc){
static int CounterCallback(int iEvent, void *eventData, void *userData){
if(iEvent == MONITOR || iEvent == COUNTEND){
updateCountList();
}
@ -714,13 +708,13 @@ int SICSHdbAdapter(SConnection *pCon, SicsInterp *pSics, void *pData,
hugo.node = path;
if(countList < 0){
countList = LLDcreate(sizeof(CountEntry));
RegisterCallback(pCount->pCall, SCGetContext(pCon),
RegisterCallback(pCount->pCall,
COUNTSTART, CounterCallback,
NULL, NULL);
RegisterCallback(pCount->pCall, SCGetContext(pCon),
RegisterCallback(pCount->pCall,
COUNTEND, CounterCallback,
NULL, NULL);
RegisterCallback(pCount->pCall, SCGetContext(pCon),
RegisterCallback(pCount->pCall,
MONITOR, CounterCallback,
NULL, NULL);
}

View File

@ -175,6 +175,7 @@ static int MakeLinkNode(pHdb parent, char *name, SConnection *pCon,
assert(pInter);
/* print command to log files */
/*
for( i = 0; i < self->iFiles; i++)
{
if(self->pFiles[i])
@ -182,6 +183,7 @@ static int MakeLinkNode(pHdb parent, char *name, SConnection *pCon,
fprintf(self->pFiles[i],"SICS>> %s\n",pCommand);
}
}
*/
/* print to command log if user or manager */
if(SCGetRights(self) <= usUser)
@ -218,7 +220,7 @@ static hdbCallbackReturn CommandSetCallback(pHdb node, void *userData,
if((mm = GetHdbSetMessage(message)) == NULL){
return hdbContinue;
}
pCon = (SConnection *)pCon;
pCon = (SConnection *)mm->callData;
v = *(mm->v);
if(pCon == NULL){
@ -245,7 +247,9 @@ static hdbCallbackReturn CommandSetCallback(pHdb node, void *userData,
}
current = current->next;
}
SendHdbStatusMessage(node,"start");
status = HDBInvoke(pCon,pServ->pSics, GetCharArray(cmd));
SendHdbStatusMessage(node,"stop");
DeleteDynString(cmd);
if(status == 1){
return hdbContinue;

View File

@ -17,6 +17,8 @@
* interpreter interface.
*
* Refactored to new callback system, Markus Zolliker, Mark Koennecke, March 2008
*
* Added start and finished messages to commands. Mark Koennecke, November 2008
*/
#include <stdlib.h>
#include <string.h>
@ -47,6 +49,8 @@ char *trim(char *str);
static char killID[] = {"killID"};
static char killInternalID[] = {"killInternalID"};
static char killPtr[] = {"killPtr"};
static char startID[] = {"start"};
static char stopID[] = {"stop"};
/*----------------------------------------------------------------------------------*/
pHdbIDMessage GetKillIDMessage(pHdbMessage message){
if(message->type == killID){
@ -68,7 +72,38 @@ pHdbPtrMessage GetKillPtrMessage(pHdbMessage message){
}
return NULL;
}
/*-----------------------------------------------------------------------------------*/
pHdbMessage GetHdbStartMessage(pHdbMessage message){
if(message->type == startID){
return (pHdbMessage)message;
}
return NULL;
}
/*-----------------------------------------------------------------------------------*/
pHdbMessage GetHdbStopMessage(pHdbMessage message){
if(message->type == stopID){
return (pHdbMessage)message;
}
return NULL;
}
/*-----------------------------------------------------------------------------------*/
void SendHdbStatusMessage(pHdb node, char *status){
pHdbMessage pRes = NULL;
pRes = malloc(sizeof(hdbMessage));
if(pRes == NULL){
return;
}
if(strcmp(status,"start") == 0){
pRes->type = startID;
} else if(strcmp(status,"stop") == 0){
pRes->type = stopID;
} else {
/* someone is trying to create an non existent message */
assert(0);
}
InvokeCallbackChain(node,pRes);
free(pRes);
}
/*=============== common callback functions used for SICS ===========================*/
static hdbCallbackReturn SICSCheckPermissionCallback(pHdb node, void *userData,
pHdbMessage message){
@ -274,8 +309,10 @@ static hdbCallbackReturn SICSFuncCallback(pHdb node, void *userData,
}
func = (SICSOBJFunc)node->value.v.func;
if(func != NULL){
SendHdbStatusMessage(node, "start");
status = func((pSICSOBJ)userData,(SConnection *)mm->callData,
node, par,nPar);
SendHdbStatusMessage(node, "stop");
} else {
printf("Great Badness in calling SICSFuncCallback\n");
return hdbAbort;
@ -297,7 +334,6 @@ pHdbCallback MakeSICSReadDriveCallback(void *sicsObject){
/*---------------------------------------------------------------------------------------*/
typedef struct {
SConnection *pCon;
commandContext context;
int ID;
int internalID;
}HdbCBInfo;
@ -438,6 +474,7 @@ static hdbCallbackReturn SICSNotifyCallback(pHdb node, void *userData,
pHdbIDMessage idm = NULL;
pHdbPtrMessage cmm = NULL;
pHdbDataMessage mm = NULL;
SConnection *tstCon;
cbInfo = (HdbCBInfo *)userData;
@ -459,15 +496,41 @@ static hdbCallbackReturn SICSNotifyCallback(pHdb node, void *userData,
}
}
if((cmm = GetKillPtrMessage(message)) != NULL){
if(cmm->pPtr == cbInfo->pCon){
tstCon = cmm->pPtr;
if(tstCon != NULL && tstCon->ident == cbInfo->pCon->ident){
return hdbKill;
} else {
return hdbContinue;
}
}
/**
* handle start and stop messages
*/
if(GetHdbStartMessage(message) != NULL){
pPath = GetHipadabaPath(node);
result = CreateDynString(128,128);
DynStringConcat(result, pPath);
DynStringConcat(result," STARTED");
SCWrite(cbInfo->pCon, GetCharArray(result), eEvent);
DeleteDynString(result);
free(pPath);
return hdbContinue;
}
if(GetHdbStopMessage(message) != NULL){
pPath = GetHipadabaPath(node);
result = CreateDynString(128,128);
DynStringConcat(result, pPath);
DynStringConcat(result," FINISHED");
SCWrite(cbInfo->pCon, GetCharArray(result), eEvent);
DeleteDynString(result);
free(pPath);
return hdbContinue;
}
/*
* react only on update messages
* Deal with update messages
*/
if((mm = GetHdbUpdateMessage(message)) == NULL){
return hdbContinue;
@ -481,20 +544,12 @@ static hdbCallbackReturn SICSNotifyCallback(pHdb node, void *userData,
outCode = eEvent;
/*
* we want our notifications to come even when called from a macro
*/
macro = SCinMacro(cbInfo->pCon);
SCsetMacro(cbInfo->pCon,0);
/**
* if transfer = zip always transfer data in zipped form
*/
if(GetHdbProperty(node,"transfer",value,80) == 1){
if(strstr(value,"zip") != NULL){
SCPushContext2(cbInfo->pCon,cbInfo->context);
status = sendZippedNodeData(node, cbInfo->pCon);
SCPopContext(cbInfo->pCon);
SCsetMacro(cbInfo->pCon,macro);
free(pPath);
DeleteDynString(result);
return hdbContinue;
@ -503,9 +558,8 @@ static hdbCallbackReturn SICSNotifyCallback(pHdb node, void *userData,
if(mm->v->arrayLength < 100){
printedData = formatValue(*(mm->v), node);
if(pPath == NULL || printedData == NULL || result == NULL){
SCWriteInContext(cbInfo->pCon,"ERROR: out of memory formatting data" ,
eEvent,cbInfo->context);
SCsetMacro(cbInfo->pCon,macro);
SCWrite(cbInfo->pCon,"ERROR: out of memory formatting data" ,
eEvent);
/*
* no need to interrupt something because writing data to a client does
* not work
@ -514,21 +568,31 @@ static hdbCallbackReturn SICSNotifyCallback(pHdb node, void *userData,
}
formatNameValue(protocol, pPath, GetCharArray(printedData), result,
mm->v->dataType);
SCWriteInContext(cbInfo->pCon,GetCharArray(result),
outCode,cbInfo->context);
SCWrite(cbInfo->pCon,GetCharArray(result),
outCode);
DeleteDynString(printedData);
} else {
formatNameValue(protocol, pPath,"!!datachange!!", result, HIPTEXT);
SCWriteInContext(cbInfo->pCon,GetCharArray(result),
outCode,cbInfo->context);
SCWrite(cbInfo->pCon,GetCharArray(result),
outCode);
}
SCsetMacro(cbInfo->pCon,macro);
free(pPath);
DeleteDynString(result);
return hdbContinue;
}
/*-----------------------------------------------------------------------------------------*/
static void cbKill(void *pData){
HdbCBInfo *cbInfo = (HdbCBInfo *)pData;
if(cbInfo == NULL){
return;
}
if(cbInfo->pCon != NULL){
SCDeleteConnection(cbInfo->pCon);
}
free(cbInfo);
}
/*-----------------------------------------------------------------------------------------*/
pHdbCallback MakeNotifyCallback(SConnection *pCon, int id){
HdbCBInfo *cbInfo = NULL;
@ -536,11 +600,14 @@ pHdbCallback MakeNotifyCallback(SConnection *pCon, int id){
if(cbInfo == NULL){
return NULL;
}
cbInfo->pCon = pCon;
cbInfo->context = SCGetContext(pCon);
cbInfo->pCon = SCCopyConnection(pCon);
if(cbInfo->pCon == NULL){
return NULL;
}
SCsetMacro(cbInfo->pCon,0);
cbInfo->ID = id;
cbInfo->internalID = -1;
return MakeHipadabaCallback(SICSNotifyCallback, cbInfo,free);
return MakeHipadabaCallback(SICSNotifyCallback, cbInfo,cbKill);
}
/*-------------------------------------------------------------------------*/
static hdbCallbackReturn TreeChangeCallback(pHdb node, void *userData,
@ -553,6 +620,7 @@ static hdbCallbackReturn TreeChangeCallback(pHdb node, void *userData,
pHdbIDMessage idm = NULL;
pHdbPtrMessage cmm = NULL;
pHdbTreeChangeMessage tm = NULL;
SConnection *tstCon = NULL;
HdbCBInfo *cbInfo = (HdbCBInfo *)userData;
@ -574,7 +642,8 @@ static hdbCallbackReturn TreeChangeCallback(pHdb node, void *userData,
}
}
if((cmm = GetKillPtrMessage(message)) != NULL){
if(cmm->pPtr == cbInfo->pCon){
tstCon = cmm->pPtr;
if(tstCon != NULL && tstCon->ident == cbInfo->pCon->ident){
return hdbKill;
} else {
return hdbContinue;
@ -588,7 +657,7 @@ static hdbCallbackReturn TreeChangeCallback(pHdb node, void *userData,
if(cbInfo != NULL && cbInfo->pCon != NULL){
result = CreateDynString(128,128);
if(result == NULL){
SCWriteInContext(cbInfo->pCon,"ERROR: out of memory in TreeChangeCallback",outCode,cbInfo->context);
SCWrite(cbInfo->pCon,"ERROR: out of memory in TreeChangeCallback",outCode);
return hdbAbort;
}
path = GetHipadabaPath(node);
@ -597,7 +666,7 @@ static hdbCallbackReturn TreeChangeCallback(pHdb node, void *userData,
else
outCode = eEvent;
formatNameValue(protocol, "treechange", path, result, node->value.dataType);
SCWriteInContext(cbInfo->pCon,GetCharArray(result),outCode,cbInfo->context);
SCWrite(cbInfo->pCon,GetCharArray(result),outCode);
DeleteDynString(result);
free(path);
}
@ -611,10 +680,12 @@ pHdbCallback MakeTreeChangeCallback(SConnection *pCon, int id){
if(cbInfo == NULL){
return NULL;
}
cbInfo->pCon = pCon;
cbInfo->context = SCGetContext(pCon);
cbInfo->pCon = SCCopyConnection(pCon);
if(cbInfo->pCon == NULL){
return NULL;
}
cbInfo->ID = id;
return MakeHipadabaCallback(TreeChangeCallback, cbInfo,free);
return MakeHipadabaCallback(TreeChangeCallback, cbInfo,cbKill);
}
/*----------------------------------------------------------------------------------------*/
static hdbCallbackReturn SICSScriptWriteCallback(pHdb node, void *userData,
@ -1741,6 +1812,12 @@ pDynString formatValue(hdbValue v, pHdb node){
DynStringConcat(result,number);
}
break;
case HIPFUNC:
DynStringConcat(result,"FUNCTION");
break;
case HIPOBJ:
DynStringConcat(result,"OBJECT");
break;
}
return result;
}
@ -2281,7 +2358,7 @@ static int GetHdbNode(SConnection *pCon, SicsInterp *pSics, void *pData,
if ((protocol = isJSON(pCon)) == 1)
outCode = eHdbEvent;
else
outCode = eEvent;
outCode = eValue;
result = CreateDynString(128,128);
formatNameValue(protocol, oriPath, GetCharArray(parData), result, newValue.dataType);
@ -2322,7 +2399,7 @@ static int GetHdbVal(SConnection *pCon, SicsInterp *pSics, void *pData,
if ((protocol = isJSON(pCon)) == 1)
outCode = eHdbEvent;
else
outCode = eEvent;
outCode = eValue;
SCWrite(pCon,GetCharArray(parData), outCode);
DeleteDynString(parData);
ReleaseHdbValue(&newValue);
@ -2610,7 +2687,7 @@ static int ListHdbNode(SConnection *pCon, SicsInterp *pSics, void *pData,
outCode = eHdbEvent;
} else {
listData = formatPlainList(node);
outCode = eEvent;
outCode = eValue;
}
}
if(listData == NULL){
@ -2801,6 +2878,7 @@ static int ChainHdbNode(SConnection *pCon, SicsInterp *pSics, void *pData,
assert(pInter);
/* print command to log files */
/*
for( i = 0; i < self->iFiles; i++)
{
if(self->pFiles[i])
@ -2808,6 +2886,7 @@ static int ChainHdbNode(SConnection *pCon, SicsInterp *pSics, void *pData,
fprintf(self->pFiles[i],"SICS>> %s\n",pCommand);
}
}
*/
/* print to command log if user or manager */
if(SCGetRights(self) <= usUser)
@ -2841,10 +2920,14 @@ static hdbCallbackReturn CommandSetCallback(pHdb node, void *userData,
pHdbDataMessage mm = NULL;
hdbValue v;
/**
* TODO: this is a duplicate: resolve. It is still here because the old
* Hipadaba configuration commands still work
*/
if((mm = GetHdbSetMessage(message)) == NULL){
return hdbContinue;
}
pCon = (SConnection *)pCon;
pCon = (SConnection *)mm->callData;
v = *(mm->v);
if(pCon == NULL){
@ -2871,7 +2954,9 @@ static hdbCallbackReturn CommandSetCallback(pHdb node, void *userData,
}
current = current->next;
}
SendHdbStatusMessage(node,"start");
status = HDBInvoke(pCon,pServ->pSics, GetCharArray(cmd));
SendHdbStatusMessage(node,"stop");
DeleteDynString(cmd);
if(status == 1){
return hdbContinue;

View File

@ -34,6 +34,9 @@ typedef struct {
}hdbPtrMessage, *pHdbPtrMessage;
/*-----------------------------------------------------------------------------*/
pHdbPtrMessage GetKillPtrMessage(pHdbMessage message);
pHdbMessage GetHdbStartMessage(pHdbMessage message);
pHdbMessage GetHdbStopMessage(pHdbMessage message);
void SendHdbStatusMessage(pHdb node, char *status);
/*======================== data structure for automatic parameter update =======*/
typedef struct {
SConnection *pCon;
@ -299,7 +302,7 @@ int SICSHdbGetPar(void *obj, SConnection *pCon, char *path, hdbValue *v);
int SICSHdbUpdatePar(void *obj, SConnection *pCon, char *path, hdbValue v);
/**
* SICSHdbSetPar sets the value of a parameter.
* @param obj The object for which to get a parameter.
* @param obj The object for which to set a parameter.
* @param pCon The optional connection object to use for reporting errors.
* @param path The path to the parameter.
* @param v the value

102
sicsobj.c
View File

@ -5,6 +5,7 @@
*
* Mark Koennecke, July 2007
*/
#include <stdio.h>
#include <sics.h>
#include <tcl.h>
#include "assert.h"
@ -21,6 +22,50 @@ extern int decodeSICSPriv(char *txt); /* from access.c */
void DefaultKill(void *data){
return;
}
/*--------------------------------------------------------------------------*/
void DefaultFree(void *data){
if(data != NULL){
free(data);
}
}
/*---------------------------------------------------------------------------*/
static void saveSICSNode(pHdb node, char *prefix, FILE *fd){
char newprefix[1024], val[20];
pHdb child;
hdbValue v;
pDynString data = NULL;
if(GetHdbProperty(node,"__save",val,20) == 1){
GetHipadabaPar(node,&v,NULL);
data = formatValue(v,node);
if(data != NULL){
fprintf(fd,"%s %s\n", prefix, GetCharArray(data));
DeleteDynString(data);
}
child = node->child;
while(child != NULL){
snprintf(newprefix,1024,"%s/%s", prefix,child->name);
saveSICSNode(child,newprefix,fd);
child = child->next;
}
}
}
/*---------------------------------------------------------------------------*/
int SaveSICSOBJ(void *data, char *name, FILE *fd){
pSICSOBJ self = (pSICSOBJ)data;
char prefix[1024];
pHdb node;
if(self != NULL && self->objectNode != NULL){
node = self->objectNode->child;
while(node != NULL){
snprintf(prefix, 1024,"%s %s", name, node->name);
saveSICSNode(node, prefix, fd);
node = node->next;
}
}
return 1;
}
/*---------------------------------------------------------------------------*/
pSICSOBJ MakeSICSOBJv(char *name, char *class, int type, int priv){
pSICSOBJ pNew = NULL;
@ -32,6 +77,7 @@ pSICSOBJ MakeSICSOBJv(char *name, char *class, int type, int priv){
}
memset(pNew,0,sizeof(SICSOBJ));
pNew->pDes = CreateDescriptor(class);
pNew->pDes->SaveStatus = SaveSICSOBJ;
if (type == HIPNONE) {
pNew->objectNode = MakeHipadabaNode(name, HIPNONE, 1);
} else {
@ -87,6 +133,20 @@ static int invokeOBJFunction(pSICSOBJ object, pHdb commandNode, SConnection *pCo
pHdb currentPar = NULL;
SICSOBJFunc pFunc = NULL;
pHdb parArray[64];
char buffer[1024];
/*
* If the first argument has the special name args, concatenate all arguments
* and put the result as text into this parameter. This allows for the
* object function to parse and interpret the arguments itself.
*/
if(commandNode->child != NULL && strcmp(commandNode->child->name,"args") == 0) {
Arg2Text(argc,argv,buffer,1024);
assignPar(commandNode->child,pCon,buffer);
parArray[0] = commandNode->child;
count = 1;
goto invoke;
}
/*
* assign parameters and fill parameter array for function at the same
@ -106,12 +166,14 @@ static int invokeOBJFunction(pSICSOBJ object, pHdb commandNode, SConnection *pCo
count++;
}
pFunc = (SICSOBJFunc)commandNode->value.v.func;
invoke: pFunc = (SICSOBJFunc)commandNode->value.v.func;
if(pFunc == NULL){
SCWrite(pCon,"ERROR: internal error, function not found",eError);
return 0;
}
SendHdbStatusMessage(commandNode,"start");
status = pFunc(object, pCon, commandNode, parArray,count);
SendHdbStatusMessage(commandNode,"stop");
return status;
}
/*---------------------------------------------------------------------------*/
@ -219,6 +281,42 @@ static int isNodePrintable(pHdb node){
}
}
/*---------------------------------------------------------------------------*/
static void objFormatNode(pHdb node, pDynString data){
char par[40];
pDynString val = NULL;
snprintf(par,40,"%-20s = ",node->name);
DynStringConcat(data,par);
val = formatValue(node->value,node);
if(val != NULL){
DynStringConcat(data,GetCharArray(val));
DynStringConcatChar(data,'\n');
DeleteDynString(val);
}
}
/*---------------------------------------------------------------------------*/
static int ListObj(pSICSOBJ self, SConnection *pCon, int argc, char *argv[]){
pHdb node = NULL;
pDynString data;
data = CreateDynString(128,128);
if(data == NULL){
return 0;
}
node = self->pDes->parNode;
if(node != NULL){
objFormatNode(node,data);
node = node->child;
while(node != NULL){
objFormatNode(node,data);
node = node->next;
}
}
SCWrite(pCon,GetCharArray(data),eValue);
DeleteDynString(data);
return 1;
}
/*---------------------------------------------------------------------------*/
int InvokeSICSOBJ(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]){
pSICSOBJ self = NULL;
@ -263,6 +361,8 @@ int InvokeSICSOBJ(SConnection *pCon, SicsInterp *pSics, void *pData,
if(status == -1){
if(strcmp(argv[1],"makescriptfunc") == 0) {
return MakeScriptFunc(self,pCon,argc,argv);
} else if(strcmp(argv[1],"list") == 0){
return ListObj(self,pCon,argc,argv);
}
SCPrintf(pCon, eError, "ERROR: %s %s not found", argv[0], argv[1]);
}

View File

@ -29,7 +29,9 @@ pSICSOBJ MakeSICSOBJ(char *name, char *class);
pSICSOBJ MakeSICSOBJv(char *name, char *class, int type, int priv);
void KillSICSOBJ(void *data);
void DefaultKill(void *data);
void DefaultFree(void *data);
int SaveSICSOBJ(void *data, char *name, FILE *fd);
/**
* This creates a new SICS object and installs it in the interpreter. It returns

View File

@ -345,8 +345,7 @@
}
}
/*--------------------------------------------------------------------*/
static int VarInterestCallback(int iEvent, void *pEvent, void *pUser,
commandContext cc)
static int VarInterestCallback(int iEvent, void *pEvent, void *pUser)
{
SConnection *pCon;
char pBueffel[512];
@ -360,7 +359,13 @@
pVar = (pSicsVariable)pEvent;
pCon = (SConnection *)pUser;
SCPushContext2(pCon,cc);
/* check kill conditions */
if(pCon == NULL || !SCisConnected(pCon))
{
return -1;
}
switch(pVar->eType)
{
case veInt:
@ -386,7 +391,6 @@
status = 1;
break;
}
SCPopContext(pCon);
return status;
}
/*----------------------------------------------------------------------*/
@ -536,17 +540,16 @@ static int VarSetFromText(pSicsVariable self, SConnection *pCon, char *text)
}
else if(strcmp(pCurrent->text,"interest") == 0) /* interest */
{
lID = RegisterCallback(pVar->pCall, SCGetContext(pCon),
lID = RegisterCallback(pVar->pCall,
VALUECHANGE, VarInterestCallback,
pCon, NULL);
SCRegister(pCon,pInterp, pVar->pCall,lID);
SCCopyConnection(pCon), SCDeleteConnection);
DeleteTokenList(pList);
SCSendOK(pCon);
return 1;
}
else if(strcmp(pCurrent->text,"uninterest") == 0)
{
RemoveCallback2(pVar->pCall,pCon);
RemoveCallbackCon(pVar->pCall,pCon);
DeleteTokenList(pList);
SCSendOK(pCon);
return 1;

View File

@ -20,8 +20,8 @@
#define RANDOMWARNING -7003
#define STOPPED -7004
#define FAILRATE 0.05
#define WARNRATE 0.1
#define FAILRATE 0.00005
#define WARNRATE 0.00001
/*-----------------------------------------------------------------------*/
typedef struct {
time_t tTarget;

Some files were not shown because too many files have changed in this diff Show More