Custom AT commands

The custom AT commands library allows any part of the application to register custom AT commands that are handled in the application. The list of custom AT commands are passed to the Modem library. This allows the application to add custom AT commands and to override modem AT calls with application callbacks while using the standard AT API of the Modem library.

Configuration

You can enable the custom AT commands library by setting the CONFIG_AT_CUSTOM_CMD Kconfig option.

Usage

To add a custom AT command or overwrite an existing command, you must add the AT commands filter and callback with the AT_CUSTOM_CMD macro in the at_custom_cmd.h file. If the filter matches the first characters of the AT command that is sent to the nrf_modem_at_cmd() function, the AT command is passed to the filter callback instead of to the modem. When returning from the callback, the content of the provided buffer is treated as the modem response and is returned to the nrf_modem_at_ API that sent the command.

Note

When the custom AT commands library is enabled, the application must not call the nrf_modem_at_cmd_filter_set() function because it overrides the handler set by the library. Instead, the application must add the AT filters using the AT_CUSTOM_CMD macro.

Adding a custom command

The application can define an custom command to receive a callback using the AT_CUSTOM_CMD macro. A custom AT command has a name, a filter string, a callback function, and a state. Multiple parts of the application can define their own custom commands. However, there can be only one callback per filter match. The filter uses the callback of the first match found in the list of custom commands. Hence, make sure to keep the filters accurate to avoid conflicts with other filters.

Note

The custom commands only trigger on calls to the nrf_modem_at_cmd() function. Calls to nrf_modem_at_printf(), nrf_modem_at_cmd_async(), and nrf_modem_at_scanf() are forwarded directly to the modem.

The following code snippet shows how to add a custom command that triggers on +MYCOMMAND calls to the nrf_modem_at_cmd() function:

/* AT filter callback for +MYCOMMAND calls */
AT_CUSTOM_CMD(my_command_filter, "AT+MYCOMMAND", my_command_callback);

     int my_command_callback(char *buf, size_t len, char *at_cmd);
     {
             printf("Callback for %s", at_cmd);
             return at_custom_cmd_respond(buf, len, "OK\r\n");
     }

AT command responses for custom commands

When returning from the callback, the content of the provided buf buffer is treated as the modem response by the Modem library. Hence, the following response format must match that of the modem:

  • The successful responses end with OK\r\n.

  • For error response, use ERROR\r\n, +CME ERROR: <errorcode>, or +CMS ERROR: <errorcode> depending on the error.

To simplify filling the response buffer, you can use the at_custom_cmd_respond() function. This allows formatting arguments and ensures that the response does not overflow the response buffer.

The following code snippet shows how responses can be added to the +MYCOMMAND AT command.

/* AT filter callback for +MYCOMMAND calls */
AT_CUSTOM_CMD(my_command_filter, "AT+MYCOMMAND", my_command_callback);

int my_command_callback(char *buf, size_t len, char *at_cmd);
{
        /* test */
        if(strncmp("AT+MYCOMMAND=?", at_cmd, strlen("AT+MYCOMMAND=?")) == 0) {
                return at_custom_cmd_respond(buf, len, "+MYCOMMAND: (%d, %d)\r\nOK\r\n", 0, 1);
        }
        /* set */
        if(strncmp("AT+MYCOMMAND=", at_cmd, strlen("AT+MYCOMMAND=")) == 0) {
                return at_custom_cmd_respond(buf, len, "OK\r\n");
        }
        /* read */
        if(strncmp("AT+MYCOMMAND?", at_cmd, strlen("AT+MYCOMMAND?")) == 0) {
                return at_custom_cmd_respond(buf, len, "+CME ERROR: %d\r\n", 1);
        }
}

Pausing and resuming

A custom AT command is active by default. A custom AT command can be paused and resumed with the at_custom_cmd_pause() and at_custom_cmd_resume() functions, respectively. You can pause a custom command at declaration by appending AT_CUSTOM_CMD_PAUSED to the filter definition.

The following code snippet shows how to resume a custom command that is paused by default:

/* AT filter callback for +MYCOMMAND calls */
AT_CUSTOM_CMD(my_command_filter, "AT+MYCOMMAND", my_command_callback, AT_CUSTOM_CMD_PAUSED);

int resume_my_command_filter(void)
{
        /* resume the filter */
        at_custom_cmd_resume(&my_command_filter);
}

int my_command_callback(char *buf, size_t len, char *at_cmd);
{
        return at_custom_cmd_respond(buf, len "OK\r\n");
}

API documentation

Header file: include/modem/at_custom_cmd.h
Source file: lib/at_custom_cmd/src/at_custom_cmd.c
group at_custom_cmd

Public API for adding custom AT commands using filters in the Modem library with application callbacks.

Defines

AT_CUSTOM_CMD_PAUSED
AT_CUSTOM_CMD_ACTIVE
AT_CUSTOM_CMD(entry, _filter, _callback, ...)

Define an custom AT command callback.

Parameters
  • entry – The entry name.

  • _filter – The (partial) AT command on which the callback should trigger.

  • _callback – The AT command callback function.

  • ... – Optional initial state ( AT_CUSTOM_CMD_PAUSED or AT_CUSTOM_CMD_ACTIVE ). The default is AT_CUSTOM_CMD_ACTIVE .

Functions

int at_custom_cmd_respond(char *buf, size_t buf_size, const char *response, ...)

Fill response buffer without overflowing the buffer.

Note

For the modem library to accept the response in buf as a success, the response must contain “OK\r\n”. If the response is an error, use “ERROR\r\n” or appropriate CMS/CME responses, e.g. “+CMS ERROR: <errorcode>”.

Parameters
  • buf – Buffer to put response into.

  • buf_size – Size of the response buffer.

  • response – Response format.

  • ... – Format arguments.

Return values
  • 0 – on success.

  • -NRF_EFAULT – if no buffer provided.

  • -NRF_E2BIG – if the provided buffer is too small for the response.

void at_custom_cmd_pause(struct nrf_modem_at_cmd_filter *entry)

Pause a custom AT command.

Parameters
  • entry – Pointer to the custom AT command to pause.

void at_custom_cmd_resume(struct nrf_modem_at_cmd_filter *entry)

Resume a custom AT command.

Parameters
  • entry – Pointer to the custom AT command to resume.