2424#include "lll.h"
2525#include "lll_clock.h"
2626#include "lll/lll_vendor.h"
27+ #include "lll_chan.h"
2728#include "lll/lll_adv_types.h"
2829#include "lll_adv.h"
2930#include "lll/lll_adv_pdu.h"
3334#include "ull_adv_types.h"
3435
3536#include "ull_internal.h"
37+ #include "ull_chan_internal.h"
3638#include "ull_adv_internal.h"
3739
3840#include "ll.h"
@@ -449,6 +451,43 @@ uint8_t const *ull_adv_aux_random_addr_get(struct ll_adv_set const *const adv,
449451 return adv -> rnd_addr ;
450452}
451453
454+ uint8_t ull_adv_aux_chm_update (void )
455+ {
456+ /* For each created extended advertising set */
457+ for (uint8_t handle = 0 ; handle < BT_CTLR_ADV_SET ; ++ handle ) {
458+ struct ll_adv_aux_set * aux ;
459+ struct ll_adv_set * adv ;
460+ uint8_t chm_last ;
461+
462+ adv = ull_adv_is_created_get (handle );
463+ if (!adv || !adv -> lll .aux ) {
464+ continue ;
465+ }
466+
467+ aux = HDR_LLL2ULL (adv -> lll .aux );
468+ if (aux -> chm_last != aux -> chm_first ) {
469+ /* TODO: Handle previous Channel Map Update being in
470+ * progress
471+ */
472+ continue ;
473+ }
474+
475+ /* Append the channelMapNew that will be picked up by ULL */
476+ chm_last = aux -> chm_last + 1 ;
477+ if (chm_last == DOUBLE_BUFFER_SIZE ) {
478+ chm_last = 0U ;
479+ }
480+ aux -> chm [chm_last ].data_chan_count =
481+ ull_chan_map_get (aux -> chm [chm_last ].data_chan_map );
482+ aux -> chm_last = chm_last ;
483+ }
484+
485+ /* TODO: Should failure due to Channel Map Update being already in
486+ * progress be returned to caller?
487+ */
488+ return 0 ;
489+ }
490+
452491uint8_t ull_adv_aux_hdr_set_clear (struct ll_adv_set * adv ,
453492 uint16_t sec_hdr_add_fields ,
454493 uint16_t sec_hdr_rem_fields ,
@@ -903,17 +942,18 @@ void ull_adv_aux_ptr_fill(uint8_t **dptr, uint8_t phy_s)
903942{
904943 struct pdu_adv_aux_ptr * aux_ptr ;
905944
945+ /* NOTE: Channel Index and Aux Offset will be set on every advertiser's
946+ * event prepare when finding the auxiliary event's ticker offset.
947+ */
948+
906949 * dptr -= sizeof (struct pdu_adv_aux_ptr );
907950 aux_ptr = (void * )* dptr ;
908951
909- /* FIXME: implementation defined */
910952 aux_ptr -> chan_idx = 0U ;
911953
912954 aux_ptr -> ca = (lll_clock_ppm_local_get () <= SCA_50_PPM ) ?
913955 SCA_VALUE_50_PPM : SCA_VALUE_500_PPM ;
914956
915- /* NOTE: Aux Offset will be set in advertiser LLL event
916- */
917957 aux_ptr -> offs_units = 0U ;
918958 aux_ptr -> offs = 0U ;
919959
@@ -1015,6 +1055,7 @@ struct ll_adv_aux_set *ull_adv_aux_acquire(struct lll_adv *lll)
10151055{
10161056 struct lll_adv_aux * lll_aux ;
10171057 struct ll_adv_aux_set * aux ;
1058+ uint8_t chm_last ;
10181059 int err ;
10191060
10201061 aux = aux_acquire ();
@@ -1032,6 +1073,18 @@ struct ll_adv_aux_set *ull_adv_aux_acquire(struct lll_adv *lll)
10321073 return NULL ;
10331074 }
10341075
1076+ /* Initialize data channel calculation counter, data channel identifier,
1077+ * and channel map to use.
1078+ */
1079+ lll_csrand_get (& lll_aux -> data_chan_counter ,
1080+ sizeof (lll_aux -> data_chan_counter ));
1081+ lll_csrand_get (& aux -> data_chan_id , sizeof (aux -> data_chan_id ));
1082+ chm_last = aux -> chm_first ;
1083+ aux -> chm_last = chm_last ;
1084+ aux -> chm [chm_last ].data_chan_count =
1085+ ull_chan_map_get (aux -> chm [chm_last ].data_chan_map );
1086+
1087+
10351088 /* NOTE: ull_hdr_init(&aux->ull); is done on start */
10361089 lll_hdr_init (lll_aux , aux );
10371090
@@ -1063,12 +1116,12 @@ void ull_adv_aux_offset_get(struct ll_adv_set *adv)
10631116 LL_ASSERT (!ret );
10641117}
10651118
1066- struct pdu_adv_aux_ptr * ull_adv_aux_lll_offset_fill (uint32_t ticks_offset ,
1067- uint32_t start_us ,
1068- struct pdu_adv * pdu )
1119+ struct pdu_adv_aux_ptr * ull_adv_aux_lll_offset_fill (struct pdu_adv * pdu ,
1120+ uint32_t ticks_offset ,
1121+ uint32_t start_us )
10691122{
10701123 struct pdu_adv_com_ext_adv * pri_com_hdr ;
1071- struct pdu_adv_aux_ptr * aux ;
1124+ struct pdu_adv_aux_ptr * aux_ptr ;
10721125 struct pdu_adv_ext_hdr * h ;
10731126 uint32_t offs ;
10741127 uint8_t * ptr ;
@@ -1085,18 +1138,18 @@ struct pdu_adv_aux_ptr *ull_adv_aux_lll_offset_fill(uint32_t ticks_offset,
10851138 ptr += sizeof (struct pdu_adv_adi );
10861139 }
10871140
1088- aux = (void * )ptr ;
1141+ aux_ptr = (void * )ptr ;
10891142 offs = HAL_TICKER_TICKS_TO_US (ticks_offset ) - start_us ;
10901143 offs = offs / OFFS_UNIT_30_US ;
10911144 if (!!(offs >> 13 )) {
1092- aux -> offs = offs / (OFFS_UNIT_300_US / OFFS_UNIT_30_US );
1093- aux -> offs_units = 1U ;
1145+ aux_ptr -> offs = offs / (OFFS_UNIT_300_US / OFFS_UNIT_30_US );
1146+ aux_ptr -> offs_units = 1U ;
10941147 } else {
1095- aux -> offs = offs ;
1096- aux -> offs_units = 0U ;
1148+ aux_ptr -> offs = offs ;
1149+ aux_ptr -> offs_units = 0U ;
10971150 }
10981151
1099- return aux ;
1152+ return aux_ptr ;
11001153}
11011154
11021155void ull_adv_aux_done (struct node_rx_event_done * done )
@@ -1211,16 +1264,22 @@ static uint8_t aux_time_update(struct ll_adv_aux_set *aux, struct pdu_adv *pdu,
12111264
12121265static void mfy_aux_offset_get (void * param )
12131266{
1214- struct ll_adv_set * adv = param ;
1267+ struct pdu_adv_aux_ptr * aux_ptr ;
1268+ struct lll_adv_aux * lll_aux ;
12151269 struct ll_adv_aux_set * aux ;
12161270 uint32_t ticks_to_expire ;
1271+ uint8_t data_chan_count ;
1272+ uint8_t * data_chan_map ;
12171273 uint32_t ticks_current ;
1274+ struct ll_adv_set * adv ;
12181275 struct pdu_adv * pdu ;
12191276 uint8_t ticker_id ;
12201277 uint8_t retry ;
12211278 uint8_t id ;
12221279
1223- aux = HDR_LLL2ULL (adv -> lll .aux );
1280+ adv = param ;
1281+ lll_aux = adv -> lll .aux ;
1282+ aux = HDR_LLL2ULL (lll_aux );
12241283 ticker_id = TICKER_ID_ADV_AUX_BASE + ull_adv_aux_handle_get (aux );
12251284
12261285 id = TICKER_NULL ;
@@ -1259,19 +1318,32 @@ static void mfy_aux_offset_get(void *param)
12591318 /* Store the ticks offset for population in other advertising primary
12601319 * channel PDUs.
12611320 */
1262- aux -> lll . ticks_offset = ticks_to_expire ;
1321+ lll_aux -> ticks_offset = ticks_to_expire ;
12631322
12641323 /* NOTE: as remainder used in scheduling primary PDU not available,
12651324 * compensate with a probable jitter of one ticker resolution unit that
12661325 * would be included in the packet timer capture when scheduling next
12671326 * advertising primary channel PDU.
12681327 */
1269- aux -> lll . ticks_offset +=
1328+ lll_aux -> ticks_offset +=
12701329 HAL_TICKER_US_TO_TICKS (EVENT_TICKER_RES_MARGIN_US );
12711330
1272- /* FIXME: we are in ULL_LOW context, fill offset in LLL context */
1273- pdu = lll_adv_data_curr_get (& adv -> lll );
1274- ull_adv_aux_lll_offset_fill (ticks_to_expire , 0 , pdu );
1331+ /* FIXME: we are in ULL_LOW context, fill offset in LLL context? */
1332+ pdu = lll_adv_data_latest_peek (& adv -> lll );
1333+ aux_ptr = ull_adv_aux_lll_offset_fill (pdu , ticks_to_expire , 0 );
1334+
1335+ /* Process channel map update, if any */
1336+ if (aux -> chm_first != aux -> chm_last ) {
1337+ /* Use channelMapNew */
1338+ aux -> chm_first = aux -> chm_last ;
1339+ }
1340+
1341+ /* Calculate the radio channel to use */
1342+ data_chan_map = aux -> chm [aux -> chm_first ].data_chan_map ;
1343+ data_chan_count = aux -> chm [aux -> chm_first ].data_chan_count ;
1344+ aux_ptr -> chan_idx = lll_chan_sel_2 (lll_aux -> data_chan_counter ,
1345+ aux -> data_chan_id ,
1346+ data_chan_map , data_chan_count );
12751347}
12761348
12771349static void ticker_cb (uint32_t ticks_at_expire , uint32_t ticks_drift ,
0 commit comments