mirror of https://github.com/ARMmbed/mbed-os.git
Merge commit '02021856e4681bd5092e48b8513ff90fb5d6b1e9' into origin/nanostack_release_12_8_0_feature_wisun
* commit '02021856e4681bd5092e48b8513ff90fb5d6b1e9': Squashed 'features/nanostack/sal-stack-nanostack/' changes from 35b95da122..3183d87e41pull/14164/head
commit
07089272fa
File diff suppressed because it is too large
Load Diff
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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_ */
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
||||
/**
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
|
||||
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.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.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.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,9 +3096,9 @@ 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) {
|
||||
// Set timeout for check to 30 -60 seconds
|
||||
//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);
|
||||
}
|
||||
/* While in Join State 4, if a non Border Router determines it has been unable to communicate with the PAN Border
|
||||
|
@ -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;
|
||||
|
|
|
@ -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)) {
|
||||
// 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_mode = new_cfg->operating_mode;
|
||||
cur->ws_info->hopping_schdule.operating_class = new_cfg->operating_class;
|
||||
|
||||
if (ws_common_regulatory_domain_config(cur, &cur->ws_info->hopping_schdule) < 0) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -53,33 +53,57 @@ 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));
|
||||
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,30 +299,60 @@ 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->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;
|
||||
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;
|
||||
} 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 {
|
||||
return -1;
|
||||
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->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;
|
||||
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;
|
||||
} 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 {
|
||||
return -1;
|
||||
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) {
|
||||
|
@ -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,12 +413,22 @@ uint16_t ws_common_channel_number_calc(uint8_t regulatory_domain, uint8_t operat
|
|||
return 10;
|
||||
}
|
||||
} else if (regulatory_domain == REG_DOMAIN_NA) {
|
||||
if (operating_class == 1) {
|
||||
return 129;
|
||||
} else if (operating_class == 2) {
|
||||
return 64;
|
||||
} else if (operating_class == 3) {
|
||||
return 42;
|
||||
if (channel_plan_id == 255) {
|
||||
if (operating_class == 1) {
|
||||
return 129;
|
||||
} else if (operating_class == 2) {
|
||||
return 64;
|
||||
} else if (operating_class == 3) {
|
||||
return 42;
|
||||
}
|
||||
} else {
|
||||
if (channel_plan_id == 1) {
|
||||
return 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) {
|
||||
|
@ -285,12 +439,22 @@ uint16_t ws_common_channel_number_calc(uint8_t regulatory_domain, uint8_t operat
|
|||
return 12;
|
||||
}
|
||||
} else if (regulatory_domain == REG_DOMAIN_BZ) {
|
||||
if (operating_class == 1) {
|
||||
return 129;
|
||||
} else if (operating_class == 2) {
|
||||
return 64;
|
||||
} else if (operating_class == 3) {
|
||||
return 42;
|
||||
if (channel_plan_id == 255) {
|
||||
if (operating_class == 1) {
|
||||
return 129;
|
||||
} else if (operating_class == 2) {
|
||||
return 64;
|
||||
} else if (operating_class == 3) {
|
||||
return 42;
|
||||
}
|
||||
} else {
|
||||
if (channel_plan_id == 1) {
|
||||
return 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) {
|
||||
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
if (!buffer) {
|
||||
|
||||
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);
|
||||
tr_debug("macPD buffer allocate fail %u", pd_data_ind->data_len);
|
||||
#endif
|
||||
return NULL;
|
||||
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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
***************************************************************************
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright (c) 2017, Arm Limited and affiliates.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright 2016 by Andrey Butok. FNET Community.
|
||||
*
|
||||
***************************************************************************
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue