Legato ATClient sends false newline characters

Hi,

I have been using the ATClient for some time now and I have noticed an issue when my device (WP7607-1) sends AT commands over the UART1 interface.

For example, when I format my command as follows: “AT\r\n”
I see the following output (in hex):

[2019-04-15_09:12:52]0D
[2019-04-15_09:12:52]41 54 0D 0A

As you see there is a ‘rogue’ ‘\n’ character preceding the actual command. This causes my AT server device to return an error, since it treats the ‘\n’ character as a command with no input.

How can I get rid of this ‘\n’ character preceding every command?

This issue is still not resolved. Any information is much welcome since it is blocking my development at the moment.

For atClient applications, you can only call APIs like “le_atClient_SetCommand()” or “le_atClient_SetCommandAndSend()” to fill your AT command string without “\r\n”. For example for the command “AT\r\n”, you just need call le_atClient_SetCommand(cmdRef, “AT”).

Thanks for your answer. But how do I configure line endings then? I can’t simply send “AT”, that is not sufficient for my application.

I did exactly this. I tried with UART1 set to canonical and raw mode, which made no difference at all, see logs below:

[2019-04-28_11:29:18]0D
[2019-04-28_11:29:18]41 54
[2019-04-28_11:29:23]0D
[2019-04-28_11:29:23]41 54
[2019-04-28_11:29:28]0D
[2019-04-28_11:29:28]41 54
[2019-04-28_11:29:33]0D
[2019-04-28_11:29:33]41 54
[2019-04-28_11:56:38]0D
[2019-04-28_11:56:38]41 54
[2019-04-28_11:56:43]0D
[2019-04-28_11:56:43]41 54
[2019-04-28_11:56:48]0D
[2019-04-28_11:56:48]41 54
[2019-04-28_11:56:53]0D
[2019-04-28_11:56:53]41 54
[2019-04-28_11:57:55]0D
[2019-04-28_11:57:55]54 45 53 54 31 32 33
[2019-04-28_11:58:00]0D
[2019-04-28_11:58:00]54 45 53 54 31 32 33
[2019-04-28_11:58:05]0D
[2019-04-28_11:58:05]54 45 53 54 31 32 33
[2019-04-28_11:58:10]0D
[2019-04-28_11:58:10]54 45 53 54 31 32 33

No need to add “\r” or “\r\n” at the end of the command string. atClient service will auto-matically apend “\r” at the end of the AT command string passed to “le_atClient_SetCommand()" or “le_atClient_SetCommandAndSend()”. You can refer to the sample code atClientTest.c in legato/apps/test/atServices/atClientTest/atClientTestComp for more details.

I ran the ATClientTest you mentioned a few times. Again, no “\r\n” to be found at the end and still every command starts with ‘0D’. Maybe you can try the same code on “dev/tty/HS0” (UART1)?

[2019-04-28_12:48:16]0D
[2019-04-28_12:48:16]41 54 2B 43 47 53 4E
[2019-04-28_12:51:20]0D
[2019-04-28_12:51:20]41 54 2B 43 47 53 4E

I don’t remember if the “\n” is apended by atClient Service code. I have never received such issue before. Is the UART1 connected to a sierra modem’s AT parser, or your own AT parser ? It could be an AT parser issue if connected to your own AT parser (your AT parser need support AT command started with “\n").

It is connected to an ESP32 AT parser. The ESP32 AT parser does not support commands starting with a ‘\n’ character thus it returns an error, or the uart on the esp32 simply gets stuck. I do not believe this is intended behaviour, starting commands with a newline is not documented anywhere for AT command client in legato docs.

Sorry, my mistake !
“0x0D” is ‘\r’ . Yes, atClient Service will apend ‘\r’ to each AT command string, so when you pass “AT” to le_atClient_SetCommand(), atClient Service will echo string “AT\r” to AT parser, this is designed behavior.
It’ very strange ,why the ‘\r’ is sent before the command in your log ? In atClient code, we DO apend ‘\r’ to the comand string as below:

        uint32_t len = strlen(cmdPtr->cmd)+2;
        char atCommand[len];
        memset(atCommand, 0, len);
        snprintf(atCommand, len, "%s\r", cmdPtr->cmd);

        le_dev_Write(&(interfacePtr->device),
                       (uint8_t*) atCommand,
                       len-1);

You are correct. I also sometimes mix up 0D with 0A… :wink:

But as you see in all my logs, ‘\r’ is always prepended before the command. So string “AT” will become “\rAT” instead of:

I have no idea what could be causing this, but if we assume the legato code contains no errors then it has to be in the UART1 driver, or maybe I am initializing some memory for holding the command string wrong?

Do you have suggestions on correct initialization for UART1 driver? If you have a few minutes spare maybe you can test/try my usecase. Note that I am using /dev/tty/HS0 instead the ‘standard’ /dev/tty/AT interface!

ps. I appreciate your help so far, it is good to have somebody thinking with me!

Yes, agree with you. It should be a UART1 driver issue ( maybe on ESP32 side) rather than a legato issue. You need first debug the UART1 port. For example check if the UART1 parameters are configured properly in your application and the module.

A simple way is stop legato and then run shell commands like " echo “AT” > /dev/ttyHS0 " or “microcom /dev/ttyHS0” and then check if expected command string is received on ESP32 .

Is it possible to share the code snippet and Legato log?

log level debug
logread -f

And if you connect WP7 /dev/ttyHS0 to your PC, what exactly is received?

Below my test using Legato 18.08 to send “AT” by ATClient to /dev/ttyHS0, host PC side it can receive the expected “AT\r” (41 54 0D)

May 3 01:42:20 swi-mdm9x28-ar758x user.debug Legato: DBUG | atClientDaemon[8183]/atClient T=atCommandClient-10 | le_dev.c PrintBuffer() 216 | ‘/dev/ttyHS0’ → AT<CR>

Thx

Hi Lotam,

I execute the following code snippet:

#include "legato.h"
#include "interfaces.h"

le_atClient_DeviceRef_t DevRef;
le_atClient_CmdRef_t cmdRef;

COMPONENT_INIT
{
    LE_INFO("ATClient test using UART 1 (/dev/ttyHS0.");

    const char *tty = "/dev/ttyHS0";
    int fd;

	/* Open UART1 for use in linux application */
	LE_INFO("Opening serial interface: %s", tty);
	fd = le_tty_Open(tty, O_RDWR | O_NOCTTY | O_NDELAY);
	LE_FATAL_IF(fd == 0, "Fatal error opening interface");

	/* Init the at client */
	DevRef = le_atClient_Start(fd);
    cmdRef = le_atClient_Create();

    /* Initialize the device */
    LE_ASSERT_OK(le_atClient_SetDevice(cmdRef, DevRef));
    LE_ASSERT_OK(le_atClient_SetCommand(cmdRef, "AT+TEST123"));
    LE_ASSERT_OK(le_atClient_SetFinalResponse(cmdRef, "OK|ERROR|+CME ERROR"));

    /* Send the command */
    le_atClient_Send(cmdRef);
}

In the past I also ran some code to initialize the UART1 interface but I do not include this in my program anymore.

I receive the following on a terminal program:
In text:
[2019-05-03_09:32:21]
[2019-05-03_09:32:21]AT+TEST123

In hex:
[2019-05-03_09:32:21]0D
[2019-05-03_09:32:21]41 54 2B 54 45 53 54 31 32 33

The log:

legato_atclient_log.txt (267.9 KB)

Hi Langestefan,
Thanks for the code and log, but sorry that I still cannot reproduce the issue at my environment.

Using your code, my PC (connect to ttyHS0 via USB-to-UART cable) can received expected:

[RX] - AT+TEST123
[RX] - 41 54 2B 54 45 53 54 31 32 33 0D (Hex)

May I ask the software version you are using?
If you are using modified Yocto, please test using official software from Sierra.

Another way to verify whether it is platform or Legato issue, please try below console command

stty -F /dev/ttyHS0 115200
echo -en “AT+TEST123\r” > /dev/ttyHS0

In which it should just send AT+TEST123<CR> so to see is it external factors.
And maybe test using different terminal software, PC or cable?

Thx

Hi Lotam,

Thanks for your reply.

May I ask, what is your UART1 configured for? I think I should use either “AT service mode” or linux application mode. I can set this option in developer studio.

Hi langestefan,

This must be set Linux application mode and I believe you already set it correctly, otherwise /dev/ttyHS0 will not available.

Thx

Yes, I did set it to Linux application mode. Unfortunately, my issue is still not solved. I performed the following steps:

I ran this command:

This command outputs exactly what I expect (I just use “AT” as my string in these commands):

First try:
[R] → [2019-05-07_13:44:40]41 54

Second try:
[R] → [2019-05-07_13:44:46]41 54

Now, when I run AT client software I see the following:

[R] → [2019-05-07_13:46:20]41 54
[R] → [2019-05-07_13:46:21]0D
[R] → [2019-05-07_13:46:21]41 54
[R] → [2019-05-07_13:46:22]0D
[R] → [2019-05-07_13:46:22]41 54

So, the ‘0D’ character is not being output immediately with the command string but it is ‘saved’ and prepended for the next command!

If I then switch back to the CLI and run echo -en “AT” > /dev/ttyHS0 I see:
[R] → [2019-05-07_13:46:50]0D
[R] → [2019-05-07_13:46:50]41 54

So it’s pretty clear to me that there is some issue with line endings in the output buffer of the AT command client.

Could you please try running the atclient in a loop? (so sending multiple commands in a row)

Hi langestefan,

Do you mean when you send below in CLI

echo -en “AT” > /dev/ttyHS0

Then you are getting the exact “AT” twice?

[R] → [2019-05-07_13:44:40]41 54

Do you have chance to try the exact lines in my previous response to include <CR> (“\r”) to see is <CR> received properly?

stty -F /dev/ttyHS0 115200
echo -en “AT+TEST123\r” > /dev/ttyHS0

Yes, in my test, I have modified your code to call le_atClient_Send() multiple times to re-send the “AT+TEST123”.

My result is expected, atClient does wait for response timeout (30sec) then send again.
Attached the UART data captured using app “realterm” on PC.
attest.txt (135 Bytes)

Again, may I ask what hardware/software you are using?
And what terminal app you are using on your PC?

Thx

Hi lotam,

Your comments made me investigate the reliability of the serial terminal program I was using. So to confirm that the issue was not on Legato side I hooked up the WP76 to a logic analyser. I was very surprised to see that the WP76 was indeed sending the right string of characters, and the issue was in my terminal program (which I have used for two years without any issues!). Nevertheless, the ESP32 could not handle the line endings of the Legato AT client. The error codes I saw previously where not connected to the output of my serial program. I made a mistake in thinking these two issues were connected, thus I blamed Legato.

I managed to solve this issue as well by modifying the line endings of the ESP32 stack. Communication between the two devices is now fully functional.

Thanks again for your help!