I have a problem with AT command for sending SMS - AT+CMGS. After sending AT+CMGS=<length of PDU datagram><CR> I wait for response of modem. After reading <CR><LF>><Space> I send <PDU datagram><CTRL-Z> but I don't get any answer from modem. If I send any command after that the response to that command is +CMGS=<reference number> which is exactly the response which I expected later.
But if I wait for about 100ms after reading <CR><LF>><Space> and than send PDU datagram than everything works well and I receive expected answer from modem.
It is really necessary to wait after receiving response from modem? I thought that I can send response immediately after reading <CR><LF>><Space>. Can someone help me to understand where could be a problem?
Thanks a lot
You are correct in your assumption, 27.005 states for AT+CMGS:
the TA shall send a four character sequence
<CR><LF><greater_than><space> (IRA 13, 10, 62, 32) after command line
is terminated with <CR>; after that text can be entered from TE to
ME/TA.
(TA (terminal adapter) is modem, TE (terminal equipment) is sender of AT commands)
However, in practice some additional small delay might be needed even in cases where the modem have signalled that it is ready to receive.
Related
I am writing an application which acts on commands received via SMS (in Python, but the problem occurs in other languages).
This page on the CMGL command shows the following command and response:
AT+CMGL="ALL"
+CMGL: 1,"REC UNREAD","+31628870634",,"11/01/09,10:26:26+04"
This is text message 1
+CMGL: 2,"REC UNREAD","+31628870634",,"11/01/09,10:26:49+04"
This is text message 2
OK
Most implementations I have looked at look for a valid status such as OK or ERROR to detect the end of the response.
I am trying to find a way to determine the difference between this status code and the end of the message.
Otherwise it would be possible for a malicious sender to send a message of
Hello<CR><LF>OK<CR><LF>+CMGL: 1,(rest of fake message...)
Because I am receiving data on the serial port, there is no clear way to tell when I have reached the end of one message from the GSM board.
Could anyone point me to some information on the best practice here please? Other implementations I have seen do not seem to cover this issue.
The only idea I have had so far (but feels quite messy) is to keep reading until a timeout has been hit. Then check the number of OK / ERROR lines in the message and only accept the last.
I am using a Huawei E303 modem and I am not seeing new messages via AT commands. Huawei's application "Mobile Partner" is able to read these messages but I don't understand how.
I have set AT+CMGF=1 and when I try AT+CPMS? I get +CPMS:"SM",0,30,"SM",0,30,"SM",0,30
When a new message arrives I get a +CTMI: "SM", 0 every single time. That value never increments. AT+CMGL="ALL" returns response OK but no messages.
I am now out of ideas. How can I read a message if counting them always returns zero?
What is amazing is that the Huawei application can read incoming messages, can send messages without any problems.
I am a developer, working on "Telit" GE865-Quad using AT commands.
I am planning an application, witch sends SMS when certain condition occurs. When the application does not send SMS the modem is shut-down (Therefore every time I want to send SMS I have to turn on the modem). This application sends 3 SMS to different numbers one after the other.
The application is working just fine. The problem apear after a while (after sending certain amount of SMS), when I give the command to send SMS I get "+CMS ERROR 41" ("Temporary failure"). Once this message appear, every time I try to send SMS I get the same ERROR - It is like the SIM card is stuck. The only way I have found to get rid of this error is to enter the SIM card to my privet phone and send SMS.
I have spoken to "Telit" representative and he could not give a satisfying answer other then adding more delay between messages.
This is some of the relevant code :
(Turning on sequence) // From "Telit" GE865-Quad DataSheet
> #QSS: 3 //Before I start working with the modem i wait for this response with means the SIM is ready to use and the registration is to cellular network is complete*/
AT+CMGF=1 // Text Mode
OK
AT+CMGS=+xxxxxxxxxxxx // My number.
"This is the message i want to send" //Preparing the desired message require some coding But I think this is irrelevant to the subject.
//Delay for 3 secs//
And again : AT+CMGS=+xxxxxxxxxxxx // My number.
"This is the message I want to send"
//Delay for 3 secs//
(The same thing one more time)
The questions are:
Why does it happen, what am I doing wrong??
How can I unblock the SIM? What does the phone do so I can keep sending SMS?
The purpose is the keep sending SMS automatically.
This is the first time I publish a message in this website so if something is unclear please let me know. :)
Thanks for all the helpers.
Itay.
today i encountered this +CMS ERROR: 41 error, many times.
There was about 40 unread messages in the receiving modem.
After i deleted all received messages error disappeared.
I think may be operator is protecting customers from spam.
Dmitri
It is due Either SMS service on your SIM is not available or your SMS subscription is expired.
I want to send notifications to apple devices in batches (1.000 device tokens in batch for example). Ant it seems that I can't know for sure that message was delivered to APNs.
Here is the code sample:
ssl_connection(bundle_id) do |ssl, socket|
device_tokens.each do |device_token|
ssl.write(apn_message_for device_token)
# I can check if there is an error response from APNs
response_has_an_error = IO.select([socket],nil,nil,0) != nil
# ...
end
end
The main problem is if network is down after the ssl_connection is established
ssl.write(...)
will never raise an error. Is there any way to ckeck that connection still works?
The second problem is in delay between ssl.write and ready error answer from APNs. I can pass timeout parameter to IO.select after last messege was sent. Maybe It's OK to wait for a few seconds for 1.000 batch, but wat if I have to send 1.000 messages for differend bundle_ids?
At https://zeropush.com, we use a gem named grocer to handle our communication with Apple and we had a similar problem. The solution we found was to use the socket's read_non_block method before each write to check for incoming data on the socket which would indicate an error.
It makes the logic a bit funny because read_non_block throws IO::WaitReadable if there is no data to read. So we call read_non_block and catch IO::WaitReadable before continuing as normal. In our case, catching the exception is the happy case. You may be able to use a similar approach rather than using IO.select(...).
One issue to be aware of is that Apple may not respond immediately and any notifications sent between a failing notification and reading from the socket will be lost.
You can see the code we are using in production at https://github.com/SymmetricInfinity/grocer/blob/master/lib/grocer/connection.rb#L30.
I am using Arduino to control an SM5100B GSM device, everything works except when I want to send an SMS after receiving another. I get this,
Error code:
O K > + C M G S : 2 5 O K + C M E E R R O R : 4
My code for handling the aforementioned received SMS:
#include <SoftwareSerial.h> //Include the NewSoftSerial library to send serial commands to the cellular module.
char inchar; //Will hold the incoming character from the Serial Port.
SoftwareSerial cell(2,3);
char mobilenumber[] = "0597010129";
void setup() {
//GSM
Serial.begin(9600); // opens serial port, sets data rate to 9600 bps
Serial.println("Initialize GSM module serial port for communication.");
cell.begin(9600);
delay(35000); // give time for GSM module to register on network etc.
Serial.println("delay off");
cell.println("AT+CMGF=1"); // set SMS mode to text
delay(200);
cell.println("AT+CNMI=3,3,0,0"); // set module to send SMS data to serial out upon receipt
delay(200);
}
void loop() {
if(cell.available() >0)//If a character comes in, from the cellular module
{
inchar=cell.read();
Serial.println(inchar);
if (inchar=='#'){ // OK - the start of our command
delay(10);
inchar=cell.read();
Serial.println(inchar);
if (inchar=='a'){
delay(10);
Serial.println("The folowing SMS : \n");
inchar=cell.read();
Serial.println(inchar);
if (inchar=='0'){ //sequance = #a0
Serial.println("#a0 was received");
}
else if (inchar=='1'){//sequance = #a1
Serial.println("#a1 was received ");
sendSms();
}
}
cell.println("AT+CMGD=1,4");// AT command to delete all msgs
Serial.println(" delete all SMS");
}
}//end of if(cell.available() >0) {...}
}
void sendSms(){
//cell.println("AT+CMGF=1"); // set SMS mode to text
cell.print("AT+CMGS="); // now send message...
cell.print((char)34); // ASCII equivalent of "
cell.print(mobilenumber);
cell.println((char)34); // ASCII equivalent of "
delay(500); // give the module some thinking time
cell.print(":D hello m3alleg :D"); // our message to send
cell.println((char)26); // ASCII equivalent of Ctrl-Z
delay(20000);
}
General note about your handling of AT commands.
No, no, no! This way of doing it will never work reliably. You MUST
wait for the > character to be received before sending "text
to send". Or actually it is not just the > character, it is four
characters. Quote from 3GPP specification 27.005:
the TA shall send a four character sequence
<CR><LF><greater_than><space> (IRA 13, 10, 62, 32) after command line
is terminated with <CR>; after that text can be entered from TE to
ME/TA.
(TA (terminal adapter) here means modem and TE (terminal equipment) the sender of AT commands)
For any abortable AT command (and 27.005 clearly states for AT+CMGS
This command should be abortable.) the sending of any character will
abort the operation of the command. To quote ITU V.250:
5.6.1 Aborting commands
...
Aborting
of commands is accomplished by the
transmission from the DTE to the DCE
of any character.
(DCE (data communication equipment) here means modem and DTE (data terminal equipment) the sender of AT commands)
This means that when you send "text to send" before "\r\n> " is sent
by the modem the command will be aborted. There is no way to wait "long
enough" for expecting the response be send. You MUST read and parse
the response text you get back from the modem.
The same applies for the final result code after each command (e.g. OK,
ERROR, CME ERROR and a few more). For instance sending "AT+CMGF=1"
and then sending the next command without first waiting for OK is begging
for problems. So always when sending AT commands, you MUST wait
for the final result code before sending the next command.
Please never, never use delay to wait for any AT command response. It's
as useful as kicking dogs that stand in your way in order to get them
to move. Yes it might actually work some times, but at some point you
will be sorry for taking that approach...
Answer to your question.
Based on the response you get, I can see that your problem is not command
abortion (although your parsing have serious problems as described above
that you should fix), and the CME ERROR is your best clue. From section
"9.2.1 General errors" in 27.007 it gives operation not supported as
description for value 4.
27.005 states that:
If sending fails in a network or an ME error, final result code +CMS ERROR: is returned.
Notice that this is +CMS ERROR and not +CME ERROR, but it is applicable, see below.
I guess that sequence of actions is as following:
The AT command handling part of the SM100B GSM modem accepts the sms data
and formats it in an appropriate format and sends it of to the part of the
modem that communicates with the GSM network. It successfully send the
sms data to the network and reports this back to the AT command handling
part which then prints +CMGS: 25 and final result code OK. However
after a short time the network sends back a rejection message for the sms,
which is then given as the +CME ERROR response.
If my guess above is correct, should the response have been delivered
as +CMS ERROR instead? No, because the final response
has for the AT+CMGS command has already been given (OK), and
returning multiple final result codes for a command should never be done
(except by mistake (note 1)).
And while +CME ERROR can replace the ERROR final result code,
it is not only a final result code. From the AT+CMEE command description:
Set command disables or enables the use of result code +CME ERROR: as an indication of an error relating to
the functionality of the MT. When enabled, MT related errors cause +CME ERROR: final result code instead
of the regular ERROR final result code. ERROR is returned normally when error is related to syntax, invalid parameters,
or TA functionality.
Thus +CME ERROR can both be an final result code as well as an unsolicited
result code (possibly also an intermediate result code).
But could not the AT+CMGS command have waited to receive the network
rejection and returned +CMS ERROR? Probably not. Without knowing too
much about the network details of sms sending, it might be the case
that rejection today might occur at a much later time than before. Such
changes are sometimes a problem with GSM related AT commands which have
an old heritage that was originally tightly tied to GSM behaviour which
some times becomes less and less true as the technology moves to GPRS,
UMTS, LTE, etc.
Note 1:
One of my former colleagues used to complain about the way the standard
have specified voice call handling, because after a ATD1234; command
you first get the final result code OK, and then later when the call is
ended you get a new final result code NO CARRIER. This just horribly
bad design, the call end indication should have been a specific unsolicited
response and not a final response.
So to summarise
Your sms seems to be rejected by the network. Try to find out why.
You also have some serious problems with your AT command handling
that you should fix; there is no way to handle AT commands without
reading and parsing the response text from the modem.
cell.println("AT+CNMI=3,3,0,0"); // set module to send SMS data to
serial out upon receipt
For anyone who is looking for answer to the same problem I had:
I was trying to wake up gsm module from sleep mode by sending sms and it didn't work right away. Phone call goes straight to UART, but for sms you have to use this command to set module to send SMS data to serial port upon receipt .
AT+CNMI=3,3,0,0