1 /* USER CODE BEGIN Header */
2 /**
3   ******************************************************************************
4   * @file    aci_adv_nwk.c
5   * @author  MCD Application Team
6   * @brief   Adaptation layer from stack native advertising interface
7   *                      to network interface.
8   ******************************************************************************
9   * @attention
10   *
11   * Copyright (c) 2024 STMicroelectronics.
12   * All rights reserved.
13   *
14   * This software is licensed under terms that can be found in the LICENSE file
15   * in the root directory of this software component.
16   * If no LICENSE file comes with this software, it is provided AS-IS.
17   *
18   ******************************************************************************
19   */
20 /* USER CODE END Header */
21 
22 #include <string.h>
23 #include "aci_adv_nwk.h"
24 #include "app_common.h"
25 #include "adv_buff_alloc.h"
26 #include "adv_buff_alloc_tiny.h"
27 #include "pawr_buff_alloc.h"
28 #include "ble.h"
29 
30 #define LEGACY_ADV_HANDLE   0xFE
31 #define MEM_ALLOC_OVERHEAD   8
32 #define MAX_ADV_DATA_LENGTH MIN(CFG_BLE_GATT_ADV_NWK_BUFFER_SIZE - CFG_BLE_ATT_QUEUED_WRITE_SIZE - MEM_ALLOC_OVERHEAD, 1650)
33 
34 /** @name Operation codes for setting advertising data
35   * @{
36   */
37 #define INTERMEDIATE_FRAGMENT   0
38 #define FIRST_FRAGMENT          1
39 #define LAST_FRAGMENT           2
40 #define COMPLETE_DATA           3
41 #define UNCHANGED_DATA          4
42 /**
43   * @}
44   */
45 
46 /** @name Options for layer parameter of set_legacy_adv_scan_data
47   * @{
48   */
49 #define LL                      0
50 #define GAP                     1
51 /**
52   * @}
53   */
54 
55 #if (CFG_BLE_CONTROLLER_EXT_ADV_SCAN_ENABLED == 0)
56 
57 static tBleStatus allocate_and_set_data_legacy(uint8_t Advertising_Handle, uint8_t Operation,
58                                                uint8_t Data_Length, uint8_t *Data, uint8_t adv_scan_resp, uint8_t layer);
59 
60 static tBleStatus set_legacy_data_ptr(uint16_t Data_Length, uint8_t *Data, uint8_t adv_scan_resp, uint8_t layer);
61 
aci_adv_nwk_init(void)62 void aci_adv_nwk_init(void)
63 {
64   adv_tiny_buff_init();
65 }
66 
allocate_and_set_data(uint8_t Advertising_Handle,uint8_t Operation,uint8_t Data_Length,uint8_t * Data,uint8_t adv_scan_resp,uint8_t layer)67 static tBleStatus allocate_and_set_data(uint8_t Advertising_Handle, uint8_t Operation, uint8_t Data_Length, uint8_t *Data, uint8_t adv_scan_resp, uint8_t layer)
68 {
69   return allocate_and_set_data_legacy(Advertising_Handle, Operation, Data_Length, Data, adv_scan_resp, layer);
70 }
71 
72 /* Event raised by the stack when a new data pointer becomes active.
73    The function will free the the memory pointed by the old pointer.
74 */
aci_hal_adv_scan_resp_data_update_event_preprocess(void * old_pointer,void * new_pointer)75 int aci_hal_adv_scan_resp_data_update_event_preprocess(void *old_pointer, void *new_pointer)
76 {
77   if (new_pointer != old_pointer)
78   {
79     adv_tiny_buff_free(old_pointer);
80   }
81 
82   return 1;
83 }
84 
85 // Advertising_Handle is actually not used
allocate_and_set_data_legacy(uint8_t Advertising_Handle,uint8_t Operation,uint8_t Data_Length,uint8_t * Data,uint8_t adv_scan_resp,uint8_t layer)86 static tBleStatus allocate_and_set_data_legacy(uint8_t Advertising_Handle, uint8_t Operation, uint8_t Data_Length, uint8_t *Data, uint8_t adv_scan_resp, uint8_t layer)
87 {
88   tBleStatus ret;
89   uint8_t *adv_buffer;
90 
91   if(Operation != COMPLETE_DATA || Data_Length > 31)
92     return BLE_ERROR_INVALID_HCI_CMD_PARAMS;
93 
94   adv_buffer = adv_tiny_buff_alloc();
95 
96   if(adv_buffer == NULL)
97     return BLE_ERROR_CONTROLLER_BUSY;
98 
99   memcpy(adv_buffer, Data, Data_Length);
100 
101   ret = set_legacy_data_ptr(Data_Length, adv_buffer, adv_scan_resp, layer);
102 
103   if(ret)
104   {
105     adv_tiny_buff_free(adv_buffer);
106   }
107 
108   return ret;
109 }
110 
set_legacy_data_ptr(uint16_t Data_Length,uint8_t * Data,uint8_t adv_scan_resp,uint8_t layer)111 static tBleStatus set_legacy_data_ptr(uint16_t Data_Length, uint8_t *Data, uint8_t adv_scan_resp, uint8_t layer)
112 {
113   if(adv_scan_resp == ADV_DATA){
114     // Advertising Data
115 #if (BLESTACK_CONTROLLER_ONLY == 0)
116     if(layer == GAP)
117       return aci_gap_set_advertising_data(0, COMPLETE_DATA, Data_Length, Data);
118     else
119 #endif
120       return ll_set_legacy_advertising_data_ptr(Data_Length, Data);
121   }
122   else{
123     // Scan Response
124 #if (BLESTACK_CONTROLLER_ONLY == 0)
125     if(layer == GAP)
126       return aci_gap_set_scan_response_data(0, Data_Length, Data);
127     else
128 #endif
129       return ll_set_legacy_scan_reponse_data_ptr(Data_Length, Data);
130   }
131 }
132 
aci_gap_set_advertising_enable_preprocess(uint8_t Enable,uint8_t Number_of_Sets,Advertising_Set_Parameters_t Advertising_Set_Parameters[])133 tBleStatus aci_gap_set_advertising_enable_preprocess(uint8_t Enable,
134                                                      uint8_t Number_of_Sets,
135                                                      Advertising_Set_Parameters_t Advertising_Set_Parameters[])
136 {
137   return BLE_STATUS_SUCCESS;
138 }
139 
140 #else /* (CFG_BLE_CONTROLLER_EXT_ADV_SCAN_ENABLED == 1) */
141 
hci_le_read_maximum_advertising_data_length(uint16_t * Maximum_Advertising_Data_Length)142 tBleStatus hci_le_read_maximum_advertising_data_length(uint16_t *Maximum_Advertising_Data_Length)
143 {
144   *Maximum_Advertising_Data_Length = MAX_ADV_DATA_LENGTH;
145 
146   return BLE_STATUS_SUCCESS;
147 }
148 
149 static tBleStatus allocate_and_set_data_ext(uint8_t Advertising_Handle,
150                                             uint8_t Operation, uint8_t Data_Length, uint8_t *Data, uint8_t data_type, uint8_t layer);
151 
aci_adv_nwk_init(void)152 void aci_adv_nwk_init(void)
153 {
154   adv_buff_init();
155 #if (CFG_BLE_CONTROLLER_PERIODIC_ADV_WR_ENABLED == 1)
156   pawr_buff_init();
157 #endif
158 }
159 
allocate_and_set_data(uint8_t Advertising_Handle,uint8_t Operation,uint8_t Data_Length,uint8_t * Data,uint8_t data_type,uint8_t layer)160 static tBleStatus allocate_and_set_data(uint8_t Advertising_Handle, uint8_t Operation, uint8_t Data_Length, uint8_t *Data, uint8_t data_type, uint8_t layer)
161 {
162   return allocate_and_set_data_ext(Advertising_Handle, Operation, Data_Length, Data, data_type, layer);
163 }
164 
hci_le_set_extended_advertising_data(uint8_t Advertising_Handle,uint8_t Operation,uint8_t Fragment_Preference,uint8_t Advertising_Data_Length,uint8_t * Advertising_Data)165 tBleStatus hci_le_set_extended_advertising_data(uint8_t Advertising_Handle, uint8_t Operation,
166                                                 uint8_t Fragment_Preference,
167                                                 uint8_t Advertising_Data_Length, uint8_t *Advertising_Data)
168 {
169   return allocate_and_set_data(Advertising_Handle,
170                                 Operation, Advertising_Data_Length, Advertising_Data, ADV_DATA, LL);
171 
172 }
173 
hci_le_set_extended_scan_response_data(uint8_t Advertising_Handle,uint8_t Operation,uint8_t Fragment_Preference,uint8_t Scan_Response_Data_Length,uint8_t * Scan_Response_Data)174 tBleStatus hci_le_set_extended_scan_response_data(uint8_t Advertising_Handle, uint8_t Operation,
175                                                 uint8_t Fragment_Preference,
176                                                 uint8_t Scan_Response_Data_Length, uint8_t *Scan_Response_Data)
177 {
178   return allocate_and_set_data(Advertising_Handle,
179                                 Operation, Scan_Response_Data_Length, Scan_Response_Data, SCAN_RESP_DATA, LL);
180 }
181 
182 #if (CFG_BLE_CONTROLLER_PERIODIC_ADV_ENABLED == 1)
hci_le_set_periodic_advertising_data(uint8_t Advertising_Handle,uint8_t Operation,uint8_t Advertising_Data_Length,uint8_t * Advertising_Data)183 tBleStatus hci_le_set_periodic_advertising_data(uint8_t Advertising_Handle, uint8_t Operation,
184                                                 uint8_t Advertising_Data_Length, uint8_t *Advertising_Data)
185 {
186   return allocate_and_set_data(Advertising_Handle,
187                                Operation, Advertising_Data_Length, Advertising_Data, PERIODIC_ADV_DATA, LL);
188 }
189 
190 #if (CFG_BLE_CONTROLLER_PERIODIC_ADV_WR_ENABLED == 1)
191 
hci_le_set_periodic_advertising_subevent_data(uint8_t Advertising_Handle,uint8_t Num_Subevents,Subevent_Data_Parameters_t Subevent_Data_Parameters[])192 tBleStatus hci_le_set_periodic_advertising_subevent_data(uint8_t Advertising_Handle,
193                                                          uint8_t Num_Subevents,
194                                                          Subevent_Data_Parameters_t Subevent_Data_Parameters[])
195 {
196   tBleStatus ret;
197   uint8_t i;
198   void * p;
199   Subevent_Data_Ptr_Parameters_t Subevent_Data_Ptr_Parameters[CFG_BLE_PAWR_SUBEVENT_DATA_COUNT_MAX] = {0};
200   uint16_t adv_event_prop;
201   uint8_t adv_enabled, periodic_adv_configured, periodic_adv_enabled;
202 
203   if (Advertising_Handle > 0xEF)
204   {
205     return BLE_ERROR_INVALID_HCI_CMD_PARAMS;
206   }
207 
208   /* Check if advertising set exists, so that error 0x42 will be returned. */
209   ret = ll_get_advertising_info(Advertising_Handle, &adv_enabled, &periodic_adv_configured, &periodic_adv_enabled, &adv_event_prop);
210   if(ret!=0)
211   {
212     return BLE_ERROR_UNKNOWN_ADVERTISING_IDENTIFIER;
213   }
214 
215   if(pawr_buff_subevent_num_available() < Num_Subevents)
216   {
217     /* This happens is host has given more data than what requested by the Controller.  */
218     return BLE_ERROR_COMMAND_DISALLOWED;
219   }
220 
221   for(i = 0; i < Num_Subevents; i++)
222   {
223     if(Subevent_Data_Parameters[i].Subevent_Data_Length > MAX_PAWR_SUBEVENT_DATA_SIZE)
224     {
225       /* This should never happen as long as MAX_PAWR_SUBEVENT_DATA_SIZE >= 249. */
226       ret = BLE_ERROR_MEMORY_CAPACITY_EXCEEDED;
227       goto fail;
228     }
229 
230     p = pawr_buff_subevent_alloc();
231 
232     if(p != NULL)
233     {
234       Subevent_Data_Ptr_Parameters[i].Subevent = Subevent_Data_Parameters[i].Subevent;
235       Subevent_Data_Ptr_Parameters[i].Response_Slot_Start = Subevent_Data_Parameters[i].Response_Slot_Start;
236       Subevent_Data_Ptr_Parameters[i].Response_Slot_Count = Subevent_Data_Parameters[i].Response_Slot_Count;
237       Subevent_Data_Ptr_Parameters[i].Subevent_Data_Length = Subevent_Data_Parameters[i].Subevent_Data_Length;
238       memcpy(p, Subevent_Data_Parameters[i].Subevent_Data, Subevent_Data_Parameters[i].Subevent_Data_Length);
239       Subevent_Data_Ptr_Parameters[i].Subevent_Data = p;
240     }
241     else
242     {
243       /* This should never happen since we checked num of available buffers before. */
244       goto fail;
245     }
246   }
247 
248   ret = ll_set_periodic_advertising_subevent_data_ptr(Advertising_Handle,
249                                                       Num_Subevents,
250                                                       Subevent_Data_Ptr_Parameters);
251 
252   if(ret == BLE_STATUS_SUCCESS)
253     return ret;
254 
255 fail:
256 
257   /* Free allocated buffers */
258   for(i = 0; i < Num_Subevents; i++)
259   {
260     pawr_buff_free(Subevent_Data_Ptr_Parameters[i].Subevent_Data, HAL_PAWR_DATA_TYPE_SUBEVENT);
261   }
262   return ret;
263 }
264 
hci_le_set_periodic_advertising_response_data(uint16_t Sync_Handle,uint16_t Request_Event,uint8_t Request_Subevent,uint8_t Response_Subevent,uint8_t Response_Slot,uint8_t Response_Data_Length,uint8_t Response_Data[])265 tBleStatus hci_le_set_periodic_advertising_response_data(uint16_t Sync_Handle,
266                                                          uint16_t Request_Event,
267                                                          uint8_t Request_Subevent,
268                                                          uint8_t Response_Subevent,
269                                                          uint8_t Response_Slot,
270                                                          uint8_t Response_Data_Length,
271                                                          uint8_t Response_Data[])
272 {
273   tBleStatus ret;
274   void * p;
275 
276   if(Response_Data_Length > MAX_PAWR_RESPONSE_DATA_SIZE)
277   {
278     /* This should never happen as long as MAX_PAWR_RESPONSE_DATA_SIZE >= 247. */
279     return BLE_ERROR_MEMORY_CAPACITY_EXCEEDED;
280   }
281 
282   p = pawr_buff_resp_alloc();
283 
284   if(p == NULL)
285   {
286     return BLE_ERROR_MEMORY_CAPACITY_EXCEEDED;
287   }
288 
289   memcpy(p, Response_Data, Response_Data_Length);
290 
291   ret = ll_set_periodic_advertising_response_data_ptr(Sync_Handle, Request_Event,
292                                                       Request_Subevent, Response_Subevent,
293                                                       Response_Slot, Response_Data_Length,
294                                                       p);
295 
296   if(ret != BLE_STATUS_SUCCESS)
297   {
298     pawr_buff_free(p, HAL_PAWR_DATA_TYPE_RESPONSE);
299   }
300 
301   return ret;
302 }
303 
304 #endif /* (CFG_BLE_CONTROLLER_PERIODIC_ADV_WR_ENABLED == 1) */
305 #endif /* (CFG_BLE_CONTROLLER_PERIODIC_ADV_ENABLED == 1) */
306 
aci_hal_adv_scan_resp_data_update_event_preprocess(void * old_pointer,void * new_pointer)307 int aci_hal_adv_scan_resp_data_update_event_preprocess(void *old_pointer, void *new_pointer)
308 {
309   if (new_pointer != old_pointer)
310   {
311     adv_buff_free_old(old_pointer);
312   }
313 
314   /* Do not forward the event. */
315   return 1;
316 }
317 
318 #if (CFG_BLE_CONTROLLER_PERIODIC_ADV_WR_ENABLED == 1)
aci_hal_pawr_data_free_event_preprocess(void * buffer,uint8_t type)319 int aci_hal_pawr_data_free_event_preprocess(void *buffer, uint8_t type)
320 {
321   pawr_buff_free(buffer, type);
322 
323   /* Do not forward the event. */
324   return 1;
325 }
326 #endif
327 
adv_data_check_param(uint8_t Advertising_Handle,uint8_t Operation,uint8_t Advertising_Data_Length,uint8_t * adv_enabled)328 static uint8_t adv_data_check_param(uint8_t Advertising_Handle, uint8_t Operation, uint8_t Advertising_Data_Length, uint8_t *adv_enabled)
329 {
330   uint16_t adv_event_prop;
331   uint8_t ret;
332   uint8_t periodic_adv_configured;
333   uint8_t periodic_adv_enabled;
334 
335   if(Advertising_Handle == LEGACY_ADV_HANDLE){
336 
337     *adv_enabled = TRUE;
338 
339     if(Operation != COMPLETE_DATA || Advertising_Data_Length > 31)
340       return BLE_ERROR_INVALID_HCI_CMD_PARAMS;
341 
342     return BLE_STATUS_SUCCESS;
343   }
344 
345   if(Advertising_Handle > 0xEF || Operation > UNCHANGED_DATA)
346     return BLE_ERROR_INVALID_HCI_CMD_PARAMS;
347 
348   ret = ll_get_advertising_info(Advertising_Handle, adv_enabled, &periodic_adv_configured, &periodic_adv_enabled, &adv_event_prop);
349 
350   /* "If the advertising set corresponding to the Advertising_Handle parameter does
351   not exist, then the Controller shall return the error code Unknown Advertising
352   Identifier (0x42)." */
353   if(ret!=0) // Advertising set does not exist.
354     return BLE_ERROR_UNKNOWN_ADVERTISING_IDENTIFIER;
355 
356   /* "If the advertising set specifies a type that does not support advertising data, the
357   Controller shall return the error code Invalid HCI Command Parameters (0x12)." */
358   if((adv_event_prop & HCI_ADV_EVENT_PROP_LEGACY && adv_event_prop & HCI_ADV_EVENT_PROP_DIRECTED) || // Legacy, directed advertising
359      (adv_event_prop & HCI_ADV_EVENT_PROP_SCANNABLE && !(adv_event_prop & HCI_ADV_EVENT_PROP_LEGACY))) // Scannable, non-legacy
360     return BLE_ERROR_INVALID_HCI_CMD_PARAMS;
361 
362   /* "If the advertising set uses legacy advertising PDUs that support advertising
363   data and either Operation is not 0x03 or the Advertising_Data_Length
364   parameter exceeds 31 octets, the Controller shall return the error code Invalid
365   HCI Command Parameters (0x12)."  */
366   if(adv_event_prop & HCI_ADV_EVENT_PROP_LEGACY && (Operation != COMPLETE_DATA || Advertising_Data_Length > 31)) // Legacy advertising
367     return BLE_ERROR_INVALID_HCI_CMD_PARAMS;
368 
369   /* "If Operation is not 0x03 or 0x04 and Advertising_Data_Length is zero, the
370   Controller shall return the error code Invalid HCI Command Parameters (0x12)." */
371   if(Operation != COMPLETE_DATA && Operation != UNCHANGED_DATA && Advertising_Data_Length == 0)
372     return BLE_ERROR_INVALID_HCI_CMD_PARAMS;
373 
374   /* "If advertising is currently enabled for the specified advertising set and
375   Operation does not have the value 0x03 or 0x04, the Controller shall return the
376   error code Command Disallowed (0x0C)." */
377   if(*adv_enabled && Operation != COMPLETE_DATA && Operation != UNCHANGED_DATA)
378     return BLE_ERROR_COMMAND_DISALLOWED;
379 
380   return BLE_STATUS_SUCCESS;
381 }
382 
scan_resp_data_check_param(uint8_t Advertising_Handle,uint8_t Operation,uint8_t Scan_Resp_Data_Length,uint8_t * adv_enabled)383 static uint8_t scan_resp_data_check_param(uint8_t Advertising_Handle, uint8_t Operation, uint8_t Scan_Resp_Data_Length, uint8_t *adv_enabled)
384 {
385   uint16_t adv_event_prop;
386   uint8_t ret;
387   uint8_t periodic_adv_configured;
388   uint8_t periodic_adv_enabled;
389 
390   if(Advertising_Handle == LEGACY_ADV_HANDLE){
391 
392     /* Assume advertising is always enabled, even if this is not true.
393        In this way the old buffer cannot be freed even if the advertising is not enabled. */
394     *adv_enabled = TRUE;
395 
396     if(Operation != COMPLETE_DATA || Scan_Resp_Data_Length > 31)
397       return BLE_ERROR_INVALID_HCI_CMD_PARAMS;
398 
399     return BLE_STATUS_SUCCESS;
400   }
401 
402   if(Operation > COMPLETE_DATA)
403     return BLE_ERROR_INVALID_HCI_CMD_PARAMS;
404 
405   ret = ll_get_advertising_info(Advertising_Handle, adv_enabled, &periodic_adv_configured, &periodic_adv_enabled, &adv_event_prop);
406 
407   /* "If the advertising set corresponding to the Advertising_Handle parameter does
408   not exist, then the Controller shall return the error code Unknown Advertising
409   Identifier (0x42)." */
410   if(ret!=0) // Advertising set does not exist.
411     return BLE_ERROR_UNKNOWN_ADVERTISING_IDENTIFIER;
412 
413   /* "If the advertising set is non-scannable and the Host uses this command other
414       than to discard existing data, the Controller shall return the error code Invalid
415       HCI Command Parameters (0x12)." */
416   if((!(adv_event_prop & HCI_ADV_EVENT_PROP_SCANNABLE) && Scan_Resp_Data_Length != 0))
417     return BLE_ERROR_INVALID_HCI_CMD_PARAMS;
418 
419   /* If the advertising set uses scannable legacy advertising PDUs and either
420      Operation is not 0x03 or the Scan_Response_Data_Length parameter exceeds
421      31 octets, the Controller shall return the error code Invalid HCI Command
422      Parameters (0x12). */
423   if(adv_event_prop & HCI_ADV_EVENT_PROP_LEGACY && adv_event_prop & HCI_ADV_EVENT_PROP_SCANNABLE
424      && (Operation != COMPLETE_DATA || Scan_Resp_Data_Length > 31))
425     return BLE_ERROR_INVALID_HCI_CMD_PARAMS;
426 
427   /* "If Operation is not 0x03 and Scan_Response_Data_Length is zero, the
428       Controller shall return the error code Invalid HCl Command Parameters (0x12)." */
429   if(Operation != COMPLETE_DATA && Scan_Resp_Data_Length == 0)
430     return BLE_ERROR_INVALID_HCI_CMD_PARAMS;
431 
432   /* "If advertising is currently enabled for the specified advertising set and
433       Operation does not have the value 0x03, the Controller shall return the error
434       code Command Disallowed (0x0C)." */
435   if(*adv_enabled && Operation != COMPLETE_DATA)
436     return BLE_ERROR_COMMAND_DISALLOWED;
437 
438   return BLE_STATUS_SUCCESS;
439 }
440 
441 #if (CFG_BLE_CONTROLLER_PERIODIC_ADV_ENABLED == 1)
periodic_adv_data_check_param(uint8_t Advertising_Handle,uint8_t Operation,uint8_t Advertising_Data_Length,uint8_t * adv_enabled,uint8_t * periodic_adv_enabled)442 static uint8_t periodic_adv_data_check_param(uint8_t Advertising_Handle, uint8_t Operation, uint8_t Advertising_Data_Length, uint8_t *adv_enabled, uint8_t *periodic_adv_enabled)
443 {
444   uint16_t adv_event_prop;
445   uint8_t periodic_adv_configured;
446   uint8_t ret;
447 
448   if(Operation > UNCHANGED_DATA)
449     return BLE_ERROR_INVALID_HCI_CMD_PARAMS;
450 
451   ret = ll_get_advertising_info(Advertising_Handle, adv_enabled, &periodic_adv_configured, periodic_adv_enabled, &adv_event_prop);
452 
453   /* "If the advertising set corresponding to the Advertising_Handle parameter does
454      not exist, then the Controller shall return the error code Unknown Advertising
455      Identifier (0x42)." */
456   if(ret!=0) // Advertising set does not exist.
457     return BLE_ERROR_UNKNOWN_ADVERTISING_IDENTIFIER;
458 
459   /* "If the advertising set has not been configured for periodic advertising,
460      then the Controller shall return the error code Command Disallowed (0x0C)." */
461   if(!periodic_adv_configured)
462     return BLE_ERROR_COMMAND_DISALLOWED;
463 
464   if(Advertising_Data_Length > 252)
465     return BLE_ERROR_INVALID_HCI_CMD_PARAMS;
466 
467   if ((Operation != COMPLETE_DATA) && (Operation != UNCHANGED_DATA))
468   {
469     /* "If periodic advertising is currently enabled for the specified advertising set and
470         Operation does not have the value 0x03 or 0x04, then the Controller shall
471         return the error code Command Disallowed (0x0C)." */
472     if(*periodic_adv_enabled)
473       return BLE_ERROR_COMMAND_DISALLOWED;
474 
475     if(Advertising_Data_Length == 0U)
476       return BLE_ERROR_INVALID_HCI_CMD_PARAMS;
477   }
478 
479   return  BLE_STATUS_SUCCESS;
480 }
481 #endif
482 
set_data_ptr(uint8_t Advertising_Handle,uint8_t Operation,uint16_t Data_Length,uint8_t * Data,uint8_t data_type,uint8_t gap)483 static tBleStatus set_data_ptr(uint8_t Advertising_Handle,
484                                     uint8_t Operation, uint16_t Data_Length, uint8_t *Data, uint8_t data_type, uint8_t gap)
485 {
486   if(data_type == ADV_DATA)
487   {
488     // Advertising Data
489 #if (BLESTACK_CONTROLLER_ONLY == 0)
490     if(gap)
491     {
492       return aci_gap_set_advertising_data(Advertising_Handle, Operation,
493                                           Data_Length, Data);
494 	}
495     else
496 #endif
497     {
498       if(Advertising_Handle == LEGACY_ADV_HANDLE)
499       {
500         return ll_set_legacy_advertising_data_ptr(Data_Length, Data);
501       }
502       else
503       {
504         return ll_set_advertising_data_ptr(Advertising_Handle, Operation, Data_Length, Data);
505       }
506     }
507   }
508   else if (data_type == SCAN_RESP_DATA)
509   {
510     // Scan Response
511 #if (BLESTACK_CONTROLLER_ONLY == 0)
512     if(gap)
513     {
514       return aci_gap_set_scan_response_data(Advertising_Handle,
515                                             Data_Length, Data);
516 	}
517     else
518 #endif
519     {
520       if(Advertising_Handle == LEGACY_ADV_HANDLE)
521       {
522         return ll_set_legacy_scan_reponse_data_ptr(Data_Length, Data);
523       }
524       else
525       {
526         return ll_set_scan_reponse_data_ptr(Advertising_Handle, Data_Length, Data);
527       }
528     }
529   }
530 #if (CFG_BLE_CONTROLLER_PERIODIC_ADV_ENABLED == 1)
531   else
532   { /* data_type == PERIODIC_ADV_DATA */
533     return ll_set_periodic_advertising_data_ptr(Advertising_Handle, Operation, Data_Length, Data);
534   }
535 #else
536   return BLE_ERROR_UNKNOWN_HCI_COMMAND;
537 #endif
538 }
539 
allocate_and_set_data_ext(uint8_t Advertising_Handle,uint8_t Operation,uint8_t Data_Length,uint8_t * Data,uint8_t data_type,uint8_t layer)540 static tBleStatus allocate_and_set_data_ext(uint8_t Advertising_Handle,
541                                   uint8_t Operation, uint8_t Data_Length, uint8_t *Data, uint8_t data_type, uint8_t layer)
542 {
543   uint8_t *buffer;
544   uint16_t buff_len;
545   uint8_t adv_enabled;
546 #if CONTROLLER_PERIODIC_ADV_ENABLED
547   uint8_t periodic_adv_enabled;
548 #endif
549   uint8_t status = BLE_ERROR_UNKNOWN_HCI_COMMAND;
550   uint16_t old_buff_len;
551   uint8_t extend = FALSE;
552 
553   if(Advertising_Handle == LEGACY_ADV_HANDLE && layer != LL){
554     return BLE_ERROR_INVALID_HCI_CMD_PARAMS; // This should not happen
555   }
556 
557   if(data_type == ADV_DATA){
558     status = adv_data_check_param(Advertising_Handle, Operation, Data_Length, &adv_enabled);
559   }
560   else if(data_type == SCAN_RESP_DATA){
561     status = scan_resp_data_check_param(Advertising_Handle, Operation, Data_Length, &adv_enabled);
562   }
563 #if (CFG_BLE_CONTROLLER_PERIODIC_ADV_ENABLED == 1)
564   else { /* PERIODIC_ADV_DATA */
565     status = periodic_adv_data_check_param(Advertising_Handle, Operation, Data_Length, &adv_enabled, &periodic_adv_enabled);
566   }
567 #endif
568 
569   if(status)
570     return status;
571 
572   /* Allocate the buffer */
573   switch(Operation){
574 
575   case UNCHANGED_DATA:
576     return set_data_ptr(Advertising_Handle, Operation, Data_Length, Data, data_type, layer);
577 
578   case FIRST_FRAGMENT:
579   case COMPLETE_DATA:
580     extend = FALSE;
581     adv_buff_free_next(Advertising_Handle, data_type);
582     break;
583 
584   case INTERMEDIATE_FRAGMENT:
585   case LAST_FRAGMENT:
586     extend = TRUE;
587     break;
588 
589   }
590 
591   buffer = adv_buff_alloc(Advertising_Handle, Data_Length, extend, &old_buff_len, data_type);
592   if((buffer == NULL && Data_Length != 0) || (old_buff_len + Data_Length > MAX_ADV_DATA_LENGTH)){
593     // Tell the stack that current advertising data has to be cancelled.
594     set_data_ptr(Advertising_Handle, COMPLETE_DATA, 0, NULL, data_type, layer);
595     adv_buff_deactivate_current(Advertising_Handle, data_type);
596     adv_buff_free_next(Advertising_Handle, data_type);
597 
598     return BLE_ERROR_MEMORY_CAPACITY_EXCEEDED;
599   }
600 
601   memcpy(buffer + old_buff_len, Data, Data_Length);
602 
603   buff_len = old_buff_len + Data_Length;
604 
605   if(Operation == LAST_FRAGMENT || Operation == COMPLETE_DATA){
606     status = set_data_ptr(Advertising_Handle, COMPLETE_DATA, buff_len, buffer, data_type, layer);
607     if(status == BLE_STATUS_SUCCESS){
608       adv_buff_deactivate_current(Advertising_Handle, data_type);
609       adv_buff_activate_next(Advertising_Handle, data_type);
610     }
611     else{
612       // Free what has been allocated so far for this advertising handle
613       adv_buff_free_next(Advertising_Handle, data_type);
614     }
615   }
616   else if(Operation == FIRST_FRAGMENT){
617     // Discard any existing partial or complete advertising data.
618     set_data_ptr(Advertising_Handle, COMPLETE_DATA, 0, NULL, data_type, layer);
619     adv_buff_deactivate_current(Advertising_Handle, data_type);
620   }
621 
622   return status;
623 }
624 
625 #if (CFG_BLE_CONTROLLER_PERIODIC_ADV_ENABLED == 1)
hci_le_set_periodic_advertising_enable_preprocess(uint8_t Enable,uint8_t Advertising_Handle)626 tBleStatus hci_le_set_periodic_advertising_enable_preprocess(uint8_t Enable,
627                                                              uint8_t Advertising_Handle)
628 {
629   /* If bit 0 of Enable in the HCI_LE_Set_Periodic_Advertising_Enable command is set to 1
630      (periodic advertising is enabled) and the advertising set contains partial periodic
631      advertising data, the Status value in the response to the command shall be
632      Command Disallowed (0x0C). */
633   if(((Enable & 0x01U) == 0x01U) && (new_buff_pending(Advertising_Handle, PERIODIC_ADV_DATA) == TRUE))
634     return BLE_ERROR_COMMAND_DISALLOWED;
635 
636   return BLE_STATUS_SUCCESS;
637 }
638 #endif
639 
hci_le_set_extended_advertising_enable_preprocess(uint8_t Enable,uint8_t Number_of_Sets,Advertising_Set_Parameters_t Advertising_Set_Parameters[])640 tBleStatus hci_le_set_extended_advertising_enable_preprocess(uint8_t Enable,
641                                                              uint8_t Number_of_Sets,
642                                                              Advertising_Set_Parameters_t Advertising_Set_Parameters[])
643 {
644   /*  The remainder of this section only applies if Enable is set to 0x01.
645   If the advertising data or scan response data in the advertising set is not
646   complete, the Controller shall return the error code Command Disallowed
647   (0x0C). */
648   if(Enable == 0x01){
649 
650     for(int i = 0; i < Number_of_Sets; i++){
651       if(new_buff_pending(Advertising_Set_Parameters[i].Advertising_Handle, ADV_DATA) == TRUE ||
652          new_buff_pending(Advertising_Set_Parameters[i].Advertising_Handle, SCAN_RESP_DATA) == TRUE)
653         return BLE_ERROR_COMMAND_DISALLOWED;
654     }
655 
656   }
657 
658   return BLE_STATUS_SUCCESS;
659 }
660 
aci_gap_set_advertising_enable_preprocess(uint8_t Enable,uint8_t Number_of_Sets,Advertising_Set_Parameters_t Advertising_Set_Parameters[])661 tBleStatus aci_gap_set_advertising_enable_preprocess(uint8_t Enable,
662                                                      uint8_t Number_of_Sets,
663                                                      Advertising_Set_Parameters_t Advertising_Set_Parameters[])
664 {
665   return hci_le_set_extended_advertising_enable_preprocess(Enable, Number_of_Sets, Advertising_Set_Parameters);
666 }
667 
668 #endif /* CFG_BLE_CONTROLLER_EXT_ADV_SCAN_ENABLED == 0 */
669 
hci_le_set_advertising_data(uint8_t Advertising_Data_Length,uint8_t Advertising_Data[31])670 tBleStatus hci_le_set_advertising_data(uint8_t Advertising_Data_Length,
671                                        uint8_t Advertising_Data[31])
672 {
673   return allocate_and_set_data(LEGACY_ADV_HANDLE, COMPLETE_DATA, Advertising_Data_Length, Advertising_Data, ADV_DATA, LL);
674 }
675 
hci_le_set_scan_response_data(uint8_t Scan_Response_Data_Length,uint8_t Scan_Response_Data[31])676 tBleStatus hci_le_set_scan_response_data(uint8_t Scan_Response_Data_Length,
677                                          uint8_t Scan_Response_Data[31])
678 {
679   return allocate_and_set_data(LEGACY_ADV_HANDLE, COMPLETE_DATA, Scan_Response_Data_Length, Scan_Response_Data, SCAN_RESP_DATA, LL);
680 }
681 
aci_gap_set_advertising_data_nwk(uint8_t Advertising_Handle,uint8_t Operation,uint8_t Advertising_Data_Length,uint8_t * Advertising_Data)682 tBleStatus aci_gap_set_advertising_data_nwk(uint8_t Advertising_Handle,
683                                             uint8_t Operation, uint8_t Advertising_Data_Length, uint8_t *Advertising_Data)
684 {
685   return allocate_and_set_data(Advertising_Handle,
686                                 Operation, Advertising_Data_Length, Advertising_Data, ADV_DATA, GAP);
687 }
688 
aci_gap_set_scan_response_data_nwk(uint8_t Advertising_Handle,uint8_t Operation,uint8_t Scan_Response_Data_Length,uint8_t * Scan_Response_Data)689 tBleStatus aci_gap_set_scan_response_data_nwk(uint8_t Advertising_Handle,
690                                               uint8_t Operation, uint8_t Scan_Response_Data_Length, uint8_t *Scan_Response_Data)
691 {
692   return allocate_and_set_data(Advertising_Handle,
693                                 Operation, Scan_Response_Data_Length, Scan_Response_Data, SCAN_RESP_DATA, GAP);
694 }
695 
696 /* --------------------- E A D --------------------- */
697 
698 #if (BLESTACK_CONTROLLER_ONLY == 0)
699 
700 extern void char_copy(volatile uint8_t *from, volatile uint8_t *q, size_t n);
701 
702 #define ACI_EAD_PAYLOAD_CLEAR_DATA_LEN_MAX (241U)
703 #define ACI_EAD_PAYLOAD_ENCRY_DATA_LEN_MAX (254U)
704 /* the overhead for Encrypted data is given by the leading Randomizer field (5 octets)
705  * and by the trailing MIC field (4 octes) */
706 #define ACI_EAD_PAYLOAD_OVERHEAD_SIZE      (9U)
707 
aci_gap_encrypt_adv_data_nwk(uint8_t session_key[16],uint8_t iv[8],uint8_t adv_payload_data_clear_len,uint8_t adv_payload_data_clear[],uint8_t * adv_payload_data_encrypted_len,uint8_t adv_payload_data_encrypted[])708 tBleStatus aci_gap_encrypt_adv_data_nwk(uint8_t session_key[16],
709                                         uint8_t iv[8],
710                                         uint8_t adv_payload_data_clear_len,
711                                         uint8_t adv_payload_data_clear[],
712                                         uint8_t *adv_payload_data_encrypted_len,
713                                         uint8_t adv_payload_data_encrypted[])
714 {
715     uint8_t Status;
716 
717     /* Check that length of adv_payload_data_clear (declared in adv_payload_data_clear_len)
718     * does not exceed 241 octets, that is an upper bound deriving from the maximum allowed length
719     * of adv_payload_data_encrypted that will be returned into the HCI_Command_Complete event -
720     * that has an overhead of 3+2 octets - thus with a remaining net data payload of 255 - (3+2) = 250 octets;
721     * hence, considering that adv_payload_data_encrypted will carry also 2 extra fields
722     * accounting for total 5+4=9 octets, then the maximum allowed length for adv_payload_data_clear is
723     * 255 - (3+2) - (5+4) = 241 octets.
724     */
725     if ((adv_payload_data_clear_len == 0) ||
726         (adv_payload_data_clear_len > ACI_EAD_PAYLOAD_CLEAR_DATA_LEN_MAX))
727     {
728         return BLE_ERROR_INVALID_HCI_CMD_PARAMS;
729     }
730 
731     uint32_t clear_data_aligned[((ACI_EAD_PAYLOAD_CLEAR_DATA_LEN_MAX - 1) / sizeof(uint32_t))+1] = { 0U };
732     char_copy((uint8_t *)adv_payload_data_clear, (uint8_t *)clear_data_aligned, adv_payload_data_clear_len);
733 
734     Status = aci_gap_encrypt_adv_data(session_key /* 16 */,
735                                       iv /* 8 */,
736                                       adv_payload_data_clear_len,
737                                       clear_data_aligned,
738                                       adv_payload_data_encrypted);
739 
740     if (Status == BLE_STATUS_SUCCESS)
741     {
742         /* the size of returned field adv_payload_data_encrypted is 9 octets longer
743         * w.r.t. adv_payload_data_clear since it contains 2 more fields:
744         * - the Randomizer (5 octets in front of payload), and
745         * - the MIC (4 octets appended as a footer).
746         */
747         *adv_payload_data_encrypted_len = adv_payload_data_clear_len + 9U;
748     }
749     else
750     {
751         *adv_payload_data_encrypted_len = 0U;
752     }
753 
754     return Status;
755 }
756 
aci_gap_decrypt_adv_data_nwk(uint8_t session_key[16],uint8_t iv[8],uint8_t adv_payload_data_encrypted_len,uint8_t adv_payload_data_encrypted[],uint8_t * adv_payload_data_clear_len,uint8_t adv_payload_data_clear[])757 tBleStatus aci_gap_decrypt_adv_data_nwk(uint8_t session_key[16],
758                                         uint8_t iv[8],
759                                         uint8_t adv_payload_data_encrypted_len,
760                                         uint8_t adv_payload_data_encrypted[],
761                                         uint8_t *adv_payload_data_clear_len,
762                                         uint8_t adv_payload_data_clear[])
763 {
764     uint8_t Status;
765 
766     /* Check that length of adv_payload_data_encrypted (declared in adv_payload_data_encrypted_len)
767      * does not exceed 254 octets, that is an upper bound deriving from the Core Spec v.5.x, Part C, Sec. 11,
768      * where the Length field in the ADV header has a size of 1 octet.
769      */
770     if (adv_payload_data_encrypted_len > ACI_EAD_PAYLOAD_ENCRY_DATA_LEN_MAX)
771     {
772         return BLE_ERROR_INVALID_HCI_CMD_PARAMS;
773     }
774 
775     uint32_t clear_data_aligned[((ACI_EAD_PAYLOAD_ENCRY_DATA_LEN_MAX - ACI_EAD_PAYLOAD_OVERHEAD_SIZE -1) / sizeof(uint32_t))+1] = { 0U };
776 
777     Status = aci_gap_decrypt_adv_data(session_key,
778                                       iv,
779                                       adv_payload_data_encrypted_len,
780                                       adv_payload_data_encrypted,
781                                       clear_data_aligned);
782 
783     if (Status == BLE_STATUS_SUCCESS)
784     {
785         /* returned adv_payload_data_clear is 9 octets shorter w.r.t. adv_payload_data_encrypted
786         * since it doesn't contain the 2 extra fields attached to encryped data, i.e.:
787         * - the Randomizer (5 octets in front of payload), and
788         * - the MIC (4 octets appended as a footer).
789         */
790         *adv_payload_data_clear_len = adv_payload_data_encrypted_len - ACI_EAD_PAYLOAD_OVERHEAD_SIZE;
791         char_copy((uint8_t *)clear_data_aligned, (uint8_t *)adv_payload_data_clear, (*adv_payload_data_clear_len));
792     }
793     else
794     {
795         *adv_payload_data_clear_len = 0U;
796     }
797 
798     return Status;
799 }
800 
801 #endif
802 
803 /******************* (C) COPYRIGHT 2020 STMicroelectronics *****END OF FILE****/
804