1848 lines
63 KiB
C++
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__
|
|
}
|