rx_int32 IOBuffer::consumeI32BE() {
	rx_int32 val = 0;
	memcpy(&val, buffer+consumed, 4);
	val = FromBE32(val);
	consumed += 4;
	return val;
}
Beispiel #2
0
inline void
SkyLinesTracking::Client::OnTrafficReceived(const TrafficResponsePacket &packet,
                                            size_t length)
{
  const unsigned n = packet.traffic_count;
  const TrafficResponsePacket::Traffic *traffic =
    (const TrafficResponsePacket::Traffic *)(&packet + 1);

  if (length != sizeof(packet) + n * sizeof(*traffic))
    return;

  const TrafficResponsePacket::Traffic *end = traffic + n;
  for (; traffic != end; ++traffic)
    handler->OnTraffic(FromBE32(traffic->pilot_id),
                       FromBE32(traffic->time),
                       ::GeoPoint(Angle::Degrees(fixed(FromBE32(traffic->location.longitude)) / 1000000),
                                  Angle::Degrees(fixed(FromBE32(traffic->location.latitude)) / 1000000)),
                       FromBE16(traffic->altitude));
}
Beispiel #3
0
inline void
SkyLinesTracking::Client::OnTrafficReceived(const TrafficResponsePacket &packet,
        size_t length)
{
    if (length < sizeof(packet))
        return;

    const unsigned n = packet.traffic_count;
    const ConstBuffer<TrafficResponsePacket::Traffic>
    list((const TrafficResponsePacket::Traffic *)(&packet + 1), n);

    if (length != sizeof(packet) + n * sizeof(list.front()))
        return;

    for (const auto &traffic : list)
        handler->OnTraffic(FromBE32(traffic.pilot_id),
                           FromBE32(traffic.time),
                           ImportGeoPoint(traffic.location),
                           (int16_t)FromBE16(traffic.altitude));
}
Beispiel #4
0
static bool
ListNavpoints(CAI302Device &device, OperationEnvironment &env)
{
  const int count = device.ReadNavpointCount(env);
  if (count < 0)
    return false;

  printf("count=%u\n", count);
  for (int i = 0; i < count; ++i) {
    CAI302::Navpoint n;
    if (!device.ReadNavpoint(i, n, env))
      return false;

    int32_t latitude = FromBE32(n.latitude) - 54000000;
    char latitude_letter = latitude >= 0 ? 'N' : 'S';
    if (latitude < 0)
      latitude = -latitude;

    int32_t longitude = FromBE32(n.longitude) - 108000000;
    char longitude_letter = longitude >= 0 ? 'E' : 'W';
    if (longitude < 0)
      longitude = -longitude;

    printf("%u: %u:%02u:%02u%c %u:%02u:%02u%c '%.*s' '%.*s'\n", i,
           latitude / 10000 / 60,
           latitude / 10000 % 60,
           latitude * 6 / 1000 % 60,
           latitude_letter,
           longitude / 10000 / 60,
           longitude / 10000 % 60,
           longitude * 6 / 1000 % 60,
           longitude_letter,
           StringBufferLength(n.name, ARRAY_SIZE(n.name)), n.name,
           StringBufferLength(n.remark, ARRAY_SIZE(n.remark)), n.remark);
  }

  return true;
}
Beispiel #5
0
inline void
SkyLinesTracking::Client::OnUserNameReceived(const UserNameResponsePacket &packet,
                                             size_t length)
{
  if (length != sizeof(packet) + packet.name_length)
    return;

  /* the name follows the UserNameResponsePacket object */
  const char *_name = (const char *)(&packet + 1);
  const std::string name(_name, packet.name_length);
  if (!ValidateUTF8(name.c_str()))
    return;

  UTF8ToWideConverter tname(name.c_str());
  handler->OnUserName(FromBE32(packet.user_id), tname);
}
Beispiel #6
0
inline void
SkyLinesTracking::Client::OnWaveReceived(const WaveResponsePacket &packet,
        size_t length)
{
    if (length < sizeof(packet))
        return;

    const unsigned n = packet.wave_count;
    ConstBuffer<Wave> waves((const Wave *)(&packet + 1), n);
    if (length != sizeof(packet) + waves.size * sizeof(waves.front()))
        return;

    for (const auto &wave : waves)
        handler->OnWave(FromBE32(wave.time),
                        ImportGeoPoint(wave.a), ImportGeoPoint(wave.b));
}
Beispiel #7
0
inline void
SkyLinesTracking::Client::OnThermalReceived(const ThermalResponsePacket &packet,
        size_t length)
{
    if (length < sizeof(packet))
        return;

    const unsigned n = packet.thermal_count;
    ConstBuffer<Thermal> thermals((const Thermal *)(&packet + 1), n);
    if (length != sizeof(packet) + thermals.size * sizeof(thermals.front()))
        return;

    for (const auto &thermal : thermals)
        handler->OnThermal(FromBE32(thermal.time),
                           AGeoPoint(ImportGeoPoint(thermal.bottom_location),
                                     FromBE16(thermal.bottom_altitude)),
                           AGeoPoint(ImportGeoPoint(thermal.top_location),
                                     FromBE16(thermal.top_altitude)),
                           FromBE16(thermal.lift) / 256.);
}
Beispiel #8
0
bool
LX::ConvertLXNToIGC(const void *_data, size_t _length,
                    FILE *file)
{
    const uint8_t *data = (const uint8_t *)_data, *end = data + _length;
    Context context;
    char ch;
    unsigned l;

    while (data < end) {
        union LXN::Packet packet = { data };

        unsigned packet_length;
        switch ((LXN::Command)*packet.cmd) {
        case LXN::EMPTY:
            packet_length = 0;
            while (data < end && *data == LXN::EMPTY) {
                ++packet_length;
                ++data;
            }

            fprintf(file, "LFILEMPTY%u\r\n", packet_length);
            break;

        case LXN::END:
            return true;

        case LXN::VERSION:
            data += sizeof(*packet.version);
            if (data > end)
                return false;

            fprintf(file,
                    "HFRFWFIRMWAREVERSION:%3.1f\r\n"
                    "HFRHWHARDWAREVERSION:%3.1f\r\n",
                    packet.version->software / 10.,
                    packet.version->hardware / 10.);
            break;

        case LXN::START:
            data += sizeof(*packet.start);
            if (data > end ||
                    memcmp(packet.start->streraz, "STReRAZ", 8) != 0)
                return false;

            context.flight_no = packet.start->flight_no;
            break;

        case LXN::ORIGIN:
            data += sizeof(*packet.origin);
            if (data > end)
                return false;

            context.origin_time = FromBE32(packet.origin->time);
            context.origin_latitude = (int32_t)FromBE32(packet.origin->latitude);
            context.origin_longitude = (int32_t)FromBE32(packet.origin->longitude);

            fprintf(file, "L%.*sORIGIN%02d%02d%02d" "%02d%05d%c" "%03d%05d%c\r\n",
                    (int)sizeof(context.vendor), context.vendor,
                    context.origin_time / 3600, context.origin_time % 3600 / 60,
                    context.origin_time % 60,
                    abs(context.origin_latitude) / 60000,
                    abs(context.origin_latitude) % 60000,
                    context.origin_latitude >= 0 ? 'N' : 'S',
                    abs(context.origin_longitude) / 60000,
                    abs(context.origin_longitude) % 60000,
                    context.origin_longitude >= 0 ? 'E' : 'W');
            break;

        case LXN::SECURITY_OLD:
            data += sizeof(*packet.security_old);
            if (data > end)
                return false;

            fprintf(file, "G%22.22s\r\n", packet.security_old->foo);
            break;

        case LXN::SERIAL:
            data += sizeof(*packet.serial);
            if (data > end)
                return false;

            if (!ValidString(packet.serial->serial, sizeof(packet.serial->serial)))
                return false;

            fprintf(file, "A%sFLIGHT:%u\r\nHFDTE%s\r\n",
                    packet.serial->serial, context.flight_no, context.date);
            break;

        case LXN::POSITION_OK:
        case LXN::POSITION_BAD:
            data += sizeof(*packet.position);
            if (data > end)
                return false;

            HandlePosition(file, context, *packet.position);
            break;

        case LXN::SECURITY:
            data += sizeof(*packet.security);
            if (data > end ||
                    packet.security->length > sizeof(packet.security->foo))
                return false;

            if (packet.security->type == LXN::SECURITY_HIGH)
                ch = '2';
            else if (packet.security->type == LXN::SECURITY_MED)
                ch = '1';
            else if (packet.security->type == LXN::SECURITY_LOW)
                ch = '0';
            else
                return false;

            fprintf(file, "G%c", ch);

            for (unsigned i = 0; i < packet.security->length; ++i)
                fprintf(file, "%02X", packet.security->foo[i]);

            fprintf(file, "\r\n");
            break;

        case LXN::SECURITY_7000:
            data += sizeof(*packet.security_7000);
            if (data > end ||
                    packet.security_7000->x40 != 0x40)
                return false;

            fprintf(file, "G3");
            for (auto ch : packet.security_7000->line1)
                fprintf(file, "%02X", ch);

            fprintf(file, "\r\nG");
            for (auto ch : packet.security_7000->line2)
                fprintf(file, "%02X", ch);

            fprintf(file, "\r\nG");
            for (auto ch : packet.security_7000->line3)
                fprintf(file, "%02X", ch);

            fprintf(file, "\r\n");
            break;

        case LXN::COMPETITION_CLASS:
            data += sizeof(*packet.competition_class);
            if (data > end)
                return false;

            if (!ValidString(packet.competition_class->class_id,
                             sizeof(packet.competition_class->class_id)))
                return false;

            if (context.flight_info.competition_class_id == 7)
                fprintf(file,
                        "HFFXA%03d\r\n"
                        "HFPLTPILOT:%s\r\n"
                        "HFGTYGLIDERTYPE:%s\r\n"
                        "HFGIDGLIDERID:%s\r\n"
                        "HFDTM%03dGPSDATUM:%s\r\n"
                        "HFCIDCOMPETITIONID:%s\r\n"
                        "HFCCLCOMPETITIONCLASS:%s\r\n"
                        "HFGPSGPS:%s\r\n",
                        context.flight_info.fix_accuracy,
                        context.flight_info.pilot,
                        context.flight_info.glider,
                        context.flight_info.registration,
                        context.flight_info.gps_date,
                        LXN::FormatGPSDate(context.flight_info.gps_date),
                        context.flight_info.competition_class,
                        packet.competition_class->class_id,
                        context.flight_info.gps);
            break;

        case LXN::TASK:
            data += sizeof(*packet.task);
            if (data > end)
                return false;

            context.time = FromBE32(packet.task->time);

            // from a valid IGC file read with LXe:
            // C 11 08 11 14 11 18 11 08 11 0001 -2

            fprintf(file, "C%02d%02d%02d%02d%02d%02d"
                    "%02d%02d%02d" "%04d%02d\r\n",
                    packet.task->day, packet.task->month, packet.task->year,
                    context.time / 3600, context.time % 3600 / 60, context.time % 60,
                    packet.task->day2, packet.task->month2, packet.task->year2,
                    FromBE16(packet.task->task_id), packet.task->num_tps);

            for (unsigned i = 0; i < sizeof(packet.task->usage); ++i) {
                if (packet.task->usage[i]) {
                    int latitude = (int32_t)FromBE32(packet.task->latitude[i]);
                    int longitude = (int32_t)FromBE32(packet.task->longitude[i]);

                    if (!ValidString(packet.task->name[i], sizeof(packet.task->name[i])))
                        return false;

                    fprintf(file, "C%02d%05d%c" "%03d%05d%c" "%s\r\n",
                            abs(latitude) / 60000, abs(latitude) % 60000,
                            latitude >= 0 ?  'N' : 'S',
                            abs(longitude) / 60000, abs(longitude) % 60000,
                            longitude >= 0 ? 'E' : 'W',
                            packet.task->name[i]);
                }
            }
            break;

        case LXN::EVENT:
            data += sizeof(*packet.event);
            if (data > end ||
                    !ValidString(packet.event->foo, sizeof(packet.event->foo)))
                return false;

            context.event = *packet.event;
            context.is_event = true;
            break;

        case LXN::B_EXT:
            data += sizeof(*packet.b_ext) +
                    context.b_ext.num * sizeof(packet.b_ext->data[0]);
            if (data > end)
                return false;

            for (unsigned i = 0; i < context.b_ext.num; ++i)
                fprintf(file, "%0*u",
                        (int)context.b_ext.extensions[i].width,
                        FromBE16(packet.b_ext->data[i]));

            fprintf(file, "\r\n");
            break;

        case LXN::K_EXT:
            data += sizeof(*packet.k_ext) +
                    context.k_ext.num * sizeof(packet.k_ext->data[0]);
            if (data > end)
                return false;

            l = context.time + packet.k_ext->foo;
            fprintf(file, "K%02d%02d%02d",
                    l / 3600, l % 3600 / 60, l % 60);

            for (unsigned i = 0; i < context.k_ext.num; ++i)
                fprintf(file, "%0*u",
                        context.k_ext.extensions[i].width,
                        FromBE16(packet.k_ext->data[i]));

            fprintf(file, "\r\n");
            break;

        case LXN::DATE:
            data += sizeof(*packet.date);
            if (data > end ||
                    packet.date->day > 31 || packet.date->month > 12)
                return false;

            snprintf(context.date, sizeof(context.date),
                     "%02d%02d%02d",
                     packet.date->day % 100, packet.date->month % 100,
                     FromBE16(packet.date->year));
            break;

        case LXN::FLIGHT_INFO:
            data += sizeof(*packet.flight_info);
            if (data > end ||
                    !ValidString(packet.flight_info->pilot,
                                 sizeof(packet.flight_info->pilot)) ||
                    !ValidString(packet.flight_info->glider,
                                 sizeof(packet.flight_info->glider)) ||
                    !ValidString(packet.flight_info->registration,
                                 sizeof(packet.flight_info->registration)) ||
                    !ValidString(packet.flight_info->competition_class,
                                 sizeof(packet.flight_info->competition_class)) ||
                    !ValidString(packet.flight_info->gps, sizeof(packet.flight_info->gps)))
                return false;

            if (packet.flight_info->competition_class_id > 7)
                return false;

            if (packet.flight_info->competition_class_id < 7)
                fprintf(file,
                        "HFFXA%03d\r\n"
                        "HFPLTPILOT:%s\r\n"
                        "HFGTYGLIDERTYPE:%s\r\n"
                        "HFGIDGLIDERID:%s\r\n"
                        "HFDTM%03dGPSDATUM:%s\r\n"
                        "HFCIDCOMPETITIONID:%s\r\n"
                        "HFCCLCOMPETITIONCLASS:%s\r\n"
                        "HFGPSGPS:%s\r\n",
                        packet.flight_info->fix_accuracy,
                        packet.flight_info->pilot,
                        packet.flight_info->glider,
                        packet.flight_info->registration,
                        packet.flight_info->gps_date,
                        LXN::FormatGPSDate(packet.flight_info->gps_date),
                        packet.flight_info->competition_class,
                        LXN::FormatCompetitionClass(packet.flight_info->competition_class_id),
                        packet.flight_info->gps);

            context.flight_info = *packet.flight_info;
            break;

        case LXN::K_EXT_CONFIG:
            data += sizeof(*packet.ext_config);
            if (data > end)
                return false;

            HandleExtConfig(file, *packet.ext_config, context.k_ext, 'J', 8);
            break;

        case LXN::B_EXT_CONFIG:
            data += sizeof(*packet.ext_config);
            if (data > end)
                return false;

            HandleExtConfig(file, *packet.ext_config, context.b_ext, 'I', 36);
            break;

#ifdef __clang__
#pragma GCC diagnostic ignored "-Wcovered-switch-default"
#endif
        default:
            if (*packet.cmd < 0x40) {
                data += sizeof(*packet.string);
                if (data > end)
                    return false;

                data += packet.string->length;
                if (data > end)
                    return false;

                fprintf(file, "%.*s\r\n",
                        (int)packet.string->length, packet.string->value);

                if (packet.string->length >= 12 + sizeof(context.vendor) &&
                        memcmp(packet.string->value, "HFFTYFRTYPE:", 12) == 0)
                    memcpy(context.vendor, packet.string->value + 12, sizeof(context.vendor));
            } else
                return false;
        }
    }

    return false;
}
Beispiel #9
0
static constexpr Angle
ImportAngle(int32_t src)
{
    return Angle::Degrees(int32_t(FromBE32(src)) / 1000000.);
}
Beispiel #10
0
inline void
Server::OnDatagramReceived(Client &&client,
                           void *data, size_t length)
{
  Header &header = *(Header *)data;
  if (length < sizeof(header))
    return;

  const uint16_t received_crc = FromBE16(header.crc);
  header.crc = 0;

  const uint16_t calculated_crc = UpdateCRC16CCITT(data, length, 0);
  if (received_crc != calculated_crc)
    return;

  client.key = FromBE64(header.key);

  const auto &ping = *(const PingPacket *)data;
  const auto &fix = *(const FixPacket *)data;
  const auto &traffic = *(const TrafficRequestPacket *)data;
  const auto &user_name = *(const UserNameRequestPacket *)data;
  const auto &wave = ((const WaveSubmitPacket *)data)->wave;
  const auto &thermal = ((const ThermalSubmitPacket *)data)->thermal;

  switch ((Type)FromBE16(header.type)) {
  case PING:
    if (length < sizeof(ping))
      return;

    OnPing(client, FromBE16(ping.id));
    break;

  case FIX:
    if (length < sizeof(fix))
      return;

    OnFix(client,
          ImportTimeMs(fix.time),
          fix.flags & ToBE32(FixPacket::FLAG_LOCATION)
          ? ImportGeoPoint(fix.location)
          : ::GeoPoint::Invalid(),
          fix.flags & ToBE32(FixPacket::FLAG_ALTITUDE)
          ? FromBE16(fix.altitude)
          : -1);
    break;

  case TRAFFIC_REQUEST:
    if (length < sizeof(traffic))
      return;

    OnTrafficRequest(client,
                     traffic.flags & ToBE32(TrafficRequestPacket::FLAG_NEAR));
    break;

  case USER_NAME_REQUEST:
    if (length < sizeof(user_name))
      return;

    OnUserNameRequest(client,
                      FromBE32(user_name.user_id));
    break;

  case WAVE_SUBMIT:
    if (length < sizeof(wave))
      return;

    OnWaveSubmit(client,
                 ImportTimeMs(wave.time),
                 ImportGeoPoint(wave.a), ImportGeoPoint(wave.b),
                 (int16_t)FromBE16(wave.bottom_altitude),
                 (int16_t)FromBE16(wave.top_altitude),
                 FromBE16(wave.lift) / 256.);
    break;

  case WAVE_REQUEST:
    OnWaveRequest(client);
    break;

  case THERMAL_SUBMIT:
    if (length < sizeof(thermal))
      return;

    OnThermalSubmit(client,
                    ImportTimeMs(thermal.time),
                    ImportGeoPoint(thermal.bottom_location),
                    (int16_t)FromBE16(thermal.bottom_altitude),
                    ImportGeoPoint(thermal.top_location),
                    (int16_t)FromBE16(thermal.top_altitude),
                    FromBE16(thermal.lift) / 256.);
    break;

  case THERMAL_REQUEST:
    OnThermalRequest(client);
    break;

  case ACK:
  case TRAFFIC_RESPONSE:
  case USER_NAME_RESPONSE:
  case WAVE_RESPONSE:
  case THERMAL_RESPONSE:
    /* these are server-to-client packets; ignore them */
    break;
  }
}