Ejemplo n.º 1
0
int run_snap_poco(struct katcp_dispatch *d, void *data)
{
  struct snap_poco *n;
  struct capture_poco *cp;
  uint32_t addr, ctrl[2];
  int rr, wr, i, sr;
  void *payload;
  unsigned int total;

  n = data;

  if(need_current_mode_katcp(d, POCO_POCO_MODE) == NULL){
    log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "left poco mode hence disabling %s snap", n->n_name);
    return -1;
  }

#ifdef DEBUG
  if(n->n_magic != SNAP_MAGIC){
    fprintf(stderr, "snap: bad magic: got 0x%x\n", n->n_magic);
    abort();
  }
#endif

  cp = n->n_capture;

  rr = read_pce(d, n->n_addr, &addr, 0, 4);
  if(rr != 4){
    log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "unable to read snap address of %s", n->n_name);
    return -1;
  }

  if((addr + 1) < n->n_count){
    log_message_katcp(d, KATCP_LEVEL_TRACE, NULL, "snap has %u waiting for %u", addr, n->n_count);
    return 0;
  }

  log_message_katcp(d, KATCP_LEVEL_TRACE, NULL, "snap got full %u+1 words", addr);

  total = n->n_count * 4;

  for(i = 0; i < total; i += n->n_chunk){
    sr = i - total;
    if(sr > n->n_chunk){
      sr = n->n_chunk;
    }

    payload = data_udp_poco(d, cp, i, sr);
    if(payload == NULL){
      log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "snap: unable to acquire payload space of %d", sr);
      return -1;
    }

    /* TODO: add support to read from multiple blockrams */
    if(n->n_blocks == 1){
      rr = read_pce(d, n->n_bram[0], payload, i, sr);
      if(rr < sr){
        log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "snap: blockram read failed");
        return -1;
      }
    } else {
#if 0
      fprintf(stderr, "snap: multiple blocks read still to be implemented\n");
      for(i = 0; i < n->n_blocks; i++){
          rr = read_pce(d, n->n_bram[i], payload, i, sr);
          if(rr < sr){
            log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "snap: blockram read failed");
            return -1;
          }
        }
      }
#endif
    }

    tx_udp_poco(d, cp);
  }
Ejemplo n.º 2
0
int run_generic_capture(struct katcp_dispatch *d, struct capture_poco *cp, int poke)
{
  /* logic:  */
  /* zero poke means that we are being run from a timer, advance our state */
  /* machine, by looking at state value (initial value zero, but never changed */
  /* by subsequent api logic */
  /* nonzero poke means that the user has changed a parameter */

#if 0
  /* scary logic for client using the API: ping means that the user has changed some parameter - client has to figure out what to do on the basis of that, otherwise just run whatever client state machine, client can use c_state for that, where 0 is the starting condition (never gets reset by API logic, client responsible for that) */
#endif

  sane_capture(cp);

  log_message_katcp(d, KATCP_LEVEL_TRACE, NULL, "capture %s with notification %d and state %d", cp->c_name, poke, cp->c_state);

  switch(poke){

    case CAPTURE_POKE_AUTO : /* automatic state machine runner */
      switch(cp->c_state){

        case IDLE_GENERIC_CAPTURE :
          log_message_katcp(d, KATCP_LEVEL_WARN, NULL, "running capture timer while idle is unexpected");
          return -1;

        case PREP_GENERIC_CAPTURE :

          log_message_katcp(d, KATCP_LEVEL_DEBUG, NULL, "capture-prepare %s", cp->c_name);

          if(cp->c_fd < 0){
            log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "no valid destination, not starting capture %s", cp->c_name);
            return -1;
          }
          if(cp->c_start.tv_sec == 0){
            log_message_katcp(d, KATCP_LEVEL_FATAL, NULL, "no valid start time while prepping");
            cp->c_state = IDLE_GENERIC_CAPTURE;
            return -1;
          }
          if(cp->c_toggle){
            log_message_katcp(d, KATCP_LEVEL_DEBUG, NULL, "toggling start for %s", cp->c_name);

            if((*(cp->c_toggle))(d, cp->c_dump, 1) < 0){
              log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "unable to trigger data collection");
              cp->c_state = IDLE_GENERIC_CAPTURE;
              return -1;
            }
          }
          register_at_tv_katcp(d, &(cp->c_start), &timer_generic_capture, cp);
          cp->c_start.tv_sec = 0;
          cp->c_start.tv_sec = 0;

          meta_udp_poco(d, cp, START_STREAM_CONTROL_POCO);
          tx_udp_poco(d, cp);

          cp->c_state = START_GENERIC_CAPTURE;
          break;

        case START_GENERIC_CAPTURE : 
          /* MAYBE: change from log to #capture-start ? */
          log_message_katcp(d, KATCP_LEVEL_INFO, NULL, "capture-start %s", cp->c_name);

          if(cp->c_stop.tv_sec){
            log_message_katcp(d, KATCP_LEVEL_INFO, NULL, "scheduling stop at %lu.%06lu", cp->c_stop.tv_sec, cp->c_stop.tv_usec);
            register_at_tv_katcp(d, &(cp->c_stop), &timer_generic_capture, cp);
          }
          cp->c_state = RUN_GENERIC_CAPTURE;
          break;

        case RUN_GENERIC_CAPTURE  : 

          log_message_katcp(d, KATCP_LEVEL_INFO, NULL, "capture-stop %s", cp->c_name);

          if(cp->c_toggle){
            if((*(cp->c_toggle))(d, cp->c_dump, 0) < 0){
              log_message_katcp(d, KATCP_LEVEL_WARN, NULL, "problems stopping %s", cp->c_name);
            }
          } else {
            log_message_katcp(d, KATCP_LEVEL_WARN, NULL, "no switch to stop capture for %s", cp->c_name);
          }

          meta_udp_poco(d, cp, STOP_STREAM_CONTROL_POCO);
          tx_udp_poco(d, cp);

          cp->c_stop.tv_sec = 0;
          cp->c_stop.tv_usec = 0;
          cp->c_state = IDLE_GENERIC_CAPTURE;
          break;

        default :
          log_message_katcp(d, KATCP_LEVEL_FATAL, NULL, "bad state %d for capture %s", cp->c_state, cp->c_name);
          cp->c_state = IDLE_GENERIC_CAPTURE;
          return -1;
      }
      break;

    case CAPTURE_POKE_START : /* user notification start */

      switch(cp->c_state){
        case IDLE_GENERIC_CAPTURE :
          break;
        case PREP_GENERIC_CAPTURE :
          log_message_katcp(d, KATCP_LEVEL_WARN, NULL, "overriding previously scheduled capture start for %s", cp->c_name);
          break;
        default :
          log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "capture for %s already running or scheduled to run", cp->c_name);
          return -1;
      }

      if(cp->c_prep.tv_sec == 0){
        log_message_katcp(d, KATCP_LEVEL_FATAL, NULL, "no valid prep time given for %s", cp->c_name);
        return -1;
      }

      if(cmp_time_katcp(&(cp->c_prep), &(cp->c_start)) >= 0){
        log_message_katcp(d, KATCP_LEVEL_FATAL, NULL, "prep time not before start time for %s", cp->c_name);
        return -1;
      }

      if((cp->c_stop.tv_sec != 0) && (cmp_time_katcp(&(cp->c_stop), &(cp->c_start)) < 0)){
        log_message_katcp(d, KATCP_LEVEL_WARN, NULL, "overriding stale stop carelessly scheduled for %lu.%06lus", cp->c_stop.tv_sec, cp->c_stop.tv_usec);
        cp->c_stop.tv_sec = 0;
        cp->c_stop.tv_usec = 0;
      }

      if(cp->c_fd < 0){
        log_message_katcp(d, KATCP_LEVEL_WARN, NULL, "hoping for that valid destination for %s will be set soon", cp->c_name);
      }

      register_at_tv_katcp(d, &(cp->c_prep), &timer_generic_capture, cp);

      cp->c_prep.tv_sec = 0;
      cp->c_prep.tv_usec = 0;

      cp->c_state = PREP_GENERIC_CAPTURE;
      break;

    case CAPTURE_POKE_STOP  : /* user notification - stop */
      if(cp->c_stop.tv_sec == 0){
        log_message_katcp(d, KATCP_LEVEL_FATAL, NULL, "having no stop time set when requesting sto is a major logic failure");
      }

      switch(cp->c_state){
        case IDLE_GENERIC_CAPTURE :
          if(cp->c_start.tv_sec != 0) {
            log_message_katcp(d, KATCP_LEVEL_FATAL, NULL, "having a start time set in idle state is a major logic failure");
          }

          log_message_katcp(d, KATCP_LEVEL_WARN, NULL, "setting a stop at %lu.%lus while idle on %s despite having no start time", cp->c_stop.tv_sec, cp->c_stop.tv_usec, cp->c_name);
          break;

        case PREP_GENERIC_CAPTURE : 
          if(cmp_time_katcp(&(cp->c_stop), &(cp->c_start)) <= 0){

            log_message_katcp(d, KATCP_LEVEL_WARN, NULL, "cancelling capture on %s as stop time preceeds start time", cp->c_name);

            cp->c_stop.tv_sec = 0;
            cp->c_stop.tv_usec = 0;

            cp->c_start.tv_sec = 0;
            cp->c_start.tv_usec = 0;

            discharge_timer_katcp(d, cp);
          }
          break;

        case RUN_GENERIC_CAPTURE :
          register_at_tv_katcp(d, &(cp->c_stop), &timer_generic_capture, cp);
          break;

      }
      break;

    default :
      log_message_katcp(d, KATCP_LEVEL_FATAL, NULL, "unknown poke state %d", poke);
      return -1;
      break;
  }

  return 0; /* time registration functions look at this code, but only for periodic events */
}