- more AsconStatus states
- enhancements in binprot - make Logger public (logger.h) - added lscprot (50 ms write delay for lakeshore models) - additonal bug fixes
This commit is contained in:
3
ascon.c
3
ascon.c
@ -669,6 +669,7 @@ Ascon *AsconMake(SConnection * con, int argc, char *argv[])
|
|||||||
a->responseValid = 0;
|
a->responseValid = 0;
|
||||||
a->readState = 0;
|
a->readState = 0;
|
||||||
a->lineCount = 1;
|
a->lineCount = 1;
|
||||||
|
a->separator = NULL;
|
||||||
a->killPrivate = NULL;
|
a->killPrivate = NULL;
|
||||||
a->private = NULL;
|
a->private = NULL;
|
||||||
|
|
||||||
@ -752,7 +753,7 @@ AsconStatus AsconTask(Ascon * a)
|
|||||||
case AsconNotConnected:
|
case AsconNotConnected:
|
||||||
return AsconOffline;
|
return AsconOffline;
|
||||||
case AsconConnecting:
|
case AsconConnecting:
|
||||||
return AsconUnconnected;
|
return AsconConnectPending;
|
||||||
case AsconConnectDone:
|
case AsconConnectDone:
|
||||||
a->state = AsconIdle;
|
a->state = AsconIdle;
|
||||||
DynStringClear(a->errmsg); /* connection o.k. */
|
DynStringClear(a->errmsg); /* connection o.k. */
|
||||||
|
1
ascon.h
1
ascon.h
@ -17,6 +17,7 @@ typedef struct Ascon Ascon;
|
|||||||
typedef enum {
|
typedef enum {
|
||||||
AsconOffline,
|
AsconOffline,
|
||||||
AsconUnconnected,
|
AsconUnconnected,
|
||||||
|
AsconConnectPending,
|
||||||
AsconPending,
|
AsconPending,
|
||||||
AsconReady,
|
AsconReady,
|
||||||
AsconFailure /* codes after this indicate also failure */
|
AsconFailure /* codes after this indicate also failure */
|
||||||
|
48
binprot.c
48
binprot.c
@ -27,6 +27,7 @@
|
|||||||
*
|
*
|
||||||
* and formatItem is one of the follwing
|
* and formatItem is one of the follwing
|
||||||
*
|
*
|
||||||
|
* a number (decimal format): returned byte must match (else error)
|
||||||
* skip skip one byte
|
* skip skip one byte
|
||||||
* skip<n> skip <n> bytes
|
* skip<n> skip <n> bytes
|
||||||
* code returned function code, when bit7 is set, the response is
|
* code returned function code, when bit7 is set, the response is
|
||||||
@ -39,6 +40,7 @@
|
|||||||
* and append it to the response
|
* and append it to the response
|
||||||
* float convert 4 bytes from ieee float
|
* float convert 4 bytes from ieee float
|
||||||
* and append the number to the response
|
* and append the number to the response
|
||||||
|
* dump read all bytes in read buffer as hex (only for tests)
|
||||||
* crc check crc (if wrong, "badCRC" is added to the response)
|
* crc check crc (if wrong, "badCRC" is added to the response)
|
||||||
*
|
*
|
||||||
* multiple items in the response are space separated
|
* multiple items in the response are space separated
|
||||||
@ -49,16 +51,16 @@
|
|||||||
*
|
*
|
||||||
* sct send 250 3 int2 10 2 crc / skip code skip float crc
|
* sct send 250 3 int2 10 2 crc / skip code skip float crc
|
||||||
*
|
*
|
||||||
* different crc's might be used (argv[2] opf BinInit):
|
* different crc's might be used (argv[2] of BinInit):
|
||||||
* modbus-crc: CRC-16-IBM, order: lo,hi
|
* modbus-crc: CRC-16-IBM, order: lo,hi
|
||||||
* keller-crc: CRC-16-IBM, order: hi,lo
|
* keller-crc: CRC-16-IBM, order: hi,lo
|
||||||
* sycon-crc: sort of mod 256 checksum, byte stuffing included (no float allowed)
|
* sycon-crc: sort of mod 256 checksum, byte stuffing included (no float allowed)
|
||||||
* chksum-crc: simple 8bit checksum
|
* chksum-crc: simple 8bit checksum
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef enum {intType, hexType, floatType,
|
typedef enum {intType, hexType, floatType, skipType, codeType, checkType,
|
||||||
skipType, codeType, crcType, dumpType, errorType} BinDataType;
|
crcType, dumpType, endType, errorType} BinDataType;
|
||||||
// dumpType, errorType must be the last items
|
// dumpType, endType, errorType must be the last items
|
||||||
|
|
||||||
typedef enum {modbusCrc, kellerCrc, rsportCrc, syconCrc, chksumCrc} CrcAlgorithm;
|
typedef enum {modbusCrc, kellerCrc, rsportCrc, syconCrc, chksumCrc} CrcAlgorithm;
|
||||||
|
|
||||||
@ -164,7 +166,7 @@ int BinReadItem(Ascon *a) {
|
|||||||
if (sscanf(p->nextFmt, "%30s%n", item, &valen) <= 0) {
|
if (sscanf(p->nextFmt, "%30s%n", item, &valen) <= 0) {
|
||||||
if (p->type < dumpType) {
|
if (p->type < dumpType) {
|
||||||
p->dumpFrom = GetDynStringLength(a->rdBuffer);
|
p->dumpFrom = GetDynStringLength(a->rdBuffer);
|
||||||
p->type= dumpType;
|
p->type = endType;
|
||||||
}
|
}
|
||||||
p->expectedChars = 999;
|
p->expectedChars = 999;
|
||||||
return 0;
|
return 0;
|
||||||
@ -193,13 +195,22 @@ int BinReadItem(Ascon *a) {
|
|||||||
p->type = hexType;
|
p->type = hexType;
|
||||||
} else if (strcasecmp(item, "code") == 0) {
|
} else if (strcasecmp(item, "code") == 0) {
|
||||||
p->type = codeType;
|
p->type = codeType;
|
||||||
|
} else if (strcasecmp(item, "dump") == 0) {
|
||||||
|
p->dumpFrom = GetDynStringLength(a->rdBuffer);
|
||||||
|
p->type = dumpType;
|
||||||
} else if (strncasecmp(item, "skip", 4) == 0) {
|
} else if (strncasecmp(item, "skip", 4) == 0) {
|
||||||
size = 1;
|
size = 1;
|
||||||
sscanf(item + 4, "%d", &size);
|
sscanf(item + 4, "%d", &size);
|
||||||
p->expectedChars = size;
|
p->expectedChars = size;
|
||||||
p->type = skipType;
|
p->type = skipType;
|
||||||
} else {
|
} else {
|
||||||
return -1;
|
p->iValue = 0;
|
||||||
|
if (1 == sscanf(item, "%ld", &p->iValue)) {
|
||||||
|
p->expectedChars = 1;
|
||||||
|
p->type = checkType;
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
p->nextFmt += valen;
|
p->nextFmt += valen;
|
||||||
return 1;
|
return 1;
|
||||||
@ -268,6 +279,7 @@ int BinHandler(Ascon *a) {
|
|||||||
int valen;
|
int valen;
|
||||||
BinDataType type;
|
BinDataType type;
|
||||||
long iValue;
|
long iValue;
|
||||||
|
unsigned long uValue;
|
||||||
double fValue;
|
double fValue;
|
||||||
BinPrivate *p = a->private;
|
BinPrivate *p = a->private;
|
||||||
|
|
||||||
@ -327,11 +339,12 @@ int BinHandler(Ascon *a) {
|
|||||||
BinError(a, "invalid integer");
|
BinError(a, "invalid integer");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
uValue = iValue;
|
||||||
for (i = size - 1; i >= 0; i--) {
|
for (i = size - 1; i >= 0; i--) {
|
||||||
if (i < sizeof data) {
|
if (i < sizeof data) {
|
||||||
data[i] = iValue % 256;
|
data[i] = uValue % 256;
|
||||||
}
|
}
|
||||||
iValue /= 256;
|
uValue >>= 8;
|
||||||
}
|
}
|
||||||
for (i = 0; i < size; i++) {
|
for (i = 0; i < size; i++) {
|
||||||
if (i >= sizeof data) {
|
if (i >= sizeof data) {
|
||||||
@ -411,7 +424,11 @@ int BinHandler(Ascon *a) {
|
|||||||
snprintf(item, sizeof item, "%2.2x ", (str[i] & 255));
|
snprintf(item, sizeof item, "%2.2x ", (str[i] & 255));
|
||||||
DynStringConcat(p->result, item);
|
DynStringConcat(p->result, item);
|
||||||
}
|
}
|
||||||
if (p->type == errorType) {
|
if (p->type == endType && p->dumpFrom < l) {
|
||||||
|
DynStringCopy(a->errmsg, "BINERR: superflous chars ");
|
||||||
|
DynStringConcat(a->errmsg, GetCharArray(p->result));
|
||||||
|
a->state = AsconFailed;
|
||||||
|
} else if (p->type == errorType) {
|
||||||
DynStringConcat(a->errmsg, GetCharArray(p->result));
|
DynStringConcat(a->errmsg, GetCharArray(p->result));
|
||||||
a->state = AsconFailed;
|
a->state = AsconFailed;
|
||||||
} else {
|
} else {
|
||||||
@ -492,6 +509,7 @@ int BinHandler(Ascon *a) {
|
|||||||
DynStringCopy(p->result, item);
|
DynStringCopy(p->result, item);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case endType:
|
||||||
case dumpType:
|
case dumpType:
|
||||||
break;
|
break;
|
||||||
case skipType:
|
case skipType:
|
||||||
@ -555,6 +573,16 @@ int BinHandler(Ascon *a) {
|
|||||||
/* subtract CRC char (undo the addition) and subtract crc higher four bits */
|
/* subtract CRC char (undo the addition) and subtract crc higher four bits */
|
||||||
p->chksum -= a->lastChar + (a->lastChar & 0x0f) * 16;
|
p->chksum -= a->lastChar + (a->lastChar & 0x0f) * 16;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case checkType:
|
||||||
|
p->expectedChars--;
|
||||||
|
if ((a->lastChar & 255) != p->iValue) {
|
||||||
|
DynStringCopy(a->errmsg, "BINERR: mismatch ");
|
||||||
|
p->type = errorType;
|
||||||
|
p->dumpFrom = 0;
|
||||||
|
/* skip to end */
|
||||||
|
p->nextFmt = "";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (p->expectedChars <= 0) {
|
if (p->expectedChars <= 0) {
|
||||||
BinReadItem(a);
|
BinReadItem(a);
|
||||||
|
1
devser.c
1
devser.c
@ -580,6 +580,7 @@ char *DevStatus(DevSer *devser) {
|
|||||||
switch (devser->status) {
|
switch (devser->status) {
|
||||||
case AsconOffline: return "disconnected";
|
case AsconOffline: return "disconnected";
|
||||||
case AsconUnconnected: return "unconnected";
|
case AsconUnconnected: return "unconnected";
|
||||||
|
case AsconConnectPending: return "connecting";
|
||||||
/*
|
/*
|
||||||
case AsconPending: return "busy";
|
case AsconPending: return "busy";
|
||||||
case AsconReady: return "ready";
|
case AsconReady: return "ready";
|
||||||
|
21
logger.c
21
logger.c
@ -15,18 +15,6 @@ Markus Zolliker, Sept 2004
|
|||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
|
|
||||||
struct Logger {
|
|
||||||
char *name;
|
|
||||||
char *old;
|
|
||||||
int oldsize;
|
|
||||||
int period;
|
|
||||||
time_t last, lastWrite, omitTime;
|
|
||||||
int numeric;
|
|
||||||
float omitValue;
|
|
||||||
int exact;
|
|
||||||
Logger *next;
|
|
||||||
};
|
|
||||||
|
|
||||||
static char *dir = NULL;
|
static char *dir = NULL;
|
||||||
static Logger *list;
|
static Logger *list;
|
||||||
static time_t lastLife = 0;
|
static time_t lastLife = 0;
|
||||||
@ -152,6 +140,7 @@ int LoggerWrite0(Logger * log, time_t now, int period, char *value)
|
|||||||
int l, ext, writeInfo;
|
int l, ext, writeInfo;
|
||||||
FILE *fil;
|
FILE *fil;
|
||||||
time_t beforenow;
|
time_t beforenow;
|
||||||
|
char *nl;
|
||||||
|
|
||||||
if (log->name[0] == '\0')
|
if (log->name[0] == '\0')
|
||||||
return 0;
|
return 0;
|
||||||
@ -211,7 +200,13 @@ int LoggerWrite0(Logger * log, time_t now, int period, char *value)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
strftime(stim, sizeof stim, "%H:%M:%S", &tm);
|
strftime(stim, sizeof stim, "%H:%M:%S", &tm);
|
||||||
fprintf(fil, "%s\t%s\n", stim, value);
|
nl = strchr(value, '\n');
|
||||||
|
if (nl == NULL) {
|
||||||
|
fprintf(fil, "%s\t%s\n", stim, value);
|
||||||
|
} else {
|
||||||
|
/* newline within string! do write only characters before nl */
|
||||||
|
fprintf(fil, "%s\t%.*s\n", stim, (nl - value), value);
|
||||||
|
}
|
||||||
log->lastWrite = now;
|
log->lastWrite = now;
|
||||||
fclose(fil);
|
fclose(fil);
|
||||||
|
|
||||||
|
15
logger.h
15
logger.h
@ -10,7 +10,20 @@ Markus Zolliker, Sept 2004
|
|||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
typedef struct Logger Logger;
|
typedef struct Logger {
|
||||||
|
/* public */
|
||||||
|
char *name;
|
||||||
|
int numeric;
|
||||||
|
int period;
|
||||||
|
int exact;
|
||||||
|
/* private: */
|
||||||
|
char *old;
|
||||||
|
int oldsize;
|
||||||
|
time_t last, lastWrite, omitTime;
|
||||||
|
float omitValue;
|
||||||
|
struct Logger *next;
|
||||||
|
} Logger;
|
||||||
|
|
||||||
|
|
||||||
Logger *LoggerMake(char *name, int period, int exact);
|
Logger *LoggerMake(char *name, int period, int exact);
|
||||||
void LoggerKill(Logger * log);
|
void LoggerKill(Logger * log);
|
||||||
|
101
lscprot.c
Normal file
101
lscprot.c
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
#include "ascon.h"
|
||||||
|
#include "ascon.i"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* script context protocol for LakeShore 370 / 340 etc. models
|
||||||
|
* a 50 msec waiting time is needed after each reply / command
|
||||||
|
*
|
||||||
|
* Markus Zolliker May 2016
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
double last;
|
||||||
|
double delay;
|
||||||
|
} LscPrivate;
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
int LscProtHandler(Ascon *a)
|
||||||
|
{
|
||||||
|
LscPrivate *p;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
if (a->state == AsconWriteStart) {
|
||||||
|
p = a->private;
|
||||||
|
if (DoubleTime() < p->last + p->delay) { // 50 msec
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
res = AsconStdHandler(a);
|
||||||
|
if (a->state == AsconReadDone) {
|
||||||
|
p = a->private;
|
||||||
|
p->last = DoubleTime();
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
static void LscPrivateKill(void *p) {
|
||||||
|
free(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
int LscProtInit(Ascon *a, SConnection *con, int argc, char *argv[])
|
||||||
|
{
|
||||||
|
enum nPars {NA=4};
|
||||||
|
char *pars[NA];
|
||||||
|
static char *parn[NA]={
|
||||||
|
"sendterminator",
|
||||||
|
"timeout",
|
||||||
|
"replyterminator",
|
||||||
|
"writedelay"
|
||||||
|
};
|
||||||
|
char *msg;
|
||||||
|
LscPrivate *p;
|
||||||
|
|
||||||
|
assert(argc>1);
|
||||||
|
a->hostport = strdup(argv[1]);
|
||||||
|
|
||||||
|
if (!AsconInterpreteArgs(argc-2, argv+2, NA, parn, pars)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
p = calloc(sizeof(*p), 1);
|
||||||
|
if (p == NULL) return 0;
|
||||||
|
|
||||||
|
p->last = DoubleTime();
|
||||||
|
a->private = p;
|
||||||
|
a->killPrivate = LscPrivateKill;
|
||||||
|
|
||||||
|
if (pars[0]) {
|
||||||
|
a->sendTerminator = strdup(pars[0]);
|
||||||
|
} else {
|
||||||
|
a->sendTerminator = strdup("\n");
|
||||||
|
}
|
||||||
|
if (pars[1] && pars[1][0] != '\0') {
|
||||||
|
a->timeout = atof(pars[1]);
|
||||||
|
} else {
|
||||||
|
a->timeout = 2.0; /* sec */
|
||||||
|
}
|
||||||
|
if (pars[2] && pars[2][0] != '\0') {
|
||||||
|
a->replyTerminator = strdup(pars[2]);
|
||||||
|
} else {
|
||||||
|
a->replyTerminator = NULL;
|
||||||
|
}
|
||||||
|
if (pars[3] && pars[3][0] != '\0') {
|
||||||
|
p->delay = atof(pars[3]);
|
||||||
|
} else {
|
||||||
|
p->delay = 0.05;
|
||||||
|
}
|
||||||
|
AsconCheckTerminators(a);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
void AddLscProtocol()
|
||||||
|
{
|
||||||
|
static AsconProtocol lscprot;
|
||||||
|
lscprot.name = "lsc";
|
||||||
|
lscprot.handler = LscProtHandler;
|
||||||
|
lscprot.init = LscProtInit;
|
||||||
|
AsconInsertProtocol(&lscprot);
|
||||||
|
}
|
2
make_gen
2
make_gen
@ -45,7 +45,7 @@ SOBJ = network.o ifile.o conman.o SCinter.o splitter.o passwd.o \
|
|||||||
singlenb.o simindex.o simidx.o uselect.o singletas.o motorsec.o \
|
singlenb.o simindex.o simidx.o uselect.o singletas.o motorsec.o \
|
||||||
rwpuffer.o asynnet.o background.o countersec.o hdbtable.o velosec.o \
|
rwpuffer.o asynnet.o background.o countersec.o hdbtable.o velosec.o \
|
||||||
histmemsec.o sansbc.o sicsutil.o strlutil.o genbinprot.o trace.o\
|
histmemsec.o sansbc.o sicsutil.o strlutil.o genbinprot.o trace.o\
|
||||||
singlebinb.o taskobj.o sctcomtask.o tasmono.o multicountersec.o \
|
singlebinb.o taskobj.o sctcomtask.o tasmono.o multicountersec.o lscprot.o \
|
||||||
messagepipe.o sicsget.o remoteobject.o pmacprot.o charbychar.o binprot.o \
|
messagepipe.o sicsget.o remoteobject.o pmacprot.o charbychar.o binprot.o \
|
||||||
cnvrt.o tclClock.o tclDate.o tclUnixTime.o stack_trace.o logv2.o outcode.o
|
cnvrt.o tclClock.o tclDate.o tclUnixTime.o stack_trace.o logv2.o outcode.o
|
||||||
|
|
||||||
|
1
ofac.c
1
ofac.c
@ -51,6 +51,7 @@ static void InitGeneral(void)
|
|||||||
INIT(AddBinProtocol);
|
INIT(AddBinProtocol);
|
||||||
INIT(AddPMACProtocoll);
|
INIT(AddPMACProtocoll);
|
||||||
INIT(AddCharByCharProtocoll);
|
INIT(AddCharByCharProtocoll);
|
||||||
|
INIT(AddLscProtocol);
|
||||||
INIT(MakeTrace);
|
INIT(MakeTrace);
|
||||||
INIT(InitTaskOBJ);
|
INIT(InitTaskOBJ);
|
||||||
INIT(RemoteObjectInit);
|
INIT(RemoteObjectInit);
|
||||||
|
Reference in New Issue
Block a user