pmaports/modem/tqftpserv/0003-tqftpserv-handle-rsize-offset-options.patch
Luca Weiss d7c64500ee
modem/tqftpserv: upgrade and add patches for rsize & seek option handling (MR 4747)
Makes modem work on fairphone-fp4 (sm6350/sm7225) and fairphone-fp5
(sc7280/qcm6490)

Patches are submitted upstream:
https://github.com/andersson/tqftpserv/pull/13
[ci:skip-build]: already built successfully in CI
2024-03-06 01:50:52 +01:00

117 lines
3.9 KiB
Diff

From c56fa600c6c94950edafa157843e1891df523084 Mon Sep 17 00:00:00 2001
From: Luca Weiss <luca.weiss@fairphone.com>
Date: Fri, 19 Jan 2024 14:15:34 +0100
Subject: [PATCH 3/5] tqftpserv: handle rsize & offset options
The rsize (number of bytes the client wants to receive) and offset (the
offset in bytes from the start of file) are used on newer modems (such
as SM7225 or QCM6490), so let's support them properly.
Some examples to illustrate the usage:
* rsize=160 seek=52: we should send 160 bytes starting at byte 52 in the
requested file. With blksize=7680 this is a single 160(+4) sized
packet.
* rsize=313028 seek=81920: we should send in total 313028 bytes,
starting at byte 81920. With blksize=7680 and wsize=10 this spans
multiple windows of 10 packets each, that example would be packed into
41 packets with an ACK between every 10 windows - and a final ACK at
the end.
* rsize=53760 blksize=7680: We send 7 packets of 7680 bytes each, then
we send 1 packet with 0 bytes of data (only 4 bytes header) and then
get an ACK on packet 8.
---
tqftpserv.c | 39 +++++++++++++++++++++++++++++++++------
1 file changed, 33 insertions(+), 6 deletions(-)
diff --git a/tqftpserv.c b/tqftpserv.c
index eed99a1..b931346 100644
--- a/tqftpserv.c
+++ b/tqftpserv.c
@@ -74,9 +74,10 @@ static struct list_head readers = LIST_INIT(readers);
static struct list_head writers = LIST_INIT(writers);
static ssize_t tftp_send_data(struct tftp_client *client,
- unsigned int block, size_t offset)
+ unsigned int block, size_t offset, size_t rsize)
{
ssize_t len;
+ size_t send_len;
char *buf;
char *p;
@@ -98,8 +99,21 @@ static ssize_t tftp_send_data(struct tftp_client *client,
p += len;
- // printf("[TQFTP] Sending %zd bytes of DATA\n", p - buf);
- len = send(client->sock, buf, p - buf, 0);
+ /* If rsize was set, we should limit the data in the response to n bytes */
+ if (rsize != 0) {
+ /* Header (4 bytes) + data size */
+ send_len = 4 + rsize;
+ if (send_len > p - buf) {
+ printf("[TQFTP] requested data of %ld bytes but only read %ld bytes from file, rejecting\n", rsize, len);
+ free(buf);
+ return -EINVAL;
+ }
+ } else {
+ send_len = p - buf;
+ }
+
+ // printf("[TQFTP] Sending %zd bytes of DATA\n", send_len);
+ len = send(client->sock, buf, send_len, 0);
free(buf);
@@ -336,7 +350,7 @@ static void handle_rrq(const char *buf, size_t len, struct sockaddr_qrtr *sq)
rsize ? &rsize : NULL,
seek ? &seek : NULL);
} else {
- tftp_send_data(client, 1, 0);
+ tftp_send_data(client, 1, 0, 0);
}
}
@@ -418,7 +432,7 @@ static void handle_wrq(const char *buf, size_t len, struct sockaddr_qrtr *sq)
rsize ? &rsize : NULL,
seek ? &seek : NULL);
} else {
- tftp_send_data(client, 1, 0);
+ tftp_send_data(client, 1, 0, 0);
}
}
@@ -463,9 +477,19 @@ static int handle_reader(struct tftp_client *client)
last = buf[2] << 8 | buf[3];
// printf("[TQFTP] Got ack for %d\n", last);
+ /* We've sent enough data for rsize already */
+ if (last * client->blksize > client->rsize)
+ return 0;
+
for (block = last; block < last + client->wsize; block++) {
+ size_t offset = client->seek + block * client->blksize;
+ size_t rsize = 0;
+ /* Check if need to limit response size based for requested rsize */
+ if (block * client->blksize + client->blksize > client->rsize)
+ rsize = client->rsize - (block * client->blksize);
+
n = tftp_send_data(client, block + 1,
- block * client->blksize);
+ offset, rsize);
if (n < 0) {
printf("[TQFTP] Sent block %d failed: %zd\n", block + 1, n);
break;
@@ -473,6 +497,9 @@ static int handle_reader(struct tftp_client *client)
// printf("[TQFTP] Sent block %d of %zd\n", block + 1, n);
if (n == 0)
break;
+ /* We've sent enough data for rsize already */
+ if (block * client->blksize + client->blksize > client->rsize)
+ break;
}
return 1;
--
2.44.0