Line data Source code
1 : //# nreal.cc: this defines VLA nearly realtime routines for read VLA data
2 : //# Copyright (C) 1997,1999,2000
3 : //# Associated Universities, Inc. Washington DC, USA.
4 : //#
5 : //# This library is free software; you can redistribute it and/or modify it
6 : //# under the terms of the GNU Library General Public License as published by
7 : //# the Free Software Foundation; either version 2 of the License, or (at your
8 : //# option) any later version.
9 : //#
10 : //# This library is distributed in the hope that it will be useful, but WITHOUT
11 : //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 : //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
13 : //# License for more details.
14 : //#
15 : //# You should have received a copy of the GNU Library General Public License
16 : //# along with this library; if not, write to the Free Software Foundation,
17 : //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
18 : //#
19 : //# Correspondence concerning AIPS++ should be addressed as follows:
20 : //# Internet email: casa-feedback@nrao.edu.
21 : //# Postal address: AIPS++ Project Office
22 : //# National Radio Astronomy Observatory
23 : //# 520 Edgemont Road
24 : //# Charlottesville, VA 22903-2475 USA
25 : //#
26 : //# $Id: nreal.cc,v 19.1.34.5 2006/02/17 23:46:40 wyoung Exp $
27 :
28 : //# Includes
29 :
30 : /*
31 : _olroutines - Routines for fetching data from the current VLA disk file
32 :
33 : _olopen - opens the on online status record
34 : _olread - returns a data from the shared memory
35 : _olclose - close out the online status record
36 :
37 : Dec 1992 Modified by George Martin to remove timeout while waiting for data
38 :
39 : Dec 1992 Switched to _ol for AIPS compatibility
40 :
41 : Feb 1993 Added changes made by Wes Young and a little other cleanup
42 :
43 : Jun 1993 Changed "sleep()" to sleep1() for fractions of a second
44 :
45 : Mar 1994 Begin changes to get rid of "slots", add printing of
46 : internet addresses instead of slot numbers
47 :
48 : Sep 1994 Changed routines to wait only when last_record == last_record
49 : avoids alot of hanging problems. Also olopen_ forks aoc_clnt
50 : if it's aips. Probably don't want this for miranda.
51 :
52 :
53 : This is some real yucky code I wrote a long time ago but as it more or less
54 : works, I'm reluctant to change it too much
55 : */
56 :
57 : #include <signal.h>
58 : #include <stdio.h>
59 : #include <stdlib.h>
60 : #include <string.h>
61 : #include <time.h>
62 : #include <sys/types.h>
63 : #include <sys/stat.h>
64 : #include <unistd.h>
65 : #include <errno.h>
66 : #include <arpa/inet.h>
67 :
68 : #include <nrao/VLA/nreal.h>
69 : #include <iostream>
70 :
71 :
72 : /*int MAX_TIME = 60; */
73 : int QUIT = 0;
74 : int ONLINE = 0;
75 : #define LEAP_SECONDS 33
76 :
77 : static int Last_Record;
78 :
79 : void ThatsAllFolks(int);
80 : void sleep1(double);
81 :
82 : static FILE *fpVisData = 0;
83 : static FILE *timeData = 0;
84 : static FILE *hostLog = 0;
85 : static char logDataFile[131];
86 : // int fdVisData;
87 : static long lastMJAD = 0;
88 : static long lastTick = 0;
89 : static long MJAD = 0;
90 : static off_t lastOffset;
91 : static int oldDay =0;
92 : static int previousDay = 0;
93 : static char *tomorrowsFile = 0;
94 :
95 : static const char *visDataDir = "/home/vis-serv-mirror/vladata/";
96 :
97 0 : char *getTodaysFile(char *dataDir, char *aDate, int relDay){
98 0 : int LeapSeconds = LEAP_SECONDS;
99 : time_t curTime, holdTime; /* time vars */
100 : struct tm *tmTime; /* time structure */
101 0 : if(!aDate)
102 0 : aDate = (char *)calloc(1, 81);
103 0 : curTime = time(&holdTime) + LeapSeconds + relDay*86400;
104 0 : tmTime = gmtime(&curTime);
105 0 : sprintf(aDate, "%s/vla%04d-%02d-%02d.dat",dataDir, tmTime->tm_year+1900,
106 0 : tmTime->tm_mon+1, tmTime->tm_mday);
107 0 : return(aDate);
108 : }
109 :
110 0 : char *getVisDir(){
111 0 : char *dataDir = 0;
112 0 : dataDir = getenv("VISDATADIR");
113 0 : if(!dataDir){
114 0 : dataDir = strdup(visDataDir);
115 : }
116 0 : return(dataDir);
117 : }
118 :
119 0 : int whatsToday(){
120 0 : time_t LeapSeconds = LEAP_SECONDS;
121 : time_t curTime, holdTime; /* time vars */
122 : struct tm *tmTime; /* time structure */
123 0 : curTime = time(&holdTime) + LeapSeconds;
124 0 : tmTime = gmtime(&curTime);
125 0 : return tmTime->tm_yday;
126 : }
127 :
128 0 : int oladvf_(int* /*unit_no*/, int *files){
129 0 : char *visDataFile = 0;
130 0 : int rstatus = 0;
131 :
132 0 : if(!*files)
133 0 : rewind(fpVisData);
134 0 : else if(*files < 0){
135 : /* Reset the file name to the previous days data */
136 :
137 0 : if(fpVisData)
138 0 : fclose(fpVisData);
139 0 : visDataFile = getTodaysFile(getVisDir(), visDataFile, *files);
140 0 : fpVisData = fopen(visDataFile, "r");
141 0 : ONLINE = 1;
142 0 : previousDay = *files;
143 0 : oldDay += *files;
144 0 : if(fpVisData == NULL){
145 0 : rstatus = -1;
146 0 : printf("Unable to open file %s, sorry\n", visDataFile);
147 0 : printf("Historical data is not kept on-line very long, please try to get it from"
148 : " the VLA archive.\n");
149 : }
150 : } else {
151 0 : rstatus = fseeko(fpVisData, 0, SEEK_END);
152 : }
153 0 : return rstatus;
154 : }
155 0 : int olseek(off_t offset){
156 0 : int r_status = 0;
157 0 : if(fpVisData != NULL){
158 0 : if(offset < 0){
159 0 : r_status = fseeko(fpVisData, 0, SEEK_END);
160 : }else {
161 0 : r_status = fseeko(fpVisData, offset, SEEK_SET);
162 : }
163 : }
164 0 : return r_status;
165 : }
166 16 : void attachFile(const char *filename)
167 : {
168 16 : fpVisData = fopen(filename, "r");
169 16 : ONLINE=false;
170 16 : QUIT=false;
171 : //std::cerr << "Attaching to " << filename << std::endl;
172 16 : }
173 16 : void detachFile(){
174 16 : fclose(fpVisData);
175 16 : fpVisData = 0;
176 16 : }
177 0 : int olopen_(int *unit_no, char *filename, int /*charCount*/)
178 : {
179 0 : char *visDataFile = 0;
180 : char iAm[81];
181 0 : signal(SIGINT, ThatsAllFolks);
182 0 : signal(SIGUSR1, ThatsAllFolks);
183 0 : signal(SIGUSR2, ThatsAllFolks);
184 0 : signal(SIGTERM, ThatsAllFolks);
185 0 : signal(SIGHUP, ThatsAllFolks);
186 0 : if(!strcasecmp(filename, "online")){
187 0 : ONLINE = 1;
188 0 : tomorrowsFile = getTodaysFile(getVisDir(), tomorrowsFile, 1);
189 0 : visDataFile = getTodaysFile(getVisDir(), visDataFile, 0);
190 0 : timeData = fopen("/home/vis-serv-mirror/vladata/lastdata", "r");
191 0 : if(timeData){
192 : #ifdef __APPLE__
193 : fscanf(timeData, "%ld %ld %lld", &lastMJAD, &lastTick, &lastOffset);
194 : #else
195 0 : fscanf(timeData, "%ld %ld %zd", &lastMJAD, &lastTick, &lastOffset);
196 : #endif
197 0 : MJAD = lastMJAD;
198 : }
199 0 : gethostname(iAm, 81);
200 0 : sprintf(logDataFile, "%s/connected/%s.%ld", visDataDir, iAm,
201 0 : static_cast<long>(getpid()));
202 0 : hostLog = fopen(logDataFile, "w");
203 :
204 : }else{
205 0 : visDataFile = filename;
206 0 : ONLINE = 0;
207 0 : if(fpVisData)
208 0 : fclose(fpVisData);
209 : }
210 : // printf ("Data file is %s\n", visDataFile);
211 0 : oldDay = whatsToday();
212 :
213 :
214 0 : if (*unit_no == -99){ /* called by aips */
215 0 : *unit_no = -1;
216 0 : } else if (*unit_no == 99) { /* non aips call */
217 0 : *unit_no = 1;
218 : } else { /* illegal call */
219 0 : *unit_no = 0;
220 0 : return (*unit_no);
221 : }
222 0 : fpVisData = fopen(visDataFile, "r");
223 0 : if(fpVisData){
224 0 : if(ONLINE){
225 0 : if(lastOffset > 0){
226 0 : fseeko(fpVisData, lastOffset, SEEK_SET);
227 : }else{
228 0 : fseeko(fpVisData, 0, SEEK_END);
229 0 : printf("On-line disk opened");
230 : }
231 : }
232 : } else {
233 : // fdVisData = fileno(fpVisData);
234 0 : *unit_no = 0;
235 0 : printf("ERROR: On-line disk opened FAILED!");
236 : }
237 :
238 : /*free(tmTime);*/
239 : /*free(visDataFile);*/
240 :
241 0 : return(*unit_no);
242 : }
243 : /*
244 : Function to terminate Data stream
245 : */
246 0 : void ThatsAllFolks(int /*theSignal*/){
247 0 : QUIT = 1;
248 0 : return;
249 : }
250 0 : void reattachCurrent(){
251 0 : char *visDataFile = 0;
252 0 : if(previousDay < 0) previousDay++;
253 0 : else if(previousDay > 0) previousDay--;
254 0 : visDataFile = getTodaysFile(getVisDir(), visDataFile, previousDay);
255 0 : if(fpVisData)
256 0 : fclose(fpVisData);
257 0 : fpVisData = fopen(visDataFile, "r");
258 0 : while(fpVisData == NULL){
259 0 : sleep1(5.0);
260 0 : visDataFile = getTodaysFile(getVisDir(), visDataFile, previousDay);
261 0 : fpVisData = fopen(visDataFile, "r");
262 : }
263 0 : free(visDataFile);
264 0 : }
265 :
266 31631 : int diskread_(int */*unit_no*/, char *buffer)
267 : {
268 :
269 : static int FirstRecord = 1;
270 : static int NumPhysRecords;
271 : static int PhysRecord;
272 : static int LastSize;
273 :
274 : long LRSize;
275 31631 : int RecordSize = PHYS_RECORD_SIZE;
276 : struct stat;
277 : int curDay;
278 31631 : size_t itemsGot = 0;
279 : static int feedback = 0;
280 :
281 : /*
282 : Ok here we go, first see if we have to reopen the current data file.
283 :
284 : Need to make sure we're at the end of the file.
285 : */
286 :
287 31631 : Last_Record++;
288 : /*free(tmTime);*/
289 31631 : if(timeData){
290 0 : rewind(timeData);
291 : #ifdef __APPLE__
292 : fscanf(timeData, "%ld %ld %lld", &MJAD, &lastTick, &lastOffset);
293 : #else
294 0 : fscanf(timeData, "%ld %ld %zd", &MJAD, &lastTick, &lastOffset);
295 : #endif
296 : }
297 31631 : if(hostLog){
298 0 : rewind(hostLog);
299 : #ifdef __APPLE__
300 : fprintf(hostLog, "%ld %ld %lld\n", MJAD, lastTick, lastOffset);
301 : #else
302 0 : fprintf(hostLog, "%ld %ld %zd\n", MJAD, lastTick, lastOffset);
303 : #endif
304 : }
305 : /* Now we check that we're at the end of file and try again after a bit */
306 : /* Double check there is enough data to read */
307 : /* Get the visibility data from the file */
308 31631 : if(FirstRecord){
309 20585 : if(feedback)
310 0 : printf("Fetching 0\n");
311 20585 : PhysRecord = 0;
312 20585 : itemsGot = fread(buffer, 2048, 1, fpVisData);
313 : // printf("itemsGot %d %d item size = 2048\n", itemsGot, ftell(fpVisData));
314 20585 : if(!itemsGot || feof(fpVisData) || ferror(fpVisData)){
315 16 : clearerr(fpVisData);
316 16 : if(!ONLINE){
317 16 : QUIT=1;
318 16 : FirstRecord = 1;
319 : } else{
320 0 : if(!feedback)
321 0 : printf("Fetching 1\n");
322 : // feedback = 1;
323 : }
324 16 : while(ONLINE && !QUIT){
325 0 : itemsGot = fread(buffer, 2048, 1, fpVisData);
326 0 : if(itemsGot){
327 0 : break;
328 : }
329 : /* If it is the next day and eof close out and reattach */
330 0 : if(feof(fpVisData)){
331 0 : curDay = whatsToday();
332 0 : if(oldDay != curDay){
333 0 : reattachCurrent();
334 0 : if(feedback)
335 0 : printf(".Next File found\n");
336 : // feedback = 0;
337 0 : oldDay +=1;
338 : }
339 0 : clearerr(fpVisData);
340 : }
341 0 : sleep1(10.0); /* should decode integration time and use it */
342 : }
343 : }
344 20585 : if(QUIT){
345 16 : FirstRecord = 1;
346 16 : return(0);
347 : }
348 20569 : memcpy((void *)&LRSize, buffer+sizeof(TapeHeader), sizeof(LRSize));
349 20569 : LRSize = 2*ntohl(LRSize);
350 : // printf ("LRSize %d\n", LRSize);
351 20569 : NumPhysRecords = LRSize/(PHYS_RECORD_SIZE-4);
352 20569 : if(LRSize%(PHYS_RECORD_SIZE-4)){
353 20569 : NumPhysRecords += 1;
354 20569 : LastSize = 2048*((LRSize%(PHYS_RECORD_SIZE-4))/2048);
355 20569 : if((LRSize%(PHYS_RECORD_SIZE-4))%2048)
356 20569 : LastSize += 2048; /* Ignore the Tape header */
357 : } else {
358 0 : LastSize = PHYS_RECORD_SIZE-4;
359 : }
360 20569 : FirstRecord = 0;
361 : }
362 31615 : if(feedback)
363 0 : printf(".\n");
364 31615 : PhysRecord++;
365 : // std::cout << "PhysRecord, NumPhysRecords : " << PhysRecord << ", " << NumPhysRecords << std::endl;
366 : // std::cout << "RecordSize : " << RecordSize << std::endl;
367 31615 : if(PhysRecord == NumPhysRecords){
368 20569 : RecordSize = LastSize;
369 20569 : FirstRecord = 1;
370 20569 : if(feedback)
371 0 : printf("Fetched\n");
372 : }
373 31615 : if(PhysRecord == 1){
374 20569 : if (RecordSize > 2048) {
375 : // finish getting this record
376 20569 : itemsGot = fread(buffer+2048, RecordSize-2048, 1, fpVisData);
377 : // std::cout << "A: itemsGot : " << itemsGot << " item size = " << (RecordSize-2048) << " feof(fpVisData) : " << feof(fpVisData) << " ferror(fpVisData) " << ferror(fpVisData) << std::endl;
378 : }
379 : } else {
380 11046 : itemsGot = fread(buffer, RecordSize, 1, fpVisData);
381 : // std::cout << "B: itemsGot : " << itemsGot << " item size = " << RecordSize << " feof(fpVisData) : " << feof(fpVisData) << " ferror(fpVisData) " << ferror(fpVisData) << std::endl;
382 : }
383 31615 : if(!itemsGot || feof(fpVisData) || ferror(fpVisData))
384 0 : QUIT= 1;
385 31615 : if(QUIT){
386 0 : FirstRecord =1;
387 0 : return(0);}
388 :
389 31615 : return(RecordSize);
390 : }
391 :
392 20585 : int readVLALogRec(char *data){
393 20585 : int dum(99);
394 : TapeHeader tapeHead;
395 20585 : char *physrec = new char[PHYS_RECORD_SIZE]; //Allocate the physical Record
396 :
397 20585 : int bytesRead = diskread_(&dum, physrec); // Read first physical record
398 : // std::cout << "bytesRead : " << bytesRead << std::endl;
399 :
400 20585 : memcpy(&tapeHead, physrec, sizeof(TapeHeader)); //Get the "tape" information
401 :
402 : //Calculate the Logical Record Size
403 : long LRSize ;
404 20585 : memcpy((void *)&LRSize, physrec+sizeof(TapeHeader), sizeof(LRSize));
405 20585 : LRSize = 2*ntohl(LRSize);
406 : // std::cout << "LRSize : " << LRSize << std::endl;
407 : // Now shift the bits from the physical to Logical Record
408 20585 : int BeePtr(0);
409 20585 : int NumPhysRecs(ntohs(tapeHead.total));
410 20585 : int en = sizeof(TapeHeader);
411 : // std::cout << "NumPhysRecs : " << NumPhysRecs << std::endl;
412 : // std::cout << "en : " << en << std::endl;
413 :
414 20585 : if (ntohs(tapeHead.current) == 1) {
415 20569 : memcpy(data+BeePtr, physrec+en, PHYS_RECORD_SIZE-en);
416 20569 : BeePtr = PHYS_RECORD_SIZE - en;
417 : }
418 20585 : if((LRSize < MAX_LOGICAL_RECORD_SIZE) && (ntohs(tapeHead.current) <= ntohs(tapeHead.total))){
419 31615 : for (int i=1; i<NumPhysRecs && !QUIT ; i++) {
420 11046 : bytesRead += diskread_(&dum, physrec);
421 11046 : memcpy(data+BeePtr, physrec+en, PHYS_RECORD_SIZE - en);
422 11046 : BeePtr += (PHYS_RECORD_SIZE - en);
423 : }
424 20569 : } else {
425 : // std::cout << "QUIT=1 : " << std::endl;
426 16 : QUIT = 1;
427 : }
428 :
429 20585 : delete [] physrec;
430 20585 : if(QUIT)
431 16 : LRSize = 0;
432 20585 : return LRSize;
433 : }
434 :
435 :
436 :
437 0 : int olread_(int *unit_no, char *buffer, int /*buff_len*/)
438 : {
439 0 : return diskread_(unit_no, buffer);
440 : }
441 :
442 0 : int olclose_(int */*unit_no*/)
443 : {
444 0 : fclose(fpVisData);
445 0 : if(timeData)
446 0 : fclose(timeData);
447 0 : if(hostLog)
448 0 : fclose(hostLog);
449 0 : unlink(logDataFile);
450 0 : return 0;
451 : }
452 :
453 : /* Implement a "sleep()" function which also suspends for fractions of
454 : a second. Following a GNU implementation of usleep(), this routine
455 : calls select() with NULL pointers of the I/O descriptor sets to
456 : do the actual delay. This is potentially better than sleep() which
457 : only does integer seconds and usleep() which only does micro seconds */
458 :
459 : #include <sys/time.h>
460 : #include <sys/types.h>
461 : #ifdef R6000
462 : #include <sys/select.h>
463 : #endif
464 :
465 0 : void sleep1(double sleep_time) {
466 :
467 : struct timeval wait;
468 : double wait_mu;
469 : int ready;
470 :
471 0 : if ( (sleep_time <= 0.0) || (sleep_time > 1.0e8) )
472 0 : return;
473 :
474 : /* convert floating seconds to integer
475 : seconds and micro seconds */
476 :
477 0 : wait_mu = sleep_time*1000000.0; /* secs to micro secs */
478 :
479 0 : wait.tv_sec = (long int) (wait_mu/1000000.0);
480 0 : wait.tv_usec = (long int) (wait_mu - ( (double) wait.tv_sec*1000000.0));
481 :
482 0 : ready = select(1, (fd_set *) NULL, (fd_set *) NULL, (fd_set *) NULL, &wait); if (ready < 0) {
483 0 : perror ("error on calling setitimer");
484 0 : return;
485 : }
486 0 : return;
487 : }
488 :
|