I'm developing a piece of embedded software, which also communicates with a modem through the AT protocol. Now I want to read messages, but I have come across a problem with my memory capacity. It could be that there are multiple messages for me, and using the AT command set, I get them returned all at once. I do not have the memory capacity to store them all to process them (I only have 1KB or so).
See the examples here: http://www.smssolutions.net/tutorials/gsm/receivesmsat/
AT+CMGL="ALL". I then get back something like:
+CMGL: 1,"REC UNREAD","+31625012354",,"07/07/05,09:55:16+08" Test message 1 +CMGL: 2,"REC UNREAD","+31625012354",,"07/07/05,09:56:03+08" Test message 2 OK
The problem here is that the message can contain certain directives, which trigger certain actions, which might take a while to execute. During that time, the buffer for receiving data from the modem can (will) overflow. On the other hand, I do not have the memory capacity to first read ALL the messages into memory to prevent the buffer overflow, and then process them from memory.
An alternative is reading a single message, with
AT+CMGR=2, getting back just one message:
+CMGL: 2,"REC UNREAD","+31625012354",,"07/07/05,09:56:03+08" Test message 2 OK
However, for this to work, I need know the storage location (2 in the above example).
My gut feeling tells me to first run
AT+CMGL, parsing the data and only keeping the storage locations, then requesting and parsing (and deleting) them one by one with
However, I would like to receive a second opinion. I'm not that experienced with AT nor with embedded software yet, so perhaps I'm overlooking something.
AT+CMGL="ALL" and save the first message up to the return. Ignore all other data until you receive
OK, indicating that the modem is done. After processing the first message, delete it by sending
AT+CMGD=<NUM> (where is the number of the first message). Repeat.
Yes, it's kind of ugly, but it works fine.
There is an unsolicited message that may be configured for newly received SMS messages. Take a look at this question for a bit more information on configuring the system.
Whenever you receive the
+CMTI message the index field (the number at the end of the string can be used when reading the message, just pass this value to the
AT+CMGR command to get the latest received message.
I would recommend deleting older (used) messages as most embedded type modules only have very limited memory for storing messages.
Another solution that I use. Send
AT+CPMS to read how many messages are stored in the SIM internal memory and what is the capacity (number of messages) of the memory.
AT+CPMS reports there is one or more messages waiting in the memory, send
AT+CMGR starting from position 1. You will end with one message (maybe at position 2 or 10) that you can receive and parse.
After processing it, delete it with
AT+CMGD (now you now what is its position).