AT Commands Server

API Reference

The AT commands Server handles AT commands' subscriptions on a requested serial device. The server is compliant with 3GPP 27.007, paragraphs 4.0, 4.1 and 4.2, and V25 ter, paragraphs 5.3, 5.4.

IPC interfaces binding

All the functions of this API are provided by the atService.

Here's a code sample binding to the AT commands server:

  atServerTest.atServerTestComp.le_atServer -> atService.le_atServer

AT command syntax

Syntax rules

To be interpreted, the command line sent to the AT commands server must start by the pattern "AT" (mean ATtention command).
Lowercase characters are changed to their uppercase equivalents. Only characters between quotes are not replaced.

The supported command formats are:

  • Basic syntax command:
    • using the format AT<command>[<number>]
      The command name is composed of one or several of those characters: A to Z, & and \.
    • the syntax of S command is also supported, like:
      • ATS<parameter_number>?
      • ATS<parameter_number>=<value>
    • D command is supported. The characters which don't belong to the following list are ignore:
      • V.250 dialing digits: 0 1 2 3 4 5 6 7 8 9 * # + A B C D
      • V.250 modifier characters: , T P ! W @
      • V.250 semicolon character: ;
      • GSM/UMTS modifier characters:
        • I or i for CLIR supplementary service subscription (I=invocation, i=suppression)
        • G or g for CUG supplementary service subscription (G=invocation, g=suppression)
        • Direct dialing from phonebook: > (if follow by a string, it has to be put between quote)
      All characters after the "D" are considered part of The D command parameter up to a semicolon or the end of command line.
  • Extended command format, with the following format:
    • action command with no parameters: AT+<name>
    • parameter command: AT+<name>=<value1>[,<value2>[,<value3>[...]]]
      Values must be separated by a coma. Some values may be optional: in that case, optional value can be omitted in the AT command (e.g. AT+ABCD=,1).
      A value is a string composed of one or several of the following characters: 0 to 9, A to F, H, h, *, #, +, -. To set a value with other characters, the value has to be set between quote.
    • test command (determine the supported values): AT+<name>=?
    • read command (determine the current values, or stored values): AT+<name>?[<value>]
      An optional parameter is supported.
'+' AT command starting character shall be replaced by other symbol, not included into a to z, A to Z, & and \.

Concatenating commands

Basic syntax command can be concatenated without a separator:

Additional commands (extended syntax command or basic syntax command) can be added after an extended syntax command with the insertion of a semicolon at the end of the command:

Extended syntax command can be concatenated after basic syntax commands without a separator:

Device Binding

le_atServer_Open() must be called to bind the file descriptor of the device with the AT commands server. Note that a socket can also be bound. Multiple devices can be bound. A file descriptor can be unbound using le_atServer_Close().

The server can be suspended using le_atServer_Suspend() in order to use the opened fd for other purposes like starting a PPP service on the opened fd. For that a fd dup needs to be done before opening a server session. When needed, the server can be resumed using le_atServer_Resume(). Make sure to close the fd when the application exists or you may get too many open files error.

used before opening a server session


A new AT command can be added into the parser using le_atServer_Create(), and it can be deleted using le_atServer_Delete(). le_atServer_EnableEcho() allows the user to enable echo on a selected device. le_atServer_DisableEcho() allows the user to disable echo on a selected device.


To handle the AT command, the application has to subscribe a handler using le_atServer_AddCommandHandler(). It can be removed with le_atServer_RemoveCommandHandler().

The called handler (le_atServer_CommandHandlerRef_t prototype) can use le_atServer_GetCommandName() to retrieve the received AT command string.

The device used to execute the AT command can be retrieve thanks to le_atServer_GetDevice().

It can also call le_atServer_GetParameter() to retrieve parameters of the AT command. This function gets the string sending through the AT command. If the parameter was sent between quotes, the quotes are removed. This API can be used for both formats:

  • In case of a basic format command (AT<command>[<number>]), if exists, the <number> can be retrieved at the index 0. For S command specific format (ATS<parameter_number>=<value>), the <parameter_number> is retrieved at the index 0, the <value> parameter at the index 1.
  • In case of an extended format command, parameters are retrieved thanks to their indexes, starting from 0. If the parameter is missed (e.g. "AT+CMD=,1"), the getting value is an empty string (i.e. '\0' with null length).

The handler receives in argument the type of the AT command (of le_atServer_Type_t type). Even if these types are specific to the extended format commands according to the standards, they are also applicable here to basic format commands to detect commands with parameters, or read values (e.g. ATS<parameter_number>?).

If the parameter is parsed with quotes, the quotes are removed when retrieving the parameter value using le_atServer_GetParameter() API. If a parmeter is not parsed with quotes, that parameter is converted to uppercase equivalent.

Registration Handler

The AT command handling mechanism may rely on an intermediate handler to reroute the AT commands to the atServer. le_atServer_AddCmdRegistrationHandler() installs such a registration handler that will be called each time a new command is subscribed by an application with le_atServer_AddCommandHandler().


Intermediate response

The application has can send intermediate responses through le_atServer_SendIntermediateResponse().

If le_atServer_SendIntermediateResponse() return LE_FAULT, the final response have to be sent.

Final result code

The application must return a final result code using le_atServer_SendFinalResultCode(). The corresponding device will be locked until the final response is sent.

If no answer is sent, the device will not accept any new AT commands (an error will be returned).

le_atServer_SendFinalResultCode() takes as arguments the AT command reference, a pattern (which is the prefix of the final response), a final response type as defined in le_atServer_FinalRsp_t and an error code identifier.

The final response type permits to the AT command Server to continue or stop the parsing of concatenated commands: if one command is failed, next commands are not executed, the final result of the concatenated AT command is the last error.

Unsolicited response

The application can also send unsolicited responses to warn a host application using le_atServer_SendUnsolicitedResponse().

This response is sent when no AT command is being processing on the device (i.e. unsolicited response is sent between the latest final response and the next reception of an AT command).

If an unsolicited response is sent when an AT command is in progress, the unsolicited response is buffered and sent as soon as the device becomes available (i.e., the processing AT command sends its final response).

Error codes

le_atServer_EnableExtendedErrorCodes() allows the user to use extended error codes on a selected device. When this mode is enabled, numerical codes are displayed when an error occurs. le_atServer_EnableVerboseErrorCodes() allows the user to enable verbose error codes on a selected device. Thus, instead of numerical codes, error are actually displayed as verbose messages. le_atServer_DisableExtendedErrorCodes() allows the user to disable the current error mode namely extended error codes or verbose error codes on a selected device.

User can create custom error codes using le_atServer_CreateErrorCode() by providing an error code identifier and a specific pattern. The pattern is a prefix of the final response string. Standard error codes use the patterns "+CME ERROR: " and "+CMS ERROR: " for instance. These standard patterns are defined in the following macros: CME_ERROR and CMS_ERROR. The code identifier should be equal or higher than 512 as the range [0, 511] is reserved for standard error codes defined in 3GPP 27.007 9.2 and TS 127.005 3.2.5.

le_atServer_CreateErrorCode() returns a reference which can be used to attach a custom verbose message to the error codes by calling le_atServer_SetVerboseErrorCode(). le_atServer_DeleteErrorCode() allows the user to drop an already registered error code.


le_atServer_GetTextAsync() allows the user to register a le_atServer_GetTextCallback_t callback to retrieve text and sends a prompt <CR><LF><greater_than><SPACE> on the current command's device.

It will receive at max LE_ATDEFS_TEXT_MAX_LEN bytes. If Esc Key is hit then the command is canceled and an empty buffer is returned with result set to LE_OK. If Ctrl+z is hit then the received buffer is returned and the result is set to LE_OK. In case of a read error, an empty buffer is returned with result set to LE_IO_ERROR;






It is easy to send text messages. <CTRL-Z>

+CMGS: 5



A second file descriptor can be used thanks to le_atServer_OpenBridge() to send all unknown AT commands to an alternative device (such as the modem). For all devices linked to that bridge using le_atServer_AddDeviceToBridge(), unknown commands will be sent through that file descriptor.

The bridge only works with AT commands that have the following terminal responses:

  • "OK"
  • "BUSY"
  • "ERROR"
  • "+CME ERROR"
  • "+CMS ERROR"

AT commands executed through the bridge do not support text mode (e.g.; +CMGS) or data mode (e.g.; ATD*99***1#). Sending these commands through the bridge may lock the Legato AT commands parser.

AT commands server is opened on the file descriptor fd1 using le_atServer_Open() API. AT commands server is bridged on the file descriptor fd2 using le_atServer_OpenBridge() API.

A device can be remove from a bridge thanks to le_atServer_RemoveDeviceFromBridge() API. A bridge can be closed using le_atServer_CloseBridge() API.

Some modem AT commands may conflict with Legato APIs; using both may cause problems that can be difficult to diagnose. The modem AT commands should be avoided whenever possible, and should only be used with great care.

The application can send an unsolicited on all opened device, or only one on a dedicated device.