disconnect callback
This commit is contained in:
@ -186,7 +186,7 @@ class AsynDriverInterface : StreamBusInterface
|
|||||||
bool supportsEvent();
|
bool supportsEvent();
|
||||||
bool supportsAsyncRead();
|
bool supportsAsyncRead();
|
||||||
bool connectRequest(unsigned long connecttimeout_ms);
|
bool connectRequest(unsigned long connecttimeout_ms);
|
||||||
bool disconnect();
|
bool disconnectRequest();
|
||||||
void finish();
|
void finish();
|
||||||
|
|
||||||
#ifdef EPICS_3_14
|
#ifdef EPICS_3_14
|
||||||
@ -462,11 +462,6 @@ lockRequest(unsigned long lockTimeout_ms)
|
|||||||
clientName(), lockTimeout_ms);
|
clientName(), lockTimeout_ms);
|
||||||
asynStatus status;
|
asynStatus status;
|
||||||
lockTimeout = lockTimeout_ms ? lockTimeout_ms*0.001 : -1.0;
|
lockTimeout = lockTimeout_ms ? lockTimeout_ms*0.001 : -1.0;
|
||||||
if (!lockTimeout_ms)
|
|
||||||
{
|
|
||||||
if (!connectToAsynPort()) return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
ioAction = Lock;
|
ioAction = Lock;
|
||||||
status = pasynManager->queueRequest(pasynUser, priority(),
|
status = pasynManager->queueRequest(pasynUser, priority(),
|
||||||
lockTimeout);
|
lockTimeout);
|
||||||
@ -497,6 +492,8 @@ connectToAsynPort()
|
|||||||
clientName(), pasynUser->errorMessage);
|
clientName(), pasynUser->errorMessage);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
debug("AsynDriverInterface::connectToAsynPort(%s) is %s connected\n",
|
||||||
|
clientName(), connected ? "already" : "not yet");
|
||||||
if (!connected)
|
if (!connected)
|
||||||
{
|
{
|
||||||
status = pasynCommon->connect(pvtCommon, pasynUser);
|
status = pasynCommon->connect(pvtCommon, pasynUser);
|
||||||
@ -510,6 +507,12 @@ connectToAsynPort()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// We probably should set REN=1 prior to sending but this
|
||||||
|
// seems to hang up the device every other time.
|
||||||
|
// if (pasynGpib)
|
||||||
|
// {
|
||||||
|
// pasynGpib->ren(pvtGpib, pasynUser, 1);
|
||||||
|
// }
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -517,10 +520,12 @@ connectToAsynPort()
|
|||||||
void AsynDriverInterface::
|
void AsynDriverInterface::
|
||||||
lockHandler()
|
lockHandler()
|
||||||
{
|
{
|
||||||
|
int connected;
|
||||||
debug("AsynDriverInterface::lockHandler(%s)\n",
|
debug("AsynDriverInterface::lockHandler(%s)\n",
|
||||||
clientName());
|
clientName());
|
||||||
pasynManager->blockProcessCallback(pasynUser, false);
|
pasynManager->blockProcessCallback(pasynUser, false);
|
||||||
lockCallback(StreamIoSuccess);
|
connected = connectToAsynPort();
|
||||||
|
lockCallback(connected ? StreamIoSuccess : StreamIoFault);
|
||||||
}
|
}
|
||||||
|
|
||||||
// interface function: we don't need exclusive access any more
|
// interface function: we don't need exclusive access any more
|
||||||
@ -1202,46 +1207,27 @@ connectRequest(unsigned long connecttimeout_ms)
|
|||||||
void AsynDriverInterface::
|
void AsynDriverInterface::
|
||||||
connectHandler()
|
connectHandler()
|
||||||
{
|
{
|
||||||
int connected;
|
connectCallback(connectToAsynPort() ? StreamIoSuccess : StreamIoFault);
|
||||||
asynStatus status;
|
|
||||||
|
|
||||||
pasynManager->isConnected(pasynUser, &connected);
|
|
||||||
debug("AsynDriverInterface::connectHandler %s is %s connected\n",
|
|
||||||
clientName(), connected ? "already" : "not yet");
|
|
||||||
if (!connected)
|
|
||||||
{
|
|
||||||
status = pasynCommon->connect(pvtCommon, pasynUser);
|
|
||||||
if (status != asynSuccess)
|
|
||||||
{
|
|
||||||
error("%s connectRequest: pasynCommon->connect() failed: %s\n",
|
|
||||||
clientName(), pasynUser->errorMessage);
|
|
||||||
connectCallback(StreamIoFault);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
connectCallback(StreamIoSuccess);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AsynDriverInterface::
|
bool AsynDriverInterface::
|
||||||
disconnect()
|
disconnectRequest()
|
||||||
{
|
{
|
||||||
asynStatus status;
|
asynStatus status;
|
||||||
ioAction = Disconnect;
|
ioAction = Disconnect;
|
||||||
|
|
||||||
debug("AsynDriverInterface::disconnect %s\n",
|
debug("AsynDriverInterface::disconnectRequest %s\n",
|
||||||
clientName());
|
clientName());
|
||||||
status = pasynManager->queueRequest(pasynUser,
|
status = pasynManager->queueRequest(pasynUser,
|
||||||
asynQueuePriorityConnect, 0.0);
|
asynQueuePriorityConnect, 0.0);
|
||||||
if (status != asynSuccess)
|
if (status != asynSuccess)
|
||||||
{
|
{
|
||||||
error("%s disconnect: pasynManager->queueRequest() failed: %s\n",
|
error("%s disconnectRequest: pasynManager->queueRequest() failed: %s\n",
|
||||||
clientName(), pasynUser->errorMessage);
|
clientName(), pasynUser->errorMessage);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// continues with:
|
// continues with:
|
||||||
// handleRequest() -> disconnectHandler()
|
// handleRequest() -> disconnectHandler()
|
||||||
// or handleTimeout()
|
|
||||||
// (does not expect callback)
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1261,9 +1247,11 @@ disconnectHandler()
|
|||||||
{
|
{
|
||||||
error("%s connectRequest: pasynCommon->disconnect() failed: %s\n",
|
error("%s connectRequest: pasynCommon->disconnect() failed: %s\n",
|
||||||
clientName(), pasynUser->errorMessage);
|
clientName(), pasynUser->errorMessage);
|
||||||
|
disconnectCallback(StreamIoFault);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
disconnectCallback(StreamIoSuccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AsynDriverInterface::
|
void AsynDriverInterface::
|
||||||
@ -1273,6 +1261,12 @@ finish()
|
|||||||
clientName());
|
clientName());
|
||||||
cancelTimer();
|
cancelTimer();
|
||||||
ioAction = None;
|
ioAction = None;
|
||||||
|
// if (pasynGpib)
|
||||||
|
// {
|
||||||
|
// // Release GPIB device the the end of the protocol
|
||||||
|
// // to re-enable local buttons.
|
||||||
|
// pasynGpib->ren(pvtGpib, pasynUser, 0);
|
||||||
|
// }
|
||||||
debug("AsynDriverInterface::finish(%s) done\n",
|
debug("AsynDriverInterface::finish(%s) done\n",
|
||||||
clientName());
|
clientName());
|
||||||
}
|
}
|
||||||
@ -1335,9 +1329,9 @@ void handleTimeout(asynUser* pasynUser)
|
|||||||
interface->connectCallback(StreamIoTimeout);
|
interface->connectCallback(StreamIoTimeout);
|
||||||
break;
|
break;
|
||||||
case Disconnect:
|
case Disconnect:
|
||||||
debug ("AsynDriverInterface %s: disconnect timeout\n",
|
error("AsynDriverInterface %s: disconnect timeout\n",
|
||||||
interface->clientName());
|
interface->clientName());
|
||||||
// not interested in callback
|
// should not happen because of infinite timeout
|
||||||
break;
|
break;
|
||||||
// No AsyncRead here because we don't use timeout when polling
|
// No AsyncRead here because we don't use timeout when polling
|
||||||
default:
|
default:
|
||||||
|
@ -89,7 +89,7 @@ connectRequest (unsigned long)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool StreamBusInterface::
|
bool StreamBusInterface::
|
||||||
disconnect ()
|
disconnectRequest ()
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -137,6 +137,11 @@ connectCallback(StreamIoStatus)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void StreamBusInterface::Client::
|
||||||
|
disconnectCallback(StreamIoStatus)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
long StreamBusInterface::Client::
|
long StreamBusInterface::Client::
|
||||||
priority()
|
priority()
|
||||||
{
|
{
|
||||||
|
@ -42,6 +42,7 @@ public:
|
|||||||
const void* input, long size);
|
const void* input, long size);
|
||||||
virtual void eventCallback(StreamIoStatus status);
|
virtual void eventCallback(StreamIoStatus status);
|
||||||
virtual void connectCallback(StreamIoStatus status);
|
virtual void connectCallback(StreamIoStatus status);
|
||||||
|
virtual void disconnectCallback(StreamIoStatus status);
|
||||||
virtual long priority();
|
virtual long priority();
|
||||||
virtual const char* name() = 0;
|
virtual const char* name() = 0;
|
||||||
virtual const char* getInTerminator(size_t& length) = 0;
|
virtual const char* getInTerminator(size_t& length) = 0;
|
||||||
@ -86,7 +87,7 @@ public:
|
|||||||
return businterface->connectRequest(timeout_ms);
|
return businterface->connectRequest(timeout_ms);
|
||||||
}
|
}
|
||||||
bool busDisconnect() {
|
bool busDisconnect() {
|
||||||
return businterface->disconnect();
|
return businterface->disconnectRequest();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -113,6 +114,8 @@ protected:
|
|||||||
{ client->eventCallback(status); }
|
{ client->eventCallback(status); }
|
||||||
void connectCallback(StreamIoStatus status)
|
void connectCallback(StreamIoStatus status)
|
||||||
{ client->connectCallback(status); }
|
{ client->connectCallback(status); }
|
||||||
|
void disconnectCallback(StreamIoStatus status)
|
||||||
|
{ client->disconnectCallback(status); }
|
||||||
const char* getInTerminator(size_t& length)
|
const char* getInTerminator(size_t& length)
|
||||||
{ return client->getInTerminator(length); }
|
{ return client->getInTerminator(length); }
|
||||||
const char* getOutTerminator(size_t& length)
|
const char* getOutTerminator(size_t& length)
|
||||||
@ -132,7 +135,7 @@ protected:
|
|||||||
unsigned long replytimeout_ms); // supportsEvents() returns true
|
unsigned long replytimeout_ms); // supportsEvents() returns true
|
||||||
virtual void release();
|
virtual void release();
|
||||||
virtual bool connectRequest(unsigned long connecttimeout_ms);
|
virtual bool connectRequest(unsigned long connecttimeout_ms);
|
||||||
virtual bool disconnect();
|
virtual bool disconnectRequest();
|
||||||
virtual void finish();
|
virtual void finish();
|
||||||
|
|
||||||
// pure virtual
|
// pure virtual
|
||||||
|
@ -23,6 +23,12 @@
|
|||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <epicsExport.h>
|
||||||
|
int showAsyncErrors = 0;
|
||||||
|
extern "C" {
|
||||||
|
epicsExportAddress(int, showAsyncErrors);
|
||||||
|
}
|
||||||
|
|
||||||
enum Commands { end_cmd, in_cmd, out_cmd, wait_cmd, event_cmd, exec_cmd,
|
enum Commands { end_cmd, in_cmd, out_cmd, wait_cmd, event_cmd, exec_cmd,
|
||||||
connect_cmd, disconnect_cmd };
|
connect_cmd, disconnect_cmd };
|
||||||
const char* commandStr[] = { "end", "in", "out", "wait", "event", "exec",
|
const char* commandStr[] = { "end", "in", "out", "wait", "event", "exec",
|
||||||
@ -801,6 +807,8 @@ writeCallback(StreamIoStatus status)
|
|||||||
flags &= ~WritePending;
|
flags &= ~WritePending;
|
||||||
if (status != StreamIoSuccess)
|
if (status != StreamIoSuccess)
|
||||||
{
|
{
|
||||||
|
error("%s: write failed: %s\n",
|
||||||
|
name(), StreamIoStatusStr[status]);
|
||||||
finishProtocol(WriteTimeout);
|
finishProtocol(WriteTimeout);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -921,7 +929,11 @@ readCallback(StreamIoStatus status,
|
|||||||
finishProtocol(ReplyTimeout);
|
finishProtocol(ReplyTimeout);
|
||||||
return 0;
|
return 0;
|
||||||
case StreamIoFault:
|
case StreamIoFault:
|
||||||
error("%s: I/O error when reading from device\n", name());
|
error("%s: I/O error after reading %ld byte%s: \"%s%s\"\n",
|
||||||
|
name(),
|
||||||
|
inputBuffer.length(), inputBuffer.length()==1 ? "" : "s",
|
||||||
|
inputBuffer.length() > 20 ? "..." : "",
|
||||||
|
inputBuffer.expand(-20,20)());
|
||||||
finishProtocol(Fault);
|
finishProtocol(Fault);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -985,7 +997,7 @@ readCallback(StreamIoStatus status,
|
|||||||
}
|
}
|
||||||
// try to parse what we got
|
// try to parse what we got
|
||||||
end = inputBuffer.length();
|
end = inputBuffer.length();
|
||||||
if (!(flags & AsyncMode))
|
if (!(flags & AsyncMode)||showAsyncErrors)
|
||||||
{
|
{
|
||||||
error("%s: Timeout after reading %ld byte%s \"%s%s\"\n",
|
error("%s: Timeout after reading %ld byte%s \"%s%s\"\n",
|
||||||
name(), end, end==1 ? "" : "s", end > 20 ? "..." : "",
|
name(), end, end==1 ? "" : "s", end > 20 ? "..." : "",
|
||||||
@ -1115,7 +1127,7 @@ matchInput()
|
|||||||
}
|
}
|
||||||
if (consumed < 0)
|
if (consumed < 0)
|
||||||
{
|
{
|
||||||
if (!(flags & AsyncMode) && onMismatch[0] != in_cmd)
|
if ((!(flags & AsyncMode)||showAsyncErrors) && onMismatch[0] != in_cmd)
|
||||||
{
|
{
|
||||||
error("%s: Input \"%s%s\" does not match format %%%s\n",
|
error("%s: Input \"%s%s\" does not match format %%%s\n",
|
||||||
name(), inputLine.expand(consumedInput, 20)(),
|
name(), inputLine.expand(consumedInput, 20)(),
|
||||||
@ -1130,7 +1142,7 @@ matchInput()
|
|||||||
flags &= ~Separator;
|
flags &= ~Separator;
|
||||||
if (!matchValue(fmt, fieldAddress ? fieldAddress() : NULL))
|
if (!matchValue(fmt, fieldAddress ? fieldAddress() : NULL))
|
||||||
{
|
{
|
||||||
if (!(flags & AsyncMode) && onMismatch[0] != in_cmd)
|
if ((!(flags & AsyncMode)||showAsyncErrors) && onMismatch[0] != in_cmd)
|
||||||
{
|
{
|
||||||
if (flags & ScanTried)
|
if (flags & ScanTried)
|
||||||
error("%s: Input \"%s%s\" does not match format %%%s\n",
|
error("%s: Input \"%s%s\" does not match format %%%s\n",
|
||||||
@ -1160,7 +1172,7 @@ matchInput()
|
|||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (commandIndex[i] >= ' ') i++;
|
while (commandIndex[i] >= ' ') i++;
|
||||||
if (!(flags & AsyncMode) && onMismatch[0] != in_cmd)
|
if ((!(flags & AsyncMode)||showAsyncErrors) && onMismatch[0] != in_cmd)
|
||||||
{
|
{
|
||||||
error("%s: Input \"%s%s\" too short."
|
error("%s: Input \"%s%s\" too short."
|
||||||
" No match for \"%s\"\n",
|
" No match for \"%s\"\n",
|
||||||
@ -1173,7 +1185,7 @@ matchInput()
|
|||||||
}
|
}
|
||||||
if (command != inputLine[consumedInput])
|
if (command != inputLine[consumedInput])
|
||||||
{
|
{
|
||||||
if (!(flags & AsyncMode) && onMismatch[0] != in_cmd)
|
if ((!(flags & AsyncMode)||showAsyncErrors) && onMismatch[0] != in_cmd)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (commandIndex[i] >= ' ') i++;
|
while (commandIndex[i] >= ' ') i++;
|
||||||
@ -1198,7 +1210,7 @@ matchInput()
|
|||||||
long surplus = inputLine.length()-consumedInput;
|
long surplus = inputLine.length()-consumedInput;
|
||||||
if (surplus > 0 && !(flags & IgnoreExtraInput))
|
if (surplus > 0 && !(flags & IgnoreExtraInput))
|
||||||
{
|
{
|
||||||
if (!(flags & AsyncMode) && onMismatch[0] != in_cmd)
|
if ((!(flags & AsyncMode)||showAsyncErrors) && onMismatch[0] != in_cmd)
|
||||||
{
|
{
|
||||||
error("%s: %ld byte%s surplus input \"%s%s\"\n",
|
error("%s: %ld byte%s surplus input \"%s%s\"\n",
|
||||||
name(), surplus, surplus==1 ? "" : "s",
|
name(), surplus, surplus==1 ? "" : "s",
|
||||||
@ -1510,8 +1522,23 @@ bool StreamCore::evalDisconnect()
|
|||||||
finishProtocol(Fault);
|
finishProtocol(Fault);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
evalCommand();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void StreamCore::
|
||||||
|
disconnectCallback(StreamIoStatus status)
|
||||||
|
{
|
||||||
|
switch (status)
|
||||||
|
{
|
||||||
|
case StreamIoSuccess:
|
||||||
|
evalCommand();
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
error("%s: Disconnect failed\n",
|
||||||
|
name());
|
||||||
|
finishProtocol(Fault);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#include "streamReferences"
|
#include "streamReferences"
|
||||||
|
@ -200,6 +200,7 @@ protected:
|
|||||||
void eventCallback(StreamIoStatus status);
|
void eventCallback(StreamIoStatus status);
|
||||||
void execCallback(StreamIoStatus status);
|
void execCallback(StreamIoStatus status);
|
||||||
void connectCallback(StreamIoStatus status);
|
void connectCallback(StreamIoStatus status);
|
||||||
|
void disconnectCallback(StreamIoStatus status);
|
||||||
const char* getInTerminator(size_t& length);
|
const char* getInTerminator(size_t& length);
|
||||||
const char* getOutTerminator(size_t& length);
|
const char* getOutTerminator(size_t& length);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user