1 /*
2  * Copyright (c) 2020 - 2023, Nordic Semiconductor ASA
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright notice, this
11  *    list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
18  *    contributors may be used to endorse or promote products derived from this
19  *    software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  *
33  */
34 
35 /**
36  * @file nrf_802154_buffer_mgr_dst.h
37  * @brief Buffer management for destination peer of a nRF 802.15.4 serialization.
38  *
39  * Receiving a buffer from a remote peer and then sending notification about
40  * that buffer is a common scenario in serialization.
41  *
42  * This module is intended for a local peer who receives a buffer content
43  * referenced by @c buffer_handle from a remote peer.
44  * Function @ref nrf_802154_buffer_mgr_dst_add allows creation of a copy of
45  * received content and provides a native local pointer to the copy of received
46  * data. When local peer needs to notify a remote peer about some events related
47  * to the buffer @ref nrf_802154_buffer_mgr_dst_search_by_local_pointer function
48  * can be used to map a local pointer to @c buffer_handle the buffer has been
49  * received with. When local peer is done with given buffer
50  * @ref nrf_802154_buffer_mgr_dst_remove_by_local_pointer should be called to
51  * remove mapping and free any resources used by the mapping.
52  */
53 
54 #ifndef NRF_802154_BUFFER_MGR_DST_H__
55 #define NRF_802154_BUFFER_MGR_DST_H__
56 
57 #include <stddef.h>
58 #include <stdbool.h>
59 #include <stdint.h>
60 
61 #include "nrf_802154_kvmap.h"
62 #include "nrf_802154_buffer_allocator.h"
63 
64 /**@brief Type of a buffer manager for destination peer of serialization. */
65 typedef struct
66 {
67     /**@brief Map for matching local pointers to remote buffer handle.
68      *
69      * Key is a local pointer (@c void*)
70      * Value is a remote buffer handle (@c uint32_t)
71      */
72     nrf_802154_kvmap_t            map;
73 
74     /**@brief Allocator providing storage for local buffers. */
75     nrf_802154_buffer_allocator_t allocator;
76 } nrf_802154_buffer_mgr_dst_t;
77 
78 /**@brief Calculates number of bytes needed to store map.
79  * @param buffers_count     Number of buffers to be tracked.
80  */
81 #define NRF_802154_BUFFER_MGR_DST_MAP_MEMSIZE(buffers_count) \
82     NRF_802154_KVMAP_MEMORY_SIZE((buffers_count), sizeof(void *), sizeof(uint32_t))
83 
84 /**@brief Defines instance of @ref rf_802154_buffer_mgr_dst_t with all necessary accompanying
85  *        variables.
86  *
87  * Instance defined by this macro needs to be initialized. See an example below:
88  * @code
89  * static NRF_802154_BUFFER_MGR_DST_INST_DECL(m_buffer_mgr_host, 10U);
90  *
91  * void foo(void)
92  * {
93  *     NRF_802154_BUFFER_MGR_DST_INIT(m_buffer_mgr_host)
94  * }
95  * @endcode
96  *
97  * @param name          Identifier of an object of type @ref nrf_802154_buffer_mgr_dst_t
98  * @param buffers_count Number of buffers the @c name object will be able to track.
99  */
100 #define NRF_802154_BUFFER_MGR_DST_INST_DECL(name, buffers_count) \
101     nrf_802154_buffer_mgr_dst_t name;                            \
102     uint8_t name ## _map_mem[                                    \
103         NRF_802154_BUFFER_MGR_DST_MAP_MEMSIZE(buffers_count)]    \
104     __attribute__((aligned(4)));                                 \
105     uint8_t name ## _allocator_mem[                              \
106         NRF_802154_BUFFER_ALLOCATOR_MEMORY_SIZE(buffers_count)]  \
107     __attribute__((aligned(4)));                                 \
108     const size_t name ## _buffers_count = (buffers_count);
109 
110 /**@brief Provides extern complementary to @ref NRF_802154_BUFFER_MGR_DST_INST_DECL.
111  *
112  * @param name Identifier of an object of type @ref nrf_802154_buffer_mgr_dst_t
113  */
114 #define NRF_802154_BUFFER_MGR_DST_INST_DECL_EXTERN(name) \
115     extern nrf_802154_buffer_mgr_dst_t name
116 
117 /**@brief As @ref NRF_802154_BUFFER_MGR_DST_INST_DECL but with static storage. */
118 #define NRF_802154_BUFFER_MGR_DST_INST_DECL_STATIC(name, buffers_count) \
119     static nrf_802154_buffer_mgr_dst_t name;                            \
120     static uint8_t name ## _map_mem[                                    \
121         NRF_802154_BUFFER_MGR_DST_MAP_MEMSIZE(buffers_count)]           \
122     __attribute__((aligned(4)));                                        \
123     static uint8_t name ## _allocator_mem[                              \
124         NRF_802154_BUFFER_ALLOCATOR_MEMORY_SIZE(buffers_count)]         \
125     __attribute__((aligned(4)));                                        \
126     static const size_t name ## _buffers_count = (buffers_count);
127 
128 /**@brief Calls @ref nrf_802154_buffer_mgr_dst_init for an object instantiated by
129  *        @ref NRF_802154_BUFFER_MGR_DST_INST_DECL.
130  * @param name Name of object instance introduced by a NRF_802154_BUFFER_MGR_DST_INST_DECL
131  *             (note: not a pointer)
132  */
133 #define NRF_802154_BUFFER_MGR_DST_INIT(name) \
134     nrf_802154_buffer_mgr_dst_init(          \
135         &name,                               \
136         name ## _map_mem,                    \
137         name ## _allocator_mem,              \
138         name ## _buffers_count)
139 
140 /**@brief Initializes a buffer manager.
141  *
142  * @param[out] p_obj         Pointer to an object instance to initialize
143  * @param[in]  p_map_memory  Pointer to a memory buffer of size equal to
144  *                           @ref NRF_802154_BUFFER_MGR_DST_MAP_MEMSIZE(@c buffers_count)
145  * @param[in]  p_allocator_memory Pointer to a memory buffer of size equal to
146  *                           @ref NRF_802154_BUFFER_ALLOCATOR_MEMORY_SIZE(@c buffers_count)
147  * @param[in]  buffers_count Number of buffers the object @p p_obj will be able to track
148  *
149  * @sa @ref NRF_802154_BUFFER_MGR_DST_INSTANCE_DECL, @ref NRF_802154_BUFFER_DST_MGR_INIT
150  */
151 void nrf_802154_buffer_mgr_dst_init(
152     nrf_802154_buffer_mgr_dst_t * p_obj,
153     void                        * p_map_memory,
154     void                        * p_allocator_memory,
155     size_t                        buffers_count);
156 
157 /**@brief Adds a remote buffer handle to a buffer manager obtaining a local pointer.
158  *
159  * This causes an allocation of a buffer and copy of data into it.
160  *
161  * @param[in,out] p_obj           Pointer to a buffer manager object.
162  * @param[in]     buffer_handle   Handle of a remote buffer.
163  * @param[in]     p_data          Points to a data the buffer returned by @p pp_local_pointer
164  *                                should contain.
165  * @param[in]     data_size       Length of data pointed by @p p_data
166  * @param[out]    p_local_pointer A pointer to an buffer where a copy of data pointed by
167  *                                @ref p_data has been made
168  *
169  * @retval true   Buffer added to tracking
170  * @retval false  Out of memory, @c *pp_local_pointer is undefined
171  */
172 bool nrf_802154_buffer_mgr_dst_add(
173     nrf_802154_buffer_mgr_dst_t * p_obj,
174     uint32_t                      buffer_handle,
175     const void                  * p_data,
176     size_t                        data_size,
177     void                       ** pp_local_pointer);
178 
179 /**@brief Searches remote buffer handle by a local buffer pointer.
180  *
181  * @param[in,out] p_obj           Pointer to an host buffer manager object.
182  * @param[in]     p_local_pointer Local pointer buffer obtained from call to
183  *                                @ref nrf_802154_buffer_mgr_dst_add
184  * @param[out]    p_buffer_handle Pointer to a remote buffer handle assocciated with
185  *                                local pointer
186  *
187  * @retval true     Given @p p_local_pointer has been found. The handle associated with
188  *                  the pointer is available at @c *p_buffer_handle.
189  * @retval false    Given @p p_local_pointer has not been found.
190  */
191 bool nrf_802154_buffer_mgr_dst_search_by_local_pointer(
192     nrf_802154_buffer_mgr_dst_t * p_obj,
193     void                        * p_local_pointer,
194     uint32_t                    * p_buffer_handle);
195 
196 /**@brief Removes a local pointer to remote buffer handle association from a buffer manager.
197  *
198  * This function frees buffer pointed by a @p p_local_pointer if it exists in buffer manager.
199  *
200  * @param[in,out] p_obj           Pointer to a buffer manager object.
201  * @param[in]     p_local_pointer Local pointer to be removed from buffer manager.
202  *
203  * @retval true   Association has been found and has been removed. Storage pointed by
204  *                @p p_local_pointer has been deallocated. Data behind the @ref p_local_pointer
205  *                is undefined.
206  * @retval false  Association has not been found (but it does not exist in the
207  *                buffer manager anyway). Buffer manager has been not modified.
208  */
209 bool nrf_802154_buffer_mgr_dst_remove_by_local_pointer(
210     nrf_802154_buffer_mgr_dst_t * p_obj,
211     void                        * p_local_pointer);
212 
213 #endif // NRF_802154_BUFFER_MGR_DST_H__
214