00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207 #include <stdio.h>
00208 #include <assert.h>
00209 #include "midas.h"
00210 #include "msystem.h"
00211 #include "mcstd.h"
00212
00213 #ifdef YBOS_SUPPORT
00214 #include "ybos.h"
00215 #endif
00216
00217
00218
00219
00220
00221
00222 extern char *frontend_name;
00223
00224 extern char *frontend_file_name;
00225
00226 extern BOOL frontend_call_loop;
00227
00228 extern INT max_event_size;
00229
00230 extern INT max_event_size_frag;
00231
00232 extern INT event_buffer_size;
00233
00234 extern INT display_period;
00235
00236 extern INT frontend_init(void);
00237
00238 extern INT frontend_exit(void);
00239
00240 extern INT frontend_loop(void);
00241
00242 extern INT begin_of_run(INT run_number, char *error);
00243
00244 extern INT end_of_run(INT run_number, char *error);
00245
00246 extern INT pause_run(INT run_number, char *error);
00247
00248 extern INT resume_run(INT run_number, char *error);
00249
00250 extern INT poll_event(INT source, INT count, BOOL test);
00251
00252 extern INT interrupt_configure(INT cmd, INT source, PTYPE adr);
00253
00254
00255
00256
00257
00258
00259 #undef USE_EVENT_CHANNEL
00260
00261 #define SERVER_CACHE_SIZE 100000
00262
00263 #define ODB_UPDATE_TIME 1000
00264
00265 #define DEFAULT_FE_TIMEOUT 60000
00266
00267 INT run_state;
00268
00269 INT run_number;
00270
00271 DWORD actual_time;
00272
00273 DWORD actual_millitime;
00274
00275
00276 char host_name[HOST_NAME_LENGTH];
00277
00278 char exp_name[NAME_LENGTH];
00279
00280
00281 INT max_bytes_per_sec;
00282
00283 INT optimize = 0;
00284
00285 INT fe_stop = 0;
00286
00287 BOOL debug;
00288
00289 DWORD auto_restart = 0;
00290
00291
00292 HNDLE hDB;
00293
00294
00295 #ifdef YBOS_SUPPORT
00296 struct {
00297
00298 DWORD ybos_type;
00299
00300 DWORD odb_type;
00301
00302 INT tsize;
00303
00304 } id_map[] = {
00305
00306 {
00307 A1_BKTYPE, TID_CHAR, 1},
00308 {
00309 I1_BKTYPE, TID_BYTE, 1},
00310 {
00311 I2_BKTYPE, TID_WORD, 2},
00312 {
00313 I4_BKTYPE, TID_DWORD, 4},
00314 {
00315 F4_BKTYPE, TID_FLOAT, 4},
00316 {
00317 D8_BKTYPE, TID_DOUBLE, 8},
00318 {
00319 0, 0}
00320 };
00321
00322
00323 #endif
00324
00325
00326 extern EQUIPMENT equipment[];
00327
00328
00329 EQUIPMENT * interrupt_eq = NULL;
00330
00331 EVENT_HEADER * interrupt_odb_buffer;
00332
00333 BOOL interrupt_odb_buffer_valid;
00334
00335
00336 int send_event(INT index);
00337
00338 void send_all_periodic_events(INT transition);
00339
00340 void interrupt_routine(void);
00341
00342 void interrupt_enable(BOOL flag);
00343
00344 void display(BOOL bInit);
00345
00346
00347
00348
00349 #define EQUIPMENT_COMMON_STR "\
00350 Event ID = WORD: 0 \ n \
00351 Trigger mask = WORD: 0 \ n \
00352 Buffer = STRING: [32] SYSTEM \ n \
00353 Type = INT: 0 \ n \
00354 Source = INT: 0 \ n \
00355 Format = STRING: [8] FIXED \ n \
00356 Enabled = BOOL: 0 \ n \
00357 Read on = INT: 0 \ n \
00358 Period = INT: 0 \ n \
00359 Event limit = DOUBLE: 0 \ n \
00360 Num subevents = DWORD: 0 \ n \
00361 Log history = INT: 0 \ n \
00362 Frontend host = STRING: [32] \ n \
00363 Frontend name = STRING: [32] \ n \
00364 Frontend file name = STRING: [256] \ n \
00365 "
00366
00367 #define EQUIPMENT_STATISTICS_STR " \
00368 Events sent = DOUBLE: 0 \ n \
00369 Events per sec. = DOUBLE: 0 \ n \
00370 kBytes per sec. = DOUBLE:0 \ n \
00371 "
00372
00373 /*-- transition callbacks ------------------------------------------*/
00374
00375 /*-- start ---------------------------------------------------------*/
00376
00377 INT tr_start(INT rn, char *error)
00378 {
00379 INT i, status;
00380
00381 /* reset serial numbers */
00382 for (i=0 ; equipment[i].name[0] ; i++)
00383 {
00384 equipment[i].serial_number = 1;
00385 equipment[i].subevent_number = 0;
00386 equipment[i].stats.events_sent = 0;
00387 equipment[i].odb_in = equipment[i].odb_out = 0;
00388 }
00389
00390 status = begin_of_run(rn, error);
00391
00392 if (status == CM_SUCCESS)
00393 {
00394 run_state = STATE_RUNNING;
00395 run_number = rn;
00396
00397 send_all_periodic_events(TR_START);
00398
00399 if (display_period)
00400 {
00401 ss_printf(14, 2, " Running ");
00402 ss_printf(36, 2, " % d ", rn);
00403 }
00404
00405 /* enable interrupts */
00406 interrupt_enable(TRUE);
00407 }
00408
00409 return status;
00410 }
00411
00412 /*-- prestop -------------------------------------------------------*/
00413
00414 INT tr_prestop(INT rn, char *error)
00415 {
00416 INT status, i;
00417
00418 /* disable interrupts */
00419 interrupt_enable(FALSE);
00420
00421 status = end_of_run(rn, error);
00422
00423 if (status == CM_SUCCESS)
00424 {
00425 /* don't send events if already stopped */
00426 if (run_state != STATE_STOPPED)
00427 send_all_periodic_events(TR_STOP);
00428
00429 run_state = STATE_STOPPED;
00430 run_number = rn;
00431
00432 if (display_period)
00433 ss_printf(14, 2, " Stopped ");
00434 }
00435 else
00436 interrupt_enable(TRUE);
00437
00438 /* flush remaining buffered events */
00439 rpc_flush_event();
00440 for (i=0 ; equipment[i].name[0] ; i++)
00441 if (equipment[i].buffer_handle)
00442 {
00443 INT err = bm_flush_cache(equipment[i].buffer_handle, SYNC);
00444 if (err != BM_SUCCESS)
00445 {
00446 cm_msg(MERROR," tr_prestop "," bm_flush_cache(SYNC) error % d ",err);
00447 return err;
00448 }
00449 }
00450
00451 return status;
00452 }
00453
00454 /*-- pause ---------------------------------------------------------*/
00455
00456 INT tr_prepause(INT rn, char *error)
00457 {
00458 INT status;
00459
00460 /* disable interrupts */
00461 interrupt_enable(FALSE);
00462
00463 status = pause_run(rn, error);
00464
00465 if (status == CM_SUCCESS)
00466 {
00467 run_state = STATE_PAUSED;
00468 run_number = rn;
00469
00470 send_all_periodic_events(TR_PAUSE);
00471
00472 if (display_period)
00473 ss_printf(14, 2, " Paused ");
00474 }
00475 else
00476 interrupt_enable(TRUE);
00477
00478 return status;
00479 }
00480
00481 /*-- resume --------------------------------------------------------*/
00482
00483 INT tr_resume(INT rn, char *error)
00484 {
00485 INT status;
00486
00487 status = resume_run(rn, error);
00488
00489 if (status == CM_SUCCESS)
00490 {
00491 run_state = STATE_RUNNING;
00492 run_number = rn;
00493
00494 send_all_periodic_events(TR_RESUME);
00495
00496 if (display_period)
00497 ss_printf(14, 2, " Running ");
00498
00499 /* enable interrupts */
00500 interrupt_enable(TRUE);
00501 }
00502
00503 return status;
00504 }
00505
00506 /*------------------------------------------------------------------*/
00507
00508 INT manual_trigger(INT index, void *prpc_param[])
00509 {
00510 WORD event_id, i;
00511
00512 event_id = CWORD(0);
00513
00514 for (i=0 ; equipment[i].name[0] ; i++)
00515 if (equipment[i].info.event_id == event_id)
00516 send_event(i);
00517
00518 if (display_period)
00519 display(FALSE);
00520
00521 return SUCCESS;
00522 }
00523
00524 /*------------------------------------------------------------------*/
00525
00526 INT register_equipment(void)
00527 {
00528 INT index, count, size, status, i, j, k, n;
00529 char str[256];
00530 EQUIPMENT_INFO *eq_info;
00531 EQUIPMENT_STATS *eq_stats;
00532 DWORD start_time, delta_time;
00533 HNDLE hKey;
00534 BOOL manual_trig_flag = FALSE;
00535 BANK_LIST *bank_list;
00536 DWORD dummy;
00537
00538 /* get current ODB run state */
00539 size = sizeof(run_state);
00540 run_state = STATE_STOPPED;
00541 db_get_value(hDB, 0, " / Runinfo / State ", &run_state, &size, TID_INT, TRUE);
00542 size = sizeof(run_number);
00543 run_number = 1;
00544 status = db_get_value(hDB, 0, " / Runinfo /
00545 Run number ", &run_number, &size, TID_INT, TRUE);
00546 assert(status == SUCCESS);
00547
00548 /* scan EQUIPMENT table from FRONTEND.C */
00549 for (index=0 ; equipment[index].name[0] ; index++)
00550 {
00551 eq_info = &equipment[index].info;
00552 eq_stats = &equipment[index].stats;
00553
00554 if (eq_info->event_id == 0)
00555 {
00556 printf(" Event ID 0 for %s
00557 not allowed \ n ", equipment[index].name);
00558 ss_sleep(5000);
00559 }
00560
00561 /* init status */
00562 equipment[index].status = FE_SUCCESS;
00563
00564 sprintf(str, " / Equipment / %s / Common ", equipment[index].name);
00565
00566 /* get last event limit from ODB */
00567 if (eq_info->eq_type != EQ_SLOW)
00568 {
00569 db_find_key(hDB, 0, str, &hKey);
00570 size = sizeof(double);
00571 if (hKey)
00572 db_get_value(hDB, hKey, " Event limit ", &eq_info->event_limit, &size, TID_DOUBLE, TRUE);
00573 }
00574
00575 /* Create common subtree */
00576 status = db_check_record(hDB, 0, str, EQUIPMENT_COMMON_STR, TRUE);
00577 if (status != DB_SUCCESS)
00578 {
00579 printf(" Cannot check equipment record, status = %d \ n ", status);
00580 ss_sleep(3000);
00581 }
00582 db_find_key(hDB, 0, str, &hKey);
00583
00584 if (equal_ustring(eq_info->format, " YBOS "))
00585 equipment[index].format = FORMAT_YBOS;
00586 else if (equal_ustring(eq_info->format, " FIXED "))
00587 equipment[index].format = FORMAT_FIXED;
00588 else /* default format is MIDAS */
00589 equipment[index].format = FORMAT_MIDAS;
00590
00591 gethostname(eq_info->frontend_host, sizeof(eq_info->frontend_host));
00592 strcpy(eq_info->frontend_name, frontend_name);
00593 strcpy(eq_info->frontend_file_name, frontend_file_name);
00594
00595 /* set record from equipment[] table in frontend.c */
00596 db_set_record(hDB, hKey, eq_info, sizeof(EQUIPMENT_INFO), 0);
00597
00598 /* open hot link to equipment info */
00599 db_open_record(hDB, hKey, eq_info, sizeof(EQUIPMENT_INFO), MODE_READ, NULL, NULL);
00600
00601 /*---- Create variables record ---------------------------------*/
00602 sprintf(str, " / Equipment / %s / Variables ", equipment[index].name);
00603 if (equipment[index].event_descrip)
00604 {
00605 if (equipment[index].format == FORMAT_FIXED)
00606 db_check_record(hDB, 0, str, (char *)equipment[index].event_descrip, TRUE);
00607 else
00608 {
00609 /* create bank descriptions */
00610 bank_list = (BANK_LIST *)equipment[index].event_descrip;
00611
00612 for (; bank_list->name[0] ; bank_list++)
00613 {
00614 /* mabye needed later...
00615 if (bank_list->output_flag == 0)
00616 continue;
00617 */
00618
00619 if (bank_list->type == TID_STRUCT)
00620 {
00621 sprintf(str, " / Equipment / %s / Variables / %s ", equipment[index].name, bank_list->name);
00622 status = db_check_record(hDB, 0, str, strcomb(bank_list->init_str), TRUE);
00623 if (status != DB_SUCCESS)
00624 {
00625 printf(" Cannot check / create record \ "%s\", status = %d\n", str, status);
00626
00627 ss_sleep(3000);
00628
00629 }
00630
00631 }
00632
00633
00634 else
00635
00636 {
00637
00638 sprintf(str, "/Equipment/%s/Variables/%s", equipment[index].name,
00639 bank_list->name);
00640
00641 dummy = 0;
00642
00643 db_set_value(hDB, 0, str, &dummy, rpc_tid_size(bank_list->type), 1,
00644 bank_list->type);
00645
00646 }
00647
00648 }
00649
00650 }
00651
00652 }
00653
00654
00655 else
00656
00657 db_create_key(hDB, 0, str, TID_KEY);
00658
00659
00660 sprintf(str, "/Equipment/%s/Variables", equipment[index].name);
00661
00662 db_find_key(hDB, 0, str, &hKey);
00663
00664 equipment[index].hkey_variables = hKey;
00665
00666
00667
00668 sprintf(str, "/Equipment/%s/Statistics", equipment[index].name);
00669
00670
00671 status = db_check_record(hDB, 0, str, EQUIPMENT_STATISTICS_STR, TRUE);
00672
00673 if (status != DB_SUCCESS)
00674
00675 {
00676
00677 printf("Cannot create/check statistics record, error %d\n", status);
00678
00679 ss_sleep(3000);
00680
00681 }
00682
00683
00684 status = db_find_key(hDB, 0, str, &hKey);
00685
00686 if (status != DB_SUCCESS)
00687
00688 {
00689
00690 printf("Cannot find statistics record, error %d\n", status);
00691
00692 ss_sleep(3000);
00693
00694 }
00695
00696
00697 eq_stats->events_sent = 0;
00698
00699 eq_stats->events_per_sec = 0;
00700
00701 eq_stats->kbytes_per_sec = 0;
00702
00703
00704
00705 status =
00706 db_open_record(hDB, hKey, eq_stats, sizeof(EQUIPMENT_STATS),
00707 MODE_WRITE, NULL, NULL);
00708
00709 if (status != DB_SUCCESS)
00710
00711 {
00712
00713 printf
00714 ("Cannot open statistics record, error %d. Probably other FE is using it\n",
00715 status);
00716
00717 ss_sleep(3000);
00718
00719 }
00720
00721
00722
00723 if (eq_info->buffer[0])
00724
00725 {
00726
00727 status =
00728 bm_open_buffer(eq_info->buffer, EVENT_BUFFER_SIZE,
00729 &equipment[index].buffer_handle);
00730
00731 if (status != BM_SUCCESS && status != BM_CREATED)
00732
00733 {
00734
00735 cm_msg(MERROR, "register_equipment",
00736
00737 "Cannot open event buffer. Try to reduce EVENT_BUFFER_SIZE in midas.h \
00738 and rebuild the system.");
00739
00740 return 0;
00741
00742 }
00743
00744
00745
00746 bm_set_cache_size(equipment[index].buffer_handle, 0,
00747 SERVER_CACHE_SIZE);
00748
00749 }
00750
00751 else
00752
00753 equipment[index].buffer_handle = 0;
00754
00755
00756
00757 if (eq_info->eq_type & EQ_POLLED)
00758
00759 {
00760
00761 if (display_period)
00762
00763 printf("\nCalibrating");
00764
00765
00766 count = 1;
00767
00768 do
00769
00770 {
00771
00772 if (display_period)
00773
00774 printf(".");
00775
00776
00777 start_time = ss_millitime();
00778
00779
00780 poll_event(equipment[index].info.source, count, TRUE);
00781
00782
00783 delta_time = ss_millitime() - start_time;
00784
00785
00786 if (delta_time > 0)
00787
00788 count = (INT) ((double) count * 100 / delta_time);
00789
00790 else
00791
00792 count *= 100;
00793
00794 } while (delta_time > 120 || delta_time < 80);
00795
00796
00797 equipment[index].poll_count =
00798 (INT) ((double) eq_info->period / 100 * count);
00799
00800
00801 if (display_period)
00802
00803 printf("OK\n");
00804
00805 }
00806
00807
00808
00809 if (eq_info->eq_type & EQ_INTERRUPT)
00810
00811 {
00812
00813
00814
00815 for (i = 0; equipment[i].name[0]; i++)
00816
00817 if (equipment[i].info.eq_type & EQ_POLLED)
00818
00819 {
00820
00821 equipment[index].status = FE_ERR_DISABLED;
00822
00823 cm_msg(MINFO, "register_equipment",
00824
00825 "Interrupt readout cannot be combined with polled readout");
00826
00827 }
00828
00829
00830 if (equipment[index].status != FE_ERR_DISABLED)
00831
00832 {
00833
00834 if (eq_info->enabled)
00835
00836 {
00837
00838 if (interrupt_eq)
00839
00840 {
00841
00842 equipment[index].status = FE_ERR_DISABLED;
00843
00844 cm_msg(MINFO, "register_equipment",
00845
00846 "Defined more than one equipment with interrupt readout");
00847
00848 }
00849
00850 else
00851
00852 {
00853
00854 interrupt_configure(CMD_INTERRUPT_ATTACH,
00855 eq_info->source, (PTYPE) interrupt_routine);
00856
00857 interrupt_eq = &equipment[index];
00858
00859 interrupt_odb_buffer =
00860 (EVENT_HEADER *) malloc(MAX_EVENT_SIZE + sizeof(EVENT_HEADER));
00861
00862 }
00863
00864 }
00865
00866 else
00867
00868 {
00869
00870 equipment[index].status = FE_ERR_DISABLED;
00871
00872 cm_msg(MINFO, "register_equipment",
00873 "Equipment %s disabled in file \"frontend.c\"",
00874
00875 equipment[index].name);
00876
00877 }
00878
00879 }
00880
00881 }
00882
00883
00884
00885 if (eq_info->eq_type & EQ_SLOW)
00886
00887 {
00888
00889
00890 for (i = 0; equipment[index].driver[i].name[0]; i++)
00891
00892 for (j = i + 1; equipment[index].driver[j].name[0]; j++)
00893
00894 if (equal_ustring
00895 (equipment[index].driver[i].name,
00896
00897 equipment[index].driver[j].name))
00898
00899 {
00900
00901 strcpy(str, equipment[index].driver[i].name);
00902
00903 for (k = 0, n = 0; equipment[index].driver[k].name[0]; k++)
00904
00905 if (equal_ustring(str, equipment[index].driver[k].name))
00906
00907 sprintf(equipment[index].driver[k].name, "%s_%d", str, n++);
00908
00909
00910 break;
00911
00912 }
00913
00914
00915
00916 if (eq_info->enabled)
00917
00918 equipment[index].status =
00919 equipment[index].cd(CMD_INIT, &equipment[index]);
00920
00921 else
00922
00923 {
00924
00925 equipment[index].status = FE_ERR_DISABLED;
00926
00927 cm_msg(MINFO, "register_equipment",
00928 "Equipment %s disabled in file \"frontend.c\"",
00929
00930 equipment[index].name);
00931
00932 }
00933
00934
00935
00936 if (equipment[index].status != FE_SUCCESS)
00937
00938 ss_sleep(3000);
00939
00940 }
00941
00942
00943
00944 if (eq_info->eq_type & EQ_MANUAL_TRIG)
00945
00946 {
00947
00948 if (!manual_trig_flag)
00949
00950 cm_register_function(RPC_MANUAL_TRIG, manual_trigger);
00951
00952
00953 manual_trig_flag = TRUE;
00954
00955 }
00956
00957 }
00958
00959
00960
00961 return SUCCESS;
00962
00963 }
00964
00965
00966
00967
00968
00969 void update_odb(EVENT_HEADER * pevent, HNDLE hKey, INT format)
00970 {
00971
00972 INT size, i, ni4, tsize, status, n_data;
00973
00974 void *pdata;
00975
00976 char name[5];
00977
00978 BANK_HEADER * pbh;
00979
00980 BANK * pbk;
00981
00982 BANK32 * pbk32;
00983
00984 void *pydata;
00985
00986 DWORD odb_type;
00987
00988 DWORD * pyevt, bkname;
00989
00990 WORD bktype;
00991
00992 HNDLE hKeyRoot, hKeyl;
00993
00994 KEY key;
00995
00996
00997
00998
00999
01000 if (format == FORMAT_FIXED)
01001
01002 {
01003
01004 if (db_set_record
01005 (hDB, hKey, (char *) (pevent + 1),
01006 pevent->data_size,
01007 0) != DB_SUCCESS)
01008
01009 cm_msg(MERROR, "update_odb", "event #%d size mismatch",
01010 pevent->event_id);
01011
01012 }
01013
01014 else if (format == FORMAT_MIDAS)
01015
01016 {
01017
01018 pbh = (BANK_HEADER *) (pevent + 1);
01019
01020 pbk = NULL;
01021
01022 pbk32 = NULL;
01023
01024 do
01025
01026 {
01027
01028
01029 if (bk_is32(pbh))
01030
01031 {
01032
01033 size = bk_iterate32(pbh, &pbk32, &pdata);
01034
01035 if (pbk32 == NULL)
01036
01037 break;
01038
01039 bkname = *((DWORD *) pbk32->name);
01040
01041 bktype = (WORD) pbk32->type;
01042
01043 }
01044
01045 else
01046
01047 {
01048
01049 size = bk_iterate(pbh, &pbk, &pdata);
01050
01051 if (pbk == NULL)
01052
01053 break;
01054
01055 bkname = *((DWORD *) pbk->name);
01056
01057 bktype = (WORD) pbk->type;
01058
01059 }
01060
01061
01062 n_data = size;
01063
01064 if (rpc_tid_size(bktype & 0xFF))
01065
01066 n_data /= rpc_tid_size(bktype & 0xFF);
01067
01068
01069
01070 *((DWORD *) name) = bkname;
01071
01072 name[4] = 0;
01073
01074
01075 if (bktype == TID_STRUCT)
01076
01077 {
01078
01079 status = db_find_key(hDB, hKey, name, &hKeyRoot);
01080
01081 if (status != DB_SUCCESS)
01082
01083 {
01084
01085 cm_msg(MERROR, "update_odb",
01086 "please define bank %s in BANK_LIST in frontend.c",
01087 name);
01088
01089 continue;
01090
01091 }
01092
01093
01094
01095 for (i = 0;; i++)
01096
01097 {
01098
01099 char *temp;
01100
01101 status = db_enum_key(hDB, hKeyRoot, i, &hKeyl);
01102
01103 if (status == DB_NO_MORE_SUBKEYS)
01104
01105 break;
01106
01107
01108 db_get_key(hDB, hKeyl, &key);
01109
01110
01111
01112 if (key.type != TID_STRING && key.type != TID_LINK)
01113
01114 pdata =
01115 (void *) VALIGN(pdata,
01116 min(ss_get_struct_align(), key.item_size));
01117
01118
01119 status =
01120 db_set_data(hDB, hKeyl, pdata,
01121 key.item_size * key.num_values,
01122
01123 key.num_values, key.type);
01124
01125 if (status != DB_SUCCESS)
01126
01127 {
01128
01129 cm_msg(MERROR, "update_odb", "cannot write %s to ODB", name);
01130
01131 continue;
01132
01133 }
01134
01135
01136
01137
01138 temp = (char *) pdata;
01139 temp += key.item_size * key.num_values;
01140
01141 pdata = (void *) temp;
01142
01143 }
01144 }
01145
01146 else
01147
01148 {
01149
01150
01151 if (n_data > 0)
01152
01153 db_set_value(hDB, hKey, name, pdata, size,
01154 n_data, bktype & 0xFF);
01155
01156 }
01157
01158
01159 } while (1);
01160
01161 }
01162
01163 else if (format == FORMAT_YBOS)
01164
01165 {
01166
01167 #ifdef YBOS_SUPPORT
01168 YBOS_BANK_HEADER * pybkh;
01169
01170
01171
01172 pyevt = (DWORD *) (pevent + 1);
01173
01174 pybkh = NULL;
01175
01176 do
01177
01178 {
01179
01180
01181 ni4 = ybk_iterate(pyevt, &pybkh, &pydata);
01182
01183 if (pybkh == NULL || ni4 == 0)
01184
01185 break;
01186
01187
01188
01189 tsize = odb_type = 0;
01190
01191 for (i = 0; id_map[0].ybos_type > 0; i++)
01192
01193 {
01194
01195 if (pybkh->type == id_map[i].ybos_type)
01196
01197 {
01198
01199 odb_type = id_map[i].odb_type;
01200
01201 tsize = id_map[i].tsize;
01202
01203 break;
01204
01205 }
01206
01207 }
01208
01209
01210
01211 *((DWORD *) name) = pybkh->name;
01212
01213 name[4] = 0;
01214
01215
01216
01217 if (strncmp(name, "EVID", 4) == 0)
01218
01219 continue;
01220
01221
01222
01223 if (pybkh->type == D8_BKTYPE)
01224
01225 ni4 /= 2;
01226
01227 if (pybkh->type == I2_BKTYPE)
01228
01229 ni4 *= 2;
01230
01231 if (pybkh->type == I1_BKTYPE || pybkh->type == A1_BKTYPE)
01232
01233 ni4 *= 4;
01234
01235
01236
01237 size = ni4 * tsize;
01238
01239 if ((status =
01240 db_set_value(hDB, hKey, name, pydata, size, ni4,
01241 odb_type & 0xFF)) != DB_SUCCESS)
01242
01243 {
01244
01245 float *ftemp;
01246
01247 printf
01248 ("status:%i odb_type:%li name:%s ni4:%i size:%i tsize:%i\n",
01249
01250 status, odb_type, name, ni4, size, tsize);
01251
01252 ftemp = (float *) pydata;
01253 for (i = 0; i < 6; i++)
01254
01255 printf("data: %f\n", *ftemp++);
01256
01257 }
01258
01259 } while (1);
01260
01261 #endif
01262 }
01263
01264
01265 rpc_set_option(-1, RPC_OTRANSPORT, RPC_TCP);
01266
01267 }
01268
01269
01270
01271
01272
01273 int send_event(INT index)
01274 {
01275
01276 EQUIPMENT_INFO * eq_info;
01277
01278 EVENT_HEADER * pevent, *pfragment;
01279
01280 char *pdata;
01281
01282 unsigned char *pd;
01283
01284 INT i, status;
01285
01286 DWORD sent, size;
01287
01288 static void *frag_buffer = NULL;
01289
01290
01291 eq_info = &equipment[index].info;
01292
01293
01294
01295 if (eq_info->eq_type & EQ_FRAGMENTED)
01296
01297 {
01298
01299 if (frag_buffer == NULL)
01300
01301 frag_buffer = malloc(max_event_size_frag);
01302
01303
01304 if (frag_buffer == NULL)
01305
01306 {
01307
01308 cm_msg(MERROR, "send_event",
01309 "Not enough memory to allocate buffer for fragmented events");
01310
01311 return SS_NO_MEMORY;
01312
01313 }
01314
01315
01316 pevent = (EVENT_HEADER *) frag_buffer;
01317
01318 }
01319
01320 else
01321
01322 {
01323
01324
01325 pevent = dm_pointer_get();
01326
01327 if (pevent == NULL)
01328
01329 {
01330
01331 cm_msg(MERROR, "send_event",
01332 "dm_pointer_get not returning valid pointer");
01333
01334 return SS_NO_MEMORY;
01335
01336 }
01337
01338 }
01339
01340
01341
01342 pevent->event_id = eq_info->event_id;
01343
01344 pevent->trigger_mask = eq_info->trigger_mask;
01345
01346 pevent->data_size = 0;
01347
01348 pevent->time_stamp = ss_time();
01349
01350 pevent->serial_number = equipment[index].serial_number++;
01351
01352
01353 equipment[index].last_called = ss_millitime();
01354
01355
01356
01357 *((EQUIPMENT **) (pevent + 1)) = &equipment[index];
01358
01359 pevent->data_size = equipment[index].readout((char *) (pevent + 1), 0);
01360
01361
01362
01363 if (pevent->data_size)
01364
01365 {
01366
01367 if (eq_info->eq_type & EQ_FRAGMENTED)
01368
01369 {
01370
01371
01372 if (pevent->data_size + sizeof(EVENT_HEADER) >
01373 (DWORD) max_event_size_frag)
01374
01375 {
01376
01377 cm_msg(MERROR, "send_event",
01378 "Event size %ld larger than maximum size %d for frag. ev.",
01379
01380 (long) (pevent->data_size +
01381 sizeof(EVENT_HEADER)), max_event_size_frag);
01382
01383 return SS_NO_MEMORY;
01384
01385 }
01386
01387
01388
01389 pfragment = dm_pointer_get();
01390
01391 if (pfragment == NULL)
01392
01393 {
01394
01395 cm_msg(MERROR, "send_event",
01396 "dm_pointer_get not returning valid pointer");
01397
01398 return SS_NO_MEMORY;
01399
01400 }
01401
01402
01403
01404 memcpy(pfragment, pevent, sizeof(EVENT_HEADER));
01405
01406 pfragment->event_id |= EVENTID_FRAG1;
01407
01408
01409
01410 pd = (unsigned char *) (pfragment + 1);
01411 size = pevent->data_size;
01412
01413 for (i = 0; i < 4; i++)
01414
01415 {
01416
01417 pd[i] = (unsigned char) (size & 0xFF);
01418
01419 size >>= 8;
01420
01421 }
01422
01423 pfragment->data_size = sizeof(DWORD);
01424
01425
01426 pdata = (char *) (pevent + 1);
01427
01428
01429 for (i = 0, sent = 0; sent < pevent->data_size; i++)
01430
01431 {
01432
01433 if (i > 0)
01434
01435 {
01436
01437 pfragment = dm_pointer_get();
01438
01439
01440
01441 memcpy(pfragment, pevent, sizeof(EVENT_HEADER));
01442
01443 pfragment->event_id |= EVENTID_FRAG;
01444
01445
01446
01447 size = pevent->data_size - sent;
01448
01449 if (size > max_event_size - sizeof(EVENT_HEADER))
01450
01451 size = max_event_size - sizeof(EVENT_HEADER);
01452
01453
01454 memcpy(pfragment + 1, pdata, size);
01455
01456 pfragment->data_size = size;
01457
01458 sent += size;
01459
01460 pdata += size;
01461
01462 }
01463
01464
01465
01466 if (equipment[index].buffer_handle)
01467
01468 {
01469
01470 #ifdef USE_EVENT_CHANNEL
01471 dm_pointer_increment(equipment[index].
01472 buffer_handle,
01473
01474 pfragment->
01475 data_size + sizeof(EVENT_HEADER));
01476
01477 #else
01478
01479 rpc_flush_event();
01480
01481 status =
01482 bm_send_event(equipment[index].
01483 buffer_handle, pfragment,
01484
01485 pfragment->data_size +
01486 sizeof(EVENT_HEADER), SYNC);
01487
01488 if (status != BM_SUCCESS)
01489
01490 {
01491
01492 cm_msg(MERROR, "send_event",
01493 "bm_send_event(SYNC) error %d", status);
01494
01495 return status;
01496
01497 }
01498
01499 #endif
01500
01501 }
01502
01503 }
01504
01505
01506 if (equipment[index].buffer_handle) {
01507
01508 #ifndef USE_EVENT_CHANNEL
01509 status = bm_flush_cache(equipment[index].buffer_handle, SYNC);
01510
01511 if (status != BM_SUCCESS)
01512
01513 {
01514
01515 cm_msg(MERROR, "send_event",
01516 "bm_flush_cache(SYNC) error %d", status);
01517
01518 return status;
01519
01520 }
01521
01522 #endif
01523
01524 }
01525
01526 }
01527
01528 else
01529
01530 {
01531
01532
01533
01534 if (pevent->data_size + sizeof(EVENT_HEADER) >
01535 (DWORD) max_event_size)
01536
01537 {
01538
01539 cm_msg(MERROR, "send_event",
01540 "Event size %ld larger than maximum size %d",
01541
01542 (long) (pevent->data_size +
01543 sizeof(EVENT_HEADER)), max_event_size);
01544
01545 return SS_NO_MEMORY;
01546
01547 }
01548
01549
01550
01551 if (equipment[index].buffer_handle)
01552
01553 {
01554
01555 #ifdef USE_EVENT_CHANNEL
01556 dm_pointer_increment(equipment[index].
01557 buffer_handle,
01558
01559 pevent->data_size +
01560 sizeof(EVENT_HEADER));
01561
01562 #else
01563
01564 rpc_flush_event();
01565
01566 status =
01567 bm_send_event(equipment[index].buffer_handle,
01568 pevent,
01569
01570 pevent->data_size + sizeof(EVENT_HEADER), SYNC);
01571
01572 if (status != BM_SUCCESS)
01573
01574 {
01575
01576 cm_msg(MERROR, "send_event",
01577 "bm_send_event(SYNC) error %d", status);
01578
01579 return status;
01580
01581 }
01582
01583 status = bm_flush_cache(equipment[index].buffer_handle, SYNC);
01584
01585 if (status != BM_SUCCESS)
01586
01587 {
01588
01589 cm_msg(MERROR, "send_event",
01590 "bm_flush_cache(SYNC) error %d", status);
01591
01592 return status;
01593
01594 }
01595
01596 #endif
01597
01598 }
01599
01600
01601
01602
01603 if ((eq_info->read_on & RO_ODB) ||
01604 (eq_info->history > 0 && (eq_info->eq_type & ~EQ_SLOW)))
01605
01606 {
01607
01608 update_odb(pevent,
01609 equipment[index].hkey_variables,
01610 equipment[index].format);
01611
01612 equipment[index].odb_out++;
01613
01614 }
01615
01616 }
01617
01618
01619 equipment[index].bytes_sent +=
01620 pevent->data_size + sizeof(EVENT_HEADER);
01621
01622 equipment[index].events_sent++;
01623
01624
01625 equipment[index].stats.events_sent += equipment[index].events_sent;
01626
01627 equipment[index].events_sent = 0;
01628
01629 }
01630
01631 else
01632
01633 equipment[index].serial_number--;
01634
01635
01636
01637 #ifdef USE_EVENT_CHANNEL
01638 if ((status = dm_area_flush()) != CM_SUCCESS)
01639
01640 cm_msg(MERROR, "send_event", "dm_area_flush: %i", status);
01641
01642 #endif
01643
01644
01645 for (i = 0; equipment[i].name[0]; i++)
01646
01647 if (equipment[i].buffer_handle)
01648
01649 {
01650
01651 status = bm_flush_cache(equipment[i].buffer_handle, SYNC);
01652
01653 if (status != BM_SUCCESS)
01654
01655 {
01656
01657 cm_msg(MERROR, "send_event",
01658 "bm_flush_cache(SYNC) error %d", status);
01659
01660 return status;
01661
01662 }
01663
01664 }
01665
01666
01667 return CM_SUCCESS;
01668
01669 }
01670
01671
01672
01673
01674
01675 void send_all_periodic_events(INT transition)
01676 {
01677
01678 EQUIPMENT_INFO * eq_info;
01679
01680 INT i;
01681
01682
01683 for (i = 0; equipment[i].name[0]; i++)
01684
01685 {
01686
01687 eq_info = &equipment[i].info;
01688
01689
01690 if (!eq_info->enabled || equipment[i].status != FE_SUCCESS)
01691
01692 continue;
01693
01694
01695 if (transition == TR_START && (eq_info->read_on & RO_BOR) == 0)
01696
01697 continue;
01698
01699 if (transition == TR_STOP && (eq_info->read_on & RO_EOR) == 0)
01700
01701 continue;
01702
01703 if (transition == TR_PAUSE && (eq_info->read_on & RO_PAUSE) == 0)
01704
01705 continue;
01706
01707 if (transition == TR_RESUME && (eq_info->read_on & RO_RESUME) == 0)
01708
01709 continue;
01710
01711
01712 send_event(i);
01713
01714 }
01715
01716 }
01717
01718
01719
01720
01721
01722 BOOL interrupt_enabled;
01723
01724
01725 void interrupt_enable(BOOL flag)
01726 {
01727
01728 interrupt_enabled = flag;
01729
01730
01731 if (interrupt_eq)
01732
01733 {
01734
01735 if (interrupt_enabled)
01736
01737 interrupt_configure(CMD_INTERRUPT_ENABLE, 0, 0);
01738
01739 else
01740
01741 interrupt_configure(CMD_INTERRUPT_DISABLE, 0, 0);
01742
01743 }
01744
01745 }
01746
01747
01748
01749
01750
01751 void interrupt_routine(void)
01752 {
01753
01754 EVENT_HEADER * pevent;
01755
01756
01757
01758
01759 if ((pevent = dm_pointer_get()) == NULL)
01760
01761 cm_msg(MERROR, "interrupt_routine",
01762 "interrupt, dm_pointer_get returned NULL");
01763
01764
01765
01766 pevent->event_id = interrupt_eq->info.event_id;
01767
01768 pevent->trigger_mask = interrupt_eq->info.trigger_mask;
01769
01770 pevent->data_size = 0;
01771
01772 pevent->time_stamp = actual_time;
01773
01774 pevent->serial_number = interrupt_eq->serial_number++;
01775
01776
01777
01778 pevent->data_size = interrupt_eq->readout((char *) (pevent + 1), 0);
01779
01780
01781
01782 if (pevent->data_size)
01783
01784 {
01785
01786 interrupt_eq->bytes_sent += pevent->data_size + sizeof(EVENT_HEADER);
01787
01788 interrupt_eq->events_sent++;
01789
01790
01791 if (interrupt_eq->buffer_handle)
01792
01793 {
01794
01795 #ifdef USE_EVENT_CHANNEL
01796 dm_pointer_increment(interrupt_eq->buffer_handle,
01797
01798 pevent->data_size + sizeof(EVENT_HEADER));
01799
01800 #else
01801
01802 rpc_send_event(interrupt_eq->buffer_handle, pevent,
01803
01804 pevent->data_size + sizeof(EVENT_HEADER), SYNC);
01805
01806 #endif
01807
01808 }
01809
01810
01811
01812 if (interrupt_eq->info.read_on & RO_ODB ||
01813 interrupt_eq->info.history)
01814
01815 {
01816
01817 if (actual_millitime - interrupt_eq->last_called > ODB_UPDATE_TIME)
01818
01819 {
01820
01821 interrupt_eq->last_called = actual_millitime;
01822
01823 memcpy(interrupt_odb_buffer, pevent,
01824 pevent->data_size + sizeof(EVENT_HEADER));
01825
01826 interrupt_odb_buffer_valid = TRUE;
01827
01828 interrupt_eq->odb_out++;
01829
01830 }
01831
01832 }
01833
01834 }
01835
01836 else
01837
01838 interrupt_eq->serial_number--;
01839
01840
01841 }
01842
01843
01844
01845
01846
01847 int message_print(const char *msg)
01848 {
01849
01850 char str[160];
01851
01852
01853 memset(str, ' ', 159);
01854
01855 str[159] = 0;
01856
01857
01858 if (msg[0] == '[')
01859
01860 msg = strchr(msg, ']') + 2;
01861
01862
01863 memcpy(str, msg, strlen(msg));
01864
01865 ss_printf(0, 20, str);
01866
01867
01868 return 0;
01869
01870 }
01871
01872
01873
01874 void display(BOOL bInit)
01875 {
01876
01877 INT i, status;
01878
01879 time_t full_time;
01880
01881 char str[30];
01882
01883
01884 if (bInit)
01885
01886 {
01887
01888 ss_clear_screen();
01889
01890
01891 if (host_name[0])
01892
01893 strcpy(str, host_name);
01894
01895 else
01896
01897 strcpy(str, "<local>");
01898
01899
01900 ss_printf(0, 0, "%s connected to %s. Press \"!\" to exit",
01901 frontend_name, str);
01902
01903 ss_printf(0, 1,
01904 "================================================================================");
01905
01906 ss_printf(0, 2, "Run status: %s",
01907 run_state ==
01908 STATE_STOPPED ? "Stopped" :
01909 run_state ==
01910 STATE_RUNNING ? "Running" :
01911 "Paused");
01912
01913 ss_printf(25, 2, "Run number %d ", run_number);
01914
01915 ss_printf(0, 3,
01916 "================================================================================");
01917
01918 ss_printf(0, 4,
01919 "Equipment Status Events Events/sec Rate[kB/s] ODB->FE FE->ODB");
01920
01921 ss_printf(0, 5,
01922 "--------------------------------------------------------------------------------");
01923
01924 for (i = 0; equipment[i].name[0]; i++)
01925
01926 ss_printf(0, i + 6, "%s", equipment[i].name);
01927
01928 }
01929
01930
01931
01932 time(&full_time);
01933
01934 strcpy(str, ctime(&full_time) + 11);
01935
01936 str[8] = 0;
01937
01938 ss_printf(72, 0, "%s", str);
01939
01940
01941 for (i = 0; equipment[i].name[0]; i++)
01942
01943 {
01944
01945 status = equipment[i].status;
01946
01947
01948 if ((status == 0 || status == FE_SUCCESS)
01949 &&
01950 equipment[i].info.enabled)
01951
01952 ss_printf(14, i + 6, "OK ");
01953
01954 else if (!equipment[i].info.enabled)
01955
01956 ss_printf(14, i + 6, "Disabled ");
01957
01958 else if (status == FE_ERR_ODB)
01959
01960 ss_printf(14, i + 6, "ODB Error");
01961
01962 else if (status == FE_ERR_HW)
01963
01964 ss_printf(14, i + 6, "HW Error ");
01965
01966 else if (status == FE_ERR_DISABLED)
01967
01968 ss_printf(14, i + 6, "Disabled ");
01969
01970 else
01971
01972 ss_printf(14, i + 6, "Unknown ");
01973
01974
01975 if (equipment[i].stats.events_sent > 1E9)
01976
01977 ss_printf(25, i + 6, "%1.3lfG ",
01978 equipment[i].stats.events_sent / 1E9);
01979
01980 else if (equipment[i].stats.events_sent > 1E6)
01981
01982 ss_printf(25, i + 6, "%1.3lfM ",
01983 equipment[i].stats.events_sent / 1E6);
01984
01985 else
01986
01987 ss_printf(25, i + 6, "%1.0lf ",
01988 equipment[i].stats.events_sent);
01989
01990 ss_printf(36, i + 6, "%1.1lf ",
01991 equipment[i].stats.events_per_sec);
01992
01993 ss_printf(47, i + 6, "%1.1lf ",
01994 equipment[i].stats.kbytes_per_sec);
01995
01996 ss_printf(58, i + 6, "%ld ", equipment[i].odb_in);
01997
01998 ss_printf(69, i + 6, "%ld ", equipment[i].odb_out);
01999
02000 }
02001
02002
02003
02004 ss_printf(0, i + 6, "");
02005
02006 }
02007
02008
02009
02010
02011
02012 BOOL logger_root()
02013
02014 {
02015
02016 int size, i, status;
02017
02018 char str[80];
02019
02020 HNDLE hKeyRoot, hKey;
02021
02022
02023 if (db_find_key(hDB, 0, "/Logger/Channels", &hKeyRoot) == DB_SUCCESS)
02024
02025 {
02026
02027 for (i = 0;; i++)
02028
02029 {
02030
02031 status = db_enum_key(hDB, hKeyRoot, i, &hKey);
02032
02033 if (status == DB_NO_MORE_SUBKEYS)
02034
02035 break;
02036
02037
02038 strcpy(str, "MIDAS");
02039
02040 size = sizeof(str);
02041
02042 db_get_value(hDB, hKey, "Settings/Format", str, &size,
02043 TID_STRING, TRUE);
02044
02045
02046 if (equal_ustring(str, "ROOT"))
02047
02048 return TRUE;
02049
02050 }
02051
02052 }
02053
02054
02055 return FALSE;
02056
02057 }
02058
02059
02060
02061
02062
02063 INT scheduler(void)
02064 {
02065
02066 EQUIPMENT_INFO * eq_info;
02067
02068 EQUIPMENT * eq;
02069
02070 EVENT_HEADER * pevent;
02071
02072 DWORD last_time_network = 0, last_time_display =
02073 0,
02074 last_time_flush = 0, readout_start;
02075
02076 INT i, j, index, status, ch, source, size, state;
02077
02078 char str[80];
02079
02080 BOOL buffer_done, flag, force_update = FALSE;
02081
02082
02083 INT opt_max = 0, opt_index = 0, opt_tcp_size = 128, opt_cnt = 0;
02084
02085 INT err;
02086
02087
02088 #ifdef OS_VXWORKS
02089 rpc_set_opt_tcp_size(1024);
02090
02091 #ifdef PPCxxx
02092 rpc_set_opt_tcp_size(NET_TCP_SIZE);
02093
02094 #endif
02095
02096 #endif
02097
02098
02099
02100
02101 do
02102
02103 {
02104
02105 actual_millitime = ss_millitime();
02106
02107 actual_time = ss_time();
02108
02109
02110
02111 for (index = 0;; index++)
02112
02113 {
02114
02115 eq = &equipment[index];
02116
02117 eq_info = &eq->info;
02118
02119
02120
02121 if (!eq->name[0])
02122
02123 break;
02124
02125
02126 if (!eq_info->enabled)
02127
02128 continue;
02129
02130
02131 if (eq->status != FE_SUCCESS)
02132
02133 continue;
02134
02135
02136
02137 if ((eq_info->eq_type & EQ_SLOW)
02138 &&
02139 eq->status == FE_SUCCESS)
02140
02141 {
02142
02143 if (eq_info->event_limit > 0 && run_state == STATE_RUNNING)
02144
02145 {
02146
02147 if (actual_time - eq->last_idle >= (DWORD) eq_info->event_limit)
02148
02149 {
02150
02151 eq->cd(CMD_IDLE, eq);
02152
02153 eq->last_idle = actual_time;
02154
02155 }
02156
02157 }
02158
02159 else
02160
02161 eq->cd(CMD_IDLE, eq);
02162
02163 }
02164
02165
02166 if (run_state == STATE_STOPPED
02167 && (eq_info->read_on & RO_STOPPED) == 0)
02168
02169 continue;
02170
02171 if (run_state == STATE_PAUSED
02172 && (eq_info->read_on & RO_PAUSED) == 0)
02173
02174 continue;
02175
02176 if (run_state == STATE_RUNNING
02177 && (eq_info->read_on & RO_RUNNING) == 0)
02178
02179 continue;
02180
02181
02182
02183 if ((eq_info->eq_type & EQ_PERIODIC)
02184 || (eq_info->eq_type & EQ_SLOW))
02185
02186 {
02187
02188 if (eq_info->period == 0)
02189
02190 continue;
02191
02192
02193
02194 if (actual_millitime - eq->last_called >=
02195 (DWORD) eq_info->period)
02196
02197 {
02198
02199
02200 interrupt_enable(FALSE);
02201
02202
02203
02204 status = send_event(index);
02205
02206
02207 if (status != CM_SUCCESS)
02208
02209 {
02210
02211 cm_msg(MERROR, "scheduler", "send_event error %d", status);
02212
02213 goto net_error;
02214
02215 }
02216
02217
02218
02219 interrupt_enable(TRUE);
02220
02221 }
02222
02223 }
02224
02225
02226
02227 if (eq_info->eq_type & EQ_POLLED)
02228
02229 {
02230
02231 readout_start = actual_millitime;
02232
02233 pevent = NULL;
02234
02235
02236 while ((source =
02237 poll_event(eq_info->source, eq->poll_count, FALSE)) > 0)
02238
02239 {
02240
02241 pevent = dm_pointer_get();
02242
02243 if (pevent == NULL)
02244
02245 {
02246
02247 cm_msg(MERROR, "scheduler",
02248 "polled, dm_pointer_get not returning valid pointer");
02249
02250 status = SS_NO_MEMORY;
02251
02252 goto net_error;
02253
02254 }
02255
02256
02257
02258 pevent->event_id = eq_info->event_id;
02259
02260 pevent->trigger_mask = eq_info->trigger_mask;
02261
02262 pevent->data_size = 0;
02263
02264 pevent->time_stamp = actual_time;
02265
02266 pevent->serial_number = eq->serial_number;
02267
02268
02269
02270
02271
02272 *(INT *) (pevent + 1) = source;
02273
02274
02275 if (eq->info.num_subevents)
02276
02277 {
02278
02279 eq->subevent_number = 0;
02280
02281 do
02282
02283 {
02284
02285 *(INT *) ((char *) (pevent + 1)
02286 + pevent->data_size) = source;
02287
02288
02289
02290 size =
02291 eq->readout((char *) (pevent + 1), pevent->data_size);
02292
02293 pevent->data_size += size;
02294
02295 if (size > 0)
02296
02297 {
02298
02299 if (pevent->data_size + sizeof(EVENT_HEADER) > (DWORD)
02300 max_event_size)
02301
02302 {
02303
02304 cm_msg(MERROR,
02305 "scheduler",
02306 "Event size %ld larger than maximum size %d",
02307
02308 (long)
02309 (pevent->
02310 data_size +
02311 sizeof(EVENT_HEADER)), max_event_size);
02312
02313 }
02314
02315
02316 eq->subevent_number++;
02317
02318 eq->serial_number++;
02319
02320 }
02321
02322
02323
02324 do
02325
02326 {
02327
02328 source =
02329 poll_event(eq_info->source, eq->poll_count, FALSE);
02330
02331
02332 if (source == FALSE)
02333
02334 {
02335
02336 actual_millitime = ss_millitime();
02337
02338
02339
02340 if (actual_millitime - readout_start > (DWORD)
02341 eq_info->period)
02342
02343 break;
02344
02345 }
02346
02347 } while (source == FALSE);
02348
02349
02350 } while (eq->subevent_number <
02351 eq->info.num_subevents && source);
02352
02353
02354
02355 pevent->data_size = eq->readout((char *) (pevent + 1), -1);
02356
02357 }
02358
02359 else
02360
02361 {
02362
02363
02364 pevent->data_size = eq->readout((char *) (pevent + 1), 0);
02365
02366
02367
02368 if (pevent->data_size +
02369 sizeof(EVENT_HEADER) > (DWORD) max_event_size)
02370
02371 {
02372
02373 cm_msg(MERROR, "scheduler",
02374 "Event size %ld larger than maximum size %d",
02375
02376 (long) (pevent->
02377 data_size +
02378 sizeof(EVENT_HEADER)), max_event_size);
02379
02380 }
02381
02382
02383
02384 if (pevent->data_size)
02385
02386 eq->serial_number++;
02387
02388 }
02389
02390
02391
02392 if (pevent->data_size)
02393
02394 {
02395
02396 if (eq->buffer_handle)
02397
02398 {
02399
02400
02401 if (pevent->serial_number == 1)
02402
02403 if (logger_root())
02404
02405 update_odb(pevent, eq->hkey_variables, eq->format);
02406
02407
02408 #ifdef USE_EVENT_CHANNEL
02409 dm_pointer_increment(eq->
02410 buffer_handle,
02411
02412 pevent->
02413 data_size + sizeof(EVENT_HEADER));
02414
02415 #else
02416
02417 status =
02418 rpc_send_event(eq->
02419 buffer_handle,
02420 pevent,
02421
02422 pevent->
02423 data_size + sizeof(EVENT_HEADER), SYNC);
02424
02425
02426 if (status != SUCCESS)
02427
02428 {
02429
02430 cm_msg(MERROR,
02431 "scheduler", "rpc_send_event error %d", status);
02432
02433 goto net_error;
02434
02435 }
02436
02437 #endif
02438
02439
02440 eq->bytes_sent +=
02441 pevent->data_size + sizeof(EVENT_HEADER);
02442
02443
02444 if (eq->info.num_subevents)
02445
02446 eq->events_sent += eq->subevent_number;
02447
02448 else
02449
02450 eq->events_sent++;
02451
02452 }
02453
02454 }
02455
02456
02457 actual_millitime = ss_millitime();
02458
02459
02460
02461 if (actual_millitime - readout_start >
02462 (DWORD) eq_info->period)
02463
02464 break;
02465
02466
02467
02468 if (eq_info->event_limit > 0
02469 &&
02470 eq->stats.events_sent +
02471 eq->events_sent >= eq_info->event_limit)
02472
02473 break;
02474
02475 }
02476
02477
02478
02479 if (pevent && (eq_info->read_on & RO_ODB || eq_info->history))
02480
02481 {
02482
02483 if (actual_millitime - eq->last_called >
02484 ODB_UPDATE_TIME && pevent != NULL)
02485
02486 {
02487
02488 eq->last_called = actual_millitime;
02489
02490 update_odb(pevent, eq->hkey_variables, eq->format);
02491
02492 eq->odb_out++;
02493
02494 }
02495
02496 }
02497
02498 }
02499
02500
02501
02502 if (eq_info->eq_type & EQ_INTERRUPT)
02503
02504 {
02505
02506
02507
02508
02509 if (interrupt_odb_buffer_valid)
02510
02511 {
02512
02513 update_odb(interrupt_odb_buffer,
02514 interrupt_eq->hkey_variables,
02515 interrupt_eq->format);
02516
02517 interrupt_odb_buffer_valid = FALSE;
02518
02519 }
02520
02521
02522 }
02523
02524
02525
02526 if (eq_info->eq_type != EQ_SLOW
02527 &&
02528 eq_info->event_limit > 0
02529 &&
02530 eq->stats.events_sent + eq->events_sent >=
02531 eq_info->event_limit &&
02532 run_state == STATE_RUNNING)
02533
02534 {
02535
02536
02537 if (cm_transition
02538 (TR_STOP, 0, str, sizeof(str), SYNC, FALSE) != CM_SUCCESS)
02539
02540 cm_msg(MERROR, "scheduler", "cannot stop run: %s", str);
02541
02542
02543
02544 size = sizeof(BOOL);
02545
02546 flag = FALSE;
02547
02548 db_get_value(hDB, 0, "/Logger/Auto restart",
02549 &flag, &size, TID_BOOL, TRUE);
02550
02551
02552 if (flag)
02553
02554 auto_restart = ss_time() + 20;
02555
02556
02557
02558 force_update = TRUE;
02559
02560 }
02561
02562 }
02563
02564
02565
02566 if (frontend_call_loop)
02567
02568 {
02569
02570 status = frontend_loop();
02571
02572 if (status != CM_SUCCESS)
02573
02574 status = RPC_SHUTDOWN;
02575
02576 }
02577
02578
02579
02580 cm_check_deferred_transition();
02581
02582
02583
02584 if (force_update ||
02585 (display_period
02586 && actual_millitime - last_time_display >
02587 (DWORD) display_period) ||
02588 (!display_period
02589 && actual_millitime -
02590 last_time_display > 3000))
02591
02592 {
02593
02594 force_update = FALSE;
02595
02596
02597
02598 if (actual_millitime != last_time_display)
02599
02600 {
02601
02602 max_bytes_per_sec = 0;
02603
02604 for (i = 0; equipment[i].name[0]; i++)
02605
02606 {
02607
02608 eq = &equipment[i];
02609
02610 eq->stats.events_sent += eq->events_sent;
02611
02612 eq->stats.events_per_sec =
02613
02614 eq->events_sent /
02615 ((actual_millitime - last_time_display) / 1000.0);
02616
02617 eq->stats.kbytes_per_sec =
02618
02619 eq->bytes_sent / 1024.0 /
02620 ((actual_millitime - last_time_display) / 1000.0);
02621
02622
02623 if ((INT) eq->bytes_sent > max_bytes_per_sec)
02624
02625 max_bytes_per_sec = eq->bytes_sent;
02626
02627
02628 eq->bytes_sent = 0;
02629
02630 eq->events_sent = 0;
02631
02632 }
02633
02634
02635 max_bytes_per_sec = (DWORD)
02636 ((double) max_bytes_per_sec /
02637 ((actual_millitime - last_time_display) / 1000.0));
02638
02639
02640
02641 if (optimize)
02642
02643 {
02644
02645 opt_max = max(opt_max, (INT) max_bytes_per_sec);
02646
02647 ss_printf(0, opt_index,
02648 "%6d : %5.1lf %5.1lf",
02649 opt_tcp_size, opt_max / 1024.0,
02650
02651 max_bytes_per_sec / 1024.0);
02652
02653 if (++opt_cnt == 10)
02654
02655 {
02656
02657 opt_cnt = 0;
02658
02659 opt_max = 0;
02660
02661 opt_index++;
02662
02663 opt_tcp_size = 1 << (opt_index + 7);
02664
02665 rpc_set_opt_tcp_size(opt_tcp_size);
02666
02667 if (1 << (opt_index + 7) > 0x8000)
02668
02669 {
02670
02671 opt_index = 0;
02672
02673 opt_tcp_size = 1 << 7;
02674
02675 rpc_set_opt_tcp_size(opt_tcp_size);
02676
02677 }
02678
02679 }
02680
02681 }
02682
02683
02684 }
02685
02686
02687
02688 rpc_set_option(-1, RPC_OTRANSPORT, RPC_FTCP);
02689
02690 db_send_changed_records();
02691
02692 rpc_set_option(-1, RPC_OTRANSPORT, RPC_TCP);
02693
02694
02695 if (display_period)
02696
02697 {
02698
02699 display(FALSE);
02700
02701
02702
02703 ch = 0;
02704
02705 status = 0;
02706
02707 while (ss_kbhit())
02708
02709 {
02710
02711 ch = ss_getchar(0);
02712
02713 if (ch == -1)
02714
02715 ch = getchar();
02716
02717
02718 if (ch == '!')
02719
02720 status = RPC_SHUTDOWN;
02721
02722 }
02723
02724
02725 if (ch > 0)
02726
02727 display(TRUE);
02728
02729 if (status == RPC_SHUTDOWN)
02730
02731 break;
02732
02733 }
02734
02735
02736 last_time_display = actual_millitime;
02737
02738 }
02739
02740
02741
02742 if (actual_millitime - last_time_flush > 1000)
02743
02744 {
02745
02746 last_time_flush = actual_millitime;
02747
02748
02749
02750
02751
02752 if (max_bytes_per_sec < SERVER_CACHE_SIZE)
02753
02754 {
02755
02756 interrupt_enable(FALSE);
02757
02758
02759 #ifdef USE_EVENT_CHANNEL
02760 if ((status = dm_area_flush()) != CM_SUCCESS)
02761
02762 cm_msg(MERROR, "scheduler", "dm_area_flush: %i", status);
02763
02764 #endif
02765
02766
02767 for (i = 0; equipment[i].name[0]; i++)
02768
02769 {
02770
02771 if (equipment[i].buffer_handle)
02772
02773 {
02774
02775
02776 buffer_done = FALSE;
02777
02778 for (j = 0; j < i; j++)
02779
02780 if (equipment[i].
02781 buffer_handle == equipment[j].buffer_handle)
02782
02783 {
02784
02785 buffer_done = TRUE;
02786
02787 break;
02788
02789 }
02790
02791
02792 if (!buffer_done)
02793
02794 {
02795
02796 rpc_set_option(-1, RPC_OTRANSPORT, RPC_FTCP);
02797
02798 rpc_flush_event();
02799
02800 err = bm_flush_cache(equipment[i].buffer_handle, ASYNC);
02801
02802 if (err != BM_SUCCESS)
02803
02804 {
02805
02806 cm_msg(MERROR,
02807 "scheduler",
02808 "bm_flush_cache(ASYNC) error %d", err);
02809
02810 return err;
02811
02812 }
02813
02814 rpc_set_option(-1, RPC_OTRANSPORT, RPC_TCP);
02815
02816 }
02817
02818 }
02819
02820 }
02821
02822 interrupt_enable(TRUE);
02823
02824 }
02825
02826 }
02827
02828
02829
02830 if (auto_restart > 0 && ss_time() > auto_restart)
02831
02832 {
02833
02834
02835 size = sizeof(state);
02836
02837 status =
02838 db_get_value(hDB, 0, "Runinfo/State", &state, &size,
02839 TID_INT, TRUE);
02840
02841 if (status != DB_SUCCESS)
02842
02843 cm_msg(MERROR, "scheduler",
02844 "cannot get Runinfo/State in database");
02845
02846
02847 if (state == STATE_STOPPED)
02848
02849 {
02850
02851 auto_restart = 0;
02852
02853 size = sizeof(run_number);
02854
02855 status =
02856 db_get_value(hDB, 0, "/Runinfo/Run number",
02857 &run_number, &size, TID_INT, TRUE);
02858
02859 assert(status == SUCCESS);
02860
02861
02862 if (run_number <= 0)
02863
02864 {
02865
02866 cm_msg(MERROR, "main",
02867 "aborting on attempt to use invalid run number %d",
02868 run_number);
02869
02870 abort();
02871
02872 }
02873
02874
02875 cm_msg(MTALK, "main", "starting new run");
02876
02877 status =
02878 cm_transition(TR_START, run_number + 1, NULL, 0, SYNC, FALSE);
02879
02880 if (status != CM_SUCCESS)
02881
02882 cm_msg(MERROR, "main", "cannot restart run");
02883
02884 }
02885
02886 }
02887
02888
02889
02890 if (run_state == STATE_RUNNING && interrupt_eq == NULL)
02891
02892 {
02893
02894
02895 if (actual_millitime - last_time_network > 500)
02896
02897 {
02898
02899 status = cm_yield(0);
02900
02901 last_time_network = actual_millitime;
02902
02903 }
02904
02905 else
02906
02907 status = RPC_SUCCESS;
02908
02909 }
02910
02911 else
02912
02913
02914
02915 status = cm_yield(100);
02916
02917
02918
02919 if (fe_stop)
02920
02921 status = RPC_SHUTDOWN;
02922
02923
02924 } while (status != RPC_SHUTDOWN && status != SS_ABORT);
02925
02926
02927 net_error:
02928
02929 return status;
02930
02931 }
02932
02933
02934
02935
02936
02937 #ifdef HAVE_CAMAC
02938
02939 INT cnaf_callback(INT index, void *prpc_param[])
02940 {
02941
02942 DWORD cmd, b, c, n, a, f, *pdword, *size, *x, *q, dtemp;
02943
02944 WORD * pword, *pdata, temp;
02945
02946 INT i, count;
02947
02948
02949
02950 cmd = CDWORD(0);
02951
02952 b = CDWORD(1);
02953
02954 c = CDWORD(2);
02955
02956 n = CDWORD(3);
02957
02958 a = CDWORD(4);
02959
02960 f = CDWORD(5);
02961
02962 pdword = CPDWORD(6);
02963
02964 pword = CPWORD(6);
02965
02966 pdata = CPWORD(6);
02967
02968 size = CPDWORD(7);
02969
02970 x = CPDWORD(8);
02971
02972 q = CPDWORD(9);
02973
02974
02975
02976 if (index == RPC_CNAF16)
02977
02978 count = *size / sizeof(WORD);
02979
02980 else
02981
02982 count = *size / sizeof(DWORD);
02983
02984
02985 switch (cmd)
02986
02987 {
02988
02989
02990
02991 case CNAF_INHIBIT_SET:
02992
02993 cam_inhibit_set(c);
02994
02995 break;
02996
02997 case CNAF_INHIBIT_CLEAR:
02998
02999 cam_inhibit_clear(c);
03000
03001 break;
03002
03003 case CNAF_CRATE_CLEAR:
03004
03005 cam_crate_clear(c);
03006
03007 break;
03008
03009 case CNAF_CRATE_ZINIT:
03010
03011 cam_crate_zinit(c);
03012
03013 break;
03014
03015
03016 case CNAF_TEST:
03017
03018 break;
03019
03020
03021 case CNAF:
03022
03023 if (index == RPC_CNAF16)
03024
03025 {
03026
03027 for (i = 0; i < count; i++)
03028
03029 if (f < 16)
03030
03031 cam16i_q(c, n, a, f, pword++, (int *) x, (int *) q);
03032
03033 else if (f < 24)
03034
03035 cam16o_q(c, n, a, f, pword[i], (int *) x, (int *) q);
03036
03037 else
03038
03039 cam16i_q(c, n, a, f, &temp, (int *) x, (int *) q);
03040
03041 }
03042
03043 else
03044
03045 {
03046
03047 for (i = 0; i < count; i++)
03048
03049 if (f < 16)
03050
03051 cam24i_q(c, n, a, f, pdword++, (int *) x, (int *) q);
03052
03053 else if (f < 24)
03054
03055 cam24o_q(c, n, a, f, pdword[i], (int *) x, (int *) q);
03056
03057 else
03058
03059 cam24i_q(c, n, a, f, &dtemp, (int *) x, (int *) q);
03060
03061 }
03062
03063 break;
03064
03065
03066 case CNAF_nQ:
03067
03068 if (index == RPC_CNAF16)
03069
03070 {
03071
03072 if (f < 16)
03073
03074 cam16i_rq(c, n, a, f, (WORD **) & pdword, count);
03075
03076 }
03077
03078 else
03079
03080 {
03081
03082 if (f < 16)
03083
03084 cam24i_rq(c, n, a, f, &pdword, count);
03085
03086 }
03087
03088
03089
03090 *size = (int) pdword - (int) pdata;
03091
03092 break;
03093
03094
03095 default:
03096
03097 printf("cnaf: Unknown command 0x%X\n", (unsigned int) cmd);
03098
03099 }
03100
03101 if (debug)
03102
03103 {
03104
03105 if (index == RPC_CNAF16)
03106
03107 printf
03108 ("cmd=%d r=%d c=%d n=%d a=%d f=%d d=%X x=%d q=%d\n",
03109
03110 (int) cmd, (int) count, (int) c, (int) n, (int) a,
03111 (int) f, (int) pword[0], (int) *x, (int) *q);
03112
03113 else if (index == RPC_CNAF24)
03114
03115 printf
03116 ("cmd=%d r=%d c=%d n=%d a=%d f=%d d=%X x=%d q=%d\n",
03117
03118 (int) cmd, (int) count, (int) c, (int) n, (int) a,
03119 (int) f, (int) pdword[0], (int) *x, (int) *q);
03120
03121 }
03122
03123
03124 return RPC_SUCCESS;
03125
03126 }
03127
03128
03129
03130 #endif
03131
03132
03133
03134 #ifdef OS_VXWORKS
03135 int mfe(char *ahost_name, char *aexp_name, BOOL adebug)
03136 #else
03137
03138 int main(int argc, char *argv[])
03139 #endif
03140
03141 {
03142
03143 INT status, i, dm_size;
03144
03145 INT daemon;
03146
03147
03148 host_name[0] = 0;
03149
03150 exp_name[0] = 0;
03151
03152 debug = FALSE;
03153
03154 daemon = 0;
03155
03156
03157 setbuf(stdout, 0);
03158
03159 setbuf(stderr, 0);
03160
03161
03162 #ifdef SIGPIPE
03163 signal(SIGPIPE, SIG_IGN);
03164
03165 #endif
03166
03167
03168 #ifdef OS_VXWORKS
03169 if (ahost_name)
03170
03171 strcpy(host_name, ahost_name);
03172
03173 if (aexp_name)
03174
03175 strcpy(exp_name, aexp_name);
03176
03177 debug = adebug;
03178
03179 #else
03180
03181
03182
03183 cm_get_environment(host_name, sizeof(host_name), exp_name,
03184 sizeof(exp_name));
03185
03186
03187
03188 for (i = 1; i < argc; i++)
03189
03190 {
03191
03192 if (argv[i][0] == '-' && argv[i][1] == 'd')
03193
03194 debug = TRUE;
03195
03196 else if (argv[i][0] == '-' && argv[i][1] == 'D')
03197
03198 daemon = 1;
03199
03200 else if (argv[i][0] == '-' && argv[i][1] == 'O')
03201
03202 daemon = 2;
03203
03204 else if (argv[i][0] == '-')
03205
03206 {
03207
03208 if (i + 1 >= argc || argv[i + 1][0] == '-')
03209
03210 goto usage;
03211
03212 if (argv[i][1] == 'e')
03213
03214 strcpy(exp_name, argv[++i]);
03215
03216 else if (argv[i][1] == 'h')
03217
03218 strcpy(host_name, argv[++i]);
03219
03220 else
03221
03222 {
03223
03224 usage:
03225 printf
03226 ("usage: frontend [-h Hostname] [-e Experiment] [-d] [-D] [-O]\n");
03227
03228 printf(" [-d] Used to debug the frontend\n");
03229
03230 printf(" [-D] Become a daemon\n");
03231
03232 printf(" [-O] Become a daemon but keep stdout\n");
03233
03234 return 0;
03235
03236 }
03237 }
03238
03239 }
03240 #endif
03241
03242
03243
03244 if (event_buffer_size < 2 * max_event_size)
03245
03246 {
03247
03248 printf("event_buffer_size too small for max. event size\n");
03249
03250 ss_sleep(5000);
03251
03252 return 1;
03253
03254 }
03255
03256
03257 if (max_event_size > MAX_EVENT_SIZE)
03258
03259 {
03260
03261 printf
03262 ("Requested max_event_size (%d) exceeds max. system event size (%d)",
03263
03264 max_event_size, MAX_EVENT_SIZE);
03265
03266 ss_sleep(5000);
03267
03268 return 1;
03269
03270 }
03271
03272
03273 dm_size = event_buffer_size;
03274
03275
03276 #ifdef OS_VXWORKS
03277
03278
03279 dm_size =
03280 2 * 10 * (max_event_size + sizeof(EVENT_HEADER) + sizeof(INT));
03281
03282 if (dm_size > memFindMax())
03283
03284 {
03285
03286 cm_msg(MERROR, "mainFE", "Not enough mem space for event size");
03287
03288 return 0;
03289
03290 }
03291
03292
03293 dm_size = 0.2 * memFindMax();
03294
03295
03296
03297 dm_size /= 2;
03298
03299 #endif
03300
03301
03302
03303 #ifdef OS_MSDOS
03304 if (dm_size > 0x4000)
03305
03306 dm_size = 0x4000;
03307
03308 #endif
03309
03310
03311
03312 printf("Event buffer size : %d\n", event_buffer_size);
03313
03314 printf("Buffer allocation : 2 x %d\n", dm_size);
03315
03316 printf("System max event size : %d\n", MAX_EVENT_SIZE);
03317
03318 printf("User max event size : %d\n", max_event_size);
03319
03320 if (max_event_size_frag > 0)
03321
03322 printf("User max frag. size : %d\n", max_event_size_frag);
03323
03324 printf("# of events per buffer : %d\n\n", dm_size / max_event_size);
03325
03326
03327 if (daemon)
03328
03329 {
03330
03331 printf("\nBecoming a daemon...\n");
03332
03333 ss_daemon_init(daemon == 2);
03334
03335 }
03336
03337
03338
03339 if (display_period)
03340
03341 {
03342
03343 if (host_name[0])
03344
03345 printf("Connect to experiment %s on host %s...",
03346 exp_name, host_name);
03347
03348 else
03349
03350 printf("Connect to experiment %s...", exp_name);
03351
03352 }
03353
03354
03355 status =
03356 cm_connect_experiment1(host_name, exp_name, frontend_name,
03357 NULL,
03358 DEFAULT_ODB_SIZE, DEFAULT_FE_TIMEOUT);
03359
03360 if (status != CM_SUCCESS)
03361
03362 {
03363
03364
03365 ss_sleep(5000);
03366
03367 return 1;
03368
03369 }
03370
03371
03372 if (display_period)
03373
03374 printf("OK\n");
03375
03376
03377
03378 status = dm_buffer_create(dm_size, max_event_size);
03379
03380 if (status != CM_SUCCESS)
03381
03382 {
03383
03384 printf("dm_buffer_create: Not enough memory or event too big\n");
03385
03386 return 1;
03387
03388 }
03389
03390
03391
03392 cm_cleanup(frontend_name, FALSE);
03393
03394
03395
03396 status = cm_shutdown(frontend_name, FALSE);
03397
03398 if (status == CM_SUCCESS && display_period)
03399
03400 {
03401
03402 printf("Previous frontend stopped\n");
03403
03404
03405
03406 ss_sleep(3000);
03407
03408 }
03409
03410
03411
03412 if (cm_register_transition(TR_START, tr_start) != CM_SUCCESS
03413 ||
03414 cm_register_transition(TR_PRESTOP,
03415 tr_prestop) != CM_SUCCESS
03416 ||
03417 cm_register_transition(TR_PREPAUSE,
03418 tr_prepause) != CM_SUCCESS
03419 ||
03420 cm_register_transition(TR_RESUME, tr_resume) != CM_SUCCESS)
03421
03422 {
03423
03424 printf("Failed to start local RPC server");
03425
03426 cm_disconnect_experiment();
03427
03428 dm_buffer_release();
03429
03430
03431
03432 ss_sleep(5000);
03433
03434 return 1;
03435
03436 }
03437
03438
03439 #ifdef HAVE_CAMAC
03440
03441
03442 cm_register_function(RPC_CNAF16, cnaf_callback);
03443
03444 cm_register_function(RPC_CNAF24, cnaf_callback);
03445
03446
03447 #endif
03448
03449
03450 cm_get_experiment_database(&hDB, &status);
03451
03452
03453
03454 #ifdef OS_VXWORKS
03455 cm_synchronize(NULL);
03456
03457 #endif
03458
03459
03460
03461 if (debug)
03462
03463 cm_set_watchdog_params(TRUE, 0);
03464
03465
03466
03467 rpc_set_option(-1, RPC_OTIMEOUT, 120000);
03468
03469
03470
03471 if (display_period)
03472
03473 cm_set_msg_print(MT_ALL, MT_ALL, message_print);
03474
03475
03476
03477 if (display_period)
03478
03479 printf("Init hardware...");
03480
03481 if (frontend_init() != SUCCESS)
03482
03483 {
03484
03485 if (display_period)
03486
03487 printf("\n");
03488
03489 cm_disconnect_experiment();
03490
03491 dm_buffer_release();
03492
03493
03494
03495 ss_sleep(5000);
03496
03497 return 1;
03498
03499 }
03500
03501
03502
03503 if (register_equipment() != SUCCESS)
03504
03505 {
03506
03507 if (display_period)
03508
03509 printf("\n");
03510
03511 cm_disconnect_experiment();
03512
03513 dm_buffer_release();
03514
03515
03516
03517 ss_sleep(5000);
03518
03519 return 1;
03520
03521 }
03522
03523
03524 if (display_period)
03525
03526 printf("OK\n");
03527
03528
03529
03530 if (display_period)
03531
03532 {
03533
03534 ss_sleep(1000);
03535
03536 display(TRUE);
03537
03538 }
03539
03540
03541
03542 if (interrupt_eq && run_state == STATE_RUNNING)
03543
03544 interrupt_enable(TRUE);
03545
03546
03547
03548 ss_getchar(0);
03549
03550
03551
03552 status = scheduler();
03553
03554
03555
03556 ss_getchar(TRUE);
03557
03558
03559
03560 if (interrupt_eq)
03561
03562 {
03563
03564 interrupt_configure(CMD_INTERRUPT_DISABLE, 0, 0);
03565
03566 interrupt_configure(CMD_INTERRUPT_DETACH, 0, 0);
03567
03568 if (interrupt_odb_buffer)
03569
03570 free(interrupt_odb_buffer);
03571
03572 }
03573
03574
03575
03576 if (interrupt_eq != NULL)
03577
03578 interrupt_configure(CMD_INTERRUPT_DETACH,
03579 interrupt_eq->info.source, 0);
03580
03581
03582
03583 frontend_exit();
03584
03585
03586
03587 for (i = 0; equipment[i].name[0]; i++)
03588
03589 if ((equipment[i].info.eq_type & EQ_SLOW)
03590 &&
03591 equipment[i].status == FE_SUCCESS)
03592
03593 equipment[i].cd(CMD_EXIT, &equipment[i]);
03594
03595
03596
03597 cm_disconnect_experiment();
03598
03599
03600 if (display_period)
03601
03602 {
03603
03604 if (status == RPC_SHUTDOWN)
03605
03606 {
03607
03608 ss_clear_screen();
03609
03610 ss_printf(0, 0, "Frontend shut down.");
03611
03612 ss_printf(0, 1, "");
03613
03614 }
03615
03616 }
03617
03618
03619 if (status != RPC_SHUTDOWN)
03620
03621 printf("Network connection aborted.\n");
03622
03623
03624 dm_buffer_release();
03625
03626
03627 return 0;
03628
03629 }
03630
03631