| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
#!/usr/bin/perl |
|
2
|
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
package BACnet::APDU; |
|
4
|
|
|
|
|
|
|
|
|
5
|
27
|
|
|
27
|
|
216
|
use warnings; |
|
|
27
|
|
|
|
|
60
|
|
|
|
27
|
|
|
|
|
1634
|
|
|
6
|
27
|
|
|
27
|
|
137
|
use strict; |
|
|
27
|
|
|
|
|
77
|
|
|
|
27
|
|
|
|
|
679
|
|
|
7
|
|
|
|
|
|
|
|
|
8
|
27
|
|
|
27
|
|
13131
|
use BACnet::DataTypes::ObjectIdentifier; |
|
|
27
|
|
|
|
|
127
|
|
|
|
27
|
|
|
|
|
989
|
|
|
9
|
27
|
|
|
27
|
|
172
|
use BACnet::DataTypes::UnsignedInt; |
|
|
27
|
|
|
|
|
52
|
|
|
|
27
|
|
|
|
|
598
|
|
|
10
|
27
|
|
|
27
|
|
113
|
use BACnet::DataTypes::UnsignedInt; |
|
|
27
|
|
|
|
|
50
|
|
|
|
27
|
|
|
|
|
512
|
|
|
11
|
|
|
|
|
|
|
|
|
12
|
27
|
|
|
27
|
|
118
|
use BACnet::PDUTypes::ConfirmedRequest; |
|
|
27
|
|
|
|
|
45
|
|
|
|
27
|
|
|
|
|
617
|
|
|
13
|
27
|
|
|
27
|
|
13094
|
use BACnet::PDUTypes::UnconfirmedRequest; |
|
|
27
|
|
|
|
|
68
|
|
|
|
27
|
|
|
|
|
1106
|
|
|
14
|
27
|
|
|
27
|
|
13022
|
use BACnet::PDUTypes::SimpleACK; |
|
|
27
|
|
|
|
|
92
|
|
|
|
27
|
|
|
|
|
945
|
|
|
15
|
27
|
|
|
27
|
|
12653
|
use BACnet::PDUTypes::ComplexACK; |
|
|
27
|
|
|
|
|
87
|
|
|
|
27
|
|
|
|
|
962
|
|
|
16
|
27
|
|
|
27
|
|
12911
|
use BACnet::PDUTypes::Error; |
|
|
27
|
|
|
|
|
81
|
|
|
|
27
|
|
|
|
|
938
|
|
|
17
|
27
|
|
|
27
|
|
13559
|
use BACnet::PDUTypes::Reject; |
|
|
27
|
|
|
|
|
87
|
|
|
|
27
|
|
|
|
|
866
|
|
|
18
|
27
|
|
|
27
|
|
12394
|
use BACnet::PDUTypes::Abort; |
|
|
27
|
|
|
|
|
89
|
|
|
|
27
|
|
|
|
|
1075
|
|
|
19
|
|
|
|
|
|
|
|
|
20
|
27
|
|
|
27
|
|
134
|
use parent 'BACnet::NPDU'; |
|
|
27
|
|
|
|
|
51
|
|
|
|
27
|
|
|
|
|
143
|
|
|
21
|
|
|
|
|
|
|
|
|
22
|
27
|
|
|
27
|
|
1516
|
use constant { MAX_RESPONSE => 0x04, }; |
|
|
27
|
|
|
|
|
73
|
|
|
|
27
|
|
|
|
|
12358
|
|
|
23
|
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
our $apdu_types = { |
|
25
|
|
|
|
|
|
|
'Confirmed-Request' => 0x0, #Implemented |
|
26
|
|
|
|
|
|
|
'Unconfirmed-Request' => 0x1, #Implemented |
|
27
|
|
|
|
|
|
|
'Simple-ACK' => 0x2, #Implemented |
|
28
|
|
|
|
|
|
|
'Complex-ACK' => 0x3, #Implemented |
|
29
|
|
|
|
|
|
|
'Segmented-ACK' => 0x4, |
|
30
|
|
|
|
|
|
|
'Error' => 0x5, #Implemented |
|
31
|
|
|
|
|
|
|
'Reject' => 0x6, #Implemented |
|
32
|
|
|
|
|
|
|
'Abort' => 0x7, #Implemented |
|
33
|
|
|
|
|
|
|
}; |
|
34
|
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
our $apdu_types_rev = { reverse %$apdu_types }; |
|
36
|
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
our $apdu_tag_type = { |
|
38
|
|
|
|
|
|
|
0x0 => 'BACnet::PDUTypes::ConfirmedRequest', |
|
39
|
|
|
|
|
|
|
0x1 => 'BACnet::PDUTypes::UnconfirmedRequest', |
|
40
|
|
|
|
|
|
|
0x2 => 'BACnet::PDUTypes::SimpleACK', |
|
41
|
|
|
|
|
|
|
0x3 => 'BACnet::PDUTypes::ComplexACK', |
|
42
|
|
|
|
|
|
|
0x4 => undef, |
|
43
|
|
|
|
|
|
|
0x5 => 'BACnet::PDUTypes::Error', |
|
44
|
|
|
|
|
|
|
0x6 => 'BACnet::PDUTypes::Reject', |
|
45
|
|
|
|
|
|
|
0x7 => 'BACnet::PDUTypes::Abort', |
|
46
|
|
|
|
|
|
|
}; |
|
47
|
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
sub construct { |
|
49
|
0
|
|
|
0
|
0
|
|
my ( $class, $apdu_payload ) = @_; |
|
50
|
|
|
|
|
|
|
|
|
51
|
0
|
|
|
|
|
|
my $data = $apdu_payload->{data}; |
|
52
|
|
|
|
|
|
|
|
|
53
|
0
|
|
|
|
|
|
my $self = BACnet::NPDU->construct($data); |
|
54
|
|
|
|
|
|
|
|
|
55
|
0
|
|
|
|
|
|
$self->{payload} = $apdu_payload; |
|
56
|
|
|
|
|
|
|
|
|
57
|
0
|
|
|
|
|
|
return bless $self, $class; |
|
58
|
|
|
|
|
|
|
} |
|
59
|
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
sub parse { |
|
61
|
0
|
|
|
0
|
0
|
|
my ( $self, $data ) = @_; |
|
62
|
|
|
|
|
|
|
|
|
63
|
0
|
|
|
|
|
|
my @data = unpack( 'C*', $data ); |
|
64
|
|
|
|
|
|
|
|
|
65
|
0
|
0
|
|
|
|
|
if ( !defined $data[0] ) { |
|
66
|
0
|
|
|
|
|
|
$self->{error} = "APDU: missing apdu type"; |
|
67
|
0
|
|
|
|
|
|
return $self; |
|
68
|
|
|
|
|
|
|
} |
|
69
|
|
|
|
|
|
|
|
|
70
|
0
|
|
|
|
|
|
my $apdu_type = $data[0] >> 4; |
|
71
|
|
|
|
|
|
|
|
|
72
|
0
|
|
|
|
|
|
my $apdu_type_to_parse = $apdu_tag_type->{$apdu_type}; |
|
73
|
|
|
|
|
|
|
|
|
74
|
0
|
0
|
|
|
|
|
if ( !defined $apdu_type_to_parse ) { |
|
75
|
0
|
|
|
|
|
|
$self->{error} = "APDU: unknown apdu type"; |
|
76
|
0
|
|
|
|
|
|
return $self; |
|
77
|
|
|
|
|
|
|
} |
|
78
|
|
|
|
|
|
|
|
|
79
|
0
|
|
|
|
|
|
$self->{payload} = $apdu_type_to_parse->parse($data); |
|
80
|
|
|
|
|
|
|
|
|
81
|
0
|
0
|
|
|
|
|
if ( defined $self->{payload}->{error} ) { |
|
82
|
|
|
|
|
|
|
$self->{error} = |
|
83
|
0
|
|
|
|
|
|
"APDU: propagated error($self->{payload}->{error})"; |
|
84
|
0
|
|
|
|
|
|
return $self; |
|
85
|
|
|
|
|
|
|
} |
|
86
|
|
|
|
|
|
|
|
|
87
|
0
|
|
|
|
|
|
return $self; |
|
88
|
|
|
|
|
|
|
} |
|
89
|
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
1; |