I am trying to add some error detection to a script that is used to send SMS messages from our surveillance system. Most of the time it works like a charm but in some rare cases it stops sending the messages and we have no idea why.
We haven’t been able to reproduce the error so I’m wondering if anyone out there has had a similar problem. Below is the code that send the message and below that an idea I had that might be able to catch the error.
Here is the code that sends the message:
sub sendsms {
my ($number,$msg) = @_;
my $store = undef;
my $status = undef;
$msg =~ tr/\\[\]_'^~\{\}\|/\/\(\)\-"??\(\)!/; # \ -> /, [ -> (, ] -> ), ...., strippa út [ ] _ ' ^ ~ { } | \
$msg =~ tr/\xe1\xe9\xed\xf3\xfa\xfd\xf0\xfe\xe6\xf6\xc1\xc9\xcd\xd3\xda\xdd\xd0\xde\xc6\xd6/aeiouydtaoAEIOUYDTAO/;
for (my $i = 0; $i < length($msg); $i++) {
substr($msg,$i,1) = '_' if (ord(substr($msg,$i,1)) < 0x20 || ord(substr($msg,$i,1)) > 0x7f);
}
my $s = substr($msg,0,$maxlen);
RETRY: for (my $t = 0; $t < 5; $t++) {
eval {
put('AT+CMGD='.($next_store+1), 'OK');
put('AT+CSCA="'.$sca.'",145', 'OK');
put('AT+CMGF=1', 'OK');
put('AT+CMGW="'.$number.'",145', '>');
put($s, '>');
my $a = put("\x{1a}", undef);
print "a = '$a'\n" if ($verbose);
if ($a =~ /\+CMGW: ([0-9]*)/) {
$store = $1;
last RETRY;
}
};
if ($@) {
print "ERROR: attempt $t: $@\n";
}
sleep 2*($t+1);
}
if (defined $store) {
print "Message store $store\n" if ($verbose);
put('AT+CMSS='.$store.',"'.$number.'",145',undef);
$next_store = (($store - 1) + 1) % $stores;
}
else {
die "Message not stored";
}
}
The put function:
sub put {
my ($cmd,$expect) = @_;
print "Sending command '$cmd' expecting '$expect'\n" if ($verbose);
$modem->atsend($cmd."\r\n") || die "FAILED send\n";
my $a = $modem->answer();
die "Failed '$cmd' expected '$expect' got '$a'\n" if (defined $expect && !($a =~ /$expect/));
return $a;
}
Like I said earlier this works 99% of the time. The error seems to be that the messages are written to the store but never sent.
My idea:
eval {'$status = AT+CPAS'};
if (defined $status and ($status == '+CPAS: 1' or $status == '+CPAS: 2')){
print "Modem returned an error status: ".$status;
flush_stores();
sendsms('+xxxxxxxxxx', 'There is an error in the 3G modem');
}
Flush function:
sub flush_stores {
for (my $i = 0; $i < $stores; $i++) {
put('AT+CMGD='.($i+1), 'OK');
}
}
Will this work?
If not, what will?
Gísli
This seems to have been a hardware problem. We have replaced the 3G modem and SIM card and it’s all working smoothly for now. It would be interesting to know if there is any way to detect these kinds of failures.