mirror of https://github.com/ARMmbed/mbed-os.git
Merge commit 'fa7202c2e699b26a024d38657a6e495e073fea07'
* commit 'fa7202c2e699b26a024d38657a6e495e073fea07': Squashed 'connectivity/nanostack/sal-stack-nanostack/' changes from 4a3c5c525b..225a4af94fpull/15103/head
commit
b1adec9028
|
@ -129,10 +129,11 @@ typedef void mcps_data_request(const mac_api_t *api, const mcps_data_req_t *data
|
|||
* @param ie_ext Information element list to MCPS-DATA.request
|
||||
* @param asynch_channel_list Optional channel list to asynch data request. Give NULL when normal data request.
|
||||
* @param priority Data request priority level
|
||||
* @param phy_mode_id Use mode switch if given phy_mode_id > 0
|
||||
*
|
||||
* Asynch data request is mac standard extension. asynch_channel_list include channel mask which channel message is requested to send.
|
||||
*/
|
||||
typedef void mcps_data_request_ext(const mac_api_t *api, const mcps_data_req_t *data, const mcps_data_req_ie_list_t *ie_ext, const struct channel_list_s *asynch_channel_list, mac_data_priority_t priority);
|
||||
typedef void mcps_data_request_ext(const mac_api_t *api, const mcps_data_req_t *data, const mcps_data_req_ie_list_t *ie_ext, const struct channel_list_s *asynch_channel_list, mac_data_priority_t priority, uint8_t phy_mode_id);
|
||||
|
||||
/**
|
||||
* @brief mcps_purge_request MCPS_PURGE request call
|
||||
|
@ -192,6 +193,16 @@ typedef void mcps_ack_data_req_ext(const mac_api_t *api, mcps_ack_data_payload_t
|
|||
typedef void mcps_edfe_handler(const mac_api_t *api, mcps_edfe_response_t *response_message);
|
||||
|
||||
|
||||
/**
|
||||
* @brief mode_switch_resolver Callback to resolve configuration behind received PHY mode ID
|
||||
* @param api The API which handled the response
|
||||
* @param phy_mode_id PHY mode ID to be resolved
|
||||
* @param rf_config Resolved configuration
|
||||
* @return 0 in case of success, negative otherwise
|
||||
*/
|
||||
typedef int8_t mode_switch_resolver(const mac_api_t *api, uint8_t phy_mode_id, phy_rf_channel_configuration_s *rf_config);
|
||||
|
||||
|
||||
/**
|
||||
* @brief mcps_purge_confirm MCPS-PURGE confirm is called as a response to MCPS-PURGE request
|
||||
* @param api The API which handled the request
|
||||
|
@ -272,6 +283,16 @@ typedef int8_t mac_api_enable_mcps_ext(mac_api_t *api,
|
|||
typedef int8_t mac_api_enable_mcps_edfe_ext(mac_api_t *api,
|
||||
mcps_edfe_handler *edfe_ind_cb);
|
||||
|
||||
/**
|
||||
* @brief mac_api_mode_switch_resolver_ext Initialises mode switch resolver callback. Upper layer must configure function when mode switch is used.
|
||||
* @param api mac_api_t pointer, which is created by application.
|
||||
* @param mode_resolver_cb Upper layer function to resolve received PHY mode ID
|
||||
* @param base_phy_mode Base PHY mode, device returns to this mode after mode switch transmission or reception
|
||||
* @return -1 if error, 0 otherwise
|
||||
*/
|
||||
typedef int8_t mac_api_mode_switch_resolver_ext(mac_api_t *api,
|
||||
mode_switch_resolver *mode_resolver_cb, uint8_t base_phy_mode);
|
||||
|
||||
/**
|
||||
* \brief Struct mac_api_s defines functions for two-way communications between external MAC and Upper layer.
|
||||
* Application creates mac_api_t object by calling external MAC's creator function.
|
||||
|
@ -279,30 +300,32 @@ typedef int8_t mac_api_enable_mcps_edfe_ext(mac_api_t *api,
|
|||
* Then MAC is operated by Upper layer by calling MLME or MCPS primitive functions.
|
||||
*/
|
||||
struct mac_api_s {
|
||||
mac_api_initialize *mac_initialize; /**< MAC initialize function to use */
|
||||
mac_api_enable_mcps_ext *mac_mcps_extension_enable; /**< MAC MCPS IE extension enable function, optional feature */
|
||||
mac_api_enable_mcps_edfe_ext *mac_mcps_edfe_enable; /**< MAC MCPS MCPS EDFE frame extension enable function, optional feature */
|
||||
mac_api_initialize *mac_initialize; /**< MAC initialize function to use */
|
||||
mac_api_enable_mcps_ext *mac_mcps_extension_enable; /**< MAC MCPS IE extension enable function, optional feature */
|
||||
mac_api_enable_mcps_edfe_ext *mac_mcps_edfe_enable; /**< MAC MCPS MCPS EDFE frame extension enable function, optional feature */
|
||||
mac_api_mode_switch_resolver_ext *mac_mode_switch_resolver_set; /**< MAC Mode switch resolver function set, optional feature */
|
||||
//External MAC callbacks
|
||||
mlme_request *mlme_req; /**< MAC MLME request function to use */
|
||||
mcps_data_request *mcps_data_req; /**< MAC MCPS data request function to use */
|
||||
mcps_data_request_ext *mcps_data_req_ext; /**< MAC MCPS data request with Information element extension function to use */
|
||||
mcps_purge_request *mcps_purge_req; /**< MAC MCPS purge request function to use */
|
||||
mlme_request *mlme_req; /**< MAC MLME request function to use */
|
||||
mcps_data_request *mcps_data_req; /**< MAC MCPS data request function to use */
|
||||
mcps_data_request_ext *mcps_data_req_ext; /**< MAC MCPS data request with Information element extension function to use */
|
||||
mcps_purge_request *mcps_purge_req; /**< MAC MCPS purge request function to use */
|
||||
//Upper layer callbacksMLME_ASSOCIATE
|
||||
mcps_data_confirm *data_conf_cb; /**< MAC MCPS data confirm callback function */
|
||||
mcps_data_confirm_ext *data_conf_ext_cb; /**< MAC MCPS data confirm with payload callback function */
|
||||
mcps_data_indication *data_ind_cb; /**< MAC MCPS data indication callback function */
|
||||
mcps_data_indication_ext *data_ind_ext_cb; /**< MAC MCPS data indication with IE extension's callback function */
|
||||
mcps_edfe_handler *edfe_ind_cb; /**< MAC MCPS EDFE detection extension's callback function */
|
||||
mcps_ack_data_req_ext *enhanced_ack_data_req_cb; /**< Enhanced ACK IE element and payload request from MAC user */
|
||||
mcps_purge_confirm *purge_conf_cb; /**< MAC MCPS purge confirm callback function */
|
||||
mlme_confirm *mlme_conf_cb; /**< MAC MLME confirm callback function */
|
||||
mlme_indication *mlme_ind_cb; /**< MAC MLME indication callback function */
|
||||
mac_ext_mac64_address_set *mac64_set; /**< MAC extension function to set mac64 address */
|
||||
mac_ext_mac64_address_get *mac64_get; /**< MAC extension function to get mac64 address */
|
||||
mac_storage_decription_sizes_get *mac_storage_sizes_get; /**< Getter function to query data storage sizes from MAC */
|
||||
mcps_data_confirm *data_conf_cb; /**< MAC MCPS data confirm callback function */
|
||||
mcps_data_confirm_ext *data_conf_ext_cb; /**< MAC MCPS data confirm with payload callback function */
|
||||
mcps_data_indication *data_ind_cb; /**< MAC MCPS data indication callback function */
|
||||
mcps_data_indication_ext *data_ind_ext_cb; /**< MAC MCPS data indication with IE extension's callback function */
|
||||
mcps_edfe_handler *edfe_ind_cb; /**< MAC MCPS EDFE detection extension's callback function */
|
||||
mode_switch_resolver *mode_resolver_cb; /**< MAC Mode switch resolver callback function */
|
||||
mcps_ack_data_req_ext *enhanced_ack_data_req_cb; /**< Enhanced ACK IE element and payload request from MAC user */
|
||||
mcps_purge_confirm *purge_conf_cb; /**< MAC MCPS purge confirm callback function */
|
||||
mlme_confirm *mlme_conf_cb; /**< MAC MLME confirm callback function */
|
||||
mlme_indication *mlme_ind_cb; /**< MAC MLME indication callback function */
|
||||
mac_ext_mac64_address_set *mac64_set; /**< MAC extension function to set mac64 address */
|
||||
mac_ext_mac64_address_get *mac64_get; /**< MAC extension function to get mac64 address */
|
||||
mac_storage_decription_sizes_get *mac_storage_sizes_get; /**< Getter function to query data storage sizes from MAC */
|
||||
|
||||
int8_t parent_id; /**< Upper layer id */
|
||||
uint16_t phyMTU; /**< Maximum Transmission Unit(MTU) used by MAC*/
|
||||
int8_t parent_id; /**< Upper layer id */
|
||||
uint16_t phyMTU; /**< Maximum Transmission Unit(MTU) used by MAC*/
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -39,6 +39,23 @@ extern "C" {
|
|||
|
||||
#include "ns_types.h"
|
||||
|
||||
/**
|
||||
* \brief Set Wi-SUN version number
|
||||
*
|
||||
* Sets the Wi-SUN protocol version.
|
||||
* 1 = Wi-SUN FAN 1.0
|
||||
* 2 = Wi-SUN FAN 1.1
|
||||
*
|
||||
* Set version to 0 to stop override and use stack default
|
||||
*
|
||||
* \param interface_id Network Interface
|
||||
* \param version Wi-SUN version
|
||||
*
|
||||
* \return 0 OK
|
||||
* \return <0 Failure
|
||||
*/
|
||||
|
||||
int ws_test_version_set(int8_t interface_id, uint8_t version);
|
||||
/**
|
||||
* \brief Set Pan size.
|
||||
*
|
||||
|
|
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Pelion and affiliates.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef NET_WS_TEST_EXT_H_
|
||||
#define NET_WS_TEST_EXT_H_
|
||||
|
||||
/**
|
||||
* \file net_ws_test_ext.h
|
||||
* \brief Wi-SUN Library External Test API.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "ns_types.h"
|
||||
|
||||
/* Test procedure triggers
|
||||
*
|
||||
* Example about using the triggers during bootstrap to trigger
|
||||
* messages and state transitions.
|
||||
*
|
||||
* Border Router Node
|
||||
*
|
||||
* Join state 1 (select PAN)
|
||||
*
|
||||
* PROC_PA
|
||||
* ------- PAN Advertisement------------>
|
||||
*
|
||||
* PROC_EAPOL
|
||||
* Select EAPOL target
|
||||
* Join state 2 (authenticate)
|
||||
* <------ EAPOL authentication -------->
|
||||
* Join State 3 (acquire PAN configuration)
|
||||
*
|
||||
* PROC_PC
|
||||
* ------- PAN Configuration ----------->
|
||||
* Join state 4 (configure routing)
|
||||
*
|
||||
* PROC_DIO
|
||||
* ------- DIO ------------------------->
|
||||
* Neighbor discovery (NS probing for ETX)
|
||||
* Create RPL candidate parent set
|
||||
*
|
||||
* PROC_RPL
|
||||
* Select RPL parent
|
||||
* <------ DHCP ------------------------>
|
||||
*
|
||||
* PROC_DAO
|
||||
* <------ DAO --------------------------
|
||||
* ------- DAO acknowledge ------------->
|
||||
*
|
||||
* Join state 5 (operational)
|
||||
*
|
||||
*
|
||||
* On automatic mode the PROC_PAS, PROC_EAPOL, PROC_PCS, PROC_DIS and PROC_RPL
|
||||
* will be triggered automatically by the node during the bootstrap.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Test procedure triggers.
|
||||
*/
|
||||
typedef enum {
|
||||
PROC_DIS, /* trigger DODAG information object solicit (node) */
|
||||
PROC_DIO, /* trigger DODAG information object (BR, node) */
|
||||
PROC_DAO, /* trigger Destination advertisement object (node) */
|
||||
|
||||
PROC_PAS, /* trigger PAN Advertisement Solicit (node) */
|
||||
PROC_PA, /* trigger PAN Advertisement (BR, node) */
|
||||
PROC_PCS, /* trigger PAN Configuration Solicit (node) */
|
||||
PROC_PC, /* trigger PAN Configuration (BR, node) */
|
||||
|
||||
PROC_EAPOL, /* trigger EAPOL target selection (initiates authentication, node) */
|
||||
PROC_RPL, /* trigger RPL parent selection (node) */
|
||||
|
||||
PROC_AUTO_ON, /* trigger bootstrap test procedures automatically */
|
||||
PROC_AUTO_OFF, /* disable automatic bootstrap test procedure triggering */
|
||||
|
||||
MSG_NONE
|
||||
} ws_test_proc_t;
|
||||
|
||||
/**
|
||||
* Trigger a test procedure
|
||||
*
|
||||
* Can be used to trigger a test procedure, e.g. to send a message (DIS,
|
||||
* DIO, DAO, PAS, PS, PCS and PC) or to trigger bootstrap state change
|
||||
* on node e.g. EAPOL target selection.
|
||||
*
|
||||
* \param interface_id Network Interface ID >= 0 or -1 for Wi-SUN mesh interface
|
||||
* Default value is -1
|
||||
* \param procedure Triggered procedure
|
||||
* \param parameters Parameters for future extensions, shall be set to NULL
|
||||
*
|
||||
* \return 0 Success
|
||||
* \return <0 Failure
|
||||
*/
|
||||
int ws_test_procedure_trigger(int8_t interface_id, ws_test_proc_t procedure, void *parameters);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* NET_WS_TEST_EXT_H_ */
|
|
@ -61,23 +61,39 @@ static inline void ns_sha256_clone(ns_sha256_context *dst,
|
|||
|
||||
static inline void ns_sha256_starts(ns_sha256_context *ctx)
|
||||
{
|
||||
#if (MBEDTLS_VERSION_MAJOR >= 3)
|
||||
(void)mbedtls_sha256_starts(ctx, 0);
|
||||
#else
|
||||
(void)mbedtls_sha256_starts_ret(ctx, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void ns_sha256_update(ns_sha256_context *ctx, const void *input,
|
||||
size_t ilen)
|
||||
{
|
||||
#if (MBEDTLS_VERSION_MAJOR >= 3)
|
||||
(void)mbedtls_sha256_update(ctx, input, ilen);
|
||||
#else
|
||||
(void)mbedtls_sha256_update_ret(ctx, input, ilen);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void ns_sha256_finish(ns_sha256_context *ctx, void *output)
|
||||
{
|
||||
#if (MBEDTLS_VERSION_MAJOR >= 3)
|
||||
(void)mbedtls_sha256_finish(ctx, output);
|
||||
#else
|
||||
(void)mbedtls_sha256_finish_ret(ctx, output);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void ns_sha256(const void *input, size_t ilen, void *output)
|
||||
{
|
||||
#if (MBEDTLS_VERSION_MAJOR >= 3)
|
||||
(void)mbedtls_sha256(input, ilen, output, 0);
|
||||
#else
|
||||
(void)mbedtls_sha256_ret(input, ilen, output, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Extensions to standard mbed TLS - output the first bits of a hash only */
|
||||
|
@ -85,10 +101,18 @@ static inline void ns_sha256(const void *input, size_t ilen, void *output)
|
|||
static inline void ns_sha256_finish_nbits(ns_sha256_context *ctx, void *output, unsigned obits)
|
||||
{
|
||||
if (obits == 256) {
|
||||
#if (MBEDTLS_VERSION_MAJOR >= 3)
|
||||
(void)mbedtls_sha256_finish(ctx, output);
|
||||
#else
|
||||
(void)mbedtls_sha256_finish_ret(ctx, output);
|
||||
#endif
|
||||
} else {
|
||||
uint8_t sha256[32];
|
||||
#if (MBEDTLS_VERSION_MAJOR >= 3)
|
||||
(void)mbedtls_sha256_finish(ctx, sha256);
|
||||
#else
|
||||
(void)mbedtls_sha256_finish_ret(ctx, sha256);
|
||||
#endif
|
||||
memcpy(output, sha256, obits / 8);
|
||||
}
|
||||
}
|
||||
|
@ -96,10 +120,18 @@ static inline void ns_sha256_finish_nbits(ns_sha256_context *ctx, void *output,
|
|||
static inline void ns_sha256_nbits(const void *input, size_t ilen, void *output, unsigned obits)
|
||||
{
|
||||
if (obits == 256) {
|
||||
#if (MBEDTLS_VERSION_MAJOR >= 3)
|
||||
(void)mbedtls_sha256(input, ilen, output, 0);
|
||||
#else
|
||||
(void)mbedtls_sha256_ret(input, ilen, output, 0);
|
||||
#endif
|
||||
} else {
|
||||
uint8_t sha256[32];
|
||||
#if (MBEDTLS_VERSION_MAJOR >= 3)
|
||||
(void)mbedtls_sha256(input, ilen, sha256, 0);
|
||||
#else
|
||||
(void)mbedtls_sha256_ret(input, ilen, sha256, 0);
|
||||
#endif
|
||||
memcpy(output, sha256, obits / 8);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,24 @@
|
|||
|
||||
#include "ns_types.h"
|
||||
|
||||
/**
|
||||
* Time zone information structure.
|
||||
*
|
||||
* Daylight saving time and time zone information learned by network stack
|
||||
*
|
||||
*/
|
||||
typedef struct timezone_info {
|
||||
/** Timestamp of the Daylight saving time change*/
|
||||
uint64_t timestamp;
|
||||
/** Time zone information in minutes*/
|
||||
int16_t timezone;
|
||||
/** Change that is applied when timestamp is reached*/
|
||||
int16_t deviation;
|
||||
/** Time configuration status bit field
|
||||
* "bit xxxxxxxxxxxxxxxS" 0 = false 1 = true Daylight saving time status*/
|
||||
uint16_t status;
|
||||
} timezone_info_t;
|
||||
|
||||
/**
|
||||
* System time read callback.
|
||||
*
|
||||
|
@ -48,6 +66,22 @@ typedef uint64_t ns_time_api_system_time_callback(void);
|
|||
*/
|
||||
typedef void ns_time_api_system_time_write_callback(uint64_t write_time);
|
||||
|
||||
/**
|
||||
* New time zone and daylight saving time information learned from stack.
|
||||
*
|
||||
* Called when network stack learns the time zone and daylights saving time information.
|
||||
*
|
||||
* In Wi-SUN Border router can distribute this information to synchronize all nodes in network.
|
||||
* This information is updated roughly once a day using DHCPv6 protocol
|
||||
*
|
||||
* If network stack does not have the information this is not called and can be called when information becomes available.
|
||||
* This can be called multiple times with same information.
|
||||
*
|
||||
* \param info_ptr time zone and daylight saving time configuration.
|
||||
*
|
||||
*/
|
||||
typedef void ns_time_api_time_configuration_notify_callback(timezone_info_t *info_ptr);
|
||||
|
||||
/**
|
||||
* System time read callback set.
|
||||
*
|
||||
|
@ -68,4 +102,15 @@ void ns_time_api_system_time_callback_set(ns_time_api_system_time_callback callb
|
|||
*/
|
||||
void ns_time_api_system_time_write_callback_set(ns_time_api_system_time_write_callback callback_wr);
|
||||
|
||||
/**
|
||||
* Set system time configuration notify callback.
|
||||
*
|
||||
* Sets system time configuration notify callback that is called if network stack
|
||||
* learns time information from other devices in the network.
|
||||
*
|
||||
* \param callback_wr system time write callback.
|
||||
*
|
||||
*/
|
||||
void ns_time_api_time_configuration_notify_callback_set(ns_time_api_time_configuration_notify_callback callback_wr);
|
||||
|
||||
#endif /* NS_TIME_API_H_ */
|
||||
|
|
|
@ -143,6 +143,7 @@ typedef struct phy_signal_info_s {
|
|||
typedef struct phy_csma_params {
|
||||
uint32_t backoff_time; /**< CSMA Backoff us time before start CCA & TX. 0 should disable current backoff*/
|
||||
bool cca_enabled; /**< True will affect CCA check false start TX direct after backoff */
|
||||
bool mode_switch_phr; /**< True - Frame is a mode switch PHR. In this case PHY driver should skip FCS and send two byte PHR as it is given by TX callback */
|
||||
} phy_csma_params_t;
|
||||
|
||||
/** PHY modulation scheme */
|
||||
|
|
|
@ -74,6 +74,20 @@ typedef struct bbr_radius_timing {
|
|||
uint8_t radius_retry_count;
|
||||
} bbr_radius_timing_t;
|
||||
|
||||
/**
|
||||
* \brief Daylights saving time parameters.
|
||||
*/
|
||||
typedef struct bbr_timezone_configuration {
|
||||
/** Timestamp of the Daylight saving time change*/
|
||||
uint64_t timestamp;
|
||||
/** Time zone information in minutes*/
|
||||
int16_t timezone;
|
||||
/** Change that is applied when timestamp is reached*/
|
||||
int16_t deviation;
|
||||
/** Time configuration status bit field
|
||||
* "bit xxxxxxxxxxxxxxxS" 0 = false 1 = true Daylight saving time status*/
|
||||
uint16_t status;
|
||||
} bbr_timezone_configuration_t;
|
||||
/**
|
||||
* Start backbone border router service.
|
||||
*
|
||||
|
@ -521,4 +535,22 @@ int ws_bbr_radius_timing_validate(int8_t interface_id, bbr_radius_timing_t *timi
|
|||
*/
|
||||
int ws_bbr_dns_query_result_set(int8_t interface_id, const uint8_t address[16], char *domain_name_ptr);
|
||||
|
||||
/**
|
||||
* \brief A function to set time zone and daylights saving time configuration
|
||||
*
|
||||
* Border router distributes this information in DHCP Reply messages to
|
||||
* all the devices joining to the Wi-SUN mesh network.
|
||||
*
|
||||
* Border router keeps this information until reboot and continues to distribute the information.
|
||||
* If the information is changed the updates are sent to devices in network when they
|
||||
* renew their address. This can take time from 1 to 24 hours
|
||||
*
|
||||
* \param interface_id Network interface ID.
|
||||
* \param daylight_saving_time_ptr daylights saving time configuration. NULL if you want to remove the configuration.
|
||||
*
|
||||
* \return < 0 failure
|
||||
* \return >= 0 success
|
||||
*/
|
||||
int ws_bbr_timezone_configuration_set(int8_t interface_id, bbr_timezone_configuration_t *daylight_saving_time_ptr);
|
||||
|
||||
#endif /* WS_BBR_API_H_ */
|
||||
|
|
|
@ -78,6 +78,17 @@ extern "C" {
|
|||
#define CHANNEL_SPACING_800 0x05 /**< 800 khz */
|
||||
#define CHANNEL_SPACING_1200 0x06 /**< 1200 khz */
|
||||
|
||||
/*
|
||||
* Wi-SUN FAN 1.1 Phy capability types.
|
||||
*
|
||||
*/
|
||||
#define WS_PHY_TYPE_ID_FSK 0 /**< FSK phy type */
|
||||
#define WS_PHY_TYPE_ID_FSK_FEC 1 /**< FSK with FEC phy type */
|
||||
#define WS_PHY_TYPE_ID_OFDM1 2 /**< OFDM1 phy type */
|
||||
#define WS_PHY_TYPE_ID_OFDM2 3 /**< OFDM2 phy type */
|
||||
#define WS_PHY_TYPE_ID_OFDM3 4 /**< OFDM3 phy type */
|
||||
#define WS_PHY_TYPE_ID_OFDM4 5 /**< OFDM4 phy type */
|
||||
|
||||
/*
|
||||
* Network Size definitions are device amount in hundreds of devices.
|
||||
* These definitions are meant to give some estimates of sizes. Any value can be given as parameter
|
||||
|
@ -225,6 +236,28 @@ typedef struct ws_neighbour_info {
|
|||
ws_management_neighbor_type_e type;
|
||||
} ws_neighbour_info_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief ws_management_pcap_t Wi-SUN FAN 1.1 Phy Capability type and operating mode
|
||||
*/
|
||||
typedef struct ws_management_pcap {
|
||||
/** Phy type */
|
||||
uint8_t phy_type;
|
||||
/** Phy operating mode */
|
||||
uint16_t operating_mode;
|
||||
} ws_management_pcap_t;
|
||||
|
||||
/**
|
||||
* @brief ws_management_pcap_info_t Wi-SUN FAN 1.1 Phy Capability list for MDR support
|
||||
*/
|
||||
typedef struct ws_management_pcap_info {
|
||||
/** Length of the capability */
|
||||
uint8_t length_of_list: 3;
|
||||
/** Capability information */
|
||||
ws_management_pcap_t pcap[7];
|
||||
} ws_management_pcap_info_t;
|
||||
|
||||
|
||||
/**
|
||||
* Initialize Wi-SUN stack.
|
||||
*
|
||||
|
@ -875,6 +908,20 @@ int ws_device_min_sens_set(
|
|||
int8_t interface_id,
|
||||
uint8_t device_min_sens);
|
||||
|
||||
/**
|
||||
* Set Phy Capability support for MDR, FAN 1.1 feature
|
||||
*
|
||||
*
|
||||
* \param interface_id Network interface ID.
|
||||
* \param pcap_list pointer to supported list
|
||||
*
|
||||
* \return 0 Success.
|
||||
* \return <0 Failure.
|
||||
*/
|
||||
int ws_management_phy_capability_set(
|
||||
int8_t interface_id,
|
||||
ws_management_pcap_info_t *pcap_list);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -118,7 +118,7 @@ static uint8_t protocol_buffer_valid(buffer_t *b, protocol_interface_info_entry_
|
|||
|
||||
void protocol_init(void)
|
||||
{
|
||||
tr_debug("P.Init\n");
|
||||
tr_debug("P.Init");
|
||||
#ifdef PANA
|
||||
sec_libray_init();
|
||||
#endif
|
||||
|
@ -134,7 +134,7 @@ void protocol_6lowpan_stack(buffer_t *b)
|
|||
{
|
||||
protocol_interface_info_entry_t *cur = b->interface;
|
||||
if (protocol_buffer_valid(b, cur) == 0) {
|
||||
tr_debug("Drop Packets\n");
|
||||
tr_debug("Drop Packets");
|
||||
buffer_free(b);
|
||||
return;
|
||||
}
|
||||
|
@ -230,7 +230,7 @@ void protocol_6lowpan_stack(buffer_t *b)
|
|||
b = tcp_up(b);
|
||||
break;
|
||||
default:
|
||||
tr_debug("LLL\n");
|
||||
tr_debug("LLL");
|
||||
b = buffer_free(b);
|
||||
break;
|
||||
}
|
||||
|
@ -871,7 +871,7 @@ bool protocol_6lowpan_stagger_estimate_get(int8_t interface_id, uint32_t data_am
|
|||
}
|
||||
|
||||
// For small networks sets 10 seconds stagger
|
||||
if (network_size <= 100 && ws_info(cur_interface)) {
|
||||
if (ws_info(cur_interface) && (network_size <= 100 || ws_test_proc_auto_trg(cur_interface))) {
|
||||
stagger_value = 10;
|
||||
} else {
|
||||
stagger_value = 1 + ((data_amount * 1024 * 8 * network_size) / datarate);
|
||||
|
|
|
@ -1548,7 +1548,7 @@ int8_t arm_network_processor_up(protocol_interface_info_entry_t *cur)
|
|||
{
|
||||
int8_t ret_val = -1;
|
||||
if ((cur->configure_flags & INTERFACE_SETUP_NETWORK_DRIVER_MASK) != INTERFACE_SETUP_NETWORK_DRIVER_READY) {
|
||||
tr_debug("Interface not yet fully configured\n");
|
||||
tr_debug("Interface not yet fully configured");
|
||||
ret_val = -5;
|
||||
} else {
|
||||
protocol_6lowpan_register_handlers(cur);
|
||||
|
@ -2123,7 +2123,7 @@ static void nwk_rpl_dio_scan(protocol_interface_info_entry_t *cur)
|
|||
if (nwk_bootstrap_icmp_rpl_dis_msg_tx(cur)) {
|
||||
cur->bootsrap_state_machine_cnt = 45 << cur->nwk_rpl_scan_counter;
|
||||
cur->nwk_rpl_scan_counter++;
|
||||
tr_debug("MC_DIS\n");
|
||||
tr_debug("MC_DIS");
|
||||
cur->nwk_bootstrap_state = ER_RPL_SCAN;
|
||||
} else {
|
||||
cur->bootsrap_state_machine_cnt = 3;
|
||||
|
|
|
@ -476,13 +476,14 @@ void mac_helper_security_key_clean(protocol_interface_info_entry_t *interface)
|
|||
|
||||
void mac_helper_coordinator_address_set(protocol_interface_info_entry_t *interface, addrtype_t adr_type, uint8_t *adr_ptr)
|
||||
{
|
||||
uint16_t short_addr;
|
||||
mlme_set_t set_req;
|
||||
set_req.attr_index = 0;
|
||||
|
||||
if (adr_type == ADDR_802_15_4_SHORT) {
|
||||
memcpy(interface->mac_parameters->mac_cordinator_info.mac_mlme_coord_address, adr_ptr, 2);
|
||||
interface->mac_parameters->mac_cordinator_info.cord_adr_mode = MAC_ADDR_MODE_16_BIT;
|
||||
uint16_t short_addr = common_read_16_bit(interface->mac_parameters->mac_cordinator_info.mac_mlme_coord_address);
|
||||
short_addr = common_read_16_bit(interface->mac_parameters->mac_cordinator_info.mac_mlme_coord_address);
|
||||
set_req.attr = macCoordShortAddress;
|
||||
set_req.value_pointer = &short_addr;
|
||||
set_req.value_size = 2;
|
||||
|
|
|
@ -144,6 +144,33 @@ uint16_t mac_ie_nested_discover(uint8_t *payload_ptr, uint16_t length, mac_neste
|
|||
return 0;
|
||||
}
|
||||
|
||||
uint16_t mac_ie_nested_tagged_discover(uint8_t *payload_ptr, uint16_t length, mac_nested_payload_IE_t *nested_ie, uint8_t sub_tag_id)
|
||||
{
|
||||
mac_nested_payload_IE_t ie_element;
|
||||
uint8_t *sub_tag_ptr;
|
||||
while (length >= 2) {
|
||||
mac_ie_nested_id_parse(&ie_element, payload_ptr);
|
||||
|
||||
if (length < ie_element.length + 2) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
sub_tag_ptr = ie_element.content_ptr;
|
||||
if (ie_element.length > 1 && nested_ie->id == ie_element.id && *sub_tag_ptr == sub_tag_id) {
|
||||
sub_tag_ptr++;
|
||||
ie_element.length--;
|
||||
nested_ie->content_ptr = sub_tag_ptr;
|
||||
nested_ie->length = ie_element.length;
|
||||
return ie_element.length;
|
||||
}
|
||||
|
||||
length -= ie_element.length + 2;
|
||||
|
||||
payload_ptr += ie_element.length + 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t mac_ie_header_discover(uint8_t *header_ptr, uint16_t length, mac_header_IE_t *header_ie)
|
||||
{
|
||||
mac_header_IE_t ie_element;
|
||||
|
|
|
@ -49,6 +49,9 @@ uint16_t mac_ie_payload_discover(uint8_t *payload_ptr, uint16_t length, struct m
|
|||
/** Nested IE element discover inside parsed payload element */
|
||||
uint16_t mac_ie_nested_discover(uint8_t *payload_ptr, uint16_t length, mac_nested_payload_IE_t *nested_ie);
|
||||
|
||||
/** Nested IE element discover with Sub Tag ID inside parsed payload element */
|
||||
uint16_t mac_ie_nested_tagged_discover(uint8_t *payload_ptr, uint16_t length, mac_nested_payload_IE_t *nested_ie, uint8_t sub_tag_id);
|
||||
|
||||
/** Header IE elemnt discover */
|
||||
uint8_t mac_ie_header_discover(uint8_t *header_ptr, uint16_t length, struct mac_header_IE_s *header_ie);
|
||||
|
||||
|
|
|
@ -2308,7 +2308,7 @@ void thread_bootstrap_state_machine(protocol_interface_info_entry_t *cur)
|
|||
break;
|
||||
|
||||
case ER_BOOTSRAP_DONE:
|
||||
tr_debug("Thread SM:Bootstrap Done");
|
||||
tr_info("Thread SM:Bootstrap Done");
|
||||
cur->nwk_nd_re_scan_count = 0;
|
||||
break;
|
||||
case ER_BOOTSTRAP_SCAN_FAIL:
|
||||
|
|
|
@ -262,7 +262,7 @@ static int thread_commissioning_active_get_cb(int8_t service_id, uint8_t source_
|
|||
|
||||
if ((len = thread_meshcop_tlv_find(response_ptr->payload_ptr, response_ptr->payload_len, MESHCOP_TLV_NETWORK_MESH_LOCAL_ULA, &ptr)) > 0) {
|
||||
state = COMMISSIONING_STATE_ACCEPT;
|
||||
tr_debug(" TLV ml prefix=%s\r\n", trace_array(ptr, len));
|
||||
tr_debug(" TLV ml prefix=%s", trace_array(ptr, len));
|
||||
memcpy(this->leader_address, ptr, 8);
|
||||
memcpy(this->leader_address + 8, ADDR_SHORT_ADR_SUFFIC, 6);
|
||||
common_write_16_bit(0xfc00, this->leader_address + 14);
|
||||
|
|
|
@ -2006,7 +2006,7 @@ void thread_reset_neighbour_info(protocol_interface_info_entry_t *cur, mac_neigh
|
|||
|
||||
if (!thread_i_am_router(cur) && thread_endnode_parent && thread_endnode_parent->shortAddress == neighbour->mac16) {
|
||||
if (cur->nwk_bootstrap_state != ER_CHILD_ID_REQ) {
|
||||
tr_warn("End device lost parent, reset!\n");
|
||||
tr_warn("End device lost parent, reset!");
|
||||
thread_bootstrap_connection_error(cur->id, CON_PARENT_CONNECT_DOWN, NULL);
|
||||
}
|
||||
}
|
||||
|
@ -2238,18 +2238,18 @@ int thread_common_primary_bbr_get(struct protocol_interface_info_entry *cur, uin
|
|||
(service_tlv_ptr[0] & 0x80) && // THREAD_ENTERPRISE_NUMBER
|
||||
service_tlv_ptr[1] == 1 && // length 1
|
||||
service_tlv_ptr[2] == THREAD_SERVICE_DATA_BBR) {
|
||||
//tr_info("BBR service TLV: %s\r\n", trace_array(service_tlv_ptr, service_tlv_len));
|
||||
//tr_info("BBR service TLV: %s", trace_array(service_tlv_ptr, service_tlv_len));
|
||||
// try to parse SUB-TLVs
|
||||
// network_data_server_tlv_parse(service_tlv_ptr, tlv_length);
|
||||
uint16_t server_tlv_len = 0;
|
||||
uint8_t *server_tlv_ptr = thread_common_server_tlv_list_get(service_tlv_ptr, service_tlv_len, &server_tlv_len);
|
||||
uint16_t found_tlv_len;
|
||||
uint8_t *found_tlv = NULL;
|
||||
//tr_info("BBR server TLV: %s\r\n", trace_array(server_tlv_ptr, server_tlv_len));
|
||||
//tr_info("BBR server TLV: %s", trace_array(server_tlv_ptr, server_tlv_len));
|
||||
do {
|
||||
found_tlv_len = thread_meshcop_tlv_find_next(server_tlv_ptr, server_tlv_len, THREAD_NWK_DATA_TYPE_SERVER_DATA | THREAD_NWK_STABLE_DATA, &found_tlv);
|
||||
if (found_tlv && found_tlv_len > 8) {
|
||||
//tr_info("BBR server TLV: %s\r\n", trace_array(found_tlv, found_tlv_len));
|
||||
//tr_info("BBR server TLV: %s", trace_array(found_tlv, found_tlv_len));
|
||||
if (addr_ptr) {
|
||||
thread_addr_write_mesh_local_16(addr_ptr, common_read_16_bit(found_tlv), cur->thread_info);
|
||||
}
|
||||
|
|
|
@ -1137,7 +1137,7 @@ static void lowpan_data_request_to_mac(protocol_interface_info_entry_t *cur, buf
|
|||
} else {
|
||||
mcps_data_req_ie_list_t ie_list;
|
||||
memset(&ie_list, 0, sizeof(mcps_data_req_ie_list_t));
|
||||
cur->mac_api->mcps_data_req_ext(cur->mac_api, &dataReq, &ie_list, NULL, data_priority);
|
||||
cur->mac_api->mcps_data_req_ext(cur->mac_api, &dataReq, &ie_list, NULL, data_priority, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -70,7 +70,7 @@ static uint8_t current_instance_id = RPL_INSTANCE_ID;
|
|||
//TAG ID This must be update if NVM_BBR_INFO_LEN or data structure
|
||||
#define NVM_BBR_INFO_TAG 1
|
||||
// BSI 2 bytes
|
||||
#define NVM_BBR_INFO_LEN 2
|
||||
#define NVM_BBR_INFO_LEN 4
|
||||
|
||||
typedef struct bbr_info_nvm_tlv {
|
||||
uint16_t tag; /**< Unique tag */
|
||||
|
@ -97,6 +97,9 @@ static uint8_t current_global_prefix[16] = {0}; // DHCP requires 16 bytes prefix
|
|||
static uint32_t bbr_delay_timer = BBR_CHECK_INTERVAL; // initial delay.
|
||||
static uint32_t global_prefix_unavailable_timer = 0; // initial delay.
|
||||
|
||||
static bbr_timezone_configuration_t *bbr_time_config = NULL;
|
||||
|
||||
|
||||
static rpl_dodag_conf_t rpl_conf = {
|
||||
// Lifetime values
|
||||
.default_lifetime = 120,
|
||||
|
@ -132,41 +135,57 @@ static bbr_info_nvm_tlv_t bbr_info_nvm_tlv = {
|
|||
};
|
||||
|
||||
static uint16_t ws_bbr_fhss_bsi = 0;
|
||||
static uint16_t ws_bbr_pan_id = 0xffff;
|
||||
|
||||
static int8_t ws_bbr_nvm_info_read(bbr_info_nvm_tlv_t *tlv_entry)
|
||||
static int8_t ws_bbr_info_tlv_read(bbr_info_nvm_tlv_t *tlv_entry, uint16_t *bsi, uint16_t *pan_id)
|
||||
{
|
||||
tlv_entry->tag = NVM_BBR_INFO_TAG;
|
||||
tlv_entry->len = NVM_BBR_INFO_LEN;
|
||||
|
||||
int8_t ret_val = ws_pae_nvm_store_tlv_file_read(BBR_INFO_FILE, (nvm_tlv_t *) &bbr_info_nvm_tlv);
|
||||
|
||||
if (ret_val < 0 || tlv_entry->tag != NVM_BBR_INFO_TAG || tlv_entry->len != NVM_BBR_INFO_LEN) {
|
||||
ws_pae_nvm_store_tlv_file_remove(BBR_INFO_FILE);
|
||||
tlv_entry->len = 0;
|
||||
if (tlv_entry->tag != NVM_BBR_INFO_TAG || tlv_entry->len != NVM_BBR_INFO_LEN) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint8_t *tlv = (uint8_t *) &tlv_entry->data[0];
|
||||
|
||||
*bsi = common_read_16_bit(tlv);
|
||||
tlv += 2;
|
||||
*pan_id = common_read_16_bit(tlv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ws_bbr_nvm_info_write(bbr_info_nvm_tlv_t *tlv_entry)
|
||||
static void ws_bbr_info_tlv_write(bbr_info_nvm_tlv_t *tlv_entry, uint16_t bsi, uint16_t pan_id)
|
||||
{
|
||||
tlv_entry->tag = NVM_BBR_INFO_TAG;
|
||||
tlv_entry->len = NVM_BBR_INFO_LEN;
|
||||
ws_pae_nvm_store_tlv_file_write(BBR_INFO_FILE, (nvm_tlv_t *) tlv_entry);
|
||||
tr_debug("BBR info NVM update");
|
||||
|
||||
uint8_t *tlv = (uint8_t *) &tlv_entry->data[0];
|
||||
|
||||
tlv = common_write_16_bit(bsi, tlv);
|
||||
common_write_16_bit(pan_id, tlv);
|
||||
}
|
||||
|
||||
static uint16_t ws_bbr_bsi_read(bbr_info_nvm_tlv_t *tlv_entry)
|
||||
static int8_t ws_bbr_nvm_info_read(uint16_t *bsi, uint16_t *pan_id)
|
||||
{
|
||||
if (tlv_entry->tag != NVM_BBR_INFO_TAG || tlv_entry->len != NVM_BBR_INFO_LEN) {
|
||||
return 0;
|
||||
ws_pae_nvm_store_generic_tlv_create((nvm_tlv_t *) &bbr_info_nvm_tlv, NVM_BBR_INFO_TAG, NVM_BBR_INFO_LEN);
|
||||
|
||||
if (ws_pae_nvm_store_tlv_file_read(BBR_INFO_FILE, (nvm_tlv_t *) &bbr_info_nvm_tlv) < 0) {
|
||||
ws_pae_nvm_store_tlv_file_remove(BBR_INFO_FILE);
|
||||
return -1;
|
||||
}
|
||||
return common_read_16_bit(tlv_entry->data + BBR_NVM_BSI_OFFSET);
|
||||
|
||||
if (ws_bbr_info_tlv_read(&bbr_info_nvm_tlv, bsi, pan_id) < 0) {
|
||||
ws_pae_nvm_store_tlv_file_remove(BBR_INFO_FILE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ws_bbr_bsi_write(bbr_info_nvm_tlv_t *tlv_entry, uint16_t bsi)
|
||||
static void ws_bbr_nvm_info_write(uint16_t bsi, uint16_t pan_id)
|
||||
{
|
||||
common_write_16_bit(bsi, tlv_entry->data + BBR_NVM_BSI_OFFSET);
|
||||
ws_bbr_info_tlv_write(&bbr_info_nvm_tlv, bsi, pan_id);
|
||||
|
||||
ws_pae_nvm_store_tlv_file_write(BBR_INFO_FILE, (nvm_tlv_t *) &bbr_info_nvm_tlv);
|
||||
tr_debug("BBR info NVM update");
|
||||
}
|
||||
|
||||
static void ws_bbr_rpl_version_timer_start(protocol_interface_info_entry_t *cur, uint8_t version)
|
||||
|
@ -488,24 +507,32 @@ static uint8_t *ws_bbr_dhcp_server_dynamic_vendor_data_write(int8_t interfaceId,
|
|||
// If local time is not available vendor data is not written and data_len is not modified
|
||||
(void)interfaceId;
|
||||
|
||||
uint64_t time_read;
|
||||
uint64_t time_read = 0;
|
||||
|
||||
if (0 != ns_time_system_time_read(&time_read)) {
|
||||
return ptr;
|
||||
}
|
||||
ns_time_system_time_read(&time_read);
|
||||
|
||||
if (data_len) {
|
||||
*data_len += net_vendor_option_current_time_length();
|
||||
if (time_read) {
|
||||
*data_len += net_vendor_option_current_time_length();
|
||||
}
|
||||
if (bbr_time_config) {
|
||||
*data_len += net_vendor_option_time_configuration_length();
|
||||
}
|
||||
}
|
||||
if (!ptr) {
|
||||
return ptr;
|
||||
}
|
||||
time_read += 2208988800; // Time starts now from the 0 era instead of First day of Unix (1 Jan 1970)
|
||||
if (time_read) {
|
||||
time_read += 2208988800; // Time starts now from the 0 era instead of First day of Unix (1 Jan 1970)
|
||||
|
||||
uint32_t era = time_read / (uint64_t)(4294967296);
|
||||
uint32_t timestamp = time_read - (era * (uint64_t)(4294967296));
|
||||
ptr = net_vendor_option_current_time_write(ptr, era, timestamp, 0);
|
||||
uint32_t era = time_read / (uint64_t)(4294967296);
|
||||
uint32_t timestamp = time_read - (era * (uint64_t)(4294967296));
|
||||
ptr = net_vendor_option_current_time_write(ptr, era, timestamp, 0);
|
||||
}
|
||||
if (bbr_time_config) {
|
||||
ptr = net_vendor_option_time_configuration_write(ptr, bbr_time_config->timestamp, bbr_time_config->timezone, bbr_time_config->deviation, bbr_time_config->status);
|
||||
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
@ -953,24 +980,21 @@ static void ws_bbr_forwarding_cb(protocol_interface_info_entry_t *interface, buf
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ws_bbr_init(protocol_interface_info_entry_t *interface)
|
||||
{
|
||||
(void) interface;
|
||||
//Read From NVM
|
||||
if (ws_bbr_nvm_info_read(&bbr_info_nvm_tlv) < 0) {
|
||||
if (ws_bbr_nvm_info_read(&ws_bbr_fhss_bsi, &ws_bbr_pan_id) < 0) {
|
||||
//NVM value not available Randomize Value Here by first time
|
||||
ws_bbr_fhss_bsi = randLIB_get_16bit();
|
||||
tr_debug("Randomized init value BSI %u", ws_bbr_fhss_bsi);
|
||||
} else {
|
||||
ws_bbr_fhss_bsi = ws_bbr_bsi_read(&bbr_info_nvm_tlv);
|
||||
tr_debug("Read BSI %u from NVM", ws_bbr_fhss_bsi);
|
||||
tr_debug("Read PAN ID %u from NVM", ws_bbr_pan_id);
|
||||
}
|
||||
interface->if_common_forwarding_out_cb = &ws_bbr_forwarding_cb;
|
||||
}
|
||||
|
||||
|
||||
uint16_t ws_bbr_bsi_generate(protocol_interface_info_entry_t *interface)
|
||||
{
|
||||
(void) interface;
|
||||
|
@ -979,11 +1003,16 @@ uint16_t ws_bbr_bsi_generate(protocol_interface_info_entry_t *interface)
|
|||
//Update value for next round
|
||||
ws_bbr_fhss_bsi++;
|
||||
//Store To NVN
|
||||
ws_bbr_bsi_write(&bbr_info_nvm_tlv, ws_bbr_fhss_bsi);
|
||||
ws_bbr_nvm_info_write(&bbr_info_nvm_tlv);
|
||||
ws_bbr_nvm_info_write(ws_bbr_fhss_bsi, ws_bbr_pan_id);
|
||||
return bsi;
|
||||
}
|
||||
|
||||
uint16_t ws_bbr_pan_id_get(protocol_interface_info_entry_t *interface)
|
||||
{
|
||||
(void) interface;
|
||||
return ws_bbr_pan_id;
|
||||
}
|
||||
|
||||
#endif //HAVE_WS_BORDER_ROUTER
|
||||
|
||||
/* Public APIs
|
||||
|
@ -1188,7 +1217,7 @@ int ws_bbr_rpl_parameters_set(int8_t interface_id, uint8_t dio_interval_min, uin
|
|||
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
|
||||
|
||||
ws_bbr_cfg_t cfg;
|
||||
if (ws_cfg_bbr_get(&cfg, NULL) < 0) {
|
||||
if (ws_cfg_bbr_get(&cfg) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -1202,7 +1231,7 @@ int ws_bbr_rpl_parameters_set(int8_t interface_id, uint8_t dio_interval_min, uin
|
|||
cfg.dio_redundancy_constant = dio_redundancy_constant;
|
||||
}
|
||||
|
||||
if (ws_cfg_bbr_set(cur, NULL, &cfg, 0) < 0) {
|
||||
if (ws_cfg_bbr_set(cur, &cfg, 0) < 0) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
|
@ -1224,7 +1253,7 @@ int ws_bbr_rpl_parameters_get(int8_t interface_id, uint8_t *dio_interval_min, ui
|
|||
}
|
||||
|
||||
ws_bbr_cfg_t cfg;
|
||||
if (ws_cfg_bbr_get(&cfg, NULL) < 0) {
|
||||
if (ws_cfg_bbr_get(&cfg) < 0) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
|
@ -1246,7 +1275,7 @@ int ws_bbr_rpl_parameters_validate(int8_t interface_id, uint8_t dio_interval_min
|
|||
(void) interface_id;
|
||||
#ifdef HAVE_WS_BORDER_ROUTER
|
||||
ws_bbr_cfg_t cfg;
|
||||
if (ws_cfg_bbr_get(&cfg, NULL) < 0) {
|
||||
if (ws_cfg_bbr_get(&cfg) < 0) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
|
@ -1260,7 +1289,7 @@ int ws_bbr_rpl_parameters_validate(int8_t interface_id, uint8_t dio_interval_min
|
|||
cfg.dio_redundancy_constant = dio_redundancy_constant;
|
||||
}
|
||||
|
||||
if (ws_cfg_bbr_validate(NULL, &cfg) < 0) {
|
||||
if (ws_cfg_bbr_validate(&cfg) < 0) {
|
||||
return -3;
|
||||
}
|
||||
|
||||
|
@ -1289,8 +1318,7 @@ int ws_bbr_bsi_set(int8_t interface_id, uint16_t new_bsi)
|
|||
ws_bootstrap_restart_delayed(cur->id);
|
||||
}
|
||||
|
||||
ws_bbr_bsi_write(&bbr_info_nvm_tlv, new_bsi);
|
||||
ws_bbr_nvm_info_write(&bbr_info_nvm_tlv);
|
||||
ws_bbr_nvm_info_write(ws_bbr_fhss_bsi, ws_bbr_pan_id);
|
||||
ws_bbr_fhss_bsi = new_bsi;
|
||||
return 0;
|
||||
#else
|
||||
|
@ -1299,24 +1327,16 @@ int ws_bbr_bsi_set(int8_t interface_id, uint16_t new_bsi)
|
|||
#endif
|
||||
}
|
||||
|
||||
|
||||
int ws_bbr_pan_configuration_set(int8_t interface_id, uint16_t pan_id)
|
||||
{
|
||||
(void) interface_id;
|
||||
#ifdef HAVE_WS_BORDER_ROUTER
|
||||
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
|
||||
|
||||
ws_gen_cfg_t cfg;
|
||||
if (ws_cfg_gen_get(&cfg, NULL) < 0) {
|
||||
return -1;
|
||||
if (ws_bbr_pan_id != pan_id) {
|
||||
ws_bbr_pan_id = pan_id;
|
||||
// Store to NVM and restart bootstrap
|
||||
ws_bbr_nvm_info_write(ws_bbr_fhss_bsi, ws_bbr_pan_id);
|
||||
ws_bootstrap_restart_delayed(interface_id);
|
||||
}
|
||||
|
||||
cfg.network_pan_id = pan_id;
|
||||
|
||||
if (ws_cfg_gen_set(cur, NULL, &cfg, 0) < 0) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
#else
|
||||
(void) pan_id;
|
||||
|
@ -1332,12 +1352,7 @@ int ws_bbr_pan_configuration_get(int8_t interface_id, uint16_t *pan_id)
|
|||
return -1;
|
||||
}
|
||||
|
||||
ws_gen_cfg_t cfg;
|
||||
if (ws_cfg_gen_get(&cfg, NULL) < 0) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
*pan_id = cfg.network_pan_id;
|
||||
*pan_id = ws_bbr_pan_id;
|
||||
|
||||
return 0;
|
||||
#else
|
||||
|
@ -1349,21 +1364,10 @@ int ws_bbr_pan_configuration_get(int8_t interface_id, uint16_t *pan_id)
|
|||
int ws_bbr_pan_configuration_validate(int8_t interface_id, uint16_t pan_id)
|
||||
{
|
||||
(void) interface_id;
|
||||
(void) pan_id;
|
||||
#ifdef HAVE_WS_BORDER_ROUTER
|
||||
ws_gen_cfg_t cfg;
|
||||
if (ws_cfg_gen_get(&cfg, NULL) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
cfg.network_pan_id = pan_id;
|
||||
|
||||
if (ws_cfg_gen_validate(NULL, &cfg) < 0) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
#else
|
||||
(void) pan_id;
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
@ -1553,3 +1557,32 @@ update_information:
|
|||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
int ws_bbr_timezone_configuration_set(int8_t interface_id, bbr_timezone_configuration_t *daylight_saving_time_ptr)
|
||||
{
|
||||
#ifdef HAVE_WS_BORDER_ROUTER
|
||||
(void) interface_id;
|
||||
|
||||
if (!daylight_saving_time_ptr) {
|
||||
// Delete configuration
|
||||
ns_dyn_mem_free(bbr_time_config);
|
||||
bbr_time_config = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!bbr_time_config) {
|
||||
bbr_time_config = ns_dyn_mem_alloc(sizeof(bbr_timezone_configuration_t));
|
||||
}
|
||||
|
||||
if (!bbr_time_config) {
|
||||
return -2;
|
||||
}
|
||||
*bbr_time_config = *daylight_saving_time_ptr;
|
||||
|
||||
return 0;
|
||||
#else
|
||||
(void) interface_id;
|
||||
(void) daylight_saving_time_ptr;
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -38,6 +38,7 @@ bool ws_bbr_ready_to_start(protocol_interface_info_entry_t *cur);
|
|||
bool ws_bbr_backbone_address_get(uint8_t *address);
|
||||
|
||||
uint16_t ws_bbr_bsi_generate(protocol_interface_info_entry_t *interface);
|
||||
uint16_t ws_bbr_pan_id_get(protocol_interface_info_entry_t *interface);
|
||||
void ws_bbr_init(protocol_interface_info_entry_t *interface);
|
||||
|
||||
#else
|
||||
|
@ -50,6 +51,7 @@ void ws_bbr_init(protocol_interface_info_entry_t *interface);
|
|||
#define ws_bbr_ready_to_start(cur) true
|
||||
#define ws_bbr_backbone_address_get(address) 0
|
||||
#define ws_bbr_bsi_generate(interface) 0
|
||||
#define ws_bbr_pan_id_get(interface) 0
|
||||
#define ws_bbr_init(interface) (void) 0
|
||||
|
||||
#endif //HAVE_WS_BORDER_ROUTER
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -26,17 +26,53 @@ typedef enum {
|
|||
WS_OPERATION_START, /**< active operation start*/
|
||||
WS_ROUTING_READY, /**< RPL routing connected to BR*/
|
||||
WS_FAST_DISCONNECT, /**< Do fast timeout after Border router timeout*/
|
||||
WS_NORMAL_DISCONNECT /**< Border have been rebooted so Slow poison Process*/
|
||||
WS_NORMAL_DISCONNECT, /**< Border have been rebooted so Slow poison Process*/
|
||||
WS_TEST_PROC_TRIGGER /**< Trigger test procedure */
|
||||
} ws_bootsrap_event_type_e;
|
||||
|
||||
/* Bootstrap internal test procedures, these must match to ws_test_proc_t
|
||||
on net_ws_test_ext.h */
|
||||
typedef enum {
|
||||
PROCEDURE_DIS,
|
||||
PROCEDURE_DIO,
|
||||
PROCEDURE_DAO,
|
||||
|
||||
PROCEDURE_PAS,
|
||||
PROCEDURE_PA,
|
||||
PROCEDURE_PCS,
|
||||
PROCEDURE_PC,
|
||||
|
||||
PROCEDURE_EAPOL,
|
||||
PROCEDURE_RPL,
|
||||
PROCEDURE_AUTO_ON,
|
||||
PROCEDURE_AUTO_OFF,
|
||||
|
||||
/* Above must match to ws_test_proc_t */
|
||||
|
||||
PROCEDURE_PAS_TRICKLE_INCON,
|
||||
PROCEDURE_PCS_TRICKLE_INCON
|
||||
|
||||
} ws_bootsrap_procedure_t;
|
||||
|
||||
typedef enum {
|
||||
WS_PARENT_SOFT_SYNCH = 0, /**< let FHSS make decision if synchronization is needed*/
|
||||
WS_PARENT_HARD_SYNCH, /**< Synch FHSS with latest synch information*/
|
||||
WS_EAPOL_PARENT_SYNCH, /**< Broadcast synch with EAPOL parent*/
|
||||
} ws_parent_synch_e;
|
||||
|
||||
#ifdef HAVE_WS
|
||||
|
||||
//#include "6LoWPAN/ws/ws_llc.h"
|
||||
#include "6LoWPAN/ws/ws_common_defines.h"
|
||||
|
||||
struct rpl_instance;
|
||||
struct llc_neighbour_req;
|
||||
struct ws_us_ie;
|
||||
struct ws_bs_ie;
|
||||
struct ws_neighbor_class_entry;
|
||||
struct ws_stack_info;
|
||||
struct ws_neighbour_info;
|
||||
struct mcps_data_ie_list;
|
||||
struct mcps_data_ind_s;
|
||||
|
||||
extern uint16_t test_pan_version;
|
||||
|
||||
int ws_bootstrap_init(int8_t interface_id, net_6lowpan_mode_e bootstrap_mode);
|
||||
|
||||
|
@ -46,25 +82,10 @@ int ws_bootstrap_restart(int8_t interface_id);
|
|||
|
||||
int ws_bootstrap_restart_delayed(int8_t interface_id);
|
||||
|
||||
int ws_bootstrap_set_rf_config(protocol_interface_info_entry_t *cur, phy_rf_channel_configuration_s rf_configs);
|
||||
|
||||
int ws_bootstrap_neighbor_remove(protocol_interface_info_entry_t *cur, const uint8_t *ll_address);
|
||||
|
||||
int ws_bootstrap_aro_failure(protocol_interface_info_entry_t *cur, const uint8_t *ll_address);
|
||||
|
||||
/*State machine transactions*/
|
||||
void ws_bootstrap_event_discovery_start(protocol_interface_info_entry_t *cur);
|
||||
|
||||
void ws_bootstrap_event_configuration_start(protocol_interface_info_entry_t *cur);
|
||||
|
||||
void ws_bootstrap_event_authentication_start(protocol_interface_info_entry_t *cur);
|
||||
|
||||
void ws_bootstrap_event_operation_start(protocol_interface_info_entry_t *cur);
|
||||
|
||||
void ws_bootstrap_event_routing_ready(protocol_interface_info_entry_t *cur);
|
||||
|
||||
void ws_bootstrap_event_disconnect(protocol_interface_info_entry_t *cur, ws_bootsrap_event_type_e event_type);
|
||||
|
||||
void ws_bootstrap_configuration_trickle_reset(protocol_interface_info_entry_t *cur);
|
||||
|
||||
void ws_bootstrap_seconds_timer(protocol_interface_info_entry_t *cur, uint32_t seconds);
|
||||
|
@ -99,6 +120,84 @@ int ws_bootstrap_neighbor_info_get(protocol_interface_info_entry_t *cur, struct
|
|||
|
||||
void ws_bootstrap_mac_neighbor_short_time_set(struct protocol_interface_info_entry *interface, const uint8_t *src64, uint32_t valid_time);
|
||||
|
||||
int ws_bootstrap_test_procedure_trigger(protocol_interface_info_entry_t *cur, ws_bootsrap_procedure_t procedure);
|
||||
|
||||
/*
|
||||
* Functions shared with different bootstrap modes
|
||||
*/
|
||||
|
||||
bool ws_bootstrap_network_name_matches(const struct mcps_data_ie_list *ie_ext, const char *network_name_ptr);
|
||||
|
||||
/*State machine transactions*/
|
||||
void ws_bootstrap_event_discovery_start(protocol_interface_info_entry_t *cur);
|
||||
|
||||
void ws_bootstrap_event_configuration_start(protocol_interface_info_entry_t *cur);
|
||||
|
||||
void ws_bootstrap_event_authentication_start(protocol_interface_info_entry_t *cur);
|
||||
|
||||
void ws_bootstrap_event_operation_start(protocol_interface_info_entry_t *cur);
|
||||
|
||||
void ws_bootstrap_event_routing_ready(protocol_interface_info_entry_t *cur);
|
||||
|
||||
void ws_bootstrap_event_disconnect(protocol_interface_info_entry_t *cur, ws_bootsrap_event_type_e event_type);
|
||||
|
||||
void ws_bootstrap_test_procedure_trigger_exec(protocol_interface_info_entry_t *cur, ws_bootsrap_procedure_t procedure);
|
||||
|
||||
void ws_bootstrap_network_down(protocol_interface_info_entry_t *cur);
|
||||
|
||||
// Bootstrap functions
|
||||
void ws_bootstrap_start_authentication(protocol_interface_info_entry_t *cur);
|
||||
|
||||
|
||||
// Bootstrap state machine state Functions
|
||||
bool ws_bootstrap_state_discovery(struct protocol_interface_info_entry *cur);
|
||||
bool ws_bootstrap_state_authenticate(struct protocol_interface_info_entry *cur);
|
||||
bool ws_bootstrap_state_configure(struct protocol_interface_info_entry *cur);
|
||||
bool ws_bootstrap_state_wait_rpl(struct protocol_interface_info_entry *cur);
|
||||
bool ws_bootstrap_state_active(struct protocol_interface_info_entry *cur);
|
||||
void ws_bootstrap_state_disconnect(protocol_interface_info_entry_t *cur, ws_bootsrap_event_type_e event_type);
|
||||
void ws_bootstrap_state_change(protocol_interface_info_entry_t *cur, icmp_state_t nwk_bootstrap_state);
|
||||
|
||||
void ws_bootstrap_candidate_list_clean(struct protocol_interface_info_entry *cur, uint8_t pan_max, uint32_t current_time, uint16_t pan_id);
|
||||
void ws_bootstrap_candidate_parent_store(parent_info_t *parent, const struct mcps_data_ind_s *data, ws_utt_ie_t *ws_utt, ws_us_ie_t *ws_us, ws_pan_information_t *pan_information);
|
||||
void ws_bootstrap_candidate_table_reset(protocol_interface_info_entry_t *cur);
|
||||
parent_info_t *ws_bootstrap_candidate_parent_get(struct protocol_interface_info_entry *cur, const uint8_t *addr, bool create);
|
||||
void ws_bootstrap_candidate_parent_sort(struct protocol_interface_info_entry *cur, parent_info_t *new_entry);
|
||||
parent_info_t *ws_bootstrap_candidate_parent_get_best(protocol_interface_info_entry_t *cur);
|
||||
|
||||
void ws_bootstrap_primary_parent_set(struct protocol_interface_info_entry *cur, struct llc_neighbour_req *neighbor_info, ws_parent_synch_e synch_req);
|
||||
void ws_bootstrap_parent_confirm(protocol_interface_info_entry_t *cur, struct rpl_instance *instance);
|
||||
bool ws_bootstrap_neighbor_info_request(struct protocol_interface_info_entry *interface, const uint8_t *mac_64, struct llc_neighbour_req *neighbor_buffer, bool request_new);
|
||||
void ws_bootstrap_neighbor_list_clean(struct protocol_interface_info_entry *interface);
|
||||
int8_t ws_bootstrap_neighbor_set(protocol_interface_info_entry_t *cur, parent_info_t *parent_ptr, bool clear_list);
|
||||
void ws_nud_table_reset(protocol_interface_info_entry_t *cur);
|
||||
void ws_address_registration_update(protocol_interface_info_entry_t *interface, const uint8_t addr[16]);
|
||||
|
||||
|
||||
void ws_bootstrap_configure_csma_ca_backoffs(protocol_interface_info_entry_t *cur, uint8_t max_backoffs, uint8_t min_be, uint8_t max_be);
|
||||
void ws_bootstrap_fhss_configure_channel_masks(protocol_interface_info_entry_t *cur, fhss_ws_configuration_t *fhss_configuration);
|
||||
int8_t ws_bootstrap_fhss_set_defaults(protocol_interface_info_entry_t *cur, fhss_ws_configuration_t *fhss_configuration);
|
||||
void ws_bootstrap_fhss_activate(protocol_interface_info_entry_t *cur);
|
||||
uint16_t ws_bootstrap_randomize_fixed_channel(uint16_t configured_fixed_channel, uint8_t number_of_channels, uint32_t *channel_mask);
|
||||
int ws_bootstrap_set_domain_rf_config(protocol_interface_info_entry_t *cur);
|
||||
void ws_bootstrap_configure_max_retries(protocol_interface_info_entry_t *cur, uint8_t max_mac_retries);
|
||||
void ws_bootstrap_configure_data_request_restart(protocol_interface_info_entry_t *cur, uint8_t cca_failure_restart_max, uint8_t tx_failure_restart_max, uint16_t blacklist_min_ms, uint16_t blacklist_max_ms);
|
||||
|
||||
|
||||
void ws_bootstrap_llc_hopping_update(struct protocol_interface_info_entry *cur, const fhss_ws_configuration_t *fhss_configuration);
|
||||
|
||||
void ws_bootstrap_rpl_activate(protocol_interface_info_entry_t *cur);
|
||||
void ws_bootstrap_rpl_scan_start(protocol_interface_info_entry_t *cur);
|
||||
|
||||
void ws_bootstrap_ip_stack_reset(protocol_interface_info_entry_t *cur);
|
||||
void ws_bootstrap_ip_stack_activate(protocol_interface_info_entry_t *cur);
|
||||
|
||||
void ws_bootstrap_packet_congestion_init(protocol_interface_info_entry_t *cur);
|
||||
|
||||
void ws_bootstrap_asynch_trickle_stop(protocol_interface_info_entry_t *cur);
|
||||
void ws_bootstrap_advertise_start(protocol_interface_info_entry_t *cur);
|
||||
|
||||
void ws_bootstrap_network_start(protocol_interface_info_entry_t *cur);
|
||||
#else
|
||||
|
||||
#define ws_bootstrap_init(interface_id, bootstrap_mode) (-1)
|
||||
|
@ -111,6 +210,7 @@ void ws_bootstrap_mac_neighbor_short_time_set(struct protocol_interface_info_ent
|
|||
#define ws_bootstrap_secondary_parent_update(interface)
|
||||
#define ws_bootstrap_stack_info_get(cur, info_ptr)
|
||||
#define ws_bootstrap_neighbor_info_get(cur, neighbor_ptr, count)
|
||||
#define ws_bootstrap_test_procedure_trigger(cur, procedure);
|
||||
|
||||
|
||||
#endif //HAVE_WS
|
||||
|
|
|
@ -0,0 +1,479 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Pelion and affiliates.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "nsconfig.h"
|
||||
#if defined(HAVE_WS) && defined(HAVE_WS_BORDER_ROUTER)
|
||||
#include "ns_types.h"
|
||||
#include "ns_trace.h"
|
||||
#include "nsdynmemLIB.h"
|
||||
#include "net_interface.h"
|
||||
#include "eventOS_event.h"
|
||||
#include "randLIB.h"
|
||||
#include "common_functions.h"
|
||||
#include "mac_common_defines.h"
|
||||
#include "sw_mac.h"
|
||||
#include "ccmLIB.h"
|
||||
#include "Core/include/ns_monitor.h"
|
||||
#include "NWK_INTERFACE/Include/protocol.h"
|
||||
#include "6LoWPAN/Bootstraps/protocol_6lowpan.h"
|
||||
#include "6LoWPAN/Bootstraps/protocol_6lowpan_interface.h"
|
||||
#include "ipv6_stack/protocol_ipv6.h"
|
||||
#include "ipv6_stack/ipv6_routing_table.h"
|
||||
#include "6LoWPAN/MAC/mac_helper.h"
|
||||
#include "6LoWPAN/MAC/mac_data_poll.h"
|
||||
#include "6LoWPAN/MAC/mpx_api.h"
|
||||
#include "6LoWPAN/MAC/mac_ie_lib.h"
|
||||
#include "MPL/mpl.h"
|
||||
#include "RPL/rpl_protocol.h"
|
||||
#include "RPL/rpl_control.h"
|
||||
#include "RPL/rpl_data.h"
|
||||
#include "RPL/rpl_policy.h"
|
||||
#include "Common_Protocols/icmpv6.h"
|
||||
#include "Common_Protocols/icmpv6_radv.h"
|
||||
#include "Common_Protocols/ipv6_constants.h"
|
||||
#include "Common_Protocols/ip.h"
|
||||
#include "Service_Libs/Trickle/trickle.h"
|
||||
#include "Service_Libs/fhss/channel_list.h"
|
||||
#include "Service_Libs/utils/ns_time.h"
|
||||
#include "6LoWPAN/ws/ws_common_defines.h"
|
||||
#include "6LoWPAN/ws/ws_common_defines.h"
|
||||
#include "6LoWPAN/ws/ws_config.h"
|
||||
#include "6LoWPAN/ws/ws_common.h"
|
||||
#include "6LoWPAN/ws/ws_bootstrap.h"
|
||||
#include "6LoWPAN/ws/ws_bbr_api_internal.h"
|
||||
#include "6LoWPAN/ws/ws_common_defines.h"
|
||||
#include "6LoWPAN/ws/ws_llc.h"
|
||||
#include "6LoWPAN/ws/ws_neighbor_class.h"
|
||||
#include "6LoWPAN/ws/ws_ie_lib.h"
|
||||
#include "6LoWPAN/ws/ws_stats.h"
|
||||
#include "6LoWPAN/ws/ws_cfg_settings.h"
|
||||
#include "6LoWPAN/lowpan_adaptation_interface.h"
|
||||
#include "Service_Libs/etx/etx.h"
|
||||
#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h"
|
||||
#include "Service_Libs/nd_proxy/nd_proxy.h"
|
||||
#include "Service_Libs/blacklist/blacklist.h"
|
||||
#include "platform/topo_trace.h"
|
||||
#include "dhcp_service_api.h"
|
||||
#include "libDHCPv6/libDHCPv6.h"
|
||||
#include "libDHCPv6/libDHCPv6_vendordata.h"
|
||||
#include "DHCPv6_client/dhcpv6_client_api.h"
|
||||
#include "ws_management_api.h"
|
||||
#include "net_rpl.h"
|
||||
#include "mac_api.h"
|
||||
#include "6LoWPAN/ws/ws_pae_controller.h"
|
||||
#include "6LoWPAN/ws/ws_eapol_pdu.h"
|
||||
#include "6LoWPAN/ws/ws_eapol_auth_relay.h"
|
||||
#include "6LoWPAN/ws/ws_eapol_relay.h"
|
||||
#include "libNET/src/net_dns_internal.h"
|
||||
#include "Service_Libs/random_early_detection/random_early_detection_api.h"
|
||||
|
||||
|
||||
#define TRACE_GROUP "wsbs"
|
||||
|
||||
static int8_t ws_bootstrap_6lbr_fhss_configure(protocol_interface_info_entry_t *cur)
|
||||
{
|
||||
// Read configuration of existing FHSS and start using the default values for any network
|
||||
fhss_ws_configuration_t fhss_configuration = ws_common_get_current_fhss_configuration(cur);
|
||||
//GET BSI from BBR module
|
||||
fhss_configuration.bsi = ws_bbr_bsi_generate(cur);
|
||||
ws_bootstrap_fhss_configure_channel_masks(cur, &fhss_configuration);
|
||||
// Randomize fixed channels. Only used if channel plan is fixed.
|
||||
cur->ws_info->cfg->fhss.fhss_uc_fixed_channel = ws_bootstrap_randomize_fixed_channel(cur->ws_info->cfg->fhss.fhss_uc_fixed_channel, cur->ws_info->hopping_schdule.number_of_channels, fhss_configuration.channel_mask);
|
||||
cur->ws_info->cfg->fhss.fhss_bc_fixed_channel = ws_bootstrap_randomize_fixed_channel(cur->ws_info->cfg->fhss.fhss_bc_fixed_channel, cur->ws_info->hopping_schdule.number_of_channels, fhss_configuration.channel_mask);
|
||||
ws_bootstrap_fhss_set_defaults(cur, &fhss_configuration);
|
||||
ns_fhss_ws_configuration_set(cur->ws_info->fhss_api, &fhss_configuration);
|
||||
ws_bootstrap_llc_hopping_update(cur, &fhss_configuration);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int8_t ws_bootstrap_6lbr_backbone_ip_addr_get(protocol_interface_info_entry_t *interface_ptr, uint8_t *address)
|
||||
{
|
||||
(void) interface_ptr;
|
||||
(void) address;
|
||||
|
||||
if (ws_bbr_backbone_address_get(address)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void ws_bootstrap_6lbr_eapol_congestion_init(protocol_interface_info_entry_t *cur)
|
||||
{
|
||||
random_early_detection_free(cur->llc_random_early_detection);
|
||||
cur->llc_random_early_detection = NULL;
|
||||
|
||||
if (cur->llc_random_early_detection == NULL) {
|
||||
cur->llc_random_early_detection = random_early_detection_create(
|
||||
cur->ws_info->cfg->sec_prot.max_simult_sec_neg_tx_queue_min,
|
||||
cur->ws_info->cfg->sec_prot.max_simult_sec_neg_tx_queue_max,
|
||||
100, RED_AVERAGE_WEIGHT_EIGHTH);
|
||||
}
|
||||
|
||||
random_early_detection_free(cur->llc_eapol_random_early_detection);
|
||||
cur->llc_eapol_random_early_detection = NULL;
|
||||
|
||||
if (cur->llc_eapol_random_early_detection == NULL) {
|
||||
cur->llc_eapol_random_early_detection = random_early_detection_create(
|
||||
cur->ws_info->cfg->sec_prot.max_simult_sec_neg_tx_queue_min,
|
||||
cur->ws_info->cfg->sec_prot.max_simult_sec_neg_tx_queue_max,
|
||||
100, RED_AVERAGE_WEIGHT_EIGHTH);
|
||||
}
|
||||
}
|
||||
|
||||
static void ws_bootstrap_6lbr_pan_config_analyse(struct protocol_interface_info_entry *cur, const struct mcps_data_ind_s *data, const struct mcps_data_ie_list *ie_ext, ws_utt_ie_t *ws_utt, ws_us_ie_t *ws_us)
|
||||
{
|
||||
ws_bs_ie_t ws_bs_ie;
|
||||
ws_bt_ie_t ws_bt_ie;
|
||||
llc_neighbour_req_t neighbor_info;
|
||||
|
||||
if (data->SrcPANId != cur->ws_info->network_pan_id) {
|
||||
return;
|
||||
}
|
||||
if (!ws_wh_bt_read(ie_ext->headerIeList, ie_ext->headerIeListLength, &ws_bt_ie)) {
|
||||
tr_warn("BT-IE");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ws_wp_nested_bs_read(ie_ext->payloadIeList, ie_ext->payloadIeListLength, &ws_bs_ie)) {
|
||||
// Corrupted
|
||||
tr_error("No broadcast schedule");
|
||||
return;
|
||||
}
|
||||
|
||||
//If we are border router or learned configuration we only update already learned neighbours.
|
||||
|
||||
if (ws_bootstrap_neighbor_info_request(cur, data->SrcAddr, &neighbor_info, false)) {
|
||||
//Update Neighbor Broadcast and Unicast Parameters
|
||||
ws_neighbor_class_neighbor_unicast_time_info_update(neighbor_info.ws_neighbor, ws_utt, data->timestamp, (uint8_t *) data->SrcAddr);
|
||||
ws_neighbor_class_neighbor_unicast_schedule_set(neighbor_info.ws_neighbor, ws_us, &cur->ws_info->hopping_schdule);
|
||||
ws_neighbor_class_neighbor_broadcast_time_info_update(neighbor_info.ws_neighbor, &ws_bt_ie, data->timestamp);
|
||||
ws_neighbor_class_neighbor_broadcast_schedule_set(neighbor_info.ws_neighbor, &ws_bs_ie);
|
||||
}
|
||||
}
|
||||
|
||||
static void ws_bootstrap_6lbr_pan_config_solicit_analyse(struct protocol_interface_info_entry *cur, const struct mcps_data_ind_s *data, ws_utt_ie_t *ws_utt, ws_us_ie_t *ws_us)
|
||||
{
|
||||
llc_neighbour_req_t neighbor_info;
|
||||
|
||||
if (data->SrcPANId != cur->ws_info->network_pan_id) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ws_bootstrap_neighbor_info_request(cur, data->SrcAddr, &neighbor_info, false)) {
|
||||
ws_neighbor_class_neighbor_unicast_time_info_update(neighbor_info.ws_neighbor, ws_utt, data->timestamp, (uint8_t *) data->SrcAddr);
|
||||
ws_neighbor_class_neighbor_unicast_schedule_set(neighbor_info.ws_neighbor, ws_us, &cur->ws_info->hopping_schdule);
|
||||
}
|
||||
}
|
||||
|
||||
void ws_bootstrap_6lbr_asynch_ind(struct protocol_interface_info_entry *cur, const struct mcps_data_ind_s *data, const struct mcps_data_ie_list *ie_ext, uint8_t message_type)
|
||||
{
|
||||
// Store weakest heard packet RSSI
|
||||
if (cur->ws_info->weakest_received_rssi > data->signal_dbm) {
|
||||
cur->ws_info->weakest_received_rssi = data->signal_dbm;
|
||||
}
|
||||
|
||||
if (data->SrcAddrMode != MAC_ADDR_MODE_64_BIT) {
|
||||
// Not from long address
|
||||
return;
|
||||
}
|
||||
ws_stats_update(cur, STATS_WS_ASYNCH_RX, 1);
|
||||
//Validate network name
|
||||
switch (message_type) {
|
||||
case WS_FT_PAN_ADVERT:
|
||||
case WS_FT_PAN_ADVERT_SOL:
|
||||
case WS_FT_PAN_CONF_SOL:
|
||||
//Check Network Name
|
||||
if (!ws_bootstrap_network_name_matches(ie_ext, cur->ws_info->cfg->gen.network_name)) {
|
||||
// Not in our network
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case WS_FT_PAN_CONF:
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
//UTT-IE and US-IE are mandatory for all Asynch Messages
|
||||
ws_utt_ie_t ws_utt;
|
||||
if (!ws_wh_utt_read(ie_ext->headerIeList, ie_ext->headerIeListLength, &ws_utt)) {
|
||||
// Corrupted
|
||||
return;
|
||||
}
|
||||
|
||||
ws_us_ie_t ws_us;
|
||||
if (!ws_wp_nested_us_read(ie_ext->payloadIeList, ie_ext->payloadIeListLength, &ws_us)) {
|
||||
// Corrupted
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ws_bootstrap_validate_channel_plan(&ws_us, cur) ||
|
||||
!ws_bootstrap_validate_channel_function(&ws_us, NULL)) {
|
||||
return;
|
||||
}
|
||||
|
||||
//Handle Message's
|
||||
switch (message_type) {
|
||||
case WS_FT_PAN_ADVERT:
|
||||
// Analyse Advertisement
|
||||
ws_stats_update(cur, STATS_WS_ASYNCH_RX_PA, 1);
|
||||
tr_info("received ADVERT Src:%s panid:%x rssi:%d", trace_array(data->SrcAddr, 8), data->SrcPANId, data->signal_dbm);
|
||||
// Border routers do not do any analysing on the Advertisements heard from others
|
||||
// in future if we need PANID conflict detection we could use this
|
||||
break;
|
||||
case WS_FT_PAN_ADVERT_SOL:
|
||||
ws_stats_update(cur, STATS_WS_ASYNCH_RX_PAS, 1);
|
||||
tr_info("received ADVERT SOL Src:%s rssi:%d", trace_array(data->SrcAddr, 8), data->signal_dbm);
|
||||
trickle_inconsistent_heard(&cur->ws_info->trickle_pan_advertisement, &cur->ws_info->trickle_params_pan_discovery);
|
||||
|
||||
break;
|
||||
case WS_FT_PAN_CONF:
|
||||
ws_stats_update(cur, STATS_WS_ASYNCH_RX_PC, 1);
|
||||
tr_info("received CONFIG Src:%s rssi:%d", trace_array(data->SrcAddr, 8), data->signal_dbm);
|
||||
ws_bootstrap_6lbr_pan_config_analyse(cur, data, ie_ext, &ws_utt, &ws_us);
|
||||
break;
|
||||
case WS_FT_PAN_CONF_SOL:
|
||||
ws_stats_update(cur, STATS_WS_ASYNCH_RX_PCS, 1);
|
||||
tr_info("received CONFIG SOL Src:%s rssi:%d", trace_array(data->SrcAddr, 8), data->signal_dbm);
|
||||
trickle_inconsistent_heard(&cur->ws_info->trickle_pan_config, &cur->ws_info->trickle_params_pan_discovery);
|
||||
ws_bootstrap_6lbr_pan_config_solicit_analyse(cur, data, &ws_utt, &ws_us);
|
||||
default:
|
||||
// Unknown message do not process
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ws_bootstrap_6lbr_asynch_confirm(struct protocol_interface_info_entry *interface, uint8_t asynch_message)
|
||||
{
|
||||
ws_stats_update(interface, STATS_WS_ASYNCH_TX, 1);
|
||||
if (interface->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER) {
|
||||
if (asynch_message == WS_FT_PAN_CONF && interface->ws_info->pending_key_index_info.state == PENDING_KEY_INDEX_ACTIVATE) {
|
||||
interface->ws_info->pending_key_index_info.state = NO_PENDING_PROCESS;
|
||||
tr_info("Activate new default key %u", interface->ws_info->pending_key_index_info.index + 1);
|
||||
mac_helper_security_auto_request_key_index_set(interface, interface->ws_info->pending_key_index_info.index, interface->ws_info->pending_key_index_info.index + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ws_bootstrap_6lbr_event_handler(protocol_interface_info_entry_t *cur, arm_event_s *event)
|
||||
{
|
||||
ws_bootsrap_event_type_e event_type;
|
||||
event_type = (ws_bootsrap_event_type_e)event->event_type;
|
||||
|
||||
switch (event_type) {
|
||||
case WS_INIT_EVENT:
|
||||
tr_debug("tasklet init");
|
||||
break;
|
||||
case WS_DISCOVERY_START:
|
||||
tr_info("Discovery start");
|
||||
protocol_mac_reset(cur);
|
||||
ws_llc_reset(cur);
|
||||
lowpan_adaptation_interface_reset(cur->id);
|
||||
//Clear Pending Key Index State
|
||||
cur->ws_info->pending_key_index_info.state = NO_PENDING_PROCESS;
|
||||
cur->mac_parameters->mac_default_key_index = 0;
|
||||
|
||||
ipv6_destination_cache_clean(cur->id);
|
||||
|
||||
// Clear parent blacklist
|
||||
blacklist_clear();
|
||||
|
||||
// All trickle timers stopped to allow entry from any state
|
||||
ws_bootstrap_asynch_trickle_stop(cur);
|
||||
//Init Packet congestion
|
||||
ws_bootstrap_packet_congestion_init(cur);
|
||||
|
||||
tr_info("Border router start network");
|
||||
|
||||
|
||||
if (!ws_bbr_ready_to_start(cur)) {
|
||||
// Wi-SUN not started yet we wait for Border router permission
|
||||
ws_bootstrap_state_change(cur, ER_WAIT_RESTART);
|
||||
cur->nwk_nd_re_scan_count = randLIB_get_random_in_range(40, 100);
|
||||
return;
|
||||
}
|
||||
// Clear Old information from stack
|
||||
cur->ws_info->network_pan_id = 0xffff;
|
||||
cur->ws_info->pan_information.pan_version_set = false;
|
||||
ws_nud_table_reset(cur);
|
||||
ws_bootstrap_neighbor_list_clean(cur);
|
||||
ws_bootstrap_ip_stack_reset(cur);
|
||||
ws_pae_controller_auth_init(cur);
|
||||
|
||||
uint16_t pan_id = ws_bbr_pan_id_get(cur);
|
||||
if (pan_id != 0xffff) {
|
||||
cur->ws_info->network_pan_id = pan_id;
|
||||
} else {
|
||||
if (cur->ws_info->network_pan_id == 0xffff) {
|
||||
cur->ws_info->network_pan_id = randLIB_get_random_in_range(0, 0xfffd);
|
||||
}
|
||||
}
|
||||
if (!cur->ws_info->pan_information.pan_version_set) {
|
||||
cur->ws_info->pan_information.pan_version = randLIB_get_random_in_range(0, 0xffff);
|
||||
cur->ws_info->pan_information.pan_version_set = true;
|
||||
}
|
||||
cur->ws_info->pan_information.pan_size = 0;
|
||||
cur->ws_info->pan_information.routing_cost = 0;
|
||||
cur->ws_info->pan_information.rpl_routing_method = true;
|
||||
cur->ws_info->pan_information.use_parent_bs = true;
|
||||
cur->ws_info->pan_information.version = WS_FAN_VERSION_1_0;
|
||||
// initialize for FAN 1.1 defaults
|
||||
if (ws_version_1_1(cur)) {
|
||||
cur->ws_info->pan_information.version = WS_FAN_VERSION_1_1;
|
||||
#ifdef HAVE_WS_VERSION_1_1
|
||||
if (!cur->ws_info->lfngtk.lfn_version_learned) {
|
||||
//Randomize LFN version
|
||||
cur->ws_info->lfngtk.lfn_version = randLIB_get_random_in_range(0, 0xffff);
|
||||
cur->ws_info->lfngtk.lfn_version_learned = true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
uint8_t *gtkhash = ws_pae_controller_gtk_hash_ptr_get(cur);
|
||||
ws_llc_set_gtkhash(cur, gtkhash);
|
||||
ws_bbr_pan_version_increase(cur);
|
||||
|
||||
// Set default parameters for FHSS when starting a discovery
|
||||
ws_common_regulatory_domain_config(cur, &cur->ws_info->hopping_schdule);
|
||||
ws_bootstrap_6lbr_fhss_configure(cur);
|
||||
ws_bootstrap_set_domain_rf_config(cur);
|
||||
ws_bootstrap_fhss_activate(cur);
|
||||
ns_fhss_ws_set_hop_count(cur->ws_info->fhss_api, 0);
|
||||
|
||||
uint8_t ll_addr[16];
|
||||
addr_interface_get_ll_address(cur, ll_addr, 1);
|
||||
|
||||
//SET EAPOL authenticator EUI64
|
||||
ws_pae_controller_border_router_addr_write(cur, cur->mac);
|
||||
|
||||
// Set EAPOL relay to port 10255 and authenticator relay to 10253 (and to own ll address)
|
||||
ws_eapol_relay_start(cur, BR_EAPOL_RELAY_SOCKET_PORT, ll_addr, EAPOL_RELAY_SOCKET_PORT);
|
||||
|
||||
// Set authenticator relay to port 10253 and PAE to 10254 (and to own ll address)
|
||||
ws_eapol_auth_relay_start(cur, EAPOL_RELAY_SOCKET_PORT, ll_addr, PAE_AUTH_SOCKET_PORT);
|
||||
|
||||
// Set PAN ID and network name to controller
|
||||
ws_pae_controller_nw_info_set(cur, cur->ws_info->network_pan_id, cur->ws_info->pan_information.pan_version, cur->ws_info->cfg->gen.network_name);
|
||||
|
||||
// Set backbone IP address get callback
|
||||
ws_pae_controller_auth_cb_register(cur, ws_bootstrap_6lbr_backbone_ip_addr_get);
|
||||
|
||||
// Set PAE port to 10254 and authenticator relay to 10253 (and to own ll address)
|
||||
ws_pae_controller_authenticator_start(cur, PAE_AUTH_SOCKET_PORT, ll_addr, EAPOL_RELAY_SOCKET_PORT);
|
||||
|
||||
// Initialize eapol congestion tracking
|
||||
ws_bootstrap_6lbr_eapol_congestion_init(cur);
|
||||
|
||||
// Set retry configuration for bootstrap ready state
|
||||
ws_bootstrap_configure_max_retries(cur, WS_MAX_FRAME_RETRIES);
|
||||
|
||||
// Set TX failure request restart configuration
|
||||
ws_bootstrap_configure_data_request_restart(cur, WS_CCA_REQUEST_RESTART_MAX, WS_TX_REQUEST_RESTART_MAX, WS_REQUEST_RESTART_BLACKLIST_MIN, WS_REQUEST_RESTART_BLACKLIST_MAX);
|
||||
|
||||
// Set CSMA-CA backoff configuration
|
||||
ws_bootstrap_configure_csma_ca_backoffs(cur, WS_MAX_CSMA_BACKOFFS, WS_MAC_MIN_BE, WS_MAC_MAX_BE);
|
||||
|
||||
ws_bootstrap_event_operation_start(cur);
|
||||
break;
|
||||
|
||||
case WS_CONFIGURATION_START:
|
||||
tr_info("6LBR Configuration start");
|
||||
break;
|
||||
case WS_OPERATION_START:
|
||||
tr_info("operation start");
|
||||
// Advertisements stopped during the RPL scan
|
||||
ws_bootstrap_asynch_trickle_stop(cur);
|
||||
// Activate RPL
|
||||
// Activate IPv6 stack
|
||||
ws_bootstrap_ip_stack_activate(cur);
|
||||
ws_bootstrap_rpl_activate(cur);
|
||||
ws_bootstrap_network_start(cur);
|
||||
// Wait for RPL start
|
||||
ws_bootstrap_event_routing_ready(cur);
|
||||
break;
|
||||
case WS_ROUTING_READY:
|
||||
tr_info("Routing ready");
|
||||
// stopped all to make sure we can enter here from any state
|
||||
ws_bootstrap_asynch_trickle_stop(cur);
|
||||
|
||||
// Indicate PAE controller that bootstrap is ready
|
||||
ws_pae_controller_bootstrap_done(cur);
|
||||
|
||||
ws_bootstrap_advertise_start(cur);
|
||||
ws_bootstrap_state_change(cur, ER_BOOTSRAP_DONE);
|
||||
break;
|
||||
case WS_FAST_DISCONNECT:
|
||||
ws_bootstrap_state_disconnect(cur, WS_FAST_DISCONNECT);
|
||||
break;
|
||||
case WS_NORMAL_DISCONNECT:
|
||||
ws_bootstrap_state_disconnect(cur, WS_NORMAL_DISCONNECT);
|
||||
break;
|
||||
|
||||
case WS_TEST_PROC_TRIGGER:
|
||||
ws_bootstrap_test_procedure_trigger_exec(cur, (ws_bootsrap_procedure_t) event->data_ptr);
|
||||
break;
|
||||
|
||||
default:
|
||||
tr_err("Invalid event received");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ws_bootstrap_6lbr_state_machine(protocol_interface_info_entry_t *cur)
|
||||
{
|
||||
|
||||
switch (cur->nwk_bootstrap_state) {
|
||||
case ER_WAIT_RESTART:
|
||||
tr_debug("WS SM:Wait for startup");
|
||||
ws_bootstrap_event_discovery_start(cur);
|
||||
break;
|
||||
case ER_ACTIVE_SCAN:
|
||||
tr_debug("WS SM:Active Scan");
|
||||
break;
|
||||
case ER_SCAN:
|
||||
tr_debug("WS SM:configuration Scan");
|
||||
break;
|
||||
case ER_PANA_AUTH:
|
||||
tr_info("authentication start");
|
||||
break;
|
||||
case ER_RPL_SCAN:
|
||||
tr_debug("WS SM:Wait RPL to contact DODAG root");
|
||||
break;
|
||||
case ER_BOOTSRAP_DONE:
|
||||
tr_info("WS SM:Bootstrap Done");
|
||||
// Bootstrap_done event to application
|
||||
nwk_bootsrap_state_update(ARM_NWK_BOOTSTRAP_READY, cur);
|
||||
break;
|
||||
case ER_RPL_NETWORK_LEAVING:
|
||||
tr_debug("WS SM:RPL Leaving ready trigger discovery");
|
||||
ws_bootstrap_event_discovery_start(cur);
|
||||
break;
|
||||
default:
|
||||
tr_warn("WS SM:Invalid state %d", cur->nwk_bootstrap_state);
|
||||
}
|
||||
}
|
||||
|
||||
void ws_bootstrap_6lbr_seconds_timer(protocol_interface_info_entry_t *cur, uint32_t seconds)
|
||||
{
|
||||
(void)cur;
|
||||
(void)seconds;
|
||||
}
|
||||
|
||||
|
||||
#endif //HAVE_WS_BORDER_ROUTER && HAVE_WS
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Pelion and affiliates.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef WS_BOOTSTRAP_6LBR_H_
|
||||
#define WS_BOOTSTRAP_6LBR_H_
|
||||
|
||||
#if defined(HAVE_WS) && defined(HAVE_WS_BORDER_ROUTER)
|
||||
|
||||
void ws_bootstrap_6lbr_asynch_ind(struct protocol_interface_info_entry *cur, const struct mcps_data_ind_s *data, const struct mcps_data_ie_list *ie_ext, uint8_t message_type);
|
||||
void ws_bootstrap_6lbr_asynch_confirm(struct protocol_interface_info_entry *interface, uint8_t asynch_message);
|
||||
void ws_bootstrap_6lbr_event_handler(protocol_interface_info_entry_t *cur, arm_event_s *event);
|
||||
void ws_bootstrap_6lbr_state_machine(protocol_interface_info_entry_t *cur);
|
||||
void ws_bootstrap_6lbr_seconds_timer(protocol_interface_info_entry_t *cur, uint32_t seconds);
|
||||
|
||||
#define wisun_mode_border_router(cur) (cur->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER)
|
||||
|
||||
#else
|
||||
|
||||
#define ws_bootstrap_6lbr_asynch_ind(cur, data, ie_ext, message_type) ((void) 0)
|
||||
#define ws_bootstrap_6lbr_asynch_confirm(interface, asynch_message) ((void) 0)
|
||||
#define ws_bootstrap_6lbr_event_handler(cur, event) ((void) 0)
|
||||
#define ws_bootstrap_6lbr_state_machine(cur) ((void) 0)
|
||||
#define ws_bootstrap_6lbr_seconds_timer(cur, seconds) ((void) 0)
|
||||
|
||||
#define wisun_mode_border_router(cur) (false)
|
||||
|
||||
#endif //HAVE_WS
|
||||
|
||||
#endif /* WS_BOOTSTRAP_H_ */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Pelion and affiliates.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef WS_BOOTSTRAP_FFN_H_
|
||||
#define WS_BOOTSTRAP_FFN_H_
|
||||
|
||||
#if defined(HAVE_WS) && defined(HAVE_WS_ROUTER)
|
||||
|
||||
void ws_bootstrap_ffn_asynch_ind(struct protocol_interface_info_entry *cur, const struct mcps_data_ind_s *data, const struct mcps_data_ie_list *ie_ext, uint8_t message_type);
|
||||
void ws_bootstrap_ffn_asynch_confirm(struct protocol_interface_info_entry *interface, uint8_t asynch_message);
|
||||
void ws_bootstrap_ffn_event_handler(protocol_interface_info_entry_t *cur, arm_event_s *event);
|
||||
void ws_bootstrap_ffn_state_machine(protocol_interface_info_entry_t *cur);
|
||||
void ws_bootstrap_ffn_seconds_timer(protocol_interface_info_entry_t *cur, uint32_t seconds);
|
||||
|
||||
#define wisun_mode_router(cur) (cur->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_ROUTER)
|
||||
|
||||
#else
|
||||
|
||||
#define ws_bootstrap_ffn_asynch_ind(cur, data, ie_ext, message_type) ((void) 0)
|
||||
#define ws_bootstrap_ffn_asynch_confirm(interface, asynch_message) ((void) 0)
|
||||
#define ws_bootstrap_ffn_event_handler(cur, event) ((void) 0)
|
||||
#define ws_bootstrap_ffn_state_machine(cur) ((void) 0)
|
||||
#define ws_bootstrap_ffn_seconds_timer(cur, seconds) ((void) 0)
|
||||
|
||||
#define wisun_mode_router(cur) (false)
|
||||
|
||||
#endif //HAVE_WS
|
||||
|
||||
#endif /* WS_BOOTSTRAP_H_ */
|
|
@ -0,0 +1,172 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Pelion and affiliates.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "nsconfig.h"
|
||||
#if defined(HAVE_WS) && defined(HAVE_WS_HOST)
|
||||
#include "ns_types.h"
|
||||
#include "ns_trace.h"
|
||||
#include "nsdynmemLIB.h"
|
||||
#include "net_interface.h"
|
||||
#include "eventOS_event.h"
|
||||
#include "randLIB.h"
|
||||
#include "common_functions.h"
|
||||
#include "mac_common_defines.h"
|
||||
#include "sw_mac.h"
|
||||
#include "ccmLIB.h"
|
||||
#include "Core/include/ns_monitor.h"
|
||||
#include "NWK_INTERFACE/Include/protocol.h"
|
||||
#include "6LoWPAN/Bootstraps/protocol_6lowpan.h"
|
||||
#include "6LoWPAN/Bootstraps/protocol_6lowpan_interface.h"
|
||||
#include "ipv6_stack/protocol_ipv6.h"
|
||||
#include "ipv6_stack/ipv6_routing_table.h"
|
||||
#include "6LoWPAN/MAC/mac_helper.h"
|
||||
#include "6LoWPAN/MAC/mac_data_poll.h"
|
||||
#include "6LoWPAN/MAC/mpx_api.h"
|
||||
#include "6LoWPAN/MAC/mac_ie_lib.h"
|
||||
#include "MPL/mpl.h"
|
||||
#include "RPL/rpl_protocol.h"
|
||||
#include "RPL/rpl_control.h"
|
||||
#include "RPL/rpl_data.h"
|
||||
#include "RPL/rpl_policy.h"
|
||||
#include "Common_Protocols/icmpv6.h"
|
||||
#include "Common_Protocols/icmpv6_radv.h"
|
||||
#include "Common_Protocols/ipv6_constants.h"
|
||||
#include "Common_Protocols/ip.h"
|
||||
#include "Service_Libs/Trickle/trickle.h"
|
||||
#include "Service_Libs/fhss/channel_list.h"
|
||||
#include "Service_Libs/utils/ns_time.h"
|
||||
#include "6LoWPAN/ws/ws_common_defines.h"
|
||||
#include "6LoWPAN/ws/ws_common_defines.h"
|
||||
#include "6LoWPAN/ws/ws_config.h"
|
||||
#include "6LoWPAN/ws/ws_common.h"
|
||||
#include "6LoWPAN/ws/ws_bootstrap.h"
|
||||
#include "6LoWPAN/ws/ws_bbr_api_internal.h"
|
||||
#include "6LoWPAN/ws/ws_common_defines.h"
|
||||
#include "6LoWPAN/ws/ws_llc.h"
|
||||
#include "6LoWPAN/ws/ws_neighbor_class.h"
|
||||
#include "6LoWPAN/ws/ws_ie_lib.h"
|
||||
#include "6LoWPAN/ws/ws_stats.h"
|
||||
#include "6LoWPAN/ws/ws_cfg_settings.h"
|
||||
#include "6LoWPAN/lowpan_adaptation_interface.h"
|
||||
#include "Service_Libs/etx/etx.h"
|
||||
#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h"
|
||||
#include "Service_Libs/nd_proxy/nd_proxy.h"
|
||||
#include "Service_Libs/blacklist/blacklist.h"
|
||||
#include "platform/topo_trace.h"
|
||||
#include "dhcp_service_api.h"
|
||||
#include "libDHCPv6/libDHCPv6.h"
|
||||
#include "libDHCPv6/libDHCPv6_vendordata.h"
|
||||
#include "DHCPv6_client/dhcpv6_client_api.h"
|
||||
#include "ws_management_api.h"
|
||||
#include "net_rpl.h"
|
||||
#include "mac_api.h"
|
||||
#include "6LoWPAN/ws/ws_pae_controller.h"
|
||||
#include "6LoWPAN/ws/ws_eapol_pdu.h"
|
||||
#include "6LoWPAN/ws/ws_eapol_auth_relay.h"
|
||||
#include "6LoWPAN/ws/ws_eapol_relay.h"
|
||||
#include "libNET/src/net_dns_internal.h"
|
||||
#include "Service_Libs/random_early_detection/random_early_detection_api.h"
|
||||
|
||||
#define TRACE_GROUP "wsbs"
|
||||
|
||||
|
||||
void ws_bootstrap_lfn_asynch_ind(struct protocol_interface_info_entry *cur, const struct mcps_data_ind_s *data, const struct mcps_data_ie_list *ie_ext, uint8_t message_type)
|
||||
{
|
||||
(void)ie_ext;
|
||||
// Store weakest heard packet RSSI
|
||||
if (cur->ws_info->weakest_received_rssi > data->signal_dbm) {
|
||||
cur->ws_info->weakest_received_rssi = data->signal_dbm;
|
||||
}
|
||||
|
||||
if (data->SrcAddrMode != MAC_ADDR_MODE_64_BIT) {
|
||||
// Not from long address
|
||||
return;
|
||||
}
|
||||
ws_stats_update(cur, STATS_WS_ASYNCH_RX, 1);
|
||||
tr_warn("Wi-SUN LFN Mode received message id: %x", message_type);
|
||||
}
|
||||
|
||||
void ws_bootstrap_lfn_asynch_confirm(struct protocol_interface_info_entry *interface, uint8_t asynch_message)
|
||||
{
|
||||
(void)asynch_message;
|
||||
ws_stats_update(interface, STATS_WS_ASYNCH_TX, 1);
|
||||
}
|
||||
|
||||
void ws_bootstrap_lfn_event_handler(protocol_interface_info_entry_t *cur, arm_event_s *event)
|
||||
{
|
||||
(void)cur;
|
||||
ws_bootsrap_event_type_e event_type;
|
||||
event_type = (ws_bootsrap_event_type_e)event->event_type;
|
||||
|
||||
switch (event_type) {
|
||||
case WS_INIT_EVENT:
|
||||
tr_debug("tasklet init");
|
||||
break;
|
||||
/* case WS_DISCOVERY_START:
|
||||
case WS_CONFIGURATION_START:
|
||||
case WS_OPERATION_START:
|
||||
case WS_ROUTING_READY:
|
||||
case WS_FAST_DISCONNECT:
|
||||
case WS_NORMAL_DISCONNECT:
|
||||
*/
|
||||
default:
|
||||
tr_err("Invalid event received");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ws_bootstrap_lfn_state_machine(protocol_interface_info_entry_t *cur)
|
||||
{
|
||||
|
||||
switch (cur->nwk_bootstrap_state) {
|
||||
case ER_WAIT_RESTART:
|
||||
tr_debug("WS SM:Wait for startup");
|
||||
break;
|
||||
case ER_ACTIVE_SCAN:
|
||||
tr_debug("WS SM:Active Scan");
|
||||
break;
|
||||
case ER_SCAN:
|
||||
tr_debug("WS SM:configuration Scan");
|
||||
break;
|
||||
case ER_PANA_AUTH:
|
||||
tr_info("authentication start");
|
||||
// Advertisements stopped during the EAPOL
|
||||
break;
|
||||
case ER_RPL_SCAN:
|
||||
tr_debug("WS SM:Wait RPL to contact DODAG root");
|
||||
break;
|
||||
case ER_BOOTSRAP_DONE:
|
||||
tr_info("WS SM:Bootstrap Done");
|
||||
// Bootstrap_done event to application
|
||||
break;
|
||||
case ER_RPL_NETWORK_LEAVING:
|
||||
tr_debug("WS SM:RPL Leaving ready trigger discovery");
|
||||
break;
|
||||
default:
|
||||
tr_warn("WS SM:Invalid state %d", cur->nwk_bootstrap_state);
|
||||
}
|
||||
}
|
||||
|
||||
void ws_bootstrap_lfn_seconds_timer(protocol_interface_info_entry_t *cur, uint32_t seconds)
|
||||
{
|
||||
(void)cur;
|
||||
(void)seconds;
|
||||
}
|
||||
|
||||
|
||||
#endif //HAVE_WS_BORDER_ROUTER && HAVE_WS
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Pelion and affiliates.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef WS_BOOTSTRAP_LFN_H_
|
||||
#define WS_BOOTSTRAP_LFN_H_
|
||||
|
||||
#if defined(HAVE_WS) && defined(HAVE_WS_HOST)
|
||||
|
||||
void ws_bootstrap_lfn_asynch_ind(struct protocol_interface_info_entry *cur, const struct mcps_data_ind_s *data, const struct mcps_data_ie_list *ie_ext, uint8_t message_type);
|
||||
void ws_bootstrap_lfn_asynch_confirm(struct protocol_interface_info_entry *interface, uint8_t asynch_message);
|
||||
void ws_bootstrap_lfn_event_handler(protocol_interface_info_entry_t *cur, arm_event_s *event);
|
||||
void ws_bootstrap_lfn_state_machine(protocol_interface_info_entry_t *cur);
|
||||
void ws_bootstrap_lfn_seconds_timer(protocol_interface_info_entry_t *cur, uint32_t seconds);
|
||||
|
||||
#define wisun_mode_host(cur) (cur->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_HOST)
|
||||
|
||||
#else
|
||||
|
||||
#define ws_bootstrap_ffn_asynch_ind(cur, data, ie_ext, message_type) ((void) 0)
|
||||
#define ws_bootstrap_ffn_asynch_confirm(interface, asynch_message) ((void) 0)
|
||||
#define ws_bootstrap_ffn_event_handler(cur, event) ((void) 0)
|
||||
#define ws_bootstrap_lfn_state_machine(cur) ((void) 0)
|
||||
#define ws_bootstrap_lfn_seconds_timer(cur, seconds) ((void) 0)
|
||||
|
||||
#define wisun_mode_host(cur) (false)
|
||||
|
||||
#endif //HAVE_WS
|
||||
|
||||
#endif /* WS_BOOTSTRAP_H_ */
|
|
@ -39,10 +39,8 @@
|
|||
#define CFG_SETTINGS_OK 0
|
||||
#define CFG_SETTINGS_CHANGED 1
|
||||
|
||||
#define CFG_FLAGS_DISABLE_VAL_SET 0x01
|
||||
#define CFG_FLAGS_OVERRIDE_DISABLE_VAL_SET 0x02
|
||||
#define CFG_FLAGS_FORCE_INTERNAL_CONFIG 0x04
|
||||
#define CFG_FLAGS_BOOTSTRAP_RESTART_DISABLE 0x08
|
||||
#define CFG_FLAGS_BOOTSTRAP_RESTART_DISABLE 0x01
|
||||
#define CFG_FLAGS_BOOTSTRAP_SET_VALUES 0x02
|
||||
|
||||
#define TRICKLE_IMIN_60_SECS 60
|
||||
#define TRICKLE_IMIN_30_SECS 30
|
||||
|
@ -58,8 +56,8 @@ typedef struct ws_cfg_nw_size_s {
|
|||
|
||||
static uint32_t ws_test_temporary_entry_lifetime = 0;
|
||||
typedef int8_t (*ws_cfg_default_set)(void *cfg);
|
||||
typedef int8_t (*ws_cfg_validate)(void *cfg, void *new_cfg);
|
||||
typedef int8_t (*ws_cfg_set)(protocol_interface_info_entry_t *cur, void *cfg, void *new_cfg, uint8_t *flags);
|
||||
typedef int8_t (*ws_cfg_validate)(void *new_cfg);
|
||||
typedef int8_t (*ws_cfg_set)(protocol_interface_info_entry_t *cur, void *new_cfg, uint8_t flags);
|
||||
|
||||
typedef struct {
|
||||
ws_cfg_default_set default_set;
|
||||
|
@ -104,9 +102,6 @@ const cfg_devices_in_config_t devices_by_datarate[] = {
|
|||
{ 2, 20, 50, 100}, // Configuration for 600kbs - 2400kbs
|
||||
};
|
||||
|
||||
|
||||
static int8_t ws_cfg_to_get(ws_cfgs_t **cfg, ws_cfgs_t *new_cfg, ws_cfg_validate valid_cb, ws_cfgs_t *external_cfg, uint8_t *cfg_flags, uint8_t *flags);
|
||||
|
||||
static void ws_cfg_network_size_config_set_small(ws_cfg_nw_size_t *cfg);
|
||||
static void ws_cfg_network_size_config_set_medium(ws_cfg_nw_size_t *cfg);
|
||||
static void ws_cfg_network_size_config_set_large(ws_cfg_nw_size_t *cfg);
|
||||
|
@ -146,55 +141,6 @@ static const ws_cfg_cb_t cfg_cb[] = {
|
|||
// Wisun configuration storage
|
||||
ws_cfg_t ws_cfg;
|
||||
|
||||
// If automatic network size mode; external configuration shown to towards users of external APIs
|
||||
ws_cfg_nw_size_t *nw_size_external_cfg = NULL;
|
||||
|
||||
static int8_t ws_cfg_to_get(ws_cfgs_t **cfg, ws_cfgs_t *new_cfg, ws_cfg_validate valid_cb, ws_cfgs_t *ws_cfg_ptr, uint8_t *cfg_flags, uint8_t *flags)
|
||||
{
|
||||
// In case target configuration is not set, uses ws_cfg storage
|
||||
if (*cfg == NULL) {
|
||||
// In case external configuration is not same as internal
|
||||
if (nw_size_external_cfg && (!flags || !(*flags & CFG_FLAGS_FORCE_INTERNAL_CONFIG))) {
|
||||
if (ws_cfg_ptr == (ws_cfgs_t *) &ws_cfg.gen) {
|
||||
*cfg = (ws_cfgs_t *) &nw_size_external_cfg->gen;
|
||||
} else if (ws_cfg_ptr == (ws_cfgs_t *) &ws_cfg.timing) {
|
||||
*cfg = (ws_cfgs_t *) &nw_size_external_cfg->timing;
|
||||
} else if (ws_cfg_ptr == (ws_cfgs_t *) &ws_cfg.bbr) {
|
||||
*cfg = (ws_cfgs_t *) &nw_size_external_cfg->bbr;
|
||||
} else if (ws_cfg_ptr == (ws_cfgs_t *) &ws_cfg.sec_prot) {
|
||||
*cfg = (ws_cfgs_t *) &nw_size_external_cfg->sec_prot;
|
||||
} else if (ws_cfg_ptr == (ws_cfgs_t *) &ws_cfg.mpl) {
|
||||
*cfg = (ws_cfgs_t *) &nw_size_external_cfg->mpl;
|
||||
} else {
|
||||
*cfg = ws_cfg_ptr;
|
||||
}
|
||||
} else {
|
||||
*cfg = ws_cfg_ptr;
|
||||
}
|
||||
|
||||
if (valid_cb) {
|
||||
int8_t ret = valid_cb(*cfg, new_cfg);
|
||||
// On failure and if nothing is changed, returns
|
||||
if (ret != CFG_SETTINGS_CHANGED) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!cfg_flags) {
|
||||
return CFG_SETTINGS_CHANGED;
|
||||
}
|
||||
*cfg_flags = 0;
|
||||
if (flags) {
|
||||
*cfg_flags |= *flags;
|
||||
}
|
||||
if (nw_size_external_cfg && !(*cfg_flags & CFG_FLAGS_OVERRIDE_DISABLE_VAL_SET)) {
|
||||
*cfg_flags |= CFG_FLAGS_DISABLE_VAL_SET;
|
||||
}
|
||||
|
||||
return CFG_SETTINGS_CHANGED;
|
||||
}
|
||||
|
||||
#ifdef FEA_TRACE_SUPPORT
|
||||
static void ws_cfg_trace(ws_cfgs_t *cfg, ws_cfgs_t *new_cfg, uint8_t size, char *name)
|
||||
{
|
||||
|
@ -236,19 +182,15 @@ static int8_t ws_cfg_network_size_default_set(ws_gen_cfg_t *cfg)
|
|||
return CFG_SETTINGS_OK;
|
||||
}
|
||||
|
||||
int8_t ws_cfg_network_size_get(ws_gen_cfg_t *cfg, uint8_t *flags)
|
||||
int8_t ws_cfg_network_size_get(ws_gen_cfg_t *cfg)
|
||||
{
|
||||
ws_gen_cfg_t *get_cfg = NULL;
|
||||
ws_cfg_to_get((ws_cfgs_t **) &get_cfg, NULL, NULL, (ws_cfgs_t *) &ws_cfg.gen, 0, flags);
|
||||
*cfg = *get_cfg;
|
||||
|
||||
*cfg = ws_cfg.gen;
|
||||
return CFG_SETTINGS_OK;
|
||||
}
|
||||
|
||||
int8_t ws_cfg_network_size_validate(ws_gen_cfg_t *cfg, ws_gen_cfg_t *new_cfg)
|
||||
int8_t ws_cfg_network_size_validate(ws_gen_cfg_t *new_cfg)
|
||||
{
|
||||
ws_cfg_to_get((ws_cfgs_t **) &cfg, (ws_cfgs_t *) new_cfg, NULL, (ws_cfgs_t *) &ws_cfg.gen, 0, 0);
|
||||
|
||||
ws_gen_cfg_t *cfg = &ws_cfg.gen;
|
||||
if (cfg->network_size != new_cfg->network_size) {
|
||||
return CFG_SETTINGS_CHANGED;
|
||||
}
|
||||
|
@ -258,29 +200,24 @@ int8_t ws_cfg_network_size_validate(ws_gen_cfg_t *cfg, ws_gen_cfg_t *new_cfg)
|
|||
|
||||
typedef void (*ws_cfg_network_size_config_set_size)(ws_cfg_nw_size_t *cfg);
|
||||
|
||||
int8_t ws_cfg_network_size_set(protocol_interface_info_entry_t *cur, ws_gen_cfg_t *cfg, ws_gen_cfg_t *new_cfg, uint8_t *flags)
|
||||
int8_t ws_cfg_network_size_set(protocol_interface_info_entry_t *cur, ws_gen_cfg_t *new_cfg, uint8_t flags)
|
||||
{
|
||||
uint8_t cfg_flags;
|
||||
int8_t ret = ws_cfg_to_get((ws_cfgs_t **) &cfg, (ws_cfgs_t *) new_cfg, (ws_cfg_validate) ws_cfg_network_size_validate, (ws_cfgs_t *) &ws_cfg.gen, &cfg_flags, flags);
|
||||
if (ret != CFG_SETTINGS_CHANGED) {
|
||||
return ret;
|
||||
}
|
||||
(void) flags;
|
||||
|
||||
uint8_t old_network_size = cfg->network_size;
|
||||
|
||||
// If network size configuration has not changed, returns
|
||||
if (cfg->network_size == new_cfg->network_size) {
|
||||
if (ws_cfg_network_size_validate(new_cfg) != CFG_SETTINGS_CHANGED) {
|
||||
return CFG_SETTINGS_OK;
|
||||
}
|
||||
|
||||
ws_gen_cfg_t *cfg = &ws_cfg.gen;
|
||||
|
||||
cfg->network_size = new_cfg->network_size;
|
||||
|
||||
ws_cfg_nw_size_t nw_size_cfg;
|
||||
ws_cfg_gen_get(&nw_size_cfg.gen, NULL);
|
||||
ws_cfg_timing_get(&nw_size_cfg.timing, NULL);
|
||||
ws_cfg_bbr_get(&nw_size_cfg.bbr, NULL);
|
||||
ws_cfg_sec_prot_get(&nw_size_cfg.sec_prot, NULL);
|
||||
ws_cfg_mpl_get(&nw_size_cfg.mpl, NULL);
|
||||
ws_cfg_gen_get(&nw_size_cfg.gen);
|
||||
ws_cfg_timing_get(&nw_size_cfg.timing);
|
||||
ws_cfg_bbr_get(&nw_size_cfg.bbr);
|
||||
ws_cfg_sec_prot_get(&nw_size_cfg.sec_prot);
|
||||
ws_cfg_mpl_get(&nw_size_cfg.mpl);
|
||||
|
||||
ws_cfg_network_size_config_set_size set_function = NULL;
|
||||
|
||||
|
@ -301,46 +238,13 @@ int8_t ws_cfg_network_size_set(protocol_interface_info_entry_t *cur, ws_gen_cfg_
|
|||
set_function(&nw_size_cfg);
|
||||
}
|
||||
|
||||
uint8_t cfg_network_size = cfg->network_size;
|
||||
/* Sets values if changed */
|
||||
ws_cfg_gen_set(cur, &nw_size_cfg.gen, 0x00);
|
||||
ws_cfg_timing_set(cur, &nw_size_cfg.timing, 0x00);
|
||||
ws_cfg_bbr_set(cur, &nw_size_cfg.bbr, 0x00);
|
||||
ws_cfg_sec_prot_set(cur, &nw_size_cfg.sec_prot, 0x00);
|
||||
ws_cfg_mpl_set(cur, &nw_size_cfg.mpl, 0x00);
|
||||
|
||||
/* If no longer in an automatic network size mode, frees automatic configuration,
|
||||
so that new configuration is set */
|
||||
if (nw_size_external_cfg && old_network_size == NETWORK_SIZE_AUTOMATIC) {
|
||||
ns_dyn_mem_free(nw_size_external_cfg);
|
||||
nw_size_external_cfg = NULL;
|
||||
}
|
||||
|
||||
uint8_t set_flags = 0;
|
||||
if (cfg_network_size == NETWORK_SIZE_AUTOMATIC) {
|
||||
set_flags = CFG_FLAGS_DISABLE_VAL_SET;
|
||||
}
|
||||
/* Sets values if changed or network size has been previously automatic (to make sure
|
||||
the settings are in sync */
|
||||
if (ws_cfg_gen_validate(&ws_cfg.gen, &nw_size_cfg.gen) == CFG_SETTINGS_CHANGED ||
|
||||
old_network_size == NETWORK_SIZE_AUTOMATIC) {
|
||||
ws_cfg_gen_set(cur, &ws_cfg.gen, &nw_size_cfg.gen, &set_flags);
|
||||
}
|
||||
if (ws_cfg_timing_validate(&ws_cfg.timing, &nw_size_cfg.timing) == CFG_SETTINGS_CHANGED ||
|
||||
old_network_size == NETWORK_SIZE_AUTOMATIC) {
|
||||
ws_cfg_timing_set(cur, &ws_cfg.timing, &nw_size_cfg.timing, &set_flags);
|
||||
}
|
||||
if (ws_cfg_bbr_validate(&ws_cfg.bbr, &nw_size_cfg.bbr) == CFG_SETTINGS_CHANGED ||
|
||||
old_network_size == NETWORK_SIZE_AUTOMATIC) {
|
||||
ws_cfg_bbr_set(cur, &ws_cfg.bbr, &nw_size_cfg.bbr, &set_flags);
|
||||
}
|
||||
if (ws_cfg_sec_prot_validate(&ws_cfg.sec_prot, &nw_size_cfg.sec_prot) == CFG_SETTINGS_CHANGED ||
|
||||
old_network_size == NETWORK_SIZE_AUTOMATIC) {
|
||||
ws_cfg_sec_prot_set(cur, &ws_cfg.sec_prot, &nw_size_cfg.sec_prot, &set_flags);
|
||||
}
|
||||
if (ws_cfg_mpl_validate(&ws_cfg.mpl, &nw_size_cfg.mpl) == CFG_SETTINGS_CHANGED ||
|
||||
old_network_size == NETWORK_SIZE_AUTOMATIC) {
|
||||
ws_cfg_mpl_set(cur, &ws_cfg.mpl, &nw_size_cfg.mpl, &set_flags);
|
||||
}
|
||||
|
||||
// If is in an automatic network size mode, updates automatic configuration
|
||||
if (cfg_network_size == NETWORK_SIZE_AUTOMATIC && cur) {
|
||||
ws_cfg_network_size_configure(cur, cur->ws_info->pan_information.pan_size);
|
||||
}
|
||||
return CFG_SETTINGS_OK;
|
||||
}
|
||||
|
||||
|
@ -349,7 +253,7 @@ static uint8_t ws_cfg_config_get_by_size(protocol_interface_info_entry_t *cur, u
|
|||
(void)cur;
|
||||
|
||||
ws_phy_cfg_t phy_cfg;
|
||||
if (ws_cfg_phy_get(&phy_cfg, NULL) < 0) {
|
||||
if (ws_cfg_phy_get(&phy_cfg) < 0) {
|
||||
return CONFIG_SMALL;
|
||||
}
|
||||
uint32_t data_rate = ws_common_datarate_get_from_phy_mode(phy_cfg.phy_mode_id, phy_cfg.operating_mode);
|
||||
|
@ -377,50 +281,6 @@ static uint8_t ws_cfg_config_get_by_size(protocol_interface_info_entry_t *cur, u
|
|||
return CONFIG_XLARGE;
|
||||
}
|
||||
|
||||
int8_t ws_cfg_network_size_configure(protocol_interface_info_entry_t *cur, uint16_t network_size)
|
||||
{
|
||||
// Read settings that are affected by network size
|
||||
ws_cfg_nw_size_t new_nw_size_cfg;
|
||||
uint8_t flags = CFG_FLAGS_OVERRIDE_DISABLE_VAL_SET | CFG_FLAGS_FORCE_INTERNAL_CONFIG;
|
||||
|
||||
ws_cfg_gen_get(&new_nw_size_cfg.gen, &flags);
|
||||
ws_cfg_timing_get(&new_nw_size_cfg.timing, &flags);
|
||||
ws_cfg_bbr_get(&new_nw_size_cfg.bbr, &flags);
|
||||
ws_cfg_sec_prot_get(&new_nw_size_cfg.sec_prot, &flags);
|
||||
ws_cfg_mpl_get(&new_nw_size_cfg.mpl, &flags);
|
||||
|
||||
if (!nw_size_external_cfg) {
|
||||
nw_size_external_cfg = ns_dyn_mem_alloc(sizeof(ws_cfg_nw_size_t));
|
||||
if (!nw_size_external_cfg) {
|
||||
return -1;
|
||||
}
|
||||
memcpy(nw_size_external_cfg, &new_nw_size_cfg, sizeof(ws_cfg_nw_size_t));
|
||||
}
|
||||
|
||||
network_size = network_size / 100;
|
||||
if (network_size == 0) {
|
||||
network_size = 1;
|
||||
}
|
||||
|
||||
if (ws_cfg_config_get_by_size(cur, network_size) == CONFIG_SMALL) {
|
||||
ws_cfg_network_size_config_set_small(&new_nw_size_cfg);
|
||||
} else if (ws_cfg_config_get_by_size(cur, network_size) == CONFIG_MEDIUM) {
|
||||
ws_cfg_network_size_config_set_medium(&new_nw_size_cfg);
|
||||
} else if (ws_cfg_config_get_by_size(cur, network_size) == CONFIG_LARGE) {
|
||||
ws_cfg_network_size_config_set_large(&new_nw_size_cfg);
|
||||
} else {
|
||||
ws_cfg_network_size_config_set_xlarge(&new_nw_size_cfg);
|
||||
}
|
||||
|
||||
ws_cfg_gen_set(cur, NULL, &new_nw_size_cfg.gen, &flags);
|
||||
ws_cfg_timing_set(cur, NULL, &new_nw_size_cfg.timing, &flags);
|
||||
ws_cfg_bbr_set(cur, NULL, &new_nw_size_cfg.bbr, &flags);
|
||||
ws_cfg_sec_prot_set(cur, NULL, &new_nw_size_cfg.sec_prot, &flags);
|
||||
ws_cfg_mpl_set(cur, &ws_cfg.mpl, &new_nw_size_cfg.mpl, &flags);
|
||||
|
||||
return CFG_SETTINGS_OK;
|
||||
}
|
||||
|
||||
cfg_network_size_type_e ws_cfg_network_config_get(protocol_interface_info_entry_t *cur)
|
||||
{
|
||||
// Get size of the network Amount of devices in the network
|
||||
|
@ -430,7 +290,7 @@ cfg_network_size_type_e ws_cfg_network_config_get(protocol_interface_info_entry_
|
|||
(void)cur;
|
||||
|
||||
ws_gen_cfg_t cfg;
|
||||
if (ws_cfg_gen_get(&cfg, NULL) < 0) {
|
||||
if (ws_cfg_gen_get(&cfg) < 0) {
|
||||
return CONFIG_SMALL;
|
||||
}
|
||||
|
||||
|
@ -563,7 +423,6 @@ static void ws_cfg_network_size_config_set_large(ws_cfg_nw_size_t *cfg)
|
|||
cfg->mpl.mpl_trickle_k = MPL_LARGE_K;
|
||||
cfg->mpl.mpl_trickle_timer_exp = MPL_LARGE_EXPIRATIONS;
|
||||
cfg->mpl.seed_set_entry_lifetime = MPL_LARGE_SEED_LIFETIME;
|
||||
|
||||
}
|
||||
|
||||
static void ws_cfg_network_size_config_set_xlarge(ws_cfg_nw_size_t *cfg)
|
||||
|
@ -653,25 +512,21 @@ static void ws_cfg_network_size_config_set_certificate(ws_cfg_nw_size_t *cfg)
|
|||
static int8_t ws_cfg_gen_default_set(ws_gen_cfg_t *cfg)
|
||||
{
|
||||
memset(cfg->network_name, 0, sizeof(cfg->network_name));
|
||||
cfg->network_pan_id = 0xffff;
|
||||
cfg->rpl_parent_candidate_max = WS_RPL_PARENT_CANDIDATE_MAX;
|
||||
cfg->rpl_selected_parent_max = WS_RPL_SELECTED_PARENT_MAX;
|
||||
|
||||
return CFG_SETTINGS_OK;
|
||||
}
|
||||
|
||||
int8_t ws_cfg_gen_get(ws_gen_cfg_t *cfg, uint8_t *flags)
|
||||
int8_t ws_cfg_gen_get(ws_gen_cfg_t *cfg)
|
||||
{
|
||||
ws_gen_cfg_t *get_cfg = NULL;
|
||||
ws_cfg_to_get((ws_cfgs_t **) &get_cfg, NULL, NULL, (ws_cfgs_t *) &ws_cfg.gen, 0, flags);
|
||||
*cfg = *get_cfg;
|
||||
|
||||
*cfg = ws_cfg.gen;
|
||||
return CFG_SETTINGS_OK;
|
||||
}
|
||||
|
||||
int8_t ws_cfg_gen_validate(ws_gen_cfg_t *cfg, ws_gen_cfg_t *new_cfg)
|
||||
int8_t ws_cfg_gen_validate(ws_gen_cfg_t *new_cfg)
|
||||
{
|
||||
ws_cfg_to_get((ws_cfgs_t **) &cfg, (ws_cfgs_t *) new_cfg, NULL, (ws_cfgs_t *) &ws_cfg.gen, 0, 0);
|
||||
ws_gen_cfg_t *cfg = &ws_cfg.gen;
|
||||
|
||||
if (strlen(new_cfg->network_name) > 32) {
|
||||
return CFG_SETTINGS_ERROR_GEN_CONF;
|
||||
|
@ -679,7 +534,6 @@ int8_t ws_cfg_gen_validate(ws_gen_cfg_t *cfg, ws_gen_cfg_t *new_cfg)
|
|||
|
||||
// Regulator domain, operating mode or class has changed
|
||||
if (strcmp(cfg->network_name, new_cfg->network_name) != 0 ||
|
||||
cfg->network_pan_id != new_cfg->network_pan_id ||
|
||||
cfg->rpl_parent_candidate_max != new_cfg->rpl_parent_candidate_max ||
|
||||
cfg->rpl_selected_parent_max != new_cfg->rpl_selected_parent_max) {
|
||||
return CFG_SETTINGS_CHANGED;
|
||||
|
@ -688,30 +542,29 @@ int8_t ws_cfg_gen_validate(ws_gen_cfg_t *cfg, ws_gen_cfg_t *new_cfg)
|
|||
return CFG_SETTINGS_OK;
|
||||
}
|
||||
|
||||
int8_t ws_cfg_gen_set(protocol_interface_info_entry_t *cur, ws_gen_cfg_t *cfg, ws_gen_cfg_t *new_cfg, uint8_t *flags)
|
||||
int8_t ws_cfg_gen_set(protocol_interface_info_entry_t *cur, ws_gen_cfg_t *new_cfg, uint8_t flags)
|
||||
{
|
||||
(void) cur;
|
||||
(void) flags;
|
||||
|
||||
uint8_t cfg_flags;
|
||||
int8_t ret = ws_cfg_to_get((ws_cfgs_t **) &cfg, (ws_cfgs_t *) new_cfg, (ws_cfg_validate) ws_cfg_gen_validate, (ws_cfgs_t *) &ws_cfg.gen, &cfg_flags, flags);
|
||||
if (ret != CFG_SETTINGS_CHANGED) {
|
||||
int8_t ret = ws_cfg_gen_validate(new_cfg);
|
||||
if (!(flags & CFG_FLAGS_BOOTSTRAP_SET_VALUES) && ret != CFG_SETTINGS_CHANGED) {
|
||||
return ret;
|
||||
}
|
||||
if (cfg == new_cfg) {
|
||||
|
||||
if (flags & CFG_FLAGS_BOOTSTRAP_SET_VALUES) {
|
||||
return CFG_SETTINGS_OK;
|
||||
}
|
||||
|
||||
ws_gen_cfg_t *cfg = &ws_cfg.gen;
|
||||
|
||||
ws_cfg_trace((ws_cfgs_t *) cfg, (ws_cfgs_t *) new_cfg, sizeof(ws_gen_cfg_t), "gen");
|
||||
|
||||
cfg->network_size = new_cfg->network_size;
|
||||
if (&cfg->network_name != &new_cfg->network_name) {
|
||||
strncpy(cfg->network_name, new_cfg->network_name, 32);
|
||||
}
|
||||
cfg->network_pan_id = new_cfg->network_pan_id;
|
||||
cfg->rpl_parent_candidate_max = new_cfg->rpl_parent_candidate_max;
|
||||
cfg->rpl_selected_parent_max = new_cfg->rpl_selected_parent_max;
|
||||
|
||||
if (cur && !(cfg_flags & CFG_FLAGS_BOOTSTRAP_RESTART_DISABLE)) {
|
||||
if (cur && !(flags & CFG_FLAGS_BOOTSTRAP_RESTART_DISABLE)) {
|
||||
ws_bootstrap_restart_delayed(cur->id);
|
||||
}
|
||||
|
||||
|
@ -730,18 +583,15 @@ int8_t ws_cfg_phy_default_set(ws_phy_cfg_t *cfg)
|
|||
return CFG_SETTINGS_OK;
|
||||
}
|
||||
|
||||
int8_t ws_cfg_phy_get(ws_phy_cfg_t *cfg, uint8_t *flags)
|
||||
int8_t ws_cfg_phy_get(ws_phy_cfg_t *cfg)
|
||||
{
|
||||
ws_phy_cfg_t *get_cfg = NULL;
|
||||
ws_cfg_to_get((ws_cfgs_t **) &get_cfg, NULL, NULL, (ws_cfgs_t *) &ws_cfg.phy, 0, flags);
|
||||
*cfg = *get_cfg;
|
||||
|
||||
*cfg = ws_cfg.phy;
|
||||
return CFG_SETTINGS_OK;
|
||||
}
|
||||
|
||||
int8_t ws_cfg_phy_validate(ws_phy_cfg_t *cfg, ws_phy_cfg_t *new_cfg)
|
||||
int8_t ws_cfg_phy_validate(ws_phy_cfg_t *new_cfg)
|
||||
{
|
||||
ws_cfg_to_get((ws_cfgs_t **) &cfg, (ws_cfgs_t *) new_cfg, NULL, (ws_cfgs_t *) &ws_cfg.phy, 0, 0);
|
||||
ws_phy_cfg_t *cfg = &ws_cfg.phy;
|
||||
|
||||
// Regulator domain, operating mode or class has changed
|
||||
if (cfg->regulatory_domain != new_cfg->regulatory_domain ||
|
||||
|
@ -770,15 +620,14 @@ int8_t ws_cfg_phy_validate(ws_phy_cfg_t *cfg, ws_phy_cfg_t *new_cfg)
|
|||
return CFG_SETTINGS_OK;
|
||||
}
|
||||
|
||||
int8_t ws_cfg_phy_set(protocol_interface_info_entry_t *cur, ws_phy_cfg_t *cfg, ws_phy_cfg_t *new_cfg, uint8_t *flags)
|
||||
int8_t ws_cfg_phy_set(protocol_interface_info_entry_t *cur, ws_phy_cfg_t *new_cfg, uint8_t flags)
|
||||
{
|
||||
uint8_t cfg_flags;
|
||||
int8_t ret = ws_cfg_to_get((ws_cfgs_t **) &cfg, (ws_cfgs_t *) new_cfg, (ws_cfg_validate) ws_cfg_phy_validate, (ws_cfgs_t *) &ws_cfg.phy, &cfg_flags, flags);
|
||||
if (ret != CFG_SETTINGS_CHANGED) {
|
||||
int8_t ret = ws_cfg_phy_validate(new_cfg);
|
||||
if (!(flags & CFG_FLAGS_BOOTSTRAP_SET_VALUES) && ret != CFG_SETTINGS_CHANGED) {
|
||||
return ret;
|
||||
}
|
||||
// Check settings and configure interface
|
||||
if (cur && !(cfg_flags & CFG_FLAGS_DISABLE_VAL_SET)) {
|
||||
if (cur) {
|
||||
// Set operating mode for FSK if given with PHY mode ID
|
||||
if ((new_cfg->phy_mode_id == 1) || (new_cfg->phy_mode_id == 17)) {
|
||||
cur->ws_info->hopping_schdule.operating_mode = OPERATING_MODE_1a;
|
||||
|
@ -809,15 +658,17 @@ int8_t ws_cfg_phy_set(protocol_interface_info_entry_t *cur, ws_phy_cfg_t *cfg, w
|
|||
}
|
||||
}
|
||||
|
||||
if (cfg == new_cfg) {
|
||||
if (flags & CFG_FLAGS_BOOTSTRAP_SET_VALUES) {
|
||||
return CFG_SETTINGS_OK;
|
||||
}
|
||||
|
||||
ws_phy_cfg_t *cfg = &ws_cfg.phy;
|
||||
|
||||
ws_cfg_trace((ws_cfgs_t *) cfg, (ws_cfgs_t *) new_cfg, sizeof(ws_phy_cfg_t), "phy");
|
||||
|
||||
*cfg = *new_cfg;
|
||||
|
||||
if (cur && !(cfg_flags & CFG_FLAGS_BOOTSTRAP_RESTART_DISABLE)) {
|
||||
if (cur && !(flags & CFG_FLAGS_BOOTSTRAP_RESTART_DISABLE)) {
|
||||
ws_bootstrap_restart_delayed(cur->id);
|
||||
}
|
||||
|
||||
|
@ -837,18 +688,15 @@ int8_t ws_cfg_timing_default_set(ws_timing_cfg_t *cfg)
|
|||
return CFG_SETTINGS_OK;
|
||||
}
|
||||
|
||||
int8_t ws_cfg_timing_get(ws_timing_cfg_t *cfg, uint8_t *flags)
|
||||
int8_t ws_cfg_timing_get(ws_timing_cfg_t *cfg)
|
||||
{
|
||||
ws_timing_cfg_t *get_cfg = NULL;
|
||||
ws_cfg_to_get((ws_cfgs_t **) &get_cfg, NULL, NULL, (ws_cfgs_t *) &ws_cfg.timing, 0, flags);
|
||||
*cfg = *get_cfg;
|
||||
|
||||
*cfg = ws_cfg.timing;
|
||||
return CFG_SETTINGS_OK;
|
||||
}
|
||||
|
||||
int8_t ws_cfg_timing_validate(ws_timing_cfg_t *cfg, ws_timing_cfg_t *new_cfg)
|
||||
int8_t ws_cfg_timing_validate(ws_timing_cfg_t *new_cfg)
|
||||
{
|
||||
ws_cfg_to_get((ws_cfgs_t **) &cfg, (ws_cfgs_t *) new_cfg, NULL, (ws_cfgs_t *) &ws_cfg.timing, 0, 0);
|
||||
ws_timing_cfg_t *cfg = &ws_cfg.timing;
|
||||
|
||||
if (cfg->disc_trickle_imin != new_cfg->disc_trickle_imin ||
|
||||
cfg->disc_trickle_imax != new_cfg->disc_trickle_imax ||
|
||||
|
@ -876,15 +724,16 @@ int8_t ws_cfg_timing_validate(ws_timing_cfg_t *cfg, ws_timing_cfg_t *new_cfg)
|
|||
return CFG_SETTINGS_OK;
|
||||
}
|
||||
|
||||
int8_t ws_cfg_timing_set(protocol_interface_info_entry_t *cur, ws_timing_cfg_t *cfg, ws_timing_cfg_t *new_cfg, uint8_t *flags)
|
||||
int8_t ws_cfg_timing_set(protocol_interface_info_entry_t *cur, ws_timing_cfg_t *new_cfg, uint8_t flags)
|
||||
{
|
||||
uint8_t cfg_flags;
|
||||
int8_t ret = ws_cfg_to_get((ws_cfgs_t **) &cfg, (ws_cfgs_t *) new_cfg, (ws_cfg_validate) ws_cfg_timing_validate, (ws_cfgs_t *) &ws_cfg.timing, &cfg_flags, flags);
|
||||
if (ret != CFG_SETTINGS_CHANGED) {
|
||||
(void) flags;
|
||||
|
||||
int8_t ret = ws_cfg_timing_validate(new_cfg);
|
||||
if (!(flags & CFG_FLAGS_BOOTSTRAP_SET_VALUES) && ret != CFG_SETTINGS_CHANGED) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (cur && !(cfg_flags & CFG_FLAGS_DISABLE_VAL_SET)) {
|
||||
if (cur) {
|
||||
cur->ws_info->trickle_params_pan_discovery.Imin = new_cfg->disc_trickle_imin * 10;
|
||||
cur->ws_info->trickle_params_pan_discovery.Imax = new_cfg->disc_trickle_imax * 10;
|
||||
cur->ws_info->trickle_params_pan_discovery.k = new_cfg->disc_trickle_k;
|
||||
|
@ -892,10 +741,12 @@ int8_t ws_cfg_timing_set(protocol_interface_info_entry_t *cur, ws_timing_cfg_t *
|
|||
ws_pae_controller_configure(cur, NULL, NULL, new_cfg);
|
||||
}
|
||||
|
||||
if (cfg == new_cfg) {
|
||||
if (flags & CFG_FLAGS_BOOTSTRAP_SET_VALUES) {
|
||||
return CFG_SETTINGS_OK;
|
||||
}
|
||||
|
||||
ws_timing_cfg_t *cfg = &ws_cfg.timing;
|
||||
|
||||
ws_cfg_trace((ws_cfgs_t *) cfg, (ws_cfgs_t *) new_cfg, sizeof(ws_timing_cfg_t), "timing");
|
||||
|
||||
*cfg = *new_cfg;
|
||||
|
@ -922,19 +773,15 @@ static int8_t ws_cfg_bbr_default_set(ws_bbr_cfg_t *cfg)
|
|||
return CFG_SETTINGS_OK;
|
||||
}
|
||||
|
||||
int8_t ws_cfg_bbr_get(ws_bbr_cfg_t *cfg, uint8_t *flags)
|
||||
int8_t ws_cfg_bbr_get(ws_bbr_cfg_t *cfg)
|
||||
{
|
||||
ws_bbr_cfg_t *get_cfg = NULL;
|
||||
ws_cfg_to_get((ws_cfgs_t **) &get_cfg, NULL, NULL, (ws_cfgs_t *) &ws_cfg.bbr, 0, flags);
|
||||
*cfg = *get_cfg;
|
||||
|
||||
*cfg = ws_cfg.bbr;
|
||||
return CFG_SETTINGS_OK;
|
||||
}
|
||||
|
||||
int8_t ws_cfg_bbr_validate(ws_bbr_cfg_t *cfg, ws_bbr_cfg_t *new_cfg)
|
||||
int8_t ws_cfg_bbr_validate(ws_bbr_cfg_t *new_cfg)
|
||||
{
|
||||
ws_cfg_to_get((ws_cfgs_t **) &cfg, (ws_cfgs_t *) new_cfg, NULL, (ws_cfgs_t *) &ws_cfg.bbr, 0, 0);
|
||||
|
||||
ws_bbr_cfg_t *cfg = &ws_cfg.bbr;
|
||||
if (cfg->dio_interval_min != new_cfg->dio_interval_min ||
|
||||
cfg->dio_interval_doublings != new_cfg->dio_interval_doublings ||
|
||||
cfg->dio_redundancy_constant != new_cfg->dio_redundancy_constant ||
|
||||
|
@ -948,18 +795,16 @@ int8_t ws_cfg_bbr_validate(ws_bbr_cfg_t *cfg, ws_bbr_cfg_t *new_cfg)
|
|||
return CFG_SETTINGS_OK;
|
||||
}
|
||||
|
||||
int8_t ws_cfg_bbr_set(protocol_interface_info_entry_t *cur, ws_bbr_cfg_t *cfg, ws_bbr_cfg_t *new_cfg, uint8_t *flags)
|
||||
int8_t ws_cfg_bbr_set(protocol_interface_info_entry_t *cur, ws_bbr_cfg_t *new_cfg, uint8_t flags)
|
||||
{
|
||||
(void) cur;
|
||||
(void) flags;
|
||||
|
||||
uint8_t cfg_flags;
|
||||
int8_t ret = ws_cfg_to_get((ws_cfgs_t **) &cfg, (ws_cfgs_t *) new_cfg, (ws_cfg_validate) ws_cfg_bbr_validate, (ws_cfgs_t *) &ws_cfg.bbr, &cfg_flags, flags);
|
||||
if (ret != CFG_SETTINGS_CHANGED) {
|
||||
int8_t ret = ws_cfg_bbr_validate(new_cfg);
|
||||
if (!(flags & CFG_FLAGS_BOOTSTRAP_SET_VALUES) && ret != CFG_SETTINGS_CHANGED) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!(cfg_flags & CFG_FLAGS_DISABLE_VAL_SET)) {
|
||||
if (cur) {
|
||||
// cur is optional, default values are for Wi-SUN small network parameters,
|
||||
ws_bbr_rpl_config(cur, new_cfg->dio_interval_min, new_cfg->dio_interval_doublings,
|
||||
new_cfg->dio_redundancy_constant, new_cfg->dag_max_rank_increase,
|
||||
|
@ -967,10 +812,12 @@ int8_t ws_cfg_bbr_set(protocol_interface_info_entry_t *cur, ws_bbr_cfg_t *cfg, w
|
|||
ws_bbr_dhcp_address_lifetime_set(cur, new_cfg->dhcp_address_lifetime);
|
||||
}
|
||||
|
||||
if (cfg == new_cfg) {
|
||||
if (flags & CFG_FLAGS_BOOTSTRAP_SET_VALUES) {
|
||||
return CFG_SETTINGS_OK;
|
||||
}
|
||||
|
||||
ws_bbr_cfg_t *cfg = &ws_cfg.bbr;
|
||||
|
||||
ws_cfg_trace((ws_cfgs_t *) cfg, (ws_cfgs_t *) new_cfg, sizeof(ws_bbr_cfg_t), "rpl");
|
||||
|
||||
*cfg = *new_cfg;
|
||||
|
@ -990,18 +837,15 @@ static int8_t ws_cfg_mpl_default_set(ws_mpl_cfg_t *cfg)
|
|||
return CFG_SETTINGS_OK;
|
||||
}
|
||||
|
||||
int8_t ws_cfg_mpl_get(ws_mpl_cfg_t *cfg, uint8_t *flags)
|
||||
int8_t ws_cfg_mpl_get(ws_mpl_cfg_t *cfg)
|
||||
{
|
||||
ws_mpl_cfg_t *get_cfg = NULL;
|
||||
ws_cfg_to_get((ws_cfgs_t **) &get_cfg, NULL, NULL, (ws_cfgs_t *) &ws_cfg.mpl, 0, flags);
|
||||
*cfg = *get_cfg;
|
||||
|
||||
*cfg = ws_cfg.mpl;
|
||||
return CFG_SETTINGS_OK;
|
||||
}
|
||||
|
||||
int8_t ws_cfg_mpl_validate(ws_mpl_cfg_t *cfg, ws_mpl_cfg_t *new_cfg)
|
||||
int8_t ws_cfg_mpl_validate(ws_mpl_cfg_t *new_cfg)
|
||||
{
|
||||
ws_cfg_to_get((ws_cfgs_t **) &cfg, (ws_cfgs_t *) new_cfg, NULL, (ws_cfgs_t *) &ws_cfg.mpl, 0, 0);
|
||||
ws_mpl_cfg_t *cfg = &ws_cfg.mpl;
|
||||
|
||||
// MPL configuration has changed
|
||||
if (cfg->mpl_trickle_imin != new_cfg->mpl_trickle_imin ||
|
||||
|
@ -1015,9 +859,9 @@ int8_t ws_cfg_mpl_validate(ws_mpl_cfg_t *cfg, ws_mpl_cfg_t *new_cfg)
|
|||
return CFG_SETTINGS_OK;
|
||||
}
|
||||
|
||||
int8_t ws_cfg_mpl_set(protocol_interface_info_entry_t *cur, ws_mpl_cfg_t *cfg, ws_mpl_cfg_t *new_cfg, uint8_t *flags)
|
||||
int8_t ws_cfg_mpl_set(protocol_interface_info_entry_t *cur, ws_mpl_cfg_t *new_cfg, uint8_t flags)
|
||||
{
|
||||
uint8_t cfg_flags;
|
||||
(void) flags;
|
||||
|
||||
// In Wi-SUN Border router will have modified settings to improve reliability
|
||||
if (cur && cur->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER) {
|
||||
|
@ -1033,12 +877,12 @@ int8_t ws_cfg_mpl_set(protocol_interface_info_entry_t *cur, ws_mpl_cfg_t *cfg, w
|
|||
}
|
||||
}
|
||||
|
||||
int8_t ret = ws_cfg_to_get((ws_cfgs_t **) &cfg, (ws_cfgs_t *) new_cfg, (ws_cfg_validate) ws_cfg_mpl_validate, (ws_cfgs_t *) &ws_cfg.mpl, &cfg_flags, flags);
|
||||
if (ret != CFG_SETTINGS_CHANGED) {
|
||||
int8_t ret = ws_cfg_mpl_validate(new_cfg);
|
||||
if (!(flags & CFG_FLAGS_BOOTSTRAP_SET_VALUES) && ret != CFG_SETTINGS_CHANGED) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (cur && !(cfg_flags & CFG_FLAGS_DISABLE_VAL_SET)) {
|
||||
if (cur) {
|
||||
cur->mpl_data_trickle_params.Imin = MPL_MS_TO_TICKS(new_cfg->mpl_trickle_imin * 1000);
|
||||
cur->mpl_data_trickle_params.Imax = MPL_MS_TO_TICKS(new_cfg->mpl_trickle_imax * 1000);
|
||||
cur->mpl_data_trickle_params.k = new_cfg->mpl_trickle_k;
|
||||
|
@ -1051,10 +895,12 @@ int8_t ws_cfg_mpl_set(protocol_interface_info_entry_t *cur, ws_mpl_cfg_t *cfg, w
|
|||
}
|
||||
}
|
||||
|
||||
if (cfg == new_cfg) {
|
||||
if (flags & CFG_FLAGS_BOOTSTRAP_SET_VALUES) {
|
||||
return CFG_SETTINGS_OK;
|
||||
}
|
||||
|
||||
ws_mpl_cfg_t *cfg = &ws_cfg.mpl;
|
||||
|
||||
ws_cfg_trace((ws_cfgs_t *) cfg, (ws_cfgs_t *) new_cfg, sizeof(ws_mpl_cfg_t), "mpl");
|
||||
|
||||
*cfg = *new_cfg;
|
||||
|
@ -1080,18 +926,15 @@ int8_t ws_cfg_fhss_default_set(ws_fhss_cfg_t *cfg)
|
|||
return CFG_SETTINGS_OK;
|
||||
}
|
||||
|
||||
int8_t ws_cfg_fhss_get(ws_fhss_cfg_t *cfg, uint8_t *flags)
|
||||
int8_t ws_cfg_fhss_get(ws_fhss_cfg_t *cfg)
|
||||
{
|
||||
ws_fhss_cfg_t *get_cfg = NULL;
|
||||
ws_cfg_to_get((ws_cfgs_t **) &get_cfg, NULL, NULL, (ws_cfgs_t *) &ws_cfg.fhss, 0, flags);
|
||||
*cfg = *get_cfg;
|
||||
|
||||
*cfg = ws_cfg.fhss;
|
||||
return CFG_SETTINGS_OK;
|
||||
}
|
||||
|
||||
int8_t ws_cfg_fhss_validate(ws_fhss_cfg_t *cfg, ws_fhss_cfg_t *new_cfg)
|
||||
int8_t ws_cfg_fhss_validate(ws_fhss_cfg_t *new_cfg)
|
||||
{
|
||||
ws_cfg_to_get((ws_cfgs_t **) &cfg, (ws_cfgs_t *) new_cfg, NULL, (ws_cfgs_t *) &ws_cfg.fhss, 0, 0);
|
||||
ws_fhss_cfg_t *cfg = &ws_cfg.fhss;
|
||||
|
||||
if (memcmp(cfg->fhss_channel_mask, new_cfg->fhss_channel_mask, sizeof(uint32_t) * 8) != 0 ||
|
||||
cfg->fhss_uc_dwell_interval != new_cfg->fhss_uc_dwell_interval ||
|
||||
|
@ -1123,20 +966,21 @@ int8_t ws_cfg_fhss_validate(ws_fhss_cfg_t *cfg, ws_fhss_cfg_t *new_cfg)
|
|||
return CFG_SETTINGS_OK;
|
||||
}
|
||||
|
||||
int8_t ws_cfg_fhss_set(protocol_interface_info_entry_t *cur, ws_fhss_cfg_t *cfg, ws_fhss_cfg_t *new_cfg, uint8_t *flags)
|
||||
int8_t ws_cfg_fhss_set(protocol_interface_info_entry_t *cur, ws_fhss_cfg_t *new_cfg, uint8_t flags)
|
||||
{
|
||||
(void) cur;
|
||||
|
||||
uint8_t cfg_flags;
|
||||
int8_t ret = ws_cfg_to_get((ws_cfgs_t **) &cfg, (ws_cfgs_t *) new_cfg, (ws_cfg_validate) ws_cfg_fhss_validate, (ws_cfgs_t *) &ws_cfg.fhss, &cfg_flags, flags);
|
||||
if (ret != CFG_SETTINGS_CHANGED) {
|
||||
int8_t ret = ws_cfg_fhss_validate(new_cfg);
|
||||
if (!(flags & CFG_FLAGS_BOOTSTRAP_SET_VALUES) && ret != CFG_SETTINGS_CHANGED) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (cfg == new_cfg) {
|
||||
if (flags & CFG_FLAGS_BOOTSTRAP_SET_VALUES) {
|
||||
return CFG_SETTINGS_OK;
|
||||
}
|
||||
|
||||
ws_fhss_cfg_t *cfg = &ws_cfg.fhss;
|
||||
|
||||
ws_cfg_trace((ws_cfgs_t *) cfg, (ws_cfgs_t *) new_cfg, sizeof(ws_fhss_cfg_t), "fhss");
|
||||
|
||||
*cfg = *new_cfg;
|
||||
|
@ -1159,7 +1003,7 @@ int8_t ws_cfg_fhss_set(protocol_interface_info_entry_t *cur, ws_fhss_cfg_t *cfg,
|
|||
cfg->fhss_bc_fixed_channel = 0xffff;
|
||||
}
|
||||
|
||||
if (cur && !(cfg_flags & CFG_FLAGS_BOOTSTRAP_RESTART_DISABLE)) {
|
||||
if (cur && !(flags & CFG_FLAGS_BOOTSTRAP_RESTART_DISABLE)) {
|
||||
ws_bootstrap_restart_delayed(cur->id);
|
||||
}
|
||||
|
||||
|
@ -1181,18 +1025,15 @@ static int8_t ws_cfg_sec_timer_default_set(ws_sec_timer_cfg_t *cfg)
|
|||
return CFG_SETTINGS_OK;
|
||||
}
|
||||
|
||||
int8_t ws_cfg_sec_timer_get(ws_sec_timer_cfg_t *cfg, uint8_t *flags)
|
||||
int8_t ws_cfg_sec_timer_get(ws_sec_timer_cfg_t *cfg)
|
||||
{
|
||||
ws_sec_timer_cfg_t *get_cfg = NULL;
|
||||
ws_cfg_to_get((ws_cfgs_t **) &get_cfg, NULL, NULL, (ws_cfgs_t *) &ws_cfg.sec_timer, 0, flags);
|
||||
*cfg = *get_cfg;
|
||||
|
||||
*cfg = ws_cfg.sec_timer;
|
||||
return CFG_SETTINGS_OK;
|
||||
}
|
||||
|
||||
int8_t ws_cfg_sec_timer_validate(ws_sec_timer_cfg_t *cfg, ws_sec_timer_cfg_t *new_cfg)
|
||||
int8_t ws_cfg_sec_timer_validate(ws_sec_timer_cfg_t *new_cfg)
|
||||
{
|
||||
ws_cfg_to_get((ws_cfgs_t **) &cfg, (ws_cfgs_t *) new_cfg, NULL, (ws_cfgs_t *) &ws_cfg.sec_timer, 0, 0);
|
||||
ws_sec_timer_cfg_t *cfg = &ws_cfg.sec_timer;
|
||||
|
||||
if (cfg->gtk_expire_offset != new_cfg->gtk_expire_offset ||
|
||||
cfg->pmk_lifetime != new_cfg->pmk_lifetime ||
|
||||
|
@ -1210,22 +1051,25 @@ int8_t ws_cfg_sec_timer_validate(ws_sec_timer_cfg_t *cfg, ws_sec_timer_cfg_t *ne
|
|||
return CFG_SETTINGS_OK;
|
||||
}
|
||||
|
||||
int8_t ws_cfg_sec_timer_set(protocol_interface_info_entry_t *cur, ws_sec_timer_cfg_t *cfg, ws_sec_timer_cfg_t *new_cfg, uint8_t *flags)
|
||||
int8_t ws_cfg_sec_timer_set(protocol_interface_info_entry_t *cur, ws_sec_timer_cfg_t *new_cfg, uint8_t flags)
|
||||
{
|
||||
uint8_t cfg_flags;
|
||||
int8_t ret = ws_cfg_to_get((ws_cfgs_t **) &cfg, (ws_cfgs_t *) new_cfg, (ws_cfg_validate) ws_cfg_sec_timer_validate, (ws_cfgs_t *) &ws_cfg.sec_timer, &cfg_flags, flags);
|
||||
if (ret != CFG_SETTINGS_CHANGED) {
|
||||
(void) flags;
|
||||
|
||||
int8_t ret = ws_cfg_sec_timer_validate(new_cfg);
|
||||
if (!(flags & CFG_FLAGS_BOOTSTRAP_SET_VALUES) && ret != CFG_SETTINGS_CHANGED) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (cur && !(cfg_flags & CFG_FLAGS_DISABLE_VAL_SET)) {
|
||||
if (cur) {
|
||||
ws_pae_controller_configure(cur, new_cfg, NULL, NULL);
|
||||
}
|
||||
|
||||
if (cfg == new_cfg) {
|
||||
if (flags & CFG_FLAGS_BOOTSTRAP_SET_VALUES) {
|
||||
return CFG_SETTINGS_OK;
|
||||
}
|
||||
|
||||
ws_sec_timer_cfg_t *cfg = &ws_cfg.sec_timer;
|
||||
|
||||
ws_cfg_trace((ws_cfgs_t *) cfg, (ws_cfgs_t *) new_cfg, sizeof(ws_sec_timer_cfg_t), "sec_timer");
|
||||
|
||||
*cfg = *new_cfg;
|
||||
|
@ -1249,18 +1093,15 @@ static int8_t ws_cfg_sec_prot_default_set(ws_sec_prot_cfg_t *cfg)
|
|||
return CFG_SETTINGS_OK;
|
||||
}
|
||||
|
||||
int8_t ws_cfg_sec_prot_get(ws_sec_prot_cfg_t *cfg, uint8_t *flags)
|
||||
int8_t ws_cfg_sec_prot_get(ws_sec_prot_cfg_t *cfg)
|
||||
{
|
||||
ws_sec_prot_cfg_t *get_cfg = NULL;
|
||||
ws_cfg_to_get((ws_cfgs_t **) &get_cfg, NULL, NULL, (ws_cfgs_t *) &ws_cfg.sec_prot, 0, flags);
|
||||
*cfg = *get_cfg;
|
||||
|
||||
*cfg = ws_cfg.sec_prot;
|
||||
return CFG_SETTINGS_OK;
|
||||
}
|
||||
|
||||
int8_t ws_cfg_sec_prot_validate(ws_sec_prot_cfg_t *cfg, ws_sec_prot_cfg_t *new_cfg)
|
||||
int8_t ws_cfg_sec_prot_validate(ws_sec_prot_cfg_t *new_cfg)
|
||||
{
|
||||
ws_cfg_to_get((ws_cfgs_t **) &cfg, (ws_cfgs_t *) new_cfg, NULL, (ws_cfgs_t *) &ws_cfg.sec_prot, 0, 0);
|
||||
ws_sec_prot_cfg_t *cfg = &ws_cfg.sec_prot;
|
||||
|
||||
if (cfg->sec_prot_trickle_imin != new_cfg->sec_prot_trickle_imin ||
|
||||
cfg->sec_prot_trickle_imax != new_cfg->sec_prot_trickle_imax ||
|
||||
|
@ -1279,22 +1120,25 @@ int8_t ws_cfg_sec_prot_validate(ws_sec_prot_cfg_t *cfg, ws_sec_prot_cfg_t *new_c
|
|||
return CFG_SETTINGS_OK;
|
||||
}
|
||||
|
||||
int8_t ws_cfg_sec_prot_set(protocol_interface_info_entry_t *cur, ws_sec_prot_cfg_t *cfg, ws_sec_prot_cfg_t *new_cfg, uint8_t *flags)
|
||||
int8_t ws_cfg_sec_prot_set(protocol_interface_info_entry_t *cur, ws_sec_prot_cfg_t *new_cfg, uint8_t flags)
|
||||
{
|
||||
uint8_t cfg_flags;
|
||||
int8_t ret = ws_cfg_to_get((ws_cfgs_t **) &cfg, (ws_cfgs_t *) new_cfg, (ws_cfg_validate) ws_cfg_sec_prot_validate, (ws_cfgs_t *) &ws_cfg.sec_prot, &cfg_flags, flags);
|
||||
if (ret != CFG_SETTINGS_CHANGED) {
|
||||
(void) flags;
|
||||
|
||||
int8_t ret = ws_cfg_sec_prot_validate(new_cfg);
|
||||
if (!(flags & CFG_FLAGS_BOOTSTRAP_SET_VALUES) && ret != CFG_SETTINGS_CHANGED) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (cur && !(cfg_flags & CFG_FLAGS_DISABLE_VAL_SET)) {
|
||||
if (cur) {
|
||||
ws_pae_controller_configure(cur, NULL, new_cfg, NULL);
|
||||
}
|
||||
|
||||
if (cfg == new_cfg) {
|
||||
if (flags & CFG_FLAGS_BOOTSTRAP_SET_VALUES) {
|
||||
return CFG_SETTINGS_OK;
|
||||
}
|
||||
|
||||
ws_sec_prot_cfg_t *cfg = &ws_cfg.sec_prot;
|
||||
|
||||
ws_cfg_trace((ws_cfgs_t *) cfg, (ws_cfgs_t *) new_cfg, sizeof(ws_sec_prot_cfg_t), "sec_prot");
|
||||
|
||||
*cfg = *new_cfg;
|
||||
|
@ -1324,11 +1168,9 @@ int8_t ws_cfg_settings_default_set(void)
|
|||
|
||||
// Set new configuration values
|
||||
for (uint8_t index = 0; index < CFG_CB_NUM; index++) {
|
||||
uint8_t flags = 0;
|
||||
if (cfg_cb[index].set(NULL,
|
||||
((uint8_t *)&ws_cfg) + cfg_cb[index].setting_offset,
|
||||
((uint8_t *)&ws_cfg) + cfg_cb[index].setting_offset,
|
||||
&flags) < 0) {
|
||||
0x00) < 0) {
|
||||
tr_info("FATAL CONFIG FAILURE");
|
||||
ret_value = CFG_SETTINGS_OTHER_ERROR;
|
||||
}
|
||||
|
@ -1345,13 +1187,11 @@ int8_t ws_cfg_settings_interface_set(protocol_interface_info_entry_t *cur)
|
|||
|
||||
// Set new configuration values
|
||||
for (uint8_t index = 0; index < CFG_CB_NUM; index++) {
|
||||
uint8_t flags = CFG_FLAGS_BOOTSTRAP_RESTART_DISABLE;
|
||||
// Validation
|
||||
if (cfg_cb[index].set) {
|
||||
if (cfg_cb[index].set(cur,
|
||||
((uint8_t *)&ws_cfg) + cfg_cb[index].setting_offset,
|
||||
((uint8_t *)&ws_cfg) + cfg_cb[index].setting_offset,
|
||||
&flags) < 0) {
|
||||
CFG_FLAGS_BOOTSTRAP_RESTART_DISABLE | CFG_FLAGS_BOOTSTRAP_SET_VALUES) < 0) {
|
||||
tr_info("FATAL CONFIG FAILURE");
|
||||
ret_value = CFG_SETTINGS_OTHER_ERROR;
|
||||
}
|
||||
|
@ -1361,30 +1201,19 @@ int8_t ws_cfg_settings_interface_set(protocol_interface_info_entry_t *cur)
|
|||
return ret_value;
|
||||
}
|
||||
|
||||
int8_t ws_cfg_settings_get(protocol_interface_info_entry_t *cur, ws_cfg_t *cfg)
|
||||
int8_t ws_cfg_settings_get(ws_cfg_t *cfg)
|
||||
{
|
||||
(void) cur;
|
||||
|
||||
*cfg = ws_cfg;
|
||||
|
||||
ws_cfg_gen_get(&cfg->gen, NULL);
|
||||
ws_cfg_timing_get(&cfg->timing, NULL);
|
||||
ws_cfg_bbr_get(&cfg->bbr, NULL);
|
||||
ws_cfg_sec_prot_get(&cfg->sec_prot, NULL);
|
||||
ws_cfg_mpl_get(&cfg->mpl, NULL);
|
||||
|
||||
return CFG_SETTINGS_OK;
|
||||
}
|
||||
|
||||
int8_t ws_cfg_settings_validate(protocol_interface_info_entry_t *cur, struct ws_cfg_s *new_cfg)
|
||||
int8_t ws_cfg_settings_validate(struct ws_cfg_s *new_cfg)
|
||||
{
|
||||
(void) cur;
|
||||
|
||||
// Validate new configuration values
|
||||
for (uint8_t index = 0; index < CFG_CB_NUM; index++) {
|
||||
if (cfg_cb[index].validate) {
|
||||
int8_t ret = cfg_cb[index].validate(
|
||||
((uint8_t *)&ws_cfg) + cfg_cb[index].setting_offset,
|
||||
((uint8_t *)new_cfg) + cfg_cb[index].setting_offset);
|
||||
if (ret < 0) {
|
||||
// Validation failed
|
||||
|
@ -1406,7 +1235,6 @@ int8_t ws_cfg_settings_set(protocol_interface_info_entry_t *cur, ws_cfg_t *new_c
|
|||
for (uint8_t index = 0; index < CFG_CB_NUM; index++) {
|
||||
if (cfg_cb[index].validate) {
|
||||
int8_t ret = cfg_cb[index].validate(
|
||||
((uint8_t *)&ws_cfg) + cfg_cb[index].setting_offset,
|
||||
((uint8_t *)new_cfg) + cfg_cb[index].setting_offset);
|
||||
|
||||
if (ret < 0) {
|
||||
|
@ -1425,12 +1253,10 @@ int8_t ws_cfg_settings_set(protocol_interface_info_entry_t *cur, ws_cfg_t *new_c
|
|||
|
||||
// Set new configuration values
|
||||
for (uint8_t index = 0; index < CFG_CB_NUM; index++) {
|
||||
uint8_t flags = 0;
|
||||
// Validation
|
||||
if (call_cfg_set[index]) {
|
||||
if (cfg_cb[index].set(cur,
|
||||
((uint8_t *)&ws_cfg) + cfg_cb[index].setting_offset,
|
||||
((uint8_t *)new_cfg) + cfg_cb[index].setting_offset, &flags) < 0) {
|
||||
((uint8_t *)new_cfg) + cfg_cb[index].setting_offset, 0x00) < 0) {
|
||||
tr_info("FATAL CONFIG FAILURE");
|
||||
ret_value = CFG_SETTINGS_OTHER_ERROR;
|
||||
}
|
||||
|
|
|
@ -26,7 +26,6 @@ typedef struct ws_gen_cfg_s {
|
|||
default values */
|
||||
uint8_t network_size; /**< Network size selection; default medium (= 8) */
|
||||
char network_name[33]; /**< Network name; max 32 octets + terminating 0 */
|
||||
uint16_t network_pan_id; /**< PAN identifier; PAN_ID; default 0xffff */
|
||||
uint16_t rpl_parent_candidate_max; /**< RPL parent candidate maximum value; default 5 */
|
||||
uint16_t rpl_selected_parent_max; /**< RPL selected parent maximum value; default 2 */
|
||||
} ws_gen_cfg_t;
|
||||
|
@ -163,48 +162,50 @@ typedef enum {
|
|||
int8_t ws_cfg_settings_init(void);
|
||||
int8_t ws_cfg_settings_default_set(void);
|
||||
int8_t ws_cfg_settings_interface_set(protocol_interface_info_entry_t *cur);
|
||||
int8_t ws_cfg_network_size_configure(protocol_interface_info_entry_t *cur, uint16_t network_size);
|
||||
int8_t ws_cfg_settings_get(ws_cfg_t *cfg);
|
||||
int8_t ws_cfg_settings_validate(struct ws_cfg_s *new_cfg);
|
||||
int8_t ws_cfg_settings_set(protocol_interface_info_entry_t *cur, ws_cfg_t *new_cfg);
|
||||
|
||||
cfg_network_size_type_e ws_cfg_network_config_get(protocol_interface_info_entry_t *cur);
|
||||
|
||||
int8_t ws_cfg_network_size_get(ws_gen_cfg_t *cfg, uint8_t *flags);
|
||||
int8_t ws_cfg_network_size_validate(ws_gen_cfg_t *cfg, ws_gen_cfg_t *new_cfg);
|
||||
int8_t ws_cfg_network_size_set(protocol_interface_info_entry_t *cur, ws_gen_cfg_t *cfg, ws_gen_cfg_t *new_cfg, uint8_t *flags);
|
||||
int8_t ws_cfg_network_size_get(ws_gen_cfg_t *cfg);
|
||||
int8_t ws_cfg_network_size_validate(ws_gen_cfg_t *new_cfg);
|
||||
int8_t ws_cfg_network_size_set(protocol_interface_info_entry_t *cur, ws_gen_cfg_t *new_cfg, uint8_t flags);
|
||||
|
||||
int8_t ws_cfg_gen_get(ws_gen_cfg_t *cfg, uint8_t *flags);
|
||||
int8_t ws_cfg_gen_validate(ws_gen_cfg_t *cfg, ws_gen_cfg_t *new_cfg);
|
||||
int8_t ws_cfg_gen_set(protocol_interface_info_entry_t *cur, ws_gen_cfg_t *cfg, ws_gen_cfg_t *new_cfg, uint8_t *flags);
|
||||
int8_t ws_cfg_gen_get(ws_gen_cfg_t *cfg);
|
||||
int8_t ws_cfg_gen_validate(ws_gen_cfg_t *new_cfg);
|
||||
int8_t ws_cfg_gen_set(protocol_interface_info_entry_t *cur, ws_gen_cfg_t *new_cfg, uint8_t flags);
|
||||
|
||||
int8_t ws_cfg_phy_default_set(ws_phy_cfg_t *cfg);
|
||||
int8_t ws_cfg_phy_get(ws_phy_cfg_t *cfg, uint8_t *flags);
|
||||
int8_t ws_cfg_phy_validate(ws_phy_cfg_t *cfg, ws_phy_cfg_t *new_cfg);
|
||||
int8_t ws_cfg_phy_set(protocol_interface_info_entry_t *cur, ws_phy_cfg_t *cfg, ws_phy_cfg_t *new_cfg, uint8_t *flags);
|
||||
int8_t ws_cfg_phy_get(ws_phy_cfg_t *cfg);
|
||||
int8_t ws_cfg_phy_validate(ws_phy_cfg_t *new_cfg);
|
||||
int8_t ws_cfg_phy_set(protocol_interface_info_entry_t *cur, ws_phy_cfg_t *new_cfg, uint8_t flags);
|
||||
|
||||
int8_t ws_cfg_timing_default_set(ws_timing_cfg_t *cfg);
|
||||
int8_t ws_cfg_timing_get(ws_timing_cfg_t *cfg, uint8_t *flags);
|
||||
int8_t ws_cfg_timing_validate(ws_timing_cfg_t *cfg, ws_timing_cfg_t *new_cfg);
|
||||
int8_t ws_cfg_timing_set(protocol_interface_info_entry_t *cur, ws_timing_cfg_t *cfg, ws_timing_cfg_t *new_cfg, uint8_t *flags);
|
||||
int8_t ws_cfg_timing_get(ws_timing_cfg_t *cfg);
|
||||
int8_t ws_cfg_timing_validate(ws_timing_cfg_t *new_cfg);
|
||||
int8_t ws_cfg_timing_set(protocol_interface_info_entry_t *cur, ws_timing_cfg_t *new_cfg, uint8_t flags);
|
||||
|
||||
int8_t ws_cfg_bbr_get(ws_bbr_cfg_t *cfg, uint8_t *flags);
|
||||
int8_t ws_cfg_bbr_validate(ws_bbr_cfg_t *cfg, ws_bbr_cfg_t *new_cfg);
|
||||
int8_t ws_cfg_bbr_set(protocol_interface_info_entry_t *cur, ws_bbr_cfg_t *cfg, ws_bbr_cfg_t *new_cfg, uint8_t *flags);
|
||||
int8_t ws_cfg_bbr_get(ws_bbr_cfg_t *cfg);
|
||||
int8_t ws_cfg_bbr_validate(ws_bbr_cfg_t *new_cfg);
|
||||
int8_t ws_cfg_bbr_set(protocol_interface_info_entry_t *cur, ws_bbr_cfg_t *new_cfg, uint8_t flags);
|
||||
|
||||
int8_t ws_cfg_mpl_get(ws_mpl_cfg_t *cfg, uint8_t *flags);
|
||||
int8_t ws_cfg_mpl_validate(ws_mpl_cfg_t *cfg, ws_mpl_cfg_t *new_cfg);
|
||||
int8_t ws_cfg_mpl_set(protocol_interface_info_entry_t *cur, ws_mpl_cfg_t *cfg, ws_mpl_cfg_t *new_cfg, uint8_t *flags);
|
||||
int8_t ws_cfg_mpl_get(ws_mpl_cfg_t *cfg);
|
||||
int8_t ws_cfg_mpl_validate(ws_mpl_cfg_t *new_cfg);
|
||||
int8_t ws_cfg_mpl_set(protocol_interface_info_entry_t *cur, ws_mpl_cfg_t *new_cfg, uint8_t flags);
|
||||
|
||||
int8_t ws_cfg_fhss_default_set(ws_fhss_cfg_t *cfg);
|
||||
int8_t ws_cfg_fhss_get(ws_fhss_cfg_t *cfg, uint8_t *flags);
|
||||
int8_t ws_cfg_fhss_validate(ws_fhss_cfg_t *cfg, ws_fhss_cfg_t *new_cfg);
|
||||
int8_t ws_cfg_fhss_set(protocol_interface_info_entry_t *cur, ws_fhss_cfg_t *cfg, ws_fhss_cfg_t *new_cfg, uint8_t *flags);
|
||||
int8_t ws_cfg_fhss_get(ws_fhss_cfg_t *cfg);
|
||||
int8_t ws_cfg_fhss_validate(ws_fhss_cfg_t *new_cfg);
|
||||
int8_t ws_cfg_fhss_set(protocol_interface_info_entry_t *cur, ws_fhss_cfg_t *new_cfg, uint8_t flags);
|
||||
|
||||
int8_t ws_cfg_sec_timer_get(ws_sec_timer_cfg_t *cfg, uint8_t *flags);
|
||||
int8_t ws_cfg_sec_timer_validate(ws_sec_timer_cfg_t *cfg, ws_sec_timer_cfg_t *new_cfg);
|
||||
int8_t ws_cfg_sec_timer_set(protocol_interface_info_entry_t *cur, ws_sec_timer_cfg_t *cfg, ws_sec_timer_cfg_t *new_cfg, uint8_t *flags);
|
||||
int8_t ws_cfg_sec_timer_get(ws_sec_timer_cfg_t *cfg);
|
||||
int8_t ws_cfg_sec_timer_validate(ws_sec_timer_cfg_t *new_cfg);
|
||||
int8_t ws_cfg_sec_timer_set(protocol_interface_info_entry_t *cur, ws_sec_timer_cfg_t *new_cfg, uint8_t flags);
|
||||
|
||||
int8_t ws_cfg_sec_prot_get(ws_sec_prot_cfg_t *cfg, uint8_t *flags);
|
||||
int8_t ws_cfg_sec_prot_validate(ws_sec_prot_cfg_t *cfg, ws_sec_prot_cfg_t *new_cfg);
|
||||
int8_t ws_cfg_sec_prot_set(protocol_interface_info_entry_t *cur, ws_sec_prot_cfg_t *cfg, ws_sec_prot_cfg_t *new_cfg, uint8_t *flags);
|
||||
int8_t ws_cfg_sec_prot_get(ws_sec_prot_cfg_t *cfg);
|
||||
int8_t ws_cfg_sec_prot_validate(ws_sec_prot_cfg_t *new_cfg);
|
||||
int8_t ws_cfg_sec_prot_set(protocol_interface_info_entry_t *cur, ws_sec_prot_cfg_t *new_cfg, uint8_t flags);
|
||||
|
||||
uint32_t ws_cfg_neighbour_temporary_lifetime_get(void);
|
||||
void ws_cfg_neighbour_temporary_lifetime_set(uint32_t lifetime);
|
||||
|
|
|
@ -20,21 +20,28 @@
|
|||
#include "ns_types.h"
|
||||
#include "ns_trace.h"
|
||||
#include "randLIB.h"
|
||||
#include "common_functions.h"
|
||||
#include <ns_list.h>
|
||||
#include <nsdynmemLIB.h>
|
||||
#include "Common_Protocols/icmpv6.h"
|
||||
#include "mac_common_defines.h"
|
||||
#include "net_interface.h"
|
||||
#include "eventOS_event.h"
|
||||
#include "6LoWPAN/MAC/mpx_api.h"
|
||||
#include "6LoWPAN/ws/ws_config.h"
|
||||
#include "6LoWPAN/ws/ws_common_defines.h"
|
||||
#include "6LoWPAN/ws/ws_llc.h"
|
||||
#include "6LoWPAN/ws/ws_common.h"
|
||||
#include "6LoWPAN/ws/ws_bootstrap.h"
|
||||
#include "6LoWPAN/ws/ws_bootstrap_6lbr.h"
|
||||
#include "6LoWPAN/ws/ws_bootstrap_ffn.h"
|
||||
#include "6LoWPAN/ws/ws_bootstrap_lfn.h"
|
||||
#include "6LoWPAN/ws/ws_bbr_api_internal.h"
|
||||
#include "6LoWPAN/ws/ws_pae_controller.h"
|
||||
#include "6LoWPAN/ws/ws_cfg_settings.h"
|
||||
#include "6LoWPAN/ws/ws_stats.h"
|
||||
#include "6LoWPAN/ws/ws_ie_lib.h"
|
||||
#include "6LoWPAN/ws/ws_phy.h"
|
||||
#include "Service_Libs/etx/etx.h"
|
||||
#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h"
|
||||
#include "Service_Libs/blacklist/blacklist.h"
|
||||
|
@ -58,13 +65,13 @@ static int8_t ws_disable_channels_in_range(uint32_t *channel_mask, uint16_t numb
|
|||
{
|
||||
for (uint16_t i = 0; i < number_of_channels; i++) {
|
||||
if (i >= range_start && i <= range_stop) {
|
||||
channel_mask[0 + (i / 32)] &= ~(1 << (i % 32));
|
||||
channel_mask[i / 32] &= ~(1U << (i % 32));
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int8_t ws_generate_channel_list(uint32_t *channel_mask, uint16_t number_of_channels, uint8_t regulatory_domain, uint8_t operating_class, uint8_t channel_plan_id)
|
||||
int8_t ws_common_generate_channel_list(uint32_t *channel_mask, uint16_t number_of_channels, uint8_t regulatory_domain, uint8_t operating_class, uint8_t channel_plan_id)
|
||||
{
|
||||
// Clear channel mask
|
||||
for (uint8_t i = 0; i < 8; i++) {
|
||||
|
@ -72,7 +79,7 @@ int8_t ws_generate_channel_list(uint32_t *channel_mask, uint16_t number_of_chann
|
|||
}
|
||||
// Enable all channels
|
||||
for (uint16_t i = 0; i < number_of_channels; i++) {
|
||||
channel_mask[0 + (i / 32)] |= (1 << (i % 32));
|
||||
channel_mask[i / 32] |= 1U << (i % 32);
|
||||
}
|
||||
// Disable unsupported channels per regional frequency bands
|
||||
if (regulatory_domain == REG_DOMAIN_BZ) {
|
||||
|
@ -93,121 +100,38 @@ int8_t ws_generate_channel_list(uint32_t *channel_mask, uint16_t number_of_chann
|
|||
ws_disable_channels_in_range(channel_mask, number_of_channels, 3, 10);
|
||||
}
|
||||
}
|
||||
} else if (regulatory_domain == REG_DOMAIN_EU) {
|
||||
if (channel_plan_id == 32) {
|
||||
ws_disable_channels_in_range(channel_mask, number_of_channels, 55, 56);
|
||||
ws_disable_channels_in_range(channel_mask, number_of_channels, 61, 63);
|
||||
ws_disable_channels_in_range(channel_mask, number_of_channels, 65, 66);
|
||||
} else if (channel_plan_id == 33) {
|
||||
ws_disable_channels_in_range(channel_mask, number_of_channels, 27, 28);
|
||||
ws_disable_channels_in_range(channel_mask, number_of_channels, 30, 33);
|
||||
} else if (channel_plan_id == 36) {
|
||||
ws_disable_channels_in_range(channel_mask, number_of_channels, 55, 56);
|
||||
ws_disable_channels_in_range(channel_mask, number_of_channels, 61, 63);
|
||||
ws_disable_channels_in_range(channel_mask, number_of_channels, 65, 66);
|
||||
} else if (channel_plan_id == 37) {
|
||||
ws_disable_channels_in_range(channel_mask, number_of_channels, 27, 28);
|
||||
ws_disable_channels_in_range(channel_mask, number_of_channels, 30, 33);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t ws_active_channel_count(uint32_t *channel_mask, uint16_t number_of_channels)
|
||||
uint16_t ws_common_active_channel_count(uint32_t *channel_mask, uint16_t number_of_channels)
|
||||
{
|
||||
uint16_t active_channels = 0;
|
||||
// Set channel maks outside excluded channels
|
||||
for (uint16_t i = 0; i < number_of_channels; i++) {
|
||||
if (channel_mask[0 + (i / 32)] & (1 << (i % 32))) {
|
||||
if (channel_mask[i / 32] & (1U << (i % 32))) {
|
||||
active_channels++;
|
||||
}
|
||||
}
|
||||
return active_channels;
|
||||
}
|
||||
|
||||
uint32_t ws_decode_channel_spacing(uint8_t channel_spacing)
|
||||
{
|
||||
if (CHANNEL_SPACING_100 == channel_spacing) {
|
||||
return 100000;
|
||||
} else if (CHANNEL_SPACING_200 == channel_spacing) {
|
||||
return 200000;
|
||||
} else if (CHANNEL_SPACING_250 == channel_spacing) {
|
||||
return 250000;
|
||||
} else if (CHANNEL_SPACING_400 == channel_spacing) {
|
||||
return 400000;
|
||||
} else if (CHANNEL_SPACING_600 == channel_spacing) {
|
||||
return 600000;
|
||||
} else if (CHANNEL_SPACING_800 == channel_spacing) {
|
||||
return 800000;
|
||||
} else if (CHANNEL_SPACING_1200 == channel_spacing) {
|
||||
return 1200000;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t ws_get_datarate_using_operating_mode(uint8_t operating_mode)
|
||||
{
|
||||
if ((OPERATING_MODE_1a == operating_mode) || (OPERATING_MODE_1b == operating_mode)) {
|
||||
return 50000;
|
||||
} else if ((OPERATING_MODE_2a == operating_mode) || (OPERATING_MODE_2b == operating_mode)) {
|
||||
return 100000;
|
||||
} else if (OPERATING_MODE_3 == operating_mode) {
|
||||
return 150000;
|
||||
} else if ((OPERATING_MODE_4a == operating_mode) || (OPERATING_MODE_4b == operating_mode)) {
|
||||
return 200000;
|
||||
} else if (OPERATING_MODE_5 == operating_mode) {
|
||||
return 300000;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t ws_get_datarate_using_phy_mode_id(uint8_t phy_mode_id)
|
||||
{
|
||||
if (84 == phy_mode_id) {
|
||||
return 150000;
|
||||
} else if (85 == phy_mode_id) {
|
||||
return 200000;
|
||||
} else if ((68 == phy_mode_id) || (86 == phy_mode_id)) {
|
||||
return 300000;
|
||||
} else if ((34 == phy_mode_id) || (51 == phy_mode_id) || (69 == phy_mode_id)) {
|
||||
return 400000;
|
||||
} else if ((52 == phy_mode_id) || (70 == phy_mode_id)) {
|
||||
return 600000;
|
||||
} else if ((35 == phy_mode_id) || (53 == phy_mode_id)) {
|
||||
return 800000;
|
||||
} else if ((36 == phy_mode_id) || (54 == phy_mode_id)) {
|
||||
return 1200000;
|
||||
} else if (37 == phy_mode_id) {
|
||||
return 1600000;
|
||||
} else if (38 == phy_mode_id) {
|
||||
return 2400000;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t ws_get_ofdm_option_using_phy_mode_id(uint8_t phy_mode_id)
|
||||
{
|
||||
if ((phy_mode_id >= 34) && (phy_mode_id <= 38)) {
|
||||
return OFDM_OPTION_1;
|
||||
} else if ((phy_mode_id >= 51) && (phy_mode_id <= 54)) {
|
||||
return OFDM_OPTION_2;
|
||||
} else if ((phy_mode_id >= 68) && (phy_mode_id <= 70)) {
|
||||
return OFDM_OPTION_3;
|
||||
} else if ((phy_mode_id >= 84) && (phy_mode_id <= 86)) {
|
||||
return OFDM_OPTION_4;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t ws_get_ofdm_mcs_using_phy_mode_id(uint8_t phy_mode_id)
|
||||
{
|
||||
if (34 == phy_mode_id) {
|
||||
return OFDM_MCS_2;
|
||||
} else if ((35 == phy_mode_id) || (51 == phy_mode_id)) {
|
||||
return OFDM_MCS_3;
|
||||
} else if ((36 == phy_mode_id) || (52 == phy_mode_id) || (68 == phy_mode_id) || (84 == phy_mode_id)) {
|
||||
return OFDM_MCS_4;
|
||||
} else if ((37 == phy_mode_id) || (53 == phy_mode_id) || (69 == phy_mode_id) || (85 == phy_mode_id)) {
|
||||
return OFDM_MCS_5;
|
||||
} else if ((38 == phy_mode_id) || (54 == phy_mode_id) || (70 == phy_mode_id) || (86 == phy_mode_id)) {
|
||||
return OFDM_MCS_6;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
phy_modulation_index_e ws_get_modulation_index_using_operating_mode(uint8_t operating_mode)
|
||||
{
|
||||
if ((OPERATING_MODE_1b == operating_mode) || (OPERATING_MODE_2b == operating_mode) || (OPERATING_MODE_4b == operating_mode)) {
|
||||
return MODULATION_INDEX_1_0;
|
||||
} else {
|
||||
return MODULATION_INDEX_0_5;
|
||||
}
|
||||
}
|
||||
|
||||
int8_t ws_common_regulatory_domain_config(protocol_interface_info_entry_t *cur, ws_hopping_schedule_t *hopping_schdule)
|
||||
{
|
||||
(void)cur;
|
||||
|
@ -229,23 +153,18 @@ int8_t ws_common_regulatory_domain_config(protocol_interface_info_entry_t *cur,
|
|||
if (phy_type >= 2 && phy_mode > 6) {
|
||||
return -1;
|
||||
}
|
||||
// Skip if PHY mode is for FSK modulation
|
||||
if (!phy_mode_id || ((phy_mode_id > 8) && (phy_mode_id < 17)) || phy_mode_id > 24) {
|
||||
|
||||
if (M_OFDM == ws_phy_get_modulation_using_phy_mode_id(phy_mode_id)) {
|
||||
// Validate OFDM configurations
|
||||
if (((phy_mode_id >= 34) && (phy_mode_id <= 38)) ||
|
||||
((phy_mode_id >= 51) && (phy_mode_id <= 54)) ||
|
||||
((phy_mode_id >= 68) && (phy_mode_id <= 70)) ||
|
||||
((phy_mode_id >= 84) && (phy_mode_id <= 86))) {
|
||||
if (ws_get_datarate_using_phy_mode_id(phy_mode_id) == 0 ||
|
||||
ws_get_ofdm_option_using_phy_mode_id(phy_mode_id) == 0 ||
|
||||
ws_get_ofdm_mcs_using_phy_mode_id(phy_mode_id) == 0) {
|
||||
//Unsupported PHY mode
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
// Invalid PHY mode ID
|
||||
if (!ws_phy_get_datarate_using_phy_mode_id(phy_mode_id) ||
|
||||
!ws_phy_get_ofdm_option_using_phy_mode_id(phy_mode_id) ||
|
||||
!ws_phy_get_ofdm_mcs_using_phy_mode_id(phy_mode_id)) {
|
||||
//Unsupported PHY mode
|
||||
return -1;
|
||||
}
|
||||
} else if (M_UNDEFINED == ws_phy_get_modulation_using_phy_mode_id(phy_mode_id)) {
|
||||
// Invalid PHY mode ID
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
hopping_schdule->channel_plan = 0;
|
||||
|
@ -261,20 +180,44 @@ int8_t ws_common_regulatory_domain_config(protocol_interface_info_entry_t *cur,
|
|||
return -1;
|
||||
}
|
||||
} else if (hopping_schdule->regulatory_domain == REG_DOMAIN_EU) {
|
||||
if (hopping_schdule->operating_class == 1) {
|
||||
hopping_schdule->ch0_freq = 8631;
|
||||
hopping_schdule->channel_spacing = CHANNEL_SPACING_100;
|
||||
} else if (hopping_schdule->operating_class == 2) {
|
||||
hopping_schdule->ch0_freq = 8631;
|
||||
hopping_schdule->channel_spacing = CHANNEL_SPACING_200;
|
||||
} else if (hopping_schdule->operating_class == 3) {
|
||||
hopping_schdule->ch0_freq = 8701;
|
||||
hopping_schdule->channel_spacing = CHANNEL_SPACING_100;
|
||||
} else if (hopping_schdule->operating_class == 4) {
|
||||
hopping_schdule->ch0_freq = 8702;
|
||||
hopping_schdule->channel_spacing = CHANNEL_SPACING_200;
|
||||
if (hopping_schdule->channel_plan_id == 255) {
|
||||
if (hopping_schdule->operating_class == 1) {
|
||||
hopping_schdule->ch0_freq = 8631;
|
||||
hopping_schdule->channel_spacing = CHANNEL_SPACING_100;
|
||||
} else if (hopping_schdule->operating_class == 2) {
|
||||
hopping_schdule->ch0_freq = 8631;
|
||||
hopping_schdule->channel_spacing = CHANNEL_SPACING_200;
|
||||
} else if (hopping_schdule->operating_class == 3) {
|
||||
hopping_schdule->ch0_freq = 8701;
|
||||
hopping_schdule->channel_spacing = CHANNEL_SPACING_100;
|
||||
} else if (hopping_schdule->operating_class == 4) {
|
||||
hopping_schdule->ch0_freq = 8702;
|
||||
hopping_schdule->channel_spacing = CHANNEL_SPACING_200;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
return -1;
|
||||
if (hopping_schdule->channel_plan_id == 32) {
|
||||
hopping_schdule->ch0_freq = 8631;
|
||||
hopping_schdule->channel_spacing = CHANNEL_SPACING_100;
|
||||
} else if (hopping_schdule->channel_plan_id == 33) {
|
||||
hopping_schdule->ch0_freq = 8631;
|
||||
hopping_schdule->channel_spacing = CHANNEL_SPACING_200;
|
||||
} else if (hopping_schdule->channel_plan_id == 34) {
|
||||
hopping_schdule->ch0_freq = 8701;
|
||||
hopping_schdule->channel_spacing = CHANNEL_SPACING_100;
|
||||
} else if (hopping_schdule->channel_plan_id == 35) {
|
||||
hopping_schdule->ch0_freq = 8702;
|
||||
hopping_schdule->channel_spacing = CHANNEL_SPACING_200;
|
||||
} else if (hopping_schdule->channel_plan_id == 36) {
|
||||
hopping_schdule->ch0_freq = 8631;
|
||||
hopping_schdule->channel_spacing = CHANNEL_SPACING_100;
|
||||
} else if (hopping_schdule->channel_plan_id == 37) {
|
||||
hopping_schdule->ch0_freq = 8631;
|
||||
hopping_schdule->channel_spacing = CHANNEL_SPACING_200;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
} else if (hopping_schdule->regulatory_domain == REG_DOMAIN_IN) {
|
||||
if (hopping_schdule->operating_class == 1) {
|
||||
|
@ -385,15 +328,10 @@ uint16_t ws_common_channel_number_calc(uint8_t regulatory_domain, uint8_t operat
|
|||
return 16;
|
||||
}
|
||||
} else if (regulatory_domain == REG_DOMAIN_EU) {
|
||||
if (operating_class == 1) {
|
||||
return 69;
|
||||
} else if (operating_class == 2) {
|
||||
return 35;
|
||||
} else if (operating_class == 3) {
|
||||
return 55;
|
||||
} else if (operating_class == 4) {
|
||||
return 27;
|
||||
if (channel_plan_id == 255) {
|
||||
channel_plan_id = ws_phy_convert_operating_class_to_channel_plan_id(operating_class, regulatory_domain);
|
||||
}
|
||||
return ws_phy_get_number_of_channels_using_channel_plan_id(channel_plan_id);
|
||||
} else if (regulatory_domain == REG_DOMAIN_IN) {
|
||||
if (operating_class == 1) {
|
||||
return 19;
|
||||
|
@ -402,22 +340,9 @@ uint16_t ws_common_channel_number_calc(uint8_t regulatory_domain, uint8_t operat
|
|||
}
|
||||
} else if (regulatory_domain == REG_DOMAIN_NA) {
|
||||
if (channel_plan_id == 255) {
|
||||
if (operating_class == 1) {
|
||||
return 129;
|
||||
} else if (operating_class == 2) {
|
||||
return 64;
|
||||
} else if (operating_class == 3) {
|
||||
return 42;
|
||||
}
|
||||
} else {
|
||||
if (channel_plan_id == 1) {
|
||||
return 129;
|
||||
} else if (channel_plan_id == 2) {
|
||||
return 64;
|
||||
} else if (channel_plan_id == 5) {
|
||||
return 21;
|
||||
}
|
||||
channel_plan_id = ws_phy_convert_operating_class_to_channel_plan_id(operating_class, regulatory_domain);
|
||||
}
|
||||
return ws_phy_get_number_of_channels_using_channel_plan_id(channel_plan_id);
|
||||
} else if (regulatory_domain == REG_DOMAIN_JP) {
|
||||
if (operating_class == 1) {
|
||||
return 38;
|
||||
|
@ -428,22 +353,9 @@ uint16_t ws_common_channel_number_calc(uint8_t regulatory_domain, uint8_t operat
|
|||
}
|
||||
} else if (regulatory_domain == REG_DOMAIN_BZ) {
|
||||
if (channel_plan_id == 255) {
|
||||
if (operating_class == 1) {
|
||||
return 129;
|
||||
} else if (operating_class == 2) {
|
||||
return 64;
|
||||
} else if (operating_class == 3) {
|
||||
return 42;
|
||||
}
|
||||
} else {
|
||||
if (channel_plan_id == 1) {
|
||||
return 129;
|
||||
} else if (channel_plan_id == 2) {
|
||||
return 64;
|
||||
} else if (channel_plan_id == 5) {
|
||||
return 21;
|
||||
}
|
||||
channel_plan_id = ws_phy_convert_operating_class_to_channel_plan_id(operating_class, regulatory_domain);
|
||||
}
|
||||
return ws_phy_get_number_of_channels_using_channel_plan_id(channel_plan_id);
|
||||
} else if (regulatory_domain == REG_DOMAIN_WW) {
|
||||
if (operating_class == 1) {
|
||||
// TODO we dont support this yet, but it is used as test value
|
||||
|
@ -472,12 +384,13 @@ int8_t ws_common_allocate_and_init(protocol_interface_info_entry_t *cur)
|
|||
ns_list_init(&cur->ws_info->parent_list_free);
|
||||
ns_list_init(&cur->ws_info->parent_list_reserved);
|
||||
|
||||
cur->ws_info->version = test_pan_version;
|
||||
|
||||
cur->ws_info->network_pan_id = 0xffff;
|
||||
cur->ws_info->pan_information.use_parent_bs = true;
|
||||
cur->ws_info->pan_information.rpl_routing_method = true;
|
||||
cur->ws_info->pan_information.pan_version_set = false;
|
||||
cur->ws_info->pan_information.version = WS_FAN_VERSION_1_0;
|
||||
|
||||
cur->ws_info->pending_key_index_info.state = NO_PENDING_PROCESS;
|
||||
|
||||
cur->ws_info->hopping_schdule.regulatory_domain = REG_DOMAIN_EU;
|
||||
|
@ -490,14 +403,40 @@ int8_t ws_common_allocate_and_init(protocol_interface_info_entry_t *cur)
|
|||
ws_common_regulatory_domain_config(cur, &cur->ws_info->hopping_schdule);
|
||||
cur->ws_info->pending_key_index_info.state = NO_PENDING_PROCESS;
|
||||
|
||||
|
||||
// initialize for FAN 1.1 defaults
|
||||
if (ws_version_1_1(cur)) {
|
||||
cur->ws_info->pan_information.version = WS_FAN_VERSION_1_1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ws_common_init(int8_t interface_id, net_6lowpan_mode_e bootstrap_mode)
|
||||
{
|
||||
return ws_bootstrap_init(interface_id, bootstrap_mode);
|
||||
}
|
||||
|
||||
void ws_common_state_machine(protocol_interface_info_entry_t *cur)
|
||||
{
|
||||
if (wisun_mode_host(cur)) {
|
||||
// Configure for LFN device
|
||||
ws_bootstrap_lfn_state_machine(cur);
|
||||
} else if (wisun_mode_router(cur)) {
|
||||
// Configure FFN device
|
||||
ws_bootstrap_ffn_state_machine(cur);
|
||||
} else if (wisun_mode_border_router(cur)) {
|
||||
// Configure as Border router
|
||||
ws_bootstrap_6lbr_state_machine(cur);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ws_common_seconds_timer(protocol_interface_info_entry_t *cur, uint32_t seconds)
|
||||
{
|
||||
ws_bbr_seconds_timer(cur, seconds);
|
||||
ws_bootstrap_seconds_timer(cur, seconds);
|
||||
ws_bootstrap_6lbr_seconds_timer(cur, seconds);
|
||||
ws_bootstrap_ffn_seconds_timer(cur, seconds);
|
||||
ws_bootstrap_lfn_seconds_timer(cur, seconds);
|
||||
blacklist_ttl_update(seconds);
|
||||
}
|
||||
|
||||
|
@ -508,6 +447,12 @@ void ws_common_fast_timer(protocol_interface_info_entry_t *cur, uint16_t ticks)
|
|||
ws_llc_fast_timer(cur, ticks);
|
||||
}
|
||||
|
||||
void ws_common_create_ll_address(uint8_t *ll_address, const uint8_t *mac64)
|
||||
{
|
||||
memcpy(ll_address, ADDR_LINK_LOCAL_PREFIX, 8);
|
||||
memcpy(ll_address + 8, mac64, 8);
|
||||
ll_address[8] ^= 2;
|
||||
}
|
||||
|
||||
void ws_common_neighbor_update(protocol_interface_info_entry_t *cur, const uint8_t *ll_address)
|
||||
{
|
||||
|
@ -652,13 +597,10 @@ uint32_t ws_common_latency_estimate_get(protocol_interface_info_entry_t *cur)
|
|||
|
||||
uint32_t ws_common_datarate_get_from_phy_mode(uint8_t phy_mode_id, uint8_t operating_mode)
|
||||
{
|
||||
if (((phy_mode_id >= 34) && (phy_mode_id <= 38)) ||
|
||||
((phy_mode_id >= 51) && (phy_mode_id <= 54)) ||
|
||||
((phy_mode_id >= 68) && (phy_mode_id <= 70)) ||
|
||||
((phy_mode_id >= 84) && (phy_mode_id <= 86))) {
|
||||
return ws_get_datarate_using_phy_mode_id(phy_mode_id);
|
||||
if (phy_mode_id == 255) {
|
||||
phy_mode_id = ws_phy_convert_operating_mode_to_phy_mode_id(operating_mode);
|
||||
}
|
||||
return ws_get_datarate_using_operating_mode(operating_mode);
|
||||
return ws_phy_get_datarate_using_phy_mode_id(phy_mode_id);
|
||||
}
|
||||
|
||||
uint32_t ws_common_datarate_get(protocol_interface_info_entry_t *cur)
|
||||
|
@ -737,4 +679,16 @@ void ws_common_border_router_alive_update(protocol_interface_info_entry_t *inter
|
|||
interface->ws_info->pan_timeout_timer = interface->ws_info->cfg->timing.pan_timeout;
|
||||
}
|
||||
|
||||
fhss_ws_configuration_t ws_common_get_current_fhss_configuration(protocol_interface_info_entry_t *cur)
|
||||
{
|
||||
fhss_ws_configuration_t fhss_configuration;
|
||||
memset(&fhss_configuration, 0, sizeof(fhss_ws_configuration_t));
|
||||
if (ns_fhss_ws_configuration_get(cur->ws_info->fhss_api)) {
|
||||
memcpy(&fhss_configuration, ns_fhss_ws_configuration_get(cur->ws_info->fhss_api), sizeof(fhss_ws_configuration_t));
|
||||
} else {
|
||||
tr_error("FHSS configuration could not be read");
|
||||
}
|
||||
return fhss_configuration;
|
||||
}
|
||||
|
||||
#endif // HAVE_WS
|
||||
|
|
|
@ -37,6 +37,8 @@ struct ws_pan_information_s;
|
|||
struct ws_neighbor_class_s;
|
||||
struct ws_excluded_channel_data_s;
|
||||
struct ws_cfg_s;
|
||||
struct ws_neighbor_class_entry;
|
||||
struct mcps_data_ie_list;
|
||||
|
||||
typedef struct parent_info_s {
|
||||
uint16_t pan_id; /**< PAN ID */
|
||||
|
@ -79,6 +81,30 @@ typedef struct {
|
|||
uint16_t old_bsi;
|
||||
} ws_bsi_block_t;
|
||||
|
||||
typedef struct {
|
||||
uint16_t eapol_trigger_timer;
|
||||
uint16_t pas_trigger_timer;
|
||||
uint16_t pcs_trigger_timer;
|
||||
uint16_t dis_trigger_timer;
|
||||
uint16_t dis_trigger_timer_val;
|
||||
uint16_t rpl_trigger_timer;
|
||||
uint16_t rpl_trigger_timer_val;
|
||||
uint8_t pas_trigger_count;
|
||||
uint8_t pcs_trigger_count;
|
||||
bool auto_trg_enabled;
|
||||
} ws_test_proc_trg_t;
|
||||
|
||||
typedef struct {
|
||||
uint16_t lfn_version;
|
||||
bool lfn_version_learned: 1;
|
||||
bool active_hash_1: 1;
|
||||
bool active_hash_2: 1;
|
||||
bool active_hash_3: 1;
|
||||
unsigned active_key_index: 2;
|
||||
uint8_t lgtkhash[24];
|
||||
} ws_lfn_lgtk_t;
|
||||
|
||||
|
||||
typedef NS_LIST_HEAD(ws_nud_table_entry_t, link) ws_nud_table_list_t;
|
||||
|
||||
typedef struct ws_info_s {
|
||||
|
@ -87,6 +113,7 @@ typedef struct ws_info_s {
|
|||
trickle_t trickle_pan_advertisement_solicit;
|
||||
trickle_t trickle_pan_advertisement;
|
||||
trickle_params_t trickle_params_pan_discovery;
|
||||
uint8_t version; // Wi-SUN version information 1 = 1.0 2 = 1.x
|
||||
uint8_t rpl_state; // state from rpl_event_t
|
||||
uint8_t pas_requests; // Amount of PAN solicits sent
|
||||
uint8_t device_min_sens; // Device min sensitivity set by the application
|
||||
|
@ -114,6 +141,11 @@ typedef struct ws_info_s {
|
|||
ws_nud_table_entry_t nud_table_entrys[ACTIVE_NUD_PROCESS_MAX];
|
||||
ws_nud_table_list_t active_nud_process;
|
||||
ws_nud_table_list_t free_nud_entries;
|
||||
ws_test_proc_trg_t test_proc_trg;
|
||||
#ifdef HAVE_WS_VERSION_1_1
|
||||
ws_lfn_lgtk_t lfngtk;
|
||||
ws_phy_cap_info_t phy_cap_info;
|
||||
#endif
|
||||
struct ws_cfg_s *cfg; /**< Wi-SUN configuration */
|
||||
struct ws_pan_information_s pan_information;
|
||||
ws_hopping_schedule_t hopping_schdule;
|
||||
|
@ -125,21 +157,9 @@ typedef struct ws_info_s {
|
|||
|
||||
#ifdef HAVE_WS
|
||||
|
||||
int8_t ws_generate_channel_list(uint32_t *channel_mask, uint16_t number_of_channels, uint8_t regulatory_domain, uint8_t operating_class, uint8_t channel_plan_id);
|
||||
int8_t ws_common_generate_channel_list(uint32_t *channel_mask, uint16_t number_of_channels, uint8_t regulatory_domain, uint8_t operating_class, uint8_t channel_plan_id);
|
||||
|
||||
uint16_t ws_active_channel_count(uint32_t *channel_mask, uint16_t number_of_channels);
|
||||
|
||||
uint32_t ws_decode_channel_spacing(uint8_t channel_spacing);
|
||||
|
||||
uint32_t ws_get_datarate_using_operating_mode(uint8_t operating_mode);
|
||||
|
||||
uint32_t ws_get_datarate_using_phy_mode_id(uint8_t phy_mode_id);
|
||||
|
||||
uint8_t ws_get_ofdm_option_using_phy_mode_id(uint8_t phy_mode_id);
|
||||
|
||||
uint8_t ws_get_ofdm_mcs_using_phy_mode_id(uint8_t phy_mode_id);
|
||||
|
||||
phy_modulation_index_e ws_get_modulation_index_using_operating_mode(uint8_t operating_mode);
|
||||
uint16_t ws_common_active_channel_count(uint32_t *channel_mask, uint16_t number_of_channels);
|
||||
|
||||
int8_t ws_common_regulatory_domain_config(protocol_interface_info_entry_t *cur, ws_hopping_schedule_t *hopping_schdule);
|
||||
|
||||
|
@ -151,6 +171,8 @@ void ws_common_seconds_timer(protocol_interface_info_entry_t *cur, uint32_t seco
|
|||
|
||||
void ws_common_fast_timer(protocol_interface_info_entry_t *cur, uint16_t ticks);
|
||||
|
||||
void ws_common_create_ll_address(uint8_t *ll_address, const uint8_t *mac64);
|
||||
|
||||
void ws_common_neighbor_update(protocol_interface_info_entry_t *cur, const uint8_t *ll_address);
|
||||
|
||||
void ws_common_black_list_neighbour(const uint8_t *ll_address, uint8_t nd_status);
|
||||
|
@ -184,11 +206,35 @@ void ws_common_primary_parent_update(protocol_interface_info_entry_t *interface,
|
|||
void ws_common_secondary_parent_update(protocol_interface_info_entry_t *interface);
|
||||
|
||||
uint8_t ws_common_temporary_entry_size(uint8_t mac_table_size);
|
||||
|
||||
void ws_common_border_router_alive_update(protocol_interface_info_entry_t *interface);
|
||||
|
||||
int ws_common_init(int8_t interface_id, net_6lowpan_mode_e bootstrap_mode);
|
||||
|
||||
void ws_common_state_machine(protocol_interface_info_entry_t *cur);
|
||||
|
||||
fhss_ws_configuration_t ws_common_get_current_fhss_configuration(protocol_interface_info_entry_t *cur);
|
||||
|
||||
#define ws_info(cur) ((cur)->ws_info)
|
||||
#ifdef HAVE_WS_VERSION_1_1
|
||||
#define ws_version_1_0(cur) (((cur)->ws_info) && ((cur)->ws_info)->version == 1)
|
||||
#define ws_version_1_1(cur) (((cur)->ws_info) && ((cur)->ws_info)->version > 1)
|
||||
#define ws_lfn_version_learned(cur) ((cur)->ws_info->lfngtk.lfn_version_learned == true)
|
||||
#define ws_neighbour_cap_pointer(neighbour) (&neighbour->pcap_info)
|
||||
#else
|
||||
#define ws_version_1_1(cur) (false)
|
||||
#define ws_version_1_0(cur) ((cur)->ws_info)
|
||||
#define ws_lfn_version_learned(cur) (false)
|
||||
#define ws_neighbour_cap_pointer(neighbour) NULL
|
||||
#endif
|
||||
#define ws_test_proc_auto_trg(cur) ((cur)->ws_info->test_proc_trg.auto_trg_enabled == true)
|
||||
#else
|
||||
#define ws_info(cur) ((ws_info_t *) NULL)
|
||||
#define ws_version_1_1(cur) (false)
|
||||
#define ws_version_1_0(cur) (false)
|
||||
#define ws_lfn_version_learned(cur) (false)
|
||||
#define ws_neighbour_cap_pointer(neighbour) NULL
|
||||
#define ws_test_proc_auto_trg(cur) (false)
|
||||
#define ws_common_seconds_timer(cur, seconds)
|
||||
#define ws_common_neighbor_update(cur, ll_address) ((void) 0)
|
||||
#define ws_common_black_list_neighbour(ll_address, nd_status) ((void) 0)
|
||||
|
@ -207,6 +253,8 @@ void ws_common_border_router_alive_update(protocol_interface_info_entry_t *inter
|
|||
#define ws_common_primary_parent_update(interface, neighbor)
|
||||
#define ws_common_secondary_parent_update(interface)
|
||||
#define ws_common_border_router_alive_update(interface) ((void) 0)
|
||||
#define ws_common_init(interface_id, bootstrap_mode) 0
|
||||
#define ws_common_state_machine(cur)
|
||||
|
||||
|
||||
#endif //HAVE_WS
|
||||
|
|
|
@ -28,19 +28,40 @@
|
|||
#define WH_IE_MHDS_TYPE 5 /**< MHDS information for mesh routing */
|
||||
#define WH_IE_VH_TYPE 6 /**< Vendor header information */
|
||||
#define WH_IE_EA_TYPE 9 /**< Eapol Auhtenticator EUI-64 header information */
|
||||
/* Wi-SUN FAN dfinition 1.1 */
|
||||
#define WH_IE_LUTT_TYPE 10 /**< LFN Unicast Timing and Frame Type information */
|
||||
#define WH_IE_LBT_TYPE 11 /**< LFN Broadcast Timing information */
|
||||
#define WH_IE_NR_TYPE 12 /**< Node Role IE information */
|
||||
#define WH_IE_LUS_TYPE 13 /**< LFN Unicast Schedule information */
|
||||
#define WH_IE_FLUS_TYPE 14 /**< FFN for LFN unicast Schedule information */
|
||||
#define WH_IE_LBS_TYPE 15 /**< LFN Broadcast Schedule information */
|
||||
#define WH_IE_LND_TYPE 16 /**< LFN Network Discovery information */
|
||||
#define WH_IE_LTO_TYPE 17 /**< LFN Timing information */
|
||||
#define WH_IE_PANID_TYPE 18 /**< PAN Identifier information */
|
||||
|
||||
|
||||
#define WS_WP_NESTED_IE 4 /**< WS nested Payload IE element'selement could include mltiple sub payload IE */
|
||||
|
||||
#define WS_WP_SUB_IE_ELEMENT_HEADER_LENGTH 2
|
||||
|
||||
/* Payload IE sub elements in side WS_WP_NESTED_IE */
|
||||
#define WP_PAYLOAD_IE_US_TYPE 1 /**< Unicast Schedule information */
|
||||
#define WP_PAYLOAD_IE_BS_TYPE 2 /**< Broadcast Schedule information */
|
||||
#define WP_PAYLOAD_IE_VP_TYPE 3 /**< Vendor Payload information */
|
||||
/* Long form subID's */
|
||||
#define WP_PAYLOAD_IE_US_TYPE 1 /**< Unicast Schedule information */
|
||||
#define WP_PAYLOAD_IE_BS_TYPE 2 /**< Broadcast Schedule information */
|
||||
#define WP_PAYLOAD_IE_VP_TYPE 3 /**< Vendor Payload information */
|
||||
/* Wi-SUN FAN definition 1.1 */
|
||||
#define WP_PAYLOAD_IE_LFN_CHANNEL_PLAN_TYPE 4 /**< LFN Channel Plan information*/
|
||||
|
||||
/* Short form subID's */
|
||||
#define WP_PAYLOAD_IE_PAN_TYPE 4 /**< PAN Information */
|
||||
#define WP_PAYLOAD_IE_NETNAME_TYPE 5 /**< Network Name information */
|
||||
#define WP_PAYLOAD_IE_PAN_VER_TYPE 6 /**< Pan configuration version */
|
||||
#define WP_PAYLOAD_IE_GTKHASH_TYPE 7 /**< GTK Hash information */
|
||||
/* Wi-SUN FAN definition 1.1 */
|
||||
#define WP_PAYLOAD_IE_PCAP_TYPE 8 /**< PHY Capability information */
|
||||
#define WP_PAYLOAD_IE_LFNVER_TYPE 9 /**< LFN Version information */
|
||||
#define WP_PAYLOAD_IE_LGTKHASH_TYPE 10 /**< LFN GTK Hash Information */
|
||||
|
||||
|
||||
/* WS frame types to WH_IE_UTT_TYPE */
|
||||
#define WS_FT_PAN_ADVERT 0 /**< PAN Advert */
|
||||
|
@ -50,14 +71,25 @@
|
|||
#define WS_FT_DATA 4 /**< data type inside MPX */
|
||||
#define WS_FT_ACK 5 /**< Enhanced ACK */
|
||||
#define WS_FT_EAPOL 6 /**< EAPOL message inside MPX */
|
||||
/* Wi-SUN FAN 1.1 */
|
||||
#define WS_FT_LPA 9 /**< LFN PAN Advert */
|
||||
#define WS_FT_LPAS 10 /**< LFN PAN Advert Solicit */
|
||||
#define WS_FT_LPC 11 /**< LFN PAN Config */
|
||||
#define WS_FT_LPCS 12 /**< LFN PAN Config Solicit */
|
||||
|
||||
|
||||
/* WS exluded channel Control */
|
||||
#define WS_EXC_CHAN_CTRL_NONE 0 /**< No excluded channels */
|
||||
#define WS_EXC_CHAN_CTRL_RANGE 1 /**< Excluded channels are in 1 or multiple channel range */
|
||||
#define WS_EXC_CHAN_CTRL_BITMASK 2 /**< Excluded channels are marked to bitmask which length based on configured channels */
|
||||
#define WS_EXC_CHAN_CTRL_BITMASK 2 /**< Excluded channels are marked to bitmask which length based on configured channels */
|
||||
|
||||
#define WS_EXCLUDED_MAX_RANGE_TO_SEND 3
|
||||
|
||||
|
||||
#define WS_NR_ROLE_BR 0
|
||||
#define WS_NR_ROLE_ROUTER 1
|
||||
#define WS_NR_ROLE_LFN 2
|
||||
|
||||
/**
|
||||
* @brief ws_pan_information_t PAN information
|
||||
*/
|
||||
|
@ -68,6 +100,7 @@ typedef struct ws_pan_information_s {
|
|||
bool use_parent_bs: 1; /**< 1 for force to follow parent broadcast schedule. 0 node may define own schedule. */
|
||||
bool rpl_routing_method: 1; /**< 1 when RPL routing is selected and 0 when L2 routing. */
|
||||
bool pan_version_set: 1; /**< 1 PAN version is set. */
|
||||
bool lfn_window_style: 1; /**< 1 FFN management trasmission. */
|
||||
unsigned version: 3; /**< Pan version support. */
|
||||
} ws_pan_information_t;
|
||||
|
||||
|
@ -125,6 +158,101 @@ typedef struct ws_utt_ie {
|
|||
uint_fast24_t ufsi;
|
||||
} ws_utt_ie_t;
|
||||
|
||||
/**
|
||||
* @brief ws_utt_ie_t WS LUTT-IE
|
||||
*/
|
||||
typedef struct ws_lutt_ie {
|
||||
uint8_t message_type;
|
||||
uint16_t slot_number;
|
||||
uint_fast24_t interval_offset;
|
||||
} ws_lutt_ie_t;
|
||||
|
||||
/**
|
||||
* @brief ws_lbt_ie_t WS LBT-IE
|
||||
*/
|
||||
typedef struct ws_lbt_ie {
|
||||
uint16_t slot_number;
|
||||
uint_fast24_t interval_offset;
|
||||
} ws_lbt_ie_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief ws_nr_ie_t WS NR-IE
|
||||
*/
|
||||
typedef struct ws_nr_ie {
|
||||
unsigned node_role: 3;
|
||||
uint8_t clock_drift;
|
||||
uint8_t timing_accurancy;
|
||||
uint_fast24_t listen_interval_min;
|
||||
uint_fast24_t listen_interval_max;
|
||||
} ws_nr_ie_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief ws_lus_ie_t WS LUS-IE
|
||||
*/
|
||||
typedef struct ws_lus_ie {
|
||||
uint8_t channel_plan_tag;
|
||||
uint_fast24_t listen_interval;
|
||||
} ws_lus_ie_t;
|
||||
|
||||
/**
|
||||
* @brief ws_lus_ie_t WS FLUS-IE
|
||||
*/
|
||||
typedef struct ws_flus_ie {
|
||||
uint8_t channel_plan_tag;
|
||||
uint8_t dwell_interval;
|
||||
} ws_flus_ie_t;
|
||||
|
||||
/**
|
||||
* @brief ws_lnd_ie_t WS LND-IE
|
||||
*/
|
||||
typedef struct ws_lnd_ie {
|
||||
uint8_t response_threshold;
|
||||
uint8_t discovery_slot_time;
|
||||
uint8_t discovery_slots;
|
||||
uint16_t discovery_first_slot;
|
||||
uint_fast24_t response_delay;
|
||||
} ws_lnd_ie_t;
|
||||
|
||||
/**
|
||||
* @brief ws_lto_ie_t WS LTO-IE
|
||||
*/
|
||||
typedef struct ws_lto_ie {
|
||||
uint_fast24_t offset;
|
||||
uint_fast24_t adjusted_listening_interval;
|
||||
} ws_lto_ie_t;
|
||||
|
||||
/**
|
||||
* @brief ws_lbs_ie_t WS LBS-IE
|
||||
*/
|
||||
typedef struct ws_lbs_ie {
|
||||
uint8_t channel_plan_tag;
|
||||
uint16_t broadcast_secheduler_id;
|
||||
uint_fast24_t broadcast_interval;
|
||||
} ws_lbs_ie_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief ws_panid_ie_t WS PANID-IE
|
||||
*/
|
||||
typedef struct ws_panid_ie {
|
||||
uint16_t panid;
|
||||
} ws_panid_ie_t;
|
||||
|
||||
/**
|
||||
* @brief ws_pcap_ie_t WS PCAB-IE
|
||||
*/
|
||||
typedef struct ws_pcap_ie {
|
||||
unsigned phy_type: 3;
|
||||
uint16_t operating_mode;
|
||||
} ws_pcap_ie_t;
|
||||
|
||||
typedef struct ws_phy_cap_info {
|
||||
unsigned length_of_list: 3;
|
||||
ws_pcap_ie_t pcap[7];
|
||||
} ws_phy_cap_info_t;
|
||||
|
||||
/**
|
||||
* @brief ws_bt_ie_t WS BT-IE read
|
||||
*/
|
||||
|
@ -141,6 +269,26 @@ typedef struct ws_fc_ie {
|
|||
uint8_t rx_flow_ctrl;
|
||||
} ws_fc_ie_t;
|
||||
|
||||
/**
|
||||
* @brief ws_lfnver_ie_t WS LFNVER-IE element
|
||||
*/
|
||||
typedef struct ws_lfnver_ie {
|
||||
uint16_t lfn_version;
|
||||
} ws_lfnver_ie_t;
|
||||
|
||||
/**
|
||||
* @brief ws_lgtkhash_ie_t WS LGTKHASH-IE element
|
||||
*/
|
||||
typedef struct ws_lgtkhash_ie {
|
||||
bool lgtk0: 1; /**< 1= LGTK0 in line 0 = elided */
|
||||
bool lgtk1: 1; /**< 1= LGTK1 in line 0 = elided */
|
||||
bool lgtk2: 1; /**< 1= LGTK2 in line 0 = elided */
|
||||
unsigned active_lgtk_index: 2; /**< Indicate Active LGTK index 0-2 */
|
||||
uint8_t *lgtk0_hash; /**< LGTK0 64-bit Hash if lgtk0=1*/
|
||||
uint8_t *lgtk1_hash; /**< LGTK1 64-bit Hash if lgtk1=1*/
|
||||
uint8_t *lgtk2_hash; /**< LGTK2 64-bit Hash if lgtk2=1*/
|
||||
} ws_lgtkhash_ie_t;
|
||||
|
||||
/**
|
||||
* @brief ws_channel_plan_zero_t WS channel plan 0 define domain and class
|
||||
*/
|
||||
|
@ -158,6 +306,14 @@ typedef struct ws_channel_plan_one {
|
|||
uint16_t number_of_channel;
|
||||
} ws_channel_plan_one_t;
|
||||
|
||||
/**
|
||||
* @brief ws_channel_plan_two_t WS channel plan 2 define regulator domain and chanel plan 1
|
||||
*/
|
||||
typedef struct ws_channel_plan_two {
|
||||
uint8_t regulator_domain;
|
||||
uint8_t channel_plan_id;
|
||||
} ws_channel_plan_two_t;
|
||||
|
||||
/**
|
||||
* @brief ws_channel_function_zero_t WS function 0 fixed channel
|
||||
*/
|
||||
|
@ -189,6 +345,43 @@ typedef struct ws_excluded_channel_mask {
|
|||
uint8_t mask_len_inline;
|
||||
} ws_excluded_channel_mask_t;
|
||||
|
||||
|
||||
typedef struct ws_excluded_channel_range_out {
|
||||
unsigned excluded_range_length: 3;
|
||||
ws_excluded_channel_range_data_t *exluded_range;
|
||||
} ws_excluded_channel_range_out_t;
|
||||
|
||||
|
||||
typedef struct ws_excluded_channel_mask_out {
|
||||
uint16_t excluded_channel_count;
|
||||
uint8_t channel_mask_bytes_inline;
|
||||
uint32_t *channel_mask;
|
||||
} ws_excluded_channel_mask_out_t;
|
||||
|
||||
/**
|
||||
* @brief ws_generic_channel_info_t Generic Channel Info
|
||||
*/
|
||||
typedef struct ws_generic_channel_info {
|
||||
unsigned channel_plan: 3;
|
||||
unsigned channel_function: 3;
|
||||
unsigned excluded_channel_ctrl: 2;
|
||||
union {
|
||||
ws_channel_plan_zero_t zero;
|
||||
ws_channel_plan_one_t one;
|
||||
ws_channel_plan_two_t two;
|
||||
} plan;
|
||||
union {
|
||||
ws_channel_function_zero_t zero;
|
||||
ws_channel_function_three_t three;
|
||||
} function;
|
||||
union {
|
||||
ws_excluded_channel_range_out_t range;
|
||||
ws_excluded_channel_mask_out_t mask;
|
||||
ws_excluded_channel_range_t range_in;
|
||||
ws_excluded_channel_mask_t mask_in;
|
||||
} excluded_channels;
|
||||
} ws_generic_channel_info_t;
|
||||
|
||||
/**
|
||||
* @brief ws_us_ie_t WS US-IE read
|
||||
*/
|
||||
|
@ -202,6 +395,7 @@ typedef struct ws_us_ie {
|
|||
union {
|
||||
ws_channel_plan_zero_t zero;
|
||||
ws_channel_plan_one_t one;
|
||||
ws_channel_plan_two_t two;
|
||||
} plan;
|
||||
union {
|
||||
ws_channel_function_zero_t zero;
|
||||
|
@ -228,6 +422,7 @@ typedef struct ws_bs_ie {
|
|||
union {
|
||||
ws_channel_plan_zero_t zero;
|
||||
ws_channel_plan_one_t one;
|
||||
ws_channel_plan_two_t two;
|
||||
} plan;
|
||||
union {
|
||||
ws_channel_function_zero_t zero;
|
||||
|
@ -247,6 +442,7 @@ typedef struct ws_bs_ie {
|
|||
#define WS_MPX_MAX_MTU 1576
|
||||
|
||||
#define WS_FAN_VERSION_1_0 1
|
||||
#define WS_FAN_VERSION_1_1 2
|
||||
|
||||
#define WS_NEIGHBOR_LINK_TIMEOUT 2200
|
||||
|
||||
|
@ -381,9 +577,9 @@ typedef struct ws_bs_ie {
|
|||
/* Default FHSS timing information
|
||||
*
|
||||
*/
|
||||
#define WS_FHSS_UC_DWELL_INTERVAL 255;
|
||||
#define WS_FHSS_BC_INTERVAL 1020;
|
||||
#define WS_FHSS_BC_DWELL_INTERVAL 255;
|
||||
#define WS_FHSS_UC_DWELL_INTERVAL 255
|
||||
#define WS_FHSS_BC_INTERVAL 1020
|
||||
#define WS_FHSS_BC_DWELL_INTERVAL 255
|
||||
|
||||
/*
|
||||
* EAPOL relay and PAE authenticator socket settings
|
||||
|
|
|
@ -97,7 +97,7 @@
|
|||
|
||||
#define PAN_VERSION_SMALL_NETWORK_TIMEOUT 30*60
|
||||
|
||||
#define PAN_VERSION_MEDIUM_NETWORK_TIMEOUT 60*60
|
||||
#define PAN_VERSION_MEDIUM_NETWORK_TIMEOUT 30*60
|
||||
|
||||
#define PAN_VERSION_LARGE_NETWORK_TIMEOUT 90*60
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
|
||||
#include "ws_management_api.h"
|
||||
#include "ns_time_api.h"
|
||||
#include "net_ws_test_ext.h"
|
||||
|
||||
#ifndef HAVE_WS
|
||||
int ws_management_node_init(
|
||||
|
@ -362,6 +363,12 @@ int ws_management_timing_parameters_validate(
|
|||
}
|
||||
|
||||
/* ### test api ### */
|
||||
int ws_test_version_set(int8_t interface_id, uint8_t version)
|
||||
{
|
||||
(void) interface_id;
|
||||
(void) version;
|
||||
return -1;
|
||||
}
|
||||
int ws_test_pan_size_set(int8_t interface_id, uint16_t pan_size)
|
||||
{
|
||||
(void) interface_id;
|
||||
|
@ -488,5 +495,22 @@ int8_t ws_test_drop_edfe_data_frames(int8_t interface_id, uint8_t number_of_dro
|
|||
return -1;
|
||||
}
|
||||
|
||||
int ws_test_procedure_trigger(int8_t interface_id, ws_test_proc_t procedure, void *parameters)
|
||||
{
|
||||
(void) interface_id;
|
||||
(void) procedure;
|
||||
(void) parameters;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ws_management_phy_capability_set(
|
||||
int8_t interface_id,
|
||||
ws_management_pcap_info_t *pcap_list)
|
||||
{
|
||||
(void)interface_id;
|
||||
(void)pcap_list;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
#endif // no HAVE_WS
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -24,6 +24,8 @@ struct ws_bt_ie;
|
|||
struct ws_us_ie;
|
||||
struct ws_hopping_schedule_s;
|
||||
struct ws_fc_ie;
|
||||
struct ws_phy_cap_info;
|
||||
struct ws_pcap_ie;
|
||||
|
||||
/**
|
||||
* @brief ws_wp_network_name_t WS nested payload network name
|
||||
|
@ -33,6 +35,16 @@ typedef struct ws_wp_network_name {
|
|||
uint8_t *network_name;
|
||||
} ws_wp_network_name_t;
|
||||
|
||||
#define ws_wp_nested_lfn_version_length() 2
|
||||
#define ws_wh_lutt_length() 6
|
||||
#define ws_wh_lus_length() 4
|
||||
#define ws_wh_flus_length() 2
|
||||
#define ws_wh_lbt_length() 5
|
||||
#define ws_wh_lbs_length() 6
|
||||
#define ws_wh_lnd_length() 8
|
||||
#define ws_wh_lto_length() 6
|
||||
#define ws_wh_panid_length() 2
|
||||
|
||||
/* WS_WH HEADER IE */
|
||||
uint8_t *ws_wh_utt_write(uint8_t *ptr, uint8_t message_type);
|
||||
uint8_t *ws_wh_bt_write(uint8_t *ptr);
|
||||
|
@ -40,12 +52,34 @@ uint8_t *ws_wh_fc_write(uint8_t *ptr, struct ws_fc_ie *fc_ie);
|
|||
uint8_t *ws_wh_rsl_write(uint8_t *ptr, uint8_t rsl);
|
||||
uint8_t *ws_wh_vh_write(uint8_t *ptr, uint8_t *vendor_header, uint8_t vendor_header_length);
|
||||
uint8_t *ws_wh_ea_write(uint8_t *ptr, uint8_t *eui64);
|
||||
/* Wi-SUN FAN 1.1 */
|
||||
uint8_t *ws_wh_lutt_write(uint8_t *ptr, uint8_t message_type);
|
||||
uint8_t *ws_wh_lus_write(uint8_t *ptr, struct ws_lus_ie *lus_ptr);
|
||||
uint8_t *ws_wh_flus_write(uint8_t *ptr, struct ws_flus_ie *flus_ptr);
|
||||
uint8_t *ws_wh_lbt_write(uint8_t *ptr);
|
||||
uint8_t *ws_wh_lbs_write(uint8_t *ptr, struct ws_lbs_ie *lbs_ptr);
|
||||
uint8_t *ws_wh_nr_write(uint8_t *ptr, struct ws_nr_ie *nr_ptr);
|
||||
uint16_t ws_wh_nr_length(struct ws_nr_ie *nr_ptr);
|
||||
uint8_t *ws_wh_lnd_write(uint8_t *ptr, struct ws_lnd_ie *lnd_ptr);
|
||||
uint8_t *ws_wh_lto_write(uint8_t *ptr, struct ws_lto_ie *lto_ptr);
|
||||
uint8_t *ws_wh_panid_write(uint8_t *ptr, uint16_t pana_id);
|
||||
|
||||
|
||||
bool ws_wh_utt_read(uint8_t *data, uint16_t length, struct ws_utt_ie *utt_ie);
|
||||
bool ws_wh_bt_read(uint8_t *data, uint16_t length, struct ws_bt_ie *bt_ie);
|
||||
bool ws_wh_fc_read(uint8_t *data, uint16_t length, struct ws_fc_ie *fc_ie);
|
||||
bool ws_wh_rsl_read(uint8_t *data, uint16_t length, int8_t *rsl);
|
||||
bool ws_wh_ea_read(uint8_t *data, uint16_t length, uint8_t *eui64);
|
||||
/*Wi-SUN FAN 1.1 */
|
||||
bool ws_wh_lutt_read(uint8_t *data, uint16_t length, struct ws_lutt_ie *ws_lutt);
|
||||
bool ws_wh_lus_read(uint8_t *data, uint16_t length, struct ws_lus_ie *lus_ptr);
|
||||
bool ws_wh_flus_read(uint8_t *data, uint16_t length, struct ws_flus_ie *flus_ptr);
|
||||
bool ws_wh_lbt_read(uint8_t *data, uint16_t length, struct ws_lbt_ie *ws_lbt);
|
||||
bool ws_wh_lbs_read(uint8_t *data, uint16_t length, struct ws_lbs_ie *lbs_ptr);
|
||||
bool ws_wh_nr_read(uint8_t *data, uint16_t length, struct ws_nr_ie *nr_ptr);
|
||||
bool ws_wh_lnd_read(uint8_t *data, uint16_t length, struct ws_lnd_ie *lnd_ptr);
|
||||
bool ws_wh_lto_read(uint8_t *data, uint16_t length, struct ws_lto_ie *lto_ptr);
|
||||
bool ws_wh_panid_read(uint8_t *data, uint16_t length, struct ws_panid_ie *ws_panid);
|
||||
|
||||
/* WS_WP_NESTED PAYLOD IE */
|
||||
uint8_t *ws_wp_base_write(uint8_t *ptr, uint16_t length);
|
||||
|
@ -56,6 +90,22 @@ uint8_t *ws_wp_nested_netname_write(uint8_t *ptr, uint8_t *network_name, uint8_t
|
|||
uint8_t *ws_wp_nested_pan_ver_write(uint8_t *ptr, struct ws_pan_information_s *pan_congiguration);
|
||||
uint8_t *ws_wp_nested_gtkhash_write(uint8_t *ptr, uint8_t *gtkhash, uint8_t gtkhash_length);
|
||||
uint16_t ws_wp_nested_hopping_schedule_length(struct ws_hopping_schedule_s *hopping_schedule, bool unicast_schedule);
|
||||
/* Wi-SUN FAN 1.1 */
|
||||
/* WS PCAP */
|
||||
uint8_t *ws_wp_nested_pcap_write(uint8_t *ptr, struct ws_phy_cap_info *pcap_list);
|
||||
uint16_t ws_wp_nested_pcap_length(uint8_t list_length);
|
||||
struct ws_pcap_ie ws_ie_lib_generate_phy_cap_from_phy_mode_id(uint8_t phy_mode_id);
|
||||
uint8_t ws_ie_lib_phy_mode_id_get_from_phy_cap(struct ws_pcap_ie *phy_cap);
|
||||
void ws_ie_lib_phy_cap_list_update(struct ws_phy_cap_info *phy_pap, struct ws_pcap_ie *pcap);
|
||||
/* WS LFN version */
|
||||
uint8_t *ws_wp_nested_lfn_version_write(uint8_t *ptr, struct ws_lfnver_ie *ws_lfnver);
|
||||
/* WS LFN GTK HAS */
|
||||
uint8_t *ws_wp_nested_lgtk_hash_write(uint8_t *ptr, struct ws_lgtkhash_ie *ws_lgtkhash);
|
||||
uint16_t ws_wp_lgtk_hash_length(struct ws_lgtkhash_ie *ws_lgtkhash);
|
||||
/* WS LFN Channel plan */
|
||||
uint8_t *ws_wp_nested_lfn_channel_plan_write(uint8_t *ptr, struct ws_generic_channel_info *ws_lcp, uint8_t plan_tag_id);
|
||||
uint16_t ws_wp_nested_lfn_channel_plan_length(struct ws_generic_channel_info *ws_lcp);
|
||||
|
||||
|
||||
bool ws_wp_nested_us_read(uint8_t *data, uint16_t length, struct ws_us_ie *us_ie);
|
||||
bool ws_wp_nested_bs_read(uint8_t *data, uint16_t length, struct ws_bs_ie *bs_ie);
|
||||
|
@ -63,6 +113,11 @@ bool ws_wp_nested_pan_read(uint8_t *data, uint16_t length, struct ws_pan_informa
|
|||
bool ws_wp_nested_pan_version_read(uint8_t *data, uint16_t length, uint16_t *pan_version);
|
||||
bool ws_wp_nested_network_name_read(uint8_t *data, uint16_t length, ws_wp_network_name_t *network_name);
|
||||
uint8_t *ws_wp_nested_gtkhash_read(uint8_t *data, uint16_t length);
|
||||
/* Wi-SUN FAN 1.1 */
|
||||
bool ws_wp_nested_pcap_read(uint8_t *data, uint16_t length, struct ws_phy_cap_info *ws_pcap_list);
|
||||
bool ws_wp_nested_lfn_version_read(uint8_t *data, uint16_t length, struct ws_lfnver_ie *ws_lfnver);
|
||||
bool ws_wp_nested_lgtk_hash_read(uint8_t *data, uint16_t length, struct ws_lgtkhash_ie *ws_lgtkhash);
|
||||
bool ws_wp_nested_lfn_channel_plan_read(uint8_t *data, uint16_t length, struct ws_generic_channel_info *ws_lcp, uint8_t plan_tag_id);
|
||||
|
||||
|
||||
#endif /* WS_IE_LIB_H_ */
|
||||
|
|
|
@ -49,13 +49,15 @@ typedef struct wh_ie_sub_list_s {
|
|||
* @brief wp_nested_ie_sub_list_t ws asynch Nested Payload sub IE element request list
|
||||
*/
|
||||
typedef struct wp_nested_ie_sub_list_s {
|
||||
bool us_ie: 1; /**< Unicast Schedule information */
|
||||
bool bs_ie: 1; /**< Broadcast Schedule information */
|
||||
bool vp_ie: 1; /**< Vendor Payload information */
|
||||
bool pan_ie: 1; /**< PAN Information */
|
||||
bool net_name_ie: 1; /**< Network Name information */
|
||||
bool pan_version_ie: 1; /**< Pan configuration version */
|
||||
bool gtkhash_ie: 1; /**< GTK Hash information */
|
||||
bool us_ie: 1; /**< Unicast Schedule information */
|
||||
bool bs_ie: 1; /**< Broadcast Schedule information */
|
||||
bool vp_ie: 1; /**< Vendor Payload information */
|
||||
bool pan_ie: 1; /**< PAN Information */
|
||||
bool net_name_ie: 1; /**< Network Name information */
|
||||
bool pan_version_ie: 1; /**< Pan configuration version */
|
||||
bool gtkhash_ie: 1; /**< GTK Hash information */
|
||||
bool lfn_gtk_version_ie: 1; /**< LFN Version & GTK Hash */
|
||||
bool phy_cap_ie: 1; /** < Phy Cap information for MDR */
|
||||
} wp_nested_ie_sub_list_t;
|
||||
|
||||
/**
|
||||
|
@ -124,7 +126,7 @@ typedef void ws_asynch_confirm(struct protocol_interface_info_entry *interface,
|
|||
* @return true when neighbor info is available
|
||||
* @return false when no neighbor info
|
||||
*/
|
||||
typedef bool ws_neighbor_info_request(struct protocol_interface_info_entry *interface, const uint8_t *mac_64, llc_neighbour_req_t *neighbor_buffer, bool request_new);
|
||||
typedef bool ws_neighbor_info_request(struct protocol_interface_info_entry *interface, const uint8_t *mac_64, struct llc_neighbour_req *neighbor_buffer, bool request_new);
|
||||
|
||||
/**
|
||||
* @brief ws_llc_create ws LLC module create
|
||||
|
|
|
@ -34,6 +34,8 @@
|
|||
#include "6LoWPAN/ws/ws_bootstrap.h"
|
||||
#include "6LoWPAN/ws/ws_ie_lib.h"
|
||||
#include "6LoWPAN/ws/ws_llc.h"
|
||||
#include "6LoWPAN/ws/ws_neighbor_class.h"
|
||||
#include "6LoWPAN/ws/ws_ie_lib.h"
|
||||
#include "6LoWPAN/ws/ws_mpx_header.h"
|
||||
#include "6LoWPAN/ws/ws_pae_controller.h"
|
||||
#include "6LoWPAN/ws/ws_cfg_settings.h"
|
||||
|
@ -42,6 +44,7 @@
|
|||
#include "Service_Libs/etx/etx.h"
|
||||
#include "fhss_ws_extension.h"
|
||||
#include "Service_Libs/random_early_detection/random_early_detection_api.h"
|
||||
#include "ws_management_api.h"
|
||||
|
||||
#ifdef HAVE_WS
|
||||
|
||||
|
@ -158,7 +161,7 @@ typedef struct {
|
|||
|
||||
static NS_LIST_DEFINE(llc_data_base_list, llc_data_base_t, link);
|
||||
|
||||
static uint16_t ws_wp_nested_message_length(wp_nested_ie_sub_list_t requested_list, llc_ie_params_t *params);
|
||||
static uint16_t ws_wp_nested_message_length(wp_nested_ie_sub_list_t requested_list, llc_data_base_t *llc_base);
|
||||
static uint16_t ws_wh_headers_length(wh_ie_sub_list_t requested_list, llc_ie_params_t *params);
|
||||
|
||||
/** LLC message local functions */
|
||||
|
@ -378,9 +381,10 @@ static uint16_t ws_wh_headers_length(wh_ie_sub_list_t requested_list, llc_ie_par
|
|||
return length;
|
||||
}
|
||||
|
||||
static uint16_t ws_wp_nested_message_length(wp_nested_ie_sub_list_t requested_list, llc_ie_params_t *params)
|
||||
static uint16_t ws_wp_nested_message_length(wp_nested_ie_sub_list_t requested_list, llc_data_base_t *llc_base)
|
||||
{
|
||||
uint16_t length = 0;
|
||||
llc_ie_params_t *params = &llc_base->ie_params;
|
||||
if (requested_list.gtkhash_ie) {
|
||||
//Static 32 bytes allways
|
||||
length += WS_WP_SUB_IE_ELEMENT_HEADER_LENGTH + params->gtkhash_length;
|
||||
|
@ -411,6 +415,23 @@ static uint16_t ws_wp_nested_message_length(wp_nested_ie_sub_list_t requested_li
|
|||
length += 2;
|
||||
}
|
||||
}
|
||||
#ifdef HAVE_WS_VERSION_1_1
|
||||
if (ws_version_1_1(llc_base->interface_ptr)) {
|
||||
if (requested_list.lfn_gtk_version_ie) {
|
||||
|
||||
length += WS_WP_SUB_IE_ELEMENT_HEADER_LENGTH + ws_wp_nested_lfn_version_length();
|
||||
ws_lgtkhash_ie_t ws_lgtkhash;
|
||||
ws_lgtkhash.lgtk0 = llc_base->interface_ptr->ws_info->lfngtk.active_hash_1;
|
||||
ws_lgtkhash.lgtk1 = llc_base->interface_ptr->ws_info->lfngtk.active_hash_2;
|
||||
ws_lgtkhash.lgtk2 = llc_base->interface_ptr->ws_info->lfngtk.active_hash_3;
|
||||
length += WS_WP_SUB_IE_ELEMENT_HEADER_LENGTH + ws_wp_lgtk_hash_length(&ws_lgtkhash);
|
||||
}
|
||||
|
||||
if (requested_list.phy_cap_ie) {
|
||||
length += WS_WP_SUB_IE_ELEMENT_HEADER_LENGTH + ws_wp_nested_pcap_length(llc_base->interface_ptr->ws_info->phy_cap_info.length_of_list);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (requested_list.bs_ie) {
|
||||
///Dynamic length
|
||||
|
@ -774,6 +795,11 @@ static void ws_llc_data_indication_cb(const mac_api_t *api, const mcps_data_ind_
|
|||
//SET trusted state
|
||||
mac_neighbor_table_trusted_neighbor(mac_neighbor_info(interface), neighbor_info.neighbor, true);
|
||||
}
|
||||
//
|
||||
//Phy CAP info read and store
|
||||
if (ws_version_1_1(interface)) {
|
||||
ws_neighbor_class_pcap_ie_store(neighbor_info.ws_neighbor, ie_ext);
|
||||
}
|
||||
}
|
||||
|
||||
mcps_data_ind_t data_ind = *data;
|
||||
|
@ -1010,6 +1036,26 @@ static void ws_llc_lowpan_mpx_header_set(llc_message_t *message, uint16_t user_i
|
|||
message->ie_vector_list[1].iovLen = ptr - (uint8_t *)message->ie_vector_list[1].ieBase;
|
||||
}
|
||||
|
||||
#ifdef HAVE_WS_VERSION_1_1
|
||||
uint8_t ws_llc_mdr_phy_mode_get(llc_data_base_t *base, const struct mcps_data_req_s *data)
|
||||
{
|
||||
|
||||
if (!ws_version_1_1(base->interface_ptr) || !data->TxAckReq || data->msduLength < 500) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
llc_neighbour_req_t neighbor_info;
|
||||
|
||||
if (!base->ws_neighbor_info_request_cb(base->interface_ptr, data->DstAddr, &neighbor_info, false)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return neighbor_info.ws_neighbor->phy_mode_id;
|
||||
}
|
||||
#else
|
||||
#define ws_llc_mdr_phy_mode_get(base, data) 0
|
||||
#endif
|
||||
|
||||
static void ws_llc_lowpan_mpx_data_request(llc_data_base_t *base, mpx_user_t *user_cb, const struct mcps_data_req_s *data, mac_data_priority_t priority)
|
||||
{
|
||||
wh_ie_sub_list_t ie_header_mask;
|
||||
|
@ -1038,7 +1084,7 @@ static void ws_llc_lowpan_mpx_data_request(llc_data_base_t *base, mpx_user_t *us
|
|||
nested_wp_id.us_ie = true;
|
||||
|
||||
uint16_t ie_header_length = ws_wh_headers_length(ie_header_mask, &base->ie_params);
|
||||
uint16_t nested_ie_length = ws_wp_nested_message_length(nested_wp_id, &base->ie_params);
|
||||
uint16_t nested_ie_length = ws_wp_nested_message_length(nested_wp_id, base);
|
||||
|
||||
uint16_t over_head_size = ie_header_length;
|
||||
if (nested_ie_length) {
|
||||
|
@ -1066,6 +1112,7 @@ static void ws_llc_lowpan_mpx_data_request(llc_data_base_t *base, mpx_user_t *us
|
|||
ns_list_add_to_end(&base->llc_message_list, message);
|
||||
|
||||
mcps_data_req_t data_req;
|
||||
uint8_t phy_mode_id = ws_llc_mdr_phy_mode_get(base, data);
|
||||
message->mpx_user_handle = data->msduHandle;
|
||||
message->ack_requested = data->TxAckReq;
|
||||
if (data->TxAckReq) {
|
||||
|
@ -1140,7 +1187,7 @@ static void ws_llc_lowpan_mpx_data_request(llc_data_base_t *base, mpx_user_t *us
|
|||
message->ie_ext.payloadIovLength = 0; //Set Back 2 at response handler
|
||||
}
|
||||
|
||||
base->interface_ptr->mac_api->mcps_data_req_ext(base->interface_ptr->mac_api, &data_req, &message->ie_ext, NULL, message->priority);
|
||||
base->interface_ptr->mac_api->mcps_data_req_ext(base->interface_ptr->mac_api, &data_req, &message->ie_ext, NULL, message->priority, phy_mode_id);
|
||||
}
|
||||
|
||||
static void ws_llc_eapol_data_req_init(mcps_data_req_t *data_req, llc_message_t *message)
|
||||
|
@ -1187,7 +1234,7 @@ static void ws_llc_mpx_eapol_send(llc_data_base_t *base, llc_message_t *message)
|
|||
ns_list_add_to_end(&base->llc_message_list, message);
|
||||
ws_llc_eapol_data_req_init(&data_req, message);
|
||||
base->temp_entries->active_eapol_session = true;
|
||||
base->interface_ptr->mac_api->mcps_data_req_ext(base->interface_ptr->mac_api, &data_req, &message->ie_ext, NULL, message->priority);
|
||||
base->interface_ptr->mac_api->mcps_data_req_ext(base->interface_ptr->mac_api, &data_req, &message->ie_ext, NULL, message->priority, 0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1207,7 +1254,7 @@ static void ws_llc_mpx_eapol_request(llc_data_base_t *base, mpx_user_t *user_cb,
|
|||
nested_wp_id.us_ie = true;
|
||||
|
||||
uint16_t ie_header_length = ws_wh_headers_length(ie_header_mask, &base->ie_params);
|
||||
uint16_t nested_ie_length = ws_wp_nested_message_length(nested_wp_id, &base->ie_params);
|
||||
uint16_t nested_ie_length = ws_wp_nested_message_length(nested_wp_id, base);
|
||||
|
||||
uint16_t over_head_size = ie_header_length;
|
||||
if (nested_ie_length) {
|
||||
|
@ -1764,6 +1811,31 @@ mpx_api_t *ws_llc_mpx_api_get(struct protocol_interface_info_entry *interface)
|
|||
}
|
||||
return &base->mpx_data_base.mpx_api;
|
||||
}
|
||||
#ifdef HAVE_WS_VERSION_1_1
|
||||
|
||||
static void ws_llc_phy_cab_list_generate(struct protocol_interface_info_entry *interface, ws_phy_cap_info_t *phy_cap)
|
||||
{
|
||||
|
||||
memset(phy_cap, 0, sizeof(ws_phy_cap_info_t));
|
||||
|
||||
ws_phy_cap_info_t *prefedd_list = &interface->ws_info->phy_cap_info;
|
||||
|
||||
if (!prefedd_list->length_of_list) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
for (int i = 0; i < prefedd_list->length_of_list; i++) {
|
||||
ws_ie_lib_phy_cap_list_update(phy_cap, &prefedd_list->pcap[i]);
|
||||
}
|
||||
|
||||
//Add base support
|
||||
ws_pcap_ie_t base_cap = ws_ie_lib_generate_phy_cap_from_phy_mode_id(interface->ws_info->hopping_schdule.phy_mode_id);
|
||||
if (base_cap.operating_mode) {
|
||||
ws_ie_lib_phy_cap_list_update(phy_cap, &base_cap);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int8_t ws_llc_asynch_request(struct protocol_interface_info_entry *interface, asynch_request_t *request)
|
||||
{
|
||||
|
@ -1783,7 +1855,7 @@ int8_t ws_llc_asynch_request(struct protocol_interface_info_entry *interface, as
|
|||
request->wh_requested_ie_list.rsl_ie = false; //Never should not be a part Asynch message
|
||||
request->wh_requested_ie_list.vh_ie = false;
|
||||
uint16_t header_buffer_length = ws_wh_headers_length(request->wh_requested_ie_list, &base->ie_params);
|
||||
uint16_t wp_nested_payload_length = ws_wp_nested_message_length(request->wp_requested_nested_ie_list, &base->ie_params);
|
||||
uint16_t wp_nested_payload_length = ws_wp_nested_message_length(request->wp_requested_nested_ie_list, base);
|
||||
|
||||
//Allocated
|
||||
uint16_t total_length = header_buffer_length;
|
||||
|
@ -1880,9 +1952,37 @@ int8_t ws_llc_asynch_request(struct protocol_interface_info_entry *interface, as
|
|||
//Write Vendor spesific payload
|
||||
ptr = ws_wp_nested_vp_write(ptr, base->ie_params.vendor_payload, base->ie_params.vendor_payload_length);
|
||||
}
|
||||
|
||||
#ifdef HAVE_WS_VERSION_1_1
|
||||
if (ws_version_1_1(interface)) {
|
||||
if (request->wp_requested_nested_ie_list.lfn_gtk_version_ie) {
|
||||
ws_lfnver_ie_t lfn_ver;
|
||||
ws_lgtkhash_ie_t ws_lgtkhash;
|
||||
//Write LFN Version
|
||||
lfn_ver.lfn_version = interface->ws_info->lfngtk.lfn_version;
|
||||
ptr = ws_wp_nested_lfn_version_write(ptr, &lfn_ver);
|
||||
//Write LFN GTK Hash info
|
||||
ws_lgtkhash.lgtk0 = base->interface_ptr->ws_info->lfngtk.active_hash_1;
|
||||
ws_lgtkhash.lgtk1 = base->interface_ptr->ws_info->lfngtk.active_hash_2;
|
||||
ws_lgtkhash.lgtk2 = base->interface_ptr->ws_info->lfngtk.active_hash_3;
|
||||
ws_lgtkhash.active_lgtk_index = base->interface_ptr->ws_info->lfngtk.active_key_index;
|
||||
ws_lgtkhash.lgtk0_hash = base->interface_ptr->ws_info->lfngtk.lgtkhash;
|
||||
ws_lgtkhash.lgtk1_hash = base->interface_ptr->ws_info->lfngtk.lgtkhash + 8;
|
||||
ws_lgtkhash.lgtk2_hash = base->interface_ptr->ws_info->lfngtk.lgtkhash + 16;
|
||||
ptr = ws_wp_nested_lgtk_hash_write(ptr, &ws_lgtkhash);
|
||||
}
|
||||
|
||||
if (request->wp_requested_nested_ie_list.phy_cap_ie) {
|
||||
ws_phy_cap_info_t phy_cap;
|
||||
ws_llc_phy_cab_list_generate(base->interface_ptr, &phy_cap);
|
||||
ptr = ws_wp_nested_pcap_write(ptr, &phy_cap);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
base->interface_ptr->mac_api->mcps_data_req_ext(base->interface_ptr->mac_api, &data_req, &message->ie_ext, &request->channel_list, message->priority);
|
||||
base->interface_ptr->mac_api->mcps_data_req_ext(base->interface_ptr->mac_api, &data_req, &message->ie_ext, &request->channel_list, message->priority, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -51,24 +51,24 @@ int ws_management_node_init(
|
|||
}
|
||||
|
||||
ws_phy_cfg_t phy_cfg;
|
||||
if (ws_cfg_phy_get(&phy_cfg, NULL) < 0) {
|
||||
if (ws_cfg_phy_get(&phy_cfg) < 0) {
|
||||
return -3;
|
||||
}
|
||||
|
||||
phy_cfg.regulatory_domain = regulatory_domain;
|
||||
|
||||
if (ws_cfg_phy_set(cur, NULL, &phy_cfg, 0) < 0) {
|
||||
if (ws_cfg_phy_set(cur, &phy_cfg, 0) < 0) {
|
||||
return -4;
|
||||
}
|
||||
|
||||
ws_gen_cfg_t gen_cfg;
|
||||
if (ws_cfg_gen_get(&gen_cfg, NULL) < 0) {
|
||||
if (ws_cfg_gen_get(&gen_cfg) < 0) {
|
||||
return -3;
|
||||
}
|
||||
|
||||
strncpy(gen_cfg.network_name, network_name_ptr, 32);
|
||||
|
||||
if (ws_cfg_gen_set(cur, NULL, &gen_cfg, 0) < 0) {
|
||||
if (ws_cfg_gen_set(cur, &gen_cfg, 0) < 0) {
|
||||
return -4;
|
||||
}
|
||||
|
||||
|
@ -93,13 +93,13 @@ int ws_management_network_name_set(
|
|||
}
|
||||
|
||||
ws_gen_cfg_t cfg;
|
||||
if (ws_cfg_gen_get(&cfg, NULL) < 0) {
|
||||
if (ws_cfg_gen_get(&cfg) < 0) {
|
||||
return -3;
|
||||
}
|
||||
|
||||
strncpy(cfg.network_name, network_name_ptr, 32);
|
||||
|
||||
if (ws_cfg_gen_set(cur, NULL, &cfg, 0) < 0) {
|
||||
if (ws_cfg_gen_set(cur, &cfg, 0) < 0) {
|
||||
return -4;
|
||||
}
|
||||
|
||||
|
@ -120,7 +120,7 @@ int ws_management_network_name_get(
|
|||
}
|
||||
|
||||
ws_gen_cfg_t cfg;
|
||||
if (ws_cfg_gen_get(&cfg, NULL) < 0) {
|
||||
if (ws_cfg_gen_get(&cfg) < 0) {
|
||||
return -3;
|
||||
}
|
||||
|
||||
|
@ -143,13 +143,13 @@ int ws_management_network_name_validate(
|
|||
}
|
||||
|
||||
ws_gen_cfg_t cfg;
|
||||
if (ws_cfg_gen_get(&cfg, NULL) < 0) {
|
||||
if (ws_cfg_gen_get(&cfg) < 0) {
|
||||
return -3;
|
||||
}
|
||||
|
||||
strncpy(cfg.network_name, network_name_ptr, 32);
|
||||
|
||||
if (ws_cfg_gen_validate(NULL, &cfg) < 0) {
|
||||
if (ws_cfg_gen_validate(&cfg) < 0) {
|
||||
return -4;
|
||||
}
|
||||
|
||||
|
@ -170,7 +170,7 @@ int ws_management_domain_configuration_set(
|
|||
|
||||
ws_phy_cfg_t cfg;
|
||||
ws_phy_cfg_t cfg_default;
|
||||
if (ws_cfg_phy_get(&cfg, NULL) < 0) {
|
||||
if (ws_cfg_phy_get(&cfg) < 0) {
|
||||
return -3;
|
||||
}
|
||||
|
||||
|
@ -196,7 +196,7 @@ int ws_management_domain_configuration_set(
|
|||
cfg.channel_plan_id = channel_plan_id;
|
||||
}
|
||||
|
||||
if (ws_cfg_phy_set(cur, NULL, &cfg, 0) < 0) {
|
||||
if (ws_cfg_phy_set(cur, &cfg, 0) < 0) {
|
||||
return -4;
|
||||
}
|
||||
|
||||
|
@ -216,7 +216,7 @@ int ws_management_domain_configuration_get(
|
|||
}
|
||||
|
||||
ws_phy_cfg_t cfg;
|
||||
if (ws_cfg_phy_get(&cfg, NULL) < 0) {
|
||||
if (ws_cfg_phy_get(&cfg) < 0) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
|
@ -246,7 +246,7 @@ int ws_management_domain_configuration_validate(
|
|||
}
|
||||
|
||||
ws_phy_cfg_t cfg;
|
||||
if (ws_cfg_phy_get(&cfg, NULL) < 0) {
|
||||
if (ws_cfg_phy_get(&cfg) < 0) {
|
||||
return -3;
|
||||
}
|
||||
|
||||
|
@ -254,7 +254,7 @@ int ws_management_domain_configuration_validate(
|
|||
cfg.phy_mode_id = phy_mode_id;
|
||||
cfg.channel_plan_id = channel_plan_id;
|
||||
|
||||
if (ws_cfg_phy_validate(NULL, &cfg) < 0) {
|
||||
if (ws_cfg_phy_validate(&cfg) < 0) {
|
||||
return -4;
|
||||
}
|
||||
|
||||
|
@ -276,7 +276,7 @@ int ws_management_regulatory_domain_set(
|
|||
|
||||
ws_phy_cfg_t cfg;
|
||||
ws_phy_cfg_t cfg_default;
|
||||
if (ws_cfg_phy_get(&cfg, NULL) < 0) {
|
||||
if (ws_cfg_phy_get(&cfg) < 0) {
|
||||
return -3;
|
||||
}
|
||||
|
||||
|
@ -300,7 +300,7 @@ int ws_management_regulatory_domain_set(
|
|||
cfg.operating_class = cfg_default.operating_class;
|
||||
}
|
||||
|
||||
if (ws_cfg_phy_set(cur, NULL, &cfg, 0) < 0) {
|
||||
if (ws_cfg_phy_set(cur, &cfg, 0) < 0) {
|
||||
return -4;
|
||||
}
|
||||
|
||||
|
@ -323,7 +323,7 @@ int ws_management_regulatory_domain_get(
|
|||
}
|
||||
|
||||
ws_phy_cfg_t cfg;
|
||||
if (ws_cfg_phy_get(&cfg, NULL) < 0) {
|
||||
if (ws_cfg_phy_get(&cfg) < 0) {
|
||||
return -3;
|
||||
}
|
||||
|
||||
|
@ -347,7 +347,7 @@ int ws_management_regulatory_domain_validate(
|
|||
}
|
||||
|
||||
ws_phy_cfg_t cfg;
|
||||
if (ws_cfg_phy_get(&cfg, NULL) < 0) {
|
||||
if (ws_cfg_phy_get(&cfg) < 0) {
|
||||
return -3;
|
||||
}
|
||||
|
||||
|
@ -355,7 +355,7 @@ int ws_management_regulatory_domain_validate(
|
|||
cfg.operating_class = operating_class;
|
||||
cfg.operating_mode = operating_mode;
|
||||
|
||||
if (ws_cfg_phy_validate(NULL, &cfg) < 0) {
|
||||
if (ws_cfg_phy_validate(&cfg) < 0) {
|
||||
return -4;
|
||||
}
|
||||
|
||||
|
@ -374,13 +374,13 @@ int ws_management_network_size_set(
|
|||
}
|
||||
|
||||
ws_gen_cfg_t cfg;
|
||||
if (ws_cfg_network_size_get(&cfg, NULL) < 0) {
|
||||
if (ws_cfg_network_size_get(&cfg) < 0) {
|
||||
return -3;
|
||||
}
|
||||
|
||||
cfg.network_size = network_size;
|
||||
|
||||
if (ws_cfg_network_size_set(cur, NULL, &cfg, 0) < 0) {
|
||||
if (ws_cfg_network_size_set(cur, &cfg, 0) < 0) {
|
||||
return -3;
|
||||
}
|
||||
|
||||
|
@ -401,7 +401,7 @@ int ws_management_network_size_get(
|
|||
}
|
||||
|
||||
ws_gen_cfg_t cfg;
|
||||
if (ws_cfg_network_size_get(&cfg, NULL) < 0) {
|
||||
if (ws_cfg_network_size_get(&cfg) < 0) {
|
||||
return -3;
|
||||
}
|
||||
|
||||
|
@ -421,13 +421,13 @@ int ws_management_network_size_validate(
|
|||
}
|
||||
|
||||
ws_gen_cfg_t cfg;
|
||||
if (ws_cfg_network_size_get(&cfg, NULL) < 0) {
|
||||
if (ws_cfg_network_size_get(&cfg) < 0) {
|
||||
return -3;
|
||||
}
|
||||
|
||||
cfg.network_size = network_size;
|
||||
|
||||
if (ws_cfg_network_size_validate(NULL, &cfg) < 0) {
|
||||
if (ws_cfg_network_size_validate(&cfg) < 0) {
|
||||
return -4;
|
||||
}
|
||||
|
||||
|
@ -446,7 +446,7 @@ int ws_management_channel_mask_set(
|
|||
}
|
||||
|
||||
ws_fhss_cfg_t cfg;
|
||||
if (ws_cfg_fhss_get(&cfg, NULL) < 0) {
|
||||
if (ws_cfg_fhss_get(&cfg) < 0) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
|
@ -463,7 +463,7 @@ int ws_management_channel_mask_set(
|
|||
}
|
||||
|
||||
|
||||
if (ws_cfg_fhss_set(cur, NULL, &cfg, 0) < 0) {
|
||||
if (ws_cfg_fhss_set(cur, &cfg, 0) < 0) {
|
||||
return -3;
|
||||
}
|
||||
|
||||
|
@ -484,7 +484,7 @@ int ws_management_channel_mask_get(
|
|||
}
|
||||
|
||||
ws_fhss_cfg_t cfg;
|
||||
if (ws_cfg_fhss_get(&cfg, NULL) < 0) {
|
||||
if (ws_cfg_fhss_get(&cfg) < 0) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
|
@ -504,13 +504,13 @@ int ws_management_channel_mask_validate(
|
|||
}
|
||||
|
||||
ws_fhss_cfg_t cfg;
|
||||
if (ws_cfg_fhss_get(&cfg, NULL) < 0) {
|
||||
if (ws_cfg_fhss_get(&cfg) < 0) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
memcpy(cfg.fhss_channel_mask, channel_mask, sizeof(uint32_t) * 8);
|
||||
|
||||
if (ws_cfg_fhss_validate(NULL, &cfg) < 0) {
|
||||
if (ws_cfg_fhss_validate(&cfg) < 0) {
|
||||
return -4;
|
||||
}
|
||||
|
||||
|
@ -557,7 +557,7 @@ int ws_management_fhss_timing_configure(
|
|||
}
|
||||
|
||||
ws_fhss_cfg_t cfg;
|
||||
if (ws_cfg_fhss_get(&cfg, NULL) < 0) {
|
||||
if (ws_cfg_fhss_get(&cfg) < 0) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
|
@ -584,7 +584,7 @@ int ws_management_fhss_timing_configure(
|
|||
cfg.fhss_bc_dwell_interval = fhss_bc_dwell_interval;
|
||||
}
|
||||
|
||||
if (ws_cfg_fhss_set(cur, NULL, &cfg, 0) < 0) {
|
||||
if (ws_cfg_fhss_set(cur, &cfg, 0) < 0) {
|
||||
return -3;
|
||||
}
|
||||
|
||||
|
@ -605,7 +605,7 @@ int ws_management_fhss_unicast_channel_function_configure(
|
|||
}
|
||||
|
||||
ws_fhss_cfg_t cfg;
|
||||
if (ws_cfg_fhss_get(&cfg, NULL) < 0) {
|
||||
if (ws_cfg_fhss_get(&cfg) < 0) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
|
@ -631,7 +631,7 @@ int ws_management_fhss_unicast_channel_function_configure(
|
|||
cfg.fhss_uc_fixed_channel = cfg_default.fhss_uc_fixed_channel;
|
||||
}
|
||||
|
||||
if (ws_cfg_fhss_set(cur, NULL, &cfg, 0) < 0) {
|
||||
if (ws_cfg_fhss_set(cur, &cfg, 0) < 0) {
|
||||
return -3;
|
||||
}
|
||||
|
||||
|
@ -654,7 +654,7 @@ int ws_management_fhss_unicast_channel_function_get(
|
|||
}
|
||||
|
||||
ws_fhss_cfg_t cfg;
|
||||
if (ws_cfg_fhss_get(&cfg, NULL) < 0) {
|
||||
if (ws_cfg_fhss_get(&cfg) < 0) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
|
@ -678,7 +678,7 @@ int ws_management_fhss_unicast_channel_function_validate(
|
|||
}
|
||||
|
||||
ws_fhss_cfg_t cfg;
|
||||
if (ws_cfg_fhss_get(&cfg, NULL) < 0) {
|
||||
if (ws_cfg_fhss_get(&cfg) < 0) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
|
@ -686,7 +686,7 @@ int ws_management_fhss_unicast_channel_function_validate(
|
|||
cfg.fhss_uc_channel_function = channel_function;
|
||||
cfg.fhss_uc_fixed_channel = fixed_channel;
|
||||
|
||||
if (ws_cfg_fhss_validate(NULL, &cfg) < 0) {
|
||||
if (ws_cfg_fhss_validate(&cfg) < 0) {
|
||||
return -4;
|
||||
}
|
||||
|
||||
|
@ -708,7 +708,7 @@ int ws_management_fhss_broadcast_channel_function_configure(
|
|||
}
|
||||
|
||||
ws_fhss_cfg_t cfg;
|
||||
if (ws_cfg_fhss_get(&cfg, NULL) < 0) {
|
||||
if (ws_cfg_fhss_get(&cfg) < 0) {
|
||||
return -2;
|
||||
}
|
||||
ws_fhss_cfg_t cfg_default;
|
||||
|
@ -740,7 +740,7 @@ int ws_management_fhss_broadcast_channel_function_configure(
|
|||
cfg.fhss_bc_fixed_channel = cfg_default.fhss_bc_fixed_channel;
|
||||
}
|
||||
|
||||
if (ws_cfg_fhss_set(cur, NULL, &cfg, 0) < 0) {
|
||||
if (ws_cfg_fhss_set(cur, &cfg, 0) < 0) {
|
||||
return -3;
|
||||
}
|
||||
|
||||
|
@ -764,7 +764,7 @@ int ws_management_fhss_broadcast_channel_function_get(
|
|||
}
|
||||
|
||||
ws_fhss_cfg_t cfg;
|
||||
if (ws_cfg_fhss_get(&cfg, NULL) < 0) {
|
||||
if (ws_cfg_fhss_get(&cfg) < 0) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
|
@ -790,7 +790,7 @@ int ws_management_fhss_broadcast_channel_function_validate(
|
|||
}
|
||||
|
||||
ws_fhss_cfg_t cfg;
|
||||
if (ws_cfg_fhss_get(&cfg, NULL) < 0) {
|
||||
if (ws_cfg_fhss_get(&cfg) < 0) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
|
@ -799,7 +799,7 @@ int ws_management_fhss_broadcast_channel_function_validate(
|
|||
cfg.fhss_bc_channel_function = channel_function;
|
||||
cfg.fhss_bc_fixed_channel = fixed_channel;
|
||||
|
||||
if (ws_cfg_fhss_validate(NULL, &cfg) < 0) {
|
||||
if (ws_cfg_fhss_validate(&cfg) < 0) {
|
||||
return -4;
|
||||
}
|
||||
|
||||
|
@ -821,7 +821,7 @@ int ws_management_timing_parameters_set(
|
|||
}
|
||||
|
||||
ws_timing_cfg_t cfg;
|
||||
if (ws_cfg_timing_get(&cfg, NULL) < 0) {
|
||||
if (ws_cfg_timing_get(&cfg) < 0) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
|
@ -854,7 +854,7 @@ int ws_management_timing_parameters_set(
|
|||
cfg.pan_timeout = cfg_default.pan_timeout;;
|
||||
}
|
||||
|
||||
if (ws_cfg_timing_set(cur, NULL, &cfg, 0) < 0) {
|
||||
if (ws_cfg_timing_set(cur, &cfg, 0) < 0) {
|
||||
return -3;
|
||||
}
|
||||
|
||||
|
@ -878,7 +878,7 @@ int ws_management_timing_parameters_get(
|
|||
}
|
||||
|
||||
ws_timing_cfg_t cfg;
|
||||
if (ws_cfg_timing_get(&cfg, NULL) < 0) {
|
||||
if (ws_cfg_timing_get(&cfg) < 0) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
|
@ -904,7 +904,7 @@ int ws_management_timing_parameters_validate(
|
|||
}
|
||||
|
||||
ws_timing_cfg_t cfg;
|
||||
if (ws_cfg_timing_get(&cfg, NULL) < 0) {
|
||||
if (ws_cfg_timing_get(&cfg) < 0) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
|
@ -913,7 +913,7 @@ int ws_management_timing_parameters_validate(
|
|||
cfg.disc_trickle_k = disc_trickle_k;
|
||||
cfg.pan_timeout = pan_timeout;
|
||||
|
||||
if (ws_cfg_timing_validate(NULL, &cfg) < 0) {
|
||||
if (ws_cfg_timing_validate(&cfg) < 0) {
|
||||
return -4;
|
||||
}
|
||||
|
||||
|
@ -957,4 +957,33 @@ int ws_device_min_sens_set(
|
|||
return 0;
|
||||
}
|
||||
|
||||
int ws_management_phy_capability_set(
|
||||
int8_t interface_id,
|
||||
ws_management_pcap_info_t *pcap_list)
|
||||
{
|
||||
#ifdef HAVE_WS_VERSION_1_1
|
||||
protocol_interface_info_entry_t *cur;
|
||||
cur = protocol_stack_interface_info_get_by_id(interface_id);
|
||||
if (!cur || !ws_info(cur) || pcap_list->length_of_list > 7) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
//Set supported configure for MDR
|
||||
//TODO add validation for Phy_type and operation modes
|
||||
cur->ws_info->phy_cap_info.length_of_list = pcap_list->length_of_list;
|
||||
for (int i = 0; i < pcap_list->length_of_list; i++) {
|
||||
cur->ws_info->phy_cap_info.pcap[i].phy_type = pcap_list->pcap[i].phy_type;
|
||||
cur->ws_info->phy_cap_info.pcap[i].operating_mode = pcap_list->pcap[i].operating_mode;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
#else
|
||||
(void)interface_id;
|
||||
(void)pcap_list;
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#endif // HAVE_WS
|
||||
|
|
|
@ -26,7 +26,9 @@
|
|||
#include "6LoWPAN/ws/ws_config.h"
|
||||
#include "6LoWPAN/ws/ws_neighbor_class.h"
|
||||
#include "6LoWPAN/ws/ws_common.h"
|
||||
#include "6LoWPAN/ws/ws_ie_lib.h"
|
||||
#include "ws_management_api.h"
|
||||
#include "mac_api.h"
|
||||
|
||||
#ifdef HAVE_WS
|
||||
|
||||
|
@ -168,7 +170,7 @@ static void ws_neighbour_excluded_mask_by_range(ws_channel_mask_t *channel_info,
|
|||
|
||||
if (channel >= range_start && channel <= range_stop) {
|
||||
//Cut channel
|
||||
compare_mask_bit = 1 << (channel % 32);
|
||||
compare_mask_bit = 1U << (channel % 32);
|
||||
mask_index = 0 + (channel / 32);
|
||||
|
||||
if (channel_info->channel_mask[mask_index] & compare_mask_bit) {
|
||||
|
@ -187,7 +189,7 @@ static uint32_t ws_reserve_order_32_bit(uint32_t value)
|
|||
uint32_t ret_val = 0;
|
||||
for (uint8_t i = 0; i < 32; i++) {
|
||||
if ((value & (1 << i))) {
|
||||
ret_val |= 1 << ((32 - 1) - i);
|
||||
ret_val |= 1U << ((32 - 1) - i);
|
||||
}
|
||||
}
|
||||
return ret_val;
|
||||
|
@ -258,21 +260,23 @@ void ws_neighbor_class_neighbor_unicast_schedule_set(ws_neighbor_class_entry_t *
|
|||
} else if (ws_us->channel_plan == 1) {
|
||||
ws_neighbor->fhss_data.uc_timing_info.unicast_number_of_channels = ws_us->plan.one.number_of_channel;
|
||||
|
||||
} else if (ws_us->channel_plan == 2) {
|
||||
//TODO add Channel plan 2 channel count function call here
|
||||
}
|
||||
|
||||
//Handle excluded channel and generate activate channel list
|
||||
if (ws_us->excluded_channel_ctrl == WS_EXC_CHAN_CTRL_RANGE) {
|
||||
ws_generate_channel_list(ws_neighbor->fhss_data.uc_channel_list.channel_mask, ws_neighbor->fhss_data.uc_timing_info.unicast_number_of_channels, own_shedule->regulatory_domain, own_shedule->operating_class, own_shedule->channel_plan_id);
|
||||
ws_neighbor->fhss_data.uc_channel_list.channel_count = ws_active_channel_count(ws_neighbor->fhss_data.uc_channel_list.channel_mask, ws_neighbor->fhss_data.uc_timing_info.unicast_number_of_channels);
|
||||
ws_common_generate_channel_list(ws_neighbor->fhss_data.uc_channel_list.channel_mask, ws_neighbor->fhss_data.uc_timing_info.unicast_number_of_channels, own_shedule->regulatory_domain, own_shedule->operating_class, own_shedule->channel_plan_id);
|
||||
ws_neighbor->fhss_data.uc_channel_list.channel_count = ws_common_active_channel_count(ws_neighbor->fhss_data.uc_channel_list.channel_mask, ws_neighbor->fhss_data.uc_timing_info.unicast_number_of_channels);
|
||||
ws_neighbour_excluded_mask_by_range(&ws_neighbor->fhss_data.uc_channel_list, &ws_us->excluded_channels.range, ws_neighbor->fhss_data.uc_timing_info.unicast_number_of_channels);
|
||||
} else if (ws_us->excluded_channel_ctrl == WS_EXC_CHAN_CTRL_BITMASK) {
|
||||
ws_generate_channel_list(ws_neighbor->fhss_data.uc_channel_list.channel_mask, ws_neighbor->fhss_data.uc_timing_info.unicast_number_of_channels, own_shedule->regulatory_domain, own_shedule->operating_class, own_shedule->channel_plan_id);
|
||||
ws_neighbor->fhss_data.uc_channel_list.channel_count = ws_active_channel_count(ws_neighbor->fhss_data.uc_channel_list.channel_mask, ws_neighbor->fhss_data.uc_timing_info.unicast_number_of_channels);
|
||||
ws_common_generate_channel_list(ws_neighbor->fhss_data.uc_channel_list.channel_mask, ws_neighbor->fhss_data.uc_timing_info.unicast_number_of_channels, own_shedule->regulatory_domain, own_shedule->operating_class, own_shedule->channel_plan_id);
|
||||
ws_neighbor->fhss_data.uc_channel_list.channel_count = ws_common_active_channel_count(ws_neighbor->fhss_data.uc_channel_list.channel_mask, ws_neighbor->fhss_data.uc_timing_info.unicast_number_of_channels);
|
||||
ws_neighbour_excluded_mask_by_mask(&ws_neighbor->fhss_data.uc_channel_list, &ws_us->excluded_channels.mask, ws_neighbor->fhss_data.uc_timing_info.unicast_number_of_channels);
|
||||
} else if (ws_us->excluded_channel_ctrl == WS_EXC_CHAN_CTRL_NONE) {
|
||||
if (ws_neighbor->fhss_data.uc_timing_info.unicast_number_of_channels != ws_neighbor->fhss_data.uc_channel_list.channel_count) {
|
||||
ws_generate_channel_list(ws_neighbor->fhss_data.uc_channel_list.channel_mask, ws_neighbor->fhss_data.uc_timing_info.unicast_number_of_channels, own_shedule->regulatory_domain, own_shedule->operating_class, own_shedule->channel_plan_id);
|
||||
ws_neighbor->fhss_data.uc_channel_list.channel_count = ws_active_channel_count(ws_neighbor->fhss_data.uc_channel_list.channel_mask, ws_neighbor->fhss_data.uc_timing_info.unicast_number_of_channels);
|
||||
ws_common_generate_channel_list(ws_neighbor->fhss_data.uc_channel_list.channel_mask, ws_neighbor->fhss_data.uc_timing_info.unicast_number_of_channels, own_shedule->regulatory_domain, own_shedule->operating_class, own_shedule->channel_plan_id);
|
||||
ws_neighbor->fhss_data.uc_channel_list.channel_count = ws_common_active_channel_count(ws_neighbor->fhss_data.uc_channel_list.channel_mask, ws_neighbor->fhss_data.uc_timing_info.unicast_number_of_channels);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -391,6 +395,13 @@ bool ws_neighbor_class_neighbor_duplicate_packet_check(ws_neighbor_class_entry_t
|
|||
return true;
|
||||
}
|
||||
|
||||
#ifdef HAVE_WS_VERSION_1_1
|
||||
void ws_neighbor_class_pcap_ie_store(struct ws_neighbor_class_entry *ws_neighbor, const struct mcps_data_ie_list *ie_ext)
|
||||
{
|
||||
ws_wp_nested_pcap_read(ie_ext->payloadIeList, ie_ext->payloadIeListLength, &ws_neighbor->pcap_info);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* HAVE_WS */
|
||||
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
#include "fhss_ws_extension.h"
|
||||
#include "6LoWPAN/ws/ws_common_defines.h"
|
||||
|
||||
struct mcps_data_ie_list;
|
||||
|
||||
#define RSL_UNITITIALIZED 0x7fff
|
||||
|
||||
typedef struct ws_neighbor_class_entry {
|
||||
|
@ -34,6 +36,10 @@ typedef struct ws_neighbor_class_entry {
|
|||
bool broadcast_shedule_info_stored: 1;
|
||||
bool synch_done : 1;
|
||||
bool unicast_data_rx : 1;
|
||||
#ifdef HAVE_WS_VERSION_1_1
|
||||
uint8_t phy_mode_id; /*!< Bootstrap configured Preference Phy mode for MDR */
|
||||
ws_phy_cap_info_t pcap_info;
|
||||
#endif
|
||||
} ws_neighbor_class_entry_t;
|
||||
|
||||
/**
|
||||
|
@ -182,5 +188,10 @@ void ws_neighbor_class_rsl_in_calculate(ws_neighbor_class_entry_t *ws_neighbor,
|
|||
void ws_neighbor_class_rsl_out_calculate(ws_neighbor_class_entry_t *ws_neighbor, uint8_t rsl_reported);
|
||||
|
||||
bool ws_neighbor_class_neighbor_duplicate_packet_check(ws_neighbor_class_entry_t *ws_neighbor, uint8_t mac_dsn, uint32_t rx_timestamp);
|
||||
#ifdef HAVE_WS_VERSION_1_1
|
||||
void ws_neighbor_class_pcap_ie_store(ws_neighbor_class_entry_t *ws_neighbor, const struct mcps_data_ie_list *ie_ext);
|
||||
#else
|
||||
#define ws_neighbor_class_pcap_ie_store(ws_neighbor, ie_ext) ((void)0)
|
||||
#endif
|
||||
|
||||
#endif /* WS_NEIGHBOR_CLASS_H_ */
|
||||
|
|
|
@ -80,6 +80,13 @@
|
|||
// Short GTK lifetime value, for GTK install check
|
||||
#define SHORT_GTK_LIFETIME 10 * 3600 // 10 hours
|
||||
|
||||
// Frame counter exhaust check timer
|
||||
#define FRAME_CNT_TIMER 3600
|
||||
|
||||
#define SECONDS_IN_DAY (3600 * 24)
|
||||
#define TIME_MINIMUM_DIFFERENCE 5
|
||||
#define TIME_DIFFERENCE_THRESHOLD 3600
|
||||
|
||||
typedef struct {
|
||||
ns_list_link_t link; /**< Link */
|
||||
uint16_t pan_id; /**< PAN ID */
|
||||
|
@ -93,6 +100,7 @@ typedef struct {
|
|||
ws_pae_auth_nw_info_updated *nw_info_updated; /**< Security keys network info updated callback */
|
||||
ws_pae_auth_ip_addr_get *ip_addr_get; /**< IP address get callback */
|
||||
ws_pae_auth_congestion_get *congestion_get; /**< Congestion get callback */
|
||||
ws_pae_auth_nw_frame_counter_read *nw_frame_cnt_read; /**< Network frame counter read callback */
|
||||
supp_list_t active_supp_list; /**< List of active supplicants */
|
||||
supp_list_t waiting_supp_list; /**< List of waiting supplicants */
|
||||
shared_comp_list_t shared_comp_list; /**< Shared component list */
|
||||
|
@ -101,13 +109,20 @@ typedef struct {
|
|||
const sec_prot_certs_t *certs; /**< Certificates */
|
||||
sec_prot_keys_nw_info_t *sec_keys_nw_info; /**< Security keys network information */
|
||||
sec_cfg_t *sec_cfg; /**< Security configuration */
|
||||
frame_counters_t *frame_counters; /**< Frame counters */
|
||||
uint64_t prev_system_time; /**< Previous system time */
|
||||
uint64_t system_time_diff; /**< System time diffence */
|
||||
uint32_t prev_frame_cnt; /**< Previous frame counter */
|
||||
uint16_t prev_frame_cnt_timer; /**< Previous frame counter timer */
|
||||
uint16_t supp_max_number; /**< Max number of stored supplicants */
|
||||
uint16_t waiting_supp_list_size; /**< Waiting supplicants list size */
|
||||
uint8_t relay_socked_msg_if_instance_id; /**< Relay socket message interface instance identifier */
|
||||
uint8_t radius_socked_msg_if_instance_id; /**< Radius socket message interface instance identifier */
|
||||
bool timer_running : 1; /**< Timer is running */
|
||||
bool gtk_new_inst_req_exp : 1; /**< GTK new install required timer expired */
|
||||
bool gtk_new_act_time_exp: 1; /**< GTK new activation time expired */
|
||||
bool gtk_new_act_time_exp : 1; /**< GTK new activation time expired */
|
||||
bool prev_system_time_set : 1; /**< Previous system time set */
|
||||
bool prev_frame_cnt_set : 1; /**< Previous frame counter set */
|
||||
} pae_auth_t;
|
||||
|
||||
static int8_t ws_pae_auth_network_keys_from_gtks_set(pae_auth_t *pae_auth, bool force_install);
|
||||
|
@ -118,6 +133,8 @@ static pae_auth_t *ws_pae_auth_get(protocol_interface_info_entry_t *interface_pt
|
|||
static pae_auth_t *ws_pae_auth_by_kmp_service_get(kmp_service_t *service);
|
||||
static int8_t ws_pae_auth_event_send(kmp_service_t *service, void *data);
|
||||
static void ws_pae_auth_tasklet_handler(arm_event_s *event);
|
||||
static uint32_t ws_pae_auth_lifetime_key_frame_cnt_check(pae_auth_t *pae_auth, uint8_t gtk_index, uint16_t seconds);
|
||||
static uint32_t ws_pae_auth_lifetime_system_time_check(pae_auth_t *pae_auth, int8_t gtk_index, uint16_t seconds, uint32_t dec_extra_seconds);
|
||||
static void ws_pae_auth_gtk_key_insert(pae_auth_t *pae_auth);
|
||||
static int8_t ws_pae_auth_new_gtk_activate(pae_auth_t *pae_auth);
|
||||
static int8_t ws_pae_auth_timer_if_start(kmp_service_t *service, kmp_api_t *kmp);
|
||||
|
@ -145,9 +162,9 @@ static void ws_pae_auth_waiting_supp_deleted(void *pae_auth);
|
|||
static int8_t tasklet_id = -1;
|
||||
static NS_LIST_DEFINE(pae_auth_list, pae_auth_t, link);
|
||||
|
||||
int8_t ws_pae_auth_init(protocol_interface_info_entry_t *interface_ptr, sec_prot_gtk_keys_t *next_gtks, const sec_prot_certs_t *certs, sec_cfg_t *sec_cfg, sec_prot_keys_nw_info_t *sec_keys_nw_info)
|
||||
int8_t ws_pae_auth_init(protocol_interface_info_entry_t *interface_ptr, sec_prot_gtk_keys_t *next_gtks, const sec_prot_certs_t *certs, sec_cfg_t *sec_cfg, sec_prot_keys_nw_info_t *sec_keys_nw_info, frame_counters_t *frame_counters)
|
||||
{
|
||||
if (!interface_ptr || !next_gtks || !certs || !sec_cfg || !sec_keys_nw_info) {
|
||||
if (!interface_ptr || !next_gtks || !certs || !sec_cfg || !sec_keys_nw_info || !frame_counters) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -175,16 +192,24 @@ int8_t ws_pae_auth_init(protocol_interface_info_entry_t *interface_ptr, sec_prot
|
|||
pae_auth->nw_info_updated = NULL;
|
||||
pae_auth->ip_addr_get = NULL;
|
||||
pae_auth->congestion_get = NULL;
|
||||
pae_auth->nw_frame_cnt_read = NULL;
|
||||
|
||||
pae_auth->next_gtks = next_gtks;
|
||||
pae_auth->certs = certs;
|
||||
pae_auth->sec_keys_nw_info = sec_keys_nw_info;
|
||||
pae_auth->sec_cfg = sec_cfg;
|
||||
pae_auth->frame_counters = frame_counters;
|
||||
pae_auth->prev_system_time = 0;
|
||||
pae_auth->system_time_diff = 0;
|
||||
pae_auth->prev_frame_cnt = 0;
|
||||
pae_auth->prev_frame_cnt_timer = FRAME_CNT_TIMER;
|
||||
pae_auth->supp_max_number = SUPPLICANT_MAX_NUMBER;
|
||||
pae_auth->waiting_supp_list_size = 0;
|
||||
|
||||
pae_auth->gtk_new_inst_req_exp = false;
|
||||
pae_auth->gtk_new_act_time_exp = false;
|
||||
pae_auth->prev_frame_cnt_set = false;
|
||||
pae_auth->prev_system_time_set = false;
|
||||
|
||||
pae_auth->relay_socked_msg_if_instance_id = 0;
|
||||
pae_auth->radius_socked_msg_if_instance_id = 0;
|
||||
|
@ -316,7 +341,7 @@ int8_t ws_pae_auth_delete(protocol_interface_info_entry_t *interface_ptr)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void ws_pae_auth_cb_register(protocol_interface_info_entry_t *interface_ptr, ws_pae_auth_gtk_hash_set *hash_set, ws_pae_auth_nw_key_insert *nw_key_insert, ws_pae_auth_nw_key_index_set *nw_key_index_set, ws_pae_auth_nw_info_updated *nw_info_updated, ws_pae_auth_ip_addr_get *ip_addr_get, ws_pae_auth_congestion_get *congestion_get)
|
||||
void ws_pae_auth_cb_register(protocol_interface_info_entry_t *interface_ptr, ws_pae_auth_gtk_hash_set *hash_set, ws_pae_auth_nw_key_insert *nw_key_insert, ws_pae_auth_nw_key_index_set *nw_key_index_set, ws_pae_auth_nw_info_updated *nw_info_updated, ws_pae_auth_ip_addr_get *ip_addr_get, ws_pae_auth_congestion_get *congestion_get, ws_pae_auth_nw_frame_counter_read *nw_frame_cnt_read)
|
||||
{
|
||||
if (!interface_ptr) {
|
||||
return;
|
||||
|
@ -333,6 +358,7 @@ void ws_pae_auth_cb_register(protocol_interface_info_entry_t *interface_ptr, ws_
|
|||
pae_auth->nw_info_updated = nw_info_updated;
|
||||
pae_auth->ip_addr_get = ip_addr_get;
|
||||
pae_auth->congestion_get = congestion_get;
|
||||
pae_auth->nw_frame_cnt_read = nw_frame_cnt_read;
|
||||
}
|
||||
|
||||
void ws_pae_auth_start(protocol_interface_info_entry_t *interface_ptr)
|
||||
|
@ -364,6 +390,9 @@ void ws_pae_auth_start(protocol_interface_info_entry_t *interface_ptr)
|
|||
|
||||
// Sets active key index
|
||||
ws_pae_auth_network_key_index_set(pae_auth, index);
|
||||
|
||||
pae_auth->prev_system_time = ws_pae_current_time_get();
|
||||
pae_auth->prev_system_time_set = true;
|
||||
}
|
||||
|
||||
void ws_pae_auth_gtks_updated(protocol_interface_info_entry_t *interface_ptr)
|
||||
|
@ -734,7 +763,12 @@ void ws_pae_auth_slow_timer(uint16_t seconds)
|
|||
if (!sec_prot_keys_gtk_is_set(pae_auth->sec_keys_nw_info->gtks, i)) {
|
||||
continue;
|
||||
}
|
||||
uint32_t timer_seconds = sec_prot_keys_gtk_lifetime_decrement(pae_auth->sec_keys_nw_info->gtks, i, current_time, seconds, true);
|
||||
uint32_t gtk_lifetime_dec_extra_seconds = 0;
|
||||
if (active_index == i) {
|
||||
gtk_lifetime_dec_extra_seconds = ws_pae_auth_lifetime_key_frame_cnt_check(pae_auth, i, seconds);
|
||||
gtk_lifetime_dec_extra_seconds = ws_pae_auth_lifetime_system_time_check(pae_auth, i, seconds, gtk_lifetime_dec_extra_seconds);
|
||||
}
|
||||
uint32_t timer_seconds = sec_prot_keys_gtk_lifetime_decrement(pae_auth->sec_keys_nw_info->gtks, i, current_time, seconds + gtk_lifetime_dec_extra_seconds, true);
|
||||
if (active_index == i) {
|
||||
if (!pae_auth->gtk_new_inst_req_exp) {
|
||||
pae_auth->gtk_new_inst_req_exp = ws_pae_timers_gtk_new_install_required(pae_auth->sec_cfg, timer_seconds);
|
||||
|
@ -766,6 +800,10 @@ void ws_pae_auth_slow_timer(uint16_t seconds)
|
|||
pae_auth->nw_info_updated(pae_auth->interface_ptr);
|
||||
}
|
||||
}
|
||||
if (gtk_lifetime_dec_extra_seconds != 0) {
|
||||
// Update keys to NVM as needed
|
||||
pae_auth->nw_info_updated(pae_auth->interface_ptr);
|
||||
}
|
||||
}
|
||||
|
||||
if (timer_seconds == 0) {
|
||||
|
@ -786,6 +824,159 @@ void ws_pae_auth_slow_timer(uint16_t seconds)
|
|||
ws_pae_key_storage_timer(seconds);
|
||||
}
|
||||
|
||||
static uint32_t ws_pae_auth_lifetime_key_frame_cnt_check(pae_auth_t *pae_auth, uint8_t gtk_index, uint16_t seconds)
|
||||
{
|
||||
uint32_t decrement_seconds = 0;
|
||||
|
||||
if (pae_auth->prev_frame_cnt_timer > seconds) {
|
||||
pae_auth->prev_frame_cnt_timer -= seconds;
|
||||
return 0;
|
||||
}
|
||||
pae_auth->prev_frame_cnt_timer = FRAME_CNT_TIMER;
|
||||
|
||||
uint32_t frame_cnt = 0;
|
||||
if (pae_auth->nw_frame_cnt_read(pae_auth->interface_ptr, &frame_cnt, gtk_index) < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
sec_timer_cfg_t *timer_cfg = &pae_auth->sec_cfg->timer_cfg;
|
||||
|
||||
// For GTK lifetime and frame counter space calculate the percent that has been used
|
||||
uint32_t gtk_lifetime_left = sec_prot_keys_gtk_lifetime_get(pae_auth->sec_keys_nw_info->gtks, gtk_index);
|
||||
uint32_t gtk_lifetime = timer_cfg->gtk_expire_offset;
|
||||
uint32_t gtk_lifetime_left_percent = gtk_lifetime_left * 100 / gtk_lifetime;
|
||||
|
||||
uint32_t frame_cnt_left_percent = ((uint64_t)((UINT32_MAX - frame_cnt))) * 100 / UINT32_MAX;
|
||||
|
||||
tr_info("Active GTK lifetime %"PRIu32", frame counter %"PRIu32" percent, counter %"PRIu32, gtk_lifetime_left_percent, frame_cnt_left_percent, frame_cnt);
|
||||
|
||||
/* If frame counter space has been exhausted faster than should be based on GTK lifetime
|
||||
* decrements GTK lifetime. Do not check until 20% of the frame counter space has been used
|
||||
* so that we have data from longer time period. As sanity check, validate that GTK lifetime
|
||||
* is not more than 105% of the GTK lifetime.
|
||||
*/
|
||||
uint32_t gtk_new_install_req_seconds = timer_cfg->gtk_expire_offset - timer_cfg->gtk_new_install_req * timer_cfg->gtk_expire_offset / 100;
|
||||
if ((frame_cnt_left_percent < gtk_lifetime_left_percent && frame_cnt_left_percent < 80) ||
|
||||
gtk_lifetime_left_percent > 105) {
|
||||
// If not yet on GTK update period
|
||||
if (gtk_lifetime_left > (gtk_new_install_req_seconds + SECONDS_IN_DAY)) {
|
||||
uint32_t diff = gtk_lifetime_left_percent - frame_cnt_left_percent;
|
||||
decrement_seconds = gtk_lifetime * diff / 100 + SECONDS_IN_DAY;
|
||||
if (decrement_seconds > gtk_lifetime_left - gtk_new_install_req_seconds) {
|
||||
decrement_seconds = gtk_lifetime_left - gtk_new_install_req_seconds;
|
||||
}
|
||||
tr_info("Decrement GTK lifetime percent, seconds %"PRIu32, decrement_seconds);
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate how much frame counters have changed and store maximum if larger than previous maximum
|
||||
uint32_t frame_cnt_diff = 0;
|
||||
if (pae_auth->prev_frame_cnt_set && frame_cnt > pae_auth->prev_frame_cnt) {
|
||||
frame_cnt_diff = frame_cnt - pae_auth->prev_frame_cnt;
|
||||
if (frame_cnt_diff > pae_auth->frame_counters->counter[gtk_index].max_frame_counter_chg) {
|
||||
pae_auth->frame_counters->counter[gtk_index].max_frame_counter_chg = frame_cnt_diff;
|
||||
}
|
||||
}
|
||||
|
||||
tr_info("Frame counter change %"PRIu32", max %"PRIu32, frame_cnt_diff, pae_auth->frame_counters->counter[gtk_index].max_frame_counter_chg);
|
||||
|
||||
/* Calculates an estimate for how much free frame counter space is needed for the GTK update and
|
||||
* initiates it faster if needed (default length of GTK update is 6 days).
|
||||
*/
|
||||
uint32_t max_needed_frame_counters =
|
||||
pae_auth->frame_counters->counter[gtk_index].max_frame_counter_chg * gtk_new_install_req_seconds / 3600;
|
||||
// Adds 20% to calculated value
|
||||
max_needed_frame_counters = max_needed_frame_counters * 120 / 100;
|
||||
// If estimated value is more than is left starts GTK update right away (if not already started)
|
||||
if (max_needed_frame_counters >= (UINT32_MAX - frame_cnt)) {
|
||||
if (gtk_lifetime_left > gtk_new_install_req_seconds) {
|
||||
decrement_seconds = gtk_lifetime_left - gtk_new_install_req_seconds;
|
||||
tr_info("Decrement GTK lifetime update, seconds %"PRIu32, decrement_seconds);
|
||||
}
|
||||
}
|
||||
|
||||
/* Calculates an estimate for how much free frame counter space is needed for the GTK activation and
|
||||
* initiates it faster if needed (default length of GTK activation is 60 minutes).
|
||||
*/
|
||||
uint32_t gtk_new_activation_time_seconds = timer_cfg->gtk_expire_offset / timer_cfg->gtk_new_act_time;
|
||||
// Calculates the estimated maximum value for frame counter during GTK update
|
||||
max_needed_frame_counters =
|
||||
pae_auth->frame_counters->counter[gtk_index].max_frame_counter_chg * gtk_new_activation_time_seconds / 3600;
|
||||
// Adds 200% to calculated value
|
||||
max_needed_frame_counters = max_needed_frame_counters * 300 / 100;
|
||||
// If estimated value is more than is left starts GTK update right away (if not already started)
|
||||
if (max_needed_frame_counters >= (UINT32_MAX - frame_cnt)) {
|
||||
if (gtk_lifetime_left > gtk_new_activation_time_seconds) {
|
||||
decrement_seconds = gtk_lifetime_left - gtk_new_activation_time_seconds;
|
||||
tr_info("Decrement GTK lifetime activation, seconds %"PRIu32, decrement_seconds);
|
||||
}
|
||||
}
|
||||
|
||||
pae_auth->prev_frame_cnt = frame_cnt;
|
||||
pae_auth->prev_frame_cnt_set = true;
|
||||
|
||||
return decrement_seconds;
|
||||
}
|
||||
|
||||
static uint32_t ws_pae_auth_lifetime_system_time_check(pae_auth_t *pae_auth, int8_t gtk_index, uint16_t seconds, uint32_t dec_extra_seconds)
|
||||
{
|
||||
// Read current system time and compare it to previous time
|
||||
uint64_t current_time = ws_pae_current_time_get();
|
||||
if (pae_auth->prev_system_time_set) {
|
||||
if (current_time > pae_auth->prev_system_time + TIME_MINIMUM_DIFFERENCE) {
|
||||
pae_auth->system_time_diff += current_time - pae_auth->prev_system_time;
|
||||
}
|
||||
}
|
||||
pae_auth->prev_system_time = current_time;
|
||||
pae_auth->prev_system_time_set = true;
|
||||
|
||||
uint64_t time_diff = 0;
|
||||
// Update lifetimes only if time difference is more than hour
|
||||
if (pae_auth->system_time_diff > TIME_DIFFERENCE_THRESHOLD + seconds + dec_extra_seconds) {
|
||||
time_diff = pae_auth->system_time_diff - seconds - dec_extra_seconds;
|
||||
} else {
|
||||
return dec_extra_seconds;
|
||||
}
|
||||
pae_auth->system_time_diff = 0;
|
||||
|
||||
uint32_t new_dec_extra_seconds = dec_extra_seconds;
|
||||
|
||||
if (time_diff > 0) {
|
||||
/* If the system time has made a large jump then use the stored time to calculate the lifetime
|
||||
(this implies e.g. that new time has been received from NTP and old time was not valid) */
|
||||
if (!ws_pae_time_old_and_new_validate(current_time, current_time + time_diff)) {
|
||||
// Allow one jump without invalidating active GTK
|
||||
if (pae_auth->sec_keys_nw_info->system_time_changed == SYSTEM_TIME_NOT_CHANGED) {
|
||||
pae_auth->sec_keys_nw_info->system_time_changed = SYSTEM_TIME_CHANGED;
|
||||
tr_info("System time large change ignored; difference: %"PRIu64, time_diff);
|
||||
time_diff = 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t gtk_lifetime_left = sec_prot_keys_gtk_lifetime_get(pae_auth->sec_keys_nw_info->gtks, gtk_index);
|
||||
sec_timer_cfg_t *timer_cfg = &pae_auth->sec_cfg->timer_cfg;
|
||||
uint32_t gtk_new_activation_time_seconds = timer_cfg->gtk_expire_offset / timer_cfg->gtk_new_act_time;
|
||||
|
||||
// If there is GTK lifetime left
|
||||
if (gtk_lifetime_left > (seconds + dec_extra_seconds + time_diff)) {
|
||||
// If GTK lifetime would be less than new activation time sets decrements time to activation time
|
||||
if (gtk_lifetime_left - seconds - dec_extra_seconds - time_diff < gtk_new_activation_time_seconds) {
|
||||
new_dec_extra_seconds = gtk_lifetime_left - gtk_new_activation_time_seconds;
|
||||
} else {
|
||||
// Decrements GTK lifetime
|
||||
new_dec_extra_seconds = dec_extra_seconds + time_diff;
|
||||
}
|
||||
} else {
|
||||
// If there is no GTK lifetime left decrements time to activation time
|
||||
new_dec_extra_seconds = gtk_lifetime_left - gtk_new_activation_time_seconds;
|
||||
}
|
||||
|
||||
tr_info("System change difference: %"PRIu64" decrement extra: %"PRIu32" (seconds: %"PRIu16" previous extra %"PRIu32")", time_diff, new_dec_extra_seconds, seconds, dec_extra_seconds);
|
||||
}
|
||||
|
||||
return new_dec_extra_seconds;
|
||||
}
|
||||
|
||||
static void ws_pae_auth_gtk_key_insert(pae_auth_t *pae_auth)
|
||||
{
|
||||
// Gets index to install the key
|
||||
|
@ -962,27 +1153,36 @@ static bool ws_pae_auth_active_limit_reached(uint16_t active_supp, pae_auth_t *p
|
|||
return pae_auth->congestion_get(pae_auth->interface_ptr, active_supp);
|
||||
}
|
||||
|
||||
static void ws_pae_auth_waiting_supp_remove_oldest(pae_auth_t *pae_auth, const kmp_addr_t *addr)
|
||||
{
|
||||
supp_entry_t *delete_supp = ns_list_get_last(&pae_auth->waiting_supp_list);
|
||||
if (!delete_supp) {
|
||||
return;
|
||||
}
|
||||
tr_info("PAE: waiting list full, eui-64: %s, deleted eui-64: %s", trace_array(addr->eui_64, 8), trace_array(delete_supp->addr.eui_64, 8));
|
||||
// Create new instance
|
||||
kmp_api_t *new_kmp = ws_pae_auth_kmp_create_and_start(pae_auth->kmp_service, MSG_PROT, pae_auth->relay_socked_msg_if_instance_id, delete_supp, pae_auth->sec_cfg);
|
||||
if (!new_kmp) {
|
||||
return;
|
||||
}
|
||||
kmp_api_create_request(new_kmp, MSG_PROT, &delete_supp->addr, &delete_supp->sec_keys);
|
||||
(void) ws_pae_lib_supp_list_remove(pae_auth, &pae_auth->waiting_supp_list, delete_supp, ws_pae_auth_waiting_supp_deleted);
|
||||
}
|
||||
|
||||
static supp_entry_t *ws_pae_auth_waiting_supp_list_add(pae_auth_t *pae_auth, supp_entry_t *supp_entry, const kmp_addr_t *addr)
|
||||
{
|
||||
// Entry is already allocated
|
||||
if (supp_entry) {
|
||||
// If the waiting list if full removes the oldest entry from the list
|
||||
if (pae_auth->waiting_supp_list_size >= WAITING_SUPPLICANT_LIST_MAX_SIZE) {
|
||||
ws_pae_auth_waiting_supp_remove_oldest(pae_auth, addr);
|
||||
}
|
||||
ns_list_add_to_start(&pae_auth->waiting_supp_list, supp_entry);
|
||||
pae_auth->waiting_supp_list_size++;
|
||||
} else {
|
||||
// If the waiting list if full removes the oldest entry from the list
|
||||
if (pae_auth->waiting_supp_list_size >= WAITING_SUPPLICANT_LIST_MAX_SIZE) {
|
||||
supp_entry_t *delete_supp = ns_list_get_last(&pae_auth->waiting_supp_list);
|
||||
if (!delete_supp) {
|
||||
return NULL;
|
||||
}
|
||||
tr_info("PAE: waiting list full, eui-64: %s, deleted eui-64: %s", trace_array(addr->eui_64, 8), trace_array(delete_supp->addr.eui_64, 8));
|
||||
// Create new instance
|
||||
kmp_api_t *new_kmp = ws_pae_auth_kmp_create_and_start(pae_auth->kmp_service, MSG_PROT, pae_auth->relay_socked_msg_if_instance_id, delete_supp, pae_auth->sec_cfg);
|
||||
if (!new_kmp) {
|
||||
return NULL;
|
||||
}
|
||||
kmp_api_create_request(new_kmp, MSG_PROT, &delete_supp->addr, &delete_supp->sec_keys);
|
||||
(void) ws_pae_lib_supp_list_remove(pae_auth, &pae_auth->waiting_supp_list, delete_supp, ws_pae_auth_waiting_supp_deleted);
|
||||
ws_pae_auth_waiting_supp_remove_oldest(pae_auth, addr);
|
||||
}
|
||||
supp_entry = ws_pae_lib_supp_list_add(&pae_auth->waiting_supp_list, addr);
|
||||
if (!supp_entry) {
|
||||
|
|
|
@ -48,12 +48,13 @@
|
|||
* \param timer_settings timer settings
|
||||
* \param sec_cfg security configuration
|
||||
* \param sec_keys_nw_info security keys network information
|
||||
* \param frame_counters frame counters
|
||||
*
|
||||
* \return < 0 failure
|
||||
* \return >= 0 success
|
||||
*
|
||||
*/
|
||||
int8_t ws_pae_auth_init(protocol_interface_info_entry_t *interface_ptr, sec_prot_gtk_keys_t *next_gtks, const sec_prot_certs_t *certs, sec_cfg_t *sec_cfg, sec_prot_keys_nw_info_t *sec_keys_nw_info);
|
||||
int8_t ws_pae_auth_init(protocol_interface_info_entry_t *interface_ptr, sec_prot_gtk_keys_t *next_gtks, const sec_prot_certs_t *certs, sec_cfg_t *sec_cfg, sec_prot_keys_nw_info_t *sec_keys_nw_info, frame_counters_t *frame_counters);
|
||||
|
||||
/**
|
||||
* ws_pae_auth_addresses_set set relay addresses
|
||||
|
@ -260,6 +261,19 @@ typedef void ws_pae_auth_ip_addr_get(protocol_interface_info_entry_t *interface_
|
|||
*/
|
||||
typedef bool ws_pae_auth_congestion_get(protocol_interface_info_entry_t *interface_ptr, uint16_t active_supp);
|
||||
|
||||
/**
|
||||
* ws_pae_auth_nw_frame_counter_read network frame counter read callback
|
||||
*
|
||||
* \param interface_ptr interface
|
||||
* \param counter frame counter
|
||||
* \param gtk_index GTK index
|
||||
*
|
||||
* \return < 0 failure
|
||||
* \return >= 0 success
|
||||
*
|
||||
*/
|
||||
typedef int8_t ws_pae_auth_nw_frame_counter_read(protocol_interface_info_entry_t *interface_ptr, uint32_t *counter, uint8_t gtk_index);
|
||||
|
||||
/**
|
||||
* ws_pae_auth_cb_register register PAE authenticator callbacks
|
||||
*
|
||||
|
@ -270,17 +284,18 @@ typedef bool ws_pae_auth_congestion_get(protocol_interface_info_entry_t *interfa
|
|||
* \param nw_info_updated network keys updated callback
|
||||
* \param ip_addr_get IP addressing information callback
|
||||
* \param congestion_get congestion get callback
|
||||
* \param nw_frame_cnt_read network frame counter read callback
|
||||
*
|
||||
*/
|
||||
void ws_pae_auth_cb_register(protocol_interface_info_entry_t *interface_ptr, ws_pae_auth_gtk_hash_set *hash_set, ws_pae_auth_nw_key_insert *nw_key_insert, ws_pae_auth_nw_key_index_set *nw_key_index_set, ws_pae_auth_nw_info_updated *nw_info_updated, ws_pae_auth_ip_addr_get *ip_addr_get, ws_pae_auth_congestion_get *congestion_get);
|
||||
void ws_pae_auth_cb_register(protocol_interface_info_entry_t *interface_ptr, ws_pae_auth_gtk_hash_set *hash_set, ws_pae_auth_nw_key_insert *nw_key_insert, ws_pae_auth_nw_key_index_set *nw_key_index_set, ws_pae_auth_nw_info_updated *nw_info_updated, ws_pae_auth_ip_addr_get *ip_addr_get, ws_pae_auth_congestion_get *congestion_get, ws_pae_auth_nw_frame_counter_read *nw_frame_cnt_read);
|
||||
|
||||
#else
|
||||
|
||||
#define ws_pae_auth_init(interface_ptr, next_gtks, certs, sec_cfg, sec_keys_nw_info) 1
|
||||
#define ws_pae_auth_init(interface_ptr, next_gtks, certs, sec_cfg, sec_keys_nw_info, frame_counters) 1
|
||||
#define ws_pae_auth_timing_adjust(timing)
|
||||
#define ws_pae_auth_addresses_set(interface_ptr, local_port, remote_addr, remote_port) 1
|
||||
#define ws_pae_auth_delete NULL
|
||||
#define ws_pae_auth_cb_register(interface_ptr, hash_set, nw_key_insert, nw_key_index_set, nw_info_updated, ip_addr_get, congestion_get) {(void) hash_set;}
|
||||
#define ws_pae_auth_cb_register(interface_ptr, hash_set, nw_key_insert, nw_key_index_set, nw_info_updated, ip_addr_get, congestion_get, nw_frame_cnt_read) {(void) hash_set;}
|
||||
#define ws_pae_auth_start(interface_ptr)
|
||||
#define ws_pae_auth_gtks_updated NULL
|
||||
#define ws_pae_auth_nw_key_index_update NULL
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "ws_management_api.h"
|
||||
#include "ws_bbr_api.h"
|
||||
#include "Service_Libs/utils/ns_file.h"
|
||||
#include "Service_Libs/utils/ns_time.h"
|
||||
#include "NWK_INTERFACE/Include/protocol.h"
|
||||
#include "6LoWPAN/ws/ws_config.h"
|
||||
#include "6LoWPAN/ws/ws_cfg_settings.h"
|
||||
|
@ -51,7 +52,7 @@ typedef void ws_pae_timer(uint16_t ticks);
|
|||
typedef int8_t ws_pae_br_addr_write(protocol_interface_info_entry_t *interface_ptr, const uint8_t *eui_64);
|
||||
typedef int8_t ws_pae_br_addr_read(protocol_interface_info_entry_t *interface_ptr, uint8_t *eui_64);
|
||||
typedef void ws_pae_gtks_updated(protocol_interface_info_entry_t *interface_ptr);
|
||||
typedef int8_t ws_pae_gtk_hash_update(protocol_interface_info_entry_t *interface_ptr, uint8_t *gtkhash);
|
||||
typedef int8_t ws_pae_gtk_hash_update(protocol_interface_info_entry_t *interface_ptr, uint8_t *gtkhash, bool del_gtk_on_mismatch);
|
||||
typedef int8_t ws_pae_nw_key_index_update(protocol_interface_info_entry_t *interface_ptr, uint8_t index);
|
||||
typedef int8_t ws_pae_nw_info_set(protocol_interface_info_entry_t *interface_ptr, uint16_t pan_id, char *network_name, bool updated);
|
||||
|
||||
|
@ -119,6 +120,7 @@ static void ws_pae_controller_nw_info_updated_check(protocol_interface_info_entr
|
|||
#ifdef HAVE_PAE_AUTH
|
||||
static void ws_pae_controller_auth_ip_addr_get(protocol_interface_info_entry_t *interface_ptr, uint8_t *address);
|
||||
static bool ws_pae_controller_auth_congestion_get(protocol_interface_info_entry_t *interface_ptr, uint16_t active_supp);
|
||||
static int8_t ws_pae_controller_auth_nw_frame_counter_read(protocol_interface_info_entry_t *interface_ptr, uint32_t *counter, uint8_t gtk_index);
|
||||
#endif
|
||||
static pae_controller_t *ws_pae_controller_get(protocol_interface_info_entry_t *interface_ptr);
|
||||
static void ws_pae_controller_frame_counter_timer(uint16_t seconds, pae_controller_t *entry);
|
||||
|
@ -140,8 +142,8 @@ static int8_t ws_pae_controller_frame_counter_read(pae_controller_t *controller)
|
|||
static void ws_pae_controller_frame_counter_reset(frame_counters_t *frame_counters);
|
||||
static void ws_pae_controller_frame_counter_index_reset(frame_counters_t *frame_counters, uint8_t index);
|
||||
static int8_t ws_pae_controller_nw_info_read(pae_controller_t *controller, sec_prot_gtk_keys_t *gtks);
|
||||
static int8_t ws_pae_controller_nvm_nw_info_write(protocol_interface_info_entry_t *interface_ptr, uint16_t pan_id, char *network_name, uint8_t *gtk_eui64, sec_prot_gtk_keys_t *gtks);
|
||||
static int8_t ws_pae_controller_nvm_nw_info_read(protocol_interface_info_entry_t *interface_ptr, uint16_t *pan_id, char *network_name, uint8_t *gtk_eui64, sec_prot_gtk_keys_t *gtks);
|
||||
static int8_t ws_pae_controller_nvm_nw_info_write(protocol_interface_info_entry_t *interface_ptr, uint16_t pan_id, char *network_name, uint8_t *gtk_eui64, sec_prot_gtk_keys_t *gtks, uint64_t stored_time, uint8_t time_changed);
|
||||
static int8_t ws_pae_controller_nvm_nw_info_read(protocol_interface_info_entry_t *interface_ptr, uint16_t *pan_id, char *network_name, uint8_t *gtk_eui64, sec_prot_gtk_keys_t *gtks, uint64_t current_time, uint8_t *time_changed);
|
||||
|
||||
|
||||
static const char *FRAME_COUNTER_FILE = FRAME_COUNTER_FILE_NAME;
|
||||
|
@ -196,7 +198,7 @@ int8_t ws_pae_controller_bootstrap_done(protocol_interface_info_entry_t *interfa
|
|||
|
||||
/* Trigger GTK hash update to supplicant, so it can check whether keys have been updated
|
||||
during bootstrap. Does nothing if GTKs are up to date. */
|
||||
ws_pae_supp_gtk_hash_update(interface_ptr, controller->gtkhash);
|
||||
ws_pae_supp_gtk_hash_update(interface_ptr, controller->gtkhash, false);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
@ -239,7 +241,7 @@ int8_t ws_pae_controller_authenticator_start(protocol_interface_info_entry_t *in
|
|||
ws_pae_auth_node_limit_set(controller->interface_ptr, pae_controller_config.node_limit);
|
||||
}
|
||||
|
||||
ws_pae_auth_cb_register(interface_ptr, ws_pae_controller_gtk_hash_set, ws_pae_controller_nw_key_check_and_insert, ws_pae_controller_nw_key_index_check_and_set, ws_pae_controller_nw_info_updated_check, ws_pae_controller_auth_ip_addr_get, ws_pae_controller_auth_congestion_get);
|
||||
ws_pae_auth_cb_register(interface_ptr, ws_pae_controller_gtk_hash_set, ws_pae_controller_nw_key_check_and_insert, ws_pae_controller_nw_key_index_check_and_set, ws_pae_controller_nw_info_updated_check, ws_pae_controller_auth_ip_addr_get, ws_pae_controller_auth_congestion_get, ws_pae_controller_auth_nw_frame_counter_read);
|
||||
|
||||
controller->auth_started = true;
|
||||
|
||||
|
@ -376,7 +378,8 @@ static void ws_pae_controller_nw_info_updated_check(protocol_interface_info_entr
|
|||
if (arm_nwk_mac_address_read(interface_ptr->id, &mac_params) >= 0) {
|
||||
memcpy(gtk_eui64, mac_params.mac_long, 8);
|
||||
}
|
||||
ws_pae_controller_nvm_nw_info_write(interface_ptr, controller->sec_keys_nw_info.key_pan_id, controller->sec_keys_nw_info.network_name, gtk_eui64, controller->sec_keys_nw_info.gtks);
|
||||
uint64_t system_time = ws_pae_current_time_get();
|
||||
ws_pae_controller_nvm_nw_info_write(interface_ptr, controller->sec_keys_nw_info.key_pan_id, controller->sec_keys_nw_info.network_name, gtk_eui64, controller->sec_keys_nw_info.gtks, system_time, controller->sec_keys_nw_info.system_time_changed);
|
||||
controller->sec_keys_nw_info.updated = false;
|
||||
sec_prot_keys_gtks_updated_reset(controller->sec_keys_nw_info.gtks);
|
||||
}
|
||||
|
@ -410,6 +413,21 @@ static bool ws_pae_controller_auth_congestion_get(protocol_interface_info_entry_
|
|||
|
||||
return controller->congestion_get(interface_ptr, active_supp);
|
||||
}
|
||||
|
||||
static int8_t ws_pae_controller_auth_nw_frame_counter_read(protocol_interface_info_entry_t *interface_ptr, uint32_t *counter, uint8_t gtk_index)
|
||||
{
|
||||
if (!interface_ptr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
pae_controller_t *controller = ws_pae_controller_get(interface_ptr);
|
||||
if (!controller) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
controller->nw_frame_counter_read(interface_ptr, counter, gtk_index);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int8_t ws_pae_controller_nw_key_valid(protocol_interface_info_entry_t *interface_ptr, uint8_t *br_iid)
|
||||
|
@ -546,19 +564,31 @@ static int8_t ws_pae_controller_gak_from_gtk(uint8_t *gak, uint8_t *gtk, char *n
|
|||
|
||||
mbedtls_sha256_init(&ctx);
|
||||
|
||||
#if (MBEDTLS_VERSION_MAJOR >= 3)
|
||||
if (mbedtls_sha256_starts(&ctx, 0) != 0) {
|
||||
#else
|
||||
if (mbedtls_sha256_starts_ret(&ctx, 0) != 0) {
|
||||
#endif
|
||||
ret_val = -1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
#if (MBEDTLS_VERSION_MAJOR >= 3)
|
||||
if (mbedtls_sha256_update(&ctx, input, network_name_len + GTK_LEN) != 0) {
|
||||
#else
|
||||
if (mbedtls_sha256_update_ret(&ctx, input, network_name_len + GTK_LEN) != 0) {
|
||||
#endif
|
||||
ret_val = -1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
uint8_t output[32];
|
||||
|
||||
#if (MBEDTLS_VERSION_MAJOR >= 3)
|
||||
if (mbedtls_sha256_finish(&ctx, output) != 0) {
|
||||
#else
|
||||
if (mbedtls_sha256_finish_ret(&ctx, output) != 0) {
|
||||
#endif
|
||||
ret_val = -1;
|
||||
goto error;
|
||||
}
|
||||
|
@ -792,8 +822,8 @@ static int8_t ws_pae_controller_frame_counter_read(pae_controller_t *controller)
|
|||
|
||||
// Read frame counters
|
||||
if (ws_pae_controller_nvm_frame_counter_read(&controller->restart_cnt, &stored_time, &controller->sec_keys_nw_info.pan_version, &controller->frame_counters) >= 0) {
|
||||
// Current time is not valid
|
||||
if (ws_pae_current_time_set(stored_time) < 0) {
|
||||
// Check if stored time is not valid
|
||||
if (ws_pae_stored_time_check_and_set(stored_time) < 0) {
|
||||
ret_value = -1;
|
||||
}
|
||||
// This is used to ensure that PMK replay counters are fresh after each re-start.
|
||||
|
@ -837,16 +867,23 @@ static void ws_pae_controller_frame_counter_index_reset(frame_counters_t *frame_
|
|||
memset(frame_counters->counter[index].gtk, 0, GTK_LEN);
|
||||
frame_counters->counter[index].frame_counter = 0;
|
||||
frame_counters->counter[index].stored_frame_counter = 0;
|
||||
frame_counters->counter[index].max_frame_counter_chg = 0;
|
||||
frame_counters->counter[index].set = false;
|
||||
}
|
||||
|
||||
static int8_t ws_pae_controller_nw_info_read(pae_controller_t *controller, sec_prot_gtk_keys_t *gtks)
|
||||
{
|
||||
uint8_t nvm_gtk_eui64[8];
|
||||
if (ws_pae_controller_nvm_nw_info_read(controller->interface_ptr, &controller->sec_keys_nw_info.key_pan_id, controller->sec_keys_nw_info.network_name, nvm_gtk_eui64, gtks) < 0) {
|
||||
uint64_t system_time = ws_pae_current_time_get();
|
||||
|
||||
uint8_t system_time_changed = controller->sec_keys_nw_info.system_time_changed;
|
||||
if (ws_pae_controller_nvm_nw_info_read(controller->interface_ptr, &controller->sec_keys_nw_info.key_pan_id, controller->sec_keys_nw_info.network_name, nvm_gtk_eui64, gtks, system_time, &controller->sec_keys_nw_info.system_time_changed) < 0) {
|
||||
// If no stored GTKs and network info (pan_id and network name) exits
|
||||
return -1;
|
||||
}
|
||||
if (system_time_changed != controller->sec_keys_nw_info.system_time_changed) {
|
||||
controller->sec_keys_nw_info.updated = true;
|
||||
}
|
||||
|
||||
/* Get own EUI-64 and compare to the one read from the NVM. In case of mismatch delete GTKs and make
|
||||
full authentication to update keys with new EUI-64 and in case of authenticator to update new
|
||||
|
@ -867,21 +904,21 @@ static int8_t ws_pae_controller_nw_info_read(pae_controller_t *controller, sec_p
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int8_t ws_pae_controller_nvm_nw_info_write(protocol_interface_info_entry_t *interface_ptr, uint16_t pan_id, char *network_name, uint8_t *gtk_eui64, sec_prot_gtk_keys_t *gtks)
|
||||
static int8_t ws_pae_controller_nvm_nw_info_write(protocol_interface_info_entry_t *interface_ptr, uint16_t pan_id, char *network_name, uint8_t *gtk_eui64, sec_prot_gtk_keys_t *gtks, uint64_t stored_time, uint8_t time_changed)
|
||||
{
|
||||
nw_info_nvm_tlv_t *tlv = (nw_info_nvm_tlv_t *) ws_pae_controller_nvm_tlv_get(interface_ptr);
|
||||
if (!tlv) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ws_pae_nvm_store_nw_info_tlv_create(tlv, pan_id, network_name, gtk_eui64, gtks);
|
||||
ws_pae_nvm_store_nw_info_tlv_create(tlv, pan_id, network_name, gtk_eui64, gtks, stored_time, time_changed);
|
||||
|
||||
ws_pae_nvm_store_tlv_file_write(NW_INFO_FILE, (nvm_tlv_t *) tlv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int8_t ws_pae_controller_nvm_nw_info_read(protocol_interface_info_entry_t *interface_ptr, uint16_t *pan_id, char *network_name, uint8_t *gtk_eui64, sec_prot_gtk_keys_t *gtks)
|
||||
static int8_t ws_pae_controller_nvm_nw_info_read(protocol_interface_info_entry_t *interface_ptr, uint16_t *pan_id, char *network_name, uint8_t *gtk_eui64, sec_prot_gtk_keys_t *gtks, uint64_t current_time, uint8_t *time_changed)
|
||||
{
|
||||
nw_info_nvm_tlv_t *tlv_entry = (nw_info_nvm_tlv_t *) ws_pae_controller_nvm_tlv_get(interface_ptr);
|
||||
if (!tlv_entry) {
|
||||
|
@ -894,7 +931,7 @@ static int8_t ws_pae_controller_nvm_nw_info_read(protocol_interface_info_entry_t
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (ws_pae_nvm_store_nw_info_tlv_read(tlv_entry, pan_id, network_name, gtk_eui64, gtks) < 0) {
|
||||
if (ws_pae_nvm_store_nw_info_tlv_read(tlv_entry, pan_id, network_name, gtk_eui64, gtks, current_time, time_changed) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -939,10 +976,13 @@ int8_t ws_pae_controller_auth_init(protocol_interface_info_entry_t *interface_pt
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (ws_pae_auth_init(controller->interface_ptr, &controller->next_gtks, &controller->certs, &controller->sec_cfg, &controller->sec_keys_nw_info) < 0) {
|
||||
if (ws_pae_auth_init(controller->interface_ptr, &controller->next_gtks, &controller->certs, &controller->sec_cfg, &controller->sec_keys_nw_info, &controller->frame_counters) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// For Border Router enable the time acquired as default
|
||||
ns_time_system_time_acquired_set();
|
||||
|
||||
controller->pae_delete = ws_pae_auth_delete;
|
||||
controller->pae_fast_timer = ws_pae_auth_fast_timer;
|
||||
controller->pae_slow_timer = ws_pae_auth_slow_timer;
|
||||
|
@ -967,21 +1007,21 @@ int8_t ws_pae_controller_auth_init(protocol_interface_info_entry_t *interface_pt
|
|||
sec_prot_keys_gtks_updated_reset(&controller->gtks);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ws_pae_controller_nw_info_read(controller, read_gtks_to) >= 0) {
|
||||
if (read_gtks_to && ws_pae_controller_nw_info_read(controller, read_gtks_to) >= 0) {
|
||||
/* If network information i.e pan_id and network name exists updates bootstrap with it,
|
||||
(in case already configured by application then no changes are made) */
|
||||
if (controller->nw_info_updated) {
|
||||
controller->nw_info_updated(interface_ptr, controller->sec_keys_nw_info.key_pan_id, controller->sec_keys_nw_info.pan_version, controller->sec_keys_nw_info.network_name);
|
||||
}
|
||||
if (!read_gtks_to || sec_prot_keys_gtk_count(read_gtks_to) == 0) {
|
||||
if (sec_prot_keys_gtk_count(read_gtks_to) == 0) {
|
||||
// Key material invalid or GTKs are expired, delete GTKs from NVM
|
||||
uint8_t gtk_eui64[8] = {0}; // Set GTK EUI-64 to zero
|
||||
ws_pae_controller_nvm_nw_info_write(controller->interface_ptr, controller->sec_keys_nw_info.key_pan_id, controller->sec_keys_nw_info.network_name, gtk_eui64, NULL);
|
||||
uint64_t system_time = ws_pae_current_time_get();
|
||||
ws_pae_controller_nvm_nw_info_write(controller->interface_ptr, controller->sec_keys_nw_info.key_pan_id, controller->sec_keys_nw_info.network_name, gtk_eui64, NULL, system_time, controller->sec_keys_nw_info.system_time_changed);
|
||||
}
|
||||
}
|
||||
|
||||
ws_pae_key_storage_init();
|
||||
|
||||
if (read_gtks_to) {
|
||||
ws_pae_key_storage_read(controller->restart_cnt);
|
||||
} else {
|
||||
|
@ -1662,7 +1702,7 @@ int8_t ws_pae_controller_gtk_hash_update(protocol_interface_info_entry_t *interf
|
|||
memcpy(controller->gtkhash, gtkhash, 32);
|
||||
|
||||
if (controller->pae_gtk_hash_update) {
|
||||
return controller->pae_gtk_hash_update(interface_ptr, controller->gtkhash);
|
||||
return controller->pae_gtk_hash_update(interface_ptr, controller->gtkhash, true);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -1731,9 +1771,12 @@ static void ws_pae_controller_frame_counter_store(pae_controller_t *entry, bool
|
|||
}
|
||||
uint32_t frame_counter = entry->frame_counters.counter[i].frame_counter;
|
||||
|
||||
// If threshold check is disabled or frame counter has advanced for the threshold value, stores the new value
|
||||
if (!use_threshold ||
|
||||
frame_counter > entry->frame_counters.counter[i].stored_frame_counter + FRAME_COUNTER_STORE_THRESHOLD) {
|
||||
/* If threshold check is disabled or frame counter has advanced for the threshold value, stores the new value.
|
||||
If frame counter is at maximum at storage, do not initiate storing */
|
||||
if (!use_threshold || (
|
||||
(frame_counter > entry->frame_counters.counter[i].stored_frame_counter + FRAME_COUNTER_STORE_THRESHOLD) &&
|
||||
!(entry->frame_counters.counter[i].stored_frame_counter == UINT32_MAX &&
|
||||
frame_counter >= UINT32_MAX - FRAME_COUNTER_STORE_THRESHOLD))) {
|
||||
entry->frame_counters.counter[i].stored_frame_counter = frame_counter;
|
||||
update_needed = true;
|
||||
tr_debug("Stored updated frame counter: index %i value %"PRIu32"", i, frame_counter);
|
||||
|
@ -1761,8 +1804,9 @@ static void ws_pae_controller_frame_counter_store(pae_controller_t *entry, bool
|
|||
|
||||
if (update_needed || entry->frame_cnt_store_force_timer == 0) {
|
||||
tr_debug("Write frame counters: system time %"PRIu32"", protocol_core_monotonic_time / 10);
|
||||
uint64_t system_time = ws_pae_current_time_get();
|
||||
// Writes modified frame counters
|
||||
ws_pae_nvm_store_frame_counter_tlv_create((frame_cnt_nvm_tlv_t *) &entry->pae_nvm_buffer, entry->restart_cnt, entry->sec_keys_nw_info.pan_version, &entry->frame_counters);
|
||||
ws_pae_nvm_store_frame_counter_tlv_create((frame_cnt_nvm_tlv_t *) &entry->pae_nvm_buffer, entry->restart_cnt, entry->sec_keys_nw_info.pan_version, &entry->frame_counters, system_time);
|
||||
ws_pae_controller_nvm_frame_counter_write((frame_cnt_nvm_tlv_t *) &entry->pae_nvm_buffer);
|
||||
|
||||
// Reset force interval when ever values are stored
|
||||
|
|
|
@ -944,7 +944,7 @@ static int8_t ws_pae_key_storage_array_time_update_entry(uint64_t time_differenc
|
|||
#endif
|
||||
}
|
||||
|
||||
if (storage_array_entry->pmk_lifetime_set) {
|
||||
if (storage_array_entry->ptk_lifetime_set) {
|
||||
#ifdef EXTRA_DEBUG_INFO
|
||||
tr_debug("KeyS time update diff: %"PRIi64" PTK OLD t: %i %i eui64: %s", time_difference, STIME_TIME_GET(storage_array_entry->ptk_lifetime), STIME_FORMAT_GET(storage_array_entry->ptk_lifetime), tr_array(storage_array_entry->ptk_eui_64, 8));
|
||||
#endif
|
||||
|
|
|
@ -40,34 +40,7 @@
|
|||
#define PAE_NVM_FIELD_NOT_SET 0 // Field is not present
|
||||
#define PAE_NVM_FIELD_SET 1 // Field is present
|
||||
|
||||
void ws_pae_nvm_store_generic_tlv_create(nvm_tlv_t *tlv_entry, uint16_t tag, uint16_t length)
|
||||
{
|
||||
tlv_entry->tag = tag;
|
||||
tlv_entry->len = length;
|
||||
}
|
||||
|
||||
nvm_tlv_t *ws_pae_nvm_store_generic_tlv_allocate_and_create(uint16_t tag, uint16_t length)
|
||||
{
|
||||
nvm_tlv_t *tlv_entry = ns_dyn_mem_alloc(length + sizeof(nvm_tlv_t));
|
||||
if (!tlv_entry) {
|
||||
return NULL;
|
||||
}
|
||||
tlv_entry->tag = tag;
|
||||
tlv_entry->len = length;
|
||||
|
||||
return tlv_entry;
|
||||
}
|
||||
|
||||
void ws_pae_nvm_store_generic_tlv_free(nvm_tlv_t *tlv_entry)
|
||||
{
|
||||
if (!tlv_entry) {
|
||||
return;
|
||||
}
|
||||
|
||||
ns_dyn_mem_free(tlv_entry);
|
||||
}
|
||||
|
||||
void ws_pae_nvm_store_nw_info_tlv_create(nw_info_nvm_tlv_t *tlv_entry, uint16_t pan_id, char *nw_name, uint8_t *gtk_eui64, sec_prot_gtk_keys_t *gtks)
|
||||
void ws_pae_nvm_store_nw_info_tlv_create(nw_info_nvm_tlv_t *tlv_entry, uint16_t pan_id, char *nw_name, uint8_t *gtk_eui64, sec_prot_gtk_keys_t *gtks, uint64_t stored_time, uint8_t time_changed)
|
||||
{
|
||||
int len;
|
||||
tlv_entry->tag = PAE_NVM_NW_INFO_TAG;
|
||||
|
@ -90,13 +63,14 @@ void ws_pae_nvm_store_nw_info_tlv_create(nw_info_nvm_tlv_t *tlv_entry, uint16_t
|
|||
memcpy((char *)tlv, gtk_eui64, 8);
|
||||
tlv += 8;
|
||||
|
||||
uint64_t current_time = ws_pae_current_time_get();
|
||||
*tlv++ = time_changed;
|
||||
tlv = common_write_64_bit(stored_time, tlv);
|
||||
|
||||
for (uint8_t i = 0; i < GTK_NUM; i++) {
|
||||
if (gtks && sec_prot_keys_gtk_is_set(gtks, i)) {
|
||||
*tlv++ = PAE_NVM_FIELD_SET; // GTK is set
|
||||
|
||||
uint64_t expirytime = sec_prot_keys_gtk_exptime_from_lifetime_get(gtks, i, current_time);
|
||||
uint64_t expirytime = sec_prot_keys_gtk_exptime_from_lifetime_get(gtks, i, stored_time);
|
||||
// Sets stored expiration time to GTKs; no need to update anymore to NVM if not changed
|
||||
sec_prot_keys_gtk_expirytime_set(gtks, i, expirytime);
|
||||
|
||||
|
@ -118,11 +92,11 @@ void ws_pae_nvm_store_nw_info_tlv_create(nw_info_nvm_tlv_t *tlv_entry, uint16_t
|
|||
}
|
||||
}
|
||||
|
||||
tr_debug("NVM NW_INFO write PAN ID %i name: %s", pan_id, nw_name);
|
||||
tr_info("NVM NW_INFO write PAN ID: %i name: %s stored time: %"PRIu64, pan_id, nw_name, stored_time);
|
||||
|
||||
}
|
||||
|
||||
int8_t ws_pae_nvm_store_nw_info_tlv_read(nw_info_nvm_tlv_t *tlv_entry, uint16_t *pan_id, char *nw_name, uint8_t *gtk_eui64, sec_prot_gtk_keys_t *gtks)
|
||||
int8_t ws_pae_nvm_store_nw_info_tlv_read(nw_info_nvm_tlv_t *tlv_entry, uint16_t *pan_id, char *nw_name, uint8_t *gtk_eui64, sec_prot_gtk_keys_t *gtks, uint64_t current_time, uint8_t *time_changed)
|
||||
{
|
||||
if (!tlv_entry || !pan_id || !nw_name) {
|
||||
return -1;
|
||||
|
@ -150,9 +124,20 @@ int8_t ws_pae_nvm_store_nw_info_tlv_read(nw_info_nvm_tlv_t *tlv_entry, uint16_t
|
|||
memcpy(gtk_eui64, (char *)tlv, 8);
|
||||
tlv += 8;
|
||||
|
||||
uint64_t current_time = ws_pae_current_time_get();
|
||||
*time_changed = *tlv++;
|
||||
uint64_t stored_time = common_read_64_bit(tlv);
|
||||
tlv += 8;
|
||||
// Use either stored time or current time as reference when calculating lifetimes
|
||||
current_time = ws_pae_time_old_or_new_select(stored_time, current_time);
|
||||
/* If the selected time has made a large jump then use the stored time to calculate the lifetime
|
||||
(this implies e.g. that new time has been received from NTP and old time was not valid) */
|
||||
if (*time_changed == SYSTEM_TIME_NOT_CHANGED && !ws_pae_time_old_and_new_validate(stored_time, current_time)) {
|
||||
*time_changed = SYSTEM_TIME_CHANGED;
|
||||
current_time = stored_time;
|
||||
tr_info("NVM NW_INFO system time change");
|
||||
}
|
||||
|
||||
tr_debug("NVM NW_INFO current time: %"PRIi64, current_time);
|
||||
tr_info("NVM NW_INFO current time: %"PRIi64" stored time: %"PRIi64, current_time, stored_time);
|
||||
|
||||
if (gtks && sec_prot_keys_gtk_count(gtks) == 0) {
|
||||
// If application has not set GTKs read them from NVM
|
||||
|
@ -160,9 +145,10 @@ int8_t ws_pae_nvm_store_nw_info_tlv_read(nw_info_nvm_tlv_t *tlv_entry, uint16_t
|
|||
if (*tlv++ == PAE_NVM_FIELD_SET) { /* GTK is set */
|
||||
uint64_t expirytime = common_read_64_bit(tlv);
|
||||
uint32_t lifetime = 0;
|
||||
// Calculate lifetime
|
||||
if (ws_pae_time_diff_calc(current_time, expirytime, &lifetime, true) < 0) {
|
||||
tlv += 8 + 1 + 1 + GTK_LEN;
|
||||
tr_debug("GTK index %i, expired expiry time: %"PRIi64", lifetime: %"PRIi32, i, expirytime, lifetime);
|
||||
tr_info("GTK index %i, expired expiry time: %"PRIi64", lifetime: %"PRIi32, i, expirytime, lifetime);
|
||||
continue;
|
||||
}
|
||||
tlv += 8;
|
||||
|
@ -171,7 +157,7 @@ int8_t ws_pae_nvm_store_nw_info_tlv_read(nw_info_nvm_tlv_t *tlv_entry, uint16_t
|
|||
|
||||
uint8_t install_order = *tlv++;
|
||||
|
||||
tr_debug("GTK index: %i, status: %i, install order %i, expiry time: %"PRIi64", lifetime: %"PRIi32, i, status, install_order, expirytime, lifetime);
|
||||
tr_info("GTK index: %i, status: %i, install order %i, expiry time: %"PRIi64", lifetime: %"PRIi32, i, status, install_order, expirytime, lifetime);
|
||||
|
||||
sec_prot_keys_gtk_set(gtks, i, tlv, lifetime);
|
||||
sec_prot_keys_gtk_expirytime_set(gtks, i, expirytime);
|
||||
|
@ -185,7 +171,7 @@ int8_t ws_pae_nvm_store_nw_info_tlv_read(nw_info_nvm_tlv_t *tlv_entry, uint16_t
|
|||
sec_prot_keys_gtks_updated_reset(gtks);
|
||||
}
|
||||
|
||||
tr_debug("NVM NW_INFO read PAN ID %i name: %s", *pan_id, nw_name);
|
||||
tr_info("NVM NW_INFO read PAN ID %i name: %s", *pan_id, nw_name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -234,7 +220,7 @@ void ws_pae_nvm_store_keys_tlv_create(keys_nvm_tlv_t *tlv_entry, sec_prot_keys_t
|
|||
}
|
||||
tlv += PTK_LEN;
|
||||
|
||||
tr_debug("NVM KEYS write");
|
||||
tr_info("NVM KEYS write");
|
||||
}
|
||||
|
||||
int8_t ws_pae_nvm_store_keys_tlv_read(keys_nvm_tlv_t *tlv_entry, sec_prot_keys_t *sec_keys)
|
||||
|
@ -282,12 +268,12 @@ int8_t ws_pae_nvm_store_keys_tlv_read(keys_nvm_tlv_t *tlv_entry, sec_prot_keys_t
|
|||
|
||||
sec_prot_keys_updated_reset(sec_keys);
|
||||
|
||||
tr_debug("NVM KEYS read");
|
||||
tr_info("NVM KEYS read");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ws_pae_nvm_store_frame_counter_tlv_create(frame_cnt_nvm_tlv_t *tlv_entry, uint32_t restart_cnt, uint16_t pan_version, frame_counters_t *counters)
|
||||
void ws_pae_nvm_store_frame_counter_tlv_create(frame_cnt_nvm_tlv_t *tlv_entry, uint32_t restart_cnt, uint16_t pan_version, frame_counters_t *counters, uint64_t stored_time)
|
||||
{
|
||||
tlv_entry->tag = PAE_NVM_FRAME_COUNTER_TAG;
|
||||
tlv_entry->len = PAE_NVM_FRAME_COUNTER_LEN;
|
||||
|
@ -296,7 +282,6 @@ void ws_pae_nvm_store_frame_counter_tlv_create(frame_cnt_nvm_tlv_t *tlv_entry, u
|
|||
|
||||
tlv = common_write_32_bit(restart_cnt, tlv);
|
||||
|
||||
uint64_t stored_time = ws_pae_current_time_get();
|
||||
tlv = common_write_64_bit(stored_time, tlv);
|
||||
|
||||
tlv = common_write_16_bit(pan_version, tlv);
|
||||
|
@ -304,17 +289,18 @@ void ws_pae_nvm_store_frame_counter_tlv_create(frame_cnt_nvm_tlv_t *tlv_entry, u
|
|||
for (uint8_t index = 0; index < GTK_NUM; index++) {
|
||||
if (!counters->counter[index].set) {
|
||||
*tlv++ = PAE_NVM_FIELD_NOT_SET;
|
||||
memset(tlv, 0, GTK_LEN + 4);
|
||||
tlv += GTK_LEN + 4;
|
||||
memset(tlv, 0, GTK_LEN + 4 + 4);
|
||||
tlv += GTK_LEN + 4 + 4;
|
||||
continue;
|
||||
}
|
||||
*tlv++ = PAE_NVM_FIELD_SET;
|
||||
memcpy(tlv, counters->counter[index].gtk, GTK_LEN);
|
||||
tlv += GTK_LEN;
|
||||
tlv = common_write_32_bit(counters->counter[index].frame_counter, tlv);
|
||||
tlv = common_write_32_bit(counters->counter[index].max_frame_counter_chg, tlv);
|
||||
}
|
||||
|
||||
tr_debug("NVM FRAME COUNTER write");
|
||||
tr_info("NVM FRAME COUNTER write; stored time: %"PRIu64, stored_time);
|
||||
}
|
||||
|
||||
int8_t ws_pae_nvm_store_frame_counter_tlv_read(frame_cnt_nvm_tlv_t *tlv_entry, uint32_t *restart_cnt, uint64_t *stored_time, uint16_t *pan_version, frame_counters_t *counters)
|
||||
|
@ -342,7 +328,7 @@ int8_t ws_pae_nvm_store_frame_counter_tlv_read(frame_cnt_nvm_tlv_t *tlv_entry, u
|
|||
// Frame counter not set
|
||||
if (*tlv++ == PAE_NVM_FIELD_NOT_SET) {
|
||||
counters->counter[index].set = false;
|
||||
tlv += GTK_LEN + 4;
|
||||
tlv += GTK_LEN + 4 + 4;
|
||||
continue;
|
||||
}
|
||||
// Frame counter is set, read GTK key and counter values
|
||||
|
@ -351,9 +337,11 @@ int8_t ws_pae_nvm_store_frame_counter_tlv_read(frame_cnt_nvm_tlv_t *tlv_entry, u
|
|||
tlv += GTK_LEN;
|
||||
counters->counter[index].frame_counter = common_read_32_bit(tlv);
|
||||
tlv += 4;
|
||||
counters->counter[index].max_frame_counter_chg = common_read_32_bit(tlv);
|
||||
tlv += 4;
|
||||
}
|
||||
|
||||
tr_debug("NVM FRAME COUNTER read");
|
||||
tr_info("NVM FRAME COUNTER read; stored time: %"PRIu64, *stored_time);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -367,7 +355,7 @@ void ws_pae_nvm_store_key_storage_index_tlv_create(nvm_tlv_t *tlv_entry, uint64_
|
|||
|
||||
tlv = common_write_64_bit(bitfield, tlv);
|
||||
|
||||
tr_debug("NVM KEY STORAGE INDEX write");
|
||||
tr_info("NVM KEY STORAGE INDEX write");
|
||||
}
|
||||
|
||||
int8_t ws_pae_nvm_store_key_storage_index_tlv_read(nvm_tlv_t *tlv_entry, uint64_t *bitfield)
|
||||
|
@ -384,7 +372,7 @@ int8_t ws_pae_nvm_store_key_storage_index_tlv_read(nvm_tlv_t *tlv_entry, uint64_
|
|||
*bitfield = common_read_64_bit(tlv);
|
||||
tlv += 8;
|
||||
|
||||
tr_debug("NVM KEY STORAGE INDEX read");
|
||||
tr_info("NVM KEY STORAGE INDEX read");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -35,16 +35,24 @@
|
|||
#define PAE_NVM_KEY_STORAGE_INDEX_TAG 4
|
||||
#define PAE_NVM_KEY_STORAGE_TAG 5
|
||||
|
||||
// pan_id (2) + network name (33) + GTK EUI-64 (own EUI-64) (8) + (GTK set (1) + GTK expiry timestamp (8) + status (1) + install order (1) + GTK (16)) * 4
|
||||
#define PAE_NVM_NW_INFO_LEN 2 + 33 + 8 + (1 + 8 + 1 + 1 + GTK_LEN) * GTK_NUM
|
||||
// pan_id (2) + network name (33) + GTK EUI-64 (own EUI-64) (8) + stored time (8) + time changed (1) + (GTK set (1) + GTK expiry timestamp (8) + status (1) + install order (1) + GTK (16)) * 4
|
||||
#define PAE_NVM_NW_INFO_LEN 2 + 33 + 8 + 8 + 1 + (1 + 8 + 1 + 1 + GTK_LEN) * GTK_NUM
|
||||
|
||||
// PTK EUI-64 set (1) + PTK EUI-64 (8) + PMK set (1) + PMK lifetime (4) + PMK (32) + PMK replay counter (8) + PTK set (1) + PTK lifetime (4) + PTK (48)
|
||||
#define PAE_NVM_KEYS_LEN 1 + 8 + 1 + 4 + PMK_LEN + 8 + 1 + 4 + PTK_LEN
|
||||
|
||||
// restart counter + stored time + pan version + (frame counter set (1) + GTK (16) + frame counter (4)) * 4
|
||||
#define PAE_NVM_FRAME_COUNTER_LEN 4 + 8 + 2 + (1 + GTK_LEN + 4) * GTK_NUM
|
||||
// restart counter + stored time + pan version + (frame counter set (1) + GTK (16) + frame counter (4) + max frame counter change (4)) * 4
|
||||
#define PAE_NVM_FRAME_COUNTER_LEN 4 + 8 + 2 + (1 + GTK_LEN + 4 + 4) * GTK_NUM
|
||||
|
||||
#define PAE_NVM_DEFAULT_BUFFER_SIZE sizeof(nvm_tlv_t) + PAE_NVM_NW_INFO_LEN
|
||||
#if (PAE_NVM_NW_INFO_LEN >= PAE_NVM_KEYS_LEN) && (PAE_NVM_NW_INFO_LEN >= PAE_NVM_FRAME_COUNTER_LEN)
|
||||
#define PAE_NVM_LARGEST_FILE PAE_NVM_NW_INFO_LEN
|
||||
#elif (PAE_NVM_KEYS_LEN >= PAE_NVM_NW_INFO_LEN) && (PAE_NVM_KEYS_LEN >= PAE_NVM_FRAME_COUNTER_LEN)
|
||||
#define PAE_NVM_LARGEST_FILE PAE_NVM_KEYS_LEN
|
||||
#else
|
||||
#define PAE_NVM_LARGEST_FILE PAE_NVM_FRAME_COUNTER_LEN
|
||||
#endif
|
||||
|
||||
#define PAE_NVM_DEFAULT_BUFFER_SIZE sizeof(nvm_tlv_t) + PAE_NVM_LARGEST_FILE
|
||||
|
||||
// key storage index bitfield (8)
|
||||
#define PAE_NVM_KEY_STORAGE_INDEX_LEN 8
|
||||
|
@ -91,11 +99,13 @@ void ws_pae_nvm_store_generic_tlv_free(nvm_tlv_t *tlv_entry);
|
|||
* \param pan_id PAN ID
|
||||
* \param nw_name network name
|
||||
* \param gtks GTK keys
|
||||
* \param stored_time stored timestampt
|
||||
* \param time_changed stored time has changed
|
||||
*
|
||||
* \return TLV entry or NULL
|
||||
*
|
||||
*/
|
||||
void ws_pae_nvm_store_nw_info_tlv_create(nw_info_nvm_tlv_t *tlv_entry, uint16_t pan_id, char *nw_name, uint8_t *gtk_eui64, sec_prot_gtk_keys_t *gtks);
|
||||
void ws_pae_nvm_store_nw_info_tlv_create(nw_info_nvm_tlv_t *tlv_entry, uint16_t pan_id, char *nw_name, uint8_t *gtk_eui64, sec_prot_gtk_keys_t *gtks, uint64_t stored_time, uint8_t time_changed);
|
||||
|
||||
/**
|
||||
* ws_pae_nvm_store_nw_info_tlv_read read from NVM network info TLV
|
||||
|
@ -104,12 +114,14 @@ void ws_pae_nvm_store_nw_info_tlv_create(nw_info_nvm_tlv_t *tlv_entry, uint16_t
|
|||
* \param pan_id PAN ID
|
||||
* \param nw_name network name
|
||||
* \param gtks GTK keys
|
||||
* \param current_time current timestampt
|
||||
* \param time_changed stored time has changed
|
||||
*
|
||||
* \return < 0 failure
|
||||
* \return >= 0 success
|
||||
*
|
||||
*/
|
||||
int8_t ws_pae_nvm_store_nw_info_tlv_read(nw_info_nvm_tlv_t *tlv_entry, uint16_t *pan_id, char *nw_name, uint8_t *gtk_eui64, sec_prot_gtk_keys_t *gtks);
|
||||
int8_t ws_pae_nvm_store_nw_info_tlv_read(nw_info_nvm_tlv_t *tlv_entry, uint16_t *pan_id, char *nw_name, uint8_t *gtk_eui64, sec_prot_gtk_keys_t *gtks, uint64_t current_time, uint8_t *time_changed);
|
||||
|
||||
/**
|
||||
* ws_pae_nvm_store_keys_tlv_create create NVM keys TLV
|
||||
|
@ -139,9 +151,10 @@ int8_t ws_pae_nvm_store_keys_tlv_read(keys_nvm_tlv_t *tlv_entry, sec_prot_keys_t
|
|||
* \param restart_cnt re-start counter
|
||||
* \param pan_version PAN version
|
||||
* \param counters frame counters
|
||||
* \param stored_time stored timestampt
|
||||
*
|
||||
*/
|
||||
void ws_pae_nvm_store_frame_counter_tlv_create(frame_cnt_nvm_tlv_t *tlv_entry, uint32_t restart_cnt, uint16_t pan_version, frame_counters_t *counters);
|
||||
void ws_pae_nvm_store_frame_counter_tlv_create(frame_cnt_nvm_tlv_t *tlv_entry, uint32_t restart_cnt, uint16_t pan_version, frame_counters_t *counters, uint64_t stored_time);
|
||||
|
||||
/**
|
||||
* ws_pae_nvm_store_frame_counter_tlv_read read from NVM frame counter TLV
|
||||
|
|
|
@ -43,6 +43,33 @@ static int8_t ws_pae_nvm_store_create_path(char *fast_data_path, const char *fil
|
|||
static int8_t ws_pae_nvm_store_write(const char *file_name, nvm_tlv_t *tlv);
|
||||
static int8_t ws_pae_nvm_store_read(const char *file_name, nvm_tlv_t *tlv);
|
||||
|
||||
void ws_pae_nvm_store_generic_tlv_create(nvm_tlv_t *tlv_entry, uint16_t tag, uint16_t length)
|
||||
{
|
||||
tlv_entry->tag = tag;
|
||||
tlv_entry->len = length;
|
||||
}
|
||||
|
||||
nvm_tlv_t *ws_pae_nvm_store_generic_tlv_allocate_and_create(uint16_t tag, uint16_t length)
|
||||
{
|
||||
nvm_tlv_t *tlv_entry = ns_dyn_mem_alloc(length + sizeof(nvm_tlv_t));
|
||||
if (!tlv_entry) {
|
||||
return NULL;
|
||||
}
|
||||
tlv_entry->tag = tag;
|
||||
tlv_entry->len = length;
|
||||
|
||||
return tlv_entry;
|
||||
}
|
||||
|
||||
void ws_pae_nvm_store_generic_tlv_free(nvm_tlv_t *tlv_entry)
|
||||
{
|
||||
if (!tlv_entry) {
|
||||
return;
|
||||
}
|
||||
|
||||
ns_dyn_mem_free(tlv_entry);
|
||||
}
|
||||
|
||||
int8_t ws_pae_nvm_store_tlv_file_write(const char *file, nvm_tlv_t *tlv)
|
||||
{
|
||||
if (!ws_pae_nvm_store_root_path_valid()) {
|
||||
|
|
|
@ -47,6 +47,38 @@ typedef struct {
|
|||
// tag + length
|
||||
#define NVM_TLV_FIXED_LEN sizeof(nvm_tlv_t)
|
||||
|
||||
/**
|
||||
* ws_pae_nvm_store_generic_tlv_create create NVM generic storage TLV
|
||||
*
|
||||
* \param tlv_entry TLV entry
|
||||
* \param tag tag
|
||||
* \param length length of the (whole) entry
|
||||
*
|
||||
* \return < 0 failure
|
||||
* \return >= 0 success
|
||||
*
|
||||
*/
|
||||
void ws_pae_nvm_store_generic_tlv_create(nvm_tlv_t *tlv_entry, uint16_t tag, uint16_t length);
|
||||
|
||||
/**
|
||||
* ws_pae_nvm_store_generic_tlv_allocate_and_create allocate and create NVM generic storage TLV
|
||||
*
|
||||
* \param tag tag
|
||||
* \param length length of the (whole) entry
|
||||
*
|
||||
* \return TLV entry or NULL
|
||||
*
|
||||
*/
|
||||
nvm_tlv_t *ws_pae_nvm_store_generic_tlv_allocate_and_create(uint16_t tag, uint16_t length);
|
||||
|
||||
/**
|
||||
* ws_pae_nvm_store_generic_tlv_free free NVM generic storage TLV
|
||||
*
|
||||
* \param tlv_entry TLV entry
|
||||
*
|
||||
*/
|
||||
void ws_pae_nvm_store_generic_tlv_free(nvm_tlv_t *tlv_entry);
|
||||
|
||||
/**
|
||||
* ws_pae_nvm_store_tlv_file_write write a list of TLVs to file
|
||||
*
|
||||
|
|
|
@ -294,7 +294,7 @@ static int8_t ws_pae_supp_gtk_hash_mismatch_check(pae_supp_t *pae_supp)
|
|||
}
|
||||
|
||||
// Check GTK hashes and initiate EAPOL procedure if mismatch is detected */
|
||||
gtk_mismatch_e mismatch = sec_prot_keys_gtks_hash_update(pae_supp->sec_keys_nw_info->gtks, gtkhash);
|
||||
gtk_mismatch_e mismatch = sec_prot_keys_gtks_hash_update(pae_supp->sec_keys_nw_info->gtks, gtkhash, false);
|
||||
if (mismatch != GTK_NO_MISMATCH) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -303,7 +303,7 @@ static int8_t ws_pae_supp_gtk_hash_mismatch_check(pae_supp_t *pae_supp)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int8_t ws_pae_supp_gtk_hash_update(protocol_interface_info_entry_t *interface_ptr, uint8_t *gtkhash)
|
||||
int8_t ws_pae_supp_gtk_hash_update(protocol_interface_info_entry_t *interface_ptr, uint8_t *gtkhash, bool del_gtk_on_mismatch)
|
||||
{
|
||||
pae_supp_t *pae_supp = ws_pae_supp_get(interface_ptr);
|
||||
if (!pae_supp) {
|
||||
|
@ -311,7 +311,7 @@ int8_t ws_pae_supp_gtk_hash_update(protocol_interface_info_entry_t *interface_pt
|
|||
}
|
||||
|
||||
// Check GTK hashes and initiate EAPOL procedure if mismatch is detected */
|
||||
gtk_mismatch_e mismatch = sec_prot_keys_gtks_hash_update(pae_supp->sec_keys_nw_info->gtks, gtkhash);
|
||||
gtk_mismatch_e mismatch = sec_prot_keys_gtks_hash_update(pae_supp->sec_keys_nw_info->gtks, gtkhash, del_gtk_on_mismatch);
|
||||
if (mismatch > GTK_NO_MISMATCH) {
|
||||
tr_info("GTK hash update %s %s %s %s",
|
||||
trace_array(>khash[0], 8),
|
||||
|
|
|
@ -130,12 +130,13 @@ int8_t ws_pae_supp_nw_key_valid(protocol_interface_info_entry_t *interface_ptr,
|
|||
*
|
||||
* \param interface_ptr interface
|
||||
* \param gtkhash GTK hash, 32 bytes
|
||||
* \param del_gtk_on_mismatch Delete GTK in case of mismatch
|
||||
*
|
||||
* \return < 0 failure
|
||||
* \return >= 0 success
|
||||
*
|
||||
*/
|
||||
int8_t ws_pae_supp_gtk_hash_update(protocol_interface_info_entry_t *interface_ptr, uint8_t *gtkhash);
|
||||
int8_t ws_pae_supp_gtk_hash_update(protocol_interface_info_entry_t *interface_ptr, uint8_t *gtkhash, bool del_gtk_on_mismatch);
|
||||
|
||||
/**
|
||||
* ws_pae_supp_nw_key_index_update key index been updated (on PAN configuration)
|
||||
|
|
|
@ -34,7 +34,9 @@
|
|||
// Wednesday, January 1, 2020 0:00:00 GMT
|
||||
#define CURRENT_TIME_INIT_VALUE 1577836800
|
||||
|
||||
static uint64_t current_time = CURRENT_TIME_INIT_VALUE;
|
||||
#define SECONDS_IN_WEEK (7 * 24 * 60 * 60)
|
||||
|
||||
static uint64_t ws_pae_current_time = CURRENT_TIME_INIT_VALUE;
|
||||
|
||||
uint16_t ws_pae_time_to_short_convert(uint32_t time)
|
||||
{
|
||||
|
@ -146,36 +148,76 @@ int8_t ws_pae_time_diff_calc(uint64_t curr_time, uint64_t comp_time, uint32_t *t
|
|||
return 0;
|
||||
}
|
||||
|
||||
uint64_t ws_pae_time_old_or_new_select(uint64_t old_time, uint64_t new_time)
|
||||
{
|
||||
// If current time is more than one week in the past use the stored time
|
||||
if (old_time > SECONDS_IN_WEEK && new_time < old_time - SECONDS_IN_WEEK) {
|
||||
return old_time;
|
||||
}
|
||||
|
||||
return new_time;
|
||||
}
|
||||
|
||||
bool ws_pae_time_old_and_new_validate(uint64_t old_time, uint64_t new_time)
|
||||
{
|
||||
/* If new time is more than one week in the past or more than a month in the
|
||||
future the old time is not valid */
|
||||
if ((old_time > SECONDS_IN_WEEK && new_time < old_time - SECONDS_IN_WEEK) ||
|
||||
new_time > (old_time + SYSTEM_TIME_MAXIMUM_DIFF)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint64_t ws_pae_current_time_get(void)
|
||||
{
|
||||
if (!ns_time_system_time_acquired_get()) {
|
||||
return ws_pae_current_time;
|
||||
}
|
||||
|
||||
uint64_t new_time;
|
||||
if (ns_time_system_time_read(&new_time) == 0) {
|
||||
new_time = ws_pae_time_old_or_new_select(ws_pae_current_time, new_time);
|
||||
return new_time;
|
||||
}
|
||||
|
||||
return current_time;
|
||||
return ws_pae_current_time;
|
||||
}
|
||||
|
||||
void ws_pae_current_time_update(uint16_t seconds)
|
||||
{
|
||||
current_time += seconds;
|
||||
ws_pae_current_time += seconds;
|
||||
}
|
||||
|
||||
int8_t ws_pae_current_time_set(uint64_t time)
|
||||
int8_t ws_pae_stored_time_check_and_set(uint64_t stored_time)
|
||||
{
|
||||
uint64_t new_system_time;
|
||||
current_time = time;
|
||||
|
||||
tr_debug("Current time set: %"PRIi64, time);
|
||||
tr_debug("Stored time check and set: %"PRIi64, stored_time);
|
||||
|
||||
if (ns_time_system_time_read(&new_system_time) == 0) {
|
||||
// System time has gone backwards
|
||||
if (new_system_time < current_time || new_system_time > current_time + SYSTEM_TIME_MAXIMUM_DIFF) {
|
||||
tr_error("FATAL: system time less than reference time or more than 12 months in future: %"PRIi64" reference time: %"PRIi64, new_system_time, current_time);
|
||||
return -1;
|
||||
}
|
||||
if (!ns_time_system_time_acquired_get()) {
|
||||
ws_pae_current_time = stored_time;
|
||||
return stored_time;
|
||||
}
|
||||
|
||||
if (ns_time_system_time_read(&new_system_time) == 0) {
|
||||
// Use either stored time or current time as reference when calculating lifetimes
|
||||
ws_pae_current_time = ws_pae_time_old_or_new_select(stored_time, new_system_time);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int8_t ws_pae_current_time_check_and_set(uint64_t current_time)
|
||||
{
|
||||
uint64_t new_system_time;
|
||||
|
||||
tr_debug("Current time check and set: %"PRIi64, current_time);
|
||||
|
||||
if (ns_time_system_time_read(&new_system_time) == 0) {
|
||||
// Use either stored time or current time as reference when calculating lifetimes
|
||||
ws_pae_current_time = ws_pae_time_old_or_new_select(current_time, new_system_time);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ typedef enum {
|
|||
#define STIME_TIME_GET(stime) (stime & STIME_TIME_MASK)
|
||||
|
||||
// Maximum difference in stored and indicated system time
|
||||
#define SYSTEM_TIME_MAXIMUM_DIFF (60 * 60 * 24 * 30 * 12)
|
||||
#define SYSTEM_TIME_MAXIMUM_DIFF (60 * 60 * 24 * 30) // One month
|
||||
|
||||
/**
|
||||
* ws_pae_time_to_short_convert convert time to short format
|
||||
|
@ -87,6 +87,28 @@ bool ws_pae_time_from_short_time_compare(uint16_t short_time1, uint16_t short_ti
|
|||
*/
|
||||
int8_t ws_pae_time_diff_calc(uint64_t curr_time, uint64_t comp_time, uint32_t *time_diff, bool future);
|
||||
|
||||
/**
|
||||
* ws_pae_time_old_or_new_select selected old or new time (based on difference)
|
||||
*
|
||||
* \param old_time old time
|
||||
* \param new_time new time
|
||||
*
|
||||
* \return old or new time
|
||||
*
|
||||
*/
|
||||
uint64_t ws_pae_time_old_or_new_select(uint64_t old_time, uint64_t new_time);
|
||||
|
||||
/**
|
||||
* ws_pae_time_old_and_new_validate validate old and new time (based on difference)
|
||||
*
|
||||
* \param old_time old time
|
||||
* \param new_time new time
|
||||
*
|
||||
* \return TRUE old time is valid, FALSE old time is not valid
|
||||
*
|
||||
*/
|
||||
bool ws_pae_time_old_and_new_validate(uint64_t old_time, uint64_t new_time);
|
||||
|
||||
/**
|
||||
* ws_pae_current_time_get gets current time
|
||||
*
|
||||
|
@ -96,7 +118,7 @@ int8_t ws_pae_time_diff_calc(uint64_t curr_time, uint64_t comp_time, uint32_t *t
|
|||
uint64_t ws_pae_current_time_get(void);
|
||||
|
||||
/**
|
||||
* ws_pae_current_time_get updates current time
|
||||
* ws_pae_current_time_update updates current time
|
||||
*
|
||||
* \param seconds seconds to be added to current time
|
||||
*
|
||||
|
@ -104,13 +126,13 @@ uint64_t ws_pae_current_time_get(void);
|
|||
void ws_pae_current_time_update(uint16_t seconds);
|
||||
|
||||
/**
|
||||
* ws_pae_current_time_set sets current time
|
||||
* ws_pae_stored_time_check_and_set stored time check and set current time
|
||||
*
|
||||
* \param time new time
|
||||
* \param stored_time stored time
|
||||
*
|
||||
* \return < 0 failure
|
||||
* \return >= 0 success
|
||||
*/
|
||||
int8_t ws_pae_current_time_set(uint64_t time);
|
||||
int8_t ws_pae_stored_time_check_and_set(uint64_t stored_time);
|
||||
|
||||
#endif /* WS_PAE_KEY_STORAGE_H_ */
|
||||
|
|
|
@ -0,0 +1,353 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Pelion and affiliates.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "nsconfig.h"
|
||||
#include "ns_types.h"
|
||||
#include "ns_trace.h"
|
||||
#include "ws_management_api.h"
|
||||
|
||||
#ifdef HAVE_WS
|
||||
#define TRACE_GROUP "wsph"
|
||||
|
||||
uint32_t ws_phy_decode_channel_spacing(uint8_t channel_spacing)
|
||||
{
|
||||
if (CHANNEL_SPACING_100 == channel_spacing) {
|
||||
return 100000;
|
||||
} else if (CHANNEL_SPACING_200 == channel_spacing) {
|
||||
return 200000;
|
||||
} else if (CHANNEL_SPACING_250 == channel_spacing) {
|
||||
return 250000;
|
||||
} else if (CHANNEL_SPACING_400 == channel_spacing) {
|
||||
return 400000;
|
||||
} else if (CHANNEL_SPACING_600 == channel_spacing) {
|
||||
return 600000;
|
||||
} else if (CHANNEL_SPACING_800 == channel_spacing) {
|
||||
return 800000;
|
||||
} else if (CHANNEL_SPACING_1200 == channel_spacing) {
|
||||
return 1200000;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t ws_phy_get_datarate_using_operating_mode(uint8_t operating_mode)
|
||||
{
|
||||
if ((OPERATING_MODE_1a == operating_mode) || (OPERATING_MODE_1b == operating_mode)) {
|
||||
return 50000;
|
||||
} else if ((OPERATING_MODE_2a == operating_mode) || (OPERATING_MODE_2b == operating_mode)) {
|
||||
return 100000;
|
||||
} else if (OPERATING_MODE_3 == operating_mode) {
|
||||
return 150000;
|
||||
} else if ((OPERATING_MODE_4a == operating_mode) || (OPERATING_MODE_4b == operating_mode)) {
|
||||
return 200000;
|
||||
} else if (OPERATING_MODE_5 == operating_mode) {
|
||||
return 300000;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t ws_phy_convert_operating_class_to_channel_plan_id(uint8_t operating_class, uint8_t regulatory_domain)
|
||||
{
|
||||
if (regulatory_domain == REG_DOMAIN_KR) {
|
||||
|
||||
} else if (regulatory_domain == REG_DOMAIN_EU) {
|
||||
if ((operating_class == 1) || (operating_class == 2) || (operating_class == 3) || (operating_class == 4)) {
|
||||
return operating_class + 31;
|
||||
}
|
||||
} else if (regulatory_domain == REG_DOMAIN_IN) {
|
||||
|
||||
} else if ((regulatory_domain == REG_DOMAIN_NA) || (regulatory_domain == REG_DOMAIN_BZ)) {
|
||||
if ((operating_class == 1) || (operating_class == 2) || (operating_class == 3)) {
|
||||
return operating_class;
|
||||
}
|
||||
} else if (regulatory_domain == REG_DOMAIN_JP) {
|
||||
|
||||
} else if (regulatory_domain == REG_DOMAIN_WW) {
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t ws_phy_convert_operating_mode_to_phy_mode_id(uint8_t operating_mode)
|
||||
{
|
||||
if (OPERATING_MODE_1a == operating_mode) {
|
||||
return 1;
|
||||
} else if (OPERATING_MODE_1b == operating_mode) {
|
||||
return 2;
|
||||
} else if (OPERATING_MODE_2a == operating_mode) {
|
||||
return 3;
|
||||
} else if (OPERATING_MODE_2b == operating_mode) {
|
||||
return 4;
|
||||
} else if (OPERATING_MODE_3 == operating_mode) {
|
||||
return 5;
|
||||
} else if (OPERATING_MODE_4a == operating_mode) {
|
||||
return 6;
|
||||
} else if (OPERATING_MODE_4b == operating_mode) {
|
||||
return 7;
|
||||
} else if (OPERATING_MODE_5 == operating_mode) {
|
||||
return 8;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t ws_phy_get_datarate_using_phy_mode_id(uint8_t phy_mode_id)
|
||||
{
|
||||
if (84 == phy_mode_id) {
|
||||
return 150000;
|
||||
} else if (85 == phy_mode_id) {
|
||||
return 200000;
|
||||
} else if ((68 == phy_mode_id) || (86 == phy_mode_id)) {
|
||||
return 300000;
|
||||
} else if ((34 == phy_mode_id) || (51 == phy_mode_id) || (69 == phy_mode_id)) {
|
||||
return 400000;
|
||||
} else if ((52 == phy_mode_id) || (70 == phy_mode_id)) {
|
||||
return 600000;
|
||||
} else if ((35 == phy_mode_id) || (53 == phy_mode_id)) {
|
||||
return 800000;
|
||||
} else if ((36 == phy_mode_id) || (54 == phy_mode_id)) {
|
||||
return 1200000;
|
||||
} else if (37 == phy_mode_id) {
|
||||
return 1600000;
|
||||
} else if (38 == phy_mode_id) {
|
||||
return 2400000;
|
||||
} else if ((1 == phy_mode_id) || (2 == phy_mode_id) || (17 == phy_mode_id) || (18 == phy_mode_id)) {
|
||||
return 50000;
|
||||
} else if ((3 == phy_mode_id) || (4 == phy_mode_id) || (19 == phy_mode_id) || (20 == phy_mode_id)) {
|
||||
return 100000;
|
||||
} else if ((5 == phy_mode_id) || (21 == phy_mode_id)) {
|
||||
return 150000;
|
||||
} else if ((6 == phy_mode_id) || (7 == phy_mode_id) || (22 == phy_mode_id) || (23 == phy_mode_id)) {
|
||||
return 200000;
|
||||
} else if ((8 == phy_mode_id) || (24 == phy_mode_id)) {
|
||||
return 300000;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t ws_phy_get_ofdm_option_using_phy_mode_id(uint8_t phy_mode_id)
|
||||
{
|
||||
if ((phy_mode_id >= 34) && (phy_mode_id <= 38)) {
|
||||
return OFDM_OPTION_1;
|
||||
} else if ((phy_mode_id >= 51) && (phy_mode_id <= 54)) {
|
||||
return OFDM_OPTION_2;
|
||||
} else if ((phy_mode_id >= 68) && (phy_mode_id <= 70)) {
|
||||
return OFDM_OPTION_3;
|
||||
} else if ((phy_mode_id >= 84) && (phy_mode_id <= 86)) {
|
||||
return OFDM_OPTION_4;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t ws_phy_get_ofdm_mcs_using_phy_mode_id(uint8_t phy_mode_id)
|
||||
{
|
||||
if (34 == phy_mode_id) {
|
||||
return OFDM_MCS_2;
|
||||
} else if ((35 == phy_mode_id) || (51 == phy_mode_id)) {
|
||||
return OFDM_MCS_3;
|
||||
} else if ((36 == phy_mode_id) || (52 == phy_mode_id) || (68 == phy_mode_id) || (84 == phy_mode_id)) {
|
||||
return OFDM_MCS_4;
|
||||
} else if ((37 == phy_mode_id) || (53 == phy_mode_id) || (69 == phy_mode_id) || (85 == phy_mode_id)) {
|
||||
return OFDM_MCS_5;
|
||||
} else if ((38 == phy_mode_id) || (54 == phy_mode_id) || (70 == phy_mode_id) || (86 == phy_mode_id)) {
|
||||
return OFDM_MCS_6;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t ws_phy_get_channel_plan_id_using_phy_mode_id(uint8_t phy_mode_id, uint8_t regulatory_domain, uint8_t base_channel_plan_id)
|
||||
{
|
||||
if (regulatory_domain == REG_DOMAIN_KR) {
|
||||
|
||||
} else if (regulatory_domain == REG_DOMAIN_EU) {
|
||||
// As on EU domain the PHY mode ID cannot unambiguously define the used channel plan id, use the one which best matches to the base channel plan id
|
||||
if ((base_channel_plan_id == 32) || (base_channel_plan_id == 33)) {
|
||||
if ((phy_mode_id == 1) || (phy_mode_id == 17)) {
|
||||
return 32;
|
||||
} else if ((phy_mode_id == 3) || (phy_mode_id == 5) || (phy_mode_id == 19) || (phy_mode_id == 21) || ((phy_mode_id >= 84) && (phy_mode_id <= 86))) {
|
||||
return 33;
|
||||
}
|
||||
} else if ((base_channel_plan_id == 36) || (base_channel_plan_id == 37)) {
|
||||
if ((phy_mode_id == 1) || (phy_mode_id == 17)) {
|
||||
return 36;
|
||||
} else if ((phy_mode_id == 3) || (phy_mode_id == 5) || (phy_mode_id == 19) || (phy_mode_id == 21) || ((phy_mode_id >= 84) && (phy_mode_id <= 86))) {
|
||||
return 37;
|
||||
}
|
||||
} else if ((base_channel_plan_id == 34) || (base_channel_plan_id == 35)) {
|
||||
if ((phy_mode_id == 1) || (phy_mode_id == 17)) {
|
||||
return 34;
|
||||
} else if ((phy_mode_id == 3) || (phy_mode_id == 5) || (phy_mode_id == 19) || (phy_mode_id == 21) || ((phy_mode_id >= 84) && (phy_mode_id <= 86))) {
|
||||
return 35;
|
||||
}
|
||||
}
|
||||
} else if (regulatory_domain == REG_DOMAIN_IN) {
|
||||
|
||||
} else if ((regulatory_domain == REG_DOMAIN_NA) || (regulatory_domain == REG_DOMAIN_BZ)) {
|
||||
if ((phy_mode_id == 2) || (phy_mode_id == 3) || (phy_mode_id == 18) || (phy_mode_id == 19) || ((phy_mode_id >= 84) && (phy_mode_id <= 86))) {
|
||||
return 1;
|
||||
} else if ((phy_mode_id == 5) || (phy_mode_id == 6) || (phy_mode_id == 21) || (phy_mode_id == 22) || ((phy_mode_id >= 68) && (phy_mode_id <= 70))) {
|
||||
return 2;
|
||||
} else if ((phy_mode_id == 8) || (phy_mode_id == 24)) {
|
||||
return 3;
|
||||
} else if ((phy_mode_id >= 51) && (phy_mode_id <= 54)) {
|
||||
return 4;
|
||||
} else if ((phy_mode_id >= 34) && (phy_mode_id <= 38)) {
|
||||
return 5;
|
||||
}
|
||||
} else if (regulatory_domain == REG_DOMAIN_JP) {
|
||||
|
||||
} else if (regulatory_domain == REG_DOMAIN_WW) {
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t ws_phy_get_number_of_channels_using_channel_plan_id(uint8_t channel_plan_id)
|
||||
{
|
||||
if (channel_plan_id == 1) {
|
||||
return 129;
|
||||
} else if (channel_plan_id == 2) {
|
||||
return 64;
|
||||
} else if (channel_plan_id == 3) {
|
||||
return 42;
|
||||
} else if (channel_plan_id == 4) {
|
||||
return 32;
|
||||
} else if (channel_plan_id == 5) {
|
||||
return 21;
|
||||
} else if (channel_plan_id == 32) {
|
||||
return 69;
|
||||
} else if (channel_plan_id == 33) {
|
||||
return 35;
|
||||
} else if (channel_plan_id == 34) {
|
||||
return 55;
|
||||
} else if (channel_plan_id == 35) {
|
||||
return 27;
|
||||
} else if (channel_plan_id == 36) {
|
||||
return 125;
|
||||
} else if (channel_plan_id == 37) {
|
||||
return 62;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t ws_phy_get_channel_spacing_using_channel_plan_id(uint8_t channel_plan_id)
|
||||
{
|
||||
if (channel_plan_id == 1) {
|
||||
return 200000;
|
||||
} else if (channel_plan_id == 2) {
|
||||
return 400000;
|
||||
} else if (channel_plan_id == 3) {
|
||||
return 600000;
|
||||
} else if (channel_plan_id == 4) {
|
||||
return 800000;
|
||||
} else if (channel_plan_id == 5) {
|
||||
return 1200000;
|
||||
} else if (channel_plan_id == 32) {
|
||||
return 100000;
|
||||
} else if (channel_plan_id == 33) {
|
||||
return 200000;
|
||||
} else if (channel_plan_id == 34) {
|
||||
return 100000;
|
||||
} else if (channel_plan_id == 35) {
|
||||
return 200000;
|
||||
} else if (channel_plan_id == 36) {
|
||||
return 100000;
|
||||
} else if (channel_plan_id == 37) {
|
||||
return 200000;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t ws_phy_get_channel_0_frequency_using_channel_plan_id(uint8_t channel_plan_id)
|
||||
{
|
||||
if (channel_plan_id == 1) {
|
||||
return 902200000;
|
||||
} else if (channel_plan_id == 2) {
|
||||
return 902400000;
|
||||
} else if (channel_plan_id == 3) {
|
||||
return 902600000;
|
||||
} else if (channel_plan_id == 4) {
|
||||
return 902800000;
|
||||
} else if (channel_plan_id == 5) {
|
||||
return 903200000;
|
||||
} else if (channel_plan_id == 32) {
|
||||
return 863100000;
|
||||
} else if (channel_plan_id == 33) {
|
||||
return 863100000;
|
||||
} else if (channel_plan_id == 34) {
|
||||
return 870100000;
|
||||
} else if (channel_plan_id == 35) {
|
||||
return 870200000;
|
||||
} else if (channel_plan_id == 36) {
|
||||
return 863100000;
|
||||
} else if (channel_plan_id == 37) {
|
||||
return 863100000;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool ws_phy_get_fsk_fec_enabled_using_phy_mode_id(uint8_t phy_mode_id)
|
||||
{
|
||||
if ((phy_mode_id >= 17) && (phy_mode_id <= 24)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
phy_modulation_e ws_phy_get_modulation_using_phy_mode_id(uint8_t phy_mode_id)
|
||||
{
|
||||
if (((phy_mode_id >= 34) && (phy_mode_id <= 38)) ||
|
||||
((phy_mode_id >= 51) && (phy_mode_id <= 54)) ||
|
||||
((phy_mode_id >= 68) && (phy_mode_id <= 70)) ||
|
||||
((phy_mode_id >= 84) && (phy_mode_id <= 86))) {
|
||||
return M_OFDM;
|
||||
} else if (((phy_mode_id >= 1) && (phy_mode_id <= 8)) || ((phy_mode_id >= 17) && (phy_mode_id <= 24))) {
|
||||
return M_2FSK;
|
||||
} else {
|
||||
return M_UNDEFINED;
|
||||
}
|
||||
}
|
||||
|
||||
phy_modulation_index_e ws_phy_get_modulation_index_using_phy_mode_id(uint8_t phy_mode_id)
|
||||
{
|
||||
if (ws_phy_get_modulation_using_phy_mode_id(phy_mode_id) != M_2FSK) {
|
||||
return MODULATION_INDEX_UNDEFINED;
|
||||
}
|
||||
|
||||
if ((2 == phy_mode_id) || (18 == phy_mode_id) ||
|
||||
(4 == phy_mode_id) || (20 == phy_mode_id) ||
|
||||
(7 == phy_mode_id) || (23 == phy_mode_id)) {
|
||||
return MODULATION_INDEX_1_0;
|
||||
}
|
||||
return MODULATION_INDEX_0_5;
|
||||
}
|
||||
|
||||
phy_modulation_index_e ws_phy_get_modulation_index_using_operating_mode(uint8_t operating_mode)
|
||||
{
|
||||
if ((OPERATING_MODE_1b == operating_mode) || (OPERATING_MODE_2b == operating_mode) || (OPERATING_MODE_4b == operating_mode)) {
|
||||
return MODULATION_INDEX_1_0;
|
||||
} else {
|
||||
return MODULATION_INDEX_0_5;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif //HAVE_WS
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Pelion and affiliates.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef WS_PHY_H_
|
||||
#define WS_PHY_H_
|
||||
|
||||
uint32_t ws_phy_decode_channel_spacing(uint8_t channel_spacing);
|
||||
|
||||
uint32_t ws_phy_get_datarate_using_operating_mode(uint8_t operating_mode);
|
||||
|
||||
uint8_t ws_phy_convert_operating_class_to_channel_plan_id(uint8_t operating_class, uint8_t regulatory_domain);
|
||||
|
||||
uint8_t ws_phy_convert_operating_mode_to_phy_mode_id(uint8_t operating_mode);
|
||||
|
||||
uint8_t ws_phy_get_channel_plan_id_using_phy_mode_id(uint8_t phy_mode_id, uint8_t regulatory_domain, uint8_t base_channel_plan_id);
|
||||
|
||||
uint32_t ws_phy_get_datarate_using_phy_mode_id(uint8_t phy_mode_id);
|
||||
|
||||
uint8_t ws_phy_get_ofdm_option_using_phy_mode_id(uint8_t phy_mode_id);
|
||||
|
||||
uint8_t ws_phy_get_ofdm_mcs_using_phy_mode_id(uint8_t phy_mode_id);
|
||||
|
||||
uint16_t ws_phy_get_number_of_channels_using_channel_plan_id(uint8_t channel_plan_id);
|
||||
|
||||
uint32_t ws_phy_get_channel_spacing_using_channel_plan_id(uint8_t channel_plan_id);
|
||||
|
||||
uint32_t ws_phy_get_channel_0_frequency_using_channel_plan_id(uint8_t channel_plan_id);
|
||||
|
||||
bool ws_phy_get_fsk_fec_enabled_using_phy_mode_id(uint8_t phy_mode_id);
|
||||
|
||||
phy_modulation_e ws_phy_get_modulation_using_phy_mode_id(uint8_t phy_mode_id);
|
||||
|
||||
phy_modulation_index_e ws_phy_get_modulation_index_using_phy_mode_id(uint8_t phy_mode_id);
|
||||
|
||||
phy_modulation_index_e ws_phy_get_modulation_index_using_operating_mode(uint8_t operating_mode);
|
||||
|
||||
#endif //WS_PHY_H_
|
|
@ -21,6 +21,7 @@
|
|||
#include "ns_list.h"
|
||||
#include "nsdynmemLIB.h"
|
||||
#include "net_ws_test.h"
|
||||
#include "net_ws_test_ext.h"
|
||||
#include "fhss_config.h"
|
||||
#include "ws_management_api.h"
|
||||
#include "mac_api.h"
|
||||
|
@ -32,6 +33,7 @@
|
|||
#include "6LoWPAN/ws/ws_bbr_api_internal.h"
|
||||
#include "6LoWPAN/ws/ws_pae_controller.h"
|
||||
#include "6LoWPAN/ws/ws_cfg_settings.h"
|
||||
#include "6LoWPAN/ws/ws_bootstrap.h"
|
||||
#include "randLIB.h"
|
||||
|
||||
#include "ns_trace.h"
|
||||
|
@ -41,6 +43,25 @@
|
|||
|
||||
#ifdef HAVE_WS
|
||||
|
||||
int ws_test_version_set(int8_t interface_id, uint8_t version)
|
||||
{
|
||||
test_pan_version = version;
|
||||
|
||||
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
|
||||
if (cur) {
|
||||
if (!ws_info(cur)) {
|
||||
return -1;
|
||||
}
|
||||
cur->ws_info->version = version;
|
||||
if (ws_version_1_0(cur)) {
|
||||
cur->ws_info->pan_information.version = WS_FAN_VERSION_1_0;
|
||||
} else if (ws_version_1_1(cur)) {
|
||||
cur->ws_info->pan_information.version = WS_FAN_VERSION_1_1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ws_test_pan_size_set(int8_t interface_id, uint16_t pan_size)
|
||||
{
|
||||
|
||||
|
@ -88,7 +109,7 @@ int ws_test_key_lifetime_set(int8_t interface_id, uint32_t gtk_lifetime, uint32_
|
|||
}
|
||||
|
||||
ws_sec_timer_cfg_t cfg;
|
||||
if (ws_cfg_sec_timer_get(&cfg, NULL) < 0) {
|
||||
if (ws_cfg_sec_timer_get(&cfg) < 0) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
|
@ -102,7 +123,7 @@ int ws_test_key_lifetime_set(int8_t interface_id, uint32_t gtk_lifetime, uint32_
|
|||
cfg.ptk_lifetime = ptk_lifetime;
|
||||
}
|
||||
|
||||
if (ws_cfg_sec_timer_set(cur, NULL, &cfg, NULL) < 0) {
|
||||
if (ws_cfg_sec_timer_set(cur, &cfg, 0x00) < 0) {
|
||||
return -3;
|
||||
}
|
||||
|
||||
|
@ -119,7 +140,7 @@ int ws_test_gtk_time_settings_set(int8_t interface_id, uint8_t revocat_lifetime_
|
|||
}
|
||||
|
||||
ws_sec_timer_cfg_t cfg;
|
||||
if (ws_cfg_sec_timer_get(&cfg, NULL) < 0) {
|
||||
if (ws_cfg_sec_timer_get(&cfg) < 0) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
|
@ -136,7 +157,7 @@ int ws_test_gtk_time_settings_set(int8_t interface_id, uint8_t revocat_lifetime_
|
|||
cfg.gtk_max_mismatch = max_mismatch;
|
||||
}
|
||||
|
||||
if (ws_cfg_sec_timer_set(cur, NULL, &cfg, NULL) < 0) {
|
||||
if (ws_cfg_sec_timer_set(cur, &cfg, 0x00) < 0) {
|
||||
return -3;
|
||||
}
|
||||
|
||||
|
@ -177,4 +198,27 @@ int ws_test_neighbour_temporary_lifetime_set(int8_t interface_id, uint32_t tempo
|
|||
return 0;
|
||||
}
|
||||
|
||||
int ws_test_procedure_trigger(int8_t interface_id, ws_test_proc_t procedure, void *parameters)
|
||||
{
|
||||
(void) parameters;
|
||||
|
||||
protocol_interface_info_entry_t *cur = NULL;;
|
||||
|
||||
if (interface_id > 0) {
|
||||
cur = protocol_stack_interface_info_get_by_id(interface_id);
|
||||
if (!cur || !ws_info(cur)) {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
cur = protocol_stack_interface_info_get_wisun_mesh();
|
||||
if (!cur) {
|
||||
if (procedure != PROC_AUTO_ON && procedure != PROC_AUTO_OFF) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ws_bootstrap_test_procedure_trigger(cur, procedure);
|
||||
}
|
||||
|
||||
#endif // HAVE_WS
|
||||
|
|
|
@ -114,7 +114,7 @@ void nd_border_router_setup_refresh(nwk_interface_id id, bool fresh_abro)
|
|||
nd_router_object->life_time = nd_configure->life_time;
|
||||
|
||||
if (!ns_list_is_empty(&nd_router_object->prefix_list)) {
|
||||
tr_debug("Release Prefix\n");
|
||||
tr_debug("Release Prefix");
|
||||
icmpv6_prefix_list_free(&nd_router_object->prefix_list);
|
||||
}
|
||||
|
||||
|
|
|
@ -371,7 +371,7 @@ void addr_policy_table_print(void)
|
|||
ns_list_foreach(addr_policy_table_entry_t, entry, &addr_policy_table) {
|
||||
char addr[40];
|
||||
ip6tos(entry->prefix, addr);
|
||||
tr_debug("%3d %3d %s/%u\n", entry->precedence, entry->label, addr, entry->prefix_len);
|
||||
tr_debug("%3d %3d %s/%u", entry->precedence, entry->label, addr, entry->prefix_len);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -834,12 +834,12 @@ void socket_list_print(route_print_fn_t *print_fn, char sep)
|
|||
/* Chuck in a consistency check */
|
||||
for (int i = 0; i < SOCKETS_MAX; i++) {
|
||||
if (socket_instance[i] && socket_instance[i]->id != i) {
|
||||
tr_err("ID %d points to %p with id %d\n", i, (void *)socket_instance[i], socket_instance[i]->id);
|
||||
tr_err("ID %d points to %p with id %d", i, (void *)socket_instance[i], socket_instance[i]->id);
|
||||
}
|
||||
}
|
||||
ns_list_foreach(socket_t, socket, &socket_list) {
|
||||
if (socket->id != -1 && socket_pointer_get(socket->id) != socket) {
|
||||
tr_err("Socket %p has invalid ID %d\n", (void *)socket, socket->id);
|
||||
tr_err("Socket %p has invalid ID %d", (void *)socket, socket->id);
|
||||
}
|
||||
sockbuf_check(&socket->rcvq);
|
||||
sockbuf_check(&socket->sndq);
|
||||
|
|
|
@ -212,7 +212,7 @@ void dhcp_client_delete(int8_t interface)
|
|||
do {
|
||||
srv_data_ptr = libdhcpv6_nonTemporal_entry_get_by_instance(dhcp_client->libDhcp_instance);
|
||||
if (srv_data_ptr != NULL) {
|
||||
tr_debug("Free DHCPv6 Client\n");
|
||||
tr_debug("Free DHCPv6 Client");
|
||||
memcpy(temporary_address, srv_data_ptr->iaNontemporalAddress.addressPrefix, 16);
|
||||
dhcp_service_req_remove_all(srv_data_ptr);// remove all pending retransmissions
|
||||
libdhcvp6_nontemporalAddress_server_data_free(srv_data_ptr);
|
||||
|
|
|
@ -137,7 +137,7 @@ int8_t mac_cca_threshold_update(protocol_interface_rf_mac_setup_s *rf_ptr, uint8
|
|||
return -1;
|
||||
}
|
||||
}
|
||||
tr_debug("Channel %u CCA threshold to %i", channel, rf_ptr->cca_threshold->ch_thresholds[channel]);
|
||||
tr_info("Channel %u CCA threshold to %i", channel, rf_ptr->cca_threshold->ch_thresholds[channel]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -96,6 +96,7 @@ typedef struct mac_pre_build_frame {
|
|||
uint8_t cca_request_restart_cnt;
|
||||
uint8_t tx_request_restart_cnt;
|
||||
uint8_t priority;
|
||||
uint8_t phy_mode_id;
|
||||
uint32_t blacklist_start_time_us;
|
||||
uint16_t blacklist_period_ms;
|
||||
uint16_t initial_tx_channel;
|
||||
|
|
|
@ -43,7 +43,8 @@ typedef enum mac_event_t {
|
|||
MAC_ACK_SECURITY_FAIL,
|
||||
MAC_UNKNOWN_DESTINATION,
|
||||
MAC_TX_PRECOND_FAIL,
|
||||
MAC_RETURN_TO_QUEUE
|
||||
MAC_RETURN_TO_QUEUE,
|
||||
MAC_MODE_SWITCH_TIMEOUT
|
||||
} mac_event_t;
|
||||
|
||||
typedef enum mac_tx_status_type_t {
|
||||
|
@ -95,11 +96,21 @@ typedef enum arm_nwk_mlme_event_type {
|
|||
ARM_NWK_MAC_MLME_INDIRECT_DATA_POLL_AFTER_DATA = 5,
|
||||
} arm_nwk_mlme_event_type_e;
|
||||
|
||||
typedef enum mac_mode_switch_states {
|
||||
MAC_MS_IDLE = 0,
|
||||
MAC_MS_PHR_SEND_READY,
|
||||
MAC_MS_DATA_SEND_READY,
|
||||
MAC_MS_PHR_RECEIVED,
|
||||
MAC_MS_DATA_RECEIVED,
|
||||
MAC_MS_TIMEOUT
|
||||
} mac_mode_switch_states_e;
|
||||
|
||||
#define ENHANCED_ACK_MAX_LENGTH 255
|
||||
|
||||
typedef struct dev_driver_tx_buffer {
|
||||
uint8_t *buf;
|
||||
uint8_t *enhanced_ack_buf;
|
||||
uint8_t mode_switch_phr_buf[2];
|
||||
uint16_t ack_len;
|
||||
uint16_t len;
|
||||
unsigned priority: 2;
|
||||
|
@ -180,6 +191,7 @@ typedef struct protocol_interface_rf_mac_setup {
|
|||
bool mac_ack_tx_active: 1;
|
||||
bool mac_edfe_tx_active: 1;
|
||||
bool mac_edfe_response_tx_active: 1;
|
||||
bool mac_mode_switch_phr_tx_active: 1;
|
||||
bool mac_frame_pending: 1;
|
||||
/* MAC Capability Information */
|
||||
bool macCapRxOnIdle: 1;
|
||||
|
@ -228,6 +240,8 @@ typedef struct protocol_interface_rf_mac_setup {
|
|||
|
||||
uint8_t mac_channel;
|
||||
uint8_t mac_tx_start_channel;
|
||||
uint8_t base_phy_mode;
|
||||
mac_mode_switch_states_e mode_switch_state;
|
||||
//uint8_t cca_failure;
|
||||
|
||||
/* MAC TX Queue */
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#include "MAC/IEEE802_15_4/mac_header_helper_functions.h"
|
||||
#include "MAC/IEEE802_15_4/mac_indirect_data.h"
|
||||
#include "MAC/IEEE802_15_4/mac_cca_threshold.h"
|
||||
#include "MAC/IEEE802_15_4/mac_mode_switch.h"
|
||||
#include "MAC/rf_driver_storage.h"
|
||||
|
||||
#include "sw_mac.h"
|
||||
|
@ -156,7 +157,7 @@ void mcps_sap_data_req_handler(protocol_interface_rf_mac_setup_s *rf_mac_setup,
|
|||
{
|
||||
mcps_data_req_ie_list_t ie_list;
|
||||
memset(&ie_list, 0, sizeof(mcps_data_req_ie_list_t));
|
||||
mcps_sap_data_req_handler_ext(rf_mac_setup, data_req, &ie_list, NULL, MAC_DATA_NORMAL_PRIORITY);
|
||||
mcps_sap_data_req_handler_ext(rf_mac_setup, data_req, &ie_list, NULL, MAC_DATA_NORMAL_PRIORITY, 0);
|
||||
}
|
||||
|
||||
static bool mac_ie_vector_length_validate(ns_ie_iovec_t *ie_vector, uint16_t iov_length, uint16_t *length_out)
|
||||
|
@ -195,8 +196,9 @@ static bool mac_ie_vector_length_validate(ns_ie_iovec_t *ie_vector, uint16_t iov
|
|||
}
|
||||
|
||||
|
||||
void mcps_sap_data_req_handler_ext(protocol_interface_rf_mac_setup_s *rf_mac_setup, const mcps_data_req_t *data_req, const mcps_data_req_ie_list_t *ie_list, const channel_list_s *asynch_channel_list, mac_data_priority_t priority)
|
||||
void mcps_sap_data_req_handler_ext(protocol_interface_rf_mac_setup_s *rf_mac_setup, const mcps_data_req_t *data_req, const mcps_data_req_ie_list_t *ie_list, const channel_list_s *asynch_channel_list, mac_data_priority_t priority, uint8_t phy_mode_id)
|
||||
{
|
||||
(void) phy_mode_id;
|
||||
uint8_t status = MLME_SUCCESS;
|
||||
mac_pre_build_frame_t *buffer = NULL;
|
||||
|
||||
|
@ -292,6 +294,7 @@ void mcps_sap_data_req_handler_ext(protocol_interface_rf_mac_setup_s *rf_mac_set
|
|||
buffer->fcf_dsn.frametype = FC_DATA_FRAME;
|
||||
buffer->ExtendedFrameExchange = data_req->ExtendedFrameExchange;
|
||||
buffer->WaitResponse = data_req->TxAckReq;
|
||||
buffer->phy_mode_id = phy_mode_id;
|
||||
if (data_req->ExtendedFrameExchange) {
|
||||
buffer->fcf_dsn.ackRequested = false;
|
||||
} else {
|
||||
|
@ -1106,6 +1109,10 @@ static void mac_mcps_asynch_finish(protocol_interface_rf_mac_setup_s *rf_mac_set
|
|||
|
||||
static bool mcps_sap_check_buffer_timeout(protocol_interface_rf_mac_setup_s *rf_mac_setup, mac_pre_build_frame_t *buffer)
|
||||
{
|
||||
// Timestamp is not implemented by virtual RF driver. Do not check buffer age.
|
||||
if (rf_mac_setup->dev_driver->phy_driver->arm_net_virtual_tx_cb) {
|
||||
return false;
|
||||
}
|
||||
// Convert from 1us slots to seconds
|
||||
uint32_t buffer_age_s = (mac_mcps_sap_get_phy_timestamp(rf_mac_setup) - buffer->request_start_time_us) / 1000000;
|
||||
// Do not timeout broadcast frames. Broadcast interval could be very long.
|
||||
|
@ -1834,6 +1841,12 @@ static int8_t mcps_generic_packet_build(protocol_interface_rf_mac_setup_s *rf_pt
|
|||
mac_security_authentication_data_params_set(&ccm_ptr, mhr_start, (buffer->mac_header_length_with_security + open_payload));
|
||||
ccm_process_run(&ccm_ptr);
|
||||
}
|
||||
// Packet is sent using mode switch. Build mode switch PHR
|
||||
if (buffer->phy_mode_id) {
|
||||
if (mac_build_mode_switch_phr(rf_ptr, tx_buf->mode_switch_phr_buf, buffer->phy_mode_id)) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -2083,6 +2096,7 @@ int8_t mcps_generic_ack_build(protocol_interface_rf_mac_setup_s *rf_ptr, bool in
|
|||
phy_csma_params_t csma_params;
|
||||
csma_params.backoff_time = 0;
|
||||
csma_params.cca_enabled = false;
|
||||
csma_params.mode_switch_phr = false;
|
||||
rf_ptr->dev_driver->phy_driver->extension(PHY_EXTENSION_SET_CSMA_PARAMETERS, (uint8_t *) &csma_params);
|
||||
if (rf_ptr->active_pd_data_request) {
|
||||
timer_mac_stop(rf_ptr);
|
||||
|
@ -2197,8 +2211,10 @@ static int8_t mcps_pd_data_cca_trig(protocol_interface_rf_mac_setup_s *rf_ptr, m
|
|||
rf_ptr->mac_edfe_tx_active = true;
|
||||
}
|
||||
|
||||
} else if (buffer->phy_mode_id) {
|
||||
rf_ptr->mac_mode_switch_phr_tx_active = true;
|
||||
cca_enabled = true;
|
||||
} else {
|
||||
|
||||
if (rf_ptr->mac_ack_tx_active) {
|
||||
mac_csma_backoff_start(rf_ptr);
|
||||
platform_exit_critical();
|
||||
|
@ -2209,13 +2225,13 @@ static int8_t mcps_pd_data_cca_trig(protocol_interface_rf_mac_setup_s *rf_ptr, m
|
|||
|
||||
}
|
||||
// Use double CCA check with FHSS for data packets only
|
||||
if (rf_ptr->fhss_api && !rf_ptr->mac_ack_tx_active && !rf_ptr->mac_edfe_tx_active && !rf_ptr->active_pd_data_request->asynch_request) {
|
||||
if (rf_ptr->fhss_api && !rf_ptr->mac_ack_tx_active && !rf_ptr->mac_edfe_tx_active && !rf_ptr->active_pd_data_request->asynch_request && !rf_ptr->mac_mode_switch_phr_tx_active) {
|
||||
if ((buffer->tx_time - (rf_ptr->multi_cca_interval * (rf_ptr->number_of_csma_ca_periods - 1))) > mac_mcps_sap_get_phy_timestamp(rf_ptr)) {
|
||||
buffer->csma_periods_left = rf_ptr->number_of_csma_ca_periods - 1;
|
||||
buffer->tx_time -= (rf_ptr->multi_cca_interval * (rf_ptr->number_of_csma_ca_periods - 1));
|
||||
}
|
||||
}
|
||||
mac_pd_sap_set_phy_tx_time(rf_ptr, buffer->tx_time, cca_enabled);
|
||||
mac_pd_sap_set_phy_tx_time(rf_ptr, buffer->tx_time, cca_enabled, rf_ptr->mac_mode_switch_phr_tx_active);
|
||||
if (mac_plme_cca_req(rf_ptr) != 0) {
|
||||
if (buffer->fcf_dsn.frametype == MAC_FRAME_ACK || (buffer->ExtendedFrameExchange && rf_ptr->mac_edfe_response_tx_active)) {
|
||||
//ACK or EFDE Response
|
||||
|
|
|
@ -123,7 +123,7 @@ int8_t mac_virtual_sap_data_cb(void *identifier, struct arm_phy_sap_msg_s *messa
|
|||
|
||||
void mcps_sap_data_req_handler(struct protocol_interface_rf_mac_setup *rf_mac_setup, const struct mcps_data_req_s *data_req);
|
||||
|
||||
void mcps_sap_data_req_handler_ext(struct protocol_interface_rf_mac_setup *rf_mac_setup, const struct mcps_data_req_s *data_req, const struct mcps_data_req_ie_list *ie_list, const channel_list_s *asynch_channel_list, mac_data_priority_t priority);
|
||||
void mcps_sap_data_req_handler_ext(struct protocol_interface_rf_mac_setup *rf_mac_setup, const struct mcps_data_req_s *data_req, const struct mcps_data_req_ie_list *ie_list, const channel_list_s *asynch_channel_list, mac_data_priority_t priority, uint8_t phy_mode_id);
|
||||
|
||||
void mac_mcps_trig_buffer_from_queue(struct protocol_interface_rf_mac_setup *rf_mac_setup);
|
||||
|
||||
|
|
|
@ -826,7 +826,7 @@ int8_t mac_mlme_set_req(protocol_interface_rf_mac_setup_s *rf_mac_setup, const m
|
|||
case macCCAThreshold:
|
||||
pu8 = (uint8_t *) set_req->value_pointer;
|
||||
rf_mac_setup->dev_driver->phy_driver->extension(PHY_EXTENSION_SET_CCA_THRESHOLD, pu8);
|
||||
tr_debug("Set CCA threshold to %u%%", *pu8);
|
||||
tr_info("Set CCA threshold to %u%%", *pu8);
|
||||
return 0;
|
||||
case macMultiCSMAParameters:
|
||||
return mac_mlme_set_multi_csma_parameters(rf_mac_setup, set_req);
|
||||
|
|
|
@ -0,0 +1,240 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Pelion and affiliates.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "string.h"
|
||||
#include "nsconfig.h"
|
||||
#include "ns_types.h"
|
||||
#include "ns_trace.h"
|
||||
#include "common_functions.h"
|
||||
#include "mac_api.h"
|
||||
#include "MAC/IEEE802_15_4/sw_mac_internal.h"
|
||||
#include "MAC/IEEE802_15_4/mac_defines.h"
|
||||
#include "MAC/IEEE802_15_4/mac_mode_switch.h"
|
||||
#include "MAC/IEEE802_15_4/mac_mcps_sap.h"
|
||||
#include "MAC/IEEE802_15_4/mac_timer.h"
|
||||
#include "MAC/rf_driver_storage.h"
|
||||
|
||||
#define TRACE_GROUP "mswc"
|
||||
|
||||
static uint8_t mac_calculate_mode_switch_parity(uint16_t mode_switch_phr)
|
||||
{
|
||||
uint8_t counter = 0;
|
||||
// Calculate number of 1-bits in (15-bit) input and return modulo-2 of the sum
|
||||
for (int i = 0; i < 15; i++) {
|
||||
if (mode_switch_phr & (1 << i)) {
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
return counter % 2;
|
||||
}
|
||||
/*
|
||||
* 11-bit input must be padded with 4 leading zeroes.
|
||||
* Reverse the 15-bit result and divide with polynomial X⁴ + X + 1 -> 10011
|
||||
* Return remainder as checksum
|
||||
*
|
||||
* Example:
|
||||
* Input: xxxxx01000000001
|
||||
* Padded input: x000001000000001
|
||||
* Reversed and padded input: 100000000100000x
|
||||
* Calculated checksum: 0x0f (00001111)
|
||||
*
|
||||
* Division:
|
||||
*
|
||||
* 10011010101 <- Result
|
||||
* -----------------
|
||||
* 10011 | 100000000100000 <- Highest bit (10000) is 1, add 1 in result
|
||||
* 10011 <- 10011 * 1
|
||||
* -----
|
||||
* 00110 <- Highest bit (00110) is 0, add 0 in result
|
||||
* 00000 <- 10011 * 0
|
||||
* -----
|
||||
* .
|
||||
* .
|
||||
* .
|
||||
* -----
|
||||
* 11100
|
||||
* 10011
|
||||
* ----
|
||||
* 1111 <- Remainder
|
||||
*
|
||||
*/
|
||||
static uint8_t mac_calculate_mode_switch_checksum(uint16_t mode_switch_phr)
|
||||
{
|
||||
// X⁴ + X + 1 -> 0b10011 -> 0x13
|
||||
uint8_t polynomial = 0x13;
|
||||
// Pad input with four leading zeroes
|
||||
mode_switch_phr &= ~0x7800;
|
||||
// Reverse input
|
||||
uint16_t phr_reversed = 0;
|
||||
for (int i = 0; i < 16; i++) {
|
||||
if (mode_switch_phr & (1 << i)) {
|
||||
phr_reversed |= 1 << (15 - i);
|
||||
}
|
||||
}
|
||||
// Divide 15-bit padded and reversed input, use polynomial 10011 as the divider
|
||||
uint8_t shift = 11;
|
||||
uint8_t remainder = phr_reversed >> shift;
|
||||
for (int i = 0; i < 11; i++) {
|
||||
// Check highest bit
|
||||
if (remainder & (1 << 4)) {
|
||||
remainder ^= polynomial;
|
||||
} else {
|
||||
remainder ^= 0;
|
||||
}
|
||||
// Division ready, return remainder as checksum
|
||||
if (!(--shift)) {
|
||||
return remainder;
|
||||
}
|
||||
remainder <<= 1;
|
||||
if (phr_reversed & (1 << shift)) {
|
||||
remainder |= 1;
|
||||
}
|
||||
}
|
||||
// Shouldn't go here
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Mode switch PHR format:
|
||||
*
|
||||
* | 0 | 1-2 | 3-10 | 11-14 | 15 |
|
||||
* |Mode Switch|Reserved|New Phy Mode ID|Checksum|Parity|
|
||||
*
|
||||
*/
|
||||
int8_t mac_build_mode_switch_phr(protocol_interface_rf_mac_setup_s *rf_ptr, uint8_t *data_ptr, uint8_t phy_mode_id)
|
||||
{
|
||||
(void) rf_ptr;
|
||||
if (!data_ptr) {
|
||||
return -1;
|
||||
}
|
||||
// - Write mode switch and PHY mode id fields
|
||||
uint16_t mode_switch_phr = 1 << SHIFT_MODE_SWITCH;
|
||||
mode_switch_phr |= phy_mode_id << SHIFT_MODE_SWITCH_PHY_MODE;
|
||||
// - Calculate checksum
|
||||
mode_switch_phr |= mac_calculate_mode_switch_checksum(mode_switch_phr) << SHIFT_MODE_SWITCH_CHECKSUM;
|
||||
// - Calculate parity
|
||||
mode_switch_phr |= mac_calculate_mode_switch_parity(mode_switch_phr) << SHIFT_MODE_SWITCH_PARITY;
|
||||
|
||||
common_write_16_bit_inverse(mode_switch_phr, data_ptr);
|
||||
|
||||
// - With successful return value, MAC should start CSMA-CA for a mode switch PHR
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int8_t mac_change_mode_switch_configuration(protocol_interface_rf_mac_setup_s *rf_ptr, uint8_t phy_mode_id, mac_mode_switch_states_e new_state)
|
||||
{
|
||||
mac_api_t *mac_api = get_sw_mac_api(rf_ptr);
|
||||
if (mac_api->mode_resolver_cb) {
|
||||
phy_rf_channel_configuration_s rf_config;
|
||||
memset(&rf_config, 0, sizeof(phy_rf_channel_configuration_s));
|
||||
if (!mac_api->mode_resolver_cb(mac_api, phy_mode_id, &rf_config)) {
|
||||
rf_ptr->dev_driver->phy_driver->extension(PHY_EXTENSION_SET_RF_CONFIGURATION, (uint8_t *) &rf_config);
|
||||
rf_ptr->mode_switch_state = new_state;
|
||||
return 0;
|
||||
} else {
|
||||
tr_error("Mode switch could not resolve PHY mode ID %u", phy_mode_id);
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static uint32_t mac_calculate_timeout(protocol_interface_rf_mac_setup_s *rf_ptr, uint8_t phy_mode_id)
|
||||
{
|
||||
mac_api_t *mac_api = get_sw_mac_api(rf_ptr);
|
||||
if (mac_api->mode_resolver_cb) {
|
||||
phy_rf_channel_configuration_s rf_config;
|
||||
memset(&rf_config, 0, sizeof(phy_rf_channel_configuration_s));
|
||||
if (!mac_api->mode_resolver_cb(mac_api, phy_mode_id, &rf_config)) {
|
||||
// Calculate transmission time of max size packet + Ack size + max settling time + Tack
|
||||
return ((uint64_t)(1200 + 100) * 8000000 / rf_config.datarate + 1500 + 5000);
|
||||
}
|
||||
}
|
||||
// If could not resolve configuration, use 300ms as default timeout
|
||||
return 300000;
|
||||
}
|
||||
|
||||
int8_t mac_parse_mode_switch_phr(protocol_interface_rf_mac_setup_s *rf_ptr, const uint8_t *data_ptr, uint16_t data_len)
|
||||
{
|
||||
if (data_len != PHR_LEN) {
|
||||
return -1;
|
||||
}
|
||||
if (!data_ptr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint16_t mode_switch_phr = common_read_16_bit_inverse(data_ptr);
|
||||
if (!(mode_switch_phr & MASK_MODE_SWITCH)) {
|
||||
// Mode switch not enabled
|
||||
return -1;
|
||||
}
|
||||
|
||||
// - Validate checksum
|
||||
if (mac_calculate_mode_switch_checksum(mode_switch_phr) != ((mode_switch_phr & MASK_MODE_SWITCH_CHECKSUM) >> SHIFT_MODE_SWITCH_CHECKSUM)) {
|
||||
// Invalid checksum, TODO: error correction
|
||||
return -1;
|
||||
}
|
||||
// - Validate parity
|
||||
if (mac_calculate_mode_switch_parity(mode_switch_phr) != (mode_switch_phr & MASK_MODE_SWITCH_PARITY) >> SHIFT_MODE_SWITCH_PARITY) {
|
||||
// Invalid parity
|
||||
return -1;
|
||||
}
|
||||
// - Read PHY mode id
|
||||
uint8_t phy_mode_id = (mode_switch_phr & MASK_MODE_SWITCH_PHY_MODE) >> SHIFT_MODE_SWITCH_PHY_MODE;
|
||||
|
||||
// When mode switch PHR was received, change new configuration here to wait data packet and set mode switch state machine to 'PHR received'
|
||||
if (mac_change_mode_switch_configuration(rf_ptr, phy_mode_id, MAC_MS_PHR_RECEIVED)) {
|
||||
return -1;
|
||||
}
|
||||
// Backup timer, if reception of data packet fails
|
||||
timer_mac_start(rf_ptr, MAC_MODE_SWITCH_TIMEOUT, mac_calculate_timeout(rf_ptr, phy_mode_id) / 50);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int8_t mac_update_mode_switch_state(protocol_interface_rf_mac_setup_s *rf_ptr, mac_mode_switch_states_e state, uint8_t phy_mode_id)
|
||||
{
|
||||
switch (state) {
|
||||
case MAC_MS_PHR_SEND_READY:
|
||||
// When mode switch PHR was sent, change new configuration here before transmitting data packet and set mode switch state machine to 'PHR send ready'
|
||||
if (!mac_change_mode_switch_configuration(rf_ptr, phy_mode_id, MAC_MS_PHR_SEND_READY)) {
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case MAC_MS_DATA_SEND_READY:
|
||||
// When data packet was sent, switch back to base configuration and set mode switch state machine to 'idle'
|
||||
if ((rf_ptr->mode_switch_state == MAC_MS_PHR_SEND_READY) && !mac_change_mode_switch_configuration(rf_ptr, phy_mode_id, MAC_MS_IDLE)) {
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case MAC_MS_DATA_RECEIVED:
|
||||
// When packet was received in new configuration, switch back to base configuration and set mode switch state machine to 'idle'
|
||||
if ((rf_ptr->mode_switch_state == MAC_MS_PHR_RECEIVED) && !mac_change_mode_switch_configuration(rf_ptr, phy_mode_id, MAC_MS_IDLE)) {
|
||||
// Packet was received, stop backup timer to not cause timeout event
|
||||
timer_mac_stop(rf_ptr);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case MAC_MS_TIMEOUT:
|
||||
// When reception timeout occurs, switch back to base configuration and set mode switch state machine to 'idle'
|
||||
if ((rf_ptr->mode_switch_state == MAC_MS_PHR_RECEIVED) && !mac_change_mode_switch_configuration(rf_ptr, phy_mode_id, MAC_MS_IDLE)) {
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return -1;
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Pelion and affiliates.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef MAC_MODE_SWITCH_H_
|
||||
#define MAC_MODE_SWITCH_H_
|
||||
|
||||
#define PHR_LEN 2
|
||||
|
||||
#define SHIFT_MODE_SWITCH_PARITY (15)
|
||||
#define SHIFT_MODE_SWITCH_CHECKSUM (11)
|
||||
#define SHIFT_MODE_SWITCH_PHY_MODE (3)
|
||||
#define SHIFT_MODE_SWITCH (0)
|
||||
#define MASK_MODE_SWITCH_PARITY (0x8000)
|
||||
#define MASK_MODE_SWITCH_CHECKSUM (0x7800)
|
||||
#define MASK_MODE_SWITCH_PHY_MODE (0x07F8)
|
||||
#define MASK_MODE_SWITCH (0x0001)
|
||||
|
||||
/**
|
||||
* @brief Build mode switch PHR.
|
||||
* @param rf_ptr Pointer to MAC instance.
|
||||
* @param data_ptr Pointer to data buffer.
|
||||
* @param phy_mode_id Used PHY mode id.
|
||||
* @return 0 - success, -1 - failure.
|
||||
*/
|
||||
int8_t mac_build_mode_switch_phr(protocol_interface_rf_mac_setup_s *rf_ptr, uint8_t *data_ptr, uint8_t phy_mode_id);
|
||||
|
||||
/**
|
||||
* @brief Parse mode switch PHR.
|
||||
* @param rf_ptr Pointer to MAC instance.
|
||||
* @param data_ptr Pointer to data buffer.
|
||||
* @param data_len Data length.
|
||||
* @return 0 - mode switch PHR found, -1 - mode switch PHR not found.
|
||||
*/
|
||||
int8_t mac_parse_mode_switch_phr(protocol_interface_rf_mac_setup_s *rf_ptr, const uint8_t *data_ptr, uint16_t data_len);
|
||||
|
||||
/**
|
||||
* @brief Update mode switch state.
|
||||
* @param rf_ptr Pointer to MAC instance.
|
||||
*/
|
||||
int8_t mac_update_mode_switch_state(protocol_interface_rf_mac_setup_s *rf_ptr, mac_mode_switch_states_e state, uint8_t phy_mode_id);
|
||||
|
||||
#endif /* MAC_MODE_SWITCH_H_ */
|
|
@ -35,6 +35,7 @@
|
|||
#include "MAC/IEEE802_15_4/mac_filter.h"
|
||||
#include "MAC/IEEE802_15_4/mac_mcps_sap.h"
|
||||
#include "MAC/IEEE802_15_4/mac_cca_threshold.h"
|
||||
#include "MAC/IEEE802_15_4/mac_mode_switch.h"
|
||||
#include "MAC/rf_driver_storage.h"
|
||||
#include "Core/include/ns_monitor.h"
|
||||
#include "ns_trace.h"
|
||||
|
@ -49,6 +50,10 @@
|
|||
// MAC should learn and make this dynamic by sending first few packets with predefined CSMA period.
|
||||
#define MIN_FHSS_CSMA_PERIOD_US 5000
|
||||
|
||||
// Add extra CSMA-CA delay for packets using mode switch. The delay between mode switch PHR and data packet equals to MDR_SETTLING_TIME_US
|
||||
// Must be between 510 and 1500 us
|
||||
#define MDR_SETTLING_TIME_US 510
|
||||
|
||||
static int8_t mac_data_interface_tx_done_cb(protocol_interface_rf_mac_setup_s *rf_ptr, phy_link_tx_status_e status, uint8_t cca_retry, uint8_t tx_retry);
|
||||
static void mac_sap_cca_fail_cb(protocol_interface_rf_mac_setup_s *rf_ptr, uint16_t failed_channel);
|
||||
|
||||
|
@ -106,6 +111,9 @@ uint32_t mac_csma_backoff_get(protocol_interface_rf_mac_setup_s *rf_mac_setup)
|
|||
backoff_in_us = 1;
|
||||
}
|
||||
if (rf_mac_setup->fhss_api) {
|
||||
if (rf_mac_setup->active_pd_data_request->phy_mode_id) {
|
||||
backoff_in_us += MDR_SETTLING_TIME_US;
|
||||
}
|
||||
// Synchronization error when backoff time is shorter than allowed.
|
||||
// TODO: Make this dynamic.
|
||||
if (backoff_in_us < MIN_FHSS_CSMA_PERIOD_US) {
|
||||
|
@ -184,6 +192,9 @@ int8_t mac_plme_cca_req(protocol_interface_rf_mac_setup_s *rf_mac_setup)
|
|||
if (rf_mac_setup->mac_ack_tx_active || (rf_mac_setup->mac_edfe_tx_active && rf_mac_setup->mac_edfe_response_tx_active)) {
|
||||
buffer = tx_buf->enhanced_ack_buf;
|
||||
length = tx_buf->ack_len;
|
||||
} else if (rf_mac_setup->mac_mode_switch_phr_tx_active) {
|
||||
buffer = tx_buf->mode_switch_phr_buf;
|
||||
length = sizeof(tx_buf->mode_switch_phr_buf);
|
||||
} else {
|
||||
buffer = tx_buf->buf;
|
||||
length = tx_buf->len;
|
||||
|
@ -232,6 +243,7 @@ void mac_pd_abort_active_tx(protocol_interface_rf_mac_setup_s *rf_mac_setup)
|
|||
phy_csma_params_t csma_params;
|
||||
// Set TX time to 0 to abort current transmission
|
||||
csma_params.backoff_time = 0;
|
||||
csma_params.mode_switch_phr = false;
|
||||
rf_mac_setup->dev_driver->phy_driver->extension(PHY_EXTENSION_SET_CSMA_PARAMETERS, (uint8_t *) &csma_params);
|
||||
}
|
||||
|
||||
|
@ -242,8 +254,12 @@ void mac_pd_abort_active_tx(protocol_interface_rf_mac_setup_s *rf_mac_setup)
|
|||
* \param tx_time TX timestamp to be set.
|
||||
*
|
||||
*/
|
||||
void mac_pd_sap_set_phy_tx_time(protocol_interface_rf_mac_setup_s *rf_mac_setup, uint32_t tx_time, bool cca_enabled)
|
||||
void mac_pd_sap_set_phy_tx_time(protocol_interface_rf_mac_setup_s *rf_mac_setup, uint32_t tx_time, bool cca_enabled, bool mode_switch)
|
||||
{
|
||||
// Given tx_time is for the actual data packet. Mode switch PHR must be sent with the offset of MDR settling time.
|
||||
if (mode_switch) {
|
||||
tx_time -= MDR_SETTLING_TIME_US;
|
||||
}
|
||||
// With TX time set to zero, PHY sends immediately
|
||||
if (!tx_time) {
|
||||
tx_time++;
|
||||
|
@ -251,6 +267,7 @@ void mac_pd_sap_set_phy_tx_time(protocol_interface_rf_mac_setup_s *rf_mac_setup,
|
|||
phy_csma_params_t csma_params;
|
||||
csma_params.backoff_time = tx_time;
|
||||
csma_params.cca_enabled = cca_enabled;
|
||||
csma_params.mode_switch_phr = mode_switch;
|
||||
rf_mac_setup->dev_driver->phy_driver->extension(PHY_EXTENSION_SET_CSMA_PARAMETERS, (uint8_t *) &csma_params);
|
||||
}
|
||||
|
||||
|
@ -300,7 +317,7 @@ void mac_pd_sap_state_machine(protocol_interface_rf_mac_setup_s *rf_mac_setup)
|
|||
cca_enabled = true;
|
||||
}
|
||||
|
||||
mac_pd_sap_set_phy_tx_time(rf_mac_setup, active_buf->tx_time, cca_enabled);
|
||||
mac_pd_sap_set_phy_tx_time(rf_mac_setup, active_buf->tx_time, cca_enabled, rf_mac_setup->mac_mode_switch_phr_tx_active);
|
||||
if (active_buf->fcf_dsn.frametype == FC_BEACON_FRAME) {
|
||||
// FHSS synchronization info is written in the end of transmitted (Beacon) buffer
|
||||
dev_driver_tx_buffer_s *tx_buf = &rf_mac_setup->dev_driver_tx_buffer;
|
||||
|
@ -335,6 +352,10 @@ void mac_pd_sap_state_machine(protocol_interface_rf_mac_setup_s *rf_mac_setup)
|
|||
} else if (rf_mac_setup->mac_tx_result == MAC_TIMER_ACK) {
|
||||
mac_data_interface_tx_done_cb(rf_mac_setup, PHY_LINK_TX_FAIL, 0, 0);
|
||||
}
|
||||
} else {
|
||||
if (rf_mac_setup->mac_tx_result == MAC_MODE_SWITCH_TIMEOUT) {
|
||||
mac_update_mode_switch_state(rf_mac_setup, MAC_MS_TIMEOUT, rf_mac_setup->base_phy_mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -424,6 +445,7 @@ static bool mac_data_asynch_channel_switch(protocol_interface_rf_mac_setup_s *rf
|
|||
static void mac_data_ack_tx_finish(protocol_interface_rf_mac_setup_s *rf_ptr)
|
||||
{
|
||||
rf_ptr->mac_ack_tx_active = false;
|
||||
mac_update_mode_switch_state(rf_ptr, MAC_MS_DATA_RECEIVED, rf_ptr->base_phy_mode);
|
||||
if (rf_ptr->fhss_api) {
|
||||
//SET tx completed false because ack isnot never queued
|
||||
rf_ptr->fhss_api->data_tx_done(rf_ptr->fhss_api, false, false, 0xff);
|
||||
|
@ -449,7 +471,6 @@ int8_t mac_data_edfe_force_stop(protocol_interface_rf_mac_setup_s *rf_ptr)
|
|||
|
||||
static int8_t mac_data_interface_tx_done_cb(protocol_interface_rf_mac_setup_s *rf_ptr, phy_link_tx_status_e status, uint8_t cca_retry, uint8_t tx_retry)
|
||||
{
|
||||
|
||||
if (!rf_ptr->macRfRadioTxActive) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -513,7 +534,7 @@ static int8_t mac_data_interface_tx_done_cb(protocol_interface_rf_mac_setup_s *r
|
|||
if (active_buf->csma_periods_left > 0) {
|
||||
active_buf->csma_periods_left--;
|
||||
active_buf->tx_time += rf_ptr->multi_cca_interval;
|
||||
mac_pd_sap_set_phy_tx_time(rf_ptr, active_buf->tx_time, true);
|
||||
mac_pd_sap_set_phy_tx_time(rf_ptr, active_buf->tx_time, true, false);
|
||||
#ifdef TIMING_TOOL_TRACES
|
||||
tr_info("%u CSMA_start", mac_mcps_sap_get_phy_timestamp(rf_ptr));
|
||||
#endif
|
||||
|
@ -555,6 +576,23 @@ VALIDATE_TX_TIME:
|
|||
mac_data_ack_tx_finish(rf_ptr);
|
||||
return 0;
|
||||
}
|
||||
} else if (rf_ptr->mac_mode_switch_phr_tx_active) {
|
||||
#ifdef TIMING_TOOL_TRACES
|
||||
tr_info("%u TX_done", mac_mcps_sap_get_phy_timestamp(rf_ptr));
|
||||
#endif
|
||||
rf_ptr->mac_mode_switch_phr_tx_active = false;
|
||||
if (rf_ptr->fhss_api) {
|
||||
rf_ptr->fhss_api->data_tx_done(rf_ptr->fhss_api, false, true, rf_ptr->active_pd_data_request->msduHandle);
|
||||
}
|
||||
if (!mac_update_mode_switch_state(rf_ptr, MAC_MS_PHR_SEND_READY, rf_ptr->active_pd_data_request->phy_mode_id)) {
|
||||
mac_pd_sap_set_phy_tx_time(rf_ptr, rf_ptr->active_pd_data_request->tx_time, true, rf_ptr->mac_mode_switch_phr_tx_active);
|
||||
if (mac_plme_cca_req(rf_ptr) != 0) {
|
||||
mac_sap_no_ack_cb(rf_ptr);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
// Failed to start data transmission after mode switch PHR was sent
|
||||
status = PHY_LINK_TX_FAIL;
|
||||
}
|
||||
|
||||
// Do not update CCA count when Ack is received, it was already updated with PHY_LINK_TX_SUCCESS event
|
||||
|
@ -580,7 +618,7 @@ VALIDATE_TX_TIME:
|
|||
timer_mac_stop(rf_ptr);
|
||||
}
|
||||
uint16_t failed_channel = rf_ptr->mac_channel;
|
||||
if (rf_ptr->fhss_api && rf_ptr->active_pd_data_request->asynch_request == false) {
|
||||
if (rf_ptr->active_pd_data_request && rf_ptr->active_pd_data_request->asynch_request == false) {
|
||||
/* waiting_ack == false allows FHSS to change back to RX channel after transmission
|
||||
* tx_completed == true allows FHSS to delete stored failure handles
|
||||
*/
|
||||
|
@ -610,7 +648,12 @@ VALIDATE_TX_TIME:
|
|||
waiting_ack = false;
|
||||
tx_completed = true;
|
||||
}
|
||||
rf_ptr->fhss_api->data_tx_done(rf_ptr->fhss_api, waiting_ack, tx_completed, rf_ptr->active_pd_data_request->msduHandle);
|
||||
if (waiting_ack == false) {
|
||||
mac_update_mode_switch_state(rf_ptr, MAC_MS_DATA_SEND_READY, rf_ptr->base_phy_mode);
|
||||
}
|
||||
if (rf_ptr->fhss_api) {
|
||||
rf_ptr->fhss_api->data_tx_done(rf_ptr->fhss_api, waiting_ack, tx_completed, rf_ptr->active_pd_data_request->msduHandle);
|
||||
}
|
||||
}
|
||||
|
||||
switch (status) {
|
||||
|
@ -674,7 +717,7 @@ static int8_t mac_data_interface_tx_done_by_ack_cb(protocol_interface_rf_mac_set
|
|||
if (mcps_sap_pd_ack(rf_ptr, buf) != 0) {
|
||||
mcps_sap_pre_parsed_frame_buffer_free(buf);
|
||||
}
|
||||
|
||||
mac_update_mode_switch_state(rf_ptr, MAC_MS_DATA_SEND_READY, rf_ptr->base_phy_mode);
|
||||
if (rf_ptr->fhss_api) {
|
||||
rf_ptr->fhss_api->data_tx_done(rf_ptr->fhss_api, false, true, rf_ptr->active_pd_data_request->msduHandle);
|
||||
}
|
||||
|
@ -1040,19 +1083,27 @@ int8_t mac_pd_sap_data_cb(void *identifier, arm_phy_sap_msg_t *message)
|
|||
goto ERROR_HANDLER;
|
||||
}
|
||||
|
||||
if (pd_data_ind->data_len < 3) {
|
||||
return -1;
|
||||
}
|
||||
#ifdef TIMING_TOOL_TRACES
|
||||
tr_info("%u RX_start", mac_pd_sap_get_phy_rx_time(rf_ptr));
|
||||
tr_info("%u RX_done", mac_mcps_sap_get_phy_timestamp(rf_ptr));
|
||||
#endif
|
||||
|
||||
if (!mac_parse_mode_switch_phr(rf_ptr, pd_data_ind->data_ptr, pd_data_ind->data_len)) {
|
||||
// TODO: mode switch returned 0, needs some logic to wait frame with new mode
|
||||
goto ERROR_HANDLER;
|
||||
}
|
||||
|
||||
if (pd_data_ind->data_len < 3) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
mac_cca_threshold_event_send(rf_ptr, rf_ptr->mac_channel, pd_data_ind->dbm);
|
||||
mac_fcf_sequence_t fcf_read;
|
||||
const uint8_t *ptr = mac_header_parse_fcf_dsn(&fcf_read, pd_data_ind->data_ptr);
|
||||
|
||||
// No need to send Ack - Check if RX channel needs to be updated
|
||||
if (fcf_read.ackRequested == false) {
|
||||
mac_update_mode_switch_state(rf_ptr, MAC_MS_DATA_RECEIVED, rf_ptr->base_phy_mode);
|
||||
if (rf_ptr->fhss_api) {
|
||||
rf_ptr->fhss_api->data_tx_done(rf_ptr->fhss_api, false, false, 0);
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ int8_t mac_plme_cca_req(struct protocol_interface_rf_mac_setup *rf_mac_setup);
|
|||
|
||||
void mac_pd_abort_active_tx(struct protocol_interface_rf_mac_setup *rf_mac_setup);
|
||||
|
||||
void mac_pd_sap_set_phy_tx_time(struct protocol_interface_rf_mac_setup *rf_mac_setup, uint32_t tx_time, bool cca_enabled);
|
||||
void mac_pd_sap_set_phy_tx_time(struct protocol_interface_rf_mac_setup *rf_mac_setup, uint32_t tx_time, bool cca_enabled, bool mode_switch);
|
||||
|
||||
void mac_pd_sap_rf_low_level_function_set(void *mac_ptr, void *driver);
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#include "MAC/IEEE802_15_4/mac_pd_sap.h"
|
||||
#include "MAC/IEEE802_15_4/mac_timer.h"
|
||||
#include "sw_mac.h"
|
||||
|
||||
#define TRACE_GROUP "mTim"
|
||||
|
||||
/*-------------------MAC TIMER FUNCTIONS--------------------------*/
|
||||
|
||||
|
|
|
@ -55,10 +55,11 @@ static int8_t ns_sw_mac_initialize(mac_api_t *api, mcps_data_confirm *mcps_data_
|
|||
mlme_confirm *mlme_conf_callback, mlme_indication *mlme_ind_callback, int8_t parent_id);
|
||||
static int8_t ns_sw_mac_api_enable_mcps_ext(mac_api_t *api, mcps_data_indication_ext *data_ind_cb, mcps_data_confirm_ext *data_cnf_cb, mcps_ack_data_req_ext *ack_data_req_cb);
|
||||
static int8_t ns_sw_mac_api_enable_edfe_ext(mac_api_t *api, mcps_edfe_handler *edfe_ind_cb);
|
||||
static int8_t ns_sw_mac_api_mode_switch_resolver_set(mac_api_t *api, mode_switch_resolver *mode_resolver_cb, uint8_t base_phy_mode);
|
||||
|
||||
static void mlme_req(const mac_api_t *api, mlme_primitive id, const void *data);
|
||||
static void mcps_req(const mac_api_t *api, const mcps_data_req_t *data);
|
||||
static void mcps_req_ext(const mac_api_t *api, const mcps_data_req_t *data, const mcps_data_req_ie_list_t *ie_ext, const channel_list_s *asynch_channel_list, mac_data_priority_t priority);
|
||||
static void mcps_req_ext(const mac_api_t *api, const mcps_data_req_t *data, const mcps_data_req_ie_list_t *ie_ext, const channel_list_s *asynch_channel_list, mac_data_priority_t priority, uint8_t phy_mode_id);
|
||||
static uint8_t purge_req(const mac_api_t *api, const mcps_purge_t *data);
|
||||
static int8_t macext_mac64_address_set(const mac_api_t *api, const uint8_t *mac64);
|
||||
static int8_t macext_mac64_address_get(const mac_api_t *api, mac_extended_address_type type, uint8_t *mac64_buf);
|
||||
|
@ -130,6 +131,7 @@ mac_api_t *ns_sw_mac_create(int8_t rf_driver_id, mac_description_storage_size_t
|
|||
this->mac_initialize = &ns_sw_mac_initialize;
|
||||
this->mac_mcps_extension_enable = &ns_sw_mac_api_enable_mcps_ext;
|
||||
this->mac_mcps_edfe_enable = &ns_sw_mac_api_enable_edfe_ext;
|
||||
this->mac_mode_switch_resolver_set = &ns_sw_mac_api_mode_switch_resolver_set;
|
||||
this->mlme_req = &mlme_req;
|
||||
this->mcps_data_req = &mcps_req;
|
||||
this->mcps_data_req_ext = &mcps_req_ext;
|
||||
|
@ -344,6 +346,19 @@ static int8_t ns_sw_mac_api_enable_edfe_ext(mac_api_t *api, mcps_edfe_handler *e
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int8_t ns_sw_mac_api_mode_switch_resolver_set(mac_api_t *api, mode_switch_resolver *mode_resolver_cb, uint8_t base_phy_mode)
|
||||
{
|
||||
if (api != mac_store.mac_api) {
|
||||
return -1;
|
||||
}
|
||||
if (!mac_store.setup->mac_extension_enabled) {
|
||||
return -1;
|
||||
}
|
||||
mac_store.setup->base_phy_mode = base_phy_mode;
|
||||
mac_store.mac_api->mode_resolver_cb = mode_resolver_cb;
|
||||
return 0;
|
||||
}
|
||||
|
||||
mac_api_t *get_sw_mac_api(protocol_interface_rf_mac_setup_s *setup)
|
||||
{
|
||||
if (!mac_store.mac_api || mac_store.mac_api->parent_id == -1 || mac_store.setup != setup) {
|
||||
|
@ -582,15 +597,15 @@ static void mcps_req(const mac_api_t *api, const mcps_data_req_t *data)
|
|||
/* Call direct new API but without IE extensions */
|
||||
mcps_data_req_ie_list_t ie_list;
|
||||
memset(&ie_list, 0, sizeof(mcps_data_req_ie_list_t));
|
||||
mcps_sap_data_req_handler_ext(mac_store.setup, data, &ie_list, NULL, MAC_DATA_NORMAL_PRIORITY);
|
||||
mcps_sap_data_req_handler_ext(mac_store.setup, data, &ie_list, NULL, MAC_DATA_NORMAL_PRIORITY, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void mcps_req_ext(const mac_api_t *api, const mcps_data_req_t *data, const mcps_data_req_ie_list_t *ie_ext, const channel_list_s *asynch_channel_list, mac_data_priority_t priority)
|
||||
static void mcps_req_ext(const mac_api_t *api, const mcps_data_req_t *data, const mcps_data_req_ie_list_t *ie_ext, const channel_list_s *asynch_channel_list, mac_data_priority_t priority, uint8_t phy_mode_id)
|
||||
{
|
||||
//TODO: Populate linked list when present
|
||||
if (mac_store.mac_api == api) {
|
||||
mcps_sap_data_req_handler_ext(mac_store.setup, data, ie_ext, asynch_channel_list, priority);
|
||||
mcps_sap_data_req_handler_ext(mac_store.setup, data, ie_ext, asynch_channel_list, priority, phy_mode_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -501,7 +501,7 @@ static void mpl_buffer_transmit(mpl_domain_t *domain, mpl_buffered_message_t *me
|
|||
memcpy(buf->src_sa.address, message->message + IPV6_HDROFF_SRC_ADDR, 16);
|
||||
|
||||
ipv6_transmit_multicast_on_interface(buf, domain->interface);
|
||||
tr_debug("MPL transmit %u", mpl_buffer_sequence(message));
|
||||
tr_info("MPL transmit %u", mpl_buffer_sequence(message));
|
||||
}
|
||||
|
||||
static void mpl_buffer_inconsistent(const mpl_domain_t *domain, mpl_buffered_message_t *message)
|
||||
|
|
|
@ -45,5 +45,6 @@ protocol_interface_info_entry_t *protocol_stack_interface_info_get_by_id(int8_t
|
|||
protocol_interface_info_entry_t *protocol_stack_interface_info_get_by_bootstrap_id(int8_t id);
|
||||
protocol_interface_info_entry_t *protocol_stack_interface_info_get_by_rpl_domain(const struct rpl_domain *domain, int8_t last_id);
|
||||
protocol_interface_info_entry_t *protocol_stack_interface_info_get_by_fhss_api(const struct fhss_api *fhss_api);
|
||||
protocol_interface_info_entry_t *protocol_stack_interface_info_get_wisun_mesh(void);
|
||||
|
||||
#endif /* NWK_INTERFACE_INCLUDE_PROTOCOL_ABSTRACT_H_ */
|
||||
|
|
|
@ -65,7 +65,6 @@
|
|||
#include "6LoWPAN/Thread/thread_bootstrap.h"
|
||||
#include "6LoWPAN/Thread/thread_routing.h"
|
||||
#include "6LoWPAN/Thread/thread_management_internal.h"
|
||||
#include "6LoWPAN/ws/ws_bootstrap.h"
|
||||
#include "6LoWPAN/ws/ws_common.h"
|
||||
#ifdef HAVE_WS
|
||||
#include "6LoWPAN/ws/ws_pae_controller.h"
|
||||
|
@ -806,6 +805,18 @@ protocol_interface_info_entry_t *protocol_stack_interface_info_get_by_fhss_api(c
|
|||
return NULL;
|
||||
}
|
||||
|
||||
protocol_interface_info_entry_t *protocol_stack_interface_info_get_wisun_mesh(void)
|
||||
{
|
||||
#ifdef HAVE_WS
|
||||
ns_list_foreach(protocol_interface_info_entry_t, cur, &protocol_interface_info_list) {
|
||||
if (cur->ws_info) {
|
||||
return cur;
|
||||
}
|
||||
}
|
||||
#endif //HAVE_WS
|
||||
return NULL;
|
||||
}
|
||||
|
||||
protocol_interface_info_entry_t *protocol_stack_interface_sleep_possibility(void)
|
||||
{
|
||||
ns_list_foreach(protocol_interface_info_entry_t, cur, &protocol_interface_info_list) {
|
||||
|
@ -1148,7 +1159,7 @@ void net_bootsrap_cb_run(uint8_t event)
|
|||
if (thread_info(cur)) {
|
||||
thread_bootstrap_state_machine(cur);
|
||||
} else if (ws_info(cur)) {
|
||||
ws_bootstrap_state_machine(cur);
|
||||
ws_common_state_machine(cur);
|
||||
} else {
|
||||
protocol_6lowpan_bootstrap(cur);
|
||||
}
|
||||
|
|
|
@ -70,7 +70,7 @@ void protocol_timer_start(protocol_timer_id_t id, void (*passed_fptr)(uint16_t),
|
|||
protocol_timer[id].fptr = passed_fptr;
|
||||
platform_exit_critical();
|
||||
} else {
|
||||
tr_debug("Do Not use Null pointer for fptr!!!\n");
|
||||
tr_debug("Do Not use Null pointer for fptr!!!");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1549,6 +1549,20 @@ static buffer_t *rpl_control_dis_handler(protocol_interface_info_entry_t *cur, r
|
|||
return buffer_free(buf);
|
||||
}
|
||||
|
||||
void rpl_control_transmit_dio_trigger(protocol_interface_info_entry_t *cur, struct rpl_domain *domain)
|
||||
{
|
||||
ns_list_foreach(rpl_instance_t, instance, &domain->instances) {
|
||||
rpl_instance_dio_trigger(instance, cur, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void rpl_control_parent_selection_trigger(struct rpl_domain *domain)
|
||||
{
|
||||
ns_list_foreach(rpl_instance_t, instance, &domain->instances) {
|
||||
rpl_instance_run_parent_selection(instance);
|
||||
}
|
||||
}
|
||||
|
||||
void rpl_control_transmit_dis(rpl_domain_t *domain, protocol_interface_info_entry_t *cur, uint8_t pred, uint8_t instance_id, const uint8_t *dodagid, const uint8_t version, const uint8_t *dst)
|
||||
{
|
||||
uint16_t length = 2;
|
||||
|
|
|
@ -133,6 +133,11 @@ struct buffer *rpl_control_source_route_error_handler(struct buffer *buf, struct
|
|||
|
||||
/* Manually send DIS packets for bootstrap */
|
||||
void rpl_control_transmit_dis(struct rpl_domain *domain, struct protocol_interface_info_entry *cur, uint8_t pred, uint8_t instance_id, const uint8_t *dodagid, const uint8_t version, const uint8_t *dst);
|
||||
/* Manually send DIO packets for bootstrap */
|
||||
void rpl_control_transmit_dio_trigger(struct protocol_interface_info_entry *cur, struct rpl_domain *domain);
|
||||
/* Manually trigger RPL parent selection */
|
||||
void rpl_control_parent_selection_trigger(struct rpl_domain *domain);
|
||||
|
||||
bool rpl_control_have_dodag(struct rpl_domain *domain);
|
||||
|
||||
/* APIs used to manipulate configuration at the root */
|
||||
|
|
|
@ -786,19 +786,31 @@ static int8_t radius_client_sec_prot_eui_64_hash_generate(uint8_t *eui_64, uint8
|
|||
|
||||
mbedtls_sha256_init(&ctx);
|
||||
|
||||
#if (MBEDTLS_VERSION_MAJOR >= 3)
|
||||
if (mbedtls_sha256_starts(&ctx, 0) != 0) {
|
||||
#else
|
||||
if (mbedtls_sha256_starts_ret(&ctx, 0) != 0) {
|
||||
#endif
|
||||
ret_val = -1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
#if (MBEDTLS_VERSION_MAJOR >= 3)
|
||||
if (mbedtls_sha256_update(&ctx, hashed_string, 24) != 0) {
|
||||
#else
|
||||
if (mbedtls_sha256_update_ret(&ctx, hashed_string, 24) != 0) {
|
||||
#endif
|
||||
ret_val = -1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
uint8_t output[32];
|
||||
|
||||
#if (MBEDTLS_VERSION_MAJOR >= 3)
|
||||
if (mbedtls_sha256_finish(&ctx, output) != 0) {
|
||||
#else
|
||||
if (mbedtls_sha256_finish_ret(&ctx, output) != 0) {
|
||||
#endif
|
||||
ret_val = -1;
|
||||
goto error;
|
||||
}
|
||||
|
@ -872,19 +884,35 @@ static int8_t radius_client_sec_prot_response_authenticator_calc(sec_prot_t *pro
|
|||
|
||||
mbedtls_md5_init(&ctx);
|
||||
|
||||
#if (MBEDTLS_VERSION_MAJOR >= 3)
|
||||
if (mbedtls_md5_starts(&ctx) != 0) {
|
||||
#else
|
||||
if (mbedtls_md5_starts_ret(&ctx) != 0) {
|
||||
#endif
|
||||
goto end;
|
||||
}
|
||||
|
||||
#if (MBEDTLS_VERSION_MAJOR >= 3)
|
||||
if (mbedtls_md5_update(&ctx, msg_ptr, msg_len) != 0) {
|
||||
#else
|
||||
if (mbedtls_md5_update_ret(&ctx, msg_ptr, msg_len) != 0) {
|
||||
#endif
|
||||
goto end;
|
||||
}
|
||||
|
||||
#if (MBEDTLS_VERSION_MAJOR >= 3)
|
||||
if (mbedtls_md5_update(&ctx, key, key_len) != 0) {
|
||||
#else
|
||||
if (mbedtls_md5_update_ret(&ctx, key, key_len) != 0) {
|
||||
#endif
|
||||
goto end;
|
||||
}
|
||||
|
||||
#if (MBEDTLS_VERSION_MAJOR >= 3)
|
||||
if (mbedtls_md5_finish(&ctx, auth_ptr) != 0) {
|
||||
#else
|
||||
if (mbedtls_md5_finish_ret(&ctx, auth_ptr) != 0) {
|
||||
#endif
|
||||
goto end;
|
||||
}
|
||||
|
||||
|
@ -940,35 +968,59 @@ static int8_t radius_client_sec_prot_ms_mppe_recv_key_pmk_decrypt(sec_prot_t *pr
|
|||
while (cipher_text_len >= MS_MPPE_RECV_KEY_BLOCK_LEN) {
|
||||
mbedtls_md5_init(&ctx);
|
||||
|
||||
#if (MBEDTLS_VERSION_MAJOR >= 3)
|
||||
if (mbedtls_md5_starts(&ctx) != 0) {
|
||||
#else
|
||||
if (mbedtls_md5_starts_ret(&ctx) != 0) {
|
||||
#endif
|
||||
md5_failed = true;
|
||||
break;
|
||||
}
|
||||
|
||||
#if (MBEDTLS_VERSION_MAJOR >= 3)
|
||||
if (mbedtls_md5_update(&ctx, key, key_len) != 0) {
|
||||
#else
|
||||
if (mbedtls_md5_update_ret(&ctx, key, key_len) != 0) {
|
||||
#endif
|
||||
md5_failed = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (first_interm_b_value) {
|
||||
// b(1) = MD5(secret + request-authenticator + salt)
|
||||
#if (MBEDTLS_VERSION_MAJOR >= 3)
|
||||
if (mbedtls_md5_update(&ctx, request_authenticator, MS_MPPE_RECV_KEY_BLOCK_LEN) != 0) {
|
||||
#else
|
||||
if (mbedtls_md5_update_ret(&ctx, request_authenticator, MS_MPPE_RECV_KEY_BLOCK_LEN) != 0) {
|
||||
#endif
|
||||
md5_failed = true;
|
||||
break;
|
||||
}
|
||||
#if (MBEDTLS_VERSION_MAJOR >= 3)
|
||||
if (mbedtls_md5_update(&ctx, salt_ptr, MS_MPPE_RECV_KEY_SALT_LEN) != 0) {
|
||||
#else
|
||||
if (mbedtls_md5_update_ret(&ctx, salt_ptr, MS_MPPE_RECV_KEY_SALT_LEN) != 0) {
|
||||
#endif
|
||||
md5_failed = true;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// b(i) = MD5(secret + cipher_text(i - 1))
|
||||
#if (MBEDTLS_VERSION_MAJOR >= 3)
|
||||
if (mbedtls_md5_update(&ctx, cipher_text_ptr - MS_MPPE_RECV_KEY_BLOCK_LEN, MS_MPPE_RECV_KEY_BLOCK_LEN) != 0) {
|
||||
#else
|
||||
if (mbedtls_md5_update_ret(&ctx, cipher_text_ptr - MS_MPPE_RECV_KEY_BLOCK_LEN, MS_MPPE_RECV_KEY_BLOCK_LEN) != 0) {
|
||||
#endif
|
||||
md5_failed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#if (MBEDTLS_VERSION_MAJOR >= 3)
|
||||
if (mbedtls_md5_finish(&ctx, interm_b_val) != 0) {
|
||||
#else
|
||||
if (mbedtls_md5_finish_ret(&ctx, interm_b_val) != 0) {
|
||||
#endif
|
||||
md5_failed = true;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -507,7 +507,7 @@ uint32_t sec_prot_keys_gtk_lifetime_get(sec_prot_gtk_keys_t *gtks, uint8_t index
|
|||
return gtks->gtk[index].lifetime;
|
||||
}
|
||||
|
||||
uint32_t sec_prot_keys_gtk_lifetime_decrement(sec_prot_gtk_keys_t *gtks, uint8_t index, uint64_t current_time, uint16_t seconds, bool gtk_update_enable)
|
||||
uint32_t sec_prot_keys_gtk_lifetime_decrement(sec_prot_gtk_keys_t *gtks, uint8_t index, uint64_t current_time, uint32_t seconds, bool gtk_update_enable)
|
||||
{
|
||||
if (gtks->gtk[index].lifetime > seconds) {
|
||||
gtks->gtk[index].lifetime -= seconds;
|
||||
|
@ -527,6 +527,7 @@ uint32_t sec_prot_keys_gtk_lifetime_decrement(sec_prot_gtk_keys_t *gtks, uint8_t
|
|||
// If timestamps differ for more than 5 minutes marks field as updated (and stores to NVM)
|
||||
if (diff > 300 && gtk_update_enable) {
|
||||
gtks->updated = true;
|
||||
sec_prot_keys_gtk_expirytime_set(gtks, index, expirytime);
|
||||
}
|
||||
|
||||
return gtks->gtk[index].lifetime;
|
||||
|
@ -716,7 +717,7 @@ int8_t sec_prot_keys_gtk_valid_check(uint8_t *gtk)
|
|||
return 0;
|
||||
}
|
||||
|
||||
gtk_mismatch_e sec_prot_keys_gtks_hash_update(sec_prot_gtk_keys_t *gtks, uint8_t *gtkhash)
|
||||
gtk_mismatch_e sec_prot_keys_gtks_hash_update(sec_prot_gtk_keys_t *gtks, uint8_t *gtkhash, bool del_gtk_on_mismatch)
|
||||
{
|
||||
uint8_t *gtk_hash_ptr = gtkhash;
|
||||
|
||||
|
@ -729,11 +730,15 @@ gtk_mismatch_e sec_prot_keys_gtks_hash_update(sec_prot_gtk_keys_t *gtks, uint8_t
|
|||
uint32_t lifetime = sec_prot_keys_gtk_lifetime_get(gtks, i);
|
||||
if (lifetime > GTK_EXPIRE_MISMATCH_TIME) {
|
||||
tr_info("GTK mismatch %i expired time, lifetime: %"PRIu32"", i, lifetime);
|
||||
if (mismatch < GTK_LIFETIME_MISMATCH) {
|
||||
// Only indicate mismatch in case fresh hash is received
|
||||
if (mismatch < GTK_LIFETIME_MISMATCH && del_gtk_on_mismatch) {
|
||||
mismatch = GTK_LIFETIME_MISMATCH;
|
||||
}
|
||||
}
|
||||
sec_prot_keys_gtk_clear(gtks, i);
|
||||
// Only delete in case fresh hash is received
|
||||
if (del_gtk_on_mismatch) {
|
||||
sec_prot_keys_gtk_clear(gtks, i);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Check is hash matches to existing key
|
||||
|
@ -759,7 +764,10 @@ gtk_mismatch_e sec_prot_keys_gtks_hash_update(sec_prot_gtk_keys_t *gtks, uint8_t
|
|||
if (mismatch < GTK_HASH_MISMATCH) {
|
||||
mismatch = GTK_HASH_MISMATCH;
|
||||
}
|
||||
sec_prot_keys_gtk_clear(gtks, i);
|
||||
// Only delete in case fresh hash is received
|
||||
if (del_gtk_on_mismatch) {
|
||||
sec_prot_keys_gtk_clear(gtks, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,6 +62,10 @@
|
|||
|
||||
#define SEC_MAXIMUM_LIFETIME (60 * 60 * 24 * 30 * 24) // Maximum life time for PMK, PTK, GTKs etc. is two years
|
||||
|
||||
// System time changed
|
||||
#define SYSTEM_TIME_NOT_CHANGED 0
|
||||
#define SYSTEM_TIME_CHANGED 1
|
||||
|
||||
typedef struct {
|
||||
uint8_t key[GTK_LEN]; /**< Group Transient Key (128 bits) */
|
||||
uint64_t expirytime; /**< GTK expiry time on storage */
|
||||
|
@ -108,7 +112,8 @@ typedef struct {
|
|||
typedef struct {
|
||||
uint8_t gtk[GTK_LEN]; /**< GTK of the frame counter */
|
||||
uint32_t frame_counter; /**< Current frame counter */
|
||||
uint32_t stored_frame_counter; /**< Stored Frame counter */
|
||||
uint32_t stored_frame_counter; /**< Stored frame counter */
|
||||
uint32_t max_frame_counter_chg; /**< Maximum frame counter change */
|
||||
bool set : 1; /**< Value has been set */
|
||||
} frame_counter_t;
|
||||
|
||||
|
@ -144,6 +149,7 @@ typedef struct {
|
|||
uint16_t new_pan_id; /**< new PAN ID indicated by bootstrap */
|
||||
uint16_t key_pan_id; /**< PAN ID for keys */
|
||||
uint16_t pan_version; /**< PAN version for keys */
|
||||
uint8_t system_time_changed; /**< System time changed */
|
||||
bool updated : 1; /**< Network info has been updated */
|
||||
} sec_prot_keys_nw_info_t;
|
||||
|
||||
|
@ -630,7 +636,7 @@ uint32_t sec_prot_keys_gtk_lifetime_get(sec_prot_gtk_keys_t *gtks, uint8_t index
|
|||
* \return new GTK lifetime
|
||||
*
|
||||
*/
|
||||
uint32_t sec_prot_keys_gtk_lifetime_decrement(sec_prot_gtk_keys_t *gtks, uint8_t index, uint64_t current_time, uint16_t seconds, bool gtk_update_enable);
|
||||
uint32_t sec_prot_keys_gtk_lifetime_decrement(sec_prot_gtk_keys_t *gtks, uint8_t index, uint64_t current_time, uint32_t seconds, bool gtk_update_enable);
|
||||
|
||||
/**
|
||||
* sec_prot_keys_gtk_exptime_from_lifetime_get converts GTK lifetime to expiry time.
|
||||
|
@ -806,11 +812,12 @@ int8_t sec_prot_keys_gtk_valid_check(uint8_t *gtk);
|
|||
*
|
||||
* \param gtks GTK keys
|
||||
* \param gtk_hash GTK hash
|
||||
* \param del_gtk_on_mismatch Delete GTK in case of mismatch
|
||||
*
|
||||
* \return GTK mismatch type or no mismatch
|
||||
*
|
||||
*/
|
||||
gtk_mismatch_e sec_prot_keys_gtks_hash_update(sec_prot_gtk_keys_t *gtks, uint8_t *gtkhash);
|
||||
gtk_mismatch_e sec_prot_keys_gtks_hash_update(sec_prot_gtk_keys_t *gtks, uint8_t *gtkhash, bool del_gtk_on_mismatch);
|
||||
|
||||
/**
|
||||
* sec_prot_keys_gtk_hash_empty checks if GTK hash field is empty
|
||||
|
|
|
@ -514,19 +514,31 @@ int8_t sec_prot_lib_gtkhash_generate(uint8_t *gtk, uint8_t *gtk_hash)
|
|||
|
||||
mbedtls_sha256_init(&ctx);
|
||||
|
||||
#if (MBEDTLS_VERSION_MAJOR >= 3)
|
||||
if (mbedtls_sha256_starts(&ctx, 0) != 0) {
|
||||
#else
|
||||
if (mbedtls_sha256_starts_ret(&ctx, 0) != 0) {
|
||||
#endif
|
||||
ret_val = -1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
#if (MBEDTLS_VERSION_MAJOR >= 3)
|
||||
if (mbedtls_sha256_update(&ctx, gtk, 16) != 0) {
|
||||
#else
|
||||
if (mbedtls_sha256_update_ret(&ctx, gtk, 16) != 0) {
|
||||
#endif
|
||||
ret_val = -1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
uint8_t output[32];
|
||||
|
||||
#if (MBEDTLS_VERSION_MAJOR >= 3)
|
||||
if (mbedtls_sha256_finish(&ctx, output) != 0) {
|
||||
#else
|
||||
if (mbedtls_sha256_finish_ret(&ctx, output) != 0) {
|
||||
#endif
|
||||
ret_val = -1;
|
||||
goto error;
|
||||
}
|
||||
|
|
|
@ -595,7 +595,7 @@ static void tls_sec_prot_tls_export_keys(void *handle, const uint8_t *master_sec
|
|||
const uint8_t *print_data = eap_tls_key_material;
|
||||
uint16_t print_data_len = 128;
|
||||
while (true) {
|
||||
tr_debug("EAP-TLS key material %s\n", trace_array(print_data, print_data_len > 32 ? 32 : print_data_len));
|
||||
tr_debug("EAP-TLS key material %s", trace_array(print_data, print_data_len > 32 ? 32 : print_data_len));
|
||||
if (print_data_len > 32) {
|
||||
print_data_len -= 32;
|
||||
print_data += 32;
|
||||
|
|
|
@ -18,12 +18,8 @@
|
|||
#include "nsconfig.h"
|
||||
|
||||
#ifdef HAVE_WS
|
||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||
#include "mbedtls/config.h"
|
||||
#else
|
||||
#include MBEDTLS_CONFIG_FILE
|
||||
#endif
|
||||
|
||||
#include "mbedtls/version.h"
|
||||
#if defined(MBEDTLS_SSL_TLS_C) && defined(MBEDTLS_X509_CRT_PARSE_C) && defined(MBEDTLS_SSL_EXPORT_KEYS) /* EXPORT_KEYS not supported by mbedtls baremetal yet */
|
||||
#define WS_MBEDTLS_SECURITY_ENABLED
|
||||
#endif
|
||||
|
@ -49,7 +45,6 @@
|
|||
#include "mbedtls/platform.h"
|
||||
#include "mbedtls/ssl_cookie.h"
|
||||
#include "mbedtls/entropy.h"
|
||||
#include "mbedtls/entropy_poll.h"
|
||||
#include "mbedtls/ctr_drbg.h"
|
||||
#include "mbedtls/ssl_ciphersuites.h"
|
||||
#include "mbedtls/debug.h"
|
||||
|
@ -77,7 +72,9 @@ struct tls_security_s {
|
|||
mbedtls_pk_context pkey; /**< Private key for own certificate */
|
||||
void *handle; /**< Handle provided in callbacks (defined by library user) */
|
||||
bool ext_cert_valid : 1; /**< Extended certificate validation enabled */
|
||||
#if (MBEDTLS_VERSION_MAJOR < 3)
|
||||
tls_sec_prot_lib_crt_verify_cb *crt_verify; /**< Verify function for client/server certificate */
|
||||
#endif
|
||||
tls_sec_prot_lib_send *send; /**< Send callback */
|
||||
tls_sec_prot_lib_receive *receive; /**< Receive callback */
|
||||
tls_sec_prot_lib_export_keys *export_keys; /**< Export keys callback */
|
||||
|
@ -90,12 +87,22 @@ static int tls_sec_prot_lib_ssl_get_timer(void *ctx);
|
|||
static int tls_sec_lib_entropy_poll(void *data, unsigned char *output, size_t len, size_t *olen);
|
||||
static int tls_sec_prot_lib_ssl_send(void *ctx, const unsigned char *buf, size_t len);
|
||||
static int tls_sec_prot_lib_ssl_recv(void *ctx, unsigned char *buf, size_t len);
|
||||
static int tls_sec_prot_lib_ssl_export_keys(void *p_expkey, const unsigned char *ms,
|
||||
#if (MBEDTLS_VERSION_MAJOR >= 3)
|
||||
static void tls_sec_prot_lib_ssl_export_keys(void *p_expkey, mbedtls_ssl_key_export_type type,
|
||||
const unsigned char *secret,
|
||||
size_t secret_len,
|
||||
const unsigned char client_random[32],
|
||||
const unsigned char server_random[32],
|
||||
mbedtls_tls_prf_types tls_prf_type);
|
||||
#else
|
||||
static int tls_sec_prot_lib_ssl_export_keys(void *p_expkey, const unsigned char *secret,
|
||||
const unsigned char *kb, size_t maclen, size_t keylen,
|
||||
size_t ivlen, const unsigned char client_random[32],
|
||||
const unsigned char server_random[32],
|
||||
mbedtls_tls_prf_types tls_prf_type);
|
||||
#endif
|
||||
|
||||
#if (MBEDTLS_VERSION_MAJOR < 3)
|
||||
static int tls_sec_prot_lib_x509_crt_verify(void *ctx, mbedtls_x509_crt *crt, int certificate_depth, uint32_t *flags);
|
||||
static int8_t tls_sec_prot_lib_subject_alternative_name_validate(mbedtls_x509_crt *crt);
|
||||
static int8_t tls_sec_prot_lib_extended_key_usage_validate(mbedtls_x509_crt *crt);
|
||||
|
@ -105,6 +112,7 @@ static int tls_sec_prot_lib_x509_crt_idevid_ldevid_verify(tls_security_t *sec, m
|
|||
#ifdef HAVE_PAE_SUPP
|
||||
static int tls_sec_prot_lib_x509_crt_server_verify(tls_security_t *sec, mbedtls_x509_crt *crt, uint32_t *flags);
|
||||
#endif
|
||||
#endif
|
||||
#ifdef TLS_SEC_PROT_LIB_TLS_DEBUG
|
||||
static void tls_sec_prot_lib_debug(void *ctx, int level, const char *file, int line, const char *string);
|
||||
#endif
|
||||
|
@ -234,7 +242,11 @@ static int tls_sec_prot_lib_configure_certificates(tls_security_t *sec, const se
|
|||
return -1;
|
||||
}
|
||||
|
||||
#if (MBEDTLS_VERSION_MAJOR >= 3)
|
||||
if (mbedtls_pk_parse_key(&sec->pkey, key, key_len, NULL, 0, mbedtls_ctr_drbg_random, &sec->ctr_drbg) < 0) {
|
||||
#else
|
||||
if (mbedtls_pk_parse_key(&sec->pkey, key, key_len, NULL, 0) < 0) {
|
||||
#endif
|
||||
tr_error("Private key parse error");
|
||||
return -1;
|
||||
}
|
||||
|
@ -310,6 +322,7 @@ int8_t tls_sec_prot_lib_connect(tls_security_t *sec, bool is_server, const sec_p
|
|||
return -1;
|
||||
}
|
||||
|
||||
#if (MBEDTLS_VERSION_MAJOR < 3)
|
||||
#ifdef HAVE_PAE_SUPP
|
||||
if (is_server_is_not_set) {
|
||||
sec->crt_verify = tls_sec_prot_lib_x509_crt_server_verify;
|
||||
|
@ -320,7 +333,7 @@ int8_t tls_sec_prot_lib_connect(tls_security_t *sec, bool is_server, const sec_p
|
|||
sec->crt_verify = tls_sec_prot_lib_x509_crt_idevid_ldevid_verify;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
if ((mbedtls_ssl_config_defaults(&sec->conf,
|
||||
is_server_is_set ? MBEDTLS_SSL_IS_SERVER : MBEDTLS_SSL_IS_CLIENT,
|
||||
|
@ -384,7 +397,11 @@ int8_t tls_sec_prot_lib_connect(tls_security_t *sec, bool is_server, const sec_p
|
|||
#endif
|
||||
|
||||
// Export keys callback
|
||||
#if (MBEDTLS_VERSION_MAJOR >= 3)
|
||||
mbedtls_ssl_set_export_keys_cb(&sec->ssl, tls_sec_prot_lib_ssl_export_keys, sec);
|
||||
#else
|
||||
mbedtls_ssl_conf_export_keys_ext_cb(&sec->conf, tls_sec_prot_lib_ssl_export_keys, sec);
|
||||
#endif
|
||||
|
||||
#if !defined(MBEDTLS_SSL_CONF_MIN_MINOR_VER) || !defined(MBEDTLS_SSL_CONF_MIN_MAJOR_VER)
|
||||
mbedtls_ssl_conf_min_version(&sec->conf, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MAJOR_VERSION_3);
|
||||
|
@ -395,7 +412,9 @@ int8_t tls_sec_prot_lib_connect(tls_security_t *sec, bool is_server, const sec_p
|
|||
#endif /* !defined(MBEDTLS_SSL_CONF_MAX_MINOR_VER) || !defined(MBEDTLS_SSL_CONF_MAX_MAJOR_VER) */
|
||||
|
||||
// Set certificate verify callback
|
||||
#if (MBEDTLS_VERSION_MAJOR < 3)
|
||||
mbedtls_ssl_set_verify(&sec->ssl, tls_sec_prot_lib_x509_crt_verify, sec);
|
||||
#endif
|
||||
|
||||
/* Currently assuming we are running fast enough HW that ECC calculations are not blocking any normal operation.
|
||||
*
|
||||
|
@ -432,7 +451,11 @@ int8_t tls_sec_prot_lib_process(tls_security_t *sec)
|
|||
return TLS_SEC_PROT_LIB_ERROR;
|
||||
}
|
||||
|
||||
#if (MBEDTLS_VERSION_MAJOR >= 3)
|
||||
if (sec->ssl.private_state == MBEDTLS_SSL_HANDSHAKE_OVER) {
|
||||
#else
|
||||
if (sec->ssl.state == MBEDTLS_SSL_HANDSHAKE_OVER) {
|
||||
#endif
|
||||
return TLS_SEC_PROT_LIB_HANDSHAKE_OVER;
|
||||
}
|
||||
}
|
||||
|
@ -469,16 +492,31 @@ static int tls_sec_prot_lib_ssl_recv(void *ctx, unsigned char *buf, size_t len)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int tls_sec_prot_lib_ssl_export_keys(void *p_expkey, const unsigned char *ms,
|
||||
#if (MBEDTLS_VERSION_MAJOR >= 3)
|
||||
static void tls_sec_prot_lib_ssl_export_keys(void *p_expkey, mbedtls_ssl_key_export_type type,
|
||||
const unsigned char *secret,
|
||||
size_t secret_len,
|
||||
const unsigned char client_random[32],
|
||||
const unsigned char server_random[32],
|
||||
mbedtls_tls_prf_types tls_prf_type)
|
||||
#else
|
||||
static int tls_sec_prot_lib_ssl_export_keys(void *p_expkey, const unsigned char *secret,
|
||||
const unsigned char *kb, size_t maclen, size_t keylen,
|
||||
size_t ivlen, const unsigned char client_random[32],
|
||||
const unsigned char server_random[32],
|
||||
mbedtls_tls_prf_types tls_prf_type)
|
||||
#endif
|
||||
{
|
||||
#if (MBEDTLS_VERSION_MAJOR >= 3)
|
||||
if (type != MBEDTLS_SSL_KEY_EXPORT_TLS12_MASTER_SECRET || secret_len < 48) {
|
||||
return;
|
||||
}
|
||||
#else
|
||||
(void) kb;
|
||||
(void) maclen;
|
||||
(void) keylen;
|
||||
(void) ivlen;
|
||||
#endif
|
||||
|
||||
tls_security_t *sec = (tls_security_t *)p_expkey;
|
||||
|
||||
|
@ -487,18 +525,24 @@ static int tls_sec_prot_lib_ssl_export_keys(void *p_expkey, const unsigned char
|
|||
memcpy(random, client_random, 32);
|
||||
memcpy(&random[32], server_random, 32);
|
||||
|
||||
int ret = mbedtls_ssl_tls_prf(tls_prf_type, ms, 48, "client EAP encryption",
|
||||
int ret = mbedtls_ssl_tls_prf(tls_prf_type, secret, 48, "client EAP encryption",
|
||||
random, 64, eap_tls_key_material, 128);
|
||||
|
||||
if (ret != 0) {
|
||||
tr_error("key material PRF error");
|
||||
#if (MBEDTLS_VERSION_MAJOR < 3)
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
sec->export_keys(sec->handle, ms, eap_tls_key_material);
|
||||
sec->export_keys(sec->handle, secret, eap_tls_key_material);
|
||||
|
||||
#if (MBEDTLS_VERSION_MAJOR < 3)
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if (MBEDTLS_VERSION_MAJOR < 3)
|
||||
static int tls_sec_prot_lib_x509_crt_verify(void *ctx, mbedtls_x509_crt *crt, int certificate_depth, uint32_t *flags)
|
||||
{
|
||||
tls_security_t *sec = (tls_security_t *) ctx;
|
||||
|
@ -605,6 +649,7 @@ static int tls_sec_prot_lib_x509_crt_server_verify(tls_security_t *sec, mbedtls_
|
|||
return 0;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static int tls_sec_lib_entropy_poll(void *ctx, unsigned char *output, size_t len, size_t *olen)
|
||||
{
|
||||
|
|
|
@ -35,7 +35,7 @@ static bool channel_list_bit_test32(uint32_t word, int_fast8_t bit_number)
|
|||
{
|
||||
bool bitSet;
|
||||
|
||||
if (word & ((uint32_t) 1 << bit_number)) {
|
||||
if (word & (1U << bit_number)) {
|
||||
bitSet = true;
|
||||
} else {
|
||||
bitSet = false;
|
||||
|
@ -92,9 +92,9 @@ void channel_list_set_channel(uint32_t *list, int channel, bool active)
|
|||
return;
|
||||
}
|
||||
if (active) {
|
||||
list[channel / 32] |= (1 << channel % 32);
|
||||
list[channel / 32] |= (1U << channel % 32);
|
||||
} else {
|
||||
list[channel / 32] &= ~(1 << channel % 32);
|
||||
list[channel / 32] &= ~(1U << channel % 32);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -292,7 +292,7 @@ static int32_t fhss_channel_index_from_mask(const uint32_t *channel_mask, int32_
|
|||
int32_t active_channels = 0;
|
||||
// Set channel maks outside excluded channels
|
||||
for (int32_t i = 0; i < number_of_channels; i++) {
|
||||
if (channel_mask[0 + (i / 32)] & (1 << (i % 32))) {
|
||||
if (channel_mask[i / 32] & (1U << (i % 32))) {
|
||||
if (channel_index == active_channels) {
|
||||
return i;
|
||||
}
|
||||
|
|
|
@ -29,12 +29,12 @@ int8_t hmac_md_calc(const alg_hmac_md_e md, const uint8_t *key, uint16_t key_len
|
|||
{
|
||||
#ifdef EXTRA_DEBUG_INFO
|
||||
// Extensive debug for now, to be disabled later
|
||||
tr_debug("hmac_md key %s\n", trace_array(key, key_len));
|
||||
tr_debug("hmac_md key %s", trace_array(key, key_len));
|
||||
|
||||
const uint8_t *print_data = data;
|
||||
uint16_t print_data_len = data_len;
|
||||
while (true) {
|
||||
tr_debug("hmac_md data %s\n", trace_array(print_data, print_data_len > 32 ? 32 : print_data_len));
|
||||
tr_debug("hmac_md data %s", trace_array(print_data, print_data_len > 32 ? 32 : print_data_len));
|
||||
if (print_data_len > 32) {
|
||||
print_data_len -= 32;
|
||||
print_data += 32;
|
||||
|
@ -81,7 +81,7 @@ int8_t hmac_md_calc(const alg_hmac_md_e md, const uint8_t *key, uint16_t key_len
|
|||
memcpy(result, result_value, result_len);
|
||||
|
||||
#ifdef EXTRA_DEBUG_INFO
|
||||
tr_debug("hmac_md result %s\n", trace_array(result_value, 20));
|
||||
tr_debug("hmac_md result %s", trace_array(result_value, 20));
|
||||
#endif
|
||||
return 0;
|
||||
|
||||
|
|
|
@ -349,7 +349,7 @@ int nd_proxy_downstream_interface_register(int8_t interface_id, nd_proxy_req_cb
|
|||
ns_list_foreach(nd_proxy_upstream_list_s, e, &upstream_interface_list) {
|
||||
|
||||
if (proxy_cache_interface_enable_proxy(e->id, interface_id) == 0) {
|
||||
tr_debug("Proxy bridge enabled for interface %i to %i\n", e->id, interface_id);
|
||||
tr_debug("Proxy bridge enabled for interface %i to %i", e->id, interface_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -391,7 +391,7 @@ int nd_proxy_upstream_interface_register(int8_t interface_id, nd_proxy_req_cb *r
|
|||
ns_list_foreach(nd_proxy_downstream_list_s, e, &downstream_interface_list) {
|
||||
|
||||
if (proxy_cache_interface_enable_proxy(interface_id, e->id) == 0) {
|
||||
tr_debug("Proxy bridge enabled for interface %i to %i \n", interface_id, e->id);
|
||||
tr_debug("Proxy bridge enabled for interface %i to %i", interface_id, e->id);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -21,11 +21,7 @@
|
|||
#include "ns_list.h"
|
||||
#include "ns_trace.h"
|
||||
|
||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||
#include "mbedtls/config.h"
|
||||
#else
|
||||
#include MBEDTLS_CONFIG_FILE
|
||||
#endif
|
||||
#include "mbedtls/version.h"
|
||||
|
||||
#if defined(MBEDTLS_NIST_KW_C) && defined(HAVE_WS) && (defined(HAVE_PAE_SUPP) || defined(HAVE_PAE_AUTH))
|
||||
#include "mbedtls/nist_kw.h"
|
||||
|
@ -48,7 +44,7 @@ int8_t nist_aes_key_wrap(uint8_t is_wrap, const uint8_t *key, int16_t key_bits,
|
|||
const uint8_t *print_data = key;
|
||||
uint16_t print_data_len = key_bits / 8;
|
||||
while (true) {
|
||||
tr_debug("nist_aes_key_wrap key %s\n", trace_array(print_data, print_data_len > 32 ? 32 : print_data_len));
|
||||
tr_debug("nist_aes_key_wrap key %s", trace_array(print_data, print_data_len > 32 ? 32 : print_data_len));
|
||||
if (print_data_len > 32) {
|
||||
print_data_len -= 32;
|
||||
print_data += 32;
|
||||
|
@ -60,7 +56,7 @@ int8_t nist_aes_key_wrap(uint8_t is_wrap, const uint8_t *key, int16_t key_bits,
|
|||
print_data = input;
|
||||
print_data_len = input_len;
|
||||
while (true) {
|
||||
tr_debug("nist_aes_key_wrap in %s\n", trace_array(print_data, print_data_len > 32 ? 32 : print_data_len));
|
||||
tr_debug("nist_aes_key_wrap in %s", trace_array(print_data, print_data_len > 32 ? 32 : print_data_len));
|
||||
if (print_data_len > 32) {
|
||||
print_data_len -= 32;
|
||||
print_data += 32;
|
||||
|
@ -95,7 +91,7 @@ int8_t nist_aes_key_wrap(uint8_t is_wrap, const uint8_t *key, int16_t key_bits,
|
|||
print_data = output;
|
||||
print_data_len = *output_len;
|
||||
while (true) {
|
||||
tr_debug("nist_aes_key_wrap out %s\n", trace_array(print_data, print_data_len > 32 ? 32 : print_data_len));
|
||||
tr_debug("nist_aes_key_wrap out %s", trace_array(print_data, print_data_len > 32 ? 32 : print_data_len));
|
||||
if (print_data_len > 32) {
|
||||
print_data_len -= 32;
|
||||
print_data += 32;
|
||||
|
|
|
@ -22,6 +22,9 @@
|
|||
|
||||
static ns_time_api_system_time_callback *system_time_read_callback = NULL;
|
||||
static ns_time_api_system_time_write_callback *system_time_write_callback = NULL;
|
||||
static ns_time_api_time_configuration_notify_callback *system_time_configuration_notify_callback = NULL;
|
||||
|
||||
static bool system_time_acquired = false;
|
||||
|
||||
void ns_time_api_system_time_callback_set(ns_time_api_system_time_callback callback_rd)
|
||||
{
|
||||
|
@ -33,10 +36,16 @@ void ns_time_api_system_time_write_callback_set(ns_time_api_system_time_write_ca
|
|||
system_time_write_callback = callback_wr;
|
||||
}
|
||||
|
||||
void ns_time_api_time_configuration_notify_callback_set(ns_time_api_time_configuration_notify_callback callback_wr)
|
||||
{
|
||||
system_time_configuration_notify_callback = callback_wr;
|
||||
}
|
||||
|
||||
int ns_time_system_time_write(uint64_t time_write)
|
||||
{
|
||||
if (system_time_write_callback) {
|
||||
system_time_write_callback(time_write);
|
||||
system_time_acquired = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -53,3 +62,23 @@ int ns_time_system_time_read(uint64_t *time_read)
|
|||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ns_time_system_timezone_info_notify(timezone_info_t *info_ptr)
|
||||
{
|
||||
if (system_time_configuration_notify_callback && info_ptr) {
|
||||
system_time_configuration_notify_callback(info_ptr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void ns_time_system_time_acquired_set(void)
|
||||
{
|
||||
system_time_acquired = true;
|
||||
}
|
||||
|
||||
bool ns_time_system_time_acquired_get(void)
|
||||
{
|
||||
return system_time_acquired;
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
* \file ns_time.h
|
||||
* \brief Nanostack internal time handling API.
|
||||
*/
|
||||
#include "ns_time_api.h"
|
||||
|
||||
/**
|
||||
* Write new time as a platform time
|
||||
|
@ -51,6 +52,33 @@ int ns_time_system_time_write(uint64_t time_write);
|
|||
*/
|
||||
int ns_time_system_time_read(uint64_t *time_read);
|
||||
|
||||
/**
|
||||
* Notify Time zone and daylight saving time information
|
||||
*
|
||||
* \param info_ptr time zone information pointer.
|
||||
*
|
||||
* \return 0 in success.
|
||||
* \return <0 in case of errors.
|
||||
*
|
||||
*/
|
||||
int ns_time_system_timezone_info_notify(timezone_info_t *info_ptr);
|
||||
|
||||
/**
|
||||
* Set system time acquired
|
||||
*
|
||||
* Sets system time acquired (e.g. has been acquired from network)
|
||||
*
|
||||
*/
|
||||
void ns_time_system_time_acquired_set(void);
|
||||
|
||||
/**
|
||||
* Get system time acquired
|
||||
*
|
||||
* Checks whether system time has been acquired (e.g. has been written)
|
||||
*
|
||||
* \return TRUE system time has been acquired, FALSE system time has not been acquired
|
||||
*
|
||||
*/
|
||||
bool ns_time_system_time_acquired_get(void);
|
||||
|
||||
#endif /* _NS_TIME_H_ */
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Pelion and affiliates.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#define HAVE_WS
|
||||
#define HAVE_WS_HOST
|
||||
#define HAVE_WS_VERSION_1_1
|
||||
#define HAVE_RPL
|
||||
#define HAVE_MPL
|
||||
#define HAVE_6LOWPAN_ND
|
||||
#define HAVE_IPV6_ND
|
||||
#define HAVE_PAE_SUPP
|
||||
#define HAVE_6LOWPAN_ROUTER
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2019, Pelion and affiliates.
|
||||
* Copyright (c) 2019-2021, Pelion and affiliates.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
@ -15,12 +15,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#define HAVE_6LOWPAN_ROUTER
|
||||
#include "cfg_ws_host.h"
|
||||
|
||||
#define HAVE_WS_ROUTER
|
||||
#define HAVE_RPL
|
||||
#define HAVE_IPV6_ND
|
||||
#define HAVE_6LOWPAN_ND
|
||||
#define HAVE_MPL
|
||||
#define HAVE_WS
|
||||
#define HAVE_PAE_SUPP
|
||||
#define HAVE_EAPOL_RELAY
|
||||
|
|
|
@ -32,4 +32,5 @@
|
|||
#define TCP_TEST
|
||||
#define THREAD_THCI_SUPPORT
|
||||
#define HAVE_WS
|
||||
#define HAVE_WS_VERSION_1_1
|
||||
#define MLE_TEST
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Pelion and affiliates.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
#include "base/cfg_ws_host.h"
|
||||
|
||||
#define FEA_TRACE_SUPPORT
|
||||
#define EXTRA_CONSISTENCY_CHECKS
|
||||
|
|
@ -323,16 +323,16 @@ static void ipv6_nd_bootstrap(protocol_interface_info_entry_t *cur)
|
|||
break;
|
||||
|
||||
case IPV6_ROUTER_SOLICATION:
|
||||
tr_debug("Waiting for ICMPv6 Router Advertisement");
|
||||
if (ipv6_nd_rs(cur)) {
|
||||
tr_debug("Waiting for ICMPv6 Router Advertisement");
|
||||
if (cur->ipv6_configure->routerSolicationRetryCounter != ROUTER_SOL_MAX_COUNTER) {
|
||||
cur->ipv6_configure->routerSolicationRetryCounter++;
|
||||
}
|
||||
cur->ipv6_configure->ND_TIMER = (cur->ipv6_configure->routerSolicationRetryCounter * 25);
|
||||
|
||||
} else {
|
||||
cur->ipv6_configure->ND_TIMER = 1;
|
||||
}
|
||||
if (cur->ipv6_configure->routerSolicationRetryCounter == 0) {
|
||||
cur->ipv6_configure->routerSolicationRetryCounter++;
|
||||
}
|
||||
cur->ipv6_configure->ND_TIMER = (cur->ipv6_configure->routerSolicationRetryCounter * 25);
|
||||
break;
|
||||
|
||||
case IPV6_GP_GEN:
|
||||
|
|
|
@ -137,7 +137,7 @@ uint8_t *net_vendor_option_current_time_read(uint8_t *ptr, uint16_t length, int3
|
|||
}
|
||||
|
||||
option_len = common_read_16_bit(ptr + 2);
|
||||
ptr += 4;
|
||||
ptr += 2 * sizeof(uint16_t);
|
||||
|
||||
if (option_len < 3 * sizeof(uint32_t)) {
|
||||
// Corrupted as not enough room for fields
|
||||
|
@ -147,11 +147,70 @@ uint8_t *net_vendor_option_current_time_read(uint8_t *ptr, uint16_t length, int3
|
|||
if (era) {
|
||||
*era = (int32_t)common_read_32_bit(ptr);
|
||||
}
|
||||
|
||||
if (offset) {
|
||||
*offset = common_read_32_bit(ptr + sizeof(uint32_t));
|
||||
}
|
||||
|
||||
if (fraction) {
|
||||
*fraction = common_read_32_bit(ptr + 2 * sizeof(uint32_t));
|
||||
*fraction = common_read_32_bit(ptr + sizeof(uint32_t) + sizeof(uint32_t));
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
uint16_t net_vendor_option_time_configuration_length(void)
|
||||
{
|
||||
return 4 + 1 * sizeof(uint64_t) + 2 * sizeof(int16_t) + 1 * sizeof(uint16_t);
|
||||
}
|
||||
|
||||
uint8_t *net_vendor_option_time_configuration_write(uint8_t *ptr, uint64_t timestamp, int16_t timezone, int16_t deviation, uint16_t status)
|
||||
{
|
||||
|
||||
ptr = common_write_16_bit(ARM_DHCP_VENDOR_DATA_TIME_CONFIGURATION, ptr);
|
||||
ptr = common_write_16_bit(1 * sizeof(uint64_t) + 2 * sizeof(int16_t) + 1 * sizeof(uint16_t), ptr);
|
||||
ptr = common_write_16_bit(status, ptr);
|
||||
ptr = common_write_64_bit(timestamp, ptr);
|
||||
ptr = common_write_16_bit((uint16_t)deviation, ptr);
|
||||
ptr = common_write_16_bit((uint16_t)timezone, ptr);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
uint8_t *net_vendor_option_time_configuration_read(uint8_t *ptr, uint16_t length, uint64_t *timestamp, int16_t *timezone, int16_t *deviation, uint16_t *status)
|
||||
{
|
||||
uint16_t option_len;
|
||||
|
||||
if (length < net_vendor_option_time_configuration_length()) {
|
||||
// Corrupted as there is no room for all fields
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (common_read_16_bit(ptr) != ARM_DHCP_VENDOR_DATA_TIME_CONFIGURATION) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
option_len = common_read_16_bit(ptr + sizeof(uint16_t));
|
||||
ptr += 2 * sizeof(uint16_t);
|
||||
|
||||
if (option_len < 1 * sizeof(uint64_t) + 2 * sizeof(int16_t) + 1 * sizeof(uint16_t)) {
|
||||
// Corrupted as not enough room for fields
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (status) {
|
||||
*status = (uint16_t)common_read_16_bit(ptr);
|
||||
}
|
||||
|
||||
if (timestamp) {
|
||||
*timestamp = common_read_64_bit(ptr + sizeof(uint16_t));
|
||||
}
|
||||
|
||||
if (deviation) {
|
||||
*deviation = (int16_t)common_read_16_bit(ptr + sizeof(uint16_t) + sizeof(uint64_t));
|
||||
}
|
||||
|
||||
if (timezone) {
|
||||
*timezone = (int16_t)common_read_16_bit(ptr + sizeof(uint16_t) + sizeof(uint64_t) + sizeof(uint16_t));
|
||||
}
|
||||
|
||||
return ptr;
|
||||
|
|
|
@ -66,6 +66,17 @@
|
|||
* */
|
||||
#define ARM_DHCP_VENDOR_DATA_NETWORK_TIME 298
|
||||
|
||||
/* ARM Defined vendor data option to distribute Time configuration
|
||||
*
|
||||
* uint16_t status Bit field for status
|
||||
* bit 1 Daylight saving time status 0 = false 1 = true
|
||||
* Additional bits reserved for future and are ignored on receive
|
||||
* uint64_t timestamp Time stamp of the Daylight saving time change
|
||||
* int16_t deviation Change that is applied when time stamp is reached
|
||||
* int16_t timezone Time zone information in minutes compared to UTC time
|
||||
*/
|
||||
#define ARM_DHCP_VENDOR_DATA_TIME_CONFIGURATION 299
|
||||
|
||||
/* DHCPv6 vendor options to distribute ARM vendor data*/
|
||||
|
||||
uint16_t net_dns_option_vendor_option_data_dns_query_length(char *domain);
|
||||
|
@ -78,5 +89,8 @@ uint16_t net_vendor_option_current_time_length(void);
|
|||
uint8_t *net_vendor_option_current_time_write(uint8_t *ptr, int32_t era, uint32_t offset, uint32_t fraction);
|
||||
uint8_t *net_vendor_option_current_time_read(uint8_t *ptr, uint16_t length, int32_t *era, uint32_t *offset, uint32_t *fraction);
|
||||
|
||||
uint16_t net_vendor_option_time_configuration_length(void);
|
||||
uint8_t *net_vendor_option_time_configuration_write(uint8_t *ptr, uint64_t timestamp, int16_t timezone, int16_t deviation, uint16_t status);
|
||||
uint8_t *net_vendor_option_time_configuration_read(uint8_t *ptr, uint16_t length, uint64_t *timestamp, int16_t *timezone, int16_t *deviation, uint16_t *status);
|
||||
|
||||
#endif /* LIBDHCPV6_VENDOR_DATA_H_ */
|
||||
|
|
|
@ -67,7 +67,7 @@
|
|||
#include "6LoWPAN/Thread/thread_routing.h"
|
||||
#include "6LoWPAN/Thread/thread_bootstrap.h"
|
||||
#include "6LoWPAN/Thread/thread_management_internal.h"
|
||||
#include "6LoWPAN/ws/ws_bootstrap.h"
|
||||
#include "6LoWPAN/ws/ws_common.h"
|
||||
#ifdef HAVE_WS
|
||||
#include "6LoWPAN/ws/ws_pae_controller.h"
|
||||
#endif
|
||||
|
@ -168,7 +168,7 @@ int8_t arm_net_nwk_scan(int8_t interface_id, channel_list_s *scan_list, void (*p
|
|||
if (cur->lowpan_info & INTERFACE_NWK_ACTIVE) {
|
||||
ret_val = -1;
|
||||
} else if (arm_channel_list_validation(scan_list)) {
|
||||
tr_debug("Given channel mask is empty!\n");
|
||||
tr_debug("Given channel mask is empty!");
|
||||
ret_val = -2;
|
||||
} else {
|
||||
nwk_scan_params_t *scan_params = &cur->mac_parameters->nwk_scan_params;
|
||||
|
@ -768,7 +768,7 @@ static int arm_net_channel_bit_mask_to_number(const uint32_t *channel_mask)
|
|||
|
||||
for (j = 0; j < 8; j++) {
|
||||
for (i = 0; i < 32; i++) {
|
||||
if (channel_mask[j] & ((uint32_t)1 << i)) {
|
||||
if (channel_mask[j] & (1U << i)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -804,7 +804,7 @@ int8_t arm_nwk_interface_network_driver_set(int8_t interface_id, const channel_l
|
|||
protocol_interface_info_entry_t *cur = 0;
|
||||
|
||||
if (arm_channel_list_validation(nwk_channel_list)) {
|
||||
tr_debug("Given channel mask is empty!\n");
|
||||
tr_debug("Given channel mask is empty!");
|
||||
return -5;
|
||||
}
|
||||
|
||||
|
@ -981,15 +981,21 @@ int8_t arm_nwk_link_layer_security_mode(int8_t interface_id, net_6lowpan_link_la
|
|||
|
||||
int8_t arm_network_certificate_chain_set(const arm_certificate_chain_entry_s *chain_info)
|
||||
{
|
||||
int8_t ret = -2;
|
||||
|
||||
#if !defined(PANA) && !defined(HAVE_WS)
|
||||
(void)chain_info;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_WS
|
||||
ws_pae_controller_certificate_chain_set(chain_info);
|
||||
ret = ws_pae_controller_certificate_chain_set(chain_info);
|
||||
#endif
|
||||
|
||||
return pana_interface_certificate_chain_set(chain_info);
|
||||
#ifdef PANA
|
||||
ret = pana_interface_certificate_chain_set(chain_info);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int8_t arm_network_trusted_certificate_add(const arm_certificate_entry_s *cert)
|
||||
|
@ -1207,7 +1213,7 @@ int8_t arm_nwk_interface_configure_6lowpan_bootstrap_set(int8_t interface_id, ne
|
|||
if (net_6lowpan_mode_extension == NET_6LOWPAN_THREAD) {
|
||||
ret_val = thread_node_bootstrap_init(interface_id, bootstrap_mode);
|
||||
} else if (net_6lowpan_mode_extension == NET_6LOWPAN_WS) {
|
||||
ret_val = ws_bootstrap_init(interface_id, bootstrap_mode);
|
||||
ret_val = ws_common_init(interface_id, bootstrap_mode);
|
||||
} else {
|
||||
ret_val = arm_6lowpan_bootstarp_bootstrap_set(interface_id, bootstrap_mode, net_6lowpan_mode_extension);
|
||||
}
|
||||
|
@ -1226,7 +1232,7 @@ int8_t arm_nwk_set_channel_list(int8_t interface_id, const channel_list_s *nwk_c
|
|||
}
|
||||
|
||||
if (arm_channel_list_validation(nwk_channel_list)) {
|
||||
tr_debug("Given channel mask is empty!\n");
|
||||
tr_debug("Given channel mask is empty!");
|
||||
return -2;
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,9 @@ SRCS += \
|
|||
source/6LoWPAN/ws/ws_mpx_header.c \
|
||||
source/6LoWPAN/ws/ws_neighbor_class.c \
|
||||
source/6LoWPAN/ws/ws_bootstrap.c \
|
||||
source/6LoWPAN/ws/ws_bootstrap_6lbr.c \
|
||||
source/6LoWPAN/ws/ws_bootstrap_ffn.c \
|
||||
source/6LoWPAN/ws/ws_bootstrap_lfn.c \
|
||||
source/6LoWPAN/ws/ws_common.c \
|
||||
source/6LoWPAN/ws/ws_management_api.c \
|
||||
source/6LoWPAN/ws/ws_bbr_api.c \
|
||||
|
@ -43,6 +46,7 @@ SRCS += \
|
|||
source/6LoWPAN/ws/ws_eapol_pdu.c \
|
||||
source/6LoWPAN/ws/ws_stats.c \
|
||||
source/6LoWPAN/ws/ws_cfg_settings.c \
|
||||
source/6LoWPAN/ws/ws_phy.c \
|
||||
source/BorderRouter/border_router.c \
|
||||
source/Common_Protocols/icmpv6.c \
|
||||
source/Common_Protocols/icmpv6_prefix.c \
|
||||
|
@ -83,6 +87,7 @@ SRCS += \
|
|||
source/MAC/IEEE802_15_4/sw_mac.c \
|
||||
source/MAC/IEEE802_15_4/mac_fhss_callbacks.c \
|
||||
source/MAC/IEEE802_15_4/mac_cca_threshold.c \
|
||||
source/MAC/IEEE802_15_4/mac_mode_switch.c \
|
||||
source/MAC/ethernet/ethernet_mac_api.c \
|
||||
source/MAC/serial/serial_mac_api.c \
|
||||
source/MAC/virtual_rf/virtual_rf_client.c \
|
||||
|
|
Loading…
Reference in New Issue