1 /******************************************************************************
2 *
3 * Copyright (C) 1999-2012 Broadcom Corporation
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18 #include <android-base/stringprintf.h>
19 #include <base/logging.h>
20 #include "gki_int.h"
21
22 #if (GKI_NUM_TOTAL_BUF_POOLS > 16)
23 #error Number of pools out of range (16 Max)!
24 #endif
25
26 #if (BTU_STACK_LITE_ENABLED == FALSE)
27 static void gki_add_to_pool_list(uint8_t pool_id);
28 static void gki_remove_from_pool_list(uint8_t pool_id);
29 #endif /* BTU_STACK_LITE_ENABLED == FALSE */
30
31 extern bool nfc_debug_enabled;
32
33 using android::base::StringPrintf;
34
35 /*******************************************************************************
36 **
37 ** Function gki_init_free_queue
38 **
39 ** Description Internal function called at startup to initialize a free
40 ** queue. It is called once for each free queue.
41 **
42 ** Returns void
43 **
44 *******************************************************************************/
gki_init_free_queue(uint8_t id,uint16_t size,uint16_t total,void * p_mem)45 static void gki_init_free_queue(uint8_t id, uint16_t size, uint16_t total,
46 void* p_mem) {
47 uint16_t i;
48 uint16_t act_size;
49 BUFFER_HDR_T* hdr;
50 BUFFER_HDR_T* hdr1 = nullptr;
51 uint32_t* magic;
52 int32_t tempsize = size;
53 tGKI_COM_CB* p_cb = &gki_cb.com;
54
55 /* Ensure an even number of longwords */
56 tempsize = (int32_t)ALIGN_POOL(size);
57 act_size = (uint16_t)(tempsize + BUFFER_PADDING_SIZE);
58
59 /* Remember pool start and end addresses */
60 if (p_mem) {
61 p_cb->pool_start[id] = (uint8_t*)p_mem;
62 p_cb->pool_end[id] = (uint8_t*)p_mem + (act_size * total);
63 }
64
65 p_cb->pool_size[id] = act_size;
66
67 p_cb->freeq[id].size = (uint16_t)tempsize;
68 p_cb->freeq[id].total = total;
69 p_cb->freeq[id].cur_cnt = 0;
70 p_cb->freeq[id].max_cnt = 0;
71
72 /* Initialize index table */
73 if (p_mem) {
74 hdr = (BUFFER_HDR_T*)p_mem;
75 p_cb->freeq[id].p_first = hdr;
76 for (i = 0; i < total; i++) {
77 hdr->task_id = GKI_INVALID_TASK;
78 hdr->q_id = id;
79 hdr->status = BUF_STATUS_FREE;
80 magic = (uint32_t*)((uint8_t*)hdr + BUFFER_HDR_SIZE + tempsize);
81 *magic = MAGIC_NO;
82 hdr1 = hdr;
83 hdr = (BUFFER_HDR_T*)((uint8_t*)hdr + act_size);
84 hdr1->p_next = hdr;
85 }
86 if (hdr1 != nullptr) hdr = hdr1;
87 hdr->p_next = nullptr;
88 p_cb->freeq[id].p_last = hdr;
89 }
90 return;
91 }
92
gki_alloc_free_queue(uint8_t id)93 static bool gki_alloc_free_queue(uint8_t id) {
94 FREE_QUEUE_T* Q;
95 tGKI_COM_CB* p_cb = &gki_cb.com;
96
97 Q = &p_cb->freeq[p_cb->pool_list[id]];
98
99 if (Q->p_first == nullptr) {
100 void* p_mem = GKI_os_malloc((Q->size + BUFFER_PADDING_SIZE) * Q->total);
101 if (p_mem) {
102 // re-initialize the queue with allocated memory
103 gki_init_free_queue(id, Q->size, Q->total, p_mem);
104 return true;
105 }
106 GKI_exception(GKI_ERROR_BUF_SIZE_TOOBIG,
107 "gki_alloc_free_queue: Not enough memory");
108 }
109 return false;
110 }
111
112 /*******************************************************************************
113 **
114 ** Function gki_buffer_init
115 **
116 ** Description Called once internally by GKI at startup to initialize all
117 ** buffers and free buffer pools.
118 **
119 ** Returns void
120 **
121 *******************************************************************************/
gki_buffer_init(void)122 void gki_buffer_init(void) {
123 uint8_t i, tt, mb;
124 tGKI_COM_CB* p_cb = &gki_cb.com;
125
126 /* Initialize mailboxes */
127 for (tt = 0; tt < GKI_MAX_TASKS; tt++) {
128 for (mb = 0; mb < NUM_TASK_MBOX; mb++) {
129 p_cb->OSTaskQFirst[tt][mb] = nullptr;
130 p_cb->OSTaskQLast[tt][mb] = nullptr;
131 }
132 }
133
134 for (tt = 0; tt < GKI_NUM_TOTAL_BUF_POOLS; tt++) {
135 p_cb->pool_start[tt] = nullptr;
136 p_cb->pool_end[tt] = nullptr;
137 p_cb->pool_size[tt] = 0;
138
139 p_cb->freeq[tt].p_first = nullptr;
140 p_cb->freeq[tt].p_last = nullptr;
141 p_cb->freeq[tt].size = 0;
142 p_cb->freeq[tt].total = 0;
143 p_cb->freeq[tt].cur_cnt = 0;
144 p_cb->freeq[tt].max_cnt = 0;
145 }
146
147 /* Use default from target.h */
148 p_cb->pool_access_mask = GKI_DEF_BUFPOOL_PERM_MASK;
149
150 #if (GKI_NUM_FIXED_BUF_POOLS > 0)
151 gki_init_free_queue(0, GKI_BUF0_SIZE, GKI_BUF0_MAX, p_cb->bufpool0);
152 #endif
153
154 #if (GKI_NUM_FIXED_BUF_POOLS > 1)
155 gki_init_free_queue(1, GKI_BUF1_SIZE, GKI_BUF1_MAX, p_cb->bufpool1);
156 #endif
157
158 #if (GKI_NUM_FIXED_BUF_POOLS > 2)
159 gki_init_free_queue(2, GKI_BUF2_SIZE, GKI_BUF2_MAX, p_cb->bufpool2);
160 #endif
161
162 #if (GKI_NUM_FIXED_BUF_POOLS > 3)
163 gki_init_free_queue(3, GKI_BUF3_SIZE, GKI_BUF3_MAX, p_cb->bufpool3);
164 #endif
165
166 #if (GKI_NUM_FIXED_BUF_POOLS > 4)
167 gki_init_free_queue(4, GKI_BUF4_SIZE, GKI_BUF4_MAX, p_cb->bufpool4);
168 #endif
169
170 #if (GKI_NUM_FIXED_BUF_POOLS > 5)
171 gki_init_free_queue(5, GKI_BUF5_SIZE, GKI_BUF5_MAX, p_cb->bufpool5);
172 #endif
173
174 #if (GKI_NUM_FIXED_BUF_POOLS > 6)
175 gki_init_free_queue(6, GKI_BUF6_SIZE, GKI_BUF6_MAX, p_cb->bufpool6);
176 #endif
177
178 #if (GKI_NUM_FIXED_BUF_POOLS > 7)
179 gki_init_free_queue(7, GKI_BUF7_SIZE, GKI_BUF7_MAX, p_cb->bufpool7);
180 #endif
181
182 #if (GKI_NUM_FIXED_BUF_POOLS > 8)
183 gki_init_free_queue(8, GKI_BUF8_SIZE, GKI_BUF8_MAX, p_cb->bufpool8);
184 #endif
185
186 #if (GKI_NUM_FIXED_BUF_POOLS > 9)
187 gki_init_free_queue(9, GKI_BUF9_SIZE, GKI_BUF9_MAX, p_cb->bufpool9);
188 #endif
189
190 #if (GKI_NUM_FIXED_BUF_POOLS > 10)
191 gki_init_free_queue(10, GKI_BUF10_SIZE, GKI_BUF10_MAX, p_cb->bufpool10);
192 #endif
193
194 #if (GKI_NUM_FIXED_BUF_POOLS > 11)
195 gki_init_free_queue(11, GKI_BUF11_SIZE, GKI_BUF11_MAX, p_cb->bufpool11);
196 #endif
197
198 #if (GKI_NUM_FIXED_BUF_POOLS > 12)
199 gki_init_free_queue(12, GKI_BUF12_SIZE, GKI_BUF12_MAX, p_cb->bufpool12);
200 #endif
201
202 #if (GKI_NUM_FIXED_BUF_POOLS > 13)
203 gki_init_free_queue(13, GKI_BUF13_SIZE, GKI_BUF13_MAX, p_cb->bufpool13);
204 #endif
205
206 #if (GKI_NUM_FIXED_BUF_POOLS > 14)
207 gki_init_free_queue(14, GKI_BUF14_SIZE, GKI_BUF14_MAX, p_cb->bufpool14);
208 #endif
209
210 #if (GKI_NUM_FIXED_BUF_POOLS > 15)
211 gki_init_free_queue(15, GKI_BUF15_SIZE, GKI_BUF15_MAX, p_cb->bufpool15);
212 #endif
213
214 /* add pools to the pool_list which is arranged in the order of size */
215 for (i = 0; i < GKI_NUM_FIXED_BUF_POOLS; i++) {
216 p_cb->pool_list[i] = i;
217 }
218
219 p_cb->curr_total_no_of_pools = GKI_NUM_FIXED_BUF_POOLS;
220
221 return;
222 }
223
224 /*******************************************************************************
225 **
226 ** Function GKI_init_q
227 **
228 ** Description Called by an application to initialize a buffer queue.
229 **
230 ** Returns void
231 **
232 *******************************************************************************/
GKI_init_q(BUFFER_Q * p_q)233 void GKI_init_q(BUFFER_Q* p_q) {
234 p_q->p_first = p_q->p_last = nullptr;
235 p_q->count = 0;
236
237 return;
238 }
239
240 /*******************************************************************************
241 **
242 ** Function GKI_getbuf
243 **
244 ** Description Called by an application to get a free buffer which
245 ** is of size greater or equal to the requested size.
246 **
247 ** Note: This routine only takes buffers from public pools.
248 ** It will not use any buffers from pools
249 ** marked GKI_RESTRICTED_POOL.
250 **
251 ** Parameters size - (input) number of bytes needed.
252 **
253 ** Returns A pointer to the buffer, or NULL if none available
254 **
255 *******************************************************************************/
GKI_getbuf(uint16_t size)256 void* GKI_getbuf(uint16_t size) {
257 BUFFER_HDR_T* p_hdr;
258 FREE_QUEUE_T* Q;
259
260 #if defined(DYN_ALLOC) || defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
261 if (size == 0) {
262 LOG(ERROR) << StringPrintf("getbuf: Size is zero");
263 #ifndef DYN_ALLOC
264 abort();
265 #else
266 return (nullptr);
267 #endif
268 }
269
270 size = ALIGN_POOL(size);
271 size_t total_sz = size + sizeof(BUFFER_HDR_T)
272 #if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE)
273 + sizeof(uint32_t);
274 #else
275 ;
276 #endif
277 p_hdr = (BUFFER_HDR_T*)GKI_os_malloc(total_sz);
278 if (!p_hdr) {
279 LOG(ERROR) << StringPrintf("unable to allocate buffer!!!!!");
280 #ifndef DYN_ALLOC
281 abort();
282 #else
283 return (nullptr);
284 #endif
285 }
286
287 memset(p_hdr, 0, total_sz);
288
289 #if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE)
290 *(uint32_t*)((uint8_t*)p_hdr + BUFFER_HDR_SIZE + size) = MAGIC_NO;
291 #endif
292 p_hdr->task_id = GKI_get_taskid();
293 p_hdr->status = BUF_STATUS_UNLINKED;
294 p_hdr->p_next = nullptr;
295 p_hdr->Type = 0;
296
297 p_hdr->q_id = 0;
298 p_hdr->size = size;
299
300 GKI_disable();
301 Q = &gki_cb.com.freeq[p_hdr->q_id];
302 if (++Q->cur_cnt > Q->max_cnt) Q->max_cnt = Q->cur_cnt;
303 GKI_enable();
304
305 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
306 "%s %p %d:%d", __func__, ((uint8_t*)p_hdr + BUFFER_HDR_SIZE), Q->cur_cnt,
307 Q->max_cnt);
308 UNUSED(gki_alloc_free_queue);
309 return (void*)((uint8_t*)p_hdr + BUFFER_HDR_SIZE);
310 #else
311 uint8_t i;
312 tGKI_COM_CB* p_cb = &gki_cb.com;
313
314 if (size == 0) {
315 GKI_exception(GKI_ERROR_BUF_SIZE_ZERO, "getbuf: Size is zero");
316 return (nullptr);
317 }
318
319 /* Find the first buffer pool that is public that can hold the desired size */
320 for (i = 0; i < p_cb->curr_total_no_of_pools; i++) {
321 if (size <= p_cb->freeq[p_cb->pool_list[i]].size) break;
322 }
323
324 if (i == p_cb->curr_total_no_of_pools) {
325 GKI_exception(GKI_ERROR_BUF_SIZE_TOOBIG, "getbuf: Size is too big");
326 return (nullptr);
327 }
328
329 /* Make sure the buffers aren't disturbed til finished with allocation */
330 GKI_disable();
331
332 /* search the public buffer pools that are big enough to hold the size
333 * until a free buffer is found */
334 for (; i < p_cb->curr_total_no_of_pools; i++) {
335 /* Only look at PUBLIC buffer pools (bypass RESTRICTED pools) */
336 if (((uint16_t)1 << p_cb->pool_list[i]) & p_cb->pool_access_mask) continue;
337
338 Q = &p_cb->freeq[p_cb->pool_list[i]];
339 if (Q->cur_cnt < Q->total) {
340 if (Q->p_first == nullptr && gki_alloc_free_queue(i) != true) {
341 LOG(ERROR) << StringPrintf("out of buffer");
342 GKI_enable();
343 return nullptr;
344 }
345
346 if (Q->p_first == nullptr) {
347 /* gki_alloc_free_queue() failed to alloc memory */
348 LOG(ERROR) << StringPrintf("fail alloc free queue");
349 GKI_enable();
350 return nullptr;
351 }
352
353 p_hdr = Q->p_first;
354 Q->p_first = p_hdr->p_next;
355
356 if (!Q->p_first) Q->p_last = nullptr;
357
358 if (++Q->cur_cnt > Q->max_cnt) Q->max_cnt = Q->cur_cnt;
359
360 GKI_enable();
361
362 p_hdr->task_id = GKI_get_taskid();
363
364 p_hdr->status = BUF_STATUS_UNLINKED;
365 p_hdr->p_next = nullptr;
366 p_hdr->Type = 0;
367 return ((void*)((uint8_t*)p_hdr + BUFFER_HDR_SIZE));
368 }
369 }
370
371 LOG(ERROR) << StringPrintf("unable to allocate buffer!!!!!");
372
373 GKI_enable();
374
375 return (nullptr);
376 #endif
377 }
378
379 /*******************************************************************************
380 **
381 ** Function GKI_getpoolbuf
382 **
383 ** Description Called by an application to get a free buffer from
384 ** a specific buffer pool.
385 **
386 ** Note: If there are no more buffers available from the pool,
387 ** the public buffers are searched for an available
388 ** buffer.
389 **
390 ** Parameters pool_id - (input) pool ID to get a buffer out of.
391 **
392 ** Returns A pointer to the buffer, or NULL if none available
393 **
394 *******************************************************************************/
GKI_getpoolbuf(uint8_t pool_id)395 void* GKI_getpoolbuf(uint8_t pool_id) {
396 #if defined(DYN_ALLOC) || defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
397 uint16_t size = 0;
398 switch (pool_id) {
399 // NFC_NCI_POOL_ID, NFC_RW_POOL_ID and NFC_CE_POOL_ID are all redefined to
400 // GKI_POOL_ID_2.
401 case GKI_POOL_ID_2:
402 size = GKI_BUF2_SIZE;
403 break;
404
405 // LLCP_POOL_ID, GKI_MAX_BUF_SIZE_POOL_ID are redefined to GKI_POOL_ID_3.
406 case GKI_POOL_ID_3:
407 size = GKI_BUF3_SIZE;
408 break;
409
410 default:
411 LOG(ERROR) << StringPrintf("Unknown pool ID: %d", pool_id);
412 #ifndef DYN_ALLOC
413 abort();
414 #else
415 return (nullptr);
416 #endif
417 break;
418 }
419
420 return GKI_getbuf(size);
421 #else
422 FREE_QUEUE_T* Q;
423 BUFFER_HDR_T* p_hdr;
424 tGKI_COM_CB* p_cb = &gki_cb.com;
425
426 if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS) return (nullptr);
427
428 /* Make sure the buffers aren't disturbed til finished with allocation */
429 GKI_disable();
430
431 Q = &p_cb->freeq[pool_id];
432 if (Q->cur_cnt < Q->total) {
433 if (Q->p_first == nullptr && gki_alloc_free_queue(pool_id) != true) return nullptr;
434
435 if (Q->p_first == nullptr) {
436 /* gki_alloc_free_queue() failed to alloc memory */
437 LOG(ERROR) << StringPrintf("fail alloc free queue");
438 return nullptr;
439 }
440
441 p_hdr = Q->p_first;
442 Q->p_first = p_hdr->p_next;
443
444 if (!Q->p_first) Q->p_last = nullptr;
445
446 if (++Q->cur_cnt > Q->max_cnt) Q->max_cnt = Q->cur_cnt;
447
448 GKI_enable();
449
450 p_hdr->task_id = GKI_get_taskid();
451
452 p_hdr->status = BUF_STATUS_UNLINKED;
453 p_hdr->p_next = nullptr;
454 p_hdr->Type = 0;
455
456 return ((void*)((uint8_t*)p_hdr + BUFFER_HDR_SIZE));
457 }
458
459 /* If here, no buffers in the specified pool */
460 GKI_enable();
461
462 /* try for free buffers in public pools */
463 return (GKI_getbuf(p_cb->freeq[pool_id].size));
464 #endif
465 }
466
467 /*******************************************************************************
468 **
469 ** Function GKI_freebuf
470 **
471 ** Description Called by an application to return a buffer to the free
472 ** pool.
473 **
474 ** Parameters p_buf - (input) address of the beginning of a buffer.
475 **
476 ** Returns void
477 **
478 *******************************************************************************/
GKI_freebuf(void * p_buf)479 void GKI_freebuf(void* p_buf) {
480 BUFFER_HDR_T* p_hdr;
481 FREE_QUEUE_T* Q;
482
483 #if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE)
484 if (!p_buf || gki_chk_buf_damage(p_buf)) {
485 GKI_exception(GKI_ERROR_BUF_CORRUPTED, "Free - Buf Corrupted");
486 return;
487 }
488 #endif
489
490 p_hdr = (BUFFER_HDR_T*)((uint8_t*)p_buf - BUFFER_HDR_SIZE);
491
492 if (p_hdr->status != BUF_STATUS_UNLINKED) {
493 GKI_exception(GKI_ERROR_FREEBUF_BUF_LINKED, "Freeing Linked Buf");
494 return;
495 }
496
497 if (p_hdr->q_id >= GKI_NUM_TOTAL_BUF_POOLS) {
498 GKI_exception(GKI_ERROR_FREEBUF_BAD_QID, "Bad Buf QId");
499 return;
500 }
501
502 #if defined(DYN_ALLOC) || defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
503 GKI_disable();
504 Q = &gki_cb.com.freeq[p_hdr->q_id];
505 if (Q->cur_cnt > 0) Q->cur_cnt--;
506 GKI_enable();
507
508 GKI_os_free(p_hdr);
509 #else
510 GKI_disable();
511
512 /*
513 ** Release the buffer
514 */
515 Q = &gki_cb.com.freeq[p_hdr->q_id];
516 if (Q->p_last)
517 Q->p_last->p_next = p_hdr;
518 else
519 Q->p_first = p_hdr;
520
521 Q->p_last = p_hdr;
522 p_hdr->p_next = nullptr;
523 p_hdr->status = BUF_STATUS_FREE;
524 p_hdr->task_id = GKI_INVALID_TASK;
525 if (Q->cur_cnt > 0) Q->cur_cnt--;
526
527 GKI_enable();
528 #endif
529 }
530
531 /*******************************************************************************
532 **
533 ** Function GKI_get_buf_size
534 **
535 ** Description Called by an application to get the size of a buffer.
536 **
537 ** Parameters p_buf - (input) address of the beginning of a buffer.
538 **
539 ** Returns the size of the buffer
540 **
541 *******************************************************************************/
GKI_get_buf_size(void * p_buf)542 uint16_t GKI_get_buf_size(void* p_buf) {
543 BUFFER_HDR_T* p_hdr;
544
545 p_hdr = (BUFFER_HDR_T*)((uint8_t*)p_buf - BUFFER_HDR_SIZE);
546
547 #if defined(DYN_ALLOC) || defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
548 return p_hdr->size;
549 #else
550 if ((uintptr_t)p_hdr & 1) return (0);
551
552 if (p_hdr->q_id < GKI_NUM_TOTAL_BUF_POOLS) {
553 return (gki_cb.com.freeq[p_hdr->q_id].size);
554 }
555
556 return (0);
557 #endif
558 }
559
560 /*******************************************************************************
561 **
562 ** Function gki_chk_buf_damage
563 **
564 ** Description Called internally by OSS to check for buffer corruption.
565 **
566 ** Returns TRUE if there is a problem, else FALSE
567 **
568 *******************************************************************************/
gki_chk_buf_damage(void * p_buf)569 bool gki_chk_buf_damage(void* p_buf) {
570 #if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE)
571
572 uint32_t* magic;
573 magic = (uint32_t*)((uint8_t*)p_buf + GKI_get_buf_size(p_buf));
574
575 if ((uintptr_t)magic & 1) return true;
576
577 if (*magic == MAGIC_NO) return false;
578
579 LOG(ERROR) << StringPrintf("%s 0x%x %p", __func__, *magic, p_buf);
580 return true;
581
582 #else
583 UNUSED(p_buf);
584 return false;
585
586 #endif
587 }
588
589 /*******************************************************************************
590 **
591 ** Function GKI_send_msg
592 **
593 ** Description Called by applications to send a buffer to a task
594 **
595 ** Returns Nothing
596 **
597 *******************************************************************************/
GKI_send_msg(uint8_t task_id,uint8_t mbox,void * msg)598 void GKI_send_msg(uint8_t task_id, uint8_t mbox, void* msg) {
599 BUFFER_HDR_T* p_hdr;
600 tGKI_COM_CB* p_cb = &gki_cb.com;
601
602 /* If task non-existant or not started, drop buffer */
603 if ((task_id >= GKI_MAX_TASKS) || (mbox >= NUM_TASK_MBOX) ||
604 (p_cb->OSRdyTbl[task_id] == TASK_DEAD)) {
605 GKI_exception(GKI_ERROR_SEND_MSG_BAD_DEST, "Sending to unknown dest");
606 GKI_freebuf(msg);
607 return;
608 }
609
610 #if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE)
611 if (gki_chk_buf_damage(msg)) {
612 GKI_exception(GKI_ERROR_BUF_CORRUPTED, "Send - Buffer corrupted");
613 return;
614 }
615 #endif
616
617 p_hdr = (BUFFER_HDR_T*)((uint8_t*)msg - BUFFER_HDR_SIZE);
618
619 if (p_hdr->status != BUF_STATUS_UNLINKED) {
620 GKI_exception(GKI_ERROR_SEND_MSG_BUF_LINKED, "Send - buffer linked");
621 return;
622 }
623
624 GKI_disable();
625
626 if (p_cb->OSTaskQFirst[task_id][mbox])
627 p_cb->OSTaskQLast[task_id][mbox]->p_next = p_hdr;
628 else
629 p_cb->OSTaskQFirst[task_id][mbox] = p_hdr;
630
631 p_cb->OSTaskQLast[task_id][mbox] = p_hdr;
632
633 p_hdr->p_next = nullptr;
634 p_hdr->status = BUF_STATUS_QUEUED;
635 p_hdr->task_id = task_id;
636
637 GKI_enable();
638
639 GKI_send_event(task_id, (uint16_t)EVENT_MASK(mbox));
640
641 return;
642 }
643
644 /*******************************************************************************
645 **
646 ** Function GKI_read_mbox
647 **
648 ** Description Called by applications to read a buffer from one of
649 ** the task mailboxes. A task can only read its own mailbox.
650 **
651 ** Parameters: mbox - (input) mailbox ID to read (0, 1, 2, or 3)
652 **
653 ** Returns NULL if the mailbox was empty, else the address of a buffer
654 **
655 *******************************************************************************/
GKI_read_mbox(uint8_t mbox)656 void* GKI_read_mbox(uint8_t mbox) {
657 uint8_t task_id = GKI_get_taskid();
658 void* p_buf = nullptr;
659 BUFFER_HDR_T* p_hdr;
660
661 if ((task_id >= GKI_MAX_TASKS) || (mbox >= NUM_TASK_MBOX)) return (nullptr);
662
663 GKI_disable();
664
665 if (gki_cb.com.OSTaskQFirst[task_id][mbox]) {
666 p_hdr = gki_cb.com.OSTaskQFirst[task_id][mbox];
667 gki_cb.com.OSTaskQFirst[task_id][mbox] = p_hdr->p_next;
668
669 p_hdr->p_next = nullptr;
670 p_hdr->status = BUF_STATUS_UNLINKED;
671
672 p_buf = (uint8_t*)p_hdr + BUFFER_HDR_SIZE;
673 }
674
675 GKI_enable();
676
677 return (p_buf);
678 }
679
680 /*******************************************************************************
681 **
682 ** Function GKI_enqueue
683 **
684 ** Description Enqueue a buffer at the tail of the queue
685 **
686 ** Parameters: p_q - (input) pointer to a queue.
687 ** p_buf - (input) address of the buffer to enqueue
688 **
689 ** Returns void
690 **
691 *******************************************************************************/
GKI_enqueue(BUFFER_Q * p_q,void * p_buf)692 void GKI_enqueue(BUFFER_Q* p_q, void* p_buf) {
693 BUFFER_HDR_T* p_hdr;
694
695 #if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE)
696 if (gki_chk_buf_damage(p_buf)) {
697 GKI_exception(GKI_ERROR_BUF_CORRUPTED, "Enqueue - Buffer corrupted");
698 return;
699 }
700 #endif
701
702 p_hdr = (BUFFER_HDR_T*)((uint8_t*)p_buf - BUFFER_HDR_SIZE);
703
704 if (p_hdr->status != BUF_STATUS_UNLINKED) {
705 GKI_exception(GKI_ERROR_ENQUEUE_BUF_LINKED, "Eneueue - buf already linked");
706 return;
707 }
708
709 GKI_disable();
710
711 /* Since the queue is exposed (C vs C++), keep the pointers in exposed format
712 */
713 if (p_q->p_first) {
714 BUFFER_HDR_T* p_last_hdr =
715 (BUFFER_HDR_T*)((uint8_t*)p_q->p_last - BUFFER_HDR_SIZE);
716 p_last_hdr->p_next = p_hdr;
717 } else
718 p_q->p_first = p_buf;
719
720 p_q->p_last = p_buf;
721 p_q->count++;
722
723 p_hdr->p_next = nullptr;
724 p_hdr->status = BUF_STATUS_QUEUED;
725
726 GKI_enable();
727
728 return;
729 }
730
731 /*******************************************************************************
732 **
733 ** Function GKI_enqueue_head
734 **
735 ** Description Enqueue a buffer at the head of the queue
736 **
737 ** Parameters: p_q - (input) pointer to a queue.
738 ** p_buf - (input) address of the buffer to enqueue
739 **
740 ** Returns void
741 **
742 *******************************************************************************/
GKI_enqueue_head(BUFFER_Q * p_q,void * p_buf)743 void GKI_enqueue_head(BUFFER_Q* p_q, void* p_buf) {
744 BUFFER_HDR_T* p_hdr;
745
746 #if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE)
747 if (gki_chk_buf_damage(p_buf)) {
748 GKI_exception(GKI_ERROR_BUF_CORRUPTED, "Enqueue - Buffer corrupted");
749 return;
750 }
751 #endif
752
753 p_hdr = (BUFFER_HDR_T*)((uint8_t*)p_buf - BUFFER_HDR_SIZE);
754
755 if (p_hdr->status != BUF_STATUS_UNLINKED) {
756 GKI_exception(GKI_ERROR_ENQUEUE_BUF_LINKED,
757 "Eneueue head - buf already linked");
758 return;
759 }
760
761 GKI_disable();
762
763 if (p_q->p_first) {
764 p_hdr->p_next = (BUFFER_HDR_T*)((uint8_t*)p_q->p_first - BUFFER_HDR_SIZE);
765 p_q->p_first = p_buf;
766 } else {
767 p_q->p_first = p_buf;
768 p_q->p_last = p_buf;
769 p_hdr->p_next = nullptr;
770 }
771 p_q->count++;
772
773 p_hdr->status = BUF_STATUS_QUEUED;
774
775 GKI_enable();
776
777 return;
778 }
779
780 /*******************************************************************************
781 **
782 ** Function GKI_dequeue
783 **
784 ** Description Dequeues a buffer from the head of a queue
785 **
786 ** Parameters: p_q - (input) pointer to a queue.
787 **
788 ** Returns NULL if queue is empty, else buffer
789 **
790 *******************************************************************************/
GKI_dequeue(BUFFER_Q * p_q)791 void* GKI_dequeue(BUFFER_Q* p_q) {
792 BUFFER_HDR_T* p_hdr;
793
794 GKI_disable();
795
796 if (!p_q || !p_q->count) {
797 GKI_enable();
798 return (nullptr);
799 }
800
801 p_hdr = (BUFFER_HDR_T*)((uint8_t*)p_q->p_first - BUFFER_HDR_SIZE);
802
803 /* Keep buffers such that GKI header is invisible
804 */
805 if (p_hdr->p_next)
806 p_q->p_first = ((uint8_t*)p_hdr->p_next + BUFFER_HDR_SIZE);
807 else {
808 p_q->p_first = nullptr;
809 p_q->p_last = nullptr;
810 }
811
812 p_q->count--;
813
814 p_hdr->p_next = nullptr;
815 p_hdr->status = BUF_STATUS_UNLINKED;
816
817 GKI_enable();
818
819 return ((uint8_t*)p_hdr + BUFFER_HDR_SIZE);
820 }
821
822 /*******************************************************************************
823 **
824 ** Function GKI_remove_from_queue
825 **
826 ** Description Dequeue a buffer from the middle of the queue
827 **
828 ** Parameters: p_q - (input) pointer to a queue.
829 ** p_buf - (input) address of the buffer to enqueue
830 **
831 ** Returns NULL if queue is empty, else buffer
832 **
833 *******************************************************************************/
GKI_remove_from_queue(BUFFER_Q * p_q,void * p_buf)834 void* GKI_remove_from_queue(BUFFER_Q* p_q, void* p_buf) {
835 BUFFER_HDR_T* p_prev;
836 BUFFER_HDR_T* p_buf_hdr;
837
838 GKI_disable();
839
840 if (p_buf == p_q->p_first) {
841 GKI_enable();
842 return (GKI_dequeue(p_q));
843 }
844
845 p_buf_hdr = (BUFFER_HDR_T*)((uint8_t*)p_buf - BUFFER_HDR_SIZE);
846 p_prev = (BUFFER_HDR_T*)((uint8_t*)p_q->p_first - BUFFER_HDR_SIZE);
847
848 for (; p_prev; p_prev = p_prev->p_next) {
849 /* If the previous points to this one, move the pointers around */
850 if (p_prev->p_next == p_buf_hdr) {
851 p_prev->p_next = p_buf_hdr->p_next;
852
853 /* If we are removing the last guy in the queue, update p_last */
854 if (p_buf == p_q->p_last) p_q->p_last = p_prev + 1;
855
856 /* One less in the queue */
857 p_q->count--;
858
859 /* The buffer is now unlinked */
860 p_buf_hdr->p_next = nullptr;
861 p_buf_hdr->status = BUF_STATUS_UNLINKED;
862
863 GKI_enable();
864 return (p_buf);
865 }
866 }
867
868 GKI_enable();
869 return (nullptr);
870 }
871
872 /*******************************************************************************
873 **
874 ** Function GKI_getfirst
875 **
876 ** Description Return a pointer to the first buffer in a queue
877 **
878 ** Parameters: p_q - (input) pointer to a queue.
879 **
880 ** Returns NULL if queue is empty, else buffer address
881 **
882 *******************************************************************************/
GKI_getfirst(BUFFER_Q * p_q)883 void* GKI_getfirst(BUFFER_Q* p_q) { return (p_q->p_first); }
884
885 /*******************************************************************************
886 **
887 ** Function GKI_getlast
888 **
889 ** Description Return a pointer to the last buffer in a queue
890 **
891 ** Parameters: p_q - (input) pointer to a queue.
892 **
893 ** Returns NULL if queue is empty, else buffer address
894 **
895 *******************************************************************************/
GKI_getlast(BUFFER_Q * p_q)896 void* GKI_getlast(BUFFER_Q* p_q) { return (p_q->p_last); }
897
898 /*******************************************************************************
899 **
900 ** Function GKI_getnext
901 **
902 ** Description Return a pointer to the next buffer in a queue
903 **
904 ** Parameters: p_buf - (input) pointer to the buffer to find the next one
905 ** from.
906 **
907 ** Returns NULL if no more buffers in the queue, else next buffer
908 ** address
909 **
910 *******************************************************************************/
GKI_getnext(void * p_buf)911 void* GKI_getnext(void* p_buf) {
912 BUFFER_HDR_T* p_hdr;
913
914 p_hdr = (BUFFER_HDR_T*)((uint8_t*)p_buf - BUFFER_HDR_SIZE);
915
916 if (p_hdr->p_next)
917 return ((uint8_t*)p_hdr->p_next + BUFFER_HDR_SIZE);
918 else
919 return (nullptr);
920 }
921
922 /*******************************************************************************
923 **
924 ** Function GKI_queue_is_empty
925 **
926 ** Description Check the status of a queue.
927 **
928 ** Parameters: p_q - (input) pointer to a queue.
929 **
930 ** Returns TRUE if queue is empty, else FALSE
931 **
932 *******************************************************************************/
GKI_queue_is_empty(BUFFER_Q * p_q)933 bool GKI_queue_is_empty(BUFFER_Q* p_q) { return ((bool)(p_q->count == 0)); }
934
935 /*******************************************************************************
936 **
937 ** Function GKI_find_buf_start
938 **
939 ** Description This function is called with an address inside a buffer,
940 ** and returns the start address ofthe buffer.
941 **
942 ** The buffer should be one allocated from one of GKI's pools.
943 **
944 ** Parameters: p_user_area - (input) address of anywhere in a GKI buffer.
945 **
946 ** Returns void * - Address of the beginning of the specified buffer if
947 ** successful, otherwise NULL if unsuccessful
948 **
949 *******************************************************************************/
GKI_find_buf_start(void * p_user_area)950 void* GKI_find_buf_start(void* p_user_area) {
951 uint16_t xx, size;
952 uint32_t yy;
953 tGKI_COM_CB* p_cb = &gki_cb.com;
954 uint8_t* p_ua = (uint8_t*)p_user_area;
955
956 for (xx = 0; xx < GKI_NUM_TOTAL_BUF_POOLS; xx++) {
957 if ((p_ua > p_cb->pool_start[xx]) && (p_ua < p_cb->pool_end[xx])) {
958 yy = (uint32_t)(p_ua - p_cb->pool_start[xx]);
959
960 size = p_cb->pool_size[xx];
961
962 yy = (yy / size) * size;
963
964 return ((void*)(p_cb->pool_start[xx] + yy + sizeof(BUFFER_HDR_T)));
965 }
966 }
967
968 /* If here, invalid address - not in one of our buffers */
969 GKI_exception(GKI_ERROR_BUF_SIZE_ZERO, "GKI_get_buf_start:: bad addr");
970
971 return (nullptr);
972 }
973
974 /********************************************************
975 * The following functions are not needed for light stack
976 *********************************************************/
977 #ifndef BTU_STACK_LITE_ENABLED
978 #define BTU_STACK_LITE_ENABLED FALSE
979 #endif
980
981 #if (BTU_STACK_LITE_ENABLED == FALSE)
982
983 /*******************************************************************************
984 **
985 ** Function GKI_set_pool_permission
986 **
987 ** Description This function is called to set or change the permissions for
988 ** the specified pool ID.
989 **
990 ** Parameters pool_id - (input) pool ID to be set or changed
991 ** permission - (input) GKI_PUBLIC_POOL or GKI_RESTRICTED_POOL
992 **
993 ** Returns GKI_SUCCESS if successful
994 ** GKI_INVALID_POOL if unsuccessful
995 **
996 *******************************************************************************/
GKI_set_pool_permission(uint8_t pool_id,uint8_t permission)997 uint8_t GKI_set_pool_permission(uint8_t pool_id, uint8_t permission) {
998 tGKI_COM_CB* p_cb = &gki_cb.com;
999
1000 if (pool_id < GKI_NUM_TOTAL_BUF_POOLS) {
1001 if (permission == GKI_RESTRICTED_POOL)
1002 p_cb->pool_access_mask =
1003 (uint16_t)(p_cb->pool_access_mask | (1 << pool_id));
1004
1005 else /* mark the pool as public */
1006 p_cb->pool_access_mask =
1007 (uint16_t)(p_cb->pool_access_mask & ~(1 << pool_id));
1008
1009 return (GKI_SUCCESS);
1010 } else
1011 return (GKI_INVALID_POOL);
1012 }
1013
1014 /*******************************************************************************
1015 **
1016 ** Function gki_add_to_pool_list
1017 **
1018 ** Description Adds pool to the pool list which is arranged in the
1019 ** order of size
1020 **
1021 ** Returns void
1022 **
1023 *******************************************************************************/
gki_add_to_pool_list(uint8_t pool_id)1024 static void gki_add_to_pool_list(uint8_t pool_id) {
1025 int32_t i, j;
1026 tGKI_COM_CB* p_cb = &gki_cb.com;
1027
1028 /* Find the position where the specified pool should be inserted into the list
1029 */
1030 for (i = 0; i < p_cb->curr_total_no_of_pools; i++) {
1031 if (p_cb->freeq[pool_id].size <= p_cb->freeq[p_cb->pool_list[i]].size)
1032 break;
1033 }
1034
1035 /* Insert the new buffer pool ID into the list of pools */
1036 for (j = p_cb->curr_total_no_of_pools; j > i; j--) {
1037 p_cb->pool_list[j] = p_cb->pool_list[j - 1];
1038 }
1039
1040 p_cb->pool_list[i] = pool_id;
1041
1042 return;
1043 }
1044
1045 /*******************************************************************************
1046 **
1047 ** Function gki_remove_from_pool_list
1048 **
1049 ** Description Removes pool from the pool list. Called when a pool is
1050 ** deleted
1051 **
1052 ** Returns void
1053 **
1054 *******************************************************************************/
gki_remove_from_pool_list(uint8_t pool_id)1055 static void gki_remove_from_pool_list(uint8_t pool_id) {
1056 tGKI_COM_CB* p_cb = &gki_cb.com;
1057 uint8_t i;
1058
1059 for (i = 0; i < p_cb->curr_total_no_of_pools; i++) {
1060 if (pool_id == p_cb->pool_list[i]) break;
1061 }
1062
1063 while (i < (p_cb->curr_total_no_of_pools - 1)) {
1064 p_cb->pool_list[i] = p_cb->pool_list[i + 1];
1065 i++;
1066 }
1067
1068 return;
1069 }
1070
1071 /*******************************************************************************
1072 **
1073 ** Function GKI_poolcount
1074 **
1075 ** Description Called by an application to get the total number of buffers
1076 ** in the specified buffer pool.
1077 **
1078 ** Parameters pool_id - (input) pool ID to get the free count of.
1079 **
1080 ** Returns the total number of buffers in the pool
1081 **
1082 *******************************************************************************/
GKI_poolcount(uint8_t pool_id)1083 uint16_t GKI_poolcount(uint8_t pool_id) {
1084 if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS) return (0);
1085
1086 return (gki_cb.com.freeq[pool_id].total);
1087 }
1088
1089 /*******************************************************************************
1090 **
1091 ** Function GKI_poolfreecount
1092 **
1093 ** Description Called by an application to get the number of free buffers
1094 ** in the specified buffer pool.
1095 **
1096 ** Parameters pool_id - (input) pool ID to get the free count of.
1097 **
1098 ** Returns the number of free buffers in the pool
1099 **
1100 *******************************************************************************/
GKI_poolfreecount(uint8_t pool_id)1101 uint16_t GKI_poolfreecount(uint8_t pool_id) {
1102 FREE_QUEUE_T* Q;
1103
1104 if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS) return (0);
1105
1106 Q = &gki_cb.com.freeq[pool_id];
1107
1108 return ((uint16_t)(Q->total - Q->cur_cnt));
1109 }
1110
1111 /*******************************************************************************
1112 **
1113 ** Function GKI_change_buf_owner
1114 **
1115 ** Description Called to change the task ownership of a buffer.
1116 **
1117 ** Parameters: p_buf - (input) pointer to the buffer
1118 ** task_id - (input) task id to change ownership to
1119 **
1120 ** Returns void
1121 **
1122 *******************************************************************************/
GKI_change_buf_owner(void * p_buf,uint8_t task_id)1123 void GKI_change_buf_owner(void* p_buf, uint8_t task_id) {
1124 BUFFER_HDR_T* p_hdr = (BUFFER_HDR_T*)((uint8_t*)p_buf - BUFFER_HDR_SIZE);
1125
1126 p_hdr->task_id = task_id;
1127
1128 return;
1129 }
1130
1131 #if (GKI_SEND_MSG_FROM_ISR == TRUE)
1132 /*******************************************************************************
1133 **
1134 ** Function GKI_isend_msg
1135 **
1136 ** Description Called from interrupt context to send a buffer to a task
1137 **
1138 ** Returns Nothing
1139 **
1140 *******************************************************************************/
GKI_isend_msg(uint8_t task_id,uint8_t mbox,void * msg)1141 void GKI_isend_msg(uint8_t task_id, uint8_t mbox, void* msg) {
1142 BUFFER_HDR_T* p_hdr;
1143 tGKI_COM_CB* p_cb = &gki_cb.com;
1144
1145 /* If task non-existant or not started, drop buffer */
1146 if ((task_id >= GKI_MAX_TASKS) || (mbox >= NUM_TASK_MBOX) ||
1147 (p_cb->OSRdyTbl[task_id] == TASK_DEAD)) {
1148 GKI_exception(GKI_ERROR_SEND_MSG_BAD_DEST, "Sending to unknown dest");
1149 GKI_freebuf(msg);
1150 return;
1151 }
1152
1153 #if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE)
1154 if (gki_chk_buf_damage(msg)) {
1155 GKI_exception(GKI_ERROR_BUF_CORRUPTED, "Send - Buffer corrupted");
1156 return;
1157 }
1158 #endif
1159
1160 #if (GKI_ENABLE_OWNER_CHECK == TRUE)
1161 if (gki_chk_buf_owner(msg)) {
1162 GKI_exception(GKI_ERROR_NOT_BUF_OWNER, "Send by non-owner");
1163 return;
1164 }
1165 #endif
1166
1167 p_hdr = (BUFFER_HDR_T*)((uint8_t*)msg - BUFFER_HDR_SIZE);
1168
1169 if (p_hdr->status != BUF_STATUS_UNLINKED) {
1170 GKI_exception(GKI_ERROR_SEND_MSG_BUF_LINKED, "Send - buffer linked");
1171 return;
1172 }
1173
1174 if (p_cb->OSTaskQFirst[task_id][mbox])
1175 p_cb->OSTaskQLast[task_id][mbox]->p_next = p_hdr;
1176 else
1177 p_cb->OSTaskQFirst[task_id][mbox] = p_hdr;
1178
1179 p_cb->OSTaskQLast[task_id][mbox] = p_hdr;
1180
1181 p_hdr->p_next = NULL;
1182 p_hdr->status = BUF_STATUS_QUEUED;
1183 p_hdr->task_id = task_id;
1184
1185 GKI_isend_event(task_id, (uint16_t)EVENT_MASK(mbox));
1186
1187 return;
1188 }
1189 #endif
1190
1191 /*******************************************************************************
1192 **
1193 ** Function GKI_create_pool
1194 **
1195 ** Description Called by applications to create a buffer pool.
1196 **
1197 ** Parameters: size - (input) length (in bytes) of each buffer in the pool
1198 ** count - (input) number of buffers to allocate for the pool
1199 ** permission - (input) restricted or public access?
1200 ** (GKI_PUBLIC_POOL or GKI_RESTRICTED_POOL)
1201 ** p_mem_pool - (input) pointer to an OS memory pool, NULL if
1202 ** not provided
1203 **
1204 ** Returns the buffer pool ID, which should be used in calls to
1205 ** GKI_getpoolbuf(). If a pool could not be created, this
1206 ** function returns 0xff.
1207 **
1208 *******************************************************************************/
GKI_create_pool(uint16_t size,uint16_t count,uint8_t permission,void * p_mem_pool)1209 uint8_t GKI_create_pool(uint16_t size, uint16_t count, uint8_t permission,
1210 void* p_mem_pool) {
1211 uint8_t xx;
1212 uint32_t mem_needed;
1213 int32_t tempsize = size;
1214 tGKI_COM_CB* p_cb = &gki_cb.com;
1215
1216 /* First make sure the size of each pool has a valid size with room for the
1217 * header info */
1218 if (size > MAX_USER_BUF_SIZE) return (GKI_INVALID_POOL);
1219
1220 /* First, look for an unused pool */
1221 for (xx = 0; xx < GKI_NUM_TOTAL_BUF_POOLS; xx++) {
1222 if (!p_cb->pool_start[xx]) break;
1223 }
1224
1225 if (xx == GKI_NUM_TOTAL_BUF_POOLS) return (GKI_INVALID_POOL);
1226
1227 /* Ensure an even number of longwords */
1228 tempsize = (int32_t)ALIGN_POOL(size);
1229
1230 mem_needed = (tempsize + BUFFER_PADDING_SIZE) * count;
1231
1232 if (!p_mem_pool) p_mem_pool = GKI_os_malloc(mem_needed);
1233
1234 if (p_mem_pool) {
1235 /* Initialize the new pool */
1236 gki_init_free_queue(xx, size, count, p_mem_pool);
1237 gki_add_to_pool_list(xx);
1238 (void)GKI_set_pool_permission(xx, permission);
1239 p_cb->curr_total_no_of_pools++;
1240
1241 return (xx);
1242 } else
1243 return (GKI_INVALID_POOL);
1244 }
1245
1246 /*******************************************************************************
1247 **
1248 ** Function GKI_delete_pool
1249 **
1250 ** Description Called by applications to delete a buffer pool. The
1251 ** function calls the operating specific function to free the
1252 ** actual memory. An exception is generated if an error is
1253 ** detected.
1254 **
1255 ** Parameters: pool_id - (input) Id of the poll being deleted.
1256 **
1257 ** Returns void
1258 **
1259 *******************************************************************************/
GKI_delete_pool(uint8_t pool_id)1260 void GKI_delete_pool(uint8_t pool_id) {
1261 FREE_QUEUE_T* Q;
1262 tGKI_COM_CB* p_cb = &gki_cb.com;
1263
1264 if ((pool_id >= GKI_NUM_TOTAL_BUF_POOLS) || (!p_cb->pool_start[pool_id]))
1265 return;
1266
1267 GKI_disable();
1268 Q = &p_cb->freeq[pool_id];
1269
1270 if (!Q->cur_cnt) {
1271 Q->size = 0;
1272 Q->total = 0;
1273 Q->cur_cnt = 0;
1274 Q->max_cnt = 0;
1275 Q->p_first = nullptr;
1276 Q->p_last = nullptr;
1277
1278 GKI_os_free(p_cb->pool_start[pool_id]);
1279
1280 p_cb->pool_start[pool_id] = nullptr;
1281 p_cb->pool_end[pool_id] = nullptr;
1282 p_cb->pool_size[pool_id] = 0;
1283
1284 gki_remove_from_pool_list(pool_id);
1285 p_cb->curr_total_no_of_pools--;
1286 } else
1287 GKI_exception(GKI_ERROR_DELETE_POOL_BAD_QID, "Deleting bad pool");
1288
1289 GKI_enable();
1290
1291 return;
1292 }
1293
1294 #endif /* BTU_STACK_LITE_ENABLED == FALSE */
1295
1296 /*******************************************************************************
1297 **
1298 ** Function GKI_get_pool_bufsize
1299 **
1300 ** Description Called by an application to get the size of buffers in a
1301 ** pool
1302 **
1303 ** Parameters Pool ID.
1304 **
1305 ** Returns the size of buffers in the pool
1306 **
1307 *******************************************************************************/
GKI_get_pool_bufsize(uint8_t pool_id)1308 uint16_t GKI_get_pool_bufsize(uint8_t pool_id) {
1309 #if defined(DYN_ALLOC) || defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
1310 uint16_t size = 0;
1311 switch (pool_id) {
1312 case GKI_POOL_ID_0:
1313 size = GKI_BUF0_SIZE;
1314 break;
1315 case GKI_POOL_ID_1:
1316 size = GKI_BUF1_SIZE;
1317 break;
1318 case GKI_POOL_ID_2:
1319 size = GKI_BUF2_SIZE;
1320 break;
1321 case GKI_POOL_ID_3:
1322 size = GKI_BUF3_SIZE;
1323 break;
1324 /* Here could be more pool ids, but they are not used in the current
1325 * implementation */
1326 default:
1327 LOG(ERROR) << StringPrintf("Unknown pool ID: %d", pool_id);
1328 return (0);
1329 break;
1330 }
1331 return (size);
1332 #else
1333 if (pool_id < GKI_NUM_TOTAL_BUF_POOLS)
1334 return (gki_cb.com.freeq[pool_id].size);
1335
1336 return (0);
1337 #endif
1338 }
1339
1340 /*******************************************************************************
1341 **
1342 ** Function GKI_poolutilization
1343 **
1344 ** Description Called by an application to get the buffer utilization
1345 ** in the specified buffer pool.
1346 **
1347 ** Parameters pool_id - (input) pool ID to get the free count of.
1348 **
1349 ** Returns % of buffers used from 0 to 100
1350 **
1351 *******************************************************************************/
GKI_poolutilization(uint8_t pool_id)1352 uint16_t GKI_poolutilization(uint8_t pool_id) {
1353 FREE_QUEUE_T* Q;
1354
1355 if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS) return (100);
1356
1357 Q = &gki_cb.com.freeq[pool_id];
1358
1359 if (Q->total == 0) return (100);
1360
1361 return ((Q->cur_cnt * 100) / Q->total);
1362 }
1363