2021-04-04 22:15:46 +02:00
|
|
|
#define CATCH_CONFIG_MAIN // This tells the catch header to generate a main
|
|
|
|
#include <memory>
|
|
|
|
#include <future>
|
|
|
|
#include "catch.hpp"
|
|
|
|
#include "cxx_include/esp_modem_api.hpp"
|
2021-05-13 07:28:05 +02:00
|
|
|
#include "LoopbackTerm.h"
|
2021-04-04 22:15:46 +02:00
|
|
|
|
|
|
|
using namespace esp_modem;
|
|
|
|
|
2022-02-23 11:00:05 +01:00
|
|
|
TEST_CASE("Test polymorphic delete for custom device/dte", "[esp_modem]")
|
|
|
|
{
|
|
|
|
auto term = std::make_unique<LoopbackTerm>(true);
|
|
|
|
auto dte = std::make_shared<DTE>(std::move(term));
|
|
|
|
CHECK(term == nullptr);
|
|
|
|
esp_modem_dce_config_t dce_config = ESP_MODEM_DCE_DEFAULT_CONFIG("APN");
|
|
|
|
|
|
|
|
// Create custom device and DTE manually to check for a potential undefined behaviour
|
|
|
|
auto device = new GenericModule(std::move(dte), &dce_config);
|
|
|
|
device->power_down();
|
|
|
|
delete device;
|
|
|
|
auto custom_dte = new DTE(std::make_unique<LoopbackTerm>(false));
|
|
|
|
custom_dte->command("AT", nullptr, 0);
|
|
|
|
delete custom_dte;
|
|
|
|
}
|
|
|
|
|
2021-05-13 07:28:05 +02:00
|
|
|
TEST_CASE("DCE AT parser", "[esp_modem]")
|
|
|
|
{
|
|
|
|
auto term = std::make_unique<LoopbackTerm>(true);
|
|
|
|
auto dte = std::make_shared<DTE>(std::move(term));
|
|
|
|
CHECK(term == nullptr);
|
|
|
|
esp_modem_dce_config_t dce_config = ESP_MODEM_DCE_DEFAULT_CONFIG("APN");
|
|
|
|
esp_netif_t netif{};
|
|
|
|
auto dce = create_BG96_dce(&dce_config, dte, &netif);
|
|
|
|
CHECK(dce != nullptr);
|
|
|
|
|
|
|
|
CHECK(dce->set_command_mode() == command_result::OK);
|
|
|
|
|
|
|
|
int milli_volt, bcl, bcs;
|
|
|
|
CHECK(dce->get_battery_status(milli_volt, bcl, bcs) == command_result::OK);
|
|
|
|
CHECK(milli_volt == 123456);
|
|
|
|
CHECK(bcl == 1);
|
2021-12-06 11:16:38 +01:00
|
|
|
CHECK(bcs == 20);
|
2021-05-13 07:28:05 +02:00
|
|
|
|
|
|
|
int rssi, ber;
|
|
|
|
CHECK(dce->get_signal_quality(rssi, ber) == command_result::OK);
|
|
|
|
CHECK(rssi == 123);
|
|
|
|
CHECK(ber == 456);
|
|
|
|
|
|
|
|
bool pin_ok;
|
|
|
|
CHECK(dce->read_pin(pin_ok) == command_result::OK);
|
|
|
|
CHECK(pin_ok == false);
|
|
|
|
CHECK(dce->set_pin("1234") == command_result::OK);
|
|
|
|
CHECK(dce->read_pin(pin_ok) == command_result::OK);
|
|
|
|
CHECK(pin_ok == true);
|
2021-11-25 16:24:49 +01:00
|
|
|
|
|
|
|
std::string model;
|
|
|
|
CHECK(dce->get_module_name(model) == command_result::OK);
|
|
|
|
CHECK(model == "0G Dummy Model");
|
2021-05-13 07:28:05 +02:00
|
|
|
}
|
|
|
|
|
2021-04-04 22:15:46 +02:00
|
|
|
|
|
|
|
TEST_CASE("DTE send/receive command", "[esp_modem]")
|
|
|
|
{
|
|
|
|
auto term = std::make_unique<LoopbackTerm>();
|
|
|
|
auto dte = std::make_unique<DTE>(std::move(term));
|
|
|
|
|
|
|
|
const auto test_command = "Test\n";
|
|
|
|
CHECK(term == nullptr);
|
|
|
|
|
2021-04-19 11:28:53 +02:00
|
|
|
CHECK(dte->set_mode(esp_modem::modem_mode::COMMAND_MODE) == true);
|
2021-04-04 22:15:46 +02:00
|
|
|
|
|
|
|
auto ret = dte->command(test_command, [&](uint8_t *data, size_t len) {
|
2021-06-01 10:21:51 +02:00
|
|
|
std::string response((char *)data, len);
|
2021-04-04 22:15:46 +02:00
|
|
|
CHECK(response == test_command);
|
|
|
|
return command_result::OK;
|
|
|
|
}, 1000);
|
|
|
|
CHECK(ret == command_result::OK);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_CASE("DCE commands", "[esp_modem]")
|
|
|
|
{
|
|
|
|
auto term = std::make_unique<LoopbackTerm>();
|
|
|
|
auto dte = std::make_shared<DTE>(std::move(term));
|
|
|
|
CHECK(term == nullptr);
|
|
|
|
|
|
|
|
esp_modem_dce_config_t dce_config = ESP_MODEM_DCE_DEFAULT_CONFIG("APN");
|
|
|
|
esp_netif_t netif{};
|
|
|
|
auto dce = create_SIM7600_dce(&dce_config, dte, &netif);
|
|
|
|
CHECK(dce != nullptr);
|
|
|
|
|
|
|
|
const auto test_command = "Test\n";
|
|
|
|
auto ret = dce->command(test_command, [&](uint8_t *data, size_t len) {
|
2021-06-01 10:21:51 +02:00
|
|
|
std::string response((char *)data, len);
|
2021-04-04 22:15:46 +02:00
|
|
|
CHECK(response == test_command);
|
|
|
|
return command_result::OK;
|
|
|
|
}, 1000);
|
|
|
|
CHECK(ret == command_result::OK);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_CASE("DCE AT commands", "[esp_modem]")
|
|
|
|
{
|
|
|
|
auto term = std::make_unique<LoopbackTerm>();
|
|
|
|
auto dte = std::make_shared<DTE>(std::move(term));
|
|
|
|
CHECK(term == nullptr);
|
|
|
|
|
|
|
|
esp_modem_dce_config_t dce_config = ESP_MODEM_DCE_DEFAULT_CONFIG("APN");
|
|
|
|
esp_netif_t netif{};
|
|
|
|
auto dce = create_SIM7600_dce(&dce_config, dte, &netif);
|
|
|
|
CHECK(dce != nullptr);
|
|
|
|
|
2021-05-13 07:28:05 +02:00
|
|
|
int milli_volt, bcl, bcs;
|
2021-04-04 22:15:46 +02:00
|
|
|
CHECK(dce->set_echo(false) == command_result::OK);
|
|
|
|
CHECK(dce->set_echo(true) == command_result::OK);
|
2021-05-13 07:28:05 +02:00
|
|
|
CHECK(dce->get_battery_status(milli_volt, bcl, bcs) == command_result::OK);
|
|
|
|
CHECK(milli_volt == 123456);
|
2021-04-04 22:15:46 +02:00
|
|
|
CHECK(dce->resume_data_mode() == command_result::FAIL);
|
|
|
|
}
|
|
|
|
|
2021-05-13 07:28:05 +02:00
|
|
|
|
2021-04-04 22:15:46 +02:00
|
|
|
TEST_CASE("DCE modes", "[esp_modem]")
|
|
|
|
{
|
|
|
|
auto term = std::make_unique<LoopbackTerm>();
|
|
|
|
auto dte = std::make_shared<DTE>(std::move(term));
|
|
|
|
CHECK(term == nullptr);
|
|
|
|
|
|
|
|
esp_modem_dce_config_t dce_config = ESP_MODEM_DCE_DEFAULT_CONFIG("APN");
|
|
|
|
esp_netif_t netif{};
|
|
|
|
auto dce = create_SIM7600_dce(&dce_config, dte, &netif);
|
|
|
|
CHECK(dce != nullptr);
|
|
|
|
|
2022-05-24 14:53:11 +02:00
|
|
|
CHECK(dce->set_mode(esp_modem::modem_mode::COMMAND_MODE) == true);
|
2021-04-04 22:15:46 +02:00
|
|
|
CHECK(dce->set_mode(esp_modem::modem_mode::COMMAND_MODE) == false);
|
|
|
|
CHECK(dce->set_mode(esp_modem::modem_mode::DATA_MODE) == true);
|
|
|
|
CHECK(dce->set_mode(esp_modem::modem_mode::COMMAND_MODE) == true);
|
|
|
|
}
|
2021-04-07 09:51:41 +02:00
|
|
|
|
2021-06-01 10:21:51 +02:00
|
|
|
TEST_CASE("DCE CMUX test", "[esp_modem]")
|
|
|
|
{
|
2021-04-07 09:51:41 +02:00
|
|
|
auto term = std::make_unique<LoopbackTerm>();
|
|
|
|
auto dte = std::make_shared<DTE>(std::move(term));
|
|
|
|
CHECK(term == nullptr);
|
|
|
|
|
|
|
|
esp_modem_dce_config_t dce_config = ESP_MODEM_DCE_DEFAULT_CONFIG("APN");
|
|
|
|
esp_netif_t netif{};
|
|
|
|
auto dce = create_SIM7600_dce(&dce_config, dte, &netif);
|
|
|
|
CHECK(dce != nullptr);
|
|
|
|
|
|
|
|
CHECK(dce->set_mode(esp_modem::modem_mode::CMUX_MODE) == true);
|
|
|
|
const auto test_command = "Test\n";
|
|
|
|
auto ret = dce->command(test_command, [&](uint8_t *data, size_t len) {
|
|
|
|
std::string response((char *) data, len);
|
2021-05-13 07:28:05 +02:00
|
|
|
std::cout << "Response:" << response << std::endl;
|
2021-04-07 09:51:41 +02:00
|
|
|
CHECK(response == test_command);
|
|
|
|
return command_result::OK;
|
|
|
|
}, 1000);
|
|
|
|
CHECK(ret == command_result::OK);
|
2021-05-13 07:28:05 +02:00
|
|
|
}
|
2022-06-06 15:05:38 +02:00
|
|
|
|
|
|
|
TEST_CASE("Test CMUX protocol by injecting payloads", "[esp_modem]")
|
|
|
|
{
|
|
|
|
auto term = std::make_unique<LoopbackTerm>();
|
|
|
|
auto loopback = term.get();
|
|
|
|
auto dte = std::make_shared<DTE>(std::move(term));
|
|
|
|
CHECK(term == nullptr);
|
|
|
|
|
|
|
|
esp_modem_dce_config_t dce_config = ESP_MODEM_DCE_DEFAULT_CONFIG("APN");
|
|
|
|
esp_netif_t netif{};
|
|
|
|
auto dce = create_SIM7600_dce(&dce_config, dte, &netif);
|
|
|
|
CHECK(dce != nullptr);
|
|
|
|
|
|
|
|
CHECK(dce->set_mode(esp_modem::modem_mode::CMUX_MODE) == true);
|
|
|
|
const auto test_command = "Test\n";
|
|
|
|
// 1 byte payload size
|
|
|
|
uint8_t test_payload[] = {0xf9, 0x05, 0xff, 0x0b, 0x54, 0x65, 0x73, 0x74, 0x0a, 0xbb, 0xf9 };
|
|
|
|
loopback->inject(&test_payload[0], sizeof(test_payload), 1);
|
|
|
|
auto ret = dce->command(test_command, [&](uint8_t *data, size_t len) {
|
|
|
|
std::string response((char *) data, len);
|
|
|
|
CHECK(response == test_command);
|
|
|
|
return command_result::OK;
|
|
|
|
}, 1000);
|
|
|
|
CHECK(ret == command_result::OK);
|
|
|
|
|
|
|
|
// 2 byte payload size
|
|
|
|
uint8_t long_payload[453] = { 0xf9, 0x05, 0xef, 0x7c, 0x03, 0x7e }; // header
|
|
|
|
long_payload[5] = 0x7e; // payload to validate
|
|
|
|
long_payload[449] = 0x7e;
|
|
|
|
long_payload[450] = '\n';
|
|
|
|
long_payload[451] = 0x53; // footer
|
|
|
|
long_payload[452] = 0xf9;
|
|
|
|
for (int i=0; i<5; ++i) {
|
|
|
|
// inject the whole payload (i=0) and then per 1,2,3,4 bytes (i)
|
|
|
|
loopback->inject(&long_payload[0], sizeof(long_payload), i==0?sizeof(long_payload):i);
|
|
|
|
auto ret = dce->command("ignore", [&](uint8_t *data, size_t len) {
|
|
|
|
CHECK(data[0] == 0x7e);
|
|
|
|
CHECK(data[len-2] == 0x7e);
|
|
|
|
CHECK(data[len-1] == '\n');
|
|
|
|
return command_result::OK;
|
|
|
|
}, 1000);
|
|
|
|
CHECK(ret == command_result::OK);
|
|
|
|
}
|
|
|
|
}
|