pud: nmealib: fix isInvalidNMEACharacter function
authorFerry Huberts <ferry.huberts@pelagic.nl>
Fri, 21 Mar 2014 11:27:06 +0000 (12:27 +0100)
committerFerry Huberts <ferry.huberts@pelagic.nl>
Fri, 21 Mar 2014 11:27:24 +0000 (12:27 +0100)
Signed-off-by: Ferry Huberts <ferry.huberts@pelagic.nl>
lib/pud/nmealib/src/parse.c

index 6589912..2b11b92 100644 (file)
  * @return true on success, false otherwise
  */
 static bool _nmea_parse_time(const char *s, const int len, nmeaTIME *t) {
-       assert(s);
-       assert(t);
-
-       if (len == (sizeof("hhmmss") - 1)) {
-               t->hsec = 0;
-               return (3 == nmea_scanf(s, len, "%2d%2d%2d", &t->hour, &t->min, &t->sec));
-       }
-
-       if (len == (sizeof("hhmmss.s") - 1)) {
-               if (4 == nmea_scanf(s, len, "%2d%2d%2d.%d", &t->hour, &t->min, &t->sec, &t->hsec)) {
-                       t->hsec *= 10;
-                       return true;
-               }
-               return false;
-       }
-
-       if (len == (sizeof("hhmmss.ss") - 1)) {
-               return (4 == nmea_scanf(s, len, "%2d%2d%2d.%d", &t->hour, &t->min, &t->sec, &t->hsec));
-       }
-
-       if (len == (sizeof("hhmmss.sss") - 1)) {
-               if ((4 == nmea_scanf(s, len, "%2d%2d%2d.%d", &t->hour, &t->min, &t->sec, &t->hsec))) {
-                       t->hsec = (t->hsec + 9) / 10;
-                       return true;
-               }
-               return false;
-       }
-
-       nmea_error("Parse error: invalid time format in %s", s);
-       return false;
+  assert(s);
+  assert(t);
+
+  if (len == (sizeof("hhmmss") - 1)) {
+    t->hsec = 0;
+    return (3 == nmea_scanf(s, len, "%2d%2d%2d", &t->hour, &t->min, &t->sec));
+  }
+
+  if (len == (sizeof("hhmmss.s") - 1)) {
+    if (4 == nmea_scanf(s, len, "%2d%2d%2d.%d", &t->hour, &t->min, &t->sec, &t->hsec)) {
+      t->hsec *= 10;
+      return true;
+    }
+    return false;
+  }
+
+  if (len == (sizeof("hhmmss.ss") - 1)) {
+    return (4 == nmea_scanf(s, len, "%2d%2d%2d.%d", &t->hour, &t->min, &t->sec, &t->hsec));
+  }
+
+  if (len == (sizeof("hhmmss.sss") - 1)) {
+    if ((4 == nmea_scanf(s, len, "%2d%2d%2d.%d", &t->hour, &t->min, &t->sec, &t->hsec))) {
+      t->hsec = (t->hsec + 9) / 10;
+      return true;
+    }
+    return false;
+  }
+
+  nmea_error("Parse error: invalid time format in %s", s);
+  return false;
 }
 
 /**
@@ -84,22 +84,22 @@ static bool _nmea_parse_time(const char *s, const int len, nmeaTIME *t) {
  * @return true on success, false otherwise
  */
 static bool _nmea_parse_date(const int date, nmeaTIME *t) {
-       assert(t);
-
-       if ((date < 0) || (date > 999999)) {
-               nmea_error("Parse error: invalid time format in %d", date);
-               return false;
-       }
-
-       t->day = date / 10000;
-       t->mon = (date / 100) % 100;
-       t->mon--;
-       t->year = date % 100;
-       if (t->year < 90) {
-               t->year += 100;
-       }
-
-       return true;
+  assert(t);
+
+  if ((date < 0) || (date > 999999)) {
+    nmea_error("Parse error: invalid time format in %d", date);
+    return false;
+  }
+
+  t->day = date / 10000;
+  t->mon = (date / 100) % 100;
+  t->mon--;
+  t->year = date % 100;
+  if (t->year < 90) {
+    t->year += 100;
+  }
+
+  return true;
 }
 
 /**
@@ -116,17 +116,17 @@ static bool _nmea_parse_date(const int date, nmeaTIME *t) {
  * @return true when valid, false otherwise
  */
 static bool validateTime(const nmeaTIME * t) {
-       if (!t) {
-               return false;
-       }
+  if (!t) {
+    return false;
+  }
 
-       if (!((t->hour >= 0) && (t->hour < 24) && (t->min >= 0) && (t->min < 60) && (t->sec >= 0) && (t->sec <= 60)
-                       && (t->hsec >= 0) && (t->hsec < 100))) {
-               nmea_error("Parse error: invalid time (%d:%d:%d.%d)", t->hour, t->min, t->sec, t->hsec);
-               return false;
-       }
+  if (!((t->hour >= 0) && (t->hour < 24) && (t->min >= 0) && (t->min < 60) && (t->sec >= 0) && (t->sec <= 60)
+      && (t->hsec >= 0) && (t->hsec < 100))) {
+    nmea_error("Parse error: invalid time (%d:%d:%d.%d)", t->hour, t->min, t->sec, t->hsec);
+    return false;
+  }
 
-       return true;
+  return true;
 }
 
 /**
@@ -142,16 +142,16 @@ static bool validateTime(const nmeaTIME * t) {
  * @return true when valid, false otherwise
  */
 static bool validateDate(const nmeaTIME * t) {
-       if (!t) {
-               return false;
-       }
+  if (!t) {
+    return false;
+  }
 
-       if (!((t->year >= 90) && (t->year <= 189) && (t->mon >= 0) && (t->mon <= 11) && (t->day >= 1) && (t->day <= 31))) {
-               nmea_error("Parse error: invalid date (%d-%d-%d - D-M-Y)", t->day, t->mon, t->year);
-               return false;
-       }
+  if (!((t->year >= 90) && (t->year <= 189) && (t->mon >= 0) && (t->mon <= 11) && (t->day >= 1) && (t->day <= 31))) {
+    nmea_error("Parse error: invalid date (%d-%d-%d - D-M-Y)", t->day, t->mon, t->year);
+    return false;
+  }
 
-       return true;
+  return true;
 }
 
 /**
@@ -167,25 +167,25 @@ static bool validateDate(const nmeaTIME * t) {
  * @return true when valid, false otherwise
  */
 static bool validateNSEW(char * c, const bool ns) {
-       if (!c) {
-               return false;
-       }
-
-       *c = toupper(*c);
-
-       if (ns) {
-               if (!((*c == 'N') || (*c == 'S'))) {
-                       nmea_error("Parse error: invalid north/south (%c)", *c);
-                       return false;
-               }
-       } else {
-               if (!((*c == 'E') || (*c == 'W'))) {
-                       nmea_error("Parse error: invalid east/west (%c)", *c);
-                       return false;
-               }
-       }
-
-       return true;
+  if (!c) {
+    return false;
+  }
+
+  *c = toupper(*c);
+
+  if (ns) {
+    if (!((*c == 'N') || (*c == 'S'))) {
+      nmea_error("Parse error: invalid north/south (%c)", *c);
+      return false;
+    }
+  } else {
+    if (!((*c == 'E') || (*c == 'W'))) {
+      nmea_error("Parse error: invalid east/west (%c)", *c);
+      return false;
+    }
+  }
+
+  return true;
 }
 
 /**
@@ -211,19 +211,19 @@ static bool validateNSEW(char * c, const bool ns) {
  * @return true when valid, false otherwise
  */
 static bool validateMode(char * c) {
-       if (!c) {
-               return false;
-       }
+  if (!c) {
+    return false;
+  }
 
-       *c = toupper(*c);
+  *c = toupper(*c);
 
-       if (!((*c == 'A') || (*c == 'D') || (*c == 'E') || (*c == 'F') || (*c == 'M') || (*c == 'N') || (*c == 'P')
-                       || (*c == 'R') || (*c == 'S'))) {
-               nmea_error("Parse error: invalid mode (%c)", *c);
-               return false;
-       }
+  if (!((*c == 'A') || (*c == 'D') || (*c == 'E') || (*c == 'F') || (*c == 'M') || (*c == 'N') || (*c == 'P')
+      || (*c == 'R') || (*c == 'S'))) {
+    nmea_error("Parse error: invalid mode (%c)", *c);
+    return false;
+  }
 
-       return true;
+  return true;
 }
 
 /**
@@ -237,12 +237,25 @@ static bool validateMode(char * c) {
  * - NULL otherwise
  */
 const char * isInvalidNMEACharacter(const char * c) {
-       static const char invalidChars[] = { '$', '*', '!', '\\', '^', '~' };
-       static const char * invalidNonAsciiCharsName = "non-ascii character";
-       static const char * invalidCharsNames[] = { "sentence delimiter ($)", "checksum field delimiter (*)", "comma (,)",
-                       "exclamation mark (!)", "backslash (\\)", "power (^)", "tilde (~)" };
-
-       size_t charIndex;
+  static const char * invalidNonAsciiCharsName = "non-ascii character";
+  static const char invalidChars[] = {
+      '$',
+      '*',
+      '!',
+      '\\',
+      '^',
+      '~'
+  };
+  static const char * invalidCharsNames[] = {
+      "sentence delimiter ($)",
+      "checksum field delimiter (*)",
+      "exclamation mark (!)",
+      "backslash (\\)",
+      "power (^)",
+      "tilde (~)"
+  };
+
+  size_t charIndex;
 
   if (!((*c >= 32) && (*c <= 126))) {
     return invalidNonAsciiCharsName;
@@ -271,20 +284,20 @@ const char * isInvalidNMEACharacter(const char * c) {
  * - NULL otherwise
  */
 const char * nmea_parse_sentence_has_invalid_chars(const char * s, const size_t len) {
-       size_t i;
+  size_t i;
 
-       if (!s || !len) {
-               return NULL;
-       }
+  if (!s || !len) {
+    return NULL;
+  }
 
-       for (i = 0; i < len; i++) {
-               const char * invalidCharName = isInvalidNMEACharacter(&s[i]);
-               if (invalidCharName) {
-                 return invalidCharName;
-               }
-       }
+  for (i = 0; i < len; i++) {
+    const char * invalidCharName = isInvalidNMEACharacter(&s[i]);
+    if (invalidCharName) {
+      return invalidCharName;
+    }
+  }
 
-       return NULL;
+  return NULL;
 }
 
 /**
@@ -296,23 +309,23 @@ const char * nmea_parse_sentence_has_invalid_chars(const char * s, const size_t
  * @return The packet type (or GPNON when it could not be determined)
  */
 enum nmeaPACKTYPE nmea_parse_get_sentence_type(const char *s, const int len) {
-       static const char *pheads[] = { "GPGGA", "GPGSA", "GPGSV", "GPRMC", "GPVTG" };
-       static const enum nmeaPACKTYPE types[] = { GPGGA, GPGSA, GPGSV, GPRMC, GPVTG };
-       unsigned int i;
+  static const char *pheads[] = { "GPGGA", "GPGSA", "GPGSV", "GPRMC", "GPVTG" };
+  static const enum nmeaPACKTYPE types[] = { GPGGA, GPGSA, GPGSV, GPRMC, GPVTG };
+  unsigned int i;
 
-       assert(s);
+  assert(s);
 
-       if (len < 5) {
-               return GPNON;
-       }
+  if (len < 5) {
+    return GPNON;
+  }
 
-       for (i = 0; i < (sizeof(types) / sizeof(types[0])); i++) {
-               if (!memcmp(s, pheads[i], 5)) {
-                       return types[i];
-               }
-       }
+  for (i = 0; i < (sizeof(types) / sizeof(types[0])); i++) {
+    if (!memcmp(s, pheads[i], 5)) {
+      return types[i];
+    }
+  }
 
-       return GPNON;
+  return GPNON;
 }
 
 /**
@@ -325,109 +338,109 @@ enum nmeaPACKTYPE nmea_parse_get_sentence_type(const char *s, const int len) {
  * @return 1 (true) - if parsed successfully or 0 (false) otherwise.
  */
 int nmea_parse_GPGGA(const char *s, const int len, bool has_checksum, nmeaGPGGA *pack) {
-       int token_count;
-       char time_buff[NMEA_TIMEPARSE_BUF];
-       size_t time_buff_len = 0;
-
-       if (!has_checksum) {
-         return 0;
-       }
-
-       assert(s);
-       assert(pack);
-
-       nmea_trace_buff(s, len);
-
-       /*
-        * Clear before parsing, to be able to detect absent fields
-        */
-       time_buff[0] = '\0';
-       pack->present = 0;
-       pack->utc.hour = -1;
-       pack->utc.min = -1;
-       pack->utc.sec = -1;
-       pack->utc.hsec = -1;
-       pack->lat = NAN;
-       pack->ns = 0;
-       pack->lon = NAN;
-       pack->ew = 0;
-       pack->sig = -1;
-       pack->satinuse = -1;
-       pack->HDOP = NAN;
-       pack->elv = NAN;
-       pack->elv_units = 0;
-       pack->diff = 0;                 /* ignored */
-       pack->diff_units = 0;   /* ignored */
-       pack->dgps_age = 0;             /* ignored */
-       pack->dgps_sid = 0;             /* ignored */
-
-       /* parse */
-       token_count = nmea_scanf(s, len, "$GPGGA,%s,%f,%c,%f,%c,%d,%d,%f,%f,%c,%f,%c,%f,%d*", &time_buff[0], &pack->lat,
-                       &pack->ns, &pack->lon, &pack->ew, &pack->sig, &pack->satinuse, &pack->HDOP, &pack->elv, &pack->elv_units,
-                       &pack->diff, &pack->diff_units, &pack->dgps_age, &pack->dgps_sid);
-
-       /* see that we have enough tokens */
-       if (token_count != 14) {
-               nmea_error("GPGGA parse error: need 14 tokens, got %d in %s", token_count, s);
-               return 0;
-       }
-
-       /* determine which fields are present and validate them */
-
-       time_buff_len = strlen(&time_buff[0]);
-       if (time_buff_len > (NMEA_TIMEPARSE_BUF - 1))
-               time_buff_len = NMEA_TIMEPARSE_BUF - 1;
-       if (time_buff_len) {
-               if (!_nmea_parse_time(&time_buff[0], time_buff_len, &pack->utc)) {
-                       return 0;
-               }
-
-               if (!validateTime(&pack->utc)) {
-                       return 0;
-               }
-
-               nmea_INFO_set_present(&pack->present, UTCTIME);
-       }
-       if (!isnan(pack->lat) && (pack->ns)) {
-               if (!validateNSEW(&pack->ns, true)) {
-                       return 0;
-               }
-
-               nmea_INFO_set_present(&pack->present, LAT);
-       }
-       if (!isnan(pack->lon) && (pack->ew)) {
-               if (!validateNSEW(&pack->ew, false)) {
-                       return 0;
-               }
-
-               nmea_INFO_set_present(&pack->present, LON);
-       }
-       if (pack->sig != -1) {
-               if (!((pack->sig >= NMEA_SIG_FIRST) && (pack->sig <= NMEA_SIG_LAST))) {
-                       nmea_error("GPGGA parse error: invalid signal %d, expected [%d, %d]", pack->sig, NMEA_SIG_FIRST, NMEA_SIG_LAST);
-                       return 0;
-               }
-
-               nmea_INFO_set_present(&pack->present, SIG);
-       }
-       if (pack->satinuse != -1) {
-               nmea_INFO_set_present(&pack->present, SATINUSECOUNT);
-       }
-       if (!isnan(pack->HDOP)) {
-               nmea_INFO_set_present(&pack->present, HDOP);
-       }
-       if (!isnan(pack->elv) && (pack->elv_units)) {
-               if (pack->elv_units != 'M') {
-                       nmea_error("GPGGA parse error: invalid elevation unit (%c)", pack->elv_units);
-                       return 0;
-               }
-
-               nmea_INFO_set_present(&pack->present, ELV);
-       }
-       /* ignore diff and diff_units */
-       /* ignore dgps_age and dgps_sid */
-
-       return 1;
+  int token_count;
+  char time_buff[NMEA_TIMEPARSE_BUF];
+  size_t time_buff_len = 0;
+
+  if (!has_checksum) {
+    return 0;
+  }
+
+  assert(s);
+  assert(pack);
+
+  nmea_trace_buff(s, len);
+
+  /*
+   * Clear before parsing, to be able to detect absent fields
+   */
+  time_buff[0] = '\0';
+  pack->present = 0;
+  pack->utc.hour = -1;
+  pack->utc.min = -1;
+  pack->utc.sec = -1;
+  pack->utc.hsec = -1;
+  pack->lat = NAN;
+  pack->ns = 0;
+  pack->lon = NAN;
+  pack->ew = 0;
+  pack->sig = -1;
+  pack->satinuse = -1;
+  pack->HDOP = NAN;
+  pack->elv = NAN;
+  pack->elv_units = 0;
+  pack->diff = 0;     /* ignored */
+  pack->diff_units = 0; /* ignored */
+  pack->dgps_age = 0;   /* ignored */
+  pack->dgps_sid = 0;   /* ignored */
+
+  /* parse */
+  token_count = nmea_scanf(s, len, "$GPGGA,%s,%f,%c,%f,%c,%d,%d,%f,%f,%c,%f,%c,%f,%d*", &time_buff[0], &pack->lat,
+      &pack->ns, &pack->lon, &pack->ew, &pack->sig, &pack->satinuse, &pack->HDOP, &pack->elv, &pack->elv_units,
+      &pack->diff, &pack->diff_units, &pack->dgps_age, &pack->dgps_sid);
+
+  /* see that we have enough tokens */
+  if (token_count != 14) {
+    nmea_error("GPGGA parse error: need 14 tokens, got %d in %s", token_count, s);
+    return 0;
+  }
+
+  /* determine which fields are present and validate them */
+
+  time_buff_len = strlen(&time_buff[0]);
+  if (time_buff_len > (NMEA_TIMEPARSE_BUF - 1))
+    time_buff_len = NMEA_TIMEPARSE_BUF - 1;
+  if (time_buff_len) {
+    if (!_nmea_parse_time(&time_buff[0], time_buff_len, &pack->utc)) {
+      return 0;
+    }
+
+    if (!validateTime(&pack->utc)) {
+      return 0;
+    }
+
+    nmea_INFO_set_present(&pack->present, UTCTIME);
+  }
+  if (!isnan(pack->lat) && (pack->ns)) {
+    if (!validateNSEW(&pack->ns, true)) {
+      return 0;
+    }
+
+    nmea_INFO_set_present(&pack->present, LAT);
+  }
+  if (!isnan(pack->lon) && (pack->ew)) {
+    if (!validateNSEW(&pack->ew, false)) {
+      return 0;
+    }
+
+    nmea_INFO_set_present(&pack->present, LON);
+  }
+  if (pack->sig != -1) {
+    if (!((pack->sig >= NMEA_SIG_FIRST) && (pack->sig <= NMEA_SIG_LAST))) {
+      nmea_error("GPGGA parse error: invalid signal %d, expected [%d, %d]", pack->sig, NMEA_SIG_FIRST, NMEA_SIG_LAST);
+      return 0;
+    }
+
+    nmea_INFO_set_present(&pack->present, SIG);
+  }
+  if (pack->satinuse != -1) {
+    nmea_INFO_set_present(&pack->present, SATINUSECOUNT);
+  }
+  if (!isnan(pack->HDOP)) {
+    nmea_INFO_set_present(&pack->present, HDOP);
+  }
+  if (!isnan(pack->elv) && (pack->elv_units)) {
+    if (pack->elv_units != 'M') {
+      nmea_error("GPGGA parse error: invalid elevation unit (%c)", pack->elv_units);
+      return 0;
+    }
+
+    nmea_INFO_set_present(&pack->present, ELV);
+  }
+  /* ignore diff and diff_units */
+  /* ignore dgps_age and dgps_sid */
+
+  return 1;
 }
 
 /**
@@ -440,75 +453,75 @@ int nmea_parse_GPGGA(const char *s, const int len, bool has_checksum, nmeaGPGGA
  * @return 1 (true) - if parsed successfully or 0 (false) otherwise.
  */
 int nmea_parse_GPGSA(const char *s, const int len, bool has_checksum, nmeaGPGSA *pack) {
-       int token_count;
-       int i;
-
-       if (!has_checksum) {
-         return 0;
-       }
-
-       assert(s);
-       assert(pack);
-
-       nmea_trace_buff(s, len);
-
-       /*
-        * Clear before parsing, to be able to detect absent fields
-        */
-       pack->present = 0;
-       pack->fix_mode = 0;
-       pack->fix_type = -1;
-       for (i = 0; i < NMEA_MAXSAT; i++) {
-               pack->sat_prn[i] = 0;
-       }
-       pack->PDOP = NAN;
-       pack->HDOP = NAN;
-       pack->VDOP = NAN;
-
-       /* parse */
-       token_count = nmea_scanf(s, len, "$GPGSA,%c,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%f,%f,%f*", &pack->fix_mode,
-                       &pack->fix_type, &pack->sat_prn[0], &pack->sat_prn[1], &pack->sat_prn[2], &pack->sat_prn[3],
-                       &pack->sat_prn[4], &pack->sat_prn[5], &pack->sat_prn[6], &pack->sat_prn[7], &pack->sat_prn[8],
-                       &pack->sat_prn[9], &pack->sat_prn[10], &pack->sat_prn[11], &pack->PDOP, &pack->HDOP, &pack->VDOP);
-
-       /* see that we have enough tokens */
-       if (token_count != 17) {
-               nmea_error("GPGSA parse error: need 17 tokens, got %d in %s", token_count, s);
-               return 0;
-       }
-
-       /* determine which fields are present and validate them */
-
-       pack->fix_mode = toupper(pack->fix_mode);
-       if (!((pack->fix_mode == 'A') || (pack->fix_mode == 'M'))) {
-               nmea_error("GPGSA parse error: invalid fix mode (%c)", pack->fix_mode);
-               return 0;
-       }
-       if (pack->fix_type != -1) {
-               if (!((pack->fix_type >= NMEA_FIX_FIRST) && (pack->fix_type <= NMEA_FIX_LAST))) {
-                       nmea_error("GPGSA parse error: invalid fix type %d, expected [%d, %d]", pack->fix_type, NMEA_FIX_FIRST, NMEA_FIX_LAST);
-                       return 0;
-               }
-
-               nmea_INFO_set_present(&pack->present, FIX);
-       }
-       for (i = 0; i < NMEA_MAXSAT; i++) {
-               if (pack->sat_prn[i] != 0) {
-                       nmea_INFO_set_present(&pack->present, SATINUSE);
-                       break;
-               }
-       }
-       if (!isnan(pack->PDOP)) {
-               nmea_INFO_set_present(&pack->present, PDOP);
-       }
-       if (!isnan(pack->HDOP)) {
-               nmea_INFO_set_present(&pack->present, HDOP);
-       }
-       if (!isnan(pack->VDOP)) {
-               nmea_INFO_set_present(&pack->present, VDOP);
-       }
-
-       return 1;
+  int token_count;
+  int i;
+
+  if (!has_checksum) {
+    return 0;
+  }
+
+  assert(s);
+  assert(pack);
+
+  nmea_trace_buff(s, len);
+
+  /*
+   * Clear before parsing, to be able to detect absent fields
+   */
+  pack->present = 0;
+  pack->fix_mode = 0;
+  pack->fix_type = -1;
+  for (i = 0; i < NMEA_MAXSAT; i++) {
+    pack->sat_prn[i] = 0;
+  }
+  pack->PDOP = NAN;
+  pack->HDOP = NAN;
+  pack->VDOP = NAN;
+
+  /* parse */
+  token_count = nmea_scanf(s, len, "$GPGSA,%c,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%f,%f,%f*", &pack->fix_mode,
+      &pack->fix_type, &pack->sat_prn[0], &pack->sat_prn[1], &pack->sat_prn[2], &pack->sat_prn[3],
+      &pack->sat_prn[4], &pack->sat_prn[5], &pack->sat_prn[6], &pack->sat_prn[7], &pack->sat_prn[8],
+      &pack->sat_prn[9], &pack->sat_prn[10], &pack->sat_prn[11], &pack->PDOP, &pack->HDOP, &pack->VDOP);
+
+  /* see that we have enough tokens */
+  if (token_count != 17) {
+    nmea_error("GPGSA parse error: need 17 tokens, got %d in %s", token_count, s);
+    return 0;
+  }
+
+  /* determine which fields are present and validate them */
+
+  pack->fix_mode = toupper(pack->fix_mode);
+  if (!((pack->fix_mode == 'A') || (pack->fix_mode == 'M'))) {
+    nmea_error("GPGSA parse error: invalid fix mode (%c)", pack->fix_mode);
+    return 0;
+  }
+  if (pack->fix_type != -1) {
+    if (!((pack->fix_type >= NMEA_FIX_FIRST) && (pack->fix_type <= NMEA_FIX_LAST))) {
+      nmea_error("GPGSA parse error: invalid fix type %d, expected [%d, %d]", pack->fix_type, NMEA_FIX_FIRST, NMEA_FIX_LAST);
+      return 0;
+    }
+
+    nmea_INFO_set_present(&pack->present, FIX);
+  }
+  for (i = 0; i < NMEA_MAXSAT; i++) {
+    if (pack->sat_prn[i] != 0) {
+      nmea_INFO_set_present(&pack->present, SATINUSE);
+      break;
+    }
+  }
+  if (!isnan(pack->PDOP)) {
+    nmea_INFO_set_present(&pack->present, PDOP);
+  }
+  if (!isnan(pack->HDOP)) {
+    nmea_INFO_set_present(&pack->present, HDOP);
+  }
+  if (!isnan(pack->VDOP)) {
+    nmea_INFO_set_present(&pack->present, VDOP);
+  }
+
+  return 1;
 }
 
 /**
@@ -521,81 +534,81 @@ int nmea_parse_GPGSA(const char *s, const int len, bool has_checksum, nmeaGPGSA
  * @return 1 (true) - if parsed successfully or 0 (false) otherwise.
  */
 int nmea_parse_GPGSV(const char *s, const int len, bool has_checksum, nmeaGPGSV *pack) {
-       int token_count;
-       int token_count_expected;
-       int sat_count;
-       int sat_counted = 0;
-
-       if (!has_checksum) {
-         return 0;
-       }
-
-       assert(s);
-       assert(pack);
-
-       nmea_trace_buff(s, len);
-
-       /*
-        * Clear before parsing, to be able to detect absent fields
-        */
-       memset(pack, 0, sizeof(nmeaGPGSV));
-
-       /* parse */
-       token_count = nmea_scanf(s, len, "$GPGSV,%d,%d,%d,"
-                       "%d,%d,%d,%d,"
-                       "%d,%d,%d,%d,"
-                       "%d,%d,%d,%d,"
-                       "%d,%d,%d,%d*", &pack->pack_count, &pack->pack_index, &pack->sat_count, &pack->sat_data[0].id,
-                       &pack->sat_data[0].elv, &pack->sat_data[0].azimuth, &pack->sat_data[0].sig, &pack->sat_data[1].id,
-                       &pack->sat_data[1].elv, &pack->sat_data[1].azimuth, &pack->sat_data[1].sig, &pack->sat_data[2].id,
-                       &pack->sat_data[2].elv, &pack->sat_data[2].azimuth, &pack->sat_data[2].sig, &pack->sat_data[3].id,
-                       &pack->sat_data[3].elv, &pack->sat_data[3].azimuth, &pack->sat_data[3].sig);
-
-       /* return if we have no sentences or sats */
-       if ((pack->pack_count < 1) || (pack->pack_count > NMEA_NSATPACKS) || (pack->pack_index < 1)
-                       || (pack->pack_index > pack->pack_count) || (pack->sat_count < 0) || (pack->sat_count > NMEA_MAXSAT)) {
-               nmea_error("GPGSV parse error: inconsistent pack (count/index/satcount = %d/%d/%d)", pack->pack_count,
-                               pack->pack_index, pack->sat_count);
-               return 0;
-       }
-
-       /* validate all sat settings and count the number of sats in the sentence */
-       for (sat_count = 0; sat_count < NMEA_SATINPACK; sat_count++) {
-               if (pack->sat_data[sat_count].id != 0) {
-                       if ((pack->sat_data[sat_count].id < 0)) {
-                               nmea_error("GPGSV parse error: invalid sat %d id (%d)", sat_count + 1, pack->sat_data[sat_count].id);
-                               return 0;
-                       }
-                       if ((pack->sat_data[sat_count].elv < -90) || (pack->sat_data[sat_count].elv > 90)) {
-                               nmea_error("GPGSV parse error: invalid sat %d elevation (%d)", sat_count + 1, pack->sat_data[sat_count].elv);
-                               return 0;
-                       }
-                       if ((pack->sat_data[sat_count].azimuth < 0) || (pack->sat_data[sat_count].azimuth >= 360)) {
-                               nmea_error("GPGSV parse error: invalid sat %d azimuth (%d)", sat_count + 1, pack->sat_data[sat_count].azimuth);
-                               return 0;
-                       }
-                       if ((pack->sat_data[sat_count].sig < 0) || (pack->sat_data[sat_count].sig > 99)) {
-                               nmea_error("GPGSV parse error: invalid sat %d signal (%d)", sat_count + 1, pack->sat_data[sat_count].sig);
-                               return 0;
-                       }
-                       sat_counted++;
-               }
-       }
-
-       /* see that we have enough tokens */
-       token_count_expected = (sat_counted * 4) + 3;
-       if ((token_count < token_count_expected) || (token_count > (NMEA_SATINPACK * 4 + 3))) {
-               nmea_error("GPGSV parse error: need %d tokens, got %d", token_count_expected, token_count);
-               return 0;
-       }
-
-       /* determine which fields are present and validate them */
-
-       if (pack->sat_count > 0) {
-               nmea_INFO_set_present(&pack->present, SATINVIEW);
-       }
-
-       return 1;
+  int token_count;
+  int token_count_expected;
+  int sat_count;
+  int sat_counted = 0;
+
+  if (!has_checksum) {
+    return 0;
+  }
+
+  assert(s);
+  assert(pack);
+
+  nmea_trace_buff(s, len);
+
+  /*
+   * Clear before parsing, to be able to detect absent fields
+   */
+  memset(pack, 0, sizeof(nmeaGPGSV));
+
+  /* parse */
+  token_count = nmea_scanf(s, len, "$GPGSV,%d,%d,%d,"
+      "%d,%d,%d,%d,"
+      "%d,%d,%d,%d,"
+      "%d,%d,%d,%d,"
+      "%d,%d,%d,%d*", &pack->pack_count, &pack->pack_index, &pack->sat_count, &pack->sat_data[0].id,
+      &pack->sat_data[0].elv, &pack->sat_data[0].azimuth, &pack->sat_data[0].sig, &pack->sat_data[1].id,
+      &pack->sat_data[1].elv, &pack->sat_data[1].azimuth, &pack->sat_data[1].sig, &pack->sat_data[2].id,
+      &pack->sat_data[2].elv, &pack->sat_data[2].azimuth, &pack->sat_data[2].sig, &pack->sat_data[3].id,
+      &pack->sat_data[3].elv, &pack->sat_data[3].azimuth, &pack->sat_data[3].sig);
+
+  /* return if we have no sentences or sats */
+  if ((pack->pack_count < 1) || (pack->pack_count > NMEA_NSATPACKS) || (pack->pack_index < 1)
+      || (pack->pack_index > pack->pack_count) || (pack->sat_count < 0) || (pack->sat_count > NMEA_MAXSAT)) {
+    nmea_error("GPGSV parse error: inconsistent pack (count/index/satcount = %d/%d/%d)", pack->pack_count,
+        pack->pack_index, pack->sat_count);
+    return 0;
+  }
+
+  /* validate all sat settings and count the number of sats in the sentence */
+  for (sat_count = 0; sat_count < NMEA_SATINPACK; sat_count++) {
+    if (pack->sat_data[sat_count].id != 0) {
+      if ((pack->sat_data[sat_count].id < 0)) {
+        nmea_error("GPGSV parse error: invalid sat %d id (%d)", sat_count + 1, pack->sat_data[sat_count].id);
+        return 0;
+      }
+      if ((pack->sat_data[sat_count].elv < -90) || (pack->sat_data[sat_count].elv > 90)) {
+        nmea_error("GPGSV parse error: invalid sat %d elevation (%d)", sat_count + 1, pack->sat_data[sat_count].elv);
+        return 0;
+      }
+      if ((pack->sat_data[sat_count].azimuth < 0) || (pack->sat_data[sat_count].azimuth >= 360)) {
+        nmea_error("GPGSV parse error: invalid sat %d azimuth (%d)", sat_count + 1, pack->sat_data[sat_count].azimuth);
+        return 0;
+      }
+      if ((pack->sat_data[sat_count].sig < 0) || (pack->sat_data[sat_count].sig > 99)) {
+        nmea_error("GPGSV parse error: invalid sat %d signal (%d)", sat_count + 1, pack->sat_data[sat_count].sig);
+        return 0;
+      }
+      sat_counted++;
+    }
+  }
+
+  /* see that we have enough tokens */
+  token_count_expected = (sat_counted * 4) + 3;
+  if ((token_count < token_count_expected) || (token_count > (NMEA_SATINPACK * 4 + 3))) {
+    nmea_error("GPGSV parse error: need %d tokens, got %d", token_count_expected, token_count);
+    return 0;
+  }
+
+  /* determine which fields are present and validate them */
+
+  if (pack->sat_count > 0) {
+    nmea_INFO_set_present(&pack->present, SATINVIEW);
+  }
+
+  return 1;
 }
 
 /**
@@ -608,132 +621,132 @@ int nmea_parse_GPGSV(const char *s, const int len, bool has_checksum, nmeaGPGSV
  * @return 1 (true) - if parsed successfully or 0 (false) otherwise.
  */
 int nmea_parse_GPRMC(const char *s, const int len, bool has_checksum, nmeaGPRMC *pack) {
-       int token_count;
-       char time_buff[NMEA_TIMEPARSE_BUF];
-       int date;
-       size_t time_buff_len = 0;
-
-       if (!has_checksum) {
-         return 0;
-       }
-
-       assert(s);
-       assert(pack);
-
-       nmea_trace_buff(s, len);
-
-       /*
-        * Clear before parsing, to be able to detect absent fields
-        */
-       time_buff[0] = '\0';
-       date = -1;
-       pack->present = 0;
-       pack->utc.year = -1;
-       pack->utc.mon = -1;
-       pack->utc.day = -1;
-       pack->utc.hour = -1;
-       pack->utc.min = -1;
-       pack->utc.sec = -1;
-       pack->utc.hsec = -1;
-       pack->status = 0;
-       pack->lat = NAN;
-       pack->ns = 0;
-       pack->lon = NAN;
-       pack->ew = 0;
-       pack->speed = NAN;
-       pack->track = NAN;
-       pack->magvar = NAN;
-       pack->magvar_ew = 0;
-       pack->mode = 0;
-
-       /* parse */
-       token_count = nmea_scanf(s, len, "$GPRMC,%s,%c,%f,%c,%f,%c,%f,%f,%d,%f,%c,%c*", &time_buff[0], &pack->status,
-                       &pack->lat, &pack->ns, &pack->lon, &pack->ew, &pack->speed, &pack->track, &date,
-                       &pack->magvar, &pack->magvar_ew, &pack->mode);
-
-       /* see that we have enough tokens */
-       if ((token_count != 11) && (token_count != 12)) {
-               nmea_error("GPRMC parse error: need 11 or 12 tokens, got %d in %s", token_count, s);
-               return 0;
-       }
-
-       /* determine which fields are present and validate them */
-
-       time_buff_len = strlen(&time_buff[0]);
-       if (time_buff_len) {
-               if (!_nmea_parse_time(&time_buff[0], time_buff_len, &pack->utc)) {
-                       return 0;
-               }
-
-               if (!validateTime(&pack->utc)) {
-                       return 0;
-               }
-
-               nmea_INFO_set_present(&pack->present, UTCTIME);
-       }
-
-       if (!pack->status) {
-               pack->status = 'V';
-       } else {
-               pack->status = toupper(pack->status);
-               if (!((pack->status == 'A') || (pack->status == 'V'))) {
-                       nmea_error("GPRMC parse error: invalid status (%c)", pack->status);
-                       return 0;
-               }
-       }
-       if (!isnan(pack->lat) && (pack->ns)) {
-               if (!validateNSEW(&pack->ns, true)) {
-                       return 0;
-               }
-
-               nmea_INFO_set_present(&pack->present, LAT);
-       }
-       if (!isnan(pack->lon) && (pack->ew)) {
-               if (!validateNSEW(&pack->ew, false)) {
-                       return 0;
-               }
-
-               nmea_INFO_set_present(&pack->present, LON);
-       }
-       if (!isnan(pack->speed)) {
-               nmea_INFO_set_present(&pack->present, SPEED);
-       }
-       if (!isnan(pack->track)) {
-               nmea_INFO_set_present(&pack->present, TRACK);
-       }
-
-       if (date != -1) {
-               if (!_nmea_parse_date(date, &pack->utc)) {
-                       return 0;
-               }
-
-               if (!validateDate(&pack->utc)) {
-                       return 0;
-               }
-
-               nmea_INFO_set_present(&pack->present, UTCDATE);
-       }
-
-       if (!isnan(pack->magvar) && (pack->magvar_ew)) {
-               if (!validateNSEW(&pack->magvar_ew, false)) {
-                       return 0;
-               }
-
-               nmea_INFO_set_present(&pack->present, MAGVAR);
-       }
-       if (token_count == 11) {
-               pack->mode = 'A';
-       } else {
-               if (!pack->mode) {
-                       pack->mode = 'N';
-               } else {
-                       if (!validateMode(&pack->mode)) {
-                               return 0;
-                       }
-               }
-       }
-
-       return 1;
+  int token_count;
+  char time_buff[NMEA_TIMEPARSE_BUF];
+  int date;
+  size_t time_buff_len = 0;
+
+  if (!has_checksum) {
+    return 0;
+  }
+
+  assert(s);
+  assert(pack);
+
+  nmea_trace_buff(s, len);
+
+  /*
+   * Clear before parsing, to be able to detect absent fields
+   */
+  time_buff[0] = '\0';
+  date = -1;
+  pack->present = 0;
+  pack->utc.year = -1;
+  pack->utc.mon = -1;
+  pack->utc.day = -1;
+  pack->utc.hour = -1;
+  pack->utc.min = -1;
+  pack->utc.sec = -1;
+  pack->utc.hsec = -1;
+  pack->status = 0;
+  pack->lat = NAN;
+  pack->ns = 0;
+  pack->lon = NAN;
+  pack->ew = 0;
+  pack->speed = NAN;
+  pack->track = NAN;
+  pack->magvar = NAN;
+  pack->magvar_ew = 0;
+  pack->mode = 0;
+
+  /* parse */
+  token_count = nmea_scanf(s, len, "$GPRMC,%s,%c,%f,%c,%f,%c,%f,%f,%d,%f,%c,%c*", &time_buff[0], &pack->status,
+      &pack->lat, &pack->ns, &pack->lon, &pack->ew, &pack->speed, &pack->track, &date,
+      &pack->magvar, &pack->magvar_ew, &pack->mode);
+
+  /* see that we have enough tokens */
+  if ((token_count != 11) && (token_count != 12)) {
+    nmea_error("GPRMC parse error: need 11 or 12 tokens, got %d in %s", token_count, s);
+    return 0;
+  }
+
+  /* determine which fields are present and validate them */
+
+  time_buff_len = strlen(&time_buff[0]);
+  if (time_buff_len) {
+    if (!_nmea_parse_time(&time_buff[0], time_buff_len, &pack->utc)) {
+      return 0;
+    }
+
+    if (!validateTime(&pack->utc)) {
+      return 0;
+    }
+
+    nmea_INFO_set_present(&pack->present, UTCTIME);
+  }
+
+  if (!pack->status) {
+    pack->status = 'V';
+  } else {
+    pack->status = toupper(pack->status);
+    if (!((pack->status == 'A') || (pack->status == 'V'))) {
+      nmea_error("GPRMC parse error: invalid status (%c)", pack->status);
+      return 0;
+    }
+  }
+  if (!isnan(pack->lat) && (pack->ns)) {
+    if (!validateNSEW(&pack->ns, true)) {
+      return 0;
+    }
+
+    nmea_INFO_set_present(&pack->present, LAT);
+  }
+  if (!isnan(pack->lon) && (pack->ew)) {
+    if (!validateNSEW(&pack->ew, false)) {
+      return 0;
+    }
+
+    nmea_INFO_set_present(&pack->present, LON);
+  }
+  if (!isnan(pack->speed)) {
+    nmea_INFO_set_present(&pack->present, SPEED);
+  }
+  if (!isnan(pack->track)) {
+    nmea_INFO_set_present(&pack->present, TRACK);
+  }
+
+  if (date != -1) {
+    if (!_nmea_parse_date(date, &pack->utc)) {
+      return 0;
+    }
+
+    if (!validateDate(&pack->utc)) {
+      return 0;
+    }
+
+    nmea_INFO_set_present(&pack->present, UTCDATE);
+  }
+
+  if (!isnan(pack->magvar) && (pack->magvar_ew)) {
+    if (!validateNSEW(&pack->magvar_ew, false)) {
+      return 0;
+    }
+
+    nmea_INFO_set_present(&pack->present, MAGVAR);
+  }
+  if (token_count == 11) {
+    pack->mode = 'A';
+  } else {
+    if (!pack->mode) {
+      pack->mode = 'N';
+    } else {
+      if (!validateMode(&pack->mode)) {
+        return 0;
+      }
+    }
+  }
+
+  return 1;
 }
 
 /**
@@ -746,88 +759,88 @@ int nmea_parse_GPRMC(const char *s, const int len, bool has_checksum, nmeaGPRMC
  * @return 1 (true) - if parsed successfully or 0 (false) otherwise.
  */
 int nmea_parse_GPVTG(const char *s, const int len, bool has_checksum, nmeaGPVTG *pack) {
-       int token_count;
-
-       if (!has_checksum) {
-         return 0;
-       }
-
-       assert(s);
-       assert(pack);
-
-       nmea_trace_buff(s, len);
-
-       /*
-        * Clear before parsing, to be able to detect absent fields
-        */
-       pack->present = 0;
-       pack->track = NAN;
-       pack->track_t = 0;
-       pack->mtrack = NAN;
-       pack->mtrack_m = 0;
-       pack->spn = NAN;
-       pack->spn_n = 0;
-       pack->spk = NAN;
-       pack->spk_k = 0;
-
-       /* parse */
-       token_count = nmea_scanf(s, len, "$GPVTG,%f,%c,%f,%c,%f,%c,%f,%c*", &pack->track, &pack->track_t, &pack->mtrack,
-                       &pack->mtrack_m, &pack->spn, &pack->spn_n, &pack->spk, &pack->spk_k);
-
-       /* see that we have enough tokens */
-       if (token_count != 8) {
-               nmea_error("GPVTG parse error: need 8 tokens, got %d in %s", token_count, s);
-               return 0;
-       }
-
-       /* determine which fields are present and validate them */
-
-       if (!isnan(pack->track) && (pack->track_t)) {
-               pack->track_t = toupper(pack->track_t);
-               if (pack->track_t != 'T') {
-                       nmea_error("GPVTG parse error: invalid track unit, got %c, expected T", pack->track_t);
-                       return 0;
-               }
-
-               nmea_INFO_set_present(&pack->present, TRACK);
-       }
-       if (!isnan(pack->mtrack) && (pack->mtrack_m)) {
-               pack->mtrack_m = toupper(pack->mtrack_m);
-               if (pack->mtrack_m != 'M') {
-                       nmea_error("GPVTG parse error: invalid mtrack unit, got %c, expected M", pack->mtrack_m);
-                       return 0;
-               }
-
-               nmea_INFO_set_present(&pack->present, MTRACK);
-       }
-       if (!isnan(pack->spn) && (pack->spn_n)) {
-               pack->spn_n = toupper(pack->spn_n);
-               if (pack->spn_n != 'N') {
-                       nmea_error("GPVTG parse error: invalid knots speed unit, got %c, expected N", pack->spn_n);
-                       return 0;
-               }
-
-               nmea_INFO_set_present(&pack->present, SPEED);
-
-               if (isnan(pack->spk)) {
-                       pack->spk = pack->spn * NMEA_TUD_KNOTS;
-                       pack->spk_k = 'K';
-               }
-       }
-       if (!isnan(pack->spk) && (pack->spk_k)) {
-               pack->spk_k = toupper(pack->spk_k);
-               if (pack->spk_k != 'K') {
-                       nmea_error("GPVTG parse error: invalid kph speed unit, got %c, expected K", pack->spk_k);
-                       return 0;
-               }
-
-               nmea_INFO_set_present(&pack->present, SPEED);
-
-               if (isnan(pack->spn)) {
-                       pack->spn = pack->spk / NMEA_TUD_KNOTS;
-                       pack->spn_n = 'N';
-               }
-       }
-
-       return 1;
+  int token_count;
+
+  if (!has_checksum) {
+    return 0;
+  }
+
+  assert(s);
+  assert(pack);
+
+  nmea_trace_buff(s, len);
+
+  /*
+   * Clear before parsing, to be able to detect absent fields
+   */
+  pack->present = 0;
+  pack->track = NAN;
+  pack->track_t = 0;
+  pack->mtrack = NAN;
+  pack->mtrack_m = 0;
+  pack->spn = NAN;
+  pack->spn_n = 0;
+  pack->spk = NAN;
+  pack->spk_k = 0;
+
+  /* parse */
+  token_count = nmea_scanf(s, len, "$GPVTG,%f,%c,%f,%c,%f,%c,%f,%c*", &pack->track, &pack->track_t, &pack->mtrack,
+      &pack->mtrack_m, &pack->spn, &pack->spn_n, &pack->spk, &pack->spk_k);
+
+  /* see that we have enough tokens */
+  if (token_count != 8) {
+    nmea_error("GPVTG parse error: need 8 tokens, got %d in %s", token_count, s);
+    return 0;
+  }
+
+  /* determine which fields are present and validate them */
+
+  if (!isnan(pack->track) && (pack->track_t)) {
+    pack->track_t = toupper(pack->track_t);
+    if (pack->track_t != 'T') {
+      nmea_error("GPVTG parse error: invalid track unit, got %c, expected T", pack->track_t);
+      return 0;
+    }
+
+    nmea_INFO_set_present(&pack->present, TRACK);
+  }
+  if (!isnan(pack->mtrack) && (pack->mtrack_m)) {
+    pack->mtrack_m = toupper(pack->mtrack_m);
+    if (pack->mtrack_m != 'M') {
+      nmea_error("GPVTG parse error: invalid mtrack unit, got %c, expected M", pack->mtrack_m);
+      return 0;
+    }
+
+    nmea_INFO_set_present(&pack->present, MTRACK);
+  }
+  if (!isnan(pack->spn) && (pack->spn_n)) {
+    pack->spn_n = toupper(pack->spn_n);
+    if (pack->spn_n != 'N') {
+      nmea_error("GPVTG parse error: invalid knots speed unit, got %c, expected N", pack->spn_n);
+      return 0;
+    }
+
+    nmea_INFO_set_present(&pack->present, SPEED);
+
+    if (isnan(pack->spk)) {
+      pack->spk = pack->spn * NMEA_TUD_KNOTS;
+      pack->spk_k = 'K';
+    }
+  }
+  if (!isnan(pack->spk) && (pack->spk_k)) {
+    pack->spk_k = toupper(pack->spk_k);
+    if (pack->spk_k != 'K') {
+      nmea_error("GPVTG parse error: invalid kph speed unit, got %c, expected K", pack->spk_k);
+      return 0;
+    }
+
+    nmea_INFO_set_present(&pack->present, SPEED);
+
+    if (isnan(pack->spn)) {
+      pack->spn = pack->spk / NMEA_TUD_KNOTS;
+      pack->spn_n = 'N';
+    }
+  }
+
+  return 1;
 }