Beispiel #1
0
int dada_connect(dada_handle obj,
                 key_t       key) {
	obj->key = key;
	obj->hdu = dada_hdu_create(obj->log);
	dada_hdu_set_key(obj->hdu, obj->key);
	if( dada_hdu_connect(obj->hdu) < 0 ) {
		return DADA_CONNECT_FAILED;
	}
	obj->bufsize    = ipcbuf_get_bufsz((ipcbuf_t*)obj->hdu->data_block);
	obj->headersize = ipcbuf_get_bufsz((ipcbuf_t*)obj->hdu->header_block);
	return DADA_NO_ERROR;
}
Beispiel #2
0
/*
  Input: pointer to initialized data block, opened writable file descriptor
  
  Byte copy of the contents of the data block to the file. Does not check 
  where the data discontinuity is in the ring buffer, or which sub-blocks are 
  full or partially full.

  XXX: throw an error if for some reason parts of the data block can't
  be copied? (only possible if someone destroys the data block while this
  function is running)
 */
void event_to_file(const ipcio_t* db, FILE* evfd)
{
  int ii, nbytes;
  
  //basic ring buffer, which we use from the ipcio_t file-like abstraction
  //(cast works only b/c the ipcbuf_t element comes first in the ipcio_t struct)
  ipcbuf_t* buf = (ipcbuf_t *)db; 
  //pointers to sub-blocks
  char** buffer = buf->buffer;
    
  int nbufs = ipcbuf_get_nbufs(buf);
  int bufsz = ipcbuf_get_bufsz(buf);

  printf("event_to_file: nbuf = %d bufsz = %d\n",nbufs,bufsz);
  
  if(nbufs <= 0) {
    fprintf(stderr,"event_to_file: nbufs = %d\n",nbufs);
    exit(1);
  }

  if(bufsz <= 0) {
    fprintf(stderr,"event_to_file: bufsz = %d\n",bufsz);
    exit(1);
  }

  for(ii=0; ii<nbufs; ii++) {
    nbytes = fwrite(buffer[ii],1,bufsz,evfd);
    if(nbytes != bufsz)
      fprintf(stderr,"event_to_file: wrote only %d of %d bytes\n",nbytes,bufsz);
  }
}
Beispiel #3
0
/*
 *  start the observation on the data block, completing the header and marking
 *  the buffer as filled
 */
time_t leda_udpdb_start (udpdb_t * ctx, char * obs_header)
{
  // get the next available header block
  uint64_t header_size = ipcbuf_get_bufsz (ctx->hdu->header_block);
  char * header = ipcbuf_get_next_write (ctx->hdu->header_block);

  // copy the current observation's header to the header block
  memcpy (header, obs_header, header_size);

  // note to jkocz: here you could connect to ROACH'es and reg_arm, that way we
  // can insert the UTC_START into the DADA metadata if desirable


  // set any additional parameters that need setting
  uint64_t obs_offset = 0;
  if (ascii_header_set (header, "OBS_OFFSET", "%"PRIu64, obs_offset) < 0)
    multilog (ctx->log, LOG_WARNING, "Could not write OBS_OFFSET to header\n");

  if (ascii_header_set (header, "HDR_SIZE", "%"PRIu64, header_size) < 0)
    multilog (ctx->log, LOG_WARNING, "Could not write HDR_SIZE to header\n");

  if (utc_start)
  {
    char buffer[64];
    //strftime (buffer, 64, DADA_TIMESTR, localtime(&utc_start));
    strftime (buffer, 64, DADA_TIMESTR, gmtime(&utc_start));
    if (ascii_header_set (header, "UTC_START", "%s", buffer) < 0)
      multilog (ctx->log, LOG_WARNING, "Could not write UTC_START to header\n");

  }


  if (ctx->verbose > 1)
    multilog (ctx->log, LOG_INFO, "header=%s\n", header);

  // mark the header as filled
  if (ipcbuf_mark_filled (ctx->hdu->header_block, header_size) < 0)
  {
    multilog (ctx->log, LOG_ERR, "start: could not mark filled Header Block\n");
    return -1;
  }

  // open a block of the data block, ready for writing
  if (leda_udpdb_open_buffer (ctx) < 0)
  {
    multilog (ctx->log, LOG_ERR, "start: leda_udpdb_open_buffer failed\n");
    return -1;
  }

  return 0;
}
Beispiel #4
0
int main (int argc, char **argv)
{

  /* DADA Logger */ 
  multilog_t* log = 0;

  /* Interface on which to listen for udp packets */
  char * interface = "any";

  /* port for control commands */
  int control_port = 0;

  /* port for incoming UDP packets */
  int inc_port = LEDA_DEFAULT_UDPDB_PORT;

  /* multilog output port */
  int l_port = LEDA_DEFAULT_PWC_LOGPORT;

  /* Flag set in daemon mode */
  char daemon = 0;

  /* Flag set in verbose mode */
  int verbose = 0;

  /* number of seconds/bytes to acquire for */
  unsigned nsecs = 0;

  /* actual struct with info */
  udpdb_t udpdb;

  /* custom header from a file, implies no controlling pwcc */
  char * header_file = NULL;

  /* Pointer to array of "read" data */
  char *src;

  /* Ignore dropped packets */
  unsigned ignore_dropped = 0;

  // default shared memory key
  key_t dada_key = DADA_DEFAULT_BLOCK_KEY;

  // DADA Header + Data unit
  dada_hdu_t * hdu = 0;

  int arg = 0;

  int cpu_core = -1;

  unsigned int num_inputs = 1;

  /* statistics thread */
  pthread_t stats_thread_id;

  /* control thread */
  pthread_t control_thread_id;

  /* receiving thread */
  pthread_t receiving_thread_id;

  while ((arg=getopt(argc,argv,"b:c:df:i:k:l:n:p:t:vh")) != -1) {
    switch (arg) {

    case 'b':
      cpu_core = atoi(optarg);
      break; 

    case 'c':
      control_port = atoi(optarg);
      break; 

    case 'd':
      daemon = 1;
      break; 

    case 'f':
      header_file = strdup(optarg);
      break; 

    case 'k':
      if (sscanf (optarg, "%x", &dada_key) != 1) {
        fprintf (stderr, "dada_db: could not parse key from %s\n", optarg);
        return -1;
      }
      break;

    case 'i':
      if (optarg)
        interface = optarg;
      break;
    
    case 'l':
      if (optarg) {
        l_port = atoi(optarg);
        break;
      } else {
        usage();
        return EXIT_FAILURE;
      }

    case 'n':
      num_inputs = atoi(optarg);
      break;

    case 'p':
      inc_port = atoi (optarg);
      break;

    case 't':
      nsecs = atoi (optarg);
      break;

    case 'v':
      verbose++;
      break;

    case 'h':
      usage();
      return 0;
      
    default:
      usage ();
      return 0;
      
    }
  }
  
  char * obs_header = 0;

  if (!control_port && !header_file)
  {
    fprintf(stderr, "ERROR: no control port or header file specified\n");
    usage();
    exit(EXIT_FAILURE);
  }

  // check the command line arguments
  if (header_file != NULL)
  {
    obs_header = (char *) malloc(sizeof(char) * DADA_DEFAULT_HEADER_SIZE);
    if (!obs_header)
    {
      fprintf (stderr, "could not allocate memory\n");
      return (EXIT_FAILURE);
    }
    
    // read the ASCII DADA header from the file
    if (fileread (header_file, obs_header, DADA_DEFAULT_HEADER_SIZE) < 0)
    {
      free (obs_header);
      fprintf (stderr, "ERROR: could not read ASCII header from %s\n", header_file);
      return (EXIT_FAILURE);
    }
  }
    

  int i = 0;
  int rval = 0;
  void* result = 0;

  log = multilog_open ("leda_udpdb_thread", 0);

  if (daemon)
    be_a_daemon ();
  else
    multilog_add (log, stderr);
  udpdb.log = log;

  // initialize the data structure
  multilog (log, LOG_INFO, "main: leda_udpdb_init_receiver()\n");
  if (leda_udpdb_init_receiver (&udpdb) < 0)
  {
    multilog (log, LOG_ERR, "could not initialize socket\n");
    return EXIT_FAILURE;
  }

  udpdb.verbose = verbose;
  udpdb.port = inc_port;
  udpdb.recv_core = cpu_core;
  udpdb.interface = strdup(interface);
  udpdb.control_port = control_port;
  udpdb.packets_per_buffer = 0;
  udpdb.bytes_to_acquire = -1;
  udpdb.num_inputs = num_inputs;

  multilog (log, LOG_INFO, "main: dada_create_hdu()\n");

  // create the HDU struct
  hdu = dada_hdu_create (log);

  // set the key to connecting to the HDU
  dada_hdu_set_key (hdu, dada_key);

  // connect to HDU
  if (dada_hdu_connect (hdu) < 0)
  {
    multilog (log, LOG_ERR, "could not connect to hdu\n");
    return EXIT_FAILURE;
  }
  udpdb.hdu = hdu;

  // determine block size of the data block
  udpdb.hdu_bufsz = ipcbuf_get_bufsz ((ipcbuf_t *) hdu->data_block);

  // determine number of packets per block, must 
  if (udpdb.hdu_bufsz % UDP_DATA != 0)
  {
    multilog (log, LOG_ERR, "data block size for [%"PRIu64"] was not "
              "a multiple of the UDP_DATA size [%d]\n", udpdb.hdu_bufsz, UDP_DATA);
    return EXIT_FAILURE;
  }
  udpdb.packets_per_buffer = udpdb.hdu_bufsz / UDP_DATA;
  if (udpdb.verbose)
    multilog (udpdb.log, LOG_INFO, "main: HDU bufsz=%"PRIu64", UDP_DATA=%d, packets_per_buffer=%"PRIu64"\n", 
                                  udpdb.hdu_bufsz, UDP_DATA, udpdb.packets_per_buffer);


  if (verbose)
    multilog(log, LOG_INFO, "main: leda_udpdb_prepare()\n");
  if (leda_udpdb_prepare (&udpdb) < 0)
  {
    multilog(log, LOG_ERR, "could allocate required resources\n");
    return EXIT_FAILURE;
  }

  signal(SIGINT, signal_handler);

  // start the control thread
  if (control_port) 
  {
    if (verbose)
      multilog(log, LOG_INFO, "starting control_thread()\n");
    rval = pthread_create (&control_thread_id, 0, (void *) control_thread, (void *) &udpdb);
    if (rval != 0) {
      multilog(log, LOG_INFO, "Error creating control_thread: %s\n", strerror(rval));
      return -1;
    }
  }

  if (verbose)
    multilog(log, LOG_INFO, "starting stats_thread()\n");
  rval = pthread_create (&stats_thread_id, 0, (void *) stats_thread, (void *) &udpdb);
  if (rval != 0) {
    multilog(log, LOG_INFO, "Error creating stats_thread: %s\n", strerror(rval));
    return -1;
  }

  // main control loop
  while (!quit_threads) 
  {
    if (verbose)
      multilog(log, LOG_INFO, "main: leda_udpdb_reset_receiver()\n");
    leda_udpdb_reset_receiver (&udpdb);

    // wait for a START command before initialising receivers
    while (!start_pending && !quit_threads && control_port) 
      usleep(100000);

    if (quit_threads)
      break;

    // if header was supplied via text file, begin immediately
    if (header_file)
    {
      if (verbose)
        multilog(log, LOG_INFO, "main: leda_udpdb_start()\n");
      time_t utc = leda_udpdb_start (&udpdb, obs_header);
      if (utc == -1 ) {
        multilog(log, LOG_ERR, "Could not run start function\n");
        return EXIT_FAILURE;
      }
    }

    /* set the total number of bytes to acquire */
    udpdb.bytes_to_acquire = 1600 * 1000 * 1000 * (int64_t) nsecs;

    if (verbose)
    { 
      if (udpdb.bytes_to_acquire) 
        multilog(log, LOG_INFO, "bytes_to_acquire = %"PRIu64" Million Bytes, nsecs=%d\n", udpdb.bytes_to_acquire/1000000, nsecs);
      else
        multilog(log, LOG_INFO, "Acquiring data indefinitely\n");
    }

    //rval = pthread_create (&receiving_thread_id, &recv_attr, (void *) leda_udpdb_receive_obs , (void *) &udpdb);
    if (verbose)
      multilog(log, LOG_INFO, "starting leda_udpdb_receive_obs thread\n");
    rval = pthread_create (&receiving_thread_id, 0, (void *) leda_udpdb_receive_obs , (void *) &udpdb);
    if (rval != 0) {
      multilog(log, LOG_INFO, "Error creating leda_udpdb_receive_obs thread: %s\n", strerror(rval));
      return -1;
    }

    if (verbose) 
      multilog(log, LOG_INFO, "joining leda_udpdb_receive_obs thread\n");
    pthread_join (receiving_thread_id, &result);

    if (verbose) 
      multilog(log, LOG_INFO, "udpdb_stop_function\n");
    if ( udpdb_stop_function(&udpdb) != 0)
      fprintf(stderr, "Error stopping acquisition");


    if (!control_port)
      quit_threads = 1;

  }

  if (control_port)
  {
    if (verbose)
      multilog(log, LOG_INFO, "joining control_thread\n");
    pthread_join (control_thread_id, &result);
  }

  if (verbose)
    multilog(log, LOG_INFO, "joining stats_thread\n");
  pthread_join (stats_thread_id, &result);

  // clean up memory 
  if ( leda_udpdb_destroy_receiver (&udpdb) < 0) 
    fprintf(stderr, "failed to clean up receivers\n");

  // disconnect from HDU
  if (dada_hdu_disconnect (hdu) < 0)
    multilog (log, LOG_ERR, "could not unlock write on hdu\n");

  return EXIT_SUCCESS;
}