/** * \brief Parse GGA packet from buffer. * @param buff a constant character pointer of packet buffer. * @param buff_sz buffer size. * @param pack a pointer of packet which will filled by function. * @return 1 (true) - if parsed successfully or 0 (false) - if fail. */ int nmea_parse_GPGGA(const char *buff, int buff_sz, nmeaGPGGA *pack) { char time_buff[NMEA_TIMEPARSE_BUF]; NMEA_ASSERT(buff && pack); memset(pack, 0, sizeof(nmeaGPGGA)); nmea_trace_buff(buff, buff_sz); if(14 != nmea_scanf(buff, buff_sz, "$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))) { nmea_error("GPGGA parse error!"); return 0; } if(0 != _nmea_parse_time(&time_buff[0], (int)strlen(&time_buff[0]), &(pack->utc))) { nmea_error("GPGGA time parse error!"); return 0; } return 1; }
/** * \brief Parse RMC packet from buffer. * @param buff a constant character pointer of packet buffer. * @param buff_sz buffer size. * @param pack a pointer of packet which will filled by function. * @return 1 (true) - if parsed successfully or 0 (false) - if fail. */ int nmea_parse_GPRMC( const char *buff, int buff_sz, nmeaGPRMC *pack ) { int nsen; char type; char time_buff[NMEA_TIMEPARSE_BUF]; NMEA_ASSERT( buff && pack ); memset( pack, 0, sizeof( nmeaGPRMC ) ); nmea_trace_buff( buff, buff_sz ); nsen = nmea_scanf( buff, buff_sz, "$G%CRMC,%s,%C,%f,%C,%f,%C,%f,%f,%2d%2d%2d,%f,%C,%C*", &( type ), &( time_buff[0] ), &( pack->status ), &( pack->lat ), &( pack->ns ), &( pack->lon ), &( pack->ew ), &( pack->speed ), &( pack->direction ), &( pack->utc.day ), &( pack->utc.mon ), &( pack->utc.year ), &( pack->declination ), &( pack->declin_ew ), &( pack->mode ) ); if ( nsen != 14 && nsen != 15 ) { nmea_error( "GPRMC parse error!" ); return 0; } if ( type != 'P' && type != 'N' ) { nmea_error( "G?RMC invalid type " ); return 0; } if ( 0 != _nmea_parse_time( &time_buff[0], ( int )strlen( &time_buff[0] ), &( pack->utc ) ) ) { nmea_error( "GPRMC time parse error!" ); return 0; } if ( pack->utc.year < 90 ) pack->utc.year += 100; pack->utc.mon -= 1; return 1; }
/** * Parse a GPRMC sentence from a string * * @param s the string * @param len the length of the string * @param pack a pointer to the result structure * @return 1 (true) - if parsed successfully or 0 (false) otherwise. */ int nmea_parse_GPRMC(const char *s, const int len, nmeaGPRMC *pack) { int token_count; char time_buff[NMEA_TIMEPARSE_BUF]; int date; size_t time_buff_len = 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; }
/** * Parse a GPGGA sentence from a string * * @param s the string * @param len the length of the string * @param pack a pointer to the result structure * @return 1 (true) - if parsed successfully or 0 (false) otherwise. */ int nmea_parse_GPGGA(const char *s, const int len, nmeaGPGGA *pack) { int token_count; char time_buff[NMEA_TIMEPARSE_BUF]; size_t time_buff_len = 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; }