00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "TMidasOnline.h"
00013
00014 #include <string>
00015 #include <assert.h>
00016 #include "midas.h"
00017 #include "msystem.h"
00018
00019
00020
00021
00022 TMidasOnline::TMidasOnline()
00023 {
00024 fDB = 0;
00025 fStartHandler = 0;
00026 fStopHandler = 0;
00027 fPauseHandler = 0;
00028 fResumeHandler = 0;
00029 fEventRequests = 0;
00030 fEventHandler = 0;
00031 }
00032
00033 TMidasOnline::~TMidasOnline()
00034 {
00035 disconnect();
00036 }
00037
00038 TMidasOnline* TMidasOnline::instance()
00039 {
00040 if (!gfMidas)
00041 gfMidas = new TMidasOnline();
00042
00043 return gfMidas;
00044 }
00045
00046 int TMidasOnline::connect(const char*hostname,const char*exptname,const char*progname)
00047 {
00048 int status;
00049
00050 char xhostname[HOST_NAME_LENGTH];
00051 char xexptname[NAME_LENGTH];
00052
00053
00054 status = cm_get_environment(xhostname, sizeof(xhostname), xexptname, sizeof(xexptname));
00055 assert(status == CM_SUCCESS);
00056
00057 if (hostname)
00058 strlcpy(xhostname,hostname,sizeof(xhostname));
00059
00060 if (exptname)
00061 strlcpy(xexptname,exptname,sizeof(xexptname));
00062
00063 fHostname = xhostname;
00064 fExptname = xexptname;
00065
00066 fprintf(stderr, "TMidasOnline::connect: Connecting to experiment \"%s\" on host \"%s\"\n", fExptname.c_str(), fHostname.c_str());
00067
00068
00069 int watchdog = 60*1000;
00070
00071 status = cm_connect_experiment1((char*)fHostname.c_str(), (char*)fExptname.c_str(), (char*)progname, NULL, DEFAULT_ODB_SIZE, watchdog);
00072
00073 if (status == CM_UNDEF_EXP)
00074 {
00075 fprintf(stderr, "TMidasOnline::connect: Error: experiment \"%s\" not defined.\n", fExptname.c_str());
00076 return -1;
00077 }
00078 else if (status != CM_SUCCESS)
00079 {
00080 fprintf(stderr, "TMidasOnline::connect: Cannot connect to MIDAS, status %d.\n", status);
00081 return -1;
00082 }
00083
00084 status = cm_get_experiment_database(&fDB, NULL);
00085 assert(status == CM_SUCCESS);
00086
00087 cm_set_watchdog_params(true, 60*1000);
00088
00089 return 0;
00090 }
00091
00092 int TMidasOnline::disconnect()
00093 {
00094 if (fDB)
00095 {
00096 fprintf(stderr, "TMidasOnline::disconnect: Disconnecting from experiment \"%s\" on host \"%s\"\n", fExptname.c_str(), fHostname.c_str());
00097 cm_disconnect_experiment();
00098 fDB = 0;
00099 }
00100
00101 return 0;
00102 }
00103
00104 void TMidasOnline::registerTransitions()
00105 {
00106 cm_register_transition(TR_START, NULL, 300);
00107 cm_register_transition(TR_PAUSE, NULL, 700);
00108 cm_register_transition(TR_RESUME, NULL, 300);
00109 cm_register_transition(TR_STOP, NULL, 700);
00110 }
00111
00112 void TMidasOnline::setTransitionHandlers(TransitionHandler start,TransitionHandler stop,TransitionHandler pause,TransitionHandler resume)
00113 {
00114 fStartHandler = start;
00115 fStopHandler = stop;
00116 fPauseHandler = pause;
00117 fResumeHandler = resume;
00118 }
00119
00120 bool TMidasOnline::checkTransitions()
00121 {
00122 int transition, run_number, trans_time;
00123
00124 int status = cm_query_transition(&transition, &run_number, &trans_time);
00125 if (status != CM_SUCCESS)
00126 return false;
00127
00128
00129
00130 if (transition == TR_START)
00131 {
00132 if (fStartHandler)
00133 (*fStartHandler)(transition,run_number,trans_time);
00134 return true;
00135 }
00136 else if (transition == TR_STOP)
00137 {
00138 if (fStopHandler)
00139 (*fStopHandler)(transition,run_number,trans_time);
00140 return true;
00141
00142 }
00143 else if (transition == TR_PAUSE)
00144 {
00145 if (fPauseHandler)
00146 (*fPauseHandler)(transition,run_number,trans_time);
00147 return true;
00148
00149 }
00150 else if (transition == TR_RESUME)
00151 {
00152 if (fResumeHandler)
00153 (*fResumeHandler)(transition,run_number,trans_time);
00154 return true;
00155 }
00156
00157 return false;
00158 }
00159
00160 bool TMidasOnline::poll(int mdelay)
00161 {
00162
00163
00164 if (checkTransitions())
00165 return true;
00166
00167 int status = cm_yield(mdelay);
00168 if (status == RPC_SHUTDOWN || status == SS_ABORT)
00169 {
00170 fprintf(stderr, "TMidasOnline::poll: cm_yield(%d) status %d, shutting down.\n",mdelay,status);
00171 disconnect();
00172 return false;
00173 }
00174
00175 return true;
00176 }
00177
00178 void TMidasOnline::setEventHandler(EventHandler handler)
00179 {
00180 fEventHandler = handler;
00181 }
00182
00183 static void eventCallback(HNDLE buffer_handle, HNDLE request_id, EVENT_HEADER* pheader, void* pevent)
00184 {
00185 #if 0
00186 printf("eventCallback: buffer %d, request %d, pheader %p (event_id: %d, trigger mask: 0x%x, serial: %d, time: %d, size: %d), pevent %p\n",
00187 buffer_handle,
00188 request_id,
00189 pheader,
00190 pheader->event_id,
00191 pheader->trigger_mask,
00192 pheader->serial_number,
00193 pheader->time_stamp,
00194 pheader->data_size,
00195 pevent);
00196 #endif
00197
00198 if (TMidasOnline::instance()->fEventHandler)
00199 TMidasOnline::instance()->fEventHandler(pheader,pevent,pheader->data_size);
00200 }
00201
00202 int TMidasOnline::receiveEvent(int requestId, void* pevent, int size, bool async)
00203 {
00204 EventRequest* r = fEventRequests;
00205
00206 while (1)
00207 {
00208 if (!r)
00209 {
00210 fprintf(stderr, "TMidasOnline::receiveEvent: Cannot find request %d\n", requestId);
00211 return -1;
00212 }
00213
00214 if (r->fRequestId == requestId)
00215 break;
00216
00217 r = r->fNext;
00218 }
00219
00220 int flag = 0;
00221 if (async){
00222 #ifdef BM_NO_WAIT
00223 flag = BM_NO_WAIT;
00224 #else
00225 flag = ASYNC;
00226 #endif
00227 }
00228
00229
00230 int status = bm_receive_event(r->fBufferHandle, pevent, &size, flag);
00231
00232 if (status == BM_ASYNC_RETURN)
00233 {
00234 return 0;
00235 }
00236
00237 if (status != BM_SUCCESS)
00238 {
00239 fprintf(stderr, "TMidasOnline::receiveEvent: bm_receive_event() error %d\n", status);
00240 return -1;
00241 }
00242
00243 return size;
00244 }
00245
00246 #ifndef EVENT_BUFFER_SIZE
00247 #define EVENT_BUFFER_SIZE 0
00248 #endif
00249
00250 int TMidasOnline::eventRequest(const char* bufferName, int eventId, int triggerMask, int samplingType, bool poll)
00251 {
00252 int status;
00253 EventRequest* r = new EventRequest();
00254
00255 if (bufferName == NULL)
00256 bufferName = EVENT_BUFFER_NAME;
00257
00258 r->fNext = NULL;
00259 r->fBufferName = bufferName;
00260 r->fEventId = eventId;
00261 r->fTriggerMask = triggerMask;
00262 r->fSamplingType = samplingType;
00263
00264
00265
00266 status = bm_open_buffer((char*)bufferName, EVENT_BUFFER_SIZE, &r->fBufferHandle);
00267 if (status!=SUCCESS && status!=BM_CREATED)
00268 {
00269 fprintf(stderr, "TMidasOnline::eventRequest: Cannot find data buffer \"%s\", bm_open_buffer() error %d\n", bufferName, status);
00270 return -1;
00271 }
00272
00273
00274 if(samplingType != GET_RECENT){
00275 status = bm_set_cache_size(r->fBufferHandle, 100000, 0);
00276 assert(status == BM_SUCCESS);
00277 }
00278
00279 if (poll)
00280 status = bm_request_event(r->fBufferHandle, r->fEventId, r->fTriggerMask, r->fSamplingType, &r->fRequestId, NULL);
00281 else
00282 status = bm_request_event(r->fBufferHandle, r->fEventId, r->fTriggerMask, r->fSamplingType, &r->fRequestId, eventCallback);
00283 assert(status == BM_SUCCESS);
00284
00285 fprintf(stderr, "TMidasOnline::eventRequest: Event request: buffer \"%s\" (%d), event id 0x%x, trigger mask 0x%x, sample %d, request id: %d\n",bufferName,r->fBufferHandle,r->fEventId,r->fTriggerMask,r->fSamplingType,r->fRequestId);
00286
00287 r->fNext = fEventRequests;
00288 fEventRequests = r;
00289
00290 return r->fRequestId;
00291 };
00292
00293 int TMidasOnline::getBufferLevel(){
00294
00295 if(!fEventRequests || !fEventRequests->fBufferHandle) return -1;
00296
00297 int n_bytes;
00298 bm_get_buffer_level(fEventRequests->fBufferHandle, &n_bytes);
00299
00300 return n_bytes;
00301
00302 }
00303
00304 int TMidasOnline::getBufferSize(){
00305
00306 if(!fEventRequests || !fEventRequests->fBufferHandle) return -1;
00307
00308 BUFFER_HEADER buffer_header;
00309 bm_get_buffer_info(fEventRequests->fBufferHandle,&buffer_header);
00310
00311 return buffer_header.size;
00312
00313 }
00314 void TMidasOnline::deleteEventRequest(int requestId)
00315 {
00316 for (EventRequest* r = fEventRequests; r != NULL; r = r->fNext)
00317 if (r->fRequestId == requestId)
00318 {
00319 int status = bm_delete_request(r->fRequestId);
00320 assert(status == BM_SUCCESS);
00321
00322 r->fBufferHandle = -1;
00323 r->fRequestId = -1;
00324 }
00325 }
00326
00327
00328
00329
00330 int TMidasOnline::odbReadInt(const char*name,int index,int defaultValue)
00331 {
00332 int value = defaultValue;
00333 if (odbReadAny(name,index,TID_INT,&value) == 0)
00334 return value;
00335 else
00336 return defaultValue;
00337 };
00338
00339 uint32_t TMidasOnline::odbReadUint32(const char*name,int index,uint32_t defaultValue)
00340 {
00341 uint32_t value = defaultValue;
00342 if (odbReadAny(name,index,TID_DWORD,&value) == 0)
00343 return value;
00344 else
00345 return defaultValue;
00346 };
00347
00348 bool TMidasOnline::odbReadBool(const char*name,int index,bool defaultValue)
00349 {
00350 uint32_t value = defaultValue;
00351 if (odbReadAny(name,index,TID_BOOL,&value) == 0)
00352 return value;
00353 else
00354 return defaultValue;
00355 };
00356
00357 float TMidasOnline::odbReadFloat(const char*name,int index,float defaultValue)
00358 {
00359 float value = defaultValue;
00360 if (odbReadAny(name,index,TID_FLOAT,&value) == 0)
00361 return value;
00362 else
00363 return defaultValue;
00364 };
00365
00366 double TMidasOnline::odbReadDouble(const char*name,int index,double defaultValue)
00367 {
00368 double value = defaultValue;
00369 if (odbReadAny(name,index,TID_DOUBLE,&value) == 0)
00370 return value;
00371 else
00372 return defaultValue;
00373 };
00374
00375 const char* TMidasOnline::odbReadString(const char *name, int index, const char *defaultValue)
00376 {
00377 const int bufsize = 1024;
00378 static char buf[bufsize];
00379 if (odbReadAny(name, index, TID_STRING, buf, bufsize) == 0)
00380 return buf;
00381 else
00382 return defaultValue;
00383 };
00384
00385 int TMidasOnline::odbReadArraySize(const char*name)
00386 {
00387 int status;
00388 HNDLE hdir = 0;
00389 HNDLE hkey;
00390 KEY key;
00391
00392 status = db_find_key (fDB, hdir, (char*)name, &hkey);
00393 if (status != SUCCESS)
00394 return 0;
00395
00396 status = db_get_key(fDB, hkey, &key);
00397 if (status != SUCCESS)
00398 return 0;
00399
00400 return key.num_values;
00401 }
00402
00403 int TMidasOnline::odbReadAny(const char*name,int index,int tid,void* buf, int bufsize)
00404 {
00405 int status;
00406 int size = bufsize;
00407 HNDLE hdir = 0;
00408 HNDLE hkey;
00409
00410 if (size == 0)
00411 size = rpc_tid_size(tid);
00412
00413 status = db_find_key (fDB, hdir, (char*)name, &hkey);
00414 if (status == SUCCESS)
00415 {
00416 status = db_get_data_index(fDB, hkey, buf, &size, index, tid);
00417 if (status != SUCCESS)
00418 {
00419 cm_msg(MERROR, "TMidasOnline", "Cannot read \'%s\'[%d] of type %d from odb, db_get_data_index() status %d", name, index, tid, status);
00420 return -1;
00421 }
00422
00423 return 0;
00424 }
00425 else if (status == DB_NO_KEY)
00426 {
00427 cm_msg(MINFO, "TMidasOnline", "Creating \'%s\'[%d] of type %d", name, index, tid);
00428
00429 status = db_create_key(fDB, hdir, (char*)name, tid);
00430 if (status != SUCCESS)
00431 {
00432 cm_msg (MERROR, "TMidasOnline", "Cannot create \'%s\' of type %d, db_create_key() status %d", name, tid, status);
00433 return -1;
00434 }
00435
00436 status = db_find_key (fDB, hdir, (char*)name, &hkey);
00437 if (status != SUCCESS)
00438 {
00439 cm_msg(MERROR, "TMidasOnline", "Cannot create \'%s\', db_find_key() status %d", name, status);
00440 return -1;
00441 }
00442
00443 status = db_set_data_index(fDB, hkey, buf, size, index, tid);
00444 if (status != SUCCESS)
00445 {
00446 cm_msg(MERROR, "TMidasOnline", "Cannot write \'%s\'[%d] of type %d to odb, db_set_data_index() status %d", name, index, tid, status);
00447 return -1;
00448 }
00449
00450 return 0;
00451 }
00452 else
00453 {
00454 cm_msg(MERROR, "TMidasOnline", "Cannot read \'%s\'[%d] from odb, db_find_key() status %d", name, index, status);
00455 return -1;
00456 }
00457 };
00458
00459 TMidasOnline* TMidasOnline::gfMidas = NULL;
00460
00461