From 6177c7167cdd6dbc103f42a4797d153abf01f6d0 Mon Sep 17 00:00:00 2001 From: ArenM Date: Tue, 7 Sep 2021 19:48:40 -0400 Subject: [PATCH] gnss: use sendfile to upload xtra data This should make the data upload much faster because it handles incomplete writes better, and because it the kernel copies the data between the files directly, and it doesn't get sent to userspace and back. --- src/gnss.c | 47 +++++++++++++++++++++++------------------------ 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/src/gnss.c b/src/gnss.c index 64fcbcf..2a1b38a 100644 --- a/src/gnss.c +++ b/src/gnss.c @@ -8,8 +8,12 @@ #include "manager.h" #include "at.h" +#include +#include +#include + #define BUFFER_SIZE 256 -#define UPLOAD_DELAY 100000 +#define UPLOAD_DELAY_US 10000 #define RESCHEDULE_IN_SECS 30 static void gnss_step(struct EG25Manager *manager); @@ -297,39 +301,34 @@ 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; - /* 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); + if (fstat(manager->gnss_assistance_fd, &sb) != 0) { + g_error("Unable to upload xtra data: %s", g_strerror(errno)); } + do { + errno = 0; + /* Copy downloaded XTRA assistance data to the modem over serial */ + 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); } }