#!/opt/bin/perl use Device::SerialPort; #script global setting values my $port_path = "/dev/usb/tts/0"; my $basedir = '/opt/files/'; my $msgdir = '/opt/files/msg/'; my $logdir = '/opt/files/log/'; my $backupdir = '/opt/files/msg_backup/'; #my $backup = 1; my $log = 1; my $incomingfilemask = "in.msg"; my $outgoingfilemask = "out.msg"; my $sleeptime = 10; # intercycle sleep time in seconds if no new messages my $runcycles = 100; #if runcycles set more than 1000, script will run endless if($log ==1){ open (LOG,">>$logdir".'UDP.log') }else{ open (LOG,">/dev/null"); } my $run = 1; # serial port init section $port = new Device::SerialPort($port_path) or die "cannot open serial port:$!\n"; $port->baudrate(115200); #for siemens #$port->baudrate(921600); $port->parity("none"); $port->databits(8); $port->stopbits(1); $port->read_char_time(0); $port->read_const_time(1000); my %map; my %unmap; chdir ($basedir); loadMAP(); # init mobile phone send_at('AT+CMGF=0'); #set to receive unread messages send_at('AT+CPMS="ME"'); #set default storage to mobile # main cycle section while($run){ my @msg2del; my $rcvd_id = 0; my @mobile_out = split("\r",talk_mobile("AT+CMGL=4\r\n")); #print join ("\n",@mobile_out)."\n"; my $totalsize = 0; foreach $line ( @mobile_out){ $line =~ s/\n//g; if($line eq ''){ next}; if($line =~ /\+CMGL:/){ #print "AT response: $line\n"; ($header,$param) = split(/:/,$line); (@id) = split(/,/,$param); #print "msg id's:".join(':',@id)."\n"; $msg2del[$rcvd_id]= $id[0]; $rcvd_id ++; next; } $totalsize +=length($line); if($line =~/07/){ #print LOG $line."\n"; my $parserpos = 0; my $LoSMSC = hex(substr($line,$parserpos,2)); $parserpos = $LoSMSC*2+4; # jump over SMSC address my $LoMSISDN = hex(substr($line,$parserpos,2)); $parserpos += 2; my $toMSISDN = substr($line,$parserpos,2); $parserpos += 2; unless(int($LoMSISDN/2)*2 == $LoMSISDN){ $LoMSISDN ++; } $senderMSISDN = unpack_number(substr($line,$parserpos,$LoMSISDN)); $parserpos += $LoMSISDN+2; ## jump protocol identifier my $TP_DCS = hex(substr($line,$parserpos,2)); $parserpos +=2; my $TP_SCTS = swap_number(substr($line,$parserpos,14)); $parserpos +=14; my @TS = split('',$TP_SCTS); my $rcvd_date = $TS[4].$TS[5].$TS[2].$TS[3].'20'.$TS[0].$TS[1]; my $rcvd_time = $TS[6].$TS[7].$TS[8].$TS[9].$TS[10].$TS[11]; my $TP_UDL = hex(substr($line,$parserpos,2)); $parserpos +=2; my $msg_text = hex2ascii(substr($line,$parserpos,$TP_UDL*2)); my $msgfilename = "$msgdir/$incomingfilemask.$rcvd_date$rcvd_time.$senderMSISDN"; open (OUT,">$msgfilename") || print "cannot create $msgfilename"; #print "LoMSISDN=$LoMSISDN,MSISDN=$senderMSISDN,DCS=$TP_DCS,date=$rcvd_date $rcvd_time, msglen=$TP_UDL, pos=$parserpos\n"; print OUT $msg_text; close (OUT); }else{ #print "tag not found for $line\n"; } } while($rcvd_id >0){ my $msgid = $msg2del[$rcvd_id-1]; send_at('AT+CMGD='.$msgid)."\n"; $rcvd_id --; } #send outgong messages section if(opendir(MSGDIR,$msgdir)){ my @files = readdir(MSGDIR); foreach $msgfile (@files){ if($msgfile =~ /$outgoingfilemask/){ #print "processing outgoing message $msgfile..."; ($mask,$mask2,$date,$MSISDN) = split(/\./,$msgfile); if(open(MSGIN,$msgdir.$msgfile)){ while(<MSGIN>){ chomp; #reading text of the message if(defined($_)){send_SMS($MSISDN,$_)}; #print "to $MSISDN,text <$_>\n"; } close(MSGIN); system "rm $msgdir$msgfile"; }else {print "cannot open msg file $msgfile"}; } } closedir(MSGDIR); }else{ print LOG "cannot open outgoing message directory $msg_input_dir\n"; } if($runcycles ==0 ){ undef $run; }else{ unless($runcycles >= 1000){$runcycles --;}; sleep($sleeptime); } } close(LOG); sub send_SMS{ my ($MSISDN,$text) = @_; $TP_LOA = sprintf("%02X",length($MSISDN)); $TP_MSISDN = unpack_number($MSISDN); $TP_UD = ascii2hex($text); $TP_UDL = sprintf("%02X",length($TP_UD)/2); $TP_TOA = '91'; #international number $outline = $TP_SMSC.'1100'.$TP_LOA.$TP_TOA.$TP_MSISDN.'0008AA'.$TP_UDL.$TP_UD; $lout = length($outline)/2; $outline = '00'.$outline; if(defined($backup)){ if(open(BF,">$backupdir/$MSISDN.".int(1000*rand()))){ print BF $outline; close(BF); } } my @mobile_out = split("\r",talk_mobile("AT+CMGS=$lout\r\n")); my $totalsize = 0; my $prompt; foreach $line ( @mobile_out){ $line =~ s/\n//g; if($line =~ /\>/){$prompt = 1}; }; if($prompt ==1){ my @mobile_out = split("\r",talk_mobile($outline.chr(26))); my $totalsize = 0; foreach $line ( @mobile_out){ $line =~ s/\n//g; }; }else{ #no prompt from mobile - error } } sub hex2ascii{ my $inline = shift; my $lol = length($inline); #print "inline=<".$inline.">\n"; my $result = ''; my $seek = 0; while(defined($quad = substr($inline,$seek*4,4))){ $result .= $map{$quad}; $seek ++; } #print "length =$lol,$seek characters converted\n"; return $result; } sub ascii2hex{ my $inline = shift; my $result = ''; my $seek = 0; while(defined($char = substr($inline,$seek,1))){ unless($char eq ''){$result .= $unmap{$char}}; $seek ++; } return $result; } sub unpack_number{ my $result = ''; my $inline = shift; my $seek =0; $num_len = length($inline); if(($num_len - 2 * int($num_len / 2)) >0 ){ $inline .='F'; } while($pair = substr($inline,$seek*2,2)){ $result .= reverse($pair); $seek ++; } return ($result); } sub swap_number{ my $result = ''; my $inline = shift; my $seek =0; while($pair = substr($inline,$seek*2,2)){ $result .= reverse($pair); $seek ++; } return ($result); } sub send_at{ my $cmd = shift; my $result; my @mobile_out = split("\r",talk_mobile($cmd."\r\n")); my $totalsize = 0; foreach $line ( @mobile_out){ $line =~ s/\n//g; if($line eq 'OK'){ $result = 1; }elsif($line eq 'ERROR'){ $result = -1; } } } sub talk_mobile{ my $cmd = shift; $port->lookclear; $port->write("$cmd"); my $read_chars = 0; my $buffer = ""; my $eol =1; while($eol){ my ($count,$saw) = $port->read(255); if($count > 0){ $buffer.= $saw; if(($saw =~ /OK/)or($saw =~/ERROR/)or($saw =~/\>/)) {undef $eol} } } return $buffer; } sub loadMAP{ if(open(UCS,"UCS.map")){ $loaded = 0; while(<UCS>){ chomp; my ($code,$value)=split(/,/,$_,2); $map{$code} = $value; $loaded ++; } #print $loaded ." patterns loaded\n"; close(UCS); }else{ print "cannot open UCS.map file\n"}; if(open(UUCS,"UCS.unmap")){ $loaded = 0; while(<UUCS>){ chomp; my ($code,$value)=split(/,/,$_,2); $unmap{$code} = $value; $loaded ++; } close(UUCS); }else{ print "cannot open UCS.unmap file\n"};
Source: https://habr.com/ru/post/130391/
All Articles