1 /* USER CODE BEGIN Header */
2 /**
3   ******************************************************************************
4   * @file    adv_buff_alloc.c
5   * @author  AMS - RF Application team
6   * @brief   Module providing buffer allocation for advertising data.
7   ******************************************************************************
8   * @attention
9   *
10   * Copyright (c) 2024 STMicroelectronics.
11   * All rights reserved.
12   *
13   * This software is licensed under terms that can be found in the LICENSE file
14   * in the root directory of this software component.
15   * If no LICENSE file comes with this software, it is provided AS-IS.
16   *
17   ******************************************************************************
18   */
19 /* USER CODE END Header */
20 #include <stdint.h>
21 #include <stdlib.h>
22 #include "ble.h"
23 #include "pawr_buff_alloc.h"
24 
25 #if (CFG_BLE_CONTROLLER_PERIODIC_ADV_WR_ENABLED == 1)
26 
27 static uint8_t pawr_subevent_buf[CFG_BLE_PAWR_SUBEVENT_DATA_COUNT_MAX][MAX_PAWR_SUBEVENT_DATA_SIZE];
28 
29 static uint8_t pawr_resp_buff[MAX_PAWR_RESPONSE_SUBEVENT_COUNT][MAX_PAWR_SUBEVENT_DATA_SIZE];
30 
31 #if CFG_BLE_PAWR_SUBEVENT_DATA_COUNT_MAX < 33
32 /* Variable used to keep which buffer is used and which one is not in use by the link layer.
33    Up to 32 buffers can be handled.  */
34 static uint32_t used_subevent_buff_msk;
35 
36 #elif CFG_BLE_PAWR_SUBEVENT_DATA_COUNT_MAX < 65
37 
38 static uint64_t used_subevent_buff_msk;
39 
40 #else
41 
42 #error "This implementation does not allow to handle more than 64 buffers for subevents."
43 
44 #endif
45 
46 #if MAX_PAWR_RESPONSE_SUBEVENT_COUNT < 9
47 /* Variable used to keep which buffer is used and which one is not in use by the link layer.
48    Up to 32 buffers can be handled.  */
49 static uint8_t used_resp_buff_msk;
50 
51 #else
52 
53 #error "This implementation does not allow to handle more than 8 buffers for pawr responses."
54 
55 #endif
56 
57 #define BUFFER_IN_USE(mask, i)        (mask & (1<<i))
58 #define SET_BUFFER_IN_USE(mask, i)    (mask |= (1<<i))
59 #define CLEAR_BUFFER_IN_USE(mask, i)  (mask &= ~(1<<i))
60 
61 /**
62 * @brief  Initialize the module for buffer allocation. Mandatory before any use of the module.
63 * @retval None
64 */
pawr_buff_init(void)65 void pawr_buff_init(void)
66 {
67   used_subevent_buff_msk = 0;
68   used_resp_buff_msk = 0;
69 }
70 
subevent_buff_free(void * p)71 static void subevent_buff_free(void *p)
72 {
73   for(int i = 0; i < CFG_BLE_PAWR_SUBEVENT_DATA_COUNT_MAX; i++)
74     {
75       if(p == pawr_subevent_buf[i])
76       {
77         CLEAR_BUFFER_IN_USE(used_subevent_buff_msk, i);
78         return;
79       }
80     }
81 }
82 
response_buff_free(void * p)83 static void response_buff_free(void *p)
84 {
85   for(int i = 0; i < MAX_PAWR_RESPONSE_SUBEVENT_COUNT; i++)
86   {
87     if(p == pawr_resp_buff[i])
88     {
89       CLEAR_BUFFER_IN_USE(used_resp_buff_msk, i);
90       return;
91     }
92   }
93 }
94 
95 /**
96 * @brief  Mark a buffer as free.
97 * @param  p Pointer to the buffer
98 * @param  t Type of buffer between subevent data and response data
99 * @retval None
100 */
pawr_buff_free(void * p,uint8_t t)101 void pawr_buff_free(void * p, uint8_t t)
102 {
103   switch (t)
104   {
105   case HAL_PAWR_DATA_TYPE_SUBEVENT:
106     // p is a buffer for PAwR subevents
107     subevent_buff_free(p);
108     break;
109   case HAL_PAWR_DATA_TYPE_RESPONSE:
110     // p is a buffer for PAwR responses
111     response_buff_free(p);
112     break;
113   default:
114     break;
115   }
116 }
117 
118 /**
119 * @brief  Allocate a buffer of MAX_PAWR_SUBEVENT_DATA_SIZE bytes for PaWR subevents.
120 * @retval It returns the pointer to the buffer.
121 */
pawr_buff_subevent_alloc(void)122 void * pawr_buff_subevent_alloc(void)
123 {
124   uint8_t i;
125 
126   for(i = 0; i < CFG_BLE_PAWR_SUBEVENT_DATA_COUNT_MAX && BUFFER_IN_USE(used_subevent_buff_msk, i) ; i++);
127 
128   if(i == CFG_BLE_PAWR_SUBEVENT_DATA_COUNT_MAX)
129   {
130     // No free buffer found.
131     return NULL;
132   }
133 
134   SET_BUFFER_IN_USE(used_subevent_buff_msk, i);
135 
136   return pawr_subevent_buf[i];
137 }
138 
139 /**
140 * @brief  Allocate a buffer of MAX_PAWR_RESPONSE_DATA_SIZE bytes for PaWR response data.
141 * @retval It returns the pointer to the buffer.
142 */
pawr_buff_resp_alloc(void)143 void * pawr_buff_resp_alloc(void)
144 {
145   uint8_t i;
146 
147   for(i = 0; i < MAX_PAWR_RESPONSE_SUBEVENT_COUNT && BUFFER_IN_USE(used_resp_buff_msk, i) ; i++);
148 
149   if(i == MAX_PAWR_RESPONSE_SUBEVENT_COUNT)
150   {
151     // No free buffer found.
152     return NULL;
153   }
154 
155   SET_BUFFER_IN_USE(used_resp_buff_msk, i);
156 
157   return pawr_resp_buff[i];
158 }
159 
pawr_buff_subevent_num_available(void)160 uint8_t pawr_buff_subevent_num_available(void)
161 {
162   uint8_t i;
163   uint8_t available_buff = 0;
164 
165   for(i = 0; i < CFG_BLE_PAWR_SUBEVENT_DATA_COUNT_MAX; i++)
166   {
167     if(!BUFFER_IN_USE(used_subevent_buff_msk, i))
168     {
169       available_buff++;
170     }
171   }
172 
173   return available_buff;
174 }
175 
176 #endif /* CONTROLLER_PERIODIC_ADV_WR_ENABLED == 1 */
177 
178