bool
EWMicroRecorderDevice::Declare(const Declaration &declaration,
                               OperationEnvironment &env)
{
  // Must have at least two, max 12 waypoints
  if (declaration.size() < 2 || declaration.size() > 12)
    return false;

  /* during tests, the EW has taken up to one second to respond to
     the command \x18 */
  port->SetRxTimeout(2500);

  bool success = DeclareInner(*port, declaration, env);

  port->Write("!!\r\n");         // go back to NMEA mode

  return success;
}
static bool
DeclareInner(Port &port, const Declaration &declaration,
             OperationEnvironment &env)
{
  assert(declaration.size() >= 2);
  assert(declaration.size() <= 12);

  char user_data[2500];

  if (!TryConnect(port, user_data) || env.IsCancelled())
    return false;

  char *p = strstr(user_data, "USER DETAILS");
  if (p != NULL)
    *p = 0;

  port.Write('\x18');         // start to upload file
  port.Write(user_data);

  port.Write("USER DETAILS\r\n--------------\r\n\r\n");
  EWMicroRecorderPrintf(port, _T("%-15s %s\r\n"),
                        _T("Pilot Name:"), declaration.PilotName.c_str());
  EWMicroRecorderPrintf(port, _T("%-15s %s\r\n"),
                        _T("Competition ID:"),
                        declaration.CompetitionId.c_str());
  EWMicroRecorderPrintf(port, _T("%-15s %s\r\n"),
                        _T("Aircraft Type:"),
                        declaration.AircraftType.c_str());
  EWMicroRecorderPrintf(port, _T("%-15s %s\r\n"),
                        _T("Aircraft ID:"), declaration.AircraftReg.c_str());
  port.Write("\r\nFLIGHT DECLARATION\r\n-------------------\r\n\r\n");

  EWMicroRecorderPrintf(port, _T("%-15s %s\r\n"),
                        _T("Description:"), _T("XCSoar task declaration"));

  for (unsigned i = 0; i < 11; i++) {
    if (env.IsCancelled())
      return false;

    if (i+1>= declaration.size()) {
      EWMicroRecorderPrintf(port, _T("%-17s %s\r\n"),
               _T("TP LatLon:"), _T("0000000N00000000E TURN POINT"));
    } else {
      const Waypoint &wp = declaration.get_waypoint(i);
      if (i == 0) {
        EWMicroRecorderWriteWaypoint(port, wp, _T("Take Off LatLong:"));
        EWMicroRecorderWriteWaypoint(port, wp, _T("Start LatLon:"));
      } else if (i + 1 < declaration.size()) {
        EWMicroRecorderWriteWaypoint(port, wp, _T("TP LatLon:"));
      }
    }
  }

  const Waypoint &wp = declaration.get_last_waypoint();
  EWMicroRecorderWriteWaypoint(port, wp, _T("Finish LatLon:"));
  EWMicroRecorderWriteWaypoint(port, wp, _T("Land LatLon:"));

  if (env.IsCancelled())
      return false;

  port.Write('\x03');         // finish sending user file

  return port.ExpectString("uploaded successfully");
}