diff --git a/components/802.15.4_RF/atmel-rf-driver/atmel-rf-driver/NanostackRfPhyAtmel.h b/components/802.15.4_RF/atmel-rf-driver/atmel-rf-driver/NanostackRfPhyAtmel.h index 028663f63e..d6fab5cf5d 100644 --- a/components/802.15.4_RF/atmel-rf-driver/atmel-rf-driver/NanostackRfPhyAtmel.h +++ b/components/802.15.4_RF/atmel-rf-driver/atmel-rf-driver/NanostackRfPhyAtmel.h @@ -70,9 +70,16 @@ #if !defined(TEST_PIN_SPARE_2) #define TEST_PIN_SPARE_2 D8 #endif +#if !defined(SE2435L_CSD) +#define SE2435L_CSD D2 +#endif +#if !defined(SE2435L_ANT_SEL) +#define SE2435L_ANT_SEL D8 +#endif class RFBits; class TestPins; +class Se2435Pins; class NanostackRfPhyAtmel : public NanostackRfPhy { public: @@ -86,10 +93,13 @@ public: virtual void set_mac_address(uint8_t *mac); private: +#if !defined(DISABLE_AT24MAC) AT24Mac _mac; +#endif uint8_t _mac_addr[8]; RFBits *_rf; TestPins *_test_pins; + Se2435Pins *_se2435_pa_pins; bool _mac_set; const PinName _spi_mosi; diff --git a/components/802.15.4_RF/atmel-rf-driver/source/AT86RF215Reg.h b/components/802.15.4_RF/atmel-rf-driver/source/AT86RF215Reg.h index 70555ac63f..6836b0cb3f 100644 --- a/components/802.15.4_RF/atmel-rf-driver/source/AT86RF215Reg.h +++ b/components/802.15.4_RF/atmel-rf-driver/source/AT86RF215Reg.h @@ -26,6 +26,7 @@ extern "C" { #define RF24_IRQS 0x01 #define BBC0_IRQS 0x02 #define BBC1_IRQS 0x03 +#define RF_AUXS 0x01 #define RF_CFG 0x06 #define RF_IQIFC1 0x0B #define RF_PN 0x0D @@ -47,6 +48,8 @@ extern "C" { #define RF_EDV 0x10 #define RF_TXCUTC 0x12 #define RF_TXDFE 0x13 +#define RF_PAC 0x14 +#define RF_PADFE 0x16 #define BBC_IRQM 0x00 #define BBC_PC 0x01 #define BBC_RXFLL 0x04 @@ -85,6 +88,20 @@ extern "C" { #define BBC1_FBRXS 0x3000 #define BBC1_FBTXS 0x3800 +// RF_AUXS +#define EXTLNABYP (1 << 7) +#define AGCMAP 0x60 +#define AGCMAP_2 (2 << 5) +#define AVEN (1 << 3) + +// RF_PAC +#define TXPWR 0x1F +#define TXPWR_11 (11 << 0) + +// RF_PADFE +#define PADFE 0xC0 +#define RF_FEMODE3 (3 << 6) + // RF_AGCC #define AGCI (1 << 6) #define AVGS 0x30 @@ -95,7 +112,6 @@ extern "C" { #define TGT_1 (1 << 5) #define TGT_3 (3 << 5) - // RF_RXBWC #define BW 0x0F #define RF_BW2000KHZ_IF2000KHZ (11 << 0) diff --git a/components/802.15.4_RF/atmel-rf-driver/source/AT86RFReg.h b/components/802.15.4_RF/atmel-rf-driver/source/AT86RFReg.h index c53d9fe922..fb86b7119b 100644 --- a/components/802.15.4_RF/atmel-rf-driver/source/AT86RFReg.h +++ b/components/802.15.4_RF/atmel-rf-driver/source/AT86RFReg.h @@ -48,6 +48,7 @@ extern "C" { #define PART_AT86RF212 0x07 #define PART_AT86RF233 0x0B #define PART_AT86RF215 0x34 +#define PART_AT86RF215M 0x36 #define VERSION_AT86RF212 0x01 #define VERSION_AT86RF212B 0x03 diff --git a/components/802.15.4_RF/atmel-rf-driver/source/NanostackRfPhyAT86RF215.cpp b/components/802.15.4_RF/atmel-rf-driver/source/NanostackRfPhyAT86RF215.cpp index a48abf6c90..488b337527 100644 --- a/components/802.15.4_RF/atmel-rf-driver/source/NanostackRfPhyAT86RF215.cpp +++ b/components/802.15.4_RF/atmel-rf-driver/source/NanostackRfPhyAT86RF215.cpp @@ -23,6 +23,7 @@ #include "platform/mbed_wait_api.h" #include "nanostack/platform/arm_hal_phy.h" #include "NanostackRfPhyAtmel.h" +#include "AT86RFReg.h" #include "AT86RF215Reg.h" #include "mbed_trace.h" #include "common_functions.h" @@ -165,6 +166,7 @@ using namespace rtos; #include "rfbits.h" static RFBits *rf; static TestPins *test_pins; +static Se2435Pins *se2435_pa_pins = NULL; #define MAC_FRAME_TYPE_MASK 0x07 #define MAC_TYPE_ACK (2) @@ -464,6 +466,18 @@ static void rf_init_registers(rf_modules_e module) rf_write_rf_register_field(RF_AGCS, module, TGT, TGT_3); } } + if (se2435_pa_pins) { + // Wakeup SE2435L + se2435_pa_pins->CSD = 1; + // Antenna port selection: (0 - port 1, 1 - port 2) + se2435_pa_pins->ANT_SEL = 0; + // Enable external front end with configuration 3 + rf_write_rf_register_field(RF_PADFE, module, PADFE, RF_FEMODE3); + // Output power at 900MHz: 0 dBm with FSK/QPSK, less than -5 dBm with OFDM + rf_write_rf_register_field(RF_PAC, module, TXPWR, TXPWR_11); + } + // Enable analog voltage regulator + rf_write_rf_register_field(RF_AUXS, module, AVEN, AVEN); // Disable filtering FCS rf_write_bbc_register_field(BBC_PC, module, FCSFE, 0); // Set channel spacing @@ -1189,10 +1203,28 @@ int RFBits::init_215_driver(RFBits *_rf, TestPins *_test_pins, const uint8_t mac test_pins = _test_pins; irq_thread_215.start(mbed::callback(this, &RFBits::rf_irq_task)); rf->spi.frequency(25000000); + /* Atmel AT86RF215 Device Family datasheet: + * Errata #9: RF215M device has a wrong part number + * Description: + * The RF215M device part number is 0x34 instead of 0x36 (register RF_PN.PN). + */ +#if !defined(HAVE_AT86RF215M) *rf_part_num = rf_read_common_register(RF_PN); +#else + *rf_part_num = PART_AT86RF215M; + // AT86RF215M is Sub-GHz only transceiver. Change default settings. + rf_module = RF_09; + mac_mode = IEEE_802_15_4G_2012; +#endif rf_version_num = rf_read_common_register(RF_VN); tr_info("RF version number: %x", rf_version_num); return rf_device_register(mac); } +int RFBits::init_se2435_pa(Se2435Pins *_se2435_pa_pins) +{ + se2435_pa_pins = _se2435_pa_pins; + return 0; +} + #endif // MBED_CONF_NANOSTACK_CONFIGURATION && DEVICE_SPI && DEVICE_INTERRUPTIN && defined(MBED_CONF_RTOS_PRESENT) diff --git a/components/802.15.4_RF/atmel-rf-driver/source/NanostackRfPhyAtmel.cpp b/components/802.15.4_RF/atmel-rf-driver/source/NanostackRfPhyAtmel.cpp index e747af742d..ef3ce7f447 100644 --- a/components/802.15.4_RF/atmel-rf-driver/source/NanostackRfPhyAtmel.cpp +++ b/components/802.15.4_RF/atmel-rf-driver/source/NanostackRfPhyAtmel.cpp @@ -275,8 +275,15 @@ TestPins::TestPins(PinName test_pin_1, PinName test_pin_2, PinName test_pin_3, P { } +Se2435Pins::Se2435Pins(PinName csd_pin, PinName ant_sel_pin) + : CSD(csd_pin), + ANT_SEL(ant_sel_pin) +{ +} + static RFBits *rf; static TestPins *test_pins; +static Se2435Pins *se2435_pa_pins; static uint8_t rf_part_num = 0; /*TODO: RSSI Base value setting*/ static int8_t rf_rssi_base_val = -91; @@ -2168,14 +2175,21 @@ static uint8_t rf_scale_lqi(int8_t rssi) NanostackRfPhyAtmel::NanostackRfPhyAtmel(PinName spi_mosi, PinName spi_miso, PinName spi_sclk, PinName spi_cs, PinName spi_rst, PinName spi_slp, PinName spi_irq, PinName i2c_sda, PinName i2c_scl) - : _mac(i2c_sda, i2c_scl), _mac_addr(), _rf(NULL), _test_pins(NULL), _mac_set(false), - _spi_mosi(spi_mosi), _spi_miso(spi_miso), _spi_sclk(spi_sclk), - _spi_cs(spi_cs), _spi_rst(spi_rst), _spi_slp(spi_slp), _spi_irq(spi_irq) + : +#if !defined(DISABLE_AT24MAC) + _mac(i2c_sda, i2c_scl), +#endif + _mac_addr(), _rf(NULL), _test_pins(NULL), _se2435_pa_pins(NULL), _mac_set(false), + _spi_mosi(spi_mosi), _spi_miso(spi_miso), _spi_sclk(spi_sclk), + _spi_cs(spi_cs), _spi_rst(spi_rst), _spi_slp(spi_slp), _spi_irq(spi_irq) { _rf = new RFBits(_spi_mosi, _spi_miso, _spi_sclk, _spi_cs, _spi_rst, _spi_slp, _spi_irq); #ifdef TEST_GPIOS_ENABLED _test_pins = new TestPins(TEST_PIN_TX, TEST_PIN_RX, TEST_PIN_CSMA, TEST_PIN_SPARE_1, TEST_PIN_SPARE_2); #endif +#ifdef SE2435L_PA + _se2435_pa_pins = new Se2435Pins(SE2435L_CSD, SE2435L_ANT_SEL); +#endif } NanostackRfPhyAtmel::~NanostackRfPhyAtmel() @@ -2200,19 +2214,29 @@ int8_t NanostackRfPhyAtmel::rf_register() // Read the mac address if it hasn't been set by a user rf = _rf; test_pins = _test_pins; + se2435_pa_pins = _se2435_pa_pins; if (!_mac_set) { +// Unless AT24MAC is available, using randomly generated MAC address +#if !defined(DISABLE_AT24MAC) int ret = _mac.read_eui64((void *)_mac_addr); if (ret < 0) { rf = NULL; rf_if_unlock(); return -1; } +#else + randLIB_seed_random(); + randLIB_get_n_bytes_random(_mac_addr, 8); + _mac_addr[0] |= 2; //Set Local Bit + _mac_addr[0] &= ~1; //Clear multicast bit +#endif } /*Reset RF module*/ rf_if_reset_radio(); rf_part_num = rf_if_read_part_num(); int8_t radio_id = -1; if (rf_part_num != PART_AT86RF231 && rf_part_num != PART_AT86RF233 && rf_part_num != PART_AT86RF212) { + rf->init_se2435_pa(_se2435_pa_pins); // Register RF type 215. Jumps to AT86RF215 driver. radio_id = rf->init_215_driver(_rf, _test_pins, _mac_addr, &rf_part_num); } else { diff --git a/components/802.15.4_RF/atmel-rf-driver/source/rfbits.h b/components/802.15.4_RF/atmel-rf-driver/source/rfbits.h index 94143e6a8b..e9b17b2ea8 100644 --- a/components/802.15.4_RF/atmel-rf-driver/source/rfbits.h +++ b/components/802.15.4_RF/atmel-rf-driver/source/rfbits.h @@ -51,6 +51,7 @@ public: Timeout cca_timer; Timer tx_timer; int init_215_driver(RFBits *_rf, TestPins *_test_pins, const uint8_t mac[8], uint8_t *rf_part_num); + int init_se2435_pa(Se2435Pins *_se2435_pa_pins); #ifdef MBED_CONF_RTOS_PRESENT Thread irq_thread; Thread irq_thread_215; @@ -70,4 +71,11 @@ public: DigitalOut TEST5; }; +class Se2435Pins { +public: + Se2435Pins(PinName csd_pin, PinName ant_sel_pin); + DigitalOut CSD; + DigitalOut ANT_SEL; +}; + #endif /* RFBITS_H_ */ diff --git a/components/802.15.4_RF/stm-s2lp-rf-driver/mbed_lib.json b/components/802.15.4_RF/stm-s2lp-rf-driver/mbed_lib.json index 80c1ad14b8..55e4bf1748 100644 --- a/components/802.15.4_RF/stm-s2lp-rf-driver/mbed_lib.json +++ b/components/802.15.4_RF/stm-s2lp-rf-driver/mbed_lib.json @@ -1,17 +1,73 @@ { "name": "s2lp", "config": { + "SPI_SDI": { + "help": "SPI_SDI pin for SPI connection. D11 assumed, needs to be set/overwritten otherwise", + "value": null + }, + "SPI_SDO": { + "help": "SPI_SDO pin for SPI connection. D12 assumed, needs to be set/overwritten otherwise", + "value": null + }, + "SPI_SCLK": { + "help": "SPI_SCLK pin for SPI connection, D13 assumed, needs to be set/overwritten otherwise", + "value": null + }, + "SPI_CS": { + "help": "SPI_CS pin for SPI connection, A1 assumed, needs to be set/overwritten otherwise", + "value": null + }, + "SPI_SDN": { + "help": "SPI_SDN pin for SPI connection, D7 assumed, needs to be set/overwritten otherwise", + "value": null + }, + "TEST_PIN_TX": { + "help": "TEST_PIN_TX pin for serial connection, D6 assumed, needs to be set/overwritten otherwise", + "value": null + }, + "TEST_PIN_RX": { + "help": "TEST_PIN_RX pin for serial connection, D5 assumed, needs to be set/overwritten otherwise", + "value": null + }, + "TEST_PIN_CSMA": { + "help": "TEST_PIN_CSMA pin for CSMA, D4 assumed, needs to be set/overwritten otherwise", + "value": null + }, + "TEST_PIN_SPARE_1": { + "help": "TEST_PIN_SPARE_1 pin for testing, D2 assumed, needs to be set/overwritten otherwise", + "value": null + }, + "TEST_PIN_SPARE_2": { + "help": "TEST_PIN_SPARE_2 pin for testing, D8 assumed, needs to be set/overwritten otherwise", + "value": null + }, + "SPI_GPIO0": { + "help": "SPI_GPIO0 pin for GPIO testing, A0 assumed, needs to be set/overwritten otherwise", + "value": null + }, + "SPI_GPIO1": { + "help": "SPI_GPIO1 pin for GPIO testing, A2 assumed, needs to be set/overwritten otherwise", + "value": null + }, + "SPI_GPIO2": { + "help": "SPI_GPIO2 pin for GPIO testing, A3 assumed, needs to be set/overwritten otherwise", + "value": null + }, + "SPI_GPIO3": { + "help": "SPI_GPIO3 pin for GPIO testing, A5 assumed, needs to be set/overwritten otherwise", + "value": null + }, + "I2C_SDA": { + "help": "I2C_SDA pin for I2C SDA, null assumed, needs to be set/overwritten otherwise", + "value": null + }, + "I2C_SCL": { + "help": "I2C_SCL pin for I2C SCL, null assumed, needs to be set/overwritten otherwise", + "value": null + }, "provide-default": { "help": "Provide default NanostackRfpy. [true/false]", "value": false - }, - "target_overrides": { - "MTB_STM_S2LP": { - "s2lp.provide-default": true - }, - "MTB_STM_S2LP_CT": { - "s2lp.provide-default": true - } } } } diff --git a/components/802.15.4_RF/stm-s2lp-rf-driver/source/NanostackRfPhys2lp.cpp b/components/802.15.4_RF/stm-s2lp-rf-driver/source/NanostackRfPhys2lp.cpp index 10d8e86376..720a0535ec 100644 --- a/components/802.15.4_RF/stm-s2lp-rf-driver/source/NanostackRfPhys2lp.cpp +++ b/components/802.15.4_RF/stm-s2lp-rf-driver/source/NanostackRfPhys2lp.cpp @@ -182,7 +182,9 @@ static bool rf_rx_filter(uint8_t *mac_header, uint8_t *mac_64bit_addr, uint8_t * static void rf_cca_timer_start(uint32_t slots); static RFPins *rf; +#ifdef TEST_GPIOS_ENABLED static TestPins_S2LP *test_pins; +#endif static phy_device_driver_s device_driver; static int8_t rf_radio_driver_id = -1; static uint8_t *tx_data_ptr; @@ -707,7 +709,7 @@ static int8_t rf_extension(phy_extension_type_e extension_type, uint8_t *data_pt break; case PHY_EXTENSION_SET_CHANNEL_CCA_THRESHOLD: if ((rssi_threshold != (int8_t)*data_ptr) && (rf_state != RF_RX_STARTED)) { - rssi_threshold = (int8_t)*data_ptr; + rssi_threshold = (int8_t)*data_ptr; // *NOPAD* rf_update_cca_threshold = true; rf_receive(rf_rx_channel); } @@ -760,9 +762,9 @@ static void rf_tx_sent_handler(void) TEST_TX_DONE rf_backup_timer_stop(); rf_disable_interrupt(TX_DATA_SENT); + rf_update_tx_active_time(); if (rf_state != RF_TX_ACK) { tx_finnish_time = rf_get_timestamp(); - rf_update_tx_active_time(); rf_state = RF_IDLE; rf_receive(rf_rx_channel); if (device_driver.phy_tx_done_cb) { @@ -829,7 +831,6 @@ static void rf_cca_timer_interrupt(void) } rf_flush_tx_fifo(); tx_finnish_time = rf_get_timestamp(); - rf_update_tx_active_time(); if (device_driver.phy_tx_done_cb) { device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle, PHY_LINK_CCA_FAIL, 0, 0); } @@ -963,7 +964,6 @@ static void rf_handle_ack(uint8_t seq_number, uint8_t pending) phy_link_tx_status_e phy_status; if (tx_sequence == (uint16_t)seq_number) { tx_finnish_time = rf_get_timestamp(); - rf_update_tx_active_time(); if (pending) { phy_status = PHY_LINK_TX_DONE_PENDING; } else { @@ -1294,7 +1294,9 @@ int8_t NanostackRfPhys2lp::rf_register() } rf = _rf; +#ifdef TEST_GPIOS_ENABLED test_pins = _test_pins; +#endif int8_t radio_id = rf_device_register(_mac_addr); if (radio_id < 0) { @@ -1317,18 +1319,18 @@ void NanostackRfPhys2lp::rf_unregister() } NanostackRfPhys2lp::NanostackRfPhys2lp(PinName spi_sdi, PinName spi_sdo, PinName spi_sclk, PinName spi_cs, PinName spi_sdn - ,PinName spi_gpio0, PinName spi_gpio1, PinName spi_gpio2, PinName spi_gpio3 + , PinName spi_gpio0, PinName spi_gpio1, PinName spi_gpio2, PinName spi_gpio3 #ifdef AT24MAC - ,PinName i2c_sda, PinName i2c_scl + , PinName i2c_sda, PinName i2c_scl #endif //AT24MAC - ) + ) : #ifdef AT24MAC - _mac(i2c_sda, i2c_scl), + _mac(i2c_sda, i2c_scl), #endif //AT24MAC - _mac_addr(), _rf(NULL), _mac_set(false), - _spi_sdi(spi_sdi), _spi_sdo(spi_sdo), _spi_sclk(spi_sclk), _spi_cs(spi_cs), _spi_sdn(spi_sdn), - _spi_gpio0(spi_gpio0), _spi_gpio1(spi_gpio1), _spi_gpio2(spi_gpio2), _spi_gpio3(spi_gpio3) + _mac_addr(), _rf(NULL), _mac_set(false), + _spi_sdi(spi_sdi), _spi_sdo(spi_sdo), _spi_sclk(spi_sclk), _spi_cs(spi_cs), _spi_sdn(spi_sdn), + _spi_gpio0(spi_gpio0), _spi_gpio1(spi_gpio1), _spi_gpio2(spi_gpio2), _spi_gpio3(spi_gpio3) { _rf = new RFPins(_spi_sdi, _spi_sdo, _spi_sclk, _spi_cs, _spi_sdn, _spi_gpio0, _spi_gpio1, _spi_gpio2, _spi_gpio3); #ifdef TEST_GPIOS_ENABLED @@ -1438,11 +1440,11 @@ static bool rf_rx_filter(uint8_t *mac_header, uint8_t *mac_64bit_addr, uint8_t * NanostackRfPhy &NanostackRfPhy::get_default_instance() { static NanostackRfPhys2lp rf_phy(S2LP_SPI_SDI, S2LP_SPI_SDO, S2LP_SPI_SCLK, S2LP_SPI_CS, S2LP_SPI_SDN - ,S2LP_SPI_GPIO0, S2LP_SPI_GPIO1, S2LP_SPI_GPIO2, S2LP_SPI_GPIO3 + , S2LP_SPI_GPIO0, S2LP_SPI_GPIO1, S2LP_SPI_GPIO2, S2LP_SPI_GPIO3 #ifdef AT24MAC - ,S2LP_I2C_SDA, S2LP_I2C_SCL + , S2LP_I2C_SDA, S2LP_I2C_SCL #endif //AT24MAC - ); + ); return rf_phy; } #endif // MBED_CONF_S2LP_PROVIDE_DEFAULT diff --git a/components/802.15.4_RF/stm-s2lp-rf-driver/source/rf_configuration.c b/components/802.15.4_RF/stm-s2lp-rf-driver/source/rf_configuration.c index 3cb0c2b6a1..9f261ee02d 100644 --- a/components/802.15.4_RF/stm-s2lp-rf-driver/source/rf_configuration.c +++ b/components/802.15.4_RF/stm-s2lp-rf-driver/source/rf_configuration.c @@ -157,7 +157,7 @@ void rf_conf_calculate_rx_filter_bandwidth_registers(uint32_t rx_bandwidth, uint int16_t rf_conf_cca_threshold_percent_to_rssi(uint8_t percent) { - uint8_t step = (MAX_RSSI_THRESHOLD-MIN_RSSI_THRESHOLD); + uint8_t step = (MAX_RSSI_THRESHOLD - MIN_RSSI_THRESHOLD); return MIN_RSSI_THRESHOLD + (step * percent) / 100; } diff --git a/components/802.15.4_RF/stm-s2lp-rf-driver/stm-s2lp-rf-driver/NanostackRfPhys2lp.h b/components/802.15.4_RF/stm-s2lp-rf-driver/stm-s2lp-rf-driver/NanostackRfPhys2lp.h index d83fb25c8d..280aa3ddba 100644 --- a/components/802.15.4_RF/stm-s2lp-rf-driver/stm-s2lp-rf-driver/NanostackRfPhys2lp.h +++ b/components/802.15.4_RF/stm-s2lp-rf-driver/stm-s2lp-rf-driver/NanostackRfPhys2lp.h @@ -25,87 +25,100 @@ #include "InterruptIn.h" #include "SPI.h" -// Uncomment to use testing gpios attached to TX/RX processes -// #define TEST_GPIOS_ENABLED - -#if defined(TARGET_MTB_STM_S2LP) || defined(TARGET_MTB_STM_S2LP_CT) -#if !defined(S2LP_SPI_SDI) -#define S2LP_SPI_SDI PA_7 -#endif -#if !defined(S2LP_SPI_SDO) -#define S2LP_SPI_SDO PA_6 -#endif -#if !defined(S2LP_SPI_SCLK) -#define S2LP_SPI_SCLK PA_5 -#endif -#if !defined(S2LP_SPI_CS) -#define S2LP_SPI_CS PC_0 -#endif -#if !defined(S2LP_SPI_SDN) -#define S2LP_SPI_SDN PF_13 -#endif -#if !defined(S2LP_SPI_GPIO0) -#define S2LP_SPI_GPIO0 PA_3 -#endif -#if !defined(S2LP_SPI_GPIO1) -#define S2LP_SPI_GPIO1 PC_3 -#endif -#if !defined(S2LP_SPI_GPIO2) -#define S2LP_SPI_GPIO2 PF_3 -#endif -#if !defined(S2LP_SPI_GPIO3) -#define S2LP_SPI_GPIO3 PF_10 -#endif -#if !defined(S2LP_I2C_SDA) -#define S2LP_I2C_SDA PB_7 -#endif -#if !defined(S2LP_I2C_SCL) -#define S2LP_I2C_SCL PB_6 -#endif -#define AT24MAC +#if defined(MBED_CONF_S2LP_SPI_SDI) +#define S2LP_SPI_SDI MBED_CONF_S2LP_SPI_SDI #else -#if !defined(S2LP_SPI_SDI) -#define S2LP_SPI_SDI D11 +#define S2LP_SPI_SDI D11 #endif -#if !defined(S2LP_SPI_SDO) -#define S2LP_SPI_SDO D12 + +#if defined(MBED_CONF_S2LP_SPI_SDO) +#define S2LP_SPI_SDO MBED_CONF_S2LP_SPI_SDO +#else +#define S2LP_SPI_SDO D12 #endif -#if !defined(S2LP_SPI_SCLK) -#define S2LP_SPI_SCLK D13 + +#if defined(MBED_CONF_S2LP_SPI_SCLK) +#define S2LP_SPI_SCLK MBED_CONF_S2LP_SPI_SCLK +#else +#define S2LP_SPI_SCLK D13 #endif -#if !defined(S2LP_SPI_CS) -#define S2LP_SPI_CS A1 + +#if defined(MBED_CONF_S2LP_SPI_CS) +#define S2LP_SPI_CS MBED_CONF_S2LP_SPI_CS +#else +#define S2LP_SPI_CS A1 #endif -#if !defined(S2LP_SPI_SDN) -#define S2LP_SPI_SDN D7 + +#if defined(MBED_CONF_S2LP_SPI_SDN) +#define S2LP_SPI_SDN MBED_CONF_S2LP_SPI_SDN +#else +#define S2LP_SPI_SDN D7 #endif -#if !defined(TEST_PIN_TX) -#define TEST_PIN_TX D6 + +#if defined(MBED_CONF_S2LP_TEST_PIN_TX) +#define S2LP_TEST_PIN_TX MBED_CONF_S2LP_TEST_PIN_TX +#else +#define S2LP_TEST_PIN_TX D6 #endif -#if !defined(TEST_PIN_RX) -#define TEST_PIN_RX D5 + +#if defined(MBED_CONF_S2LP_TEST_PIN_RX) +#define S2LP_TEST_PIN_RX MBED_CONF_S2LP_TEST_PIN_RX +#else +#define S2LP_TEST_PIN_RX D5 #endif -#if !defined(TEST_PIN_CSMA) -#define TEST_PIN_CSMA D4 + +#if defined(MBED_CONF_S2LP_TEST_PIN_CSMA) +#define S2LP_TEST_PIN_CSMA MBED_CONF_S2LP_TEST_PIN_CSMA +#else +#define S2LP_TEST_PIN_CSMA D4 #endif -#if !defined(TEST_PIN_SPARE_1) -#define TEST_PIN_SPARE_1 D2 + +#if defined(MBED_CONF_S2LP_TEST_PIN_SPARE_1) +#define S2LP_TEST_PIN_SPARE_1 MBED_CONF_S2LP_TEST_PIN_SPARE_1 +#else +#define S2LP_TEST_PIN_SPARE_1 D2 #endif -#if !defined(TEST_PIN_SPARE_2) -#define TEST_PIN_SPARE_2 D8 + +#if defined(MBED_CONF_S2LP_TEST_PIN_SPARE_2) +#define S2LP_TEST_PIN_SPARE_2 MBED_CONF_S2LP_TEST_PIN_SPARE_2 +#else +#define S2LP_TEST_PIN_SPARE_2 D8 #endif -#if !defined(S2LP_SPI_GPIO0) -#define S2LP_SPI_GPIO0 A0 + +#if defined(MBED_CONF_S2LP_SPI_GPIO0) +#define S2LP_SPI_GPIO0 MBED_CONF_S2LP_SPI_GPIO0 +#else +#define S2LP_SPI_GPIO0 A0 #endif -#if !defined(S2LP_SPI_GPIO1) -#define S2LP_SPI_GPIO1 A2 + +#if defined(MBED_CONF_S2LP_SPI_GPIO1) +#define S2LP_SPI_GPIO1 MBED_CONF_S2LP_SPI_GPIO1 +#else +#define S2LP_SPI_GPIO1 A2 #endif -#if !defined(S2LP_SPI_GPIO2) -#define S2LP_SPI_GPIO2 A3 + +#if defined(MBED_CONF_S2LP_SPI_GPIO2) +#define S2LP_SPI_GPIO2 MBED_CONF_S2LP_SPI_GPIO2 +#else +#define S2LP_SPI_GPIO2 A3 #endif -#if !defined(S2LP_SPI_GPIO3) -#define S2LP_SPI_GPIO3 A5 + +#if defined(MBED_CONF_S2LP_SPI_GPIO3) +#define S2LP_SPI_GPIO3 MBED_CONF_S2LP_SPI_GPIO3 +#else +#define S2LP_SPI_GPIO3 A5 #endif + +#if defined(MBED_CONF_S2LP_I2C_SDA) +#define S2LP_I2C_SDA MBED_CONF_S2LP_I2C_SDA +#else +#define S2LP_I2C_SDA null +#endif + +#if defined(MBED_CONF_S2LP_I2C_SCL) +#define S2LP_I2C_SCL MBED_CONF_S2LP_I2C_SCL +#else +#define S2LP_I2C_SCL null #endif #include "at24mac_s2lp.h" @@ -116,11 +129,11 @@ class TestPins_S2LP; class NanostackRfPhys2lp : public NanostackRfPhy { public: NanostackRfPhys2lp(PinName spi_sdi, PinName spi_sdo, PinName spi_sclk, PinName spi_cs, PinName spi_sdn - ,PinName spi_gpio0, PinName spi_gpio1, PinName spi_gpio2, PinName spi_gpio3 + , PinName spi_gpio0, PinName spi_gpio1, PinName spi_gpio2, PinName spi_gpio3 #ifdef AT24MAC - ,PinName i2c_sda, PinName i2c_scl + , PinName i2c_sda, PinName i2c_scl #endif //AT24MAC - ); + ); virtual ~NanostackRfPhys2lp(); virtual int8_t rf_register(); virtual void rf_unregister(); diff --git a/features/nanostack/sal-stack-nanostack/README.md b/features/nanostack/sal-stack-nanostack/README.md index f614033fa7..ddddf390c7 100644 --- a/features/nanostack/sal-stack-nanostack/README.md +++ b/features/nanostack/sal-stack-nanostack/README.md @@ -3,37 +3,29 @@ ARM Mesh networking stack This repository contains the ARM mesh networking stack that provides support for the following mesh protocols: - * 6LoWPAN with Neighbor Discovery (ND) and Mesh Link Establishment (MLE) - * Thread - * Wi-SUN +* 6LoWPAN with Neighbor Discovery (ND) and Mesh Link Establishment (MLE) +* Wi-SUN - All networking stacks are using IEEE 802.15.4 based radios. +All networking stacks are using IEEE 802.15.4 based radios. The full documentation is hosted in [Mbed OS documentation](https://os.mbed.com/docs/mbed-os/latest/reference/mesh-tech.html). -On mbed OS, mesh networking stacks can be used through [Mbed Mesh API](https://os.mbed.com/docs/mbed-os/latest/apis/mesh-api.html) and [Network Socket API](https://os.mbed.com/docs/mbed-os/v5.11/apis/network-socket.html). +On mbed OS, mesh networking stacks can be used through [Mbed Mesh API](https://os.mbed.com/docs/mbed-os/latest/apis/mesh-api.html) and [Network Socket API](https://os.mbed.com/docs/mbed-os/latest/apis/network-socket.html). To see, how the mesh networking stack works, check the example application [mbed-os-example-mesh-minimal](https://github.com/ARMmbed/mbed-os-example-mesh-minimal). - -##6LoWPAN with ND and MLE + +## 6LoWPAN with ND and MLE This networking stack is using standard 6LoWPAN and uses: * Neighbor Discovery Protocol ([RFC4861](https://tools.ietf.org/html/rfc4861)) to locate other devices in the mesh network. * Mesh-Link-Establishment ([draft-kelsey-intarea-mesh-link-establishment-06](https://tools.ietf.org/html/draft-kelsey-intarea-mesh-link-establishment-06)) is used for establishing and configuring secure radio links. - -##Thread -Thread is standardized by [Thread group](https://www.threadgroup.org/). -![](docs/img/thread_certified.png) -mbed OS is now a Thread Certified Component. Using IPv6 with 6LoWPAN as the foundation, Thread technology provides a low-power, self-healing mesh network designed for the home. - -##Wi-SUN +## Wi-SUN Wi-SUN (Smart Utility Networks) specification is standardized by [Wi-SUN Alliance](https://www.wi-sun.org/). -Mbed OS release 5.12 contains the initial Mbed Wi-SUN FAN implementation. Functionality of the Mbed Wi-SUN network stack will be updated when the Wi-SUN protocol is specified further. ## License diff --git a/features/nanostack/sal-stack-nanostack/docs/img/thread_certified.png b/features/nanostack/sal-stack-nanostack/docs/img/thread_certified.png deleted file mode 100644 index c86ee53a7e..0000000000 Binary files a/features/nanostack/sal-stack-nanostack/docs/img/thread_certified.png and /dev/null differ diff --git a/features/nanostack/sal-stack-nanostack/nanostack/ws_bbr_api.h b/features/nanostack/sal-stack-nanostack/nanostack/ws_bbr_api.h index df40279109..9182ea74fd 100644 --- a/features/nanostack/sal-stack-nanostack/nanostack/ws_bbr_api.h +++ b/features/nanostack/sal-stack-nanostack/nanostack/ws_bbr_api.h @@ -40,6 +40,8 @@ typedef struct bbr_information { uint8_t dodag_id[16]; /** Address prefix given to devices in network set to 0 if not available*/ uint8_t prefix[8]; + /** Address IID of the border router set to 0 if not available*/ + uint8_t IID[8]; /** Amount of devices in the network. */ uint16_t devices_in_network; /** Border router instance identifier defined in RPL */ diff --git a/features/nanostack/sal-stack-nanostack/nanostack/ws_management_api.h b/features/nanostack/sal-stack-nanostack/nanostack/ws_management_api.h index 99092ba5f5..37e66999ab 100644 --- a/features/nanostack/sal-stack-nanostack/nanostack/ws_management_api.h +++ b/features/nanostack/sal-stack-nanostack/nanostack/ws_management_api.h @@ -75,10 +75,16 @@ extern "C" { #define CHANNEL_SPACING_100 0x03 // 100 khz #define CHANNEL_SPACING_250 0x04 // 250 khz -#define NETWORK_SIZE_CERTIFICATE 0x00 -#define NETWORK_SIZE_SMALL 0x01 -#define NETWORK_SIZE_MEDIUM 0x08 -#define NETWORK_SIZE_LARGE 0x10 +/* + * 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 /** Temporary API change flag. this will be removed when new version of API is implemented on applications @@ -229,9 +235,9 @@ int ws_management_regulatory_domain_validate( * * timing parameters follows the specification example from Wi-SUN specification * - * Default value: medium - * small network size: hundreds of devices - * Large network size: thousands of devices + * Default value: medium 100 - 800 device + * small network size: less than 100 devices + * Large network size: 800 - 1500 devices * automatic: when discovering the network network size is learned * from advertisements and timings adjusted accordingly * diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Bootstraps/Generic/protocol_6lowpan_bootstrap.c b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Bootstraps/Generic/protocol_6lowpan_bootstrap.c index cbe3e12c67..0a21788cc2 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Bootstraps/Generic/protocol_6lowpan_bootstrap.c +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Bootstraps/Generic/protocol_6lowpan_bootstrap.c @@ -588,7 +588,7 @@ static void mle_neigh_entry_update_by_mle_tlv_list(int8_t interface_id, mac_neig uint8_t link_idr; uint8_t iop_flags; if (mle_link_quality_tlv_parse(mac64, short_address, mle_tlv_info.dataPtr, mle_tlv_info.tlvLen, &iop_flags, &link_idr)) { - etx_remote_incoming_idr_update(interface_id, link_idr, entry_temp->index); + etx_remote_incoming_idr_update(interface_id, link_idr, entry_temp->index, entry_temp->mac64); if ((iop_flags & MLE_NEIGHBOR_PRIORITY_LINK) == MLE_NEIGHBOR_PRIORITY_LINK) { entry_temp->link_role = CHILD_NEIGHBOUR; @@ -965,9 +965,9 @@ int protocol_6lowpan_router_synch_to_new_router(protocol_interface_info_entry_t static uint8_t mle_calculate_idr(int8_t interface_id, mle_message_t *mle_msg, mac_neighbor_table_entry_t *entry_temp) { if (!entry_temp) { - return etx_lqi_dbm_update(-2, mle_msg->lqi, mle_msg->dbm, 0) >> 3; + return etx_lqi_dbm_update(-2, mle_msg->lqi, mle_msg->dbm, 0, NULL) >> 3; } - return etx_lqi_dbm_update(interface_id, mle_msg->lqi, mle_msg->dbm, entry_temp->index) >> 3; + return etx_lqi_dbm_update(interface_id, mle_msg->lqi, mle_msg->dbm, entry_temp->index, entry_temp->mac64) >> 3; } @@ -1609,7 +1609,7 @@ static void lowpan_neighbor_entry_remove_notify(mac_neighbor_table_entry_t *entr } mac_helper_devicetable_remove(cur_interface->mac_api, entry_ptr->index, entry_ptr->mac64); //Removes ETX neighbor - etx_neighbor_remove(cur_interface->id, entry_ptr->index); + etx_neighbor_remove(cur_interface->id, entry_ptr->index, entry_ptr->mac64); //Remove MLE frame counter info mle_service_frame_counter_entry_delete(cur_interface->id, entry_ptr->index); diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_bootstrap.c b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_bootstrap.c index 07e231c864..1d0537d343 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_bootstrap.c +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_bootstrap.c @@ -141,7 +141,7 @@ static void thread_neighbor_remove(mac_neighbor_table_entry_t *entry_ptr, void * thread_reset_neighbour_info(cur, entry_ptr); //Removes ETX neighbor - etx_neighbor_remove(cur->id, entry_ptr->index); + etx_neighbor_remove(cur->id, entry_ptr->index, entry_ptr->mac64); //Remove MLE frame counter info mle_service_frame_counter_entry_delete(cur->id, entry_ptr->index); } diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/adaptation_interface.c b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/adaptation_interface.c index 99636719d9..87d6657735 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/adaptation_interface.c +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/adaptation_interface.c @@ -155,7 +155,7 @@ static void lowpan_adaptation_etx_update_cb(protocol_interface_info_entry_t *cur // Gets table entry mac_neighbor_table_entry_t *neigh_table_ptr = mac_neighbor_table_address_discover(mac_neighbor_info(cur), buf->dst_sa.address + PAN_ID_LEN, buf->dst_sa.addr_type); if (neigh_table_ptr) { - etx_transm_attempts_update(cur->id, 1 + confirm->tx_retries, success, neigh_table_ptr->index); + etx_transm_attempts_update(cur->id, 1 + confirm->tx_retries, success, neigh_table_ptr->index, neigh_table_ptr->mac64); // Updates ETX statistics etx_storage_t *etx_entry = etx_storage_entry_get(cur->id, neigh_table_ptr->index); if (etx_entry) { diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_bbr_api.c b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_bbr_api.c index c0a1d00163..f841be8144 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_bbr_api.c +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_bbr_api.c @@ -20,6 +20,7 @@ #include "ns_types.h" #include "ns_trace.h" #include "net_interface.h" +#include "socket_api.h" #include "eventOS_event.h" #include "NWK_INTERFACE/Include/protocol.h" #include "6LoWPAN/Bootstraps/protocol_6lowpan.h" @@ -94,7 +95,16 @@ 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 { - cur->ws_info->rpl_version_timer = RPL_VERSION_LIFETIME_RESTART; + if (cur->ws_info->cfg->gen.network_size <= NETWORK_SIZE_SMALL) { + // handles also NETWORK_SIZE_CERTIFICATE + cur->ws_info->rpl_version_timer = RPL_VERSION_LIFETIME_RESTART_SMALL; + } else if (cur->ws_info->cfg->gen.network_size <= NETWORK_SIZE_MEDIUM) { + cur->ws_info->rpl_version_timer = RPL_VERSION_LIFETIME_RESTART_MEDIUM; + } else if (cur->ws_info->cfg->gen.network_size <= NETWORK_SIZE_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; + } } } @@ -232,7 +242,10 @@ static if_address_entry_t *ws_bbr_slaac_generate(protocol_interface_info_entry_t static void ws_bbr_slaac_remove(protocol_interface_info_entry_t *cur, uint8_t *ula_prefix) { - icmpv6_slaac_prefix_update(cur, ula_prefix, 64, 0, 0); + if (cur) { + icmpv6_slaac_prefix_update(cur, ula_prefix, 64, 0, 0); + } + addr_policy_table_delete_entry(ula_prefix, 64); } @@ -361,6 +374,9 @@ static void ws_bbr_dhcp_server_start(protocol_interface_info_entry_t *cur, uint8 } static void ws_bbr_dhcp_server_stop(protocol_interface_info_entry_t *cur, uint8_t *global_id) { + if (!cur) { + return; + } uint8_t temp_address[16]; memcpy(temp_address, global_id, 8); memset(temp_address + 8, 0, 8); @@ -368,7 +384,6 @@ static void ws_bbr_dhcp_server_stop(protocol_interface_info_entry_t *cur, uint8_ DHCPv6_server_service_delete(cur->id, global_id, false); //Delete Client dhcp_client_global_address_delete(cur->id, NULL, temp_address); - } static void ws_bbr_routing_stop(protocol_interface_info_entry_t *cur) @@ -632,6 +647,11 @@ uint16_t test_pan_size_override = 0xffff; uint16_t ws_bbr_pan_size(protocol_interface_info_entry_t *cur) { uint16_t result = 0; + + if (!cur || !cur->rpl_domain) { + return 0; + } + if (test_pan_size_override != 0xffff) { return test_pan_size_override; } @@ -710,7 +730,6 @@ void ws_bbr_stop(int8_t interface_id) protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); ws_bbr_routing_stop(cur); - backbone_interface_id = -1; current_instance_id++; @@ -764,6 +783,13 @@ int ws_bbr_info_get(int8_t interface_id, bbr_information_t *info_ptr) memcpy(info_ptr->dodag_id, current_dodag_id, 16); memcpy(info_ptr->prefix, current_global_prefix, 8); + // Get the Wi-SUN interface generated address that is used in the RF interface. + const uint8_t *wisun_if_addr = addr_select_with_prefix(cur, current_global_prefix, 64, SOCKET_IPV6_PREFER_SRC_PUBLIC); + + if (wisun_if_addr) { + memcpy(info_ptr->IID, wisun_if_addr + 8, 8); + } + info_ptr->devices_in_network = ws_bbr_pan_size(cur); info_ptr->instance_id = current_instance_id; info_ptr->version = dodag_info.version_num; diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_bootstrap.c b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_bootstrap.c index e40ed39b88..0d02498a5d 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_bootstrap.c +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_bootstrap.c @@ -97,13 +97,14 @@ static void ws_bootstrap_nw_frame_counter_set(protocol_interface_info_entry_t *c static void ws_bootstrap_nw_frame_counter_read(protocol_interface_info_entry_t *cur, uint32_t *counter, uint8_t slot); static void ws_bootstrap_nw_info_updated(protocol_interface_info_entry_t *interface_ptr, uint16_t pan_id, char *network_name); static void ws_bootstrap_authentication_completed(protocol_interface_info_entry_t *cur, auth_result_e result, uint8_t *target_eui_64); +static const uint8_t *ws_bootstrap_authentication_next_target(protocol_interface_info_entry_t *cur, const uint8_t *previous_eui_64, uint16_t *pan_id); static void ws_bootstrap_pan_version_increment(protocol_interface_info_entry_t *cur); static ws_nud_table_entry_t *ws_nud_entry_discover(protocol_interface_info_entry_t *cur, void *neighbor); static void ws_nud_entry_remove(protocol_interface_info_entry_t *cur, mac_neighbor_table_entry_t *entry_ptr); static bool ws_neighbor_entry_nud_notify(mac_neighbor_table_entry_t *entry_ptr, void *user_data); static void ws_address_registration_update(protocol_interface_info_entry_t *interface, const uint8_t addr[16]); - +static int8_t ws_bootstrap_neighbor_set(protocol_interface_info_entry_t *cur, parent_info_t *parent_ptr, bool clear_list); static void ws_bootstrap_candidate_table_reset(protocol_interface_info_entry_t *cur); static parent_info_t *ws_bootstrap_candidate_parent_get(struct protocol_interface_info_entry *cur, const uint8_t *addr, bool create); @@ -147,7 +148,7 @@ mac_neighbor_table_entry_t *ws_bootstrap_mac_neighbor_add(struct protocol_interf static void ws_bootstrap_neighbor_delete(struct protocol_interface_info_entry *interface, mac_neighbor_table_entry_t *entry_ptr) { mac_helper_devicetable_remove(interface->mac_api, entry_ptr->index, entry_ptr->mac64); - etx_neighbor_remove(interface->id, entry_ptr->index); + etx_neighbor_remove(interface->id, entry_ptr->index, entry_ptr->mac64); ws_neighbor_class_entry_remove(&interface->ws_info->neighbor_storage, entry_ptr->index); } @@ -168,7 +169,6 @@ static void ws_bootstap_eapol_neigh_entry_allocate(struct protocol_interface_inf return; } interface->ws_info->eapol_tx_index = mac_entry->index; - tr_debug("Allocated Eapol Index TX %u", interface->ws_info->eapol_tx_index); } void ws_bootstrap_eapol_rx_temporary_set(struct protocol_interface_info_entry *interface, const uint8_t *src64) @@ -188,8 +188,6 @@ ws_neighbor_class_entry_t *ws_bootstrap_eapol_tx_temporary_set(struct protocol_i } memcpy(mac_entry->mac64, src64, 8); - - tr_debug("EAPOL Temporary TX neighbor %s : index:%u", trace_array(src64, 8), interface->ws_info->eapol_tx_index); mac_helper_device_description_write(interface, &device_desc, src64, 0xffff, 0, false); mac_helper_devicetable_direct_set(interface->mac_api, &device_desc, interface->ws_info->eapol_tx_index); return ws_neighbor_class_entry_get(&interface->ws_info->neighbor_storage, mac_entry->index); @@ -204,7 +202,6 @@ void ws_bootstrap_eapol_tx_temporary_clear(struct protocol_interface_info_entry memset(mac_entry->mac64, 0xff, 8); mac_helper_devicetable_remove(interface->mac_api, interface->ws_info->eapol_tx_index, NULL); - tr_debug("Clear EAPOL-Temporary"); } static void ws_bootstrap_neighbor_list_clean(struct protocol_interface_info_entry *interface) @@ -545,8 +542,8 @@ 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); - ws_generate_channel_list(fhss_configuration->unicast_channel_mask, cur->ws_info->hopping_schdule.number_of_channels, cur->ws_info->hopping_schdule.regulatory_domain); + 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); // 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]; @@ -1129,7 +1126,7 @@ static parent_info_t *ws_bootstrap_candidate_parent_allocate(protocol_interface_ return entry; } -static void ws_bootstrap_candidate_parent_free(protocol_interface_info_entry_t *cur, uint8_t *addr) +static void ws_bootstrap_candidate_parent_free(protocol_interface_info_entry_t *cur, const uint8_t *addr) { ns_list_foreach_safe(parent_info_t, entry, &cur->ws_info->parent_list_reserved) { if (memcmp(entry->addr, addr, 8) == 0) { @@ -1346,14 +1343,15 @@ static void ws_bootstrap_pan_advertisement_solicit_analyse(struct protocol_inter * a PAN Advertisement Solicit with NETNAME-IE / Network Name matching that configured on the receiving node. */ 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 */ - if (ws_bootstrap_state_discovery(cur) && - cur->bootsrap_state_machine_cnt > cur->ws_info->trickle_params_pan_discovery.Imin + 50) { - cur->bootsrap_state_machine_cnt = cur->ws_info->trickle_params_pan_discovery.Imin + randLIB_get_8bit() % 50; + if (ws_bootstrap_state_discovery(cur) && cur->ws_info->cfg->gen.network_size <= NETWORK_SIZE_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); + tr_info("Making parent selection in %u s", (cur->bootsrap_state_machine_cnt / 10)); } } @@ -1423,7 +1421,7 @@ static void ws_bootstrap_pan_config_analyse(struct protocol_interface_info_entry } if (neighbour_pointer_valid) { - etx_lqi_dbm_update(cur->id, data->mpduLinkQuality, data->signal_dbm, neighbor_info.neighbor->index); + etx_lqi_dbm_update(cur->id, data->mpduLinkQuality, data->signal_dbm, neighbor_info.neighbor->index, neighbor_info.neighbor->mac64); //Update Neighbor Broadcast and Unicast Parameters ws_neighbor_class_neighbor_unicast_time_info_update(neighbor_info.ws_neighbor, ws_utt, data->timestamp); ws_neighbor_class_neighbor_unicast_schedule_set(neighbor_info.ws_neighbor, ws_us); @@ -1508,7 +1506,7 @@ static void ws_bootstrap_pan_config_solicit_analyse(struct protocol_interface_in llc_neighbour_req_t neighbor_info; if (ws_bootstrap_neighbor_info_request(cur, data->SrcAddr, &neighbor_info, false)) { - etx_lqi_dbm_update(cur->id, data->mpduLinkQuality, data->signal_dbm, neighbor_info.neighbor->index); + etx_lqi_dbm_update(cur->id, data->mpduLinkQuality, data->signal_dbm, neighbor_info.neighbor->index, neighbor_info.neighbor->mac64); ws_neighbor_class_neighbor_unicast_time_info_update(neighbor_info.ws_neighbor, ws_utt, data->timestamp); ws_neighbor_class_neighbor_unicast_schedule_set(neighbor_info.ws_neighbor, ws_us); } @@ -1823,7 +1821,7 @@ static bool ws_neighbor_entry_nud_notify(mac_neighbor_table_entry_t *entry_ptr, return false; } - if (!rpl_control_is_dodag_parent_candidate(cur, ll_address, WS_NEIGHBOUR_MAX_CANDIDATE_PROBE)) { + if (!rpl_control_is_dodag_parent_candidate(cur, ll_address, cur->ws_info->cfg->gen.rpl_parent_candidate_max)) { //NUD Not needed for if neighbour is not parent candidate return false; } @@ -1986,7 +1984,7 @@ int ws_bootstrap_init(int8_t interface_id, net_6lowpan_mode_e bootstrap_mode) ret_val = -4; goto init_fail; } - if (ws_pae_controller_cb_register(cur, &ws_bootstrap_authentication_completed, &ws_bootstrap_nw_key_set, &ws_bootstrap_nw_key_clear, &ws_bootstrap_nw_key_index_set, &ws_bootstrap_nw_frame_counter_set, &ws_bootstrap_nw_frame_counter_read, &ws_bootstrap_pan_version_increment, &ws_bootstrap_nw_info_updated) < 0) { + if (ws_pae_controller_cb_register(cur, &ws_bootstrap_authentication_completed, &ws_bootstrap_authentication_next_target, &ws_bootstrap_nw_key_set, &ws_bootstrap_nw_key_clear, &ws_bootstrap_nw_key_index_set, &ws_bootstrap_nw_frame_counter_set, &ws_bootstrap_nw_frame_counter_read, &ws_bootstrap_pan_version_increment, &ws_bootstrap_nw_info_updated) < 0) { ret_val = -4; goto init_fail; } @@ -2278,8 +2276,8 @@ static void ws_bootstrap_rpl_callback(rpl_event_t event, void *handle) ws_eapol_relay_start(cur, EAPOL_RELAY_SOCKET_PORT, dodag_info.dodag_id, EAPOL_RELAY_SOCKET_PORT); // Set network information to PAE ws_pae_controller_nw_info_set(cur, cur->ws_info->network_pan_id, cur->ws_info->cfg->gen.network_name); - // Network key is valid - ws_pae_controller_nw_key_valid(cur); + // Network key is valid, indicate border router IID to controller + ws_pae_controller_nw_key_valid(cur, &dodag_info.dodag_id[8]); // After successful DAO ACK connection to border router is verified cur->ws_info->pan_timeout_timer = cur->ws_info->cfg->timing.pan_timeout; @@ -2381,19 +2379,21 @@ static void ws_rpl_prefix_callback(prefix_entry_t *prefix, void *handle, uint8_t static bool ws_rpl_candidate_soft_filtering(protocol_interface_info_entry_t *cur, struct rpl_instance *instance) { - //If bootstrap active we not need any candidate filtering - if ((cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_ACTIVE) && (ws_info(cur)->cfg->gen.network_size == NETWORK_SIZE_CERTIFICATE)) { - return true; - } - //Already many candidates - if (rpl_control_candidate_list_size(cur, instance) > cur->ws_info->cfg->gen.rpl_parent_candidate_max) { + uint16_t candidate_list_size = rpl_control_candidate_list_size(cur, instance); + if (candidate_list_size >= cur->ws_info->cfg->gen.rpl_parent_candidate_max) { return false; } + uint16_t selected_parents = rpl_control_selected_parent_count(cur, instance); + //Already enough selected candidates - if (rpl_control_selected_parent_count(cur, instance) >= cur->ws_info->cfg->gen.rpl_selected_parent_max) { - return false; + if (selected_parents >= cur->ws_info->cfg->gen.rpl_selected_parent_max) { + candidate_list_size -= selected_parents; + if (candidate_list_size >= 2) { + //We have more candidates than selected + return false; + } } return true; @@ -2427,6 +2427,19 @@ static bool ws_rpl_new_parent_callback(uint8_t *ll_parent_address, void *handle, ws_neighbor_temp_class_t *entry = ws_llc_get_multicast_temp_entry(cur, mac64); if (!ws_rpl_candidate_soft_filtering(cur, instance)) { + + //Acept only better than own rank here + if (candidate_rank >= rpl_control_current_rank(instance)) { + //Do not accept no more siblings + return false; + } + + uint16_t candidate_list_size = rpl_control_candidate_list_size(cur, instance); + if (candidate_list_size > cur->ws_info->cfg->gen.rpl_parent_candidate_max + 1) { + //Accept only 1 better 1 time + return false; + } + if (!neigh_buffer.neighbor) { //Do not accept any new in that Place return false; @@ -2459,42 +2472,6 @@ static bool ws_rpl_new_parent_callback(uint8_t *ll_parent_address, void *handle, if (neigh_buffer.neighbor) { return true; } -#if 0 - if (!rpl_control_find_worst_neighbor(cur, instance, replacing)) { - return false; - } - - // +2 Is for PAN ID space - memcpy(mac64 + 2, replacing + 8, 8); - mac64[2] ^= 2; - - if (ws_etx_read(cur, ADDR_802_15_4_LONG, mac64) == 0xffff) { - //Not proped yet because ETX is 0xffff - return false; - } - - uint16_t etx = 0; - if (neigh_buffer.neighbor) { - etx = etx_local_etx_read(cur->id, neigh_buffer.neighbor->index); - } - - // Accept now only better one's when max candidates selected and max candidate list size is reached - if (!rpl_possible_better_candidate(cur, instance, replacing, candidate_rank, etx)) { - return false; - } - //TODO if replacing has poor ETX, put it in blacklist as "poor ETX" to prevent reselection - //Mark That We can try remove replaced link - replace_ok = true; - -neigh_create: - - - if (neigh_buffer.neighbor) { - //Use Already discovered entry - create_ok = true; - goto neigh_create_ok; - } -#endif if (!entry) { //No Multicast Entry Available @@ -2508,7 +2485,7 @@ neigh_create: //Copy fhss temporary data *ws_neigh = entry->neigh_info_list; //ETX Create here - etx_lqi_dbm_update(cur->id, entry->mpduLinkQuality, entry->signal_dbm, neigh_buffer.neighbor->index); + etx_lqi_dbm_update(cur->id, entry->mpduLinkQuality, entry->signal_dbm, neigh_buffer.neighbor->index, neigh_buffer.neighbor->mac64); mac_neighbor_table_trusted_neighbor(mac_neighbor_info(cur), neigh_buffer.neighbor, true); } ws_llc_free_multicast_temp_entry(cur, entry); @@ -2635,7 +2612,7 @@ static void ws_bootstrap_start_discovery(protocol_interface_info_entry_t *cur) } // Discovery statemachine is checkked after we have sent the Solicit - uint16_t time_to_solicit = 0; + uint32_t time_to_solicit = 0; if (cur->ws_info->trickle_pan_advertisement_solicit.t > cur->ws_info->trickle_pan_advertisement_solicit.now) { time_to_solicit = cur->ws_info->trickle_pan_advertisement_solicit.t - cur->ws_info->trickle_pan_advertisement_solicit.now; } @@ -2644,7 +2621,13 @@ static void ws_bootstrap_start_discovery(protocol_interface_info_entry_t *cur) cur->ws_info->trickle_params_pan_discovery.Imin, cur->ws_info->trickle_params_pan_discovery.Imax, cur->ws_info->trickle_params_pan_discovery.TimerExpirations, cur->ws_info->trickle_params_pan_discovery.k, cur->ws_info->trickle_pan_advertisement_solicit.I, cur->ws_info->trickle_pan_advertisement_solicit.t, cur->ws_info->trickle_pan_advertisement_solicit.now, cur->ws_info->trickle_pan_advertisement_solicit.c); - cur->bootsrap_state_machine_cnt = time_to_solicit + cur->ws_info->trickle_params_pan_discovery.Imin + randLIB_get_8bit() % 50; + time_to_solicit += cur->ws_info->trickle_params_pan_discovery.Imin + randLIB_get_random_in_range(0, cur->ws_info->trickle_params_pan_discovery.Imin); + + if (time_to_solicit > 0xffff) { + time_to_solicit = 0xffff; + } + cur->bootsrap_state_machine_cnt = time_to_solicit; + tr_info("Making parent selection in %u s", (cur->bootsrap_state_machine_cnt / 10)); } @@ -2757,6 +2740,24 @@ static void ws_bootstrap_authentication_completed(protocol_interface_info_entry_ } } +static const uint8_t *ws_bootstrap_authentication_next_target(protocol_interface_info_entry_t *cur, const uint8_t *previous_eui_64, uint16_t *pan_id) +{ + ws_bootstrap_candidate_parent_free(cur, previous_eui_64); + + // Gets best target + parent_info_t *parent_info = ws_bootstrap_candidate_parent_get_best(cur); + if (parent_info) { + /* On failure still continues with the new parent, and on next call, + will try to set the neighbor again */ + ws_bootstrap_neighbor_set(cur, parent_info, true); + *pan_id = parent_info->pan_id; + return parent_info->addr; + } + + // If no targets found, retries the last one + return previous_eui_64; +} + // Start configuration learning static void ws_bootstrap_start_configuration_learn(protocol_interface_info_entry_t *cur) { @@ -2830,7 +2831,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); + 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); } async_req->channel_list.channel_page = CHANNEL_PAGE_10; @@ -3146,6 +3147,36 @@ static void ws_bootstrap_event_handler(arm_event_s *event) } } +static int8_t ws_bootstrap_neighbor_set(protocol_interface_info_entry_t *cur, parent_info_t *parent_ptr, bool clear_list) +{ + uint16_t pan_id = cur->ws_info->network_pan_id; + + // Add EAPOL neighbor + cur->ws_info->network_pan_id = parent_ptr->pan_id; + cur->ws_info->pan_information = parent_ptr->pan_information; + cur->ws_info->pan_information.pan_version = 0; // This is learned from actual configuration + + // If PAN ID changes, clear learned neighbors and activate FHSS + if (pan_id != cur->ws_info->network_pan_id) { + if (clear_list) { + ws_bootstrap_neighbor_list_clean(cur); + } + ws_bootstrap_fhss_activate(cur); + } + + llc_neighbour_req_t neighbor_info; + if (!ws_bootstrap_neighbor_info_request(cur, parent_ptr->addr, &neighbor_info, true)) { + //Remove Neighbour and set Link setup back + ns_list_remove(&cur->ws_info->parent_list_reserved, parent_ptr); + ns_list_add_to_end(&cur->ws_info->parent_list_free, parent_ptr); + return -1; + } + + ws_neighbor_class_neighbor_unicast_time_info_update(neighbor_info.ws_neighbor, &parent_ptr->ws_utt, parent_ptr->timestamp); + ws_neighbor_class_neighbor_unicast_schedule_set(neighbor_info.ws_neighbor, &parent_ptr->ws_us); + return 0; +} + /* * State machine * @@ -3166,29 +3197,21 @@ select_best_candidate: // randomize new channel and start MAC ws_bootstrap_fhss_activate(cur); // Next check will be after one trickle - cur->bootsrap_state_machine_cnt += cur->ws_info->trickle_params_pan_discovery.Imin + randLIB_get_8bit() % 50; + uint32_t random_start = cur->ws_info->trickle_params_pan_discovery.Imin + randLIB_get_random_in_range(0, cur->ws_info->trickle_params_pan_discovery.Imin); + if (random_start > 0xffff) { + random_start = 0xffff; + } + cur->bootsrap_state_machine_cnt = random_start; + tr_info("Making parent selection in %u s", (cur->bootsrap_state_machine_cnt / 10)); return; } tr_info("selected parent:%s panid %u", trace_array(selected_parent_ptr->addr, 8), selected_parent_ptr->pan_id); - // Add EAPOL neighbour - cur->ws_info->network_pan_id = selected_parent_ptr->pan_id; - cur->ws_info->pan_information = selected_parent_ptr->pan_information; - cur->ws_info->pan_information.pan_version = 0; // This is learned from actual configuration - - ws_bootstrap_fhss_activate(cur); - llc_neighbour_req_t neighbor_info; - if (!ws_bootstrap_neighbor_info_request(cur, selected_parent_ptr->addr, &neighbor_info, true)) { - //Remove Neighbour and set Link setup back - ns_list_remove(&cur->ws_info->parent_list_reserved, selected_parent_ptr); - ns_list_add_to_end(&cur->ws_info->parent_list_free, selected_parent_ptr); + if (ws_bootstrap_neighbor_set(cur, selected_parent_ptr, false) < 0) { goto select_best_candidate; } - ws_neighbor_class_neighbor_unicast_time_info_update(neighbor_info.ws_neighbor, &selected_parent_ptr->ws_utt, selected_parent_ptr->timestamp); - ws_neighbor_class_neighbor_unicast_schedule_set(neighbor_info.ws_neighbor, &selected_parent_ptr->ws_us); - ws_pae_controller_set_target(cur, selected_parent_ptr->pan_id, selected_parent_ptr->addr); // temporary!!! store since auth ws_bootstrap_event_authentication_start(cur); return; diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_cfg_settings.c b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_cfg_settings.c index 9a53e7cebd..8eacf4802d 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_cfg_settings.c +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_cfg_settings.c @@ -82,6 +82,7 @@ static int8_t ws_cfg_to_get(ws_cfgs_t **cfg, ws_cfgs_t *new_cfg, ws_cfg_validate static void ws_cfg_network_size_config_set_small(ws_cfg_nw_size_t *cfg); static void ws_cfg_network_size_config_set_medium(ws_cfg_nw_size_t *cfg); static void ws_cfg_network_size_config_set_large(ws_cfg_nw_size_t *cfg); +static void ws_cfg_network_size_config_set_xlarge(ws_cfg_nw_size_t *cfg); static void ws_cfg_network_size_config_set_certificate(ws_cfg_nw_size_t *cfg); static int8_t ws_cfg_network_size_default_set(ws_gen_cfg_t *cfg); static int8_t ws_cfg_gen_default_set(ws_gen_cfg_t *cfg); @@ -261,8 +262,10 @@ int8_t ws_cfg_network_size_set(protocol_interface_info_entry_t *cur, ws_gen_cfg_ set_function = ws_cfg_network_size_config_set_small; } else if (cfg->network_size <= NETWORK_SIZE_MEDIUM) { set_function = ws_cfg_network_size_config_set_medium; - } else { + } else if (cfg->network_size <= NETWORK_SIZE_LARGE) { set_function = ws_cfg_network_size_config_set_large; + } else { + set_function = ws_cfg_network_size_config_set_xlarge; } // Overrides the values on the new configuration @@ -334,9 +337,12 @@ int8_t ws_cfg_network_size_configure(protocol_interface_info_entry_t *cur, uint1 } else if (network_size < 800) { // Medium ws_cfg_network_size_config_set_medium(&new_nw_size_cfg); + } else if (network_size < 1500) { + // Medium + ws_cfg_network_size_config_set_large(&new_nw_size_cfg); } else { // Large - ws_cfg_network_size_config_set_large(&new_nw_size_cfg); + ws_cfg_network_size_config_set_xlarge(&new_nw_size_cfg); } ws_cfg_gen_set(cur, NULL, &new_nw_size_cfg.gen, &flags); @@ -374,7 +380,13 @@ static void ws_cfg_network_size_config_set_small(ws_cfg_nw_size_t *cfg) cfg->sec_prot.sec_prot_trickle_imax = SEC_PROT_SMALL_IMAX; cfg->sec_prot.sec_prot_trickle_timer_exp = SEC_PROT_TIMER_EXPIRATIONS; cfg->sec_prot.sec_prot_retry_timeout = SEC_PROT_RETRY_TIMEOUT_SMALL; - cfg->sec_prot.sec_max_ongoing_authentication = MAX_SIMULTANEOUS_EAP_TLS_NEGOTIATIONS_SMALL; + + cfg->sec_prot.sec_max_ongoing_authentication = MAX_SIMULTANEOUS_SECURITY_NEGOTIATIONS_SMALL; + + cfg->sec_prot.initial_key_retry_delay = DEFAULT_INITIAL_KEY_RETRY_TIMER; + cfg->sec_prot.initial_key_imin = SMALL_NW_INITIAL_KEY_TRICKLE_IMIN_SECS; + cfg->sec_prot.initial_key_imax = SMALL_NW_INITIAL_KEY_TRICKLE_IMAX_SECS; + cfg->sec_prot.initial_key_retry_cnt = DEFAULT_INITIAL_KEY_RETRY_COUNT; } static void ws_cfg_network_size_config_set_medium(ws_cfg_nw_size_t *cfg) @@ -384,16 +396,16 @@ static void ws_cfg_network_size_config_set_medium(ws_cfg_nw_size_t *cfg) cfg->gen.rpl_selected_parent_max = WS_RPL_SELECTED_PARENT_MAX; // Configure the Wi-SUN timing trickle parameters - cfg->timing.disc_trickle_imin = TRICKLE_IMIN_30_SECS; // 30 seconds - cfg->timing.disc_trickle_imax = TRICKLE_IMIN_30_SECS << 5; // 960 seconds; 16 minutes + cfg->timing.disc_trickle_imin = TRICKLE_IMIN_60_SECS; // 60 seconds + cfg->timing.disc_trickle_imax = TRICKLE_IMIN_60_SECS << 4; // 960 seconds; 16 minutes cfg->timing.disc_trickle_k = 1; cfg->timing.pan_timeout = PAN_VERSION_MEDIUM_NETWORK_TIMEOUT; cfg->timing.temp_link_min_timeout = WS_NEIGHBOR_TEMPORARY_LINK_MIN_TIMEOUT_SMALL; cfg->timing.temp_eapol_min_timeout = WS_EAPOL_TEMPORARY_ENTRY_MEDIUM_TIMEOUT; // RPL configuration - cfg->bbr.dio_interval_min = WS_RPL_DIO_IMIN_MEDIUM; // 15; 32s - cfg->bbr.dio_interval_doublings = WS_RPL_DIO_DOUBLING_MEDIUM; // 2; 1024s + cfg->bbr.dio_interval_min = WS_RPL_DIO_IMIN_MEDIUM; // 17; 128s + cfg->bbr.dio_interval_doublings = WS_RPL_DIO_DOUBLING_MEDIUM; // 3; 1024s cfg->bbr.dio_redundancy_constant = WS_RPL_DIO_REDUNDANCY_MEDIUM; // 10 cfg->bbr.dag_max_rank_increase = WS_RPL_MAX_HOP_RANK_INCREASE; cfg->bbr.min_hop_rank_increase = WS_RPL_MIN_HOP_RANK_INCREASE; @@ -404,7 +416,13 @@ static void ws_cfg_network_size_config_set_medium(ws_cfg_nw_size_t *cfg) cfg->sec_prot.sec_prot_trickle_imax = SEC_PROT_SMALL_IMAX; cfg->sec_prot.sec_prot_trickle_timer_exp = SEC_PROT_TIMER_EXPIRATIONS; cfg->sec_prot.sec_prot_retry_timeout = SEC_PROT_RETRY_TIMEOUT_SMALL; - cfg->sec_prot.sec_max_ongoing_authentication = MAX_SIMULTANEOUS_EAP_TLS_NEGOTIATIONS_MEDIUM; + + cfg->sec_prot.sec_max_ongoing_authentication = MAX_SIMULTANEOUS_SECURITY_NEGOTIATIONS_MEDIUM; + + cfg->sec_prot.initial_key_retry_delay = DEFAULT_INITIAL_KEY_RETRY_TIMER; + cfg->sec_prot.initial_key_imin = MEDIUM_NW_INITIAL_KEY_TRICKLE_IMIN_SECS; + cfg->sec_prot.initial_key_imax = MEDIUM_NW_INITIAL_KEY_TRICKLE_IMAX_SECS; + cfg->sec_prot.initial_key_retry_cnt = DEFAULT_INITIAL_KEY_RETRY_COUNT; } static void ws_cfg_network_size_config_set_large(ws_cfg_nw_size_t *cfg) @@ -414,16 +432,16 @@ static void ws_cfg_network_size_config_set_large(ws_cfg_nw_size_t *cfg) cfg->gen.rpl_selected_parent_max = WS_RPL_SELECTED_PARENT_MAX; // Configure the Wi-SUN timing trickle parameters - cfg->timing.disc_trickle_imin = TRICKLE_IMIN_60_SECS; // 60 seconds - cfg->timing.disc_trickle_imax = TRICKLE_IMIN_60_SECS << 4; // 960 seconds; 16 minutes + cfg->timing.disc_trickle_imin = TRICKLE_IMIN_60_SECS << 2; // 240 seconds + cfg->timing.disc_trickle_imax = 1536; // 1536 seconds; 25 minutes cfg->timing.disc_trickle_k = 1; cfg->timing.pan_timeout = PAN_VERSION_LARGE_NETWORK_TIMEOUT; cfg->timing.temp_link_min_timeout = WS_NEIGHBOR_TEMPORARY_LINK_MIN_TIMEOUT_LARGE; cfg->timing.temp_eapol_min_timeout = WS_EAPOL_TEMPORARY_ENTRY_LARGE_TIMEOUT; // RPL configuration - cfg->bbr.dio_interval_min = WS_RPL_DIO_IMIN_LARGE; // 19; 524s, 9min - cfg->bbr.dio_interval_doublings = WS_RPL_DIO_DOUBLING_LARGE; // 1; 1024s, 17min + cfg->bbr.dio_interval_min = WS_RPL_DIO_IMIN_LARGE; // 18; 262s, 4.5min + cfg->bbr.dio_interval_doublings = WS_RPL_DIO_DOUBLING_LARGE; // 3; 2048s, 34min cfg->bbr.dio_redundancy_constant = WS_RPL_DIO_REDUNDANCY_LARGE; // 10 cfg->bbr.dag_max_rank_increase = WS_RPL_MAX_HOP_RANK_INCREASE; cfg->bbr.min_hop_rank_increase = WS_RPL_MIN_HOP_RANK_INCREASE; @@ -434,7 +452,49 @@ static void ws_cfg_network_size_config_set_large(ws_cfg_nw_size_t *cfg) cfg->sec_prot.sec_prot_trickle_imax = SEC_PROT_LARGE_IMAX; cfg->sec_prot.sec_prot_trickle_timer_exp = SEC_PROT_TIMER_EXPIRATIONS; cfg->sec_prot.sec_prot_retry_timeout = SEC_PROT_RETRY_TIMEOUT_LARGE; - cfg->sec_prot.sec_max_ongoing_authentication = MAX_SIMULTANEOUS_EAP_TLS_NEGOTIATIONS_LARGE; + + cfg->sec_prot.sec_max_ongoing_authentication = MAX_SIMULTANEOUS_SECURITY_NEGOTIATIONS_LARGE; + + cfg->sec_prot.initial_key_retry_delay = NONE_INITIAL_KEY_RETRY_TIMER; + cfg->sec_prot.initial_key_imin = LARGE_NW_INITIAL_KEY_TRICKLE_IMIN_SECS; + cfg->sec_prot.initial_key_imax = LARGE_NW_INITIAL_KEY_TRICKLE_IMAX_SECS; + cfg->sec_prot.initial_key_retry_cnt = LARGE_NW_INITIAL_KEY_RETRY_COUNT; +} + +static void ws_cfg_network_size_config_set_xlarge(ws_cfg_nw_size_t *cfg) +{ + // Configure the Wi-SUN parent configuration + cfg->gen.rpl_parent_candidate_max = WS_RPL_PARENT_CANDIDATE_MAX; + cfg->gen.rpl_selected_parent_max = WS_RPL_SELECTED_PARENT_MAX; + + // Configure the Wi-SUN timing trickle parameters + cfg->timing.disc_trickle_imin = TRICKLE_IMIN_60_SECS << 2; // 240 seconds + cfg->timing.disc_trickle_imax = 1920; // 1920 seconds; 32 minutes + cfg->timing.disc_trickle_k = 1; + cfg->timing.pan_timeout = PAN_VERSION_XLARGE_NETWORK_TIMEOUT; + cfg->timing.temp_link_min_timeout = WS_NEIGHBOR_TEMPORARY_LINK_MIN_TIMEOUT_LARGE; + cfg->timing.temp_eapol_min_timeout = WS_EAPOL_TEMPORARY_ENTRY_LARGE_TIMEOUT; + + // RPL configuration + cfg->bbr.dio_interval_min = WS_RPL_DIO_IMIN_XLARGE; // 18; 262s, 4.5min + cfg->bbr.dio_interval_doublings = WS_RPL_DIO_DOUBLING_XLARGE; // 4; 2048s, 34min + cfg->bbr.dio_redundancy_constant = WS_RPL_DIO_REDUNDANCY_XLARGE; // 10 + cfg->bbr.dag_max_rank_increase = WS_RPL_MAX_HOP_RANK_INCREASE; + cfg->bbr.min_hop_rank_increase = WS_RPL_MIN_HOP_RANK_INCREASE; + cfg->bbr.dhcp_address_lifetime = WS_DHCP_ADDRESS_LIFETIME_LARGE; + + // EAPOL configuration + cfg->sec_prot.sec_prot_trickle_imin = SEC_PROT_LARGE_IMIN; + cfg->sec_prot.sec_prot_trickle_imax = SEC_PROT_LARGE_IMAX; + cfg->sec_prot.sec_prot_trickle_timer_exp = SEC_PROT_TIMER_EXPIRATIONS; + cfg->sec_prot.sec_prot_retry_timeout = SEC_PROT_RETRY_TIMEOUT_LARGE; + + cfg->sec_prot.sec_max_ongoing_authentication = MAX_SIMULTANEOUS_SECURITY_NEGOTIATIONS_LARGE; + + cfg->sec_prot.initial_key_retry_delay = NONE_INITIAL_KEY_RETRY_TIMER; + cfg->sec_prot.initial_key_imin = EXTRA_LARGE_NW_INITIAL_KEY_TRICKLE_IMIN_SECS; + cfg->sec_prot.initial_key_imax = EXTRA_LARGE_NW_INITIAL_KEY_TRICKLE_IMAX_SECS; + cfg->sec_prot.initial_key_retry_cnt = EXTRA_LARGE_NW_INITIAL_KEY_RETRY_COUNT; } static void ws_cfg_network_size_config_set_certificate(ws_cfg_nw_size_t *cfg) @@ -464,7 +524,13 @@ static void ws_cfg_network_size_config_set_certificate(ws_cfg_nw_size_t *cfg) cfg->sec_prot.sec_prot_trickle_imax = SEC_PROT_SMALL_IMAX; cfg->sec_prot.sec_prot_trickle_timer_exp = SEC_PROT_TIMER_EXPIRATIONS; cfg->sec_prot.sec_prot_retry_timeout = SEC_PROT_RETRY_TIMEOUT_SMALL; - cfg->sec_prot.sec_max_ongoing_authentication = MAX_SIMULTANEOUS_EAP_TLS_NEGOTIATIONS_SMALL; + + cfg->sec_prot.sec_max_ongoing_authentication = MAX_SIMULTANEOUS_SECURITY_NEGOTIATIONS_SMALL; + + cfg->sec_prot.initial_key_retry_delay = DEFAULT_INITIAL_KEY_RETRY_TIMER; + cfg->sec_prot.initial_key_imin = SMALL_NW_INITIAL_KEY_TRICKLE_IMIN_SECS; + cfg->sec_prot.initial_key_imax = SMALL_NW_INITIAL_KEY_TRICKLE_IMAX_SECS; + cfg->sec_prot.initial_key_retry_cnt = DEFAULT_INITIAL_KEY_RETRY_COUNT; } static int8_t ws_cfg_gen_default_set(ws_gen_cfg_t *cfg) @@ -617,8 +683,8 @@ int8_t ws_cfg_phy_set(protocol_interface_info_entry_t *cur, ws_phy_cfg_t *cfg, w static int8_t ws_cfg_timing_default_set(ws_timing_cfg_t *cfg) { // Configure the Wi-SUN timing trickle parameters - cfg->disc_trickle_imin = TRICKLE_IMIN_30_SECS; // 30 seconds - cfg->disc_trickle_imax = TRICKLE_IMIN_30_SECS << 5; // 960 seconds; 16 minutes + cfg->disc_trickle_imin = TRICKLE_IMIN_60_SECS; // 60 seconds + cfg->disc_trickle_imax = TRICKLE_IMIN_60_SECS << 4; // 960 seconds; 16 minutes cfg->disc_trickle_k = 1; cfg->pan_timeout = PAN_VERSION_MEDIUM_NETWORK_TIMEOUT; cfg->temp_link_min_timeout = WS_NEIGHBOR_TEMPORARY_LINK_MIN_TIMEOUT_SMALL; @@ -695,13 +761,13 @@ int8_t ws_cfg_timing_set(protocol_interface_info_entry_t *cur, ws_timing_cfg_t * static int8_t ws_cfg_bbr_default_set(ws_bbr_cfg_t *cfg) { // Something in between - // imin: 15 (32s) - // doublings:5 (960s) + // imin: 17 (128s) + // doublings:3 (1024s) // redundancy; 10 - //ws_bbr_rpl_config(cur, 15, 5, 10, WS_RPL_MAX_HOP_RANK_INCREASE, WS_RPL_MIN_HOP_RANK_INCREASE); + //ws_bbr_rpl_config(cur, 17, 3, 10, WS_RPL_MAX_HOP_RANK_INCREASE, WS_RPL_MIN_HOP_RANK_INCREASE); - cfg->dio_interval_min = 15; // 32s - cfg->dio_interval_doublings = 5; // 1024s + cfg->dio_interval_min = WS_RPL_DIO_IMIN_MEDIUM; // 128s + cfg->dio_interval_doublings = WS_RPL_DIO_DOUBLING_MEDIUM; // 1024s cfg->dio_redundancy_constant = 10; cfg->dag_max_rank_increase = WS_RPL_MAX_HOP_RANK_INCREASE; cfg->min_hop_rank_increase = WS_RPL_MIN_HOP_RANK_INCREASE; @@ -1011,7 +1077,12 @@ static int8_t ws_cfg_sec_prot_default_set(ws_sec_prot_cfg_t *cfg) cfg->sec_prot_trickle_imax = SEC_PROT_SMALL_IMAX; cfg->sec_prot_trickle_timer_exp = 2; cfg->sec_prot_retry_timeout = SEC_PROT_RETRY_TIMEOUT_SMALL; - cfg->sec_max_ongoing_authentication = MAX_SIMULTANEOUS_EAP_TLS_NEGOTIATIONS_MEDIUM; + cfg->sec_max_ongoing_authentication = MAX_SIMULTANEOUS_SECURITY_NEGOTIATIONS_MEDIUM; + cfg->initial_key_retry_delay = DEFAULT_INITIAL_KEY_RETRY_TIMER; + cfg->initial_key_imin = MEDIUM_NW_INITIAL_KEY_TRICKLE_IMIN_SECS; + cfg->initial_key_imax = MEDIUM_NW_INITIAL_KEY_TRICKLE_IMAX_SECS; + cfg->initial_key_retry_cnt = DEFAULT_INITIAL_KEY_RETRY_COUNT; + return CFG_SETTINGS_OK; } @@ -1032,7 +1103,11 @@ int8_t ws_cfg_sec_prot_validate(ws_sec_prot_cfg_t *cfg, ws_sec_prot_cfg_t *new_c cfg->sec_prot_trickle_imax != new_cfg->sec_prot_trickle_imax || cfg->sec_prot_trickle_timer_exp != new_cfg->sec_prot_trickle_timer_exp || cfg->sec_prot_retry_timeout != new_cfg->sec_prot_retry_timeout || - cfg->sec_max_ongoing_authentication != new_cfg->sec_max_ongoing_authentication) { + cfg->sec_max_ongoing_authentication != new_cfg->sec_max_ongoing_authentication || + cfg->initial_key_retry_delay != new_cfg->initial_key_retry_delay || + cfg->initial_key_imin != new_cfg->initial_key_retry_delay || + cfg->initial_key_imax != new_cfg->initial_key_retry_delay || + cfg->initial_key_retry_cnt != new_cfg->initial_key_retry_delay) { return CFG_SETTINGS_CHANGED; } diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_cfg_settings.h b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_cfg_settings.h index 9011d8147b..bc46336229 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_cfg_settings.h +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_cfg_settings.h @@ -108,11 +108,15 @@ typedef struct ws_sec_timer_cfg_s { * \brief Struct ws_sec_prot_cfg_t Security protocols configuration */ typedef struct ws_sec_prot_cfg_s { - uint16_t sec_prot_retry_timeout; /**< Security protocol retry timeout; seconds; default 330 */ - uint16_t sec_prot_trickle_imin; /**< Security protocol trickle parameters Imin; seconds; default 30 */ - uint16_t sec_prot_trickle_imax; /**< Security protocol trickle parameters Imax; seconds; default 90 */ - uint8_t sec_prot_trickle_timer_exp; /**< Security protocol trickle timer expirations; default 2 */ - uint16_t sec_max_ongoing_authentication; /**< Pae authenticator max Accept ongoing authentication count */ + uint16_t sec_prot_retry_timeout; /**< Security protocol retry timeout; seconds; default 330 */ + uint16_t sec_prot_trickle_imin; /**< Security protocol trickle parameters Imin; seconds; default 30 */ + uint16_t sec_prot_trickle_imax; /**< Security protocol trickle parameters Imax; seconds; default 90 */ + uint8_t sec_prot_trickle_timer_exp; /**< Security protocol trickle timer expirations; default 2 */ + uint16_t sec_max_ongoing_authentication; /**< Pae authenticator max Accept ongoing authentication count */ + uint16_t initial_key_retry_delay; /**< Delay before starting initial key trickle; seconds; default 120 */ + uint16_t initial_key_imin; /**< Initial key trickle Imin; seconds; default 360 */ + uint16_t initial_key_imax; /**< Initial key trickle Imax; seconds; default 720 */ + uint8_t initial_key_retry_cnt; /**< Number of initial key retries; default 2 */ } ws_sec_prot_cfg_t; /** diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_common.c b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_common.c index 169da011ac..010f6c14ac 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_common.c +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_common.c @@ -49,12 +49,34 @@ 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) +int8_t ws_generate_channel_list(uint32_t *channel_mask, uint16_t number_of_channels, uint8_t regulatory_domain, uint8_t operating_class) { - (void)regulatory_domain; - for (uint8_t i = 0; i < number_of_channels; i++) { - channel_mask[0 + (i / 32)] |= (1 << (i % 32)); + 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; + } + } + + // Clear channel mask + for (uint8_t i = 0; i < 8; i++) { + channel_mask[i] = 0; + } + + // Set channel maks outside excluded 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)); + } } return 0; } @@ -159,6 +181,19 @@ int8_t ws_common_regulatory_domain_config(protocol_interface_info_entry_t *cur, } 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; + } else { + return -1; + } } else if (hopping_schdule->regulatory_domain == REG_DOMAIN_JP) { if (hopping_schdule->operating_class == 1) { hopping_schdule->ch0_freq = 9206; @@ -189,6 +224,7 @@ int8_t ws_common_regulatory_domain_config(protocol_interface_info_entry_t *cur, if (!hopping_schdule->number_of_channels) { return -1; } + return 0; } @@ -232,6 +268,14 @@ uint16_t ws_common_channel_number_calc(uint8_t regulatory_domain, uint8_t operat } else if (operating_class == 3) { 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; + } } else if (regulatory_domain == REG_DOMAIN_WW) { if (operating_class == 1) { // TODO we dont support this yet, but it is used as test value @@ -391,8 +435,10 @@ uint32_t ws_common_latency_estimate_get(protocol_interface_info_entry_t *cur) latency = 4000; } else if (network_size <= NETWORK_SIZE_MEDIUM) { latency = 8000; - } else { + } else if (network_size <= NETWORK_SIZE_LARGE) { latency = 16000; + } else { + latency = 24000; } return latency; diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_common.h b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_common.h index ec6a7b9955..08d726ee6b 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_common.h +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_common.h @@ -113,7 +113,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); +int8_t ws_generate_channel_list(uint32_t *channel_mask, uint16_t number_of_channels, uint8_t regulatory_domain, uint8_t operating_class); uint32_t ws_decode_channel_spacing(uint8_t channel_spacing); diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_common_defines.h b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_common_defines.h index 2de37bf842..749a5aa1fa 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_common_defines.h +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_common_defines.h @@ -242,7 +242,6 @@ typedef struct ws_bs_ie { #define WS_NEIGHBOR_ETX_SAMPLE_MAX 3 #define WS_NEIGHBOR_FIRST_ETX_SAMPLE_MIN_COUNT 3 //This can't be bigger than WS_NEIGHBOR_ETX_SAMPLE_MAX -#define WS_NEIGHBOUR_MAX_CANDIDATE_PROBE 5 #define WS_PROBE_INIT_BASE_SECONDS 8 @@ -322,7 +321,7 @@ typedef struct ws_bs_ie { /* * Automatic CCA threshold: default threshold and range in dBm. */ -#define CCA_DEFAULT_DBM -85 +#define CCA_DEFAULT_DBM -60 #define CCA_HIGH_LIMIT -60 #define CCA_LOW_LIMIT -100 diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_config.h b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_config.h index 9b84a5dbfb..6b00d6004c 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_config.h +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_config.h @@ -31,14 +31,18 @@ #define WS_RPL_DIO_DOUBLING_SMALL 2 #define WS_RPL_DIO_REDUNDANCY_SMALL 0 -#define WS_RPL_DIO_IMIN_MEDIUM 15 -#define WS_RPL_DIO_DOUBLING_MEDIUM 5 +#define WS_RPL_DIO_IMIN_MEDIUM 17 +#define WS_RPL_DIO_DOUBLING_MEDIUM 3 #define WS_RPL_DIO_REDUNDANCY_MEDIUM 10 -#define WS_RPL_DIO_IMIN_LARGE 19 -#define WS_RPL_DIO_DOUBLING_LARGE 1 +#define WS_RPL_DIO_IMIN_LARGE 18 +#define WS_RPL_DIO_DOUBLING_LARGE 3 #define WS_RPL_DIO_REDUNDANCY_LARGE 10 // May need some tuning still +#define WS_RPL_DIO_IMIN_XLARGE 18 +#define WS_RPL_DIO_DOUBLING_XLARGE 4 +#define WS_RPL_DIO_REDUNDANCY_XLARGE 10 // May need some tuning still + #define WS_RPL_DIO_IMIN_AUTOMATIC 14 #define WS_RPL_DIO_DOUBLING_AUTOMATIC 3 #define WS_RPL_DIO_REDUNDANCY_AUTOMATIC 0 @@ -68,7 +72,10 @@ // RPL version number update intervall // after restart version numbers are increased faster and then slowed down when network is stable #define RPL_VERSION_LIFETIME 12*3600 -#define RPL_VERSION_LIFETIME_RESTART 3600 +#define RPL_VERSION_LIFETIME_RESTART_SMALL 3600 +#define RPL_VERSION_LIFETIME_RESTART_MEDIUM 2*3600 +#define RPL_VERSION_LIFETIME_RESTART_LARGE 4*3600 +#define RPL_VERSION_LIFETIME_RESTART_EXTRA_LARGE 8*3600 /* Border router connection lost timeout * @@ -85,6 +92,8 @@ #define PAN_VERSION_LARGE_NETWORK_TIMEOUT 90*60 +#define PAN_VERSION_XLARGE_NETWORK_TIMEOUT 120*60 + /* Routing Cost Weighting factor */ #define PRC_WEIGHT_FACTOR 256 @@ -157,10 +166,11 @@ extern uint8_t DEVICE_MIN_SENS; /* * MAC frame counter NVM storing configuration */ -#define FRAME_COUNTER_STORE_INTERVAL 60 // Time interval (on seconds) between frame counter store operations -#define FRAME_COUNTER_STORE_TRIGGER 5 // Delay (on seconds) before storing, when storing of frame counters is triggered -#define FRAME_COUNTER_INCREMENT 1000 // How much frame counter is incremented on start up -#define FRAME_COUNTER_STORE_THRESHOLD 800 // How much frame counter must increment before it is stored +#define FRAME_COUNTER_STORE_INTERVAL 60 // Time interval (on seconds) between checking if frame counter storing is needed +#define FRAME_COUNTER_STORE_FORCE_INTERVAL (3600 * 20) // Time interval (on seconds) before frame counter storing is forced (if no other storing operations triggered) +#define FRAME_COUNTER_STORE_TRIGGER 5 // Delay (on seconds) before storing, when storing of frame counters is triggered +#define FRAME_COUNTER_INCREMENT 1000 // How much frame counter is incremented on start up +#define FRAME_COUNTER_STORE_THRESHOLD 800 // How much frame counter must increment before it is stored /* @@ -203,10 +213,10 @@ extern uint8_t DEVICE_MIN_SENS; #define SEC_PROT_TIMER_EXPIRATIONS 2 // Number of retries -// Maximum number of simultaneous EAP-TLS negotiations -#define MAX_SIMULTANEOUS_EAP_TLS_NEGOTIATIONS_SMALL 3 -#define MAX_SIMULTANEOUS_EAP_TLS_NEGOTIATIONS_MEDIUM 20 -#define MAX_SIMULTANEOUS_EAP_TLS_NEGOTIATIONS_LARGE 50 +// Maximum number of simultaneous security negotiations +#define MAX_SIMULTANEOUS_SECURITY_NEGOTIATIONS_SMALL 3 +#define MAX_SIMULTANEOUS_SECURITY_NEGOTIATIONS_MEDIUM 20 +#define MAX_SIMULTANEOUS_SECURITY_NEGOTIATIONS_LARGE 50 /* * Security protocol timer configuration parameters @@ -222,4 +232,33 @@ extern uint8_t DEVICE_MIN_SENS; #define DEFAULT_GTK_MAX_MISMATCH 64 // 64 minutes #define DEFAULT_GTK_NEW_INSTALL_REQUIRED 80 // 80 percent of GTK lifetime --> 24 days +/* + * Security protocol initial EAPOL-key parameters + */ + +// How long the wait is before the first initial EAPOL-key retry +#define DEFAULT_INITIAL_KEY_RETRY_TIMER 120 +#define NONE_INITIAL_KEY_RETRY_TIMER 0 + +// Small network Default trickle values for sending of initial EAPOL-key +#define SMALL_NW_INITIAL_KEY_TRICKLE_IMIN_SECS 360 /* 6 to 8.3 minutes */ +#define SMALL_NW_INITIAL_KEY_TRICKLE_IMAX_SECS 500 + +// Small network Default trickle values for sending of initial EAPOL-key +#define MEDIUM_NW_INITIAL_KEY_TRICKLE_IMIN_SECS 360 /* 6 to 12 minutes */ +#define MEDIUM_NW_INITIAL_KEY_TRICKLE_IMAX_SECS 720 + +// Large network trickle values for sending of initial EAPOL-key +#define LARGE_NW_INITIAL_KEY_TRICKLE_IMIN_SECS 600 /* 10 to 20 minutes */ +#define LARGE_NW_INITIAL_KEY_TRICKLE_IMAX_SECS 1200 +#define LARGE_NW_INITIAL_KEY_RETRY_COUNT 4 + +// Very slow network values for sending of initial EAPOL-key +#define EXTRA_LARGE_NW_INITIAL_KEY_TRICKLE_IMIN_SECS 600 /* 10 to 20 minutes */ +#define EXTRA_LARGE_NW_INITIAL_KEY_TRICKLE_IMAX_SECS 1200 +#define EXTRA_LARGE_NW_INITIAL_KEY_RETRY_COUNT 4 + +// How many times sending of initial EAPOL-key is retried +#define DEFAULT_INITIAL_KEY_RETRY_COUNT 2 + #endif /* WS_CONFIG_H_ */ diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_eapol_pdu.c b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_eapol_pdu.c index ffe83c4a48..f20530d466 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_eapol_pdu.c +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_eapol_pdu.c @@ -31,6 +31,7 @@ #include "6LoWPAN/MAC/mpx_api.h" #include "6LoWPAN/ws/ws_config.h" #include "6LoWPAN/ws/ws_eapol_pdu.h" +#include "6LoWPAN/ws/ws_llc.h" #ifdef HAVE_WS @@ -49,6 +50,7 @@ typedef NS_LIST_HEAD(eapol_pdu_msdu_t, link) eapol_pdu_msdu_list_t; typedef struct { uint8_t priority; + bool filter_requsted: 1; ws_eapol_pdu_address_check *addr_check; ws_eapol_pdu_receive *receive; ns_list_link_t link; @@ -147,6 +149,7 @@ int8_t ws_eapol_pdu_cb_register(protocol_interface_info_entry_t *interface_ptr, new_cb->priority = cb_data->priority; new_cb->addr_check = cb_data->addr_check; new_cb->receive = cb_data->receive; + new_cb->filter_requsted = cb_data->filter_requsted; ns_list_foreach(eapol_pdu_recv_cb_t, entry, &eapol_pdu_data->recv_cb_list) { if (new_cb->priority <= entry->priority) { @@ -307,6 +310,11 @@ static void ws_eapol_pdu_mpx_data_indication(const mpx_api_t *api, const struct ns_list_foreach(eapol_pdu_recv_cb_t, entry, &eapol_pdu_data->recv_cb_list) { if (entry->addr_check(eapol_pdu_data->interface_ptr, data->SrcAddr) >= 0) { + if (entry->filter_requsted && !ws_llc_eapol_relay_forward_filter(eapol_pdu_data->interface_ptr, data->SrcAddr, data->DSN, data->timestamp)) { + tr_info("EAPOL relay filter drop"); + return; + } + entry->receive(eapol_pdu_data->interface_ptr, data->SrcAddr, data->msdu_ptr, data->msduLength); break; } diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_eapol_pdu.h b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_eapol_pdu.h index 75f4ef4074..c385e9313c 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_eapol_pdu.h +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_eapol_pdu.h @@ -99,6 +99,7 @@ typedef enum { typedef struct { eapol_pdu_recv_prior_t priority; /**< Priority: high, medium or low */ + bool filter_requsted: 1; /**< True when EAPOL temporary filter requsted, false for normal functionality */ ws_eapol_pdu_address_check *addr_check; /**< Address check callback */ ws_eapol_pdu_receive *receive; /**< PDU receive callback */ } eapol_pdu_recv_cb_data_t; diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_eapol_relay.c b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_eapol_relay.c index 367181bfcc..a5a83c3ec3 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_eapol_relay.c +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_eapol_relay.c @@ -53,6 +53,7 @@ static void ws_eapol_relay_socket_cb(void *cb); static const eapol_pdu_recv_cb_data_t eapol_pdu_recv_cb_data = { .priority = EAPOL_PDU_RECV_LOW_PRIORITY, + .filter_requsted = true, .addr_check = ws_eapol_relay_eapol_pdu_address_check, .receive = ws_eapol_relay_eapol_pdu_receive }; diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_llc.h b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_llc.h index fdb8f946be..fd3b010501 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_llc.h +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_llc.h @@ -78,15 +78,21 @@ typedef struct llc_neighbour_req { struct ws_neighbor_class_entry *ws_neighbor; /**< Wi-sun Neighbor information entry. */ } llc_neighbour_req_t; +typedef struct eapol_temporary_info_s { + uint8_t eapol_rx_relay_filter; /*!< seconds for dropping duplicate id */ + uint8_t last_rx_mac_sequency; /*!< Only compared when Timer is active */ + uint16_t eapol_timeout; /*!< EAPOL relay Temporary entry lifetime */ +} eapol_temporary_info_t; + /** * Neighbor temporary structure for storage FHSS data before create a real Neighbour info */ typedef struct ws_neighbor_temp_class_s { struct ws_neighbor_class_entry neigh_info_list; /*!< Allocated hopping info array*/ + eapol_temporary_info_t eapol_temp_info; uint8_t mac64[8]; uint8_t mpduLinkQuality; int8_t signal_dbm; - uint16_t eapol_timeout; ns_list_link_t link; } ws_neighbor_temp_class_t; @@ -220,6 +226,8 @@ void ws_llc_hopping_schedule_config(struct protocol_interface_info_entry *interf void ws_llc_timer_seconds(struct protocol_interface_info_entry *interface, uint16_t seconds_update); +bool ws_llc_eapol_relay_forward_filter(struct protocol_interface_info_entry *interface, const uint8_t *joiner_eui64, uint8_t mac_sequency, uint32_t rx_timestamp); + ws_neighbor_temp_class_t *ws_llc_get_multicast_temp_entry(struct protocol_interface_info_entry *interface, const uint8_t *mac64); void ws_llc_free_multicast_temp_entry(struct protocol_interface_info_entry *interface, ws_neighbor_temp_class_t *neighbor); diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_llc_data_service.c b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_llc_data_service.c index d82fc467d1..73f468a27c 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_llc_data_service.c +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_llc_data_service.c @@ -100,7 +100,7 @@ typedef struct { typedef NS_LIST_HEAD(llc_message_t, link) llc_message_list_t; #define MAX_NEIGH_TEMPORARY_MULTICAST_SIZE 5 -#define MAX_NEIGH_TEMPORRY_EAPOL_SIZE 15 +#define MAX_NEIGH_TEMPORRY_EAPOL_SIZE 30 #define MAX_NEIGH_TEMPORAY_LIST_SIZE (MAX_NEIGH_TEMPORARY_MULTICAST_SIZE + MAX_NEIGH_TEMPORRY_EAPOL_SIZE) typedef struct { @@ -431,7 +431,7 @@ static void ws_llc_mac_confirm_cb(const mac_api_t *api, const mcps_data_conf_t * ws_neighbor_temp_class_t *temp_entry = ws_llc_discover_eapol_temp_entry(base->temp_entries, message->dst_address); if (temp_entry) { //Update Temporary Lifetime - temp_entry->eapol_timeout = interface->ws_info->cfg->timing.temp_eapol_min_timeout + 1; + temp_entry->eapol_temp_info.eapol_timeout = interface->ws_info->cfg->timing.temp_eapol_min_timeout + 1; } } } @@ -449,7 +449,7 @@ static void ws_llc_mac_confirm_cb(const mac_api_t *api, const mcps_data_conf_t * } if (message->dst_address_type == MAC_ADDR_MODE_64_BIT && base->ws_neighbor_info_request_cb(interface, message->dst_address, &neighbor_info, false)) { - etx_transm_attempts_update(interface->id, 1 + data->tx_retries, success, neighbor_info.neighbor->index); + etx_transm_attempts_update(interface->id, 1 + data->tx_retries, success, neighbor_info.neighbor->index, neighbor_info.neighbor->mac64); //TODO discover RSL from Enchanced ACK Header IE elements ws_utt_ie_t ws_utt; if (ws_wh_utt_read(conf_data->headerIeList, conf_data->headerIeListLength, &ws_utt)) { @@ -648,6 +648,11 @@ static void ws_llc_data_indication_cb(const mac_api_t *api, const mcps_data_ind_ } } + if (!multicast && !ws_neighbor_class_neighbor_duplicate_packet_check(neighbor_info.ws_neighbor, data->DSN, data->timestamp)) { + tr_info("Drop duplicate message"); + return; + } + ws_neighbor_class_neighbor_unicast_time_info_update(neighbor_info.ws_neighbor, &ws_utt, data->timestamp); if (us_ie_inline) { ws_neighbor_class_neighbor_unicast_schedule_set(neighbor_info.ws_neighbor, &us_ie); @@ -675,7 +680,7 @@ static void ws_llc_data_indication_cb(const mac_api_t *api, const mcps_data_ind_ if (neighbor_info.neighbor) { //Refresh ETX dbm - etx_lqi_dbm_update(interface->id, data->mpduLinkQuality, data->signal_dbm, neighbor_info.neighbor->index); + etx_lqi_dbm_update(interface->id, data->mpduLinkQuality, data->signal_dbm, neighbor_info.neighbor->index, neighbor_info.neighbor->mac64); if (data->Key.SecurityLevel) { //SET trusted state mac_neighbor_table_trusted_neighbor(mac_neighbor_info(interface), neighbor_info.neighbor, true); @@ -740,7 +745,7 @@ static void ws_llc_eapol_indication_cb(const mac_api_t *api, const mcps_data_ind return; } //Update Temporary Lifetime - temp_entry->eapol_timeout = interface->ws_info->cfg->timing.temp_eapol_min_timeout + 1; + temp_entry->eapol_temp_info.eapol_timeout = interface->ws_info->cfg->timing.temp_eapol_min_timeout + 1; neighbor_info.ws_neighbor = &temp_entry->neigh_info_list; //Storage Signal info for future ETX update possibility @@ -838,78 +843,6 @@ static void ws_llc_mac_indication_cb(const mac_api_t *api, const mcps_data_ind_t if (ws_utt.message_type == WS_FT_EAPOL) { ws_llc_eapol_indication_cb(api, data, ie_ext, ws_utt); return; - llc_data_base_t *base = ws_llc_mpx_frame_common_validates(api, data, ws_utt); - if (!base) { - return; - } - - //Discover MPX header and handler - mac_payload_IE_t mpx_ie; - mpx_msg_t mpx_frame; - mpx_user_t *user_cb = ws_llc_mpx_header_parse(base, ie_ext, &mpx_frame, &mpx_ie); - if (!user_cb) { - return; - } - - mac_payload_IE_t ws_wp_nested; - ws_us_ie_t us_ie; - bool us_ie_inline = false; - bool bs_ie_inline = false; - ws_wp_nested.id = WS_WP_NESTED_IE; - ws_bs_ie_t ws_bs_ie; - if (mac_ie_payload_discover(ie_ext->payloadIeList, ie_ext->payloadIeListLength, &ws_wp_nested) > 2) { - us_ie_inline = ws_wp_nested_us_read(ws_wp_nested.content_ptr, ws_wp_nested.length, &us_ie); - bs_ie_inline = ws_wp_nested_bs_read(ws_wp_nested.content_ptr, ws_wp_nested.length, &ws_bs_ie); - } - - //Validate Unicast shedule Channel Plan - if (us_ie_inline && !ws_bootstrap_validate_channel_plan(&us_ie, base->interface_ptr)) { - //Channel plan configuration mismatch - return; - } - - llc_neighbour_req_t neighbor_info; - - if (!base->ws_neighbor_info_request_cb(base->interface_ptr, data->SrcAddr, &neighbor_info, true)) { - //tr_debug("Drop message no neighbor"); - return; - } - - ws_neighbor_class_neighbor_unicast_time_info_update(neighbor_info.ws_neighbor, &ws_utt, data->timestamp); - if (us_ie_inline) { - ws_neighbor_class_neighbor_unicast_schedule_set(neighbor_info.ws_neighbor, &us_ie); - } - //Update BS if it is part of message - if (bs_ie_inline) { - ws_neighbor_class_neighbor_broadcast_schedule_set(neighbor_info.ws_neighbor, &ws_bs_ie); - } - - uint8_t auth_eui64[8]; - //Discover and write Auhtenticator EUI-64 - if (ws_wh_ea_read(ie_ext->headerIeList, ie_ext->headerIeListLength, auth_eui64)) { - ws_pae_controller_border_router_addr_write(base->interface_ptr, auth_eui64); - } - - - //Update BT if it is part of message - ws_bt_ie_t ws_bt; - if (ws_wh_bt_read(ie_ext->headerIeList, ie_ext->headerIeListLength, &ws_bt)) { - ws_neighbor_class_neighbor_broadcast_time_info_update(neighbor_info.ws_neighbor, &ws_bt, data->timestamp); - if (neighbor_info.neighbor) { - if (neighbor_info.neighbor->link_role == PRIORITY_PARENT_NEIGHBOUR) { - // We have broadcast schedule set up set the broadcast parent schedule - ns_fhss_ws_set_parent(base->interface_ptr->ws_info->fhss_api, neighbor_info.neighbor->mac64, &neighbor_info.ws_neighbor->fhss_data.bc_timing_info, false); - } else { - ws_bootstrap_eapol_parent_synch(base->interface_ptr, &neighbor_info); - } - } - } - - mcps_data_ind_t data_ind = *data; - data_ind.msdu_ptr = mpx_frame.frame_ptr; - data_ind.msduLength = mpx_frame.frame_length; - user_cb->data_ind(&base->mpx_data_base.mpx_api, &data_ind); - return; } } @@ -1401,6 +1334,7 @@ static void ws_init_temporary_neigh_data(ws_neighbor_temp_class_t *entry, const entry->neigh_info_list.rsl_in = RSL_UNITITIALIZED; entry->neigh_info_list.rsl_out = RSL_UNITITIALIZED; memcpy(entry->mac64, mac64, 8); + entry->eapol_temp_info.eapol_rx_relay_filter = 0; } @@ -1725,13 +1659,51 @@ void ws_llc_timer_seconds(struct protocol_interface_info_entry *interface, uint1 } ns_list_foreach_safe(ws_neighbor_temp_class_t, entry, &base->temp_entries->active_eapol_temp_neigh) { - if (entry->eapol_timeout <= seconds_update) { + if (entry->eapol_temp_info.eapol_timeout <= seconds_update) { ns_list_remove(&base->temp_entries->active_eapol_temp_neigh, entry); ns_list_add_to_end(&base->temp_entries->free_temp_neigh, entry); } else { - entry->eapol_timeout -= seconds_update; + entry->eapol_temp_info.eapol_timeout -= seconds_update; + if (entry->eapol_temp_info.eapol_rx_relay_filter == 0) { + //No active filter period + continue; + } + + //Update filter time + if (entry->eapol_temp_info.eapol_rx_relay_filter <= seconds_update) { + entry->eapol_temp_info.eapol_rx_relay_filter = 0; + } else { + entry->eapol_temp_info.eapol_rx_relay_filter -= seconds_update; + } } } } +bool ws_llc_eapol_relay_forward_filter(struct protocol_interface_info_entry *interface, const uint8_t *joiner_eui64, uint8_t mac_sequency, uint32_t rx_timestamp) +{ + llc_data_base_t *base = ws_llc_discover_by_interface(interface); + if (!base) { + return false; + } + + ws_neighbor_temp_class_t *neighbor = ws_llc_discover_eapol_temp_entry(base->temp_entries, joiner_eui64); + if (!neighbor) { + llc_neighbour_req_t neighbor_info; + //Discover here Normal Neighbour + if (!base->ws_neighbor_info_request_cb(interface, joiner_eui64, &neighbor_info, false)) { + return false; + } + return ws_neighbor_class_neighbor_duplicate_packet_check(neighbor_info.ws_neighbor, mac_sequency, rx_timestamp); + } + + if (neighbor->eapol_temp_info.eapol_rx_relay_filter && neighbor->eapol_temp_info.last_rx_mac_sequency == mac_sequency) { + return false; + } + neighbor->eapol_temp_info.last_rx_mac_sequency = mac_sequency; + neighbor->eapol_temp_info.eapol_rx_relay_filter = 6; //Activate 5-5.99 seconds filter time + return true; + +} + + #endif diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_management_api.c b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_management_api.c index cd4ce0cd80..ef9e9cffbd 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_management_api.c +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_management_api.c @@ -41,9 +41,11 @@ int ws_management_node_init( protocol_interface_info_entry_t *cur; cur = protocol_stack_interface_info_get_by_id(interface_id); + if (interface_id >= 0 && (!cur || !ws_info(cur))) { return -1; } + if (!network_name_ptr || !fhss_timer_ptr) { return -2; } @@ -70,7 +72,9 @@ int ws_management_node_init( return -4; } - cur->ws_info->fhss_timer_ptr = fhss_timer_ptr; + if (cur && ws_info(cur)) { + cur->ws_info->fhss_timer_ptr = fhss_timer_ptr; + } return 0; } @@ -398,7 +402,7 @@ int ws_management_channel_plan_set( protocol_interface_info_entry_t *cur; cur = protocol_stack_interface_info_get_by_id(interface_id); - if (interface_id >= 0 && (!cur || !ws_info(cur))) { + if (!cur || !ws_info(cur)) { return -1; } cur->ws_info->hopping_schdule.channel_plan = channel_plan; diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_neighbor_class.c b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_neighbor_class.c index 7e4e7eedc0..214c46f871 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_neighbor_class.c +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_neighbor_class.c @@ -322,5 +322,32 @@ void ws_neighbor_class_rsl_out_calculate(ws_neighbor_class_entry_t *ws_neighbor, return; } + +bool ws_neighbor_class_neighbor_duplicate_packet_check(ws_neighbor_class_entry_t *ws_neighbor, uint8_t mac_dsn, uint32_t rx_timestamp) +{ + if (ws_neighbor->last_DSN != mac_dsn) { + // New packet allways accepted + ws_neighbor->last_DSN = mac_dsn; + return true; + } + + if (!ws_neighbor->unicast_data_rx) { + // No unicast info stored always accepted + return true; + } + + rx_timestamp -= ws_neighbor->fhss_data.uc_timing_info.utt_rx_timestamp; + rx_timestamp /= 1000000; //Convert to s + + //Compare only when last rx timestamp is less than 5 seconds + if (rx_timestamp < 5) { + //Packet is sent too fast filter it out + return false; + } + + return true; +} + + #endif /* HAVE_WS */ diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_neighbor_class.h b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_neighbor_class.h index c381b43f50..f470a25a8b 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_neighbor_class.h +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_neighbor_class.h @@ -28,6 +28,7 @@ typedef struct ws_neighbor_class_entry { uint16_t rsl_in; /*!< RSL EWMA heard from neighbour*/ uint16_t rsl_out; /*!< RSL EWMA heard by neighbour*/ uint16_t routing_cost; /*!< ETX to border Router. */ + uint8_t last_DSN; bool candidate_parent: 1; bool broadcast_timing_info_stored: 1; bool broadcast_shedule_info_stored: 1; @@ -181,4 +182,6 @@ void ws_neighbor_class_rsl_in_calculate(ws_neighbor_class_entry_t *ws_neighbor, */ void ws_neighbor_class_rsl_out_calculate(ws_neighbor_class_entry_t *ws_neighbor, uint8_t rsl_reported); +bool ws_neighbor_class_neighbor_duplicate_packet_check(ws_neighbor_class_entry_t *ws_neighbor, uint8_t mac_dsn, uint32_t rx_timestamp); + #endif /* WS_NEIGHBOR_CLASS_H_ */ diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_pae_auth.c b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_pae_auth.c index b28f929f15..077c3ae580 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_pae_auth.c +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_pae_auth.c @@ -59,19 +59,18 @@ #define PAE_TASKLET_EVENT 2 #define PAE_TASKLET_TIMER 3 -// Wait for for supplicant to indicate activity (e.g. to send a message) -#define WAIT_FOR_AUTHENTICATION_TICKS 5 * 60 * 10 // 5 minutes - +/* Wait for supplicant to indicate activity (e.g. to send a message) when + authentication is ongoing */ +#define WAIT_FOR_AUTHENTICATION_TICKS 2 * 60 * 10 // 2 minutes +// Wait after authentication has completed before supplicant entry goes inactive +#define WAIT_AFTER_AUTHENTICATION_TICKS 15 * 10 // 15 seconds /* If EAP-TLS is delayed due to simultaneous negotiations limit, defines how long to wait for previous negotiation to complete */ #define EAP_TLS_NEGOTIATION_TRIGGER_TIMEOUT 60 * 10 // 60 seconds // Default for maximum number of supplicants -#define SUPPLICANT_MAX_NUMBER 1000 - -// Default for maximum number of active supplicants (making security negotiations) -#define ACTIVE_SUPPLICANT_MAX_NUMBER 100 +#define SUPPLICANT_MAX_NUMBER 5000 /* Default for number of supplicants to purge per garbage collect call from nanostack monitor */ @@ -99,7 +98,6 @@ typedef struct { sec_timer_cfg_t *sec_timer_cfg; /**< Timer configuration */ sec_prot_cfg_t *sec_prot_cfg; /**< Protocol Configuration */ uint16_t supp_max_number; /**< Max number of stored supplicants */ - uint16_t slow_timer_seconds; /**< Slow timer seconds */ bool timer_running : 1; /**< Timer is running */ bool gtk_new_inst_req_exp : 1; /**< GTK new install required timer expired */ bool gtk_new_act_time_exp: 1; /**< GTK new activation time expired */ @@ -128,7 +126,7 @@ static void ws_pae_auth_kmp_api_create_indication(kmp_api_t *kmp, kmp_type_e typ static void ws_pae_auth_kmp_api_finished_indication(kmp_api_t *kmp, kmp_result_e result, kmp_sec_keys_t *sec_keys); static void ws_pae_auth_next_kmp_trigger(pae_auth_t *pae_auth, supp_entry_t *supp_entry); static kmp_type_e ws_pae_auth_next_protocol_get(pae_auth_t *pae_auth, supp_entry_t *supp_entry); -static kmp_api_t *ws_pae_auth_kmp_create_and_start(kmp_service_t *service, kmp_type_e type, supp_entry_t *supp_entry, sec_prot_cfg_t *cfg); +static kmp_api_t *ws_pae_auth_kmp_create_and_start(kmp_service_t *service, kmp_type_e type, supp_entry_t *supp_entry, sec_prot_cfg_t *prot_cfg, sec_timer_cfg_t *timer_cfg); static void ws_pae_auth_kmp_api_finished(kmp_api_t *kmp); static int8_t tasklet_id = -1; @@ -168,7 +166,6 @@ int8_t ws_pae_auth_init(protocol_interface_info_entry_t *interface_ptr, sec_prot pae_auth->sec_prot_cfg = sec_prot_cfg; pae_auth->supp_max_number = SUPPLICANT_MAX_NUMBER; - pae_auth->slow_timer_seconds = 0; pae_auth->gtk_new_inst_req_exp = false; pae_auth->gtk_new_act_time_exp = false; @@ -709,11 +706,7 @@ void ws_pae_auth_slow_timer(uint16_t seconds) } } - pae_auth->slow_timer_seconds += seconds; - if (pae_auth->slow_timer_seconds > 60) { - ws_pae_lib_supp_list_slow_timer_update(&pae_auth->active_supp_list, pae_auth->sec_timer_cfg, pae_auth->slow_timer_seconds); - pae_auth->slow_timer_seconds = 0; - } + ws_pae_lib_supp_list_slow_timer_update(&pae_auth->active_supp_list, seconds); } // Update key storage timer @@ -871,7 +864,7 @@ static kmp_api_t *ws_pae_auth_kmp_incoming_ind(kmp_service_t *service, kmp_type_ if (!supp_entry) { // Checks if active supplicant list has space for new supplicants - if (ws_pae_lib_supp_list_active_limit_reached(&pae_auth->active_supp_list, ACTIVE_SUPPLICANT_MAX_NUMBER)) { + if (ws_pae_lib_supp_list_active_limit_reached(&pae_auth->active_supp_list, pae_auth->sec_prot_cfg->sec_max_ongoing_authentication)) { tr_debug("PAE: active limit reached, eui-64: %s", trace_array(kmp_address_eui_64_get(addr), 8)); return NULL; } @@ -906,7 +899,7 @@ static kmp_api_t *ws_pae_auth_kmp_incoming_ind(kmp_service_t *service, kmp_type_ } // Create a new KMP for initial eapol-key - kmp = kmp_api_create(service, type + IEEE_802_1X_INITIAL_KEY, pae_auth->sec_prot_cfg); + kmp = kmp_api_create(service, type + IEEE_802_1X_INITIAL_KEY, pae_auth->sec_prot_cfg, pae_auth->sec_timer_cfg); if (!kmp) { return 0; @@ -986,6 +979,8 @@ static void ws_pae_auth_next_kmp_trigger(pae_auth_t *pae_auth, supp_entry_t *sup kmp_type_e next_type = ws_pae_auth_next_protocol_get(pae_auth, supp_entry); if (next_type == KMP_TYPE_NONE) { + // Supplicant goes inactive after 15 seconds + ws_pae_lib_supp_timer_ticks_set(supp_entry, WAIT_AFTER_AUTHENTICATION_TICKS); // All done return; } else { @@ -1019,7 +1014,7 @@ static void ws_pae_auth_next_kmp_trigger(pae_auth_t *pae_auth, supp_entry_t *sup } // Create new instance - kmp_api_t *new_kmp = ws_pae_auth_kmp_create_and_start(pae_auth->kmp_service, next_type, supp_entry, pae_auth->sec_prot_cfg); + kmp_api_t *new_kmp = ws_pae_auth_kmp_create_and_start(pae_auth->kmp_service, next_type, supp_entry, pae_auth->sec_prot_cfg, pae_auth->sec_timer_cfg); if (!new_kmp) { return; } @@ -1032,7 +1027,7 @@ static void ws_pae_auth_next_kmp_trigger(pae_auth_t *pae_auth, supp_entry_t *sup return; } // Create TLS instance */ - if (ws_pae_auth_kmp_create_and_start(pae_auth->kmp_service, TLS_PROT, supp_entry, pae_auth->sec_prot_cfg) == NULL) { + if (ws_pae_auth_kmp_create_and_start(pae_auth->kmp_service, TLS_PROT, supp_entry, pae_auth->sec_prot_cfg, pae_auth->sec_timer_cfg) == NULL) { ws_pae_lib_kmp_list_delete(&supp_entry->kmp_list, new_kmp); return; } @@ -1099,10 +1094,10 @@ static kmp_type_e ws_pae_auth_next_protocol_get(pae_auth_t *pae_auth, supp_entry return next_type; } -static kmp_api_t *ws_pae_auth_kmp_create_and_start(kmp_service_t *service, kmp_type_e type, supp_entry_t *supp_entry, sec_prot_cfg_t *cfg) +static kmp_api_t *ws_pae_auth_kmp_create_and_start(kmp_service_t *service, kmp_type_e type, supp_entry_t *supp_entry, sec_prot_cfg_t *prot_cfg, sec_timer_cfg_t *timer_cfg) { // Create KMP instance for new authentication - kmp_api_t *kmp = kmp_api_create(service, type, cfg); + kmp_api_t *kmp = kmp_api_create(service, type, prot_cfg, timer_cfg); if (!kmp) { return NULL; diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_pae_controller.c b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_pae_controller.c index c040b97bb0..05eb06983b 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_pae_controller.c +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_pae_controller.c @@ -72,7 +72,8 @@ typedef struct { uint8_t gtkhash[32]; /**< GTK hashes */ sec_prot_certs_t certs; /**< Certificates */ nw_key_t nw_key[GTK_NUM]; /**< Currently active network keys (on MAC) */ - uint16_t frame_cnt_store_timer; /**< Timer for storing frame counter value */ + uint16_t frame_cnt_store_timer; /**< Timer to check if storing of frame counter value is needed */ + uint32_t frame_cnt_store_force_timer; /**< Timer to force storing of frame counter, if no other updates */ frame_counters_t frame_counters; /**< Frame counters */ sec_timer_cfg_t sec_timer_cfg; /**< Timer configuration (configuration set values) */ sec_prot_cfg_t sec_prot_cfg; /**< Configuration */ @@ -86,6 +87,7 @@ typedef struct { ws_pae_controller_nw_frame_counter_read *nw_frame_counter_read; /**< Frame counter read callback */ ws_pae_controller_pan_ver_increment *pan_ver_increment; /**< PAN version increment callback */ ws_pae_controller_nw_info_updated *nw_info_updated; /**< Network information updated callback */ + ws_pae_controller_auth_next_target *auth_next_target; /**< Authentication next target callback */ ws_pae_delete *pae_delete; /**< PAE delete callback */ ws_pae_timer *pae_fast_timer; /**< PAE fast timer callback */ ws_pae_timer *pae_slow_timer; /**< PAE slow timer callback */ @@ -164,7 +166,7 @@ int8_t ws_pae_controller_authenticate(protocol_interface_info_entry_t *interface return 0; } - if (ws_pae_supp_authenticate(controller->interface_ptr, controller->target_pan_id, controller->target_eui_64) < 0) { + if (ws_pae_supp_authenticate(controller->interface_ptr, controller->target_pan_id, controller->target_eui_64, controller->sec_keys_nw_info.network_name) < 0) { controller->auth_completed(interface_ptr, AUTH_RESULT_ERR_UNSPEC, controller->target_eui_64); } #endif @@ -220,7 +222,7 @@ int8_t ws_pae_controller_authenticator_start(protocol_interface_info_entry_t *in return 0; } -int8_t ws_pae_controller_cb_register(protocol_interface_info_entry_t *interface_ptr, ws_pae_controller_auth_completed *completed, ws_pae_controller_nw_key_set *nw_key_set, ws_pae_controller_nw_key_clear *nw_key_clear, ws_pae_controller_nw_send_key_index_set *nw_send_key_index_set, ws_pae_controller_nw_frame_counter_set *nw_frame_counter_set, ws_pae_controller_nw_frame_counter_read *nw_frame_counter_read, ws_pae_controller_pan_ver_increment *pan_ver_increment, ws_pae_controller_nw_info_updated *nw_info_updated) +int8_t ws_pae_controller_cb_register(protocol_interface_info_entry_t *interface_ptr, ws_pae_controller_auth_completed *completed, ws_pae_controller_auth_next_target *auth_next_target, ws_pae_controller_nw_key_set *nw_key_set, ws_pae_controller_nw_key_clear *nw_key_clear, ws_pae_controller_nw_send_key_index_set *nw_send_key_index_set, ws_pae_controller_nw_frame_counter_set *nw_frame_counter_set, ws_pae_controller_nw_frame_counter_read *nw_frame_counter_read, ws_pae_controller_pan_ver_increment *pan_ver_increment, ws_pae_controller_nw_info_updated *nw_info_updated) { if (!interface_ptr) { return -1; @@ -239,7 +241,7 @@ int8_t ws_pae_controller_cb_register(protocol_interface_info_entry_t *interface_ controller->nw_frame_counter_read = nw_frame_counter_read; controller->pan_ver_increment = pan_ver_increment; controller->nw_info_updated = nw_info_updated; - + controller->auth_next_target = auth_next_target; return 0; } @@ -325,7 +327,7 @@ static void ws_pae_controller_nw_info_updated_check(protocol_interface_info_entr } } -int8_t ws_pae_controller_nw_key_valid(protocol_interface_info_entry_t *interface_ptr) +int8_t ws_pae_controller_nw_key_valid(protocol_interface_info_entry_t *interface_ptr, uint8_t *br_iid) { if (!interface_ptr) { return -1; @@ -336,7 +338,7 @@ int8_t ws_pae_controller_nw_key_valid(protocol_interface_info_entry_t *interface return -1; } - return ws_pae_supp_nw_key_valid(interface_ptr); + return ws_pae_supp_nw_key_valid(interface_ptr, br_iid); } static int8_t ws_pae_controller_nw_key_check_and_insert(protocol_interface_info_entry_t *interface_ptr, sec_prot_gtk_keys_t *gtks) @@ -601,6 +603,9 @@ int8_t ws_pae_controller_init(protocol_interface_info_entry_t *interface_ptr) controller->nw_send_key_index_set = NULL; controller->nw_frame_counter_set = NULL; controller->pan_ver_increment = NULL; + controller->nw_info_updated = NULL; + controller->auth_next_target = NULL; + memset(&controller->sec_timer_cfg, 0, sizeof(ws_sec_timer_cfg_t)); memset(&controller->sec_prot_cfg, 0, sizeof(sec_prot_cfg_t)); @@ -624,7 +629,15 @@ int8_t ws_pae_controller_configure(protocol_interface_info_entry_t *interface_pt controller->sec_prot_cfg.sec_prot_trickle_params.k = 0; controller->sec_prot_cfg.sec_prot_trickle_params.TimerExpirations = sec_prot_cfg->sec_prot_trickle_timer_exp; controller->sec_prot_cfg.sec_prot_retry_timeout = sec_prot_cfg->sec_prot_retry_timeout * 10; + controller->sec_prot_cfg.sec_max_ongoing_authentication = sec_prot_cfg->sec_max_ongoing_authentication; + + controller->sec_prot_cfg.initial_key_retry_delay = sec_prot_cfg->initial_key_retry_delay; + controller->sec_prot_cfg.initial_key_trickle_params.Imin = sec_prot_cfg->initial_key_imin; + controller->sec_prot_cfg.initial_key_trickle_params.Imax = sec_prot_cfg->initial_key_imax; + controller->sec_prot_cfg.initial_key_trickle_params.k = 0; + controller->sec_prot_cfg.initial_key_trickle_params.TimerExpirations = 2; + controller->sec_prot_cfg.initial_key_retry_cnt = sec_prot_cfg->initial_key_retry_cnt; } if (sec_timer_cfg) { @@ -661,6 +674,7 @@ static void ws_pae_controller_data_init(pae_controller_t *controller) controller->frame_counter_read = false; controller->gtk_index = -1; controller->frame_cnt_store_timer = FRAME_COUNTER_STORE_INTERVAL; + controller->frame_cnt_store_force_timer = FRAME_COUNTER_STORE_FORCE_INTERVAL; controller->restart_cnt = 0; ws_pae_controller_frame_counter_reset(&controller->frame_counters); sec_prot_keys_gtks_init(&controller->gtks); @@ -791,7 +805,7 @@ int8_t ws_pae_controller_supp_init(protocol_interface_info_entry_t *interface_pt controller->pae_nw_key_index_update = ws_pae_supp_nw_key_index_update; controller->pae_nw_info_set = NULL; - ws_pae_supp_cb_register(controller->interface_ptr, controller->auth_completed, ws_pae_controller_nw_key_check_and_insert, ws_pae_controller_active_nw_key_set, ws_pae_controller_gtk_hash_ptr_get, ws_pae_controller_nw_info_updated_check); + ws_pae_supp_cb_register(controller->interface_ptr, controller->auth_completed, controller->auth_next_target, ws_pae_controller_nw_key_check_and_insert, ws_pae_controller_active_nw_key_set, ws_pae_controller_gtk_hash_ptr_get, ws_pae_controller_nw_info_updated_check); ws_pae_controller_frame_counter_read(controller); ws_pae_controller_nw_info_read(controller, controller->sec_keys_nw_info.gtks); @@ -1369,6 +1383,13 @@ static void ws_pae_controller_frame_counter_timer(uint16_t seconds, pae_controll entry->frame_cnt_store_timer = FRAME_COUNTER_STORE_INTERVAL; ws_pae_controller_frame_counter_store(entry, true); } + + if (entry->frame_cnt_store_force_timer > seconds) { + entry->frame_cnt_store_force_timer -= seconds; + } else { + entry->frame_cnt_store_force_timer = 0; + ws_pae_controller_frame_counter_store(entry, true); + } } static void ws_pae_controller_frame_counter_timer_trigger(uint16_t seconds, pae_controller_t *entry) @@ -1422,11 +1443,14 @@ static void ws_pae_controller_frame_counter_store(pae_controller_t *entry, bool } } - if (update_needed) { + if (update_needed || entry->frame_cnt_store_force_timer == 0) { tr_debug("Write frame counters: system time %"PRIu32"", protocol_core_monotonic_time / 10); // Writes modified frame counters ws_pae_nvm_store_frame_counter_tlv_create((nvm_tlv_t *) &entry->pae_nvm_buffer, entry->restart_cnt, &entry->frame_counters); ws_pae_controller_nvm_frame_counter_write((nvm_tlv_t *) &entry->pae_nvm_buffer); + + // Reset force interval when ever values are stored + entry->frame_cnt_store_force_timer = FRAME_COUNTER_STORE_FORCE_INTERVAL; } } diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_pae_controller.h b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_pae_controller.h index d24ba6319d..2f7e01e6df 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_pae_controller.h +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_pae_controller.h @@ -249,12 +249,13 @@ int8_t ws_pae_controller_nw_info_set(protocol_interface_info_entry_t *interface_ * ws_pae_controller_nw_key_valid network key is valid i.e. used successfully on bootstrap * * \param interface_ptr interface + * \param br_iid border router IID for which the keys are valid * * \return < 0 failure * \return >= 0 success * */ -int8_t ws_pae_controller_nw_key_valid(protocol_interface_info_entry_t *interface_ptr); +int8_t ws_pae_controller_nw_key_valid(protocol_interface_info_entry_t *interface_ptr, uint8_t *br_iid); /** * ws_pae_controller_border_router_addr_write write border router address @@ -278,7 +279,7 @@ int8_t ws_pae_controller_border_router_addr_write(protocol_interface_info_entry_ * \return >= 0 success * */ -int8_t ws_pae_controller_border_router_addr_read(protocol_interface_info_entry_t *interface_ptr, uint8_t *eui_64); +int8_t ws_pae_controller_border_router_addr_read(protocol_interface_info_entry_t *interface_ptr, uint8_t *iid); /** * ws_pae_controller_gtk_update update GTKs (test interface) @@ -492,6 +493,18 @@ typedef void ws_pae_controller_nw_frame_counter_read(protocol_interface_info_ent */ typedef void ws_pae_controller_auth_completed(protocol_interface_info_entry_t *interface_ptr, auth_result_e result, uint8_t *target_eui_64); +/** + * ws_pae_controller_auth_next_target get next target to attempt authentication + * + * \param interface_ptr interface + * \param previous_eui_64 EUI-64 of previous target + * \param pan_id pan id + * + * \return EUI-64 of the next target or previous target if new one not available + * + */ +typedef const uint8_t *ws_pae_controller_auth_next_target(protocol_interface_info_entry_t *interface_ptr, const uint8_t *previous_eui_64, uint16_t *pan_id); + /** * ws_pae_controller_pan_ver_increment PAN version increment callback * @@ -515,6 +528,7 @@ typedef void ws_pae_controller_nw_info_updated(protocol_interface_info_entry_t * * * \param interface_ptr interface * \param completed authentication completed callback + * \param next_target authentication next target callback * \param nw_key_set network key set callback * \param nw_key_clear network key clear callback * \param nw_send_key_index_set network send key index set callback @@ -527,7 +541,7 @@ typedef void ws_pae_controller_nw_info_updated(protocol_interface_info_entry_t * * \return >= 0 success * */ -int8_t ws_pae_controller_cb_register(protocol_interface_info_entry_t *interface_ptr, ws_pae_controller_auth_completed *completed, ws_pae_controller_nw_key_set *nw_key_set, ws_pae_controller_nw_key_clear *nw_key_clear, ws_pae_controller_nw_send_key_index_set *nw_send_key_index_set, ws_pae_controller_nw_frame_counter_set *nw_frame_counter_set, ws_pae_controller_nw_frame_counter_read *nw_frame_counter_read, ws_pae_controller_pan_ver_increment *pan_ver_increment, ws_pae_controller_nw_info_updated *nw_info_updated); +int8_t ws_pae_controller_cb_register(protocol_interface_info_entry_t *interface_ptr, ws_pae_controller_auth_completed *completed, ws_pae_controller_auth_next_target *auth_next_target, ws_pae_controller_nw_key_set *nw_key_set, ws_pae_controller_nw_key_clear *nw_key_clear, ws_pae_controller_nw_send_key_index_set *nw_send_key_index_set, ws_pae_controller_nw_frame_counter_set *nw_frame_counter_set, ws_pae_controller_nw_frame_counter_read *nw_frame_counter_read, ws_pae_controller_pan_ver_increment *pan_ver_increment, ws_pae_controller_nw_info_updated *nw_info_updated); /** * ws_pae_controller_fast_timer PAE controller fast timer call diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_pae_key_storage.c b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_pae_key_storage.c index 556f6c068c..b50dfb0302 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_pae_key_storage.c +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_pae_key_storage.c @@ -87,6 +87,7 @@ typedef struct { } key_storage_array_t; typedef struct { + uint8_t settings_set; /**< Settings set, do not use defaults */ uint8_t storages_empty; /**< Number of empty i.e. to be allocated storages */ uint16_t storage_default_size; /**< Default size for storages */ uint16_t replace_index; /**< Index to replace when storages are full */ @@ -138,6 +139,7 @@ int8_t ws_pae_key_storage_memory_set(uint8_t key_storages_number, const uint16_t int8_t ws_pae_key_storage_settings_set(uint8_t alloc_max_number, uint16_t alloc_size, uint16_t storing_interval) { + key_storage_params.settings_set = true; key_storage_params.storages_empty = alloc_max_number; key_storage_params.storage_default_size = alloc_size; key_storage_params.store_timer = storing_interval; @@ -148,18 +150,19 @@ int8_t ws_pae_key_storage_settings_set(uint8_t alloc_max_number, uint16_t alloc_ void ws_pae_key_storage_init(void) { - key_storage_params.storages_empty = DEFAULT_NUMBER_OF_STORAGES; - key_storage_params.storage_default_size = STORAGE_ARRAY_HEADER_LEN + (sizeof(sec_prot_keys_storage_t) * DEFAULT_NUMBER_OF_ENTRIES_IN_ONE_STORAGE); + if (!key_storage_params.settings_set) { + key_storage_params.storages_empty = DEFAULT_NUMBER_OF_STORAGES; + key_storage_params.storage_default_size = STORAGE_ARRAY_HEADER_LEN + (sizeof(sec_prot_keys_storage_t) * DEFAULT_NUMBER_OF_ENTRIES_IN_ONE_STORAGE); + key_storage_params.store_timer = DEFAULT_STORING_INTERVAL; + key_storage_params.store_timer_timeout = DEFAULT_STORING_INTERVAL; + } key_storage_params.replace_index = 0; key_storage_params.store_bitfield = 0, - key_storage_params.store_timer_timeout = DEFAULT_STORING_INTERVAL; - key_storage_params.store_timer = DEFAULT_STORING_INTERVAL; key_storage_params.restart_cnt = 0; } void ws_pae_key_storage_delete(void) { - memset(&key_storage_params, 0, sizeof(key_storage_params_t)); ws_pae_key_storage_list_all_free(); } diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_pae_lib.c b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_pae_lib.c index 697e2f04ea..d47aff8a8f 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_pae_lib.c +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_pae_lib.c @@ -26,8 +26,8 @@ #include "NWK_INTERFACE/Include/protocol.h" #include "6LoWPAN/ws/ws_cfg_settings.h" #include "6LoWPAN/ws/ws_config.h" -#include "6LoWPAN/ws/ws_pae_timers.h" #include "Security/protocols/sec_prot_cfg.h" +#include "6LoWPAN/ws/ws_pae_timers.h" #include "Security/kmp/kmp_addr.h" #include "Security/kmp/kmp_api.h" #include "Security/protocols/sec_prot_certs.h" @@ -242,17 +242,16 @@ bool ws_pae_lib_supp_list_timer_update(void *instance, supp_list_t *active_supp_ return timer_running; } -void ws_pae_lib_supp_list_slow_timer_update(supp_list_t *supp_list, sec_timer_cfg_t *timer_settings, uint16_t seconds) +void ws_pae_lib_supp_list_slow_timer_update(supp_list_t *supp_list, uint16_t seconds) { ns_list_foreach(supp_entry_t, entry, supp_list) { - if (sec_prot_keys_pmk_lifetime_decrement(&entry->sec_keys, timer_settings->pmk_lifetime, seconds)) { + if (sec_prot_keys_pmk_lifetime_decrement(&entry->sec_keys, seconds)) { tr_info("PMK and PTK expired, eui-64: %s, system time: %"PRIu32"", trace_array(entry->addr.eui_64, 8), protocol_core_monotonic_time / 10); } - if (sec_prot_keys_ptk_lifetime_decrement(&entry->sec_keys, timer_settings->ptk_lifetime, seconds)) { + if (sec_prot_keys_ptk_lifetime_decrement(&entry->sec_keys, seconds)) { tr_info("PTK expired, eui-64: %s, system time: %"PRIu32"", trace_array(entry->addr.eui_64, 8), protocol_core_monotonic_time / 10); } } - } void ws_pae_lib_supp_init(supp_entry_t *entry) diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_pae_lib.h b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_pae_lib.h index d469c4c55a..eed138e74c 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_pae_lib.h +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_pae_lib.h @@ -252,11 +252,10 @@ bool ws_pae_lib_supp_list_timer_update(void *instance, supp_list_t *active_supp_ * ws_pae_lib_supp_list_slow_timer_update updates slow timer on supplicant list * * \param supp_list list of supplicants - * \param timer_settings timer settings * \param seconds seconds * */ -void ws_pae_lib_supp_list_slow_timer_update(supp_list_t *supp_list, sec_timer_cfg_t *timer_settings, uint16_t seconds); +void ws_pae_lib_supp_list_slow_timer_update(supp_list_t *supp_list, uint16_t seconds); /** * ws_pae_lib_supp_list_timer_update updates supplicant timers diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_pae_nvm_data.c b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_pae_nvm_data.c index 2c0ab29e23..3212240af8 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_pae_nvm_data.c +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_pae_nvm_data.c @@ -204,10 +204,12 @@ void ws_pae_nvm_store_keys_tlv_create(nvm_tlv_t *tlv_entry, sec_prot_keys_t *sec uint8_t *pmk = sec_prot_keys_pmk_get(sec_keys); if (pmk) { *tlv++ = PAE_NVM_FIELD_SET; + uint32_t lifetime = sec_prot_keys_pmk_lifetime_get(sec_keys); + tlv = common_write_32_bit(lifetime, tlv); memcpy(tlv, pmk, PMK_LEN); } else { *tlv++ = PAE_NVM_FIELD_NOT_SET; - memset(tlv, 0, PMK_LEN); + memset(tlv, 0, 4 + PMK_LEN); } tlv += PMK_LEN; @@ -217,10 +219,12 @@ void ws_pae_nvm_store_keys_tlv_create(nvm_tlv_t *tlv_entry, sec_prot_keys_t *sec uint8_t *ptk = sec_prot_keys_ptk_get(sec_keys); if (ptk) { *tlv++ = PAE_NVM_FIELD_SET; + uint32_t lifetime = sec_prot_keys_ptk_lifetime_get(sec_keys); + tlv = common_write_32_bit(lifetime, tlv); memcpy(tlv, ptk, PTK_LEN); } else { *tlv++ = PAE_NVM_FIELD_NOT_SET; - memset(tlv, 0, PTK_LEN); + memset(tlv, 0, 4 + PTK_LEN); } tlv += PTK_LEN; @@ -247,7 +251,11 @@ int8_t ws_pae_nvm_store_keys_tlv_read(nvm_tlv_t *tlv_entry, sec_prot_keys_t *sec // PMK set if (*tlv++ == PAE_NVM_FIELD_SET) { - sec_prot_keys_pmk_write(sec_keys, tlv); + uint32_t lifetime = common_read_32_bit(tlv); + tlv += 4; + sec_prot_keys_pmk_write(sec_keys, tlv, lifetime); + } else { + tlv += 4; } tlv += PMK_LEN; @@ -257,7 +265,11 @@ int8_t ws_pae_nvm_store_keys_tlv_read(nvm_tlv_t *tlv_entry, sec_prot_keys_t *sec // PTK set if (*tlv++ == PAE_NVM_FIELD_SET) { - sec_prot_keys_ptk_write(sec_keys, tlv); + uint32_t lifetime = common_read_32_bit(tlv); + tlv += 4; + sec_prot_keys_ptk_write(sec_keys, tlv, lifetime); + } else { + tlv += 4; } tlv += PTK_LEN; diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_pae_nvm_data.h b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_pae_nvm_data.h index 438cf508d0..c55d56412b 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_pae_nvm_data.h +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_pae_nvm_data.h @@ -38,8 +38,8 @@ // pan_id (2) + network name (33) + (GTK set (1) + GTK expiry timestamp (8) + status (1) + install order (1) + GTK (16)) * 4 #define PAE_NVM_NW_INFO_LEN 2 + 33 + (1 + 8 + 1 + 1 + GTK_LEN) * GTK_NUM -// PTK EUI-64 set (1) + PTK EUI-64 (8) + PMK set (1) + PMK (32) + PMK replay counter (8) + PTK set (1) + PTK (48) -#define PAE_NVM_KEYS_LEN 1 + 8 + 1 + PMK_LEN + 8 + 1 + PTK_LEN +// PTK EUI-64 set (1) + PTK EUI-64 (8) + PMK set (1) + PMK lifetime (4) + PMK (32) + PMK replay counter (8) + PTK set (1) + PTK lifetime (4) + PTK (48) +#define PAE_NVM_KEYS_LEN 1 + 8 + 1 + 4 + PMK_LEN + 8 + 1 + 4 + PTK_LEN // restart counter + stored time + (frame counter set (1) + GTK (16) + frame counter (4)) * 4 #define PAE_NVM_FRAME_COUNTER_LEN 4 + 8 + (1 + GTK_LEN + 4) * GTK_NUM diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_pae_supp.c b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_pae_supp.c index a5e03ad86a..7954010d50 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_pae_supp.c +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_pae_supp.c @@ -86,6 +86,7 @@ typedef struct { kmp_service_t *kmp_service; /**< KMP service */ protocol_interface_info_entry_t *interface_ptr; /**< Interface */ ws_pae_supp_auth_completed *auth_completed; /**< Authentication completed callback, continue bootstrap */ + ws_pae_supp_auth_next_target *auth_next_target; /**< Authentication next target callback */ ws_pae_supp_nw_key_insert *nw_key_insert; /**< Key insert callback */ ws_pae_supp_nw_key_index_set *nw_key_index_set; /**< Key index set callback */ ws_pae_supp_gtk_hash_ptr_get *gtk_hash_ptr_get; /**< Get pointer to GTK hash storage callback */ @@ -96,7 +97,8 @@ typedef struct { uint16_t initial_key_retry_timer; /**< Timer to trigger initial EAPOL-Key 1st retry */ trickle_t auth_trickle_timer; /**< Trickle timer for re-sending initial EAPOL-key or for GTK mismatch */ trickle_params_t auth_trickle_params; /**< Trickle parameters for initial EAPOL-key or for GTK mismatch */ - uint8_t new_br_eui_64[8]; /**< Border router EUI-64 indicated by bootstrap */ + uint8_t new_br_eui_64[8]; /**< Border router EUI-64 indicated by bootstrap after bootstrap start */ + uint8_t comp_br_eui_64[8]; /**< Border router EUI-64 indicated by bootstrap after bootstrap completed */ sec_prot_keys_nw_info_t *sec_keys_nw_info; /**< Security keys network information */ sec_timer_cfg_t *sec_timer_cfg; /**< Timer configuration */ sec_prot_cfg_t *sec_prot_cfg; /**< Protocol Configuration */ @@ -105,46 +107,26 @@ typedef struct { bool auth_trickle_running : 1; /**< Initial EAPOL-Key Trickle timer running */ bool auth_requested : 1; /**< Authentication has been requested by the bootstrap */ bool timer_running : 1; /**< Timer is running */ - bool new_br_eui_64_set : 1; /**< Border router address has been set */ + bool new_br_eui_64_set : 1; /**< Border router address has been set after bootstrap start */ bool new_br_eui_64_fresh : 1; /**< Border router address is fresh (set during this authentication attempt) */ - bool entry_address_active: 1; + bool comp_br_eui_64_set : 1; /**< Border router address has been set after bootstrap completed */ + bool entry_address_active: 1; /**< EAPOL target address is set */ + bool tx_failure_on_initial_key: 1; /**< TX failure has happened on initial EAPOL-key sequence */ } pae_supp_t; -// How many times sending of initial EAPOL-key is retried -#define INITIAL_KEY_RETRY_COUNT 2 - // How many times sending of initial EAPOL-key is initiated on key update #define KEY_UPDATE_RETRY_COUNT 3 #define LIFETIME_MISMATCH_RETRY_COUNT 1 /* No retries */ -// How long the wait is before the first initial EAPOL-key retry -#define DEFAULT_INITIAL_KEY_RETRY_TIMER 120 -#define NONE_INITIAL_KEY_RETRY_TIMER 0 - -// Default trickle values for sending of initial EAPOL-key -#define DEFAULT_TRICKLE_IMIN_SECS 360 /* 6 to 12 minutes */ -#define DEFAULT_TRICKLE_IMAX_SECS 720 - -// Very slow network values for sending of initial EAPOL-key -#define VERY_SLOW_NW_TRICKLE_IMIN_SECS 600 /* 10 to 60 minutes */ -#define VERY_SLOW_NW_TRICKLE_IMAX_SECS 3600 - // Trickle timer on how long to wait response after last retry before failing authentication #define LAST_INTERVAL_TRICKLE_IMIN_SECS 240 /* 4 minutes */ #define LAST_INTERVAL_TRICKLE_IMAX_SECS 240 -static trickle_params_t initial_eapol_key_trickle_params = { - .Imin = DEFAULT_TRICKLE_IMIN_SECS, /* 360 second; ticks are 1 second */ - .Imax = DEFAULT_TRICKLE_IMAX_SECS, /* 720 second */ - .k = 0, /* infinity - no consistency checking */ - .TimerExpirations = 2 -}; - static void ws_pae_supp_free(pae_supp_t *pae_supp); static void ws_pae_supp_authenticate_response(pae_supp_t *pae_supp, auth_result_e result); static int8_t ws_pae_supp_initial_key_send(pae_supp_t *pae_supp); static void ws_pae_supp_nvm_update(pae_supp_t *pae_supp); -static int8_t ws_pae_supp_nw_keys_valid_check(pae_supp_t *pae_supp, uint16_t pan_id); +static int8_t ws_pae_supp_nw_keys_valid_check(pae_supp_t *pae_supp, uint16_t pan_id, char *dest_network_name); static int8_t ws_pae_supp_nvm_keys_write(pae_supp_t *pae_supp); static pae_supp_t *ws_pae_supp_get(protocol_interface_info_entry_t *interface_ptr); static int8_t ws_pae_supp_event_send(kmp_service_t *service, void *data); @@ -175,6 +157,7 @@ static void ws_pae_supp_kmp_api_finished(kmp_api_t *kmp); static const eapol_pdu_recv_cb_data_t eapol_pdu_recv_cb_data = { .priority = EAPOL_PDU_RECV_HIGH_PRIORITY, + .filter_requsted = false, .addr_check = ws_pae_supp_eapol_pdu_address_check, .receive = kmp_eapol_pdu_if_receive }; @@ -183,7 +166,6 @@ static const char *KEYS_FILE = KEYS_FILE_NAME; static int8_t tasklet_id = -1; static NS_LIST_DEFINE(pae_supp_list, pae_supp_t, link); -static uint8_t timing_value = 0; // Timing value set based e.g. on network size static void ws_pae_supp_address_set(pae_supp_t *pae_supp, kmp_addr_t *address) { @@ -201,14 +183,14 @@ static bool ws_pae_supp_address_is_set(pae_supp_t *pae_supp) return pae_supp->entry_address_active; } -int8_t ws_pae_supp_authenticate(protocol_interface_info_entry_t *interface_ptr, uint16_t dest_pan_id, uint8_t *dest_eui_64) +int8_t ws_pae_supp_authenticate(protocol_interface_info_entry_t *interface_ptr, uint16_t dest_pan_id, uint8_t *dest_eui_64, char *dest_network_name) { pae_supp_t *pae_supp = ws_pae_supp_get(interface_ptr); if (!pae_supp) { return -1; } - if (ws_pae_supp_nw_keys_valid_check(pae_supp, dest_pan_id) >= 0) { + if (ws_pae_supp_nw_keys_valid_check(pae_supp, dest_pan_id, dest_network_name) >= 0) { pae_supp->auth_completed(interface_ptr, AUTH_RESULT_OK, NULL); return 0; } @@ -216,9 +198,10 @@ int8_t ws_pae_supp_authenticate(protocol_interface_info_entry_t *interface_ptr, // Delete GTKs sec_prot_keys_gtks_init(pae_supp->sec_keys_nw_info->gtks); - /* PAN ID has changed, delete key data associated with border router + /* Network name or PAN ID has changed, delete key data associated with border router i.e PMK, PTK, EA-IE data (border router EUI-64) */ - if (pae_supp->sec_keys_nw_info->key_pan_id != 0xFFFF && pae_supp->sec_keys_nw_info->key_pan_id != dest_pan_id) { + if (strcmp(pae_supp->sec_keys_nw_info->network_name, dest_network_name) != 0 || + (pae_supp->sec_keys_nw_info->key_pan_id != 0xFFFF && pae_supp->sec_keys_nw_info->key_pan_id != dest_pan_id)) { 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); @@ -228,6 +211,7 @@ int8_t ws_pae_supp_authenticate(protocol_interface_info_entry_t *interface_ptr, // Prepare to receive new border router address pae_supp->new_br_eui_64_fresh = false; + pae_supp->comp_br_eui_64_set = false; // Stores target/parent address kmp_address_init(KMP_ADDR_EUI_64, &pae_supp->target_addr, dest_eui_64); @@ -268,9 +252,14 @@ int8_t ws_pae_supp_border_router_addr_read(protocol_interface_info_entry_t *inte return -1; } + // Check if there is border router EUI-64 on used on 4WH PTK generation uint8_t *br_eui_64 = sec_prot_keys_ptk_eui_64_get(&pae_supp->entry.sec_keys); if (!br_eui_64) { - return -1; + // Check if there is border router EUI-64 indicated by the bootstrap when bootstrap completed + if (!pae_supp->comp_br_eui_64_set) { + return -1; + } + br_eui_64 = pae_supp->comp_br_eui_64; } memcpy(eui_64, br_eui_64, 8); @@ -278,14 +267,31 @@ int8_t ws_pae_supp_border_router_addr_read(protocol_interface_info_entry_t *inte return 0; } -int8_t ws_pae_supp_nw_key_valid(protocol_interface_info_entry_t *interface_ptr) +int8_t ws_pae_supp_nw_key_valid(protocol_interface_info_entry_t *interface_ptr, uint8_t *br_iid) { pae_supp_t *pae_supp = ws_pae_supp_get(interface_ptr); if (!pae_supp) { return -1; } - tr_info("NW key valid"); + 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 (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", 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; @@ -482,7 +488,7 @@ static int8_t ws_pae_supp_initial_key_send(pae_supp_t *pae_supp) return 0; } -static int8_t ws_pae_supp_nw_keys_valid_check(pae_supp_t *pae_supp, uint16_t pan_id) +static int8_t ws_pae_supp_nw_keys_valid_check(pae_supp_t *pae_supp, uint16_t pan_id, char *dest_network_name) { // Checks how many times authentication has been tried with current network keys if (pae_supp->nw_keys_used_cnt >= STORED_KEYS_MAXIMUM_USE_COUNT) { @@ -497,9 +503,11 @@ static int8_t ws_pae_supp_nw_keys_valid_check(pae_supp_t *pae_supp, uint16_t pan return -1; } - /* Checks if keys match to PAN ID and that needed keys exists (PMK, PTK and a GTK), - and calls inserts function that will update the network keys as needed */ - if ((pan_id == pae_supp->sec_keys_nw_info->key_pan_id) && + /* Checks if keys match to network name and PAN ID and that needed keys exists (PMK, + PTK and a GTK), and calls inserts function that will update the network keys as + needed */ + if ((strcmp(dest_network_name, pae_supp->sec_keys_nw_info->network_name) == 0 && + pan_id == pae_supp->sec_keys_nw_info->key_pan_id) && (sec_prot_keys_gtk_count(pae_supp->sec_keys_nw_info->gtks) > 0) && (sec_prot_keys_pmk_get(&pae_supp->entry.sec_keys) != NULL) && (sec_prot_keys_ptk_get(&pae_supp->entry.sec_keys) != NULL)) { @@ -515,7 +523,7 @@ static int8_t ws_pae_supp_nw_keys_valid_check(pae_supp_t *pae_supp, uint16_t pan } } -void ws_pae_supp_cb_register(protocol_interface_info_entry_t *interface_ptr, ws_pae_supp_auth_completed *completed, ws_pae_supp_nw_key_insert *nw_key_insert, ws_pae_supp_nw_key_index_set *nw_key_index_set, ws_pae_supp_gtk_hash_ptr_get *gtk_hash_ptr_get, ws_pae_supp_nw_info_updated *nw_info_updated) +void ws_pae_supp_cb_register(protocol_interface_info_entry_t *interface_ptr, ws_pae_supp_auth_completed *completed, ws_pae_supp_auth_next_target *auth_next_target, ws_pae_supp_nw_key_insert *nw_key_insert, ws_pae_supp_nw_key_index_set *nw_key_index_set, ws_pae_supp_gtk_hash_ptr_get *gtk_hash_ptr_get, ws_pae_supp_nw_info_updated *nw_info_updated) { pae_supp_t *pae_supp = ws_pae_supp_get(interface_ptr); if (!pae_supp) { @@ -523,6 +531,7 @@ void ws_pae_supp_cb_register(protocol_interface_info_entry_t *interface_ptr, ws_ } pae_supp->auth_completed = completed; + pae_supp->auth_next_target = auth_next_target; pae_supp->nw_key_insert = nw_key_insert; pae_supp->nw_key_index_set = nw_key_index_set; pae_supp->gtk_hash_ptr_get = gtk_hash_ptr_get; @@ -546,13 +555,14 @@ int8_t ws_pae_supp_init(protocol_interface_info_entry_t *interface_ptr, const se pae_supp->interface_ptr = interface_ptr; pae_supp->auth_completed = NULL; + pae_supp->auth_next_target = NULL; pae_supp->nw_key_insert = NULL; pae_supp->nw_key_index_set = NULL; pae_supp->gtk_hash_ptr_get = NULL; pae_supp->initial_key_timer = 0; pae_supp->initial_key_retry_timer = 0; pae_supp->nw_keys_used_cnt = 0; - pae_supp->initial_key_retry_cnt = INITIAL_KEY_RETRY_COUNT; + pae_supp->initial_key_retry_cnt = DEFAULT_INITIAL_KEY_RETRY_COUNT; pae_supp->sec_keys_nw_info = sec_keys_nw_info; pae_supp->sec_timer_cfg = sec_timer_cfg; pae_supp->sec_prot_cfg = sec_prot_cfg; @@ -561,6 +571,7 @@ int8_t ws_pae_supp_init(protocol_interface_info_entry_t *interface_ptr, const se pae_supp->timer_running = false; pae_supp->new_br_eui_64_set = false; pae_supp->new_br_eui_64_fresh = false; + pae_supp->comp_br_eui_64_set = false; pae_supp->entry_address_active = false; ws_pae_lib_supp_init(&pae_supp->entry); @@ -786,6 +797,15 @@ void ws_pae_supp_slow_timer(uint16_t seconds) // Checks if trickle timer expires if (trickle_timer(&pae_supp->auth_trickle_timer, &pae_supp->auth_trickle_params, seconds)) { if (pae_supp->initial_key_retry_cnt > 0) { + // On initial EAPOL-key TX failure, check for other parents + if (pae_supp->auth_requested && pae_supp->tx_failure_on_initial_key) { + // Returns same target if no other valid targets found + const uint8_t *next_target = pae_supp->auth_next_target(pae_supp->interface_ptr, kmp_address_eui_64_get(&pae_supp->target_addr), &pae_supp->sec_keys_nw_info->key_pan_id); + kmp_address_eui_64_set(&pae_supp->target_addr, next_target); + ws_pae_supp_address_set(pae_supp, &pae_supp->target_addr); + } + pae_supp->tx_failure_on_initial_key = false; + // Sends initial EAPOL-key if (ws_pae_supp_initial_key_send(pae_supp) < 0) { tr_info("EAPOL-Key send failed"); } @@ -800,7 +820,12 @@ void ws_pae_supp_slow_timer(uint16_t seconds) tr_info("GTKs do not match to GTK hash"); retry = true; } - ws_pae_supp_authenticate_response(pae_supp, AUTH_RESULT_ERR_UNSPEC); + auth_result_e result = AUTH_RESULT_ERR_UNSPEC; + if (pae_supp->tx_failure_on_initial_key) { + result = AUTH_RESULT_ERR_TX_NO_ACK; + pae_supp->tx_failure_on_initial_key = false; + } + ws_pae_supp_authenticate_response(pae_supp, result); if (retry) { // Start trickle timer to try re-authentication ws_pae_supp_initial_key_update_trickle_timer_start(pae_supp, KEY_UPDATE_RETRY_COUNT); @@ -838,7 +863,7 @@ void ws_pae_supp_slow_timer(uint16_t seconds) pae_supp->initial_key_timer -= seconds; } else { pae_supp->initial_key_timer = 0; - + pae_supp->tx_failure_on_initial_key = false; // Sends initial EAPOL-Key message if (ws_pae_supp_initial_key_send(pae_supp) < 0) { tr_info("EAPOL-Key send failed"); @@ -852,46 +877,40 @@ void ws_pae_supp_slow_timer(uint16_t seconds) static void ws_pae_supp_initial_trickle_timer_start(pae_supp_t *pae_supp) { - pae_supp->auth_trickle_params = initial_eapol_key_trickle_params; + /* Starts trickle for initial EAPOL-key. Default sequence has fixed delay of 2 minutes, + * one re-transmit interval, last re-transmit interval transmit time and a wait time + * for the authenticator to answer the last re-transmit. + * + * Interval I [6,12] minutes. Sequence: + * + * fixed 2 minutes delay + I + last I transmit time t + wait for answer [2,4] minutes + * + * There are two retries. Minimum time that sequence takes before authentication failure + * is 16 minutes and maximum is 30 minutes. + * + * + * Extremely slow network + * + * Starts trickle for initial EAPOL-key, Interval I [10,60] minutes. Sequence: + * I + last I transmit time t + wait for answer [2,4] minutes + * There are two retries. Minimum time that sequence takes before authentication failure + * is 22 minutes and maximum is 124 minutes. + */ + pae_supp->auth_trickle_params = pae_supp->sec_prot_cfg->initial_key_trickle_params; + pae_supp->initial_key_retry_timer = pae_supp->sec_prot_cfg->initial_key_retry_delay; - // Very fast, medium and slow network - if (timing_value < 25) { - /* Starts trickle for initial EAPOL-key. Sequence has fixed delay of 2 minutes, - * one re-transmit interval, last re-transmit interval transmit time and a wait time - * for the authenticator to answer the last re-transmit. - * - * Interval I [6,12] minutes. Sequence: - * - * fixed 2 minutes delay + I + last I transmit time t + wait for answer [2,4] minutes - * - * There are two retries. Minimum time that sequence takes before authentication failure - * is 16 minutes and maximum is 30 minutes. - */ - pae_supp->initial_key_retry_timer = DEFAULT_INITIAL_KEY_RETRY_TIMER; // 2 minutes - } else { - /* Extremely slow network - * - * Starts trickle for initial EAPOL-key, Interval I [10,60] minutes. Sequence: - * I + last I transmit time t + wait for answer [2,4] minutes - * There are two retries. Minimum time that sequence takes before authentication failure - * is 22 minutes and maximum is 124 minutes. - */ - pae_supp->auth_trickle_params.Imin = VERY_SLOW_NW_TRICKLE_IMIN_SECS; - pae_supp->auth_trickle_params.Imax = VERY_SLOW_NW_TRICKLE_IMAX_SECS; - pae_supp->initial_key_retry_timer = NONE_INITIAL_KEY_RETRY_TIMER; // 0 seconds - } trickle_start(&pae_supp->auth_trickle_timer, &pae_supp->auth_trickle_params); tr_info("Initial EAPOL-Key trickle I: [%i,%i] %i, t: %i", pae_supp->auth_trickle_params.Imin, pae_supp->auth_trickle_params.Imax, pae_supp->auth_trickle_timer.I, pae_supp->auth_trickle_timer.t); pae_supp->auth_trickle_running = true; - pae_supp->initial_key_retry_cnt = INITIAL_KEY_RETRY_COUNT; + pae_supp->initial_key_retry_cnt = pae_supp->sec_prot_cfg->initial_key_retry_cnt; } static void ws_pae_supp_initial_last_interval_trickle_timer_start(pae_supp_t *pae_supp) { // Starts trickle last to wait response after last retry before failing authentication - pae_supp->auth_trickle_params = initial_eapol_key_trickle_params; pae_supp->auth_trickle_params.Imin = LAST_INTERVAL_TRICKLE_IMIN_SECS; pae_supp->auth_trickle_params.Imax = LAST_INTERVAL_TRICKLE_IMAX_SECS; + pae_supp->auth_trickle_params.k = 0; pae_supp->auth_trickle_params.TimerExpirations = 1; // Set I to [iMin,iMax] (4 to 4 minutes) -> t is [I/2 - I] (2 minutes to 4 minutes) trickle_start(&pae_supp->auth_trickle_timer, &pae_supp->auth_trickle_params); @@ -1119,7 +1138,7 @@ static kmp_api_t *ws_pae_supp_kmp_incoming_ind(kmp_service_t *service, kmp_type_ static kmp_api_t *ws_pae_supp_kmp_create_and_start(kmp_service_t *service, kmp_type_e type, pae_supp_t *pae_supp) { // Create new instance - kmp_api_t *kmp = kmp_api_create(service, type, pae_supp->sec_prot_cfg); + kmp_api_t *kmp = kmp_api_create(service, type, pae_supp->sec_prot_cfg, pae_supp->sec_timer_cfg); if (!kmp) { return NULL; } @@ -1217,7 +1236,8 @@ static void ws_pae_supp_kmp_api_finished_indication(kmp_api_t *kmp, kmp_result_e /* Fails authentication only if other authentication protocols are not yet started by authenticator */ if (ws_pae_lib_kmp_list_count(&pae_supp->entry.kmp_list) <= 1) { - ws_pae_supp_authenticate_response(pae_supp, AUTH_RESULT_ERR_TX_NO_ACK); + // Continues with trickle but selects different parent + pae_supp->tx_failure_on_initial_key = true; } } } diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_pae_supp.h b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_pae_supp.h index d5d6ac3c6b..7bd2017061 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_pae_supp.h +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_pae_supp.h @@ -81,13 +81,14 @@ void ws_pae_supp_slow_timer(uint16_t seconds); * \param interface_ptr interface * \param dest_pan_id EAPOL target PAN ID * \param dest_eui_64 EAPOL target + * \param dest_network_name EAPOL target network name * * \return < 0 failure * \return 0 authentication done, continue * \return > 0 authentication started * */ -int8_t ws_pae_supp_authenticate(protocol_interface_info_entry_t *interface_ptr, uint16_t dest_pan_id, uint8_t *dest_eui_64); +int8_t ws_pae_supp_authenticate(protocol_interface_info_entry_t *interface_ptr, uint16_t dest_pan_id, uint8_t *dest_eui_64, char *dest_network_name); /** * ws_pae_supp_border_router_addr_write write border router address @@ -117,12 +118,13 @@ int8_t ws_pae_supp_border_router_addr_read(protocol_interface_info_entry_t *inte * ws_pae_supp_nw_key_valid network key is valid i.e. used successfully on bootstrap * * \param interface_ptr interface + * \param br_iid border router IID for which the keys are valid * * \return < 0 failure * \return >= 0 success * */ -int8_t ws_pae_supp_nw_key_valid(protocol_interface_info_entry_t *interface_ptr); +int8_t ws_pae_supp_nw_key_valid(protocol_interface_info_entry_t *interface_ptr, uint8_t *br_iid); /** * ws_pae_supp_gtk_hash_update GTK hash has been updated (on PAN configuration) @@ -190,6 +192,17 @@ typedef void ws_pae_supp_nw_key_index_set(protocol_interface_info_entry_t *inter */ typedef void ws_pae_supp_auth_completed(protocol_interface_info_entry_t *interface_ptr, auth_result_e result, uint8_t *target_eui_64); +/** + * ws_pae_supp_auth_next_target get next target to attempt authentication + * + * \param interface_ptr interface + * \param previous_eui_64 EUI-64 of previous target + * + * \return EUI-64 of the next target or previous target if new one not available + * + */ +typedef const uint8_t *ws_pae_supp_auth_next_target(protocol_interface_info_entry_t *interface_ptr, const uint8_t *previous_eui_64, uint16_t *pan_id); + /** * ws_pae_supp_nw_key_insert network key insert callback * @@ -230,7 +243,7 @@ typedef void ws_pae_supp_nw_info_updated(protocol_interface_info_entry_t *interf * \param nw_info_updated security keys network information updated callback * */ -void ws_pae_supp_cb_register(protocol_interface_info_entry_t *interface_ptr, ws_pae_supp_auth_completed *completed, ws_pae_supp_nw_key_insert *nw_key_insert, ws_pae_supp_nw_key_index_set *nw_key_index_set, ws_pae_supp_gtk_hash_ptr_get *gtk_hash_ptr_get, ws_pae_supp_nw_info_updated *nw_info_updated); +void ws_pae_supp_cb_register(protocol_interface_info_entry_t *interface_ptr, ws_pae_supp_auth_completed *completed, ws_pae_supp_auth_next_target *auth_next_target, ws_pae_supp_nw_key_insert *nw_key_insert, ws_pae_supp_nw_key_index_set *nw_key_index_set, ws_pae_supp_gtk_hash_ptr_get *gtk_hash_ptr_get, ws_pae_supp_nw_info_updated *nw_info_updated); #else diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_pae_time.c b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_pae_time.c index 72482429d5..ad60f3d0e2 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_pae_time.c +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_pae_time.c @@ -31,7 +31,10 @@ #define TRACE_GROUP "wst" // Wednesday, January 1, 2020 0:00:00 GMT -#define CURRENT_TIME_INIT_VALUE 1577836800 +#define CURRENT_TIME_INIT_VALUE 1577836800 + +// Increment two hours in addition to maximum storing interval +#define CURRENT_TIME_INCREMENT_VALUE (2 * 3600) static uint64_t current_time = CURRENT_TIME_INIT_VALUE; static ns_time_api_system_time_callback *system_time_callback = NULL; @@ -171,6 +174,8 @@ int8_t ws_pae_current_time_set(uint64_t time) tr_error("FATAL: system time less than reference time or more than 12 months in future: %"PRIi64" reference time: %"PRIi64, system_time, current_time); return -1; } + } else { + current_time += FRAME_COUNTER_STORE_FORCE_INTERVAL + CURRENT_TIME_INCREMENT_VALUE; } return 0; diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_pae_timers.c b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_pae_timers.c index fd3f02e621..a07d0e6deb 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_pae_timers.c +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_pae_timers.c @@ -26,6 +26,7 @@ #include "NWK_INTERFACE/Include/protocol.h" #include "6LoWPAN/ws/ws_config.h" #include "6LoWPAN/ws/ws_cfg_settings.h" +#include "Security/protocols/sec_prot_cfg.h" #include "6LoWPAN/ws/ws_pae_timers.h" #ifdef HAVE_WS diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_pae_timers.h b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_pae_timers.h index ec792996a0..7b8f58052d 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_pae_timers.h +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_pae_timers.h @@ -18,18 +18,6 @@ #ifndef WS_PAE_TIMERS_H_ #define WS_PAE_TIMERS_H_ -typedef struct sec_timer_cfg_s { - uint32_t gtk_expire_offset; /* GTK lifetime; GTK_EXPIRE_OFFSET (seconds) */ - uint32_t pmk_lifetime; /* PMK lifetime (seconds) */ - uint32_t ptk_lifetime; /* PTK lifetime (seconds) */ - uint16_t gtk_new_act_time; /* GTK_NEW_ACTIVATION_TIME (1/X of expire offset) */ - uint16_t revocat_lifetime_reduct; /* REVOCATION_LIFETIME_REDUCTION (reduction of lifetime) */ - uint16_t gtk_request_imin; /* GTK_REQUEST_IMIN (seconds) */ - uint16_t gtk_request_imax; /* GTK_REQUEST_IMAX (seconds) */ - uint16_t gtk_max_mismatch; /* GTK_MAX_MISMATCH (seconds) */ - uint8_t gtk_new_install_req; /* GTK_NEW_INSTALL_REQUIRED (percent of GTK lifetime) */ -} sec_timer_cfg_t; - /** * ws_pae_timers_settings_init initializes timer settings structure * diff --git a/features/nanostack/sal-stack-nanostack/source/MAC/IEEE802_15_4/mac_data_buffer.h b/features/nanostack/sal-stack-nanostack/source/MAC/IEEE802_15_4/mac_data_buffer.h index b285c069de..4888cc816d 100644 --- a/features/nanostack/sal-stack-nanostack/source/MAC/IEEE802_15_4/mac_data_buffer.h +++ b/features/nanostack/sal-stack-nanostack/source/MAC/IEEE802_15_4/mac_data_buffer.h @@ -97,6 +97,7 @@ typedef struct mac_pre_build_frame { bool mac_allocated_payload_ptr: 1; bool asynch_request: 1; bool message_builded: 1; + bool DSN_allocated: 1; unsigned security_mic_len: 5; //Max possible lengths 0, 4, 8, 16 bytes unsigned priority: 2; struct mac_pre_build_frame *next; //Pointer for queue purpose diff --git a/features/nanostack/sal-stack-nanostack/source/MAC/IEEE802_15_4/mac_mcps_sap.c b/features/nanostack/sal-stack-nanostack/source/MAC/IEEE802_15_4/mac_mcps_sap.c index 97613bbeff..ee16dc8670 100644 --- a/features/nanostack/sal-stack-nanostack/source/MAC/IEEE802_15_4/mac_mcps_sap.c +++ b/features/nanostack/sal-stack-nanostack/source/MAC/IEEE802_15_4/mac_mcps_sap.c @@ -1226,6 +1226,7 @@ mac_pre_build_frame_t *mcps_sap_prebuild_frame_buffer_get(uint16_t payload_size) memset(buffer, 0, sizeof(mac_pre_build_frame_t)); buffer->initial_tx_channel = 0xffff; buffer->aux_header.frameCounter = 0xffffffff; + buffer->DSN_allocated = false; if (payload_size) { //Mac interlnal payload allocate buffer->mac_payload = ns_dyn_mem_temporary_alloc(payload_size); @@ -1502,7 +1503,10 @@ static void mcps_generic_sequence_number_allocate(protocol_interface_rf_mac_setu switch (buffer->fcf_dsn.frametype) { case MAC_FRAME_CMD: case MAC_FRAME_DATA: - buffer->fcf_dsn.DSN = mac_mlme_set_new_sqn(rf_ptr); + if (!buffer->DSN_allocated) { + buffer->fcf_dsn.DSN = mac_mlme_set_new_sqn(rf_ptr); + buffer->DSN_allocated = true; + } break; case MAC_FRAME_BEACON: buffer->fcf_dsn.DSN = mac_mlme_set_new_beacon_sqn(rf_ptr); diff --git a/features/nanostack/sal-stack-nanostack/source/RPL/rpl_control.c b/features/nanostack/sal-stack-nanostack/source/RPL/rpl_control.c index 72ef949fc2..37eacc4345 100644 --- a/features/nanostack/sal-stack-nanostack/source/RPL/rpl_control.c +++ b/features/nanostack/sal-stack-nanostack/source/RPL/rpl_control.c @@ -391,7 +391,7 @@ static void rpl_control_addr_notifier(struct protocol_interface_info_entry *inte } } -static void rpl_control_etx_change_callback(int8_t nwk_id, uint16_t previous_etx, uint16_t current_etx, uint8_t attribute_index) +static void rpl_control_etx_change_callback(int8_t nwk_id, uint16_t previous_etx, uint16_t current_etx, uint8_t attribute_index, const uint8_t *mac64) { protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(nwk_id); @@ -405,14 +405,29 @@ static void rpl_control_etx_change_callback(int8_t nwk_id, uint16_t previous_et uint16_t delay = rpl_policy_etx_change_parent_selection_delay(domain); tr_debug("Triggering parent selection due to ETX %s on neigh index %u, etx %u", better ? "better" : "worse", attribute_index, current_etx); rpl_dodag_t *dodag = NULL; + //Define Link Local Address + uint8_t ll_parent_address[16]; + memcpy(ll_parent_address, ADDR_LINK_LOCAL_PREFIX, 8); + memcpy(ll_parent_address + 8, mac64, 8); + ll_parent_address[8] ^= 2; ns_list_foreach(rpl_instance_t, instance, &domain->instances) { - if (better) { - dodag = rpl_instance_current_dodag(instance); - } - rpl_instance_trigger_parent_selection(instance, delay, dodag); + if (rpl_instance_am_root(instance)) { rpl_downward_paths_invalidate(instance); + } else { + if (better) { + //Only react here for candidate updates and when DODAG version is configured + if (rpl_instance_address_is_candidate(instance, ll_parent_address, 0)) { + dodag = rpl_instance_current_dodag(instance); + if (dodag) { + rpl_instance_trigger_parent_selection(instance, delay, dodag); + } + } + } else if (rpl_instance_address_is_parent(instance, ll_parent_address)) { + //Quick reaction for selected parent only + rpl_instance_trigger_parent_selection(instance, delay, NULL); + } } } } diff --git a/features/nanostack/sal-stack-nanostack/source/Security/kmp/kmp_api.c b/features/nanostack/sal-stack-nanostack/source/Security/kmp/kmp_api.c index 345e9ba9fc..d3a61fe867 100644 --- a/features/nanostack/sal-stack-nanostack/source/Security/kmp/kmp_api.c +++ b/features/nanostack/sal-stack-nanostack/source/Security/kmp/kmp_api.c @@ -99,7 +99,7 @@ static void kmp_sec_prot_receive_disable(sec_prot_t *prot); #define kmp_api_get_from_prot(prot) (kmp_api_t *)(((uint8_t *)prot) - offsetof(kmp_api_t, sec_prot)); -kmp_api_t *kmp_api_create(kmp_service_t *service, kmp_type_e type, sec_prot_cfg_t *cfg) +kmp_api_t *kmp_api_create(kmp_service_t *service, kmp_type_e type, sec_prot_cfg_t *prot_cfg, sec_timer_cfg_t *timer_cfg) { if (!service) { return 0; @@ -151,7 +151,8 @@ kmp_api_t *kmp_api_create(kmp_service_t *service, kmp_type_e type, sec_prot_cfg_ kmp->sec_prot.addr_get = kmp_sec_prot_eui64_addr_get; kmp->sec_prot.type_get = kmp_sec_prot_by_type_get; kmp->sec_prot.receive_disable = kmp_sec_prot_receive_disable; - kmp->sec_prot.cfg = cfg; + kmp->sec_prot.prot_cfg = prot_cfg; + kmp->sec_prot.timer_cfg = timer_cfg; if (sec_prot->init(&kmp->sec_prot) < 0) { ns_dyn_mem_free(kmp); diff --git a/features/nanostack/sal-stack-nanostack/source/Security/kmp/kmp_api.h b/features/nanostack/sal-stack-nanostack/source/Security/kmp/kmp_api.h index 062b36b4ad..10f36528bd 100644 --- a/features/nanostack/sal-stack-nanostack/source/Security/kmp/kmp_api.h +++ b/features/nanostack/sal-stack-nanostack/source/Security/kmp/kmp_api.h @@ -125,12 +125,13 @@ typedef void kmp_api_finished(kmp_api_t *kmp); * * \param service KMP service * \param type KMP type - * \param cfg configuration + * \param prot_cfg protocol configuration + * \param timer_cfg timer configuration * * \return KMP instance or NULL * */ -kmp_api_t *kmp_api_create(kmp_service_t *service, kmp_type_e type, sec_prot_cfg_t *cfg); +kmp_api_t *kmp_api_create(kmp_service_t *service, kmp_type_e type, sec_prot_cfg_t *prot_cfg, sec_timer_cfg_t *timer_cfg); /** * kmp_api_start start KMP api diff --git a/features/nanostack/sal-stack-nanostack/source/Security/protocols/eap_tls_sec_prot/auth_eap_tls_sec_prot.c b/features/nanostack/sal-stack-nanostack/source/Security/protocols/eap_tls_sec_prot/auth_eap_tls_sec_prot.c index e8118585ad..2fd7d96b65 100644 --- a/features/nanostack/sal-stack-nanostack/source/Security/protocols/eap_tls_sec_prot/auth_eap_tls_sec_prot.c +++ b/features/nanostack/sal-stack-nanostack/source/Security/protocols/eap_tls_sec_prot/auth_eap_tls_sec_prot.c @@ -189,7 +189,7 @@ static int8_t auth_eap_tls_sec_prot_receive(sec_prot_t *prot, void *pdu, uint16_ // Call state machine prot->state_machine(prot); // Resets trickle timer to give time for supplicant to answer - sec_prot_timer_trickle_start(&data->common, &prot->cfg->sec_prot_trickle_params); + sec_prot_timer_trickle_start(&data->common, &prot->prot_cfg->sec_prot_trickle_params); data->init_key_cnt++; } // Filters repeated initial EAPOL-key messages @@ -297,7 +297,7 @@ static void auth_eap_tls_sec_prot_timer_timeout(sec_prot_t *prot, uint16_t ticks } sec_prot_timer_timeout_handle(prot, &data->common, - &prot->cfg->sec_prot_trickle_params, ticks); + &prot->prot_cfg->sec_prot_trickle_params, ticks); } static void auth_eap_tls_sec_prot_tls_create_indication(sec_prot_t *tls_prot) @@ -421,7 +421,7 @@ static void auth_eap_tls_sec_prot_state_machine(sec_prot_t *prot) auth_eap_tls_sec_prot_message_send(prot, EAP_REQ, EAP_IDENTITY, EAP_TLS_EXCHANGE_NONE); // Start trickle timer to re-send if no response - sec_prot_timer_trickle_start(&data->common, &prot->cfg->sec_prot_trickle_params); + sec_prot_timer_trickle_start(&data->common, &prot->prot_cfg->sec_prot_trickle_params); sec_prot_state_set(prot, &data->common, EAP_TLS_STATE_RESPONSE_ID); break; @@ -445,7 +445,7 @@ static void auth_eap_tls_sec_prot_state_machine(sec_prot_t *prot) auth_eap_tls_sec_prot_message_send(prot, EAP_REQ, EAP_TLS, EAP_TLS_EXCHANGE_START); // Start trickle timer to re-send if no response - sec_prot_timer_trickle_start(&data->common, &prot->cfg->sec_prot_trickle_params); + sec_prot_timer_trickle_start(&data->common, &prot->prot_cfg->sec_prot_trickle_params); sec_prot_state_set(prot, &data->common, EAP_TLS_STATE_RESPONSE_START); break; @@ -527,7 +527,7 @@ static void auth_eap_tls_sec_prot_state_machine(sec_prot_t *prot) auth_eap_tls_sec_prot_message_send(prot, EAP_REQ, EAP_TLS, EAP_TLS_EXCHANGE_ONGOING); // Start trickle timer to re-send if no response - sec_prot_timer_trickle_start(&data->common, &prot->cfg->sec_prot_trickle_params); + sec_prot_timer_trickle_start(&data->common, &prot->prot_cfg->sec_prot_trickle_params); } else { // TLS done, indicate success to peer if (data->tls_result == EAP_TLS_RESULT_HANDSHAKE_OVER) { diff --git a/features/nanostack/sal-stack-nanostack/source/Security/protocols/eap_tls_sec_prot/supp_eap_tls_sec_prot.c b/features/nanostack/sal-stack-nanostack/source/Security/protocols/eap_tls_sec_prot/supp_eap_tls_sec_prot.c index c7c935242d..b7df2d6eb6 100644 --- a/features/nanostack/sal-stack-nanostack/source/Security/protocols/eap_tls_sec_prot/supp_eap_tls_sec_prot.c +++ b/features/nanostack/sal-stack-nanostack/source/Security/protocols/eap_tls_sec_prot/supp_eap_tls_sec_prot.c @@ -404,7 +404,7 @@ static void supp_eap_tls_sec_prot_state_machine(sec_prot_t *prot) } // Set retry timeout based on network size - data->common.ticks = prot->cfg->sec_prot_retry_timeout; + data->common.ticks = prot->prot_cfg->sec_prot_retry_timeout; // Store sequence ID supp_eap_tls_sec_prot_seq_id_update(prot); @@ -449,7 +449,7 @@ static void supp_eap_tls_sec_prot_state_machine(sec_prot_t *prot) supp_eap_tls_sec_prot_seq_id_update(prot); sec_prot_state_set(prot, &data->common, EAP_TLS_STATE_REQUEST); - data->common.ticks = prot->cfg->sec_prot_retry_timeout; + data->common.ticks = prot->prot_cfg->sec_prot_retry_timeout; // Initialize TLS protocol if (supp_eap_tls_sec_prot_init_tls(prot) < 0) { @@ -483,7 +483,7 @@ static void supp_eap_tls_sec_prot_state_machine(sec_prot_t *prot) // Store sequence ID if (supp_eap_tls_sec_prot_seq_id_update(prot)) { // When receiving a new sequence number, adds more time for re-send if no response - data->common.ticks = prot->cfg->sec_prot_retry_timeout; + data->common.ticks = prot->prot_cfg->sec_prot_retry_timeout; } // All fragments received for a message diff --git a/features/nanostack/sal-stack-nanostack/source/Security/protocols/fwh_sec_prot/auth_fwh_sec_prot.c b/features/nanostack/sal-stack-nanostack/source/Security/protocols/fwh_sec_prot/auth_fwh_sec_prot.c index 735112eeab..285a75db8e 100644 --- a/features/nanostack/sal-stack-nanostack/source/Security/protocols/fwh_sec_prot/auth_fwh_sec_prot.c +++ b/features/nanostack/sal-stack-nanostack/source/Security/protocols/fwh_sec_prot/auth_fwh_sec_prot.c @@ -313,7 +313,7 @@ static int8_t auth_fwh_sec_prot_message_send(sec_prot_t *prot, fwh_sec_prot_msg_ static void auth_fwh_sec_prot_timer_timeout(sec_prot_t *prot, uint16_t ticks) { fwh_sec_prot_int_t *data = fwh_sec_prot_get(prot); - sec_prot_timer_timeout_handle(prot, &data->common, &prot->cfg->sec_prot_trickle_params, ticks); + sec_prot_timer_timeout_handle(prot, &data->common, &prot->prot_cfg->sec_prot_trickle_params, ticks); } static void auth_fwh_sec_prot_state_machine(sec_prot_t *prot) @@ -350,7 +350,7 @@ static void auth_fwh_sec_prot_state_machine(sec_prot_t *prot) auth_fwh_sec_prot_message_send(prot, FWH_MESSAGE_1); // Start trickle timer to re-send if no response - sec_prot_timer_trickle_start(&data->common, &prot->cfg->sec_prot_trickle_params); + sec_prot_timer_trickle_start(&data->common, &prot->prot_cfg->sec_prot_trickle_params); sec_prot_state_set(prot, &data->common, FWH_STATE_MESSAGE_2); break; @@ -378,7 +378,7 @@ static void auth_fwh_sec_prot_state_machine(sec_prot_t *prot) auth_fwh_sec_prot_message_send(prot, FWH_MESSAGE_3); // Start trickle timer to re-send if no response - sec_prot_timer_trickle_start(&data->common, &prot->cfg->sec_prot_trickle_params); + sec_prot_timer_trickle_start(&data->common, &prot->prot_cfg->sec_prot_trickle_params); sec_prot_state_set(prot, &data->common, FWH_STATE_MESSAGE_4); } @@ -406,7 +406,7 @@ static void auth_fwh_sec_prot_state_machine(sec_prot_t *prot) // Reset PTK mismatch sec_prot_keys_ptk_mismatch_reset(prot->sec_keys); // Update PTK - sec_prot_keys_ptk_write(prot->sec_keys, data->new_ptk); + sec_prot_keys_ptk_write(prot->sec_keys, data->new_ptk, prot->timer_cfg->ptk_lifetime); sec_prot_keys_ptk_eui_64_write(prot->sec_keys, data->remote_eui64); sec_prot_state_set(prot, &data->common, FWH_STATE_FINISH); } diff --git a/features/nanostack/sal-stack-nanostack/source/Security/protocols/fwh_sec_prot/supp_fwh_sec_prot.c b/features/nanostack/sal-stack-nanostack/source/Security/protocols/fwh_sec_prot/supp_fwh_sec_prot.c index e5a44e18b8..ef3e9bd991 100644 --- a/features/nanostack/sal-stack-nanostack/source/Security/protocols/fwh_sec_prot/supp_fwh_sec_prot.c +++ b/features/nanostack/sal-stack-nanostack/source/Security/protocols/fwh_sec_prot/supp_fwh_sec_prot.c @@ -139,7 +139,7 @@ static int8_t supp_fwh_sec_prot_init(sec_prot_t *prot) sec_prot_init(&data->common); sec_prot_state_set(prot, &data->common, FWH_STATE_INIT); - data->common.ticks = prot->cfg->sec_prot_retry_timeout; + data->common.ticks = prot->prot_cfg->sec_prot_retry_timeout; data->msg3_received = false; data->msg3_retry_wait = false; data->recv_replay_cnt = 0; @@ -337,7 +337,7 @@ static void supp_fwh_sec_prot_state_machine(sec_prot_t *prot) if (sec_prot_result_ok_check(&data->common)) { // Send 4WH message 2 supp_fwh_sec_prot_message_send(prot, FWH_MESSAGE_2); - data->common.ticks = prot->cfg->sec_prot_retry_timeout; + data->common.ticks = prot->prot_cfg->sec_prot_retry_timeout; sec_prot_state_set(prot, &data->common, FWH_STATE_MESSAGE_3); } else { // Ready to be deleted @@ -365,7 +365,7 @@ static void supp_fwh_sec_prot_state_machine(sec_prot_t *prot) // Send 4WH message 2 supp_fwh_sec_prot_message_send(prot, FWH_MESSAGE_2); - data->common.ticks = prot->cfg->sec_prot_retry_timeout; + data->common.ticks = prot->prot_cfg->sec_prot_retry_timeout; return; } else if (data->recv_msg != FWH_MESSAGE_3) { return; @@ -392,7 +392,7 @@ static void supp_fwh_sec_prot_state_machine(sec_prot_t *prot) // Sends 4WH Message 4 supp_fwh_sec_prot_message_send(prot, FWH_MESSAGE_4); - data->common.ticks = prot->cfg->sec_prot_retry_timeout; + data->common.ticks = prot->prot_cfg->sec_prot_retry_timeout; sec_prot_state_set(prot, &data->common, FWH_STATE_FINISH); break; @@ -409,7 +409,7 @@ static void supp_fwh_sec_prot_state_machine(sec_prot_t *prot) tr_info("4WH: finish, wait Message 3 retry"); - sec_prot_keys_ptk_write(prot->sec_keys, data->new_ptk); + sec_prot_keys_ptk_write(prot->sec_keys, data->new_ptk, prot->timer_cfg->ptk_lifetime); sec_prot_keys_ptk_eui_64_write(prot->sec_keys, data->remote_eui64); data->common.ticks = 60 * 10; // 60 seconds diff --git a/features/nanostack/sal-stack-nanostack/source/Security/protocols/gkh_sec_prot/auth_gkh_sec_prot.c b/features/nanostack/sal-stack-nanostack/source/Security/protocols/gkh_sec_prot/auth_gkh_sec_prot.c index d39e912c6b..7d736ae95b 100644 --- a/features/nanostack/sal-stack-nanostack/source/Security/protocols/gkh_sec_prot/auth_gkh_sec_prot.c +++ b/features/nanostack/sal-stack-nanostack/source/Security/protocols/gkh_sec_prot/auth_gkh_sec_prot.c @@ -261,7 +261,7 @@ static int8_t auth_gkh_sec_prot_message_send(sec_prot_t *prot, gkh_sec_prot_msg_ static void auth_gkh_sec_prot_timer_timeout(sec_prot_t *prot, uint16_t ticks) { gkh_sec_prot_int_t *data = gkh_sec_prot_get(prot); - sec_prot_timer_timeout_handle(prot, &data->common, &prot->cfg->sec_prot_trickle_params, ticks); + sec_prot_timer_timeout_handle(prot, &data->common, &prot->prot_cfg->sec_prot_trickle_params, ticks); } static void auth_gkh_sec_prot_state_machine(sec_prot_t *prot) @@ -290,7 +290,7 @@ static void auth_gkh_sec_prot_state_machine(sec_prot_t *prot) auth_gkh_sec_prot_message_send(prot, GKH_MESSAGE_1); // Start trickle timer to re-send if no response - sec_prot_timer_trickle_start(&data->common, &prot->cfg->sec_prot_trickle_params); + sec_prot_timer_trickle_start(&data->common, &prot->prot_cfg->sec_prot_trickle_params); sec_prot_state_set(prot, &data->common, GKH_STATE_MESSAGE_2); diff --git a/features/nanostack/sal-stack-nanostack/source/Security/protocols/sec_prot.h b/features/nanostack/sal-stack-nanostack/source/Security/protocols/sec_prot.h index 556d769f6b..c6ebae78a9 100644 --- a/features/nanostack/sal-stack-nanostack/source/Security/protocols/sec_prot.h +++ b/features/nanostack/sal-stack-nanostack/source/Security/protocols/sec_prot.h @@ -268,7 +268,8 @@ struct sec_prot_s { sec_prot_receive_disable *receive_disable; /**< Disable receiving of messages */ sec_prot_keys_t *sec_keys; /**< Security keys storage pointer */ - sec_prot_cfg_t *cfg; /**< Configuration pointer */ + sec_prot_cfg_t *prot_cfg; /**< Security protocol configuration pointer */ + sec_timer_cfg_t *timer_cfg; /**< Security timer configuration pointer */ uint8_t header_size; /**< Header size */ sec_prot_int_data_t *data; /**< Protocol internal data */ }; diff --git a/features/nanostack/sal-stack-nanostack/source/Security/protocols/sec_prot_cfg.h b/features/nanostack/sal-stack-nanostack/source/Security/protocols/sec_prot_cfg.h index fa2a88dafb..f0a118b7c1 100644 --- a/features/nanostack/sal-stack-nanostack/source/Security/protocols/sec_prot_cfg.h +++ b/features/nanostack/sal-stack-nanostack/source/Security/protocols/sec_prot_cfg.h @@ -24,6 +24,23 @@ typedef struct sec_prot_cfg_s { trickle_params_t sec_prot_trickle_params; uint16_t sec_prot_retry_timeout; uint16_t sec_max_ongoing_authentication; + uint16_t initial_key_retry_delay; + trickle_params_t initial_key_trickle_params; + uint8_t initial_key_retry_cnt; } sec_prot_cfg_t; +/* Security timer configuration settings */ + +typedef struct sec_timer_cfg_s { + uint32_t gtk_expire_offset; /* GTK lifetime; GTK_EXPIRE_OFFSET (seconds) */ + uint32_t pmk_lifetime; /* PMK lifetime (seconds) */ + uint32_t ptk_lifetime; /* PTK lifetime (seconds) */ + uint16_t gtk_new_act_time; /* GTK_NEW_ACTIVATION_TIME (1/X of expire offset) */ + uint16_t revocat_lifetime_reduct; /* REVOCATION_LIFETIME_REDUCTION (reduction of lifetime) */ + uint16_t gtk_request_imin; /* GTK_REQUEST_IMIN (seconds) */ + uint16_t gtk_request_imax; /* GTK_REQUEST_IMAX (seconds) */ + uint16_t gtk_max_mismatch; /* GTK_MAX_MISMATCH (seconds) */ + uint8_t gtk_new_install_req; /* GTK_NEW_INSTALL_REQUIRED (percent of GTK lifetime) */ +} sec_timer_cfg_t; + #endif /* SEC_PROT_CONF_H_ */ diff --git a/features/nanostack/sal-stack-nanostack/source/Security/protocols/sec_prot_keys.c b/features/nanostack/sal-stack-nanostack/source/Security/protocols/sec_prot_keys.c index 49fd18758a..d7071e9323 100644 --- a/features/nanostack/sal-stack-nanostack/source/Security/protocols/sec_prot_keys.c +++ b/features/nanostack/sal-stack-nanostack/source/Security/protocols/sec_prot_keys.c @@ -56,8 +56,8 @@ sec_prot_keys_t *sec_prot_keys_create(sec_prot_gtk_keys_t *gtks, const sec_prot_ void sec_prot_keys_init(sec_prot_keys_t *sec_keys, sec_prot_gtk_keys_t *gtks, const sec_prot_certs_t *certs) { memset(sec_keys, 0, sizeof(sec_prot_keys_t)); - sec_keys->pmk_lifetime = PMK_LIFETIME_INSTALL; - sec_keys->ptk_lifetime = PTK_LIFETIME_INSTALL; + sec_keys->pmk_lifetime = 0; + sec_keys->ptk_lifetime = 0; sec_keys->pmk_key_replay_cnt = 0; sec_keys->gtks = gtks; sec_keys->certs = certs; @@ -101,12 +101,12 @@ void sec_prot_keys_gtks_delete(sec_prot_gtk_keys_t *gtks) ns_dyn_mem_free(gtks); } -void sec_prot_keys_pmk_write(sec_prot_keys_t *sec_keys, uint8_t *pmk) +void sec_prot_keys_pmk_write(sec_prot_keys_t *sec_keys, uint8_t *pmk, uint32_t pmk_lifetime) { memcpy(sec_keys->pmk, pmk, PMK_LEN); sec_keys->pmk_key_replay_cnt = 0; sec_keys->pmk_key_replay_cnt_set = false; - sec_keys->pmk_lifetime = PMK_LIFETIME_INSTALL; + sec_keys->pmk_lifetime = pmk_lifetime; sec_keys->pmk_set = true; sec_keys->updated = true; } @@ -116,7 +116,7 @@ void sec_prot_keys_pmk_delete(sec_prot_keys_t *sec_keys) memset(sec_keys->pmk, 0, PMK_LEN); sec_keys->pmk_key_replay_cnt = 0; sec_keys->pmk_key_replay_cnt_set = false; - sec_keys->pmk_lifetime = PMK_LIFETIME_INSTALL; + sec_keys->pmk_lifetime = 0; sec_keys->pmk_set = false; sec_keys->updated = true; } @@ -130,6 +130,15 @@ uint8_t *sec_prot_keys_pmk_get(sec_prot_keys_t *sec_keys) return sec_keys->pmk; } +uint32_t sec_prot_keys_pmk_lifetime_get(sec_prot_keys_t *sec_keys) +{ + if (!sec_keys->pmk_set) { + return 0; + } + + return sec_keys->pmk_lifetime; +} + uint64_t sec_prot_keys_pmk_replay_cnt_get(sec_prot_keys_t *sec_keys) { return sec_keys->pmk_key_replay_cnt; @@ -184,16 +193,12 @@ bool sec_prot_keys_pmk_mismatch_is_set(sec_prot_keys_t *sec_keys) return sec_keys->pmk_mismatch; } -bool sec_prot_keys_pmk_lifetime_decrement(sec_prot_keys_t *sec_keys, uint32_t default_lifetime, uint8_t seconds) +bool sec_prot_keys_pmk_lifetime_decrement(sec_prot_keys_t *sec_keys, uint8_t seconds) { if (!sec_keys->pmk_set) { return false; } - if (sec_keys->pmk_lifetime == PMK_LIFETIME_INSTALL) { - sec_keys->pmk_lifetime = default_lifetime; - } - if (sec_keys->pmk_lifetime > seconds) { sec_keys->pmk_lifetime -= seconds; } else { @@ -207,10 +212,10 @@ bool sec_prot_keys_pmk_lifetime_decrement(sec_prot_keys_t *sec_keys, uint32_t de return false; } -void sec_prot_keys_ptk_write(sec_prot_keys_t *sec_keys, uint8_t *ptk) +void sec_prot_keys_ptk_write(sec_prot_keys_t *sec_keys, uint8_t *ptk, uint32_t ptk_lifetime) { memcpy(sec_keys->ptk, ptk, PTK_LEN); - sec_keys->ptk_lifetime = PTK_LIFETIME_INSTALL; + sec_keys->ptk_lifetime = ptk_lifetime; sec_keys->ptk_set = true; sec_keys->updated = true; } @@ -218,7 +223,7 @@ void sec_prot_keys_ptk_write(sec_prot_keys_t *sec_keys, uint8_t *ptk) void sec_prot_keys_ptk_delete(sec_prot_keys_t *sec_keys) { memset(sec_keys->ptk, 0, PTK_LEN); - sec_keys->ptk_lifetime = PTK_LIFETIME_INSTALL; + sec_keys->ptk_lifetime = 0; sec_keys->ptk_set = false; sec_keys->updated = true; } @@ -232,6 +237,15 @@ uint8_t *sec_prot_keys_ptk_get(sec_prot_keys_t *sec_keys) return sec_keys->ptk; } +uint32_t sec_prot_keys_ptk_lifetime_get(sec_prot_keys_t *sec_keys) +{ + if (!sec_keys->ptk_set) { + return 0; + } + + return sec_keys->ptk_lifetime; +} + void sec_prot_keys_ptk_mismatch_set(sec_prot_keys_t *sec_keys) { sec_keys->ptk_mismatch = true; @@ -270,16 +284,12 @@ void sec_prot_keys_ptk_eui_64_delete(sec_prot_keys_t *sec_keys) sec_keys->updated = true; } -bool sec_prot_keys_ptk_lifetime_decrement(sec_prot_keys_t *sec_keys, uint32_t default_lifetime, uint8_t seconds) +bool sec_prot_keys_ptk_lifetime_decrement(sec_prot_keys_t *sec_keys, uint8_t seconds) { if (!sec_keys->ptk_set) { return false; } - if (sec_keys->ptk_lifetime == PTK_LIFETIME_INSTALL) { - sec_keys->ptk_lifetime = default_lifetime; - } - if (sec_keys->ptk_lifetime > seconds) { sec_keys->ptk_lifetime -= seconds; } else { @@ -913,7 +923,7 @@ uint8_t sec_prot_keys_gtk_count(sec_prot_gtk_keys_t *gtks) void sec_prot_keys_ptk_installed_gtk_hash_clear_all(sec_prot_keys_t *sec_keys) { for (uint8_t index = 0; index < GTK_NUM; index++) { - memset(sec_keys->ins_gtk_hash[sec_keys->gtk_set_index].hash, 0, INS_GTK_HASH_LEN); + memset(sec_keys->ins_gtk_hash[index].hash, 0, INS_GTK_HASH_LEN); } sec_keys->ins_gtk_hash_set = 0; sec_keys->ins_gtk_4wh_hash_set = 0; diff --git a/features/nanostack/sal-stack-nanostack/source/Security/protocols/sec_prot_keys.h b/features/nanostack/sal-stack-nanostack/source/Security/protocols/sec_prot_keys.h index 376a3f4159..06302519d2 100644 --- a/features/nanostack/sal-stack-nanostack/source/Security/protocols/sec_prot_keys.h +++ b/features/nanostack/sal-stack-nanostack/source/Security/protocols/sec_prot_keys.h @@ -56,9 +56,6 @@ #define GTK_ALL_HASHES_LEN GTK_HASH_LEN * GTK_NUM #define INS_GTK_HASH_LEN 2 -#define PMK_LIFETIME_INSTALL 0xFFFFF -#define PTK_LIFETIME_INSTALL 0xFFFFF - // Limit is 60000 (of 65536) #define PMK_KEY_REPLAY_CNT_LIMIT 60000 // Upper limit for PMK replay counter #define PMK_KEY_REPLAY_CNT_LIMIT_MASK 0xFFFF // Upper limit mask @@ -215,9 +212,10 @@ void sec_prot_keys_gtks_delete(sec_prot_gtk_keys_t *gtks); * * \param sec_keys security keys * \param pmk Pairwise Master Key + * \param pmk_lifetime PMK lifetime * */ -void sec_prot_keys_pmk_write(sec_prot_keys_t *sec_keys, uint8_t *pmk); +void sec_prot_keys_pmk_write(sec_prot_keys_t *sec_keys, uint8_t *pmk, uint32_t pmk_lifetime); /** * sec_prot_keys_pmk_delete deletes PMK @@ -237,6 +235,16 @@ void sec_prot_keys_pmk_delete(sec_prot_keys_t *sec_keys); */ uint8_t *sec_prot_keys_pmk_get(sec_prot_keys_t *sec_keys); +/** + * sec_prot_keys_pmk_lifetime_get Pairwise Master Key lifetime + * + * \param sec_keys security keys + * + * \return PMK lifetime + * + */ +uint32_t sec_prot_keys_pmk_lifetime_get(sec_prot_keys_t *sec_keys); + /** * sec_prot_keys_pmk_replay_cnt_get gets PMK replay counter value * @@ -309,23 +317,23 @@ bool sec_prot_keys_pmk_mismatch_is_set(sec_prot_keys_t *sec_keys); * sec_prot_keys_pmk_lifetime_decrement decrements PMK lifetime * * \param sec_keys security keys - * \param default_lifetime default lifetime for PMK * \param seconds elapsed seconds * * \return true PMK expired and deleted both PMK and PTK * \return false PMK not expired * */ -bool sec_prot_keys_pmk_lifetime_decrement(sec_prot_keys_t *sec_keys, uint32_t default_lifetime, uint8_t seconds); +bool sec_prot_keys_pmk_lifetime_decrement(sec_prot_keys_t *sec_keys, uint8_t seconds); /** * sec_prot_keys_ptk_write writes Pairwise Transient Key * * \param sec_keys security keys * \param ptk Pairwise Transient Key + * \param ptk_lifetime PTK lifetime * */ -void sec_prot_keys_ptk_write(sec_prot_keys_t *sec_keys, uint8_t *ptk); +void sec_prot_keys_ptk_write(sec_prot_keys_t *sec_keys, uint8_t *ptk, uint32_t ptk_lifetime); /** * sec_prot_keys_ptk_delete deletes PTK @@ -345,6 +353,16 @@ void sec_prot_keys_ptk_delete(sec_prot_keys_t *sec_keys); */ uint8_t *sec_prot_keys_ptk_get(sec_prot_keys_t *sec_keys); +/** + * sec_prot_keys_ptk_lifetime_get gets Pairwise Transient Key lifetime + * + * \param sec_keys security keys + * + * \return PTK lifetime + * + */ +uint32_t sec_prot_keys_ptk_lifetime_get(sec_prot_keys_t *sec_keys); + /** * sec_prot_keys_ptk_mismatch_set set PTK mismatch * @@ -402,14 +420,13 @@ void sec_prot_keys_ptk_eui_64_delete(sec_prot_keys_t *sec_keys); * sec_prot_keys_ptk_lifetime_decrement decrements PTK lifetime * * \param sec_keys security keys - * \param default_lifetime default lifetime for PTK * \param seconds elapsed seconds * * \return true PTK expired and deleted * \return false PTK not expired * */ -bool sec_prot_keys_ptk_lifetime_decrement(sec_prot_keys_t *sec_keys, uint32_t default_lifetime, uint8_t seconds); +bool sec_prot_keys_ptk_lifetime_decrement(sec_prot_keys_t *sec_keys, uint8_t seconds); /** * sec_prot_keys_are_updated returns security keys have been updated flag diff --git a/features/nanostack/sal-stack-nanostack/source/Security/protocols/tls_sec_prot/tls_sec_prot.c b/features/nanostack/sal-stack-nanostack/source/Security/protocols/tls_sec_prot/tls_sec_prot.c index 330ed6b143..d4b8c549ae 100644 --- a/features/nanostack/sal-stack-nanostack/source/Security/protocols/tls_sec_prot/tls_sec_prot.c +++ b/features/nanostack/sal-stack-nanostack/source/Security/protocols/tls_sec_prot/tls_sec_prot.c @@ -375,7 +375,7 @@ static void client_tls_sec_prot_state_machine(sec_prot_t *prot) data->calculating = false; if (sec_prot_result_ok_check(&data->common)) { - sec_prot_keys_pmk_write(prot->sec_keys, data->new_pmk); + sec_prot_keys_pmk_write(prot->sec_keys, data->new_pmk, prot->timer_cfg->pmk_lifetime); } // KMP-FINISHED.indication, @@ -494,7 +494,7 @@ static void server_tls_sec_prot_state_machine(sec_prot_t *prot) data->calculating = false; if (sec_prot_result_ok_check(&data->common)) { - sec_prot_keys_pmk_write(prot->sec_keys, data->new_pmk); + sec_prot_keys_pmk_write(prot->sec_keys, data->new_pmk, prot->timer_cfg->pmk_lifetime); } // KMP-FINISHED.indication, diff --git a/features/nanostack/sal-stack-nanostack/source/Service_Libs/etx/etx.c b/features/nanostack/sal-stack-nanostack/source/Service_Libs/etx/etx.c index 639490981a..76b7c7d203 100644 --- a/features/nanostack/sal-stack-nanostack/source/Service_Libs/etx/etx.c +++ b/features/nanostack/sal-stack-nanostack/source/Service_Libs/etx/etx.c @@ -37,9 +37,14 @@ #define TRACE_GROUP "etx" +typedef struct { + uint8_t attribute_index; + const uint8_t *mac64; +} ext_neigh_info_t; + static uint16_t etx_current_calc(uint16_t etx, uint8_t accumulated_failures); static uint16_t etx_dbm_lqi_calc(uint8_t lqi, int8_t dbm); -static void etx_value_change_callback_needed_check(uint16_t etx, uint16_t *stored_diff_etx, uint8_t accumulated_failures, uint8_t attribute_index); +static void etx_value_change_callback_needed_check(uint16_t etx, uint16_t *stored_diff_etx, uint8_t accumulated_failures, ext_neigh_info_t *etx_neigh_info); static void etx_accum_failures_callback_needed_check(etx_storage_t *entry, uint8_t attribute_index); static void etx_cache_entry_init(uint8_t attribute_index); @@ -90,7 +95,7 @@ static ext_info_t etx_info = { .interface_id = -1 }; -static void etx_calculation(etx_storage_t *entry, uint16_t attempts, uint8_t acks_rx, uint8_t attribute_index) +static void etx_calculation(etx_storage_t *entry, uint16_t attempts, uint8_t acks_rx, ext_neigh_info_t *etx_neigh_info) { if (etx_info.hysteresis && !entry->stored_diff_etx) { if (entry->etx_samples >= etx_info.init_etx_sample_count) { @@ -130,9 +135,9 @@ static void etx_calculation(etx_storage_t *entry, uint16_t attempts, uint8_t ack entry->etx = etx; if (entry->etx_samples >= etx_info.init_etx_sample_count) { - etx_cache_entry_init(attribute_index); + etx_cache_entry_init(etx_neigh_info->attribute_index); // Checks if ETX value change callback is needed - etx_value_change_callback_needed_check(entry->etx, &(entry->stored_diff_etx), entry->accumulated_failures, attribute_index); + etx_value_change_callback_needed_check(entry->etx, &(entry->stored_diff_etx), entry->accumulated_failures, etx_neigh_info); } } @@ -203,7 +208,7 @@ static etx_sample_storage_t *etx_cache_sample_update(uint8_t attribute_index, ui * \param addr_type address type, ADDR_802_15_4_SHORT or ADDR_802_15_4_LONG * \param addr_ptr PAN ID with 802.15.4 address */ -void etx_transm_attempts_update(int8_t interface_id, uint8_t attempts, bool success, uint8_t attribute_index) +void etx_transm_attempts_update(int8_t interface_id, uint8_t attempts, bool success, uint8_t attribute_index, const uint8_t *mac64_addr_ptr) { uint8_t accumulated_failures; // Gets table entry @@ -212,6 +217,10 @@ void etx_transm_attempts_update(int8_t interface_id, uint8_t attempts, bool succ return; } + ext_neigh_info_t etx_neigh_info; + etx_neigh_info.attribute_index = attribute_index; + etx_neigh_info.mac64 = mac64_addr_ptr; + if (entry->etx_samples < 7) { entry->etx_samples++; } @@ -225,7 +234,7 @@ void etx_transm_attempts_update(int8_t interface_id, uint8_t attempts, bool succ return; } - etx_calculation(entry, storage->attempts_count, storage->received_acks, attribute_index); + etx_calculation(entry, storage->attempts_count, storage->received_acks, &etx_neigh_info); if (entry->etx_samples < 7 && !success) { entry->etx_samples = 7; //Stop Probing to failure @@ -254,7 +263,7 @@ void etx_transm_attempts_update(int8_t interface_id, uint8_t attempts, bool succ if (entry->etx) { if (success) { - etx_calculation(entry, attempts + accumulated_failures, 1, attribute_index); + etx_calculation(entry, attempts + accumulated_failures, 1, &etx_neigh_info); } } } @@ -268,35 +277,42 @@ void etx_transm_attempts_update(int8_t interface_id, uint8_t attempts, bool succ * \param remote_incoming_idr Remote incoming IDR * \param mac64_addr_ptr long MAC address */ -void etx_remote_incoming_idr_update(int8_t interface_id, uint8_t remote_incoming_idr, uint8_t attribute_index) +void etx_remote_incoming_idr_update(int8_t interface_id, uint8_t remote_incoming_idr, uint8_t attribute_index, const uint8_t *mac64_addr_ptr) { etx_storage_t *entry = etx_storage_entry_get(interface_id, attribute_index); - - if (entry) { - // If ETX has been set - if (entry->etx) { - // If hysteresis is set stores ETX value to enable comparison - if (etx_info.hysteresis && !entry->stored_diff_etx) { - entry->stored_diff_etx = entry->etx; - } - // remote EXT = remote incoming IDR^2 (12 bit fraction) - uint32_t remote_ext = ((uint32_t)remote_incoming_idr * remote_incoming_idr) << 2; - - // ETX = 7/8 * current ETX + 1/8 * remote ETX */ - uint32_t etx = entry->etx - (entry->etx >> ETX_MOVING_AVERAGE_FRACTION); - etx += remote_ext >> ETX_MOVING_AVERAGE_FRACTION; - - if (etx > 0xffff) { - entry->etx = 0xffff; - } else { - entry->etx = etx; - } - - // Checks if ETX value change callback is needed - etx_value_change_callback_needed_check(entry->etx, &(entry->stored_diff_etx), entry->accumulated_failures, attribute_index); - } - entry->remote_incoming_idr = remote_incoming_idr; + if (!entry) { + return; } + + ext_neigh_info_t etx_neigh_info; + etx_neigh_info.attribute_index = attribute_index; + etx_neigh_info.mac64 = mac64_addr_ptr; + + + // If ETX has been set + if (entry->etx) { + // If hysteresis is set stores ETX value to enable comparison + if (etx_info.hysteresis && !entry->stored_diff_etx) { + entry->stored_diff_etx = entry->etx; + } + // remote EXT = remote incoming IDR^2 (12 bit fraction) + uint32_t remote_ext = ((uint32_t)remote_incoming_idr * remote_incoming_idr) << 2; + + // ETX = 7/8 * current ETX + 1/8 * remote ETX */ + uint32_t etx = entry->etx - (entry->etx >> ETX_MOVING_AVERAGE_FRACTION); + etx += remote_ext >> ETX_MOVING_AVERAGE_FRACTION; + + if (etx > 0xffff) { + entry->etx = 0xffff; + } else { + entry->etx = etx; + } + + // Checks if ETX value change callback is needed + etx_value_change_callback_needed_check(entry->etx, &(entry->stored_diff_etx), entry->accumulated_failures, &etx_neigh_info); + } + entry->remote_incoming_idr = remote_incoming_idr; + } /** @@ -442,14 +458,18 @@ static uint16_t etx_current_calc(uint16_t etx, uint8_t accumulated_failures) * * \return 0x0100 to 0xFFFF local incoming IDR value (8 bit fraction) */ -uint16_t etx_lqi_dbm_update(int8_t interface_id, uint8_t lqi, int8_t dbm, uint8_t attribute_index) +uint16_t etx_lqi_dbm_update(int8_t interface_id, uint8_t lqi, int8_t dbm, uint8_t attribute_index, const uint8_t *mac64_addr_ptr) { uint32_t local_incoming_idr = 0; uint32_t etx = 0; etx_storage_t *entry = etx_storage_entry_get(interface_id, attribute_index); + if (entry) { + ext_neigh_info_t etx_neigh_info; + etx_neigh_info.attribute_index = attribute_index; + etx_neigh_info.mac64 = mac64_addr_ptr; // If local ETX is not set calculate it based on LQI and dBm if (!entry->etx) { etx = etx_dbm_lqi_calc(lqi, dbm); @@ -458,7 +478,7 @@ uint16_t etx_lqi_dbm_update(int8_t interface_id, uint8_t lqi, int8_t dbm, uint8_ entry->tmp_etx = true; if (etx_info.callback_ptr) { etx_info.callback_ptr(etx_info.interface_id, 0, entry->etx >> 4, - attribute_index); + attribute_index, mac64_addr_ptr); } } // If local ETX has been calculated without remote incoming IDR and @@ -474,7 +494,7 @@ uint16_t etx_lqi_dbm_update(int8_t interface_id, uint8_t lqi, int8_t dbm, uint8_ entry->etx = etx >> 12; local_incoming_idr >>= 4; - etx_value_change_callback_needed_check(entry->etx, &(entry->stored_diff_etx), entry->accumulated_failures, attribute_index); + etx_value_change_callback_needed_check(entry->etx, &(entry->stored_diff_etx), entry->accumulated_failures, &etx_neigh_info); } } @@ -721,7 +741,7 @@ uint8_t etx_accum_failures_callback_register(nwk_interface_id nwk_id, int8_t int * * \return ETX value (12 bit fraction) */ -static void etx_value_change_callback_needed_check(uint16_t etx, uint16_t *stored_diff_etx, uint8_t accumulated_failures, uint8_t attribute_index) +static void etx_value_change_callback_needed_check(uint16_t etx, uint16_t *stored_diff_etx, uint8_t accumulated_failures, ext_neigh_info_t *etx_neigh_info) { uint16_t current_etx; bool callback = false; @@ -747,7 +767,7 @@ static void etx_value_change_callback_needed_check(uint16_t etx, uint16_t *store // Calls callback function if (callback) { - etx_info.callback_ptr(etx_info.interface_id, (*stored_diff_etx) >> 4, current_etx >> 4, attribute_index); + etx_info.callback_ptr(etx_info.interface_id, (*stored_diff_etx) >> 4, current_etx >> 4, etx_neigh_info->attribute_index, etx_neigh_info->mac64); *stored_diff_etx = current_etx; } } @@ -782,7 +802,7 @@ static void etx_accum_failures_callback_needed_check(etx_storage_t *entry, uint8 * \param mac64_addr_ptr long MAC address * */ -void etx_neighbor_remove(int8_t interface_id, uint8_t attribute_index) +void etx_neighbor_remove(int8_t interface_id, uint8_t attribute_index, const uint8_t *mac64_addr_ptr) { //tr_debug("Remove attribute %u", attribute_index); @@ -795,7 +815,8 @@ void etx_neighbor_remove(int8_t interface_id, uint8_t attribute_index) if (!stored_diff_etx) { stored_diff_etx = 0xffff; } - etx_info.callback_ptr(etx_info.interface_id, stored_diff_etx, 0xffff, attribute_index); + + etx_info.callback_ptr(etx_info.interface_id, stored_diff_etx, 0xffff, attribute_index, mac64_addr_ptr); } if (etx_info.cache_sample_requested) { @@ -829,7 +850,10 @@ void etx_cache_timer(int8_t interface_id, uint16_t seconds_update) etx_sample_storage_t *storage = etx_info.etx_cache_storage_list + neighbour->index; if (etx_update_possible(storage, etx_entry, seconds_update)) { - etx_calculation(etx_entry, storage->attempts_count, storage->received_acks, neighbour->index); + ext_neigh_info_t etx_neigh_info; + etx_neigh_info.attribute_index = neighbour->index; + etx_neigh_info.mac64 = neighbour->mac64; + etx_calculation(etx_entry, storage->attempts_count, storage->received_acks, &etx_neigh_info); } } diff --git a/features/nanostack/sal-stack-nanostack/source/Service_Libs/etx/etx.h b/features/nanostack/sal-stack-nanostack/source/Service_Libs/etx/etx.h index c785cc5c98..a1c40b2694 100644 --- a/features/nanostack/sal-stack-nanostack/source/Service_Libs/etx/etx.h +++ b/features/nanostack/sal-stack-nanostack/source/Service_Libs/etx/etx.h @@ -76,8 +76,9 @@ typedef struct etx_sample_storage_s { * \param attempts number of attempts to send message * \param success was message sending successful * \param attribute_index Neighbour attribute index + * \param mac64_addr_ptr Neighbour MAC64 */ -void etx_transm_attempts_update(int8_t interface_id, uint8_t attempts, bool success, uint8_t attribute_index); +void etx_transm_attempts_update(int8_t interface_id, uint8_t attempts, bool success, uint8_t attribute_index, const uint8_t *mac64_addr_ptr); /** * \brief A function to update ETX value based on remote incoming IDR @@ -88,8 +89,9 @@ void etx_transm_attempts_update(int8_t interface_id, uint8_t attempts, bool succ * \param interface_id Interface identifier * \param remote_incoming_idr Remote incoming IDR * \param attribute_index Neighbour attribute index + * \param mac64_addr_ptr Neighbour MAC64 */ -void etx_remote_incoming_idr_update(int8_t interface_id, uint8_t remote_incoming_idr, uint8_t attribute_index); +void etx_remote_incoming_idr_update(int8_t interface_id, uint8_t remote_incoming_idr, uint8_t attribute_index, const uint8_t *mac64_addr_ptr); /** * \brief A function to read ETX value @@ -139,10 +141,11 @@ uint16_t etx_local_etx_read(int8_t interface_id, uint8_t attribute_index); * \param lqi link quality indicator * \param dbm measured dBm * \param attribute_index Neighbour attribute index + * \param mac64_addr_ptr Neighbour MAC64 * * \return 0x0100 to 0xFFFF local incoming IDR value (8 bit fraction) */ -uint16_t etx_lqi_dbm_update(int8_t interface_id, uint8_t lqi, int8_t dbm, uint8_t attribute_index); +uint16_t etx_lqi_dbm_update(int8_t interface_id, uint8_t lqi, int8_t dbm, uint8_t attribute_index, const uint8_t *mac64_addr_ptr); /** * \brief A function callback that indicates ETX value change @@ -154,9 +157,10 @@ uint16_t etx_lqi_dbm_update(int8_t interface_id, uint8_t lqi, int8_t dbm, uint8_ * \param previous_etx ETX value to what the current ETX was compared (8 bit fraction) * \param current_etx current ETX value (8 bit fraction) * \param attribute_index Neighbour attribute index + * \param mac64_addr_ptr Pointer to MAC64 for given etx update * */ -typedef void (etx_value_change_handler_t)(int8_t nwk_id, uint16_t previous_etx, uint16_t current_etx, uint8_t attribute_index); +typedef void (etx_value_change_handler_t)(int8_t nwk_id, uint16_t previous_etx, uint16_t current_etx, uint8_t attribute_index, const uint8_t *mac64_addr_ptr); /** * \brief A function callback that indicates the number of accumulated TX failures @@ -232,9 +236,10 @@ uint8_t etx_accum_failures_callback_register(nwk_interface_id nwk_id, int8_t int * if that is set. * * \param attribute_index Neighbour attribute index + * \param mac64_addr_ptr Neighbour MAC64 * */ -void etx_neighbor_remove(int8_t interface_id, uint8_t attribute_index); +void etx_neighbor_remove(int8_t interface_id, uint8_t attribute_index, const uint8_t *mac64_addr_ptr); /** * \brief A function for update cached ETX calculation diff --git a/features/nanostack/sal-stack-nanostack/test/nanostack/unittest/mac/mac_cca_threshold/Makefile b/features/nanostack/sal-stack-nanostack/test/nanostack/unittest/mac/mac_cca_threshold/Makefile deleted file mode 100644 index a3cec64068..0000000000 --- a/features/nanostack/sal-stack-nanostack/test/nanostack/unittest/mac/mac_cca_threshold/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -include ../../makefile_defines.txt - -COMPONENT_NAME = mac_cca_threshold_unit - -#This must be changed manually -SRC_FILES = \ - ../../../../../source/MAC/IEEE802_15_4/mac_cca_threshold.c - -TEST_SRC_FILES = \ - main.cpp \ - mac_cca_threshold_test.cpp \ - test_mac_cca_threshold.c \ - ../../stub/mbed_trace_stub.c \ - ../../stub/nsdynmemLIB_stub.c \ - -include ../../MakefileWorker.mk - -CPPUTESTFLAGS += -DFEA_TRACE_SUPPORT - diff --git a/features/nanostack/sal-stack-nanostack/test/nanostack/unittest/mac/mac_cca_threshold/mac_cca_threshold_test.cpp b/features/nanostack/sal-stack-nanostack/test/nanostack/unittest/mac/mac_cca_threshold/mac_cca_threshold_test.cpp deleted file mode 100644 index 62a4ea4ff4..0000000000 --- a/features/nanostack/sal-stack-nanostack/test/nanostack/unittest/mac/mac_cca_threshold/mac_cca_threshold_test.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2016-2018, Arm Limited and affiliates. - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include "CppUTest/TestHarness.h" -#include "test_mac_cca_threshold.h" - -TEST_GROUP(mac_cca_threshold) -{ - void setup() { - } - - void teardown() { - } -}; - -TEST(mac_cca_threshold, test_mac_cca_thr_init) -{ - CHECK(test_mac_cca_thr_init()); -} - -TEST(mac_cca_threshold, test_mac_cca_thr_update_channel_threshold) -{ - CHECK(test_mac_cca_thr_update_channel_threshold()); -} - -TEST(mac_cca_threshold, test_mac_cca_thr_channel_failed) -{ - CHECK(test_mac_cca_thr_channel_failed()); -} - -TEST(mac_cca_threshold, test_mac_cca_threshold_update) -{ - CHECK(test_mac_cca_threshold_update()); -} diff --git a/features/nanostack/sal-stack-nanostack/test/nanostack/unittest/mac/mac_cca_threshold/main.cpp b/features/nanostack/sal-stack-nanostack/test/nanostack/unittest/mac/mac_cca_threshold/main.cpp deleted file mode 100644 index e362bd7009..0000000000 --- a/features/nanostack/sal-stack-nanostack/test/nanostack/unittest/mac/mac_cca_threshold/main.cpp +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2016-2018, Arm Limited and affiliates. - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "CppUTest/CommandLineTestRunner.h" -#include "CppUTest/TestPlugin.h" -#include "CppUTest/TestRegistry.h" -#include "CppUTestExt/MockSupportPlugin.h" -int main(int ac, char **av) -{ - return CommandLineTestRunner::RunAllTests(ac, av); -} - -IMPORT_TEST_GROUP(mac_cca_threshold); - diff --git a/features/nanostack/sal-stack-nanostack/test/nanostack/unittest/mac/mac_cca_threshold/test_mac_cca_threshold.c b/features/nanostack/sal-stack-nanostack/test/nanostack/unittest/mac/mac_cca_threshold/test_mac_cca_threshold.c deleted file mode 100644 index 5d7f9bffb1..0000000000 --- a/features/nanostack/sal-stack-nanostack/test/nanostack/unittest/mac/mac_cca_threshold/test_mac_cca_threshold.c +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright (c) 2020, Arm Limited and affiliates. - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include "nsconfig.h" -#include "test_mac_cca_threshold.h" -#include "mac_defines.h" -#include "nsdynmemLIB_stub.h" -#include "MAC/IEEE802_15_4/mac_cca_threshold.h" - -static protocol_interface_rf_mac_setup_s setup; - -static void test_free() -{ - if (setup.cca_threshold && setup.cca_threshold->ch_thresholds) { - free(setup.cca_threshold->ch_thresholds); - } - if (setup.cca_threshold) { - free(setup.cca_threshold); - } -} - -static void test_initialize(void) -{ - memset(&setup, 0, sizeof(protocol_interface_rf_mac_setup_s)); -} - -bool test_mac_cca_threshold_update() -{ - uint8_t number_of_channels = 64; - int8_t default_dbm = -60; - int8_t high_limit = -30; - int8_t low_limit = -120; - test_initialize(); - // Initialize CCA threshold - nsdynmemlib_stub.returnCounter = 2; - mac_cca_thr_init(&setup, number_of_channels, default_dbm, high_limit, low_limit); - // Test calling init again - nsdynmemlib_stub.returnCounter = 2; - mac_cca_thr_init(&setup, number_of_channels, default_dbm, high_limit, low_limit); - // Test all channels set to default dBm - for (int i = 0; i < number_of_channels; i++) { - if (mac_cca_thr_get_dbm(&setup, i) != default_dbm) { - return false; - } - } - // Test several CCA fails - for (int i = 0; i < 5; i++) { - mac_cca_threshold_update(&setup, 10, 127); - } - if (mac_cca_thr_get_dbm(&setup, 10) != default_dbm + (5 * CCA_THRESHOLD_STEP)) { - return false; - } - // Test setting to low limit - mac_cca_threshold_update(&setup, 10, -125); - if (mac_cca_thr_get_dbm(&setup, 10) != low_limit) { - return false; - } - mac_cca_threshold_update(&setup, 10, 127); - if (mac_cca_thr_get_dbm(&setup, 10) != (low_limit + CCA_THRESHOLD_STEP)) { - return false; - } - // Test receiving same dBm as low limit - mac_cca_threshold_update(&setup, 10, -120); - if (mac_cca_thr_get_dbm(&setup, 10) != low_limit) { - return false; - } - // Test receiving step above low limit - mac_cca_threshold_update(&setup, 10, -120 + CCA_THRESHOLD_STEP); - if (mac_cca_thr_get_dbm(&setup, 10) != low_limit) { - return false; - } - test_free(); - return true; -} - - -bool test_mac_cca_thr_channel_failed() -{ - uint8_t number_of_channels = 35; - int8_t default_dbm = -31; - int8_t high_limit = -30; - int8_t low_limit = -100; - test_initialize(); - // Initialize CCA threshold - nsdynmemlib_stub.returnCounter = 2; - mac_cca_thr_init(&setup, number_of_channels, default_dbm, high_limit, low_limit); - // Test that default dBm is set - if (setup.cca_threshold->ch_thresholds[10] != default_dbm) { - return false; - } - // Test setting above high limit - if (mac_cca_threshold_update(&setup, 10, 127) || setup.cca_threshold->ch_thresholds[10] != high_limit) { - return false; - } - // Test setting above high limit again - if (!mac_cca_threshold_update(&setup, 10, 127) || setup.cca_threshold->ch_thresholds[10] != high_limit) { - return false; - } - //Set threshold to -65 - CCA_THRESHOLD_STEP - mac_cca_threshold_update(&setup, 10, -65); - // Test setting one step high with CCA fail - if (mac_cca_threshold_update(&setup, 10, 127) || setup.cca_threshold->ch_thresholds[10] != -65) { - return false; - } - test_free(); - return true; -} - -bool test_mac_cca_thr_update_channel_threshold() -{ - uint8_t number_of_channels = 35; - int8_t default_dbm = -50; - int8_t high_limit = -30; - int8_t low_limit = -100; - test_initialize(); - // Initialize CCA threshold - nsdynmemlib_stub.returnCounter = 2; - mac_cca_thr_init(&setup, number_of_channels, default_dbm, high_limit, low_limit); - // Test that default dBm is set - if (setup.cca_threshold->ch_thresholds[10] != default_dbm) { - return false; - } - // Test setting new threshold - if (mac_cca_threshold_update(&setup, 10, -70) || setup.cca_threshold->ch_thresholds[10] != (-70 - CCA_THRESHOLD_STEP)) { - return false; - } - // Test if packet received with higher dBm - if (!mac_cca_threshold_update(&setup, 10, -65) || setup.cca_threshold->ch_thresholds[10] != (-70 - CCA_THRESHOLD_STEP)) { - return false; - } - // Test setting to low limit - if (mac_cca_threshold_update(&setup, 10, -101) || setup.cca_threshold->ch_thresholds[10] != low_limit) { - return false; - } - // Test received lower RSSI than low limit - if (!mac_cca_threshold_update(&setup, 10, -101) || setup.cca_threshold->ch_thresholds[10] != low_limit) { - return false; - } - test_free(); - return true; -} - -bool test_mac_cca_thr_init() -{ - test_initialize(); - // Test default dBm above high limit - if (!mac_cca_thr_init(&setup, 35, -10, -11, -110)) { - return false; - } - // Test default dBm below low limit - if (!mac_cca_thr_init(&setup, 35, -111, -11, -110)) { - return false; - } - // Test high limit below low limit - if (!mac_cca_thr_init(&setup, 35, -50, -110, -11)) { - return false; - } - nsdynmemlib_stub.returnCounter = 0; - // Test allocation failed - if (!mac_cca_thr_init(&setup, 35, -50, -30, -100)) { - return false; - } - nsdynmemlib_stub.returnCounter = 1; - // Test second allocation failed - if (!mac_cca_thr_init(&setup, 35, -50, -30, -100)) { - return false; - } - nsdynmemlib_stub.returnCounter = 2; - // Test success - if (mac_cca_thr_init(&setup, 35, -50, -30, -100)) { - return false; - } - test_free(); - return true; -} diff --git a/features/nanostack/sal-stack-nanostack/test/nanostack/unittest/mac/mac_cca_threshold/test_mac_cca_threshold.h b/features/nanostack/sal-stack-nanostack/test/nanostack/unittest/mac/mac_cca_threshold/test_mac_cca_threshold.h deleted file mode 100644 index 85ca78c556..0000000000 --- a/features/nanostack/sal-stack-nanostack/test/nanostack/unittest/mac/mac_cca_threshold/test_mac_cca_threshold.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2020, Arm Limited and affiliates. - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef TEST_MAC_CCA_THRESHOLD_H -#define TEST_MAC_CCA_THRESHOLD_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -bool test_mac_cca_thr_init(); -bool test_mac_cca_thr_update_channel_threshold(); -bool test_mac_cca_thr_channel_failed(); -bool test_mac_cca_threshold_update(); - -#ifdef __cplusplus -} -#endif - -#endif // TEST_MAC_CCA_THRESHOLD_H - diff --git a/features/nanostack/sal-stack-nanostack/test/nanostack/unittest/stub/mac_cca_threshold_stub.c b/features/nanostack/sal-stack-nanostack/test/nanostack/unittest/stub/mac_cca_threshold_stub.c deleted file mode 100644 index f1c88fb722..0000000000 --- a/features/nanostack/sal-stack-nanostack/test/nanostack/unittest/stub/mac_cca_threshold_stub.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2020, Arm Limited and affiliates. - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "nsconfig.h" -#include -#include "ns_types.h" -#include "ns_list.h" -#include "ns_trace.h" -#include "mac_defines.h" - -int8_t mac_cca_threshold_update(protocol_interface_rf_mac_setup_s *rf_ptr, uint16_t event_data) -{ - return 0; -} - -int8_t mac_cca_thr_deinit(protocol_interface_rf_mac_setup_s *rf_ptr) -{ - return 0; -} - -int8_t mac_cca_thr_init(protocol_interface_rf_mac_setup_s *rf_ptr, uint8_t number_of_channels, int8_t default_dbm, int8_t high_limit, int8_t low_limit) -{ - return 0; -} - -int8_t mac_cca_thr_get_dbm(protocol_interface_rf_mac_setup_s *rf_ptr, uint8_t channel) -{ - return 0; -} diff --git a/features/nanostack/sal-stack-nanostack/test/nanostack/unittest/stub/ns_monitor_stub.h b/features/nanostack/sal-stack-nanostack/test/nanostack/unittest/stub/ns_monitor_stub.h deleted file mode 100644 index f3fdc22c59..0000000000 --- a/features/nanostack/sal-stack-nanostack/test/nanostack/unittest/stub/ns_monitor_stub.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2015-2017, Arm Limited and affiliates. - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef __NS_MONITOR_STUB_H__ -#define __NS_MONITOR_STUB_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct { - bool return_bool; -} ns_monitor_stub_def; - -extern ns_monitor_stub_def ns_monitor_stub; - - -#ifdef __cplusplus -} -#endif - -#endif // __NS_MONITOR_STUB_H__