int main(int argc, char *argv[]) { struct evn_filename *ef; int i, cnt; u_int64_t li; char **filenames; int filenamecount; if (argc < 2) { // filenames = precoded; // filenamecount = PRECODELEN - 1; printf("Cut&paste to try: Expected:\n"); printf("-----------------------------------------------------------------\n"); printf("gre53_Ef_scan035_154d12h43m10s.vsi 1180874590 (in 2007)\n"); printf("gre53_Ef_scan035_154124310.vsi 1180874590 (in 2007)\n"); printf(" date -u --date \"01/01/2007 12:43:10 + 153 days\" +%%s\n"); printf("R1262_On_037-1240b_2007037124050_flen=5408000000.evn 1170765650\n"); printf(" date -u --date \"01/01/2007 12:40:50 + 36 days\" +%%s\n"); printf("R1262_On_037-1240b_2007037_dl=5408000000.vsi 1170720000\n"); printf("R1262_On_037-1240b_2007y037d_dl=5408000000.vsi 1170720000\n"); printf(" date -u --date \"01/01/2007 + 36 days 0:0:0\" +%%s\n"); printf("R1262_On_037-1240b_2007y037d12h6m1s_dl=5408000000.vsi 1170763561\n"); printf(" date -u --date \"01/01/2007 + 36 days 12:06:01\" +%%s\n"); printf("gre53_Ef_scan035_2006-11-21T08:45:00_dl=14400000.vsi 1164098700\n"); printf(" date -u --date \"11/21/2006 08:45:00\" +%%s\n"); printf("dummy_Mh_scan01_124500.00_dl=1500.vsi\n"); printf("\n"); return 0; } else { filenames = argv; filenamecount = argc - 1; } cnt = 1; while (cnt<=filenamecount) { printf("----- Parsing name: %s -----\n\n", filenames[cnt]); ef = parse_evn_filename(filenames[cnt]); if (ef->valid) { printf("Name seems to be valid\n"); } else { printf("Name is invalid\n"); } printf("ef->exp_name = %s\t", ef->exp_name); printf("ef->station_code = %s\t", ef->station_code); printf("ef->scan_name = %s\t", ef->scan_name); printf("ef->file_type = %s\n", ef->file_type); printf("ef->data_start_time_ascii = %s\t", ef->data_start_time_ascii); printf("ef->data_start_time = %f\n", ef->data_start_time); for (i=0; i<ef->nr_auxinfo; i++) printf("ef->auxinfo[%d] = %s\n", i, ef->auxinfo[i]); if (get_aux_entry("flen", ef->auxinfo, ef->nr_auxinfo) != 0) { sscanf(get_aux_entry("flen", ef->auxinfo, ef->nr_auxinfo), "%lld", &li); printf(" parsed flen param: %lld\n", li); } if (get_aux_entry("dl", ef->auxinfo, ef->nr_auxinfo) != 0) { sscanf(get_aux_entry("dl", ef->auxinfo, ef->nr_auxinfo), "%lld", &li); printf(" parsed dl param: %lld\n", li); } printf("\n"); cnt++; } return 0; }
/*------------------------------------------------------------------------ * int ttp_open_transfer(ttp_session_t *session); * * Tries to create a new TTP file request object for the given session * by reading the name of a requested file from the client. If we are * able to negotiate the transfer successfully, we return 0. If we * can't negotiate the transfer because of I/O or file errors, we * return a negative vlaue. * * The client is sent a result byte of 0 if the request is accepted * (because the file can be read) and a non-zero result byte otherwise. *------------------------------------------------------------------------*/ int ttp_open_transfer(ttp_session_t *session) { char filename[MAX_FILENAME_LENGTH]; /* the name of the file to transfer */ u_int64_t file_size; /* network-order version of file size */ u_int32_t block_size; /* network-order version of block size */ u_int32_t block_count; /* network-order version of block count */ time_t epoch; int status; ttp_transfer_t *xfer = &session->transfer; ttp_parameter_t *param = session->parameter; #ifdef VSIB_REALTIME /* VLBI/VSIB-related variables */ struct evn_filename *ef; double starttime; struct timeval d; #endif char size[10]; char file_no[10]; char message[20]; u_int16_t i; struct timeval ping_s, ping_e; /* clear out the transfer data */ memset(xfer, 0, sizeof(*xfer)); /* read in the requested filename */ status = read_line(session->client_fd, filename, MAX_FILENAME_LENGTH); if (status < 0) error("Could not read filename from client"); filename[MAX_FILENAME_LENGTH - 1] = '\0'; if(!strcmp(filename, TS_DIRLIST_HACK_CMD)) { /* The client requested listing of files and their sizes (dir command) * Send strings: NNN \0 name1 \0 len1 \0 nameN \0 lenN \0 */ snprintf(file_no, sizeof(file_no), "%u", param->total_files); full_write(session->client_fd, file_no, strlen(file_no)+1); for(i=0; i<param->total_files; i++) { full_write(session->client_fd, param->file_names[i], strlen(param->file_names[i])+1); snprintf(message, sizeof(message), "%Lu", (ull_t)(param->file_sizes[i])); full_write(session->client_fd, message, strlen(message)+1); } full_read(session->client_fd, message, 1); return warn("File list sent!"); } else if(!strcmp(filename,"*")) { if(param->allhook != 0) { /* execute the provided program on server side to see what files * should be gotten */ const int MaxFileListLength = 32768; char fileList[MaxFileListLength]; const char *fl; int nFile = 0; int length = 0; int l; FILE *p; fprintf(stderr, "Using allhook program: %s\n", param->allhook); p = popen((char *)(param->allhook), "r"); if(p) { memset(fileList, 0, MaxFileListLength); while(1) { if(fgets(message, sizeof(message), p) == 0) break; /* get lenght of string and strip non printable chars */ for(l = 0; message[l] >= ' '; ++l) {} message[l] = 0; fprintf(stdout, " '%s'\n", message); if(l + length >= MaxFileListLength) break; strncpy(fileList + length, message, l); length += l + 1; ++nFile; } } pclose(p); memset(size, 0, sizeof(size)); snprintf(size, sizeof(size), "%u", length); full_write(session->client_fd, size, 10); memset(file_no, 0, sizeof(file_no)); snprintf(file_no, sizeof(file_no), "%u", nFile); full_write(session->client_fd, file_no, 10); printf("\nSent multi-GET filename count and array size to client\n"); memset(message, 0, sizeof(message)); full_read(session->client_fd, message, 8); printf("Client response: %s\n", message); fl = fileList; if(nFile > 0) { for(i=0; i<nFile; i++) { l = strlen(fl); full_write(session->client_fd, fl, l+1); fl += l+1; } memset(message, 0, sizeof(message)); full_read(session->client_fd, message, 8); printf("Sent file list, client response: %s\n", message); status = read_line(session->client_fd, filename, MAX_FILENAME_LENGTH); if (status < 0) error("Could not read filename from client"); } } else { /* A multiple file request - sent the file names first, * and next the client requests a download of each in turn (get * command) */ memset(size, 0, sizeof(size)); snprintf(size, sizeof(size), "%u", param->file_name_size); full_write(session->client_fd, size, 10); memset(file_no, 0, sizeof(file_no)); snprintf(file_no, sizeof(file_no), "%u", param->total_files); full_write(session->client_fd, file_no, 10); printf("\nSent multi-GET filename count and array size to client\n"); memset(message, 0, sizeof(message)); full_read(session->client_fd, message, 8); printf("Client response: %s\n", message); for(i=0; i<param->total_files; i++) full_write(session->client_fd, param->file_names[i], strlen(param->file_names[i])+1); memset(message, 0, sizeof(message)); full_read(session->client_fd, message, 8); printf("Sent file list, client response: %s\n", message); status = read_line(session->client_fd, filename, MAX_FILENAME_LENGTH); if (status < 0) error("Could not read filename from client"); } } /* store the filename in the transfer object */ xfer->filename = strdup(filename); if (xfer->filename == NULL) return warn("Memory allocation error"); /* make a note of the request */ if (param->verbose_yn) printf("Request for file: '%s'\n", filename); #ifndef VSIB_REALTIME /* try to open the file for reading */ xfer->file = fopen(filename, "r"); if (xfer->file == NULL) { sprintf(g_error, "File '%s' does not exist or cannot be read", filename); /* signal failure to the client */ status = full_write(session->client_fd, "\x008", 1); if (status < 0) warn("Could not signal request failure to client"); return warn(g_error); } #else /* get starting time (UTC) and detect whether local disk copy is wanted */ if (strrchr(filename,'/') == NULL) { ef = parse_evn_filename(filename); /* attempt to parse */ param->fileout = 0; } else { ef = parse_evn_filename(strrchr(filename, '/')+1); /* attempt to parse */ param->fileout = 1; } if (!ef->valid) { fprintf(stderr, "Warning: EVN filename parsing failed, '%s' not following EVN File Naming Convention?\n", filename); } /* get time multiplexing info from EVN filename (currently these are all unused) */ if (get_aux_entry("sl",ef->auxinfo, ef->nr_auxinfo) == 0) param->totalslots= 1; /* default to 1 */ else sscanf(get_aux_entry("sl",ef->auxinfo, ef->nr_auxinfo), "%d", &(param->totalslots)); if (get_aux_entry("sn",ef->auxinfo, ef->nr_auxinfo) == 0) param->slotnumber= 1; /* default to 1 */ else sscanf(get_aux_entry("sn",ef->auxinfo, ef->nr_auxinfo), "%d", ¶m->slotnumber); if (get_aux_entry("sr",ef->auxinfo, ef->nr_auxinfo) == 0) param->samplerate= 512; /* default to 512 Msamples/s */ else sscanf(get_aux_entry("sr",ef->auxinfo, ef->nr_auxinfo), "%d", ¶m->samplerate); /* try to open the vsib for reading */ xfer->vsib = fopen("/dev/vsib", "r"); if (xfer->vsib == NULL) { sprintf(g_error, "VSIB board does not exist in /dev/vsib or it cannot be read"); status = full_write(session->client_fd, "\002", 1); if (status < 0) { warn("Could not signal request failure to client"); } return warn(g_error); } /* try to open the local disk copy file for writing */ if (param->fileout) { xfer->file = fopen(filename, "wb"); if (xfer->file == NULL) { sprintf(g_error, "Could not open local file '%s' for writing", filename); status = full_write(session->client_fd, "\x010", 1); if (status < 0) { warn("Could not signal request failure to client"); } fclose(xfer->vsib); return warn(g_error); } } /* Start half a second before full UTC seconds change. If EVN filename date/time parse failed, start immediately. */ if (!(NULL == ef->data_start_time_ascii || ef->data_start_time <= 1.0)) { u_int64_t timedelta_usec; starttime = ef->data_start_time - 0.5; assert( gettimeofday(&d, NULL) == 0 ); timedelta_usec = (unsigned long)((starttime - (double)d.tv_sec)* 1000000.0) - (double)d.tv_usec; fprintf(stderr, "Sleeping until specified time (%s) for %Lu usec...\n", ef->data_start_time_ascii, (ull_t)timedelta_usec); usleep_that_works(timedelta_usec); } /* Check if the client is still connected after the long(?) wait */ //if(recv(session->client_fd, &status, 1, MSG_PEEK)<0) { // // connection has terminated, exit // fclose(xfer->vsib); // return warn("The client disconnected while server was sleeping."); //} /* start at next 1PPS pulse */ start_vsib(session); #endif // end of VSIB_REALTIME section /* begin round trip time estimation */ gettimeofday(&ping_s,NULL); /* try to signal success to the client */ status = full_write(session->client_fd, "\000", 1); if (status < 0) return warn("Could not signal request approval to client"); /* read in the block size, target bitrate, and error rate */ if (full_read(session->client_fd, ¶m->block_size, 4) < 0) return warn("Could not read block size"); param->block_size = ntohl(param->block_size); if (full_read(session->client_fd, ¶m->target_rate, 4) < 0) return warn("Could not read target bitrate"); param->target_rate = ntohl(param->target_rate); if (full_read(session->client_fd, ¶m->error_rate, 4) < 0) return warn("Could not read error rate"); param->error_rate = ntohl(param->error_rate); /* end round trip time estimation */ gettimeofday(&ping_e,NULL); /* read in the slowdown and speedup factors */ if (full_read(session->client_fd, ¶m->slower_num, 2) < 0) return warn("Could not read slowdown numerator"); param->slower_num = ntohs(param->slower_num); if (full_read(session->client_fd, ¶m->slower_den, 2) < 0) return warn("Could not read slowdown denominator"); param->slower_den = ntohs(param->slower_den); if (full_read(session->client_fd, ¶m->faster_num, 2) < 0) return warn("Could not read speedup numerator"); param->faster_num = ntohs(param->faster_num); if (full_read(session->client_fd, ¶m->faster_den, 2) < 0) return warn("Could not read speedup denominator"); param->faster_den = ntohs(param->faster_den); #ifndef VSIB_REALTIME /* try to find the file statistics */ fseeko(xfer->file, 0, SEEK_END); param->file_size = ftello(xfer->file); fseeko(xfer->file, 0, SEEK_SET); #else /* get length of recording in bytes from filename */ if (get_aux_entry("flen", ef->auxinfo, ef->nr_auxinfo) != 0) { sscanf(get_aux_entry("flen", ef->auxinfo, ef->nr_auxinfo), "%" SCNu64, (u_int64_t*) &(param->file_size)); } else if (get_aux_entry("dl", ef->auxinfo, ef->nr_auxinfo) != 0) { sscanf(get_aux_entry("dl", ef->auxinfo, ef->nr_auxinfo), "%" SCNu64, (u_int64_t*) &(param->file_size)); } else { param->file_size = 60LL * 512000000LL * 4LL / 8; /* default to amount of bytes equivalent to 4 minutes at 512Mbps */ } fprintf(stderr, "Realtime file length in bytes: %Lu\n", (ull_t)param->file_size); #endif param->block_count = (param->file_size / param->block_size) + ((param->file_size % param->block_size) != 0); param->epoch = time(NULL); /* reply with the length, block size, number of blocks, and run epoch */ file_size = tsunami_htonll(param->file_size); if (full_write(session->client_fd, &file_size, 8) < 0) return warn("Could not submit file size"); block_size = htonl (param->block_size); if (full_write(session->client_fd, &block_size, 4) < 0) return warn("Could not submit block size"); block_count = htonl (param->block_count); if (full_write(session->client_fd, &block_count, 4) < 0) return warn("Could not submit block count"); epoch = htonl (param->epoch); if (full_write(session->client_fd, &epoch, 4) < 0) return warn("Could not submit run epoch"); /*calculate and convert RTT to u_sec*/ session->parameter->wait_u_sec=(ping_e.tv_sec - ping_s.tv_sec)*1000000+(ping_e.tv_usec-ping_s.tv_usec); /*add a 10% safety margin*/ session->parameter->wait_u_sec = session->parameter->wait_u_sec + ((int)(session->parameter->wait_u_sec* 0.1)); /* and store the inter-packet delay */ param->ipd_time = (u_int32_t) ((1000000LL * 8 * param->block_size) / param->target_rate); xfer->ipd_current = param->ipd_time * 3; /* if we're doing a transcript */ if (param->transcript_yn) xscript_open(session); /* we succeeded! */ return 0; }