os_mbuf.h 39 KB

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