mirror of https://github.com/ARMmbed/mbed-os.git
Merge pull request #13079 from artokin/nanostack_release_12_3_0
[feature-wisun] Nanostack release v12.3.0pull/13124/head
commit
72fa02d92b
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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/).
|
||||
|
||||

|
||||
|
||||
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
|
||||
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 9.9 KiB |
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
/**
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 */
|
||||
};
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
@ -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());
|
||||
}
|
|
@ -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);
|
||||
|
|
@ -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;
|
||||
}
|
|
@ -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 <stdbool.h>
|
||||
|
||||
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
|
||||
|
|
@ -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 <string.h>
|
||||
#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;
|
||||
}
|
|
@ -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__
|
Loading…
Reference in New Issue