ca: monitor support
This commit is contained in:
@@ -322,13 +322,9 @@ ChannelRPC::shared_pointer CAChannel::createChannelRPC(
|
||||
|
||||
epics::pvData::Monitor::shared_pointer CAChannel::createMonitor(
|
||||
epics::pvData::MonitorRequester::shared_pointer const & monitorRequester,
|
||||
epics::pvData::PVStructure::shared_pointer const & /*pvRequest*/)
|
||||
epics::pvData::PVStructure::shared_pointer const & pvRequest)
|
||||
{
|
||||
Status errorStatus(Status::STATUSTYPE_ERROR, "not implemented");
|
||||
Monitor::shared_pointer nullMonitor;
|
||||
EXCEPTION_GUARD(monitorRequester->monitorConnect(errorStatus, nullMonitor,
|
||||
Structure::shared_pointer()));
|
||||
return nullMonitor;
|
||||
return CAChannelMonitor::create(shared_from_this(), monitorRequester, pvRequest);
|
||||
}
|
||||
|
||||
|
||||
@@ -1113,3 +1109,162 @@ void CAChannelPut::unlock()
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Monitor::shared_pointer CAChannelMonitor::create(
|
||||
CAChannel::shared_pointer const & channel,
|
||||
epics::pvData::MonitorRequester::shared_pointer const & monitorRequester,
|
||||
epics::pvData::PVStructure::shared_pointer const & pvRequest)
|
||||
{
|
||||
Monitor::shared_pointer thisPtr(new CAChannelMonitor(channel, monitorRequester, pvRequest));
|
||||
static_cast<CAChannelMonitor*>(thisPtr.get())->activate();
|
||||
return thisPtr;
|
||||
}
|
||||
|
||||
|
||||
CAChannelMonitor::~CAChannelMonitor()
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
|
||||
CAChannelMonitor::CAChannelMonitor(CAChannel::shared_pointer const & _channel,
|
||||
epics::pvData::MonitorRequester::shared_pointer const & _monitorRequester,
|
||||
epics::pvData::PVStructure::shared_pointer const & pvRequest) :
|
||||
channel(_channel),
|
||||
monitorRequester(_monitorRequester),
|
||||
getType(getDBRType(pvRequest, _channel->getNativeType())),
|
||||
pvStructure(createPVStructure(_channel, getType)),
|
||||
changedBitSet(new BitSet(pvStructure->getStructure()->getNumberFields())),
|
||||
overrunBitSet(new BitSet(pvStructure->getStructure()->getNumberFields())),
|
||||
count(0),
|
||||
element(new MonitorElement())
|
||||
{
|
||||
// TODO
|
||||
changedBitSet->set(0);
|
||||
|
||||
element->pvStructurePtr = pvStructure;
|
||||
element->changedBitSet = changedBitSet;
|
||||
element->overrunBitSet = overrunBitSet;
|
||||
}
|
||||
|
||||
void CAChannelMonitor::activate()
|
||||
{
|
||||
// TODO remove
|
||||
thisPointer = shared_from_this();
|
||||
|
||||
EXCEPTION_GUARD(monitorRequester->monitorConnect(Status::Ok, shared_from_this(),
|
||||
pvStructure->getStructure()));
|
||||
}
|
||||
|
||||
|
||||
/* --------------- epics::pvData::Monitor --------------- */
|
||||
|
||||
|
||||
static void ca_subscription_handler(struct event_handler_args args)
|
||||
{
|
||||
CAChannelMonitor *channelMonitor = static_cast<CAChannelMonitor*>(args.usr);
|
||||
channelMonitor->subscriptionEvent(args);
|
||||
}
|
||||
|
||||
|
||||
void CAChannelMonitor::subscriptionEvent(struct event_handler_args &args)
|
||||
{
|
||||
if (args.status == ECA_NORMAL)
|
||||
{
|
||||
// TODO override indicator
|
||||
|
||||
copyDBRtoPVStructure copyFunc = copyFuncTable[getType];
|
||||
if (copyFunc)
|
||||
copyFunc(args.dbr, args.count, pvStructure);
|
||||
else
|
||||
{
|
||||
// TODO remove
|
||||
std::cout << "no copy func implemented" << std::endl;
|
||||
}
|
||||
|
||||
{
|
||||
Lock lock(mutex);
|
||||
count = 1;
|
||||
}
|
||||
monitorRequester->monitorEvent(shared_from_this());
|
||||
}
|
||||
else
|
||||
{
|
||||
//Status errorStatus(Status::STATUSTYPE_ERROR, String(ca_message(args.status)));
|
||||
//EXCEPTION_GUARD(channelMonitorRequester->MonitorDone(errorStatus));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
epics::pvData::Status CAChannelMonitor::start()
|
||||
{
|
||||
// TODO DBE_PROPERTY support
|
||||
int result = ca_create_subscription(getType, channel->getElementCount(),
|
||||
channel->getChannelID(), DBE_VALUE,
|
||||
ca_subscription_handler, this,
|
||||
&eventID);
|
||||
if (result == ECA_NORMAL)
|
||||
{
|
||||
ca_flush_io();
|
||||
return Status::Ok;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Status(Status::STATUSTYPE_ERROR, String(ca_message(result)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
epics::pvData::Status CAChannelMonitor::stop()
|
||||
{
|
||||
int result = ca_clear_subscription(eventID);
|
||||
|
||||
if (result == ECA_NORMAL)
|
||||
{
|
||||
return Status::Ok;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Status(Status::STATUSTYPE_ERROR, String(ca_message(result)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
epics::pvData::MonitorElementPtr CAChannelMonitor::poll()
|
||||
{
|
||||
Lock lock(mutex);
|
||||
if (count)
|
||||
{
|
||||
count--;
|
||||
return element;
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullElement;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CAChannelMonitor::release(epics::pvData::MonitorElementPtr const & /*monitorElement*/)
|
||||
{
|
||||
// noop
|
||||
}
|
||||
|
||||
|
||||
/* --------------- epics::pvData::Destroyable --------------- */
|
||||
|
||||
|
||||
void CAChannelMonitor::destroy()
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
@@ -206,6 +206,61 @@ private:
|
||||
epics::pvData::BitSet::shared_pointer bitSet;
|
||||
};
|
||||
|
||||
|
||||
class CAChannelMonitor :
|
||||
public epics::pvData::Monitor,
|
||||
public std::tr1::enable_shared_from_this<CAChannelMonitor>
|
||||
{
|
||||
|
||||
public:
|
||||
POINTER_DEFINITIONS(CAChannelMonitor);
|
||||
|
||||
static epics::pvData::Monitor::shared_pointer create(CAChannel::shared_pointer const & channel,
|
||||
epics::pvData::MonitorRequester::shared_pointer const & monitorRequester,
|
||||
epics::pvData::PVStructure::shared_pointer const & pvRequest);
|
||||
|
||||
virtual ~CAChannelMonitor();
|
||||
|
||||
void subscriptionEvent(struct event_handler_args &args);
|
||||
|
||||
/* --------------- epics::pvData::Monitor --------------- */
|
||||
|
||||
virtual epics::pvData::Status start();
|
||||
virtual epics::pvData::Status stop();
|
||||
virtual epics::pvData::MonitorElementPtr poll();
|
||||
virtual void release(epics::pvData::MonitorElementPtr const & monitorElement);
|
||||
|
||||
/* --------------- epics::pvData::Destroyable --------------- */
|
||||
|
||||
virtual void destroy();
|
||||
|
||||
private:
|
||||
|
||||
CAChannelMonitor(CAChannel::shared_pointer const & _channel,
|
||||
epics::pvData::MonitorRequester::shared_pointer const & _monitorRequester,
|
||||
epics::pvData::PVStructure::shared_pointer const & pvRequest);
|
||||
void activate();
|
||||
|
||||
// TODO weak_ptr usage?
|
||||
CAChannel::shared_pointer channel;
|
||||
epics::pvData::MonitorRequester::shared_pointer monitorRequester;
|
||||
chtype getType;
|
||||
|
||||
epics::pvData::PVStructure::shared_pointer pvStructure;
|
||||
epics::pvData::BitSet::shared_pointer changedBitSet;
|
||||
epics::pvData::BitSet::shared_pointer overrunBitSet;
|
||||
evid eventID;
|
||||
|
||||
epics::pvData::Mutex mutex;
|
||||
int count;
|
||||
|
||||
epics::pvData::MonitorElement::shared_pointer element;
|
||||
epics::pvData::MonitorElement::shared_pointer nullElement;
|
||||
|
||||
// TODO remove
|
||||
Monitor::shared_pointer thisPointer;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif /* CACHANNEL_H */
|
||||
|
||||
Reference in New Issue
Block a user