- moved initializer and remob to the kernel
This commit is contained in:
139
initializer.c
139
initializer.c
@ -1,139 +0,0 @@
|
||||
/*---------------------------------------------------------------------------
|
||||
initializer.c
|
||||
|
||||
initializer routines
|
||||
|
||||
Markus Zolliker, March 2005
|
||||
----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "sics.h"
|
||||
#include "initializer.h"
|
||||
|
||||
typedef struct Item {
|
||||
struct Item *next;
|
||||
const char *type;
|
||||
const char *name;
|
||||
Initializer maker;
|
||||
int startupOnly;
|
||||
} Item;
|
||||
|
||||
static Item *list = NULL;
|
||||
static int startup = 1;
|
||||
|
||||
void MakeInitializer(const char *type, const char *name, Initializer maker, int startupOnly) {
|
||||
Item *item;
|
||||
|
||||
item = calloc(1, sizeof *item);
|
||||
assert(item);
|
||||
item->maker = maker;
|
||||
item->next = list;
|
||||
item->type = type;
|
||||
item->name = name;
|
||||
item->startupOnly = startupOnly;
|
||||
list = item;
|
||||
}
|
||||
|
||||
Initializer GetInitializer(const char *type, const char *name) {
|
||||
Item *p, **last;
|
||||
|
||||
if (startup && pServ->pReader != NULL) {
|
||||
/* pServ->pReader exists: startup finished */
|
||||
startup = 0;
|
||||
/* remove startup initializers */
|
||||
p = list;
|
||||
last = &list;
|
||||
while (p != NULL) {
|
||||
if (p->startupOnly) {
|
||||
*last = p->next;
|
||||
free(p);
|
||||
p = *last;
|
||||
} else {
|
||||
last = &p->next;
|
||||
p = p->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
p = list;
|
||||
while (p != NULL && (strcasecmp(p->name, name) != 0 || strcasecmp(p->type, type) != 0)) {
|
||||
p = p->next;
|
||||
}
|
||||
if (p) {
|
||||
return p->maker;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int MakeObject(SConnection *con, SicsInterp *sics,
|
||||
void *data, int argc, char *argv[]) {
|
||||
CmdInitializer cmdin;
|
||||
CommandList *command;
|
||||
char *className;
|
||||
|
||||
if (argc < 3) {
|
||||
SCPrintf(con, eError, "%s needs more arguments", argv[0]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
cmdin = (CmdInitializer)GetInitializer("Object", argv[2]);
|
||||
if (cmdin) {
|
||||
return cmdin(con, argc, argv, ! startup);
|
||||
} else {
|
||||
SCPrintf(con, eError, "do not know how to make a %s object", argv[2]);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int RemoveObject(SConnection *con, SicsInterp *sics,
|
||||
void *data, int argc, char *argv[]) {
|
||||
CmdInitializer cmdin;
|
||||
CommandList *command;
|
||||
char *className;
|
||||
|
||||
if (argc != 2) {
|
||||
SCPrintf(con, eError, "%s has 1 argument", argv[0]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
command = FindCommand(sics, argv[1]);
|
||||
if (!command) {
|
||||
SCPrintf(con, eError, "ERROR: %s not found", argv[1]);
|
||||
return 0;
|
||||
}
|
||||
className = ((pDummy)command->pData)->pDescriptor->name;
|
||||
cmdin = (CmdInitializer)GetInitializer("Object", className);
|
||||
if (cmdin) {
|
||||
/* if we have an initializer, we are allowed to remove */
|
||||
if (pServ->pExecutor && isInRunMode(pServ->pExecutor)) {
|
||||
SCPrintf(con, eError, "ERROR: cannot remove %s while running", argv[1]);
|
||||
return 0;
|
||||
}
|
||||
SCPrintf(con, eValue, "remove %s", argv[1]);
|
||||
SCparChange(con);
|
||||
return RemoveCommand(sics, argv[1]);
|
||||
} else {
|
||||
SCPrintf(con, eError, "ERROR: %s is not removable", argv[1]);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void KillInitializers(void *data) {
|
||||
KillDummy(data);
|
||||
Item *item, *next;
|
||||
|
||||
item = list;
|
||||
while (item) {
|
||||
next = item->next;
|
||||
free(item);
|
||||
item = next;
|
||||
}
|
||||
list = NULL;
|
||||
}
|
||||
|
||||
void MakeDriver(const char *driver, CmdInitializer maker, int startupOnly) {
|
||||
if (! FindCommand(pServ->pSics, "MakeObject")) {
|
||||
AddCommandWithFlag(pServ->pSics, "MakeObject", MakeObject, KillInitializers, NULL, 0);
|
||||
AddCommandWithFlag(pServ->pSics, "RemoveObject", RemoveObject, NULL, NULL, 0);
|
||||
}
|
||||
MakeInitializer("Object", driver, (Initializer)maker, startupOnly);
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
/*---------------------------------------------------------------------------
|
||||
initializer.h
|
||||
|
||||
initializer list routines
|
||||
|
||||
Markus Zolliker, March 2005
|
||||
----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef SICSINIT_H
|
||||
#define SICSINIT_H
|
||||
|
||||
typedef void (*Initializer)(void);
|
||||
|
||||
void MakeInitializer(const char *type, const char *name, Initializer maker, int startupOnly);
|
||||
|
||||
Initializer GetInitializer(const char *type, const char *name);
|
||||
|
||||
/*
|
||||
MakeObject has the following syntax:
|
||||
|
||||
MakeObject objectName driver [ args ... ]
|
||||
|
||||
*/
|
||||
typedef int (*CmdInitializer) (SConnection *pCon, int argc, char *argv[], int dynamic);
|
||||
/*
|
||||
make a driver with the initializer function maker
|
||||
when the dynamic argument is not 0, the command was created after startup,
|
||||
i.e. the SaveStatus routine has also to write command creation code.
|
||||
*/
|
||||
void MakeDriver(const char *driver, CmdInitializer maker, int startupOnly);
|
||||
|
||||
#endif
|
3
make_gen
3
make_gen
@ -16,8 +16,7 @@ OBJ=psi.o buffer.o ruli.o dmc.o nxsans.o nextrics.o sps.o pimotor.o \
|
||||
el755driv.o amorscan.o serial.o scontroller.o t_update.o \
|
||||
t_rlp.o t_conv.o el737hpdriv.o dornier2.o el734hp.o \
|
||||
el737hpv2driv.o swmotor2.o tricssupport.o \
|
||||
fsm.o remob.o logger.o sugar.o pardef.o \
|
||||
ease.o initializer.o strobj.o oxinst.o \
|
||||
fsm.o logger.o sugar.o pardef.o ease.o strobj.o oxinst.o \
|
||||
ipsdriv.o ilmdriv.o itcdriv.o ighdriv.o euro2kdriv.o modbus.o \
|
||||
dgrambroadcast.o sinq.o tabledrive.o
|
||||
|
||||
|
854
remob.c
854
remob.c
@ -1,854 +0,0 @@
|
||||
/*-----------------------------------------------------------------------
|
||||
remob.c
|
||||
|
||||
implements remote driveable objects living on an other sics server
|
||||
|
||||
M. Zolliker July 04
|
||||
|
||||
------------------------------------------------------------------------*/
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <netdb.h>
|
||||
#include "fortify.h"
|
||||
#include "sics.h"
|
||||
#include "devexec.h"
|
||||
#include "remob.h"
|
||||
#include "splitter.h"
|
||||
#include "status.h"
|
||||
#include "servlog.h"
|
||||
#include "site.h"
|
||||
/*-------------------------------------------------------------------------*/
|
||||
#define INTERRUPTMODE 0
|
||||
#define ACCESSCODE 1
|
||||
|
||||
/*------------------------------------------------------------------------ */
|
||||
typedef struct Remob Remob;
|
||||
|
||||
typedef struct RemServer {
|
||||
pObjectDescriptor desc;
|
||||
char *name;
|
||||
char *host;
|
||||
int port;
|
||||
int actChan; /* 0 or 1 */
|
||||
mkChannel *chans[2]; /* 0: Spy, 1: User */
|
||||
int incomplete;
|
||||
char line[256];
|
||||
Remob *objList;
|
||||
int matchMap;
|
||||
int timeout;
|
||||
int taskActive;
|
||||
SCStore conn;
|
||||
} RemServer;
|
||||
|
||||
struct Remob {
|
||||
pObjectDescriptor desc;
|
||||
char *name;
|
||||
pIDrivable pDrivInt;
|
||||
pICallBack pCall;
|
||||
RemServer *server;
|
||||
int status;
|
||||
Remob *next;
|
||||
int markForDel;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
float fVal;
|
||||
char *pName;
|
||||
} RemobCallback;
|
||||
|
||||
typedef struct {
|
||||
char *pName;
|
||||
SConnection *pCon;
|
||||
} RemobInfo;
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
static char *StartsWith(char *line, char *name) {
|
||||
/* if line does not start with name, return NULL
|
||||
else return a pointer to the next non-white space character
|
||||
*/
|
||||
char *str;
|
||||
int l;
|
||||
|
||||
l = strlen(name);
|
||||
if (0 != strncmp(line, name, l)) return NULL;
|
||||
str = line + l;
|
||||
while (*str == ' ') {
|
||||
str++;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
static int RemWrite(RemServer *remserver, char *line) {
|
||||
int iret;
|
||||
mkChannel *chan;
|
||||
|
||||
chan = remserver->chans[remserver->actChan];
|
||||
if (chan) {
|
||||
/* printf("> %s\n", line); */
|
||||
iret = NETWrite(chan, line, strlen(line));
|
||||
if (iret == 0) iret = -1;
|
||||
return iret;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
static int RemRead(RemServer *remserver, long tmo) {
|
||||
int iRet;
|
||||
mkChannel *chan;
|
||||
|
||||
chan = remserver->chans[remserver->actChan];
|
||||
if (chan == NULL) return 0; /* no data */
|
||||
iRet = NETReadTillTermNew(chan, tmo, "\n",
|
||||
remserver->line+remserver->incomplete, sizeof(remserver->line)-remserver->incomplete);
|
||||
if (iRet == 0) {
|
||||
remserver->incomplete = strlen(remserver->line); /* number of chars already received */
|
||||
return 0; /* timeout */
|
||||
} else {
|
||||
remserver->incomplete=0;
|
||||
}
|
||||
return iRet;
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
static int RemHandle(RemServer *remserver) {
|
||||
char *line, *par, *str;
|
||||
Remob *remob;
|
||||
|
||||
/* skip whitespace at the beginning */
|
||||
line=remserver->line;
|
||||
while (*line < ' ' && *line != '\0') {
|
||||
line++;
|
||||
}
|
||||
memmove(remserver->line, line, strlen(line));
|
||||
|
||||
/* handle drivstat messages */
|
||||
line = remserver->line;
|
||||
for (remob = remserver->objList; remob != NULL; remob = remob->next) {
|
||||
par=StartsWith(line, remob->name);
|
||||
if (par != NULL) {
|
||||
if ((str = StartsWith(par, "finished"))) {
|
||||
if (*str == '\0') {
|
||||
remob->status = HWIdle;
|
||||
} else {
|
||||
remob->status = HWFault;
|
||||
}
|
||||
line[0]='\0';
|
||||
return 1;
|
||||
}
|
||||
if ((str = StartsWith(par, "started"))) {
|
||||
remob->status = HWBusy;
|
||||
line[0]='\0';
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
static void RemCopy(RemServer *remserver, SConnection *pCon) {
|
||||
if (pCon != NULL && remserver->line[0] != '\0') {
|
||||
SCPrintf(pCon, eStatus, " %s", remserver->line);
|
||||
}
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
static void RemDisconnect(RemServer *remserver) {
|
||||
int i;
|
||||
|
||||
for (i=0; i<2; i++) {
|
||||
if (remserver->chans[i] != NULL) {
|
||||
NETClosePort(remserver->chans[i]);
|
||||
free(remserver->chans[i]);
|
||||
remserver->chans[i]=NULL;
|
||||
/* printf("disconnected\n"); */
|
||||
}
|
||||
}
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
static void RemConnect(RemServer *remserver) {
|
||||
int iRet;
|
||||
char buf[256];
|
||||
mkChannel *chan;
|
||||
|
||||
chan = remserver->chans[remserver->actChan];
|
||||
if (!chan) {
|
||||
remserver->timeout = 0;
|
||||
chan = NETConnect(remserver->host, remserver->port);
|
||||
if (!chan) {
|
||||
return;
|
||||
}
|
||||
remserver->chans[remserver->actChan] = chan;
|
||||
if (remserver->actChan == 0) {
|
||||
iRet = RemWrite(remserver, "Spy 007\ntransact listexe interest\n");
|
||||
} else {
|
||||
iRet = RemWrite(remserver, "remuser sesam\ntransact listexe interest\n");
|
||||
}
|
||||
if (iRet < 0) goto close;
|
||||
iRet = RemRead(remserver, 1000);
|
||||
while (iRet > 0) { /* eat login response */
|
||||
if (StartsWith(remserver->line, "TRANSACTIONFINISHED")) {
|
||||
/* printf("connected\n"); */
|
||||
return;
|
||||
}
|
||||
iRet = RemRead(remserver, 1000);
|
||||
}
|
||||
goto close;
|
||||
}
|
||||
return;
|
||||
close:
|
||||
RemDisconnect(remserver);
|
||||
return;
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
static int RemServerTask(void *data) {
|
||||
RemServer *remserver=data;
|
||||
int iRet;
|
||||
SConnection *pCon;
|
||||
|
||||
if (!remserver->taskActive) return 0; /* remove task */
|
||||
if (RemRead(remserver, 0) <= 0) return 1; /* continue */
|
||||
|
||||
/* printf("< %s\n", buf); */
|
||||
|
||||
if (RemHandle(remserver)) { /* handle drivstat messages */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* forward oll other messages */
|
||||
pCon = SCLoad(&remserver->conn);
|
||||
if (pCon) {
|
||||
RemCopy(remserver, pCon);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
static int RemTransact(RemServer *remserver, SConnection *pCon, char *cmd, ...) {
|
||||
/* the variable arguments are for filtering:
|
||||
|
||||
"<name", &val get float value named name
|
||||
"!blabla" skip lines starting with blabla
|
||||
">" write untreated lines to pCon
|
||||
*/
|
||||
char buf[256];
|
||||
int iRet;
|
||||
int i, typ;
|
||||
char *arg, *val, *endp;
|
||||
float *f;
|
||||
va_list ap;
|
||||
int try;
|
||||
int argMask;
|
||||
|
||||
try=2;
|
||||
if (remserver->timeout) { /* eat old responses */
|
||||
while (RemRead(remserver, 0) > 0) {
|
||||
RemHandle(remserver);
|
||||
}
|
||||
}
|
||||
tryagain:
|
||||
strcpy(buf, "transact ");
|
||||
strcat(buf, cmd);
|
||||
strcat(buf,"\n");
|
||||
RemConnect(remserver);
|
||||
iRet = RemWrite(remserver, buf);
|
||||
if (iRet < 0) goto close;
|
||||
|
||||
iRet = RemRead(remserver, 2000);
|
||||
if (iRet <= 0) goto close;
|
||||
while (!StartsWith(remserver->line, "TRANSACTIONFINISHED")) {
|
||||
RemHandle(remserver);
|
||||
va_start(ap, cmd);
|
||||
arg = va_arg(ap, char *);
|
||||
argMask=1;
|
||||
remserver->matchMap = 0;
|
||||
while (arg != NULL) {
|
||||
if (*arg == '>') {
|
||||
RemCopy(remserver, pCon);
|
||||
} else if (*arg == '<') {
|
||||
f = va_arg(ap, float *);
|
||||
val = StartsWith(remserver->line, arg+1);
|
||||
if (val != NULL) {
|
||||
val = StartsWith(val, "=");
|
||||
if (val != NULL) {
|
||||
*f = strtod(val, &endp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (*arg == '!') {
|
||||
if (StartsWith(remserver->line, arg+1)) {
|
||||
remserver->matchMap |= argMask;
|
||||
argMask = argMask*2;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
printf("unknown argument in RemTransact: %s\n", arg);
|
||||
assert(0);
|
||||
}
|
||||
arg = va_arg(ap, char *);
|
||||
}
|
||||
va_end(ap);
|
||||
iRet = RemRead(remserver, 2000);
|
||||
if (iRet <= 0) goto close;
|
||||
}
|
||||
return 1;
|
||||
close:
|
||||
if (iRet == 0) {
|
||||
snprintf(buf, sizeof(buf), "ERROR: timeout on %s", remserver->name);
|
||||
SCWrite(pCon,buf,eError);
|
||||
remserver->timeout = 1;
|
||||
return iRet;
|
||||
}
|
||||
RemDisconnect(remserver);
|
||||
try--;
|
||||
if (try>0) goto tryagain;
|
||||
snprintf(buf, sizeof(buf), "ERROR: no connection to %s", remserver->name);
|
||||
SCWrite(pCon,buf,eError);
|
||||
return iRet;
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
static void *RemobGetInterface(void *pData, int iID) {
|
||||
Remob *self = pData;
|
||||
|
||||
assert(self);
|
||||
if(iID == DRIVEID) {
|
||||
return self->pDrivInt;
|
||||
} else if(iID == CALLBACKINTERFACE) {
|
||||
return self->pCall;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
/*------------------------------------------------------------------------*/
|
||||
static int RemobHalt(void *self) {
|
||||
Remob *remob=self;
|
||||
RemServer *remserver;
|
||||
char buf[64];
|
||||
|
||||
assert(remob);
|
||||
remserver = remob->server;
|
||||
RemConnect(remserver);
|
||||
snprintf(buf, sizeof(buf), "stopexe %s\n", remob->name);
|
||||
return RemWrite(remserver, buf);
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static int RemobLimits(void *self, float fVal, char *error, int iErrLen) {
|
||||
float fHard;
|
||||
Remob *remob=self;
|
||||
|
||||
assert(remob);
|
||||
/* check is done one remote server */
|
||||
return 1;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static float RemobGetValue(void *pData, SConnection *pCon) {
|
||||
Remob *remob=pData;
|
||||
char buf[80];
|
||||
float none, value;
|
||||
int iRet;
|
||||
|
||||
assert(remob);
|
||||
|
||||
SCSave(&remob->server->conn, pCon);
|
||||
none = -1.25e6;
|
||||
value= none;
|
||||
snprintf(buf, sizeof(buf), "<%s", remob->name);
|
||||
iRet = RemTransact(remob->server, pCon, remob->name, buf, &value, ">", NULL);
|
||||
if (iRet <= 0) {
|
||||
return 0.0;
|
||||
}
|
||||
if (value != none) {
|
||||
return value;
|
||||
}
|
||||
snprintf(buf, sizeof(buf), "can not get %s", remob->name);
|
||||
SCWrite(pCon, buf, eWarning);
|
||||
return 0.0;
|
||||
}
|
||||
/*------------------------------------------------------------------------*/
|
||||
static int RemobSaveStatus(void *pData, char *name, FILE *fil) {
|
||||
Remob *self = pData;
|
||||
|
||||
assert(self);
|
||||
assert(fil);
|
||||
|
||||
/*
|
||||
data is stored on remote server
|
||||
*/
|
||||
return 1;
|
||||
}
|
||||
/*------------------------------------------------------------------------*/
|
||||
static int RemServerSaveStatus(void *pData, char *name, FILE *fil) {
|
||||
RemServer *remserver = pData;
|
||||
Remob *remob;
|
||||
|
||||
assert(remserver);
|
||||
assert(fil);
|
||||
|
||||
for (remob = remserver->objList; remob != NULL; remob = remob->next) {
|
||||
fprintf(fil, "catch { remob new %s %s }\n", remob->name, remserver->name);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/*------------------------------------------------------------------------*/
|
||||
static int RemobStatus(void *pData, SConnection *pCon) {
|
||||
Remob *remob=pData;
|
||||
|
||||
assert(remob);
|
||||
|
||||
SCSave(&remob->server->conn, pCon);
|
||||
return remob->status;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static long RemobRun(void *self, SConnection *pCon, float fNew) {
|
||||
Remob *remob=self;
|
||||
float fHard;
|
||||
int i, iRet, iCode;
|
||||
char buf[512], sBuf[64];
|
||||
char pError[132];
|
||||
Remob *p;
|
||||
RemServer *remserver;
|
||||
long lTime;
|
||||
float fDelta;
|
||||
|
||||
remserver = remob->server;
|
||||
SCSave(&remserver->conn, pCon);
|
||||
assert(remob);
|
||||
assert(pCon);
|
||||
|
||||
remob->status = HWIdle;
|
||||
snprintf(buf, sizeof(buf), "run %s %f", remob->name, fNew);
|
||||
iRet = RemTransact(remserver, pCon, buf, "!ERROR: somebody else", "!ERROR: cannot", ">", NULL);
|
||||
if (iRet <= 0) return 0;
|
||||
|
||||
if (remserver->matchMap & 1) { /* already running, stop first */
|
||||
remob->status = HWBusy;
|
||||
snprintf(sBuf, sizeof(sBuf), "stopexe %s", remob->name);
|
||||
iRet = RemTransact(remserver, pCon, sBuf, ">", NULL);
|
||||
if (iRet <= 0) return 0;
|
||||
while (remob->status == HWBusy) {
|
||||
iRet = RemRead(remserver, 1000);
|
||||
if (iRet <= 0) break;
|
||||
RemCopy(remserver, pCon);
|
||||
}
|
||||
iRet = RemTransact(remserver, pCon, buf, ">", NULL);
|
||||
if (iRet <= 0) return 0;
|
||||
}
|
||||
if (remob->status != HWBusy) {
|
||||
return 0;
|
||||
}
|
||||
return OKOK;
|
||||
}
|
||||
/*-----------------------------------------------------------------------*/
|
||||
static void KillInfo(void *pData) {
|
||||
RemobInfo *self = pData;
|
||||
|
||||
assert(self);
|
||||
if (self->pName) {
|
||||
free(self->pName);
|
||||
}
|
||||
free(self);
|
||||
}
|
||||
/*------------------- The CallBack function for interest ------------------*/
|
||||
static int InterestCallback(int iEvent, void *pEvent, void *pUser) {
|
||||
RemobCallback *psCall = pEvent;
|
||||
RemobInfo *pInfo = pUser;
|
||||
char buf[80];
|
||||
|
||||
assert(psCall);
|
||||
assert(pInfo);
|
||||
|
||||
snprintf(buf, sizeof(buf),"%s.position = %f ", pInfo->pName, psCall->fVal);
|
||||
SCWrite(pInfo->pCon,buf,eValue);
|
||||
return 1;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int RemobAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[]) {
|
||||
Remob *remob = pData;
|
||||
char buf[512];
|
||||
TokenList *pList = NULL;
|
||||
TokenList *pCurrent;
|
||||
TokenList *pName;
|
||||
int iRet;
|
||||
int i;
|
||||
int pos;
|
||||
float fValue;
|
||||
long lID;
|
||||
char *endp;
|
||||
char acce[128], inte[128];
|
||||
|
||||
assert(pCon);
|
||||
assert(pSics);
|
||||
assert(remob);
|
||||
|
||||
if (SCGetRights(pCon) > usUser) {
|
||||
remob->server->actChan = 0;
|
||||
} else {
|
||||
remob->server->actChan = 1;
|
||||
}
|
||||
SCSave(&remob->server->conn, pCon);
|
||||
if (argc == 1) {
|
||||
iRet = RemTransact(remob->server, pCon, argv[0], ">", NULL);
|
||||
} else if (strcasecmp(argv[1],"list") == 0) {
|
||||
snprintf(buf, sizeof(buf), "%s ", remob->name);
|
||||
i = strlen(buf);
|
||||
Arg2Text(argc-1, argv+1, buf + i, sizeof buf - i);
|
||||
/*
|
||||
snprintf(acce, sizeof(acce), "!%s.accesscode", remob->name);
|
||||
snprintf(inte, sizeof(inte), "!%s.interruptmode", remob->name);
|
||||
*/
|
||||
|
||||
RemTransact(remob->server, pCon, buf, ">", NULL);
|
||||
|
||||
iRet=1;
|
||||
} else {
|
||||
pos=snprintf(buf, sizeof(buf), "%s ", remob->name);
|
||||
for (i=1; i<argc; i++) {
|
||||
pos+=snprintf(buf+pos, sizeof(buf)-pos, "%s ", argv[i]);
|
||||
}
|
||||
iRet = RemTransact(remob->server, pCon, buf, ">", NULL);
|
||||
}
|
||||
return iRet;
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static void RemobKill(void *self) {
|
||||
Remob *remob = self;
|
||||
Remob *p, **last;
|
||||
|
||||
assert(remob);
|
||||
|
||||
/* remove from object list */
|
||||
if (remob->server) {
|
||||
last = &remob->server->objList;
|
||||
p = *last;
|
||||
while (p != remob && p !=NULL) {
|
||||
last = &p->next;
|
||||
p = p->next;
|
||||
}
|
||||
if (p != NULL) {
|
||||
*last = p->next;
|
||||
}
|
||||
remob->next = NULL;
|
||||
}
|
||||
if (remob->name) {
|
||||
free(remob->name);
|
||||
}
|
||||
if (remob->pDrivInt) {
|
||||
free(remob->pDrivInt);
|
||||
}
|
||||
if (remob->pCall) {
|
||||
DeleteCallBackInterface(remob->pCall);
|
||||
}
|
||||
|
||||
/* kill Descriptor */
|
||||
if (remob->desc) {
|
||||
DeleteDescriptor(remob->desc);
|
||||
}
|
||||
free(remob);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int RemServerAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[]) {
|
||||
RemServer *remserver = pData;
|
||||
char buf[512];
|
||||
TokenList *pList = NULL;
|
||||
TokenList *pCurrent;
|
||||
TokenList *pName;
|
||||
int iRet;
|
||||
int i;
|
||||
int pos;
|
||||
float fValue;
|
||||
long lID;
|
||||
char *endp, *serverport, *thishostname;
|
||||
char acce[128], inte[128];
|
||||
struct sockaddr_in adr;
|
||||
struct hostent *thishost;
|
||||
mkChannel *chan;
|
||||
Remob *p, *next;
|
||||
|
||||
assert(pCon);
|
||||
assert(pSics);
|
||||
assert(remserver);
|
||||
|
||||
if (SCGetRights(pCon) > usUser) {
|
||||
remserver->actChan = 0;
|
||||
} else {
|
||||
remserver->actChan = 1;
|
||||
}
|
||||
chan = remserver->chans[remserver->actChan];
|
||||
if (argc == 1) {
|
||||
serverport = IFindOption(pSICSOptions,"ServerPort");
|
||||
i = sizeof adr;
|
||||
thishostname = NULL;
|
||||
if (chan) {
|
||||
if (getsockname(chan->sockid, (void *)&adr, &i) >= 0) {
|
||||
thishost = gethostbyaddr((char *)&adr.sin_addr,
|
||||
sizeof adr.sin_addr, AF_INET);
|
||||
if (thishost) {
|
||||
thishostname = thishost->h_name;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (thishostname == NULL) thishostname = "undef";
|
||||
SCPrintf(pCon, eStatus, "%s = %s:%d %s:%s",
|
||||
argv[0], remserver->host, remserver->port, thishostname, serverport);
|
||||
} else if (argc>2 && strcasecmp(argv[1],"nowait") == 0) {
|
||||
RemConnect(remserver);
|
||||
for (i=2; i<argc; i++) {
|
||||
if (i>2) {
|
||||
RemWrite(remserver, " ");
|
||||
}
|
||||
RemWrite(remserver, argv[i]);
|
||||
}
|
||||
RemWrite(remserver, "\n");
|
||||
} else if (argc==2 && strcasecmp(argv[1],"markForDel") == 0) {
|
||||
p = remserver->objList;
|
||||
while (p) {
|
||||
p->markForDel = 1;
|
||||
p = p->next;
|
||||
}
|
||||
} else if (argc==2 && strcasecmp(argv[1],"delMarked") == 0) {
|
||||
p = remserver->objList;
|
||||
while (p) {
|
||||
next = p->next;
|
||||
if (p->markForDel) {
|
||||
if (p->pDrivInt && pServ->pExecutor && isInRunMode(pServ->pExecutor)) {
|
||||
SCWrite(pCon,"ERROR: cannot delete while running",eError);
|
||||
return 0;
|
||||
}
|
||||
RemoveCommand(pSics, p->name);
|
||||
}
|
||||
p = next;
|
||||
}
|
||||
} else {
|
||||
pos=0;
|
||||
for (i=1; i<argc; i++) {
|
||||
pos+=snprintf(buf+pos, sizeof(buf)-pos, "%s ", argv[i]);
|
||||
}
|
||||
iRet = RemTransact(remserver, pCon, buf, ">", NULL);
|
||||
return iRet;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static void RemServerKill(void *self) {
|
||||
RemServer *remserver = self;
|
||||
Remob *remob, *next;
|
||||
|
||||
assert(remserver);
|
||||
|
||||
if (remserver->taskActive) {
|
||||
remserver->taskActive=0;
|
||||
/* let the tasker kill me */
|
||||
return;
|
||||
}
|
||||
remob = remserver->objList;
|
||||
while (remob) {
|
||||
next = remob->next;
|
||||
RemoveCommand(pServ->pSics, remob->name);
|
||||
remob = next;
|
||||
}
|
||||
RemDisconnect(remserver);
|
||||
DeleteDescriptor(remserver->desc);
|
||||
if (remserver->name) free(remserver->name);
|
||||
if (remserver->host) free(remserver->host);
|
||||
free(remserver);
|
||||
}
|
||||
/*-----------------------------------------------------------------------*/
|
||||
static int RemobSetDriveable(Remob *remob, int driveable) {
|
||||
if (driveable) {
|
||||
/* initialise Drivable interface */
|
||||
remob->pDrivInt = CreateDrivableInterface();
|
||||
if (!remob->pDrivInt) return 0;
|
||||
remob->pDrivInt->SetValue = RemobRun;
|
||||
remob->pDrivInt->CheckLimits = RemobLimits;
|
||||
remob->pDrivInt->CheckStatus = RemobStatus;
|
||||
remob->pDrivInt->GetValue = RemobGetValue;
|
||||
remob->pDrivInt->Halt = RemobHalt;
|
||||
} else if (remob->pDrivInt) {
|
||||
free(remob->pDrivInt);
|
||||
remob->pDrivInt = NULL;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/*-----------------------------------------------------------------------*/
|
||||
static Remob *RemobInit(char *name, RemServer *remserver) {
|
||||
Remob *remob, *p;
|
||||
|
||||
assert(name);
|
||||
|
||||
/* get memory */
|
||||
remob = (Remob *)calloc(1,sizeof(Remob));
|
||||
if(!remob) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* copy arguments */
|
||||
remob->server = remserver;
|
||||
remob->name = strdup(name);
|
||||
|
||||
/* initialise object descriptor */
|
||||
remob->desc = CreateDescriptor("RemObject");
|
||||
if (!remob->desc) goto killit;
|
||||
remob->desc->GetInterface = RemobGetInterface;
|
||||
remob->desc->SaveStatus = RemobSaveStatus;
|
||||
|
||||
/* initialise callback interface */
|
||||
remob->pCall = CreateCallBackInterface();
|
||||
if(!remob->pCall) goto killit;
|
||||
|
||||
/* check if not yet in object list */
|
||||
for (p = remserver->objList; p != NULL; p=p->next) {
|
||||
if (p == remob) break;
|
||||
}
|
||||
if (p == NULL) {
|
||||
remob->next = remserver->objList;
|
||||
remserver->objList = remob;
|
||||
}
|
||||
|
||||
remob->markForDel = 0;
|
||||
/* done */
|
||||
return remob;
|
||||
killit:
|
||||
RemobKill(remob);
|
||||
return NULL;
|
||||
}
|
||||
/*-----------------------------------------------------------------------*/
|
||||
static RemServer *RemServerInit(char *name, char *host, int port) {
|
||||
RemServer *remserver = NULL;
|
||||
|
||||
assert(name);
|
||||
|
||||
remserver = calloc(1, sizeof(RemServer));
|
||||
if (!remserver) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* initialise object descriptor */
|
||||
remserver->desc = CreateDescriptor("RemServer");
|
||||
if (!remserver->desc) {
|
||||
free(remserver);
|
||||
return NULL;
|
||||
}
|
||||
remserver->desc->SaveStatus = RemServerSaveStatus;
|
||||
remserver->name = strdup(name);
|
||||
remserver->host = strdup(host);
|
||||
remserver->port = port;
|
||||
remserver->incomplete = 0;
|
||||
remserver->objList = NULL;
|
||||
remserver->chans[0] = NULL;
|
||||
remserver->chans[1] = NULL;
|
||||
if (!remserver->name ||
|
||||
!remserver->host ||
|
||||
!remserver->port) {
|
||||
/* no success, clean up */
|
||||
RemServerKill(remserver);
|
||||
return NULL;
|
||||
}
|
||||
remserver->taskActive = 1;
|
||||
TaskRegister(pServ->pTasker, RemServerTask, NULL, RemServerKill, remserver, 1);
|
||||
return remserver;
|
||||
}
|
||||
/*--------------------------------------------------------------------------
|
||||
The Factory function for creating a remote driveable object.
|
||||
|
||||
Usage:
|
||||
Remob server serverName host:port
|
||||
Remob obj remobName serverName
|
||||
Remob drv remobName serverName
|
||||
Remob del remobName
|
||||
Remob del serverName
|
||||
*/
|
||||
|
||||
int RemobCreate(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[]) {
|
||||
RemServer *remserver = NULL;
|
||||
Remob *remob = NULL;
|
||||
char host[128];
|
||||
char *p;
|
||||
int iD, iRet;
|
||||
char *obj;
|
||||
|
||||
assert(pCon);
|
||||
assert(pSics);
|
||||
|
||||
argtolower(argc,argv);
|
||||
if (argc >= 4 && strcmp(argv[1], "server") == 0) {
|
||||
if (argc == 5) {
|
||||
remserver = RemServerInit(argv[2], argv[3], atoi(argv[4]));
|
||||
} else {
|
||||
p = strchr(argv[3], ':');
|
||||
if (!p) {
|
||||
SCPrintf(pCon, eError, "ERROR: illegal host:port");
|
||||
return 0;
|
||||
}
|
||||
snprintf(host, sizeof host, "%.*s", p-argv[3], argv[3]);
|
||||
remserver = RemServerInit(argv[2], host, atoi(p+1));
|
||||
}
|
||||
if (!remserver) {
|
||||
SCPrintf(pCon, eError, "ERROR: Failure to create remote server connection %s", argv[2]);
|
||||
return 0;
|
||||
}
|
||||
/* create the interpreter command */
|
||||
iRet = AddCommand(pSics,argv[2],RemServerAction,RemServerKill,remserver);
|
||||
if (!iRet) {
|
||||
SCPrintf(pCon, eError, "ERROR: duplicate command %s not created",argv[2]);
|
||||
RemServerKill(remserver);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
} else if (argc == 4 && (strcmp(argv[1], "obj") == 0 || strcmp(argv[1], "drv") == 0)) {
|
||||
remserver = FindCommandData(pServ->pSics, argv[3], "RemServer");
|
||||
if (!remserver) {
|
||||
SCPrintf(pCon, eError, "ERROR: remote server %s not found", argv[3]);
|
||||
return 0;
|
||||
}
|
||||
remob = FindCommandData(pServ->pSics, argv[2], "RemObject");
|
||||
if (remob) {
|
||||
if (remob->server == remserver) {
|
||||
RemobSetDriveable(remob, strcmp(argv[1], "drv") == 0);
|
||||
remob->markForDel = 0;
|
||||
return 1; /* object exists already, silent return */
|
||||
}
|
||||
}
|
||||
remob = RemobInit(argv[2], remserver);
|
||||
if (!remob) {
|
||||
SCPrintf(pCon, eError, "ERROR: Failure to create remote object %s", argv[1]);
|
||||
return 0;
|
||||
}
|
||||
RemobSetDriveable(remob, strcmp(argv[1], "drv") == 0);
|
||||
/* create the interpreter command */
|
||||
iRet = AddCommand(pSics,argv[2],RemobAction,RemobKill,remob);
|
||||
SCparChange(pCon);
|
||||
if (!iRet) {
|
||||
SCPrintf(pCon, eError, "ERROR: duplicate command %s not created",argv[2]);
|
||||
RemobKill(remob);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
} else if (argc == 3 && strcmp(argv[1], "del") == 0) {
|
||||
remob = FindCommandData(pSics, argv[2], "RemObject");
|
||||
if (remob) { /* its a remob */
|
||||
if (remob->pDrivInt && pServ->pExecutor && isInRunMode(pServ->pExecutor)) {
|
||||
SCPrintf(pCon,eError,"ERROR: cannot delete %s while running", argv[2]);
|
||||
return 0;
|
||||
}
|
||||
return RemoveCommand(pSics, argv[2]);
|
||||
}
|
||||
if (pServ->pExecutor && isInRunMode(pServ->pExecutor)) {
|
||||
SCPrintf(pCon,eError,"ERROR: cannot delete %s while running", argv[2]);
|
||||
return 0;
|
||||
}
|
||||
remserver = FindCommandData(pSics, argv[2], "RemServer");
|
||||
if (remserver) { /* its a remserver */
|
||||
return RemoveCommand(pSics, argv[2]);
|
||||
}
|
||||
SCWrite(pCon,"ERROR: remob object not found",eError);
|
||||
return 0;
|
||||
}
|
||||
SCPrintf(pCon, eError, "ERROR: illegal arguments for command remob");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
19
remob.h
19
remob.h
@ -1,19 +0,0 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
remote driveable objects
|
||||
|
||||
Markus Zolliker July 04
|
||||
|
||||
copyright: see implementation file
|
||||
|
||||
----------------------------------------------------------------------------*/
|
||||
#ifndef SICSREM
|
||||
#define SICSREM
|
||||
#include "Scommon.h"
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
int RemobCreate(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[]);
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user