diff --git a/src/gnss.c b/src/gnss.c index ad5869b..80bce4d 100644 --- a/src/gnss.c +++ b/src/gnss.c @@ -943,6 +943,22 @@ static void * gnss_thread(void * p_data) pthread_mutex_unlock(&gnss->mutex_data); usleep(5 * 1000); } + + /* this thread is the only writer to gnss->session, it's safe read the same values without mutex_data locked */ + if (gnss->gnss_info) { + struct gnss_state *gnss_info = gnss->gnss_info; + pthread_mutex_lock(&gnss_info->lock); + gnss_info->antenna_power = gnss->session->antenna_power; + gnss_info->antenna_status = gnss->session->antenna_status; + gnss_info->fix = gnss->session->fix; + gnss_info->fixOk = gnss->session->fixOk; + gnss_info->leap_seconds = gnss->session->context->leap_seconds; + gnss_info->lsChange = gnss->session->context->lsChange; + gnss_info->satellites_count = gnss->session->satellites_count; + gnss_info->survey_in_position_error = gnss->session->survey_in_position_error; + pthread_mutex_unlock(&gnss_info->lock); + } + pthread_mutex_lock(&gnss->mutex_data); stop = gnss->stop; action = gnss->action; diff --git a/src/gnss.h b/src/gnss.h index a2b5e73..6c593f0 100644 --- a/src/gnss.h +++ b/src/gnss.h @@ -125,6 +125,23 @@ struct gps_context_t { const char *buf, const size_t len); }; + +/** + * @struct gnss_state + * @brief Structure containing data with the latest gnss values + */ +struct gnss_state { + float survey_in_position_error; + int fix; + int satellites_count; + int leap_seconds; + int lsChange; + int8_t antenna_power; + int8_t antenna_status; + bool fixOk; + pthread_mutex_t lock; +}; + /** * @struct gps_device_t * @brief Structure containing data about the gnss device @@ -180,6 +197,7 @@ struct gnss { bool stop; int receiver_version_major; int receiver_version_minor; + struct gnss_state *gnss_info; }; struct gnss* gnss_init(const struct config *config, char *gnss_device_tty, struct gps_device_t *session, int fd_clock); diff --git a/src/monitoring.c b/src/monitoring.c index 6aadde1..2978c2d 100644 --- a/src/monitoring.c +++ b/src/monitoring.c @@ -565,7 +565,7 @@ static void json_add_oscillator_data(struct json_object *resp, struct monitoring } /** - * @brief Add GNSS data to json response + * @brief Add GNSS data to json response. Must be called under gnss_info.lock locked * * @param resp * @param monitoring @@ -627,10 +627,13 @@ static fd_status_t on_peer_ready_send(int sockfd, struct monitoring * monitoring json_add_clock_data(json_resp, monitoring); json_add_oscillator_data(json_resp, monitoring); - json_add_gnss_data(json_resp, monitoring); pthread_mutex_unlock(&monitoring->mutex); + pthread_mutex_lock(&monitoring->gnss_info.lock); + json_add_gnss_data(json_resp, monitoring); + pthread_mutex_unlock(&monitoring->gnss_info.lock); + const char *resp = json_object_to_json_string(json_resp); json_object_object_del(json_resp, "disciplining"); json_object_object_del(json_resp, "gnss"); @@ -728,6 +731,8 @@ struct monitoring* monitoring_init(const struct config *config, struct devices_p monitoring->gnss_info.lsChange = -10; monitoring->gnss_info.satellites_count = -1; monitoring->gnss_info.survey_in_position_error = -1.0; + pthread_mutex_init(&monitoring->gnss_info.lock, NULL); + pthread_mutex_init(&monitoring->mutex, NULL); pthread_cond_init(&monitoring->cond, NULL); diff --git a/src/monitoring.h b/src/monitoring.h index 68aa9e6..467ea64 100644 --- a/src/monitoring.h +++ b/src/monitoring.h @@ -33,17 +33,6 @@ enum monitoring_request { REQUEST_RESET_UBLOX_SERIAL }; -struct gnss_state { - float survey_in_position_error; - int fix; - int satellites_count; - int leap_seconds; - int lsChange; - int8_t antenna_power; - int8_t antenna_status; - bool fixOk; -}; - /** * @brief General structure for monitoring thread */ diff --git a/src/oscillatord.c b/src/oscillatord.c index d3af38f..7de88a5 100644 --- a/src/oscillatord.c +++ b/src/oscillatord.c @@ -333,6 +333,9 @@ int main(int argc, char *argv[]) error(EXIT_FAILURE, errno, "Failed to listen to the receiver"); return -EINVAL; } + if (monitoring) { + gnss->gnss_info = &monitoring->gnss_info; + } if (disciplining_mode) { /* Get disciplining parameters files exposed by driver */ @@ -612,7 +615,6 @@ int main(int argc, char *argv[]) if (monitoring_mode) { /* Check for monitoring requests */ enum monitoring_request request; - struct gnss_state gnss_info = {}; struct od_monitoring disciplining = { .clock_class = CLOCK_CLASS_UNCALIBRATED, .status = WARMUP, @@ -621,18 +623,6 @@ int main(int argc, char *argv[]) .convergence_progress = 0.00, .ready_for_holdover = false, }; - if (gnss) { - pthread_mutex_lock(&gnss->mutex_data); - gnss_info.antenna_power = gnss->session->antenna_power; - gnss_info.antenna_status = gnss->session->antenna_status; - gnss_info.fix = gnss->session->fix; - gnss_info.fixOk = gnss->session->fixOk; - gnss_info.leap_seconds = gnss->session->context->leap_seconds; - gnss_info.lsChange = gnss->session->context->lsChange; - gnss_info.satellites_count = gnss->session->satellites_count; - gnss_info.survey_in_position_error = gnss->session->survey_in_position_error; - pthread_mutex_unlock(&gnss->mutex_data); - } if (disciplining_mode) { if(od_get_monitoring_data(od, &disciplining) != 0) { log_warn("Could not get disciplining data"); @@ -650,15 +640,13 @@ int main(int argc, char *argv[]) oscillator_get_phase_error(oscillator, &osc_attr.phase_error); oscillator_get_disciplining_status(oscillator, &disciplining); } + pthread_mutex_lock(&monitoring->mutex); monitoring->osc_attributes = osc_attr; monitoring->ctrl_values = ctrl_values; monitoring->disciplining = disciplining; request = monitoring->request; monitoring->request = REQUEST_NONE; - if (gnss) - monitoring->gnss_info = gnss_info; - pthread_mutex_unlock(&monitoring->mutex); switch(request) {