Newline entering ^M in telnet console

Hey Everyone,

My apologies in advance for any missteps, first time poster, and general coding greenhorn.

Some general background information on hardware/software, I am using an Arduino Leonardo ETH 2 with PoE and Arduino IDE version 1.8.9. Computer is set to 192.168.0.1 and the Leonardo is set to 192.168.0.2 (I have confirmed communications).

I am attempting to have the Leonardo act as a Telnet server that I can access and send arbitrary strings to (aside from the command ‘cl’ to close the connection) and have it mirror said string back to me via the telnet client console. I’ve gotten right down to the leanest version I can where it simply allows a connection, gives a prompt, and allows me to type. It then breaks the input down into a character array and this is where I’m running into issues (I think).

My code is located @ https://github.com/ArcherK1162/Arduino-Leonardo-TelnetServer.git

Everything seems to work until I add the following call to parseReceivedText() in the getReceivedText() function;

void getReceivedText()
{
  char c;
  int charsWaiting;

  // copy waiting characters into textBuff
  //until textBuff full, LF received, or no more characters
  charsWaiting = client.available();
  do {
    c = client.read();
    textBuff[charsReceived] = c;
    charsReceived++;
    charsWaiting--;
  }
  while(charsReceived <= textBuffSize && c != 0xA && charsWaiting > 0);

  // if LF found go look at received text and execute command
  if(c == 0xA) {
   parseReceivedText();

  // after completing command, print a new prompt
   printPrompt();
  }

  // go back to loop until more characters are received

}

void parseReceivedText()
{
  for(int i=0;i<charsReceived ; i++ ){
    client.print(textBuff[i]);
  }

  if(textBuff[0] == 'c'){
    if(textBuff[1] == 'l'){
      closeConnection();
    }
  }
}

After the for loop is added to the parseReceivedText() function the Telnet client begins to return ^M characters on the 3rd iteration in place of a newline when hitting enter (as well as ^? in place of backspaces). Here is what my telnet console looks like;

Test Server

>Testing
Testing

>Testing
Testing

>Testing^M^M^M^M^M^M^M^M

I’ve attempted converted the char array into a string and printing it to client, but with the same result. But if I remove the for loop, though I obviously no longer get my input mirrored back, I can type many iterations of the loop no problem.

What does you code do if no characters are available to read? It still executes the do() loop once and attempts to read an empty buffer. You need to only do that reading when data is available

void getReceivedText()
{
  char c = 0;
  int charsWaiting;

  // copy waiting characters into textBuff
  //until textBuff full, LF received, or no more characters
  charsWaiting = client.available();
  while (charsReceived <= textBuffSize && c != 0xA && charsWaiting > 0) {
    c = client.read();
    textBuff[charsReceived] = c;
    charsReceived++;
    charsWaiting--;
  }

  // if LF found go look at received text and execute command
  if (c == 0xA) {
    parseReceivedText();

    // after completing command, print a new prompt
    printPrompt();
  }

  // go back to loop until more characters are received

}

void parseReceivedText()
{
  for (int i = 0; i < charsReceived ; i++ ) {
    client.print(textBuff[i]);
  }

  if (textBuff[0] == 'c') {
    if (textBuff[1] == 'l') {
      closeConnection();
    }
  }
}
/code]

blh64:
What does you code do if no characters are available to read? It still executes the do() loop once and attempts to read an empty buffer. You need to only do that reading when data is available

void getReceivedText()

{
  char c = 0;
  int charsWaiting;

// copy waiting characters into textBuff
  //until textBuff full, LF received, or no more characters
  charsWaiting = client.available();
  while (charsReceived <= textBuffSize && c != 0xA && charsWaiting > 0) {
    c = client.read();
    textBuff[charsReceived] = c;
    charsReceived++;
    charsWaiting–;
  }

// if LF found go look at received text and execute command
  if (c == 0xA) {
    parseReceivedText();

// after completing command, print a new prompt
    printPrompt();
  }

// go back to loop until more characters are received

}

void parseReceivedText()
{
  for (int i = 0; i < charsReceived ; i++ ) {
    client.print(textBuff[i]);
  }

if (textBuff[0] == ‘c’) {
    if (textBuff[1] == ‘l’) {
      closeConnection();
    }
  }
}
/code]

Yeah, if nothing is typed it still runs through the do portion then prompts the user again. I believe I could just rid the do portion and put it all behind the while, so the last portion of the if statement of charsWaiting should prevent it from running.

I believe I could just rid the do portion and put it all behind the while, so the last portion of the if statement of charsWaiting should prevent it from running.

Yep. The do/while statement has its place, but it is not normally used anywhere near as often as it is used (usually incorrectly) by newbies with Arduinos.

So after moving the do(while) content into a normal while loop, I got thrown into an infinite loop hell of prompts. I reverted back to the do(while) to do some debugging, nothing looks terribly out of the ordinary, when I just hit enter it starts at 1 for the newline character (I assume) then decrements to 0 and all is great. Just out of curiosity I adjusted the loops parameters to check to see if the current character ‘c’ isn’t a 0xA or 0xD, tossed everything into JUST a while loop, to see if that would amount to anything and looks like my infinite prompt hell is gone.

That’s one inefficiency cut out, but looks like my 3rd iteration with the for loop below still gives me those weird ^M characters instead of enter/newline.

for(int i=0;i<charsReceived ; i++ ){
    client.print(textBuff[i]);
  }

Well, thank you all for the words of wisdom, I found the issue.

The code is all good, it seems this was a mistake in my telnetting to the Leonardo. For some reason letting it default to port 23 was my mistake and not specifying port 23 in the telnet X.X.X.X 23 command. Not sure what difference specifying port 23 made as it was using 23 by default already, but it no longer gives me these off ^M characters.