Knight KE / Mbed OS Game_Master
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers mac_data_poll.c Source File

mac_data_poll.c

00001 /*
00002  * Copyright (c) 2014-2017, 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 
00049 #define TRACE_GROUP "mPol"
00050 
00051 #define MAC_DATA_POLL_DEFAULT_RATE 20
00052 
00053 #define MAC_DATA_POLL_REQUEST_EVENT 1
00054 
00055 static int8_t mac_data_poll_tasklet = -1;
00056 
00057 static void mac_data_poll_cb_run(int8_t interface_id);
00058 
00059 
00060 static void mac_data_poll_cb(arm_event_s *event)
00061 {
00062     uint8_t event_type = event->event_type;
00063 
00064     switch (event_type) {
00065         case MAC_DATA_POLL_REQUEST_EVENT:
00066             mac_data_poll_cb_run((int8_t)event->event_id);
00067             break;
00068 
00069         default:
00070 
00071             break;
00072     }
00073 }
00074 
00075 static int8_t mac_data_poll_tasklet_init(void)
00076 {
00077     if (mac_data_poll_tasklet < 0) {
00078         mac_data_poll_tasklet = eventOS_event_handler_create(&mac_data_poll_cb, 0);
00079     }
00080 
00081     return mac_data_poll_tasklet;
00082 }
00083 
00084 static int8_t host_link_configuration(bool rx_on_idle, protocol_interface_info_entry_t *cur)
00085 {
00086     bool backUp_bool = cur->mac_parameters->RxOnWhenIdle;
00087     if (rx_on_idle) {
00088         cur->lowpan_info &= ~INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE;
00089     } else {
00090         tr_debug("Enable Poll state by host Link");
00091         cur->lowpan_info |= INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE;
00092     }
00093     mac_helper_pib_boolean_set(cur, macRxOnWhenIdle, rx_on_idle);
00094 
00095     if (thread_info(cur)) {
00096         if(rx_on_idle != backUp_bool){
00097             //If mode have been changed, send child update
00098             thread_bootstrap_child_update_trig(cur);
00099         }
00100         return 0;
00101     } else {
00102         if (protocol_6lowpan_child_update(cur) == 0) {
00103             mac_data_poll_init_protocol_poll(cur);
00104             return 0;
00105         }
00106     }
00107 
00108     //Swap back If Send Fail
00109     if (!backUp_bool) {
00110         cur->lowpan_info |= INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE;
00111     } else {
00112         cur->lowpan_info &= ~INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE;
00113     }
00114     mac_helper_pib_boolean_set(cur, macRxOnWhenIdle, backUp_bool);
00115     return -1;
00116 }
00117 
00118 static void mac_data_poll_protocol_internal(protocol_interface_info_entry_t *cur)
00119 {
00120     if (cur->rfd_poll_info->protocol_poll == 0) {
00121         if (cur->rfd_poll_info->host_mode == NET_HOST_SLOW_POLL_MODE) {
00122             if (!cur->rfd_poll_info->pollActive) {
00123                 mac_poll_timer_trig(1, cur);
00124             }
00125         }
00126     }
00127     cur->rfd_poll_info->protocol_poll++;
00128     tr_debug("Protocol Poll: %02x", cur->rfd_poll_info->protocol_poll);
00129 }
00130 
00131 static void mac_data_poll_protocol_poll_internal_cancel(struct protocol_interface_info_entry *cur)
00132 {
00133     nwk_rfd_poll_setups_s *rf_ptr = cur->rfd_poll_info;
00134 
00135     if (rf_ptr->protocol_poll == 0) {
00136         return;
00137     }
00138 
00139     if (--rf_ptr->protocol_poll == 0) {
00140         tr_debug("Disable Protocol Poll");
00141         if (!rf_ptr->pollActive) {
00142             if (rf_ptr->nwk_app_poll_time) {
00143                 mac_poll_timer_trig(1, cur);
00144             } else {
00145                 eventOS_event_timer_cancel(cur->id, mac_data_poll_tasklet);
00146                 tr_debug("Stop Poll");
00147             }
00148         }
00149     }
00150 }
00151 
00152 void mac_data_poll_init_protocol_poll(protocol_interface_info_entry_t *cur)
00153 {
00154     if (!cur || !cur->rfd_poll_info || !(cur->lowpan_info & INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE)) {
00155         return;
00156     }
00157 
00158     mac_data_poll_protocol_internal(cur);
00159 
00160 }
00161 
00162 uint32_t mac_data_poll_host_poll_time_max(protocol_interface_info_entry_t *cur)
00163 {
00164     if (!cur || !cur->rfd_poll_info) {
00165         return 0;
00166     }
00167 
00168     return cur->rfd_poll_info->slow_poll_rate_seconds;
00169 }
00170 
00171 uint32_t mac_data_poll_host_timeout(protocol_interface_info_entry_t *cur)
00172 {
00173     if (!cur || !cur->rfd_poll_info) {
00174         return 0;
00175     }
00176 
00177     return cur->rfd_poll_info->timeOutInSeconds;
00178 }
00179 
00180 uint32_t mac_data_poll_get_max_sleep_period(protocol_interface_info_entry_t *cur)
00181 {
00182     if (cur && cur->if_stack_buffer_handler && (cur->rfd_poll_info && !cur->rfd_poll_info->pollActive)) { // Verify That TX is not active
00183         if (cur->rfd_poll_info->protocol_poll) {
00184             return 300;
00185         } else {
00186             return cur->rfd_poll_info->nwk_app_poll_time;
00187         }
00188     }
00189     return 0;
00190 }
00191 
00192 void mac_data_poll_protocol_poll_mode_decrement(struct protocol_interface_info_entry *cur)
00193 {
00194     if (!cur || !cur->rfd_poll_info) {
00195         return;
00196     }
00197 
00198     if (!(cur->lowpan_info & INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE)) {
00199         return;
00200     }
00201 
00202     mac_data_poll_protocol_poll_internal_cancel(cur);
00203 }
00204 
00205 void mac_data_poll_protocol_poll_mode_disable(struct protocol_interface_info_entry *cur)
00206 {
00207     if (!cur || !cur->rfd_poll_info) {
00208         return;
00209     }
00210 
00211     if (!(cur->lowpan_info & INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE)) {
00212         return;
00213     }
00214 
00215     mac_data_poll_protocol_poll_internal_cancel(cur);
00216 }
00217 
00218 void mac_data_poll_disable(struct protocol_interface_info_entry *cur)
00219 {
00220     if (!cur || !cur->rfd_poll_info) {
00221         return;
00222     }
00223 
00224     eventOS_event_timer_cancel(cur->id, mac_data_poll_tasklet);
00225     cur->rfd_poll_info->protocol_poll = 0;
00226     cur->rfd_poll_info->pollActive = false;
00227 }
00228 
00229 void mac_data_poll_enable_check(protocol_interface_info_entry_t *cur)
00230 {
00231     if (!cur || !cur->rfd_poll_info ) {
00232         return;
00233     }
00234 
00235     if (!(cur->lowpan_info & INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE)) {
00236         return;
00237     }
00238 
00239     mac_data_poll_protocol_internal(cur);
00240 }
00241 
00242 int8_t mac_data_poll_host_mode_get(struct protocol_interface_info_entry *cur, net_host_mode_t *mode)
00243 {
00244     if (!cur || !cur->rfd_poll_info) {
00245         return -1;
00246     }
00247 
00248     *mode = cur->rfd_poll_info->host_mode;
00249     return 0;
00250 }
00251 
00252 void mac_poll_timer_trig(uint32_t poll_time, protocol_interface_info_entry_t *cur)
00253 {
00254     if( !cur ){
00255         return;
00256     }
00257     eventOS_event_timer_cancel(cur->id, mac_data_poll_tasklet);
00258 
00259     if (poll_time) {
00260         if (cur->lowpan_info & INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE) {
00261 
00262             if (poll_time < 20) {
00263                 arm_event_s event = {
00264                         .receiver = mac_data_poll_tasklet,
00265                         .sender = mac_data_poll_tasklet,
00266                         .event_id = cur->id,
00267                         .data_ptr = NULL,
00268                         .event_type = MAC_DATA_POLL_REQUEST_EVENT,
00269                         .priority = ARM_LIB_MED_PRIORITY_EVENT,
00270                 };
00271 
00272                 if (eventOS_event_send(&event) != 0) {
00273                     tr_error("eventOS_event_send() failed");
00274                 }
00275             } else {
00276                 if (eventOS_event_timer_request(cur->id, MAC_DATA_POLL_REQUEST_EVENT, mac_data_poll_tasklet, poll_time)!= 0) {
00277                     tr_error("Poll Timer start Fail");
00278                 }
00279             }
00280 
00281         }
00282     }
00283 }
00284 
00285 void mac_mlme_poll_confirm(protocol_interface_info_entry_t *cur, const mlme_poll_conf_t *confirm)
00286 {
00287     if( !cur || !confirm ){
00288         return;
00289     }
00290 
00291     uint32_t poll_time = 1;
00292     nwk_rfd_poll_setups_s *rf_ptr = cur->rfd_poll_info;
00293     if( !rf_ptr ){
00294         return;
00295     }
00296 
00297     rf_ptr->pollActive = false;
00298 
00299     switch (confirm->status) {
00300         case MLME_SUCCESS:
00301             //tr_debug("Poll Confirm: Data with Data");
00302             rf_ptr->nwk_parent_poll_fail = 0;
00303             //Trig new Data Poll immediately
00304             mle_refresh_entry_timeout(cur->id, rf_ptr->poll_req.CoordAddress, (addrtype_t)rf_ptr->poll_req.CoordAddrMode, true);
00305             poll_time = 1;
00306             break;
00307 
00308         case MLME_NO_DATA:
00309             //Start next case timer
00310             rf_ptr->nwk_parent_poll_fail = 0;
00311             mle_refresh_entry_timeout(cur->id, rf_ptr->poll_req.CoordAddress, (addrtype_t)rf_ptr->poll_req.CoordAddrMode, true);
00312             //tr_debug("Poll Confirm: No Data");
00313 
00314             if (rf_ptr->protocol_poll == 0) {
00315                 poll_time = rf_ptr->nwk_app_poll_time;
00316             } else {
00317                 poll_time = 300;
00318             }
00319 
00320             break;
00321         default:
00322             tr_debug("Poll Confirm: fail %x", confirm->status);
00323             rf_ptr->nwk_parent_poll_fail++;
00324             if (rf_ptr->nwk_parent_poll_fail  > 3) {
00325                 //tr_debug("Parent Poll Fail");
00326                 poll_time = 0;
00327                 rf_ptr->nwk_parent_poll_fail = 0;
00328                 if( rf_ptr->pollFailCb ){
00329                     rf_ptr->pollFailCb(cur->id);
00330                 }
00331             } else {
00332                 poll_time = 2000;
00333             }
00334             break;
00335     }
00336 
00337     mac_poll_timer_trig(poll_time, cur);
00338 
00339 
00340 }
00341 
00342 
00343 static void mac_data_poll_cb_run(int8_t interface_id)
00344 {
00345     protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
00346     if (!cur) {
00347         return;
00348     }
00349     nwk_rfd_poll_setups_s *rf_ptr = cur->rfd_poll_info;
00350 
00351     if (!rf_ptr) {
00352         return;
00353     }
00354 
00355     rf_ptr->poll_req.CoordAddrMode = (unsigned)mac_helper_coordinator_address_get(cur, rf_ptr->poll_req.CoordAddress);
00356 
00357     if (rf_ptr->poll_req.CoordAddrMode == MAC_ADDR_MODE_NONE) {
00358         return;
00359     }
00360 
00361     memset(&rf_ptr->poll_req.Key, 0, sizeof(mlme_security_t));
00362     rf_ptr->poll_req.CoordPANId = mac_helper_panid_get(cur);
00363 
00364     rf_ptr->poll_req.Key.SecurityLevel = mac_helper_default_security_level_get(cur);
00365     if (rf_ptr->poll_req.Key.SecurityLevel) {
00366 
00367         rf_ptr->poll_req.Key.KeyIndex = mac_helper_default_key_index_get(cur);
00368         rf_ptr->poll_req.Key.KeyIdMode = mac_helper_default_security_key_id_mode_get(cur);
00369     }
00370 
00371     if (cur->mac_api && cur->mac_api->mlme_req) {
00372         rf_ptr->pollActive = true;
00373         cur->mac_api->mlme_req(cur->mac_api, MLME_POLL, (void*) &rf_ptr->poll_req);
00374     } else {
00375         tr_error("MAC not registered to interface");
00376     }
00377 }
00378 
00379 int8_t mac_data_poll_host_mode_set(struct protocol_interface_info_entry *cur, net_host_mode_t mode, uint32_t poll_time)
00380 {
00381 #ifndef NO_MLE
00382     if( !cur){
00383         return -1;
00384     }
00385     int8_t ret_val = 0;
00386     nwk_rfd_poll_setups_s *rf_ptr = cur->rfd_poll_info;
00387     //Check IF Bootsrap Ready and type is Host
00388     if (!rf_ptr ) {
00389         return -1;
00390     }
00391 
00392     if (cur->lowpan_info & INTERFACE_NWK_ROUTER_DEVICE) {
00393         return -3;
00394     }
00395 
00396 
00397     switch (mode) {
00398         case NET_HOST_SLOW_POLL_MODE:
00399             //slow mode
00400             //Check Host current sleep state
00401             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) {
00402                 uint32_t new_poll_time;
00403                 uint32_t new_Timeout;
00404 
00405                 if (poll_time == 0 || poll_time > 864001) {
00406                     return -2;
00407                 }
00408 
00409                 //Calculate
00410                 //Timeout from Poll Time
00411                 new_Timeout = poll_time * 4;
00412 
00413                 if (new_Timeout < 32) { //Keep Timeout always to 32 seconds min
00414                     new_Timeout = 32;
00415                 }
00416 
00417                 if (new_Timeout != rf_ptr->timeOutInSeconds) {
00418                     rf_ptr->timeOutInSeconds = new_Timeout;
00419                 }
00420 
00421                 rf_ptr->slow_poll_rate_seconds = poll_time;
00422 
00423                 new_poll_time = (poll_time * 1000);
00424                 if (rf_ptr->host_mode == NET_HOST_RX_ON_IDLE) {
00425                     tr_debug("Init Poll timer and period");
00426                     mle_class_mode_set(cur->id, MLE_CLASS_SLEEPY_END_DEVICE);
00427                 }
00428 
00429                 rf_ptr->nwk_app_poll_time = new_poll_time;
00430                 tr_debug("Enable Poll state slow poll");
00431                 if (host_link_configuration(false, cur) != 0) {
00432                     return -3;
00433                 }
00434                 mac_poll_timer_trig(1, cur);
00435                 rf_ptr->host_mode = NET_HOST_SLOW_POLL_MODE;
00436             }
00437             break;
00438         case NET_HOST_FAST_POLL_MODE:
00439             //fast mode
00440             //Check Host current sleep state
00441             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) {
00442                 if (rf_ptr->host_mode != NET_HOST_FAST_POLL_MODE) {
00443                     tr_debug("Enable Fast poll mode");
00444                     if (rf_ptr->host_mode == NET_HOST_RX_ON_IDLE) {
00445                         tr_debug("Init Poll timer and period");
00446                         if (host_link_configuration(false, cur) != 0) {
00447                             return  -3;
00448                         }
00449                     }
00450                 }
00451                 tr_debug("Enable Poll By APP");
00452                 mle_class_mode_set(cur->id, MLE_CLASS_SLEEPY_END_DEVICE);
00453                 mac_helper_pib_boolean_set(cur, macRxOnWhenIdle, false);
00454                 mac_poll_timer_trig(1, cur);
00455                 rf_ptr->nwk_app_poll_time = 300;
00456                 rf_ptr->host_mode = NET_HOST_FAST_POLL_MODE;
00457 
00458             }
00459             break;
00460 
00461         case NET_HOST_RX_ON_IDLE:
00462             // Non-sleep mode
00463             if (rf_ptr->host_mode == NET_HOST_FAST_POLL_MODE || rf_ptr->host_mode == NET_HOST_SLOW_POLL_MODE) {
00464                 if (host_link_configuration(true, cur) == 0) {
00465                     rf_ptr->host_mode = NET_HOST_RX_ON_IDLE;
00466                     rf_ptr->nwk_app_poll_time = 0;
00467                 } else {
00468                     ret_val = -3;
00469                 }
00470             }
00471             break;
00472 
00473         default:
00474             ret_val = -1;
00475             break;
00476     }
00477 
00478     return ret_val;
00479 #else /* MLE_DRAFT */
00480     return -1;
00481 #endif /* MLE_DRAFT */
00482 }
00483 
00484 void mac_data_poll_init(struct protocol_interface_info_entry *cur)
00485 {
00486     if (!cur) {
00487         return;
00488     }
00489 
00490     if (cur->lowpan_info & INTERFACE_NWK_ROUTER_DEVICE) {
00491         if (cur->rfd_poll_info) {
00492             ns_dyn_mem_free(cur->rfd_poll_info);
00493             cur->rfd_poll_info = NULL;
00494         }
00495         mac_helper_pib_boolean_set(cur, macRxOnWhenIdle, true);
00496         return;
00497     }
00498 
00499     //Allocate and Init
00500     nwk_rfd_poll_setups_s *rfd_ptr = cur->rfd_poll_info;
00501 
00502     if (!rfd_ptr) {
00503         if (mac_data_poll_tasklet_init() < 0 ) {
00504             tr_error("Mac data poll tasklet init fail");
00505         } else {
00506             rfd_ptr = ns_dyn_mem_alloc(sizeof(nwk_rfd_poll_setups_s));
00507             if (rfd_ptr) {
00508                 rfd_ptr->timeOutInSeconds = 0;
00509                 rfd_ptr->nwk_parent_poll_fail = false;
00510                 rfd_ptr->protocol_poll = 0;
00511                 rfd_ptr->slow_poll_rate_seconds = 0;
00512                 rfd_ptr->pollActive = false;
00513                 cur->rfd_poll_info = rfd_ptr;
00514             }
00515         }
00516     }
00517 
00518     if (!rfd_ptr) {
00519         return;
00520     }
00521 
00522     //Set MAc Data poll Fail Callback
00523     rfd_ptr->pollFailCb = nwk_parent_poll_fail_cb;
00524 
00525     if (cur->mac_parameters->RxOnWhenIdle) {
00526         tr_debug("Set Non-Sleepy HOST");
00527         rfd_ptr->host_mode = NET_HOST_RX_ON_IDLE;
00528         mle_class_mode_set(cur->id, MLE_CLASS_END_DEVICE);
00529     } else {
00530 
00531         rfd_ptr->protocol_poll = 1;
00532         mac_poll_timer_trig(200, cur);
00533         tr_debug("Set Sleepy HOST configure");
00534         rfd_ptr->host_mode = NET_HOST_FAST_POLL_MODE;
00535         mle_class_mode_set(cur->id, MLE_CLASS_SLEEPY_END_DEVICE);
00536         rfd_ptr->slow_poll_rate_seconds = 3;
00537         rfd_ptr->timeOutInSeconds = 32;
00538         rfd_ptr->nwk_app_poll_time = 300;
00539         rfd_ptr->nwk_parent_poll_fail = 0;
00540     }
00541 }