677 lines
20 KiB
C
677 lines
20 KiB
C
/*------------------------------------------------------------------------
|
|
File: anstoSite.c
|
|
|
|
This is the site specific interface to SICS for ANSTO. This file implements
|
|
the interface defined in ../site.h
|
|
|
|
Copyright: see file Copyright.txt
|
|
|
|
Template: Mark Koennecke, June 2003
|
|
Nick Hauser, Paul Hathaway, May 2004
|
|
$Name: not supported by cvs2svn $
|
|
$Revision: 1.23.2.5 $
|
|
-----------------------------------------------------------------------*/
|
|
#include "made_config.h"
|
|
#include <stdlib.h>
|
|
#include <assert.h>
|
|
#include <glob.h>
|
|
#include <fortify.h>
|
|
#include <sics.h>
|
|
#include <motor.h>
|
|
#include <asyncprotocol.h>
|
|
#include <asyncqueue.h>
|
|
#include <tcl.h>
|
|
#include <site.h>
|
|
#include <SCinter.h>
|
|
#include <splitter.h>
|
|
|
|
#ifdef SICS_VALGRIND
|
|
#include <valgrind/memcheck.h>
|
|
#endif
|
|
|
|
#include "protocol.h"
|
|
#include "sicslist.h"
|
|
#include "macro.h"
|
|
#include "status.h"
|
|
/* site-specific driver header files */
|
|
#include "motor_dmc2280.h"
|
|
#include "motor_asim.h"
|
|
#include "itc4.h"
|
|
/* Added code for new LH45 and Lakeshore 340 drivers */
|
|
#include "lh45.h"
|
|
#include "lakeshore340.h"
|
|
#include "west4100.h"
|
|
/* Added HTTP support for ANSTO OPAL NBI Histogram Server */
|
|
#include "anstohttp.h"
|
|
#include "anstoutil.h"
|
|
/* Added customized HMControl object to support ANSTO OPAL NBI Histogram Server */
|
|
#include "hmcontrol.h"
|
|
#include "hmcontrol_ansto.h" // extends hmcontrol.h
|
|
/* Added code for NHQ200 HV Power Supply */
|
|
#include "nhq200.h"
|
|
/* Added code for Oak Ridge High Voltage Power Supply */
|
|
#include "orhvps.h"
|
|
/* Added code for new LS340 LAKESORE 340 Temperature Controller */
|
|
#include "ls340.h"
|
|
|
|
#include "safetyplc.h"
|
|
#include "lssmonitor.h"
|
|
#include "beamstopaction.h"
|
|
#include "cameradriver.h"
|
|
#include "aqp_opalstatus.h"
|
|
#include "omron_asyncprotocol.h"
|
|
#include "huber_asyncprotocol.h"
|
|
|
|
/*@observer@*//*@null@*/ pCounterDriver CreateMonCounter(/*@observer@*/SConnection *pCon, /*@observer@*/char *name, char *params);
|
|
|
|
|
|
extern void AddGalilProtocoll();
|
|
extern void AddModbusProtocoll();
|
|
extern void AddOxfordProtocoll();
|
|
extern void AddNewportProtocoll();
|
|
extern void AddOrdHVPSProtocoll();
|
|
extern void AddVelSelProtocol();
|
|
extern void AddUSBTMCProtocoll();
|
|
extern void AddHttpProtocoll();
|
|
extern void AddProtek608Protocol();
|
|
extern void AddRFAmpProtocol();
|
|
extern void AddTCPMBProtocol ();
|
|
extern void AddLFGenProtocol();
|
|
extern void AddSCAQAProtocol();
|
|
extern int ANSTO_MakeHistMemory(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]);
|
|
extern int Ansto_Stack_Trace(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]);
|
|
extern int testLogCmd(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]);
|
|
extern pCounterDriver CreateCam(SConnection *pCon, char *name, char *asynq);
|
|
|
|
int SICS_Site(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[])
|
|
{
|
|
char line[132];
|
|
#ifdef SICS_SITE
|
|
snprintf(line, 132, "SICS_Site = %s", SICS_SITE);
|
|
#else
|
|
snprintf(line, 132, "SICS_Site = ANSTO");
|
|
#endif
|
|
SCWrite(pCon, line, eValue);
|
|
return OKOK;
|
|
};
|
|
|
|
int SICS_Version(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[])
|
|
{
|
|
char line[132];
|
|
#ifdef SICS_VERSION
|
|
snprintf(line, 132, "SICS_Version = %s", SICS_VERSION);
|
|
#else
|
|
snprintf(line, 132, "SICS_Version = UNKNOWN");
|
|
#endif
|
|
SCWrite(pCon, line, eValue);
|
|
return OKOK;
|
|
};
|
|
|
|
int SICS_Revision(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[])
|
|
{
|
|
char line[132];
|
|
#ifdef SICS_REVISION
|
|
snprintf(line, 132, "SICS_Revision = %s", SICS_REVISION);
|
|
#else
|
|
snprintf(line, 132, "SICS_Revision = UNKNOWN");
|
|
#endif
|
|
SCWrite(pCon, line, eValue);
|
|
return OKOK;
|
|
};
|
|
|
|
static int Ansto_Valgrind(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[])
|
|
{
|
|
/* check authorisation: only users permitted here */
|
|
if (!SCMatchRights(pCon, usUser)) {
|
|
SCWrite(pCon, "ERROR: Insufficient Privilege to do Valgrind", eError);
|
|
return 0;
|
|
}
|
|
|
|
/* check enough arguments */
|
|
if (argc < 2) {
|
|
SCWrite(pCon, "ERROR: Valgrind subcommand not specified ", eError);
|
|
return 0;
|
|
}
|
|
|
|
if (strcasecmp(argv[1], "added") == 0) {
|
|
#ifdef VALGRIND_DO_ADDED_LEAK_CHECK
|
|
VALGRIND_DO_ADDED_LEAK_CHECK;
|
|
SCSendOK(pCon);
|
|
#else
|
|
SCPrintf(pCon, eError, "VALGRIND_DO_ADDED_LEAK_CHECK not supported for %s", argv[1]);
|
|
#endif
|
|
return OKOK;
|
|
}
|
|
|
|
if (strcasecmp(argv[1], "changed") == 0) {
|
|
#ifdef VALGRIND_DO_CHANGED_LEAK_CHECK
|
|
VALGRIND_DO_CHANGED_LEAK_CHECK;
|
|
SCSendOK(pCon);
|
|
#else
|
|
SCPrintf(pCon, eError, "VALGRIND_DO_CHANGED_LEAK_CHECK not supported for %s", argv[1]);
|
|
#endif
|
|
return OKOK;
|
|
}
|
|
|
|
if (strcasecmp(argv[1], "quick") == 0) {
|
|
#ifdef VALGRIND_DO_QUICK_LEAK_CHECK
|
|
VALGRIND_DO_QUICK_LEAK_CHECK;
|
|
SCSendOK(pCon);
|
|
#else
|
|
SCPrintf(pCon, eError, "VALGRIND_DO_QUICK_LEAK_CHECK not supported for %s", argv[1]);
|
|
#endif
|
|
return OKOK;
|
|
}
|
|
|
|
if (strcasecmp(argv[1], "check") == 0) {
|
|
#ifdef VALGRIND_DO_LEAK_CHECK
|
|
VALGRIND_DO_LEAK_CHECK;
|
|
SCSendOK(pCon);
|
|
#else
|
|
SCPrintf(pCon, eError, "VALGRIND_DO_LEAK_CHECK not supported for %s", argv[1]);
|
|
#endif
|
|
return OKOK;
|
|
}
|
|
|
|
if (strcasecmp(argv[1], "bytes") == 0) {
|
|
#ifdef VALGRIND_COUNT_LEAKS
|
|
static long int leaked_bytes = 0;
|
|
static long int dubious_bytes = 0;
|
|
static long int reachable_bytes = 0;
|
|
static long int suppressed_bytes = 0;
|
|
long int leaked = 0;
|
|
long int dubious = 0;
|
|
long int reachable = 0;
|
|
long int suppressed = 0;
|
|
VALGRIND_COUNT_LEAKS(leaked, dubious, reachable, suppressed);
|
|
if (argc > 2 && strcasecmp(argv[2], "delta") == 0) {
|
|
SCPrintf(pCon, eLog, "Valgrind delta bytes: leaked=%ld, dubious=%ld, reachable=%ld, suppressed=%ld",
|
|
leaked - leaked_bytes, dubious - dubious_bytes, reachable - reachable_bytes, suppressed - suppressed_bytes);
|
|
} else {
|
|
SCPrintf(pCon, eLog, "Valgrind bytes: leaked=%ld, dubious=%ld, reachable=%ld, suppressed=%ld",
|
|
leaked, dubious, reachable, suppressed);
|
|
}
|
|
leaked_bytes = leaked;
|
|
dubious_bytes = dubious;
|
|
reachable_bytes = reachable;
|
|
suppressed_bytes = suppressed;
|
|
#else
|
|
SCPrintf(pCon, eError, "VALGRIND_COUNT_LEAKS not supported for %s", argv[1]);
|
|
#endif
|
|
return OKOK;
|
|
}
|
|
|
|
if (strcasecmp(argv[1], "blocks") == 0) {
|
|
#ifdef VALGRIND_COUNT_LEAK_BLOCKS
|
|
static long int leaked_blocks = 0;
|
|
static long int dubious_blocks = 0;
|
|
static long int reachable_blocks = 0;
|
|
static long int suppressed_blocks = 0;
|
|
long int leaked = 0;
|
|
long int dubious = 0;
|
|
long int reachable = 0;
|
|
long int suppressed = 0;
|
|
VALGRIND_COUNT_LEAK_BLOCKS(leaked, dubious, reachable, suppressed);
|
|
if (argc > 2 && strcasecmp(argv[2], "delta") == 0) {
|
|
SCPrintf(pCon, eLog, "Valgrind delta blocks: leaked=%ld, dubious=%ld, reachable=%ld, suppressed=%ld",
|
|
leaked - leaked_blocks, dubious - dubious_blocks, reachable - reachable_blocks, suppressed - suppressed_blocks);
|
|
} else {
|
|
SCPrintf(pCon, eLog, "Valgrind blocks: leaked=%ld, dubious=%ld, reachable=%ld, suppressed=%ld",
|
|
leaked, dubious, reachable, suppressed);
|
|
}
|
|
leaked_blocks = leaked;
|
|
dubious_blocks = dubious;
|
|
reachable_blocks = reachable;
|
|
suppressed_blocks = suppressed;
|
|
#else
|
|
SCPrintf(pCon, eError, "VALGRIND_COUNT_LEAK_BLOCKS not supported for %s", argv[1]);
|
|
#endif
|
|
return OKOK;
|
|
}
|
|
|
|
SCPrintf(pCon, eError, "Valgrind subcommand not supported for %s", argv[1]);
|
|
return OKOK;
|
|
}
|
|
|
|
void SiteReportVersion(void)
|
|
{
|
|
fprintf(stdout, "SICS version=%s revision=%s at %s\n",
|
|
SICS_VERSION, SICS_REVISION, SICS_SITE);
|
|
}
|
|
|
|
static int MacroFileEvalGlob(SConnection * pCon, SicsInterp * pInter, void *pData,
|
|
int argc, char *argv[])
|
|
{
|
|
int i;
|
|
int rv;
|
|
int flags;
|
|
Status eOld;
|
|
glob_t globbuf;
|
|
char *args[3];
|
|
|
|
assert(pCon);
|
|
assert(pInter);
|
|
|
|
/* check authorisation: only users permitted here */
|
|
if (!SCMatchRights(pCon, usUser)) {
|
|
SCWrite(pCon, "ERROR: Insufficient Privilege to do FileEval", eError);
|
|
return 0;
|
|
}
|
|
|
|
/* check enough arguments */
|
|
if (argc < 2) {
|
|
SCWrite(pCon, "ERROR: No filename specified ", eError);
|
|
return 0;
|
|
}
|
|
|
|
/* handle status first */
|
|
eOld = GetStatus();
|
|
SetStatus(eBatch);
|
|
|
|
flags = GLOB_NOSORT;
|
|
#if defined(GLOB_BRACE)
|
|
flags |= GLOB_BRACE;
|
|
#endif
|
|
#if defined(GLOB_TILDE_CHECK)
|
|
flags |= GLOB_TILDE_CHECK;
|
|
#endif
|
|
memset(&globbuf, 0, sizeof(globbuf));
|
|
for (i = 1; i < argc; ++i) {
|
|
glob(argv[i], flags, NULL, &globbuf);
|
|
flags |= GLOB_APPEND;
|
|
}
|
|
args[0] = "fileeval";
|
|
args[2] = NULL;
|
|
rv = 1;
|
|
for (i = 0; i < (int) globbuf.gl_pathc; ++i) {
|
|
args[1] = globbuf.gl_pathv[i];
|
|
SCPrintf(pCon, eLog, "fileeval %s", args[1]);
|
|
if (0 == MacroFileEval(pCon, pInter, pData, 2, args))
|
|
rv = 0;
|
|
}
|
|
if (0 == globbuf.gl_pathc) {
|
|
SCWrite(pCon, "ERROR: No file(s) found in FileEvalGlob", eError);
|
|
rv = 0;
|
|
}
|
|
globfree(&globbuf);
|
|
SetStatus(eOld);
|
|
if (1 == rv)
|
|
SCSendOK(pCon);
|
|
return rv;
|
|
}
|
|
|
|
/* Test of the logging facilities */
|
|
int testLogCmd(SConnection *pCon, SicsInterp *pInter, void *pData,
|
|
int argc, char *argv[]) {
|
|
char lbuf[2048];
|
|
char sbuf[1000];
|
|
int i;
|
|
SICSLogWrite("Multiline:\nLine 1\r\nLine 2\r\nLine 3\r\n", eLog);
|
|
memset(lbuf, 0, sizeof(lbuf));
|
|
memset(sbuf, ' ', sizeof(sbuf));
|
|
SICSLogPrintf(eLog, "Hexlog %d all zero bytes", (int) sizeof(lbuf));
|
|
SICSLogWriteHex(lbuf, sizeof(lbuf), eLog);
|
|
for (i = 0; i <= 128; ++i)
|
|
sbuf[i] = sbuf[sizeof(sbuf) - 1 - i] = i;
|
|
sbuf[sizeof(sbuf) / 2] = '!';
|
|
SICSLogPrintf(eLog, "Hexlog %d mid space bytes", (int) sizeof(sbuf));
|
|
SICSLogWriteHex(sbuf, sizeof(sbuf), eLog);
|
|
for (i = 0; i < 1000; ++i)
|
|
sbuf[i] = ' ' + (i % 96);
|
|
sbuf[sizeof(sbuf) - 1] = '\0';
|
|
SICSLogWrite("Very long line 1000 bytes", eLog);
|
|
SICSLogWrite(sbuf, eLog);
|
|
SCSendOK(pCon);
|
|
return OKOK;
|
|
}
|
|
|
|
/**
|
|
* \brief Writes multiline output from a command to a client.
|
|
* This is useful for implementing Tcl proc wrappers for commands.
|
|
* NOTE: SICS-764, currently this sends output to the client as well as capturing it.
|
|
* We should try to improve this in Release 3.2 see SICS-765
|
|
*/
|
|
int Ansto_Capture(SConnection *pCon, SicsInterp * pSics, void *pData, int argc, char *argv[]) {
|
|
char buffer[1024];
|
|
char *command, *data;
|
|
int status, inMacro;
|
|
|
|
if (argc < 2) {
|
|
SCWrite(pCon, "ERROR: insufficient arguments to capture", eError);
|
|
return 0;
|
|
}
|
|
command = Arg2Tcl(argc - 1, &argv[1], buffer, sizeof buffer);
|
|
inMacro = pCon->iMacro;
|
|
pCon->iMacro = 0;
|
|
status = InterpExecute(pSics, pCon, command);
|
|
pCon->iMacro = inMacro;
|
|
if (command != buffer)
|
|
free(command);
|
|
data = ANETgetWBuffer(pCon->sockHandle);
|
|
SCWrite(pCon, data, eValue);
|
|
return status;
|
|
}
|
|
|
|
void SiteInit(void) {
|
|
#define INIT(F) { void F(void); F(); }
|
|
/* insert here initialization routines ... */
|
|
INIT(SctEmonInit);
|
|
INIT(ANSTO_SctDriveInit);
|
|
AddGalilProtocoll();
|
|
AddModbusProtocoll();
|
|
AddOxfordProtocoll();
|
|
AddNewportProtocoll();
|
|
AddOrdHVPSProtocoll();
|
|
AddVelSelProtocol();
|
|
AddUSBTMCProtocoll();
|
|
AddHttpProtocoll();
|
|
AddProtek608Protocol();
|
|
AddRFAmpProtocol();
|
|
AddTCPMBProtocol();
|
|
AddLFGenProtocol();
|
|
AddSCAQAProtocol();
|
|
}
|
|
|
|
static pSite /*@null@*/ siteANSTO = NULL;
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
static void AddCommands(SicsInterp *pInter)
|
|
{
|
|
DMC2280InitProtocol(pInter);
|
|
SafetyPLCInitProtocol(pInter);
|
|
LSSInitProtocol(pInter);
|
|
NHQ200InitProtocol(pInter);
|
|
ORHVPSInitProtocol(pInter);
|
|
LS340InitProtocol(pInter);
|
|
CameraInitProtocol(pInter);
|
|
OpalStatusInitProtocol(pInter);
|
|
LOADERInitProtocol(pInter);
|
|
AddCommand(pInter,"InstallProtocolHandler", InstallProtocol,NULL,NULL);
|
|
AddCommand(pInter,"hostnam",hostNamCmd,NULL,NULL);
|
|
AddCommand(pInter,"portnum",portNumCmd,NULL,NULL);
|
|
AddCommand(pInter,"abortbatch",AbortBatch,NULL,NULL);
|
|
AddCommand(pInter,"testlog",testLogCmd,NULL,NULL);
|
|
AddCommand(pInter,"MakeHMControl_ANSTO",MakeHMControl_ANSTO,NULL,NULL);
|
|
// AddCommand(pInter,"MakeAsyncProtocol",AsyncProtocolFactory,NULL,NULL);
|
|
// AddCommand(pInter,"MakeAsyncQueue",AsyncQueueFactory,NULL,NULL);
|
|
AddCommand(pInter,"MakeMultiChan",AsyncQueueFactory,NULL,NULL);
|
|
AddCommand(pInter,"MakeSafetyPLC",SafetyPLCFactory,NULL,NULL);
|
|
AddCommand(pInter,"MakeLSSMonitor",LSSFactory,NULL,NULL);
|
|
AddCommand(pInter,"MakeActionObject",ActionObjectFactory,NULL,NULL);
|
|
AddCommand(pInter,"ANSTO_MakeHM",ANSTO_MakeHistMemory,NULL,NULL);
|
|
AddCommand(pInter,"SICS_Site",SICS_Site,NULL,NULL);
|
|
AddCommand(pInter,"SICS_Version",SICS_Version,NULL,NULL);
|
|
AddCommand(pInter,"SICS_Revision",SICS_Revision,NULL,NULL);
|
|
AddCommand(pInter, "sicslist", SicsList, NULL, NULL);
|
|
AddCommand(pInter, "FileEvalGlob", MacroFileEvalGlob, NULL, NULL);
|
|
AddCommand(pInter, "Valgrind", Ansto_Valgrind, NULL, NULL);
|
|
AddCommand(pInter, "anstocapture", Ansto_Capture, NULL, NULL);
|
|
AddCommand(pInter, "stack_trace", Ansto_Stack_Trace, NULL, NULL);
|
|
|
|
/*
|
|
* Tcl 8.5 has implemented the clock command in tcl rather then C.
|
|
* This includes the same command, backported from Tcl 8.4
|
|
*/
|
|
#if 0
|
|
printf("TCL interpreter %s safe\n", Tcl_IsSafe(InterpGetTcl(pServ->pSics)) ? "is" : "is not");
|
|
//TclClockInit(InterpGetTcl(pServ->pSics));
|
|
#else
|
|
/*
|
|
* from tclClock.c
|
|
*/
|
|
int Tcl_ClockObjCmd (ClientData client, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
|
|
/*
|
|
* Tcl 8.5 has implemented the clock command in tcl rather than C.
|
|
* This includes the same command, backported from Tcl 8.4
|
|
*/
|
|
|
|
Tcl_CreateObjCommand(InterpGetTcl(pServ->pSics), "clock", Tcl_ClockObjCmd, NULL, NULL);
|
|
#endif
|
|
|
|
}
|
|
/*---------------------------------------------------------------------*/
|
|
static void RemoveCommands(SicsInterp *pSics){
|
|
}
|
|
/*-------------------------------------------------------------------*/
|
|
/*@null@*/ static pMotor CreateMotorAnsto(SConnection *pCon, int argc, char *argv[])
|
|
{
|
|
MotorDriver *pDriver = NULL;
|
|
pMotor pNew = NULL;
|
|
char pBueffel[132];
|
|
|
|
/* create the motor */
|
|
strtolower(argv[1]);
|
|
if(strcmp(argv[1],"dmc2280") == 0) {
|
|
pDriver = (MotorDriver *)CreateDMC2280(pCon,argv[0],argv[2]);
|
|
if(!pDriver){
|
|
return NULL;
|
|
}
|
|
pNew = MotorInit("DMC2280",argv[0],pDriver);
|
|
if(!pNew) {
|
|
sprintf(pBueffel,"ERROR:SITE: Failure to create motor %s",argv[1]);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return NULL;
|
|
}
|
|
pNew->pActionRoutine = DMC2280Action;
|
|
}
|
|
if(strcmp(argv[1],"asim") == 0) {
|
|
pDriver = (MotorDriver *)CreateASIM(pCon,argv[0],argv[2]);
|
|
if(!pDriver){
|
|
return NULL;
|
|
}
|
|
pNew = MotorInit("ASIM",argv[0],pDriver);
|
|
if(!pNew) {
|
|
sprintf(pBueffel,"ERROR:SITE: Failure to create motor %s",argv[1]);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return NULL;
|
|
}
|
|
pNew->pActionRoutine = SimAction;
|
|
}
|
|
|
|
|
|
|
|
return pNew;
|
|
}
|
|
/*-------------------------------------------------------------------*/
|
|
static pCounterDriver CreateCounterDriverAnsto(SConnection *pCon,
|
|
int argc,
|
|
char *argv[]){
|
|
pCounterDriver pDriver = NULL;
|
|
strtolower(argv[2]);
|
|
if(strcmp(argv[2],"anstomonitor") == 0) {
|
|
pDriver = CreateMonCounter(pCon, argv[1], argv[3]);
|
|
} else if (strcmp(argv[2], "anstocamera") == 0) {
|
|
pDriver = CreateCam(pCon, argv[1], argv[3]);
|
|
}
|
|
if(!pDriver){
|
|
return NULL;
|
|
}
|
|
return pDriver;
|
|
}
|
|
/*-------------------------------------------------------------------*/
|
|
static HistDriver *CreateAnstoHistMem(char *name, pStringDict pOptions){
|
|
HistDriver *pNew = NULL;
|
|
|
|
if(strcmp(name,"anstohttp") == 0){
|
|
pNew = CreateAnstoHttpDriver(pOptions);
|
|
}
|
|
return pNew;
|
|
}
|
|
/*-------------------------------------------------------------------*/
|
|
static pVelSelDriv CreateVelSelDriv(char *name, char *array,
|
|
Tcl_Interp *pTcl){
|
|
pVelSelDriv pNew = NULL;
|
|
return pNew;
|
|
}
|
|
/*-------------------------------------------------------------------*/
|
|
static pCodri CreateController(SConnection *pCon,int argc, char *argv[]){
|
|
pCodri pNew = NULL;
|
|
if(strcmp(argv[0],"tcpdocho") == 0){
|
|
if(argc < 2){
|
|
SCWrite(pCon,"ERROR: insufficient number of arguments for creating TcpDoCho",
|
|
eError);
|
|
return NULL;
|
|
}
|
|
return NULL;
|
|
}
|
|
return pNew;
|
|
}
|
|
/*------------------------------------------------------------------*/
|
|
static pEVControl InstallEnvironmentController(SicsInterp *pSics,
|
|
SConnection *pCon,
|
|
int argc, char *argv[]){
|
|
int status;
|
|
pEVControl pNew = NULL;
|
|
pEVDriver pDriv = NULL;
|
|
strtolower(argv[3]);
|
|
|
|
|
|
/* Added code for new LH45 driver */
|
|
if(strcmp(argv[3],"lh45") == 0) {
|
|
pDriv = CreateLH45Driver(argc-4,&argv[4]);
|
|
if(pDriv){
|
|
pNew = CreateEVController(pDriv,argv[2],&status);
|
|
if(pNew != NULL){
|
|
AddCommand(pSics,argv[2],LH45Wrapper,DeleteEVController,
|
|
pNew);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Added code for new Lakeshore 340 driver */
|
|
if(strcmp(argv[3],"lakeshore340") == 0) {
|
|
pDriv = CreateLAKESHORE340Driver(argc-4,&argv[4]);
|
|
if(pDriv){
|
|
pNew = CreateEVController(pDriv,argv[2],&status);
|
|
if(pNew != NULL){
|
|
AddCommand(pSics,argv[2],LAKESHORE340Wrapper,DeleteEVController,
|
|
pNew);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Added code for new Lakeshore 340 driver */
|
|
if(strcmp(argv[3],"west4100") == 0) {
|
|
pDriv = CreateWEST4100Driver(argc-4,&argv[4]);
|
|
if(pDriv){
|
|
pNew = CreateEVController(pDriv,argv[2],&status);
|
|
if(pNew != NULL){
|
|
AddCommand(pSics,argv[2],WEST4100Wrapper,DeleteEVController,
|
|
pNew);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Added code for new NHQ 200 driver */
|
|
if(strcmp(argv[3],"nhq200") == 0) {
|
|
pDriv = CreateNHQ200Driver(argc-4,&argv[4]);
|
|
if(pDriv){
|
|
pNew = CreateEVController(pDriv,argv[2],&status);
|
|
if(pNew != NULL){
|
|
NHQ200Register(pNew, pDriv);
|
|
AddCommand(pSics,argv[2],NHQ200Wrapper,DeleteEVController,
|
|
pNew);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Added code for new Oak Ridge High Voltage Power Supply driver */
|
|
if(strcmp(argv[3],"orhvps") == 0) {
|
|
pDriv = CreateORHVPSDriver(argc-4,&argv[4]);
|
|
if(pDriv){
|
|
pNew = CreateEVController(pDriv,argv[2],&status);
|
|
if(pNew != NULL){
|
|
ORHVPSRegister(pNew, pDriv);
|
|
AddCommand(pSics,argv[2],ORHVPSWrapper,DeleteEVController,
|
|
pNew);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Added code for new LS340 LAKSHORE Temperature Controller 340 Driver */
|
|
if(strcmp(argv[3],"ls340") == 0) {
|
|
pDriv = CreateLS340Driver(argc,argv);
|
|
if(pDriv){
|
|
pNew = CreateEVController(pDriv,argv[2],&status);
|
|
if(pNew != NULL){
|
|
LS340Register(pNew, pDriv);
|
|
AddCommand(pSics,argv[2],LS340Wrapper,DeleteEVController,
|
|
pNew);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
return pNew;
|
|
}
|
|
/*-----------------------------------------------------------------*/
|
|
static int ConfigureScan(pScanData self, char *option){
|
|
if(!self) {
|
|
return 0;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
/*--------------------------------------------------------------------*/
|
|
static void KillSite(void *site){
|
|
free(site);
|
|
siteANSTO = NULL;
|
|
}
|
|
/*---------------------------------------------------------------------
|
|
The scheme here goes along the lines of the singleton design pattern
|
|
---------------------------------------------------------------------*/
|
|
pSite getSite(void)
|
|
{
|
|
if(siteANSTO == NULL)
|
|
{
|
|
siteANSTO = (pSite)malloc(sizeof(Site));
|
|
/*
|
|
we cannot go on if we do not even have enough memory to allocate
|
|
the site data structure
|
|
*/
|
|
assert(siteANSTO);
|
|
/*
|
|
initializing function pointers
|
|
*/
|
|
siteANSTO->AddSiteCommands = AddCommands;
|
|
siteANSTO->RemoveSiteCommands = RemoveCommands;
|
|
siteANSTO->CreateMotor = CreateMotorAnsto;
|
|
siteANSTO->CreateCounterDriver = CreateCounterDriverAnsto;
|
|
siteANSTO->CreateHistogramMemoryDriver = CreateAnstoHistMem;
|
|
siteANSTO->CreateVelocitySelector = CreateVelSelDriv;
|
|
siteANSTO->CreateControllerDriver = CreateController;
|
|
siteANSTO->InstallEnvironmentController = InstallEnvironmentController;
|
|
siteANSTO->ConfigureScan = ConfigureScan;
|
|
siteANSTO->KillSite = KillSite;
|
|
}
|
|
return siteANSTO;
|
|
}
|
|
|
|
void broadcastPrintf(int iOut, char *fmt, ...)
|
|
{
|
|
va_list ap;
|
|
char buf[256];
|
|
char *dyn;
|
|
unsigned int l;
|
|
int res;
|
|
|
|
va_start(ap, fmt);
|
|
l = vsnprintf(buf, sizeof buf, fmt, ap);
|
|
va_end(ap);
|
|
if (l >= sizeof buf) {
|
|
/* we have probably a C99 conforming snprintf and
|
|
need a larger buffer
|
|
*/
|
|
dyn = malloc(l+1);
|
|
if (dyn != NULL) {
|
|
va_start(ap, fmt);
|
|
vsnprintf(dyn, l+1, fmt, ap);
|
|
va_end(ap);
|
|
ServerWriteGlobal(dyn, iOut);
|
|
free(dyn);
|
|
}
|
|
}
|
|
ServerWriteGlobal(buf, iOut);
|
|
}
|