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
 
 /**