Merge commit '02021856e4681bd5092e48b8513ff90fb5d6b1e9' into origin/nanostack_release_12_8_0_feature_wisun

* commit '02021856e4681bd5092e48b8513ff90fb5d6b1e9':
  Squashed 'features/nanostack/sal-stack-nanostack/' changes from 35b95da122..3183d87e41
pull/14164/head
Arto Kinnunen 2021-01-18 15:24:13 +02:00
commit 07089272fa
52 changed files with 1330 additions and 434 deletions

File diff suppressed because it is too large Load Diff

View File

@ -132,6 +132,9 @@ typedef struct fhss_ws_configuration {
/** Wi-SUN specific unicast channel mask */
uint32_t unicast_channel_mask[8];
/** Channel mask size */
uint16_t channel_mask_size;
/** Vendor defined channel function. */
fhss_vendor_defined_cf *vendor_defined_cf;

View File

@ -78,7 +78,7 @@ typedef enum {
} mlme_primitive;
/**
* \struct mac_description_storage_size_t
* \struct mac_description_storage_size_s
* \brief Container for MAC storage sizes.
*/
typedef struct mac_description_storage_size_s {
@ -305,7 +305,7 @@ struct mac_api_s {
};
/**
* \struct mac_statistics_t
* \struct mac_statistics_s
* \brief MAC statistics structure.
*/
typedef struct mac_statistics_s {

View File

@ -103,7 +103,7 @@ typedef enum arm_library_event_type_e {
#define SOCKET_BIND_DONE SOCKET_CONNECT_DONE /**< Backward compatibility */
#define SOCKET_BIND_FAIL SOCKET_CONNECT_FAIL /**< Backward compatibility */
#define SOCKET_BIND_AUTH_FAIL SOCKET_CONNECT_AUTH_FAIL /**< Backward compatibility */
/* @} */
/** @} */
/** Network security levels. */
typedef enum net_security_t {
@ -1228,3 +1228,4 @@ extern const cca_threshold_table_s *arm_nwk_get_cca_threshold_table(int8_t inter
}
#endif
#endif /* NET_INTERFACE_H_ */

View File

@ -89,7 +89,7 @@ typedef enum pana_client_nvm_update_process_t {
} pana_client_nvm_update_process_t;
/*!
* \struct wpan_nvm_params_t
* \struct wpan_nvm_params
* \brief Network nvm parameters.
*/
typedef struct wpan_nvm_params {

View File

@ -52,7 +52,7 @@ extern "C" {
#endif
/*!
* \enum net_host_mode_t
* \enum net_host_mode
* \brief Sleepy host states.
*/
typedef enum net_host_mode {

View File

@ -36,7 +36,7 @@ typedef struct ns_mdns *ns_mdns_t; /**< Instance */
typedef struct ns_mdns_service *ns_mdns_service_t; /**< Service instance */
/*!
* \struct ns_mdns_service_param_t
* \struct ns_mdns_service_param
* \brief Structure for mDNS service parameters
*/
typedef struct ns_mdns_service_param {

View File

@ -48,6 +48,7 @@ extern "C" {
#define ARM_AES_MBEDTLS_CONTEXT_MIN 1 /**</ event loop use only */
#endif
/** AES context */
typedef struct arm_aes_context arm_aes_context_t;
/**

View File

@ -196,7 +196,7 @@ typedef struct socket_callback_t {
} socket_callback_t;
/*!
* \struct ns_msghdr_t
* \struct ns_msghdr
* \brief Normal IP socket message structure for socket_recvmsg() and socket_sendmsg().
*/
@ -211,7 +211,7 @@ typedef struct ns_msghdr {
} ns_msghdr_t;
/*!
* \struct ns_cmsghdr_t
* \struct ns_cmsghdr
* \brief Control messages.
*/
typedef struct ns_cmsghdr {
@ -242,7 +242,7 @@ typedef struct ns_cmsghdr {
#define NS_MSG_LEGACY0 0x4000
///@}
/*!
* \struct ns_in6_pktinfo_t
* \struct ns_in6_pktinfo
* \brief IPv6 packet info which is used for socket_recvmsg() socket_sendmsg().
*/
typedef struct ns_in6_pktinfo {

View File

@ -16,7 +16,7 @@
*/
/**
* \file ws_management_if.h
* \file ws_management_api.h
* \brief Wi-SUN management interface.
*
* This interface is used for configuring Wi-SUN devices.
@ -37,61 +37,63 @@ extern "C" {
#endif
/* Regulatory domain values*/
#define REG_DOMAIN_WW 0x00 // World wide
#define REG_DOMAIN_NA 0x01 // North America
#define REG_DOMAIN_JP 0x02 // Japan
#define REG_DOMAIN_EU 0x03 // European Union
#define REG_DOMAIN_CH 0x04 // China
#define REG_DOMAIN_IN 0x05 // India
#define REG_DOMAIN_MX 0x06 //
#define REG_DOMAIN_BZ 0x07 // Brazil
#define REG_DOMAIN_AZ 0x08 // Australia
#define REG_DOMAIN_NZ 0x08 // New zealand
#define REG_DOMAIN_KR 0x09 // Korea
#define REG_DOMAIN_PH 0x0A //
#define REG_DOMAIN_MY 0x0B //
#define REG_DOMAIN_HK 0x0C //
#define REG_DOMAIN_SG 0x0D // band 866-869
#define REG_DOMAIN_TH 0x0E //
#define REG_DOMAIN_VN 0x0F //
#define REG_DOMAIN_SG_H 0x10 // band 920-925
#define REG_DOMAIN_WW 0x00 /**< World wide */
#define REG_DOMAIN_NA 0x01 /**< North America */
#define REG_DOMAIN_JP 0x02 /**< Japan */
#define REG_DOMAIN_EU 0x03 /**< European Union */
#define REG_DOMAIN_CH 0x04 /**< China */
#define REG_DOMAIN_IN 0x05 /**< India */
#define REG_DOMAIN_MX 0x06 /**< Mexico */
#define REG_DOMAIN_BZ 0x07 /**< Brazil */
#define REG_DOMAIN_AZ 0x08 /**< Australia */
#define REG_DOMAIN_NZ 0x08 /**< New zealand */
#define REG_DOMAIN_KR 0x09 /**< Korea */
#define REG_DOMAIN_PH 0x0A /**< Philippines */
#define REG_DOMAIN_MY 0x0B /**< Malaysia */
#define REG_DOMAIN_HK 0x0C /**< Hong Kong */
#define REG_DOMAIN_SG 0x0D /**< Singapore band 866-869 */
#define REG_DOMAIN_TH 0x0E /**< Thailand */
#define REG_DOMAIN_VN 0x0F /**< Vietnam */
#define REG_DOMAIN_SG_H 0x10 /**< Singapore band 920-925 */
#define OPERATING_MODE_1a 0x1a
#define OPERATING_MODE_1b 0x1b
#define OPERATING_MODE_2a 0x2a
#define OPERATING_MODE_2b 0x2b
#define OPERATING_MODE_3 0x03
#define OPERATING_MODE_4a 0x4a
#define OPERATING_MODE_4b 0x4b
#define OPERATING_MODE_5 0x05
#define OPERATING_MODE_1a 0x1a /**< 50, 0,5 */
#define OPERATING_MODE_1b 0x1b /**< 50, 1.0 */
#define OPERATING_MODE_2a 0x2a /**< 100, 0,5 */
#define OPERATING_MODE_2b 0x2b /**< 100, 1.0 */
#define OPERATING_MODE_3 0x03 /**< 150, 0.5 */
#define OPERATING_MODE_4a 0x4a /**< 200, 0.5 */
#define OPERATING_MODE_4b 0x4b /**< 200, 1.0 */
#define OPERATING_MODE_5 0x05 /**< 300, 0.5 */
#define CHANNEL_FUNCTION_FIXED 0x00 // Fixed channel
#define CHANNEL_FUNCTION_TR51CF 0x01 // TR51CF
#define CHANNEL_FUNCTION_DH1CF 0x02 // Direct Hash
#define CHANNEL_FUNCTION_VENDOR_DEFINED 0x03 // vendor given channel hop schedule
#define CHANNEL_FUNCTION_FIXED 0x00 /**< Fixed channel */
#define CHANNEL_FUNCTION_TR51CF 0x01 /**< TR51CF */
#define CHANNEL_FUNCTION_DH1CF 0x02 /**< Direct Hash */
#define CHANNEL_FUNCTION_VENDOR_DEFINED 0x03 /**< vendor given channel hop schedule */
#define CHANNEL_SPACING_200 0x00 // 200 khz
#define CHANNEL_SPACING_400 0x01 // 400 khz
#define CHANNEL_SPACING_600 0x02 // 600 khz
#define CHANNEL_SPACING_100 0x03 // 100 khz
#define CHANNEL_SPACING_250 0x04 // 250 khz
#define CHANNEL_SPACING_200 0x00 /**< 200 khz */
#define CHANNEL_SPACING_400 0x01 /**< 400 khz */
#define CHANNEL_SPACING_600 0x02 /**< 600 khz */
#define CHANNEL_SPACING_100 0x03 /**< 100 khz */
#define CHANNEL_SPACING_250 0x04 /**< 250 khz */
#define CHANNEL_SPACING_800 0x05 /**< 800 khz */
#define CHANNEL_SPACING_1200 0x06 /**< 1200 khz */
/*
* Network Size definitions are device amount in hundreds of devices.
* These definitions are meant to give some estimates of sizes. Any value can be given as parameter
*/
#define NETWORK_SIZE_CERTIFICATE 0x00 // Network configuration used in Wi-SUN certification
#define NETWORK_SIZE_SMALL 0x01 // Small networks
#define NETWORK_SIZE_MEDIUM 0x08 // 100 - 800 device networks are medium sized
#define NETWORK_SIZE_LARGE 0x0F // 800 - 1500 device networks are large
#define NETWORK_SIZE_XLARGE 0x19 // 2500+ devices
#define NETWORK_SIZE_AUTOMATIC 0xFF
#define NETWORK_SIZE_CERTIFICATE 0x00 /**< Network configuration used in Wi-SUN certification */
#define NETWORK_SIZE_SMALL 0x01 /**< Small networks */
#define NETWORK_SIZE_MEDIUM 0x08 /**< 100 - 800 device networks are medium sized */
#define NETWORK_SIZE_LARGE 0x0F /**< 800 - 1500 device networks are large */
#define NETWORK_SIZE_XLARGE 0x19 /**< 2500+ devices */
#define NETWORK_SIZE_AUTOMATIC 0xFF /**< Automatic network size */
/** Temporary API change flag. this will be removed when new version of API is implemented on applications
*
*/
#define WS_MANAGEMENT_API_VER_2
#define WS_MANAGEMENT_API_VER_2 /**< Management API version */
/**
* \brief Struct ws_statistics defines the Wi-SUN statistics storage structure.
@ -184,6 +186,83 @@ int ws_management_network_name_validate(
int8_t interface_id,
char *network_name_ptr);
/**
* Configure PHY mode ID of Wi-SUN stack as defined by Wi-SUN FAN 1.1.
*
* Change the default configuration for Wi-SUN PHY operation.
*
* Supported values:
* FSK without FEC:
* PHY mode ID | Symbol Rate (kbps) | Modulation Index
* 1 50 0.5
* 2 50 1.0
* 3 100 0.5
* 4 100 1.0
* 5 150 0.5
* 6 200 0.5
* 7 200 1.0
* 8 300 0.5
*
* FSK with FEC:
* PHY mode ID | Symbol Rate (kbps) | Modulation Index
* 17 50 0.5
* 18 50 1.0
* 19 100 0.5
* 20 100 1.0
* 21 150 0.5
* 22 200 0.5
* 23 200 1.0
* 24 300 0.5
*
* OFDM:
* PHY mode ID | Option | MCS | Data rate (kbps)
* 34 1 2 400
* 35 1 3 800
* 36 1 4 1200
* 37 1 5 1600
* 38 1 6 2400
* 51 2 3 400
* 52 2 4 600
* 53 2 5 800
* 54 2 6 1200
* 68 3 4 300
* 69 3 5 400
* 70 3 6 600
* 84 4 4 150
* 85 4 5 200
* 86 4 6 300
*
* if value of 255 is given then previous value is used.
*
* \param interface_id Network interface ID.
* \param phy_mode_id PHY mode ID. Default 255 (not used).
*
* \return 0, Init OK.
* \return <0 Init fail.
*/
int ws_management_phy_mode_id_set(
int8_t interface_id,
uint8_t phy_mode_id);
/**
* Configure Channel plan ID of Wi-SUN stack as defined by Wi-SUN FAN 1.1.
*
* Change the default channel configuration for Wi-SUN.
*
* Supported values: TBD
*
* if value of 255 is given then previous value is used.
*
* \param interface_id Network interface ID.
* \param channel_plan_id Channel plan ID. Default 255 (not used).
*
* \return 0, Init OK.
* \return <0 Init fail.
*/
int ws_management_channel_plan_id_set(
int8_t interface_id,
uint8_t channel_plan_id);
/**
* Configure regulatory domain of Wi-SUN stack.
*

View File

@ -110,6 +110,15 @@ typedef struct {
#define LOWPAN_ACTIVE_UNICAST_ONGOING_MAX 10
/* Minimum buffer amount and memory size to ensure operation even in out of memory situation
*/
#define LOWPAN_MEM_LIMIT_MIN_QUEUE 10
#define LOWPAN_MEM_LIMIT_MIN_MEMORY 10000
#define LOWPAN_MEM_LIMIT_REMOVE_NORMAL 3000 // Remove when approaching memory limit
#define LOWPAN_MEM_LIMIT_REMOVE_MAX 10000 // Remove when at memory limit
static NS_LIST_DEFINE(fragmenter_interface_list, fragmenter_interface_t, link);
/* Adaptation interface local functions */
@ -493,6 +502,63 @@ int8_t lowpan_adaptation_interface_mpx_register(int8_t interface_id, struct mpx_
return 0;
}
void lowpan_adaptation_free_heap(bool full_gc)
{
ns_list_foreach(fragmenter_interface_t, interface_ptr, &fragmenter_interface_list) {
// Go through all interfaces and free small amount of memory
// This is not very radical, but gives time to recover wthout causing too harsh changes
lowpan_adaptation_free_low_priority_packets(interface_ptr->interface_id, full_gc ? LOWPAN_MEM_LIMIT_REMOVE_MAX : LOWPAN_MEM_LIMIT_REMOVE_NORMAL);
}
}
int8_t lowpan_adaptation_free_low_priority_packets(int8_t interface_id, uint32_t requested_amount)
{
fragmenter_interface_t *interface_ptr = lowpan_adaptation_interface_discover(interface_id);
if (!interface_ptr) {
return -1;
}
uint32_t adaptation_memory = 0;
uint16_t adaptation_packets = 0;
uint32_t memory_freed = 0;
uint16_t packets_freed = 0;
ns_list_foreach(buffer_t, entry, &interface_ptr->directTxQueue) {
adaptation_memory += sizeof(buffer_t) + entry->size;
adaptation_packets++;
}
if (interface_ptr->directTxQueue_size < LOWPAN_MEM_LIMIT_MIN_QUEUE) {
// Minimum reserved for operations
return 0;
}
if (adaptation_memory < LOWPAN_MEM_LIMIT_MIN_MEMORY) {
// Minimum reserved for operations
return 0;
}
if (adaptation_memory - requested_amount < LOWPAN_MEM_LIMIT_MIN_MEMORY) {
// only reduse to minimum
requested_amount = adaptation_memory - LOWPAN_MEM_LIMIT_MIN_MEMORY;
}
//Only remove last entries from TX queue with low priority
ns_list_foreach_reverse_safe(buffer_t, entry, &interface_ptr->directTxQueue) {
if (entry->priority == QOS_NORMAL) {
memory_freed += sizeof(buffer_t) + entry->size;
packets_freed++;
ns_list_remove(&interface_ptr->directTxQueue, entry);
interface_ptr->directTxQueue_size--;
lowpan_adaptation_tx_queue_level_update(interface_ptr);
socket_tx_buffer_event_and_free(entry, SOCKET_TX_FAIL);
}
if (memory_freed > requested_amount) {
// Enough memory freed
break;
}
}
tr_info("Adaptation Free low priority packets memory: %" PRIi32 " queue: %d deallocated %" PRIi32 " bytes, %d packets, %" PRIi32 " requested", adaptation_memory, adaptation_packets, memory_freed, packets_freed, requested_amount);
return 0;
}
static fragmenter_tx_entry_t *lowpan_indirect_entry_allocate(uint16_t fragment_buffer_size)
{
@ -1562,7 +1628,6 @@ int8_t lowpan_adaptation_free_messages_from_queues_by_address(struct protocol_in
return 0;
}
int8_t lowpan_adaptation_indirect_queue_params_set(struct protocol_interface_info_entry *cur, uint16_t indirect_big_packet_threshold, uint16_t max_indirect_big_packets_total, uint16_t max_indirect_small_packets_per_child)
{
fragmenter_interface_t *interface_ptr = lowpan_adaptation_interface_discover(cur->id);

View File

@ -36,8 +36,13 @@ int8_t lowpan_adaptation_interface_reset(int8_t interface_id);
int8_t lowpan_adaptation_interface_mpx_register(int8_t interface_id, struct mpx_api_s *mpx_api, uint16_t mpx_user_id);
void lowpan_adaptation_free_heap(bool full_gc);
int8_t lowpan_adaptation_free_low_priority_packets(int8_t interface_id, uint32_t requested_amount);
/**
* \brief call this before normatl TX. This function prepare buffer link spesific metadata and verify packet destination
* \brief call this before normal TX. This function prepare buffer link specific metadata and verify packet destination
*/
struct buffer *lowpan_adaptation_data_process_tx_preprocess(struct protocol_interface_info_entry *cur, struct buffer *buf);

View File

@ -176,12 +176,12 @@ static void ws_bbr_rpl_version_timer_start(protocol_interface_info_entry_t *cur,
//stable version for RPL so slow timer update is ok
cur->ws_info->rpl_version_timer = RPL_VERSION_LIFETIME;
} else {
if (cur->ws_info->cfg->gen.network_size <= NETWORK_SIZE_SMALL) {
// handles also NETWORK_SIZE_CERTIFICATE
if (ws_cfg_network_config_get(cur) <= CONFIG_SMALL) {
// Also handles CONFIG_CERTIFICATE
cur->ws_info->rpl_version_timer = RPL_VERSION_LIFETIME_RESTART_SMALL;
} else if (cur->ws_info->cfg->gen.network_size <= NETWORK_SIZE_MEDIUM) {
} else if (ws_cfg_network_config_get(cur) <= CONFIG_MEDIUM) {
cur->ws_info->rpl_version_timer = RPL_VERSION_LIFETIME_RESTART_MEDIUM;
} else if (cur->ws_info->cfg->gen.network_size <= NETWORK_SIZE_LARGE) {
} else if (ws_cfg_network_config_get(cur) <= CONFIG_LARGE) {
cur->ws_info->rpl_version_timer = RPL_VERSION_LIFETIME_RESTART_LARGE;
} else {
cur->ws_info->rpl_version_timer = RPL_VERSION_LIFETIME_RESTART_EXTRA_LARGE;

View File

@ -116,6 +116,9 @@ static parent_info_t *ws_bootstrap_candidate_parent_get(struct protocol_interfac
static void ws_bootstrap_candidate_parent_sort(struct protocol_interface_info_entry *cur, parent_info_t *new_entry);
static void ws_bootstrap_packet_congestion_init(protocol_interface_info_entry_t *cur);
static void ws_bootstrap_asynch_trickle_stop(protocol_interface_info_entry_t *cur);
static void ws_bootstrap_advertise_start(protocol_interface_info_entry_t *cur);
typedef enum {
WS_PARENT_SOFT_SYNCH = 0, /**< let FHSS make decision if synchronization is needed*/
WS_PARENT_HARD_SYNCH, /**< Synch FHSS with latest synch information*/
@ -624,8 +627,9 @@ static uint8_t ws_generate_exluded_channel_list_from_active_channels(ws_excluded
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, cur->ws_info->hopping_schdule.operating_class);
ws_generate_channel_list(fhss_configuration->unicast_channel_mask, cur->ws_info->hopping_schdule.number_of_channels, cur->ws_info->hopping_schdule.regulatory_domain, cur->ws_info->hopping_schdule.operating_class);
fhss_configuration->channel_mask_size = cur->ws_info->hopping_schdule.number_of_channels;
ws_generate_channel_list(fhss_configuration->channel_mask, cur->ws_info->hopping_schdule.number_of_channels, cur->ws_info->hopping_schdule.regulatory_domain, cur->ws_info->hopping_schdule.operating_class, cur->ws_info->hopping_schdule.channel_plan_id);
ws_generate_channel_list(fhss_configuration->unicast_channel_mask, cur->ws_info->hopping_schdule.number_of_channels, cur->ws_info->hopping_schdule.regulatory_domain, cur->ws_info->hopping_schdule.operating_class, cur->ws_info->hopping_schdule.channel_plan_id);
// 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];
@ -1550,10 +1554,10 @@ static void ws_bootstrap_pan_advertisement_solicit_analyse(struct protocol_inter
*/
trickle_consistent_heard(&cur->ws_info->trickle_pan_advertisement_solicit);
/*
* Optimized PAN discovery to select faster the parent if we hear solicit from someone else
* Optimized PAN discovery to select the parent faster if we hear solicit from someone else
*/
if (ws_bootstrap_state_discovery(cur) && cur->ws_info->cfg->gen.network_size <= NETWORK_SIZE_MEDIUM &&
if (ws_bootstrap_state_discovery(cur) && ws_cfg_network_config_get(cur) <= CONFIG_MEDIUM &&
cur->bootsrap_state_machine_cnt > cur->ws_info->trickle_params_pan_discovery.Imin * 2) {
cur->bootsrap_state_machine_cnt = cur->ws_info->trickle_params_pan_discovery.Imin + randLIB_get_random_in_range(0, cur->ws_info->trickle_params_pan_discovery.Imin);
@ -2044,7 +2048,7 @@ static void ws_neighbor_entry_remove_notify(mac_neighbor_table_entry_t *entry_pt
static uint32_t ws_probe_init_time_get(protocol_interface_info_entry_t *cur)
{
if (cur->ws_info->cfg->gen.network_size <= NETWORK_SIZE_SMALL) {
if (ws_cfg_network_config_get(cur) <= CONFIG_SMALL) {
return WS_SMALL_PROBE_INIT_BASE_SECONDS;
}
@ -2397,11 +2401,29 @@ static int ws_bootstrap_set_domain_rf_config(protocol_interface_info_entry_t *cu
{
phy_rf_channel_configuration_s rf_configs;
memset(&rf_configs, 0, sizeof(phy_rf_channel_configuration_s));
rf_configs.channel_0_center_frequency = (uint32_t)cur->ws_info->hopping_schdule.ch0_freq * 100000;
rf_configs.channel_spacing = ws_decode_channel_spacing(cur->ws_info->hopping_schdule.channel_spacing);
uint8_t phy_mode_id = cur->ws_info->hopping_schdule.phy_mode_id;
if (((phy_mode_id >= 34) && (phy_mode_id <= 38)) ||
((phy_mode_id >= 51) && (phy_mode_id <= 54)) ||
((phy_mode_id >= 68) && (phy_mode_id <= 70)) ||
((phy_mode_id >= 84) && (phy_mode_id <= 86))) {
rf_configs.modulation = M_OFDM;
rf_configs.datarate = ws_get_datarate_using_phy_mode_id(cur->ws_info->hopping_schdule.phy_mode_id);
rf_configs.ofdm_option = ws_get_ofdm_option_using_phy_mode_id(cur->ws_info->hopping_schdule.phy_mode_id);
rf_configs.ofdm_mcs = ws_get_ofdm_mcs_using_phy_mode_id(cur->ws_info->hopping_schdule.phy_mode_id);
} else {
if ((phy_mode_id >= 17) && (phy_mode_id <= 24)) {
rf_configs.fec = true;
} else {
rf_configs.fec = false;
}
rf_configs.modulation = M_2FSK;
rf_configs.datarate = ws_get_datarate_using_operating_mode(cur->ws_info->hopping_schdule.operating_mode);
rf_configs.modulation_index = ws_get_modulation_index_using_operating_mode(cur->ws_info->hopping_schdule.operating_mode);
rf_configs.modulation = M_2FSK;
}
rf_configs.channel_0_center_frequency = (uint32_t)cur->ws_info->hopping_schdule.ch0_freq * 100000;
rf_configs.channel_spacing = ws_decode_channel_spacing(cur->ws_info->hopping_schdule.channel_spacing);
rf_configs.number_of_channels = cur->ws_info->hopping_schdule.number_of_channels;
ws_bootstrap_set_rf_config(cur, rf_configs);
return 0;
@ -2560,6 +2582,12 @@ static void ws_bootstrap_rpl_callback(rpl_event_t event, void *handle)
// After successful DAO ACK connection to border router is verified
cur->ws_info->pan_timeout_timer = cur->ws_info->cfg->timing.pan_timeout;
}
if (!cur->ws_info->trickle_pa_running || !cur->ws_info->trickle_pc_running) {
//Enable wi-sun asynch adverisment
ws_bootstrap_advertise_start(cur);
}
ws_set_fhss_hop(cur);
@ -2576,6 +2604,8 @@ static void ws_bootstrap_rpl_callback(rpl_event_t event, void *handle)
} else if (event == RPL_EVENT_LOCAL_REPAIR_START) {
tr_debug("RPL local repair start");
//Disable Asynchs
ws_bootstrap_asynch_trickle_stop(cur);
ws_nwk_event_post(cur, ARM_NWK_NWK_CONNECTION_DOWN);
} else if (event == RPL_EVENT_DAO_PARENT_ADD) {
@ -3066,8 +3096,8 @@ static void ws_bootstrap_rpl_scan_start(protocol_interface_info_entry_t *cur)
tr_debug("Start RPL learn");
// 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->cfg->gen.network_size > NETWORK_SIZE_SMALL) {
//For Large network and medium should do passive scan
if (ws_cfg_network_config_get(cur) > CONFIG_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);
}
@ -3115,7 +3145,7 @@ static void ws_set_asynch_channel_list(protocol_interface_info_entry_t *cur, asy
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, cur->ws_info->hopping_schdule.operating_class);
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, cur->ws_info->hopping_schdule.operating_class, cur->ws_info->hopping_schdule.channel_plan_id);
}
async_req->channel_list.channel_page = CHANNEL_PAGE_10;

View File

@ -79,6 +79,32 @@ typedef union {
ws_sec_prot_cfg_t sec_prot;
} ws_cfgs_t;
typedef struct cfg_devices_in_config {
uint8_t max_for_small;
uint8_t max_for_medium;
uint8_t max_for_large;
uint8_t max_for_xlarge;
} cfg_devices_in_config_t;
/* Table for amount of devices that certain configuration should be used
*
* larger data rates allow more devices to be used with faster settings.
*
* For example with network the size of 2000 devices we use
* Xlrage configuration with 50kbs data rate.
* Large configuration with 300kbs data rate.
* and with 600kbs data rate it is possible to use medium network settings.
*
*/
const cfg_devices_in_config_t devices_by_datarate[] = {
{ 1, 4, 10, 25}, // Configuration for 50 -100kbs
{ 1, 8, 15, 25}, // Configuration for 150kbs - 200kbs
{ 2, 15, 25, 50}, // Configuration for 300kbs
{ 3, 20, 40, 100}, // Configuration for 600kbs - 2400kbs
};
static int8_t ws_cfg_to_get(ws_cfgs_t **cfg, ws_cfgs_t *new_cfg, ws_cfg_validate valid_cb, ws_cfgs_t *external_cfg, uint8_t *cfg_flags, uint8_t *flags);
static void ws_cfg_network_size_config_set_small(ws_cfg_nw_size_t *cfg);
@ -258,13 +284,13 @@ int8_t ws_cfg_network_size_set(protocol_interface_info_entry_t *cur, ws_gen_cfg_
ws_cfg_network_size_config_set_size set_function = NULL;
if (cfg->network_size == NETWORK_SIZE_CERTIFICATE) {
if (ws_cfg_network_config_get(cur) == CONFIG_CERTIFICATE) {
set_function = ws_cfg_network_size_config_set_certificate;
} else if (cfg->network_size <= NETWORK_SIZE_SMALL || cfg->network_size == NETWORK_SIZE_AUTOMATIC) {
} else if (ws_cfg_network_config_get(cur) == CONFIG_SMALL || cfg->network_size == NETWORK_SIZE_AUTOMATIC) {
set_function = ws_cfg_network_size_config_set_small;
} else if (cfg->network_size <= NETWORK_SIZE_MEDIUM) {
} else if (ws_cfg_network_config_get(cur) == CONFIG_MEDIUM) {
set_function = ws_cfg_network_size_config_set_medium;
} else if (cfg->network_size <= NETWORK_SIZE_LARGE) {
} else if (ws_cfg_network_config_get(cur) == CONFIG_LARGE) {
set_function = ws_cfg_network_size_config_set_large;
} else {
set_function = ws_cfg_network_size_config_set_xlarge;
@ -360,6 +386,47 @@ int8_t ws_cfg_network_size_configure(protocol_interface_info_entry_t *cur, uint1
return CFG_SETTINGS_OK;
}
cfg_network_size_type_e ws_cfg_network_config_get(protocol_interface_info_entry_t *cur)
{
// Get size of the network Amount of devices in the network
// Get the data rate of the network
// Adjust the configuration type based on the network size and data rate
(void)cur;
ws_gen_cfg_t cfg;
if (ws_cfg_gen_get(&cfg, NULL) < 0) {
return CONFIG_SMALL;
}
ws_phy_cfg_t phy_cfg;
if (ws_cfg_phy_get(&phy_cfg, NULL) < 0) {
return CONFIG_SMALL;
}
uint32_t data_rate = ws_get_datarate_using_operating_mode(phy_cfg.operating_mode);
uint8_t index;
if (data_rate < 150000) {
index = 0;
} else if (data_rate < 300000) {
index = 1;
} else if (data_rate < 600000) {
index = 2;
} else {
index = 3;
}
if (cfg.network_size == NETWORK_SIZE_CERTIFICATE) {
return CONFIG_CERTIFICATE;
} else if (cfg.network_size <= devices_by_datarate[index].max_for_small) {
return CONFIG_SMALL;
} else if (cfg.network_size <= devices_by_datarate[index].max_for_medium) {
return CONFIG_MEDIUM;
} else if (cfg.network_size <= devices_by_datarate[index].max_for_large) {
return CONFIG_LARGE;
}
return CONFIG_XLARGE;
}
static void ws_cfg_network_size_config_set_small(ws_cfg_nw_size_t *cfg)
{
@ -651,6 +718,8 @@ int8_t ws_cfg_phy_default_set(ws_phy_cfg_t *cfg)
cfg->regulatory_domain = REG_DOMAIN_EU;
cfg->operating_mode = OPERATING_MODE_3;
cfg->operating_class = 2;
cfg->phy_mode_id = 255;
cfg->channel_plan_id = 255;
return CFG_SETTINGS_OK;
}
@ -671,12 +740,16 @@ int8_t ws_cfg_phy_validate(ws_phy_cfg_t *cfg, ws_phy_cfg_t *new_cfg)
// Regulator domain, operating mode or class has changed
if (cfg->regulatory_domain != new_cfg->regulatory_domain ||
cfg->operating_mode != new_cfg->operating_mode ||
cfg->operating_class != new_cfg->operating_class) {
cfg->operating_class != new_cfg->operating_class ||
cfg->phy_mode_id != new_cfg->phy_mode_id ||
cfg->channel_plan_id != new_cfg->channel_plan_id) {
ws_hopping_schedule_t hopping_schdule = {
.regulatory_domain = new_cfg->regulatory_domain,
.operating_mode = new_cfg->operating_mode,
.operating_class = new_cfg->operating_class
.operating_class = new_cfg->operating_class,
.phy_mode_id = new_cfg->phy_mode_id,
.channel_plan_id = new_cfg->channel_plan_id
};
// Check that new settings are valid
@ -698,11 +771,31 @@ int8_t ws_cfg_phy_set(protocol_interface_info_entry_t *cur, ws_phy_cfg_t *cfg, w
if (ret != CFG_SETTINGS_CHANGED) {
return ret;
}
// Check settings and configure interface
if (cur && !(cfg_flags & CFG_FLAGS_DISABLE_VAL_SET)) {
cur->ws_info->hopping_schdule.regulatory_domain = new_cfg->regulatory_domain;
// Set operating mode for FSK if given with PHY mode ID
if ((new_cfg->phy_mode_id == 1) || (new_cfg->phy_mode_id == 17)) {
cur->ws_info->hopping_schdule.operating_mode = OPERATING_MODE_1a;
} else if ((new_cfg->phy_mode_id == 2) || (new_cfg->phy_mode_id == 18)) {
cur->ws_info->hopping_schdule.operating_mode = OPERATING_MODE_1b;
} else if ((new_cfg->phy_mode_id == 3) || (new_cfg->phy_mode_id == 19)) {
cur->ws_info->hopping_schdule.operating_mode = OPERATING_MODE_2a;
} else if ((new_cfg->phy_mode_id == 4) || (new_cfg->phy_mode_id == 20)) {
cur->ws_info->hopping_schdule.operating_mode = OPERATING_MODE_2b;
} else if ((new_cfg->phy_mode_id == 5) || (new_cfg->phy_mode_id == 21)) {
cur->ws_info->hopping_schdule.operating_mode = OPERATING_MODE_3;
} else if ((new_cfg->phy_mode_id == 6) || (new_cfg->phy_mode_id == 22)) {
cur->ws_info->hopping_schdule.operating_mode = OPERATING_MODE_4a;
} else if ((new_cfg->phy_mode_id == 7) || (new_cfg->phy_mode_id == 23)) {
cur->ws_info->hopping_schdule.operating_mode = OPERATING_MODE_4b;
} else if ((new_cfg->phy_mode_id == 8) || (new_cfg->phy_mode_id == 24)) {
cur->ws_info->hopping_schdule.operating_mode = OPERATING_MODE_5;
} else {
cur->ws_info->hopping_schdule.operating_mode = new_cfg->operating_mode;
}
cur->ws_info->hopping_schdule.phy_mode_id = new_cfg->phy_mode_id;
cur->ws_info->hopping_schdule.channel_plan_id = new_cfg->channel_plan_id;
cur->ws_info->hopping_schdule.regulatory_domain = new_cfg->regulatory_domain;
cur->ws_info->hopping_schdule.operating_class = new_cfg->operating_class;
if (ws_common_regulatory_domain_config(cur, &cur->ws_info->hopping_schdule) < 0) {

View File

@ -38,6 +38,8 @@ 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 */
uint8_t phy_mode_id; /**< PHY mode ID; default 255 (not used) */
uint8_t channel_plan_id; /**< Channel plan ID; default 255 (not used) */
} ws_phy_cfg_t;
/**
@ -146,11 +148,23 @@ typedef struct ws_cfg_s {
#define CFG_SETTINGS_ERROR_SEC_TIMER_CONF -17 /**< Security timers configuration error */
#define CFG_SETTINGS_ERROR_SEC_PROT_CONF -18 /**< Security protocols configuration error */
/** Network configuration parameters sets for different network sizes*/
typedef enum {
CONFIG_CERTIFICATE = 0, ///< Configuration used in Wi-SUN Certification
CONFIG_SMALL = 1, ///< Small networks that can utilize fast recovery
CONFIG_MEDIUM = 2, ///< Medium networks that can form quickly but require balance on load
CONFIG_LARGE = 3, ///< Large networks that needs to throttle joining and maintenance
CONFIG_XLARGE = 4 ///< Xlarge networks with very slow joining, maintenance and recovery profile
} cfg_network_size_type_e;
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);
cfg_network_size_type_e ws_cfg_network_config_get(protocol_interface_info_entry_t *cur);
int8_t ws_cfg_network_size_get(ws_gen_cfg_t *cfg, uint8_t *flags);
int8_t ws_cfg_network_size_validate(ws_gen_cfg_t *cfg, ws_gen_cfg_t *new_cfg);
int8_t ws_cfg_network_size_set(protocol_interface_info_entry_t *cur, ws_gen_cfg_t *cfg, ws_gen_cfg_t *new_cfg, uint8_t *flags);

View File

@ -53,34 +53,58 @@ uint8_t DEVICE_MIN_SENS = 174 - 93;
uint16_t test_max_child_count_override = 0xffff;
int8_t ws_generate_channel_list(uint32_t *channel_mask, uint16_t number_of_channels, uint8_t regulatory_domain, uint8_t operating_class)
static int8_t ws_disable_channels_in_range(uint32_t *channel_mask, uint16_t number_of_channels, uint16_t range_start, uint16_t range_stop)
{
uint32_t excluded_start_channel = 0xFFFFFFFF;
uint32_t excluded_end_channel = 0xFFFFFFFF;
if (regulatory_domain == REG_DOMAIN_BZ) {
if (operating_class == 1) {
excluded_start_channel = 26;
excluded_end_channel = 64;
} else if (operating_class == 2) {
excluded_start_channel = 12;
excluded_end_channel = 32;
} else if (operating_class == 3) {
excluded_start_channel = 7;
excluded_end_channel = 21;
for (uint16_t i = 0; i < number_of_channels; i++) {
if (i >= range_start && i <= range_stop) {
channel_mask[0 + (i / 32)] &= ~(1 << (i % 32));
}
}
return 0;
}
int8_t ws_generate_channel_list(uint32_t *channel_mask, uint16_t number_of_channels, uint8_t regulatory_domain, uint8_t operating_class, uint8_t channel_plan_id)
{
// Clear channel mask
for (uint8_t i = 0; i < 8; i++) {
channel_mask[i] = 0;
}
// Set channel maks outside excluded channels
// Enable all channels
for (uint16_t i = 0; i < number_of_channels; i++) {
if (i < excluded_start_channel || i > excluded_end_channel) {
channel_mask[0 + (i / 32)] |= (1 << (i % 32));
}
// Disable unsupported channels per regional frequency bands
if (regulatory_domain == REG_DOMAIN_NA) {
if (channel_plan_id == 1) {
ws_disable_channels_in_range(channel_mask, number_of_channels, 1, 7);
} else if (channel_plan_id == 5) {
ws_disable_channels_in_range(channel_mask, number_of_channels, 5, 7);
}
}
if (regulatory_domain == REG_DOMAIN_BZ) {
if (channel_plan_id == 255) {
if (operating_class == 1) {
ws_disable_channels_in_range(channel_mask, number_of_channels, 26, 64);
} else if (operating_class == 2) {
ws_disable_channels_in_range(channel_mask, number_of_channels, 12, 32);
} else if (operating_class == 3) {
ws_disable_channels_in_range(channel_mask, number_of_channels, 7, 21);
}
} else {
if (channel_plan_id == 1) {
ws_disable_channels_in_range(channel_mask, number_of_channels, 1, 7);
ws_disable_channels_in_range(channel_mask, number_of_channels, 64, 64);
ws_disable_channels_in_range(channel_mask, number_of_channels, 72, 103);
ws_disable_channels_in_range(channel_mask, number_of_channels, 106, 111);
} else if (channel_plan_id == 2) {
ws_disable_channels_in_range(channel_mask, number_of_channels, 24, 24);
ws_disable_channels_in_range(channel_mask, number_of_channels, 32, 47);
ws_disable_channels_in_range(channel_mask, number_of_channels, 52, 55);
} else if (channel_plan_id == 5) {
ws_disable_channels_in_range(channel_mask, number_of_channels, 5, 10);
ws_disable_channels_in_range(channel_mask, number_of_channels, 19, 23);
}
}
}
return 0;
}
@ -109,6 +133,10 @@ uint32_t ws_decode_channel_spacing(uint8_t channel_spacing)
return 400000;
} else if (CHANNEL_SPACING_600 == channel_spacing) {
return 600000;
} else if (CHANNEL_SPACING_800 == channel_spacing) {
return 800000;
} else if (CHANNEL_SPACING_1200 == channel_spacing) {
return 1200000;
}
return 0;
}
@ -129,6 +157,60 @@ uint32_t ws_get_datarate_using_operating_mode(uint8_t operating_mode)
return 0;
}
uint32_t ws_get_datarate_using_phy_mode_id(uint8_t phy_mode_id)
{
if (84 == phy_mode_id) {
return 150000;
} else if (85 == phy_mode_id) {
return 200000;
} else if ((68 == phy_mode_id) || (86 == phy_mode_id)) {
return 300000;
} else if ((34 == phy_mode_id) || (51 == phy_mode_id) || (69 == phy_mode_id)) {
return 400000;
} else if ((52 == phy_mode_id) || (70 == phy_mode_id)) {
return 600000;
} else if ((35 == phy_mode_id) || (53 == phy_mode_id)) {
return 800000;
} else if ((36 == phy_mode_id) || (54 == phy_mode_id)) {
return 1200000;
} else if (37 == phy_mode_id) {
return 1600000;
} else if (38 == phy_mode_id) {
return 2400000;
}
return 0;
}
uint8_t ws_get_ofdm_option_using_phy_mode_id(uint8_t phy_mode_id)
{
if ((phy_mode_id >= 34) && (phy_mode_id <= 38)) {
return OFDM_OPTION_1;
} else if ((phy_mode_id >= 51) && (phy_mode_id <= 54)) {
return OFDM_OPTION_2;
} else if ((phy_mode_id >= 68) && (phy_mode_id <= 70)) {
return OFDM_OPTION_3;
} else if ((phy_mode_id >= 84) && (phy_mode_id <= 86)) {
return OFDM_OPTION_4;
}
return 0;
}
uint8_t ws_get_ofdm_mcs_using_phy_mode_id(uint8_t phy_mode_id)
{
if (34 == phy_mode_id) {
return OFDM_MCS_2;
} else if ((35 == phy_mode_id) || (51 == phy_mode_id)) {
return OFDM_MCS_3;
} else if ((36 == phy_mode_id) || (52 == phy_mode_id) || (68 == phy_mode_id) || (84 == phy_mode_id)) {
return OFDM_MCS_4;
} else if ((37 == phy_mode_id) || (53 == phy_mode_id) || (69 == phy_mode_id) || (85 == phy_mode_id)) {
return OFDM_MCS_5;
} else if ((38 == phy_mode_id) || (54 == phy_mode_id) || (70 == phy_mode_id) || (86 == phy_mode_id)) {
return OFDM_MCS_6;
}
return 0;
}
phy_modulation_index_e ws_get_modulation_index_using_operating_mode(uint8_t operating_mode)
{
if ((OPERATING_MODE_1b == operating_mode) || (OPERATING_MODE_2b == operating_mode) || (OPERATING_MODE_4b == operating_mode)) {
@ -146,6 +228,38 @@ int8_t ws_common_regulatory_domain_config(protocol_interface_info_entry_t *cur,
return -1;
}
// Validate PHY mode ID
if (hopping_schdule->phy_mode_id != 255) {
uint8_t phy_mode_id = hopping_schdule->phy_mode_id;
uint8_t phy_type = phy_mode_id >> 4;
uint8_t phy_mode = phy_mode_id & 0x0f;
// Invalid PHY type
if (phy_type > 5) {
return -1;
}
// Invalid OFDM mode
if (phy_type >= 2 && phy_mode > 6) {
return -1;
}
// Skip if PHY mode is for FSK modulation
if (!phy_mode_id || ((phy_mode_id > 8) && (phy_mode_id < 17)) || phy_mode_id > 24) {
// Validate OFDM configurations
if (((phy_mode_id >= 34) && (phy_mode_id <= 38)) ||
((phy_mode_id >= 51) && (phy_mode_id <= 54)) ||
((phy_mode_id >= 68) && (phy_mode_id <= 70)) ||
((phy_mode_id >= 84) && (phy_mode_id <= 86))) {
if (ws_get_datarate_using_phy_mode_id(phy_mode_id) == 0 ||
ws_get_ofdm_option_using_phy_mode_id(phy_mode_id) == 0 ||
ws_get_ofdm_mcs_using_phy_mode_id(phy_mode_id) == 0) {
//Unsupported PHY mode
return -1;
}
} else {
// Invalid PHY mode ID
return -1;
}
}
}
hopping_schdule->channel_plan = 0;
if (hopping_schdule->regulatory_domain == REG_DOMAIN_KR) {
@ -185,6 +299,7 @@ int8_t ws_common_regulatory_domain_config(protocol_interface_info_entry_t *cur,
return -1;
}
} else if (hopping_schdule->regulatory_domain == REG_DOMAIN_NA) {
if (hopping_schdule->channel_plan_id == 255) {
if (hopping_schdule->operating_class == 1) {
hopping_schdule->ch0_freq = 9022;
hopping_schdule->channel_spacing = CHANNEL_SPACING_200;
@ -197,7 +312,22 @@ int8_t ws_common_regulatory_domain_config(protocol_interface_info_entry_t *cur,
} else {
return -1;
}
} else {
if (hopping_schdule->channel_plan_id == 1) {
hopping_schdule->ch0_freq = 9022;
hopping_schdule->channel_spacing = CHANNEL_SPACING_200;
} else if (hopping_schdule->channel_plan_id == 2) {
hopping_schdule->ch0_freq = 9024;
hopping_schdule->channel_spacing = CHANNEL_SPACING_400;
} else if (hopping_schdule->channel_plan_id == 5) {
hopping_schdule->ch0_freq = 9032;
hopping_schdule->channel_spacing = CHANNEL_SPACING_1200;
} else {
return -1;
}
}
} else if (hopping_schdule->regulatory_domain == REG_DOMAIN_BZ) {
if (hopping_schdule->channel_plan_id == 255) {
if (hopping_schdule->operating_class == 1) {
hopping_schdule->ch0_freq = 9022;
hopping_schdule->channel_spacing = CHANNEL_SPACING_200;
@ -210,6 +340,20 @@ int8_t ws_common_regulatory_domain_config(protocol_interface_info_entry_t *cur,
} else {
return -1;
}
} else {
if (hopping_schdule->channel_plan_id == 1) {
hopping_schdule->ch0_freq = 9022;
hopping_schdule->channel_spacing = CHANNEL_SPACING_200;
} else if (hopping_schdule->channel_plan_id == 2) {
hopping_schdule->ch0_freq = 9024;
hopping_schdule->channel_spacing = CHANNEL_SPACING_400;
} else if (hopping_schdule->channel_plan_id == 5) {
hopping_schdule->ch0_freq = 9032;
hopping_schdule->channel_spacing = CHANNEL_SPACING_1200;
} else {
return -1;
}
}
} else if (hopping_schdule->regulatory_domain == REG_DOMAIN_JP) {
if (hopping_schdule->operating_class == 1) {
hopping_schdule->ch0_freq = 9206;
@ -236,7 +380,7 @@ int8_t ws_common_regulatory_domain_config(protocol_interface_info_entry_t *cur,
} else {
return -1;
}
hopping_schdule->number_of_channels = (uint8_t)ws_common_channel_number_calc(hopping_schdule->regulatory_domain, hopping_schdule->operating_class);
hopping_schdule->number_of_channels = (uint8_t)ws_common_channel_number_calc(hopping_schdule->regulatory_domain, hopping_schdule->operating_class, hopping_schdule->channel_plan_id);
if (!hopping_schdule->number_of_channels) {
return -1;
}
@ -244,7 +388,7 @@ int8_t ws_common_regulatory_domain_config(protocol_interface_info_entry_t *cur,
return 0;
}
uint16_t ws_common_channel_number_calc(uint8_t regulatory_domain, uint8_t operating_class)
uint16_t ws_common_channel_number_calc(uint8_t regulatory_domain, uint8_t operating_class, uint8_t channel_plan_id)
{
if (regulatory_domain == REG_DOMAIN_KR) {
if (operating_class == 1) {
@ -269,6 +413,7 @@ uint16_t ws_common_channel_number_calc(uint8_t regulatory_domain, uint8_t operat
return 10;
}
} else if (regulatory_domain == REG_DOMAIN_NA) {
if (channel_plan_id == 255) {
if (operating_class == 1) {
return 129;
} else if (operating_class == 2) {
@ -276,6 +421,15 @@ uint16_t ws_common_channel_number_calc(uint8_t regulatory_domain, uint8_t operat
} else if (operating_class == 3) {
return 42;
}
} else {
if (channel_plan_id == 1) {
return 136;
} else if (channel_plan_id == 2) {
return 64;
} else if (channel_plan_id == 5) {
return 24;
}
}
} else if (regulatory_domain == REG_DOMAIN_JP) {
if (operating_class == 1) {
return 38;
@ -285,6 +439,7 @@ uint16_t ws_common_channel_number_calc(uint8_t regulatory_domain, uint8_t operat
return 12;
}
} else if (regulatory_domain == REG_DOMAIN_BZ) {
if (channel_plan_id == 255) {
if (operating_class == 1) {
return 129;
} else if (operating_class == 2) {
@ -292,6 +447,15 @@ uint16_t ws_common_channel_number_calc(uint8_t regulatory_domain, uint8_t operat
} else if (operating_class == 3) {
return 42;
}
} else {
if (channel_plan_id == 1) {
return 136;
} else if (channel_plan_id == 2) {
return 64;
} else if (channel_plan_id == 5) {
return 24;
}
}
} else if (regulatory_domain == REG_DOMAIN_WW) {
if (operating_class == 1) {
// TODO we dont support this yet, but it is used as test value
@ -366,10 +530,16 @@ void ws_common_neighbor_update(protocol_interface_info_entry_t *cur, const uint8
}
}
void ws_common_black_list_neighbour(const uint8_t *ll_address, uint8_t nd_status)
{
if (nd_status == ARO_FULL) {
blacklist_update(ll_address, false);
}
}
void ws_common_aro_failure(protocol_interface_info_entry_t *cur, const uint8_t *ll_address)
{
tr_warn("ARO registration Failure %s", trace_ipv6(ll_address));
blacklist_update(ll_address, false);
ws_bootstrap_aro_failure(cur, ll_address);
}
@ -478,18 +648,13 @@ bool ws_common_negative_aro_mark(protocol_interface_info_entry_t *interface, con
uint32_t ws_common_latency_estimate_get(protocol_interface_info_entry_t *cur)
{
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;
}
if (network_size <= NETWORK_SIZE_SMALL) {
// handles also NETWORK_SIZE_CERTIFICATE
if (ws_cfg_network_config_get(cur) <= CONFIG_SMALL) {
// Also has the certificate settings
latency = 5000;
} else if (network_size <= NETWORK_SIZE_MEDIUM) {
} else if (ws_cfg_network_config_get(cur) <= CONFIG_MEDIUM) {
latency = 10000;
} else if (network_size <= NETWORK_SIZE_LARGE) {
} else if (ws_cfg_network_config_get(cur) <= CONFIG_LARGE) {
latency = 20000;
} else {
latency = 30000;

View File

@ -122,7 +122,7 @@ typedef struct ws_info_s {
#ifdef HAVE_WS
int8_t ws_generate_channel_list(uint32_t *channel_mask, uint16_t number_of_channels, uint8_t regulatory_domain, uint8_t operating_class);
int8_t ws_generate_channel_list(uint32_t *channel_mask, uint16_t number_of_channels, uint8_t regulatory_domain, uint8_t operating_class, uint8_t channel_plan_id);
uint16_t ws_active_channel_count(uint32_t *channel_mask, uint16_t number_of_channels);
@ -130,11 +130,17 @@ uint32_t ws_decode_channel_spacing(uint8_t channel_spacing);
uint32_t ws_get_datarate_using_operating_mode(uint8_t operating_mode);
uint32_t ws_get_datarate_using_phy_mode_id(uint8_t phy_mode_id);
uint8_t ws_get_ofdm_option_using_phy_mode_id(uint8_t phy_mode_id);
uint8_t ws_get_ofdm_mcs_using_phy_mode_id(uint8_t phy_mode_id);
phy_modulation_index_e ws_get_modulation_index_using_operating_mode(uint8_t operating_mode);
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);
uint16_t ws_common_channel_number_calc(uint8_t regulatory_domain, uint8_t operating_class, uint8_t channel_plan_id);
int8_t ws_common_allocate_and_init(protocol_interface_info_entry_t *cur);
@ -144,6 +150,8 @@ void ws_common_fast_timer(protocol_interface_info_entry_t *cur, uint16_t ticks);
void ws_common_neighbor_update(protocol_interface_info_entry_t *cur, const uint8_t *ll_address);
void ws_common_black_list_neighbour(const uint8_t *ll_address, uint8_t nd_status);
void ws_common_aro_failure(protocol_interface_info_entry_t *cur, const uint8_t *ll_address);
void ws_common_neighbor_remove(protocol_interface_info_entry_t *cur, const uint8_t *ll_address);
@ -170,6 +178,7 @@ uint8_t ws_common_temporary_entry_size(uint8_t mac_table_size);
#define ws_info(cur) ((ws_info_t *) NULL)
#define ws_common_seconds_timer(cur, seconds)
#define ws_common_neighbor_update(cur, ll_address) ((void) 0)
#define ws_common_black_list_neighbour(ll_address, nd_status) ((void) 0)
#define ws_common_aro_failure(cur, ll_address)
#define ws_common_neighbor_remove(cur, ll_address)
#define ws_common_fast_timer(cur, ticks) ((void) 0)

View File

@ -100,6 +100,8 @@ typedef struct ws_hopping_schedule_s {
uint8_t regulatory_domain; /**< PHY regulatory domain default to "KR" 0x09 */
uint8_t operating_class; /**< PHY operating class default to 1 */
uint8_t operating_mode; /**< PHY operating mode default to "1b" symbol rate 50, modulation index 1 */
uint8_t phy_mode_id; /**< PHY mode ID, default to 255 */
uint8_t channel_plan_id; /**< Channel plan ID, default to 255 */
uint8_t channel_plan; /**< 0: use regulatory domain values 1: application defined plan */
uint8_t uc_channel_function; /**< 0: Fixed channel, 1:TR51CF, 2: Direct Hash, 3: Vendor defined */
uint8_t bc_channel_function; /**< 0: Fixed channel, 1:TR51CF, 2: Direct Hash, 3: Vendor defined */

View File

@ -68,6 +68,24 @@ int ws_management_network_name_validate(
return -1;
}
int ws_management_phy_mode_id_set(
int8_t interface_id,
uint8_t phy_mode_id)
{
(void)interface_id;
(void)phy_mode_id;
return -1;
}
int ws_management_channel_plan_id_set(
int8_t interface_id,
uint8_t channel_plan_id)
{
(void)interface_id;
(void)channel_plan_id;
return -1;
}
int ws_management_regulatory_domain_set(
int8_t interface_id,
uint8_t regulatory_domain,

View File

@ -156,6 +156,74 @@ int ws_management_network_name_validate(
return 0;
}
int ws_management_phy_mode_id_set(
int8_t interface_id,
uint8_t phy_mode_id)
{
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;
ws_phy_cfg_t cfg_default;
if (ws_cfg_phy_get(&cfg, NULL) < 0) {
return -3;
}
if (ws_cfg_phy_default_set(&cfg_default) < 0) {
return -3;
}
if (phy_mode_id != 255) {
cfg.phy_mode_id = phy_mode_id;
} else {
cfg.phy_mode_id = cfg_default.phy_mode_id;
}
if (ws_cfg_phy_set(cur, NULL, &cfg, 0) < 0) {
return -4;
}
return 0;
}
int ws_management_channel_plan_id_set(
int8_t interface_id,
uint8_t channel_plan_id)
{
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;
ws_phy_cfg_t cfg_default;
if (ws_cfg_phy_get(&cfg, NULL) < 0) {
return -3;
}
if (ws_cfg_phy_default_set(&cfg_default) < 0) {
return -3;
}
if (channel_plan_id != 255) {
cfg.channel_plan_id = channel_plan_id;
} else {
cfg.channel_plan_id = cfg_default.channel_plan_id;
}
if (ws_cfg_phy_set(cur, NULL, &cfg, 0) < 0) {
return -4;
}
return 0;
}
int ws_management_regulatory_domain_set(
int8_t interface_id,
uint8_t regulatory_domain,

View File

@ -254,7 +254,7 @@ void ws_neighbor_class_neighbor_unicast_schedule_set(ws_neighbor_class_entry_t *
} else {
if (ws_us->channel_plan == 0) {
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);
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, own_shedule->channel_plan_id);
} 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;
@ -262,16 +262,16 @@ void ws_neighbor_class_neighbor_unicast_schedule_set(ws_neighbor_class_entry_t *
//Handle excluded channel and generate activate channel list
if (ws_us->excluded_channel_ctrl == WS_EXC_CHAN_CTRL_RANGE) {
ws_generate_channel_list(ws_neighbor->fhss_data.uc_channel_list.channel_mask, ws_neighbor->fhss_data.uc_timing_info.unicast_number_of_channels, own_shedule->regulatory_domain, own_shedule->operating_class);
ws_generate_channel_list(ws_neighbor->fhss_data.uc_channel_list.channel_mask, ws_neighbor->fhss_data.uc_timing_info.unicast_number_of_channels, own_shedule->regulatory_domain, own_shedule->operating_class, own_shedule->channel_plan_id);
ws_neighbor->fhss_data.uc_channel_list.channel_count = ws_active_channel_count(ws_neighbor->fhss_data.uc_channel_list.channel_mask, ws_neighbor->fhss_data.uc_timing_info.unicast_number_of_channels);
ws_neighbour_excluded_mask_by_range(&ws_neighbor->fhss_data.uc_channel_list, &ws_us->excluded_channels.range, ws_neighbor->fhss_data.uc_timing_info.unicast_number_of_channels);
} else if (ws_us->excluded_channel_ctrl == WS_EXC_CHAN_CTRL_BITMASK) {
ws_generate_channel_list(ws_neighbor->fhss_data.uc_channel_list.channel_mask, ws_neighbor->fhss_data.uc_timing_info.unicast_number_of_channels, own_shedule->regulatory_domain, own_shedule->operating_class);
ws_generate_channel_list(ws_neighbor->fhss_data.uc_channel_list.channel_mask, ws_neighbor->fhss_data.uc_timing_info.unicast_number_of_channels, own_shedule->regulatory_domain, own_shedule->operating_class, own_shedule->channel_plan_id);
ws_neighbor->fhss_data.uc_channel_list.channel_count = ws_active_channel_count(ws_neighbor->fhss_data.uc_channel_list.channel_mask, ws_neighbor->fhss_data.uc_timing_info.unicast_number_of_channels);
ws_neighbour_excluded_mask_by_mask(&ws_neighbor->fhss_data.uc_channel_list, &ws_us->excluded_channels.mask, ws_neighbor->fhss_data.uc_timing_info.unicast_number_of_channels);
} else if (ws_us->excluded_channel_ctrl == WS_EXC_CHAN_CTRL_NONE) {
if (ws_neighbor->fhss_data.uc_timing_info.unicast_number_of_channels != ws_neighbor->fhss_data.uc_channel_list.channel_count) {
ws_generate_channel_list(ws_neighbor->fhss_data.uc_channel_list.channel_mask, ws_neighbor->fhss_data.uc_timing_info.unicast_number_of_channels, own_shedule->regulatory_domain, own_shedule->operating_class);
ws_generate_channel_list(ws_neighbor->fhss_data.uc_channel_list.channel_mask, ws_neighbor->fhss_data.uc_timing_info.unicast_number_of_channels, own_shedule->regulatory_domain, own_shedule->operating_class, own_shedule->channel_plan_id);
ws_neighbor->fhss_data.uc_channel_list.channel_count = ws_active_channel_count(ws_neighbor->fhss_data.uc_channel_list.channel_mask, ws_neighbor->fhss_data.uc_timing_info.unicast_number_of_channels);
}
}

View File

@ -186,6 +186,7 @@ static int8_t ws_pae_key_storage_allocate(const void *instance, uint16_t key_sto
if (new_storage_array == NULL) {
key_storage_array->storage_array_handle = ns_dyn_mem_alloc(key_storage_size);
if (!key_storage_array->storage_array_handle) {
ns_dyn_mem_free(key_storage_array);
return -1;
}
key_storage_array->allocated = true;

View File

@ -269,6 +269,8 @@ int8_t ws_pae_supp_border_router_addr_read(protocol_interface_info_entry_t *inte
int8_t ws_pae_supp_nw_key_valid(protocol_interface_info_entry_t *interface_ptr, uint8_t *br_iid)
{
(void) br_iid;
pae_supp_t *pae_supp = ws_pae_supp_get(interface_ptr);
if (!pae_supp) {
return -1;
@ -276,24 +278,6 @@ int8_t ws_pae_supp_nw_key_valid(protocol_interface_info_entry_t *interface_ptr,
tr_info("NW key valid indication");
// Store border router EUI-64 received on bootstrap complete
memcpy(pae_supp->comp_br_eui_64, br_iid, 8);
pae_supp->comp_br_eui_64[0] ^= 0x02;
pae_supp->comp_br_eui_64_set = true;
// Get the EUI-64 used on 4WH handshake PTK generation
uint8_t *ptk_eui_64 = sec_prot_keys_ptk_eui_64_get(&pae_supp->entry.sec_keys);
/* If border router EUI-64 received on bootstrap complete does not match to
EUI-64 stored with keys, delete keys */
if (!ptk_eui_64 || memcmp(ptk_eui_64, pae_supp->comp_br_eui_64, 8) != 0) {
tr_warn("Delete keys: PTK EUI-64 %s does not match to BR EUI-64 %s",
ptk_eui_64 ? tr_array(ptk_eui_64, 8) : "", tr_array(pae_supp->comp_br_eui_64, 8));
sec_prot_keys_pmk_delete(&pae_supp->entry.sec_keys);
sec_prot_keys_ptk_delete(&pae_supp->entry.sec_keys);
sec_prot_keys_ptk_eui_64_delete(&pae_supp->entry.sec_keys);
}
// Stored keys are valid
pae_supp->nw_keys_used_cnt = 0;

View File

@ -357,6 +357,7 @@ static void icmpv6_na_wisun_aro_handler(protocol_interface_info_entry_t *cur_int
(void)life_time;
if (nd_status != ARO_SUCCESS) {
ws_common_black_list_neighbour(src_addr, nd_status);
ws_common_aro_failure(cur_interface, src_addr);
}
}
@ -1447,7 +1448,7 @@ static void icmpv6_aro_cb(buffer_t *buf, uint8_t status)
ll_address[8] ^= 2;
}
if (rpl_control_address_register_done(buf->interface, ll_address, status)) {
// When RPL returns true neighbor should be blacklisted
// When RPL returns true neighbor should be deleted
ws_common_aro_failure(buf->interface, ll_address);
}
}

View File

@ -82,7 +82,7 @@ void tcp_test_drop_reset()
}
#endif
#ifdef FEA_TRACE_SUPPORT
#if defined(FEA_TRACE_SUPPORT) && MBED_CONF_MBED_TRACE_ENABLE && (MBED_TRACE_MAX_LEVEL >= TRACE_LEVEL_DEBUG)
static const char *trace_tcp_flags(uint16_t flags)
{
static char buf[9];
@ -1223,7 +1223,9 @@ buffer_t *tcp_up(buffer_t *buf)
seg_len++;
}
#if defined(FEA_TRACE_SUPPORT) && MBED_CONF_MBED_TRACE_ENABLE && (MBED_TRACE_MAX_LEVEL >= TRACE_LEVEL_DEBUG)
tr_debug("TCP_UP: dst_p=%d, src_p=%d, flags=%s", buf->dst_sa.port, buf->src_sa.port, trace_tcp_flags(flags));
#endif
/* clear flags that will be ignored */
flags &= ~(TCP_FLAG_CWR | TCP_FLAG_ECE | TCP_FLAG_URG);

View File

@ -34,6 +34,7 @@
#include "ipv6_stack/ipv6_routing_table.h"
#include "NWK_INTERFACE/Include/protocol.h"
#include "6LoWPAN/ws/ws_pae_controller.h"
#include "6LoWPAN/lowpan_adaptation_interface.h"
#include "NWK_INTERFACE/Include/protocol.h"
#define TRACE_GROUP "mntr"
@ -73,7 +74,8 @@ typedef void (ns_maintenance_gc_cb)(bool full_gc);
*/
static ns_maintenance_gc_cb *ns_maintenance_gc_functions[] = {
ipv6_destination_cache_forced_gc,
ws_pae_controller_forced_gc
ws_pae_controller_forced_gc,
lowpan_adaptation_free_heap
};
static void ns_monitor_heap_gc(bool full_gc)

View File

@ -26,6 +26,7 @@
struct cca_structure_s;
struct buffer;
struct mac_pre_build_frame;
struct mac_pre_parsed_frame_s;
struct mlme_key_descriptor_s;
struct arm_device_driver_list;
struct fhss_api;
@ -204,6 +205,7 @@ typedef struct protocol_interface_rf_mac_setup {
bool macBroadcastDisabled: 1;
bool scan_active: 1;
bool rf_csma_extension_supported: 1;
bool rf_pd_ack_buffer_is_in_use: 1;
uint16_t mac_short_address;
uint16_t pan_id;
uint8_t mac64[8];
@ -233,7 +235,9 @@ typedef struct protocol_interface_rf_mac_setup {
struct mac_pre_build_frame *pd_data_request_queue_to_go;
struct mac_pre_build_frame *pd_data_request_bc_queue_to_go;
struct mac_pre_build_frame *active_pd_data_request;
struct mac_pre_parsed_frame_s *pd_rx_ack_buffer;
/* MAC Beacon info */
uint16_t allocated_ack_buffer_length;
uint16_t max_beacon_payload_length;
uint8_t *mac_beacon_payload;
uint8_t mac_beacon_payload_size;
@ -253,6 +257,7 @@ typedef struct protocol_interface_rf_mac_setup {
struct mac_pre_build_frame enhanced_ack_buffer;
uint32_t enhanced_ack_handler_timestamp;
arm_event_t mac_mcps_timer_event;
arm_event_storage_t mac_ack_event;
uint16_t indirect_pending_bytes;
arm_nwk_mlme_event_type_e mac_mlme_event;
mac_event_t timer_mac_event;

View File

@ -29,6 +29,7 @@
#include "mac_mcps.h"
#include "MAC/IEEE802_15_4/mac_mcps_sap.h"
#include "MAC/IEEE802_15_4/mac_header_helper_functions.h"
#include "MAC/rf_driver_storage.h"
#define TRACE_GROUP "mFil"
@ -291,7 +292,7 @@ int_fast8_t mac_filter_add_long(int8_t interface_id, uint8_t mac64[8], int16_t l
return 0;
}
int_fast8_t mac_filter_modify_link_quality(int8_t interface_id, mac_pre_parsed_frame_t *mac_frame)
int_fast8_t mac_filter_modify_link_quality(int8_t interface_id, struct mac_fcf_sequence_s *fcf, struct arm_pd_sap_generic_ind_s *mac_frame)
{
filter_instance_t *this = filter_instance_find(interface_id);
filter_t *filter_ptr = NULL;
@ -300,25 +301,24 @@ int_fast8_t mac_filter_modify_link_quality(int8_t interface_id, mac_pre_parsed_f
int16_t dbm_m;
int16_t dbm_add;
if (!this || !mac_frame) {
if (!this) {
return 0;
}
if (!this->enabled) {
return 0;
}
tr_debug_extra("mac_filter_modify_link_quality lqi %d dbm %d", mac_frame->link_quality, mac_frame->dbm);
tr_debug_extra("mac_filter_modify_link_quality lqi %d dbm %d", mac_frame->LQI, mac_frame->dbm);
if (mac_frame->fcf_dsn.SrcAddrMode == MAC_ADDR_MODE_NONE) {
if (fcf->SrcAddrMode == MAC_ADDR_MODE_NONE) {
return 0;
}
uint8_t srcAddress[8];
mac_header_get_src_address(&mac_frame->fcf_dsn, mac_header_message_start_pointer(mac_frame), srcAddress);
mac_header_get_src_address(fcf, mac_frame->data_ptr, srcAddress);
//Find filter for specific address
if (mac_frame->fcf_dsn.SrcAddrMode == MAC_ADDR_MODE_16_BIT) {
if (fcf->SrcAddrMode == MAC_ADDR_MODE_16_BIT) {
uint16_t mac16 = common_read_16_bit(srcAddress);
filter_ptr = filter_find_short(this, mac16);
if (!filter_ptr && this->resolve_long_cb) {
@ -354,14 +354,14 @@ int_fast8_t mac_filter_modify_link_quality(int8_t interface_id, mac_pre_parsed_f
}
//calculate
int16_t lqi = ((mac_frame->LQI * lqi_m) >> 8) + lqi_add;
int16_t lqi = ((mac_frame->link_quality * lqi_m) >> 8) + lqi_add;
// Saturate
if (lqi > 255) {
mac_frame->LQI = 255;
mac_frame->link_quality = 255;
} else if (lqi < 0) {
mac_frame->LQI = 0;
mac_frame->link_quality = 0;
} else {
mac_frame->LQI = lqi;
mac_frame->link_quality = lqi;
}
//calculate
@ -375,14 +375,14 @@ int_fast8_t mac_filter_modify_link_quality(int8_t interface_id, mac_pre_parsed_f
mac_frame->dbm = dbm;
}
tr_debug_extra("mac_filter_modify_link_quality result lqi %d dbm %d", mac_frame->LQI, mac_frame->dbm);
tr_debug_extra("mac_filter_modify_link_quality result lqi %d dbm %d", mac_frame->link_quality, mac_frame->dbm);
// If quality goes below treshold packet is dropped
if ((dbm_m != 0x100 || dbm_add != 0) && (mac_frame->dbm < MAC_FILTER_SIGNAL_FLOOR)) {
tr_debug_extra("Filter dropped packet signal too low");
return 1;
}
if ((lqi_m != 0x100 || lqi_add != 0) && (mac_frame->LQI < 1)) {
if ((lqi_m != 0x100 || lqi_add != 0) && (mac_frame->link_quality < 1)) {
tr_debug_extra("Filter dropped packet LQI < 1");
return 1;
}

View File

@ -24,7 +24,8 @@
#ifndef MAC_FILTER_H_
#define MAC_FILTER_H_
struct mac_pre_parsed_frame_s;
struct mac_fcf_sequence_s;
struct arm_pd_sap_generic_ind_s;
/**
* Modify the link quality values.
@ -41,6 +42,6 @@ struct mac_pre_parsed_frame_s;
* return >0 Packet is ignored.
* return 0 Packet is not dropped.
*/
int_fast8_t mac_filter_modify_link_quality(int8_t interface_id, struct mac_pre_parsed_frame_s *mac_frame);
int_fast8_t mac_filter_modify_link_quality(int8_t interface_id, struct mac_fcf_sequence_s *fcf, struct arm_pd_sap_generic_ind_s *mac_frame);
#endif /* MAC_FILTER_H_ */

View File

@ -2372,6 +2372,18 @@ static mac_pre_build_frame_t *mcps_sap_pd_req_queue_read(protocol_interface_rf_m
void mcps_sap_pre_parsed_frame_buffer_free(mac_pre_parsed_frame_t *buf)
{
if (!buf) {
return;
}
if (buf->mac_class_ptr && buf->fcf_dsn.frametype == FC_ACK_FRAME) {
struct protocol_interface_rf_mac_setup *rf_mac_setup = buf->mac_class_ptr;
if (rf_mac_setup->rf_pd_ack_buffer_is_in_use) {
rf_mac_setup->rf_pd_ack_buffer_is_in_use = false;
return;
}
}
ns_dyn_mem_free(buf);
}
@ -2388,6 +2400,37 @@ mac_pre_parsed_frame_t *mcps_sap_pre_parsed_frame_buffer_get(const uint8_t *data
return buffer;
}
mac_pre_parsed_frame_t *mcps_sap_pre_parsed_ack_buffer_get(protocol_interface_rf_mac_setup_s *rf_ptr, const uint8_t *data_ptr, uint16_t frame_length)
{
if (rf_ptr->rf_pd_ack_buffer_is_in_use) {
#ifdef __linux__
tr_debug("mac ACK buffer get fail: already active");
#endif
return NULL;
}
if (frame_length > rf_ptr->allocated_ack_buffer_length) {
//Free Current
if (rf_ptr->pd_rx_ack_buffer) {
ns_dyn_mem_free(rf_ptr->pd_rx_ack_buffer);
rf_ptr->allocated_ack_buffer_length = 0;
}
rf_ptr->pd_rx_ack_buffer = ns_dyn_mem_alloc(sizeof(mac_pre_parsed_frame_t) + frame_length);
if (!rf_ptr->pd_rx_ack_buffer) {
return NULL;
}
rf_ptr->allocated_ack_buffer_length = frame_length;
}
memset(rf_ptr->pd_rx_ack_buffer, 0, sizeof(mac_pre_parsed_frame_t) + rf_ptr->allocated_ack_buffer_length);
rf_ptr->pd_rx_ack_buffer->frameLength = frame_length;
memcpy(mac_header_message_start_pointer(rf_ptr->pd_rx_ack_buffer), data_ptr, frame_length);
//Mark active ACK buffer state
rf_ptr->rf_pd_ack_buffer_is_in_use = true;
return rf_ptr->pd_rx_ack_buffer;
}
static void mac_set_active_event(protocol_interface_rf_mac_setup_s *rf_mac_setup, uint8_t event_type)
{
rf_mac_setup->active_mac_events |= (1 << event_type);
@ -2458,21 +2501,36 @@ int8_t mcps_sap_pd_confirm_failure(void *mac_ptr)
return eventOS_event_send(&event);
}
void mcps_sap_pd_ack(void *ack_ptr)
int8_t mcps_sap_pd_ack(struct protocol_interface_rf_mac_setup *rf_ptr, mac_pre_parsed_frame_t *buffer)
{
if (mac_tasklet_event_handler < 0 || !ack_ptr) {
return;
if (mac_tasklet_event_handler < 0 || !buffer) {
return -1;
}
if (buffer->fcf_dsn.frametype == FC_ACK_FRAME) {
arm_event_storage_t *event = &rf_ptr->mac_ack_event;
event->data.data_ptr = buffer;
event->data.event_data = 0;
event->data.event_id = 0;
event->data.event_type = MCPS_SAP_DATA_ACK_CNF_EVENT;
event->data.priority = ARM_LIB_HIGH_PRIORITY_EVENT;
event->data.sender = 0;
event->data.receiver = mac_tasklet_event_handler;
eventOS_event_send_user_allocated(event);
return 0;
}
arm_event_s event = {
.receiver = mac_tasklet_event_handler,
.sender = 0,
.event_id = 0,
.data_ptr = ack_ptr,
.data_ptr = buffer,
.event_type = MCPS_SAP_DATA_ACK_CNF_EVENT,
.priority = ARM_LIB_HIGH_PRIORITY_EVENT,
};
eventOS_event_send(&event);
return eventOS_event_send(&event);
}
void mcps_sap_trig_tx(void *mac_ptr)
@ -2566,6 +2624,17 @@ void mac_mcps_buffer_queue_free(protocol_interface_rf_mac_setup_s *rf_mac_setup)
mcps_sap_prebuild_frame_buffer_free(buffer);
}
}
if (rf_mac_setup->pd_rx_ack_buffer) {
if (rf_mac_setup->rf_pd_ack_buffer_is_in_use) {
eventOS_cancel(&rf_mac_setup->mac_ack_event);
rf_mac_setup->rf_pd_ack_buffer_is_in_use = false;
}
ns_dyn_mem_free(rf_mac_setup->pd_rx_ack_buffer);
rf_mac_setup->pd_rx_ack_buffer = NULL;
rf_mac_setup->allocated_ack_buffer_length = 0;
}
}
/**
* Function return list start pointer

View File

@ -36,6 +36,7 @@ struct mcps_purge_s;
struct mcps_data_req_ie_list;
struct channel_list_s;
struct mcps_enhanced_frame_response_s;
struct mac_pre_parsed_frame_s;
/** Address types */
typedef enum {
@ -100,6 +101,8 @@ void mcps_sap_pd_req_queue_write(struct protocol_interface_rf_mac_setup *rf_mac_
*/
mac_pre_parsed_frame_t *mcps_sap_pre_parsed_frame_buffer_get(const uint8_t *data_ptr, uint16_t frame_length);
mac_pre_parsed_frame_t *mcps_sap_pre_parsed_ack_buffer_get(struct protocol_interface_rf_mac_setup *rf_ptr, const uint8_t *data_ptr, uint16_t frame_length);
/**
* Forward Buffer for MAC MCPS SAP layer event handler
*/
@ -112,7 +115,7 @@ int8_t mcps_sap_pd_confirm(void *mac_ptr);
int8_t mcps_sap_pd_confirm_failure(void *mac_ptr);
void mcps_sap_pd_ack(void *ack_ptr);
int8_t mcps_sap_pd_ack(struct protocol_interface_rf_mac_setup *rf_ptr, struct mac_pre_parsed_frame_s *buffer);
int8_t mac_virtual_sap_data_cb(void *identifier, struct arm_phy_sap_msg_s *message);

View File

@ -480,6 +480,8 @@ static int8_t mac_data_interface_tx_done_cb(protocol_interface_rf_mac_setup_s *r
rf_ptr->dev_driver->phy_driver->phy_tail_length, active_buf->tx_time);
// When FHSS TX handle returns -1, transmission of the packet is currently not allowed -> restart CCA timer
if (tx_handle_retval == -1) {
// RX channel could have changed during CSMA-CA, must update using TX done callback
rf_ptr->fhss_api->data_tx_done(rf_ptr->fhss_api, false, false, rf_ptr->active_pd_data_request->msduHandle);
mac_sap_cca_fail_cb(rf_ptr, 0xffff);
return PHY_TX_NOT_ALLOWED;
}
@ -631,14 +633,19 @@ VALIDATE_TX_TIME:
return 0;
}
static int8_t mac_data_interface_waiting_ack(protocol_interface_rf_mac_setup_s *rf_ptr, const mac_fcf_sequence_t *fcf_read)
{
if (!rf_ptr->macRfRadioTxActive || !rf_ptr->active_pd_data_request || rf_ptr->active_pd_data_request->fcf_dsn.DSN != fcf_read->DSN) {
return -1;
}
return 0;
}
static int8_t mac_data_interface_tx_done_by_ack_cb(protocol_interface_rf_mac_setup_s *rf_ptr, mac_pre_parsed_frame_t *buf)
{
if (!rf_ptr->macRfRadioTxActive || !rf_ptr->active_pd_data_request || rf_ptr->active_pd_data_request->fcf_dsn.DSN != buf->fcf_dsn.DSN) {
return -1;
}
timer_mac_stop(rf_ptr);
if (buf->fcf_dsn.framePending) {
rf_ptr->mac_tx_result = MAC_TX_DONE_PENDING;
@ -647,7 +654,9 @@ static int8_t mac_data_interface_tx_done_by_ack_cb(protocol_interface_rf_mac_set
}
rf_ptr->macRfRadioTxActive = false;
rf_ptr->macTxProcessActive = false;
mcps_sap_pd_ack(buf);
if (mcps_sap_pd_ack(rf_ptr, buf) != 0) {
mcps_sap_pre_parsed_frame_buffer_free(buf);
}
if (rf_ptr->fhss_api) {
rf_ptr->fhss_api->data_tx_done(rf_ptr->fhss_api, false, true, rf_ptr->active_pd_data_request->msduHandle);
@ -891,22 +900,35 @@ static int8_t mac_pd_sap_generate_edfe_response(protocol_interface_rf_mac_setup_
static mac_pre_parsed_frame_t *mac_pd_sap_allocate_receive_buffer(protocol_interface_rf_mac_setup_s *rf_ptr, const mac_fcf_sequence_t *fcf_read, arm_pd_sap_generic_ind_t *pd_data_ind)
{
// Unless receiving Ack, check that system has enough space to handle the new packet
if (fcf_read->frametype != FC_ACK_FRAME) {
if (!ns_monitor_packet_allocation_allowed()) {
mac_pre_parsed_frame_t *buffer = NULL;
if (fcf_read->frametype != FC_ACK_FRAME || rf_ptr->macProminousMode) {
if (!rf_ptr->macProminousMode && !ns_monitor_packet_allocation_allowed()) {
// stack can not handle new packets for routing
#ifdef __linux__
tr_debug("Packet ingress drop buffer allocation");
#endif
return NULL;
}
}
mac_pre_parsed_frame_t *buffer = mcps_sap_pre_parsed_frame_buffer_get(pd_data_ind->data_ptr, pd_data_ind->data_len);
buffer = mcps_sap_pre_parsed_frame_buffer_get(pd_data_ind->data_ptr, pd_data_ind->data_len);
if (!buffer) {
#ifdef __linux__
tr_debug("macPD buffer allocate fail %u", pd_data_ind->data_len);
#endif
return NULL;
}
} else {
//Allocate ACK buffer
buffer = mcps_sap_pre_parsed_ack_buffer_get(rf_ptr, pd_data_ind->data_ptr, pd_data_ind->data_len);
if (!buffer) {
#ifdef __linux__
tr_debug("macPD ACK buffer allocate fail %u", pd_data_ind->data_len);
#endif
return NULL;
}
}
//Copy Pre Parsed values
buffer->fcf_dsn = *fcf_read;
buffer->timestamp = mac_pd_sap_get_phy_rx_time(rf_ptr);
@ -1012,11 +1034,20 @@ int8_t mac_pd_sap_data_cb(void *identifier, arm_phy_sap_msg_t *message)
mac_fcf_sequence_t fcf_read;
const uint8_t *ptr = mac_header_parse_fcf_dsn(&fcf_read, pd_data_ind->data_ptr);
buffer = mac_pd_sap_allocate_receive_buffer(rf_ptr, &fcf_read, pd_data_ind);
if (buffer && mac_filter_modify_link_quality(rf_ptr->mac_interface_id, buffer) == 1) {
// No need to send Ack - Check if RX channel needs to be updated
if (fcf_read.ackRequested == false) {
if (rf_ptr->fhss_api) {
rf_ptr->fhss_api->data_tx_done(rf_ptr->fhss_api, false, false, 0);
}
}
//Modify link quality
if (mac_filter_modify_link_quality(rf_ptr->mac_interface_id, &fcf_read, pd_data_ind) == 1) {
goto ERROR_HANDLER;
}
if (!rf_ptr->macProminousMode) {
//Pre validate things before allocate buffer
if (mac_pd_sap_validate_fcf(rf_ptr, &fcf_read, pd_data_ind)) {
goto ERROR_HANDLER;
}
@ -1024,12 +1055,26 @@ int8_t mac_pd_sap_data_cb(void *identifier, arm_phy_sap_msg_t *message)
pd_data_ind->data_len = 0; // Do not update RX drop in that case
goto ERROR_HANDLER;
}
//Ack can be send even buffer allocate fail
if (mac_pd_sap_generate_ack(rf_ptr, &fcf_read, pd_data_ind)) {
#ifdef __linux__
tr_debug("Drop a Data by ignored ACK generation");
#endif
goto ERROR_HANDLER;
}
if (fcf_read.frametype == FC_ACK_FRAME && mac_data_interface_waiting_ack(rf_ptr, &fcf_read)) {
#ifdef __linux__
tr_debug("Drop a ACK not a proper DSN");
#endif
goto ERROR_HANDLER;
}
}
//Allocate Buffer
buffer = mac_pd_sap_allocate_receive_buffer(rf_ptr, &fcf_read, pd_data_ind);
if (!rf_ptr->macProminousMode) {
if (buffer) {
if (mac_pd_sap_parse_length_fields(buffer, pd_data_ind, ptr)) {
goto ERROR_HANDLER;
@ -1098,7 +1143,7 @@ int8_t mac_pd_sap_data_cb(void *identifier, arm_phy_sap_msg_t *message)
//Mark session closed
rf_ptr->mac_edfe_info->state = MAC_EDFE_FRAME_IDLE;
rf_ptr->mac_edfe_tx_active = false;
if (mac_data_interface_tx_done_by_ack_cb(rf_ptr, buffer)) {
if (mac_data_interface_waiting_ack(rf_ptr, &buffer->fcf_dsn) || mac_data_interface_tx_done_by_ack_cb(rf_ptr, buffer)) {
mcps_sap_pre_parsed_frame_buffer_free(buffer);
}
return 0;

View File

@ -1169,6 +1169,23 @@ malformed:
goto invalid_parent;
}
/* RFC 6550 8.3: A DIO from a sender with lesser DAGRank that causes no
* changes to the recipient's parent set, preferred parent, or Rank SHOULD
* be considered consistent with respect to the Trickle timer.
*
* Now, if we don't run parent selection immediately, how do we know if it's
* consistent or not? Compromise is to treat all lower ranked DIOs as
* consistent, and reset (and hold) the consistent counter to 0 if any of
* the above change. This actually seems better than the RFC 6550 rule, as
* it guarantees we will transmit if those change. The rule as stated
* would mean a large number of parent messages would stop us advertising
* a Rank change.
*/
if (version == rpl_instance_current_dodag_version(instance) &&
(rpl_rank_compare(dodag, rank, rpl_instance_current_rank(instance)) & RPL_CMP_LESS)) {
rpl_instance_consistent_rx(instance);
}
/* Now we create the neighbour, if we don't already have a record */
if (!neighbour) {
@ -1208,23 +1225,6 @@ malformed:
rpl_dodag_set_leaf(dodag, true);
}
/* RFC 6550 8.3: A DIO from a sender with lesser DAGRank that causes no
* changes to the recipient's parent set, preferred parent, or Rank SHOULD
* be considered consistent with respect to the Trickle timer.
*
* Now, if we don't run parent selection immediately, how do we know if it's
* consistent or not? Compromise is to treat all lower ranked DIOs as
* consistent, and reset (and hold) the consistent counter to 0 if any of
* the above change. This actually seems better than the RFC 6550 rule, as
* it guarantees we will transmit if those change. The rule as stated
* would mean a large number of parent messages would stop us advertising
* a Rank change.
*/
if (version == rpl_instance_current_dodag_version(instance) &&
(rpl_rank_compare(dodag, rank, rpl_instance_current_rank(instance)) & RPL_CMP_LESS)) {
rpl_instance_consistent_rx(instance);
}
rpl_instance_neighbours_changed(instance, dodag);
return buffer_free(buf);

View File

@ -885,9 +885,24 @@ void rpl_instance_send_dao_update(rpl_instance_t *instance)
instance->requested_dao_ack = need_ack;
instance->dao_in_transit = true;
if (instance->dao_attempt < 16) {
uint32_t t = (uint32_t) rpl_policy_initial_dao_ack_wait(instance->domain, mop) << instance->dao_attempt;
t = randLIB_randomise_base(t, 0x4000, 0xC000);
instance->dao_retry_timer = t <= 0xffff ? t : 0xffff;
uint32_t delay = rpl_policy_initial_dao_ack_wait(instance->domain, mop);
if (delay < dodag->dio_timer_params.Imin) {
//Use Imin Based on delay if it is longer than cache retry
delay = dodag->dio_timer_params.Imin;
}
//Multiply Delay by attempt
delay = delay << instance->dao_attempt;
if (delay > 5400) {
//MAX base 540 seconds (9min)
delay = 5400;
}
// 0.5 - 1.5 *t randomized base delay
delay = randLIB_randomise_base(delay, 0x4000, 0xC000);
instance->dao_retry_timer = delay;
} else {
instance->dao_retry_timer = 0xffff;
}

View File

@ -180,6 +180,7 @@ struct rpl_instance {
bool requested_dao_ack: 1; /* If we requested an ACK (so we retry if no ACK, rather than assuming success) */
bool pending_neighbour_confirmation: 1; /* if we have not finished address registration state to parent */
bool parent_was_selected: 1;
bool advertised_dodag_membership_since_last_repair: 1; /* advertised dodag membership since last repair */
uint8_t poison_count;
uint8_t repair_dis_count;
uint16_t repair_dis_timer;
@ -192,7 +193,7 @@ struct rpl_instance {
rpl_dodag_version_t *current_dodag_version; /* Pointer to DODAG version we are a member of (if any) */
uint16_t current_rank; /* Current rank in current DODAG Version */
uint16_t parent_selection_timer;
rpl_dodag_version_t *last_advertised_dodag_version; /* Pointer to last DODAG version we advertised */
trickle_t dio_timer; /* Trickle timer for DIO transmission */
rpl_dao_root_transit_children_list_t root_children;
rpl_dao_target_list_t dao_targets; /* List of DAO targets */

View File

@ -1665,8 +1665,9 @@ void rpl_instance_dio_trigger(rpl_instance_t *instance, protocol_interface_info_
#endif
}
rpl_dodag_version_limit_greediness(dodag_version, rank);
instance->last_advertised_dodag_version = dodag_version;
if (rank != RPL_RANK_INFINITE) {
instance->advertised_dodag_membership_since_last_repair = true;
}
}
static void rpl_instance_dis_timer(rpl_instance_t *instance, uint16_t seconds)
@ -1715,6 +1716,7 @@ void rpl_instance_set_local_repair(rpl_instance_t *instance, bool repair)
instance->repair_dis_count = 0;
} else {
instance->repair_dis_timer = 0;
instance->advertised_dodag_membership_since_last_repair = false;
}
/* When repair ends, eliminate all higher-rank neighbours (potential sub-DODAG) from table */
@ -1839,7 +1841,7 @@ void rpl_upward_dio_timer(rpl_instance_t *instance, uint16_t ticks)
/* Delay sending first DIO if we are still potentially gathering info */
/* Important to always send DIOs if we ever have sent any, so we can indicate problems to others */
if (!rpl_instance_am_root(instance) && !instance->last_advertised_dodag_version && rpl_policy_parent_confirmation_requested()) {
if (!rpl_instance_am_root(instance) && !instance->poison_count && !instance->advertised_dodag_membership_since_last_repair && rpl_policy_parent_confirmation_requested()) {
// We don't have DAO target generated
if (ns_list_count(&instance->dao_targets) == 0) {

View File

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

View File

@ -195,7 +195,7 @@ void fhss_set_txrx_slot_length(fhss_structure_t *fhss_structure)
if (fhss_structure->ws->fhss_configuration.fhss_broadcast_interval == 0 || fhss_structure->ws->fhss_configuration.fhss_bc_dwell_interval == 0) {
return;
}
uint32_t txrx_slot_length_ms_tmp = WS_TXRX_SLOT_LEN_MS;
uint32_t txrx_slot_length_ms_tmp = WS_TXRX_SLOT_LEN_MS_MAX;
if (fhss_structure->callbacks.read_datarate) {
/* Calculate minimum TX slot length which can fit optimal packet length twice.
* Twice, because 0, 1, 4, 5... hop starts transmission at the beginning of TX slot and 2, 3, 6, 7... hop at the middle of TX slot
@ -217,9 +217,14 @@ void fhss_set_txrx_slot_length(fhss_structure_t *fhss_structure)
if (datarate) {
txrx_slot_length_ms_tmp = ((fhss_structure->optimal_packet_length * 2) * (8000000 / datarate)) / 1000;
// Do not allow using too high TX slot length.
if (txrx_slot_length_ms_tmp > WS_TXRX_SLOT_LEN_MS) {
tr_debug("TX slot length setting too high %"PRIu32"ms, using %"PRIu32"ms", txrx_slot_length_ms_tmp, (uint32_t)WS_TXRX_SLOT_LEN_MS);
txrx_slot_length_ms_tmp = WS_TXRX_SLOT_LEN_MS;
if (txrx_slot_length_ms_tmp > WS_TXRX_SLOT_LEN_MS_MAX) {
tr_debug("TX slot length setting too high %"PRIu32"ms, using %"PRIu32"ms", txrx_slot_length_ms_tmp, (uint32_t)WS_TXRX_SLOT_LEN_MS_MAX);
txrx_slot_length_ms_tmp = WS_TXRX_SLOT_LEN_MS_MAX;
}
// Do not allow using too low TX slot length.
if (txrx_slot_length_ms_tmp < WS_TXRX_SLOT_LEN_MS_MIN) {
tr_debug("TX slot length setting too low %"PRIu32"ms, using %"PRIu32"ms", txrx_slot_length_ms_tmp, (uint32_t)WS_TXRX_SLOT_LEN_MS_MIN);
txrx_slot_length_ms_tmp = WS_TXRX_SLOT_LEN_MS_MIN;
}
}
}
@ -241,14 +246,14 @@ static int32_t fhss_ws_calc_bc_channel(fhss_structure_t *fhss_structure)
int32_t next_channel = fhss_structure->ws->fhss_configuration.broadcast_fixed_channel;
if (fhss_structure->ws->fhss_configuration.ws_bc_channel_function == WS_TR51CF) {
next_channel = tr51_get_bc_channel_index(fhss_structure->ws->tr51_channel_table, fhss_structure->ws->tr51_output_table, fhss_structure->ws->bc_slot, fhss_structure->ws->fhss_configuration.bsi, fhss_structure->number_of_channels, NULL);
next_channel = tr51_get_bc_channel_index(fhss_structure->ws->tr51_channel_table, fhss_structure->ws->tr51_output_table, fhss_structure->ws->bc_slot, fhss_structure->ws->fhss_configuration.bsi, fhss_structure->number_of_bc_channels, NULL);
next_channel = fhss_channel_index_from_mask(fhss_structure->ws->fhss_configuration.channel_mask, next_channel, fhss_structure->number_of_channels);
if (++fhss_structure->ws->bc_slot == fhss_structure->number_of_channels) {
if (++fhss_structure->ws->bc_slot == fhss_structure->number_of_bc_channels) {
fhss_structure->ws->bc_slot = 0;
}
} else if (fhss_structure->ws->fhss_configuration.ws_bc_channel_function == WS_DH1CF) {
fhss_structure->ws->bc_slot++;
next_channel = dh1cf_get_bc_channel_index(fhss_structure->ws->bc_slot, fhss_structure->ws->fhss_configuration.bsi, fhss_structure->number_of_channels);
next_channel = dh1cf_get_bc_channel_index(fhss_structure->ws->bc_slot, fhss_structure->ws->fhss_configuration.bsi, fhss_structure->number_of_bc_channels);
next_channel = fhss_channel_index_from_mask(fhss_structure->ws->fhss_configuration.channel_mask, next_channel, fhss_structure->number_of_channels);
} else if (fhss_structure->ws->fhss_configuration.ws_bc_channel_function == WS_VENDOR_DEF_CF) {
if (fhss_structure->ws->fhss_configuration.vendor_defined_cf) {
@ -338,7 +343,7 @@ static void fhss_broadcast_handler(const fhss_api_t *fhss_api, uint16_t delay)
}
if (fhss_structure->ws->fhss_configuration.ws_bc_channel_function == WS_TR51CF) {
fhss_structure->ws->bc_slot %= fhss_structure->number_of_channels;
fhss_structure->ws->bc_slot %= fhss_structure->number_of_bc_channels;
}
if (fhss_structure->ws->is_on_bc_channel == false) {
@ -924,7 +929,7 @@ static uint32_t fhss_ws_get_retry_period_callback(const fhss_api_t *api, uint8_t
uint32_t cur_time_us = fhss_structure->callbacks.read_timestamp(fhss_structure->fhss_api);
uint32_t tx_trig_offset_us = (txrx_slot_length_us / 2) * calc_own_tx_trig_slot(fhss_structure->own_hop);
uint32_t next_tx_trig_slot_start_us = unicast_start_us + (txrx_slot_length_us * !fhss_ws_check_tx_allowed(fhss_structure)) + tx_trig_offset_us;
uint32_t next_tx_trig_slot_start_us = unicast_start_us + (txrx_slot_length_us * (fhss_structure->own_hop & 1)) + tx_trig_offset_us;
uint32_t next_tx_trig_slot_end_us = next_tx_trig_slot_start_us + (txrx_slot_length_us / 2);
while ((next_tx_trig_slot_start_us < cur_time_us) || ((next_tx_trig_slot_start_us - cur_time_us) > (uint32_t) MS_TO_US(fhss_structure->ws->fhss_configuration.fhss_broadcast_interval))) {
if (cur_time_us < next_tx_trig_slot_end_us) {
@ -1081,13 +1086,13 @@ 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_bc = 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) {
if (channel_count_bc <= 0 || fhss_configuration->channel_mask_size == 0) {
return -1;
}
if (fhss_structure->number_of_channels < channel_count ||
if (fhss_structure->number_of_bc_channels < channel_count_bc ||
(channel_count_uc && fhss_structure->number_of_uc_channels < channel_count_uc)) {
// Channel amount changed to largeneed to reallocate channel table
ns_dyn_mem_free(fhss_structure->ws->tr51_channel_table);
@ -1095,7 +1100,7 @@ int fhss_ws_configuration_set(fhss_structure_t *fhss_structure, const fhss_ws_co
ns_dyn_mem_free(fhss_structure->ws->tr51_output_table);
fhss_structure->ws->tr51_output_table = NULL;
if (fhss_ws_manage_channel_table_allocation(fhss_structure, channel_count_uc > channel_count ? channel_count_uc : channel_count)) {
if (fhss_ws_manage_channel_table_allocation(fhss_structure, channel_count_uc > channel_count_bc ? channel_count_uc : channel_count_bc)) {
return -1;
}
}
@ -1118,10 +1123,11 @@ int fhss_ws_configuration_set(fhss_structure_t *fhss_structure, const fhss_ws_co
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;
channel_count_uc = channel_count_bc;
}
fhss_structure->number_of_channels = channel_count;
fhss_structure->number_of_channels = fhss_configuration->channel_mask_size;
fhss_structure->number_of_bc_channels = channel_count_bc;
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;
@ -1132,7 +1138,7 @@ int fhss_ws_configuration_set(fhss_structure_t *fhss_structure, const fhss_ws_co
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_bc_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,

View File

@ -19,8 +19,10 @@
// TX slot length is optimised to this packet length
#define OPTIMAL_PACKET_LENGTH 500
// Default TX/RX slot length in milliseconds. Is used when datarate is not given by PHY.
#define WS_TXRX_SLOT_LEN_MS 100
// Max TX/RX slot length in milliseconds. Is used when datarate is not given by PHY or calculated slot length exceeds maximum allowed.
#define WS_TXRX_SLOT_LEN_MS_MAX 100
// Min TX/RX slot length in milliseconds. Is used when calculated slot length is under minimum allowed.
#define WS_TXRX_SLOT_LEN_MS_MIN 10
// Default minimum broadcast synchronization interval in seconds
#define DEFAULT_MIN_SYNCH_INTERVAL 60
// Drift compensation allowed if at least SYNCH_COMPENSATION_MIN_INTERVAL (seconds) since last synchronization

View File

@ -1,6 +1,7 @@
/**************************************************************************
*
* Copyright (c) 2017, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0
* Copyright 2011-2016 by Andrey Butok. FNET Community.
* Copyright 2008-2010 by Andrey Butok. Freescale Semiconductor, Inc.
*

View File

@ -1,6 +1,7 @@
/**************************************************************************
*
* Copyright (c) 2019 Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0
* Copyright 2011-2016 by Andrey Butok. FNET Community.
* Copyright 2008-2010 by Andrey Butok. Freescale Semiconductor, Inc.
*

View File

@ -1,6 +1,7 @@
/**************************************************************************
*
* Copyright (c) 2019 Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0
* Copyright 2011-2016 by Andrey Butok. FNET Community.
* Copyright 2008-2010 by Andrey Butok. Freescale Semiconductor, Inc.
*

View File

@ -1,6 +1,7 @@
/**************************************************************************
*
* Copyright (c) 2017, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0
* Copyright 2011-2016 by Andrey Butok. FNET Community.
* Copyright 2008-2010 by Andrey Butok. Freescale Semiconductor, Inc.
*

View File

@ -1,6 +1,7 @@
/**************************************************************************
*
* Copyright (c) 2017, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0
* Copyright 2011-2016 by Andrey Butok. FNET Community.
* Copyright 2008-2010 by Andrey Butok. Freescale Semiconductor, Inc.
*

View File

@ -1,6 +1,7 @@
/**************************************************************************
*
* Copyright (c) 2017, 2019 Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0
* Copyright 2016 by Andrey Butok. FNET Community.
*
***************************************************************************

View File

@ -1,6 +1,7 @@
/**************************************************************************
*
* Copyright (c) 2017, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0
* Copyright 2016 by Andrey Butok. FNET Community.
*
***************************************************************************

View File

@ -1,5 +1,6 @@
/**************************************************************************
* Copyright (c) 2017, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0
* Copyright 2011-2016 by Andrey Butok. FNET Community.
* Copyright 2008-2010 by Andrey Butok. Freescale Semiconductor, Inc.
*

View File

@ -1,6 +1,7 @@
/**************************************************************************
*
* Copyright (c) 2017, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0
* Copyright 2011-2016 by Andrey Butok. FNET Community.
* Copyright 2008-2010 by Andrey Butok. Freescale Semiconductor, Inc.
*

View File

@ -1,6 +1,7 @@
/**************************************************************************
*
* Copyright (c) 2017, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0
* Copyright 2011-2016 by Andrey Butok. FNET Community.
* Copyright 2008-2010 by Andrey Butok. Freescale Semiconductor, Inc.
*

View File

@ -1,6 +1,7 @@
/**************************************************************************
*
* Copyright (c) 2017, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0
* Copyright 2011-2016 by Andrey Butok. FNET Community.
* Copyright 2008-2010 by Freescale Semiconductor, Inc.
* Copyright 2003 by Motorola SPS.

View File

@ -17,7 +17,7 @@
#include "nsconfig.h"
#include "ns_types.h"
#include "eventOS_event.h"
#include "Core/include/ns_monitor.h"
#include "mac_api.h" // for mcps_packet_ingress_rate_limit_by_memory
#include "MAC/IEEE802_15_4/mac_mcps_sap.h" // for mcps_packet_ingress_rate_limit_by_memory