mirror of https://github.com/ARMmbed/mbed-os.git
Merge commit '185db1333ed41be03e3a565e0f0171cad90857a1'
* commit '185db1333ed41be03e3a565e0f0171cad90857a1': Squashed 'features/nanostack/sal-stack-nanostack/' changes from fb7413b846..89a497a386pull/12754/head
commit
6275f710bf
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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*/
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
@ -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_
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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_
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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])
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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_ */
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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 */
|
||||
};
|
||||
|
|
|
@ -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_ */
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 \
|
||||
|
|
Loading…
Reference in New Issue