1 /*
2 * SPDX-FileCopyrightText: 2015-2022 The Apache Software Foundation (ASF)
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * SPDX-FileContributor: 2019-2022 Espressif Systems (Shanghai) CO LTD
7 */
8 /*
9 * Licensed to the Apache Software Foundation (ASF) under one
10 * or more contributor license agreements. See the NOTICE file
11 * distributed with this work for additional information
12 * regarding copyright ownership. The ASF licenses this file
13 * to you under the Apache License, Version 2.0 (the
14 * "License"); you may not use this file except in compliance
15 * with the License. You may obtain a copy of the License at
16 *
17 * http://www.apache.org/licenses/LICENSE-2.0
18 *
19 * Unless required by applicable law or agreed to in writing,
20 * software distributed under the License is distributed on an
21 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
22 * KIND, either express or implied. See the License for the
23 * specific language governing permissions and limitations
24 * under the License.
25 */
26
27
28 /**
29 * @addtogroup OSKernel
30 * @{
31 * @defgroup OSMbuf Chained Memory Buffers
32 * @{
33 */
34
35
36 #ifndef _OS_MBUF_H
37 #define _OS_MBUF_H
38
39 #include "os/os.h"
40
41 #ifdef __cplusplus
42 extern "C" {
43 #endif
44
45 /**
46 * A mbuf pool from which to allocate mbufs. This contains a pointer to the os
47 * mempool to allocate mbufs out of, the total number of elements in the pool,
48 * and the amount of "user" data in a non-packet header mbuf. The total pool
49 * size, in bytes, should be:
50 * os_mbuf_count * (omp_databuf_len + sizeof(struct os_mbuf))
51 */
52 struct os_mbuf_pool {
53 /**
54 * Total length of the databuf in each mbuf. This is the size of the
55 * mempool block, minus the mbuf header
56 */
57 uint16_t omp_databuf_len;
58 /**
59 * The memory pool which to allocate mbufs out of
60 */
61 struct os_mempool *omp_pool;
62
63 STAILQ_ENTRY(os_mbuf_pool) omp_next;
64 };
65
66
67 /**
68 * A packet header structure that preceeds the mbuf packet headers.
69 */
70 struct os_mbuf_pkthdr {
71 /**
72 * Overall length of the packet.
73 */
74 uint16_t omp_len;
75 /**
76 * Flags
77 */
78 uint16_t omp_flags;
79
80 STAILQ_ENTRY(os_mbuf_pkthdr) omp_next;
81 };
82
83 /**
84 * Chained memory buffer.
85 */
86 struct os_mbuf {
87 /**
88 * Current pointer to data in the structure
89 */
90 uint8_t *om_data;
91 /**
92 * Flags associated with this buffer, see OS_MBUF_F_* defintions
93 */
94 uint8_t om_flags;
95 /**
96 * Length of packet header
97 */
98 uint8_t om_pkthdr_len;
99 /**
100 * Length of data in this buffer
101 */
102 uint16_t om_len;
103
104 /**
105 * The mbuf pool this mbuf was allocated out of
106 */
107 struct os_mbuf_pool *om_omp;
108
109 SLIST_ENTRY(os_mbuf) om_next;
110
111 /**
112 * Pointer to the beginning of the data, after this buffer
113 */
114 uint8_t om_databuf[0];
115 };
116
117 /**
118 * Structure representing a queue of mbufs.
119 */
120 struct os_mqueue {
121 STAILQ_HEAD(, os_mbuf_pkthdr) mq_head;
122 /** Event to post when new buffers are available on the queue. */
123 struct ble_npl_event mq_ev;
124 };
125
126 /*
127 * Given a flag number, provide the mask for it
128 *
129 * @param __n The number of the flag in the mask
130 */
131 #define OS_MBUF_F_MASK(__n) (1 << (__n))
132
133 /*
134 * Checks whether a given mbuf is a packet header mbuf
135 *
136 * @param __om The mbuf to check
137 */
138 #define OS_MBUF_IS_PKTHDR(__om) \
139 ((__om)->om_pkthdr_len >= sizeof (struct os_mbuf_pkthdr))
140
141 /** Get a packet header pointer given an mbuf pointer */
142 #define OS_MBUF_PKTHDR(__om) ((struct os_mbuf_pkthdr *) \
143 (void *)((uint8_t *)&(__om)->om_data + sizeof(struct os_mbuf)))
144
145 /** Given a mbuf packet header pointer, return a pointer to the mbuf */
146 #define OS_MBUF_PKTHDR_TO_MBUF(__hdr) \
147 (struct os_mbuf *)(void *)((uint8_t *)(__hdr) - sizeof(struct os_mbuf))
148
149 /**
150 * Gets the length of an entire mbuf chain. The specified mbuf must have a
151 * packet header.
152 */
153 #define OS_MBUF_PKTLEN(__om) (OS_MBUF_PKTHDR(__om)->omp_len)
154
155 /**
156 * Access the data of a mbuf, and cast it to type
157 *
158 * @param __om The mbuf to access, and cast
159 * @param __type The type to cast it to
160 */
161 #define OS_MBUF_DATA(__om, __type) \
162 (__type) ((__om)->om_data)
163
164 /**
165 * Access the "user header" in the head of an mbuf chain.
166 *
167 * @param om Pointer to the head of an mbuf chain.
168 */
169 #define OS_MBUF_USRHDR(om) \
170 (void *)((uint8_t *)om + sizeof (struct os_mbuf) + \
171 sizeof (struct os_mbuf_pkthdr))
172
173 /**
174 * Retrieves the length of the user header in an mbuf.
175 *
176 * @param om Pointer to the mbuf to query.
177 */
178 #define OS_MBUF_USRHDR_LEN(om) \
179 ((om)->om_pkthdr_len - sizeof (struct os_mbuf_pkthdr))
180
181
182 /** @cond INTERNAL_HIDDEN */
183
184 /*
185 * Called by OS_MBUF_LEADINGSPACE() macro
186 */
187 static inline uint16_t
_os_mbuf_leadingspace(struct os_mbuf * om)188 _os_mbuf_leadingspace(struct os_mbuf *om)
189 {
190 uint16_t startoff;
191 uint16_t leadingspace;
192
193 startoff = 0;
194 if (OS_MBUF_IS_PKTHDR(om)) {
195 startoff = om->om_pkthdr_len;
196 }
197
198 leadingspace = (uint16_t) (OS_MBUF_DATA(om, uint8_t *) -
199 ((uint8_t *) &om->om_databuf[0] + startoff));
200
201 return (leadingspace);
202 }
203
204 /** @endcond */
205
206 /**
207 * Returns the leading space (space at the beginning) of the mbuf.
208 * Works on both packet header, and regular mbufs, as it accounts
209 * for the additional space allocated to the packet header.
210 *
211 * @param __omp Is the mbuf pool (which contains packet header length.)
212 * @param __om Is the mbuf in that pool to get the leadingspace for
213 *
214 * @return Amount of leading space available in the mbuf
215 */
216 #define OS_MBUF_LEADINGSPACE(__om) _os_mbuf_leadingspace(__om)
217
218
219 /** @cond INTERNAL_HIDDEN */
220
221 /* Called by OS_MBUF_TRAILINGSPACE() macro. */
222 static inline uint16_t
_os_mbuf_trailingspace(struct os_mbuf * om)223 _os_mbuf_trailingspace(struct os_mbuf *om)
224 {
225 struct os_mbuf_pool *omp;
226
227 omp = om->om_omp;
228
229 return (&om->om_databuf[0] + omp->omp_databuf_len) -
230 (om->om_data + om->om_len);
231 }
232
233 /** @endcond */
234
235 /**
236 * Returns the trailing space (space at the end) of the mbuf.
237 * Works on both packet header and regular mbufs.
238 *
239 * @param __omp The mbuf pool for this mbuf
240 * @param __om Is the mbuf in that pool to get trailing space for
241 *
242 * @return The amount of trailing space available in the mbuf
243 */
244 #define OS_MBUF_TRAILINGSPACE(__om) _os_mbuf_trailingspace(__om)
245
246
247 #if SOC_ESP_NIMBLE_CONTROLLER
248 /**
249 * Initializes an mqueue. An mqueue is a queue of mbufs that ties to a
250 * particular task's event queue. Mqueues form a helper API around a common
251 * paradigm: wait on an event queue until at least one packet is available,
252 * then process a queue of packets.
253 *
254 * When mbufs are available on the queue, an event OS_EVENT_T_MQUEUE_DATA
255 * will be posted to the task's mbuf queue.
256 *
257 * @param mq The mqueue to initialize
258 * @param ev_cb The callback to associate with the mqeueue
259 * event. Typically, this callback pulls each
260 * packet off the mqueue and processes them.
261 * @param arg The argument to associate with the mqueue event.
262 *
263 * @return 0 on success, non-zero on failure.
264 */
265 int r_os_mqueue_init(struct os_mqueue *mq, ble_npl_event_fn *ev_cb, void *arg);
266 #define os_mqueue_init r_os_mqueue_init
267
268
269 /**
270 * Remove and return a single mbuf from the mbuf queue. Does not block.
271 *
272 * @param mq The mbuf queue to pull an element off of.
273 *
274 * @return The next mbuf in the queue, or NULL if queue has no mbufs.
275 */
276 struct os_mbuf *r_os_mqueue_get(struct os_mqueue *);
277 #define os_mqueue_get r_os_mqueue_get
278 /**
279 * Adds a packet (i.e. packet header mbuf) to an mqueue. The event associated
280 * with the mqueue gets posted to the specified eventq.
281 *
282 * @param mq The mbuf queue to append the mbuf to.
283 * @param evq The event queue to post an event to.
284 * @param m The mbuf to append to the mbuf queue.
285 *
286 * @return 0 on success, non-zero on failure.
287 */
288 int r_os_mqueue_put(struct os_mqueue *, struct ble_npl_eventq *, struct os_mbuf *);
289 #define os_mqueue_put r_os_mqueue_put
290
291
292 /**
293 * MSYS is a system level mbuf registry. Allows the system to share
294 * packet buffers amongst the various networking stacks that can be running
295 * simultaeneously.
296 *
297 * Mbuf pools are created in the system initialization code, and then when
298 * a mbuf is allocated out of msys, it will try and find the best fit based
299 * upon estimated mbuf size.
300 *
301 * os_msys_register() registers a mbuf pool with MSYS, and allows MSYS to
302 * allocate mbufs out of it.
303 *
304 * @param new_pool The pool to register with MSYS
305 *
306 * @return 0 on success, non-zero on failure
307 */
308 int r_os_msys_register(struct os_mbuf_pool *);
309 #define os_msys_register r_os_msys_register
310
311
312 /**
313 * Allocate a mbuf from msys. Based upon the data size requested,
314 * os_msys_get() will choose the mbuf pool that has the best fit.
315 *
316 * @param dsize The estimated size of the data being stored in the mbuf
317 * @param leadingspace The amount of leadingspace to allocate in the mbuf
318 *
319 * @return A freshly allocated mbuf on success, NULL on failure.
320 */
321 struct os_mbuf *r_os_msys_get(uint16_t dsize, uint16_t leadingspace);
322 #define os_msys_get r_os_msys_get
323 /**
324 * De-registers all mbuf pools from msys.
325 */
326 void r_os_msys_reset(void);
327 #define os_msys_reset r_os_msys_reset
328
329
330 /**
331 * Allocate a packet header structure from the MSYS pool. See
332 * os_msys_register() for a description of MSYS.
333 *
334 * @param dsize The estimated size of the data being stored in the mbuf
335 * @param user_hdr_len The length to allocate for the packet header structure
336 *
337 * @return A freshly allocated mbuf on success, NULL on failure.
338 */
339 struct os_mbuf *r_os_msys_get_pkthdr(uint16_t dsize, uint16_t user_hdr_len);
340 #define os_msys_get_pkthdr r_os_msys_get_pkthdr
341 /**
342 * Count the number of blocks in all the mbuf pools that are allocated.
343 *
344 * @return total number of blocks allocated in Msys
345 */
346 int r_os_msys_count(void);
347 #define os_msys_count r_os_msys_count
348
349
350 /**
351 * Return the number of free blocks in Msys
352 *
353 * @return Number of free blocks available in Msys
354 */
355 int r_os_msys_num_free(void);
356 #define os_msys_num_free r_os_msys_num_free
357
358
359 /**
360 * Initialize a pool of mbufs.
361 *
362 * @param omp The mbuf pool to initialize
363 * @param mp The memory pool that will hold this mbuf pool
364 * @param buf_len The length of the buffer itself.
365 * @param nbufs The number of buffers in the pool
366 *
367 * @return 0 on success, error code on failure.
368 */
369 int r_os_mbuf_pool_init(struct os_mbuf_pool *, struct os_mempool *mp,
370 uint16_t, uint16_t);
371 #define os_mbuf_pool_init r_os_mbuf_pool_init
372 /**
373 * Get an mbuf from the mbuf pool. The mbuf is allocated, and initialized
374 * prior to being returned.
375 *
376 * @param omp The mbuf pool to return the packet from
377 * @param leadingspace The amount of leadingspace to put before the data
378 * section by default.
379 *
380 * @return An initialized mbuf on success, and NULL on failure.
381 */
382 struct os_mbuf *r_os_mbuf_get(struct os_mbuf_pool *omp, uint16_t);
383 #define os_mbuf_get r_os_mbuf_get
384 /**
385 * Allocate a new packet header mbuf out of the os_mbuf_pool.
386 *
387 * @param omp The mbuf pool to allocate out of
388 * @param user_pkthdr_len The packet header length to reserve for the caller.
389 *
390 * @return A freshly allocated mbuf on success, NULL on failure.
391 */
392 struct os_mbuf *r_os_mbuf_get_pkthdr(struct os_mbuf_pool *omp,
393 uint8_t pkthdr_len);
394 #define os_mbuf_get_pkthdr r_os_mbuf_get_pkthdr
395 /**
396 * Duplicate a chain of mbufs. Return the start of the duplicated chain.
397 *
398 * @param omp The mbuf pool to duplicate out of
399 * @param om The mbuf chain to duplicate
400 *
401 * @return A pointer to the new chain of mbufs
402 */
403 struct os_mbuf *r_os_mbuf_dup(struct os_mbuf *m);
404 #define os_mbuf_dup r_os_mbuf_dup
405 /**
406 * Locates the specified absolute offset within an mbuf chain. The offset
407 * can be one past than the total length of the chain, but no greater.
408 *
409 * @param om The start of the mbuf chain to seek within.
410 * @param off The absolute address to find.
411 * @param out_off On success, this points to the relative offset
412 * within the returned mbuf.
413 *
414 * @return The mbuf containing the specified offset on
415 * success.
416 * NULL if the specified offset is out of bounds.
417 */
418 struct os_mbuf *r_os_mbuf_off(const struct os_mbuf *om, int off,
419 uint16_t *out_off);
420 #define os_mbuf_off r_os_mbuf_off
421
422 /*
423 * Copy data from an mbuf chain starting "off" bytes from the beginning,
424 * continuing for "len" bytes, into the indicated buffer.
425 *
426 * @param m The mbuf chain to copy from
427 * @param off The offset into the mbuf chain to begin copying from
428 * @param len The length of the data to copy
429 * @param dst The destination buffer to copy into
430 *
431 * @return 0 on success;
432 * -1 if the mbuf does not contain enough data.
433 */
434 int r_os_mbuf_copydata(const struct os_mbuf *m, int off, int len, void *dst);
435 #define os_mbuf_copydata r_os_mbuf_copydata
436
437
438 /**
439 * @brief Calculates the length of an mbuf chain.
440 *
441 * Calculates the length of an mbuf chain. If the mbuf contains a packet
442 * header, you should use `OS_MBUF_PKTLEN()` as a more efficient alternative to
443 * this function.
444 *
445 * @param om The mbuf to measure.
446 *
447 * @return The length, in bytes, of the provided mbuf
448 * chain.
449 */
450 uint16_t r_os_mbuf_len(const struct os_mbuf *om);
451 #define os_mbuf_len r_os_mbuf_len
452
453
454 /**
455 * Append data onto a mbuf
456 *
457 * @param om The mbuf to append the data onto
458 * @param data The data to append onto the mbuf
459 * @param len The length of the data to append
460 *
461 * @return 0 on success, and an error code on failure
462 */
463 int r_os_mbuf_append(struct os_mbuf *m, const void *, uint16_t);
464 #define os_mbuf_append r_os_mbuf_append
465
466
467 /**
468 * Reads data from one mbuf and appends it to another. On error, the specified
469 * data range may be partially appended. Neither mbuf is required to contain
470 * an mbuf packet header.
471 *
472 * @param dst The mbuf to append to.
473 * @param src The mbuf to copy data from.
474 * @param src_off The absolute offset within the source mbuf
475 * chain to read from.
476 * @param len The number of bytes to append.
477 *
478 * @return 0 on success;
479 * OS_EINVAL if the specified range extends beyond
480 * the end of the source mbuf chain.
481 */
482 int r_os_mbuf_appendfrom(struct os_mbuf *dst, const struct os_mbuf *src,
483 uint16_t src_off, uint16_t len);
484 #define os_mbuf_appendfrom r_os_mbuf_appendfrom
485 /**
486 * Release a mbuf back to the pool
487 *
488 * @param omp The Mbuf pool to release back to
489 * @param om The Mbuf to release back to the pool
490 *
491 * @return 0 on success, -1 on failure
492 */
493 int r_os_mbuf_free(struct os_mbuf *mb);
494 #define os_mbuf_free r_os_mbuf_free
495
496
497 /**
498 * Free a chain of mbufs
499 *
500 * @param omp The mbuf pool to free the chain of mbufs into
501 * @param om The starting mbuf of the chain to free back into the pool
502 *
503 * @return 0 on success, -1 on failure
504 */
505 int r_os_mbuf_free_chain(struct os_mbuf *om);
506 #define os_mbuf_free_chain r_os_mbuf_free_chain
507
508
509 /**
510 * Adjust the length of a mbuf, trimming either from the head or the tail
511 * of the mbuf.
512 *
513 * @param mp The mbuf chain to adjust
514 * @param req_len The length to trim from the mbuf. If positive, trims
515 * from the head of the mbuf, if negative, trims from the
516 * tail of the mbuf.
517 */
518 void r_os_mbuf_adj(struct os_mbuf *mp, int req_len);
519 #define os_mbuf_adj r_os_mbuf_adj
520
521
522
523 /**
524 * Performs a memory compare of the specified region of an mbuf chain against a
525 * flat buffer.
526 *
527 * @param om The start of the mbuf chain to compare.
528 * @param off The offset within the mbuf chain to start the
529 * comparison.
530 * @param data The flat buffer to compare.
531 * @param len The length of the flat buffer.
532 *
533 * @return 0 if both memory regions are identical;
534 * A memcmp return code if there is a mismatch;
535 * INT_MAX if the mbuf is too short.
536 */
537 int r_os_mbuf_cmpf(const struct os_mbuf *om, int off, const void *data, int len);
538 #define os_mbuf_cmpf r_os_mbuf_cmpf
539
540
541 /**
542 * Compares the contents of two mbuf chains. The ranges of the two chains to
543 * be compared are specified via the two offset parameters and the len
544 * parameter. Neither mbuf chain is required to contain a packet header.
545 *
546 * @param om1 The first mbuf chain to compare.
547 * @param offset1 The absolute offset within om1 at which to
548 * start the comparison.
549 * @param om2 The second mbuf chain to compare.
550 * @param offset2 The absolute offset within om2 at which to
551 * start the comparison.
552 * @param len The number of bytes to compare.
553 *
554 * @return 0 if both mbuf segments are identical;
555 * A memcmp() return code if the segment contents
556 * differ;
557 * INT_MAX if a specified range extends beyond the
558 * end of its corresponding mbuf chain.
559 */
560 int r_os_mbuf_cmpm(const struct os_mbuf *om1, uint16_t offset1,
561 const struct os_mbuf *om2, uint16_t offset2,
562 uint16_t len);
563 #define os_mbuf_cmpm r_os_mbuf_cmpm
564 /**
565 * Increases the length of an mbuf chain by adding data to the front. If there
566 * is insufficient room in the leading mbuf, additional mbufs are allocated and
567 * prepended as necessary. If this function fails to allocate an mbuf, the
568 * entire chain is freed.
569 *
570 * The specified mbuf chain does not need to contain a packet header.
571 *
572 * @param omp The mbuf pool to allocate from.
573 * @param om The head of the mbuf chain.
574 * @param len The number of bytes to prepend.
575 *
576 * @return The new head of the chain on success;
577 * NULL on failure.
578 */
579 struct os_mbuf *r_os_mbuf_prepend(struct os_mbuf *om, int len);
580 #define os_mbuf_prepend r_os_mbuf_prepend
581 /**
582 * Prepends a chunk of empty data to the specified mbuf chain and ensures the
583 * chunk is contiguous. If either operation fails, the specified mbuf chain is
584 * freed and NULL is returned.
585 *
586 * @param om The mbuf chain to prepend to.
587 * @param len The number of bytes to prepend and pullup.
588 *
589 * @return The modified mbuf on success;
590 * NULL on failure (and the mbuf chain is freed).
591 */
592 struct os_mbuf *r_os_mbuf_prepend_pullup(struct os_mbuf *om, uint16_t len);
593 #define os_mbuf_prepend_pullup r_os_mbuf_prepend_pullup
594 /**
595 * Copies the contents of a flat buffer into an mbuf chain, starting at the
596 * specified destination offset. If the mbuf is too small for the source data,
597 * it is extended as necessary. If the destination mbuf contains a packet
598 * header, the header length is updated.
599 *
600 * @param omp The mbuf pool to allocate from.
601 * @param om The mbuf chain to copy into.
602 * @param off The offset within the chain to copy to.
603 * @param src The source buffer to copy from.
604 * @param len The number of bytes to copy.
605 *
606 * @return 0 on success; nonzero on failure.
607 */
608 int r_os_mbuf_copyinto(struct os_mbuf *om, int off, const void *src, int len);
609 #define os_mbuf_copyinto r_os_mbuf_copyinto
610
611
612 /**
613 * Attaches a second mbuf chain onto the end of the first. If the first chain
614 * contains a packet header, the header's length is updated. If the second
615 * chain has a packet header, its header is cleared.
616 *
617 * @param first The mbuf chain being attached to.
618 * @param second The mbuf chain that gets attached.
619 */
620 void r_os_mbuf_concat(struct os_mbuf *first, struct os_mbuf *second);
621 #define os_mbuf_concat r_os_mbuf_concat
622
623
624
625 /**
626 * Increases the length of an mbuf chain by the specified amount. If there is
627 * not sufficient room in the last buffer, a new buffer is allocated and
628 * appended to the chain. It is an error to request more data than can fit in
629 * a single buffer.
630 *
631 * @param omp
632 * @param om The head of the chain to extend.
633 * @param len The number of bytes to extend by.
634 *
635 * @return A pointer to the new data on success;
636 * NULL on failure.
637 */
638 void *r_os_mbuf_extend(struct os_mbuf *om, uint16_t len);
639 #define os_mbuf_extend r_os_mbuf_extend
640 /**
641 * Rearrange a mbuf chain so that len bytes are contiguous,
642 * and in the data area of an mbuf (so that OS_MBUF_DATA() will
643 * work on a structure of size len.) Returns the resulting
644 * mbuf chain on success, free's it and returns NULL on failure.
645 *
646 * If there is room, it will add up to "max_protohdr - len"
647 * extra bytes to the contiguous region, in an attempt to avoid being
648 * called next time.
649 *
650 * @param omp The mbuf pool to take the mbufs out of
651 * @param om The mbuf chain to make contiguous
652 * @param len The number of bytes in the chain to make contiguous
653 *
654 * @return The contiguous mbuf chain on success, NULL on failure.
655 */
656 struct os_mbuf *r_os_mbuf_pullup(struct os_mbuf *om, uint16_t len);
657 #define os_mbuf_pullup r_os_mbuf_pullup
658
659 /**
660 * Removes and frees empty mbufs from the front of a chain. If the chain
661 * contains a packet header, it is preserved.
662 *
663 * @param om The mbuf chain to trim.
664 *
665 * @return The head of the trimmed mbuf chain.
666 */
667 struct os_mbuf *r_os_mbuf_trim_front(struct os_mbuf *om);
668 #define os_mbuf_trim_front r_os_mbuf_trim_front
669 /**
670 * Increases the length of an mbuf chain by inserting a gap at the specified
671 * offset. The contents of the gap are indeterminate. If the mbuf chain
672 * contains a packet header, its total length is increased accordingly.
673 *
674 * This function never frees the provided mbuf chain.
675 *
676 * @param om The mbuf chain to widen.
677 * @param off The offset at which to insert the gap.
678 * @param len The size of the gap to insert.
679 *
680 * @return 0 on success; SYS_[...] error code on failure.
681 */
682 int r_os_mbuf_widen(struct os_mbuf *om, uint16_t off, uint16_t len);
683 #define os_mbuf_widen r_os_mbuf_widen
684
685
686
687 /**
688 * Creates a single chained mbuf from m1 and m2 utilizing all
689 * the available buffer space in all mbufs in the resulting
690 * chain. In other words, ensures there is no leading space in
691 * any mbuf in the resulting chain and trailing space only in
692 * the last mbuf in the chain. Mbufs from either chain may be
693 * freed if not needed. No mbufs are allocated. Note that mbufs
694 * from m2 are added to the end of m1. If m1 has a packet
695 * header, it is retained and length updated. If m2 has a packet
696 * header it is discarded. If m1 is NULL, NULL is returned and
697 * m2 is left untouched.
698 *
699 * @param m1 Pointer to first mbuf chain to pack
700 * @param m2 Pointer to second mbuf chain to pack
701 *
702 * @return struct os_mbuf* Pointer to resulting mbuf chain
703 */
704 struct os_mbuf *r_os_mbuf_pack_chains(struct os_mbuf *m1, struct os_mbuf *m2);
705 #define os_mbuf_pack_chains r_os_mbuf_pack_chains
706
707 #else
708 /**
709 * Initializes an mqueue. An mqueue is a queue of mbufs that ties to a
710 * particular task's event queue. Mqueues form a helper API around a common
711 * paradigm: wait on an event queue until at least one packet is available,
712 * then process a queue of packets.
713 *
714 * When mbufs are available on the queue, an event OS_EVENT_T_MQUEUE_DATA
715 * will be posted to the task's mbuf queue.
716 *
717 * @param mq The mqueue to initialize
718 * @param ev_cb The callback to associate with the mqeueue
719 * event. Typically, this callback pulls each
720 * packet off the mqueue and processes them.
721 * @param arg The argument to associate with the mqueue event.
722 *
723 * @return 0 on success, non-zero on failure.
724 */
725 int os_mqueue_init(struct os_mqueue *mq, ble_npl_event_fn *ev_cb, void *arg);
726
727 /**
728 * Remove and return a single mbuf from the mbuf queue. Does not block.
729 *
730 * @param mq The mbuf queue to pull an element off of.
731 *
732 * @return The next mbuf in the queue, or NULL if queue has no mbufs.
733 */
734 struct os_mbuf *os_mqueue_get(struct os_mqueue *);
735
736 /**
737 * Adds a packet (i.e. packet header mbuf) to an mqueue. The event associated
738 * with the mqueue gets posted to the specified eventq.
739 *
740 * @param mq The mbuf queue to append the mbuf to.
741 * @param evq The event queue to post an event to.
742 * @param m The mbuf to append to the mbuf queue.
743 *
744 * @return 0 on success, non-zero on failure.
745 */
746 int os_mqueue_put(struct os_mqueue *, struct ble_npl_eventq *, struct os_mbuf *);
747
748 /**
749 * MSYS is a system level mbuf registry. Allows the system to share
750 * packet buffers amongst the various networking stacks that can be running
751 * simultaeneously.
752 *
753 * Mbuf pools are created in the system initialization code, and then when
754 * a mbuf is allocated out of msys, it will try and find the best fit based
755 * upon estimated mbuf size.
756 *
757 * os_msys_register() registers a mbuf pool with MSYS, and allows MSYS to
758 * allocate mbufs out of it.
759 *
760 * @param new_pool The pool to register with MSYS
761 *
762 * @return 0 on success, non-zero on failure
763 */
764 int os_msys_register(struct os_mbuf_pool *);
765
766 /**
767 * Allocate a mbuf from msys. Based upon the data size requested,
768 * os_msys_get() will choose the mbuf pool that has the best fit.
769 *
770 * @param dsize The estimated size of the data being stored in the mbuf
771 * @param leadingspace The amount of leadingspace to allocate in the mbuf
772 *
773 * @return A freshly allocated mbuf on success, NULL on failure.
774 */
775 struct os_mbuf *os_msys_get(uint16_t dsize, uint16_t leadingspace);
776
777 /**
778 * De-registers all mbuf pools from msys.
779 */
780 void os_msys_reset(void);
781
782 /**
783 * Allocate a packet header structure from the MSYS pool. See
784 * os_msys_register() for a description of MSYS.
785 *
786 * @param dsize The estimated size of the data being stored in the mbuf
787 * @param user_hdr_len The length to allocate for the packet header structure
788 *
789 * @return A freshly allocated mbuf on success, NULL on failure.
790 */
791 struct os_mbuf *os_msys_get_pkthdr(uint16_t dsize, uint16_t user_hdr_len);
792
793 /**
794 * Count the number of blocks in all the mbuf pools that are allocated.
795 *
796 * @return total number of blocks allocated in Msys
797 */
798 int os_msys_count(void);
799
800 /**
801 * Return the number of free blocks in Msys
802 *
803 * @return Number of free blocks available in Msys
804 */
805 int os_msys_num_free(void);
806
807 /**
808 * Initialize a pool of mbufs.
809 *
810 * @param omp The mbuf pool to initialize
811 * @param mp The memory pool that will hold this mbuf pool
812 * @param buf_len The length of the buffer itself.
813 * @param nbufs The number of buffers in the pool
814 *
815 * @return 0 on success, error code on failure.
816 */
817 int os_mbuf_pool_init(struct os_mbuf_pool *, struct os_mempool *mp,
818 uint16_t, uint16_t);
819
820 /**
821 * Get an mbuf from the mbuf pool. The mbuf is allocated, and initialized
822 * prior to being returned.
823 *
824 * @param omp The mbuf pool to return the packet from
825 * @param leadingspace The amount of leadingspace to put before the data
826 * section by default.
827 *
828 * @return An initialized mbuf on success, and NULL on failure.
829 */
830 struct os_mbuf *os_mbuf_get(struct os_mbuf_pool *omp, uint16_t);
831
832 /**
833 * Allocate a new packet header mbuf out of the os_mbuf_pool.
834 *
835 * @param omp The mbuf pool to allocate out of
836 * @param user_pkthdr_len The packet header length to reserve for the caller.
837 *
838 * @return A freshly allocated mbuf on success, NULL on failure.
839 */
840 struct os_mbuf *os_mbuf_get_pkthdr(struct os_mbuf_pool *omp,
841 uint8_t pkthdr_len);
842
843 /**
844 * Duplicate a chain of mbufs. Return the start of the duplicated chain.
845 *
846 * @param omp The mbuf pool to duplicate out of
847 * @param om The mbuf chain to duplicate
848 *
849 * @return A pointer to the new chain of mbufs
850 */
851 struct os_mbuf *os_mbuf_dup(struct os_mbuf *m);
852
853 /**
854 * Locates the specified absolute offset within an mbuf chain. The offset
855 * can be one past than the total length of the chain, but no greater.
856 *
857 * @param om The start of the mbuf chain to seek within.
858 * @param off The absolute address to find.
859 * @param out_off On success, this points to the relative offset
860 * within the returned mbuf.
861 *
862 * @return The mbuf containing the specified offset on
863 * success.
864 * NULL if the specified offset is out of bounds.
865 */
866 struct os_mbuf *os_mbuf_off(const struct os_mbuf *om, int off,
867 uint16_t *out_off);
868
869
870 /*
871 * Copy data from an mbuf chain starting "off" bytes from the beginning,
872 * continuing for "len" bytes, into the indicated buffer.
873 *
874 * @param m The mbuf chain to copy from
875 * @param off The offset into the mbuf chain to begin copying from
876 * @param len The length of the data to copy
877 * @param dst The destination buffer to copy into
878 *
879 * @return 0 on success;
880 * -1 if the mbuf does not contain enough data.
881 */
882 int os_mbuf_copydata(const struct os_mbuf *m, int off, int len, void *dst);
883
884 /**
885 * @brief Calculates the length of an mbuf chain.
886 *
887 * Calculates the length of an mbuf chain. If the mbuf contains a packet
888 * header, you should use `OS_MBUF_PKTLEN()` as a more efficient alternative to
889 * this function.
890 *
891 * @param om The mbuf to measure.
892 *
893 * @return The length, in bytes, of the provided mbuf
894 * chain.
895 */
896 uint16_t os_mbuf_len(const struct os_mbuf *om);
897
898 /**
899 * Append data onto a mbuf
900 *
901 * @param om The mbuf to append the data onto
902 * @param data The data to append onto the mbuf
903 * @param len The length of the data to append
904 *
905 * @return 0 on success, and an error code on failure
906 */
907 int os_mbuf_append(struct os_mbuf *m, const void *, uint16_t);
908
909 /**
910 * Reads data from one mbuf and appends it to another. On error, the specified
911 * data range may be partially appended. Neither mbuf is required to contain
912 * an mbuf packet header.
913 *
914 * @param dst The mbuf to append to.
915 * @param src The mbuf to copy data from.
916 * @param src_off The absolute offset within the source mbuf
917 * chain to read from.
918 * @param len The number of bytes to append.
919 *
920 * @return 0 on success;
921 * OS_EINVAL if the specified range extends beyond
922 * the end of the source mbuf chain.
923 */
924 int os_mbuf_appendfrom(struct os_mbuf *dst, const struct os_mbuf *src,
925 uint16_t src_off, uint16_t len);
926
927 /**
928 * Release a mbuf back to the pool
929 *
930 * @param omp The Mbuf pool to release back to
931 * @param om The Mbuf to release back to the pool
932 *
933 * @return 0 on success, -1 on failure
934 */
935 int os_mbuf_free(struct os_mbuf *mb);
936
937 /**
938 * Free a chain of mbufs
939 *
940 * @param omp The mbuf pool to free the chain of mbufs into
941 * @param om The starting mbuf of the chain to free back into the pool
942 *
943 * @return 0 on success, -1 on failure
944 */
945 int os_mbuf_free_chain(struct os_mbuf *om);
946
947 /**
948 * Adjust the length of a mbuf, trimming either from the head or the tail
949 * of the mbuf.
950 *
951 * @param mp The mbuf chain to adjust
952 * @param req_len The length to trim from the mbuf. If positive, trims
953 * from the head of the mbuf, if negative, trims from the
954 * tail of the mbuf.
955 */
956 void os_mbuf_adj(struct os_mbuf *mp, int req_len);
957
958
959 /**
960 * Performs a memory compare of the specified region of an mbuf chain against a
961 * flat buffer.
962 *
963 * @param om The start of the mbuf chain to compare.
964 * @param off The offset within the mbuf chain to start the
965 * comparison.
966 * @param data The flat buffer to compare.
967 * @param len The length of the flat buffer.
968 *
969 * @return 0 if both memory regions are identical;
970 * A memcmp return code if there is a mismatch;
971 * INT_MAX if the mbuf is too short.
972 */
973 int os_mbuf_cmpf(const struct os_mbuf *om, int off, const void *data, int len);
974
975 /**
976 * Compares the contents of two mbuf chains. The ranges of the two chains to
977 * be compared are specified via the two offset parameters and the len
978 * parameter. Neither mbuf chain is required to contain a packet header.
979 *
980 * @param om1 The first mbuf chain to compare.
981 * @param offset1 The absolute offset within om1 at which to
982 * start the comparison.
983 * @param om2 The second mbuf chain to compare.
984 * @param offset2 The absolute offset within om2 at which to
985 * start the comparison.
986 * @param len The number of bytes to compare.
987 *
988 * @return 0 if both mbuf segments are identical;
989 * A memcmp() return code if the segment contents
990 * differ;
991 * INT_MAX if a specified range extends beyond the
992 * end of its corresponding mbuf chain.
993 */
994 int os_mbuf_cmpm(const struct os_mbuf *om1, uint16_t offset1,
995 const struct os_mbuf *om2, uint16_t offset2,
996 uint16_t len);
997
998 /**
999 * Increases the length of an mbuf chain by adding data to the front. If there
1000 * is insufficient room in the leading mbuf, additional mbufs are allocated and
1001 * prepended as necessary. If this function fails to allocate an mbuf, the
1002 * entire chain is freed.
1003 *
1004 * The specified mbuf chain does not need to contain a packet header.
1005 *
1006 * @param omp The mbuf pool to allocate from.
1007 * @param om The head of the mbuf chain.
1008 * @param len The number of bytes to prepend.
1009 *
1010 * @return The new head of the chain on success;
1011 * NULL on failure.
1012 */
1013 struct os_mbuf *os_mbuf_prepend(struct os_mbuf *om, int len);
1014
1015 /**
1016 * Prepends a chunk of empty data to the specified mbuf chain and ensures the
1017 * chunk is contiguous. If either operation fails, the specified mbuf chain is
1018 * freed and NULL is returned.
1019 *
1020 * @param om The mbuf chain to prepend to.
1021 * @param len The number of bytes to prepend and pullup.
1022 *
1023 * @return The modified mbuf on success;
1024 * NULL on failure (and the mbuf chain is freed).
1025 */
1026 struct os_mbuf *os_mbuf_prepend_pullup(struct os_mbuf *om, uint16_t len);
1027
1028 /**
1029 * Copies the contents of a flat buffer into an mbuf chain, starting at the
1030 * specified destination offset. If the mbuf is too small for the source data,
1031 * it is extended as necessary. If the destination mbuf contains a packet
1032 * header, the header length is updated.
1033 *
1034 * @param omp The mbuf pool to allocate from.
1035 * @param om The mbuf chain to copy into.
1036 * @param off The offset within the chain to copy to.
1037 * @param src The source buffer to copy from.
1038 * @param len The number of bytes to copy.
1039 *
1040 * @return 0 on success; nonzero on failure.
1041 */
1042 int os_mbuf_copyinto(struct os_mbuf *om, int off, const void *src, int len);
1043
1044 /**
1045 * Attaches a second mbuf chain onto the end of the first. If the first chain
1046 * contains a packet header, the header's length is updated. If the second
1047 * chain has a packet header, its header is cleared.
1048 *
1049 * @param first The mbuf chain being attached to.
1050 * @param second The mbuf chain that gets attached.
1051 */
1052 void os_mbuf_concat(struct os_mbuf *first, struct os_mbuf *second);
1053
1054
1055 /**
1056 * Increases the length of an mbuf chain by the specified amount. If there is
1057 * not sufficient room in the last buffer, a new buffer is allocated and
1058 * appended to the chain. It is an error to request more data than can fit in
1059 * a single buffer.
1060 *
1061 * @param omp
1062 * @param om The head of the chain to extend.
1063 * @param len The number of bytes to extend by.
1064 *
1065 * @return A pointer to the new data on success;
1066 * NULL on failure.
1067 */
1068 void *os_mbuf_extend(struct os_mbuf *om, uint16_t len);
1069
1070 /**
1071 * Rearrange a mbuf chain so that len bytes are contiguous,
1072 * and in the data area of an mbuf (so that OS_MBUF_DATA() will
1073 * work on a structure of size len.) Returns the resulting
1074 * mbuf chain on success, free's it and returns NULL on failure.
1075 *
1076 * If there is room, it will add up to "max_protohdr - len"
1077 * extra bytes to the contiguous region, in an attempt to avoid being
1078 * called next time.
1079 *
1080 * @param omp The mbuf pool to take the mbufs out of
1081 * @param om The mbuf chain to make contiguous
1082 * @param len The number of bytes in the chain to make contiguous
1083 *
1084 * @return The contiguous mbuf chain on success, NULL on failure.
1085 */
1086 struct os_mbuf *os_mbuf_pullup(struct os_mbuf *om, uint16_t len);
1087
1088
1089 /**
1090 * Removes and frees empty mbufs from the front of a chain. If the chain
1091 * contains a packet header, it is preserved.
1092 *
1093 * @param om The mbuf chain to trim.
1094 *
1095 * @return The head of the trimmed mbuf chain.
1096 */
1097 struct os_mbuf *os_mbuf_trim_front(struct os_mbuf *om);
1098
1099 /**
1100 * Increases the length of an mbuf chain by inserting a gap at the specified
1101 * offset. The contents of the gap are indeterminate. If the mbuf chain
1102 * contains a packet header, its total length is increased accordingly.
1103 *
1104 * This function never frees the provided mbuf chain.
1105 *
1106 * @param om The mbuf chain to widen.
1107 * @param off The offset at which to insert the gap.
1108 * @param len The size of the gap to insert.
1109 *
1110 * @return 0 on success; SYS_[...] error code on failure.
1111 */
1112 int os_mbuf_widen(struct os_mbuf *om, uint16_t off, uint16_t len);
1113
1114
1115 /**
1116 * Creates a single chained mbuf from m1 and m2 utilizing all
1117 * the available buffer space in all mbufs in the resulting
1118 * chain. In other words, ensures there is no leading space in
1119 * any mbuf in the resulting chain and trailing space only in
1120 * the last mbuf in the chain. Mbufs from either chain may be
1121 * freed if not needed. No mbufs are allocated. Note that mbufs
1122 * from m2 are added to the end of m1. If m1 has a packet
1123 * header, it is retained and length updated. If m2 has a packet
1124 * header it is discarded. If m1 is NULL, NULL is returned and
1125 * m2 is left untouched.
1126 *
1127 * @param m1 Pointer to first mbuf chain to pack
1128 * @param m2 Pointer to second mbuf chain to pack
1129 *
1130 * @return struct os_mbuf* Pointer to resulting mbuf chain
1131 */
1132 struct os_mbuf *os_mbuf_pack_chains(struct os_mbuf *m1, struct os_mbuf *m2);
1133
1134 #endif
1135 #ifdef __cplusplus
1136 }
1137 #endif
1138
1139 #endif /* _OS_MBUF_H */
1140
1141
1142 /**
1143 * @} OSMbuf
1144 * @} OSKernel
1145 */
1146