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
ws_neighbor_class.c
00001 /* 00002 * Copyright (c) 2018-2019, 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 #include "nsconfig.h" 00019 #include <string.h> 00020 #include "ns_types.h" 00021 #include "ns_list.h" 00022 #include "ns_trace.h" 00023 #include "nsdynmemLIB.h" 00024 #include "fhss_config.h " 00025 #include "6LoWPAN/ws/ws_config.h" 00026 #include "6LoWPAN/ws/ws_neighbor_class.h" 00027 #include "6LoWPAN/ws/ws_common.h" 00028 #include "ws_management_api.h" 00029 00030 #ifdef HAVE_WS 00031 00032 00033 #define TRACE_GROUP "wsne" 00034 00035 00036 bool ws_neighbor_class_alloc(ws_neighbor_class_t *class_data, uint8_t list_size) 00037 { 00038 00039 class_data->neigh_info_list = ns_dyn_mem_alloc(sizeof(ws_neighbor_class_entry_t) * list_size); 00040 if (!class_data->neigh_info_list ) { 00041 return false; 00042 } 00043 00044 class_data->list_size = list_size; 00045 ws_neighbor_class_entry_t *list_ptr = class_data->neigh_info_list ; 00046 for (uint8_t i = 0; i < list_size; i++) { 00047 memset(list_ptr, 0, sizeof(ws_neighbor_class_entry_t)); 00048 list_ptr->rsl_in = RSL_UNITITIALIZED; 00049 list_ptr->rsl_out = RSL_UNITITIALIZED; 00050 list_ptr++; 00051 } 00052 return true; 00053 } 00054 00055 00056 void ws_neighbor_class_dealloc(ws_neighbor_class_t *class_data) 00057 { 00058 ns_dyn_mem_free(class_data->neigh_info_list ); 00059 class_data->neigh_info_list = NULL; 00060 class_data->list_size = 0; 00061 } 00062 00063 ws_neighbor_class_entry_t *ws_neighbor_class_entry_get(ws_neighbor_class_t *class_data, uint8_t attribute_index) 00064 { 00065 if (!class_data->neigh_info_list || attribute_index >= class_data->list_size ) { 00066 return NULL; 00067 } 00068 00069 ws_neighbor_class_entry_t *entry = class_data->neigh_info_list + attribute_index; 00070 return entry; 00071 } 00072 00073 uint8_t ws_neighbor_class_entry_index_get(ws_neighbor_class_t *class_data, ws_neighbor_class_entry_t *entry) 00074 { 00075 if (!class_data->neigh_info_list ) { 00076 return 0xff; 00077 } 00078 return entry - class_data->neigh_info_list ; 00079 } 00080 00081 void ws_neighbor_class_entry_remove(ws_neighbor_class_t *class_data, uint8_t attribute_index) 00082 { 00083 ws_neighbor_class_entry_t *entry = ws_neighbor_class_entry_get(class_data, attribute_index); 00084 if (entry) { 00085 memset(entry, 0, sizeof(ws_neighbor_class_entry_t)); 00086 entry->rsl_in = RSL_UNITITIALIZED; 00087 entry->rsl_out = RSL_UNITITIALIZED; 00088 } 00089 } 00090 00091 void ws_neighbor_class_neighbor_unicast_time_info_update(ws_neighbor_class_entry_t *ws_neighbor, ws_utt_ie_t *ws_utt, uint32_t timestamp) 00092 { 00093 ws_neighbor->fhss_data.uc_timing_info.utt_rx_timestamp = timestamp; 00094 ws_neighbor->fhss_data.uc_timing_info.ufsi = ws_utt->ufsi; 00095 } 00096 00097 void ws_neighbor_class_neighbor_unicast_schedule_set(ws_neighbor_class_entry_t *ws_neighbor, ws_us_ie_t *ws_us) 00098 { 00099 ws_neighbor->fhss_data.uc_timing_info.unicast_channel_function = ws_us->channel_function; 00100 if (ws_us->channel_function == WS_FIXED_CHANNEL) { 00101 ws_neighbor->fhss_data.uc_timing_info.fixed_channel = ws_us->function.zero.fixed_channel; 00102 ws_neighbor->fhss_data.uc_timing_info.unicast_number_of_channels = 1; 00103 } else { 00104 if (ws_us->channel_plan == 0) { 00105 ws_neighbor->fhss_data.uc_timing_info.unicast_number_of_channels = ws_common_channel_number_calc(ws_us->plan.zero.regulator_domain, ws_us->plan.zero.operation_class); 00106 } else if (ws_us->channel_plan == 1) { 00107 ws_neighbor->fhss_data.uc_timing_info.unicast_number_of_channels = ws_us->plan.one.number_of_channel; 00108 } else { 00109 ws_neighbor->fhss_data.uc_timing_info.unicast_number_of_channels = 0; 00110 } 00111 } 00112 ws_neighbor->fhss_data.uc_timing_info.unicast_dwell_interval = ws_us->dwell_interval; 00113 } 00114 00115 00116 void ws_neighbor_class_neighbor_broadcast_time_info_update(ws_neighbor_class_entry_t *ws_neighbor, ws_bt_ie_t *ws_bt_ie, uint32_t timestamp) 00117 { 00118 ws_neighbor->broadcast_timing_info_stored = true; 00119 ws_neighbor->fhss_data.bc_timing_info.bt_rx_timestamp = timestamp; 00120 ws_neighbor->fhss_data.bc_timing_info.broadcast_slot = ws_bt_ie->broadcast_slot_number; 00121 ws_neighbor->fhss_data.bc_timing_info.broadcast_interval_offset = ws_bt_ie->broadcast_interval_offset; 00122 } 00123 00124 00125 void ws_neighbor_class_neighbor_broadcast_schedule_set(ws_neighbor_class_entry_t *ws_neighbor, ws_bs_ie_t *ws_bs_ie) 00126 { 00127 ws_neighbor->broadcast_shedule_info_stored = true; 00128 ws_neighbor->fhss_data.bc_timing_info.broadcast_channel_function = ws_bs_ie->channel_function; 00129 if (ws_bs_ie->channel_function == WS_FIXED_CHANNEL) { 00130 ws_neighbor->fhss_data.bc_timing_info.fixed_channel = ws_bs_ie->function.zero.fixed_channel; 00131 } 00132 ws_neighbor->fhss_data.bc_timing_info.broadcast_dwell_interval = ws_bs_ie->dwell_interval; 00133 ws_neighbor->fhss_data.bc_timing_info.broadcast_interval = ws_bs_ie->broadcast_interval; 00134 ws_neighbor->fhss_data.bc_timing_info.broadcast_schedule_id = ws_bs_ie->broadcast_schedule_identifier; 00135 } 00136 00137 void ws_neighbor_class_rf_sensitivity_calculate(uint8_t rsl_heard) 00138 { 00139 if (DEVICE_MIN_SENS > rsl_heard) { 00140 // We are hearing packet with lower than min_sens dynamically learn the sensitivity 00141 DEVICE_MIN_SENS = rsl_heard; 00142 } 00143 } 00144 00145 uint8_t ws_neighbor_class_rsl_from_dbm_calculate(int8_t dbm_heard) 00146 { 00147 /* RSL MUST be calculated as the received signal level relative to standard 00148 * thermal noise (290oK) at 1 Hz bandwidth or 174 dBm. 00149 * This provides a range of -174 (0) to +80 (254) dBm. 00150 */ 00151 00152 return dbm_heard + 174; 00153 } 00154 00155 static void ws_neighbor_class_parent_set_analyze(ws_neighbor_class_entry_t *ws_neighbor) 00156 { 00157 if (ws_neighbor->rsl_in == RSL_UNITITIALIZED || 00158 ws_neighbor->rsl_out == RSL_UNITITIALIZED) { 00159 ws_neighbor->candidate_parent = false; 00160 return; 00161 } 00162 00163 if (ws_neighbor_class_rsl_in_get(ws_neighbor) < (DEVICE_MIN_SENS + CAND_PARENT_THRESHOLD - CAND_PARENT_HYSTERISIS) && 00164 ws_neighbor_class_rsl_out_get(ws_neighbor) < (DEVICE_MIN_SENS + CAND_PARENT_THRESHOLD - CAND_PARENT_HYSTERISIS)) { 00165 ws_neighbor->candidate_parent = false; 00166 } 00167 00168 if (ws_neighbor_class_rsl_in_get(ws_neighbor) > (DEVICE_MIN_SENS + CAND_PARENT_THRESHOLD + CAND_PARENT_HYSTERISIS) && 00169 ws_neighbor_class_rsl_out_get(ws_neighbor) > (DEVICE_MIN_SENS + CAND_PARENT_THRESHOLD + CAND_PARENT_HYSTERISIS)) { 00170 ws_neighbor->candidate_parent = true; 00171 } 00172 } 00173 00174 void ws_neighbor_class_rsl_in_calculate(ws_neighbor_class_entry_t *ws_neighbor, int8_t dbm_heard) 00175 { 00176 uint8_t rsl = ws_neighbor_class_rsl_from_dbm_calculate(dbm_heard); 00177 // Calculate minimum sensitivity from heard packets. 00178 ws_neighbor_class_rf_sensitivity_calculate(rsl); 00179 if (ws_neighbor->rsl_in == RSL_UNITITIALIZED) { 00180 ws_neighbor->rsl_in = rsl << WS_RSL_SCALING; 00181 } 00182 ws_neighbor->rsl_in = ws_neighbor->rsl_in + rsl - (ws_neighbor->rsl_in >> WS_RSL_SCALING); 00183 ws_neighbor_class_parent_set_analyze(ws_neighbor); 00184 return; 00185 } 00186 00187 void ws_neighbor_class_rsl_out_calculate(ws_neighbor_class_entry_t *ws_neighbor, uint8_t rsl_reported) 00188 { 00189 if (ws_neighbor->rsl_out == RSL_UNITITIALIZED) { 00190 ws_neighbor->rsl_out = rsl_reported << WS_RSL_SCALING; 00191 } 00192 ws_neighbor->rsl_out = ws_neighbor->rsl_out + rsl_reported - (ws_neighbor->rsl_out >> WS_RSL_SCALING); 00193 ws_neighbor_class_parent_set_analyze(ws_neighbor); 00194 return; 00195 } 00196 00197 #endif /* HAVE_WS */ 00198
Generated on Tue Jul 12 2022 13:55:04 by
1.7.2