Пример #1
0
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;
}
Пример #2
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", &param->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", &param->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, &param->block_size,  4) < 0) return warn("Could not read block size");            param->block_size  = ntohl(param->block_size);
    if (full_read(session->client_fd, &param->target_rate, 4) < 0) return warn("Could not read target bitrate");        param->target_rate = ntohl(param->target_rate);
    if (full_read(session->client_fd, &param->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, &param->slower_num,  2) < 0) return warn("Could not read slowdown numerator");    param->slower_num  = ntohs(param->slower_num);
    if (full_read(session->client_fd, &param->slower_den,  2) < 0) return warn("Could not read slowdown denominator");  param->slower_den  = ntohs(param->slower_den);
    if (full_read(session->client_fd, &param->faster_num,  2) < 0) return warn("Could not read speedup numerator");     param->faster_num  = ntohs(param->faster_num);
    if (full_read(session->client_fd, &param->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;
}