Always return 0 from the AsconReading state to make sure we exit the AsconTask().

Since the PSI update the AsconTask() function will loop forever unless you return 0.
This commit is contained in:
Ferdi Franceschini
2013-03-13 19:06:57 +11:00
parent 94f21f832e
commit 1079f6e702

View File

@@ -280,37 +280,38 @@ static int aduLen = 0, RespLen = 0, pduLen = 0, DatLen = 0;
static const int TIDidx=0, PIDidx=2, LENidx=4, UIDidx=6, CODEidx=7, DATLENidx=8, DATAidx=9; static const int TIDidx=0, PIDidx=2, LENidx=4, UIDidx=6, CODEidx=7, DATLENidx=8, DATAidx=9;
static unsigned char ADU[ADUSIZE]; /* Allows upto 8 bytes if data */ static unsigned char ADU[ADUSIZE]; /* Allows upto 8 bytes if data */
int TCPMBReading(Ascon *a) { int TCPMBReading(Ascon *a) {
const int MBAPLen = 7; const int MBAPLen = 7, UIDpos=6;
int i, ret, rlen, byteCnt, allRead = 0; int i, ret, rlen, byteCnt;
char chr, temp[64], errMsg[ERRLEN]; char chr, temp[64], errMsg[ERRLEN];
unsigned char ieee[4]; unsigned char ieee[4];
double dval; double dval;
long int lival; long int lival;
ret = AsconReadChar(a->fd, &chr); ret = AsconReadChar(a->fd, &chr);
/* TODO Check for timeout while reading and call AsconError()
Eg if (DoubleTime() > a->lastReconnect + a->reconnectInterval) then AsconError
*/
while (ret > 0) { while (ret > 0) {
a->start = DoubleTime(); a->start = DoubleTime();
ADU[aduLen++] = chr; ADU[aduLen++] = chr;
ret = AsconReadChar(a->fd, &chr); ret = AsconReadChar(a->fd, &chr);
} }
if (ret < 0) {
AsconError(a, "AsconReadChar failed:", errno);
return 1;
}
if (RespLen == 0 && aduLen > CODEidx) { if (RespLen == 0 && aduLen > CODEidx) {
RespLen = (ADU[LENidx] << 8) + ADU[LENidx+1]; RespLen = (ADU[LENidx] << 8) + ADU[LENidx+1];
} }
if (allRead == 0 && aduLen >= (6 + RespLen)) {
/* all of response has been read */ if (aduLen < (UIDpos + RespLen)) {
/* FIXME If the Length field (ie RespLen) is wrong then we loop forever waiting for a response. if (ret == 0) {
Can this be detected automatically (eg timeout) and reset? if (a->timeout > 0) {
*/ if (DoubleTime() - a->start > a->timeout) {
allRead = 1; AsconError(a, "read timeout", 0);
a->state = AsconTimeout;
} }
if (allRead) { }
} else if (ret < 0) {
AsconError(a, "AsconReadChar failed:", errno);
}
return 0;
}
if (ADU[CODEidx] > 0x80) { if (ADU[CODEidx] > 0x80) {
a->state = AsconReadDone; a->state = AsconReadDone;
snprintf(errMsg, ERRLEN, "TCPMODBUS: Function code %d exception %d:", ADU[CODEidx] & 0x0F, ADU[8] &0x0F); snprintf(errMsg, ERRLEN, "TCPMODBUS: Function code %d exception %d:", ADU[CODEidx] & 0x0F, ADU[8] &0x0F);
@@ -395,17 +396,7 @@ int TCPMBReading(Ascon *a) {
} }
aduLen = 0, DatLen = 0, RespLen = 0; aduLen = 0, DatLen = 0, RespLen = 0;
memset(ADU, 0, ADUSIZE); memset(ADU, 0, ADUSIZE);
if (a->state != AsconReadDone) { return 0;
if (a->timeout > 0) {
if (DoubleTime() - a->start > a->timeout) {
AsconError(a, "read timeout", 0);
a->state = AsconTimeout;
}
}
}
}
return 1;
} }
int TCPMBUtil(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]) { int TCPMBUtil(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]) {