void nmea_reader_parse(char *line) { switch (minmea_sentence_id(line, false)) { case MINMEA_SENTENCE_RMC: { struct minmea_sentence_rmc frame; if (minmea_parse_rmc(&frame, line)) { D("$xxRMC: raw coordinates and speed: (%d/%d,%d/%d) %d/%d\n", frame.latitude.value, frame.latitude.scale, frame.longitude.value, frame.longitude.scale, frame.speed.value, frame.speed.scale); D("$xxRMC fixed-point coordinates and speed scaled to three decimal places: (%d,%d) %d\n", minmea_rescale(&frame.latitude, 1000), minmea_rescale(&frame.longitude, 1000), minmea_rescale(&frame.speed, 1000)); D("$xxRMC floating point degree coordinates and speed: (%f,%f) %f\n", minmea_tocoord(&frame.latitude), minmea_tocoord(&frame.longitude), minmea_tofloat(&frame.speed)); notifier_set_date_time(frame.date, frame.time); notifier_set_latlong(minmea_tocoord(&frame.latitude), minmea_tocoord(&frame.longitude)); notifier_set_speed(minmea_tofloat(&frame.speed)); notifier_set_bearing(minmea_tofloat(&frame.course)); notifier_push_location(); } else { D("$xxRMC sentence is not parsed\n"); } } break; case MINMEA_SENTENCE_GGA: { struct minmea_sentence_gga frame; if (minmea_parse_gga(&frame, line)) { D("$xxGGA: fix quality: %d\n", frame.fix_quality); D("$xxGGA: latitude: %f\n", minmea_tocoord(&frame.latitude)); D("$xxGGA: longitude: %f\n", minmea_tocoord(&frame.longitude)); D("$xxGGA: fix quality: %d\n", frame.fix_quality); D("$xxGGA: satellites tracked: %d\n", frame.satellites_tracked); D("$xxGGA: hdop: %f\n", minmea_tofloat(&frame.hdop)); D("$xxGGA: altitude: %f %c\n", minmea_tofloat(&frame.altitude), frame.altitude_units); D("$xxGGA: height: %f %c\n", minmea_tofloat(&frame.height), frame.height_units); notifier_set_latlong(minmea_tocoord(&frame.latitude), minmea_tocoord(&frame.longitude)); notifier_set_altitude(minmea_tofloat(&frame.altitude), frame.altitude_units); // TODO figure out how to get accuracy, is it EPE ? // Use hdop value for now notifier_set_accuracy(minmea_tofloat(&frame.hdop)); notifier_push_location(); } else { D("$xxGGA sentence is not parsed\n"); } } break; case MINMEA_SENTENCE_GSA: { struct minmea_sentence_gsa frame; char talker[3]; if (minmea_parse_gsa(&frame, line) && minmea_talker_id(talker, line)) { D("$%sGSA: mode: %c\n", talker, frame.mode); D("$%sGSA: fix type: %d\n", talker, frame.fix_type); D("$%sGSA: pdop: %f\n", talker, minmea_tofloat(&frame.pdop)); D("$%sGSA: hdop: %f\n", talker, minmea_tofloat(&frame.hdop)); D("$%sGSA: vdop: %f\n", talker, minmea_tofloat(&frame.vdop)); notifier_svs_used_ids(frame.sats); notifier_set_accuracy(minmea_tofloat(&frame.hdop)); notifier_push_location(); } } break; case MINMEA_SENTENCE_GSV: { struct minmea_sentence_gsv frame; char talker[3]; if ( minmea_parse_gsv(&frame, line) && minmea_talker_id(talker, line) ) { D("$%sGSV: message %d of %d\n", talker, frame.msg_nr, frame.total_msgs); D("$%sGSV: sattelites in view: %d\n", talker, frame.total_sats); notifier_svs_update_status(talker, frame.msg_nr, frame.total_msgs); notifier_svs_inview(talker, frame.total_sats); for (int i = 0; i < 4; i++) { notifier_svs_append(talker, frame.sats[i].nr, frame.sats[i].elevation, frame.sats[i].azimuth, frame.sats[i].snr); D("$%sGSV: sat nr %d, elevation: %d, azimuth: %d, snr: %d dbm\n", talker, frame.sats[i].nr, frame.sats[i].elevation, frame.sats[i].azimuth, frame.sats[i].snr); } } else { D("$xxGSV sentence is not parsed\n"); } } break; case MINMEA_SENTENCE_VTG: { struct minmea_sentence_vtg frame; if (minmea_parse_vtg(&frame, line)) { D("$xxVTG: true track degrees = %f\n", minmea_tofloat(&frame.true_track_degrees)); D(" magnetic track degrees = %f\n", minmea_tofloat(&frame.magnetic_track_degrees)); D(" speed knots = %f\n", minmea_tofloat(&frame.speed_knots)); D(" speed kph = %f\n", minmea_tofloat(&frame.speed_kph)); notifier_set_speed(minmea_tofloat(&frame.speed_knots)); notifier_set_bearing(minmea_tofloat(&frame.true_track_degrees)); notifier_push_location(); } else { D("$xxVTG sentence is not parsed\n"); } } break; case MINMEA_INVALID: { D("$xxxxx sentence is not valid\n"); } break; default: { D("$xxxxx sentence is not parsed\n"); } break; } }
void decode_NMEA(char *buffer, FILE *fp) { struct timespec next; clock_gettime(CLOCK_MONOTONIC, &next); switch (minmea_sentence_id(buffer, false)) { case MINMEA_SENTENCE_RMC: { struct minmea_sentence_rmc frame; if (minmea_parse_rmc(&frame, buffer)) { fprintf(fp, "$RMC: %ld.%ld\t coordinates and speed: (%f,%f) %f\tDate: %d/%d/%d\n", (long) next.tv_sec, (long) next.tv_nsec, minmea_tocoord(&frame.latitude), minmea_tocoord(&frame.longitude), minmea_tofloat(&frame.speed), frame.date.day, frame.date.month, frame.date.year ); }else { fprintf(fp, "$RMC sentence is not parsed\n"); } } break; case MINMEA_SENTENCE_GGA: { struct minmea_sentence_gga frame; if (minmea_parse_gga(&frame, buffer)) { fprintf(fp, "$GGA: %ld.%ld\t fix quality: %d\t Altitude: %0.8f\t Time: %02d:%02d:%02d.%06d\n", (long) next.tv_sec, (long) next.tv_nsec, frame.fix_quality, minmea_tofloat(&frame.altitude), frame.time.hours, frame.time.minutes, frame.time.seconds, frame.time.microseconds); } else { fprintf(fp, "$GGA sentence is not parsed\n"); } } break; case MINMEA_SENTENCE_GST: { struct minmea_sentence_gst frame; if (minmea_parse_gst(&frame, buffer)) { fprintf(fp, "$GST: %ld.%ld\t floating point degree latitude, longitude and altitude error deviation: (%f,%f,%f)\n", (long) next.tv_sec, (long) next.tv_nsec, minmea_tofloat(&frame.latitude_error_deviation), minmea_tofloat(&frame.longitude_error_deviation), minmea_tofloat(&frame.altitude_error_deviation)); } else { fprintf(fp, "$GST sentence is not parsed\n"); } } break; case MINMEA_SENTENCE_GSV: { struct minmea_sentence_gsv frame; if (minmea_parse_gsv(&frame, buffer)) { if (frame.msg_nr == frame.total_msgs) fprintf(fp, "$GSV: %ld.%ld\t satellites in view: %d\n", (long) next.tv_sec, (long) next.tv_nsec, frame.total_sats); } else { fprintf(fp, "$GSV sentence is not parsed\n"); } } break; case MINMEA_SENTENCE_GSA: { struct minmea_sentence_gsa frame; if (minmea_parse_gsa(&frame, buffer)) { fprintf(fp, "$GSA: %ld.%ld\t Fix quality:\t %f, %f, %f\n", (long) next.tv_sec, (long) next.tv_nsec, minmea_tofloat(&frame.pdop), minmea_tofloat(&frame.hdop), minmea_tofloat(&frame.vdop)); } else { fprintf(fp, "$GSA sentence not parsed\n"); } } break; case MINMEA_INVALID: { fprintf(fp, "$xxxxx sentence is not valid:\n\t%s\n", buffer); } break; default: { buffer[6] = '\0'; fprintf(fp, "%s sentence is not parsed\n", buffer); } break; } }