- added AsconHostport function
- added composite terminator in standard protocol
This commit is contained in:
46
ascon.c
46
ascon.c
@ -71,6 +71,7 @@ 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";
|
||||||
@ -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,11 +468,20 @@ int AsconStdHandler(Ascon * a)
|
|||||||
}
|
}
|
||||||
if (a->replyTerminator != NULL) {
|
if (a->replyTerminator != NULL) {
|
||||||
if (strchr(a->replyTerminator, chr) != NULL) {
|
if (strchr(a->replyTerminator, chr) != NULL) {
|
||||||
|
if (a->compositeTerminator) {
|
||||||
|
/* one character was o.k., but all have to match */
|
||||||
|
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;
|
a->state = AsconReadDone;
|
||||||
if (chr == '\n' || chr == '\r') {
|
if (chr == '\n' || chr == '\r') {
|
||||||
DynStringBackspace(a->rdBuffer); /* remove LF or CR */
|
DynStringBackspace(a->rdBuffer); /* remove LF or CR */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (chr == '\n') { /* LF */
|
if (chr == '\n') { /* LF */
|
||||||
DynStringBackspace(a->rdBuffer); /* remove LF */
|
DynStringBackspace(a->rdBuffer); /* remove LF */
|
||||||
@ -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;
|
||||||
@ -796,3 +825,12 @@ 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
11
ascon.h
@ -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
14
ascon.i
@ -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
|
||||||
|
Reference in New Issue
Block a user