all: updated FSF address in GPL text
[sip-router] / modules / app_perl / lib / perl / Kamailio / Utils / PhoneNumbers.pm
1 #
2 # $Id$
3 #
4 # Perl module for Kamailio
5 #
6 # Copyright (C) 2006 Collax GmbH
7 #                    (Bastian Friedrich <bastian.friedrich@collax.com>)
8 #
9 # This file is part of Kamailio, a free SIP server.
10 #
11 # Kamailio is free software; you can redistribute it and/or modify
12 # it under the terms of the GNU General Public License as published by
13 # the Free Software Foundation; either version 2 of the License, or
14 # (at your option) any later version
15 #
16 # Kamailio is distributed in the hope that it will be useful,
17 # but WITHOUT ANY WARRANTY; without even the implied warranty of
18 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 # GNU General Public License for more details.
20 #
21 # You should have received a copy of the GNU General Public License
22 # along with this program; if not, write to the Free Software
23 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
24 #
25
26 # This file was kindly donated by Collax GmbH
27
28
29 =head1 Kamailio::Utils::PhoneNumbers
30
31 Kamailio::Utils::PhoneNumbers - Functions for canonical forms of phone numbers.
32
33  use Kamailio::Utils::PhoneNumbers;
34
35  my $phonenumbers = new Kamailio::Utils::PhoneNumbers(
36       publicAccessPrefix => "0",
37       internationalPrefix => "+",
38       longDistancePrefix => "0",
39       areaCode => "761",
40       pbxCode => "456842",
41       countryCode => "49"
42     );
43                                         
44  $canonical = $phonenumbers->canonicalForm("07612034567");
45  $number    = $phonenumbers->dialNumber("+497612034567");
46
47 A telphone number starting with a plus sign and containing all dial prefixes 
48 is in canonical form. This is usally not the number to dial at any location,
49 so the dialing number depends on the context of the user/system.
50
51 The idea to canonicalize numbers were taken from hylafax.
52
53 Example: +497614514829 is the canonical form of my phone number, 829 is the 
54 number to dial at Pyramid, 4514829 is the dialing number from Freiburg are and
55 so on.
56
57 To canonicalize any number, we strip off any dial prefix we find and 
58 then add the prefixes for the location. So, when the user enters the
59 number 04514829 in context pyramid, we remove the publicAccessPrefix 
60 (at Pyramid this is 0) and the  pbxPrefix (4514 here). The result 
61 is 829. Then we add all the general dial prefixes - 49 (country) 761 (area) 
62 4514 (pbx) and 829, the number itself => +497614514829 
63
64 To get the dialing number from a canonical phone number, we substract all
65 general prefixes until we have something 
66
67 As said before, the interpretation of a phone number depends on the context of
68 the location. For the functions in this package, the context is created through
69 the C<new> operator.
70
71 The following fields should be set:
72
73       'longDistancePrefix' 
74       'areaCode'
75       'pbxCode' 
76       'internationalPrefix'
77       'publicAccessPrefix'
78       'countryCode'
79
80 This module exports the following functions when C<use>ed:
81
82 =cut
83
84 package Kamailio::Utils::PhoneNumbers;
85
86 use Exporter;
87 our @ISA = qw(Exporter);
88 our @EXPORT = qw(
89              canonicalForm
90              dialNumber
91             );
92
93 =head2 new(publicAccessPrefix,internationalPrefix,longDistancePrefix,countryCode,areaCode,pbxCode)
94
95 The new operator returns an object of this type and sets its locational
96 context according to the passed parameters. See
97 L<Kamailio::Utils::PhoneNumbers> above.
98
99 =cut
100
101 sub new {
102         my $class = shift;
103         my %setup = @_;
104
105         my $self = {
106                 PAPrefix => %setup->{'publicAccessPrefix'},
107                 IDPrefix => %setup->{'internationalPrefix'},
108                 LDPrefix => %setup->{'longDistancePrefix'},
109
110                 Country => %setup->{'countryCode'},
111                 Area => %setup->{'areaCode'},
112                 PBX => %setup->{'pbxCode'}
113         };
114
115         bless $self, $class;
116
117         return $self;
118
119 }
120
121 =head2 canonicalForm( number [, context] )
122
123 Convert a phone number (given as first argument) into its canonical form. When
124 no context is passed in as the second argument, the default context from the
125 systems configuration file is used.
126
127 =cut
128 sub canonicalForm {
129   my $self = shift;
130   my $number  = shift;
131
132   $number =~ s/[^+0-9]*//g;                         # strip white space etc.
133
134   if( $number =~ m/^[^+]/ ) {
135     $number =~ s/^$self->{'PAPrefix'}$self->{'IDPrefix'}/+/;                          # replace int. dialing code
136     if( $number =~ m/^[^+]/ ) {
137       $number =~ s/^$self->{'PAPrefix'}$->{'LDPrefix'}/+$self->{'Country'}/;                # long distance number
138       if( $number =~ m/^[^+]/ ) {
139         $number =~ s/^$self->{'PAPrefix'}/+$self->{'Country'}$self->{'Area'}/;                  # local number
140         if( $number =~ m/^[^+]/ ) {
141            $number =~ s/^(.*)/+$self->{'Country'}$self->{'Area'}$self->{PBX}$1/;              # else cononicalize
142         }
143       }
144     }
145   }
146   return $number;
147 }
148
149 =head2 dialNumber( number [, context] )
150
151 Convert a canonical phone number (given in the first argument) into a number to
152 to dial.  WHen no context is given in the second argument, a default context
153 from the systems configuration is used.
154
155 =cut
156 sub dialNumber {
157         my $self = shift;
158         my $number  = shift;
159
160         $number =~ s/[^+0-9]+//g;                                                                                       # strip syntactical sugar.
161         $number =~ s/^$self->{'PAPrefix'}$self->{'IDPrefix'}$self->{'Country'}$self->{'Area'}$self->{'PBX'}//;          # inhouse phone call
162         $number =~ s/^$self->{'PAPrefix'}$self->{'IDPrefix'}$self->{'Country'}$self->{'Area'}/$self->{'PAPrefix'}/;     # local phone call
163         $number =~ s/^$self->{'PAPrefix'}$self->{'LDPrefix'}$self->{'Area'}$self->{'PBX'}//;                            # inhouse phone call
164         $number =~ s/^$self->{'PAPrefix'}$self->{'LDPrefix'}$self->{'Area'}/$self->{'PAPrefix'}/;                       # local phone call
165         $number =~ s/^$self->{'PAPrefix'}$self->{'IDPrefix'}$self->{'Country'}/$self->{'PAPrefix'}$self->{'LDPrefix'}/; # long distance call
166         $number =~ s/^$self->{'PAPrefix'}$self->{'PBX'}//;                                                              # inhouse call
167         $number =~ s/^[+]$self->{'Country'}$self->{'Area'}$self->{'PBX'}//;                                             # inhouse phone call
168         $number =~ s/^[+]$self->{'Country'}$self->{'Area'}/$self->{'PAPrefix'}/;                                        # local phone call
169         $number =~ s/^[+]$self->{'Country'}/$self->{'PAPrefix'}$self->{'LDPrefix'}/;                                    # long distance call
170         $number =~ s/^[+]/$self->{'PAPrefix'}$self->{'IDPrefix'}/;                                                      # international call
171
172         return $number;
173 }
174
175 1;