diff --git a/components/esp_modem/include/cxx_include/esp_modem_command_library.hpp b/components/esp_modem/include/cxx_include/esp_modem_command_library.hpp index feba2febc..6e3729e13 100644 --- a/components/esp_modem/include/cxx_include/esp_modem_command_library.hpp +++ b/components/esp_modem/include/cxx_include/esp_modem_command_library.hpp @@ -22,6 +22,19 @@ namespace dce_commands { * @{ */ +/** + * @brief Generic AT command to be send with pass and fail phrases + * + * @param t Commandable object (anything that can accept commands) + * @param command Command to be sent do the commandable object + * @param pass_phrase String to be present in the reply to pass this command + * @param fail_phrase String to be present in the reply to fail this command + * @param timeout_ms Timeout in ms + */ +command_result generic_command(CommandableIf *t, const std::string &command, + const std::string &pass_phrase, + const std::string &fail_phrase, uint32_t timeout_ms); + /** * @brief Declaration of all commands is generated from esp_modem_command_declare.inc */ diff --git a/components/esp_modem/include/cxx_include/esp_modem_dce_factory.hpp b/components/esp_modem/include/cxx_include/esp_modem_dce_factory.hpp index 46113029a..a9aeead65 100644 --- a/components/esp_modem/include/cxx_include/esp_modem_dce_factory.hpp +++ b/components/esp_modem/include/cxx_include/esp_modem_dce_factory.hpp @@ -69,6 +69,10 @@ public: ESP_MODEM_THROW_IF_FALSE(netif != nullptr, "Null netif"); } + explicit Creator(std::shared_ptr dte): dte(std::move(dte)), device(nullptr), netif(nullptr) + { + } + ~Creator() { if (device != nullptr) { diff --git a/components/esp_modem/include/cxx_include/esp_modem_dte.hpp b/components/esp_modem/include/cxx_include/esp_modem_dte.hpp index d6be01856..2ee56099a 100644 --- a/components/esp_modem/include/cxx_include/esp_modem_dte.hpp +++ b/components/esp_modem/include/cxx_include/esp_modem_dte.hpp @@ -29,6 +29,13 @@ class CMux; * @{ */ +struct DTE_Command { + DTE_Command(const std::string &cmd): data((uint8_t *)cmd.c_str()), len(cmd.length()) {} + + uint8_t *data; + size_t len; +}; + /** * DTE (Data Terminal Equipment) class */ @@ -54,7 +61,9 @@ public: * @param len Data len to write * @return number of bytes written */ - int write(uint8_t *data, size_t len); + int write(uint8_t *data, size_t len) override; + + int write(DTE_Command command); /** * @brief Reading from the underlying terminal @@ -70,6 +79,8 @@ public: */ void set_read_cb(std::function f); + void on_read(got_line_cb on_data) override; + /** * @brief Sets DTE error callback * @param f Function to be called on DTE error diff --git a/components/esp_modem/include/cxx_include/esp_modem_types.hpp b/components/esp_modem/include/cxx_include/esp_modem_types.hpp index 80abbcfd9..513b1f847 100644 --- a/components/esp_modem/include/cxx_include/esp_modem_types.hpp +++ b/components/esp_modem/include/cxx_include/esp_modem_types.hpp @@ -80,6 +80,9 @@ public: */ virtual command_result command(const std::string &command, got_line_cb got_line, uint32_t time_ms, const char separator) = 0; virtual command_result command(const std::string &command, got_line_cb got_line, uint32_t time_ms) = 0; + + virtual int write(uint8_t *data, size_t len) = 0; + virtual void on_read(got_line_cb on_data) = 0; }; /** diff --git a/components/esp_modem/include/generate/esp_modem_command_declare.inc b/components/esp_modem/include/generate/esp_modem_command_declare.inc index 0b6c343c2..71a734f80 100644 --- a/components/esp_modem/include/generate/esp_modem_command_declare.inc +++ b/components/esp_modem/include/generate/esp_modem_command_declare.inc @@ -1,4 +1,4 @@ -// Copyright 2021 Espressif Systems (Shanghai) PTE LTD +// Copyright 2021-2022 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. @@ -11,36 +11,11 @@ // 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. +#pragma once -#ifndef _ESP_MODEM_COMMAND_DECLARE_INC_ -#define _ESP_MODEM_COMMAND_DECLARE_INC_ +#include "esp_modem_command_declare_helper.inc" -// Parameters -// * handle different parameters for C++ and C API -// * make parameter unique names, so they could be easily referenced and forwarded -#define _ARG(param, name) param -#define INT_IN(param, name) int _ARG(param, name) -#ifdef __cplusplus -#include -#define STRING_IN(param, name) const std::string& _ARG(param, name) -#define STRING_OUT(param, name) std::string& _ARG(param, name) -#define BOOL_IN(param, name) const bool _ARG(param, name) -#define BOOL_OUT(param, name) bool& _ARG(param, name) -#define INT_OUT(param, name) int& _ARG(param, name) -#define INTEGER_LIST_IN(param, name) const int* _ARG(param, name) - -#define STRUCT_OUT(struct_name, p1) struct_name& p1 -#else -#define STRING_IN(param, name) const char* _ARG(param, name) -#define STRING_OUT(param, name) char* _ARG(param, name) -#define BOOL_IN(param, name) const bool _ARG(param, name) -#define BOOL_OUT(param, name) bool* _ARG(param, name) -#define INT_OUT(param, name) int* _ARG(param, name) -#define INTEGER_LIST_IN(param, name) const int* _ARG(param, name) -#define STRUCT_OUT(struct_name, p1) esp_modem_ ## struct_name ## _t* p1 -#endif - #define DECLARE_ALL_COMMAND_APIS(...) \ /** * @brief Sends the initial AT sequence to sync up with the device @@ -331,5 +306,3 @@ public: #endif #endif - -#endif // _ESP_MODEM_COMMAND_DECLARE_INC_ diff --git a/components/esp_modem/src/esp_modem_dte.cpp b/components/esp_modem/src/esp_modem_dte.cpp index f5ad1339b..98e3ff687 100644 --- a/components/esp_modem/src/esp_modem_dte.cpp +++ b/components/esp_modem/src/esp_modem_dte.cpp @@ -202,6 +202,34 @@ int DTE::write(uint8_t *data, size_t len) return secondary_term->write(data, len); } +int DTE::write(DTE_Command command) +{ + return primary_term->write(command.data, command.len); +} + +void DTE::on_read(got_line_cb on_read_cb) +{ + if (on_read_cb == nullptr) { + primary_term->set_read_cb(nullptr); + internal_lock.unlock(); + return; + } + internal_lock.lock(); + primary_term->set_read_cb([this, on_read_cb](uint8_t *data, size_t len) { + if (!data) { + data = buffer.get(); + len = primary_term->read(data, buffer.size); + } + auto res = on_read_cb(data, len); + if (res == command_result::OK || res == command_result::FAIL) { + primary_term->set_read_cb(nullptr); + internal_lock.unlock(); + return true; + } + return false; + }); +} + /** * Implemented here to keep all headers C++11 compliant */