Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ws_management_api.c Source File

ws_management_api.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 <string.h>
00019 #include "nsconfig.h"
00020 #include "ns_types.h"
00021 #include "ns_trace.h"
00022 #include <ns_list.h>
00023 #include <nsdynmemLIB.h>
00024 #include "NWK_INTERFACE/Include/protocol.h"
00025 #include "6LoWPAN/ws/ws_common.h"
00026 #include "6LoWPAN/ws/ws_bootstrap.h"
00027 
00028 #include "ws_management_api.h"
00029 
00030 #define TRACE_GROUP "wsmg"
00031 
00032 #ifdef HAVE_WS
00033 
00034 int ws_management_node_init(
00035     int8_t interface_id,
00036     uint8_t regulatory_domain,
00037     char *network_name_ptr,
00038     fhss_timer_t *fhss_timer_ptr)
00039 {
00040     protocol_interface_info_entry_t *cur;
00041 
00042     cur = protocol_stack_interface_info_get_by_id(interface_id);
00043     if (!cur || !ws_info(cur)) {
00044         return -1;
00045     }
00046     if (!network_name_ptr || !fhss_timer_ptr) {
00047         return -2;
00048     }
00049     cur->ws_info->hopping_schdule.regulatory_domain = regulatory_domain;
00050     if (ws_common_regulatory_domain_config(cur) < 0) {
00051         // Invalid regulatory domain set
00052         return -3;
00053     }
00054     strncpy(cur->ws_info->network_name, network_name_ptr, 32);
00055     cur->ws_info->fhss_timer_ptr = fhss_timer_ptr;
00056     return 0;
00057 }
00058 
00059 int ws_management_network_name_set(
00060     int8_t interface_id,
00061     char *network_name_ptr)
00062 {
00063     protocol_interface_info_entry_t *cur;
00064     cur = protocol_stack_interface_info_get_by_id(interface_id);
00065     if (!cur || !ws_info(cur)) {
00066         return -1;
00067     }
00068     if (!network_name_ptr || strlen(network_name_ptr) == 0 || strlen(network_name_ptr) > 32) {
00069         return -2;
00070     }
00071     if (strcmp(cur->ws_info->network_name, network_name_ptr) == 0) {
00072         // Network name is the same no further actions required.
00073         return 0;
00074     }
00075     strncpy(cur->ws_info->network_name, network_name_ptr, 32);
00076     // if settings change reset_restart for the settings needed
00077     if (cur->lowpan_info & INTERFACE_NWK_ACTIVE) {
00078         // bootstrap active need to restart
00079         ws_bootstrap_restart(interface_id);
00080     }
00081 
00082     return 0;
00083 }
00084 int ws_management_regulatory_domain_set(
00085     int8_t interface_id,
00086     uint8_t regulatory_domain,
00087     uint8_t operating_class,
00088     uint8_t operating_mode)
00089 {
00090     uint8_t regulatory_domain_saved;
00091     uint8_t operating_class_saved;
00092     uint8_t operating_mode_saved;
00093     protocol_interface_info_entry_t *cur;
00094 
00095     cur = protocol_stack_interface_info_get_by_id(interface_id);
00096     if (!cur || !ws_info(cur)) {
00097         return -1;
00098     }
00099     regulatory_domain_saved = cur->ws_info->hopping_schdule.regulatory_domain;
00100     operating_class_saved = cur->ws_info->hopping_schdule.operating_mode;
00101     operating_mode_saved = cur->ws_info->hopping_schdule.operating_class;
00102     if (regulatory_domain != 255) {
00103         cur->ws_info->hopping_schdule.regulatory_domain = regulatory_domain;
00104     }
00105     if (operating_mode != 255) {
00106         cur->ws_info->hopping_schdule.operating_mode = operating_mode;
00107     }
00108     if (operating_class != 255) {
00109         cur->ws_info->hopping_schdule.operating_class = operating_class;
00110     }
00111     if (ws_common_regulatory_domain_config(cur) != 0) {
00112         // Restore old config on failure
00113         //tr_error("unsupported regulatory domain: %d class: %d, mode: %d", regulatory_domain, operating_class, operating_mode);
00114         cur->ws_info->hopping_schdule.regulatory_domain = regulatory_domain_saved;
00115         cur->ws_info->hopping_schdule.operating_mode = operating_mode_saved;
00116         cur->ws_info->hopping_schdule.operating_class = operating_class_saved;
00117         ws_common_regulatory_domain_config(cur);
00118         return -1;
00119     }
00120     // if settings change reset_restart for the settings needed
00121     if (cur->lowpan_info & INTERFACE_NWK_ACTIVE) {
00122         // bootstrap active need to restart
00123         ws_bootstrap_restart(interface_id);
00124     }
00125 
00126     return 0;
00127 }
00128 
00129 int ws_management_network_size_set(
00130     int8_t interface_id,
00131     uint8_t network_size)
00132 {
00133     protocol_interface_info_entry_t *cur;
00134 
00135     cur = protocol_stack_interface_info_get_by_id(interface_id);
00136     if (!cur || !ws_info(cur)) {
00137         return -1;
00138     }
00139     //Store old setup if new is not accepted
00140     uint8_t old_setup = ws_info(cur)->network_size_config;
00141     ws_info(cur)->network_size_config = network_size;
00142 
00143     uint16_t rpl_parent_candidate_max;
00144     uint16_t rpl_selected_parent_max;
00145 
00146     if (network_size == NETWORK_SIZE_CERTIFICATE) {
00147         rpl_parent_candidate_max = WS_CERTIFICATE_RPL_PARENT_CANDIDATE_MAX;
00148         rpl_selected_parent_max = WS_CERTIFICATE_RPL_SELECTED_PARENT_MAX;
00149     } else {
00150         rpl_parent_candidate_max = WS_RPL_PARENT_CANDIDATE_MAX;
00151         rpl_selected_parent_max = WS_RPL_SELECTED_PARENT_MAX;
00152     }
00153 
00154     if (network_size == NETWORK_SIZE_LARGE) {
00155         ws_common_network_size_configure(cur, 5000);
00156     } else if (network_size == NETWORK_SIZE_MEDIUM) {
00157         ws_common_network_size_configure(cur, 200);
00158     } else if (network_size == NETWORK_SIZE_SMALL) {
00159         ws_common_network_size_configure(cur, 10);
00160     } else if (network_size == NETWORK_SIZE_CERTIFICATE) {
00161         ws_common_network_size_configure(cur, 0);
00162     } else {
00163         ws_info(cur)->network_size_config = old_setup;
00164         return -2;
00165     }
00166     cur->ws_info->rpl_parent_candidate_max = rpl_parent_candidate_max;
00167     cur->ws_info->rpl_selected_parent_max = rpl_selected_parent_max;
00168     return 0;
00169 }
00170 
00171 int ws_management_channel_mask_set(
00172     int8_t interface_id,
00173     uint32_t channel_mask[8])
00174 {
00175     protocol_interface_info_entry_t *cur;
00176 
00177     cur = protocol_stack_interface_info_get_by_id(interface_id);
00178     if (!cur || !ws_info(cur)) {
00179         return -1;
00180     }
00181     memcpy(cur->ws_info->fhss_channel_mask, channel_mask, sizeof(uint32_t) * 8);
00182     return 0;
00183 }
00184 
00185 int ws_management_channel_plan_set(
00186     int8_t interface_id,
00187     uint8_t channel_plan,
00188     uint8_t uc_channel_function,
00189     uint8_t bc_channel_function,
00190     uint32_t ch0_freq, // Stack can not modify this
00191     uint8_t channel_spacing,// Stack can not modify this
00192     uint8_t number_of_channels)
00193 {
00194     protocol_interface_info_entry_t *cur;
00195 
00196     cur = protocol_stack_interface_info_get_by_id(interface_id);
00197     if (!cur || !ws_info(cur)) {
00198         return -1;
00199     }
00200     cur->ws_info->hopping_schdule.channel_plan = channel_plan;
00201     cur->ws_info->hopping_schdule.uc_channel_function = uc_channel_function;
00202     cur->ws_info->hopping_schdule.bc_channel_function = bc_channel_function;
00203     cur->ws_info->hopping_schdule.ch0_freq = ch0_freq;
00204     cur->ws_info->hopping_schdule.channel_spacing = channel_spacing;
00205     cur->ws_info->hopping_schdule.number_of_channels = number_of_channels;
00206 
00207     // TODO update fields to llc
00208     return 0;
00209 }
00210 
00211 int ws_management_fhss_timing_configure(
00212     int8_t interface_id,
00213     uint8_t fhss_uc_dwell_interval,
00214     uint32_t fhss_broadcast_interval,
00215     uint8_t fhss_bc_dwell_interval)
00216 {
00217     protocol_interface_info_entry_t *cur;
00218 
00219     cur = protocol_stack_interface_info_get_by_id(interface_id);
00220     if (!cur || !ws_info(cur)) {
00221         return -1;
00222     }
00223     if (fhss_uc_dwell_interval > 0) {
00224         cur->ws_info->fhss_uc_dwell_interval = fhss_uc_dwell_interval;
00225     }
00226     if (fhss_broadcast_interval > 0) {
00227         cur->ws_info->fhss_bc_interval = fhss_broadcast_interval;
00228 
00229     }
00230     if (fhss_bc_dwell_interval > 0) {
00231         cur->ws_info->fhss_bc_dwell_interval = fhss_bc_dwell_interval;
00232 
00233     }
00234 
00235     // if settings change reset_restart for the settings needed
00236     if (cur->lowpan_info & INTERFACE_NWK_ACTIVE) {
00237         // bootstrap active need to restart
00238         ws_bootstrap_restart(interface_id);
00239     }
00240     return 0;
00241 }
00242 
00243 int ws_management_fhss_unicast_channel_function_configure(
00244     int8_t interface_id,
00245     uint8_t channel_function,
00246     uint16_t fixed_channel,
00247     uint8_t dwell_interval)
00248 {
00249     protocol_interface_info_entry_t *cur;
00250 
00251     cur = protocol_stack_interface_info_get_by_id(interface_id);
00252     if (!cur || !ws_info(cur)) {
00253         return -1;
00254     }
00255     if (channel_function != WS_FIXED_CHANNEL &&
00256             channel_function != WS_VENDOR_DEF_CF &&
00257             channel_function != WS_DH1CF &&
00258             channel_function != WS_TR51CF) {
00259         return -2;
00260     }
00261 
00262     if (channel_function == WS_FIXED_CHANNEL && fixed_channel == 0xffff) {
00263         fixed_channel = 0;
00264         tr_warn("Fixed channel not configured. Set to 0");
00265     }
00266 
00267 
00268     cur->ws_info->fhss_uc_channel_function = channel_function;
00269     if (cur->ws_info->fhss_uc_channel_function == WS_FIXED_CHANNEL) {
00270         cur->ws_info->fhss_uc_fixed_channel = fixed_channel;
00271     } else {
00272         cur->ws_info->fhss_uc_fixed_channel = 0xffff;
00273     }
00274 
00275     cur->ws_info->fhss_uc_dwell_interval = dwell_interval;
00276 
00277     // if settings change reset_restart for the settings needed
00278     if (cur->lowpan_info & INTERFACE_NWK_ACTIVE) {
00279         // bootstrap active need to restart
00280         ws_bootstrap_restart(interface_id);
00281     }
00282     return 0;
00283 
00284 }
00285 
00286 int ws_management_fhss_broadcast_channel_function_configure(
00287     int8_t interface_id,
00288     uint8_t channel_function,
00289     uint16_t fixed_channel,
00290     uint8_t dwell_interval,
00291     uint32_t broadcast_interval)
00292 {
00293     protocol_interface_info_entry_t *cur;
00294 
00295     cur = protocol_stack_interface_info_get_by_id(interface_id);
00296     if (!cur || !ws_info(cur)) {
00297         return -1;
00298     }
00299     if (channel_function != WS_FIXED_CHANNEL &&
00300             channel_function != WS_VENDOR_DEF_CF &&
00301             channel_function != WS_DH1CF &&
00302             channel_function != WS_TR51CF) {
00303         return -2;
00304     }
00305 
00306     if (channel_function == WS_FIXED_CHANNEL && fixed_channel == 0xffff) {
00307         fixed_channel = 0;
00308         tr_warn("Fixed channel not configured. Set to 0");
00309     }
00310 
00311     cur->ws_info->fhss_bc_channel_function = channel_function;
00312     if (cur->ws_info->fhss_bc_channel_function == WS_FIXED_CHANNEL) {
00313         cur->ws_info->fhss_bc_fixed_channel = fixed_channel;
00314     } else {
00315         cur->ws_info->fhss_bc_fixed_channel = 0xffff;
00316     }
00317 
00318     cur->ws_info->fhss_bc_dwell_interval = dwell_interval;
00319     cur->ws_info->fhss_bc_interval = broadcast_interval;
00320 
00321     // if settings change reset_restart for the settings needed
00322     if (cur->lowpan_info & INTERFACE_NWK_ACTIVE) {
00323         // bootstrap active need to restart
00324         ws_bootstrap_restart(interface_id);
00325     }
00326     return 0;
00327 
00328 }
00329 #endif // HAVE_WS