os_mbuf.h 39 KB

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