Advanced esp-modem use cases

This chapter outlines basic extensibility of the esp-modem component.

Custom instantiation with DCE factory

It is possible to create a modem handle in many different ways:

  • Build a DCE on top a generic module, user defined module or build the module only (in case the application will only use AT command interface)

  • Create the DCE as a shared, unique or a vanilla pointer

  • Create a generic DCE or a templated DCE_T of a specific module (this could be one of the supported modules or a user defined module)

All the functionality is provided by the DCE factory

group ESP_MODEM_DCE_FACTORY

DCE modem factory.

Enums

enum class ModemType

Specific modem choice when creating by the Factory.

Values:

enumerator GenericModule

Default generic module with the most common commands

enumerator SIM7600

Derived from the GenericModule, specifics applied to SIM7600 model

enumerator SIM7070

Derived from the GenericModule, specifics applied to SIM7070 model

enumerator SIM7000

Derived from the GenericModule, specifics applied to SIM7000 model

enumerator BG96

Derived from the GenericModule, specifics applied to BG69 model

enumerator SIM800

Derived from the GenericModule with specifics applied to SIM800 model

class FactoryHelper
#include <esp_modem_dce_factory.hpp>

Helper class for creating a user define pointer in a specific way, either as a plain pointer, shared_ptr or unique_ptr.

template<typename T_Module>
class Creator
#include <esp_modem_dce_factory.hpp>

Creator class for building a DCE_T<Module> in a specific way, either from a Module object or by default from the DTE and netif.

Throws

class Factory
#include <esp_modem_dce_factory.hpp>

Factory class for creating virtual DCE objects based on the configuration of the supplied module. This could also be used to create a custom module or a DCE_T<module>, provided user app derives from this factory.

Public Functions

template<typename ...Args>
inline std::unique_ptr<DCE> build_unique(const config *cfg, Args&&... args)

Create a default unique_ptr DCE generically, with the chosen module derived from the GenericModule.

Template Parameters

Args – Arguments to the builder, i.e. constructor of esp_modem::DCE_T class

Parameters
Returns

unique_ptr DCE of the created DCE on success

Public Static Functions

template<typename T_Module, typename ...Args>
static inline std::unique_ptr<DCE> build_unique(const config *cfg, Args&&... args)

Create a default unique_ptr DCE in a specific way (from the module)

Template Parameters
  • Module – Specific Module used in this DCE

  • Args – Arguments to the builder, i.e. constructor of esp_modem::DCE_T class

Parameters
Returns

unique_ptr DCE of the created DCE on success

template<typename T_Module, typename ...Args>
static inline DCE *build(const config *cfg, Args&&... args)

Create a DCE.

Template Parameters
  • Module – Specific Module used in this DCE

  • Args – Arguments to the builder, i.e. constructor of esp_modem::DCE_T class

Parameters
Returns

DCE pointer the created DCE on success

Create custom module

Creating a custom module is necessary if the application needs to use a specific device that is not supported and their commands differ from any of the supported devices. In this case it is recommended to define a new class representing this specific device and derive from the esp_modem::GenericModule (or any other available module, that’s close to your custom device). Then you can create the DCE using the DCE factory public method esp_modem::dce_factory::Factory::create_unique_dce_from().

Please note that the pppos_client example defines a trivial custom DCE which overrides one command, and adds a new command for demonstration purposes only.

It is also possible to create a specific DCE class that would conform to the generic DCE API and use all generic commands, work with commands differently. This might be useful to add some custom preprocessing of commands or replies. Please check the modem_console example with CONFIG_EXAMPLE_MODEM_DEVICE_SHINY=y configuration which demonstrates overriding default command() method to implement URC processing in user space.

Create new communication interface

In order to connect to a device using an unsupported interface (e.g. SPI or I2C), it is necessary to implement a custom DTE object and supply it into the DCE factory. The DCE is typically created in two steps:

  • Define and create the corresponding terminal, which communicates on the custom interface. This terminal should support basic IO methods defined in esp_modem::Terminal and derive from it.

  • Create the DTE which uses the custom Terminal

Please refer to the implementation of the existing UART DTE.