Merge commit '185db1333ed41be03e3a565e0f0171cad90857a1'

* commit '185db1333ed41be03e3a565e0f0171cad90857a1':
  Squashed 'features/nanostack/sal-stack-nanostack/' changes from fb7413b846..89a497a386
pull/12754/head
Arto Kinnunen 2020-04-03 14:57:23 +03:00
commit 6275f710bf
79 changed files with 4197 additions and 1029 deletions

View File

@ -116,9 +116,12 @@ typedef struct fhss_ws_configuration {
/** Broadcast fixed channel */
uint8_t broadcast_fixed_channel;
/** Channel mask. */
/** Channel mask. Wi-SUN will use this for broadcast */
uint32_t channel_mask[8];
/** Wi-SUN specific unicast channel mask */
uint32_t unicast_channel_mask[8];
/** Vendor defined channel function. */
fhss_vendor_defined_cf *vendor_defined_cf;

View File

@ -30,6 +30,14 @@
extern "C" {
#endif
/**
* @brief ws_channel_mask_t WS neighbour supported channel mask
*/
typedef struct ws_channel_mask {
uint16_t channel_count; /**<active channels at mask */
uint32_t channel_mask[8]; /**< Supported channels */
} ws_channel_mask_t;
/**
* @brief unicast_timing_info Unicast timing/hopping schedule information structure.
*/
@ -64,6 +72,7 @@ typedef struct fhss_ws_neighbor_timing_info {
uint8_t timing_accuracy; /**< Neighbor timing accuracy */
unicast_timing_info_t uc_timing_info; /**< Neighbor unicast timing info */
broadcast_timing_info_t bc_timing_info; /**< Neighbor broadcast timing info */
ws_channel_mask_t uc_channel_list; /**< Neighbor Unicast channel list */
uint32_t *excluded_channels; /**< Neighbor excluded channels (bit mask) */
} fhss_ws_neighbor_timing_info_t;

View File

@ -43,6 +43,7 @@
#define MAC_IEEE_802_15_4_MIN_MPDU_OVERHEAD 9 /**< Minimum overhead added by MAC to MPDU */
#define MAC_IEEE_802_15_4_MAX_BEACON_OVERHEAD 75 /**< Maximum overhead which is added by the MAC for beacon */
#define MAC_IEEE_802_15_4_MAX_PHY_PACKET_SIZE 127 /**< Maximum number of octets PHY layer is able to receive */
#define MAC_IEEE_802_15_4G_MAX_PHY_PACKET_SIZE 2047 /**< Maximum number of octets PHY layer is able to receive */
#define MAC_IEEE_802_15_4_MAX_BEACON_PAYLOAD_LENGTH \
(MAC_IEEE_802_15_4_MAX_PHY_PACKET_SIZE - MAC_IEEE_802_15_4_MAX_BEACON_OVERHEAD) /**< Maximum size of beacon payload */

View File

@ -264,6 +264,7 @@ typedef enum {
macAutoRequestKeyIndex = 0x7b, /*<The index of the key used for automatic data*/
macDefaultKeySource = 0x7c, /*<Default key source*/
//NON standard extension
mac802_15_4Mode = 0xf6, /*<IEEE 802.15.4 mode*/
macDeviceDescriptionPanIDUpdate = 0xf7, /*<Thread pending link update case this will update device descrioton list pan-id to new one*/
macTXPower = 0xf8, /*<TX output power*/
macCCAThreshold = 0xf9, /*<CCA threshold*/

View File

@ -79,7 +79,8 @@ typedef enum {
PHY_EXTENSION_SET_RF_CONFIGURATION, /**< Set RF configuration using phy_rf_channel_configuration_s structure */
PHY_EXTENSION_FILTERING_SUPPORT, /**< Return filtering modes that can be supported by the PHY driver. See phy_link_filters_e */
PHY_EXTENSION_SET_TX_POWER, /**< Set TX output power which is given as percentage of maximum. 0 is the lowest possible TX power and 100 is the highest possible TX power */
PHY_EXTENSION_SET_CCA_THRESHOLD /**< Set CCA threshold which is given as percentage of maximum threshold. 0 is the lowest(strictest) possible threshold and 100 is the highest possible threshold */
PHY_EXTENSION_SET_CCA_THRESHOLD, /**< Set CCA threshold which is given as percentage of maximum threshold. 0 is the lowest(strictest) possible threshold and 100 is the highest possible threshold */
PHY_EXTENSION_SET_802_15_4_MODE /**< Set IEEE 802.15.4 mode as defined by phy_802_15_4_mode_t*/
} phy_extension_type_e;
/** Address types */
@ -172,6 +173,15 @@ typedef enum {
MODULATION_INDEX_UNDEFINED ///< Modulation index undefined
} phy_modulation_index_e;
/**
* @brief enum phy_802_15_4_mode_t IEEE 802.15.4 mode
*
*/
typedef enum {
IEEE_802_15_4_2011, /**<IEEE 802.15.4-2011*/
IEEE_802_15_4G_2012 /**<IEEE 802.15.4g-2012*/
} phy_802_15_4_mode_t;
/** Channel configuration */
typedef struct phy_rf_channel_configuration_s {
uint32_t channel_0_center_frequency; ///< Center frequency

View File

@ -694,27 +694,29 @@ static inline int8_t socket_read_session_address(int8_t socket, ns_address_t *ad
*
* IPv6 socket options summary
*
* | opt_name / cmsg_type | Data type | set/getsockopt | sendmsg | recvmsg |
* | :--------------------------: | :--------------: | :-------------: | :-----: | :-------------------------------: |
* | SOCKET_IPV6_TCLASS | int16_t | Yes | Yes | If enabled with RECVTCLASS |
* | SOCKET_IPV6_UNICAST_HOPS | int16_t | Yes | No | No |
* | SOCKET_IPV6_MULTICAST_HOPS | int16_t | Yes | No | No |
* | SOCKET_IPV6_ADDR_PREFERENCES | int | Yes | No | No |
* | SOCKET_IPV6_USE_MIN_MTU | int8_t | Yes | Yes | No |
* | SOCKET_IPV6_DONTFRAG | int8_t | Yes | Yes | No |
* | SOCKET_IPV6_FLOW_LABEL | int32_t | Yes | No | No |
* | SOCKET_IPV6_HOPLIMIT | int16_t | No | Yes | If enabled with RECVHOPLIMIT |
* | SOCKET_IPV6_PKTINFO | ns_in6_pktinfo_t | No | Yes | If enabled with RECVPKTINFO |
* | SOCKET_IPV6_RECVPKTINFO | bool | Yes | No | No |
* | SOCKET_IPV6_RECVHOPLIMIT | bool | Yes | No | No |
* | SOCKET_IPV6_RECVTCLASS | bool | Yes | No | No |
* | SOCKET_IPV6_MULTICAST_IF | int8_t | Yes | No | No |
* | SOCKET_IPV6_MULTICAST_LOOP | bool | Yes | Yes | No |
* | SOCKET_IPV6_JOIN_GROUP | ns_ipv6_mreq_t | Set only | No | No |
* | SOCKET_IPV6_LEAVE_GROUP | ns_ipv6_mreq_t | Set only | No | No |
* | SOCKET_BROADCAST_PAN | int8_t | Yes | No | No |
* | SOCKET_LINK_LAYER_SECURITY | int8_t | Yes | No | No |
* | SOCKET_INTERFACE_SELECT | int8_t | Yes | No | No |
* | opt_name / cmsg_type | Data type | set/getsockopt | sendmsg | recvmsg |
* | :--------------------------: | :---------- ----: | :-------------: | :-----: | :-------------------------------: |
* | SOCKET_IPV6_TCLASS | int16_t | Yes | Yes | If enabled with RECVTCLASS |
* | SOCKET_IPV6_UNICAST_HOPS | int16_t | Yes | No | No |
* | SOCKET_IPV6_MULTICAST_HOPS | int16_t | Yes | No | No |
* | SOCKET_IPV6_ADDR_PREFERENCES | int | Yes | No | No |
* | SOCKET_IPV6_USE_MIN_MTU | int8_t | Yes | Yes | No |
* | SOCKET_IPV6_DONTFRAG | int8_t | Yes | Yes | No |
* | SOCKET_IPV6_FLOW_LABEL | int32_t | Yes | No | No |
* | SOCKET_IPV6_HOPLIMIT | int16_t | No | Yes | If enabled with RECVHOPLIMIT |
* | SOCKET_IPV6_PKTINFO | ns_in6_pktinfo_t | No | Yes | If enabled with RECVPKTINFO |
* | SOCKET_IPV6_RECVPKTINFO | bool | Yes | No | No |
* | SOCKET_IPV6_RECVHOPLIMIT | bool | Yes | No | No |
* | SOCKET_IPV6_RECVTCLASS | bool | Yes | No | No |
* | SOCKET_IPV6_MULTICAST_IF | int8_t | Yes | No | No |
* | SOCKET_IPV6_MULTICAST_LOOP | bool | Yes | Yes | No |
* | SOCKET_IPV6_JOIN_GROUP | ns_ipv6_mreq_t | Set only | No | No |
* | SOCKET_IPV6_LEAVE_GROUP | ns_ipv6_mreq_t | Set only | No | No |
* | SOCKET_BROADCAST_PAN | int8_t | Yes | No | No |
* | SOCKET_LINK_LAYER_SECURITY | int8_t | Yes | No | No |
* | SOCKET_INTERFACE_SELECT | int8_t | Yes | No | No |
* | SOCKET_LATENCY | ns_ipv6_latency_t | Get only | No | No |
* | SOCKET_STAGGER | ns_ipv6_stagger_t | Get only | No | No |
*
*/
@ -753,6 +755,10 @@ static inline int8_t socket_read_session_address(int8_t socket, ns_address_t *ad
#define SOCKET_IPV6_JOIN_GROUP 15
/** Leave a multicast group, using ns_ipv6_mreq_t */
#define SOCKET_IPV6_LEAVE_GROUP 16
/** Read estimated latency to reach destination */
#define SOCKET_LATENCY 17
/** Read estimated stagger value that can be used as initial delay after bootstrap or firmware update. */
#define SOCKET_STAGGER 18
#define SOCKET_BROADCAST_PAN 0xfc /**< Internal use - transmit with IEEE 802.15.4 broadcast PAN ID */
#define SOCKET_LINK_LAYER_SECURITY 0xfd /**< Not standard enable or disable socket security at link layer (For 802.15.4). */
@ -765,6 +771,20 @@ typedef struct ns_ipv6_mreq {
int8_t ipv6mr_interface; /**< interface id */
} ns_ipv6_mreq_t;
/** Latency request used for getsockopt() */
typedef struct {
uint8_t dest_addr[16]; /**< [IN] IPv6 destination address */
uint32_t latency; /**< [OUT] estimated latency value in milliseconds */
} ns_ipv6_latency_t;
/** Stagger request used for getsockopt() */
typedef struct {
uint8_t dest_addr[16]; /**< [IN] IPv6 destination address */
uint16_t data_amount; /**< [IN] Amount of data in kilobytes */
uint16_t stagger_min; /**< [OUT] Minimum stagger value in seconds */
uint16_t stagger_max; /**< [OUT] Maximum stagger value in seconds */
uint16_t stagger_rand; /**< [OUT] Randomized stagger value in seconds */
} ns_ipv6_stagger_t;
/**
* \brief Set an option for a socket
*
@ -804,6 +824,7 @@ int8_t socket_setsockopt(int8_t socket, uint8_t level, uint8_t opt_name, const v
* \return 0 on success.
* \return -1 invalid socket ID.
* \return -2 invalid/unsupported option.
* \return -3 data can't be retrieved.
*/
int8_t socket_getsockopt(int8_t socket, uint8_t level, uint8_t opt_name, void *opt_value, uint16_t *opt_len);

View File

@ -52,6 +52,7 @@ int ws_bbr_start(int8_t interface_id, int8_t backbone_interface_id);
#define BBR_GUA_ROUTE 0x0002 /**< More specific route is added for GUA prefix */
#define BBR_BB_WAIT 0x0004 /**< Wait backbone availability before starting Wi-SUN network */
#define BBR_DEFAULT_ROUTE 0x0008 /**< Add default route parameter to DIO */
#define BBR_REQUIRE_DAO_REFRESH 0x0010 /**< Do not increment PAN version number when active forces DAO update from nodes*/
/**
* Configure border router features.
@ -158,4 +159,88 @@ int ws_bbr_eapol_node_limit_set(int8_t interface_id, uint16_t limit);
*/
int ws_bbr_ext_certificate_validation_set(int8_t interface_id, uint8_t validation);
/**
* Sets RPL parameters
*
* Sets RPL DIO trickle parameters.
*
* \param interface_id Network interface ID.
* \param dio_interval_min DIO trickle timer Imin parameter.
* \param dio_interval_doublings DIO trickle timer Imax parameter as doublings of Imin
* \param dio_redundancy_constant DIO trickle timer redundancy constant.
*
* \return 0, RPL parameters set.
* \return <0 Node RPL parameters set failed.
*/
int ws_bbr_rpl_parameters_set(int8_t interface_id, uint8_t dio_interval_min, uint8_t dio_interval_doublings, uint8_t dio_redundancy_constant);
/**
* Gets RPL parameters
*
* Gets RPL DIO trickle parameters.
*
* \param interface_id Network interface ID.
* \param dio_interval_min DIO trickle timer Imin parameter.
* \param dio_interval_doublings DIO trickle timer Imax parameter as doublings of Imin
* \param dio_redundancy_constant DIO trickle timer redundancy constant.
*
* \return 0, RPL parameters get.
* \return <0 Node RPL parameters get failed.
*/
int ws_bbr_rpl_parameters_get(int8_t interface_id, uint8_t *dio_interval_min, uint8_t *dio_interval_doublings, uint8_t *dio_redundancy_constant);
/**
* Validate RPL parameters
*
* Validates RPL DIO trickle parameters.
*
* \param interface_id Network interface ID.
* \param dio_interval_min DIO trickle timer Imin parameter.
* \param dio_interval_doublings DIO trickle timer Imax parameter as doublings of Imin
* \param dio_redundancy_constant DIO trickle timer redundancy constant.
*
* \return 0, RPL parameters validated.
* \return <0 Node RPL parameters validation failed.
*/
int ws_bbr_rpl_parameters_validate(int8_t interface_id, uint8_t dio_interval_min, uint8_t dio_interval_doublings, uint8_t dio_redundancy_constant);
/**
* Sets PAN configuration
*
* Sets PAN configuration parameters.
*
* \param interface_id Network interface ID.
* \param pan_id PAN ID; 0xffff default, generate the PAN ID.
*
* \return 0, PAN configuration set.
* \return <0 PAN configuration set failed.
*/
int ws_bbr_pan_configuration_set(int8_t interface_id, uint16_t pan_id);
/**
* Gets PAN configuration
*
* Gets PAN configuration parameters.
*
* \param interface_id Network interface ID.
* \param pan_id PAN ID; 0xffff default
*
* \return 0, PAN configuration get.
* \return <0 PAN configuration get failed.
*/
int ws_bbr_pan_configuration_get(int8_t interface_id, uint16_t *pan_id);
/**
* Validates PAN configuration
*
* Validates PAN configuration parameters.
*
* \param interface_id Network interface ID.
* \param pan_id PAN ID.
*
* \return 0, PAN configuration validated.
* \return <0 PAN configuration validation failed.
*/
int ws_bbr_pan_configuration_validate(int8_t interface_id, uint16_t pan_id);
#endif /* WS_BBR_API_H_ */

View File

@ -75,12 +75,11 @@ extern "C" {
#define CHANNEL_SPACING_100 0x03 // 100 khz
#define CHANNEL_SPACING_250 0x04 // 250 khz
#define NETWORK_SIZE_AUTOMATIC 0x00
#define NETWORK_SIZE_SMALL 0x01
#define NETWORK_SIZE_MEDIUM 0x08
#define NETWORK_SIZE_LARGE 0x10
#define NETWORK_SIZE_CERTIFICATE 0xFF
#define NETWORK_SIZE_CERTIFICATE 0x00
#define NETWORK_SIZE_SMALL 0x01
#define NETWORK_SIZE_MEDIUM 0x08
#define NETWORK_SIZE_LARGE 0x10
#define NETWORK_SIZE_AUTOMATIC 0xFF
/** Temporary API change flag. this will be removed when new version of API is implemented on applications
*
@ -132,22 +131,55 @@ int ws_management_network_name_set(
int8_t interface_id,
char *network_name_ptr);
/**
* Get the network name
*
* \param interface_id Network interface ID.
* \param network_name_ptr Nul terminated Network name limited to 32 characters.
*
* \return 0, OK.
* \return <0 Fail.
*/
int ws_management_network_name_get(
int8_t interface_id,
char *network_name_ptr);
/**
* Validate the network name
*
* \param interface_id Network interface ID.
* \param network_name_ptr Nul terminated Network name limited to 32 characters.
*
* \return 0, OK.
* \return <0 Fail.
*/
int ws_management_network_name_validate(
int8_t interface_id,
char *network_name_ptr);
/**
* Configure regulatory domain of Wi-SUN stack.
*
* Change the default configuration for Wi-SUN PHY operation.
*
* Supported values:
* Domain: "NA"(0x01), "KR"(0x09)
* Operating class: (1), (2)
* operation mode: "1b" (symbol rate 50, modulation index 1)
* Domain: "NA"(0x01), "KR"(0x09), "EU"(0x03), "IN"(0x05), "KR"(0x09), "JP"(0x09), "WW"(0x00)
* Operating class: (1), (2), (3), (4)
* Operation mode: "1a" (symbol rate 50, modulation index 0.5)
* "1b" (symbol rate 50, modulation index 1.0)
* "2a" (symbol rate 100, modulation index 0.5)
* "2b" (symbol rate 100, modulation index 1.0)
* "3" (symbol rate 150, modulation index 0.5)
* "4a" (symbol rate 200, modulation index 0.5)
* "4b" (symbol rate 200, modulation index 1.0)
* "5" (symbol rate 300, modulation index 0.5)
*
* if value of 255 is given then previous value is used.
*
* \param interface_id Network interface ID.
* \param regulatory_domain FHSS regulatory domain default to "KR" 0x09.
* \param operating_class FHSS operating class default to 1.
* \param operating_mode FHSS phy operating mode default to "1b".
* \param regulatory_domain FHSS regulatory domain. Default to "EU" 0x03.
* \param operating_class FHSS operating class. Default to 2.
* \param operating_mode FHSS phy operating mode. Default to "3".
*
* \return 0, Init OK.
* \return <0 Init fail.
@ -158,19 +190,61 @@ int ws_management_regulatory_domain_set(
uint8_t operating_class,
uint8_t operating_mode);
/**
* Get regulatory domain of Wi-SUN stack.
*
* \param interface_id Network interface ID.
* \param regulatory_domain FHSS regulatory domain.
* \param operating_class FHSS operating class.
* \param operating_mode FHSS phy operating mode.
*
* \return 0, OK.
* \return <0 Fail.
*/
int ws_management_regulatory_domain_get(
int8_t interface_id,
uint8_t *regulatory_domain,
uint8_t *operating_class,
uint8_t *operating_mode);
/**
* Validate regulatory domain of Wi-SUN stack.
*
* \param interface_id Network interface ID.
* \param regulatory_domain FHSS regulatory domain.
* \param operating_class FHSS operating class.
* \param operating_mode FHSS phy operating mode.
*
* \return 0, OK.
* \return <0 Fail.
*/
int ws_management_regulatory_domain_validate(
int8_t interface_id,
uint8_t regulatory_domain,
uint8_t operating_class,
uint8_t operating_mode);
/**
* Set timing parameters related to network size.
*
* timing parameters follows the specification example from Wi-SUN specification
*
* Default value: automatic
* Default value: medium
* small network size: hundreds of devices
* Large network size: thousands of devices
* automatic: when discovering the network network size is learned
* from advertisements and timings adjusted accordingly
*
* When network size is changed, it will override following configuration values:
* - Timing settings set by ws_management_timing_parameters_set()
* - RPL settings set by ws_bbr_rpl_parameters_set()
*
* If values should be other than defaults set by stack, they need to set using
* above function calls after network size change.
*
* \param interface_id Network interface ID.
* \param network_size define from NETWORK_SIZE_*.
* \param network_size Network size in hundreds of devices, certificate or automatic.
* See NETWORK_SIZE_ definition.
*
* \return 0, Init OK.
* \return <0 Init fail.
@ -179,6 +253,34 @@ int ws_management_network_size_set(
int8_t interface_id,
uint8_t network_size);
/**
* Get timing parameters related to network size.
*
* \param interface_id Network interface ID.
* \param network_size Network size in hundreds of devices, certificate or automatic.
* See NETWORK_SIZE_ definition.
*
* \return 0, OK.
* \return <0 Fail.
*/
int ws_management_network_size_get(
int8_t interface_id,
uint8_t *network_size);
/**
* Validate timing parameters related to network size.
*
* \param interface_id Network interface ID.
* \param network_size Network size in hundreds of devices, certificate or automatic.
* See NETWORK_SIZE_ definition.
*
* \return 0, OK.
* \return <0 Fail.
*/
int ws_management_network_size_validate(
int8_t interface_id,
uint8_t network_size);
/**
* Set channel mask for FHSS operation.
*
@ -194,6 +296,32 @@ int ws_management_channel_mask_set(
int8_t interface_id,
uint32_t channel_mask[8]);
/**
* Get channel mask for FHSS operation.
*
* \param interface_id Network interface ID.
* \param channel_mask set bits matching the channel 1 to allow channel 0 to disallow.
*
* \return 0, OK.
* \return <0 Fail.
*/
int ws_management_channel_mask_get(
int8_t interface_id,
uint32_t *channel_mask);
/**
* Validate channel mask for FHSS operation.
*
* \param interface_id Network interface ID.
* \param channel_mask set bits matching the channel 1 to allow channel 0 to disallow.
*
* \return 0, OK.
* \return <0 Fail.
*/
int ws_management_channel_mask_validate(
int8_t interface_id,
uint32_t channel_mask[8]);
/**
* Configure Application defined channel plan.
*
@ -227,6 +355,7 @@ int ws_management_channel_plan_set(
*
* Change the default configuration for Wi-SUN FHSS operation.
*
*
* \param interface_id Network interface ID.
* \param fhss_uc_dwell_interval default to 250 ms.
* \param fhss_broadcast_interval default to 800 ms.
@ -262,6 +391,40 @@ int ws_management_fhss_unicast_channel_function_configure(
uint16_t fixed_channel,
uint8_t dwell_interval);
/**
* Get unicast channel function.
*
* \param interface_id Network interface ID.
* \param channel_function Unicast channel function.
* \param fixed_channel Used channel when channel function is fixed channel.
* \param dwell_interval Used dwell interval when channel function is TR51 or DH1.
*
* \return 0, OK.
* \return <0 fail.
*/
int ws_management_fhss_unicast_channel_function_get(
int8_t interface_id,
uint8_t *channel_function,
uint16_t *fixed_channel,
uint8_t *dwell_interval);
/**
* Validate unicast channel function.
*
* \param interface_id Network interface ID.
* \param channel_function Unicast channel function.
* \param fixed_channel Used channel when channel function is fixed channel.
* \param dwell_interval Used dwell interval when channel function is TR51 or DH1.
*
* \return 0, OK.
* \return <0 fail.
*/
int ws_management_fhss_unicast_channel_function_validate(
int8_t interface_id,
uint8_t channel_function,
uint16_t fixed_channel,
uint8_t dwell_interval);
/**
* Configure broadcast channel function.
*
@ -285,6 +448,110 @@ int ws_management_fhss_broadcast_channel_function_configure(
uint8_t dwell_interval,
uint32_t broadcast_interval);
/**
* Get broadcast channel function.
*
* \param interface_id Network interface ID.
* \param channel_function Broadcast channel function.
* \param fixed_channel Used channel when channel function is fixed channel.
* \param dwell_interval Broadcast channel dwell interval.
* \param broadcast_interval Broadcast interval.
*
* \return 0, OK.
* \return <0 Fail.
*/
int ws_management_fhss_broadcast_channel_function_get(
int8_t interface_id,
uint8_t *channel_function,
uint16_t *fixed_channel,
uint8_t *dwell_interval,
uint32_t *broadcast_interval);
/**
* Validate broadcast channel function.
*
* \param interface_id Network interface ID.
* \param channel_function Broadcast channel function.
* \param fixed_channel Used channel when channel function is fixed channel.
* \param dwell_interval Broadcast channel dwell interval.
* \param broadcast_interval Broadcast interval.
*
* \return 0, OK.
* \return <0 Fail.
*/
int ws_management_fhss_broadcast_channel_function_validate(
int8_t interface_id,
uint8_t channel_function,
uint16_t fixed_channel,
uint8_t dwell_interval,
uint32_t broadcast_interval);
/**
* Set timing parameters
*
* Sets the parameters for the PAN discovery trickle timer and PAN timeout.
*
* When network size is changed using ws_management_network_size_set(),
* it will override the configuration values set by this function.
*
* \param interface_id Network interface ID.
* \param disc_trickle_imin Discovery trickle Imin
* \param disc_trickle_imax Discovery trickle Imax.
* \param disc_trickle_k Discovery trickle k.
* \param pan_timeout PAN timeout.
*
* \return 0, Init OK.
* \return <0 Init fail.
*/
int ws_management_timing_parameters_set(
int8_t interface_id,
uint16_t disc_trickle_imin,
uint16_t disc_trickle_imax,
uint8_t disc_trickle_k,
uint16_t pan_timeout);
/**
* Get timing parameters
*
* Gets the parameters for the PAN discovery trickle timer and PAN timeout.
*
* \param interface_id Network interface ID.
* \param disc_trickle_imin Discovery trickle Imin
* \param disc_trickle_imax Discovery trickle Imax.
* \param disc_trickle_k Discovery trickle k.
* \param pan_timeout PAN timeout.
*
* \return 0, Init OK.
* \return <0 Init fail.
*/
int ws_management_timing_parameters_get(
int8_t interface_id,
uint16_t *disc_trickle_imin,
uint16_t *disc_trickle_imax,
uint8_t *disc_trickle_k,
uint16_t *pan_timeout);
/**
* Validate timing parameters
*
* Validates the parameters for the PAN discovery trickle timer and PAN timeout.
*
* \param interface_id Network interface ID.
* \param disc_trickle_imin Discovery trickle Imin
* \param disc_trickle_imax Discovery trickle Imax.
* \param disc_trickle_k Discovery trickle k.
* \param pan_timeout PAN timeout.
*
* \return 0, Init OK.
* \return <0 Init fail.
*/
int ws_management_timing_parameters_validate(
int8_t interface_id,
uint16_t disc_trickle_imin,
uint16_t disc_trickle_imax,
uint8_t disc_trickle_k,
uint16_t pan_timeout);
/**
* Start collecting Wi-SUN statistics.
*

View File

@ -74,8 +74,11 @@
#include "6LoWPAN/Fragmentation/cipv6_fragmenter.h"
#include "Service_Libs/etx/etx.h"
#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h"
#include "6LoWPAN/ws/ws_common.h"
#include "6LoWPAN/ws/ws_bootstrap.h"
#ifdef HAVE_WS
#include "6LoWPAN/ws/ws_cfg_settings.h"
#endif
#define TRACE_GROUP_LOWPAN "6lo"
#define TRACE_GROUP "6lo"
@ -117,6 +120,9 @@ void protocol_init(void)
#ifdef HAVE_RPL
protocol_6lowpan_rpl_domain = rpl_control_create_domain();
#endif
#ifdef HAVE_WS
ws_cfg_settings_init();
#endif
}
void protocol_6lowpan_stack(buffer_t *b)
@ -779,3 +785,83 @@ uint8_t protocol_6lowpan_beacon_compare_rx(int8_t interface_id, uint8_t join_pri
return conn_to_pref;
}
bool protocol_6lowpan_latency_estimate_get(int8_t interface_id, uint32_t *latency)
{
protocol_interface_info_entry_t *cur_interface = protocol_stack_interface_info_get_by_id(interface_id);
uint32_t latency_estimate = 0;
if (!cur_interface) {
return false;
}
if (cur_interface->eth_mac_api) {
// either PPP or Ethernet interface.
latency_estimate = 100;
} else if (thread_info(cur_interface)) {
// thread network
latency_estimate = 1000;
} else if (ws_info(cur_interface)) {
latency_estimate = ws_common_latency_estimate_get(cur_interface);
} else {
// 6LoWPAN ND
latency_estimate = 8000;
}
if (latency_estimate != 0) {
*latency = latency_estimate;
return true;
}
return false;
}
bool protocol_6lowpan_stagger_estimate_get(int8_t interface_id, uint32_t data_amount, uint16_t *stagger_min, uint16_t *stagger_max, uint16_t *stagger_rand)
{
size_t network_size;
uint32_t datarate;
protocol_interface_info_entry_t *cur_interface = protocol_stack_interface_info_get_by_id(interface_id);
if (!cur_interface) {
return false;
}
*stagger_min = 1;
if (cur_interface->eth_mac_api) {
// either PPP or Ethernet interface.
network_size = 1;
datarate = 1000000;
} else if (thread_info(cur_interface)) {
// thread network
network_size = 23;
datarate = 250000;
} else if (ws_info(cur_interface)) {
network_size = ws_common_network_size_estimate_get(cur_interface);
datarate = ws_common_datarate_get(cur_interface);
} else {
// 6LoWPAN ND
network_size = 1000;
datarate = 250000;
}
if (data_amount == 0) {
// If no data amount given, use 1kB
data_amount = 1;
}
/**Example:
* Maximum stagger value to send 1kB on 50 devices network using datarate 50000 kb/:
* (1 * 1024 * 8 * 50) / (50000/4)) = ~ 32s
*
* devices: 50, datarate: 250kbps => stagger ~ 6s
* devices: 1000, datarate: 50kbps => stagger ~ 655s
*/
/* Do not occupy whole bandwidth, halve the theoretical datarate and reserve room for other channel usage */
datarate = datarate / 4;
*stagger_max = (uint16_t) * stagger_min + ((data_amount * 1024 * 8 * network_size) / datarate);
// Randomize stagger value
*stagger_rand = randLIB_get_random_in_range(*stagger_min, *stagger_max);
return true;
}

View File

@ -75,5 +75,7 @@ uint8_t protocol_6lowpan_beacon_join_priority_tx(int8_t interface_id);
uint8_t protocol_6lowpan_beacon_compare_rx(int8_t interface_id, uint8_t join_priority, uint8_t link_quality);
bool protocol_6lowpan_bootsrap_start(struct protocol_interface_info_entry *interface);
bool protocol_6lowpan_bootsrap_link_set(struct protocol_interface_info_entry *interface, struct mlme_pan_descriptor_s *pan_descriptor, const uint8_t *beacon_payload, uint8_t beacon_length);
bool protocol_6lowpan_latency_estimate_get(int8_t interface_id, uint32_t *latency);
bool protocol_6lowpan_stagger_estimate_get(int8_t interface_id, uint32_t data_amount, uint16_t *stagger_min, uint16_t *stagger_max, uint16_t *stagger_rand);
#endif /* PROTOCOL_6LOWPAN_H_ */

View File

@ -27,6 +27,7 @@
#include "6LoWPAN/ws/ws_config.h"
#include "6LoWPAN/ws/ws_common.h"
#include "6LoWPAN/ws/ws_bootstrap.h"
#include "6LoWPAN/ws/ws_cfg_settings.h"
#include "RPL/rpl_control.h"
#include "RPL/rpl_data.h"
#include "Common_Protocols/icmpv6.h"
@ -61,6 +62,7 @@ static uint8_t current_instance_id = RPL_INSTANCE_ID;
*/
static int8_t backbone_interface_id = -1; // BBR backbone information
static uint16_t configuration = 0;
static uint32_t pan_version_timer = 0;
static uint8_t static_dodag_prefix[8] = {0xfd, 0x00, 0x72, 0x83, 0x7e};
static uint8_t static_dodag_id_prefix[8] = {0xfd, 0x00, 0x61, 0x72, 0x6d};
@ -80,9 +82,9 @@ static rpl_dodag_conf_t rpl_conf = {
.dag_max_rank_increase = WS_RPL_MAX_HOP_RANK_INCREASE,
.min_hop_rank_increase = WS_RPL_MIN_HOP_RANK_INCREASE,
// DIO configuration
.dio_interval_min = WS_RPL_DIO_IMIN,
.dio_interval_doublings = WS_RPL_DIO_DOUBLING,
.dio_redundancy_constant = WS_RPL_DIO_REDUNDANCY
.dio_interval_min = WS_RPL_DIO_IMIN_SMALL,
.dio_interval_doublings = WS_RPL_DIO_DOUBLING_SMALL,
.dio_redundancy_constant = WS_RPL_DIO_REDUNDANCY_SMALL
};
static void ws_bbr_rpl_version_timer_start(protocol_interface_info_entry_t *cur, uint8_t version)
@ -109,9 +111,9 @@ void ws_bbr_rpl_config(protocol_interface_info_entry_t *cur, uint8_t imin, uint8
{
if (imin == 0 || doubling == 0) {
// use default values
imin = WS_RPL_DIO_IMIN;
doubling = WS_RPL_DIO_DOUBLING;
redundancy = WS_RPL_DIO_REDUNDANCY;
imin = WS_RPL_DIO_IMIN_SMALL;
doubling = WS_RPL_DIO_DOUBLING_SMALL;
redundancy = WS_RPL_DIO_REDUNDANCY_SMALL;
}
if (rpl_conf.dio_interval_min == imin &&
@ -532,6 +534,22 @@ static void ws_bbr_rpl_status_check(protocol_interface_info_entry_t *cur)
}
}
}
void ws_bbr_pan_version_increase(protocol_interface_info_entry_t *cur)
{
if (!cur) {
return;
}
tr_debug("Border router version number update");
if (configuration & BBR_REQUIRE_DAO_REFRESH) {
// Version number is not periodically increased forcing nodes to check Border router availability using DAO
pan_version_timer = 0;
} else {
pan_version_timer = cur->ws_info->cfg->timing.pan_timeout / PAN_VERSION_CHANGE_INTERVAL;
}
cur->ws_info->pan_information.pan_version++;
// Inconsistent for border router to make information distribute faster
ws_bootstrap_configuration_trickle_reset(cur);
}
void ws_bbr_seconds_timer(protocol_interface_info_entry_t *cur, uint32_t seconds)
{
@ -574,18 +592,21 @@ void ws_bbr_seconds_timer(protocol_interface_info_entry_t *cur, uint32_t seconds
}
// Normal BBR operation
if (protocol_6lowpan_rpl_root_dodag) {
if (cur->ws_info->pan_version_timer > seconds) {
cur->ws_info->pan_version_timer -= seconds;
} else {
// PAN version number update
tr_debug("Border router version number update");
cur->ws_info->pan_version_timer = ws_common_version_lifetime_get(cur->ws_info->network_size_config);
cur->ws_info->pan_information.pan_version++;
// Inconsistent for border router to make information distribute faster
ws_bootstrap_configuration_trickle_reset(cur);
if (cur->ws_info->network_size_config == NETWORK_SIZE_AUTOMATIC) {
ws_common_network_size_configure(cur, cur->ws_info->pan_information.pan_size);
/*
* PAN version change is one way to enable nodes to detect the border router availability
* if this is not done periodically devices need to have other means to detect border router condiftion
*
* If devices do not see version change they need to send DAO to border router before PAN timeout
*
* The update frequency should be related to PAN timeout and happen for example 4 times.
*/
if (pan_version_timer > 0) {
if (pan_version_timer > seconds) {
pan_version_timer -= seconds;
} else {
// PAN version number update
pan_version_timer = 0;
ws_bbr_pan_version_increase(cur);
}
}
if (cur->ws_info->rpl_version_timer > seconds) {
@ -754,3 +775,163 @@ int ws_bbr_ext_certificate_validation_set(int8_t interface_id, uint8_t validatio
return -1;
#endif
}
int ws_bbr_rpl_parameters_set(int8_t interface_id, uint8_t dio_interval_min, uint8_t dio_interval_doublings, uint8_t dio_redundancy_constant)
{
(void) interface_id;
#ifdef HAVE_WS_BORDER_ROUTER
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
ws_rpl_cfg_t cfg;
if (ws_cfg_rpl_get(&cfg, NULL) < 0) {
return -1;
}
if (dio_interval_min > 0) {
cfg.dio_interval_min = dio_interval_min;
}
if (dio_interval_doublings > 0) {
cfg.dio_interval_doublings = dio_interval_doublings;
}
if (dio_redundancy_constant != 0xff) {
cfg.dio_redundancy_constant = dio_redundancy_constant;
}
if (ws_cfg_rpl_set(cur, NULL, &cfg, 0) < 0) {
return -2;
}
return 0;
#else
(void) dio_interval_min;
(void) dio_interval_doublings;
(void) dio_redundancy_constant;
return -1;
#endif
}
int ws_bbr_rpl_parameters_get(int8_t interface_id, uint8_t *dio_interval_min, uint8_t *dio_interval_doublings, uint8_t *dio_redundancy_constant)
{
(void) interface_id;
#ifdef HAVE_WS_BORDER_ROUTER
if (!dio_interval_min || !dio_interval_doublings || !dio_redundancy_constant) {
return -1;
}
ws_rpl_cfg_t cfg;
if (ws_cfg_rpl_get(&cfg, NULL) < 0) {
return -2;
}
*dio_interval_min = cfg.dio_interval_min;
*dio_interval_doublings = cfg.dio_interval_doublings;
*dio_redundancy_constant = cfg.dio_redundancy_constant;
return 0;
#else
(void) dio_interval_min;
(void) dio_interval_doublings;
(void) dio_redundancy_constant;
return -1;
#endif
}
int ws_bbr_rpl_parameters_validate(int8_t interface_id, uint8_t dio_interval_min, uint8_t dio_interval_doublings, uint8_t dio_redundancy_constant)
{
(void) interface_id;
#ifdef HAVE_WS_BORDER_ROUTER
ws_rpl_cfg_t cfg;
if (ws_cfg_rpl_get(&cfg, NULL) < 0) {
return -2;
}
if (dio_interval_min > 0) {
cfg.dio_interval_min = dio_interval_min;
}
if (dio_interval_doublings > 0) {
cfg.dio_interval_doublings = dio_interval_doublings;
}
if (dio_redundancy_constant != 0xff) {
cfg.dio_redundancy_constant = dio_redundancy_constant;
}
if (ws_cfg_rpl_validate(NULL, &cfg) < 0) {
return -3;
}
return 0;
#else
(void) dio_interval_min;
(void) dio_interval_doublings;
(void) dio_redundancy_constant;
return -1;
#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;
}
cfg.network_pan_id = pan_id;
if (ws_cfg_gen_set(cur, NULL, &cfg, 0) < 0) {
return -2;
}
return 0;
#else
(void) pan_id;
return -1;
#endif
}
int ws_bbr_pan_configuration_get(int8_t interface_id, uint16_t *pan_id)
{
(void) interface_id;
#ifdef HAVE_WS_BORDER_ROUTER
if (!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;
return 0;
#else
(void) pan_id;
return -1;
#endif
}
int ws_bbr_pan_configuration_validate(int8_t interface_id, uint16_t pan_id)
{
(void) interface_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
}

View File

@ -25,6 +25,8 @@ extern uint16_t test_pan_size_override;
void ws_bbr_seconds_timer(protocol_interface_info_entry_t *cur, uint32_t seconds);
void ws_bbr_pan_version_increase(protocol_interface_info_entry_t *cur);
uint16_t ws_bbr_pan_size(protocol_interface_info_entry_t *cur);
void ws_bbr_rpl_config(protocol_interface_info_entry_t *cur, uint8_t imin, uint8_t doubling, uint8_t redundancy, uint16_t dag_max_rank_increase, uint16_t min_hop_rank_increase);
@ -35,6 +37,7 @@ bool ws_bbr_ready_to_start(protocol_interface_info_entry_t *cur);
#else
#define ws_bbr_seconds_timer( cur, seconds)
#define ws_bbr_pan_version_increase(cur)
#define ws_bbr_pan_size(cur) 0
#define ws_bbr_rpl_config( cur, imin, doubling, redundancy, dag_max_rank_increase, min_hop_rank_increase)
#define ws_bbr_ready_to_start(cur) true

View File

@ -54,6 +54,7 @@
#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"
@ -98,6 +99,8 @@ static ws_nud_table_entry_t *ws_nud_entry_discover(protocol_interface_info_entry
static void ws_nud_entry_remove(protocol_interface_info_entry_t *cur, mac_neighbor_table_entry_t *entry_ptr);
static bool ws_neighbor_entry_nud_notify(mac_neighbor_table_entry_t *entry_ptr, void *user_data);
static void ws_address_registration_update(protocol_interface_info_entry_t *interface, const uint8_t addr[16]);
static void ws_bootstrap_candidate_table_reset(protocol_interface_info_entry_t *cur);
static parent_info_t *ws_bootstrap_candidate_parent_get(struct protocol_interface_info_entry *cur, const uint8_t *addr, bool create);
@ -151,17 +154,28 @@ static void ws_bootstrap_neighbor_list_clean(struct protocol_interface_info_entr
mac_neighbor_table_neighbor_list_clean(mac_neighbor_info(interface));
}
static void ws_address_reregister_trig(struct protocol_interface_info_entry *interface)
{
if (interface->ws_info->aro_registration_timer == 0) {
interface->ws_info->aro_registration_timer = WS_NEIGHBOR_NUD_TIMEOUT;
}
}
static void ws_bootstrap_address_notification_cb(struct protocol_interface_info_entry *interface, const struct if_address_entry *addr, if_address_callback_t reason)
{
/* No need for LL address registration */
if (addr->source == ADDR_SOURCE_UNKNOWN) {
if (addr->source == ADDR_SOURCE_UNKNOWN || !interface->ws_info) {
return;
}
if (reason == ADDR_CALLBACK_DAD_COMPLETE) {
//Trig Address Registartion only when Bootstrap is ready
if (interface->nwk_bootstrap_state == ER_BOOTSRAP_DONE && addr->source != ADDR_SOURCE_DHCP) {
tr_debug("Address registration %s", trace_ipv6(addr->address));
rpl_control_register_address(interface, addr->address);
if (addr->source != ADDR_SOURCE_DHCP) {
if (interface->nwk_bootstrap_state == ER_BOOTSRAP_DONE) {
tr_debug("Address registration %s", trace_ipv6(addr->address));
ws_address_registration_update(interface, addr->address);
}
ws_address_reregister_trig(interface);
}
if (addr_ipv6_scope(addr->address, interface) > IPV6_SCOPE_LINK_LOCAL) {
// at least ula address available inside mesh.
@ -188,12 +202,6 @@ static void ws_bootstrap_address_notification_cb(struct protocol_interface_info_
break;
}
}
} else if (reason == ADDR_CALLBACK_TIMER) {
if (addr->source != ADDR_SOURCE_DHCP) {
tr_debug("Address Re registration %s", trace_ipv6(addr->address));
//Register
rpl_control_register_address(interface, addr->address);
}
}
}
@ -409,11 +417,10 @@ static fhss_ws_neighbor_timing_info_t *ws_get_neighbor_info(const fhss_api_t *ap
}
static void ws_bootstrap_llc_hopping_update(struct protocol_interface_info_entry *cur, const fhss_ws_configuration_t *fhss_configuration)
{
memcpy(cur->ws_info->hopping_schdule.channel_mask, fhss_configuration->channel_mask, sizeof(uint32_t) * 8);
cur->ws_info->hopping_schdule.uc_fixed_channel = fhss_configuration->unicast_fixed_channel;
cur->ws_info->hopping_schdule.bc_fixed_channel = fhss_configuration->broadcast_fixed_channel;
// Read UC channel function from WS info because FHSS might be temporarily configured to fixed channel during discovery.
cur->ws_info->hopping_schdule.uc_channel_function = cur->ws_info->fhss_uc_channel_function;
cur->ws_info->hopping_schdule.uc_channel_function = cur->ws_info->cfg->fhss.fhss_uc_channel_function;
cur->ws_info->hopping_schdule.bc_channel_function = fhss_configuration->ws_bc_channel_function;
cur->ws_info->hopping_schdule.fhss_bc_dwell_interval = fhss_configuration->fhss_bc_dwell_interval;
cur->ws_info->hopping_schdule.fhss_broadcast_interval = fhss_configuration->fhss_broadcast_interval;
@ -421,65 +428,126 @@ static void ws_bootstrap_llc_hopping_update(struct protocol_interface_info_entry
cur->ws_info->hopping_schdule.fhss_bsi = fhss_configuration->bsi;
}
static uint8_t ws_generate_exluded_channel_list_from_active_channels(ws_excluded_channel_data_t *excluded_data, const uint32_t *selected_channel_mask, uint16_t number_of_channels)
{
bool active_range = false;
//Clear Old Data
memset(excluded_data, 0, sizeof(ws_excluded_channel_data_t));
for (uint8_t i = 0; i < number_of_channels; i++) {
if (selected_channel_mask[0 + (i / 32)] & (1 << (i % 32))) {
if (active_range) {
//Mark range stop here
active_range = false;
}
} else {
//Mark excluded channel
//Swap Order already here
excluded_data->channel_mask[0 + (i / 32)] |= 1 << (31 - (i % 32));
excluded_data->excluded_channel_count++;
if (excluded_data->excluded_range_length < WS_EXCLUDED_MAX_RANGE_TO_SEND) {
if (!active_range) {
excluded_data->excluded_range_length++;
active_range = true;
//Set start channel
excluded_data->exluded_range[excluded_data->excluded_range_length - 1].range_start = i;
} else {
excluded_data->exluded_range[excluded_data->excluded_range_length - 1].range_end = i;
}
}
}
}
excluded_data->channel_mask_bytes_inline = ((number_of_channels + 7) / 8);
uint8_t channel_plan = 0;
if (excluded_data->excluded_range_length == 0) {
excluded_data->excuded_channel_ctrl = WS_EXC_CHAN_CTRL_NONE;
} else if (excluded_data->excluded_range_length <= WS_EXCLUDED_MAX_RANGE_TO_SEND) {
uint8_t range_length = (excluded_data->excluded_range_length * 4) + 3;
if (range_length <= ((number_of_channels + 7) / 8) + 6) {
excluded_data->excuded_channel_ctrl = WS_EXC_CHAN_CTRL_RANGE;
} else {
excluded_data->excuded_channel_ctrl = WS_EXC_CHAN_CTRL_BITMASK;
channel_plan = 1;
}
} else {
excluded_data->excuded_channel_ctrl = WS_EXC_CHAN_CTRL_BITMASK;
channel_plan = 1;
}
tr_debug("Excluded ctrl %u, exluded channel count %u, total domain channels %u", excluded_data->excuded_channel_ctrl, excluded_data->excluded_channel_count, number_of_channels);
return channel_plan;
}
static void ws_fhss_configure_channel_masks(protocol_interface_info_entry_t *cur, fhss_ws_configuration_t *fhss_configuration)
{
ws_generate_channel_list(fhss_configuration->channel_mask, cur->ws_info->hopping_schdule.number_of_channels, cur->ws_info->hopping_schdule.regulatory_domain);
ws_generate_channel_list(fhss_configuration->unicast_channel_mask, cur->ws_info->hopping_schdule.number_of_channels, cur->ws_info->hopping_schdule.regulatory_domain);
// using bitwise AND operation for user set channel mask to remove channels not allowed in this device
for (uint8_t n = 0; n < 8; n++) {
fhss_configuration->unicast_channel_mask[n] &= cur->ws_info->cfg->fhss.fhss_channel_mask[n];
}
//Update Exluded channels
cur->ws_info->hopping_schdule.channel_plan = ws_generate_exluded_channel_list_from_active_channels(&cur->ws_info->hopping_schdule.excluded_channels, fhss_configuration->unicast_channel_mask, cur->ws_info->hopping_schdule.number_of_channels);
}
static int8_t ws_fhss_initialize(protocol_interface_info_entry_t *cur)
{
fhss_api_t *fhss_api = ns_sw_mac_get_fhss_api(cur->mac_api);
fhss_ws_configuration_t fhss_configuration;
memset(&fhss_configuration, 0, sizeof(fhss_ws_configuration_t));
if (!fhss_api) {
// When FHSS doesn't exist yet, create one
fhss_ws_configuration_t fhss_configuration;
memset(&fhss_configuration, 0, sizeof(fhss_ws_configuration_t));
ws_generate_channel_list(fhss_configuration.channel_mask, cur->ws_info->hopping_schdule.number_of_channels, cur->ws_info->hopping_schdule.regulatory_domain);
ws_fhss_configure_channel_masks(cur, &fhss_configuration);
// using bitwise AND operation for user set channel mask to remove channels not allowed in this device
for (uint8_t n = 0; n < 8; n++) {
fhss_configuration.channel_mask[n] &= cur->ws_info->fhss_channel_mask[n];
}
fhss_configuration.fhss_uc_dwell_interval = cur->ws_info->fhss_uc_dwell_interval;
fhss_configuration.ws_uc_channel_function = (fhss_ws_channel_functions)cur->ws_info->fhss_uc_channel_function;
fhss_configuration.ws_bc_channel_function = (fhss_ws_channel_functions)cur->ws_info->fhss_bc_channel_function;
fhss_configuration.fhss_bc_dwell_interval = cur->ws_info->fhss_bc_dwell_interval;
fhss_configuration.fhss_broadcast_interval = cur->ws_info->fhss_bc_interval;
fhss_configuration.fhss_uc_dwell_interval = cur->ws_info->cfg->fhss.fhss_uc_dwell_interval;
fhss_configuration.ws_uc_channel_function = (fhss_ws_channel_functions)cur->ws_info->cfg->fhss.fhss_uc_channel_function;
fhss_configuration.ws_bc_channel_function = (fhss_ws_channel_functions)cur->ws_info->cfg->fhss.fhss_bc_channel_function;
fhss_configuration.fhss_bc_dwell_interval = cur->ws_info->cfg->fhss.fhss_bc_dwell_interval;
fhss_configuration.fhss_broadcast_interval = cur->ws_info->cfg->fhss.fhss_bc_interval;
fhss_api = ns_fhss_ws_create(&fhss_configuration, cur->ws_info->fhss_timer_ptr);
if (!fhss_api) {
return -1;
}
ns_sw_mac_fhss_register(cur->mac_api, fhss_api);
} else {
// Read defaults from the configuration to help FHSS testing
const fhss_ws_configuration_t *fhss_configuration = ns_fhss_ws_configuration_get(fhss_api);
if (!fhss_configuration) {
const fhss_ws_configuration_t *fhss_configuration_copy = ns_fhss_ws_configuration_get(fhss_api);
if (!fhss_configuration_copy) {
// no configuration set yet
return 0;
}
memcpy(cur->ws_info->fhss_channel_mask, fhss_configuration->channel_mask, sizeof(uint32_t) * 8);
cur->ws_info->fhss_uc_channel_function = fhss_configuration->ws_uc_channel_function;
cur->ws_info->fhss_bc_channel_function = fhss_configuration->ws_bc_channel_function;
cur->ws_info->fhss_bc_dwell_interval = fhss_configuration->fhss_bc_dwell_interval;
cur->ws_info->fhss_bc_interval = fhss_configuration->fhss_broadcast_interval;
cur->ws_info->fhss_uc_dwell_interval = fhss_configuration->fhss_uc_dwell_interval;
cur->ws_info->fhss_bc_fixed_channel = fhss_configuration->broadcast_fixed_channel;
cur->ws_info->fhss_uc_fixed_channel = fhss_configuration->unicast_fixed_channel;
fhss_configuration = *fhss_configuration_copy;
memcpy(cur->ws_info->cfg->fhss.fhss_channel_mask, fhss_configuration_copy->unicast_channel_mask, sizeof(uint32_t) * 8);
cur->ws_info->cfg->fhss.fhss_uc_channel_function = fhss_configuration_copy->ws_uc_channel_function;
cur->ws_info->cfg->fhss.fhss_bc_channel_function = fhss_configuration_copy->ws_bc_channel_function;
cur->ws_info->cfg->fhss.fhss_bc_dwell_interval = fhss_configuration_copy->fhss_bc_dwell_interval;
cur->ws_info->cfg->fhss.fhss_bc_interval = fhss_configuration_copy->fhss_broadcast_interval;
cur->ws_info->cfg->fhss.fhss_uc_dwell_interval = fhss_configuration_copy->fhss_uc_dwell_interval;
cur->ws_info->cfg->fhss.fhss_bc_fixed_channel = fhss_configuration_copy->broadcast_fixed_channel;
cur->ws_info->cfg->fhss.fhss_uc_fixed_channel = fhss_configuration_copy->unicast_fixed_channel;
ws_fhss_configure_channel_masks(cur, &fhss_configuration);
ns_fhss_ws_configuration_set(fhss_api, &fhss_configuration);
}
return 0;
}
static int8_t ws_fhss_set_defaults(protocol_interface_info_entry_t *cur, fhss_ws_configuration_t *fhss_configuration)
{
fhss_configuration->fhss_uc_dwell_interval = cur->ws_info->fhss_uc_dwell_interval;
fhss_configuration->ws_uc_channel_function = (fhss_ws_channel_functions)cur->ws_info->fhss_uc_channel_function;
fhss_configuration->ws_bc_channel_function = (fhss_ws_channel_functions)cur->ws_info->fhss_bc_channel_function;
fhss_configuration->fhss_bc_dwell_interval = cur->ws_info->fhss_bc_dwell_interval;
fhss_configuration->fhss_broadcast_interval = cur->ws_info->fhss_bc_interval;
if (cur->ws_info->fhss_uc_fixed_channel != 0xffff) {
fhss_configuration->unicast_fixed_channel = cur->ws_info->fhss_uc_fixed_channel;
}
fhss_configuration->broadcast_fixed_channel = cur->ws_info->fhss_bc_fixed_channel;
ws_generate_channel_list(fhss_configuration->channel_mask, cur->ws_info->hopping_schdule.number_of_channels, cur->ws_info->hopping_schdule.regulatory_domain);
// using bitwise AND operation for user set channel mask to remove channels not allowed in this device
for (uint8_t n = 0; n < 8; n++) {
fhss_configuration->channel_mask[n] &= cur->ws_info->fhss_channel_mask[n];
fhss_configuration->fhss_uc_dwell_interval = cur->ws_info->cfg->fhss.fhss_uc_dwell_interval;
fhss_configuration->ws_uc_channel_function = (fhss_ws_channel_functions)cur->ws_info->cfg->fhss.fhss_uc_channel_function;
fhss_configuration->ws_bc_channel_function = (fhss_ws_channel_functions)cur->ws_info->cfg->fhss.fhss_bc_channel_function;
fhss_configuration->fhss_bc_dwell_interval = cur->ws_info->cfg->fhss.fhss_bc_dwell_interval;
fhss_configuration->fhss_broadcast_interval = cur->ws_info->cfg->fhss.fhss_bc_interval;
if (cur->ws_info->cfg->fhss.fhss_uc_fixed_channel != 0xffff) {
fhss_configuration->unicast_fixed_channel = cur->ws_info->cfg->fhss.fhss_uc_fixed_channel;
}
fhss_configuration->broadcast_fixed_channel = cur->ws_info->cfg->fhss.fhss_bc_fixed_channel;
return 0;
}
static int8_t ws_fhss_border_router_configure(protocol_interface_info_entry_t *cur)
@ -492,6 +560,7 @@ static int8_t ws_fhss_border_router_configure(protocol_interface_info_entry_t *c
memcpy(&fhss_configuration, ns_fhss_ws_configuration_get(cur->ws_info->fhss_api), sizeof(fhss_ws_configuration_t));
}
ws_fhss_set_defaults(cur, &fhss_configuration);
ws_fhss_configure_channel_masks(cur, &fhss_configuration);
ns_fhss_ws_configuration_set(cur->ws_info->fhss_api, &fhss_configuration);
ws_bootstrap_llc_hopping_update(cur, &fhss_configuration);
@ -515,17 +584,19 @@ static int8_t ws_fhss_configure(protocol_interface_info_entry_t *cur, bool disco
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));
ws_fhss_set_defaults(cur, &fhss_configuration);
ws_fhss_configure_channel_masks(cur, &fhss_configuration);
}
// Discovery is done using fixed channel
if (discovery) {
fhss_configuration.ws_uc_channel_function = WS_FIXED_CHANNEL;
} else {
fhss_configuration.ws_uc_channel_function = (fhss_ws_channel_functions)cur->ws_info->fhss_uc_channel_function;
fhss_configuration.ws_uc_channel_function = (fhss_ws_channel_functions)cur->ws_info->cfg->fhss.fhss_uc_channel_function;
}
fhss_configuration.ws_bc_channel_function = WS_FIXED_CHANNEL;
fhss_configuration.fhss_broadcast_interval = 0;
uint8_t tmp_uc_fixed_channel = ws_randomize_fixed_channel(cur->ws_info->fhss_uc_fixed_channel, cur->ws_info->hopping_schdule.number_of_channels);
uint8_t tmp_bc_fixed_channel = ws_randomize_fixed_channel(cur->ws_info->fhss_bc_fixed_channel, cur->ws_info->hopping_schdule.number_of_channels);
uint8_t tmp_uc_fixed_channel = ws_randomize_fixed_channel(cur->ws_info->cfg->fhss.fhss_uc_fixed_channel, cur->ws_info->hopping_schdule.number_of_channels);
uint8_t tmp_bc_fixed_channel = ws_randomize_fixed_channel(cur->ws_info->cfg->fhss.fhss_bc_fixed_channel, cur->ws_info->hopping_schdule.number_of_channels);
fhss_configuration.unicast_fixed_channel = tmp_uc_fixed_channel;
fhss_configuration.broadcast_fixed_channel = tmp_bc_fixed_channel;
ns_fhss_ws_configuration_set(cur->ws_info->fhss_api, &fhss_configuration);
@ -577,12 +648,12 @@ static void ws_bootstrap_primary_parent_set(struct protocol_interface_info_entry
fhss_configuration.ws_bc_channel_function = (fhss_ws_channel_functions)neighbor_info->ws_neighbor->fhss_data.bc_timing_info.broadcast_channel_function;
if (fhss_configuration.ws_bc_channel_function == WS_FIXED_CHANNEL) {
cur->ws_info->hopping_schdule.bc_fixed_channel = neighbor_info->ws_neighbor->fhss_data.bc_timing_info.fixed_channel;
cur->ws_info->fhss_bc_fixed_channel = neighbor_info->ws_neighbor->fhss_data.bc_timing_info.fixed_channel;
cur->ws_info->cfg->fhss.fhss_bc_fixed_channel = neighbor_info->ws_neighbor->fhss_data.bc_timing_info.fixed_channel;
}
fhss_configuration.bsi = neighbor_info->ws_neighbor->fhss_data.bc_timing_info.broadcast_schedule_id;
fhss_configuration.fhss_bc_dwell_interval = neighbor_info->ws_neighbor->fhss_data.bc_timing_info.broadcast_dwell_interval;
fhss_configuration.fhss_broadcast_interval = neighbor_info->ws_neighbor->fhss_data.bc_timing_info.broadcast_interval;
fhss_configuration.broadcast_fixed_channel = cur->ws_info->fhss_bc_fixed_channel;
fhss_configuration.broadcast_fixed_channel = cur->ws_info->cfg->fhss.fhss_bc_fixed_channel;
neighbor_info->ws_neighbor->synch_done = true;
}
@ -822,6 +893,7 @@ void ws_bootstrap_configuration_reset(protocol_interface_info_entry_t *cur)
cur->ws_info->trickle_pa_running = false;
cur->ws_info->trickle_pcs_running = false;
cur->ws_info->trickle_pc_running = false;
cur->ws_info->trickle_pc_consistency_block_period = 0;
//cur->mac_security_key_usage_update_cb = ws_management_mac_security_key_update_cb;
return;
@ -896,12 +968,54 @@ static parent_info_t *ws_bootstrap_candidate_parent_get_best(protocol_interface_
return ns_list_get_first(&cur->ws_info->parent_list_reserved);
}
static void ws_bootstrap_decode_exclude_range_to_mask_by_range(void *mask_buffer, ws_excluded_channel_range_t *range_info, uint16_t number_of_channels)
{
uint16_t range_start, range_stop;
uint8_t mask_index = 0;
//uint8_t channel_index = 0;
uint8_t *range_ptr = range_info->range_start;
uint32_t *mask_ptr = mask_buffer;
while (range_info->number_of_range) {
range_start = common_read_16_bit_inverse(range_ptr);
range_ptr += 2;
range_stop = common_read_16_bit_inverse(range_ptr);
range_ptr += 2;
range_info->number_of_range--;
for (uint16_t channel = 0; channel < number_of_channels; channel++) {
if (channel && (channel % 32 == 0)) {
mask_index++;
//channel_index = 0;
}
if (channel >= range_start && channel <= range_stop) {
//mask_ptr[mask_index] |= 1 << (31 - channel_index);
mask_ptr[0 + (channel / 32)] |= 1 << (31 - (channel % 32));
} else if (channel > range_stop) {
break;
}
}
}
}
static 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)
{
parent->ws_utt = *ws_utt;
// Saved from unicast IE
parent->ws_us = *ws_us;
//copy excluded channel here if it is inline
if (ws_us->excluded_channel_ctrl == WS_EXC_CHAN_CTRL_RANGE) {
memset(parent->excluded_channel_data, 0, 32);
//Decode Range to mask here
ws_bootstrap_decode_exclude_range_to_mask_by_range(parent->excluded_channel_data, &parent->ws_us.excluded_channels.range, 256);
parent->ws_us.excluded_channels.mask.channel_mask = parent->excluded_channel_data;
parent->ws_us.excluded_channels.mask.mask_len_inline = 32;
parent->ws_us.excluded_channel_ctrl = WS_EXC_CHAN_CTRL_BITMASK;
} else if (ws_us->excluded_channel_ctrl == WS_EXC_CHAN_CTRL_BITMASK) {
parent->ws_us.excluded_channels.mask.channel_mask = parent->excluded_channel_data;
memcpy(parent->excluded_channel_data, ws_us->excluded_channels.mask.channel_mask, ws_us->excluded_channels.mask.mask_len_inline);
}
// Saved from Pan information, do not overwrite pan_version as it is not valid here
parent->pan_information.pan_size = pan_information->pan_size;
parent->pan_information.routing_cost = pan_information->routing_cost;
@ -1088,6 +1202,13 @@ static void ws_bootstrap_pan_advertisement_analyse(struct protocol_interface_inf
return;
}
if (ws_us->excluded_channel_ctrl) {
//Validate that we can storage data
if (ws_us->excluded_channel_ctrl == WS_EXC_CHAN_CTRL_BITMASK && ws_us->excluded_channels.mask.mask_len_inline > 32) {
return;
}
}
// Check pan flags so that it is valid
if (!pan_information.rpl_routing_method) {
// NOT RPL routing
@ -1130,9 +1251,9 @@ static void ws_bootstrap_pan_advertisement_analyse(struct protocol_interface_inf
if (rpl_control_is_dodag_parent(cur, ll_address)) {
// automatic network size adjustment learned
if (cur->ws_info->network_size_config == NETWORK_SIZE_AUTOMATIC &&
if (cur->ws_info->cfg->gen.network_size == NETWORK_SIZE_AUTOMATIC &&
cur->ws_info->pan_information.pan_size != pan_information.pan_size) {
ws_common_network_size_configure(cur, pan_information.pan_size);
ws_cfg_network_size_configure(cur, pan_information.pan_size);
}
cur->ws_info->pan_information.pan_size = pan_information.pan_size;
@ -1247,8 +1368,12 @@ static void ws_bootstrap_pan_config_analyse(struct protocol_interface_info_entry
if (cur->ws_info->configuration_learned) {
tr_info("PAN Config analyse own:%d, heard:%d", cur->ws_info->pan_information.pan_version, pan_version);
if (cur->ws_info->pan_information.pan_version == pan_version) {
// Same version heard so it is consistent
trickle_consistent_heard(&cur->ws_info->trickle_pan_config);
//Check if Trgigle have been resetted in short time skip this then
if (cur->ws_info->trickle_pc_consistency_block_period == 0) {
// Same version heard so it is consistent
trickle_consistent_heard(&cur->ws_info->trickle_pan_config);
}
if (neighbour_pointer_valid && neighbor_info.neighbor->link_role == PRIORITY_PARENT_NEIGHBOUR) {
ws_bootstrap_primary_parent_set(cur, &neighbor_info, WS_PARENT_SOFT_SYNCH);
}
@ -1264,6 +1389,7 @@ static void ws_bootstrap_pan_config_analyse(struct protocol_interface_info_entry
// older version heard ignoring the message
return;
}
cur->ws_info->trickle_pc_consistency_block_period = WS_CONFIG_CONSISTENT_FILTER_PERIOD;
}
}
@ -1278,7 +1404,7 @@ static void ws_bootstrap_pan_config_analyse(struct protocol_interface_info_entry
tr_info("Updated PAN configuration own:%d, heard:%d", cur->ws_info->pan_information.pan_version, pan_version);
// restart PAN version timer
cur->ws_info->pan_version_timeout_timer = ws_common_version_timeout_get(cur->ws_info->network_size_config);
cur->ws_info->pan_timeout_timer = cur->ws_info->cfg->timing.pan_timeout;
cur->ws_info->pan_information.pan_version = pan_version;
ws_pae_controller_gtk_hash_update(cur, gtkhash_ptr);
@ -1359,7 +1485,20 @@ static bool ws_channel_plan_one_compare(ws_channel_plan_one_t *rx_plan, ws_hoppi
return true;
}
bool ws_bootstrap_validate_channel_plan(ws_us_ie_t *ws_us, struct protocol_interface_info_entry *cur)
{
if (ws_us->channel_plan == 0) {
if (!ws_channel_plan_zero_compare(&ws_us->plan.zero, &cur->ws_info->hopping_schdule)) {
return false;
}
} else if (ws_us->channel_plan == 1) {
if (!ws_channel_plan_one_compare(&ws_us->plan.one, &cur->ws_info->hopping_schdule)) {
return false;
}
}
return true;
}
static void ws_bootstrap_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)
@ -1375,7 +1514,7 @@ static void ws_bootstrap_asynch_ind(struct protocol_interface_info_entry *cur, c
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->network_name)) {
if (!ws_bootstrap_network_name_matches(ie_ext, cur->ws_info->cfg->gen.network_name)) {
// Not in our network
return;
}
@ -1399,21 +1538,10 @@ static void ws_bootstrap_asynch_ind(struct protocol_interface_info_entry *cur, c
return;
}
//Compare Unicast channel Plan
if (ws_us.channel_plan != cur->ws_info->hopping_schdule.channel_plan) {
if (!ws_bootstrap_validate_channel_plan(&ws_us, cur)) {
return;
}
if (ws_us.channel_plan == 0) {
if (!ws_channel_plan_zero_compare(&ws_us.plan.zero, &cur->ws_info->hopping_schdule)) {
return;
}
} else if (ws_us.channel_plan == 1) {
if (!ws_channel_plan_one_compare(&ws_us.plan.one, &cur->ws_info->hopping_schdule)) {
return;
}
}
//Handle Message's
switch (message_type) {
case WS_FT_PAN_ADVERT:
@ -1507,13 +1635,7 @@ static void ws_bootstrap_neighbor_table_clean(struct protocol_interface_info_ent
//Read current timestamp
uint32_t time_from_last_unicast_shedule = ws_time_from_last_unicast_traffic(current_time_stamp, ws_neighbor);
uint32_t min_timeout;
if (interface->ws_info->network_size_config == NETWORK_SIZE_LARGE) {
min_timeout = WS_NEIGHBOR_TEMPORARY_LINK_MIN_TIMEOUT_LARGE;
} else {
min_timeout = WS_NEIGHBOR_TEMPORARY_LINK_MIN_TIMEOUT_SMALL;
}
if (time_from_last_unicast_shedule > min_timeout) {
if (time_from_last_unicast_shedule > interface->ws_info->cfg->timing.temp_link_min_timeout) {
//Accept only Enough Old Device
if (!neighbor_entry_ptr) {
//Accept first compare
@ -1615,12 +1737,19 @@ static bool ws_neighbor_entry_nud_notify(mac_neighbor_table_entry_t *entry_ptr,
if (time_from_start > WS_NEIGHBOR_NUD_TIMEOUT) {
if (ipv6_neighbour_has_registered_by_eui64(&cur->ipv6_neighbour_cache, entry_ptr->mac64)) {
// This is our child with valid ARO registration Change link timeout to future we check at 2 minute intervals
entry_ptr->lifetime = entry_ptr->lifetime + 120;
if (entry_ptr->lifetime > entry_ptr->link_lifetime) {
entry_ptr->lifetime = entry_ptr->link_lifetime;
}
/* For parents ARO registration is sent in link timeout times
* For candidate parents NUD is needed
* For children NUD is sent only at very close to end
*/
if (ipv6_neighbour_has_registered_by_eui64(&cur->ipv6_neighbour_cache, entry_ptr->mac64) &&
(time_from_start < WS_NEIGHBOR_NUD_TIMEOUT * 1.8)) {
/* This is our child with valid ARO registration send NUD if we are close to delete
*
* if ARO was received link is considered active so this is only in case of very long ARO registration times
*
* 1.8 means with link timeout of 30 minutes that NUD is sent 6 minutes before timeout
*
*/
return false;
}
@ -1766,6 +1895,11 @@ int ws_bootstrap_init(int8_t interface_id, net_6lowpan_mode_e bootstrap_mode)
goto init_fail;
}
if (ws_cfg_settings_interface_set(cur) < 0) {
ret_val = -4;
goto init_fail;
}
if (ws_bootstrap_tasklet_init(cur) != 0) {
ret_val = -4;
goto init_fail;
@ -1786,6 +1920,10 @@ int ws_bootstrap_init(int8_t interface_id, net_6lowpan_mode_e bootstrap_mode)
ret_val = -4;
goto init_fail;
}
if (ws_pae_controller_configure(cur, &cur->ws_info->cfg->sec_timer, &cur->ws_info->cfg->sec_prot) < 0) {
ret_val = -4;
goto init_fail;
}
//Init EAPOL PDU handler and register it to MPX
if (ws_eapol_pdu_init(cur) < 0) {
@ -1817,19 +1955,13 @@ int ws_bootstrap_init(int8_t interface_id, net_6lowpan_mode_e bootstrap_mode)
// Set the default parameters for MPL
cur->mpl_proactive_forwarding = true;
cur->mpl_data_trickle_params.Imin = MPL_MS_TO_TICKS(DATA_MESSAGE_IMIN);
cur->mpl_data_trickle_params.Imax = MPL_MS_TO_TICKS(DATA_MESSAGE_IMAX);
cur->mpl_data_trickle_params.TimerExpirations = DATA_MESSAGE_TIMER_EXPIRATIONS;
cur->mpl_data_trickle_params.k = 8;
// Specification is ruling out the compression mode, but we are now doing it.
cur->mpl_seed = true;
cur->mpl_seed_id_mode = MULTICAST_MPL_SEED_ID_IPV6_SRC_FOR_DOMAIN;
cur->mpl_seed_set_entry_lifetime = MPL_SEED_SET_ENTRY_TIMEOUT;
cur->mpl_control_trickle_params.TimerExpirations = 0;
mpl_domain_create(cur, ADDR_ALL_MPL_FORWARDERS, NULL, MULTICAST_MPL_SEED_ID_DEFAULT, -1, 0, NULL, NULL);
cur->mpl_domain = mpl_domain_create(cur, ADDR_ALL_MPL_FORWARDERS, NULL, MULTICAST_MPL_SEED_ID_DEFAULT, -1, 0, NULL, NULL);
addr_add_group(cur, ADDR_REALM_LOCAL_ALL_NODES);
addr_add_group(cur, ADDR_REALM_LOCAL_ALL_ROUTERS);
@ -1858,9 +1990,26 @@ int ws_bootstrap_restart(int8_t interface_id)
return 0;
}
int ws_bootstrap_restart_delayed(int8_t interface_id)
{
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
if (!cur || !cur->ws_info) {
return -1;
}
ws_bootstrap_state_change(cur, ER_WAIT_RESTART);
cur->bootsrap_state_machine_cnt = 3;
return 0;
}
int ws_bootstrap_set_rf_config(protocol_interface_info_entry_t *cur, phy_rf_channel_configuration_s rf_configs)
{
mlme_set_t set_request;
// Set MAC mode
phy_802_15_4_mode_t mac_mode = IEEE_802_15_4G_2012;
set_request.attr = mac802_15_4Mode;
set_request.value_pointer = &mac_mode;
set_request.value_size = sizeof(phy_802_15_4_mode_t);
cur->mac_api->mlme_req(cur->mac_api, MLME_SET, &set_request);
// Set RF configuration
set_request.attr = macRfConfiguration;
set_request.value_pointer = &rf_configs;
@ -1928,7 +2077,7 @@ static void ws_bootstrap_fhss_activate(protocol_interface_info_entry_t *cur)
mac_helper_pib_boolean_set(cur, macRxOnWhenIdle, true);
cur->lowpan_info &= ~INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE;
ws_bootstrap_mac_security_enable(cur);
ws_bootstrap_mac_activate(cur, cur->ws_info->fhss_uc_fixed_channel, cur->ws_info->network_pan_id, true);
ws_bootstrap_mac_activate(cur, cur->ws_info->cfg->fhss.fhss_uc_fixed_channel, cur->ws_info->network_pan_id, true);
return;
}
@ -1986,10 +2135,33 @@ static void ws_set_fhss_hop(protocol_interface_info_entry_t *cur)
tr_debug("own hop: %u, own rank: %u, rank inc: %u", own_hop, own_rank, rank_inc);
}
static void ws_address_registration_update(protocol_interface_info_entry_t *interface)
static void ws_address_registration_update(protocol_interface_info_entry_t *interface, const uint8_t addr[16])
{
rpl_control_register_address(interface, addr);
// Timer is used only to track full registrations
if (addr != NULL && interface->ws_info->aro_registration_timer) {
// Single address update and timer is running
return;
}
if (interface->ws_info->aro_registration_timer == 0) {
// Timer expired and check if we have valid address to register
ns_list_foreach(if_address_entry_t, address, &interface->ip_addresses) {
if (!addr_is_ipv6_link_local(address->address)) {
// We have still valid addresses let the timer run for next period
tr_info("ARO registration timer start");
interface->ws_info->aro_registration_timer = WS_NEIGHBOR_NUD_TIMEOUT;
return;
}
}
}
}
static void ws_address_parent_update(protocol_interface_info_entry_t *interface)
{
rpl_control_register_address(interface, NULL);
tr_info("RPL parent update ... register ARO");
ws_address_registration_update(interface, NULL);
}
static void ws_bootstrap_rpl_callback(rpl_event_t event, void *handle)
@ -2014,9 +2186,13 @@ static void ws_bootstrap_rpl_callback(rpl_event_t event, void *handle)
// Set both own port and border router port to 10253
ws_eapol_relay_start(cur, EAPOL_RELAY_SOCKET_PORT, dodag_info.dodag_id, EAPOL_RELAY_SOCKET_PORT);
// Set network information to PAE
ws_pae_controller_nw_info_set(cur, cur->ws_info->network_pan_id, cur->ws_info->network_name);
ws_pae_controller_nw_info_set(cur, cur->ws_info->network_pan_id, cur->ws_info->cfg->gen.network_name);
// Network key is valid
ws_pae_controller_nw_key_valid(cur);
// After successful DAO ACK connection to border router is verified
cur->ws_info->pan_timeout_timer = cur->ws_info->cfg->timing.pan_timeout;
}
ws_set_fhss_hop(cur);
@ -2031,7 +2207,7 @@ static void ws_bootstrap_rpl_callback(rpl_event_t event, void *handle)
*/
} else if (event == RPL_EVENT_DAO_PARENT_ADD) {
ws_address_registration_update(cur);
ws_address_parent_update(cur);
}
cur->ws_info->rpl_state = event;
tr_info("RPL event %d", event);
@ -2046,7 +2222,7 @@ static void ws_dhcp_client_global_adress_cb(int8_t interface, uint8_t dhcp_addr[
if (register_status) {
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface);
if (cur) {
rpl_control_register_address(cur, prefix);
ws_address_reregister_trig(cur);
}
} else {
//Delete dhcpv6 client
@ -2114,13 +2290,18 @@ static void ws_rpl_prefix_callback(prefix_entry_t *prefix, void *handle, uint8_t
static bool ws_rpl_candidate_soft_filtering(protocol_interface_info_entry_t *cur, struct rpl_instance *instance)
{
//If bootstrap active we not need any candidate filtering
if ((cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_ACTIVE) && (ws_info(cur)->cfg->gen.network_size == NETWORK_SIZE_CERTIFICATE)) {
return true;
}
//Already many candidates
if (rpl_control_candidate_list_size(cur, instance) > cur->ws_info->rpl_parent_candidate_max) {
if (rpl_control_candidate_list_size(cur, instance) > cur->ws_info->cfg->rpl.rpl_parent_candidate_max) {
return false;
}
//Already enough selected candidates
if (rpl_control_selected_parent_count(cur, instance) >= cur->ws_info->rpl_selected_parent_max) {
if (rpl_control_selected_parent_count(cur, instance) >= cur->ws_info->cfg->rpl.rpl_selected_parent_max) {
return false;
}
@ -2267,6 +2448,7 @@ static void ws_bootstrap_rpl_activate(protocol_interface_info_entry_t *cur)
rpl_control_process_routes(protocol_6lowpan_rpl_domain, false); // Wi-SUN assumes that no default route needed
rpl_control_request_parent_link_confirmation(true);
rpl_control_set_dio_multicast_min_config_advertisment_count(WS_MIN_DIO_MULTICAST_CONFIG_ADVERTISMENT_COUNT);
rpl_control_set_address_registration_timeout((WS_NEIGHBOR_LINK_TIMEOUT / 60) + 1);
rpl_control_set_dao_retry_count(WS_MAX_DAO_RETRIES);
rpl_control_set_initial_dao_ack_wait(WS_MAX_DAO_INITIAL_TIMEOUT);
rpl_control_set_mrhof_parent_set_size(WS_MAX_PARENT_SET_COUNT);
@ -2274,13 +2456,16 @@ static void ws_bootstrap_rpl_activate(protocol_interface_info_entry_t *cur)
rpl_control_set_memory_limits(WS_NODE_RPL_SOFT_MEM_LIMIT, WS_NODE_RPL_HARD_MEM_LIMIT);
}
// Set the minimum target refresh to sen DAO registrations before pan timeout
rpl_control_set_minimum_dao_target_refresh(WS_RPL_DAO_MAX_TIMOUT);
cur->ws_info->rpl_state = 0xff; // Set invalid state and learn from event
}
static void ws_bootstrap_network_start(protocol_interface_info_entry_t *cur)
{
//Set Network names, Pan information configure, hopping schedule & GTKHash
ws_llc_set_network_name(cur, (uint8_t *)cur->ws_info->network_name, strlen(cur->ws_info->network_name));
ws_llc_set_network_name(cur, (uint8_t *)cur->ws_info->cfg->gen.network_name, strlen(cur->ws_info->cfg->gen.network_name));
ws_llc_set_pan_information_pointer(cur, &cur->ws_info->pan_information);
}
@ -2289,11 +2474,11 @@ static void ws_bootstrap_network_discovery_configure(protocol_interface_info_ent
// Reset information to defaults
cur->ws_info->network_pan_id = 0xffff;
ws_common_regulatory_domain_config(cur);
ws_common_regulatory_domain_config(cur, &cur->ws_info->hopping_schdule);
ws_fhss_configure(cur, true);
//Set Network names, Pan information configure, hopping schedule & GTKHash
ws_llc_set_network_name(cur, (uint8_t *)cur->ws_info->network_name, strlen(cur->ws_info->network_name));
ws_llc_set_network_name(cur, (uint8_t *)cur->ws_info->cfg->gen.network_name, strlen(cur->ws_info->cfg->gen.network_name));
}
@ -2302,12 +2487,14 @@ static void ws_bootstrap_advertise_start(protocol_interface_info_entry_t *cur)
cur->ws_info->trickle_pa_running = true;
trickle_start(&cur->ws_info->trickle_pan_advertisement, &cur->ws_info->trickle_params_pan_discovery);
cur->ws_info->trickle_pc_running = true;
cur->ws_info->trickle_pc_consistency_block_period = 0;
trickle_start(&cur->ws_info->trickle_pan_config, &cur->ws_info->trickle_params_pan_discovery);
}
static void ws_bootstrap_pan_version_increment(protocol_interface_info_entry_t *cur)
{
cur->ws_info->pan_version_timer = 1;
(void)cur;
ws_bbr_pan_version_increase(cur);
}
// Start network scan
@ -2319,7 +2506,7 @@ static void ws_bootstrap_start_discovery(protocol_interface_info_entry_t *cur)
ws_bootstrap_state_change(cur, ER_ACTIVE_SCAN);
cur->nwk_nd_re_scan_count = 0;
cur->ws_info->configuration_learned = false;
cur->ws_info->pan_version_timeout_timer = 0;
cur->ws_info->pan_timeout_timer = 0;
// Clear learned neighbours
ws_bootstrap_neighbor_list_clean(cur);
@ -2369,7 +2556,7 @@ static void ws_bootstrap_start_discovery(protocol_interface_info_entry_t *cur)
static void ws_bootstrap_start_authentication(protocol_interface_info_entry_t *cur)
{
// Set PAN ID and network name to controller
ws_pae_controller_nw_info_set(cur, cur->ws_info->network_pan_id, cur->ws_info->network_name);
ws_pae_controller_nw_info_set(cur, cur->ws_info->network_pan_id, cur->ws_info->cfg->gen.network_name);
ws_pae_controller_authenticate(cur);
}
@ -2431,6 +2618,12 @@ static void ws_bootstrap_authentication_completed(protocol_interface_info_entry_
ws_bootstrap_candidate_parent_free(cur, target_eui_64);
// Go back for network scanning
ws_bootstrap_state_change(cur, ER_ACTIVE_SCAN);
// Start PAS interval between imin - imax.
cur->ws_info->trickle_pas_running = true;
trickle_start(&cur->ws_info->trickle_pan_advertisement_solicit, &cur->ws_info->trickle_params_pan_discovery);
// Parent selection is made before imin/2 so if there is parent candidates solicit is not sent
cur->bootsrap_state_machine_cnt = randLIB_get_random_in_range(10, cur->ws_info->trickle_params_pan_discovery.Imin >> 1);
tr_info("Making parent selection in %u s", (cur->bootsrap_state_machine_cnt / 10));
} else {
@ -2467,10 +2660,15 @@ static void ws_bootstrap_rpl_scan_start(protocol_interface_info_entry_t *cur)
// routers wait until RPL root is contacted
ws_bootstrap_state_change(cur, ER_RPL_SCAN);
//For Large network and medium shuold do passive scan
if (cur->ws_info->network_size_config == NETWORK_SIZE_LARGE || cur->ws_info->network_size_config == NETWORK_SIZE_MEDIUM) {
if (cur->ws_info->cfg->gen.network_size > NETWORK_SIZE_SMALL) {
// Set timeout for check to 30 -60 seconds
cur->bootsrap_state_machine_cnt = randLIB_get_random_in_range(WS_RPL_DIS_INITIAL_TIMEOUT / 2, WS_RPL_DIS_INITIAL_TIMEOUT);
}
/* While in Join State 4, if a non Border Router determines it has been unable to communicate with the PAN Border
* Router for an interval of PAN_TIMEOUT, a node MUST assume failure of the PAN Border Router and MUST
* Transition to Join State 1
*/
cur->ws_info->pan_timeout_timer = cur->ws_info->cfg->timing.pan_timeout;
}
/*
@ -2505,9 +2703,9 @@ void ws_bootstrap_configuration_trickle_reset(protocol_interface_info_entry_t *c
static void ws_set_asynch_channel_list(protocol_interface_info_entry_t *cur, asynch_request_t *async_req)
{
memset(&async_req->channel_list, 0, sizeof(channel_list_s));
if (cur->ws_info->fhss_uc_channel_function == WS_FIXED_CHANNEL) {
if (cur->ws_info->cfg->fhss.fhss_uc_channel_function == WS_FIXED_CHANNEL) {
//SET 1 Channel only
uint16_t channel_number = cur->ws_info->fhss_uc_fixed_channel;
uint16_t channel_number = cur->ws_info->cfg->fhss.fhss_uc_fixed_channel;
async_req->channel_list.channel_mask[0 + (channel_number / 32)] = (1 << (channel_number % 32));
} else {
ws_generate_channel_list(async_req->channel_list.channel_mask, cur->ws_info->hopping_schdule.number_of_channels, cur->ws_info->hopping_schdule.regulatory_domain);
@ -2581,6 +2779,10 @@ static uint16_t ws_bootstrap_routing_cost_calculate(protocol_interface_info_entr
//Scale to 128 based ETX (local read retur 0x100 - 0xffff
etx = etx >> 1;
}
// Make the 0xffff as maximum value
if (ws_neighbor->routing_cost + etx > 0xffff) {
return 0xffff;
}
return ws_neighbor->routing_cost + etx;
}
@ -2685,11 +2887,15 @@ static void ws_bootstrap_event_handler(arm_event_s *event)
cur->ws_info->pending_key_index_info.state = NO_PENDING_PROCESS;
cur->mac_parameters->mac_default_key_index = 0;
// Clear parent blacklist
blacklist_clear();
// All trickle timers stopped to allow entry from any state
cur->ws_info->trickle_pa_running = false;
cur->ws_info->trickle_pc_running = false;
cur->ws_info->trickle_pas_running = false;
cur->ws_info->trickle_pcs_running = false;
cur->ws_info->trickle_pc_consistency_block_period = 0;
if (cur->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER) {
tr_info("Border router start network");
@ -2703,9 +2909,13 @@ static void ws_bootstrap_event_handler(arm_event_s *event)
ws_pae_controller_auth_init(cur);
// Randomize fixed channels. Only used if channel plan is fixed.
cur->ws_info->fhss_uc_fixed_channel = ws_randomize_fixed_channel(cur->ws_info->fhss_uc_fixed_channel, cur->ws_info->hopping_schdule.number_of_channels);
cur->ws_info->fhss_bc_fixed_channel = ws_randomize_fixed_channel(cur->ws_info->fhss_bc_fixed_channel, cur->ws_info->hopping_schdule.number_of_channels);
cur->ws_info->network_pan_id = randLIB_get_random_in_range(0, 0xfffd);
cur->ws_info->cfg->fhss.fhss_uc_fixed_channel = ws_randomize_fixed_channel(cur->ws_info->cfg->fhss.fhss_uc_fixed_channel, cur->ws_info->hopping_schdule.number_of_channels);
cur->ws_info->cfg->fhss.fhss_bc_fixed_channel = ws_randomize_fixed_channel(cur->ws_info->cfg->fhss.fhss_bc_fixed_channel, cur->ws_info->hopping_schdule.number_of_channels);
if (cur->ws_info->cfg->gen.network_pan_id == 0xffff) {
cur->ws_info->network_pan_id = randLIB_get_random_in_range(0, 0xfffd);
} else {
cur->ws_info->network_pan_id = cur->ws_info->cfg->gen.network_pan_id;
}
cur->ws_info->pan_information.pan_size = 0;
cur->ws_info->pan_information.pan_version = randLIB_get_random_in_range(0, 0xffff);
cur->ws_info->pan_information.routing_cost = 0;
@ -2715,7 +2925,7 @@ static void ws_bootstrap_event_handler(arm_event_s *event)
uint8_t *gtkhash = ws_pae_controller_gtk_hash_ptr_get(cur);
ws_llc_set_gtkhash(cur, gtkhash);
cur->ws_info->pan_version_timer = ws_common_version_lifetime_get(cur->ws_info->network_size_config);
ws_bbr_pan_version_increase(cur);
// Set default parameters for FHSS when starting a discovery
ws_fhss_border_router_configure(cur);
@ -2735,7 +2945,7 @@ static void ws_bootstrap_event_handler(arm_event_s *event)
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->network_name);
ws_pae_controller_nw_info_set(cur, cur->ws_info->network_pan_id, cur->ws_info->cfg->gen.network_name);
// 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);
@ -2757,6 +2967,7 @@ static void ws_bootstrap_event_handler(arm_event_s *event)
cur->ws_info->trickle_pc_running = false;
cur->ws_info->trickle_pas_running = false;
cur->ws_info->trickle_pcs_running = false;
cur->ws_info->trickle_pc_consistency_block_period = 0;
// Build list of possible neighbours and learn first broadcast schedule
@ -2769,6 +2980,7 @@ static void ws_bootstrap_event_handler(arm_event_s *event)
cur->ws_info->trickle_pc_running = false;
cur->ws_info->trickle_pas_running = false;
cur->ws_info->trickle_pcs_running = false;
cur->ws_info->trickle_pc_consistency_block_period = 0;
// Activate RPL
// Activate IPv6 stack
ws_bootstrap_ip_stack_activate(cur);
@ -2788,6 +3000,7 @@ static void ws_bootstrap_event_handler(arm_event_s *event)
cur->ws_info->trickle_pc_running = false;
cur->ws_info->trickle_pas_running = false;
cur->ws_info->trickle_pcs_running = false;
cur->ws_info->trickle_pc_consistency_block_period = 0;
// Indicate PAE controller that bootstrap is ready
ws_pae_controller_bootstrap_done(cur);
@ -2947,6 +3160,7 @@ void ws_bootstrap_state_machine(protocol_interface_info_entry_t *cur)
cur->ws_info->trickle_pc_running = false;
cur->ws_info->trickle_pas_running = false;
cur->ws_info->trickle_pcs_running = false;
cur->ws_info->trickle_pc_consistency_block_period = 0;
ws_fhss_configure(cur, false);
ws_bootstrap_start_authentication(cur);
break;
@ -3007,27 +3221,58 @@ void ws_bootstrap_trickle_timer(protocol_interface_info_entry_t *cur, uint16_t t
tr_info("Send PAN advertisement");
ws_bootstrap_pan_advert(cur);
}
if (cur->ws_info->trickle_pc_running &&
trickle_timer(&cur->ws_info->trickle_pan_config, &cur->ws_info->trickle_params_pan_discovery, ticks)) {
// send PAN Configuration
tr_info("Send PAN configuration");
ws_bootstrap_pan_config(cur);
if (cur->ws_info->trickle_pc_running) {
if (cur->ws_info->trickle_pc_consistency_block_period) {
if (ticks >= cur->ws_info->trickle_pc_consistency_block_period) {
cur->ws_info->trickle_pc_consistency_block_period = 0;
} else {
cur->ws_info->trickle_pc_consistency_block_period -= ticks;
}
}
if (trickle_timer(&cur->ws_info->trickle_pan_config, &cur->ws_info->trickle_params_pan_discovery, ticks)) {
// send PAN Configuration
tr_info("Send PAN configuration");
ws_bootstrap_pan_config(cur);
}
}
}
void ws_bootstrap_seconds_timer(protocol_interface_info_entry_t *cur, uint32_t seconds)
{
if (cur->ws_info->pan_version_timeout_timer) {
/* Border router keep alive check
*/
if (cur->ws_info->pan_timeout_timer) {
// PAN version timer running
if (cur->ws_info->pan_version_timeout_timer > seconds) {
cur->ws_info->pan_version_timeout_timer -= seconds;
if (cur->ws_info->pan_timeout_timer > seconds) {
cur->ws_info->pan_timeout_timer -= seconds;
if (cur->ws_info->pan_timeout_timer < cur->ws_info->cfg->timing.pan_timeout / 10) {
/* pan timeout is closing need to verify that DAO is tested before the pan times out.
This will give some extra time for RPL to find better parents.
Border router liveliness can be checked from version number change or from successful DAO registrations
in this case there has not been any version number changes during this PAN lifetime.
*/
rpl_control_dao_timeout(cur->rpl_domain, 20);
}
} else {
// Border router has timed out
cur->ws_info->pan_timeout_timer = 0;
tr_warn("Border router has timed out");
ws_bootstrap_event_discovery_start(cur);
}
}
if (cur->ws_info->aro_registration_timer) {
if (cur->ws_info->aro_registration_timer > seconds) {
cur->ws_info->aro_registration_timer -= seconds;
} else {
// Update all addressess. This function will update the timer value if needed
cur->ws_info->aro_registration_timer = 0;
ws_address_registration_update(cur, NULL);
}
}
}
void ws_primary_parent_update(protocol_interface_info_entry_t *interface, mac_neighbor_table_entry_t *neighbor)
@ -3050,7 +3295,7 @@ void ws_secondary_parent_update(protocol_interface_info_entry_t *interface)
if (interface->ws_info) {
ns_list_foreach(if_address_entry_t, address, &interface->ip_addresses) {
if (!addr_is_ipv6_link_local(address->address)) {
ws_address_registration_update(interface);
ws_address_parent_update(interface);
}
}
}

View File

@ -30,6 +30,7 @@ typedef enum {
#ifdef HAVE_WS
struct llc_neighbour_req;
struct ws_us_ie;
int ws_bootstrap_init(int8_t interface_id, net_6lowpan_mode_e bootstrap_mode);
@ -37,6 +38,8 @@ void ws_bootstrap_state_machine(protocol_interface_info_entry_t *cur);
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);
@ -76,6 +79,8 @@ bool ws_eapol_relay_state_active(protocol_interface_info_entry_t *cur);
void ws_bootstrap_eapol_parent_synch(struct protocol_interface_info_entry *cur, struct llc_neighbour_req *neighbor_info);
bool ws_bootstrap_validate_channel_plan(struct ws_us_ie *ws_us, struct protocol_interface_info_entry *cur);
#else
#define ws_bootstrap_init(interface_id, bootstrap_mode) (-1)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,183 @@
/*
* Copyright (c) 2020, Arm Limited 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_CFG_STORAGE_H_
#define WS_CFG_STORAGE_H_
/**
* \brief Struct ws_gen_cfg_t General configuration
*/
typedef struct ws_gen_cfg_s {
/* Changing the network size resets the configuration settings depending on it to
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 */
} ws_gen_cfg_t;
/**
* \brief Struct ws_phy_cfg_t Physical layer configuration
*/
typedef struct ws_phy_cfg_s {
uint8_t regulatory_domain; /**< PHY regulatory domain; default "KR" 0x09 */
uint8_t operating_class; /**< PHY operating class; default 1 */
uint8_t operating_mode; /**< PHY operating mode; default "1b" symbol rate 50, modulation index 1 */
} ws_phy_cfg_t;
/**
* \brief Struct ws_timing_cfg_t Timing configuration
*/
typedef struct ws_timing_cfg_s {
uint16_t disc_trickle_imin; /**< Discovery trickle Imin; DISC_IMIN; seconds; range 1-255; default 30 */
uint16_t disc_trickle_imax; /**< Discovery trickle Imax; DISC_IMAX; seconds; range (2-2^8)*Imin; default 960 */
uint8_t disc_trickle_k; /**< Discovery trickle k; DISC_K; default 1 */
uint16_t pan_timeout; /**< PAN timeout; PAN_TIMEOUT; seconds; range 60-15300; default 3840 */
uint16_t temp_link_min_timeout; /**< Temporary neighbor link minimum timeout; seconds; default 260 */
} ws_timing_cfg_t;
/**
* \brief Struct ws_rpl_cfg_t RPL configuration
*/
typedef struct ws_rpl_cfg_s {
uint8_t dio_interval_min; /**> DIO interval min; DEFAULT_DIO_INTERVAL_MIN; 2^value in milliseconds; range 1-255; default */
uint8_t dio_interval_doublings; /**> DIO interval doublings; DEFAULT_DIO_INTERVAL_DOUBLINGS; range 1-8; default */
uint8_t dio_redundancy_constant; /**> DIO redundancy constant; DEFAULT_DIO_REDUNDANCY_CONSTANT; range 0-10; default */
uint16_t dag_max_rank_increase;
uint16_t min_hop_rank_increase;
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_rpl_cfg_t;
/**
* \brief Struct ws_fhss_cfg_t Frequency hopping configuration
*/
typedef struct ws_fhss_cfg_s {
uint8_t fhss_uc_dwell_interval; /**< FHSS unicast dwell interval; range 15-250 milliseconds; default 255 */
uint8_t fhss_bc_dwell_interval; /**< FHSS broadcast dwell interval; range 15-250 milliseconds; default 255 */
uint32_t fhss_bc_interval; /**< FHSS broadcast interval; duration between broadcast dwell intervals. range: 0-16777216 milliseconds; default 1020 */
uint8_t fhss_uc_channel_function; /**< FHSS WS unicast channel function; default 2 direct hash channel function */
uint8_t fhss_bc_channel_function; /**< FHSS WS broadcast channel function; default 2 direct hash channel function */
uint16_t fhss_uc_fixed_channel; /**< FHSS unicast fixed channel; default 0xffff */
uint16_t fhss_bc_fixed_channel; /**< FHSS broadcast fixed channel; default 0xffff */
uint32_t fhss_channel_mask[8]; /**< FHSS channel mask; default; 0xffffffff * 8 */
} ws_fhss_cfg_t;
/**
* \brief Struct ws_mpl_cfg_t Multicast configuration
*/
typedef struct ws_mpl_cfg_s {
uint16_t mpl_trickle_imin; /**< MPL trickle parameters Imin; DATA_MESSAGE_IMIN; seconds; range 1-255; default 10 */
uint16_t mpl_trickle_imax; /**< MPL trickle parameters Imax; DATA_MESSAGE_IMAX; seconds; range (2-2^8)*Imin; default 10 */
uint8_t mpl_trickle_k; /**< MPL trickle parameters k; default 8 */
uint8_t mpl_trickle_timer_exp; /**< MPL trickle parameters timer expirations; default 3 */
uint16_t seed_set_entry_lifetime; /**< MPL minimum seed set lifetime; seconds; default 960 */
} ws_mpl_cfg_t;
/**
* \brief Struct ws_sec_timer_cfg_t Security timers configuration
*/
typedef struct ws_sec_timer_cfg_s {
uint32_t gtk_expire_offset; /**< GTK lifetime; GTK_EXPIRE_OFFSET; minutes; default 43200 */
uint32_t pmk_lifetime; /**< PMK lifetime; minutes; default 172800 */
uint32_t ptk_lifetime; /**< PTK lifetime; minutes; default 86400 */
uint16_t gtk_new_act_time; /**< GTK_NEW_ACTIVATION_TIME (1/X of expire offset); default 720 */
uint16_t revocat_lifetime_reduct; /**< REVOCATION_LIFETIME_REDUCTION (reduction of lifetime); default 30 */
uint16_t gtk_request_imin; /**< GTK_REQUEST_IMIN; minutes; range 1-255; default 4 */
uint16_t gtk_request_imax; /**< GTK_REQUEST_IMAX; minutes; range (2-2^8)*Imin; default 64 */
uint16_t gtk_max_mismatch; /**< GTK_MAX_MISMATCH; minutes; default 64 */
uint8_t gtk_new_install_req; /**< GTK_NEW_INSTALL_REQUIRED; percent of GTK lifetime; range 1-100; default 80 */
} ws_sec_timer_cfg_t;
/**
* \brief Struct ws_sec_prot_cfg_t Security protocols configuration
*/
typedef struct ws_sec_prot_cfg_s {
uint16_t sec_prot_retry_timeout; /**< Security protocol retry timeout; seconds; default 330 */
uint16_t sec_prot_trickle_imin; /**< Security protocol trickle parameters Imin; seconds; default 30 */
uint16_t sec_prot_trickle_imax; /**< Security protocol trickle parameters Imax; seconds; default 90 */
uint8_t sec_prot_trickle_timer_exp; /**< Security protocol trickle timer expirations; default 2 */
} ws_sec_prot_cfg_t;
/**
* \brief Struct ws_nw_size_cfg_t Network size configuration
*/
typedef struct ws_cfg_s {
ws_gen_cfg_t gen; /**< General configuration */
ws_phy_cfg_t phy; /**< Physical layer configuration */
ws_timing_cfg_t timing; /**< Timing configuration */
ws_rpl_cfg_t rpl; /**< RPL configuration */
ws_fhss_cfg_t fhss; /**< Frequency hopping configuration */
ws_mpl_cfg_t mpl; /**< Multicast configuration */
ws_sec_timer_cfg_t sec_timer; /**< Security timers configuration */
ws_sec_prot_cfg_t sec_prot; /**< Security protocols configuration */
} ws_cfg_t;
/** Configuration setting errors. */
#define CFG_SETTINGS_PARAMETER_ERROR -1 /**< Function parameter error */
#define CFG_SETTINGS_OTHER_ERROR -2 /**< Other error */
#define CFG_SETTINGS_ERROR_NW_SIZE_CONF -10 /**< Network size configuration error */
#define CFG_SETTINGS_ERROR_GEN_CONF -11 /**< General configuration error */
#define CFG_SETTINGS_ERROR_PHY_CONF -12 /**< Physical layer configuration error */
#define CFG_SETTINGS_ERROR_TIMING_CONF -13 /**< Timing configuration error */
#define CFG_SETTINGS_ERROR_RPL_CONF -14 /**< RPL configuration error */
#define CFG_SETTINGS_ERROR_FHSS_CONF -15 /**< Frequency hopping configuration error */
#define CFG_SETTINGS_ERROR_MPL_CONF -16 /**< Multicast configuration error */
#define CFG_SETTINGS_ERROR_SEC_TIMER_CONF -17 /**< Security timers configuration error */
#define CFG_SETTINGS_ERROR_SEC_PROT_CONF -18 /**< Security protocols configuration error */
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_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_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_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_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_rpl_get(ws_rpl_cfg_t *cfg, uint8_t *flags);
int8_t ws_cfg_rpl_validate(ws_rpl_cfg_t *cfg, ws_rpl_cfg_t *new_cfg);
int8_t ws_cfg_rpl_set(protocol_interface_info_entry_t *cur, ws_rpl_cfg_t *cfg, ws_rpl_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_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_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_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);
#endif // WS_CFG_STORAGE_H_

View File

@ -29,6 +29,7 @@
#include "6LoWPAN/ws/ws_bootstrap.h"
#include "6LoWPAN/ws/ws_bbr_api_internal.h"
#include "6LoWPAN/ws/ws_pae_controller.h"
#include "6LoWPAN/ws/ws_cfg_settings.h"
#include "Service_Libs/etx/etx.h"
#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h"
#include "Service_Libs/blacklist/blacklist.h"
@ -44,30 +45,7 @@
// This provides a range of -174 (0) to +80 (254) dBm
uint8_t DEVICE_MIN_SENS = 174 - 93;
#define TRICKLE_IMIN_60_SECS (60 * 10)
#define TRICKLE_IMIN_30_SECS (30 * 10)
#define TRICKLE_IMIN_15_SECS (15 * 10)
static const trickle_params_t trickle_params_pan_discovery_large = {
.Imin = TRICKLE_IMIN_60_SECS, /* 60 second; ticks are 1s */
.Imax = TRICKLE_IMIN_60_SECS << 4, /* 960 seconds 16 min*/
.k = 1, /* 1 */
.TimerExpirations = TRICKLE_EXPIRATIONS_INFINITE
};
static const trickle_params_t trickle_params_pan_discovery_medium = {
.Imin = TRICKLE_IMIN_30_SECS, /* 30 second; ticks are 1s */
.Imax = TRICKLE_IMIN_30_SECS << 5, /* 960 seconds 16 min*/
.k = 1, /* 1 */
.TimerExpirations = TRICKLE_EXPIRATIONS_INFINITE
};
static const trickle_params_t trickle_params_pan_discovery_small = {
.Imin = TRICKLE_IMIN_15_SECS, /* 15 second; ticks are 1s */
.Imax = TRICKLE_IMIN_15_SECS << 2, /* 60 seconds 1 min*/
.k = 1, /* 1 */
.TimerExpirations = TRICKLE_EXPIRATIONS_INFINITE
};
uint16_t test_max_child_count_override = 0xffff;
@ -135,92 +113,98 @@ static int ws_set_domain_rf_config(protocol_interface_info_entry_t *cur)
return 0;
}
int8_t ws_common_regulatory_domain_config(protocol_interface_info_entry_t *cur)
int8_t ws_common_regulatory_domain_config(protocol_interface_info_entry_t *cur, ws_hopping_schedule_t *hopping_schdule)
{
cur->ws_info->hopping_schdule.channel_plan = 0;
if (ws_get_datarate_using_operating_mode(hopping_schdule->operating_mode) == 0) {
//Unsupported operation mode
return -1;
}
if (cur->ws_info->hopping_schdule.regulatory_domain == REG_DOMAIN_KR) {
if (cur->ws_info->hopping_schdule.operating_class == 1) {
cur->ws_info->hopping_schdule.ch0_freq = 9171;
cur->ws_info->hopping_schdule.channel_spacing = CHANNEL_SPACING_200;
} else if (cur->ws_info->hopping_schdule.operating_class == 2) {
cur->ws_info->hopping_schdule.ch0_freq = 9173;
cur->ws_info->hopping_schdule.channel_spacing = CHANNEL_SPACING_400;
hopping_schdule->channel_plan = 0;
if (hopping_schdule->regulatory_domain == REG_DOMAIN_KR) {
if (hopping_schdule->operating_class == 1) {
hopping_schdule->ch0_freq = 9171;
hopping_schdule->channel_spacing = CHANNEL_SPACING_200;
} else if (hopping_schdule->operating_class == 2) {
hopping_schdule->ch0_freq = 9173;
hopping_schdule->channel_spacing = CHANNEL_SPACING_400;
} else {
return -1;
}
} else if (cur->ws_info->hopping_schdule.regulatory_domain == REG_DOMAIN_EU) {
if (cur->ws_info->hopping_schdule.operating_class == 1) {
cur->ws_info->hopping_schdule.ch0_freq = 8631;
cur->ws_info->hopping_schdule.channel_spacing = CHANNEL_SPACING_100;
} else if (cur->ws_info->hopping_schdule.operating_class == 2) {
cur->ws_info->hopping_schdule.ch0_freq = 8631;
cur->ws_info->hopping_schdule.channel_spacing = CHANNEL_SPACING_200;
} else if (cur->ws_info->hopping_schdule.operating_class == 3) {
cur->ws_info->hopping_schdule.ch0_freq = 8701;
cur->ws_info->hopping_schdule.channel_spacing = CHANNEL_SPACING_100;
} else if (cur->ws_info->hopping_schdule.operating_class == 4) {
cur->ws_info->hopping_schdule.ch0_freq = 8702;
cur->ws_info->hopping_schdule.channel_spacing = CHANNEL_SPACING_200;
} 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;
} else {
return -1;
}
} else if (cur->ws_info->hopping_schdule.regulatory_domain == REG_DOMAIN_IN) {
if (cur->ws_info->hopping_schdule.operating_class == 1) {
cur->ws_info->hopping_schdule.ch0_freq = 8651;
cur->ws_info->hopping_schdule.channel_spacing = CHANNEL_SPACING_100;
} else if (cur->ws_info->hopping_schdule.operating_class == 2) {
cur->ws_info->hopping_schdule.ch0_freq = 8651;
cur->ws_info->hopping_schdule.channel_spacing = CHANNEL_SPACING_200;
} else if (hopping_schdule->regulatory_domain == REG_DOMAIN_IN) {
if (hopping_schdule->operating_class == 1) {
hopping_schdule->ch0_freq = 8651;
hopping_schdule->channel_spacing = CHANNEL_SPACING_100;
} else if (hopping_schdule->operating_class == 2) {
hopping_schdule->ch0_freq = 8651;
hopping_schdule->channel_spacing = CHANNEL_SPACING_200;
} else {
return -1;
}
} else if (cur->ws_info->hopping_schdule.regulatory_domain == REG_DOMAIN_NA) {
if (cur->ws_info->hopping_schdule.operating_class == 1) {
cur->ws_info->hopping_schdule.ch0_freq = 9022;
cur->ws_info->hopping_schdule.channel_spacing = CHANNEL_SPACING_200;
} else if (cur->ws_info->hopping_schdule.operating_class == 2) {
cur->ws_info->hopping_schdule.ch0_freq = 9024;
cur->ws_info->hopping_schdule.channel_spacing = CHANNEL_SPACING_400;
} else if (cur->ws_info->hopping_schdule.operating_class == 3) {
cur->ws_info->hopping_schdule.ch0_freq = 9026;
cur->ws_info->hopping_schdule.channel_spacing = CHANNEL_SPACING_600;
} else if (hopping_schdule->regulatory_domain == REG_DOMAIN_NA) {
if (hopping_schdule->operating_class == 1) {
hopping_schdule->ch0_freq = 9022;
hopping_schdule->channel_spacing = CHANNEL_SPACING_200;
} else if (hopping_schdule->operating_class == 2) {
hopping_schdule->ch0_freq = 9024;
hopping_schdule->channel_spacing = CHANNEL_SPACING_400;
} else if (hopping_schdule->operating_class == 3) {
hopping_schdule->ch0_freq = 9026;
hopping_schdule->channel_spacing = CHANNEL_SPACING_600;
} else {
return -1;
}
} else if (cur->ws_info->hopping_schdule.regulatory_domain == REG_DOMAIN_JP) {
if (cur->ws_info->hopping_schdule.operating_class == 1) {
cur->ws_info->hopping_schdule.ch0_freq = 9206;
cur->ws_info->hopping_schdule.channel_spacing = CHANNEL_SPACING_200;
} else if (cur->ws_info->hopping_schdule.operating_class == 2) {
cur->ws_info->hopping_schdule.ch0_freq = 9209;
cur->ws_info->hopping_schdule.channel_spacing = CHANNEL_SPACING_400;
} else if (cur->ws_info->hopping_schdule.operating_class == 3) {
cur->ws_info->hopping_schdule.ch0_freq = 9208;
cur->ws_info->hopping_schdule.channel_spacing = CHANNEL_SPACING_600;
} else if (hopping_schdule->regulatory_domain == REG_DOMAIN_JP) {
if (hopping_schdule->operating_class == 1) {
hopping_schdule->ch0_freq = 9206;
hopping_schdule->channel_spacing = CHANNEL_SPACING_200;
} else if (hopping_schdule->operating_class == 2) {
hopping_schdule->ch0_freq = 9209;
hopping_schdule->channel_spacing = CHANNEL_SPACING_400;
} else if (hopping_schdule->operating_class == 3) {
hopping_schdule->ch0_freq = 9208;
hopping_schdule->channel_spacing = CHANNEL_SPACING_600;
} else {
return -1;
}
} else if (cur->ws_info->hopping_schdule.regulatory_domain == REG_DOMAIN_WW) {
if (cur->ws_info->hopping_schdule.operating_class == 1) {
cur->ws_info->hopping_schdule.ch0_freq = 24002;
cur->ws_info->hopping_schdule.channel_spacing = CHANNEL_SPACING_200;
} else if (cur->ws_info->hopping_schdule.operating_class == 2) {
cur->ws_info->hopping_schdule.ch0_freq = 24004;
cur->ws_info->hopping_schdule.channel_spacing = CHANNEL_SPACING_400;
} else if (hopping_schdule->regulatory_domain == REG_DOMAIN_WW) {
if (hopping_schdule->operating_class == 1) {
hopping_schdule->ch0_freq = 24002;
hopping_schdule->channel_spacing = CHANNEL_SPACING_200;
} else if (hopping_schdule->operating_class == 2) {
hopping_schdule->ch0_freq = 24004;
hopping_schdule->channel_spacing = CHANNEL_SPACING_400;
} else {
return -1;
}
} else {
return -1;
}
cur->ws_info->hopping_schdule.number_of_channels = (uint8_t)ws_common_channel_number_calc(cur->ws_info->hopping_schdule.regulatory_domain, cur->ws_info->hopping_schdule.operating_class);
if (!cur->ws_info->hopping_schdule.number_of_channels) {
hopping_schdule->number_of_channels = (uint8_t)ws_common_channel_number_calc(hopping_schdule->regulatory_domain, hopping_schdule->operating_class);
if (!hopping_schdule->number_of_channels) {
return -1;
}
// Note: doesn't work for Brazil region
ws_generate_channel_list(cur->ws_info->hopping_schdule.channel_mask, cur->ws_info->hopping_schdule.number_of_channels, cur->ws_info->hopping_schdule.regulatory_domain);
ws_set_domain_rf_config(cur);
if (cur) {
ws_set_domain_rf_config(cur);
}
return 0;
}
@ -292,10 +276,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->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.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;
cur->ws_info->hopping_schdule.operating_mode = OPERATING_MODE_3;
cur->ws_info->hopping_schdule.operating_class = 2;
@ -303,70 +290,12 @@ int8_t ws_common_allocate_and_init(protocol_interface_info_entry_t *cur)
cur->ws_info->hopping_schdule.clock_drift = 255;
// Timing accuracy is given from 0 to 2.55msec with 10usec resolution
cur->ws_info->hopping_schdule.timing_accurancy = 100;
ws_common_regulatory_domain_config(cur);
cur->ws_info->network_size_config = NETWORK_SIZE_MEDIUM;
cur->ws_info->rpl_parent_candidate_max = WS_RPL_PARENT_CANDIDATE_MAX;
cur->ws_info->rpl_selected_parent_max = WS_RPL_SELECTED_PARENT_MAX;
ws_common_network_size_configure(cur, 200); // defaults to medium network size
// Set defaults for the device. user can modify these.
cur->ws_info->fhss_uc_fixed_channel = 0xffff;
cur->ws_info->fhss_bc_fixed_channel = 0xffff;
cur->ws_info->fhss_uc_dwell_interval = WS_FHSS_UC_DWELL_INTERVAL;
cur->ws_info->fhss_bc_interval = WS_FHSS_BC_INTERVAL;
cur->ws_info->fhss_bc_dwell_interval = WS_FHSS_BC_DWELL_INTERVAL;
cur->ws_info->fhss_uc_channel_function = WS_DH1CF;
cur->ws_info->fhss_bc_channel_function = WS_DH1CF;
ws_common_regulatory_domain_config(cur, &cur->ws_info->hopping_schdule);
cur->ws_info->pending_key_index_info.state = NO_PENDING_PROCESS;
for (uint8_t n = 0; n < 8; n++) {
cur->ws_info->fhss_channel_mask[n] = 0xffffffff;
}
return 0;
}
void ws_common_network_size_configure(protocol_interface_info_entry_t *cur, uint16_t network_size)
{
// TODO Modify NUD timings based on network size
// TODO Modify EAPOLL timings
if (network_size < 100) {
// Configure the Wi-SUN discovery trickle parameters
cur->ws_info->trickle_params_pan_discovery = trickle_params_pan_discovery_small;
// default values are for Wi-SUN small network parameters
// imin: 14 (16s)
// doublings:3 (128s)
// redundancy; 0 Disabled
if (cur->ws_info->network_size_config == NETWORK_SIZE_AUTOMATIC) {
ws_bbr_rpl_config(cur, 14, 3, 0, WS_RPL_MAX_HOP_RANK_INCREASE, WS_RPL_MIN_HOP_RANK_INCREASE);
} else if (cur->ws_info->network_size_config == NETWORK_SIZE_CERTIFICATE) {
ws_bbr_rpl_config(cur, 0, 0, 0, WS_CERTIFICATE_RPL_MAX_HOP_RANK_INCREASE, WS_CERTIFICATE_RPL_MIN_HOP_RANK_INCREASE);
} else {
ws_bbr_rpl_config(cur, 0, 0, 0, WS_RPL_MAX_HOP_RANK_INCREASE, WS_RPL_MIN_HOP_RANK_INCREASE);
}
ws_pae_controller_timing_adjust(1); // Fast and reactive network
} else if (network_size < 300) {
// Configure the Wi-SUN discovery trickle parameters
cur->ws_info->trickle_params_pan_discovery = trickle_params_pan_discovery_medium;
// Something in between
// imin: 15 (32s)
// doublings:5 (960s)
// redundancy; 10
ws_bbr_rpl_config(cur, 15, 5, 10, WS_RPL_MAX_HOP_RANK_INCREASE, WS_RPL_MIN_HOP_RANK_INCREASE);
ws_pae_controller_timing_adjust(9); // medium limited network
} else {
// Configure the Wi-SUN discovery trickle parameters
cur->ws_info->trickle_params_pan_discovery = trickle_params_pan_discovery_large;
// Wi-SUN Large network parameters
// imin: 19 (524s, 9 min)
// doublings:1 (1048s, 17 min)
// redundancy; 10 May need some tuning still
ws_bbr_rpl_config(cur, 19, 1, 10, WS_RPL_MAX_HOP_RANK_INCREASE, WS_RPL_MIN_HOP_RANK_INCREASE);
ws_pae_controller_timing_adjust(24); // Very slow and high latency network
}
return;
}
void ws_common_seconds_timer(protocol_interface_info_entry_t *cur, uint32_t seconds)
{
@ -418,6 +347,14 @@ uint8_t ws_common_allow_child_registration(protocol_interface_info_entry_t *inte
//Validate Is EUI64 already allocated for any address
if (ipv6_neighbour_has_registered_by_eui64(&interface->ipv6_neighbour_cache, eui64)) {
/*
* ARO registration from child can update the link timeout so we don't need to send extra NUD if ARO received
*/
mac_neighbor_table_entry_t *mac_neighbor = mac_neighbor_entry_get_by_mac64(mac_neighbor_info(interface), eui64, false, false);
if (mac_neighbor) {
mac_neighbor_table_neighbor_refresh(mac_neighbor_info(interface), mac_neighbor, mac_neighbor->link_lifetime);
}
tr_info("Child registration from old child");
return ARO_SUCCESS;
}
@ -456,35 +393,53 @@ bool ws_common_negative_aro_mark(protocol_interface_info_entry_t *interface, con
return true;
}
uint32_t ws_common_version_lifetime_get(uint8_t config)
uint32_t ws_common_latency_estimate_get(protocol_interface_info_entry_t *cur)
{
uint32_t lifetime;
if (config == NETWORK_SIZE_SMALL || config == NETWORK_SIZE_CERTIFICATE) {
lifetime = PAN_VERSION_SMALL_NETWORK_LIFETIME;
} else if (config == NETWORK_SIZE_MEDIUM) {
lifetime = PAN_VERSION_MEDIUM_NETWORK_LIFETIME;
} else {
lifetime = PAN_VERSION_LARGE_NETWORK_LIFETIME;
uint32_t latency = 0;
uint8_t network_size = cur->ws_info->cfg->gen.network_size;
if (network_size == NETWORK_SIZE_AUTOMATIC) {
network_size = cur->ws_info->pan_information.pan_size / 100;
}
return lifetime;
}
uint32_t ws_common_version_timeout_get(uint8_t config)
{
uint32_t lifetime;
if (config == NETWORK_SIZE_SMALL || config == NETWORK_SIZE_CERTIFICATE) {
lifetime = PAN_VERSION_SMALL_NETWORK_TIMEOUT;
} else if (config == NETWORK_SIZE_MEDIUM) {
lifetime = PAN_VERSION_MEDIUM_NETWORK_TIMEOUT;
} else {
lifetime = PAN_VERSION_LARGE_NETWORK_TIMEOUT;
if (network_size <= NETWORK_SIZE_SMALL) {
// handles also NETWORK_SIZE_CERTIFICATE
latency = 8000;
} else if (network_size <= NETWORK_SIZE_MEDIUM) {
latency = 16000;
} else {
latency = 32000;
}
return lifetime;
return latency;
}
uint32_t ws_common_datarate_get(protocol_interface_info_entry_t *cur)
{
return ws_get_datarate_using_operating_mode(cur->ws_info->hopping_schdule.operating_mode);
}
uint32_t ws_common_network_size_estimate_get(protocol_interface_info_entry_t *cur)
{
uint32_t network_size_estimate = 0;
uint8_t network_size = cur->ws_info->cfg->gen.network_size;
if (network_size == NETWORK_SIZE_AUTOMATIC) {
network_size = cur->ws_info->pan_information.pan_size / 100;
}
if (network_size <= NETWORK_SIZE_SMALL) {
// tens of devices (now 30), handles also NETWORK_SIZE_CERTIFICATE
network_size_estimate = 30;
} else if (network_size <= NETWORK_SIZE_MEDIUM) {
// hundreds of devices (now 300)
network_size_estimate = 300;
} else {
// huge amount of devices (now 1000)
network_size_estimate = 1000;
}
return network_size_estimate;
}
#endif // HAVE_WS

View File

@ -35,6 +35,8 @@ extern uint16_t test_max_child_count_override;
struct ws_pan_information_s;
struct ws_neighbor_class_s;
struct ws_excluded_channel_data_s;
struct ws_cfg_s;
typedef struct parent_info_s {
uint16_t pan_id; /**< PAN ID */
@ -46,6 +48,7 @@ typedef struct parent_info_s {
ws_us_ie_t ws_us;
uint32_t timestamp; /**< Timestamp when packet was received */
uint32_t age; /**< Age of entry in 100ms ticks */
uint8_t excluded_channel_data[32]; //Channel mask Max length and it accept 8 different range
ns_list_link_t link;
} parent_info_t;
@ -72,45 +75,33 @@ typedef struct {
typedef NS_LIST_HEAD(ws_nud_table_entry_t, link) ws_nud_table_list_t;
typedef struct ws_info_s {
char network_name[33]; // Network name max 32 octets + terminating 0.
uint16_t network_pan_id;
trickle_t trickle_pan_config_solicit;
trickle_t trickle_pan_config;
trickle_t trickle_pan_advertisement_solicit;
trickle_t trickle_pan_advertisement;
trickle_params_t trickle_params_pan_discovery;
uint8_t network_size_config; // configuration for network size selection of application.
uint16_t rpl_parent_candidate_max;
uint16_t rpl_selected_parent_max;
uint8_t rpl_state; // state from rpl_event_t
uint8_t pas_requests; // Amount of PAN solicits sent
parent_info_t parent_info[WS_PARENT_LIST_SIZE];
parent_info_list_t parent_list_free;
parent_info_list_t parent_list_reserved;
uint16_t aro_registration_timer; /**< Aro registration timer */
uint16_t rpl_version_timer; /**< RPL version update timeout */
uint32_t pan_version_timer; /**< border router version update timeout */
uint32_t pan_version_timeout_timer; /**< routers will fallback to previous state after this */
uint32_t pan_timeout_timer; /**< routers will fallback to previous state after this */
uint32_t pan_config_sol_max_timeout;
uint8_t gtkhash[32];
uint16_t network_pan_id;
bool configuration_learned: 1;
bool trickle_pas_running: 1;
bool trickle_pa_running: 1;
bool trickle_pcs_running: 1;
bool trickle_pc_running: 1;
uint16_t trickle_pc_consistency_block_period;
ws_pending_key_index_t pending_key_index_info;
// default fhss parameters for this device
uint8_t fhss_uc_dwell_interval;
uint8_t fhss_bc_dwell_interval;
uint32_t fhss_bc_interval;
uint8_t fhss_uc_channel_function;
uint8_t fhss_bc_channel_function;
uint16_t fhss_uc_fixed_channel;
uint16_t fhss_bc_fixed_channel;
uint32_t fhss_channel_mask[8];
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;
struct ws_cfg_s *cfg; /**< Wi-SUN configuration */
struct ws_pan_information_s pan_information;
ws_hopping_schedule_t hopping_schdule;
struct ws_statistics *stored_stats_ptr;
@ -123,14 +114,12 @@ typedef struct ws_info_s {
int8_t ws_generate_channel_list(uint32_t *channel_mask, uint16_t number_of_channels, uint8_t regulatory_domain);
int8_t ws_common_regulatory_domain_config(protocol_interface_info_entry_t *cur);
int8_t ws_common_regulatory_domain_config(protocol_interface_info_entry_t *cur, ws_hopping_schedule_t *hopping_schdule);
uint16_t ws_common_channel_number_calc(uint8_t regulatory_domain, uint8_t operating_class);
int8_t ws_common_allocate_and_init(protocol_interface_info_entry_t *cur);
void ws_common_network_size_configure(protocol_interface_info_entry_t *cur, uint16_t network_size);
void ws_common_seconds_timer(protocol_interface_info_entry_t *cur, uint32_t seconds);
void ws_common_fast_timer(protocol_interface_info_entry_t *cur, uint16_t ticks);
@ -145,11 +134,14 @@ uint8_t ws_common_allow_child_registration(protocol_interface_info_entry_t *cur,
bool ws_common_negative_aro_mark(protocol_interface_info_entry_t *interface, const uint8_t *eui64);
uint32_t ws_common_version_lifetime_get(uint8_t config);
uint32_t ws_common_version_timeout_get(uint8_t config);
uint32_t ws_common_latency_estimate_get(protocol_interface_info_entry_t *cur);
uint32_t ws_common_datarate_get(protocol_interface_info_entry_t *cur);
uint32_t ws_common_network_size_estimate_get(protocol_interface_info_entry_t *cur);
#define ws_info(cur) ((cur)->ws_info)
#else
#define ws_info(cur) ((ws_info_t *) NULL)
@ -160,6 +152,9 @@ uint32_t ws_common_version_timeout_get(uint8_t config);
#define ws_common_fast_timer(cur, ticks) ((void) 0)
#define ws_common_allow_child_registration(cur, eui64) (2)
#define ws_common_negative_aro_mark(interface, eui64)(false)
#define ws_common_latency_estimate_get(cur) 0
#define ws_common_datarate_get(cur) 0
#define ws_common_network_size_estimate_get(cur) 0
#endif //HAVE_WS
#endif //WS_COMMON_H_

View File

@ -51,6 +51,12 @@
#define WS_FT_ACK 5 /**< Enhanced ACK */
#define WS_FT_EAPOL 6 /**< EAPOL message inside MPX */
/* 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_EXCLUDED_MAX_RANGE_TO_SEND 3
/**
* @brief ws_pan_information_t PAN information
@ -64,6 +70,26 @@ typedef struct ws_pan_information_s {
unsigned version: 3; /**< Pan version support. */
} ws_pan_information_t;
/**
* @brief ws_excluded_channel_range_data_t Excludd Chanel range information
*/
typedef struct ws_excluded_channel_range_data_s {
uint16_t range_start;
uint16_t range_end;
} ws_excluded_channel_range_data_t;
/**
* @brief ws_excluded_channel_data_t Excludd Chanel information
*/
typedef struct ws_excluded_channel_data_s {
unsigned excuded_channel_ctrl: 2;
unsigned excluded_range_length: 3;
ws_excluded_channel_range_data_t exluded_range[WS_EXCLUDED_MAX_RANGE_TO_SEND];
uint16_t excluded_channel_count;
uint8_t channel_mask_bytes_inline;
uint32_t channel_mask[8];
} ws_excluded_channel_data_t;
/**
* @brief ws_hopping_schedule_t Chanel hopping schedule information
*/
@ -84,8 +110,8 @@ typedef struct ws_hopping_schedule_s {
uint16_t bc_fixed_channel;
uint16_t fhss_bsi;
uint32_t fhss_broadcast_interval;
uint32_t channel_mask[8];
uint_fast24_t ch0_freq; // Default should be derived from regulatory domain
ws_excluded_channel_data_t excluded_channels;
} ws_hopping_schedule_t;
/**
@ -137,6 +163,22 @@ typedef struct ws_channel_function_three {
uint8_t *channel_list;
} ws_channel_function_three_t;
/**
* @brief ws_excluded_channel_range_t WS excluded channel range
*/
typedef struct ws_excluded_channel_range {
uint8_t number_of_range;
uint8_t *range_start;
} ws_excluded_channel_range_t;
/**
* @brief ws_excluded_channel_mask_t WS excluded channel mask
*/
typedef struct ws_excluded_channel_mask {
uint8_t *channel_mask;
uint8_t mask_len_inline;
} ws_excluded_channel_mask_t;
/**
* @brief ws_us_ie_t WS US-IE read
*/
@ -155,6 +197,10 @@ typedef struct ws_us_ie {
ws_channel_function_zero_t zero;
ws_channel_function_three_t three;
} function;
union {
ws_excluded_channel_range_t range;
ws_excluded_channel_mask_t mask;
} excluded_channels;
} ws_us_ie_t;
/**
@ -249,6 +295,11 @@ typedef struct ws_bs_ie {
*/
#define WS_TACK_MAX_MS 5
/*
* Config new version consistent filter period in 100ms periods
*/
#define WS_CONFIG_CONSISTENT_FILTER_PERIOD 100
// With FHSS we need to check CCA twice on TX channel
#define WS_NUMBER_OF_CSMA_PERIODS 2
// Interval between two CCA checks

View File

@ -27,9 +27,21 @@
*
*/
#define WS_RPL_DIO_IMIN 15
#define WS_RPL_DIO_DOUBLING 2
#define WS_RPL_DIO_REDUNDANCY 0
#define WS_RPL_DIO_IMIN_SMALL 15
#define WS_RPL_DIO_DOUBLING_SMALL 2
#define WS_RPL_DIO_REDUNDANCY_SMALL 0
#define WS_RPL_DIO_IMIN_MEDIUM 15
#define WS_RPL_DIO_DOUBLING_MEDIUM 5
#define WS_RPL_DIO_REDUNDANCY_MEDIUM 10
#define WS_RPL_DIO_IMIN_LARGE 19
#define WS_RPL_DIO_DOUBLING_LARGE 1
#define WS_RPL_DIO_REDUNDANCY_LARGE 10 // May need some tuning still
#define WS_RPL_DIO_IMIN_AUTOMATIC 14
#define WS_RPL_DIO_DOUBLING_AUTOMATIC 3
#define WS_RPL_DIO_REDUNDANCY_AUTOMATIC 0
#define WS_RPL_MIN_HOP_RANK_INCREASE 196
#define WS_RPL_MAX_HOP_RANK_INCREASE 2048
@ -37,14 +49,17 @@
#define WS_CERTIFICATE_RPL_MIN_HOP_RANK_INCREASE 128
#define WS_CERTIFICATE_RPL_MAX_HOP_RANK_INCREASE 0
/*
* RPL DAO timeout maximum value. This will force DAO timeout to happen before this time
*/
#define WS_RPL_DAO_MAX_TIMOUT (3600*2)
/* Border router version change interval
*
* Minimum interval at which a Border Router shall increment its PAN Version value.
* Amount of version increases border router makes during PAN_TIMEOUT time
*/
#define PAN_VERSION_SMALL_NETWORK_LIFETIME 4*60
#define PAN_VERSION_MEDIUM_NETWORK_LIFETIME 15*60
#define PAN_VERSION_LARGE_NETWORK_LIFETIME 30*60 //30min
#define PAN_VERSION_CHANGE_INTERVAL 3
// RPL version number update intervall
// after restart version numbers are increased faster and then slowed down when network is stable
@ -101,10 +116,11 @@ extern uint8_t DEVICE_MIN_SENS;
* IMIN = 10 seconds, IMAX = 3 doublings
*/
#define DATA_MESSAGE_IMIN (10 * 1000)
#define DATA_MESSAGE_IMIN 10
#define DATA_MESSAGE_TIMER_EXPIRATIONS 3
#define DATA_MESSAGE_IMAX (80 * 1000)
#define MPL_SEED_SET_ENTRY_TIMEOUT (DATA_MESSAGE_IMAX * 24 * 4 / 1000) // 10 seconds per hop making this 240 seconds
#define DATA_MESSAGE_IMAX 80
#define DATA_MESSAGE_K 8
#define MPL_SEED_SET_ENTRY_TIMEOUT (DATA_MESSAGE_IMAX * 24 * 4) // 10 seconds per hop making this 240 seconds
/* DHCP client timeout configuration values
*
@ -170,4 +186,31 @@ extern uint8_t DEVICE_MIN_SENS;
*/
#define WISUN_1_0_ERRATA_FIX
/*
* Security protocol message retry configuration parameters
*/
#define SEC_PROT_SMALL_IMIN 30 // Retries done in 30 seconds
#define SEC_PROT_SMALL_IMAX 90 // Largest value 90 seconds
#define SEC_PROT_RETRY_TIMEOUT_SMALL 330 // Retry timeout for small network additional 30 seconds for authenticator delay
#define SEC_PROT_LARGE_IMIN 60 // Retries done in 60 seconds
#define SEC_PROT_LARGE_IMAX 240 // Largest value 240 seconds
#define SEC_PROT_RETRY_TIMEOUT_LARGE 750 // Retry timeout for large network additional 30 seconds for authenticator delay
#define SEC_PROT_TIMER_EXPIRATIONS 2 // Number of retries
/*
* Security protocol timer configuration parameters
*/
#define MINUTES_IN_DAY 24 * 60
#define DEFAULT_GTK_EXPIRE_OFFSET 43200 // 30 days
#define DEFAULT_PMK_LIFETIME 4 * 30 * MINUTES_IN_DAY // 4 months
#define DEFAULT_PTK_LIFETIME 2 * 30 * MINUTES_IN_DAY // 2 months
#define DEFAULT_GTK_NEW_ACTIVATION_TIME 720 // default 1/720 * 30 days --> 60 minutes
#define DEFAULT_REVOCATION_LIFETIME_REDUCTION 30 // default 1/30 * 30 days --> 1 day
#define DEFAULT_GTK_REQUEST_IMIN 4 // 4 minutes
#define DEFAULT_GTK_REQUEST_IMAX 64 // 64 minutes
#define DEFAULT_GTK_MAX_MISMATCH 64 // 64 minutes
#define DEFAULT_GTK_NEW_INSTALL_REQUIRED 80 // 80 percent of GTK lifetime --> 24 days
#endif /* WS_CONFIG_H_ */

View File

@ -49,6 +49,24 @@ int ws_management_network_name_set(
return -1;
}
int ws_management_network_name_get(
int8_t interface_id,
char *network_name_ptr)
{
(void)interface_id;
(void)network_name_ptr;
return -1;
}
int ws_management_network_name_validate(
int8_t interface_id,
char *network_name_ptr)
{
(void)interface_id;
(void)network_name_ptr;
return -1;
}
int ws_management_regulatory_domain_set(
int8_t interface_id,
uint8_t regulatory_domain,
@ -62,6 +80,32 @@ int ws_management_regulatory_domain_set(
return -1;
}
int ws_management_regulatory_domain_get(
int8_t interface_id,
uint8_t *regulatory_domain,
uint8_t *operating_class,
uint8_t *operating_mode)
{
(void)interface_id;
(void)regulatory_domain;
(void)operating_class;
(void)operating_mode;
return -1;
}
int ws_management_regulatory_domain_validate(
int8_t interface_id,
uint8_t regulatory_domain,
uint8_t operating_class,
uint8_t operating_mode)
{
(void)interface_id;
(void)regulatory_domain;
(void)operating_class;
(void)operating_mode;
return -1;
}
int ws_management_network_size_set(
int8_t interface_id,
uint8_t network_size)
@ -71,6 +115,24 @@ int ws_management_network_size_set(
return -1;
}
int ws_management_network_size_get(
int8_t interface_id,
uint8_t *network_size)
{
(void)interface_id;
(void)network_size;
return -1;
}
int ws_management_network_size_validate(
int8_t interface_id,
uint8_t network_size)
{
(void)interface_id;
(void)network_size;
return -1;
}
int ws_management_channel_mask_set(
int8_t interface_id,
uint32_t channel_mask[8])
@ -80,6 +142,24 @@ int ws_management_channel_mask_set(
return -1;
}
int ws_management_channel_mask_get(
int8_t interface_id,
uint32_t *channel_mask)
{
(void)interface_id;
(void)channel_mask;
return -1;
}
int ws_management_channel_mask_validate(
int8_t interface_id,
uint32_t channel_mask[8])
{
(void)interface_id;
(void)channel_mask;
return -1;
}
int ws_management_channel_plan_set(
int8_t interface_id,
uint8_t channel_plan,
@ -125,6 +205,32 @@ int ws_management_fhss_unicast_channel_function_configure(
return -1;
}
int ws_management_fhss_unicast_channel_function_get(
int8_t interface_id,
uint8_t *channel_function,
uint16_t *fixed_channel,
uint8_t *dwell_interval)
{
(void)interface_id;
(void)channel_function;
(void)fixed_channel;
(void)dwell_interval;
return -1;
}
int ws_management_fhss_unicast_channel_function_validate(
int8_t interface_id,
uint8_t channel_function,
uint16_t fixed_channel,
uint8_t dwell_interval)
{
(void)interface_id;
(void)channel_function;
(void)fixed_channel;
(void)dwell_interval;
return -1;
}
int ws_management_fhss_broadcast_channel_function_configure(
int8_t interface_id,
uint8_t channel_function,
@ -140,6 +246,81 @@ int ws_management_fhss_broadcast_channel_function_configure(
return -1;
}
int ws_management_fhss_broadcast_channel_function_get(
int8_t interface_id,
uint8_t *channel_function,
uint16_t *fixed_channel,
uint8_t *dwell_interval,
uint32_t *broadcast_interval)
{
(void)interface_id;
(void)channel_function;
(void)fixed_channel;
(void)dwell_interval;
(void)broadcast_interval;
return -1;
}
int ws_management_fhss_broadcast_channel_function_validate(
int8_t interface_id,
uint8_t channel_function,
uint16_t fixed_channel,
uint8_t dwell_interval,
uint32_t broadcast_interval)
{
(void)interface_id;
(void)channel_function;
(void)fixed_channel;
(void)dwell_interval;
(void)broadcast_interval;
return -1;
}
int ws_management_timing_parameters_set(
int8_t interface_id,
uint16_t disc_trickle_imin,
uint16_t disc_trickle_imax,
uint8_t disc_trickle_k,
uint16_t pan_timeout)
{
(void)interface_id;
(void)disc_trickle_imin;
(void)disc_trickle_imax;
(void)disc_trickle_k;
(void)pan_timeout;
return -1;
}
int ws_management_timing_parameters_get(
int8_t interface_id,
uint16_t *disc_trickle_imin,
uint16_t *disc_trickle_imax,
uint8_t *disc_trickle_k,
uint16_t *pan_timeout)
{
(void)interface_id;
(void)disc_trickle_imin;
(void)disc_trickle_imax;
(void)disc_trickle_k;
(void)pan_timeout;
return -1;
}
int ws_management_timing_parameters_validate(
int8_t interface_id,
uint16_t disc_trickle_imin,
uint16_t disc_trickle_imax,
uint8_t disc_trickle_k,
uint16_t pan_timeout)
{
(void)interface_id;
(void)disc_trickle_imin;
(void)disc_trickle_imax;
(void)disc_trickle_k;
(void)pan_timeout;
return -1;
}
/* ### test api ### */
int ws_test_pan_size_set(int8_t interface_id, uint16_t pan_size)
{

View File

@ -82,7 +82,13 @@ uint16_t ws_wp_nested_hopping_schedule_length(struct ws_hopping_schedule_s *hopp
length += ws_channel_function_length(channel_function, 1);
//Todo Derive some how exluded channel control
if (unicast_schedule && hopping_schedule->excluded_channels.excuded_channel_ctrl) {
if (hopping_schedule->excluded_channels.excuded_channel_ctrl == WS_EXC_CHAN_CTRL_RANGE) {
length += (hopping_schedule->excluded_channels.excluded_range_length * 4) + 1;
} else {
length += hopping_schedule->excluded_channels.channel_mask_bytes_inline;
}
}
return length;
}
@ -161,10 +167,11 @@ uint8_t *ws_wp_nested_hopping_schedule_write(uint8_t *ptr, struct ws_hopping_sch
channel_info_base = (hopping_schedule->channel_plan);
if (unicast_schedule) {
channel_info_base |= (hopping_schedule->uc_channel_function << 3);
//Set Excluded Channel control part
channel_info_base |= (hopping_schedule->excluded_channels.excuded_channel_ctrl << 6);
} else {
channel_info_base |= (hopping_schedule->bc_channel_function << 3);
}
//Todo define excluded channel ctrl
*ptr++ = channel_info_base;
@ -176,9 +183,9 @@ uint8_t *ws_wp_nested_hopping_schedule_write(uint8_t *ptr, struct ws_hopping_sch
break;
case 1:
//CHo, Channel spasing and number of channel's inline
ptr = common_write_24_bit(hopping_schedule->fhss_uc_dwell_interval, ptr);
*ptr++ = ((hopping_schedule->channel_spacing << 4) & 0xf0);
ptr = common_write_16_bit(hopping_schedule->number_of_channels, ptr);
ptr = common_write_24_bit_inverse(hopping_schedule->ch0_freq * 100, ptr);
*ptr++ = hopping_schedule->channel_spacing;
ptr = common_write_16_bit_inverse(hopping_schedule->number_of_channels, ptr);
break;
default:
break;
@ -210,6 +217,44 @@ uint8_t *ws_wp_nested_hopping_schedule_write(uint8_t *ptr, struct ws_hopping_sch
break;
}
if (unicast_schedule && hopping_schedule->excluded_channels.excuded_channel_ctrl) {
if (hopping_schedule->excluded_channels.excuded_channel_ctrl == WS_EXC_CHAN_CTRL_RANGE) {
uint8_t range_length = hopping_schedule->excluded_channels.excluded_range_length;
ws_excluded_channel_range_data_t *range_ptr = hopping_schedule->excluded_channels.exluded_range;
*ptr++ = range_length;
while (range_length) {
ptr = common_write_16_bit_inverse(range_ptr->range_start, ptr);
ptr = common_write_16_bit_inverse(range_ptr->range_end, ptr);
range_length--;
range_ptr++;
}
} else if (hopping_schedule->excluded_channels.excuded_channel_ctrl == WS_EXC_CHAN_CTRL_BITMASK) {
//Set Mask
uint16_t channel_mask_length = hopping_schedule->excluded_channels.channel_mask_bytes_inline * 8;
for (uint8_t i = 0; i < 8; i++) {
uint32_t mask_value = hopping_schedule->excluded_channels.channel_mask[i];
if (channel_mask_length >= 32) {
ptr = common_write_32_bit(mask_value, ptr);
channel_mask_length -= 32;
} else {
//Write MSB Bits from mask 24-8 top bits
uint8_t move_mask = 0;
while (channel_mask_length) {
*ptr++ = (uint8_t)(mask_value >> (24 - move_mask));
channel_mask_length -= 8;
move_mask += 8;
}
}
if (channel_mask_length == 0) {
break;
}
}
}
}
return ptr;
}
@ -330,8 +375,9 @@ static uint8_t *ws_channel_plan_zero_read(uint8_t *ptr, ws_channel_plan_zero_t *
static uint8_t *ws_channel_plan_one_read(uint8_t *ptr, ws_channel_plan_one_t *plan)
{
plan->ch0 = common_read_24_bit_inverse(ptr);
plan->ch0 /= 100;
ptr += 3;
plan->channel_spacing = (*ptr++ & 0xf0) >> 4;
plan->channel_spacing = *ptr++;
plan->number_of_channel = common_read_16_bit_inverse(ptr);
ptr += 2;
return ptr;
@ -358,6 +404,7 @@ bool ws_wp_nested_us_read(uint8_t *data, uint16_t length, struct ws_us_ie *us_ie
if (mac_ie_nested_discover(data, length, &nested_payload_ie) < 4) {
return false;
}
data = nested_payload_ie.content_ptr;
us_ie->dwell_interval = *data++;
us_ie->clock_drift = *data++;
@ -419,6 +466,36 @@ bool ws_wp_nested_us_read(uint8_t *data, uint16_t length, struct ws_us_ie *us_ie
}
switch (us_ie->excluded_channel_ctrl) {
case WS_EXC_CHAN_CTRL_NONE:
break;
case WS_EXC_CHAN_CTRL_RANGE:
us_ie->excluded_channels.range.number_of_range = *data;
if (nested_payload_ie.length < (us_ie->excluded_channels.range.number_of_range * 4) + 1) {
return false;
}
//Set Range start after validation
us_ie->excluded_channels.range.range_start = data + 1;
break;
case WS_EXC_CHAN_CTRL_BITMASK:
if (us_ie->channel_plan == 1) {
us_ie->excluded_channels.mask.mask_len_inline = ((us_ie->plan.one.number_of_channel + 7) / 8);
if (us_ie->excluded_channels.mask.mask_len_inline != nested_payload_ie.length) {
//Channel mask length is not correct
return false;
}
} else {
us_ie->excluded_channels.mask.mask_len_inline = nested_payload_ie.length;
}
us_ie->excluded_channels.mask.channel_mask = data;
break;
default:
return false;
}
return true;
}
bool ws_wp_nested_bs_read(uint8_t *data, uint16_t length, struct ws_bs_ie *bs_ie)

View File

@ -547,6 +547,12 @@ static void ws_llc_mac_indication_cb(const mac_api_t *api, const mcps_data_ind_t
bs_ie_inline = ws_wp_nested_bs_read(ws_wp_nested.content_ptr, ws_wp_nested.length, &ws_bs_ie);
}
//Validate Unicast shedule Channel Plan
if (us_ie_inline && !ws_bootstrap_validate_channel_plan(&us_ie, interface)) {
//Channel plan configuration mismatch
return;
}
llc_neighbour_req_t neighbor_info;
bool multicast;
bool request_new_entry;

View File

@ -21,11 +21,12 @@
#include "ns_trace.h"
#include <ns_list.h>
#include <nsdynmemLIB.h>
#include "fhss_config.h"
#include "ws_management_api.h"
#include "NWK_INTERFACE/Include/protocol.h"
#include "6LoWPAN/ws/ws_common.h"
#include "6LoWPAN/ws/ws_bootstrap.h"
#include "ws_management_api.h"
#include "6LoWPAN/ws/ws_cfg_settings.h"
#define TRACE_GROUP "wsmg"
@ -40,19 +41,37 @@ int ws_management_node_init(
protocol_interface_info_entry_t *cur;
cur = protocol_stack_interface_info_get_by_id(interface_id);
if (!cur || !ws_info(cur)) {
if (interface_id >= 0 && (!cur || !ws_info(cur))) {
return -1;
}
if (!network_name_ptr || !fhss_timer_ptr) {
return -2;
}
cur->ws_info->hopping_schdule.regulatory_domain = regulatory_domain;
if (ws_common_regulatory_domain_config(cur) < 0) {
// Invalid regulatory domain set
ws_phy_cfg_t phy_cfg;
if (ws_cfg_phy_get(&phy_cfg, NULL) < 0) {
return -3;
}
strncpy(cur->ws_info->network_name, network_name_ptr, 32);
phy_cfg.regulatory_domain = regulatory_domain;
if (ws_cfg_phy_set(cur, NULL, &phy_cfg, 0) < 0) {
return -4;
}
ws_gen_cfg_t gen_cfg;
if (ws_cfg_gen_get(&gen_cfg, NULL) < 0) {
return -3;
}
strncpy(gen_cfg.network_name, network_name_ptr, 32);
if (ws_cfg_gen_set(cur, NULL, &gen_cfg, 0) < 0) {
return -4;
}
cur->ws_info->fhss_timer_ptr = fhss_timer_ptr;
return 0;
}
@ -62,65 +81,162 @@ int ws_management_network_name_set(
{
protocol_interface_info_entry_t *cur;
cur = protocol_stack_interface_info_get_by_id(interface_id);
if (!cur || !ws_info(cur)) {
if (interface_id >= 0 && (!cur || !ws_info(cur))) {
return -1;
}
if (!network_name_ptr || strlen(network_name_ptr) == 0 || strlen(network_name_ptr) > 32) {
if (!network_name_ptr) {
return -2;
}
if (strcmp(cur->ws_info->network_name, network_name_ptr) == 0) {
// Network name is the same no further actions required.
return 0;
ws_gen_cfg_t cfg;
if (ws_cfg_gen_get(&cfg, NULL) < 0) {
return -3;
}
strncpy(cur->ws_info->network_name, network_name_ptr, 32);
// if settings change reset_restart for the settings needed
if (cur->lowpan_info & INTERFACE_NWK_ACTIVE) {
// bootstrap active need to restart
ws_bootstrap_restart(interface_id);
strncpy(cfg.network_name, network_name_ptr, 32);
if (ws_cfg_gen_set(cur, NULL, &cfg, 0) < 0) {
return -4;
}
return 0;
}
int ws_management_network_name_get(
int8_t interface_id,
char *network_name_ptr)
{
protocol_interface_info_entry_t *cur;
cur = protocol_stack_interface_info_get_by_id(interface_id);
if (interface_id >= 0 && (!cur || !ws_info(cur))) {
return -1;
}
if (!network_name_ptr) {
return -2;
}
ws_gen_cfg_t cfg;
if (ws_cfg_gen_get(&cfg, NULL) < 0) {
return -3;
}
memcpy(network_name_ptr, cfg.network_name, 32);
return 0;
}
int ws_management_network_name_validate(
int8_t interface_id,
char *network_name_ptr)
{
protocol_interface_info_entry_t *cur;
cur = protocol_stack_interface_info_get_by_id(interface_id);
if (interface_id >= 0 && (!cur || !ws_info(cur))) {
return -1;
}
if (!network_name_ptr) {
return -2;
}
ws_gen_cfg_t cfg;
if (ws_cfg_gen_get(&cfg, NULL) < 0) {
return -3;
}
strncpy(cfg.network_name, network_name_ptr, 32);
if (ws_cfg_gen_validate(NULL, &cfg) < 0) {
return -4;
}
return 0;
}
int ws_management_regulatory_domain_set(
int8_t interface_id,
uint8_t regulatory_domain,
uint8_t operating_class,
uint8_t operating_mode)
{
uint8_t regulatory_domain_saved;
uint8_t operating_class_saved;
uint8_t operating_mode_saved;
protocol_interface_info_entry_t *cur;
cur = protocol_stack_interface_info_get_by_id(interface_id);
if (!cur || !ws_info(cur)) {
if (interface_id >= 0 && (!cur || !ws_info(cur))) {
return -1;
}
regulatory_domain_saved = cur->ws_info->hopping_schdule.regulatory_domain;
operating_class_saved = cur->ws_info->hopping_schdule.operating_mode;
operating_mode_saved = cur->ws_info->hopping_schdule.operating_class;
ws_phy_cfg_t cfg;
if (ws_cfg_phy_get(&cfg, NULL) < 0) {
return -3;
}
if (regulatory_domain != 255) {
cur->ws_info->hopping_schdule.regulatory_domain = regulatory_domain;
cfg.regulatory_domain = regulatory_domain;
}
if (operating_mode != 255) {
cur->ws_info->hopping_schdule.operating_mode = operating_mode;
cfg.operating_mode = operating_mode;
}
if (operating_class != 255) {
cur->ws_info->hopping_schdule.operating_class = operating_class;
cfg.operating_class = operating_class;
}
if (ws_common_regulatory_domain_config(cur) != 0) {
// Restore old config on failure
//tr_error("unsupported regulatory domain: %d class: %d, mode: %d", regulatory_domain, operating_class, operating_mode);
cur->ws_info->hopping_schdule.regulatory_domain = regulatory_domain_saved;
cur->ws_info->hopping_schdule.operating_mode = operating_mode_saved;
cur->ws_info->hopping_schdule.operating_class = operating_class_saved;
ws_common_regulatory_domain_config(cur);
if (ws_cfg_phy_set(cur, NULL, &cfg, 0) < 0) {
return -4;
}
return 0;
}
int ws_management_regulatory_domain_get(
int8_t interface_id,
uint8_t *regulatory_domain,
uint8_t *operating_class,
uint8_t *operating_mode)
{
protocol_interface_info_entry_t *cur;
cur = protocol_stack_interface_info_get_by_id(interface_id);
if (interface_id >= 0 && (!cur || !ws_info(cur))) {
return -1;
}
// if settings change reset_restart for the settings needed
if (cur->lowpan_info & INTERFACE_NWK_ACTIVE) {
// bootstrap active need to restart
ws_bootstrap_restart(interface_id);
if (!regulatory_domain || !operating_class || !operating_mode) {
return -2;
}
ws_phy_cfg_t cfg;
if (ws_cfg_phy_get(&cfg, NULL) < 0) {
return -3;
}
*regulatory_domain = cfg.regulatory_domain;
*operating_class = cfg.operating_class;
*operating_mode = cfg.operating_mode;
return 0;
}
int ws_management_regulatory_domain_validate(
int8_t interface_id,
uint8_t regulatory_domain,
uint8_t operating_class,
uint8_t operating_mode)
{
protocol_interface_info_entry_t *cur;
cur = protocol_stack_interface_info_get_by_id(interface_id);
if (interface_id >= 0 && (!cur || !ws_info(cur))) {
return -1;
}
ws_phy_cfg_t cfg;
if (ws_cfg_phy_get(&cfg, NULL) < 0) {
return -3;
}
cfg.regulatory_domain = regulatory_domain;
cfg.operating_class = operating_class;
cfg.operating_mode = operating_mode;
if (ws_cfg_phy_validate(NULL, &cfg) < 0) {
return -4;
}
return 0;
@ -133,38 +249,68 @@ int ws_management_network_size_set(
protocol_interface_info_entry_t *cur;
cur = protocol_stack_interface_info_get_by_id(interface_id);
if (!cur || !ws_info(cur)) {
if (interface_id >= 0 && (!cur || !ws_info(cur))) {
return -1;
}
//Store old setup if new is not accepted
uint8_t old_setup = ws_info(cur)->network_size_config;
ws_info(cur)->network_size_config = network_size;
uint16_t rpl_parent_candidate_max;
uint16_t rpl_selected_parent_max;
if (network_size == NETWORK_SIZE_CERTIFICATE) {
rpl_parent_candidate_max = WS_CERTIFICATE_RPL_PARENT_CANDIDATE_MAX;
rpl_selected_parent_max = WS_CERTIFICATE_RPL_SELECTED_PARENT_MAX;
} else {
rpl_parent_candidate_max = WS_RPL_PARENT_CANDIDATE_MAX;
rpl_selected_parent_max = WS_RPL_SELECTED_PARENT_MAX;
ws_gen_cfg_t cfg;
if (ws_cfg_network_size_get(&cfg, NULL) < 0) {
return -3;
}
if (network_size == NETWORK_SIZE_LARGE) {
ws_common_network_size_configure(cur, 5000);
} else if (network_size == NETWORK_SIZE_MEDIUM) {
ws_common_network_size_configure(cur, 200);
} else if (network_size == NETWORK_SIZE_SMALL) {
ws_common_network_size_configure(cur, 10);
} else if (network_size == NETWORK_SIZE_CERTIFICATE) {
ws_common_network_size_configure(cur, 0);
} else {
ws_info(cur)->network_size_config = old_setup;
cfg.network_size = network_size;
if (ws_cfg_network_size_set(cur, NULL, &cfg, 0) < 0) {
return -3;
}
return 0;
}
int ws_management_network_size_get(
int8_t interface_id,
uint8_t *network_size)
{
protocol_interface_info_entry_t *cur;
cur = protocol_stack_interface_info_get_by_id(interface_id);
if (interface_id >= 0 && (!cur || !ws_info(cur))) {
return -1;
}
if (!network_size) {
return -2;
}
cur->ws_info->rpl_parent_candidate_max = rpl_parent_candidate_max;
cur->ws_info->rpl_selected_parent_max = rpl_selected_parent_max;
ws_gen_cfg_t cfg;
if (ws_cfg_network_size_get(&cfg, NULL) < 0) {
return -3;
}
*network_size = cfg.network_size;
return 0;
}
int ws_management_network_size_validate(
int8_t interface_id,
uint8_t network_size)
{
protocol_interface_info_entry_t *cur;
cur = protocol_stack_interface_info_get_by_id(interface_id);
if (interface_id >= 0 && (!cur || !ws_info(cur))) {
return -1;
}
ws_gen_cfg_t cfg;
if (ws_cfg_network_size_get(&cfg, NULL) < 0) {
return -3;
}
cfg.network_size = network_size;
if (ws_cfg_network_size_validate(NULL, &cfg) < 0) {
return -4;
}
return 0;
}
@ -175,10 +321,68 @@ int ws_management_channel_mask_set(
protocol_interface_info_entry_t *cur;
cur = protocol_stack_interface_info_get_by_id(interface_id);
if (!cur || !ws_info(cur)) {
if (interface_id >= 0 && (!cur || !ws_info(cur))) {
return -1;
}
memcpy(cur->ws_info->fhss_channel_mask, channel_mask, sizeof(uint32_t) * 8);
ws_fhss_cfg_t cfg;
if (ws_cfg_fhss_get(&cfg, NULL) < 0) {
return -2;
}
memcpy(cfg.fhss_channel_mask, channel_mask, sizeof(uint32_t) * 8);
if (ws_cfg_fhss_set(cur, NULL, &cfg, 0) < 0) {
return -3;
}
return 0;
}
int ws_management_channel_mask_get(
int8_t interface_id,
uint32_t *channel_mask)
{
protocol_interface_info_entry_t *cur;
cur = protocol_stack_interface_info_get_by_id(interface_id);
if (interface_id >= 0 && (!cur || !ws_info(cur))) {
return -1;
}
if (!channel_mask) {
return -2;
}
ws_fhss_cfg_t cfg;
if (ws_cfg_fhss_get(&cfg, NULL) < 0) {
return -2;
}
memcpy(channel_mask, cfg.fhss_channel_mask, sizeof(uint32_t) * 8);
return 0;
}
int ws_management_channel_mask_validate(
int8_t interface_id,
uint32_t channel_mask[8])
{
protocol_interface_info_entry_t *cur;
cur = protocol_stack_interface_info_get_by_id(interface_id);
if (interface_id >= 0 && (!cur || !ws_info(cur))) {
return -1;
}
ws_fhss_cfg_t cfg;
if (ws_cfg_fhss_get(&cfg, NULL) < 0) {
return -2;
}
memcpy(cfg.fhss_channel_mask, channel_mask, sizeof(uint32_t) * 8);
if (ws_cfg_fhss_validate(NULL, &cfg) < 0) {
return -4;
}
return 0;
}
@ -194,7 +398,7 @@ int ws_management_channel_plan_set(
protocol_interface_info_entry_t *cur;
cur = protocol_stack_interface_info_get_by_id(interface_id);
if (!cur || !ws_info(cur)) {
if (interface_id >= 0 && (!cur || !ws_info(cur))) {
return -1;
}
cur->ws_info->hopping_schdule.channel_plan = channel_plan;
@ -217,38 +421,29 @@ int ws_management_fhss_timing_configure(
protocol_interface_info_entry_t *cur;
cur = protocol_stack_interface_info_get_by_id(interface_id);
if (!cur || !ws_info(cur)) {
if (interface_id >= 0 && (!cur || !ws_info(cur))) {
return -1;
}
if (fhss_uc_dwell_interval && fhss_uc_dwell_interval < 15) {
ws_fhss_cfg_t cfg;
if (ws_cfg_fhss_get(&cfg, NULL) < 0) {
return -2;
}
if (fhss_bc_dwell_interval && fhss_bc_dwell_interval < 15) {
return -2;
if (fhss_uc_dwell_interval > 0) {
cfg.fhss_uc_dwell_interval = fhss_uc_dwell_interval;
}
if (fhss_broadcast_interval > 0) {
cfg.fhss_bc_interval = fhss_broadcast_interval;
}
if (fhss_bc_dwell_interval > 0) {
cfg.fhss_bc_dwell_interval = fhss_bc_dwell_interval;
}
bool updated_configure = false;
if (fhss_uc_dwell_interval > 0 && cur->ws_info->fhss_uc_dwell_interval != fhss_uc_dwell_interval) {
cur->ws_info->fhss_uc_dwell_interval = fhss_uc_dwell_interval;
updated_configure = true;
}
if (fhss_broadcast_interval > 0 && cur->ws_info->fhss_bc_interval != fhss_broadcast_interval) {
cur->ws_info->fhss_bc_interval = fhss_broadcast_interval;
updated_configure = true;
}
if (fhss_bc_dwell_interval > 0 && cur->ws_info->fhss_bc_dwell_interval != fhss_bc_dwell_interval) {
cur->ws_info->fhss_bc_dwell_interval = fhss_bc_dwell_interval;
updated_configure = true;
if (ws_cfg_fhss_set(cur, NULL, &cfg, 0) < 0) {
return -3;
}
// if settings change reset_restart for the settings needed
if (updated_configure && (cur->lowpan_info & INTERFACE_NWK_ACTIVE)) {
// bootstrap active need to restart
ws_bootstrap_restart(interface_id);
}
return 0;
}
@ -261,53 +456,82 @@ int ws_management_fhss_unicast_channel_function_configure(
protocol_interface_info_entry_t *cur;
cur = protocol_stack_interface_info_get_by_id(interface_id);
if (!cur || !ws_info(cur)) {
if (interface_id >= 0 && (!cur || !ws_info(cur))) {
return -1;
}
if (channel_function != WS_FIXED_CHANNEL &&
channel_function != WS_VENDOR_DEF_CF &&
channel_function != WS_DH1CF &&
channel_function != WS_TR51CF) {
ws_fhss_cfg_t cfg;
if (ws_cfg_fhss_get(&cfg, NULL) < 0) {
return -2;
}
if (dwell_interval && dwell_interval < 15) {
return -2;
if (dwell_interval > 0) {
cfg.fhss_uc_dwell_interval = dwell_interval;
}
if (channel_function == WS_FIXED_CHANNEL && fixed_channel == 0xffff) {
fixed_channel = 0;
tr_warn("Fixed channel not configured. Set to 0");
cfg.fhss_uc_channel_function = channel_function;
cfg.fhss_uc_fixed_channel = fixed_channel;
if (ws_cfg_fhss_set(cur, NULL, &cfg, 0) < 0) {
return -3;
}
bool updated_config = false;
if (cur->ws_info->fhss_uc_channel_function != channel_function) {
cur->ws_info->fhss_uc_channel_function = channel_function;
updated_config = true;
}
if (cur->ws_info->fhss_uc_channel_function == WS_FIXED_CHANNEL) {
if (cur->ws_info->fhss_uc_fixed_channel != fixed_channel) {
cur->ws_info->fhss_uc_fixed_channel = fixed_channel;
updated_config = true;
}
} else {
cur->ws_info->fhss_uc_fixed_channel = 0xffff;
}
if (dwell_interval && cur->ws_info->fhss_uc_dwell_interval != dwell_interval) {
cur->ws_info->fhss_uc_dwell_interval = dwell_interval;
updated_config = true;
}
// if settings change reset_restart for the settings needed
if (updated_config && (cur->lowpan_info & INTERFACE_NWK_ACTIVE)) {
// bootstrap active need to restart
ws_bootstrap_restart(interface_id);
}
return 0;
}
int ws_management_fhss_unicast_channel_function_get(
int8_t interface_id,
uint8_t *channel_function,
uint16_t *fixed_channel,
uint8_t *dwell_interval)
{
protocol_interface_info_entry_t *cur;
cur = protocol_stack_interface_info_get_by_id(interface_id);
if (interface_id >= 0 && (!cur || !ws_info(cur))) {
return -1;
}
if (!channel_function || !fixed_channel || !dwell_interval) {
return -2;
}
ws_fhss_cfg_t cfg;
if (ws_cfg_fhss_get(&cfg, NULL) < 0) {
return -2;
}
*dwell_interval = cfg.fhss_uc_dwell_interval;
*channel_function = cfg.fhss_uc_channel_function;
*fixed_channel = cfg.fhss_uc_fixed_channel;
return 0;
}
int ws_management_fhss_unicast_channel_function_validate(
int8_t interface_id,
uint8_t channel_function,
uint16_t fixed_channel,
uint8_t dwell_interval)
{
protocol_interface_info_entry_t *cur;
cur = protocol_stack_interface_info_get_by_id(interface_id);
if (interface_id >= 0 && (!cur || !ws_info(cur))) {
return -1;
}
ws_fhss_cfg_t cfg;
if (ws_cfg_fhss_get(&cfg, NULL) < 0) {
return -2;
}
cfg.fhss_uc_dwell_interval = dwell_interval;
cfg.fhss_uc_channel_function = channel_function;
cfg.fhss_uc_fixed_channel = fixed_channel;
if (ws_cfg_fhss_validate(NULL, &cfg) < 0) {
return -4;
}
return 0;
}
int ws_management_fhss_broadcast_channel_function_configure(
@ -320,57 +544,187 @@ int ws_management_fhss_broadcast_channel_function_configure(
protocol_interface_info_entry_t *cur;
cur = protocol_stack_interface_info_get_by_id(interface_id);
if (!cur || !ws_info(cur)) {
if (interface_id >= 0 && (!cur || !ws_info(cur))) {
return -1;
}
if (channel_function != WS_FIXED_CHANNEL &&
channel_function != WS_VENDOR_DEF_CF &&
channel_function != WS_DH1CF &&
channel_function != WS_TR51CF) {
ws_fhss_cfg_t cfg;
if (ws_cfg_fhss_get(&cfg, NULL) < 0) {
return -2;
}
if (dwell_interval && dwell_interval < 15) {
return -2;
if (dwell_interval > 0) {
cfg.fhss_bc_dwell_interval = dwell_interval;
}
if (broadcast_interval > 0) {
cfg.fhss_bc_interval = broadcast_interval;
}
if (channel_function == WS_FIXED_CHANNEL && fixed_channel == 0xffff) {
fixed_channel = 0;
tr_warn("Fixed channel not configured. Set to 0");
cfg.fhss_bc_channel_function = channel_function;
cfg.fhss_bc_fixed_channel = fixed_channel;
if (ws_cfg_fhss_set(cur, NULL, &cfg, 0) < 0) {
return -3;
}
bool updated_config = false;
if (cur->ws_info->fhss_bc_channel_function != channel_function) {
cur->ws_info->fhss_bc_channel_function = channel_function;
updated_config = true;
}
if (cur->ws_info->fhss_bc_channel_function == WS_FIXED_CHANNEL) {
if (cur->ws_info->fhss_bc_fixed_channel != fixed_channel) {
cur->ws_info->fhss_bc_fixed_channel = fixed_channel;
updated_config = true;
}
} else {
cur->ws_info->fhss_bc_fixed_channel = 0xffff;
}
if (dwell_interval > 0 && cur->ws_info->fhss_bc_dwell_interval != dwell_interval) {
cur->ws_info->fhss_bc_dwell_interval = dwell_interval;
updated_config = true;
}
if (broadcast_interval > 0 && cur->ws_info->fhss_bc_interval != broadcast_interval) {
cur->ws_info->fhss_bc_interval = broadcast_interval;
updated_config = true;
}
// if settings change reset_restart for the settings needed
if (updated_config && (cur->lowpan_info & INTERFACE_NWK_ACTIVE)) {
// bootstrap active need to restart
ws_bootstrap_restart(interface_id);
}
return 0;
}
int ws_management_fhss_broadcast_channel_function_get(
int8_t interface_id,
uint8_t *channel_function,
uint16_t *fixed_channel,
uint8_t *dwell_interval,
uint32_t *broadcast_interval)
{
protocol_interface_info_entry_t *cur;
cur = protocol_stack_interface_info_get_by_id(interface_id);
if (interface_id >= 0 && (!cur || !ws_info(cur))) {
return -1;
}
if (!channel_function || !fixed_channel || !dwell_interval) {
return -2;
}
ws_fhss_cfg_t cfg;
if (ws_cfg_fhss_get(&cfg, NULL) < 0) {
return -2;
}
*dwell_interval = cfg.fhss_bc_dwell_interval;
*broadcast_interval = cfg.fhss_bc_interval;
*channel_function = cfg.fhss_bc_channel_function;
*fixed_channel = cfg.fhss_bc_fixed_channel;
return 0;
}
int ws_management_fhss_broadcast_channel_function_validate(
int8_t interface_id,
uint8_t channel_function,
uint16_t fixed_channel,
uint8_t dwell_interval,
uint32_t broadcast_interval)
{
protocol_interface_info_entry_t *cur;
cur = protocol_stack_interface_info_get_by_id(interface_id);
if (interface_id >= 0 && (!cur || !ws_info(cur))) {
return -1;
}
ws_fhss_cfg_t cfg;
if (ws_cfg_fhss_get(&cfg, NULL) < 0) {
return -2;
}
cfg.fhss_bc_dwell_interval = dwell_interval;
cfg.fhss_bc_interval = broadcast_interval;
cfg.fhss_bc_channel_function = channel_function;
cfg.fhss_bc_fixed_channel = fixed_channel;
if (ws_cfg_fhss_validate(NULL, &cfg) < 0) {
return -4;
}
return 0;
}
int ws_management_timing_parameters_set(
int8_t interface_id,
uint16_t disc_trickle_imin,
uint16_t disc_trickle_imax,
uint8_t disc_trickle_k,
uint16_t pan_timeout)
{
protocol_interface_info_entry_t *cur;
cur = protocol_stack_interface_info_get_by_id(interface_id);
if (interface_id >= 0 && (!cur || !ws_info(cur))) {
return -1;
}
ws_timing_cfg_t cfg;
if (ws_cfg_timing_get(&cfg, NULL) < 0) {
return -2;
}
if (disc_trickle_imin > 0) {
cfg.disc_trickle_imin = disc_trickle_imin;
}
if (disc_trickle_imax > 0) {
cfg.disc_trickle_imax = disc_trickle_imax;
}
if (disc_trickle_k > 0) {
cfg.disc_trickle_k = disc_trickle_k;
}
if (pan_timeout > 0) {
cfg.pan_timeout = pan_timeout;
}
if (ws_cfg_timing_set(cur, NULL, &cfg, 0) < 0) {
return -3;
}
return 0;
}
int ws_management_timing_parameters_get(
int8_t interface_id,
uint16_t *disc_trickle_imin,
uint16_t *disc_trickle_imax,
uint8_t *disc_trickle_k,
uint16_t *pan_timeout)
{
protocol_interface_info_entry_t *cur;
cur = protocol_stack_interface_info_get_by_id(interface_id);
if (interface_id >= 0 && (!cur || !ws_info(cur))) {
return -1;
}
if (!disc_trickle_imin || !disc_trickle_imax || !disc_trickle_k || !pan_timeout) {
return -2;
}
ws_timing_cfg_t cfg;
if (ws_cfg_timing_get(&cfg, NULL) < 0) {
return -2;
}
*disc_trickle_imin = cfg.disc_trickle_imin;
*disc_trickle_imax = cfg.disc_trickle_imax;
*disc_trickle_k = cfg.disc_trickle_k;
*pan_timeout = cfg.pan_timeout;
return 0;
}
int ws_management_timing_parameters_validate(
int8_t interface_id,
uint16_t disc_trickle_imin,
uint16_t disc_trickle_imax,
uint8_t disc_trickle_k,
uint16_t pan_timeout)
{
protocol_interface_info_entry_t *cur;
cur = protocol_stack_interface_info_get_by_id(interface_id);
if (interface_id >= 0 && (!cur || !ws_info(cur))) {
return -1;
}
ws_timing_cfg_t cfg;
if (ws_cfg_timing_get(&cfg, NULL) < 0) {
return -2;
}
cfg.disc_trickle_imin = disc_trickle_imin;
cfg.disc_trickle_imax = disc_trickle_imax;
cfg.disc_trickle_k = disc_trickle_k;
cfg.pan_timeout = pan_timeout;
if (ws_cfg_timing_validate(NULL, &cfg) < 0) {
return -4;
}
return 0;
}
#endif // HAVE_WS

View File

@ -21,6 +21,7 @@
#include "ns_list.h"
#include "ns_trace.h"
#include "nsdynmemLIB.h"
#include "common_functions.h"
#include "fhss_config.h"
#include "6LoWPAN/ws/ws_config.h"
#include "6LoWPAN/ws/ws_neighbor_class.h"
@ -94,6 +95,121 @@ void ws_neighbor_class_neighbor_unicast_time_info_update(ws_neighbor_class_entry
ws_neighbor->fhss_data.uc_timing_info.ufsi = ws_utt->ufsi;
}
static void ws_neighbour_channel_list_enable_all(ws_channel_mask_t *channel_info, uint16_t number_of_channels)
{
uint32_t mask;
channel_info->channel_count = number_of_channels;
for (uint8_t n = 0; n < 8; n++) {
if (number_of_channels >= 32) {
mask = 0xffffffff;
number_of_channels -= 32;
} else if (number_of_channels) {
mask = 0;
//Start bit enable to MSB
for (uint16_t i = 0; i < (number_of_channels % 32); i++) {
mask |= 1 << i;
}
number_of_channels = 0;
} else {
mask = 0;
}
channel_info->channel_mask[n] = mask;
}
}
static void ws_neighbour_excluded_mask_by_range(ws_channel_mask_t *channel_info, ws_excluded_channel_range_t *range_info, uint16_t number_of_channels)
{
uint16_t range_start, range_stop;
uint8_t mask_index = 0;
uint32_t compare_mask_bit;
uint8_t *range_ptr = range_info->range_start;
while (range_info->number_of_range) {
range_start = common_read_16_bit_inverse(range_ptr);
range_ptr += 2;
range_stop = common_read_16_bit_inverse(range_ptr);
range_ptr += 2;
range_info->number_of_range--;
for (uint16_t channel = 0; channel < number_of_channels; channel++) {
if (channel >= range_start && channel <= range_stop) {
//Cut channel
compare_mask_bit = 1 << (channel % 32);
mask_index = 0 + (channel / 32);
if (channel_info->channel_mask[mask_index] & compare_mask_bit) {
channel_info->channel_mask[mask_index] ^= compare_mask_bit;
channel_info->channel_count--;
}
} else if (channel > range_stop) {
break;
}
}
}
}
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);
}
}
return ret_val;
}
static void ws_neighbour_excluded_mask_by_mask(ws_channel_mask_t *channel_info, ws_excluded_channel_mask_t *mask_info, uint16_t number_of_channels)
{
if (mask_info->mask_len_inline == 0) {
return;
}
uint16_t channel_at_mask;
uint8_t mask_index = 0;
uint32_t channel_compare_mask, compare_mask_bit;
uint8_t *mask_ptr = mask_info->channel_mask;
channel_at_mask = mask_info->mask_len_inline * 8;
for (uint16_t channel = 0; channel < number_of_channels; channel += 32) {
if (channel) {
mask_index++;
mask_ptr += 4;
}
//Read allaways 32-bit
if (channel_at_mask >= 32) {
channel_compare_mask = common_read_32_bit(mask_ptr);
channel_at_mask -= 32;
} else {
//Read Rest bytes seprately
channel_compare_mask = 0;
uint8_t move_mask = 0;
//Convert 8-24bit to 32-bit
while (channel_at_mask) {
channel_compare_mask |= (uint32_t)(*mask_ptr++ << (24 - move_mask));
channel_at_mask -= 8;
move_mask += 8;
}
}
//Reserve bit order for compare
channel_compare_mask = ws_reserve_order_32_bit(channel_compare_mask);
//Compare now 32-bit mask's bits one by one
for (uint8_t i = 0; i < 32; i++) {
//Start from MSB
compare_mask_bit = 1 << (i);
if ((channel_compare_mask & compare_mask_bit) && (channel_info->channel_mask[mask_index] & compare_mask_bit)) {
channel_info->channel_mask[mask_index] ^= compare_mask_bit;
channel_info->channel_count--;
}
}
//Stop compare if all bits in line are compared
if (channel_at_mask == 0) {
break;
}
}
}
void ws_neighbor_class_neighbor_unicast_schedule_set(ws_neighbor_class_entry_t *ws_neighbor, ws_us_ie_t *ws_us)
{
ws_neighbor->fhss_data.uc_timing_info.unicast_channel_function = ws_us->channel_function;
@ -105,9 +221,21 @@ void ws_neighbor_class_neighbor_unicast_schedule_set(ws_neighbor_class_entry_t *
ws_neighbor->fhss_data.uc_timing_info.unicast_number_of_channels = ws_common_channel_number_calc(ws_us->plan.zero.regulator_domain, ws_us->plan.zero.operation_class);
} 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 {
ws_neighbor->fhss_data.uc_timing_info.unicast_number_of_channels = 0;
}
//Handle excluded channel and generate activate channel list
if (ws_us->excluded_channel_ctrl == WS_EXC_CHAN_CTRL_RANGE) {
ws_neighbour_channel_list_enable_all(&ws_neighbor->fhss_data.uc_channel_list, 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_neighbour_channel_list_enable_all(&ws_neighbor->fhss_data.uc_channel_list, 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_neighbour_channel_list_enable_all(&ws_neighbor->fhss_data.uc_channel_list, ws_neighbor->fhss_data.uc_timing_info.unicast_number_of_channels);
}
}
}
ws_neighbor->fhss_data.uc_timing_info.unicast_dwell_interval = ws_us->dwell_interval;
}

View File

@ -23,12 +23,14 @@
#include "ns_trace.h"
#include "nsdynmemLIB.h"
#include "fhss_config.h"
#include "ws_management_api.h"
#include "eventOS_event.h"
#include "eventOS_scheduler.h"
#include "eventOS_event_timer.h"
#include "ns_address.h"
#include "NWK_INTERFACE/Include/protocol.h"
#include "6LoWPAN/ws/ws_config.h"
#include "Security/protocols/sec_prot_cfg.h"
#include "Security/kmp/kmp_addr.h"
#include "Security/kmp/kmp_api.h"
#include "Security/kmp/kmp_socket_if.h"
@ -39,6 +41,7 @@
#include "Security/protocols/tls_sec_prot/tls_sec_prot.h"
#include "Security/protocols/fwh_sec_prot/auth_fwh_sec_prot.h"
#include "Security/protocols/gkh_sec_prot/auth_gkh_sec_prot.h"
#include "6LoWPAN/ws/ws_cfg_settings.h"
#include "6LoWPAN/ws/ws_pae_controller.h"
#include "6LoWPAN/ws/ws_pae_timers.h"
#include "6LoWPAN/ws/ws_pae_auth.h"
@ -86,7 +89,8 @@ typedef struct {
sec_prot_gtk_keys_t *gtks; /**< GTKs */
sec_prot_gtk_keys_t *next_gtks; /**< Next GTKs */
const sec_prot_certs_t *certs; /**< Certificates */
timer_settings_t *timer_settings; /**< Timer settings */
sec_timer_cfg_t *sec_timer_cfg; /**< Timer configuration */
sec_prot_cfg_t *sec_prot_cfg; /**< Protocol Configuration */
uint16_t supp_max_number; /**< Max number of stored supplicants */
uint16_t slow_timer_seconds; /**< Slow timer seconds */
bool timer_running : 1; /**< Timer is running */
@ -117,13 +121,13 @@ static void ws_pae_auth_kmp_api_create_indication(kmp_api_t *kmp, kmp_type_e typ
static void ws_pae_auth_kmp_api_finished_indication(kmp_api_t *kmp, kmp_result_e result, kmp_sec_keys_t *sec_keys);
static void ws_pae_auth_next_kmp_trigger(pae_auth_t *pae_auth, supp_entry_t *supp_entry);
static kmp_type_e ws_pae_auth_next_protocol_get(pae_auth_t *pae_auth, supp_entry_t *supp_entry);
static kmp_api_t *ws_pae_auth_kmp_create_and_start(kmp_service_t *service, kmp_type_e type, supp_entry_t *supp_entry);
static kmp_api_t *ws_pae_auth_kmp_create_and_start(kmp_service_t *service, kmp_type_e type, supp_entry_t *supp_entry, sec_prot_cfg_t *cfg);
static void ws_pae_auth_kmp_api_finished(kmp_api_t *kmp);
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 *gtks, sec_prot_gtk_keys_t *next_gtks, const sec_prot_certs_t *certs, timer_settings_t *timer_settings)
int8_t ws_pae_auth_init(protocol_interface_info_entry_t *interface_ptr, sec_prot_gtk_keys_t *gtks, sec_prot_gtk_keys_t *next_gtks, const sec_prot_certs_t *certs, sec_timer_cfg_t *sec_timer_cfg, sec_prot_cfg_t *sec_prot_cfg)
{
if (!interface_ptr || !gtks || !certs) {
return -1;
@ -150,7 +154,8 @@ int8_t ws_pae_auth_init(protocol_interface_info_entry_t *interface_ptr, sec_prot
pae_auth->gtks = gtks;
pae_auth->next_gtks = next_gtks;
pae_auth->certs = certs;
pae_auth->timer_settings = timer_settings;
pae_auth->sec_timer_cfg = sec_timer_cfg;
pae_auth->sec_prot_cfg = sec_prot_cfg;
pae_auth->supp_max_number = SUPPLICANT_MAX_NUMBER;
pae_auth->slow_timer_seconds = 0;
@ -215,14 +220,6 @@ error:
return -1;
}
int8_t ws_pae_auth_timing_adjust(uint8_t timing)
{
auth_gkh_sec_prot_timing_adjust(timing);
auth_fwh_sec_prot_timing_adjust(timing);
auth_eap_tls_sec_prot_timing_adjust(timing);
return 0;
}
int8_t ws_pae_auth_addresses_set(protocol_interface_info_entry_t *interface_ptr, uint16_t local_port, const uint8_t *remote_addr, uint16_t remote_port)
{
if (!interface_ptr || !remote_addr) {
@ -387,7 +384,7 @@ int8_t ws_pae_auth_node_access_revoke_start(protocol_interface_info_entry_t *int
// As default removes other keys than active
int8_t not_removed_index = active_index;
uint32_t revocation_lifetime = ws_pae_timers_gtk_revocation_lifetime_get(pae_auth->timer_settings);
uint32_t revocation_lifetime = ws_pae_timers_gtk_revocation_lifetime_get(pae_auth->sec_timer_cfg);
uint32_t active_lifetime = sec_prot_keys_gtk_lifetime_get(pae_auth->gtks, active_index);
@ -608,7 +605,7 @@ void ws_pae_auth_slow_timer(uint16_t seconds)
uint32_t timer_seconds = sec_prot_keys_gtk_lifetime_decrement(pae_auth->gtks, i, seconds);
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->timer_settings, timer_seconds);
pae_auth->gtk_new_inst_req_exp = ws_pae_timers_gtk_new_install_required(pae_auth->sec_timer_cfg, timer_seconds);
if (pae_auth->gtk_new_inst_req_exp) {
int8_t second_index = sec_prot_keys_gtk_install_order_second_index_get(pae_auth->gtks);
if (second_index < 0) {
@ -622,7 +619,7 @@ void ws_pae_auth_slow_timer(uint16_t seconds)
}
if (!pae_auth->gtk_new_act_time_exp) {
pae_auth->gtk_new_act_time_exp = ws_pae_timers_gtk_new_activation_time(pae_auth->timer_settings, timer_seconds);
pae_auth->gtk_new_act_time_exp = ws_pae_timers_gtk_new_activation_time(pae_auth->sec_timer_cfg, timer_seconds);
if (pae_auth->gtk_new_act_time_exp) {
int8_t new_active_index = ws_pae_auth_new_gtk_activate(pae_auth);
tr_info("GTK new activation time active index: %i, time: %"PRIu32", new index: %i, system time: %"PRIu32"", active_index, timer_seconds, new_active_index, protocol_core_monotonic_time / 10);
@ -644,8 +641,8 @@ void ws_pae_auth_slow_timer(uint16_t seconds)
pae_auth->slow_timer_seconds += seconds;
if (pae_auth->slow_timer_seconds > 60) {
ws_pae_lib_supp_list_slow_timer_update(&pae_auth->active_supp_list, pae_auth->timer_settings, pae_auth->slow_timer_seconds);
ws_pae_lib_supp_list_slow_timer_update(&pae_auth->inactive_supp_list, pae_auth->timer_settings, pae_auth->slow_timer_seconds);
ws_pae_lib_supp_list_slow_timer_update(&pae_auth->active_supp_list, pae_auth->sec_timer_cfg, pae_auth->slow_timer_seconds);
ws_pae_lib_supp_list_slow_timer_update(&pae_auth->inactive_supp_list, pae_auth->sec_timer_cfg, pae_auth->slow_timer_seconds);
pae_auth->slow_timer_seconds = 0;
}
}
@ -675,7 +672,7 @@ static void ws_pae_auth_gtk_key_insert(pae_auth_t *pae_auth)
}
// Gets latest installed key lifetime and adds GTK expire offset to it
uint32_t lifetime = pae_auth->timer_settings->gtk_expire_offset;
uint32_t lifetime = pae_auth->sec_timer_cfg->gtk_expire_offset;
int8_t last_index = sec_prot_keys_gtk_install_order_last_index_get(pae_auth->gtks);
if (last_index >= 0) {
lifetime += sec_prot_keys_gtk_lifetime_get(pae_auth->gtks, last_index);
@ -838,7 +835,7 @@ static kmp_api_t *ws_pae_auth_kmp_incoming_ind(kmp_service_t *service, kmp_type_
}
// Create a new KMP for initial eapol-key
kmp = kmp_api_create(service, type + IEEE_802_1X_INITIAL_KEY);
kmp = kmp_api_create(service, type + IEEE_802_1X_INITIAL_KEY, pae_auth->sec_prot_cfg);
if (!kmp) {
return 0;
@ -952,7 +949,7 @@ static void ws_pae_auth_next_kmp_trigger(pae_auth_t *pae_auth, supp_entry_t *sup
}
// Create new instance
kmp_api_t *new_kmp = ws_pae_auth_kmp_create_and_start(pae_auth->kmp_service, next_type, supp_entry);
kmp_api_t *new_kmp = ws_pae_auth_kmp_create_and_start(pae_auth->kmp_service, next_type, supp_entry, pae_auth->sec_prot_cfg);
if (!new_kmp) {
return;
}
@ -965,7 +962,7 @@ static void ws_pae_auth_next_kmp_trigger(pae_auth_t *pae_auth, supp_entry_t *sup
return;
}
// Create TLS instance */
if (ws_pae_auth_kmp_create_and_start(pae_auth->kmp_service, TLS_PROT, supp_entry) == NULL) {
if (ws_pae_auth_kmp_create_and_start(pae_auth->kmp_service, TLS_PROT, supp_entry, pae_auth->sec_prot_cfg) == NULL) {
ws_pae_lib_kmp_list_delete(&supp_entry->kmp_list, new_kmp);
return;
}
@ -1009,7 +1006,7 @@ static kmp_type_e ws_pae_auth_next_protocol_get(pae_auth_t *pae_auth, supp_entry
* has been, trigger 4WH to update also the PTK. This prevents writing multiple
* GTK keys to same index using same PTK.
*/
if (pae_auth->timer_settings->gtk_expire_offset > SHORT_GTK_LIFETIME &&
if (pae_auth->sec_timer_cfg->gtk_expire_offset > SHORT_GTK_LIFETIME &&
sec_prot_keys_ptk_installed_gtk_hash_mismatch_check(sec_keys, gtk_index)) {
// start 4WH towards supplicant
next_type = IEEE_802_11_4WH;
@ -1033,10 +1030,10 @@ static kmp_type_e ws_pae_auth_next_protocol_get(pae_auth_t *pae_auth, supp_entry
}
static kmp_api_t *ws_pae_auth_kmp_create_and_start(kmp_service_t *service, kmp_type_e type, supp_entry_t *supp_entry)
static kmp_api_t *ws_pae_auth_kmp_create_and_start(kmp_service_t *service, kmp_type_e type, supp_entry_t *supp_entry, sec_prot_cfg_t *cfg)
{
// Create KMP instance for new authentication
kmp_api_t *kmp = kmp_api_create(service, type);
kmp_api_t *kmp = kmp_api_create(service, type, cfg);
if (!kmp) {
return NULL;

View File

@ -47,34 +47,14 @@
* \param next_gtks next group keys to be used
* \param cert_chain certificate chain
* \param timer_settings timer settings
* \param sec_timer_cfg timer configuration
* \param sec_prot_cfg protocol configuration
*
* \return < 0 failure
* \return >= 0 success
*
*/
int8_t ws_pae_auth_init(protocol_interface_info_entry_t *interface_ptr, sec_prot_gtk_keys_t *gtks, sec_prot_gtk_keys_t *next_gtks, const sec_prot_certs_t *certs, timer_settings_t *timer_settings);
/**
* ws_pae_auth_timing_adjust Adjust retries and timings of the security protocols
*
* Timing value is a generic number between 0 to 32 that goes from fast and
* reactive network to low bandwidth and long latency.
*
* example value definitions:
* 0-8 very fast network
* 9-16 medium network
* 16-24 slow network
* 25-32 extremely slow network
*
* There is no need to have lots variations in every layer if protocol is not very active in any case.
*
* \param timing Timing value.
*
* \return < 0 failure
* \return >= 0 success
*
*/
int8_t ws_pae_auth_timing_adjust(uint8_t timing);
int8_t ws_pae_auth_init(protocol_interface_info_entry_t *interface_ptr, sec_prot_gtk_keys_t *gtks, sec_prot_gtk_keys_t *next_gtks, const sec_prot_certs_t *certs, sec_timer_cfg_t *sec_timer_cfg, sec_prot_cfg_t *sec_prot_cfg);
/**
* ws_pae_auth_addresses_set set relay addresses
@ -231,7 +211,7 @@ void ws_pae_auth_cb_register(protocol_interface_info_entry_t *interface_ptr, ws_
#else
#define ws_pae_auth_init(interface_ptr, gtks, next_gtks, certs, timer_settings) 1
#define ws_pae_auth_init(interface_ptr, gtks, next_gtks, certs, sec_timer_cfg, sec_prot_cfg) 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

View File

@ -23,9 +23,12 @@
#include "nsdynmemLIB.h"
#include "fhss_config.h"
#include "ns_address.h"
#include "ws_management_api.h"
#include "NWK_INTERFACE/Include/protocol.h"
#include "6LoWPAN/ws/ws_config.h"
#include "6LoWPAN/ws/ws_cfg_settings.h"
#include "6LoWPAN/ws/ws_pae_controller.h"
#include "Security/protocols/sec_prot_cfg.h"
#include "Security/protocols/sec_prot_certs.h"
#include "Security/protocols/sec_prot_keys.h"
#include "6LoWPAN/ws/ws_pae_timers.h"
@ -67,7 +70,8 @@ typedef struct {
char *network_name; /**< Network name for GAK generation */
uint16_t frame_cnt_store_timer; /**< Timer for storing frame counter value */
frame_counters_t frame_counters; /**< Frame counters */
timer_settings_t timer_settings; /**< Timer settings */
sec_timer_cfg_t sec_timer_cfg; /**< Timer configuration (configuration set values) */
sec_prot_cfg_t sec_prot_cfg; /**< Configuration */
protocol_interface_info_entry_t *interface_ptr; /**< List link entry */
ws_pae_controller_auth_completed *auth_completed; /**< Authentication completed callback, continue bootstrap */
ws_pae_controller_nw_key_set *nw_key_set; /**< Key set callback */
@ -576,6 +580,8 @@ int8_t ws_pae_controller_init(protocol_interface_info_entry_t *interface_ptr)
controller->nw_frame_counter_set = NULL;
controller->pan_ver_increment = NULL;
controller->pae_nvm_buffer = pae_nvm_buffer;
memset(&controller->sec_timer_cfg, 0, sizeof(ws_sec_timer_cfg_t));
memset(&controller->sec_prot_cfg, 0, sizeof(sec_prot_cfg_t));
ws_pae_controller_data_init(controller);
@ -584,6 +590,29 @@ int8_t ws_pae_controller_init(protocol_interface_info_entry_t *interface_ptr)
return 0;
}
int8_t ws_pae_controller_configure(protocol_interface_info_entry_t *interface_ptr, struct ws_sec_timer_cfg_s *sec_timer_cfg, struct ws_sec_prot_cfg_s *sec_prot_cfg)
{
pae_controller_t *controller = ws_pae_controller_get(interface_ptr);
if (controller == NULL) {
return 0;
}
if (sec_prot_cfg) {
controller->sec_prot_cfg.sec_prot_trickle_params.Imin = sec_prot_cfg->sec_prot_trickle_imin * 10;
controller->sec_prot_cfg.sec_prot_trickle_params.Imax = sec_prot_cfg->sec_prot_trickle_imax * 10;
controller->sec_prot_cfg.sec_prot_trickle_params.k = 0;
controller->sec_prot_cfg.sec_prot_trickle_params.TimerExpirations = sec_prot_cfg->sec_prot_trickle_timer_exp;
controller->sec_prot_cfg.sec_prot_retry_timeout = sec_prot_cfg->sec_prot_retry_timeout * 10;
}
if (sec_timer_cfg) {
ws_pae_timers_settings_init(&controller->sec_timer_cfg, sec_timer_cfg);
}
return 0;
}
static void ws_pae_controller_data_init(pae_controller_t *controller)
{
memset(controller->target_eui_64, 0, 8);
@ -616,7 +645,6 @@ static void ws_pae_controller_data_init(pae_controller_t *controller)
sec_prot_keys_gtks_init(&controller->next_gtks);
sec_prot_certs_init(&controller->certs);
sec_prot_certs_ext_certificate_validation_set(&controller->certs, pae_controller_config.ext_cert_valid_enabled);
ws_pae_timers_settings_init(&controller->timer_settings);
}
static void ws_pae_controller_frame_counter_read(pae_controller_t *controller)
@ -667,7 +695,7 @@ int8_t ws_pae_controller_supp_init(protocol_interface_info_entry_t *interface_pt
return -1;
}
if (ws_pae_supp_init(controller->interface_ptr, &controller->certs, &controller->timer_settings) < 0) {
if (ws_pae_supp_init(controller->interface_ptr, &controller->certs, &controller->sec_timer_cfg, &controller->sec_prot_cfg) < 0) {
return -1;
}
@ -693,7 +721,7 @@ 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->gtks, &controller->next_gtks, &controller->certs, &controller->timer_settings) < 0) {
if (ws_pae_auth_init(controller->interface_ptr, &controller->gtks, &controller->next_gtks, &controller->certs, &controller->sec_timer_cfg, &controller->sec_prot_cfg) < 0) {
return -1;
}
@ -752,13 +780,6 @@ int8_t ws_pae_controller_delete(protocol_interface_info_entry_t *interface_ptr)
return 0;
}
int8_t ws_pae_controller_timing_adjust(uint8_t timing)
{
ws_pae_supp_timing_adjust(timing);
ws_pae_auth_timing_adjust(timing);
return 0;
}
int8_t ws_pae_controller_certificate_chain_set(const arm_certificate_chain_entry_s *new_chain)
{
if (!new_chain) {
@ -998,7 +1019,7 @@ int8_t ws_pae_controller_gtk_update(int8_t interface_id, uint8_t *gtk[GTK_NUM])
for (uint8_t i = 0; i < GTK_NUM; i++) {
if (gtk[i]) {
uint32_t lifetime = sec_prot_keys_gtk_install_order_last_lifetime_get(&controller->gtks);
lifetime += controller->timer_settings.gtk_expire_offset;
lifetime += controller->sec_timer_cfg.gtk_expire_offset;
if (sec_prot_keys_gtk_set(&controller->gtks, i, gtk[i], lifetime) >= 0) {
controller->gtks_set = true;
tr_info("GTK set index: %i, lifetime %"PRIu32", system time: %"PRIu32"", i, lifetime, protocol_core_monotonic_time / 10);
@ -1053,30 +1074,6 @@ int8_t ws_pae_controller_active_key_update(int8_t interface_id, uint8_t index)
return 0;
}
int8_t ws_pae_controller_key_lifetime_update(int8_t interface_id, uint32_t gtk_lifetime, uint32_t pmk_lifetime, uint32_t ptk_lifetime)
{
pae_controller_t *controller = ws_pae_controller_get_or_create(interface_id);
if (!controller) {
return -1;
}
ws_pae_timers_lifetime_set(&controller->timer_settings, gtk_lifetime, pmk_lifetime, ptk_lifetime);
return 0;
}
int8_t ws_pae_controller_gtk_time_settings_update(int8_t interface_id, uint8_t revocat_lifetime_reduct, uint8_t new_activation_time, uint8_t new_install_req, uint32_t max_mismatch)
{
pae_controller_t *controller = ws_pae_controller_get_or_create(interface_id);
if (!controller) {
return -1;
}
ws_pae_timers_gtk_time_settings_set(&controller->timer_settings, revocat_lifetime_reduct, new_activation_time, new_install_req, max_mismatch);
return 0;
}
int8_t ws_pae_controller_node_keys_remove(int8_t interface_id, uint8_t *eui_64)
{
#ifndef HAVE_PAE_AUTH

View File

@ -28,6 +28,8 @@ typedef enum {
} auth_result_e;
struct nvm_tlv_entry;
struct ws_sec_timer_cfg_s;
struct ws_sec_prot_cfg_s;
/**
* ws_pae_controller_set_target sets EAPOL target for PAE supplicant
@ -89,6 +91,19 @@ int8_t ws_pae_controller_authenticator_start(protocol_interface_info_entry_t *in
*/
int8_t ws_pae_controller_init(protocol_interface_info_entry_t *interface_ptr);
/**
* ws_pae_controller_config_set sets PAE controller configuration
*
* \param interface_ptr interface
* \param sec_timer_cfg timer configuration or NULL if not set
* \param sec_prot_cfg protocol configuration or NULL if not set
*
* \return < 0 failure
* \return >= 0 success
*
*/
int8_t ws_pae_controller_configure(protocol_interface_info_entry_t *interface_ptr, struct ws_sec_timer_cfg_s *sec_timer_cfg, struct ws_sec_prot_cfg_s *sec_prot_cfg);
/**
* ws_pae_controller_init initializes PAE supplicant
*
@ -133,28 +148,6 @@ int8_t ws_pae_controller_stop(protocol_interface_info_entry_t *interface_ptr);
*/
int8_t ws_pae_controller_delete(protocol_interface_info_entry_t *interface_ptr);
/**
* ws_pae_controller_timing_adjust Adjust retries and timings of the security protocols
*
* Timing value is a generic number between 0 to 32 that goes from fast and
* reactive network to low bandwidth and long latency.
*
* example value definitions:
* 0-8 very fast network
* 9-16 medium network
* 16-24 slow network
* 25-32 extremely slow network
*
* There is no need to have lots variations in every layer if protocol is not very active in any case.
*
* \param timing Timing value.
*
* \return < 0 failure
* \return >= 0 success
*
*/
int8_t ws_pae_controller_timing_adjust(uint8_t timing);
/**
* ws_pae_controller_certificate_chain_set set certificate chain
*

View File

@ -22,13 +22,16 @@
#include "ns_trace.h"
#include "nsdynmemLIB.h"
#include "fhss_config.h"
#include "ws_management_api.h"
#include "NWK_INTERFACE/Include/protocol.h"
#include "6LoWPAN/ws/ws_cfg_settings.h"
#include "6LoWPAN/ws/ws_config.h"
#include "6LoWPAN/ws/ws_pae_timers.h"
#include "Security/protocols/sec_prot_cfg.h"
#include "Security/kmp/kmp_addr.h"
#include "Security/kmp/kmp_api.h"
#include "Security/protocols/sec_prot_certs.h"
#include "Security/protocols/sec_prot_keys.h"
#include "6LoWPAN/ws/ws_pae_timers.h"
#include "6LoWPAN/ws/ws_pae_lib.h"
#ifdef HAVE_WS
@ -228,7 +231,7 @@ bool ws_pae_lib_supp_list_timer_update(supp_list_t *active_supp_list, supp_list_
return timer_running;
}
void ws_pae_lib_supp_list_slow_timer_update(supp_list_t *supp_list, timer_settings_t *timer_settings, uint16_t seconds)
void ws_pae_lib_supp_list_slow_timer_update(supp_list_t *supp_list, sec_timer_cfg_t *timer_settings, uint16_t seconds)
{
ns_list_foreach(supp_entry_t, entry, supp_list) {
if (sec_prot_keys_pmk_lifetime_decrement(&entry->sec_keys, timer_settings->pmk_lifetime, seconds)) {

View File

@ -233,7 +233,7 @@ bool ws_pae_lib_supp_list_timer_update(supp_list_t *active_supp_list, supp_list_
* \param seconds seconds
*
*/
void ws_pae_lib_supp_list_slow_timer_update(supp_list_t *supp_list, timer_settings_t *timer_settings, uint16_t seconds);
void ws_pae_lib_supp_list_slow_timer_update(supp_list_t *supp_list, sec_timer_cfg_t *timer_settings, uint16_t seconds);
/**
* ws_pae_lib_supp_list_timer_update updates supplicant timers

View File

@ -23,6 +23,7 @@
#include "ns_trace.h"
#include "nsdynmemLIB.h"
#include "fhss_config.h"
#include "ws_management_api.h"
#include "eventOS_event.h"
#include "eventOS_scheduler.h"
#include "eventOS_event_timer.h"
@ -32,6 +33,7 @@
#include "RPL/rpl_control.h"
#include "RPL/rpl_data.h"
#include "6LoWPAN/ws/ws_config.h"
#include "Security/protocols/sec_prot_cfg.h"
#include "Security/kmp/kmp_addr.h"
#include "Security/kmp/kmp_api.h"
#include "Security/protocols/sec_prot_certs.h"
@ -41,6 +43,7 @@
#include "Security/protocols/tls_sec_prot/tls_sec_prot.h"
#include "Security/protocols/fwh_sec_prot/supp_fwh_sec_prot.h"
#include "Security/protocols/gkh_sec_prot/supp_gkh_sec_prot.h"
#include "6LoWPAN/ws/ws_cfg_settings.h"
#include "6LoWPAN/ws/ws_pae_controller.h"
#include "6LoWPAN/ws/ws_pae_timers.h"
#include "6LoWPAN/ws/ws_pae_supp.h"
@ -101,7 +104,8 @@ typedef struct {
sec_prot_gtk_keys_t gtks; /**< GTKs */
uint8_t new_br_eui_64[8]; /**< Border router EUI-64 indicated by bootstrap */
sec_prot_keys_nw_info_t sec_keys_nw_info; /**< Security keys network information */
timer_settings_t *timer_settings; /**< Timer settings */
sec_timer_cfg_t *sec_timer_cfg; /**< Timer configuration */
sec_prot_cfg_t *sec_prot_cfg; /**< Protocol Configuration */
uint8_t nw_keys_used_cnt; /**< How many times bootstrap has been tried with current keys */
uint8_t initial_key_retry_cnt; /**< initial EAPOL-Key retry counter */
bool auth_trickle_running : 1; /**< Initial EAPOL-Key Trickle timer running */
@ -370,7 +374,7 @@ int8_t ws_pae_supp_gtk_hash_update(protocol_interface_info_entry_t *interface_pt
// Starts supplicant timer
ws_pae_supp_timer_start(pae_supp);
tr_info("GTK update start imin: %i, imax: %i, max mismatch: %i, tr time: %i", pae_supp->timer_settings->gtk_request_imin, pae_supp->timer_settings->gtk_request_imax, pae_supp->timer_settings->gtk_max_mismatch, pae_supp->auth_trickle_timer.t);
tr_info("GTK update start imin: %i, imax: %i, max mismatch: %i, tr time: %i", pae_supp->sec_timer_cfg->gtk_request_imin, pae_supp->sec_timer_cfg->gtk_request_imax, pae_supp->sec_timer_cfg->gtk_max_mismatch, pae_supp->auth_trickle_timer.t);
}
}
@ -618,7 +622,7 @@ void ws_pae_supp_cb_register(protocol_interface_info_entry_t *interface_ptr, ws_
pae_supp->gtk_hash_ptr_get = gtk_hash_ptr_get;
}
int8_t ws_pae_supp_init(protocol_interface_info_entry_t *interface_ptr, const sec_prot_certs_t *certs, timer_settings_t *timer_settings)
int8_t ws_pae_supp_init(protocol_interface_info_entry_t *interface_ptr, const sec_prot_certs_t *certs, sec_timer_cfg_t *sec_timer_cfg, sec_prot_cfg_t *sec_prot_cfg)
{
if (!interface_ptr) {
return -1;
@ -641,8 +645,9 @@ int8_t ws_pae_supp_init(protocol_interface_info_entry_t *interface_ptr, const se
pae_supp->initial_key_timer = 0;
pae_supp->initial_key_retry_timer = 0;
pae_supp->nw_keys_used_cnt = 0;
pae_supp->timer_settings = timer_settings;
pae_supp->initial_key_retry_cnt = INITIAL_KEY_RETRY_COUNT;
pae_supp->sec_timer_cfg = sec_timer_cfg;
pae_supp->sec_prot_cfg = sec_prot_cfg;
pae_supp->auth_trickle_running = false;
pae_supp->auth_requested = false;
pae_supp->timer_running = false;
@ -744,14 +749,6 @@ int8_t ws_pae_supp_delete(protocol_interface_info_entry_t *interface_ptr)
return 0;
}
int8_t ws_pae_supp_timing_adjust(uint8_t timing)
{
timing_value = timing;
supp_fwh_sec_prot_timing_adjust(timing);
supp_eap_sec_prot_timing_adjust(timing);
return 0;
}
static void ws_pae_supp_free(pae_supp_t *pae_supp)
{
if (!pae_supp) {
@ -998,8 +995,8 @@ static void ws_pae_supp_initial_last_interval_trickle_timer_start(pae_supp_t *pa
static void ws_pae_supp_initial_key_update_trickle_timer_start(pae_supp_t *pae_supp, uint8_t timer_expirations)
{
// Starts trickle for the key update
pae_supp->auth_trickle_params.Imin = pae_supp->timer_settings->gtk_request_imin;
pae_supp->auth_trickle_params.Imax = pae_supp->timer_settings->gtk_request_imax;
pae_supp->auth_trickle_params.Imin = pae_supp->sec_timer_cfg->gtk_request_imin;
pae_supp->auth_trickle_params.Imax = pae_supp->sec_timer_cfg->gtk_request_imax;
pae_supp->auth_trickle_params.k = 0;
pae_supp->auth_trickle_params.TimerExpirations = timer_expirations;
@ -1216,7 +1213,7 @@ static kmp_api_t *ws_pae_supp_kmp_incoming_ind(kmp_service_t *service, kmp_type_
static kmp_api_t *ws_pae_supp_kmp_create_and_start(kmp_service_t *service, kmp_type_e type, pae_supp_t *pae_supp)
{
// Create new instance
kmp_api_t *kmp = kmp_api_create(service, type);
kmp_api_t *kmp = kmp_api_create(service, type, pae_supp->sec_prot_cfg);
if (!kmp) {
return NULL;
}

View File

@ -38,13 +38,14 @@
*
* \param interface_ptr interface
* \param cert_chain certificate chain
* \param timer_settings timer settings
* \param sec_timer_cfg timer configuration
* \param sec_prot_cfg protocol configuration
*
* \return < 0 failure
* \return >= 0 success
*
*/
int8_t ws_pae_supp_init(protocol_interface_info_entry_t *interface_ptr, const sec_prot_certs_t *certs, timer_settings_t *timer_settings);
int8_t ws_pae_supp_init(protocol_interface_info_entry_t *interface_ptr, const sec_prot_certs_t *certs, sec_timer_cfg_t *sec_timer_cfg, sec_prot_cfg_t *sec_prot_cfg);
/**
* ws_pae_supp_delete deletes PAE supplicant
@ -57,29 +58,6 @@ int8_t ws_pae_supp_init(protocol_interface_info_entry_t *interface_ptr, const se
*/
int8_t ws_pae_supp_delete(protocol_interface_info_entry_t *interface_ptr);
/**
* ws_pae_supp_timing_adjust Adjust retries and timings of the 4WH protocol
*
* Timing value is a generic number between 0 to 32 that goes from fast and
* reactive network to low bandwidth and long latency.
*
* example value definitions:
* 0-8 very fast network
* 9-16 medium network
* 16-24 slow network
* 25-32 extremely slow network
*
* There is no need to have lots variations in every layer if protocol is not very active in any case.
*
* \param timing Timing value.
*
* \return < 0 failure
* \return >= 0 success
*
*/
int8_t ws_pae_supp_timing_adjust(uint8_t timing);
/**
* ws_pae_supp_fast_timer PAE supplicant fast timer call
*
@ -259,7 +237,7 @@ void ws_pae_supp_cb_register(protocol_interface_info_entry_t *interface_ptr, ws_
#else
#define ws_pae_supp_init(interface_ptr, certs, timer_settings) 1
#define ws_pae_supp_init(interface_ptr, certs, sec_timer_cfg, sec_prot_cfg) 1
#define ws_pae_supp_delete NULL
#define ws_pae_supp_timing_adjust(timing) 1
#define ws_pae_supp_cb_register(interface_ptr, completed, nw_key_insert, nw_key_index_set)

View File

@ -22,44 +22,43 @@
#include "ns_trace.h"
#include "nsdynmemLIB.h"
#include "fhss_config.h"
#include "ws_management_api.h"
#include "NWK_INTERFACE/Include/protocol.h"
#include "6LoWPAN/ws/ws_config.h"
#include "6LoWPAN/ws/ws_cfg_settings.h"
#include "6LoWPAN/ws/ws_pae_timers.h"
#ifdef HAVE_WS
#define TRACE_GROUP "wspt"
#define SECONDS_IN_DAY 24 * 60 * 60
#define SECONDS_IN_MONTH 30 * SECONDS_IN_DAY
#define SECONDS_IN_MINUTE 60
#define DEFAULT_GTK_EXPIRE_OFFSET 43200 // 30 days
#define DEFAULT_PMK_LIFETIME 4 // 4 months
#define DEFAULT_PTK_LIFETIME 2 // 2 months
#define DEFAULT_GTK_NEW_ACTIVATION_TIME 720 // default 1/720 * 30 days --> 60 minutes
#define DEFAULT_REVOCATION_LIFETIME_REDUCTION 30 // default 1/30 * 30 days --> 1 day
#define DEFAULT_GTK_REQUEST_IMIN 4 // 4 minutes
#define DEFAULT_GTK_REQUEST_IMAX 64 // 64 minutes
#define DEFAULT_GTK_MAX_MISMATCH 64 // 64 minutes
#define DEFAULT_GTK_NEW_INSTALL_REQUIRED 80 // 80 percent of GTK lifetime --> 24 days
static void ws_pae_timers_calculate(timer_settings_t *timer_settings);
static void ws_pae_timers_calculate(sec_timer_cfg_t *timer_settings);
void ws_pae_timers_settings_init(timer_settings_t *timer_settings)
void ws_pae_timers_settings_init(sec_timer_cfg_t *timer_settings, ws_sec_timer_cfg_t *new_timer_settings)
{
timer_settings->gtk_expire_offset = DEFAULT_GTK_EXPIRE_OFFSET * SECONDS_IN_MINUTE;
timer_settings->pmk_lifetime = DEFAULT_PMK_LIFETIME * SECONDS_IN_MONTH;
timer_settings->ptk_lifetime = DEFAULT_PTK_LIFETIME * SECONDS_IN_MONTH;
timer_settings->gtk_new_act_time = DEFAULT_GTK_NEW_ACTIVATION_TIME;
timer_settings->revocat_lifetime_reduct = DEFAULT_REVOCATION_LIFETIME_REDUCTION;
timer_settings->gtk_request_imin = DEFAULT_GTK_REQUEST_IMIN * SECONDS_IN_MINUTE;
timer_settings->gtk_request_imax = DEFAULT_GTK_REQUEST_IMAX * SECONDS_IN_MINUTE;
timer_settings->gtk_max_mismatch = DEFAULT_GTK_MAX_MISMATCH * SECONDS_IN_MINUTE;
timer_settings->gtk_new_install_req = DEFAULT_GTK_NEW_INSTALL_REQUIRED;
if (timer_settings == NULL || new_timer_settings == NULL) {
return;
}
timer_settings->gtk_expire_offset = new_timer_settings->gtk_expire_offset * SECONDS_IN_MINUTE;
timer_settings->pmk_lifetime = new_timer_settings->pmk_lifetime * SECONDS_IN_MINUTE;
timer_settings->ptk_lifetime = new_timer_settings->ptk_lifetime * SECONDS_IN_MINUTE;
timer_settings->gtk_new_act_time = new_timer_settings->gtk_new_act_time;
timer_settings->revocat_lifetime_reduct = new_timer_settings->revocat_lifetime_reduct;
timer_settings->gtk_request_imin = new_timer_settings->gtk_request_imin * SECONDS_IN_MINUTE;
timer_settings->gtk_request_imax = new_timer_settings->gtk_request_imax * SECONDS_IN_MINUTE;
timer_settings->gtk_max_mismatch = new_timer_settings->gtk_max_mismatch * SECONDS_IN_MINUTE;
timer_settings->gtk_new_install_req = new_timer_settings->gtk_new_install_req;
ws_pae_timers_calculate(timer_settings);
}
void ws_pae_timers_lifetime_set(timer_settings_t *timer_settings, uint32_t gtk_lifetime, uint32_t pmk_lifetime, uint32_t ptk_lifetime)
void ws_pae_timers_lifetime_set(sec_timer_cfg_t *timer_settings, uint32_t gtk_lifetime, uint32_t pmk_lifetime, uint32_t ptk_lifetime)
{
if (gtk_lifetime) {
timer_settings->gtk_expire_offset = gtk_lifetime * 60;
@ -73,7 +72,7 @@ void ws_pae_timers_lifetime_set(timer_settings_t *timer_settings, uint32_t gtk_l
ws_pae_timers_calculate(timer_settings);
}
void ws_pae_timers_gtk_time_settings_set(timer_settings_t *timer_settings, uint8_t revocat_lifetime_reduct, uint8_t new_activation_time, uint8_t new_install_req, uint32_t max_mismatch)
void ws_pae_timers_gtk_time_settings_set(sec_timer_cfg_t *timer_settings, uint8_t revocat_lifetime_reduct, uint8_t new_activation_time, uint8_t new_install_req, uint32_t max_mismatch)
{
if (revocat_lifetime_reduct) {
timer_settings->revocat_lifetime_reduct = revocat_lifetime_reduct;
@ -90,7 +89,7 @@ void ws_pae_timers_gtk_time_settings_set(timer_settings_t *timer_settings, uint8
ws_pae_timers_calculate(timer_settings);
}
static void ws_pae_timers_calculate(timer_settings_t *timer_settings)
static void ws_pae_timers_calculate(sec_timer_cfg_t *timer_settings)
{
// Calculate GTK_NEW_INSTALL_REQUIRED < 100 * (1 - 1 / REVOCATION_LIFETIME_REDUCTION)
uint8_t calc_gtk_new_install_req = 100 - (100 / timer_settings->revocat_lifetime_reduct);
@ -106,9 +105,6 @@ static void ws_pae_timers_calculate(timer_settings_t *timer_settings)
}
// Verify that GTK request Imin and Imax are sensible when compared to revocation lifetime
timer_settings->gtk_request_imin = DEFAULT_GTK_REQUEST_IMIN * SECONDS_IN_MINUTE;
timer_settings->gtk_request_imax = DEFAULT_GTK_REQUEST_IMAX * SECONDS_IN_MINUTE;
uint32_t gtk_revocation_lifetime = timer_settings->gtk_expire_offset / timer_settings->revocat_lifetime_reduct;
uint32_t new_activation_time = timer_settings->gtk_expire_offset / timer_settings->gtk_new_act_time;
@ -147,7 +143,7 @@ static void ws_pae_timers_calculate(timer_settings_t *timer_settings)
}
}
bool ws_pae_timers_gtk_new_install_required(timer_settings_t *timer_settings, uint32_t seconds)
bool ws_pae_timers_gtk_new_install_required(sec_timer_cfg_t *timer_settings, uint32_t seconds)
{
uint32_t gtk_new_install_req_seconds = timer_settings->gtk_expire_offset - timer_settings->gtk_new_install_req * timer_settings->gtk_expire_offset / 100;
@ -158,7 +154,7 @@ bool ws_pae_timers_gtk_new_install_required(timer_settings_t *timer_settings, ui
}
}
bool ws_pae_timers_gtk_new_activation_time(timer_settings_t *timer_settings, uint32_t seconds)
bool ws_pae_timers_gtk_new_activation_time(sec_timer_cfg_t *timer_settings, uint32_t seconds)
{
uint32_t gtk_gtk_new_activation_time_seconds = timer_settings->gtk_expire_offset / timer_settings->gtk_new_act_time;
@ -169,7 +165,7 @@ bool ws_pae_timers_gtk_new_activation_time(timer_settings_t *timer_settings, uin
}
}
uint32_t ws_pae_timers_gtk_revocation_lifetime_get(timer_settings_t *timer_settings)
uint32_t ws_pae_timers_gtk_revocation_lifetime_get(sec_timer_cfg_t *timer_settings)
{
return timer_settings->gtk_expire_offset / timer_settings->revocat_lifetime_reduct;
}

View File

@ -18,25 +18,26 @@
#ifndef WS_PAE_TIMERS_H_
#define WS_PAE_TIMERS_H_
typedef struct {
uint32_t gtk_expire_offset; // GTK lifetime; GTK_EXPIRE_OFFSET (seconds)
uint32_t pmk_lifetime; // PMK lifetime (seconds)
uint32_t ptk_lifetime; // PTK lifetime (seconds)
uint16_t gtk_new_act_time; // GTK_NEW_ACTIVATION_TIME (1/X of expire offset)
uint16_t revocat_lifetime_reduct; // REVOCATION_LIFETIME_REDUCTION (reduction of lifetime)
uint16_t gtk_request_imin; // GTK_REQUEST_IMIN (seconds)
uint16_t gtk_request_imax; // GTK_REQUEST_IMAX (seconds)
uint16_t gtk_max_mismatch; // GTK_MAX_MISMATCH (seconds)
uint8_t gtk_new_install_req; // GTK_NEW_INSTALL_REQUIRED (percent of GTK lifetime)
} timer_settings_t;
typedef struct sec_timer_cfg_s {
uint32_t gtk_expire_offset; /* GTK lifetime; GTK_EXPIRE_OFFSET (seconds) */
uint32_t pmk_lifetime; /* PMK lifetime (seconds) */
uint32_t ptk_lifetime; /* PTK lifetime (seconds) */
uint16_t gtk_new_act_time; /* GTK_NEW_ACTIVATION_TIME (1/X of expire offset) */
uint16_t revocat_lifetime_reduct; /* REVOCATION_LIFETIME_REDUCTION (reduction of lifetime) */
uint16_t gtk_request_imin; /* GTK_REQUEST_IMIN (seconds) */
uint16_t gtk_request_imax; /* GTK_REQUEST_IMAX (seconds) */
uint16_t gtk_max_mismatch; /* GTK_MAX_MISMATCH (seconds) */
uint8_t gtk_new_install_req; /* GTK_NEW_INSTALL_REQUIRED (percent of GTK lifetime) */
} sec_timer_cfg_t;
/**
* ws_pae_timers_settings_init initializes timer settings structure
*
* \param timer_settings timer settings
* \param new_timer_settings new timer settings
*
*/
void ws_pae_timers_settings_init(timer_settings_t *timer_settings);
void ws_pae_timers_settings_init(sec_timer_cfg_t *timer_settings, ws_sec_timer_cfg_t *new_timer_settings);
/**
* ws_pae_timers_lifetime_set sets GTK, PTK and PTK lifetimes
@ -47,7 +48,7 @@ void ws_pae_timers_settings_init(timer_settings_t *timer_settings);
* \param ptk_lifetime PTK lifetime
*
*/
void ws_pae_timers_lifetime_set(timer_settings_t *timer_settings, uint32_t gtk_lifetime, uint32_t pmk_lifetime, uint32_t ptk_lifetime);
void ws_pae_timers_lifetime_set(sec_timer_cfg_t *timer_settings, uint32_t gtk_lifetime, uint32_t pmk_lifetime, uint32_t ptk_lifetime);
/**
* ws_pae_timers_gtk_time_settings_set sets GTK, PTK and PTK lifetimes
@ -59,7 +60,7 @@ void ws_pae_timers_lifetime_set(timer_settings_t *timer_settings, uint32_t gtk_l
* \param max_mismatch max mismatch
*
*/
void ws_pae_timers_gtk_time_settings_set(timer_settings_t *timer_settings, uint8_t revocat_lifetime_reduct, uint8_t new_activation_time, uint8_t new_install_req, uint32_t max_mismatch);
void ws_pae_timers_gtk_time_settings_set(sec_timer_cfg_t *timer_settings, uint8_t revocat_lifetime_reduct, uint8_t new_activation_time, uint8_t new_install_req, uint32_t max_mismatch);
/**
* ws_pae_timers_gtk_new_install_required GTK new install required check
@ -71,7 +72,7 @@ void ws_pae_timers_gtk_time_settings_set(timer_settings_t *timer_settings, uint8
* \return false GTK install not required
*
*/
bool ws_pae_timers_gtk_new_install_required(timer_settings_t *timer_settings, uint32_t seconds);
bool ws_pae_timers_gtk_new_install_required(sec_timer_cfg_t *timer_settings, uint32_t seconds);
/**
* ws_pae_timers_gtk_new_activation_time GTK new activation time
@ -83,7 +84,7 @@ bool ws_pae_timers_gtk_new_install_required(timer_settings_t *timer_settings, ui
* \return false GTK new activation time not expired
*
*/
bool ws_pae_timers_gtk_new_activation_time(timer_settings_t *timer_settings, uint32_t seconds);
bool ws_pae_timers_gtk_new_activation_time(sec_timer_cfg_t *timer_settings, uint32_t seconds);
/**
* ws_pae_timers_gtk_revocation_lifetime_get GTK revocation lifetime get
@ -93,6 +94,6 @@ bool ws_pae_timers_gtk_new_activation_time(timer_settings_t *timer_settings, uin
* \return GTK revocation lifetime
*
*/
uint32_t ws_pae_timers_gtk_revocation_lifetime_get(timer_settings_t *timer_settings);
uint32_t ws_pae_timers_gtk_revocation_lifetime_get(sec_timer_cfg_t *timer_settings);
#endif /* WS_PAE_TIMERS_H_ */

View File

@ -21,11 +21,14 @@
#include <ns_list.h>
#include <nsdynmemLIB.h>
#include <net_ws_test.h>
#include "fhss_config.h"
#include "ws_management_api.h"
#include "NWK_INTERFACE/Include/protocol.h"
#include "6LoWPAN/ws/ws_config.h"
#include "6LoWPAN/ws/ws_common.h"
#include "6LoWPAN/ws/ws_bbr_api_internal.h"
#include "6LoWPAN/ws/ws_pae_controller.h"
#include "6LoWPAN/ws/ws_cfg_settings.h"
#include "randLIB.h"
#include "ns_trace.h"
@ -74,24 +77,67 @@ int ws_test_active_key_set(int8_t interface_id, uint8_t index)
int ws_test_key_lifetime_set(int8_t interface_id, uint32_t gtk_lifetime, uint32_t pmk_lifetime, uint32_t ptk_lifetime)
{
(void) interface_id;
(void) gtk_lifetime;
(void) pmk_lifetime;
(void) ptk_lifetime;
protocol_interface_info_entry_t *cur;
return ws_pae_controller_key_lifetime_update(interface_id, gtk_lifetime, pmk_lifetime, ptk_lifetime);
cur = protocol_stack_interface_info_get_by_id(interface_id);
if (!cur || !ws_info(cur)) {
return -1;
}
ws_sec_timer_cfg_t cfg;
if (ws_cfg_sec_timer_get(&cfg, NULL) < 0) {
return -2;
}
if (gtk_lifetime > 0) {
cfg.gtk_expire_offset = gtk_lifetime;
}
if (pmk_lifetime > 0) {
cfg.pmk_lifetime = pmk_lifetime;
}
if (ptk_lifetime > 0) {
cfg.ptk_lifetime = ptk_lifetime;
}
if (ws_cfg_sec_timer_set(cur, NULL, &cfg, NULL) < 0) {
return -3;
}
return 0;
}
int ws_test_gtk_time_settings_set(int8_t interface_id, uint8_t revocat_lifetime_reduct, uint8_t new_activation_time, uint8_t new_install_req, uint32_t max_mismatch)
{
(void) interface_id;
(void) revocat_lifetime_reduct;
(void) new_activation_time;
(void) new_install_req;
(void) max_mismatch;
protocol_interface_info_entry_t *cur;
cur = protocol_stack_interface_info_get_by_id(interface_id);
if (!cur || !ws_info(cur)) {
return -1;
}
return ws_pae_controller_gtk_time_settings_update(interface_id, revocat_lifetime_reduct, new_activation_time, new_install_req, max_mismatch);
ws_sec_timer_cfg_t cfg;
if (ws_cfg_sec_timer_get(&cfg, NULL) < 0) {
return -2;
}
if (revocat_lifetime_reduct > 0) {
cfg.revocat_lifetime_reduct = revocat_lifetime_reduct;
}
if (new_activation_time > 0) {
cfg.gtk_new_act_time = new_activation_time;
}
if (new_install_req > 0) {
cfg.gtk_new_install_req = new_install_req;
}
if (max_mismatch > 0) {
cfg.gtk_max_mismatch = max_mismatch;
}
if (ws_cfg_sec_timer_set(cur, NULL, &cfg, NULL) < 0) {
return -3;
}
return 0;
}
int ws_test_next_gtk_set(int8_t interface_id, uint8_t *gtk[4])

View File

@ -1377,6 +1377,7 @@ void ack_remove_neighbour_cb(struct buffer *buffer_ptr, uint8_t status)
static void icmpv6_aro_cb(buffer_t *buf, uint8_t status)
{
(void)status;
uint8_t ll_address[16];
if (buf->dst_sa.addr_type == ADDR_IPV6) {
/*Full IPv6 address*/
@ -1387,8 +1388,8 @@ static void icmpv6_aro_cb(buffer_t *buf, uint8_t status)
memcpy(ll_address + 8, &buf->dst_sa.address[2], 8);
ll_address[8] ^= 2;
}
rpl_control_address_register_done(buf->interface, ll_address, status);
if (status != SOCKET_TX_DONE) {
if (rpl_control_address_register_done(buf->interface, ll_address, status)) {
// When RPL returns true neighbor should be blacklisted
ws_common_aro_failure(buf->interface, ll_address);
}
}

View File

@ -22,11 +22,11 @@
* \enum error_t
* \brief System generic error.
*/
typedef enum error_t {
typedef enum {
eOK = 0, /*!< no error */
eFALSE = 1, /*!< no result */
eBUSY = 2, /*!< resource busy */
eSYSTEM /*!< error code readable in sys_error */
} error_t;
} socket_error_t;
#endif /* NS_ERROR_TYPES_H_ */

View File

@ -190,7 +190,7 @@ extern void socket_init(void);
extern int8_t socket_event_handler_id_get(void);
extern bool socket_data_queued_event_push(socket_t *socket);
extern void socket_event_push(uint8_t sock_event, socket_t *socket, int8_t interface_id, void *session_ptr, uint16_t length);
extern error_t socket_create(socket_family_t family, socket_type_t type, uint8_t protocol, int8_t *sid, uint16_t port, void (*passed_fptr)(void *), bool buffer_type);
extern socket_error_t socket_create(socket_family_t family, socket_type_t type, uint8_t protocol, int8_t *sid, uint16_t port, void (*passed_fptr)(void *), bool buffer_type);
extern socket_t *socket_new_incoming_connection(socket_t *listen_socket);
void socket_connection_abandoned(socket_t *socket, int8_t interface_id, uint8_t reason);
void socket_connection_complete(socket_t *socket, int8_t interface_id);
@ -201,8 +201,8 @@ extern void socket_id_detach(int8_t sid);
extern buffer_t *socket_buffer_read(socket_t *socket);
extern socket_t *socket_lookup(socket_family_t family, uint8_t protocol, const sockaddr_t *local_addr, const sockaddr_t *remote_addr);
extern socket_t *socket_lookup_ipv6(uint8_t protocol, const sockaddr_t *local_addr, const sockaddr_t *remote_addr, bool allow_wildcards);
extern error_t socket_port_validate(uint16_t port, uint8_t protocol);
extern error_t socket_up(buffer_t *buf);
extern socket_error_t socket_port_validate(uint16_t port, uint8_t protocol);
extern socket_error_t socket_up(buffer_t *buf);
extern bool socket_message_validate_iov(const struct ns_msghdr *msg, uint16_t *length_out);
extern int16_t socket_buffer_sendmsg(int8_t sid, buffer_t *buf, const struct ns_msghdr *msg, int flags);
extern socket_t *socket_pointer_get(int8_t socket);

View File

@ -342,7 +342,7 @@ static void socket_free(socket_t *socket)
ns_dyn_mem_free(socket);
}
error_t socket_port_validate(uint16_t port, uint8_t protocol)
socket_error_t socket_port_validate(uint16_t port, uint8_t protocol)
{
ns_list_foreach(socket_t, socket, &socket_list) {
if (!socket_is_ipv6(socket)) {
@ -497,7 +497,7 @@ socket_t *socket_dereference(socket_t *socket_ptr)
* \return eFALSE no free sockets
* \return eBUSY port reserved
*/
error_t socket_create(socket_family_t family, socket_type_t type, uint8_t protocol, int8_t *sid, uint16_t port, void (*passed_fptr)(void *), bool buffer_type)
socket_error_t socket_create(socket_family_t family, socket_type_t type, uint8_t protocol, int8_t *sid, uint16_t port, void (*passed_fptr)(void *), bool buffer_type)
{
if (sid) {
*sid = -1;
@ -850,7 +850,7 @@ socket_t *socket_lookup(socket_family_t family, uint8_t protocol, const sockaddr
* \return eFALSE no socket found
* \return eBUSY socket full
*/
error_t socket_up(buffer_t *buf)
socket_error_t socket_up(buffer_t *buf)
{
socket_t *socket = buf->socket;

View File

@ -225,6 +225,8 @@ typedef struct protocol_interface_rf_mac_setup {
uint8_t aUnitBackoffPeriod;
uint8_t number_of_csma_ca_periods; /**< Number of CSMA-CA periods */
uint16_t multi_cca_interval; /**< Length of the additional CSMA-CA period(s) in microseconds */
uint16_t phy_mtu_size;
phy_802_15_4_mode_t current_mac_mode;
/* Indirect queue parameters */
struct mac_pre_build_frame *indirect_pd_data_request_queue;
struct mac_pre_build_frame enhanced_ack_buffer;

View File

@ -228,8 +228,8 @@ void mcps_sap_data_req_handler_ext(protocol_interface_rf_mac_setup_s *rf_mac_set
goto verify_status;
}
if ((data_req->msduLength + ie_header_length + ie_payload_length) > rf_mac_setup->dev_driver->phy_driver->phy_MTU - MAC_DATA_PACKET_MIN_HEADER_LENGTH) {
tr_debug("packet %u, %u", data_req->msduLength, rf_mac_setup->dev_driver->phy_driver->phy_MTU);
if ((data_req->msduLength + ie_header_length + ie_payload_length) > rf_mac_setup->phy_mtu_size - MAC_DATA_PACKET_MIN_HEADER_LENGTH) {
tr_debug("packet %u, %u", data_req->msduLength, rf_mac_setup->phy_mtu_size);
status = MLME_FRAME_TOO_LONG;
goto verify_status;
}
@ -358,7 +358,7 @@ verify_status:
static int8_t mac_virtual_data_req_handler(protocol_interface_rf_mac_setup_s *rf_mac_setup, const uint8_t *data_ptr, uint16_t data_length)
{
if (!rf_mac_setup->macUpState || data_length > rf_mac_setup->dev_driver->phy_driver->phy_MTU) {
if (!rf_mac_setup->macUpState || data_length > rf_mac_setup->phy_mtu_size) {
return -1;
}
@ -1576,7 +1576,7 @@ static int8_t mcps_generic_packet_build(protocol_interface_rf_mac_setup_s *rf_pt
uint16_t mac_payload_length = frame_length;
if (mac_payload_length > MAC_IEEE_802_15_4_MAX_MAC_SAFE_PAYLOAD_SIZE &&
dev_driver->phy_MTU == MAC_IEEE_802_15_4_MAX_PHY_PACKET_SIZE) {
rf_ptr->phy_mtu_size == MAC_IEEE_802_15_4_MAX_PHY_PACKET_SIZE) {
/* IEEE 802.15.4-2003 only allowed unsecured payloads up to 102 bytes
* (always leaving room for maximum MAC overhead).
* IEEE 802.15.4-2006 allows bigger if MAC header is small enough, but
@ -1596,8 +1596,8 @@ static int8_t mcps_generic_packet_build(protocol_interface_rf_mac_setup_s *rf_pt
//Add MHR length to total length
frame_length += buffer->mac_header_length_with_security + buffer->security_mic_len;
if ((frame_length) > dev_driver->phy_MTU - 2) {
tr_debug("Too Long %u, %u pa %u header %u mic %u", frame_length, mac_payload_length, buffer->mac_header_length_with_security, buffer->security_mic_len, dev_driver->phy_MTU);
if ((frame_length) > rf_ptr->phy_mtu_size - 2) {
tr_debug("Too Long %u, %u pa %u header %u mic %u", frame_length, mac_payload_length, buffer->mac_header_length_with_security, buffer->security_mic_len, rf_ptr->phy_mtu_size);
buffer->status = MLME_FRAME_TOO_LONG;
//decrement security counter
if (key_desc) {
@ -1745,8 +1745,8 @@ int8_t mcps_generic_ack_build(protocol_interface_rf_mac_setup_s *rf_ptr, bool in
//Add MHR length to total length
frame_length += buffer->mac_header_length_with_security + buffer->security_mic_len;
uint16_t ack_mtu_size;
if (ENHANCED_ACK_MAX_LENGTH > dev_driver->phy_MTU) {
ack_mtu_size = dev_driver->phy_MTU;
if (ENHANCED_ACK_MAX_LENGTH > rf_ptr->phy_mtu_size) {
ack_mtu_size = rf_ptr->phy_mtu_size;
} else {
ack_mtu_size = ENHANCED_ACK_MAX_LENGTH;
}

View File

@ -69,6 +69,7 @@ static void mac_mlme_timer_cb(int8_t timer_id, uint16_t slots);
static void mac_mlme_start_confirm_handler(protocol_interface_rf_mac_setup_s *rf_ptr, const mlme_start_conf_t *conf);
static void mac_mlme_scan_confirm_handler(protocol_interface_rf_mac_setup_s *rf_ptr, const mlme_scan_conf_t *conf);
static int mac_mlme_set_symbol_rate(protocol_interface_rf_mac_setup_s *rf_mac_setup);
static int mac_mlme_allocate_tx_buffers(protocol_interface_rf_mac_setup_s *rf_mac_setup, arm_device_driver_list_s *dev_driver, uint16_t mtu_size);
static void mac_mlme_energy_scan_start(protocol_interface_rf_mac_setup_s *rf_mac_setup, uint8_t channel)
{
@ -767,6 +768,29 @@ int8_t mac_mlme_set_req(protocol_interface_rf_mac_setup_s *rf_mac_setup, const m
memcpy(rf_mac_setup->coord_long_address, set_req->value_pointer, 8);
}
return 0;
case mac802_15_4Mode:
pu8 = (uint8_t *) set_req->value_pointer;
if (rf_mac_setup->current_mac_mode == *pu8) {
return -1;
}
rf_mac_setup->current_mac_mode = *pu8;
rf_mac_setup->dev_driver->phy_driver->extension(PHY_EXTENSION_SET_802_15_4_MODE, pu8);
uint16_t new_mtu_size = MAC_IEEE_802_15_4_MAX_PHY_PACKET_SIZE;
if (*pu8 == IEEE_802_15_4G_2012) {
new_mtu_size = MAC_IEEE_802_15_4G_MAX_PHY_PACKET_SIZE;
}
mac_api_t *mac_api = get_sw_mac_api(rf_mac_setup);
if (rf_mac_setup->dev_driver->phy_driver->phy_MTU > new_mtu_size) {
mac_api->phyMTU = rf_mac_setup->phy_mtu_size = new_mtu_size;
} else {
mac_api->phyMTU = rf_mac_setup->phy_mtu_size = rf_mac_setup->dev_driver->phy_driver->phy_MTU;
}
if (mac_mlme_allocate_tx_buffers(rf_mac_setup, rf_mac_setup->dev_driver, rf_mac_setup->phy_mtu_size)) {
tr_err("Failed to reallocate TX buffers");
return -1;
}
tr_debug("Set MAC mode to %s, MTU size: %u", *pu8 == IEEE_802_15_4G_2012 ? "IEEE 802.15.4G-2012" : "IEEE 802.15.4-2011", rf_mac_setup->phy_mtu_size);
return 0;
case macTXPower:
pu8 = (uint8_t *) set_req->value_pointer;
rf_mac_setup->dev_driver->phy_driver->extension(PHY_EXTENSION_SET_TX_POWER, pu8);
@ -1067,9 +1091,29 @@ static int mac_mlme_set_symbol_rate(protocol_interface_rf_mac_setup_s *rf_mac_se
return -1;
}
protocol_interface_rf_mac_setup_s *mac_mlme_data_base_allocate(uint8_t *mac64, arm_device_driver_list_s *dev_driver, mac_description_storage_size_t *storage_sizes)
static int mac_mlme_allocate_tx_buffers(protocol_interface_rf_mac_setup_s *rf_mac_setup, arm_device_driver_list_s *dev_driver, uint16_t mtu_size)
{
ns_dyn_mem_free(rf_mac_setup->dev_driver_tx_buffer.buf);
ns_dyn_mem_free(rf_mac_setup->mac_beacon_payload);
uint16_t total_length = 0;
//Allocate tx buffer by given MTU + header + tail
total_length = mtu_size;
total_length += (dev_driver->phy_driver->phy_header_length + dev_driver->phy_driver->phy_tail_length);
rf_mac_setup->dev_driver_tx_buffer.buf = ns_dyn_mem_alloc(total_length);
if (!rf_mac_setup->dev_driver_tx_buffer.buf) {
return -1;
}
//allocate Beacon Payload buffer
rf_mac_setup->max_beacon_payload_length = mtu_size - MAC_IEEE_802_15_4_MAX_BEACON_OVERHEAD;
rf_mac_setup->mac_beacon_payload = ns_dyn_mem_alloc(rf_mac_setup->max_beacon_payload_length);
if (!rf_mac_setup->mac_beacon_payload) {
return -1;
}
return 0;
}
protocol_interface_rf_mac_setup_s *mac_mlme_data_base_allocate(uint8_t *mac64, arm_device_driver_list_s *dev_driver, mac_description_storage_size_t *storage_sizes, uint16_t mtu_size)
{
//allocate security
if (!dev_driver || !mac64 || !dev_driver->phy_driver || !storage_sizes) {
return NULL;
@ -1102,20 +1146,9 @@ protocol_interface_rf_mac_setup_s *mac_mlme_data_base_allocate(uint8_t *mac64, a
mac_mlme_data_base_deallocate(entry);
return NULL;
}
entry->phy_mtu_size = mtu_size;
//Allocate tx buffer by given MTU + header + tail
total_length = dev_driver->phy_driver->phy_MTU;
total_length += (dev_driver->phy_driver->phy_header_length + dev_driver->phy_driver->phy_tail_length);
entry->dev_driver_tx_buffer.buf = ns_dyn_mem_alloc(total_length);
if (!entry->dev_driver_tx_buffer.buf) {
mac_mlme_data_base_deallocate(entry);
return NULL;
}
//allocate Beacon Payload buffer
entry->max_beacon_payload_length = dev_driver->phy_driver->phy_MTU - MAC_IEEE_802_15_4_MAX_BEACON_OVERHEAD;
entry->mac_beacon_payload = ns_dyn_mem_alloc(entry->max_beacon_payload_length);
if (!entry->mac_beacon_payload) {
if (mac_mlme_allocate_tx_buffers(entry, dev_driver, mtu_size)) {
mac_mlme_data_base_deallocate(entry);
return NULL;
}

View File

@ -106,7 +106,7 @@ void mac_mlme_event_cb(void *mac_ptr);
void mac_mlme_set_active_state(struct protocol_interface_rf_mac_setup *entry, bool new_state);
struct protocol_interface_rf_mac_setup *mac_mlme_data_base_allocate(uint8_t *mac64, struct arm_device_driver_list *dev_driver, struct mac_description_storage_size_s *storage_sizes);
struct protocol_interface_rf_mac_setup *mac_mlme_data_base_allocate(uint8_t *mac64, struct arm_device_driver_list *dev_driver, struct mac_description_storage_size_s *storage_sizes, uint16_t mtu_size);
void mac_mlme_data_base_deallocate(struct protocol_interface_rf_mac_setup *rf_mac);
uint8_t mac_mlme_set_new_sqn(struct protocol_interface_rf_mac_setup *rf_setup);

View File

@ -111,7 +111,7 @@ uint32_t mac_csma_backoff_get(protocol_interface_rf_mac_setup_s *rf_mac_setup)
backoff_in_us += ((rf_mac_setup->multi_cca_interval * (rf_mac_setup->number_of_csma_ca_periods - 1)) - backoff_in_us);
}
if (rf_mac_setup->mac_tx_retry) {
backoff_in_us += rf_mac_setup->fhss_api->get_retry_period(rf_mac_setup->fhss_api, rf_mac_setup->active_pd_data_request->DstAddr, rf_mac_setup->dev_driver->phy_driver->phy_MTU);
backoff_in_us += rf_mac_setup->fhss_api->get_retry_period(rf_mac_setup->fhss_api, rf_mac_setup->active_pd_data_request->DstAddr, rf_mac_setup->phy_mtu_size);
}
}
return backoff_in_us;

View File

@ -31,6 +31,9 @@
#include "mac_fhss_callbacks.h"
#include "eventOS_callback_timer.h"
#include "common_functions.h"
#include "ns_trace.h"
#define TRACE_GROUP "swm"
//TODO: create linked list of created MACs
@ -96,13 +99,28 @@ mac_api_t *ns_sw_mac_create(int8_t rf_driver_id, mac_description_storage_size_t
memset(this, 0, sizeof(mac_api_t));
this->parent_id = -1;
mac_store.dev_driver = driver;
mac_store.setup = mac_mlme_data_base_allocate(mac_store.dev_driver->phy_driver->PHY_MAC, mac_store.dev_driver, storage_sizes);
// Set default MTU size to 127 unless it is too much for PHY driver
if (driver->phy_driver->phy_MTU > MAC_IEEE_802_15_4_MAX_PHY_PACKET_SIZE) {
this->phyMTU = MAC_IEEE_802_15_4_MAX_PHY_PACKET_SIZE;
} else {
this->phyMTU = driver->phy_driver->phy_MTU;
}
mac_store.setup = mac_mlme_data_base_allocate(mac_store.dev_driver->phy_driver->PHY_MAC, mac_store.dev_driver, storage_sizes, this->phyMTU);
if (!mac_store.setup) {
ns_dyn_mem_free(this);
return NULL;
}
// Set MAC mode to PHY driver
mac_store.setup->current_mac_mode = IEEE_802_15_4_2011;
if (mac_store.setup->dev_driver->phy_driver->extension) {
mac_store.setup->dev_driver->phy_driver->extension(PHY_EXTENSION_SET_802_15_4_MODE, (uint8_t *) &mac_store.setup->current_mac_mode);
}
tr_debug("Set MAC mode to %s, MTU size: %u", "IEEE 802.15.4-2011", mac_store.setup->phy_mtu_size);
arm_net_phy_init(driver->phy_driver, &sw_mac_net_phy_rx, &sw_mac_net_phy_tx_done);
arm_net_virtual_config_rx_cb_set(driver->phy_driver, &sw_mac_net_phy_config_parser);
arm_net_virtual_confirmation_rx_cb_set(driver->phy_driver, &mac_mlme_virtual_confirmation_handle);
@ -116,10 +134,8 @@ mac_api_t *ns_sw_mac_create(int8_t rf_driver_id, mac_description_storage_size_t
this->mac64_get = &macext_mac64_address_get;
this->mac64_set = &macext_mac64_address_set;
this->mac_storage_sizes_get = &sw_mac_storage_decription_sizes_get;
this->phyMTU = driver->phy_driver->phy_MTU;
mac_store.mac_api = this;
mac_store.virtual_driver = NULL;
return this;
}
@ -279,8 +295,8 @@ static int8_t ns_sw_mac_api_enable_mcps_ext(mac_api_t *api, mcps_data_indication
ns_dyn_mem_free(mac_store.setup->dev_driver_tx_buffer.enhanced_ack_buf);
uint16_t total_length;
if (ENHANCED_ACK_MAX_LENGTH > dev_driver->phy_driver->phy_MTU) {
total_length = dev_driver->phy_driver->phy_MTU;
if (ENHANCED_ACK_MAX_LENGTH > mac_store.setup->phy_mtu_size) {
total_length = mac_store.setup->phy_mtu_size;
} else {
total_length = ENHANCED_ACK_MAX_LENGTH;
}

View File

@ -375,6 +375,7 @@ struct protocol_interface_info_entry {
trickle_params_t mpl_control_trickle_params;
uint16_t mpl_seed_set_entry_lifetime;
uint8_t mpl_seed_id[16];
struct mpl_domain *mpl_domain;
#endif
if_6lowpan_dad_entry_t if_6lowpan_dad_process;
lowpan_context_list_t lowpan_contexts;

View File

@ -181,11 +181,19 @@ void rpl_control_set_dio_multicast_min_config_advertisment_count(uint8_t min_cou
rpl_policy_set_dio_multicast_config_advertisment_min_count(min_count);
}
void rpl_control_set_address_registration_timeout(uint16_t timeout_in_minutes)
{
rpl_policy_set_address_registration_timeout(timeout_in_minutes);
}
void rpl_control_set_dao_retry_count(uint8_t count)
{
rpl_policy_set_dao_retry_count(count);
}
void rpl_control_set_minimum_dao_target_refresh(uint16_t seconds)
{
rpl_policy_set_minimum_dao_target_refresh(seconds);
}
void rpl_control_set_initial_dao_ack_wait(uint16_t timeout_in_ms)
{
rpl_policy_set_initial_dao_ack_wait(timeout_in_ms);
@ -198,6 +206,9 @@ void rpl_control_set_mrhof_parent_set_size(uint16_t parent_set_size)
/* Send address registration to either specified address, or to non-registered address */
void rpl_control_register_address(protocol_interface_info_entry_t *interface, const uint8_t addr[16])
{
if (!interface->rpl_domain) {
return;
}
if (!rpl_policy_parent_confirmation_requested()) {
return;
}
@ -206,21 +217,23 @@ void rpl_control_register_address(protocol_interface_info_entry_t *interface, co
}
}
void rpl_control_address_register_done(protocol_interface_info_entry_t *interface, const uint8_t ll_addr[16], uint8_t status)
bool rpl_control_address_register_done(protocol_interface_info_entry_t *interface, const uint8_t ll_addr[16], uint8_t status)
{
bool blacklist_neighbour = false;
if (!interface->rpl_domain) {
return;
return false;
}
if (!rpl_policy_parent_confirmation_requested()) {
return;
return false;
}
ns_list_foreach(struct rpl_instance, instance, &interface->rpl_domain->instances) {
rpl_neighbour_t *neighbour = rpl_lookup_neighbour_by_ll_address(instance, ll_addr, interface->id);
if (neighbour) {
rpl_instance_address_registration_done(interface, instance, neighbour, status);
blacklist_neighbour = blacklist_neighbour || rpl_instance_address_registration_done(interface, instance, neighbour, status);
}
}
return blacklist_neighbour;
}
bool rpl_control_is_dodag_parent(protocol_interface_info_entry_t *interface, const uint8_t ll_addr[16])
@ -673,6 +686,14 @@ void rpl_control_force_leaf(rpl_domain_t *domain, bool leaf)
}
}
}
void rpl_control_dao_timeout(rpl_domain_t *domain, uint16_t seconds)
{
ns_list_foreach(rpl_instance_t, instance, &domain->instances) {
rpl_instance_dao_timeout(instance, seconds);
}
}
void rpl_control_process_routes(rpl_domain_t *domain, bool process_routes)
{
domain->process_routes = process_routes;

View File

@ -145,6 +145,9 @@ void rpl_control_process_routes(rpl_domain_t *domain, bool process_routes);
/* Manually send poison on all existing instances a few times */
void rpl_control_poison(rpl_domain_t *domain, uint8_t poison_count);
/* force DAO to verify connections before given time*/
void rpl_control_dao_timeout(rpl_domain_t *domain, uint16_t seconds);
/* APIs to create domains and map them to interfaces */
rpl_domain_t *rpl_control_create_domain(void);
void rpl_control_delete_domain(rpl_domain_t *domain);
@ -170,11 +173,13 @@ bool rpl_control_find_worst_neighbor(struct protocol_interface_info_entry *inter
/* Parent link confirmation API extension */
void rpl_control_request_parent_link_confirmation(bool requested);
void rpl_control_set_dio_multicast_min_config_advertisment_count(uint8_t min_count);
void rpl_control_set_address_registration_timeout(uint16_t timeout_in_minutes);
void rpl_control_set_dao_retry_count(uint8_t count);
void rpl_control_set_minimum_dao_target_refresh(uint16_t seconds);
void rpl_control_set_initial_dao_ack_wait(uint16_t timeout_in_ms);
void rpl_control_set_mrhof_parent_set_size(uint16_t parent_set_size);
void rpl_control_register_address(struct protocol_interface_info_entry *interface, const uint8_t addr[16]);
void rpl_control_address_register_done(struct protocol_interface_info_entry *interface, const uint8_t ll_addr[16], uint8_t status);
bool rpl_control_address_register_done(struct protocol_interface_info_entry *interface, const uint8_t ll_addr[16], uint8_t status);
/* Configure and return the routing lookup predicate for a specified RPL instance ID */
ipv6_route_predicate_fn_t *rpl_control_get_route_predicate(rpl_domain_t *domain, uint8_t instance_id, const uint8_t src[16], const uint8_t dst[16]);
@ -198,7 +203,7 @@ uint8_t rpl_policy_mrhof_parent_set_size_get(const rpl_domain_t *domain);
#define rpl_control_remove_domain_from_interface(cur) ((void) 0)
#define rpl_control_free_domain_instances_from_interface(cur) ((void) 0)
#define rpl_control_register_address(interface, addr) ((void) 0)
#define rpl_control_address_register_done(interface, ll_addr, status) ((void) 0)
#define rpl_control_address_register_done(interface, ll_addr, status) (false)
#define rpl_policy_mrhof_parent_set_size_get(domain) (0)
#define rpl_control_set_mrhof_parent_set_size(parent_set_size)

View File

@ -109,8 +109,6 @@ static void rpl_downward_topo_sort_invalidate(rpl_instance_t *instance);
#define DEFAULT_DAO_DELAY 10 /* *100ms ticks = 1s */
//#define MINIMUM_DAO_TARGET_REFRESH (5*60) /* seconds */
/* Bit <n> of the PC mask */
#define PCBIT(n) (UINT8_C(0x80) >> (n))
@ -184,7 +182,7 @@ static bool rpl_instance_parent_selection_ready(rpl_instance_t *instance)
{
rpl_neighbour_t *neighbour = ns_list_get_first(&instance->candidate_neighbours);
if (neighbour && neighbour->dodag_parent && neighbour->dao_path_control) {
//We have a Primary parent with Dao patha control
//We have a Primary parent with Dao path control
return true;
}
return false;
@ -1603,11 +1601,10 @@ void rpl_instance_dao_acked(rpl_instance_t *instance, const uint8_t src[16], int
} else {
t = 0xFFFFFFFF;
}
#ifdef MINIMUM_DAO_TARGET_REFRESH
if (t > MINIMUM_DAO_TARGET_REFRESH) {
t = randLIB_randomise_base(MINIMUM_DAO_TARGET_REFRESH, 0x7333, 0x8CCD); /* +/- 10% */
if (rpl_policy_minimum_dao_target_refresh() && t > rpl_policy_minimum_dao_target_refresh()) {
// set the minimum target refresh time ranging from 25% to 10% below the value
t = randLIB_randomise_base(rpl_policy_minimum_dao_target_refresh(), 0x6000, 0x7333);
}
#endif
target->info.non_root.refresh_timer = t;
tr_debug("set rfr to %"PRIu32, t);
}
@ -1639,6 +1636,21 @@ void rpl_instance_dao_request(struct rpl_instance *instance, struct rpl_neighbou
rpl_instance_dao_trigger(instance, 0);
}
void rpl_instance_dao_timeout(struct rpl_instance *instance, uint16_t seconds)
{
// Forces DAO timeout to happen before given time distributed in given time
ns_list_foreach(rpl_dao_target_t, target, &instance->dao_targets) {
if (!target->published || target->info.non_root.refresh_timer == 0) {
continue;
}
if (target->info.non_root.refresh_timer < seconds) {
continue;
}
// Shorten the timeout
target->info.non_root.refresh_timer = randLIB_get_random_in_range(1, seconds);
}
}
void rpl_downward_dao_slow_timer(rpl_instance_t *instance, uint16_t seconds)
{
@ -1771,8 +1783,11 @@ static bool rpl_instance_push_address_registration(protocol_interface_info_entry
aro.status = ARO_SUCCESS;
aro.present = true;
aro.lifetime = (addr->valid_lifetime / 60) + 1;
memcpy(aro.eui64, interface->mac, 8);
aro.lifetime = rpl_policy_address_registration_timeout();
if (!aro.lifetime) {
aro.lifetime = (addr->valid_lifetime / 60) + 1;
}
buffer_t *buf = icmpv6_build_ns(interface, neighbour->ll_address, addr->address, true, false, &aro);
if (!buf) {
@ -1807,6 +1822,13 @@ static void rpl_instance_address_registration_cancel(rpl_instance_t *instance)
instance->dao_retry_timer = 0;
}
static void rpl_instance_address_registration_retry(rpl_dao_target_t *dao_target)
{
dao_target->active_confirmation_state = true; // Active timer is set true so the response_wait_time runs out
dao_target->trig_confirmation_state = true;
dao_target->response_wait_time = 20; // Wait 20 seconds before retry
}
void rpl_instance_parent_address_reg_timer_update(rpl_instance_t *instance, uint16_t seconds)
{
if (!instance->pending_neighbour_confirmation) {
@ -1861,7 +1883,6 @@ void rpl_instance_parent_address_reg_timer_update(rpl_instance_t *instance, uint
return;
}
if (rpl_instance_push_address_registration(interface, neighbour, address)) {
instance->wait_response = neighbour;
dao_target->response_wait_time = 5;
@ -1869,33 +1890,41 @@ void rpl_instance_parent_address_reg_timer_update(rpl_instance_t *instance, uint
}
void rpl_instance_address_registration_done(protocol_interface_info_entry_t *interface, rpl_instance_t *instance, rpl_neighbour_t *neighbour, uint8_t status)
bool rpl_instance_address_registration_done(protocol_interface_info_entry_t *interface, rpl_instance_t *instance, rpl_neighbour_t *neighbour, uint8_t status)
{
if (!instance->pending_neighbour_confirmation) {
return;
return false;
}
rpl_dao_target_t *dao_target = rpl_instance_get_active_target_confirmation(instance);
if (!dao_target || instance->wait_response != neighbour) {
return;
return false;
}
tr_debug("Address %s register to %s", trace_ipv6(dao_target->prefix), trace_ipv6(neighbour->ll_address));
if (status == SOCKET_TX_DONE) {
/* State_timer is 1/10 s. Set renewal to 75-85% of lifetime */
if_address_entry_t *address = rpl_interface_addr_get(interface, dao_target->prefix);
if (address && address->source != ADDR_SOURCE_DHCP) {
address->state_timer = (address->preferred_lifetime * randLIB_get_random_in_range(75, 85) / 10);
if (status != SOCKET_TX_DONE) {
if (neighbour->addr_reg_failures > 0) {
// Neighbor should be blacklisted after this.
tr_error("Address registration failed delete neighbor");
rpl_instance_address_registration_cancel(instance);
rpl_delete_neighbour(instance, neighbour);
return true;
}
neighbour->confirmed = true;
dao_target->response_wait_time = 6;
} else {
tr_error("Address registration failed");
rpl_delete_neighbour(instance, neighbour);
rpl_instance_address_registration_cancel(instance);
tr_warn("Address registration ACK fail retry selection");
neighbour->addr_reg_failures++;
rpl_instance_address_registration_retry(dao_target);
return false;
}
/* State_timer is 1/10 s. Set renewal to 75-85% of lifetime */
if_address_entry_t *address = rpl_interface_addr_get(interface, dao_target->prefix);
if (address && address->source != ADDR_SOURCE_DHCP) {
address->state_timer = (address->preferred_lifetime * randLIB_get_random_in_range(75, 85) / 10);
}
neighbour->addr_reg_failures = 0;
neighbour->confirmed = true;
dao_target->response_wait_time = 6;
return false;
}
#endif /* HAVE_RPL */

View File

@ -38,11 +38,12 @@ void rpl_instance_delete_published_dao_target(struct rpl_instance *instance, con
struct rpl_dao_target *rpl_instance_match_dao_target(struct rpl_instance *instance, const uint8_t *prefix, uint8_t prefix_len);
void rpl_instance_dao_request(struct rpl_instance *instance, struct rpl_neighbour *neighbour);
void rpl_instance_dao_timeout(struct rpl_instance *instance, uint16_t seconds);
void rpl_instance_dao_trigger(struct rpl_instance *instance, uint16_t delay);
void rpl_instance_dao_acked(struct rpl_instance *instance, const uint8_t src[16], int8_t interface_id, uint8_t dao_sequence, uint8_t status);
void rpl_instance_parent_address_reg_timer_update(struct rpl_instance *instance, uint16_t seconds);
void rpl_instance_send_address_registration(rpl_instance_t *instance, const uint8_t addr[16]);
void rpl_instance_address_registration_done(protocol_interface_info_entry_t *interface, rpl_instance_t *instance, rpl_neighbour_t *neighbour, uint8_t status);
bool rpl_instance_address_registration_done(protocol_interface_info_entry_t *interface, rpl_instance_t *instance, rpl_neighbour_t *neighbour, uint8_t status);
struct rpl_dao_target *rpl_instance_get_active_target_confirmation(struct rpl_instance *instance);
#ifdef HAVE_RPL_DAO_HANDLING

View File

@ -40,6 +40,8 @@ static int16_t rpl_policy_dao_initial_timeout_conf = 20; // Default is 2 seconds
static uint16_t rpl_policy_dio_validity_period_hysteresis = 0x0180; //Fixed Point 1.5
static uint8_t rpl_policy_multicast_config_min_advertisment_count = 0;
static uint8_t rpl_policy_mrhof_parent_set_size_conf = 3; // default parent set size
static uint16_t rpl_policy_minimum_dao_target_refresh_conf = 0; // by default follow the configuration
static uint16_t rpl_policy_address_registration_timeout_value = 0; // Address registration timeouts in minutes 0 use address lifetime
/* TODO - application API to control when to join new instances / DODAGs
*
@ -115,6 +117,16 @@ void rpl_policy_set_initial_dao_ack_wait(uint16_t timeout_in_ms)
rpl_policy_dao_initial_timeout_conf = timeout_in_ms;
}
void rpl_policy_set_minimum_dao_target_refresh(uint16_t seconds)
{
rpl_policy_minimum_dao_target_refresh_conf = seconds;
}
uint16_t rpl_policy_minimum_dao_target_refresh(void)
{
return rpl_policy_minimum_dao_target_refresh_conf;
}
uint16_t rpl_policy_initial_dao_ack_wait(const rpl_domain_t *domain, uint8_t mop)
{
(void)mop;
@ -381,6 +393,16 @@ void rpl_policy_set_dio_multicast_config_advertisment_min_count(uint8_t min_coun
rpl_policy_multicast_config_min_advertisment_count = min_count;
}
uint16_t rpl_policy_address_registration_timeout()
{
return rpl_policy_address_registration_timeout_value;
}
void rpl_policy_set_address_registration_timeout(uint16_t timeout_in_minutes)
{
rpl_policy_address_registration_timeout_value = timeout_in_minutes;
}
#ifdef RPL_STRUCTURES_H_
#error "rpl_structures.h should not be included by rpl_policy.c"

View File

@ -29,6 +29,9 @@ bool rpl_policy_request_dao_acks(const rpl_domain_t *domain, uint8_t mop);
uint16_t rpl_policy_initial_dao_ack_wait(const rpl_domain_t *domain, uint8_t mop);
void rpl_policy_set_initial_dao_ack_wait(uint16_t timeout_in_ms);
void rpl_policy_set_minimum_dao_target_refresh(uint16_t seconds);
uint16_t rpl_policy_minimum_dao_target_refresh(void);
void rpl_policy_set_dao_retry_count(uint8_t count);
int8_t rpl_policy_dao_retry_count();
@ -68,5 +71,7 @@ bool rpl_policy_parent_confirmation_requested(void);
void rpl_policy_set_parent_confirmation_request(bool confirmation_requested);
uint8_t rpl_policy_dio_multicast_config_advertisment_min_count(void);
void rpl_policy_set_dio_multicast_config_advertisment_min_count(uint8_t min_count);
uint16_t rpl_policy_address_registration_timeout();
void rpl_policy_set_address_registration_timeout(uint16_t timeout_in_minutes);
#endif /* RPL_POLICY_H_ */

View File

@ -52,6 +52,7 @@ struct rpl_neighbour {
unsigned dodag_pref: 4; // Preference indication for DODAG parents (0=best)
uint8_t dao_path_control; // Path control bit assignments for DAO parent
uint8_t old_dao_path_control;
uint8_t addr_reg_failures; // Address registration failure count (missing ACK)
int8_t interface_id;
uint8_t g_mop_prf;
uint8_t dtsn;

View File

@ -444,6 +444,7 @@ rpl_neighbour_t *rpl_create_neighbour(rpl_dodag_version_t *version, const uint8_
neighbour->dtsn = dtsn;
neighbour->dao_path_control = 0;
neighbour->confirmed = 0;
neighbour->addr_reg_failures = 0;
/* Need to limit number of neighbours here - chucking worst neighbour */

View File

@ -25,6 +25,7 @@
#include "Common_Protocols/ipv6_constants.h"
#include "socket_api.h"
#include "6LoWPAN/ws/ws_config.h"
#include "Security/protocols/sec_prot_cfg.h"
#include "Security/kmp/kmp_addr.h"
#include "Security/kmp/kmp_api.h"
#include "Security/kmp/kmp_socket_if.h"
@ -98,7 +99,7 @@ static void kmp_sec_prot_receive_disable(sec_prot_t *prot);
#define kmp_api_get_from_prot(prot) (kmp_api_t *)(((uint8_t *)prot) - offsetof(kmp_api_t, sec_prot));
kmp_api_t *kmp_api_create(kmp_service_t *service, kmp_type_e type)
kmp_api_t *kmp_api_create(kmp_service_t *service, kmp_type_e type, sec_prot_cfg_t *cfg)
{
if (!service) {
return 0;
@ -150,6 +151,7 @@ kmp_api_t *kmp_api_create(kmp_service_t *service, kmp_type_e type)
kmp->sec_prot.addr_get = kmp_sec_prot_eui64_addr_get;
kmp->sec_prot.type_get = kmp_sec_prot_by_type_get;
kmp->sec_prot.receive_disable = kmp_sec_prot_receive_disable;
kmp->sec_prot.cfg = cfg;
if (sec_prot->init(&kmp->sec_prot) < 0) {
ns_dyn_mem_free(kmp);

View File

@ -61,6 +61,8 @@ typedef struct sec_prot_s sec_prot_t;
typedef struct kmp_api_s kmp_api_t;
typedef struct kmp_service_s kmp_service_t;
struct ws_cfg_settings_s;
/**
* kmp_api_create_request KMP-CREATE.request
*
@ -123,11 +125,12 @@ typedef void kmp_api_finished(kmp_api_t *kmp);
*
* \param service KMP service
* \param type KMP type
* \param cfg configuration
*
* \return KMP instance or NULL
*
*/
kmp_api_t *kmp_api_create(kmp_service_t *service, kmp_type_e type);
kmp_api_t *kmp_api_create(kmp_service_t *service, kmp_type_e type, sec_prot_cfg_t *cfg);
/**
* kmp_api_start start KMP api

View File

@ -23,6 +23,7 @@
#include "nsdynmemLIB.h"
#include "6LoWPAN/ws/ws_config.h"
#include "NWK_INTERFACE/Include/protocol.h"
#include "Security/protocols/sec_prot_cfg.h"
#include "Security/kmp/kmp_addr.h"
#include "Security/kmp/kmp_api.h"
#include "Security/kmp/kmp_eapol_pdu_if.h"

View File

@ -29,6 +29,7 @@
#include "Common_Protocols/ipv6_constants.h"
#include "socket_api.h"
#include "6LoWPAN/ws/ws_config.h"
#include "Security/protocols/sec_prot_cfg.h"
#include "Security/kmp/kmp_addr.h"
#include "Security/kmp/kmp_api.h"
#include "Security/kmp/kmp_socket_if.h"

View File

@ -24,6 +24,8 @@
#include "fhss_config.h"
#include "NWK_INTERFACE/Include/protocol.h"
#include "6LoWPAN/ws/ws_config.h"
#include "6LoWPAN/ws/ws_cfg_settings.h"
#include "Security/protocols/sec_prot_cfg.h"
#include "Security/kmp/kmp_addr.h"
#include "Security/kmp/kmp_api.h"
#include "Security/PANA/pana_eap_header.h"
@ -77,22 +79,6 @@ typedef struct {
bool send_pending: 1; /**< TLS data is not yet send to network */
} eap_tls_sec_prot_int_t;
/*Small network setup*/
#define EAP_TLS_SMALL_IMIN 300 // retries done in 30 seconds
#define EAP_TLS_SMALL_IMAX 900 // Largest value 90 seconds
/* Large network setup*/
#define EAP_TLS_LARGE_IMIN 600 // retries done in 60 seconds
#define EAP_TLS_LARGE_IMAX 2400 // Largest value 240 seconds
static trickle_params_t eap_tls_trickle_params = {
.Imin = EAP_TLS_SMALL_IMIN, /* ticks are 100ms */
.Imax = EAP_TLS_SMALL_IMAX, /* ticks are 100ms */
.k = 0, /* infinity - no consistency checking */
.TimerExpirations = 2
};
static uint16_t auth_eap_tls_sec_prot_size(void);
static int8_t auth_eap_tls_sec_prot_init(sec_prot_t *prot);
@ -126,19 +112,6 @@ int8_t auth_eap_tls_sec_prot_register(kmp_service_t *service)
return 0;
}
int8_t auth_eap_tls_sec_prot_timing_adjust(uint8_t timing)
{
if (timing < 16) {
eap_tls_trickle_params.Imin = EAP_TLS_SMALL_IMIN;
eap_tls_trickle_params.Imax = EAP_TLS_SMALL_IMAX;
} else {
eap_tls_trickle_params.Imin = EAP_TLS_LARGE_IMIN;
eap_tls_trickle_params.Imax = EAP_TLS_LARGE_IMAX;
}
return 0;
}
static uint16_t auth_eap_tls_sec_prot_size(void)
{
return sizeof(eap_tls_sec_prot_int_t);
@ -216,7 +189,7 @@ static int8_t auth_eap_tls_sec_prot_receive(sec_prot_t *prot, void *pdu, uint16_
// Call state machine
prot->state_machine(prot);
// Resets trickle timer to give time for supplicant to answer
sec_prot_timer_trickle_start(&data->common, &eap_tls_trickle_params);
sec_prot_timer_trickle_start(&data->common, &prot->cfg->sec_prot_trickle_params);
data->init_key_cnt++;
}
// Filters repeated initial EAPOL-key messages
@ -323,7 +296,8 @@ static void auth_eap_tls_sec_prot_timer_timeout(sec_prot_t *prot, uint16_t ticks
data->burst_filt_timer = 0;
}
sec_prot_timer_timeout_handle(prot, &data->common, &eap_tls_trickle_params, ticks);
sec_prot_timer_timeout_handle(prot, &data->common,
&prot->cfg->sec_prot_trickle_params, ticks);
}
static void auth_eap_tls_sec_prot_tls_create_indication(sec_prot_t *tls_prot)
@ -447,7 +421,7 @@ static void auth_eap_tls_sec_prot_state_machine(sec_prot_t *prot)
auth_eap_tls_sec_prot_message_send(prot, EAP_REQ, EAP_IDENTITY, EAP_TLS_EXCHANGE_NONE);
// Start trickle timer to re-send if no response
sec_prot_timer_trickle_start(&data->common, &eap_tls_trickle_params);
sec_prot_timer_trickle_start(&data->common, &prot->cfg->sec_prot_trickle_params);
sec_prot_state_set(prot, &data->common, EAP_TLS_STATE_RESPONSE_ID);
break;
@ -471,7 +445,7 @@ static void auth_eap_tls_sec_prot_state_machine(sec_prot_t *prot)
auth_eap_tls_sec_prot_message_send(prot, EAP_REQ, EAP_TLS, EAP_TLS_EXCHANGE_START);
// Start trickle timer to re-send if no response
sec_prot_timer_trickle_start(&data->common, &eap_tls_trickle_params);
sec_prot_timer_trickle_start(&data->common, &prot->cfg->sec_prot_trickle_params);
sec_prot_state_set(prot, &data->common, EAP_TLS_STATE_RESPONSE_START);
break;
@ -553,7 +527,7 @@ static void auth_eap_tls_sec_prot_state_machine(sec_prot_t *prot)
auth_eap_tls_sec_prot_message_send(prot, EAP_REQ, EAP_TLS, EAP_TLS_EXCHANGE_ONGOING);
// Start trickle timer to re-send if no response
sec_prot_timer_trickle_start(&data->common, &eap_tls_trickle_params);
sec_prot_timer_trickle_start(&data->common, &prot->cfg->sec_prot_trickle_params);
} else {
// TLS done, indicate success to peer
if (data->tls_result == EAP_TLS_RESULT_HANDSHAKE_OVER) {

View File

@ -25,6 +25,7 @@
#include "fhss_config.h"
#include "NWK_INTERFACE/Include/protocol.h"
#include "6LoWPAN/ws/ws_config.h"
#include "Security/protocols/sec_prot_cfg.h"
#include "Security/kmp/kmp_addr.h"
#include "Security/kmp/kmp_api.h"
#include "Security/PANA/pana_eap_header.h"

View File

@ -24,6 +24,7 @@
#include "fhss_config.h"
#include "NWK_INTERFACE/Include/protocol.h"
#include "6LoWPAN/ws/ws_config.h"
#include "Security/protocols/sec_prot_cfg.h"
#include "Security/kmp/kmp_addr.h"
#include "Security/kmp/kmp_api.h"
#include "Security/PANA/pana_eap_header.h"
@ -75,8 +76,6 @@ typedef struct {
#define EAP_TLS_RETRY_TIMEOUT_SMALL 330*10 // retry timeout for small network additional 30 seconds for authenticator delay
#define EAP_TLS_RETRY_TIMEOUT_LARGE 750*10 // retry timeout for large network additional 30 seconds for authenticator delay
static uint16_t retry_timeout = EAP_TLS_RETRY_TIMEOUT_SMALL;
static uint16_t supp_eap_tls_sec_prot_size(void);
static int8_t supp_eap_tls_sec_prot_init(sec_prot_t *prot);
@ -110,17 +109,6 @@ int8_t supp_eap_tls_sec_prot_register(kmp_service_t *service)
return 0;
}
int8_t supp_eap_sec_prot_timing_adjust(uint8_t timing)
{
if (timing < 16) {
retry_timeout = EAP_TLS_RETRY_TIMEOUT_SMALL;
} else {
retry_timeout = EAP_TLS_RETRY_TIMEOUT_LARGE;
}
return 0;
}
static uint16_t supp_eap_tls_sec_prot_size(void)
{
return sizeof(eap_tls_sec_prot_int_t);
@ -416,7 +404,7 @@ static void supp_eap_tls_sec_prot_state_machine(sec_prot_t *prot)
}
// Set retry timeout based on network size
data->common.ticks = retry_timeout;
data->common.ticks = prot->cfg->sec_prot_retry_timeout;
// Store sequence ID
supp_eap_tls_sec_prot_seq_id_update(prot);
@ -461,7 +449,7 @@ static void supp_eap_tls_sec_prot_state_machine(sec_prot_t *prot)
supp_eap_tls_sec_prot_seq_id_update(prot);
sec_prot_state_set(prot, &data->common, EAP_TLS_STATE_REQUEST);
data->common.ticks = retry_timeout;
data->common.ticks = prot->cfg->sec_prot_retry_timeout;
// Initialize TLS protocol
if (supp_eap_tls_sec_prot_init_tls(prot) < 0) {
@ -495,7 +483,7 @@ static void supp_eap_tls_sec_prot_state_machine(sec_prot_t *prot)
// Store sequence ID
if (supp_eap_tls_sec_prot_seq_id_update(prot)) {
// When receiving a new sequence number, adds more time for re-send if no response
data->common.ticks = retry_timeout;
data->common.ticks = prot->cfg->sec_prot_retry_timeout;
}
// All fragments received for a message

View File

@ -33,27 +33,5 @@
*/
int8_t supp_eap_tls_sec_prot_register(kmp_service_t *service);
/**
* supp_eap_sec_prot_timing_adjust Adjust retries and timings of the 4WH protocol
*
* Timing value is a generic number between 0 to 32 that goes from fast and
* reactive network to low bandwidth and long latency.
*
* example value definitions:
* 0-8 very fast network
* 9-16 medium network
* 16-24 slow network
* 25-32 extremely slow network
*
* There is no need to have lots variations in every layer if protocol is not very active in any case.
*
* \param timing Timing value.
*
* \return < 0 failure
* \return >= 0 success
*
*/
int8_t supp_eap_sec_prot_timing_adjust(uint8_t timing);
#endif /* SUPP_EAP_TLS_SEC_PROT_H_ */

View File

@ -24,6 +24,8 @@
#include "fhss_config.h"
#include "NWK_INTERFACE/Include/protocol.h"
#include "6LoWPAN/ws/ws_config.h"
#include "6LoWPAN/ws/ws_cfg_settings.h"
#include "Security/protocols/sec_prot_cfg.h"
#include "Security/kmp/kmp_addr.h"
#include "Security/kmp/kmp_api.h"
#include "Security/PANA/pana_eap_header.h"
@ -68,21 +70,6 @@ typedef struct {
uint16_t recv_size; /**< received pdu size */
} fwh_sec_prot_int_t;
/*Small network setup*/
#define FWH_SMALL_IMIN 300 // retries done in 30 seconds
#define FWH_SMALL_IMAX 900 // Largest value 90 seconds
/* Large network setup*/
#define FWH_LARGE_IMIN 600 // retries done in 60 seconds
#define FWH_LARGE_IMAX 2400 // Largest value 240 seconds
static trickle_params_t fwh_trickle_params = {
.Imin = FWH_SMALL_IMIN, /* ticks are 100ms */
.Imax = FWH_SMALL_IMAX, /* ticks are 100ms */
.k = 0, /* infinity - no consistency checking */
.TimerExpirations = 2
};
static uint16_t auth_fwh_sec_prot_size(void);
static int8_t auth_fwh_sec_prot_init(sec_prot_t *prot);
@ -113,18 +100,6 @@ int8_t auth_fwh_sec_prot_register(kmp_service_t *service)
return 0;
}
int8_t auth_fwh_sec_prot_timing_adjust(uint8_t timing)
{
if (timing < 16) {
fwh_trickle_params.Imin = FWH_SMALL_IMIN;
fwh_trickle_params.Imax = FWH_SMALL_IMAX;
} else {
fwh_trickle_params.Imin = FWH_LARGE_IMIN;
fwh_trickle_params.Imax = FWH_LARGE_IMAX;
}
return 0;
}
static uint16_t auth_fwh_sec_prot_size(void)
{
return sizeof(fwh_sec_prot_int_t);
@ -331,7 +306,7 @@ static int8_t auth_fwh_sec_prot_message_send(sec_prot_t *prot, fwh_sec_prot_msg_
static void auth_fwh_sec_prot_timer_timeout(sec_prot_t *prot, uint16_t ticks)
{
fwh_sec_prot_int_t *data = fwh_sec_prot_get(prot);
sec_prot_timer_timeout_handle(prot, &data->common, &fwh_trickle_params, ticks);
sec_prot_timer_timeout_handle(prot, &data->common, &prot->cfg->sec_prot_trickle_params, ticks);
}
static void auth_fwh_sec_prot_state_machine(sec_prot_t *prot)
@ -368,7 +343,7 @@ static void auth_fwh_sec_prot_state_machine(sec_prot_t *prot)
auth_fwh_sec_prot_message_send(prot, FWH_MESSAGE_1);
// Start trickle timer to re-send if no response
sec_prot_timer_trickle_start(&data->common, &fwh_trickle_params);
sec_prot_timer_trickle_start(&data->common, &prot->cfg->sec_prot_trickle_params);
sec_prot_state_set(prot, &data->common, FWH_STATE_MESSAGE_2);
break;
@ -396,7 +371,7 @@ static void auth_fwh_sec_prot_state_machine(sec_prot_t *prot)
auth_fwh_sec_prot_message_send(prot, FWH_MESSAGE_3);
// Start trickle timer to re-send if no response
sec_prot_timer_trickle_start(&data->common, &fwh_trickle_params);
sec_prot_timer_trickle_start(&data->common, &prot->cfg->sec_prot_trickle_params);
sec_prot_state_set(prot, &data->common, FWH_STATE_MESSAGE_4);
}

View File

@ -24,6 +24,7 @@
#include "fhss_config.h"
#include "NWK_INTERFACE/Include/protocol.h"
#include "6LoWPAN/ws/ws_config.h"
#include "Security/protocols/sec_prot_cfg.h"
#include "Security/kmp/kmp_addr.h"
#include "Security/kmp/kmp_api.h"
#include "Security/PANA/pana_eap_header.h"
@ -82,11 +83,6 @@ typedef struct {
bool recv_replay_cnt_set : 1; /**< received replay counter set */
} fwh_sec_prot_int_t;
#define FWH_RETRY_TIMEOUT_SMALL 300*10 // retry timeout for small network
#define FWH_RETRY_TIMEOUT_LARGE 720*10 // retry timeout for large network
static uint16_t retry_timeout = FWH_RETRY_TIMEOUT_SMALL;
static uint16_t supp_fwh_sec_prot_size(void);
static int8_t supp_fwh_sec_prot_init(sec_prot_t *prot);
@ -124,15 +120,6 @@ int8_t supp_fwh_sec_prot_register(kmp_service_t *service)
return 0;
}
int8_t supp_fwh_sec_prot_timing_adjust(uint8_t timing)
{
if (timing < 16) {
retry_timeout = FWH_RETRY_TIMEOUT_SMALL;
} else {
retry_timeout = FWH_RETRY_TIMEOUT_LARGE;
}
return 0;
}
static uint16_t supp_fwh_sec_prot_size(void)
{
@ -152,7 +139,7 @@ static int8_t supp_fwh_sec_prot_init(sec_prot_t *prot)
sec_prot_init(&data->common);
sec_prot_state_set(prot, &data->common, FWH_STATE_INIT);
data->common.ticks = retry_timeout;
data->common.ticks = prot->cfg->sec_prot_retry_timeout;
data->msg3_received = false;
data->msg3_retry_wait = false;
data->recv_replay_cnt = 0;
@ -350,7 +337,7 @@ static void supp_fwh_sec_prot_state_machine(sec_prot_t *prot)
if (sec_prot_result_ok_check(&data->common)) {
// Send 4WH message 2
supp_fwh_sec_prot_message_send(prot, FWH_MESSAGE_2);
data->common.ticks = retry_timeout;
data->common.ticks = prot->cfg->sec_prot_retry_timeout;
sec_prot_state_set(prot, &data->common, FWH_STATE_MESSAGE_3);
} else {
// Ready to be deleted
@ -378,7 +365,7 @@ static void supp_fwh_sec_prot_state_machine(sec_prot_t *prot)
// Send 4WH message 2
supp_fwh_sec_prot_message_send(prot, FWH_MESSAGE_2);
data->common.ticks = retry_timeout;
data->common.ticks = prot->cfg->sec_prot_retry_timeout;
return;
} else if (data->recv_msg != FWH_MESSAGE_3) {
return;
@ -405,7 +392,7 @@ static void supp_fwh_sec_prot_state_machine(sec_prot_t *prot)
// Sends 4WH Message 4
supp_fwh_sec_prot_message_send(prot, FWH_MESSAGE_4);
data->common.ticks = retry_timeout;
data->common.ticks = prot->cfg->sec_prot_retry_timeout;
sec_prot_state_set(prot, &data->common, FWH_STATE_FINISH);
break;

View File

@ -34,26 +34,4 @@
*/
int8_t supp_fwh_sec_prot_register(kmp_service_t *service);
/**
* supp_fwh_sec_prot_timing_adjust Adjust retries and timings of the 4WH protocol
*
* Timing value is a generic number between 0 to 32 that goes from fast and
* reactive network to low bandwidth and long latency.
*
* example value definitions:
* 0-8 very fast network
* 9-16 medium network
* 16-24 slow network
* 25-32 extremely slow network
*
* There is no need to have lots variations in every layer if protocol is not very active in any case.
*
* \param timing Timing value.
*
* \return < 0 failure
* \return >= 0 success
*
*/
int8_t supp_fwh_sec_prot_timing_adjust(uint8_t timing);
#endif /* SUPP_FWH_SEC_PROT_H_ */

View File

@ -24,6 +24,8 @@
#include "fhss_config.h"
#include "NWK_INTERFACE/Include/protocol.h"
#include "6LoWPAN/ws/ws_config.h"
#include "6LoWPAN/ws/ws_cfg_settings.h"
#include "Security/protocols/sec_prot_cfg.h"
#include "Security/kmp/kmp_addr.h"
#include "Security/kmp/kmp_api.h"
#include "Security/PANA/pana_eap_header.h"
@ -60,21 +62,6 @@ typedef struct {
uint16_t recv_size; /**< Received pdu size */
} gkh_sec_prot_int_t;
/*Small network setup*/
#define GKH_SMALL_IMIN 300 // retries done in 30 seconds
#define GKH_SMALL_IMAX 900 // Largest value 90 seconds
/* Large network setup*/
#define GKH_LARGE_IMIN 600 // retries done in 60 seconds
#define GKH_LARGE_IMAX 2400 // Largest value 240 seconds
static trickle_params_t gkh_trickle_params = {
.Imin = GKH_SMALL_IMIN, /* ticks are 100ms */
.Imax = GKH_SMALL_IMAX, /* ticks are 100ms */
.k = 0, /* infinity - no consistency checking */
.TimerExpirations = 2
};
static uint16_t auth_gkh_sec_prot_size(void);
static int8_t auth_gkh_sec_prot_init(sec_prot_t *prot);
@ -103,18 +90,6 @@ int8_t auth_gkh_sec_prot_register(kmp_service_t *service)
return 0;
}
int8_t auth_gkh_sec_prot_timing_adjust(uint8_t timing)
{
if (timing < 16) {
gkh_trickle_params.Imin = GKH_SMALL_IMIN;
gkh_trickle_params.Imax = GKH_SMALL_IMAX;
} else {
gkh_trickle_params.Imin = GKH_LARGE_IMIN;
gkh_trickle_params.Imax = GKH_LARGE_IMAX;
}
return 0;
}
static uint16_t auth_gkh_sec_prot_size(void)
{
return sizeof(gkh_sec_prot_int_t);
@ -283,7 +258,7 @@ static int8_t auth_gkh_sec_prot_message_send(sec_prot_t *prot, gkh_sec_prot_msg_
static void auth_gkh_sec_prot_timer_timeout(sec_prot_t *prot, uint16_t ticks)
{
gkh_sec_prot_int_t *data = gkh_sec_prot_get(prot);
sec_prot_timer_timeout_handle(prot, &data->common, &gkh_trickle_params, ticks);
sec_prot_timer_timeout_handle(prot, &data->common, &prot->cfg->sec_prot_trickle_params, ticks);
}
static void auth_gkh_sec_prot_state_machine(sec_prot_t *prot)
@ -312,7 +287,7 @@ static void auth_gkh_sec_prot_state_machine(sec_prot_t *prot)
auth_gkh_sec_prot_message_send(prot, GKH_MESSAGE_1);
// Start trickle timer to re-send if no response
sec_prot_timer_trickle_start(&data->common, &gkh_trickle_params);
sec_prot_timer_trickle_start(&data->common, &prot->cfg->sec_prot_trickle_params);
sec_prot_state_set(prot, &data->common, GKH_STATE_MESSAGE_2);

View File

@ -24,6 +24,7 @@
#include "fhss_config.h"
#include "NWK_INTERFACE/Include/protocol.h"
#include "6LoWPAN/ws/ws_config.h"
#include "Security/protocols/sec_prot_cfg.h"
#include "Security/kmp/kmp_addr.h"
#include "Security/kmp/kmp_api.h"
#include "Security/PANA/pana_eap_header.h"

View File

@ -24,6 +24,7 @@
#include "fhss_config.h"
#include "NWK_INTERFACE/Include/protocol.h"
#include "6LoWPAN/ws/ws_config.h"
#include "Security/protocols/sec_prot_cfg.h"
#include "Security/kmp/kmp_addr.h"
#include "Security/kmp/kmp_api.h"
#include "Security/PANA/pana_eap_header.h"

View File

@ -268,6 +268,7 @@ struct sec_prot_s {
sec_prot_receive_disable *receive_disable; /**< Disable receiving of messages */
sec_prot_keys_t *sec_keys; /**< Security keys storage pointer */
sec_prot_cfg_t *cfg; /**< Configuration pointer */
uint8_t header_size; /**< Header size */
sec_prot_int_data_t *data; /**< Protocol internal data */
};

View File

@ -0,0 +1,28 @@
/*
* Copyright (c) 2020, Arm Limited 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 SEC_PROT_CFG_H_
#define SEC_PROT_CFG_H_
/* Security protocol configuration settings */
typedef struct sec_prot_cfg_s {
trickle_params_t sec_prot_trickle_params;
uint16_t sec_prot_retry_timeout;
} sec_prot_cfg_t;
#endif /* SEC_PROT_CONF_H_ */

View File

@ -25,6 +25,7 @@
#include "Common_Protocols/ipv6_constants.h"
#include "socket_api.h"
#include "6LoWPAN/ws/ws_config.h"
#include "Security/protocols/sec_prot_cfg.h"
#include "Security/kmp/kmp_addr.h"
#include "Security/kmp/kmp_api.h"
#include "Security/PANA/pana_eap_header.h"

View File

@ -26,6 +26,7 @@
#include "NWK_INTERFACE/Include/protocol.h"
#include "6LoWPAN/ws/ws_config.h"
#include "Service_Libs/Trickle/trickle.h"
#include "Security/protocols/sec_prot_cfg.h"
#include "Security/kmp/kmp_addr.h"
#include "Security/kmp/kmp_api.h"
#include "Security/PANA/pana_eap_header.h"

View File

@ -22,8 +22,10 @@
#include "ns_trace.h"
#include "nsdynmemLIB.h"
#include "fhss_config.h"
#include "Service_Libs/Trickle/trickle.h"
#include "NWK_INTERFACE/Include/protocol.h"
#include "6LoWPAN/ws/ws_config.h"
#include "Security/protocols/sec_prot_cfg.h"
#include "Security/kmp/kmp_addr.h"
#include "Security/kmp/kmp_api.h"
#include "Security/PANA/pana_eap_header.h"

View File

@ -35,10 +35,14 @@
#include "ns_trace.h"
#include "nsdynmemLIB.h"
#include "common_functions.h"
#include "Service_Libs/Trickle/trickle.h"
#include "Security/protocols/sec_prot_cfg.h"
#include "Security/protocols/sec_prot_certs.h"
#include "Security/protocols/tls_sec_prot/tls_sec_prot_lib.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 */
#ifdef WS_MBEDTLS_SECURITY_ENABLED
#endif
#include "mbedtls/sha256.h"
#include "mbedtls/error.h"
@ -51,8 +55,6 @@
#include "mbedtls/debug.h"
#include "mbedtls/oid.h"
#include "mbedtls/ssl_internal.h"
#define TRACE_GROUP "tlsl"
#define TLS_HANDSHAKE_TIMEOUT_MIN 25000
@ -395,13 +397,12 @@ int8_t tls_sec_prot_lib_connect(tls_security_t *sec, bool is_server, const sec_p
// Set certificate verify callback
mbedtls_ssl_set_verify(&sec->ssl, tls_sec_prot_lib_x509_crt_verify, sec);
#ifdef MBEDTLS_ECP_RESTARTABLE
if (is_server_is_set) {
// Temporary to enable non blocking ECC */
sec->ssl.handshake->ecrs_enabled = 1;
}
#endif
/* Currently assuming we are running fast enough HW that ECC calculations are not blocking any normal operation.
*
* If there is a problem with ECC calculations and those are taking too long in border router
* MBEDTLS_ECP_RESTARTABLE feature needs to be enabled and public API is needed to allow it in border router
* enabling should be done here.
*/
return 0;
}
@ -572,7 +573,7 @@ static int tls_sec_prot_lib_x509_crt_idevid_ldevid_verify(tls_security_t *sec, m
// For both IDevID and LDevId both subject alternative name or extended key usage must be valid
if (tls_sec_prot_lib_subject_alternative_name_validate(crt) < 0 ||
tls_sec_prot_lib_extended_key_usage_validate(crt) < 0) {
tr_error("invalid cert");
tr_info("no wisun fields on cert");
if (sec->ext_cert_valid) {
*flags |= MBEDTLS_X509_BADCERT_OTHER;
return MBEDTLS_ERR_X509_CERT_VERIFY_FAILED;
@ -592,7 +593,7 @@ static int tls_sec_prot_lib_x509_crt_server_verify(tls_security_t *sec, mbedtls_
if (sane_res >= 0 || ext_key_res >= 0) {
// Then both subject alternative name and extended key usage must be valid
if (sane_res < 0 || ext_key_res < 0) {
tr_error("invalid cert");
tr_info("no wisun fields on cert");
if (sec->ext_cert_valid) {
*flags |= MBEDTLS_X509_BADCERT_OTHER;
return MBEDTLS_ERR_X509_CERT_VERIFY_FAILED;

View File

@ -40,6 +40,7 @@ struct fhss_structure {
int8_t fhss_event_timer;
uint8_t active_fhss_events;
uint16_t number_of_channels;
uint16_t number_of_uc_channels;
uint16_t optimal_packet_length;
fhss_states fhss_state;
uint32_t fhss_timeout;

View File

@ -122,6 +122,8 @@ fhss_structure_t *fhss_ws_enable(fhss_api_t *fhss_api, const fhss_ws_configurati
return NULL;
}
int channel_count = channel_list_count_channels(fhss_configuration->channel_mask);
int uc_channel_count = channel_list_count_channels(fhss_configuration->unicast_channel_mask);
if (channel_count <= 0) {
// There must be at least one configured channel in channel list
return NULL;
@ -145,7 +147,15 @@ fhss_structure_t *fhss_ws_enable(fhss_api_t *fhss_api, const fhss_ws_configurati
fhss_struct->fhss_event_timer = eventOS_callback_timer_register(fhss_event_timer_cb);
fhss_struct->ws->fhss_configuration = *fhss_configuration;
if (uc_channel_count == 0) {
//If Unicast channel is empty use Domain mask
for (uint8_t i = 0; i < 8; i++) {
fhss_struct->ws->fhss_configuration.unicast_channel_mask[i] = fhss_configuration->channel_mask[i];
}
uc_channel_count = channel_count;
}
fhss_struct->number_of_channels = channel_count;
fhss_struct->number_of_uc_channels = uc_channel_count;
fhss_struct->optimal_packet_length = OPTIMAL_PACKET_LENGTH;
fhss_ws_set_hop_count(fhss_struct, 0xff);
fhss_struct->rx_channel = fhss_configuration->unicast_fixed_channel;
@ -371,7 +381,7 @@ static uint32_t fhss_ws_calculate_ufsi(fhss_structure_t *fhss_structure, uint32_
uint8_t dwell_time = fhss_structure->ws->fhss_configuration.fhss_uc_dwell_interval;
uint16_t cur_slot = fhss_structure->ws->uc_slot;
if (cur_slot == 0) {
cur_slot = fhss_structure->number_of_channels;
cur_slot = fhss_structure->number_of_uc_channels;
}
cur_slot--;
uint32_t remaining_time_ms = US_TO_MS(get_remaining_slots_us(fhss_structure, fhss_unicast_handler, MS_TO_US(fhss_structure->ws->fhss_configuration.fhss_uc_dwell_interval)));
@ -383,8 +393,8 @@ static uint32_t fhss_ws_calculate_ufsi(fhss_structure_t *fhss_structure, uint32_
uint64_t ms_since_seq_start = (cur_slot * dwell_time) + (dwell_time - remaining_time_ms) + time_to_tx;
uint32_t seq_length = 0x10000;
if (fhss_structure->ws->fhss_configuration.ws_uc_channel_function == WS_TR51CF) {
ms_since_seq_start %= (dwell_time * fhss_structure->number_of_channels);
seq_length = fhss_structure->number_of_channels;
ms_since_seq_start %= (dwell_time * fhss_structure->number_of_uc_channels);
seq_length = fhss_structure->number_of_uc_channels;
}
return own_floor((float)(ms_since_seq_start * DEF_2E24) / (seq_length * dwell_time));
}
@ -467,16 +477,16 @@ static void fhss_ws_update_uc_channel_callback(fhss_structure_t *fhss_structure)
if (fhss_structure->ws->fhss_configuration.ws_uc_channel_function == WS_FIXED_CHANNEL) {
return;
} else if (fhss_structure->ws->fhss_configuration.ws_uc_channel_function == WS_TR51CF) {
next_channel = fhss_structure->rx_channel = tr51_get_uc_channel_index(fhss_structure->ws->tr51_channel_table, fhss_structure->ws->tr51_output_table, fhss_structure->ws->uc_slot, mac_address, fhss_structure->number_of_channels, NULL);
if (++fhss_structure->ws->uc_slot == fhss_structure->number_of_channels) {
next_channel = fhss_structure->rx_channel = tr51_get_uc_channel_index(fhss_structure->ws->tr51_channel_table, fhss_structure->ws->tr51_output_table, fhss_structure->ws->uc_slot, mac_address, fhss_structure->number_of_uc_channels, NULL);
if (++fhss_structure->ws->uc_slot == fhss_structure->number_of_uc_channels) {
fhss_structure->ws->uc_slot = 0;
}
} else if (fhss_structure->ws->fhss_configuration.ws_uc_channel_function == WS_DH1CF) {
next_channel = fhss_structure->rx_channel = dh1cf_get_uc_channel_index(fhss_structure->ws->uc_slot, mac_address, fhss_structure->number_of_channels);
next_channel = fhss_structure->rx_channel = dh1cf_get_uc_channel_index(fhss_structure->ws->uc_slot, mac_address, fhss_structure->number_of_uc_channels);
fhss_structure->ws->uc_slot++;
} else if (fhss_structure->ws->fhss_configuration.ws_uc_channel_function == WS_VENDOR_DEF_CF) {
if (fhss_structure->ws->fhss_configuration.vendor_defined_cf) {
next_channel = fhss_structure->rx_channel = fhss_structure->ws->fhss_configuration.vendor_defined_cf(fhss_structure->fhss_api, fhss_structure->ws->bc_slot, mac_address, fhss_structure->ws->fhss_configuration.bsi, fhss_structure->number_of_channels);
next_channel = fhss_structure->rx_channel = fhss_structure->ws->fhss_configuration.vendor_defined_cf(fhss_structure->fhss_api, fhss_structure->ws->bc_slot, mac_address, fhss_structure->ws->fhss_configuration.bsi, fhss_structure->number_of_uc_channels);
}
}
// Do not switch unicast channel when broadcast channel is active.
@ -521,16 +531,17 @@ static int fhss_ws_tx_handle_callback(const fhss_api_t *api, bool is_broadcast_a
fhss_stats_update(fhss_structure, STATS_FHSS_UNKNOWN_NEIGHBOR, 1);
return -2;
}
// TODO: WS bootstrap has to store neighbors number of channels
if (neighbor_timing_info->uc_timing_info.unicast_number_of_channels == 0) {
neighbor_timing_info->uc_timing_info.unicast_number_of_channels = fhss_structure->number_of_channels;
return -1;
}
uint16_t destination_slot = fhss_ws_calculate_destination_slot(neighbor_timing_info, tx_time);
int32_t tx_channel = neighbor_timing_info->uc_timing_info.fixed_channel;
if (neighbor_timing_info->uc_timing_info.unicast_channel_function == WS_TR51CF) {
tx_channel = tr51_get_uc_channel_index(fhss_structure->ws->tr51_channel_table, fhss_structure->ws->tr51_output_table, destination_slot, destination_address, neighbor_timing_info->uc_timing_info.unicast_number_of_channels, NULL);
} else if (neighbor_timing_info->uc_timing_info.unicast_channel_function == WS_DH1CF) {
tx_channel = dh1cf_get_uc_channel_index(destination_slot, destination_address, neighbor_timing_info->uc_timing_info.unicast_number_of_channels);
tx_channel = dh1cf_get_uc_channel_index(destination_slot, destination_address, neighbor_timing_info->uc_channel_list.channel_count);
} else if (neighbor_timing_info->uc_timing_info.unicast_channel_function == WS_VENDOR_DEF_CF) {
if (fhss_structure->ws->fhss_configuration.vendor_defined_cf) {
tx_channel = fhss_structure->ws->fhss_configuration.vendor_defined_cf(fhss_structure->fhss_api, fhss_structure->ws->bc_slot, destination_address, fhss_structure->ws->fhss_configuration.bsi, neighbor_timing_info->uc_timing_info.unicast_number_of_channels);
@ -951,6 +962,7 @@ int fhss_ws_remove_parent(fhss_structure_t *fhss_structure, const uint8_t eui64[
int fhss_ws_configuration_set(fhss_structure_t *fhss_structure, const fhss_ws_configuration_t *fhss_configuration)
{
int channel_count = channel_list_count_channels(fhss_configuration->channel_mask);
int channel_count_uc = channel_list_count_channels(fhss_configuration->unicast_channel_mask);
if (channel_count <= 0) {
return -1;
}
@ -968,17 +980,27 @@ int fhss_ws_configuration_set(fhss_structure_t *fhss_structure, const fhss_ws_co
fhss_structure->ws->unicast_timer_running = true;
}
fhss_structure->ws->fhss_configuration = *fhss_configuration;
if (channel_count_uc == 0) {
//If Unicast channel is empty use Domain mask
for (uint8_t i = 0; i < 8; i++) {
fhss_structure->ws->fhss_configuration.unicast_channel_mask[i] = fhss_configuration->channel_mask[i];
}
channel_count_uc = channel_count;
}
fhss_structure->number_of_channels = channel_count;
fhss_structure->number_of_uc_channels = channel_count_uc;
if (fhss_configuration->ws_uc_channel_function == WS_FIXED_CHANNEL) {
fhss_structure->rx_channel = fhss_configuration->unicast_fixed_channel;
}
platform_exit_critical();
tr_info("fhss Configuration set, UC channel: %d, BC channel: %d, UC CF: %d, BC CF: %d, channels: %d, uc dwell: %d, bc dwell: %d, bc interval: %"PRIu32", bsi:%d",
tr_info("fhss Configuration set, UC channel: %d, BC channel: %d, UC CF: %d, BC CF: %d, channels: BC %d UC %d, uc dwell: %d, bc dwell: %d, bc interval: %"PRIu32", bsi:%d",
fhss_structure->ws->fhss_configuration.unicast_fixed_channel,
fhss_structure->ws->fhss_configuration.broadcast_fixed_channel,
fhss_structure->ws->fhss_configuration.ws_uc_channel_function,
fhss_structure->ws->fhss_configuration.ws_bc_channel_function,
fhss_structure->number_of_channels,
fhss_structure->number_of_uc_channels,
fhss_structure->ws->fhss_configuration.fhss_uc_dwell_interval,
fhss_structure->ws->fhss_configuration.fhss_bc_dwell_interval,
fhss_structure->ws->fhss_configuration.fhss_broadcast_interval,

View File

@ -39,10 +39,14 @@
#include "Common_Protocols/ipv6_flow.h"
#include "Common_Protocols/tcp.h"
#include "Common_Protocols/udp.h"
#include "6LoWPAN/Bootstraps/protocol_6lowpan.h"
#include "common_functions.h"
#define TRACE_GROUP "sckA"
/* Data already written to space provided */
#define GETSOCKOPT_DATA_READY 1
const uint8_t ns_in6addr_any[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int8_t socket_open(uint8_t protocol, uint16_t identifier, void (*passed_fptr)(void *))
@ -1010,12 +1014,35 @@ int8_t socket_setsockopt(int8_t socket, uint8_t level, uint8_t opt_name, const v
}
}
static bool socket_latency_get(const uint8_t dest_addr[static 16], uint32_t *latency)
{
ipv6_route_t *route = ipv6_route_choose_next_hop(dest_addr, -1, NULL);
if (!route) {
return false;
}
return protocol_6lowpan_latency_estimate_get(route->info.interface_id, latency);
}
static bool socket_stagger_value_get(const uint8_t dest_addr[static 16], uint32_t data_amount, uint16_t *stagger_min, uint16_t *stagger_max, uint16_t *stagger_rand)
{
ipv6_route_t *route = ipv6_route_choose_next_hop(dest_addr, -1, NULL);
if (!route) {
// No route found, return 0
return false;
}
return protocol_6lowpan_stagger_estimate_get(route->info.interface_id, data_amount, stagger_min, stagger_max, stagger_rand);
}
static union {
int8_t s8;
uint16_t u16;
int16_t s16;
uint32_t u32;
int32_t s32;
uint64_t u64;
int64_t s64;
bool boolean;
} opt_temp;
@ -1130,7 +1157,41 @@ static int8_t ipv6_getsockopt(const socket_t *socket_ptr, uint8_t opt_name, cons
*value = &opt_temp.boolean;
*len = sizeof(bool);
break;
case SOCKET_LATENCY: {
ns_ipv6_latency_t *ns_ipv6_latency = (ns_ipv6_latency_t *)*value;
if (*len < sizeof(ns_ipv6_latency_t)) {
return -1;
}
if (socket_latency_get(ns_ipv6_latency->dest_addr, &ns_ipv6_latency->latency)) {
*len = sizeof(ns_ipv6_latency_t);
return GETSOCKOPT_DATA_READY;
}
return -3;
/* break; */
}
case SOCKET_STAGGER: {
ns_ipv6_stagger_t *ns_ipv6_stagger = (ns_ipv6_stagger_t *)*value;
uint16_t stagger_min, stagger_max, stagger_rand;
bool retval;
if (*len < sizeof(ns_ipv6_stagger_t)) {
return -1;
}
retval = socket_stagger_value_get(ns_ipv6_stagger->dest_addr,
ns_ipv6_stagger->data_amount,
&stagger_min, &stagger_max, &stagger_rand);
if (retval) {
ns_ipv6_stagger->stagger_min = stagger_min;
ns_ipv6_stagger->stagger_max = stagger_max;
ns_ipv6_stagger->stagger_rand = stagger_rand;
*len = sizeof(ns_ipv6_stagger_t);
return GETSOCKOPT_DATA_READY;
}
return -3;
/* break; */
}
default:
return -2;
}
@ -1145,12 +1206,15 @@ int8_t socket_getsockopt(int8_t socket, uint8_t level, uint8_t opt_name, void *o
return -1;
}
const void *value;
uint16_t len;
const void *value = opt_value;
uint16_t len = *opt_len;
if (level == SOCKET_IPPROTO_IPV6 && socket_is_ipv6(socket_ptr)) {
int8_t ret = ipv6_getsockopt(socket_ptr, opt_name, &value, &len);
if (ret != 0) {
if (ret == GETSOCKOPT_DATA_READY) {
ret = 0;
}
return ret;
}
} else if (level == SOCKET_SOL_SOCKET) {
@ -1198,4 +1262,3 @@ ns_cmsghdr_t *NS_CMSG_NXTHDR(const ns_msghdr_t *msgh, const ns_cmsghdr_t *cmsg)
}
return (ns_cmsghdr_t *) start_of_next_header;
}

View File

@ -40,6 +40,7 @@ SRCS += \
source/6LoWPAN/ws/ws_eapol_relay_lib.c \
source/6LoWPAN/ws/ws_eapol_pdu.c \
source/6LoWPAN/ws/ws_stats.c \
source/6LoWPAN/ws/ws_cfg_settings.c \
source/BorderRouter/border_router.c \
source/Common_Protocols/icmpv6.c \
source/Common_Protocols/icmpv6_prefix.c \