Example #1
0
// Public facade function.
int gcodep_parse_stream(GCodeParser_t *parser, int input_fd, FILE *err_stream) {
  if (err_stream) {
    // Output needs to be unbuffered, otherwise they'll never make it.
    setvbuf(err_stream, NULL, _IONBF, 0);
  }

  FILE *gcode_stream = fdopen(input_fd, "r");
  if (gcode_stream == NULL) {
    perror("Opening gcode stream");
    return 1;
  }

  fd_set read_fds;
  struct timeval wait_time;
  int select_ret;
  wait_time.tv_sec = 0;
  wait_time.tv_usec = 50 * 1000;
  FD_ZERO(&read_fds);

  arm_signal_handler();
  char buffer[8192];
  while (!caught_signal) {
    // Read with timeout. If we don't get anything on our input, but it
    // is not finished yet, we tell our
    FD_SET(input_fd, &read_fds);
    // When we're already in idle mode, we're not interested in change.
    wait_time.tv_usec = 50 * 1000;
    select_ret = select(input_fd + 1, &read_fds, NULL, NULL, &wait_time);
    if (select_ret < 0)  // Broken stream.
      break;

    if (select_ret == 0) {  // Timeout. Regularly call.
      parser->callbacks.input_idle(parser->callbacks.user_data);
      continue;
    }

    // Filedescriptor readable. Now wait for a line to finish.
    if (fgets(buffer, sizeof(buffer), gcode_stream) == NULL)
      break;
    gcodep_parse_line(parser, buffer, err_stream);
  }
  disarm_signal_handler();

  if (err_stream) {
    fflush(err_stream);
  }
  fclose(gcode_stream);

  if (parser->program_in_progress) {
    parser->callbacks.gcode_finished(parser->callbacks.user_data);
  }

  return caught_signal ? 2 : 0;
}
int determine_print_stats(int input_fd, float max_feedrate, float speed_factor,
			  struct BeagleGPrintStats *result) {
  struct StatsData data;
  bzero(&data, sizeof(data));
  data.max_feedrate = max_feedrate;
  data.cfg_speed_factor = speed_factor;
  data.prog_speed_factor = 1.0f;
  data.current_G1_feedrate = max_feedrate / 10; // some reasonable default.
  bzero(result, sizeof(*result));
  data.stats = result;

  struct GCodeParserCb callbacks;
  bzero(&callbacks, sizeof(callbacks));
  callbacks.rapid_move = &duration_G0;
  callbacks.coordinated_move = &duration_G1;
  callbacks.dwell = &duration_dwell;
  callbacks.set_speed_factor = &duration_set_speed_factor;

  // Not implemented
  callbacks.go_home = &dummy_home;
  callbacks.unprocessed = &ignore_other_commands;
  callbacks.set_fanspeed = &dummy_setvalue;
  callbacks.set_temperature = &dummy_setvalue;
  callbacks.motors_enable = &dummy_motors_enable;
  callbacks.wait_temperature = &dummy_noparam;

  FILE *f = fdopen(input_fd, "r");
  if (f == NULL) {
    perror("Couldn't determine print stats");
    return 1;
  }
  GCodeParser_t *parser = gcodep_new(&callbacks, &data);
  char buffer[8192];
  while (fgets(buffer, sizeof(buffer), f)) {
    gcodep_parse_line(parser, buffer, stderr);
  }
  fclose(f);
  gcodep_delete(parser);

  return 0;
}