mirror of
https://gitlab.com/mobian1/eg25-manager.git
synced 2025-08-29 15:22:20 +02:00
Merge branch 'gnss_cleanup' into 'master'
Fix various small issues in the gnss assistance data upload code Closes #20 See merge request mobian1/devices/eg25-manager!29
This commit is contained in:
149
src/gnss.c
149
src/gnss.c
@@ -8,8 +8,13 @@
|
||||
#include "manager.h"
|
||||
#include "at.h"
|
||||
|
||||
#include <sys/sendfile.h>
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define BUFFER_SIZE 256
|
||||
#define UPLOAD_DELAY 100000
|
||||
#define UPLOAD_DELAY_US 10000
|
||||
#define UPLOAD_TIMEOUT_S 10
|
||||
#define RESCHEDULE_IN_SECS 30
|
||||
|
||||
static void gnss_step(struct EG25Manager *manager);
|
||||
@@ -195,71 +200,71 @@ static void state_at_gnss(struct EG25Manager *manager)
|
||||
|
||||
static void fetch_assistance_data(struct EG25Manager *manager)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode response;
|
||||
long status_code;
|
||||
gchar *url = NULL;
|
||||
curl_off_t downloaded;
|
||||
CURL *curl = NULL;
|
||||
g_autofree gchar *url = NULL;
|
||||
FILE *tmp_file = NULL;
|
||||
long int size;
|
||||
gchar errbuf[CURL_ERROR_SIZE];
|
||||
errbuf[0] = 0;
|
||||
|
||||
/* Fetch assistance data with curl */
|
||||
tmp_file = fdopen(manager->gnss_assistance_fd, "wb+");
|
||||
if (tmp_file == NULL) {
|
||||
g_critical("Unable to open file to save assistance data: %s",
|
||||
g_strerror(errno));
|
||||
goto bail;
|
||||
}
|
||||
|
||||
lseek(manager->gnss_assistance_fd, 0, SEEK_SET);
|
||||
ftruncate(manager->gnss_assistance_fd, 0);
|
||||
url = g_strconcat(manager->gnss_assistance_url, "/",
|
||||
manager->gnss_assistance_file, NULL);
|
||||
|
||||
curl = curl_easy_init();
|
||||
if (!curl)
|
||||
g_error ("Unable to initialize curl");
|
||||
if (!curl) {
|
||||
g_critical("Unable to initialize curl");
|
||||
goto bail;
|
||||
}
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, url);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, NULL);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, tmp_file);
|
||||
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errbuf);
|
||||
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
|
||||
curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1L);
|
||||
response = curl_easy_perform(curl);
|
||||
if (response == CURLE_HTTP_RETURNED_ERROR) {
|
||||
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status_code);
|
||||
curl_easy_cleanup(curl);
|
||||
g_warning ("Unable to fetch GNSS assistance data from %s (HTTP %ld)",
|
||||
url, status_code);
|
||||
|
||||
/* Restart upload on HTTP error status code */
|
||||
g_message ("Rescheduling upload because of failure in %ds",
|
||||
RESCHEDULE_IN_SECS);
|
||||
manager->gnss_assistance_step = EG25_GNSS_STEP_LAST;
|
||||
g_timeout_add_seconds(RESCHEDULE_IN_SECS,
|
||||
G_SOURCE_FUNC(gnss_upload_assistance_data),
|
||||
manager);
|
||||
return;
|
||||
response = curl_easy_perform(curl);
|
||||
if (response != CURLE_OK) {
|
||||
g_warning("Unable to fetch GNSS assistance data from %s: %s",
|
||||
url, strlen(errbuf) ? errbuf : curl_easy_strerror(response));
|
||||
goto bail;
|
||||
}
|
||||
|
||||
/* Get file size in bytes */
|
||||
size = (long int)lseek(manager->gnss_assistance_fd, 0, SEEK_END);
|
||||
lseek(manager->gnss_assistance_fd, 0, SEEK_SET);
|
||||
|
||||
if (size <= 0) {
|
||||
g_warning ("GNSS assistance data contains 0 bytes,"
|
||||
"check network connection.");
|
||||
/*
|
||||
* Restart upload when file does not contain any data,
|
||||
* mostly because of no network connection.
|
||||
*/
|
||||
g_message ("Rescheduling upload because of failure in %ds",
|
||||
RESCHEDULE_IN_SECS);
|
||||
manager->gnss_assistance_step = EG25_GNSS_STEP_LAST;
|
||||
g_timeout_add_seconds(RESCHEDULE_IN_SECS,
|
||||
G_SOURCE_FUNC(gnss_upload_assistance_data),
|
||||
manager);
|
||||
return;
|
||||
response = curl_easy_getinfo(curl, CURLINFO_SIZE_DOWNLOAD_T, &downloaded);
|
||||
if (response) {
|
||||
g_critical("Unable to get number of downloaded bytes from curl");
|
||||
goto bail;
|
||||
} else if (downloaded <= 0) {
|
||||
g_warning("Downloaded empty assistance data file");
|
||||
goto bail;
|
||||
}
|
||||
|
||||
g_message("Fetching GNSS assistance data from %s was successfull", url);
|
||||
|
||||
fflush(tmp_file);
|
||||
curl_easy_cleanup(curl);
|
||||
g_free(url);
|
||||
|
||||
/* Go to the next step */
|
||||
manager->gnss_assistance_step++;
|
||||
gnss_step(manager);
|
||||
return;
|
||||
|
||||
bail:
|
||||
if (curl != NULL)
|
||||
curl_easy_cleanup(curl);
|
||||
manager->gnss_assistance_step = EG25_GNSS_STEP_LAST;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
@@ -279,18 +284,24 @@ static void init_assistance_data_upload_start(struct EG25Manager *manager,
|
||||
const char *response)
|
||||
{
|
||||
gchar value[BUFFER_SIZE];
|
||||
long int size;
|
||||
off_t size;
|
||||
|
||||
/* Process AT response */
|
||||
at_process_result(manager, response);
|
||||
|
||||
/* Get file size in bytes */
|
||||
size = (long int)lseek(manager->gnss_assistance_fd, 0, SEEK_END);
|
||||
size = lseek(manager->gnss_assistance_fd, 0, SEEK_END);
|
||||
if (size == -1) {
|
||||
g_critical("gnss: unable to read size of xtra data file: %s", g_strerror(errno));
|
||||
|
||||
manager->gnss_assistance_step = EG25_GNSS_STEP_LAST;
|
||||
return;
|
||||
}
|
||||
lseek(manager->gnss_assistance_fd, 0, SEEK_SET);
|
||||
|
||||
/* Start upload */
|
||||
g_snprintf(value, BUFFER_SIZE, "\"RAM:%s\",%ld\r\n",
|
||||
manager->gnss_assistance_file, size);
|
||||
g_snprintf(value, BUFFER_SIZE, "\"RAM:%s\",%ld,%d",
|
||||
manager->gnss_assistance_file, size, UPLOAD_TIMEOUT_S);
|
||||
g_message("Initiate GNSS assistance data upload: %s", value);
|
||||
at_append_command(manager, "QFUPL", NULL, value, NULL,
|
||||
init_assistance_data_upload_ready);
|
||||
@@ -310,39 +321,39 @@ static void init_assistance_data_upload(struct EG25Manager *manager)
|
||||
|
||||
static void upload_assistance_data(struct EG25Manager *manager)
|
||||
{
|
||||
char buffer[2*BUFFER_SIZE];
|
||||
gint len;
|
||||
gboolean success = TRUE;
|
||||
gint error;
|
||||
glong written_total = 0;
|
||||
gint ret;
|
||||
struct stat sb;
|
||||
|
||||
if (fstat(manager->gnss_assistance_fd, &sb) != 0) {
|
||||
g_critical("gnss: unable to stat xtra data file: %s", g_strerror(errno));
|
||||
|
||||
/* Make sure the upload times out and the modem goes back to AT command mode */
|
||||
sleep(UPLOAD_TIMEOUT_S + 1);
|
||||
manager->gnss_assistance_step = EG25_GNSS_STEP_LAST;
|
||||
return;
|
||||
}
|
||||
|
||||
do {
|
||||
errno = 0;
|
||||
/* Copy downloaded XTRA assistance data to the modem over serial */
|
||||
while((len = read(manager->gnss_assistance_fd, buffer, 2*BUFFER_SIZE)) > 0)
|
||||
{
|
||||
len = write(manager->at_fd, buffer, len);
|
||||
if (len < 0) {
|
||||
success = FALSE;
|
||||
g_error("Writing GNSS assistance data failed: %d", len);
|
||||
break;
|
||||
}
|
||||
usleep(UPLOAD_DELAY);
|
||||
g_message("Uploaded %d bytes", len);
|
||||
}
|
||||
ret = sendfile(manager->at_fd, manager->gnss_assistance_fd, &written_total, sb.st_size);
|
||||
error = errno;
|
||||
usleep(UPLOAD_DELAY_US);
|
||||
} while ((!error && written_total < sb.st_size) || (ret == -1 && error == EAGAIN));
|
||||
|
||||
/* Clear QFUPL AT command and process next */
|
||||
at_next_command(manager);
|
||||
|
||||
/* Go to the next step if successful */
|
||||
if (success) {
|
||||
if (!error) {
|
||||
g_message("Successfully uploaded %ld bytes to the modem", written_total);
|
||||
manager->gnss_assistance_step++;
|
||||
gnss_step(manager);
|
||||
}
|
||||
/* Restart upload */
|
||||
else {
|
||||
g_message ("Rescheduling upload because of failure in %ds",
|
||||
RESCHEDULE_IN_SECS);
|
||||
} else {
|
||||
g_critical("Unable to upload xtra data: %s", g_strerror(error));
|
||||
manager->gnss_assistance_step = EG25_GNSS_STEP_LAST;
|
||||
g_timeout_add_seconds(RESCHEDULE_IN_SECS,
|
||||
G_SOURCE_FUNC(gnss_upload_assistance_data),
|
||||
manager);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -385,9 +396,9 @@ static void finish_assistance_data_upload(struct EG25Manager *manager)
|
||||
#ifdef HAVE_MMGLIB
|
||||
static void enable_mm_gnss(struct EG25Manager *manager)
|
||||
{
|
||||
MMModemLocationSource sources;
|
||||
gboolean signal_location;
|
||||
g_autoptr (GError) error = NULL;
|
||||
MMModemLocationSource sources = mm_modem_location_get_enabled(manager->mm_location);
|
||||
gboolean signal_location = mm_modem_location_signals_location(manager->mm_location);
|
||||
|
||||
if (manager->gnss_sources & EG25_GNSS_SOURCE_UNMANAGED)
|
||||
sources |= MM_MODEM_LOCATION_SOURCE_GPS_UNMANAGED;
|
||||
@@ -396,8 +407,6 @@ static void enable_mm_gnss(struct EG25Manager *manager)
|
||||
if (manager->gnss_sources & EG25_GNSS_SOURCE_RAW)
|
||||
sources |= MM_MODEM_LOCATION_SOURCE_GPS_RAW;
|
||||
|
||||
sources = mm_modem_location_get_enabled(manager->mm_location);
|
||||
signal_location = mm_modem_location_signals_location(manager->mm_location);
|
||||
mm_modem_location_setup_sync(manager->mm_location, sources,
|
||||
signal_location, NULL, &error);
|
||||
if (error != NULL)
|
||||
|
Reference in New Issue
Block a user