Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

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-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 }