1 /** @file
2  *  @brief Bluetooth "view" buffer abstraction
3  */
4 
5 /*
6  * Copyright (c) 2024 Nordic Semiconductor ASA
7  *
8  * SPDX-License-Identifier: Apache-2.0
9  */
10 
11 #ifndef ZEPHYR_SUBSYS_BLUETOOTH_HOST_BUF_VIEW_H_
12 #define ZEPHYR_SUBSYS_BLUETOOTH_HOST_BUF_VIEW_H_
13 
14 #include <stddef.h>
15 
16 #include <zephyr/net_buf.h>
17 
18 
19 struct bt_buf_view_meta {
20 	struct net_buf *parent;
21 	/* saves the data pointers while the parent buffer is locked. */
22 	struct net_buf_simple backup;
23 };
24 
25 /** @internal
26  *
27  *  @brief Create a "view" or "window" into an existing buffer.
28  *  - enforces one active view at a time per-buffer
29  *  -> this restriction enables prepending data (ie. for headers)
30  *  - forbids appending data to the view
31  *  - pulls the size of the view from said buffer.
32  *
33  *  The "virtual buffer" that is generated has to be allocated from a buffer
34  *  pool. This is to allow refcounting and attaching a destroy callback. The
35  *  configured size of the buffers in that pool should be zero-length.
36  *
37  *  The user-data size is application-dependent, but should be minimized to save
38  *  memory. user_data is not used by the view API.
39  *
40  *  The view mechanism needs to store extra metadata in order to unlock the
41  *  original buffer when the view is destroyed.
42  *
43  *  The storage and allocation of the view buf pool and the view metadata is the
44  *  application's responsibility.
45  *
46  *  @note The `headroom` param is only used for __ASSERT(). The idea is that
47  *  it's easier to debug a headroom assert failure at allocation time, rather
48  *  than later down the line when a lower layer tries to add its headers and
49  *  fails.
50  *
51  *  @param view         Uninitialized "View" buffer
52  *  @param parent       Buffer data is pulled from into `view`
53  *  @param len          Amount to pull
54  *  @param meta         Uninitialized metadata storage
55  *
56  *  @return view if the operation was successful. NULL on error.
57  */
58 struct net_buf *bt_buf_make_view(struct net_buf *view,
59 				 struct net_buf *parent,
60 				 size_t len,
61 				 struct bt_buf_view_meta *meta);
62 
63 /** @internal
64  *
65  *  @brief Check if `parent` has view.
66  *
67  *  If `parent` has been passed to @ref bt_buf_make_view() and the resulting
68  *  view buffer has not been destroyed.
69  */
70 bool bt_buf_has_view(const struct net_buf *parent);
71 
72 /** @internal
73  *
74  *  @brief Destroy the view buffer
75  *
76  *  Equivalent of @ref net_buf_destroy.
77  *  It is mandatory to call this from the view pool's `destroy` callback.
78  *
79  *  This frees the parent buffer, and allows calling @ref bt_buf_make_view again.
80  *  The metadata is also freed for re-use.
81  *
82  *  @param view View to destroy
83  *  @param meta Meta that was given to @ref bt_buf_make_view
84  */
85 void bt_buf_destroy_view(struct net_buf *view, struct bt_buf_view_meta *meta);
86 
87 #endif /* ZEPHYR_SUBSYS_BLUETOOTH_HOST_BUF_VIEW_H_ */
88