You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by cc...@apache.org on 2015/11/21 03:01:27 UTC
incubator-mynewt-larva git commit: Add copyinto and splice mbuf
functions.
Repository: incubator-mynewt-larva
Updated Branches:
refs/heads/master 065725d55 -> 02751e369
Add copyinto and splice mbuf functions.
Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/commit/02751e36
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/tree/02751e36
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/diff/02751e36
Branch: refs/heads/master
Commit: 02751e3695a18adbaa0313f29035bf4f3d8348d1
Parents: 065725d
Author: Christopher Collins <cc...@gmail.com>
Authored: Fri Nov 20 18:01:06 2015 -0800
Committer: Christopher Collins <cc...@gmail.com>
Committed: Fri Nov 20 18:01:06 2015 -0800
----------------------------------------------------------------------
libs/os/include/os/os_mbuf.h | 7 ++-
libs/os/src/os_mbuf.c | 127 +++++++++++++++++++++++++++++++++++++-
2 files changed, 129 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/02751e36/libs/os/include/os/os_mbuf.h
----------------------------------------------------------------------
diff --git a/libs/os/include/os/os_mbuf.h b/libs/os/include/os/os_mbuf.h
index d056730..3e3d56c 100644
--- a/libs/os/include/os/os_mbuf.h
+++ b/libs/os/include/os/os_mbuf.h
@@ -211,8 +211,8 @@ struct os_mbuf * os_mbuf_off(struct os_mbuf *om, int off, int *out_off);
int os_mbuf_copydata(const struct os_mbuf *m, int off, int len, void *dst);
/* Append data onto a mbuf */
-int os_mbuf_append(struct os_mbuf_pool *omp, struct os_mbuf *m, void *,
- uint16_t);
+int os_mbuf_append(struct os_mbuf_pool *omp, struct os_mbuf *m,
+ const void *data, uint16_t len);
/* Free a mbuf */
int os_mbuf_free(struct os_mbuf_pool *omp, struct os_mbuf *mb);
@@ -226,5 +226,8 @@ int os_mbuf_memcmp(const struct os_mbuf *om, int off, const void *data,
struct os_mbuf *os_mbuf_prepend(struct os_mbuf_pool *omp, struct os_mbuf *om,
int len);
+int os_mbuf_copyinto(struct os_mbuf_pool *omp, struct os_mbuf *om, int off,
+ const void *src, int len);
+void os_mbuf_splice(struct os_mbuf *first, struct os_mbuf *second);
#endif /* _OS_MBUF_H */
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/02751e36/libs/os/src/os_mbuf.c
----------------------------------------------------------------------
diff --git a/libs/os/src/os_mbuf.c b/libs/os/src/os_mbuf.c
index 0b51793..a48325c 100644
--- a/libs/os/src/os_mbuf.c
+++ b/libs/os/src/os_mbuf.c
@@ -205,7 +205,7 @@ _os_mbuf_copypkthdr(struct os_mbuf_pool *omp, struct os_mbuf *new_buf,
* @return 0 on success, and an error code on failure
*/
int
-os_mbuf_append(struct os_mbuf_pool *omp, struct os_mbuf *om, void *data,
+os_mbuf_append(struct os_mbuf_pool *omp, struct os_mbuf *om, const void *data,
uint16_t len)
{
struct os_mbuf *last;
@@ -342,18 +342,24 @@ err:
struct os_mbuf *
os_mbuf_off(struct os_mbuf *om, int off, int *out_off)
{
+ struct os_mbuf *next;
+
while (1) {
if (om == NULL) {
return NULL;
}
- if (om->om_len >= off) {
+ next = SLIST_NEXT(om, om_next);
+
+ if (om->om_len > off ||
+ (om->om_len == off && next == NULL)) {
+
*out_off = off;
return om;
}
off -= om->om_len;
- om = SLIST_NEXT(om, om_next);
+ om = next;
}
}
@@ -589,6 +595,121 @@ os_mbuf_prepend(struct os_mbuf_pool *omp, struct os_mbuf *om, int len)
return om;
}
+/**
+ * Copies the contents of a flat buffer into an mbuf chain, starting at the
+ * specified destination offset. If the mbuf is too small for the source data,
+ * it is extended as necessary. If the destination mbuf contains a packet
+ * header, the header length is updated.
+ *
+ * @param omp The mbuf pool to allocate from.
+ * @param om The mbuf chain to copy into.
+ * @param off The offset within the chain to copy to.
+ * @param src The source buffer to copy from.
+ * @param len The number of bytes to copy.
+ *
+ * @return 0 on success; nonzero on failure.
+ */
+int
+os_mbuf_copyinto(struct os_mbuf_pool *omp, struct os_mbuf *om, int off,
+ const void *src, int len)
+{
+ struct os_mbuf *next;
+ struct os_mbuf *cur;
+ const uint8_t *sptr;
+ int copylen;
+ int cur_off;
+ int rc;
+
+ /* Find the mbuf,offset pair for the start of the destination. */
+ cur = os_mbuf_off(om, off, &cur_off);
+ if (cur == NULL) {
+ return -1;
+ }
+
+ /* Overwrite existing data until we reach the end of the chain. */
+ sptr = src;
+ while (1) {
+ copylen = min(cur->om_len - cur_off, len);
+ if (copylen > 0) {
+ memcpy(cur->om_data + cur_off, sptr, copylen);
+ sptr += copylen;
+ len -= copylen;
+
+ copylen = 0;
+ }
+
+ if (len == 0) {
+ /* All the source data fit in the existing mbuf chain. */
+ return 0;
+ }
+
+ next = SLIST_NEXT(cur, om_next);
+ if (next == NULL) {
+ break;
+ }
+
+ cur = next;
+ }
+
+ /* Append the remaining data to the end of the chain. */
+ rc = os_mbuf_append(omp, cur, sptr, len);
+ if (rc != 0) {
+ return rc;
+ }
+
+ /* Fix up the packet header, if one is present. */
+ if (OS_MBUF_IS_PKTHDR(om)) {
+ OS_MBUF_PKTHDR(om)->omp_len =
+ max(OS_MBUF_PKTHDR(om)->omp_len, off + len);
+ }
+
+ return 0;
+}
+
+/**
+ * Attaches a second mbuf chain onto the end of the first. If the first chain
+ * contains a packet header, the header's length is updated. If the second
+ * chain has a packet header, its header is cleared.
+ *
+ * @param first The mbuf chain being attached to.
+ * @param second The mbuf chain that gets attached.
+ */
+void
+os_mbuf_splice(struct os_mbuf *first, struct os_mbuf *second)
+{
+ struct os_mbuf *next;
+ struct os_mbuf *cur;
+
+ /* Point 'cur' to the last buffer in the first chain. */
+ cur = first;
+ while (1) {
+ next = SLIST_NEXT(cur, om_next);
+ if (next == NULL) {
+ break;
+ }
+
+ cur = next;
+ }
+
+ /* Attach the second chain to the end of the first. */
+ SLIST_NEXT(cur, om_next) = second;
+
+ /* If the first chain has a packet header, calculate the length of the
+ * second chain and add it to the header length.
+ */
+ if (OS_MBUF_IS_PKTHDR(first)) {
+ if (OS_MBUF_IS_PKTHDR(second)) {
+ OS_MBUF_PKTHDR(first)->omp_len += OS_MBUF_PKTHDR(second)->omp_len;
+ } else {
+ for (cur = second; cur != NULL; cur = SLIST_NEXT(cur, om_next)) {
+ OS_MBUF_PKTHDR(first)->omp_len += cur->om_len;
+ }
+ }
+ }
+
+ second->om_flags &= ~OS_MBUF_F_PKTHDR;
+}
+
#if 0
/**