diff --git a/autogen_rel.sh b/autogen_rel.sh index 6375383..9c33fce 100644 --- a/autogen_rel.sh +++ b/autogen_rel.sh @@ -26,7 +26,7 @@ export CAFE_EPICS_V_MINOR=$EBMIN export CAFE_EPICS_V_PATCH=$EBPAT -CAFE_VERSION=cafe-1.3.0-final-1 +CAFE_VERSION=cafe-1.3.0-final-2 ./configure \ diff --git a/examples/cafeTest/cafeTest b/examples/cafeTest/cafeTest index a5df7dd..89e52c8 100755 Binary files a/examples/cafeTest/cafeTest and b/examples/cafeTest/cafeTest differ diff --git a/examples/cafeTest/cafeTest.cc b/examples/cafeTest/cafeTest.cc index 4a7f25c..53c746c 100644 --- a/examples/cafeTest/cafeTest.cc +++ b/examples/cafeTest/cafeTest.cc @@ -10,8 +10,8 @@ // PV_X1,PV_Y1 are scalar numerics // PV_WF is a vector numeric // PV_MBBI is an mbbi record with a number of enum vakues -// PV_X!_DESC is of data type dbr_string_t -// PV_JOKE is a non-existant channel (used to show CAFE response is such cases) +// PV_X1_DESC is of data type dbr_string_t +// PV_JOKE is a non-existant channel (used to illustrate CAFE response is such cases) #define PV_X1 "ARIDI-BPM-01LE:X-AVG" #define PV_Y1 "ARIDI-BPM-01LE:Y-AVG" @@ -22,7 +22,7 @@ #define NHANDLES 6 // should match number of pvs above that we are to open. - +#define __METHOD__ "cafeTest.cc" //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // (1) Establishing connections to EPICS Process Variables (PVs) @@ -51,22 +51,21 @@ int main( int argc, char *argv[] ) using namespace std; - string pvArray[NHANDLES]={PV_X1,PV_Y1,PV_WF,PV_MBBI,PV_X1_DESC,PV_JOKE}; - unsigned int hArray[NHANDLES]; - - - //Instantaite CAFE - - CAFE * cafe = new CAFE(); - + string pvArray[NHANDLES]={PV_X1,PV_Y1,PV_WF,PV_MBBI,PV_X1_DESC,PV_JOKE}; + unsigned int hArray [NHANDLES]; + + vector hV; //vector of handles + vector pvV; //corresponding vector of pvs + vector stateV;//corresponding vector of connection states + unsigned int handle; - int status; - //Class with methods to report on the value and meaning of status codes - CAFEStatus cstat; - //Classes defining value/name pairs of alarm status andseverity - CAFEGlobalAlarmSeverity alarmSev; - CAFEGlobalAlarmCondition alarmStat; + int status; + + //Instantaite CAFE + CAFE * cafe = new CAFE(); + + //------------------------------------------------------------ @@ -77,17 +76,18 @@ int main( int argc, char *argv[] ) cout << "START: (1) Establishing connections to EPICS Process Variables (PVs) " << endl; cout << "---------------------------------------------------------------------" << endl; - - - // An open operation will pend the ioc for a default amount of time given by: + + // An open channel operation will pend the ioc for a default amount of time given by: // cafe->channelOpenPolicy.getDefaultTimeout() // else otherwise specified. cafe->channelOpenPolicy.setTimeout(0.1); //pend 0.1 seconds - - + // Open one channel - // It is not an error if the channel is not connected! + // An exception is ***not*** thrown if the channel does not connect! + // The open method returns a handle as an output argument + // Subsequent cafe method invocations on a channel may be made on a per handle or pv basis + try { cafe->open(pvArray[0].c_str(), handle); } @@ -95,13 +95,6 @@ int main( int argc, char *argv[] ) cout << e.what() << endl; exit(1); } - - - unsigned int hDesc; - - vector hV; - vector pvV; - vector stateV; try{ @@ -116,8 +109,7 @@ int main( int argc, char *argv[] ) //cafe->channelOpenPolicy.setFlushSendBufferKind(WITH_PEND_EVENT); //cafe->channelOpenPolicy.setTimeout(1.0); - //cafe->open(...) - + //cafe->open(...) //cafe->openNow() // Now send messages to IOC @@ -130,31 +122,33 @@ int main( int argc, char *argv[] ) // Vector interfaces also exist // vector pvVector // vector hVector - // cafe->open(pvVector, hVector, NHANDLES); + // cafe->open(pvVector, hVector); + //Only after the following method is invoked are the open requests made + //or if the ca message buffer becomes full and is consequently flushed //cafe->openNow() ; // and wait for cafe->channelOpenPolicy.getTimeout() //or cafe->openNowAndWait(0.5); //wait for specified time, here 0.5 seconds - - + //Is the given channel connected? Returns true/false bool ifYes= cafe->isChannelConnected(hArray[0]); //Are all channels connected? Returns true/false ifYes= cafe->allChannelsConnected(); - - + if (!ifYes) { cafe->printDisconnectedHandles(); } - + //Handle helper functions also provide information on PV handles and their connection states - status=cafe->getHandleHelper().getDisconnectedHandles(hV, pvV); - status=cafe->getHandleHelper().getHandles(hV, pvV); - status=cafe->getHandleHelper().getHandleStates(hV, pvV,stateV); - - + //hV and pvV vectors are used further down this code. + + status=cafe->getHandleHelper().getDisconnectedHandles(hV, pvV); //output args return handles and their pv names + status=cafe->getHandleHelper().getHandles(hV, pvV); //output args return handles and their pv names + //output args return handles, their pv names, and connection states + status=cafe->getHandleHelper().getHandleStates(hV, pvV,stateV); + } catch(CAFEException_open & e) { cout << e.what() << endl; @@ -166,36 +160,34 @@ int main( int argc, char *argv[] ) // To close a single Channel // cafe->close(hArray[0]); - // To close many channels + // To close an array of channels // cafe->closeChannels(hArray, NHANDLES); - // To close alls channesl + // To close all channels // cafe->closeChannels(); // If you wish to close channels that are in other threads // (i.e., with other ca_client_context) // use instead the following methods: // To close a single Channel irrespective of ca_client_context - // i.e. these will also close handles in other threads // cafe->closeHandle(hArray[0[); - // To close many handles + // To close an array of handles // cafe->closeHandles(hArray, NHANDLES); + // // To close all handles - // cafe->closeHandles(); - - - + // cafe->closeHandles(); + + // Methods also exist that close a vector of handles - not shown cout << "---------------------------------------------------------------------" << endl; cout << "STOP: (1) Establishing connections to EPICS Process Variables (PVs) " << endl; cout << "---------------------------------------------------------------------" << endl; - - + //------------------------------------------------------------ //(2) Basic Single Channel Operations //------------------------------------------------------------ @@ -213,10 +205,16 @@ int main( int argc, char *argv[] ) status=cafe->get(hArray[0], d); if (status != ICAFE_NORMAL) { - cout << "Status indicates an error at line no." << __LINE__ << endl; - cstat.report(status); + cout << "Status = " << status << "; indicates an error at " << __METHOD__ << "//" << __LINE__ << endl; + cafe->getCafeStatus().report(status); //or cafe->printStatus(handle,status); + + //To explicitly check on timeout error + if (cafe->getCafeStatus().isTimeout(status)) { + cout << "Above is a timeout error" << endl; + } + } else { cout << "Value d=" << d << endl; @@ -227,51 +225,81 @@ int main( int argc, char *argv[] ) status=cafe->get(handle, f, alarmStatus, alarmSeverity, ets); if (status != ICAFE_NORMAL) { - cout << "Status indicates an error at line no." << __LINE__ << endl; + cout << "Status = " << status << "; indicates an error at " << __METHOD__ << "//" << __LINE__ << endl; + cafe->getCafeStatus().report(status); + //or cafe->printStatus(hArray[0],status); } else { cout << "Value f=" << f << endl; - cout << "AlarmStatus= " << alarmStat.asString(alarmStatus) << " AlarmSeverity=" << alarmSev.asString(alarmSeverity) + cout << "AlarmStatus= " << cafe->getEpicsAlarmCondition().asString(alarmStatus) << " AlarmSeverity=" << cafe->getEpicsAlarmSeverity().asString(alarmSeverity) << " TimeStamp= " << ets.secPastEpoch << " sec. " << ets.nsec << " nsec " << endl; } - + d=0; //get by pvname status=cafe->get(pvArray[0].c_str(), d); if (status != ICAFE_NORMAL) { - cout << "Status indicates an error at line no." << __LINE__ << endl; - cstat.report(status); + cout << "Status = " << status << "; indicates an error at " << __METHOD__ << "//" << __LINE__ << endl; + cafe->getCafeStatus().report(status); //or cafe->printStatus(handle,status); - - + //To explicitly check on timeout error - if (cstat.csc.isTimeout(status)) { + if (cafe->getCafeStatus().isTimeout(status)) { cout << "Above is a timeout error" << endl; } } - + else { + cout << "Value d=" << d << endl; + } - //To interchange between handle and array - handle = cafe->getHandleFromPV(pvArray[0].c_str()); - const char * pvName= cafe->getPVFromHandle(handle); + //Handle and PV Mappring, i.e., to interchange between handle and pvName + handle = cafe->getHandleFromPV(pvArray[0].c_str()); + const char * pvName = cafe->getPVFromHandle(handle); - //------------------------------------------------------------ - //Data retrieval methods returning structured data + //Set data + //The set method is able to intrepret all data types, and can + //cater for scalar values and arrays //------------------------------------------------------------ + //by pvName + status=cafe->set(PV_X1, 0.02453); - + //by Handle + status=cafe->set(handle, 0.02453); + + if (status!=ICAFE_NORMAL) { + cafe->getCafeStatus().report(status); + } + //or to print an error with pv name (handle as input argument) + //cafe->printStatusIfError(handle,status); + //or + //cafe->printStatusIfError(cafe->getHandleFromPV(PV_X1),status); + //or another way to print an error with pv name + cafe->printStatusIfError(PV_X1,status); + + + + //------------------------------------------------------------ + //Data retrieval methods returning structured data + //and set with PvDataHolder object + //------------------------------------------------------------ + + + //This example acts on a waveform + PVDataHolder pvd; - + //if wf, ***must*** allocate memory as follows: pvd.setNelem(cafe->getNelemNative(hArray[2])); + //status=cafe->get(pvArray[2].c_str(), pvd); status=cafe->get(hArray[2], pvd); + if (status==ICAFE_NORMAL) { pvd.print(10); //Show only 10 elements of the waveform @@ -294,16 +322,32 @@ int main( int argc, char *argv[] ) cout << "pvd.getAsLongLong() = " << pvd.getAsLongLong() << endl; cout << "pvd.getAsULongLong() = " << pvd.getAsULongLong() << endl; - boost::shared_ptr > spVd = pvd.getAsVDouble(); - cout << "pvd.getAsVDouble() = " << spVd.get()[0][0] << " [0] " << spVd.get()[0][1] << " [1] " << endl; + boost::shared_ptr > spVd = pvd.getAsVDouble(); + + cout << "pvd.getAsVDouble() = " << spVd.get()[0][0] << " [0] " ; + if (spVd.get()[0].size()>1) { + cout << spVd.get()[0][1] << " [1] "; + } + cout << endl; vector * vd= spVd.get(); - cout << "pvd.getAsVDouble() = " << vd[0][0] << " [0] " << vd[0][1] << " [1] " << endl; - + cout << "pvd.getAsVDouble() = " << vd[0][0] << " [0] " ; + if (vd[0].size()>1 ) { + cout << vd[0][1] << " [1] "; + } + cout << endl; boost::shared_ptr > spVf = pvd.getAsVFloat(); - cout << "pvd.getAsVFloat() = " << spVf.get()[0][0] << " [0] " << spVf.get()[0][1] << " [1] " << endl; + cout << "pvd.getAsVFloat() = " << spVf.get()[0][0] << " [0] " ; + if (spVf.get()[0].size()>1) { + cout << spVf.get()[0][1] << " [1] "; + } + cout << endl; + vector * vf= spVf.get(); - cout << "pvd.getAsVFloat() = " << vf[0][0] << " [0] " << vf[0][1] << " [1] " << endl; - + cout << "pvd.getAsVFloat() = " << vf[0][0] << " [0] " ; + if (vf[0].size()>1) { + cout << vf[0][1] << " [1] "; + } + cout << endl; cout << "pvd.getPVName() = " << pvd.getPV() << endl; cout << "pvd.getPVAlias() = " << pvd.getPVAlias() << endl; @@ -326,8 +370,8 @@ int main( int argc, char *argv[] ) //cout << "pvd.getEnumIntegerValueAsString() = " << pvd.getEnumIntegerValueAsString() << endl; //for mbbi/o records - cout << "pvd.concatToString() = " << pvd.concatToString() << endl; //for waveforesm with data type dbr_chart_t - cout << "pvd.getWFAsString() = " << pvd.concatToString() << endl; + cout << "pvd.concatToString() = " << pvd.concatToString() << endl; // for waveforesm with data type dbr_chart_t + cout << "(Does same as above) = " << pvd.getWFAsString() << endl; // for waveforesm with data type dbr_chart_t @@ -338,41 +382,59 @@ int main( int argc, char *argv[] ) //Alarm status and severities have value/name (int/string) pairs. //The string equivalent of a given value may be gotten as shown - cout << "Alarm Status =" << alarmStat.asString(pvd.getAlarmStatus()) << endl; - cout << "Alarm Severity =" << alarmSev.asString(pvd.getAlarmSeverity()) << endl; + cout << "Alarm Status = " << cafe->getEpicsAlarmCondition().asString(pvd.getAlarmStatus()) << endl; + cout << "Alarm Severity = " << cafe->getEpicsAlarmSeverity().asString(pvd.getAlarmSeverity()) << endl; //Information concerning the meaning of the status of the cafe operation - cout << cstat.severity(pvd.getStatus()) << endl; //Whether WARNING OR ERROR - cout << cstat.asString(pvd.getStatus()) << endl; - cout << cstat.code(pvd.getStatus()) << endl; - cout << cstat.info(pvd.getStatus()) << endl; - cout << cstat.message(pvd.getStatus()) << endl; - //print summary - cstat.report(pvd.getStatus()); + cout << cafe->getCafeStatus().severity(pvd.getStatus()) << endl; //Whether WARNING, ERROR, OR INFO + cout << cafe->getCafeStatus().asString(pvd.getStatus()) << endl; + cout << cafe->getCafeStatus().code(pvd.getStatus()) << endl; + cout << cafe->getCafeStatus().info(pvd.getStatus()) << endl; + cout << cafe->getCafeStatus().message(pvd.getStatus()) << endl; + //print summary + cout << "<---- SUMMARY --> " << endl; + cafe->getCafeStatus().report(pvd.getStatus()); + cout << "<---- END SUMMARY --> " << endl; } // if status=ICAFE_NORMAL - - //------------------------------------------------------------ - //Set data - //The set method is able to intrepret all data types, and can - //cater for scalar values and arrays - //------------------------------------------------------------ + else { + cout << "Status = " << status << "; indicates an error at " << __METHOD__ << "//" << __LINE__ << endl; + cafe->getCafeStatus().report(status); + } - status=cafe->set(PV_X1, 0.02453); - - if (status!=ICAFE_NORMAL) { - cstat.report(status); - } - //or another way to print an error with pv name - cafe->printStatusIfError(cafe->getHandleFromPV(PV_X1),status); + //Can also perform a set using PvDataHolder as follows: + //Single value + pvd.set(2.2); // + status=cafe->set(hArray[2], pvd); + if (status != ICAFE_NORMAL) { + cout << "Status = " << status << "; indicates an error at " << __METHOD__ << "//" << __LINE__ << endl; + cafe->getCafeStatus().report(status); + } + + //For Waveform + double inwf [20] = {1.15,2.2,3.3,4.4,5.5,6.6,7.7,8.8,9.9,10.10, 11, 12, 13,14,15,16,17,18,19,20.20}; + //***Must*** declare size of array here, or the number of elements to set if less! + //cafe->getHandleHelper().setNelem(hArray[2],20); + pvd.setNelem(20); + pvd.set(inwf); + + status=cafe->set(hArray[2], pvd); + + + //cout << "nelements " << pvd.getNelem() << " " << endl; + //cout << " client " << cafe->getHandleHelper().getNelemClient(hArray[2]) << endl; + //cout << " native " << cafe->getHandleHelper().getNelemClient(hArray[2]) << endl; + //cout << " requested " << cafe->getHandleHelper().getNelemRequest(hArray[2]) << endl; + cout << "------------------------------------------------------------" << endl; cout << "END: (2) Basic Single Channel Operations " << endl; cout << "------------------------------------------------------------" << endl; - - + + + //------------------------------------------------------------ //(3) Waveforms and Arrays //------------------------------------------------------------ @@ -380,47 +442,65 @@ int main( int argc, char *argv[] ) cout << "------------------------------------------------------------" << endl; cout << "START: (3) Waveforms and Arrays " << endl; cout << "------------------------------------------------------------" << endl; - - + //------------------------------------------------------------ //Data retrieval methods returning a waveform array //------------------------------------------------------------ - - double * dwf = new double[cafe->getNelemNative(hArray[2])]; - double inwf [20] = {1.1,2.2,3.3,4.4,5.5,6.6,7.7,8.8,9.9,10, 11, 12, 13,14,15,16,17,18,19,20}; - - + //inwf array of 20 doubles previous defined + //copy to vector to illustrate other possibilities - //by pvName - status=cafe->set(PV_WF, inwf); + vector dvv (inwf, inwf+20); + //Be sure to assign memory + cafe->getHandleHelper().setNelem(hArray[2], 20); + //Actually set method with vectors, will check the size of the vector + //and adjust the setNelem accordingly if required + + //Methods invoking vectors are by Handle + status=cafe->set(cafe->getHandleFromPV(PV_WF), dvv); + //or + //status=cafe->set(hArray[2], inwf); + if (status != ICAFE_NORMAL) { + cout << "Status = " << status << "; indicates an error at " << __METHOD__ << "//" << __LINE__ << endl; + cafe->getCafeStatus().report(status); + } + + + + //reset Number of elements to native value for get operation + cafe->getHandleHelper().setNelem(hArray[2], cafe->getNelemNative(hArray[2]) ); + + + //Allocate + double * dwf = new double[cafe->getNelemNative(hArray[2])]; + status=cafe->get(PV_WF, dwf); if (status != ICAFE_NORMAL) { - cout << "Status indicates an error at line no." << __LINE__ << endl; - cstat.report(status); + cout << "Status = " << status << "; indicates an error at " << __METHOD__ << "//" << __LINE__ << endl; + cafe->getCafeStatus().report(status); } else { cout << PV_WF << " successfully read out " << endl; cout << "First five elements have values: " << endl; - for (int i=0; igetNelemNative(hArray[2])); ++i) { + for (int i=0; igetNelemRequest(hArray[2])); ++i) { cout << dwf[i] << " [" << i << "] "; } cout << endl; } - + - //One may also set the number of elements to retrieve + //One may also set the number of elements to retrieve an offset //int nelem =cafe->getHandleHelper().setNelemToNative(hArray[2]); - int nelem = cafe->getHandleHelper().setNelem(hArray[2], 10); //returns max(10, cafe->getNelemNative(handle)) + int nelem = cafe->getHandleHelper().setNelem (hArray[2], 10); //returns max(10, cafe->getNelemNative(handle)) //and offset int offset = cafe->getHandleHelper().setOffset(hArray[2], 2); //by Handle status=cafe->get(hArray[2], dwf); if (status != ICAFE_NORMAL) { - cout << "Status indicates an error at line no." << __LINE__ << endl; - cstat.report(status); + cout << "Status = " << status << "; indicates an error at " << __METHOD__ << "//" << __LINE__ << endl; + cafe->getCafeStatus().report(status); } else { cout << PV_WF << " sucessfully read out " << endl; @@ -434,48 +514,61 @@ int main( int argc, char *argv[] ) //reset offset for read and the nelemtonative cout << "Resetting nelem for wf to native value: " << cafe->getHandleHelper().setNelemToNative(hArray[2]) << " and resetting offset to: " << cafe->getHandleHelper().setOffset(hArray[2], 0) << endl; - - cafe->get(hArray[2]); + + //by handle + status=cafe->set(cafe->getHandleFromPV(PV_WF), dvv); + + if (status != ICAFE_NORMAL) { + cout << "Status = " << status << "; indicates an error at " << __METHOD__ << "//" << __LINE__ << endl; + cafe->getCafeStatus().report(status); + } delete dwf; //------------------------------------------------------------ //Data retrieval methods returning a std::vector //------------------------------------------------------------ - vector dV; + vector dV; dbr_short_t alarmSta; dbr_short_t alarmSe; epicsTimeStamp tsta; - cout << "nELEM n: " << cafe->getHandleHelper().getNelemNative (hArray[2]) << endl; - cout << "nELEM r: " << cafe->getHandleHelper().getNelemRequest(hArray[2]) << endl; - cout << "nELEM c: " << cafe->getHandleHelper().getNelemClient (hArray[2]) << endl; + //cout << "nELEM native: " << cafe->getHandleHelper().getNelemNative (hArray[2]) << endl; + //cout << "nELEM requested over ca: " << cafe->getHandleHelper().getNelemRequest(hArray[2]) << endl; + //cout << "nELEM client requested: " << cafe->getHandleHelper().getNelemClient (hArray[2]) << endl; cout << "set nelem to 16, get: " << cafe->getHandleHelper().setNelem(hArray[2],16) << endl;; - cout << "nELEM n: " << cafe->getHandleHelper().getNelemNative (hArray[2]) << endl; - cout << "nELEM r: " << cafe->getHandleHelper().getNelemRequest(hArray[2]) << endl; - cout << "nELEM c: " << cafe->getHandleHelper().getNelemClient (hArray[2]) << endl; + //cout << "nELEM native: " << cafe->getHandleHelper().getNelemNative (hArray[2]) << endl; + //cout << "nELEM requested over ca: " << cafe->getHandleHelper().getNelemRequest(hArray[2]) << endl; + //cout << "nELEM client requested: " << cafe->getHandleHelper().getNelemClient (hArray[2]) << endl; // - cout << "get nelem cache get: " << cafe->getHandleHelper().getNelemToRetrieveFromCache(hArray[2]) << endl; + //cout << "get nelem cache get: " << cafe->getHandleHelper().getNelemToRetrieveFromCache(hArray[2]) << endl; cout << "set nelem cache to 12, get: " << cafe->getHandleHelper().setNelemToRetrieveFromCache(hArray[2],12) << endl; - cout << "get nelem cache get: " << cafe->getHandleHelper().getNelemToRetrieveFromCache(hArray[2]) << endl; + //cout << "get nelem cache get: " << cafe->getHandleHelper().getNelemToRetrieveFromCache(hArray[2]) << endl; //Will retrieve 16 elements status=cafe->get(hArray[2], dV); - cout << "dV.size " << dV.size() << endl; + + if (status != ICAFE_NORMAL) { + cout << "Status = " << status << "; indicates an error at " << __METHOD__ << "//" << __LINE__ << endl; + cafe->getCafeStatus().report(status); + } + else { + cout << "dV.size will be 16 -> " << dV.size() << endl; + } //Will retrieve 12 elements from cache status=cafe->getCache(hArray[2], dV, alarmSta, alarmSe, tsta); - cout << "status " << status << endl; - cout << "dV.size " << dV.size() << endl; + + cout << "dV.size will be 12 -> " << dV.size() << endl; if (status != ICAFE_NORMAL) { - cout << "Status indicates an error at line no." << __LINE__ << endl; - cstat.report(status); + cout << "Status = " << status << "; indicates an error at " << __METHOD__ << "//" << __LINE__ << endl; + cafe->getCafeStatus().report(status); } else { cout << PV_WF << " successfully read out " << endl; cout << "Elements 1-5 of WF have values:" << endl; - for (int i=0; iterminate(); + //exit(1); + + cout << "------------------------------------------------------------" << endl; + cout << "START: (5) Handling Enumerated Types " << endl; + cout << "------------------------------------------------------------" << endl; + + //GET INFORMATION OF ENUM PV + PVCtrlHolder pvCtrl; + status=cafe->getCtrl(PV_MBBI, pvCtrl); + + vector enums= pvCtrl.getEnumStrings(); + cout << "------------------------" << endl; + cout << "ENUM NAME/VALUE PAIRS ARE:" << endl; + for (int i=0; iget(PV_MBBI, enumStrVal); + cout << "VALUE as string: " << enumStrVal << endl; + + + cout << "getEnumFromString: " << pvCtrl.getEnumFromString(enumStrVal) << endl; + + unsigned short enumShortVal; + status= cafe->get(PV_MBBI, enumShortVal); + cout << "VALUE as int: " << enumShortVal << endl; + + cout << "getStringFromEnum: " << pvCtrl.getStringFromEnum(enumShortVal) << endl; + + + PVDataHolder pvDat; + status= cafe->get(PV_MBBI, pvDat); + cout << "VALUE as string: " << pvDat.getAsString() << endl; + cout << "VALUE as int: " << pvDat.getAsUShort() << endl; + cout << "Integer Value as String: " << pvDat.getEnumIntegerValueAsString() << endl; + + //Each of these 3 methods will set the pv value to 1, i.e., "on" + status = cafe->set(PV_MBBI, "on"); + status = cafe->set(PV_MBBI, 1); + status = cafe->set(PV_MBBI, " 1 "); //leading and trailing spaces are ignored + + //try to set an illegal value + status = cafe->set(PV_MBBI, "invalid enum name"); + cafe->printStatus(PV_MBBI,status); + + + cout << "------------------------------------------------------------" << endl; + cout << "END: (5) Handling Enumerated Types " << endl; + cout << "------------------------------------------------------------" << endl; cout << "------------------------------------------------------------" << endl; @@ -492,40 +638,61 @@ int main( int argc, char *argv[] ) cout << "------------------------------------------------------------" << endl; vector statusV; - cafe->getScalars(hV, dV, statusV); + //vector of doubles + status=cafe->getScalars(hV, dV, statusV); - for (unsigned int i=0; iprintStatusIfError(hV[i],statusV[i]); + } + } + else { + for (unsigned int i=0; iset(hV[0], 3.214); + if (status != ICAFE_NORMAL) { + cout << "Status = " << status << "; indicates an error at " << __METHOD__ << "//" << __LINE__ << endl; + cafe->getCafeStatus().report(status); + } //or Asynchronous gets - cafe->get(hV, statusV); - cafe->getCache(hV, dV, statusV); - - - for (unsigned int i=0; iget(hV, statusV); + if (status != ICAFE_NORMAL) { + cout << "Status = " << status << "; indicates an error at " << __METHOD__ << "//" << __LINE__ << endl; + cafe->getCafeStatus().report(status); + } + else { + status=cafe->getCache(hV, dV, statusV); + + for (unsigned int i=0; igetNelemNative(hArray[i])); } - - + //input Array of handles cout << "---------------------------------------" << endl; cout << "status=cafe->get(hArray, NHANDLES, pvdArray)" << endl; @@ -541,6 +708,11 @@ int main( int argc, char *argv[] ) status=cafe->getPVArray(hV, pvdArray); + if (status != ICAFE_NORMAL) { + for (size_t i=0; iprintStatusIfError(hV[i],pvdArray[i].getStatus()); + } + } //Asynchronous get cout << "---------------------------------------" << endl; @@ -553,7 +725,7 @@ int main( int argc, char *argv[] ) status=cafe->get(hArray, NHANDLES, statusArray); if (status != ICAFE_NORMAL) { - //cstat.report(status); + //cafe->getCafeStatus().report(status); for (size_t i=0; iprintStatusIfError(hArray[i],statusArray[i]); } @@ -570,11 +742,87 @@ int main( int argc, char *argv[] ) cout << "------------------------------------------------------------" << endl; - cout << " END: (5) Mulitple Compound Operations " << endl; + cout << " END: (5) Multiple Compound Operations " << endl; cout << "------------------------------------------------------------" << endl; + + cout << "------------------------------------------------------------" << endl; + cout << "START: (9) Asynchronous interactions and retrieving data from cache " << endl; + cout << "------------------------------------------------------------" << endl; + //status=cafe->get(hArray[0]); + //by array + //status=cafe->get(hArray, NHANDLES, statusV); + //by vector + //status=cafe->get(hV, statusV); + + + //status=cafe->get(pvArray[0].c_str()); + //by array + //status=cafe->get(pvArray, NHANDLES, statusV); + //by vector + + // hV=cafe->getHandleHelper().getHandlesFromPVs(pvV); + + //for (int i=0; i< hV.size(); ++i) { + // cout << hV[i] << " " << pvV[i] << endl; + //} + + status=cafe->get(pvV, statusV); + + if (status != ICAFE_NORMAL) { + cout << "//ERROR MESSAGE REPORT// " << endl; + for (int i=0; i printStatusIfError(pvV[i].c_str(), statusV[i]); + } + } + cout << "//--------------------// " << endl; + } + + + //cafe->_ca_flush_io(); + cafe->flushNow(); + + status=cafe->getCache(hArray, NHANDLES, pvdArray); + + + status=cafe->getCachePVArray(hV, pvdArray); + + + + for (size_t i=0; iset(hArray[1], 3.333455666); + cafe->flushNow(); + cafe->get(hArray[1]); + cafe->flushNow(); + + + status=cafe->getCache(hV, pvdArray); + + + for (size_t i=0; igetCache(hV, dV, statusV); + + //for (size_t i=0; igetCafeStatus().report(e.groupEx.statusCode); exit(1); } @@ -611,7 +859,7 @@ int main( int argc, char *argv[] ) PVDataHolder * pvdA = pvgroup.getPVData(); - pvdA[0].setNelem(1); //just an example, only required if user wishes to set nelemens for wf from native + pvdA[0].setNelem(1); //just an example, only required if user wishes to set nelems for wf to other than native cafe->groupGet(gHandle, pvgroup); @@ -621,13 +869,12 @@ int main( int argc, char *argv[] ) pvgroup.print(pvgroup.getNPV(),25); - //Overwrite values for set method pvdA[0].set(1.111); - double d4[4]= {1,2,3,4}; + float d4[4]= {1,2,3,4}; pvdA[2].set(d4); - + status=cafe->groupSet(gHandle, pvgroup); cafe->groupGet(gHandle, pvgroup); @@ -649,7 +896,7 @@ int main( int argc, char *argv[] ) //Will send to /tmp - cafe->snapshot2XML(pvgroup); + //cafe->snapshot2XML(pvgroup); @@ -659,7 +906,7 @@ int main( int argc, char *argv[] ) cout << "------------------------------------------------------------" << endl; - cout << "START: (7) Control System Parameters and Channel Information" << endl; + cout << "START: (7) Control System Parameters " << endl; cout << "------------------------------------------------------------" << endl; // An example of a single get that retrieves control display parameters @@ -713,7 +960,7 @@ int main( int argc, char *argv[] ) cout << "------------------------------------------------------------" << endl; - cout << " END: (7) Control System Parameters and Channel Information" << endl; + cout << " END: (7) Control System Parameters" << endl; cout << "------------------------------------------------------------" << endl; cout << "------------------------------------------------------------" << endl; @@ -819,6 +1066,7 @@ int main( int argc, char *argv[] ) usleep(100000); // 0.1s just about long enough to trigger an extra monitor + cafe->monitorStop(hArray[0], mp); cafe->monitorStop(hArray[0], mp2.getMonitorID()); //Actually, only the monitorID is required @@ -850,58 +1098,7 @@ int main( int argc, char *argv[] ) cout << " END: (8) Monitors, either with or without user supplied callbacks " << endl; cout << "------------------------------------------------------------" << endl; - - cout << "------------------------------------------------------------" << endl; - cout << "START: (9) Asynchronous interactions and retrieving data from cache " << endl; - cout << "------------------------------------------------------------" << endl; - status=cafe->get(hArray[0]); - //by array - status=cafe->get(hArray, NHANDLES, statusV); - //by vector - status=cafe->get(hV, statusV); - - //cafe->_ca_flush_io(); - cafe->flushNow(); - - status=cafe->getCache(hArray, NHANDLES, pvdArray); - - int NL=10; - system("date"); - for (int i=0; igetCachePVArray(hV, pvdArray); - } - system("date"); - - sleep(1); - for (size_t i=0; iset(hArray[1], 3.333455666); - cafe->get(hArray[1]); - cafe->flushNow(); - system("date"); - for (int i=0; igetCache(hV, pvdArray); - } - system("date"); - - for (size_t i=0; igetCache(hV, dV, statusV); - - //for (size_t i=0; igetHandleHelper().checkConsistency(); + if (status != ICAFE_NORMAL) { + cafe->getCafeStatus().report(status); + } + + + cafe->groupClose(); + cafe->closeHandles(); + + cafe->terminate(); + return 0; cout << "------------------------------------------------------------" << endl; cout << " END: (12) Gracefully terminate CAFE " << endl; cout << "------------------------------------------------------------" << endl; - - cafe->printHandles(); - - cafe->groupClose(); - cafe->closeHandles(); - cafe->terminate(); - return 0; @@ -984,7 +1191,7 @@ int main( int argc, char *argv[] ) cout << "Channel: " << pvgroup.getPVData()[i].getPVName() << endl; cout << "Status: " << pvgroup.getPVData()[i].getStatus() << " [" << i << "] of " << pvgroup.getNPV() << endl; - cstat.report( pvgroup.getPVData()[i].getStatus() ); + cafe->getCafeStatus().report( pvgroup.getPVData()[i].getStatus() ); } } } diff --git a/examples/cafeTest/callbacks.h b/examples/cafeTest/callbacks.h index af4eef4..a8f743c 100644 --- a/examples/cafeTest/callbacks.h +++ b/examples/cafeTest/callbacks.h @@ -31,31 +31,31 @@ void callbackHandlerMonitor( struct event_handler_args args) { if (args.type < DBR_GR_STRING) { PVDataHolder pvd(args.count); (*it_handle).getPVDataHolder(pvd); - pvd.print(); - cout << "val/D//= " << pvd.getAsString(0) << endl; + //pvd.print(); + //cout << "val/D//= " << pvd.getAsString(0) << endl; } else if (args.type < DBR_PUT_ACKT) { PVCtrlHolder pvc(args.count); (*it_handle).getPVCtrlHolder(pvc); - pvc.print(); - cout << "val/C/= " << pvc.getAsString(0) << endl; + //pvc.print(); + //cout << "val/C/= " << pvc.getAsString(0) << endl; } + + //cout << "args.usr = " << (unsigned int) args.usr << endl; + //cout << "getUsrArgs() = " << (unsigned int) (*it_handle).getUsrArgs() << endl; + + /* vector mpV = (*it_handle).getMonitorPolicyVector(); - - - cout << args.usr << endl; - cout << (*it_handle).getUsrArgs() << endl; - - for (int i=0; i & V, int getCache(const unsigned int _handle, vector & V, dbr_short_t &alarmStatus, dbr_short_t &alarmSeverity, epicsTimeStamp &ts);//6 - +//NON_BLOCKING int get(vector handleV, vector &statusV); int getV(vector handleV, vector &statusV){ - status=get(handleV, statusV); ca_flush_io(); //Yes let's flush here! + status=get(handleV, statusV); ca_flush_io(); //Yes let's flush here! return status;} +int get(vector pvV, vector &statusV) { + vector hV; + hV.reserve(pvV.size()); + hV=handleHelper.getHandlesFromPVs(pvV); + return get(hV, statusV); + +} + + int getScalars(vector handleV, vector & V, vector &statusV){ //0 CAFE::get(handleV, statusV); CAFE::waitForBundledEvents(handleV, statusV); diff --git a/include/connect.h b/include/connect.h index a085ab3..3b98866 100644 --- a/include/connect.h +++ b/include/connect.h @@ -40,6 +40,10 @@ class Connect CAFEStatus cafeStatus; CAFEStatusSeverity cafeStatusSeverity; + CAFEGlobalAlarmSeverity epicsAlarmSeverity; + CAFEGlobalAlarmCondition epicsAlarmStatus; + + cafeConduit_set::iterator itcs; cafeGroup_set::iterator itgs; @@ -140,6 +144,11 @@ class Connect CAFEStatus getCafeStatus() {return cafeStatus;} CAFEStatusSeverity getCafeStatusSeverity() {return cafeStatusSeverity;} + CAFEGlobalAlarmCondition getEpicsAlarmStatus() {return epicsAlarmStatus;} + CAFEGlobalAlarmCondition getEpicsAlarmCondition() {return epicsAlarmStatus;} + CAFEGlobalAlarmSeverity getEpicsAlarmSeverity() {return epicsAlarmSeverity;} + + int flushNow() {return ca_flush_io();} int _ca_flush_io(){return ca_flush_io();} @@ -493,6 +502,13 @@ class Connect int printStatusIfError(vector handleV, vector statusV); + int printStatus(const char *pv, int status); + int printStatusIfError(const char *pv, int status); + int printStatus(const char * pvArray, unsigned int nelem, int * statusArray); + int printStatusIfError(const char * pvArray, unsigned int nelem, int * statusArray); + int printStatus(vector pvV, vector statusV); + int printStatusIfError(vector pvV, vector statusV); + int setPVAlias(unsigned int handle, const char * pv) throw (CAFEException_open); // GROUP FUNCTIONS diff --git a/include/handleHelper.h b/include/handleHelper.h index aed7ca2..6808d41 100644 --- a/include/handleHelper.h +++ b/include/handleHelper.h @@ -83,6 +83,8 @@ class HandleHelper : public Helper { unsigned int getHandleFromPVAlias(const char * _pv); unsigned int getHandleFromPVAlias(const char * _pv, ca_client_context * ccc); + vector getHandlesFromPVs(vector pvV, ca_client_context * ccc); + vector getHandlesFromPVs(vector pvV); vector getHandlesFromWithinGroupV(unsigned int gh); unsigned int * getHandlesFromWithinGroup(unsigned int gh); diff --git a/include/instant.cpp b/include/instant.cpp index b4f1779..c81bb72 100644 --- a/include/instant.cpp +++ b/include/instant.cpp @@ -764,15 +764,15 @@ template int Instant::clientRequests( if (it_handle != handle_index.end()) { - union db_access_val * PVDataL; - unsigned int nelem; - //unsigned int offset; - chtype dbrTypeRequest_DataBuffer; + //union db_access_val * PVDataL; + //unsigned int nelem; + + //chtype dbrTypeRequest_DataBuffer; - PVDataL = (*it_handle).getPutBuffer (); - nelem = (*it_handle).getChannelRequestMetaPrimitive().getNelem(); + //PVDataL = (*it_handle).getPutBuffer (); + //nelem = (*it_handle).getChannelRequestMetaPrimitive().getNelem(); - dbrTypeRequest_DataBuffer = (*it_handle).getChannelRequestMetaPrimitive().getDbrDataType(); + //dbrTypeRequest_DataBuffer = (*it_handle).getChannelRequestMetaPrimitive().getDbrDataType(); switch(_dbrType) { case DBR_STRING: @@ -805,15 +805,7 @@ template int Instant::clientRequests( return ECAFE_INVALID_SWITCH_CASE; break; } - /* - epicsTimeStamp ts; - ts.secPastEpoch= 0; // default value if cache does not have timeStamp - ts.nsec = 0; // default value if cache does not have timeStamp - dbr_short_t alarmStatus =-1; // default value if cache does not have alarmStatus - dbr_short_t alarmSeverity =-1; // default value if cache does not have alarmSeverity - //helper function to set TimeStamps! - helper.setSTS(_handle, alarmStatus, alarmSeverity, ts); - */ + } else { diff --git a/include/makefile b/include/makefile index 2932b8e..9ad2a17 100644 --- a/include/makefile +++ b/include/makefile @@ -186,7 +186,7 @@ htmldir = ${docdir} includedir = ${prefix}/include infodir = ${datarootdir}/info install_sh = ${SHELL} /afs/psi.ch/project/cafe/gitlab/CAFE/cpp/install-sh -libdir = /opt/gfa/cafe/cpp/cafe-1.3.0-final-1/lib +libdir = /opt/gfa/cafe/cpp/cafe-1.3.0-final-2/lib libexecdir = ${exec_prefix}/libexec localedir = ${datarootdir}/locale localstatedir = ${prefix}/var @@ -195,7 +195,7 @@ mandir = ${datarootdir}/man mkdir_p = /bin/mkdir -p oldincludedir = /usr/include pdfdir = ${docdir} -prefix = /opt/gfa/cafe/cpp/cafe-1.3.0-final-1 +prefix = /opt/gfa/cafe/cpp/cafe-1.3.0-final-2 program_transform_name = s,x,x, psdir = ${docdir} sbindir = ${exec_prefix}/sbin diff --git a/include/statusCodes.h b/include/statusCodes.h index c574562..7f630df 100644 --- a/include/statusCodes.h +++ b/include/statusCodes.h @@ -107,7 +107,8 @@ enum CAFE_ERROR_STATE { ECAFE_NODATA=ICAFE_STATUS_ERROR, ECAFE_INVALID_ENUM_INDEX, ECAFE_PVGROUP_GROUPHANDLE_MISMATCH, ECAFE_TIMEOUT_SET_AND_MATCH, - ECAFE_HANDLE_MISMATCH_SET_AND_MATCH + ECAFE_HANDLE_MISMATCH_SET_AND_MATCH, + ECAFE_INCONSISTENT_CONTAINER_CORRECTED }; enum CAFE_FILE_ERROR { ECAFE_LOAD_COLLECTION=ICAFE_FILE_ERROR, @@ -415,6 +416,7 @@ public: * 1033 ECAFE_PVGROUP_GROUPHANDLE_MISMATCH \n * 1034 ECAFE_TIMEOUT_SET_AND_MATCH \n * 1035 ECAFE_HANDLE_MISMATCH_SET_AND_MATCH \n +* 1036 ECAFE_INCONSISTENT_CONTAINER_CORRECTED \n * 1100 ECAFE_LOAD_COLLECTION \n * 1101 ECAFE_LOAD_GROUP \n * 1200 ECAFE_BPM_DATA_IS_INVALID \n @@ -507,7 +509,10 @@ public: mapStatusInfo.insert(std::make_pair((int) ECAFE_TIMEOUT_SET_AND_MATCH, "Readback channel did not reach set value within specified timeout period ")); mapStatusInfo.insert(std::make_pair((int) ECAFE_HANDLE_MISMATCH_SET_AND_MATCH, "Number of set/readback handles do not match")); - mapStatusInfo.insert(std::make_pair((int) ECAFE_LOAD_COLLECTION, "CAFE collection could not be loaded from xml configuration file " )); + mapStatusInfo.insert(std::make_pair((int) ECAFE_INCONSISTENT_CONTAINER_CORRECTED, "Boost container required update after consistency check")); + + + mapStatusInfo.insert(std::make_pair((int) ECAFE_LOAD_COLLECTION, "CAFE collection could not be loaded from xml configuration file " )); mapStatusInfo.insert(std::make_pair((int) ECAFE_LOAD_GROUP, "CAFE group could not be loaded from group xml configuration file " )); mapStatusInfo.insert(std::make_pair((int) ECAFE_BPM_DATA_IS_INVALID, "CAFE BPM Service: Data Validity channel reports BPM data is INVALID " )); @@ -659,12 +664,15 @@ public: mapStatusCode.insert(std::make_pair((int) ECAFE_HASH_UNIQUEID_EXISTS, "CAFE ERROR: ECAFE_HASH_UNIQUEID_EXISTS")); mapStatusCode.insert(std::make_pair((int) ECAFE_WRONG_CA_CONTEXT, "CAFE ERROR: ECAFE_WRONG_CA_CONTEXT")); mapStatusCode.insert(std::make_pair((int) ECAFE_INVALID_CAFENUM_POLICY_TYPE, "CAFE ERROR: ECAFE_INVALID_CAFENUM_POLICY_TYPE")); - mapStatusCode.insert(std::make_pair((int) ECAFE_MAX_MONITORS_PER_CHAN_EXCEEDED, "CAFE_ERROR: ECAFE_MAX_MONITORS_PER_CHAN_EXCEEDED")); - mapStatusCode.insert(std::make_pair((int) ECAFE_INVALID_ENUM_INDEX, "CAFE_ERROR: ECAFE_INVALID_ENUM_INDEX")); + mapStatusCode.insert(std::make_pair((int) ECAFE_MAX_MONITORS_PER_CHAN_EXCEEDED, "CAFE_ERROR: ECAFE_MAX_MONITORS_PER_CHAN_EXCEEDED")); + mapStatusCode.insert(std::make_pair((int) ECAFE_INVALID_ENUM_INDEX, "CAFE_ERROR: ECAFE_INVALID_ENUM_INDEX")); mapStatusCode.insert(std::make_pair((int) ECAFE_PVGROUP_GROUPHANDLE_MISMATCH, "CAFE ERROR:ECAFE_PVGROUP_GROUPHANDLE_MISMATCH")); mapStatusCode.insert(std::make_pair((int) ECAFE_TIMEOUT_SET_AND_MATCH, "CAFE ERROR: CAFE_TIMEOUT_SET_AND_MATCH")); mapStatusCode.insert(std::make_pair((int) ECAFE_HANDLE_MISMATCH_SET_AND_MATCH, "CAFE ERROR: CAFE_HANDLE_MISMATCH_SET_AND_MATCH")); + mapStatusCode.insert(std::make_pair((int) ECAFE_INCONSISTENT_CONTAINER_CORRECTED,"CAFE ERROR: ECAFE_INCONSISTENT_CONTAINER_CORRECTED")); + + mapStatusCode.insert(std::make_pair((int) ECAFE_LOAD_COLLECTION, "CAFE ERROR: ECAFE_LOAD_COLLECTION")); mapStatusCode.insert(std::make_pair((int) ECAFE_LOAD_GROUP, "CAFE ERROR: ECAFE_LOAD_GROUP")); @@ -871,6 +879,9 @@ public: mapStatusSeverity.insert(std::make_pair((int) ECAFE_TIMEOUT_SET_AND_MATCH, "WARN")); mapStatusSeverity.insert(std::make_pair((int) ECAFE_HANDLE_MISMATCH_SET_AND_MATCH, "ERROR")); + mapStatusSeverity.insert(std::make_pair((int) ECAFE_INCONSISTENT_CONTAINER_CORRECTED, "WARN")); + + mapStatusSeverity.insert(std::make_pair((int) ECAFE_LOAD_COLLECTION, "ERROR")); mapStatusSeverity.insert(std::make_pair((int) ECAFE_LOAD_GROUP, "ERROR")); @@ -967,6 +978,10 @@ class CAFEStatus { strRet.append(csi.message(i)); return (std::string) strRet; } + + bool isTimeout(int i) { + return csc.isTimeout(i); + } void report (int i) { std::cout << "------------------" << std::endl; diff --git a/include/transpose.h b/include/transpose.h index d7cdf7d..2c78184 100644 --- a/include/transpose.h +++ b/include/transpose.h @@ -311,6 +311,12 @@ template int Transpose::put(const unsigned int _handle, }//if noStrings>0 }//if + + + //cout << "dbrTypeRequest_DataBuffer " << dbrTypeRequest_DataBuffer << endl; + //cout << "_dbrType " << _dbrType << endl; + + //cout << "nelem " << nelem << endl; switch (dbrTypeRequest_DataBuffer) { @@ -444,9 +450,12 @@ template int Transpose::put(const unsigned int _handle, } break; case DBR_DOUBLE: //6 + for (unsigned int i=0; i int Transpose::put(const unsigned int _handle, return ECAFE_INVALID_HANDLE; } - + cout << "status " << status << endl; return status; diff --git a/makefile b/makefile index f2cdb6e..daf417d 100644 --- a/makefile +++ b/makefile @@ -227,7 +227,7 @@ htmldir = ${docdir} includedir = ${prefix}/include infodir = ${datarootdir}/info install_sh = ${SHELL} /afs/psi.ch/project/cafe/gitlab/CAFE/cpp/install-sh -libdir = /opt/gfa/cafe/cpp/cafe-1.3.0-final-1/lib +libdir = /opt/gfa/cafe/cpp/cafe-1.3.0-final-2/lib libexecdir = ${exec_prefix}/libexec localedir = ${datarootdir}/locale localstatedir = ${prefix}/var @@ -236,7 +236,7 @@ mandir = ${datarootdir}/man mkdir_p = /bin/mkdir -p oldincludedir = /usr/include pdfdir = ${docdir} -prefix = /opt/gfa/cafe/cpp/cafe-1.3.0-final-1 +prefix = /opt/gfa/cafe/cpp/cafe-1.3.0-final-2 program_transform_name = s,x,x, psdir = ${docdir} sbindir = ${exec_prefix}/sbin diff --git a/src/cafe.cpp b/src/cafe.cpp index bfb480a..d0c9de9 100644 --- a/src/cafe.cpp +++ b/src/cafe.cpp @@ -618,7 +618,7 @@ int CAFE::get(const char * pv, PVDataHolder & pvd) { int CAFE::get(const unsigned int handle, PVDataHolder & pvd) { #define __METHOD__ "CAFE::get(unsigned int handle, PVDataHolder & pvd)" - cout << __FILE__ << " " << __LINE__ << " " << __METHOD__ << endl; + //cout << __FILE__ << " " << __LINE__ << " " << __METHOD__ << endl; status=ICAFE_NORMAL; diff --git a/src/connect.cpp b/src/connect.cpp index f151106..4cf9076 100644 --- a/src/connect.cpp +++ b/src/connect.cpp @@ -2298,6 +2298,127 @@ int Connect::monitorStart(vector handleV, vector &statusV, } + + + + /** + * \brief print status information of given pv + * \param pv input: pv for which handle is to be matched \n + * \param status input: reporting status \n + * \return ECA_NORMAL if all OK else ECAFE_INVALID_HANDLE + */ + int Connect::printStatus(const char *pv, int status) { + + unsigned int handle=handleHelper.getHandleFromPV(pv); + + if (handle==0) { + return ECAFE_INVALID_HANDLE; + } + return Connect::printStatus(handle, status); + + } + + + /** + * \brief print status information of given pv only on error + * \param pv input: pv for which handle is to be matched\n + * \param status input: reporting status \n + * \return ECA_NORMAL if all OK else ECAFE_INVALID_HANDLE + */ + int Connect::printStatusIfError(const char * pv, int status) { + + if (status==ICAFE_NORMAL) {return ICAFE_NORMAL;}; + + unsigned int handle=handleHelper.getHandleFromPV(pv); + + if (handle==0) { + return ECAFE_INVALID_HANDLE; + } + return Connect::printStatus(handle, status); + + } + + + /** + * \brief print status information of given PVs + * \param pvV input: vector of pvs for which handles to conduit objects are to be matched\n + * \param statusV input: vector of statuses \n + * \return ECA_NORMAL if all OK else ECAFE_INVALID_HANDLE (if one or more handles are invalid) + */ + int Connect::printStatus(vector pvV, vector statusV) { + + int overallStatus=ICAFE_NORMAL; bool isGood=true; + int localStatus=ICAFE_NORMAL; + for (unsigned int i=0; i < min(pvV.size(),statusV.size()); ++i) { + localStatus=Connect::printStatus(pvV[i].c_str(), statusV[i]); + if(isGood && localStatus!=ICAFE_NORMAL) {overallStatus=localStatus; isGood=false;} + } + return overallStatus; + } + + /** + * \brief print status information of given PVs only on error + * \param pvV input: vector of PVs for which handles to Conduit objects are to be matched\n + * \param statusV input: vector of statuses \n + * \return ECA_NORMAL if all OK else ECAFE_INVALID_HANDLE (if one or more handles are invalid) + */ + int Connect::printStatusIfError(vector pvV, vector statusV) { + int overallStatus=ICAFE_NORMAL; bool isGood=true; + int localStatus=ICAFE_NORMAL; + for (unsigned int i=0; i HandleHelper::getHandlesFromPVs(vector pvV) { + + ca_client_context * ccc = ca_current_context(); + + return getHandlesFromPVs(pvV,ccc); + +} + + +/** + * \brief Rerieves vector of handles for given vector of PVs + * \param pvV input: vector of PVS + * \param ccc input: ca_client_context * + * \param handleV output: vector of handles + * \return ICAFE_NORMAL if all OK else ECAFE_INVALID_HANDLE + */ +vector HandleHelper::getHandlesFromPVs(vector pvV, ca_client_context * ccc) { +#define __METHOD__ "HandleHelper::getHandlesFromPVs()" + + vector handleV; + + handleV.reserve(pvV.size()); + + + cafeConduit_set_by_pv & pv_index = cs.get (); + cafeConduit_set_by_pv::iterator it_pv; + + for (unsigned int i=0; i0) {continue;} // Channels within a group don't count! + + if (!strcmp((*itcs).getPV(), pvV[i].c_str()) && (*itcs).getClientContext()== ccc) { + + handleV.push_back((*itcs).handle); + break; + } + } + handleV.push_back(0); + } + } //for + + + + return handleV; +#undef __METHOD__ + +} + + /** * \brief Prints Conduit member values for all given handles * \return ICAFE_NORMAL if all OK else ECAFE_INVALID_HANDLE diff --git a/src/makefile b/src/makefile index 033f578..5a2298b 100644 --- a/src/makefile +++ b/src/makefile @@ -207,7 +207,7 @@ htmldir = ${docdir} includedir = ${prefix}/include infodir = ${datarootdir}/info install_sh = ${SHELL} /afs/psi.ch/project/cafe/gitlab/CAFE/cpp/install-sh -libdir = /opt/gfa/cafe/cpp/cafe-1.3.0-final-1/lib +libdir = /opt/gfa/cafe/cpp/cafe-1.3.0-final-2/lib libexecdir = ${exec_prefix}/libexec localedir = ${datarootdir}/locale localstatedir = ${prefix}/var @@ -216,7 +216,7 @@ mandir = ${datarootdir}/man mkdir_p = /bin/mkdir -p oldincludedir = /usr/include pdfdir = ${docdir} -prefix = /opt/gfa/cafe/cpp/cafe-1.3.0-final-1 +prefix = /opt/gfa/cafe/cpp/cafe-1.3.0-final-2 program_transform_name = s,x,x, psdir = ${docdir} sbindir = ${exec_prefix}/sbin