nmea_s * nmea_parse(char *sentence, int length, int check_checksum) { nmea_t type = nmea_get_type(sentence); if (NMEA_UNKNOWN == type) { return (nmea_s *) NULL; } int n_vals; int val_index = 0; char *value; char *values[255]; nmea_parser_module_s *parser; /* Validate */ if (-1 == nmea_validate(sentence, length, check_checksum)) { return (nmea_s *) NULL; } /* Crop sentence from type word and checksum */ char *val_string = _crop_sentence(sentence, length); if (NULL == val_string) { return (nmea_s *) NULL; } /* Split the sentence into values */ n_vals = _split_string(val_string, values); if (0 == n_vals) { return (nmea_s *) NULL; } /* Get the right parser */ parser = nmea_get_parser_by_type(type); if (NULL == parser) { return (nmea_s *) NULL; } /* Allocate memory for parsed data */ parser->allocate_data((nmea_parser_s *) parser); if (NULL == parser->parser.data) { return (nmea_s *) NULL; } /* Set default values */ parser->set_default((nmea_parser_s *) parser); parser->errors = 0; /* Loop through the values and parse them... */ while (val_index < n_vals) { value = values[val_index]; if (-1 == _is_value_set(value)) { val_index++; continue; } if (-1 == parser->parse((nmea_parser_s *) parser, value, val_index)) { parser->errors++; } val_index++; } parser->parser.data->type = type; parser->parser.data->errors = parser->errors; return parser->parser.data; }
int MtkGps::parse_nmea(const char *str) { if (!nmea_is_valid(str)) return -1; int ret, nmea_type = nmea_get_type(str); if (nmea_type == NMEA_SEN_GGA) { ret = nmea_parse_gpgga(str, &gga); if (ret == 0) { fix_time = gga.time; fix_msec = gga.millisec; valid |= NMEA_SEN_GGA; } return ret; } if (nmea_type == NMEA_SEN_RMC) { ret = nmea_parse_gprmc(str, &rmc); if (ret == 0) { double frac; latitude = rmc.latitude / 100.0; frac = modf(latitude, &latitude); latitude += frac/0.6; if (rmc.flags & NMEA_LAT_SOUTH) latitude = -latitude; longitude = rmc.longitude / 100.0; frac = modf(longitude, &longitude); longitude += frac/0.6; if (rmc.flags & NMEA_LON_WEST) longitude = -longitude; fix_time = rmc.time; fix_msec = rmc.millisec; fix_date = rmc.date; valid |= NMEA_SEN_RMC; } return ret; } if (nmea_type == NMEA_SEN_GLL) { ret = nmea_parse_gpgll(str, &gll); if (ret == 0) { fix_time = gll.time; fix_msec = gll.millisec; valid |= NMEA_SEN_GLL; } return ret; } if (nmea_type == NMEA_SEN_VTG) { ret = nmea_parse_gpvtg(str, &vtg); if (ret == 0) valid |= NMEA_SEN_VTG; return ret; } if (nmea_type == NMEA_SEN_GSA) { ret = nmea_parse_gpgsa(str, &gsa); if (ret == 0) valid |= NMEA_SEN_GSA; return ret; } if (nmea_type == NMEA_SEN_ZDA) { ret = nmea_parse_gpzda(str, &zda); if (ret == 0) { fix_date = zda.date; fix_time = zda.time; fix_msec = zda.millisec; valid |= NMEA_SEN_ZDA; } return ret; } if (nmea_type == NMEA_SEN_GSV) { ret = nmea_parse_gpgsv(str, gsv, &ngsv, &igsv); if (ret == 0) valid |= NMEA_SEN_GSV; return ret; } if (nmea_type == NMEA_SEN_MCHN) { ret = nmea_parse_mtkchn(str, chn); if (ret == 0) valid |= NMEA_SEN_MCHN; return ret; } // firmware release info if (nmea_type == NMEA_SEN_MTK) { int type = getMtkPType(nmea); if (type == PMTK_DT_RELEASE) { if (release != NULL) free((void *)release); char *end = strchr(nmea, '*'); if (end) *end = '\0'; release = strdup(nmea + 9); return 0; } } return 0; }