Add period to names
[tpope-extra.git] / perl / mobile-phone-monitor
1 #!/usr/bin/perl
2 # $Id$
3 # -*- perl -*- vim: ft=perl sw=4 sts=4
4
5 # Monitors a bluetooth mobile phome for calls.  You'll need to bind rfcomm1 to
6 # your mobile phone's SP service.  You'll also need my Device::Nokia module
7 # (the name is misleading, it's not Nokia specific).
8
9 use strict;
10 use Device::Nokia;
11 my $number;
12 my %status;
13
14 my $gsm = new Device::Nokia( port => '/dev/rfcomm1', log => 'file,/dev/null');
15
16 $SIG{INT}  = 'death';
17 $SIG{TERM} = 'death';
18 $SIG{QUIT} = 'death';
19
20 sub initialize {
21     my $gsm=shift;
22     $gsm->connect() || return 0;
23     $gsm->atsend( 'AT+CLIP=1' . Device::Modem::CR );
24     $gsm->answer();
25     return 1;
26 }
27
28 initialize($gsm) || die "Could not initialize modem: $!";
29
30 daemonize() if (shift eq "-d");
31
32 while(1) {
33 %status=("is_active"=>1);
34 while($status{"is_active"} ne 0) {
35     for(my $i=0;$i<8;$i++) {
36         sleep 1;
37         $number = wait_for_ring();
38         if($number) {
39             $status{"number"} = $number;
40             output_status(%status);
41             ring($number);
42             last;
43         } elsif(!defined($number)) { $status{"is_active"}=0; last; };
44     }
45     my %newstatus=gather_data($gsm);
46     ring() if($newstatus{"call"}!=0 && $status{"call"}!=0);
47     foreach (keys %newstatus) {
48         $status{$_} = $newstatus{$_} if(defined ($newstatus{$_}));
49     }
50     undef $status{"number"} if (!$number && $status{"callsetup"}==0 && $status{"call"}==0);
51     output_status(%status);
52 }
53 $gsm->disconnect();
54 #print "Chillin'...\n";
55 output_status(is_active => 0);
56 do {sleep 60}
57 until(initialize($gsm));
58 }
59
60 sub wait_for_ring {
61     local $_;
62     eval {
63         local $SIG{ALRM} = sub { die "alarm\n" };
64         alarm 5;
65         $_ = $gsm->answer("\\+CLIP: \"[0-9]+\",[0-9]+\$", 30);
66         alarm 0
67     };
68     if($@) {
69         die unless $@ eq "alarm\n";
70         return undef;
71     } else {
72         m/CLIP: "([0-9]+)",/;
73         return "$1";
74     }
75 }
76
77 sub ring {
78     system($ENV{"HOME"} . "/bin/phone-call " . $_[0]);
79 }
80
81 sub gather_data {
82   my %data;
83   my $gsm=shift;
84     eval {
85         local $SIG{ALRM} = sub { die "alarm\n" };
86         alarm 15;
87   %data=$gsm->indicators();
88   my ($first, $second) = $gsm->battery_strength();
89   $data{"source"}=$first;
90   $data{"battery"}=$second;
91   ($first, $second) = $gsm->signal_quality();
92   $data{"signal"}=$first;
93   alarm 0;
94   };
95     if($@) {
96         die unless $@ eq "alarm\n";
97         return (is_active => 0);
98     } else {
99         $data{"is_active"}=$gsm->is_active() && $data{"signal"} && 1 || 0;
100         return %data;
101     }
102 }
103
104 sub output_status {
105     my %status = @_;
106     open STATUS, ">/tmp/.phone-status.new" || die $!;
107     foreach my $indicator (sort keys %status) {
108         print STATUS "$indicator=" . $status{$indicator} . "\n";
109     };
110     close STATUS;
111     rename "/tmp/.phone-status.new", "/tmp/.phone-status" || die $!;
112 }
113
114
115 sub daemonize {
116     chdir "/";
117     my $pid=fork();
118     if($pid) {
119         exit(0)
120     }
121     elsif(defined($pid))
122     {
123         close STDIN;
124         close STDOUT;
125         close STDERR;
126     }
127     else { exit(1); }
128 }
129
130 sub death {
131     $gsm->disconnect() if($gsm);
132     unlink "/tmp/.phone-status.new", "/tmp/.phone-status";
133     exit(0);
134 }