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-2015 Cosimo Streppone, cosimo@cpan.org
3             # Copyright (C) 2006-2015 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             package Sms::Token::UDH;
14 11     11   39 use strict;
  11         12  
  11         251  
15              
16 11     11   34 use Device::Gsm::Pdu;
  11         30  
  11         203  
17 11     11   3485 use Device::Gsm::Sms::Token;
  11         18  
  11         220  
18              
19             #IEI types corresponding CSMS
20 11     11   40 use constant IEI_T_8 => 0x00;
  11         11  
  11         425  
21 11     11   34 use constant IEI_T_16 => 0x08;
  11         10  
  11         330  
22 11     11   31 use constant IEI_T_8_L => 5;
  11         10  
  11         430  
23 11     11   35 use constant IEI_T_16_L => 6;
  11         14  
  11         357  
24              
25             #constants for compatibility with older versions
26             ##user data headers in CSMS more here : http://mobiletidings.com/2009/02/18/combining-sms-messages/
27 11     11   30 use constant UDH1 => '050003';
  11         12  
  11         345  
28 11     11   36 use constant UDH2 => '060804';
  11         11  
  11         416  
29              
30             #lenght in septets
31 11     11   34 use constant UDH1_LENGTH => 7;
  11         9  
  11         347  
32 11     11   34 use constant UDH2_LENGTH => 8;
  11         11  
  11         4739  
33              
34             @Sms::Token::UDH::ISA = ('Sms::Token');
35              
36             # takes (scalar message (string) reference)
37             # returns success/failure of decoding
38             # if all ok, removes user data header from message
39             sub decode {
40 0     0     my ($self, $rMessage) = @_;
41              
42             # Get length of message
43 0           my $ud_len = hex substr($$rMessage, 0, 2);
44              
45             #get UDH length
46 0           my $udhl = hex substr($$rMessage, 2, 2);
47              
48             #get UDH raw data
49 0           my $udh = substr($$rMessage, 4, 2 * $udhl);
50              
51             #cut udh from message
52 0           $$rMessage = substr($$rMessage, 4 + 2 * $udhl);
53 0           my $udhCp = $udh;
54 0           my %udh_data_hash;
55 0           while (length($udh)) {
56              
57             #Information-Element-Identifier type octet
58 0           my $IEI_t = hex(substr($udh, 0, 2));
59              
60             #Information-Element-Identifier data length
61 0           my $IEI_l = hex(substr($udh, 2, 2));
62              
63             #Information-Element-Identifier data
64 0           my $IEI_d = substr($udh, 4, 2 * $IEI_l);
65              
66             #cut element form data
67 0           $udh = substr($udh, 4 + 2 * $IEI_l);
68              
69             #store data in hash
70 0           $udh_data_hash{$IEI_t} = $IEI_d;
71             }
72 0           my $csms_ref_hex;
73             my $csms_ref_num;
74 0           my $csms_parts;
75 0           my $csms_part_num;
76 0 0         if (defined($udh_data_hash{ +IEI_T_8 })) {
    0          
77             ($csms_ref_hex, $csms_parts, $csms_part_num)
78 0           = ($udh_data_hash{ +IEI_T_8 }
79             =~ /^([A-F0-9]{2})([A-F0-9]{2})([A-F0-9]{2})/);
80 0           $csms_parts = hex($csms_parts);
81 0           $csms_part_num = hex($csms_part_num);
82 0           $csms_ref_num = hex($csms_ref_hex);
83              
84             }
85             elsif (defined($udh_data_hash{ +IEI_T_16 })) {
86             ($csms_ref_hex, $csms_parts, $csms_part_num)
87 0           = ($udh_data_hash{ +IEI_T_16 }
88             =~ /^([A-F0-9]{4})([A-F0-9]{2})([A-F0-9]{2})/);
89 0           $csms_parts = hex($csms_parts);
90 0           $csms_part_num = hex($csms_part_num);
91 0           $csms_ref_num = hex($csms_ref_hex);
92             }
93 0 0         if (defined($csms_ref_hex)) {
94 0           $self->set('IS_CSMS' => 1);
95 0           $self->set('REF_NUM' => $csms_ref_num);
96 0           $self->set('REF_HEX' => $csms_ref_hex);
97 0           $self->set('PARTS' => $csms_parts);
98 0           $self->set('PART_NUM' => $csms_part_num);
99             }
100             else {
101 0           $self->set('IS_CSMS' => 0);
102             }
103 0           $self->set('UDHI' => 1);
104 0           $self->set('length' => $udhl);
105 0           $self->set('raw_data' => $udhCp);
106 0           $self->data(\%udh_data_hash);
107 0           $self->state(Sms::Token::DECODED);
108              
109             #restore ud_len
110 0           $$rMessage = sprintf("%02X", $ud_len - ($udhl + 1)) . $$rMessage;
111              
112 0           return 1;
113             }
114              
115             #
116             # [token]->encode($IEI_t1=>$IEI_d1,$IEI_t2=>$IEI_d2,... )
117             # takes %opts like above, returns complete UDH string
118             # eg. my $udh=new Sms::Token("UDH");print $udh->encode(0x00=>"050401") gives 050003050401
119             #
120             sub encode {
121 0     0     my $self = shift;
122 0           my %udh_data_hash = @_;
123 0           my $udh;
124 0           foreach (keys %udh_data_hash) {
125 0           my $IEI_t = sprintf("%02X", $_);
126 0           my $IEI_l = sprintf("%02X", length($udh_data_hash{$_}) / 2);
127 0           $udh .= $IEI_t . $IEI_l . $udh_data_hash{$_};
128             }
129 0           $udh = sprintf("%02X", length($udh) / 2) . $udh;
130 0           return $udh;
131             }
132              
133             #
134             #return padding for given user data header lenght
135             #
136              
137             sub calculate_padding {
138              
139             #my $self=shift;
140 0     0     my $udhl = shift;
141 0 0         return 0 unless ($udhl);
142 0           return 7 - ((($udhl + 1) * 8) % 7);
143             }
144              
145             1;
146