mbed-os/UNITTESTS/features/lorawan/lorawanstack/Test_LoRaWANStack.cpp

932 lines
27 KiB
C++

/*
* Copyright (c) 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 "gtest/gtest.h"
#include "LoRaWANStack.h"
#include "EventQueue.h"
#include "LoRaPHY_stub.h"
#include "LoRaMac_stub.h"
#include "equeue_stub.h"
#include "lorawan_data_structures.h"
static uint8_t batt_level = 0;
using namespace events;
class my_LoRaPHY : public LoRaPHY {
public:
my_LoRaPHY()
{
};
virtual ~my_LoRaPHY()
{
};
};
uint8_t my_cb()
{
return 1;
}
class my_radio : public LoRaRadio {
public:
radio_events_t *_ev;
virtual void init_radio(radio_events_t *events)
{
_ev = events;
};
virtual void radio_reset()
{
};
virtual void sleep(void)
{
};
virtual void standby(void)
{
};
virtual void set_rx_config(radio_modems_t modem, uint32_t bandwidth,
uint32_t datarate, uint8_t coderate,
uint32_t bandwidth_afc, uint16_t preamble_len,
uint16_t symb_timeout, bool fix_len,
uint8_t payload_len,
bool crc_on, bool freq_hop_on, uint8_t hop_period,
bool iq_inverted, bool rx_continuous)
{
};
virtual void set_tx_config(radio_modems_t modem, int8_t power, uint32_t fdev,
uint32_t bandwidth, uint32_t datarate,
uint8_t coderate, uint16_t preamble_len,
bool fix_len, bool crc_on, bool freq_hop_on,
uint8_t hop_period, bool iq_inverted, uint32_t timeout)
{
};
virtual void send(uint8_t *buffer, uint8_t size)
{
};
virtual void receive(void)
{
};
virtual void set_channel(uint32_t freq)
{
};
virtual uint32_t random(void)
{
};
virtual uint8_t get_status(void)
{
return uint8_value;
};
virtual void set_max_payload_length(radio_modems_t modem, uint8_t max)
{
};
virtual void set_public_network(bool enable)
{
};
virtual uint32_t time_on_air(radio_modems_t modem, uint8_t pkt_len)
{
};
virtual bool perform_carrier_sense(radio_modems_t modem,
uint32_t freq,
int16_t rssi_threshold,
uint32_t max_carrier_sense_time)
{
return bool_value;
};
virtual void start_cad(void)
{
};
virtual bool check_rf_frequency(uint32_t frequency)
{
return bool_value;
};
virtual void set_tx_continuous_wave(uint32_t freq, int8_t power, uint16_t time)
{
};
virtual void lock(void)
{
};
virtual void unlock(void)
{
};
bool bool_value;
uint8_t uint8_value;
};
class Test_LoRaWANStack : public testing::Test {
protected:
LoRaWANStack *object;
virtual void SetUp()
{
LoRaMac_stub::status_value = LORAWAN_STATUS_OK;
object = new LoRaWANStack();
}
virtual void TearDown()
{
delete object;
}
};
TEST_F(Test_LoRaWANStack, constructor)
{
EXPECT_TRUE(object);
}
TEST_F(Test_LoRaWANStack, bind_phy_and_radio_driver)
{
my_radio radio;
my_LoRaPHY phy;
object->bind_phy_and_radio_driver(radio, phy);
}
TEST_F(Test_LoRaWANStack, initialize_mac_layer)
{
EXPECT_TRUE(LORAWAN_STATUS_PARAMETER_INVALID == object->initialize_mac_layer(NULL));
EventQueue queue;
EXPECT_TRUE(LORAWAN_STATUS_OK == object->initialize_mac_layer(&queue));
EXPECT_TRUE(LORAWAN_STATUS_OK == object->initialize_mac_layer(&queue));
//Visit callback
if (LoRaMac_stub::_scheduling_failure_handler) {
LoRaMac_stub::_scheduling_failure_handler.call();
}
}
void events_cb(lorawan_event_t ev)
{
}
void lc_resp(uint8_t a, uint8_t b)
{
}
uint8_t batt_lvl()
{
return batt_level;
}
TEST_F(Test_LoRaWANStack, set_lora_callbacks)
{
lorawan_app_callbacks_t cb;
EXPECT_TRUE(LORAWAN_STATUS_NOT_INITIALIZED == object->set_lora_callbacks(&cb));
EventQueue queue;
EXPECT_TRUE(LORAWAN_STATUS_OK == object->initialize_mac_layer(&queue));
EXPECT_TRUE(LORAWAN_STATUS_PARAMETER_INVALID == object->set_lora_callbacks(NULL));
cb.events = NULL;
EXPECT_TRUE(LORAWAN_STATUS_PARAMETER_INVALID == object->set_lora_callbacks(&cb));
cb.events = events_cb;
cb.link_check_resp = lc_resp;
cb.battery_level = batt_lvl;
EXPECT_TRUE(LORAWAN_STATUS_OK == object->set_lora_callbacks(&cb));
}
TEST_F(Test_LoRaWANStack, connect)
{
EXPECT_TRUE(LORAWAN_STATUS_NOT_INITIALIZED == object->connect());
EventQueue queue;
EXPECT_TRUE(LORAWAN_STATUS_OK == object->initialize_mac_layer(&queue));
LoRaMac_stub::status_value = LORAWAN_STATUS_BUSY;
EXPECT_TRUE(LORAWAN_STATUS_BUSY == object->connect());
LoRaMac_stub::status_value = LORAWAN_STATUS_OK;
EXPECT_TRUE(LORAWAN_STATUS_OK == object->connect());
//_ctrl_flags & CONN_IN_PROGRESS_FLAG
EXPECT_TRUE(LORAWAN_STATUS_BUSY == object->connect());
my_radio radio;
my_LoRaPHY phy;
object->bind_phy_and_radio_driver(radio, phy);
struct equeue_event ptr;
equeue_stub.void_ptr = &ptr;
equeue_stub.call_cb_immediately = true;
loramac_mcps_confirm_t conf;
LoRaMac_stub::mcps_conf_ptr = &conf;
radio._ev->tx_done();
loramac_mcps_indication_t ind;
LoRaMac_stub::mcps_ind_ptr = &ind;
loramac_mlme_confirm_t mlme;
LoRaMac_stub::mlme_conf_ptr = &mlme;
mlme.pending = true;
mlme.req_type = MLME_JOIN;
mlme.status = LORAMAC_EVENT_INFO_STATUS_OK;
LoRaMac_stub::bool_value = false;
radio._ev->rx_done(NULL, 0, 0, 0);
//_ctrl_flags & CONNECTED_FLAG
EXPECT_TRUE(LORAWAN_STATUS_ALREADY_CONNECTED == object->connect());
//Visit rx_interrupt_handler's first if
radio._ev->rx_done(NULL, 65535, 0, 0);
}
TEST_F(Test_LoRaWANStack, connect_args)
{
lorawan_connect_t conn;
EXPECT_TRUE(LORAWAN_STATUS_NOT_INITIALIZED == object->connect(conn));
EventQueue queue;
EXPECT_TRUE(LORAWAN_STATUS_OK == object->initialize_mac_layer(&queue));
conn.connect_type = lorawan_connect_type_t(8);
EXPECT_TRUE(LORAWAN_STATUS_PARAMETER_INVALID == object->connect(conn));
LoRaMac_stub::status_value = LORAWAN_STATUS_BUSY;
conn.connect_type = LORAWAN_CONNECTION_OTAA;
EXPECT_TRUE(LORAWAN_STATUS_BUSY == object->connect(conn));
LoRaMac_stub::status_value = LORAWAN_STATUS_OK;
EXPECT_TRUE(LORAWAN_STATUS_OK == object->connect(conn));
//_ctrl_flags & CONN_IN_PROGRESS_FLAG
EXPECT_TRUE(LORAWAN_STATUS_BUSY == object->connect(conn));
object->shutdown();
conn.connect_type = LORAWAN_CONNECTION_ABP;
EXPECT_TRUE(LORAWAN_STATUS_OK == object->connect(conn));
//_ctrl_flags & CONNECTED_FLAG
EXPECT_TRUE(LORAWAN_STATUS_ALREADY_CONNECTED == object->connect(conn));
}
TEST_F(Test_LoRaWANStack, add_channels)
{
lorawan_channelplan_t plan;
EXPECT_TRUE(LORAWAN_STATUS_NOT_INITIALIZED == object->add_channels(plan));
EventQueue queue;
EXPECT_TRUE(LORAWAN_STATUS_OK == object->initialize_mac_layer(&queue));
LoRaMac_stub::status_value = LORAWAN_STATUS_OK;
EXPECT_TRUE(LORAWAN_STATUS_OK == object->add_channels(plan));
}
TEST_F(Test_LoRaWANStack, remove_a_channel)
{
EXPECT_TRUE(LORAWAN_STATUS_NOT_INITIALIZED == object->remove_a_channel(1));
EventQueue queue;
EXPECT_TRUE(LORAWAN_STATUS_OK == object->initialize_mac_layer(&queue));
LoRaMac_stub::status_value = LORAWAN_STATUS_OK;
EXPECT_TRUE(LORAWAN_STATUS_OK == object->remove_a_channel(1));
}
TEST_F(Test_LoRaWANStack, drop_channel_list)
{
EXPECT_TRUE(LORAWAN_STATUS_NOT_INITIALIZED == object->drop_channel_list());
EventQueue queue;
EXPECT_TRUE(LORAWAN_STATUS_OK == object->initialize_mac_layer(&queue));
LoRaMac_stub::status_value = LORAWAN_STATUS_OK;
EXPECT_TRUE(LORAWAN_STATUS_OK == object->drop_channel_list());
}
TEST_F(Test_LoRaWANStack, get_enabled_channels)
{
lorawan_channelplan_t plan;
EXPECT_TRUE(LORAWAN_STATUS_NOT_INITIALIZED == object->get_enabled_channels(plan));
EventQueue queue;
EXPECT_TRUE(LORAWAN_STATUS_OK == object->initialize_mac_layer(&queue));
LoRaMac_stub::status_value = LORAWAN_STATUS_OK;
EXPECT_TRUE(LORAWAN_STATUS_OK == object->get_enabled_channels(plan));
}
TEST_F(Test_LoRaWANStack, set_confirmed_msg_retry)
{
EXPECT_TRUE(LORAWAN_STATUS_NOT_INITIALIZED == object->set_confirmed_msg_retry(1));
EventQueue queue;
EXPECT_TRUE(LORAWAN_STATUS_OK == object->initialize_mac_layer(&queue));
EXPECT_TRUE(LORAWAN_STATUS_PARAMETER_INVALID == object->set_confirmed_msg_retry(255));
LoRaMac_stub::status_value = LORAWAN_STATUS_OK;
EXPECT_TRUE(LORAWAN_STATUS_OK == object->set_confirmed_msg_retry(1));
}
TEST_F(Test_LoRaWANStack, set_channel_data_rate)
{
EXPECT_TRUE(LORAWAN_STATUS_NOT_INITIALIZED == object->set_channel_data_rate(4));
EventQueue queue;
EXPECT_TRUE(LORAWAN_STATUS_OK == object->initialize_mac_layer(&queue));
LoRaMac_stub::status_value = LORAWAN_STATUS_OK;
EXPECT_TRUE(LORAWAN_STATUS_OK == object->set_channel_data_rate(4));
}
TEST_F(Test_LoRaWANStack, enable_adaptive_datarate)
{
EXPECT_TRUE(LORAWAN_STATUS_NOT_INITIALIZED == object->enable_adaptive_datarate(false));
EventQueue queue;
EXPECT_TRUE(LORAWAN_STATUS_OK == object->initialize_mac_layer(&queue));
LoRaMac_stub::status_value = LORAWAN_STATUS_OK;
EXPECT_TRUE(LORAWAN_STATUS_OK == object->enable_adaptive_datarate(false));
}
TEST_F(Test_LoRaWANStack, handle_tx)
{
EXPECT_TRUE(LORAWAN_STATUS_NOT_INITIALIZED == object->handle_tx(0, NULL, 0, 0, true, false));
EventQueue queue;
EXPECT_TRUE(LORAWAN_STATUS_OK == object->initialize_mac_layer(&queue));
LoRaMac_stub::status_value = LORAWAN_STATUS_OK;
EXPECT_TRUE(LORAWAN_STATUS_PARAMETER_INVALID == object->handle_tx(0, NULL, 0, 0, false, false));
lorawan_app_callbacks_t cb;
cb.events = events_cb;
cb.link_check_resp = lc_resp;
cb.battery_level = batt_lvl;
struct equeue_event ptr;
equeue_stub.void_ptr = &ptr;
equeue_stub.call_cb_immediately = true;
EXPECT_TRUE(LORAWAN_STATUS_OK == object->set_lora_callbacks(&cb));
EXPECT_TRUE(LORAWAN_STATUS_OK == object->set_link_check_request());
LoRaMac_stub::status_value = LORAWAN_STATUS_OK;
EXPECT_TRUE(LORAWAN_STATUS_NO_ACTIVE_SESSIONS == object->handle_tx(0, NULL, 0, 0, true, false));
lorawan_connect_t conn;
conn.connect_type = LORAWAN_CONNECTION_ABP;
EXPECT_TRUE(LORAWAN_STATUS_OK == object->connect(conn));
LoRaMac_stub::bool_value = false;
EXPECT_TRUE(LORAWAN_STATUS_NO_NETWORK_JOINED == object->handle_tx(0, NULL, 0, 0, true, false));
LoRaMac_stub::bool_value = true;
EXPECT_TRUE(LORAWAN_STATUS_WOULD_BLOCK == object->handle_tx(0, NULL, 0, 0, true, false));
LoRaMac_stub::bool_false_counter = 1;
LoRaMac_stub::bool_value = true;
//set_application_port fails
EXPECT_TRUE(LORAWAN_STATUS_PORT_INVALID == object->handle_tx(0, NULL, 0, 0, true, false));
LoRaMac_stub::bool_false_counter = 1;
LoRaMac_stub::bool_value = true;
//Wrong flags -> LORAWAN_STATUS_PARAMETER_INVALID
EXPECT_TRUE(LORAWAN_STATUS_PARAMETER_INVALID == object->handle_tx(1, NULL, 0, 0x04, true, false));
LoRaMac_stub::bool_false_counter = 1;
//Actual sending
EXPECT_TRUE(LORAWAN_STATUS_OK == object->handle_tx(1, NULL, 0, 0x08, true, false));
}
TEST_F(Test_LoRaWANStack, handle_rx)
{
uint8_t port;
int flags;
EXPECT_TRUE(LORAWAN_STATUS_NOT_INITIALIZED == object->handle_rx(NULL, 0, port, flags, false));
EventQueue queue;
EXPECT_TRUE(LORAWAN_STATUS_OK == object->initialize_mac_layer(&queue));
LoRaMac_stub::status_value = LORAWAN_STATUS_OK;
EXPECT_TRUE(LORAWAN_STATUS_NO_ACTIVE_SESSIONS == object->handle_rx(NULL, 0, port, flags, false));
struct equeue_event ptr;
equeue_stub.void_ptr = &ptr;
equeue_stub.call_cb_immediately = true;
lorawan_connect_t conn;
conn.connect_type = LORAWAN_CONNECTION_ABP;
EXPECT_TRUE(LORAWAN_STATUS_OK == object->connect(conn));
EXPECT_TRUE(LORAWAN_STATUS_WOULD_BLOCK == object->handle_rx(NULL, 0, port, flags, false));
//Prepare ready for receive state
lorawan_app_callbacks_t cb;
cb.events = events_cb;
cb.link_check_resp = lc_resp;
cb.battery_level = batt_lvl;
EXPECT_TRUE(LORAWAN_STATUS_OK == object->set_lora_callbacks(&cb));
my_radio radio;
my_LoRaPHY phy;
object->bind_phy_and_radio_driver(radio, phy);
loramac_mcps_confirm_t conf;
conf.status = LORAMAC_EVENT_INFO_STATUS_OK;
LoRaMac_stub::mcps_conf_ptr = &conf;
radio._ev->tx_done();
loramac_mcps_indication_t ind;
ind.status = LORAMAC_EVENT_INFO_STATUS_OK;
LoRaMac_stub::mcps_ind_ptr = &ind;
loramac_mlme_confirm_t mlme;
LoRaMac_stub::mlme_conf_ptr = &mlme;
mlme.pending = false;
mlme.req_type = MLME_JOIN;
mlme.status = LORAMAC_EVENT_INFO_STATUS_OK;
LoRaMac_stub::bool_value = true;
conf.req_type = MCPS_PROPRIETARY;
ind.pending = true;
LoRaMac_stub::dev_class_value = CLASS_A;
loramac_mlme_indication_t mlme_ind;
mlme_ind.pending = false;
LoRaMac_stub::mlme_ind_ptr = &mlme_ind;
uint8_t ind_buf[150];
for (int i = 0; i < 110; i++) {
ind_buf[i] = i;
}
ind.buffer = ind_buf;
ind.buffer_size = 150;
ind.type = MCPS_UNCONFIRMED;
ind.port = 15;
ind.is_data_recvd = true;
ind.fpending_status = false;
LoRaMac_stub::dev_class_value = CLASS_A;
radio._ev->rx_done(NULL, 0, 0, 0);
//data == NULL || LENGTH == 0 (2 cases)
EXPECT_TRUE(LORAWAN_STATUS_PARAMETER_INVALID == object->handle_rx(NULL, 0, port, flags, false));
uint8_t data[50];
EXPECT_TRUE(LORAWAN_STATUS_PARAMETER_INVALID == object->handle_rx(data, 0, port, flags, false));
//validate_params returns Would block
port = 43;
EXPECT_TRUE(LORAWAN_STATUS_WOULD_BLOCK == object->handle_rx(data, 50, port, flags, true));
ind.type = MCPS_CONFIRMED;
radio._ev->rx_done(NULL, 0, 0, 0);
EXPECT_TRUE(LORAWAN_STATUS_WOULD_BLOCK == object->handle_rx(data, 50, port, flags, true));
//Call again to visit send_automatic_uplink_message error case
LoRaMac_stub::bool_true_counter = 1;
ind.type = MCPS_CONFIRMED;
ind.status = LORAMAC_EVENT_INFO_STATUS_ERROR;
LoRaMac_stub::bool_value = false;
radio._ev->rx_done(NULL, 0, 0, 0);
ind.status = LORAMAC_EVENT_INFO_STATUS_OK;
LoRaMac_stub::bool_value = true;
//convert_to_msg_flag cases
ind.fpending_status = true;
ind.type = MCPS_PROPRIETARY;
radio._ev->rx_done(NULL, 0, 0, 0);
EXPECT_TRUE(LORAWAN_STATUS_WOULD_BLOCK == object->handle_rx(data, 50, port, flags, true));
ind.type = MCPS_MULTICAST;
radio._ev->rx_done(NULL, 0, 0, 0);
EXPECT_TRUE(LORAWAN_STATUS_WOULD_BLOCK == object->handle_rx(data, 50, port, flags, true));
ind.type = MCPS_UNCONFIRMED;
radio._ev->rx_done(NULL, 0, 0, 0);
//read not complete
EXPECT_TRUE(50 == object->handle_rx(data, 50, port, flags, false));
EXPECT_EQ(10, data[10]);
EXPECT_TRUE(50 == object->handle_rx(data, 50, port, flags, false));
EXPECT_EQ(60, data[10]);
//read complete
EXPECT_TRUE(50 == object->handle_rx(data, 50, port, flags, false));
EXPECT_EQ(100, data[0]);
//read can fit the buffer
for (int i = 0; i < 110; i++) {
ind_buf[i] = i;
}
ind.buffer = ind_buf;
ind.buffer_size = 50;
ind.type = mcps_type_t(66);
radio._ev->rx_done(NULL, 0, 0, 0);
EXPECT_TRUE(50 == object->handle_rx(data, 50, port, flags, false));
EXPECT_EQ(10, data[10]);
}
TEST_F(Test_LoRaWANStack, set_link_check_request)
{
EXPECT_TRUE(LORAWAN_STATUS_NOT_INITIALIZED == object->set_link_check_request());
EventQueue queue;
EXPECT_TRUE(LORAWAN_STATUS_OK == object->initialize_mac_layer(&queue));
LoRaMac_stub::status_value = LORAWAN_STATUS_OK;
EXPECT_TRUE(LORAWAN_STATUS_PARAMETER_INVALID == object->set_link_check_request());
lorawan_app_callbacks_t cb;
cb.events = events_cb;
cb.link_check_resp = lc_resp;
cb.battery_level = batt_lvl;
EXPECT_TRUE(LORAWAN_STATUS_OK == object->set_lora_callbacks(&cb));
EXPECT_TRUE(LORAWAN_STATUS_OK == object->set_link_check_request());
}
TEST_F(Test_LoRaWANStack, remove_link_check_request)
{
object->remove_link_check_request();
}
TEST_F(Test_LoRaWANStack, shutdown)
{
EXPECT_TRUE(LORAWAN_STATUS_NOT_INITIALIZED == object->shutdown());
EventQueue queue;
EXPECT_TRUE(LORAWAN_STATUS_OK == object->initialize_mac_layer(&queue));
EXPECT_TRUE(LORAWAN_STATUS_DEVICE_OFF == object->shutdown());
}
TEST_F(Test_LoRaWANStack, set_device_class)
{
EXPECT_TRUE(LORAWAN_STATUS_NOT_INITIALIZED == object->set_device_class(CLASS_A));
EventQueue queue;
EXPECT_TRUE(LORAWAN_STATUS_OK == object->initialize_mac_layer(&queue));
LoRaMac_stub::status_value = LORAWAN_STATUS_OK;
EXPECT_TRUE(LORAWAN_STATUS_UNSUPPORTED == object->set_device_class(CLASS_B));
EXPECT_TRUE(LORAWAN_STATUS_OK == object->set_device_class(CLASS_A));
}
TEST_F(Test_LoRaWANStack, acquire_tx_metadata)
{
lorawan_tx_metadata data;
memset(&data, 0, sizeof(data));
EXPECT_TRUE(LORAWAN_STATUS_NOT_INITIALIZED == object->acquire_tx_metadata(data));
EventQueue queue;
EXPECT_TRUE(LORAWAN_STATUS_OK == object->initialize_mac_layer(&queue));
LoRaMac_stub::status_value = LORAWAN_STATUS_OK;
// stale = true;
EXPECT_TRUE(LORAWAN_STATUS_METADATA_NOT_AVAILABLE == object->acquire_tx_metadata(data));
// stale = false;
my_radio radio;
my_LoRaPHY phy;
object->bind_phy_and_radio_driver(radio, phy);
struct equeue_event ptr;
equeue_stub.void_ptr = &ptr;
equeue_stub.call_cb_immediately = true;
loramac_mcps_confirm_t conf;
memset(&conf, 0, sizeof(conf));
conf.status = LORAMAC_EVENT_INFO_STATUS_OK;
LoRaMac_stub::mcps_conf_ptr = &conf;
radio._ev->tx_done();
LoRaMac_stub::slot_value = RX_SLOT_WIN_2;
radio._ev->rx_timeout();
EXPECT_TRUE(LORAWAN_STATUS_OK == object->acquire_tx_metadata(data));
}
TEST_F(Test_LoRaWANStack, acquire_rx_metadata)
{
lorawan_rx_metadata data;
memset(&data, 0, sizeof(data));
EXPECT_TRUE(LORAWAN_STATUS_NOT_INITIALIZED == object->acquire_rx_metadata(data));
EventQueue queue;
EXPECT_TRUE(LORAWAN_STATUS_OK == object->initialize_mac_layer(&queue));
LoRaMac_stub::status_value = LORAWAN_STATUS_OK;
// stale = true;
EXPECT_TRUE(LORAWAN_STATUS_METADATA_NOT_AVAILABLE == object->acquire_rx_metadata(data));
// stale = false;
my_radio radio;
my_LoRaPHY phy;
object->bind_phy_and_radio_driver(radio, phy);
struct equeue_event ptr;
equeue_stub.void_ptr = &ptr;
equeue_stub.call_cb_immediately = true;
loramac_mcps_confirm_t conf;
memset(&conf, 0, sizeof(conf));
conf.status = LORAMAC_EVENT_INFO_STATUS_OK;
LoRaMac_stub::mcps_conf_ptr = &conf;
radio._ev->tx_done();
loramac_mcps_indication_t ind;
memset(&ind, 0, sizeof(ind));
ind.status = LORAMAC_EVENT_INFO_STATUS_OK;
LoRaMac_stub::mcps_ind_ptr = &ind;
loramac_mlme_confirm_t mlme;
mlme.status = LORAMAC_EVENT_INFO_STATUS_OK;
LoRaMac_stub::mlme_conf_ptr = &mlme;
mlme.pending = true;
mlme.req_type = MLME_JOIN;
//Visit mlme_confirm_handler here also
mlme.status = LORAMAC_EVENT_INFO_STATUS_CRYPTO_FAIL;
LoRaMac_stub::bool_value = false;
radio._ev->rx_done(NULL, 0, 0, 0);
mlme.status = LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT;
radio._ev->rx_done(NULL, 0, 0, 0);
mlme.status = LORAMAC_EVENT_INFO_STATUS_RX1_TIMEOUT;
LoRaMac_stub::slot_value = RX_SLOT_WIN_2;
radio._ev->rx_done(NULL, 0, 0, 0);
lorawan_app_callbacks_t cb;
cb.events = events_cb;
cb.link_check_resp = lc_resp;
cb.battery_level = batt_lvl;
EXPECT_TRUE(LORAWAN_STATUS_OK == object->set_lora_callbacks(&cb));
mlme.req_type = MLME_LINK_CHECK;
mlme.status = LORAMAC_EVENT_INFO_STATUS_OK;
LoRaMac_stub::bool_true_counter = true;
radio._ev->rx_done(NULL, 0, 0, 0);
EXPECT_TRUE(LORAWAN_STATUS_OK == object->acquire_rx_metadata(data));
}
TEST_F(Test_LoRaWANStack, acquire_backoff_metadata)
{
int b;
EXPECT_TRUE(LORAWAN_STATUS_NOT_INITIALIZED == object->acquire_backoff_metadata(b));
EventQueue queue;
EXPECT_TRUE(LORAWAN_STATUS_OK == object->initialize_mac_layer(&queue));
LoRaMac_stub::int_value = 2;
EXPECT_TRUE(LORAWAN_STATUS_OK == object->acquire_backoff_metadata(b));
LoRaMac_stub::int_value = 0;
EXPECT_TRUE(LORAWAN_STATUS_METADATA_NOT_AVAILABLE == object->acquire_backoff_metadata(b));
}
TEST_F(Test_LoRaWANStack, stop_sending)
{
EXPECT_TRUE(LORAWAN_STATUS_NOT_INITIALIZED == object->stop_sending());
EventQueue queue;
EXPECT_TRUE(LORAWAN_STATUS_OK == object->initialize_mac_layer(&queue));
LoRaMac_stub::status_value = LORAWAN_STATUS_BUSY;
EXPECT_TRUE(LORAWAN_STATUS_BUSY == object->stop_sending());
LoRaMac_stub::status_value = LORAWAN_STATUS_OK;
EXPECT_TRUE(LORAWAN_STATUS_OK == object->stop_sending());
}
TEST_F(Test_LoRaWANStack, lock)
{
object->lock();
}
TEST_F(Test_LoRaWANStack, unlock)
{
object->unlock();
}
TEST_F(Test_LoRaWANStack, interrupt_functions)
{
lorawan_connect_t conn;
EventQueue queue;
EXPECT_TRUE(LORAWAN_STATUS_OK == object->initialize_mac_layer(&queue));
my_radio radio;
my_LoRaPHY phy;
object->bind_phy_and_radio_driver(radio, phy);
struct equeue_event ptr;
equeue_stub.void_ptr = &ptr;
equeue_stub.call_cb_immediately = true;
loramac_mcps_confirm_t conf;
LoRaMac_stub::mcps_conf_ptr = &conf;
radio._ev->tx_done();
loramac_mcps_indication_t ind;
LoRaMac_stub::mcps_ind_ptr = &ind;
loramac_mlme_confirm_t mlme;
LoRaMac_stub::mlme_conf_ptr = &mlme;
mlme.pending = true;
mlme.req_type = MLME_JOIN;
mlme.status = LORAMAC_EVENT_INFO_STATUS_OK;
LoRaMac_stub::bool_value = false;
radio._ev->rx_done(NULL, 0, 0, 0);
radio._ev->rx_done(NULL, 0, 0, 0);
radio._ev->rx_error();
LoRaMac_stub::slot_value = RX_SLOT_WIN_2;
radio._ev->rx_error();
conf.req_type = MCPS_UNCONFIRMED;
LoRaMac_stub::bool_value = true;
radio._ev->rx_error();
conf.req_type = MCPS_CONFIRMED;
radio._ev->rx_error();
LoRaMac_stub::bool_value = false;
LoRaMac_stub::slot_value = RX_SLOT_WIN_1;
radio._ev->rx_timeout();
radio._ev->tx_timeout();
object->shutdown();
conn.connect_type = LORAWAN_CONNECTION_OTAA;
object->connect(conn);
LoRaMac_stub::status_value = LORAWAN_STATUS_OK;
object->connect(conn);
radio._ev->tx_timeout();
}
TEST_F(Test_LoRaWANStack, process_transmission)
{
EventQueue queue;
EXPECT_TRUE(LORAWAN_STATUS_OK == object->initialize_mac_layer(&queue));
lorawan_app_callbacks_t cb;
cb.events = events_cb;
cb.link_check_resp = lc_resp;
cb.battery_level = batt_lvl;
EXPECT_TRUE(LORAWAN_STATUS_OK == object->set_lora_callbacks(&cb));
my_radio radio;
my_LoRaPHY phy;
object->bind_phy_and_radio_driver(radio, phy);
object->connect();
struct equeue_event ptr;
equeue_stub.void_ptr = &ptr;
equeue_stub.call_cb_immediately = true;
loramac_mcps_confirm_t conf;
LoRaMac_stub::mcps_conf_ptr = &conf;
radio._ev->tx_done();
loramac_mcps_indication_t ind;
LoRaMac_stub::mcps_ind_ptr = &ind;
loramac_mlme_confirm_t mlme;
LoRaMac_stub::mlme_conf_ptr = &mlme;
mlme.pending = true;
mlme.req_type = MLME_JOIN;
mlme.status = LORAMAC_EVENT_INFO_STATUS_OK;
LoRaMac_stub::bool_value = false;
radio._ev->rx_done(NULL, 0, 0, 0);
LoRaMac_stub::bool_value = true;
conf.req_type = MCPS_PROPRIETARY;
LoRaMac_stub::bool_false_counter = 1;
LoRaMac_stub::dev_class_value = CLASS_A;
object->handle_tx(1, NULL, 0, MSG_UNCONFIRMED_FLAG, true, false);
radio._ev->tx_done();
LoRaMac_stub::bool_false_counter = 1;
LoRaMac_stub::dev_class_value = CLASS_A;
object->handle_tx(1, NULL, 0, MSG_UNCONFIRMED_FLAG, true, false);
radio._ev->tx_done();
LoRaMac_stub::bool_false_counter = 1;
LoRaMac_stub::dev_class_value = CLASS_C;
object->handle_tx(1, NULL, 0, MSG_UNCONFIRMED_FLAG, true, false);
radio._ev->tx_done();
LoRaMac_stub::bool_false_counter = 1;
conf.req_type = MCPS_CONFIRMED;
object->handle_tx(1, NULL, 0, MSG_UNCONFIRMED_FLAG, true, false);
radio._ev->tx_done();
}
TEST_F(Test_LoRaWANStack, process_reception)
{
EventQueue queue;
EXPECT_TRUE(LORAWAN_STATUS_OK == object->initialize_mac_layer(&queue));
//Prepare ready for receive state
lorawan_app_callbacks_t cb;
cb.events = events_cb;
cb.link_check_resp = lc_resp;
cb.battery_level = batt_lvl;
EXPECT_TRUE(LORAWAN_STATUS_OK == object->set_lora_callbacks(&cb));
my_radio radio;
my_LoRaPHY phy;
object->bind_phy_and_radio_driver(radio, phy);
struct equeue_event ptr;
equeue_stub.void_ptr = &ptr;
equeue_stub.call_cb_immediately = true;
loramac_mcps_confirm_t conf;
memset(&conf, 0, sizeof(&conf));
LoRaMac_stub::mcps_conf_ptr = &conf;
radio._ev->tx_done();
loramac_mcps_indication_t ind;
memset(&ind, 0, sizeof(ind));
LoRaMac_stub::mcps_ind_ptr = &ind;
loramac_mlme_confirm_t mlme;
LoRaMac_stub::mlme_conf_ptr = &mlme;
mlme.pending = false;
mlme.req_type = MLME_JOIN;
mlme.status = LORAMAC_EVENT_INFO_STATUS_OK;
LoRaMac_stub::bool_value = true;
conf.req_type = MCPS_PROPRIETARY;
ind.pending = true;
LoRaMac_stub::dev_class_value = CLASS_C;
loramac_mlme_indication_t mlme_ind;
mlme_ind.pending = false;
LoRaMac_stub::mlme_ind_ptr = &mlme_ind;
uint8_t ind_buf[150];
for (int i = 0; i < 110; i++) {
ind_buf[i] = i;
}
ind.buffer = ind_buf;
ind.buffer_size = 150;
//_loramac.get_mcps_confirmation()->req_type == MCPS_CONFIRMED
conf.req_type = MCPS_CONFIRMED;
conf.status = LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT;
radio._ev->rx_done(NULL, 0, 0, 0);
ind.is_ack_recvd = false;
LoRaMac_stub::bool_true_counter = 1;
LoRaMac_stub::bool_value = false;
LoRaMac_stub::slot_value = RX_SLOT_WIN_2;
conf.status = LORAMAC_EVENT_INFO_STATUS_TX_DR_PAYLOAD_SIZE_ERROR;
radio._ev->rx_done(NULL, 0, 0, 0);
conf.req_type = MCPS_UNCONFIRMED;
LoRaMac_stub::dev_class_value = CLASS_A;
LoRaMac_stub::bool_true_counter++;
mlme_ind.pending = true;
mlme_ind.indication_type = MLME_SCHEDULE_UPLINK;
conf.status = LORAMAC_EVENT_INFO_STATUS_ERROR;
radio._ev->rx_done(NULL, 0, 0, 0);
ind.is_ack_recvd = true;
conf.req_type = MCPS_CONFIRMED;
conf.status = LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT;
radio._ev->rx_done(NULL, 0, 0, 0);
}