1 /*
2 * Copyright (c) 2018-2021 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #if defined(CONFIG_BT_CTLR_ADV_PDU_LINK)
8 #define PDU_ADV_MEM_SIZE MROUND(PDU_AC_LL_HEADER_SIZE + \
9 PDU_AC_PAYLOAD_SIZE_MAX + \
10 sizeof(uintptr_t))
11 #define PDU_ADV_NEXT_PTR(p) *(struct pdu_adv **)((uint8_t *)(p) + \
12 PDU_ADV_MEM_SIZE - \
13 sizeof(uintptr_t))
14 #else
15 #define PDU_ADV_MEM_SIZE MROUND(PDU_AC_LL_HEADER_SIZE + \
16 PDU_AC_PAYLOAD_SIZE_MAX)
17 #endif
18
19 int lll_adv_data_init(struct lll_adv_pdu *pdu);
20 int lll_adv_data_reset(struct lll_adv_pdu *pdu);
21 int lll_adv_data_dequeue(struct lll_adv_pdu *pdu);
22 int lll_adv_data_release(struct lll_adv_pdu *pdu);
23
lll_adv_pdu_enqueue(struct lll_adv_pdu * pdu,uint8_t idx)24 static inline void lll_adv_pdu_enqueue(struct lll_adv_pdu *pdu, uint8_t idx)
25 {
26 pdu->last = idx;
27 }
28
29 struct pdu_adv *lll_adv_pdu_alloc(struct lll_adv_pdu *pdu, uint8_t *idx);
30 struct pdu_adv *lll_adv_pdu_alloc_pdu_adv(void);
31
lll_adv_data_alloc(struct lll_adv * lll,uint8_t * idx)32 static inline struct pdu_adv *lll_adv_data_alloc(struct lll_adv *lll,
33 uint8_t *idx)
34 {
35 return lll_adv_pdu_alloc(&lll->adv_data, idx);
36 }
37
lll_adv_data_enqueue(struct lll_adv * lll,uint8_t idx)38 static inline void lll_adv_data_enqueue(struct lll_adv *lll, uint8_t idx)
39 {
40 lll_adv_pdu_enqueue(&lll->adv_data, idx);
41 }
42
lll_adv_data_peek(struct lll_adv * lll)43 static inline struct pdu_adv *lll_adv_data_peek(struct lll_adv *lll)
44 {
45 return (void *)lll->adv_data.pdu[lll->adv_data.last];
46 }
47
lll_adv_data_curr_get(struct lll_adv * lll)48 static inline struct pdu_adv *lll_adv_data_curr_get(struct lll_adv *lll)
49 {
50 return (void *)lll->adv_data.pdu[lll->adv_data.first];
51 }
52
lll_adv_scan_rsp_alloc(struct lll_adv * lll,uint8_t * idx)53 static inline struct pdu_adv *lll_adv_scan_rsp_alloc(struct lll_adv *lll,
54 uint8_t *idx)
55 {
56 return lll_adv_pdu_alloc(&lll->scan_rsp, idx);
57 }
58
lll_adv_scan_rsp_enqueue(struct lll_adv * lll,uint8_t idx)59 static inline void lll_adv_scan_rsp_enqueue(struct lll_adv *lll, uint8_t idx)
60 {
61 lll_adv_pdu_enqueue(&lll->scan_rsp, idx);
62 }
63
lll_adv_scan_rsp_peek(const struct lll_adv * lll)64 static inline struct pdu_adv *lll_adv_scan_rsp_peek(const struct lll_adv *lll)
65 {
66 return (void *)lll->scan_rsp.pdu[lll->scan_rsp.last];
67 }
68
69 static inline struct pdu_adv *
lll_adv_pdu_latest_peek(const struct lll_adv_pdu * const pdu)70 lll_adv_pdu_latest_peek(const struct lll_adv_pdu *const pdu)
71 {
72 uint8_t first;
73
74 first = pdu->first;
75 if (first != pdu->last) {
76 first += 1U;
77 if (first == DOUBLE_BUFFER_SIZE) {
78 first = 0U;
79 }
80 }
81
82 return (void *)pdu->pdu[first];
83 }
84
85 static inline struct pdu_adv *
lll_adv_data_latest_peek(const struct lll_adv * const lll)86 lll_adv_data_latest_peek(const struct lll_adv *const lll)
87 {
88 return lll_adv_pdu_latest_peek(&lll->adv_data);
89 }
90
91 #if defined(CONFIG_BT_CTLR_ADV_EXT)
lll_adv_aux_data_init(struct lll_adv_pdu * pdu)92 static inline int lll_adv_aux_data_init(struct lll_adv_pdu *pdu)
93 {
94 return lll_adv_data_init(pdu);
95 }
96
lll_adv_aux_data_alloc(struct lll_adv_aux * lll,uint8_t * idx)97 static inline struct pdu_adv *lll_adv_aux_data_alloc(struct lll_adv_aux *lll,
98 uint8_t *idx)
99 {
100 return lll_adv_pdu_alloc(&lll->data, idx);
101 }
102
lll_adv_aux_data_enqueue(struct lll_adv_aux * lll,uint8_t idx)103 static inline void lll_adv_aux_data_enqueue(struct lll_adv_aux *lll,
104 uint8_t idx)
105 {
106 lll_adv_pdu_enqueue(&lll->data, idx);
107 }
108
109 static inline struct pdu_adv *
lll_adv_aux_data_peek(const struct lll_adv_aux * const lll)110 lll_adv_aux_data_peek(const struct lll_adv_aux *const lll)
111 {
112 return (void *)lll->data.pdu[lll->data.last];
113 }
114
115 static inline struct pdu_adv *
lll_adv_aux_data_latest_peek(const struct lll_adv_aux * const lll)116 lll_adv_aux_data_latest_peek(const struct lll_adv_aux *const lll)
117 {
118 return lll_adv_pdu_latest_peek(&lll->data);
119 }
120
lll_adv_aux_data_curr_get(struct lll_adv_aux * lll)121 static inline struct pdu_adv *lll_adv_aux_data_curr_get(struct lll_adv_aux *lll)
122 {
123 return (void *)lll->data.pdu[lll->data.first];
124 }
125
lll_adv_aux_scan_rsp_alloc(struct lll_adv * lll,uint8_t * idx)126 static inline struct pdu_adv *lll_adv_aux_scan_rsp_alloc(struct lll_adv *lll,
127 uint8_t *idx)
128 {
129 return lll_adv_pdu_alloc(&lll->scan_rsp, idx);
130 }
131
132
133 #if defined(CONFIG_BT_CTLR_ADV_PERIODIC)
134 int lll_adv_and_extra_data_release(struct lll_adv_pdu *pdu);
135
136 #if defined(CONFIG_BT_CTLR_ADV_SYNC_PDU_BACK2BACK)
137 void lll_adv_sync_pdu_b2b_update(struct lll_adv_sync *lll, uint8_t idx);
138 #endif
139
lll_adv_sync_data_init(struct lll_adv_pdu * pdu)140 static inline int lll_adv_sync_data_init(struct lll_adv_pdu *pdu)
141 {
142 return lll_adv_data_init(pdu);
143 }
144
145 struct pdu_adv *lll_adv_pdu_and_extra_data_alloc(struct lll_adv_pdu *pdu,
146 void **extra_data,
147 uint8_t *idx);
148
lll_adv_sync_data_alloc(struct lll_adv_sync * lll,void ** extra_data,uint8_t * idx)149 static inline struct pdu_adv *lll_adv_sync_data_alloc(struct lll_adv_sync *lll,
150 void **extra_data,
151 uint8_t *idx)
152 {
153 #if defined(CONFIG_BT_CTLR_ADV_EXT_PDU_EXTRA_DATA_MEMORY)
154 return lll_adv_pdu_and_extra_data_alloc(&lll->data, extra_data, idx);
155 #else
156 return lll_adv_pdu_alloc(&lll->data, idx);
157 #endif /* CONFIG_BT_CTLR_ADV_EXT_PDU_EXTRA_DATA_MEMORY */
158 }
159
lll_adv_sync_data_release(struct lll_adv_sync * lll)160 static inline void lll_adv_sync_data_release(struct lll_adv_sync *lll)
161 {
162 #if defined(CONFIG_BT_CTLR_ADV_EXT_PDU_EXTRA_DATA_MEMORY)
163 lll_adv_and_extra_data_release(&lll->data);
164 #else
165 lll_adv_data_release(&lll->data);
166 #endif /* CONFIG_BT_CTLR_ADV_EXT_PDU_EXTRA_DATA_MEMORY */
167 }
168
lll_adv_sync_data_enqueue(struct lll_adv_sync * lll,uint8_t idx)169 static inline void lll_adv_sync_data_enqueue(struct lll_adv_sync *lll,
170 uint8_t idx)
171 {
172 lll_adv_pdu_enqueue(&lll->data, idx);
173 }
174
175 static inline struct pdu_adv *
lll_adv_sync_data_peek(const struct lll_adv_sync * lll,void ** extra_data)176 lll_adv_sync_data_peek(const struct lll_adv_sync *lll, void **extra_data)
177 {
178 uint8_t last = lll->data.last;
179
180 #if defined(CONFIG_BT_CTLR_ADV_EXT_PDU_EXTRA_DATA_MEMORY)
181 if (extra_data) {
182 *extra_data = lll->data.extra_data[last];
183 }
184 #endif /* CONFIG_BT_CTLR_ADV_EXT_PDU_EXTRA_DATA_MEMORY */
185
186 return (void *)lll->data.pdu[last];
187 }
188
189 static inline struct pdu_adv *
lll_adv_sync_data_latest_peek(const struct lll_adv_sync * const lll)190 lll_adv_sync_data_latest_peek(const struct lll_adv_sync *const lll)
191 {
192 return lll_adv_pdu_latest_peek(&lll->data);
193 }
194
195 #if defined(CONFIG_BT_CTLR_ADV_EXT_PDU_EXTRA_DATA_MEMORY)
lll_adv_sync_extra_data_peek(struct lll_adv_sync * lll)196 static inline void *lll_adv_sync_extra_data_peek(struct lll_adv_sync *lll)
197 {
198 return lll->data.extra_data[lll->data.last];
199 }
200
lll_adv_sync_extra_data_curr_get(struct lll_adv_sync * lll)201 static inline void *lll_adv_sync_extra_data_curr_get(struct lll_adv_sync *lll)
202 {
203 return lll->data.extra_data[lll->data.first];
204 }
205 #endif /* CONFIG_BT_CTLR_ADV_EXT_PDU_EXTRA_DATA_MEMORY */
206 #endif /* CONFIG_BT_CTLR_ADV_PERIODIC */
207 #endif /* CONFIG_BT_CTLR_ADV_EXT */
208
209 #if defined(CONFIG_BT_CTLR_ADV_PDU_LINK)
210 /* Release PDU and all linked PDUs, shall only be called from ULL */
211 void lll_adv_pdu_linked_release_all(struct pdu_adv *pdu_first);
212
lll_adv_pdu_linked_next_get(struct pdu_adv * pdu)213 static inline struct pdu_adv *lll_adv_pdu_linked_next_get(struct pdu_adv *pdu)
214 {
215 return PDU_ADV_NEXT_PTR(pdu);
216 }
217
lll_adv_pdu_linked_last_get(struct pdu_adv * pdu)218 static inline struct pdu_adv *lll_adv_pdu_linked_last_get(struct pdu_adv *pdu)
219 {
220 while (PDU_ADV_NEXT_PTR(pdu)) {
221 pdu = PDU_ADV_NEXT_PTR(pdu);
222 }
223 return pdu;
224 }
225
lll_adv_pdu_linked_append(struct pdu_adv * pdu,struct pdu_adv * prev)226 static inline void lll_adv_pdu_linked_append(struct pdu_adv *pdu,
227 struct pdu_adv *prev)
228 {
229 PDU_ADV_NEXT_PTR(prev) = pdu;
230 }
231
lll_adv_pdu_linked_append_end(struct pdu_adv * pdu,struct pdu_adv * first)232 static inline void lll_adv_pdu_linked_append_end(struct pdu_adv *pdu,
233 struct pdu_adv *first)
234 {
235 struct pdu_adv *last;
236
237 last = lll_adv_pdu_linked_last_get(first);
238 lll_adv_pdu_linked_append(pdu, last);
239 }
240 #endif
241