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.
This commit is contained in:
ArenM
2021-09-07 19:48:40 -04:00
parent 750c41cbb5
commit 6177c7167c

View File

@@ -8,8 +8,12 @@
#include "manager.h" #include "manager.h"
#include "at.h" #include "at.h"
#include <sys/sendfile.h>
#include <sys/stat.h>
#include <errno.h>
#define BUFFER_SIZE 256 #define BUFFER_SIZE 256
#define UPLOAD_DELAY 100000 #define UPLOAD_DELAY_US 10000
#define RESCHEDULE_IN_SECS 30 #define RESCHEDULE_IN_SECS 30
static void gnss_step(struct EG25Manager *manager); 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) static void upload_assistance_data(struct EG25Manager *manager)
{ {
char buffer[2*BUFFER_SIZE]; gint error;
gint len; glong written_total = 0;
gboolean success = TRUE; gint ret;
struct stat sb;
/* Copy downloaded XTRA assistance data to the modem over serial */ if (fstat(manager->gnss_assistance_fd, &sb) != 0) {
while((len = read(manager->gnss_assistance_fd, buffer, 2*BUFFER_SIZE)) > 0) g_error("Unable to upload xtra data: %s", g_strerror(errno));
{
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);
} }
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 */ /* Clear QFUPL AT command and process next */
at_next_command(manager); at_next_command(manager);
/* Go to the next step if successful */ /* 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++; manager->gnss_assistance_step++;
gnss_step(manager); gnss_step(manager);
} } else {
/* Restart upload */ g_critical("Unable to upload xtra data: %s", g_strerror(error));
else {
g_message ("Rescheduling upload because of failure in %ds",
RESCHEDULE_IN_SECS);
manager->gnss_assistance_step = EG25_GNSS_STEP_LAST; manager->gnss_assistance_step = EG25_GNSS_STEP_LAST;
g_timeout_add_seconds(RESCHEDULE_IN_SECS,
G_SOURCE_FUNC(gnss_upload_assistance_data),
manager);
} }
} }