Files
cpp/src/cafeGroup.cpp
T
2021-03-16 09:30:56 +01:00

1848 lines
63 KiB
C++

///
/// \file cafeGroup.cpp
///
/// \author Jan Chrin, PSI
/// \date January 2016
/// \version CAFE 1.0.0
///
#include <cafe.h>
using namespace std;
//// Groups
/**
* \brief Fills the PVGroup object indentified by the groupHandle from memory.\n
* Does NOT do a "get". Method used to fill the PVGroup class with meta-data.
* \param _groupHandle input: handle to the group object
* \param pvgroup output: data pertaining to the object
* \return statusGroup
*/
int CAFE::groupFetch(const unsigned int _groupHandle, PVGroup &pvgroup)
{
#define __METHOD__ "groupFetch( _groupHandle, &pvgroup)"
string s = handleHelper.getGroupNameFromGroupHandle(_groupHandle);
if (s!="")
{
bool groupExists=false;
for (unsigned short i = 0; i < PVGroupV.size(); ++i)
{
if (strcmp(PVGroupV[i].name, s.c_str()) == 0)
{
pvgroup = PVGroupV[i];
pvgroup.groupHandle=_groupHandle;
groupExists=true;
break;
}
}
if (!groupExists)
{
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
cafeStatus.report(ECAFE_UNKNOWN_GROUP);
return ECAFE_UNKNOWN_GROUP;
}
}
else
{
return ECAFE_UNKNOWN_GROUP;
}
return ICAFE_NORMAL;
#undef __METHOD__
};
/**
* \brief Fills the PVGroup object indentified by the groupHandle from memory.\n
* Method used to fill the PVGroup class both with meta-data and actual data
* (from hash table)
* \param _groupHandle input: handle to the group object
* \param pvgroup output: data pertaining to the object
* \return statusGroup
*/
int CAFE::groupAttach(const unsigned int _groupHandle, PVGroup &pvgroup)
{
#define __METHOD__ "groupAttach(_groupHandle, &pvgroup)"
string s = handleHelper.getGroupNameFromGroupHandle(_groupHandle);
unsigned int iIdx;
if (s!="")
{
bool groupExists=false;
for (unsigned short i = 0; i < PVGroupV.size(); ++i)
{
if (strcmp(PVGroupV[i].name, s.c_str()) == 0)
{
pvgroup = PVGroupV[i];
iIdx=i;
groupExists=true;
break;
}
}
if (!groupExists)
{
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
cafeStatus.report(ECAFE_UNKNOWN_GROUP);
return ECAFE_UNKNOWN_GROUP;
}
}
else
{
return ECAFE_UNKNOWN_GROUP;
}
//Fill group from current data in hash table:
pvgroup.statusGroup=ICAFE_NORMAL;
cafeGroup_set_by_groupHandle & groupHandle_index = gs.get<by_groupHandle> ();
cafeGroup_set_by_groupHandle::iterator it_groupHandle;
it_groupHandle = groupHandle_index.find(_groupHandle);
if (it_groupHandle != groupHandle_index.end())
{
unsigned int nGroupMember = (*it_groupHandle).getNMember();
if (pvgroup.npv != (*it_groupHandle).getNMember())
{
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
cout << "A MISMATCH IN THE NUMBER OF GROUP MEMBERS DETECTED " << endl;
cout << "CLIENT (pvgroup.npv) CLAIMS " << pvgroup.npv
<< " CONDUITGROUP OBJECT CLAIMS " << (*it_groupHandle).getNMember() << endl;
nGroupMember = min(pvgroup.npv,(*it_groupHandle).getNMember());
cout << "TAKING SMALLER OF THE TWO NUMBERS " << endl;
}
cafeConduit_set_by_handle & handle_index = cs.get<by_handle> ();
cafeConduit_set_by_handle::iterator it_handle;
for (unsigned int iMember = 0; iMember < nGroupMember; ++iMember)
{
bool hf=false;
//reset
pvgroup.pvdata[iMember].alarmStatus =-1;
pvgroup.pvdata[iMember].alarmSeverity =-1;
pvgroup.pvdata[iMember].ts.secPastEpoch=0;
pvgroup.pvdata[iMember].ts.nsec=0;
pvgroup.pvdata[iMember].hasAlarm=true;
pvgroup.pvdata[iMember].hasTS=true;
pvgroup.pvdata[iMember].rule=true;
pvgroup.pvdata[iMember].status=ICAFE_NORMAL;
it_handle = handle_index.find((*it_groupHandle).mHandle[iMember]);
if (it_handle != handle_index.end())
{
hf=true;
}
if (!hf)
{
pvgroup.pvdata[iMember].status=ECAFE_INVALID_HANDLE;
if(MUTEX)
{
cafeMutex.lock();
}
groupHandle_index.modify(it_groupHandle,
change_sg_status(pvgroup.pvdata[iMember].status, iMember));
if(MUTEX)
{
cafeMutex.unlock();
}
cout << "WARNING: " << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
cafeStatus.report(ECAFE_INVALID_HANDLE);
cout << "Invalid handle = " << (*it_groupHandle).mHandle[iMember]
<< " for groupMember [" << iMember << "] " << endl;
pvgroup.statusGroup=ECAFE_INVALID_HANDLE;
continue;
}
if (!(*it_handle).getChannelRegalia().getConnectFlag())
{
if (pvgroup.statusGroup==ICAFE_NORMAL)
{
pvgroup.statusGroup=(*it_handle).getChannelRegalia().getCafeConnectionState();
}
}
//this sets size and nelem to 1 if not connected
//unsigned int a=
pvgroup.pvdata[iMember].setNelem( (*it_handle).getChannelRegalia().getNelem() );
//set Device, Attribute for handle
ChannelDeviceAttribute channelDeviceAttribute;
channelDeviceAttribute.init((*it_handle).pv, deviceAttributeDeliminator);
if(MUTEX)
{
cafeMutex.lock();
}
handle_index.modify(it_handle, change_channelDeviceAttribute(
channelDeviceAttribute));
if(MUTEX)
{
cafeMutex.unlock();
}
//Above lines replace need for handleHelper
// handleHelper.setChannelDeviceAttribute(deviceAttributeDeliminator);
(*it_handle).getPVDataHolder(pvgroup.pvdata[iMember]);
} //for
PVGroupV[iIdx]=pvgroup;
pvgroup.groupHandle=_groupHandle;
return pvgroup.statusGroup;
}
else
{
return ECAFE_INVALID_GROUP_HANDLE;
}
#undef __METHOD__
};
/**
* \brief Fills the PVGroup object indentified by pvgroup.groupHandle \n
* \param pvgroup input/output: data pertaining to the object
* \return statusGroup
*/
int CAFE::groupSet(PVGroup &pvgroup)
{
#define __METHOD__ "groupSet(&pvgroup)"
return CAFE::groupSet(pvgroup.groupHandle, pvgroup);
#undef __METHOD__
};
/**
* \brief Fills the PVGroup object indentified by the groupHandle \n
* \param _groupHandle input: handle to the group object
* \param pvgroup input/output: data pertaining to the object
* \return statusGroup
*/
int CAFE::groupSet(const unsigned int _groupHandle, PVGroup &pvgroup)
{
#define __METHOD__ "groupSet( _groupHandle, &pvgroup)"
if (pvgroup.npv==0)
{
cout << "WARNING: " << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
cafeStatus.report(ECAFE_EMPTY_GROUP);
return ECAFE_EMPTY_GROUP;
}
else if (pvgroup.groupHandle!=_groupHandle)
{
cout << "WARNING: " << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
cout << "Input groupHandle " << _groupHandle << " does not match that within pvgroup "
<< pvgroup.groupHandle << endl;
cout << "groupSet operation NOT attempted. Client clarification required! " << endl;
cafeStatus.report(ECAFE_PVGROUP_GROUPHANDLE_MISMATCH);
return ECAFE_PVGROUP_GROUPHANDLE_MISMATCH;
}
int gStatus=ICAFE_NORMAL;
cafeGroup_set_by_groupHandle & groupHandle_index = gs.get<by_groupHandle> ();
cafeGroup_set_by_groupHandle::iterator it_groupHandle;
it_groupHandle = groupHandle_index.find(_groupHandle);
if (it_groupHandle != groupHandle_index.end())
{
unsigned int nGroupMember = (*it_groupHandle).getNMember();
if (pvgroup.npv != (*it_groupHandle).getNMember())
{
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
cout << "A MISMATCH IN THE NUMBER OF GROUP MEMBERS DETECTED " << endl;
cout << "CLIENT (pvgroup.npv) CLAIMS " << pvgroup.npv
<< " CONDUITGROUP OBJECT CLAIMS " << (*it_groupHandle).getNMember() << endl;
nGroupMember = min(pvgroup.npv,(*it_groupHandle).getNMember());
cout << "TAKING SMALLER OF THE TWO NUMBERS " << endl;
}
cafeConduit_set_by_handle & handle_index = cs.get<by_handle> ();
cafeConduit_set_by_handle::iterator it_handle;
bool * nelemPreviousFlag = new bool [nGroupMember];
unsigned int * nelemPrevious = new unsigned int [nGroupMember];
for (unsigned int iMember = 0; iMember < nGroupMember; ++iMember)
{
bool hf=false;
//reset
pvgroup.pvdata[iMember].alarmStatus=-1;
pvgroup.pvdata[iMember].alarmSeverity=-1;
pvgroup.pvdata[iMember].ts.secPastEpoch=0;
pvgroup.pvdata[iMember].ts.nsec=0;
pvgroup.pvdata[iMember].status=ICAFE_NORMAL;
it_handle = handle_index.find((*it_groupHandle).mHandle[iMember]);
if (it_handle != handle_index.end())
{
hf=true;
if (pvgroup.pvdata[iMember].getRule() != (*it_groupHandle).getRule(iMember))
{
if(MUTEX)
{
cafeMutex.lock();
}
groupHandle_index.modify(it_groupHandle,
change_sg_rule(pvgroup.pvdata[iMember].rule, iMember));
if(MUTEX)
{
cafeMutex.unlock();
}
}
if (!pvgroup.pvdata[iMember].getRule() )
{
pvgroup.pvdata[iMember].status=ICAFE_RULE_FALSE;
}
if(MUTEX)
{
cafeMutex.lock();
}
groupHandle_index.modify(it_groupHandle,
change_sg_status(pvgroup.pvdata[iMember].status, iMember));
if(MUTEX)
{
cafeMutex.unlock();
}
}
if (!hf)
{
nelemPrevious[iMember]=0;
nelemPreviousFlag[iMember]=false;
pvgroup.pvdata[iMember].status=ECAFE_INVALID_HANDLE;
if(MUTEX)
{
cafeMutex.lock();
}
groupHandle_index.modify(it_groupHandle,
change_sg_status(pvgroup.pvdata[iMember].status, iMember));
if(MUTEX)
{
cafeMutex.unlock();
}
cout << "WARNING: " << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
cafeStatus.report(ECAFE_INVALID_HANDLE);
cout << "Invalid handle = " << (*it_groupHandle).mHandle[iMember]
<< " for groupMember [" << iMember << "] " << endl;
continue;
}
unsigned int handle=(*it_groupHandle).mHandle[iMember];
nelemPrevious[iMember]=handleHelper.getNelemClient(handle);
nelemPreviousFlag[iMember]=false;
//Find Native DataType
if ( (pvgroup.pvdata[iMember].status=cafeGranules.channelVerifyPut(handle,
pvgroup.pvdata[iMember].dataType)) != ICAFE_NORMAL)
{
if(MUTEX)
{
cafeMutex.lock();
}
groupHandle_index.modify(it_groupHandle,
change_sg_status(pvgroup.pvdata[iMember].status, iMember));
if(MUTEX)
{
cafeMutex.unlock();
}
cout << "WARNING: " << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
cout << "CHANNEL: " << pvgroup.pvdata[iMember].pv << endl;
cafeStatus.report(pvgroup.pvdata[iMember].status);
continue;
}
// Examine No of elements and set accordingly....
if (handleHelper.getNelemClient(handle) != pvgroup.pvdata[iMember].getNelem())
{
nelemPreviousFlag[iMember]=true;
handleHelper.setNelem(handle, pvgroup.pvdata[iMember].getNelem());
//cout << "INFO: " << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
//cout << "Changing handleHelper.getNelemClient(handle) to that given in pvgroup.pvdata[iMember].nelem " << endl;
//cout << "i.e., To: " << pvgroup.pvdata[iMember].nelem << " From: " << handleHelper.getNelemClient(handle) << endl;
}
if ( (pvgroup.pvdata[iMember].status=cafeGranules.channelPreparePut(handle))
!= ICAFE_NORMAL)
{
if(MUTEX)
{
cafeMutex.lock();
}
groupHandle_index.modify(it_groupHandle,
change_sg_status(pvgroup.pvdata[iMember].status, iMember));
if(MUTEX)
{
cafeMutex.unlock();
}
cout << "WARNING: " << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
cafeStatus.report(pvgroup.pvdata[iMember].status);
continue;
}
pvgroup.pvdata[iMember].dbrDataType=
((*it_handle).getChannelRequestMetaPrimitive().getDbrDataType());
switch ((*it_handle).getChannelRequestMetaPrimitive().getDbrDataType())
{
case DBR_STRING:
renderString.putString(handle, pvgroup.pvdata[iMember].val.get());
break;
case DBR_SHORT:
renderShort.put(handle, pvgroup.pvdata[iMember].val.get(), pvgroup.pvdata[iMember].dataType);
break;
case DBR_FLOAT:
renderFloat.put(handle, pvgroup.pvdata[iMember].val.get(), pvgroup.pvdata[iMember].dataType);
break;
case DBR_ENUM:
renderEnum.put(handle, pvgroup.pvdata[iMember].val.get(), pvgroup.pvdata[iMember].dataType);
break;
case DBR_CHAR:
renderChar.put(handle, pvgroup.pvdata[iMember].val.get(), pvgroup.pvdata[iMember].dataType);
break;
case DBR_LONG:
renderLong.put(handle, pvgroup.pvdata[iMember].val.get(), pvgroup.pvdata[iMember].dataType);
break;
case DBR_DOUBLE:
renderDouble.put(handle, pvgroup.pvdata[iMember].val.get(), pvgroup.pvdata[iMember].dataType);
break;
default:
cout << "ERROR: " << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
cafeStatus.report(ECAFE_INVALID_SWITCH_CASE);
cout << "SWITCH STATMENT NOT MEANT FOR CAFE DATATYPE=" <<
pvgroup.pvdata[iMember].dataType <<endl;
cout << "ABORTING DATA CONVERTION TO LOCAL putBuffer" << endl;
delete [] nelemPreviousFlag;
delete [] nelemPrevious;
return ECAFE_INVALID_SWITCH_CASE;
break;
}
} //for
//Put Data into putBuffer
gStatus=(*it_groupHandle).put();
//this returns normal even if a channel is not connected
channelTimeoutPolicySGPut = (*it_groupHandle).getChannelTimeoutPolicySGPut();
if (gStatus!=ECA_NORMAL && channelTimeoutPolicySGPut.getSelfGoverningTimeout())
{
cout << "WARNING: " << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
cafeStatus.report(gStatus);
}
channelTimeoutPolicySGPut = (*it_groupHandle).getChannelTimeoutPolicySGPut();
unsigned short ntries=0;
double originalTimeOut=channelTimeoutPolicySGPut.getTimeout();
//Withdraw this test for now; not required
//while ( (ca_sg_test((*it_groupHandle).getGroupID()) == ECA_IOINPROGRESS
// || gStatus == ECA_TIMEOUT) && channelTimeoutPolicySGPut.getSelfGoverningTimeout()
// && ntries<channelTimeoutPolicySGPut.getNtries()
// ) {
while ( (gStatus == ECA_TIMEOUT) && channelTimeoutPolicySGPut.getSelfGoverningTimeout()
&& ntries<channelTimeoutPolicySGPut.getNtries()
)
{
++ntries;
//CAFEStatus cafeStatus;
//Withdraw this test for now; not required
//if (ca_sg_test((*it_groupHandle).getGroupID()) == ECA_IOINPROGRESS ) {
// cout << "WARNING: " << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
// cafeStatus.report(ECA_IOINPROGRESS);
//}
if (gStatus == ECA_TIMEOUT)
{
cout << "WARNING: " << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
cafeStatus.report(ECA_TIMEOUT);
}
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
cout << "Changing SG PUT timeout from: " << channelTimeoutPolicySGPut.getTimeout()
<< " to: " <<
(originalTimeOut + channelTimeoutPolicySGPut.getDeltaTimeout()*ntries)
<< " seconds" <<endl;
channelTimeoutPolicySGPut.setTimeout( (originalTimeOut +
channelTimeoutPolicySGPut.getDeltaTimeout()*ntries));
if(MUTEX)
{
cafeMutex.lock(); //lock
}
groupHandle_index.modify(it_groupHandle,
change_channelTimeoutPolicySGPut(channelTimeoutPolicySGPut));
if(MUTEX)
{
cafeMutex.unlock(); //unlock
}
if (gStatus == ECA_TIMEOUT)
{
gStatus=(*it_groupHandle).put();
}
} //while
if (ntries > 0 )
{
//if (ntries >= channelTimeoutPolicySGPut.getNtries() ) {
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
std::cout << "No of(additional) tries=" << ntries << std::endl;
if (gStatus==ECAFE_TIMEOUT)
{
std::cout << "is the MAXIMUM allowed as configured through SGTimeoutPolicy! " << std::endl;
std::cout << "SETTING SELF-GOVERNING TIMEOUT FOR SG PUT OPERATIONS FOR THIS CHANNEL TO FALSE" << std::endl;
std::cout << "RESTORING TIMEOUT TO ORIGINAL SG PUT VALUE OF: " << originalTimeOut << " SECONDS " << std::endl;
channelTimeoutPolicySGPut.setSelfGoverningTimeout(false);
channelTimeoutPolicySGPut.setTimeout( originalTimeOut );
if(MUTEX)
{
cafeMutex.lock(); //lock
}
groupHandle_index.modify(it_groupHandle,
change_channelTimeoutPolicySGPut(channelTimeoutPolicySGPut));
if(MUTEX)
{
cafeMutex.unlock(); //unlock
}
}
else
{
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
cout << "Changed SG PUT from intitial " << originalTimeOut << " to: " <<
(originalTimeOut +
channelTimeoutPolicySGPut.getDeltaTimeout()*ntries)
<< " seconds after " << ntries << " sg_put calls " <<endl;
}
} //IF
//Withdraw this test for now; not required
//if (ca_sg_test((*it_groupHandle).getGroupID()) == ECA_IOINPROGRESS) {
// ca_sg_reset((*it_groupHandle).getGroupID());
// cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
// std::cout << " No. of ca_sg_test(gid) INSTIGATED: " << ntries+1 << std::endl;
// std::cout
// << " ca_sg_reset(gid) HAS BEEN FORCED SO THAT ca_sg_test() returns ECA_IODONE"
// <<std::endl;
// std::cout << " ***PLEASE** REPORT THIS OCCURRENCE TO jan.chrin@psi.ch THANKS!! "
// << std::endl;
//}
int * mstatus =(*it_groupHandle).getStatus();
bool groupStatusFlag = false;
pvgroup.statusGroup= gStatus; //ICAFE_NORMAL;
if (pvgroup.statusGroup==ECA_TIMEOUT)
{
groupStatusFlag = true;
}
for (unsigned int iMember = 0; iMember< (*it_groupHandle).getNMember(); ++iMember)
{
if (pvgroup.pvdata[iMember].status == ECAFE_INVALID_HANDLE)
{
continue;
}
it_handle = handle_index.find((*it_groupHandle).mHandle[iMember]);
if (it_handle != handle_index.end())
{
//do nothing as handle exists
if (nelemPreviousFlag[iMember]==true)
{
handleHelper.setNelem((*it_groupHandle).mHandle[iMember], nelemPrevious[iMember]);
}
}
else
{
//Should not get this far if invalid handle
cout << "WARNING: " << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
cafeStatus.report(ECAFE_INVALID_HANDLE);
cout << "Invalid handle = " << (*it_groupHandle).mHandle[iMember] << " for groupMember [" << iMember << "] " << endl;
continue;
}
if(MUTEX)
{
cafeMutex.lock();
}
handle_index.modify(it_handle, change_status( mstatus[iMember] ));
if(MUTEX)
{
cafeMutex.unlock();
}
if (mstatus[iMember]!=ICAFE_NORMAL)
{
pvgroup.pvdata[iMember].status = mstatus[iMember];
if (pvgroup.pvdata[iMember].status != ICAFE_NORMAL
&& pvgroup.pvdata[iMember].status != ICAFE_RULE_FALSE
&& !groupStatusFlag)
{
pvgroup.statusGroup = pvgroup.pvdata[iMember].status;
groupStatusFlag = true;
}
continue;
}
} // for iMember
delete [] nelemPreviousFlag;
delete [] nelemPrevious;
return pvgroup.statusGroup;
}
else
{
return ECAFE_INVALID_GROUP_HANDLE;
}
#undef __METHOD__
}
/**
*
* \brief Retrieves scalar value from the PVGroup object indentified by the group handle \n
* \param _groupHandle input: handle to the group object
* \param valV output: vector of syting values
* \param statusV output: vector of int values reporting the status
* \return statusGroup
*/
int CAFE::groupGetScalar(const unsigned int _groupHandle, std::vector<std::string> &valV, std::vector<int> &statusV)
{
#define __METHOD__ "groupGetScalar( _groupHandle, vector<string> &valV, vector<int> &statusV)"
PVGroup pvgroup;
CAFE::groupAttach(_groupHandle, pvgroup);
pvgroup.setHasAlarm(false);
pvgroup.setHasTS(false);
CAFE::set(CAFE::getHandlesFromWithinGroupV(_groupHandle)[9],8.88);
status=CAFE::groupGet(_groupHandle, pvgroup);
valV.reserve(pvgroup.npv);
statusV.reserve(pvgroup.npv);
for (unsigned int iMember = 0; iMember < pvgroup.npv; ++iMember)
{
cout << pvgroup.pvdata[iMember].getAsString(0)
<< " ts " << pvgroup.pvdata[iMember].ts.secPastEpoch << " " << pvgroup.pvdata[iMember].ts.nsec
<< " STATUS " << pvgroup.pvdata[iMember].status
<< " iMember" << iMember << endl;
valV.push_back(pvgroup.pvdata[iMember].getAsString(0));
statusV.push_back(pvgroup.pvdata[iMember].status);
}
if (pvgroup.statusGroup==ECA_TIMEOUT)
{
cout << "WARNING: " << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
cafeStatus.report(ECA_TIMEOUT);
cout << "SG TIMEOUT OCCURRED. REVERTING TO ASYNCHRNOUS GET" << endl;
return CAFE::getScalars(CAFE::getHandlesFromWithinGroupV(_groupHandle), valV, statusV);
}
else
{
return pvgroup.statusGroup;
}
#undef __METHOD__
}
/**
*
* \brief Retrieves scalar value from the PVGroup object indentified by the group handle \n
* \param _groupHandle input: handle to the group object
* \param valV output: vector of double values
* \param statusV output: vector of int values reporting the status
* \return statusGroup
*/
int CAFE::groupGetScalar(const unsigned int _groupHandle, std::vector<double> &valV, std::vector<int> &statusV)
{
#define __METHOD__ "groupGetScalar( _groupHandle, vector<double> &valV, vector<int> &statusV)"
PVGroup pvgroup;
CAFE::groupAttach(_groupHandle, pvgroup);
pvgroup.setHasAlarm(false);
pvgroup.setHasTS(false);
CAFE::groupGet(_groupHandle, pvgroup);
valV.reserve(pvgroup.npv);
statusV.reserve(pvgroup.npv);
for (unsigned int iMember = 0; iMember < pvgroup.npv; ++iMember)
{
valV.push_back(pvgroup.pvdata[iMember].getAsDouble(0));
statusV.push_back(pvgroup.pvdata[iMember].status);
}
return pvgroup.statusGroup;
#undef __METHOD__
}
/**
*
* \brief Retrieves scalar value from the PVGroup object indentified by the group handle \n
* \param _groupHandle input: handle to the group object
* \param valV output: vector of float values
* \param statusV output: vector of int values reporting the status
* \return statusGroup
*/
int CAFE::groupGetScalar(const unsigned int _groupHandle, std::vector<float> &valV, std::vector<int> &statusV)
{
#define __METHOD__ "groupGetScalar( _groupHandle, vector<float> &valV, vector<int> &statusV)"
PVGroup pvgroup;
CAFE::groupAttach(_groupHandle, pvgroup);
pvgroup.setHasAlarm(false);
pvgroup.setHasTS(false);
CAFE::groupGet(_groupHandle, pvgroup);
valV.reserve(pvgroup.npv);
statusV.reserve(pvgroup.npv);
for (unsigned int iMember = 0; iMember < pvgroup.npv; ++iMember)
{
valV.push_back(pvgroup.pvdata[iMember].getAsFloat(0));
statusV.push_back(pvgroup.pvdata[iMember].status);
}
return pvgroup.statusGroup;
#undef __METHOD__
}
/**
*
* \brief Retrieves scalar value from the PVGroup object indentified by the group handle \n
* \param _groupHandle input: handle to the group object
* \param valV output: vector of short values
* \param statusV output: vector of int values reporting the status
* \return statusGroup
*/
int CAFE::groupGetScalar(const unsigned int _groupHandle, std::vector<short> &valV, std::vector<int> &statusV)
{
#define __METHOD__ "groupGetScalar( _groupHandle, vector<short> &valV, vector<int> &statusV)"
PVGroup pvgroup;
CAFE::groupAttach(_groupHandle, pvgroup);
pvgroup.setHasAlarm(false);
pvgroup.setHasTS(false);
CAFE::groupGet(_groupHandle, pvgroup);
valV.reserve(pvgroup.npv);
statusV.reserve(pvgroup.npv);
for (unsigned int iMember = 0; iMember < pvgroup.npv; ++iMember)
{
valV.push_back(pvgroup.pvdata[iMember].getAsShort(0));
statusV.push_back(pvgroup.pvdata[iMember].status);
}
return pvgroup.statusGroup;
#undef __METHOD__
}
/**
*
* \brief Retrieves scalar value from the PVGroup object indentified by the group handle \n
* \param _groupHandle input: handle to the group object
* \param valV output: vector of long values
* \param statusV output: vector of int values reporting the status
* \return statusGroup
*/
int CAFE::groupGetScalar(const unsigned int _groupHandle, std::vector<long> &valV, std::vector<int> &statusV)
{
#define __METHOD__ "groupGetScalar( _groupHandle, vector<long> &valV, vector<int> &statusV)"
PVGroup pvgroup;
CAFE::groupAttach(_groupHandle, pvgroup);
pvgroup.setHasAlarm(false);
pvgroup.setHasTS(false);
CAFE::groupGet(_groupHandle, pvgroup);
valV.reserve(pvgroup.npv);
statusV.reserve(pvgroup.npv);
for (unsigned int iMember = 0; iMember < pvgroup.npv; ++iMember)
{
valV.push_back(pvgroup.pvdata[iMember].getAsLong(0));
statusV.push_back(pvgroup.pvdata[iMember].status);
}
return pvgroup.statusGroup;
#undef __METHOD__
}
/**
*
* \brief Retrieves scalar value from the PVGroup object indentified by the group handle \n
* \param _groupHandle input: handle to the group object
* \param valV output: vector of long long values
* \param statusV output: vector of int values reporting the status
* \return statusGroup
*/
int CAFE::groupGetScalar(const unsigned int _groupHandle, std::vector<long long> &valV, std::vector<int> &statusV)
{
#define __METHOD__ "groupGetScalar( _groupHandle, vector<long long> &valV, vector<int> &statusV)"
PVGroup pvgroup;
CAFE::groupAttach(_groupHandle, pvgroup);
pvgroup.setHasAlarm(false);
pvgroup.setHasTS(false);
CAFE::groupGet(_groupHandle, pvgroup);
valV.reserve(pvgroup.npv);
statusV.reserve(pvgroup.npv);
for (unsigned int iMember = 0; iMember < pvgroup.npv; ++iMember)
{
valV.push_back(pvgroup.pvdata[iMember].getAsLongLong(0));
statusV.push_back(pvgroup.pvdata[iMember].status);
}
return pvgroup.statusGroup;
#undef __METHOD__
}
/**
*
* \brief Retrieves scalar value from the PVGroup object indentified by the group handle \n
* \param _groupHandle input: handle to the group object
* \param valV output: vector of unsigned short values
* \param statusV output: vector of int values reporting the status
* \return statusGroup
*/
int CAFE::groupGetScalar(const unsigned int _groupHandle, std::vector<unsigned short> &valV, std::vector<int> &statusV)
{
#define __METHOD__ "groupGetScalar( _groupHandle, vector<unsigned short> &valV, vector<int> &statusV)"
PVGroup pvgroup;
CAFE::groupAttach(_groupHandle, pvgroup);
pvgroup.setHasAlarm(false);
pvgroup.setHasTS(false);
CAFE::groupGet(_groupHandle, pvgroup);
valV.reserve(pvgroup.npv);
statusV.reserve(pvgroup.npv);
for (unsigned int iMember = 0; iMember < pvgroup.npv; ++iMember)
{
valV.push_back(pvgroup.pvdata[iMember].getAsUShort(0));
statusV.push_back(pvgroup.pvdata[iMember].status);
}
return pvgroup.statusGroup;
#undef __METHOD__
}
/**
*
* \brief Retrieves scalar value from the PVGroup object indentified by the group handle \n
* \param _groupHandle input: handle to the group object
* \param valV output: vector of unsigned char values
* \param statusV output: vector of int values reporting the status
* \return statusGroup
*/
int CAFE::groupGetScalar(const unsigned int _groupHandle, std::vector<unsigned char> &valV, std::vector<int> &statusV)
{
#define __METHOD__ "groupGetScalar( _groupHandle, vector<unsigned char> &valV, vector<int> &statusV)"
PVGroup pvgroup;
CAFE::groupAttach(_groupHandle, pvgroup);
pvgroup.setHasAlarm(false);
pvgroup.setHasTS(false);
CAFE::groupGet(_groupHandle, pvgroup);
valV.reserve(pvgroup.npv);
statusV.reserve(pvgroup.npv);
for (unsigned int iMember = 0; iMember < pvgroup.npv; ++iMember)
{
valV.push_back(pvgroup.pvdata[iMember].getAsUChar(0));
statusV.push_back(pvgroup.pvdata[iMember].status);
}
return pvgroup.statusGroup;
#undef __METHOD__
}
/**
*
* \brief Retrieves scalar value from the PVGroup object indentified by the group handle \n
* \param _groupHandle input: handle to the group object
* \param valV output: vector of char values
* \param statusV output: vector of int values reporting the status
* \return statusGroup
*/
int CAFE::groupGetScalar(const unsigned int _groupHandle, std::vector<char> &valV, std::vector<int> &statusV)
{
#define __METHOD__ "groupGetScalar( _groupHandle, vector<char> &valV, vector<int> &statusV)"
PVGroup pvgroup;
CAFE::groupAttach(_groupHandle, pvgroup);
pvgroup.setHasAlarm(false);
pvgroup.setHasTS(false);
CAFE::groupGet(_groupHandle, pvgroup);
valV.reserve(pvgroup.npv);
statusV.reserve(pvgroup.npv);
for (unsigned int iMember = 0; iMember < pvgroup.npv; ++iMember)
{
valV.push_back(pvgroup.pvdata[iMember].getAsChar(0));
statusV.push_back(pvgroup.pvdata[iMember].status);
}
return pvgroup.statusGroup;
#undef __METHOD__
}
/**
*
* \brief Retrieves scalar value from the PVGroup object indentified by the group handle \n
* \param _groupHandle input: handle to the group object
* \param val output: array of string values
* \param statusArray output: array of int values reporting the status
* \return statusGroup
*/
int CAFE::groupGetScalar(const unsigned int _groupHandle, std::string * val, int * statusArray)
{
#define __METHOD__ "groupGetScalar( _groupHandle, string * val, int * statusArray)"
PVGroup pvgroup;
CAFE::groupAttach(_groupHandle, pvgroup);
pvgroup.setHasAlarm(false);
pvgroup.setHasTS(false);
CAFE::groupGet(_groupHandle, pvgroup);
for (unsigned int iMember = 0; iMember < pvgroup.npv; ++iMember)
{
val[iMember]=pvgroup.pvdata[iMember].getAsString(0);
statusArray[iMember]=pvgroup.pvdata[iMember].status;
}
return pvgroup.statusGroup;
#undef __METHOD__
}
/**
*
* \brief Retrieves scalar value from the PVGroup object indentified by the group handle \n
* \param _groupHandle input: handle to the group object
* \param val output: array of double values
* \param statusArray output: array of int values reporting the status
* \return statusGroup
*/
int CAFE::groupGetScalar(const unsigned int _groupHandle, double * val, int * statusArray)
{
#define __METHOD__ "groupGetScalar( _groupHandle, double * val, int * statusArray)"
PVGroup pvgroup;
CAFE::groupAttach(_groupHandle, pvgroup);
pvgroup.setHasAlarm(false);
pvgroup.setHasTS(false);
CAFE::groupGet(_groupHandle, pvgroup);
for (unsigned int iMember = 0; iMember < pvgroup.npv; ++iMember)
{
val[iMember]=pvgroup.pvdata[iMember].getAsDouble(0);
statusArray[iMember]=pvgroup.pvdata[iMember].status;
}
return pvgroup.statusGroup;
#undef __METHOD__
}
/**
*
* \brief Retrieves scalar value from the PVGroup object indentified by the group handle \n
* \param _groupHandle input: handle to the group object
* \param val output: array of float values
* \param statusArray output: array of int values reporting the status
* \return statusGroup
*/
int CAFE::groupGetScalar(const unsigned int _groupHandle, float * val, int * statusArray)
{
#define __METHOD__ "groupGetScalar( _groupHandle, float * val, int * statusArray)"
PVGroup pvgroup;
CAFE::groupAttach(_groupHandle, pvgroup);
pvgroup.setHasAlarm(false);
pvgroup.setHasTS(false);
CAFE::groupGet(_groupHandle, pvgroup);
for (unsigned int iMember = 0; iMember < pvgroup.npv; ++iMember)
{
val[iMember]=pvgroup.pvdata[iMember].getAsFloat(0);
statusArray[iMember]=pvgroup.pvdata[iMember].status;
}
return pvgroup.statusGroup;
#undef __METHOD__
}
/**
*
* \brief Retrieves scalar value from the PVGroup object indentified by the group handle \n
* \param _groupHandle input: handle to the group object
* \param val output: array of short values
* \param statusArray output: array of int values reporting the status
* \return statusGroup
*/
int CAFE::groupGetScalar(const unsigned int _groupHandle, short * val, int * statusArray)
{
#define __METHOD__ "groupGetScalar( _groupHandle, short * val, int * statusArray)"
PVGroup pvgroup;
CAFE::groupAttach(_groupHandle, pvgroup);
pvgroup.setHasAlarm(false);
pvgroup.setHasTS(false);
CAFE::groupGet(_groupHandle, pvgroup);
for (unsigned int iMember = 0; iMember < pvgroup.npv; ++iMember)
{
val[iMember]=pvgroup.pvdata[iMember].getAsShort(0);
statusArray[iMember]=pvgroup.pvdata[iMember].status;
}
return pvgroup.statusGroup;
#undef __METHOD__
}
/**
*
* \brief Retrieves scalar value from the PVGroup object indentified by the group handle \n
* \param _groupHandle input: handle to the group object
* \param val output: array of long values
* \param statusArray output: array of int values reporting the status
* \return statusGroup
*/
int CAFE::groupGetScalar(const unsigned int _groupHandle, long * val, int * statusArray)
{
#define __METHOD__ "groupGetScalar( _groupHandle, long * val, int * statusArray)"
PVGroup pvgroup;
CAFE::groupAttach(_groupHandle, pvgroup);
pvgroup.setHasAlarm(false);
pvgroup.setHasTS(false);
CAFE::groupGet(_groupHandle, pvgroup);
for (unsigned int iMember = 0; iMember < pvgroup.npv; ++iMember)
{
val[iMember]=pvgroup.pvdata[iMember].getAsLong(0);
statusArray[iMember]=pvgroup.pvdata[iMember].status;
}
return pvgroup.statusGroup;
#undef __METHOD__
}
/**
*
* \brief Retrieves scalar value from the PVGroup object indentified by the group handle \n
* \param _groupHandle input: handle to the group object
* \param val output: array of long long values
* \param statusArray output: array of int values reporting the status
* \return statusGroup
*/
int CAFE::groupGetScalar(const unsigned int _groupHandle, long long * val, int * statusArray)
{
#define __METHOD__ "groupGetScalar( _groupHandle, long long * val, int * statusArray)"
PVGroup pvgroup;
CAFE::groupAttach(_groupHandle, pvgroup);
pvgroup.setHasAlarm(false);
pvgroup.setHasTS(false);
CAFE::groupGet(_groupHandle, pvgroup);
for (unsigned int iMember = 0; iMember < pvgroup.npv; ++iMember)
{
val[iMember]=pvgroup.pvdata[iMember].getAsLongLong(0);
statusArray[iMember]=pvgroup.pvdata[iMember].status;
}
return pvgroup.statusGroup;
#undef __METHOD__
}
/**
*
* \brief Retrieves scalar value from the PVGroup object indentified by the group handle \n
* \param _groupHandle input: handle to the group object
* \param val output: array of unsigned short values
* \param statusArray output: array of int values reporting the status
* \return statusGroup
*/
int CAFE::groupGetScalar(const unsigned int _groupHandle, unsigned short * val, int * statusArray)
{
#define __METHOD__ "groupGetScalar( _groupHandle, unsigned short * val, int * statusArray)"
PVGroup pvgroup;
CAFE::groupAttach(_groupHandle, pvgroup);
pvgroup.setHasAlarm(false);
pvgroup.setHasTS(false);
CAFE::groupGet(_groupHandle, pvgroup);
for (unsigned int iMember = 0; iMember < pvgroup.npv; ++iMember)
{
val[iMember]=pvgroup.pvdata[iMember].getAsUShort(0);
statusArray[iMember]=pvgroup.pvdata[iMember].status;
}
return pvgroup.statusGroup;
#undef __METHOD__
}
/**
*
* \brief Retrieves scalar value from the PVGroup object indentified by the group handle \n
* \param _groupHandle input: handle to the group object
* \param val output: array of unsigned char values
* \param statusArray output: array of int values reporting the status
* \return statusGroup
*/
int CAFE::groupGetScalar(const unsigned int _groupHandle, unsigned char * val, int * statusArray)
{
#define __METHOD__ "groupGetScalar( _groupHandle, unsigned char * val, int * statusArray)"
PVGroup pvgroup;
CAFE::groupAttach(_groupHandle, pvgroup);
pvgroup.setHasAlarm(false);
pvgroup.setHasTS(false);
CAFE::groupGet(_groupHandle, pvgroup);
for (unsigned int iMember = 0; iMember < pvgroup.npv; ++iMember)
{
val[iMember]=pvgroup.pvdata[iMember].getAsUChar(0);
statusArray[iMember]=pvgroup.pvdata[iMember].status;
}
//Asynchronous get
//get()
//waitForBundleEvents
//getCache
return pvgroup.statusGroup;
#undef __METHOD__
}
/**
*
* \brief Retrieves scalar value from the PVGroup object indentified by the group handle \n
* \param _groupHandle input: handle to the group object
* \param val output: array of char values
* \param statusArray output: array of int values reporting the status
* \return statusGroup
*/
int CAFE::groupGetScalar(const unsigned int _groupHandle, char * val, int * statusArray)
{
#define __METHOD__ "groupGetScalar( _groupHandle, char * val, int * statusArray)"
PVGroup pvgroup;
CAFE::groupAttach(_groupHandle, pvgroup);
pvgroup.setHasAlarm(false);
pvgroup.setHasTS(false);
CAFE::groupGet(_groupHandle, pvgroup);
for (unsigned int iMember = 0; iMember < pvgroup.npv; ++iMember)
{
val[iMember]=pvgroup.pvdata[iMember].getAsChar(0);
statusArray[iMember]=pvgroup.pvdata[iMember].status;
}
return pvgroup.statusGroup;
#undef __METHOD__
}
/**
*
* \brief Fills the PVGroup object indentified by the pvgroup.groupHandle \n
* \param pvgroup input/output: data pertaining to the object
* \return statusGroup
*/
int CAFE::groupGet(PVGroup &pvgroup)
{
#define __METHOD__ "groupGet(&pvgroup)"
return CAFE::groupGet(pvgroup.groupHandle, pvgroup);
#undef __METHOD__
}
/**
* \brief Fills the PVGroup object indentified by the groupHandle \n
* \param _groupHandle input: handle to the group object
* \param pvgroup output: data pertaining to the object
* \return statusGroup
*/
int CAFE::groupGet(const unsigned int _groupHandle, PVGroup &pvgroup)
{
#define __METHOD__ "groupGet( _groupHandle, &pvgroup)"
int gStatus=ICAFE_NORMAL;
if (pvgroup.npv==0 || pvgroup.groupHandle==0)
{
gStatus=groupAttach(_groupHandle, pvgroup);
if (gStatus != ICAFE_NORMAL)
{
return gStatus;
}
};
if (pvgroup.groupHandle != _groupHandle)
{
return ECAFE_PVGROUP_GROUPHANDLE_MISMATCH;
}
cafeGroup_set_by_groupHandle & groupHandle_index = gs.get<by_groupHandle> ();
cafeGroup_set_by_groupHandle::iterator it_groupHandle;
it_groupHandle = groupHandle_index.find(_groupHandle);
if (it_groupHandle != groupHandle_index.end())
{
unsigned int nGroupMember = (*it_groupHandle).getNMember();
if (pvgroup.npv != (*it_groupHandle).getNMember())
{
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
cout << "A MISMATCH IN THE NUMBER OF GROUP MEMBERS DETECTED " << endl;
cout << "CLIENT (pvgroup.npv) CLAIMS " << pvgroup.npv
<< " CONDUITGROUP OBJECT CLAIMS " << (*it_groupHandle).getNMember() << endl;
nGroupMember = min(pvgroup.npv,(*it_groupHandle).getNMember());
cout << "TAKING SMALLER OF THE TWO NUMBERS " << endl;
}
cafeConduit_set_by_handle & handle_index = cs.get<by_handle> ();
cafeConduit_set_by_handle::iterator it_handle;
for (unsigned int iMember = 0; iMember < nGroupMember; ++iMember)
{
bool hf=false;
//reset
pvgroup.pvdata[iMember].alarmStatus=-1;
pvgroup.pvdata[iMember].alarmSeverity=-1;
pvgroup.pvdata[iMember].ts.secPastEpoch=0;
pvgroup.pvdata[iMember].ts.nsec=0;
pvgroup.pvdata[iMember].status=ICAFE_NORMAL;
it_handle = handle_index.find((*it_groupHandle).mHandle[iMember]);
if (it_handle != handle_index.end())
{
hf=true;
if (pvgroup.pvdata[iMember].getRule() != (*it_groupHandle).getRule(iMember))
{
if(MUTEX)
{
cafeMutex.lock();
}
groupHandle_index.modify(it_groupHandle,
change_sg_rule(pvgroup.pvdata[iMember].rule, iMember));
if(MUTEX)
{
cafeMutex.unlock();
}
}
if (!pvgroup.pvdata[iMember].getRule() )
{
pvgroup.pvdata[iMember].status=ICAFE_RULE_FALSE;
}
if(MUTEX)
{
cafeMutex.lock();
}
groupHandle_index.modify(it_groupHandle,
change_sg_status(pvgroup.pvdata[iMember].status, iMember));
if(MUTEX)
{
cafeMutex.unlock();
}
}
if (!hf)
{
pvgroup.pvdata[iMember].status=ECAFE_INVALID_HANDLE;
if(MUTEX)
{
cafeMutex.lock();
}
groupHandle_index.modify(it_groupHandle,
change_sg_status(pvgroup.pvdata[iMember].status, iMember));
if(MUTEX)
{
cafeMutex.unlock();
}
cout << "WARNING: " << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
cafeStatus.report(ECAFE_INVALID_HANDLE);
cout << "Invalid handle = " << (*it_groupHandle).mHandle[iMember]
<< " for groupMember [" << iMember << "] " << endl;
continue;
}
unsigned int handle=(*it_groupHandle).mHandle[iMember];
//May happen that channel has just connected and native datatype not yet entered
CAFE_DATATYPE cdt = pvgroup.pvdata[iMember].dataType;
//Check groupDataType
if (pvgroup.pvdata[iMember].dataType<CAFE_STRING ||
pvgroup.pvdata[iMember].dataType>CAFE_DOUBLE)
{
cdt=CAFE_STRING;
}
//Let us take a look at hasAlarm and hasTS flags to determine if these are retrieved from SC
chtype _chtype= cdt;
if (!pvgroup.pvdata[iMember].hasAlarm && !pvgroup.pvdata[iMember].hasTS)
{
handleHelper.setCafeDbrType(handle, CAFENUM::DBR_PRIMITIVE);
}
else if (pvgroup.pvdata[iMember].hasAlarm && !pvgroup.pvdata[iMember].hasTS)
{
_chtype=dbf_type_to_DBR_STS (cdt);
handleHelper.setCafeDbrType(handle, CAFENUM::DBR_STS) ;
}
else if (pvgroup.pvdata[iMember].hasTS)
{
_chtype=dbf_type_to_DBR_TIME (cdt);
handleHelper.setCafeDbrType(handle, CAFENUM::DBR_TIME) ;
}
//Always Return to Native DataType for now
if ( (pvgroup.pvdata[iMember].status=cafeGranules.channelVerifyGet(handle,
_chtype)) != ICAFE_NORMAL)
{
//dbf_type_to_DBR_TIME (cdt))) != ICAFE_NORMAL) {
if(MUTEX)
{
cafeMutex.lock();
}
groupHandle_index.modify(it_groupHandle,
change_sg_status(pvgroup.pvdata[iMember].status, iMember));
if(MUTEX)
{
cafeMutex.unlock();
}
//May not be connected - wish to report this here
cout << "WARNING: " << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
cout << "CHANNEL: " << pvgroup.pvdata[iMember].pv << endl;
cafeStatus.report(pvgroup.pvdata[iMember].status);
continue;
}
// Examine the No of elements and set accordingly....
if ( handleHelper.getNelemClient(handle) != pvgroup.pvdata[iMember].getNelem())
{
cout << "INFO: " << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
cout << "Changing handleHelper.getNelemClient(handle) to that given in pvgroup.pvdata[iMember].nelem" << endl;
cout << "i.e., From: " << handleHelper.getNelemClient(handle) << " To: " << pvgroup.pvdata[iMember].nelem << endl;
handleHelper.setNelem(handle, pvgroup.pvdata[iMember].getNelem()); //Change made back 12 September 2019
/*
//Change made 17 March 2017
cout << "INFO: " << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
cout << "Changing pvgroup.pvdata[iMember].nelem to that given in handleHelper.getNelemClient(handle)" << endl;
cout << "i.e., From: " << pvgroup.pvdata[iMember].nelem << " To: " << handleHelper.getNelemClient(handle) << endl;
pvgroup.pvdata[iMember].nelem=handleHelper.getNelemClient(handle);
*/
}
if ( (pvgroup.pvdata[iMember].status=cafeGranules.channelPrepareGet(handle))
!= ICAFE_NORMAL)
{
if(MUTEX)
{
cafeMutex.lock();
}
groupHandle_index.modify(it_groupHandle,
change_sg_status(pvgroup.pvdata[iMember].status, iMember));
if(MUTEX)
{
cafeMutex.unlock();
}
cout << "WARNING: " << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
cafeStatus.report(pvgroup.pvdata[iMember].status);
continue;
}
} //for
gStatus=(*it_groupHandle).get();
channelTimeoutPolicySGGet = (*it_groupHandle).getChannelTimeoutPolicySGGet();
//this returns normal even if a channel is not connected
if (gStatus!=ECA_NORMAL && channelTimeoutPolicySGGet.getSelfGoverningTimeout())
{
cout << "WARNING: " << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
cafeStatus.report(gStatus);
if (gStatus == ECA_TIMEOUT)
{
cout << "ENABLING AUTO- CORRECTIVE PROCEDURE: " << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
}
}
unsigned short ntries=0;
double originalTimeOut=channelTimeoutPolicySGGet.getTimeout();
//Withdraw this test for now; not required
//if (ca_sg_test((*it_groupHandle).getGroupID()) == ECA_IOINPROGRESS ) {
// cout << "WARNING: " << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
// cafeStatus.report(ECA_IOINPROGRESS);
//}
//Withdraw this test for now; not required
//while ( (ca_sg_test((*it_groupHandle).getGroupID()) == ECA_IOINPROGRESS
// || gStatus == ECA_TIMEOUT) && channelTimeoutPolicySGGet.getSelfGoverningTimeout()
// && ntries<channelTimeoutPolicySGGet.getNtries()
// ) {
while ( (gStatus == ECA_TIMEOUT) && channelTimeoutPolicySGGet.getSelfGoverningTimeout()
&& ntries<channelTimeoutPolicySGGet.getNtries()
)
{
++ntries;
//Withdraw this test for now; not required
//if (ca_sg_test((*it_groupHandle).getGroupID()) == ECA_IOINPROGRESS ) {
// cout << "WARNING: " << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
// cafeStatus.report(ECA_IOINPROGRESS);
//}
//if (gStatus == ECA_TIMEOUT) {
// cout << "WARNING: " << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
// cafeStatus.report(ECA_TIMEOUT);
//}
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
cout << "Changing SG GET timeout from: " << channelTimeoutPolicySGGet.getTimeout()
<< " to: " << (originalTimeOut + channelTimeoutPolicySGGet.getDeltaTimeout()*ntries)
<< " seconds" << endl;
channelTimeoutPolicySGGet.setTimeout( (originalTimeOut +
channelTimeoutPolicySGGet.getDeltaTimeout()*ntries));
if(MUTEX)
{
cafeMutex.lock(); //lock
}
groupHandle_index.modify(it_groupHandle,
change_channelTimeoutPolicySGGet(channelTimeoutPolicySGGet));
if(MUTEX)
{
cafeMutex.unlock(); //unlock
}
if (gStatus == ECA_TIMEOUT)
{
gStatus=(*it_groupHandle).get();
}
} //while
if (ntries>0)
{
//if (ntries >= channelTimeoutPolicySGGet.getNtries() ) {
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
std::cout << "No of(additional) tries=" << ntries << std::endl;
if (gStatus==ECAFE_TIMEOUT)
{
std::cout << "is the MAXIMUM allowed as configured through SGTimeoutPolicy! " << std::endl;
std::cout << "SETTING SELF-GOVERNING TIMEOUT FOR SG GET OPERATIONS FOR THIS CHANNEL TO FALSE" << std::endl;
std::cout << "RESTORING TIMEOUT TO ORIGINAL SG GET VALUE OF: " << originalTimeOut << " SECONDS " << std::endl;
channelTimeoutPolicySGGet.setSelfGoverningTimeout(false);
channelTimeoutPolicySGGet.setTimeout( originalTimeOut );
if(MUTEX)
{
cafeMutex.lock(); //lock
}
groupHandle_index.modify(it_groupHandle,
change_channelTimeoutPolicySGGet(channelTimeoutPolicySGGet));
if(MUTEX)
{
cafeMutex.unlock(); //unlock
}
}
else
{
cout << "Changed SG GET from intitial " << originalTimeOut << " to: " <<
(originalTimeOut +
channelTimeoutPolicySGGet.getDeltaTimeout()*ntries)
<< " seconds" << endl;
}
} //if
//Withdraw this test for now; not required
//if (ca_sg_test((*it_groupHandle).getGroupID()) == ECA_IOINPROGRESS) {
// ca_sg_reset((*it_groupHandle).getGroupID());
// cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
// std::cout << " No. of ca_sg_test(gid) INSTIGATED: " << ntries+1 << std::endl;
// std::cout
// << " ca_sg_reset(gid) HAS BEEN FORCED SO THAT ca_sg_test() returns ECA_IODONE"
// <<std::endl;
// std::cout << " ***PLEASE** REPORT THIS OCCURRENCE TO jan.chrin@psi.ch THANKS!! "
// <<std::endl;
//}
int * mstatus =(*it_groupHandle).getStatus();
bool groupStatusFlag = false;
pvgroup.statusGroup= gStatus; //ICAFE_NORMAL;
if ( pvgroup.statusGroup==ECA_TIMEOUT)
{
groupStatusFlag = true;
}
for (unsigned int iMember = 0; iMember< (*it_groupHandle).getNMember(); ++iMember)
{
if (pvgroup.pvdata[iMember].status == ECAFE_INVALID_HANDLE)
{
continue;
}
it_handle = handle_index.find((*it_groupHandle).mHandle[iMember]);
if (it_handle != handle_index.end())
{
//do nothing as handle exists
}
else
{
//Should not get this far if invalid handle
cout << "WARNING: " << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
cafeStatus.report(ECAFE_INVALID_HANDLE);
cout << "Invalid handle = " << (*it_groupHandle).mHandle[iMember]
<< " for groupMember [" << iMember << "] " << endl;
continue;
}
if(MUTEX)
{
cafeMutex.lock();
}
handle_index.modify(it_handle, change_status(mstatus[iMember]));
if(MUTEX)
{
cafeMutex.unlock();
}
if (mstatus[iMember]!=ICAFE_NORMAL)
{
pvgroup.pvdata[iMember].status = mstatus[iMember];
if (pvgroup.pvdata[iMember].status != ICAFE_NORMAL
&& pvgroup.pvdata[iMember].status != ICAFE_RULE_FALSE
&& !groupStatusFlag)
{
pvgroup.statusGroup = pvgroup.pvdata[iMember].status;
groupStatusFlag = true;
}
continue;
}
//cout << __METHOD__ << " / " << iMember << " " << nGroupMember << endl;
(*it_handle).getPVDataHolder(pvgroup.pvdata[iMember]);
//cout << __METHOD__ << " / " << mstatus[iMember] << endl;
//check back alarms and timestamps into conduit
//handleHelper.setSTS((*it_groupHandle).mHandle[iMember],pvgroup.pvdata[iMember].alarmStatus, \
//pvgroup.pvdata[iMember].alarmSeverity, pvgroup.pvdata[iMember].ts);
if(MUTEX)
{
cafeMutex.lock();
}
handle_index.modify(it_handle, change_alarmStatus(pvgroup.pvdata[iMember].alarmStatus));
handle_index.modify(it_handle, change_alarmSeverity(pvgroup.pvdata[iMember].alarmSeverity));
handle_index.modify(it_handle, change_epicsTimeStamp(pvgroup.pvdata[iMember].ts));
if(MUTEX)
{
cafeMutex.unlock();
}
} // for iMember
return pvgroup.statusGroup;
}
else
{
return ECAFE_INVALID_GROUP_HANDLE;
}
#undef __METHOD__
}
/**
* \brief Starts a monitor on all PVs within the PVGroup object indentified by the groupHandle \n
* \param groupHandle input: handle to the group object
* \param statusV output: status of individual monitors
* \param mpV output: vector of MonitorPolicy
* \return ECAFE_NORMAL if all OK else first error encountered
*/
int CAFE::groupMonitorStart(const unsigned int groupHandle, std::vector<int> &statusV,
std::vector<MonitorPolicy> &mpV)
{
#define __METHOD__ "groupMonitorStart(groupHandle, &statusV, &mpV)"
// open groupHandle
cafeGroup_set_by_groupHandle & groupHandle_index = gs.get<by_groupHandle> ();
cafeGroup_set_by_groupHandle::iterator it_groupHandle;
it_groupHandle = groupHandle_index.find(groupHandle);
if (it_groupHandle != groupHandle_index.end())
{
unsigned int nGroupMember = (*it_groupHandle).getNMember();
vector<unsigned int> handleV;
handleV.reserve(nGroupMember);
cafeConduit_set_by_handle & handle_index = cs.get<by_handle> ();
cafeConduit_set_by_handle::iterator it_handle;
// fill vector of member handles
for (unsigned int iMember = 0; iMember < nGroupMember; ++iMember)
{
it_handle = handle_index.find((*it_groupHandle).mHandle[iMember]);
if (it_handle != handle_index.end())
{
handleV.push_back((*it_groupHandle).mHandle[iMember]);
}
else
{
cout << "WARNING: " << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
cafeStatus.report(ECAFE_INVALID_HANDLE);
cout << "Invalid handle = " << (*it_groupHandle).mHandle[iMember]
<< " for groupMember [" << iMember << "] " << endl;
continue;
}
}
// issue monitorStart command
return monitorStart(handleV, statusV, mpV);
}
else
{
return ECAFE_INVALID_GROUP_HANDLE;
}
#undef __METHOD__
}
/**
* \brief Starts a monitor on all PVs within the PVGroup object indentified by the groupHandle \n
* \param groupHandle input: handle to the group object
* \param statusV output: status of individual monitors
* \param monitorIDV output: vector of monitor ID (unsigned int)
* \return ECAFE_NORMAL if all OK else first error encountered
*/
int CAFE::groupMonitorStart(const unsigned int groupHandle, std::vector<int> &statusV,
std::vector<unsigned int> &monitorIDV)
{
#define __METHOD__ "groupMonitorStart(groupHandle, &statusV, &monitorIDV)"
// open groupHandle
cafeGroup_set_by_groupHandle & groupHandle_index = gs.get<by_groupHandle> ();
cafeGroup_set_by_groupHandle::iterator it_groupHandle;
it_groupHandle = groupHandle_index.find(groupHandle);
if (it_groupHandle != groupHandle_index.end())
{
unsigned int nGroupMember = (*it_groupHandle).getNMember();
vector<unsigned int> handleV;
handleV.reserve(nGroupMember);
cafeConduit_set_by_handle & handle_index = cs.get<by_handle> ();
cafeConduit_set_by_handle::iterator it_handle;
// fill vector of member handles
for (unsigned int iMember = 0; iMember < nGroupMember; ++iMember)
{
it_handle = handle_index.find((*it_groupHandle).mHandle[iMember]);
if (it_handle != handle_index.end())
{
handleV.push_back((*it_groupHandle).mHandle[iMember]);
}
else
{
cout << "WARNING: " << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
cafeStatus.report(ECAFE_INVALID_HANDLE);
cout << "Invalid handle = " << (*it_groupHandle).mHandle[iMember]
<< " for groupMember [" << iMember << "] " << endl;
continue;
}
}
// issue monitorStart command
return monitorStart(handleV, statusV, monitorIDV);
}
else
{
return ECAFE_INVALID_GROUP_HANDLE;
}
#undef __METHOD__
}
/**
* \brief Stops a monitor on all PVs within the PVGroup object indentified by the groupHandle \n
* \param groupHandle input: handle to the group object
* \param statusV output: status of individual monitor stop operations
* \return ECAFE_NORMAL if all OK else first error encountered
*/
int CAFE::groupMonitorStop (const unsigned int groupHandle, std::vector<int> &statusV)
{
#define __METHOD__ "groupMonitorStop(groupHandle, &statusV)"
// open groupHandle
cafeGroup_set_by_groupHandle & groupHandle_index = gs.get<by_groupHandle> ();
cafeGroup_set_by_groupHandle::iterator it_groupHandle;
it_groupHandle = groupHandle_index.find(groupHandle);
if (it_groupHandle != groupHandle_index.end())
{
unsigned int nGroupMember = (*it_groupHandle).getNMember();
vector<unsigned int> handleV;
handleV.reserve(nGroupMember);
cafeConduit_set_by_handle & handle_index = cs.get<by_handle> ();
cafeConduit_set_by_handle::iterator it_handle;
// fill vector of member handles
for (unsigned int iMember = 0; iMember < nGroupMember; ++iMember)
{
it_handle = handle_index.find((*it_groupHandle).mHandle[iMember]);
if (it_handle != handle_index.end())
{
handleV.push_back((*it_groupHandle).mHandle[iMember]);
}
else
{
cout << "WARNING: " << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
cafeStatus.report(ECAFE_INVALID_HANDLE);
cout << "Invalid handle = " << (*it_groupHandle).mHandle[iMember]
<< " for groupMember [" << iMember << "] " << endl;
continue;
}
}
// issue monitorStart command
return monitorStop(handleV, statusV);
}
else
{
return ECAFE_INVALID_GROUP_HANDLE;
}
#undef __METHOD__
}