File Coverage

blib/lib/GSM/ARFCN.pm
Criterion Covered Total %
statement 76 79 96.2
branch 38 40 95.0
condition 21 33 63.6
subroutine 11 11 100.0
pod 8 10 80.0
total 154 173 89.0


line stmt bran cond sub pod time code
1             package GSM::ARFCN;
2 2     2   45471 use strict;
  2         5  
  2         1771  
3             our $VERSION ='0.04';
4              
5             =head1 NAME
6              
7             GSM::ARFCN - Absolute Radio Frequency Channel Number (ARFCN) Converter
8              
9             =head1 SYNOPSIS
10              
11             use GSM::ARFCN;
12             my $ga=GSM::ARFCN->new(24);
13             my $frequency=$ga->fdl;
14              
15             =head1 DESCRIPTION
16              
17             The Absolute Radio Frequency Channel Number (ARFCN) is a unique number given to each radio channel in GSM Radio Communication Band plan. The ARFCN can be used to calculate the frequency of the radio channel.
18              
19             The ARFCNs used in GSM-1900 band (US PCS-1900) overlap with the ARFCNs used in GSM-1800 band (DCS-1800). In the GSM-1900 band plan, the ARFCNs 512 to 810 are different frequencies than the same channel numbers in the GMS-1800 band plan. A multiband mobile phone will interpret ARFCN numbers 512 to 810 as either GSM-1800 or GSM-1900 frequencies based on a band plan indicator.
20              
21             For this package to interpret ARFCN numbers 512 to 810 as either GSM-1800 or GSM-1900 frequencies, set the additional parameter band plan indicator (i.e. "bpi") to either "GSM-1800" or "GSM-1900" (DEFAULT) to make the correct interpretation.
22              
23             =head1 USAGE
24              
25             use GSM::ARFCN;
26             my $frequency=GSM::ARFCN->new(24)->fdl; #MHz
27              
28             Looping without blessing a new object each time
29              
30             use GSM::ARFCN;
31             my $ga=GSM::ARFCN->new;
32             foreach my $channel (0 .. 1023) {
33             $ga->channel($channel); #sets channel and recalculates the object properties
34             printf "Channel: %s;\tBand: %s\tUplink: %s MHz,\tDownlink: %s MHz\n", $ga->channel, $ga->band, $ga->ful, $ga->fdl
35             if $ga->band;
36             }
37              
38             =head1 CONSTRUCTOR
39              
40             =head2 new
41              
42             my $obj=GSM::ARFCN->new; #blesses empty object; no channel set
43             my $obj=GSM::ARFCN->new(24); #default bpi=>"GSM-1900"
44             my $obj=GSM::ARFCN->new(channel=>24); #default bpi=>"GSM-1900"
45             my $obj=GSM::ARFCN->new(channel=>24, bpi=>"GSM-1800"); #specify band plan indicator
46              
47             =cut
48              
49             sub new {
50 6     6 1 25 my $this = shift();
51 6   33     38 my $class = ref($this) || $this;
52 6         10 my $self = {};
53 6         9 bless $self, $class;
54 6         16 $self->initialize(@_);
55 6         14 return $self;
56             }
57              
58             sub initialize {
59 6     6 0 10 my $self=shift;
60 6 100       13 if (scalar(@_) == 1) {
61 1         5 %$self=(channel=>shift);
62             } else {
63 5         18 %$self=@_;
64             }
65 6 100       14 $self->bpi("GSM-1900") unless $self->bpi;
66 6 100       11 $self->calculate if defined $self->channel;
67             }
68              
69             sub calculate {
70 30     30 0 31 my $self=shift;
71 30         53 my $n=$self->channel;
72 30         42 my $cs=$self->{'cs'}=0.2;
73 30 100 66     478 if ($n ==0) {
    100 66        
    100 66        
    100 66        
    100 33        
    50 66        
    100 66        
    100 66        
    100 100        
    100 66        
    100          
74 1         3 $self->{"band"}="EGSM-900";
75 1         2 $self->{"fs"}=45;
76 1         4 $self->{"ful"}=890 + $cs * $n;
77              
78             } elsif ($n >= 1 and $n <= 124) {
79 8         21 $self->{"band"}="GSM-900";
80 8         15 $self->{"fs"}=45;
81 8         17 $self->{"ful"}=890 + $cs * $n;
82              
83             } elsif ($n >= 128 and $n <= 251) {
84 2         22 $self->{"band"}="GSM-850";
85 2         3 $self->{"fs"}=45;
86 2         5 $self->{"ful"}=824.2 + $cs * ($n - 128);
87              
88             } elsif ($n >= 259 and $n <= 293) {
89 2         3 $self->{"band"}="GSM-450";
90 2         3 $self->{"fs"}=10;
91 2         6 $self->{"ful"}=450.6 + $cs * ($n - 259);
92              
93             } elsif ($n >= 306 and $n <= 340) {
94 2         3 $self->{"band"}="GSM-480";
95 2         2 $self->{"fs"}=10;
96 2         6 $self->{"ful"}=479 + $cs * ($n - 306);
97              
98             } elsif ($n >= 350 and $n <= 425) {
99 0         0 $self->{"band"}="TGSM-810";
100 0         0 $self->{"fs"}=10;
101 0         0 $self->{"ful"}=806 + $cs * ($n - 350);
102              
103             } elsif ($n >= 438 and $n <= 511) {
104 2         6 $self->{"band"}="GSM-750";
105 2         3 $self->{"fs"}=30;
106 2         7 $self->{"ful"}=747.2 + $cs * ($n - 438);
107              
108             } elsif ($n >= 512 and $n <= 810) {
109 4 100       11 if ($self->bpi eq "GSM-1800") {
110 2         4 $self->{"band"}="GSM-1800";
111 2         3 $self->{"fs"}=95;
112 2         6 $self->{"ful"}=1710.2 + $cs * ($n - 512);
113             } else {
114 2         5 $self->{"band"}="GSM-1900";
115 2         2 $self->{"fs"}=80;
116 2         6 $self->{"ful"}=1850.2 + $cs * ($n - 512);
117             }
118              
119             } elsif ($n >= 811 and $n <= 885) {
120 2         4 $self->{"band"}="GSM-1800";
121 2         3 $self->{"fs"}=95;
122 2         7 $self->{"ful"}=1710.2 + $cs * ($n - 512);
123              
124             } elsif ($n >= 955 and $n <= 974) {
125 2         3 $self->{"band"}="RGSM-900";
126 2         3 $self->{"fs"}=45;
127 2         8 $self->{"ful"}=890 + $cs * ($n - 1024);
128              
129             } elsif ($n >= 975 and $n <= 1023) {
130 3         5 $self->{"band"}="EGSM-900";
131 3         4 $self->{"fs"}=45;
132 3         7 $self->{"ful"}=890 + $cs * ($n - 1024);
133              
134             } else {
135 2         3 $self->{"band"}="";
136 2         4 delete $self->{'cs'};
137             }
138 30 100       60 $self->{"fdl"}=$self->ful + $self->fs if $self->band;
139             }
140              
141             =head1 METHODS
142              
143             =head2 channel
144              
145             Sets or returns the channel. Recalculates properties when updated.
146              
147             =cut
148              
149             sub channel {
150 68     68 1 1506 my $self=shift;
151 68 100       123 if (@_) {
152 22         33 $self->{"channel"}=shift;
153 22 50       69 $self->calculate if defined $self->{"channel"};
154             }
155 68         745 return $self->{"channel"};
156             }
157              
158             =head2 bpi
159              
160             Set and returns the band plan indicator. Recalculates properties when set.
161              
162             my $bpi=$ga->bpi("GSM-1900"); #default
163             my $bpi=$ga->bpi("GSM-1800");
164              
165             =cut
166              
167             sub bpi {
168 23     23 1 705 my $self=shift;
169 23 100       58 if (@_) {
170 6         11 $self->{"bpi"}=shift;
171 6 100       15 $self->calculate if defined $self->channel;
172             }
173 23         71 return $self->{"bpi"};
174             }
175              
176             =head1 PROPERTIES
177              
178             =head2 band
179              
180             Returns the GSM band for the current channel. If the current channel is unknown by this package, this property will be false but defined.
181              
182             print $ga->band;
183             if ($ga->band) {
184             #Channel is valid
185             } else {
186             #Channel is not valid
187             }
188              
189             =cut
190              
191             sub band {
192 56     56 1 72 my $self=shift;
193 56         205 return $self->{"band"};
194             }
195              
196             =head2 ful (Frequency Uplink)
197              
198             Returns the channel uplink frequency in MHz.
199              
200             my $frequency=$ga->ful;
201              
202             =cut
203              
204             sub ful {
205 54     54 1 68 my $self=shift;
206 54         177 return $self->{"ful"};
207             }
208              
209             =head2 fdl (Frequency Downlink)
210              
211             Returns the channel downlink frequency in MHz.
212              
213             =cut
214              
215             sub fdl {
216 26     26 1 42 my $self=shift;
217 26         109 return $self->{"fdl"};
218             }
219              
220             =head2 fs (Frequency Separation)
221              
222             Returns the frequency separation between the uplink and downlink frequencies in MHz.
223              
224             =cut
225              
226             sub fs {
227 33     33 1 38 my $self=shift;
228 33         88 return $self->{"fs"};
229             }
230              
231             =head2 cs (Channel Spacing)
232              
233             Returns the channel spacing in MHz. Currently, this is always 0.2 MHz. The actual bandwidth of the signal is 270.833 KHz.
234              
235             =cut
236              
237             sub cs {
238 5     5 1 9 my $self=shift;
239 5         16 return $self->{"cs"};
240             }
241              
242             =head1 BUGS
243              
244             Submit to RT and email author.
245              
246             =head1 SUPPORT
247              
248             Try the author.
249              
250             =head1 AUTHOR
251              
252             Michael R. Davis
253             CPAN ID: MRDVT
254             STOP, LLC
255             domain=>michaelrdavis,tld=>com,account=>perl
256             http://www.stopllc.com/
257              
258             =head1 COPYRIGHT
259              
260             This program is free software licensed under the...
261              
262             The BSD License
263              
264             The full text of the license can be found in the
265             LICENSE file included with this module.
266              
267             =head1 SEE ALSO
268              
269             L, L
270              
271             =cut
272              
273             1;