title: Writing a GSM modem driver?
body: <p>I've been working on an application which uses a GSM modem for one of two things; check its status using the built in HTTP stack by sending a GET request to the server, or sending data to the server (using UDP).  I have tried several different methods to keep this as reliable as possible, and I'm finally ready to ask for help.</p>
  
  <p>My application is written for the SIMCOM908 module and the PIC18 platform (I'm using a PIC18 Explorer for development).</p>
  
  <p>So the problem is sometimes the modem is busy doing something, and misses a command.  As a human, I would see that and just resend the command.  Adding a facility for my MCU to timeout and resend isn't an issue.</p>
  
  <p>What is an issue is that the modem sends unsolicited responses after different events.  When the modem changes registration status (with the cell tower) it would respond with <code>+CGREG: 1, ...</code> or when the GPS is ready <code>GPS Ready</code>.  These responses can happen at any time, including in the middle of a command (like creating an IP connection).</p>
  
  <p>This is a problem, because I haven't thought of a way to deal with this.  My application needs to send a command (to connect to the server for example, <code>AT+CIPSTART="UDP","example.com",5000</code>)  This command will response with 'OK', and then when the command has finished 'CONNECT OK'.  However, I need to be able to react to the many other possible responses, and I haven't figured out a way of doing this.  What do I need to do with my code to; wait for a response from the modem, check the response, perform an action based on that response?</p>
  
  <p>I am code limited (being an 8-bit microcontroller!) and would like the keep repetition to a minimum.  How can I write a response function that will take a response from the GSM module (solicited or now) and then let the rest of my program know what is happening?</p>
  
  <p>Ideally, I'd like to do something with those responses.  Like keep an internal state (when I hear <code>GPS Ready</code>, I know I can power the GPS etc.</p>
  
  <p>Maybe there are some things I should think about, or maybe there's an open source project that already solves this problem?</p>
  
  <p>Here's what I have so far:</p>
  
  <pre><code>/* Command responses */
  enum {
      // Common
      OK = 0,
      ERROR,
      TIMEOUT,
      OTHER,
      // CGREG
      NOT_REGISTERED,
      // CGATT
      NOT_ATTACHED,
      // Network Status
      NO_NETWORK,
      // GPRS status
      NO_ADDRESS,
      // HTTP ACTION
      NETWORK_ERROR,
      // IP Stack State
      IP_INITIAL,
      IP_STATUS,
      IP_CONFIG,
      UDP_CLOSING,
      UDP_CLOSED,
      UDP_CONNECTING
  } gsmResponse;
  
  int gsm_sendCommand(const char * cmd) {
      unsigned long timeout = timer_getCurrentTime() + 5000;
  
      uart_clearb(GSM_UART); // Clear the input buffer
      uart_puts(GSM_UART, cmd); // Send the command to the module
      while (strstr(bf2, "\r") == NULL) { // Keep waiting for a response from the module
          if (timeout &lt; timer_getCurrentTime()) { // Check we haven't timed out yet
              printf("Command timed out: %s\r\n", cmd);
              return TIMEOUT;
          }
      }
      timer_delay(100); // Let the rest of the response be received.
  
      return OK;
  }
  
  int gsm_simpleCommand(const char * cmd) {
      if (gsm_sendCommand(cmd) == TIMEOUT)
          return TIMEOUT;
  
      // Getting an ERROR response is quick, so if there is a response, this will be there
      if (strstr(bf2, "ERROR") != NULL)
          return ERROR;
  
      // Sometimes the OK (meaning the command ran) can take a while
      // As long as there wasn't an error, we can wait for the OK
      while (strstr(bf2, "OK") == NULL);
      return OK;
  }
  </code></pre>
  
  <p>A simple command is any AT command that is specifically looking for <code>OK</code> or <code>ERROR</code> in response.  Something like <code>AT</code>.  However, I also use it for more advanced commands like <code>AT+CPIN?</code> because it means I will have captured the whole response, and can further search for the <code>+CPIN: READY</code>.  However, none of this actually response to the unsolicited responses.  In fact, the <code>gsm_sendCommand()</code> function will return early when the unsolicited response is received.</p>
  
  <p>What a good way to manage complex, occasionally unsolicited, status messages like this?  Please take note that this application is written in C, and runs on an 8bit microcontroller!</p>