Example #1
0
BOOL VLDeclAddWayPoint(PDeviceDescriptor_t d, const WAYPOINT *wp){

  if (nturnpoints == 0) {
    TCHAR2usascii(wp->Name, vl.declaration.task.startpoint.name, 7);
    vl.declaration.task.startpoint.name[6] ='\0';

    vl.declaration.task.startpoint.lon =
      wp->Longitude;
    vl.declaration.task.startpoint.lat =
      wp->Latitude;
    nturnpoints++;
  } else {
    TCHAR2usascii(wp->Name, vl.declaration.task.turnpoints[nturnpoints-1].name, 7);
    vl.declaration.task.turnpoints[nturnpoints-1].name[6]='\0';

    vl.declaration.task.turnpoints[nturnpoints-1].lon =
      wp->Longitude;
    vl.declaration.task.turnpoints[nturnpoints-1].lat =
      wp->Latitude;
    nturnpoints++;
  }
  TCHAR2usascii(wp->Name, vl.declaration.task.finishpoint.name, 7);
  vl.declaration.task.finishpoint.name[6]='\0';
  vl.declaration.task.finishpoint.lon =
    wp->Longitude;
  vl.declaration.task.finishpoint.lat =
    wp->Latitude;

  return(TRUE);

}
Example #2
0
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/// Converts TCHAR[] string into US-ASCII string with characters safe for
/// writing to LX devices.
///
/// Characters are converted into their most similar representation
/// in ASCII. Nonconvertable characters are replaced by '?'.
///
/// Output string will always be terminated by '\0'.
///
/// @param input    input string (must be terminated with '\0')
/// @param outSize  output buffer size
/// @param output   output buffer
///
/// @retval true  all characters copied
/// @retval false some characters could not be copied due to buffer size
///
//static
bool DevLXNano::Wide2LxAscii(const TCHAR* input, int outSize, char* output)
{
  if (outSize == 0)
    return(false);

  int res = TCHAR2usascii(input, output, outSize);

  // replace all non-ascii characters with '?' - LX Colibri is very sensitive
  // on non-ascii chars - the electronic seal can be broken
  // (unicode2usascii() should be enough, but to be sure that someone has not
  // incorrectly changed unicode2usascii())
  output--;
  while (*++output != '\0')
  {
    if (*output < 32 || *output > 126)
      *output = '?';
  }

  return(res >= 0);
} // Wide2LxAscii()
Example #3
0
/** 
 * @brief Sends task declaration
 *
 * @param d Device handle
 * @param decl Task declaration data
 * @param errBufSize The size of the buffer for error string
 * @param errBuf The buffer for error string
 * 
 * @return Operation status
 */
bool CDevIMI::DeclarationWrite(PDeviceDescriptor_t d, const Declaration_t &decl, unsigned errBufSize, TCHAR errBuf[])
{
  if(!_connected) {
    // LKTOKEN  _@M1411_ = "Device not connected!"
    _sntprintf(errBuf, errBufSize, _T("%s"), gettext(_T("_@M1411_")));
    return false;
  }
  
  TDeclaration imiDecl;
  memset(&imiDecl, 0, sizeof(imiDecl));
  
  // idecl.date ignored - will be set by FR
  TCHAR2usascii(decl.PilotName,        imiDecl.header.plt, sizeof(imiDecl.header.plt));
  // decl.header.db1Year = year; decl.header.db1Month = month; decl.header.db1Day = day;
  TCHAR2usascii(decl.AircraftType,     imiDecl.header.gty, sizeof(imiDecl.header.gty));
  TCHAR2usascii(decl.AircraftRego,     imiDecl.header.gid, sizeof(imiDecl.header.gid));
  TCHAR2usascii(decl.CompetitionID,    imiDecl.header.cid, sizeof(imiDecl.header.cid));
  TCHAR2usascii(decl.CompetitionClass, imiDecl.header.ccl, sizeof(imiDecl.header.ccl));
  // strncpy(decl.header.clb, idecl.clb, sizeof(decl.header.clb));
  // strncpy(decl.header.sit, idecl.sit, sizeof(decl.header.sit));
  // strncpy(decl.header.cm2, idecl.cm2, sizeof(decl.header.cm2));
  // decl.header.db2Year = year; decl.header.db2Month = month; decl.header.db2Day = day;
  TCHAR tskName[IMIDECL_TASK_NAME_LENGTH];
  TaskFileName(IMIDECL_TASK_NAME_LENGTH, tskName);
  TCHAR2usascii(tskName, imiDecl.header.tskName, sizeof(imiDecl.header.tskName));
  // decl.header.tskYear = year; decl.header.tskMonth = month; decl.header.tskDay = day;
  // decl.header.tskNumber = MIN(9999, idecl.tskNumber);
  
  IMIWaypoint(decl, 0, imiDecl.wp[0]);
  for(int i=0; i<decl.num_waypoints; i++)
    IMIWaypoint(decl, i + 1, imiDecl.wp[i + 1]);
  IMIWaypoint(decl, decl.num_waypoints + 1, imiDecl.wp[decl.num_waypoints + 1]);
  
  // send declaration for current task
  const TMsg *msg = SendRet(d, errBufSize, errBuf, MSG_DECLARATION, &imiDecl, sizeof(imiDecl), MSG_ACK_SUCCESS, 0, static_cast<IMIBYTE>(-1));
  if(!msg && errBuf[0] == '\0') {
    // LKTOKEN  _@M1415_ = "Declaration not accepted!"
    _sntprintf(errBuf, errBufSize, _T("%s"), gettext(_T("_@M1415_")));
  }
  
  return msg;
}
Example #4
0
/** 
 * @brief Sets data in IMI Waypoint structure
 * 
 * @param decl LK task declaration
 * @param imiIdx The index of IMI waypoint to set
 * @param imiWp IMI waypoint structure to set
 */
void CDevIMI::IMIWaypoint(const Declaration_t &decl, unsigned imiIdx, TWaypoint &imiWp)
{
  unsigned idx = imiIdx == 0 ? 0 :
    (imiIdx == (unsigned)decl.num_waypoints + 1 ? imiIdx - 2 : imiIdx - 1);
  const WAYPOINT &wp = *decl.waypoint[idx];
  
  // set name
  TCHAR2usascii(wp.Name, imiWp.name, sizeof(imiWp.name));
  
  // set latitude
  TAngle a;
  double angle = wp.Latitude;
  if((a.sign = (angle < 0) ? 1 : 0) != 0)
    angle *= -1;
  a.degrees = static_cast<IMIDWORD>(angle);
  a.milliminutes = static_cast<IMIDWORD>((angle - a.degrees) * 60 * 1000);
  imiWp.lat = a.value;
  
  // set longitude
  angle = wp.Longitude;
  if((a.sign = (angle < 0) ? 1 : 0) != 0)
    angle *= -1;
  a.degrees = static_cast<IMIDWORD>(angle);
  a.milliminutes = static_cast<IMIDWORD>((angle - a.degrees) * 60 * 1000);
  imiWp.lon = a.value;
  
  // TAKEOFF and LANDING do not have OZs
  if(imiIdx == 0 || imiIdx == (unsigned)decl.num_waypoints + 1)
    return;
  
  // set observation zones
  if(imiIdx == 1) {
    // START
    imiWp.oz.style = 3;
    switch(StartLine) {
    case 0: // cylinder
      imiWp.oz.A1 = 1800;
      break;
    case 1: // line
      imiWp.oz.line_only = 1;
      break;
    case 2: // fai sector
      imiWp.oz.A1 = 450;
      break;
    }
    imiWp.oz.R1 = std::min((DWORD)250000, StartRadius);
  }
  else if(imiIdx == (unsigned)decl.num_waypoints) {
    // FINISH
    imiWp.oz.style = 4;
    switch(FinishLine) {
    case 0: // cylinder
      imiWp.oz.A1 = 1800;
      break;
    case 1: // line
      imiWp.oz.line_only = 1;
      break;
    case 2: // fai sector
      imiWp.oz.A1 = 450;
      break;
    }
    imiWp.oz.R1 = std::min((DWORD)250000, FinishRadius);
  }
  else {
    // TPs
    if(AATEnabled) {
      imiWp.oz.style = 1;
      switch(Task[idx].AATType) {
      case CIRCLE:
        imiWp.oz.A1 = 1800;
        imiWp.oz.R1 = std::min(250000, (int)Task[idx].AATCircleRadius);
        break;
      case SECTOR:
        imiWp.oz.A1 = ((int)(360 + Task[idx].AATFinishRadial - Task[idx].AATStartRadial) % 360) * 10 / 2;
        imiWp.oz.A12 = ((int)(Task[idx].AATStartRadial * 10) + 1800 + imiWp.oz.A1) % 3600;
        imiWp.oz.R1 = std::min(250000, (int)Task[idx].AATSectorRadius);
        break;
      }
    }
    else {
      imiWp.oz.style = 2;
      switch(SectorType) {
      case 0: // cylinder
        imiWp.oz.A1 = 1800;
        imiWp.oz.R1 = std::min((DWORD)250000, SectorRadius);
        break;
      case 1: // sector
        imiWp.oz.A1 = 450;
        imiWp.oz.R1 = std::min((DWORD)250000, SectorRadius);
        break;
      case 2: // German DAe 0.5/10
        imiWp.oz.A1 = 450;
        imiWp.oz.R1 = 10000;
        imiWp.oz.A2 = 1800;
        imiWp.oz.R2 = 500;
        break;
      }
    }
  }
  
  // other unused data
  imiWp.oz.maxAlt = 0;
  imiWp.oz.reduce = 0;
  imiWp.oz.move   = 0;
}
Example #5
0
BOOL VLDeclare(PDeviceDescriptor_t d, Declaration_t *decl, unsigned errBufferLen, TCHAR errBuffer[])
{
  vl.set_device(d);
  nturnpoints = 0;

  const unsigned BUFF_LEN = 128;
  TCHAR buffer[BUFF_LEN];
  int err = VLA_ERR_NOERR;

  // LKTOKEN  _@M1400_ = "Task declaration"
  // LKTOKEN  _@M1404_ = "Opening connection"
  _sntprintf(buffer, BUFF_LEN, _T("%s: %s..."), MsgToken(1400), MsgToken(1404));
  CreateProgressDialog(buffer);
  if((err = vl.open(1, 20, 1, 38400L)) != VLA_ERR_NOERR) {
    // LKTOKEN  _@M1411_ = "Device not connected!"
    _tcsncpy(errBuffer, MsgToken(1411), errBufferLen);
    return FALSE;
  }

  // LKTOKEN  _@M1400_ = "Task declaration"
  // LKTOKEN  _@M1405_ = "Testing connection"
  _sntprintf(buffer, BUFF_LEN, _T("%s: %s..."), MsgToken(1400), MsgToken(1405));
  CreateProgressDialog(buffer);
  if((err = vl.read_info()) != VLA_ERR_NOERR) {
    // LKTOKEN  _@M1414_ = "Device not responsive!"
    _tcsncpy(errBuffer, MsgToken(1414), errBufferLen);
    return FALSE;
  }

  TCHAR2usascii(decl->PilotName, vl.declaration.flightinfo.pilot, 66);
  vl.declaration.flightinfo.pilot[64]='\0';

  TCHAR2usascii(decl->AircraftRego, vl.declaration.flightinfo.gliderid, 8);
  vl.declaration.flightinfo.gliderid[7]='\0';

  TCHAR2usascii(decl->AircraftType, vl.declaration.flightinfo.glidertype, 13);
  vl.declaration.flightinfo.glidertype[12]='\0';

  TCHAR2usascii(decl->CompetitionID, vl.declaration.flightinfo.competitionid, 4);
  vl.declaration.flightinfo.competitionid[3]='\0'; // BUGFIX 100331

  TCHAR2usascii(decl->CompetitionClass, vl.declaration.flightinfo.competitionclass, 13);
  vl.declaration.flightinfo.competitionclass[12]='\0'; // BUGFIX 100331

  if (ValidWayPoint(HomeWaypoint)) {

    TCHAR2usascii(WayPointList[HomeWaypoint].Name, vl.declaration.flightinfo.homepoint.name, 7);
    vl.declaration.flightinfo.homepoint.name[6]='\0'; // BUGFIX 100331

    vl.declaration.flightinfo.homepoint.lon =
      WayPointList[HomeWaypoint].Longitude;
    vl.declaration.flightinfo.homepoint.lat =
      WayPointList[HomeWaypoint].Latitude;
  }

  int i;
  for (i = 0; i < decl->num_waypoints; i++)
    VLDeclAddWayPoint(d, decl->waypoint[i]);

  vl.declaration.task.nturnpoints = max(min(nturnpoints-2, 12), 0);

  LockTaskData();

  // start..
  switch(StartLine) {
  case 0: // cylinder
    vl.declaration.task.startpoint.oztyp = VLAPI_DATA::DCLWPT::OZTYP_CYLSKT;
    vl.declaration.task.startpoint.lw = min(1500,(int)StartRadius);
    vl.declaration.task.startpoint.rz = min(1500,(int)StartRadius);
    vl.declaration.task.startpoint.rs = 0;
    break;
  case 1: // line
    vl.declaration.task.startpoint.oztyp = VLAPI_DATA::DCLWPT::OZTYP_LINE;
    vl.declaration.task.startpoint.lw = StartRadius * 2;
    vl.declaration.task.startpoint.rs = 0;
    vl.declaration.task.startpoint.rz = 0;
    break;
  case 2: // fai sector
    vl.declaration.task.startpoint.oztyp = VLAPI_DATA::DCLWPT::OZTYP_CYLSKT;
    vl.declaration.task.startpoint.lw = min(15000,(int)StartRadius);
    vl.declaration.task.startpoint.rz = 0;
    vl.declaration.task.startpoint.rs = min(15000,(int)StartRadius);
    break;
  }
  vl.declaration.task.startpoint.ws = 360;

  // rest of task...
  for (i=0; i<nturnpoints; i++) {
    // note this is for non-aat only!
    switch (SectorType) {
    case 0: // cylinder
      vl.declaration.task.turnpoints[i].oztyp = VLAPI_DATA::DCLWPT::OZTYP_CYLSKT;
      vl.declaration.task.turnpoints[i].rz = min(1500,(int)SectorRadius);
      vl.declaration.task.turnpoints[i].rs = 0;
      vl.declaration.task.turnpoints[i].lw = 0;
      break;
    case 1: // sector
      vl.declaration.task.turnpoints[i].oztyp = VLAPI_DATA::DCLWPT::OZTYP_CYLSKT;
      vl.declaration.task.turnpoints[i].rz = 0;
      vl.declaration.task.turnpoints[i].rs = min(15000,(int)SectorRadius);
      vl.declaration.task.turnpoints[i].lw = 0;
      break;
    case 2: // German DAe 0.5/10
      vl.declaration.task.turnpoints[i].oztyp = VLAPI_DATA::DCLWPT::OZTYP_CYLSKT;
      vl.declaration.task.turnpoints[i].rz = 500;
      vl.declaration.task.turnpoints[i].rs = 10000;
      vl.declaration.task.turnpoints[i].lw = 0;
      break;
    };
    vl.declaration.task.turnpoints[i].ws = 360; // auto direction

  }

  // Finish
  switch(FinishLine) {
  case 0: // cylinder
    vl.declaration.task.finishpoint.oztyp = VLAPI_DATA::DCLWPT::OZTYP_CYLSKT;
    vl.declaration.task.finishpoint.lw = min(1500,(int)FinishRadius);
    vl.declaration.task.finishpoint.rz = min(1500,(int)FinishRadius);
    vl.declaration.task.finishpoint.rs = 0;
    break;
  case 1: // line
    vl.declaration.task.finishpoint.oztyp = VLAPI_DATA::DCLWPT::OZTYP_LINE;
    vl.declaration.task.finishpoint.lw = FinishRadius*2;
    vl.declaration.task.finishpoint.rz = 0;
    vl.declaration.task.finishpoint.rs = 0;
    break;
  case 2: // fai sector
    vl.declaration.task.finishpoint.oztyp = VLAPI_DATA::DCLWPT::OZTYP_CYLSKT;
    vl.declaration.task.finishpoint.lw = min(15000,(int)FinishRadius);
    vl.declaration.task.finishpoint.rz = 0;
    vl.declaration.task.finishpoint.rs = min(15000,(int)FinishRadius);
    break;
  }
  vl.declaration.task.finishpoint.ws = 360;

  UnlockTaskData();

  // LKTOKEN  _@M1400_ = "Task declaration"
  // LKTOKEN  _@M1403_ = "Sending  declaration"
  _sntprintf(buffer, BUFF_LEN, _T("%s: %s..."), MsgToken(1400), MsgToken(1403));
  CreateProgressDialog(buffer);
  if((err = vl.write_db_and_declaration()) != VLA_ERR_NOERR) {
    // LKTOKEN  _@M1415_ = "Declaration not accepted!"
    _tcsncpy(errBuffer, MsgToken(1415), errBufferLen);
  }

  // LKTOKEN  _@M1400_ = "Task declaration"
  // LKTOKEN  _@M1406_ = "Closing connection"
  _sntprintf(buffer, BUFF_LEN, _T("%s: %s..."), MsgToken(1400), MsgToken(1406));
  CreateProgressDialog(buffer);
  vl.close(1);

  return err == VLA_ERR_NOERR;
}