diff --git a/nanostack/net_interface.h b/nanostack/net_interface.h index 8b47bc6a4ac1..2062a76eb161 100644 --- a/nanostack/net_interface.h +++ b/nanostack/net_interface.h @@ -286,6 +286,12 @@ typedef struct { uint8_t *beacon_payload_tlv_ptr; /**< Optional steering parameters. */ } network_driver_setup_s; +/** CCA threshold table */ +typedef struct { + uint8_t number_of_channels; /**< Number of channels */ + const int8_t *cca_threshold_table; /**< CCA threshold table */ +} cca_threshold_table_s; + /** * Init 6LoWPAN library * @@ -1135,6 +1141,20 @@ extern int8_t arm_nwk_set_cca_threshold(int8_t interface_id, uint8_t cca_thresho */ extern int8_t arm_nwk_set_tx_output_power(int8_t interface_id, uint8_t tx_power); +/** + * \brief Get CCA threshold table. + * + * This function can be used to read CCA threshold table. + * CCA threshold table structure contains number of channels and an array indicating the currently used CCA threshold value of each channel. CCA threshold values are updated by library continuously. + * If channels are reconfigured, number of channels and table length are changed automatically. User should check the table length (number of channels) before reading the table. + * Automatic CCA threshold feature may not be enabled before interface is up, causing function to return NULL. + * Returned pointer to cca_threshold_table_s structure is valid until interface is destroyed. Re-reading the pointer with this function is allowed any time. + * + * \param interface_id Network interface ID. + * \return NULL if automatic CCA threshold feature is not enabled, otherwise pointer to CCA threshold structure. + */ +extern const cca_threshold_table_s *arm_nwk_get_cca_threshold_table(int8_t interface_id); + #ifdef __cplusplus } diff --git a/source/6LoWPAN/MAC/mac_helper.c b/source/6LoWPAN/MAC/mac_helper.c index 3475f87df387..ab5961f5f2a2 100644 --- a/source/6LoWPAN/MAC/mac_helper.c +++ b/source/6LoWPAN/MAC/mac_helper.c @@ -995,3 +995,23 @@ int8_t mac_helper_mac_device_description_pan_id_update(int8_t interface_id, uint cur->mac_api->mlme_req(cur->mac_api, MLME_SET, &set_req); return 0; } + +int8_t mac_helper_start_auto_cca_threshold(int8_t interface_id, uint8_t number_of_channels, int8_t default_dbm, int8_t high_limit, int8_t low_limit) +{ + protocol_interface_info_entry_t *cur; + cur = protocol_stack_interface_info_get_by_id(interface_id); + if (!cur || !cur->mac_api) { + return -1; + } + uint8_t start_cca_thr[4] = {number_of_channels, default_dbm, high_limit, low_limit}; + mlme_set_t set_req; + set_req.attr = macCCAThresholdStart; + set_req.value_pointer = &start_cca_thr; + set_req.value_size = sizeof(start_cca_thr); + cur->mac_api->mlme_req(cur->mac_api, MLME_SET, &set_req); + /* Get CCA threshold table. Table is stored to interface structure */ + mlme_get_t get_req; + get_req.attr = macCCAThreshold; + cur->mac_api->mlme_req(cur->mac_api, MLME_GET, &get_req); + return 0; +} diff --git a/source/6LoWPAN/MAC/mac_helper.h b/source/6LoWPAN/MAC/mac_helper.h index dbd5b13d647f..8c9c651cd1fd 100644 --- a/source/6LoWPAN/MAC/mac_helper.h +++ b/source/6LoWPAN/MAC/mac_helper.h @@ -134,4 +134,6 @@ int8_t mac_helper_mac_mlme_max_retry_set(int8_t interface_id, uint8_t mac_retry_ int8_t mac_helper_mac_device_description_pan_id_update(int8_t interface_id, uint16_t pan_id); +int8_t mac_helper_start_auto_cca_threshold(int8_t interface_id, uint8_t number_of_channels, int8_t default_dbm, int8_t high_limit, int8_t low_limit); + #endif // MAC_HELPER_H diff --git a/source/6LoWPAN/MAC/mac_response_handler.c b/source/6LoWPAN/MAC/mac_response_handler.c index 87d3003bbc68..68054aa1ce6a 100644 --- a/source/6LoWPAN/MAC/mac_response_handler.c +++ b/source/6LoWPAN/MAC/mac_response_handler.c @@ -81,6 +81,15 @@ static void mac_mlme_frame_counter_confirmation_handle(protocol_interface_info_e info_entry->mac_parameters->security_frame_counter = *temp_ptr; } +static void mac_mlme_cca_threshold_confirmation_handle(protocol_interface_info_entry_t *info_entry, mlme_get_conf_t *confirmation) +{ + if (confirmation->value_size < 1) { + return; + } + info_entry->mac_parameters->cca_thr_table.number_of_channels = confirmation->value_size; + info_entry->mac_parameters->cca_thr_table.cca_threshold_table = (int8_t *)confirmation->value_pointer; +} + static void mac_mlme_get_confirmation_handler(protocol_interface_info_entry_t *info_entry, mlme_get_conf_t *confirmation) { @@ -96,6 +105,10 @@ static void mac_mlme_get_confirmation_handler(protocol_interface_info_entry_t *i mac_mlme_frame_counter_confirmation_handle(info_entry, confirmation); break; + case macCCAThreshold: + mac_mlme_cca_threshold_confirmation_handle(info_entry, confirmation); + break; + default: break; diff --git a/source/6LoWPAN/ws/ws_bootstrap.c b/source/6LoWPAN/ws/ws_bootstrap.c index 3065a6a22b7f..6bd10d5aa613 100644 --- a/source/6LoWPAN/ws/ws_bootstrap.c +++ b/source/6LoWPAN/ws/ws_bootstrap.c @@ -2135,11 +2135,7 @@ int ws_bootstrap_set_rf_config(protocol_interface_info_entry_t *cur, phy_rf_chan set_request.value_size = sizeof(mlme_multi_csma_ca_param_t); cur->mac_api->mlme_req(cur->mac_api, MLME_SET, &set_request); // Start automatic CCA threshold - uint8_t start_cca_thr[4] = {cur->ws_info->hopping_schdule.number_of_channels, CCA_DEFAULT_DBM, CCA_HIGH_LIMIT, CCA_LOW_LIMIT}; - set_request.attr = macCCAThresholdStart; - set_request.value_pointer = &start_cca_thr; - set_request.value_size = sizeof(start_cca_thr); - cur->mac_api->mlme_req(cur->mac_api, MLME_SET, &set_request); + mac_helper_start_auto_cca_threshold(cur->id, cur->ws_info->hopping_schdule.number_of_channels, CCA_DEFAULT_DBM, CCA_HIGH_LIMIT, CCA_LOW_LIMIT); return 0; } diff --git a/source/MAC/IEEE802_15_4/mac_cca_threshold.c b/source/MAC/IEEE802_15_4/mac_cca_threshold.c index 33b9b274107e..ffb40f16bf52 100644 --- a/source/MAC/IEEE802_15_4/mac_cca_threshold.c +++ b/source/MAC/IEEE802_15_4/mac_cca_threshold.c @@ -140,3 +140,11 @@ int8_t mac_cca_threshold_update(protocol_interface_rf_mac_setup_s *rf_ptr, uint8 tr_debug("Channel %u CCA threshold to %i", channel, rf_ptr->cca_threshold->ch_thresholds[channel]); return 0; } + +mac_cca_threshold_s *mac_get_cca_threshold_table(protocol_interface_rf_mac_setup_s *rf_ptr) +{ + if (!rf_ptr->cca_threshold) { + return NULL; + } + return rf_ptr->cca_threshold; +} diff --git a/source/MAC/IEEE802_15_4/mac_cca_threshold.h b/source/MAC/IEEE802_15_4/mac_cca_threshold.h index a2081ba5883e..6e0da89bd058 100644 --- a/source/MAC/IEEE802_15_4/mac_cca_threshold.h +++ b/source/MAC/IEEE802_15_4/mac_cca_threshold.h @@ -49,6 +49,7 @@ int8_t mac_cca_thr_deinit(protocol_interface_rf_mac_setup_s *rf_ptr); /** * @brief Read CCA threshold of specific channel. + * @param rf_ptr Pointer to MAC instance. * @param channel Channel. * @return CCA threshold (dBm), CCA_FAILED_DBM Feature not enabled. */ @@ -56,10 +57,18 @@ int8_t mac_cca_thr_get_dbm(protocol_interface_rf_mac_setup_s *rf_ptr, uint8_t ch /** * @brief Update CCA threshold of specific channel. + * @param rf_ptr Pointer to MAC instance. * @param channel Channel. * @param dbm CCA threshold (dBm). * @return 0 Updated, negative Already using this value. */ int8_t mac_cca_threshold_update(protocol_interface_rf_mac_setup_s *rf_ptr, uint8_t channel, int8_t dbm); +/** + * @brief Get pointer to CCA threshold table. + * @param rf_ptr Pointer to MAC instance. + * @return CCA threshold table. + */ +mac_cca_threshold_s *mac_get_cca_threshold_table(protocol_interface_rf_mac_setup_s *rf_ptr); + #endif /* MAC_CCA_THRESHOLD_H_ */ diff --git a/source/MAC/IEEE802_15_4/mac_mlme.c b/source/MAC/IEEE802_15_4/mac_mlme.c index d8db1d60f668..e1e2e4d34382 100644 --- a/source/MAC/IEEE802_15_4/mac_mlme.c +++ b/source/MAC/IEEE802_15_4/mac_mlme.c @@ -878,7 +878,7 @@ int8_t mac_mlme_get_req(struct protocol_interface_rf_mac_setup *rf_mac_setup, ml if (!get_req || !rf_mac_setup) { return -1; } - + mac_cca_threshold_s *cca_thr_table = NULL; switch (get_req->attr) { case macDeviceTable: get_req->value_pointer = mac_sec_mib_device_description_get_attribute_index(rf_mac_setup, get_req->attr_index); @@ -908,6 +908,12 @@ int8_t mac_mlme_get_req(struct protocol_interface_rf_mac_setup *rf_mac_setup, ml get_req->value_size = 4; break; + case macCCAThreshold: + cca_thr_table = mac_get_cca_threshold_table(rf_mac_setup); + get_req->value_size = cca_thr_table->number_of_channels; + get_req->value_pointer = cca_thr_table->ch_thresholds; + break; + default: get_req->status = MLME_UNSUPPORTED_ATTRIBUTE; break; diff --git a/source/NWK_INTERFACE/Include/protocol.h b/source/NWK_INTERFACE/Include/protocol.h index 2a1b3fbbf975..9880a5d2cc8a 100644 --- a/source/NWK_INTERFACE/Include/protocol.h +++ b/source/NWK_INTERFACE/Include/protocol.h @@ -238,6 +238,7 @@ typedef struct arm_15_4_mac_parameters_t { uint16_t pan_id; uint16_t mac_short_address; mac_cordinator_s mac_cordinator_info; + cca_threshold_table_s cca_thr_table; uint8_t number_of_fhss_channel_retries; /* MAC Beacon info */ uint8_t *mac_beacon_payload; diff --git a/source/libNET/src/ns_net.c b/source/libNET/src/ns_net.c index caf446493f1b..ed35581c5e79 100644 --- a/source/libNET/src/ns_net.c +++ b/source/libNET/src/ns_net.c @@ -1570,3 +1570,18 @@ int8_t arm_nwk_set_tx_output_power(int8_t interface_id, uint8_t tx_power) cur->mac_api->mlme_req(cur->mac_api, MLME_SET, &set_req); return 0; } + +const cca_threshold_table_s *arm_nwk_get_cca_threshold_table(int8_t interface_id) +{ + protocol_interface_info_entry_t *cur; + cur = protocol_stack_interface_info_get_by_id(interface_id); + // Interface or MAC parameters not initialized + if (!cur || !cur->mac_parameters) { + return NULL; + } + // Automatic CCA threshold not initialized + if (!cur->mac_parameters->cca_thr_table.cca_threshold_table || !cur->mac_parameters->cca_thr_table.number_of_channels) { + return NULL; + } + return &cur->mac_parameters->cca_thr_table; +} diff --git a/test/nanostack/unittest/stub/mac_cca_threshold_stub.c b/test/nanostack/unittest/stub/mac_cca_threshold_stub.c index f1c88fb7220d..e71c16680a67 100644 --- a/test/nanostack/unittest/stub/mac_cca_threshold_stub.c +++ b/test/nanostack/unittest/stub/mac_cca_threshold_stub.c @@ -21,8 +21,9 @@ #include "ns_list.h" #include "ns_trace.h" #include "mac_defines.h" +#include "mac_cca_threshold.h" -int8_t mac_cca_threshold_update(protocol_interface_rf_mac_setup_s *rf_ptr, uint16_t event_data) +int8_t mac_cca_threshold_update(protocol_interface_rf_mac_setup_s *rf_ptr, uint8_t channel, int8_t dbm) { return 0; } @@ -41,3 +42,8 @@ int8_t mac_cca_thr_get_dbm(protocol_interface_rf_mac_setup_s *rf_ptr, uint8_t ch { return 0; } + +mac_cca_threshold_s *mac_get_cca_threshold_table(protocol_interface_rf_mac_setup_s *rf_ptr) +{ + return NULL; +}