- added AsconHostport function

- added composite terminator in standard protocol
This commit is contained in:
zolliker
2012-06-19 06:31:06 +00:00
parent 3141f63f20
commit 36d1204da0
3 changed files with 70 additions and 11 deletions

56
ascon.c
View File

@ -71,7 +71,8 @@ void AsconError(Ascon *a, char *msg, int errorno)
"timeout" "timeout"
}; };
char *state; char *state;
char num[8];
if (a->state < 0 || a->state >= AsconMaxState) { if (a->state < 0 || a->state >= AsconMaxState) {
state = "bad state"; state = "bad state";
} else { } else {
@ -128,8 +129,10 @@ static void AsconConnect(Ascon * a)
return; return;
} }
colon = strchr(a->hostport, ':'); colon = strchr(a->hostport, ':');
if (colon == NULL) if (colon == NULL) {
AsconError(a, "expected 'host:port' or 'unconnected'", 0);
return; return;
}
port = atoi(colon + 1); port = atoi(colon + 1);
if (port <= 0) { if (port <= 0) {
AsconError(a, "bad port number", 0); AsconError(a, "bad port number", 0);
@ -321,6 +324,7 @@ int AsconBaseHandler(Ascon * a)
if (ret == 0) { if (ret == 0) {
/* in progress */ /* in progress */
} else if (ret > 0) { } else if (ret > 0) {
DynStringClear(a->errmsg);
a->state = AsconConnectDone; /* success */ a->state = AsconConnectDone; /* success */
} else if (ret < 0) { } else if (ret < 0) {
AsconError(a, "ASC3", errno); AsconError(a, "ASC3", errno);
@ -419,7 +423,7 @@ int AsconStdHandler(Ascon * a)
int result; int result;
char chr; char chr;
int ret, l; int ret, l;
char *cmd, *opt; char *cmd, *opt, *buf;
switch (a->state) { switch (a->state) {
case AsconWriteStart: case AsconWriteStart:
@ -464,9 +468,18 @@ int AsconStdHandler(Ascon * a)
} }
if (a->replyTerminator != NULL) { if (a->replyTerminator != NULL) {
if (strchr(a->replyTerminator, chr) != NULL) { if (strchr(a->replyTerminator, chr) != NULL) {
a->state = AsconReadDone; if (a->compositeTerminator) {
if (chr == '\n' || chr == '\r') { /* one character was o.k., but all have to match */
DynStringBackspace(a->rdBuffer); /* remove LF or CR */ l = strlen(a->replyTerminator);
buf = GetCharArray(a->rdBuffer) + GetDynStringLength(a->rdBuffer) - l;
if (strncmp(buf, a->replyTerminator, l) == 0) {
a->state = AsconReadDone;
}
} else {
a->state = AsconReadDone;
if (chr == '\n' || chr == '\r') {
DynStringBackspace(a->rdBuffer); /* remove LF or CR */
}
} }
} }
} else { } else {
@ -502,10 +515,13 @@ int AsconStdHandler(Ascon * a)
* Treat hex strings as terminators right. Note that this * Treat hex strings as terminators right. Note that this
* is limited to single character terminators. * is limited to single character terminators.
* M.Z. changed strstr to strncmp (more precise) * M.Z. changed strstr to strncmp (more precise)
*
* M.Z. add new option (composite terminator):
* convert 'term' to term
*/ */
static void AsconCheckTerminators(Ascon *a) void AsconCheckTerminators(Ascon *a)
{ {
int c; int c, i, l;
if (a->sendTerminator != NULL && strncmp(a->sendTerminator,"0x",2) == 0) { if (a->sendTerminator != NULL && strncmp(a->sendTerminator,"0x",2) == 0) {
sscanf(a->sendTerminator,"%x",&c); sscanf(a->sendTerminator,"%x",&c);
@ -517,6 +533,17 @@ static void AsconCheckTerminators(Ascon *a)
a->replyTerminator[0] = (char)c; a->replyTerminator[0] = (char)c;
a->replyTerminator[1] = '\0'; a->replyTerminator[1] = '\0';
} }
a->compositeTerminator = 0;
if (a->replyTerminator != NULL && a->replyTerminator[0] == '\'') {
l = strlen(a->replyTerminator);
if (l > 2 && a->replyTerminator[l-1] == '\'') {
for (i = 0; i < l - 2; i++) {
a->replyTerminator[i] = a->replyTerminator[i+1];
}
a->replyTerminator[l-2] = '\0';
a->compositeTerminator = 1;
}
}
} }
int AsconInterpreteArgs(int argc, char *argv[], int AsconInterpreteArgs(int argc, char *argv[],
@ -715,6 +742,7 @@ AsconStatus AsconTask(Ascon * a)
return AsconUnconnected; return AsconUnconnected;
case AsconConnectDone: case AsconConnectDone:
a->state = AsconIdle; a->state = AsconIdle;
DynStringClear(a->errmsg); /* connection o.k. */
return AsconReady; return AsconReady;
case AsconWriteDone: case AsconWriteDone:
if (a->noResponse) { if (a->noResponse) {
@ -731,6 +759,7 @@ AsconStatus AsconTask(Ascon * a)
case AsconReadDone: case AsconReadDone:
a->state = AsconIdle; a->state = AsconIdle;
a->responseValid = 1; a->responseValid = 1;
DynStringClear(a->errmsg);
return AsconReady; return AsconReady;
case AsconIdle: case AsconIdle:
return AsconReady; return AsconReady;
@ -794,5 +823,14 @@ char *AsconGetError(Ascon *a)
int AsconLastState(Ascon *a) int AsconLastState(Ascon *a)
{ {
return (int)a->state; return (int)a->state;
} }
char *AsconHostport(Ascon *a)
{
if (a==NULL) {
return NULL;
}
return a->hostport;
}

11
ascon.h
View File

@ -19,7 +19,7 @@ typedef enum {
AsconUnconnected, AsconUnconnected,
AsconPending, AsconPending,
AsconReady, AsconReady,
AsconFailure AsconFailure /* codes after this indicate also failure */
} AsconStatus; } AsconStatus;
/** \brief make a new asynchronous connection /** \brief make a new asynchronous connection
@ -96,8 +96,15 @@ void AsconError(Ascon *a, char *msg, int errorno);
/** /**
* \brief return the last ascon state. Only used for statistics * \brief return the last ascon state. Only used for statistics
* \param a The Adcon to query * \param a The Ascon to query
* \return the AsconState as an integer. * \return the AsconState as an integer.
*/ */
int AsconLastState(Ascon *a); int AsconLastState(Ascon *a);
/**
* \brief return host:port
* \param a The Ascon to query
* \return the host and port
*/
char *AsconHostport(Ascon *a);
#endif #endif

14
ascon.i
View File

@ -55,6 +55,7 @@ typedef int (* AsconHandler)(Ascon *connection);
struct Ascon { struct Ascon {
AsconState state; /**< the current state */ AsconState state; /**< the current state */
int fd; /**< socket */ int fd; /**< socket */
int conState; /**< 1: connection refused, 0: else */
int readState; /**< (std) last char was CR */ int readState; /**< (std) last char was CR */
pDynString rdBuffer; /**< read buffer */ pDynString rdBuffer; /**< read buffer */
pDynString wrBuffer; /**< write buffer */ pDynString wrBuffer; /**< write buffer */
@ -73,6 +74,7 @@ struct Ascon {
char lastChar; /**< last char read */ char lastChar; /**< last char read */
char *separator; /**< (std) separator for multiline responses */ char *separator; /**< (std) separator for multiline responses */
int lineCount; /**< number of lines expected (counting down) */ int lineCount; /**< number of lines expected (counting down) */
int compositeTerminator; /**< the terminator contains several chars */
void *private; /**< private data of protocol */ void *private; /**< private data of protocol */
void (*killPrivate)(void *); /**< kill function for private */ void (*killPrivate)(void *); /**< kill function for private */
}; };
@ -116,6 +118,8 @@ int AsconStdHandler(Ascon *a);
* if no replyTerminator is given, or if it is empty, CR, LF or CR/LF all are detected * if no replyTerminator is given, or if it is empty, CR, LF or CR/LF all are detected
* as terminators. If the terminator is CR, LF or CR/LF, it is removed from the result, * as terminators. If the terminator is CR, LF or CR/LF, it is removed from the result,
* all other terminators are kept in the result. * all other terminators are kept in the result.
* is the first and the last character are single quotes (') is is treated as a composite
* terminator and not as a list of single character terminators
* separator is used for multiline responses. If this parameter * separator is used for multiline responses. If this parameter
* is given (and not empty) a command may be followed by a line count in curly brackets, * is given (and not empty) a command may be followed by a line count in curly brackets,
* indicating that a multiline response is expected. All the lines of the response are * indicating that a multiline response is expected. All the lines of the response are
@ -180,4 +184,14 @@ int AsconWriteChars(int fd, char *data, int length);
*/ */
void AsconError(Ascon *a, char *msg, int errorno); void AsconError(Ascon *a, char *msg, int errorno);
int AsconInterpreteArgs(int argc, char *argv[],
int parc, char *parn[], char *pars[]);
/**
* Treat hex strings as terminators right. Note that this
* is limited to single character terminators.
*/
void AsconCheckTerminators(Ascon *a);
#endif #endif