00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include <stdio.h>
00018 #include "midas.h"
00019 #include "mevb.h"
00020 #include "msystem.h"
00021 #include "ybos.h"
00022
00023 #define SERVER_CACHE_SIZE 100000
00024
00025 #define ODB_UPDATE_TIME 1000
00026
00027 #define DEFAULT_FE_TIMEOUT 60000
00028
00029 EBUILDER_SETTINGS ebset;
00030 EBUILDER_CHANNEL ebch[MAX_CHANNELS];
00031
00032 INT run_state;
00033 INT run_number;
00034 DWORD last_time;
00035 DWORD actual_time;
00036 DWORD actual_millitime;
00037
00038 char svn_revision[] = "$Id: mevb.c 3472 2006-12-19 10:16:08Z ritt $";
00039 char host_name[HOST_NAME_LENGTH];
00040 char expt_name[NAME_LENGTH];
00041 char buffer_name[NAME_LENGTH];
00042 INT nfragment;
00043 char *dest_event;
00044 HNDLE hDB, hKey, hStatKey, hSubkey, hEqKey, hESetKey;
00045 BOOL debug = FALSE, debug1 = FALSE;
00046
00047 BOOL wheel = FALSE;
00048 char bars[] = "|\\-/";
00049 int i_bar;
00050 BOOL abort_requested = FALSE, stop_requested = TRUE;
00051 DWORD stop_time = 0, request_stop_time = 0;
00052
00053 INT(*meb_fragment_add) (char *, char *, INT *);
00054 INT handFlush(void);
00055 INT source_booking(void);
00056 INT source_unbooking(void);
00057 INT close_buffers(void);
00058 INT source_scan(INT fmt, EQUIPMENT_INFO * eq_info);
00059 INT eb_mfragment_add(char *pdest, char *psrce, INT * size);
00060 INT eb_yfragment_add(char *pdest, char *psrce, INT * size);
00061
00062 INT eb_begin_of_run(INT, char *, char *);
00063 INT eb_end_of_run(INT, char *);
00064 INT eb_user(INT, BOOL mismatch, EBUILDER_CHANNEL *, EVENT_HEADER *, void *, INT *);
00065 INT load_fragment(void);
00066 INT scan_fragment(void);
00067 extern char *frontend_name;
00068 extern char *frontend_file_name;
00069 extern BOOL frontend_call_loop;
00070
00071 extern INT max_event_size;
00072 extern INT max_event_size_frag;
00073 extern INT event_buffer_size;
00074 extern INT display_period;
00075 extern INT ebuilder_init(void);
00076 extern INT ebuilder_exit(void);
00077 extern INT ebuilder_loop(void);
00078
00079 extern EQUIPMENT equipment[];
00080 extern INT ybos_event_swap(DWORD * pevt);
00081
00082 #define EQUIPMENT_COMMON_STR "\
00083 Event ID = WORD : 0\n\
00084 Trigger mask = WORD : 0\n\
00085 Buffer = STRING : [32] SYSTEM\n\
00086 Type = INT : 0\n\
00087 Source = INT : 0\n\
00088 Format = STRING : [8] FIXED\n\
00089 Enabled = BOOL : 0\n\
00090 Read on = INT : 0\n\
00091 Period = INT : 0\n\
00092 Event limit = DOUBLE : 0\n\
00093 Num subevents = DWORD : 0\n\
00094 Log history = INT : 0\n\
00095 Frontend host = STRING : [32] \n\
00096 Frontend name = STRING : [32] \n\
00097 Frontend file name = STRING : [256] \n\
00098 "
00099
00100 #define EQUIPMENT_STATISTICS_STR "\
00101 Events sent = DOUBLE : 0\n\
00102 Events per sec. = DOUBLE : 0\n\
00103 kBytes per sec. = DOUBLE : 0\n\
00104 "
00105
00106
00107 INT register_equipment(void)
00108 {
00109 INT index, size, status;
00110 char str[256];
00111 EQUIPMENT_INFO *eq_info;
00112 EQUIPMENT_STATS *eq_stats;
00113 HNDLE hKey;
00114
00115
00116 size = sizeof(run_state);
00117 run_state = STATE_STOPPED;
00118 db_get_value(hDB, 0, "/Runinfo/State", &run_state, &size, TID_INT, TRUE);
00119 size = sizeof(run_number);
00120 run_number = 1;
00121 status = db_get_value(hDB, 0, "/Runinfo/Run number", &run_number, &size, TID_INT, TRUE);
00122 assert(status == SUCCESS);
00123
00124
00125 for (index = 0; equipment[index].name[0]; index++) {
00126 eq_info = &equipment[index].info;
00127 eq_stats = &equipment[index].stats;
00128
00129 if (eq_info->event_id == 0) {
00130 printf("\nEvent ID 0 for %s not allowed\n", equipment[index].name);
00131 cm_disconnect_experiment();
00132 ss_sleep(5000);
00133 exit(0);
00134 }
00135
00136
00137 equipment[index].status = EB_SUCCESS;
00138
00139 sprintf(str, "/Equipment/%s/Common", equipment[index].name);
00140
00141
00142 if (eq_info->eq_type != EQ_SLOW) {
00143 db_find_key(hDB, 0, str, &hKey);
00144 size = sizeof(double);
00145 if (hKey)
00146 db_get_value(hDB, hKey, "Event limit", &eq_info->event_limit, &size, TID_DOUBLE, TRUE);
00147 }
00148
00149
00150 status = db_check_record(hDB, 0, str, EQUIPMENT_COMMON_STR, TRUE);
00151 if (status != DB_SUCCESS) {
00152 printf("Cannot check equipment record, status = %d\n", status);
00153 ss_sleep(3000);
00154 }
00155 db_find_key(hDB, 0, str, &hKey);
00156
00157 if (equal_ustring(eq_info->format, "YBOS"))
00158 equipment[index].format = FORMAT_YBOS;
00159 else if (equal_ustring(eq_info->format, "FIXED"))
00160 equipment[index].format = FORMAT_FIXED;
00161 else
00162 equipment[index].format = FORMAT_MIDAS;
00163
00164 gethostname(eq_info->frontend_host, sizeof(eq_info->frontend_host));
00165 strcpy(eq_info->frontend_name, frontend_name);
00166 strcpy(eq_info->frontend_file_name, frontend_file_name);
00167
00168
00169 db_set_record(hDB, hKey, eq_info, sizeof(EQUIPMENT_INFO), 0);
00170
00171
00172 size = sizeof(EQUIPMENT_INFO);
00173 db_get_record(hDB, hKey, eq_info, &size, 0);
00174
00175
00176 sprintf(str, "/Equipment/%s/Variables", equipment[index].name);
00177 db_create_key(hDB, 0, str, TID_KEY);
00178 db_find_key(hDB, 0, str, &hKey);
00179 equipment[index].hkey_variables = hKey;
00180
00181
00182 sprintf(str, "/Equipment/%s/Statistics", equipment[index].name);
00183
00184 status = db_check_record(hDB, 0, str, EQUIPMENT_STATISTICS_STR, TRUE);
00185 if (status != DB_SUCCESS) {
00186 printf("Cannot create/check statistics record, error %d\n", status);
00187 ss_sleep(3000);
00188 }
00189
00190 status = db_find_key(hDB, 0, str, &hKey);
00191 if (status != DB_SUCCESS) {
00192 printf("Cannot find statistics record, error %d\n", status);
00193 ss_sleep(3000);
00194 }
00195
00196 eq_stats->events_sent = 0;
00197 eq_stats->events_per_sec = 0;
00198 eq_stats->kbytes_per_sec = 0;
00199
00200
00201 status = db_open_record(hDB, hKey, eq_stats, sizeof(EQUIPMENT_STATS)
00202 , MODE_WRITE, NULL, NULL);
00203 if (status != DB_SUCCESS) {
00204 cm_msg(MERROR, "register_equipment",
00205 "Cannot open statistics record, error %d. Probably other FE is using it", status);
00206 ss_sleep(3000);
00207 }
00208
00209
00210 if (eq_info->buffer[0]) {
00211 status = bm_open_buffer(eq_info->buffer, 2 * MAX_EVENT_SIZE, &equipment[index].buffer_handle);
00212 if (status != BM_SUCCESS && status != BM_CREATED) {
00213 cm_msg(MERROR, "register_equipment",
00214 "Cannot open event buffer. Try to reduce EVENT_BUFFER_SIZE in midas.h \
00215 and rebuild the system.");
00216 return 0;
00217 }
00218
00219
00220 bm_set_cache_size(equipment[index].buffer_handle, 0, SERVER_CACHE_SIZE);
00221 } else {
00222 cm_msg(MERROR, "register_equipment", "Destination buffer must be present");
00223 ss_sleep(3000);
00224 exit(0);
00225 }
00226 }
00227 return SUCCESS;
00228 }
00229
00230
00231 INT load_fragment(void)
00232 {
00233 INT i, size, type;
00234 HNDLE hEqKey, hSubkey;
00235 EQUIPMENT_INFO *eq_info;
00236 KEY key;
00237 char buffer[NAME_LENGTH];
00238 char format[8];
00239
00240
00241 eq_info = &equipment[0].info;
00242
00243
00244 if (db_find_key(hDB, 0, "Equipment", &hEqKey) != DB_SUCCESS) {
00245 cm_msg(MINFO, "load_fragment", "Equipment listing not found");
00246 return EB_ERROR;
00247 }
00248
00249
00250 for (i = 0, nfragment = 0;; i++) {
00251 db_enum_key(hDB, hEqKey, i, &hSubkey);
00252 if (!hSubkey)
00253 break;
00254 db_get_key(hDB, hSubkey, &key);
00255 if (key.type == TID_KEY) {
00256
00257 if (debug)
00258 printf("Equipment name:%s\n", key.name);
00259
00260 size = sizeof(INT);
00261 db_get_value(hDB, hSubkey, "common/type", &type, &size, TID_INT, 0);
00262 size = sizeof(buffer);
00263 db_get_value(hDB, hSubkey, "common/Buffer", buffer, &size, TID_STRING, 0);
00264 size = sizeof(format);
00265 db_get_value(hDB, hSubkey, "common/Format", format, &size, TID_STRING, 0);
00266
00267 if ((type & EQ_EB)
00268 && (strncmp(buffer, buffer_name, strlen(buffer_name)) == 0)
00269 && (strncmp(format, eq_info->format, strlen(format)) == 0)) {
00270
00271 strcpy(ebch[nfragment].format, format);
00272 strcpy(ebch[nfragment].buffer, buffer);
00273 size = sizeof(WORD);
00274 db_get_value(hDB, hSubkey, "common/Trigger Mask", &ebch[nfragment].trigger_mask, &size, TID_WORD,
00275 0);
00276 size = sizeof(WORD);
00277 db_get_value(hDB, hSubkey, "common/Event ID", &ebch[nfragment].event_id, &size, TID_WORD, 0);
00278 nfragment++;
00279 }
00280 }
00281 }
00282
00283 if (nfragment > 1)
00284 printf("Found %d fragments for event building\n", nfragment);
00285 else
00286 printf("Found one fragment for event building\n");
00287
00288
00289
00290 if (equipment[0].format == FORMAT_MIDAS)
00291 meb_fragment_add = eb_mfragment_add;
00292 else if (equipment[0].format == FORMAT_YBOS)
00293 meb_fragment_add = eb_yfragment_add;
00294 else {
00295 cm_msg(MERROR, "load_fragment", "Unknown data format :%d", format);
00296 return EB_ERROR;
00297 }
00298
00299
00300 dest_event = (char *) malloc(nfragment * (max_event_size + sizeof(EVENT_HEADER)));
00301 memset(dest_event, 0, nfragment * (max_event_size + sizeof(EVENT_HEADER)));
00302 if (dest_event == NULL) {
00303 cm_msg(MERROR, "load_fragment", "%s: Not enough memory for event buffer", frontend_name);
00304 return EB_ERROR;
00305 }
00306 return EB_SUCCESS;
00307 }
00308
00309
00310 INT scan_fragment(void)
00311 {
00312 INT fragn, status;
00313 EQUIPMENT *eq;
00314 EQUIPMENT_INFO *eq_info;
00315 INT ch;
00316
00317
00318 eq_info = &equipment[0].info;
00319 status = 0;
00320 eq = NULL;
00321
00322
00323 do {
00324 switch (run_state) {
00325 case STATE_STOPPED:
00326 case STATE_PAUSED:
00327
00328 status = cm_yield(500);
00329 if (wheel) {
00330 printf("...%c Snoring\r", bars[i_bar++ % 4]);
00331 fflush(stdout);
00332 }
00333 break;
00334 case STATE_RUNNING:
00335 status = source_scan(equipment[0].format, eq_info);
00336 switch (status) {
00337 case BM_ASYNC_RETURN:
00338 for (fragn = 0; fragn < nfragment; fragn++) {
00339 if (ebch[fragn].timeout > TIMEOUT) {
00340 if (stop_requested) {
00341 if (debug)
00342 printf("Stop requested on timeout %d\n", status);
00343 status = close_buffers();
00344 break;
00345 } else {
00346
00347
00348 status = cm_yield(10);
00349 if (wheel) {
00350 printf("...%c Timing on %1.0lf\r", bars[i_bar++ % 4], eq->stats.events_sent);
00351 fflush(stdout);
00352 }
00353 }
00354 }
00355
00356 }
00357 break;
00358 case EB_ERROR:
00359 case EB_USER_ERROR:
00360 abort_requested = TRUE;
00361 if (status == EB_USER_ERROR)
00362 cm_msg(MTALK, "scan_fragment", "%s: Error signaled by user code - stopping run...",
00363 frontend_name);
00364 else
00365 cm_msg(MTALK, "EBuilder", "%s: Event mismatch - Stopping run...", frontend_name);
00366 if (cm_transition(TR_STOP, 0, NULL, 0, ASYNC, 0) != CM_SUCCESS) {
00367 cm_msg(MERROR, "scan_fragment", "%s: Stop Transition request failed", frontend_name);
00368 return status;
00369 }
00370 if (debug)
00371 printf("Stop requested on Error %d\n", status);
00372 status = close_buffers();
00373 return status;
00374 break;
00375 case EB_SUCCESS:
00376 case EB_SKIP:
00377
00378
00379 break;
00380 default:
00381 cm_msg(MERROR, "scan_fragment", "unexpected return %d", status);
00382 status = SS_ABORT;
00383 }
00384 break;
00385 }
00386
00387
00388 if ((actual_millitime = ss_millitime()) - last_time > 1000) {
00389
00390 rpc_flush_event();
00391
00392 bm_flush_cache(equipment[0].buffer_handle, ASYNC);
00393
00394 status = cm_yield(10);
00395
00396 eq = &equipment[0];
00397 eq->stats.events_sent += eq->events_sent;
00398 eq->stats.events_per_sec = eq->events_sent / ((actual_millitime - last_time) / 1000.0);
00399 eq->stats.kbytes_per_sec = eq->bytes_sent / 1024.0 / ((actual_millitime - last_time) / 1000.0);
00400 eq->bytes_sent = 0;
00401 eq->events_sent = 0;
00402
00403 db_send_changed_records();
00404
00405 last_time = ss_millitime();
00406 }
00407
00408 ch = 0;
00409 if (ss_kbhit()) {
00410 ch = ss_getchar(0);
00411 if (ch == -1)
00412 ch = getchar();
00413 if ((char) ch == '!')
00414 break;
00415 }
00416 } while (status != RPC_SHUTDOWN && status != SS_ABORT);
00417
00418 return status;
00419 }
00420
00421
00422 INT eb_mfragment_add(char *pdest, char *psrce, INT * size)
00423 {
00424 BANK_HEADER *psbh, *pdbh;
00425 char *psdata, *pddata;
00426 INT bksize;
00427
00428
00429 *size = ((EVENT_HEADER *) pdest)->data_size;
00430
00431
00432 pddata = pdest + *size + sizeof(EVENT_HEADER);
00433
00434 if (*size) {
00435
00436
00437
00438 psbh = (BANK_HEADER *) (((EVENT_HEADER *) psrce) + 1);
00439 bk_swap(psbh, FALSE);
00440
00441
00442 psbh = (BANK_HEADER *) (((EVENT_HEADER *) psrce) + 1);
00443 psdata = (char *) (psbh + 1);
00444
00445
00446 bksize = psbh->data_size;
00447
00448
00449 memcpy(pddata, psdata, bksize);
00450
00451
00452 ((EVENT_HEADER *) pdest)->data_size += bksize;
00453
00454
00455 pdbh = (BANK_HEADER *) (((EVENT_HEADER *) pdest) + 1);
00456 pdbh->data_size += bksize;
00457
00458 *size = ((EVENT_HEADER *) pdest)->data_size;
00459 } else {
00460
00461
00462 *size = ((EVENT_HEADER *) psrce)->data_size;
00463
00464
00465 psbh = (BANK_HEADER *) (((EVENT_HEADER *) psrce) + 1);
00466 bk_swap(psbh, FALSE);
00467
00468
00469 memcpy(pddata, psbh, *size);
00470
00471
00472 ((EVENT_HEADER *) pdest)->data_size = *size;
00473 }
00474 return CM_SUCCESS;
00475 }
00476
00477
00478 INT eb_yfragment_add(char *pdest, char *psrce, INT * size)
00479 {
00480
00481
00482
00483
00484 char *psdata, *pddata;
00485 DWORD *pslrl, *pdlrl;
00486 INT i4frgsize, i1frgsize, status;
00487
00488
00489 *size = ((EVENT_HEADER *) pdest)->data_size;
00490
00491
00492
00493 pddata = pdest + *size + sizeof(EVENT_HEADER);
00494
00495
00496 if (*size) {
00497
00498
00499 pslrl = (DWORD *) (((EVENT_HEADER *) psrce) + 1);
00500
00501
00502 status = ybos_event_swap(pslrl);
00503
00504
00505 psdata = (char *) (pslrl + 1);
00506
00507
00508 i4frgsize = (*pslrl);
00509 i1frgsize = 4 * i4frgsize;
00510
00511
00512 memcpy(pddata, psdata, i1frgsize);
00513
00514
00515 ((EVENT_HEADER *) pdest)->data_size += i1frgsize;
00516
00517
00518 pdlrl = (DWORD *) (((EVENT_HEADER *) pdest) + 1);
00519 *pdlrl += i4frgsize;
00520
00521
00522 *size = ((EVENT_HEADER *) pdest)->data_size;
00523 } else {
00524
00525
00526
00527
00528
00529
00530
00531 pslrl = (DWORD *) (((EVENT_HEADER *) psrce) + 1);
00532
00533
00534 status = ybos_event_swap(pslrl);
00535
00536
00537 *size = ((EVENT_HEADER *) psrce)->data_size;
00538
00539
00540 memcpy(pddata, (char *) pslrl, *size);
00541
00542
00543 ((EVENT_HEADER *) pdest)->data_size += *size;
00544
00545 }
00546 return CM_SUCCESS;
00547 }
00548
00549
00550 INT tr_start(INT rn, char *error)
00551 {
00552 EBUILDER(ebuilder_str);
00553 INT status, size, i;
00554 char str[128];
00555 KEY key;
00556 HNDLE hKey, hEqkey, hEqFRkey;
00557 EQUIPMENT_INFO *eq_info;
00558
00559
00560 eq_info = &equipment[0].info;
00561
00562
00563 sprintf(str, "/Equipment/%s/Common", equipment[0].name);
00564 status = db_find_key(hDB, 0, str, &hKey);
00565 size = sizeof(EQUIPMENT_INFO);
00566 db_get_record(hDB, hKey, eq_info, &size, 0);
00567
00568 ebset.nfragment = nfragment;
00569
00570
00571 for (i = 0; equipment[i].name[0]; i++) {
00572 equipment[i].serial_number = 1;
00573 equipment[i].subevent_number = 0;
00574 equipment[i].stats.events_sent = 0;
00575 equipment[i].odb_in = equipment[i].odb_out = 0;
00576 }
00577
00578
00579 sprintf(str, "/Equipment/%s/Settings", equipment[0].name);
00580 if (db_find_key(hDB, 0, str, &hEqkey) != DB_SUCCESS) {
00581 status = db_create_record(hDB, 0, str, strcomb(ebuilder_str));
00582 }
00583
00584
00585 sprintf(str, "/Equipment/%s/Settings", equipment[0].name);
00586 if (db_find_key(hDB, 0, str, &hEqkey) != DB_SUCCESS) {
00587 cm_msg(MINFO, "tr_start", "/Equipment/%s/Settings not found", equipment[0].name);
00588 }
00589
00590
00591 size = sizeof(ebset.user_field);
00592 status = db_get_value(hDB, hEqkey, "User Field", ebset.user_field, &size, TID_STRING, TRUE);
00593
00594
00595 size = sizeof(ebset.user_build);
00596 status = db_get_value(hDB, hEqkey, "User Build", &ebset.user_build, &size, TID_BOOL, TRUE);
00597
00598
00599 size = sizeof(INT);
00600 status = db_set_value(hDB, hEqkey, "Number of Fragment", &ebset.nfragment, size, 1, TID_INT);
00601
00602
00603 status = db_find_key(hDB, hEqkey, "Fragment Required", &hEqFRkey);
00604 status = db_get_key(hDB, hEqFRkey, &key);
00605 assert(status == DB_SUCCESS);
00606
00607 if (key.num_values != ebset.nfragment) {
00608 cm_msg(MINFO, "tr_start", "Number of Fragment mismatch ODB:%d - CUR:%d", key.num_values, ebset.nfragment);
00609 free(ebset.preqfrag);
00610 size = ebset.nfragment * sizeof(BOOL);
00611 ebset.preqfrag = malloc(size);
00612 for (i = 0; i < ebset.nfragment; i++)
00613 ebset.preqfrag[i] = TRUE;
00614 status =
00615 db_set_value(hDB, hEqkey, "Fragment Required", ebset.preqfrag, size, ebset.nfragment, TID_BOOL);
00616 } else {
00617 size = key.total_size;
00618 free(ebset.preqfrag);
00619 ebset.preqfrag = malloc(size);
00620 status = db_get_data(hDB, hEqFRkey, ebset.preqfrag, &size, TID_BOOL);
00621 }
00622
00623 free(ebset.received);
00624 ebset.received = malloc(size);
00625 for (i = 0; i < ebset.nfragment; i++)
00626 ebset.received[i] = FALSE;
00627
00628
00629 for (i = 0; i < ebset.nfragment; i++)
00630 if (ebset.preqfrag[i])
00631 break;
00632
00633 if (i == ebset.nfragment) {
00634 cm_msg(MERROR, "tr_start", "Run start aborted because no fragment required");
00635 return 0;
00636 }
00637
00638
00639 status = eb_begin_of_run(run_number, ebset.user_field, error);
00640 if (status != EB_SUCCESS) {
00641 cm_msg(MERROR, "tr_start", "run start aborted due to eb_begin_of_run (%d)", status);
00642 return status;
00643 }
00644
00645
00646 status = source_booking();
00647 if (status != SUCCESS)
00648 return status;
00649
00650 if (!eq_info->enabled) {
00651 cm_msg(MINFO, "tr_start", "Event Builder disabled");
00652 return CM_SUCCESS;
00653 }
00654
00655
00656 run_state = STATE_RUNNING;
00657 run_number = rn;
00658 stop_requested = FALSE;
00659 abort_requested = FALSE;
00660 printf("%s-Starting New Run: %d\n", frontend_name, rn);
00661
00662
00663 return CM_SUCCESS;
00664 }
00665
00666
00667 INT tr_stop(INT rn, char *error)
00668 {
00669 printf("\n%s-Stopping Run: %d detected\n", frontend_name, rn);
00670
00671
00672 stop_requested = TRUE;
00673
00674
00675 request_stop_time = ss_millitime();
00676 return CM_SUCCESS;
00677 }
00678
00679
00680 void free_event_buffer(INT nfrag)
00681 {
00682 INT i;
00683 for (i = 0; i < nfrag; i++) {
00684 if (ebch[i].pfragment) {
00685 free(ebch[i].pfragment);
00686 ebch[i].pfragment = NULL;
00687 }
00688 }
00689 }
00690
00691
00692 INT handFlush()
00693 {
00694 int i, size, status;
00695 char strout[256];
00696
00697
00698 if (debug)
00699 printf("Hand flushing system buffer... \n");
00700 for (i = 0; i < nfragment; i++) {
00701 do {
00702 status = 0;
00703 if (ebset.preqfrag[i]) {
00704 size = max_event_size;
00705 status = bm_receive_event(ebch[i].hBuf, ebch[i].pfragment, &size, ASYNC);
00706 if (debug1) {
00707 sprintf(strout,
00708 "booking:Hand flush bm_receive_event[%d] hndle:%d stat:%d Last Ser:%d",
00709 i, ebch[i].hBuf, status, ((EVENT_HEADER *) ebch[i].pfragment)->serial_number);
00710 printf("%s\n", strout);
00711 }
00712 }
00713 } while (status == BM_SUCCESS);
00714 }
00715
00716
00717 status = bm_empty_buffers();
00718 if (status != BM_SUCCESS)
00719 cm_msg(MERROR, "handFlush", "bm_empty_buffers failure [%d]", status);
00720 run_state = STATE_STOPPED;
00721 return status;
00722 }
00723
00724
00725
00726 INT source_booking()
00727 {
00728 INT j, i, status, status1, status2;
00729
00730 if (debug)
00731 printf("Entering booking\n");
00732
00733 status1 = status2 = 0;
00734
00735
00736 for (i = 0; i < nfragment; i++) {
00737
00738 if (ebset.preqfrag[i]) {
00739
00740 status1 = bm_open_buffer(ebch[i].buffer, 2 * MAX_EVENT_SIZE, &(ebch[i].hBuf));
00741
00742 if (debug)
00743 printf("bm_open_buffer frag:%d buf:%s handle:%d stat:%d\n",
00744 i, ebch[i].buffer, ebch[i].hBuf, status1);
00745
00746 status2 =
00747 bm_request_event(ebch[i].hBuf, ebch[i].event_id,
00748 TRIGGER_ALL, GET_ALL, &ebch[i].req_id, NULL);
00749 if (debug)
00750 printf("bm_request_event frag:%d id:%d msk:%d req_id:%d stat:%d\n",
00751 i, ebch[i].event_id, ebch[i].trigger_mask, ebch[i].req_id, status2);
00752 if (((status1 != BM_SUCCESS) && (status1 != BM_CREATED)) ||
00753 ((status2 != BM_SUCCESS) && (status2 != BM_CREATED))) {
00754 cm_msg(MERROR, "source_booking",
00755 "Open buffer/event request failure [%d %d %d]", i, status1, status2);
00756 return BM_CONFLICT;
00757 }
00758
00759
00760 if (ebch[i].pfragment)
00761 free(ebch[i].pfragment);
00762 ebch[i].pfragment = (char *) malloc(max_event_size + sizeof(EVENT_HEADER));
00763 if (debug)
00764 printf("malloc pevent frag:%d pevent:%p\n", i, ebch[i].pfragment);
00765 if (ebch[i].pfragment == NULL) {
00766 free_event_buffer(nfragment);
00767 cm_msg(MERROR, "source_booking", "Can't allocate space for buffer");
00768 return BM_NO_MEMORY;
00769 }
00770 }
00771 }
00772
00773
00774 status = bm_empty_buffers();
00775 if (status != BM_SUCCESS) {
00776 cm_msg(MERROR, "source_booking", "bm_empty_buffers failure [%d]", status);
00777 return status;
00778 }
00779
00780 if (debug) {
00781 printf("bm_empty_buffers stat:%d\n", status);
00782 for (j = 0; j < ebset.nfragment; j++) {
00783 printf(" buff:%s", ebch[j].buffer);
00784 printf(" ser#:%d", ebch[j].serial);
00785 printf(" hbuf:%2d", ebch[j].hBuf);
00786 printf(" rqid:%2d", ebch[j].req_id);
00787 printf(" opst:%d", status1);
00788 printf(" rqst:%d", status2);
00789 printf(" evid:%2d", ebch[j].event_id);
00790 printf(" tmsk:0x%4.4x\n", ebch[j].trigger_mask);
00791 }
00792 }
00793
00794 return SUCCESS;
00795 }
00796
00797
00798 INT source_unbooking()
00799 {
00800 INT i, status;
00801
00802
00803 for (i = 0; i < nfragment; i++) {
00804
00805
00806 if (ebch[i].pfragment != NULL) {
00807 bm_empty_buffers();
00808
00809
00810 status = bm_delete_request(ebch[i].req_id);
00811 if (debug)
00812 printf("unbook: bm_delete_req[%d] req_id:%d stat:%d\n", i, ebch[i].req_id, status);
00813
00814
00815 status = bm_close_buffer(ebch[i].hBuf);
00816 if (debug)
00817 printf("unbook: bm_close_buffer[%d] hndle:%d stat:%d\n", i, ebch[i].hBuf, status);
00818 if (status != BM_SUCCESS) {
00819 cm_msg(MERROR, "source_unbooking", "Close buffer[%d] stat:", i, status);
00820 return status;
00821 }
00822 }
00823 }
00824
00825
00826 free_event_buffer(nfragment);
00827
00828 return EB_SUCCESS;
00829 }
00830
00831
00832 INT close_buffers(void)
00833 {
00834 INT status;
00835 char error[256];
00836 EQUIPMENT *eq;
00837
00838 eq = &equipment[0];
00839
00840
00841 bm_flush_cache(equipment[0].buffer_handle, SYNC);
00842
00843 eb_end_of_run(run_number, error);
00844
00845 handFlush();
00846
00847 status = source_unbooking();
00848
00849
00850 stop_time = ss_millitime() - request_stop_time;
00851 sprintf(error, "Run %d Stop after %1.0lf events sent DT:%d[ms]",
00852 run_number, eq->stats.events_sent, stop_time);
00853 cm_msg(MINFO, "close_buffers", "%s", error);
00854
00855 run_state = STATE_STOPPED;
00856 abort_requested = FALSE;
00857 return status;
00858 }
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881 INT source_scan(INT fmt, EQUIPMENT_INFO * eq_info)
00882 {
00883 static DWORD serial;
00884 DWORD *plrl;
00885 BOOL complete;
00886 INT i, status, size;
00887 INT act_size;
00888 BOOL found, event_mismatch;
00889 BANK_HEADER *psbh;
00890
00891 status = 0;
00892
00893
00894 for (i = 0; i < nfragment; i++) {
00895
00896 if (ebset.preqfrag[i] && !ebset.received[i]) {
00897
00898 size = max_event_size;
00899 status = bm_receive_event(ebch[i].hBuf, ebch[i].pfragment, &size, ASYNC);
00900 switch (status) {
00901 case BM_SUCCESS:
00902
00903 ebset.received[i] = TRUE;
00904
00905 ebch[i].serial = ((EVENT_HEADER *) ebch[i].pfragment)->serial_number;
00906
00907
00908 switch (fmt) {
00909 case FORMAT_YBOS:
00910 plrl = (DWORD *) (((EVENT_HEADER *) ebch[i].pfragment) + 1);
00911 ybos_event_swap(plrl);
00912 break;
00913 case FORMAT_MIDAS:
00914 psbh = (BANK_HEADER *) (((EVENT_HEADER *) ebch[i].pfragment) + 1);
00915 bk_swap(psbh, FALSE);
00916 break;
00917 }
00918
00919 if (debug1) {
00920 printf("SUCC: ch:%d ser:%d rec:%d sz:%d\n", i, ebch[i].serial, ebset.received[i], size);
00921 }
00922 break;
00923 case BM_ASYNC_RETURN:
00924 ebch[i].timeout++;
00925 if (debug1) {
00926 printf("ASYNC: ch:%d ser:%d rec:%d sz:%d\n", i, ebch[i].serial, ebset.received[i], size);
00927 }
00928 break;
00929 default:
00930 cm_msg(MERROR, "source_scan", "bm_receive_event error %d", status);
00931 return status;
00932 break;
00933 }
00934 }
00935 }
00936
00937
00938 complete = FALSE;
00939 for (i = 0; i < nfragment; i++) {
00940 if (ebset.preqfrag[i] && !ebset.received[i])
00941 break;
00942 }
00943 if (i == nfragment) {
00944 complete = TRUE;
00945
00946 found = event_mismatch = FALSE;
00947 serial = 0;
00948
00949 for (i = 0; i < nfragment; i++) {
00950 if (ebset.preqfrag[i] && ebset.received[i] && !found) {
00951 serial = ebch[i].serial;
00952 found = TRUE;
00953 } else {
00954 if (ebset.preqfrag[i] && ebset.received[i] && (serial != ebch[i].serial)) {
00955
00956 event_mismatch = TRUE;
00957 }
00958 }
00959 }
00960
00961
00962 if (event_mismatch && debug) {
00963 char str[256];
00964 char strsub[128];
00965 strcpy(str, "event mismatch: ");
00966 for (i = 0; i < nfragment; i++) {
00967 sprintf(strsub, "Ser[%d]:%d ", i, ebch[i].serial);
00968 strcat(str, strsub);
00969 }
00970 printf("event serial mismatch %s\n", str);
00971 }
00972
00973
00974 memset(dest_event, 0, sizeof(EVENT_HEADER));
00975 act_size = 0;
00976
00977
00978
00979 bm_compose_event((EVENT_HEADER *) dest_event, eq_info->event_id, eq_info->trigger_mask,
00980 act_size, serial);
00981
00982
00983 status =
00984 eb_user(nfragment, event_mismatch, ebch, (EVENT_HEADER *) dest_event,
00985 (void *) ((EVENT_HEADER *) dest_event + 1), &act_size);
00986 if (status != EB_SUCCESS) {
00987 if (status == EB_SKIP) {
00988
00989 for (i = 0; i < nfragment; i++) {
00990 ebch[i].timeout = 0;
00991 ebset.received[i] = FALSE;
00992 }
00993 }
00994 return status;
00995 }
00996
00997
00998 if (!ebset.user_build) {
00999 for (i = 0; i < nfragment; i++) {
01000 if (ebset.preqfrag[i]) {
01001 status = meb_fragment_add(dest_event, ebch[i].pfragment, &act_size);
01002 if (status != EB_SUCCESS) {
01003 cm_msg(MERROR, "source_scan",
01004 "compose fragment:%d current size:%d (%d)", i, act_size, status);
01005 return EB_ERROR;
01006 }
01007 }
01008 }
01009 }
01010
01011
01012 act_size = ((EVENT_HEADER *) dest_event)->data_size + sizeof(EVENT_HEADER);
01013
01014
01015 status = rpc_send_event(equipment[0].buffer_handle, dest_event, act_size, SYNC);
01016 if (status != BM_SUCCESS) {
01017 if (debug)
01018 printf("rpc_send_event returned error %d, event_size %d\n", status, act_size);
01019 cm_msg(MERROR, "source_scan", "%s: rpc_send_event returned error %d", frontend_name, status);
01020 return EB_ERROR;
01021 }
01022
01023
01024 equipment[0].bytes_sent += act_size;
01025
01026
01027 equipment[0].events_sent++;
01028
01029
01030 for (i = 0; i < nfragment; i++) {
01031 ebch[i].timeout = 0;
01032 ebset.received[i] = FALSE;
01033 }
01034 }
01035
01036 return status;
01037 }
01038
01039
01040 int main(int argc, char **argv)
01041 {
01042 INT status, size, rstate;
01043 int i;
01044 BOOL daemon = FALSE;
01045 HNDLE hEqkey;
01046 EBUILDER(ebuilder_str);
01047 char str[128];
01048
01049
01050 memset(&ebch[0], 0, sizeof(ebch));
01051
01052
01053 cm_get_environment(host_name, sizeof(host_name), expt_name, sizeof(expt_name));
01054
01055
01056 strcpy(buffer_name, "SYSTEM");
01057
01058
01059 for (i = 1; i < argc; i++) {
01060 if (argv[i][0] == '-' && argv[i][1] == 'd')
01061 debug = TRUE;
01062 else if (argv[i][0] == '-' && argv[i][1] == 'D')
01063 daemon = TRUE;
01064 else if (argv[i][0] == '-' && argv[i][1] == 'w')
01065 wheel = TRUE;
01066 else if (argv[i][0] == '-') {
01067 if (i + 1 >= argc || argv[i + 1][0] == '-')
01068 goto usage;
01069 if (strncmp(argv[i], "-e", 2) == 0)
01070 strcpy(expt_name, argv[++i]);
01071 else if (strncmp(argv[i], "-h", 2) == 0)
01072 strcpy(host_name, argv[++i]);
01073 else if (strncmp(argv[i], "-b", 2) == 0)
01074 strcpy(buffer_name, argv[++i]);
01075 } else {
01076 usage:
01077 printf("usage: mevb [-h <Hostname>] [-e <Experiment>] [-b <buffername>] [-d] [-w] [-D]\n");
01078 printf(" [-h <Hostname>] Host where midas experiment is running on\n");
01079 printf(" [-e <Experiment>] Midas experiment if more than one exists\n");
01080 printf(" [-b <buffername>] Specify evnet buffer name, use \"SYSTEM\" by default\n");
01081 printf(" [-d] Print debugging output\n");
01082 printf(" [-w] Show wheel\n");
01083 printf(" [-D] Start as a daemon\n");
01084 return 0;
01085 }
01086 }
01087
01088
01089 strcpy(str, svn_revision+12);
01090 if (strchr(str, ' '))
01091 *strchr(str, ' ') = 0;
01092 printf("Program mevb, revision %s from ", str);
01093 strcpy(str, svn_revision+17);
01094 if (strchr(str, ' '))
01095 *strchr(str, ' ') = 0;
01096 printf("%s. Press \"!\" to exit.\n", str);
01097
01098 if (daemon) {
01099 printf("Becoming a daemon...\n");
01100 ss_daemon_init(FALSE);
01101 }
01102
01103
01104 status = cm_connect_experiment(host_name, expt_name, frontend_name, NULL);
01105 if (status != CM_SUCCESS) {
01106 ss_sleep(5000);
01107 goto exit;
01108 }
01109
01110 if (debug)
01111 cm_set_watchdog_params(TRUE, 0);
01112
01113
01114 status = cm_get_experiment_database(&hDB, &hKey);
01115 if (status != EB_SUCCESS) {
01116 ss_sleep(5000);
01117 goto exit;
01118 }
01119
01120
01121 status = cm_exist(frontend_name, FALSE);
01122 if (status == CM_SUCCESS) {
01123 cm_msg(MERROR, "main", "%s running already!.", frontend_name);
01124 cm_disconnect_experiment();
01125 goto exit;
01126 }
01127
01128
01129 size = sizeof(rstate);
01130 db_get_value(hDB, 0, "/Runinfo/State", &rstate, &size, TID_INT, FALSE);
01131 if (rstate != STATE_STOPPED) {
01132 cm_msg(MERROR, "main", "Run in Progress, EBuilder aborted!.");
01133 cm_disconnect_experiment();
01134 goto exit;
01135 }
01136
01137 if (ebuilder_init() != SUCCESS) {
01138 cm_disconnect_experiment();
01139
01140 ss_sleep(5000);
01141 goto exit;
01142 }
01143
01144
01145 status = register_equipment();
01146 if (status != EB_SUCCESS) {
01147 ss_sleep(5000);
01148 goto exit;
01149 }
01150
01151
01152 status = load_fragment();
01153 if (status != EB_SUCCESS) {
01154 ss_sleep(5000);
01155 goto exit;
01156 }
01157
01158
01159 if (cm_register_transition(TR_START, tr_start, 400) != CM_SUCCESS)
01160 return status;
01161 if (cm_register_transition(TR_STOP, tr_stop, 600) != CM_SUCCESS)
01162 goto exit;
01163
01164
01165 sprintf(str, "/Equipment/%s/Settings", equipment[0].name);
01166 if (db_find_key(hDB, 0, str, &hEqkey) != DB_SUCCESS) {
01167 status = db_create_record(hDB, 0, str, strcomb(ebuilder_str));
01168 }
01169
01170
01171 ss_getchar(0);
01172
01173
01174 status = scan_fragment();
01175 printf("%s-Out of scan_fragment\n", frontend_name);
01176
01177
01178 printf("%s-Unbooking\n", frontend_name);
01179 source_unbooking();
01180
01181 ebuilder_exit();
01182
01183
01184 ss_getchar(TRUE);
01185
01186 exit:
01187
01188 free_event_buffer(ebset.nfragment);
01189
01190
01191 cm_disconnect_experiment();
01192 return 0;
01193 }