#!/usr/bin/perl # vim:set ft=perl sw=2: # 120705 PeterG # Copyright (C) 2012 PeterG. This program is free software: you # can redistribute it and/or modify it under the terms of the # GNU General Public License as published by the Free Software # Foundation, either version 2 of the License, or (at your # option) any later version. This program is distributed in the # hope that it will be useful, but WITHOUT ANY WARRANTY; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. use strict; use integer; my $INIT = 1; my $LINE = 0; my @MODES = ('no service','AMPS','CDMA','GSM/GPRS','HDR','WCDMA','GPS'); my @MODES2 = ('no service','GSM','GPRS','EDEG','WCDMA', 'HSDPA','HSUPA','HSDPA/HSUPA','TD-SCDMA','HSPA+'); my @SRVSTS = ('no service','restricted','valid','regional','standby'); my @SIMSTS = ('invalid','valid','invalid-if-CS','invalid-if-PS', 'invalid-if-PS-CS'); my $MODE = 'TBD'; my $MODE2 = 'TBD'; my $RSSI = 'TBD (TBD)'; my $SIMST = 'TBD'; my $SRVST = 'TBD'; my ($GREG,$LOC,$CELL) = ('TBD','TBD','TBD'); my $umts = $ARGV[0]; $umts = '/dev/ttyUSB2' if (undef $umts || $umts eq ''); open UMTS,"+<",$umts || die "open <> '$umts': $!"; while () { if ($INIT == 1) { print UMTS 'AT ^CURC=1',"\r\n"; # enable periodic reports print UMTS 'AT +CREG=2',"\r\n"; # enable cell state reporting print UMTS 'AT +CGREG=2',"\r\n"; # enable more cell state reporting print UMTS 'AT +CSQ',"\r\n"; # report SNR print UMTS 'AT +CGREG?',"\r\n"; # report cell state print UMTS 'AT ^SYSINFO',"\r\n"; # report overall state print UMTS 'AT ^SYSINFOEX',"\r\n"; # report overall extended state $INIT = 0; } next unless m/^[+^]/; my ($type,$values) = split /:/; $type =~ tr/a-z/A-Z/; $values =~ s/[\r\n]+$//; if ($type eq '^DSFLOWRPT') { # ^DSFLOWRPT:0000058A,000000E2,000000D4,00000000000088A9,0000000000007F1E,000AFC80,00280DE8 my ($etime,$tx,$rx,$txsofar,$rxsofar,$txmax,$rxmax) = map hex,(split /,/,$values); ($txmax,$rxmax) = map { $_ / (1024) } ($txmax,$rxmax); ($txsofar,$rxsofar) = map { $_ / (1024*1024) } ($txsofar,$rxsofar); my ($ehour,$emin,$esec) = (($etime/3600),($etime%3600)/60,$etime%60); my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); if ($LINE == 0) { # Periodic explicit reports. print UMTS 'AT +CSQ',"\r\n"; # report SNR print UMTS 'AT +CGREG?',"\r\n"; # report cell state print UMTS 'AT ^SYSINFO',"\r\n"; # report overall state print UMTS 'AT ^SYSINFOEX',"\r\n";# report overall extended state # Header. print "hh:mm:ss "; print "RX-BPS TX-BPS ELAPSED RX/TX-MIB ATTEN.DBM MODE CELL\n"; } printf "%02u:%02u:%02u ",$hour,$min,$sec; printf "%6u %6u %03u:%02u:%02u %5u/%-4u %-9s %-11s %-7s\n", $rx,$tx,$ehour,$emin,$esec,$rxsofar,$txsofar,$RSSI,$MODE2,$CELL; $LINE = ($LINE < 10) ? $LINE+1 : 0; } elsif ($type eq '^SYSINFOEX') { # ^SYSINFOEX:2,2,0,1,,3,"WCDMA",41,"WCDMA" my ($srvst,$srvdo,$roamst,$simst,$res1,$mode,$moden,$mode2,$moden2) = split /,/,$values; $SRVST = $SRVSTS[$srvst]; $SIMST = $SIMSTS[$simst]; ($MODE = $moden . '.') =~ tr /"//d; ($MODE2 = $moden2 . '.') =~ tr /"//d; } elsif ($type eq '^SYSINFO') { # ^SYSINFO:2,2,0,5,1,,4 my ($srvst,$srvdo,$roamst,$mode,$simst,$res1,$mode2) = split /,/,$values; $SRVST = $SRVSTS[$srvst]; $SIMST = $SIMSTS[$simst]; ($MODE,$MODE2) = ($MODES[$mode],$MODES2[$mode2]); } elsif ($type eq '^SRVST') { # ^SRVST:2 my $srvst = $values; $SRVST = $SRVSTS[$srvst]; } elsif ($type eq '^MODE') { # ^MODE:5,4 my ($mode,$mode2) = split /,/,$values; ($MODE,$MODE2) = ($MODES[$mode],$MODES2[$mode2]); } elsif ($type eq '^STIN') { # ^STIN:99,1,0 my ($a,$b,$c) = split /,/,$values; } elsif ($type eq '^SIMST') { # ^SIMST:1 $SIMST = $values; } elsif ($type eq '+CSQ') { # +CSQ: 18,99 $values =~ tr/ //d; my ($r,$ninenine) = split /,/,$values; $RSSI = convRssiToDbm($r); } elsif ($type eq '^RSSI') { # ^RSSI:18 $RSSI =convRssiToDbm($values); } elsif ($type eq '^CSNR') { # ^CSNR:-77,-12 } elsif ($type eq '+CGREG') { # +CGREG: 0 # +CGREG: 2,0 # +CGREG: 1, 999, 9C9999 # +CGREG: 2,1, 999, 9C9999 my $fields = 1 + ($values =~ tr/,//); $values =~ tr/ //d; if ($fields == 1) { ($GREG,$LOC,$CELL) = ('n.a.','n.a.','n.a.'); } elsif ($fields == 2) { my $n; ($n,$GREG,$LOC,$CELL) = ('','n.a.', 'n.a.', 'n.a.'); } elsif ($fields == 3) { ($GREG,$LOC,$CELL) = split /,/,$values; } elsif ($fields == 4) { my $n; ($n,$GREG,$LOC,$CELL) = split /,/,$values; } else { print; } } elsif ($type eq '+CREG') { # +CREG: 0 } elsif ($type eq '^BOOT') { # ^BOOT:3475052,0,0,0,99 } elsif (m/^[^ ]/) { print; } } exit 0; sub convRssiToDbm() { my ($r) = @_; if (($r >= 1) and ($r <= 30)) { return sprintf "%d (%u)",(($r-1)*2)-109,$r-1; } elsif ($r == 0) { return '< -113'; } elsif ($r == 31) { return '>= -51'; } elsif ($r == 99) { return 'unknown'; } return "???"; }