SparkFun Forums 

Where electronics enthusiasts find answers.

For the discussion of Arduino related topics.
By GForce2010
#198140
I need help, hopefully just a push in the correct direction.

I have written a simple sketch that connect to a telnet server.

The server responds with some information I need to capture and store for use later.

Below is an example of what the server sends me.
Code: Select all
RL3]\[Test 1}|{3}|{S]\[Test 2}|{41}|{L]\[Test 3}|{1234}|{L
The RL shows that this line is a Roster List, the number after is how many items in this list.

I have the code that can read through the message and identifies when the roster lists begins and I read the number into an integer.

What I need is to be able to save the data to however many variables I need. The amount in the roster list will vary.

From the example above i need the following: -
Code: Select all
Test 1, 3, S
Test2, 41, L
Test 3, 1234, L
This is what I have so far.
Code: Select all
void read() {
  
String content = "";
  char character;

  while(client.available()) {
      character = client.read();
      if (character == 'R') {
        character = client.read();
        if (character == 'L') {

          //We are in the roster list section
          Serial.println("Roster list seen");
          roster = client.parseInt();  //sets how many items in roster

        } 
      }
      content.concat(character);
  }


}
Any help appreciated.

Thanks.
#198147
Below is completely UNTESTED code, but I expect it will can set you in the right direction.

It is better to break down the code is smaller subroutines, read the complete line in one-go and then parse it.
Code: Select all
///////////////// define global ///////////////////
#define NAME_SIZE 15
#define MAXBUF 100

// structure to capture RL entries
struct rl_entry{
  char          name[15]; // store name
  uint8_t       var1;     // variable 1
  char          var2;     // variable 2
} rl_entry;

// variables used on more places
struct rl_entry *content;

char buffer[MAXBUF];     // read all the character in a buffer
////////////////////////////////////////////////

void loop1()
{
    int num_bytes, entry_cnt;

    // read all the data from remote
    num_bytes = read_line();
    
    // if anything received
    if (num_bytes > 0)
    {
        entry_cnt = find_header();

        // found entry count
        if (entry_cnt > 0)
        {
            // allocate memory to store content
            get_memory(entry_cnt);

            // parse content
            parse_content(entry_cnt);

            // do something with that content that you want to do
            handle_content(entry_cnt);

            // free allocated memory
            free(content);
        }
    }
}

/* check for data from remote and store in buffer */
int read_line()
{
  int  ind = 0;

 while(client.available())
  {
      buffer[ind++] = client.read();

      if (ind == MAXBUF-1)
      {
          Serial.println(F("buffer limit reached"));
          break;            // stop the while loop
      }

      //potential 10ms delay (not sure how fast the connection is)
      delay(10);
  }

  //terminate
  buffer[ind]= 0x0;

  return(ind);
}
/* Find RL and return the entry count */
int find_header()
{
    char *q = strstr(buffer, "RL");

    if (q != NULL)
    {
        q += 2;     // skip RL
        return(atoi(*q));
    }
    return(0);
}

/* get memory for structure */
void get_memory(int cnt)
{
    // allocate enough memory to store the content
    content = (struct rl_entry *) malloc(cnt * sizeof(struct rl_entry));

    if (!content) {
        Serial.println(F("could not allocate memory"));
        fail();
    }
}

/* parse content into the global structure
 * format expected : RL3]\[Test 1}|{3}|{S]\[Test 2}|{41}|{L]\[Test 3}|{1234}|{L] */
void parse_content(int entry_cnt)
{
    char temp[10];
    int  i, cur_entry = 0;
    char *p, *q = buffer;

    while (cur_entry < entry_cnt)
    {
        ////////////////////// get name //////////////////////////
        
        // look for begin of name entry
        q = strstr(q,"]/[");

        // if found, now look for end of name entry
        if (q != NULL)  p = strstr(q, "}|{");

        // did we find begin & end of name entry
        if(q == NULL || p == NULL)
        {
            Serial.println(F("input format error: name"));
            Serial.println(buf);
            fail();
        }

        q += 3; // skip ]\[ to start of name
        i=0;

        // store name in structure
        while (q < p && i < NAME_SIZE) content[cur_entry].name[i++] = *q++;
        content[cur_entry].name[i]= 0x0; 
        
        ////////////////////// get variable 1 //////////////////////////
        
        q = p + 3;  // skip }|{ to start of variable 1
        p = strstr(q, "}|{");

        // did not find end of variable 1 entry
        if (p == NULL)
        {
            Serial.println(F("input format error: variable 1"));
            Serial.println(buf);
            fail();
        }

        i=0;

        // get first variable
        while (q < p && i < 10) temp[i++] = *q++;
        temp[i] = 0x0;

        // store as integer in structure
        content[cur_entry].var1 = atoi(temp);

        ////////////////////// get variable 2 //////////////////////////
        
        q = p + 3;  // skip }|{ to begin variable 2
        p = strstr(q, "]");

        // did not find end of second/ last variable entry (one character
        if(p == NULL ||  p - q != 1)
        {
            Serial.println(F("input format error: variable 2"));
            Serial.println(buf);
            fail();
        }

        // store last variable
        content[cur_entry].var2 = *q;
  }
}

/* do something with the received information */
void handle_content(int entry_cnt)
{
  
}