|
38 | 38 | #define IE_HEADER_ID_MASK 0x7f80
|
39 | 39 | #define WH_IE_ID 0x2a
|
40 | 40 | #define WH_SUB_ID_UTT 1
|
| 41 | +#define WH_SUB_ID_BT 2 |
41 | 42 |
|
42 | 43 | struct ws_ie_t {
|
43 | 44 | uint8_t *content_ptr;
|
@@ -106,10 +107,13 @@ static void fhss_broadcast_handler(const fhss_api_t *fhss_api, uint16_t delay)
|
106 | 107 | if (!fhss_structure) {
|
107 | 108 | return;
|
108 | 109 | }
|
| 110 | + // TODO: check parent broadcast timing constantly and calculate drift error |
109 | 111 | if (fhss_structure->ws->is_on_bc_channel == false) {
|
110 | 112 | fhss_start_timer(fhss_structure, fhss_structure->ws->fhss_configuration.fhss_bc_dwell_interval*1000, fhss_broadcast_handler);
|
111 | 113 | fhss_structure->ws->is_on_bc_channel = true;
|
112 | 114 | next_channel = fhss_ws_calc_bc_channel(fhss_structure);
|
| 115 | + // TODO: Randomize polling TX queue when on broadcast channel |
| 116 | + fhss_structure->callbacks.tx_poll(fhss_structure->fhss_api); |
113 | 117 | } else {
|
114 | 118 | uint32_t timeout = (fhss_structure->ws->fhss_configuration.fhss_broadcast_interval - fhss_structure->ws->fhss_configuration.fhss_bc_dwell_interval) * 1000;
|
115 | 119 | fhss_start_timer(fhss_structure, timeout, fhss_broadcast_handler);
|
@@ -156,6 +160,19 @@ static uint32_t fhss_ws_calculate_ufsi(fhss_structure_t *fhss_structure, uint32_
|
156 | 160 | return own_floor((float)(ms_since_seq_start * DEF_2E24) / (seq_length*dwell_time));
|
157 | 161 | }
|
158 | 162 |
|
| 163 | +static uint32_t fhss_ws_calculate_broadcast_interval_offset(fhss_structure_t *fhss_structure, uint32_t tx_time) |
| 164 | +{ |
| 165 | + uint8_t dwell_time = fhss_structure->ws->fhss_configuration.fhss_bc_dwell_interval; |
| 166 | + uint32_t broadcast_interval = fhss_structure->ws->fhss_configuration.fhss_broadcast_interval; |
| 167 | + |
| 168 | + uint32_t remaining_time = (fhss_structure->platform_functions.fhss_get_remaining_slots(fhss_broadcast_handler, fhss_structure->fhss_api) / 1000); |
| 169 | + if (fhss_structure->ws->is_on_bc_channel == true) { |
| 170 | + remaining_time += (broadcast_interval - dwell_time); |
| 171 | + } |
| 172 | + uint32_t time_to_tx = (tx_time - fhss_structure->fhss_api->read_timestamp(fhss_structure->fhss_api)) / 1000; |
| 173 | + return (broadcast_interval-remaining_time) + time_to_tx; |
| 174 | +} |
| 175 | + |
159 | 176 | static uint16_t fhss_ws_calculate_destination_slot(fhss_ws_neighbor_timing_info_t *neighbor_timing_info, uint32_t tx_time)
|
160 | 177 | {
|
161 | 178 | uint_fast24_t ufsi = neighbor_timing_info->uc_timing_info.ufsi;
|
@@ -238,7 +255,7 @@ static int fhss_ws_tx_handle_callback(const fhss_api_t *api, bool is_broadcast_a
|
238 | 255 | if (!fhss_structure) {
|
239 | 256 | return -1;
|
240 | 257 | }
|
241 |
| - if (is_broadcast_addr) { |
| 258 | + if (is_broadcast_addr || (fhss_structure->ws->is_on_bc_channel == true)) { |
242 | 259 | return 0;
|
243 | 260 | }
|
244 | 261 | if (fhss_structure->fhss_state == FHSS_SYNCHRONIZED) {
|
@@ -274,13 +291,22 @@ static int fhss_ws_tx_handle_callback(const fhss_api_t *api, bool is_broadcast_a
|
274 | 291 |
|
275 | 292 | static bool fhss_ws_check_tx_conditions_callback(const fhss_api_t *api, bool is_broadcast_addr, uint8_t handle, int frame_type, uint16_t frame_length, uint8_t phy_header_length, uint8_t phy_tail_length)
|
276 | 293 | {
|
277 |
| - (void) api; |
278 |
| - (void) is_broadcast_addr; |
279 | 294 | (void) handle;
|
280 | 295 | (void) frame_type;
|
281 | 296 | (void) frame_length;
|
282 | 297 | (void) phy_header_length;
|
283 | 298 | (void) phy_tail_length;
|
| 299 | + fhss_structure_t *fhss_structure = fhss_get_object_with_api(api); |
| 300 | + if (!fhss_structure) { |
| 301 | + return true; |
| 302 | + } |
| 303 | + if (fhss_structure->ws->fhss_configuration.ws_channel_function == WS_FIXED_CHANNEL) { |
| 304 | + return true; |
| 305 | + } |
| 306 | + // Do not allow broadcast destination on unicast channel |
| 307 | + if (is_broadcast_addr && (fhss_structure->ws->is_on_bc_channel == false)) { |
| 308 | + return false; |
| 309 | + } |
284 | 310 | return true;
|
285 | 311 | }
|
286 | 312 |
|
@@ -320,6 +346,11 @@ static int16_t fhss_ws_write_synch_info_callback(const fhss_api_t *api, uint8_t
|
320 | 346 | uint32_t ufsi = fhss_ws_calculate_ufsi(fhss_structure, tx_time);
|
321 | 347 | common_write_24_bit_inverse(ufsi, header_ie.content_ptr+1);
|
322 | 348 | }
|
| 349 | + if (fhss_ws_ie_header_discover(ptr, length, &header_ie, WH_SUB_ID_BT)) { |
| 350 | + uint32_t broadcast_interval_offset = fhss_ws_calculate_broadcast_interval_offset(fhss_structure, tx_time); |
| 351 | + common_write_16_bit_inverse(fhss_structure->ws->bc_slot, header_ie.content_ptr); |
| 352 | + common_write_24_bit_inverse(broadcast_interval_offset, header_ie.content_ptr+2); |
| 353 | + } |
323 | 354 | return 0;
|
324 | 355 | }
|
325 | 356 |
|
@@ -402,6 +433,16 @@ int fhss_ws_set_parent(fhss_structure_t *fhss_structure, const uint8_t eui64[8],
|
402 | 433 | if (!fhss_structure->ws) {
|
403 | 434 | return -1;
|
404 | 435 | }
|
| 436 | + if (fhss_structure->ws->fhss_configuration.ws_channel_function == WS_FIXED_CHANNEL) { |
| 437 | + return 0; |
| 438 | + } |
| 439 | + // Start broadcast schedule when BC intervals are known |
| 440 | + if (bc_timing_info->broadcast_interval && bc_timing_info->broadcast_dwell_interval) { |
| 441 | + fhss_start_timer(fhss_structure, (bc_timing_info->broadcast_interval-bc_timing_info->broadcast_interval_offset)*1000, fhss_broadcast_handler); |
| 442 | + fhss_structure->ws->fhss_configuration.fhss_bc_dwell_interval = bc_timing_info->broadcast_dwell_interval; |
| 443 | + fhss_structure->ws->fhss_configuration.fhss_broadcast_interval = bc_timing_info->broadcast_interval; |
| 444 | + fhss_structure->ws->bc_slot = bc_timing_info->broadcast_slot; |
| 445 | + } |
405 | 446 | //TODO: support multiple parents
|
406 | 447 | fhss_structure->ws->parent_bc_info = bc_timing_info;
|
407 | 448 | return 0;
|
|
0 commit comments