File Coverage

blib/lib/Device/Gsm/Sms/Token/UDH.pm
Criterion Covered Total %
statement 33 84 39.2
branch 0 8 0.0
condition n/a
subroutine 11 14 78.5
pod n/a
total 44 106 41.5


line stmt bran cond sub pod time code
1             # Sms::Token::UDH - SMS UDH token (User Data Header stores non text data inluding CSMS ref,parts,part number)
2             # Copyright (C) 2002-2006 Cosimo Streppone, cosimo@cpan.org
3             # Copyright (C) 2006-2011 Grzegorz Wozniak, wozniakg@gmail.com
4             #
5             # This program is free software; you can redistribute it and/or modify
6             # it only under the terms of Perl itself.
7             #
8             # This program is distributed in the hope that it will be useful,
9             # but WITHOUT ANY WARRANTY; without even the implied warranty of
10             # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11             # Perl licensing terms for details.
12             #
13             # $Id$
14              
15             package Sms::Token::UDH;
16 10     10   61 use strict;
  10         18  
  10         383  
17              
18 10     10   60 use Device::Gsm::Pdu;
  10         57  
  10         255  
19 10     10   9176 use Device::Gsm::Sms::Token;
  10         27  
  10         386  
20              
21             #IEI types corresponding CSMS
22 10     10   60 use constant IEI_T_8 => 0x00;
  10         16  
  10         565  
23 10     10   50 use constant IEI_T_16 => 0x08;
  10         18  
  10         381  
24 10     10   51 use constant IEI_T_8_L => 5;
  10         21  
  10         396  
25 10     10   52 use constant IEI_T_16_L => 6;
  10         17  
  10         484  
26              
27             #constants for compatibility with older versions
28             ##user data headers in CSMS more here : http://mobiletidings.com/2009/02/18/combining-sms-messages/
29 10     10   57 use constant UDH1 => '050003';
  10         19  
  10         443  
30 10     10   59 use constant UDH2 => '060804';
  10         21  
  10         8782  
31              
32             #lenght in septets
33 10     10   55 use constant UDH1_LENGTH => 7;
  10         20  
  10         441  
34 10     10   46 use constant UDH2_LENGTH => 8;
  10         18  
  10         8231  
35              
36             @Sms::Token::UDH::ISA = ('Sms::Token');
37              
38             # takes (scalar message (string) reference)
39             # returns success/failure of decoding
40             # if all ok, removes user data header from message
41             sub decode {
42 0     0     my ($self, $rMessage) = @_;
43              
44             # Get length of message
45 0           my $ud_len = hex substr($$rMessage, 0, 2);
46              
47             #get UDH length
48 0           my $udhl = hex substr($$rMessage, 2, 2);
49              
50             #get UDH raw data
51 0           my $udh = substr($$rMessage, 4, 2 * $udhl);
52              
53             #cut udh from message
54 0           $$rMessage = substr($$rMessage, 4 + 2 * $udhl);
55 0           my $udhCp = $udh;
56 0           my %udh_data_hash;
57 0           while (length($udh)) {
58              
59             #Information-Element-Identifier type octet
60 0           my $IEI_t = hex(substr($udh, 0, 2));
61              
62             #Information-Element-Identifier data length
63 0           my $IEI_l = hex(substr($udh, 2, 2));
64              
65             #Information-Element-Identifier data
66 0           my $IEI_d = substr($udh, 4, 2 * $IEI_l);
67              
68             #cut element form data
69 0           $udh = substr($udh, 4 + 2 * $IEI_l);
70              
71             #store data in hash
72 0           $udh_data_hash{$IEI_t} = $IEI_d;
73             }
74 0           my $csms_ref_hex;
75             my $csms_ref_num;
76 0           my $csms_parts;
77 0           my $csms_part_num;
78 0 0         if (defined($udh_data_hash{ +IEI_T_8 })) {
    0          
79 0           ($csms_ref_hex, $csms_parts, $csms_part_num)
80             = ($udh_data_hash{ +IEI_T_8 }
81             =~ /^([A-F0-9]{2})([A-F0-9]{2})([A-F0-9]{2})/);
82 0           $csms_parts = hex($csms_parts);
83 0           $csms_part_num = hex($csms_part_num);
84 0           $csms_ref_num = hex($csms_ref_hex);
85              
86             }
87             elsif (defined($udh_data_hash{ +IEI_T_16 })) {
88 0           ($csms_ref_hex, $csms_parts, $csms_part_num)
89             = ($udh_data_hash{ +IEI_T_16 }
90             =~ /^([A-F0-9]{4})([A-F0-9]{2})([A-F0-9]{2})/);
91 0           $csms_parts = hex($csms_parts);
92 0           $csms_part_num = hex($csms_part_num);
93 0           $csms_ref_num = hex($csms_ref_hex);
94             }
95 0 0         if (defined($csms_ref_hex)) {
96 0           $self->set('IS_CSMS' => 1);
97 0           $self->set('REF_NUM' => $csms_ref_num);
98 0           $self->set('REF_HEX' => $csms_ref_hex);
99 0           $self->set('PARTS' => $csms_parts);
100 0           $self->set('PART_NUM' => $csms_part_num);
101             }
102             else {
103 0           $self->set('IS_CSMS' => 0);
104             }
105 0           $self->set('UDHI' => 1);
106 0           $self->set('length' => $udhl);
107 0           $self->set('raw_data' => $udhCp);
108 0           $self->data(\%udh_data_hash);
109 0           $self->state(Sms::Token::DECODED);
110              
111             #restore ud_len
112 0           $$rMessage = sprintf("%02X", $ud_len - ($udhl + 1)) . $$rMessage;
113              
114 0           return 1;
115             }
116              
117             #
118             # [token]->encode($IEI_t1=>$IEI_d1,$IEI_t2=>$IEI_d2,... )
119             # takes %opts like above, returns complete UDH string
120             # eg. my $udh=new Sms::Token("UDH");print $udh->encode(0x00=>"050401") gives 050003050401
121             #
122             sub encode {
123 0     0     my $self = shift;
124 0           my %udh_data_hash = @_;
125 0           my $udh;
126 0           foreach (keys %udh_data_hash) {
127 0           my $IEI_t = sprintf("%02X", $_);
128 0           my $IEI_l = sprintf("%02X", length($udh_data_hash{$_}) / 2);
129 0           $udh .= $IEI_t . $IEI_l . $udh_data_hash{$_};
130             }
131 0           $udh = sprintf("%02X", length($udh) / 2) . $udh;
132 0           return $udh;
133             }
134              
135             #
136             #return padding for given user data header lenght
137             #
138              
139             sub calculate_padding {
140              
141             #my $self=shift;
142 0     0     my $udhl = shift;
143 0 0         return 0 unless ($udhl);
144 0           return 7 - ((($udhl + 1) * 8) % 7);
145             }
146              
147             1;
148