esp_modem: Moved to component folder

This commit is contained in:
David Čermák
2021-05-19 23:00:28 +08:00
committed by David Cermak
parent 61f264f97a
commit 90641c89eb
133 changed files with 21 additions and 21 deletions

View File

@ -0,0 +1,15 @@
cmake_minimum_required(VERSION 3.5)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
set(EXTRA_COMPONENT_DIRS # Add esp_modem component and linux port components
../..
../../port/linux)
set(COMPONENTS main)
project(host_modem_test)
idf_component_get_property(esp_modem esp_modem COMPONENT_LIB)
target_compile_definitions(${esp_modem} PRIVATE "-DCONFIG_COMPILER_CXX_EXCEPTIONS")
target_compile_definitions(${esp_modem} PRIVATE "-DCONFIG_IDF_TARGET_LINUX")
target_link_options(${esp_modem} INTERFACE -fsanitize=address)

View File

@ -0,0 +1,5 @@
# Host test for esp_modem
This test uses linux port and some idf mocks in order to compile and execute it under linux.
This test uses `catch` as a test framework and implements a test terminal class `LoopbackTerm`

View File

@ -0,0 +1,10 @@
idf_component_register(SRCS "test_modem.cpp" "LoopbackTerm.cpp"
INCLUDE_DIRS "$ENV{IDF_PATH}/tools/catch"
REQUIRES esp_modem)
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
target_link_libraries(${COMPONENT_LIB} PRIVATE Threads::Threads)
target_compile_features(${COMPONENT_LIB} PRIVATE cxx_std_17)
target_compile_definitions(${COMPONENT_LIB} PRIVATE "-DCONFIG_IDF_TARGET_LINUX")

View File

@ -0,0 +1,82 @@
#include <memory>
#include <future>
#include <cstring>
#include "LoopbackTerm.h"
void LoopbackTerm::start()
{
status = status_t::STARTED;
}
void LoopbackTerm::stop()
{
status = status_t::STOPPED;
}
int LoopbackTerm::write(uint8_t *data, size_t len)
{
if (len > 2 && (data[len-1] == '\r' || data[len-1] == '+') ) { // Simple AT responder
std::string command((char*)data, len);
std::string response;
if (command == "+++") {
response = "NO CARRIER\r\n";
} else if (command == "ATE1\r" || command == "ATE0\r") {
response = "OK\r\n";
} else if (command == "ATO\r") {
response = "ERROR\r\n";
} else if (command.find("ATD") != std::string::npos) {
response = "CONNECT\r\n";
} else if (command.find("AT+CSQ\r") != std::string::npos) {
response = "+CSQ: 123,456\n\r\nOK\r\n";
} else if (command.find("AT+CBC\r") != std::string::npos) {
response = is_bg96 ? "+CBC: 1,2,123456V\r\r\n\r\nOK\r\n\n\r\n":
"+CBC: 123.456V\r\r\n\r\nOK\r\n\n\r\n";
} else if (command.find("AT+CPIN=1234\r") != std::string::npos) {
response = "OK\r\n";
pin_ok = true;
} else if (command.find("AT+CPIN?\r") != std::string::npos) {
response = pin_ok?"+CPIN: READY\r\nOK\r\n":"+CPIN: SIM PIN\r\nOK\r\n";
} else if (command.find("AT") != std::string::npos) {
response = "OK\r\n";
}
if (!response.empty()) {
data_len = response.length();
loopback_data.resize(data_len);
memcpy(&loopback_data[0], &response[0], data_len);
auto ret = std::async(on_data, nullptr, data_len);
return len;
}
}
if (len > 2 && data[0] == 0xf9) { // Simple CMUX responder
// turn the request into a reply -> implements CMUX loopback
if (data[2] == 0x3f) // SABM command
data[2] = 0x73;
else if (data[2] == 0xef) { // Generic request
data[2] = 0xff; // generic reply
}
}
loopback_data.resize(data_len + len);
memcpy(&loopback_data[data_len], data, len);
data_len += len;
auto ret = std::async(on_data, nullptr, data_len);
return len;
}
int LoopbackTerm::read(uint8_t *data, size_t len)
{
size_t read_len = std::min(data_len, len);
if (read_len) {
if (loopback_data.capacity() < len)
loopback_data.reserve(len);
memcpy(data, &loopback_data[0], read_len);
loopback_data.erase(loopback_data.begin(), loopback_data.begin() + read_len);
data_len -= read_len;
}
return read_len;
}
LoopbackTerm::LoopbackTerm(bool is_bg96): loopback_data(), data_len(0), pin_ok(false), is_bg96(is_bg96) {}
LoopbackTerm::LoopbackTerm(): loopback_data(), data_len(0), pin_ok(false), is_bg96(false) {}
LoopbackTerm::~LoopbackTerm() = default;

View File

@ -0,0 +1,36 @@
#ifndef _LOOPBACKTERM_H_
#define _LOOPBACKTERM_H_
#include "cxx_include/esp_modem_api.hpp"
#include "cxx_include/esp_modem_terminal.hpp"
using namespace esp_modem;
class LoopbackTerm : public Terminal {
public:
explicit LoopbackTerm(bool is_bg96);
explicit LoopbackTerm();
~LoopbackTerm() override;
void start() override;
void stop() override;
int write(uint8_t *data, size_t len) override;
int read(uint8_t *data, size_t len) override;
private:
enum class status_t {
STARTED,
STOPPED
};
status_t status;
SignalGroup signal;
std::vector<uint8_t> loopback_data;
size_t data_len;
bool pin_ok;
bool is_bg96;
};
#endif //_LOOPBACKTERM_H_

View File

@ -0,0 +1,136 @@
#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"
#include "LoopbackTerm.h"
using namespace esp_modem;
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);
CHECK(bcs == 2);
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);
}
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);
CHECK(dte->set_mode(esp_modem::modem_mode::COMMAND_MODE) == true);
auto ret = dte->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);
}
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) {
std::string response((char*)data, len);
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);
int milli_volt, bcl, bcs;
CHECK(dce->set_echo(false) == command_result::OK);
CHECK(dce->set_echo(true) == command_result::OK);
CHECK(dce->get_battery_status(milli_volt, bcl, bcs) == command_result::OK);
CHECK(milli_volt == 123456);
CHECK(dce->resume_data_mode() == command_result::FAIL);
}
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);
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);
}
TEST_CASE("DCE CMUX test", "[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);
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);
std::cout << "Response:" << response << std::endl;
CHECK(response == test_command);
return command_result::OK;
}, 1000);
CHECK(ret == command_result::OK);
}

View File

@ -0,0 +1,5 @@
CONFIG_IDF_TARGET="linux"
CONFIG_COMPILER_CXX_EXCEPTIONS=y
CONFIG_COMPILER_CXX_RTTI=y
CONFIG_COMPILER_CXX_EXCEPTIONS_EMG_POOL_SIZE=0
CONFIG_COMPILER_STACK_CHECK_NONE=y

View File

@ -0,0 +1,74 @@
#
# Automatically generated file. DO NOT EDIT.
# Espressif IoT Development Framework (ESP-IDF) Project Configuration
#
CONFIG_IDF_CMAKE=y
CONFIG_IDF_TARGET="linux"
CONFIG_IDF_FIRMWARE_CHIP_ID=0xFFFF
#
# SDK tool configuration
#
CONFIG_SDK_TOOLPREFIX=""
# CONFIG_SDK_TOOLCHAIN_SUPPORTS_TIME_WIDE_64_BITS is not set
# end of SDK tool configuration
#
# Build type
#
CONFIG_APP_BUILD_TYPE_APP_2NDBOOT=y
# CONFIG_APP_BUILD_TYPE_ELF_RAM is not set
CONFIG_APP_BUILD_GENERATE_BINARIES=y
CONFIG_APP_BUILD_BOOTLOADER=y
CONFIG_APP_BUILD_USE_FLASH_SECTIONS=y
# end of Build type
#
# Compiler options
#
CONFIG_COMPILER_OPTIMIZATION_DEFAULT=y
# CONFIG_COMPILER_OPTIMIZATION_SIZE is not set
# CONFIG_COMPILER_OPTIMIZATION_PERF is not set
# CONFIG_COMPILER_OPTIMIZATION_NONE is not set
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y
# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT is not set
# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE is not set
CONFIG_COMPILER_HIDE_PATHS_MACROS=y
CONFIG_COMPILER_CXX_EXCEPTIONS=y
CONFIG_COMPILER_CXX_EXCEPTIONS_EMG_POOL_SIZE=0
CONFIG_COMPILER_CXX_RTTI=y
CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y
# CONFIG_COMPILER_STACK_CHECK_MODE_NORM is not set
# CONFIG_COMPILER_STACK_CHECK_MODE_STRONG is not set
# CONFIG_COMPILER_STACK_CHECK_MODE_ALL is not set
# CONFIG_COMPILER_WARN_WRITE_STRINGS is not set
# CONFIG_COMPILER_DISABLE_GCC8_WARNINGS is not set
# CONFIG_COMPILER_DUMP_RTL_FILES is not set
# end of Compiler options
#
# Component config
#
#
# Compatibility options
#
# CONFIG_LEGACY_INCLUDE_COMMON_HEADERS is not set
# end of Compatibility options
# Deprecated options for backward compatibility
CONFIG_TOOLPREFIX=""
CONFIG_COMPILER_OPTIMIZATION_LEVEL_DEBUG=y
# CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE is not set
CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED=y
# CONFIG_OPTIMIZATION_ASSERTIONS_SILENT is not set
# CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED is not set
CONFIG_CXX_EXCEPTIONS=y
CONFIG_CXX_EXCEPTIONS_EMG_POOL_SIZE=0
CONFIG_STACK_CHECK_NONE=y
# CONFIG_STACK_CHECK_NORM is not set
# CONFIG_STACK_CHECK_STRONG is not set
# CONFIG_STACK_CHECK_ALL is not set
# CONFIG_WARN_WRITE_STRINGS is not set
# CONFIG_DISABLE_GCC8_WARNINGS is not set
# End of deprecated options