Demo
Dependents: A_TeseoLocationNEW A_TeseoLocation
Middlewares/NMEAParser.c
- Committer:
- HarryKeane
- Date:
- 2020-01-31
- Revision:
- 5:d91199cfc6a4
- Parent:
- 0:a77f1f1f8318
File content as of revision 5:d91199cfc6a4:
/** ******************************************************************************* * @file NMEAParser.c * @author AST / Central Lab * @version V1.0.0 * @date 18-May-2017 * @brief NMEA sentence parser * ******************************************************************************* * @attention * * <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2> * * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); * You may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.st.com/software_license_agreement_liberty_v2 * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * 3. Neither the name of STMicroelectronics nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ******************************************************************************** */ #include "string.h" #include "NMEAParser.h" #include "NMEAUtils.h" /** @defgroup Middlewares * @brief Contains all platform independent modules (eg. NMEA Sentence Parser, ...). * @{ */ /** @defgroup ST * @{ */ /** @defgroup LIB_NMEA * @{ */ /** @defgroup NMEA_PARSER * @{ */ /** @addtogroup NMEA_PARSER_PUBLIC_FUNCTIONS * @{ */ /** * @brief Function that makes the parsing of the $GPGGA NMEA string with all Global Positioning System Fixed data. * @param gpgga_data Pointer to GPGGA_Infos struct * @param NMEA NMEA string read by the Gps expansion * @retval ParseStatus_Typedef PARSE_SUCC if the parsing process goes ok, PARSE_FAIL if it doesn't */ ParseStatus_Typedef parse_gpgga(GPGGA_Infos *gpgga_data, uint8_t *NMEA) { uint8_t app[MAX_MSG_LEN][MAX_MSG_LEN]; uint8_t valid_msg = 0; ParseStatus_Typedef status = PARSE_FAIL; if(NMEA == NULL) return status; /* clear the app[][] buffer */ for (uint8_t i=0; i<MAX_MSG_LEN; i++) { memset(app[i], 0, MAX_MSG_LEN); } for(unsigned i = 0, j = 0, k = 0; NMEA[i] != '\n' && i < strlen((char *)NMEA) - 1; i++) { if ((NMEA[i] == ',') || (NMEA[i] == '*')) { app[j][k] = '\0'; if (strcmp((char *)app[0], "$GPGGA") == 0) { j++; k = 0; valid_msg = 1; continue; } else { while(NMEA[i++] != '\n'); j = k = 0; } } app[j][k++] = NMEA[i]; } if (valid_msg == 1) { unsigned int valid; sscanf ((char *)app[6], "%u", &valid); gpgga_data->valid = (GPS_ValidTypedef)valid; if (gpgga_data->valid == VALID) { scan_utc ((char *)app[1], &gpgga_data->utc); sscanf ((char *)app[2], "%lf", &gpgga_data->xyz.lat); sscanf ((char *)app[3], "%c", &gpgga_data->xyz.ns); sscanf ((char *)app[4], "%lf", &gpgga_data->xyz.lon); sscanf ((char *)app[5], "%c", &gpgga_data->xyz.ew); sscanf ((char *)app[7], "%d", &gpgga_data->sats); sscanf ((char *)app[8], "%f", &gpgga_data->acc); sscanf ((char *)app[9], "%f", &gpgga_data->xyz.alt); sscanf ((char *)app[10], "%c", &gpgga_data->xyz.mis); sscanf ((char *)app[11], "%d", &gpgga_data->geoid.height); sscanf ((char *)app[12], "%c", &gpgga_data->geoid.mis); sscanf ((char *)app[13], "%d", &gpgga_data->update); sscanf ((char *)app[14], "%x", &gpgga_data->checksum); valid_msg = 0; status = PARSE_SUCC; } } return status; } /** * @brief Function that makes the parsing of the string read by the Gps expansion, capturing the right parameters from it. * @param gns_data Pointer to GNS_Infos struct * @param NMEA NMEA string read by the Gps expansion * @retval ParseStatus_Typedef PARSE_SUCC if the parsing process goes ok, PARSE_FAIL if it doesn't */ ParseStatus_Typedef parse_gnsmsg (GNS_Infos *gns_data, uint8_t *NMEA) { uint8_t app[MAX_MSG_LEN][MAX_MSG_LEN]; uint8_t valid_msg = 0; ParseStatus_Typedef status = PARSE_FAIL; if(NMEA == NULL) return status; /* clear the app[][] buffer */ for (uint8_t i=0; i<MAX_MSG_LEN; i++) { memset(app[i], 0, MAX_MSG_LEN); } for (unsigned i = 0, j = 0, k = 0; NMEA[i] != '\n' && i < strlen((char *)NMEA) - 1; i++) { if ((NMEA[i] == ',') || (NMEA[i] == '*')) { app[j][k] = '\0'; if ((strcmp((char *)app[0], "$GPGNS") == 0) || (strcmp((char *)app[0], "$GLGNS") == 0) || (strcmp((char *)app[0], "$GAGNS") == 0) || (strcmp((char *)app[0], "$BDGNS") == 0) || (strcmp((char *)app[0], "$QZGNS") == 0) || (strcmp((char *)app[0], "$GNGNS") == 0)) { j++; k = 0; valid_msg = 1; continue; } else { while (NMEA[i++] != '\n'); j = k = 0; } } app[j][k++] = NMEA[i]; } if (valid_msg == 1) { sscanf ((char *)app[0], "%s", gns_data->constellation); scan_utc ((char *)app[1], &gns_data->utc); sscanf ((char *)app[2], "%lf", &gns_data->xyz.lat); sscanf ((char *)app[3], "%c", &gns_data->xyz.ns); sscanf ((char *)app[4], "%lf", &gns_data->xyz.lon); sscanf ((char *)app[5], "%c", &gns_data->xyz.ew); sscanf ((char *)app[6], "%c", &gns_data->gps_mode); sscanf ((char *)app[7], "%c", &gns_data->glonass_mode); sscanf ((char *)app[8], "%d", &gns_data->sats); sscanf ((char *)app[9], "%f", &gns_data->hdop); sscanf ((char *)app[10], "%f", &gns_data->xyz.alt); sscanf ((char *)app[11], "%f", &gns_data->geo_sep); sscanf ((char *)app[12], "%c", &gns_data->dgnss_age); sscanf ((char *)app[13], "%c", &gns_data->dgnss_ref); sscanf ((char *)app[14], "%x", &gns_data->checksum); valid_msg = 0; status = PARSE_SUCC; } return status; } /** * @brief Function that makes the parsing of the $GPGST NMEA string with GPS Pseudorange Noise Statistics. * @param GPGST_Infos Pointer to a GPGST_Infos struct * @param NMEA NMEA string read by the Gps expansion. * @retval ParseStatus_Typedef PARSE_SUCC if the parsing process goes ok, PARSE_FAIL if it doesn't */ ParseStatus_Typedef parse_gpgst (GPGST_Infos *gpgst_data, uint8_t *NMEA) { uint8_t app[MAX_MSG_LEN][MAX_MSG_LEN]; uint8_t valid_msg = 0; ParseStatus_Typedef status = PARSE_FAIL; if(NMEA == NULL) return status; /* clear the app[][] buffer */ for (uint8_t i=0; i<MAX_MSG_LEN; i++) { memset(app[i], 0, MAX_MSG_LEN); } for (unsigned i = 0, j = 0, k = 0; NMEA[i] != '\n' && i < strlen((char *)NMEA) - 1; i++) { if ((NMEA[i] == ',') || (NMEA[i] == '*')) { app[j][k] = '\0'; if (strcmp((char *)app[0], "$GPGST") == 0) { j++; k = 0; valid_msg = 1; continue; } else { while (NMEA[i++] != '\n'); j = k = 0; } } app[j][k++] = NMEA[i]; } if (valid_msg == 1) { scan_utc ((char *)app[1], &gpgst_data->utc); sscanf ((char *)app[2], "%f", &gpgst_data->EHPE); sscanf ((char *)app[3], "%f", &gpgst_data->semi_major_dev); sscanf ((char *)app[4], "%f", &gpgst_data->semi_minor_dev); sscanf ((char *)app[5], "%f", &gpgst_data->semi_major_angle); sscanf ((char *)app[6], "%f", &gpgst_data->lat_err_dev); sscanf ((char *)app[7], "%f", &gpgst_data->lon_err_dev); sscanf ((char *)app[8], "%f", &gpgst_data->alt_err_dev); sscanf ((char *)app[9], "%x", &gpgst_data->checksum); valid_msg = 0; status = PARSE_SUCC; } return status; } /** * @brief Function that makes the parsing of the $GPRMC NMEA string with Recommended Minimum Specific GPS/Transit data. * @param GPRMC_Infos Pointer to a GPRMC_Infos struct * @param NMEA NMEA string read by the Gps expansion. * @retval ParseStatus_Typedef PARSE_SUCC if the parsing process goes ok, PARSE_FAIL if it doesn't */ ParseStatus_Typedef parse_gprmc (GPRMC_Infos *gprmc_data, uint8_t *NMEA) { uint8_t app[MAX_MSG_LEN][MAX_MSG_LEN]; uint8_t valid_msg = 0; ParseStatus_Typedef status = PARSE_FAIL; if(NMEA == NULL) return status; /* clear the app[][] buffer */ for (uint8_t i=0; i<MAX_MSG_LEN; i++) { memset(app[i], 0, MAX_MSG_LEN); } for (unsigned i = 0, j = 0, k = 0; NMEA[i] != '\n' && i < strlen((char *)NMEA) - 1; i++) { if ((NMEA[i] == ',') || (NMEA[i] == '*')) { app[j][k] = '\0'; if (strcmp((char *)app[0], "$GPRMC") == 0) { j++; k = 0; valid_msg = 1; continue; } else { while (NMEA[i++] != '\n'); j = k = 0; } } app[j][k++] = NMEA[i]; } if (valid_msg == 1) { scan_utc ((char *)app[1], &gprmc_data->utc); sscanf ((char *)app[2], "%c", &gprmc_data->status); sscanf ((char *)app[3], "%lf", &gprmc_data->xyz.lat); sscanf ((char *)app[4], "%c", &gprmc_data->xyz.ns); sscanf ((char *)app[5], "%lf", &gprmc_data->xyz.lon); sscanf ((char *)app[6], "%c", &gprmc_data->xyz.ew); sscanf ((char *)app[7], "%f", &gprmc_data->speed); sscanf ((char *)app[8], "%f", &gprmc_data->trackgood); sscanf ((char *)app[9], "%d", &gprmc_data->date); sscanf ((char *)app[10], "%f", &gprmc_data->mag_var); sscanf ((char *)app[11], "%c", &gprmc_data->mag_var_dir); /* WARNING: from received msg, it seems there is another data (app[12]) before the checksum */ sscanf ((char *)app[13], "%x", &gprmc_data->checksum); valid_msg = 0; status = PARSE_SUCC; } return status; } /** * @brief Function that makes the parsing of the string read by the Gps expansion, capturing the right parameters from it. * @param GSA_Infos Pointer to a GSA_Infos struct * @param NMEA NMEA string read by the Gps expansion. * @retval ParseStatus_Typedef PARSE_SUCC if the parsing process goes ok, PARSE_FAIL if it doesn't */ ParseStatus_Typedef parse_gsamsg (GSA_Infos *gsa_data, uint8_t *NMEA) { uint8_t app[MAX_MSG_LEN][MAX_MSG_LEN]; uint8_t valid_msg = 0; ParseStatus_Typedef status = PARSE_FAIL; if(NMEA == NULL) return status; /* clear the app[][] buffer */ for (uint8_t i=0; i<19; i++) { memset(app[i], 0, 19); } for (unsigned i = 0, j = 0, k = 0; NMEA[i] != '\n' && i < strlen((char *)NMEA) - 1; i++) { if ((NMEA[i] == ',') || (NMEA[i] == '*')) { app[j][k] = '\0'; if ((strcmp((char *)app[0], "$GPGSA") == 0) || (strcmp((char *)app[0], "$GLGSA") == 0) || (strcmp((char *)app[0], "$GAGSA") == 0) || (strcmp((char *)app[0], "$BDGSA") == 0) || (strcmp((char *)app[0], "$GNGSA") == 0)) { j++; k = 0; valid_msg = 1; continue; } else { while (NMEA[i++] != '\n'); j = k = 0; } } app[j][k++] = NMEA[i]; } if (valid_msg == 1) { sscanf ((char *)app[0], "%s", gsa_data->constellation); sscanf ((char *)app[1], "%c", &gsa_data->operating_mode); sscanf ((char *)app[2], "%d", &gsa_data->current_mode); for (uint8_t i=0; i<MAX_SAT_NUM; i++) { sscanf ((char *)app[3+i], "%d", &gsa_data->sat_prn[i]); } sscanf ((char *)app[15], "%f", &gsa_data->pdop); sscanf ((char *)app[16], "%f", &gsa_data->hdop); sscanf ((char *)app[17], "%f", &gsa_data->vdop); sscanf ((char *)app[18], "%x", &gsa_data->checksum); valid_msg = 0; status = PARSE_SUCC; } return status; } /** * @brief Function that makes the parsing of the string read by the Gps expansion, capturing the right parameters from it. * @param GSV_Infos Pointer to a GSV_Infos struct * @param NMEA NMEA string read by the Gps expansion. * @retval ParseStatus_Typedef PARSE_SUCC if the parsing process goes ok, PARSE_FAIL if it doesn't */ ParseStatus_Typedef parse_gsvmsg(GSV_Infos *gsv_data, uint8_t *NMEA) { uint8_t app[32][16]; uint8_t app_idx; uint8_t gsv_idx = 0; int msg_amount = 1; int curr_msg; uint8_t right_msg = 0; uint8_t valid_gsv_msg = 0; unsigned i, j, k; unsigned l = 0; ParseStatus_Typedef status = PARSE_FAIL; if(NMEA == NULL) return status; while (right_msg < msg_amount) { /* clear the app[][] buffer */ for (uint8_t pos=0; pos<32; pos++) { memset(app[pos], 0, 16); } for (i = l, j = 0, k = 0; NMEA[i] != '\n' && i < strlen((char *)NMEA) - 1; i++) { if (NMEA[i] == ',') { app[j][k] = '\0'; if ((strcmp((char *)app[0], "$GPGSV") == 0) || (strcmp((char *)app[0], "$GLGSV") == 0) || (strcmp((char *)app[0], "$GAGSV") == 0) || (strcmp((char *)app[0], "$BDGSV") == 0) || (strcmp((char *)app[0], "$QZGSV") == 0) || (strcmp((char *)app[0], "$GNGSV") == 0)) { j++; k = 0; valid_gsv_msg = 1; continue; } else { while (NMEA[i++] != '\n'); j = k = 0; } } if ((NMEA[i] == '*') && (k!=0)) { j++; k=0; } app[j][k++] = NMEA[i]; } l = i; if (valid_gsv_msg == 1) { valid_gsv_msg = 0; sscanf((char *)app[1], "%d", &msg_amount); sscanf((char *)app[2], "%d", &curr_msg); if (curr_msg == right_msg+1) { valid_gsv_msg = 1; right_msg++; } } else { right_msg = msg_amount; } if (valid_gsv_msg == 1) { sscanf((char *)app[0], "%s", gsv_data->constellation); sscanf((char *)app[1], "%d", &gsv_data->amount); sscanf((char *)app[2], "%d", &gsv_data->number); sscanf((char *)app[3], "%d", &gsv_data->tot_sats); app_idx = 4; while (app[app_idx][0] != '*') { sscanf((char *)app[app_idx++], "%d", &gsv_data->gsv_sat_i[gsv_idx].prn); sscanf((char *)app[app_idx++], "%d", &gsv_data->gsv_sat_i[gsv_idx].elev); sscanf((char *)app[app_idx++], "%d", &gsv_data->gsv_sat_i[gsv_idx].azim); if (app[app_idx][0] != '*') { sscanf((char *)app[app_idx++], "%d", &gsv_data->gsv_sat_i[gsv_idx].cn0); } else { sscanf("", "%d", &gsv_data->gsv_sat_i[gsv_idx].cn0); } gsv_idx++; } valid_gsv_msg = 0; status = PARSE_SUCC; } } return status; } /** * @brief * @param Geofence_Infos Pointer to a Geofence_Infos struct * @param NMEA NMEA string read by the Gps expansion. * @retval ParseStatus_Typedef PARSE_SUCC if the parsing process goes ok, PARSE_FAIL if it doesn't */ ParseStatus_Typedef parse_pstmgeofence(Geofence_Infos *geofence_data, uint8_t *NMEA) { uint8_t app[MAX_MSG_LEN][MAX_MSG_LEN]; uint8_t valid_msg = 0; ParseStatus_Typedef status = PARSE_FAIL; if(NMEA == NULL) return status; /* clear the app[][] buffer */ for (uint8_t i=0; i<MAX_MSG_LEN; i++) { memset(app[i], 0, MAX_MSG_LEN); } for(unsigned i = 0, j = 0, k = 0; NMEA[i] != '\n' && i < strlen((char *)NMEA) - 1; i++) { if ((NMEA[i] == ',') || (NMEA[i] == '*')) { app[j][k] = '\0'; if ((strcmp((char *)app[0], "$PSTMCFGGEOFENCEOK") == 0) || (strcmp((char *)app[0], "$PSTMCFGGEOFENCEERROR") == 0) || (strcmp((char *)app[0], "$PSTMGEOFENCECFGOK") == 0) || (strcmp((char *)app[0], "$PSTMGEOFENCECFGERROR") == 0) || (strcmp((char *)app[0], "$PSTMGEOFENCESTATUS") == 0) || (strcmp((char *)app[0], "$PSTMGEOFENCE") == 0) || (strcmp((char *)app[0], "$PSTMGEOFENCEREQERROR") == 0)) { j++; k = 0; valid_msg = 1; continue; } else { while(NMEA[i++] != '\n'); j = k = 0; } } app[j][k++] = NMEA[i]; } if (valid_msg == 1) { /* Enabling */ if (strcmp((char *)app[0], "$PSTMCFGGEOFENCEOK") == 0) { geofence_data->op = GNSS_FEATURE_EN_MSG; geofence_data->result = 0; } if (strcmp((char *)app[0], "$PSTMCFGGEOFENCEERROR") == 0) { geofence_data->op = GNSS_FEATURE_EN_MSG; geofence_data->result = 1; } /* Configuring */ if (strcmp((char *)app[0], "$PSTMGEOFENCECFGOK") == 0) { geofence_data->op = GNSS_GEOFENCE_CFG_MSG; geofence_data->result = 0; } if (strcmp((char *)app[0], "$PSTMGEOFENCECFGERROR") == 0) { geofence_data->op = GNSS_GEOFENCE_STATUS_MSG; geofence_data->result = 1; } /* Querying Status */ if (strcmp((char *)app[0], "$PSTMGEOFENCESTATUS") == 0) { geofence_data->op = GNSS_GEOFENCE_STATUS_MSG; geofence_data->result = 0; sscanf((char *)app[1], "%02d%02d%02d", &geofence_data->timestamp.hh,&geofence_data->timestamp.mm,&geofence_data->timestamp.ss); sscanf((char *)app[2], "%04d%02d%02d", &geofence_data->timestamp.year,&geofence_data->timestamp.month,&geofence_data->timestamp.day); for(uint8_t i = 0; i<MAX_GEOFENCES_NUM; i++) { sscanf((char *)app[3+i], "%d", &geofence_data->status[i]); } } /* Alarm Msg */ if (strcmp((char *)app[0], "$PSTMGEOFENCE") == 0) { geofence_data->op = GNSS_GEOFENCE_ALARM_MSG; geofence_data->result = 0; sscanf((char *)app[1], "%02d%02d%02d", &geofence_data->timestamp.hh,&geofence_data->timestamp.mm,&geofence_data->timestamp.ss); sscanf((char *)app[2], "%04d%02d%02d", &geofence_data->timestamp.year,&geofence_data->timestamp.month,&geofence_data->timestamp.day); sscanf((char *)app[3], "%d", &geofence_data->idAlarm); sscanf((char *)app[9], "%d", &geofence_data->status[geofence_data->idAlarm]); } valid_msg = 0; status = PARSE_SUCC; } return status; } /** * @brief * @param Odometer_Infos Pointer to a Odometer_Infos struct * @param NMEA NMEA string read by the Gps expansion. * @retval ParseStatus_Typedef PARSE_SUCC if the parsing process goes ok, PARSE_FAIL if it doesn't */ ParseStatus_Typedef parse_pstmodo(Odometer_Infos *odo_data, uint8_t *NMEA) { uint8_t app[MAX_MSG_LEN][MAX_MSG_LEN]; uint8_t valid_msg = 0; ParseStatus_Typedef status = PARSE_FAIL; if(NMEA == NULL) return status; /* clear the app[][] buffer */ for (uint8_t i=0; i<MAX_MSG_LEN; i++) { memset(app[i], 0, MAX_MSG_LEN); } for(unsigned i = 0, j = 0, k = 0; NMEA[i] != '\n' && i < strlen((char *)NMEA) - 1; i++) { if ((NMEA[i] == ',') || (NMEA[i] == '*')) { app[j][k] = '\0'; if ((strcmp((char *)app[0], "$PSTMCFGODOOK") == 0) || (strcmp((char *)app[0], "$PSTMCFGODOERROR") == 0) || (strcmp((char *)app[0], "$PSTMODOSTARTOK") == 0) || (strcmp((char *)app[0], "$PSTMODOSTARTERROR") == 0) || (strcmp((char *)app[0], "$PSTMODOSTOPOK") == 0) || (strcmp((char *)app[0], "$PSTMODOSTOPERROR") == 0)) { j++; k = 0; valid_msg = 1; continue; } else { while(NMEA[i++] != '\n'); j = k = 0; } } app[j][k++] = NMEA[i]; } if (valid_msg == 1) { /* Enabling */ if (strcmp((char *)app[0], "$PSTMCFGODOOK") == 0) { odo_data->op = GNSS_FEATURE_EN_MSG; odo_data->result = 0; } if (strcmp((char *)app[0], "$PSTMCFGODOERROR") == 0) { odo_data->op = GNSS_FEATURE_EN_MSG; odo_data->result = 1; } /* Start */ if (strcmp((char *)app[0], "$PSTMODOSTARTOK") == 0) { odo_data->op = GNSS_ODO_START_MSG; odo_data->result = 0; } if (strcmp((char *)app[0], "$PSTMODOSTARTERROR") == 0) { odo_data->op = GNSS_ODO_START_MSG; odo_data->result = 1; } /* Stop */ if (strcmp((char *)app[0], "$PSTMODOSTOPOK") == 0) { odo_data->op = GNSS_ODO_STOP_MSG; odo_data->result = 0; } if (strcmp((char *)app[0], "$PSTMODOSTOPERROR") == 0) { odo_data->op = GNSS_ODO_STOP_MSG; odo_data->result = 1; } valid_msg = 0; status = PARSE_SUCC; } return status; } /** * @brief * @param Datalog_Infos Pointer to a Datalog_Infos struct * @param NMEA NMEA string read by the Gps expansion. * @retval ParseStatus_Typedef PARSE_SUCC if the parsing process goes ok, PARSE_FAIL if it doesn't */ ParseStatus_Typedef parse_pstmdatalog(Datalog_Infos *datalog_data, uint8_t *NMEA) { uint8_t app[MAX_MSG_LEN][MAX_MSG_LEN]; uint8_t valid_msg = 0; ParseStatus_Typedef status = PARSE_FAIL; if(NMEA == NULL) return status; /* clear the app[][] buffer */ for (uint8_t i=0; i<MAX_MSG_LEN; i++) { memset(app[i], 0, MAX_MSG_LEN); } for(unsigned i = 0, j = 0, k = 0; NMEA[i] != '\n' && i < strlen((char *)NMEA) - 1; i++) { if ((NMEA[i] == ',') || (NMEA[i] == '*')) { app[j][k] = '\0'; if ((strcmp((char *)app[0], "$PSTMCFGLOGOK") == 0) || (strcmp((char *)app[0], "$PSTMCFGLOGERROR") == 0) || (strcmp((char *)app[0], "$PSTMLOGCREATEOK") == 0) || (strcmp((char *)app[0], "$PSTMLOGCREATEERROR") == 0) || (strcmp((char *)app[0], "$PSTMLOGSTARTOK") == 0) || (strcmp((char *)app[0], "$PSTMLOGSTARTERROR") == 0) || (strcmp((char *)app[0], "$PSTMLOGSTOPOK") == 0) || (strcmp((char *)app[0], "$PSTMLOGSTOPERROR") == 0) || (strcmp((char *)app[0], "$PSTMLOGERASEOK") == 0) || (strcmp((char *)app[0], "$PSTMLOGERASEERROR") == 0)) { j++; k = 0; valid_msg = 1; continue; } else { while(NMEA[i++] != '\n'); j = k = 0; } } app[j][k++] = NMEA[i]; } if (valid_msg == 1) { /* Enabling */ if (strcmp((char *)app[0], "$PSTMCFGLOGOK") == 0) { datalog_data->op = GNSS_FEATURE_EN_MSG; datalog_data->result = 0; } if (strcmp((char *)app[0], "$PSTMCFGLOGERROR") == 0) { datalog_data->op = GNSS_FEATURE_EN_MSG; datalog_data->result = 1; } /* Configuring */ if (strcmp((char *)app[0], "$PSTMLOGCREATEOK") == 0) { datalog_data->op = GNSS_DATALOG_CFG_MSG; datalog_data->result = 0; } if (strcmp((char *)app[0], "$PSTMLOGCREATEERROR") == 0) { datalog_data->op = GNSS_DATALOG_CFG_MSG; datalog_data->result = 1; } /* Start */ if (strcmp((char *)app[0], "$PSTMLOGSTARTOK") == 0) { datalog_data->op = GNSS_DATALOG_START_MSG; datalog_data->result = 0; } if (strcmp((char *)app[0], "$PSTMLOGSTARTERROR") == 0) { datalog_data->op = GNSS_DATALOG_START_MSG; datalog_data->result = 1; } /* Stop */ if (strcmp((char *)app[0], "$PSTMLOGSTOPOK") == 0) { datalog_data->op = GNSS_DATALOG_STOP_MSG; datalog_data->result = 0; } if (strcmp((char *)app[0], "$PSTMLOGSTOPERROR") == 0) { datalog_data->op = GNSS_DATALOG_STOP_MSG; datalog_data->result = 1; } /* Erase */ if (strcmp((char *)app[0], "$PSTMLOGERASEOK") == 0) { datalog_data->op = GNSS_DATALOG_ERASE_MSG; datalog_data->result = 0; } if (strcmp((char *)app[0], "$PSTMLOGERASEERROR") == 0) { datalog_data->op = GNSS_DATALOG_ERASE_MSG; datalog_data->result = 1; } valid_msg = 0; status = PARSE_SUCC; } return status; } /** * @brief * @param Ack_Info Ack from Teseo * @param NMEA NMEA string read by the Gps expansion. * @retval ParseStatus_Typedef PARSE_SUCC if the parsing process goes ok, PARSE_FAIL if it doesn't */ ParseStatus_Typedef parse_pstmsgl(Ack_Info *ack, uint8_t *NMEA) { uint8_t app[MAX_MSG_LEN][MAX_MSG_LEN]; uint8_t valid_msg = 0; ParseStatus_Typedef status = PARSE_FAIL; if(NMEA == NULL) return status; /* clear the app[][] buffer */ for (uint8_t i=0; i<MAX_MSG_LEN; i++) { memset(app[i], 0, MAX_MSG_LEN); } for(unsigned i = 0, j = 0, k = 0; NMEA[i] != '\n' && i < strlen((char *)NMEA) - 1; i++) { if ((NMEA[i] == ',') || (NMEA[i] == '*')) { app[j][k] = '\0'; if ((strcmp((char *)app[0], "$PSTMCFGMSGLOK") == 0) || (strcmp((char *)app[0], "$PSTMCFGMSGLERROR") == 0)) { j++; k = 0; valid_msg = 1; continue; } else { while(NMEA[i++] != '\n'); j = k = 0; } } app[j][k++] = NMEA[i]; } if (valid_msg == 1) { /* Enabling */ if (strcmp((char *)app[0], "$PSTMCFGMSGLOK") == 0) { *ack = 0; } if (strcmp((char *)app[0], "$PSTMCFGMSGLERROR") == 0) { *ack = 1; } valid_msg = 0; status = PARSE_SUCC; } return status; } /** * @brief * @param Ack_Info Ack from Teseo * @param NMEA NMEA string read by the Gps expansion. * @retval ParseStatus_Typedef PARSE_SUCC if the parsing process goes ok, PARSE_FAIL if it doesn't */ ParseStatus_Typedef parse_pstmsavepar(Ack_Info *ack, uint8_t *NMEA) { uint8_t app[MAX_MSG_LEN][MAX_MSG_LEN]; uint8_t valid_msg = 0; ParseStatus_Typedef status = PARSE_FAIL; if(NMEA == NULL) return status; /* clear the app[][] buffer */ for (uint8_t i=0; i<MAX_MSG_LEN; i++) { memset(app[i], 0, MAX_MSG_LEN); } for(unsigned i = 0, j = 0, k = 0; NMEA[i] != '\n' && i < strlen((char *)NMEA) - 1; i++) { if ((NMEA[i] == ',') || (NMEA[i] == '*')) { app[j][k] = '\0'; if ((strcmp((char *)app[0], "$PSTMSAVEPAROK") == 0) || (strcmp((char *)app[0], "$PSTMSAVEPARERROR") == 0)) { j++; k = 0; valid_msg = 1; continue; } else { while(NMEA[i++] != '\n'); j = k = 0; } } app[j][k++] = NMEA[i]; } if (valid_msg == 1) { /* Enabling */ if (strcmp((char *)app[0], "$PSTMSAVEPAROK") == 0) { *ack = 0; } if (strcmp((char *)app[0], "$PSTMSAVEPARERROR") == 0) { *ack = 1; } valid_msg = 0; status = PARSE_SUCC; } return status; } /** * @brief This function makes a copy of the datas stored into gps_t into the 'info' param * @param info Instance of a GPGGA_Infos object where there are the infos to be copied * @param gps_t Instance of a GPGGA_Infos object pointer where the infos stored into gps_t have to be copied * @retval None */ void copy_data(GPGGA_Infos *info, GPGGA_Infos gps_t){ info->acc = gps_t.acc; info->geoid.height = gps_t.geoid.height; info->geoid.mis = gps_t.geoid.mis; info->sats = gps_t.sats; info->update = gps_t.update; info->utc.hh = gps_t.utc.hh; info->utc.mm = gps_t.utc.mm; info->utc.ss = gps_t.utc.ss; info->utc.utc = gps_t.utc.utc; info->valid = gps_t.valid; info->xyz.alt = gps_t.xyz.alt; info->xyz.lat = gps_t.xyz.lat; info->xyz.lon = gps_t.xyz.lon; info->xyz.ew = gps_t.xyz.ew; info->xyz.ns = gps_t.xyz.ns; info->xyz.mis = gps_t.xyz.mis; info->checksum = gps_t.checksum; } /** * @} */ /** * @} */ /** * @} */ /** * @} */ /** * @} */