/// /// \file connect.h /// \author Jan Chrin, PSI /// \date Release February: 2015 /// \version CAFE 1.0.0 /// #ifndef CONNECT_H #define CONNECT_H // generated by autotools #include #include #include #include #include #include #include #include #include #include #include #include #if HAVE_BOOST_THREAD #include #include #endif class Connect { protected: int status; CAFEStatus cafeStatus; CAFEStatusSeverity cafeStatusSeverity; CAFEGlobalAlarmSeverity epicsAlarmSeverity; CAFEGlobalAlarmCondition epicsAlarmStatus; cafeConduit_set::iterator itcs; cafeGroup_set::iterator itgs; CAFEDataTypeCode cafeDataTypeCode; ExceptionsHelper exceptionsHelper; ChannelCreatePolicy channelCreatePolicy; PolicyHelper policyHelper; HandleHelper handleHelper; Helper helper; std::string deviceAttributeDeliminator; bool pyCafeFlag; //connectCallbacks.cc static void callbackHandlerAccessRights(struct access_rights_handler_args args); static void callbackHandlerException (struct exception_handler_args args); //connect.cpp int createChannel(unsigned int handle, const char * pv, chid &pCh); int createHandle(const char * pv, ca_client_context * ccc, unsigned int &handle) //int createHandle(const char * pv, ca_client_context * ccc, ChannelRequestPolicy channelRequestPolicyPut, unsigned int &handle) throw (CAFEException_pv); int contextDestroy(); int contextDestroy(ca_client_context * cctLocal); unsigned short epicsVersion(unsigned short & major, unsigned short & minor, unsigned short & patch); //group functions int createChannelWithinGroup(unsigned int handle, const char * pv, chid &pCh); int createHandleWithinGroup(const char * pv, ca_client_context * ccc, unsigned int & _handle) throw (CAFEException_pv); public: Connect(){ channelMonitorPolicy.setPolicy( (ChannelWhenToFlushSendBufferPolicyKind) CAFENUM::FLUSH_AFTER_EACH_CHANNEL_SUBSCRIPTION, CAFENUM::WITH_FLUSH_IO, DEFAULT_TIMEOUT_PEND_IO); channelOpenGroupPolicy.setPolicy( CAFENUM::FLUSH_AFTER_EACH_GROUP_CREATION, CAFENUM::WITH_PEND_EVENT, DEFAULT_TIMEOUT_SG_PEND_EVENT); channelOpenPolicy.setPolicy( CAFENUM::FLUSH_AFTER_EACH_CHANNEL_CREATION, CAFENUM::WITH_PEND_EVENT, DEFAULT_TIMEOUT_PEND_EVENT); deviceAttributeDeliminator=DEFAULT_DEVICE_ATTRIBUTE_DELIMINATOR; #if HAVE_PYTHON_H pyCafeFlag=true; #else pyCafeFlag=false; #endif }; //these need to be public PrintErrorPolicy printErrorPolicy; ChannelOpenPolicy channelOpenPolicy; ChannelOpenPolicy channelClosePolicy; //can also use for close ChannelOpenPolicy channelMonitorPolicy; ChannelOpenPolicy channelOpenGroupPolicy; //28 May 2017 ChannelRequestPolicy channelRequestPolicyMasterPut; ChannelRequestPolicy channelRequestPolicyMasterGet; ChannelRequestPolicy channelRequestPolicyMasterGetCtrl; ChannelGetActionWhenMonitorPolicy channelGetActionWhenMonitorPolicyMaster; //ChannelOpenPolicy getChannelOpenPolicy(){return channelOpenPolicy;} //ChannelOpenPolicy getChannelClosePolicy(){return channelClosePolicy;} //ChannelOpenPolicy getChannelMonitorPolicy(){return channelMonitorPolicy;} //ChannelOpenPolicy getChannelOpenGroupPolicy(){return channelOpenGroupPolicy;} HandleHelper getHandleHelper() {return handleHelper;} HandleHelper getInfo() {return handleHelper;} PolicyHelper getPolicyHelper() {return policyHelper;} PolicyHelper getPolicy() {return policyHelper;} unsigned int getNelemClient(unsigned int h){ return handleHelper.getNelemClient(h);} unsigned int getNelemNative(unsigned int h){ return handleHelper.getNelemNative(h);} unsigned int getNelemRequest(unsigned int h){ return handleHelper.getNelemRequest(h);} int getStatus() {return status;} CAFEStatus getCafeStatus() {return cafeStatus;} CAFEStatusSeverity getCafeStatusSeverity() {return cafeStatusSeverity;} CAFEGlobalAlarmCondition getEpicsAlarmStatus() {return epicsAlarmStatus;} CAFEGlobalAlarmCondition getEpicsAlarmCondition() {return epicsAlarmStatus;} CAFEGlobalAlarmSeverity getEpicsAlarmSeverity() {return epicsAlarmSeverity;} int flushNow() {return ca_flush_io();} int _ca_flush_io(){return ca_flush_io();} int _ca_poll(){return ca_poll();} int _ca_pend_io(double t){return ca_pend_io(t);} int _ca_pend_event(double t){return ca_pend_event(t);} //connect.cc bool setPyCafe(bool b){return pyCafeFlag=b;}; bool getPyCafe(){return pyCafeFlag;} ; int init() throw (CAFEException_init); int init(ca_preemptive_callback_select select) throw (CAFEException_init); //std::string int open(const string pvS, unsigned int &handle) throw (CAFEException_open){ try { open (pvS.c_str(), handle);} catch(CAFEException_open &e) {throw e;}; } int open(const string pvS, const std::string pvAliasS, unsigned int &handle) throw (CAFEException_open){ try { open (pvS.c_str(), pvAliasS.c_str(), handle);} catch(CAFEException_open &e) {throw e;}; } int open(const string *pvArrayS, unsigned int *handleArray, const unsigned int nHandles) throw (CAFEException_open); //const char *pv int open(const char *pv, unsigned int &handle) throw (CAFEException_open); int open(const char *pv, const char *pvAlias, unsigned int &handle) throw (CAFEException_open); int open(const char **pvArray, unsigned int *handleArray, const unsigned int nHandles) throw (CAFEException_open); int open(vector, vector &) throw (CAFEException_open); int open(vector, vector &) throw (CAFEException_open); int openV(vector s, vector &i) throw (CAFEException_open) {return open(s,i); }; //################################################################################ void openGroupPrepare(){ channelOpenGroupPolicy.setFlushSendBufferKind(WITH_PEND_EVENT); channelOpenGroupPolicy.setWhenToFlushSendBuffer(FLUSH_DESIGNATED_TO_CLIENT); return; } void openMonitorPrepare(){ channelMonitorPolicy.setFlushSendBufferKind(WITH_FLUSH_IO); channelMonitorPolicy.setWhenToFlushSendBuffer(FLUSH_DESIGNATED_TO_CLIENT); return; } double setOpenDefaultPendTime(double _timeout){ return channelOpenPolicy.setDefaultTimeout(_timeout); } double getOpenDefaultPendTime(){ return channelOpenPolicy.getDefaultTimeout(); } void openGroupNowAndWait(double _timeout){ double dto = channelOpenGroupPolicy.getTimeout(); channelOpenGroupPolicy.setTimeout(_timeout); channelOpenGroupPolicy.flushSendBufferNow(); // //reset channelOpenGroupPolicy.setWhenToFlushSendBuffer(FLUSH_NOW); channelOpenGroupPolicy.setFlushSendBufferKind(WITH_PEND_EVENT); //channelOpenGroupPolicy.setTimeoutToDefault(); channelOpenGroupPolicy.setTimeout(dto); return; } void openMonitorNow(){ channelMonitorPolicy.flushSendBufferNow(); //reset channelMonitorPolicy.setWhenToFlushSendBuffer(FLUSH_NOW); channelMonitorPolicy.setFlushSendBufferKind(WITH_FLUSH_IO); return; } void openMonitorNowAndWait(double _timeout){ channelMonitorPolicy.setTimeout(_timeout); channelMonitorPolicy.flushSendBufferNow(); //reset channelMonitorPolicy.setWhenToFlushSendBuffer(FLUSH_NOW); channelMonitorPolicy.setFlushSendBufferKind(WITH_FLUSH_IO); return; } void openPrepare() { channelOpenPolicy.setFlushSendBufferKind(WITH_PEND_EVENT); channelOpenPolicy.setWhenToFlushSendBuffer(FLUSH_DESIGNATED_TO_CLIENT); return; } void openNowAndWait(double _timeout) { double dto = channelOpenPolicy.getTimeout(); channelOpenPolicy.setTimeout(_timeout); channelOpenPolicy.flushSendBufferNow(); //reset channelOpenPolicy.setWhenToFlushSendBuffer(FLUSH_NOW); channelOpenPolicy.setFlushSendBufferKind(WITH_PEND_EVENT); //channelOpenPolicy.setTimeoutToDefault(); channelOpenPolicy.setTimeout(dto); return; } void openNow() { channelOpenPolicy.flushSendBufferNow(); channelOpenPolicy.setWhenToFlushSendBuffer(FLUSH_NOW); channelOpenPolicy.setFlushSendBufferKind(WITH_PEND_EVENT); return; } void openNoWait(){ channelOpenPolicy.setFlushSendBufferKind(WITH_PEND_EVENT); channelOpenPolicy.setWhenToFlushSendBuffer(FLUSH_DESIGNATED_TO_CLIENT); return; } bool initCallbackComplete(vector hV) { return initCallbackComplete(&hV[0], hV.size()); } bool initCallbackComplete(unsigned int * hArray, unsigned int nelem); //################################################################################# unsigned int printHandle(unsigned int h){return handleHelper.printHandle(h);}; unsigned int printHandles(void){return handleHelper.printHandles();}; unsigned int printDisconnectedHandles(void){return handleHelper.printDisconnectedHandles();}; unsigned int getDisconnectedHandles(vector &dhV, vector &pvV) {return handleHelper.getDisconnectedHandles(dhV, pvV);}; void printCAFEException_pv(CAFEException_pv & e){exceptionsHelper.printCAFEException_pv(e);}; //closeChannel(s) only close within a context int closeChannels(unsigned int * handleArray, unsigned int nHandles); int closeChannels(vector v){ //unsigned int * handleArray = new unsigned int[v.size()]; //int status= closeChannels(handleArray, v.size()); //delete [] handleArray; //return status; return closeChannels(&v[0], v.size()); }; int closeChannelsV(vector v){ //unsigned int * handleArray = new unsigned int[v.size()]; //int status= closeChannels(handleArray, v.size()); //delete [] handleArray; //return status; return closeChannels(&v[0], v.size()); }; int close(unsigned int handle); int closeChannel(unsigned int handle){return close(handle);}; int closeChannels(); int closeChannels(ca_client_context * cctLocal); int close(){return closeChannels();}; //closeHandle(s) close regardless of context int closeHandlesV(vector v){ return closeHandles(&v[0], v.size());} int closeHandles (vector v){ return closeHandles(&v[0], v.size());} int closeHandles(unsigned int * handleArray, unsigned int nHandles); int closeHandle(unsigned int handle); int closeHandles(); // Monitors int monitorStart(unsigned int handle, MonitorPolicy &mp); int monitorStart(unsigned int handle, unsigned int & monitorID); int monitorStart(unsigned int handle) { unsigned int monitorID; return monitorStart(handle, monitorID); } int monitorStop (unsigned int handle, MonitorPolicy mp); int monitorStop (unsigned int handle, unsigned int monitorID); int monitorStopWithID (unsigned int handle, unsigned int monitorID){ return monitorStop(handle, monitorID);} int monitorStop (unsigned int handle); //stop all monitors for this handle int monitorStop (); int monitorStopAll (){return monitorStop();}; int monitorStop (ca_client_context * ccc); // Monitors for arrays and vectors int monitorStart(unsigned int * handleArray, unsigned int nelem) { int * statusArray = new int[nelem]; MonitorPolicy * mpV = new MonitorPolicy[nelem]; status = monitorStart (handleArray, nelem, statusArray, mpV); delete [] statusArray; delete [] mpV; return status; } int monitorStart(unsigned int * handleArray, unsigned int nelem, int *statusArray, MonitorPolicy * mpV); int monitorStart(unsigned int * handleArray, unsigned int nelem, int *statusArray, unsigned int * monitorIDArray); int monitorStart(vector handleV, vector &statusV, vector &mpV); int monitorStart(vector handleV, vector &statusV, vector &monitorIDV); int monitorStop (unsigned int * handleArray, unsigned int nelem, int *statusArray); int monitorStop (vector handleV, vector &statusV); int monitorStop(unsigned int * handleArray, unsigned int nelem) { int * statusArray = new int[nelem]; status = monitorStop (handleArray, nelem, statusArray); delete [] statusArray; return status; } MonitorPolicy * createMonitorPolicyArray(const unsigned int nmp) { MonitorPolicy * mpArray = new MonitorPolicy[nmp]; return mpArray; } int terminate(); int terminate(ca_client_context * cctLocal); unsigned int getHandleFromPV(const char * pv) {return handleHelper.getHandleFromPV(pv); } const char * getPVFromHandle(unsigned int handle){ return handleHelper.getPVFromHandle(handle); } unsigned int getHandleFromPVWithinGroup(const char * pv, unsigned int grh) { return handleHelper.getHandleFromPVWithinGroup(pv, grh); } bool isEnum(unsigned int handle) {return handleHelper.isEnum(handle);} bool isValid(unsigned int handle) { for (itcs = cs.begin(); itcs != cs.end(); ++itcs) {if ((*itcs).getHandle()==handle) {return true;}} return false;} bool allChannelsConnected() { for (itcs = cs.begin(); itcs != cs.end(); ++itcs) {if (!(*itcs).isConnected()) {return false;}} return true;} bool isConnected(unsigned int handle) { return isChannelConnected(handle); } bool isChannelConnected(unsigned int handle){cafeConduit_set_by_handle & handle_index=cs.get(); cafeConduit_set_by_handle::iterator it_handle; it_handle = handle_index.find(handle); if (it_handle != handle_index.end()) {return (*it_handle).isConnected();} else {std::cout<< "Input handle " << handle << " does not exists! " << std::endl; return false;}} int getChannelInfo(unsigned int handle, ChannelRegalia & channelInfo){ cafeConduit_set_by_handle & handle_index=cs.get(); cafeConduit_set_by_handle::iterator it_handle; it_handle = handle_index.find(handle); if (it_handle != handle_index.end()) {channelInfo=(*it_handle).getChannelRegalia(); return ICAFE_NORMAL;} else {return ECAFE_INVALID_HANDLE;} }; chid getChannelID(unsigned int handle){cafeConduit_set_by_handle & handle_index=cs.get(); cafeConduit_set_by_handle::iterator it_handle; it_handle = handle_index.find(handle); if (it_handle != handle_index.end()) {return (*it_handle).getChannelID();} else {std::cout<< "Input handle " << handle << " does not exists! " << std::endl; return NULL;}} ca_client_context * getClientContext(const char * pvname){ return handleHelper.getContextFromPV(pvname); } ca_client_context * getClientContext(unsigned int handle){ return handleHelper.getContextFromHandle(handle); } int attachContext(ca_client_context *ccc){ if (ccc != NULL) { return ca_attach_context(ccc); } else { return ECAFE_NULLCONTEXT;} } int attachContextByPVName(const char * pvname){ ca_client_context * ccc=getClientContext(pvname); if (ccc != NULL) { return ca_attach_context(ccc); } else { return ECAFE_NULLCONTEXT;} } int attachContextByHandle(unsigned int handle){ ca_client_context * ccc=getClientContext(handle); if (ccc != NULL) { return ca_attach_context(ccc); } else { return ECAFE_NULLCONTEXT;} } //Add these methods for QCafe int updateAccessRead(unsigned int handle, int ar) {cafeConduit_set_by_handle & handle_index=cs.get(); cafeConduit_set_by_handle::iterator it_handle; it_handle = handle_index.find(handle); if (it_handle != handle_index.end()) { if ( (*it_handle).getAccessRead() != ar ) { if(MUTEX){cafeMutex.lock();} handle_index.modify(it_handle, change_accessRead(ar)); if(MUTEX){cafeMutex.unlock();} } return ICAFE_NORMAL;} else {std::cout<< "Input handle " << handle << " does not exists! " << std::endl; return ECAFE_INVALID_HANDLE;} } int updateAccessWrite(unsigned int handle, int aw) {cafeConduit_set_by_handle & handle_index=cs.get(); cafeConduit_set_by_handle::iterator it_handle; it_handle = handle_index.find(handle); if (it_handle != handle_index.end()) { if ( (*it_handle).getAccessWrite() != aw ) { if(MUTEX){cafeMutex.lock();} handle_index.modify(it_handle, change_accessWrite(aw)); if(MUTEX){cafeMutex.unlock();} } return ICAFE_NORMAL;} else {std::cout<< "Input handle " << handle << " does not exists! " << std::endl; return ECAFE_INVALID_HANDLE;} } bool getReadAccess(unsigned int handle){cafeConduit_set_by_handle & handle_index=cs.get(); cafeConduit_set_by_handle::iterator it_handle; it_handle = handle_index.find(handle); if (it_handle != handle_index.end()) {return (bool) (*it_handle).getAccessRead();} else {std::cout<< "Input handle " << handle << " does not exists! " << std::endl; return false;}} bool getWriteAccess(unsigned int handle){cafeConduit_set_by_handle & handle_index=cs.get(); cafeConduit_set_by_handle::iterator it_handle; it_handle = handle_index.find(handle); if (it_handle != handle_index.end()) {return (bool) (*it_handle).getAccessWrite();} else {std::cout<< "Input handle " << handle << " does not exists! " << std::endl; return false;}} void printStatusMessage(int status) { string s = getCafeStatus().csi.message(status); string c = getCafeStatus().csc.message(status); printf("%s\n",c.c_str()); printf("%s\n",s.c_str()); } int printStatus(unsigned int handle, int status); int printStatusIfError(unsigned int handle, int status); int printStatus(unsigned int * handleArray, unsigned int nelem, int * statusArray); int printStatusIfError(unsigned int * handleArray, unsigned int nelem, int * statusArray); int printStatus(vector handleV, vector statusV); int printStatusIfError(vector handleV, vector statusV); int printStatus(const char *pv, int status); int printStatusIfError(const char *pv, int status); int printStatus(const char * pvArray, unsigned int nelem, int * statusArray); int printStatusIfError(const char * pvArray, unsigned int nelem, int * statusArray); int printStatus(vector pvV, vector statusV); int printStatusIfError(vector pvV, vector statusV); int setPVAlias(unsigned int handle, const char * pv) throw (CAFEException_open); // GROUP FUNCTIONS PVDataHolder * getPVData(vector handleArray); int collectionDefine(const char * collectionName, vector deviceV); int collectionDefine(const char * collectionName, vector deviceV); int collectionDefine(const char * collectionName, pv_string_t * deviceArray, unsigned int deviceLength); int collectionFetch(const char * collectionName, vector &deviceListV); int collectionFetch(const char * collectionName, vector &deviceListV); int collectionFetch(const char * collectionName,deviceCollection &dC); vector getCollections() const {return deviceCollectionV;}; //To do: Add shared_ptr for this method to ensure memory release int collectionMemberList(const char * collectionName, boost::shared_ptr &list, unsigned int &listLength); //int collectionMemberList(const char * collectionName, dbr_string_t * &list, unsigned int &listLength); //To do: Add shared_ptr for this method to ensure memory release int collectionList (boost::shared_ptr &clist, unsigned int &listLength); //int collectionList (dbr_string_t * &clist, unsigned int &listLength); int collectionMemberList(const char * collectionName, vector &list); int collectionList (vector &clist); int devicePositionOrderedMultiMap(const char * collectionName, std::multimap &posDev); int devicePositionMap(const char * collectionName, std::map &posDev); int devicePositionV(const char * collectionName, std::vector &dev, std::vector &pos); int fetchIndexOfCollectionMember(const char *collectionName, const char * deviceName); bool isGroup(const char *); bool isCollection(const char *); int groupOpen(const char *pv, unsigned int &groupHandle) throw (CAFEException_groupOpen); int groupOpen(PVGroup &pvgroup, unsigned int &groupHandle) throw (CAFEException_groupOpen); int groupClose(unsigned int groupHandle); int groupClose(); int groupCloseAll(){return groupClose(); }; int groupHandleErase(); int groupHandleErase(ca_client_context *ccc); int groupCombine(const char * newGroupName, const char * groupName1, const char * groupName2); // PVGroup &pvGroup); int groupCombine(const char * newGroupName, vector groupName);// PVGroup &pvGroup); vector generateChannelList(vector inputStringV) { return getFromGlobalChannelList(inputStringV); } vector getFromGlobalChannelList(vector); int groupDefine (const char * groupName, const char * collectionName, vector attributeV); int groupDefine (const char * groupName, const char * collectionName, vector attributeV); int groupDefine (const char * groupName, const char * collectionName, pv_string_t * attributeArray, unsigned short attributeLength); int groupDefine (const char * groupName, const char * collectionName, pv_string_t attribute){ pv_string_t aA[1]; strcpy(aA[0], attribute); return groupDefine(groupName, collectionName, aA, 1); } int groupDefine (const char * groupName, vector deviceV, vector attributeV);// PVGroup &pvGroup); int groupDefine (const char * groupName, vector deviceV, vector attributeV); //PVGroup &pvGroup); int groupDefine (const char * groupName, pv_string_t * deviceArray, unsigned int deviceLength, pv_string_t * attributeArray, unsigned short attributeLength); // int groupDefine (const char * groupName, vector pvArrayV); // PVGroup &pvGroup); int groupDefine (const char * groupName, vector pvArrayV); // PVGroup &pvGroup); int groupDefine (const char * groupName, pv_string_t * pvArray, unsigned int pvArrayLength); //PVGroup &pvGroup); //To do: Add shared_ptr for this method to ensure memory release int groupMemberList(const char * groupName, boost::shared_ptr &list, unsigned int &listLength); //int groupMemberList(const char * groupName, dbr_string_t * &list, unsigned int &listLength); int groupList (boost::shared_ptr &glist, unsigned int &listLength); //int groupList (dbr_string_t * &glist, unsigned int &listLength); int groupMemberList(const char * groupName, vector &list); int groupList (vector &glist); int fetchIndexOfGroupMember(const char *groupName, const char * pv); void setDeviceAttributeDeliminator(std::string d) {deviceAttributeDeliminator=d;}; std::string getDeviceAttributeDeliminator() const {return deviceAttributeDeliminator;}; }; #endif // CONNECT_H