#!/usr/bin/perl -w use strict; use Device::Modem; use Getopt::Long; use Unix::Syslog qw(:macros); use Unix::Syslog qw(:subs); use Config::General; use LockFile::Simple qw(lock trylock unlock); my ( $device, $verbose, $configfile, $symlink ); GetOptions( "device=s" => \$device, "verbose" => \$verbose, "symlink=s" => \$symlink, "configfile=s" => \$configfile); if( ! defined $device ) { die "--device must be given\n"; } my $devicepath="/dev/$device"; $configfile||="/etc/umts/pin.conf"; my $conf = new Config::General("$configfile"); my %config = $conf->getall; my $pin = $config{pin}{override}{pin}; $pin ||= $config{pin}{default}{pin}; openlog( "umts-pin", LOG_PID, LOG_USER); if( defined $config{pin}{send} && $config{pin}{send} eq "no" ) { syslog(LOG_INFO, "not sending PIN to %s, send pin is no in %s", $devicepath, $configfile); exit 0 } syslog(LOG_INFO, "sending PIN to %s", $devicepath); my $lockmgr = LockFile::Simple->make(-format => "/var/lock/LCK..%f", -stale => 1); my $lock = $lockmgr->lock("$device") or die "Can't lock $device\n"; my $modem; if( $verbose ) { $modem = new Device::Modem( port => "$devicepath", log => "syslog" ); } else { $modem = new Device::Modem( port => "$devicepath" ); } sub modemcommand { my ($command)=@_; if( $verbose ) { syslog(LOG_DEBUG, "send AT%s", $command); print "send AT$command\n"; } $modem->atsend("AT$command". Device::Modem::CR); } sub modem_parse_answer { my ($result,@lines)=$modem->parse_answer; if( $verbose ) { syslog(LOG_DEBUG, "result %s", $result); print "result $result\n"; foreach my $line( @lines ) { syslog(LOG_DEBUG, "line %s", $line); print "line $line\n"; } } return ($result, @lines); } sub pin_status { modemcommand( '+CPIN?' ); my ($result, @lines) = modem_parse_answer(); if( $result eq "OK" && grep(/^\+CPIN: SIM PIN$/, @lines) == 1 ) { return 0; } else { return 1; } } sub send_pin { modemcommand( "+CPIN=". $pin ); my ($result, @lines) = modem_parse_answer(); if( $result ne "OK" ) { syslog(LOG_ERR, "cannot send PIN: %s", $!); die "cannot send PIN: $!"; } } if( ! $modem->connect( baudrate => 115200 ) ) { syslog(LOG_ERR, "cannot connect to %s: %s", $devicepath, $!); die "cannot connect to $devicepath: $!\n"; } $modem->echo(0); $modem->attention(); my $result; modemcommand( '&F' ); $result = $modem->parse_answer(); if( !pin_status() ) { send_pin(); } if( !pin_status() ) { syslog(LOG_INFO, "first PIN attempt unsuccessful, sleeping 10 seconds", $devicepath, $!); sleep 10; send_pin(); } if( !pin_status() ) { syslog(LOG_ERR, "wrong PIN?", $devicepath, $!); die "wrong PIN?\n"; } $modem->disconnect; syslog(LOG_INFO, "PIN entered for %s", $devicepath); if ($verbose) { print "PIN entered for $devicepath\n"; } $lock->release; if( defined $symlink ) { symlink ("/dev/$device", "/dev/$symlink"); }