latest changes to match caProvider.html

This commit is contained in:
mrkraimer
2018-09-24 13:45:21 -04:00
parent 10bb8039e5
commit e9d2114e96
3 changed files with 88 additions and 107 deletions
+4 -2
View File
@@ -402,8 +402,7 @@ void CAChannelGetField::callRequester(CAChannelPtr const & caChannel)
if(!requester) return;
PVStructurePtr pvRequest(createRequest(""));
DbdToPvPtr dbdToPv = DbdToPv::create(caChannel,pvRequest,getIO);
PVStructurePtr pvStructure = dbdToPv->createPVStructure();
Structure::const_shared_pointer structure(pvStructure->getStructure());
Structure::const_shared_pointer structure(dbdToPv->getStructure());
Field::const_shared_pointer field =
subField.empty() ?
std::tr1::static_pointer_cast<const Field>(structure) :
@@ -471,6 +470,7 @@ void CAChannelGet::activate()
std::cout << "CAChannelGet::activate " << channel->getChannelName() << endl;
}
dbdToPv = DbdToPv::create(channel,pvRequest,getIO);
dbdToPv->getChoices(channel);
pvStructure = dbdToPv->createPVStructure();
bitSet = BitSetPtr(new BitSet(pvStructure->getStructure()->getNumberFields()));
notifyGetRequester = NotifyGetRequesterPtr(new NotifyGetRequester());
@@ -595,6 +595,7 @@ void CAChannelPut::activate()
cout << "CAChannelPut::activate " << channel->getChannelName() << endl;
}
dbdToPv = DbdToPv::create(channel,pvRequest,putIO);
dbdToPv->getChoices(channel);
pvStructure = dbdToPv->createPVStructure();
bitSet = BitSetPtr(new BitSet(pvStructure->getStructure()->getNumberFields()));
PVStringPtr pvString = pvRequest->getSubField<PVString>("record._options.block");
@@ -854,6 +855,7 @@ void CAChannelMonitor::activate()
std::cout << "CAChannelMonitor::activate " << channel->getChannelName() << endl;
}
dbdToPv = DbdToPv::create(channel,pvRequest,monitorIO);
dbdToPv->getChoices(channel);
pvStructure = dbdToPv->createPVStructure();
activeElement = MonitorElementPtr(new MonitorElement(pvStructure));
int32 queueSize = 2;
+81 -98
View File
@@ -10,6 +10,7 @@
#include <alarm.h>
#include <alarmString.h>
#include <pv/alarm.h>
#include <pv/standardField.h>
#include <pv/logger.h>
#include <pv/pvAccess.h>
@@ -23,6 +24,7 @@
using namespace epics::pvData;
using std::string;
using std::ostringstream;
using std::cout;
namespace epics {
namespace pvAccess {
@@ -30,23 +32,7 @@ namespace ca {
#define CA_PRIORITY 50
static void enumChoicesHandler(struct event_handler_args args)
{
DbdToPv *dbdToPv = static_cast<DbdToPv*>(args.usr);
dbdToPv->getChoicesDone(args);
}
static void description_connection_handler(struct connection_handler_args args)
{
DbdToPv *dbdToPv = static_cast<DbdToPv*>(ca_puser(args.chid));
dbdToPv->descriptionConnected(args);
}
static void descriptionHandler(struct event_handler_args args)
{
DbdToPv *dbdToPv = static_cast<DbdToPv*>(args.usr);
dbdToPv->getDescriptionDone(args);
}
DbdToPvPtr DbdToPv::create(
CAChannelPtr const & caChannel,
@@ -60,7 +46,7 @@ DbdToPvPtr DbdToPv::create(
DbdToPv::DbdToPv(IOType ioType)
: ioType(ioType),
fieldRequested(false),
valueRequested(false),
alarmRequested(false),
timeStampRequested(false),
displayRequested(false),
@@ -68,8 +54,6 @@ DbdToPv::DbdToPv(IOType ioType)
valueAlarmRequested(false),
isArray(false),
firstTime(true),
choicesValid(false),
waitForChoicesValid(false),
caValueType(-1),
caRequestType(-1),
maxElements(0)
@@ -104,6 +88,42 @@ static chtype getDbrType(const ScalarType scalarType)
throw std::runtime_error("getDbr: illegal scalarType");
}
static dbr_short_t convertDBstatus(dbr_short_t dbStatus)
{
switch(dbStatus) {
case NO_ALARM:
return noStatus;
case READ_ALARM:
case WRITE_ALARM:
case HIHI_ALARM:
case HIGH_ALARM:
case LOLO_ALARM:
case LOW_ALARM:
case STATE_ALARM:
case COS_ALARM:
case HW_LIMIT_ALARM:
return deviceStatus;
case COMM_ALARM:
case TIMEOUT_ALARM:
return driverStatus;
case CALC_ALARM:
case SCAN_ALARM:
case LINK_ALARM:
case SOFT_ALARM:
case BAD_SUB_ALARM:
return recordStatus;
case DISABLE_ALARM:
case SIMM_ALARM:
case READ_ACCESS_ALARM:
case WRITE_ACCESS_ALARM:
return dbStatus;
case UDF_ALARM:
return undefinedStatus;
default:
return undefinedStatus; // UNDEFINED
}
}
void DbdToPv::activate(
CAChannelPtr const & caChannel,
@@ -131,14 +151,14 @@ void DbdToPv::activate(
}
if(fieldPVStructure->getPVFields().size()==0)
{
fieldRequested = true;
valueRequested = true;
alarmRequested = true;
timeStampRequested = true;
displayRequested = true;
controlRequested = true;
valueAlarmRequested = true;
} else {
if(fieldPVStructure->getSubField("value")) fieldRequested = true;
if(fieldPVStructure->getSubField("value")) valueRequested = true;
if(fieldPVStructure->getSubField("alarm")) alarmRequested = true;
if(fieldPVStructure->getSubField("timeStamp")) timeStampRequested = true;
if(fieldPVStructure->getSubField("display")) displayRequested = true;
@@ -173,18 +193,7 @@ void DbdToPv::activate(
}
caRequestType = (properties.size()==0 ? DBR_ENUM : DBR_TIME_ENUM);
structure = standardField->enumerated(properties);
int result = ca_array_get_callback(DBR_GR_ENUM,
1,
channelID, enumChoicesHandler, this);
if (result == ECA_NORMAL) result = ca_flush_io();
if (result != ECA_NORMAL) {
string mess(caChannel->getChannelName());
mess += " DbdToPv::activate getting enum cnoices ";
mess += ca_message(result);
throw std::runtime_error(mess);
}
// NOTE: we do not wait here, since all subsequent request (over TCP) is serialized
// and will guarantee that enumChoicesHandler is called first
return;
}
maxElements = ca_element_count(channelID);
@@ -204,7 +213,7 @@ void DbdToPv::activate(
FieldCreatePtr fieldCreate(FieldCreate::getFieldCreate());
PVDataCreatePtr pvDataCreate(PVDataCreate::getPVDataCreate());
FieldBuilderPtr fieldBuilder(fieldCreate->createFieldBuilder());
if(fieldRequested) {
if(valueRequested) {
if(isArray) {
fieldBuilder->addArray("value",st);
} else {
@@ -242,38 +251,27 @@ void DbdToPv::activate(
} else {
caRequestType = dbf_type_to_DBR(caValueType);
}
if(displayRequested) {
chid channelID;
string name(caChannel->getChannelName() + ".DESC");
int result = ca_create_channel(name.c_str(),
description_connection_handler,
this,
CA_PRIORITY, // TODO mapping
&channelID);
if (result == ECA_NORMAL) result = ca_flush_io();
if (result != ECA_NORMAL) {
string mess(caChannel->getChannelName());
mess += " DbdToPv::activate getting description ";
mess += ca_message(result);
throw std::runtime_error(mess);
}
}
chtype DbdToPv::getRequestType()
{
if(caRequestType<0) {
throw std::runtime_error("DbDToPv::getRequestType: bad type");
}
return caRequestType;
}
void DbdToPv::descriptionConnected(struct connection_handler_args args)
Structure::const_shared_pointer DbdToPv::getStructure()
{
if (args.op != CA_OP_CONN_UP) return;
ca_array_get_callback(DBR_STRING,
0,
args.chid, descriptionHandler, this);
return structure;
}
void DbdToPv::getDescriptionDone(struct event_handler_args &args)
static void enumChoicesHandler(struct event_handler_args args)
{
if(args.status!=ECA_NORMAL) return;
const dbr_string_t *value = static_cast<const dbr_string_t *>(dbr_value_ptr(args.dbr,DBR_STRING));
description = string(*value);
ca_clear_channel(args.chid);
DbdToPv *dbdToPv = static_cast<DbdToPv*>(args.usr);
dbdToPv->getChoicesDone(args);
}
void DbdToPv::getChoicesDone(struct event_handler_args &args)
@@ -288,21 +286,29 @@ void DbdToPv::getChoicesDone(struct event_handler_args &args)
size_t num = dbr_enum_p->no_str;
choices.reserve(num);
for(size_t i=0; i<num; ++i) choices.push_back(string(&dbr_enum_p->strs[i][0]));
bool signal = false;
{
Lock lock(choicesMutex);
choicesValid = true;
if(waitForChoicesValid) signal = true;
}
if(signal) choicesEvent.signal();
choicesEvent.signal();
}
chtype DbdToPv::getRequestType()
void DbdToPv::getChoices(CAChannelPtr const & caChannel)
{
if(caRequestType<0) {
throw std::runtime_error("DbDToPv::getRequestType: bad type");
if(caRequestType==DBR_ENUM||caRequestType==DBR_TIME_ENUM)
{
caChannel->attachContext();
chid channelID = caChannel->getChannelID();
int result = ca_array_get_callback(DBR_GR_ENUM,
1,
channelID, enumChoicesHandler, this);
if (result == ECA_NORMAL) {
result = ca_flush_io();
choicesEvent.wait();
} else {
string mess(caChannel->getChannelName());
mess += " DbdToPv::activate getting enum cnoices ";
mess += ca_message(result);
throw std::runtime_error(mess);
}
}
return caRequestType;
}
PVStructurePtr DbdToPv::createPVStructure()
@@ -368,7 +374,7 @@ Status DbdToPv::getFromDBD(
Status errorStatus(Status::STATUSTYPE_ERROR, string(ca_message(args.status)));
return errorStatus;
}
if(fieldRequested)
if(valueRequested)
{
void * value = dbr_value_ptr(args.dbr,caRequestType);
if(isArray) {
@@ -461,7 +467,7 @@ Status DbdToPv::getFromDBD(
PVIntPtr pvStatus(pvAlarm->getSubField<PVInt>("status"));
if(caAlarm.status!=status) {
caAlarm.status = status;
pvStatus->put(status);
pvStatus->put(convertDBstatus(status));
string message("UNKNOWN STATUS");
if(status<=ALARM_NSTATUS) message = string(epicsAlarmConditionStrings[status]);
pvMessage->put(message);
@@ -488,7 +494,7 @@ Status DbdToPv::getFromDBD(
bitSet->set(pvSeconds->getFieldOffset());
}
if(caTimeStamp.nsec!=stamp.nsec) {
caTimeStamp.secPastEpoch = stamp.secPastEpoch;
caTimeStamp.nsec = stamp.nsec;
PVIntPtr pvNano(pvTimeStamp->getSubField<PVInt>("nanoseconds"));
pvNano->put(stamp.nsec);
bitSet->set(pvNano->getFieldOffset());
@@ -590,14 +596,6 @@ Status DbdToPv::getFromDBD(
pvString->put(format);
bitSet->set(pvString->getFieldOffset());
}
if(!description.empty())
{
PVStringPtr pvString = pvDisplay->getSubField<PVString>("description");
if(description.compare(pvString->get()) !=0) {
pvString->put(description);
bitSet->set(pvString->getFieldOffset());
}
}
}
if(valueAlarmRequested) {
double upper_alarm_limit = 0.0;
@@ -668,6 +666,8 @@ Status DbdToPv::getFromDBD(
return Status::Ok;
}
template<typename dbrT, typename pvT>
const void * put_DBRScalar(dbrT *val,PVScalar::shared_pointer const & pvScalar)
{
@@ -750,23 +750,6 @@ Status DbdToPv::putToDBD(
switch(caValueType) {
case DBR_ENUM:
{
bool wait = false;
{
Lock lock(choicesMutex);
if(!choicesValid) {
wait = true;
waitForChoicesValid = true;
}
}
bool result = true;
if(wait) {
result = choicesEvent.wait(5.0);
}
if(!result) {
Status errorStatus(
Status::STATUSTYPE_ERROR, string("DbdToPv::getFromDBD "));
return errorStatus;
}
dbr_enum_t indexvalue = pvStructure->getSubField<PVInt>("value.index")->get();
pValue = &indexvalue;
break;
+3 -7
View File
@@ -89,6 +89,8 @@ public:
epics::pvData::PVStructurePtr const & pvRequest,
IOType ioType
);
epics::pvData::Structure::const_shared_pointer getStructure();
void getChoices(CAChannelPtr const & caChannel);
epics::pvData::PVStructurePtr createPVStructure();
chtype getRequestType();
epics::pvData::Status getFromDBD(
@@ -104,8 +106,6 @@ public:
void *userArg
);
void getChoicesDone(struct event_handler_args &args);
void descriptionConnected(struct connection_handler_args args);
void getDescriptionDone(struct event_handler_args &args);
private:
DbdToPv(IOType ioType);
void activate(
@@ -113,7 +113,7 @@ private:
epics::pvData::PVStructurePtr const & pvRequest
);
IOType ioType;
bool fieldRequested;
bool valueRequested;
bool alarmRequested;
bool timeStampRequested;
bool displayRequested;
@@ -121,19 +121,15 @@ private:
bool valueAlarmRequested;
bool isArray;
bool firstTime;
bool choicesValid;
bool waitForChoicesValid;
chtype caValueType;
chtype caRequestType;
unsigned long maxElements;
epics::pvData::Mutex choicesMutex;
epics::pvData::Event choicesEvent;
epicsTimeStamp caTimeStamp;
CaAlarm caAlarm;
CaDisplay caDisplay;
CaControl caControl;
CaValueAlarm caValueAlarm;
std::string description;
epics::pvData::Structure::const_shared_pointer structure;
std::vector<std::string> choices;
};