Sending SMS via GPRS modem using Perl Device::SerialPort
Sometimes ago, I posted a script to send SMS using Gammu. Now, I would like to deep dive on the underlying communication to GPRS modem using AT command to send SMS.
The sequence of AT commands to use are:
#!/usr/bin/perl
use POSIX;
use Device::SerialPort;
$modem_dev="/dev/ttyS1";
# change it to your mobile network SMSC number.
$smsc="+62811000000";
# to read modem response
sub readModem
{
if (!defined $_[0])
{
return;
} else {
my $tmout = 2;
my $ret = "";
while ($tmout>0)
{
my ($cnt,$saw) = $_[0]->read(255);
if ($cnt>0)
{
$ret.=$saw;
} else {
$tmout--;
}
select(undef,undef,undef,0.2);
}
return $ret;
}
}
$modem = Device::SerialPort->new($modem_dev);
if (defined $modem)
{
$modem->databits(8);
$modem->baudrate(115200);
$modem->parity("none");
$modem->stopbits(1);
$modem->stty_echo(0);
$modem->read_char_time(0); # don't wait each char
$modem->read_const_time(500); # spend 500ms to read data from serial line
} else {
print "Modem ".$modem_dev." is not available.\n";
exit();
}
$phone = $ARGV[0];
$msg = $ARGV[1];
$modem->write("ATZ\r\n");
$str = &readModem($modem);
$modem->write("ATE0\r\n");
$str = &readModem($modem);
$modem->write("AT+CMGF=1\r\n");
$str = &readModem($modem);
$modem->write("AT+CSCA=\"$smsc\",145\r\n");
$str = &readModem($modem);
# Some modems requires \r\n for this command
$modem->write("AT+CMGS=\"".$phone."\"\n");
#$modem->write("AT+CMGS=\"".$phone."\"\r\n");
$str = &readModem($modem);
# wait for 2 second for the prompt to appear
select(undef,undef,undef,2);\" : ".$str."\n";
$modem->write($msg.pack('c',26));
sleep(2);
$str = &readModem($modem);
$modem->close();
To use this script, you need to pass 2 arguments which are phone number as the first argument and the message as the second argument.
e.g:
# ./sendSMS "+62812344556" "Test SMS via Perl"
I hope this could help.
The sequence of AT commands to use are:
- ATZ : Reset modem
- ATE0 : Disable echo (not necessary)
- AT+CMGF : Setting the SMS mode (Text or PDU)
- AT+CSCA : Query or set the SMS center number
- AT+CMGS: Send SMS
#!/usr/bin/perl
use POSIX;
use Device::SerialPort;
$modem_dev="/dev/ttyS1";
# change it to your mobile network SMSC number.
$smsc="+62811000000";
# to read modem response
sub readModem
{
if (!defined $_[0])
{
return;
} else {
my $tmout = 2;
my $ret = "";
while ($tmout>0)
{
my ($cnt,$saw) = $_[0]->read(255);
if ($cnt>0)
{
$ret.=$saw;
} else {
$tmout--;
}
select(undef,undef,undef,0.2);
}
return $ret;
}
}
$modem = Device::SerialPort->new($modem_dev);
if (defined $modem)
{
$modem->databits(8);
$modem->baudrate(115200);
$modem->parity("none");
$modem->stopbits(1);
$modem->stty_echo(0);
$modem->read_char_time(0); # don't wait each char
$modem->read_const_time(500); # spend 500ms to read data from serial line
} else {
print "Modem ".$modem_dev." is not available.\n";
exit();
}
$phone = $ARGV[0];
$msg = $ARGV[1];
$modem->write("ATZ\r\n");
$str = &readModem($modem);
$modem->write("ATE0\r\n");
$str = &readModem($modem);
$modem->write("AT+CMGF=1\r\n");
$str = &readModem($modem);
$modem->write("AT+CSCA=\"$smsc\",145\r\n");
$str = &readModem($modem);
# Some modems requires \r\n for this command
$modem->write("AT+CMGS=\"".$phone."\"\n");
#$modem->write("AT+CMGS=\"".$phone."\"\r\n");
$str = &readModem($modem);
# wait for 2 second for the prompt to appear
select(undef,undef,undef,2);\" : ".$str."\n";
$modem->write($msg.pack('c',26));
sleep(2);
$str = &readModem($modem);
$modem->close();
To use this script, you need to pass 2 arguments which are phone number as the first argument and the message as the second argument.
e.g:
# ./sendSMS "+62812344556" "Test SMS via Perl"
I hope this could help.
Comments