Example #1
0
bool
FlarmDevice::ReadFlightInfo(RecordedFlightInfo &flight,
                            OperationEnvironment &env)
{
  // Create header for getting record information
  FLARM::FrameHeader header = PrepareFrameHeader(FLARM::MT_GETRECORDINFO);

  // Send request
  if (!SendStartByte() ||
      !SendFrameHeader(header, env, 1000))
    return false;

  // Wait for an answer and save the payload for further processing
  AllocatedArray<uint8_t> data;
  uint16_t length;
  uint8_t ack_result =
    WaitForACKOrNACK(header.GetSequenceNumber(), data, length, env, 1000);

  // If neither ACK nor NACK was received
  if (ack_result != FLARM::MT_ACK || length <= 2)
    return false;

  char *record_info = (char *)data.begin() + 2;
  return ParseRecordInfo(record_info, flight);
}
Example #2
0
bool
FlarmDevice::DownloadFlight(Path path, OperationEnvironment &env)
{
  FileOutputStream fos(path);
  BufferedOutputStream os(fos);

  if (env.IsCancelled())
    return false;

  env.SetProgressRange(100);
  while (true) {
    // Create header for getting IGC file data
    FLARM::FrameHeader header = PrepareFrameHeader(FLARM::MT_GETIGCDATA);

    // Send request
    if (!SendStartByte() ||
        !SendFrameHeader(header, env, 1000) ||
        env.IsCancelled())
      return false;

    // Wait for an answer and save the payload for further processing
    AllocatedArray<uint8_t> data;
    uint16_t length;
    bool ack = WaitForACKOrNACK(header.GetSequenceNumber(), data,
                                length, env, 10000) == FLARM::MT_ACK;

    // If no ACK was received
    if (!ack || length <= 3 || env.IsCancelled())
      return false;

    length -= 3;

    // Read progress (in percent)
    uint8_t progress = *(data.begin() + 2);
    env.SetProgressPosition(std::min((unsigned)progress, 100u));

    const char *last_char = (const char *)data.end() - 1;
    bool is_last_packet = (*last_char == 0x1A);
    if (is_last_packet)
      length--;

    // Read IGC data
    const char *igc_data = (const char *)data.begin() + 3;
    os.Write(igc_data, length);

    if (is_last_packet)
      break;
  }

  os.Flush();
  fos.Commit();

  return true;
}
Example #3
0
bool
FlarmDevice::BinaryReset(OperationEnvironment &env, unsigned timeout_ms)
{
  TimeoutClock timeout(timeout_ms);

  // Create header for sending a binary reset request
  FLARM::FrameHeader header = PrepareFrameHeader(FLARM::MT_EXIT);

  // Send request and wait for positive answer
  return SendStartByte() &&
    SendFrameHeader(header, env, timeout.GetRemainingOrZero());
}
Example #4
0
bool
FlarmDevice::BinaryPing(OperationEnvironment &env, unsigned timeout_ms)
{
  const TimeoutClock timeout(timeout_ms);

  // Create header for sending a binary ping request
  FLARM::FrameHeader header = PrepareFrameHeader(FLARM::MT_PING);

  // Send request and wait for positive answer
  return SendStartByte() &&
    SendFrameHeader(header, env, timeout.GetRemainingOrZero()) &&
    WaitForACK(header.GetSequenceNumber(), env, timeout.GetRemainingOrZero());
}
Example #5
0
FLARM::MessageType
FlarmDevice::SelectFlight(uint8_t record_number, OperationEnvironment &env)
{
  // Create header for selecting a log record
  uint8_t data[1] = { record_number };
  FLARM::FrameHeader header = PrepareFrameHeader(FLARM::MT_SELECTRECORD,
                                                 data, sizeof(data));

  // Send request
  if (!SendStartByte() ||
      !SendFrameHeader(header, env, 1000) ||
      !SendEscaped(data, sizeof(data), env, 1000))
    return FLARM::MT_ERROR;

  // Wait for an answer
  return WaitForACKOrNACK(header.GetSequenceNumber(), env, 1000);
}