Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
mac_data_poll.c
00001 /* 00002 * Copyright (c) 2014-2018, Arm Limited and affiliates. 00003 * SPDX-License-Identifier: Apache-2.0 00004 * 00005 * Licensed under the Apache License, Version 2.0 (the "License"); 00006 * you may not use this file except in compliance with the License. 00007 * You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 00018 /* 00019 * \file mac_data_poll.c 00020 * \brief Add short description about this file!!! 00021 * 00022 */ 00023 00024 #include "nsconfig.h" 00025 #include "ns_types.h" 00026 #include "eventOS_event.h" 00027 #include "eventOS_scheduler.h" 00028 #include "eventOS_callback_timer.h" 00029 #include "string.h" 00030 #include "ns_trace.h" 00031 #include "nsdynmemLIB.h" 00032 #include "mac_api.h" 00033 #include "mlme.h" 00034 00035 #include "NWK_INTERFACE/Include/protocol_stats.h" 00036 #include "NWK_INTERFACE/Include/protocol.h" 00037 #include "platform/arm_hal_interrupt.h" 00038 #include "common_functions.h" 00039 #include "6LoWPAN/Bootstraps/protocol_6lowpan.h" 00040 #include "6LoWPAN/Bootstraps/network_lib.h" 00041 #include "6LoWPAN/Thread/thread_common.h" 00042 #include "6LoWPAN/Thread/thread_bootstrap.h" 00043 #ifndef NO_MLE 00044 #include "MLE/mle.h" 00045 #endif 00046 #include "6LoWPAN/MAC/mac_helper.h" 00047 #include "6LoWPAN/MAC/mac_data_poll.h" 00048 #include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h" 00049 00050 #define TRACE_GROUP "mPol" 00051 00052 #define MAC_DATA_POLL_DEFAULT_RATE 20 00053 00054 #define MAC_DATA_POLL_REQUEST_EVENT 1 00055 00056 static int8_t mac_data_poll_tasklet = -1; 00057 00058 static void mac_data_poll_cb_run(int8_t interface_id); 00059 00060 00061 static void mac_data_poll_cb(arm_event_s *event) 00062 { 00063 uint8_t event_type = event->event_type; 00064 00065 switch (event_type) { 00066 case MAC_DATA_POLL_REQUEST_EVENT: 00067 mac_data_poll_cb_run((int8_t)event->event_id); 00068 break; 00069 00070 default: 00071 00072 break; 00073 } 00074 } 00075 00076 static int8_t mac_data_poll_tasklet_init(void) 00077 { 00078 if (mac_data_poll_tasklet < 0) { 00079 mac_data_poll_tasklet = eventOS_event_handler_create(&mac_data_poll_cb, 0); 00080 } 00081 00082 return mac_data_poll_tasklet; 00083 } 00084 00085 static int8_t host_link_configuration(bool rx_on_idle, protocol_interface_info_entry_t *cur) 00086 { 00087 bool backUp_bool = cur->mac_parameters->RxOnWhenIdle; 00088 if (rx_on_idle) { 00089 cur->lowpan_info &= ~INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE; 00090 } else { 00091 tr_debug("Enable Poll state by host Link"); 00092 cur->lowpan_info |= INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE; 00093 } 00094 mac_helper_pib_boolean_set(cur, macRxOnWhenIdle, rx_on_idle); 00095 00096 if (thread_info(cur)) { 00097 if (rx_on_idle != backUp_bool) { 00098 //If mode have been changed, send child update 00099 thread_bootstrap_child_update_trig(cur); 00100 } 00101 return 0; 00102 } else { 00103 if (protocol_6lowpan_child_update(cur) == 0) { 00104 mac_data_poll_init_protocol_poll(cur); 00105 return 0; 00106 } 00107 } 00108 00109 //Swap back If Send Fail 00110 if (!backUp_bool) { 00111 cur->lowpan_info |= INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE; 00112 } else { 00113 cur->lowpan_info &= ~INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE; 00114 } 00115 mac_helper_pib_boolean_set(cur, macRxOnWhenIdle, backUp_bool); 00116 return -1; 00117 } 00118 00119 static void mac_data_poll_protocol_internal(protocol_interface_info_entry_t *cur) 00120 { 00121 if (cur->rfd_poll_info->protocol_poll == 0) { 00122 if (cur->rfd_poll_info->host_mode == NET_HOST_SLOW_POLL_MODE) { 00123 if (!cur->rfd_poll_info->pollActive) { 00124 mac_poll_timer_trig(1, cur); 00125 } 00126 } 00127 } 00128 cur->rfd_poll_info->protocol_poll++; 00129 tr_debug("Protocol Poll: %02x", cur->rfd_poll_info->protocol_poll); 00130 } 00131 00132 static void mac_data_poll_protocol_poll_internal_cancel(struct protocol_interface_info_entry *cur) 00133 { 00134 nwk_rfd_poll_setups_s *rf_ptr = cur->rfd_poll_info; 00135 00136 if (rf_ptr->protocol_poll == 0) { 00137 return; 00138 } 00139 00140 if (--rf_ptr->protocol_poll == 0) { 00141 tr_debug("Disable Protocol Poll"); 00142 if (!rf_ptr->pollActive) { 00143 if (rf_ptr->nwk_app_poll_time) { 00144 mac_poll_timer_trig(1, cur); 00145 } else { 00146 eventOS_event_timer_cancel(cur->id, mac_data_poll_tasklet); 00147 tr_debug("Stop Poll"); 00148 } 00149 } 00150 } 00151 } 00152 00153 void mac_data_poll_init_protocol_poll(protocol_interface_info_entry_t *cur) 00154 { 00155 if (!cur || !cur->rfd_poll_info || !(cur->lowpan_info & INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE)) { 00156 return; 00157 } 00158 00159 mac_data_poll_protocol_internal(cur); 00160 00161 } 00162 00163 uint32_t mac_data_poll_host_poll_time_max(protocol_interface_info_entry_t *cur) 00164 { 00165 if (!cur || !cur->rfd_poll_info) { 00166 return 0; 00167 } 00168 00169 return cur->rfd_poll_info->slow_poll_rate_seconds; 00170 } 00171 00172 uint32_t mac_data_poll_host_timeout(protocol_interface_info_entry_t *cur) 00173 { 00174 if (!cur || !cur->rfd_poll_info) { 00175 return 0; 00176 } 00177 00178 return cur->rfd_poll_info->timeOutInSeconds; 00179 } 00180 00181 uint32_t mac_data_poll_get_max_sleep_period(protocol_interface_info_entry_t *cur) 00182 { 00183 if (cur && cur->if_stack_buffer_handler && (cur->rfd_poll_info && !cur->rfd_poll_info->pollActive)) { // Verify That TX is not active 00184 if (cur->rfd_poll_info->protocol_poll) { 00185 return 300; 00186 } else { 00187 return cur->rfd_poll_info->nwk_app_poll_time; 00188 } 00189 } 00190 return 0; 00191 } 00192 00193 void mac_data_poll_protocol_poll_mode_decrement(struct protocol_interface_info_entry *cur) 00194 { 00195 if (!cur || !cur->rfd_poll_info) { 00196 return; 00197 } 00198 00199 if (!(cur->lowpan_info & INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE)) { 00200 return; 00201 } 00202 00203 mac_data_poll_protocol_poll_internal_cancel(cur); 00204 } 00205 00206 void mac_data_poll_protocol_poll_mode_disable(struct protocol_interface_info_entry *cur) 00207 { 00208 if (!cur || !cur->rfd_poll_info) { 00209 return; 00210 } 00211 00212 if (!(cur->lowpan_info & INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE)) { 00213 return; 00214 } 00215 00216 mac_data_poll_protocol_poll_internal_cancel(cur); 00217 } 00218 00219 void mac_data_poll_disable(struct protocol_interface_info_entry *cur) 00220 { 00221 if (!cur || !cur->rfd_poll_info) { 00222 return; 00223 } 00224 00225 eventOS_event_timer_cancel(cur->id, mac_data_poll_tasklet); 00226 cur->rfd_poll_info->protocol_poll = 0; 00227 cur->rfd_poll_info->pollActive = false; 00228 } 00229 00230 void mac_data_poll_enable_check(protocol_interface_info_entry_t *cur) 00231 { 00232 if (!cur || !cur->rfd_poll_info) { 00233 return; 00234 } 00235 00236 if (!(cur->lowpan_info & INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE)) { 00237 return; 00238 } 00239 00240 mac_data_poll_protocol_internal(cur); 00241 } 00242 00243 int8_t mac_data_poll_host_mode_get(struct protocol_interface_info_entry *cur, net_host_mode_t *mode) 00244 { 00245 if (!cur || !cur->rfd_poll_info) { 00246 return -1; 00247 } 00248 00249 *mode = cur->rfd_poll_info->host_mode; 00250 return 0; 00251 } 00252 00253 void mac_poll_timer_trig(uint32_t poll_time, protocol_interface_info_entry_t *cur) 00254 { 00255 if (!cur) { 00256 return; 00257 } 00258 eventOS_event_timer_cancel(cur->id, mac_data_poll_tasklet); 00259 00260 if (poll_time) { 00261 if (cur->lowpan_info & INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE) { 00262 00263 if (poll_time < 20) { 00264 arm_event_s event = { 00265 .receiver = mac_data_poll_tasklet, 00266 .sender = mac_data_poll_tasklet, 00267 .event_id = cur->id, 00268 .data_ptr = NULL, 00269 .event_type = MAC_DATA_POLL_REQUEST_EVENT, 00270 .priority = ARM_LIB_MED_PRIORITY_EVENT, 00271 }; 00272 00273 if (eventOS_event_send(&event) != 0) { 00274 tr_error("eventOS_event_send() failed"); 00275 } 00276 } else { 00277 if (eventOS_event_timer_request(cur->id, MAC_DATA_POLL_REQUEST_EVENT, mac_data_poll_tasklet, poll_time) != 0) { 00278 tr_error("Poll Timer start Fail"); 00279 } 00280 } 00281 00282 } 00283 } 00284 } 00285 static mac_neighbor_table_entry_t *neighbor_data_poll_referesh(protocol_interface_info_entry_t *cur, uint8_t *address, addrtype_t type) 00286 { 00287 mac_neighbor_table_entry_t *entry = mac_neighbor_table_address_discover(mac_neighbor_info(cur), address, type); 00288 00289 if (!entry) { 00290 return NULL; 00291 } 00292 00293 if (!entry->connected_device ) { 00294 return NULL; 00295 } 00296 00297 if (!entry->nud_active ) { 00298 entry->lifetime = entry->link_lifetime ; 00299 } 00300 return entry; 00301 } 00302 00303 void mac_mlme_poll_confirm(protocol_interface_info_entry_t *cur, const mlme_poll_conf_t *confirm) 00304 { 00305 if (!cur || !confirm) { 00306 return; 00307 } 00308 00309 uint32_t poll_time = 1; 00310 nwk_rfd_poll_setups_s *rf_ptr = cur->rfd_poll_info; 00311 if (!rf_ptr) { 00312 return; 00313 } 00314 00315 rf_ptr->pollActive = false; 00316 mac_neighbor_table_entry_t *entry = NULL; 00317 00318 switch (confirm->status) { 00319 case MLME_SUCCESS: 00320 //tr_debug("Poll Confirm: Data with Data"); 00321 rf_ptr->nwk_parent_poll_fail = 0; 00322 //Trig new Data Poll immediately 00323 entry = neighbor_data_poll_referesh(cur, rf_ptr->poll_req.CoordAddress, (addrtype_t)rf_ptr->poll_req.CoordAddrMode); 00324 poll_time = 1; 00325 break; 00326 00327 case MLME_NO_DATA: 00328 //Start next case timer 00329 rf_ptr->nwk_parent_poll_fail = 0; 00330 entry = neighbor_data_poll_referesh(cur, rf_ptr->poll_req.CoordAddress, (addrtype_t)rf_ptr->poll_req.CoordAddrMode); 00331 //tr_debug("Poll Confirm: No Data"); 00332 00333 if (rf_ptr->protocol_poll == 0) { 00334 poll_time = rf_ptr->nwk_app_poll_time; 00335 } else { 00336 poll_time = 300; 00337 } 00338 00339 break; 00340 default: 00341 tr_debug("Poll Confirm: fail %x", confirm->status); 00342 rf_ptr->nwk_parent_poll_fail++; 00343 if (rf_ptr->nwk_parent_poll_fail > 3) { 00344 //tr_debug("Parent Poll Fail"); 00345 poll_time = 0; 00346 rf_ptr->nwk_parent_poll_fail = 0; 00347 if (rf_ptr->pollFailCb) { 00348 rf_ptr->pollFailCb(cur->id); 00349 } 00350 } else { 00351 poll_time = 2000; 00352 } 00353 break; 00354 } 00355 if (thread_info(cur) && entry) { 00356 thread_neighbor_communication_update(cur, entry->index ); 00357 } 00358 00359 mac_poll_timer_trig(poll_time, cur); 00360 00361 00362 } 00363 00364 00365 static void mac_data_poll_cb_run(int8_t interface_id) 00366 { 00367 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); 00368 if (!cur) { 00369 return; 00370 } 00371 nwk_rfd_poll_setups_s *rf_ptr = cur->rfd_poll_info; 00372 00373 if (!rf_ptr) { 00374 return; 00375 } 00376 00377 rf_ptr->poll_req.CoordAddrMode = (unsigned)mac_helper_coordinator_address_get(cur, rf_ptr->poll_req.CoordAddress); 00378 00379 if (rf_ptr->poll_req.CoordAddrMode == MAC_ADDR_MODE_NONE) { 00380 return; 00381 } 00382 00383 memset(&rf_ptr->poll_req.Key, 0, sizeof(mlme_security_t)); 00384 rf_ptr->poll_req.CoordPANId = mac_helper_panid_get(cur); 00385 00386 rf_ptr->poll_req.Key.SecurityLevel = mac_helper_default_security_level_get(cur); 00387 if (rf_ptr->poll_req.Key.SecurityLevel) { 00388 00389 rf_ptr->poll_req.Key.KeyIndex = mac_helper_default_key_index_get(cur); 00390 rf_ptr->poll_req.Key.KeyIdMode = mac_helper_default_security_key_id_mode_get(cur); 00391 } 00392 00393 if (cur->mac_api && cur->mac_api->mlme_req) { 00394 rf_ptr->pollActive = true; 00395 cur->mac_api->mlme_req(cur->mac_api, MLME_POLL, (void *) &rf_ptr->poll_req); 00396 } else { 00397 tr_error("MAC not registered to interface"); 00398 } 00399 } 00400 00401 int8_t mac_data_poll_host_mode_set(struct protocol_interface_info_entry *cur, net_host_mode_t mode, uint32_t poll_time) 00402 { 00403 #ifndef NO_MLE 00404 if (!cur) { 00405 return -1; 00406 } 00407 int8_t ret_val = 0; 00408 nwk_rfd_poll_setups_s *rf_ptr = cur->rfd_poll_info; 00409 //Check IF Bootsrap Ready and type is Host 00410 if (!rf_ptr) { 00411 return -1; 00412 } 00413 00414 if (cur->lowpan_info & INTERFACE_NWK_ROUTER_DEVICE) { 00415 return -3; 00416 } 00417 00418 00419 switch (mode) { 00420 case NET_HOST_SLOW_POLL_MODE: 00421 //slow mode 00422 //Check Host current sleep state 00423 if (rf_ptr->host_mode == NET_HOST_FAST_POLL_MODE || rf_ptr->host_mode == NET_HOST_SLOW_POLL_MODE || rf_ptr->host_mode == NET_HOST_RX_ON_IDLE) { 00424 uint32_t new_poll_time; 00425 uint32_t new_Timeout; 00426 00427 if (poll_time == 0 || poll_time > 864001) { 00428 return -2; 00429 } 00430 00431 //Calculate 00432 //Timeout from Poll Time 00433 new_Timeout = poll_time * 4; 00434 00435 if (new_Timeout < 32) { //Keep Timeout always to 32 seconds min 00436 new_Timeout = 32; 00437 } 00438 00439 if (new_Timeout != rf_ptr->timeOutInSeconds) { 00440 rf_ptr->timeOutInSeconds = new_Timeout; 00441 } 00442 00443 rf_ptr->slow_poll_rate_seconds = poll_time; 00444 00445 new_poll_time = (poll_time * 1000); 00446 if (rf_ptr->host_mode == NET_HOST_RX_ON_IDLE) { 00447 tr_debug("Init Poll timer and period"); 00448 } 00449 00450 rf_ptr->nwk_app_poll_time = new_poll_time; 00451 tr_debug("Enable Poll state slow poll"); 00452 if (host_link_configuration(false, cur) != 0) { 00453 return -3; 00454 } 00455 mac_poll_timer_trig(1, cur); 00456 rf_ptr->host_mode = NET_HOST_SLOW_POLL_MODE; 00457 } 00458 break; 00459 case NET_HOST_FAST_POLL_MODE: 00460 //fast mode 00461 //Check Host current sleep state 00462 if (rf_ptr->host_mode == NET_HOST_FAST_POLL_MODE || rf_ptr->host_mode == NET_HOST_SLOW_POLL_MODE || rf_ptr->host_mode == NET_HOST_RX_ON_IDLE) { 00463 if (rf_ptr->host_mode != NET_HOST_FAST_POLL_MODE) { 00464 tr_debug("Enable Fast poll mode"); 00465 if (rf_ptr->host_mode == NET_HOST_RX_ON_IDLE) { 00466 tr_debug("Init Poll timer and period"); 00467 if (host_link_configuration(false, cur) != 0) { 00468 return -3; 00469 } 00470 } 00471 } 00472 tr_debug("Enable Poll By APP"); 00473 mac_helper_pib_boolean_set(cur, macRxOnWhenIdle, false); 00474 mac_poll_timer_trig(1, cur); 00475 rf_ptr->nwk_app_poll_time = 300; 00476 rf_ptr->host_mode = NET_HOST_FAST_POLL_MODE; 00477 00478 } 00479 break; 00480 00481 case NET_HOST_RX_ON_IDLE: 00482 // Non-sleep mode 00483 if (rf_ptr->host_mode == NET_HOST_FAST_POLL_MODE || rf_ptr->host_mode == NET_HOST_SLOW_POLL_MODE) { 00484 if (host_link_configuration(true, cur) == 0) { 00485 rf_ptr->host_mode = NET_HOST_RX_ON_IDLE; 00486 rf_ptr->nwk_app_poll_time = 0; 00487 } else { 00488 ret_val = -3; 00489 } 00490 } 00491 break; 00492 00493 default: 00494 ret_val = -1; 00495 break; 00496 } 00497 00498 return ret_val; 00499 #else /* MLE_DRAFT */ 00500 return -1; 00501 #endif /* MLE_DRAFT */ 00502 } 00503 00504 void mac_data_poll_init(struct protocol_interface_info_entry *cur) 00505 { 00506 if (!cur) { 00507 return; 00508 } 00509 00510 if (cur->lowpan_info & INTERFACE_NWK_ROUTER_DEVICE) { 00511 if (cur->rfd_poll_info) { 00512 ns_dyn_mem_free(cur->rfd_poll_info); 00513 cur->rfd_poll_info = NULL; 00514 } 00515 mac_helper_pib_boolean_set(cur, macRxOnWhenIdle, true); 00516 return; 00517 } 00518 00519 //Allocate and Init 00520 nwk_rfd_poll_setups_s *rfd_ptr = cur->rfd_poll_info; 00521 00522 if (!rfd_ptr) { 00523 if (mac_data_poll_tasklet_init() < 0) { 00524 tr_error("Mac data poll tasklet init fail"); 00525 } else { 00526 rfd_ptr = ns_dyn_mem_alloc(sizeof(nwk_rfd_poll_setups_s)); 00527 if (rfd_ptr) { 00528 rfd_ptr->timeOutInSeconds = 0; 00529 rfd_ptr->nwk_parent_poll_fail = false; 00530 rfd_ptr->protocol_poll = 0; 00531 rfd_ptr->slow_poll_rate_seconds = 0; 00532 rfd_ptr->pollActive = false; 00533 cur->rfd_poll_info = rfd_ptr; 00534 } 00535 } 00536 } 00537 00538 if (!rfd_ptr) { 00539 return; 00540 } 00541 00542 //Set MAc Data poll Fail Callback 00543 rfd_ptr->pollFailCb = nwk_parent_poll_fail_cb; 00544 00545 if (cur->mac_parameters->RxOnWhenIdle) { 00546 tr_debug("Set Non-Sleepy HOST"); 00547 rfd_ptr->host_mode = NET_HOST_RX_ON_IDLE; 00548 } else { 00549 00550 rfd_ptr->protocol_poll = 1; 00551 mac_poll_timer_trig(200, cur); 00552 tr_debug("Set Sleepy HOST configure"); 00553 rfd_ptr->host_mode = NET_HOST_FAST_POLL_MODE; 00554 rfd_ptr->slow_poll_rate_seconds = 3; 00555 rfd_ptr->timeOutInSeconds = 32; 00556 rfd_ptr->nwk_app_poll_time = 300; 00557 rfd_ptr->nwk_parent_poll_fail = 0; 00558 } 00559 }
Generated on Tue Jul 12 2022 13:54:31 by
