00001
00002
00003
00004
00005
00006
00007
00008 #ifndef CONNECT_H
00009 #define CONNECT_H
00010
00011
00012 #include <config.h>
00013 #include <vector>
00014 #include <string>
00015 #include <iostream>
00016 #include <fstream>
00017 #include <sstream>
00018
00019 #include <climits>
00020
00021 #include <global.h>
00022
00023 #include <exceptionsHelper.h>
00024 #include <handleHelper.h>
00025 #include <policyHelper.h>
00026 #include <hashConduitGroup.h>
00027
00028 #if HAVE_BOOST_THREAD
00029 #include <boost/thread/thread_only.hpp>
00030 #include <boost/chrono.hpp>
00031 #endif
00032
00033
00034 class Connect
00035 {
00036 protected:
00037 int status;
00038 CAFEStatus cafeStatus;
00039 CAFEStatusSeverity cafeStatusSeverity;
00040
00041 cafeConduit_set::iterator itcs;
00042 cafeGroup_set::iterator itgs;
00043
00044 CAFEDataTypeCode cafeDataTypeCode;
00045
00046 ExceptionsHelper exceptionsHelper;
00047
00048 ChannelCreatePolicy channelCreatePolicy;
00049
00050 PolicyHelper policyHelper;
00051 HandleHelper handleHelper;
00052 Helper helper;
00053
00054 std::string deviceAttributeDeliminator;
00055
00056 bool pyCafeFlag;
00057
00058
00059 static void callbackHandlerAccessRights(struct access_rights_handler_args args);
00060
00061 static void callbackHandlerException (struct exception_handler_args args);
00062
00063
00064 int createChannel(unsigned int handle, const char * pv, chid &pCh);
00065 int createHandle(const char * pv, ca_client_context * ccc, unsigned int &handle)
00066 throw (CAFEException_pv);
00067
00068 int contextDestroy();
00069 int contextDestroy(ca_client_context * cctLocal);
00070
00071 unsigned short epicsVersion(unsigned short & major, unsigned short & minor, unsigned short & patch);
00072
00073
00074
00075 int createChannelWithinGroup(unsigned int handle, const char * pv, chid &pCh);
00076 int createHandleWithinGroup(const char * pv, ca_client_context * ccc, unsigned int & _handle)
00077 throw (CAFEException_pv);
00078
00079 public:
00080 Connect(){
00081
00082 channelMonitorPolicy.setPolicy(
00083 (ChannelWhenToFlushSendBufferPolicyKind) CAFENUM::FLUSH_AFTER_EACH_CHANNEL_SUBSCRIPTION,
00084 CAFENUM::WITH_FLUSH_IO, DEFAULT_TIMEOUT_PEND_IO);
00085
00086 channelOpenGroupPolicy.setPolicy(
00087 CAFENUM::FLUSH_AFTER_EACH_GROUP_CREATION,
00088 CAFENUM::WITH_PEND_EVENT, DEFAULT_TIMEOUT_SG_PEND_EVENT);
00089
00090 channelOpenPolicy.setPolicy(
00091 CAFENUM::FLUSH_AFTER_EACH_CHANNEL_CREATION,
00092 CAFENUM::WITH_PEND_EVENT, DEFAULT_TIMEOUT_PEND_EVENT);
00093
00094 deviceAttributeDeliminator=DEFAULT_DEVICE_ATTRIBUTE_DELIMINATOR;
00095
00096
00097 #if HAVE_PYTHON_H
00098 pyCafeFlag=true;
00099 #else
00100 pyCafeFlag=false;
00101 #endif
00102
00103 };
00104
00105
00106
00107
00108 ChannelOpenPolicy channelOpenPolicy;
00109 ChannelOpenPolicy channelClosePolicy;
00110 ChannelOpenPolicy channelMonitorPolicy;
00111 ChannelOpenPolicy channelOpenGroupPolicy;
00112
00113
00114
00115
00116
00117
00118 HandleHelper getHandleHelper() {return handleHelper;}
00119 HandleHelper getInfo() {return handleHelper;}
00120 PolicyHelper getPolicyHelper() {return policyHelper;}
00121 PolicyHelper getPolicy() {return policyHelper;}
00122
00123 unsigned int getNelemClient(unsigned int h){ return handleHelper.getNelemClient(h);}
00124 unsigned int getNelemNative(unsigned int h){ return handleHelper.getNelemNative(h);}
00125 unsigned int getNelemRequest(unsigned int h){ return handleHelper.getNelemRequest(h);}
00126
00127 int getStatus() {return status;}
00128
00129 CAFEStatus getCafeStatus() {return cafeStatus;}
00130 CAFEStatusSeverity getCafeStatusSeverity() {return cafeStatusSeverity;}
00131
00132
00133 int _ca_flush_io(){return ca_flush_io();}
00134 int _ca_poll(){return ca_poll();}
00135 int _ca_pend_io(double t){return ca_pend_io(t);}
00136 int _ca_pend_event(double t){return ca_pend_event(t);}
00137
00138
00139 bool setPyCafe(bool b){return pyCafeFlag=b;};
00140 bool getPyCafe(){return pyCafeFlag;} ;
00141 int init() throw (CAFEException_init);
00142 int init(ca_preemptive_callback_select select) throw (CAFEException_init);
00143
00144
00145 int open(const string pvS, unsigned int &handle) throw (CAFEException_open){
00146 try { open (pvS.c_str(), handle);} catch(CAFEException_open &e) {throw e;};
00147 }
00148 int open(const string pvS, const std::string pvAliasS, unsigned int &handle)
00149 throw (CAFEException_open){
00150 try { open (pvS.c_str(), pvAliasS.c_str(), handle);} catch(CAFEException_open &e) {throw e;};
00151 }
00152 int open(const string *pvArrayS, unsigned int *handleArray, const unsigned int nHandles)
00153 throw (CAFEException_open);
00154
00155
00156 int open(const char *pv, unsigned int &handle) throw (CAFEException_open);
00157 int open(const char *pv, const char *pvAlias, unsigned int &handle)
00158 throw (CAFEException_open);
00159
00160 int open(const char **pvArray, unsigned int *handleArray, const unsigned int nHandles)
00161 throw (CAFEException_open);
00162 int open(vector<const char *>, vector<unsigned int> &) throw (CAFEException_open);
00163 int open(vector<string>, vector<unsigned int> &) throw (CAFEException_open);
00164
00165 int openV(vector<string> s, vector<unsigned int> &i) throw (CAFEException_open)
00166 {return open(s,i); };
00167
00168
00169
00170
00171
00172 void openGroupPrepare(){
00173 channelOpenGroupPolicy.setFlushSendBufferKind(WITH_PEND_EVENT);
00174 channelOpenGroupPolicy.setWhenToFlushSendBuffer(FLUSH_DESIGNATED_TO_CLIENT);
00175 return;
00176 }
00177
00178 void openMonitorPrepare(){
00179 channelMonitorPolicy.setFlushSendBufferKind(WITH_FLUSH_IO);
00180 channelMonitorPolicy.setWhenToFlushSendBuffer(FLUSH_DESIGNATED_TO_CLIENT);
00181 return;
00182 }
00183
00184 double setOpenDefaultPendTime(double _timeout){
00185 return channelOpenPolicy.setDefaultTimeout(_timeout);
00186 }
00187
00188 double getOpenDefaultPendTime(){
00189 return channelOpenPolicy.getDefaultTimeout();
00190 }
00191
00192
00193 void openGroupNowAndWait(double _timeout){
00194 channelOpenGroupPolicy.setTimeout(_timeout);
00195 channelOpenGroupPolicy.flushSendBufferNow();
00196
00197 channelOpenGroupPolicy.setWhenToFlushSendBuffer(FLUSH_NOW);
00198 channelOpenGroupPolicy.setFlushSendBufferKind(WITH_PEND_EVENT);
00199 channelOpenGroupPolicy.setTimeoutToDefault();
00200 return;
00201 }
00202
00203 void openMonitorNow(){
00204 channelMonitorPolicy.flushSendBufferNow();
00205
00206 channelMonitorPolicy.setWhenToFlushSendBuffer(FLUSH_NOW);
00207 channelMonitorPolicy.setFlushSendBufferKind(WITH_FLUSH_IO);
00208 return;
00209 }
00210
00211 void openMonitorNowAndWait(double _timeout){
00212 channelMonitorPolicy.setTimeout(_timeout);
00213 channelMonitorPolicy.flushSendBufferNow();
00214
00215 channelMonitorPolicy.setWhenToFlushSendBuffer(FLUSH_NOW);
00216 channelMonitorPolicy.setFlushSendBufferKind(WITH_FLUSH_IO);
00217 return;
00218 }
00219
00220 void openPrepare() {
00221 channelOpenPolicy.setFlushSendBufferKind(WITH_PEND_EVENT);
00222 channelOpenPolicy.setWhenToFlushSendBuffer(FLUSH_DESIGNATED_TO_CLIENT);
00223 return;
00224 }
00225
00226 void openNowAndWait(double _timeout) {
00227 channelOpenPolicy.setTimeout(_timeout);
00228 channelOpenPolicy.flushSendBufferNow();
00229
00230 channelOpenPolicy.setWhenToFlushSendBuffer(FLUSH_NOW);
00231 channelOpenPolicy.setFlushSendBufferKind(WITH_PEND_EVENT);
00232 channelOpenPolicy.setTimeoutToDefault();
00233 return;
00234 }
00235
00236 void openNow() {
00237 channelOpenPolicy.flushSendBufferNow();
00238 channelOpenPolicy.setWhenToFlushSendBuffer(FLUSH_NOW);
00239 channelOpenPolicy.setFlushSendBufferKind(WITH_PEND_EVENT);
00240 return;
00241 }
00242
00243 void openNoWait(){
00244 channelOpenPolicy.setFlushSendBufferKind(WITH_PEND_EVENT);
00245 channelOpenPolicy.setWhenToFlushSendBuffer(FLUSH_DESIGNATED_TO_CLIENT);
00246 return;
00247 }
00248
00249
00250
00251
00252 unsigned int printHandle(unsigned int h){return handleHelper.printHandle(h);};
00253 unsigned int printHandles(void){return handleHelper.printHandles();};
00254 unsigned int printDisconnectedHandles(void){return handleHelper.printDisconnectedHandles();};
00255 unsigned int getDisconnectedHandles(vector<unsigned int> &dhV, vector<string> &pvV)
00256 {return handleHelper.getDisconnectedHandles(dhV, pvV);};
00257
00258
00259 void printCAFEException_pv(CAFEException_pv & e){exceptionsHelper.printCAFEException_pv(e);};
00260
00261
00262 int closeChannels(unsigned int * handleArray, unsigned int nHandles);
00263 int closeChannels(vector<unsigned int> v){
00264 unsigned int * handleArray = new unsigned int[v.size()];
00265 int status= closeChannels(handleArray, v.size());
00266 delete [] handleArray;
00267 return status;
00268 };
00269 int closeChannelsV(vector<unsigned int> v){
00270 unsigned int * handleArray = new unsigned int[v.size()];
00271 int status= closeChannels(handleArray, v.size());
00272 delete [] handleArray;
00273 return status;
00274 };
00275
00276
00277 int close(unsigned int handle);
00278 int closeChannel(unsigned int handle){return close(handle);};
00279 int closeChannels();
00280 int closeChannels(ca_client_context * cctLocal);
00281 int close(){return closeChannels();};
00282
00283
00284 int closeHandles(unsigned int * handleArray, unsigned int nHandles);
00285 int closeHandle(unsigned int handle);
00286 int closeHandles();
00287
00288
00289 int monitorStart(unsigned int handle, MonitorPolicy &mp);
00290 int monitorStart(unsigned int handle, unsigned int & monitorID);
00291 int monitorStart(unsigned int handle) {
00292 unsigned int monitorID; return monitorStart(handle, monitorID);
00293 }
00294
00295 int monitorStop (unsigned int handle, MonitorPolicy mp);
00296 int monitorStop (unsigned int handle, unsigned int monitorID);
00297 int monitorStopWithID (unsigned int handle, unsigned int monitorID){
00298 return monitorStop(handle, monitorID);}
00299 int monitorStop (unsigned int handle);
00300 int monitorStop ();
00301 int monitorStopAll (){return monitorStop();};
00302 int monitorStop (ca_client_context * ccc);
00303
00304
00305 int monitorStart(unsigned int * handleArray, unsigned int nelem) {
00306 int * statusArray = new int[nelem];
00307 MonitorPolicy * mpV = new MonitorPolicy[nelem];
00308 status = monitorStart (handleArray, nelem, statusArray, mpV);
00309 delete [] statusArray; delete [] mpV;
00310 return status;
00311 }
00312
00313 int monitorStart(unsigned int * handleArray, unsigned int nelem, int *statusArray,
00314 MonitorPolicy * mpV);
00315 int monitorStart(unsigned int * handleArray, unsigned int nelem, int *statusArray,
00316 unsigned int * monitorIDArray);
00317 int monitorStart(vector<unsigned int> handleV, vector<int> &statusV,
00318 vector<MonitorPolicy> &mpV);
00319 int monitorStart(vector<unsigned int> handleV, vector<int> &statusV,
00320 vector<unsigned int> &monitorIDV);
00321 int monitorStop (unsigned int * handleArray, unsigned int nelem, int *statusArray);
00322 int monitorStop (vector<unsigned int> handleV, vector<int> &statusV);
00323
00324 int monitorStop(unsigned int * handleArray, unsigned int nelem) {
00325 int * statusArray = new int[nelem];
00326 status = monitorStop (handleArray, nelem, statusArray);
00327 delete [] statusArray;
00328 return status;
00329 }
00330
00331
00332 MonitorPolicy * createMonitorPolicyArray(const unsigned int nmp) {
00333 MonitorPolicy * mpArray = new MonitorPolicy[nmp];
00334 return mpArray;
00335 }
00336
00337 int terminate();
00338 int terminate(ca_client_context * cctLocal);
00339
00340 unsigned int getHandleFromPV(const char * pv) {return handleHelper.getHandleFromPV(pv); }
00341 const char * getPVFromHandle(unsigned int handle){
00342 return handleHelper.getPVFromHandle(handle);
00343 }
00344
00345
00346
00347 unsigned int getHandleFromPVWithinGroup(const char * pv, unsigned int grh) {
00348 return handleHelper.getHandleFromPVWithinGroup(pv, grh); }
00349
00350
00351 bool isEnum(unsigned int handle) {return handleHelper.isEnum(handle);}
00352
00353 bool isValid(unsigned int handle) { for (itcs = cs.begin(); itcs != cs.end(); ++itcs)
00354 {if ((*itcs).getHandle()==handle) {return true;}} return false;}
00355
00356 bool allChannelsConnected() { for (itcs = cs.begin(); itcs != cs.end(); ++itcs)
00357 {if (!(*itcs).isConnected()) {return false;}} return true;}
00358 bool isConnected(unsigned int handle) {
00359 return isChannelConnected(handle);
00360 }
00361 bool isChannelConnected(unsigned int handle){cafeConduit_set_by_handle & handle_index=cs.get<by_handle>();
00362 cafeConduit_set_by_handle::iterator it_handle; it_handle = handle_index.find(handle);
00363 if (it_handle != handle_index.end()) {return (*it_handle).isConnected();}
00364 else {std::cout<< "Input handle " << handle << " does not exists! " << std::endl; return false;}}
00365 int getChannelInfo(unsigned int handle, ChannelRegalia & channelInfo){
00366 cafeConduit_set_by_handle & handle_index=cs.get<by_handle>();
00367 cafeConduit_set_by_handle::iterator it_handle; it_handle = handle_index.find(handle);
00368 if (it_handle != handle_index.end()) {channelInfo=(*it_handle).getChannelRegalia(); return ICAFE_NORMAL;}
00369 else {return ECAFE_INVALID_HANDLE;}
00370 };
00371 chid getChannelID(unsigned int handle){cafeConduit_set_by_handle & handle_index=cs.get<by_handle>();
00372 cafeConduit_set_by_handle::iterator it_handle; it_handle = handle_index.find(handle);
00373 if (it_handle != handle_index.end()) {return (*it_handle).getChannelID();}
00374 else {std::cout<< "Input handle " << handle << " does not exists! " << std::endl; return NULL;}}
00375
00376
00377 ca_client_context * getClientContext(const char * pvname){
00378 return handleHelper.getContextFromPV(pvname);
00379 }
00380
00381 ca_client_context * getClientContext(unsigned int handle){
00382 return handleHelper.getContextFromHandle(handle);
00383 }
00384
00385 int attachContext(ca_client_context *ccc){
00386 if (ccc != NULL) {
00387 return ca_attach_context(ccc);
00388 } else { return ECAFE_NULLCONTEXT;}
00389 }
00390
00391 int attachContextByPVName(const char * pvname){
00392 ca_client_context * ccc=getClientContext(pvname);
00393 if (ccc != NULL) {
00394 return ca_attach_context(ccc);
00395 } else { return ECAFE_NULLCONTEXT;}
00396 }
00397
00398 int attachContextByHandle(unsigned int handle){
00399 ca_client_context * ccc=getClientContext(handle);
00400 if (ccc != NULL) {
00401 return ca_attach_context(ccc);
00402 } else { return ECAFE_NULLCONTEXT;}
00403 }
00404
00405
00406 int updateAccessRead(unsigned int handle, int ar) {cafeConduit_set_by_handle & handle_index=cs.get<by_handle>();
00407 cafeConduit_set_by_handle::iterator it_handle; it_handle = handle_index.find(handle);
00408 if (it_handle != handle_index.end()) {
00409
00410 if ( (*it_handle).getAccessRead() != ar ) {
00411 if(MUTEX){cafeMutex.lock();}
00412 handle_index.modify(it_handle, change_accessRead(ar));
00413 if(MUTEX){cafeMutex.unlock();}
00414 }
00415 return ICAFE_NORMAL;}
00416 else {std::cout<< "Input handle " << handle << " does not exists! " << std::endl;
00417 return ECAFE_INVALID_HANDLE;}
00418 }
00419
00420 int updateAccessWrite(unsigned int handle, int aw) {cafeConduit_set_by_handle & handle_index=cs.get<by_handle>();
00421 cafeConduit_set_by_handle::iterator it_handle; it_handle = handle_index.find(handle);
00422 if (it_handle != handle_index.end()) {
00423 if ( (*it_handle).getAccessWrite() != aw ) {
00424 if(MUTEX){cafeMutex.lock();}
00425 handle_index.modify(it_handle, change_accessWrite(aw));
00426 if(MUTEX){cafeMutex.unlock();}
00427 }
00428 return ICAFE_NORMAL;}
00429 else {std::cout<< "Input handle " << handle << " does not exists! " << std::endl;
00430 return ECAFE_INVALID_HANDLE;}
00431 }
00432
00433 bool getReadAccess(unsigned int handle){cafeConduit_set_by_handle & handle_index=cs.get<by_handle>();
00434 cafeConduit_set_by_handle::iterator it_handle; it_handle = handle_index.find(handle);
00435 if (it_handle != handle_index.end()) {return (bool) (*it_handle).getAccessRead();}
00436 else {std::cout<< "Input handle " << handle << " does not exists! " << std::endl; return false;}}
00437
00438 bool getWriteAccess(unsigned int handle){cafeConduit_set_by_handle & handle_index=cs.get<by_handle>();
00439 cafeConduit_set_by_handle::iterator it_handle; it_handle = handle_index.find(handle);
00440 if (it_handle != handle_index.end()) {return (bool) (*it_handle).getAccessWrite();}
00441 else {std::cout<< "Input handle " << handle << " does not exists! " << std::endl; return false;}}
00442
00443 void printStatusMessage(int status) {
00444 string s = getCafeStatus().csi.message(status);
00445 string c = getCafeStatus().csc.message(status);
00446 printf("%s\n",c.c_str());
00447 printf("%s\n",s.c_str());
00448 }
00449
00450 int printStatus(unsigned int handle, int status);
00451 int printStatusIfError(unsigned int handle, int status);
00452 int printStatus(unsigned int * handleArray, unsigned int nelem, int * statusArray);
00453 int printStatusIfError(unsigned int * handleArray, unsigned int nelem, int * statusArray);
00454 int printStatus(vector<unsigned int> handleV, vector<int> statusV);
00455 int printStatusIfError(vector<unsigned int> handleV, vector<int> statusV);
00456
00457
00458 int setPVAlias(unsigned int handle, const char * pv) throw (CAFEException_open);
00459
00460
00461
00462 PVDataHolder * getPVData(vector <unsigned int> handleArray);
00463
00464 int collectionDefine(const char * collectionName, vector<string> deviceV);
00465 int collectionDefine(const char * collectionName, vector<const char *> deviceV);
00466 int collectionDefine(const char * collectionName, pv_string_t * deviceArray, unsigned int deviceLength);
00467 int collectionFetch(const char * collectionName, vector<string> &deviceListV);
00468 int collectionFetch(const char * collectionName, vector<const char *> &deviceListV);
00469 int collectionFetch(const char * collectionName,deviceCollection &dC);
00470 vector<deviceCollection> getCollections() const {return deviceCollectionV;};
00471
00472
00473
00474 int collectionMemberList(const char * collectionName, boost::shared_ptr<pv_string_t []> &list, unsigned int &listLength);
00475
00476
00477
00478 int collectionList (boost::shared_ptr<pv_string_t []> &clist, unsigned int &listLength);
00479
00480
00481 int collectionMemberList(const char * collectionName, vector<string> &list);
00482 int collectionList (vector<string> &clist);
00483
00484 int fetchIndexOfCollectionMember(const char *collectionName, const char * deviceName);
00485
00486 bool isGroup(const char *);
00487 bool isCollection(const char *);
00488
00489 int groupOpen(const char *pv, unsigned int &groupHandle) throw (CAFEException_groupOpen);
00490 int groupOpen(PVGroup &pvgroup, unsigned int &groupHandle) throw (CAFEException_groupOpen);
00491
00492
00493 int groupClose(unsigned int groupHandle);
00494 int groupClose();
00495 int groupCloseAll(){return groupClose(); };
00496 int groupHandleErase();
00497 int groupHandleErase(ca_client_context *ccc);
00498
00499 int groupCombine(const char * newGroupName, const char * groupName1,
00500 const char * groupName2);
00501 int groupCombine(const char * newGroupName, vector<char *> groupName);
00502
00503
00504 vector<string> generateChannelList(vector<string> inputStringV) {
00505 return getFromGlobalChannelList(inputStringV);
00506 }
00507
00508 vector<string> getFromGlobalChannelList(vector<string>);
00509
00510
00511 int groupDefine (const char * groupName, const char * collectionName, vector<string> attributeV);
00512 int groupDefine (const char * groupName, const char * collectionName, vector<const char*> attributeV);
00513 int groupDefine (const char * groupName, const char * collectionName,
00514 pv_string_t * attributeArray, unsigned short attributeLength);
00515 int groupDefine (const char * groupName, const char * collectionName, pv_string_t attribute){
00516 pv_string_t aA[1]; strcpy(aA[0], attribute);
00517 return groupDefine(groupName, collectionName, aA, 1);
00518 }
00519
00520 int groupDefine (const char * groupName, vector<string> deviceV, vector<string> attributeV);
00521 int groupDefine (const char * groupName, vector<const char *> deviceV, vector<const char*> attributeV);
00522
00523 int groupDefine (const char * groupName, pv_string_t * deviceArray, unsigned int deviceLength,
00524 pv_string_t * attributeArray, unsigned short attributeLength);
00525
00526 int groupDefine (const char * groupName, vector<string> pvArrayV);
00527 int groupDefine (const char * groupName, vector<const char *> pvArrayV);
00528 int groupDefine (const char * groupName, pv_string_t * pvArray, unsigned int pvArrayLength);
00529
00530
00531
00532
00533 int groupMemberList(const char * groupName, boost::shared_ptr<pv_string_t []> &list, unsigned int &listLength);
00534
00535
00536 int groupList (boost::shared_ptr<pv_string_t []> &glist, unsigned int &listLength);
00537
00538
00539 int groupMemberList(const char * groupName, vector<string> &list);
00540
00541 int groupList (vector<string> &glist);
00542
00543 int fetchIndexOfGroupMember(const char *groupName, const char * pv);
00544
00545 void setDeviceAttributeDeliminator(std::string d) {deviceAttributeDeliminator=d;};
00546 std::string getDeviceAttributeDeliminator() const {return deviceAttributeDeliminator;};
00547
00548
00549 };
00550
00551 #endif // CONNECT_H