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