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