mirror of https://github.com/ARMmbed/mbed-os.git
Squashed 'features/nanostack/sal-stack-nanostack/' changes from 4a3c5c525b..225a4af94f
225a4af94f Remove files from tests folder 58d2c8fa82 Merge remote-tracking branch 'origin/release_internal' into release_external 921b4b3273 Wi-SUN FAN 1.1 dynamic MDR data request enabler b8722e81b1 Corrected BR removing of waiting list entry when supplicant is in key storage 0d54d7ab39 Adjust trace levels (#2692) 681d9eae8d Added reset for pan id and version to BR network start 30d4fb2ed9 Renaming and cleaning ws bootstrap (#2688) e0da19dbf0 Add Wi-SUN host configuration (#2690) 50ecc3d0f0 Refactoring Wi-SUN stack (#2686) 9d2386d484 Renamed operation mode to operating mode. 2f755bcfdb RF config resolver and some refactoring (#2683) 86c6d19e06 Fixed WS IE PCAP read operation wrong length usage. cd3a4c2a62 Config: Remove additional HAVE_WS_ROUTER (#2684) cdd7f2d868 Added API for configure supported Phy capability. a00a3c0a02 Wi-SUN FAN 1.1 PCAP IE update 2d063d3b4a Moved State machine and timer functions to own files edb8bec609 Corrected system time check function return values 85358a635b Moved Wi-SUN Bootstrap Event handling to separate device handlers 61cbdde485 MAC to support mode switch on single channel (#2678) 1006d29e4d Added storing of PAN ID to NVM in BBR 7bf0028c66 Corrected system time jump detection on BR startup e60974d815 Split Wi-SUN bootstrap to device types a3f341266e MAC data req: API to support mode switch (#2674) cad5122a90 Removed automatic network size configuration (#2673) 35d313224a MAC: Callback set to resolve PHY mode ID (#2672) 0c5faca469 Added support for large system time changes (e.g. due to NTP) (#2670) c94b306431 LFN version and LGTK Hash IE advertisment and learn 8e075119f6 Use FAN version constant instead of pure number a5566b22b2 Channel Plan 2 validation and FAN 1.0 reject 42dba4151e Wi-Sun IE FAN 1.1 update 1d56070c24 EU channel plan ids (FAN 1.1) supported (#2668) fc4f41fb30 Add test API empty function 37efc7ec25 Add version 1.1 basic support e1558fbb1a Implemented mode switch PHR build and parse (#2665) cbd8a15d31 Corrected frame counter storing threshold check 37f7ae95eb Time configuration distribution using DHCPv6 vendor data 7415bc724b Added checks for Border Router frame counter space exhaustion (#2660) f1a65ecbe8 Mode switch PHY API (#2663) e54231b5d4 Do not check buffer age when virtual RF driver used (#2662) cc8c7bd38f arm_network_certificate_chain_set() returns -2 when PANA is disabled 319dd91bce Fix dubious semicolon in #define 2ff51abeca Remove extra '\n' in traces 19376c8837 Simplify array indexes c808661836 Fix ASAN warnings about overflows in bit shifts f998008f60 Fix use-after-free in mac_helper_coordinator_address_set() 4d04541d70 Wi-SUN header and Paylod IE element lenght future proof update. 935898badf Medium network PAN_TIMEOUT changed to 30 minutes 1af7cfeb24 Updated nanostack to be compatible with mbed TLS 3.0 (#2657) 29744e0e46 If Router Solicitation creation fails no longer tries to retry the RS right away (#2655) 2b889e92b0 Added automatic test procedure triggering during bootstrap ed9eb0503f GTKs are removed only when fresh GTK hash is received 81ecdc24f8 Added empty function for test procedure trigger 14439b4aa9 Added support for triggering test procedures b8a67a9e36 Update CHANGELOG.md for Nanostack 14.0.0 (#2649) git-subtree-dir: features/nanostack/sal-stack-nanostack git-subtree-split: 225a4af94f3faf5ca3726e86bc96cdda4c99a469pull/15101/head
parent
4e7dfcabb5
commit
6c5b7401d4
|
@ -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