diff options
author | arehbein <arehbein@sysmocom.de> | 2023-04-11 13:30:29 +0200 |
---|---|---|
committer | arehbein <arehbein@sysmocom.de> | 2023-06-19 18:30:47 +0000 |
commit | 2c59d1285e8f4c47122e1749ff1ac60e99a1874e (patch) | |
tree | 48bf4d5b36f90368fd4f089bf4beb88f39b8a5bb | |
parent | 5099d99192e339db017dcae7968e4c6835d4d1ca (diff) |
gsm/ipa: Add segmentation callback
Add segmentation callback to be used by the streaming backend of libosmo-netif
Related: OS#5753, OS#5751
Change-Id: I3a639e6896cc3b3fc8e9b2e1a58254710efa0d3f
-rw-r--r-- | include/osmocom/gsm/ipa.h | 3 | ||||
-rw-r--r-- | src/gsm/ipa.c | 29 | ||||
-rw-r--r-- | src/gsm/libosmogsm.map | 1 |
3 files changed, 33 insertions, 0 deletions
diff --git a/include/osmocom/gsm/ipa.h b/include/osmocom/gsm/ipa.h index 851b58e0..8a4dd3ff 100644 --- a/include/osmocom/gsm/ipa.h +++ b/include/osmocom/gsm/ipa.h @@ -79,3 +79,6 @@ struct msgb *ipa_msg_alloc(int headroom); int ipa_msg_recv(int fd, struct msgb **rmsg); int ipa_msg_recv_buffered(int fd, struct msgb **rmsg, struct msgb **tmp_msg); + +/* Callback for segmenting TCP stream data into IPA packets */ +int ipa_segmentation_cb(struct msgb *msg); diff --git a/src/gsm/ipa.c b/src/gsm/ipa.c index 447e8e3d..93e34df2 100644 --- a/src/gsm/ipa.c +++ b/src/gsm/ipa.c @@ -30,6 +30,7 @@ #include <stdint.h> #include <errno.h> #include <stdlib.h> +#include <inttypes.h> #include <sys/types.h> @@ -718,4 +719,32 @@ struct msgb *ipa_msg_alloc(int headroom) return nmsg; } +/*! Segmentation callback used by libosmo-netif streaming backend + * See definition of `struct osmo_io_ops` for callback semantics + * \param[in] msg Original `struct msgb` received via osmo_io + * \returns The total packet length indicated by the first header, + * otherwise + * -EAGAIN, if the header has not been read yet, + * -ENOBUFS, if the header declares a payload too large + */ +int ipa_segmentation_cb(struct msgb *msg) +{ + const struct ipaccess_head *hh = (const struct ipaccess_head *) msg->data; + size_t payload_len, total_len; + size_t available = msgb_length(msg) + msgb_tailroom(msg); + if (msgb_length(msg) < sizeof(*hh)) { + /* Haven't even read the entire header */ + return -EAGAIN; + } + payload_len = osmo_ntohs(hh->len); + total_len = sizeof(*hh) + payload_len; + if (OSMO_UNLIKELY(available < total_len)) { + LOGP(DLINP, LOGL_ERROR, "Not enough space left in message buffer. " + "Have %zu octets, but need %zu\n", + available, total_len); + return -ENOBUFS; + } + return total_len; +} + /*! @} */ diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index 29bf94fd..1e5a7b20 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -689,6 +689,7 @@ ipa_ccm_id_get_parse; ipa_ccm_id_resp_parse; ipa_ccm_make_id_resp; ipa_ccm_make_id_resp_from_req; +ipa_segmentation_cb; ipa_msg_alloc; ipa_msg_recv; ipa_msg_recv_buffered; |