add oxford protocol
r2961 | dcl | 2010-06-25 15:10:25 +1000 (Fri, 25 Jun 2010) | 2 lines
This commit is contained in:
@@ -10,7 +10,7 @@ SRC = .
|
||||
CC = gcc
|
||||
CFLAGS = -g -DLINUX $(DFORTIFY) -I$(SRC) -I../.. -Wall -Wno-unused -Wextra
|
||||
|
||||
HOBJ= nhq200util.o itc4util.o lh45util.o lakeshore340util.o west4100util.o asynsrv_utility.o geterrno.o strjoin.o chopper.o modbustcp.o sct_galilprot.o sct_modbusprot.o sct_orhvpsprot.o sct_velselprot.o sct_usbtmcprot.o sct_rfamp.o sinqhttpprot.o sct_protek608.o
|
||||
HOBJ= nhq200util.o itc4util.o lh45util.o lakeshore340util.o west4100util.o asynsrv_utility.o geterrno.o strjoin.o chopper.o modbustcp.o sct_galilprot.o sct_modbusprot.o sct_oxfordprot.o sct_orhvpsprot.o sct_velselprot.o sct_usbtmcprot.o sct_rfamp.o sinqhttpprot.o sct_protek608.o
|
||||
|
||||
libhlib.a: $(HOBJ)
|
||||
rm -f libhlib.a
|
||||
|
||||
@@ -18,23 +18,90 @@
|
||||
#include <ascon.i>
|
||||
#include <dynstring.h>
|
||||
|
||||
struct OxfordProtocol_t {
|
||||
unsigned int magic;
|
||||
Ascon* parent;
|
||||
double last_line_time;
|
||||
double last_char_time;
|
||||
double inter_line_time;
|
||||
double inter_char_time;
|
||||
};
|
||||
typedef struct OxfordProtocol_t OxfordProtocol;
|
||||
|
||||
struct OxfordQProtocol_t {
|
||||
unsigned int magic;
|
||||
Ascon* parent;
|
||||
double last_line_time;
|
||||
double last_char_time;
|
||||
double inter_line_time;
|
||||
double inter_char_time;
|
||||
};
|
||||
typedef struct OxfordQProtocol_t OxfordQProtocol;
|
||||
|
||||
/** @brief Set line terminator before sending command
|
||||
*/
|
||||
int OxfordWriteStart(Ascon *a) {
|
||||
OxfordProtocol* private;
|
||||
double now;
|
||||
private = (OxfordProtocol*) a->private;
|
||||
assert(private->magic == 0xcafef00d);
|
||||
now = DoubleTime();
|
||||
if (now < private->last_line_time) {
|
||||
private->last_line_time = now;
|
||||
}
|
||||
private->last_char_time = now;
|
||||
/*
|
||||
if (now > private->last_line_time + private->inter_line_time) {
|
||||
return 1;
|
||||
}
|
||||
*/
|
||||
DynStringConcat(a->wrBuffer,"\r");
|
||||
a->state = AsconWriting;
|
||||
a->wrPos = 0;
|
||||
a->state = AsconWriting;
|
||||
/* if there is only the terminator, do not send it */
|
||||
if (GetDynStringLength(a->wrBuffer) <= 1) {
|
||||
a->state = AsconWriteDone;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** @brief Write the line one character at a time
|
||||
*/
|
||||
int OxfordWriting(Ascon *a) {
|
||||
OxfordProtocol* private;
|
||||
int ret;
|
||||
double now;
|
||||
private = (OxfordProtocol*) a->private;
|
||||
assert(private->magic == 0xcafef00d);
|
||||
now = DoubleTime();
|
||||
if (now < private->last_char_time) {
|
||||
private->last_char_time = now;
|
||||
}
|
||||
if (now < private->last_char_time + private->inter_char_time) {
|
||||
return 1;
|
||||
}
|
||||
if (a->wrPos == 0)
|
||||
AsconReadGarbage(a->fd);
|
||||
ret = AsconWriteChars(a->fd, GetCharArray(a->wrBuffer) + a->wrPos, 1);
|
||||
if (ret < 0) {
|
||||
AsconError(a, "send failed:", errno);
|
||||
/*
|
||||
* Ooops: which state shall we go to after a write fail?
|
||||
* This seems to retry.
|
||||
*/
|
||||
} else {
|
||||
private->last_char_time = now;
|
||||
a->wrPos += ret;
|
||||
if (a->wrPos >= GetDynStringLength(a->wrBuffer)) {
|
||||
private->last_line_time = now;
|
||||
a->state = AsconWriteDone;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** @brief Map oxford replies to OK, ASCERR:..., value.
|
||||
* You can use the first character to sort replies from a oxford controller
|
||||
* into four categories
|
||||
* First character is,
|
||||
* 'SPACE' This is followed by a value
|
||||
* '?' Error, use 'TC 1' to get error code and message.
|
||||
* ':' Command received, in response to commands which don't request data.
|
||||
* '1-9' First digit of error-code followed by error message. (in response to 'TC 1')
|
||||
*/
|
||||
int OxfordReading(Ascon *a) {
|
||||
int ret;
|
||||
@@ -43,37 +110,35 @@ int OxfordReading(Ascon *a) {
|
||||
|
||||
ret = AsconReadChar(a->fd, &chr);
|
||||
while (ret > 0) {
|
||||
a->start = DoubleTime();
|
||||
|
||||
if (chr != '\r') {
|
||||
DynStringConcatChar(a->rdBuffer, chr);
|
||||
ret = AsconReadChar(a->fd, &chr);
|
||||
}
|
||||
else {
|
||||
cp = GetCharArray(a->rdBuffer);
|
||||
chr = *cp;
|
||||
if (*cp == '?') { /* command was in error */
|
||||
a->state = AsconIdle;
|
||||
#if 0
|
||||
AsconError(a, GetCharArray(a->rdBuffer), 0);
|
||||
#else
|
||||
DynStringInsert(a->rdBuffer, "ASCERR:", 0);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
else if (GetDynStringLength(a->rdBuffer) == 1) { /* command was successful */
|
||||
DynStringReplace(a->rdBuffer, "OK", 0);
|
||||
a->state = AsconReadDone;
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
a->state = AsconReadDone;
|
||||
return 1;
|
||||
a->state = AsconReadDone;
|
||||
break;
|
||||
}
|
||||
ret = AsconReadChar(a->fd, &chr);
|
||||
}
|
||||
if (ret < 0) {
|
||||
AsconError(a, "AsconReadChar failed:", errno);
|
||||
return 0;
|
||||
}
|
||||
if (a->state == AsconReadDone) {
|
||||
DynStringConcatChar(a->rdBuffer, '\0');
|
||||
} else {
|
||||
if (a->timeout > 0) {
|
||||
if (DoubleTime() - a->start > a->timeout) {
|
||||
AsconError(a, "read timeout", 0);
|
||||
a->state = AsconTimeout;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** brief Oxford protocol handler.
|
||||
/** @brief Oxford protocol handler.
|
||||
* This handler formats commands (ie adds cr line terminator) and
|
||||
* sorts replies into standard responses of
|
||||
* <value>
|
||||
@@ -88,6 +153,10 @@ int OxfordProtHandler(Ascon *a) {
|
||||
ret = OxfordWriteStart(a);
|
||||
return ret;
|
||||
break;
|
||||
case AsconWriting:
|
||||
ret = OxfordWriting(a);
|
||||
return ret;
|
||||
break;
|
||||
case AsconReading:
|
||||
ret = OxfordReading(a);
|
||||
return ret;
|
||||
@@ -99,12 +168,87 @@ int OxfordProtHandler(Ascon *a) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
void AddOxfordProtocoll(){
|
||||
AsconProtocol *prot = NULL;
|
||||
|
||||
prot = calloc(sizeof(AsconProtocol), 1);
|
||||
prot->name = strdup("oxford");
|
||||
prot->init = AsconStdInit;
|
||||
prot->handler = OxfordProtHandler;
|
||||
AsconInsertProtocol(prot);
|
||||
int OxfordQProtHandler(Ascon *a) {
|
||||
int ret;
|
||||
|
||||
switch(a->state){
|
||||
case AsconWriteStart:
|
||||
ret = OxfordWriteStart(a);
|
||||
return ret;
|
||||
break;
|
||||
case AsconWriting:
|
||||
ret = OxfordWriting(a);
|
||||
return ret;
|
||||
break;
|
||||
case AsconReading:
|
||||
ret = OxfordReading(a);
|
||||
return ret;
|
||||
break;
|
||||
default:
|
||||
ret = AsconStdHandler(a);
|
||||
return ret;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void OxfordKillPrivate(void *arg) {
|
||||
OxfordProtocol *private = (OxfordProtocol *) arg;
|
||||
assert(private->magic == 0xcafef00d);
|
||||
assert(private->parent->private == private);
|
||||
private->magic = 0;
|
||||
free(arg);
|
||||
}
|
||||
|
||||
void OxfordQKillPrivate(void *arg) {
|
||||
OxfordQProtocol *private = (OxfordQProtocol *) arg;
|
||||
assert(private->magic == 0xcafef00d);
|
||||
assert(private->parent->private == private);
|
||||
private->magic = 0;
|
||||
free(arg);
|
||||
}
|
||||
|
||||
int OxfordInit(Ascon *a, SConnection *con,
|
||||
int argc, char *argv[]) {
|
||||
OxfordProtocol *private;
|
||||
int ret;
|
||||
ret = AsconStdInit(a, con, argc, argv);
|
||||
private = calloc(sizeof(OxfordProtocol), 1);
|
||||
a->private = (void *) private;
|
||||
private->magic = 0xcafef00d;
|
||||
private->parent = a;
|
||||
private->inter_line_time = 0.100;
|
||||
private->inter_char_time = 0.010;
|
||||
a->killPrivate = OxfordKillPrivate;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int OxfordQInit(Ascon *a, SConnection *con,
|
||||
int argc, char *argv[]) {
|
||||
OxfordQProtocol *private;
|
||||
int ret;
|
||||
ret = AsconStdInit(a, con, argc, argv);
|
||||
private = calloc(sizeof(OxfordQProtocol), 1);
|
||||
a->private = (void *) private;
|
||||
private->magic = 0xcafef00d;
|
||||
private->parent = a;
|
||||
private->inter_line_time = 0.100;
|
||||
private->inter_char_time = 0.010;
|
||||
a->killPrivate = OxfordQKillPrivate;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void AddOxfordProtocoll(){
|
||||
AsconProtocol *prot = NULL;
|
||||
|
||||
prot = calloc(sizeof(AsconProtocol), 1);
|
||||
prot->name = strdup("oxford");
|
||||
prot->init = OxfordInit;
|
||||
prot->handler = OxfordProtHandler;
|
||||
AsconInsertProtocol(prot);
|
||||
|
||||
prot = calloc(sizeof(AsconProtocol), 1);
|
||||
prot->name = strdup("oxfordq");
|
||||
prot->init = OxfordQInit;
|
||||
prot->handler = OxfordQProtHandler;
|
||||
AsconInsertProtocol(prot);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user