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