From 8f17a900266f65dfcf6c0c47fceec85e8272829f Mon Sep 17 00:00:00 2001 From: David Cermak Date: Sun, 23 May 2021 20:43:50 +0200 Subject: [PATCH] esp-modem(VFS): Reworked decouple resources from the file system --- components/esp_modem/.gitignore | 9 +- components/esp_modem/CMakeLists.txt | 2 + .../examples/linux_modem/main/modem_main.cpp | 36 ++++-- .../main/simple_cmux_client_main.cpp | 10 +- .../esp_modem/include/esp_modem_config.h | 25 ++--- .../include/vfs_resource/vfs_create.hpp | 72 ++++++++++++ .../include/driver/uart.h | 1 + .../private_include/exception_stub.hpp | 15 ++- .../private_include/uart_resource.hpp | 5 +- .../esp_modem/src/esp_modem_term_fs.cpp | 31 ++---- .../esp_modem/src/esp_modem_term_uart.cpp | 42 +++---- components/esp_modem/src/esp_modem_uart.cpp | 2 +- .../esp_modem/src/esp_modem_uart_linux.cpp | 2 +- .../src/esp_modem_vfs_socket_creator.cpp | 104 ++++++++++++++++++ .../src/esp_modem_vfs_uart_creator.cpp | 64 +++++++++++ .../esp_modem/test/host_test/sdkconfig.old | 74 ------------- .../esp_modem/test/target/main/NetworkDCE.cpp | 15 +-- 17 files changed, 332 insertions(+), 177 deletions(-) create mode 100644 components/esp_modem/include/vfs_resource/vfs_create.hpp create mode 100644 components/esp_modem/src/esp_modem_vfs_socket_creator.cpp create mode 100644 components/esp_modem/src/esp_modem_vfs_uart_creator.cpp delete mode 100644 components/esp_modem/test/host_test/sdkconfig.old diff --git a/components/esp_modem/.gitignore b/components/esp_modem/.gitignore index 61e02dae7..5aa50beb2 100644 --- a/components/esp_modem/.gitignore +++ b/components/esp_modem/.gitignore @@ -51,9 +51,9 @@ tools/unit-test-app/test_configs log_ut_cmake # test application build files -tools/test_apps/**/build -tools/test_apps/**/sdkconfig -tools/test_apps/**/sdkconfig.old +test/**/build +test/**/sdkconfig +test/**/sdkconfig.old # IDF monitor test tools/test_idf_monitor/outputs @@ -88,3 +88,6 @@ build # lock files for examples and components dependencies.lock + +# ignore generated docs +docs/html \ No newline at end of file diff --git a/components/esp_modem/CMakeLists.txt b/components/esp_modem/CMakeLists.txt index a1b031ff3..f0c7e88e0 100644 --- a/components/esp_modem/CMakeLists.txt +++ b/components/esp_modem/CMakeLists.txt @@ -22,6 +22,8 @@ set(srcs ${platform_srcs} "src/esp_modem_cmux.cpp" "src/esp_modem_command_library.cpp" "src/esp_modem_term_fs.cpp" + "src/esp_modem_vfs_uart_creator.cpp" + "src/esp_modem_vfs_socket_creator.cpp" "src/esp_modem_modules.cpp") set(include_dirs "include") diff --git a/components/esp_modem/examples/linux_modem/main/modem_main.cpp b/components/esp_modem/examples/linux_modem/main/modem_main.cpp index 68b28188f..46c9449ec 100644 --- a/components/esp_modem/examples/linux_modem/main/modem_main.cpp +++ b/components/esp_modem/examples/linux_modem/main/modem_main.cpp @@ -7,9 +7,11 @@ #include "cxx_include/esp_modem_dte.hpp" #include "esp_modem_config.h" #include "esp_netif.h" +#include "vfs_resource/vfs_create.hpp" #define CONFIG_EXAMPLE_SIM_PIN "1234" +#define CONFIG_USE_VFS_UART 1 using namespace esp_modem; @@ -18,28 +20,41 @@ using namespace esp_modem; int main() { - // init the DTE esp_modem_dte_config_t dte_config = { .dte_buffer_size = 512, .task_stack_size = 1024, .task_priority = 10, - .uart_config = { }, - .vfs_config = { } + .vfs_config = {} }; - dte_config.vfs_config.dev_name = "/dev/ttyUSB0"; - dte_config.vfs_config.resource = ESP_MODEM_VFS_IS_UART; // This tells the VFS to init the UART (use termux to setup baudrate, etc.) +#if CONFIG_USE_VFS_UART == 1 + struct esp_modem_vfs_uart_creator uart_config = { + .dev_name = "/dev/ttyUSB0", + .uart = {} + }; + assert(vfs_create_uart(&uart_config, &dte_config.vfs_config) == true); +#else + /** + * @note: It is possible to setup a serial to socket bridge, running a this on a remote host which connects `/dev/ttyS0` to the modem + * socat TCP-L:2222 GOPEN:/dev/ttyS0,ispeed=115200,ospeed=1152000,b115200,raw,echo=0 + */ + struct esp_modem_vfs_socket_creator socket_config = { + .host_name = "raspberrypi.local", + .port = 2222 + }; + assert(vfs_create_socket(&socket_config, &dte_config.vfs_config) == true); +#endif + auto dte = create_vfs_dte(&dte_config); esp_netif_config_t netif_config = { .dev_name = "/dev/net/tun", .if_name = "tun0" }; esp_netif_t *tun_netif = esp_netif_new(&netif_config); - auto uart_dte = create_vfs_dte(&dte_config); esp_modem_dce_config_t dce_config = ESP_MODEM_DCE_DEFAULT_CONFIG("internet"); - auto dce = create_SIM7600_dce(&dce_config, uart_dte, tun_netif); + auto dce = create_SIM7600_dce(&dce_config, dte, tun_netif); assert(dce != nullptr); dce->set_command_mode(); @@ -50,16 +65,17 @@ int main() usleep(1000000); } std::string str; - dce->set_mode(esp_modem::modem_mode::CMUX_MODE); +// dce->set_mode(esp_modem::modem_mode::CMUX_MODE); dce->get_imsi(str); ESP_LOGI(TAG, "Modem IMSI number: %s",str.c_str()); dce->get_imei(str); ESP_LOGI(TAG, "Modem IMEI number: %s",str.c_str()); - dce->get_operator_name(str); + while (command_result::OK != dce->get_operator_name(str)) + { printf(".\n"); } ESP_LOGI(TAG, "Operator name: %s",str.c_str()); dce->set_mode(esp_modem::modem_mode::DATA_MODE); - usleep(100'000'000); + usleep(15'000'000); esp_netif_destroy(tun_netif); } \ No newline at end of file diff --git a/components/esp_modem/examples/simple_cmux_client/main/simple_cmux_client_main.cpp b/components/esp_modem/examples/simple_cmux_client/main/simple_cmux_client_main.cpp index 1fd8c70e8..47fcfb830 100644 --- a/components/esp_modem/examples/simple_cmux_client/main/simple_cmux_client_main.cpp +++ b/components/esp_modem/examples/simple_cmux_client/main/simple_cmux_client_main.cpp @@ -19,7 +19,7 @@ #include "simple_mqtt_client.hpp" #include "esp_vfs_dev.h" // For optional VFS support #include "esp_https_ota.h" // For potential OTA configuration - +#include "vfs_resource/vfs_create.hpp" #define BROKER_URL "mqtt://mqtt.eclipseprojects.io" @@ -46,11 +46,11 @@ extern "C" void app_main(void) * so doesn't give any practical benefit besides the FD use demonstration and a placeholder * to use FD terminal for other devices */ - dte_config.vfs_config.dev_name = "/dev/uart/1"; - dte_config.vfs_config.resource = ESP_MODEM_VFS_IS_UART; - dte_config.uart_config.event_queue_size = 0; + struct esp_modem_vfs_uart_creator uart_config = ESP_MODEM_VFS_DEFAULT_UART_CONFIG("/dev/uart/1"); + assert(vfs_create_uart(&uart_config, &dte_config.vfs_config) == true); + auto dte = create_vfs_dte(&dte_config); - esp_vfs_dev_uart_use_driver(dte_config.uart_config.port_num); + esp_vfs_dev_uart_use_driver(uart_config.uart.port_num); #else auto dte = create_uart_dte(&dte_config); #endif // CONFIG_EXAMPLE_USE_VFS_TERM diff --git a/components/esp_modem/include/esp_modem_config.h b/components/esp_modem/include/esp_modem_config.h index be0df5fc1..40f8f670a 100644 --- a/components/esp_modem/include/esp_modem_config.h +++ b/components/esp_modem/include/esp_modem_config.h @@ -56,23 +56,14 @@ struct esp_modem_uart_term_config { int event_queue_size; /*!< UART Event Queue Size, set to 0 if no event queue needed */ }; -/** - * @brief Resources used by VFS terminal - * - */ -typedef enum { - ESP_MODEM_VFS_IS_EXTERN = 0, /*!< External resource: internal VFS terminal takes no action to setup this */ - ESP_MODEM_VFS_IS_UART, /*!< VFS uses UART: internal VFS initializes UART based on esp_modem_uart_term_config */ -} esp_modem_vfs_resource_t; - - /** * @brief VFS configuration structure * */ struct esp_modem_vfs_term_config { - const char* dev_name; /*!< VFS device name, e.g. /dev/uart/n */ - esp_modem_vfs_resource_t resource; /*!< Underlying device which gets initialized during VFS init */ + int fd; /*!< Already created file descriptor */ + void (*deleter)(int, struct esp_modem_vfs_resource*); /*!< Custom close function for the fd */ + struct esp_modem_vfs_resource *resource; /*!< Resource attached to the VFS (need for clenaup) */ }; /** @@ -86,8 +77,10 @@ struct esp_modem_dte_config { size_t dte_buffer_size; /*!< DTE buffer size */ uint32_t task_stack_size; /*!< Terminal task stack size */ int task_priority; /*!< Terminal task priority */ - struct esp_modem_uart_term_config uart_config; /*!< Configuration for UART Terminal */ - struct esp_modem_vfs_term_config vfs_config; /*!< Configuration for VFS Terminal */ + union { + struct esp_modem_uart_term_config uart_config; /*!< Configuration for UART Terminal */ + struct esp_modem_vfs_term_config vfs_config; /*!< Configuration for VFS Terminal */ + }; }; @@ -115,10 +108,6 @@ struct esp_modem_dte_config { .tx_buffer_size = 512, \ .event_queue_size = 30, \ }, \ - .vfs_config = { \ - .dev_name = "/null", \ - .resource = ESP_MODEM_VFS_IS_EXTERN \ - }\ } typedef struct esp_modem_dte_config esp_modem_dte_config_t; diff --git a/components/esp_modem/include/vfs_resource/vfs_create.hpp b/components/esp_modem/include/vfs_resource/vfs_create.hpp new file mode 100644 index 000000000..03e11e36b --- /dev/null +++ b/components/esp_modem/include/vfs_resource/vfs_create.hpp @@ -0,0 +1,72 @@ +// Copyright 2021 Espressif Systems (Shanghai) PTE LTD +// +// 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 _VFS_CREATE_HPP_ +#define _VFS_CREATE_HPP_ + +#define ESP_MODEM_VFS_DEFAULT_UART_CONFIG(name) { \ + .dev_name = (name), \ + .uart = { \ + .port_num = UART_NUM_1, \ + .data_bits = UART_DATA_8_BITS, \ + .stop_bits = UART_STOP_BITS_1, \ + .parity = UART_PARITY_DISABLE, \ + .flow_control = ESP_MODEM_FLOW_CONTROL_NONE,\ + .baud_rate = 115200, \ + .tx_io_num = 25, \ + .rx_io_num = 26, \ + .rts_io_num = 27, \ + .cts_io_num = 23, \ + .rx_buffer_size = 4096, \ + .tx_buffer_size = 512, \ + .event_queue_size = 0, \ + }, \ +} + +/** + * @brief UART init struct for VFS + */ +struct esp_modem_vfs_uart_creator { + const char* dev_name; /*!< VFS device name, e.g. /dev/uart/n */ + const struct esp_modem_uart_term_config uart; /*!< UART driver init struct */ +}; + +/** + * @brief UART init struct for VFS + */ +struct esp_modem_vfs_socket_creator { + const char* host_name; /*!< VFS socket: host name (or IP address) */ + int port; /*!< VFS socket: port number */ +}; + +/** + * @brief Creates a socket VFS and configures the DTE struct + * + * @param config Socket config option, basically host + port + * @param created_config reference to the VFS portion of the DTE config to be set up + * @return true on success + */ +bool vfs_create_socket(struct esp_modem_vfs_socket_creator *config, struct esp_modem_vfs_term_config *created_config); + +/** + * @brief Creates a uart VFS and configures the DTE struct + * + * @param config Uart config option, basically file name and console options + * @param created_config reference to the VFS portion of the DTE config to be set up + * @return true on success + */ +bool vfs_create_uart(struct esp_modem_vfs_uart_creator *config, struct esp_modem_vfs_term_config *created_config); + + +#endif //_VFS_CREATE_HPP_ diff --git a/components/esp_modem/port/linux/esp_system_protocols_linux/include/driver/uart.h b/components/esp_modem/port/linux/esp_system_protocols_linux/include/driver/uart.h index fccc587fb..9142a2f91 100644 --- a/components/esp_modem/port/linux/esp_system_protocols_linux/include/driver/uart.h +++ b/components/esp_modem/port/linux/esp_system_protocols_linux/include/driver/uart.h @@ -12,6 +12,7 @@ // limitations under the License. #pragma once +#include typedef int uart_port_t; typedef int uart_word_length_t; diff --git a/components/esp_modem/private_include/exception_stub.hpp b/components/esp_modem/private_include/exception_stub.hpp index 0a0ff98df..5598acc01 100644 --- a/components/esp_modem/private_include/exception_stub.hpp +++ b/components/esp_modem/private_include/exception_stub.hpp @@ -16,20 +16,27 @@ #define _EXCEPTION_STUB_HPP_ #ifdef CONFIG_COMPILER_CXX_EXCEPTIONS -#define TRY_CATCH_RET_NULL(block) \ +#define TRY_CATCH_OR_DO(block, action) \ try { block \ } catch (std::bad_alloc& e) { \ ESP_LOGE(TAG, "Out of memory"); \ - return nullptr; \ - } catch (esp_err_exception& e) { \ + action; \ + } catch (::esp_modem::esp_err_exception& e) { \ esp_err_t err = e.get_err_t(); \ ESP_LOGE(TAG, "%s: Exception caught with ESP err_code=%d", __func__, err); \ ESP_LOGE(TAG, "%s", e.what()); \ - return nullptr; \ + action; \ } + +#define TRY_CATCH_RET_NULL(block) TRY_CATCH_OR_DO(block, return nullptr) #else + +#define TRY_CATCH_OR_DO(block, action) \ + block + #define TRY_CATCH_RET_NULL(block) \ block + #endif diff --git a/components/esp_modem/private_include/uart_resource.hpp b/components/esp_modem/private_include/uart_resource.hpp index 5d8be1b09..3fd786d85 100644 --- a/components/esp_modem/private_include/uart_resource.hpp +++ b/components/esp_modem/private_include/uart_resource.hpp @@ -18,7 +18,7 @@ #include "cxx_include/esp_modem_dte.hpp" #include "esp_modem_config.h" -struct esp_modem_dte_config; +struct esp_modem_uart_term_config; namespace esp_modem { @@ -26,14 +26,13 @@ namespace esp_modem { * @brief Uart Resource is a platform specific struct which is implemented separately for ESP_PLATFORM and linux target */ struct uart_resource { - explicit uart_resource(const esp_modem_dte_config *config, QueueHandle_t* event_queue, int fd); + explicit uart_resource(const esp_modem_uart_term_config *config, QueueHandle_t* event_queue, int fd); ~uart_resource(); uart_port_t port{}; }; -std::unique_ptr create_vfs_terminal(const esp_modem_dte_config *config); } // namespace esp_modem diff --git a/components/esp_modem/src/esp_modem_term_fs.cpp b/components/esp_modem/src/esp_modem_term_fs.cpp index b9ff1043e..c23e2c15c 100644 --- a/components/esp_modem/src/esp_modem_term_fs.cpp +++ b/components/esp_modem/src/esp_modem_term_fs.cpp @@ -14,43 +14,29 @@ #include #include -#include #include "cxx_include/esp_modem_dte.hpp" #include "esp_log.h" #include "esp_modem_config.h" #include "exception_stub.hpp" -#include "uart_resource.hpp" // In case of VFS using UART static const char *TAG = "fs_terminal"; namespace esp_modem { -class Resource { -public: - explicit Resource(const esp_modem_dte_config *config, int fd): - uart(config->vfs_config.resource == ESP_MODEM_VFS_IS_EXTERN? std::nullopt : std::make_optional(config, nullptr, fd)) - {} - - std::optional uart; -}; struct File { - explicit File(const char *name): fd(-1) - { - fd = open(name, O_RDWR); - throw_if_false(fd >= 0, "Cannot open the fd"); - - // Set the FD to non-blocking mode - int flags = fcntl(fd, F_GETFL, nullptr) | O_NONBLOCK; - fcntl(fd, F_SETFL, flags); - } + explicit File(const esp_modem_dte_config *config): + fd(config->vfs_config.fd), deleter(config->vfs_config.deleter), resource(config->vfs_config.resource) + {} ~File() { - if (fd >= 0) { - close(fd); + if (deleter) { + deleter(fd, resource); } } int fd; + void (*deleter)(int fd, struct esp_modem_vfs_resource *res); + struct esp_modem_vfs_resource *resource; }; class FdTerminal : public Terminal { @@ -85,7 +71,6 @@ private: static const size_t TASK_PARAMS = SignalGroup::bit3; File f; - Resource resource; SignalGroup signal; Task task_handle; }; @@ -99,7 +84,7 @@ std::unique_ptr create_vfs_terminal(const esp_modem_dte_config *config } FdTerminal::FdTerminal(const esp_modem_dte_config *config) : - f(config->vfs_config.dev_name), resource(config, f.fd), signal(), + f(config), signal(), task_handle(config->task_stack_size, config->task_priority, this, [](void* p){ auto t = static_cast(p); t->task(); diff --git a/components/esp_modem/src/esp_modem_term_uart.cpp b/components/esp_modem/src/esp_modem_term_uart.cpp index 594fadd32..8f4632fee 100644 --- a/components/esp_modem/src/esp_modem_term_uart.cpp +++ b/components/esp_modem/src/esp_modem_term_uart.cpp @@ -25,51 +25,51 @@ uart_resource::~uart_resource() } } -uart_resource::uart_resource(const esp_modem_dte_config *config, QueueHandle_t* event_queue, int fd) +uart_resource::uart_resource(const esp_modem_uart_term_config *config, QueueHandle_t* event_queue, int fd) :port(-1) { esp_err_t res; /* Config UART */ uart_config_t uart_config = {}; - uart_config.baud_rate = config->uart_config.baud_rate; - uart_config.data_bits = config->uart_config.data_bits; - uart_config.parity = config->uart_config.parity; - uart_config.stop_bits = config->uart_config.stop_bits; - uart_config.flow_ctrl = (config->uart_config.flow_control == ESP_MODEM_FLOW_CONTROL_HW) ? UART_HW_FLOWCTRL_CTS_RTS + uart_config.baud_rate = config->baud_rate; + uart_config.data_bits = config->data_bits; + uart_config.parity = config->parity; + uart_config.stop_bits = config->stop_bits; + uart_config.flow_ctrl = (config->flow_control == ESP_MODEM_FLOW_CONTROL_HW) ? UART_HW_FLOWCTRL_CTS_RTS : UART_HW_FLOWCTRL_DISABLE; uart_config.source_clk = UART_SCLK_APB; - throw_if_esp_fail(uart_param_config(config->uart_config.port_num, &uart_config), "config uart parameter failed"); + throw_if_esp_fail(uart_param_config(config->port_num, &uart_config), "config uart parameter failed"); - if (config->uart_config.flow_control == ESP_MODEM_FLOW_CONTROL_HW) { - res = uart_set_pin(config->uart_config.port_num, config->uart_config.tx_io_num, config->uart_config.rx_io_num, - config->uart_config.rts_io_num, config->uart_config.cts_io_num); + if (config->flow_control == ESP_MODEM_FLOW_CONTROL_HW) { + res = uart_set_pin(config->port_num, config->tx_io_num, config->rx_io_num, + config->rts_io_num, config->cts_io_num); } else { - res = uart_set_pin(config->uart_config.port_num, config->uart_config.tx_io_num, config->uart_config.rx_io_num, + res = uart_set_pin(config->port_num, config->tx_io_num, config->rx_io_num, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); } throw_if_esp_fail(res, "config uart gpio failed"); /* Set flow control threshold */ - if (config->uart_config.flow_control == ESP_MODEM_FLOW_CONTROL_HW) { - res = uart_set_hw_flow_ctrl(config->uart_config.port_num, UART_HW_FLOWCTRL_CTS_RTS, UART_FIFO_LEN - 8); - } else if (config->uart_config.flow_control == ESP_MODEM_FLOW_CONTROL_SW) { - res = uart_set_sw_flow_ctrl(config->uart_config.port_num, true, 8, UART_FIFO_LEN - 8); + if (config->flow_control == ESP_MODEM_FLOW_CONTROL_HW) { + res = uart_set_hw_flow_ctrl(config->port_num, UART_HW_FLOWCTRL_CTS_RTS, UART_FIFO_LEN - 8); + } else if (config->flow_control == ESP_MODEM_FLOW_CONTROL_SW) { + res = uart_set_sw_flow_ctrl(config->port_num, true, 8, UART_FIFO_LEN - 8); } throw_if_esp_fail(res, "config uart flow control failed"); /* Install UART driver and get event queue used inside driver */ - res = uart_driver_install(config->uart_config.port_num, - config->uart_config.rx_buffer_size, config->uart_config.tx_buffer_size, - config->uart_config.event_queue_size, config->uart_config.event_queue_size ? event_queue : nullptr, + res = uart_driver_install(config->port_num, + config->rx_buffer_size, config->tx_buffer_size, + config->event_queue_size, config->event_queue_size ? event_queue : nullptr, 0); throw_if_esp_fail(res, "install uart driver failed"); - throw_if_esp_fail(uart_set_rx_timeout(config->uart_config.port_num, 1), "set rx timeout failed"); + throw_if_esp_fail(uart_set_rx_timeout(config->port_num, 1), "set rx timeout failed"); - throw_if_esp_fail(uart_set_rx_full_threshold(config->uart_config.port_num, 64), "config rx full threshold failed"); + throw_if_esp_fail(uart_set_rx_full_threshold(config->port_num, 64), "config rx full threshold failed"); /* mark UART as initialized */ - port = config->uart_config.port_num; + port = config->port_num; } } // namespace esp_modem diff --git a/components/esp_modem/src/esp_modem_uart.cpp b/components/esp_modem/src/esp_modem_uart.cpp index fe163fb1b..95acd31d6 100644 --- a/components/esp_modem/src/esp_modem_uart.cpp +++ b/components/esp_modem/src/esp_modem_uart.cpp @@ -47,7 +47,7 @@ struct uart_task { class UartTerminal : public Terminal { public: explicit UartTerminal(const esp_modem_dte_config *config) : - event_queue(), uart(config, &event_queue, -1), signal(), + event_queue(), uart(&config->uart_config, &event_queue, -1), signal(), task_handle(config->task_stack_size, config->task_priority, this, s_task) {} ~UartTerminal() override = default; diff --git a/components/esp_modem/src/esp_modem_uart_linux.cpp b/components/esp_modem/src/esp_modem_uart_linux.cpp index ad696c2e3..1bc3e8625 100644 --- a/components/esp_modem/src/esp_modem_uart_linux.cpp +++ b/components/esp_modem/src/esp_modem_uart_linux.cpp @@ -23,7 +23,7 @@ namespace esp_modem { constexpr const char *TAG = "uart_resource"; -uart_resource::uart_resource(const esp_modem_dte_config *config, QueueHandle_t* event_queue, int fd): port(-1) +uart_resource::uart_resource(const esp_modem_uart_term_config *config, QueueHandle_t* event_queue, int fd): port(-1) { ESP_LOGD(TAG, "Creating uart resource" ); struct termios tty = {}; diff --git a/components/esp_modem/src/esp_modem_vfs_socket_creator.cpp b/components/esp_modem/src/esp_modem_vfs_socket_creator.cpp new file mode 100644 index 000000000..9f4d3a2e7 --- /dev/null +++ b/components/esp_modem/src/esp_modem_vfs_socket_creator.cpp @@ -0,0 +1,104 @@ +// Copyright 2021 Espressif Systems (Shanghai) PTE LTD +// +// 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 +#include +#include +#include +#include +#include +#include +#include "esp_log.h" +#include "esp_modem_config.h" +#include "cxx_include/esp_modem_exception.hpp" +#include "exception_stub.hpp" +#include "uart_resource.hpp" +#include "vfs_resource/vfs_create.hpp" + + +constexpr const char *TAG = "vfs_socket_creator"; + +/** + * @brief socket VFS + * @note: Remote command: + * socat TCP-L:2222 GOPEN:/dev/ttyS0,ispeed=115200,ospeed=1152000,b115200,raw,echo=0 + */ +static esp_err_t hostname_to_fd(const char *host, int port, int* fd) +{ + struct sockaddr_storage address = {}; + struct addrinfo *address_info; + struct addrinfo hints = {}; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + + int res = getaddrinfo(host, nullptr, &hints, &address_info); + if (res != 0 || address_info == nullptr) { + ESP_LOGE(TAG, "couldn't get hostname for :%s: " + "getaddrinfo() returns %d, addrinfo=%p", host, res, address_info); + return ESP_FAIL; + } + *fd = socket(address_info->ai_family, address_info->ai_socktype, address_info->ai_protocol); + if (*fd < 0) { + ESP_LOGE(TAG, "Failed to create socket (family %d socktype %d protocol %d)", address_info->ai_family, address_info->ai_socktype, address_info->ai_protocol); + freeaddrinfo(address_info); + return ESP_FAIL; + } + + if (address_info->ai_family == AF_INET) { + auto *p = reinterpret_cast(address_info->ai_addr); + p->sin_port = htons(port); + ESP_LOGI(TAG, "[sock=%d] Resolved IPv4 address: %s", *fd, inet_ntoa(p->sin_addr)); + memcpy(&address, p, sizeof(struct sockaddr )); + } else { + ESP_LOGE(TAG, "Unsupported protocol family %d", address_info->ai_family); + close(*fd); + freeaddrinfo(address_info); + return ESP_FAIL; + } + + freeaddrinfo(address_info); + if (connect(*fd, (struct sockaddr *)&address, sizeof(struct sockaddr)) < 0) { + ESP_LOGE(TAG, "[sock=%d] Failed to connect", *fd); + return ESP_FAIL; + } + return ESP_OK; +} + + +static void vfs_destroy_socket(int fd, struct esp_modem_vfs_resource * resource) +{ + if (fd >= 0) { + close(fd); + } +} + +bool vfs_create_socket(struct esp_modem_vfs_socket_creator *config, struct esp_modem_vfs_term_config *created_config) +{ + if (config == nullptr || created_config == nullptr) { + return false; + } + TRY_CATCH_OR_DO( + int fd = -1; + esp_modem::throw_if_esp_fail(hostname_to_fd(config->host_name, config->port, &fd)); + + // Set the FD to non-blocking mode + int flags = fcntl(fd, F_GETFL, nullptr) | O_NONBLOCK; + fcntl(fd, F_SETFL, flags); + + created_config->fd = fd; + created_config->deleter = vfs_destroy_socket; + , return false) + return true; +} diff --git a/components/esp_modem/src/esp_modem_vfs_uart_creator.cpp b/components/esp_modem/src/esp_modem_vfs_uart_creator.cpp new file mode 100644 index 000000000..f74fff8c8 --- /dev/null +++ b/components/esp_modem/src/esp_modem_vfs_uart_creator.cpp @@ -0,0 +1,64 @@ +// Copyright 2021 Espressif Systems (Shanghai) PTE LTD +// +// 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 +#include +#include +#include "esp_log.h" +#include "esp_modem_config.h" +#include "cxx_include/esp_modem_exception.hpp" +#include "exception_stub.hpp" +#include "uart_resource.hpp" +#include "vfs_resource/vfs_create.hpp" + +constexpr const char *TAG = "vfs_uart_creator"; + + +struct esp_modem_vfs_resource { + explicit esp_modem_vfs_resource(const esp_modem_uart_term_config *config, int fd) + : internal(config, nullptr, fd) {} + + esp_modem::uart_resource internal; +}; + + +static void vfs_destroy_uart(int fd, struct esp_modem_vfs_resource * resource) +{ + if (fd >= 0) { + close(fd); + } + delete resource; +} + +bool vfs_create_uart(struct esp_modem_vfs_uart_creator *config, struct esp_modem_vfs_term_config *created_config) +{ + if (!config->dev_name || created_config == nullptr) { + return false; + } + TRY_CATCH_OR_DO( + int fd = open(config->dev_name, O_RDWR); + esp_modem::throw_if_false(fd >= 0, "Cannot open the fd"); + + created_config->resource = new esp_modem_vfs_resource(&config->uart, fd); + created_config->fd = fd; + created_config->deleter = vfs_destroy_uart; + + // Set the FD to non-blocking mode + int flags = fcntl(fd, F_GETFL, nullptr) | O_NONBLOCK; + fcntl(fd, F_SETFL, flags); + + , return false) + + return true; +} diff --git a/components/esp_modem/test/host_test/sdkconfig.old b/components/esp_modem/test/host_test/sdkconfig.old deleted file mode 100644 index 58fe88b32..000000000 --- a/components/esp_modem/test/host_test/sdkconfig.old +++ /dev/null @@ -1,74 +0,0 @@ -# -# 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 diff --git a/components/esp_modem/test/target/main/NetworkDCE.cpp b/components/esp_modem/test/target/main/NetworkDCE.cpp index aacca55dd..bf6692a78 100644 --- a/components/esp_modem/test/target/main/NetworkDCE.cpp +++ b/components/esp_modem/test/target/main/NetworkDCE.cpp @@ -54,23 +54,10 @@ public: { // configure esp_modem_dte_config_t dte_config = ESP_MODEM_DTE_DEFAULT_CONFIG(); - esp_modem_dte_config_t dte_config2 = { - .dte_buffer_size = 512, - .vfs_config = {.port_num = UART_NUM_1, - .dev_name = "/dev/uart/1", - .rx_buffer_size = 1024, - .tx_buffer_size = 1024, - .baud_rate = 115200, - .tx_io_num = 25, - .rx_io_num = 26, - .task_stack_size = 4096, - .task_prio = 5} - }; esp_modem_dce_config dce_config = ESP_MODEM_DCE_DEFAULT_CONFIG(""); // create DTE and minimal network DCE - auto uart_dte = create_vfs_dte(&dte_config2); -// auto uart_dte = create_uart_dte(&dte_config); + auto uart_dte = create_uart_dte(&dte_config); dce = NetDCE_Factory::create(&dce_config, uart_dte, netif); return dce == nullptr ? ESP_FAIL : ESP_OK; }